Index: EcnlProtoTool/trunk/asp3_dcre/.cproject
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/.cproject	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/.cproject	(revision 331)
@@ -85,5 +85,5 @@
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre/mbed/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre/mbed/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/TARGET_MBED_MBRZA1H}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mruby-1.2.0/include}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mruby-1.3.0/include}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/sample8/src}&quot;"/>
Index: EcnlProtoTool/trunk/asp3_dcre/.info
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/.info	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/.info	(revision 331)
@@ -4,4 +4,4 @@
 GCC_STRING=5.2-GNUARM-NONE_v16.01
 VERSION_IDE=
-E2STUDIO_VERSION=5.3.1.002
+E2STUDIO_VERSION=5.4.0.018
 ACTIVE_CONFIGURATION=Debug
Index: EcnlProtoTool/trunk/asp3_dcre/Debug/Makefile
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/Debug/Makefile	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/Debug/Makefile	(revision 331)
@@ -197,36 +197,33 @@
 endif
 
-#
-#  ネットワークサービスの定義
-#
-
-NO_USE_TINET_LIBRARY = true
-
-#  ネットワークインタフェースの選択、何れか一つ選択する。
-
-NET_IF = ether
-
-#  イーサネット・ディバイスドライバの選択
-
-NET_DEV = if_mbed
-
-#  ネットワーク層の選択
-
-#SUPPORT_INET6 = true
-SUPPORT_INET4 = true
-
-#  API に組込む機能の選択
-
-#API_CFG_IP4MAPPED_ADDR = true
-
-#  トランスポート層の選択
-
-SUPPORT_TCP = true
-#SUPPORT_UDP = true
-
-#
-#  システムサービスの Makefile のインクルード
-#
-include $(SRCDIR)/tinet/Makefile.tinet
+TINETDIR = tinet
+ifdef TINETDIR
+	#
+	#  ネットワークサービスの定義
+	#
+	NO_USE_TINET_LIBRARY = true
+
+	#  ネットワークインタフェースの選択、何れか一つ選択する。
+	NET_IF = ether
+
+	#  イーサネット・ディバイスドライバの選択
+	NET_DEV = if_mbed
+
+	#  ネットワーク層の選択
+	SUPPORT_INET6 = true
+	SUPPORT_INET4 = true
+
+	#  API に組込む機能の選択
+	#API_CFG_IP4MAPPED_ADDR = true
+
+	#  トランスポート層の選択
+	SUPPORT_TCP = true
+	SUPPORT_UDP = true
+
+	#
+	#  ネットワークサービスの Makefile のインクルード
+	#
+	include $(SRCDIR)/$(TINETDIR)/Makefile.tinet
+endif
 
 #
@@ -239,5 +236,5 @@
 				 $(CXXRTS)
 SYSSVC_CFLAGS := $(SYSSVC_CFLAGS)
-INCLUDES := $(INCLUDES) -I$(TECSGENDIR) -I$(SRCDIR)/tecs_kernel
+INCLUDES := $(INCLUDES) -I$(TECSGENDIR) -I$(SRCDIR)/tecs_kernel -I../../musl-1.1.18/include
 
 #
@@ -261,8 +258,15 @@
 #  コンフィギュレータに関する定義
 #
-CFG_TABS := --api-table $(SRCDIR)/tinet/tcpip_api.def:tcpip \
+ifndef TINETDIR
+  CFG_TRB := -T $(TARGETDIR)/target_kernel.trb
+  CFG_TABS := --api-table $(SRCDIR)/kernel/kernel_api.def \
+			--symval-table $(SRCDIR)/kernel/kernel_sym.def $(CFG_TABS)
+else
+  CFG_TRB := -T $(TINET_ROOT)/tinet.trb:tcpip -T $(TARGETDIR)/target_kernel.trb:kernel
+  CFG_TABS := --api-table $(TINET_ROOT)/tcpip_api.def:tcpip \
 			--api-table $(SRCDIR)/kernel/kernel_api.def:kernel \
 			--symval-table $(SRCDIR)/tinet/tcpip_sym.def \
 			--symval-table $(SRCDIR)/kernel/kernel_sym.def $(CFG_TABS)
+endif
 CFG_ASMOBJS := $(CFG_ASMOBJS)
 CFG_COBJS := kernel_cfg.o $(CFG_COBJS)
@@ -333,5 +337,5 @@
 #
 KERNEL_LIB_OBJS = $(KERNEL_ASMOBJS) $(KERNEL_COBJS) $(KERNEL_LCOBJS)
-SYSSVC_OBJS = $(SYSSVC_ASMOBJS) $(SYSSVC_COBJS)
+SYSSVC_OBJS = $(SYSSVC_ASMOBJS) $(SYSSVC_COBJS) $(HIDDEN_OBJS)
 APPL_OBJS = $(APPL_ASMOBJS) $(APPL_COBJS) $(APPL_CXXOBJS)
 ALL_OBJS = $(START_OBJS) $(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) \
@@ -375,4 +379,5 @@
 cfg1_out.c cfg1_out.db: cfg1_out.timestamp ;
 cfg1_out.timestamp: $(APPL_CFG) $(TECSGEN_TIMESTAMP)
+	echo $(CFG_TABS)
 	$(CFG) --pass 1 --kernel asp $(INCLUDES) $(CFG_TABS) \
 						-M $(DEPDIR)/cfg1_out_c.d $(TARGET_KERNEL_CFG) $<
@@ -390,5 +395,5 @@
 $(CFG2_OUT_SRCS) cfg2_out.db: kernel_cfg.timestamp ;
 kernel_cfg.timestamp: cfg1_out.db cfg1_out.syms cfg1_out.srec
-	$(CFG) --pass 2 --kernel asp $(INCLUDES) -T $(TARGET_TCPIP_TRB):tcpip -T $(TARGET_KERNEL_TRB):kernel
+	$(CFG) --pass 2 --kernel asp $(INCLUDES) $(CFG_TRB)
 
 #
@@ -462,5 +467,5 @@
 	rm -f cfg1_out.syms cfg1_out.srec $(CFG1_OUT)
 	rm -f cfg1_out.timestamp cfg1_out.c cfg1_out.db
-#	rm -rf $(TECSGENDIR)
+	rm -rf $(TECSGENDIR)
 ifndef KERNEL_LIB
 	rm -f libkernel.a
Index: EcnlProtoTool/trunk/asp3_dcre/arch/arm_gcc/common/core_support.S
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/arch/arm_gcc/common/core_support.S	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/arch/arm_gcc/common/core_support.S	(revision 331)
@@ -550,4 +550,5 @@
 	ATEXT
 	AALIGN(2)
+	AWEAK(svc_handler)
 	AGLOBAL(svc_handler)
 ALABEL(svc_handler)
Index: EcnlProtoTool/trunk/asp3_dcre/arch/tracelog/tTraceLog.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/arch/tracelog/tTraceLog.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/arch/tracelog/tTraceLog.c	(revision 331)
@@ -259,4 +259,8 @@
 		tracemsg = "task %d becomes %s.";
 		break;
+	case LOG_TYPE_DSP|LOG_ENTER:
+		traceinfo[0] = get_tskid(p_trace->logpar[0]);
+		tracemsg = "dispatch from task %d.";
+		break;
 	case LOG_TYPE_DSP|LOG_LEAVE:
 		traceinfo[0] = get_tskid(p_trace->logpar[0]);
@@ -275,4 +279,20 @@
 		tracemsg = "%s:%u: Assertion `%s' failed.";
 		break;
+	case LOG_TYPE_INH|LOG_ENTER:
+		traceinfo[0] = p_trace->logpar[0];
+		tracemsg = "interrupt IN: %d";
+		break;
+	case LOG_TYPE_INH|LOG_LEAVE:
+		traceinfo[0] = p_trace->logpar[0];
+		tracemsg = "interrupt OUT: %d";
+		break;
+	case LOG_TYPE_EXC|LOG_ENTER:
+		traceinfo[0] = p_trace->logpar[0];
+		tracemsg = "exception IN: %d";
+		break;
+	case LOG_TYPE_EXC|LOG_LEAVE:
+		traceinfo[0] = p_trace->logpar[0];
+		tracemsg = "exception OUT: %d";
+		break;
 	default:
 		traceinfo[0] = p_trace->logtype;
Index: EcnlProtoTool/trunk/asp3_dcre/arch/tracelog/trace_log.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/arch/tracelog/trace_log.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/arch/tracelog/trace_log.h	(revision 331)
@@ -204,6 +204,4 @@
 #define LOG_TSKSTAT(p_tcb)		trace_2(LOG_TYPE_TSKSTAT, p_tcb, p_tcb->tstat)
 
-#define LOG_DSP_LEAVE(p_tcb)	trace_1(LOG_TYPE_DSP|LOG_LEAVE, p_tcb)
-
 #define LOG_TSYSLOG_ESYSLOG_WRITE_ENTER(priority, p_syslog) \
 								trace_wri_log((TRACE *) p_syslog)
Index: EcnlProtoTool/trunk/asp3_dcre/cfg/cfg.rb
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/cfg/cfg.rb	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/cfg/cfg.rb	(revision 331)
@@ -532,4 +532,10 @@
 end
 
+def BZERO(address, size)
+  if !$romImage.nil?
+    $romImage.set_data(address, "00" * size)
+  end
+end
+
 def PEEK(address, size, signed=false)
   if !$romImage.nil?
Index: EcnlProtoTool/trunk/asp3_dcre/cfg/pass1.rb
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/cfg/pass1.rb	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/cfg/pass1.rb	(revision 331)
@@ -4,5 +4,5 @@
 #
 #  Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
-#  Copyright (C) 2015,2016 by Embedded and Real-Time Systems Laboratory
+#  Copyright (C) 2015-2017 by Embedded and Real-Time Systems Laboratory
 #              Graduate School of Information Science, Nagoya Univ., JAPAN
 #
@@ -168,9 +168,11 @@
     end
 
-    symvalCsv = CSV.open(symvalTableFileName)
+    symvalCsv = CSV.open(symvalTableFileName,
+						{ skip_blanks: true, skip_lines: /^#/ })
     symvalCsv.each do |record|
       # 変数名
       if record[0].nil?
-        error_exit("invalid variable name in `#{fileName}'")
+        error_exit("invalid variable name in " \
+						"`#{symvalTableFileName}:#{symvalCsv.to_io.lineno}'")
       end
 
@@ -235,4 +237,9 @@
     line = @cfgFile.gets
     return(nil) if line.nil?
+
+	line.encode!("UTF-16BE", "UTF-8",	# 不正なバイト列を除外する
+					:invalid => :replace,
+					:undef => :replace,
+					:replace => '?').encode!("UTF-8")
     @lineNo += 1
 
@@ -772,5 +779,11 @@
 
 #include "#{CFG1_OUT_TARGET_H}"
-#include <limits.h>
+
+#if defined(SIL_ENDIAN_BIG) && defined(SIL_ENDIAN_LITTLE)
+#error Both SIL_ENDIAN_BIG and SIL_ENDIAN_LITTLE are defined.
+#endif
+#if !defined(SIL_ENDIAN_BIG) && !defined(SIL_ENDIAN_LITTLE)
+#error Neither SIL_ENDIAN_BIG nor SIL_ENDIAN_LITTLE is defined.
+#endif
 
 const uint32_t #{CFG1_MAGIC_NUM} = 0x12345678;
Index: EcnlProtoTool/trunk/asp3_dcre/cfg/pass2.rb
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/cfg/pass2.rb	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/cfg/pass2.rb	(revision 331)
@@ -4,5 +4,5 @@
 #
 #  Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
-#  Copyright (C) 2015,2016 by Embedded and Real-Time Systems Laboratory
+#  Copyright (C) 2015-2017 by Embedded and Real-Time Systems Laboratory
 #              Graduate School of Information Science, Nagoya Univ., JAPAN
 #
@@ -154,4 +154,5 @@
         value = @objidValues[paramName][param]
       else
+        apiDef = $apiDefinition[cfgInfo[:APINAME]]
         error("#{apiDef.has_key?(:KEYPAR) ? "E_NOEXS" : "E_ID"}: " \
 					"`#{param}' in #{cfgInfo[:APINAME]} is not defined", \
Index: EcnlProtoTool/trunk/asp3_dcre/configure.rb
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/configure.rb	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/configure.rb	(revision 331)
@@ -78,4 +78,13 @@
 #  -O <options>			シンボル定義オプション（CDEFSに追加）
 #  -k <options>			リンカオプション（LDFLAGS等に追加）
+#  -e <tinetdir>		TINET のソースの置かれているディレクトリ
+#  -i <net_if>			ネットワークインタフェース（TINETが有効の場合は必須）
+#						ether、ppp、loop の何れかを指定する。
+#  -v <net_dev>			イーサネット・ディバイスドライバ
+#  						（ネットワークインタフェースに ether を指定した場合は必須）
+#  -n <net_proto>		ネットワーク層プロトコル（TINETが有効の場合は必須）
+#						inet6、inet4、inet6/inet4、inet6m、inet6m/inet4 の何れかを指定する。
+#  -s <trans_proto>		トランスポート層プロトコル（TINETが有効の場合は必須）
+#						tcp、udp、tcp/udp の何れかを指定する。
 
 #  使用例(1)
@@ -98,4 +107,10 @@
 #  % ../configure.rb -T ct11mpcore_gcc PRC_NUM=4
 #	PRC_NUMを4に定義する．
+#
+#  使用例(5)
+#
+#  % ../configure.rb -T gr_sakura_gcc -A sample1n \
+#					-e tinet -i ether -v if_rx62n -n inet4 -s tcp -U sample1.o
+#	TINETを有効にする．
 
 #
@@ -190,4 +205,19 @@
   opt.on("-k options",		"linker options") do |val|
     $ldflags += val.split("\s+")
+  end
+  opt.on("-e options",		"path of TINET directory") do |val|
+    $tinetdir = val
+  end
+  opt.on("-i options",		"network interface (ether or ppp or loop)") do |val|
+    $net_if = val
+  end
+  opt.on("-v options",		"ethernet device driver") do |val|
+    $net_dev = val
+  end
+  opt.on("-n options",		"network layer protocol (inet6 or inet4 or inet6/inet4 or inet6m or inet6m/inet4)") do |val|
+    $net_proto = val
+  end
+  opt.on("-s options",		"transeport layer protocol (tcp or udp or tcp/udp)") do |val|
+    $trans_proto = val
   end
   opt.parse!(ARGV)
@@ -280,4 +310,13 @@
 $vartable["LDFLAGS"] = $ldflags.join(" ")
 $vartable["OBJEXT"] = GetObjectExtension()
+$vartable["TINETDIR"] = $tinetdir
+$vartable["NET_IF"] = $net_if
+$vartable["NET_DEV"] = $net_dev
+$vartable["SUPPORT_INET6"] = ($net_proto == "inet6") || ($net_proto == "inet6/inet4") || ($net_proto == "inet6m") || ($net_proto == "inet6m/inet4")
+$vartable["SUPPORT_INET4"] = ($net_proto == "inet4") || ($net_proto == "inet6/inet4") || ($net_proto == "inet6m/inet4")
+$vartable["SUPPORT_TCP"] = ($trans_proto == "tcp") || ($net_proto == "tcp/udp")
+$vartable["SUPPORT_UDP"] = ($trans_proto == "udp") || ($net_proto == "tcp/udp")
+$vartable["API_CFG_IP4MAPPED_ADDR"] = ($net_proto == "inet6m") || ($net_proto == "inet6m/inet4")
+
 ARGV.each do |arg|
   if /^([A-Za-z0-9_]+)\s*\=\s*(.*)$/ =~ arg
Index: EcnlProtoTool/trunk/asp3_dcre/include/kernel.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/include/kernel.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/include/kernel.h	(revision 331)
@@ -323,5 +323,5 @@
  *  タスク管理機能
  */
-extern ER_UINT	acre_tsk(const T_CTSK *pk_ctsk) throw();
+extern ER_ID	acre_tsk(const T_CTSK *pk_ctsk) throw();
 extern ER		del_tsk(ID tskid) throw();
 extern ER		act_tsk(ID tskid) throw();
Index: EcnlProtoTool/trunk/asp3_dcre/mbed/targets/cmsis/TARGET_RENESAS/TARGET_RZ_A1H/TOOLCHAIN_GCC_ARM/RZA1H.ld
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/mbed/targets/cmsis/TARGET_RENESAS/TARGET_RZ_A1H/TOOLCHAIN_GCC_ARM/RZA1H.ld	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/mbed/targets/cmsis/TARGET_RENESAS/TARGET_RZ_A1H/TOOLCHAIN_GCC_ARM/RZA1H.ld	(revision 331)
@@ -13,6 +13,7 @@
   SFLASH (rx) : ORIGIN = 0x18004000, LENGTH = 0x07FFC000 
   L_TTB (rw)  : ORIGIN = 0x20000000, LENGTH = 0x00004000 
-  RAM (rwx) : ORIGIN = 0x20020000, LENGTH = 0x00700000
-  RAM_NC (rwx) : ORIGIN = 0x20900000, LENGTH = 0x00100000
+  RAM (rw) : ORIGIN = 0x20004000, LENGTH = 0x000FC000
+  RAM_CMD (rwx) : ORIGIN = 0x20100000, LENGTH = 0x00800000
+  RAM_NC (rw) : ORIGIN = 0x20900000, LENGTH = 0x00100000
 }
 
@@ -155,5 +156,4 @@
         PROVIDE (__init_array_end = .);
 
-
         . = ALIGN(4);
         /* finit data */
@@ -169,5 +169,4 @@
     } > RAM
 
-    
     .bss ALIGN(0x400):
     {
@@ -180,5 +179,12 @@
     } > RAM
 
-    
+    /* .stack_dummy section doesn't contains any symbols. It is only
+     * used for linker to calculate size of stack sections, and assign
+     * values to stack symbols later */
+    .stack_dummy :
+    {
+        *(.stack)
+    } > RAM
+
     .heap :
     {
@@ -189,11 +195,12 @@
     } > RAM
 
-    /* .stack_dummy section doesn't contains any symbols. It is only
-     * used for linker to calculate size of stack sections, and assign
-     * values to stack symbols later */
-    .stack_dummy :
-    {
-        *(.stack)
-    } > RAM
+    .cmd_area :
+    {
+        __CmdBase = .;
+        Image$$CMD_AREA$$Base = .;
+        . = . + LENGTH(RAM_CMD);
+        __CmdLimit = .;
+        Image$$CMD_AREA$$Limit = .;
+    } > RAM_CMD
 
     __etext2 = __etext + SIZEOF(.data);
Index: EcnlProtoTool/trunk/asp3_dcre/mbed/targets/cmsis/TARGET_RENESAS/TARGET_RZ_A1H/TOOLCHAIN_GCC_ARM/startup_RZ1AH.S
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/mbed/targets/cmsis/TARGET_RENESAS/TARGET_RZ_A1H/TOOLCHAIN_GCC_ARM/startup_RZ1AH.S	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/mbed/targets/cmsis/TARGET_RENESAS/TARGET_RZ_A1H/TOOLCHAIN_GCC_ARM/startup_RZ1AH.S	(revision 331)
@@ -97,5 +97,5 @@
 @ Heap Configuration
 
-    .EQU    Heap_Size       , 0x00080000
+    .EQU    Heap_Size       , 0x00020000
 
     .section .heap
Index: EcnlProtoTool/trunk/asp3_dcre/mbed/targets/cmsis/TARGET_RENESAS/TARGET_RZ_A1H/mmu_Renesas_RZ_A1.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/mbed/targets/cmsis/TARGET_RENESAS/TARGET_RZ_A1H/mmu_Renesas_RZ_A1.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/mbed/targets/cmsis/TARGET_RENESAS/TARGET_RZ_A1H/mmu_Renesas_RZ_A1.c	(revision 331)
@@ -72,4 +72,5 @@
 extern uint32_t Image$$RW_DATA$$Base;
 extern uint32_t Image$$ZI_DATA$$Base;
+extern uint32_t Image$$CMD_AREA$$Base;
 extern uint32_t Image$$TTB$$ZI$$Base;
 #if defined( __CC_ARM )
@@ -83,4 +84,5 @@
 extern uint32_t Image$$RW_DATA$$Limit;
 extern uint32_t Image$$ZI_DATA$$Limit;
+extern uint32_t Image$$CMD_AREA$$Limit;
 #if defined( __CC_ARM )
 #else
@@ -93,4 +95,5 @@
 #define RW_DATA_SIZE    (((uint32_t)&Image$$RW_DATA$$Limit >> 20) - ((uint32_t)&Image$$RW_DATA$$Base >> 20) + 1)
 #define ZI_DATA_SIZE    (((uint32_t)&Image$$ZI_DATA$$Limit >> 20) - ((uint32_t)&Image$$ZI_DATA$$Base >> 20) + 1)
+#define CMD_AREA_SIZE    (((uint32_t)&Image$$CMD_AREA$$Limit >> 20) - ((uint32_t)&Image$$CMD_AREA$$Base >> 20) + 1)
 #if defined( __CC_ARM )
 #else
@@ -160,8 +163,9 @@
     //Define Image
     __TTSection (&Image$$TTB$$ZI$$Base, (uint32_t)&Image$$RO_DATA$$Base, RO_DATA_SIZE, Sect_Normal_RO);
-    __TTSection (&Image$$TTB$$ZI$$Base, 0x18200000, 4, Sect_Normal_Cod);
+    __TTSection (&Image$$TTB$$ZI$$Base, 0x18200000, (0x18800000 >> 20) - (0x18200000 >> 20) + 1, Sect_Normal_Cod);
     __TTSection (&Image$$TTB$$ZI$$Base, (uint32_t)&Image$$VECTORS$$Base, VECTORS_SIZE, Sect_Normal_Cod);
     __TTSection (&Image$$TTB$$ZI$$Base, (uint32_t)&Image$$RW_DATA$$Base, RW_DATA_SIZE, Sect_Normal_RW);
     __TTSection (&Image$$TTB$$ZI$$Base, (uint32_t)&Image$$ZI_DATA$$Base, ZI_DATA_SIZE, Sect_Normal_RW);
+	__TTSection (&Image$$TTB$$ZI$$Base, (uint32_t)&Image$$CMD_AREA$$Base, CMD_AREA_SIZE, Sect_Normal);
 #if defined( __CC_ARM )
     __TTSection (&Image$$TTB$$ZI$$Base, Renesas_RZ_A1_ONCHIP_SRAM_NC_BASE,         10, Sect_Normal_NC);
Index: EcnlProtoTool/trunk/asp3_dcre/sample/Makefile
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/sample/Makefile	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/sample/Makefile	(revision 331)
@@ -12,19 +12,19 @@
 #  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
 #  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
-#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
-#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
-#       スコード中に含まれていること．
-#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
-#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
-#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
-#       の無保証規定を掲載すること．
-#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+#  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+#      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+#      スコード中に含まれていること．
+#  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+#      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+#      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+#      の無保証規定を掲載すること．
+#  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
 #      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
 #      と．
-#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
-#         作権表示，この利用条件および下記の無保証規定を掲載すること．
+#    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+#        作権表示，この利用条件および下記の無保証規定を掲載すること．
 #    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
 #        報告すること．
-#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+#  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
 #      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
 #      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
@@ -354,5 +354,5 @@
 endif
 ifdef LDSCRIPT
-	LDFLAGS := $(LDFLAGS) -T $(LDSCRIPT)
+	LDFLAGS := $(LDFLAGS) -Wl,-T,$(LDSCRIPT)
 endif
 
Index: EcnlProtoTool/trunk/asp3_dcre/sample/route_cfg.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/sample/route_cfg.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/sample/route_cfg.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2012 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -44,11 +44,23 @@
 #include <netinet/in_var.h>
 
+/* IPv6 に関する定義 */
+
+#ifdef _IP6_CFG
+
+#if NUM_IN6_ROUTE_ENTRY > 0
+
+T_IN6_RTENTRY routing6_tbl[NUM_IN6_ROUTE_ENTRY];
+
+#endif	/* of #if NUM_IN6_ROUTE_ENTRY > 0 */
+
+#endif	/* of #ifdef _IP6_CFG */
+
 /* IPv4 に関する定義 */
 
-#ifdef SUPPORT_INET4
+#ifdef _IP4_CFG
 
 #ifdef SUPPORT_LOOP
 
-T_IN4_RTENTRY routing_tbl[NUM_ROUTE_ENTRY] = {
+T_IN4_RTENTRY routing4_tbl[NUM_IN4_ROUTE_ENTRY] = {
 	{ 0, 0, 0 },
 	};
@@ -58,5 +70,5 @@
 #ifdef SUPPORT_PPP
 
-T_IN4_RTENTRY routing_tbl[NUM_ROUTE_ENTRY] = {
+T_IN4_RTENTRY routing4_tbl[NUM_IN4_ROUTE_ENTRY] = {
 	{ 0, 0, 0 },
 	};
@@ -66,5 +78,5 @@
 #ifdef SUPPORT_ETHER
 
-T_IN4_RTENTRY routing_tbl[NUM_ROUTE_ENTRY] = {
+T_IN4_RTENTRY routing4_tbl[NUM_IN4_ROUTE_ENTRY] = {
 
 	/* 異なる LAN、default gateway による間接配送	*/
@@ -82,15 +94,3 @@
 #endif	/* of #ifdef SUPPORT_ETHER */
 
-#endif	/* of #ifdef SUPPORT_INET4 */
-
-/* IPv6 に関する定義 */
-
-#ifdef SUPPORT_INET6
-
-#if NUM_ROUTE_ENTRY > 0
-
-T_IN6_RTENTRY routing_tbl[NUM_ROUTE_ENTRY] = { };
-
-#endif	/* of #if NUM_ROUTE_ENTRY > 0 */
-
-#endif	/* of #ifdef SUPPORT_INET6 */
+#endif	/* of #ifdef _IP4_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/sample/sample1.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/sample/sample1.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/sample/sample1.c	(revision 331)
@@ -116,5 +116,5 @@
 #include "kernel_cfg.h"
 #include "sample1.h"
-#include "sample1n.h"
+/*#include "sample1n.h"*/
 
 /*
Index: EcnlProtoTool/trunk/asp3_dcre/sample/sample1n.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/sample/sample1n.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/sample/sample1n.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2012 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -39,5 +39,5 @@
 
 #include <kernel.h>
-#include <t_syslog.h>
+#include "syssvc/syslog.h"
 #include "syssvc/serial.h"
 #include "kernel_cfg.h"
@@ -92,4 +92,10 @@
 bool_t		wait_accept	= false;	/* 接続要求待ち中	*/
 
+#ifdef SUPPORT_INET6
+
+T_IPV6EP	dst;
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
 #ifdef SUPPORT_INET4
 
@@ -97,8 +103,4 @@
 
 #endif	/* of #ifdef SUPPORT_INET4 */
-
-#ifdef SUPPORT_INET6
-
-T_IPV6EP	dst;
 
 #endif	/* of #ifdef SUPPORT_INET6 */
@@ -117,4 +119,11 @@
  */
 
+#ifdef SUPPORT_INET6
+
+#define TCP_ACP_CEP(c,r,d,t)	tcp6_acp_cep(c,r,d,t)
+#define IP2STR(s,a)		ipv62str(s,a)
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
 #ifdef SUPPORT_INET4
 
@@ -124,9 +133,4 @@
 #endif	/* of #ifdef SUPPORT_INET4 */
 
-#ifdef SUPPORT_INET6
-
-#define TCP_ACP_CEP(c,r,d,t)	tcp6_acp_cep(c,r,d,t)
-#define IP2STR(s,a)		ipv62str(s,a)
-
 #endif	/* of #ifdef SUPPORT_INET6 */
 
@@ -143,5 +147,5 @@
 
 	case TFN_TCP_ACP_CEP:
-		IP2STR(addr, &dst.ipaddr);
+		IP2STR((char *)addr, &dst.ipaddr);
 		syslog(LOG_NOTICE, "connected:    %s.%d", addr, dst.portno);
 		if (*(ER*)p_parblk == E_OK)
@@ -182,5 +186,5 @@
 		connected = false;
 		syscall(sig_sem(SEM_NET_SEND));
-		IP2STR(addr, &dst.ipaddr);
+		IP2STR((char *)addr, &dst.ipaddr);
 		syslog(LOG_NOTICE, "disconnected: %s.%d", addr, dst.portno);
 		}
@@ -326,5 +330,5 @@
 			return serial_rea_dat(portid, buf, len);
 			}
-		dly_tsk(500);
+		dly_tsk(500000);
 		}
 	return off;
@@ -423,5 +427,51 @@
 	}
 
-#ifdef SUPPORT_INET4
+/*
+ *  ipv6addr -- IPv6 アドレス出力
+ */
+
+int_t
+put_ipv6addr (ID cepid, const T_IN6_ADDR *addr, int_t width)
+{
+	int_t	len = 0, ix;
+	bool_t	omit = false, zero = false;
+
+	if (addr == NULL) {
+		put_char(cepid, '0');
+		put_char(cepid, ':');
+		put_char(cepid, ':');
+		put_char(cepid, '0');
+		len = 4;
+		}
+	else {
+		for (ix = 0; ix < sizeof(T_IN6_ADDR) / 2; ix ++) {
+			if (omit) {
+				len += put_num(cepid, addr->s6_addr16[ix], 16, radhex, 0, false, ' '); 
+				if (ix < 7) {
+					put_char(cepid, ':');
+					len ++;
+					}
+				}
+			else if (ix > 0 && ix < 7 && addr->s6_addr16[ix] == 0)
+				zero = true;
+			else {
+				if (zero) {
+					omit = true;
+					put_char(cepid, ':');
+					len ++;
+					}
+				len += put_num(cepid, addr->s6_addr16[ix], 16, radhex, 0, false, ' '); 
+				if (ix < 7) {
+					put_char(cepid, ':');
+					len ++;
+					}
+				}
+			}
+
+		for ( ; len < width; len ++)
+			put_char(cepid, ' ');
+		}
+	return len;
+	}
 
 /*
@@ -429,5 +479,5 @@
  */
 
-static int_t
+int_t
 put_ipv4addr (ID cepid, ULONGEST *addr, int_t width)
 {
@@ -462,62 +512,4 @@
 	}
 
-#define PUT_IPADDR(p,a,w)	put_ipv4addr(p,a,w)
-
-#endif	/* of #ifdef SUPPORT_INET4 */
-
-#ifdef SUPPORT_INET6
-
-/*
- *  ipv6addr -- IPv6 アドレス出力
- */
-
-static int_t
-put_ipv6addr (ID cepid, const T_IN6_ADDR *addr, int_t width)
-{
-	int_t	len = 0, ix;
-	bool_t	omit = false, zero = false;
-
-	if (addr == NULL) {
-		put_char(cepid, '0');
-		put_char(cepid, ':');
-		put_char(cepid, ':');
-		put_char(cepid, '0');
-		len = 4;
-		}
-	else {
-		for (ix = 0; ix < sizeof(T_IN6_ADDR) / 2; ix ++) {
-			if (omit) {
-				len += put_num(cepid, addr->s6_addr16[ix], 16, radhex, 0, false, ' '); 
-				if (ix < 7) {
-					put_char(cepid, ':');
-					len ++;
-					}
-				}
-			else if (ix > 0 && ix < 7 && addr->s6_addr16[ix] == 0)
-				zero = true;
-			else {
-				if (zero) {
-					omit = true;
-					put_char(cepid, ':');
-					len ++;
-					}
-				len += put_num(cepid, addr->s6_addr16[ix], 16, radhex, 0, false, ' '); 
-				if (ix < 7) {
-					put_char(cepid, ':');
-					len ++;
-					}
-				}
-			}
-
-		for ( ; len < width; len ++)
-			put_char(cepid, ' ');
-		}
-	return len;
-	}
-
-#define PUT_IPADDR(p,a,w)	put_ipv6addr(p,a,w)
-
-#endif	/* of #ifdef SUPPORT_INET6 */
-
 /*
  *  put_macaddr -- MAC アドレス出力
@@ -586,5 +578,5 @@
 	va_list	ap;
 	char	padchar, *str;
-	int_t	ch, width, longflag, left, i, c;
+	int_t	ch, width, longflag, shortflag, left, i, c;
 
 	if (connected) {
@@ -597,5 +589,5 @@
 				}
 
-			width = longflag = 0;
+			width = longflag = shortflag = 0;
 			padchar = ' ';
 
@@ -619,4 +611,9 @@
 			while (ch == 'l') {		/* long (long) の指定 */
 				longflag ++;
+				ch = *format ++;
+				}
+
+			while (ch == 'h') {		/* short の指定 */
+				shortflag ++;
 				ch = *format ++;
 				}
@@ -663,17 +660,31 @@
 			case 'I':
 
+				if (longflag) {
+					str = va_arg(ap, char*);
+					put_ipv6addr(TCP_CEPID, (T_IN6_ADDR *)str, width);
+					}
+				else if (shortflag) {
+					val = GET_ARG(ap, longflag);
+					put_ipv4addr(TCP_CEPID, (ULONGEST *)val, width);
+					}
+				else {
+
+#ifdef SUPPORT_INET6
+
+					str = va_arg(ap, char*);
+					put_ipv6addr(TCP_CEPID, (T_IN6_ADDR *)str, width);
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
 #ifdef SUPPORT_INET4
 
-				val = GET_ARG(ap, longflag);
-				put_ipv4addr(TCP_CEPID, (ULONGEST *)val, width);
+					val = GET_ARG(ap, longflag);
+					put_ipv4addr(TCP_CEPID, (ULONGEST *)val, width);
 
 #endif	/* of #ifdef SUPPORT_INET4 */
 
-#ifdef SUPPORT_INET6
-
-				str = va_arg(ap, char*);
-				put_ipv6addr(TCP_CEPID, (T_IN6_ADDR *)str, width);
-
 #endif	/* of #ifdef SUPPORT_INET6 */
+
+					}
 
 				break;
@@ -701,5 +712,5 @@
 		flush_snd_buff(TCP_CEPID);
 		syscall(sig_sem(SEM_TCP_SYSLOG));
-		return E_OK;
+		return;
 		}
 	else {
@@ -714,11 +725,23 @@
 				}
 
+			longflag = 0;
 			c = *format++;
 			while ('0' <= c && c <= '9') {
 				c = *format++;
 				}
+
+			while (c == 'l') {
+				longflag = 1;
+				c = *format++;
+			}
+
 			switch (c) {
 			case 'd':
-				log.logpar[i++] = (intptr_t)va_arg(ap, int_t);
+				if(longflag == 1) {
+					log.logpar[i++] = (intptr_t)va_arg(ap, long_t);
+				}
+				else {
+					log.logpar[i++] = (intptr_t)va_arg(ap, int_t);
+				}
 				break;
 			case 'u':
Index: EcnlProtoTool/trunk/asp3_dcre/sample/sample1n.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/sample/sample1n.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/sample/sample1n.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2012 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -61,5 +61,5 @@
 /*  ネットワーク対応化関数  */
 
-extern void net_syslog(uint_t prio, const char *format, ...) throw();
+extern void	net_syslog(uint_t prio, const char *format, ...) throw();
 extern ER_UINT	net_serial_rea_dat(ID portid, char *buf, uint_t len) throw();
 extern ER	net_serial_ctl_por(ID portid, uint_t ioctl) throw();
Index: EcnlProtoTool/trunk/asp3_dcre/sample/tinet_app_config.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/sample/tinet_app_config.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/sample/tinet_app_config.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2012 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -62,12 +62,4 @@
 
 /*
- *  TCPの能動オープンのみサポートすることを指定する。
- */
-
-#ifdef UNDEF_TCP_CFG_PASSIVE_OPEN
-#undef TCP_CFG_PASSIVE_OPEN
-#endif
-
-/*
  *  TCP 通信端点の送受信ウィンドバッファの省コピー機能
  *    注意: Makefile で指定している。
@@ -97,11 +89,15 @@
 #ifdef USE_TCP_MSS_SEG
 
+#ifdef SUPPORT_INET6
+
+#define TCP_CFG_SWBUF_CSAVE_MAX_SIZE	(IF_HDR_SIZE + IPV6_MMTU)	/* 最大サイズ */
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
 #ifdef SUPPORT_INET4
 #define TCP_CFG_SWBUF_CSAVE_MAX_SIZE	(IF_HDR_SIZE + IP4_MSS)		/* 最大サイズ */
 #endif
 
-#ifdef SUPPORT_INET6
-#define TCP_CFG_SWBUF_CSAVE_MAX_SIZE	(IF_HDR_SIZE + IPV6_MMTU)	/* 最大サイズ */
-#endif
+#endif	/* of #ifdef SUPPORT_INET6 */
 
 #else	/* of #ifdef USE_TCP_MSS_SEG */
@@ -134,11 +130,15 @@
 #endif
 
+#ifdef SUPPORT_INET6
+
+#define MAX_TCP_SND_SEG			TCP6_MSS
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
 #ifdef SUPPORT_INET4
 #define MAX_TCP_SND_SEG			TCP_MSS
 #endif
 
-#ifdef SUPPORT_INET6
-#define MAX_TCP_SND_SEG			TCP6_MSS
-#endif
+#endif	/* of #ifdef SUPPORT_INET6 */
 
 #endif	/* of #ifdef USE_TCP_MSS_SEG */
@@ -154,11 +154,15 @@
 #endif
 
+#ifdef SUPPORT_INET6
+
+#define DEF_TCP_RCV_SEG			TCP6_MSS
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
 #ifdef SUPPORT_INET4
 #define DEF_TCP_RCV_SEG			TCP_MSS
 #endif
 
-#ifdef SUPPORT_INET6
-#define DEF_TCP_RCV_SEG			TCP6_MSS
-#endif
+#endif	/* of #ifdef SUPPORT_INET6 */
 
 #endif	/* of #ifdef USE_TCP_MSS_SEG */
@@ -232,7 +236,28 @@
 //#define UDP_CFG_EXTENTIONS
 
+/* IPv6 に関する定義 */
+
+#ifdef SUPPORT_PPP
+
+#define NUM_IN6_STATIC_ROUTE_ENTRY	0
+#define NUM_IN6_REDIRECT_ROUTE_ENTRY	0
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#ifdef SUPPORT_LOOP
+
+#define NUM_IN6_STATIC_ROUTE_ENTRY	0
+#define NUM_IN6_REDIRECT_ROUTE_ENTRY	0
+
+#endif	/* of #ifdef SUPPORT_LOOP */
+
+#ifdef SUPPORT_ETHER
+
+#define NUM_IN6_STATIC_ROUTE_ENTRY	0
+#define NUM_IN6_REDIRECT_ROUTE_ENTRY	1
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
 /* IPv4 に関する定義 */
-
-#ifdef SUPPORT_INET4
 
 #ifdef SUPPORT_PPP
@@ -250,6 +275,6 @@
 #endif
 
-#define NUM_STATIC_ROUTE_ENTRY		1
-#define NUM_REDIRECT_ROUTE_ENTRY	0
+#define NUM_IN4_STATIC_ROUTE_ENTRY	1
+#define NUM_IN4_REDIRECT_ROUTE_ENTRY	0
 
 #endif	/* of #ifdef SUPPORT_PPP */
@@ -257,5 +282,5 @@
 #ifdef SUPPORT_ETHER
 
-#ifdef DHCP_CFG
+#ifdef DHCP4_CLI_CFG
 
 #define IPV4_ADDR_LOCAL			MAKE_IPV4_ADDR(0,0,0,0)
@@ -263,14 +288,14 @@
 #define IPV4_ADDR_DEFAULT_GW		MAKE_IPV4_ADDR(0,0,0,0)
 
-#else	/* of #ifdef DHCP_CFG */
-
-#define IPV4_ADDR_LOCAL			MAKE_IPV4_ADDR(172,25,129,205)
+#else	/* of #ifdef DHCP4_CLI_CFG */
+
+#define IPV4_ADDR_LOCAL			MAKE_IPV4_ADDR(172,25,129,200)
 #define IPV4_ADDR_LOCAL_MASK		MAKE_IPV4_ADDR(255,255,255,0)
 #define IPV4_ADDR_DEFAULT_GW		MAKE_IPV4_ADDR(172,25,129,140)
 
-#endif	/* of #ifdef DHCP_CFG */
-
-#define NUM_STATIC_ROUTE_ENTRY		3
-#define NUM_REDIRECT_ROUTE_ENTRY	1
+#endif	/* of #ifdef DHCP4_CLI_CFG */
+
+#define NUM_IN4_STATIC_ROUTE_ENTRY	3
+#define NUM_IN4_REDIRECT_ROUTE_ENTRY	1
 
 #endif	/* of #ifdef SUPPORT_ETHER */
@@ -278,37 +303,8 @@
 #ifdef SUPPORT_LOOP
 
-#define NUM_STATIC_ROUTE_ENTRY		1
-#define NUM_REDIRECT_ROUTE_ENTRY	0
+#define NUM_IN4_STATIC_ROUTE_ENTRY	1
+#define NUM_IN4_REDIRECT_ROUTE_ENTRY	0
 
 #endif	/* of #ifdef SUPPORT_LOOP */
-
-#endif	/* of #ifdef SUPPORT_INET4 */
-
-/* IPv6 に関する定義 */
-
-#ifdef SUPPORT_INET6
-
-#ifdef SUPPORT_PPP
-
-#define NUM_STATIC_ROUTE_ENTRY		0
-#define NUM_REDIRECT_ROUTE_ENTRY	0
-
-#endif	/* of #ifdef SUPPORT_PPP */
-
-#ifdef SUPPORT_LOOP
-
-#define NUM_STATIC_ROUTE_ENTRY		0
-#define NUM_REDIRECT_ROUTE_ENTRY	0
-
-#endif	/* of #ifdef SUPPORT_LOOP */
-
-#ifdef SUPPORT_ETHER
-
-#define NUM_STATIC_ROUTE_ENTRY		0
-#define NUM_REDIRECT_ROUTE_ENTRY	1
-
-#endif	/* of #ifdef SUPPORT_ETHER */
-
-#endif	/* of #ifdef SUPPORT_INET6 */
 
 /*
@@ -417,5 +413,5 @@
  *    IPv6 でのみ割り当てる。
  *
- *    NE2000 互換 NIC のディバイスドライバ（if_ed）の最低割当て長は、
+ *    MBED Ethernet Controler のディバイスドライバ（if_mbed）の最低割当て長は、
  *    イーサネットフレームの最短長である 60（CRC の 4 オクテットを除き、
  *    更にアラインして 62）オクテットである。
@@ -579,7 +575,7 @@
 
 #if (defined(TCP_CFG_RWBUF_CSAVE) || defined(TCP_CFG_SWBUF_CSAVE)) && defined(USE_COPYSAVE_API)
-#define NUM_MPF_NET_BUF_IF_PDU		6
-#else
-#define NUM_MPF_NET_BUF_IF_PDU		5
+#define NUM_MPF_NET_BUF_IF_PDU		9
+#else
+#define NUM_MPF_NET_BUF_IF_PDU		8
 #endif
 
@@ -614,3 +610,38 @@
 #endif	/* of #ifdef SUPPORT_ETHER */
 
+/*
+ *  DNS サーバに関する定義
+ */
+
+/* DNS サーバの IP アドレス */
+
+#if !defined(DHCP6_CLI_CFG)
+
+#define IPV6_ADDR_DNS_INIT	\
+	{{{ UINT_C(0xfd), UINT_C(0x90), UINT_C(0xcc), UINT_C(0xe5), \
+	    UINT_C(0x25), UINT_C(0xf6), UINT_C(0xff), UINT_C(0x81), \
+	    UINT_C(0x02), UINT_C(0xa0), UINT_C(0x24), UINT_C(0xff), \
+	    UINT_C(0xfe), UINT_C(0x56), UINT_C(0xc5), UINT_C(0xd6) }}}
+
+#endif	/* of #if !defined(DHCP6_CLI_CFG) */
+
+#if !defined(DHCP4_CLI_CFG)
+#define IPV4_ADDR_DNS		MAKE_IPV4_ADDR(172,25,129,140)
+#endif
+
+/* DOMAIN 名 */
+
+#if !(defined(DHCP4_CLI_CFG) || defined(DHCP6_CLI_CFG))
+#define RSLV_CFG_DNS_DOMAIN_NAME_STR	"jo.tomakomai-ct.ac.jp"
+#endif
+
+/*
+ *  DHCP クライアントに関する定義
+ */
+
+/* DHCPv6 の動作モードの設定 */
+
+#define DHCP6_CLI_CFG_MODE	DHCP6_CLI_CFG_STATELESS
+//#define DHCP6_CLI_CFG_MODE	DHCP6_CLI_CFG_STATEFULL
+
 #endif /* _TINET_APP_CONFIG_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/sample/tinet_sample1n.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/sample/tinet_sample1n.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/sample/tinet_sample1n.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2012 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -40,4 +40,10 @@
 /* TCP 受付口 */
 
+#ifdef SUPPORT_INET6
+
+TCP6_CRE_REP (TCP_REPID, { 0, { IPV6_ADDRANY, 23 } } );
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
 #ifdef SUPPORT_INET4
 
@@ -46,11 +52,20 @@
 #endif	/* of #ifdef SUPPORT_INET4 */
 
-#ifdef SUPPORT_INET6
-
-TCP6_CRE_REP (TCP_REPID, { 0, { IPV6_ADDRANY, 23 } } );
-
 #endif	/* of #ifdef SUPPORT_INET6 */
 
 /* TCP 通信端点 */
+
+#ifdef SUPPORT_INET6
+
+TCP6_CRE_CEP (TCP_CEPID, {
+	0,
+	tcp_swbuf,
+	TCP_SWBUF_SIZE,
+	tcp_rwbuf,
+	TCP_RWBUF_SIZE,
+	(FP)callback_nblk_tcp
+	} );
+
+#else	/* of #ifdef SUPPORT_INET6 */
 
 #ifdef SUPPORT_INET4
@@ -67,14 +82,3 @@
 #endif	/* of #ifdef SUPPORT_INET4 */
 
-#ifdef SUPPORT_INET6
-
-TCP6_CRE_CEP (TCP_CEPID, {
-	0,
-	tcp_swbuf,
-	TCP_SWBUF_SIZE,
-	tcp_rwbuf,
-	TCP_RWBUF_SIZE,
-	(FP)callback_nblk_tcp
-	} );
-
 #endif	/* of #ifdef SUPPORT_INET6 */
Index: EcnlProtoTool/trunk/asp3_dcre/target/gr_peach_gcc/target_user.txt
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/target/gr_peach_gcc/target_user.txt	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/target/gr_peach_gcc/target_user.txt	(revision 331)
@@ -46,5 +46,5 @@
  の責任を負わない．
  
- $Id$
+ $Id: target_user.txt 1145 2017-02-06 04:26:43Z coas-nagasima $
 ----------------------------------------------------------------------
 
Index: EcnlProtoTool/trunk/asp3_dcre/target/gr_peach_gcc/tinet_target_config.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/target/gr_peach_gcc/tinet_target_config.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/target/gr_peach_gcc/tinet_target_config.h	(revision 331)
@@ -425,4 +425,51 @@
 #if 1
 
+#ifdef SUPPORT_INET6
+
+#ifdef SUPPORT_INET4
+
+#define NET_COUNT_ENABLE	(0			\
+				| PROTO_FLG_PPP_HDLC	\
+				| PROTO_FLG_PPP_PAP	\
+				| PROTO_FLG_PPP_LCP	\
+				| PROTO_FLG_PPP_IPCP	\
+				| PROTO_FLG_PPP		\
+				| PROTO_FLG_LOOP	\
+				| PROTO_FLG_ETHER_NIC	\
+				| PROTO_FLG_ETHER	\
+				| PROTO_FLG_IP6		\
+				| PROTO_FLG_ICMP6	\
+				| PROTO_FLG_ND6		\
+				| PROTO_FLG_ARP		\
+				| PROTO_FLG_IP4		\
+				| PROTO_FLG_ICMP4	\
+				| PROTO_FLG_TCP		\
+				| PROTO_FLG_UDP		\
+				| PROTO_FLG_NET_BUF	\
+				)
+
+#else	/* of #ifdef SUPPORT_INET4 */
+
+#define NET_COUNT_ENABLE	(0			\
+				| PROTO_FLG_PPP_HDLC	\
+				| PROTO_FLG_PPP_PAP	\
+				| PROTO_FLG_PPP_LCP	\
+				| PROTO_FLG_PPP_IPCP	\
+				| PROTO_FLG_PPP		\
+				| PROTO_FLG_LOOP	\
+				| PROTO_FLG_ETHER_NIC	\
+				| PROTO_FLG_ETHER	\
+				| PROTO_FLG_IP6		\
+				| PROTO_FLG_ICMP6	\
+				| PROTO_FLG_ND6		\
+				| PROTO_FLG_TCP		\
+				| PROTO_FLG_UDP		\
+				| PROTO_FLG_NET_BUF	\
+				)
+
+#endif	/* of #ifdef SUPPORT_INET4 */
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
 #ifdef SUPPORT_INET4
 
@@ -439,6 +486,6 @@
 				| PROTO_FLG_IP4		\
 				| PROTO_FLG_ICMP4	\
+				| PROTO_FLG_TCP		\
 				| PROTO_FLG_UDP		\
-				| PROTO_FLG_TCP		\
 				| PROTO_FLG_NET_BUF	\
 				)
@@ -446,23 +493,4 @@
 #endif	/* of #ifdef SUPPORT_INET4 */
 
-#ifdef SUPPORT_INET6
-
-#define NET_COUNT_ENABLE	(0			\
-				| PROTO_FLG_PPP_HDLC	\
-				| PROTO_FLG_PPP_PAP	\
-				| PROTO_FLG_PPP_LCP	\
-				| PROTO_FLG_PPP_IPCP	\
-				| PROTO_FLG_PPP		\
-				| PROTO_FLG_LOOP	\
-				| PROTO_FLG_ETHER_NIC	\
-				| PROTO_FLG_ETHER	\
-				| PROTO_FLG_IP6		\
-				| PROTO_FLG_ICMP6	\
-				| PROTO_FLG_ND6		\
-				| PROTO_FLG_UDP		\
-				| PROTO_FLG_TCP		\
-				| PROTO_FLG_NET_BUF	\
-				)
-
 #endif	/* of #ifdef SUPPORT_INET6 */
 
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/Makefile.config
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/Makefile.config	(revision 321)
+++ 	(revision )
@@ -1,179 +1,0 @@
-#
-#   TINET (TCP/IP Protocol Stack)
-#  
-#   Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
-#                    Tomakomai National College of Technology, JAPAN
-# 
-#   上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
-#   によって公表されている GNU General Public License の Version 2 に記
-#   述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
-#   を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
-#   利用と呼ぶ）することを無償で許諾する．
-#   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
-#       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
-#       スコード中に含まれていること．
-#   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
-#       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
-#       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
-#       の無保証規定を掲載すること．
-#   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
-#       用できない形で再配布する場合には，次の条件を満たすこと．
-#     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
-#         作権表示，この利用条件および下記の無保証規定を掲載すること．
-#   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
-#       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
-# 
-#   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
-#   よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
-#   含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
-#   接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
-#  
-#   @(#) $Id$
-#
-
-#
-#  「ソースファイルのディレクトリの定義」の後に追加する。
-#
-
-#
-#  TINET ソースファイルのディレクトリの定義
-#
-TINET_ROOT = $(SRCDIR)/tinet
-
-#
-#  TINET 1.1 との互換性のための定義
-#
-ifndef SUPPORT_INET4
-	ifndef SUPPORT_INET6
-		SUPPORT_INET4 = true
-	endif
-endif
-
-#
-#  ネットワークサービスに関する定義
-#
-TINET_DIR = $(TINET_ROOT)/net:$(TINET_ROOT)/netinet
-
-TINET_COBJS := $(TINET_COBJS) \
-	       net_buf.o net_count.o net_subr.o net_timer.o \
-               in_subr.o tinet_cfg.o route_cfg.o
-
-ifeq ($(SUPPORT_INET4),true)
-
-	TINET_COBJS := $(TINET_COBJS) \
-	               ip_input.o ip_output.o ip_icmp.o
-	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_INET4
-
-endif
-
-ifeq ($(SUPPORT_INET6),true)
-
-	TINET_DIR := $(TINET_DIR):$(TINET_ROOT)/netinet6
-	TINET_COBJS := $(TINET_COBJS) \
-	               in6.o in6_ifattach.o nd6_rtr.o \
-	               in6_subr.o ip6_input.o icmp6.o \
-	               dest6.o route6.o frag6.o \
-	               ah_input.o esp_input.o \
-	               nd6.o nd6_nbr.o ip6_output.o
-	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_INET6
-
-endif
-
-ifeq ($(NET_IF),loop)
-
-	TINET_COBJS := $(TINET_COBJS) if_loop.o
-	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_LOOP
-
-endif
-
-ifeq ($(NET_IF),ppp)
-
-	TINET_COBJS := $(TINET_COBJS) \
-	               ppp.o ppp_hdlc.o ppp_lcp.o ppp_fsm.o \
-	               ppp_auth.o ppp_ipcp.o ppp_upap.o
-	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_PPP
-
-ifeq ($(PPP_CFG_MODEM),true)
-
-	TINET_COBJS := $(TINET_COBJS) ppp_modem.o 
-	TINET_CDEFS := $(TINET_CDEFS) -DPPP_CFG_MODEM
-
-endif
-
-endif
-
-ifeq ($(NET_IF),ether)
-
-	#  ターゲット依存の定義のインクルード
-
-	ifdef TOOL
-	    ifdef SYS
-	        -include $(SRCDIR)/config/$(CPU)-$(TOOL)/$(SYS)/Makefile.tinet
-	    endif
-	else
-	    ifdef SYS
-	        -include $(SRCDIR)/config/$(CPU)/$(SYS)/Makefile.tinet
-	    endif
-	endif
-
-	TINET_COBJS := $(TINET_COBJS) if.o ethernet.o
-	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_ETHER
-
-	ifeq ($(SUPPORT_INET4),true)
-
-		TINET_COBJS := $(TINET_COBJS) if_ether.o
-
-	endif
-
-	ifeq ($(SUPPORT_INET6),true)
-
-		TINET_COBJS := $(TINET_COBJS) if6_ether.o 
-
-	endif
-
-	include $(TINET_ROOT)/netdev/$(NET_DEV)/Makefile.tinet
-
-endif
-
-ifeq ($(SUPPORT_TCP),true)
-
-	TINET_COBJS := $(TINET_COBJS) \
-	               tcp_input.o tcp_output.o tcp_usrreq.o \
-	               tcp_subr.o tcp_timer.o tcp_subr_ncs.o
-	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_TCP
-
-endif
-
-ifeq ($(SUPPORT_UDP),true)
-
-	TINET_COBJS := $(TINET_COBJS) \
-	               udp_input.o udp_usrreq.o udp_output.o
-	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_UDP
-
-endif
-
-#
-#  共通コンパイルオプションの定義への追加
-#
-CDEFS := $(CDEFS) $(TINET_CDEFS)
-INCLUDES := $(INCLUDES) -I$(TINET_ROOT)
-
-#
-#  アプリケーションプログラムに関する定義への追加
-#
-TINET_UTASK_CFG = tinet_$(UNAME).cfg
-
-#
-#  システムサービスに関する定義への追加
-#
-STASK_DIR := $(STASK_DIR):$(TINET_DIR)
-STASK_COBJS := $(STASK_COBJS) $(TINET_COBJS)
-STASK_LIBS := $(STASK_LIBS) -lc
-
-#
-#  TINET コンフィギュレーションファイルの生成
-#
-tinet:
-	$(CC) -E $(INCLUDES) $(CDEFS) -x c-header $(TINET_UTASK_CFG) > tmpfile9
-	$(TINET_ROOT)/cfg/tinet_cfg -s tmpfile9
-	rm -f tmpfile9
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/Makefile.tinet
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/Makefile.tinet	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/Makefile.tinet	(revision 331)
@@ -2,5 +2,5 @@
 #   TINET (TCP/IP Protocol Stack)
 #  
-#   Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+#   Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
 #                    Tomakomai National College of Technology, JAPAN
 #   Copyright (C) 2008-2009 by Hokkaido Industrial Research Institute, JAPAN
@@ -63,34 +63,52 @@
 
 #
+#  TINET 1.7 以降は、ネットワーク層の指定を変更した。
+#
+
+ifeq ($(SUPPORT_INET6),true)
+	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_INET6
+endif
+
+ifeq ($(SUPPORT_INET4),true)
+	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_INET4
+endif
+
+ifeq ($API_CFG_IP4MAPPED_ADDR,true)
+	TINET_CDEFS := $(TINET_CDEFS) -DAPI_CFG_IP4MAPPED_ADDR
+endif
+
+ifeq ($(SUPPORT_IGMP),true)
+	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_IGMP
+endif
+
+#
 #  ネットワークサービスに関する定義
 #
-TINET_DIR = $(TINET_ROOT)/net:$(TINET_ROOT)/netinet
-
+
+#  汎用通信機能
+
+TINET_DIRS = $(TINET_ROOT)/net:$(TINET_ROOT)/netinet:$(TINET_ROOT)/netinet6
 TINET_COBJS := $(TINET_COBJS) \
-	       net_buf.o net_count.o net_subr.o net_timer.o \
-               in_subr.o tinet_cfg.o route_cfg.o
-
-ifeq ($(SUPPORT_INET4),true)
-
-	TINET_COBJS := $(TINET_COBJS) \
-	               ip_input.o ip_output.o ip_icmp.o
-	TINET_KERNEL_CFG := $(TINET_KERNEL_CFG) $(TINET_ROOT)/netinet/ip.cfg
-	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_INET4
-
-endif
-
-ifeq ($(SUPPORT_INET6),true)
-
-	TINET_DIR := $(TINET_DIR):$(TINET_ROOT)/netinet6
-	TINET_COBJS := $(TINET_COBJS) \
-	               in6.o in6_ifattach.o nd6_rtr.o \
-	               in6_subr.o ip6_input.o icmp6.o \
-	               dest6.o route6.o frag6.o \
-	               ah_input.o esp_input.o \
-	               nd6.o nd6_nbr.o ip6_output.o scope6.o
-	TINET_KERNEL_CFG := $(TINET_KERNEL_CFG) $(TINET_ROOT)/netinet6/ip6.cfg
-	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_INET6
-
-endif
+               net_buf.o net_count.o net_subr.o net_timer.o if.o \
+               in_subr.o route_cfg.o
+TINET_CFG_COBJS := $(TINET_CFG_COBJS) tinet_cfg.o
+
+#  IPv6
+
+TINET_COBJS := $(TINET_COBJS) \
+               in6.o in6_ifattach.o nd6_rtr.o \
+               in6_subr.o ip6_input.o icmp6.o \
+               dest6.o route6.o frag6.o \
+               ah_input.o esp_input.o \
+               nd6.o nd6_nbr.o ip6_output.o scope6.o
+TINET_KERNEL_CFG := $(TINET_KERNEL_CFG) $(TINET_ROOT)/netinet6/ip6.cfg
+
+#  IPv4
+
+TINET_COBJS := $(TINET_COBJS) \
+               ip_input.o ip_output.o ip_icmp.o ip_igmp.o in4_subr.o
+TINET_KERNEL_CFG := $(TINET_KERNEL_CFG) $(TINET_ROOT)/netinet/ip.cfg
+
+#  loop back
 
 ifeq ($(NET_IF),loop)
@@ -102,11 +120,19 @@
 endif
 
+#  ppp
+
 ifeq ($(NET_IF),ppp)
 
 	TINET_COBJS := $(TINET_COBJS) \
 	               ppp.o ppp_hdlc.o ppp_lcp.o ppp_fsm.o \
-	               ppp_auth.o ppp_ipcp.o ppp_upap.o
+	               ppp_auth.o ppp_upap.o
 	TINET_KERNEL_CFG := $(TINET_KERNEL_CFG) $(TINET_ROOT)/net/ppp.cfg
 	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_PPP
+
+#  IPv6用 cp
+	TINET_COBJS := $(TINET_COBJS) ppp_ipv6cp.o
+
+#  IPv4用 cp
+	TINET_COBJS := $(TINET_COBJS) ppp_ipcp.o
 
 ifeq ($(PPP_CFG_MODEM),true)
@@ -143,27 +169,18 @@
 endif
 
+#  ethernet
+
 ifeq ($(NET_IF),ether)
 
-	TINET_COBJS := $(TINET_COBJS) if.o ethernet.o
-	TINET_KERNEL_CFG := $(TINET_KERNEL_CFG) $(TINET_ROOT)/net/ethernet.cfg
+	TINET_COBJS := $(TINET_COBJS) ethernet.o if6_ether.o if_ether.o
+	TINET_KERNEL_CFG := $(TINET_KERNEL_CFG) \
+	                    $(TINET_ROOT)/net/ethernet.cfg \
+	                    $(TINET_ROOT)/netinet/if_ether.cfg
 	TINET_CDEFS := $(TINET_CDEFS) -DSUPPORT_ETHER
-
-	ifeq ($(SUPPORT_INET4),true)
-
-		TINET_COBJS := $(TINET_COBJS) if_ether.o
-		TINET_KERNEL_CFG := $(TINET_KERNEL_CFG) $(TINET_ROOT)/netinet/if_ether.cfg
-
-	endif
-
-	ifeq ($(SUPPORT_INET6),true)
-
-		TINET_COBJS := $(TINET_COBJS) if6_ether.o 
-
-	endif
-
-
 	include $(TINET_ROOT)/netdev/$(NET_DEV)/Makefile.tinet
 
 endif
+
+#  TCP
 
 ifeq ($(SUPPORT_TCP),true)
@@ -177,4 +194,6 @@
 endif
 
+#  UDP
+
 ifeq ($(SUPPORT_UDP),true)
 
@@ -193,13 +212,9 @@
 
 	ifeq ($(SUPPORT_TCP),true)
-
 		TINET_COBJS := $(TINET_COBJS) tcp_usrreq.o 
-
 	endif
 
 	ifeq ($(SUPPORT_UDP),true)
-
-		TINET_COBJS := $(TINET_COBJS) udp_usrreq.o
-
+		TINET_COBJS := $(TINET_COBJS) udp_usrreq.o udp_usrreq_nblk.o
 	endif
 
@@ -207,13 +222,9 @@
 
 	ifeq ($(SUPPORT_TCP),true)
-
 		TINET_LCSRCS := $(TINET_LCSRCS) tcp_usrreq.c 
-
 	endif
 
 	ifeq ($(SUPPORT_UDP),true)
-
-		TINET_LCSRCS := $(TINET_LCSRCS) udp_usrreq.c
-
+		TINET_LCSRCS := $(TINET_LCSRCS) udp_usrreq.c udp_usrreq_nblk.c
 	endif
 
@@ -248,8 +259,13 @@
 		tcp_set_opt.o tcp_get_opt.o
 
-udp_usrreq = 	udp_can_snd.o udp_can_rcv.o udp_can_cep.o \
-		udp_cre_cep.o udp_del_cep.o \
-		udp_snd_dat.o udp_rcv_dat.o udp_send_data.o \
-		udp_set_opt.o udp_get_opt.o
+udp_usrreq = 	udp_can_cep.o udp_send_data.o \
+		udp_can_snd.o udp_can_rcv.o \
+		udp_snd_dat.o udp_rcv_dat.o \
+		udp_set_opt.o udp_get_opt.o \
+		udp_cre_cep.o udp_del_cep.o
+
+udp_usrreq_nblk = \
+		udp_can_snd_nblk.o udp_can_rcv_nblk.o \
+		udp_snd_dat_nblk.o udp_rcv_dat_nblk.o
 
 #
@@ -257,6 +273,7 @@
 #  オブジェクトファイルの依存関係の定義
 #
-$(tcp_usrreq) $(tcp_usrreq:.o=.s) $(tcp_usrreq:.o=.d): tcp_usrreq.c
-$(udp_usrreq) $(udp_usrreq:.o=.s) $(udp_usrreq:.o=.d): udp_usrreq.c udp_usrreq_nblk.c
+$(tcp_usrreq) $(tcp_usrreq:.o=.s) $(tcp_usrreq:.o=.d): tcp_usrreq.c tcpn_usrreq.c
+$(udp_usrreq) $(udp_usrreq:.o=.s) $(udp_usrreq:.o=.d): udp_usrreq.c udpn_usrreq.c
+$(udp_usrreq_nblk) $(udp_usrreq_nblk:.o=.s) $(udp_usrreq_nblk:.o=.d): udp_usrreq_nblk.c
 
 #
@@ -271,6 +288,5 @@
 ifeq ($(TARGET_KERNEL),ASP)
 
-TINET_CFG = $(APPLDIR)/tinet_$(APPLNAME).cfg
-TINET_CFG_OUT = tinet_cfg.c tinet_cfg.h
+TINET_CFG_OUT = tinet_cfg.c tinet_cfg.h tinet_kern.cfg
 TINET_KERNEL_CFG :=	$(TINET_KERNEL_CFG) \
 			$(TINET_ROOT)/tinet_asp.cfg $(TINET_ROOT)/net/net_asp.cfg 
@@ -305,5 +321,5 @@
 ifeq ($(TARGET_KERNEL),ASP)
 
-	SYSSVC_DIRS := $(SYSSVC_DIRS):$(TINET_DIR)
+	SYSSVC_DIRS := $(SYSSVC_DIRS):$(TINET_DIRS)
 	SYSSVC_ASMOBJS := $(SYSSVC_ASMOBJS)
 	SYSSVC_COBJS := $(SYSSVC_COBJS) $(TINET_COBJS)
@@ -311,4 +327,6 @@
 	SYSSVC_LIBS := $(SYSSVC_LIBS) $(LIBTINET) -lc
 
+	CFG_COBJS := $(CFG_COBJS) $(TINET_CFG_COBJS)
+
 	CLEAN_FILES := $(CLEAN_FILES) $(TINET_CFG_OUT) $(MAKE_TINET_LIB)
 
@@ -319,5 +337,5 @@
 	MTASK_CFG := $(MTASK_CFG) $(TINET_CFG)
 	MTASK_KERNEL_CFG := $(MTASK_KERNEL_CFG) $(TINET_KERNEL_CFG)
-	MTASK_DIR := $(MTASK_DIR):$(TINET_DIR)
+	MTASK_DIR := $(MTASK_DIRS):$(TINET_DIRS)
 	MTASK_LCSRCS := $(MTASK_LCSRCS) $(TINET_LCSRCS)
 	MTASK_ASMOBJS := $(MTASK_ASMOBJS)
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ether_var.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ether_var.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ether_var.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ethernet.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ethernet.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ethernet.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -63,4 +63,5 @@
 #include <net/if_arp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_var.h>
 #include <net/net_buf.h>
@@ -71,9 +72,9 @@
 #include <netinet/in_var.h>
 #include <netinet/if_ether.h>
+
 #include <netinet6/if6_ether.h>
 #include <netinet6/nd6.h>
 
 #include <net/if_var.h>
-#include <net/if6_var.h>
 
 #ifdef SUPPORT_ETHER
@@ -83,5 +84,5 @@
  */
 
-#if defined(SUPPORT_INET4)
+#if defined(_IP4_CFG)
 
 const uint8_t ether_broad_cast_addr[ETHER_ADDR_LEN] = {
@@ -90,5 +91,5 @@
 	};
 
-#endif	/* of #if defined(SUPPORT_INET4) */
+#endif	/* of #if defined(_IP4_CFG) */
 
 /*
@@ -98,32 +99,9 @@
 /* ネットワークインタフェース構造体 */
 
-#if defined(SUPPORT_INET4)
-
-static T_IFNET ether_ifnet = {
-	NULL,			/* ネットワークインタフェースのソフトウェア情報	*/
-	{
-		IPV4_ADDR_LOCAL,	/* IPv4 アドレス		*/
-		IPV4_ADDR_LOCAL_MASK,	/* サブネットマスク		*/
-		},
-	};
-
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
-
-static T_IFNET ether_ifnet = {
-	NULL,			/* ネットワークインタフェースのソフトウェア情報	*/
-	{0},			/* IPv6 アドレス情報				*/
-	{0},			/* マルチキャスト IPv6 アドレス			*/
-	0,				/* フラグ					*/
-	};
-
-#endif	/* of #if defined(SUPPORT_INET6) */
+static T_IFNET ether_ifnet;
 
 #ifdef SUPPORT_MIB
 
-/*
- *  SNMP の 管理情報ベース (MIB)
- */
+/*  SNMP の 管理情報ベース (MIB) */
 
 T_IF_STATS if_stats;
@@ -158,4 +136,32 @@
 
 /*
+ *  ether_srand -- 乱数を初期値を返す。
+ */
+
+uint32_t
+ether_srand (void)
+{
+	T_IF_SOFTC	*ic;
+	uint32_t	rval;
+
+	ic = IF_ETHER_NIC_GET_SOFTC();
+	rval  = (ic->ifaddr.lladdr[2] << 24)
+	      + (ic->ifaddr.lladdr[3] << 16)
+	      + (ic->ifaddr.lladdr[4] <<  8)
+	      + (ic->ifaddr.lladdr[5]      );
+
+#ifdef ETHER_CFG_COLLECT_ADDR
+
+	rval += (ether_collect_addr.lladdr[2] << 24)
+	      + (ether_collect_addr.lladdr[3] << 16)
+	      + (ether_collect_addr.lladdr[4] <<  8)
+	      + (ether_collect_addr.lladdr[5]      );
+
+#endif	/* of #ifdef ETHER_CFG_COLLECT_ADDR */
+
+	return rval;
+	}
+
+/*
  *  ether_get_ifnet -- ネットワークインタフェース構造体を返す。
  */
@@ -167,5 +173,5 @@
 	}
 
-#if defined(SUPPORT_INET6)
+#if defined(_IP6_CFG)
 
 /*
@@ -174,5 +180,5 @@
 
 ER
-ether_in6_resolve_multicast (T_ETHER_ADDR *ifaddr, T_IN6_ADDR *maddr)
+ether_in6_resolve_multicast (T_ETHER_ADDR *ifaddr, const T_IN6_ADDR *maddr)
 {
 	/* マルチキャストアドレスかチェックする。*/
@@ -186,5 +192,5 @@
 	}
 
-#endif	/* of #if defined(SUPPORT_INET6) */
+#endif	/* of #if defined(_IP6_CFG) */
 
 /**
@@ -203,4 +209,11 @@
       }
 #endif /* LWIP_ARP */
+
+#if LWIP_IGMP
+      /* resend IGMP memberships */
+      if (ether->_flags & IF_FLAG_IGMP) {
+        igmp_report_groups(ether);
+      }
+#endif /* LWIP_IGMP */
     }
     if (ether->link_callback) {
@@ -262,5 +275,5 @@
 
 ER
-ether_output (T_NET_BUF *output, void *dst, T_IF_ADDR *gw, TMO tmout)
+ether_output (T_NET_BUF *output, const void *dst, T_IF_ADDR *gw, TMO tmout)
 {
 	T_IF_SOFTC	*ic;
@@ -275,5 +288,5 @@
 	switch(ntohs(eth->type)) {
 
-#if defined(SUPPORT_INET4)
+#if defined(_IP4_CFG)
 
 	case ETHER_TYPE_IP:		/* IPv4	*/
@@ -292,11 +305,11 @@
 		break;
 
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
+#endif	/* of #if defined(_IP4_CFG) */
+
+#if defined(_IP6_CFG)
 
 	case ETHER_TYPE_IPV6:		/* IPv6	*/
-		error = nd6_storelladdr((T_ETHER_ADDR*)GET_ETHER_HDR(output)->dhost,
-		                        (T_IN6_ADDR*)dst, gw);
+		error = nd6_storelladdr((T_ETHER_ADDR*)eth->dhost,
+		                        (const T_IN6_ADDR*)dst, gw);
 		if (error == E_OK)
 			error = ether_raw_output(output, tmout);
@@ -311,5 +324,5 @@
 		break;
 
-#endif	/* of #if defined(SUPPORT_INET6) */
+#endif	/* of #if defined(_IP6_CFG) */
 
 	default:
@@ -398,7 +411,17 @@
 	ID		tskid;
 	uint16_t	proto;
+	uint8_t		rcount = 0;
 
 	/* ネットワークインタフェース管理を初期化する。*/
 	ifinit();
+
+	/* イーサネットネットワークインタフェース管理を初期化する。*/
+
+#if defined(_IP4_CFG)
+
+	ether_ifnet.in4_ifaddr.addr = IPV4_ADDR_LOCAL;		/* IPv4 アドレス		*/
+	ether_ifnet.in4_ifaddr.mask = IPV4_ADDR_LOCAL_MASK;	/* サブネットマスク		*/
+
+#endif	/* of #if defined(_IP4_CFG) */
 
 	/* NIC を初期化する。*/
@@ -418,17 +441,20 @@
 	                   tskid, mac2str(NULL, ic->ifaddr.lladdr));
 
-#if defined(SUPPORT_INET4)
+#if defined(_IP4_CFG)
 
 	/* ARP を初期化する。*/
 	arp_init();
 
-#endif	/* of #if defined(SUPPORT_INET4) */
+#endif	/* of #if defined(_IP4_CFG) */
 
 	ether_ifnet.ic = ic;
+
+	/* 乱数生成を初期化する。*/
+	net_srand(0);
 
 	while (true) {
 		syscall(wai_sem(ic->semid_rxb_ready));
 		if ((input = IF_ETHER_NIC_READ(ic)) != NULL) {
-			NET_COUNT_ETHER(net_count_ether.in_octets, input->len);
+			NET_COUNT_ETHER(net_count_ether.in_octets,  input->len);
 			NET_COUNT_MIB(if_stats.ifInOctets, input->len + 8);
 			NET_COUNT_ETHER(net_count_ether.in_packets, 1);
@@ -436,4 +462,17 @@
 			proto = ntohs(eth->type);
 
+			/* 乱数生成を初期化する。*/
+			if (rcount == 0) {
+
+#ifdef ETHER_CFG_COLLECT_ADDR
+				memcpy(ether_collect_addr.lladdr, eth->shost, 
+				sizeof(ether_collect_addr.lladdr));
+#endif	/* of #ifdef ETHER_CFG_COLLECT_ADDR */
+
+				net_srand(0);
+				}
+			rcount ++;
+
+
 #ifdef SUPPORT_MIB
 			if ((*eth->dhost & ETHER_MCAST_ADDR) == 0) {
@@ -445,5 +484,5 @@
 #endif	/* of #ifdef SUPPORT_MIB */
 
-#if defined(SUPPORT_INET4) && defined(ETHER_CFG_ACCEPT_ALL)
+#if defined(_IP4_CFG) && defined(ETHER_CFG_ACCEPT_ALL)
 
 			if ((*eth->dhost & ETHER_MCAST_ADDR) && *eth->dhost != 0xff) {
@@ -464,9 +503,9 @@
 				}
 
-#endif	/* of #if defined(SUPPORT_INET4) && defined(ETHER_CFG_ACCEPT_ALL) */
+#endif	/* of #if defined(_IP4_CFG) && defined(ETHER_CFG_ACCEPT_ALL) */
 
 			switch(proto) {
 
-#if defined(SUPPORT_INET4)
+#if defined(_IP4_CFG)
 
 			case ETHER_TYPE_IP:		/* IP	*/
@@ -478,7 +517,7 @@
 				break;
 
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
+#endif	/* of #if defined(_IP4_CFG) */
+
+#if defined(_IP6_CFG)
 
 			case ETHER_TYPE_IPV6:		/* IPv6	*/
@@ -486,5 +525,5 @@
 				break;
 
-#endif	/* of #if defined(SUPPORT_INET6) */
+#endif	/* of #if defined(_IP6_CFG) */
 
 			default:
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ethernet.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ethernet.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ethernet.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ethernet.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ethernet.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ethernet.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -98,4 +98,38 @@
 #endif	/* of #ifndef IF_ETHER_NIC_HDR_ALIGN */
 
+#if defined(__RX)
+
+#pragma pack
+typedef struct t_ether_header {
+
+#if IF_ETHER_NIC_HDR_ALIGN != 0
+
+	uint8_t		align[IF_ETHER_NIC_HDR_ALIGN];	/* アライン調整 */
+
+#endif	/* of #if IF_ETHER_NIC_HDR_ALIGN != 0 */
+
+	uint8_t		dhost[ETHER_ADDR_LEN];
+	uint8_t		shost[ETHER_ADDR_LEN];
+	uint16_t	type;
+	} T_ETHER_HDR;
+#pragma packoption
+
+#elif defined(TOPPERS_S810_CLG3_85)	/* of #if defined(__RX) */
+
+typedef struct t_ether_header {
+
+#if IF_ETHER_NIC_HDR_ALIGN != 0
+
+	uint8_t		align[IF_ETHER_NIC_HDR_ALIGN];	/* アライン調整 */
+
+#endif	/* of #if IF_ETHER_NIC_HDR_ALIGN != 0 */
+
+	uint8_t		dhost[ETHER_ADDR_LEN];
+	uint8_t		shost[ETHER_ADDR_LEN];
+	uint16_t	type;
+	} T_ETHER_HDR;
+
+#else	/* of #if defined(__RX) */
+
 typedef struct t_ether_header {
 
@@ -111,4 +145,6 @@
 	} __attribute__((packed, aligned(2)))T_ETHER_HDR;
 
+#endif	/* of #if defined(__RX) */
+
 #define GET_ETHER_HDR(nbuf)		((T_ETHER_HDR*)((nbuf)->buf))
 
@@ -140,4 +176,5 @@
 #define IF_HDR_ALIGN		2			/* ヘッダのアライン単位				*/
 #define IF_MTU			1500			/* インタフェースの MTU				*/
+#define IF_MIN_LEN		ETHER_MIN_LEN		/* インターフェースフレームの最短長		*/
 
 #define IF_OUTPUT(o,d,g,t)	ether_output(o,d,g,t)	/* インタフェースの出力関数			*/
@@ -148,9 +185,10 @@
 							/* ソフトウェア情報から MAC アドレスを取り出す	*/
 #define IF_GET_IFNET()		ether_get_ifnet()	/* ネットワークインタフェース構造体を返す。		*/
-#define IF_TYPE			IFT_ETHER		/* インターフェースの型				*/
+#define IF_TYPE			IFT_ETHER		/* インタフェースの型				*/
+#define IF_SRAND()		ether_srand()	/* インタフェースの乱数初期値			*/
 
 /* IPv4 関係 */
 
-#define IF_PROTO_IP		ETHER_TYPE_IP		/* インタフェースの IP プロトコル指定		*/
+#define IF_PROTO_IP		ETHER_TYPE_IP		/* インタフェースの IPv4 プロトコル指定		*/
 #define IF_PROTO_ARP		ETHER_TYPE_ARP		/* インタフェースの ARP プロトコル指定		*/
 
@@ -160,5 +198,5 @@
 #define IF_MADDR_INIT		{ { { 0, 0, 0, 0, 0, 0 } }, { { 0, 0, 0, 0, 0, 0 } } }
 							/* インタフェースのマルチキャストアドレス配列の初期化	*/
-#define IF_PROTO_IPV6		ETHER_TYPE_IPV6		/* インタフェースの IP プロトコル指定			*/
+#define IF_PROTO_IPV6		ETHER_TYPE_IPV6		/* インタフェースの IPv6 プロトコル指定			*/
 #define IF_ADDMULTI(s)		IF_ETHER_NIC_ADDMULTI(s)
 							/* マルチキャストアドレスの登録				*/
@@ -215,13 +253,13 @@
 	T_IF_ADDR		ifaddr;			/* ネットワークインタフェースのアドレス	*/
 	uint16_t		timer;			/* 送信タイムアウト			*/
-	T_IF_ETHER_NIC_SOFTC	*sc;	/* ディバイス依存のソフトウェア情報	*/
+	T_IF_ETHER_NIC_SOFTC	*sc;			/* ディバイス依存のソフトウェア情報	*/
 	ID			semid_txb_ready;	/* 送信セマフォ				*/
 	ID			semid_rxb_ready;	/* 受信セマフォ				*/
 
-#ifdef SUPPORT_INET6
+#ifdef _IP6_CFG
 
 	T_IF_ADDR 	maddrs[MAX_IF_MADDR_CNT];	/* マルチキャストアドレスリスト	*/
 
-#endif	/* of #ifdef SUPPORT_INET6 */
+#endif	/* of #ifdef _IP6_CFG */
 	};
 
@@ -231,5 +269,19 @@
 #define IF_FLAG_LINK_UP			0x10U
 
-#ifdef SUPPORT_INET6
+/*
+ *  変数
+ */
+
+#ifdef ETHER_CFG_COLLECT_ADDR
+
+T_ETHER_ADDR ether_collect_addr;
+
+#endif	/* of #ifdef ETHER_CFG_COLLECT_ADDR */
+
+/*
+ *  関数
+ */
+
+#ifdef _IP6_CFG
 
 /* 前方参照 */
@@ -243,19 +295,12 @@
 #endif	/* of #ifndef T_IN6_ADDR_DEFINED */
 
-/*
- *  関数
- */
-
-extern ER ether_in6_resolve_multicast(T_ETHER_ADDR *ifaddr, T_IN6_ADDR *maddr);
-
-#endif	/* of #ifdef SUPPORT_INET6 */
-
-/*
- *  関数
- */
+extern ER ether_in6_resolve_multicast(T_ETHER_ADDR *ifaddr, const T_IN6_ADDR *maddr);
+
+#endif	/* of #ifdef _IP6_CFG */
 
 extern T_IFNET *ether_get_ifnet (void);
-extern ER ether_output (T_NET_BUF *data, void *dst, T_IF_ADDR *gw, TMO tmout);
+extern ER ether_output (T_NET_BUF *data, const void *dst, T_IF_ADDR *gw, TMO tmout);
 extern ER ether_raw_output (T_NET_BUF *data, TMO tmout);
+extern uint32_t ether_srand (void);
 
 /** Function prototype for netif status- or link-callback functions. */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/if.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/if.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/if.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -86,13 +86,19 @@
 
 #include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/if_loop.h>
 #include <net/ethernet.h>
 #include <net/if_arp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_timer.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
 
 #include <netinet6/in6.h>
 #include <netinet6/in6_var.h>
 
-#include <net/if6_var.h>
+#include <net/if_var.h>
 
 #ifdef SUPPORT_ETHER
@@ -133,5 +139,7 @@
 	}
 
-#ifdef SUPPORT_INET6
+#endif /* of #ifdef SUPPORT_ETHER */
+
+#ifdef _IP6_CFG
 
 /*
@@ -142,4 +150,6 @@
 if_addmulti (T_IFNET *ifp, void *maddr, uint8_t type)
 {
+#if MAX_IF_MADDR_CNT > 0
+
 	T_IF_ADDR	llmaddr;
 	ER		error = E_OK;
@@ -152,5 +162,5 @@
 
 		/* IPv6 マルチキャストアドレスを登録する。*/
-		ifp->in_maddrs[ix] = *(T_IN6_ADDR*)maddr;
+		ifp->in6_maddrs[ix] = *(T_IN6_ADDR*)maddr;
 
 		/* インタフェースのアドレスに変換し、登録する。*/
@@ -162,7 +172,11 @@
 
 	return IF_ADDMULTI(ifp->ic);
+
+#else	/* of #if MAX_IF_MADDR_CNT > 0 */
+
+	return E_OK;
+
+#endif	/* of #if MAX_IF_MADDR_CNT > 0 */
 	}
 
-#endif	/* of #ifdef SUPPORT_INET6 */
-
-#endif /* of #ifdef SUPPORT_ETHER */
+#endif	/* of #ifdef _IP6_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/if.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/if.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/if.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/if6_var.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/if6_var.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/if6_var.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -68,18 +68,51 @@
 #define _IF6_VAR_H_
 
-#ifdef SUPPORT_INET6
-
 /*
  *  ネットワークインタフェース構造体
  */
 
+#if defined(_IP6_CFG)
+
+#if defined(_IP4_CFG)
+
 struct t_ifnet {
 	T_IF_SOFTC	*ic;		/* ネットワークインタフェースのソフトウェア情報	*/
-	T_IN6_IFADDR 	in_ifaddrs[NUM_IN6_IFADDR_ENTRY];
+	T_IN6_IFADDR 	in6_ifaddrs[NUM_IN6_IFADDR_ENTRY];
 					/* IPv6 アドレス情報				*/
-	T_IN6_ADDR	in_maddrs [MAX_IN6_MADDR_CNT];
+	T_IN6_ADDR	in6_maddrs [MAX_IN6_MADDR_CNT];
 					/* マルチキャスト IPv6 アドレス			*/
+	T_IN4_IFADDR 	in4_ifaddr;	/* IPv4 アドレス情報				*/
+	ether_status_callback_fn link_callback;
 	uint8_t		flags;		/* フラグ					*/
 	};
+
+#else	/* of #if defined(_IP4_CFG) */
+
+struct t_ifnet {
+	T_IF_SOFTC	*ic;		/* ネットワークインタフェースのソフトウェア情報	*/
+	T_IN6_IFADDR 	in6_ifaddrs[NUM_IN6_IFADDR_ENTRY];
+					/* IPv6 アドレス情報				*/
+	T_IN6_ADDR	in6_maddrs [MAX_IN6_MADDR_CNT];
+					/* マルチキャスト IPv6 アドレス			*/
+	ether_status_callback_fn link_callback;
+	uint8_t		flags;		/* フラグ					*/
+	};
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#else	/* of #if defined(_IP6_CFG) */
+
+#if defined(_IP4_CFG)
+
+struct t_ifnet {
+	T_IF_SOFTC	*ic;		/* ネットワークインタフェースのソフトウェア情報	*/
+	T_IN4_IFADDR 	in4_ifaddr;	/* IPv4 アドレス情報				*/
+	ether_status_callback_fn link_callback;
+	uint8_t		flags;		/* フラグ					*/
+	};
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#endif	/* of #if defined(_IP6_CFG) */
 
 #ifndef T_IFNET_DEFINED
@@ -90,4 +123,6 @@
 
 #endif	/* of #ifndef T_IFNET_DEFINED */
+
+#if defined(_IP6_CFG)
 
 /*
@@ -103,5 +138,5 @@
 extern ER if_addmulti (T_IFNET *ifp, void *maddr, uint8_t type);
 
-#endif	/* of #ifdef SUPPORT_INET6 */
+#endif	/* of #if defined(_IP6_CFG) */
 
 #endif	/* of #ifndef _IF6_VAR_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_arp.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_arp.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_arp.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_llc.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_llc.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_llc.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_loop.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_loop.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_loop.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -91,4 +91,5 @@
 #include <net/if_loop.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_count.h>
@@ -98,11 +99,8 @@
 #include <netinet/ip.h>
 #include <netinet/ip_var.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
 #include <netinet/tcp.h>
 #include <netinet/udp.h>
 
 #include <net/if_var.h>
-#include <net/if6_var.h>
 
 #ifdef SUPPORT_LOOP
@@ -124,5 +122,13 @@
 /* ネットワークインタフェース構造体 */
 
-#if defined(SUPPORT_INET4)
+#if defined(_IP6_CFG)
+
+static T_IFNET loop_ifnet = {
+	NULL,			/* ネットワークインタフェースのソフトウェア情報	*/
+	{},			/* IPv6 アドレス情報				*/
+	{},			/* マルチキャスト IPv6 アドレス			*/
+	};
+
+#elif defined(_IP4_CFG)	/* of #if defined(_IP6_CFG) */
 
 static T_IFNET loop_ifnet = {
@@ -134,15 +140,5 @@
 	};
 
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
-
-static T_IFNET loop_ifnet = {
-	NULL,			/* ネットワークインタフェースのソフトウェア情報	*/
-	{},			/* IPv6 アドレス情報				*/
-	{},			/* マルチキャスト IPv6 アドレス			*/
-	};
-
-#endif	/* of #if defined(SUPPORT_INET6) */
+#endif	/* of #if defined(_IP6_CFG) */
 
 /*
@@ -213,5 +209,5 @@
 			NET_COUNT_LOOP(net_count_loop.in_packets, 1);
 
-#if defined(SUPPORT_INET4)
+#if defined(_IP4_CFG)
 
 			/* IPv4 入力関数を呼び出す */
@@ -219,7 +215,7 @@
 				ip_input(input);
 
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
+#endif	/* of #if defined(_IP4_CFG) */
+
+#if defined(_IP6_CFG)
 
 			/* IPv6 入力関数を呼び出す */
@@ -227,5 +223,5 @@
 				ip6_input(input);
 
-#endif	/* of #if defined(SUPPORT_INET6) */
+#endif	/* of #if defined(_IP6_CFG) */
 
 			}
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_loop.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_loop.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_loop.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_loop.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_loop.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_loop.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -91,4 +91,5 @@
 #define IF_SET_PROTO(b,p)				/* インタフェースのプロトコル設定関数	*/
 #define IF_GET_IFNET()		loop_get_ifnet()	/* ネットワークインタフェース構造体を返す。		*/
+#define IF_SRAND()		(0)			/* インターフェースの乱数初期値			*/
 
 /* IPv4 関係 */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_ppp.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_ppp.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_ppp.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -59,18 +59,40 @@
 
 /*
+ *  PPP アドレスの定義（ダミー）
+ */
+
+typedef struct t_ppp_addr {
+	uint8_t		lladdr[0];
+	} T_PPP_ADDR;
+
+/*
  *  インタフェースの選択マクロ
  */
 
-#define T_IF_HDR		T_PPP_HDR	/* インタフェースのヘッダ			*/
-#define IF_HDR_ALIGN		2		/* ヘッダのアライン単位			*/
-#define IF_MTU			DEF_PPP_MTU	/* インタフェースの MTU			*/
-						/* インタフェースの IPv4 アドレス		*/
-#define IF_PROTO_IP		PPP_IP		/* インタフェースの IP プロトコル指定	*/
+#define T_IF_HDR		T_PPP_HDR		/* インタフェースのヘッダ		*/
+#define T_IF_ADDR		T_PPP_ADDR		/* インタフェースのアドレス			*/
+#define IF_HDR_ALIGN		2			/* ヘッダのアライン単位			*/
+#define IF_MTU			DEF_PPP_MTU		/* インタフェースの MTU			*/
 
 #define IF_OUTPUT(o,d,g,t)	ppp_output(o,t)		/* インタフェースの出力関数		*/
 #define IF_RAW_OUTPUT(o,t)	ppp_output(o,t)		/* インタフェースの出力関数、アドレス解決無し*/
+#define IF_SET_PROTO(b,p)	(*GET_PPP_HDR(b) = htons(p))
 							/* インタフェースのプロトコル設定関数	*/
-#define IF_SET_PROTO(b,p)	(*GET_PPP_HDR(b) = htons(p))
-#define IF_GET_IFNET()		ppp_get_ifnet()		/* ネットワークインタフェース構造体を返す。		*/
+#define IF_SOFTC_TO_IFADDR(s)	((T_IF_ADDR*)(s)->ifaddr.lladdr)
+							/* ソフトウェア情報から PPP アドレスを取り出す	*/
+#define IF_GET_IFNET()		ppp_get_ifnet()		/* ネットワークインタフェース構造体を返す。*/
+#define IF_SRAND()		(0)			/* インターフェースの乱数初期値			*/
+
+/* IPv4 関係 */
+
+#define IF_PROTO_IP		PPP_IP			/* インタフェースの IPv4 プロトコル指定	*/
+
+/* IPv6 関係 */
+
+#define MAX_IF_MADDR_CNT	0			/* インタフェースのマルチキャストアドレス配列の最大サイズ*/
+#define IF_PROTO_IPV6		PPP_IPV6		/* インタフェースの IPv6 プロトコル指定	*/
+#define IF_IN6_NEED_CACHE(i)	(false)			/* 近隣探索キャッシュを使用する。	*/
+#define IF_IN6_IFID(i,a)	get_rand_ifid(i,a)	/* インタフェース識別子の設定		*/
+#define IF_IN6_RESOLVE_MULTICAST(i,m)	{}		/* インタフェースのマルチキャストアドレスへの変換		*/
 
 /*
@@ -120,5 +142,7 @@
  */
 
-struct t_if_softc { };
+struct t_if_softc {
+	T_IF_ADDR	ifaddr;		/* ネットワークインタフェースのアドレス	*/
+	};
 
 /*
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_types.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_types.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_types.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_var.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_var.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/if_var.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -68,26 +68,5 @@
 #define _IF_VAR_H_
 
-#if defined(SUPPORT_INET4)
-
-/*
- *  ネットワークインタフェース構造体
- */
-
-struct t_ifnet {
-	T_IF_SOFTC	*ic;		/* ネットワークインタフェースのソフトウェア情報	*/
-	T_IN4_IFADDR 	in_ifaddr;	/* IPv4 アドレス情報				*/
-	ether_status_callback_fn link_callback;
-	uint8_t		flags;		/* フラグ					*/
-	};
-
-#ifndef T_IFNET_DEFINED
-
-typedef struct t_ifnet T_IFNET;
-
-#define T_IFNET_DEFINED
-
-#endif	/* of #ifndef T_IFNET_DEFINED */
-
-#endif	/* of #if defined(SUPPORT_INET4) */
+#include <net/if6_var.h>
 
 #ifdef SUPPORT_MIB
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/net.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/net.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/net.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -41,5 +41,5 @@
 
 CRE_TSK(NET_TIMER_TASK, {
-		TA_NULL,
+		TA_HLNG,
 		0,
 		net_timer_task,
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/net.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/net.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/net.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -69,124 +69,4 @@
 
 /*
- *  バイトオーダの定義
- */
-
-#define _NET_CFG_LITTLE_ENDIAN	1234
-#define _NET_CFG_BIG_ENDIAN	4321
-
-#ifdef TARGET_KERNEL_ASP
-
-#if defined(SIL_ENDIAN_LITTLE)
-
-#define _NET_CFG_BYTE_ORDER	_NET_CFG_LITTLE_ENDIAN
-
-#elif defined(SIL_ENDIAN_BIG)
-
-#define _NET_CFG_BYTE_ORDER	_NET_CFG_BIG_ENDIAN
-
-#else	/* of #if defined(SIL_ENDIAN_BIG) */
-
-#error "SIL_ENDIAN expected."
-
-#endif	/* of #if defined(SIL_ENDIAN_BIG) */
-
-#endif	/* of #ifdef TARGET_KERNEL_ASP */
-
-#ifdef TARGET_KERNEL_JSP
-
-#if SIL_ENDIAN == SIL_ENDIAN_LITTLE
-
-#define _NET_CFG_BYTE_ORDER	_NET_CFG_LITTLE_ENDIAN
-
-#elif SIL_ENDIAN == SIL_ENDIAN_BIG	/* of #if SIL_ENDIAN == SIL_ENDIAN_LITTLE */
-
-#define _NET_CFG_BYTE_ORDER	_NET_CFG_BIG_ENDIAN
-
-#else	/* of #if SIL_ENDIAN == SIL_ENDIAN_LITTLE */
-
-#error "SIL_ENDIAN expected."
-
-#endif	/* of #if SIL_ENDIAN == SIL_ENDIAN_LITTLE */
-
-#endif	/* of #ifdef TARGET_KERNEL_JSP */
-
-/*
- *  バイトオーダ変換の定義
- */
-
-#if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN
-
-#define ntohs(n)		((uint16_t)n)
-#define htons(h)		((uint16_t)h)
-#define ntohl(n)		((uint32_t)n)
-#define htonl(h)		((uint32_t)h)
-
-#define NTOHS(n)
-#define HTONS(h)
-#define NTOHL(n)
-#define HTONL(h)
-
-/*
- *  注意: IPヘッダ以降は、4 バイト境界にアラインされている事を
- *        前提としているが、4 バイト境界でアクセスする
- *        プロセッサで、ネットワーク側のデータが、4 バイト境界にアライン
- *        されていない場合は、ntoahl、ahtonl、nahcmpl を使用すること。
- */
-
-#define ntoahl(h,n)		memcpy((uint8_t*)&(h),(n),4)
-#define ahtonl(n,h)		memcpy((n),(uint8_t*)&(h),4)
-
-#define nahcmpl(n,h)		memcmp((n),(uint8_t*)&(h),4)
-
-#elif _NET_CFG_BYTE_ORDER == _NET_CFG_LITTLE_ENDIAN
-
-#ifndef NET_REV_ENDIAN_HWORD
-
-#define NET_REV_ENDIAN_HWORD(d)	((uint16_t)((((uint16_t)(d)&0xff)<<8)|(((uint16_t)(d)>>8)&0xff)))
-
-#endif	/* of #ifndef NET_REV_ENDIAN_HWORD */
-
-#ifndef NET_REV_ENDIAN_WORD
-
-#define NET_REV_ENDIAN_WORD(d)	((uint32_t)((((uint32_t)(d)&0xff)<<24)|(((uint32_t)(d)&0xff00)<<8)| \
-				            (((uint32_t)(d)>>8)&0xff00)|(((uint32_t)(d)>>24)&0xff)))
-
-#endif	/* of #ifndef NET_REV_ENDIAN_WORD */
-
-#define ntohs(n)		NET_REV_ENDIAN_HWORD(n)
-#define htons(h)		NET_REV_ENDIAN_HWORD(h)
-#define ntohl(n)		NET_REV_ENDIAN_WORD(n)
-#define htonl(h)		NET_REV_ENDIAN_WORD(h)
-
-#define NTOHS(n)		((n)=NET_REV_ENDIAN_HWORD(n))
-#define HTONS(h)		((h)=NET_REV_ENDIAN_HWORD(h))
-#define NTOHL(n)		((n)=NET_REV_ENDIAN_WORD(n))
-#define HTONL(h)		((h)=NET_REV_ENDIAN_WORD(h))
-
-/*
- *  注意: IPヘッダ以降は、4 バイト境界にアラインされている事を
- *        前提としているが、4 バイト境界でアクセスする
- *        プロセッサで、ネットワーク側のデータが、4 バイト境界にアライン
- *        されていない場合は、ntoahl、ahtonl、nahcmpl を使用すること。
- */
-
-#ifndef _MACRO_ONLY
-
-extern void rev_memcpy_word (uint8_t *dst, uint8_t *src);
-extern int  rev_memcmp_word (uint8_t *data1, uint8_t *data2);
-
-#endif	/* of #ifndef _MACRO_ONLY */
-
-#define ntoahl(h,n)		rev_memcpy_word((uint8_t*)&(h),(n))
-#define ahtonl(n,h)		rev_memcpy_word((n),(uint8_t*)&(h))
-#define nahcmpl(n,h)		rev_memcmp_word((n),(uint8_t*)&(h))
-
-#else	/* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
-
-#error "_NET_CFG_BYTE_ORDER expected."
-
-#endif	/* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
-
-/*
  *  プロトコルを識別するフラグに関する定義
  *
@@ -199,8 +79,9 @@
 #define PROTO_FLG_PPP_LCP	ULONG_C(0x00000008)	/* ppp_lcp.c	*/
 #define PROTO_FLG_PPP_IPCP	ULONG_C(0x00000010)	/* ppp_ipcp.c	*/
-#define PROTO_FLG_PPP_CCP	ULONG_C(0x00000020)	/* ppp_ccp.c	*/
-#define PROTO_FLG_PPP_PAP	ULONG_C(0x00000040)	/* ppp_upap.c	*/
-#define PROTO_FLG_PPP_MODEM	ULONG_C(0x00000080)	/* ppp_modem.c	*/
-#define PROTO_FLG_PPP		ULONG_C(0x00000100)	/* ppp.c	*/
+#define PROTO_FLG_PPP_IPV6CP	ULONG_C(0x00000020)	/* ppp_ipv6cp.c	*/
+#define PROTO_FLG_PPP_CCP	ULONG_C(0x00000040)	/* ppp_ccp.c	*/
+#define PROTO_FLG_PPP_PAP	ULONG_C(0x00000080)	/* ppp_upap.c	*/
+#define PROTO_FLG_PPP_MODEM	ULONG_C(0x00000100)	/* ppp_modem.c	*/
+#define PROTO_FLG_PPP		ULONG_C(0x00000200)	/* ppp.c	*/
 
 #define PROTO_FLG_ETHER_NIC	ULONG_C(0x00000001)	/* if_??.c	*/
@@ -216,4 +97,5 @@
 #define PROTO_FLG_IP4		ULONG_C(0x00010000)	/* ip_*.c	*/
 #define PROTO_FLG_ICMP4		ULONG_C(0x00040000)	/* ip_icmp.c	*/
+#define PROTO_FLG_IGMP		ULONG_C(0x00080000)	/* ip_igmp.c	*/
 
 #define PROTO_FLG_IP6		ULONG_C(0x00100000)	/* ip6_*.c	*/
@@ -236,4 +118,15 @@
 #define AT_INET6		UINT_C(0x20)		/* IPv6 アドレス	*/
 
+/*
+ *  IPv4 UDPオプションの定義
+ */
+
+#define IP_MULTICAST_IF    32
+#define IP_MULTICAST_TTL   33
+#define IP_MULTICAST_LOOP  34
+#define IP_ADD_MEMBERSHIP  35
+#define IP_DROP_MEMBERSHIP 36
+#define IP_MSFILTER        41
+
 #if !defined(TOPPERS_MACRO_ONLY) && !defined(_MACRO_ONLY)
 
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_asp.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_asp.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_asp.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -50,5 +50,7 @@
 		TA_TFIFO,
 		NUM_MPF_NET_BUF_CSEG,
-		sizeof(T_NET_BUF_CSEG)
+		sizeof(T_NET_BUF_CSEG),
+		NULL,
+		NULL
 		});
 #endif	/* of #if defined(NUM_MPF_NET_BUF_CSEG) && NUM_MPF_NET_BUF_CSEG > 0 */
@@ -57,5 +59,7 @@
 CRE_MPF(MPF_NET_BUF_64, {
 		TA_TFIFO, NUM_MPF_NET_BUF_64,
-		sizeof(T_NET_BUF_64)
+		sizeof(T_NET_BUF_64),
+		NULL,
+		NULL
 		});
 #endif	/* of #if defined(NUM_MPF_NET_BUF_64) && NUM_MPF_NET_BUF_64 > 0 */
@@ -65,5 +69,7 @@
 		TA_TFIFO,
 		NUM_MPF_NET_BUF_128,
-		sizeof(T_NET_BUF_128)
+		sizeof(T_NET_BUF_128),
+		NULL,
+		NULL
 		});
 #endif	/* of #if defined(NUM_MPF_NET_BUF_128) && NUM_MPF_NET_BUF_128 > 0 */
@@ -73,5 +79,7 @@
 		TA_TFIFO,
 		NUM_MPF_NET_BUF_256,
-		sizeof(T_NET_BUF_256)
+		sizeof(T_NET_BUF_256),
+		NULL,
+		NULL
 		});
 #endif	/* of #if defined(NUM_MPF_NET_BUF_256) && NUM_MPF_NET_BUF_256 > 0 */
@@ -81,5 +89,7 @@
 		TA_TFIFO,
 		NUM_MPF_NET_BUF_512,
-		sizeof(T_NET_BUF_512)
+		sizeof(T_NET_BUF_512),
+		NULL,
+		NULL
 		});
 #endif	/* of #if defined(NUM_MPF_NET_BUF_512) && NUM_MPF_NET_BUF_512 > 0 */
@@ -89,5 +99,7 @@
 		TA_TFIFO,
 		NUM_MPF_NET_BUF_IP_MSS,
-		sizeof(T_NET_BUF_IP_MSS)
+		sizeof(T_NET_BUF_IP_MSS),
+		NULL,
+		NULL
 		});
 #endif	/* of #if defined(NUM_MPF_NET_BUF_IP_MSS) && NUM_MPF_NET_BUF_IP_MSS > 0 */
@@ -97,5 +109,7 @@
 		TA_TFIFO,
 		NUM_MPF_NET_BUF_1024,
-		sizeof(T_NET_BUF_1024)
+		sizeof(T_NET_BUF_1024),
+		NULL,
+		NULL
 		});
 #endif	/* of #if defined(NUM_MPF_NET_BUF_1024) && NUM_MPF_NET_BUF_1024 > 0 */
@@ -105,5 +119,7 @@
 		TA_TFIFO,
 		NUM_MPF_NET_BUF_IPV6_MMTU,
-		sizeof(T_NET_BUF_IPV6_MMTU)
+		sizeof(T_NET_BUF_IPV6_MMTU),
+		NULL,
+		NULL
 		});
 #endif	/* of #if defined(NUM_MPF_NET_BUF_IPV6_MMTU) && NUM_MPF_NET_BUF_IPV6_MMTU > 0 */
@@ -113,22 +129,33 @@
 		TA_TFIFO,
 		NUM_MPF_NET_BUF_IF_PDU,
-		sizeof(T_NET_BUF_IF_PDU)
+		sizeof(T_NET_BUF_IF_PDU),
+		NULL,
+		NULL
 		});
 #endif	/* of #if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0 */
 
+#if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0
+
+CRE_MPF(MPF_NET_BUF_REASSM, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF6_REASSM,
+		sizeof(T_NET_BUF6_REASSM),
+		NULL,
+		NULL
+		});
+
+#else /* of #if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0 */
+
 #if defined(NUM_MPF_NET_BUF4_REASSM) && NUM_MPF_NET_BUF4_REASSM > 0
+
 CRE_MPF(MPF_NET_BUF_REASSM, {
 		TA_TFIFO,
 		NUM_MPF_NET_BUF4_REASSM,
-		sizeof(T_NET_BUF4_REASSM)
+		sizeof(T_NET_BUF4_REASSM),
+		NULL,
+		NULL
 		});
 #endif	/* of #if defined(NUM_MPF_NET_BUF4_REASSM) && NUM_MPF_NET_BUF4_REASSM > 0 */
 
-#if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0
-CRE_MPF(MPF_NET_BUF_REASSM, {
-		TA_TFIFO,
-		NUM_MPF_NET_BUF6_REASSM,
-		sizeof(T_NET_BUF6_REASSM)
-		});
 #endif	/* of #if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0 */
 
@@ -137,5 +164,7 @@
 		TA_TFIFO,
 		NUM_MPF_NET_BUF6_65536,
-		sizeof(T_NET_BUF6_65536)
+		sizeof(T_NET_BUF6_65536),
+		NULL,
+		NULL
 		});
 #endif	/* of #if defined(NUM_MPF_NET_BUF6_65536) && NUM_MPF_NET_BUF6_65536 > 0 */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_buf.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_buf.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_buf.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -57,4 +57,5 @@
 #include <net/ethernet.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_count.h>
@@ -62,11 +63,7 @@
 #include <netinet/in.h>
 #include <netinet/in_var.h>
-#include <netinet6/in6.h>
 #include <netinet/ip.h>
 #include <netinet/ip_var.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
 #include <netinet/tcp.h>
-#include <netinet/tcp_timer.h>
 #include <netinet/tcp_var.h>
 
@@ -98,4 +95,5 @@
 
 #if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0
+
 	{
 		MPF_NET_BUF_REASSM,
@@ -109,7 +107,9 @@
 
 		},
-#endif	/* of #if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0 */
+
+#else	/* of #if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0 */
 
 #if defined(NUM_MPF_NET_BUF4_REASSM) && NUM_MPF_NET_BUF4_REASSM > 0
+
 	{
 		MPF_NET_BUF_REASSM,
@@ -123,5 +123,8 @@
 
 		},
+
 #endif	/* of #if defined(NUM_MPF_NET_BUF4_REASSM) && NUM_MPF_NET_BUF4_REASSM > 0 */
+
+#endif	/* of #if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0 */
 
 #if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0
@@ -223,5 +226,5 @@
 #endif	/* of #if defined(NUM_MPF_NET_BUF_128) && NUM_MPF_NET_BUF_128 > 0 */
 
-#if defined(SUPPORT_INET4)
+#if defined(_IP4_CFG)
 
 #if defined(NUM_MPF_NET_BUF_64) && NUM_MPF_NET_BUF_64 > 0
@@ -239,5 +242,5 @@
 #endif	/* of #if defined(NUM_MPF_NET_BUF_64) && NUM_MPF_NET_BUF_64 > 0 */
 
-#endif	/* of #if defined(SUPPORT_INET4) */
+#endif	/* of #if defined(_IP4_CFG) */
 
 #if defined(NUM_MPF_NET_BUF_CSEG) && NUM_MPF_NET_BUF_CSEG > 0
@@ -308,5 +311,9 @@
 			(*buf)->len   = (uint16_t)minlen;
 			(*buf)->flags = 0;
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
 			NET_COUNT_NET_BUF(net_buf_table[ix].allocs, 1);
+			net_buf_table[ix].busies ++;
+#endif
 			return error;
 			}
@@ -316,5 +323,6 @@
 		}
 
-	syslog(LOG_WARNING, "[NET BUF] busy, index=%d, len=%4d.", (uint16_t)req_ix, minlen);
+	syslog(LOG_WARNING, "[BUF] busy, up   index:%d,%d[%4d], len:%4d.",
+	                    (uint16_t)req_ix, ix, net_buf_table[req_ix].size, minlen);
 	*buf = NULL;
 	NET_COUNT_NET_BUF(net_buf_table[req_ix].errors, 1);
@@ -346,5 +354,9 @@
 			(*buf)->len   = net_buf_table[ix].size;
 			(*buf)->flags = 0;
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
 			NET_COUNT_NET_BUF(net_buf_table[ix].allocs, 1);
+			net_buf_table[ix].busies ++;
+#endif
 			return error;
 			}
@@ -354,5 +366,6 @@
 		}
 
-	syslog(LOG_WARNING, "[NET BUF] busy, index=%d, len=%4d.", (uint16_t)req_ix, maxlen);
+	syslog(LOG_WARNING, "[BUF] busy, down index:%d,%d[%4d], len:%4d.",
+	                    (uint16_t)req_ix, ix, net_buf_table[req_ix].size, minlen);
 	*buf = NULL;
 	NET_COUNT_NET_BUF(net_buf_table[req_ix].errors, 1);
@@ -380,4 +393,6 @@
 		}
 
+#if defined(SUPPORT_TCP) && defined(TCP_CFG_SWBUF_CSAVE)
+
 	/* TCP で予約したネットワークバッファを取り出す。*/
 	if ((nbatr & NBA_RESERVE_TCP) != 0) {
@@ -386,4 +401,6 @@
 			}
 		}
+
+#endif	/* of #if defined(SUPPORT_TCP) && defined(TCP_CFG_SWBUF_CSAVE) */
 
 	if ((nbatr & NBA_SEARCH_DESCENT) != 0)
@@ -423,11 +440,20 @@
 	else {
 
+#if defined(SUPPORT_TCP) && defined(TCP_CFG_SWBUF_CSAVE)
+
 		/* TCP で、ネットワークバッファを予約する。*/
 		if (TCP_PUSH_RES_NBUF(buf) == NULL)
 			return E_OK;
 
+#endif	/* of #if defined(SUPPORT_TCP) && defined(TCP_CFG_SWBUF_CSAVE) */
+
 		/* 固定メモリプールに返す。*/
-		if ((error = rel_mpf((ID)net_buf_table[buf->idix].index, buf)) != E_OK)
+
+#if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF
+		net_buf_table[buf->idix].busies --;
+#endif
+		if ((error = rel_mpf((ID)net_buf_table[buf->idix].index, buf)) != E_OK) {
 			syslog(LOG_WARNING, "[NET BUF] %s, ID=%d.", itron_strerror(error), buf->idix);
+			}
 		}
 	return error;
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_buf.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_buf.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_buf.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -61,5 +61,5 @@
 	uint8_t		halign[4 - IF_HDR_ALIGN];
 #endif
-	uint8_t		buf[4];	/* バッファ本体		*/
+	uint8_t		buf[IF_MIN_LEN];	/* バッファ本体 */
 	};
 
@@ -71,4 +71,5 @@
 
 #endif	/* of #ifndef T_NET_BUF_DEFINED */
+
 /*
  *  64 オクテット
@@ -159,4 +160,6 @@
  *  ネットワークインタフェースの最大 PDU サイズ
  */
+
+#if defined(IF_PDU_SIZE)
 
 typedef struct t_net_buf_if_pdu {
@@ -177,4 +180,6 @@
 	} T_NET_BUF_IF_PDU;
 
+#endif	/* of #if defined(IF_PDU_SIZE) */
+
 /*
  *  ネットワークバッファ表
@@ -189,4 +194,5 @@
 
 	ulong_t		prepares;
+	ulong_t		busies;
 	ulong_t		requests;
 	ulong_t		allocs;
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_count.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_count.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_count.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -120,4 +120,5 @@
 
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_count.h>
 
@@ -142,4 +143,11 @@
 #endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_LCP */
 
+#if NET_COUNT_ENABLE & PROTO_FLG_PPP_IPV6CP
+
+T_NET_COUNT_VAL	net_count_ppp_ipv6cp_in_octets;
+T_NET_COUNT_VAL	net_count_ppp_ipv6cp_in_packets;
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_IPV6CP */
+
 #if NET_COUNT_ENABLE & PROTO_FLG_PPP_IPCP
 
@@ -190,5 +198,5 @@
 #endif	/* of #ifdef SUPPORT_ETHER */
 
-#if defined(SUPPORT_INET4)
+#if defined(_IP4_CFG)
 
 #if NET_COUNT_ENABLE & PROTO_FLG_ARP
@@ -210,7 +218,13 @@
 #endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ICMP4 */
 
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
+#if NET_COUNT_ENABLE & PROTO_FLG_IGMP
+
+T_NET_COUNT	net_count_igmp;
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ICMP4 */
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#if defined(_IP6_CFG)
 
 #if NET_COUNT_ENABLE & PROTO_FLG_IP6
@@ -232,5 +246,5 @@
 #endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ND6 */
 
-#endif	/* of #if defined(SUPPORT_INET6) */
+#endif	/* of #if defined(_IP6_CFG) */
 
 #ifdef SUPPORT_TCP
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_count.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_count.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_count.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -155,4 +155,23 @@
 #endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_LCP */
 
+/* PPP IPV6CP */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_PPP_IPV6CP
+
+#define NET_COUNT_PPP_IPV6CP(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT_VAL net_count_ppp_ipv6cp_in_octets;
+extern T_NET_COUNT_VAL net_count_ppp_ipv6cp_in_packets;
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_IPV6CP */
+
+#define NET_COUNT_PPP_IPV6CP(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_PPP_IPV6CP */
+
 /* PPP IPCP */
 
@@ -302,5 +321,5 @@
 #endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_NET_BUF */
 
-#if defined(SUPPORT_INET4)
+#if defined(_IP4_CFG)
 
 /* ARP */
@@ -380,7 +399,25 @@
 #endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ICMP4 */
 
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
+/* IGMP */
+
+#if NET_COUNT_ENABLE & PROTO_FLG_IGMP
+
+#define NET_COUNT_IGMP(v,c)	((v)+=(c))
+
+#ifndef _MACRO_ONLY
+
+extern T_NET_COUNT	net_count_igmp;
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#else	/* of #if NET_COUNT_ENABLE & PROTO_FLG_IGMP */
+
+#define NET_COUNT_IGMP(v,c)
+
+#endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_IGMP */
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#if defined(_IP6_CFG)
 
 /* IPv6 */
@@ -472,5 +509,5 @@
 #endif	/* of #if NET_COUNT_ENABLE & PROTO_FLG_ND6 */
 
-#endif	/* of #if defined(SUPPORT_INET6) */
+#endif	/* of #if defined(_IP6_CFG) */
 
 #ifdef SUPPORT_TCP
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_endian.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_endian.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_endian.h	(revision 331)
@@ -0,0 +1,209 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _NET_ENDIAN_H_
+#define _NET_ENDIAN_H_
+
+/*
+ *  ãã¤ããªã¼ãã®å®ç¾©
+ */
+
+#define _NET_CFG_LITTLE_ENDIAN	1234
+#define _NET_CFG_BIG_ENDIAN	4321
+
+#ifdef TARGET_KERNEL_ASP
+
+#if defined(SIL_ENDIAN_LITTLE)
+
+#define _NET_CFG_BYTE_ORDER	_NET_CFG_LITTLE_ENDIAN
+
+#elif defined(SIL_ENDIAN_BIG)
+
+#define _NET_CFG_BYTE_ORDER	_NET_CFG_BIG_ENDIAN
+
+#else	/* of #if defined(SIL_ENDIAN_BIG) */
+
+#error "SIL_ENDIAN expected."
+
+#endif	/* of #if defined(SIL_ENDIAN_BIG) */
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#if SIL_ENDIAN == SIL_ENDIAN_LITTLE
+
+#define _NET_CFG_BYTE_ORDER	_NET_CFG_LITTLE_ENDIAN
+
+#elif SIL_ENDIAN == SIL_ENDIAN_BIG	/* of #if SIL_ENDIAN == SIL_ENDIAN_LITTLE */
+
+#define _NET_CFG_BYTE_ORDER	_NET_CFG_BIG_ENDIAN
+
+#else	/* of #if SIL_ENDIAN == SIL_ENDIAN_LITTLE */
+
+#error "SIL_ENDIAN expected."
+
+#endif	/* of #if SIL_ENDIAN == SIL_ENDIAN_LITTLE */
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+/*
+ *  ãã¤ããªã¼ãå¤æã®å®ç¾©
+ */
+
+#if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN
+
+#define ntohs(n)		((uint16_t)n)
+#define htons(h)		((uint16_t)h)
+#define ntohl(n)		((uint32_t)n)
+#define htonl(h)		((uint32_t)h)
+
+#define NTOHS(n)
+#define HTONS(h)
+#define NTOHL(n)
+#define HTONL(h)
+
+/*
+ *  æ³¨æ: IPãããä»¥éã¯ã4 ãã¤ãå¢çã«ã¢ã©ã¤ã³ããã¦ããäºã
+ *        åæã¨ãã¦ãããã4 ãã¤ãå¢çã§ã¢ã¯ã»ã¹ãã
+ *        ãã­ã»ããµã§ããããã¯ã¼ã¯å´ã®ãã¼ã¿ãã4 ãã¤ãå¢çã«ã¢ã©ã¤ã³
+ *        ããã¦ããªãå ´åã¯ãntoahlãahtonlãnahcmpl ãä½¿ç¨ãããã¨ã
+ */
+
+#define ntoahs(h,n)		memcpy((void*)&(h),(n),sizeof(uint16_t))
+#define ahtons(n,h)		memcpy((n),(void*)&(h),sizeof(uint16_t))
+#define ntoahl(h,n)		memcpy((void*)&(h),(n),sizeof(uint32_t))
+#define ahtonl(n,h)		memcpy((n),(void*)&(h),sizeof(uint32_t))
+
+#define nahcmpl(n,h)		memcmp((n),(void*)&(h),sizeof(uint32_t))
+
+#elif _NET_CFG_BYTE_ORDER == _NET_CFG_LITTLE_ENDIAN	/* of #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
+
+#ifndef NET_REV_ENDIAN_HWORD
+
+#define NET_REV_ENDIAN_HWORD(d)	((uint16_t)((((uint16_t)(d)&0xff)<<8)|(((uint16_t)(d)>>8)&0xff)))
+
+#endif	/* of #ifndef NET_REV_ENDIAN_HWORD */
+
+#ifndef NET_REV_ENDIAN_WORD
+
+#define NET_REV_ENDIAN_WORD(d)	((uint32_t)((((uint32_t)(d)&0xff)<<24)|(((uint32_t)(d)&0xff00)<<8)| \
+				            (((uint32_t)(d)>>8)&0xff00)|(((uint32_t)(d)>>24)&0xff)))
+
+#endif	/* of #ifndef NET_REV_ENDIAN_WORD */
+
+#define ntohs(n)		NET_REV_ENDIAN_HWORD(n)
+#define htons(h)		NET_REV_ENDIAN_HWORD(h)
+#define ntohl(n)		NET_REV_ENDIAN_WORD(n)
+#define htonl(h)		NET_REV_ENDIAN_WORD(h)
+
+#define NTOHS(n)		((n)=NET_REV_ENDIAN_HWORD(n))
+#define HTONS(h)		((h)=NET_REV_ENDIAN_HWORD(h))
+#define NTOHL(n)		((n)=NET_REV_ENDIAN_WORD(n))
+#define HTONL(h)		((h)=NET_REV_ENDIAN_WORD(h))
+
+/*
+ *  æ³¨æ: IPãããä»¥éã¯ã4 ãã¤ãå¢çã«ã¢ã©ã¤ã³ããã¦ããäºã
+ *        åæã¨ãã¦ãããã4 ãã¤ãå¢çã§ã¢ã¯ã»ã¹ãã
+ *        ãã­ã»ããµã§ããããã¯ã¼ã¯å´ã®ãã¼ã¿ãã4 ãã¤ãå¢çã«ã¢ã©ã¤ã³
+ *        ããã¦ããªãå ´åã¯ãntoahlãahtonlãnahcmpl ãä½¿ç¨ãããã¨ã
+ */
+
+#ifndef _MACRO_ONLY
+
+extern void rev_memcpy_word  (void *dst, void *src);
+extern void rev_memcpy_hword (void *dst, void *src);
+
+extern int  rev_memcmp_word (void *data1, void *data2);
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#define ntoahs(h,n)		rev_memcpy_hword((void*)&(h),(n))
+#define ahtons(n,h)		rev_memcpy_hword((n),(void*)&(h))
+#define ntoahl(h,n)		rev_memcpy_word((void*)&(h),(n))
+#define ahtonl(n,h)		rev_memcpy_word((n),(void*)&(h))
+
+#define nahcmpl(n,h)		rev_memcmp_word((n),(void*)&(h))
+
+#else	/* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
+
+#error "_NET_CFG_BYTE_ORDER expected."
+
+#endif	/* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
+
+#endif	/* of #ifndef _NET_ENDIAN_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_jsp.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_jsp.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_jsp.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -127,5 +127,17 @@
 #endif	/* of #if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0 */
 
+#if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0
+
+CRE_MPF(MPF_NET_BUF_REASSM, {
+		TA_TFIFO,
+		NUM_MPF_NET_BUF6_REASSM,
+		sizeof(T_NET_BUF6_REASSM),
+		NULL
+		});
+
+#else	/* of #if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0 */
+
 #if defined(NUM_MPF_NET_BUF4_REASSM) && NUM_MPF_NET_BUF4_REASSM > 0
+
 CRE_MPF(MPF_NET_BUF_REASSM, {
 		TA_TFIFO,
@@ -134,13 +146,7 @@
 		NULL
 		});
+
 #endif	/* of #if defined(NUM_MPF_NET_BUF4_REASSM) && NUM_MPF_NET_BUF4_REASSM > 0 */
 
-#if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0
-CRE_MPF(MPF_NET_BUF_REASSM, {
-		TA_TFIFO,
-		NUM_MPF_NET_BUF6_REASSM,
-		sizeof(T_NET_BUF6_REASSM),
-		NULL
-		});
 #endif	/* of #if defined(NUM_MPF_NET_BUF6_REASSM) && NUM_MPF_NET_BUF6_REASSM > 0 */
 
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_rename.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_rename.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_rename.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -41,4 +41,13 @@
 /* net/ethernet.c */
 
+#define ether_input_task	_tinet_ether_input_task
+#define ether_get_ifnet		_tinet_ether_get_ifnet
+#define ether_in6_resolve_multicast	\
+				_tinet_ether_in6_resolve_multicast
+#define ether_srand		_tinet_ether_srand
+#define ether_output		_tinet_ether_output
+#define	ether_raw_output	_tinet_ether_raw_output
+#define ether_output_task	_tinet_ether_output_task
+
 #define ether_broad_cast_addr	_tinet_ether_broad_cast_addr
 #define ether_ipv4_addr_local	_tinet_ether_ipv4_addr_local
@@ -46,13 +55,6 @@
 				_tinet_ether_ipv4_addr_local_mask
 
-#define ether_raw_output	_tinet_ether_raw_output
-#define ether_output		_tinet_ether_output
 #define ether_in6_ifaddr	_tinet_ether_in6_ifaddr
 #define ether_in6_ifaddr_list	_tinet_ether_in6_ifaddr_list
-#define ether_in6_resolve_multicast	\
-				_tinet_ether_in6_resolve_multicast
-#define ether_input_task	_tinet_ether_input_task
-#define ether_get_ifnet		_tinet_ether_get_ifnet
-#define ether_output_task	_tinet_ether_output_task
 
 /* net/if.c */
@@ -93,5 +95,6 @@
 /* route_cfg.c */
 
-#define routing_tbl		_tinet_routing_tbl
+#define routing6_tbl		_tinet_routing6_tbl
+#define routing4_tbl		_tinet_routing4_tbl
 
 #ifdef SUPPORT_PPP
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_subr.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_subr.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_subr.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -88,5 +88,10 @@
 #include <tinet_config.h>
 
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 
 /*
@@ -103,5 +108,5 @@
 net_rand (void)
 {
-	next = (next * 1103515245 + 12345) % (ULONG_C(0x7fffffff) + 1);
+	next = (next * 99991 + 12345) & ULONG_C(0x7fffffff);
 	return next;
 	}
@@ -114,5 +119,8 @@
 net_srand (uint32_t seed)
 {
-	next += seed;
+	SYSTIM now;
+
+	syscall(get_tim(&now));
+	next += now + seed + IF_SRAND();
 	}
 
@@ -186,5 +194,5 @@
 
 /*
- *  rev_memcpy_word -- 反転メモリコピー（4 バイト）
+ *  rev_memcpy_hword -- 反転メモリコピー（2 バイト）
  *
  *    バイト単位にアクセスする事により、
@@ -193,14 +201,12 @@
 
 void
-rev_memcpy_word (uint8_t *dst, uint8_t *src)
-{
-	*(dst    ) = *(src + 3);
-	*(dst + 1) = *(src + 2);
-	*(dst + 2) = *(src + 1);
-	*(dst + 3) = *(src    );
-	}
-
-/*
- *  rev_memcmp_word -- 反転メモリ比較（4 バイト）
+rev_memcpy_hword (void *dst, void *src)
+{
+	*((uint8_t*)dst    ) = *((uint8_t*)src + 1);
+	*((uint8_t*)dst + 1) = *((uint8_t*)src    );
+	}
+
+/*
+ *  rev_memcpy_word -- 反転メモリコピー（4 バイト）
  *
  *    バイト単位にアクセスする事により、
@@ -208,11 +214,27 @@
  */
 
+void
+rev_memcpy_word (void *dst, void *src)
+{
+	*((uint8_t*)dst    ) = *((uint8_t*)src + 3);
+	*((uint8_t*)dst + 1) = *((uint8_t*)src + 2);
+	*((uint8_t*)dst + 2) = *((uint8_t*)src + 1);
+	*((uint8_t*)dst + 3) = *((uint8_t*)src    );
+	}
+
+/*
+ *  rev_memcmp_word -- 反転メモリ比較（4 バイト）
+ *
+ *    バイト単位にアクセスする事により、
+ *    境界へのアラインの問題を解決する。
+ */
+
 int_t
-rev_memcmp_word (uint8_t *data1, uint8_t *data2)
+rev_memcmp_word (void *data1, void *data2)
 {
 	int_t	ix, diff;
 
-	for (ix = 4; ix -- > 0; ) {
-		diff = *(data1 + ix) -  *(data2 + (3 - ix));
+	for (ix = sizeof(uint32_t); ix -- > 0; ) {
+		diff = *((uint8_t*)data1 + ix) -  *((uint8_t*)data2 + (3 - ix));
 		if (diff != 0)
 			return diff;
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_timer.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_timer.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_timer.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -90,13 +90,12 @@
 #include <net/ethernet.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_timer.h>
 
 #include <netinet/in.h>
+#include <netinet/in_var.h>
 #include <netinet/ip.h>
 #include <netinet/ip_var.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#include <netinet/tcp_timer.h>
 
 /*
@@ -162,5 +161,5 @@
 "\n"
 "TINET %d.%d.%d (" __DATE__ ", " __TIME__ ")\n"
-"Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering\n"
+"Copyright (C) 2001-2012 by Dep. of Computer Science and Engineering\n"
 "                    Tomakomai National College of Technology, JAPAN\n";
 
@@ -181,5 +180,12 @@
 
 	/* IP を初期化する。*/
-	IP_INIT();
+
+#if defined(_IP6_CFG)
+	ip6_init();
+#endif
+
+#if defined(_IP4_CFG)
+	ip_init();
+#endif
 
 #ifdef SUPPORT_TCP
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_timer.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_timer.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_timer.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -74,5 +74,5 @@
  */
 
-#define SYSTIM_HZ		ULONG_C(1000*1000)	/* [ms]					*/
+#define SYSTIM_HZ		ULONG_C(1000000)	/* [us]					*/
 
 /*
@@ -80,9 +80,9 @@
  */
 
-#define NET_TIMER_CYCLE		ULONG_C(100)	/* [ms]、fast timeout 使用時の動作周期	*/
+#define NET_TIMER_CYCLE		ULONG_C(100000)	/* [us]、fast timeout 使用時の動作周期	*/
 						/* タイマの周波数			*/
 #define NET_TIMER_HZ		(SYSTIM_HZ/NET_TIMER_CYCLE)
 
-#ifdef SUPPORT_INET6
+#ifdef _IP6_CFG
 #define NUM_NET_CALLOUT		12		/* タイムアウト呼出し数、10 以上	*/
 #else
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_var.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_var.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/net_var.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -81,4 +81,6 @@
 #include <net/if_ppp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
 #include <net/net_buf.h>
 #include <net/net_timer.h>
@@ -89,4 +91,5 @@
 #include <net/ppp_fsm.h>
 #include <net/ppp_lcp.h>
+#include <net/ppp_ipv6cp.h>
 #include <net/ppp_ipcp.h>
 #include <net/ppp_ccp.h>
@@ -108,17 +111,24 @@
 T_PPP_PROTENT *protocols[] = {
 	&lcp_protent,
+
+#ifdef _IP6_CFG
+	&ipv6cp_protent,
+#endif	/* of #ifdef _IP6_CFG */
+
+#ifdef _IP4_CFG
 	&ipcp_protent,
+#endif	/* of #ifdef _IP4_CFG */
 
 #ifdef SUPPORT_CCP
 	&ccp_protent,
-#endif	/* #ifdef SUPPORT_CCP */
+#endif	/* of #ifdef SUPPORT_CCP */
 
 #ifdef LCP_CFG_PAP
 	&pap_protent,
-#endif	/* #ifdef LCP_CFG_PAP */
+#endif	/* of #ifdef LCP_CFG_PAP */
 
 #ifdef LCP_CFG_CHAP
 	&chap_protent,
-#endif	/* #ifdef LCP_CFG_CHAP */
+#endif	/* of #ifdef LCP_CFG_CHAP */
 
 	NULL
@@ -223,7 +233,21 @@
 #endif	/* of #ifdef PPP_CFG_MODEM */
 
+#ifdef _IP6_CFG
+	/* IPV6CP の接続完了まで待つ。*/
+	if ((error = wait_ipv6cp()) != E_OK)
+		goto buf_ret;
+#endif	/* of #ifdef _IP6_CFG */
+
+#ifdef _IP4_CFG
 	/* IPCP の接続完了まで待つ。*/
 	if ((error = wait_ipcp()) != E_OK)
 		goto buf_ret;
+#endif	/* of #ifdef _IP4_CFG */
+
+#ifdef _IP4_CFG
+	/* IPCP の接続完了まで待つ。*/
+	if ((error = wait_ipcp()) != E_OK)
+		goto buf_ret;
+#endif	/* of #ifdef _IP4_CFG */
 
 #ifdef PPP_IDLE_TIMEOUT
@@ -290,4 +314,5 @@
 	ID		tskid;
 	int_t		ix;
+	uint8_t		rcount = 0;
 
 	/* ポートを初期設定する */
@@ -321,4 +346,7 @@
 	/* PPP 出力タスクを起動する */
 	syscall(act_tsk(PPP_OUTPUT_TASK));
+
+	/* 乱数生成を初期化する。*/
+	net_srand(0);
 
 	while (true) {
@@ -328,5 +356,10 @@
 			if (input->len > 0) {
 
-	#ifdef PPP_IDLE_TIMEOUT
+				/* 乱数生成を初期化する。*/
+				if (rcount == 0)
+					net_srand(input->len);
+				rcount ++;
+
+#ifdef PPP_IDLE_TIMEOUT
 				wai_sem(SEM_IDLE_TIMEOUT);
 				if (idle && ntohs(*GET_PPP_HDR(input)) != PPP_LCP) {
@@ -335,5 +368,5 @@
 					}
 				sig_sem(SEM_IDLE_TIMEOUT);
-	#endif	/* of #ifdef PPP_IDLE_TIMEOUT */
+#endif	/* of #ifdef PPP_IDLE_TIMEOUT */
 
 				parse_input(input);
@@ -342,5 +375,5 @@
 				syscall(rel_net_buf(input));
 
-	#ifdef PPP_IDLE_TIMEOUT
+#ifdef PPP_IDLE_TIMEOUT
 			wai_sem(SEM_IDLE_TIMEOUT);
 			if (!idle && ppp_phase == PPP_PHASE_NETWORK) {
@@ -353,5 +386,5 @@
 				}
 			sig_sem(SEM_IDLE_TIMEOUT);
-	#endif	/* of #ifdef PPP_IDLE_TIMEOUT */
+#endif	/* of #ifdef PPP_IDLE_TIMEOUT */
 
 			}
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -56,11 +56,18 @@
 	});
 
-CRE_DTQ(DTQ_PPP_OUTPUT,  { TA_TFIFO, NUM_DTQ_PPP_OUTPUT,  NULL });
+CRE_DTQ(DTQ_PPP_OUTPUT,   { TA_TFIFO, NUM_DTQ_PPP_OUTPUT,  NULL });
 
-CRE_SEM(SEM_MODEM_READY, { TA_TPRI, 0, 1 });
-CRE_SEM(SEM_IPCP_READY,  { TA_TPRI, 0, 1 });
+CRE_SEM(SEM_MODEM_READY,  { TA_TPRI, 0, 1 });
+
+#if defined(_IP6_CFG)
+CRE_SEM(SEM_IPV6CP_READY, { TA_TPRI, 0, 1 });
+#endif
+
+#if defined(_IP4_CFG)
+CRE_SEM(SEM_IPCP_READY,   { TA_TPRI, 0, 1 });
+#endif
 
 #ifdef PPP_IDLE_TIMEOUT
-CRE_SEM(SEM_IDLE_TIMEOUT,{ TA_TPRI, 1, 1 });
+CRE_SEM(SEM_IDLE_TIMEOUT, { TA_TPRI, 1, 1 });
 #endif	/* of #ifdef PPP_IDLE_TIMEOUT */
 
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -74,13 +74,15 @@
  */
 
-#define PPP_IP		UINT_C(0x0021)		/* IP   */
+#define PPP_IP		UINT_C(0x0021)		/* IPv4		*/
+#define PPP_IPV6	UINT_C(0x0057)		/* IPv6		*/
 
-#define PPP_IPCP	UINT_C(0x8021)		/* IPCP */
-#define PPP_CCP		UINT_C(0x80fd)		/* CCP */
+#define PPP_IPCP	UINT_C(0x8021)		/* IPCP		*/
+#define PPP_IPV6CP	UINT_C(0x8057)		/* IPV6CP	*/
+#define PPP_CCP		UINT_C(0x80fd)		/* CCP		*/
 
-#define PPP_LCP		UINT_C(0xc021)		/* LCP  */
-#define PPP_PAP		UINT_C(0xc023)		/* PAP  */
-#define PPP_LQR		UINT_C(0xc025)		/* LQR  */
-#define PPP_CHAP	UINT_C(0xc223)		/* CHAP */
+#define PPP_LCP		UINT_C(0xc021)		/* LCP		*/
+#define PPP_PAP		UINT_C(0xc023)		/* PAP		*/
+#define PPP_LQR		UINT_C(0xc025)		/* LQR		*/
+#define PPP_CHAP	UINT_C(0xc223)		/* CHAP		*/
 
 #define GET_PPP_HDR(nbuf)	((T_PPP_HDR*)((nbuf)->buf))
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_auth.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_auth.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_auth.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -100,4 +100,5 @@
 #include <net/if_ppp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/ppp.h>
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_auth.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_auth.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_auth.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_ccp.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_ccp.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_ccp.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -93,5 +93,4 @@
 #include <net/if_ppp.h>
 #include <net/net_buf.h>
-#include <net/net_debug.h>
 #include <net/net_count.h>
 #include <net/ppp.h>
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_ccp.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_ccp.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_ccp.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_fsm.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_fsm.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_fsm.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -86,4 +86,5 @@
 #include <net/if_ppp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_timer.h>
 #include <net/net_buf.h>
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_fsm.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_fsm.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_fsm.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -96,5 +96,5 @@
 	int8_t		retrans;	/* Configure-Request または、		*/
 					/* Terminate-Request の再送回数		*/
-	} __attribute__((packed, aligned(2)))T_PPP_FSM;
+	} T_PPP_FSM;
 
 #define T_PPP_FSM_DEFINED
@@ -124,5 +124,5 @@
 					/* 不明な CP を受信したときの処理	*/
 	bool_t  (*extcode)(T_PPP_FSM *, uint8_t, uint8_t, T_NET_BUF *);
-	} __attribute__((packed, aligned(2)))T_PPP_FSM_CALLBACKS;
+	} T_PPP_FSM_CALLBACKS;
 
 /*
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_hdlc.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_hdlc.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_hdlc.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -65,4 +65,5 @@
 #include <net/if_ppp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_count.h>
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_hdlc.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_hdlc.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_hdlc.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_ipcp.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_ipcp.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_ipcp.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -89,4 +89,5 @@
 #include <net/if_ppp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_count.h>
@@ -102,6 +103,6 @@
 #include <netinet/ip.h>
 #include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
 #include <netinet/tcp_timer.h>
-#include <netinet/tcp_var.h>
 #include <netinet/udp_var.h>
 
@@ -149,5 +150,5 @@
 	NULL,
 	{
-		IPV4_ADDR_LOCAL,		/* IP アドレス			*/
+		IPV4_ADDR_LOCAL,		/* IPv4 アドレス			*/
 		UINT_C(0),			/* サブネットマスク		*/
 		},
@@ -157,5 +158,5 @@
 	NULL,
 	{
-		IPV4_ADDR_REMOTE,		/* IP アドレス			*/
+		IPV4_ADDR_REMOTE,		/* IPv4 アドレス			*/
 		UINT_C(0),			/* サブネットマスク		*/
 		}
@@ -200,5 +201,5 @@
 	ipcp_open,			/* オープンする			*/
 	ipcp_close,			/* クローズする			*/
-	ip_input,			/* データ入力、IP 入力		*/
+	ip_input,			/* データ入力、IPv4 入力	*/
 	};
 
@@ -307,5 +308,5 @@
 	int_t cilen = 0;
 
-	cilen += sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);	/* IP アドレス */
+	cilen += sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);	/* IPv4 アドレス */
 
 	return cilen;
@@ -323,8 +324,8 @@
 	buf = output->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
 
-	/* IP アドレスオプションを追加する。 */
+	/* IPv4 アドレスオプションを追加する。 */
 	*buf ++ = IPCP_CIT_ADDR;
 	*buf ++ = sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
-	ahtonl(buf, ipcp_local_neg_cfg.in_ifaddr.addr);
+	ahtonl(buf, ipcp_local_neg_cfg.in4_ifaddr.addr);
 	buf += sizeof(uint32_t);
 	}
@@ -355,5 +356,5 @@
 	    *buf ++ != IPCP_CIT_ADDR			||
 	    *buf ++ != sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)||
-	    nahcmpl(buf, ipcp_local_neg_cfg.in_ifaddr.addr))
+	    nahcmpl(buf, ipcp_local_neg_cfg.in4_ifaddr.addr))
 		return false;
 	buf += sizeof(uint32_t);
@@ -390,5 +391,5 @@
 		buf += sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
 		len -= sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
-		new_cfg.in_ifaddr.addr = cilong;
+		new_cfg.in4_ifaddr.addr = cilong;
 		}
 
@@ -438,5 +439,5 @@
 		buf += sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
 		len -= sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
-		new_cfg.in_ifaddr.addr = 0;
+		new_cfg.in4_ifaddr.addr = 0;
 		}
 
@@ -499,5 +500,5 @@
 		switch (type) {
 
-		case IPCP_CIT_ADDR:	/* IP アドレス */
+		case IPCP_CIT_ADDR:	/* IPv4 アドレス */
 
 		 	/* CI 長が、ヘッダ + 4 オクテットでなければエラー */
@@ -506,20 +507,20 @@
 			else {
 				ntoahl(addr, ap);
-				if (addr != ipcp_remote_neg_cfg.in_ifaddr.addr &&
-				    (addr == 0 || ipcp_remote_neg_cfg.in_ifaddr.addr != 0)) {
+				if (addr != ipcp_remote_neg_cfg.in4_ifaddr.addr &&
+				    (addr == 0 || ipcp_remote_neg_cfg.in4_ifaddr.addr != 0)) {
 					*np ++ = IPCP_CIT_ADDR;
 					*np ++ = sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
-					ahtonl(np, ipcp_remote_neg_cfg.in_ifaddr.addr);
+					ahtonl(np, ipcp_remote_neg_cfg.in4_ifaddr.addr);
 					np  += sizeof(uint32_t);
 					code = PPP_CONFNAK;
 					}
 #if 1	/* 要確認 */
-				else if (addr == 0 && ipcp_remote_neg_cfg.in_ifaddr.addr == 0)
+				else if (addr == 0 && ipcp_remote_neg_cfg.in4_ifaddr.addr == 0)
 #else
-				else if (addr == 0 || ipcp_remote_neg_cfg.in_ifaddr.addr == 0)
+				else if (addr == 0 || ipcp_remote_neg_cfg.in4_ifaddr.addr == 0)
 #endif
 					code = PPP_CONFREJ;
 				else
-					ipcp_remote_neg_cfg.in_ifaddr.addr = addr;
+					ipcp_remote_neg_cfg.in4_ifaddr.addr = addr;
 				}
 			break;
@@ -582,7 +583,7 @@
 	/*
 	 *  サブネットマスクと
-	 *  ローカル・ブロードキャスト IP アドレスを設定する。
+	 *  ローカル・ブロードキャスト IPv4 アドレスを設定する。
 	 */
-	ipcp_local_ack_cfg.in_ifaddr.mask = MAKE_IPV4_LOCAL_MASK(ipcp_local_neg_cfg.in_ifaddr.addr);
+	ipcp_local_ack_cfg.in4_ifaddr.mask = MAKE_IPV4_LOCAL_MASK(ipcp_local_neg_cfg.in4_ifaddr.addr);
 
 	/* 相手の構成情報の初期設定 */
@@ -591,13 +592,13 @@
 	/*
 	 *  サブネットマスクと
-	 *  ローカル・ブロードキャスト IP アドレスを設定する。
+	 *  ローカル・ブロードキャスト IPv4 アドレスを設定する。
 	 */
-	ipcp_remote_ack_cfg.in_ifaddr.mask = MAKE_IPV4_LOCAL_MASK(ipcp_remote_neg_cfg.in_ifaddr.addr);
+	ipcp_remote_ack_cfg.in4_ifaddr.mask = MAKE_IPV4_LOCAL_MASK(ipcp_remote_neg_cfg.in4_ifaddr.addr);
 
 	sig_sem(SEM_IPCP_READY);
 
-	syslog(LOG_NOTICE, "[PPP/IPCP] up, Local IP Addr: %s, Remote IP Addr: %s.",
-	                   ip2str(NULL, &ipcp_local_neg_cfg.in_ifaddr.addr),
-	                   ip2str(NULL, &ipcp_remote_neg_cfg.in_ifaddr.addr));
+	syslog(LOG_NOTICE, "[PPP/IPCP] up, Local IPv4 Addr: %s, Remote IPv4 Addr: %s.",
+	                   ip2str(NULL, &ipcp_local_neg_cfg.in4_ifaddr.addr),
+	                   ip2str(NULL, &ipcp_remote_neg_cfg.in4_ifaddr.addr));
 	}
 
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_ipcp.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_ipcp.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_ipcp.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_ipv6cp.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_ipv6cp.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_ipv6cp.c	(revision 331)
@@ -0,0 +1,713 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * ipv6cp.c - PPP IP Control Protocol.
+ *
+ * Copyright (c) 1989 Carnegie Mellon University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by Carnegie Mellon University.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ *	PPP IP Control Protocol (IPV6CP) Module
+ *
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the Internet Initiative Japan, Inc.  The name of the
+ * IIJ may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD: src/usr.sbin/ppp/ipv6cp.c,v 1.90.2.4 2000/08/19 09:30:03 brian Exp $
+ *
+ *	TODO:
+ *		o Support IPADDRS properly
+ *		o Validate the length in IpcpDecodeConfig
+ */
+
+#include <string.h>
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_ppp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_count.h>
+#include <net/ppp.h>
+#include <net/ppp_var.h>
+#include <net/ppp_fsm.h>
+#include <net/ppp_lcp.h>
+#include <net/ppp_ipv6cp.h>
+#include <net/ppp_modem.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/udp_var.h>
+
+#include <net/if_var.h>
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  é¢æ°
+ */
+
+static void ipv6cp_init (void);
+static void ipv6cp_input (T_NET_BUF *input);
+static void ipv6cp_protrej (void);
+static void ipv6cp_lowerup (void);
+static void ipv6cp_lowerdown (void);
+static void ipv6cp_open (void);
+static void ipv6cp_close (void);
+
+/*
+ * FSM ããå¼åºãããã³ã¼ã«ããã¯é¢
+ */
+
+static void  ipv6cp_resetci(T_PPP_FSM *fsm);	/* èªæ§ææ
+å ±ããªã»ããããã	*/
+static int_t ipv6cp_cilen	(T_PPP_FSM *fsm);	/* æ§ææ
+å ±ã®é·ããè¿ãã		*/
+static void  ipv6cp_addci	(T_PPP_FSM *fsm, T_NET_BUF *output);
+						/* èªæ§ææ
+å ±ãè¿½å ããã		*/
+static bool_t  ipv6cp_ackci	(T_PPP_FSM *fsm, T_NET_BUF *input);
+						/* ACK ãåä¿¡ããã¨ãã®å¦ç	*/
+static bool_t  ipv6cp_nakci	(T_PPP_FSM *fsm, T_NET_BUF *input);
+						/* NAK ãåä¿¡ããã¨ãã®å¦ç	*/
+static bool_t  ipv6cp_rejci	(T_PPP_FSM *fsm, T_NET_BUF *input);
+						/* REJ ãåä¿¡ããã¨ãã®å¦ç	*/
+static int_t ipv6cp_reqci	(T_PPP_FSM *fsm, T_NET_BUF *input, T_NET_BUF *output);
+						/* ç¸æã®æ§ææ
+å ±ãç¢ºèªããã	*/
+static void ipv6cp_up	(T_PPP_FSM *fsm);	/* ãªã³ã¯æ¥ç¶ãç¢ºç«ããã		*/
+static void ipv6cp_down	(T_PPP_FSM *fsm);	/* ãªã³ã¯æ¥ç¶ãè§£æ¾ããã		*/
+static void ipv6cp_finished(T_PPP_FSM *fsm);	/* ä¸ä½å±¤ãçµäºããã		*/
+
+/*
+ *  å¤æ°
+ */
+
+static T_IFNET ipv6cp_local_def_cfg = {		/* èªæ§ææ
+å ±ã®è¦å®å¤		*/
+	NULL,					/* ãããã¯ã¼ã¯ã¤ã³ã¿ãã§ã¼ã¹ã®ã½ããã¦ã§ã¢æ
+å ±	*/
+	{},					/* IPv6 ã¢ãã¬ã¹æ
+å ±				*/
+	{},					/* ãã«ãã­ã£ã¹ã IPv6 ã¢ãã¬ã¹			*/
+	0,					/* ãã©ã°					*/
+	};
+
+static T_IFNET ipv6cp_remote_def_cfg = {	/* ç¸æã®æ§ææ
+å ±ã®è¦å®å¤	*/
+	NULL,					/* ãããã¯ã¼ã¯ã¤ã³ã¿ãã§ã¼ã¹ã®ã½ããã¦ã§ã¢æ
+å ±	*/
+	{},					/* IPv6 ã¢ãã¬ã¹æ
+å ±				*/
+	{},					/* ãã«ãã­ã£ã¹ã IPv6 ã¢ãã¬ã¹			*/
+	0,					/* ãã©ã°					*/
+	};
+
+static T_IFNET ipv6cp_local_neg_cfg;		/* ãã´ä¸­ã®èªæ§ææ
+å ±		*/
+
+static T_IFNET ipv6cp_remote_neg_cfg;		/* ãã´ä¸­ã®ç¸æã®æ§ææ
+å ±		*/
+
+/*
+ *  å
+¨åå¤æ°
+ */
+
+T_PPP_FSM_CALLBACKS ipv6cp_callbacks = {
+	ipv6cp_resetci,			/* èªæ§ææ
+å ±ããªã»ããããã	*/
+	ipv6cp_cilen,			/* æ§ææ
+å ±ã®é·ããè¿ãã		*/
+	ipv6cp_addci,			/* èªæ§ææ
+å ±ãè¿½å ããã		*/
+	ipv6cp_ackci,			/* ACK ãåä¿¡ããã¨ãã®å¦ç	*/
+	ipv6cp_nakci,			/* NAK ãåä¿¡ããã¨ãã®å¦ç	*/
+	ipv6cp_rejci,			/* REJ ãåä¿¡ããã¨ãã®å¦ç	*/
+	ipv6cp_reqci,			/* ç¸æã®æ§ææ
+å ±ãç¢ºèªããã	*/
+	ipv6cp_up,			/* ãªã³ã¯æ¥ç¶ãç¢ºç«ããã		*/
+	ipv6cp_down,			/* ãªã³ã¯æ¥ç¶ãè§£æ¾ããã		*/
+	NULL,				/* ä¸ä½å±¤ãéå§ããã		*/
+	ipv6cp_finished,			/* ä¸ä½å±¤ãçµäºããã		*/
+	NULL,				/* åéããã			*/
+	NULL,				/* ä¸æãª CP ãåä¿¡ããã¨ãã®å¦ç	*/
+	};
+
+T_PPP_FSM ipv6cp_fsm = {
+	&ipv6cp_callbacks,		/* ã³ã¼ã«ããã¯é¢æ°		*/
+	PPP_IPV6CP,			/* ãã­ãã³ã«			*/
+	};
+
+T_PPP_PROTENT ipv6cp_protent = {
+	PPP_IPV6CP,
+	ipv6cp_init,			/* åæå			*/
+	ipv6cp_input,			/* å
+¥å				*/
+	ipv6cp_protrej,			/* Proto-REJ åä¿¡å¦ç		*/
+	ipv6cp_lowerup,			/* ä¸ä½å±¤ãèµ·åãã		*/
+	ipv6cp_lowerdown,		/* ä¸ä½å±¤ãåæ­¢ãã		*/
+	ipv6cp_open,			/* ãªã¼ãã³ãã			*/
+	ipv6cp_close,			/* ã¯ã­ã¼ãºãã			*/
+	ip6_input,			/* ãã¼ã¿å
+¥åãIPv6 å
+¥å	*/
+	};
+
+T_IFNET ipv6cp_local_ack_cfg;		/* ç¸æã«è¨±å¯ãããã®èªæ§ææ
+å ±	*/
+T_IFNET ipv6cp_remote_ack_cfg;		/* ç¸æã«è¨±å¯ããæ§ææ
+å ±	*/
+
+/*
+ *  ppp_get_ifnet -- ãããã¯ã¼ã¯ã¤ã³ã¿ãã§ã¼ã¹æ§é ä½ãè¿ãã
+ */
+
+T_IFNET *
+ppp_get_ifnet (void)
+{
+	return &ipv6cp_local_ack_cfg;
+	}
+
+/*
+ *  wait_ipv6cp -- IP æ¥ç¶å®äºã¾ã§å¾
+ã¤ã
+ *
+ *	æ»ãå¤: æ¥ç¶ã«å¤±æããã E_OBJ ãè¿ãã
+ */
+
+ER
+wait_ipv6cp (void)
+{
+#ifdef PPP_CFG_MODEM
+	ER error;
+#endif	/* of #ifdef PPP_CFG_MODEM */
+
+	if (ipv6cp_fsm.state <= PPP_FSM_STOPPED) {
+
+#ifdef PPP_CFG_MODEM
+
+		/* ã¢ãã ã®æ¥ç¶å®äºã¾ã§å¾
+ã¤ã*/
+		if ((error = wait_modem()) != E_OK)
+			return error;
+
+#else	/* of #ifdef PPP_CFG_MODEM */
+
+		/*
+		 * ååãªã¼ãã³ããç¸æããã®æ¥ç¶å¾
+ã¡ãªã LCP ãä¸åº¦ã¯ã­ã¼ãºãã
+		 * è½åãªã¼ãã³ç¶æ
+ã§ãåãªã¼ãã³ããã
+		 */
+		lcp_close();
+		lcp_open(PPP_OPEN_ACTIVE);
+
+#endif	/* of #ifdef PPP_CFG_MODEM */
+
+		}
+
+	if (ipv6cp_fsm.state != PPP_FSM_OPENED) {
+		/* IP æ¥ç¶å®äºã¾ã§å¾
+ã¤ã*/
+		wai_sem(SEM_IPV6CP_READY);
+		if (ipv6cp_fsm.state != PPP_FSM_OPENED)
+			return E_OBJ;
+		}
+
+	return E_OK;
+	}
+
+/*
+ *  ipv6cp_init -- IPV6CP ã¢ã¸ã¥ã¼ã«ã®åæå
+ */
+
+static void
+ipv6cp_init (void)
+{
+	fsm_init(&ipv6cp_fsm);
+	}
+
+/*
+ *  ipv6cp_input -- IPV6CP å
+¥å
+ */
+
+static void
+ipv6cp_input (T_NET_BUF *input)
+{
+	NET_COUNT_PPP_IPV6CP(net_count_ppp_ipv6cp_in_octets,  input->len);
+	NET_COUNT_PPP_IPV6CP(net_count_ppp_ipv6cp_in_packets, 1);
+	fsm_input(&ipv6cp_fsm, input);
+	}
+
+/*
+ *  ipv6cp_resetci -- IPV6CPã®æ§ææ
+å ±ããªã»ããããã
+ */
+
+static void
+ipv6cp_resetci (T_PPP_FSM *fsm)
+{
+	/* èªæ§ææ
+å ±ã®åæè¨­å® */
+	ipv6cp_local_neg_cfg = ipv6cp_local_def_cfg;
+	memset((void*)&ipv6cp_local_ack_cfg, 0, sizeof(T_IFNET));
+
+	/* ç¸æã®æ§ææ
+å ±ã®åæè¨­å® */
+	ipv6cp_remote_neg_cfg = ipv6cp_remote_def_cfg;
+	memset((void*)&ipv6cp_remote_ack_cfg, 0, sizeof(T_IFNET));
+	}
+
+/*
+ *  ipv6cp_cilen -- æ§ææ
+å ±ã®é·ããè¿ãã
+ */
+
+static int_t
+ipv6cp_cilen (T_PPP_FSM *fsm)
+{
+	int_t cilen = 0;
+
+	cilen += sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);	/* IPv6 ã¢ãã¬ã¹ */
+
+	return cilen;
+	}
+
+/*
+ *  ipv6cp_addci -- IPV6CPã®æ§ææ
+å ±ãè¿½å ããã
+ */
+
+static void
+ipv6cp_addci (T_PPP_FSM *fsm, T_NET_BUF *output)
+{
+	uint8_t *buf;
+
+	buf = output->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+
+	/* IPv6 ã¢ãã¬ã¹ãªãã·ã§ã³ãè¿½å ããã */
+	*buf ++ = IPV6CP_CIT_ADDR;
+	*buf ++ = sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+	ahtonl(buf, ipv6cp_local_neg_cfg.in6_ifaddrs[0].addr);
+	buf += sizeof(uint32_t);
+	}
+
+/*
+ *  ipv6cp_ackci -- ACK ãåä¿¡ããã¨ãã®å¦ç
+ *
+ *	æ»ãå¤:	true  ACK ã¯æ­£å¸¸
+ *		false ACK ã¯ç°å¸¸
+ */
+
+static bool_t
+ipv6cp_ackci (T_PPP_FSM *fsm, T_NET_BUF *input)
+{
+	uint8_t		*buf;
+	uint16_t	len;
+
+	buf = input->buf +  sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+	len = input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+
+	/*
+	 *  æ§ææ
+å ±ã¯éä¿¡ããé ã«å®å
+¨ã«ä¸è´ããªããã°ãªããªãã
+	 *  å¾ã£ã¦ãipv6cp_addci ã§ä½æããé ã«è§£æããã
+	 */
+
+	/* ADDR ãªãã·ã§ã³ãè§£æããã */
+	if (len < sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)	||
+	    *buf ++ != IPV6CP_CIT_ADDR			||
+	    *buf ++ != sizeof(T_PPP_CI_HDR) + sizeof(uint32_t)||
+	    nahcmpl(buf, ipv6cp_local_neg_cfg.in6_ifaddrs[0].addr))
+		return false;
+	buf += sizeof(uint32_t);
+	len -= sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+
+	return true;
+	}
+
+/*
+ *  ipv6cp_nakci -- NAK ãåä¿¡ããã¨ãã®å¦ç
+ *
+ *	æ»ãå¤:	1  NAK ã¯æ­£å¸¸
+ *		0  NAK ã¯ç°å¸¸
+ */
+
+static int_t
+ipv6cp_nakci (T_PPP_FSM *fsm, T_NET_BUF *input)
+{
+	T_IFNET		new_cfg;
+	uint32_t	addr;
+	uint16_t	len;
+	uint8_t		*buf, cilen;
+
+	buf = input->buf +  sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+	len = input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+
+	new_cfg = ipv6cp_local_neg_cfg;
+
+	/* ADDR ãªãã·ã§ã³ãè§£æããã */
+	if (len >= sizeof(T_PPP_CI_HDR) + sizeof(addr)		&&
+	    * buf      == IPV6CP_CIT_ADDR			&&
+	    *(buf + 1) == sizeof(T_PPP_CI_HDR) + sizeof(addr)) {
+		memcpy(&new_cfg.in6_ifaddrs[0].addr, buf + 2, sizeof(addr));
+		buf += sizeof(T_PPP_CI_HDR) + sizeof(addr);
+		len -= sizeof(T_PPP_CI_HDR) + sizeof(addr);
+		}
+
+	/* å¾ã¯ç¡è¦ããã*/
+	while (len > sizeof(T_PPP_CI_HDR)) {
+		cilen = *(buf + 1);
+		if (len < cilen)
+			return 0;
+		buf += cilen;
+		len -= cilen;
+		}
+
+	/* é·ãã 0 ã§ãªããã°ã¨ã©ã¼ */
+	if (len != 0)
+		return 0;
+
+	/* æ°ãããªãã·ã§ã³ãè¨­å®ããã*/
+	if (fsm->state != PPP_FSM_OPENED)
+		ipv6cp_local_neg_cfg = new_cfg;
+               		
+	return 1;
+	}
+
+/*
+ *  ipv6cp_rejci -- REJ ãåä¿¡ããã¨ãã®å¦ç
+ *
+ *	æ»ãå¤:	1  REJ ã¯æ­£å¸¸
+ *		0  REJ ã¯ç°å¸¸
+ */
+
+static int_t
+ipv6cp_rejci (T_PPP_FSM *fsm, T_NET_BUF *input)
+{
+	T_IFNET		new_cfg;
+	uint8_t		*buf;
+	uint16_t	len;
+
+	buf = input->buf +  sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+	len = input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+
+	new_cfg = ipv6cp_local_neg_cfg;
+
+	/* ADDR ãªãã·ã§ã³ãè§£æããã */
+	if (len >= sizeof(T_PPP_CI_HDR) + sizeof(new_cfg.in6_ifaddrs[0].addr)	&&
+	    * buf      == IPV6CP_CIT_ADDR					&&
+	    *(buf + 1) == sizeof(T_PPP_CI_HDR) + sizeof(new_cfg.in6_ifaddrs[0].addr)) {
+		memcpy(&new_cfg.in6_ifaddrs[0].addr, &in6_addr_unspecified,
+		 sizeof(new_cfg.in6_ifaddrs[0].addr));
+		buf += sizeof(T_PPP_CI_HDR) + sizeof(new_cfg.in6_ifaddrs[0].addr);
+		len -= sizeof(T_PPP_CI_HDR) + sizeof(new_cfg.in6_ifaddrs[0].addr);
+		}
+
+	/* é·ãã 0 ã§ãªããã°ã¨ã©ã¼ */
+	if (len != 0)
+		return 0;
+
+	/* æ°ãããªãã·ã§ã³ãè¨­å®ããã*/
+	if (fsm->state != PPP_FSM_OPENED)
+		ipv6cp_local_neg_cfg = new_cfg;
+
+	return 1;
+	}
+
+/*
+ *  ipv6cp_reqci -- ç¸æã®æ§ææ
+å ±ãè§£æããã
+ */
+
+static int_t
+ipv6cp_reqci (T_PPP_FSM *fsm, T_NET_BUF *input, T_NET_BUF *output)
+{
+	T_IN6_ADDR	addr;
+	uint16_t	code, final, len, cilen;
+	uint8_t		*np, *rp, *ap, *cp, type = 0;
+
+	rp = ap = input->buf +  sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+				/* rp: REJãap: ACK ãã CI ã®ãã¤ã³ã¿	*/
+				/* æå¦ããå ´åã¯ãå¼æ° buf ã«ä¸æ¸ãããã	*/
+	len   = input->len - (sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+	np    = output->buf + sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR);
+	final = PPP_CONFACK;	/* æçµçã«éä¿¡ããã³ã¼ã */
+	while (len > 0) {
+		code = PPP_CONFACK;
+		cp   = ap;	/* cp: ç¾å¨å¦çä¸­ã® CI	*/
+
+		if (len < sizeof(T_PPP_CI_HDR)) {
+
+			/* æ®ãã CI ãããããç­ã */
+			syslog(LOG_NOTICE, "[PPP/IPV6CP] bad CI len: %d.", len);
+			cilen = len;	/* ãã¼ã¿é·ãç°å¸¸ã®å ´åã®å¦ç½®	*/
+			len  = 0;	/* ã«ã¼ãããæããã		*/
+			code  = PPP_CONFREJ;
+			goto endswitch;
+			}
+
+		type  = *ap ++;	/* CI ã®å		*/
+		cilen = *ap ++;	/* CI ã®é·ã		*/
+		if (len < cilen) {
+
+			/* æ®ãã CI é·ããç­ã */
+			syslog(LOG_NOTICE, "[PPP/IPV6CP] bad CI len: %d.", cilen);
+			cilen = len;	/* ãã¼ã¿é·ãç°å¸¸ã®å ´åã®å¦ç½®	*/
+			len  = 0;	/* ã«ã¼ãããæããã		*/
+			code  = PPP_CONFREJ;
+			goto endswitch;
+			}
+		len -= sizeof(T_PPP_CI_HDR);
+
+		/* CI ã®åã«ããåå²ããã*/
+		switch (type) {
+
+		case IPV6CP_CIT_ADDR:	/* IPv6 ã¢ãã¬ã¹ */
+
+		 	/* CI é·ããããã + 4 ãªã¯ãããã§ãªããã°ã¨ã©ã¼ */
+		 	if (cilen != sizeof(T_PPP_CI_HDR) + sizeof(addr))
+				code = PPP_CONFREJ;
+			else {
+				memcpy((uint8_t*)&ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr, ap,
+				           sizeof(ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr));
+				if (!IN6_ARE_ADDR_EQUAL(&addr, &ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr) &&
+				    (IN6_IS_ADDR_UNSPECIFIED(&addr) ||
+				     IN6_IS_ADDR_UNSPECIFIED(&ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr))) {
+					memcpy(np, (uint8_t*)&ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr,
+					               sizeof(ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr));
+					*np ++ = IPV6CP_CIT_ADDR;
+					*np ++ = sizeof(T_PPP_CI_HDR) + sizeof(uint32_t);
+					np    += sizeof(ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr);
+					code = PPP_CONFNAK;
+					}
+#if 1	/* è¦ç¢ºèª */
+				else if (IN6_IS_ADDR_UNSPECIFIED(&addr) &&
+				         IN6_IS_ADDR_UNSPECIFIED(&ipv6cp_remote_neg_cfg.in6_ifaddrs[0]))
+#else
+				else if (IN6_IS_ADDR_UNSPECIFIED(&addr) ||
+				         IN6_IS_ADDR_UNSPECIFIED(&ipv6cp_remote_neg_cfg.in6_ifaddrs[0]))
+#endif
+					code = PPP_CONFREJ;
+				else
+					ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr = addr;
+				}
+			break;
+
+		default:
+			syslog(LOG_INFO, "[PPP/IPV6CP] unexp opt: %d.", type);
+			code = PPP_CONFREJ;
+			break;
+			}
+endswitch:
+
+		if (code == PPP_CONFNAK) {
+			/* CI ã®åã Magic Number ã®å ´åãé¤ãã¦ãNAK ã®åæ°ã	*/
+			/* æå¤§å¤ MAX_PPP_FAILURES  ãè¶
+ãããæå¦ããã	*/
+			if (fsm->failures >= MAX_PPP_FAILURES)
+				code = PPP_CONFREJ;
+			else if (final != PPP_CONFREJ)
+				final = PPP_CONFNAK;
+			}
+
+		/* ãã® CI ãæå¦ãã */
+		if (code == PPP_CONFREJ) {
+			if (rp < cp)		/* åã«è©°ããã*/
+				memcpy(rp, cp, cilen);
+			rp += cilen;
+			final = PPP_CONFREJ;
+			}
+
+		ap   += cilen - sizeof(T_PPP_CI_HDR);
+		len  -= cilen - sizeof(T_PPP_CI_HDR);
+		}
+
+	/* æçµçãªé·ããèª¿æ´ããã*/
+	switch (final) {
+	case PPP_CONFNAK:
+		output->len = np - output->buf;
+		memcpy(output->buf, input->buf, sizeof(T_PPP_HDR) + sizeof(T_PPP_CP_HDR));
+		break;
+	case PPP_CONFREJ:
+		memcpy(output->buf, input->buf, output->len = rp - input->buf);
+		break;
+	case PPP_CONFACK:
+		memcpy(output->buf, input->buf, input->len);
+		break;
+		}
+
+	return final;
+	}
+
+/*
+ *  ipv6cp_up -- ãªã³ã¯æ¥ç¶ãç¢ºç«ããã
+ */
+
+static void
+ipv6cp_up (T_PPP_FSM *fsm)
+{
+	/* èªæ§ææ
+å ±ã®åæè¨­å® */
+	ipv6cp_local_ack_cfg = ipv6cp_local_neg_cfg;
+
+	sig_sem(SEM_IPV6CP_READY);
+
+	syslog(LOG_NOTICE, "[PPP/IPV6CP] up, Local IPv6 Addr: %s, Remote IPv6 Addr: %s.",
+	                   ipv62str(NULL, &ipv6cp_local_neg_cfg.in6_ifaddrs[0].addr),
+	                   ipv62str(NULL, &ipv6cp_remote_neg_cfg.in6_ifaddrs[0].addr));
+	}
+
+/*
+ *  ipv6cp_down -- ãªã³ã¯æ¥ç¶ãè§£æ¾ããã
+ */
+
+static void
+ipv6cp_down (T_PPP_FSM *fsm)
+{
+	sig_sem(SEM_IPV6CP_READY);
+	syslog(LOG_NOTICE, "[PPP/IPV6CP] down.");
+	}
+
+/*
+ *  ipv6cp_finished -- ä¸ä½å±¤ãçµäºããã
+ */
+
+static void
+ipv6cp_finished (T_PPP_FSM *fsm)
+{
+	}
+
+/*
+ *  ipv6cp_protrej -- Proto-REJ ãåä¿¡ããã¨ãã®å¦ç
+ */
+
+static void
+ipv6cp_protrej (void)
+{
+	fsm_lowerdown(&ipv6cp_fsm);
+	}
+
+/*
+ *  ipv6cp_lowerup -- IPV6CP ä¸ä½å±¤ãèµ·åããã
+ */
+
+static void
+ipv6cp_lowerup (void)
+{
+	fsm_lowerup(&ipv6cp_fsm);
+	}
+
+/*
+ *  ipv6cp_lowerdown -- IPV6CP ä¸ä½å±¤ãåæ­¢ããã
+ */
+
+static void
+ipv6cp_lowerdown (void)
+{
+	fsm_lowerdown(&ipv6cp_fsm);
+	}
+
+/*
+ *  ipv6cp_open -- IPV6CP ã®ãªã¼ãã³
+ */
+
+static void
+ipv6cp_open (void)
+{
+	fsm_open(&ipv6cp_fsm);
+	}
+
+/*
+ *  ipv6cp_close -- IPV6CP ã®ã¯ã­ã¼ãº
+ */
+
+static void
+ipv6cp_close (void)
+{
+	fsm_close(&ipv6cp_fsm);
+	}
+
+#endif	/* fo #ifdef SUPPORT_PPP */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_ipv6cp.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_ipv6cp.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_ipv6cp.h	(revision 331)
@@ -0,0 +1,143 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * ipv6cp.h - IP Control Protocol definitions.
+ *
+ * Copyright (c) 1989 Carnegie Mellon University.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by Carnegie Mellon University.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD: src/usr.sbin/pppd/ipv6cp.h,v 1.9.2.1 1999/08/29 15:47:01 peter Exp $
+ */
+
+/*
+ *	    Written by Toshiharu OHNO (tony-o@iij.ad.jp)
+ *
+ *   Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the Internet Initiative Japan.  The name of the
+ * IIJ may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD: src/usr.sbin/ppp/ipv6cp.h,v 1.30.2.2 2000/06/15 17:08:28 brian Exp $
+ *
+ *	TODO:
+ */
+
+#ifndef _PPP_IPV6CP_H_
+#define _PPP_IPV6CP_H_
+
+#ifdef SUPPORT_PPP
+
+/*
+ *  IPV6CP ã®æ§ææ
+å ± (CI)
+ */
+
+/*
+ *  CI ã®å
+ */
+
+#define IPV6CP_CIT_ADDRS		UINT_C(1)	/* IP ã¢ãã¬ã¹ (å»æ£)	*/
+#define IPV6CP_CIT_COMP_TYPE	UINT_C(2)	/* å§ç¸®æ¹å¼		*/
+#define IPV6CP_CIT_ADDR		UINT_C(3)	/* IP ã¢ãã¬ã¹		*/
+
+/*
+ *  åæ¹åç
+§
+ */
+
+#ifndef T_IFNET_DEFINED
+
+typedef struct t_ifnet T_IFNET;
+
+#define T_IFNET_DEFINED
+
+#endif	/* of #ifndef T_IFNET_DEFINED */
+
+/*
+ *  å¤æ°
+ */
+
+#ifdef T_PPP_FSM_DEFINED
+extern T_PPP_FSM	ipv6cp_fsm;
+#endif	/* of #ifdef T_PPP_FSM_DEFINED */
+
+#ifdef T_PPP_PROTENT_DEFINED
+extern T_PPP_PROTENT	ipv6cp_protent;
+#endif	/* of #ifdef T_PPP_PROTENT_DEFINED */
+
+extern T_IFNET	ipv6cp_local_ack_cfg;
+extern T_IFNET	ipv6cp_remote_ack_cfg;
+
+/*
+ *  é¢æ°
+ */
+
+extern ER wait_ipv6cp (void);
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#endif	/* of #ifndef _PPP_IPV6CP_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_lcp.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_lcp.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_lcp.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -86,4 +86,5 @@
 #include <net/if_ppp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_var.h>
 #include <net/net_buf.h>
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_lcp.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_lcp.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_lcp.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_modem.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_modem.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_modem.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -47,4 +47,5 @@
 #include <net/if_ppp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_count.h>
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_modem.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_modem.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_modem.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_upap.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_upap.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_upap.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -87,4 +87,5 @@
 #include <net/if_ppp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_timer.h>
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_upap.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_upap.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_upap.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_var.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_var.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/ppp_var.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/route.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/route.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/route.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/net/tinet.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/net/tinet.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/net/tinet.h	(revision 331)
@@ -0,0 +1,59 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _TINET_H_
+#define _TINET_H_
+
+#if !defined(TOPPERS_MACRO_ONLY) && !defined(_MACRO_ONLY)
+
+/*
+ *  TINET ç¬èªé¢æ°
+ */
+
+extern char *mac2str (char *buf, uint8_t *macaddr);
+
+#endif /* #if !defined(TOPPERS_MACRO_ONLY) && !defined(_MACRO_ONLY) */
+
+#endif	/* of #ifndef _TINET_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/Makefile.netapp
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/Makefile.netapp	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/Makefile.netapp	(revision 331)
@@ -2,5 +2,5 @@
 #   TINET (TCP/IP Protocol Stack)
 #  
-#   Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+#   Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
 #                    Tomakomai National College of Technology, JAPAN
 # 
@@ -50,11 +50,25 @@
 
 TINET_ROOT = $(SRCDIR)/tinet
-NETAPP_DIR = $(TINET_ROOT)/netapp
+NETAPP_DIRS = $(TINET_ROOT)/netapp
 NETAPP_COBJS := $(NETAPP_COBJS) netapp_subr.o
 
+ifeq ($(USE_LCD),true)
+
+	NETAPP_COBJS := $(NETAPP_COBJS) lcd.o
+
+ifeq ($(TARGET_KERNEL),ASP)
+	NETAPP_COBJS := $(NETAPP_COBJS) target_lcd.o sc1602.o
+endif
+
+ifeq ($(TARGET_KERNEL),JSP)
+	NETAPP_COBJS := $(NETAPP_COBJS) hw_lcd.o sc1602.o
+endif
+
+endif
+
 #  トランスポート層の選択
 
-SUPPORT_TCP = false
-SUPPORT_UDP = false
+#SUPPORT_TCP = false
+#SUPPORT_UDP = false
 
 # 
@@ -62,37 +76,87 @@
 # 
 
+ifeq ($(USE_WWW4_SRV),true)
+	USE_WWW_SRV = true
+	CDEFS := $(CDEFS) -DUSE_WWW4_SRV
+endif
+
 ifeq ($(USE_WWW_SRV),true)
-	SUPPORT_TCP = true
-	TCP_CFG_PASSIVE_OPEN = true
+
+	SUPPORT_TCP = true
 	USE_NETAPP_SUBR = true
 	CDEFS := $(CDEFS) -DUSE_WWW_SRV
 	NETAPP_COBJS := $(NETAPP_COBJS) wwws.o
-	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIR)/wwws.cfg
+	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/wwws.cfg
+
+endif
+
+ifeq ($(USE_TCP4_ECHO_SRV),true)
+	TCP_ECHO_SRV = tcp_echo_srv1
+	CDEFS := $(CDEFS) -DUSE_TCP4_ECHO_SRV
 endif
 
 ifeq ($(TCP_ECHO_SRV),tcp_echo_srv1)		# 送受信タスク同一型
-	SUPPORT_TCP = true
-	TCP_CFG_PASSIVE_OPEN = true
+
+	SUPPORT_TCP = true
 	USE_NETAPP_SUBR = true
 	CDEFS := $(CDEFS) -DUSE_TCP_ECHO_SRV1
 	NETAPP_COBJS := $(NETAPP_COBJS) tcp_echo_srv1.o
-	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIR)/tcp_echo_srv1.cfg
+	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/tcp_echo_srv1.cfg
+
+	ifeq ($(USE_TCP_NON_BLOCKING),true)
+		NETAPP_COBJS := $(NETAPP_COBJS) tcp_echo_srv1_nblk.o
+	endif
+
+	ifeq ($(USE_TCP_EXTENTIONS),true)
+		NETAPP_COBJS := $(NETAPP_COBJS) tcp_echo_srv1_ext.o
+	endif
+
 endif
 
 ifeq ($(TCP_ECHO_SRV),tcp_echo_srv2)		# 送受信タスク分離型
 	SUPPORT_TCP = true
-	TCP_CFG_PASSIVE_OPEN = true
 	USE_NETAPP_SUBR = true
 	CDEFS := $(CDEFS) -DUSE_TCP_ECHO_SRV2
 	NETAPP_COBJS := $(NETAPP_COBJS) tcp_echo_srv2.o
-	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIR)/tcp_echo_srv2.cfg
+	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/tcp_echo_srv2.cfg
+endif
+
+ifeq ($(USE_UDP4_ECHO_SRV),true)
+	USE_UDP_ECHO_SRV = true
 endif
 
 ifeq ($(USE_UDP_ECHO_SRV),true)
-	SUPPORT_UDP = true
-	USE_NETAPP_SUBR = true
+
 	CDEFS := $(CDEFS) -DUSE_UDP_ECHO_SRV
-	NETAPP_COBJS := $(NETAPP_COBJS) udp_echo_srv.o
-	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIR)/udp_echo_srv.cfg
+
+	ifeq ($(SUPPORT_INET6),true)
+		SUPPORT_UDP = true
+		USE_NETAPP_SUBR = true
+		CDEFS := $(CDEFS) -DUSE_UDP6_ECHO_SRV_TSK
+		NETAPP_COBJS := $(NETAPP_COBJS) udp6_echo_srv.o
+		NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/udp6_echo_srv.cfg
+
+		ifeq ($(SUPPORT_INET4),true)
+			ifeq ($(USE_UDP4_ECHO_SRV),true)
+				CDEFS := $(CDEFS) -DUSE_UDP4_ECHO_SRV_TSK
+				NETAPP_COBJS := $(NETAPP_COBJS) udp4_echo_srv.o
+				NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/udp4_echo_srv.cfg
+			endif
+		endif
+	else
+		ifeq ($(SUPPORT_INET4),true)
+			SUPPORT_UDP = true
+			USE_NETAPP_SUBR = true
+			CDEFS := $(CDEFS) -DUSE_UDP4_ECHO_SRV_TSK
+			NETAPP_COBJS := $(NETAPP_COBJS) udp4_echo_srv.o
+			NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/udp4_echo_srv.cfg
+		endif
+	endif
+endif
+
+
+ifeq ($(USE_TCP4_ECHO_CLI),true)
+	USE_TCP_ECHO_CLI = true
+	CDEFS := $(CDEFS) -DUSE_TCP4_ECHO_CLI
 endif
 
@@ -101,23 +165,48 @@
 	USE_NETAPP_SUBR = true
 	CDEFS := $(CDEFS) -DUSE_TCP_ECHO_CLI
-	NETAPP_COBJS := $(NETAPP_COBJS) tcp_echo_cli.o
-	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIR)/tcp_echo_cli.cfg
+	NETAPP_COBJS := $(NETAPP_COBJS) tcp_echo_cli.o tcp_echo_cli_snd.o tcp_echo_cli_rcv.o
+	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/tcp_echo_cli.cfg
+endif
+
+ifeq ($(USE_UDP4_ECHO_CLI),true)
+	USE_UDP_ECHO_CLI = true
 endif
 
 ifeq ($(USE_UDP_ECHO_CLI),true)
-	SUPPORT_UDP = true
-	USE_NETAPP_SUBR = true
+
 	CDEFS := $(CDEFS) -DUSE_UDP_ECHO_CLI
-	NETAPP_COBJS := $(NETAPP_COBJS) udp_echo_cli.o
-	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIR)/udp_echo_cli.cfg
+
+	ifeq ($(SUPPORT_INET6),true)
+		SUPPORT_UDP = true
+		USE_NETAPP_SUBR = true
+		CDEFS := $(CDEFS) -DUSE_UDP6_ECHO_CLI_TSK
+		NETAPP_COBJS := $(NETAPP_COBJS) udp6_echo_cli.o
+		NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/udp6_echo_cli.cfg
+	
+		ifeq ($(SUPPORT_INET4),true)
+			ifeq ($(USE_UDP4_ECHO_CLI),true)
+				CDEFS := $(CDEFS) -DUSE_UDP4_ECHO_CLI_TSK
+				NETAPP_COBJS := $(NETAPP_COBJS) udp4_echo_cli.o
+				NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/udp4_echo_cli.cfg
+			endif
+		endif
+        else
+		ifeq ($(SUPPORT_INET4),true)
+			SUPPORT_UDP = true
+			USE_NETAPP_SUBR = true
+			CDEFS := $(CDEFS) -DUSE_UDP4_ECHO_CLI_TSK
+			NETAPP_COBJS := $(NETAPP_COBJS) udp4_echo_cli.o
+			NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/udp4_echo_cli.cfg
+		endif
+
+	endif
 endif
 
 ifeq ($(USE_TCP_DISCARD_SRV),true)
 	SUPPORT_TCP = true
-	TCP_CFG_PASSIVE_OPEN = true
 	USE_NETAPP_SUBR = true
 	CDEFS := $(CDEFS) -DUSE_TCP_DISCARD_SRV
 	NETAPP_COBJS := $(NETAPP_COBJS) tcp_discard_srv.o
-	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIR)/tcp_discard_srv.cfg
+	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/tcp_discard_srv.cfg
 endif
 
@@ -127,5 +216,5 @@
 	CDEFS := $(CDEFS) -DUSE_TCP_DISCARD_CLI
 	NETAPP_COBJS := $(NETAPP_COBJS) tcp_discard_cli.o
-	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIR)/tcp_discard_cli.cfg
+	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/tcp_discard_cli.cfg
 endif
 
@@ -135,5 +224,5 @@
 	CDEFS := $(CDEFS) -DUSE_UDP_DISCARD_CLI
 	NETAPP_COBJS := $(NETAPP_COBJS) udp_discard_cli.o
-	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIR)/udp_discard_cli.cfg
+	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/udp_discard_cli.cfg
 endif
 
@@ -141,37 +230,61 @@
 	ifeq ($(TCP_CFG_NON_BLOCKING),true)
 		SUPPORT_TCP = true
-		TCP_CFG_PASSIVE_OPEN = true
 		USE_DBG_CONS = true
 		USE_NETAPP_SUBR = true
 		CDEFS := $(CDEFS) -DUSE_NET_CONS
 		NETAPP_COBJS := $(NETAPP_COBJS) net_cons.o
-		NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIR)/net_cons.cfg
+		NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/net_cons.cfg
 	endif
 endif
 
 ifeq ($(USE_DBG_CONS),true)
-
 	USE_NETAPP_SUBR = true
 	CDEFS := $(CDEFS) -DUSE_DBG_CONS
 	NETAPP_COBJS := $(NETAPP_COBJS) dbg_cons.o 
-	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIR)/dbg_cons.cfg
-
+	NETAPP_KERNEL_CFG := $(NETAPP_KERNEL_CFG) $(NETAPP_DIRS)/dbg_cons.cfg
+	ifeq ($(USE_DBG_CONS_PARSER),true)
+		CDEFS := $(CDEFS) -DUSE_DBG_CONS_PARSER
+	endif
+	ifeq ($(USE_DBG_CONS_EXTRA_PARSE),true)
+		CDEFS := $(CDEFS) -DUSE_DBG_CONS_EXTRA_PARSE
+	endif
 endif
 
 ifeq ($(USE_PING),true)
-
 	USE_NETAPP_SUBR = true
 	CDEFS := $(CDEFS) -DUSE_PING
-
 	ifeq ($(SUPPORT_INET4),true)
-
 		NETAPP_COBJS := $(NETAPP_COBJS) ping.o
 	endif
-
 	ifeq ($(SUPPORT_INET6),true)
-
 		NETAPP_COBJS := $(NETAPP_COBJS) ping6.o
 	endif
-
+endif
+
+ifeq ($(USE_RESOLVER),true)
+	SUPPORT_UDP = true
+	CDEFS := $(CDEFS) -DUSE_RESOLVER
+	NETAPP_COBJS := $(NETAPP_COBJS) resolver.o 
+
+endif
+
+ifeq ($(USE_DHCP6_CLI),true)
+	ifeq ($(SUPPORT_INET6),true)
+		SUPPORT_UDP = true
+		UDP_CFG_NON_BLOCKING = true
+		USE_UDP_NON_BLOCKING = true
+		CDEFS := $(CDEFS) -DDHCP6_CLI_CFG
+		NETAPP_COBJS := $(NETAPP_COBJS) dhcp6_cli.o 
+	endif
+endif
+
+ifeq ($(USE_DHCP4_CLI),true)
+	ifeq ($(SUPPORT_INET4),true)
+		SUPPORT_UDP = true
+		UDP_CFG_NON_BLOCKING = true
+		USE_UDP_NON_BLOCKING = true
+		CDEFS := $(CDEFS) -DDHCP4_CLI_CFG
+		NETAPP_COBJS := $(NETAPP_COBJS) dhcp4_cli.o 
+	endif
 endif
 
@@ -180,10 +293,10 @@
 endif
 
+ifeq ($(API_CFG_IP4MAPPED_ADDR),true)
+	CDEFS := $(CDEFS) -DAPI_CFG_IP4MAPPED_ADDR
+endif
+
 ifeq ($(USE_COPYSAVE_API),true)
 	CDEFS := $(CDEFS) -DUSE_COPYSAVE_API
-endif
-
-ifndef TCP_CFG_PASSIVE_OPEN
-	CDEFS := $(CDEFS) -DUNDEF_TCP_CFG_PASSIVE_OPEN
 endif
 
@@ -241,4 +354,8 @@
 endif
 
+ifeq ($(USE_LCD),true)
+	CDEFS := $(CDEFS) -DUSE_LCD
+endif
+
 #
 #  アプリケーションプログラムに関する定義への追加
@@ -247,5 +364,5 @@
 ifeq ($(TARGET_KERNEL),ASP)
 
-	APPLDIR := $(APPLDIR) $(NETAPP_DIR)
+	APPLDIR := $(APPLDIR) $(NETAPP_DIRS)
 	APPL_COBJS := $(APPL_COBJS) $(NETAPP_COBJS)
 	APPL_CFLAGS := $(APPL_CFLAGS) -fno-strict-aliasing
@@ -255,5 +372,5 @@
 ifeq ($(TARGET_KERNEL),JSP)
 
-	UTASK_DIR := $(UTASK_DIR):$(NETAPP_DIR)
+	UTASK_DIRS := $(UTASK_DIRS):$(NETAPP_DIRS)
 	UTASK_COBJS := $(UTASK_COBJS) $(NETAPP_COBJS)
 	UTASK_CFLAGS := $(UTASK_CFLAGS) -fno-strict-aliasing
@@ -261,4 +378,20 @@
 endif
 
+ifeq ($(USE_LCD),true)
+
+ifeq ($(TARGET_KERNEL),ASP)
+
+	APPLDIR := $(APPLDIR) $(SRCDIR)/pdic/sc1602
+
+endif
+
+ifeq ($(TARGET_KERNEL),JSP)
+
+	UTASK_DIRS := $(UTASK_DIRS):$(SRCDIR)/pdic/sc1602
+
+endif
+
+endif
+
 #
 #  TINET コンフィギュレーションファイルの定義への追加
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dbg_cons.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dbg_cons.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dbg_cons.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -37,4 +37,5 @@
 
 #include <stdlib.h>
+#include <string.h>
 
 #ifdef TARGET_KERNEL_ASP
@@ -44,7 +45,8 @@
 #include <syssvc/serial.h>
 #include <syssvc/logtask.h>
-#include "kernel_cfg.h"
 #include "kernel/kernel_impl.h"
 #include "kernel/task.h"
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_ASP */
@@ -55,4 +57,5 @@
 #include <t_services.h>
 #include "kernel_id.h"
+#include "tinet_id.h"
 
 #include "../kernel/jsp_kernel.h"
@@ -69,4 +72,5 @@
 #include <net/ethernet.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_timer.h>
@@ -83,36 +87,38 @@
 #include <netinet/ip.h>
 #include <netinet/ip_var.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#include <netinet6/nd6.h>
 #include <netinet/if_ether.h>
 #include <netinet/tcp.h>
-#include <netinet/tcp_timer.h>
 #include <netinet/tcp_var.h>
 #include <netinet/tcp_fsm.h>
+#include <netinet/tcp_timer.h>
 #include <netinet/udp.h>
 #include <netinet/udp_var.h>
 
+#include <netinet6/nd6.h>
+
 #include <net/if_var.h>
-#include <net/if6_var.h>
 
 #include <netapp/netapp.h>
 #include <netapp/netapp_var.h>
-#include <netapp/echo.h>
-#include <netapp/discard.h>
+#include <netapp/wwws.h>
+#include <netapp/tcp_echo_srv1.h>
+#include <netapp/tcp_echo_srv2.h>
+#include <netapp/tcp_echo_cli.h>
+#include <netapp/tcp_discard_cli.h>
+#include <netapp/udp6_echo_srv.h>
+#include <netapp/udp4_echo_srv.h>
+#include <netapp/udp6_echo_cli.h>
+#include <netapp/udp4_echo_cli.h>
+#include <netapp/udp_discard_cli.h>
+#include <netapp/resolver.h>
 #include <netapp/dbg_cons.h>
-
-#ifdef USE_LCD
-
-#include "sc1602/lcd.h"
-
-#endif	/* of #ifdef USE_LCD */
+#include <netapp/dhcp6_cli.h>
+#include <netapp/dhcp4_cli.h>
+#include "lcd.h"
 
 #ifdef USE_DBG_CONS
 
-#define DBG_LINE_SIZE	63
-
 /*
- *  task_status -- タスクの状態の出力
+ *  dbg_cons_task_status -- タスクの状態の出力
  */
 
@@ -127,6 +133,6 @@
 	};
 
-static void
-task_status (ID portid, char *line)
+void
+dbg_cons_task_status (ID portid, char *line)
 {
 	TCB	*tcb;
@@ -149,5 +155,5 @@
 			st >>= 1;
 			}
-		cons_printf(portid, "\n");
+		cons_putchar(portid, '\n');
 		}
 
@@ -176,8 +182,138 @@
 	};
 
+#if defined(SUPPORT_INET6)
+
+static void
+tcp_cep_status (ID portid, char *line)
+{
+	T_TCP_CEP*	cep;
+	int		len;
+
+#if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0
+
+	T_TCP_TWCEP*	twcep;
+
+#endif	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
+
+	cons_printf(portid,
+	            "TCP CEP Status\n"
+	            "ID  Snd-Q Rcv-Q Foreign Address                               State\n");
+
+	for (cep = tcp_cep; cep < &tcp_cep[tmax_tcp_cepid]; cep ++)
+		if (!VALID_TCP_CEP(cep)) {
+			cons_printf(portid,
+			            "%2d%c%c     0     0"
+			            " -                                            "
+			            " INVALID\n",
+			            GET_TCP_CEPID(cep),
+			            DYNAMIC_TCP_CEP(cep) ? 'D' : '.',
+			            TCP_IS_CEP_IPV6(cep) ? '6' : '4');
+			}
+		else if (cep->fsm_state == TCP_FSM_CLOSED) {
+			cons_printf(portid,
+			            "%2d%c%c     0     0"
+			            " -                                            "
+			            " CLOSED\n",
+			            GET_TCP_CEPID(cep),
+			            DYNAMIC_TCP_CEP(cep) ? 'D' : '.',
+			            TCP_IS_CEP_IPV6(cep) ? '6' : '4');
+			}
+		else if (cep->fsm_state == TCP_FSM_LISTEN) {
+			cons_printf(portid,
+			            "%2d%c%c     0     0"
+			            " -                                            "
+			            " LISTEN\n",
+			            GET_TCP_CEPID(cep),
+			            DYNAMIC_TCP_CEP(cep) ? 'D' : '.',
+			            TCP_IS_CEP_IPV6(cep) ? '6' : '4');
+			}
+		else {
+			cons_printf(portid,
+			            "%2d%c%c %5d %5d ",
+			            GET_TCP_CEPID(cep),
+			            DYNAMIC_TCP_CEP(cep) ? 'D' : '.',
+			            TCP_IS_CEP_IPV6(cep) ? '6' : '4',
+			            cep->swbuf_count, cep->rwbuf_count);
+
 #if defined(SUPPORT_INET4)
 
+			if (TCP_IS_CEP_IPV4(cep)) {
+				T_IN4_ADDR	addr;
+
+				addr = ntohl(cep->dstaddr.ipaddr.s6_addr32[3]);
+				len  = put_ipv4addr(portid, &addr, 0);
+				}
+			else
+				len  = put_ipv6addr(portid, &cep->dstaddr.ipaddr, 0);
+
+#else	/* of #if defined(SUPPORT_INET4) */
+
+			len  = put_ipv6addr(portid, &cep->dstaddr.ipaddr, 0);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+			cons_putchar(portid, '.');
+			len += cons_putnumber(portid, cep->dstaddr.portno, 10, radhex, 0, false, ' ');
+			for (len = 44 - len; len -- > 0; )
+				cons_putchar(portid, ' ');
+			if (cep->fsm_state == TCP_FSM_TIME_WAIT)
+				cons_printf(portid, " %s(%d)\n", tcp_fsm_str[cep->fsm_state],
+				                    cep->timer[TCP_TIM_2MSL] / TCP_SLOW_HZ);
+			else
+				cons_printf(portid, " %s\n", tcp_fsm_str[cep->fsm_state]);
+			}
+
+#if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0
+
+	for (twcep = tcp_twcep; twcep < &tcp_twcep[NUM_TCP_TW_CEP_ENTRY]; twcep ++) {
+		if (twcep->fsm_state == TCP_FSM_CLOSED) {
+			cons_printf(portid,
+			            "%2dTW     0     0"
+			            " -                                            "
+			            " CLOSED\n",
+			            GET_TCP_TWCEPID(twcep));
+			}
+		else {
+			cons_printf(portid, "%2dTW     0     0 ", GET_TCP_TWCEPID(twcep));
+
+#if defined(SUPPORT_INET4)
+
+			if (TCP_IS_CEP_IPV4(twcep)) {
+				T_IN4_ADDR	addr;
+
+				addr = ntohl(twcep->dstaddr.ipaddr.s6_addr32[3]);
+				len  = put_ipv4addr(portid, &addr, 0);
+				}
+			else
+				len  = put_ipv6addr(portid, &twcep->dstaddr.ipaddr, 0);
+
+#else	/* of #if defined(SUPPORT_INET4) */
+
+			len  = put_ipv6addr(portid, &twcep->dstaddr.ipaddr, 0);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+			cons_putchar(portid, '.');
+			len += cons_putnumber(portid, twcep->dstaddr.portno, 10, radhex, 0, false, ' ');
+			for (len = 44 - len; len -- > 0; )
+				cons_putchar(portid, ' ');
+			if (twcep->fsm_state == TCP_FSM_TIME_WAIT)
+				cons_printf(portid, " %s(%d)\n", tcp_fsm_str[twcep->fsm_state],
+				                    twcep->timer_2msl / TCP_SLOW_HZ);
+			else
+				cons_printf(portid, " %s\n", tcp_fsm_str[twcep->fsm_state]);
+			}
+		}
+
+#endif	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
+
+	}
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
 static void
-tcp_status (ID portid, char *line)
+tcp_cep_status (ID portid, char *line)
 {
 	T_TCP_CEP*	cep;
@@ -190,12 +326,4 @@
 #endif	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
 
-#ifdef TCP_CFG_PASSIVE_OPEN
-
-	T_TCP_REP*	rep;
-	int_t		cnt;
-
-#endif	/* of #ifdef TCP_CFG_PASSIVE_OPEN */
-
-	WAI_NET_CONS_PRINTF();
 	cons_printf(portid,
 	            "TCP CEP Status\n"
@@ -205,25 +333,28 @@
 		if (!VALID_TCP_CEP(cep)) {
 			cons_printf(portid,
-			            "%2d%c     0     0"
+			            "%2d%c%c     0     0"
 			            " -                    "
 			            " -                    "
 			            " INVALID\n",
 			            GET_TCP_CEPID(cep),
-			            DYNAMIC_TCP_CEP(cep) ? 'D' : ' ');
+			            DYNAMIC_TCP_CEP(cep) ? 'D' : '.',
+			            TCP_IS_CEP_IPV6(cep) ? '6' : '4');
 			}
 		else if (cep->fsm_state == TCP_FSM_CLOSED) {
 			cons_printf(portid,
-			            "%2d%c     0     0"
+			            "%2d%c%c     0     0"
 			            " -                    "
 			            " -                    "
 			            " CLOSED\n",
 			            GET_TCP_CEPID(cep),
-			            DYNAMIC_TCP_CEP(cep) ? 'D' : ' ');
+			            DYNAMIC_TCP_CEP(cep) ? 'D' : '.',
+			            TCP_IS_CEP_IPV6(cep) ? '6' : '4');
 			}
 		else if (cep->fsm_state == TCP_FSM_LISTEN) {
 			cons_printf(portid,
-			            "%2d%c     0     0 ",
+			            "%2d%c%c     0     0 ",
 			            GET_TCP_CEPID(cep),
-			            DYNAMIC_TCP_CEP(cep) ? 'D' : ' ');
+			            DYNAMIC_TCP_CEP(cep) ? 'D' : '.',
+			            TCP_IS_CEP_IPV6(cep) ? '6' : '4');
 			len  = PUT_IPADDR(portid, &cep->myaddr.ipaddr, 0);
 			cons_putchar(portid, ':');
@@ -263,5 +394,5 @@
 		if (twcep->fsm_state == TCP_FSM_CLOSED) {
 			cons_printf(portid,
-			            "%2dTW    0     0"
+			            "%2dTW     0     0"
 			            " -                    "
 			            " -                    "
@@ -270,5 +401,5 @@
 			}
 		else {
-			cons_printf(portid, "%2dTW    0     0 ", GET_TCP_TWCEPID(twcep));
+			cons_printf(portid, "%2dTW     0     0 ", GET_TCP_TWCEPID(twcep));
 			len  = PUT_IPADDR(portid, &twcep->myaddr.ipaddr, 0);
 			cons_putchar(portid, ':');
@@ -291,144 +422,27 @@
 #endif	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
 
-#ifdef TCP_CFG_PASSIVE_OPEN
+	}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if TNUM_TCP6_REPID > 0
+
+static void
+tcp6_rep_status (ID portid, char *line)
+{
+	T_TCP_CEP*	cep;
+	T_TCP6_REP*	rep;
+	ID		repid;
+	int_t		cnt;
+	uint_t		len;
 
 	cons_printf(portid,
-	            "TCP REP Status\n"
+	            "TCP6 REP Status\n"
 	            "ID  Local Address         CEP\n");
-	for (rep = tcp_rep; rep < &tcp_rep[tmax_tcp_repid]; rep ++) {
-		cons_printf(portid, "%2d%c ", GET_TCP_REPID(rep), DYNAMIC_TCP_REP(rep) ? 'D' : ' ');
-		if (VALID_TCP_REP(rep)) {
-			len  = PUT_IPADDR(portid, &rep->myaddr.ipaddr, 0);
-			cons_putchar(portid, ':');
-			len += cons_putnumber(portid, rep->myaddr.portno, 10, radhex, 0, false, ' ');
-			for (len = 21 - len; len -- > 0; )
-				cons_putchar(portid, ' ');
-			cnt = 0;
-			for (cep = tcp_cep; cep < &tcp_cep[tmax_tcp_cepid]; cep ++) {
-				if (cep->rep == rep) {
-					if (cnt > 0)
-						cons_printf(portid, ",%d", GET_TCP_CEPID(cep));
-					else
-						cons_printf(portid, "%d", GET_TCP_CEPID(cep));
-					cnt ++;
-					}
-				}
-			}
-		else
-			cons_printf(portid, "INVALID");
-		cons_putchar(portid, '\n');
-		}
-
-#endif	/* of #ifdef TCP_CFG_PASSIVE_OPEN */
-
-	SIG_NET_CONS_PRINTF();
-	FLUSH_SND_BUFF();
-	}
-
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
-
-static void
-tcp_status (ID portid, char *line)
-{
-	T_TCP_CEP*	cep;
-	uint_t		len;
-
-#if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0
-
-	T_TCP_TWCEP*	twcep;
-
-#endif	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
-
-#ifdef TCP_CFG_PASSIVE_OPEN
-
-	T_TCP_REP*	rep;
-	int_t		cnt;
-
-#endif	/* of #ifdef TCP_CFG_PASSIVE_OPEN */
-
-	WAI_NET_CONS_PRINTF();
-	cons_printf(portid,
-	            "TCP CEP Status\n"
-	            "ID  Snd-Q Rcv-Q Foreign Address                             State\n");
-
-	for (cep = tcp_cep; cep < &tcp_cep[tmax_tcp_cepid]; cep ++)
-		if (!VALID_TCP_CEP(cep)) {
-			cons_printf(portid,
-			            "%2d%c     0     0"
-			            " -                                          "
-			            " INVALID\n",
-			            GET_TCP_CEPID(cep),
-			            DYNAMIC_TCP_CEP(cep) ? 'D' : ' ');
-			}
-		else if (cep->fsm_state == TCP_FSM_CLOSED) {
-			cons_printf(portid,
-			            "%2d%c     0     0"
-			            " -                                          "
-			            " CLOSED\n",
-			            GET_TCP_CEPID(cep),
-			            DYNAMIC_TCP_CEP(cep) ? 'D' : ' ');
-			}
-		else if (cep->fsm_state == TCP_FSM_LISTEN) {
-			cons_printf(portid,
-			            "%2d%c     0     0"
-			            " -                                          "
-			            " LISTEN\n",
-			            GET_TCP_CEPID(cep),
-			            DYNAMIC_TCP_CEP(cep) ? 'D' : ' ');
-			}
-		else {
-			cons_printf(portid,
-			            "%2d%c %5d %5d ",
-			            GET_TCP_CEPID(cep),
-			            DYNAMIC_TCP_CEP(cep) ? 'D' : ' ',
-			            cep->swbuf_count, cep->rwbuf_count);
-			len  = PUT_IPADDR(portid, &cep->dstaddr.ipaddr, 0);
-			cons_putchar(portid, '.');
-			len += cons_putnumber(portid, cep->dstaddr.portno, 10, radhex, 0, false, ' ');
-			for (len = 42 - len; len -- > 0; )
-				cons_putchar(portid, ' ');
-			if (cep->fsm_state == TCP_FSM_TIME_WAIT)
-				cons_printf(portid, " %s(%d)\n", tcp_fsm_str[cep->fsm_state],
-				                    cep->timer[TCP_TIM_2MSL] / TCP_SLOW_HZ);
-			else
-				cons_printf(portid, " %s\n", tcp_fsm_str[cep->fsm_state]);
-			}
-
-#if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0
-
-	for (twcep = tcp_twcep; twcep < &tcp_twcep[NUM_TCP_TW_CEP_ENTRY]; twcep ++) {
-		if (twcep->fsm_state == TCP_FSM_CLOSED) {
-			cons_printf(portid,
-			            "%2dTW    0     0"
-			            " -                                          "
-			            " CLOSED\n",
-			            GET_TCP_TWCEPID(twcep));
-			}
-		else {
-			cons_printf(portid, "%2dTW    0     0 ", GET_TCP_TWCEPID(twcep));
-			len  = PUT_IPADDR(portid, &twcep->dstaddr.ipaddr, 0);
-			cons_putchar(portid, '.');
-			len += cons_putnumber(portid, twcep->dstaddr.portno, 10, radhex, 0, false, ' ');
-			for (len = 42 - len; len -- > 0; )
-				cons_putchar(portid, ' ');
-			if (twcep->fsm_state == TCP_FSM_TIME_WAIT)
-				cons_printf(portid, " %s(%d)\n", tcp_fsm_str[twcep->fsm_state],
-				                    twcep->timer_2msl / TCP_SLOW_HZ);
-			else
-				cons_printf(portid, " %s\n", tcp_fsm_str[twcep->fsm_state]);
-			}
-		}
-
-#endif	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
-
-#ifdef TCP_CFG_PASSIVE_OPEN
-
-	cons_printf(portid,
-	            "TCP REP Status\n"
-	            "ID  Local Address         CEP\n");
-	for (rep = tcp_rep; rep < &tcp_rep[tmax_tcp_repid]; rep ++) {
-		cons_printf(portid, "%2d%c ", GET_TCP_REPID(rep), DYNAMIC_TCP_REP(rep) ? 'D' : ' ');
+	for (repid = TMIN_TCP6_REPID; repid <= tmax_tcp6_repid; repid ++) {
+		rep = GET_TCP6_REP(repid);
+		cons_printf(portid, "%2d%c ", GET_TCP6_REPID(rep), DYNAMIC_TCP_REP(rep) ? 'D' : ' ');
 		if (VALID_TCP_REP(rep)) {
 			len  = PUT_IPADDR(portid, &rep->myaddr.ipaddr, 0);
@@ -439,5 +453,5 @@
 			cnt = 0;
 			for (cep = tcp_cep; cep < &tcp_cep[tmax_tcp_cepid]; cep ++) {
-				if (cep->rep == rep) {
+				if (TCP_IS_CEP_IPV6(cep) && cep->rep == rep) {
 					if (cnt > 0)
 						cons_printf(portid, ",%d", GET_TCP_CEPID(cep));
@@ -452,38 +466,51 @@
 		cons_putchar(portid, '\n');
 		}
-
-#endif	/* of #ifdef TCP_CFG_PASSIVE_OPEN */
-
-	SIG_NET_CONS_PRINTF();
-	FLUSH_SND_BUFF();
-	}
-
-#endif	/* of #if defined(SUPPORT_INET6) */
-
-#endif	/* of #ifdef SUPPORT_TCP */
-
-#ifdef SUPPORT_UDP
-
-/*
- *  udp_status -- UDP の状態の出力
- */
+	}
+
+#endif	/* of #if TNUM_TCP6_REPID > 0 */
+
+#if TNUM_TCP4_REPID > 0
 
 static void
-udp_status (ID portid, char *line)
-{
-	T_UDP_CEP*	cep;
+tcp4_rep_status (ID portid, char *line)
+{
+	T_TCP_CEP*	cep;
+	T_TCP4_REP*	rep;
+	ID		repid;
+	int_t		cnt;
 	uint_t		len;
 
-	WAI_NET_CONS_PRINTF();
 	cons_printf(portid,
-	            "UDP CEP Status\n"
-	            "ID  Local Address\n");
-
-	for (cep = udp_cep; cep < &udp_cep[tmax_udp_ccepid]; cep ++) {
-		cons_printf(portid, "%2d%c ", GET_UDP_CEPID(cep), DYNAMIC_UDP_CEP(cep) ? 'D' : ' ');
-		if (VALID_UDP_CEP(cep)) {
-			len  = PUT_IPADDR(portid, &cep->myaddr.ipaddr, 0);
-			cons_putchar(portid, '.');
-			len += cons_putnumber(portid, cep->myaddr.portno, 10, radhex, 0, false, ' ');
+	            "TCP4 REP Status\n"
+	            "ID  Local Address         CEP\n");
+	for (repid = TMIN_TCP4_REPID; repid <= tmax_tcp4_repid; repid ++) {
+		rep = GET_TCP4_REP(repid);
+		cons_printf(portid, "%2d%c ", GET_TCP4_REPID(rep), DYNAMIC_TCP_REP(rep) ? 'D' : ' ');
+		if (VALID_TCP_REP(rep)) {
+			len  = put_ipv4addr(portid, &rep->myaddr.ipaddr, 0);
+			cons_putchar(portid, ':');
+			len += cons_putnumber(portid, rep->myaddr.portno, 10, radhex, 0, false, ' ');
+			for (len = 21 - len; len -- > 0; )
+				cons_putchar(portid, ' ');
+			cnt = 0;
+			for (cep = tcp_cep; cep < &tcp_cep[tmax_tcp_cepid]; cep ++) {
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+				if (TCP_IS_CEP_IPV4(cep) && cep->rep4 == rep) {
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+				if (TCP_IS_CEP_IPV4(cep) && cep->rep == rep) {
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+					if (cnt > 0)
+						cons_printf(portid, ",%d", GET_TCP_CEPID(cep));
+					else
+						cons_printf(portid, "%d", GET_TCP_CEPID(cep));
+					cnt ++;
+					}
+				}
 			}
 		else
@@ -491,4 +518,22 @@
 		cons_putchar(portid, '\n');
 		}
+	}
+
+#endif	/* of #if TNUM_TCP4_REPID > 0 */
+
+static void
+tcp_status (ID portid, char *line)
+{
+	WAI_NET_CONS_PRINTF();
+
+	tcp_cep_status(portid, line);
+
+#if TNUM_TCP6_REPID > 0
+	tcp6_rep_status(portid, line);
+#endif
+
+#if TNUM_TCP4_REPID > 0
+	tcp4_rep_status(portid, line);
+#endif
 
 	SIG_NET_CONS_PRINTF();
@@ -496,33 +541,92 @@
 	}
 
-#endif	/* of #ifdef SUPPORT_UDP */
-
-#ifdef SUPPORT_ETHER
-
-#if defined(SUPPORT_INET4)
+#endif	/* of #ifdef SUPPORT_TCP */
+
+#ifdef SUPPORT_UDP
 
 /*
- *  ifa_status -- ARP キャッシュ出力
- */
+ *  udp6_status -- UDP の状態の出力
+ */
+
+#if TNUM_UDP6_CEPID > 0
+
+extern const ID tmax_tcp_cepid;
 
 static void
-ifa_status (ID portid, char *line)
-{
-	const T_ARP_ENTRY	*cache;
-	int_t			ix;
-
+udp6_status (ID portid, char *line)
+{
+	T_UDP6_CEP*	cep;
+	ID		cepid;
+	uint_t		len;
+
+	cons_printf(portid,
+	            "UDP6 CEP Status\n"
+	            "ID  Local Address\n");
+
+	for (cepid = TMIN_UDP6_CEPID; cepid <= tmax_udp6_cepid; cepid ++) {
+		cep = GET_UDP6_CEP(cepid);
+		cons_printf(portid, "%2d%c ", GET_UDP6_CEPID(cep), DYNAMIC_UDP_CEP(cep) ? 'D' : ' ');
+		if (VALID_UDP_CEP(cep)) {
+			len  = put_ipv6addr(portid, &cep->myaddr.ipaddr, 0);
+			cons_putchar(portid, '.');
+			len += cons_putnumber(portid, cep->myaddr.portno, 10, radhex, 0, false, ' ');
+			}
+		else
+			cons_printf(portid, "INVALID");
+		cons_putchar(portid, '\n');
+		}
+
+	SIG_NET_CONS_PRINTF();
+	}
+
+#endif	/* of #if TNUM_UDP6_CEPID > 0 */
+
+/*
+ *  udp4_status -- UDP の状態の出力
+ */
+
+#if TNUM_UDP4_CEPID > 0
+
+static void
+udp4_status (ID portid, char *line)
+{
+	T_UDP4_CEP*	cep;
+	ID		cepid;
+	uint_t		len;
+
+	cons_printf(portid,
+	            "UDP4 CEP Status\n"
+	            "ID  Local Address\n");
+
+	for (cepid = TMIN_UDP4_CEPID; cepid <= tmax_udp4_cepid; cepid ++) {
+		cep = GET_UDP4_CEP(cepid);
+		cons_printf(portid, "%2d%c ", GET_UDP4_CEPID(cep), DYNAMIC_UDP_CEP(cep) ? 'D' : ' ');
+		if (VALID_UDP_CEP(cep)) {
+			len  = put_ipv4addr(portid, &cep->myaddr.ipaddr, 0);
+			cons_putchar(portid, '.');
+			len += cons_putnumber(portid, cep->myaddr.portno, 10, radhex, 0, false, ' ');
+			}
+		else
+			cons_printf(portid, "INVALID");
+		cons_putchar(portid, '\n');
+		}
+
+	SIG_NET_CONS_PRINTF();
+	}
+
+#endif	/* of #if TNUM_UDP4_CEPID > 0 */
+
+static void
+udp_status (ID portid, char *line)
+{
 	WAI_NET_CONS_PRINTF();
-	cons_printf(portid,
-	            "ARP Cache\n"
-	            "IX Expire IP Address      MAC Address\n");
-
-	/* expire の単位は [ms]。*/
-	cache = arp_get_cache();
-	for (ix = 0; ix < NUM_ARP_ENTRY; ix ++) {
-		if (cache[ix].expire != 0)
-			cons_printf(portid, "%2d %6d %15I %M\n",
-			                    ix, cache[ix].expire / NET_TIMER_HZ,
-			                    &cache[ix].ip_addr, cache[ix].mac_addr);
-		}
+
+#if TNUM_UDP6_CEPID > 0
+	udp6_status(portid, line);
+#endif
+
+#if TNUM_UDP4_CEPID > 0
+	udp4_status(portid, line);
+#endif
 
 	SIG_NET_CONS_PRINTF();
@@ -530,10 +634,12 @@
 	}
 
-#endif	/* of #if defined(SUPPORT_INET4) */
+#endif	/* of #ifdef SUPPORT_UDP */
+
+#ifdef SUPPORT_ETHER
 
 #if defined(SUPPORT_INET6)
 
 /*
- * ifa_status -- 近隣キャッシュ状態の出力
+ * ifa6_status -- 近隣キャッシュ状態の出力
  */
 
@@ -549,5 +655,5 @@
 
 static void
-ifa_status (ID portid, char *line)
+ifa6_status (ID portid, char *line)
 {
 	const T_LLINFO_ND6	*cache;
@@ -565,9 +671,9 @@
 	for (ix = 0; ix < NUM_ND6_CACHE_ENTRY; ix ++) {
 		if (cache[ix].state != ND6_LLINFO_FREE) {
-			cons_printf(portid, "%2d %6d %10s %M %I\n",
+			cons_printf(portid, "%2d %6ld %10s %M %lI\n",
 			            ix, 
 			            cache[ix].state == ND6_LLINFO_STALE ||
-			            (uint32_t)(cache[ix].expire - now) <= 0
-			                ? 0 : (cache[ix].expire - now) / SYSTIM_HZ,
+			            (uint32_t)((int32_t)(cache[ix].expire - now) <= 0
+			                 ? 0 : (int32_t)(cache[ix].expire - now) / SYSTIM_HZ),
 			            nd_state_str[cache[ix].state],
 			            &cache[ix].ifaddr,
@@ -581,4 +687,36 @@
 
 #endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+/*
+ *  ifa4_status -- ARP キャッシュ出力
+ */
+
+static void
+ifa4_status (ID portid, char *line)
+{
+	const T_ARP_ENTRY	*cache;
+	int_t			ix;
+
+	WAI_NET_CONS_PRINTF();
+	cons_printf(portid,
+	            "ARP Cache\n"
+	            "IX Expire MAC Address       IP Address\n");
+
+	/* expire の単位は [ms]。*/
+	cache = arp_get_cache();
+	for (ix = 0; ix < NUM_ARP_ENTRY; ix ++) {
+		if (cache[ix].expire != 0)
+			cons_printf(portid, "%2d %6d %M %hI\n",
+			                    ix, cache[ix].expire / NET_TIMER_HZ,
+			                    cache[ix].mac_addr, &cache[ix].ip_addr);
+		}
+
+	SIG_NET_CONS_PRINTF();
+	FLUSH_SND_BUFF();
+	}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
 
 #endif	/* of #ifdef SUPPORT_ETHER */
@@ -673,4 +811,46 @@
 
 #endif	/* of #ifdef SUPPORT_ETHER */
+
+#if defined(SUPPORT_INET6)
+
+	cons_printf(portid, "\nIPv6\n");
+	cons_printf(portid, "\t受信オクテット数\t%lu\n",		net_count_ip6[NC_IP6_IN_OCTETS]);
+	cons_printf(portid, "\t受信データグラム数\t%lu\n",		net_count_ip6[NC_IP6_IN_PACKETS]);
+	cons_printf(portid, "\t受信エラーデータグラム数\t%lu\n",	net_count_ip6[NC_IP6_IN_ERR_PACKETS]);
+	cons_printf(portid, "\t長さエラー数\t%lu\n",			net_count_ip6[NC_IP6_IN_ERR_SHORT]);
+	cons_printf(portid, "\tバージョンエラー数\t%lu\n",		net_count_ip6[NC_IP6_IN_ERR_VER]);
+	cons_printf(portid, "\tアドレスエラー数\t%lu\n",		net_count_ip6[NC_IP6_IN_ERR_ADDR]);
+	cons_printf(portid, "\tプロトコルエラー数\t%lu\n",		net_count_ip6[NC_IP6_IN_ERR_PROTO]);
+	cons_printf(portid, "\t分割受信数\t%lu\n",			net_count_ip6[NC_IP6_FRAG_IN]);
+	cons_printf(portid, "\t分割受信フラグメント数\t%lu\n",		net_count_ip6[NC_IP6_FRAG_IN_FRAGS]);
+	cons_printf(portid, "\t分割受信再構成成功数\t%lu\n",		net_count_ip6[NC_IP6_FRAG_IN_OK]);
+	cons_printf(portid, "\t分割受信破棄数\t%lu\n",			net_count_ip6[NC_IP6_FRAG_IN_DROP]);
+	cons_printf(portid, "\t分割受信バッファり当て失敗数\t%lu\n",	net_count_ip6[NC_IP6_FRAG_IN_NO_BUF]);
+	cons_printf(portid, "\t分割受信タイムアウト数\t%lu\n",		net_count_ip6[NC_IP6_FRAG_IN_TMOUT]);
+	cons_printf(portid, "\t送信オクテット数\t%lu\n",		net_count_ip6[NC_IP6_OUT_OCTETS]);
+	cons_printf(portid, "\t送信データグラム数\t%lu\n",		net_count_ip6[NC_IP6_OUT_PACKETS]);
+	cons_printf(portid, "\t送信エラーデータグラム数\t%lu\n",	net_count_ip6[NC_IP6_OUT_ERR_PACKETS]);
+	cons_printf(portid, "\t分割送信数\t%lu\n",			net_count_ip6[NC_IP6_FRAG_OUT]);
+	cons_printf(portid, "\t分割送信フラグメント数\t%lu\n",		net_count_ip6[NC_IP6_FRAG_OUT_FRAGS]);
+
+	cons_printf(portid, "\nICMPv6\n");
+	cons_printf(portid, "\t受信オクテット数\t%lu\n",		net_count_icmp6[NC_ICMP6_IN_OCTETS]);
+	cons_printf(portid, "\t受信パケット数\t%lu\n",			net_count_icmp6[NC_ICMP6_IN_PACKETS]);
+	cons_printf(portid, "\t受信エラーパケット数\t%lu\n",		net_count_icmp6[NC_ICMP6_IN_ERR_PACKETS]);
+	cons_printf(portid, "\t受信チックサムエラー数\t%lu\n",		net_count_icmp6[NC_ICMP6_IN_ERR_CKSUM]);
+	cons_printf(portid, "\t送信オクテット数\t%lu\n",		net_count_icmp6[NC_ICMP6_OUT_OCTETS]);
+	cons_printf(portid, "\t送信パケット数\t%lu\n",			net_count_icmp6[NC_ICMP6_OUT_PACKETS]);
+	cons_printf(portid, "\t送信エラーパケット数\t%lu\n",		net_count_icmp6[NC_ICMP6_OUT_ERR_PACKETS]);
+
+	cons_printf(portid, "\n近隣探索\n");
+	cons_printf(portid, "\tルータ通知受信数\t%lu\n",		net_count_nd6[NC_ND6_RA_IN_PACKETS]);
+	cons_printf(portid, "\tルータ要請送信数\t%lu\n",		net_count_nd6[NC_ND6_RS_OUT_PACKETS]);
+	cons_printf(portid, "\t近隣通知受信数\t%lu\n",			net_count_nd6[NC_ND6_NA_IN_PACKETS]);
+	cons_printf(portid, "\t近隣通知送信数\t%lu\n",			net_count_nd6[NC_ND6_NA_OUT_PACKETS]);
+	cons_printf(portid, "\t近隣要請受信数\t%lu\n",			net_count_nd6[NC_ND6_NS_IN_PACKETS]);
+	cons_printf(portid, "\t近隣要請送信数\t%lu\n",			net_count_nd6[NC_ND6_NS_OUT_PACKETS]);
+	cons_printf(portid, "\t重複アドレス検出送信数\t%lu\n",		net_count_nd6[NC_ND6_DAD_OUT_PACKETS]);
+
+#else	/* of #if defined(SUPPORT_INET6) */
 
 #if defined(SUPPORT_INET4)
@@ -707,44 +887,4 @@
 
 #endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
-
-	cons_printf(portid, "\nIPv6\n");
-	cons_printf(portid, "\t受信オクテット数\t%lu\n",		net_count_ip6[NC_IP6_IN_OCTETS]);
-	cons_printf(portid, "\t受信データグラム数\t%lu\n",		net_count_ip6[NC_IP6_IN_PACKETS]);
-	cons_printf(portid, "\t受信エラーデータグラム数\t%lu\n",	net_count_ip6[NC_IP6_IN_ERR_PACKETS]);
-	cons_printf(portid, "\t長さエラー数\t%lu\n",			net_count_ip6[NC_IP6_IN_ERR_SHORT]);
-	cons_printf(portid, "\tバージョンエラー数\t%lu\n",		net_count_ip6[NC_IP6_IN_ERR_VER]);
-	cons_printf(portid, "\tアドレスエラー数\t%lu\n",		net_count_ip6[NC_IP6_IN_ERR_ADDR]);
-	cons_printf(portid, "\tプロトコルエラー数\t%lu\n",		net_count_ip6[NC_IP6_IN_ERR_PROTO]);
-	cons_printf(portid, "\t分割受信数\t%lu\n",			net_count_ip6[NC_IP6_FRAG_IN]);
-	cons_printf(portid, "\t分割受信フラグメント数\t%lu\n",		net_count_ip6[NC_IP6_FRAG_IN_FRAGS]);
-	cons_printf(portid, "\t分割受信再構成成功数\t%lu\n",		net_count_ip6[NC_IP6_FRAG_IN_OK]);
-	cons_printf(portid, "\t分割受信破棄数\t%lu\n",			net_count_ip6[NC_IP6_FRAG_IN_DROP]);
-	cons_printf(portid, "\t分割受信バッファり当て失敗数\t%lu\n",	net_count_ip6[NC_IP6_FRAG_IN_NO_BUF]);
-	cons_printf(portid, "\t分割受信タイムアウト数\t%lu\n",		net_count_ip6[NC_IP6_FRAG_IN_TMOUT]);
-	cons_printf(portid, "\t送信オクテット数\t%lu\n",		net_count_ip6[NC_IP6_OUT_OCTETS]);
-	cons_printf(portid, "\t送信データグラム数\t%lu\n",		net_count_ip6[NC_IP6_OUT_PACKETS]);
-	cons_printf(portid, "\t送信エラーデータグラム数\t%lu\n",	net_count_ip6[NC_IP6_OUT_ERR_PACKETS]);
-	cons_printf(portid, "\t分割送信数\t%lu\n",			net_count_ip6[NC_IP6_FRAG_OUT]);
-	cons_printf(portid, "\t分割送信フラグメント数\t%lu\n",		net_count_ip6[NC_IP6_FRAG_OUT_FRAGS]);
-
-	cons_printf(portid, "\nICMPv6\n");
-	cons_printf(portid, "\t受信オクテット数\t%lu\n",		net_count_icmp6[NC_ICMP6_IN_OCTETS]);
-	cons_printf(portid, "\t受信パケット数\t%lu\n",			net_count_icmp6[NC_ICMP6_IN_PACKETS]);
-	cons_printf(portid, "\t受信エラーパケット数\t%lu\n",		net_count_icmp6[NC_ICMP6_IN_ERR_PACKETS]);
-	cons_printf(portid, "\t受信チックサムエラー数\t%lu\n",		net_count_icmp6[NC_ICMP6_IN_ERR_CKSUM]);
-	cons_printf(portid, "\t送信オクテット数\t%lu\n",		net_count_icmp6[NC_ICMP6_OUT_OCTETS]);
-	cons_printf(portid, "\t送信パケット数\t%lu\n",			net_count_icmp6[NC_ICMP6_OUT_PACKETS]);
-	cons_printf(portid, "\t送信エラーパケット数\t%lu\n",		net_count_icmp6[NC_ICMP6_OUT_ERR_PACKETS]);
-
-	cons_printf(portid, "\n近隣探索\n");
-	cons_printf(portid, "\tルータ通知受信数\t%lu\n",		net_count_nd6[NC_ND6_RA_IN_PACKETS]);
-	cons_printf(portid, "\tルータ要請送信数\t%lu\n",		net_count_nd6[NC_ND6_RS_OUT_PACKETS]);
-	cons_printf(portid, "\t近隣通知受信数\t%lu\n",			net_count_nd6[NC_ND6_NA_IN_PACKETS]);
-	cons_printf(portid, "\t近隣通知送信数\t%lu\n",			net_count_nd6[NC_ND6_NA_OUT_PACKETS]);
-	cons_printf(portid, "\t近隣要請受信数\t%lu\n",			net_count_nd6[NC_ND6_NS_IN_PACKETS]);
-	cons_printf(portid, "\t近隣要請送信数\t%lu\n",			net_count_nd6[NC_ND6_NS_OUT_PACKETS]);
-	cons_printf(portid, "\t重複アドレス検出送信数\t%lu\n",		net_count_nd6[NC_ND6_DAD_OUT_PACKETS]);
 
 #endif	/* of #if defined(SUPPORT_INET6) */
@@ -787,9 +927,10 @@
 
 	tbl = nbuf_get_tbl();
-	cons_printf(portid, "\nネットワークバッファ\n\tサイズ\t用意数\t割当要求数\t割当数\t割当てエラー数\n");
+	cons_printf(portid, "\nネットワークバッファ\n\tサイズ\t用意数\t使用中数\t割当要求数\t割当数\t割当てエラー数\n");
 	for (ix = nbuf_get_tbl_size(); ix -- > 0; ) {
-		cons_printf(portid, "\t%lu\t%lu\t%lu\t%lu\t%lu\n",
+		cons_printf(portid, "\t%lu\t%lu\t%lu\t%lu\t%lu\t%lu\n",
 		                    tbl[ix].size,
 		                    tbl[ix].prepares,
+		                    tbl[ix].busies,
 		                    tbl[ix].requests,
 		                    tbl[ix].allocs,
@@ -833,5 +974,5 @@
 	for (ix = nbuf_get_tbl_size(); ix -- > 0; )
 		cons_printf(portid, "\t%d", tbl[ix].size);
-	cons_printf(portid, "\n");
+	cons_putchar(portid, '\n');
 
 	queue = ip_get_frag_queue();
@@ -846,5 +987,5 @@
 				cons_printf(portid, "\t%d", count);
 				}
-			cons_printf(portid, "\n");
+			cons_putchar(portid, '\n');
 			}
 		}
@@ -874,5 +1015,5 @@
 	for (ix = nbuf_get_tbl_size(); ix -- > 0; )
 		cons_printf(portid, "\t%d", tbl[ix].size);
-	cons_printf(portid, "\n");
+	cons_putchar(portid, '\n');
 
 	queue = ip6_get_frag_queue();
@@ -887,5 +1028,5 @@
 				cons_printf(portid, "\t%d", count);
 				}
-			cons_printf(portid, "\n");
+			cons_putchar(portid, '\n');
 			}
 		}
@@ -918,5 +1059,4 @@
 
 #ifdef TCP_CFG_SWBUF_CSAVE
-	T_IP_HDR*		iph;
 	T_TCP_HDR*		tcph;
 #endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
@@ -925,14 +1065,15 @@
 	WAI_NET_CONS_PRINTF();
 	get_tim(&now);
-	cons_printf(portid, "ネットワークバッファ情報\t経過時間[ms]\t%lu\n", now);
+	cons_printf(portid, "ネットワークバッファ情報\t経過時間[ms]\t%u\n", now);
 
 #if NET_COUNT_ENABLE
 
-	cons_printf(portid, "\nネットワークバッファ\n\tサイズ\t用意数\t割当要求数\t割当数\t割当てエラー数\n");
+	cons_printf(portid, "\nネットワークバッファ\n\tサイズ\t用意数\t使用中数\t割当要求数\t割当数\t割当てエラー数\n");
 	tbl = nbuf_get_tbl();
 	for (ix = nbuf_get_tbl_size(); ix -- > 0; ) {
-		cons_printf(portid, "\t%lu\t%lu\t%lu\t%lu\t%lu\n",
+		cons_printf(portid, "\t%u\t%u\t%u\t%u\t%u\t%u\n",
 		                    tbl[ix].size,
 		                    tbl[ix].prepares,
+		                    tbl[ix].busies,
 		                    tbl[ix].requests,
 		                    tbl[ix].allocs,
@@ -949,6 +1090,6 @@
 		cons_printf(portid, "%2d", GET_TCP_CEPID(cep));
 		for (nbuf = cep->reassq; nbuf != NULL; nbuf = tqhdr->next) {
-			tqhdr = GET_TCP_Q_HDR(nbuf, GET_TCP_IP_Q_HDR(nbuf)->thoff);
-			cons_printf(portid, "[a:%6d-%6d] ",
+			tqhdr = GET_TCP_Q_HDR(nbuf, GET_TCP_HDR_OFFSET(nbuf));
+			cons_printf(portid, "[a:%6lu-%6lu] ",
 			            ntohl(tqhdr->seq) - cep->irs + tqhdr->soff,
 			            ntohl(tqhdr->seq) - cep->irs + tqhdr->soff + tqhdr->slen);
@@ -957,6 +1098,6 @@
 #ifdef TCP_CFG_RWBUF_CSAVE
 		for (nbuf = cep->rwbufq; nbuf != NULL; nbuf = tqhdr->next) {
-			tqhdr = GET_TCP_Q_HDR(nbuf, GET_TCP_IP_Q_HDR(nbuf)->thoff);
-			cons_printf(portid, "[r:%6d-%6d] ",
+			tqhdr = GET_TCP_Q_HDR(nbuf, GET_TCP_HDR_OFFSET(nbuf));
+			cons_printf(portid, "[r:%6lu-%6lu] ",
 			            ntohl(tqhdr->seq) - cep->irs + tqhdr->soff,
 			            ntohl(tqhdr->seq) - cep->irs + tqhdr->soff + tqhdr->slen);
@@ -966,14 +1107,21 @@
 #ifdef TCP_CFG_SWBUF_CSAVE
 		if (cep->swbufq != NULL) {
-			iph  = GET_IP_HDR(cep->swbufq);
 			tcph = GET_TCP_HDR(cep->swbufq, GET_TCP_HDR_OFFSET(cep->swbufq));
-			cons_printf(portid, "[s:%6d-%6d] ",
+#if 0
+			cons_printf(portid, "[s:%6lu-%6lu] ",
 			            ntohl(tcph->seq) - cep->iss,
-			            ntohl(tcph->seq) - cep->iss + (GET_IP_SDU_SIZE(iph) - 
-			                                           GET_TCP_HDR_SIZE2(cep->swbufq, GET_TCP_HDR_OFFSET(cep->swbufq))));
+			            ntohl(tcph->seq) - cep->iss + (GET_IP_SDU_SIZE(cep->swbufq) - 
+			                                           GET_TCP_HDR_SIZE(cep->swbufq, GET_TCP_HDR_OFFSET(cep->swbufq))));
+#else
+			cons_printf(portid, "[s:%6lu-%6lu,%08x,%08x] ",
+			            ntohl(tcph->seq) - cep->iss,
+			            ntohl(tcph->seq) - cep->iss + (GET_IP_SDU_SIZE(cep->swbufq) - 
+			                                           GET_TCP_HDR_SIZE(cep->swbufq, GET_TCP_HDR_OFFSET(cep->swbufq))),
+			            ntohl(tcph->seq), cep->iss);
+#endif
 			}
 #endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
 
-		cons_printf(portid, "\n");
+		cons_putchar(portid, '\n');
 		}
 
@@ -1008,51 +1156,393 @@
 	}
 
+#ifdef USE_RESOLVER
+
+/*
+ *  show_dns_soa -- DNS の SOA RDATA を表示する。
+ */
+
+static ER_UINT
+show_dns_soa (ID portid, uint8_t *msg, ER_UINT length, uint_t offset)
+{
+	T_RSLV_SOA	soa;
+	ER_UINT		error;
+	uint_t		rn_offset;
+
+	if ((error = dns_analyze_soa(&soa, offset, msg, length)) < 0)
+		return error;
+
+	cons_printf(portid, "    mname:   ");
+	rn_offset = show_dns_domain_name(portid, msg, offset);
+	cons_putchar(portid, '\n');
+	cons_printf(portid, "    rname:   ");
+	show_dns_domain_name(portid, msg, rn_offset);
+	cons_putchar(portid, '\n');
+
+	cons_printf(portid, "    serial:  %d\n", soa.serial);
+	cons_printf(portid, "    refresh: %d\n", soa.refresh);
+	cons_printf(portid, "    retry:   %d\n", soa.retry);
+	cons_printf(portid, "    expirel: %d\n", soa.expire);
+	cons_printf(portid, "    minimum: %d\n", soa.minimum);
+
+	return E_OK;
+	}
+
+/*
+ *  show_dns_qdsection -- DNS の Question セクションを表示する。
+ */
+
+static ER_UINT
+show_dns_qdsection (ID portid, uint8_t *msg, ER_UINT length, T_RSLV_DNS_MSG *rslv)
+{
+	T_RSLV_QD	qd;
+	ER_UINT		offset, error;
+	int		scount;
+
+	cons_printf(portid, "question   section: %d\n", rslv->dns_hdr.qdcount);
+	offset = rslv->qd_offset;
+	for (scount = 1; scount <= rslv->dns_hdr.qdcount; scount ++) {
+		if ((error = dns_analyze_qd(&qd, offset, msg, length)) < 0)
+			return error;
+
+		cons_printf(portid, "%2d: ", scount);
+		show_dns_domain_name(portid, msg, offset);
+		cons_printf(portid, "\n    type: %-4s, class: %2s\n", dns_strtype(qd.type), dns_strclass(qd.class));
+		offset = error;
+		}
+
+	return E_OK;
+	}
+
+/*
+ *  show_dns_section -- DNS の各セクションを表示する。
+ */
+
+static ER_UINT
+show_dns_section (ID portid, uint8_t *msg, ER_UINT length, uint_t scount, uint_t offset, char *title)
+{
+	T_RSLV_RR	rr;
+	T_IN4_ADDR	in4_addr;
+	ER_UINT		error;
+	int		count, dcount, col;
+	T_IN6_ADDR	in6_addr;
+
+	cons_printf(portid, "%10s section: %d\n", title, scount);
+	for (count = 1; count <= scount; count ++) {
+		if ((error = dns_analyze_rr(&rr, offset, msg, length)) < 0)
+			return error;
+
+		cons_printf(portid, "%2d: ", count);
+		show_dns_domain_name(portid, msg, offset);
+		cons_printf(portid, "\n    type: %-4s, class: %2s, TTL: %2d, len: %3d, offset: 0x%02x\n",
+		            dns_strtype(rr.type), dns_strclass(rr.class), rr.ttl, rr.rdlength, rr.rdata_offset);
+
+		switch (rr.type) {
+		case DNS_TYPE_A:
+			memcpy((void*)&in4_addr, (void*)(msg + rr.rdata_offset), sizeof(in4_addr));
+			in4_addr = ntohl(in4_addr);
+			cons_printf(portid, "    IPv4 addr: %hI\n", &in4_addr);
+			break;
+		case DNS_TYPE_NS:
+			cons_printf(portid, "    host: ");
+			show_dns_domain_name(portid, msg, rr.rdata_offset);
+			cons_putchar(portid, '\n');
+			break;
+		case DNS_TYPE_CNAME:
+			cons_printf(portid, "    host: ");
+			show_dns_domain_name(portid, msg, rr.rdata_offset);
+			cons_putchar(portid, '\n');
+			break;
+		case DNS_TYPE_SOA:
+			show_dns_soa(portid, msg, length, rr.rdata_offset);
+			break;
+		case DNS_TYPE_PTR:
+			cons_printf(portid, "     PTR: ");
+			show_dns_domain_name(portid, msg, rr.rdata_offset);
+			cons_putchar(portid, '\n');
+			break;
+		case DNS_TYPE_AAAA:
+			memcpy((void*)&in6_addr, (void*)(msg + rr.rdata_offset), sizeof(in6_addr));
+			cons_printf(portid, "    IPv6 addr: %lI\n", &in6_addr);
+			break;
+		default:
+			cons_printf(portid, "    data: ");
+			col = 32;
+			for (dcount = 0; dcount < rr.rdlength; dcount ++) {
+				cons_printf(portid, "%02x", *(msg + rr.rdata_offset + dcount));
+				if (-- col == 0) {
+					cons_printf(portid, "\n          ");
+					col = 32;
+					}
+				}
+			cons_putchar(portid, '\n');
+			break;
+			}
+		}
+
+	return E_OK;
+	}
+/*
+ *  dns_info -- DNS 情報の表示
+ */
+
+static void
+dns_info (ID portid)
+{
+#if defined(SUPPORT_INET6)
+	T_IN6_ADDR	in6_addr;
+#endif
 #if defined(SUPPORT_INET4)
-
-#if NUM_ROUTE_ENTRY > 0
+	T_IN4_ADDR	in4_addr;
+#endif
+
+#if defined(SUPPORT_INET6)
+
+	cons_printf(portid, "domain name:     %s\n", dns_in6_get_dname());
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+	cons_printf(portid, "domain name:     %s\n", dns_in4_get_dname());
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET6)
+	dns_in6_get_addr(&in6_addr);
+	cons_printf(portid, "IPv6 DNS server: ");
+	if (IN6_IS_ADDR_UNSPECIFIED(&in6_addr))
+		cons_printf(portid, "not available.\n");
+	else
+		cons_printf(portid, "%lI.\n", &in6_addr);
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+	dns_in4_get_addr(&in4_addr);
+	cons_printf(portid, "IPv4 DNS server: ");
+	if (in4_addr == IPV4_ADDRANY)
+		cons_printf(portid, "not available.\n");
+	else
+		cons_printf(portid, "%hI.\n", &in4_addr);
+#endif	/* of #if defined(SUPPORT_INET4) */
+	}
 
 /*
- *  routing_table_status -- 経路表の出力
- */
+ *  name_lookup -- ホスト名－IP アドレス変換
+ */
+
+const char *rcode_str[] = {
+	"no error",
+	"format error",
+	"server error",
+	"name error",
+	"not implement",
+	"refused",
+	};
 
 static void
-routing_table_status (ID portid, char *line)
-{
-	int_t	ix;
-
-	if ('0' <= *(line = skip_blanks(line)) && *line <= '9') {
-		T_IN4_ADDR	target, mask, gateway;
-
-		ix = atoi(line);
-		while ('0' <= *line && *line <= '9')
-			line ++;
-		line = GET_IPADDR(&target,  skip_blanks(line));
-		line = GET_IPADDR(&mask,    skip_blanks(line));
-		       GET_IPADDR(&gateway, skip_blanks(line));
-		in4_add_route(ix, target, mask, gateway);
-		}
-
+name_lookup (ID portid, char *line)
+{
+	static char hostname[DBG_LINE_SIZE + 1];
+
+	T_RSLV_DNS_MSG	rslv;
+	ER_UINT		length, offset;
+	ER		error;
+	uint_t		flags = 0;
+	uint8_t 	*msg;
+
+	/* コマンドのオプションを設定する。*/
+	line = skip_blanks(resolv_options(&flags, line, DEFAULT_API_PROTO));
+	if ((flags & (DNS_LUP_FLAGS_PROTO_IPV6 | DNS_LUP_FLAGS_PROTO_IPV4)) == 0) {
+		cons_printf(portid, "DNS server not available.\n");
+		return;
+		}
+
+	/* 照会するホスト名・IP アドレスを解析する。*/
+	resolv_hoststr(&flags, hostname, sizeof(hostname), line);
+
+	/* 正引きでも逆引きでもプロトコル上は正引きを指定する。*/
+	flags |= DNS_LUP_OPCODE_FORWARD;
+
+	/* IPv6 アドレス、または IPv4 アドレスが指定された時は、照会タイプは PTR に設定する。*/
+	if (((flags & DNS_LUP_FLAGS_NAME_MASK) == DNS_LUP_FLAGS_NAME_IPV6) ||
+	    ((flags & DNS_LUP_FLAGS_NAME_MASK) == DNS_LUP_FLAGS_NAME_IPV4))
+		flags = (flags & ~DNS_LUP_FLAGS_QTYPE_MASK) | DNS_LUP_FLAGS_QTYPE_PTR;
+
+	if ((error = tget_mpf(MPF_RSLV_SRBUF, (void*)&msg, TMO_FEVR)) != E_OK) {
+		cons_printf(portid, "get buffer error: %s.\n", itron_strerror(error));
+		return;
+		}
+
+	if ((length = dns_lookup_host(flags | DNS_LUP_FLAGS_MSG, line, msg, DNS_UDP_MSG_LENGTH, &rslv)) < 0) {
+		//cons_printf(portid, "error: %s.\n", itron_strerror(length));
+		goto err_ret;
+		}
+
+	dly_tsk(1 * 1000);
+	cons_printf(portid, "DNS header: flags: ");
+	if (rslv.dns_hdr.code & (DNS_QR_RESPONSE | DNS_AUTHORITATIVE     |
+	                         DNS_TRUN_CATION | DNS_RECURSION_DESIRED | DNS_RECURSION_AVAILABLE)) {
+		cons_printf(portid, (rslv.dns_hdr.code & DNS_QR_RESPONSE)         ? "QR," : "");
+		cons_printf(portid, (rslv.dns_hdr.code & DNS_AUTHORITATIVE)       ? "AA," : "");
+		cons_printf(portid, (rslv.dns_hdr.code & DNS_TRUN_CATION)         ? "TC," : "");
+		cons_printf(portid, (rslv.dns_hdr.code & DNS_RECURSION_DESIRED)   ? "RD," : "");
+		cons_printf(portid, (rslv.dns_hdr.code & DNS_RECURSION_AVAILABLE) ? "RA," : "");
+		cons_printf(portid, " ");
+		}
+	cons_printf(portid, "opcode: ");
+	cons_printf(portid, (rslv.dns_hdr.code & DNS_OPCODE_REVERSE)      ? "RV"  : "FW");
+	cons_printf(portid, (rslv.dns_hdr.code & DNS_OPCODE_STATUS)       ? ",ST" : "");
+	cons_printf(portid, ", rcode: %s.\n",
+	            (rslv.dns_hdr.code & DNS_RCODE_MASK) > DNS_RCODE_REFUSED
+	            	? "6" : rcode_str[rslv.dns_hdr.code & DNS_RCODE_MASK]);
+
+	if ((offset = show_dns_qdsection(portid, msg, length, &rslv)) < 0) {
+		cons_printf(portid, "msg error: %s.\n", itron_strerror(offset));
+		}
+	if ((offset = show_dns_section(portid, msg, length, rslv.dns_hdr.ancount, rslv.an_offset, "answer")) < 0) {
+		cons_printf(portid, "msg error: %s.\n", itron_strerror(offset));
+		}
+	if ((offset = show_dns_section(portid, msg, length, rslv.dns_hdr.nscount, rslv.ns_offset, "authority")) < 0) {
+		cons_printf(portid, "msg error: %s.\n", itron_strerror(offset));
+		}
+	if ((offset = show_dns_section(portid, msg, length, rslv.dns_hdr.arcount, rslv.ar_offset, "additional")) < 0) {
+		cons_printf(portid, "msg error: %s.\n", itron_strerror(offset));
+		}
+
+err_ret:
+	if ((error = rel_mpf(MPF_RSLV_SRBUF, msg)) != E_OK)
+		cons_printf(portid, "release buffer error: %s.\n", itron_strerror(error));
+	return;
+	}
+
+#endif	 /* of #ifdef USE_RESOLVER */
+
+#if defined(DHCP6_CLI_CFG)
+
+/*
+ *  dhcp6c_info -- DHCPv6 クライアント情報の表示
+ */
+
+static void
+dhcp6c_info (ID portid)
+{
+	T_IN6_ADDR	svaddr;
+	SYSTIM		bind_start;
+	ER		error;
+	uint32_t	expire, renew, rebind, deprefer;
+
+	if ((error = dhcp6c_get_info(&svaddr, &expire, &renew, &rebind, &deprefer, &bind_start)) == E_OK) {
+		cons_printf(portid, "      DHCPv6 server: %lI.\n", &svaddr);
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS
+	
+		cons_printf(portid, "      DHCPv6 mode:   stateless.\n");
+
+#elif DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+
+		cons_printf(portid, "      DHCPv6 mode:   statefull,\n");
+		cons_printf(portid, "        Renew:       %u:%02u:%02u, Deprefer: %u:%02u:%02u,\n",
+		                       renew / 3600, (   renew / 60) % 60,    renew % 60,
+		                    deprefer / 3600, (deprefer / 60) % 60, deprefer % 60);
+		cons_printf(portid, "        Rebind:      %u:%02u:%02u, Expire:   %u:%02u:%02u.\n",
+		                      rebind / 3600, (  rebind / 60) % 60,   rebind % 60,
+		                      expire / 3600, (  expire / 60) % 60,   expire % 60);
+
+#else	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS */
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS */
+
+		}
+	else if (error == E_OBJ)
+		cons_printf(portid, "      DHCPv6 server: not available.\n");
+	}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG) */
+
+#if defined(DHCP4_CLI_CFG)
+
+/*
+ *  dhcp4c_info -- DHCPv4 クライアント情報の表示
+ */
+
+static void
+dhcp4c_info (ID portid)
+{
+	T_IN4_ADDR	svaddr;
+	SYSTIM		bind_start;
+	ER		error;
+	uint32_t	expire, renew, rebind;
+
+	if ((error = dhcp4c_get_info(&svaddr, &expire, &renew, &rebind, &bind_start)) == E_OK) {
+		cons_printf(portid, "      DHCPv4 server: %hI,\n", &svaddr);
+		cons_printf(portid, "        Renew:       %u:%02u:%02u,\n", 
+		                      renew  / 3600, (renew  / 60) % 60, renew % 60);
+		cons_printf(portid, "        Rebind:      %u:%02u:%02u, Expire:   %u:%02u:%02u.\n",
+		                      rebind / 3600, (rebind / 60) % 60, rebind % 60,
+		                      expire / 3600, (expire / 60) % 60, expire % 60);
+		}
+	else if (error == E_OBJ)
+		cons_printf(portid, "      DHCPv4 server: not available.\n");
+	}
+
+#endif	/* of #if defined(DHCP4_CLI_CFG) */
+
+#if defined(DHCP6_CLI_CFG) || defined(DHCP4_CLI_CFG)
+
+/*
+ *  dhcpc -- DHCP クライアント情報の表示と制御
+ */
+
+static void
+dhcpc (ID portid, char *line)
+{
 	WAI_NET_CONS_PRINTF();
-	cons_printf(portid,
-	            "Routing Table Status\n"
-	            "IX Target          Mask            Gateway         Expire\n");
-
-	for (ix = 0; ix < NUM_ROUTE_ENTRY; ix ++) {
-		if ((routing_tbl[ix].flags & IN_RTF_DEFINED) == 0)
-			;
-		else if ((routing_tbl[ix].flags & IN_RTF_REDIRECT) != 0)
-			cons_printf(portid, "%2d %15I %15I %15I %4d\n",
-			            ix,
-			            &routing_tbl[ix].target,
-			            &routing_tbl[ix].mask,
-			            &routing_tbl[ix].gateway,
-			            &routing_tbl[ix].expire);
-		else
-			cons_printf(portid, "%2d %15I %15I %I\n",
-			            ix,
-			            &routing_tbl[ix].target,
-			            &routing_tbl[ix].mask,
-			            &routing_tbl[ix].gateway);
-		            
+
+	switch (*line) {
+
+#if defined(DHCP6_CLI_CFG)
+	case '6':			/* DHCPv6 の制御 */
+		switch (*(line + 1)) {
+		case 'r':		/* アドレス情報を解放する。*/
+			dhcp6c_rel_info();
+			break;
+
+		case 'n':		/* アドレス情報を再取得する。*/
+			dhcp6c_renew_info();
+			break;
+
+		default:
+			dhcp6c_info(portid);
+			break;
+			}
+		break;
+#endif	/* of #if defined(DHCP6_CLI_CFG) */
+
+#if defined(DHCP4_CLI_CFG)
+	case '4':		/* DHCPv4 の制御 */
+		switch (*(line + 1)) {
+		case 'r':		/* アドレス情報を解放する。*/
+			dhcp4c_rel_info();
+			break;
+
+		case 'n':		/* アドレス情報を再取得する。*/
+			dhcp4c_renew_info();
+			break;
+
+		default:
+			dhcp4c_info(portid);
+			break;
+			}
+		break;
+#endif	/* of #if defined(DHCP4_CLI_CFG) */
+
+	default:
+
+#if defined(DHCP6_CLI_CFG)
+		dhcp6c_info(portid);
+#endif
+
+#if defined(DHCP4_CLI_CFG)
+		dhcp4c_info(portid);
+#endif
+		break;
 		}
 
@@ -1061,7 +1551,5 @@
 	}
 
-#endif	/* of #if NUM_ROUTE_ENTRY > 0 */
-
-#endif	/* of #if defined(SUPPORT_INET4) */
+#endif	/* of #if defined(DHCP6_CLI_CFG) || defined(DHCP4_CLI_CFG) */
 
 #if defined(SUPPORT_INET6)
@@ -1124,5 +1612,5 @@
 			while (ptitle -- > 0)
 				cons_printf(portid, " ");
-			cons_printf(portid, " %I\n",  &dr[rix].addr);
+			cons_printf(portid, " %lI\n",  &dr[rix].addr);
 			}
 		}
@@ -1188,5 +1676,5 @@
 			while (rtitle -- > 0)
 				cons_printf(portid, " ");
-			cons_printf(portid, "%4d %I\n",  pr[pix].prefix_len, &pr[pix].prefix);
+			cons_printf(portid, "%4d %lI\n",  pr[pix].prefix_len, &pr[pix].prefix);
 			}
 		}
@@ -1198,12 +1686,12 @@
 #endif	/* of #if NUM_ND6_DEF_RTR_ENTRY > 0 */
 
-#if NUM_ROUTE_ENTRY > 0
+#if NUM_IN6_ROUTE_ENTRY > 0
 
 /*
- *  routing_table_status -- 経路表の出力
+ *  routing6_table_status -- 経路表（IPv6）の出力
  */
 
 static void
-routing_table_status (ID portid, char *line)
+routing6_table_status (ID portid, char *line)
 {
 	SYSTIM	now;
@@ -1212,13 +1700,13 @@
 	WAI_NET_CONS_PRINTF();
 	cons_printf(portid,
-	            "Routing Table Status\n"
+	            "\nRouting Table Status (IPv6)\n"
 	            "IX Expire flags Prefix Target                         Gateway\n");
 
-	for (ix = 0; ix < NUM_STATIC_ROUTE_ENTRY; ix ++) {
-		cons_printf(portid, "%2d STATIC     - %6d %30I %I\n",
+	for (ix = 0; ix < NUM_IN6_STATIC_ROUTE_ENTRY; ix ++) {
+		cons_printf(portid, "%2d STATIC     - %6d %30lI %lI\n",
 		            ix,
-		             routing_tbl[ix].prefix_len,
-		            &routing_tbl[ix].target,
-		            &routing_tbl[ix].gateway);
+		             routing6_tbl[ix].prefix_len,
+		            &routing6_tbl[ix].target,
+		            &routing6_tbl[ix].gateway);
 		            
 		}
@@ -1228,14 +1716,14 @@
 	now /= SYSTIM_HZ;
 
-	for ( ; ix < NUM_ROUTE_ENTRY; ix ++)
-		if (routing_tbl[ix].flags & IN_RTF_DEFINED)
-			cons_printf(portid, "%2d %6d    %02x %6d %30I %I\n",
+	for ( ; ix < NUM_IN6_ROUTE_ENTRY; ix ++)
+		if (routing6_tbl[ix].flags & IN_RTF_DEFINED)
+			cons_printf(portid, "%2d %6d    %02x %6d %30lI %lI\n",
 			            ix,
-			            (uint32_t)(routing_tbl[ix].expire - now) <= 0
-			                ? 0 : routing_tbl[ix].expire - now,
-			             routing_tbl[ix].flags,
-			             routing_tbl[ix].prefix_len,
-			            &routing_tbl[ix].target,
-			            &routing_tbl[ix].gateway);
+			            (uint32_t)(routing6_tbl[ix].expire - now) <= 0
+			                ? 0 : routing6_tbl[ix].expire - now,
+			             routing6_tbl[ix].flags,
+			             routing6_tbl[ix].prefix_len,
+			            &routing6_tbl[ix].target,
+			            &routing6_tbl[ix].gateway);
 
 	SIG_NET_CONS_PRINTF();
@@ -1243,12 +1731,67 @@
 	}
 
-#endif	/* of #if NUM_ROUTE_ENTRY > 0 */
+#endif	/* of #if NUM_IN6_ROUTE_ENTRY > 0 */
 
 #endif	/* of #if defined(SUPPORT_INET6) */
 
-#if NUM_ROUTE_ENTRY > 0
+#if defined(SUPPORT_INET4)
+
+#if NUM_IN4_ROUTE_ENTRY > 0
 
 /*
- *  routing_status -- ルーティング情報
+ *  routing4_table_status -- 経路表（IPv4）の出力
+ */
+
+static void
+routing4_table_status (ID portid, char *line)
+{
+	int_t	ix;
+
+	if ('0' <= *(line = skip_blanks(line)) && *line <= '9') {
+		T_IN4_ADDR	target, mask, gateway;
+
+		ix = atoi(line);
+		while ('0' <= *line && *line <= '9')
+			line ++;
+		line = get_ipv4addr(&target,  skip_blanks(line));
+		line = get_ipv4addr(&mask,    skip_blanks(line));
+		       get_ipv4addr(&gateway, skip_blanks(line));
+		in4_add_route(ix, target, mask, gateway);
+		}
+
+	WAI_NET_CONS_PRINTF();
+	cons_printf(portid,
+	            "\nRouting Table Status (IPv4)\n"
+	            "IX Target          Mask            Gateway         Expire\n");
+
+	for (ix = 0; ix < NUM_IN4_ROUTE_ENTRY; ix ++) {
+		if ((routing4_tbl[ix].flags & IN_RTF_DEFINED) == 0)
+			;
+		else if ((routing4_tbl[ix].flags & IN_RTF_REDIRECT) != 0)
+			cons_printf(portid, "%2d %15hI %15hI %15hI %4d\n",
+			            ix,
+			            &routing4_tbl[ix].target,
+			            &routing4_tbl[ix].mask,
+			            &routing4_tbl[ix].gateway,
+			            &routing4_tbl[ix].expire);
+		else
+			cons_printf(portid, "%2d %15hI %15hI %hI\n",
+			            ix,
+			            &routing4_tbl[ix].target,
+			            &routing4_tbl[ix].mask,
+			            &routing4_tbl[ix].gateway);
+		            
+		}
+
+	SIG_NET_CONS_PRINTF();
+	FLUSH_SND_BUFF();
+	}
+
+#endif	/* of #if NUM_IN4_ROUTE_ENTRY > 0 */
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+/*
+ *  routing_status -- 経路情報
  */
 
@@ -1258,7 +1801,5 @@
 	switch (*line) {
 
-#if defined(SUPPORT_INET6)
-
-#if NUM_ND6_DEF_RTR_ENTRY > 0
+#if defined(SUPPORT_INET6) && NUM_ND6_DEF_RTR_ENTRY > 0
 
 	case 'l':		/* ディフォルトルータ・リスト情報 */
@@ -1270,24 +1811,28 @@
 		break;
 
-#endif	/* of #if NUM_ND6_DEF_RTR_ENTRY > 0 */
-
-#endif	/* of #if defined(SUPPORT_INET6) */
-
-	default:		/* ルーティング表情報 */
-		routing_table_status(portid, line);
+#endif	/* #if defined(SUPPORT_INET6) && NUM_ND6_DEF_RTR_ENTRY > 0 */
+
+	default:
+
+		/* 経路表情報 */
+
+#if defined(SUPPORT_INET6) && NUM_IN6_ROUTE_ENTRY > 0
+		routing6_table_status(portid, line);
+#endif
+
+#if defined(SUPPORT_INET4) && NUM_IN4_ROUTE_ENTRY > 0
+		routing4_table_status(portid, line);
+#endif
+
 		break;
-
-		break;
-		}
-	}
-
-#endif	/* of #if NUM_ROUTE_ENTRY > 0 */
+		}
+	}
 
 /*
- *  network_status -- ネットワークの状態の出力
- */
-
-static void
-network_status (ID portid, char *line)
+ *  dbg_cons_network_status -- ネットワークの状態の出力
+ */
+
+void
+dbg_cons_network_status (ID portid, char *line)
 {
 	switch (*line) {
@@ -1296,5 +1841,12 @@
 
 	case 'a':		/* IF アドレス情報 */
-		ifa_status(portid, line + 1);
+
+#if defined(SUPPORT_INET6)
+		ifa6_status(portid, line + 1);
+#endif
+#if defined(SUPPORT_INET4)
+		ifa4_status(portid, line + 1);
+#endif
+
 		break;
 
@@ -1313,11 +1865,18 @@
 #endif	/* of #if NET_COUNT_ENABLE */
 
-#if NUM_ROUTE_ENTRY > 0
-
-	case 'r':		/* ルーティング情報 */
+	case 'r':		/* 経路情報 */
 		routing_status(portid, line + 1);
 		break;
 
-#endif	/* of #if NUM_ROUTE_ENTRY > 0 */
+#ifdef USE_RESOLVER
+
+	case 's':		/* name lookup */
+		if (*(line = skip_blanks(line + 1)) == '\0')
+			dns_info(portid);
+		else
+			name_lookup(portid, line);
+		break;
+
+#endif	 /* of #ifdef USE_RESOLVER */
 
 #ifdef SUPPORT_TCP
@@ -1338,5 +1897,5 @@
 
 	default:
-		cons_printf(portid, "no such command: '%c%c'\n", *(line - 1), *line);
+		cons_printf(portid, "no such command: '%c%c'.\n", *(line - 1), *line);
 		SIG_NET_CONS_PRINTF();
 		FLUSH_SND_BUFF();
@@ -1345,64 +1904,35 @@
 	}
 
-#if defined(SUPPORT_INET4)
-
 /*
- *  ifconfig -- ネットワークインタフェースの構成情報
- */
-
-static void
-ifconfig (ID portid, char *line)
-{
-	T_IFNET		*ifp = IF_GET_IFNET();
-	T_IN4_ADDR	bc;
-
+ *  dbg_cons_ifconfig -- ネットワークインタフェースの構成情報
+ */
+
+void
+dbg_cons_ifconfig (ID portid, char *line)
+{
 #ifdef SUPPORT_ETHER
 
-	if (*(line = skip_blanks(line))) {
-		T_IN4_ADDR	addr, mask;
-
-		GET_IPADDR(&mask, skip_blanks(GET_IPADDR(&addr, line)));
-		in4_add_ifaddr(addr, mask);
-		}
-
-#endif	/* of #ifdef SUPPORT_ETHER */
+	T_IF_SOFTC	*ic;
 
 	WAI_NET_CONS_PRINTF();
-	cons_printf(portid,
-	            "Network Interface Configurations\n");
-
-#ifdef SUPPORT_ETHER
-
-	cons_printf(portid,
-	            "ether: %M\n",
-	            IF_ETHER_NIC_GET_SOFTC()->ifaddr.lladdr);
-
-#endif	/* of #ifdef SUPPORT_ETHER */
-
-	bc = (ifp->in_ifaddr.addr & ifp->in_ifaddr.mask) | ~ifp->in_ifaddr.mask;
-	cons_printf(portid,
-	            "inet:  %I, mask: %I, broadcast: %I\n",
-	            &ifp->in_ifaddr.addr,
-	            &ifp->in_ifaddr.mask,
-	            &bc);
-
+	ic = IF_ETHER_NIC_GET_SOFTC();
+	cons_printf(portid, "ether: %M\n", ic->ifaddr.lladdr);
 	SIG_NET_CONS_PRINTF();
 	FLUSH_SND_BUFF();
-	}
-
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+	}
+
+#if defined(NETAPP_IP6_CFG)
 
 /*
- *  ifconfig -- ネットワークインタフェースの構成情報
- */
-
-static void
-ifconfig (ID portid, char *line)
+ *  dbg_cons_ifconfig6 -- ネットワークインタフェース（IPv6）の構成情報
+ */
+
+void
+dbg_cons_ifconfig6 (ID portid, char *line)
 {
 #ifdef SUPPORT_ETHER
 
-	T_IF_SOFTC	*ic;
 	T_IFNET		*ifp = IF_GET_IFNET();
 	int_t		ix;
@@ -1410,7 +1940,4 @@
 
 	WAI_NET_CONS_PRINTF();
-	ic = IF_ETHER_NIC_GET_SOFTC();
-	cons_printf(portid, "ether: %M\ninet6:\nIX   Expire Preffered RTR PFX Flags IP Address\n",
-	                    ic->ifaddr.lladdr);
 
 	/* expire と vltime の単位は [s]。*/
@@ -1418,28 +1945,33 @@
 	now /= SYSTIM_HZ;
 
+	cons_printf(portid, "IPv6:\nIX   Expire Preffered RTR PFX Flags IP Address\n");
 	for (ix = 0; ix < NUM_IN6_IFADDR_ENTRY; ix ++) {
-		if (ifp->in_ifaddrs[ix].flags & IN6_IFF_DEFINED) {
+		if (ifp->in6_ifaddrs[ix].flags & IN6_IFF_DEFINED) {
 			cons_printf(portid, " %d", ix);
-			if (ifp->in_ifaddrs[ix].lifetime.vltime == ND6_INFINITE_LIFETIME)
+			if (ifp->in6_ifaddrs[ix].lifetime.vltime == ND6_INFINITE_LIFETIME)
 				cons_printf(portid, "    INFIN     INFIN");
 			else
 				cons_printf(portid, " %8d %9d",
-				                    (uint32_t)(ifp->in_ifaddrs[ix].lifetime.expire - now) <= 0 
-				                        ? 0 : ifp->in_ifaddrs[ix].lifetime.expire - now,
-				                    (uint32_t)(ifp->in_ifaddrs[ix].lifetime.preferred - now) <= 0
-				                        ? 0 : ifp->in_ifaddrs[ix].lifetime.preferred - now);
-			if (ifp->in_ifaddrs[ix].router_index == IN6_RTR_IX_UNREACH)
+				                    (uint32_t)(ifp->in6_ifaddrs[ix].lifetime.expire - now) <= 0 
+				                         ? 0 : ifp->in6_ifaddrs[ix].lifetime.expire - now,
+				                    (uint32_t)(ifp->in6_ifaddrs[ix].lifetime.preferred - now) <= 0
+				                         ? 0 : ifp->in6_ifaddrs[ix].lifetime.preferred - now);
+			if (ifp->in6_ifaddrs[ix].router_index == IN6_RTR_IX_UNREACH)
 				cons_printf(portid, "   -");
 			else
-				cons_printf(portid, " %3d", ifp->in_ifaddrs[ix].router_index);
-			if (ifp->in_ifaddrs[ix].prefix_index == ND6_PREFIX_IX_INVALID)
+				cons_printf(portid, " %3d", ifp->in6_ifaddrs[ix].router_index);
+			if (ifp->in6_ifaddrs[ix].prefix_index == ND6_PREFIX_IX_INVALID)
 				cons_printf(portid, "   -");
 			else
-				cons_printf(portid, " %3d", ifp->in_ifaddrs[ix].prefix_index);
-			cons_printf(portid, "    %02x %I\n",
-			                    ifp->in_ifaddrs[ix].flags,
-			                    &ifp->in_ifaddrs[ix].addr);
-			}
-		}
+				cons_printf(portid, " %3d", ifp->in6_ifaddrs[ix].prefix_index);
+			cons_printf(portid, "    %02x %lI\n",
+			                     ifp->in6_ifaddrs[ix].flags,
+			                    &ifp->in6_ifaddrs[ix].addr);
+			}
+		}
+
+#ifdef DHCP6_CLI_CFG
+	dhcp6c_info(portid);
+#endif
 
 	SIG_NET_CONS_PRINTF();
@@ -1449,12 +1981,54 @@
 	}
 
-#endif	/* of #if defined(SUPPORT_INET6) */
+#endif	/* of #if defined(NETAPP_IP6_CFG) */
+
+#if defined(NETAPP_IP4_CFG)
 
 /*
- *  show_config -- コンフィギュレーション設定の表示
- */
-
-static void
-show_config (ID portid, char *line)
+ *  dbg_cons_ifconfig4 -- ネットワークインタフェース（IPv4）の構成情報
+ */
+
+void
+dbg_cons_ifconfig4 (ID portid, char *line)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_IN4_ADDR	bc;
+
+#ifdef SUPPORT_ETHER
+
+	if (*(line = skip_blanks(line))) {
+		T_IN4_ADDR	addr, mask;
+
+		get_ipv4addr(&mask, skip_blanks(get_ipv4addr(&addr, line)));
+		in4_add_ifaddr(addr, mask);
+		}
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
+	WAI_NET_CONS_PRINTF();
+
+	bc = (ifp->in4_ifaddr.addr & ifp->in4_ifaddr.mask) | ~ifp->in4_ifaddr.mask;
+	cons_printf(portid,
+	            "IPv4: %hI, mask: %hI, broadcast: %hI\n",
+	            &ifp->in4_ifaddr.addr,
+	            &ifp->in4_ifaddr.mask,
+	            &bc);
+
+#ifdef DHCP4_CLI_CFG
+	dhcp4c_info(portid);
+#endif
+
+	SIG_NET_CONS_PRINTF();
+	FLUSH_SND_BUFF();
+	}
+
+#endif	/* of #if defined(NETAPP_IP4_CFG) */
+
+/*
+ *  dbg_cons_show_config -- コンフィギュレーション設定の表示
+ */
+
+void
+dbg_cons_show_config (ID portid, char *line)
 {
 #if defined(SUPPORT_ETHER)
@@ -1464,22 +2038,43 @@
 #endif	/* of #if defined(SUPPORT_ETHER) */
 
-#if defined(DHCP_CFG)
-
 	cons_printf(portid, "DHCP:\n");
-
-	cons_printf(portid, "  DHCP_CFG: On\n");
-
-#endif	/* of #if define(DHCP_CFG) */
+	cons_printf(portid, "  DHCP6_CLI_CFG: ");
+
+#if defined(DHCP6_CLI_CFG)
+
+	cons_printf(portid, "On\n           Mode: ");
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS
+	cons_printf(portid, "STATELESS\n");
+#elif DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+	cons_printf(portid, "STATEFULL\n");
+#endif
+
+#else	/* of #if define(DHCP6_CLI_CFG) */
+
+	cons_printf(portid, "Off\n");
+
+#endif	/* of #if define(DHCP6_CLI_CFG) */
+
+	cons_printf(portid, "  DHCP4_CLI_CFG: ");
+
+#if defined(DHCP4_CLI_CFG)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
+	cons_printf(portid, "Resolver:\n");
+	cons_printf(portid, "  USE_RESOLVER: ");
+
+#if defined(USE_RESOLVER)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
 
 #if defined(SUPPORT_TCP)
 
 	cons_printf(portid, "TCP:\n");
-
-	cons_printf(portid, "  TCP_CFG_PASSIVE_OPEN: ");
-#if defined(TCP_CFG_PASSIVE_OPEN)
-	cons_printf(portid, "On\n");
-#else
-	cons_printf(portid, "Off\n");
-#endif
 
 	cons_printf(portid, "  TCP_CFG_OPT_MSS:      ");
@@ -1553,16 +2148,23 @@
 #endif
 
+	cons_printf(portid, "  TCP_CFG_NON_BLOCKING_COMPAT14: ");
+#if defined(TCP_CFG_NON_BLOCKING_COMPAT14)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
 	cons_printf(portid, "  TCP_CFG_EXTENTIONS:   ");
 #if defined(TCP_CFG_EXTENTIONS)
 #if defined(USE_TCP_EXTENTIONS)
 	cons_printf(portid, "Use\n");
-#if defined(SUPPORT_INET4)
-	cons_printf(portid, "  NUM_VRID_TCP_REPS:    %3d\n", NUM_VRID_TCP_REPS);
-	cons_printf(portid, "  NUM_VRID_TCP_CEPS:    %3d\n", NUM_VRID_TCP_CEPS);
-#endif	
 #if defined(SUPPORT_INET6)
 	cons_printf(portid, "  NUM_VRID_TCP6_REPS:   %3d\n", NUM_VRID_TCP6_REPS);
 	cons_printf(portid, "  NUM_VRID_TCP6_CEPS:   %3d\n", NUM_VRID_TCP6_CEPS);
-#endif	
+#endif
+#if defined(SUPPORT_INET4)
+	cons_printf(portid, "  NUM_VRID_TCP4_REPS:   %3d\n", NUM_VRID_TCP4_REPS);
+	cons_printf(portid, "  NUM_VRID_TCP4_CEPS:   %3d\n", NUM_VRID_TCP4_CEPS);
+#endif
 #else
 	cons_printf(portid, "On\n");
@@ -1589,5 +2191,5 @@
 #if defined(SUPPORT_INET4)
 	addr = TCP_CFG_TRACE_IPV4_RADDR;
-	cons_printf(portid, "                            TCP_CFG_TRACE_IPV4_RADDR: %I\n", &addr);
+	cons_printf(portid, "                            TCP_CFG_TRACE_IPV4_RADDR: %hI\n", &addr);
 #endif
 	cons_printf(portid, "                            TCP_CFG_TRACE_RPORTNO:    %d\n", TCP_CFG_TRACE_RPORTNO);
@@ -1633,4 +2235,11 @@
 #endif
 
+	cons_printf(portid, "  UDP_CFG_NON_BLOCKING_COMPAT14: ");
+#if defined(UDP_CFG_NON_BLOCKING_COMPAT14)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
 	cons_printf(portid, "  UDP_CFG_EXTENTIONS:   ");
 #if defined(UDP_CFG_EXTENTIONS)
@@ -1640,5 +2249,5 @@
 	cons_printf(portid, "On\n");
 #endif
-	cons_printf(portid, "  NUM_VRID_UDP_CEPS:    %3d\n", NUM_VRID_UDP_CEPS);
+	cons_printf(portid, "  NUM_VRID_UDP4_CEPS:   %3d\n", NUM_VRID_UDP4_CEPS);
 	cons_printf(portid, "  NUM_VRID_UDP6_CEPS:   %3d\n", NUM_VRID_UDP6_CEPS);
 #else
@@ -1667,44 +2276,24 @@
 #endif
 
+#if defined(NUM_REDIRECT_ROUTE_ENTRY)
 #if NUM_REDIRECT_ROUTE_ENTRY > 0
 	cons_printf(portid, "  TMO_IN_REDIRECT: %4d[s]\n", TMO_IN_REDIRECT / NET_TIMER_HZ);
 #endif
-
-#if defined(SUPPORT_INET4)
-
-	cons_printf(portid, "IPv4:\n");
-
-	cons_printf(portid, "  IP4_CFG_FRAGMENT: ");
-
-#if defined(IP4_CFG_FRAGMENT)
+#endif	/* of #if defined(NUM_REDIRECT_ROUTE_ENTRY) */
+
+#if defined(SUPPORT_INET6)
+
+	cons_printf(portid, "IPv6:\n");
+
+	cons_printf(portid, "  IP6_IPV4_MAPPED_ADDR:   ");
+#if defined(IP6_CFG_IPV4_MAPPED_ADDR)
 	cons_printf(portid, "On\n");
-	cons_printf(portid, "    NUM_IP4_FRAG_QUEUE:       %4d\n", NUM_IP4_FRAG_QUEUE);
-	cons_printf(portid, "    IP4_CFG_FRAG_REASSM_SIZE: %4d\n", IP4_CFG_FRAG_REASSM_SIZE);
 #else
 	cons_printf(portid, "Off\n");
-#endif	/* of #if defined(IP4_CFG_FRAGMENT) */
-
-#if defined(SUPPORT_ETHER)
-	addr = IPV4_ADDR_LOCAL;
-	cons_printf(portid, "  IPV4_ADDR_LOCAL:      %I\n", &addr);
-	addr = IPV4_ADDR_LOCAL_MASK;
-	cons_printf(portid, "  IPV4_ADDR_LOCAL_MASK: %I\n", &addr);
-	addr = IPV4_ADDR_DEFAULT_GW;
-	cons_printf(portid, "  IPV4_ADDR_DEFAULT_GW: %I\n", &addr);
-#endif	/* of #if defined(SUPPORT_ETHER) */
+#endif
 
 	cons_printf(portid, "  Routing Table:\n");
-	cons_printf(portid, "    NUM_STATIC_ROUTE_ENTRY:   %d\n", NUM_STATIC_ROUTE_ENTRY);
-	cons_printf(portid, "    NUM_REDIRECT_ROUTE_ENTRY: %d\n", NUM_REDIRECT_ROUTE_ENTRY);
-
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
-
-	cons_printf(portid, "IPv6:\n");
-
-	cons_printf(portid, "  Routing Table:\n");
-	cons_printf(portid, "    NUM_STATIC_ROUTE_ENTRY:   %d\n", NUM_STATIC_ROUTE_ENTRY);
-	cons_printf(portid, "    NUM_REDIRECT_ROUTE_ENTRY: %d\n", NUM_REDIRECT_ROUTE_ENTRY);
+	cons_printf(portid, "    NUM_IN6_STATIC_ROUTE_ENTRY:   %d\n", NUM_IN6_STATIC_ROUTE_ENTRY);
+	cons_printf(portid, "    NUM_IN6_REDIRECT_ROUTE_ENTRY: %d\n", NUM_IN6_REDIRECT_ROUTE_ENTRY);
 
 	cons_printf(portid, "ND:\n");
@@ -1730,4 +2319,33 @@
 #endif	/* of #if defined(SUPPORT_INET6) */
 
+#if defined(SUPPORT_INET4)
+
+	cons_printf(portid, "IPv4:\n");
+
+	cons_printf(portid, "  IP4_CFG_FRAGMENT: ");
+
+#if defined(IP4_CFG_FRAGMENT)
+	cons_printf(portid, "On\n");
+	cons_printf(portid, "    NUM_IP4_FRAG_QUEUE:       %4d\n", NUM_IP4_FRAG_QUEUE);
+	cons_printf(portid, "    IP4_CFG_FRAG_REASSM_SIZE: %4d\n", IP4_CFG_FRAG_REASSM_SIZE);
+#else
+	cons_printf(portid, "Off\n");
+#endif	/* of #if defined(IP4_CFG_FRAGMENT) */
+
+#if defined(SUPPORT_ETHER)
+	addr = IPV4_ADDR_LOCAL;
+	cons_printf(portid, "  IPV4_ADDR_LOCAL:      %hI\n", &addr);
+	addr = IPV4_ADDR_LOCAL_MASK;
+	cons_printf(portid, "  IPV4_ADDR_LOCAL_MASK: %hI\n", &addr);
+	addr = IPV4_ADDR_DEFAULT_GW;
+	cons_printf(portid, "  IPV4_ADDR_DEFAULT_GW: %hI\n", &addr);
+#endif	/* of #if defined(SUPPORT_ETHER) */
+
+	cons_printf(portid, "  Routing Table:\n");
+	cons_printf(portid, "    NUM_IN4_STATIC_ROUTE_ENTRY:   %d\n", NUM_IN4_STATIC_ROUTE_ENTRY);
+	cons_printf(portid, "    NUM_IN4_REDIRECT_ROUTE_ENTRY: %d\n", NUM_IN4_REDIRECT_ROUTE_ENTRY);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
 #if defined(SUPPORT_INET4) && defined(SUPPORT_ETHER)
 
@@ -1771,4 +2389,11 @@
 #endif
 
+	cons_printf(portid, "  ETHER_COLLECT_ADDR:      ");
+#if defined(ETHER_COLLECT_ADDR)
+	cons_printf(portid, "On\n");
+#else
+	cons_printf(portid, "Off\n");
+#endif
+
 #endif	/* of #if defined(SUPPORT_ETHER) */
 
@@ -1854,13 +2479,117 @@
 	}
 
+#ifdef USE_PING
+
+/*
+ *  ping コマンド
+ */
+
+void
+dbg_cons_ping_comd (ID portid, char *line)
+{
+	int_t	tmo, size;
+	char	apip = DEFAULT_API_PROTO;
+
+#if defined(SUPPORT_INET6)
+	T_IN6_ADDR	addr;
+#if defined(SUPPORT_INET4)
+	T_IN4_ADDR	addr4;
+#endif
+#else
+	T_IN4_ADDR	addr;
+#endif
+
+#if defined(PING_CFG_I6RLP)
+
+	static const char i6rlp_pmtu_str1[] = " FF1E::1:2 1 1452";
+	static const char i6rlp_pmtu_str2[] = " FF1E::1:2 1 1352";
+	static const char i6rlp_pmtu_str3[] = " fe80::0200:00ff:fe00:0100 1 2";
+
+	if      (apip == '1')
+		strcpy(line, i6rlp_pmtu_str1);
+	else if (apip == '2')
+		strcpy(line, i6rlp_pmtu_str2);
+	else if (apip == '3')
+		strcpy(line, i6rlp_pmtu_str3);
+
+#endif	/* of #ifdef PING_CFG_I6RLP */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+	if ('0' <= *line && *line <= '9') {
+		if (*line == '6')
+			apip = API_PROTO_IPV6;
+		if (*line == '4')
+			apip = API_PROTO_IPV4;
+		line ++;
+		}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	if ((line = lookup_ipaddr(&addr, line, apip)) == NULL) {
+		syslog(LOG_NOTICE, "[PING] unknown host.");
+		return;
+		}
+
+	line = skip_blanks(line);
+	if ('0' <= *line && *line <= '9')
+		line = get_int(&tmo, line);
+	else
+		tmo = 3;
+
+	line = skip_blanks(line);
+	if ('0' <= *line && *line <= '9')
+		line = get_int(&size, line);
+	else
+		size = 64;
+
+#if defined(SUPPORT_INET6)
+
+#if defined(SUPPORT_INET4)
+
+	if (apip == API_PROTO_IPV6) {
+		syslog(LOG_NOTICE, "[PING6] size: %d, tmo: %d, host: %s", size, tmo, ipv62str(NULL, &addr));
+		ping6(&addr, (uint_t)tmo, (uint_t)size);
+		}
+	else {
+		addr4 = ntohl(addr.s6_addr32[3]);
+		syslog(LOG_NOTICE, "[PING4] size: %d, tmo: %d, host: %s", size, tmo, ip2str(NULL, &addr4));
+		ping4(&addr4, (uint_t)tmo, (uint_t)size);
+		}
+
+#else /* of #if defined(SUPPORT_INET4) */
+
+	syslog(LOG_NOTICE, "[PING6] size: %d, tmo: %d, host: %s", size, tmo, ipv62str(NULL, &addr));
+	ping6(&addr, (uint_t)tmo, (uint_t)size);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+
+	syslog(LOG_NOTICE, "[PING4] size: %d, tmo: %d, host: %s", size, tmo, ip2str(NULL, &addr));
+	ping4(&addr, (uint_t)tmo, (uint_t)size);
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+	}
+
+#endif	/* of #ifdef USE_PING */
+
+#ifdef USE_DBG_CONS_PARSER
+
 /*
  *  デバッグコマンド解析
  */
 
-static void
+void
 dbg_parse (ID portid, char *line)
 {
 	int_t	cepid;
-	ER	error;
+	ER	error = E_OK;
+
+#if defined(SUPPORT_UDP) && defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+	int_t	udp_cep_ipproto;
+#endif
 
 	switch (*line) {
@@ -1870,5 +2599,5 @@
 
 		case 'f':	/* show configurations */
-			show_config(portid, line + 1);
+			dbg_cons_show_config(portid, line + 1);
 			break;
 
@@ -1880,5 +2609,5 @@
 				line ++;
 			if ((error = tcp_can_cep((ID)cepid, atoi(skip_blanks(line)))) != E_OK && error != E_RLWAI) {
-				cons_printf(portid, "[TCP CAN CEP] error: %s\n", itron_strerror(error));
+				cons_printf(portid, "[TCP CAN CEP] error: %s.\n", itron_strerror(error));
 				SIG_NET_CONS_PRINTF();
 				FLUSH_SND_BUFF();
@@ -1891,12 +2620,78 @@
 
 		case 'u':	/* cancel UDP */
+
+#if defined(SUPPORT_INET6)
+
+#if defined(SUPPORT_INET4)
+
+			udp_cep_ipproto = (*(line + 2) == '4' ? API_PROTO_IPV4 : API_PROTO_IPV6);
+			cepid = atoi(line = skip_blanks(line + 3));
+			while ('0' <= *line && *line <= '9')
+				line ++;
+
+#if TNUM_UDP6_CEPID > 0
+
+			if (udp_cep_ipproto == API_PROTO_IPV6) {
+				if ((error = udp_can_cep((ID)cepid, atoi(skip_blanks(line)))) != E_OK && error != E_RLWAI) {
+					cons_printf(portid, "[UDP CAN CEP] error: %s.\n", itron_strerror(error));
+					SIG_NET_CONS_PRINTF();
+					FLUSH_SND_BUFF();
+					}
+				}
+
+#endif	/* of #if TNUM_UDP6_CEPID > 0 */
+
+#if TNUM_UDP4_CEPID > 0
+
+			if (udp_cep_ipproto == API_PROTO_IPV4) {
+				if ((error = udp_can_cep((ID)cepid, atoi(skip_blanks(line)))) != E_OK && error != E_RLWAI) {
+					cons_printf(portid, "[UDP CAN CEP] error: %s.\n", itron_strerror(error));
+					SIG_NET_CONS_PRINTF();
+					FLUSH_SND_BUFF();
+					}
+				}
+
+#endif	/* of #if TNUM_UDP4_CEPID > 0 */
+
+#else	/* of #if defined(SUPPORT_INET4) */
+
+#if TNUM_UDP6_CEPID > 0
+
 			cepid = atoi(line = skip_blanks(line + 2));
 			while ('0' <= *line && *line <= '9')
 				line ++;
+
 			if ((error = udp_can_cep((ID)cepid, atoi(skip_blanks(line)))) != E_OK && error != E_RLWAI) {
-				cons_printf(portid, "[UDP CAN CEP] error: %s\n", itron_strerror(error));
+				cons_printf(portid, "[UDP CAN CEP] error: %s.\n", itron_strerror(error));
 				SIG_NET_CONS_PRINTF();
 				FLUSH_SND_BUFF();
 				}
+
+#endif	/* of #if TNUM_UDP6_CEPID > 0 */
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+#if TNUM_UDP4_CEPID > 0
+
+			cepid = atoi(line = skip_blanks(line + 2));
+			while ('0' <= *line && *line <= '9')
+				line ++;
+
+			if ((error = udp_can_cep((ID)cepid, atoi(skip_blanks(line)))) != E_OK && error != E_RLWAI) {
+				cons_printf(portid, "[UDP CAN CEP] error: %s.\n", itron_strerror(error));
+				SIG_NET_CONS_PRINTF();
+				FLUSH_SND_BUFF();
+				}
+
+#endif	/* of #if TNUM_UDP4_CEPID > 0 */
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
 			break;
 
@@ -1906,6 +2701,4 @@
 
 		break;
-
-#if defined(USE_UDP_DISCARD_CLI) || defined(USE_TCP_DISCARD_CLI) || defined(SUPPORT_PPP) || defined(SUPPORT_ETHER) && defined(USE_NET_CONS)
 
 	case 'd':	/* discard client */
@@ -1929,4 +2722,12 @@
 #endif	/* of #if defined(SUPPORT_ETHER) && defined(USE_NET_CONS) */
 
+#if defined(DHCP6_CLI_CFG) || defined(DHCP4_CLI_CFG)
+
+		case 'h':		/* DHCP client */
+			dhcpc(portid, line + 2);
+			break;
+
+#endif	/* of #if defined(DHCP6_CLI_CFG) || defined(DHCP4_CLI_CFG) */
+
 #ifdef USE_TCP_DISCARD_CLI
 
@@ -1941,5 +2742,5 @@
 			default:
 				if ((error = psnd_dtq(DTQ_TCP_DISCARD_CLI, (intptr_t)line)) != E_OK) {
-					cons_printf(portid, "[TCP DISCARD CLI] error: %s\n",
+					cons_printf(portid, "[TCP DISCARD CLI] error: %s.\n",
 					       itron_strerror(error));
 					SIG_NET_CONS_PRINTF();
@@ -1965,5 +2766,5 @@
 			default:
 				if ((error = psnd_dtq(DTQ_UDP_DISCARD_CLI, (intptr_t)line)) != E_OK) {
-					cons_printf(portid, "[UDP DISCARD CLI] error: %s\n",
+					cons_printf(portid, "[UDP DISCARD CLI] error: %s.\n",
 					       itron_strerror(error));
 					SIG_NET_CONS_PRINTF();
@@ -1981,7 +2782,5 @@
 		break;
 
-#endif	/* of #if defined(USE_UDP_DISCARD_CLI) || defined(USE_TCP_DISCARD_CLI) || defined(SUPPORT_PPP) || defined(SUPPORT_ETHER) && defined(USE_NET_CONS) */
-
-#if defined(USE_UDP_ECHO_CLI) || defined(USE_TCP_ECHO_CLI)
+#if defined(USE_TCP_ECHO_CLI) || defined(USE_UDP_ECHO_CLI)
 
 	case 'e':	/* echo client */
@@ -2000,5 +2799,5 @@
 			default:
 				if ((error = psnd_dtq(DTQ_TCP_ECHO_CLI_SND, (intptr_t)line)) != E_OK) {
-					cons_printf(portid, "[TCP ECHO CLI] error: %s\n", itron_strerror(error));
+					cons_printf(portid, "[TCP ECHO CLI] error: %s.\n", itron_strerror(error));
 					SIG_NET_CONS_PRINTF();
 					FLUSH_SND_BUFF();
@@ -2011,20 +2810,79 @@
 #endif	/* of #ifdef USE_TCP_ECHO_CLI */
 
-#ifdef USE_UDP_ECHO_CLI
+#if defined(USE_UDP_ECHO_CLI)
 
 		case 'u':	/* UDP echo client */
-			line += 2;
-			switch (*line) {
+			switch (*(line + 2)) {
 
 			case 's':	/* cancel UDP echo */
-				udp_echo_cli_valid = false;
+
+#if defined(USE_UDP6_ECHO_CLI_TSK)
+
+#if defined(USE_UDP4_ECHO_CLI_TSK)
+
+				if (*(line + 3) == '4')
+					udp4_echo_cli_valid = false;
+				else
+					udp6_echo_cli_valid = false;
+
+#else	/* of #if defined(USE_UDP4_ECHO_CLI_TSK) */
+
+				udp6_echo_cli_valid = false;
+
+#endif	/* of #if defined(USE_UDP4_ECHO_CLI_TSK) */
+
+#else	/* of #if defined(USE_UDP6_ECHO_CLI_TSK) */
+
+#if defined(USE_UDP4_CLI_TSK)
+
+				udp4_echo_cli_valid = false;
+
+#endif	/* of #if defined(USE_UDP4_CLI_TSK) */
+
+#endif	/* of #if defined(USE_UDP6_ECHO_CLI_TSK) */
+
+
 				break;
 
 			default:
-				if ((error = psnd_dtq(DTQ_UDP_ECHO_CLI, (intptr_t)line)) != E_OK) {
-					cons_printf(portid, "[UDP ECHO CLI] error: %s\n", itron_strerror(error));
+
+				line += 2;
+
+#if defined(USE_UDP6_ECHO_CLI_TSK)
+
+#if defined(USE_UDP4_ECHO_CLI_TSK)
+
+				if (*line == '4') {
+					line ++;
+					error = psnd_dtq(DTQ_UDP4_ECHO_CLI, (intptr_t)line);
+					}
+				else {
+					if (*line && *line != ' ')
+						line ++;
+					error = psnd_dtq(DTQ_UDP6_ECHO_CLI, (intptr_t)line);
+					}
+
+#else	/* of #if defined(USE_UDP4_ECHO_CLI_TSK) */
+
+				if (*line && *line != ' ')
+					line ++;
+				error = psnd_dtq(DTQ_UDP6_ECHO_CLI, (intptr_t)line);
+
+#endif	/* of #if defined(USE_UDP4_ECHO_CLI_TSK) */
+
+#else	/* of #if defined(USE_UDP6_ECHO_CLI_TSK) */
+
+				if (*line && *line != ' ')
+					line ++;
+				error = psnd_dtq(DTQ_UDP4_ECHO_CLI, (intptr_t)line);
+
+#endif	/* of #if defined(USE_UDP6_ECHO_CLI_TSK) */
+
+				if (error != E_OK) {
+					cons_printf(portid, "[UDP ECHO CLI] error: %s.\n", itron_strerror(error));
 					SIG_NET_CONS_PRINTF();
 					FLUSH_SND_BUFF();
 					}
+
 				break;
 
@@ -2032,5 +2890,5 @@
 			break;
 
-#endif	/* of #ifdef USE_UDP_ECHO_CLI */
+#endif	/* of #if defined(USE_UDP_ECHO_CLI) */
 
 			}
@@ -2038,10 +2896,21 @@
 		break;
 
-#endif	/* of #if defined(USE_UDP_ECHO_CLI) || defined(USE_TCP_ECHO_CLI) */
+#endif	/* of #if defined(USE_TCP_ECHO_CLI) || defined(USE_UDP_ECHO_CLI) */
 
 	case 'i':
 
-		if (*(line + 1) == 'f')
-			ifconfig(portid, line + 2);
+		if (*(line + 1) == 'f') {
+
+			dbg_cons_ifconfig (portid, line + 2);
+
+#if defined(NETAPP_IP6_CFG)
+			dbg_cons_ifconfig6(portid, line + 2);
+#endif
+
+#if defined(NETAPP_IP4_CFG)
+			dbg_cons_ifconfig4(portid, line + 2);
+#endif
+
+			}
 
 #ifdef SUPPORT_PPP
@@ -2064,5 +2933,5 @@
 
 	case 'n':		/* network status */
-		network_status(portid, line + 1);
+		dbg_cons_network_status(portid, line + 1);
 		break;
 
@@ -2070,40 +2939,10 @@
 
 		if (*(line + 1) == 's')
-			task_status(portid, skip_blanks(line + 2));
+			dbg_cons_task_status(portid, skip_blanks(line + 2));
 
 #ifdef USE_PING
 
-		else {
-			int_t		tmo, size;
-			T_IN_ADDR	addr;
-
-#ifdef PING_CFG_I6RLP
-			static const char i6rlp_pmtu_str1[] = " FF1E::1:2 1 1452";
-			static const char i6rlp_pmtu_str2[] = " FF1E::1:2 1 1352";
-			static const char i6rlp_pmtu_str3[] = " fe80::0200:00ff:fe00:0100 1 2";
-
-			if      (*(line + 1) == '1')
-				strcpy(line + 1, i6rlp_pmtu_str1);
-			else if (*(line + 1) == '2')
-				strcpy(line + 1, i6rlp_pmtu_str2);
-			else if (*(line + 1) == '3')
-				strcpy(line + 1, i6rlp_pmtu_str3);
-
-#endif	/* of #ifdef PING_CFG_I6RLP */
-
-			line = skip_blanks(GET_IPADDR(&addr, skip_blanks(line + 1)));
-			if ('0' <= *line && *line <= '9')
-				line = get_int(&tmo, line);
-			else
-				tmo = 3;
-
-			line = skip_blanks(line + 1);
-			if ('0' <= *line && *line <= '9')
-				line = get_int(&size, line);
-			else
-				size = 64;
-
-			PING(&addr, (uint_t)tmo, (uint_t)size);
-			}
+		else
+			dbg_cons_ping_comd(portid, line + 1);
 
 #endif	/* of #ifdef USE_PING */
@@ -2113,5 +2952,5 @@
 	case 'r':		/* release wait task */
 		if ((error = rel_wai(atoi(skip_blanks(line + 1)))) != E_OK) {
-			cons_printf(portid, "[REL WAI TSK] error: %s\n", itron_strerror(error));
+			cons_printf(portid, "[REL WAI TSK] error: %s.\n", itron_strerror(error));
 			SIG_NET_CONS_PRINTF();
 			FLUSH_SND_BUFF();
@@ -2125,6 +2964,10 @@
 
 		case 't':		/* TCP REP */
-			if ((error = tcp_del_rep(atoi(skip_blanks(line + 2)))) != E_OK) {
-				cons_printf(portid, "[TCP DEL REP] error: %s\n", itron_strerror(error));
+	
+			error = tcp_del_rep(atoi(skip_blanks(line + 2)));
+			if (error != E_OK) {
+				cons_printf(portid, "[TCP DEL REP] ID: %d, error: %s.\n", 
+				                    atoi(skip_blanks(line + 2)),
+				                    itron_strerror(error));
 				SIG_NET_CONS_PRINTF();
 				FLUSH_SND_BUFF();
@@ -2137,9 +2980,48 @@
 
 		case 'u':		/* UDP CEP */
-			if ((error = udp_del_cep(atoi(skip_blanks(line + 2)))) != E_OK) {
-				cons_printf(portid, "[UDP DEL CEP] error: %s\n", itron_strerror(error));
+
+#if defined(USE_UDP6_ECHO_SRV_TSK)
+
+#if defined(USE_UDP4_ECHO_SRV_TSK)
+
+			if (*(line + 2) == '4') {
+				if ((error = udp_del_cep(atoi(skip_blanks(line + 3)))) != E_OK) {
+					cons_printf(portid, "[UDP DEL CEP] error: %s.\n", itron_strerror(error));
+					SIG_NET_CONS_PRINTF();
+					FLUSH_SND_BUFF();
+					}
+				}
+			else {
+				if ((error = udp6_del_cep(atoi(skip_blanks(line + 2)))) != E_OK) {
+					cons_printf(portid, "[UDP DEL CEP] error: %s.\n", itron_strerror(error));
+					SIG_NET_CONS_PRINTF();
+					FLUSH_SND_BUFF();
+					}
+				}
+
+#else	/* of #if defined(USE_UDP4_ECHO_SRV_TSK) */
+
+			if ((error = udp6_del_cep(atoi(skip_blanks(line + 2)))) != E_OK) {
+				cons_printf(portid, "[UDP DEL CEP] error: %s.\n", itron_strerror(error));
 				SIG_NET_CONS_PRINTF();
 				FLUSH_SND_BUFF();
 				}
+
+#endif	/* of #if defined(USE_UDP4_ECHO_SRV_TSK) */
+
+#else	/* of #if defined(USE_UDP6_ECHO_SRV_TSK) */
+
+#if defined(USE_UDP4_ECHO_SRV_TSK)
+
+			if ((error = udp_del_cep(atoi(skip_blanks(line + 2)))) != E_OK) {
+				cons_printf(portid, "[UDP DEL CEP] error: %s.\n", itron_strerror(error));
+				SIG_NET_CONS_PRINTF();
+				FLUSH_SND_BUFF();
+				}
+
+#endif	/* of #if defined(USE_UDP4_ECHO_SRV_TSK) */
+
+#endif	/* of #if defined(USE_UDP6_ECHO_SRV_TSK) */
+
 			break;
 
@@ -2163,5 +3045,5 @@
 			case 'd':		/* tcp discard server */
 				if ((error = wup_tsk(TCP_DISCARD_SRV_TASK)) != E_OK) {
-					cons_printf(portid, "[WUP TCP DISCARD SRV] error: %s\n", itron_strerror(error));
+					//cons_printf(portid, "[WUP TCP DISCARD SRV] error: %s.\n", itron_strerror(error));
 					SIG_NET_CONS_PRINTF();
 					FLUSH_SND_BUFF();
@@ -2170,18 +3052,28 @@
 #endif	/* of #ifdef USE_TCP_DISCARD_SRV */
 
-#if defined(USE_TCP_ECHO_SRV1) || defined(USE_TCP_ECHO_SRV2)
+#if defined(USE_TCP_ECHO_SRV1)
 			case 'e':		/* tcp echo server */
-				if ((error = wup_tsk(TCP_ECHO_SRV_TASK)) != E_OK) {
-					cons_printf(portid, "[WUP UDP DISCARD SRV] error: %s\n", itron_strerror(error));
+				if ((error = wakeup_tcp_echo_srv((*(line + 3) == '4' ? API_PROTO_IPV4 : API_PROTO_IPV6))) != E_OK) {
+					//cons_printf(portid, "[WUP TCP ECHO SRV] error: %s.\n", itron_strerror(error));
 					SIG_NET_CONS_PRINTF();
 					FLUSH_SND_BUFF();
 					}
 				break;
-#endif	/* of #if defined(USE_TCP_ECHO_SRV1) || defined(USE_TCP_ECHO_SRV2) */
+#endif	/* of #if defined(USE_TCP_ECHO_SRV1) */
+
+#if defined(USE_TCP_ECHO_SRV2)
+			case 'e':		/* tcp echo server */
+				if ((error = wup_tsk(TCP_ECHO_SRV_TASK2)) != E_OK) {
+					//cons_printf(portid, "[WUP TCP ECHO SRV] error: %s.\n", itron_strerror(error));
+					SIG_NET_CONS_PRINTF();
+					FLUSH_SND_BUFF();
+					}
+				break;
+#endif	/* of #if defined(USE_TCP_ECHO_SRV2) */
 
 #ifdef USE_WWW_SRV
 			case 'w':		/* WWW server */
-				if ((error = wup_tsk(WWW_SRV_TASK1)) != E_OK) {
-					cons_printf(portid, "[WUP WWW SRV] error: %s\n", itron_strerror(error));
+				if ((error = wakeup_www_srv((*(line + 3) == '4' ? API_PROTO_IPV4 : API_PROTO_IPV6))) != E_OK) {
+					//cons_printf(portid, "[WUP WWW SRV] error: %s.\n", itron_strerror(error));
 					SIG_NET_CONS_PRINTF();
 					FLUSH_SND_BUFF();
@@ -2200,13 +3092,54 @@
 			switch (*(line + 2)) {
 
-#if defined(USE_UDP_ECHO_SRV) && !defined(USE_UDP_CALL_BACK)
+#if !defined(USE_UDP_CALL_BACK)
+
 			case 'e':		/* udp echo server */
-				if ((error = wup_tsk(UDP_ECHO_SRV_TASK)) != E_OK) {
-					cons_printf(portid, "[WUP UDP ECHO SRV] error: %s\n", itron_strerror(error));
+
+#if defined(USE_UDP6_ECHO_SRV_TSK)
+
+#if defined(USE_UDP4_ECHO_SRV_TSK)
+
+				if (*(line + 3) == '4') {
+					if ((error = wup_tsk(UDP4_ECHO_SRV_TASK)) != E_OK) {
+						cons_printf(portid, "[WUP UDP4 ECHO SRV] error: %s.\n", itron_strerror(error));
+						SIG_NET_CONS_PRINTF();
+						FLUSH_SND_BUFF();
+						}
+					}
+				else {
+					if ((error = wup_tsk(UDP6_ECHO_SRV_TASK)) != E_OK) {
+						cons_printf(portid, "[WUP UDP6 ECHO SRV] error: %s.\n", itron_strerror(error));
+						SIG_NET_CONS_PRINTF();
+						FLUSH_SND_BUFF();
+						}
+					}
+
+#else	/* of #if defined(USE_UDP4_ECHO_SRV_TSK) */
+
+				if ((error = wup_tsk(UDP6_ECHO_SRV_TASK)) != E_OK) {
+					cons_printf(portid, "[WUP UDP6 ECHO SRV] error: %s.\n", itron_strerror(error));
 					SIG_NET_CONS_PRINTF();
 					FLUSH_SND_BUFF();
 					}
+
+#endif	/* of #if defined(USE_UDP4_ECHO_SRV_TSK) */
+
+#else	/* of #if defined(USE_UDP6_ECHO_SRV_TSK) */
+
+#if defined(USE_UDP4_ECHO_SRV_TSK)
+
+				if ((error = wup_tsk(UDP4_ECHO_SRV_TASK)) != E_OK) {
+					cons_printf(portid, "[WUP UDP4 ECHO SRV] error: %s.\n", itron_strerror(error));
+					SIG_NET_CONS_PRINTF();
+					FLUSH_SND_BUFF();
+					}
+
+#endif	/* of #if defined(USE_UDP4_ECHO_SRV_TSK) */
+
+#endif	/* of #if defined(USE_UDP6_ECHO_SRV_TSK) */
+
 				break;
-#endif	/* of #if defined(USE_UDP_ECHO_SRV) && !defined(USE_UDP_CALL_BACK) */
+
+#endif	/* of #if !defined(USE_UDP_CALL_BACK) */
 
 				}
@@ -2217,5 +3150,5 @@
 		default:
 			if ((error = wup_tsk(atoi(skip_blanks(line + 1)))) != E_OK) {
-				cons_printf(portid, "[WUP TSK] error: %s\n", itron_strerror(error));
+				cons_printf(portid, "[WUP TSK] error: %s.\n", itron_strerror(error));
 				SIG_NET_CONS_PRINTF();
 				FLUSH_SND_BUFF();
@@ -2230,5 +3163,5 @@
 	case 'w':		/* wake up task */
 		if ((error = wup_tsk(atoi(skip_blanks(line + 1)))) != E_OK) {
-			cons_printf(portid, "[WUP TSK] error: %s\n", itron_strerror(error));
+			cons_printf(portid, "[WUP TSK] error: %s.\n", itron_strerror(error));
 			SIG_NET_CONS_PRINTF();
 			FLUSH_SND_BUFF();
@@ -2242,15 +3175,17 @@
 		if (*line) {
 
-#ifdef USE_EXTRA_PARSE
-
-			extra_parse(line);
-
-#else	/* of #ifdef USE_EXTRA_PARSE */
-
-			cons_printf(portid, "no such command: '%c'\n", *line);
+#ifdef USE_DBG_CONS_EXTRA_PARSE
+
+			//cons_printf(portid, "extra command: '%c'.\n", *line);
+			dbg_cons_extra_parse(portid, line);
+
+#else	/* of #ifdef USE_DBG_CONS_EXTRA_PARSE */
+
+			//cons_printf(portid, "command: '%c'.\n", *line);
+			cons_printf(portid, "no such command: '%c'.\n", *line);
 			SIG_NET_CONS_PRINTF();
 			FLUSH_SND_BUFF();
 
-#endif	/* of #ifdef USE_EXTRA_PARSE */
+#endif	/* of #ifdef USE_DBG_CONS_EXTRA_PARSE */
 
 			}
@@ -2258,4 +3193,6 @@
 		}
 	}
+
+#endif	/* of #ifdef USE_DBG_CONS_PARSER */
 
 /*
@@ -2268,5 +3205,4 @@
 	static char line[DBG_LINE_SIZE + 1];
 
-	uint_t	len;
 	ID	tskid;
 
@@ -2274,49 +3210,60 @@
 #ifdef SUPPORT_ETHER
 
+#if 0
 #if defined(SUPPORT_INET6)
 
-	int_t		lllen;
+	uint32_t	lllen;
 	const uint8_t	*lladdr;
 
 #endif	/* of #if defined(SUPPORT_INET6) */
-
-	lcd_init();
+#endif
+
+	lcd_initialize(0);
+
+#if 0
+#if defined(SUPPORT_INET6)
+
+	dly_tsk(1 * 1000);
+	lladdr = IF_ETHER_NIC_GET_SOFTC()->ifaddr.lladdr;
+	for (lllen = ETHER_ADDR_LEN; lllen --; )
+		lcd_printf(LCD_PORTID, "%02x", *lladdr ++);
+	lcd_putc(LCD_PORTID, '\n');
+
+#else	/* of #if defined(SUPPORT_INET6) */
 
 	if ((TINET_PRVER & UINT_C(0x0f)) > 0)
-		lcd_printf("TINET-%d.%d.%d\n",
+		lcd_printf(LCD_PORTID, "TINET-%d.%d.%d\n",
 		       (TINET_PRVER   >> 12) & UINT_C(0x0f),
 		       (TINET_PRVER   >>  4) & UINT_C(0x0f),
 		        TINET_PRVER          & UINT_C(0x0f));
 	else
-		lcd_printf("TINET-%d.%d\n",
+		lcd_printf(LCD_PORTID, "TINET-%d.%d\n",
 		       (TINET_PRVER   >> 12) & UINT_C(0x0f),
 		       (TINET_PRVER   >>  4) & UINT_C(0x0f));
 
-#if defined(SUPPORT_INET6)
-
-	lladdr = IF_ETHER_NIC_GET_SOFTC()->ifaddr.lladdr;
-	for (lllen = ETHER_ADDR_LEN; lllen --; )
-		lcd_printf("%02x", *lladdr ++);
-	lcd_printf("\n");
-
-#else	/* of #if defined(SUPPORT_INET6) */
-
-	lcd_puts(ip2str(NULL, in4_get_ifaddr(0)));
-
 #endif	/* of #if defined(SUPPORT_INET6) */
+#endif
+
+#if 0
+#if defined(SUPPORT_INET4)
+
+	dly_tsk(1 * 1000);
+	lcd_puts(LCD_PORTID, ip2str(NULL, in4_get_ifaddr(0)));
+	lcd_putc(LCD_PORTID, '\n');
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+#endif
 
 #endif	/* of #ifdef SUPPORT_ETHER */
-#else	/* of #ifdef USE_LCD */
+#endif	/* of #ifdef USE_LCD */
 
 	get_tid(&tskid);
 	cons_printf(CONSOLE_PORTID, "[CONSOLE:%d] started.\n", tskid);
-
-#endif	/* of #ifdef USE_LCD */
-
 	serial_ctl_por(CONSOLE_PORTID,
 	               IOCTL_ECHO  | IOCTL_CRLF  |
 	               IOCTL_FCSND | IOCTL_FCANY | IOCTL_FCRCV);
+	netapp_srand (tskid);
 	while (true) {
-		len = cons_getline(CONSOLE_PORTID, line, DBG_LINE_SIZE);
+		cons_getline(CONSOLE_PORTID, line, DBG_LINE_SIZE);
 		dbg_parse(CONSOLE_PORTID, line);
 		}
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dbg_cons.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dbg_cons.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dbg_cons.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dbg_cons.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dbg_cons.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dbg_cons.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -53,5 +53,13 @@
 
 extern void act_tasks (void);
-extern void extra_parse (char *line);
+extern void dbg_parse (ID portid, char *line);
+extern void dbg_cons_extra_parse (ID portid, char *line);
+extern void dbg_cons_task_status (ID portid, char *line);
+extern void dbg_cons_network_status (ID portid, char *line);
+extern void dbg_cons_ifconfig (ID portid, char *line);
+extern void dbg_cons_ifconfig6 (ID portid, char *line);
+extern void dbg_cons_ifconfig4 (ID portid, char *line);
+extern void dbg_cons_show_config (ID portid, char *line);
+extern void dbg_cons_ping_comd (ID portid, char *line);
 
 #endif	/* of #ifndef _DBG_CONS_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4.h	(revision 331)
@@ -0,0 +1,387 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+ *      ã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+ *        å ±åãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef DHCP4_H
+#define DHCP4_H
+
+/*
+ *  DHCP ã«é¢ããå®ç¾©
+ *
+ *    RFC2131
+ */
+
+/*
+ *  DHCP ã¡ãã»ã¼ã¸ã®å®æ°ã®å®ç¾©
+ */
+
+#define DHCP4_CHADDR_LEN	16
+#define DHCP4_SNAME_LEN		64
+#define DHCP4_FILE_LEN		128
+#define DHCP4_DFLT_OPT_LEN	312
+#define DHCP4_UDP_MSG_LENGTH	(sizeof(uint32_t)*7+DHCP4_CHADDR_LEN	\
+				 +DHCP4_SNAME_LEN+DHCP4_FILE_LEN+DHCP4_DFLT_OPT_LEN)
+#define DHCP4_SNAME_OFFSET	(sizeof(uint32_t)*7+DHCP4_CHADDR_LEN)
+#define DHCP4_FILE_OFFSET	(DHCP4_SNAME_OFFSET+DHCP4_SNAME_LEN)
+#define DHCP4_OPTION_OFFSET	(DHCP4_FILE_OFFSET+DHCP4_FILE_LEN)
+#define DHCP4_TIME_INFINITY	UINT_C(0xffffffff)
+
+/*
+ *  DHCP ã¡ãã»ã¼ã¸
+ */
+
+typedef struct dhcp4_msg {
+	uint8_t		op;			/* packet type			*/
+	uint8_t		htype;			/* hardware address type	*/
+	uint8_t		hlen;			/* hardware address length	*/
+	uint8_t		hops;			/* gateway hops			*/
+	uint32_t	xid;			/* transaction ID		*/
+	uint16_t	secs;			/* seconds since boot began	*/
+	uint16_t	flags;
+	uint32_t	ciaddr;			/* client IP address		*/
+	uint32_t	yiaddr;			/* your   IP address		*/
+	uint32_t	siaddr;			/* server IP address		*/
+	uint32_t	giaddr;			/* relay agent IP address	*/
+	uint8_t		chaddr [DHCP4_CHADDR_LEN];	/* client hardware address	*/
+	uint8_t		sname  [DHCP4_SNAME_LEN];	/* server host name		*/
+	uint8_t		file   [DHCP4_FILE_LEN];		/* boot file name		*/
+	uint8_t		options[DHCP4_DFLT_OPT_LEN];	/* optional parameters field	*/
+	} T_DHCP4_MSG;
+
+/* packet type ã®å®ç¾© */
+
+#define DHCP4_REQUEST		UINT_C(1)
+#define DHCP4_REPLY		UINT_C(2)
+
+/* hardware address type ã®å®ç¾© */
+
+#define DHCP4_HWA_TYPE_ETHER	UINT_C(1)
+#define DHCP4_HWA_TYPE_IEEE802	UINT_C(6)
+
+/*
+ *  DHCP ãªãã·ã§ã³
+ *
+ *    RFC1533
+ */
+
+/*
+ *  ãªãã·ã§ã³ã®ç©´åã
+ */
+#define DHCP4_OPT_PAD		UINT_C(0)
+
+/*
+ *  ãµãããããã¹ã¯
+ *
+ *     code   len   subnet mask
+ *   +------+-----+-----+-----+-----+-----+
+ *   |   1  |  4  |  m1 |  m2 |  m3 |  m4 |
+ *   +------+-----+-----+-----+-----+-----+
+ */
+#define DHCP4_OPT_SUBNET_MASK	UINT_C(1)
+
+/*
+ *  ã«ã¼ã¿
+ *
+ *     code   len   addres #1               address #2
+ *   +------+-----+-----+-----+-----+-----+-----+-----+---
+ *   |   3  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 | ...
+ *   +------+-----+-----+-----+-----+-----+-----+-----+---
+ */
+#define DHCP4_OPT_ROUTER		UINT_C(3)
+
+/*
+ *  DNS ãµã¼ã
+ *
+ *     code   len   addres #1               address #2
+ *   +------+-----+-----+-----+-----+-----+-----+-----+---
+ *   |   6  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 | ...
+ *   +------+-----+-----+-----+-----+-----+-----+-----+---
+ */
+#define DHCP4_OPT_DNS_SERVER	UINT_C(6)
+
+/*
+ *  ãã¹ãå
+ *
+ *     code   len   host name
+ *   +------+-----+-----+-----+-----+-----+---
+ *   |  12  |  n  |  h1 |  h2 |  h3 |  h4 | ...
+ *   +------+-----+-----+-----+-----+-----+---
+ */
+#define DHCP4_OPT_HOST_NAME	UINT_C(12)
+
+/*
+ *  ãã¡ã¤ã³å
+ *
+ *     code   len   domain name
+ *   +------+-----+-----+-----+-----+-----+---
+ *   |  15  |  n  |  d1 |  d2 |  d3 |  d4 | ...
+ *   +------+-----+-----+-----+-----+-----+---
+ */
+#define DHCP4_OPT_DOMAIN_NAME	UINT_C(15)
+
+/*
+ *  ã«ã¼ã¿æ¢ç´¢
+ *
+ *     code   len  value
+ *   +------+-----+-----+
+ *   |  31  |  1  | 0/1 |
+ *   +------+-----+-----+
+ */
+#define DHCP4_OPT_RTR_DISOVERY	UINT_C(31)
+
+/*
+ *  éççµè·¯
+ *
+ *     code   len   destination #1          router #1
+ *   +------+-----+-----+-----+-----+-----+-----+-----+---
+ *   |  33  |  n  |  d1 |  d2 |  d3 |  d4 |  r1 |  r2 | ...
+ *   +------+-----+-----+-----+-----+-----+-----+-----+---
+ */
+#define DHCP4_OPT_STATIC_ROUTE	UINT_C(33)
+
+/*
+ *  ãã³ãã¼åºææ
+å ±
+ *
+ *     code   len   vendor-specific informations
+ *   +------+-----+-----+-----+-----+---
+ *   |  43  |  n  |  i1 |  i2 |  i3 | ...  
+ *   +------+-----+-----+-----+-----+---
+ *
+ */
+#define DHCP4_OPT_VENDOR_INFO	UINT_C(43)
+
+/*
+ *  NetBIOS over TCP/IP ãã¼ã ãµã¼ã
+ *
+ *     code   len   addres #1               address #2
+ *   +------+-----+-----+-----+-----+-----+-----+-----+---
+ *   |  44  |  n  |  a1 |  a2 |  a3 |  a4 |  a1 |  a2 | ...
+ *   +------+-----+-----+-----+-----+-----+-----+-----+---
+ */
+#define DHCP4_OPT_NETBIOS_NS	UINT_C(44)
+
+/*
+ *  NetBIOS over TCP/IP ãã¼ãã¿ã¤ã
+ *
+ *     code   len   type
+ *   +------+-----+-----+
+ *   |  46  |  1  | type|
+ *   +------+-----+-----+
+ */
+#define DHCP4_OPT_NETBIOS_NODE	UINT_C(46)
+
+/*
+ *  NetBIOS over TCP/IP ã¹ã³ã¼ã
+ *
+ *     code   len   NetBIOS scope
+ *   +------+-----+-----+-----+-----+-----+---
+ *   |  44  |  n  |  s1 |  s2 |  s3 |  s4 |  ...
+ *   +------+-----+-----+-----+-----+-----+---
+ */
+#define DHCP4_OPT_NETBIOS_SCOPE	UINT_C(47)
+
+/*
+ *  ç¹å®ã® IPv4 ã¢ãã¬ã¹è¦æ±
+ *
+ *     code   len   IPv4 address
+ *   +------+-----+-----+-----+-----+-----+
+ *   |  50  |  4  |  a1 |  a2 |  a3 |  a4 |
+ *   +------+-----+-----+-----+-----+-----+
+ */
+#define DHCP4_OPT_REQ_IPV4	UINT_C(50)
+
+/*
+ *  ãªã¼ã¹æé
+ *
+ *     code   len   lease time
+ *   +------+-----+-----+-----+-----+-----+
+ *   |  51  |  4  |  t1 |  t2 |  t3 |  t4 |
+ *   +------+-----+-----+-----+-----+-----+
+ */
+#define DHCP4_OPT_LEASE_TIME	UINT_C(51)
+
+/*
+ *  ãªãã·ã§ã³ãªã¼ãã¼ã­ã¼ã
+ *
+ *     code   len  value
+ *   +------+-----+-----+
+ *   |  52  |  1  | 1-3 |
+ *   +------+-----+-----+
+ */
+#define DHCP4_OPT_OPT_OVERLOAD	UINT_C(52)
+
+/* value ã®å®ç¾© */
+
+#define DHCP4_OPTOL_FILE	UINT_C(0x01)
+#define DHCP4_OPTOL_SNAME	UINT_C(0x02)
+#define DHCP4_OPTOL_BOTH	UINT_C(0x03)
+
+/*
+ *  DHCP ã¡ãã»ã¼ã¸ã¿ã¤ã
+ *
+ *     code   len   type
+ *   +------+-----+-----+
+ *   |  53  |  1  | 1-7 |
+ *   +------+-----+-----+
+ */
+#define DHCP4_OPT_MSG_TYPE	UINT_C(53)
+
+/* type ã®å®ç¾© */
+
+#define DHCP4_MTYPE_BOOTP	UINT_C(0)
+#define DHCP4_MTYPE_DISCOVER	UINT_C(1)
+#define DHCP4_MTYPE_OFFER	UINT_C(2)
+#define DHCP4_MTYPE_REQUEST	UINT_C(3)
+#define DHCP4_MTYPE_DECLINE	UINT_C(4)
+#define DHCP4_MTYPE_ACK		UINT_C(5)
+#define DHCP4_MTYPE_NAK		UINT_C(6)
+#define DHCP4_MTYPE_RELEASE	UINT_C(7)
+#define DHCP4_MTYPE_INFOMATION	UINT_C(8)
+
+/*
+ *  ãµã¼ã ID
+ *
+ *     code   len   IPv4 address
+ *   +------+-----+-----+-----+-----+-----+
+ *   |  54  |  4  |  a1 |  a2 |  a3 |  a4 |
+ *   +------+-----+-----+-----+-----+-----+
+ */
+#define DHCP4_OPT_SERVER_ID	UINT_C(54)
+
+/*
+ *  è¦æ±ãã©ã¡ã¼ã¿ãªã¹ã
+ *
+ *     code   len   option code
+ *   +------+-----+-----+-----+-----+---
+ *   |  55  |  n  |  c1 |  c2 |  c3 | ...  
+ *   +------+-----+-----+-----+-----+---
+ *
+ */
+#define DHCP4_OPT_REQ_PARAM	UINT_C(55)
+
+/*
+ *  Renewal (T1) æé
+ *
+ *     code   len   T1 interval
+ *   +------+-----+-----+-----+-----+-----+
+ *   |  58  |  4  |  t1 |  t2 |  t3 |  t4 |
+ *   +------+-----+-----+-----+-----+-----+
+ */
+#define DHCP4_OPT_RENEWAL_T1	UINT_C(58)
+
+/*
+ *  Rebinding (T2) æé
+ *
+ *     code   len   T2 interval
+ *   +------+-----+-----+-----+-----+-----+
+ *   |  59  |  4  |  t1 |  t2 |  t3 |  t4 |
+ *   +------+-----+-----+-----+-----+-----+
+ */
+#define DHCP4_OPT_REBINDING_T2	UINT_C(59)
+
+/*
+ *  ãã³ãã¼ã¯ã©ã¹ IDï¼RFC2132ï¼
+ *
+ *     code   len   vendor class ID
+ *   +------+-----+-----+-----+-----+---
+ *   |  60  |  n  |  i1 |  i2 |  i3 | ...  
+ *   +------+-----+-----+-----+-----+---
+ *
+ */
+#define DHCP4_OPT_VCLASS_ID	UINT_C(60)
+
+/*
+ *  ã¯ã©ã¤ã¢ã³ã ID
+ *
+ *     code   len   type  client ID
+ *   +------+-----+-----+-----+-----+---
+ *   |  61  |  n  | type|  i1 |  i2 | ...  
+ *   +------+-----+-----+-----+-----+---
+ *
+ *   type       : ãã¼ãã¦ã§ã¢ã¢ãã¬ã¹ã¿ã¤ã
+ *   i1, i2, ...: éå¸¸ MAC ã¢ãã¬ã¹
+ */
+#define DHCP4_OPT_CLIENT_ID	UINT_C(61)
+
+/*
+ *  ã¯ã©ã¹ãªãéççµè·¯ï¼RFC3442ï¼
+ *
+ *     code   len   destination #1     router #1
+ *   +------+-----+-----+------+-----+-----+-----+-----+---
+ *   |  121 |  n  |  d1 |  ... |  dN |  r1 |  r2 |  r3 | ...
+ *   +------+-----+-----+------+-----+-----+-----+-----+---
+ */
+#define DHCP4_OPT_CLASSLESS_RTE	UINT_C(121)
+
+/*
+ *  ãªãã·ã§ã³ã®çµäº
+ */
+#define DHCP4_OPT_END		UINT_C(255)
+
+/*
+ *  magic çªå·ï¼RFC1048ï¼
+ */
+
+#define DHCP4_RFC1048_MAGIC	{ UINT_C(99), UINT_C(130), UINT_C(83), UINT_C(99), }
+#define DHCP4_MAGIC_LEN		4
+
+/*
+ *  UDP ãã¼ãçªå·
+ */
+
+#ifndef DHCP4_SRV_CFG_PORTNO
+#define DHCP4_SRV_CFG_PORTNO	67	/* server	*/
+#endif
+
+#ifndef DHCP4_CLI_CFG_PORTNO
+#define DHCP4_CLI_CFG_PORTNO	68	/* client	*/
+#endif
+
+#endif	/* of #ifndef DHCP4_H */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4_cli.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4_cli.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4_cli.c	(revision 331)
@@ -0,0 +1,2131 @@
+/*
+ * Copyright 2004 Henning Brauer <henning@openbsd.org>
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999
+ * The Internet Software Consortium.    All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ *    of its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ *
+ * This client was substantially modified and enhanced by Elliot Poger
+ * for use on Linux while he was working on the MosquitoNet project at
+ * Stanford.
+ *
+ * The current version owes much to Elliot's Linux enhancements, but
+ * was substantially reorganized and partially rewritten by Ted Lemon
+ * so as to use the same networking framework that the Internet Software
+ * Consortium DHCP server uses.   Much system-specific configuration code
+ * was moved into a shell script so that as support for more operating
+ * systems is added, it will not be necessary to port and maintain
+ * system-specific configuration code to these operating systems - instead,
+ * the shell script can invoke the native tools to accomplish the same
+ * purpose.
+ */
+/*
+ * WIDE Project DHCP Implementation
+ * Copyright (c) 1995-1997 Akihiro Tominaga
+ * Copyright (c) 1995-1997 WIDE Project
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided the following conditions
+ * are satisfied,
+ *
+ * 1. Both the copyright notice and this permission notice appear in
+ *    all copies of the software, derivative works or modified versions,
+ *    and any portions thereof, and that both notices appear in
+ *    supporting documentation.
+ * 2. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by WIDE Project and
+ *      its contributors.
+ * 3. Neither the name of WIDE Project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND WIDE
+ * PROJECT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ALSO, THERE
+ * IS NO WARRANTY IMPLIED OR OTHERWISE, NOR IS SUPPORT PROVIDED.
+ *
+ * Feedback of the results generated from any improvements or
+ * extensions made to this software would be much appreciated.
+ * Any such feedback should be sent to:
+ * 
+ *  Akihiro Tominaga
+ *  WIDE Project
+ *  Keio University, Endo 5322, Kanagawa, Japan
+ *  (E-mail: dhcp-dist@wide.ad.jp)
+ *
+ * WIDE project has the rights to redistribute these changes.
+ */
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2011 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+ *      ã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+ *        å ±åãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
+#include <net/net_timer.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_itron.h>
+#include <netinet/if_ether.h>
+
+#include <net/if_var.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/dhcp4_cli.h>
+#include <netapp/dhcp4_cli_var.h>
+#include <netapp/resolver.h>
+#include "lcd.h"
+
+/*
+ *  DHCP ã¯ã©ã¤ã¢ã³ãã¿ã¹ã¯
+ */
+
+#ifdef DHCP4_CLI_CFG
+
+/*
+ *  å¤æ°
+ */
+
+static T_DHCP4_CLI_CONTEXT	context;			/* ã¯ã©ã¤ã¢ã³ãã³ã³ãã­ã¹ã	*/
+static uint8_t	magicno[DHCP4_MAGIC_LEN] = DHCP4_RFC1048_MAGIC;	/* magic çªå·ï¼RFC1048ï¼*/
+
+/* å¿
+é ãªãã·ã§ã³ãªã¹ã */
+#ifdef DHCP4_CLI_CFG_REQUIRED_OLIST
+static uint8_t	required_plist[] = DHCP4_CLI_CFG_REQUIRED_OLIST;
+#endif
+
+/* è¦æ±ãªãã·ã§ã³ãªã¹ã */
+#ifdef DHCP4_CLI_CFG_REQUEST_OLIST
+static uint8_t	request_plist[] = DHCP4_CLI_CFG_REQUEST_OLIST;
+#endif
+
+/*
+ *  dhcp4_cksum -- ãã§ãã¯ãµã ã®è¨ç®é¢æ°
+ */
+
+static uint32_t
+dhcp4_cksum (void *data, uint_t len /*ãªã¯ãããåä½*/)
+{
+	uint32_t carry, sum = 0;
+
+	for ( ; len > 0; len -= 2) {
+		sum += (*(uint8_t*)data << 8) + *((uint8_t*)data + 1);
+		data = (uint8_t*)data + 2;
+		}
+
+	while (sum >= 0x00010000) {
+		carry = sum >> 16;
+		sum   = (sum & 0xffff) + carry;
+		}
+
+	return sum;
+	}
+
+/*
+ *  create_xid -- ãã©ã³ã¶ã¯ã·ã§ã³ ID ãçæããã
+ */
+
+static uint32_t
+create_xid (void)
+{
+	T_IF_SOFTC	*ic;
+	SYSTIM		time;
+
+	ic = IF_ETHER_NIC_GET_SOFTC();
+	get_tim(&time);
+	return (dhcp4_cksum((void*)&ic->ifaddr.lladdr, ETHER_ADDR_LEN) << 16)
+	      + dhcp4_cksum((void*)&time, sizeof(time));
+	}
+
+/*
+ *  find_option_sub -- æå®ãããªãã·ã§ã³ãæ¢ç´¢ããã
+ *
+ *    æ³¨æ: å¼æ° size ã 0 ã®æã¯ãªãã·ã§ã³ãµã¤ãºãæ¤è¨¼ããªãã
+ */
+
+static uint8_t *
+find_option_sub (T_DHCP4_CLI_MSG *msg, uint_t off, uint_t len, 
+                                      uint_t tag, uint_t size, bool_t overload)
+{
+	uint8_t	*opt, *tmp;
+
+	opt = (uint8_t*)&msg->msg + off;
+	while (opt < (uint8_t*)&msg->msg + off + len && *opt != DHCP4_OPT_END) {
+		if (*opt == DHCP4_OPT_PAD)
+			opt ++;
+		else if ((*opt == DHCP4_OPT_OPT_OVERLOAD) && overload) {
+			if (*(opt + 2) & DHCP4_OPTOL_FILE) {
+				tmp = find_option_sub(msg, DHCP4_FILE_OFFSET, DHCP4_FILE_LEN, tag, len, false);
+				if (tmp != NULL)
+					return tmp;
+				}
+			if (*(opt + 2) & DHCP4_OPTOL_SNAME) {
+				tmp = find_option_sub(msg, DHCP4_SNAME_OFFSET, DHCP4_SNAME_LEN, tag, len, false);
+				if (tmp != NULL)
+					return tmp;
+				}
+			opt += *(opt + 1) + 2;
+			}
+		else if (*opt == tag && (size == 0 || *(opt + 1) == size))
+			return opt;
+		else
+			opt += *(opt + 1) + 2;
+		}
+	return NULL;
+	}
+
+/*
+ *  find_option -- æå®ãããªãã·ã§ã³ãæ¢ç´¢ããã
+ *
+ *    æ³¨æ: å¼æ° size ã 0 ã®æã¯ãªãã·ã§ã³ãµã¤ãºãæ¤è¨¼ããªãã
+ */
+
+static uint8_t *
+find_option (T_DHCP4_CLI_MSG *msg, uint_t tag, uint_t size)
+{
+	return find_option_sub(msg, DHCP4_OPTION_OFFSET + DHCP4_MAGIC_LEN,
+	                       msg->len - (DHCP4_OPTION_OFFSET + DHCP4_MAGIC_LEN),
+	                       tag, size, true);
+	}
+
+/*
+ *  is_equal_sid -- ã¡ãã»ã¼ã¸å
+ã® SERVER ID ãæ¯è¼ããã
+ */
+
+static bool_t
+is_equal_sid (T_DHCP4_CLI_MSG *msg1, T_DHCP4_CLI_MSG *msg2)
+{
+	uint8_t	*opt1, *opt2;
+
+	if ((opt1 = find_option(msg1, DHCP4_OPT_SERVER_ID, sizeof(T_IN4_ADDR))) == NULL)
+		return false;
+	if ((opt2 = find_option(msg2, DHCP4_OPT_SERVER_ID, sizeof(T_IN4_ADDR))) == NULL)
+		return false;
+
+	return msg2host32(opt1) == msg2host32(opt2);
+	}
+
+/*
+ *  timer_value -- ã¡ãã»ã¼ã¸ããæéæ
+å ±ãåãåºãã
+ */
+
+static uint32_t
+timer_value (T_DHCP4_CLI_MSG *msg, uint_t tag, uint32_t def_value)
+{
+	uint8_t 	*opt;
+	uint32_t	seconds;
+
+	if ((opt = find_option(msg, tag, sizeof(uint32_t))) == NULL)
+		return def_value;
+	else {
+
+		/* ãµã¼ãããã®ãªã¼ã¹æéã¯[s]ã*/
+		seconds = msg2host32(opt + 2);
+
+		/* ã³ã³ãã­ã¹ãå
+ã®ãªã¼ã¹æéã¯ SYSTIM_HZã*/
+		if (seconds == DHCP4_TIME_INFINITY)
+			return DHCP4_TIME_INFINITY;
+		else if (seconds > SYSTIM2SEC(DHCP4_TIME_INFINITY))
+			return DHCP4_TIME_INFINITY;
+		else
+			return SEC2SYSTIM(seconds);
+		}
+	}
+
+/*
+ *  rel_addr -- IPv4 ã¢ãã¬ã¹ããµãããããã¹ã¯ãéççµè·¯è¡¨ãè§£æ¾ããã
+ */
+
+static void
+rel_addr (void)
+{
+	ER	error;
+	uint_t	count = 0;
+
+	if ((error = in4_add_ifaddr(IPV4_ADDRANY, IPV4_ADDRANY)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, IPv4 addr: %s", itron_strerror(error));
+		count ++;
+		}
+
+	if ((error = in4_add_route(0, IPV4_ADDRANY, IPV4_ADDRANY, IPV4_ADDRANY)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, release routing table: %s", itron_strerror(error));
+		count ++;
+		}
+
+	if ((error = in4_add_route(1, IPV4_ADDRANY, IPV4_ADDRANY, IPV4_ADDRANY)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, release routing table: %s", itron_strerror(error));
+		count ++;
+		}
+
+	if ((error = in4_add_route(2, 0xffffffff, 0xffffffff, IPV4_ADDRANY)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, release routing table: %s", itron_strerror(error));
+		count ++;
+		}
+
+	if (count == 0) {
+		syslog(LOG_NOTICE, "[DHCP4C] release IPv4 addr.");
+
+#if 0
+#ifdef USE_LCD
+		dly_tsk(1 * 1000);
+		lcd_puts(LCD_PORTID, "0.0.0.0\n");
+#endif	/* of #ifdef USE_LCD */
+#endif
+
+		}
+	}
+
+/*
+ *  rel_options -- ãªã¼ã¹ããããªãã·ã§ã³ãè§£æãã¦å¤ãè§£æ¾ããã
+ */
+
+static void
+rel_options (T_DHCP4_CLI_CONTEXT *ct, uint_t off, uint_t len, bool_t overload)
+{
+#if defined(USE_RESOLVER)
+	T_IN4_ADDR	addr;
+#endif
+
+	uint8_t	*opt;
+
+	opt = (uint8_t*)&ct->act_msg->msg + off;
+	while (opt < (uint8_t*)&ct->act_msg->msg + off + len && *opt != DHCP4_OPT_END) {
+		if (*opt == DHCP4_OPT_PAD)
+			opt ++;
+		else if ((*opt == DHCP4_OPT_OPT_OVERLOAD) && overload) {
+			if (*(opt + 2) & DHCP4_OPTOL_FILE)
+				rel_options(ct, DHCP4_FILE_OFFSET, DHCP4_FILE_LEN, false);
+			if (*(opt + 2) & DHCP4_OPTOL_SNAME)
+				rel_options(ct, DHCP4_SNAME_OFFSET, DHCP4_SNAME_LEN, false);
+			opt += *(opt + 1) + 2;
+			}
+		else {
+
+			switch (*opt) {
+
+#if defined(USE_RESOLVER)
+
+			case DHCP4_OPT_DNS_SERVER:
+				addr = IPV4_ADDRANY;
+				dns_in4_set_addr(&addr);
+				break;
+
+			case DHCP4_OPT_HOST_NAME:
+				break;
+
+			case DHCP4_OPT_DOMAIN_NAME:
+				dns_in4_set_dname("", 0);
+				break;
+
+#else	/* of #if defined(USE_RESOLVER) */
+
+			case DHCP4_OPT_DNS_SERVER:
+			case DHCP4_OPT_HOST_NAME:
+			case DHCP4_OPT_DOMAIN_NAME:
+
+#endif	/* of #if defined(USE_RESOLVER) */
+
+			case DHCP4_OPT_SUBNET_MASK:
+			case DHCP4_OPT_ROUTER:
+			case DHCP4_OPT_LEASE_TIME:
+			case DHCP4_OPT_RENEWAL_T1:
+			case DHCP4_OPT_REBINDING_T2:
+				break;
+
+			default:
+				break;
+				}
+
+			opt += *(opt + 1) + 2;
+			}
+		}
+	}
+
+/*
+ *  rel_lease -- ãªã¼ã¹ãããæ
+å ±ãè§£æ¾ããã
+ */
+
+static void
+rel_lease (T_DHCP4_CLI_CONTEXT *ct)
+{
+	/* æå¹ãªãªã¼ã¹ã»ã¡ãã»ã¼ã¸æ§é ä½ãç¡ããã°ä½ãããªãã*/
+	if (ct->act_msg == NULL)
+		return;
+
+	/* ãªã¼ã¹ããããªãã·ã§ã³ãè§£æãã¦å¤ãè§£æ¾ããã*/
+	rel_options(ct, DHCP4_OPTION_OFFSET + DHCP4_MAGIC_LEN,
+	              ct->act_msg->len - (DHCP4_OPTION_OFFSET + DHCP4_MAGIC_LEN), true);
+	rel_addr();
+
+	/* æå¹ãªãªã¼ã¹ã»ã¡ãã»ã¼ã¸æ§é ä½ãè§£æ¾ããã*/
+	syscall(rel_mpf(MPF_DHCP4_CLI_MSG, (void*)ct->act_msg));
+	ct->act_msg = NULL;
+	}
+
+/*
+ *  set_addr -- IPv4 ã¢ãã¬ã¹ããµãããããã¹ã¯ãéççµè·¯è¡¨ãè¨­å®ããã
+ */
+
+static void
+set_addr (T_DHCP4_CLI_CONTEXT *ct, uint8_t *mopt, uint8_t *ropt)
+{
+	ER		error;
+	T_IN4_ADDR	addr, mask, router, net_addr;
+
+	addr     = ntohl(ct->act_msg->msg.yiaddr);
+	mask     = msg2host32(mopt + 2);
+	net_addr = addr & mask;
+	router   = msg2host32(ropt + 2);
+	
+	if ((error = in4_add_ifaddr(addr, mask)) != E_OK)
+		syslog(LOG_NOTICE, "[DHCP4C] error, set IPv4 addr: %s", itron_strerror(error));
+
+	if ((error = in4_add_route(0, IPV4_ADDRANY, IPV4_ADDRANY, router)) != E_OK)
+		syslog(LOG_NOTICE, "[DHCP4C] error, set routing table: %s", itron_strerror(error));
+
+	if ((error = in4_add_route(1, net_addr, mask, IPV4_ADDRANY)) != E_OK)
+		syslog(LOG_NOTICE, "[DHCP4C] error, set routing table: %s", itron_strerror(error));
+
+	if ((error = in4_add_route(2, 0xffffffff, 0xffffffff, IPV4_ADDRANY)) != E_OK)
+		syslog(LOG_NOTICE, "[DHCP4C] error, set routing table: %s", itron_strerror(error));
+
+	if (error == E_OK) {
+		syslog(LOG_NOTICE, "[DHCP4C] set IPv4 addr: %s.", ip2str(NULL, &addr));
+
+#ifdef USE_LCD
+		dly_tsk(1 * 1000);
+		lcd_puts(LCD_PORTID, ip2str(NULL, &addr));
+		lcd_putc(LCD_PORTID, '\n');
+#endif	/* of #ifdef USE_LCD */
+	if (ct->set_addr_callback != NULL)
+		ct->set_addr_callback();
+
+		}
+	}
+
+/*
+ *  set_options -- ãªã¼ã¹ããããªãã·ã§ã³ãè§£æãã¦å¤ãè¨­å®ããã
+ */
+
+static void
+set_options (T_DHCP4_CLI_CONTEXT *ct, uint_t off, uint_t len, bool_t overload)
+{
+#if defined(USE_RESOLVER)
+	T_IN4_ADDR	addr;
+#endif
+
+	uint8_t	*opt, *mopt = NULL, *ropt = NULL;
+
+	opt = (uint8_t*)&ct->act_msg->msg + off;
+	while (opt < (uint8_t*)&ct->act_msg->msg + off + len && *opt != DHCP4_OPT_END) {
+		if (*opt == DHCP4_OPT_PAD)
+			opt ++;
+		else if ((*opt == DHCP4_OPT_OPT_OVERLOAD) && overload) {
+			if (*(opt + 2) & DHCP4_OPTOL_FILE)
+				set_options(ct, DHCP4_FILE_OFFSET, DHCP4_FILE_LEN, false);
+			if (*(opt + 2) & DHCP4_OPTOL_SNAME)
+				set_options(ct, DHCP4_SNAME_OFFSET, DHCP4_SNAME_LEN, false);
+			opt += *(opt + 1) + 2;
+			}
+		else {
+
+			switch (*opt) {
+			case DHCP4_OPT_SUBNET_MASK:
+				mopt = opt;
+				break;
+
+			case DHCP4_OPT_ROUTER:
+				ropt = opt;
+				break;
+
+#if defined(USE_RESOLVER)
+
+			case DHCP4_OPT_DNS_SERVER:
+				addr = msg2host32(opt + 2);
+				dns_in4_set_addr(&addr);
+				break;
+
+			case DHCP4_OPT_HOST_NAME:
+				break;
+
+			case DHCP4_OPT_DOMAIN_NAME:
+				dns_in4_set_dname(opt + 2, *(opt + 1));
+				break;
+
+#else	/* of #if defined(USE_RESOLVER) */
+
+			case DHCP4_OPT_DNS_SERVER:
+			case DHCP4_OPT_HOST_NAME:
+			case DHCP4_OPT_DOMAIN_NAME:
+
+#endif	/* of #if defined(USE_RESOLVER) */
+
+			case DHCP4_OPT_LEASE_TIME:
+			case DHCP4_OPT_RENEWAL_T1:
+			case DHCP4_OPT_REBINDING_T2:
+				break;
+
+			default:
+				break;
+				}
+
+			opt += *(opt + 1) + 2;
+			}
+		}
+	if (!(mopt == NULL || ropt == NULL))
+		set_addr(ct, mopt, ropt);
+	}
+
+/*
+ *  set_lease -- ãªã¼ã¹ãããæ
+å ±ãè¨­å®ããã
+ */
+
+static void
+set_lease (T_DHCP4_CLI_CONTEXT *ct)
+{
+	/* ãªã¼ã¹ããããªãã·ã§ã³ãè§£æãã¦å¤ãè¨­å®ããã*/
+	set_options(ct, DHCP4_OPTION_OFFSET + DHCP4_MAGIC_LEN,
+	              ct->act_msg->len - (DHCP4_OPTION_OFFSET + DHCP4_MAGIC_LEN), true);
+	}
+
+/*
+ *  validate_duplicate -- æå®ããã IPv4 ã¢ãã¬ã¹ãä½¿ããã¦ããªããæ¤è¨¼ããã
+ *
+ *    ä½¿ããã¦ããªãæã¯ true ãè¿ãã
+ */
+
+static bool_t
+validate_duplicate (T_DHCP4_CLI_MSG *msg)
+{
+	T_IN4_ADDR	yiaddr;
+
+	/* æå®ããã IPv4 ã¢ãã¬ã¹ã ADDR ANY ãªãä½¿ããã¦ããªãã¨å¤æ­ããã*/
+	yiaddr = ntohl(msg->msg.yiaddr);
+	if (yiaddr == IPV4_ADDRANY)
+		return true;
+
+	/* ARP ã­ã£ãã·ã¥ã«ããã°ä½¿ããã¦ããã¨å¤æ­ããã*/
+	if (arp_lookup(yiaddr, false) != NULL)
+		return false;
+
+	/*
+	 *  ARP è¦æ±ãåºåãã¦ TMO_DHCP4C_ARP_WAIT å¾
+ã¡ã
+	 *  ARP ã­ã£ãã·ã¥ã«ãªããã°ä½¿ããã¦ããªãã¨å¤æ­ããã
+	 */
+	arp_request(&IF_ETHER_NIC_GET_SOFTC()->ifaddr, yiaddr);
+	dly_tsk(TMO_DHCP4C_ARP_WAIT);
+	return arp_lookup(yiaddr, false) == NULL;
+	}
+
+/*
+ *  validate_rcv_msg -- åä¿¡ã¡ãã»ã¼ã¸ãæ¤è¨¼ããã
+ */
+
+static ER
+validate_rcv_msg (T_DHCP4_CLI_CONTEXT *ct, T_DHCP4_CLI_MSG *msg)
+{
+	uint8_t 	*opt;
+
+	/* packet type ã DHCP4_REPLY ã§ãããã¨ãç¢ºèªããã*/
+	if (!(msg->msg.op == DHCP4_REPLY))
+		return false;
+
+	/* ã¡ãã»ã¼ã¸ã¿ã¤ããªãã·ã§ã³ããããã¨ãç¢ºèªããã*/
+	if ((opt = find_option(msg, DHCP4_OPT_MSG_TYPE, 1)) == NULL)
+		return E_PAR;
+
+	/* ã¡ãã»ã¼ã¸ã®ã¿ã¤ããä¸è´ãã¦ãããã¨ãæ¤è¨¼ããã*/
+	msg->type = *(opt + 2);
+	switch (ct->fsm) {
+
+	case DHCP4_FSM_SELECT:
+		if (!(msg->type == DHCP4_MTYPE_OFFER))
+			return E_PAR;
+		break;
+
+	case DHCP4_FSM_REQUEST:
+	case DHCP4_FSM_REBOOT:
+	case DHCP4_FSM_RENEW:
+	case DHCP4_FSM_REBIND:
+	case DHCP4_FSM_REL_INFO:
+		if (!((msg->type == DHCP4_MTYPE_ACK) || (msg->type == DHCP4_MTYPE_NAK)))
+			return E_PAR;
+		break;
+
+	case DHCP4_FSM_INIT:
+	case DHCP4_FSM_BOUND:
+	case DHCP4_FSM_INIT_REBOOT:
+		return E_PAR;
+		break;
+
+	default:
+		syslog(LOG_NOTICE, "[DHCP4C] error, unknown state: %d.", ct->fsm);
+		return E_PAR;
+		break;
+		}
+
+	/* ãã¸ãã¯çªå·ãæ¤è¨¼ããã*/
+	if (memcmp((uint8_t*)&msg->msg.options, magicno, DHCP4_MAGIC_LEN))
+		return E_PAR;
+
+	/* ãã©ã³ã¶ã¯ã·ã§ã³ ID ãç°ãªã£ã¦ããã°ã¨ã©ã¼ */
+	if (ntohl(msg->msg.xid) != ct->xid)
+		return E_PAR;
+
+	/* ãã¼ãã¦ã§ã¢ã¢ãã¬ã¹é·ã 6ï¼MAC ã¢ãã¬ã¹é·ï¼ã§ãªããã°ã¨ã©ã¼ */
+	if (msg->msg.hlen != ETHER_ADDR_LEN)
+		return E_PAR;
+
+	/* ãã¼ãã¦ã§ã¢ã¢ãã¬ã¹ãç°ãªã£ã¦ããã°ã¨ã©ã¼ */
+	if (memcmp(&msg->msg.chaddr, &ct->sc->ifaddr.lladdr, sizeof(ct->sc->ifaddr.lladdr)))
+		return E_PAR;
+
+	/*
+	 *  ã¡ãã»ã¼ã¸ã¿ã¤ãã OFFER ã®å ´åã¯ã
+	 *  ARP ãä½¿ç¨ãã¦ãæå®ããã IPv4 ã¢ãã¬ã¹ãä½¿ããã¦ããªããæ¤è¨¼ããã
+	 *  ä½¿ããã¦ããæã¯ãä»ã® IPv4 ã¢ãã¬ã¹ã®æä¾ãå¾
+ã¤ã
+	 */
+	if (msg->type == DHCP4_MTYPE_OFFER) {
+		if (!validate_duplicate(msg))
+			return E_PAR;
+		}
+
+	return E_OK;
+	}
+
+/*
+ *  eval_prefer -- åä¿¡ã¡ãã»ã¼ã¸ã®æ¨å¥¨åº¦ãè©ä¾¡ããã
+ */
+
+static void
+eval_prefer (T_DHCP4_CLI_MSG *msg)
+{
+	int	ix;
+
+	/* ç¡å¹ã®å ´åã¯çµäºããã*/
+	if (msg == NULL)
+		return;
+
+	/* æå®ããã IPv4 ã¢ãã¬ã¹ã ADDR ANY ãªãæ¨å¥¨åº¦ã 0ã«è¨­å®ããã*/
+	if (ntohl(msg->msg.yiaddr) == IPV4_ADDRANY)
+		msg->prefer = 0;
+	else
+		msg->prefer = DHCP4_CLI_CFG_PREFER_ADDR;
+
+#if defined(DHCP4_CLI_CFG_REQUEST_OLIST)
+
+	/* è¦æ±ãªãã·ã§ã³ãæ¤è¨¼ããã*/
+	for (ix = sizeof(request_plist); ix -- > 0; ) {
+		if (find_option(msg, request_plist[ix], 0) != NULL)
+			msg->prefer ++;
+		}
+
+#endif	/* of #if defined(DHCP4_CLI_CFG_REQUEST_OLIST) */
+
+#if defined(DHCP4_CLI_CFG_REQUIRED_OLIST)
+
+	/* å¿
+é ãªãã·ã§ã³ãæ¤è¨¼ããã*/
+	for (ix = sizeof(required_plist); ix -- > 0; ) {
+		if (find_option(msg, required_plist[ix], 0) == NULL)
+			msg->prefer = 0;
+		}
+
+#endif	/* of #if defined(DHCP4_CLI_CFG_REQUIRED_OLIST) */
+	}
+
+/*
+ *  eval_rcv_msg -- åä¿¡ã¡ãã»ã¼ã¸ãè©ä¾¡ããã
+ */
+
+static ER
+eval_rcv_msg (T_DHCP4_CLI_CONTEXT *ct)
+{
+	T_DHCP4_CLI_MSG	*evl, *msg;
+
+	/* ã¡ãã»ã¼ã¸ãåä¿¡ãã¦ããªããã°ä¸­æ­¢ããã*/
+	syscall(wai_sem(SEM_DHCP4_CLI_LOCK));
+	if (ct->val_lst == NULL) {
+		syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+		return E_OK;
+		}
+
+	/* æ¤è¨¼ã¡ãã»ã¼ã¸ãªã¹ãããè©ä¾¡ã¡ãã»ã¼ã¸ãåãåºãã*/
+	evl         = ct->val_lst;
+	ct->val_lst = ct->val_lst->next;
+	evl->next   = NULL;
+	syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+
+	/* è©ä¾¡ã¡ãã»ã¼ã¸ãæ¤è¨¼ããã*/
+	if (validate_rcv_msg(ct, evl) != E_OK) {
+
+		/* ã¨ã©ã¼ãçºçããè©ä¾¡ã¡ãã»ã¼ã¸ãåä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ãã«æ»ãã*/
+		goto rcv_ret;
+		}
+
+	/* åä¿¡ããã¡ãã»ã¼ã¸ã NAK ã®æã®å¦ç */
+	if (evl->type == DHCP4_MTYPE_NAK) {
+
+		/* ãªã¼ã¹ãããæ
+å ±ãè§£æ¾ããã*/
+		rel_lease(ct);
+
+		/* å
+é¨ã¨ã©ã¼ãè¨­å®ãã¦çµäºããã*/
+		return E_PAR;
+		}
+
+	/* REL_INFO ç¶æ
+ã®æã®å¦ç */
+	//cons_printf(CONSOLE_PORTID, "evl_rcv_msg3[s=%d]\n", ct->fsm);
+	if (ct->fsm == DHCP4_FSM_REL_INFO) {
+		syscall(wai_sem(SEM_DHCP4_CLI_LOCK));
+		evl->next   = ct->prf_lst;
+		ct->prf_lst = evl;
+		syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+		return E_OK;
+		}
+
+	/* è©ä¾¡ã¡ãã»ã¼ã¸ã®æ¨å¥¨åº¦ãè©ä¾¡ããã*/
+	eval_prefer(evl);
+
+	/* æ¨å¥¨ã¡ãã»ã¼ã¸ãªã¹ããç©ºãªãè©ä¾¡ã¡ãã»ã¼ã¸ãç§»ãã¦çµäºããã*/
+	if (ct->prf_lst == NULL) {
+		ct->max_prefer = evl->prefer;
+		ct->prf_lst = evl;
+		return E_OK;
+		}
+
+	/* è©ä¾¡ã¡ãã»ã¼ã¸ã®æ¨å¥¨åº¦ã¨æ¨å¥¨ã¡ãã»ã¼ã¸ãªã¹ãã®æå¤§æ¨å¥¨åº¦ãæ¯è¼ããã*/
+	if (evl->prefer > ct->max_prefer) {
+
+		/* 
+		 *  è©ä¾¡ã¡ãã»ã¼ã¸ã®æ¨å¥¨åº¦ãæ¨å¥¨ã¡ãã»ã¼ã¸ãªã¹ãã®æå¤§æ¨å¥¨åº¦ããé«ããã°ã
+		 *  æ¨å¥¨ã¡ãã»ã¼ã¸ãªã¹ããåä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ãã«æ»ãã
+		 *  è©ä¾¡ã¡ãã»ã¼ã¸ãæ¨å¥¨ã¡ãã»ã¼ã¸ãªã¹ãã«ç§»ãã
+		 */
+		ct->max_prefer = evl->prefer;
+		syscall(wai_sem(SEM_DHCP4_CLI_LOCK));
+		if (ct->rcv_lst == NULL)
+			ct->rcv_lst = ct->prf_lst;
+		else {
+			for (msg = ct->rcv_lst; msg->next != NULL; msg = msg->next)
+				;
+			msg->next = ct->prf_lst;
+			}
+		syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+		ct->prf_lst = evl;
+		return E_OK;
+		}
+
+	else if (evl->prefer == ct->max_prefer) {
+		for (msg = ct->prf_lst; msg != NULL; msg = msg->next) {
+			if (is_equal_sid(evl, msg)) {
+
+				/*
+				 *  æ¨å¥¨ã¡ãã»ã¼ã¸ãªã¹ãã«åã DHCP4_OPT_SERVER_ID ã®ã¡ãã»ã¼ã¸ãããã°ã
+				 *  è©ä¾¡ã¡ãã»ã¼ã¸ãåä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ãã«æ»ãã
+				 */
+				goto rcv_ret;
+				}
+			}
+
+		/* 
+		 *  è©ä¾¡ã¡ãã»ã¼ã¸ãæ¨å¥¨ã¡ãã»ã¼ã¸ãªã¹ãã«ç§»ãã
+		 */
+		evl->next   = ct->prf_lst;
+		ct->prf_lst = evl;
+		return E_OK;
+		}
+	
+	/*else */
+		/* 
+		 *  è©ä¾¡ã¡ãã»ã¼ã¸ã®æ¨å¥¨åº¦ãæ¨å¥¨ã¡ãã»ã¼ã¸ãªã¹ãã®æå¤§æ¨å¥¨åº¦ããä½ããã°ã
+		 *  è©ä¾¡ã¡ãã»ã¼ã¸ãåä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ãã«æ»ãã
+		 */
+
+rcv_ret:
+	syscall(wai_sem(SEM_DHCP4_CLI_LOCK));
+	evl->next   = ct->rcv_lst;
+	ct->rcv_lst = evl;
+	syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+	return E_OK;
+	}
+
+/*
+ *  select_msg -- æ¨å¥¨ã¡ãã»ã¼ã¸ãé¸æããã
+ */
+
+static T_DHCP4_CLI_MSG*
+select_msg (T_DHCP4_CLI_CONTEXT *ct)
+{
+	T_DHCP4_CLI_MSG		*msg, *select;
+
+	syscall(wai_sem(SEM_DHCP4_CLI_LOCK));
+	if (ct->prf_lst == NULL) {
+		/* ã¡ãã»ã¼ã¸ãåä¿¡ãã¦ããªããã°ä¸­æ­¢ããã*/
+		syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+		return NULL;
+		}
+
+	/* æ¨å¥¨ã¡ãã»ã¼ã¸ãªã¹ãã®å
+é ­ã®ã¡ãã»ã¼ã¸ãé¸æããã*/
+	select = ct->prf_lst;
+	ct->prf_lst  = ct->prf_lst->next;
+	select->next = NULL;
+
+	/* é¸æãããªãã£ãæ¤è¨¼ã¡ãã»ã¼ã¸ãåä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ãã«æ»ãã*/
+	if (ct->rcv_lst == NULL)
+		ct->rcv_lst = ct->prf_lst;
+	else {
+		for (msg = ct->rcv_lst; msg->next != NULL; msg = msg->next)
+			;
+		msg->next = ct->prf_lst;
+		}
+	syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+	return select;
+	}
+
+/*
+ *  select_ack -- ACK ã¡ãã»ã¼ã¸ãæ¤è¨¼ããã
+ *
+ *    åãå
+¥ãããã¨ãå¯è½ã®æã¯ true ãè¿ãã
+ */
+
+static bool_t
+select_ack (T_DHCP4_CLI_CONTEXT *ct)
+{
+	T_DHCP4_CLI_MSG	*msg;
+
+	if ((msg = select_msg(ct)) == NULL)
+		return false;
+
+	/* æå¹ãªãªã¼ã¹ã»ã¡ãã»ã¼ã¸ãæ®ã£ã¦ããã°ãåä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ãã«æ»ãã*/
+	if (ct->act_msg != NULL) {
+		syscall(wai_sem(SEM_DHCP4_CLI_LOCK));
+		ct->act_msg->next = ct->rcv_lst;
+		ct->rcv_lst = ct->act_msg;
+		syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+		}
+
+	/* æå¹ãªãªã¼ã¹ã»ã¡ãã»ã¼ã¸ã«è¨­å®ããã*/
+	ct->act_msg = msg;
+	return true;
+	}
+
+/*
+ *  select_offer -- OFFER ã¡ãã»ã¼ã¸ãæ¤è¨¼ããã
+ *
+ *    åãå
+¥ãããã¨ãå¯è½ã®æã¯ true ãè¿ãã
+ */
+
+static bool_t
+select_offer (T_DHCP4_CLI_CONTEXT *ct)
+{
+	return (ct->off_msg = select_msg(ct)) != NULL;
+	}
+
+/*
+ *  cancel_all_timers -- å
+¨ã¦ã® TIMER ãã­ã£ã³ã»ã«ããã
+ */
+
+static void
+cancel_all_timers (T_DHCP4_CLI_CONTEXT *ct)
+{
+	int ix;
+
+	syscall(wai_sem(SEM_DHCP4_CLI_TIMER));
+	for (ix = NUM_DHCP4C_TIMERS; ix -- > 0; )
+		ct->timers[ix] = 0;
+	syscall(sig_sem(SEM_DHCP4_CLI_TIMER));
+	}
+
+
+/*
+ *  start_select -- DISCOVER ã¡ãã»ã¼ã¸ãéä¿¡ãã¦ SELECT ç¶æ
+ã«é·ç§»ããã
+ */
+
+static void
+start_select (T_DHCP4_CLI_CONTEXT *ct)
+{
+	/* éä¿¡ãéå§ããæéãè¨é²ããã*/
+	get_tim(&ct->snd_start);
+
+	/* OFFER ã¡ãã»ã¼ã¸åä¿¡ã¿ã¤ã ã¢ã¦ããè¨­å®ããã*/
+	syscall(wai_sem(SEM_DHCP4_CLI_TIMER));
+	ct->timers[DHCP4C_TIMER_RCV_OFFER] = SYSTIM2TIMER(TMO_DHCP4C_OFFER);
+	syscall(sig_sem(SEM_DHCP4_CLI_TIMER));
+
+	/* éä¿¡å
+ã¢ãã¬ã¹ã«ã­ã¼ã«ã«ãããã¯ã¼ã¯ã¸ã®ãã­ã¼ãã­ã£ã¹ããè¨­å®ããã*/
+	ct->dst.ipaddr = IPV4_ADDRBROADCAST;
+
+	/* éä¿¡ééããªã»ããããã*/
+	ct->interval = 0;
+
+	/* SELECT ç¶æ
+ã«é·ç§»ããã*/
+	ct->fsm = DHCP4_FSM_SELECT;
+
+	/* DISCOVER ã¡ãã»ã¼ã¸ãéä¿¡ããã*/
+	ct->flags |= DHCP4C_FLAG_TMOUT_SND_DISC;
+	syscall(sig_sem(SEM_DHCP4_CLI_READY));
+	}
+
+/*
+ *  start_bound -- BOUND ç¶æ
+ã«é·ç§»ããã
+ */
+
+static void
+start_bound (T_DHCP4_CLI_CONTEXT *ct)
+{
+	/* ãªã¼ã¹ãããæ
+å ±ãè¨­å®ããã*/
+	set_lease(ct);
+
+	/* ãªã¼ã¹ã®æå¹æéãè¨­å®ããã*/
+	ct->expire = timer_value(ct->act_msg, DHCP4_OPT_LEASE_TIME, TMO_DHCP4C_DEF_LEASE);
+
+	/* ãªã¼ã¹æéã TMO_DHCP4C_MIN_LEASE ä»¥ä¸ã®æã¯ãTMO_DHCP4C_MIN_LEASE ã«è¨­å®ããã*/
+	if (ct->expire < TMO_DHCP4C_MIN_LEASE)
+		ct->expire = TMO_DHCP4C_MIN_LEASE;
+
+	/* RENEW ç¶æ
+ã¾ã§ã®æéãè¨­å®ããã*/
+	ct->renew = timer_value(ct->act_msg, DHCP4_OPT_RENEWAL_T1, ct->expire / 2);
+
+	/* REBIND ç¶æ
+ã¾ã§ã®æéãè¨­å®ããã*/
+	ct->rebind = timer_value(ct->act_msg, DHCP4_OPT_REBINDING_T2, ct->renew + ct->renew / 2 + ct->renew / 4);
+
+	/* EXPIREãRENEWãREBIND ã¿ã¤ãã¼ãè¨­å®ããã*/
+	syscall(wai_sem(SEM_DHCP4_CLI_TIMER));
+	ct->timers[DHCP4C_TIMER_EXPIRE] = SYSTIM2TIMER(ct->expire);		/* EXPIRE      ã¾ã§ã®æé */
+	ct->timers[DHCP4C_TIMER_REBIND] = SYSTIM2TIMER(ct->rebind);		/* REBINDï¼T2ï¼ã¾ã§ã®æé */
+	ct->timers[DHCP4C_TIMER_RENEW]  = SYSTIM2TIMER(ct->renew);		/* RENEW ï¼T1ï¼ã¾ã§ã®æé */
+	syscall(sig_sem(SEM_DHCP4_CLI_TIMER));
+
+	/* BOUND ç¶æ
+ã«é·ç§»ããã*/
+	ct->fsm = DHCP4_FSM_BOUND;
+
+	/* BIND ãéå§ããæéãè¨é²ããã*/
+	get_tim(&ct->bind_start);
+	}
+
+/*
+ *  start_send_request -- REQUEST ã¡ãã»ã¼ã¸ãéä¿¡ãã¦ãæå®ãããç¶æ
+ã«é·ç§»ããã
+ */
+
+static void
+start_send_request (T_DHCP4_CLI_CONTEXT *ct, uint_t fsm)
+{
+	T_IFNET	*ifp = IF_GET_IFNET();
+
+	/* éä¿¡ãéå§ããæéãè¨é²ããã*/
+	get_tim(&ct->snd_start);
+
+	/* é·ç§»ããç¶æ
+ã RENEW ä»¥å¤ã§ã¯ ACK/NAK ã¡ãã»ã¼ã¸åä¿¡ã¿ã¤ã ã¢ã¦ããè¨­å®ããã*/
+	if (fsm != DHCP4_FSM_RENEW) { 
+		syscall(wai_sem(SEM_DHCP4_CLI_TIMER));
+		ct->timers[DHCP4C_TIMER_RCV_ACK] = SYSTIM2TIMER(TMO_DHCP4C_ACK);
+		syscall(sig_sem(SEM_DHCP4_CLI_TIMER));
+		}
+
+	/*
+	 *  é·ç§»ããç¶æ
+ã RENEW ã§ã
+	 *  SERVER ID ãªãã·ã§ã³ãããã°ã­ã¼ã«ã«ãããã¯ã¼ã¯ã¸ã®ãã­ã¼ãã­ã£ã¹ããéä¿¡ããã
+	 */
+	if ((fsm == DHCP4_FSM_RENEW) &&
+	    (find_option(ct->act_msg, DHCP4_OPT_SERVER_ID, sizeof(T_IN4_ADDR)) !=  NULL))
+		ct->dst.ipaddr = (ifp->in4_ifaddr.addr &  ifp->in4_ifaddr.mask) | ~ifp->in4_ifaddr.mask;
+	else
+		ct->dst.ipaddr = IPV4_ADDRBROADCAST;
+
+	/* éä¿¡ééããªã»ããããã*/
+	ct->interval = 0;
+
+	/* æå®ãããç¶æ
+ã«é·ç§»ããã*/
+	ct->fsm = fsm;
+
+	/* REQUEST ã¡ãã»ã¼ã¸ãéä¿¡ããã*/
+	ct->flags |= DHCP4C_FLAG_TMOUT_SND_REQ;
+	syscall(sig_sem(SEM_DHCP4_CLI_READY));
+	}
+
+/*
+ *  start_rel_info -- ã¢ãã¬ã¹æ
+å ±ãè§£æ¾ããã
+ *
+ *    æ³¨æ: DHCPv4 ã® RFC2131 ã«ã¯ç¡ã
+ */
+
+static void
+start_rel_info (T_DHCP4_CLI_CONTEXT *ct)
+{
+	/* å
+¨ã¦ã® TIMER ãã­ã£ã³ã»ã«ããã*/
+	cancel_all_timers(ct);
+
+	/* æå¹ãªãªã¼ã¹æ
+å ±ãç¡ããã° SLEEP ã«é·ç§»ããã*/
+	if (ct->act_msg == NULL) {
+		ct->fsm = DHCP4_FSM_SLEEP;
+		return;
+		}
+
+	/* éä¿¡å
+ã¢ãã¬ã¹ã«ã­ã¼ã«ã«ãããã¯ã¼ã¯ã¸ã®ãã­ã¼ãã­ã£ã¹ããè¨­å®ããã*/
+	ct->dst.ipaddr = IPV4_ADDRBROADCAST;
+
+	/* RELEASE ã¡ãã»ã¼ã¸ãéä¿¡ããã*/
+	ct->flags |= DHCP4C_FLAG_TMOUT_SND_REL;
+	syscall(sig_sem(SEM_DHCP4_CLI_READY));
+	}
+
+/*
+ *  setup_dhcp_com_msg -- DHCP ã¡ãã»ã¼ã¸ã®å
+±éé¨åãä½æããã
+ */
+
+static uint8_t *
+setup_dhcp_com_msg (T_DHCP4_CLI_CONTEXT *ct, uint_t op, uint_t type)
+{
+	uint8_t	*option;
+
+	memset((void*)&ct->snd_msg->msg, sizeof(ct->snd_msg->msg), 0);
+	ct->snd_msg->len = sizeof(ct->snd_msg->msg);
+
+	/* ãããé¨ãè¨­å®ããã*/
+	ct->snd_msg->msg.op = op;
+	ct->snd_msg->msg.htype = DHCP4_HWA_TYPE_ETHER;
+	ct->snd_msg->msg.hlen = ETHER_ADDR_LEN;
+	HOST2MSG32(ct->snd_msg->msg.xid, ct->xid);
+
+	/* MAC ã¢ãã¬ã¹ãè¨­å®ããã*/
+	memcpy(&ct->snd_msg->msg.chaddr, &ct->sc->ifaddr.lladdr, ETHER_ADDR_LEN);
+
+	/*
+	 *  ãªãã·ã§ã³é¨ãè¨­å®ããã
+	 */
+
+	/* RFC1048 ã«å®ç¾©ããã¦ãããã¸ãã¯çªå·ãè¨­å®ããã*/
+	memcpy(&ct->snd_msg->msg.options, magicno, DHCP4_MAGIC_LEN);
+	option = ct->snd_msg->msg.options + DHCP4_MAGIC_LEN;
+
+	/* DHCP ã¡ãã»ã¼ã¸ã¿ã¤ããè¨­å®ããã*/
+	*(option ++) = DHCP4_OPT_MSG_TYPE;
+	*(option ++) = 1;
+	*(option ++) = type;
+
+	return option;
+	}
+
+/*
+ *  setup_release_msg -- RELEASE ã¡ãã»ã¼ã¸ãä½æããã
+ */
+
+static ER
+setup_release_msg (T_DHCP4_CLI_CONTEXT *ct, T_DHCP4_CLI_MSG *ref)
+{
+	uint8_t *opt, *ref_opt;
+
+	/* æå¹ãªãªã¼ã¹ã»ã¡ãã»ã¼ã¸ããªããã°ã¨ã©ã¼ */
+	if (ref == NULL)
+		return E_PAR;
+
+	ct->xid = create_xid();
+	if ((opt = setup_dhcp_com_msg(ct, DHCP4_REQUEST, DHCP4_MTYPE_RELEASE)) == NULL)
+		return E_PAR;
+
+	/*
+	 *  ãµã¼ã IDï¼server-ipï¼ãè¨­å®ããã
+	 *  RFC2131 4.4.1 Initialization and allocation of network address åç
+§
+	 */
+	if ((ref_opt = find_option(ref, DHCP4_OPT_SERVER_ID, sizeof(T_IN4_ADDR))) == NULL)
+		return E_PAR;
+	*(opt ++) = *(ref_opt ++);
+	*(opt ++) = *(ref_opt ++);
+	memcpy(opt, ref_opt, *(ref_opt - 1));
+	opt += *(ref_opt - 1);
+
+	/* 
+	 *  ã¯ã©ã¤ã¢ã³ã IDï¼MAC ã¢ãã¬ã¹ï¼ãè¨­å®ããã
+	 *  RFC2131 4.4.1 Initialization and allocation of network address åç
+§
+	 */
+	*(opt ++) = DHCP4_OPT_CLIENT_ID;
+	*(opt ++) = ETHER_ADDR_LEN + 1;
+	*(opt ++) = DHCP4_HWA_TYPE_ETHER;
+	memcpy(opt, &ct->sc->ifaddr.lladdr, ETHER_ADDR_LEN);
+	opt += ETHER_ADDR_LEN;
+
+	/* ãªãã·ã§ã³ã®çµäºãè¨­å®ããã*/
+	*(opt ++) = DHCP4_OPT_END;
+
+	/*
+	 *  ã¯ã©ã¤ã¢ã³ã IP ã¢ãã¬ã¹ï¼ciaddrï¼ãè¨­å®ããã
+	 *  RFC2131 4.4.1 Initialization and allocation of network address åç
+§
+	 */
+	HOST2MSG32(ct->snd_msg->msg.ciaddr, IF_GET_IFNET()->in4_ifaddr.addr);
+
+	/* ã¡ãã»ã¼ã¸é·ãè¨­å®ããã*/
+	ct->snd_msg->len = sizeof(ct->snd_msg->msg) - DHCP4_DFLT_OPT_LEN
+	             + (opt - (uint8_t*)&ct->snd_msg->msg.options);
+	return E_OK;
+	}
+
+
+/*
+ *  setup_request_msg -- REQUEST ã¡ãã»ã¼ã¸ãä½æããã
+ */
+
+static ER
+setup_request_msg (T_DHCP4_CLI_CONTEXT *ct, T_DHCP4_CLI_MSG *ref)
+{
+	uint8_t *opt, *ref_opt;
+
+#if defined(DHCP4_CLI_CFG_REQUIRED_OLIST) || defined(DHCP4_CLI_CFG_REQUEST_OLIST)
+	uint_t	len = 0;
+#endif
+
+	/* åç
+§ããã¡ãã»ã¼ã¸ããªããã°ã¨ã©ã¼ */
+	if (ref == NULL)
+		return E_PAR;
+
+	ct->xid = create_xid();
+	if ((opt = setup_dhcp_com_msg(ct, DHCP4_REQUEST, DHCP4_MTYPE_REQUEST)) == NULL)
+		return E_PAR;
+
+#if defined(DHCP4_CLI_CFG_REQUIRED_OLIST) || defined(DHCP4_CLI_CFG_REQUEST_OLIST)
+
+	/* è¿½å ã®ãªãã·ã§ã³ãè¨­å®ããã*/
+
+	*opt  = DHCP4_OPT_REQ_PARAM;
+	 opt += 2;
+
+#if defined(DHCP4_CLI_CFG_REQUIRED_OLIST)
+
+	/* è¦æ±ãªãã·ã§ã³ãªã¹ããè¨­å®ããã*/
+	if (sizeof(required_plist) > 0) {
+		memcpy(opt, required_plist, sizeof(required_plist));
+		opt += sizeof(required_plist);
+		len += sizeof(required_plist);
+		}
+
+#endif	/* of #if defined(DHCP4_CLI_CFG_REQUIRED_OLIST) */
+
+#if defined(DHCP4_CLI_CFG_REQUEST_OLIST)
+
+	/* è¦æ±ãªãã·ã§ã³ãªã¹ããè¨­å®ããã*/
+	if (sizeof(request_plist) > 0) {
+		memcpy(opt, request_plist, sizeof(request_plist));
+		opt += sizeof(request_plist);
+		len += sizeof(request_plist);
+		}
+
+#endif	/* of #if defined(DHCP4_CLI_CFG_REQUEST_OLIST) */
+
+	*(opt - len - 1) = len;
+
+#endif	/* of #if defined(DHCP4_CLI_CFG_REQUIRED_OLIST) || defined(DHCP4_CLI_CFG_REQUEST_OLIST) */
+
+	/*
+	 *  ãµã¼ã IDï¼server-ipï¼ãè¨­å®ããã
+	 *  RFC2131 4.4.1 Initialization and allocation of network address åç
+§
+	 */
+	if (ct->fsm == DHCP4_FSM_REQUEST) {
+		if ((ref_opt = find_option(ref, DHCP4_OPT_SERVER_ID, sizeof(T_IN4_ADDR))) == NULL)
+			return E_PAR;
+		*(opt ++) = *(ref_opt ++);
+		*(opt ++) = *(ref_opt ++);
+		memcpy(opt, ref_opt, *(ref_opt - 1));
+		opt += *(ref_opt - 1);
+		}
+
+	/*
+	 *  è¦æ± IP ã¢ãã¬ã¹ï¼requested-ipï¼ãè¨­å®ããã
+	 *  RFC2131 4.4.1 Initialization and allocation of network address åç
+§
+	 *  RFC2131 ã§ã¯ãDHCP4_FSM_RENEW ã®æ MUST NOT ã«ãªã£ã¦ãããã
+	 *  MUST ã®ããã§ããã
+	 */
+	*(opt ++) = DHCP4_OPT_REQ_IPV4;
+	*(opt ++) = sizeof(ref->msg.yiaddr);
+	if (ct->fsm == DHCP4_FSM_REQUEST || ct->fsm == DHCP4_FSM_INIT_REBOOT ||
+	    ct->fsm == DHCP4_FSM_RENEW   || ct->fsm == DHCP4_FSM_REBIND)
+	 	/* åç
+§ã¡ãã»ã¼ã¸ã¨åã IP ã¢ãã¬ã¹ï¼requested-ipï¼ãè¦æ±ããã*/
+		memcpy(opt, (uint8_t*)&ref->msg.yiaddr, sizeof(ref->msg.yiaddr));
+	else
+		host2msg32(opt, IPV4_ADDRANY);
+	opt += sizeof(ref->msg.yiaddr);
+
+	/* 
+	 *  ã¯ã©ã¤ã¢ã³ã IDï¼MAC ã¢ãã¬ã¹ï¼ãè¨­å®ããã
+	 *  RFC2131 4.4.1 Initialization and allocation of network address åç
+§
+	 */
+	*(opt ++) = DHCP4_OPT_CLIENT_ID;
+	*(opt ++) = ETHER_ADDR_LEN + 1;
+	*(opt ++) = DHCP4_HWA_TYPE_ETHER;
+	memcpy(opt, &ct->sc->ifaddr.lladdr, ETHER_ADDR_LEN);
+	opt += ETHER_ADDR_LEN;
+
+	/* ãªãã·ã§ã³ã®çµäºãè¨­å®ããã*/
+	*(opt ++) = DHCP4_OPT_END;
+
+	/*
+	 *  ã¯ã©ã¤ã¢ã³ã IP ã¢ãã¬ã¹ï¼ciaddrï¼ãè¨­å®ããã
+	 *  RFC2131 4.4.1 Initialization and allocation of network address åç
+§
+	 */
+	if (ct->fsm == DHCP4_FSM_RENEW || ct->fsm == DHCP4_FSM_REBIND)
+		HOST2MSG32(ct->snd_msg->msg.ciaddr, IF_GET_IFNET()->in4_ifaddr.addr);
+	else
+		HOST2MSG32(ct->snd_msg->msg.ciaddr, IPV4_ADDRANY);
+
+	/* ã¡ãã»ã¼ã¸é·ãè¨­å®ããã*/
+	ct->snd_msg->len = sizeof(ct->snd_msg->msg) - DHCP4_DFLT_OPT_LEN
+	             + (opt - (uint8_t*)&ct->snd_msg->msg.options);
+	return E_OK;
+	}
+
+/*
+ *  setup_discover_msg -- DISCOVER ã¡ãã»ã¼ã¸ãä½æããã
+ */
+
+static ER
+setup_discover_msg (T_DHCP4_CLI_CONTEXT *ct)
+{
+	uint8_t *opt;
+
+#if defined(DHCP4_CLI_CFG_REQUIRED_OLIST) || defined(DHCP4_CLI_CFG_REQUEST_OLIST)
+	uint_t	len = 0;
+#endif
+
+	ct->xid = create_xid();
+	if ((opt = setup_dhcp_com_msg(ct, DHCP4_REQUEST, DHCP4_MTYPE_DISCOVER)) == NULL)
+		return E_PAR;
+
+#if defined(DHCP4_CLI_CFG_REQUIRED_OLIST) || defined(DHCP4_CLI_CFG_REQUEST_OLIST)
+
+	/* è¿½å ã®ãªãã·ã§ã³ãè¨­å®ããã*/
+
+	*opt  = DHCP4_OPT_REQ_PARAM;
+	 opt += 2;
+
+#if defined(DHCP4_CLI_CFG_REQUIRED_OLIST)
+
+	/* è¦æ±ãªãã·ã§ã³ãªã¹ããè¨­å®ããã*/
+	if (sizeof(required_plist) > 0) {
+		memcpy(opt, required_plist, sizeof(required_plist));
+		opt += sizeof(required_plist);
+		len += sizeof(required_plist);
+		}
+
+#endif	/* of #if defined(DHCP4_CLI_CFG_REQUIRED_OLIST) */
+
+#if defined(DHCP4_CLI_CFG_REQUEST_OLIST)
+
+	/* è¦æ±ãªãã·ã§ã³ãªã¹ããè¨­å®ããã*/
+	if (sizeof(request_plist) > 0) {
+		memcpy(opt, request_plist, sizeof(request_plist));
+		opt += sizeof(request_plist);
+		len += sizeof(request_plist);
+		}
+
+#endif	/* of #if defined(DHCP4_CLI_CFG_REQUEST_OLIST) */
+
+	*(opt - len - 1) = len;
+
+#endif	/* of #if defined(DHCP4_CLI_CFG_REQUIRED_OLIST) || defined(DHCP4_CLI_CFG_REQUEST_OLIST) */
+
+	/* æ¢ã«ã¢ãã¬ã¹æ
+å ±ããªã¼ã¹ããã¦ããã°ãåã IP ã¢ãã¬ã¹ãè¦æ±ããã*/
+	if (ct->act_msg != NULL) {
+		*(opt ++) = DHCP4_OPT_REQ_IPV4;
+		*(opt ++) = sizeof(ct->act_msg->msg.yiaddr);
+		memcpy(opt, (uint8_t*)&ct->act_msg->msg.yiaddr, sizeof(ct->act_msg->msg.yiaddr));
+		opt += sizeof(ct->act_msg->msg.yiaddr);
+		}
+
+	/* ã¯ã©ã¤ã¢ã³ã IDï¼MAC ã¢ãã¬ã¹ï¼ãè¨­å®ããã*/
+	*(opt ++) = DHCP4_OPT_CLIENT_ID;
+	*(opt ++) = ETHER_ADDR_LEN + 1;
+	*(opt ++) = DHCP4_HWA_TYPE_ETHER;
+	memcpy(opt, &ct->sc->ifaddr.lladdr, ETHER_ADDR_LEN);
+	opt += ETHER_ADDR_LEN;
+
+	/* ãªãã·ã§ã³ã®çµäºãè¨­å®ããã*/
+	*(opt ++) = DHCP4_OPT_END;
+
+	/* éä¿¡å
+ã¢ãã¬ã¹ãè¨­å®ããã*/
+	ct->dst.ipaddr = IPV4_ADDRBROADCAST;
+
+	/* ã¡ãã»ã¼ã¸é·ãè¨­å®ããã*/
+	ct->snd_msg->len = sizeof(ct->snd_msg->msg) - DHCP4_DFLT_OPT_LEN
+	             + (opt - (uint8_t*)&ct->snd_msg->msg.options);
+	return E_OK;
+	}
+
+/*
+ *  ack_msg_timeout -- ACK/NAK ã¡ãã»ã¼ã¸åä¿¡ã¿ã¤ã ã¢ã¦ãå¦ç
+ */
+
+static void
+ack_msg_timeout (T_DHCP4_CLI_CONTEXT *ct)
+{
+	/* ACK ã¡ãã»ã¼ã¸ãåä¿¡ãã¦ããã°ãBOUND ç¶æ
+ã«é·ç§»ããã*/
+	ct->flags &= ~DHCP4C_FLAG_TMOUT_MASK;
+	if (select_ack(ct)) {
+
+		/* REQUEST ã¡ãã»ã¼ã¸éä¿¡ã¿ã¤ãã¼ãåæ­¢ããã*/
+		syscall(wai_sem(SEM_DHCP4_CLI_TIMER));
+		ct->timers[DHCP4C_TIMER_SND_REQ] = 0;
+		syscall(sig_sem(SEM_DHCP4_CLI_TIMER));
+
+		/*
+		 *  ç¶æ
+ã REQUEST ã®æã¯ã
+		 *  OFFER ã¡ãã»ã¼ã¸ãåä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ãã«æ»ãã
+		 */
+		if (ct->fsm == DHCP4_FSM_REQUEST && ct->off_msg != NULL) {
+			syscall(wai_sem(SEM_DHCP4_CLI_LOCK));
+			ct->off_msg->next = ct->rcv_lst;
+			ct->rcv_lst = ct->off_msg;
+			syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+			ct->off_msg = NULL;
+			}
+
+		/* BOUND ç¶æ
+ã«é·ç§»ããã*/
+		start_bound(ct);
+		return;
+		}
+	else {
+
+		/* ãªã¼ã¹æ
+å ±ãè§£æ¾ããã*/
+		rel_lease(ct);
+
+		ct->error = E_TMOUT;
+		}
+	}
+
+/*
+ *  send_request_msg -- REQUEST ã¡ãã»ã¼ã¸ãéä¿¡ããã
+ */
+
+static void
+send_request_msg (T_DHCP4_CLI_CONTEXT *ct)
+{
+	T_DHCP4_CLI_MSG	*ref;
+	ER		error;
+	SYSTIM		time;
+	RELTIM		interval;
+	uint16_t	secs;
+
+	/* ã¿ã¤ã ã¢ã¦ããã©ã°ãã¯ãªã¢ã¼ããã*/
+	ct->flags &= ~DHCP4C_FLAG_TMOUT_MASK;
+
+	/* ACK ã¡ãã»ã¼ã¸ãåä¿¡ãã¦ããã°ãBOUND ç¶æ
+ã«é·ç§»ããã*/
+	ct->flags &= ~DHCP4C_FLAG_TMOUT_MASK;
+	if (select_ack(ct)) {
+
+		/* ACK/NAK ã¡ãã»ã¼ã¸åä¿¡ã¿ã¤ãã¼ãåæ­¢ããã*/
+		syscall(wai_sem(SEM_DHCP4_CLI_TIMER));
+		ct->timers[DHCP4C_TIMER_RCV_ACK] = 0;
+		syscall(sig_sem(SEM_DHCP4_CLI_TIMER));
+
+		/*
+		 *  ç¶æ
+ã REQUEST ã®æã¯ã
+		 *  OFFER ã¡ãã»ã¼ã¸ãåä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ãã«æ»ãã
+		 */
+		if (ct->fsm == DHCP4_FSM_REQUEST && ct->off_msg != NULL) {
+			syscall(wai_sem(SEM_DHCP4_CLI_LOCK));
+			ct->off_msg->next = ct->rcv_lst;
+			ct->rcv_lst = ct->off_msg;
+			syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+			ct->off_msg = NULL;
+			}
+
+		/* BOUND ç¶æ
+ã«é·ç§»ããã*/
+		start_bound(ct);
+		return;
+		}
+
+	/* REQUEST ã¡ãã»ã¼ã¸ãä½æããã*/
+	if (ct->fsm == DHCP4_FSM_REQUEST)
+		ref = ct->off_msg;
+	else
+		ref = ct->act_msg;
+	if ((error = setup_request_msg(ct, ref)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, setup request message: %s", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* éä¿¡ãéå§ãã¦ããã®æéãå¾ãã*/
+	get_tim(&time);
+	interval = time - ct->snd_start;
+
+	/*
+	 * éä¿¡ãéå§ãã¦ããã®æéï¼ç§ï¼ãã¡ãã»ã¼ã¸ã«è¨­å®ããã
+	 * æå¤§å¤ã¯ 65535ã
+	 */
+	if (ct->fsm == DHCP4_FSM_REQUEST)
+		secs = ct->secs;
+	else {
+		if (SYSTIM2SEC(interval) < 65536)
+			secs = SYSTIM2SEC(interval);
+		else
+			secs = 65535;
+		}
+	HOST2MSG16(ct->snd_msg->msg.secs, secs);
+
+	/* ãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ã¡ãã»ã¼ã¸ãéä¿¡ããã*/
+	error = udp_snd_dat(ct->cepid, &ct->dst, &ct->snd_msg->msg, ct->snd_msg->len, TMO_NBLK);
+	if (error != E_WBLK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, send request message: %s", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* éä¿¡ééãè¨­å®ããã*/
+	if (ct->interval == 0)
+		/* æªè¨­å® */
+		ct->interval = TMO_DHCP4C_INIT_INTVL;
+	else
+		/* ããã¯ãªãã¢ã«ã´ãªãºã ã§ 2åã«ããï¼ä¹±æ°ä½¿ç¨ï¼éä¿¡ééãå ç®ããã*/
+		ct->interval += (netapp_rand() >> 2) % (ct->interval << 1);
+	
+	/* éä¿¡å¨æã®å¶éå¤ãè¶
+ããªãããã«ããã*/
+	if (ct->interval > TMO_DHCP4C_MAX_BACKOFF)
+		ct->interval = (TMO_DHCP4C_MAX_BACKOFF >> 1) + ((netapp_rand() >> 2) % TMO_DHCP4C_MAX_BACKOFF);
+
+	/* ãªã¼ã¹æéã®ã¿ã¤ã ã¢ã¦ããå
+éãã */
+	if (ct->fsm != DHCP4_FSM_REQUEST &&
+	    TIMEC_GT(ct->interval + time, ct->expire + ct->bind_start))
+		ct->interval = ct->expire + ct->bind_start - time + SYSTIM_HZ;
+
+	/* åéä¿¡ã¿ã¤ã ã¢ã¦ããè¨­å®ããã*/
+	syscall(wai_sem(SEM_DHCP4_CLI_TIMER));
+	ct->timers[DHCP4C_TIMER_SND_REQ] = SYSTIM2TIMER(ct->interval);
+	syscall(sig_sem(SEM_DHCP4_CLI_TIMER));
+	}
+
+/*
+ *  send_release_msg -- RELEASE ã¡ãã»ã¼ã¸ãéä¿¡ããã
+ */
+
+static void
+send_release_msg (T_DHCP4_CLI_CONTEXT *ct)
+{
+	ER		error;
+
+	/* ã¿ã¤ã ã¢ã¦ããã©ã°ãã¯ãªã¢ã¼ããã*/
+	ct->flags &= ~DHCP4C_FLAG_TMOUT_MASK;
+
+	/* RELEASE ã¡ãã»ã¼ã¸ãä½æããã*/
+	if ((error = setup_release_msg(ct, ct->act_msg)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, setup release message: %s", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* ãªã¼ã¹æ
+å ±ãè§£æ¾ããã*/
+	rel_lease(ct);
+
+	/* ãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ã¡ãã»ã¼ã¸ãéä¿¡ããã*/
+	error = udp_snd_dat(ct->cepid, &ct->dst, &ct->snd_msg->msg, ct->snd_msg->len, TMO_NBLK);
+	if (error != E_WBLK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, send release message: %s", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* ã¡ãã»ã¼ã¸éä¿¡å¾
+ã¡ãè¡ãã*/
+	syscall(wai_sem(SEM_DHCP4_CLI_READY));
+
+	/* SLEEP ç¶æ
+ã«é·ç§»ããã*/
+	ct->fsm = DHCP4_FSM_SLEEP;
+	}
+
+/*
+ *  offer_msg_timeout -- OFFER ã¡ãã»ã¼ã¸åä¿¡ã¿ã¤ã ã¢ã¦ãå¦ç
+ */
+
+static void
+offer_msg_timeout (T_DHCP4_CLI_CONTEXT *ct)
+{
+	/* OFFER ã¡ãã»ã¼ã¸ãåä¿¡ãã¦ããã°ãREQUEST ç¶æ
+ã«é·ç§»ããã*/
+	ct->flags &= ~DHCP4C_FLAG_TMOUT_MASK;
+	if (select_offer(ct)) {
+
+		/* DISCOVER ã¡ãã»ã¼ã¸éä¿¡ã¿ã¤ãã¼ãåæ­¢ããã*/
+		syscall(wai_sem(SEM_DHCP4_CLI_TIMER));
+		ct->timers[DHCP4C_TIMER_SND_DISC] = 0;
+		syscall(sig_sem(SEM_DHCP4_CLI_TIMER));
+
+		/* REQUEST ã¡ãã»ã¼ã¸ãéä¿¡ãã¦ REQUEST ç¶æ
+ã«é·ç§»ããã*/
+		start_send_request(ct, DHCP4_FSM_REQUEST);
+		}
+	else
+		ct->error = E_TMOUT;
+	}
+
+/*
+ *  send_discover_msg -- DISCOVERã¡ãã»ã¼ã¸ãéä¿¡ããã
+ */
+
+static void
+send_discover_msg (T_DHCP4_CLI_CONTEXT *ct)
+{
+	ER	error;
+	SYSTIM	time;
+	RELTIM	interval;
+
+	/* ã¿ã¤ã ã¢ã¦ããã©ã°ãã¯ãªã¢ã¼ããã*/
+	ct->flags &= ~DHCP4C_FLAG_TMOUT_MASK;
+
+	/* OFFER ã¡ãã»ã¼ã¸ãåä¿¡ãã¦ããã°ãREQUEST ç¶æ
+ã«é·ç§»ããã*/
+	ct->flags &= ~DHCP4C_FLAG_TMOUT_MASK;
+	if (select_offer(ct)) {
+
+		/* OFFER ã¡ãã»ã¼ã¸åä¿¡ã¿ã¤ãã¼ãåæ­¢ããã*/
+		syscall(wai_sem(SEM_DHCP4_CLI_TIMER));
+		ct->timers[DHCP4C_TIMER_RCV_OFFER] = 0;
+		syscall(sig_sem(SEM_DHCP4_CLI_TIMER));
+
+		/* REQUEST ã¡ãã»ã¼ã¸ãéä¿¡ãã¦ REQUEST ç¶æ
+ã«é·ç§»ããã*/
+		start_send_request(ct, DHCP4_FSM_REQUEST);
+		return;
+		}
+
+	/* DISCOVER ã¡ãã»ã¼ã¸ãä½æããã*/
+	if ((error = setup_discover_msg(ct)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, setup discover message: %s", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* éä¿¡ãéå§ãã¦ããã®æéãå¾ãã*/
+	get_tim(&time);
+	interval = time - ct->snd_start;
+
+	/*
+	 * éä¿¡ãéå§ãã¦ããã®æéï¼ç§ï¼ãã¡ãã»ã¼ã¸ã«è¨­å®ããã
+	 * æå¤§å¤ã¯ 65535ã
+	 */
+	if (SYSTIM2SEC(interval) < 65536)
+		ct->secs = SYSTIM2SEC(interval);
+	else
+		ct->secs = 65535;
+	HOST2MSG16(ct->snd_msg->msg.secs, ct->secs);
+
+	/* ãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ã¡ãã»ã¼ã¸ãéä¿¡ããã*/
+	error = udp_snd_dat(ct->cepid, &ct->dst, &ct->snd_msg->msg, ct->snd_msg->len, TMO_NBLK);
+	if (error != E_WBLK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, send discover message: %s", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* éä¿¡ééãè¨­å®ããã*/
+	if (ct->interval == 0)
+		/* æªè¨­å® */
+		ct->interval = TMO_DHCP4C_INIT_INTVL;
+	else
+		/* ããã¯ãªãã¢ã«ã´ãªãºã ã§ 2åã«ããï¼ä¹±æ°ä½¿ç¨ï¼éä¿¡ééãå ç®ããã*/
+		ct->interval += (netapp_rand() >> 2) % (ct->interval << 1);
+	
+	/* éä¿¡å¨æã®å¶éå¤ãè¶
+ããªãããã«ããã*/
+	if (ct->interval > TMO_DHCP4C_MAX_BACKOFF)
+		ct->interval = (TMO_DHCP4C_MAX_BACKOFF >> 1) + ((netapp_rand() >> 2) % TMO_DHCP4C_MAX_BACKOFF);
+
+	/* OFFER ã¡ãã»ã¼ã¸ã®åä¿¡ã¿ã¤ã ã¢ã¦ããè¶
+ããªãããã«èª¿æ´ããã*/
+	if (TIMEC_GT(time + ct->interval, ct->snd_start + TMO_DHCP4C_OFFER))
+		ct->interval = (TMO_DHCP4C_INIT_INTVL + TMO_DHCP4C_OFFER) - time + 1;
+
+	/* åéä¿¡ã¿ã¤ã ã¢ã¦ããè¨­å®ããã*/
+	syscall(wai_sem(SEM_DHCP4_CLI_TIMER));
+	ct->timers[DHCP4C_TIMER_SND_DISC] = SYSTIM2TIMER(ct->interval);
+	syscall(sig_sem(SEM_DHCP4_CLI_TIMER));
+	}
+
+/*
+ *  dhcpc_timer -- TIMER ç®¡ç
+ */
+
+static void
+dhcpc_timer (T_DHCP4_CLI_CONTEXT *ct)
+{
+	int ix;
+
+	syscall(wai_sem(SEM_DHCP4_CLI_TIMER));
+	for (ix = NUM_DHCP4C_TIMERS; ix -- > 0; ) {
+		if (ct->timers[ix] != 0) {
+			ct->timers[ix] --;
+			if (ct->timers[ix] == 0) {
+				ct->flags = (ct->flags & ~DHCP4C_FLAG_TMOUT_MASK) | DHCP4C_FLAG_TMOUT_TIMER | ix;
+				syscall(sig_sem(SEM_DHCP4_CLI_READY));
+				}
+			}
+		}
+	syscall(sig_sem(SEM_DHCP4_CLI_TIMER));
+
+	/* 1ç§æ¯ã«ã¿ã¤ã ã¢ã¦ãããã*/
+	timeout((callout_func)dhcpc_timer, ct, NET_TIMER_HZ);
+	}
+
+/*
+ *  expire_timeout -- EXPIRE ã¿ã¤ã ã¢ã¦ãå¦ç
+ */
+
+static void
+expire_timeout (T_DHCP4_CLI_CONTEXT *ct)
+{
+	//ER	error;
+
+	/* ã¿ã¤ã ã¢ã¦ããã©ã°ãã¯ãªã¢ã¼ããã*/
+	ct->flags &= ~DHCP4C_FLAG_TMOUT_MASK;
+
+	/* ç¶æ
+ã REQUEST ã®æã¯ä½ãããªãã*/
+	if (ct->fsm == DHCP4_FSM_REQUEST)
+		return;
+
+	/* å
+¨ã¦ã® TIMER ãã­ã£ã³ã»ã«ããã*/
+	cancel_all_timers(ct);
+
+	/* ãªã¼ã¹ãããæ
+å ±ãè§£æ¾ããã*/
+	rel_lease(ct);
+
+	ct->error = E_TMOUT;
+	}
+
+/*
+ *  rebind_timeout -- REBIND ã¿ã¤ã ã¢ã¦ãå¦ç
+ */
+
+static void
+rebind_timeout (T_DHCP4_CLI_CONTEXT *ct)
+{
+	/* ã¿ã¤ã ã¢ã¦ããã©ã°ãã¯ãªã¢ã¼ããã*/
+	ct->flags &= ~DHCP4C_FLAG_TMOUT_MASK;
+
+	/* å
+¨ã¦ã® TIMER ãã­ã£ã³ã»ã«ããã*/
+	cancel_all_timers(ct);
+
+	/* REQUEST ã¡ãã»ã¼ã¸ãéä¿¡ãã¦ REBIND ç¶æ
+ã«é·ç§»ããã*/
+	start_send_request(ct, DHCP4_FSM_REBIND);
+	}
+
+/*
+ *  renew_timeout -- RENEW ã¿ã¤ã ã¢ã¦ãå¦ç
+ */
+
+static void
+renew_timeout (T_DHCP4_CLI_CONTEXT *ct)
+{
+	/* ã¿ã¤ã ã¢ã¦ããã©ã°ãã¯ãªã¢ã¼ããã*/
+	ct->flags &= ~DHCP4C_FLAG_TMOUT_MASK;
+
+	/* REQUEST ã¡ãã»ã¼ã¸ãéä¿¡ãã¦ RENEW ç¶æ
+ã«é·ç§»ããã*/
+	start_send_request(ct, DHCP4_FSM_RENEW);
+	}
+
+/*
+ *  dispatch_timeout -- ã¿ã¤ã ã¢ã¦ãããæã®å¦ç
+ */
+
+static ER
+dispatch_timeout (T_DHCP4_CLI_CONTEXT *ct)
+{
+	switch (ct->flags & DHCP4C_FLAG_TMOUT_TIMER_MASK) {
+
+	case DHCP4C_TIMER_SND_DISC:
+		send_discover_msg(ct);
+		break;
+
+	case DHCP4C_TIMER_SND_REQ:
+		send_request_msg(ct);
+		break;
+
+	case DHCP4C_TIMER_RCV_OFFER:
+		offer_msg_timeout(ct);
+		break;
+
+	case DHCP4C_TIMER_RCV_ACK:
+		ack_msg_timeout(ct);
+		break;
+
+	case DHCP4C_TIMER_RENEW:
+		renew_timeout(ct);
+		break;
+
+	case DHCP4C_TIMER_REBIND:
+		rebind_timeout(ct);
+		break;
+
+	case DHCP4C_TIMER_EXPIRE:
+		expire_timeout(ct);
+		break;
+
+	case DHCP4C_TIMER_SND_REL:
+		send_release_msg(ct);
+		break;
+
+	default:
+		break;
+		}
+
+	return ct->error;
+	}
+
+/*
+ *  dispatch_event -- ã¤ãã³ãæ¯ã®å¦ç
+ */
+
+static ER
+dispatch_event (T_DHCP4_CLI_CONTEXT *ct)
+{
+	ER	error = E_OK;
+
+	while (ct->fsm != DHCP4_FSM_SLEEP && error == E_OK) {
+
+		/* ã¡ãã»ã¼ã¸ã®åä¿¡ã¨ã¿ã¤ã ã¢ã¦ããå¾
+ã¤ã*/
+		syscall(wai_sem(SEM_DHCP4_CLI_READY));
+
+		if (ct->flags & DHCP4C_FLAG_RCV_MSG) {
+			while (ct->val_lst != NULL) {
+				error = eval_rcv_msg(ct);
+				}
+			ct->flags &= ~DHCP4C_FLAG_RCV_MSG;
+			}
+		if (ct->flags & DHCP4C_FLAG_TMOUT_MASK)
+			error = dispatch_timeout(ct);
+
+		if (ct->error != E_OK)
+			error = ct->error;
+		}
+
+	return error;
+	}
+
+/*
+ *  init_context -- DHCP ã¯ã©ã¤ã¢ã³ãã³ã³ãã­ã¹ãæ§é ä½ãåæåããã
+ */
+
+static void
+init_context (T_DHCP4_CLI_CONTEXT *ct, ID cepid)
+{
+  	memset(ct, 0, sizeof(*ct));
+	ct->cepid	= cepid;
+	ct->sc		= IF_ETHER_NIC_GET_SOFTC();
+	ct->dst.portno	= DHCP4_SRV_CFG_PORTNO;
+	ct->dst.ipaddr	= IPV4_ADDRANY;
+	ct->set_addr_callback = DHCP4_CLI_SET_ADDR_CALLBACK;
+	}
+
+/*
+ *  rel_cli_msg -- ã¡ãã»ã¼ã¸æ§é ä½ãè§£æ¾ããã
+ */
+
+static void
+rel_cli_msg (T_DHCP4_CLI_CONTEXT *ct)
+{
+	T_DHCP4_CLI_MSG	*ptr, *cell;
+
+	for (ptr = ct->rcv_lst; ptr != NULL; ) {
+		cell = ptr;
+		ptr = ptr->next;
+		syscall(rel_mpf(MPF_DHCP4_CLI_MSG, (void*)cell));
+		}
+
+	for (ptr = ct->val_lst; ptr != NULL; ) {
+		cell = ptr;
+		ptr = ptr->next;
+		syscall(rel_mpf(MPF_DHCP4_CLI_MSG, (void*)cell));
+		}
+
+	for (ptr = ct->prf_lst; ptr != NULL; ) {
+		cell = ptr;
+		ptr = ptr->next;
+		syscall(rel_mpf(MPF_DHCP4_CLI_MSG, (void*)cell));
+		}
+
+	if (ct->snd_msg != NULL)
+		syscall(rel_mpf(MPF_DHCP4_CLI_MSG, (void*)ct->snd_msg));
+	ct->rcv_lst = ct->prf_lst = ct->val_lst = ct->snd_msg = NULL;
+	}
+
+/*
+ *  init_cli_msg -- åã¡ãã»ã¼ã¸æ§é ä½ãåæåããã
+ */
+
+static ER
+init_cli_msg (T_DHCP4_CLI_CONTEXT *ct)
+{
+	T_DHCP4_CLI_MSG	*cell;
+	ER		error;
+	int		count;
+
+	/* éä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãç²å¾ããã*/
+	if ((error = tget_mpf(MPF_DHCP4_CLI_MSG, (void*)&ct->snd_msg, TMO_DHCP4C_MPF_GET)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP4C] error, tget_mpf() for send: %s.", itron_strerror(error));
+		return error;
+		}
+
+	/*
+	 *  æå¹ãªãªã¼ã¹ã»ã¡ãã»ã¼ã¸æ§é ä½ãããå ´åã¯ã
+	 *  ç²å¾ããåä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ãã®æ§é ä½ã 1æ¸ããã
+	 */
+	if (ct->act_msg == NULL)
+		count = NUM_DHCP4_MSG_LIST;
+	else
+		count = NUM_DHCP4_MSG_LIST - 1;
+
+	/* åä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãç²å¾ããã*/
+	while (count --> 0) {
+		if ((error = tget_mpf(MPF_DHCP4_CLI_MSG, (void*)&cell, TMO_DHCP4C_MPF_GET)) != E_OK) {
+			syslog(LOG_NOTICE, "[DHCP4C] error, tget_mpf() for receive: %s.", itron_strerror(error));
+			break;
+			}
+		cell->next  = ct->rcv_lst;
+		ct->rcv_lst = cell;
+		}
+
+	return E_OK;
+	}
+
+/*
+ *  dhcp4c_renew_info -- ãããã¯ã¼ã¯æ
+å ±ãååå¾ããã
+ */
+
+ER
+dhcp4c_renew_info (void)
+{
+	if (context.fsm == DHCP4_FSM_BOUND) {
+
+		/* REL_INFO ç¶æ
+ã«é·ç§»ããå¾ã« SLEEP ãè§£é¤ããããã«è¨­å®ããã*/
+		context.flags |= DHCP4C_FLAG_RENEW;
+		start_rel_info(&context);
+		return E_OK;
+		}
+	else if (context.fsm == DHCP4_FSM_SLEEP) {
+
+		/* SLEEP ãè§£é¤ããã*/
+		wup_tsk(DHCP4_CLI_TASK);
+		return E_OK;
+		}
+	else
+		return E_OBJ;
+	}
+
+/*
+ *  dhcp4c_rel_info -- DHCP ã§è¨­å®ããããããã¯ã¼ã¯æ
+å ±ãè§£æ¾ããã
+ */
+
+ER
+dhcp4c_rel_info (void)
+{
+	/* REL_INFO ç¶æ
+ã«é·ç§»ããã*/
+	start_rel_info(&context);
+	return E_OK;
+	}
+
+/*
+ *  dhcp4c_get_info -- DHCP ã§è¨­å®ããããããã¯ã¼ã¯æ
+å ±ãè¿ãã
+ */
+
+ER
+dhcp4c_get_info (T_IN4_ADDR *addr, uint32_t *expire, uint32_t *renew,
+                                   uint32_t *rebind, SYSTIM *bind_start)
+{
+	if (addr  == NULL || expire == NULL || 
+	    renew == NULL || rebind == NULL || bind_start == NULL)
+		return E_PAR;
+	else if (context.act_msg == NULL)
+		return E_OBJ;
+	else {
+		*addr		= context.act_msg->srv.ipaddr;
+		*expire		= context.timers[DHCP4C_TIMER_EXPIRE];
+		*renew		= context.timers[DHCP4C_TIMER_RENEW];
+		*rebind		= context.timers[DHCP4C_TIMER_REBIND];
+		*bind_start	= context.bind_start;
+		return E_OK;
+		}
+	}
+
+/*
+ *  ã³ã¼ã«ããã¯é¢æ°
+ */
+
+ER
+callback_nblk_dhcp4_cli (ID cepid, FN fncd, void *p_parblk)
+{
+	T_DHCP4_CLI_MSG	*msg;
+	ER_UINT		len;
+
+	len = *(ER_UINT*)p_parblk;
+	if (len < 0 && len != E_RLWAI) {
+		/* E_RLWAI ä»¥å¤ã§ã0 ä»¥ä¸ã®å ´åã¯ãã¨ã©ã¼ãæå³ãã¦ããã*/
+		syslog(LOG_NOTICE, "[DHCPC(CBR)] error: %s, fncd: %s", itron_strerror(len), in_strtfn(fncd));
+		}
+	else {
+		if (fncd == TEV_UDP_RCV_DAT) {
+
+			/* åä¿¡ã¡ãã»ã¼ã¸ãªã¹ããç©ºã®æã¯ãåä¿¡ããªãã§ãã¼ã¿ã°ã©ã ãæ¨ã¦ãã*/
+			if (context.rcv_lst == NULL) 
+				syslog(LOG_NOTICE, "[DHCP4C(CBR)] receive buffer all busy.");
+			else {
+				/* ã¡ãã»ã¼ã¸ãåä¿¡ããã¡ãã»ã¼ã¸æ§é ä½ãæºåããã*/
+				syscall(wai_sem(SEM_DHCP4_CLI_LOCK));
+				msg = context.rcv_lst;
+				context.rcv_lst = context.rcv_lst->next;
+				syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+
+				/* ã¡ãã»ã¼ã¸ãåä¿¡ããã*/
+				len = udp_rcv_dat(context.cepid, &msg->srv, &msg->msg, sizeof(msg->msg), TMO_POL);
+
+				syscall(wai_sem(SEM_DHCP4_CLI_LOCK));
+				msg->len = len;
+				if (len >= 0) {
+					/* åä¿¡ããã¡ãã»ã¼ã¸ãæ¤è¨¼ã¡ãã»ã¼ã¸ãªã¹ãã«ç§»ãã*/
+					msg->next = context.val_lst;
+					context.val_lst = msg;
+					context.flags |= DHCP4C_FLAG_RCV_MSG;
+					}
+				else {
+					/* ã¡ãã»ã¼ã¸æ§é ä½ãåä¿¡ã¡ãã»ã¼ã¸ãªã¹ãã«æ»ãã*/
+					context.error = len;
+					msg->next = context.rcv_lst;
+					context.rcv_lst = msg;
+					}
+				syscall(sig_sem(SEM_DHCP4_CLI_LOCK));
+				}
+			}
+		syscall(sig_sem(SEM_DHCP4_CLI_READY));
+		}
+	return E_OK;
+	}
+
+/*
+ *  dhcp4_cli_task -- DHCP ã¯ã©ã¤ã¢ã³ãã¿ã¹ã¯
+ */
+
+void
+dhcp4_cli_task (intptr_t exinf)
+{
+	T_DHCP4_CLI_CONTEXT	*ct;
+	ID			tskid;
+	ER			error;
+
+	dly_tsk(1000);
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[DHCP4C:%d,%d] started.", tskid, (ID)exinf);
+	dly_tsk(500);
+	ct = &context;
+
+	/* DHCP ã¯ã©ã¤ã¢ã³ãã³ã³ãã­ã¹ãæ§é ä½ãåæåããã*/
+	init_context(ct, (ID)exinf);
+
+	while (true) {
+
+		/* 1ç§æ¯ã«ã¿ã¤ã ã¢ã¦ãããããã«ã¿ã¤ãã¼ãè¨­å®ããã*/
+		timeout((callout_func)dhcpc_timer, ct, NET_TIMER_HZ / DHCP4C_TIMER_HZ);
+
+		/* ã¡ãã»ã¼ã¸æ§é ä½ãåæåããã*/
+		if ((error = init_cli_msg(ct)) == E_OK) {
+
+			/* SELECT ç¶æ
+ã«é·ç§»ããã*/
+			start_select(ct);
+
+			/* ã¡ã¤ã³ã«ã¼ã */
+			error = dispatch_event(ct);
+			}
+
+		/* å
+¨ã¦ã® TIMER ãã­ã£ã³ã»ã«ããã*/
+		cancel_all_timers(ct);
+
+		/* ã¿ã¤ãã¼ãåæ­¢ããã*/
+		untimeout((callout_func)dhcpc_timer, ct);
+
+		/* ã¡ãã»ã¼ã¸æ§é ä½ãè§£æ¾ããã*/
+		rel_cli_msg (ct);
+
+		/* ãªã¼ã¹ãè§£æ¾å¾ãååå¾ãæå®ããã¦ããªããã°ä¼æ­¢ããã*/
+		if (!(ct->flags & DHCP4C_FLAG_RENEW)) {
+
+			/* ä¼æ­¢ããã*/
+			if (error == E_OK)
+				syslog(LOG_NOTICE, "[DHCP4C] lease released, go to sleep.");
+			else {
+				syslog(LOG_NOTICE, "[DHCP4C] server not available, go to sleep, error: %s.", itron_strerror(error));
+				ct->fsm = DHCP4_FSM_SLEEP;
+				}
+			slp_tsk();
+			}
+		ct->flags = 0;
+		ct->error = E_OK;
+		}
+	}
+
+#endif	/* of #ifdef DHCP4_CLI_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4_cli.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4_cli.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4_cli.cfg	(revision 331)
@@ -0,0 +1,74 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2011 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#ifdef DHCP4_CLI_CFG
+
+/*
+ *  DHCP ã¯ã©ã¤ã¢ã³ã
+ *  ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ */
+
+/* ã¿ã¹ã¯ */
+
+CRE_TSK(DHCP4_CLI_TASK, {
+	TA_HLNG|TA_ACT,
+	UDP4_DHCP_CLI_CEPID,
+	dhcp4_cli_task,
+	DHCP4_CLI_MAIN_PRIORITY,
+	DHCP4_CLI_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #ifdef DHCP4_CLI_CFG */
+
+/* ã»ããã© */
+
+#ifdef DHCP4_CLI_CFG
+
+CRE_SEM(SEM_DHCP4_CLI_READY,	{ TA_TPRI, 0, 1 });
+CRE_SEM(SEM_DHCP4_CLI_TIMER,	{ TA_TPRI, 1, 1 });
+CRE_SEM(SEM_DHCP4_CLI_LOCK,	{ TA_TPRI, 1, 1 });
+
+#endif	/* of #ifdef DHCP4_CLI_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4_cli.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4_cli.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4_cli.h	(revision 331)
@@ -0,0 +1,285 @@
+/*
+ * Copyright 2004 Henning Brauer <henning@openbsd.org>
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999
+ * The Internet Software Consortium.    All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ *    of its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ *
+ * This client was substantially modified and enhanced by Elliot Poger
+ * for use on Linux while he was working on the MosquitoNet project at
+ * Stanford.
+ *
+ * The current version owes much to Elliot's Linux enhancements, but
+ * was substantially reorganized and partially rewritten by Ted Lemon
+ * so as to use the same networking framework that the Internet Software
+ * Consortium DHCP server uses.   Much system-specific configuration code
+ * was moved into a shell script so that as support for more operating
+ * systems is added, it will not be necessary to port and maintain
+ * system-specific configuration code to these operating systems - instead,
+ * the shell script can invoke the native tools to accomplish the same
+ * purpose.
+ */
+/*
+ * WIDE Project DHCP Implementation
+ * Copyright (c) 1995-1997 Akihiro Tominaga
+ * Copyright (c) 1995-1997 WIDE Project
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided the following conditions
+ * are satisfied,
+ *
+ * 1. Both the copyright notice and this permission notice appear in
+ *    all copies of the software, derivative works or modified versions,
+ *    and any portions thereof, and that both notices appear in
+ *    supporting documentation.
+ * 2. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by WIDE Project and
+ *      its contributors.
+ * 3. Neither the name of WIDE Project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND WIDE
+ * PROJECT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ALSO, THERE
+ * IS NO WARRANTY IMPLIED OR OTHERWISE, NOR IS SUPPORT PROVIDED.
+ *
+ * Feedback of the results generated from any improvements or
+ * extensions made to this software would be much appreciated.
+ * Any such feedback should be sent to:
+ * 
+ *  Akihiro Tominaga
+ *  WIDE Project
+ *  Keio University, Endo 5322, Kanagawa, Japan
+ *  (E-mail: dhcp-dist@wide.ad.jp)
+ *
+ * WIDE project has the rights to redistribute these changes.
+ */
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2011 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+ *      ã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+ *        å ±åãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef DHCP4_CLI_H
+#define DHCP4_CLI_H
+
+#include <netapp/dhcp4.h>
+
+/* 
+ *  DHCP ã¯ã©ã¤ã¢ã³ãã®ã¹ã¿ãã¯ãµã¤ãº
+ */
+
+#define DHCP4_CLI_STACK_SIZE		1024		/* DHCP ã¯ã©ã¤ã¢ã³ãã¿ã¹ã¯ã®ã¹ã¿ãã¯ãµã¤ãº	*/
+
+/* 
+ *  DHCP ã¯ã©ã¤ã¢ã³ãã®åªå
+åº¦
+ */
+
+#define DHCP4_CLI_MAIN_PRIORITY		5		/* DHCP ã¯ã©ã¤ã¢ã³ãã¿ã¹ã¯ã®åªå
+åº¦		*/
+
+/* æ¨å¥¨åº¦ã®å®ç¾© */
+#define DHCP4_CLI_CFG_PREFER_ADDR	100		/* ã¢ãã¬ã¹ã®æ¨å¥¨åº¦	*/
+
+/* DHCP ã¯ã©ã¤ã¢ã³ãã¡ãã»ã¼ã¸ã®åä¿¡ãªã¹ããµã¤ãºï¼2ä»¥ä¸æå®ãããã¨ï¼ */
+#define NUM_DHCP4_MSG_LIST		3
+
+/*
+ *  DHCP ã¯ã©ã¤ã¢ã³ãã¡ãã»ã¼ã¸æ§é ä½æ°ãå¤æ´ç¦æ­¢ã
+ *  +1 ã¯éä¿¡ç¨
+ */
+#define NUM_MPF_DHCP4_CLI_MSG		(NUM_DHCP4_MSG_LIST+1)
+
+/* 
+ *  ã³ã³ãã¤ã«æã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³
+ */
+
+/* DHCP å¿
+é ãªãã·ã§ã³ãªã¹ã */
+
+#ifndef DHCP4_CLI_CFG_REQUIRED_OLIST
+
+#define DHCP4_CLI_CFG_REQUIRED_OLIST {	\
+	DHCP4_OPT_SUBNET_MASK,		\
+	DHCP4_OPT_ROUTER,		\
+}
+
+#endif	/* of #ifndef DHCP4_CLI_CFG_REQUIRED_OLIST */
+
+/* DHCP è¦æ±ãªãã·ã§ã³ãªã¹ã */
+
+#ifndef DHCP4_CLI_CFG_REQUEST_OLIST
+
+#if defined(USE_RESOLVER)
+
+#define DHCP4_CLI_CFG_REQUEST_OLIST {	\
+	DHCP4_OPT_DNS_SERVER,		\
+	DHCP4_OPT_DOMAIN_NAME,		\
+}
+
+#endif	/* of #if defined(USE_RESOLVER) */
+
+#endif	/* of #ifndef DHCP4_CLI_CFG_REQUEST_OLIST */
+
+/*
+ *  ã¿ã¤ã ã¢ã¦ãå¤
+ */
+
+/* åä¿¡ã¿ã¤ã ã¢ã¦ã	*/
+#define TMO_DHCP4C_OFFER	ULONG_C(120*1000)	/* OFFER ã¡ãã»ã¼ã¸	*/
+#define TMO_DHCP4C_ACK		ULONG_C(60*1000)	/* ACK/NAK ã¡ãã»ã¼ã¸	*/
+
+/* ãªã¼ã¹æéã®æ¢å®å¤	*/
+#define TMO_DHCP4C_DEF_LEASE	ULONG_C(12*60*60*1000)	/* æ¨æºæé	*/
+#define TMO_DHCP4C_MIN_LEASE	ULONG_C(60*1000)	/* æå°æé	*/
+
+/* ã¡ãã»ã¼ã¸ã®éä¿¡å¨æ	*/
+#define TMO_DHCP4C_INIT_INTVL	ULONG_C(3*1000)		/* åæå¤	*/
+#define TMO_DHCP4C_MAX_BACKOFF	ULONG_C(15*1000)	/* å¶éå¤	*/
+
+/* DHCP ãµã¼ãã¸ã® UDP éä¿¡ã¿ã¤ã ã¢ã¦ã	*/
+#define TMO_DHCP4C_UDP_SND	ULONG_C(1000000)		/* [us] */
+
+/* ã¡ãã»ã¼ã¸æ§é ä½ç²å¾ã¿ã¤ã ã¢ã¦ã	*/
+#define TMO_DHCP4C_MPF_GET	ULONG_C(1000000)		/* [us] */
+
+/* ARP è¦æ±ãéä¿¡ãã¦ããã®å¾
+ã¡æé	*/
+#define TMO_DHCP4C_ARP_WAIT	ULONG_C(1000000)		/* [us] */
+
+/* RELEASE ã¡ãã»ã¼ã¸ãéä¿¡ãã¦ããã®å¾
+ã¡æé	*/
+#define TMO_DHCP4C_SND_REL_WAIT	ULONG_C(1000000)	/* [us] */
+
+/* DHCP ã§ã¢ãã¬ã¹ãæ´æ°ãããæã«å¼ã³åºãã³ã¼ã«ããã¯é¢æ° */
+#ifndef DHCP4_CLI_SET_ADDR_CALLBACK
+#define DHCP4_CLI_SET_ADDR_CALLBACK NULL
+#endif
+
+#ifndef _MACRO_ONLY
+
+#ifdef T_IPV4EP_DEFINED
+
+/*
+ *  DHCP ã¯ã©ã¤ã¢ã³ãã¡ãã»ã¼ã¸æ§é ä½
+ */
+
+typedef struct dhcp4_cli_msg {
+	/* 4ãã¤ãå¢çã«ã¢ã©ã¤ã³ããã*/
+	T_DHCP4_MSG		msg;		/* DHCP ã¡ãã»ã¼ã¸æ§é ä½	*/
+	struct dhcp4_cli_msg	*next;		/* ãªã¹ãã®æ¬¡ã®ã¡ãã»ã¼ã¸æ§é ä½	*/
+	T_IPV4EP		srv;		/* ãµã¼ãã®IPv4ã¢ãã¬ã¹/ãã¼ãçªå· */
+	uint16_t		len;		/* msg ã®æå¹é·			*/
+	uint16_t		prefer;		/* msg ã®æ¨å¥¨åº¦			*/
+	uint8_t			type;		/* ã¡ãã»ã¼ã¸ã¿ã¤ã		*/
+	} T_DHCP4_CLI_MSG;
+
+#endif	/*of #ifdef T_IPV4EP_DEFINED */
+
+/*
+ *  ã³ã¼ã«ããã¯é¢æ°
+ */
+
+extern ER callback_nblk_dhcp4_cli (ID cepid, FN fncd, void *p_parblk);
+
+/*
+ *  ã¿ã¹ã¯
+ */
+
+extern void	dhcp4_cli_task(intptr_t exinf);
+
+/*
+ *  é¢æ°
+ */
+
+#ifdef T_IN4_ADDR_DEFINED
+
+extern ER dhcp4c_rel_info (void);
+extern ER dhcp4c_renew_info (void);
+extern ER dhcp4c_get_info (T_IN4_ADDR *addr, uint32_t *expire, uint32_t *renew,
+                                             uint32_t *rebind, SYSTIM *bind_start);
+
+#endif	/* of #ifdef T_IN4_ADDR_DEFINED */
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#endif	/* of #ifndef DHCP4_CLI_H */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4_cli_asp.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4_cli_asp.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4_cli_asp.cfg	(revision 331)
@@ -0,0 +1,73 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ASP ç¨ DHCP ã¯ã©ã¤ã¢ã³ãã®ã·ã¹ãã ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ */
+
+/*
+ *  å
+±é DHCP ã¯ã©ã¤ã¢ã³ãã®ã·ã¹ãã ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«ã®ã¤ã³ã¯ã«ã¼ã
+ */
+
+#ifdef DHCP4_CLI_CFG
+
+INCLUDE("netapp/dhcp4_cli.cfg");
+
+/*
+ * åºå®ã¡ã¢ãªãã¼ã«
+ */
+
+/* éåä¿¡ãããã¡ */
+
+CRE_MPF(MPF_DHCP4_CLI_MSG, {
+	TA_TFIFO,
+	NUM_MPF_DHCP4_CLI_MSG,
+	sizeof(T_DHCP4_CLI_MSG),
+	NULL,
+	NULL
+	});
+
+#endif	/* of #ifdef DHCP4_CLI_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4_cli_jsp.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4_cli_jsp.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4_cli_jsp.cfg	(revision 331)
@@ -0,0 +1,72 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  JSP ç¨ DHCP ã¯ã©ã¤ã¢ã³ãã®ã·ã¹ãã ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ */
+
+/*
+ *  å
+±é DHCP ã¯ã©ã¤ã¢ã³ãã®ã·ã¹ãã ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«ã®ã¤ã³ã¯ã«ã¼ã
+ */
+
+#ifdef DHCP4_CLI_CFG
+
+#include "netapp/dhcp4_cli.cfg"
+
+/*
+ * åºå®ã¡ã¢ãªãã¼ã«
+ */
+
+/* éåä¿¡ãããã¡ */
+
+CRE_MPF(MPF_DHCP4_CLI_MSG, {
+	TA_TFIFO,
+	NUM_MPF_DHCP4_CLI_MSG,
+	sizeof(T_DHCP4_CLI_MSG),
+	NULL
+	});
+
+#endif	/* of #ifdef DHCP4_CLI_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4_cli_var.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4_cli_var.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp4_cli_var.h	(revision 331)
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2004 Henning Brauer <henning@openbsd.org>
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999
+ * The Internet Software Consortium.    All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ *    of its contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
+ * Enterprises.  To learn more about the Internet Software Consortium,
+ * see ``http://www.vix.com/isc''.  To learn more about Vixie
+ * Enterprises, see ``http://www.vix.com''.
+ *
+ * This client was substantially modified and enhanced by Elliot Poger
+ * for use on Linux while he was working on the MosquitoNet project at
+ * Stanford.
+ *
+ * The current version owes much to Elliot's Linux enhancements, but
+ * was substantially reorganized and partially rewritten by Ted Lemon
+ * so as to use the same networking framework that the Internet Software
+ * Consortium DHCP server uses.   Much system-specific configuration code
+ * was moved into a shell script so that as support for more operating
+ * systems is added, it will not be necessary to port and maintain
+ * system-specific configuration code to these operating systems - instead,
+ * the shell script can invoke the native tools to accomplish the same
+ * purpose.
+ */
+/*
+ * WIDE Project DHCP Implementation
+ * Copyright (c) 1995-1997 Akihiro Tominaga
+ * Copyright (c) 1995-1997 WIDE Project
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided the following conditions
+ * are satisfied,
+ *
+ * 1. Both the copyright notice and this permission notice appear in
+ *    all copies of the software, derivative works or modified versions,
+ *    and any portions thereof, and that both notices appear in
+ *    supporting documentation.
+ * 2. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by WIDE Project and
+ *      its contributors.
+ * 3. Neither the name of WIDE Project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND WIDE
+ * PROJECT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ALSO, THERE
+ * IS NO WARRANTY IMPLIED OR OTHERWISE, NOR IS SUPPORT PROVIDED.
+ *
+ * Feedback of the results generated from any improvements or
+ * extensions made to this software would be much appreciated.
+ * Any such feedback should be sent to:
+ * 
+ *  Akihiro Tominaga
+ *  WIDE Project
+ *  Keio University, Endo 5322, Kanagawa, Japan
+ *  (E-mail: dhcp-dist@wide.ad.jp)
+ *
+ * WIDE project has the rights to redistribute these changes.
+ */
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2011 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+ *      ã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+ *        å ±åãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef DHCP4_CLI_VAR_H
+#define DHCP4_CLI_VAR_H
+
+/*
+ *  DHCP ã¯ã©ã¤ã¢ã³ãã³ã³ãã­ã¹ãæ§é ä½
+ */
+
+/* TIMER ã®å®ç¾© */
+
+#define DHCP4C_TIMER_SND_DISC	0
+#define DHCP4C_TIMER_SND_REQ	1
+#define DHCP4C_TIMER_SND_REL	2
+#define DHCP4C_TIMER_RCV_OFFER	3
+#define DHCP4C_TIMER_RCV_ACK	4
+#define DHCP4C_TIMER_RENEW	5
+#define DHCP4C_TIMER_REBIND	6
+#define DHCP4C_TIMER_EXPIRE	7
+#define NUM_DHCP4C_TIMERS	8
+
+#define DHCP4C_TIMER_HZ		1
+
+typedef struct dhcp4_cli_context {
+	T_DHCP4_CLI_MSG	*rcv_lst;	/* åä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ã		*/
+	T_DHCP4_CLI_MSG	*val_lst;	/* æ¤è¨¼ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ã		*/
+	T_DHCP4_CLI_MSG	*prf_lst;	/* æ¨å¥¨ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ã		*/
+	T_DHCP4_CLI_MSG	*snd_msg;	/* éä¿¡ã¡ãã»ã¼ã¸æ§é ä½			*/
+	T_DHCP4_CLI_MSG	*off_msg;	/* éç¥ããããªã¼ã¹ã»ã¡ãã»ã¼ã¸æ§é ä½	*/
+	T_DHCP4_CLI_MSG	*act_msg;	/* æå¹ãªãªã¼ã¹ã»ã¡ãã»ã¼ã¸æ§é ä½	*/
+	T_IF_SOFTC	*sc;		/* IF ã®ã½ããã¦ã§ã¢æ
+å ±		*/
+	T_IPV4EP	dst;		/* éä¿¡å
+ã®IPã¢ãã¬ã¹/ãã¼ãçªå·	*/
+	SYSTIM		snd_start;	/* éä¿¡ãéå§ããæé			*/
+	SYSTIM		bind_start;	/* BINDãéå§ããæé			*/
+	SYSTIM		expire;		/* ãªã¼ã¹ã®æå¹æéï¼msï¼		*/
+	SYSTIM		renew;		/* RENEWï¼T1ï¼ã¾ã§ã®æéï¼msï¼	*/
+	SYSTIM		rebind;		/* REBINDï¼T2ï¼ã¾ã§ã®æéï¼msï¼	*/
+	SYSTIM		timers[NUM_DHCP4C_TIMERS];	
+					/* ã¿ã¤ãã¼é
+å			*/
+	RELTIM		interval;	/* éä¿¡éé			*/
+	ER_UINT		error;		/* ã¨ã©ã¼ã»ãã¼ã¿é·		*/
+	ID		cepid;		/* CEP ID			*/
+	uint32_t	xid;		/* ãã©ã³ã¶ã¯ã·ã§ã³ ID		*/
+	uint16_t	flags;		/* åç¨®ãã©ã°			*/
+	uint16_t	max_prefer;	/* åä¿¡ã¡ãã»ã¼ã¸ã®æå¤§æ¨å¥¨åº¦	*/
+	uint16_t	secs;		/* seconds since boot began	*/
+	uint8_t		fsm;		/* ç¾å¨ã®ç¶æ
+			*/
+	void (* set_addr_callback)();	/* ã¢ãã¬ã¹è¨­å®æã®ã³ã¼ã«ããã¯ */
+	} T_DHCP4_CLI_CONTEXT;
+
+/* fsmï¼ç¶æ
+é·ç§»ï¼ã®å®ç¾© */
+
+#define DHCP4_FSM_INIT		1
+#define DHCP4_FSM_SELECT	2
+#define DHCP4_FSM_REQUEST	3
+#define DHCP4_FSM_BOUND		4
+#define DHCP4_FSM_RENEW		5
+#define DHCP4_FSM_REBIND	6
+#define DHCP4_FSM_INIT_REBOOT	7
+#define DHCP4_FSM_REBOOT	8
+#define DHCP4_FSM_REL_INFO	11	/* DHCPv4 ã® RFC2131 ã«ã¯ç¡ãã*/
+#define DHCP4_FSM_SLEEP		12	/* DHCPv4 ã® RFC2131 ã«ã¯ç¡ãã*/
+
+/* flag ã®å®ç¾© */
+
+#define DHCP4C_FLAG_TMOUT_SND_DISC	(DHCP4C_FLAG_TMOUT_TIMER|DHCP4C_TIMER_SND_DISC)
+#define DHCP4C_FLAG_TMOUT_SND_REQ	(DHCP4C_FLAG_TMOUT_TIMER|DHCP4C_TIMER_SND_REQ)
+#define DHCP4C_FLAG_TMOUT_SND_REL	(DHCP4C_FLAG_TMOUT_TIMER|DHCP4C_TIMER_SND_REL)
+#define DHCP4C_FLAG_TMOUT_RCV_OFFER	(DHCP4C_FLAG_TMOUT_TIMER|DHCP4C_TIMER_RCV_OFFER)
+#define DHCP4C_FLAG_TMOUT_RCV_ACK	(DHCP4C_FLAG_TMOUT_TIMER|DHCP4C_TIMER_RCV_ACK)
+#define DHCP4C_FLAG_TMOUT_EXPIRE	(DHCP4C_FLAG_TMOUT_TIMER|DHCP4C_TIMER_EXPIRE)
+#define DHCP4C_FLAG_TMOUT_RENEW		(DHCP4C_FLAG_TMOUT_TIMER|DHCP4C_TIMER_RENEW)
+#define DHCP4C_FLAG_TMOUT_REBIND	(DHCP4C_FLAG_TMOUT_TIMER|DHCP4C_TIMER_REBIND)
+#define DHCP4C_FLAG_TMOUT_TIMER		UINT_C(0x0010)
+#define DHCP4C_FLAG_TMOUT_TIMER_MASK	UINT_C(0x000f)
+#define DHCP4C_FLAG_TMOUT_MASK		UINT_C(0x001f)
+
+#define DHCP4C_FLAG_RCV_MSG		UINT_C(0x0200)
+#define DHCP4C_FLAG_RENEW		UINT_C(0x0400)
+
+/*
+ *  é¢æ°ã·ãã¥ã¬ã¼ã·ã§ã³ãã¯ã­
+ */
+
+/* ã¿ã¤ã ã¢ã¦ãã®è¨ç® */
+
+#define DHCP4C_TMOC(t)		(((t)-1000)+dhcp_rand()%2000)
+
+/* æéæ¯è¼ */
+
+#define TIMEC_GT(a,b)		((int32_t)((a)-(b))>0)
+#define TIMEC_GE(a,b)		((int32_t)((a)-(b))>=0)
+
+/* æéå®æ°ã®å¤æ */
+
+#define SYSTIM2TIMER(t)		(((t)<SYSTIM_HZ/DHCP4C_TIMER_HZ)?(DHCP4C_TIMER_HZ):((t)*DHCP4C_TIMER_HZ)/SYSTIM_HZ)
+#define SYSTIM2SEC(t)		(((t)<SYSTIM_HZ)?1:((t)/SYSTIM_HZ))
+#define SEC2TIMER(t)		((t)*DHCP4C_TIMER_HZ)
+#define SEC2SYSTIM(t)		((t)*SYSTIM_HZ)
+
+#endif	/* of #ifndef DHCP4_CLI_VAR_H */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6.h	(revision 331)
@@ -0,0 +1,345 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+ *      ã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+ *        å ±åãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef DHCP6_H
+#define DHCP6_H
+
+/*
+ *  DHCPv6 ã«é¢ããå®ç¾©
+ *
+ *    RFC3315
+ */
+
+/*
+ *  DHCPv6 ã¡ãã»ã¼ã¸ã®å®æ°ã®å®ç¾©
+ */
+
+#define DHCP6_XID_LEN		3
+#define DHCP6_OPTION_LEN	(512-(1+DHCP6_XID_LEN))
+
+/*
+ *  DHCPv6 ã¡ãã»ã¼ã¸
+ */
+
+typedef struct dhcp6_msg_hdr {
+	uint8_t	type;				/* message type		*/
+	uint8_t	xid[DHCP6_XID_LEN];		/* transaction ID	*/
+	} T_DHCP6_MSG_HDR;
+
+typedef struct dhcp6_msg {
+	T_DHCP6_MSG_HDR	hdr;
+	uint8_t		options[DHCP6_OPTION_LEN];	/* options	*/
+	} T_DHCP6_MSG;
+
+/* message type ã®å®ç¾© */
+
+#define DHCP6_SOLICIT		UINT_C(1)
+#define DHCP6_ADVERTISE		UINT_C(2)
+#define DHCP6_REQUEST		UINT_C(3)
+#define DHCP6_CONFIRM		UINT_C(4)
+#define DHCP6_RENEW		UINT_C(5)
+#define DHCP6_REBIND		UINT_C(6)
+#define DHCP6_REPLY		UINT_C(7)
+#define DHCP6_RELEASE		UINT_C(8)
+#define DHCP6_DECLINE		UINT_C(9)
+#define DHCP6_RECONFIGURE	UINT_C(10)
+#define DHCP6_INFO_REQ		UINT_C(11)
+#define DHCP6_RELAY_FORW	UINT_C(12)
+#define DHCP6_RELAY_REPL	UINT_C(13)
+
+/*
+ *  DHCPv6 ãªãã·ã§ã³
+ */
+
+#define DHCP6_OPT_CLIENTID	UINT_C(1)
+#define DHCP6_OPT_SERVERID	UINT_C(2)
+#define DHCP6_OPT_IA_NA		UINT_C(3)
+#define DHCP6_OPT_IA_TA		UINT_C(4)
+#define DHCP6_OPT_IAADDR	UINT_C(5)
+#define DHCP6_OPT_ORO		UINT_C(6)
+#define DHCP6_OPT_PREFERENCE	UINT_C(7)
+#define DHCP6_OPT_UNICAST	UINT_C(12)
+#define DHCP6_OPT_STATUS_CODE	UINT_C(13)
+#define DHCP6_OPT_RAPID_COMMIT	UINT_C(14)
+#define DHCP6_OPT_NAME_SERVERS	UINT_C(23)
+#define DHCP6_OPT_DOMAIN_SEARCH	UINT_C(24)
+#define DHCP6_OPT_IA_PD		UINT_C(25)
+
+/* hardware address type ã®å®ç¾© */
+
+#define DHCP6_HWA_TYPE_ETHER	UINT_C(1)
+#define DHCP6_HWA_TYPE_IEEE802	UINT_C(6)
+
+/* STATUS CODE ã®å®ç¾© */
+
+#define DHCP6_STAT_SUCCESS	UINT_C(0)
+#define DHCP6_STAT_UNSPECIFID	UINT_C(1)
+#define DHCP6_STAT_NO_AVAIL	UINT_C(2)
+#define DHCP6_STAT_NO_BINDING	UINT_C(3)
+#define DHCP6_STAT_NO_ONLINK	UINT_C(4)
+#define DHCP6_STAT_USE_MCAST	UINT_C(5)
+
+/* æéå®æ°[s]ã®å®ç¾© */
+
+#define DHCP6_MAX_TIME		UINT_C(0xffffffff)
+
+/*
+ *  ãªãã·ã§ã³ã®ãããé¨ã®å®ç¾©
+ */
+
+/* ãªãã·ã§ã³ã®å
+±éé¨ */
+
+typedef struct dhcp6_option {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	} T_DHCP6_OPTION;
+
+/* ãªãã·ã§ã³ã®å
+±éé¨ */
+
+/* CLIENTID ãªãã·ã§ã³ */
+
+typedef struct dhcp6_opt_clientid {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	} T_DHCP6_OPT_CLIENTID;
+
+/* SERVERID ãªãã·ã§ã³ */
+
+typedef struct dhcp6_opt_serverid {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	} T_DHCP6_OPT_SERVERID;
+
+/* IA_NA/IA_PD ãªãã·ã§ã³ */
+
+typedef struct dhcp6_opt_ia_na_pd {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	uint32_t	iaid;		/* IA ID		*/
+	uint32_t	renew;		/* renew  timeout (T1)	*/
+	uint32_t	rebind;		/* rebind timeout (T2)	*/
+	} T_DHCP6_OPT_IA_NA_PD;
+
+/* IA_TA ãªãã·ã§ã³ */
+
+typedef struct dhcp6_opt_ia_ta {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	uint32_t	iaid;		/* IA ID		*/
+	} T_DHCP6_OPT_IA_TA;
+
+/* IAADDR ãªãã·ã§ã³ */
+
+#ifdef T_IN6_ADDR_DEFINED
+
+typedef struct dhcp6_opt_iaaddr {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	T_IN6_ADDR	addr;		/* IPv6 address		*/
+	uint32_t	prefer;		/* preferred lifetime	*/
+	uint32_t	valid;		/* valid     lifetime	*/
+	} T_DHCP6_OPT_IAADDR;
+
+#endif	/* of #ifdef T_IN6_ADDR_DEFINED */
+
+/* ORO ãªãã·ã§ã³ */
+
+typedef struct dhcp6_opt_oro {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	} T_DHCP6_OPT_ORO;
+
+/* PREFERENCE ãªãã·ã§ã³ */
+
+typedef struct dhcp6_opt_preference {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	uint8_t		prefer;		/* preference value	*/
+	} T_DHCP6_OPT_PREFERENCE;
+
+/* UNICAST ãªãã·ã§ã³ */
+
+#ifdef T_IN6_ADDR_DEFINED
+
+typedef struct dhcp6_opt_unicast {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	T_IN6_ADDR	addr;		/* IPv6 address for server*/
+	} T_DHCP6_OPT_UNICAST;
+
+#endif	/* of #ifdef T_IN6_ADDR_DEFINED */
+
+/* STATUS CODE ãªãã·ã§ã³ */
+
+typedef struct dhcp6_opt_status_code {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	uint16_t	status;		/* status code		*/
+	} T_DHCP6_OPT_STATUS_CODE;
+
+/* NAME SERVERS ãªãã·ã§ã³ */
+
+typedef struct dhcp6_opt_name_servers {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	T_IN6_ADDR	addrs[1];	/* IPv6 address		*/
+	} T_DHCP6_OPT_NAME_SERVERS;
+
+/* DOMAIN SEARCH ãªãã·ã§ã³ */
+
+typedef struct dhcp6_opt_domain_search {
+	uint16_t	code;		/* option code		*/
+	uint16_t	len;		/* option length	*/
+	uint8_t		name[1];	/* domain search	*/
+	} T_DHCP6_OPT_DOMAIN_SEARCH;
+
+/*
+ *  DHCPv6 ã¿ã¤ãã³ã°å®æ°ãRFC3315 5.5 åç
+§ã
+ *  ãã®ä»ã®ã¿ã¤ãã³ã°å®æ°ã¯ dhcp6_cli.h åç
+§
+ */
+
+#ifdef SYSTIM_HZ
+
+#define TMO_SOL_MAX_DELAY	(1*SYSTIM_HZ)	/*   1[s] 	*/
+#define TMO_SOL_TIMEOUT		(1*SYSTIM_HZ)	/*   1[s] 	*/
+#define TMO_SOL_MAX_RT		(120*SYSTIM_HZ)	/* 120[s] 	*/
+#define TMO_REQ_TIMEOUT		(1*SYSTIM_HZ)	/*   1[s] 	*/
+#define TMO_REQ_MAX_RT		(30*SYSTIM_HZ)	/*  30[s] 	*/
+#define TMO_REQ_MAX_RC		10		/* åéä¿¡åæ°	*/
+#define TMO_CNF_MAX_DELAY	(1*SYSTIM_HZ)	/*   1[s] 	*/
+#define TMO_CNF_TIMEOUT		(1*SYSTIM_HZ)	/*   1[s] 	*/
+#define TMO_CNF_MAX_RT		(4*SYSTIM_HZ)	/*   4[s] 	*/
+#define TMO_CNF_MAX_RD		(10*SYSTIM_HZ)	/*  10[s] 	*/
+#define TMO_REN_TIMEOUT		(10*SYSTIM_HZ)	/*  10[s] 	*/
+#define TMO_REN_MAX_RT		(600*SYSTIM_HZ)	/* 600[s] 	*/
+#define TMO_REB_TIMEOUT		(10*SYSTIM_HZ)	/*  10[s] 	*/
+#define TMO_REB_MAX_RT		(600*SYSTIM_HZ)	/* 600[s] 	*/
+#define TMO_INF_MAX_DELAY	(1*SYSTIM_HZ)	/*   1[s] 	*/
+#define TMO_INF_TIMEOUT		(1*SYSTIM_HZ)	/*   1[s] 	*/
+#define TMO_INF_MAX_RT		(120*SYSTIM_HZ)	/* 120[s] 	*/
+#define TMO_REL_TIMEOUT		(1*SYSTIM_HZ)	/*   1[s] 	*/
+#define TMO_REL_MAX_RC		5		/* åéä¿¡åæ°	*/
+#define TMO_DEC_TIMEOUT		(1*SYSTIM_HZ)	/*   1[s] 	*/
+#define TMO_DEC_MAX_RC		5		/* åéä¿¡åæ°	*/
+#define TMO_REC_TIMEOUT		(2*SYSTIM_HZ)	/*   2[s] 	*/
+#define TMO_REC_MAX_RC		8		/* åéä¿¡åæ°	*/
+
+#endif	/* of #ifdef SYSTIM_HZ */
+
+/*
+ *  DUID -- DHCP Unique ID
+ */
+
+/* DUID_LLT æ§é ä½ */
+
+typedef struct dhcp6_duid_llt_hdr {
+	uint16_t	code;		/* DUID code		*/
+	uint16_t	type;		/* hardware type	*/
+	uint32_t	time;		/* time			*/
+	} T_DHCP6_DUID_LLT_HDR;
+
+/* DUID_LL æ§é ä½ */
+
+typedef struct dhcp6_duid_ll_hdr {
+	uint16_t	code;		/* DUID code		*/
+	uint16_t	type;		/* hardware type	*/
+	} T_DHCP6_DUID_LL_HDR;
+
+/* DUID ã¿ã¤ããRFC3315 9åç
+§ã*/
+
+#define DUID_LLT		1
+#define DUID_EN			2
+#define DUID_LL			3
+
+/*
+ *  DUID æéã®èª¿æ´
+ *  DUID æéã®éå§ã¯ 2001/1/1
+ */
+
+#define DUID_TIME_EPOCH		0
+
+/* ãªã¬ã¼è»¢éã®æå¤§ãããæ° */
+
+#define HOP_COUNT_LIMIT		32
+
+/*
+ *  IPv6 ã¢ãã¬ã¹
+ */
+
+#define IPV6_ADDR_ALL_DHCP_RELAY_SERVERS_INIT	\
+	{{{ UINT_C(0xff), UINT_C(0x02), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x01), UINT_C(0x00), UINT_C(0x02) }}}
+
+#define IPV6_ADDR_ALL_DHCP_SERVERS_INIT	\
+	{{{ UINT_C(0xff), UINT_C(0x05), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), UINT_C(0x00), \
+	    UINT_C(0x00), UINT_C(0x01), UINT_C(0x00), UINT_C(0x03) }}}
+
+/*
+ *  UDP ãã¼ãçªå·
+ */
+
+#ifndef DHCP6_SRV_CFG_PORTNO
+#define DHCP6_SRV_CFG_PORTNO	547	/* server	*/
+#endif
+
+#ifndef DHCP6_CLI_CFG_PORTNO
+#define DHCP6_CLI_CFG_PORTNO	546	/* client	*/
+#endif
+
+#endif	/* of #ifndef DHCP6_H */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6_cli.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6_cli.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6_cli.c	(revision 331)
@@ -0,0 +1,3338 @@
+/*
+ * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1995-2003 by Internet Software Consortium
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ *   Internet Systems Consortium, Inc.
+ *   950 Charter Street
+ *   Redwood City, CA 94063
+ *   <info@isc.org>
+ *   https://www.isc.org/
+ *
+ * This code is based on the original client state machine that was
+ * written by Elliot Poger.  The code has been extensively hacked on
+ * by Ted Lemon since then, so any mistakes you find are probably his
+ * fault and not Elliot's.
+ */
+/*
+ * WIDE Project DHCP Implementation
+ * Copyright (c) 1995-1997 Akihiro Tominaga
+ * Copyright (c) 1995-1997 WIDE Project
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided the following conditions
+ * are satisfied,
+ *
+ * 1. Both the copyright notice and this permission notice appear in
+ *    all copies of the software, derivative works or modified versions,
+ *    and any portions thereof, and that both notices appear in
+ *    supporting documentation.
+ * 2. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by WIDE Project and
+ *      its contributors.
+ * 3. Neither the name of WIDE Project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND WIDE
+ * PROJECT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ALSO, THERE
+ * IS NO WARRANTY IMPLIED OR OTHERWISE, NOR IS SUPPORT PROVIDED.
+ *
+ * Feedback of the results generated from any improvements or
+ * extensions made to this software would be much appreciated.
+ * Any such feedback should be sent to:
+ * 
+ *  Akihiro Tominaga
+ *  WIDE Project
+ *  Keio University, Endo 5322, Kanagawa, Japan
+ *  (E-mail: dhcp-dist@wide.ad.jp)
+ *
+ * WIDE project has the rights to redistribute these changes.
+ */
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2011 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+ *      ã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+ *        å ±åãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
+#include <net/net_timer.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/in_itron.h>
+
+#include <net/if_var.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/dhcp6_cli.h>
+#include <netapp/dhcp6_cli_var.h>
+#include <netapp/resolver.h>
+
+/*
+ *  DHCPv6 ã¯ã©ã¤ã¢ã³ãã¿ã¹ã¯
+ */
+
+#ifdef DHCP6_CLI_CFG
+
+/*
+ *  DHCP åä½ã¢ã¼ã
+ *
+ *    #define DHCP6_CLI_CFG_MODE ã§æå®ããã
+ *
+ */
+
+#if !defined(DHCP6_CLI_CFG_MODE)
+#define DHCP6_CLI_CFG_MODE	DHCP6_CLI_CFG_MODE_DEFAULT
+#endif
+
+/*
+ *  å¤æ°
+ */
+
+static const T_IN6_ADDR in6_addr_all_DHCP_relay_servers =
+	IPV6_ADDR_ALL_DHCP_RELAY_SERVERS_INIT;			/* ãªã¬ã¼ã»ãµã¼ãã® IPv6 ã¢ãã¬ã¹	*/
+static T_DHCP6_CLI_CONTEXT	context;			/* ã¯ã©ã¤ã¢ã³ãã³ã³ãã­ã¹ã	*/
+
+#ifdef DHCP6_CLI_CFG_REQUIRED_OLIST
+static uint8_t	required_plist[] = DHCP6_CLI_CFG_REQUIRED_OLIST;	/* å¿
+é ãªãã·ã§ã³ãªã¹ã		*/
+#endif
+
+#ifdef DHCP6_CLI_CFG_REQUEST_OLIST
+static uint8_t	request_plist[] = DHCP6_CLI_CFG_REQUEST_OLIST;		/* è¦æ±ãªãã·ã§ã³ãªã¹ã		*/
+#endif
+
+/*
+ *  dhcp6_rand -- RFC3315 ã«è¦å®ãããä¹±æ°ãçºçããã
+ */
+
+static int32_t
+dhcp6_rand (SYSTIM base)
+{
+	SYSTIM 		range, split;
+	uint32_t	rval;
+
+	split = (base - 1) / 10;
+	if (split == 0)
+		return 0;
+	range = (split * 2) + 10;
+	rval = netapp_rand() % range - split;
+
+	return rval;
+	}
+
+/*
+ *  init_duid -- ã¯ã©ã¤ã¢ã³ãã® DUID ãè¨­å®ããã
+ */
+
+static void
+init_duid (T_DHCP6_CLI_CONTEXT *ct)
+{
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS
+
+	/* åä½ã¢ã¼ãã« STATELESS ãæå®ãããæã¯ LL å½¢å¼ã«ããã*/
+
+	T_DHCP6_DUID_LL_HDR	*ll;
+
+	ll = (T_DHCP6_DUID_LL_HDR*)&ct->duid[0];
+	HOST2MSG16(ll->code, DUID_LL);
+	HOST2MSG16(ll->type, DHCP6_HWA_TYPE_ETHER);
+	memcpy(&ct->duid[sizeof(*ll)], &ct->sc->ifaddr.lladdr, sizeof(ct->sc->ifaddr.lladdr));
+	ct->duid_len = sizeof(*ll) + sizeof(ct->sc->ifaddr.lladdr);	/* DIUD é·ãè¨é²ããã*/
+
+#elif DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+
+	/*
+	 *    åä½ã¢ã¼ãã« DHCP6_CLI_CFG_STATEFULL ãæå®ãããæã¯ LLT å½¢å¼ã«ããã
+	 *    time ã¡ã³ãã¼ã«ã¯ç¾å¨ã®æé[s]ãè¨­å®ããã
+	 *    æ³¨æ: æ«å®çã« get_tim() ã®å¤ãä½¿ãããè¦æ¤è¨
+	 */
+
+	T_DHCP6_DUID_LLT_HDR	*llt;
+	SYSTIM			time;
+
+	get_tim(&time);
+	time = SYSTIM2SEC(time) - DUID_TIME_EPOCH;
+	llt = (T_DHCP6_DUID_LLT_HDR*)&ct->duid[0];
+	HOST2MSG16(llt->code, DUID_LLT);
+	HOST2MSG16(llt->type, DHCP6_HWA_TYPE_ETHER);
+	HOST2MSG32(llt->time, time);
+	memcpy(&ct->duid[sizeof(*llt)], &ct->sc->ifaddr.lladdr, sizeof(ct->sc->ifaddr.lladdr));
+	ct->duid_len = sizeof(*llt) + sizeof(ct->sc->ifaddr.lladdr);	/* DIUD é·ãè¨é²ããã*/
+
+#else	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS */
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS */
+
+	}
+
+/*
+ *  cancel_all_timers -- å
+¨ã¦ã® TIMER ãã­ã£ã³ã»ã«ããã
+ */
+
+static void
+cancel_all_timers (T_DHCP6_CLI_CONTEXT *ct)
+{
+	int ix;
+
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	for (ix = NUM_DHCP6C_TIMERS; ix -- > 0; )
+		ct->timers[ix] = 0;
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+	}
+
+/*
+ *  dhcpc_timer -- TIMER ç®¡ç
+ */
+
+static void
+dhcpc_timer (T_DHCP6_CLI_CONTEXT *ct)
+{
+	int ix;
+
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	for (ix = NUM_DHCP6C_TIMERS; ix -- > 0; ) {
+		if (ct->timers[ix] != 0) {
+			ct->timers[ix] --;
+			if (ct->timers[ix] == 0) {
+				ct->flags = (ct->flags & ~DHCP6C_FLAG_TMOUT_MASK) | DHCP6C_FLAG_TMOUT_TIMER | ix;
+				syscall(sig_sem(SEM_DHCP6_CLI_READY));
+				}
+			}
+		}
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/* 1ç§æ¯ã«ã¿ã¤ã ã¢ã¦ãããã*/
+	timeout((callout_func)dhcpc_timer, ct, NET_TIMER_HZ / DHCP6C_TIMER_HZ);
+	}
+
+/*
+ *  find_option -- æå®ãããªãã·ã§ã³ãæ¢ç´¢ããã
+ *
+ *    æ³¨æ: å¼æ° len ã 0 ã®æã¯ãªãã·ã§ã³ãµã¤ãºãæ¤è¨¼ããªãã
+ *          å¼æ° len ã«ã¯ãªãã·ã§ã³å
+¨ä½ã®ãµã¤ãºãæå®ãããã¨ã
+ */
+
+static uint8_t *
+find_option (uint8_t *msg, uint_t msg_len, uint_t code, uint_t len)
+{
+	T_DHCP6_OPTION	*hdr;
+	uint8_t		*last;
+
+	last = msg + msg_len;
+	while (msg < last) {
+		hdr = (T_DHCP6_OPTION*)msg;
+		if (MSG2HOST16(hdr->code) == code && (len == 0 || (MSG2HOST16(hdr->len) + sizeof(*hdr)) == len))
+			return msg;
+		else
+			msg += MSG2HOST16(hdr->len) + sizeof(*hdr);
+		}
+	return NULL;
+	}
+
+/*
+ *  find_msg_option -- æå®ãããªãã·ã§ã³ãæ¢ç´¢ããã
+ *
+ *    æ³¨æ: å¼æ° len ã 0 ã®æã¯ãªãã·ã§ã³ãµã¤ãºãæ¤è¨¼ããªãã
+ *          å¼æ° len ã«ã¯ãªãã·ã§ã³å
+¨ä½ã®ãµã¤ãºãæå®ãããã¨ã
+ */
+
+static uint8_t *
+find_msg_option (T_DHCP6_CLI_MSG *cli_msg, uint_t code, uint_t len)
+{
+	return find_option(cli_msg->msg.options, cli_msg->len, code, len);
+	}
+
+/*
+ *  is_equal_sid -- ã¡ãã»ã¼ã¸å
+ã® SERVER ID ãæ¯è¼ããã
+ */
+
+static bool_t
+is_equal_sid (T_DHCP6_CLI_MSG *msg1, T_DHCP6_CLI_MSG *msg2)
+{
+	T_DHCP6_OPT_SERVERID	*sid1;
+	T_DHCP6_OPT_SERVERID	*sid2;
+
+	if ((sid1 = (T_DHCP6_OPT_SERVERID*)find_msg_option(msg1, DHCP6_OPT_SERVERID, 0)) == NULL)
+		return false;
+	if ((sid2 = (T_DHCP6_OPT_SERVERID*)find_msg_option(msg2, DHCP6_OPT_SERVERID, 0)) == NULL)
+		return false;
+	if (MSG2HOST16(sid1->len) != MSG2HOST16(sid2->len))
+		return false;
+
+	return memcmp((uint8_t*)sid1 + sizeof(*sid1),
+	              (uint8_t*)sid2 + sizeof(*sid2), MSG2HOST16(sid1->len)) == 0;
+	}
+
+/*
+ *  validate_iaaddrs -- ã¢ãã¬ã¹æ
+å ±ï¼IAADDRï¼ãæ¤è¨¼ããã
+ */
+
+static ER
+validate_iaaddrs (uint8_t *opt, uint_t len)
+{
+	T_DHCP6_OPT_IAADDR	*iaa;
+
+	/* ãªãã·ã§ã³ã IAADDR ã§ãããã¨ãæ¤è¨¼ããã*/
+	iaa = (T_DHCP6_OPT_IAADDR*)opt;
+	if (MSG2HOST16(iaa->code) != DHCP6_OPT_IAADDR)
+		return E_PAR;
+
+	while (len > 0) {
+		/* ãªãã·ã§ã³é·ãæ¤è¨¼ããã*/
+		if (len < sizeof(*iaa))
+			return E_PAR;
+
+		/* ãªãã·ã§ã³é·ã T_DHCP6_OPT_IAADDR ã®ãµã¤ãºã¨ä¸è´ãã¦ããªããã°ã¨ã©ã¼ */
+		iaa = (T_DHCP6_OPT_IAADDR*)opt;
+		if ((MSG2HOST16(iaa->len) & ~DHCP6C_IAA_FLAG_MASK) < (sizeof(*iaa) - sizeof(T_DHCP6_OPTION)))
+			return E_PAR;
+
+		/*
+		 *  perferred-lifetime ã¨ valid-lifetime ã®å¤ãçç¾ãã¦ããã¨ãã¯ã¨ã©ã¼
+		 *  ãRFC3315 (22.6) åç
+§ã
+		 */
+		if (MSG2HOST32(iaa->prefer) > MSG2HOST32(iaa->valid))
+			return E_PAR;
+
+		len -= (MSG2HOST16(iaa->len) & ~DHCP6C_IAA_FLAG_MASK) + sizeof(T_DHCP6_OPTION);
+		opt += (MSG2HOST16(iaa->len) & ~DHCP6C_IAA_FLAG_MASK) + sizeof(T_DHCP6_OPTION);
+		}
+
+	return E_OK;
+	}
+
+/*
+ *  validate_ia_na_pd -- IA_NA/IA_PD ãªãã·ã§ã³ãæ¤è¨¼ããã
+ */
+
+static ER
+validate_ia_na_pd (T_DHCP6_CLI_MSG *msg, uint16_t code)
+{
+	T_DHCP6_OPT_IA_NA_PD	*na;
+	uint8_t			*opt;
+
+	/* IA_NA/IA_PD ãç¡ããã°æ¤è¨¼ããªãã*/
+	if ((opt = find_msg_option(msg, code, 0)) == NULL)
+		return E_OK;
+
+	/* ãªãã·ã§ã³é·ãæ¤è¨¼ããã*/
+	na = (T_DHCP6_OPT_IA_NA_PD*)opt;
+	if (!(msg->len >= (opt - (uint8_t*)&msg->msg) + sizeof(*na) &&
+	                         (MSG2HOST16(na->len) & ~DHCP6C_IAA_FLAG_MASK) >= sizeof(*na)))
+		return E_PAR;
+
+	/*
+	 *  T1 ã¨ T2 ã®å¤ãçç¾ãã¦ããæãã¾ãã¯ã¢ãã¬ã¹æ
+å ±ãèª¤ã£ã¦ããæã¯ã¨ã©ã¼
+	 *  ãRFC3315 (22.4) åç
+§ã
+	 */
+	if (MSG2HOST32(na->renew) > 0 && MSG2HOST32(na->rebind) > 0 &&
+	    MSG2HOST32(na->renew) >      MSG2HOST32(na->rebind))
+		return E_PAR;
+
+	if (validate_iaaddrs(opt + sizeof(*na), (MSG2HOST16(na->len) & ~DHCP6C_IAA_FLAG_MASK) - (sizeof(*na) - sizeof(T_DHCP6_OPTION))) != E_OK)
+		return E_PAR;
+
+	return E_OK;
+	}
+
+/*
+ *  validate_ia_ta -- IA_TA ãªãã·ã§ã³ãæ¤è¨¼ããã
+ */
+
+static ER
+validate_ia_ta (T_DHCP6_CLI_MSG *msg)
+{
+	T_DHCP6_OPT_IA_TA	*ta;
+	uint8_t			*opt;
+
+	/* IA_TA ãç¡ããã°æ¤è¨¼ããªãã*/
+	if ((opt = find_msg_option(msg, DHCP6_OPT_IA_TA, 0)) == NULL)
+		return E_OK;
+
+	/* ãªãã·ã§ã³é·ãæ¤è¨¼ããã*/
+	ta = (T_DHCP6_OPT_IA_TA	*)opt;
+	if (!(msg->len >= (opt - (uint8_t*)&msg->msg) + sizeof(*ta) &&
+	                         (MSG2HOST16(ta->len) & ~DHCP6C_IAA_FLAG_MASK) >= sizeof(*ta)))
+		return E_PAR;
+
+	/*
+	 *  ã¢ãã¬ã¹æ
+å ±ãèª¤ã£ã¦ããæã¯ã¨ã©ã¼ãRFC3315 (22.4) åç
+§ã
+	 */
+	if (validate_iaaddrs(opt + sizeof(*ta), (MSG2HOST16(ta->len) & ~DHCP6C_IAA_FLAG_MASK) - (sizeof(*ta) - sizeof(T_DHCP6_OPTION))) != E_OK)
+		return E_PAR;
+
+	return E_OK;
+	}
+/*
+ *  classify_reply -- å¿ç­ã¡ãã»ã¼ã¸ãåé¡ããã
+ */
+
+static ER
+classify_reply (T_DHCP6_CLI_MSG *msg)
+{
+	ER	error;
+
+	/* IA_NA ãªãã·ã§ã³ãæ¤è¨¼ããã*/
+	if ((error = validate_ia_na_pd(msg, DHCP6_OPT_IA_NA)) != E_OK)
+		return error;
+
+	/* IA_TA ãªãã·ã§ã³ãæ¤è¨¼ããã*/
+	if ((error = validate_ia_ta(msg)) != E_OK)
+		return error;
+
+	/* IA_PD ãªãã·ã§ã³ãæ¤è¨¼ããã*/
+	if ((error = validate_ia_na_pd(msg, DHCP6_OPT_IA_PD)) != E_OK)
+		return error;
+
+	/* ãµã¼ã DUID ããããã¨ãæ¤è¨¼ããã*/
+	if (find_msg_option(msg, DHCP6_OPT_SERVERID, 0) == NULL)
+		return E_PAR;
+
+	return E_OK;
+	}
+
+/*
+ *  validate_reply -- å¿ç­ã¡ãã»ã¼ã¸ãæ¤è¨¼ããã
+ */
+
+static ER
+validate_reply (T_DHCP6_CLI_CONTEXT *ct, T_DHCP6_CLI_MSG *msg)
+{
+	T_DHCP6_OPT_CLIENTID	*cid;
+	uint8_t			*opt;
+
+	/* ãµã¼ã DUID ããããã¨ãæ¤è¨¼ããã*/
+	if (find_msg_option(msg, DHCP6_OPT_SERVERID, 0) == NULL)
+		return E_PAR;
+
+	/* ã¯ã©ã¤ã¢ã³ã DUID ããããèªåã®ã¯ã©ã¤ã¢ã³ã DUID ã¨åããã¨ãæ¤è¨¼ããã*/
+	if ((opt = find_msg_option(msg, DHCP6_OPT_CLIENTID, 0)) == NULL)
+		return E_PAR;
+
+	cid = (T_DHCP6_OPT_CLIENTID*)opt;
+	if (MSG2HOST16(cid->len) != ct->duid_len)
+		return E_PAR;
+	if (memcmp(opt + sizeof(*cid), ct->duid, ct->duid_len) != 0)
+		return E_PAR;
+
+	return E_OK;
+	}
+
+/*
+ *  get_status_code -- STATUS ãªãã·ã§ã³ã®çµæã³ã¼ããç²å¾ããã
+ */
+
+static ER_UINT
+get_status_code (uint8_t *msg, uint_t msg_len)
+{
+	T_DHCP6_OPT_STATUS_CODE	*status;
+	uint8_t			*opt;
+
+	/* STATUS ãªãã·ã§ã³ãç¡ããã°æ¤è¨¼ããªãã*/
+	if ((opt = find_option(msg, msg_len, DHCP6_OPT_STATUS_CODE, 0)) == NULL)
+		return DHCP6_STAT_SUCCESS;
+
+	/* ãªãã·ã§ã³é·ãæ¤è¨¼ããã*/
+	status = (T_DHCP6_OPT_STATUS_CODE*)opt;
+	if (msg_len < sizeof(*status))
+		return E_PAR;
+	if (MSG2HOST16(status->len) < sizeof(*status) - sizeof(T_DHCP6_OPTION))
+		return E_PAR;
+
+	return MSG2HOST16(status->status);
+	}
+
+/*
+ *  get_msg_status_code -- STATUS ãªãã·ã§ã³ã®çµæã³ã¼ããç²å¾ããã
+ */
+
+static ER_UINT
+get_msg_status_code (T_DHCP6_CLI_MSG *cli_msg, uint_t *code)
+{
+	T_DHCP6_OPTION		*opt;
+	T_DHCP6_OPT_IA_NA_PD	*ia;
+	T_DHCP6_OPT_IA_TA	*ta;
+	ER_UINT			status;
+	uint8_t			*msg, *last;
+
+	*code = 0;
+	cli_msg->status = DHCP6_CLI_STAT_UNDEFINED;
+	if ((status = get_status_code(cli_msg->msg.options, cli_msg->len)) == DHCP6_STAT_SUCCESS) {
+
+		msg = cli_msg->msg.options;
+		last = msg + (cli_msg->len - sizeof(T_DHCP6_MSG_HDR));
+		while (msg < last) {
+
+			opt = (T_DHCP6_OPTION*)msg;
+			status = get_status_code(msg + sizeof(*opt), MSG2HOST16(opt->len));
+			if (status != DHCP6_STAT_SUCCESS) {
+				*code = MSG2HOST16(opt->code);
+				break;
+				}
+
+			if (MSG2HOST16(opt->code) == DHCP6_OPT_IA_NA || MSG2HOST16(opt->code) == DHCP6_OPT_IA_PD) {
+
+				ia = (T_DHCP6_OPT_IA_NA_PD*)opt;
+				status = get_status_code(msg + sizeof(*opt), MSG2HOST16(ia->len));
+				if (status != DHCP6_STAT_SUCCESS) {
+					*code = MSG2HOST16(((T_DHCP6_OPTION*)((uint8_t*)opt + sizeof(*opt)))->code);
+					break;
+					}
+				}
+
+			else if (MSG2HOST16(opt->code) == DHCP6_OPT_IA_TA) {
+
+				ta = (T_DHCP6_OPT_IA_TA*)opt;
+				status = get_status_code(msg + sizeof(*opt), MSG2HOST16(ta->len));
+				if (status != DHCP6_STAT_SUCCESS) {
+					*code = MSG2HOST16(((T_DHCP6_OPTION*)((uint8_t*)opt + sizeof(*opt)))->code);
+					break;
+					}
+				}
+
+			msg += MSG2HOST16(opt->len) + sizeof(*opt);
+			}
+		cli_msg->status = status;
+		}
+	
+	return status;
+	}
+
+/*
+ *  validate_rcv_msg -- åä¿¡ã¡ãã»ã¼ã¸ãæ¤è¨¼ããã
+ */
+
+static ER
+validate_rcv_msg (T_DHCP6_CLI_CONTEXT *ct, T_DHCP6_CLI_MSG *msg)
+{
+	ER	error;
+	uint_t	code;
+
+	/* ã¡ãã»ã¼ã¸ã®ã¿ã¤ããä¸è´ãã¦ãããã¨ãæ¤è¨¼ããã*/
+	switch (ct->fsm) {
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA
+
+	case DHCP6_FSM_SELECT:
+		if (msg->msg.hdr.type != DHCP6_REPLY)
+			return E_PAR;
+		break;
+	case DHCP6_FSM_INFORMED:
+		return E_PAR;
+		break;
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA */
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA
+
+	case DHCP6_FSM_INIT:
+		if (msg->msg.hdr.type != DHCP6_ADVERTISE)
+			return E_PAR;
+		break;
+
+	case DHCP6_FSM_SELECT:
+	case DHCP6_FSM_RENEW:
+	case DHCP6_FSM_REBIND:
+	case DHCP6_FSM_REL_INFO:
+		if (msg->msg.hdr.type != DHCP6_REPLY)
+			return E_PAR;
+		break;
+
+	case DHCP6_FSM_BOUND:
+		return E_PAR;
+		break;
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA */
+
+	default:
+		syslog(LOG_NOTICE, "[DHCP6C] error, unknown state: %d.", ct->fsm);
+		return E_PAR;
+		break;
+		}
+
+	/* åä¿¡ã¡ãã»ã¼ã¸ãæ¤è¨¼ããã*/
+	if ((error = validate_reply(ct, msg)) != E_OK)
+		return error;
+
+	/* åä¿¡ã¡ãã»ã¼ã¸ãåé¡ããã*/
+	if ((error = classify_reply(msg)) != E_OK)
+		return error;
+
+	/* åä¿¡ããã¡ãã»ã¼ã¸å
+ã® STATUS CODE ãªãã·ã§ã³ãæ¤è¨¼ããã*/
+	error = get_msg_status_code(msg, &code);
+	if (error != E_OK)
+		return error > 0 ? E_PAR : error;
+
+	return E_OK;
+	}
+
+/*
+ *  eval_ia_prefer -- IA_NA/IA_TA/IA_PD ã®æ¨å¥¨åº¦ãè©ä¾¡ããã
+ */
+
+static void
+eval_ia_prefer (T_DHCP6_CLI_MSG *cli_msg)
+{
+	T_DHCP6_OPTION		*opt;
+	T_DHCP6_OPT_IA_NA_PD	*ia;
+	T_DHCP6_OPT_IA_TA	*ta;
+	T_DHCP6_OPT_IAADDR	*iaa;
+	uint8_t		*msg, *last;
+	uint_t		aoff, asize;
+
+	/* ç¡å¹ã®å ´åã¯çµäºããã*/
+	if (cli_msg == NULL)
+		return;
+
+	msg = cli_msg->msg.options;
+	last = msg + (cli_msg->len - sizeof(T_DHCP6_MSG_HDR));
+	while (msg < last) {
+		opt = (T_DHCP6_OPTION*)msg;
+
+		if (MSG2HOST16(opt->code) == DHCP6_OPT_IA_NA || MSG2HOST16(opt->code) == DHCP6_OPT_IA_PD) {
+
+			ia = (T_DHCP6_OPT_IA_NA_PD*)opt;
+			aoff  = sizeof(*ia);
+			asize = MSG2HOST16(ia->len) + sizeof(*opt);
+			while (aoff < asize) {
+				cli_msg->prefer += DHCP6_CLI_CFG_PREFER_IAADDR;
+				iaa = (T_DHCP6_OPT_IAADDR*)((uint8_t*)opt + aoff);
+				aoff += (MSG2HOST16(iaa->len) & ~DHCP6C_IAA_FLAG_MASK) + sizeof(*iaa);
+				}
+			cli_msg->prefer = (cli_msg->prefer + DHCP6_CLI_CFG_PREFER_IA) | DHCP6_ClI_MSG_PREFER_ADDR;
+			}
+
+		else if (MSG2HOST16(opt->code) == DHCP6_OPT_IA_TA) {
+
+			ta = (T_DHCP6_OPT_IA_TA*)opt;
+			aoff  = sizeof(*ta);
+			asize = MSG2HOST16(ta->len) + sizeof(*opt);
+			while (aoff < asize) {
+				cli_msg->prefer += DHCP6_CLI_CFG_PREFER_IAADDR;
+				iaa = (T_DHCP6_OPT_IAADDR*)((uint8_t*)opt + aoff);
+				aoff += (MSG2HOST16(iaa->len) & ~DHCP6C_IAA_FLAG_MASK) + sizeof(*iaa);
+				}
+			cli_msg->prefer = (cli_msg->prefer + DHCP6_CLI_CFG_PREFER_IA) | DHCP6_ClI_MSG_PREFER_ADDR;
+			}
+
+		msg += MSG2HOST16(opt->len) + sizeof(*opt);
+		}
+
+	}
+
+/*
+ *  eval_prefer -- åä¿¡ã¡ãã»ã¼ã¸ã®æ¨å¥¨åº¦ãè©ä¾¡ããã
+ */
+
+static void
+eval_prefer (T_DHCP6_CLI_MSG *msg)
+{
+	uint8_t			*opt;
+	int			ix;
+
+	/* ç¡å¹ã®å ´åã¯çµäºããã*/
+	if (msg == NULL)
+		return;
+
+	/* PREFERENCE ãªãã·ã§ã³ãè©ä¾¡ããã*/
+	if ((opt = find_msg_option(msg, DHCP6_OPT_PREFERENCE, sizeof(T_DHCP6_OPT_PREFERENCE))) != NULL)
+		msg->prefer = MSG2HOST16(((T_DHCP6_OPT_PREFERENCE*)opt)->prefer) | DHCP6_ClI_MSG_PREFER_OPTION;
+	else
+		msg->prefer = 1;
+
+#if defined(DHCP6_CLI_CFG_REQUIRED_OLIST)
+
+	/* å¿
+é ãªãã·ã§ã³ãæ¤è¨¼ããã*/
+	for (ix = sizeof(required_plist); ix -- > 0; ) {
+		if (find_msg_option(msg, required_plist[ix], 0) == NULL)
+			msg->prefer = 0;
+		}
+	msg->prefer |= DHCP6_ClI_MSG_PREFER_REQUIRED;
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_REQUIRED_OLIST) */
+
+#if defined(DHCP6_CLI_CFG_REQUEST_OLIST)
+
+	/* è¦æ±ãªãã·ã§ã³ãæ¤è¨¼ããã*/
+	for (ix = sizeof(request_plist); ix -- > 0; ) {
+		if (find_msg_option(msg, request_plist[ix], 0) != NULL)
+			msg->prefer = (msg->prefer + 1) | DHCP6_ClI_MSG_PREFER_REQUEST;
+		}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_REQUEST_OLIST) */
+	}
+
+/*
+ *  eval_rcv_msg -- åä¿¡ã¡ãã»ã¼ã¸ãè©ä¾¡ããã
+ */
+
+static ER
+eval_rcv_msg (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_CLI_MSG	*evl, *msg;
+	SYSTIM		time;
+
+	/* ã¡ãã»ã¼ã¸ãåä¿¡ãã¦ããªããã°ä¸­æ­¢ããã*/
+	syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+	if (ct->val_lst == NULL) {
+		syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+		return E_OK;
+		}
+
+	/* æ¤è¨¼ã¡ãã»ã¼ã¸ãªã¹ãããè©ä¾¡ã¡ãã»ã¼ã¸ãåãåºãã*/
+	evl         = ct->val_lst;
+	ct->val_lst = ct->val_lst->next;
+	evl->next   = NULL;
+	syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+
+	/* åä¿¡æéãè¨­å®ããã*/
+	get_tim(&time);
+	evl->rcv_time = time;
+
+	/* è©ä¾¡ã¡ãã»ã¼ã¸ãæ¤è¨¼ããã*/
+	if (validate_rcv_msg(ct, evl) != E_OK) {
+
+		/* ã¨ã©ã¼ãçºçããè©ä¾¡ã¡ãã»ã¼ã¸ãåä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ãã«æ»ãã*/
+		goto rcv_ret;
+		}
+
+	/* REL_INFO ç¶æ
+ã®æã®å¦ç */
+	if (ct->fsm == DHCP6_FSM_REL_INFO) {
+		syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+		if (evl->status == DHCP6_STAT_SUCCESS) {
+			/*
+			 *  STATUS CODE ã DHCP6_STAT_SUCCESS ãªãã
+			 *  è©ä¾¡ã¡ãã»ã¼ã¸ãæ¨å¥¨ã¡ãã»ã¼ã¸ãªã¹ãã«è¨­å®ãã¦çµäºããã
+			 */
+			evl->next   = ct->prf_lst;
+			ct->prf_lst = evl;
+			}
+		else {
+			/* è©ä¾¡ã¡ãã»ã¼ã¸ãåä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ãã«æ»ãã¦çµäºããã*/
+			evl->next   = ct->rcv_lst;
+			ct->rcv_lst = evl;
+			}
+		syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+		return E_OK;
+		}
+
+	/* è©ä¾¡ã¡ãã»ã¼ã¸ã®æ¨å¥¨åº¦ãè©ä¾¡ããã*/
+	eval_prefer(evl);
+	eval_ia_prefer(evl);
+
+	/* æ¨å¥¨ã¡ãã»ã¼ã¸ãªã¹ããç©ºãªãè©ä¾¡ã¡ãã»ã¼ã¸ãç§»ãã¦çµäºããã*/
+	if (ct->prf_lst == NULL) {
+		ct->max_prefer = evl->prefer & DHCP6_ClI_MSG_PREFER_VALUE_MASK;
+		ct->prf_lst = evl;
+		return E_OK;
+		}
+
+	/* è©ä¾¡ã¡ãã»ã¼ã¸ã®æ¨å¥¨åº¦ã¨æ¨å¥¨ã¡ãã»ã¼ã¸ãªã¹ãã®æå¤§æ¨å¥¨åº¦ãæ¯è¼ããã*/
+	if ((evl->prefer & DHCP6_ClI_MSG_PREFER_VALUE_MASK) > ct->max_prefer) {
+
+		/* 
+		 *  è©ä¾¡ã¡ãã»ã¼ã¸ã®æ¨å¥¨åº¦ãæ¨å¥¨ã¡ãã»ã¼ã¸ãªã¹ãã®æå¤§æ¨å¥¨åº¦ããé«ããã°ã
+		 *  æ¨å¥¨ã¡ãã»ã¼ã¸ãªã¹ããåä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ãã«æ»ãã
+		 *  è©ä¾¡ã¡ãã»ã¼ã¸ãæ¨å¥¨ã¡ãã»ã¼ã¸ãªã¹ãã«ç§»ãã
+		 */
+		ct->max_prefer = evl->prefer & DHCP6_ClI_MSG_PREFER_VALUE_MASK;
+		syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+		if (ct->rcv_lst == NULL)
+			ct->rcv_lst = ct->prf_lst;
+		else {
+			for (msg = ct->rcv_lst; msg->next != NULL; msg = msg->next)
+				;
+			msg->next = ct->prf_lst;
+			}
+		syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+		ct->prf_lst = evl;
+		return E_OK;
+		}
+
+	else if ((evl->prefer & DHCP6_ClI_MSG_PREFER_VALUE_MASK) == ct->max_prefer) {
+		for (msg = ct->prf_lst; msg != NULL; msg = msg->next) {
+			if (is_equal_sid(evl, msg)) {
+
+				/*
+				 *  æ¨å¥¨ã¡ãã»ã¼ã¸ãªã¹ãã«åã DHCP6_OPT_SERVERID ã®ã¡ãã»ã¼ã¸ãããã°ã
+				 *  è©ä¾¡ã¡ãã»ã¼ã¸ãåä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ãã«æ»ãã
+				 */
+				goto rcv_ret;
+				}
+			}
+
+		/* 
+		 *  è©ä¾¡ã¡ãã»ã¼ã¸ãæ¨å¥¨ã¡ãã»ã¼ã¸ãªã¹ãã«ç§»ãã
+		 */
+		evl->next   = ct->prf_lst;
+		ct->prf_lst = evl;
+		return E_OK;
+		}
+	
+	/*else */
+		/* 
+		 *  è©ä¾¡ã¡ãã»ã¼ã¸ã®æ¨å¥¨åº¦ãæ¨å¥¨ã¡ãã»ã¼ã¸ãªã¹ãã®æå¤§æ¨å¥¨åº¦ããä½ããã°ã
+		 *  è©ä¾¡ã¡ãã»ã¼ã¸ãåä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ãã«æ»ãã
+		 */
+
+rcv_ret:
+	syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+	evl->next   = ct->rcv_lst;
+	ct->rcv_lst = evl;
+	syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+	return E_OK;
+	}
+
+/*
+ *  select_msg -- æ¨å¥¨ã¡ãã»ã¼ã¸ãªã¹ãã®å
+é ­ã®ã¡ãã»ã¼ã¸ãé¸æããã
+ */
+
+static T_DHCP6_CLI_MSG*
+select_msg (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_CLI_MSG		*msg, *select;
+
+	syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+	if (ct->prf_lst == NULL) {
+		/* ã¡ãã»ã¼ã¸ãåä¿¡ãã¦ããªããã°ä¸­æ­¢ããã*/
+		syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+		return NULL;
+		}
+
+	select = ct->prf_lst;
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS
+
+	if ((select->prefer & DHCP6_ClI_MSG_PREFER_REQUIRED) == 0) {
+		/* å¿
+é ãªãã·ã§ã³ãç¡ããã°é¸æããªãã*/
+		syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+		return NULL;
+		}
+
+#elif DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+
+	if (((select->prefer & DHCP6_ClI_MSG_PREFER_REQUIRED) == 0) ||
+	    ((select->prefer & DHCP6_ClI_MSG_PREFER_ADDR)     == 0)) {
+		/* å¿
+é ãªãã·ã§ã³ã¨ã¢ãã¬ã¹ãç¡ããã°é¸æããªãã*/
+		syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+		return NULL;
+		}
+
+#else	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS */
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS */
+
+	/* æ¨å¥¨ã¡ãã»ã¼ã¸ãªã¹ãã®å
+é ­ã®ã¡ãã»ã¼ã¸ãé¸æããã*/
+	ct->prf_lst  = ct->prf_lst->next;
+	select->next = NULL;
+
+	/* é¸æãããªãã£ãæ¤è¨¼ã¡ãã»ã¼ã¸ãåä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ãã«æ»ãã*/
+	if (ct->rcv_lst == NULL)
+		ct->rcv_lst = ct->prf_lst;
+	else {
+		for (msg = ct->rcv_lst; msg->next != NULL; msg = msg->next)
+			;
+		msg->next = ct->prf_lst;
+		}
+	syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+	return select;
+	}
+
+/*
+ *  advance_retrans -- åéä¿¡ã¿ã¤ã ã¢ã¦ããæ´æ°ããã
+ */
+
+static void
+advance_retrans (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/*
+	 *  åéä¿¡ééï¼RTï¼ãæ´æ°ããã
+	 *  åéä¿¡æ¯ã«ç´ 2åãããã
+	 *  æå¤§éä¿¡ééï¼MRTï¼ãè¶
+ããªãããã«ããã
+	 */
+	ct->RT += ct->RT + dhcp6_rand(ct->RT);
+	if ((ct->MRT != 0) && (ct->RT > ct->MRT))
+		ct->RT = ct->MRT + dhcp6_rand(ct->MRT);
+
+	/* åéä¿¡åæ°ãæ´æ°ããã*/
+	ct->txcount ++;
+	}
+
+/*
+ *  init_retrans -- åéä¿¡åæ°ããã©ã³ã¶ã¯ã·ã§ã³ IDããã®ä»ãè¨­å®ããã
+ */
+
+static void
+init_retrans (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* éä¿¡åæ°ããªã»ããããã*/
+	ct->txcount = 0;
+
+	/* åéä¿¡ééãè¨­å®ããã*/
+	ct->RT = ct->IRT + dhcp6_rand(ct->IRT);
+
+	/* ãã©ã³ã¶ã¯ã·ã§ã³ ID ãè¨­å®ããã*/
+	ct->xid = netapp_rand() % 0x00ffffff;
+
+	/* åä¿¡ã¡ãã»ã¼ã¸ã®æå¤§æ¨å¥¨åº¦ããªã»ããããã*/
+	ct->max_prefer = 0;
+	}
+
+/*
+ *  setup_msg_header -- ã¡ãã»ã¼ã¸ã®ãããé¨åãä½æããã
+ */
+
+static uint8_t *
+setup_msg_header (T_DHCP6_CLI_CONTEXT *ct, uint_t type)
+{
+	memset((void*)&ct->snd_msg->msg, sizeof(ct->snd_msg->msg), 0);
+	ct->snd_msg->len = sizeof(ct->snd_msg->msg);
+
+	/* ãããé¨ãè¨­å®ããã*/
+	ct->snd_msg->msg.hdr.type   = type;
+	ct->snd_msg->msg.hdr.xid[0] = (ct->xid >> 16) & 0xff;
+	ct->snd_msg->msg.hdr.xid[1] = (ct->xid >>  8) & 0xff;
+	ct->snd_msg->msg.hdr.xid[2] =  ct->xid        & 0xff;
+
+	return (uint8_t*)&ct->snd_msg->msg + sizeof(ct->snd_msg->msg.hdr);
+	}
+
+/*
+ *  common_options -- æ¨æºãªãã·ã§ã³ãè¿½å ããã
+ */
+
+static uint8_t *
+common_options (T_DHCP6_CLI_CONTEXT *ct, uint8_t *msg, uint_t type, T_DHCP6_CLI_MSG *lease)
+{
+	T_DHCP6_OPT_CLIENTID	*cid;
+	T_DHCP6_OPT_SERVERID	*sid;
+
+#if defined(DHCP6_CLI_CFG_REQUIRED_OLIST) || defined(DHCP6_CLI_CFG_REQUEST_OLIST)
+	T_DHCP6_OPT_ORO		*oro;
+#endif
+
+	uint8_t			*opt;
+	uint_t			opt_len;
+	int_t			ix;
+
+#if defined(DHCP6_CLI_CFG_RAPID_COMMIT)
+
+	/* Rapid-commit ã®æå® */
+	if (type == DHCP6_SOLICIT)
+		;
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_RAPID_COMMIT) */
+
+	/* ã¯ã©ã¤ã¢ã³ã DUID ãè¿½å ããã*/
+	cid = (T_DHCP6_OPT_CLIENTID*)msg;
+	HOST2MSG16(cid->code, DHCP6_OPT_CLIENTID);
+	HOST2MSG16(cid->len,  ct->duid_len);
+	memcpy(msg + sizeof(T_DHCP6_OPT_CLIENTID), ct->duid, ct->duid_len);
+	msg += ct->duid_len + sizeof(T_DHCP6_OPT_CLIENTID);
+
+	/* ãµã¼ã DUID ãè¿½å ããã*/
+	if (lease == NULL) {
+		if (!(type == DHCP6_SOLICIT || type == DHCP6_INFO_REQ))
+			return NULL;
+		}
+	else if (!(type == DHCP6_CONFIRM || type == DHCP6_REBIND)) {
+		if ((opt = find_msg_option(lease, DHCP6_OPT_SERVERID, 0)) != NULL) {
+			sid = (T_DHCP6_OPT_SERVERID*)opt;
+			opt_len = MSG2HOST16(sid->len);
+			memcpy(msg, opt, opt_len + sizeof(*sid));
+			msg += opt_len + sizeof(*sid);
+			}
+		}
+
+#if defined(DHCP6_CLI_CFG_REQUIRED_OLIST) || defined(DHCP6_CLI_CFG_REQUEST_OLIST)
+
+	/* å¿
+é ã»è¦æ±ãªãã·ã§ã³ãè¿½å ããã*/
+	oro = (T_DHCP6_OPT_ORO*)msg;
+	HOST2MSG16(oro->code, DHCP6_OPT_ORO);
+	HOST2MSG16(oro->len, 0);
+	msg += sizeof(oro->code) + sizeof(oro->len);
+
+#if defined(DHCP6_CLI_CFG_REQUIRED_OLIST)
+
+	/* å¿
+é ãªãã·ã§ã³ãè¿½å ããã*/
+	HOST2MSG16(oro->len, MSG2HOST16(oro->len) + sizeof(required_plist) * 2);
+	for (ix = sizeof(required_plist); ix -- > 0; ) {
+		host2msg16(msg, required_plist[ix]);
+		msg += sizeof(uint16_t);
+		}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_REQUIRED_OLIST) */
+
+#if defined(DHCP6_CLI_CFG_REQUEST_OLIST)
+
+	/* è¦æ±ãªãã·ã§ã³ãè¿½å ããã*/
+	HOST2MSG16(oro->len, MSG2HOST16(oro->len) + sizeof(request_plist) * 2);
+	for (ix = sizeof(request_plist); ix -- > 0; ) {
+		host2msg16(msg, request_plist[ix]);
+		msg += sizeof(uint16_t);
+		}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_REQUEST_OLIST) */
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_REQUIRED_OLIST) || defined(DHCP6_CLI_CFG_REQUEST_OLIST) */
+
+	return msg;
+	}
+
+/*
+ *  rel_lease -- ãªã¼ã¹ããããªãã·ã§ã³ãè§£æãã¦å¤ãè§£æ¾ããã
+ */
+
+static void
+rel_lease (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_OPTION			*hdr;
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+
+	T_DHCP6_OPT_IA_NA_PD		*ia;
+	T_DHCP6_OPT_IAADDR		*iaa;
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL */
+
+	uint8_t		*opt, *last;
+
+	/* æå¹ãªãªã¼ã¹ã»ã¡ãã»ã¼ã¸æ§é ä½ãç¡ããã°ä½ãããªãã*/
+	if (ct->act_msg == NULL)
+		return;
+
+	opt  = ct->act_msg->msg.options;
+	last = opt + (ct->act_msg->len - sizeof(T_DHCP6_MSG_HDR));
+	while (opt < last) {
+		hdr = (T_DHCP6_OPTION*)opt;
+		switch (MSG2HOST16(hdr->code)) {
+
+		case DHCP6_OPT_NAME_SERVERS:
+			dns_in6_set_addr(NULL);
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS
+			syslog(LOG_NOTICE, "[DHCP6C] release DNS server addr.");
+#endif
+			break;
+
+		case DHCP6_OPT_DOMAIN_SEARCH:
+			dns_in6_set_dname(NULL, 0);
+			break;
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+
+		case DHCP6_OPT_IA_NA:
+			ia = (T_DHCP6_OPT_IA_NA_PD*)opt;
+			if (MSG2HOST16(ia->len) > sizeof(*iaa)) {
+				iaa = (T_DHCP6_OPT_IAADDR*)(opt + sizeof(*ia));
+				in6_del_ifaddr(&iaa->addr);
+				}
+			break;
+
+		case DHCP6_OPT_IA_TA:
+			break;
+
+		case DHCP6_OPT_IA_PD:
+			break;
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL */
+
+		default:
+			break;
+			}
+		opt += MSG2HOST16(hdr->len) + sizeof(*hdr);
+		}
+	}
+
+/*
+ *  set_lease -- ãªã¼ã¹ããããªãã·ã§ã³ãè§£æãã¦å¤ãè¨­å®ããã
+ */
+
+static void
+set_lease (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_OPTION			*hdr;
+	T_DHCP6_OPT_NAME_SERVERS	*ns;
+	T_DHCP6_OPT_DOMAIN_SEARCH	*ds;
+	const uint8_t			*dname;
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+
+	T_DHCP6_OPT_IA_NA_PD		*ia;
+	T_DHCP6_OPT_IAADDR		*iaa;
+	SYSTIM				time, delay;
+	ER				error;
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL */
+
+	uint8_t		*opt, *last;
+
+	opt  = ct->act_msg->msg.options;
+	last = opt + (ct->act_msg->len - sizeof(T_DHCP6_MSG_HDR));
+	while (opt < last) {
+		hdr = (T_DHCP6_OPTION*)opt;
+		switch (MSG2HOST16(hdr->code)) {
+
+		case DHCP6_OPT_NAME_SERVERS:
+			ns = (T_DHCP6_OPT_NAME_SERVERS*)opt;
+			dns_in6_set_addr(&ns->addrs[0]);
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS
+			syslog(LOG_NOTICE, "[DHCP6C] set DNS server addr: %s.", ipv62str(NULL, &ns->addrs[0]));
+#endif
+			break;
+
+		case DHCP6_OPT_DOMAIN_SEARCH:
+			ds = (T_DHCP6_OPT_DOMAIN_SEARCH*)opt;
+			dname = dns_in6_set_dname(ds->name, MSG2HOST16(ds->len));
+			break;
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+
+		case DHCP6_OPT_IA_NA:
+			ia = (T_DHCP6_OPT_IA_NA_PD*)opt;
+			if (MSG2HOST16(ia->len) > sizeof(*iaa)) {
+				get_tim(&time);
+				delay = time - ct->act_msg->rcv_time;
+				iaa = (T_DHCP6_OPT_IAADDR*)(opt + sizeof(*ia));
+				error = in6_upd_ifaddr(&iaa->addr, 64, MSG2HOST32(iaa->valid)  - SYSTIM2SEC(delay),
+				                                       MSG2HOST32(iaa->prefer) - SYSTIM2SEC(delay));
+				if (error == E_OK)
+					syslog(LOG_NOTICE, "[DHCP6C] set IPv6 addr: %s.", ipv62str(NULL, &iaa->addr));
+				else
+					syslog(LOG_NOTICE, "[DHCP6C] set IPv6 addr, error: %s.", itron_strerror(error));
+				}
+			break;
+
+		case DHCP6_OPT_IA_TA:
+			break;
+
+		case DHCP6_OPT_IA_PD:
+			break;
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL */
+
+		default:
+			break;
+			}
+		opt += MSG2HOST16(hdr->len) + sizeof(*hdr);
+		}
+	}
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA
+
+/*
+ *  start_req_info -- INFO-REQUEST ãéå§ããã
+ *
+ *    æ³¨æ: DHCPv6 ã® RFC3315 ã«ã¯ç¡ã
+ */
+
+static void
+start_req_info (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* ã¿ã¤ã ã¢ã¦ããè¨­å®ããããRFC3315 (18.1.5) åç
+§ã*/
+	ct->IRT = TMO_INF_TIMEOUT;
+	ct->MRT = TMO_INF_MAX_RT;
+	ct->MRC = 0;
+
+	/* DHCP6_CLI_CFG_ONE_TRYãæå®ããã¦ããªããã°æ¨æºã¿ã¤ã ã¢ã¦ãã¾ã§åéããã*/
+#if defined(DHCP6_CLI_CFG_ONE_TRY)
+	ct->MRD = 0;
+#else
+	ct->MRD = TMO_DHCP6C_NORMAL;
+#endif
+
+	/* åéåæ°ã¨ãã©ã³ã¶ã¯ã·ã§ã³ ID ãè¨­å®ããã*/
+	init_retrans(ct);
+
+	/* REPLY ã¡ãã»ã¼ã¸ã®åä¿¡ã¿ã¤ã ã¢ã¦ããè¨­å®ããã*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_RCV_REPLY] = SYSTIM2TIMER(ct->MRD);
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/*
+	 *  INFO-REQUEST ã¡ãã»ã¼ã¸éä¿¡é
+å»¶æéãè¨­å®ããã
+	 *  ãã ããTMO_INF_MAX_DELAY ã 1[s]ãªã®ã§ãdly_tsk()ãä½¿ç¨ããã
+	 */
+	dly_tsk(netapp_rand() % TMO_INF_MAX_DELAY);
+
+	/* SELECT ç¶æ
+ã«é·ç§»ããã*/
+	ct->fsm = DHCP6_FSM_SELECT;
+
+	/* INFO-REQUEST ã¡ãã»ã¼ã¸ãéä¿¡ããã*/
+	ct->flags |= DHCP6C_FLAG_TMOUT_SND_IREQ;
+	syscall(sig_sem(SEM_DHCP6_CLI_READY));
+	}
+
+/*
+ *  start_informed -- INFORMED ç¶æ
+ã«é·ç§»ããã
+ *
+ *    æ³¨æ: DHCPv6 ã® RFC3315 ã«ã¯ç¡ã
+ */
+
+static void
+start_informed (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* æå¹ãªãªã¼ã¹æ
+å ±ãç¡ããã° SLEEP ã«é·ç§»ããã*/
+	if (ct->act_msg == NULL) {
+		ct->fsm = DHCP6_FSM_SLEEP;
+		return;
+		}
+
+	/* ãªã¼ã¹æ
+å ±ãè¨­å®ããã*/
+	set_lease(ct);
+
+	/* INFORMED ç¶æ
+ã«é·ç§»ããã*/
+	ct->fsm = DHCP6_FSM_INFORMED;
+
+	//ct->flags |= DHCP6C_FLAG_STAY_STATE;
+	}
+
+/*
+ *  start_rel_info -- ã¢ãã¬ã¹æ
+å ±ãè§£æ¾ããã
+ *
+ *    æ³¨æ: DHCPv6 ã® RFC3315 ã«ã¯ç¡ã
+ */
+
+static void
+start_rel_info (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* ãªã¼ã¹æ
+å ±ãè§£æ¾ããã*/
+	rel_lease(ct);
+
+	/* SLEEP ã«é·ç§»ããã*/
+	ct->fsm = DHCP6_FSM_SLEEP;
+	syscall(sig_sem(SEM_DHCP6_CLI_READY));
+	}
+
+/*
+ *  select_info_reply -- æé©ãª REPLY (INFO-REQUEST ã¸ã®å¿ç­) ã¡ãã»ã¼ã¸ãé¸æããã
+ */
+
+static bool_t
+select_info_reply (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_CLI_MSG		*msg;
+
+	/* æé©ãª REPLY ã¡ãã»ã¼ã¸ãé¸æããã*/
+	if ((msg = select_msg(ct)) == NULL)
+		return false;
+	
+	ct->act_msg = msg;
+	return true;
+	}
+
+/*
+ *  setup_info_req_msg -- INFO-REQUEST ã¡ãã»ã¼ã¸ãä½æããã
+ */
+
+static ER
+setup_info_req_msg (T_DHCP6_CLI_CONTEXT *ct)
+{
+	uint8_t	*msg;
+
+	/* ã¡ãã»ã¼ã¸ã®ãããé¨åãä½æããã*/
+	if ((msg = setup_msg_header(ct, DHCP6_INFO_REQ)) == NULL)
+		return E_PAR;
+
+	if ((msg = common_options(ct, msg, DHCP6_INFO_REQ, NULL)) == NULL)
+		return E_PAR;
+
+	/* ã¡ãã»ã¼ã¸æ§é ä½é·ãè¨­å®ããã*/
+	ct->snd_msg->len = msg - (uint8_t*)&ct->snd_msg->msg;
+
+	/* éä¿¡å
+ã¢ãã¬ã¹ãè¨­å®ããã*/
+	ct->dst.ipaddr	= in6_addr_all_DHCP_relay_servers;
+	return E_OK;
+	}
+
+/*
+ *  send_info_req_msg -- INFO-REQUEST ã¡ãã»ã¼ã¸ãéä¿¡ããã
+ */
+
+static void
+send_info_req_msg (T_DHCP6_CLI_CONTEXT *ct)
+{
+	ER	error;
+
+
+	/* REPLY ã¡ãã»ã¼ã¸ã®é¸æãçµäºãã¦ããã°ãBOUND ç¶æ
+ã«é·ç§»ããã*/
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+	if (select_info_reply(ct)) {
+
+		/* REPLY ã¡ãã»ã¼ã¸åä¿¡ã¿ã¤ãã¼ãåæ­¢ããã*/
+		syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+		ct->timers[DHCP6C_TIMER_RCV_REPLY] = 0;
+		syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+		/* INFORMED ç¶æ
+ã«é·ç§»ããã*/
+		start_informed(ct);
+		return;
+		}
+
+	/* åéä¿¡åæ°ãç¢ºèªããã*/
+	if ((ct->MRC != 0) && (ct->txcount > ct->MRC)) {
+		ct->error  = E_TMOUT;
+		return;
+		}
+
+	/* INFO-REQUEST ã¡ãã»ã¼ã¸ãä½æããã*/
+	if ((error = setup_info_req_msg(ct)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, setup request message: %s.", itron_strerror(error));
+		ct->error = error;
+		return;
+		}
+
+	/* INFO-REQUEST ã¡ãã»ã¼ã¸ãéä¿¡ããã*/
+	error = UDP_SND_DAT(ct->cepid, &ct->dst, &ct->snd_msg->msg, ct->snd_msg->len, TMO_NBLK);
+	if (error != E_WBLK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, send info-request message: %s.", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* åéä¿¡ã¿ã¤ã ã¢ã¦ããè¨­å®ããã*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_SND_IREQ] = SYSTIM2TIMER(ct->RT);
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/* åéä¿¡ã¿ã¤ã ã¢ã¦ããæ´æ°ããã*/
+	advance_retrans(ct);
+	}
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA */
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA
+
+/*
+ *  select_reply -- æé©ãª REPLY ã¡ãã»ã¼ã¸ãé¸æããã
+ */
+
+static bool_t
+select_reply (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_CLI_MSG		*msg;
+
+	/* æé©ãª REPLY ã¡ãã»ã¼ã¸ãé¸æããã*/
+	if ((msg = select_msg(ct)) == NULL)
+		return false;
+
+	if (ct->adv_msg != NULL) {
+		eval_prefer(ct->adv_msg);
+		eval_ia_prefer(ct->adv_msg);
+		}
+
+	/*
+	 *  æé©ãª REPLY ã¡ãã»ã¼ã¸ã®æ¨å¥¨åº¦ã ADVERTISE ã¡ãã»ã¼ã¸æ¨å¥¨åº¦ã®
+	 *  1/2 ä»¥ä¸ã®æã¯åä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ãã«æ»ãã
+	 */
+	if ((ct->adv_msg != NULL) && (ct->max_prefer < (ct->adv_msg->prefer & DHCP6_ClI_MSG_PREFER_VALUE_MASK) / 2)) {
+		syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+		msg->next = ct->rcv_lst;
+		ct->rcv_lst = msg;
+		syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+		}
+	else {
+
+		/*
+		 *  ct->act_msg ã«ããæå¹ãªå
+ REPLY ã¡ãã»ã¼ã¸ã
+		 *  åä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ãã«æ»ãã¦ã
+		 *  æé©ãª REPLY ã¡ãã»ã¼ã¸ã act ã«ç§»ãã
+		 */
+		if (ct->act_msg != NULL) {
+			syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+			ct->act_msg->next = ct->rcv_lst;
+			ct->rcv_lst = ct->act_msg;
+			syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+			}
+		ct->act_msg = msg;
+		}
+
+	return ct->act_msg != NULL;
+	}
+
+/*
+ *  select_adv -- æé©ãª ADVERTISE ã¡ãã»ã¼ã¸ãé¸æããã
+ */
+
+static bool_t
+select_adv (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* æé©ãª ADVERTISE ã¡ãã»ã¼ã¸ã adv ã«ç§»ãã*/
+	if ((ct->adv_msg = select_msg(ct)) != NULL) {
+
+		/*
+		 *  æé©ãª ADVERTISE ã¡ãã»ã¼ã¸ã®ãµã¼ãã® IPv6 ã¢ãã¬ã¹ã
+		 *  æ¬¡ããéä¿¡ããã¢ãã¬ã¹ã«è¨­å®ããã
+		 */
+		ct->dst = ct->adv_msg->srv;
+		return true;
+		}
+	else
+		return false;
+	}
+
+/*
+ *  eval_expire -- æ¨å¥¨æå¹æéã¨æå¹æéãæ±ºå®ããã
+ */
+
+static void
+eval_expire (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_OPTION		*opt;
+	T_DHCP6_OPT_IA_NA_PD	*ia;
+	T_DHCP6_OPT_IAADDR	*iaa;
+	SYSTIM		time;
+	uint32_t	depref, expire,
+			high, low, renew, rebind,
+			tval, iaa_high, iaa_low;
+	uint8_t		*msg, *last;
+	uint_t		aoff, asize, addrs;
+
+	/* ã¿ã¤ãã¼ãåæ­¢ããã*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_RENEW]  = 0;
+	ct->timers[DHCP6C_TIMER_REBIND] = 0;
+	ct->timers[DHCP6C_TIMER_DEPREF] = 0;
+	ct->timers[DHCP6C_TIMER_EXPIRE] = 0;
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+	
+	addrs = high = expire = 0;
+	low = renew = rebind = depref = DHCP6_MAX_TIME;
+
+	msg = ct->act_msg->msg.options;
+	last = msg + (ct->act_msg->len - sizeof(T_DHCP6_MSG_HDR));
+	get_tim(&time);
+	while (msg < last) {
+		opt = (T_DHCP6_OPTION*)msg;
+
+		/* IA_NA/IA_PD ãªãã·ã§ã³ã§ããã°ãæå¹æéãæ´æ°ããã*/
+		if (MSG2HOST16(opt->code) == DHCP6_OPT_IA_NA || MSG2HOST16(opt->code) == DHCP6_OPT_IA_PD) {
+
+			//dump_msg_option("evl_expire1", msg);
+			iaa_high = 0;
+			iaa_low  = DHCP6_MAX_TIME;
+
+			ia = (T_DHCP6_OPT_IA_NA_PD*)opt;
+			aoff  = sizeof(*ia);
+			asize = MSG2HOST16(ia->len) + sizeof(*opt);
+			while (aoff < asize) {
+
+				/* æç­ã®æ¨å¥¨æå¹æéãæ´æ°ããã*/
+				iaa = (T_DHCP6_OPT_IAADDR*)((uint8_t*)opt + aoff);
+				//dump_msg_option("evl_depref1", (uint8_t*)iaa);
+				if (!(MSG2HOST16(iaa->len) & DHCP6C_IAA_FLAG_DEPREFERD)) {
+					if (MSG2HOST32(iaa->prefer) == DHCP6_MAX_TIME)
+						tval = DHCP6_MAX_TIME;
+					else
+						tval = MSG2HOST32(iaa->prefer) + SYSTIM2SEC(ct->act_msg->rcv_time);
+					if (tval < depref)
+						depref = tval;
+					}
+
+				/* IAADDR ã®æå¹æéãæ´æ°ããã*/
+				iaa = (T_DHCP6_OPT_IAADDR*)((uint8_t*)opt + aoff);
+				if (!(MSG2HOST16(iaa->len) & DHCP6C_IAA_FLAG_EXPIRED)) {
+					if (MSG2HOST32(iaa->valid) == DHCP6_MAX_TIME)
+						tval = DHCP6_MAX_TIME;
+					else
+						tval = MSG2HOST32(iaa->valid) + SYSTIM2SEC(ct->act_msg->rcv_time);
+					tval -= SYSTIM2SEC(ct->act_msg->rcv_time);
+					if (tval > iaa_high)
+						iaa_high = tval;
+					if (tval < iaa_low)
+						iaa_low  = tval;
+					addrs ++;
+					}
+
+				aoff += (MSG2HOST16(iaa->len) & ~DHCP6C_IAA_FLAG_MASK) + sizeof(*iaa);
+				}
+
+			/* iaa_low ã¨ iaa_high/2 ã®æé·ã®æ¹ãæå¹æéã¨ãã¦é¸æããã*/
+			if (iaa_low <= (iaa_high / 2))
+				expire = iaa_high;
+			else
+				expire = iaa_low;
+
+			/* expire ã æå¤§å¤ï¼ç¡å¶éï¼ã 1 ä»¥ä¸ãªãæ¢å®å¤ã«è¨­å®ããã*/
+			if ((expire == DHCP6_MAX_TIME) || (expire <= 1))
+				expire  = SYSTIM2SEC(TMO_DHCP6C_REQ_LEASE) / 2;
+			else
+				expire /= 2;
+
+			/* renew ãæ±ºå®ããã*/
+			if (MSG2HOST32(ia->renew) == 0)
+				tval = expire + SYSTIM2SEC(ct->act_msg->rcv_time);
+			else if (MSG2HOST32(ia->renew) == DHCP6_MAX_TIME)
+				tval = DHCP6_MAX_TIME;
+			else
+				tval = MSG2HOST32(ia->renew) + SYSTIM2SEC(ct->act_msg->rcv_time);
+			if (tval < renew)
+				renew = tval;
+
+			/* rebind ãæ±ºå®ããã*/
+			if (MSG2HOST32(ia->rebind) == 0)
+				tval = (expire + expire / 2) + SYSTIM2SEC(ct->act_msg->rcv_time);
+			else if (MSG2HOST32(ia->rebind) == DHCP6_MAX_TIME)
+				tval = DHCP6_MAX_TIME;
+			else
+				tval = MSG2HOST32(ia->rebind) + SYSTIM2SEC(ct->act_msg->rcv_time);
+			if (tval < rebind)
+				rebind = tval;
+
+			/* æç­æå¹æéã¨æé·æå¹æéãæ´æ°ããã*/
+			iaa_low  += SYSTIM2SEC(ct->act_msg->rcv_time);
+			iaa_high += SYSTIM2SEC(ct->act_msg->rcv_time);
+			if (iaa_low < low)
+				low = iaa_low;
+			if (iaa_high > high)
+				high = iaa_high;
+			}
+
+		msg += MSG2HOST16(opt->len) + sizeof(*opt);
+		}
+
+	/* ã¢ãã¬ã¹ãéããã¦ããªããã°ãSLEEP ç¶æ
+ã«é·ç§»ããã*/
+	if (addrs == 0) {
+		ct->fsm    = DHCP6_FSM_SLEEP;
+		}
+
+	/* ç¶æ
+ã«ä¾å­ããå¦ç */
+	switch (ct->fsm) {
+
+	case DHCP6_FSM_BOUND:
+
+		/* RENEW ã¿ã¤ã ã¢ã¦ãã®è¨­å® */
+		if ((rebind > SYSTIM2SEC(time)) && (renew < rebind)) {
+			ct->next_MRD = SEC2SYSTIM(rebind) - time;
+			syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+			ct->timers[DHCP6C_TIMER_RENEW] = SEC2TIMER(renew) - SYSTIM2TIMER(time);
+			syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+			break;
+			}
+		/* break; */	/* ä¸ã«æããã*/
+
+	case DHCP6_FSM_RENEW:
+
+		/* REBIND ã¿ã¤ã ã¢ã¦ãã®è¨­å® */
+		ct->MRD = SEC2SYSTIM(rebind);
+		if (rebind != DHCP6_MAX_TIME) {
+			ct->next_MRD = SEC2SYSTIM(high) - time;
+			syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+			ct->timers[DHCP6C_TIMER_REBIND] = SEC2TIMER(rebind) - SYSTIM2TIMER(time);
+			syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+			}
+		break;
+
+	case DHCP6_FSM_REBIND:
+
+		ct->next_MRD = (SEC2TIMER(high) - time) - time;
+		break;
+
+	default:
+		break;
+		}
+
+	/* DEPREF ã¿ã¤ã ã¢ã¦ãã®è¨­å® */
+	if (depref != DHCP6_MAX_TIME) {
+		syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+		ct->timers[DHCP6C_TIMER_DEPREF] = SEC2TIMER(depref) - SYSTIM2TIMER(time);
+		syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+		}
+
+	/* EXPIRE ã¿ã¤ã ã¢ã¦ãã®è¨­å® */
+	if (low != DHCP6_MAX_TIME) {
+		syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+		ct->timers[DHCP6C_TIMER_EXPIRE] = SEC2TIMER(low) - SYSTIM2TIMER(time);
+		syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+		}
+	}
+
+/*
+ *  start_init -- INIT ç¶æ
+ã«é·ç§»ããã
+ */
+
+static void
+start_init (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* ã¿ã¤ã ã¢ã¦ããè¨­å®ããããRFC3315 (17.1.2) åç
+§ã*/
+	ct->IRT = TMO_SOL_TIMEOUT;
+	ct->MRT = TMO_SOL_MAX_RT;
+	ct->MRC = 0;
+
+	/* DHCP6_CLI_CFG_ONE_TRYãæå®ããã¦ããªããã°æ¨æºã¿ã¤ã ã¢ã¦ãã¾ã§åéããã*/
+#if defined(DHCP6_CLI_CFG_ONE_TRY)
+	ct->MRD = 0;
+#else
+	ct->MRD = TMO_DHCP6C_NORMAL;
+#endif
+
+	/* åéåæ°ã¨ãã©ã³ã¶ã¯ã·ã§ã³ ID ãè¨­å®ããã*/
+	init_retrans(ct);
+
+	/* RFC3315 (17.1.2) ã®è¦å®ã«å¾ã£ã¦ã¿ã¤ã ã¢ã¦ããèª¿æ´ããã*/
+	if (ct->RT <= ct->IRT)
+		ct->RT = ct->IRT + (ct->IRT - ct->RT);
+	if (ct->RT <= ct->IRT)
+		ct->RT = ct->IRT + SEC2SYSTIM(1);
+
+	/* ADVERTISE ã¡ãã»ã¼ã¸ã®åä¿¡ã¿ã¤ã ã¢ã¦ããè¨­å®ããã*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_RCV_ADV] = SYSTIM2TIMER(ct->MRD);
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/*
+	 *  SOLICIT ã¡ãã»ã¼ã¸éä¿¡é
+å»¶æéãè¨­å®ããã
+	 *  ãã ããTMO_SOL_MAX_DELAY ã 1[s]ãªã®ã§ãdly_tsk()ãä½¿ç¨ããã
+	 */
+	dly_tsk(netapp_rand() % TMO_SOL_MAX_DELAY);
+
+	/* INIT ç¶æ
+ã«é·ç§»ããã*/
+	ct->fsm = DHCP6_FSM_INIT;
+
+	/* SOLICIT ã¡ãã»ã¼ã¸ãéä¿¡ããã*/
+	ct->flags |= DHCP6C_FLAG_TMOUT_SND_SOL;
+	syscall(sig_sem(SEM_DHCP6_CLI_READY));
+	}
+
+/*
+ *  start_select -- REQUEST ã¡ãã»ã¼ã¸ãéä¿¡ãã¦ SELECT ç¶æ
+ã«é·ç§»ããã
+ */
+
+static void
+start_select (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* æå¹ãª ADVERTISE ã¡ãã»ã¼ã¸ãåä¿¡ãã¦ããªããã° SLEEP ç¶æ
+ã«é·ç§»ããã*/
+	if (ct->adv_msg == NULL) {
+		ct->fsm = DHCP6_FSM_SLEEP;
+		return;
+		}
+
+	/* ã¿ã¤ã ã¢ã¦ããè¨­å®ããããRFC3315 (18.1.1) åç
+§ã*/
+	ct->IRT = TMO_REQ_TIMEOUT;
+	ct->MRT = TMO_REQ_MAX_RT;
+	ct->MRC = TMO_REQ_MAX_RC;
+	ct->MRD = 0;
+
+	/* åéåæ°ã¨ãã©ã³ã¶ã¯ã·ã§ã³ ID ãè¨­å®ããã*/
+	init_retrans(ct);
+
+	/* REPLY ã¡ãã»ã¼ã¸ã®åä¿¡ã¿ã¤ã ã¢ã¦ããè¨­å®ããã*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_RCV_REPLY] = SYSTIM2TIMER(ct->MRD);
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/* SELECT ç¶æ
+ã«é·ç§»ããã*/
+	ct->fsm = DHCP6_FSM_SELECT;
+
+	/* REQUEST ã¡ãã»ã¼ã¸ãéä¿¡ããã*/
+	ct->flags |= DHCP6C_FLAG_TMOUT_SND_REQ;
+	syscall(sig_sem(SEM_DHCP6_CLI_READY));
+	}
+
+/*
+ *  start_bound -- BOUND ç¶æ
+ã«é·ç§»ããã
+ */
+
+static void
+start_bound (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* æå¹ãªãªã¼ã¹æ
+å ±ãç¡ããã° SLEEP ã«é·ç§»ããã*/
+	if (ct->act_msg == NULL)
+		ct->fsm = DHCP6_FSM_SLEEP;
+
+	/* BOUND ç¶æ
+ã«é·ç§»ããã*/
+	ct->fsm    = DHCP6_FSM_BOUND;
+
+	/* ãªã¼ã¹æ
+å ±ãè¨­å®ããã*/
+	set_lease(ct);
+
+	/* æå¹æéãæ±ºå®ããã*/
+	eval_expire(ct);
+
+	}
+/*
+ *  start_renew -- RENEW ç¶æ
+ã«é·ç§»ããã
+ */
+
+static void
+start_renew (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* æå¹ãªãªã¼ã¹æ
+å ±ãç¡ããã° SLEEP ã«é·ç§»ããã*/
+	if (ct->act_msg == NULL) {
+		ct->fsm = DHCP6_FSM_SLEEP;
+		return;
+		}
+
+	/* ã¿ã¤ã ã¢ã¦ããè¨­å®ããããRFC3315 (18.1.3) åç
+§ã*/
+	ct->IRT = TMO_REN_TIMEOUT;
+	ct->MRT = TMO_REN_MAX_RT;
+	ct->MRC = 0;
+	ct->MRD = ct->next_MRD;
+
+	/* åéåæ°ã¨ãã©ã³ã¶ã¯ã·ã§ã³ ID ãè¨­å®ããã*/
+	init_retrans(ct);
+
+	/* REFRESH ã¡ãã»ã¼ã¸ã¿ã¤ããè¨­å®ããã*/
+	ct->refresh_type = DHCP6_RENEW;
+
+	/* REPLY ã¡ãã»ã¼ã¸ã®åä¿¡ã¿ã¤ã ã¢ã¦ããè¨­å®ããã*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_RCV_REPLY] = SYSTIM2TIMER(ct->MRD);
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/* RENEW ç¶æ
+ã«é·ç§»ããã*/
+	ct->fsm = DHCP6_FSM_RENEW;
+
+	/* REFRESH ã¡ãã»ã¼ã¸ãéä¿¡ããã*/
+	ct->flags |= DHCP6C_FLAG_TMOUT_SND_REF;
+	syscall(sig_sem(SEM_DHCP6_CLI_READY));
+	}
+
+/*
+ *  start_rebind -- REBIND ç¶æ
+ã«é·ç§»ããã
+ */
+
+static void
+start_rebind (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* æå¹ãªãªã¼ã¹æ
+å ±ãç¡ããã° SLEEP ã«é·ç§»ããã*/
+	if (ct->act_msg == NULL) {
+		ct->fsm = DHCP6_FSM_SLEEP;
+		return;
+		}
+
+	/* ã¿ã¤ã ã¢ã¦ããè¨­å®ããããRFC3315 (18.1.4) åç
+§ã*/
+	ct->IRT = TMO_REB_TIMEOUT;
+	ct->MRT = TMO_REB_MAX_RT;
+	ct->MRC = 0;
+	ct->MRD = ct->next_MRD;
+
+	/* åéåæ°ã¨ãã©ã³ã¶ã¯ã·ã§ã³ ID ãè¨­å®ããã*/
+	init_retrans(ct);
+
+	/* REFRESH ã¡ãã»ã¼ã¸ã¿ã¤ããè¨­å®ããã*/
+	ct->refresh_type = DHCP6_REBIND;
+
+	/* REPLY ã¡ãã»ã¼ã¸ã®åä¿¡ã¿ã¤ã ã¢ã¦ããè¨­å®ããã*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_RCV_REPLY] = SYSTIM2TIMER(ct->MRD);
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/* éä¿¡å
+ã¢ãã¬ã¹ãè¨­å®ããã*/
+	ct->dst.ipaddr	= in6_addr_all_DHCP_relay_servers;
+
+	/* REBIND ç¶æ
+ã«é·ç§»ããã*/
+	ct->fsm = DHCP6_FSM_REBIND;
+
+	/* REFRESH ã¡ãã»ã¼ã¸ãéä¿¡ããã*/
+	ct->flags |= DHCP6C_FLAG_TMOUT_SND_REF;
+	syscall(sig_sem(SEM_DHCP6_CLI_READY));
+	}
+
+/*
+ *  start_rel_info -- ã¢ãã¬ã¹æ
+å ±ãè§£æ¾ããã
+ *
+ *    æ³¨æ: DHCPv6 ã® RFC3315 ã«ã¯ç¡ã
+ */
+
+static void
+start_rel_info (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* å
+¨ã¦ã® TIMER ãã­ã£ã³ã»ã«ããã*/
+	cancel_all_timers(ct);
+
+	/* ãªã¼ã¹æ
+å ±ãè§£æ¾ããã*/
+	rel_lease(ct);
+
+	/* æå¹ãªãªã¼ã¹æ
+å ±ãç¡ããã° SLEEP ã«é·ç§»ããã*/
+	if (ct->act_msg == NULL) {
+		ct->fsm = DHCP6_FSM_SLEEP;
+		return;
+		}
+
+	/* ã¿ã¤ã ã¢ã¦ããè¨­å®ããããRFC3315 (18.1.1) åç
+§ã*/
+	ct->IRT = TMO_REL_TIMEOUT;
+	ct->MRT = 0;
+	ct->MRC = TMO_REL_MAX_RC;
+	ct->MRD = 0;
+
+	/* åéåæ°ã¨ãã©ã³ã¶ã¯ã·ã§ã³ ID ãè¨­å®ããã*/
+	init_retrans(ct);
+
+	/* REL_INFO ç¶æ
+ã«é·ç§»ããã*/
+	ct->fsm = DHCP6_FSM_REL_INFO;
+
+	/* RELEASE ã¡ãã»ã¼ã¸ãéä¿¡ããã*/
+	ct->flags |= DHCP6C_FLAG_TMOUT_SND_REL;
+	syscall(sig_sem(SEM_DHCP6_CLI_READY));
+	}
+
+#if defined(DHCP6_CLI_CFG_IA_NA) || defined(DHCP6_CLI_CFG_IA_TA) || defined(DHCP6_CLI_CFG_IA_PD)
+
+/*
+ *  solicit_ia_option -- SOLICIT ã¡ãã»ã¼ã¸ã® IA_NA/IA_TA/IA_PD ãªãã·ã§ã³ã®å
+±éé¨åãè¿½å ããã
+ */
+
+static void
+solicit_ia_option (T_DHCP6_CLI_CONTEXT *ct, uint8_t *msg, uint_t code)
+{
+	T_DHCP6_OPT_IA_TA	*ia;
+	uint_t			off, len;
+
+	/* ãªãã·ã§ã³ã³ã¼ããè¨­å®ããã*/
+	ia = (T_DHCP6_OPT_IA_TA*)msg;
+	HOST2MSG16(ia->code, code);
+
+	/* IAID ãè¨­å®ããã*/
+	if (sizeof(ct->sc->ifaddr.lladdr) > sizeof(uint32_t)) {
+		off = sizeof(ct->sc->ifaddr.lladdr) - 4;
+		len = 4;
+		}
+	else {
+		off = 0;
+		len = sizeof(ct->sc->ifaddr.lladdr);
+		}
+	memcpy((uint8_t*)&ia->iaid, ((uint8_t*)ct->sc->ifaddr.lladdr) + off, len);
+	}
+
+/*
+ *  solicit_iaaddr_option -- SOLICIT ã¡ãã»ã¼ã¸ã® IAADDR ãªãã·ã§ã³ãè¿½å ããã
+ */
+
+static uint_t
+solicit_iaaddr_option (T_DHCP6_CLI_CONTEXT *ct, uint8_t *msg, uint_t code)
+{
+	T_DHCP6_OPT_IAADDR	*iaa;
+	uint32_t		t1, t2;
+	uint8_t			*opt;
+	uint_t			len;
+
+	/*
+	 *  æå¹ãªãªã¼ã¹ã»ã¡ãã»ã¼ã¸ãæ®ã£ã¦ãã¦ã
+	 *  æå®ããããªãã·ã§ã³ï¼IA_NA/IA_TA/IA_PDï¼ãããå ´åã¯
+	 *  åãã¢ãã¬ã¹ãè¦æ±ããã
+	 */
+	if ((ct->act_msg == NULL) || (opt = find_msg_option(ct->act_msg, code, 0)) == NULL)
+		return 0;
+
+	/* ãªãã·ã§ã³ã³ã¼ããè¨­å®ããã*/
+	iaa = (T_DHCP6_OPT_IAADDR*)msg;
+	HOST2MSG16(iaa->code, DHCP6_OPT_IAADDR);
+
+	/* IAADDR ãªãã·ã§ã³ãé¤ãããªãã·ã§ã³é·ãè¨­å®ããã*/
+	HOST2MSG16(iaa->len, sizeof(*iaa) - sizeof(T_DHCP6_OPTION));
+
+	/* ã¢ãã¬ã¹ãè¨­å®ããã*/
+	len = code == DHCP6_OPT_IA_TA ? sizeof(T_DHCP6_OPT_IA_TA)
+	                              : sizeof(T_DHCP6_OPT_IA_NA_PD);
+	memcpy(&iaa->addr, opt + sizeof(T_DHCP6_OPTION) + len, sizeof(iaa->addr));
+
+	/* T1ãT2 ãè¨­å®ããã*/
+	t1 = TMO_DHCP6C_REQ_LEASE / 2;
+	t2 = t1 + (t1 / 2);
+	HOST2MSG32(iaa->prefer, t1);
+	HOST2MSG32(iaa->valid,  t2);
+
+	return sizeof(*iaa);
+	}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_IA_NA) || defined(DHCP6_CLI_CFG_IA_TA) || defined(DHCP6_CLI_CFG_IA_PD) */
+
+/*
+ *  solicit_ia_na_pd -- SOLICIT ã¡ãã»ã¼ã¸ã® IA_NA/IA_PD ãªãã·ã§ã³ãè¿½å ããã
+ */
+
+#if defined(DHCP6_CLI_CFG_IA_NA) || defined(DHCP6_CLI_CFG_IA_PD)
+
+static uint8_t *
+solicit_ia_na_pd (T_DHCP6_CLI_CONTEXT *ct, uint8_t *msg, uint_t code)
+{
+	T_DHCP6_OPT_IA_NA_PD	*ia;
+	uint32_t		t1, t2;
+	uint_t			len;
+
+	/* IA_NA/IA_TA/IA_PD ãªãã·ã§ã³ã®å
+±éé¨åãè¿½å ããã*/
+	solicit_ia_option(ct, msg, code);
+	ia = (T_DHCP6_OPT_IA_NA_PD*)msg;
+
+	/* T1ãT2 ãè¨­å®ããã*/
+	t1 = TMO_DHCP6C_REQ_LEASE / 2;
+	t2 = t1 + (t1 / 2);
+	HOST2MSG32(ia->renew,  SYSTIM2SEC(t1));
+	HOST2MSG32(ia->rebind, SYSTIM2SEC(t2));
+
+	/*
+	 *  æå¹ãªãªã¼ã¹ã»ã¡ãã»ã¼ã¸ãæ®ã£ã¦ãã¦ã
+	 *  æå®ããããªãã·ã§ã³ï¼IA_NA/IA_PDï¼ãããå ´åã¯
+	 *  åãã¢ãã¬ã¹ãè¦æ±ããã
+	 */
+	msg += sizeof(*ia);
+	len  = solicit_iaaddr_option(ct, msg, code);
+
+	/* IA_NAIA_TA/IA_PD ãªãã·ã§ã³ãé¤ãããªãã·ã§ã³é·ãè¨­å®ããã*/
+	HOST2MSG16(ia->len, (sizeof(*ia) + len) - sizeof(T_DHCP6_OPTION));
+
+	return msg + len;
+	}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_IA_NA) || defined(DHCP6_CLI_CFG_IA_PD) */
+
+/*
+ *  solicit_ia_ta -- SOLICIT ã¡ãã»ã¼ã¸ã® IA_TA ãªãã·ã§ã³ãè¿½å ããã
+ */
+
+#if defined(DHCP6_CLI_CFG_IA_TA)
+
+static uint8_t *
+solicit_ia_ta (T_DHCP6_CLI_CONTEXT *ct, uint8_t *msg)
+{
+	T_DHCP6_OPT_IA_TA	*ia;
+
+	/* IA_NA/IA_TA/IA_PD ãªãã·ã§ã³ã®å
+±éé¨åãè¿½å ããã*/
+	solicit_ia_option(ct, msg, DHCP6_OPT_IA_TA);
+
+	/* IA_NAIA_TA/IA_PD ãªãã·ã§ã³ãé¤ãããªãã·ã§ã³é·ãè¨­å®ããã*/
+	ia = (T_DHCP6_OPT_IA_TA*)msg;
+	HOST2MSG16(ia->len, sizeof(*ia) - sizeof(T_DHCP6_OPTION));
+
+	/*
+	 *  æå¹ãªãªã¼ã¹ã»ã¡ãã»ã¼ã¸ãæ®ã£ã¦ãã¦ã
+	 *  æå®ããããªãã·ã§ã³ï¼IA_TAï¼ãããå ´åã¯
+	 *  åãã¢ãã¬ã¹ãè¦æ±ããã
+	 */
+	msg += sizeof(*ia);
+	return msg + solicit_iaaddr_option(ct, msg, code);
+	}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_IA_TA) */
+
+/*
+ *  setup_solicit_msg -- SOLICIT ã¡ãã»ã¼ã¸ãä½æããã
+ */
+
+static ER
+setup_solicit_msg (T_DHCP6_CLI_CONTEXT *ct, T_DHCP6_CLI_MSG *lease)
+{
+	uint8_t	*head, *msg;
+
+	/* ã¡ãã»ã¼ã¸ã®ãããé¨åãä½æããã*/
+	if ((head = setup_msg_header(ct, DHCP6_SOLICIT)) == NULL)
+		return E_PAR;
+
+	if ((msg = common_options(ct, head, DHCP6_SOLICIT, lease)) == NULL)
+		return E_PAR;
+
+#if defined(DHCP6_CLI_CFG_IA_NA)
+
+	/* IA_NA ãè¿½å ããã*/
+	msg = solicit_ia_na_pd(ct, msg, DHCP6_OPT_IA_NA);
+#endif
+
+#if defined(DHCP6_CLI_CFG_IA_TA)
+
+	/* IA_TA ãè¿½å ããã*/
+	msg = solicit_ia_ta(ct, msg);
+#endif
+
+#if defined(DHCP6_CLI_CFG_IA_PD)
+
+	/* IA_PD ãè¿½å ããã*/
+	msg = solicit_ia_na_pd(ct, msg, DHCP6_OPT_IA_PD);
+#endif
+
+	/* ã¡ãã»ã¼ã¸æ§é ä½é·ãè¨­å®ããã*/
+	ct->snd_msg->len = msg - (uint8_t*)&ct->snd_msg->msg;
+
+	/* éä¿¡å
+ã¢ãã¬ã¹ãè¨­å®ããã*/
+	ct->dst.ipaddr	= in6_addr_all_DHCP_relay_servers;
+	return E_OK;
+	}
+
+/*
+ *  send_solicit_msg -- SOLICIT ã¡ãã»ã¼ã¸ãéä¿¡ããã
+ */
+
+static void
+send_solicit_msg (T_DHCP6_CLI_CONTEXT *ct)
+{
+	ER	error;
+
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+	ct->error = E_OK;
+
+	/* ADVERTISE ã¡ãã»ã¼ã¸ã®é¸æãçµäºãã¦ããã°ãSELECT ç¶æ
+ã«é·ç§»ããã*/
+	if (select_adv(ct)) {
+
+		/* ADVERTISE ã¡ãã»ã¼ã¸åä¿¡ã¿ã¤ãã¼ãåæ­¢ããã*/
+		syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+		ct->timers[DHCP6C_TIMER_RCV_ADV] = 0;
+		syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+ 		/* REQUEST ã¡ãã»ã¼ã¸ãéä¿¡ãã¦ SELECT ç¶æ
+ã«é·ç§»ããã*/
+ 		start_select(ct);
+		return;
+		}
+
+	/* åéä¿¡åæ°ãç¢ºèªããã*/
+	if ((ct->MRC != 0) && (ct->txcount > ct->MRC)) {
+		ct->error  = E_TMOUT;
+		return;
+		}
+
+	/* SOLICIT ã¡ãã»ã¼ã¸ãä½æããã*/
+	if ((error = setup_solicit_msg(ct, NULL)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, setup solicit message: %s.", itron_strerror(error));
+		ct->error = error;
+		return;
+		}
+
+	/* SOLICIT ã¡ãã»ã¼ã¸ãéä¿¡ããã*/
+	error = UDP_SND_DAT(ct->cepid, &ct->dst, &ct->snd_msg->msg, ct->snd_msg->len, TMO_NBLK);
+	if (error != E_WBLK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, send solicit message: %s.", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* åéä¿¡ã¿ã¤ã ã¢ã¦ããè¨­å®ããã*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_SND_SOL] = SYSTIM2TIMER(ct->RT);
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/* åéä¿¡ã¿ã¤ã ã¢ã¦ããæ´æ°ããã*/
+	advance_retrans(ct);
+	}
+
+/*
+ *  request_ia_option -- REQUEST ã¡ãã»ã¼ã¸ã® IA_NA/IA_TA/IA_PD ãªãã·ã§ã³ã®å
+±éé¨åãè¿½å ããã
+ */
+
+#if defined(DHCP6_CLI_CFG_IA_NA) || defined(DHCP6_CLI_CFG_IA_TA) || defined(DHCP6_CLI_CFG_IA_PD)
+
+static uint8_t *
+request_ia_option (T_DHCP6_CLI_CONTEXT *ct, uint8_t *msg, uint_t code, uint8_t *lease)
+{
+	T_DHCP6_OPT_IA_NA_PD	*dst, *src;
+
+	dst = (T_DHCP6_OPT_IA_NA_PD*)msg;
+	src = (T_DHCP6_OPT_IA_NA_PD*)lease;
+
+	/* ãªãã·ã§ã³ã³ã¼ããè¨­å®ããã*/
+	HOST2MSG16(dst->code, code);
+
+	/* IA_NAIA_TA/IA_PD ãªãã·ã§ã³ãé¤ãããªãã·ã§ã³é·ãè¨­å®ããã*/
+	HOST2MSG16(dst->len, sizeof(*dst) - (sizeof(dst->code) + sizeof(dst->len)));
+
+	/* ADVERTISE ã¡ãã»ã¼ã¸ãã IA ID ãã³ãã¼ããã*/
+	memcpy(&dst->iaid, &src->iaid, sizeof(src->iaid));
+
+	return msg + sizeof(uint16_t) * 2 + sizeof(uint32_t);
+	}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_IA_NA) || defined(DHCP6_CLI_CFG_IA_TA) || defined(DHCP6_CLI_CFG_IA_PD) */
+
+/*
+ *  request_ia_na_pd -- REQUEST ã¡ãã»ã¼ã¸ã® IA_NA/IA_PD ãªãã·ã§ã³ãè¿½å ããã
+ */
+
+#if defined(DHCP6_CLI_CFG_IA_NA) || defined(DHCP6_CLI_CFG_IA_PD)
+
+static uint8_t *
+request_ia_na_pd (T_DHCP6_CLI_CONTEXT *ct, uint8_t *msg, uint_t msg_type, uint_t opt_code, T_DHCP6_CLI_MSG *lease)
+{
+	T_DHCP6_OPT_IA_NA_PD	*dia,  *sia;
+	T_DHCP6_OPT_IAADDR	*diaa, *siaa;
+	uint8_t			*opt;
+	uint32_t		t1, t2;
+	uint_t			ix, nsiaa;
+
+	/* ADVERTISE ã¡ãã»ã¼ã¸ã«æå®ããããªãã·ã§ã³ããããã¨ãç¢ºèªããã*/
+	if ((opt = find_msg_option(lease, opt_code, 0)) == NULL)
+		return msg;
+
+	/* IA_NA/IA_TA/IA_PD ãªãã·ã§ã³ã®å
+±éé¨åãè¿½å ããã*/
+	dia = (T_DHCP6_OPT_IA_NA_PD*)msg;
+	sia = (T_DHCP6_OPT_IA_NA_PD*)opt;
+	msg = request_ia_option(ct, msg, opt_code, opt);
+
+	/* T1ãT2 ãæ±ºå®ããã*/
+	switch (msg_type) {
+	case DHCP6_REQUEST:
+	case DHCP6_RENEW:
+	case DHCP6_REBIND:
+		t1 = SYSTIM2TIMER(TMO_DHCP6C_REQ_LEASE);
+		t2 = t1 + (t1 / 2);
+		break;
+
+	case DHCP6_CONFIRM:
+	case DHCP6_RELEASE:
+	case DHCP6_DECLINE:
+		t1 = t2 = 0;
+		break;
+
+	default:
+		syslog(LOG_NOTICE, "[DHCP6C] unkown msg_type in setup IA_NA/IA_PD for request message: %d.", msg_type);
+		return NULL;
+		break;
+		}
+
+	/* T1ãT2 ãè¨­å®ããã*/
+	HOST2MSG32(dia->renew,  t1);
+	HOST2MSG32(dia->rebind, t2);
+	msg += sizeof(dia->renew) + sizeof(dia->rebind);
+
+	/* IAADDR ãªãã·ã§ã³ãè¨­å®ããã*/
+	nsiaa = ((MSG2HOST16(sia->len) & ~DHCP6C_IAA_FLAG_MASK) - (sizeof(*sia) - (sizeof(sia->code) + sizeof(sia->len)))) / sizeof(*siaa);
+
+	for (ix = 0; ix <nsiaa; ix++) {
+		diaa = (T_DHCP6_OPT_IAADDR*)(msg + sizeof(*diaa) * ix);
+		siaa = (T_DHCP6_OPT_IAADDR*)((opt + sizeof(*sia)) + sizeof(*siaa) * ix);
+
+		/* ã¢ãã¬ã¹ã®æå¹æéãåãã¦ããã°ã¹ã­ããããã*/
+		if (MSG2HOST16(siaa->len) & DHCP6C_IAA_FLAG_EXPIRED)
+			continue;
+
+		/* ã³ã¼ãã¨é·ããè¨­å®ããã*/
+		memcpy(&diaa->code, &siaa->code, sizeof(siaa->code));
+		HOST2MSG16(diaa->len, MSG2HOST16(siaa->len) & ~DHCP6C_IAA_FLAG_MASK);
+		msg += sizeof(dia->code) + sizeof(dia->len);
+
+		/* IPv6 ã¢ãã¬ã¹ãã³ãã¼ããã*/
+		memcpy(&diaa->addr, &siaa->addr, sizeof(siaa->addr));
+		msg += sizeof(diaa->addr);
+
+		/* T1ãT2 ãæ±ºå®ããã*/
+		switch (msg_type) {
+		case DHCP6_REQUEST:
+		case DHCP6_RENEW:
+		case DHCP6_REBIND:
+			t1 = SYSTIM2TIMER(TMO_DHCP6C_REQ_LEASE);
+			t2 = t1 + 300;
+			break;
+
+		case DHCP6_CONFIRM:
+		case DHCP6_RELEASE:
+		case DHCP6_DECLINE:
+			t1 = t2 = 0;
+			break;
+
+		default:
+			syslog(LOG_NOTICE, "[DHCP6C] unknown msg_type in setup IA_NA/IA_PD for request: %d.", msg_type);
+			return NULL;
+			break;
+			}
+
+		/* T1ãT2 ãè¨­å®ããã*/
+		HOST2MSG32(diaa->prefer, t1);
+		HOST2MSG32(diaa->valid,  t2);
+		msg += sizeof(diaa->prefer) + sizeof(diaa->valid);
+
+		/* IAADDR ã«ä»å ãªãã·ã§ã³ãè¿½å ãããå
+éããã*/
+		}
+
+	HOST2MSG16(((T_DHCP6_OPTION*)dia)->len, 
+	MSG2HOST16(((T_DHCP6_OPTION*)dia)->len) + (msg - (uint8_t*)dia) - sizeof(*dia));
+	return msg;
+	}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_IA_NA) || defined(DHCP6_CLI_CFG_IA_PD) */
+
+/*
+ *  request_ia_ta -- REQUEST ã¡ãã»ã¼ã¸ã® IA_TA ãªãã·ã§ã³ãè¿½å ããã
+ */
+
+#if defined(DHCP6_CLI_CFG_IA_TA)
+
+static uint8_t *
+request_ia_ta (T_DHCP6_CLI_CONTEXT *ct, uint8_t *msg, uint_t msg_type, T_DHCP6_CLI_MSG *lease)
+{
+	T_DHCP6_OPT_IA_TA	*dia,  *sia;
+	T_DHCP6_OPT_IAADDR	*diaa, *siaa;
+	uint8_t			*opt;
+	uint32_t		t1, t2;
+	uint_t			ix, nsiaa;
+
+	/* ADVERTISE ã¡ãã»ã¼ã¸ã« IA_TA ãªãã·ã§ã³ããããã¨ãç¢ºèªããã*/
+	if ((opt = find_msg_option(lease, DHCP6_OPT_IA_TA, 0)) == NULL)
+		return msg;
+
+	/* IA_NA/IA_TA/IA_PD ãªãã·ã§ã³ã®å
+±éé¨åãè¿½å ããã*/
+	dia = (T_DHCP6_OPT_IA_TA*)msg;
+	sia = (T_DHCP6_OPT_IA_TA*)opt;
+	msg = request_ia_option(ct, msg, DHCP6_OPT_IA_TA, opt);
+
+	/* IAADDR ãªãã·ã§ã³ãè¨­å®ããã*/
+	nsiaa = ((MSG2HOST16(sia->len) & ~DHCP6C_IAA_FLAG_MASK) - (sizeof(*sia) - (sizeof(sia->code) + sizeof(sia->len)))) / sizeof(*siaa);
+
+	for (ix = 0; ix <nsiaa; ix++) {
+		diaa = (T_DHCP6_OPT_IAADDR*)(msg + sizeof(*diaa) * ix);
+		siaa = (T_DHCP6_OPT_IAADDR*)((opt + sizeof(*sia)) + sizeof(*siaa) * ix);
+
+		/* ã¢ãã¬ã¹ã®æå¹æéãåãã¦ããã°ã¹ã­ããããã*/
+		if (MSG2HOST16(siaa->len) & DHCP6C_IAA_FLAG_EXPIRED)
+			continue;
+
+		/* ã³ã¼ãã¨é·ããè¨­å®ããã*/
+		memcpy(diaa->code, siaa->code, sizeof(siaa->code));
+		diaa->len  = HOST2MSG16(MSG2HOST16(siaa->len) & ~DHCP6C_IAA_FLAG_MASK);
+		msg += sizeof(dia->code) + sizeof(dia->len);
+
+		/* IPv6 ã¢ãã¬ã¹ãã³ãã¼ããã*/
+		memcpy(diaa->addr, siaa->addr, sizeof(siaa->addr));
+		msg += sizeof(diaa->addr);
+
+		/* T1ãT2 ãæ±ºå®ããã*/
+		switch (msg_type) {
+		case DHCP6_REQUEST:
+		case DHCP6_RENEW:
+		case DHCP6_REBIND:
+			t1 = SYSTIM2TIMER(TMO_DHCP6C_REQ_LEASE);
+			t2 = t1 + 300;
+			break;
+
+		case DHCP6_CONFIRM:
+		case DHCP6_RELEASE:
+		case DHCP6_DECLINE:
+			t1 = t2 = 0;
+			break;
+
+		default:
+			syslog(LOG_NOTICE, "[DHCP6C] unknown msg_type in setup IA_TA for request message: %d.", msg_type);
+			return NULL;
+			break;
+			}
+
+		/* T1ãT2 ãè¨­å®ããã*/
+		HOST2MSG32(diaa->prefer, t1);
+		HOST2MSG32(diaa->valid,  t2);
+		msg += sizeof(diaa->prefer) + sizeof(diaa->valid);
+
+		/* IAADDR ã«ä»å ãªãã·ã§ã³ãè¿½å ãããå
+éããã*/
+		}
+
+	return msg;
+	}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG_IA_TA) */
+
+/*
+ *  setup_request_msg -- REQUEST ã¡ãã»ã¼ã¸ãä½æããã
+ */
+
+static ER
+setup_request_msg (T_DHCP6_CLI_CONTEXT *ct, T_DHCP6_CLI_MSG *lease, uint_t type)
+{
+	uint8_t	*msg;
+
+	/* ã¡ãã»ã¼ã¸ã®ãããé¨åãä½æããã*/
+	if ((msg = setup_msg_header(ct, type)) == NULL)
+		return E_PAR;
+
+	if ((msg = common_options(ct, msg, type, lease)) == NULL)
+		return E_PAR;
+
+#if defined(DHCP6_CLI_CFG_IA_NA)
+
+	/* IA_NA ãè¿½å ããã*/
+	msg = request_ia_na_pd(ct, msg, type, DHCP6_OPT_IA_NA, lease);
+#endif
+
+#if defined(DHCP6_CLI_CFG_IA_TA)
+
+	/* IA_TA ãè¿½å ããã*/
+	msg = request_ia_ta(ct, msg, type, lease);
+#endif
+
+#if defined(DHCP6_CLI_CFG_IA_PD)
+
+	/* IA_PD ãè¿½å ããã*/
+	msg = request_ia_na_pd(ct, msg, type, DHCP6_OPT_IA_PD, lease);
+#endif
+
+	/* ã¡ãã»ã¼ã¸æ§é ä½é·ãè¨­å®ããã*/
+	ct->snd_msg->len = msg - (uint8_t*)&ct->snd_msg->msg;
+	return E_OK;
+	}
+
+/*
+ *  send_request_msg -- REQUEST ã¡ãã»ã¼ã¸ãéä¿¡ããã
+ */
+
+static void
+send_request_msg (T_DHCP6_CLI_CONTEXT *ct)
+{
+	ER	error;
+
+	ct->error = E_OK;
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+
+	/* ADVERTISE ã¡ãã»ã¼ã¸ãåä¿¡ãã¦ããªããã°ã¨ã©ã¼ */
+	if (ct->adv_msg == NULL) {
+		ct->error  = E_OBJ;
+		return;
+		}
+
+	/* REPLY ã¡ãã»ã¼ã¸ã®é¸æãçµäºãã¦ããã°ãBOUND ç¶æ
+ã«é·ç§»ããã*/
+	if (select_reply(ct)) {
+
+		/* REPLY ã¡ãã»ã¼ã¸åä¿¡ã¿ã¤ãã¼ãåæ­¢ããã*/
+		syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+		ct->timers[DHCP6C_TIMER_RCV_REPLY] = 0;
+		syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	 	/* ADVERTISE ã¡ãã»ã¼ã¸ãåä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ãã«æ»ãã*/
+		syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+		ct->adv_msg->next = ct->rcv_lst;
+		ct->rcv_lst = ct->adv_msg;
+		ct->adv_msg = NULL;
+		syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+
+		/* BOUND ç¶æ
+ã«é·ç§»ããã*/
+		start_bound(ct);
+		return;
+		}
+
+	/* åéä¿¡åæ°ãç¢ºèªããã*/
+	if ((ct->MRC != 0) && (ct->txcount > ct->MRC)) {
+		ct->error  = E_TMOUT;
+		return;
+		}
+
+	/* REQUEST ã¡ãã»ã¼ã¸ãä½æããã*/
+	if ((error = setup_request_msg(ct, ct->adv_msg, DHCP6_REQUEST)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, setup request message: %s.", itron_strerror(error));
+		ct->error = error;
+		return;
+		}
+
+	/* REQUEST ã¡ãã»ã¼ã¸ãéä¿¡ããã*/
+	error = UDP_SND_DAT(ct->cepid, &ct->dst, &ct->snd_msg->msg, ct->snd_msg->len, TMO_NBLK);
+	if (error != E_WBLK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, send request message: %s.", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* åéä¿¡ã¿ã¤ã ã¢ã¦ããè¨­å®ããã*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_SND_REQ] = SYSTIM2TIMER(ct->RT);
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/* åéä¿¡ã¿ã¤ã ã¢ã¦ããæ´æ°ããã*/
+	advance_retrans(ct);
+	}
+
+/*
+ *  send_refresh_msg -- REFRESH ã¡ãã»ã¼ã¸ãéä¿¡ããã
+ */
+
+static void
+send_refresh_msg (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_OPT_UNICAST	*uc;
+	ER			error;
+	uint8_t			*opt;
+
+	/* æå¹ãªãªã¼ã¹æ
+å ±ããªããã°ã¨ã©ã¼ */
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+	if (ct->act_msg == NULL)
+		ct->error = E_OBJ;
+
+	/* REFRESH ã¿ã¤ãã RENEW ã¾ãã¯ REBIND ã§ãªããã°ã¨ã©ã¼ */
+	if (!((ct->refresh_type == DHCP6_RENEW) || (ct->refresh_type == DHCP6_REBIND)))
+		ct->error = E_PAR;
+
+	/* REPLY ã¡ãã»ã¼ã¸ã®é¸æãçµäºãã¦ããã°ãBOUND ç¶æ
+ã«é·ç§»ããã*/
+	if (select_reply(ct)) {
+
+		/* REPLY ã¡ãã»ã¼ã¸åä¿¡ã¿ã¤ãã¼ãåæ­¢ããã*/
+		syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+		ct->timers[DHCP6C_TIMER_RCV_REPLY] = 0;
+		syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+		/* ãªã¼ã¹æ
+å ±ãè§£æ¾ããã*/
+		rel_lease(ct);
+
+		/* BOUND ç¶æ
+ã«é·ç§»ããã*/
+		start_bound(ct);
+		return;
+		}
+
+	/* åéä¿¡åæ°ãç¢ºèªããã*/
+	if ((ct->MRC != 0) && (ct->txcount > ct->MRC)) {
+		eval_expire(ct);
+		return;
+		}
+
+	/*
+	 *  ãµã¼ããã UNICAST ãªãã·ã§ã³ãåä¿¡ããã¨ãã¯
+	 *  æå®ããã¢ãã¬ã¹ãéä¿¡å
+ã¢ãã¬ã¹ã«è¨­å®ããã
+	 */
+	if ((opt = find_msg_option(ct->act_msg, DHCP6_OPT_UNICAST, sizeof(T_DHCP6_OPT_UNICAST))) != NULL) {
+		uc = (T_DHCP6_OPT_UNICAST*)opt;
+		ct->dst.ipaddr = uc->addr;
+		}
+
+	/* REFRESH (REQUEST) ã¡ãã»ã¼ã¸ãä½æããã*/
+	if ((error = setup_request_msg(ct, ct->act_msg, ct->refresh_type)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, setup refresh message: %s.", itron_strerror(error));
+		ct->error = error;
+		return;
+		}
+
+	/* REFRESH ã¡ãã»ã¼ã¸ãéä¿¡ããã*/
+	error = UDP_SND_DAT(ct->cepid, &ct->dst, &ct->snd_msg->msg, ct->snd_msg->len, TMO_NBLK);
+	if (error != E_WBLK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, send refresh message: %s.", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* åéä¿¡ã¿ã¤ã ã¢ã¦ããè¨­å®ããã*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_SND_REF] = SYSTIM2TIMER(ct->RT);
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/* åéä¿¡ã¿ã¤ã ã¢ã¦ããæ´æ°ããã*/
+	advance_retrans(ct);
+	}
+
+/*
+ *  setup_release_msg -- RELEASE ã¡ãã»ã¼ã¸ãä½æããã
+ */
+
+static ER
+setup_release_msg (T_DHCP6_CLI_CONTEXT *ct, T_DHCP6_CLI_MSG *lease, uint_t type)
+{
+	uint8_t	*msg;
+
+	/* ã¡ãã»ã¼ã¸ã®ãããé¨åãä½æããã*/
+	if ((msg = setup_msg_header(ct, type)) == NULL)
+		return E_PAR;
+
+	if ((msg = common_options(ct, msg, type, lease)) == NULL)
+		return E_PAR;
+
+#if defined(DHCP6_CLI_CFG_IA_NA)
+
+	/* IA_NA ãè¿½å ããã*/
+	msg = request_ia_na_pd(ct, msg, type, DHCP6_OPT_IA_NA, lease);
+#endif
+
+#if defined(DHCP6_CLI_CFG_IA_PD)
+
+	/* IA_PD ãè¿½å ããã*/
+	msg = request_ia_na_pd(ct, msg, type, DHCP6_OPT_IA_PD, lease);
+#endif
+
+	/* ã¡ãã»ã¼ã¸æ§é ä½é·ãè¨­å®ããã*/
+	ct->snd_msg->len = msg - (uint8_t*)&ct->snd_msg->msg;
+	return E_OK;
+	}
+
+/*
+ *  send_release_msg -- RELEASE ã¡ãã»ã¼ã¸ãéä¿¡ããã
+ */
+
+static void
+send_release_msg (T_DHCP6_CLI_CONTEXT *ct)
+{
+	ER	error;
+
+	/* æå¹ãª REPLY ã¡ãã»ã¼ã¸ãåä¿¡ãã¦ããªããã°ã¨ã©ã¼ */
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+	if (ct->act_msg == NULL)
+		ct->error = E_OBJ;
+
+	/* æå¹ãª REPLY ã¡ãã»ã¼ã¸ãåä¿¡ãã¦ããã°ãSLEEP ç¶æ
+ã«é·ç§»ããã*/
+	syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+	if (ct->prf_lst != NULL) {
+
+		/* åéä¿¡ã¿ã¤ãã¼ãåæ­¢ããã*/
+		syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+		ct->timers[DHCP6C_TIMER_RCV_REPLY] = 0;
+		syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+		/* æå¹ãªãªã¼ã¹ã»ã¡ãã»ã¼ã¸æ§é ä½ãè§£æ¾ããã*/
+		if (ct->act_msg != NULL) {
+			syscall(rel_mpf(MPF_DHCP6_CLI_MSG, (void*)ct->act_msg));
+			ct->act_msg = NULL;
+			}
+
+		/* SLEEP ç¶æ
+ã«é·ç§»ããã*/
+		ct->fsm    = DHCP6_FSM_SLEEP;
+		syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+		return;
+		}
+	syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+
+	/* åéä¿¡åæ°ãç¢ºèªããã*/
+	if ((ct->MRC != 0) && (ct->txcount > ct->MRC)) {
+		ct->error  = E_TMOUT;
+		return;
+		}
+
+	/* RELEASE ã¡ãã»ã¼ã¸ãä½æããã*/
+	if ((error = setup_release_msg(ct, ct->act_msg, DHCP6_RELEASE)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, setup release message: %s.", itron_strerror(error));
+		ct->error = error;
+		return;
+		}
+
+	/* RELEASE ã¡ãã»ã¼ã¸ãéä¿¡ããã*/
+	error = UDP_SND_DAT(ct->cepid, &ct->dst, &ct->snd_msg->msg, ct->snd_msg->len, TMO_NBLK);
+	if (error != E_WBLK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, send release message: %s.", itron_strerror(error));
+		ct->error  = error;
+		return;
+		}
+
+	/* åéä¿¡ã¿ã¤ã ã¢ã¦ããè¨­å®ããã*/
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_SND_REL] = SYSTIM2TIMER(ct->RT);
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	/* åéä¿¡ã¿ã¤ã ã¢ã¦ããæ´æ°ããã*/
+	advance_retrans(ct);
+	}
+
+/*
+ *  advertise_msg_timeout -- ADVERTISE ã¡ãã»ã¼ã¸ã®ã¿ã¤ã ã¢ã¦ãå¦ç
+ */
+
+static void
+advertise_msg_timeout (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* SOLICIT ã¡ãã»ã¼ã¸éä¿¡ã¿ã¤ãã¼ãåæ­¢ããã*/
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_SND_SOL] = 0;
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+	if (select_adv(ct)) {
+		/*
+		 *  ADVERTISE ã¡ãã»ã¼ã¸ã®é¸æãçµäºãã¦ããã°ã
+ 		 *  REQUEST ã¡ãã»ã¼ã¸ãéä¿¡ãã¦ SELECT ç¶æ
+ã«é·ç§»ããã
+ 		 */
+ 		start_select(ct);
+		}
+	else
+		ct->error  = E_TMOUT;
+	}
+
+/*
+ *  renew_timeout -- RENEW ã¿ã¤ã ã¢ã¦ãå¦ç
+ */
+
+static void
+renew_timeout (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* RENEW ç¶æ
+ã«é·ç§»ããã*/
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+	start_renew(ct);
+	}
+
+/*
+ *  rebind_timeout -- REBIND ã¿ã¤ã ã¢ã¦ãå¦ç
+ */
+
+static void
+rebind_timeout (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* REBIND ç¶æ
+ã«é·ç§»ããã*/
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+	start_rebind(ct);
+	}
+
+/*
+ *  depref_timeout -- DEPREF ã¿ã¤ã ã¢ã¦ãå¦ç
+ */
+
+static void
+depref_timeout (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_OPTION		*opt;
+	T_DHCP6_OPT_IA_NA_PD	*ia;
+	T_DHCP6_OPT_IAADDR	*iaa;
+	SYSTIM		time;
+	uint8_t		*msg, *last;
+	uint_t		aoff, asize;
+
+	/* æå¹ãªãªã¼ã¹ãç¡ããã°å¦ççµäº */
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+	if (ct->act_msg == NULL) {
+		return;
+		}
+
+	get_tim(&time);
+	msg = ct->act_msg->msg.options;
+	last = msg + (ct->act_msg->len - sizeof(T_DHCP6_MSG_HDR));
+	while (msg < last) {
+
+		/* IA_NA/IA_PD ãªãã·ã§ã³ã§ããã°ãæ¨å¥¨æå¹æéãç¢ºèªããã*/
+		opt = (T_DHCP6_OPTION*)msg;
+		if (MSG2HOST16(opt->code) == DHCP6_OPT_IA_NA || MSG2HOST16(opt->code) == DHCP6_OPT_IA_PD) {
+
+			ia = (T_DHCP6_OPT_IA_NA_PD*)opt;
+			asize = MSG2HOST16(ia->len) + sizeof(*opt);
+			for (aoff  = sizeof(*ia); aoff < asize;
+				                  aoff += (MSG2HOST16(iaa->len) & ~DHCP6C_IAA_FLAG_MASK) + sizeof(*iaa)) {
+
+				/* ãã§ã«æ¨å¥¨æå¹æéãçµéãã¦ããã°å¦çããªãã*/
+				iaa = (T_DHCP6_OPT_IAADDR*)((uint8_t*)opt + aoff);
+				if ((MSG2HOST16(iaa->len) & DHCP6C_IAA_FLAG_DEPREFERD))
+					continue;
+
+				/* æ¨å¥¨æå¹æéçµéãã¦ããã° FLAG ãè¨­å®ããã*/
+				if (TIMEC_GE(time, ct->act_msg->rcv_time + MSG2HOST32(iaa->prefer))) {
+					HOST2MSG16(iaa->len, MSG2HOST16(iaa->len) | DHCP6C_IAA_FLAG_DEPREFERD);
+					if (MSG2HOST16(ia->code) == DHCP6_OPT_IA_NA)
+						syslog(LOG_NOTICE, "[DHCP6C] address depreferd: %s.", ipv62str(NULL, &iaa->addr));
+					else
+						syslog(LOG_NOTICE, "[DHCP6C] prefix  depreferd: %s.", ipv62str(NULL, &iaa->addr));
+
+					/*ãDNS ã®å¦çãå¿
+è¦ã*/
+					}
+				}
+			}
+		msg += MSG2HOST16(opt->len) + sizeof(*opt);
+		}
+
+	eval_expire(ct);
+	}
+
+/*
+ *  expire_timeout -- EXPIRE ã¿ã¤ã ã¢ã¦ãå¦ç
+ */
+
+static void
+expire_timeout (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_OPTION		*opt;
+	T_DHCP6_OPT_IA_NA_PD	*ia;
+	T_DHCP6_OPT_IAADDR	*iaa;
+	SYSTIM		time;
+	uint8_t		*msg, *last;
+	uint_t		aoff, asize, addrs = 0;
+
+	/* æå¹ãªãªã¼ã¹ãç¡ããã°å¦ççµäº */
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+	if (ct->act_msg == NULL) {
+		return;
+		}
+
+	get_tim(&time);
+	msg = ct->act_msg->msg.options;
+	last = msg + (ct->act_msg->len - sizeof(T_DHCP6_MSG_HDR));
+	while (msg < last) {
+
+		/* IA_NA/IA_PD ãªãã·ã§ã³ã§ããã°ãæå¹æéãç¢ºèªããã*/
+		opt = (T_DHCP6_OPTION*)msg;
+		if (MSG2HOST16(opt->code) == DHCP6_OPT_IA_NA || MSG2HOST16(opt->code) == DHCP6_OPT_IA_PD) {
+
+			ia = (T_DHCP6_OPT_IA_NA_PD*)opt;
+			asize = MSG2HOST16(ia->len) + sizeof(*opt);
+			for (aoff  = sizeof(*ia); aoff < asize;
+				                  aoff += (MSG2HOST16(iaa->len) & ~DHCP6C_IAA_FLAG_MASK) + sizeof(*iaa)) {
+
+				/* ãã§ã«æå¹æéãçµéãã¦ããã°å¦çããªãã*/
+				iaa = (T_DHCP6_OPT_IAADDR*)((uint8_t*)opt + aoff);
+				if ((MSG2HOST16(iaa->len) & DHCP6C_IAA_FLAG_EXPIRED))
+					continue;
+
+				/* æå¹æéçµéãã¦ããã° FLAG ãè¨­å®ããã*/
+				if (TIMEC_GE(time, ct->act_msg->rcv_time + MSG2HOST32(iaa->valid))) {
+					HOST2MSG16(iaa->len, MSG2HOST16(iaa->len) | DHCP6C_IAA_FLAG_EXPIRED);
+					if (MSG2HOST16(ia->code) == DHCP6_OPT_IA_NA)
+						syslog(LOG_NOTICE, "[DHCP6C] address expired: %s.", ipv62str(NULL, &iaa->addr));
+					else
+						syslog(LOG_NOTICE, "[DHCP6C] prefix  expired: %s.", ipv62str(NULL, &iaa->addr));
+
+					/*ãDNS ã®å¦çãå¿
+è¦ã*/
+					continue;
+					}
+				addrs ++;
+				}
+			}
+		msg += MSG2HOST16(opt->len) + sizeof(*opt);
+		}
+
+	/* æå¹ãªã¢ãã¬ã¹ãå
+¨ã¦ç¡ããªã£ãæã¯ INIT ç¶æ
+ã«é·ç§»ããã*/
+	if (addrs == 0) {
+
+	 	/* ACTIVE ãªã¼ã¹ãåä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ãã«æ»ãã*/
+		syslog(LOG_NOTICE, "[DHCP6C] all address expired.");
+		syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+		ct->act_msg->next = ct->rcv_lst;
+		ct->rcv_lst = ct->act_msg;
+		ct->act_msg = NULL;
+		syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+
+		/* å
+¨ã¦ã® TIMER ãã­ã£ã³ã»ã«ããã*/
+		cancel_all_timers(ct);
+
+		/* INIT ç¶æ
+ã«é·ç§»ããã*/
+		start_init(ct);
+		return;
+		}
+
+	eval_expire(ct);
+	}
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA */
+
+/*
+ *  reply_msg_timeout -- REPLY ã¡ãã»ã¼ã¸ã®ã¿ã¤ã ã¢ã¦ãå¦ç
+ */
+
+static void
+reply_msg_timeout (T_DHCP6_CLI_CONTEXT *ct)
+{
+	/* SOLICIT ã¡ãã»ã¼ã¸éä¿¡ã¿ã¤ãã¼ãåæ­¢ããã*/
+	ct->flags &= ~DHCP6C_FLAG_TMOUT_MASK;
+	syscall(wai_sem(SEM_DHCP6_CLI_TIMER));
+	ct->timers[DHCP6C_TIMER_SND_REQ] = 0;
+	ct->timers[DHCP6C_TIMER_SND_REF] = 0;
+	syscall(sig_sem(SEM_DHCP6_CLI_TIMER));
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA
+
+	/* STATELES ã¢ã¼ãã§ã¯SLEEP ã«é·ç§»ããã*/
+	ct->error = E_TMOUT;
+	ct->fsm   = DHCP6_FSM_SLEEP;
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA */
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA
+
+	/* RENEW ã¡ãã»ã¼ã¸ã®é¸æãçµäºãã¦ããã°ãBOUND ç¶æ
+ã«é·ç§»ããã*/
+	if (select_reply(ct)) {
+
+		/* ãªã¼ã¹æ
+å ±ãè§£æ¾ããã*/
+		rel_lease(ct);
+
+		/* BOUND ç¶æ
+ã«é·ç§»ããã*/
+		start_bound(ct);
+		}
+	else if (ct->fsm == DHCP6_FSM_RENEW || ct->fsm == DHCP6_FSM_REBIND)
+		eval_expire(ct);
+	else {
+		/* SLEEP ã«é·ç§»ããã*/
+		ct->error = E_TMOUT;
+		ct->fsm   = DHCP6_FSM_SLEEP;
+		}
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA */
+	}
+
+/*
+ *  dispatch_timeout -- ã¿ã¤ã ã¢ã¦ãããæã®å¦ç
+ */
+
+static ER
+dispatch_timeout (T_DHCP6_CLI_CONTEXT *ct)
+{
+
+	switch (ct->flags & DHCP6C_FLAG_TMOUT_TIMER_MASK) {
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA
+
+	case DHCP6C_TIMER_SND_IREQ:
+		send_info_req_msg(ct);
+		break;
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA */
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA
+
+	case DHCP6C_TIMER_SND_SOL:
+		send_solicit_msg(ct);
+		break;
+
+	case DHCP6C_TIMER_SND_REQ:
+		send_request_msg(ct);
+		break;
+
+	case DHCP6C_TIMER_SND_REF:
+		send_refresh_msg(ct);
+		break;
+
+	case DHCP6C_TIMER_SND_REL:
+		send_release_msg(ct);
+		break;
+
+	case DHCP6C_TIMER_RCV_ADV:
+		advertise_msg_timeout(ct);
+		break;
+
+	case DHCP6C_TIMER_RENEW:
+		renew_timeout(ct);
+		break;
+
+	case DHCP6C_TIMER_REBIND:
+		rebind_timeout(ct);
+		break;
+
+	case DHCP6C_TIMER_DEPREF:
+		depref_timeout(ct);
+		break;
+
+	case DHCP6C_TIMER_EXPIRE:
+		expire_timeout(ct);
+		break;
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL || DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_RA */
+
+	case DHCP6C_TIMER_RCV_REPLY:
+		reply_msg_timeout(ct);
+		break;
+
+	default:
+		syslog(LOG_NOTICE, "[DHCP6C] error, unknown timeout: %d.", ct->flags & DHCP6C_FLAG_TMOUT_TIMER_MASK);
+		break;
+		}
+
+	return ct->error;
+	}
+
+/*
+ *  dispatch_event -- ã¤ãã³ãæ¯ã®å¦ç
+ */
+
+static ER
+dispatch_event (T_DHCP6_CLI_CONTEXT *ct)
+{
+	ER	error = E_OK;
+
+	while (ct->fsm != DHCP6_FSM_SLEEP && error == E_OK) {
+
+		/* ã¡ãã»ã¼ã¸ã®éåä¿¡ã¨ã¿ã¤ã ã¢ã¦ããå¾
+ã¤ã*/
+		syscall(wai_sem(SEM_DHCP6_CLI_READY));
+
+		if (ct->flags & DHCP6C_FLAG_RCV_MSG) {
+			while (ct->val_lst != NULL) {
+				error = eval_rcv_msg(ct);
+				}
+			ct->flags &= ~DHCP6C_FLAG_RCV_MSG;
+			}
+
+		if (ct->flags & DHCP6C_FLAG_TMOUT_MASK)
+			error = dispatch_timeout(ct);
+
+		if (ct->error != E_OK)
+			error = ct->error;
+		}
+
+	return error;
+	}
+
+/*
+ *  init_context -- DHCPv6 ã¯ã©ã¤ã¢ã³ãã³ã³ãã­ã¹ãæ§é ä½ãåæåããã
+ */
+
+static void
+init_context (T_DHCP6_CLI_CONTEXT *ct, ID cepid)
+{
+  	memset(ct, 0, sizeof(*ct));
+	ct->cepid	= cepid;
+	ct->sc		= IF_ETHER_NIC_GET_SOFTC();
+	ct->dst.portno	= DHCP6_SRV_CFG_PORTNO;
+	}
+
+/*
+ *  rel_cli_msg -- ã¡ãã»ã¼ã¸æ§é ä½ãè§£æ¾ããã
+ */
+
+static void
+rel_cli_msg (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_CLI_MSG	*ptr, *cell;
+
+	syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+	for (ptr = ct->rcv_lst; ptr != NULL; ) {
+		cell = ptr;
+		ptr = ptr->next;
+		syscall(rel_mpf(MPF_DHCP6_CLI_MSG, (void*)cell));
+		}
+
+	for (ptr = ct->val_lst; ptr != NULL; ) {
+		cell = ptr;
+		ptr = ptr->next;
+		syscall(rel_mpf(MPF_DHCP6_CLI_MSG, (void*)cell));
+		}
+
+	for (ptr = ct->prf_lst; ptr != NULL; ) {
+		cell = ptr;
+		ptr = ptr->next;
+		syscall(rel_mpf(MPF_DHCP6_CLI_MSG, (void*)cell));
+		}
+
+	if (ct->snd_msg != NULL)
+		syscall(rel_mpf(MPF_DHCP6_CLI_MSG, (void*)ct->snd_msg));
+	if (ct->adv_msg != NULL)
+		syscall(rel_mpf(MPF_DHCP6_CLI_MSG, (void*)ct->adv_msg));
+	ct->rcv_lst = ct->prf_lst = ct->val_lst = ct->snd_msg = ct->adv_msg = NULL;
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS
+
+	/* ã¹ãã¼ãã¬ã¹ã®æã¯æå¹ãªãªã¼ã¹ã»ã¡ãã»ã¼ã¸æ§é ä½ãè§£æ¾ããã*/
+	if (ct->act_msg != NULL) {
+		syscall(rel_mpf(MPF_DHCP6_CLI_MSG, (void*)ct->act_msg));
+		ct->act_msg = NULL;
+		}
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS */
+
+	syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+	}
+
+/*
+ *  init_cli_msg -- åã¡ãã»ã¼ã¸æ§é ä½ãåæåããã
+ */
+
+static ER
+init_cli_msg (T_DHCP6_CLI_CONTEXT *ct)
+{
+	T_DHCP6_CLI_MSG	*cell;
+	ER		error;
+	int		count;
+
+	/* éä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãç²å¾ããã*/
+	if ((error = tget_mpf(MPF_DHCP6_CLI_MSG, (void*)&ct->snd_msg, TMO_DHCP6C_MPF_GET)) != E_OK) {
+		syslog(LOG_NOTICE, "[DHCP6C] error, tget_mpf() for send: %s.", itron_strerror(error));
+		return error;
+		}
+
+	/*
+	 *  æå¹ãªãªã¼ã¹ã»ã¡ãã»ã¼ã¸æ§é ä½ãããå ´åã¯ã
+	 *  ç²å¾ããåä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ãã®æ§é ä½ã 1æ¸ããã
+	 */
+	if (ct->act_msg == NULL)
+		count = NUM_DHCP6_CLI_MSG_LIST;
+	else
+		count = NUM_DHCP6_CLI_MSG_LIST - 1;
+
+	/* åä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãç²å¾ããã*/
+	syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+	while (count --> 0) {
+		if ((error = tget_mpf(MPF_DHCP6_CLI_MSG, (void*)&cell, TMO_DHCP6C_MPF_GET)) != E_OK) {
+			syslog(LOG_NOTICE, "[DHCP6C] error, tget_mpf() for receive: %s.", itron_strerror(error));
+			break;
+			}
+		cell->next  = ct->rcv_lst;
+		ct->rcv_lst = cell;
+		}
+	syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+
+	return E_OK;
+	}
+
+/*
+ *  dhcp6c_renew_info -- ãããã¯ã¼ã¯æ
+å ±ãååå¾ããã
+ */
+
+ER
+dhcp6c_renew_info (void)
+{
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS
+
+	if (context.fsm == DHCP6_FSM_INFORMED) {
+
+		/* REL_INFO ç¶æ
+ã«é·ç§»ããå¾ã« SLEEP ãè§£é¤ããããã«è¨­å®ããã*/
+		context.flags |= DHCP6C_FLAG_RENEW;
+		start_rel_info(&context);
+		return E_OK;
+		}
+	else if (context.fsm == DHCP6_FSM_SLEEP) {
+
+		/* SLEEP ãè§£é¤ããã*/
+		wup_tsk(DHCP6_CLI_TASK);
+		return E_OK;
+		}
+	else
+		return E_OBJ;
+
+#elif DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+
+	if (context.fsm == DHCP6_FSM_BOUND) {
+
+		/* RENEW ç¶æ
+ã«é·ç§»ããã*/
+		start_renew(&context);
+		return E_OK;
+		}
+	else if (context.fsm == DHCP6_FSM_SLEEP) {
+
+		/* SLEEP ãè§£é¤ããã*/
+		wup_tsk(DHCP6_CLI_TASK);
+		return E_OK;
+		}
+	else
+		return E_OBJ;
+
+#else	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS */
+
+#endif	/* of #if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS */
+
+	}
+
+/*
+ *  dhcp6c_rel_info -- DHCP ã§è¨­å®ããããããã¯ã¼ã¯æ
+å ±ãè§£æ¾ããã
+ */
+
+ER
+dhcp6c_rel_info (void)
+{
+	/* REL_INFO ç¶æ
+ã«é·ç§»ããã*/
+	start_rel_info(&context);
+	return E_OK;
+	}
+
+/*
+ *  dhcp6c_get_info -- DHCP ã§è¨­å®ããããããã¯ã¼ã¯æ
+å ±ãè¿ãã
+ */
+
+ER
+dhcp6c_get_info (T_IN6_ADDR *addr, uint32_t *expire, uint32_t *renew,
+                                   uint32_t *rebind, uint32_t *deprefer, SYSTIM *bind_start)
+{
+	if (addr   == NULL || expire ==   NULL || renew == NULL || 
+	    rebind == NULL || deprefer == NULL || bind_start == NULL)
+		return E_PAR;
+	else if (context.act_msg == NULL)
+		return E_OBJ;
+	else {
+		//            context.timers[DHCP6C_TIMER_EXPIRE],
+		//            context.timers[DHCP6C_TIMER_RENEW],
+		//            context.timers[DHCP6C_TIMER_REBIND],
+		//            context.timers[DHCP6C_TIMER_DEPREF]);
+
+		*addr = context.act_msg->srv.ipaddr;
+		*expire		= context.timers[DHCP6C_TIMER_EXPIRE];
+		*renew		= context.timers[DHCP6C_TIMER_RENEW];
+		*rebind		= context.timers[DHCP6C_TIMER_REBIND];
+		*deprefer	= context.timers[DHCP6C_TIMER_DEPREF];
+		*bind_start	= context.act_msg->rcv_time;
+		return E_OK;
+		}
+	}
+
+/*
+ *  ã³ã¼ã«ããã¯é¢æ°
+ */
+
+ER
+callback_nblk_dhcp6_cli (ID cepid, FN fncd, void *p_parblk)
+{
+	T_DHCP6_CLI_MSG	*msg;
+	ER_UINT		len;
+
+	len = *(ER_UINT*)p_parblk;
+	if (len < 0 && len != E_RLWAI) {
+		/* E_RLWAI ä»¥å¤ã§ã0 ä»¥ä¸ã®å ´åã¯ãã¨ã©ã¼ã³ã¼ã */
+		syslog(LOG_NOTICE, "[DHCP6C(CBR)] error: %s, fncd: %s.", itron_strerror(len), in_strtfn(fncd));
+		}
+	else {
+		if (fncd == TEV_UDP_RCV_DAT) {
+
+			/* åä¿¡ã¡ãã»ã¼ã¸ãªã¹ããç©ºã®æã¯ãåä¿¡ããªãã§ãã¼ã¿ã°ã©ã ãæ¨ã¦ãã*/
+			if (context.rcv_lst == NULL) 
+				syslog(LOG_NOTICE, "[DHCP6C(CBR)] receive buffer all busy.");
+			else {
+				/* ã¡ãã»ã¼ã¸ãåä¿¡ããã¡ãã»ã¼ã¸æ§é ä½ãæºåããã*/
+				syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+				msg = context.rcv_lst;
+				context.rcv_lst = context.rcv_lst->next;
+				syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+
+				/* ã¡ãã»ã¼ã¸ãåä¿¡ããã*/
+				len = UDP_RCV_DAT(context.cepid, &msg->srv, &msg->msg, sizeof(msg->msg), TMO_POL);
+
+				syscall(wai_sem(SEM_DHCP6_CLI_LOCK));
+				msg->len = len;
+				if (len >= 0) {
+					/* åä¿¡ããã¡ãã»ã¼ã¸ãæ¤è¨¼ã¡ãã»ã¼ã¸ãªã¹ãã«ç§»ãã*/
+					msg->next = context.val_lst;
+					context.val_lst = msg;
+					context.flags |= DHCP6C_FLAG_RCV_MSG;
+					}
+				else {
+					/* ã¡ãã»ã¼ã¸æ§é ä½ãåä¿¡ã¡ãã»ã¼ã¸ãªã¹ãã«æ»ãã*/
+					context.error = len;
+					msg->next = context.rcv_lst;
+					context.rcv_lst = msg;
+					}
+				syscall(sig_sem(SEM_DHCP6_CLI_LOCK));
+				}
+			}
+		syscall(sig_sem(SEM_DHCP6_CLI_READY));
+		}
+	return E_OK;
+	}
+/*
+ *  dhcp6_cli_task -- DHCPv6 ã¯ã©ã¤ã¢ã³ãã¿ã¹ã¯
+ */
+
+void
+dhcp6_cli_task (intptr_t exinf)
+{
+	T_DHCP6_CLI_CONTEXT	*ct;
+	ID			tskid;
+	ER			error;
+
+	dly_tsk(1000);
+	get_tid(&tskid);
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS
+	syslog(LOG_NOTICE, "[DHCP6C:%d] started in stateless.", tskid);
+#elif DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+	syslog(LOG_NOTICE, "[DHCP6C:%d] started in statefull.", tskid);
+#else
+#endif
+
+	dly_tsk(500);
+	ct = &context;
+
+	/* DHCP ã¯ã©ã¤ã¢ã³ãã³ã³ãã­ã¹ãæ§é ä½ãåæåããã*/
+	init_context(ct, (ID)exinf);
+
+	while (true) {
+
+		/* 1ç§æ¯ã«ã¿ã¤ã ã¢ã¦ãããããã«ã¿ã¤ãã¼ãè¨­å®ããã*/
+		timeout((callout_func)dhcpc_timer, ct, NET_TIMER_HZ / DHCP6C_TIMER_HZ);
+
+		/* ã¯ã©ã¤ã¢ã³ã DUID ãè¨­å®ããã*/
+		init_duid(ct);
+
+		/* ã¡ãã»ã¼ã¸æ§é ä½ãåæåããã*/
+		if ((error = init_cli_msg(ct))  == E_OK) {
+
+#if DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATELESS
+			start_req_info(ct);
+#elif DHCP6_CLI_CFG_MODE == DHCP6_CLI_CFG_STATEFULL
+			start_init(ct);
+#else
+#endif
+
+			/* ã¡ã¤ã³ã«ã¼ã */
+			error = dispatch_event(ct);
+			}
+
+		/* å
+¨ã¦ã® TIMER ãã­ã£ã³ã»ã«ããã*/
+		cancel_all_timers(ct);
+
+		/* ã¿ã¤ãã¼ãåæ­¢ããã*/
+		untimeout((callout_func)dhcpc_timer, ct);
+
+		/* ã¡ãã»ã¼ã¸æ§é ä½ãè§£æ¾ããã*/
+		rel_cli_msg(ct);
+
+		/* ãªã¼ã¹ãè§£æ¾å¾ãååå¾ãæå®ããã¦ããªããã°ä¼æ­¢ããã*/
+		if (!(ct->flags & DHCP6C_FLAG_RENEW)) {
+
+			/* ä¼æ­¢ããã*/
+			if (error == E_OK)
+				syslog(LOG_NOTICE, "[DHCP6C] lease released, go to sleep.");
+			else {
+				syslog(LOG_NOTICE, "[DHCP6C] server not available, go to sleep, error: %s.", itron_strerror(error));
+				ct->fsm = DHCP6_FSM_SLEEP;
+				}
+			slp_tsk();
+			}
+		ct->flags = 0;
+		ct->error = E_OK;
+		}
+	}
+
+#endif	/* of #ifdef DHCP6_CLI_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6_cli.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6_cli.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6_cli.cfg	(revision 331)
@@ -0,0 +1,70 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2011 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  DHCPv6 ã¯ã©ã¤ã¢ã³ã
+ *  ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ */
+
+#ifdef DHCP6_CLI_CFG
+
+/* ã¿ã¹ã¯ */
+
+CRE_TSK(DHCP6_CLI_TASK, {
+	TA_HLNG|TA_ACT,
+	UDP6_DHCP_CLI_CEPID,
+	dhcp6_cli_task,
+	DHCP6_CLI_MAIN_PRIORITY,
+	DHCP6_CLI_STACK_SIZE,
+	NULL
+	});
+
+/* ã»ããã© */
+
+CRE_SEM(SEM_DHCP6_CLI_READY,	{ TA_TPRI, 0, 1 });
+CRE_SEM(SEM_DHCP6_CLI_TIMER,	{ TA_TPRI, 1, 1 });
+CRE_SEM(SEM_DHCP6_CLI_LOCK,	{ TA_TPRI, 1, 1 });
+
+#endif	/* of #ifdef DHCP6_CLI_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6_cli.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6_cli.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6_cli.h	(revision 331)
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1995-2003 by Internet Software Consortium
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ *   Internet Systems Consortium, Inc.
+ *   950 Charter Street
+ *   Redwood City, CA 94063
+ *   <info@isc.org>
+ *   https://www.isc.org/
+ *
+ * This code is based on the original client state machine that was
+ * written by Elliot Poger.  The code has been extensively hacked on
+ * by Ted Lemon since then, so any mistakes you find are probably his
+ * fault and not Elliot's.
+ */
+/*
+ * WIDE Project DHCP Implementation
+ * Copyright (c) 1995-1997 Akihiro Tominaga
+ * Copyright (c) 1995-1997 WIDE Project
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided the following conditions
+ * are satisfied,
+ *
+ * 1. Both the copyright notice and this permission notice appear in
+ *    all copies of the software, derivative works or modified versions,
+ *    and any portions thereof, and that both notices appear in
+ *    supporting documentation.
+ * 2. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by WIDE Project and
+ *      its contributors.
+ * 3. Neither the name of WIDE Project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND WIDE
+ * PROJECT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ALSO, THERE
+ * IS NO WARRANTY IMPLIED OR OTHERWISE, NOR IS SUPPORT PROVIDED.
+ *
+ * Feedback of the results generated from any improvements or
+ * extensions made to this software would be much appreciated.
+ * Any such feedback should be sent to:
+ * 
+ *  Akihiro Tominaga
+ *  WIDE Project
+ *  Keio University, Endo 5322, Kanagawa, Japan
+ *  (E-mail: dhcp-dist@wide.ad.jp)
+ *
+ * WIDE project has the rights to redistribute these changes.
+ */
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2011 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+ *      ã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+ *        å ±åãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef DHCP6_CLI_H
+#define DHCP6_CLI_H
+
+#ifdef DHCP6_CLI_CFG
+
+#include <netinet/in.h>
+#include <netapp/dhcp6.h>
+
+/* 
+ *  DHCP ã¯ã©ã¤ã¢ã³ãã®ã¹ã¿ãã¯ãµã¤ãº
+ */
+
+#define DHCP6_CLI_STACK_SIZE		1024		/* DHCP ã¯ã©ã¤ã¢ã³ãã¿ã¹ã¯ã®ã¹ã¿ãã¯ãµã¤ãº	*/
+
+/* 
+ *  DHCP ã¯ã©ã¤ã¢ã³ãã®åªå
+åº¦
+ */
+
+#define DHCP6_CLI_MAIN_PRIORITY		5		/* DHCP ã¯ã©ã¤ã¢ã³ãã¿ã¹ã¯ã®åªå
+åº¦		*/
+
+/* 
+ *  ã³ã³ãã¤ã«æã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³
+ */
+
+/*
+ *  DHCPv6 åä½ã¢ã¼ã
+ *
+ *    #define DHCP6_CLI_CFG_MODE ã§æå®ããã
+ *    æå®ããã¦ããªããã°ãã¹ãã¼ãã¬ã¹ã«è¨­å®ããã
+ *
+ */
+
+#define DHCP6_CLI_CFG_STATELESS		0	/* ã¹ãã¼ãã¬ã¹ã«è¨­å®ããã		*/
+#define DHCP6_CLI_CFG_STATEFULL		1	/* ã¹ãã¼ããã«ã«è¨­å®ããã		*/
+#define DHCP6_CLI_CFG_RA		2	/* RA ã® M/O ãããã«ããè¨­å®ããã	*/
+#define DHCP6_CLI_CFG_MODE_DEFAULT	DHCP6_CLI_CFG_STATELESS
+
+/* IA ã®è¨­å® */
+#define DHCP6_CLI_CFG_IA_NA		1
+//#define DHCP6_CLI_CFG_IA_TA		1
+//#define DHCP6_CLI_CFG_IA_PD		1
+
+/* Rapid-commit ã®æå® */
+//#define DHCP6_CLI_CFG_RAPID_COMMIT	1
+
+/* æ¨å¥¨åº¦ã®å®ç¾© */
+#define DHCP6_CLI_CFG_PREFER_IA		50	/* IA_NA/TA/PD å½ããã®æ¨å¥¨åº¦	*/
+#define DHCP6_CLI_CFG_PREFER_IAADDR	100	/* ã¢ãã¬ã¹å½ããã®æ¨å¥¨åº¦	*/
+
+/* DHCPv6 ã¯ã©ã¤ã¢ã³ãã¡ãã»ã¼ã¸ã®åä¿¡ãªã¹ããµã¤ãºï¼2ä»¥ä¸æå®ãããã¨ï¼ */
+#define NUM_DHCP6_CLI_MSG_LIST		3
+
+/*
+ *  DHCPv6 ã¯ã©ã¤ã¢ã³ãã¡ãã»ã¼ã¸æ§é ä½æ°ãå¤æ´ç¦æ­¢ã
+ *  +1 ã¯éä¿¡ç¨
+ */
+#define NUM_MPF_DHCP6_CLI_MSG		(NUM_DHCP6_CLI_MSG_LIST+1)
+
+/* DHCP å¿
+é ãªãã·ã§ã³ãªã¹ã */
+
+#ifndef DHCP6_CLI_CFG_REQUIRED_OLIST
+
+#if defined(USE_RESOLVER)
+
+#define DHCP6_CLI_CFG_REQUIRED_OLIST {	\
+	DHCP6_OPT_NAME_SERVERS,		\
+	}
+
+#else	/* of #if defined(USE_RESOLVER) */
+
+#endif	/* of #if defined(USE_RESOLVER) */
+
+#endif	/* of #ifndef DHCP6_CLI_CFG_REQUIRED_OLIST */
+
+/* DHCP è¦æ±ãªãã·ã§ã³ãªã¹ã */
+
+#ifndef DHCP6_CLI_CFG_REQUEST_OLIST
+
+#if defined(USE_RESOLVER)
+
+#define DHCP6_CLI_CFG_REQUEST_OLIST {	\
+	DHCP6_OPT_DOMAIN_SEARCH,	\
+	}
+
+#else	/* of #if defined(USE_RESOLVER) */
+
+#endif	/* of #if defined(USE_RESOLVER) */
+
+#endif	/* of #ifndef DHCP6_CLI_CFG_REQUEST_OLIST */
+
+/*
+ *  ã¿ã¤ã ã¢ã¦ãå®æ°
+ *  RFC3315 ã«è¦å®ãããã¿ã¤ãã³ã°å®æ°ã¯ dhcp6.h åç
+§
+ */
+
+/* æ¨æºã¡ãã»ã¼ã¸ã®åéä¿¡ã¿ã¤ã ã¢ã¦ã	*/
+#define TMO_DHCP6C_NORMAL	ULONG_C(60*1000)
+
+/* æ¨æºè¦æ±ãªã¼ã¹æé			*/
+#define TMO_DHCP6C_REQ_LEASE	ULONG_C(7200*1000)
+
+/* ã¡ãã»ã¼ã¸æ§é ä½ç²å¾ã¿ã¤ã ã¢ã¦ã	*/
+#define TMO_DHCP6C_MPF_GET	ULONG_C(1000)
+
+/* ã¡ãã»ã¼ã¸åä¿¡ã¿ã¤ã ã¢ã¦ã	*/
+#define TMO_DHCP6C_RCV_DAT	ULONG_C(1000)
+
+/*
+ *  DHCPv6 ã¯ã©ã¤ã¢ã³ãã¡ãã»ã¼ã¸æ§é ä½
+ */
+
+typedef struct dhcp6_cli_msg {
+	/* 4ãã¤ãå¢çã«ã¢ã©ã¤ã³ããã*/
+	T_DHCP6_MSG		msg;		/* DHCPv6 ã¡ãã»ã¼ã¸æ§é ä½	*/
+	struct dhcp6_cli_msg	*next;		/* ãªã¹ãã®æ¬¡ã®ã¡ãã»ã¼ã¸æ§é ä½	*/
+	SYSTIM			rcv_time;	/* åä¿¡ããæé			*/
+	T_IPV6EP		srv;		/* ãµã¼ãã®IPv6ã¢ãã¬ã¹/ãã¼ãçªå· */
+	uint16_t		len;		/* msg ã®æå¹é·			*/
+	uint16_t		prefer;		/* msg ã®æ¨å¥¨åº¦			*/
+	uint16_t		status;		/* STATUS CODE ãªãã·ã§ã³ã® status */
+	} T_DHCP6_CLI_MSG;
+
+/* prefer ã®ãã©ã° */
+
+#define DHCP6_ClI_MSG_PREFER_ADDR	UINT_C(0x8000)	/* ã¢ãã¬ã¹æ
+å ±ãã		*/
+#define DHCP6_ClI_MSG_PREFER_REQUIRED	UINT_C(0x4000)	/* å¿
+é ãªãã·ã§ã³ãã		*/
+#define DHCP6_ClI_MSG_PREFER_REQUEST	UINT_C(0x2000)	/* è¦æ±ãªãã·ã§ã³ãã		*/
+#define DHCP6_ClI_MSG_PREFER_OPTION	UINT_C(0x1000)	/* PREFER ãªãã·ã§ã³ãã	*/
+#define DHCP6_ClI_MSG_PREFER_FLAG_MASK	UINT_C(0xf000)
+#define DHCP6_ClI_MSG_PREFER_VALUE_MASK	(~(DHCP6_ClI_MSG_PREFER_FLAG_MASK))
+
+/*
+ *  STATUS CODE ãªãã·ã§ã³ãç¡ãæã®å¤
+ */
+
+#define DHCP6_CLI_STAT_UNDEFINED	(-1)
+
+/*
+ *  ã³ã¼ã«ããã¯é¢æ°
+ */
+
+extern ER callback_nblk_dhcp6_cli (ID cepid, FN fncd, void *p_parblk);
+
+/*
+ *  ã¿ã¹ã¯
+ */
+
+extern void	dhcp6_cli_task(intptr_t exinf);
+
+/*
+ *  é¢æ°
+ */
+
+extern ER dhcp6c_rel_info (void);
+extern ER dhcp6c_renew_info (void);
+extern ER dhcp6c_get_info (T_IN6_ADDR *addr, uint32_t *expire, uint32_t *renew,
+                                             uint32_t *rebind, uint32_t *deprefer, SYSTIM *bind_start);
+
+#endif	/* of #ifdef DHCP6_CLI_CFG */
+
+#endif	/* of #ifndef DHCP6_CLI_H */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6_cli_asp.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6_cli_asp.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6_cli_asp.cfg	(revision 331)
@@ -0,0 +1,73 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ASP ç¨ DHCP ã¯ã©ã¤ã¢ã³ãã®ã·ã¹ãã ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ */
+
+/*
+ *  å
+±é DHCP ã¯ã©ã¤ã¢ã³ãã®ã·ã¹ãã ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«ã®ã¤ã³ã¯ã«ã¼ã
+ */
+
+#ifdef DHCP6_CLI_CFG
+
+INCLUDE("netapp/dhcp6_cli.cfg");
+
+/*
+ * åºå®ã¡ã¢ãªãã¼ã«
+ */
+
+/* éåä¿¡ãããã¡ */
+
+CRE_MPF(MPF_DHCP6_CLI_MSG, {
+	TA_TFIFO,
+	NUM_MPF_DHCP6_CLI_MSG,
+	sizeof(T_DHCP6_CLI_MSG),
+	NULL,
+	NULL
+	});
+
+#endif	/* of #ifdef DHCP6_CLI_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6_cli_jsp.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6_cli_jsp.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6_cli_jsp.cfg	(revision 331)
@@ -0,0 +1,72 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  JSP ç¨ DHCP ã¯ã©ã¤ã¢ã³ãã®ã·ã¹ãã ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ */
+
+/*
+ *  å
+±é DHCP ã¯ã©ã¤ã¢ã³ãã®ã·ã¹ãã ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«ã®ã¤ã³ã¯ã«ã¼ã
+ */
+
+#ifdef DHCP6_CLI_CFG
+
+#include "netapp/dhcp6_cli.cfg"
+
+/*
+ * åºå®ã¡ã¢ãªãã¼ã«
+ */
+
+/* éåä¿¡ãããã¡ */
+
+CRE_MPF(MPF_DHCP6_CLI_MSG, {
+	TA_TFIFO,
+	NUM_MPF_DHCP6_CLI_MSG,
+	sizeof(T_DHCP6_CLI_MSG),
+	NULL
+	});
+
+#endif	/* of #ifdef DHCP6_CLI_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6_cli_var.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6_cli_var.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dhcp6_cli_var.h	(revision 331)
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1995-2003 by Internet Software Consortium
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ *   Internet Systems Consortium, Inc.
+ *   950 Charter Street
+ *   Redwood City, CA 94063
+ *   <info@isc.org>
+ *   https://www.isc.org/
+ *
+ * This code is based on the original client state machine that was
+ * written by Elliot Poger.  The code has been extensively hacked on
+ * by Ted Lemon since then, so any mistakes you find are probably his
+ * fault and not Elliot's.
+ */
+/*
+ * WIDE Project DHCP Implementation
+ * Copyright (c) 1995-1997 Akihiro Tominaga
+ * Copyright (c) 1995-1997 WIDE Project
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided the following conditions
+ * are satisfied,
+ *
+ * 1. Both the copyright notice and this permission notice appear in
+ *    all copies of the software, derivative works or modified versions,
+ *    and any portions thereof, and that both notices appear in
+ *    supporting documentation.
+ * 2. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by WIDE Project and
+ *      its contributors.
+ * 3. Neither the name of WIDE Project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND WIDE
+ * PROJECT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ALSO, THERE
+ * IS NO WARRANTY IMPLIED OR OTHERWISE, NOR IS SUPPORT PROVIDED.
+ *
+ * Feedback of the results generated from any improvements or
+ * extensions made to this software would be much appreciated.
+ * Any such feedback should be sent to:
+ * 
+ *  Akihiro Tominaga
+ *  WIDE Project
+ *  Keio University, Endo 5322, Kanagawa, Japan
+ *  (E-mail: dhcp-dist@wide.ad.jp)
+ *
+ * WIDE project has the rights to redistribute these changes.
+ */
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2011 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+ *      ã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+ *        å ±åãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef DHCP6_CLI_VAR_H
+#define DHCP6_CLI_VAR_H
+
+#ifdef DHCP6_CLI_CFG
+
+/*
+ *  DHCP ã¯ã©ã¤ã¢ã³ãã³ã³ãã­ã¹ãæ§é ä½
+ */
+
+/* TIMER ã®å®ç¾© */
+
+#define DHCP6C_TIMER_SND_SOL	0
+#define DHCP6C_TIMER_SND_REQ	1
+#define DHCP6C_TIMER_SND_REL	2
+#define DHCP6C_TIMER_RCV_ADV	3
+#define DHCP6C_TIMER_RCV_REPLY	4
+#define DHCP6C_TIMER_RENEW	5
+#define DHCP6C_TIMER_REBIND	6
+#define DHCP6C_TIMER_EXPIRE	7
+#define DHCP6C_TIMER_DEPREF	8
+#define DHCP6C_TIMER_SND_REF	9
+#define DHCP6C_TIMER_SND_IREQ	10
+#define NUM_DHCP6C_TIMERS	11
+
+#define DHCP6C_TIMER_HZ		1
+
+/* å®æ°ã®å®ç¾© */
+
+#define MAX_DUID_LEN		(ETHER_ADDR_LEN+8)
+
+typedef struct dhcp6_cli_context {
+	T_DHCP6_CLI_MSG		*rcv_lst;	/* åä¿¡ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ã		*/
+	T_DHCP6_CLI_MSG		*val_lst;	/* æ¤è¨¼ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ã		*/
+	T_DHCP6_CLI_MSG		*prf_lst;	/* æ¨å¥¨ã¡ãã»ã¼ã¸æ§é ä½ãªã¹ã		*/
+	T_DHCP6_CLI_MSG		*snd_msg;	/* éä¿¡ã¡ãã»ã¼ã¸æ§é ä½			*/
+	T_DHCP6_CLI_MSG		*adv_msg;	/* éç¥ããããªã¼ã¹ã»ã¡ãã»ã¼ã¸æ§é ä½	*/
+	T_DHCP6_CLI_MSG		*act_msg;	/* æå¹ãªãªã¼ã¹ã»ã¡ãã»ã¼ã¸æ§é ä½	*/
+	T_IF_SOFTC		*sc;		/* IF ã®ã½ããã¦ã§ã¢æ
+å ±		*/
+	T_IPV6EP		dst;		/* éä¿¡å
+ã®IPã¢ãã¬ã¹/ãã¼ãçªå·	*/
+	SYSTIM			RT;		/* åéä¿¡éé				*/
+	SYSTIM			IRT;		/* åæåéä¿¡éé			*/
+	SYSTIM			MRT;		/* æå¤§åéä¿¡éé			*/
+	SYSTIM			MRD;		/* æå¤§åéä¿¡ç¶ç¶æé			*/
+	SYSTIM			next_MRD;	/* æ¬¡ã®æå¤§åéä¿¡ç¶ç¶æé		*/
+	SYSTIM			timers[NUM_DHCP6C_TIMERS];	
+						/* ã¿ã¤ãã¼é
+å			*/
+	ER_UINT			error;		/* ã¨ã©ã¼ã»ãã¼ã¿é·		*/
+	ID			cepid;		/* CEP ID			*/
+	uint32_t		xid;		/* ãã©ã³ã¶ã¯ã·ã§ã³ ID		*/
+	uint16_t		flags;		/* åç¨®ãã©ã°			*/
+	uint16_t		max_prefer;	/* åä¿¡ã¡ãã»ã¼ã¸ã®æå¤§æ¨å¥¨åº¦	*/
+	uint8_t			duid[MAX_DUID_LEN];	
+						/* client DHCP Unique ID	*/
+	uint8_t			duid_len;	/* client DUID é·		*/
+	uint8_t			fsm;		/* ç¾å¨ã®ç¶æ
+			*/
+	uint8_t			MRC;		/* æå¤§åéä¿¡åæ°		*/
+	uint8_t			txcount;	/* åéä¿¡åæ°			*/
+	uint8_t			refresh_type;	/* REFRESH ã®ã¡ãã»ã¼ã¸ã¿ã¤ã	*/
+	} T_DHCP6_CLI_CONTEXT;
+
+/* fsmï¼ç¶æ
+é·ç§»ï¼ã®å®ç¾© */
+
+#define DHCP6_FSM_INIT		1
+#define DHCP6_FSM_SELECT	2
+#define DHCP6_FSM_BOUND		4
+#define DHCP6_FSM_RENEW		5
+#define DHCP6_FSM_REBIND	6
+#define DHCP6_FSM_REQ_INFO	9	/* DHCPv6 ã® RFC3315 ã«ã¯ç¡ãã*/
+#define DHCP6_FSM_INFORMED	10	/* DHCPv6 ã® RFC3315 ã«ã¯ç¡ãã*/
+#define DHCP6_FSM_REL_INFO	11	/* DHCPv6 ã® RFC3315 ã«ã¯ç¡ãã*/
+#define DHCP6_FSM_SLEEP		12	/* DHCPv6 ã® RFC3315 ã«ã¯ç¡ãã*/
+
+/* flag ã®å®ç¾© */
+
+#define DHCP6C_FLAG_TMOUT_SND_SOL	(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_SND_SOL)
+#define DHCP6C_FLAG_TMOUT_SND_REQ	(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_SND_REQ)
+#define DHCP6C_FLAG_TMOUT_SND_REL	(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_SND_REL)
+#define DHCP6C_FLAG_TMOUT_RCV_ADV	(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_RCV_ADV)
+#define DHCP6C_FLAG_TMOUT_RCV_REPLY	(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_RCV_REPLY)
+#define DHCP6C_FLAG_TMOUT_RENEW		(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_RENEW)
+#define DHCP6C_FLAG_TMOUT_REBIND	(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_REBIND)
+#define DHCP6C_FLAG_TMOUT_EXPIRE	(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_EXPIRE)
+#define DHCP6C_FLAG_TMOUT_DEPREF	(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_DEPREF)
+#define DHCP6C_FLAG_TMOUT_SND_REF	(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_SND_REF)
+#define DHCP6C_FLAG_TMOUT_SND_IREQ	(DHCP6C_FLAG_TMOUT_TIMER|DHCP6C_TIMER_SND_IREQ)
+#define DHCP6C_FLAG_TMOUT_TIMER		UINT_C(0x0010)
+#define DHCP6C_FLAG_TMOUT_TIMER_MASK	UINT_C(0x000f)
+#define DHCP6C_FLAG_TMOUT_MASK		UINT_C(0x001f)
+
+#define DHCP6C_FLAG_RCV_MSG		UINT_C(0x0200)
+#define DHCP6C_FLAG_RENEW		UINT_C(0x0400)
+
+/* IAADDR æ§é ä½ã® FLAG ã®å®ç¾©ï¼len ã«å¤éåããï¼*/
+
+#define DHCP6C_IAA_FLAG_EXPIRED		UINT_C(0x8000)
+#define DHCP6C_IAA_FLAG_DEPREFERD	UINT_C(0x4000)
+#define DHCP6C_IAA_FLAG_MASK		UINT_C(0xc000)
+
+/*
+ *  é¢æ°ã·ãã¥ã¬ã¼ã·ã§ã³ãã¯ã­
+ */
+
+/* æéæ¯è¼ */
+
+#define TIMEC_GT(a,b)		((int32_t)((a)-(b))>0)
+#define TIMEC_GE(a,b)		((int32_t)((a)-(b))>=0)
+
+/* æéå®æ°ã®å¤æ */
+
+#define SYSTIM2TIMER(t)		(((t)<SYSTIM_HZ/DHCP6C_TIMER_HZ)?(DHCP6C_TIMER_HZ):((t)*DHCP6C_TIMER_HZ)/SYSTIM_HZ)
+#define SYSTIM2SEC(t)		(((t)<SYSTIM_HZ)?1:((t)/SYSTIM_HZ))
+#define SEC2TIMER(t)		((t)*DHCP6C_TIMER_HZ)
+#define SEC2SYSTIM(t)		((t)*SYSTIM_HZ)
+
+#endif	/* of #ifdef DHCP6_CLI_CFG */
+
+#endif	/* of #ifndef DHCP6_CLI_VAR_H */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/discard.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/discard.h	(revision 321)
+++ 	(revision )
@@ -1,110 +1,0 @@
-/*
- *  TINET (TCP/IP Protocol Stack)
- * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
- *                   Tomakomai National College of Technology, JAPAN
- *
- *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
- *  によって公表されている GNU General Public License の Version 2 に記
- *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
- *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
- *  利用と呼ぶ）することを無償で許諾する．
- *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
- *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
- *      スコード中に含まれていること．
- *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
- *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
- *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
- *      の無保証規定を掲載すること．
- *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
- *      用できない形で再配布する場合には，次の条件を満たすこと．
- *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
- *        作権表示，この利用条件および下記の無保証規定を掲載すること．
- *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
- *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
- *
- *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
- *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
- *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
- *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
- * 
- *  @(#) $Id$
- */
-
-#ifndef _DISCARD_H_
-#define _DISCARD_H_
-
-/* 
- *  DISCARD サーバ・クライアントのスタックサイズ
- */
-
-#define TCP_DISCARD_SRV_STACK_SIZE	1024		/* TCP DISCARD サーバタスクのスタックサイズ */
-#define TCP_DISCARD_CLI_STACK_SIZE	1024		/* TCP DISCARD クライアントタスクのスタックサイズ */
-#define UDP_DISCARD_CLI_STACK_SIZE	1024		/* UDP DISCARD クライアントタスクのスタックサイズ */
-
-/* 
- *  DISCARD サーバ・クライアントの優先度
- */
-
-#define TCP_DISCARD_SRV_MAIN_PRIORITY	5	/* TCP DISCARD サーバタスクの優先度 */
-#define TCP_DISCARD_CLI_MAIN_PRIORITY	5	/* TCP DISCARD クライアントタスクの優先度 */
-#define UDP_DISCARD_CLI_MAIN_PRIORITY	5	/* UDP DISCARD クライアントタスクの優先度 */
-
-/*
- *  TCP 送受信ウインドバッファサイズ
- */
-
-#if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0
-
-#define TCP_DISCARD_CLI_SWBUF_SIZE	((IF_MTU-(IP_HDR_SIZE+TCP_HDR_SIZE))*1)
-#define TCP_DISCARD_SRV_RWBUF_SIZE	((IF_MTU-(IP_HDR_SIZE+TCP_HDR_SIZE))*1)
-
-#else	/* of #if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0 */
-
-#if defined(SUPPORT_INET4)
-
-#define TCP_DISCARD_CLI_SWBUF_SIZE	(TCP_MSS)
-#define TCP_DISCARD_SRV_RWBUF_SIZE	(TCP_MSS)
-
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
-
-#define TCP_DISCARD_CLI_SWBUF_SIZE	(TCP6_MSS)
-#define TCP_DISCARD_SRV_RWBUF_SIZE	(TCP6_MSS)
-
-#endif	/* of #if defined(SUPPORT_INET6) */
-
-#endif	/* of #if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0 */
-
-/*
- *  変数
- */
-
-extern bool_t	tcp_discard_cli_valid;
-extern bool_t	udp_discard_cli_valid;
-
-/* TCP 送受信バッファ */
-
-extern uint8_t tcp_discard_cli_swbuf[];
-extern uint8_t tcp_discard_cli_rwbuf[];
-
-extern uint8_t tcp_discard_srv_swbuf[];
-extern uint8_t tcp_discard_srv_rwbuf[];
-
-/*
- *  タスク
- */
-
-extern void tcp_discard_srv_task(intptr_t exinf);
-extern void tcp_discard_cli_task(intptr_t exinf);
-
-extern void udp_discard_cli_task(intptr_t exinf);
-
-/*
- *  関数
- */
-
-extern ER callback_nblk_tcp_discard_cli (ID cepid, FN fncd, void *p_parblk);
-
-#endif	/* of #ifndef _DISCARD_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dns.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dns.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/dns.h	(revision 331)
@@ -0,0 +1,294 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+ *      ã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+ *        å ±åãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef DNS_H
+#define DNS_H
+
+/*
+ *  DNS ã¡ãã»ã¼ã¸ã«é¢ããå®ç¾©
+ *
+ *    RFC1034ãRFC1035ãRFC1886ãRFC2136ã
+ *    RFC2671ãRFC2845ãRFC2930ãRFC3596
+ *
+ *  DNS ã¡ãã»ã¼ã¸
+ *
+ *  +---------------------+
+ *  |       Header        |
+ *  +---------------------+
+ *  |      Question       | Question section å½¢å¼
+ *  +---------------------+
+ *  |       Answer        | RR (Resouce Record) å½¢å¼
+ *  +---------------------+
+ *  |     Authority       | RR (Resouce Record) å½¢å¼
+ *  +---------------------+
+ *  |     Additional      | RR (Resouce Record) å½¢å¼
+ *  +---------------------+
+ *
+ *  DNS ããã
+ *
+ *    0                    7  8                   15
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                      ID                       |
+ *  +--+-----------+--+--+--+--+--------+-----------+
+ *  |QR|   Opcode  |AA|TC|RD|RA|    Z   |   RCODE   |
+ *  +--+--------+--+--+--+--+--+--------+-----------+
+ *  |                    QDCOUNT                    |
+ *  +-----------------------------------------------+
+ *  |                    ANCOUNT                    |
+ *  +-----------------------------------------------+
+ *  |                    NSCOUNT                    |
+ *  +-----------------------------------------------+
+ *  |                    ARCOUNT                    |
+ *  +-----------------------------------------------+
+ */
+
+typedef struct dns_hdr {
+	uint16_t	id;		/* ID */
+	uint16_t	code;	/* QR:		1
+				   Opcode:	4
+				   AA:		1
+				   TC:		1
+				   RD:		1
+				   RA:		1
+				   Z:		3
+				   RCODE:	4
+				   */
+	uint16_t	qdcount;	/* question   section */
+	uint16_t	ancount;	/* answer     section */
+	uint16_t	nscount;	/* authority  section */
+	uint16_t	arcount;	/* additional section */
+	} T_DNS_HDR;
+
+/*
+ *  code ã®å®ç¾©
+ */
+
+/* QR ã®å®ç¾© */
+
+#define DNS_QR_QUERY		0x0000U
+#define DNS_QR_RESPONSE		0x8000U
+
+/* Opcode ã®å®ç¾© */
+
+#define DNS_OPCODE_MASK		0x7800U
+#define DNS_OPCODE_FORWARD	0x0000U
+#define DNS_OPCODE_REVERSE	0x0800U
+#define DNS_OPCODE_STATUS	0x1000U
+
+/* AA ã®å®ç¾© */
+
+#define DNS_AUTHORITATIVE	0x0400U
+
+/* TC ã®å®ç¾© */
+
+#define DNS_TRUN_CATION		0x0200U
+
+/* RD ã®å®ç¾© */
+
+#define DNS_RECURSION_DESIRED	0x0100U
+
+/* RA ã®å®ç¾© */
+
+#define DNS_RECURSION_AVAILABLE	0x0080U
+
+/* RCODE ã®å®ç¾© */
+
+#define DNS_RCODE_MASK		0x000fU
+#define DNS_RCODE_NO_ERROR	0x0000U
+#define DNS_RCODE_FORMAT_ERROR	0x0001U
+#define DNS_RCODE_SERVER_ERROR	0x0002U
+#define DNS_RCODE_NAME_ERROR	0x0003U
+#define DNS_RCODE_NOT_IMPLEMENT	0x0004U
+#define DNS_RCODE_REFUSED	0x0005U
+
+/*
+ * DNS TYPE ã®å®ç¾©
+ */
+
+#define DNS_TYPE_A		(uint16_t)1U
+#define DNS_TYPE_NS		(uint16_t)2U
+#define DNS_TYPE_CNAME		(uint16_t)5U
+#define DNS_TYPE_SOA		(uint16_t)6U
+#define DNS_TYPE_PTR		(uint16_t)12U
+#define DNS_TYPE_AAAA		(uint16_t)28U
+
+/*
+ * DNS CLASS ã®å®ç¾©
+ */
+
+#define DNS_CLASS_IN		(uint16_t)1U
+
+/*
+ *  RR (Resouce Record) å½¢å¼
+ *
+ *    0                    7  8                   15
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                       .                       |
+ *  +-----------------      .      -----------------+
+ *  |                      NAME                     |
+ *  +-----------------      .      -----------------+
+ *  |                       .                       |
+ *  +-----------------------------------------------+
+ *  |                      TYPE                     |
+ *  +-----------------------------------------------+
+ *  |                      CLASS                    |
+ *  +-----------------------------------------------+
+ *  |                       TTL                     |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *  |                    RDLENGTH                   |
+ *  +-----------------------------------------------+
+ *  |                       .                       |
+ *  +-----------------      .      -----------------+
+ *  |                     RDATA                     |
+ *  +-----------------      .      -----------------+
+ *  |                       .                       |
+ *  +-----------------------------------------------+
+ *
+ *    æ³¨æ: offset ã®åç¹ã¯ DNS message ã®å
+é ­
+ */
+
+typedef struct dns_rr {
+					/* NAME			*/
+	uint16_t	type;		/* TYPE			*/
+	uint16_t	class;		/* CLASS		*/
+	uint32_t	ttl;		/* TTL			*/
+	uint16_t	rdlength;	/* RDATA length		*/
+					/* RDATA		*/
+	} T_DNS_RR;
+
+#define T_DNS_RR_SIZE	(sizeof(uint16_t)*3+sizeof(uint32_t))
+
+/*
+ *  Question section å½¢å¼
+ *
+ *    0                    7  8                   15
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                       .                       |
+ *  +-----------------      .      -----------------+
+ *  |                     QNAME                     |
+ *  +-----------------      .      -----------------+
+ *  |                       .                       |
+ *  +-----------------------------------------------+
+ *  |                     QTYPE                     |
+ *  +-----------------------------------------------+
+ *  |                     QCLASS                    |
+ *  +-----------------------------------------------+
+ */
+
+typedef struct dns_qd {
+					/* QNAME		*/
+	uint16_t	type;		/* TYPE			*/
+	uint16_t	class;		/* CLASS		*/
+	} T_DNS_QD;
+
+#define T_DNS_QD_SIZE	(sizeof(uint16_t)*2)
+
+/*
+ *  SOA RDATA å½¢å¼
+ *
+ *    0                    7  8                   15
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                       .                       |
+ *  +-----------------      .      -----------------+
+ *  |                     MNAME                     |
+ *  +-----------------      .      -----------------+
+ *  |                       .                       |
+ *  +-----------------------------------------------+
+ *  |                       .                       |
+ *  +-----------------      .      -----------------+
+ *  |                     RNAME                     |
+ *  +-----------------      .      -----------------+
+ *  |                       .                       |
+ *  +-----------------------------------------------+
+ *  |                    SERIAL                     |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *  |                    REFRESH                    |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *  |                     RETRY                     |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *  |                    EXPIRE                     |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *  |                    MINIMUM                    |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *
+ *    æ³¨æ: offset ã®åç¹ã¯ DNS message ã®å
+é ­
+ */
+
+typedef struct dns_soa {
+					/* MNAME		*/
+					/* RNAME		*/
+	uint32_t	serial;		/* SERIAL		*/
+	uint32_t	refresh;	/* REFRESH		*/
+	uint32_t	retry;		/* RETRY		*/
+	uint32_t	expire;		/* EXPIRE		*/
+	uint32_t	minimum;	/* MINIMUM		*/
+	} T_DNS_SOA;
+
+#define T_DNS_SOA_SIZE	(sizeof(uint32_t)*5)
+
+/*
+ *  DNS ã®å®æ°ã®å®ç¾©
+ */
+
+#define DNS_LABEL_LENGTH	63
+#define DNS_NAME_LENGTH		255
+#define DNS_UDP_MSG_LENGTH	512
+
+#define DNS_MSG_COMP_MARK	0xc0
+
+#endif	/* of #ifndef DNS_H */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/echo.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/echo.h	(revision 321)
+++ 	(revision )
@@ -1,157 +1,0 @@
-/*
- *  TINET (TCP/IP Protocol Stack)
- * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
- *                   Tomakomai National College of Technology, JAPAN
- *
- *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
- *  によって公表されている GNU General Public License の Version 2 に記
- *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
- *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
- *  利用と呼ぶ）することを無償で許諾する．
- *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
- *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
- *      スコード中に含まれていること．
- *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
- *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
- *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
- *      の無保証規定を掲載すること．
- *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
- *      用できない形で再配布する場合には，次の条件を満たすこと．
- *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
- *        作権表示，この利用条件および下記の無保証規定を掲載すること．
- *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
- *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
- *
- *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
- *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
- *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
- *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
- * 
- *  @(#) $Id$
- */
-
-#ifndef _ECHO_H_
-#define _ECHO_H_
-
-/* 
- *  ECHO クライアント・サーバのスタックサイズ
- */
-
-#define TCP_ECHO_SRV_STACK_SIZE		1024		/* TCP ECHO サーバタスクのスタックサイズ		*/
-
-#ifdef TOPPERS_S810_CLG3_85
-#define TCP_ECHO_CLI_RCV_STACK_SIZE	512		/* TCP ECHO クライアント受信タスクのスタックサイズ	*/
-#define TCP_ECHO_CLI_SND_STACK_SIZE	512		/* TCP ECHO クライアント送信タスクのスタックサイズ	*/
-#else	/* of #ifdef TOPPERS_S810_CLG3_85 */
-#define TCP_ECHO_CLI_RCV_STACK_SIZE	1024		/* TCP ECHO クライアント受信タスクのスタックサイズ	*/
-#define TCP_ECHO_CLI_SND_STACK_SIZE	1024		/* TCP ECHO クライアント送信タスクのスタックサイズ	*/
-#endif	/* of #ifdef TOPPERS_S810_CLG3_85 */
-
-#define UDP_ECHO_SRV_STACK_SIZE		1024		/* UDP ECHO サーバタスクのスタックサイズ		*/
-#define UDP_ECHO_CLI_STACK_SIZE		1024		/* UDP ECHO クライアントタスクのスタックサイズ	*/
-
-/* 
- *  ECHO クライアント・サーバの優先度
- */
-
-#define TCP_ECHO_SRV_MAIN_PRIORITY	5		/* TCP ECHO サーバタスクの優先度			*/
-#define TCP_ECHO_CLI_RCV_MAIN_PRIORITY	5		/* TCP ECHO クライアント受信タスクの優先度		*/
-#define TCP_ECHO_CLI_SND_MAIN_PRIORITY	5		/* TCP ECHO クライアント送信タスクの優先度		*/
-
-#define UDP_ECHO_SRV_MAIN_PRIORITY	5		/* UDP ECHO サーバタスクの優先度			*/
-#define UDP_ECHO_CLI_MAIN_PRIORITY	5		/* UDP ECHO クライアントタスクの優先度		*/
-
-/*
- *  TCP 送受信ウインドバッファサイズ
- */
-
-#if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0
-
-#define TCP_ECHO_CLI_SWBUF_SIZE		((IF_MTU-(IP_HDR_SIZE+TCP_HDR_SIZE))*1)
-#define TCP_ECHO_CLI_RWBUF_SIZE		((IF_MTU-(IP_HDR_SIZE+TCP_HDR_SIZE))*1)
-
-#define TCP_ECHO_SRV_SWBUF_SIZE		((IF_MTU-(IP_HDR_SIZE+TCP_HDR_SIZE))*2)
-#define TCP_ECHO_SRV_RWBUF_SIZE		((IF_MTU-(IP_HDR_SIZE+TCP_HDR_SIZE))*2)
-
-#else	/* of #if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0 */
-
-#if defined(SUPPORT_INET4)
-
-#define TCP_ECHO_CLI_SWBUF_SIZE		(TCP_MSS)
-#define TCP_ECHO_CLI_RWBUF_SIZE		(TCP_MSS)
-
-#define TCP_ECHO_SRV_SWBUF_SIZE		(TCP_MSS)
-#define TCP_ECHO_SRV_RWBUF_SIZE		(TCP_MSS)
-
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
-
-#define TCP_ECHO_CLI_SWBUF_SIZE		(TCP6_MSS)
-#define TCP_ECHO_CLI_RWBUF_SIZE		(TCP6_MSS)
-
-#define TCP_ECHO_SRV_SWBUF_SIZE		(TCP6_MSS)
-#define TCP_ECHO_SRV_RWBUF_SIZE		(TCP6_MSS)
-
-#endif	/* of #if defined(SUPPORT_INET6) */
-
-#endif	/* of #if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0 */
-
-/*
- *  タスク数
- */
-
-#if !(defined(USE_TCP_ECHO_SRV1) && !defined(USE_TCP_NON_BLOCKING) && defined(USE_COPYSAVE_API))
-
-#undef  NUM_TCP_ECHO_SRV_TASKS
-#define NUM_TCP_ECHO_SRV_TASKS		1
-
-#endif	/* of #if !(defined(USE_TCP_ECHO_SRV1) && !defined(USE_TCP_NON_BLOCKING) && defined(USE_COPYSAVE_API)) */
-
-/*
- *  変数
- */
-
-extern bool_t	tcp_echo_cli_valid;
-extern bool_t	udp_echo_cli_valid;
-
-/* TCP 送受信バッファ */
-
-extern uint8_t tcp_echo_cli_swbuf[];
-extern uint8_t tcp_echo_cli_rwbuf[];
-
-#ifdef _TCP_H_
-
-extern uint8_t tcp_echo_srv_swbuf[NUM_TCP_ECHO_SRV_TASKS][TCP_ECHO_SRV_SWBUF_SIZE];
-extern uint8_t tcp_echo_srv_rwbuf[NUM_TCP_ECHO_SRV_TASKS][TCP_ECHO_SRV_RWBUF_SIZE];
-
-#endif	/* of #ifdef _TCP_H_ */
-
-/*
- *  タスク
- */
-
-extern void	tcp_echo_srv_task(intptr_t exinf);
-extern void	tcp_echo_srv_rcv_task(intptr_t exinf);
-extern void	tcp_echo_srv_snd_task(intptr_t exinf);
-extern void	tcp_echo_cli_rcv_task(intptr_t exinf);
-extern void	tcp_echo_cli_snd_task(intptr_t exinf);
-
-extern void	udp_echo_srv_task(intptr_t exinf);
-extern void	udp_echo_cli_task(intptr_t exinf);
-
-/*
- *  関数
- */
-
-extern ER callback_nblk_tcp_echo_srv (ID cepid, FN fncd, void *p_parblk);
-extern ER callback_nblk_tcp_echo_cli (ID cepid, FN fncd, void *p_parblk);
-
-extern ER callback_udp_echo_srv (ID cepid, FN fncd, void *p_parblk);
-extern ER callback_udp_echo_cli (ID cepid, FN fncd, void *p_parblk);
-
-extern ER callback_nblk_udp_echo_srv (ID cepid, FN fncd, void *p_parblk);
-extern ER callback_nblk_udp_echo_cli (ID cepid, FN fncd, void *p_parblk);
-
-#endif	/* of #ifndef _ECHO_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/lcd.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/lcd.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/lcd.c	(revision 331)
@@ -0,0 +1,495 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#include <stdarg.h>
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <sil.h>
+#include "target_syssvc.h"
+#include "target_lcd.h"
+#include <kernel.h>
+#include <t_syslog.h>
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "hw_lcd.h"
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/lcd.h>
+
+/*
+ *  å±æå¤æ°ã®å®ç¾©
+ */
+
+static bool_t newline = false;
+static int_t col = 0;
+static int8_t line[LCD_COLUMN_SIZE + 1] = { "                " };
+
+/*
+ *  lcd_cls -- LCD è¡¨ç¤ºã¯ãªã¢
+ */
+
+void
+lcd_cls (void)
+{
+	target_lcd_cls();
+	col = 0;
+	newline = false;
+	}
+
+/*
+ *  lcd_newline -- LCD ã®è¡¨ç¤ºãæ¹è¡ããã
+ */
+
+static void
+lcd_newline (void)
+{
+	target_lcd_newline(line, col);
+	col = 0;
+	newline = false;
+	}
+
+/*
+ *  lcd_initialize -- LCD åæå
+ */
+
+void
+lcd_initialize (intptr_t exinf)
+{
+	target_lcd_initialize();
+	lcd_cls();
+	}
+
+/*
+ *  lcd_putc -- LCD åºå
+ */
+
+void
+lcd_putc (ID portid, int8_t data)
+{
+	if (data == '\n')
+		newline = true;
+	else {
+		if (newline)
+			lcd_newline();
+		target_lcd_data_putc(data);
+		line[col ++] = data;
+		if (col >= LCD_COLUMN_SIZE)
+			newline = true;
+		}
+	}
+
+/*
+ *  lcd_puts -- LCD ã¸ã®æå­åã®åºå
+ */
+
+void
+lcd_puts (ID portid, const char *str)
+{
+	while (*str != '\0')
+		lcd_putc(portid, *str ++);
+	}
+
+/*
+ *  LCD ã¸ã®æ¸å¼ä»æå­ååºåã©ã¤ãã©ãª
+ */
+
+/*
+ *  æ°å¤å¤æã®ããã®å¤æè¡¨
+ */
+
+static const char radhex[] = "0123456789abcdef";
+static const char radHEX[] = "0123456789ABCDEF";
+
+/*
+ *  ãã£ã¨ãé·ãæ´æ°å (LONGEST) ã¨ç¬¦å·ãªãæ´æ°å (ULONGEST)
+ */
+
+#ifdef _int64_
+
+typedef _int64_			LONGEST;
+typedef unsigned _int64_	ULONGEST;
+
+#else	/* of #ifdef _int64_ */
+
+#ifdef _int32_
+
+typedef _int32_			LONGEST;
+typedef unsigned _int32_	ULONGEST;
+
+#else	/* of #ifdef _int32_ */
+
+typedef int_t			LONGEST;
+typedef uint_t			ULONGEST;
+
+#endif	/* of #ifdef _int32_ */
+
+#endif	/* of #ifdef _int64_ */
+
+/*
+ *  convert -- lcd_printf ã®æ°å¤å¤æ
+ */
+
+static int_t
+convert (ID portid, ULONGEST val, int_t radix,
+         const char *radchar, int_t width, bool_t minus, char padchar)
+{
+	char	digits[24];
+	int_t	ix, pad, pchars;
+	bool_t	left;
+
+	if (width < 0) {
+		width = -width;
+		left = true;
+		}
+	else
+		left = false;
+
+	ix = 0;
+	do {
+		digits[ix ++] = radchar[val % radix];
+		val /= radix;
+		} while (val != 0);
+
+	if (minus)
+		digits[ix ++] = '-';
+
+	if (width > ix)
+		pchars = width;
+	else
+		pchars = ix;
+
+	pad = ix;
+	if (!left)	/* å³è©°ã */
+		for ( ; pad < width; pad ++)
+			lcd_putc(portid, padchar);
+
+	while (ix -- > 0)
+		lcd_putc(portid, digits[ix]);
+
+	if (left)	/* å·¦è©°ã */
+		for ( ; pad < width; pad ++)
+			lcd_putc(portid, padchar);
+
+	return pchars;
+	}
+
+#if defined(SUPPORT_INET4)
+
+/*
+ *  ipv4addr -- IPv4 ã¢ãã¬ã¹åºå
+ */
+
+static void
+put_ipv4addr (ID portid, T_IN4_ADDR *addr, int_t width)
+{
+	int_t len = 3;	/* 3 ã¯ '.' ã®æå­æ° */
+
+	len += convert(portid, (*addr >> 24) & 0xff, 10, radhex, 0, false, ' '); 
+	lcd_putc(portid, '.');
+	len += convert(portid, (*addr >> 16) & 0xff, 10, radhex, 0, false, ' '); 
+	lcd_putc(portid, '.');
+	len += convert(portid, (*addr >>  8) & 0xff, 10, radhex, 0, false, ' '); 
+	lcd_putc(portid, '.');
+	len += convert(portid,  *addr        & 0xff, 10, radhex, 0, false, ' '); 
+
+	for ( ; len < width; len ++)
+		lcd_putc(portid, ' ');
+	}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#if defined(SUPPORT_INET6)
+
+/*
+ *  ipv6addr -- IPv6 ã¢ãã¬ã¹åºå
+ */
+
+static void
+put_ipv6addr (ID portid, const T_IN6_ADDR *addr, int_t width)
+{
+	int_t	len = 0, ix;
+	bool_t	omit = false, zero = false;
+
+	if (addr == NULL || IN6_IS_ADDR_UNSPECIFIED(addr)) {
+		lcd_putc(portid, ':');
+		lcd_putc(portid, ':');
+		}
+	else {
+		for (ix = 0; ix < sizeof(T_IN6_ADDR) / 2; ix ++) {
+			if (omit) {
+				if (ix < 7) {
+					lcd_putc(portid, ':');
+					len ++;
+					}
+				}
+			else if (ix > 0 && ix < 7 && addr->s6_addr16[ix] == 0)
+				zero = true;
+			else {
+				if (zero) {
+					omit = true;
+					lcd_putc(portid, ':');
+					len ++;
+					}
+				if (ix < 7) {
+					lcd_putc(portid, ':');
+					len ++;
+					}
+				}
+			}
+
+		for ( ; len < width; len ++)
+			lcd_putc(portid, ' ');
+		}
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+/*
+ *  macaddr -- MAC ã¢ãã¬ã¹åºå
+ */
+
+static void
+macaddr (ID portid, uint8_t *mac, int_t width)
+{
+	int_t oct, len;
+
+	for (oct = 5; oct -- > 0; ) {
+		convert(portid, *mac ++, 16, radhex, 2, false, '0'); 
+		lcd_putc(portid, ':');
+		}
+	convert(portid, *mac, 16, radhex, 2, false, '0'); 
+
+	for (len = 17; len < width; len ++)
+		lcd_putc(portid, ' ');
+	}
+
+/*
+ *  å¼æ°ãåãåºãããã®ãã¯ã­
+ */
+
+#ifdef _int32_
+
+#define GET_ARG(ap,lf)	 (lf ? va_arg(ap, _int32_) : va_arg(ap, int_t))
+
+#else	/* of #ifdef _int32_ */
+
+#define GET_ARG(ap,lf)	(va_arg(ap, int_t))
+
+#endif	/* of #ifdef _int32_ */
+
+/*
+ *  lcd_printf -- ã·ãªã¢ã«ãã¼ãã¸ã®æ¸å¼ä»æå­ååºå
+ */
+
+void
+lcd_printf (ID portid, const char *fmt, ...)
+{
+	va_list	ap;
+	LONGEST	val;
+	char	padchar, *str;
+	int_t	ch, width, longflag, shortflag, left;
+
+#if defined(SUPPORT_INET4)
+	T_IN4_ADDR	*addr;
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+	va_start(ap, fmt);
+	while ((ch = *fmt ++) != '\0') {
+		if (ch != '%') {		/* æ¸å¼æå®ä»¥å¤ */
+			lcd_putc(portid, (char)ch);
+			continue;
+			}
+
+		width = longflag = shortflag = 0;
+		padchar = ' ';
+
+		if (ch == '-') {		/* å·¦è©°ã */
+			fmt ++;
+			left = -1;
+			}
+		else
+			left = 1;
+
+		if ((ch = *fmt ++) == '0') {	/* ä¸ä½æ¡ã® 0 */
+			padchar = '0';
+			ch = *fmt ++;
+			}
+
+		while ('0' <= ch && ch <= '9') {	/* åºåå¹
+ */
+			width = width * 10 + ch - '0';
+			ch = *fmt ++;
+			}
+
+		while (ch == 'l') {		/* long (long) ã®æå® */
+			longflag ++;
+			ch = *fmt ++;
+			}
+
+		while (ch == 'h') {		/* short ã®æå® */
+			shortflag ++;
+			ch = *fmt ++;
+			}
+
+		switch (ch) {
+		case 'd':
+			val = GET_ARG(ap, longflag);
+			if (val >= 0)
+				convert(portid, val, 10, radhex, width * left, false, padchar);
+			else
+				convert(portid, -val, 10, radhex, width * left, true, padchar);
+			break;
+
+		case 'u':
+			val = GET_ARG(ap, longflag);
+			convert(portid, val, 10, radhex, width * left, false, padchar);
+			break;
+
+		case 'x':
+			val = GET_ARG(ap, longflag);
+			convert(portid, val, 16, radhex, width * left, false, padchar);
+			break;
+
+		case 'X':
+			val = GET_ARG(ap, longflag);
+			convert(portid, val, 16, radHEX, width * left, false, padchar);
+			break;
+
+		case 'c':
+			ch = va_arg(ap, int_t);
+			lcd_putc(portid, (char)ch);
+			break;
+
+		case 's':
+			str = va_arg(ap, char*);
+			while ((ch = *str ++) != '\0')
+				lcd_putc(portid, (char)ch);
+			break;
+
+		case 'I':
+
+			if (longflag) {
+
+#if defined(SUPPORT_INET6)
+
+				str = va_arg(ap, char*);
+				put_ipv6addr(portid, (T_IN6_ADDR *)str, width);
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+				addr = va_arg(ap, T_IN4_ADDR *);
+				put_ipv4addr(portid, addr, width);
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+				}
+			else if (shortflag) {
+
+#if defined(SUPPORT_INET4)
+
+				addr = va_arg(ap, T_IN4_ADDR *);
+				put_ipv4addr(portid, addr, width);
+
+#else	/* of #if defined(SUPPORT_INET4) */
+
+				str = va_arg(ap, char*);
+				put_ipv6addr(portid, (T_IN6_ADDR *)str, width);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+				}
+			else {
+
+#if defined(SUPPORT_INET6)
+
+				str = va_arg(ap, char*);
+				put_ipv6addr(portid, (T_IN6_ADDR *)str, width);
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+				addr = va_arg(ap, T_IN4_ADDR *);
+				put_ipv4addr(portid, addr, width);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+				}
+			break;
+
+		case 'M':
+			str = va_arg(ap, char*);
+			macaddr(portid, str, width);
+			break;
+
+		case '%':
+			lcd_putc(portid, '%');
+			break;
+
+		case '0':
+			fmt --;
+			break;
+
+		default:
+			break;
+			}
+
+		}
+	va_end(ap);
+	}
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/lcd.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/lcd.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/lcd.h	(revision 331)
@@ -0,0 +1,78 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  æ±ç¨ LCD ãã©ã¤ã
+ */
+
+#ifndef LCD_H
+#define LCD_H
+
+/*
+ *  lcd_cls -- LCD è¡¨ç¤ºã¯ãªã¢
+ */
+extern void lcd_cls (void);
+
+/*
+ *  lcd_initialize -- LCD åæå
+ */
+extern void lcd_initialize (intptr_t exinf);
+
+/*
+ *  lcd_putc -- LCD åºå
+ */
+extern void lcd_putc (ID portid, int8_t data);
+
+/*
+ *  lcd_puts -- LCD ã¸ã®æå­åã®åºå
+ */
+extern void lcd_puts (ID portid, const char *str);
+
+/*
+ *  LCD ã¸ã®æ¸å¼ä»æå­ååºåã©ã¤ãã©ãª
+ */
+extern void lcd_printf (ID portid, const char *fmt, ...);
+
+#endif	/* of #ifndef LCD_H */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/net_cons.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/net_cons.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/net_cons.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -60,13 +60,4 @@
 #endif	/* of #ifdef TARGET_KERNEL_JSP */
 
-#include <tinet_defs.h>
-
-#include <net/if.h>
-#include <net/if_ppp.h>
-#include <net/if_loop.h>
-#include <net/ethernet.h>
-#include <net/net.h>
-#include <net/net_timer.h>
-
 #include <netinet/in.h>
 #include <netinet/in_itron.h>
@@ -109,4 +100,10 @@
 #define TELNET_OPT_IAC		(255)
 
+#if defined(SUPPORT_INET6)
+#define API_PROTO		'6'
+#else
+#define API_PROTO		'4'
+#endif
+
 /*
  *  変数
@@ -121,4 +118,10 @@
 bool_t	wait_accept	= false;	/* 接続要求待ち中	*/
 
+#if defined(SUPPORT_INET6)
+
+T_IPV6EP	dst;
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
 #if defined(SUPPORT_INET4)
 
@@ -126,8 +129,4 @@
 
 #endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
-
-T_IPV6EP	dst;
 
 #endif	/* of #if defined(SUPPORT_INET6) */
@@ -156,10 +155,11 @@
 		get_tim(&now);
 		if (*(ER*)p_parblk == E_OK) {
-			syslog(LOG_NOTICE, "[NCS:%02u CBN] connected:  %6lu, from: %s.%u",
-			                   cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
+			syslog(LOG_NOTICE, "[NCS%c:%02u CBN] conct: %7lu, from: %s.%u",
+			                   API_PROTO, cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
 			connected = true;
 			}
 		else
-			syslog(LOG_NOTICE, "[NCS:%02d CBN] error: %s", itron_strerror(*(ER*)p_parblk));
+			syslog(LOG_NOTICE, "[NCS%c:%02d CBN] error: %s",
+			                   API_PROTO, itron_strerror(*(ER*)p_parblk));
 		snd_len = snd_off = rcv_len = rcv_off = 0;
 		wait_accept = false;
@@ -193,6 +193,6 @@
 		if (snd_off > 0) {
 			if ((error = tcp_snd_buf(NET_CONS_CEPID, snd_off)) != E_OK && error != E_CLS)
-				syslog(LOG_NOTICE, "[NCS:%02d SND] flush send error: %s",
-				                   NET_CONS_CEPID, itron_strerror(error));
+				syslog(LOG_NOTICE, "[NCS%c:%02d SND] flush send error: %s",
+				                   API_PROTO, NET_CONS_CEPID, itron_strerror(error));
 			snd_len = snd_off = 0;
 			}
@@ -218,6 +218,6 @@
 			if ((error = tcp_snd_buf(NET_CONS_CEPID, snd_off)) != E_OK) {
 				if (error != E_CLS)
-					syslog(LOG_NOTICE, "[NCS:%02d SND] send buff error: %s",
-					                   NET_CONS_CEPID, itron_strerror(error));
+					syslog(LOG_NOTICE, "[NCS%c:%02d SND] send buff error: %s",
+					                   API_PROTO, NET_CONS_CEPID, itron_strerror(error));
 				syscall(sig_sem(SEM_NET_CONS_SEND));
 				return;
@@ -226,6 +226,6 @@
 			if ((snd_len = tcp_get_buf(NET_CONS_CEPID, (void*)&snd_buff, TMO_FEVR)) <= 0) {
 				if (snd_len != E_CLS)
-					syslog(LOG_NOTICE, "[NCS:%02d SND] get buff error: %s",
-					                   NET_CONS_CEPID, itron_strerror(snd_len));
+					syslog(LOG_NOTICE, "[NCS%c:%02d SND] get buff error: %s",
+					                   API_PROTO, NET_CONS_CEPID, itron_strerror(snd_len));
 				syscall(sig_sem(SEM_NET_CONS_SEND));
 				return;
@@ -253,6 +253,6 @@
 			if ((error = tcp_rel_buf(NET_CONS_CEPID, rcv_len)) != E_OK) {
 				if (error != E_CLS)
-					syslog(LOG_NOTICE, "[NCS:%02d RCV] release buff error: %s",
-					                   NET_CONS_CEPID, itron_strerror(error));
+					syslog(LOG_NOTICE, "[NCS%c:%02d RCV] release buff error: %s",
+					                   API_PROTO, NET_CONS_CEPID, itron_strerror(error));
 				discon_net_cons();
 				return EOF;
@@ -264,6 +264,6 @@
 			else if (rcv_len < 0) {
 				if (rcv_len != E_CLS)
-					syslog(LOG_NOTICE, "[NCS:%02d RCV] recieve buff error: %s",
-					                   NET_CONS_CEPID, itron_strerror(rcv_len));
+					syslog(LOG_NOTICE, "[NCS%c:%02d RCV] recieve buff error: %s",
+					                   API_PROTO, NET_CONS_CEPID, itron_strerror(rcv_len));
 				discon_net_cons();
 				return EOF;
@@ -284,5 +284,5 @@
 {
 	T_SERIAL_RPOR	rpor;
-	int_t		ch, req;
+	int_t		ch;
 	char		uch;
 	ER		error;
@@ -292,5 +292,6 @@
 		error = TCP_ACP_CEP(NET_CONS_CEPID, NET_CONS_REPID, &dst, TMO_NBLK);
 #if 0
-		syslog(LOG_NOTICE, "[NCS:%02d ACP] status: %s",NET_CONS_CEPID, itron_strerror(error));
+		syslog(LOG_NOTICE, "[NCS%c:%02d ACP] status: %s",
+		                   API_PROTO, NET_CONS_CEPID, itron_strerror(error));
 #endif
 		if (error != E_WBLK)
@@ -307,5 +308,5 @@
 					case TELNET_OPT_DO:
 					case TELNET_OPT_DONT:
-						req = cons_getchar_raw();
+						cons_getchar_raw();
 						break;
 					case TELNET_OPT_SB:
@@ -354,18 +355,18 @@
 		if (snd_off > 0) {
 			if ((error = tcp_snd_buf(NET_CONS_CEPID, snd_off)) != E_OK && error != E_CLS)
-				syslog(LOG_NOTICE, "[NCS:%02d SND] send buff error: %s",
-				                   NET_CONS_CEPID, itron_strerror(error));
+				syslog(LOG_NOTICE, "[NCS%c:%02d SND] send buff error: %s",
+				                   API_PROTO, NET_CONS_CEPID, itron_strerror(error));
 			}
 		if ((error = tcp_sht_cep(NET_CONS_CEPID)) != E_OK)
-			syslog(LOG_NOTICE, "[NCS:%02d SHT] shutdown error: %s",
-			                   NET_CONS_CEPID, itron_strerror(error));
+			syslog(LOG_NOTICE, "[NCS%c:%02d SHT] shutdown error: %s",
+			                   API_PROTO, NET_CONS_CEPID, itron_strerror(error));
 		if ((error = tcp_cls_cep(NET_CONS_CEPID, TMO_FEVR)) != E_OK)
-			syslog(LOG_NOTICE, "[NCS:%02d CLS] close error: %s",
-			                   NET_CONS_CEPID, itron_strerror(error));
+			syslog(LOG_NOTICE, "[NCS%c:%02d CLS] close error: %s",
+			                   API_PROTO, NET_CONS_CEPID, itron_strerror(error));
 		connected = false;
 		syscall(sig_sem(SEM_NET_CONS_SEND));
 		get_tim(&now);
-		syslog(LOG_NOTICE, "[NCS:%02u SND] disconnected:%5lu, from: %s.%u",
-		                   NET_CONS_CEPID, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
+		syslog(LOG_NOTICE, "[NCS%c:%02u SND] discn: %7lu, from: %s.%u",
+		                   API_PROTO, NET_CONS_CEPID, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
 		}
 	return error;
@@ -499,5 +500,5 @@
 			case 'M':
 				str = va_arg(ap, char*);
-				put_macaddr(CONSOLE_PORTID, str, width);
+				put_macaddr(CONSOLE_PORTID, (uint8_t *)str, width);
 				break;
 
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/net_cons.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/net_cons.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/net_cons.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/net_cons.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/net_cons.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/net_cons.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/netapp.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/netapp.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/netapp.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -39,11 +39,17 @@
  */
 
+#if defined(SUPPORT_INET6)
+
+#define PUT_IPADDR(p,a,w)	put_ipv6addr(p,a,w)
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
 #if defined(SUPPORT_INET4)
+
 #define PUT_IPADDR(p,a,w)	put_ipv4addr(p,a,w)
-#endif
 
-#if defined(SUPPORT_INET6)
-#define PUT_IPADDR(p,a,w)	put_ipv6addr(p,a,w)
-#endif
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
 
 /*
@@ -52,8 +58,12 @@
 
 #ifndef CONSOLE_PORTID
+#define	CONSOLE_PORTID		LOGTASK_PORTID
+#endif
 
-#define	CONSOLE_PORTID		LOGTASK_PORTID
+/*
+ *  コンソールに用いる LCD ポート番号
+ */
 
-#endif	/* of #ifndef CONSOLE_PORTID */
+#define	LCD_PORTID		0
 
 /*
@@ -80,9 +90,8 @@
 extern int_t put_macaddr (ID portid, uint8_t *mac, int_t width);
 
-#if defined(SUPPORT_INET4)
+#ifdef T_IN4_ADDR_DEFINED
 extern int_t put_ipv4addr (ID portid, T_IN4_ADDR *addr, int_t width);
 #endif
-
-#if defined(SUPPORT_INET6)
+#ifdef T_IN6_ADDR_DEFINED
 extern int_t put_ipv6addr (ID portid, const T_IN6_ADDR *addr, int_t width);
 #endif
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/netapp_subr.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/netapp_subr.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/netapp_subr.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -44,4 +44,6 @@
 #include <sil.h>
 #include <syssvc/serial.h>
+#include <syssvc/logtask.h>
+#include <t_syslog.h>
 #include "kernel_cfg.h"
 #include "tinet_cfg.h"
@@ -62,4 +64,5 @@
 
 #include <net/net.h>
+#include <net/net_endian.h>
 
 #include <netinet/in.h>
@@ -68,6 +71,244 @@
 #include <netapp/netapp.h>
 #include <netapp/netapp_var.h>
+#include <netapp/resolver.h>
 
 #ifdef USE_NETAPP_SUBR
+
+/*
+ *  IPv6 と IPv4 で引数が異なる関数のコンパイル
+ */
+
+#if defined(SUPPORT_INET6)
+
+#ifdef USE_TCP_EXTENTIONS
+
+const ID vrid_tcp6_cep[] =
+{
+#if NUM_VRID_TCP6_CEPS >= 1
+	TCP6_RSV_CEPID1,
+#endif
+#if NUM_VRID_TCP6_CEPS >= 2
+	TCP6_RSV_CEPID2,
+#endif
+#if NUM_VRID_TCP6_CEPS >= 3
+	TCP6_RSV_CEPID3,
+#endif
+#if NUM_VRID_TCP6_CEPS >= 4
+	TCP6_RSV_CEPID4,
+#endif
+	};
+
+const ID vrid_tcp6_rep[] =
+{
+#if NUM_VRID_TCP6_REPS >= 1
+	TCP6_RSV_REPID1,
+#endif
+#if NUM_VRID_TCP6_REPS >= 2
+	TCP6_RSV_REPID2,
+#endif
+	};
+
+ID tskid_tcp6_cep[NUM_VRID_TCP6_CEPS];
+ID tskid_tcp6_rep[NUM_VRID_TCP6_REPS];
+
+#endif	/* #ifdef USE_TCP_EXTENTIONS */
+
+#ifdef USE_UDP_EXTENTIONS
+
+const ID vrid_udp6_cep[] =
+{
+#if NUM_VRID_UDP6_CEPS >= 1
+	UDP6_RSV_CEPID1,
+#endif
+#if NUM_VRID_UDP6_CEPS >= 2
+	UDP6_RSV_CEPID2,
+#endif
+	};
+
+ID tskid_udp6_cep[NUM_VRID_UDP6_CEPS];
+
+#endif	/* #ifdef USE_UDP_EXTENTIONS */
+
+#undef	TCP_CRE_REP
+#undef	UDP_CRE_CEP
+#undef	UDP_DEL_CEP
+#undef	TCP_IS_CEPID
+#undef  ALLOC_TCP_REP
+#undef  ALLOC_TCP_CEP
+#undef  ALLOC_UDP_CEP
+#undef  FREE_TCP_REP
+#undef  FREE_TCP_CEP
+#undef  FREE_UDP_CEP
+#undef	T_TCPN_CREP
+#undef	T_UDPN_CCEP
+#undef	NUM_VRID_TCP_CEPS
+#undef	NUM_VRID_TCP_REPS
+#undef	NUM_VRID_UDP_CEPS
+#undef	VRID_TCP_CEP
+#undef	VRID_UDP_CEP
+#undef	VRID_TCP_REP
+#undef	TSKID_TCP_CEP
+#undef	TSKID_TCP_REP
+#undef	TSKID_UDP_CEP
+#undef	API_IPPROTO
+
+#define TCP_CRE_REP		tcp6_cre_rep
+#define UDP_CRE_CEP		udp6_cre_cep
+#define UDP_DEL_CEP		udp6_del_cep
+
+#define TCP_IS_CEPID		tcp6_is_cepid
+#define ALLOC_TCP_REP		alloc_tcp6_rep
+#define ALLOC_TCP_CEP		alloc_tcp6_cep
+#define ALLOC_UDP_CEP		alloc_udp6_cep
+#define FREE_TCP_REP		free_tcp6_rep
+#define FREE_TCP_CEP		free_tcp6_cep
+#define FREE_UDP_CEP		free_udp6_cep
+#define T_TCPN_CREP		T_TCP6_CREP
+#define T_UDPN_CCEP		T_UDP6_CCEP
+#define NUM_VRID_TCP_CEPS	NUM_VRID_TCP6_CEPS
+#define NUM_VRID_TCP_REPS	NUM_VRID_TCP6_REPS
+#define NUM_VRID_UDP_CEPS	NUM_VRID_UDP6_CEPS
+#define VRID_TCP_CEP		vrid_tcp6_cep
+#define VRID_TCP_REP		vrid_tcp6_rep
+#define VRID_UDP_CEP		vrid_udp6_cep
+#define TSKID_TCP_CEP		tskid_tcp6_cep
+#define TSKID_TCP_REP		tskid_tcp6_rep
+#define TSKID_UDP_CEP		tskid_udp6_cep
+#define API_IPPROTO		API_PROTO_IPV6
+
+#include <netapp/netappn_subr.c>
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+#ifdef USE_TCP_EXTENTIONS
+
+const ID vrid_tcp4_cep[] =
+{
+#if NUM_VRID_TCP4_CEPS >= 1
+	TCP4_RSV_CEPID1,
+#endif
+#if NUM_VRID_TCP4_CEPS >= 2
+	TCP4_RSV_CEPID2,
+#endif
+#if NUM_VRID_TCP4_CEPS >= 3
+	TCP4_RSV_CEPID3,
+#endif
+#if NUM_VRID_TCP4_CEPS >= 4
+	TCP4_RSV_CEPID4,
+#endif
+	};
+
+const ID vrid_tcp4_rep[] =
+{
+#if NUM_VRID_TCP4_REPS >= 1
+	TCP4_RSV_REPID1,
+#endif
+#if NUM_VRID_TCP4_REPS >= 2
+	TCP4_RSV_REPID2,
+#endif
+	};
+
+ID tskid_tcp4_cep[NUM_VRID_TCP4_CEPS];
+ID tskid_tcp4_rep[NUM_VRID_TCP4_REPS];
+
+#endif	/* #ifdef USE_TCP_EXTENTIONS */
+
+#ifdef USE_UDP_EXTENTIONS
+
+const ID vrid_udp4_cep[] =
+{
+#if NUM_VRID_UDP4_CEPS >= 1
+	UDP4_RSV_CEPID1,
+#endif
+#if NUM_VRID_UDP4_CEPS >= 2
+	UDP4_RSV_CEPID2,
+#endif
+	};
+
+ID tskid_udp4_cep[NUM_VRID_UDP4_CEPS];
+
+#endif	/* #ifdef USE_UDP_EXTENTIONS */
+
+#undef	TCP_CRE_REP
+#undef	UDP_CRE_CEP
+#undef	UDP_DEL_CEP
+#undef	TCP_IS_CEPID
+#undef  ALLOC_TCP_REP
+#undef  ALLOC_TCP_CEP
+#undef  ALLOC_UDP_CEP
+#undef  FREE_TCP_REP
+#undef  FREE_TCP_CEP
+#undef  FREE_UDP_CEP
+#undef	T_TCPN_CREP
+#undef	T_UDPN_CCEP
+#undef	NUM_VRID_TCP_CEPS
+#undef	NUM_VRID_TCP_REPS
+#undef	NUM_VRID_UDP_CEPS
+#undef	VRID_TCP_CEP
+#undef	VRID_TCP_REP
+#undef	VRID_UDP_CEP
+#undef	TSKID_TCP_CEP
+#undef	TSKID_TCP_REP
+#undef	TSKID_UDP_CEP
+#undef	API_IPPROTO
+
+#define TCP_CRE_REP		tcp_cre_rep
+#define UDP_CRE_CEP		udp_cre_cep
+#define UDP_DEL_CEP		udp_del_cep
+#define TCP_IS_CEPID		tcp4_is_cepid
+#define ALLOC_TCP_REP		alloc_tcp4_rep
+#define ALLOC_TCP_CEP		alloc_tcp4_cep
+#define ALLOC_UDP_CEP		alloc_udp4_cep
+#define FREE_TCP_REP		free_tcp4_rep
+#define FREE_TCP_CEP		free_tcp4_cep
+#define FREE_UDP_CEP		free_udp4_cep
+#define T_TCPN_CREP		T_TCP_CREP
+#define T_UDPN_CCEP		T_UDP_CCEP
+#define NUM_VRID_TCP_CEPS	NUM_VRID_TCP4_CEPS
+#define NUM_VRID_TCP_REPS	NUM_VRID_TCP4_REPS
+#define NUM_VRID_UDP_CEPS	NUM_VRID_UDP4_CEPS
+#define VRID_TCP_CEP		vrid_tcp4_cep
+#define VRID_TCP_REP		vrid_tcp4_rep
+#define VRID_UDP_CEP		vrid_udp4_cep
+#define TSKID_TCP_CEP		tskid_tcp4_cep
+#define TSKID_TCP_REP		tskid_tcp4_rep
+#define TSKID_UDP_CEP		tskid_udp4_cep
+#define API_IPPROTO		API_PROTO_IPV4
+
+#include <netapp/netappn_subr.c>
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#undef	TCP_CRE_REP
+#undef  ALLOC_TCPN_REP
+#undef  ALLOC_TCPN_CEP
+#undef  ALLOC_UDPN_CEP
+#undef  FREE_TCPN_REP
+#undef  FREE_TCPN_CEP
+#undef  FREE_UDPN_CEP
+#undef	T_TCPN_CREP
+#undef	NUM_VRID_TCP_REPS
+#undef	NUM_VRID_UDP_CEPS
+#undef	VRID_TCP_CEP
+#undef	VRID_TCP_REP
+#undef	VRID_UDP_CEP
+#undef	TSKID_TCP_CEP
+#undef	TSKID_TCP_REP
+#undef	TSKID_UDP_CEP
+
+/*
+ *  変数
+ */
+
+static uint32_t rand_next = ULONG_C(1);
+
+#if !defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+const T_IN6_ADDR in6_addr_unspecified =
+	IPV6_ADDR_UNSPECIFIED_INIT;
+
+#endif	/* of #if !defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
 
 /*
@@ -83,4 +324,28 @@
 const char radhex[] = "0123456789abcdef";
 const char radHEX[] = "0123456789ABCDEF";
+
+/*
+ *  netapp_rand -- 乱数を返す。
+ */
+
+uint32_t
+netapp_rand (void)
+{
+	rand_next = (rand_next * 99991 + 12345) & ULONG_C(0x7fffffff);
+	return rand_next;
+	}
+
+/*
+ *  srand -- 乱数を初期化する。
+ */
+
+void
+netapp_srand (uint32_t seed)
+{
+	SYSTIM now;
+
+	syscall(get_tim(&now));
+	rand_next += now + seed;
+	}
 
 #ifndef USE_NET_CONS
@@ -160,6 +425,4 @@
 	return pchars;
 	}
-
-#if defined(SUPPORT_INET4)
 
 /*
@@ -186,10 +449,4 @@
 	}
 
-#define PUT_IPADDR(p,a,w)	put_ipv4addr(p,a,w)
-
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
-
 /*
  *  ipv6addr -- IPv6 アドレス出力
@@ -199,8 +456,8 @@
 put_ipv6addr (ID portid, const T_IN6_ADDR *addr, int_t width)
 {
-	int_t	len = 0, ix;
+	int_t	len = 0, ix, len6;
 	bool_t	omit = false, zero = false;
 
-	if (addr == NULL) {
+	if (addr == NULL || IN6_IS_ADDR_UNSPECIFIED(addr)) {
 		cons_putchar(portid, '0');
 		cons_putchar(portid, ':');
@@ -210,5 +467,9 @@
 		}
 	else {
-		for (ix = 0; ix < sizeof(T_IN6_ADDR) / 2; ix ++) {
+		if (in6_is_addr_ipv4mapped(addr))
+			len6 = sizeof(T_IN6_ADDR) / 2 - 2;
+		else
+			len6 = sizeof(T_IN6_ADDR) / 2;
+		for (ix = 0; ix < len6; ix ++) {
 			if (omit) {
 				len += cons_putnumber(portid, ntohs(addr->s6_addr16[ix]), 16, radhex, 0, false, ' '); 
@@ -234,4 +495,11 @@
 			}
 
+		if (len6 == sizeof(T_IN6_ADDR) / 2 - 2) {
+			T_IN4_ADDR ip4addr;
+
+			ip4addr = ntohl(addr->s6_addr32[3]);
+			len += put_ipv4addr(portid, &ip4addr, 0);
+			}
+
 		for ( ; len < width; len ++)
 			cons_putchar(portid, ' ');
@@ -239,8 +507,4 @@
 	return len;
 	}
-
-#define PUT_IPADDR(p,a,w)	put_ipv6addr(p,a,w)
-
-#endif	/* of #if defined(SUPPORT_INET6) */
 
 /*
@@ -275,9 +539,6 @@
 	long_t	val;
 	char	padchar, *str;
-	int_t	ch, width, longflag, left;
-
-#if defined(SUPPORT_INET4)
+	int_t	ch, width, longflag, shortflag, left;
 	T_IN4_ADDR	*addr;
-#endif	/* of #if defined(SUPPORT_INET4) */
 
 	va_start(ap, fmt);
@@ -288,8 +549,8 @@
 			}
 
-		width = longflag = 0;
+		width = longflag = shortflag = 0;
 		padchar = ' ';
 
-		if (ch == '-') {		/* 左詰め */
+		if (*fmt == '-') {		/* 左詰め */
 			fmt ++;
 			left = -1;
@@ -310,4 +571,9 @@
 		while (ch == 'l') {		/* long (long) の指定 */
 			longflag ++;
+			ch = *fmt ++;
+			}
+
+		while (ch == 'h') {		/* short の指定 */
+			shortflag ++;
 			ch = *fmt ++;
 			}
@@ -358,23 +624,36 @@
 		case 'I':
 
+			if (longflag) {
+				str = va_arg(ap, char*);
+				put_ipv6addr(portid, (T_IN6_ADDR *)str, width);
+				}
+			else if (shortflag) {
+				addr = va_arg(ap, T_IN4_ADDR *);
+				put_ipv4addr(portid, addr, width);
+				}
+			else {
+
+#if defined(SUPPORT_INET6)
+
+				str = va_arg(ap, char*);
+				put_ipv6addr(portid, (T_IN6_ADDR *)str, width);
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
 #if defined(SUPPORT_INET4)
 
-			addr = va_arg(ap, T_IN4_ADDR *);
-			put_ipv4addr(portid, addr, width);
+				addr = va_arg(ap, T_IN4_ADDR *);
+				put_ipv4addr(portid, addr, width);
 
 #endif	/* of #if defined(SUPPORT_INET4) */
 
-#if defined(SUPPORT_INET6)
-
-			str = va_arg(ap, char*);
-			put_ipv6addr(portid, (T_IN6_ADDR *)str, width);
-
 #endif	/* of #if defined(SUPPORT_INET6) */
 
+				}
 			break;
 
 		case 'M':
 			str = va_arg(ap, char*);
-			put_macaddr(portid, str, width);
+			put_macaddr(portid, (uint8_t *)str, width);
 			break;
 
@@ -396,4 +675,56 @@
 
 /*
+ *  host2msg16 -- 16ビットの値を、バイトオーダーを調整してメッセージに書き込む。
+ */
+
+void
+host2msg16 (void *msg, uint16_t host_data)
+{
+	uint16_t	msg_data;
+
+	msg_data = htons(host_data);
+	memcpy(msg, &msg_data, sizeof(msg_data));
+	}
+
+/*
+ *  host2msg32 -- 32ビットの値を、バイトオーダーを調整してメッセージに書き込む。
+ */
+
+void
+host2msg32 (void *msg, uint32_t host_data)
+{
+	uint32_t	msg_data;
+
+	msg_data = htonl(host_data);
+	memcpy(msg, &msg_data, sizeof(msg_data));
+	}
+
+/*
+ *  msg2host16 -- 16ビットの値を、バイトオーダーを調整してメッセージから読み出す。
+ */
+
+uint16_t
+msg2host16 (void *msg)
+{
+	uint16_t	host_data;
+
+	memcpy(&host_data, msg, sizeof(host_data));
+	return htons(host_data);
+	}
+
+/*
+ *  msg2host32 -- 32ビットの値を、バイトオーダーを調整してメッセージから読み出す。
+ */
+
+uint32_t
+msg2host32 (void *msg)
+{
+	uint32_t	host_data;
+
+	memcpy(&host_data, msg, sizeof(host_data));
+	return htonl(host_data);
+	}
+
+/*
  *  skip_blanks -- 空白と TAB をスキップする。
  */
@@ -416,5 +747,5 @@
 	int_t oct;
 
-	*addr = 0;
+	*addr = IPV4_ADDRANY;
 	while ('0' <= *line && *line <= '9') {
 		oct = 0;
@@ -425,8 +756,12 @@
 			line ++;
 		}
+#if 1
+	return *addr == IPV4_ADDRANY ? NULL : line;
+#else
 	return line;
-	}
-
-#if defined(SUPPORT_INET6)
+#endif
+	}
+
+#if defined(SUPPORT_INET6) || defined(USE_RESOLVER)
 
 /*
@@ -438,35 +773,51 @@
 {
 	int_t word, ix = 0, omit = 0, six;
+	char *ipv4line;
 
 	memset(addr, 0, sizeof(T_IN6_ADDR));
-	while (ix < 8 &&
-	       (('0' <= *line && *line <= '9') ||
-	        ('a' <= *line && *line <= 'f') ||
-	        ('A' <= *line && *line <= 'F'))) {
-		word = 0;
-		while (('0' <= *line && *line <= '9') ||
- 	               ('a' <= *line && *line <= 'f') ||
-	               ('A' <= *line && *line <= 'F')) {
-			if      ('0' <= *line && *line <= '9')
-				word = (word << 4) + (*line ++) - '0';
-			else if ('a' <= *line && *line <= 'f')
-				word = (word << 4) + (*line ++) - 'a' + 10;
-			else if ('A' <= *line && *line <= 'F')
-				word = (word << 4) + (*line ++) - 'A' + 10;
-			}
-		addr->s6_addr16[ix ++] = htons(word);
-		if (*line == ':') {
-			line ++;
+
+	/*
+	 * IPv4 アドレス（数字.）を検出したら IPv4 アドレスとして入力し、
+	 * IPv4 射影アドレスに変換する。
+	 */
+	for (ipv4line = line; '0' <= *ipv4line && *ipv4line <= '9'; ipv4line ++)
+		;
+	if (*ipv4line == '.') {
+		T_IN4_ADDR ipv4addr;
+
+		line = get_ipv4addr(&ipv4addr, line);
+		in6_make_ipv4mapped (addr, ipv4addr);
+		}
+	else {
+		while (ix < 8 &&
+		       (('0' <= *line && *line <= '9') ||
+		        ('a' <= *line && *line <= 'f') ||
+		        ('A' <= *line && *line <= 'F'))) {
+			word = 0;
+			while (('0' <= *line && *line <= '9') ||
+ 		               ('a' <= *line && *line <= 'f') ||
+		               ('A' <= *line && *line <= 'F')) {
+				if      ('0' <= *line && *line <= '9')
+					word = (word << 4) + (*line ++) - '0';
+				else if ('a' <= *line && *line <= 'f')
+					word = (word << 4) + (*line ++) - 'a' + 10;
+				else if ('A' <= *line && *line <= 'F')
+					word = (word << 4) + (*line ++) - 'A' + 10;
+				}
+			addr->s6_addr16[ix ++] = htons(word);
 			if (*line == ':') {
-				omit = ix;
 				line ++;
-				}
-			}
-		}
-	if (omit > 0) {
-		six = 7;
-		while (ix > omit) {
-			addr->s6_addr16[six --] = addr->s6_addr16[-- ix];
-			addr->s6_addr16[ ix   ] = 0;
+				if (*line == ':') {
+					omit = ix;
+					line ++;
+					}
+				}
+			}
+		if (omit > 0) {
+			six = 7;
+			while (ix > omit) {
+				addr->s6_addr16[six --] = addr->s6_addr16[-- ix];
+				addr->s6_addr16[ ix   ] = 0;
+				}
 			}
 		}
@@ -474,5 +825,5 @@
 	}
 
-#endif	/* of #if defined(SUPPORT_INET6) */
+#endif	/* of #if defined(SUPPORT_INET6) || defined(USE_RESOLVER) */
 
 /*
@@ -559,199 +910,319 @@
 	}
 
-#ifdef USE_TCP_EXTENTIONS
-
-const ID vrid_tcp_rep[] =
-{
-#if NUM_VRID_TCP_REPS >= 1
-	TCP_RSV_REPID1,
-#endif
-#if NUM_VRID_TCP_REPS >= 2
-	TCP_RSV_REPID2,
-#endif
-	};
-
-const ID vrid_tcp_cep[] =
-{
-#if NUM_VRID_TCP_CEPS >= 1
-	TCP_RSV_CEPID1,
-#endif
-#if NUM_VRID_TCP_CEPS >= 2
-	TCP_RSV_CEPID2,
-#endif
-#if NUM_VRID_TCP_CEPS >= 3
-	TCP_RSV_CEPID3,
-#endif
-#if NUM_VRID_TCP_CEPS >= 4
-	TCP_RSV_CEPID4,
-#endif
-	};
-
-ID tskid_tcp_rep[NUM_VRID_TCP_REPS];
-ID tskid_tcp_cep[NUM_VRID_TCP_CEPS];
-
-/*
- *  alloc_tcp_rep -- TCP 受付口を獲得する。
- */
-
-ER
-alloc_tcp_rep (ID *repid, ID tskid, T_TCP_CREP *crep)
-{
-	int_t	ix;
-
-	*repid = TCP_REP_NONE;
-	syscall(wai_sem(SEM_ALLOC_TCP_REP_LOCK));
-	for (ix = NUM_VRID_TCP_REPS; ix -- > 0; ) {
-		if (tskid_tcp_rep[ix] == TSK_NONE) {
-			*repid = vrid_tcp_rep[ix];
-			tskid_tcp_rep[ix] = tskid;
+#ifdef USE_RESOLVER
+
+/*
+ *  dns_strtype -- DNS の type の文字列を返す。
+ */
+
+const char *
+dns_strtype (uint_t type)
+{
+	switch (type) {
+	case DNS_TYPE_A:
+		return "A";
+		break;
+	case DNS_TYPE_NS:
+		return "NS";
+		break;
+	case DNS_TYPE_CNAME:
+		return "CNAME";
+		break;
+	case DNS_TYPE_SOA:
+		return "SOA";
+		break;
+	case DNS_TYPE_PTR:
+		return "PTR";
+		break;
+	case DNS_TYPE_AAAA:
+		return "AAAA";
+		break;
+	default:
+		return "unknown type";
+		break;
+		}
+	}
+
+/*
+ *  dns_strclass -- DNS の class を表示する。
+ */
+
+const char *
+dns_strclass (uint_t class)
+{
+	switch (class) {
+	case DNS_CLASS_IN:
+		return "IN";
+		break;
+	default:
+		return "unknown class";
+		break;
+		}
+	}
+
+/*
+ *  resolv_hoststr -- 文字列のFQDN・ホスト名・IPv6/IPv4 アドレスを解析する。
+ */
+
+#define IS_HOSTCH_DIGIT(c)	(('0'<=(c)&&(c)<='9'))
+#define IS_HOSTCH_XDIGIT(c)	(IS_HOSTCH_DIGIT(c)||('a'<=(c)&&(c)<='f')||('A'<=(c)&&(c)<='F'))
+#define IS_HOSTCH_ALPHA(c)	(('a'<=(c)&&(c)<='z')||('A'<=(c)&&(c)<='z'))
+#define IS_HOSTCH_ALNUM(c)	(IS_HOSTCH_ALPHA(c)||IS_HOSTCH_DIGIT(c))
+#define IS_HOSTCH_IPV6ADDR(c)	(IS_HOSTCH_XDIGIT(c)||(c)==':')
+#define IS_HOSTCH_IPV4ADDR(c)	(IS_HOSTCH_DIGIT(c)||(c)=='.')
+#define IS_HOSTCH_IPADDR(c)	(IS_HOSTCH_XDIGIT(c)||(c)==':'||(c)=='.')
+#define IS_HOSTCH_NAME_FIRST(c)	(IS_HOSTCH_ALPHA(c))
+#define IS_HOSTCH_NAME(c)	(IS_HOSTCH_ALNUM(c)||(c)=='-'||(c)=='.')
+#define IS_HOSTCH_BLANK(c)	((c)=='\0'||(c)==' '||(c)=='\t')
+
+char *
+resolv_hoststr (uint_t *flags, char *hostname, uint_t name_size, char *line)
+{
+	char *h, *p;
+
+	h = hostname;
+	p = line = skip_blanks(line);
+
+	if (IS_HOSTCH_IPADDR(*p)) {
+		while (IS_HOSTCH_DIGIT(*p)) {
+			if (h - hostname > name_size)
+				return NULL;
+			*h ++ = *p ++;
+			}
+		if (p > line && *p == '.') {
+			while (IS_HOSTCH_IPV4ADDR(*p)) {
+				if (h - hostname > name_size)
+					return NULL;
+				*h ++ = *p ++;
+				}
+			if (IS_HOSTCH_BLANK(*p)) {
+				*flags |= HOSTSTR_IPV4;
+				*h = '\0';
+				return p;
+				}
+			}
+		else if (IS_HOSTCH_IPADDR(*p)) {
+			while (IS_HOSTCH_IPADDR(*p)) {
+				if (h - hostname > name_size)
+					return NULL;
+				*h ++ = *p ++;
+				}
+			if (IS_HOSTCH_BLANK(*p)) {
+				*flags |= HOSTSTR_IPV6;
+				*h = '\0';
+				return p;
+				}
+			}
+		h = hostname;
+		p = line;
+		}
+
+	if (IS_HOSTCH_NAME_FIRST(*p)) {
+		*flags |= HOSTSTR_HOSTNAME;
+		while (IS_HOSTCH_NAME(*p)) {
+			if (h - hostname > name_size)
+				return NULL;
+			if (*p == '.')
+				*flags |= HOSTSTR_FQDN;
+			*h ++ = *p ++;
+			}
+		}
+	else
+		*flags |= HOSTSTR_OTHER;
+
+	*h = '\0';
+	return p;
+	}
+
+/*
+ *  show_dns_domain_name -- DNS のドメイン名を表示する。
+ */
+
+uint_t
+show_dns_domain_name (ID portid, uint8_t *hdr, uint_t offset)
+{
+	uint8_t	*ptr;
+	uint_t	c;
+
+	ptr = hdr + offset;
+	while (*ptr) {
+		if ((*ptr & DNS_MSG_COMP_MARK) == DNS_MSG_COMP_MARK) {
+			show_dns_domain_name(portid, hdr, (*ptr & ~DNS_MSG_COMP_MARK) << 8 | *(ptr + 1));
+			ptr += 2;
 			break;
 			}
-		}
-	syscall(sig_sem(SEM_ALLOC_TCP_REP_LOCK));
-
-	if (*repid == TCP_REP_NONE)
-		return E_NOEXS;
+		else {
+			for (c = 1; c <= *ptr; c++)
+				cons_printf(portid, "%c", *(ptr + c));
+			ptr += *ptr + 1;
+			if (*ptr)
+				cons_printf(portid, ".");
+			}
+		}
+	return ptr - hdr;
+	}
+
+/*
+ *  resolv_options -- アドレス解決のオプション解析
+ */
+
+char *
+resolv_options (uint_t *flags, char *line, char apip)
+{
+#if defined(SUPPORT_INET6)
+	T_IN6_ADDR	in6_addr;
+#endif
+
+#if defined(SUPPORT_INET4)
+	T_IN4_ADDR	in4_addr;
+#endif
+
+	line = skip_blanks(line);
+
+#if defined(SUPPORT_INET6)
+
+#if defined(SUPPORT_INET4)
+
+	*flags |= DNS_LUP_FLAGS_PROTO_IPV6 | DNS_LUP_FLAGS_PROTO_IPV4;
+	if (apip == API_PROTO_IPV4)
+		*flags |= DNS_LUP_FLAGS_QTYPE_A;
 	else
-		return TCP_CRE_REP(*repid, crep);
-	}
-
-/*
- *  free_tcp_rep -- TCP 受付口を解放する。
- */
-
-ER
-free_tcp_rep (ID repid, bool_t call_tcp_del_rep)
-{
-	int_t	ix;
-
-	syscall(wai_sem(SEM_ALLOC_TCP_REP_LOCK));
-	for (ix = NUM_VRID_TCP_REPS; ix -- > 0; ) {
-		if (repid == vrid_tcp_rep[ix]) {
-			tskid_tcp_rep[ix] = TSK_NONE;
-			break;
-			}
-		}
-	syscall(sig_sem(SEM_ALLOC_TCP_REP_LOCK));
-
-	if (call_tcp_del_rep)
-		return tcp_del_rep(repid);
-	else
-		return E_OK;
-	}
-
-/*
- *  alloc_tcp_cep -- TCP 通信端点を獲得する。
- */
-
-ER
-alloc_tcp_cep (ID *cepid, ID tskid, T_TCP_CCEP *ccep)
-{
-	int_t	ix;
-
-	*cepid = TCP_CEP_NONE;
-	syscall(wai_sem(SEM_ALLOC_TCP_CEP_LOCK));
-	for (ix = NUM_VRID_TCP_CEPS; ix -- > 0; ) {
-		if (tskid_tcp_cep[ix] == TSK_NONE) {
-			*cepid = vrid_tcp_cep[ix];
-			tskid_tcp_cep[ix] = tskid;
-			break;
-			}
-		}
-	syscall(sig_sem(SEM_ALLOC_TCP_CEP_LOCK));
-
-	if (*cepid == TCP_CEP_NONE)
-		return E_NOEXS;
-	else
-		return tcp_cre_cep(*cepid, ccep);
-	}
-
-/*
- *  free_tcp_cep -- TCP 通信端点を解放する。
- */
-
-ER
-free_tcp_cep (ID cepid)
-{
-	int_t	ix;
-
-	syscall(wai_sem(SEM_ALLOC_TCP_CEP_LOCK));
-	for (ix = NUM_VRID_TCP_CEPS; ix -- > 0; ) {
-		if (cepid == vrid_tcp_cep[ix]) {
-			tskid_tcp_cep[ix] = TSK_NONE;
-			break;
-			}
-		}
-	syscall(sig_sem(SEM_ALLOC_TCP_CEP_LOCK));
-
-	return tcp_del_cep(cepid);
-	}
-
-#endif	/* of #ifdef USE_TCP_EXTENTIONS */
-
-#ifdef USE_UDP_EXTENTIONS
-
-const ID vrid_udp_cep[] =
-{
-#if NUM_VRID_UDP_CEPS >= 1
-	UDP_RSV_CEPID1,
-#endif
-#if NUM_VRID_UDP_CEPS >= 2
-	UDP_RSV_CEPID2,
-#endif
-	};
-
-ID tskid_udp_cep[NUM_VRID_UDP_CEPS];
-
-/*
- *  alloc_udp_cep -- UDP 通信端点を獲得する。
- */
-
-ER
-alloc_udp_cep (ID *cepid, ID tskid, T_UDP_CCEP *ccep)
-{
-	int_t	ix;
-
-	*cepid = UDP_CEP_NONE;
-	syscall(wai_sem(SEM_ALLOC_UDP_CEP_LOCK));
-	for (ix = NUM_VRID_UDP_CEPS; ix -- > 0; ) {
-		if (tskid_udp_cep[ix] == TSK_NONE) {
-			*cepid = vrid_udp_cep[ix];
-			tskid_udp_cep[ix] = tskid;
-			break;
-			}
-		}
-	syscall(sig_sem(SEM_ALLOC_UDP_CEP_LOCK));
-
-	if (*cepid == UDP_CEP_NONE)
-		return E_NOEXS;
-	else
-		return UDP_CRE_CEP(*cepid, ccep);
-	}
-
-/*
- *  free_udp_cep -- UDP 通信端点を解放する。
- */
-
-ER
-free_udp_cep (ID cepid, bool_t call_udp_del_cep)
-{
-	int_t	ix;
-
-	syscall(wai_sem(SEM_ALLOC_UDP_CEP_LOCK));
-	for (ix = NUM_VRID_UDP_CEPS; ix -- > 0; ) {
-		if (cepid == vrid_udp_cep[ix]) {
-			tskid_udp_cep[ix] = TSK_NONE;
-			break;
-			}
-		}
-	syscall(sig_sem(SEM_ALLOC_UDP_CEP_LOCK));
-
-	if (call_udp_del_cep)
-		return udp_del_cep(cepid);
-	else
-		return E_OK;
-	}
-
-#endif	/* of #ifdef USE_UDP_EXTENTIONS */
+		*flags |= DNS_LUP_FLAGS_QTYPE_AAAA;
+
+	if (*line == '-') {
+		line ++;
+		if (*line == '6') {
+			line ++;
+			*flags &= ~DNS_LUP_FLAGS_PROTO_IPV4;
+			}
+		else if (*line == '4') {
+			line ++;
+			*flags &= ~DNS_LUP_FLAGS_PROTO_IPV6;
+			}
+		if (*line == 'Q' || *line == 'q') {
+			*flags &= ~DNS_LUP_FLAGS_QTYPE_A;
+			line ++;                   
+			}
+		else if (*line == 'A' || *line == 'a') {
+			*flags &= ~DNS_LUP_FLAGS_QTYPE_AAAA;
+			line ++;                   
+			}
+		while (*line && !(*line == ' ' || *line == '\t'))
+			line ++;
+		}
+
+#else	/* of #if defined(SUPPORT_INET4) */
+
+	*flags = DNS_LUP_FLAGS_PROTO_IPV6 | DNS_LUP_FLAGS_QTYPE_AAAA;
+	if (*line == '-') {
+		line ++;
+		while (*line && !(*line == ' ' || *line == '\t'))
+			line ++;
+		}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+	*flags = DNS_LUP_FLAGS_PROTO_IPV4 | DNS_LUP_FLAGS_QTYPE_A;
+	if (*line == '-') {
+		line ++;
+		while (*line && !(*line == ' ' || *line == '\t'))
+			line ++;
+		}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET6)
+
+	if (*flags | DNS_LUP_FLAGS_PROTO_IPV6) {
+		/*
+		 *  IPv6 で DNS サーバに照会することが指定されても、
+		 *  サーバの IPv6 アドレスが未定義の時は、指定を外す。
+		 */
+		dns_in6_get_addr(&in6_addr);
+		if (IN6_IS_ADDR_UNSPECIFIED(&in6_addr))
+			*flags &= ~DNS_LUP_FLAGS_PROTO_IPV6;
+		}
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+	if (*flags | DNS_LUP_FLAGS_PROTO_IPV4) {
+		/*
+		 *  IPv4 で DNS サーバに照会することが指定されても、
+		 *  サーバの IPv4 アドレスが未定義の時は、指定を外す。
+		 */
+		dns_in4_get_addr(&in4_addr);
+		if (in4_addr == IPV4_ADDRANY)
+			*flags &= ~DNS_LUP_FLAGS_PROTO_IPV4;
+		}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+	return line;
+	}
+
+#endif	/* of #ifdef USE_RESOLVER */
+
+/*
+ *  lookup_ipaddr -- ホスト名・リテラルのIPアドレスをIP アドレスに変換する。
+ */
+
+char *
+lookup_ipaddr (T_IN_ADDR *addr, char *line, char apip)
+{
+
+#ifdef USE_RESOLVER
+
+	static char hostname[DBG_LINE_SIZE + 1];
+
+	ER_UINT	error;
+	uint_t	flags = 0;
+	char	*last;
+
+	line = skip_blanks(resolv_options(&flags, line, apip));
+	if ((last = resolv_hoststr(&flags, hostname, sizeof(hostname), line)) == NULL) {
+		cons_printf(CONSOLE_PORTID, "unknown host: %s.\n", hostname);
+		return NULL;
+		}
+
+	switch (flags & DNS_LUP_FLAGS_NAME_MASK) {
+	case DNS_LUP_FLAGS_NAME_IPV4:
+	case DNS_LUP_FLAGS_NAME_IPV6:
+		line = GET_IPADDR(addr, line);		/* IP Address by Literal */
+		break;
+
+	case DNS_LUP_FLAGS_NAME_HOST:
+	case DNS_LUP_FLAGS_NAME_FQDN:
+		line = last;
+		if ((flags & (DNS_LUP_FLAGS_PROTO_IPV6 | DNS_LUP_FLAGS_PROTO_IPV4)) == 0) {
+			cons_printf(CONSOLE_PORTID, "DNS server not available.\n");
+			return NULL;
+			}
+
+		flags |= DNS_LUP_OPCODE_FORWARD;
+		if ((error = dns_host_addr(flags, hostname, addr)) != E_OK) {
+			cons_printf(CONSOLE_PORTID, "error: %s.\n", itron_strerror(error));
+			return NULL;
+			}
+		break;
+
+		}
+
+	return line;
+
+#else	/* of #ifdef USE_RESOLVER */
+
+	return GET_IPADDR(addr, skip_blanks(line));		/* IP Address by Literal */
+
+#endif	 /* of #ifdef USE_RESOLVER */
+
+	}
 
 #endif	/* of #ifdef USE_NETAPP_SUBR */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/netapp_subr.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/netapp_subr.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/netapp_subr.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/netapp_var.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/netapp_var.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/netapp_var.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -36,14 +36,111 @@
 
 /*
- *  マクロ定義
- */
-
-#if defined(SUPPORT_INET4)
-#define T_IPEP		T_IPV4EP
+ *  TOPPERS/JSP カーネル、システム時刻 (SYSTIM) の周波数
+ */
+
+#define SYSTIM_HZ		ULONG_C(1000000)	/* [us]					*/
+
+/*
+ *  IPv6/IPv4 に関する定義
+ */
+
+/*
+ *  指定されたマクロに対するサンプルアプリケーション内部のマクロの定義
+ *
+ *    SUPPORT_INET6		 .   .  ON  ON  ON  ON
+ *    SUPPORT_INET4		ON  ON   .   .  ON  ON
+ *    API_CFG_IP4MAPPED_ADDR	 .  ON   .  ON   .  ON
+ *    ----------------------    ----------------------
+ *    NETAPP_IP6_CFG             .   .  ON  ON  ON  ON
+ *    NETAPP_IP4_CFG            ON  ON   .  ON  ON  ON
+ *    
+ */
+
+#if defined(SUPPORT_INET6)
+
+#define	NETAPP_IP6_CFG
+
+#endif	/* #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4) || (defined(SUPPORT_INET6) && defined(API_CFG_IP4MAPPED_ADDR))
+#define NETAPP_IP4_CFG
 #endif
 
-#if defined(SUPPORT_INET6)
-#define T_IPEP		T_IPV6EP
+/*
+ *  IPv4 と IPv6 をコンパイル時に選択するためのマクロ
+ */
+
+#define DBG_LINE_SIZE		63
+
+#if defined(SUPPORT_INET6)
+
+#define T_IN_ADDR		T_IN6_ADDR
+#define T_IPEP			T_IPV6EP
+#define IP_ADDRANY		IPV6_ADDRANY
+#define T_TCPN_CREP		T_TCP6_CREP
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#define T_IN_ADDR		T_IN4_ADDR
+#define T_IPEP			T_IPV4EP
+#define IP_ADDRANY		IPV4_ADDRANY
+#define T_TCPN_CREP		T_TCP_CREP
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+/*
+ *  API IPプロトコルの指定
+ */
+
+#if defined(SUPPORT_INET6)
+#define DEFAULT_API_PROTO	API_PROTO_IPV6
+#else
+#define DEFAULT_API_PROTO	API_PROTO_IPV4
 #endif
+
+/*
+ *  resolv_hoststr が返す flags の値の定義
+ *
+ *    注意:
+ *
+ *      dns.h で定義されている DNS_OPCODE、
+ *      resolver.h で定義されている DNS_LUP_FLAGS と重ならない事。
+ */
+
+#define HOSTSTR_OTHER		0x0000U
+#define HOSTSTR_IPV4		DNS_LUP_FLAGS_NAME_IPV4
+#define HOSTSTR_IPV6		DNS_LUP_FLAGS_NAME_IPV6
+#define HOSTSTR_HOSTNAME	DNS_LUP_FLAGS_NAME_HOST
+#define HOSTSTR_FQDN		DNS_LUP_FLAGS_NAME_FQDN
+
+/*
+ *  定数の定義
+ */
+
+#define DBG_LINE_SIZE		63
+
+#if defined(SUPPORT_INET6)
+
+#define NUM_VRID_TCP_CEPS	NUM_VRID_TCP6_CEPS
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#define NUM_VRID_TCP_CEPS	NUM_VRID_TCP4_CEPS
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+/*
+ *  関数シミュレーションマクロ
+ */
+
+/* メッセージからの読出し */
+
+#define MSG2HOST16(p)		(msg2host16((void*)&(p)))
+#define MSG2HOST32(p)		(msg2host32((void*)&(p)))
+
+/* メッセージへの書込み */
+
+#define HOST2MSG16(p,v)		(host2msg16((void*)&(p),(v)))
+#define HOST2MSG32(p,v)		(host2msg32((void*)&(p),(v)))
 
 /*
@@ -80,4 +177,6 @@
 extern const char *in_strtfn (FN fncd);
 extern const char *itron_strerror (ER ercd);
+extern const char *dns_strtype (uint_t type);
+extern const char *dns_strclass (uint_t class);
 extern ER	net_syslog(uint_t prio, const char *format, ...) throw();
 extern ER	net_serial_ctl_por(ID portid, uint_t ioctl) throw();
@@ -85,10 +184,57 @@
 extern ER	discon_net_cons (void);
 extern void	wup_net_cons (void);
-extern ER	alloc_tcp_rep (ID *repid, ID tskid, T_TCP_CREP *crep);
-extern ER	free_tcp_rep (ID repid, bool_t call_tcp_del_rep);
-extern ER	alloc_tcp_cep (ID *cepid, ID tskid, T_TCP_CCEP *ccep);
-extern ER	free_tcp_cep (ID cepid);
-extern ER	alloc_udp_cep (ID *cepid, ID tskid, T_UDP_CCEP *ccep);
-extern ER	free_udp_cep (ID cepid, bool_t call_udp_del_cep);
+extern bool_t	tcp6_is_cepid (ID cepid);
+extern ER	alloc_tcp6_rep (ID *repid, ID tskid, T_TCP6_CREP *crep);
+extern ER	alloc_tcp6_cep (ID *cepid, ID tskid, T_TCP_CCEP *ccep);
+extern ER	alloc_udp6_cep (ID *cepid, ID tskid, T_UDP6_CCEP *ccep);
+extern ER	free_tcp6_rep (ID repid, bool_t call_tcp_del_rep);
+extern ER	free_tcp6_cep (ID cepid);
+extern ER	free_udp6_cep (ID cepid, bool_t call_udp_del_cep);
+extern bool_t	tcp4_is_cepid (ID cepid);
+extern ER	alloc_tcp4_rep (ID *repid, ID tskid, T_TCP_CREP *crep);
+extern ER	alloc_tcp4_cep (ID *cepid, ID tskid, T_TCP_CCEP *ccep);
+extern ER	alloc_udp4_cep (ID *cepid, ID tskid, T_UDP_CCEP *ccep);
+extern ER	free_tcp4_rep (ID repid, bool_t call_tcp_del_rep);
+extern ER	free_tcp4_cep (ID cepid);
+extern ER	free_udp4_cep (ID cepid, bool_t call_udp_del_cep);
+extern void	ping6 (T_IN6_ADDR *addr, uint_t tmo, uint_t len);
+extern void	ping4 (T_IN4_ADDR *addr, uint_t tmo, uint_t len);
+extern char	*get_ipv6addr (T_IN6_ADDR *addr, char *line);
+extern char	*get_ipv4addr (T_IN4_ADDR *addr, char *line);
+extern char	*resolv_options (uint_t *flags, char *line, char apip);
+extern char	*resolv_hoststr (uint_t *flags, char *hostname, uint_t name_size, char *line);
+extern char	*lookup_ipaddr (T_IN_ADDR *addr, char *line, char apip);
+extern uint_t	show_dns_domain_name (ID portid, uint8_t *hdr, uint_t offset);
+extern void	host2msg16 (void *msg, uint16_t host_data);
+extern void	host2msg32 (void *msg, uint32_t host_data);
+extern uint16_t	msg2host16 (void *msg);
+extern uint32_t	msg2host32 (void *msg);
+extern uint32_t	netapp_rand (void);
+extern void	netapp_srand (uint32_t seed);
+
+#if defined(SUPPORT_INET6)
+
+#define TCP_CRE_REP(i,r)	tcp6_cre_rep(i,r)
+#define TCP_CRE_CEP(i,c)	tcp6_cre_cep(i,c)
+#define UDP_CRE_CEP(i,c)	udp6_cre_cep(i,c)
+#define TCP_ACP_CEP(c,r,d,t)	tcp6_acp_cep(c,r,d,t)
+#define TCP_CON_CEP(c,m,d,t)	tcp6_con_cep(c,m,d,t)
+
+#define UDP_SND_DAT(c,d,b,l,t)	udp6_snd_dat(c,d,b,l,t)
+#define UDP_RCV_DAT(c,d,b,l,t)	udp6_rcv_dat(c,d,b,l,t)
+
+#define TCP_IS_CEPID(i)		tcp6_is_cepid(i)
+#define ALLOC_TCP_REP(i,t,r)	alloc_tcp6_rep(i,t,r)
+#define ALLOC_TCP_CEP(i,t,c)	alloc_tcp6_cep(i,t,c)
+#define ALLOC_UDP_CEP(i,t,c)	alloc_udp6_cep(i,t,c)
+#define FREE_TCP_REP(i,r)	free_tcp6_rep(i,r)
+#define FREE_TCP_CEP(i)		free_tcp6_cep(i)
+#define FREE_UDP_CEP(i,c)	free_udp6_cep(i,c)
+
+#define IP2STR(s,a)		ipv62str(s,a)
+#define GET_IPADDR(a,l)		get_ipv6addr(a,l)
+#define PING(a,t,l)		ping6(a,t,l)
+
+#else	/* of #if defined(SUPPORT_INET6) */
 
 #if defined(SUPPORT_INET4)
@@ -103,33 +249,18 @@
 #define UDP_RCV_DAT(c,d,b,l,t)	udp_rcv_dat(c,d,b,l,t)
 
+#define TCP_IS_CEPID(i)		tcp4_is_cepid(i)
+#define ALLOC_TCP_REP(i,t,r)	alloc_tcp4_rep(i,t,r)
+#define ALLOC_TCP_CEP(i,t,c)	alloc_tcp4_cep(i,t,c)
+#define ALLOC_UDP_CEP(i,t,c)	alloc_udp4_cep(i,t,c)
+#define FREE_TCP_REP(i,r)	free_tcp4_rep(i,r)
+#define FREE_TCP_CEP(i)		free_tcp4_cep(i)
+#define FREE_UDP_CEP(i,c)	free_udp4_cep(i,c)
+
 #define IP2STR(s,a)		ip2str(s,a)
-
 #define GET_IPADDR(a,l)		get_ipv4addr(a,l)
 #define PING(a,t,l)		ping4(a,t,l)
 
-extern void ping4 (T_IN4_ADDR *addr, uint_t tmo, uint_t len);
-extern char *get_ipv4addr (T_IN4_ADDR *addr, char *line);
-
 #endif	/* of #if defined(SUPPORT_INET4) */
 
-#if defined(SUPPORT_INET6)
-
-#define TCP_CRE_REP(i,r)	tcp6_cre_rep(i,r)
-#define TCP_CRE_CEP(i,c)	tcp6_cre_cep(i,c)
-#define UDP_CRE_CEP(i,c)	udp6_cre_cep(i,c)
-#define TCP_ACP_CEP(c,r,d,t)	tcp6_acp_cep(c,r,d,t)
-#define TCP_CON_CEP(c,m,d,t)	tcp6_con_cep(c,m,d,t)
-
-#define UDP_SND_DAT(c,d,b,l,t)	udp6_snd_dat(c,d,b,l,t)
-#define UDP_RCV_DAT(c,d,b,l,t)	udp6_rcv_dat(c,d,b,l,t)
-
-#define IP2STR(s,a)		ipv62str(s,a)
-
-#define GET_IPADDR(a,l)		get_ipv6addr(a,l)
-#define PING(a,t,l)		ping6(a,t,l)
-
-extern void ping6 (T_IN6_ADDR *addr, uint_t tmo, uint_t len);
-extern char *get_ipv6addr (T_IN6_ADDR *addr, char *line);
-
 #endif	/* of #if defined(SUPPORT_INET6) */
 
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/netappn_subr.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/netappn_subr.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/netappn_subr.c	(revision 331)
@@ -0,0 +1,219 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  ãããã¯ã¼ã¯å¿ç¨ãã­ã°ã©ã ãµãã¼ãã«ã¼ãã³
+ */
+
+#ifdef USE_TCP_EXTENTIONS
+
+/*
+ *  alloc_tcp_rep -- TCP åä»å£ãç²å¾ããã
+ */
+
+ER
+ALLOC_TCP_REP (ID *repid, ID tskid, T_TCPN_CREP *crep)
+{
+	int_t	ix;
+
+	*repid = TCP_REP_NONE;
+	syscall(wai_sem(SEM_ALLOC_TCP_REP_LOCK));
+	for (ix = NUM_VRID_TCP_REPS; ix -- > 0; ) {
+		if (TSKID_TCP_REP[ix] == TSK_NONE) {
+			*repid = VRID_TCP_REP[ix];
+			TSKID_TCP_REP[ix] = tskid;
+			break;
+			}
+		}
+	syscall(sig_sem(SEM_ALLOC_TCP_REP_LOCK));
+
+	if (*repid == TCP_REP_NONE)
+		return E_NOEXS;
+	else
+		return TCP_CRE_REP(*repid, crep);
+	}
+
+/*
+ *  free_tcp_rep -- TCP åä»å£ãè§£æ¾ããã
+ */
+
+ER
+FREE_TCP_REP (ID repid, bool_t call_tcp_del_rep)
+{
+	int_t	ix;
+
+	syscall(wai_sem(SEM_ALLOC_TCP_REP_LOCK));
+	for (ix = NUM_VRID_TCP_REPS; ix -- > 0; ) {
+		if (repid == VRID_TCP_REP[ix]) {
+			TSKID_TCP_REP[ix] = TSK_NONE;
+			break;
+			}
+		}
+	syscall(sig_sem(SEM_ALLOC_TCP_REP_LOCK));
+
+	if (call_tcp_del_rep)
+		return tcp_del_rep(repid);
+	else
+		return E_OK;
+	}
+
+/*
+ *  tcpn_is_cepid -- TCP éä¿¡ç«¯ç¹ãæå®ããããããã¯ã¼ã¯å±¤ãªã true ãè¿ãã
+ */
+
+bool_t
+TCP_IS_CEPID (ID cepid)
+{
+	int_t	ix;
+
+	for (ix = NUM_VRID_TCP_CEPS; ix -- > 0; ) {
+		if (cepid == VRID_TCP_CEP[ix])
+			return true;
+		}
+	return false;
+	}
+
+/*
+ *  alloc_tcp_cep -- TCP éä¿¡ç«¯ç¹ãç²å¾ããã
+ */
+
+ER
+ALLOC_TCP_CEP (ID *cepid, ID tskid, T_TCP_CCEP *ccep)
+{
+	int_t	ix;
+
+	*cepid = TCP_CEP_NONE;
+	syscall(wai_sem(SEM_ALLOC_TCP_CEP_LOCK));
+	for (ix = NUM_VRID_TCP_CEPS; ix -- > 0; ) {
+		if (TSKID_TCP_CEP[ix] == TSK_NONE) {
+			*cepid = VRID_TCP_CEP[ix];
+			TSKID_TCP_CEP[ix] = tskid;
+			break;
+			}
+		}
+	syscall(sig_sem(SEM_ALLOC_TCP_CEP_LOCK));
+
+	if (*cepid == TCP_CEP_NONE)
+		return E_NOEXS;
+	else
+		return tcp_cre_cep(*cepid, ccep);
+	}
+
+/*
+ *  free_tcp_cep -- TCP éä¿¡ç«¯ç¹ãè§£æ¾ããã
+ */
+
+ER
+FREE_TCP_CEP (ID cepid)
+{
+	int_t	ix;
+
+	syscall(wai_sem(SEM_ALLOC_TCP_CEP_LOCK));
+	for (ix = NUM_VRID_TCP_CEPS; ix -- > 0; ) {
+		if (cepid == VRID_TCP_CEP[ix]) {
+			TSKID_TCP_CEP[ix] = TSK_NONE;
+			break;
+			}
+		}
+	syscall(sig_sem(SEM_ALLOC_TCP_CEP_LOCK));
+
+	return tcp_del_cep(cepid);
+	}
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#ifdef USE_UDP_EXTENTIONS
+
+/*
+ *  alloc_udp_cep -- UDP éä¿¡ç«¯ç¹ãç²å¾ããã
+ */
+
+ER
+ALLOC_UDP_CEP (ID *cepid, ID tskid, T_UDPN_CCEP *ccep)
+{
+	int_t	ix;
+
+	*cepid = UDP_CEP_NONE;
+	syscall(wai_sem(SEM_ALLOC_UDP_CEP_LOCK));
+	for (ix = NUM_VRID_UDP_CEPS; ix -- > 0; ) {
+		if (TSKID_UDP_CEP[ix] == TSK_NONE) {
+			*cepid = VRID_UDP_CEP[ix];
+			TSKID_UDP_CEP[ix] = tskid;
+			break;
+			}
+		}
+	syscall(sig_sem(SEM_ALLOC_UDP_CEP_LOCK));
+
+	if (*cepid == UDP_CEP_NONE)
+		return E_NOEXS;
+	else
+		return UDP_CRE_CEP(*cepid, ccep);
+	}
+
+/*
+ *  free_udp_cep -- UDP éä¿¡ç«¯ç¹ãè§£æ¾ããã
+ */
+
+ER
+FREE_UDP_CEP (ID cepid, bool_t call_udp_del_cep)
+{
+	int_t	ix;
+
+	syscall(wai_sem(SEM_ALLOC_UDP_CEP_LOCK));
+	for (ix = NUM_VRID_UDP_CEPS; ix -- > 0; ) {
+		if (cepid == VRID_UDP_CEP[ix]) {
+			TSKID_UDP_CEP[ix] = TSK_NONE;
+			break;
+			}
+		}
+	syscall(sig_sem(SEM_ALLOC_UDP_CEP_LOCK));
+
+	if (call_udp_del_cep)
+		return UDP_DEL_CEP(cepid);
+	else
+		return E_OK;
+	}
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/ping.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/ping.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/ping.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -61,4 +61,5 @@
 #include <net/ppp_ipcp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_timer.h>
@@ -74,11 +75,16 @@
 #ifdef USE_PING
 
+#if defined(SUPPORT_INET4)
+
 /*
  *  変数
  */
 
-static uint16_t	icmp_id = 0;
+#if 0
 static uint16_t	curr_icmp_id;
 static uint16_t	curr_icmp_len;
+#endif
+
+static uint16_t	icmp_id = 0;
 static SYSTIM	icmp_start_time;
 
@@ -90,5 +96,5 @@
 icmp_reply_timeout (void *arg)
 {
-	syslog(LOG_NOTICE, "[PING] request timeout.");
+	syslog(LOG_NOTICE, "[PING4] request timeout.");
 	}
 
@@ -100,10 +106,13 @@
 icmp_echo_reply (T_NET_BUF *input, uint_t ihoff)
 {
-	SYSTIM time;
+	SYSTIM		time;
+	T_IN4_ADDR	addr;
 
 	syscall(get_tim(&time));
+	addr = ntohl(GET_IP4_HDR(input)->src);
 	untimeout(icmp_reply_timeout, NULL);
-	syslog(LOG_NOTICE, "[PING] reply, %d [ms].",
-	                   (time - icmp_start_time) * 1000 / SYSTIM_HZ);
+	syslog(LOG_NOTICE, "[PING4] reply: %5ld [ms] from: %s",
+	                   (time - icmp_start_time) * 1000 / SYSTIM_HZ,
+	                   ip2str(NULL, &addr));
 	}
 
@@ -143,6 +152,8 @@
 
 	/* 応答チェック用の変数を設定する。*/
+#if 0
 	curr_icmp_id  = icmp_id ++;
 	curr_icmp_len = len;
+#endif
 
 	NET_COUNT_MIB(icmp_stats.icmpOutMsgs, 1);
@@ -157,3 +168,5 @@
 	}
 
+#endif	/* of #if defined(SUPPORT_INET4) */
+
 #endif	/* of #ifdef USE_PING */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/ping6.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/ping6.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/ping6.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -61,4 +61,5 @@
 #include <net/ppp_ipcp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_timer.h>
@@ -67,16 +68,15 @@
 #include <netinet/in.h>
 #include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
 
-#include <netinet6/in6.h>
-#include <netinet6/in6_var.h>
 #include <netinet6/nd6.h>
 
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#include <netinet/icmp6.h>
-
-#include <net/if6_var.h>
+#include <net/if_var.h>
 
 #ifdef USE_PING
+
+#if defined(SUPPORT_INET6)
 
 /*
@@ -84,7 +84,10 @@
  */
 
-static uint16_t	send_icmp6_id = 0;
+#if 0
 static uint16_t	curr_icmp6_id;
 static uint16_t	curr_icmp6_size;
+#endif
+
+static uint16_t	send_icmp6_id = 0;
 static uint16_t	reply_count;
 static SYSTIM	icmp6_start_time;
@@ -108,13 +111,11 @@
 icmp6_echo_reply (T_NET_BUF *input, uint_t ihoff)
 {
-	T_IP6_HDR	*ip6h;
-	SYSTIM		time;
+	SYSTIM	time;
 
 	syscall(get_tim(&time));
-	ip6h  = GET_IP6_HDR(input);
-
-	syslog(LOG_NOTICE, "[PING6] reply: %5d [ms] from: %s",
+	untimeout(icmp6_reply_timeout, NULL);
+	syslog(LOG_NOTICE, "[PING6] reply: %5ld [ms] from: %s",
 	                   (time - icmp6_start_time) * 1000 / SYSTIM_HZ,
-	                   ipv62str(NULL, &ip6h->src));
+	                   ipv62str(NULL, &GET_IP6_HDR(input)->src));
 	reply_count ++;
 	}
@@ -169,12 +170,16 @@
 
 	/* 応答チェック用の変数を設定する。*/
+	reply_count = 0;
+
+#if 0
 	curr_icmp6_id   = send_icmp6_id ++;
 	curr_icmp6_size = size;
+#endif
 
-	reply_count = 0;
-
+#if 0
 	syslog(LOG_NOTICE, "[PING6] send: TMO:%d, SIZE:%d, to: %s, from %s",
 	                   tmo, size,
 	                   ipv62str(NULL, addr), ipv62str(NULL, &ia->addr));
+#endif
 
 	/* 送信後、現在の時間を記憶し、タイムアウトを設定する。*/
@@ -188,3 +193,5 @@
 	}
 
+#endif	/* of #if defined(SUPPORT_INET6) */
+
 #endif	/* of #ifdef USE_PING */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/resolver.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/resolver.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/resolver.c	(revision 331)
@@ -0,0 +1,1204 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+ *      ã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+ *        å ±åãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ãã¹ãåââIP ã¢ãã¬ã¹å¤æ
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <t_syslog.h>
+#include <syssvc/logtask.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_config.h>
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/resolver.h>
+
+#if defined(USE_RESOLVER)
+
+/*
+ *  å±æå¤æ°
+ */
+
+static uint8_t	dns_domain_name[DNS_NAME_LENGTH + 1] = RSLV_CFG_DNS_DOMAIN_NAME_STR;
+
+#if defined(SUPPORT_INET6)
+static T_IN6_ADDR in6_addr_dns      = IPV6_ADDR_DNS_INIT;
+static T_IN6_ADDR in6_addr_dns_init = IPV6_ADDR_DNS_INIT;
+#endif
+
+#if defined(SUPPORT_INET4)
+static T_IN4_ADDR in4_addr_dns = IPV4_ADDR_DNS;
+#endif
+
+static uint16_t	dns_msg_id = 0;
+
+/*
+ *  get_dns_header -- DNS ã¡ãã»ã¼ã¸ãã DNS ããããåãåºãã
+ */
+
+static ER_UINT
+get_dns_header (uint8_t *msg, uint_t length, T_RSLV_DNS_MSG *rslv)
+{
+	T_DNS_HDR	*dns_hdr;
+
+	/* DNS ããããåãåºãã*/
+	if (length < sizeof(rslv->dns_hdr))
+		return EV_RSLV_ESIZE;
+	dns_hdr = (T_DNS_HDR*)msg;
+	rslv->dns_hdr.id	= MSG2HOST16(dns_hdr->id);
+	rslv->dns_hdr.code	= MSG2HOST16(dns_hdr->code);
+	rslv->dns_hdr.qdcount	= MSG2HOST16(dns_hdr->qdcount);
+	rslv->dns_hdr.ancount	= MSG2HOST16(dns_hdr->ancount);
+	rslv->dns_hdr.nscount	= MSG2HOST16(dns_hdr->nscount);
+	rslv->dns_hdr.arcount	= MSG2HOST16(dns_hdr->arcount);
+	return sizeof(rslv->dns_hdr);
+	}
+
+/*
+ *  dns_strtype -- DNS ã® type ã®æå­åãè¿ãã
+ */
+
+static const char *
+dns_flag_qtype (uint16_t flags)
+{
+	if      (flags & DNS_LUP_FLAGS_QTYPE_AAAA)
+		return "AAAA";
+	else if (flags & DNS_LUP_FLAGS_QTYPE_A)
+		return "   A";
+	else if (flags & DNS_LUP_FLAGS_QTYPE_PTR)
+		return " PTR";
+	else
+		return "unknown type";
+	}
+
+#if defined(SUPPORT_INET6)
+
+/*
+ *  udp6_dns -- UDP/IPv6 ã«ãã DNS ãµã¼ãããã¡ãã»ã¼ã¸ãåä¿¡ããã
+ */
+
+static ER
+udp6_dns (uint16_t flags, T_IN6_ADDR *addr, uint8_t *msg, uint_t msg_size, uint_t length)
+{
+	T_IPV6EP	ep_dns;
+	ER_UINT		len = E_OK;
+	int		retry;
+
+	/* DNS ãµã¼ãã® IPv6 ã¢ãã¬ã¹ãæªå®ç¾©ã®æã¯ãã©ã¡ã¼ã¿ã¨ã©ã¼ */
+	if (IN6_IS_ADDR_UNSPECIFIED(addr) || (in6_is_addr_ipv4mapped(addr) && addr->s6_addr32[3] == IPV4_ADDRANY)) {
+		syslog(LOG_NOTICE, "[RSLV] undefined IPv6 DNS server address.");
+		return E_PAR;
+		}
+
+	memcpy(&ep_dns.ipaddr, addr, sizeof(*addr));
+	ep_dns.portno = RSLV_CFG_DNS_PORTNO;
+	for (retry = NUM_DNS_UDP_RETRY + 1; retry -- > 0; ) {
+		if ((len = udp6_snd_dat(UDP6_RESOLVER_CEPID, &ep_dns, msg, length, TMO_DNS_UDP_SND)) >= 0) {
+			if ((len = udp6_rcv_dat(UDP6_RESOLVER_CEPID, &ep_dns, msg, msg_size, TMO_DNS_UDP_RCV)) >= 0)
+				return len;
+			}
+		if (flags & DNS_LUP_FLAGS_MSG) {
+			if (len == E_TMOUT)
+				syslog(LOG_NOTICE, "[RSLV] TMOUT: %d, type: %s, server: %s.%d.",
+				       NUM_DNS_UDP_RETRY + 1 - retry,
+				       dns_flag_qtype(flags),
+				       ipv62str(NULL, &ep_dns.ipaddr), ep_dns.portno);
+			else {
+				syslog(LOG_NOTICE, "[RSLV] error:  %s, type: %s,\n       server: %s.%d.",
+				       itron_strerror(len),
+				       dns_flag_qtype(flags),
+				       ipv62str(NULL, &ep_dns.ipaddr), ep_dns.portno);
+				return len;
+				}
+			}
+		}
+	return E_TMOUT;
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+/*
+ *  udp4_dns -- UDP/IPv4 ã«ãã DNS ãµã¼ãããã¡ãã»ã¼ã¸ãåä¿¡ããã
+ */
+
+static ER
+udp4_dns (uint16_t flags, T_IN4_ADDR *addr, uint8_t *msg, uint_t msg_size, uint_t length)
+{
+	T_IPV4EP	ep_dns;
+	ER_UINT		len = E_OK;
+	int		retry;
+
+	/* DNS ãµã¼ãã® IPv4 ã¢ãã¬ã¹ãæªå®ç¾©ã®æã¯ãã©ã¡ã¼ã¿ã¨ã©ã¼ */
+	if (*addr == IPV4_ADDRANY) {
+		syslog(LOG_NOTICE, "[RSLV] undefined IPv4 DNS server address.");
+		return E_PAR;
+		}
+
+	memcpy(&ep_dns.ipaddr, addr, sizeof(*addr));
+	ep_dns.portno = RSLV_CFG_DNS_PORTNO;
+	for (retry = NUM_DNS_UDP_RETRY + 1; retry -- > 0; ) {
+		if ((len = udp_snd_dat(UDP4_RESOLVER_CEPID, &ep_dns, msg, length, TMO_DNS_UDP_SND)) >= 0) {
+			if ((len = udp_rcv_dat(UDP4_RESOLVER_CEPID, &ep_dns, msg, msg_size, TMO_DNS_UDP_RCV)) >= 0)
+				return len;
+			}
+		if (flags & DNS_LUP_FLAGS_MSG) {
+			if (len == E_TMOUT)
+				syslog(LOG_NOTICE, "[RSLV] TMOUT: %d, type: %s, server: %s.%d.",
+				       NUM_DNS_UDP_RETRY + 1 - retry,
+				       dns_flag_qtype(flags),
+				       ip2str(NULL, &ep_dns.ipaddr), ep_dns.portno);
+			else {
+				syslog(LOG_NOTICE, "[RSLV] error: %s, type: %s, server: %s.%d.",
+				       itron_strerror(len),
+				       dns_flag_qtype(flags),
+				       ip2str(NULL, &ep_dns.ipaddr), ep_dns.portno);
+				return len;
+				}
+			}
+		}
+	return E_TMOUT;
+	}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+/*
+ *  skip_label -- ã©ãã«ãèª­ã¿é£ã°ãã
+ */
+
+static char *
+skip_label (char *name)
+{
+	while (!(*name == '\0' || *name == '.'))
+		name ++;
+	return name;
+	}
+
+/*
+ *  add_name -- ã¡ãã»ã¼ã¸ã«ååãè¿½å ããã
+ */
+
+static ER_UINT
+add_name (uint8_t *msg, uint_t size, uint_t offset, char *name)
+{
+	uint_t		label_len;
+	uint8_t		*tail;
+
+	while (*name != '\0') {
+
+		/* ã¡ãã»ã¼ã¸ãµã¤ãºã«éãã¦ãããã¨ã©ã¼ */
+		if (offset + 1 > size)
+			return E_BOVR;
+
+		/* ã©ãã«ã®çµãããè¦ã¤ããã*/
+		tail = skip_label(name);
+
+		/* ã©ãã«é·ãè¨­å®ããã*/
+		label_len = tail - (uint8_t*)name;
+		if (label_len > DNS_LABEL_LENGTH) {	/* 63 ãªã¯ããããè¶
+ããã¨ã¨ã©ã¼ */
+			syslog(LOG_NOTICE, "[RSLV] label length(%d) too long > %d.",
+			                   label_len, DNS_LABEL_LENGTH);
+			return E_PAR;
+			}
+
+		*(msg + offset) = (uint8_t)label_len;
+		offset ++;
+
+		/* ã©ãã«åãè¨­å®ããã*/
+		if (offset + label_len > size) {	/* ã¡ãã»ã¼ã¸ãµã¤ãºãè¶
+ããã¨ã¨ã©ã¼ */
+			syslog(LOG_NOTICE, "[RSLV] message length(%d) too long > %d.",
+			                   offset + label_len, size);
+			return E_BOVR;
+			}
+
+		memcpy((void*)(msg + offset), (void*)name, label_len);
+		offset += label_len;
+
+		/* æ¬¡ã®ã©ãã«ã«ç§»åããã*/
+		if (*tail == '\0')
+			name = tail;
+		else
+			name = tail + 1;	/* '.' ãã¹ã­ããããã*/
+		}
+
+	return offset;
+	}
+
+/*
+ *  add_ipv6addr -- ã¡ãã»ã¼ã¸ã« IPv6 ã¢ãã¬ã¹ãè¿½å ããã
+ */
+
+static ER_UINT
+add_ipv6addr (uint8_t *msg, uint_t size, uint_t offset, char *name)
+{
+	T_IN6_ADDR	addr;
+	ER_UINT		error;
+	uint_t		len;
+	int			col;
+	char		digit[2];
+
+	len = strlen(name);
+	if (len == 0)
+		return E_PAR;
+
+	digit[1] = '\0';
+	get_ipv6addr(&addr, name);
+	for (col = sizeof(T_IN6_ADDR) * 2; -- col >= 0; ) {
+
+		/* 16é²æ° 1æ¡ã®å¤ããååã¨ãã¦è¿½å ããã*/
+		digit[0] = (addr.s6_addr8[col / 2] >> ((1 - (col % 2)) << 2)) & 0x0f;
+		if (digit[0] >= 10)
+			digit[0] += 'a' - 10;
+		else
+			digit[0] += '0';
+		if ((error = add_name(msg, size, offset, digit)) < 0)
+			return error;
+		offset = error;
+		}
+
+	/* "ip6" ãè¿½å ããã*/
+	if ((error = add_name(msg, size, offset, "ip6")) < 0)
+		return error;
+
+	/* "arpa" ãè¿½å ããã*/
+	return add_name(msg, size, error, "arpa");
+	}
+
+/*
+ *  add_ipv4addr -- ã¡ãã»ã¼ã¸ã« IPv4 ã¢ãã¬ã¹ãè¿½å ããã
+ */
+
+static ER_UINT
+add_ipv4addr (uint8_t *msg, uint_t size, uint_t offset, char *name)
+{
+	T_IN4_ADDR	addr;
+	ER_UINT		error;
+	uint_t		len, octet;
+	int			col;
+	char		*op, ostr[4];
+
+	len = strlen(name);
+	if (len == 0)
+		return E_PAR;
+
+	ostr[3] = '\0';
+	get_ipv4addr(&addr, name);
+	for (col = 0; col < sizeof(T_IN4_ADDR); col ++) {
+
+		/* 1ãªã¯ãããã®å¤ããæ´æ°å¤ãããªãã©ã«ã«å¤æããã*/
+		octet = (addr >> (col << 3)) & 0xff;
+		op = &ostr[3];
+		while (octet > 0) {
+			*(-- op) = octet % 10 + '0';
+			octet   /= 10;
+			}
+
+		/* 1ãªã¯ãããã®å¤ããååã¨ãã¦è¿½å ããã*/
+		if ((error = add_name(msg, size, offset, op)) < 0)
+			return error;
+		offset = error;
+		}
+
+	/* "in-addr" ãè¿½å ããã*/
+	if ((error = add_name(msg, size, offset, "in-addr")) < 0)
+		return error;
+
+	/* "arpa" ãè¿½å ããã*/
+	return add_name(msg, size, error, "arpa");
+	}
+
+/*
+ *  setup_dns_msg -- DNS ã¡ãã»ã¼ã¸ãä½æããã
+ */
+
+static ER
+setup_dns_msg (uint16_t flags, char *name, uint8_t *msg, uint_t msg_size)
+{
+	T_DNS_HDR	dns_hdr;
+	ER_UINT		offset;
+
+	memset((void*)&dns_hdr, 0, sizeof(dns_hdr));
+
+	dns_msg_id++;
+	HOST2MSG16(dns_hdr.id,      dns_msg_id);
+	HOST2MSG16(dns_hdr.code,    (flags & DNS_OPCODE_MASK) | DNS_RECURSION_DESIRED);
+	HOST2MSG16(dns_hdr.qdcount, 1);
+
+	memcpy((void*)msg, (void*)&dns_hdr, sizeof(dns_hdr));
+	offset = sizeof(dns_hdr);
+
+	switch (flags & DNS_LUP_FLAGS_NAME_MASK) {
+
+	case DNS_LUP_FLAGS_NAME_HOST:
+	case DNS_LUP_FLAGS_NAME_FQDN:
+
+		/* ãã¹ãåãã¾ãã¯ FQDN ã®æã®å¦çã*/
+		/* ãã¹ãåãè¿½å ããã*/
+		if ((offset = add_name(msg, msg_size, offset, name)) < 0)
+			return offset;
+
+		if (offset - sizeof(dns_hdr) > DNS_NAME_LENGTH) {		/* ååã 255 ãªã¯ããããè¶
+ããã¨ã¨ã©ã¼ */
+			syslog(LOG_NOTICE, "[RSLV] name length(%d) too long > %d.",
+			                   offset - sizeof(dns_hdr), DNS_NAME_LENGTH);
+			return E_PAR;
+			}
+
+		/* ãã¹ãåã ãã®æã¯ããã¡ã¤ã³åãè¿½å ããã*/
+		if ((flags & DNS_LUP_FLAGS_NAME_MASK) == DNS_LUP_FLAGS_NAME_HOST) {
+
+			/* ãã¡ã¤ã³åãè¿½å ããã*/
+			if ((offset = add_name(msg, msg_size, offset, dns_domain_name)) < 0)
+				return offset;
+
+			if (offset - sizeof(dns_hdr) > DNS_NAME_LENGTH) {		/* ååã 255 ãªã¯ããããè¶
+ããã¨ã¨ã©ã¼ */
+				syslog(LOG_NOTICE, "[RSLV] name length(%d) too long > %d.",
+				                   offset - sizeof(dns_hdr), DNS_NAME_LENGTH);
+				return E_PAR;
+				}
+			}
+		break;
+
+	case DNS_LUP_FLAGS_NAME_IPV4:
+		if ((offset = add_ipv4addr(msg, msg_size, offset, name)) < 0)
+			return offset;
+		break;
+
+	case DNS_LUP_FLAGS_NAME_IPV6:
+		if ((offset = add_ipv6addr(msg, msg_size, offset, name)) < 0)
+			return offset;
+		break;
+
+	default:
+		syslog(LOG_NOTICE, "[RSLV] unknown name type: %04x.", flags & DNS_LUP_FLAGS_NAME_MASK);
+		return E_PAR;
+		break;
+
+		}
+
+	/* ååã®çµäºã³ã¼ããTYPEãCLASS ãè¿½å ãã¦ãã¡ãã»ã¼ã¸é·ãè¶
+ããªããã¨ãç¢ºèªããã*/
+	if (offset + sizeof(uint16_t) * 2 + 1 > msg_size) {
+		syslog(LOG_NOTICE, "[RSLV] message length(%d) too long > %d.",
+		                   offset + sizeof(uint16_t) * 2 + 1, msg_size);
+		return E_BOVR;
+		}
+
+	/* ååã®çµäºã³ã¼ããè¨­å®ããã*/
+	*(msg + offset) = '\0';
+	offset ++;
+
+	/* DNS ã® TYPE ãè¨­å®ããã*/
+	if (flags & DNS_LUP_FLAGS_QTYPE_PTR)
+		host2msg16(msg + offset, DNS_TYPE_PTR);
+	else if (flags & DNS_LUP_FLAGS_QTYPE_AAAA)
+		host2msg16(msg + offset, DNS_TYPE_AAAA);
+	else if (flags & DNS_LUP_FLAGS_QTYPE_A)
+		host2msg16(msg + offset, DNS_TYPE_A);
+	else {
+		syslog(LOG_NOTICE, "[RSLV] unknown query type: %04x.", flags & DNS_LUP_FLAGS_QTYPE_MASK);
+		return E_PAR;
+		}
+	offset += sizeof(uint16_t);
+
+	/* DNS ã® CLASS ãè¨­å®ããã*/
+	host2msg16(msg + offset, DNS_CLASS_IN);
+
+	return offset + sizeof(uint16_t);
+	}
+
+/*
+ *  skip_dns_name -- DNS ã¡ãã»ã¼ã¸ã®ååãèª­ã¿é£ã°ãã
+ *
+ *    æ³¨æ: å§ç¸®å½¢å¼ãèæ
+®ãããä¸ä½ 2ãããã 11ãªãå§ç¸®å½¢å¼ã
+ */
+
+static ER_UINT
+skip_dns_name (uint8_t *name, uint_t offset, uint_t length)
+{
+	while (*(name + offset)) {
+		if ((*(name + offset) & 0xc0) == 0xc0) {
+			if (offset + 2 > length)
+				return EV_RSLV_ESIZE;
+			else
+				return offset + 2;
+			}
+		else if (offset + *name + 1 > length)
+			return EV_RSLV_ESIZE;
+		else
+			offset += *name + 1;
+		}
+	return offset + 1;
+	}
+
+/*
+ *  skip_dns_qd -- DNS Question section ãèª­ã¿é£ã°ãã
+ */
+
+static ER_UINT
+skip_dns_qd (uint8_t *msg, uint_t offset, uint_t length, uint_t count)
+{
+	ER_UINT	next;
+
+	while (count != 0) {
+		/* name ãèª­ã¿é£ã°ãã*/
+		if ((next = skip_dns_name(msg, offset, length)) < 0)
+			return next;
+		offset = next;
+
+		/* typeãclass ãèª­ã¿é£ã°ãã*/
+		if ((offset + sizeof(uint16_t) + sizeof(uint16_t)) > length)
+			return EV_RSLV_ESIZE;
+		offset += sizeof(uint16_t) + sizeof(uint16_t);
+
+		count --;
+		}
+
+	return offset;
+	}
+
+/*
+ *  skip_dns_rr -- DNS RR ãèª­ã¿é£ã°ãã
+ */
+
+static ER_UINT
+skip_dns_rr (uint8_t *msg, uint_t offset, uint_t length, uint_t count)
+{
+	ER_UINT		next;
+	uint16_t	len = 0;
+
+	while (count != 0) {
+		/* name ãèª­ã¿é£ã°ãã*/
+		if ((next = skip_dns_name(msg, offset, length)) < 0)
+			return next;
+		offset = next;
+
+		/* typeãclassãTTL ãèª­ã¿é£ã°ãã*/
+		if (offset + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t) > length)
+			return EV_RSLV_ESIZE;
+		offset += sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t);
+
+		/* RD length ã¨ RDATA ãèª­ã¿é£ã°ãã*/
+		if (offset + sizeof(uint16_t) > length)
+			return EV_RSLV_ESIZE;
+		len = msg2host16(msg + offset);
+
+		if (offset + sizeof(uint16_t) + len > length)
+			return EV_RSLV_ESIZE;
+		offset += sizeof(uint16_t) + len;
+
+		count --;
+		}
+
+	return offset;
+	}
+
+/*
+ *  dns_analyze_qd -- DNS ã¡ãã»ã¼ã¸ã® question section ãè§£æããã
+ */
+
+ER_UINT
+dns_analyze_qd (T_RSLV_QD *qd, uint_t offset, uint8_t *msg, uint_t length)
+{
+	ER_UINT		error;
+	T_DNS_QD	*dns_qd;
+
+	if ((error = skip_dns_name(msg, offset, length)) < 0)
+		return error;
+	offset = error;
+
+	/* DNS ã¡ãã»ã¼ã¸å
+ã®å½¢å¼ã®ãµã¤ãºã§ãã§ãã¯ããã*/
+	if (offset + T_DNS_QD_SIZE > length)
+		return EV_RSLV_ESIZE;
+
+	/*
+	 *  DNS ã¡ãã»ã¼ã¸å
+ã® SOA RDATA ããã¤ããªã¼ãã¼ãèª¿æ´ãã¦
+	 *  å
+é¨æ§é ä½ã«ã³ãã¼ããã
+	 */
+	dns_qd = (T_DNS_QD*)(msg + offset);
+	qd->type  = MSG2HOST16(dns_qd->type);
+	qd->class = MSG2HOST16(dns_qd->class);
+
+	return offset + T_DNS_QD_SIZE;
+	}
+
+/*
+ *  dns_analyze_soa -- DNS ã¡ãã»ã¼ã¸ã® SOA RDATA ãè§£æããã
+ */
+
+ER_UINT
+dns_analyze_soa (T_RSLV_SOA *soa, uint_t offset, uint8_t *msg, uint_t length)
+{
+	ER_UINT		error;
+	T_DNS_SOA	*dns_soa;
+
+	/* MNAME ãã¹ã­ããããã*/
+	if ((error = skip_dns_name(msg, offset, length)) < 0)
+		return error;
+	offset = error;
+
+	/* RNAME ãã¹ã­ããããã*/
+	if ((error = skip_dns_name(msg, offset, length)) < 0)
+		return error;
+	offset = error;
+
+	/* DNS ã¡ãã»ã¼ã¸å
+ã®å½¢å¼ã®ãµã¤ãºã§ãã§ãã¯ããã*/
+	if (offset + T_DNS_SOA_SIZE > length)
+		return EV_RSLV_ESIZE;
+
+	/*
+	 *  DNS ã¡ãã»ã¼ã¸å
+ã® SOA RDATA ããã¤ããªã¼ãã¼ãèª¿æ´ãã¦
+	 *  å
+é¨æ§é ä½ã«ã³ãã¼ããã
+	 */
+	dns_soa = (T_DNS_SOA*)(msg + offset);
+	soa->serial  = MSG2HOST32(dns_soa->serial);
+	soa->refresh = MSG2HOST32(dns_soa->refresh);
+	soa->retry   = MSG2HOST32(dns_soa->retry);
+	soa->expire  = MSG2HOST32(dns_soa->expire);
+	soa->minimum = MSG2HOST32(dns_soa->minimum);
+
+	return offset + T_DNS_SOA_SIZE;
+	}
+
+/*
+ *  dns_analyze_rr -- DNS ã¡ãã»ã¼ã¸ã® AN/NS/AR section ãè§£æããã
+ */
+
+ER_UINT
+dns_analyze_rr (T_RSLV_RR *rr, uint_t offset, uint8_t *msg, uint_t length)
+{
+	ER_UINT		error;
+	T_DNS_RR	*dns_rr;
+
+	if ((error = skip_dns_name(msg, offset, length)) < 0)
+		return error;
+	offset = error;
+
+	/* DNS ã¡ãã»ã¼ã¸å
+ã®å½¢å¼ã®ãµã¤ãºã§ãã§ãã¯ããã*/
+	if (offset + T_DNS_RR_SIZE > length)
+		return EV_RSLV_ESIZE;
+
+	/*
+	 *  DNS ã¡ãã»ã¼ã¸å
+ã® SOA RDATA ããã¤ããªã¼ãã¼ãèª¿æ´ãã¦
+	 *  å
+é¨æ§é ä½ã«ã³ãã¼ããã
+	 */
+	dns_rr = (T_DNS_RR*)(msg + offset);
+	rr->type	= MSG2HOST16(dns_rr->type);
+	rr->class	= MSG2HOST16(dns_rr->class);
+	rr->ttl		= MSG2HOST32(dns_rr->ttl);
+	rr->rdlength	= MSG2HOST16(dns_rr->rdlength);
+	rr->rdata_offset= offset + sizeof(rr->type) + sizeof(rr->class)
+	                         + sizeof(rr->ttl)  + sizeof(rr->rdlength);
+
+	return offset + T_DNS_RR_SIZE + rr->rdlength;
+	}
+
+/*
+ *  analyze_dns_msg -- DNS ã¡ãã»ã¼ã¸ãè§£æããã
+ */
+
+static ER_UINT
+analyze_dns_msg (uint8_t *msg, uint_t length, T_RSLV_DNS_MSG *rslv)
+{
+	ER_UINT	offset;
+
+	/* DNS ããããåãåºãã*/
+	if ((offset = get_dns_header(msg, length, rslv)) < 0)
+		return offset;
+
+	/* question section ãèª­ã¿é£ã°ãã*/
+	rslv->qd_offset = offset;
+	if ((offset = skip_dns_qd(msg, offset, length, rslv->dns_hdr.qdcount)) < 0)
+		return offset;
+
+	/* answer section ãèª­ã¿é£ã°ãã*/
+	rslv->an_offset = offset;
+	if ((offset = skip_dns_rr(msg, offset, length, rslv->dns_hdr.ancount)) < 0)
+		return offset;
+
+	/* authority records section ãèª­ã¿é£ã°ãã*/
+	rslv->ns_offset = offset;
+	if ((offset = skip_dns_rr(msg, offset, length, rslv->dns_hdr.nscount)) < 0)
+		return offset;
+
+	/* additional records  section ãèª­ã¿é£ã°ãã*/
+	rslv->ar_offset = offset;
+	if ((offset = skip_dns_rr(msg, offset, length, rslv->dns_hdr.arcount)) < 0)
+		return offset;
+
+	return E_OK;
+	}
+
+/*
+ *  dns_lookup_host_sub -- DNS ã«ãããã¹ãã®æ
+å ±ãåå¾ããï¼è£å©é¢æ°ï¼ã
+ */
+
+static ER_UINT
+dns_lookup_host_sub (uint16_t flags, char *hostname, uint8_t *msg, 
+                     uint_t msg_size, T_RSLV_DNS_MSG *rslv)
+{
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+	uint16_t	proto;
+#endif
+	ER_UINT		length;
+	ER		error;
+
+	if ((length = setup_dns_msg(flags, hostname, msg, msg_size)) < 0)
+		return length;
+
+#if defined(SUPPORT_INET6)
+
+#if defined(SUPPORT_INET4)
+
+	if (flags & DNS_LUP_FLAGS_PROTO_IPV6) {
+		proto = DNS_LUP_FLAGS_PROTO_IPV6;
+		if ((length = udp6_dns(flags, &in6_addr_dns, msg, msg_size, length)) < 0)
+			return length;
+		}
+	else if (flags & DNS_LUP_FLAGS_PROTO_IPV4) {
+		proto = DNS_LUP_FLAGS_PROTO_IPV4;
+		if ((length = udp4_dns(flags, &in4_addr_dns, msg, msg_size, length)) < 0)
+			return length;
+		}
+	else {
+		syslog(LOG_NOTICE, "[RSLV] unknown lookup protocol: %04x.", flags & DNS_LUP_FLAGS_PROTO_MASK);
+		return E_PAR;
+		}
+
+#else	/* of #if defined(SUPPORT_INET4) */
+
+	if (flags & DNS_LUP_FLAGS_PROTO_IPV6) {
+		if ((length = udp6_dns(flags, &in6_addr_dns, msg, msg_size, length)) < 0)
+			return length;
+		}
+	else {
+		syslog(LOG_NOTICE, "[RSLV] unknown lookup protocol: %04x.", flags & DNS_LUP_FLAGS_PROTO_MASK);
+		return E_PAR;
+		}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+	if (flags & DNS_LUP_FLAGS_PROTO_IPV4) {
+		if ((length = udp4_dns(flags, &in4_addr_dns, msg, msg_size, length)) < 0)
+			return length;
+		}
+	else {
+		syslog(LOG_NOTICE, "[RSLV] unknown lookup protocol: %04x.", flags & DNS_LUP_FLAGS_PROTO_MASK);
+		return E_PAR;
+		}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+	if ((error = analyze_dns_msg(msg, length, rslv)) != E_OK)
+		return error;
+	else {
+		if ((rslv->dns_hdr.ancount > 0) && (flags & DNS_LUP_FLAGS_MSG)) {
+
+#if defined(SUPPORT_INET6)
+
+#if defined(SUPPORT_INET4)
+
+			if (proto & DNS_LUP_FLAGS_PROTO_IPV6) {
+				syslog(LOG_NOTICE, "[RSLV] reslv:    type: %s, server: %s.%d.",
+				       dns_flag_qtype(flags),
+				       ipv62str(NULL, &in6_addr_dns),
+				       RSLV_CFG_DNS_PORTNO);
+				}
+			else {
+				syslog(LOG_NOTICE, "[RSLV] reslv:    type: %s, server: %s.%d.",
+				       dns_flag_qtype(flags),
+				       ip2str(NULL, &in4_addr_dns),
+				       RSLV_CFG_DNS_PORTNO);
+				}
+
+#else	/* of #if defined(SUPPORT_INET4) */
+
+			syslog(LOG_NOTICE, "[RSLV] reslv:    type: %s, server: %s.%d.",
+			       dns_flag_qtype(flags),
+			       ipv62str(NULL, &in6_addr_dns),
+			       RSLV_CFG_DNS_PORTNO);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+			syslog(LOG_NOTICE, "[RSLV] reslv:    type: %s, server: %s.%d.",
+			       dns_flag_qtype(flags),
+			       ip2str(NULL, &in4_addr_dns),
+			       RSLV_CFG_DNS_PORTNO);
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+			}
+		return length;
+		}
+	}
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+/*
+ *  udp64_dns -- DNS/IPv6ãDNS/IPv4 ã«ãã DNS ãµã¼ãããã¡ãã»ã¼ã¸ãåä¿¡ããã
+ */
+
+static ER_UINT
+udp64_dns (uint16_t flags, char *hostname, uint8_t *msg, 
+           uint_t msg_size, T_RSLV_DNS_MSG *rslv)
+{
+	ER_UINT		length;
+	ER		error;
+	uint16_t	proto;
+
+	/* DNS ã¡ãã»ã¼ã¸ãä½æããã*/
+	if ((length = setup_dns_msg(flags, hostname, msg, msg_size)) < 0)
+		return length;
+
+	/* UDP/IPv6 ã® DNS ãµã¼ãã«ç
+§ä¼ããã*/
+	proto = DNS_LUP_FLAGS_PROTO_IPV6;
+	if ((length = udp6_dns(flags, &in6_addr_dns, msg, msg_size, length)) < 0) {
+		/*  UDP/IPv6 ã® DNS ãµã¼ãã¸ã®ç
+§ä¼ãã¨ã©ã¼ã«ãªã£ãæã¯ãUDP/IPv4 ã® DNS ãµã¼ãã«ç
+§ä¼ããã*/
+		if ((length = setup_dns_msg(flags, hostname, msg, msg_size)) < 0)
+			return length;
+
+		/* UDP/IPv4 ã® DNS ãµã¼ãã«ç
+§ä¼ããã*/
+		proto = DNS_LUP_FLAGS_PROTO_IPV4;
+		if ((length = udp4_dns(flags, &in4_addr_dns, msg, msg_size, length)) < 0)
+			return length;
+		}
+
+	/* DNS ã¡ãã»ã¼ã¸ãè§£æããã*/
+	if ((error = analyze_dns_msg(msg, length, rslv)) != E_OK)
+		return error;
+	else {
+		if ((rslv->dns_hdr.ancount > 0) && (flags & DNS_LUP_FLAGS_MSG)) {
+			if (proto & DNS_LUP_FLAGS_PROTO_IPV6) {
+				syslog(LOG_NOTICE, "[RSLV] reslv:    type: %s, server: %s.%d.",
+				       dns_flag_qtype(flags),
+				       ipv62str(NULL, &in6_addr_dns),
+				       RSLV_CFG_DNS_PORTNO);
+				}
+			else {
+				syslog(LOG_NOTICE, "[RSLV] reslv:    type: %s, server: %s.%d.",
+				       dns_flag_qtype(flags),
+				       ip2str(NULL, &in4_addr_dns),
+				       RSLV_CFG_DNS_PORTNO);
+				}
+			}
+		return length;
+		}
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+/*
+ *  dns_lookup_host -- DNS ã«ãããã¹ãã®æ
+å ±ãåå¾ããã
+ */
+
+ER_UINT
+dns_lookup_host (uint16_t flags, char *hostname, uint8_t *msg, 
+              uint_t msg_size, T_RSLV_DNS_MSG *rslv)
+{
+	ER	error;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+	if ((flags & DNS_LUP_FLAGS_PROTO_MASK) == (DNS_LUP_FLAGS_PROTO_IPV6 | DNS_LUP_FLAGS_PROTO_IPV4)) {
+
+		/*
+		 *  IPv6/IPv4 ã®ä¸¡æ¹ãæå®ãããæã®å¦ç
+		 *  ã¾ã type == AAAA ã§ DNS ãµã¼ãã«ç
+§ä¼ããã
+		 */
+		if (flags & DNS_LUP_FLAGS_QTYPE_PTR) {
+			if ((error = udp64_dns(flags, hostname, msg, msg_size, rslv)) < 0)
+				return error;
+			}
+		else if (flags & DNS_LUP_FLAGS_QTYPE_AAAA) {
+			if ((error = udp64_dns(flags & ~DNS_LUP_FLAGS_QTYPE_A, hostname, msg, msg_size, rslv)) < 0)
+				return error;
+			}
+		else {
+			HOST2MSG16(rslv->dns_hdr.ancount, 0);
+			error = E_OK;
+			}
+
+		if (rslv->dns_hdr.ancount == 0) {
+
+			/*
+			 *  type == AAAA ã§ã¢ãã¬ã¹è§£æ±ºãã§ããªãã£ãæã®å¦ç
+			 *  type == A ã§ DNS ãµã¼ãã«ç
+§ä¼ããã
+			 */
+			if (flags & DNS_LUP_FLAGS_QTYPE_A)
+				return udp64_dns(flags & ~DNS_LUP_FLAGS_QTYPE_AAAA, hostname, msg, msg_size, rslv);
+			else {
+				syslog(LOG_NOTICE, "[RSLV] unknown query type: %04x.", flags & DNS_LUP_FLAGS_QTYPE_MASK);
+				return E_PAR;
+				}
+			}
+		else
+			return error;
+		}
+
+	if ((flags & DNS_LUP_FLAGS_QTYPE_MASK) == (DNS_LUP_FLAGS_QTYPE_AAAA | DNS_LUP_FLAGS_QTYPE_A)) {
+
+		/*
+		 *  type == AAAA ã¨ A ã®ä¸¡æ¹ãæå®ãããæã®å¦ç
+		 *  ã¾ã type == AAAA ã§ DNS ãµã¼ãã«ç
+§ä¼ããã
+		 */
+		if ((error = dns_lookup_host_sub(flags & ~DNS_LUP_FLAGS_QTYPE_A, hostname, msg, msg_size, rslv)) < 0)
+			return error;
+
+		if (rslv->dns_hdr.ancount == 0) {
+
+			/*
+			 *  type == AAAA ã§ã¢ãã¬ã¹è§£æ±ºãã§ããªãã£ãæã®å¦ç
+			 *  type == A ã§ DNS ãµã¼ãã«ç
+§ä¼ããã
+			 */
+			return dns_lookup_host_sub(flags & ~DNS_LUP_FLAGS_QTYPE_AAAA, hostname, msg, msg_size, rslv);
+			}
+#if 0
+		else {
+			syslog(LOG_NOTICE, "[RSLV] unknown query type: %04x.", flags & DNS_LUP_FLAGS_QTYPE_MASK);
+			return E_PAR;
+			}
+#endif
+		}
+
+	else {
+		/* IPv6/IPv4 ã®ã©ã¡ããä¸æ¹ãæå®ãããæã®å¦ç */
+		error = dns_lookup_host_sub(flags, hostname, msg, msg_size, rslv);
+		}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	error = dns_lookup_host_sub(flags, hostname, msg, msg_size, rslv);
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	return error;
+	}
+
+#if defined(SUPPORT_INET6)
+
+/*
+ *  dns_in6_set_dname -- DNS ã® ãã¡ã¤ã³åãè¨­å®ããï¼DHCPv6ç¨ï¼ã
+ *
+ *    æ³¨æ: new ã« NULL ãæå®ããã¨ãåæå¤ã«æ»ãã
+ */
+
+const uint8_t *
+dns_in6_set_dname (const uint8_t *new, uint_t len)
+{
+	uint8_t	*dst;
+	int	label_len, name_len = DNS_NAME_LENGTH;
+
+	if (new == NULL)
+		strcpy(dns_domain_name, RSLV_CFG_DNS_DOMAIN_NAME_STR);
+	else {
+		dst = dns_domain_name;
+		while ((*new != 0) && (name_len > 0) && (len > 0)) {
+			label_len = *new ++;
+			len --;
+			while ((name_len > 0) && (len > 0) && (label_len > 0)) {
+				*dst ++ = *new ++;
+				name_len  --;
+				len       --;
+				label_len --;
+				}
+			if ((*new != 0) && (name_len > 0)) {
+				*dst ++ = '.';
+				name_len --;
+				}
+			}
+		*dst = '\0';
+		}
+	return dns_domain_name;
+	}
+
+/*
+ *  dns_in6_get_dname -- DNS ã® ãã¡ã¤ã³åãå¾ãã
+ */
+
+const uint8_t *
+dns_in6_get_dname (void)
+{
+	return dns_domain_name;
+	}
+
+/*
+ *  dns_in6_set_addr -- DNS ãµã¼ãã® IPv6 ã¢ãã¬ã¹ãè¨­å®ããï¼DHCPv6ç¨ï¼ã
+ *
+ *    æ³¨æ: new ã« NULL ãæå®ããã¨ãåæå¤ã«æ»ãã
+ */
+
+T_IN6_ADDR *
+dns_in6_set_addr (T_IN6_ADDR *new)
+{
+	if (new == NULL)
+		in6_addr_dns = in6_addr_dns_init;
+	else
+		in6_addr_dns = *new;
+	return &in6_addr_dns;
+	}
+
+/*
+ *  dns_in6_get_addr -- DNS ãµã¼ãã® IPv6 ã¢ãã¬ã¹ãå¾ãã
+ */
+
+T_IN6_ADDR *
+dns_in6_get_addr (T_IN6_ADDR *dst)
+{
+	if (dst == NULL)
+		return NULL;
+	else {
+		*dst = in6_addr_dns;
+		return dst;
+		}
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+/*
+ *  dns_in4_set_dname -- DNS ã® ãã¡ã¤ã³åãè¨­å®ããï¼DHCPv4ç¨ï¼ã
+ *
+ *    æ³¨æ: new ã« NULL ãæå®ããã¨ãåæå¤ã«æ»ãã
+ */
+
+const uint8_t *
+dns_in4_set_dname (const uint8_t *new, uint_t len)
+{
+	uint8_t	*dst;
+	int	name_len = DNS_NAME_LENGTH;
+
+	if (new == NULL)
+		strcpy(dns_domain_name, RSLV_CFG_DNS_DOMAIN_NAME_STR);
+	else {
+		dst = dns_domain_name;
+		while ((name_len -- > 0) && (len -- > 0) && *new)
+			*dst ++ = *new ++;
+		*dst = '\0';
+		}
+	return dns_domain_name;
+	}
+
+/*
+ *  dns_in4_get_dname -- DNS ã® ãã¡ã¤ã³åãå¾ãã
+ */
+
+const uint8_t *
+dns_in4_get_dname (void)
+{
+	return dns_domain_name;
+	}
+
+/*
+ *  dns_in4_set_addr -- DNS ãµã¼ãã® IPv4 ã¢ãã¬ã¹ãè¨­å®ããï¼DHCPv4ç¨ï¼ã
+ *
+ *    æ³¨æ: new ã« NULL ãæå®ããã¨ãåæå¤ã«æ»ãã
+ */
+
+T_IN4_ADDR *
+dns_in4_set_addr (T_IN4_ADDR *new)
+{
+	if (new == NULL)
+		in4_addr_dns = IPV4_ADDR_DNS;
+	else
+		in4_addr_dns = *new;
+	return &in4_addr_dns;
+	}
+
+/*
+ *  dns_in4_get_addr -- DNS ãµã¼ãã® IPv4 ã¢ãã¬ã¹ãå¾ãã
+ */
+
+T_IN4_ADDR *
+dns_in4_get_addr (T_IN4_ADDR *dst)
+{
+	if (dst == NULL)
+		return NULL;
+	else {
+		*dst = in4_addr_dns;
+		return dst;
+		}
+	}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+/*
+ *  dns_host_addr -- ãã¹ãåã IP ã¢ãã¬ã¹ã«å¤æããã
+ */
+
+ER
+dns_host_addr (uint16_t flags, char *hostname, T_IN_ADDR *addr)
+{
+	T_RSLV_DNS_MSG	rslv;
+	T_RSLV_RR	rr;
+	ER_UINT		length, offset;
+	ER		error = E_OK;
+	int		scount;
+	uint8_t 	*msg;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+	T_IN4_ADDR	addr4;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	if ((error = tget_mpf(MPF_RSLV_SRBUF, (void*)&msg, TMO_FEVR)) != E_OK)
+		return error;
+
+	if ((length = dns_lookup_host(flags, hostname, msg, DNS_UDP_MSG_LENGTH, &rslv)) < 0) {
+		error = length;
+		goto err_ret;
+		}
+
+	offset = rslv.an_offset;
+	for (scount = 1; scount <= rslv.dns_hdr.ancount; scount ++) {
+		if ((offset = dns_analyze_rr(&rr, offset, msg, length)) < 0) {
+			error = offset;
+			goto err_ret;
+			}
+
+#if defined(SUPPORT_INET6)
+
+		if (rr.type == DNS_TYPE_AAAA && rr.class == DNS_CLASS_IN &&  rr.rdlength == sizeof(*addr)) {
+			memcpy((void*)addr, (void*)(msg + rr.rdata_offset), sizeof(*addr));
+			break;
+			}
+
+#if defined(SUPPORT_INET4)
+
+		if (rr.type == DNS_TYPE_A && rr.class == DNS_CLASS_IN && rr.rdlength == sizeof(addr4)) {
+			addr4 = msg2host32(msg + rr.rdata_offset);
+			in6_make_ipv4mapped(addr, addr4);
+			break;
+			}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+		if (rr.type == DNS_TYPE_A && rr.class == DNS_CLASS_IN && rr.rdlength == sizeof(*addr)) {
+			*addr = msg2host32((msg + rr.rdata_offset));
+			break;
+			}
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+		}
+	if (scount > rslv.dns_hdr.ancount)
+		error = EV_RSLV_UNEXPCT;
+
+err_ret:
+	rel_mpf(MPF_RSLV_SRBUF, (void*)msg);
+	return error;
+	}
+
+#endif	/* of #if defined(USE_RESOLVER) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/resolver.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/resolver.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/resolver.h	(revision 331)
@@ -0,0 +1,332 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+ *      ã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+ *        å ±åãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ãã¹ãåââIP ã¢ãã¬ã¹å¤æ
+ */
+
+#ifndef RESOLVER_H
+#define RESOLVER_H
+
+#include <netapp/dns.h>
+
+/*
+ *  ã³ã³ãã¤ã«æã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ã®æå®
+ */
+
+/* ãã¼ãçªå· */
+
+#define RSLV_CFG_DNS_PORTNO	53
+
+/*
+ *  ã¿ã¤ã ã¢ã¦ãå¤
+ */
+
+#define TMO_DNS_UDP_SND		ULONG_C(1*1000)	/* [ms]ãDNS ãµã¼ãã¸ã®   UDP éä¿¡ã¿ã¤ã ã¢ã¦ã	*/
+#define TMO_DNS_UDP_RCV		ULONG_C(5*1000)	/* [ms]ãDNS ãµã¼ãããã® UDP åä¿¡ã¿ã¤ã ã¢ã¦ã	*/
+#define NUM_DNS_UDP_RETRY	1		/* ãªãã©ã¤åæ°					*/
+
+/*
+ *  ãã¡ã¤ã³å
+ */
+
+
+#if !defined(RSLV_CFG_DNS_DOMAIN_NAME_STR)
+#define RSLV_CFG_DNS_DOMAIN_NAME_STR	""
+#endif
+
+/*
+ *  DNS ãµã¼ãã¼ã® IPã¢ãã¬ã¹
+ */
+
+#if !defined(IPV6_ADDR_DNS_INIT)
+#define IPV6_ADDR_DNS_INIT	IPV6_ADDR_UNSPECIFIED_INIT
+#endif
+
+#if !defined(IPV4_ADDR_DNS)
+#define	IPV4_ADDR_DNS		IPV4_ADDRANY
+#endif
+
+/*
+ *  éåä¿¡ãããã¡æ°
+ */
+
+#define NUM_MPF_RSLV_SRBUF	1
+
+/*
+ *  ãã­ã°ã©ã ã§ä½¿ç¨ããæ
+å ±ã®å®ç¾©
+ */
+
+/*
+ *  ãã­ã°ã©ã ã§ä½¿ç¨ãã DNS ããã
+ *
+ *    æ³¨æ: ã¡ã³ãã¯ãã¹ããã¤ããªã¼ãã¼
+ *
+ *    0                    7  8                   15
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                      ID                       |
+ *  +--+-----------+--+--+--+--+--------+-----------+
+ *  |QR|   Opcode  |AA|TC|RD|RA|    Z   |   RCODE   |
+ *  +--+--------+--+--+--+--+--+--------+-----------+
+ *  |                    QDCOUNT                    |
+ *  +-----------------------------------------------+
+ *  |                    ANCOUNT                    |
+ *  +-----------------------------------------------+
+ *  |                    NSCOUNT                    |
+ *  +-----------------------------------------------+
+ *  |                    ARCOUNT                    |
+ *  +-----------------------------------------------+
+ */
+
+typedef struct rslv_dns_hdr {
+	uint16_t	id;		/* ID */
+	uint16_t	code;	/* QR:		1
+				   Opcode:	4
+				   AA:		1
+				   TC:		1
+				   RD:		1
+				   RA:		1
+				   Z:		3
+				   RCODE:	4
+				   */
+	uint16_t	qdcount;	/* question   section */
+	uint16_t	ancount;	/* answer     section */
+	uint16_t	nscount;	/* authority  section */
+	uint16_t	arcount;	/* additional section */
+	} __attribute__((packed))T_RSLV_DNS_HDR;
+
+/*
+ *  DNS message data
+ *
+ *    æ³¨æ: ã¡ã³ãã¯ãã¹ããã¤ããªã¼ãã¼
+ */
+
+typedef struct rslv_dns_msg {
+	T_RSLV_DNS_HDR	dns_hdr;	/* DNS heder                            */
+	uint_t		qd_offset;	/* offset of question           section */
+	uint_t		an_offset;	/* offset of answer             section */
+	uint_t		ns_offset;	/* offset of authority  records section */
+	uint_t		ar_offset;	/* offset of additional records section */
+	} __attribute__((packed))T_RSLV_DNS_MSG;
+
+/*
+ *  RR (Resouce Record) å½¢å¼
+ *
+ *    0                    7  8                   15
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                       .                       |
+ *  +-----------------      .      -----------------+
+ *  |                      NAME                     |
+ *  +-----------------      .      -----------------+
+ *  |                       .                       |
+ *  +-----------------------------------------------+
+ *  |                      TYPE                     |
+ *  +-----------------------------------------------+
+ *  |                      CLASS                    |
+ *  +-----------------------------------------------+
+ *  |                       TTL                     |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *  |                    RDLENGTH                   |
+ *  +-----------------------------------------------+
+ *  |                       .                       |
+ *  +-----------------      .      -----------------+
+ *  |                     RDATA                     |
+ *  +-----------------      .      -----------------+
+ *  |                       .                       |
+ *  +-----------------------------------------------+
+ *
+ *    æ³¨æ: offset ã®åç¹ã¯ DNS message ã®å
+é ­
+ *          ã¡ã³ãã¯ãã¹ããã¤ããªã¼ãã¼
+ */
+
+typedef struct rslv_rr {
+	uint16_t	type;		/* TYPE			*/
+	uint16_t	class;		/* CLASS		*/
+	uint32_t	ttl;		/* TTL			*/
+	uint16_t	rdlength;	/* RDATA length		*/
+	uint_t		rdata_offset;	/* offset of RDATA	*/
+	} __attribute__((packed))T_RSLV_RR;
+
+/*
+ *  Question section å½¢å¼
+ *
+ *    0                    7  8                   15
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                       .                       |
+ *  +-----------------      .      -----------------+
+ *  |                     QNAME                     |
+ *  +-----------------      .      -----------------+
+ *  |                       .                       |
+ *  +-----------------------------------------------+
+ *  |                     QTYPE                     |
+ *  +-----------------------------------------------+
+ *  |                     QCLASS                    |
+ *  +-----------------------------------------------+
+ *
+ *    æ³¨æ: ã¡ã³ãã¯ãã¹ããã¤ããªã¼ãã¼
+ */
+
+typedef struct rslv_qd {
+	uint16_t	type;		/* TYPE			*/
+	uint16_t	class;		/* CLASS		*/
+	} __attribute__((packed))T_RSLV_QD;
+
+/*
+ *  SOA RDATA å½¢å¼
+ *
+ *    0                    7  8                   15
+ *  +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ *  |                       .                       |
+ *  +-----------------      .      -----------------+
+ *  |                     MNAME                     |
+ *  +-----------------      .      -----------------+
+ *  |                       .                       |
+ *  +-----------------------------------------------+
+ *  |                       .                       |
+ *  +-----------------      .      -----------------+
+ *  |                     RNAME                     |
+ *  +-----------------      .      -----------------+
+ *  |                       .                       |
+ *  +-----------------------------------------------+
+ *  |                    SERIAL                     |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *  |                    REFRESH                    |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *  |                     RETRY                     |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *  |                    EXPIRE                     |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *  |                    MINIMUM                    |
+ *  |                                               |
+ *  +-----------------------------------------------+
+ *
+ *    æ³¨æ: offset ã®åç¹ã¯ DNS message ã®å
+é ­
+ *          ã¡ã³ãã¯ãã¹ããã¤ããªã¼ãã¼
+ */
+
+typedef struct rslv_soa {
+	uint32_t	serial;		/* SERIAL		*/
+	uint32_t	refresh;	/* REFRESH		*/
+	uint32_t	retry;		/* RETRY		*/
+	uint32_t	expire;		/* EXPIRE		*/
+	uint32_t	minimum;	/* MINIMUM		*/
+	} __attribute__((packed))T_RSLV_SOA;
+
+/*
+ *  dns_lookup_host ã® flags ã®å®ç¾©
+ *
+ *    æ³¨æ:
+ *      dns.h ã§å®ç¾©ããã¦ãã DNS_OPCODE ã¨éãªããªããã¨ã
+ *      #define DNS_OPCODE_MASK		0x7800U
+ */
+
+#define DNS_LUP_FLAGS_NAME_IPV4		0x0004U
+#define DNS_LUP_FLAGS_NAME_IPV6		0x0006U
+#define DNS_LUP_FLAGS_NAME_HOST		0x0010U
+#define DNS_LUP_FLAGS_NAME_FQDN		0x0011U
+#define DNS_LUP_FLAGS_NAME_MASK		0x001fU
+
+#define DNS_LUP_OPCODE_FORWARD		DNS_OPCODE_FORWARD
+#define DNS_LUP_OPCODE_REVERSE		DNS_OPCODE_REVERSE
+#define DNS_LUP_OPCODE_STATUS		DNS_OPCODE_STATUS
+#define DNS_LUP_OPCODE_MASK		DNS_OPCODE_MASK
+
+#define DNS_LUP_FLAGS_PROTO_IPV4	0x0040U
+#define DNS_LUP_FLAGS_PROTO_IPV6	0x0080U
+#define DNS_LUP_FLAGS_PROTO_MASK	0x00c0U
+
+#define DNS_LUP_FLAGS_QTYPE_A		0x0100U
+#define DNS_LUP_FLAGS_QTYPE_AAAA	0x0200U
+#define DNS_LUP_FLAGS_QTYPE_PTR		0x0400U
+#define DNS_LUP_FLAGS_QTYPE_MASK	0x0700U
+
+#define DNS_LUP_FLAGS_MSG		0x0020U
+
+/*
+ *  ãããã¯ã¼ã¯ã¨ã©ã¼ã³ã¼ã
+ */
+
+#define EV_RSLV_ESIZE			(-100)		/* DNSã¡ãã»ã¼ã¸ã®ååé·ç°å¸¸	*/
+#define EV_RSLV_UNEXPCT			(-101)		/* äºæããªãDNSã¡ãã»ã¼ã¸	*/
+
+/*
+ *  é¢æ°
+ */
+
+extern ER_UINT	dns_lookup_host (uint16_t flags, char *hostname, uint8_t *msg, uint_t msg_len, T_RSLV_DNS_MSG *rslv);
+extern ER	dns_host_addr (uint16_t flags, char *hostname, T_IN_ADDR *addr);
+extern ER_UINT	dns_analyze_qd (T_RSLV_QD *qd, uint_t offset, uint8_t *msg, uint_t length);
+extern ER_UINT	dns_analyze_rr (T_RSLV_RR *rr, uint_t offset, uint8_t *msg, uint_t length);
+extern ER_UINT	dns_analyze_soa (T_RSLV_SOA *soa, uint_t offset, uint8_t *msg, uint_t length);
+
+/*
+ *  æ³¨æ: dns_in6_set_dnameãdns_in4_set_dnameã
+ *        dns_in6_set_addrã dns_in4_set_addr ã§ã
+ *        new ã« NULL ãæå®ããã¨ãåæå¤ã«æ»ãã
+ */
+
+extern const uint8_t *dns_in6_set_dname (const uint8_t *new, uint_t len);
+extern const uint8_t *dns_in6_get_dname (void);
+extern const uint8_t *dns_in4_set_dname (const uint8_t *new, uint_t len);
+extern const uint8_t *dns_in4_get_dname (void);
+extern T_IN6_ADDR *dns_in6_set_addr (T_IN6_ADDR *new);
+extern T_IN6_ADDR *dns_in6_get_addr (T_IN6_ADDR *dst);
+extern T_IN4_ADDR *dns_in4_set_addr (T_IN4_ADDR *new);
+extern T_IN4_ADDR *dns_in4_get_addr (T_IN4_ADDR *dst);
+
+#endif	/* of #ifndef RESOLVER_H */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/resolver_asp.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/resolver_asp.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/resolver_asp.cfg	(revision 331)
@@ -0,0 +1,66 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ASP ç¨ Resolver ã®ã·ã¹ãã ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ */
+
+#ifdef USE_RESOLVER
+
+/*
+ * åºå®ã¡ã¢ãªãã¼ã«
+ */
+
+/* éåä¿¡ãããã¡ */
+
+CRE_MPF(MPF_RSLV_SRBUF, {
+	TA_TFIFO,
+	NUM_MPF_RSLV_SRBUF,
+	DNS_UDP_MSG_LENGTH,
+	NULL,
+	NULL
+	});
+
+#endif	/* of #ifdef USE_RESOLVER */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/resolver_jsp.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/resolver_jsp.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/resolver_jsp.cfg	(revision 331)
@@ -0,0 +1,65 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  JSP ç¨ Resolver ã®ã·ã¹ãã ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ */
+
+#ifdef USE_RESOLVER
+
+/*
+ * åºå®ã¡ã¢ãªãã¼ã«
+ */
+
+/* éåä¿¡ãããã¡ */
+
+CRE_MPF(MPF_RSLV_SRBUF, {
+	TA_TFIFO,
+	NUM_MPF_RSLV_SRBUF,
+	DNS_UDP_MSG_LENGTH,
+	NULL
+	});
+
+#endif	/* of #ifdef USE_RESOLVER */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_discard_cli.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_discard_cli.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_discard_cli.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -58,24 +58,10 @@
 #endif	/* of #ifdef TARGET_KERNEL_JSP */
 
-#include <tinet_defs.h>
-#include <tinet_config.h>
-
-#include <net/if.h>
-#include <net/if_ppp.h>
-#include <net/if_loop.h>
-#include <net/ethernet.h>
-#include <net/net.h>
-#include <net/net_var.h>
-#include <net/net_timer.h>
-
 #include <netinet/in.h>
 #include <netinet/in_itron.h>
-#include <netinet/ip.h>
-#include <netinet/ip6.h>
-#include <netinet/tcp.h>
 
 #include <netapp/netapp.h>
 #include <netapp/netapp_var.h>
-#include <netapp/discard.h>
+#include <netapp/tcp_discard_cli.h>
 
 #ifdef USE_TCP_DISCARD_CLI
@@ -88,4 +74,33 @@
 
 /*#define SHOW_RCV_RANGE*/
+
+/* 送信間隔 */
+
+#ifdef TOPPERS_S810_CLG3_85
+
+#define START_DLY	(10*SYSTIM_HZ)
+#define SND_ITV		(5*SYSTIM_HZ)
+#define SLP_ITV		(30*SYSTIM_HZ)
+
+#else	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+#define START_DLY	(10*SYSTIM_HZ)
+#define SND_ITV		(5*SYSTIM_HZ)
+#define SLP_ITV		(60*SYSTIM_HZ)
+
+#endif	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+/* 自動実行 */
+
+#if defined(TCP_DISCARD_CLI_AUTO_RUN_STR)
+#else
+#if 0
+#if defined(SUPPORT_INET6)
+#define TCP_DISCARD_CLI_AUTO_RUN_STR	"fd90:cce5:25f6:ff81:201:2ff:fe81:e7c9 - 0"
+#else
+#define TCP_DISCARD_CLI_AUTO_RUN_STR	"172.25.129.142 - 0"
+#endif
+#endif
+#endif
 
 /*
@@ -143,5 +158,5 @@
 	case TFN_TCP_CLS_CEP:
 		if (nblk_error < 0)
-			syslog(LOG_NOTICE, "[TDC:%02d CBN] close error: %s", cepid, itron_strerror(nblk_error));
+			syslog(LOG_NOTICE, "[TDCn:%02u CBN] close error: %s", cepid, itron_strerror(nblk_error));
 		syscall(sig_sem(SEM_TCP_DISCARD_CLI_NBLK_READY));
 		break;
@@ -162,5 +177,5 @@
  */
 
-static void
+static ER
 send_tcp_discard (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno)
 {
@@ -183,6 +198,6 @@
 
 	if ((error = TCP_CON_CEP(cepid, &nblk_src, &nblk_dst, TMO_NBLK)) != E_WBLK) {
-		syslog(LOG_NOTICE, "[TDC:%02d SND] connect error: %s", cepid, itron_strerror(error));
-		return;
+		syslog(LOG_NOTICE, "[TDCn:%02u SND] connect error: %s", cepid, itron_strerror(error));
+		return error;
 		}
 
@@ -191,8 +206,8 @@
 
 	if (nblk_error != E_OK)
-		syslog(LOG_NOTICE, "[TDC:%02d SND] connect error: %s", cepid, itron_strerror(nblk_error));
+		syslog(LOG_NOTICE, "[TDCn:%02u SND] connect error: %s", cepid, itron_strerror(nblk_error));
 	else {
 		get_tim(&time);
-		syslog(LOG_NOTICE, "[TDC:%02d SND] connecting: %6ld, to:   %s.%d",
+		syslog(LOG_NOTICE, "[TDCn:%02u SND] conct: %7lu, to:   %s.%d",
 		                   cepid, time / SYSTIM_HZ, IP2STR(NULL, ipaddr), nblk_dst.portno);
 
@@ -202,5 +217,5 @@
 			while (soff < SND_BUF_SIZE) {
 				if ((slen = tcp_snd_dat(cepid, smsg + soff, sizeof(smsg) - soff, TMO_FEVR)) < 0) {
-					syslog(LOG_NOTICE, "[TDC:%02d SND] send error: %s",
+					syslog(LOG_NOTICE, "[TDCn:%02u SND] send error: %s",
 					                   cepid, itron_strerror(slen));
 					goto cls_ret;
@@ -211,9 +226,9 @@
 
 #ifdef SHOW_RCV_RANGE
-				syslog(LOG_NOTICE, "[TDC:%02d SND] snd: %2d, len: %4d, off: %4d",
+				syslog(LOG_NOTICE, "[TDCn:%02u SND] send:  %7lu, len: %4u, off: %4u",
 				                   cepid, scount, (uint16_t)slen, soff);
 #endif	/* of #ifdef SHOW_RCV_RANGE */
 
-				syscall(dly_tsk(500 + net_rand() % SYSTIM_HZ));
+				syscall(dly_tsk(500 + netapp_rand() % SYSTIM_HZ));
 				}
 			}
@@ -221,16 +236,18 @@
 	cls_ret:
 		get_tim(&time);
-		syslog(LOG_NOTICE, "[TDC:%02d SND] finished:   %6ld, snd: %4d,            len: %ld",
+		syslog(LOG_NOTICE, "[TDCn:%02u SND] finsh: %7lu, ttl: %lu",
 		                   cepid, time / SYSTIM_HZ, scount, total);
 
 		if ((error = tcp_sht_cep(cepid)) < 0)
-			syslog(LOG_NOTICE, "[TDC:%02d SND] shutdown error: %s", cepid, itron_strerror(error));
+			syslog(LOG_NOTICE, "[TDCn:%02u SND] shutdown error: %s", cepid, itron_strerror(error));
 
 		if ((error = tcp_cls_cep(cepid, TMO_NBLK)) != E_WBLK)
-			syslog(LOG_NOTICE, "[TDC:%02d SND] close error: %s", cepid, itron_strerror(error));
+			syslog(LOG_NOTICE, "[TDCn:%02u SND] close error: %s", cepid, itron_strerror(error));
 
 		/* 開放が完了するまで待つ。*/
 		syscall(wai_sem(SEM_TCP_DISCARD_CLI_NBLK_READY));
 		}
+
+	return E_OK;
 	}
 
@@ -241,5 +258,5 @@
  */
 
-static void
+static ER
 send_tcp_discard (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno)
 {
@@ -266,10 +283,10 @@
 
 	if ((error = TCP_CON_CEP(cepid, &src, &dst, 60 * 1000)) != E_OK) {
-		syslog(LOG_NOTICE, "[TDC:%02d SND] connect error: %s", cepid, itron_strerror(error));
-		return;
+		syslog(LOG_NOTICE, "[TDCn:%02u SND] connect error: %s", cepid, itron_strerror(error));
+		return error;
 		}
 
 	get_tim(&time);
-	syslog(LOG_NOTICE, "[TDC:%02d SND] connecting: %6ld, to:   %s.%d",
+	syslog(LOG_NOTICE, "[TDCn:%02u SND] conct: %7lu, to:   %s.%d",
 	                   cepid, time / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
 
@@ -279,5 +296,5 @@
 		while (soff < SND_BUF_SIZE) {
 			if ((slen = tcp_snd_dat(cepid, smsg + soff, sizeof(smsg) - soff, TMO_FEVR)) < 0) {
-				syslog(LOG_NOTICE, "[TDC:%02d SND] send error: %s", cepid, itron_strerror(slen));
+				syslog(LOG_NOTICE, "[TDCn:%02u SND] send error: %s", cepid, itron_strerror(slen));
 				goto cls_ret;
 				}
@@ -287,9 +304,9 @@
 
 #ifdef SHOW_RCV_RANGE
-			syslog(LOG_NOTICE, "[TDC:%02d SND] snd: %3d, len: %4d, off: %4d",
+			syslog(LOG_NOTICE, "[TDCn:%02u SND] send:  %7lu, len: %4u, off: %4u",
 			                   cepid, scount, (uint16_t)slen, soff);
 #endif	/* of #ifdef SHOW_RCV_RANGE */
 
-			syscall(dly_tsk(500 + net_rand() % SYSTIM_HZ));
+			syscall(dly_tsk(500 + netapp_rand() % SYSTIM_HZ));
 			}
 		}
@@ -297,105 +314,205 @@
 cls_ret:
 	get_tim(&time);
-	syslog(LOG_NOTICE, "[TDC:%02d SND] finished:   %6ld, snd: %4d,            len: %ld",
+	syslog(LOG_NOTICE, "[TDCn:%02u SND] finsh: %7lu, ttl: %lu",
 	                   cepid, time / SYSTIM_HZ, scount, total);
 
 	if ((error = tcp_sht_cep(cepid)) < 0)
-		syslog(LOG_NOTICE, "[TDC:%02d SND] shutdown error: %s", cepid, itron_strerror(error));
+		syslog(LOG_NOTICE, "[TDCn:%02u SND] shutdown error: %s", cepid, itron_strerror(error));
 
 	if ((error = tcp_cls_cep(cepid, TMO_FEVR)) < 0)
-		syslog(LOG_NOTICE, "[TDC:%02d SND] close error: %s", cepid, itron_strerror(error));
+		syslog(LOG_NOTICE, "[TDCn:%02u SND] close error: %s", cepid, itron_strerror(error));
+
+	return E_OK;
 	}
 
 #endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+/*
+ *  getcomd -- コマンドを得る。
+ */
+
+#ifdef TCP_DISCARD_CLI_AUTO_RUN_STR
+
+static char *
+getcomd (ID cepid, bool_t retry)
+{
+	ER		error;
+	char		*line = NULL;
+	static char	auto_run_str[] = TCP_DISCARD_CLI_AUTO_RUN_STR;
+	static int_t	count = 0;
+
+	if (retry || (count == 0)) {
+		line = auto_run_str;
+		dly_tsk(3 * 1000);
+		}
+	else {
+		while ((error = rcv_dtq(DTQ_TCP_DISCARD_CLI, (intptr_t*)&line)) != E_OK) {
+			syslog(LOG_NOTICE, "[TDCn:%02u TSK] error: %s", cepid, itron_strerror(error));
+			dly_tsk(SLP_ITV);
+			}
+		}
+
+	count ++;
+	return line;
+	}
+
+#else	/* of #ifdef TCP_DISCARD_CLI_AUTO_RUN_STR */
+
+static char *
+getcomd (ID cepid, bool_t retry)
+{
+	ER	error;
+	char	*line = NULL;
+
+	while ((error = rcv_dtq(DTQ_TCP_DISCARD_CLI, (intptr_t*)&line)) != E_OK) {
+		syslog(LOG_NOTICE, "[TDCn:%02u TSK] error: %s", cepid, itron_strerror(error));
+		dly_tsk(SLP_ITV);
+		}
+	return line;
+	}
+
+#endif	/* of #ifdef TCP_DISCARD_CLI_AUTO_RUN_STR */
 
 void
 tcp_discard_cli_task (intptr_t exinf)
 {
+	ID		tskid, cepid;
 	T_IN_ADDR	addr;
-	ID		tskid, cepid;
-	int_t		rep;
-	uint32_t	count;
+	ER		error;
+	uint8_t		*line;
+	int_t		rep, count;
+	bool_t		retry = false;
 	uint16_t	portno;
-	uint8_t		*line;
+	char		apip;
 
 #ifdef USE_TCP_EXTENTIONS
 
-	ER		error;
 	T_TCP_CCEP	ccep;
 
 #endif	/* of #ifdef USE_TCP_EXTENTIONS */
 
+#ifdef TCP_ECHO_CLI_AUTO_RUN_STR
+	dly_tsk(START_DLY);
+#endif
 	get_tid(&tskid);
-	syslog(LOG_NOTICE, "[TCP DISCARD CLI:%d,%d] started.", tskid, (ID)exinf);
+
+#if defined(SUPPORT_INET6)
+	apip = API_PROTO_IPV6;
+#if defined(SUPPORT_INET4)
+	syslog(LOG_NOTICE, "[TCPn DISCARD CLI:%d,%d] started.", tskid, (ID)exinf);
+#else
+	syslog(LOG_NOTICE, "[TCP6 DISCARD CLI:%d,%d] started.", tskid, (ID)exinf);
+#endif
+#else
+	apip = API_PROTO_IPV4;
+	syslog(LOG_NOTICE, "[TCP4 DISCARD CLI:%d,%d] started.", tskid, (ID)exinf);
+#endif
+
 	while (true) {
-		if (rcv_dtq(DTQ_TCP_DISCARD_CLI, (intptr_t*)&line) == E_OK) {
-			line = skip_blanks(GET_IPADDR(&addr, skip_blanks(line)));	/* IP Address */
-
-			if ('0' <= *line && *line <= '9') {				/* Port No */
-				line = get_int(&rep, line);
-				portno = (uint16_t)rep;
+		line = skip_blanks(getcomd((ID)exinf, retry));
+
+		if ((line = lookup_ipaddr(&addr, line, apip)) == NULL) {
+			syslog(LOG_NOTICE, "[TDCn:%02u TSK] sleep %d.%03u[s], unknown host.",
+			       (ID)exinf, SLP_ITV / SYSTIM_HZ, SLP_ITV % SYSTIM_HZ);
+			dly_tsk(SLP_ITV);
+			syslog(LOG_NOTICE, "[TDCn:%02u TSK] resume.", (ID)exinf);
+			retry = true;
+			continue;
+			}
+		else
+			retry = false;
+
+		line = skip_blanks(line);
+		if ('0' <= *line && *line <= '9') {	/* Port No */
+			line = get_int(&rep, line);
+			portno = (uint16_t)rep;
+			}
+		else {
+			line ++;
+			portno = DISCARD_SRV_PORTNO;
+			}
+
+		line = skip_blanks(line);
+		if ('0' <= *line && *line <= '9')	/* Repeat */
+			line = get_int(&rep, line);
+		else
+			rep = 1;
+
+#ifdef USE_TCP_EXTENTIONS
+
+		ccep.cepatr = 0;
+		ccep.sbufsz = TCP_DISCARD_CLI_SWBUF_SIZE;
+		ccep.rbufsz = 0;
+		ccep.rbuf = NADR;
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+		ccep.sbuf = NADR;
+#else
+		ccep.sbuf = tcp_discard_cli_swbuf;
+#endif
+#ifdef USE_TCP_NON_BLOCKING
+		ccep.callback = (FP)callback_nblk_tcp_discard_cli;
+#else
+		ccep.callback = NULL;
+#endif
+
+		if ((error = ALLOC_TCP_CEP(&cepid, tskid, &ccep)) != E_OK) {
+			syslog(LOG_NOTICE, "[TDCn:%02u TSK] CEP create error: %s", cepid, itron_strerror(error));
+			continue;
+			}
+
+#else	/* of #ifdef USE_TCP_EXTENTIONS */
+
+		cepid = (ID)exinf;
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+		tcp_discard_cli_valid = true;
+		count = 0;
+		while (rep == 0 || count < rep) {
+			if (!tcp_discard_cli_valid) {
+				syslog(LOG_NOTICE, "[TDCn:%02u TSK] canceled.", cepid);
+				break;
+				}
+
+			count ++;
+			if (rep == 0) {
+				syslog(LOG_NOTICE, "[TDCn:%02u TSK] start:       repeat: %d", cepid, count);
+				error = send_tcp_discard(cepid, &addr, portno);
+				syslog(LOG_NOTICE, "[TDCn:%02u TSK] finsh:       repeat: %d", cepid, count);
 				}
 			else {
-				line ++;
-				portno = DISCARD_SRV_PORTNO;
-				}
-
-			line = skip_blanks(line);
-			if ('0' <= *line && *line <= '9')				/* Repeat */
-				line = get_int(&rep, line);
-			else
-				rep = 1;
+				syslog(LOG_NOTICE, "[TDCn:%02u TSK] start:       repeat: %d/%d", cepid, count, rep);
+				error = send_tcp_discard(cepid, &addr, portno);
+				syslog(LOG_NOTICE, "[TDCn:%02u TSK] finsh:       repeat: %d/%d", cepid, count, rep);
+				}
+
+			if (error != E_OK) {
+				syslog(LOG_NOTICE, "[TDCn:%02u TSK] sleep %d.%03u[s], error: %s",
+				                   cepid, SLP_ITV / SYSTIM_HZ, SLP_ITV % SYSTIM_HZ, itron_strerror(error));
+				tslp_tsk(SLP_ITV);
+				syslog(LOG_NOTICE, "[TDCn:%02u TSK] resume.", cepid);
+				}
+
+#if defined(SND_ITV)
+#if SND_ITV > 0
+			if (count < rep) {
+				uint_t itv;
+				
+				itv = SND_ITV;
+				syslog(LOG_NOTICE, "[TDCn:%02u TSK] interval: %d[s].", cepid, itv / SYSTIM_HZ);
+				syscall(dly_tsk(SND_ITV));
+				}
+#endif
+#endif
+			}
 
 #ifdef USE_TCP_EXTENTIONS
 
-			ccep.cepatr = 0;
-			ccep.sbufsz = TCP_DISCARD_CLI_SWBUF_SIZE;
-			ccep.rbufsz = 0;
-			ccep.rbuf = NADR;
-
-#ifdef TCP_CFG_SWBUF_CSAVE
-			ccep.sbuf = NADR;
-#else
-			ccep.sbuf = tcp_discard_cli_swbuf;
-#endif
-#ifdef USE_TCP_NON_BLOCKING
-			ccep.callback = (FP)callback_nblk_tcp_discard_cli;
-#else
-			ccep.callback = NULL;
-#endif
-
-			if ((error = alloc_tcp_cep(&cepid, tskid, &ccep)) != E_OK) {
-				syslog(LOG_NOTICE, "[TDC:%02d TSK] CEP create error: %s", cepid, itron_strerror(error));
-				continue;
-				}
-
-#else	/* of #ifdef USE_TCP_EXTENTIONS */
-
-			cepid = (ID)exinf;
+		if ((error = FREE_TCP_CEP(cepid)) != E_OK)
+			syslog(LOG_NOTICE, "[TDCn:%02u TSK] CEP delete error: %s", cepid, itron_strerror(error));
 
 #endif	/* of #ifdef USE_TCP_EXTENTIONS */
 
-			tcp_discard_cli_valid = true;
-			for (count = rep; count -- > 0; ) {
-				if (!tcp_discard_cli_valid) {
-					syslog(LOG_NOTICE, "[TDC:%02d TSK] canceled.", (ID)exinf);
-					break;
-					}
-				syslog(LOG_NOTICE, "[TDC:%02d TSK] start:              repeat: %d/%d",
-				                   (ID)exinf, rep - count, rep);
-				send_tcp_discard(cepid, &addr, portno);
-				syslog(LOG_NOTICE, "[TDC:%02d TSK] finished:           repeat: %d/%d",
-				                   (ID)exinf, rep - count, rep);
-				syscall(dly_tsk(500 + net_rand() % SYSTIM_HZ));
-				}
-
-#ifdef USE_TCP_EXTENTIONS
-
-			if ((error = free_tcp_cep(cepid)) != E_OK)
-				syslog(LOG_NOTICE, "[TDC:%02d TSK] CEP delete error: %s", cepid, itron_strerror(error));
-
-#endif	/* of #ifdef USE_TCP_EXTENTIONS */
-
-			}
 		}
 	}
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_discard_cli.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_discard_cli.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_discard_cli.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_discard_cli.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_discard_cli.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_discard_cli.h	(revision 331)
@@ -0,0 +1,100 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _TCP_DISCARD_CLI_H_
+#define _TCP_DISCARD_CLI_H_
+
+/* ã¹ã¿ãã¯ãµã¤ãº */
+
+#define TCP_DISCARD_CLI_STACK_SIZE	1024		/* TCP DISCARD ã¯ã©ã¤ã¢ã³ãã¿ã¹ã¯ã®ã¹ã¿ãã¯ãµã¤ãº */
+
+/* åªå
+åº¦ */
+
+#define TCP_DISCARD_CLI_MAIN_PRIORITY	5	/* TCP DISCARD ã¯ã©ã¤ã¢ã³ãã¿ã¹ã¯ã®åªå
+åº¦ */
+
+/*
+ *  TCP éåä¿¡ã¦ã¤ã³ããããã¡ãµã¤ãº
+ */
+
+#if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU)
+
+#if defined(SUPPORT_INET6)
+
+#define TCP_DISCARD_CLI_SWBUF_SIZE	(1024)
+
+#elif defined(SUPPORT_INET4)
+
+#define TCP_DISCARD_CLI_SWBUF_SIZE	(512)
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#else	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+#define TCP_DISCARD_CLI_SWBUF_SIZE	(2048)
+
+#endif	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+/*
+ *  å¤æ°
+ */
+
+extern bool_t	tcp_discard_cli_valid;
+
+/* TCP éåä¿¡ãããã¡ */
+
+extern uint8_t tcp_discard_cli_swbuf[];
+extern uint8_t tcp_discard_cli_rwbuf[];
+
+/* ã¿ã¹ã¯ */
+
+extern void tcp_discard_cli_task(intptr_t exinf);
+
+/* é¢æ° */
+
+extern ER callback_nblk_tcp_discard_cli (ID cepid, FN fncd, void *p_parblk);
+
+#endif	/* of #ifndef _TCP_DISCARD_CLI_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_discard_srv.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_discard_srv.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_discard_srv.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -58,23 +58,10 @@
 #endif	/* of #ifdef TARGET_KERNEL_JSP */
 
-#include <tinet_defs.h>
-#include <tinet_config.h>
-
-#include <net/if.h>
-#include <net/if_ppp.h>
-#include <net/if_loop.h>
-#include <net/ethernet.h>
-#include <net/net.h>
-#include <net/net_timer.h>
-
 #include <netinet/in.h>
 #include <netinet/in_itron.h>
-#include <netinet/ip.h>
-#include <netinet/ip6.h>
-#include <netinet/tcp.h>
 
 #include <netapp/netapp.h>
 #include <netapp/netapp_var.h>
-#include <netapp/discard.h>
+#include <netapp/tcp_discard_srv.h>
 
 #ifdef USE_TCP_DISCARD_SRV
@@ -121,11 +108,11 @@
 
 	if ((error = TCP_ACP_CEP(cepid, repid, &dst, TMO_FEVR)) != E_OK) {
-		syslog(LOG_NOTICE, "[TDS:%02d ACP] accept error: %s", cepid, itron_strerror(error));
+		syslog(LOG_NOTICE, "[TDSn:%02u ACP] accept error: %s", cepid, itron_strerror(error));
 		return error;
 		}
 
 #ifdef USE_TCP_EXTENTIONS
-	if ((error = free_tcp_rep(repid, true)) != E_OK) {
-		syslog(LOG_NOTICE, "[TDS:%02d DEL] REP delete error: %s", cepid, itron_strerror(error));
+	if ((error = FREE_TCP_REP(repid, true)) != E_OK) {
+		syslog(LOG_NOTICE, "[TDSn:%02u DEL] REP delete error: %s", cepid, itron_strerror(error));
 		return error;
 		}
@@ -134,5 +121,5 @@
 	count = total = 0;
 	get_tim(&time);
-	syslog(LOG_NOTICE, "[TDS:%02d RCV] connected:  %6ld, from: %s.%d",
+	syslog(LOG_NOTICE, "[TDSn:%02u RCV] conct: %7lu, from: %s.%d",
 	                   cepid, time / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
 	while ((rlen = tcp_rcv_buf(cepid, (void*)&buf, TMO_FEVR)) > 0) {
@@ -140,5 +127,5 @@
 
 #ifdef SHOW_RCV_RANGE
-		syslog(LOG_NOTICE, "[TDS:%02d RCV] count: %4d, len: %4d, data: %02x -> %02x",
+		syslog(LOG_NOTICE, "[TDSn:%02u RCV] count: %6lu, len: %4u, data: %02x -> %02x",
 		       cepid, count, (uint16_t)rlen, *buf, *(buf + rlen - 1));
 #endif	/* of #ifdef SHOW_RCV_RANGE */
@@ -150,5 +137,5 @@
 
 		if ((error = tcp_rel_buf(cepid, rlen)) != E_OK) {
-			syslog(LOG_NOTICE, "[TDS:%02d RCV] rel buf error: %s",
+			syslog(LOG_NOTICE, "[TDSn:%02u RCV] rel buf error: %s",
 			                    cepid, itron_strerror(error));
 			rlen = 0;
@@ -159,14 +146,14 @@
 
 	if (rlen != 0)
-		syslog(LOG_NOTICE, "[TDS:%02d RCV] recv buf error: %s", cepid, itron_strerror(rlen));
+		syslog(LOG_NOTICE, "[TDSn:%02u RCV] recv buf error: %s", cepid, itron_strerror(rlen));
 
 	if ((error = tcp_sht_cep(cepid)) != E_OK)
-		syslog(LOG_NOTICE, "[TDS:%02d RCV] shutdown error: %s", cepid, itron_strerror(error));
+		syslog(LOG_NOTICE, "[TDSn:%02u RCV] shutdown error: %s", cepid, itron_strerror(error));
 
 	if ((error = tcp_cls_cep(cepid, TMO_FEVR)) != E_OK)
-		syslog(LOG_NOTICE, "[TDS:%02d RCV] close error: %s", cepid, itron_strerror(error));
+		syslog(LOG_NOTICE, "[TDSn:%02u RCV] close error: %s", cepid, itron_strerror(error));
 
 	get_tim(&time);
-	syslog(LOG_NOTICE, "[TDS:%02d RCV] finished:   %6ld,            rcv: %4d, len: %ld",
+	syslog(LOG_NOTICE, "[TDSn:%02u RCV] finsh: %7lu, ttl: %lu",
 	                   cepid, time / SYSTIM_HZ, count, total);
 
@@ -190,11 +177,11 @@
 
 	if ((error = TCP_ACP_CEP(cepid, repid, &dst, TMO_FEVR)) != E_OK) {
-		syslog(LOG_NOTICE, "[TDS:%02d RCV] accept error: %s", cepid, itron_strerror(error));
+		syslog(LOG_NOTICE, "[TDSn:%02u RCV] accept error: %s", cepid, itron_strerror(error));
 		return error;
 		}
 
 #ifdef USE_TCP_EXTENTIONS
-	if ((error = free_tcp_rep(repid, true)) != E_OK) {
-		syslog(LOG_NOTICE, "[TDS:%02d DEL] REP delete error: %s", cepid, itron_strerror(error));
+	if ((error = FREE_TCP_REP(repid, true)) != E_OK) {
+		syslog(LOG_NOTICE, "[TDSn:%02u DEL] REP delete error: %s", cepid, itron_strerror(error));
 		return error;
 		}
@@ -203,5 +190,5 @@
 	count = total = 0;
 	get_tim(&time);
-	syslog(LOG_NOTICE, "[TDS:%02d RCV] connected:  %6ld, from: %s.%d",
+	syslog(LOG_NOTICE, "[TDSn:%02u RCV] conct: %7lu, from: %s.%d",
 	                   cepid, time / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
 	while ((rlen = tcp_rcv_dat(cepid, buf, BUF_SIZE - 1, TMO_FEVR)) > 0) {
@@ -209,5 +196,5 @@
 
 #ifdef SHOW_RCV_RANGE
-		syslog(LOG_NOTICE, "[TDS:%02d RCV] count: %4d, len: %4d, data: %02x -> %02x",
+		syslog(LOG_NOTICE, "[TDSn:%02u RCV] count: %6lu, len: %4u, data: %02x -> %02x",
 		       cepid, count, (uint16_t)rlen, *buf, *(buf + rlen - 1));
 #endif	/* of #ifdef SHOW_RCV_RANGE */
@@ -216,14 +203,14 @@
 		}
 	if (rlen != 0)
-		syslog(LOG_NOTICE, "[TDS:%02d RCV] recv error: %s", cepid, itron_strerror(rlen));
+		syslog(LOG_NOTICE, "[TDSn:%02u RCV] recv error: %s", cepid, itron_strerror(rlen));
 
 	if ((error = tcp_sht_cep(cepid)) != E_OK)
-		syslog(LOG_NOTICE, "[TDS:%02d RCV] shutdown error: %s", cepid, itron_strerror(error));
+		syslog(LOG_NOTICE, "[TDSn:%02u RCV] shutdown error: %s", cepid, itron_strerror(error));
 
 	if ((error = tcp_cls_cep(cepid, TMO_FEVR)) != E_OK)
-		syslog(LOG_NOTICE, "[TDS:%02d RCV] close error: %s", cepid, itron_strerror(error));
+		syslog(LOG_NOTICE, "[TDSn:%02u RCV] close error: %s", cepid, itron_strerror(error));
 
 	get_tim(&time);
-	syslog(LOG_NOTICE, "[TDS:%02d RCV] finished:   %6ld,            rcv: %4d, len: %ld",
+	syslog(LOG_NOTICE, "[TDSn:%02u RCV] finsh: %7lu, ttl: %lu",
 	                   cepid, time / SYSTIM_HZ, count, total);
 
@@ -243,5 +230,5 @@
 {
 	ID		tskid;
-	T_TCP_CREP	crep;
+	T_TCPN_CREP	crep;
 
 	get_tid(&tskid);
@@ -250,13 +237,17 @@
 	crep.myaddr.portno = UINT_C(9);
 
+#if defined(SUPPORT_INET6)
+
+	memcpy(&crep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
+
+#else	/* #if defined(SUPPORT_INET6) */
+
 #if defined(SUPPORT_INET4)
 	crep.myaddr.ipaddr = IPV4_ADDRANY;
 #endif
 
-#if defined(SUPPORT_INET6)
-	memcpy(&crep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
-#endif
-
-	return alloc_tcp_rep(repid, tskid, &crep);
+#endif	/* #if defined(SUPPORT_INET6) */
+
+	return ALLOC_TCP_REP(repid, tskid, &crep);
 	}
 
@@ -285,5 +276,5 @@
 #endif
 
-	return alloc_tcp_cep(cepid, tskid, &ccep);
+	return ALLOC_TCP_CEP(cepid, tskid, &ccep);
 	}
 
@@ -299,10 +290,20 @@
 
 	syscall(get_tid(&tskid));
-	syslog(LOG_NOTICE, "[TCP ECHO SRV:%d] started.", tskid);
+
+#if defined(SUPPORT_INET6)
+#if defined(SUPPORT_INET4)
+	syslog(LOG_NOTICE, "[TCPn DISCARD SRV:%d] started.", tskid);
+#else
+	syslog(LOG_NOTICE, "[TCP6 DISCARD SRV:%d] started.", tskid);
+#endif
+#else
+	syslog(LOG_NOTICE, "[TCP4 DISCARD SRV:%d] started.", tskid);
+#endif
+
 	while (true) {
 
 		syscall(slp_tsk());
 		if ((error = get_tcp_cep (&cepid)) != E_OK) {
-			syslog(LOG_NOTICE, "[TDS:00 EXT] CEP create error: %s", itron_strerror(error));
+			syslog(LOG_NOTICE, "[TDSn:00 EXT] CEP create error: %s", itron_strerror(error));
 			continue;
 			}
@@ -311,15 +312,15 @@
 
 			if ((error = get_tcp_rep (&repid)) != E_OK) {
-				syslog(LOG_NOTICE, "[TDS:00 EXT] REP create error: %s", itron_strerror(error));
+				syslog(LOG_NOTICE, "[TDSn:00 EXT] REP create error: %s", itron_strerror(error));
 				break;
 				}
 			else if ((error = tcp_discard_srv(cepid, repid)) != E_OK) {
-				error = free_tcp_rep(repid, error != E_DLT);
+				error = FREE_TCP_REP(repid, error != E_DLT);
 				break;
 				}
 			}
 
-		if ((error = free_tcp_cep(cepid)) != E_OK)
-			syslog(LOG_NOTICE, "[TDS:%02d EXT] CEP delete error: %s", cepid, itron_strerror(error));
+		if ((error = FREE_TCP_CEP(cepid)) != E_OK)
+			syslog(LOG_NOTICE, "[TDSn:%02u EXT] CEP delete error: %s", cepid, itron_strerror(error));
 
 		}
@@ -334,5 +335,15 @@
 
 	get_tid(&tskid);
-	syslog(LOG_NOTICE, "[TCP DISCARD SRV:%d,%d] started.", tskid, (ID)exinf);
+
+#if defined(SUPPORT_INET6)
+#if defined(SUPPORT_INET4)
+	syslog(LOG_NOTICE, "[TCPn DISCARD SRV:%d,%d] started.", tskid, (ID)exinf);
+#else
+	syslog(LOG_NOTICE, "[TCP6 DISCARD SRV:%d,%d] started.", tskid, (ID)exinf);
+#endif
+#else
+	syslog(LOG_NOTICE, "[TCP4 DISCARD SRV:%d,%d] started.", tskid, (ID)exinf);
+#endif
+
 	while (true) {
 		while (tcp_discard_srv((ID)exinf, TCP_DISCARD_SRV_REPID) == E_OK)
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_discard_srv.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_discard_srv.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_discard_srv.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_discard_srv.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_discard_srv.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_discard_srv.h	(revision 331)
@@ -0,0 +1,90 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _TCP_DISCARD_SRV_H_
+#define _TCP_DISCARD_SRV_H_
+
+/* ã¹ã¿ãã¯ãµã¤ãº */
+
+#define TCP_DISCARD_SRV_STACK_SIZE	1024		/* TCP DISCARD ãµã¼ãã¿ã¹ã¯ã®ã¹ã¿ãã¯ãµã¤ãº */
+
+/* åªå
+åº¦ */
+
+#define TCP_DISCARD_SRV_MAIN_PRIORITY	5	/* TCP DISCARD ãµã¼ãã¿ã¹ã¯ã®åªå
+åº¦ */
+
+/*
+ *  TCP éåä¿¡ã¦ã¤ã³ããããã¡ãµã¤ãº
+ */
+
+#if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU)
+
+#if defined(SUPPORT_INET6)
+
+#define TCP_DISCARD_SRV_RWBUF_SIZE	(1024)
+
+#elif defined(SUPPORT_INET4)
+
+#define TCP_DISCARD_SRV_RWBUF_SIZE	(512)
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#else	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+#define TCP_DISCARD_SRV_RWBUF_SIZE	(2048)
+
+#endif	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+/* TCP éåä¿¡ãããã¡ */
+
+extern uint8_t tcp_discard_srv_swbuf[];
+extern uint8_t tcp_discard_srv_rwbuf[];
+
+/* ã¿ã¹ã¯ */
+
+extern void tcp_discard_srv_task(intptr_t exinf);
+
+#endif	/* of #ifndef _TCP_DISCARD_SRV_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -50,4 +50,5 @@
 #include <t_syslog.h>
 #include "kernel_cfg.h"
+#include "tinet_cfg.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_ASP */
@@ -57,27 +58,14 @@
 #include <t_services.h>
 #include "kernel_id.h"
+#include "tinet_id.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_JSP */
-
-#include <tinet_defs.h>
-#include <tinet_config.h>
-
-#include <net/if.h>
-#include <net/if_ppp.h>
-#include <net/if_loop.h>
-#include <net/net.h>
-#include <net/ethernet.h>
-#include <net/net_var.h>
-#include <net/net_timer.h>
 
 #include <netinet/in.h>
 #include <netinet/in_itron.h>
-#include <netinet/ip.h>
-#include <netinet/ip6.h>
-#include <netinet/tcp.h>
 
 #include <netapp/netapp.h>
 #include <netapp/netapp_var.h>
-#include <netapp/echo.h>
+#include <netapp/tcp_echo_cli.h>
 
 #ifdef USE_TCP_ECHO_CLI
@@ -96,45 +84,44 @@
 #endif	/* of #ifdef USE_TCP_EXTENTIONS */
 
-/* 表示 */
-
-//#define SHOW_RCV_RANGE
-
-/* タイムアウト */
-
-#define CON_TMO		TMO_FEVR
-//#define CON_TMO		(60*SYSTIM_HZ)
-//#define CLS_TMO		TMO_FEVR				/* Close Wait は標準で 60秒 */
-#define CLS_TMO		(70*SYSTIM_HZ+(net_rand()%SYSTIM_HZ)*10)
-//#define RCV_TMO		TMO_FEVR
-#define RCV_TMO		(40*SYSTIM_HZ+(net_rand()%SYSTIM_HZ)*20)
-//#define SND_TMO		TMO_FEVR
-#define SND_TMO		(30*SYSTIM_HZ+(net_rand()%SYSTIM_HZ)*30)
-
 /* 送信間隔 */
 
-//#define SND_DLY			ULONG_C(500)
-#define SND_ITV		(5*SYSTM_HZ)
+#ifdef TOPPERS_S810_CLG3_85
+
+//#define SND_DLY		(500)
+#define START_DLY	(10*SYSTIM_HZ)
+#define SND_ITV		(5*SYSTIM_HZ)
+#define SLP_ITV		(30*SYSTIM_HZ)
+
+#else	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+//#define SND_DLY		(500)
+#define START_DLY	(10*SYSTIM_HZ)
+#define SND_ITV		(5*SYSTIM_HZ)
 #define SLP_ITV		(60*SYSTIM_HZ)
 
+#endif	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
 /* 自動実行 */
 
+#if defined(TCP_ECHO_CLI_AUTO_RUN_STR)
+#else
 #if 0
 #if defined(SUPPORT_INET6)
-#define AUTO_RUN_STR	"fe80::211:2fff:fe8a:e8c0 - 0"
-#else
-#define AUTO_RUN_STR	"172.25.193.140 - 0"
-#endif
-#endif
-
-/*
- *  バッファサイズの定義
- */
-
-#define NUM_ECHO		20
-#define NUM_REP_PAT		20
-#define PAT_BEGIN		' '
-#define PAT_END			'~'
-#define SND_BUF_SIZE		((PAT_END - PAT_BEGIN + 1) * NUM_REP_PAT)
-#define RCV_BUF_SIZE		(SND_BUF_SIZE*15/10)
+#define TCP_ECHO_CLI_AUTO_RUN_STR	"fd90:cce5:25f6:ff81:201:2ff:fe81:e7c9 - 0"
+#else
+#define TCP_ECHO_CLI_AUTO_RUN_STR	"172.25.129.140 - 0"
+#endif
+#endif
+#endif
+
+#if defined(SUPPORT_INET6)
+#if defined(SUPPORT_INET4)
+#define API_PROTO		'n'
+#else
+#define API_PROTO		'6'
+#endif
+#else
+#define API_PROTO		'4'
+#endif
 
 /*
@@ -142,5 +129,6 @@
  */
 
-bool_t tcp_echo_cli_valid;
+bool_t	tcp_echo_cli_valid;
+uint_t	tcp_echo_cli_scount;
 
 /* TCP 送受信ウィンドバッファ */
@@ -154,19 +142,11 @@
 #endif
 
-/*
- *  変数
- */
-
-static uint_t	scount;
-static uint_t	rcount;
-
 #ifdef USE_TCP_NON_BLOCKING
 
-static T_IPEP	nblk_src = {
-			IP_ADDRANY,
-			TCP_PORTANY,
-			};
-static T_IPEP	nblk_dst;
-static ER_UINT	nblk_error;
+/*
+ *  全域変数
+ */
+
+ER_UINT	tcp_echo_cli_nblk_error;
 
 /*
@@ -179,5 +159,5 @@
 	ER	error = E_OK;
 
-	nblk_error = *(ER*)p_parblk;
+	tcp_echo_cli_nblk_error = *(ER*)p_parblk;
 
 	switch (fncd) {
@@ -188,26 +168,31 @@
 
 	case TFN_TCP_RCV_BUF:
-		if (nblk_error < 0)
-			syslog(LOG_NOTICE, "[TEC:%02d CBN] rcv buf error: %s", cepid, itron_strerror(nblk_error));
+		if (tcp_echo_cli_nblk_error < 0)
+			syslog(LOG_NOTICE, "[TEC%c:%02u CBN] error: %s",
+			                   API_PROTO, cepid, itron_strerror(tcp_echo_cli_nblk_error));
 		syscall(sig_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
 		break;
 
 	case TFN_TCP_CLS_CEP:
-		if (nblk_error < 0)
-			syslog(LOG_NOTICE, "[TEC:%02d CBN] close error: %s", cepid, itron_strerror(nblk_error));
+		if (tcp_echo_cli_nblk_error < 0)
+			syslog(LOG_NOTICE, "[TEC%c:%02u CBN] error: %s",
+			                   API_PROTO, cepid, itron_strerror(tcp_echo_cli_nblk_error));
 		syscall(sig_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
 		break;
 
 	case TFN_TCP_RCV_DAT:
-		if (nblk_error < 0)
-			syslog(LOG_NOTICE, "[TEC:%02d CBN] rcv dat error: %s", cepid, itron_strerror(nblk_error));
+		if (tcp_echo_cli_nblk_error < 0)
+			syslog(LOG_NOTICE, "[TEC%c:%02u CBN] error: %s",
+			                   API_PROTO, cepid, itron_strerror(tcp_echo_cli_nblk_error));
 		syscall(sig_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
 		break;
 
 	case TFN_TCP_SND_OOB:
-		if (nblk_error > 0)
-			syslog(LOG_NOTICE, "[TEC:%02d CBN] snd urg: %4d", cepid, nblk_error);
+		if (tcp_echo_cli_nblk_error > 0)
+			syslog(LOG_NOTICE, "[TEC%c:%02u CBN] snd urg: %4u",
+			                   API_PROTO, cepid, tcp_echo_cli_nblk_error);
 		else
-			syslog(LOG_NOTICE, "[TEC:%02d CBN] snd urg error: %s", cepid, itron_strerror(nblk_error));
+			syslog(LOG_NOTICE, "[TEC%c:%02u CBN] error: %s",
+			                   API_PROTO, cepid, itron_strerror(tcp_echo_cli_nblk_error));
 		break;
 
@@ -222,447 +207,4 @@
 	}
 
-/*
- *  send_tcp_echo -- ECHO/TCP サーバにメッセージを送信する。
- */
-
-static ER
-send_tcp_echo (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno)
-{
-	static char smsg[SND_BUF_SIZE];
-
-	ER_UINT		slen;
-	ER		error;
-	SYSTIM		time;
-	uint32_t	total;
-	uint16_t	soff, echo, rep;
-	char		*p, pat;
-
-#ifdef SND_URG_DATA_SIZE
-	int_t	urg = SND_URG_COUNT;
-#endif
-
-	nblk_dst.ipaddr = *ipaddr;
-	nblk_dst.portno = portno;
-
-	p = smsg;
-	for (rep = NUM_REP_PAT; rep -- > 0; )
-		for (pat = PAT_BEGIN; pat <= PAT_END; pat ++)
-			*p ++ = pat;
-
-	if ((error = TCP_CON_CEP(cepid, &nblk_src, &nblk_dst, TMO_NBLK)) != E_WBLK) {
-		syslog(LOG_NOTICE, "[TEC:%02d SND] connect error: %s", cepid, itron_strerror(error));
-		return error;
-		}
-
-	/* 接続が完了するまで待つ。*/
-	syscall(wai_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
-
-	if (nblk_error != E_OK)
-		syslog(LOG_NOTICE, "[TEC:%02d SND] connect error: %s", cepid, itron_strerror(nblk_error));
-	else {
-		get_tim(&time);
-		syslog(LOG_NOTICE, "[TEC:%02d SND] connecting: %6lu, to:   %s.%u",
-		                   cepid, time / SYSTIM_HZ, IP2STR(NULL, ipaddr), nblk_dst.portno);
-
-		if ((error = psnd_dtq(DTQ_TCP_ECHO_CLI_RCV, (intptr_t)cepid)) != E_OK) {
-			syslog(LOG_NOTICE, "[TEC:%02d SND] sync error: %s", cepid, itron_strerror(error));
-			goto cls_ret;
-			}
-
-		scount = total = 0;
-		for (echo = NUM_ECHO; echo -- > 0; ) {
-			soff = 0;
-			while (soff < SND_BUF_SIZE) {
-				if ((slen = tcp_snd_dat(cepid, smsg + soff, sizeof(smsg) - soff, SND_TMO)) < 0) {
-					syslog(LOG_NOTICE, "[TEC:%02d SND] snd dat error: %s",
-					                   cepid, itron_strerror(slen));
-					goto cls_ret;
-					}
-				soff  += (uint16_t)slen;
-				total +=     slen;
-				scount ++;
-#ifdef SHOW_RCV_RANGE
-				syslog(LOG_NOTICE, "[TEC:%02d SND] send cnt: %2d, len: %4d, off: %4d",
-				                   cepid, scount, (uint16_t)slen, soff);
-#endif	/* of #ifdef SHOW_RCV_RANGE */
-
-#ifdef SND_URG_DATA_SIZE
-				if (urg) {
-					if (urg == 1) {
-						if ((error = tcp_snd_oob(cepid, smsg, SND_URG_DATA_SIZE, TMO_NBLK)) != E_WBLK)
-							syslog(LOG_NOTICE, "[TEC:%02d SND] snd urg error: %s",
-							                   cepid, itron_strerror(error));
-						}
-					urg --;
-					}
-#endif	/* of #ifdef SND_URG_DATA_SIZE */
-
-#if SND_DLY > 0
-				syscall(dly_tsk(SND_DLY + net_rand() % SYSTIM_HZ));
-#endif
-				}
-			}
-
-	cls_ret:
-		if ((error = tcp_sht_cep(cepid)) < 0)
-			syslog(LOG_NOTICE, "[TEC:%02d SND] shutdown error: %s", cepid, itron_strerror(error));
-
-		/* 受信が完了するまで待つ。*/
-		syscall(slp_tsk());
-		}
-
-	return error;
-	}
-
-/*
- *  TCP ECHO クライアント受信タスク
- */
-
-#ifdef USE_COPYSAVE_API
-
-void
-tcp_echo_cli_rcv_task (intptr_t exinf)
-{
-	ID		tskid, cepid;
-	ER		error;
-	SYSTIM		time;
-	uint32_t	total;
-	uint16_t	roff, rlen;
-	char		*rmsg, head, tail;
-
-	get_tid(&tskid);
-	syslog(LOG_NOTICE, "[TCP ECHO CLI (NBLK,CS) RCV:%d] started.", tskid);
-	while (true) {
-		if ((error = rcv_dtq(DTQ_TCP_ECHO_CLI_RCV, (intptr_t*)&cepid)) != E_OK) {
-			syslog(LOG_NOTICE, "[TEC:%02d RCV] sync error: %s",
-			                   cepid, itron_strerror(error));
-			}
-                else {
-			roff = rcount = total = 0;
-			while (true) {
-				if ((error = tcp_rcv_buf(cepid, (void**)&rmsg, TMO_NBLK)) != E_WBLK) {
-					syslog(LOG_NOTICE, "[TEC:%02d RCV] rcv buf error: %s", cepid, itron_strerror(error));
-					break;
-					}
-
-				/* 受信バッファの獲得が完了するまで待つ。*/
-				syscall(wai_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
-				if (nblk_error < 0)
-					break;
-
-				rlen = nblk_error;
-				head = *rmsg;
-				tail = *(rmsg + rlen - 1);
-				if (rlen > 0) {
-					roff  += rlen;
-					total += rlen;
-					rcount ++;
-#ifdef SHOW_RCV_RANGE
-					syslog(LOG_NOTICE, "[TEC:%02d RCV] "
-					                   "recv cnt: %2d, len: %4d, off: %4d, data: %02x -> %02x",
-					                   cepid, rcount, rlen, roff, head, tail);
-#endif	/* of #ifdef SHOW_RCV_RANGE */
-					}
-				else
-					break;
-
-				if ((error = tcp_rel_buf(cepid, rlen)) != E_OK)
-					syslog(LOG_NOTICE, "[TEC:%02d RCV] rel buf error: %s", 
-					                   cepid, itron_strerror(error));
-				}
-
-			if ((error = tcp_cls_cep(cepid, TMO_NBLK)) != E_WBLK && error != E_OK)
-				syslog(LOG_NOTICE, "[TEC:%02d SND] close error: %s", cepid, itron_strerror(error));
-
-			/* 切断が完了するまで待つ。*/
-			syscall(wai_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
-
-			get_tim(&time);
-			syslog(LOG_NOTICE, "[TEC:%02u RCV] finished:   %6lu, snd: %4u, rcv: %4u, len: %u",
-			                   cepid, time / SYSTIM_HZ, scount, rcount, total);
-			}
-
-		syscall(wup_tsk(TCP_ECHO_CLI_SND_TASK));
-		}
-	}
-
-#else	/* of #ifdef USE_COPYSAVE_API */
-
-void
-tcp_echo_cli_rcv_task (intptr_t exinf)
-{
-	static char rmsg[RCV_BUF_SIZE];
-
-	ID		tskid, cepid;
-	ER		error;
-	SYSTIM		time;
-	uint32_t	total;
-	uint16_t	roff, rlen;
-	char		head, tail;
-
-	get_tid(&tskid);
-	syslog(LOG_NOTICE, "[TCP ECHO CLI (NBLK) RCV:%d] started.", tskid);
-	while (true) {
-		if ((error = rcv_dtq(DTQ_TCP_ECHO_CLI_RCV, (intptr_t*)&cepid)) != E_OK) {
-			syslog(LOG_NOTICE, "[TEC:%02d RCV] sync error: %s",
-			                   cepid, itron_strerror(error));
-			}
-                else {
-			roff = rcount = total = 0;
-			while (true) {
-				if ((error = tcp_rcv_dat(cepid, rmsg, sizeof(rmsg), TMO_NBLK)) != E_WBLK) {
-					syslog(LOG_NOTICE, "[TEC:%02d RCV] rcv error: %s", cepid, itron_strerror(error));
-					break;
-					}
-
-				/* 受信が完了するまで待つ。*/
-				syscall(wai_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
-				if (nblk_error < 0)
-					break;
-
-				rlen = nblk_error;
-				head = *rmsg;
-				tail = *(rmsg + rlen - 1);
-				rcount ++;
-				if (rlen > 0) {
-					roff  += rlen;
-					total += rlen;
-#ifdef SHOW_RCV_RANGE
-					syslog(LOG_NOTICE, "[TEC:%02d RCV] "
-					                   "recv cnt: %2d, len: %4d, off: %4d, data: %02x -> %02x",
-					                   cepid, rcount, rlen, roff, head, tail);
-#endif	/* of #ifdef SHOW_RCV_RANGE */
-					}
-				else
-					break;
-				}
-
-			if ((error = tcp_cls_cep(cepid, TMO_NBLK)) != E_WBLK && error != E_OK)
-				syslog(LOG_NOTICE, "[TEC:%02d SND] close error: %s", cepid, itron_strerror(error));
-
-			/* 切断が完了するまで待つ。*/
-			syscall(wai_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
-
-			get_tim(&time);
-			syslog(LOG_NOTICE, "[TEC:%02u RCV] finished:   %6lu, snd: %4u, rcv: %4u, len: %u",
-			                   cepid, time / SYSTIM_HZ, scount, rcount, total);
-			}
-
-		syscall(wup_tsk(TCP_ECHO_CLI_SND_TASK));
-		}
-	}
-
-#endif	/* of #ifdef USE_COPYSAVE_API */
-
-#else	/* of #ifdef USE_TCP_NON_BLOCKING */
-
-/*
- *  send_tcp_echo -- ECHO/TCP サーバにメッセージを送信する。
- */
-
-static ER
-send_tcp_echo (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno)
-{
-	static char smsg[SND_BUF_SIZE];
-	static T_IPEP src = {
-		IP_ADDRANY,
-		TCP_PORTANY,
-		};
-
-	T_IPEP		dst;
-	ER_UINT		slen;
-	ER		error;
-	SYSTIM		time;
-	uint32_t	total;
-	uint16_t	soff, echo, rep;
-	char 		pat, *p;
-
-#ifdef SND_URG_DATA_SIZE
-	int_t	urg = SND_URG_COUNT;
-#endif
-
-	dst.ipaddr = *ipaddr;
-	dst.portno = portno;
-
-	p = smsg;
-	for (rep = NUM_REP_PAT; rep -- > 0; )
-		for (pat = PAT_BEGIN; pat <= PAT_END; pat ++)
-			*p ++ = pat;
-
-	if ((error = TCP_CON_CEP(cepid, &src, &dst, CON_TMO)) != E_OK) {
-		syslog(LOG_NOTICE, "[TEC:%02d SND] connect error: %s", cepid, itron_strerror(error));
-		return error;
-		}
-
-	get_tim(&time);
-	syslog(LOG_NOTICE, "[TEC:%02u SND] connecting: %6lu, to:   %s.%u",
-	                   cepid, time / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
-
-	if ((error = psnd_dtq(DTQ_TCP_ECHO_CLI_RCV, (intptr_t)cepid)) != E_OK) {
-		syslog(LOG_NOTICE, "[TEC:%02d SND] sync error: %s", cepid, itron_strerror(error));
-		goto cls_ret;
-		}
-
-	scount = total = 0;
-	for (echo = NUM_ECHO; echo -- > 0; ) {
-		soff = 0;
-		while (soff < SND_BUF_SIZE) {
-			if ((slen = tcp_snd_dat(cepid, smsg + soff, sizeof(smsg) - soff, SND_TMO)) < 0) {
-				syslog(LOG_NOTICE, "[TEC:%02d SND] snd dat error: %s", cepid, itron_strerror(slen));
-				goto cls_ret;
-				}
-			soff  += (uint16_t)slen;
-			total +=     slen;
-			scount ++;
-#ifdef SHOW_RCV_RANGE
-			syslog(LOG_NOTICE, "[TEC:%02d SND] send count: %3d, len: %4d, offset: %4d",
-			                   cepid, scount, (uint16_t)slen, soff);
-#endif	/* of #ifdef SHOW_RCV_RANGE */
-
-#ifdef SND_URG_DATA_SIZE
-			if (urg > 0) {
-				if (urg == 1) {
-					if ((slen = tcp_snd_oob(cepid, smsg, SND_URG_DATA_SIZE, SND_TMO)) >= 0)
-						syslog(LOG_NOTICE, "[TEC:%02d SND] snd urg: %4d",
-						                   cepid, (uint16_6)slen);
-					else
-						syslog(LOG_NOTICE, "[TEC:%02d SND] snd urg error: %s",
-						                   cepid, itron_strerror(slen));
-					}
-				urg --;
-				}
-#endif	/* of #ifdef SND_URG_DATA_SIZE */
-
-#if SND_DLY > 0
-			syscall(dly_tsk(SND_DLY + net_rand() % SYSTIM_HZ));
-#endif
-			}
-		}
-
-cls_ret:
-	if ((error = tcp_sht_cep(cepid)) < 0)
-		syslog(LOG_NOTICE, "[TEC:%02d SND] shutdown error: %s", cepid, itron_strerror(error));
-
-	/* 受信が完了するまで待つ。*/
-	syscall(slp_tsk());
-
-	return error;
-	}
-
-/*
- *  TCP ECHO クライアント受信タスク
- */
-
-#ifdef USE_COPYSAVE_API
-
-void
-tcp_echo_cli_rcv_task (intptr_t exinf)
-{
-	ID		tskid, cepid;
-	ER_UINT		rlen;
-	ER		error;
-	SYSTIM		time;
-	uint32_t	total;
-	uint16_t	roff;
-	char		*rmsg;
-
-	get_tid(&tskid);
-	syslog(LOG_NOTICE, "[TCP ECHO CLI (CS) RCV:%d] started.", tskid);
-	while (true) {
-		if ((error = rcv_dtq(DTQ_TCP_ECHO_CLI_RCV, (intptr_t*)&cepid)) != E_OK) {
-			syslog(LOG_NOTICE, "[TEC:%02d RCV] sync error: %s",
-			                   cepid, itron_strerror(error));
-			}
-		else {
-			roff = rcount = total = 0;
-			while (true) {
-				if ((rlen = tcp_rcv_buf(cepid, (void**)&rmsg, RCV_TMO)) < 0) {
-					syslog(LOG_NOTICE, "[TEC:%02d RCV] rcv buf error: %s",
-					                   cepid, itron_strerror(rlen));
-					break;
-					}
-				else if (rlen > 0) {
-					roff  += (uint16_t)rlen;
-					total +=     rlen;
-					rcount ++;
-#ifdef SHOW_RCV_RANGE
-					syslog(LOG_NOTICE, "[TEC:%02d RCV] recv count: %3d, len: %4d, data: %02x -> %02x",
-					                   cepid, rcount, (uint16_t)rlen, *rmsg, *(rmsg + rlen - 1));
-#endif	/* of #ifdef SHOW_RCV_RANGE */
-					}
-				else
-					break;
-				if ((error = tcp_rel_buf(cepid, rlen)) != E_OK)
-					syslog(LOG_NOTICE, "[TEC:%02d RCV] rel buf error: %s", cepid, itron_strerror(error));
-				}
-
-			if ((error = tcp_cls_cep(cepid, CLS_TMO)) < 0)
-				syslog(LOG_NOTICE, "[TEC:%02d RCV] close error: %s", cepid, itron_strerror(error));
-
-			get_tim(&time);
-			syslog(LOG_NOTICE, "[TEC:%02u RCV] finished:   %6lu, snd: %4u, rcv: %4u, len: %u",
-			                   cepid, time / SYSTIM_HZ, scount, rcount, total);
-			}
-
-		syscall(wup_tsk(TCP_ECHO_CLI_SND_TASK));
-		}
-	}
-
-#else	/* of #ifdef USE_COPYSAVE_API */
-
-void
-tcp_echo_cli_rcv_task (intptr_t exinf)
-{
-	static char rmsg[RCV_BUF_SIZE];
-
-	ID		tskid, cepid;
-	ER_UINT		rlen;
-	ER		error;
-	SYSTIM		time;
-	uint32_t	total;
-	uint16_t	roff;
-
-	get_tid(&tskid);
-	syslog(LOG_NOTICE, "[TCP ECHO CLI RCV:%d] started.", tskid);
-	while (true) {
-		if ((error = rcv_dtq(DTQ_TCP_ECHO_CLI_RCV, (intptr_t*)&cepid)) != E_OK) {
-			syslog(LOG_NOTICE, "[TEC:%02d RCV] sync error: %s",
-			                   cepid, itron_strerror(error));
-			}
-                else {
-			roff = rcount = total = 0;
-			while (true) {
-				if ((rlen = tcp_rcv_dat(cepid, rmsg, sizeof(rmsg), RCV_TMO)) < 0) {
-					syslog(LOG_NOTICE, "[TEC:%02d RCV] rcv dat error: %s", cepid, itron_strerror(rlen));
-					tcp_can_cep(cepid, TFN_TCP_ALL);
-					break;
-					}
-				else if (rlen > 0) {
-					roff  += (uint16_t)rlen;
-					total +=     rlen;
-					rcount ++;
-#ifdef SHOW_RCV_RANGE
-					syslog(LOG_NOTICE, "[TEC:%02d RCV] recv count: %3d, len: %4d, data: %02x -> %02x",
-					                   cepid, rcount, (uint16_t)rlen, *rmsg, *(rmsg + rlen - 1));
-#endif	/* of #ifdef SHOW_RCV_RANGE */
-					}
-				else
-					break;
-				}
-
-			if ((error = tcp_cls_cep(cepid, CLS_TMO)) < 0)
-				syslog(LOG_NOTICE, "[TEC:%02d RCV] close error: %s", cepid, itron_strerror(error));
-
-			get_tim(&time);
-			syslog(LOG_NOTICE, "[TEC:%02u RCV] received:   %6lu, snd: %4u, rcv: %4u, len: %u",
-			                   cepid, time / SYSTIM_HZ, scount, rcount, total);
-			}
-
-		syscall(wup_tsk(TCP_ECHO_CLI_SND_TASK));
-		}
-	}
-
-#endif	/* of #ifdef USE_COPYSAVE_API */
-
 #endif	/* of #ifdef USE_TCP_NON_BLOCKING */
 
@@ -671,15 +213,15 @@
  */
 
-#ifdef AUTO_RUN_STR
+#ifdef TCP_ECHO_CLI_AUTO_RUN_STR
 
 static char *
-getcomd (ID cepid)
+getcomd (ID cepid, bool_t retry, char *apip)
 {
 	ER		error;
 	char		*line = NULL;
-	static char	auto_run_str[] = AUTO_RUN_STR;
+	static char	auto_run_str[] = TCP_ECHO_CLI_AUTO_RUN_STR;
 	static int_t	count = 0;
 
-	if (count == 0) {
+	if (retry || (count == 0)) {
 		line = auto_run_str;
 		dly_tsk(3 * 1000);
@@ -687,5 +229,5 @@
 	else {
 		while ((error = rcv_dtq(DTQ_TCP_ECHO_CLI_SND, (intptr_t*)&line)) != E_OK) {
-			syslog(LOG_NOTICE, "[TEC:%02d TSK] error: %s", cepid, itron_strerror(error));
+			syslog(LOG_NOTICE, "[TEC%c:%02u TSK] error: %s", API_PROTO, cepid, itron_strerror(error));
 			dly_tsk(SLP_ITV);
 			}
@@ -696,8 +238,8 @@
 	}
 
-#else	/* of #ifdef AUTO_RUN_STR */
+#else	/* of #ifdef TCP_ECHO_CLI_AUTO_RUN_STR */
 
 static char *
-getcomd (ID cepid)
+getcomd (ID cepid, bool_t retry, char *apip)
 {
 	ER	error;
@@ -705,15 +247,48 @@
 
 	while ((error = rcv_dtq(DTQ_TCP_ECHO_CLI_SND, (intptr_t*)&line)) != E_OK) {
-		syslog(LOG_NOTICE, "[TEC:%02d TSK] error: %s", cepid, itron_strerror(error));
+		syslog(LOG_NOTICE, "[TEC%c:%02u TSK] error: %s", API_PROTO, cepid, itron_strerror(error));
 		dly_tsk(SLP_ITV);
 		}
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+	if (*line == '6') {
+		line ++;
+		*apip = API_PROTO_IPV6;
+		}
+	else if (*line == '4') {
+		line ++;
+		*apip = API_PROTO_IPV4;
+		}
+	else {
+		*apip= DEFAULT_API_PROTO;
+		if (*line && *line != ' ')
+			line ++;
+		}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+	*apip= DEFAULT_API_PROTO;
+	if (*line && *line != ' ')
+		line ++;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
 	return line;
 	}
 
-#endif	/* of #ifdef AUTO_RUN_STR */
+#endif	/* of #ifdef TCP_ECHO_CLI_AUTO_RUN_STR */
 
 /*
  *  TCP ECHO クライアント送信タスク
  */
+
+/*
+ *  IP アドレスの指定
+ */
+
+#define ADDR_IPVn	'n'
+#define ADDR_IPV6	'6'
+#define ADDR_IPV4	'4'
 
 void
@@ -723,7 +298,9 @@
 	ER		error;
 	T_IN_ADDR	addr;
+	char		*line;
+	int_t		rep, count;
+	bool_t		retry = false;
 	uint16_t	portno;
-	int_t		rep, count;
-	char		*line;
+	char		apip;
 
 #ifdef USE_TCP_EXTENTIONS
@@ -733,11 +310,58 @@
 #endif	/* of #ifdef USE_TCP_EXTENTIONS */
 
+#ifdef TCP_ECHO_CLI_AUTO_RUN_STR
+	dly_tsk(START_DLY);
+#endif
 	get_tid(&tskid);
-	syslog(LOG_NOTICE, "[TCP ECHO CLI SND:%d,%d] started.", tskid, (ID)exinf);
+	syslog(LOG_NOTICE, "[TCP%c ECHO CLI SND:%d,%d] started.", DEFAULT_API_PROTO, tskid, (ID)exinf);
 	while (true) {
-		line = getcomd((ID)exinf);
-		line = skip_blanks(GET_IPADDR(&addr, skip_blanks(line)));	/* IP Address */
-
-		if ('0' <= *line && *line <= '9') {				/* Port No */
+		line = skip_blanks(getcomd((ID)exinf, retry, &apip));
+
+#if defined(SUPPORT_INET6) && !defined(SUPPORT_INET4) && !defined(API_CFG_IP4MAPPED_ADDR)
+
+		if (apip == API_PROTO_IPV4) {
+			syslog(LOG_NOTICE, "[TEC%c:%02u TSK] error: E_PAR", API_PROTO, (ID)exinf);
+			retry = true;
+			continue;
+			}
+
+#endif	/* of #if defined(SUPPORT_INET6) && !defined(SUPPORT_INET4) && !defined(API_CFG_IP4MAPPED_ADDR) */
+
+		if ((line = lookup_ipaddr(&addr, line, apip)) == NULL) {
+			syslog(LOG_NOTICE, "[TEC%c:%02u TSK] sleep %d.%03u[s], unknown host.",
+			       API_PROTO, (ID)exinf, SLP_ITV / SYSTIM_HZ, SLP_ITV % SYSTIM_HZ);
+			dly_tsk(SLP_ITV);
+			syslog(LOG_NOTICE, "[TEC%c:%02u TSK] resume.", API_PROTO, (ID)exinf);
+			retry = true;
+			continue;
+			}
+		else
+			retry = false;
+
+#if defined(SUPPORT_INET6)
+
+#if defined(USE_TCP4_ECHO_CLI)
+
+#else	/* of #if defined(USE_TCP4_ECHO_CLI) */
+
+		if (in6_is_addr_ipv4mapped(&addr))
+			apip = API_PROTO_IPV4;
+		else
+			apip = API_PROTO_IPV6;
+
+#endif	/* of #if defined(USE_TCP4_ECHO_CLI) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+		if (apip == API_PROTO_IPV6) {
+			syslog(LOG_NOTICE, "[TEC%c:%02u TSK] error: E_PAR", API_PROTO, (ID)exinf);
+			retry = true;
+			continue;
+			}
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+		line = skip_blanks(line);
+		if ('0' <= *line && *line <= '9') {	/* Port No */
 			line = get_int(&rep, line);
 			portno = (uint16_t)rep;
@@ -749,8 +373,10 @@
 
 		line = skip_blanks(line);
-		if ('0' <= *line && *line <= '9')				/* Repeat */
+		if ('0' <= *line && *line <= '9')	/* Repeat */
 			line = get_int(&rep, line);
-		else
+		else {
+			line ++;
 			rep = 1;
+			}
 
 #ifdef USE_TCP_EXTENTIONS
@@ -776,12 +402,42 @@
 #endif
 
-		if ((error = alloc_tcp_cep(&cepid, tskid, &ccep)) != E_OK) {
-			syslog(LOG_NOTICE, "[TEC:%02d TSK] CEP create error: %s", cepid, itron_strerror(error));
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+		if (apip == API_PROTO_IPV6) {
+			if ((error = alloc_tcp6_cep(&cepid, tskid, &ccep)) != E_OK) {
+				syslog(LOG_NOTICE, "[TEC%c:%02u TSK] error: %s", apip, cepid, itron_strerror(error));
+				continue;
+				}
+			}
+		else {
+			if ((error = alloc_tcp4_cep(&cepid, tskid, &ccep)) != E_OK) {
+				syslog(LOG_NOTICE, "[TEC%c:%02u TSK] error: %s", apip, cepid, itron_strerror(error));
+				continue;
+				}
+			}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+		if ((error = ALLOC_TCP_CEP(&cepid, tskid, &ccep)) != E_OK) {
+			syslog(LOG_NOTICE, "[TEC%c:%02u TSK] error: %s", apip, cepid, itron_strerror(error));
 			continue;
 			}
 
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
 #else	/* of #ifdef USE_TCP_EXTENTIONS */
 
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+		if (apip == API_PROTO_IPV6)
+			cepid = (ID)exinf;
+		else
+			cepid = TCP4_ECHO_CLI_CEPID;
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
 		cepid = (ID)exinf;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
 
 #endif	/* of #ifdef USE_TCP_EXTENTIONS */
@@ -791,5 +447,5 @@
 		while (rep == 0 || count < rep) {
 			if (!tcp_echo_cli_valid) {
-				syslog(LOG_NOTICE, "[TEC:%02d TSK] canceled.", cepid);
+				syslog(LOG_NOTICE, "[TEC%c:%02u TSK] canceled.", apip, cepid);
 				break;
 				}
@@ -797,28 +453,28 @@
 			count ++;
 			if (rep == 0) {
-				syslog(LOG_NOTICE, "[TEC:%02d TSK] start:              repeat: %d", cepid, count);
-				error = send_tcp_echo(cepid, &addr, portno);
-				syslog(LOG_NOTICE, "[TEC:%02d TSK] finished:           repeat: %d", cepid, count);
+				syslog(LOG_NOTICE, "[TEC%c:%02u TSK] start:       repeat: %d", apip, cepid, count);
+				error = tcp_echo_cli_snd(cepid, &addr, portno, apip);
+				syslog(LOG_NOTICE, "[TEC%c:%02u TSK] finsh:       repeat: %d", apip, cepid, count);
 				}
 			else {
-				syslog(LOG_NOTICE, "[TEC:%02d TSK] start:              repeat: %d/%d", cepid, count, rep);
-				error = send_tcp_echo(cepid, &addr, portno);
-				syslog(LOG_NOTICE, "[TEC:%02d TSK] finished:           repeat: %d/%d", cepid, count, rep);
+				syslog(LOG_NOTICE, "[TEC%c:%02u TSK] start:       repeat: %d/%d", apip, cepid, count, rep);
+				error = tcp_echo_cli_snd(cepid, &addr, portno, apip);
+				syslog(LOG_NOTICE, "[TEC%c:%02u TSK] finsh:       repeat: %d/%d", apip, cepid, count, rep);
 				}
 
 			if (error != E_OK) {
-				syslog(LOG_NOTICE, "[TEC:%02d TSK] sleep %d[ms], error: %s",
-				                   cepid, SLP_ITV, itron_strerror(error));
+				syslog(LOG_NOTICE, "[TEC%c:%02u TSK] sleep %d.%03u[s], error: %s",
+				                   apip, cepid, SLP_ITV / SYSTIM_HZ, SLP_ITV % SYSTIM_HZ, itron_strerror(error));
 				tslp_tsk(SLP_ITV);
-				syslog(LOG_NOTICE, "[TEC:%02d TSK] resume.", cepid);
+				syslog(LOG_NOTICE, "[TEC%c:%02u TSK] resume.", apip, cepid);
 				}
 
 #if defined(SND_ITV)
 #if SND_ITV > 0
-			if (count > 0) {
+			if (count < rep) {
 				uint_t itv;
 				
 				itv = SND_ITV;
-				syslog(LOG_NOTICE, "[TEC:%02d TSK] interval: %d[ms].", cepid, itv);
+				syslog(LOG_NOTICE, "[TEC%c:%02u TSK] interval: %d[s].", apip, cepid, itv / SYSTIM_HZ);
 				syscall(dly_tsk(SND_ITV));
 				}
@@ -829,6 +485,6 @@
 #ifdef USE_TCP_EXTENTIONS
 
-		if ((error = free_tcp_cep(cepid)) != E_OK)
-			syslog(LOG_NOTICE, "[TEC:%02d TSK] CEP delete error: %s", cepid, itron_strerror(error));
+		if ((error = FREE_TCP_CEP(cepid)) != E_OK)
+			syslog(LOG_NOTICE, "[TEC%c:%02u TSK] error: %s", apip, cepid, itron_strerror(error));
 
 #endif	/* of #ifdef USE_TCP_EXTENTIONS */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli.h	(revision 331)
@@ -0,0 +1,133 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _TCP_ECHO_CLI_H_
+#define _TCP_ECHO_CLI_H_
+
+/* ã¹ã¿ãã¯ãµã¤ãº */
+
+#ifdef TOPPERS_S810_CLG3_85
+
+#define TCP_ECHO_CLI_RCV_STACK_SIZE	512		/* TCP ECHO ã¯ã©ã¤ã¢ã³ãåä¿¡ã¿ã¹ã¯ã®ã¹ã¿ãã¯ãµã¤ãº	*/
+#define TCP_ECHO_CLI_SND_STACK_SIZE	512		/* TCP ECHO ã¯ã©ã¤ã¢ã³ãéä¿¡ã¿ã¹ã¯ã®ã¹ã¿ãã¯ãµã¤ãº	*/
+
+#else	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+#define TCP_ECHO_CLI_RCV_STACK_SIZE	1024		/* TCP ECHO ã¯ã©ã¤ã¢ã³ãåä¿¡ã¿ã¹ã¯ã®ã¹ã¿ãã¯ãµã¤ãº	*/
+#define TCP_ECHO_CLI_SND_STACK_SIZE	1024		/* TCP ECHO ã¯ã©ã¤ã¢ã³ãéä¿¡ã¿ã¹ã¯ã®ã¹ã¿ãã¯ãµã¤ãº	*/
+
+#endif	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+/* åªå
+åº¦ */
+
+#define TCP_ECHO_CLI_RCV_MAIN_PRIORITY	5		/* TCP ECHO ã¯ã©ã¤ã¢ã³ãåä¿¡ã¿ã¹ã¯ã®åªå
+åº¦		*/
+#define TCP_ECHO_CLI_SND_MAIN_PRIORITY	5		/* TCP ECHO ã¯ã©ã¤ã¢ã³ãéä¿¡ã¿ã¹ã¯ã®åªå
+åº¦		*/
+
+/*
+ *  TCP éåä¿¡ã¦ã¤ã³ããããã¡ãµã¤ãº
+ */
+
+#if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU)
+
+#if defined(SUPPORT_INET6)
+
+#define TCP_ECHO_CLI_SWBUF_SIZE		(1024)
+#define TCP_ECHO_CLI_RWBUF_SIZE		(1024)
+
+#elif defined(SUPPORT_INET4)
+
+#define TCP_ECHO_CLI_SWBUF_SIZE		(512)
+#define TCP_ECHO_CLI_RWBUF_SIZE		(512)
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#else	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+#define TCP_ECHO_CLI_SWBUF_SIZE		(2048)
+#define TCP_ECHO_CLI_RWBUF_SIZE		(2048)
+
+#endif	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+/*
+ *  ãããã¡ãµã¤ãºã®å®ç¾©
+ */
+
+#define NUM_ECHO		20
+#define NUM_REP_PAT		20
+#define PAT_BEGIN		' '
+#define PAT_END			'~'
+#define SND_BUF_SIZE		((PAT_END - PAT_BEGIN + 1) * NUM_REP_PAT)
+#define RCV_BUF_SIZE		(SND_BUF_SIZE*15/10)
+
+/*
+ *  å¤æ°
+ */
+
+extern bool_t	tcp_echo_cli_valid;
+extern uint_t	tcp_echo_cli_scount;
+extern ER_UINT	tcp_echo_cli_nblk_error;
+
+/* TCP éåä¿¡ãããã¡ */
+
+extern uint8_t tcp_echo_cli_swbuf[];
+extern uint8_t tcp_echo_cli_rwbuf[];
+
+/* ã¿ã¹ã¯*/
+
+extern void	tcp_echo_cli_rcv_task(intptr_t exinf);
+extern void	tcp_echo_cli_snd_task(intptr_t exinf);
+
+/* é¢æ° */
+
+extern ER callback_nblk_tcp_echo_cli (ID cepid, FN fncd, void *p_parblk);
+
+#ifdef T_IN_ADDR
+extern ER tcp_echo_cli_snd (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno, char apip);
+#endif
+
+#endif	/* of #ifndef _TCP_ECHO_CLI_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli_rcv.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli_rcv.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli_rcv.c	(revision 331)
@@ -0,0 +1,454 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TCP ECHO ã¯ã©ã¤ã¢ã³ãåä¿¡ã¿ã¹ã¯
+ */
+
+#include <stdlib.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/tcp_echo_cli.h>
+
+#ifdef USE_TCP_ECHO_CLI
+
+/* è¡¨ç¤º */
+
+//#define SHOW_TIME_OUT
+//#define SHOW_RCV_RANGE
+
+/* ã¿ã¤ã ã¢ã¦ã */
+
+#ifdef TOPPERS_S810_CLG3_85
+
+#define CLS_TMO		TMO_FEVR					/* Close Wait ã¯æ¨æºã§ 60ç§ */
+//#define RCV_TMO		TMO_FEVR
+#define RCV_TMO		(30*SYSTIM_HZ)
+
+#else	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+//#define CLS_TMO		TMO_FEVR				/* Close Wait ã¯æ¨æºã§ 60ç§ */
+#define CLS_TMO		(70*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*10)
+//#define RCV_TMO		TMO_FEVR
+#define RCV_TMO		(40*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*20)
+
+#endif	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+/*
+ *  API IPãã­ãã³ã«ã®æå®
+ */
+
+#undef  DEFAULT_API_PROTO
+
+#if defined(SUPPORT_INET6)
+#if defined(SUPPORT_INET4)
+#define DEFAULT_API_PROTO	API_PROTO_IPVn
+#else
+#define DEFAULT_API_PROTO	API_PROTO_IPV6
+#endif
+#else
+#define DEFAULT_API_PROTO	API_PROTO_IPV4
+#endif
+
+/*
+ *  TCP ECHO ã¯ã©ã¤ã¢ã³ãåä¿¡ã¿ã¹ã¯
+ */
+
+#ifdef USE_TCP_NON_BLOCKING
+
+#ifdef USE_COPYSAVE_API
+
+void
+tcp_echo_cli_rcv_task (intptr_t exinf)
+{
+	ID		tskid, cepid;
+	ER		error;
+	SYSTIM		time;
+	uint32_t	total, rcount;
+	uint16_t	roff, rlen;
+	char		*rmsg, head, tail, apip = DEFAULT_API_PROTO;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[TCP%c ECHO CLI (NBLK,CS) RCV:%d] started.", DEFAULT_API_PROTO, tskid);
+	while (true) {
+		if ((error = rcv_dtq(DTQ_TCP_ECHO_CLI_RCV, (intptr_t*)&cepid)) != E_OK) {
+			syslog(LOG_NOTICE, "[TEC%c:%02u DTQ] error: %s",
+			                   DEFAULT_API_PROTO, cepid, itron_strerror(error));
+			}
+                else {
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+#ifdef USE_TCP_EXTENTIONS
+
+			apip = API_PROTO_IPVn;
+
+#else	/* of #ifdef USE_TCP_EXTENTIONS */
+
+			if (cepid == TCP4_ECHO_CLI_CEPID)
+				apip = API_PROTO_IPV4;
+			else
+				apip = API_PROTO_IPV6;
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+			roff = rcount = total = 0;
+			while (true) {
+				if ((error = tcp_rcv_buf(cepid, (void**)&rmsg, TMO_NBLK)) != E_WBLK) {
+					syslog(LOG_NOTICE, "[TEC%c:%02u RCV] error: %s", apip, cepid, itron_strerror(error));
+					break;
+					}
+
+				/* åä¿¡ãããã¡ã®ç²å¾ãå®äºããã¾ã§å¾
+ã¤ã*/
+				syscall(wai_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
+				if (tcp_echo_cli_nblk_error < 0)
+					break;
+
+				rlen = tcp_echo_cli_nblk_error;
+				head = *rmsg;
+				tail = *(rmsg + rlen - 1);
+				if (rlen > 0) {
+					roff  += rlen;
+					total += rlen;
+					rcount ++;
+#ifdef SHOW_RCV_RANGE
+					syslog(LOG_NOTICE, "[TEC%c:%02u RCV] "
+					                   "count: %7lu, len: %4u, off: %4u, data: %02x -> %02x",
+					                   apip, cepid, rcount, rlen, roff, head, tail);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+					}
+				else
+					break;
+
+				if ((error = tcp_rel_buf(cepid, rlen)) != E_OK)
+					syslog(LOG_NOTICE, "[TEC%c:%02u REL] error: %s", 
+					                   apip, cepid, itron_strerror(error));
+				}
+
+			if ((error = tcp_cls_cep(cepid, TMO_NBLK)) != E_WBLK && error != E_OK)
+				syslog(LOG_NOTICE, "[TEC%c:%02u CLS] error: %s", apip, cepid, itron_strerror(error));
+
+			/* åæ­ãå®äºããã¾ã§å¾
+ã¤ã*/
+			syscall(wai_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
+
+			get_tim(&time);
+			syslog(LOG_NOTICE, "[TEC%c:%02u RCV] finsh: %7lu, ttl: %lu",
+			                   apip, cepid, time / SYSTIM_HZ, total);
+			}
+
+		syscall(wup_tsk(TCP_ECHO_CLI_SND_TASK));
+		}
+	}
+
+#else	/* of #ifdef USE_COPYSAVE_API */
+
+void
+tcp_echo_cli_rcv_task (intptr_t exinf)
+{
+	static char rmsg[RCV_BUF_SIZE];
+
+	ID		tskid, cepid;
+	ER		error;
+	SYSTIM		time;
+	uint32_t	total, rcount;
+	uint16_t	roff, rlen;
+	char		head, tail, apip = DEFAULT_API_PROTO;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[TCP%c ECHO CLI (NBLK) RCV:%d] started.", DEFAULT_API_PROTO, tskid);
+	while (true) {
+		if ((error = rcv_dtq(DTQ_TCP_ECHO_CLI_RCV, (intptr_t*)&cepid)) != E_OK) {
+			syslog(LOG_NOTICE, "[TEC%c:%02u DTQ] error: %s",
+			                   DEFAULT_API_PROTO, cepid, itron_strerror(error));
+			}
+                else {
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+			if (cepid == TCP4_ECHO_CLI_CEPID)
+				apip = API_PROTO_IPV4;
+			else
+				apip = API_PROTO_IPV6;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+			roff = rcount = total = 0;
+			while (true) {
+				if ((error = tcp_rcv_dat(cepid, rmsg, sizeof(rmsg), TMO_NBLK)) != E_WBLK) {
+					syslog(LOG_NOTICE, "[TEC%c:%02u RCV] error: %s", apip, cepid, itron_strerror(error));
+					break;
+					}
+
+				/* åä¿¡ãå®äºããã¾ã§å¾
+ã¤ã*/
+				syscall(wai_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
+				if (tcp_echo_cli_nblk_error < 0)
+					break;
+
+				rlen = tcp_echo_cli_nblk_error;
+				head = *rmsg;
+				tail = *(rmsg + rlen - 1);
+				rcount ++;
+				if (rlen > 0) {
+					roff  += rlen;
+					total += rlen;
+#ifdef SHOW_RCV_RANGE
+					syslog(LOG_NOTICE, "[TEC%c:%02u RCV] "
+					                   "count: %7lu, len: %4u, off: %4u, data: %02x -> %02x",
+					                   apip, cepid, rcount, rlen, roff, head, tail);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+					}
+				else
+					break;
+				}
+
+			if ((error = tcp_cls_cep(cepid, TMO_NBLK)) != E_WBLK && error != E_OK)
+				syslog(LOG_NOTICE, "[TEC%c:%02u CLS] error: %s", apip, cepid, itron_strerror(error));
+
+			/* åæ­ãå®äºããã¾ã§å¾
+ã¤ã*/
+			syscall(wai_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
+
+			get_tim(&time);
+			syslog(LOG_NOTICE, "[TEC%c:%02u RCV] finsh: %7lu, ttl: %lu",
+			                   apip, cepid, time / SYSTIM_HZ, total);
+			}
+
+		syscall(wup_tsk(TCP_ECHO_CLI_SND_TASK));
+		}
+	}
+
+#endif	/* of #ifdef USE_COPYSAVE_API */
+
+#else	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#ifdef USE_COPYSAVE_API
+
+void
+tcp_echo_cli_rcv_task (intptr_t exinf)
+{
+	ID		tskid, cepid;
+	ER_UINT		rlen;
+	ER		error;
+	SYSTIM		time, tmo;
+	uint32_t	total = 0, rcount;
+	uint16_t	roff;
+	char		*rmsg, apip = DEFAULT_API_PROTO;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[TCP%c ECHO CLI (CS) RCV:%d] started.", DEFAULT_API_PROTO, tskid);
+	while (true) {
+		if ((error = rcv_dtq(DTQ_TCP_ECHO_CLI_RCV, (intptr_t*)&cepid)) != E_OK) {
+			syslog(LOG_NOTICE, "[TEC%c:%02u DTQ] error: %s",
+			                   DEFAULT_API_PROTO, cepid, itron_strerror(error));
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+#ifdef USE_TCP_EXTENTIONS
+
+			if (tcp6_is_cepid(cepid))
+				apip = API_PROTO_IPV6;
+			else
+				apip = API_PROTO_IPV4;
+
+#else	/* of #ifdef USE_TCP_EXTENTIONS */
+
+			if (cepid == TCP4_ECHO_CLI_CEPID)
+				apip = API_PROTO_IPV4;
+			else
+				apip = API_PROTO_IPV6;
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+			}
+		else {
+			roff = rcount = total = 0;
+			while (true) {
+				tmo = RCV_TMO;
+#ifdef SHOW_TIME_OUT
+				syslog(LOG_NOTICE, "[TEC%c:%02u RCV] tmo:   %7lu", apip, cepid, tmo);;
+#endif	/* of #ifdef SHOW_TIME_OUT */
+				if ((rlen = tcp_rcv_buf(cepid, (void**)&rmsg, tmo)) < 0) {
+					syslog(LOG_NOTICE, "[TEC%c:%02u RCV] error: %s",
+					                   apip, cepid, itron_strerror(rlen));
+					break;
+					}
+				else if (rlen > 0) {
+					roff  += (uint16_t)rlen;
+					total +=     rlen;
+					rcount ++;
+#ifdef SHOW_RCV_RANGE
+					syslog(LOG_NOTICE, "[TEC%c:%02u RCV] count: %7lu, len: %4u, data: %02x -> %02x",
+					                   apip, cepid, rcount, (uint16_t)rlen, *rmsg, *(rmsg + rlen - 1));
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+					}
+				else
+					break;
+				if ((error = tcp_rel_buf(cepid, rlen)) != E_OK)
+					syslog(LOG_NOTICE, "[TEC%c:%02u REL] error: %s", apip, cepid, itron_strerror(error));
+				}
+
+			tmo = CLS_TMO;
+#ifdef SHOW_TIME_OUT
+			syslog(LOG_NOTICE, "[TEC%c:%02u CLS] tmo:   %7lu", apip, cepid, tmo);;
+#endif	/* of #ifdef SHOW_TIME_OUT */
+			if ((error = tcp_cls_cep(cepid, tmo)) < 0)
+				syslog(LOG_NOTICE, "[TEC%c:%02u CLS] error: %s", apip, cepid, itron_strerror(error));
+
+			get_tim(&time);
+			syslog(LOG_NOTICE, "[TEC%c:%02u RCV] finsh: %7lu, ttl: %lu",
+			                   apip, cepid, time / SYSTIM_HZ, total);
+			}
+
+		syscall(wup_tsk(TCP_ECHO_CLI_SND_TASK));
+		}
+	}
+
+#else	/* of #ifdef USE_COPYSAVE_API */
+
+void
+tcp_echo_cli_rcv_task (intptr_t exinf)
+{
+	static char rmsg[RCV_BUF_SIZE];
+
+	ID		tskid, cepid;
+	ER_UINT		rlen;
+	ER		error;
+	SYSTIM		time, tmo;
+	uint32_t	total, rcount;
+	uint16_t	roff;
+	char		apip = DEFAULT_API_PROTO;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[TCP%c ECHO CLI RCV:%d] started.", DEFAULT_API_PROTO, tskid);
+	while (true) {
+		if ((error = rcv_dtq(DTQ_TCP_ECHO_CLI_RCV, (intptr_t*)&cepid)) != E_OK) {
+			syslog(LOG_NOTICE, "[TEC%c:%02u DTQ] error: %s",
+			                   DEFAULT_API_PROTO, cepid, itron_strerror(error));
+			}
+                else {
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+			if (cepid == TCP4_ECHO_CLI_CEPID)
+				apip = API_PROTO_IPV4;
+			else
+				apip = API_PROTO_IPV6;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+			roff = rcount = total = 0;
+			while (true) {
+#ifdef SHOW_TIME_OUT
+				syslog(LOG_NOTICE, "[TEC%c:%02u RCV] tmo:   %7lu", apip, cepid, tmo);;
+#endif	/* of #ifdef SHOW_TIME_OUT */
+				tmo = RCV_TMO;
+				if ((rlen = tcp_rcv_dat(cepid, rmsg, sizeof(rmsg), tmo)) < 0) {
+					syslog(LOG_NOTICE, "[TEC%c:%02u RCV] error: %s", apip, cepid, itron_strerror(rlen));
+					tcp_can_cep(cepid, TFN_TCP_ALL);
+					break;
+					}
+				else if (rlen > 0) {
+					roff  += (uint16_t)rlen;
+					total +=     rlen;
+					rcount ++;
+#ifdef SHOW_RCV_RANGE
+					syslog(LOG_NOTICE, "[TEC%c:%02u RCV] count: %7lu, len: %4u, data: %02x -> %02x",
+					                   apip, cepid, rcount, (uint16_t)rlen, *rmsg, *(rmsg + rlen - 1));
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+					}
+				else
+					break;
+				}
+
+#ifdef SHOW_TIME_OUT
+			syslog(LOG_NOTICE, "[TEC%c:%02u CLS] tmo:   %7lu", apip, cepid, tmo);;
+#endif	/* of #ifdef SHOW_TIME_OUT */
+			tmo = CLS_TMO;
+			if ((error = tcp_cls_cep(cepid, tmo)) < 0)
+				syslog(LOG_NOTICE, "[TEC%c:%02u CLS] error: %s", apip, cepid, itron_strerror(error));
+
+			get_tim(&time);
+			syslog(LOG_NOTICE, "[TEC%c:%02u RCV] finsh: %7lu, ttl: %lu",
+			                   apip, cepid, time / SYSTIM_HZ, total);
+			}
+
+		syscall(wup_tsk(TCP_ECHO_CLI_SND_TASK));
+		}
+	}
+
+#endif	/* of #ifdef USE_COPYSAVE_API */
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#endif	/* of #ifdef USE_TCP_ECHO_CLI */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli_snd.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli_snd.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_cli_snd.c	(revision 331)
@@ -0,0 +1,499 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TCP ECHO ã¯ã©ã¤ã¢ã³ãéä¿¡é¢æ°
+ */
+
+#include <stdlib.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/tcp_echo_cli.h>
+
+#ifdef USE_TCP_ECHO_CLI
+
+/* è¡¨ç¤º */
+
+//#define SHOW_TIME_OUT
+//#define SHOW_SND_COUNT
+
+/* ã¿ã¤ã ã¢ã¦ã */
+
+#ifdef TOPPERS_S810_CLG3_85
+
+#define CON_TMO		TMO_FEVR
+//#define CON_TMO		(60*SYSTIM_HZ)
+//#define SND_TMO		TMO_FEVR
+#define SND_TMO		(30*SYSTIM_HZ)
+
+#else	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+#define CON_TMO		TMO_FEVR
+//#define CON_TMO		(60*SYSTIM_HZ)
+//#define SND_TMO		TMO_FEVR
+#define SND_TMO		(30*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*30)
+
+#endif	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+#ifdef USE_TCP_NON_BLOCKING
+
+/*
+ *  å¤æ°
+ */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+static T_IPV4EP	nblk_src4 = {
+			IPV4_ADDRANY,
+			TCP_PORTANY,
+			};
+static T_IPV4EP	nblk_dst4;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+static T_IPEP	nblk_src = {
+			IP_ADDRANY,
+			TCP_PORTANY,
+			};
+static T_IPEP	nblk_dst;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+/*
+ *  tcp4_active_open -- è½åãªã¼ãã³ãå®è¡ããã
+ *
+ *    USE_TCP_NON_BLOCKING	ON
+ */
+
+static ER
+tcp4_active_open (ID cepid, T_IN4_ADDR ipaddr, uint16_t portno)
+{
+	ER		error;
+	SYSTIM		time;
+
+	nblk_dst4.ipaddr = ipaddr;
+	nblk_dst4.portno = portno;
+
+	if ((error = tcp_con_cep(cepid, &nblk_src4, &nblk_dst4, TMO_NBLK)) != E_WBLK) {
+		syslog(LOG_NOTICE, "[TEC4:%02u CON] error: %s", cepid, itron_strerror(error));
+		return error;
+		}
+
+	/* æ¥ç¶ãå®äºããã¾ã§å¾
+ã¤ã*/
+	syscall(wai_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
+
+	if ((error = tcp_echo_cli_nblk_error) != E_OK) {
+		syslog(LOG_NOTICE, "[TEC4:%02u CON] error: %s", cepid, itron_strerror(tcp_echo_cli_nblk_error));
+		return error;
+		}
+
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[TEC4:%02u CON] conct: %7lu,  to: %s.%u",
+	                   cepid, time / SYSTIM_HZ, ip2str(NULL, &nblk_dst4.ipaddr), nblk_dst4.portno);
+	return error;
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+/*
+ *  tcp_active_open -- è½åãªã¼ãã³ãå®è¡ããã
+ *
+ *    USE_TCP_NON_BLOCKING	ON
+ */
+
+static ER
+tcp_active_open (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno, char apip)
+{
+	ER		error;
+	SYSTIM		time;
+
+	nblk_dst.ipaddr = *ipaddr;
+	nblk_dst.portno = portno;
+
+	if ((error = TCP_CON_CEP(cepid, &nblk_src, &nblk_dst, TMO_NBLK)) != E_WBLK) {
+		if (error == E_PAR || error == E_ID)
+			syslog(LOG_NOTICE, "[TEC%c:%02u CON] error: %s, API: IPv%c, addr: %s",
+			                   apip, cepid, itron_strerror(error), apip, IP2STR(NULL, ipaddr));
+		else
+			syslog(LOG_NOTICE, "[TEC%c:%02u CON] error: %s",
+			                   apip, cepid, itron_strerror(error));
+		return error;
+		}
+
+	/* æ¥ç¶ãå®äºããã¾ã§å¾
+ã¤ã*/
+	syscall(wai_sem(SEM_TCP_ECHO_CLI_NBLK_READY));
+
+	if ((error = tcp_echo_cli_nblk_error) != E_OK) {
+		syslog(LOG_NOTICE, "[TEC%c:%02u CON] error: %s",
+		                   apip, cepid, itron_strerror(tcp_echo_cli_nblk_error));
+		return error;
+		}
+
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[TEC%c:%02u CON] conct: %7lu,  to: %s.%u",
+	                   apip, cepid, time / SYSTIM_HZ,
+	                   IP2STR(NULL, &nblk_dst.ipaddr), nblk_dst.portno);
+	return error;
+	}
+
+/*
+ *  tcp_echo_cli_snd -- ECHO/TCP ãµã¼ãã«ã¡ãã»ã¼ã¸ãéä¿¡ããã
+ *
+ *    USE_TCP_NON_BLOCKING	ON
+ */
+
+ER
+tcp_echo_cli_snd (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno, char apip)
+{
+	static char smsg[SND_BUF_SIZE];
+
+	ER_UINT		slen;
+	ER		error;
+	uint32_t	total;
+	uint16_t	soff, echo, rep;
+	char		*p, pat;
+
+#ifdef SND_URG_DATA_SIZE
+	int_t	urg = SND_URG_COUNT;
+#endif
+
+	p = smsg;
+	for (rep = NUM_REP_PAT; rep -- > 0; )
+		for (pat = PAT_BEGIN; pat <= PAT_END; pat ++)
+			*p ++ = pat;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+	if (apip == API_PROTO_IPV6) {
+		if ((error = tcp_active_open(cepid, ipaddr, portno, apip)) != E_OK)
+			return error;
+		}
+	else if (in6_is_addr_ipv4mapped(ipaddr)) {
+		if ((error = tcp4_active_open(cepid, ntohl(ipaddr->s6_addr32[3]), portno)) != E_OK)
+			return error;
+		}
+	else {
+		if ((error = tcp_active_open(cepid, ipaddr, portno, apip)) != E_OK)
+			return error;
+		}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+	if ((error = tcp_active_open(cepid, ipaddr, portno, apip)) != E_OK)
+		return error;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+	if ((error = psnd_dtq(DTQ_TCP_ECHO_CLI_RCV, (intptr_t)cepid)) != E_OK) {
+		syslog(LOG_NOTICE, "[TEC%c:%02u DTQ] error: %s", apip, cepid, itron_strerror(error));
+		goto cls_ret;
+		}
+
+	tcp_echo_cli_scount = total = 0;
+	for (echo = NUM_ECHO; echo -- > 0; ) {
+		soff = 0;
+		while (soff < SND_BUF_SIZE) {
+#ifdef SHOW_TIME_OUT
+			syslog(LOG_NOTICE, "[TEC%c:%02u SND] tmo:   %7lu", apip, cepid, SND_TMO);;
+#endif/* of #ifdef SHOW_TIME_OUT */
+			if ((slen = tcp_snd_dat(cepid, smsg + soff, sizeof(smsg) - soff, SND_TMO)) < 0) {
+				syslog(LOG_NOTICE, "[TEC%c:%02u SND] error: %s",
+				                   apip, cepid, itron_strerror(slen));
+				error = slen;
+				goto cls_ret;
+				}
+			soff  += (uint16_t)slen;
+			total +=     slen;
+			tcp_echo_cli_scount ++;
+#ifdef SHOW_SND_COUNT
+			syslog(LOG_NOTICE, "[TEC%c:%02u SND] count: %7lu, len: %4u, off: %4u",
+			                   apip, cepid, tcp_echo_cli_scount, (uint16_t)slen, soff);
+#endif/* of #ifdef SHOW_SND_COUNT */
+
+#ifdef SND_URG_DATA_SIZE
+			if (urg) {
+				if (urg == 1) {
+					if ((error = tcp_snd_oob(cepid, smsg, SND_URG_DATA_SIZE, TMO_NBLK)) != E_WBLK)
+						syslog(LOG_NOTICE, "[TEC%c:%02u OOB] error: %s",
+						                   apip, cepid, itron_strerror(error));
+					}
+				urg --;
+				}
+#endif/* of #ifdef SND_URG_DATA_SIZE */
+
+#if defined(SND_DLY)
+#if SND_DLY > 0
+			syscall(dly_tsk(SND_DLY + netapp_rand() % SYSTIM_HZ));
+#endif
+#endif
+			}
+		}
+
+cls_ret:
+	if ((error = tcp_sht_cep(cepid)) < 0)
+		syslog(LOG_NOTICE, "[TEC%c:%02u SHT] error: %s", apip, cepid, itron_strerror(error));
+
+	/* åä¿¡ãå®äºããã¾ã§å¾
+ã¤ã*/
+	syscall(slp_tsk());
+
+	return error;
+	}
+
+#else	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+/*
+ *  tcp4_active_open -- è½åãªã¼ãã³ãå®è¡ããã
+ *
+ *    USE_TCP_NON_BLOCKING	OFF
+ */
+
+static ER
+tcp4_active_open (ID cepid, T_IN4_ADDR ipaddr, uint16_t portno)
+{
+	static T_IPV4EP src = {
+		IPV4_ADDRANY,
+		TCP_PORTANY,
+		};
+
+	T_IPV4EP	dst;
+	ER		error;
+	SYSTIM		time;
+
+	dst.ipaddr = ipaddr;
+	dst.portno = portno;
+
+#ifdef SHOW_TIME_OUT
+	syslog(LOG_NOTICE, "[TEC%c:%02u CON] tmo:   %7lu", API_PROTO_IPV4, cepid, CON_TMO);
+#endif	/* of #ifdef SHOW_TIME_OUT */
+	if ((error = tcp_con_cep(cepid, &src, &dst, CON_TMO)) != E_OK) {
+		syslog(LOG_NOTICE, "[TEC%c:%02u CON] error: %s, addr: %s",
+		                   API_PROTO_IPV4, cepid, itron_strerror(error), ip2str(NULL, &ipaddr));
+		return error;
+		}
+
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[TEC%c:%02u CON] conct: %7lu,  to: %s.%u",
+	                   API_PROTO_IPV4, cepid, time / SYSTIM_HZ, ip2str(NULL, &dst.ipaddr), dst.portno);
+	return error;
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+/*
+ *  tcp_active_open -- è½åãªã¼ãã³ãå®è¡ããã
+ *
+ *    USE_TCP_NON_BLOCKING	OFF
+ */
+
+static ER
+tcp_active_open (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno, char apip)
+{
+	static T_IPEP src = {
+		IP_ADDRANY,
+		TCP_PORTANY,
+		};
+
+	T_IPEP		dst;
+	ER		error;
+	SYSTIM		time;
+
+	dst.ipaddr = *ipaddr;
+	dst.portno = portno;
+
+#ifdef SHOW_TIME_OUT
+	syslog(LOG_NOTICE, "[TEC%c:%02u CON] tmo:   %7lu", apip, cepid, CON_TMO);
+#endif	/* of #ifdef SHOW_TIME_OUT */
+	if ((error = TCP_CON_CEP(cepid, &src, &dst, CON_TMO)) != E_OK) {
+		if (error == E_PAR || error == E_ID)
+			syslog(LOG_NOTICE, "[TEC%c:%02u CON] error: %s, API: IPv%c, addr: %s",
+			                   apip, cepid, itron_strerror(error), apip, IP2STR(NULL, ipaddr));
+		else
+			syslog(LOG_NOTICE, "[TEC%c:%02u CON] error: %s", apip, cepid, itron_strerror(error));
+		return error;
+		}
+
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[TEC%c:%02u CON] conct: %7lu,  to: %s.%u",
+	                   apip, cepid, time / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
+	return error;
+	}
+
+/*
+ *  tcp_echo_cli_snd -- ECHO/TCP ãµã¼ãã«ã¡ãã»ã¼ã¸ãéä¿¡ããã
+ *
+ *    USE_TCP_NON_BLOCKING	OFF
+ */
+
+ER
+tcp_echo_cli_snd (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno, char apip)
+{
+	static char smsg[SND_BUF_SIZE];
+
+	ER_UINT		slen;
+	ER		error;
+	uint32_t	total;
+	uint16_t	soff, echo, rep;
+	char		*p, pat;
+
+#ifdef SND_URG_DATA_SIZE
+	int_t	urg = SND_URG_COUNT;
+#endif
+
+	p = smsg;
+	for (rep = NUM_REP_PAT; rep -- > 0; )
+		for (pat = PAT_BEGIN; pat <= PAT_END; pat ++)
+			*p ++ = pat;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI)
+
+	if (apip == API_PROTO_IPV6) {
+		if ((error = tcp_active_open(cepid, ipaddr, portno, apip)) != E_OK)
+			return error;
+		}
+	else if (in6_is_addr_ipv4mapped(ipaddr)) {
+		if ((error = tcp4_active_open(cepid, ntohl(ipaddr->s6_addr32[3]), portno)) != E_OK)
+			return error;
+		}
+	else {
+		if ((error = tcp_active_open(cepid, ipaddr, portno, apip)) != E_OK)
+			return error;
+		}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+	if ((error = tcp_active_open(cepid, ipaddr, portno, apip)) != E_OK)
+		return error;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_CLI) */
+
+	if ((error = psnd_dtq(DTQ_TCP_ECHO_CLI_RCV, (intptr_t)cepid)) != E_OK) {
+		syslog(LOG_NOTICE, "[TEC%c:%02u DTQ] error: %s", apip, cepid, itron_strerror(error));
+		goto cls_ret;
+		}
+
+	tcp_echo_cli_scount = total = 0;
+	for (echo = NUM_ECHO; echo -- > 0; ) {
+		soff = 0;
+		while (soff < SND_BUF_SIZE) {
+#ifdef SHOW_TIME_OUT
+			syslog(LOG_NOTICE, "[TEC%c:%02u SND] tmo:   %7lu", apip, cepid, SND_TMO);
+#endif	/* of #ifdef SHOW_TIME_OUT */
+			if ((slen = tcp_snd_dat(cepid, smsg + soff, sizeof(smsg) - soff, SND_TMO)) < 0) {
+				syslog(LOG_NOTICE, "[TEC%c:%02u SND] error: %s", apip, cepid, itron_strerror(slen));
+				error = slen;
+				goto cls_ret;
+				}
+			soff  += (uint16_t)slen;
+			total +=     slen;
+			tcp_echo_cli_scount ++;
+#ifdef SHOW_SND_COUNT
+			syslog(LOG_NOTICE, "[TEC%c:%02u SND] count: %7lu, len: %4u",
+			                   apip, cepid, tcp_echo_cli_scount, (uint16_t)slen);
+#endif	/* of #ifdef SHOW_SND_COUNT */
+
+#ifdef SND_URG_DATA_SIZE
+			if (urg > 0) {
+				if (urg == 1) {
+#ifdef SHOW_TIME_OUT
+					syslog(LOG_NOTICE, "[TEC%c:%02u SND] tmo:   %7lu", apip, cepid, SND_TMO);
+#endif	/* of #ifdef SHOW_TIME_OUT */
+					if ((slen = tcp_snd_oob(cepid, smsg, SND_URG_DATA_SIZE, SND_TMO)) >= 0)
+						syslog(LOG_NOTICE, "[TEC%c:%02u SND] urg:   %7lu",
+						                   apip, cepid, (uint16_6)slen);
+					else
+						syslog(LOG_NOTICE, "[TEC%c:%02u OOB] error: %s",
+						                   apip, cepid, itron_strerror(slen));
+					}
+				urg --;
+				}
+#endif	/* of #ifdef SND_URG_DATA_SIZE */
+
+#if defined(SND_DLY)
+#if SND_DLY > 0
+			syscall(dly_tsk(SND_DLY + netapp_rand() % SYSTIM_HZ));
+#endif
+#endif
+			}
+		}
+
+cls_ret:
+	if ((error = tcp_sht_cep(cepid)) < 0)
+		syslog(LOG_NOTICE, "[TEC%c:%02u SHT] error: %s", apip, cepid, itron_strerror(error));
+
+	/* åä¿¡ãå®äºããã¾ã§å¾
+ã¤ã*/
+	syscall(slp_tsk());
+
+	return error;
+	}
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#endif	/* of #ifdef USE_TCP_ECHO_CLI */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -62,23 +62,15 @@
 #endif	/* of #ifdef TARGET_KERNEL_JSP */
 
-#include <tinet_defs.h>
-#include <tinet_config.h>
-
-#include <net/if.h>
-#include <net/if_ppp.h>
-#include <net/if_loop.h>
-#include <net/ethernet.h>
-#include <net/net.h>
-#include <net/net_timer.h>
-
 #include <netinet/in.h>
 #include <netinet/in_itron.h>
-#include <netinet/ip.h>
-#include <netinet/ip6.h>
-#include <netinet/tcp.h>
 
 #include <netapp/netapp.h>
 #include <netapp/netapp_var.h>
-#include <netapp/echo.h>
+#include <netapp/tcp_echo_srv1.h>
+#include <netapp/tcp_echo_srv1_var.h>
+
+#if defined(_NET_CFG_BYTE_ORDER)
+#error "net/net.h included."
+#endif
 
 #ifdef USE_TCP_ECHO_SRV1
@@ -100,10 +92,22 @@
  */
 
+#ifdef TOPPERS_S810_CLG3_85
+
+#define CLS_TMO		TMO_FEVR		/* Close Wait は標準で 60秒 */
+//#define RCV_TMO		TMO_FEVR
+#define RCV_TMO		(30*SYSTIM_HZ)
+//#define SND_TMO		TMO_FEVR
+#define SND_TMO		(30*SYSTIM_HZ)
+
+#else	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
 //#define CLS_TMO		TMO_FEVR	/* Close Wait は標準で 60秒 */
-#define CLS_TMO		(70*SYSTIM_HZ+(net_rand()%SYSTIM_HZ)*10)
+#define CLS_TMO		(70*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*10)
 //#define RCV_TMO		TMO_FEVR
-#define RCV_TMO		(30*SYSTIM_HZ+(net_rand()%SYSTIM_HZ)*30)
+#define RCV_TMO		(30*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*30)
 //#define SND_TMO		TMO_FEVR
-#define SND_TMO		(40*SYSTIM_HZ+(net_rand()%SYSTIM_HZ)*20)
+#define SND_TMO		(40*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*20)
+
+#endif	/* of #ifdef TOPPERS_S810_CLG3_85 */
 
 /*
@@ -121,223 +125,236 @@
 #endif
 
+#ifndef USE_TCP_NON_BLOCKING
+
 /*
  *  変数
  */
 
-/*
- *  注意:
- *
- *    BUF_SIZE は TCP の
- *    送信ウインドウバッファサイズ + 受信ウインドウバッファサイズの 
- *    3/2 倍以上の大きさがなければ、デッドロックする可能性がある。
- */
-
-#define BUF_SIZE	((TCP_ECHO_SRV_SWBUF_SIZE + \
-                          TCP_ECHO_SRV_RWBUF_SIZE) * 3 / 2)
-
-static T_IPEP		dst;			/* 接続相手		*/
-
-#ifdef USE_TCP_NON_BLOCKING
-
-static char		buffer[BUF_SIZE];
-static ER		nblk_error = E_OK;
-static ER_UINT		nblk_slen  = 0;
-static ER_UINT		nblk_rlen  = 0;
-
-#else	/* of #ifdef USE_TCP_NON_BLOCKING */
-
-#ifdef USE_COPYSAVE_API
-
-#else	/* of #ifdef USE_COPYSAVE_API */
-
-static char		buffer[BUF_SIZE];
-
-#endif	/* of #ifdef USE_COPYSAVE_API */
-
-#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
-
-#ifdef USE_TCP_NON_BLOCKING
-
-/*
- *  ノンブロッキングコールのコールバック関数
- */
-
-ER
-callback_nblk_tcp_echo_srv (ID cepid, FN fncd, void *p_parblk)
+#ifdef USE_TCP_EXTENTIONS
+
+T_TCP_ECHO_SRV_INFO tcp_echo_srv_info[NUM_TCP_ECHO_SRV_TASKS];
+
+#else	/* of #ifdef USE_TCP_EXTENTIONS */
+
+T_TCP_ECHO_SRV_INFO tcp_echo_srv_info[] = {
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV)
+
+	{ TCP4_ECHO_SRV_CEPID1, TCP4_ECHO_SRV_REPID },
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV) */
+
+	{ TCP_ECHO_SRV_CEPID1, TCP_ECHO_SRV_REPID },
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV) */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 2
+	{ TCP_ECHO_SRV_CEPID2, TCP_ECHO_SRV_REPID },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 3
+	{ TCP_ECHO_SRV_CEPID3, TCP_ECHO_SRV_REPID },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 4
+	{ TCP_ECHO_SRV_CEPID4, TCP_ECHO_SRV_REPID },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 5
+	{ TCP_ECHO_SRV_CEPID5, TCP_ECHO_SRV_REPID },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 6
+	{ TCP_ECHO_SRV_CEPID6, TCP_ECHO_SRV_REPID },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 7
+	{ TCP_ECHO_SRV_CEPID7, TCP_ECHO_SRV_REPID },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 8
+	{ TCP_ECHO_SRV_CEPID8, TCP_ECHO_SRV_REPID },
+#endif
+
+	};
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+/*
+ *  tcp_passive_open -- 受動オープンを実行する。
+ *
+ *    USE_TCP_NON_BLOCKING	OFF
+ */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+static ER
+tcp_passive_open (T_TCP_ECHO_SRV_INFO *info, char apip)
 {
-	ER	error = E_OK;
-
-	switch (fncd) {
-
-	case TFN_TCP_ACP_CEP:
-		nblk_error = *(ER*)p_parblk;
-		syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
-		break;
-
-	case TFN_TCP_RCV_DAT:
-		if ((nblk_rlen = *(ER*)p_parblk) < 0)
-			syslog(LOG_NOTICE, "[TES:%02d CBN] recv error: %s", cepid, itron_strerror(nblk_rlen));
-		syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
-		break;
-
-	case TFN_TCP_SND_DAT:
-		if ((nblk_slen = *(ER*)p_parblk) < 0)
-			syslog(LOG_NOTICE, "[TES:%02d CBN] send error: %s", cepid, itron_strerror(nblk_slen));
-		syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
-		break;
-
-	case TFN_TCP_CLS_CEP:
-		if ((nblk_error = *(ER*)p_parblk) < 0)
-			syslog(LOG_NOTICE, "[TES:%02d CBN] close error: %s", cepid, itron_strerror(nblk_error));
-		syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
-		break;
-
-	case TFN_TCP_RCV_BUF:
-		if ((nblk_rlen = *(ER*)p_parblk) < 0)
-			syslog(LOG_NOTICE, "[TES:%02d CBN] rbuf error: %s", cepid, itron_strerror(nblk_rlen));
-		syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
-		break;
-
-	case TFN_TCP_GET_BUF:
-		if ((nblk_slen = *(ER*)p_parblk) < 0)
-			syslog(LOG_NOTICE, "[TES:%02d CBN] sbuf error: %s", cepid, itron_strerror(nblk_slen));
-		syscall(sig_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
-		break;
+	ER		error = E_OK;
+
+#if TNUM_TCP4_REPID > 0
+	T_IPV4EP	dst4;
+#endif
+
+	if (apip == API_PROTO_IPV6) {
+
+#if TNUM_TCP6_REPID > 0
+
+		/* 受付口は IPv6 */
+		if ((error = tcp6_acp_cep(info->cepid, info->repid, &info->dst, TMO_FEVR)) != E_OK)
+			return error;
 
 #ifdef USE_TCP_EXTENTIONS
-
-	case TEV_TCP_RCV_OOB:
-		if ((nblk_rlen = *(ER*)p_parblk) < 0)
-			syslog(LOG_NOTICE, "[TES:%02d OOB] callback error: %s", cepid, itron_strerror(nblk_rlen));
-		else if (nblk_rlen > 0) {
-			char ch;
-
-			if ((nblk_rlen = tcp_rcv_oob(cepid, &ch, sizeof(ch))) > 0)
-				syslog(LOG_NOTICE, "[TES:%02d OOB] recv oob: 0x%02x", cepid, ch);
-			else if (nblk_rlen < 0)
-				syslog(LOG_NOTICE, "[TES:%02d OOB] recv error: %s", cepid, itron_strerror(nblk_rlen));
-			}
-		break;
-
+		if ((error = free_tcp6_rep(info->repid, true)) != E_OK)
+			return error;
 #endif	/* of #ifdef USE_TCP_EXTENTIONS */
 
-	case TFN_TCP_CON_CEP:
-	case TFN_TCP_SND_OOB:
-	default:
-		error = E_PAR;
-		break;
-		}
+#endif	/* of #if TNUM_TCP6_REPID > 0 */
+
+		}
+	else {
+
+#if TNUM_TCP4_REPID > 0
+
+		/* 受付口は IPv4 */
+		if ((error = tcp_acp_cep(info->cepid, info->repid, &dst4, TMO_FEVR)) != E_OK)
+			return error;
+		in6_make_ipv4mapped (&info->dst.ipaddr, dst4.ipaddr);
+		info->dst.portno = dst4.portno;
+
+#ifdef USE_TCP_EXTENTIONS
+		if ((error = free_tcp4_rep(info->repid, true)) != E_OK)
+			return error;
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#endif	/* of #if TNUM_TCP4_REPID > 0 */
+
+		}
+
 	return error;
 	}
 
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+/*
+ *  tcp_passive_open -- 受動オープンを実行する。
+ *
+ *    USE_TCP_NON_BLOCKING	OFF
+ */
+
+static ER
+tcp_passive_open (T_TCP_ECHO_SRV_INFO *info, char apip)
+{
+	ER		error = E_OK;
+
+	if ((error = TCP_ACP_CEP(info->cepid, info->repid, &info->dst, TMO_FEVR)) != E_OK)
+		return error;
+
+#ifdef USE_TCP_EXTENTIONS
+	if ((error = FREE_TCP_REP(info->repid, true)) != E_OK)
+		return error;
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+	return error;
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
 #ifdef USE_COPYSAVE_API
 
-static ER
-tcp_echo_srv (ID cepid, ID repid)
+/*
+ *  tcp_echo_srv -- TCP エコーサーバ
+ *
+ *    USE_TCP_NON_BLOCKING	OFF
+ *    USE_COPYSAVE_API		ON
+ */
+
+ER
+tcp_echo_srv (uint_t six, char apip)
 {
-	ER		error;
+	ER		error = E_OK;
+	ER_UINT		rblen, sblen;
 	SYSTIM		now;
 	uint32_t	total;
-	uint16_t	rblen, sblen, rlen, slen, soff, scount, rcount;
-	char		*rbuf, *sbuf, head, tail;
-
-	if ((error = TCP_ACP_CEP(cepid, repid, &dst, TMO_NBLK)) != E_WBLK) {
-		syslog(LOG_NOTICE, "[TES:%02d ACP] error: %s", cepid, itron_strerror(error));
+	uint16_t	rlen, slen, soff, scount, rcount;
+	char		*rbuf, *sbuf;
+
+#ifdef SHOW_RCV_RANGE
+	char		head, tail;
+#endif
+
+	if ((error = tcp_passive_open(&tcp_echo_srv_info[six], apip)) != E_OK) {
+		syslog(LOG_NOTICE, "[TES%c:%02u OPN] error: %s",
+		                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
 		return error;
 		}
 
-	/* 相手から接続されるまで待つ。*/
-	syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
-
-	if (nblk_error == E_OK) {
-		syscall(get_tim(&now));
-		syslog(LOG_NOTICE, "[TES:%02d ACP] connected:  %6lu, from: %s.%u",
-		                   cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
-		}
+	syscall(get_tim(&now));
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+	if (apip == API_PROTO_IPV6)
+		syslog(LOG_NOTICE, "[TES6:%02u ACP] conct: %7lu,from: %s.%u",
+		                   tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+		                   ipv62str(NULL, &tcp_echo_srv_info[six].dst.ipaddr),
+		                   tcp_echo_srv_info[six].dst.portno);
 	else {
-		syslog(LOG_NOTICE, "[TES:%02d ACP] error: %s", cepid, itron_strerror(nblk_error));
-		return nblk_error;
-		}
-
-#ifdef USE_TCP_EXTENTIONS
-	if ((error = free_tcp_rep(repid, true)) != E_OK)
-		syslog(LOG_NOTICE, "[TES:%02d DEL] REP delete error: %s", cepid, itron_strerror(error));
-#endif	/* of #ifdef USE_TCP_EXTENTIONS */
-
-	rlen = scount = rcount = total = 0;
+		T_IN4_ADDR	addr;
+
+		addr = ntohl(tcp_echo_srv_info[six].dst.ipaddr.s6_addr32[3]);
+		syslog(LOG_NOTICE, "[TES4:%02u ACP] conct: %7lu,from: %s.%u",
+		                   tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+		                   ip2str(NULL, &addr), tcp_echo_srv_info[six].dst.portno);
+		}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	syslog(LOG_NOTICE, "[TES%c:%02u ACP] conct: %7lu,from: %s.%u",
+	                   apip, tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+	                   IP2STR(NULL, &tcp_echo_srv_info[six].dst.ipaddr),
+	                   tcp_echo_srv_info[six].dst.portno);
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	scount = rcount = total = 0;
 	while (true) {
-		if ((error = tcp_rcv_buf(cepid, (void**)&rbuf, TMO_NBLK)) != E_WBLK) {
-			syslog(LOG_NOTICE, "[TES:%02d RCV] error: %s", cepid, itron_strerror(error));
+		if ((rblen = tcp_rcv_buf(tcp_echo_srv_info[six].cepid, (void**)&rbuf, RCV_TMO)) <= 0) {
+			if (rblen != E_OK)
+				syslog(LOG_NOTICE, "[TES%c:%02u RCV] error: %s",
+				                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(rblen));
 			break;
 			}
 
-		/* 受信するまで待つ。*/
-		syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
-
-		if (nblk_rlen < 0) {	/* エラー */
-			syslog(LOG_NOTICE, "[TES:%02d RCV] error: %s", 
-			                   cepid, itron_strerror(nblk_rlen));
-			break;
-			}
-		else if (nblk_rlen == 0)	/* 受信終了 */
-			break;
-
-		rblen = nblk_rlen;
-
-		/* バッファの残りにより、受信長を調整する。*/
-		if (rblen > BUF_SIZE - rlen)
-			rblen = BUF_SIZE - rlen;
-		total += rblen;
-		rlen   = rblen;
-
+		rcount ++;
+
+#ifdef SHOW_RCV_RANGE
 		head = *rbuf;
 		tail = *(rbuf + rblen - 1);
-		rcount ++;
-
-#ifdef SHOW_RCV_RANGE
-		syslog(LOG_NOTICE, "[TES:%02d RCV] "
-		                   "rcount: %4d, len: %4d, data %02x -> %02x",
-		                   cepid, rcount, rblen, head, tail);
+
+		//syslog(LOG_NOTICE, "[TES%c:%02u RCV] len:   %7lu",
+		//                   apip, tcp_echo_srv_info[six].cepid, (uint16_t)rblen);
+		syslog(LOG_NOTICE, "[TES%c:%02u RCV] rcount: %7lu, len: %6lu, data %02x -> %02x",
+		                   apip, tcp_echo_srv_info[six].cepid, rcount, (uint16_t)rblen, head, tail);
 #endif	/* of #ifdef SHOW_RCV_RANGE */
 
-		memcpy(buffer, rbuf, rblen);
-
-		if ((error = tcp_rel_buf(cepid, rlen)) < 0) {
-			syslog(LOG_NOTICE, "[TES:%02d REL] error: %s",
-			                   cepid, itron_strerror(error));
-			break;
-			}
-
+		rlen   = (uint16_t)rblen;
+		total +=     rblen;
 		soff = 0;
 		while (rlen > 0) {
 
-			if ((error = tcp_get_buf(cepid, (void**)&sbuf, TMO_NBLK)) != E_WBLK) {
-				syslog(LOG_NOTICE, "[TES:%02d GET] error: %s",
-				                   cepid, itron_strerror(error));
+			if ((sblen = tcp_get_buf(tcp_echo_srv_info[six].cepid, (void**)&sbuf, SND_TMO)) < 0) {
+				syslog(LOG_NOTICE, "[TES%c:%02u GET] error: %s",
+				                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(sblen));
 				goto err_fin;
 				}
 
-			/* 送信バッファの獲得が完了するまで待つ。*/
-			syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
-
-			if (nblk_slen < 0) {
-				syslog(LOG_NOTICE, "[TES:%02d GET] error: %s",
-				                   cepid, itron_strerror(nblk_slen));
-				goto err_fin;
-				}
-
-			sblen = nblk_slen;
+			//syslog(LOG_NOTICE, "[TES%c:%02u SND] len:   %7lu",
+			//                   apip, tcp_echo_srv_info[six].cepid, (uint16_t)sblen);
 			scount ++;
-			slen = sblen < rlen ? sblen : rlen;
-			memcpy(sbuf, buffer + soff, slen);
-
-			if ((error = tcp_snd_buf(cepid, slen)) != E_OK) {
-				syslog(LOG_NOTICE, "[TES:%02d SND] error: %s",
-				                   cepid, itron_strerror(error));
+			slen = rlen < (uint16_t)sblen ? rlen : (uint16_t)sblen;
+			memcpy(sbuf, rbuf + soff, slen);
+			if ((error = tcp_snd_buf(tcp_echo_srv_info[six].cepid, slen)) != E_OK) {
+				syslog(LOG_NOTICE, "[TES%c:%02u SND] error: %s",
+				                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
 				goto err_fin;
 				}
 #ifdef SHOW_RCV_RANGE
-			syslog(LOG_NOTICE, "[TES:%02d SND] scount: %4d, len: %4d",
-			                   cepid, scount, slen);
+			syslog(LOG_NOTICE, "[TES%c:%02u SND] scount: %4u, len: %4u",
+			                   apip, tcp_echo_srv_info[six].cepid, scount, slen);
 #endif	/* of #ifdef SHOW_RCV_RANGE */
 
@@ -345,86 +362,103 @@
 			soff += slen;
 			}
+
+		if ((error = tcp_rel_buf(tcp_echo_srv_info[six].cepid, rblen)) < 0) {
+			syslog(LOG_NOTICE, "[TES%c:%02u REL] error: %s",
+			                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+			break;
+			}
 		}
 err_fin:
 
 #ifdef USE_TCP_SHT_CEP
-	if ((error = tcp_sht_cep(cepid)) != E_OK)
-		syslog(LOG_NOTICE, "[TES:%02d SHT] error: %s", cepid, itron_strerror(error));
+	if ((error = tcp_sht_cep(tcp_echo_srv_info[six].cepid)) != E_OK)
+		syslog(LOG_NOTICE, "[TES%c:%02u SHT] error: %s",
+		                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
 #endif	/* of #ifdef USE_TCP_SHT_CEP */
 
-	if ((error = tcp_cls_cep(cepid, TMO_NBLK)) != E_WBLK)
-		syslog(LOG_NOTICE, "[TES:%02d CLS] error: %s", cepid, itron_strerror(error));
-
-	/* 開放が完了するまで待つ。*/
-	syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
+	if ((error = tcp_cls_cep(tcp_echo_srv_info[six].cepid, CLS_TMO)) != E_OK)
+		syslog(LOG_NOTICE, "[TES%c:%02u CLS] error: %s",
+		                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
 
 	syscall(get_tim(&now));
-	syslog(LOG_NOTICE, "[TES:%02d FIN] finished:   %6lu, snd: %4u, rcv: %4u, len: %lu",
-	                   cepid, now / SYSTIM_HZ, scount, rcount, total);
-
-	return error == E_WBLK ? E_OK : error;
+#if 1
+	syslog(LOG_NOTICE, "[TES%c:%02u FIN] finsh: %7lu, ttl: %lu",
+	                   apip, tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ, total);
+#else
+	syslog(LOG_NOTICE, "[TES%c:%02u FIN] finsh: %7lu, ttl: %lu, error: %s",
+	                   apip, tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ, total, itron_strerror(error));
+#endif
+
+	return error;
 	}
 
 #else	/* of #ifdef USE_COPYSAVE_API */
 
-static ER
-tcp_echo_srv (ID cepid, ID repid)
+/*
+ *  tcp_echo_srv -- TCP エコーサーバ
+ *
+ *    USE_TCP_NON_BLOCKING	OFF
+ *    USE_COPYSAVE_API		OFF
+ */
+
+ER
+tcp_echo_srv (uint_t six, char apip)
 {
+	ID		cepid;
+	ER		error = E_OK;
+	ER_UINT		rlen, slen;
 	SYSTIM		now;
-	ER		error;
 	uint32_t	total;
-	uint16_t	rlen, slen, soff, scount, rcount;
-	char		head, tail;
-
-	if ((error = TCP_ACP_CEP(cepid, repid, &dst, TMO_NBLK)) != E_WBLK) {
-		syslog(LOG_NOTICE, "[TES:%02d ACP] error: %s", cepid, itron_strerror(error));
+	uint16_t	soff, scount, rcount;
+
+	if ((error = tcp_passive_open(&tcp_echo_srv_info[six], apip)) != E_OK) {
+		syslog(LOG_NOTICE, "[TES%c:%02u OPN] error: %s",
+		                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
 		return error;
 		}
-
-	/* 相手から接続されるまで待つ。*/
-	syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
-
-	if (nblk_error == E_OK) {
-		syscall(get_tim(&now));
-		syslog(LOG_NOTICE, "[TES:%02d ACP] connected:  %6lu, from: %s.%u",
-		                   cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
-		}
-	else {
-		syslog(LOG_NOTICE, "[TES:%02d ACP] error: %s", cepid, itron_strerror(nblk_error));
-		return nblk_error;
-		}
-
-#ifdef USE_TCP_EXTENTIONS
-	if ((error = free_tcp_rep(repid, true)) != E_OK)
-		syslog(LOG_NOTICE, "[TES:%02d DEL] REP delete error: %s", cepid, itron_strerror(error));
-#endif	/* of #ifdef USE_TCP_EXTENTIONS */
-
+	
+	syscall(get_tim(&now));
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+	if (apip == API_PROTO_IPV6)
+		syslog(LOG_NOTICE, "[TES6:%02u ACP] conct: %7lu,from: %s.%u",
+		                   tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+		                   ipv62str(NULL, &tcp_echo_srv_info[six].dst.ipaddr),
+		                   tcp_echo_srv_info[six].dst.portno);
+	else	{
+		T_IN4_ADDR	addr;
+
+		addr = ntohl(tcp_echo_srv_info[six].dst.ipaddr.s6_addr32[3]);
+		syslog(LOG_NOTICE, "[TES4:%02u ACP] conct: %7lu,from: %s.%u",
+		                   tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+		                   ip2str(NULL, &addr), tcp_echo_srv_info[six].dst.portno);
+		}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	syslog(LOG_NOTICE, "[TES%c:%02u ACP] conct: %7lu,from: %s.%u",
+	                   apip, tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+	                   IP2STR(NULL, &tcp_echo_srv_info[six].dst.ipaddr),
+	                   tcp_echo_srv_info[six].dst.portno);
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	cepid =  tcp_echo_srv_info[six].cepid;
 	scount = rcount = total = 0;
 	while (true) {
-		if ((error = tcp_rcv_dat(cepid, buffer, BUF_SIZE - 1, TMO_NBLK)) != E_WBLK) {
-			syslog(LOG_NOTICE, "[TES:%02d RCV] error: %s",
-			                   cepid, itron_strerror(error));
+		if ((rlen = tcp_rcv_dat(cepid, tcp_echo_srv_info[six].buffer, BUF_SIZE - 1, RCV_TMO)) <= 0) {
+			if (rlen != E_OK)
+				syslog(LOG_NOTICE, "[TES%c:%02u RCV] error: %s",
+				                   apip, cepid, itron_strerror(rlen));
 			break;
 			}
 
-		/* 受信完了まで待つ。*/
-		syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
-
-		if (nblk_rlen < 0) {
-			syslog(LOG_NOTICE, "[TES:%02d RCV] error: %s",
-			                   cepid, itron_strerror(nblk_rlen));
-			break;
-			}
-		else if (nblk_rlen == 0)
-			break;
-
-		rlen = nblk_rlen;
-		head = *buffer;
-		tail = *(buffer + rlen - 1);
 		rcount ++;
-
 #ifdef SHOW_RCV_RANGE
-		syslog(LOG_NOTICE, "[TES:%02d RCV] rcount: %4d, len: %4d, data %02x -> %02x",
-		                   cepid, rcount, rlen, head, tail);
+		syslog(LOG_NOTICE, "[TES%c:%02u RCV] rcount: %4u, len: %4u, data %02x -> %02x",
+		                   apip, cepid, rcount,
+		                   (uint16_t)rlen, * tcp_echo_srv_info[six].tcp_echo_srv_info[six].buffer,
+		                                   *(tcp_echo_srv_info[six].tcp_echo_srv_info[six].buffer + rlen - 1));
 #endif	/* of #ifdef SHOW_RCV_RANGE */
 
@@ -433,24 +467,12 @@
 		while (rlen > 0) {
 			scount ++;
-			if ((error = tcp_snd_dat(cepid, &buffer[soff], rlen, TMO_NBLK)) != E_WBLK) {
-				syslog(LOG_NOTICE, "[TES:%02d SND] error: %s",
-				                   cepid, itron_strerror(error));
+			if ((slen = tcp_snd_dat(cepid, &tcp_echo_srv_info[six].buffer[soff], rlen, SND_TMO)) < 0) {
+				syslog(LOG_NOTICE, "[TES%c:%02u SND] error: %s",
+				                   apip, cepid, itron_strerror(slen));
 				goto err_fin;
 				}
-
-			/* 送信完了まで待つ。*/
-			syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
-
-			if (nblk_slen < 0) {
-				syslog(LOG_NOTICE, "[TES:%02d SND] error: %s",
-				                   cepid, itron_strerror(nblk_slen));
-				goto err_fin;
-				}
-
-			slen = nblk_slen;
-
 #ifdef SHOW_RCV_RANGE
-			syslog(LOG_NOTICE, "[TES:%02d SND] scount: %4d, len: %4d",
-			                   cepid, scount, slen);
+			syslog(LOG_NOTICE, "[TES%c:%02u SND] scount: %4u, len: %4u",
+			                   apip, cepid, scount, (uint16_t)slen);
 #endif	/* of #ifdef SHOW_RCV_RANGE */
 
@@ -463,301 +485,24 @@
 #ifdef USE_TCP_SHT_CEP
 	if ((error = tcp_sht_cep(cepid)) != E_OK)
-		syslog(LOG_NOTICE, "[TES:%02d SHT] error: %s", cepid, itron_strerror(error));
+		syslog(LOG_NOTICE, "[TES%c:%02u SHT] error: %s", 
+		                    apip, cepid, itron_strerror(error));
 #endif	/* of #ifdef USE_TCP_SHT_CEP */
 
-	if ((error = tcp_cls_cep(cepid, TMO_NBLK)) != E_WBLK)
-		syslog(LOG_NOTICE, "[TES:%02d CLS] error: %s", cepid, itron_strerror(error));
-
-	/* 開放が完了するまで待つ。*/
-	syscall(wai_sem(SEM_TCP_ECHO_SRV_NBLK_READY));
+	if ((error = tcp_cls_cep(cepid, CLS_TMO)) != E_OK)
+		syslog(LOG_NOTICE, "[TES%c:%02u CLS] error: %s",
+		                   apip, cepid, itron_strerror(error));
 
 	syscall(get_tim(&now));
-	syslog(LOG_NOTICE, "[TES:%02d FIN] finished:   %6lu, snd: %4u, rcv: %4u, len: %lu",
-	                   cepid, now / SYSTIM_HZ, scount, rcount, total);
-
-	return error == E_WBLK ? E_OK : error;
-	}
-
-#endif	/* of #ifdef USE_COPYSAVE_API */
-
-#else	/* of #ifdef USE_TCP_NON_BLOCKING */
-
-#ifdef USE_COPYSAVE_API
-
-static ER
-tcp_echo_srv (ID cepid, ID repid)
-{
-	ER_UINT		rblen, sblen;
-	SYSTIM		now;
-	ER		error;
-	uint32_t	total;
-	uint16_t	rlen, slen, soff, scount, rcount;
-	char		*rbuf, *sbuf, head, tail;
-
-	if ((error = TCP_ACP_CEP(cepid, repid, &dst, TMO_FEVR)) != E_OK) {
-		syslog(LOG_NOTICE, "[TES:%02d ACP] error: %s", cepid, itron_strerror(error));
-		return error;
-		}
-
-#ifdef USE_TCP_EXTENTIONS
-	if ((error = free_tcp_rep(repid, true)) != E_OK)
-		syslog(LOG_NOTICE, "[TES:%02d DEL] REP delete error: %s", cepid, itron_strerror(error));
-#endif	/* of #ifdef USE_TCP_EXTENTIONS */
-
-	scount = rcount = total = 0;
-	syscall(get_tim(&now));
-	syslog(LOG_NOTICE, "[TES:%02d ACP] connected:  %6lu, from: %s.%u",
-	                   cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
-	while (true) {
-		if ((rblen = tcp_rcv_buf(cepid, (void**)&rbuf, RCV_TMO)) <= 0) {
-			if (rblen != E_OK)
-				syslog(LOG_NOTICE, "[TES:%02d RCV] error: %s",
-				                   cepid, itron_strerror(rblen));
-			break;
-			}
-
-		head = *rbuf;
-		tail = *(rbuf + rblen - 1);
-		rcount ++;
-
-		//syslog(LOG_NOTICE, "[TES:%02d RCV] len: %4d", cepid, (uint16_t)rblen);
-#ifdef SHOW_RCV_RANGE
-		syslog(LOG_NOTICE, "[TES:%02d RCV] rcount: %4d, len: %4d, data %02x -> %02x",
-		       cepid, rcount, (uint16_t)rblen, head, tail);
-#endif	/* of #ifdef SHOW_RCV_RANGE */
-
-		rlen   = (uint16_t)rblen;
-		total +=     rblen;
-		soff = 0;
-		while (rlen > 0) {
-
-			if ((sblen = tcp_get_buf(cepid, (void**)&sbuf, SND_TMO)) < 0) {
-				syslog(LOG_NOTICE, "[TES:%02d GET] error: %s",
-				                   cepid, itron_strerror(sblen));
-				goto err_fin;
-				}
-
-			//syslog(LOG_NOTICE, "[TES:%02d SND] len: %4d", cepid, (uint16_t)sblen);
-			scount ++;
-			slen = rlen < (uint16_t)sblen ? rlen : (uint16_t)sblen;
-			memcpy(sbuf, rbuf + soff, slen);
-			if ((error = tcp_snd_buf(cepid, slen)) != E_OK) {
-				syslog(LOG_NOTICE, "[TES:%02d SND] error: %s",
-				                   cepid, itron_strerror(error));
-				goto err_fin;
-				}
-#ifdef SHOW_RCV_RANGE
-			syslog(LOG_NOTICE, "[TES:%02d SND] scount: %4d, len: %4d", cepid, scount, slen);
-#endif	/* of #ifdef SHOW_RCV_RANGE */
-
-			rlen -= slen;
-			soff += slen;
-			}
-
-		if ((error = tcp_rel_buf(cepid, rblen)) < 0) {
-			syslog(LOG_NOTICE, "[TES:%02d REL] error: %s", cepid, itron_strerror(error));
-			break;
-			}
-		}
-err_fin:
-
-#ifdef USE_TCP_SHT_CEP
-	if ((error = tcp_sht_cep(cepid)) != E_OK)
-		syslog(LOG_NOTICE, "[TES:%02d SHT] error: %s", cepid, itron_strerror(error));
-#endif	/* of #ifdef USE_TCP_SHT_CEP */
-
-	if ((error = tcp_cls_cep(cepid, CLS_TMO)) != E_OK)
-		syslog(LOG_NOTICE, "[TES:%02d CLS] error: %s", cepid, itron_strerror(error));
-
-	syscall(get_tim(&now));
-	syslog(LOG_NOTICE, "[TES:%02d FIN] finished:   %6lu, snd: %4u, rcv: %4u, len: %lu",
-	                   cepid, now / SYSTIM_HZ, scount, rcount, total);
+	syslog(LOG_NOTICE, "[TES%c:%02u FIN] finsh: %7lu, ttl: %lu",
+	                   apip, cepid, now / SYSTIM_HZ, total);
 
 	return error;
 	}
 
-#else	/* of #ifdef USE_COPYSAVE_API */
-
-/*
- *  tcp_echo_srv -- TCP エコーサーバ
- */
-
-static ER
-tcp_echo_srv (ID cepid, ID repid)
-{
-	ER_UINT		rlen, slen;
-	ER		error = E_OK;
-	SYSTIM		now;
-	uint32_t	total;
-	uint16_t	soff, scount, rcount;
-
-	if ((error = TCP_ACP_CEP(cepid, repid, &dst, TMO_FEVR)) != E_OK) {
-		syslog(LOG_NOTICE, "[TES:%02d ACP] error: %s", cepid, itron_strerror(error));
-		return error;
-		}
-
-#ifdef USE_TCP_EXTENTIONS
-	if ((error = free_tcp_rep(repid, true)) != E_OK)
-		syslog(LOG_NOTICE, "[TES:%02d DEL] REP delete error: %s", cepid, itron_strerror(error));
-#endif	/* of #ifdef USE_TCP_EXTENTIONS */
-
-	scount = rcount = total = 0;
-	syscall(get_tim(&now));
-	syslog(LOG_NOTICE, "[TES:%02d ACP] connected:  %6lu, from: %s.%u",
-	                   cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
-	while (true) {
-		if ((rlen = tcp_rcv_dat(cepid, buffer, BUF_SIZE - 1, RCV_TMO)) <= 0) {
-			if (rlen != E_OK)
-				syslog(LOG_NOTICE, "[TES:%02d RCV] error: %s",
-				                   cepid, itron_strerror(rlen));
-			break;
-			}
-
-		rcount ++;
-#ifdef SHOW_RCV_RANGE
-		syslog(LOG_NOTICE, "[TES:%02d RCV] rcount: %4d, len: %4d, data %02x -> %02x",
-		       cepid, rcount, (uint16_t)rlen, *buffer, *(buffer + rlen - 1));
-#endif	/* of #ifdef SHOW_RCV_RANGE */
-
-		total += rlen;
-		soff = 0;
-		while (rlen > 0) {
-			scount ++;
-			if ((slen = tcp_snd_dat(cepid, &buffer[soff], rlen, SND_TMO)) < 0) {
-				syslog(LOG_NOTICE, "[TES:%02d SND] error: %s",
-				                   cepid, itron_strerror(slen));
-				goto err_fin;
-				}
-#ifdef SHOW_RCV_RANGE
-			syslog(LOG_NOTICE, "[TES:%02d SND] scount: %4d, len: %4d", cepid, scount, (uint16_t)slen);
-#endif	/* of #ifdef SHOW_RCV_RANGE */
-
-			rlen -= slen;
-			soff += slen;
-			}
-		}
-err_fin:
-
-#ifdef USE_TCP_SHT_CEP
-	if ((error = tcp_sht_cep(cepid)) != E_OK)
-		syslog(LOG_NOTICE, "[TES:%02d SHT] error: %s", cepid, itron_strerror(error));
-#endif	/* of #ifdef USE_TCP_SHT_CEP */
-
-	if ((error = tcp_cls_cep(cepid, CLS_TMO)) != E_OK)
-		syslog(LOG_NOTICE, "[TES:%02d CLS] error: %s", cepid, itron_strerror(error));
-
-	syscall(get_tim(&now));
-	syslog(LOG_NOTICE, "[TES:%02d FIN] finished:   %6lu, snd: %4u, rcv: %4u, len: %lu",
-	                   cepid, now / SYSTIM_HZ, scount, rcount, total);
-
-	return error;
-	}
-
 #endif	/* of #ifdef USE_COPYSAVE_API */
 
-#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
-
-#ifdef USE_TCP_EXTENTIONS
-
-/*
- *  get_tcp_rep -- TCP 受付口を獲得する。
- */
-
-static ER
-get_tcp_rep (ID *repid)
-{
-	ID		tskid;
-	T_TCP_CREP	crep;
-
-	get_tid(&tskid);
-
-	crep.repatr = UINT_C(0);
-	crep.myaddr.portno = UINT_C(7);
-
-#if defined(SUPPORT_INET4)
-	crep.myaddr.ipaddr = IPV4_ADDRANY;
-#endif
-
-#if defined(SUPPORT_INET6)
-	memcpy(&crep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
-#endif
-
-	return alloc_tcp_rep(repid, tskid, &crep);
-	}
-
-/*
- *  get_tcp_cep -- TCP 通信端点とを獲得する。
- */
-
-static ER
-get_tcp_cep (ID *cepid)
-{
-	ID		tskid;
-	T_TCP_CCEP	ccep;
-
-	get_tid(&tskid);
-
-	ccep.cepatr = UINT_C(0);
-	ccep.sbufsz = TCP_ECHO_SRV_SWBUF_SIZE;
-	ccep.rbufsz = TCP_ECHO_SRV_RWBUF_SIZE;
-
-#ifdef TCP_CFG_SWBUF_CSAVE
-	ccep.sbuf = NADR;
-#else
-	ccep.sbuf = tcp_echo_srv_swbuf;
-#endif
-#ifdef TCP_CFG_RWBUF_CSAVE
-	ccep.rbuf = NADR;
-#else
-	ccep.rbuf = tcp_echo_srv_rwbuf;
-#endif
-#ifdef USE_TCP_NON_BLOCKING
-	ccep.callback = (FP)callback_nblk_tcp_echo_srv;
-#else
-	ccep.callback = NULL;
-#endif
-
-	return alloc_tcp_cep(cepid, tskid, &ccep);
-	}
-
-/*
- *  tcp_echo_srv_task -- TCP エコーサーバタスク
- */
-
-void
-tcp_echo_srv_task (intptr_t exinf)
-{
-	ID	tskid, cepid, repid;
-	ER	error = E_OK;
-
-	syscall(get_tid(&tskid));
-	syslog(LOG_NOTICE, "[TCP ECHO SRV:%d] started.", tskid);
-	while (true) {
-
-		syscall(slp_tsk());
-		if ((error = get_tcp_cep (&cepid)) != E_OK) {
-			syslog(LOG_NOTICE, "[TES:00 EXT] CEP create error: %s", itron_strerror(error));
-			continue;
-			}
-
-		while (true) {
-
-			if ((error = get_tcp_rep (&repid)) != E_OK) {
-				syslog(LOG_NOTICE, "[TES:00 EXT] REP create error: %s", itron_strerror(error));
-				break;
-				}
-			else if ((error = tcp_echo_srv(cepid, repid)) != E_OK) {
-				error = free_tcp_rep(repid, error != E_DLT);
-				break;
-				}
-			}
-
-		if ((error = free_tcp_cep(cepid)) != E_OK)
-			syslog(LOG_NOTICE, "[TES:%02d EXT] CEP delete error: %s", cepid, itron_strerror(error));
-
-		}
-	}
-
-#else	/* of #ifdef USE_TCP_EXTENTIONS */
+#endif	/* of #ifndef USE_TCP_NON_BLOCKING */
+
+#ifndef USE_TCP_EXTENTIONS
 
 /*
@@ -768,18 +513,46 @@
 tcp_echo_srv_task(intptr_t exinf)
 {
-	ID	tskid;
+	ID	tskid, cepid;
 	ER	error;
+	uint_t	six;
+	char	apip;
+
+	six = INDEX_SRV_INFO((ID)exinf);
+
+#if defined(SUPPORT_INET6)
+
+#if defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV)
+
+	if (six >= NUM_TCP4_ECHO_SRV_TASKS)
+		apip = API_PROTO_IPV6;
+	else
+		apip = API_PROTO_IPV4;
+
+#else	/* of #if defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV) */
+
+	apip = API_PROTO_IPV6;
+
+#endif	/* of #if defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+	apip = API_PROTO_IPV4;
+
+#endif	/* of #if defined(SUPPORT_INET6) */
 
 	syscall(get_tid(&tskid));
-	syslog(LOG_NOTICE, "[TCP ECHO SRV:%d,%d] started.", tskid, (ID)exinf);
+	cepid = tcp_echo_srv_info[six].cepid;
+	syslog(LOG_NOTICE, "[TCP%c ECHO SRV:%d,%d] started.", apip, tskid, cepid);
+
 	while (true) {
-		while ((error = tcp_echo_srv((ID)exinf, TCP_ECHO_SRV_REPID)) == E_OK)
+		while ((error = tcp_echo_srv(six, apip)) == E_OK)
 			;
-		syslog(LOG_NOTICE, "[TES:%02d] goto sleep 60[s], error: %s", (ID)exinf, itron_strerror(error));
-		tslp_tsk(60 * 1000);
+		syslog(LOG_NOTICE, "[TES%c:%02u TSK] sleep 60[s], error: %s", apip, cepid, itron_strerror(error));
+		tslp_tsk(60 * 1000 * 1000);
+		syslog(LOG_NOTICE, "[TES%c:%02u TSK] resume.", apip, cepid);
 		}
 	}
 
-#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+#endif	/* of #ifndef USE_TCP_EXTENTIONS */
 
 #endif	/* of #ifdef USE_TCP_ECHO_SRV1 */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -41,9 +41,7 @@
 /* タスク */
 
-#ifdef USE_TCP_EXTENTIONS
-
-CRE_TSK(TCP_ECHO_SRV_TASK,  {
+CRE_TSK(TCP_ECHO_SRV_TASK1,  {
 	TA_HLNG | TA_ACT,
-	0,
+	1,
 	tcp_echo_srv_task,
 	TCP_ECHO_SRV_MAIN_PRIORITY,
@@ -52,22 +50,9 @@
 	});
 
-#else	/* of #ifdef USE_TCP_EXTENTIONS */
-
-CRE_TSK(TCP_ECHO_SRV_TASK,  {
-	TA_HLNG | TA_ACT,
-	TCP_ECHO_SRV_CEPID1,
-	tcp_echo_srv_task,
-	TCP_ECHO_SRV_MAIN_PRIORITY,
-	TCP_ECHO_SRV_STACK_SIZE,
-	NULL
-	});
-
-#endif	/* of #ifdef USE_TCP_EXTENTIONS */
-
 #if NUM_TCP_ECHO_SRV_TASKS >= 2
 
 CRE_TSK(TCP_ECHO_SRV_TASK2,  {
 	TA_HLNG | TA_ACT,
-	TCP_ECHO_SRV_CEPID2,
+	2,
 	tcp_echo_srv_task,
 	TCP_ECHO_SRV_MAIN_PRIORITY,
@@ -82,5 +67,5 @@
 CRE_TSK(TCP_ECHO_SRV_TASK3,  {
 	TA_HLNG | TA_ACT,
-	TCP_ECHO_SRV_CEPID3,
+	3,
 	tcp_echo_srv_task,
 	TCP_ECHO_SRV_MAIN_PRIORITY,
@@ -95,5 +80,5 @@
 CRE_TSK(TCP_ECHO_SRV_TASK4,  {
 	TA_HLNG | TA_ACT,
-	TCP_ECHO_SRV_CEPID4,
+	4,
 	tcp_echo_srv_task,
 	TCP_ECHO_SRV_MAIN_PRIORITY,
@@ -108,5 +93,5 @@
 CRE_TSK(TCP_ECHO_SRV_TASK5,  {
 	TA_HLNG | TA_ACT,
-	TCP_ECHO_SRV_CEPID5,
+	5,
 	tcp_echo_srv_task,
 	TCP_ECHO_SRV_MAIN_PRIORITY,
@@ -121,5 +106,5 @@
 CRE_TSK(TCP_ECHO_SRV_TASK6,  {
 	TA_HLNG | TA_ACT,
-	TCP_ECHO_SRV_CEPID6,
+	6,
 	tcp_echo_srv_task,
 	TCP_ECHO_SRV_MAIN_PRIORITY,
@@ -134,5 +119,5 @@
 CRE_TSK(TCP_ECHO_SRV_TASK7,  {
 	TA_HLNG | TA_ACT,
-	TCP_ECHO_SRV_CEPID7,
+	7,
 	tcp_echo_srv_task,
 	TCP_ECHO_SRV_MAIN_PRIORITY,
@@ -147,5 +132,5 @@
 CRE_TSK(TCP_ECHO_SRV_TASK8,  {
 	TA_HLNG | TA_ACT,
-	TCP_ECHO_SRV_CEPID8,
+	8,
 	tcp_echo_srv_task,
 	TCP_ECHO_SRV_MAIN_PRIORITY,
@@ -160,5 +145,27 @@
 #ifdef USE_TCP_NON_BLOCKING
 
-CRE_SEM(SEM_TCP_ECHO_SRV_NBLK_READY,	{ TA_TPRI, 0, 1 });
+CRE_SEM(SEM_TCP_ECHO_SRV_NBLK_READY1,	{ TA_TPRI, 0, 1 });
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 2
+CRE_SEM(SEM_TCP_ECHO_SRV_NBLK_READY2,	{ TA_TPRI, 0, 1 });
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 3
+CRE_SEM(SEM_TCP_ECHO_SRV_NBLK_READY3,	{ TA_TPRI, 0, 1 });
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 4
+CRE_SEM(SEM_TCP_ECHO_SRV_NBLK_READY4,	{ TA_TPRI, 0, 1 });
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 5
+CRE_SEM(SEM_TCP_ECHO_SRV_NBLK_READY5,	{ TA_TPRI, 0, 1 });
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 6
+CRE_SEM(SEM_TCP_ECHO_SRV_NBLK_READY6,	{ TA_TPRI, 0, 1 });
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 7
+CRE_SEM(SEM_TCP_ECHO_SRV_NBLK_READY7,	{ TA_TPRI, 0, 1 });
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 8
+CRE_SEM(SEM_TCP_ECHO_SRV_NBLK_READY8,	{ TA_TPRI, 0, 1 });
+#endif
 
 #endif	/* of #ifdef USE_TCP_NON_BLOCKING */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1.h	(revision 331)
@@ -0,0 +1,135 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#ifdef USE_TCP_ECHO_SRV1
+
+#ifndef _TCP_ECHO_SRV1_H_
+#define _TCP_ECHO_SRV1_H_
+
+/* 
+ *  TCP ECHO ãµã¼ã #1
+ *
+ *    ã»éåä¿¡ã¿ã¹ã¯åä¸å
+ *    ã»ãã³ãã­ãã­ã³ã°ã³ã¼ã«
+ *    ã»çã³ãã¼ API
+ *    ã»IPv4/IPv6
+ *    ã»ç·æ¥ãã¼ã¿ã®åä¿¡
+ */
+
+/* ã¹ã¿ãã¯ãµã¤ãº */
+
+#define TCP_ECHO_SRV_STACK_SIZE		1024		/* TCP ECHO ãµã¼ãã¿ã¹ã¯ã®ã¹ã¿ãã¯ãµã¤ãº		*/
+
+/* åªå
+åº¦ */
+
+#define TCP_ECHO_SRV_MAIN_PRIORITY	5		/* TCP ECHO ãµã¼ãã¿ã¹ã¯ã®åªå
+åº¦			*/
+
+/*
+ *  TCP éåä¿¡ã¦ã¤ã³ããããã¡ãµã¤ãº
+ */
+
+#if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU)
+
+#if defined(SUPPORT_INET6)
+
+#define TCP_ECHO_SRV_SWBUF_SIZE		(1024)
+#define TCP_ECHO_SRV_RWBUF_SIZE		(1024)
+
+#elif defined(SUPPORT_INET4)
+
+#define TCP_ECHO_SRV_SWBUF_SIZE		(512)
+#define TCP_ECHO_SRV_RWBUF_SIZE		(512)
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#else	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+#define TCP_ECHO_SRV_SWBUF_SIZE		(1024)
+#define TCP_ECHO_SRV_RWBUF_SIZE		(1024)
+
+#endif	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+/*
+ *  ã¿ã¹ã¯æ°
+ */
+
+#ifndef NUM_TCP_ECHO_SRV_TASKS
+#define NUM_TCP_ECHO_SRV_TASKS		1
+#endif
+
+/* IPv4 ç¨ã® TCP ã¨ã³ã¼ãµã¼ãã¿ã¹ã¯ã¯ 1åã«å¶éããã*/
+
+#ifdef  NUM_TCP4_ECHO_SRV_TASKS
+#undef  NUM_TCP4_ECHO_SRV_TASKS
+#endif
+#define NUM_TCP4_ECHO_SRV_TASKS		1
+
+/*
+ *  å¤æ°
+ */
+
+/* TCP éåä¿¡ã¦ã£ã³ããããã¡ */
+
+extern uint8_t tcp_echo_srv_swbuf[NUM_TCP_ECHO_SRV_TASKS][TCP_ECHO_SRV_SWBUF_SIZE];
+extern uint8_t tcp_echo_srv_rwbuf[NUM_TCP_ECHO_SRV_TASKS][TCP_ECHO_SRV_RWBUF_SIZE];
+
+/*
+ *  ã¿ã¹ã¯
+ */
+
+extern void	tcp_echo_srv_task(intptr_t exinf);
+
+/*
+ *  é¢æ°
+ */
+
+extern ER callback_nblk_tcp_echo_srv (ID cepid, FN fncd, void *p_parblk);
+extern ER wakeup_tcp_echo_srv (char apip);
+
+#endif	/* of #ifndef _TCP_ECHO_SRV1_H_ */
+
+#endif	/* of #ifdef USE_TCP_ECHO_SRV1 */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1_ext.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1_ext.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1_ext.c	(revision 331)
@@ -0,0 +1,381 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TCP ECHO ãµã¼ã #1
+ *
+ *    ã»éåä¿¡ã¿ã¹ã¯åä¸å
+ *    ã»ãã³ãã­ãã­ã³ã°ã³ã¼ã«
+ *    ã»çã³ãã¼ API
+ *    ã»IPv4/IPv6
+ *    ã»ç·æ¥ãã¼ã¿ã®åä¿¡
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/tcp_echo_srv1.h>
+#include <netapp/tcp_echo_srv1_var.h>
+
+#ifdef USE_TCP_ECHO_SRV1
+
+/*
+ *  è¡¨ç¤º
+ */
+
+//#define SHOW_RCV_RANGE
+
+/*
+ *  ã³ãã¯ã·ã§ã³åæ­æ¹æ³ã®æå®
+ */
+
+#define USE_TCP_SHT_CEP
+
+/*
+ *  ã¿ã¤ã ã¢ã¦ã
+ */
+
+#ifdef TOPPERS_S810_CLG3_85
+
+#define CLS_TMO		TMO_FEVR		/* Close Wait ã¯æ¨æºã§ 60ç§ */
+//#define RCV_TMO		TMO_FEVR
+#define RCV_TMO		(30*SYSTIM_HZ)
+//#define SND_TMO		TMO_FEVR
+#define SND_TMO		(30*SYSTIM_HZ)
+
+#else	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+//#define CLS_TMO		TMO_FEVR	/* Close Wait ã¯æ¨æºã§ 60ç§ */
+#define CLS_TMO		(70*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*10)
+//#define RCV_TMO		TMO_FEVR
+#define RCV_TMO		(30*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*30)
+//#define SND_TMO		TMO_FEVR
+#define SND_TMO		(40*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*20)
+
+#endif	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+#ifdef USE_TCP_EXTENTIONS
+
+/*
+ *  å¤æ°
+ */
+
+typedef struct t_tcp_echo_srv_task_info {
+	ID	taskid;		/* ã¿ã¹ã¯ ID		*/
+	bool_t	active;		/* åä½ç¶æ
+		*/
+	char	apip;		/* API IPãã­ãã³ã«	*/
+	} T_TCP_ECHO_SRV_TASK_INFO;
+
+static T_TCP_ECHO_SRV_TASK_INFO tcp_echo_srv_task_info[NUM_TCP_ECHO_SRV_TASKS] = {
+
+				{ TCP_ECHO_SRV_TASK1, false },
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 2
+				{ TCP_ECHO_SRV_TASK2, false },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 3
+				{ TCP_ECHO_SRV_TASK3, false },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 4
+				{ TCP_ECHO_SRV_TASK4, false },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 5
+				{ TCP_ECHO_SRV_TASK5, false },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 6
+				{ TCP_ECHO_SRV_TASK6, false },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 7
+				{ TCP_ECHO_SRV_TASK7, false },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 8
+				{ TCP_ECHO_SRV_TASK8, false },
+#endif
+
+			};
+
+/*
+ *  get_tcp_rep -- TCP åä»å£ãç²å¾ããã
+ */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+static ER
+get_tcp_rep (ID *repid, char apip)
+{
+	ID		tskid;
+	T_TCP6_CREP	crep6;
+	T_TCP_CREP	crep4;
+
+	get_tid(&tskid);
+	if (apip == API_PROTO_IPV6) {
+		crep6.repatr = UINT_C(0);
+		crep6.myaddr.portno = UINT_C(7);
+		memcpy(&crep6.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
+		return alloc_tcp6_rep(repid, tskid, &crep6);
+		}
+	else {
+		crep4.repatr = UINT_C(0);
+		crep4.myaddr.portno = UINT_C(7);
+		crep4.myaddr.ipaddr = IPV4_ADDRANY;
+		return alloc_tcp4_rep(repid, tskid, &crep4);
+		}
+	}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+static ER
+get_tcp_rep (ID *repid, char apip)
+{
+	ID		tskid;
+	T_TCPN_CREP	crep;
+
+	get_tid(&tskid);
+
+	crep.repatr = UINT_C(0);
+	crep.myaddr.portno = UINT_C(7);
+
+#if defined(SUPPORT_INET6)
+
+	memcpy(&crep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
+
+#else	/* #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+	crep.myaddr.ipaddr = IPV4_ADDRANY;
+#endif
+
+#endif	/* #if defined(SUPPORT_INET6) */
+
+	return ALLOC_TCP_REP(repid, tskid, &crep);
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+/*
+ *  get_tcp_cep -- TCP éä¿¡ç«¯ç¹ãç²å¾ããã
+ */
+
+static ER
+get_tcp_cep (ID *cepid, char apip)
+{
+	ID		tskid;
+	T_TCP_CCEP	ccep;
+
+	get_tid(&tskid);
+
+	ccep.cepatr = UINT_C(0);
+	ccep.sbufsz = TCP_ECHO_SRV_SWBUF_SIZE;
+	ccep.rbufsz = TCP_ECHO_SRV_RWBUF_SIZE;
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+	ccep.sbuf = NADR;
+#else
+	ccep.sbuf = tcp_echo_srv_swbuf;
+#endif
+#ifdef TCP_CFG_RWBUF_CSAVE
+	ccep.rbuf = NADR;
+#else
+	ccep.rbuf = tcp_echo_srv_rwbuf;
+#endif
+#ifdef USE_TCP_NON_BLOCKING
+	ccep.callback = (FP)callback_nblk_tcp_echo_srv;
+#else
+	ccep.callback = NULL;
+#endif
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+	if (apip == API_PROTO_IPV6)
+		return alloc_tcp6_cep(cepid, tskid, &ccep);
+	else
+		return alloc_tcp4_cep(cepid, tskid, &ccep);
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	return ALLOC_TCP_CEP(cepid, tskid, &ccep);
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	}
+
+/*
+ *  wakeup_tcp_echo_srv -- TCP ã¨ã³ã¼ãµã¼ãã¿ã¹ã¯ã®ä¼æ­¢è§£é¤
+ */
+
+ER
+wakeup_tcp_echo_srv (char apip)
+{
+	int	ix;
+
+	for (ix = NUM_TCP_ECHO_SRV_TASKS; -- ix >= 0; )
+		if (!tcp_echo_srv_task_info[ix].active) {
+			syslog(LOG_NOTICE, "[TCP%c ECHO SRV(EXT):%d] wake up.",
+			                   apip, tcp_echo_srv_task_info[ix].taskid);
+			tcp_echo_srv_task_info[ix].apip   = apip;
+			tcp_echo_srv_task_info[ix].active = true;
+			return syscall(wup_tsk(tcp_echo_srv_task_info[ix].taskid));
+			}
+	syslog(LOG_NOTICE, "[TCP%c ECHO SRV(EXT):%d] wake up error: %s.",
+			   apip, tcp_echo_srv_task_info[ix].taskid, itron_strerror(E_ID));
+	return E_ID;
+	}
+
+/*
+ *  tcp_echo_srv_task -- TCP ã¨ã³ã¼ãµã¼ãã¿ã¹ã¯
+ */
+
+void
+tcp_echo_srv_task (intptr_t exinf)
+{
+	ID	tskid;
+	ER	error = E_OK;
+	int	ix;
+	char	apip;
+
+	syscall(get_tid(&tskid));
+	syslog(LOG_NOTICE, "[TCPn ECHO SRV(EXT):%d] started.", tskid);
+	while (true) {
+		syslog(LOG_NOTICE, "[TCPn ECHO SRV(EXT):%d] goto sleep.", tskid);
+		syscall(slp_tsk());
+
+		for (ix = NUM_TCP_ECHO_SRV_TASKS; -- ix >= 0; ) {
+			if (tcp_echo_srv_task_info[ix].taskid == tskid) {
+				break;
+				}
+			}
+
+		apip = tcp_echo_srv_task_info[ix].apip;
+		if ((error = get_tcp_cep(&tcp_echo_srv_info[ix].cepid, apip)) != E_OK) {
+			syslog(LOG_NOTICE, "[TCP%c ECHO SRV(EXT):%d] create CEP error: %s",
+		                           apip, tskid, itron_strerror(error));
+			continue;
+			}
+
+		while (true) {
+
+			if ((error = get_tcp_rep(&tcp_echo_srv_info[ix].repid, apip)) != E_OK) {
+				syslog(LOG_NOTICE, "[TCP%c ECHO SRV(EXT):%d] create REP error: %s",
+		                                   apip, tskid, itron_strerror(error));
+				break;
+				}
+			else if ((error = tcp_echo_srv(ix, apip)) != E_OK) {
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+				if (apip == API_PROTO_IPV6)
+					error = free_tcp6_rep(tcp_echo_srv_info[ix].repid, error != E_DLT);
+				else
+					error = free_tcp4_rep(tcp_echo_srv_info[ix].repid, error != E_DLT);
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+				error = FREE_TCP_REP(tcp_echo_srv_info[ix].repid, error != E_DLT);
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+				if (error != E_OK) {
+					syslog(LOG_NOTICE, "[TCP%c ECHO SRV(EXT):%d] delete REP error: %s",
+		                                           apip, tskid, itron_strerror(error));
+					}
+
+				break;
+				}
+			}
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+		if (apip == API_PROTO_IPV6)
+			error = free_tcp6_cep(tcp_echo_srv_info[ix].cepid);
+		else
+			error = free_tcp4_cep(tcp_echo_srv_info[ix].cepid);
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+		error = FREE_TCP_CEP(tcp_echo_srv_info[ix].cepid);
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+		if (error != E_OK) {
+			syslog(LOG_NOTICE, "[TCP%c ECHO SRV(EXT):%d] delete CEP error: %s",
+		                           apip, tskid, itron_strerror(error));
+			}
+
+		for (ix = NUM_TCP_ECHO_SRV_TASKS; -- ix >= 0; ) {
+			if (tcp_echo_srv_task_info[ix].taskid == tskid) {
+				tcp_echo_srv_task_info[ix].active = false;
+				break;
+				}
+			}
+
+		}
+	}
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_TCP_ECHO_SRV1 */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1_nblk.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1_nblk.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1_nblk.c	(revision 331)
@@ -0,0 +1,656 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  TCP ECHO ãµã¼ã #1
+ *
+ *    ã»éåä¿¡ã¿ã¹ã¯åä¸å
+ *    ã»ãã³ãã­ãã­ã³ã°ã³ã¼ã«
+ *    ã»çã³ãã¼ API
+ *    ã»IPv4/IPv6
+ *    ã»ç·æ¥ãã¼ã¿ã®åä¿¡
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/tcp_echo_srv1.h>
+#include <netapp/tcp_echo_srv1_var.h>
+
+#ifdef USE_TCP_ECHO_SRV1
+
+/*
+ *  è¡¨ç¤º
+ */
+
+//#define SHOW_RCV_RANGE
+
+/*
+ *  ã³ãã¯ã·ã§ã³åæ­æ¹æ³ã®æå®
+ */
+
+#define USE_TCP_SHT_CEP
+
+/*
+ *  ã¿ã¤ã ã¢ã¦ã
+ */
+
+#ifdef TOPPERS_S810_CLG3_85
+
+#define CLS_TMO		TMO_FEVR		/* Close Wait ã¯æ¨æºã§ 60ç§ */
+//#define RCV_TMO		TMO_FEVR
+#define RCV_TMO		(30*SYSTIM_HZ)
+//#define SND_TMO		TMO_FEVR
+#define SND_TMO		(30*SYSTIM_HZ)
+
+#else	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+//#define CLS_TMO		TMO_FEVR	/* Close Wait ã¯æ¨æºã§ 60ç§ */
+#define CLS_TMO		(70*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*10)
+//#define RCV_TMO		TMO_FEVR
+#define RCV_TMO		(30*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*30)
+//#define SND_TMO		TMO_FEVR
+#define SND_TMO		(40*SYSTIM_HZ+(netapp_rand()%SYSTIM_HZ)*20)
+
+#endif	/* of #ifdef TOPPERS_S810_CLG3_85 */
+
+#ifdef USE_TCP_NON_BLOCKING
+
+/*
+ *  å¤æ°
+ */
+
+#ifdef USE_TCP_EXTENTIONS
+
+T_TCP_ECHO_SRV_INFO tcp_echo_srv_info[] = {
+
+	{ 0, 0, SEM_TCP_ECHO_SRV_NBLK_READY1 },
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 2
+	{ 0, 0, SEM_TCP_ECHO_SRV_NBLK_READY2 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 3
+	{ 0, 0, SEM_TCP_ECHO_SRV_NBLK_READY3 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 4
+	{ 0, 0, SEM_TCP_ECHO_SRV_NBLK_READY4 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 5
+	{ 0, 0, SEM_TCP_ECHO_SRV_NBLK_READY5 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 6
+	{ 0, 0, SEM_TCP_ECHO_SRV_NBLK_READY6 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 7
+	{ 0, 0, SEM_TCP_ECHO_SRV_NBLK_READY7 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 8
+	{ 0, 0, SEM_TCP_ECHO_SRV_NBLK_READY8 },
+#endif
+
+	};
+
+#else	/* of #ifdef USE_TCP_EXTENTIONS */
+
+T_TCP_ECHO_SRV_INFO tcp_echo_srv_info[] = {
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV)
+
+	{ TCP4_ECHO_SRV_CEPID1, TCP4_ECHO_SRV_REPID, SEM_TCP_ECHO_SRV_NBLK_READY1 },
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV) */
+
+	{ TCP_ECHO_SRV_CEPID1, TCP_ECHO_SRV_REPID, SEM_TCP_ECHO_SRV_NBLK_READY1 },
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV) */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 2
+	{ TCP_ECHO_SRV_CEPID2, TCP_ECHO_SRV_REPID, SEM_TCP_ECHO_SRV_NBLK_READY2 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 3
+	{ TCP_ECHO_SRV_CEPID3, TCP_ECHO_SRV_REPID, SEM_TCP_ECHO_SRV_NBLK_READY3 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 4
+	{ TCP_ECHO_SRV_CEPID4, TCP_ECHO_SRV_REPID, SEM_TCP_ECHO_SRV_NBLK_READY4 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 5
+	{ TCP_ECHO_SRV_CEPID5, TCP_ECHO_SRV_REPID, SEM_TCP_ECHO_SRV_NBLK_READY5 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 6
+	{ TCP_ECHO_SRV_CEPID6, TCP_ECHO_SRV_REPID, SEM_TCP_ECHO_SRV_NBLK_READY6 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 7
+	{ TCP_ECHO_SRV_CEPID7, TCP_ECHO_SRV_REPID, SEM_TCP_ECHO_SRV_NBLK_READY7 },
+#endif
+#if NUM_TCP_ECHO_SRV_TASKS >= 8
+	{ TCP_ECHO_SRV_CEPID8, TCP_ECHO_SRV_REPID, SEM_TCP_ECHO_SRV_NBLK_READY8 },
+#endif
+
+	};
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+/*
+ *  find_srv_info -- æ¥ç¶ç¸æã®æ
+å ±æ§é ä½ãæ¢ç´¢ããã
+ */
+
+static 
+T_TCP_ECHO_SRV_INFO *find_srv_info (ID cepid)
+{
+	T_TCP_ECHO_SRV_INFO	*ri;
+
+	for (ri = &tcp_echo_srv_info[sizeof(tcp_echo_srv_info) / sizeof(T_TCP_ECHO_SRV_INFO)]; ri --; )
+		if (ri->cepid == cepid)
+			return ri;
+	return NULL;
+	}
+
+/*
+ *  ãã³ãã­ãã­ã³ã°ã³ã¼ã«ã®ã³ã¼ã«ããã¯é¢æ°
+ */
+
+ER
+callback_nblk_tcp_echo_srv (ID cepid, FN fncd, void *p_parblk)
+{
+	ER		error = E_OK;
+	T_TCP_ECHO_SRV_INFO	*ri;
+
+	if ((ri = find_srv_info(cepid)) == NULL) {
+		syslog(LOG_NOTICE, "[TESn:%02u CBN] CEPID not found", cepid);
+		return E_PAR;
+		}
+
+	switch (fncd) {
+
+	case TFN_TCP_ACP_CEP:
+		ri->error = *(ER*)p_parblk;
+		syscall(sig_sem(ri->semid));
+		break;
+
+	case TFN_TCP_RCV_DAT:
+		if ((ri->rlen = *(ER*)p_parblk) < 0)
+			syslog(LOG_NOTICE, "[TESn:%02u CBN] error: %s", cepid, itron_strerror(ri->rlen));
+		syscall(sig_sem(ri->semid));
+		break;
+
+	case TFN_TCP_SND_DAT:
+		if ((ri->slen = *(ER*)p_parblk) < 0)
+			syslog(LOG_NOTICE, "[TESn:%02u CBN] error: %s", cepid, itron_strerror(ri->slen));
+		syscall(sig_sem(ri->semid));
+		break;
+
+	case TFN_TCP_CLS_CEP:
+		if ((ri->error = *(ER*)p_parblk) < 0)
+			syslog(LOG_NOTICE, "[TESn:%02u CBN] error: %s", cepid, itron_strerror(ri->error));
+		syscall(sig_sem(ri->semid));
+		break;
+
+	case TFN_TCP_RCV_BUF:
+		if ((ri->rlen = *(ER*)p_parblk) < 0)
+			syslog(LOG_NOTICE, "[TESn:%02u CBN] error: %s", cepid, itron_strerror(ri->rlen));
+		syscall(sig_sem(ri->semid));
+		break;
+
+	case TFN_TCP_GET_BUF:
+		if ((ri->slen = *(ER*)p_parblk) < 0)
+			syslog(LOG_NOTICE, "[TESn:%02u CBN] error: %s", cepid, itron_strerror(ri->slen));
+		syscall(sig_sem(ri->semid));
+		break;
+
+#ifdef USE_TCP_EXTENTIONS
+
+	case TEV_TCP_RCV_OOB:
+		if ((ri->rlen = *(ER*)p_parblk) < 0)
+			syslog(LOG_NOTICE, "[TESn:%02u OOB] error: %s", cepid, itron_strerror(ri->rlen));
+		else if (ri->rlen > 0) {
+			char ch;
+
+			if ((ri->rlen = tcp_rcv_oob(cepid, &ch, sizeof(ch))) > 0)
+				syslog(LOG_NOTICE, "[TESn:%02u OOB] recv oob: 0x%02x", cepid, ch);
+			else if (ri->rlen < 0)
+				syslog(LOG_NOTICE, "[TESn:%02u OOB] error: %s", cepid, itron_strerror(ri->rlen));
+			}
+		break;
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+	case TFN_TCP_CON_CEP:
+	case TFN_TCP_SND_OOB:
+	default:
+		error = E_PAR;
+		break;
+		}
+	return error;
+	}
+
+/*
+ *  tcp_passive_open -- ååãªã¼ãã³ãå®è¡ããã
+ *
+ *    USE_TCP_NON_BLOCKING	ON
+ */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+static ER
+tcp_passive_open (T_TCP_ECHO_SRV_INFO *info, char apip)
+{
+	ER		error;
+	T_IPV4EP	dst4;
+
+	if (apip == API_PROTO_IPV6) {
+		/* åä»å£ã¯ IPv6 */
+		if ((error = tcp6_acp_cep(info->cepid, info->repid, &info->dst, TMO_NBLK)) != E_WBLK)
+			return error;
+
+		/* ç¸æããæ¥ç¶ãããã¾ã§å¾
+ã¤ã*/
+		syscall(wai_sem(info->semid));
+
+		if (info->error != E_OK)
+			return info->error;
+
+#ifdef USE_TCP_EXTENTIONS
+		if ((error = free_tcp6_rep(info->repid, true)) != E_OK)
+			return error;
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+		}
+	else {
+		/* åä»å£ã¯ IPv4 */
+		if ((error = tcp_acp_cep(info->cepid, info->repid, &dst4, TMO_NBLK)) != E_WBLK)
+			return error;
+
+		/* ç¸æããæ¥ç¶ãããã¾ã§å¾
+ã¤ã*/
+		syscall(wai_sem(info->semid));
+
+		if (info->error != E_OK)
+			return info->error;
+
+#ifdef USE_TCP_EXTENTIONS
+		if ((error = free_tcp4_rep(info->repid, true)) != E_OK)
+			return error;
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+		in6_make_ipv4mapped (&info->dst.ipaddr, dst4.ipaddr);
+		info->dst.portno = dst4.portno;
+
+		}
+
+	return E_OK;
+	}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+static ER
+tcp_passive_open (T_TCP_ECHO_SRV_INFO *info, char apip)
+{
+	ER		error;
+
+	if ((error = TCP_ACP_CEP(info->cepid, info->repid, &info->dst, TMO_NBLK)) != E_WBLK)
+		return error;
+
+	/* ç¸æããæ¥ç¶ãããã¾ã§å¾
+ã¤ã*/
+	syscall(wai_sem(info->semid));
+
+	if (info->error != E_OK)
+		return info->error;
+
+#ifdef USE_TCP_EXTENTIONS
+	if ((error = FREE_TCP_REP(info->repid, true)) != E_OK)
+		return error;
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+	return E_OK;
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV) */
+
+#ifdef USE_COPYSAVE_API
+
+/*
+ *  tcp_echo_srv -- TCP ã¨ã³ã¼ãµã¼ã
+ *
+ *    USE_TCP_NON_BLOCKING	ON
+ *    USE_COPYSAVE_API		ON
+ */
+
+ER
+tcp_echo_srv (uint_t six, char apip)
+{
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+	T_IN4_ADDR	ipv4addr;
+#endif
+	ER		error;
+	SYSTIM		now;
+	uint32_t	total;
+	uint16_t	rblen, sblen, rlen, slen, soff, scount, rcount;
+	char		*rbuf, *sbuf, head, tail;
+
+	if ((error = tcp_passive_open(&tcp_echo_srv_info[six], apip)) != E_OK)
+		return error;
+
+	syscall(get_tim(&now));
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+	if (apip == API_PROTO_IPV6)
+		syslog(LOG_NOTICE, "[TES6:%02u ACP] conct: %7lu,from: %s.%u",
+		                   tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+		                   ipv62str(NULL, &tcp_echo_srv_info[six].dst.ipaddr),
+		                   tcp_echo_srv_info[six].dst.portno);
+	else {
+		ipv4addr = ntohl(tcp_echo_srv_info[six].dst.ipaddr.s6_addr32[3]);
+		syslog(LOG_NOTICE, "[TES4:%02u ACP] conct: %7lu,from: %s.%u",
+		                   tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+		                   ip2str(NULL, &ipv4addr),
+		                   tcp_echo_srv_info[six].dst.portno);
+		}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	syslog(LOG_NOTICE, "[TES%c:%02u ACP] conct: %7lu,from: %s.%u",
+	                   apip, tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+	                   IP2STR(NULL, &tcp_echo_srv_info[six].dst.ipaddr),
+	                   tcp_echo_srv_info[six].dst.portno);
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	rlen = scount = rcount = total = 0;
+	while (true) {
+		if ((error = tcp_rcv_buf(tcp_echo_srv_info[six].cepid, (void**)&rbuf, TMO_NBLK)) != E_WBLK) {
+			syslog(LOG_NOTICE, "[TES%c:%02u RCV] error: %s",
+	                                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+			break;
+			}
+
+		/* åä¿¡ããã¾ã§å¾
+ã¤ã*/
+		syscall(wai_sem(tcp_echo_srv_info[six].semid));
+
+		if (tcp_echo_srv_info[six].rlen < 0) {	/* ã¨ã©ã¼ */
+			syslog(LOG_NOTICE, "[TES%c:%02u RCV] error: %s", 
+	                                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(tcp_echo_srv_info[six].rlen));
+			break;
+			}
+		else if (tcp_echo_srv_info[six].rlen == 0)	/* åä¿¡çµäº */
+			break;
+
+		rblen = tcp_echo_srv_info[six].rlen;
+
+		/* ãããã¡ã®æ®ãã«ãããåä¿¡é·ãèª¿æ´ããã*/
+		if (rblen > BUF_SIZE - rlen)
+			rblen = BUF_SIZE - rlen;
+		total += rblen;
+		rlen   = rblen;
+
+		head = *rbuf;
+		tail = *(rbuf + rblen - 1);
+		rcount ++;
+
+#ifdef SHOW_RCV_RANGE
+		syslog(LOG_NOTICE, "[TES%c:%02u RCV] "
+		                   "rcount: %7lu, len: %6lu, data %02x -> %02x",
+	                           apip, tcp_echo_srv_info[six].cepid, rcount, rblen, head, tail);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+
+		memcpy(tcp_echo_srv_info[six].buffer, rbuf, rblen);
+
+		if ((error = tcp_rel_buf(tcp_echo_srv_info[six].cepid, rlen)) < 0) {
+			syslog(LOG_NOTICE, "[TES%c:%02u REL] error: %s",
+	                                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+			break;
+			}
+
+		soff = 0;
+		while (rlen > 0) {
+
+			if ((error = tcp_get_buf(tcp_echo_srv_info[six].cepid, (void**)&sbuf, TMO_NBLK)) != E_WBLK) {
+				syslog(LOG_NOTICE, "[TES%c:%02u GET] error: %s",
+	                                           apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+				goto err_fin;
+				}
+
+			/* éä¿¡ãããã¡ã®ç²å¾ãå®äºããã¾ã§å¾
+ã¤ã*/
+			syscall(wai_sem(tcp_echo_srv_info[six].semid));
+
+			if (tcp_echo_srv_info[six].slen < 0) {
+				syslog(LOG_NOTICE, "[TES%c:%02u GET] error: %s",
+	                                           apip, tcp_echo_srv_info[six].cepid, itron_strerror(tcp_echo_srv_info[six].slen));
+				goto err_fin;
+				}
+
+			sblen = tcp_echo_srv_info[six].slen;
+			scount ++;
+			slen = sblen < rlen ? sblen : rlen;
+			memcpy(sbuf, tcp_echo_srv_info[six].buffer + soff, slen);
+
+			if ((error = tcp_snd_buf(tcp_echo_srv_info[six].cepid, slen)) != E_OK) {
+				syslog(LOG_NOTICE, "[TES%c:%02u SND] error: %s",
+	                                           apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+				goto err_fin;
+				}
+#ifdef SHOW_RCV_RANGE
+			syslog(LOG_NOTICE, "[TES%c:%02u SND] scount: %7lu, len: %4u",
+	                                   apip, cepid, scount, slen);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+
+			rlen -= slen;
+			soff += slen;
+			}
+		}
+err_fin:
+
+#ifdef USE_TCP_SHT_CEP
+	if ((error = tcp_sht_cep(tcp_echo_srv_info[six].cepid)) != E_OK)
+		syslog(LOG_NOTICE, "[TES%c:%02u SHT] error: %s",
+	                           apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+#endif	/* of #ifdef USE_TCP_SHT_CEP */
+
+	if ((error = tcp_cls_cep(tcp_echo_srv_info[six].cepid, TMO_NBLK)) != E_WBLK)
+		syslog(LOG_NOTICE, "[TES%c:%02u CLS] error: %s",
+	                           apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+
+	/* éæ¾ãå®äºããã¾ã§å¾
+ã¤ã*/
+	syscall(wai_sem(tcp_echo_srv_info[six].semid));
+
+	syscall(get_tim(&now));
+	syslog(LOG_NOTICE, "[TES%c:%02u FIN] finsh: %7lu, ttl: %lu",
+	                   apip, tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ, total);
+
+	return error == E_WBLK ? E_OK : error;
+	}
+
+#else	/* of #ifdef USE_COPYSAVE_API */
+
+/*
+ *  tcp_echo_srv -- TCP ã¨ã³ã¼ãµã¼ã
+ *
+ *    USE_TCP_NON_BLOCKING	ON
+ *    USE_COPYSAVE_API		OFF
+ */
+
+ER
+tcp_echo_srv (uint_t six, char apip)
+{
+	T_IN4_ADDR	ipv4addr;
+	ER		error;
+	SYSTIM		now;
+	uint32_t	total;
+	uint16_t	rlen, slen, soff, scount, rcount;
+	char		head, tail;
+
+	if ((error = tcp_passive_open(&tcp_echo_srv_info[six], apip)) != E_OK)
+		return error;
+
+	syscall(get_tim(&now));
+	if (apip == API_PROTO_IPV6)
+		syslog(LOG_NOTICE, "[TES6:%02u ACP] conct: %7lu,from: %s.%u",
+		                   tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+		                   ipv62str(NULL, &tcp_echo_srv_info[six].dst.ipaddr),
+		                   tcp_echo_srv_info[six].dst.portno);
+	else {
+		ipv4addr = ntohl(tcp_echo_srv_info[six].dst.ipaddr.s6_addr32[3]);
+		syslog(LOG_NOTICE, "[TES4:%02u ACP] conct: %7lu,from: %s.%u",
+		                   tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ,
+		                   ip2str(NULL, &ipv4addr),
+		                   tcp_echo_srv_info[six].dst.portno);
+		}
+
+	scount = rcount = total = 0;
+	while (true) {
+		if ((error = tcp_rcv_dat(tcp_echo_srv_info[six].cepid, tcp_echo_srv_info[six].buffer, BUF_SIZE - 1, TMO_NBLK)) != E_WBLK) {
+			syslog(LOG_NOTICE, "[TES%c:%02u RCV] error: %s",
+	                                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+			break;
+			}
+
+		/* åä¿¡å®äºã¾ã§å¾
+ã¤ã*/
+		syscall(wai_sem(tcp_echo_srv_info[six].semid));
+
+		if (tcp_echo_srv_info[six].rlen < 0) {
+			syslog(LOG_NOTICE, "[TES%c:%02u RCV] error: %s",
+	                                   apip, tcp_echo_srv_info[six].cepid, itron_strerror(tcp_echo_srv_info[six].rlen));
+			break;
+			}
+		else if (tcp_echo_srv_info[six].rlen == 0)
+			break;
+
+		rlen = tcp_echo_srv_info[six].rlen;
+		head = * tcp_echo_srv_info[six].buffer;
+		tail = *(tcp_echo_srv_info[six].buffer + rlen - 1);
+		rcount ++;
+
+#ifdef SHOW_RCV_RANGE
+		syslog(LOG_NOTICE, "[TES%c:%02u RCV] rcount: %4u, len: %4u, data %02x -> %02x",
+	                           apip, tcp_echo_srv_info[six].cepid, rcount, rlen, head, tail);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+
+		total += rlen;
+		soff = 0;
+		while (rlen > 0) {
+			scount ++;
+			if ((error = tcp_snd_dat(tcp_echo_srv_info[six].cepid, &tcp_echo_srv_info[six].buffer[soff], rlen, TMO_NBLK)) != E_WBLK) {
+				syslog(LOG_NOTICE, "[TES%c:%02u SND] error: %s",
+	                                           apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+				goto err_fin;
+				}
+
+			/* éä¿¡å®äºã¾ã§å¾
+ã¤ã*/
+			syscall(wai_sem(tcp_echo_srv_info[six].semid));
+
+			if (tcp_echo_srv_info[six].slen < 0) {
+				syslog(LOG_NOTICE, "[TES%c:%02u SND] error: %s",
+	                                           apip, tcp_echo_srv_info[six].cepid, itron_strerror(tcp_echo_srv_info[six].slen));
+				goto err_fin;
+				}
+
+			slen = tcp_echo_srv_info[six].slen;
+
+#ifdef SHOW_RCV_RANGE
+			syslog(LOG_NOTICE, "[TES%c:%02u SND] scount: %4u, len: %4u",
+	                                   apip, tcp_echo_srv_info[six].cepid, scount, slen);
+#endif	/* of #ifdef SHOW_RCV_RANGE */
+
+			rlen -= slen;
+			soff += slen;
+			}
+		}
+err_fin:
+
+#ifdef USE_TCP_SHT_CEP
+	if ((error = tcp_sht_cep(tcp_echo_srv_info[six].cepid)) != E_OK)
+		syslog(LOG_NOTICE, "[TES%c:%02u SHT] error: %s",
+	                           apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+#endif	/* of #ifdef USE_TCP_SHT_CEP */
+
+	if ((error = tcp_cls_cep(tcp_echo_srv_info[six].cepid, TMO_NBLK)) != E_WBLK)
+		syslog(LOG_NOTICE, "[TES%c:%02u CLS] error: %s",
+	                           apip, tcp_echo_srv_info[six].cepid, itron_strerror(error));
+
+	/* éæ¾ãå®äºããã¾ã§å¾
+ã¤ã*/
+	syscall(wai_sem(tcp_echo_srv_info[six].semid));
+
+	syscall(get_tim(&now));
+	syslog(LOG_NOTICE, "[TES%c:%02u FIN] finsh: %7lu, ttl: %lu",
+	                   apip, tcp_echo_srv_info[six].cepid, now / SYSTIM_HZ, total);
+
+	return error == E_WBLK ? E_OK : error;
+	}
+
+#endif	/* of #ifdef USE_COPYSAVE_API */
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#endif	/* of #ifdef USE_TCP_ECHO_SRV1 */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1_var.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1_var.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv1_var.h	(revision 331)
@@ -0,0 +1,111 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#ifdef USE_TCP_ECHO_SRV1
+
+#ifndef _TCP_ECHO_SRV1_VAR_H_
+#define _TCP_ECHO_SRV1_VAR_H_
+
+/*
+ *  æ³¨æ:
+ *
+ *    BUF_SIZE ã¯ TCP ã®
+ *    éä¿¡ã¦ã¤ã³ãã¦ãããã¡ãµã¤ãº + åä¿¡ã¦ã¤ã³ãã¦ãããã¡ãµã¤ãºã® 
+ *    3/2 åä»¥ä¸ã®å¤§ããããªããã°ããããã­ãã¯ããå¯è½æ§ãããã
+ */
+
+#define BUF_SIZE	((TCP_ECHO_SRV_SWBUF_SIZE + \
+                          TCP_ECHO_SRV_RWBUF_SIZE) * 3 / 2)
+
+/*
+ *  ãµã¼ãæ
+å ±æ§é ä½
+ */
+
+typedef struct t_tcp_echo_srv_info {
+	ID	cepid;		/* éä¿¡ç«¯ç¹ ID		*/
+	ID	repid;		/* åä»å£   ID		*/
+
+#ifdef USE_TCP_NON_BLOCKING
+	ID	semid;		/* NBLK ç¨ ã»ããã©ID	*/
+	ER	error;		/* NBLK ç¨ error	*/
+	ER_UINT	slen;		/* NBLK ç¨ éä¿¡ãã¼ã¿æ°	*/
+	ER_UINT	rlen;		/* NBLK ç¨ åä¿¡ãã¼ã¿æ°	*/
+#endif
+
+	T_IPEP	dst;		/* æ¥ç¶ç¸æã¢ãã¬ã¹æ
+å ±	*/
+
+#ifdef USE_TCP_NON_BLOCKING
+
+	char	buffer[BUF_SIZE];
+
+#else	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#ifndef USE_COPYSAVE_API
+	char	buffer[BUF_SIZE];
+#endif
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+	} T_TCP_ECHO_SRV_INFO;
+
+#define INDEX_SRV_INFO(id)	((id)-1)
+
+/*
+ *  å¤æ°
+ */
+
+extern T_TCP_ECHO_SRV_INFO tcp_echo_srv_info[];
+
+/*
+ *  é¢æ°
+ */
+
+extern ER tcp_echo_srv (uint_t six, char apip);
+
+#endif	/* of #ifndef _TCP_ECHO_SRV1_VAR_H_ */
+
+#endif	/* of #ifdef USE_TCP_ECHO_SRV1 */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -70,10 +70,9 @@
 #include <netinet/in_itron.h>
 #include <netinet/ip.h>
-#include <netinet/ip6.h>
 #include <netinet/tcp.h>
 
 #include <netapp/netapp.h>
 #include <netapp/netapp_var.h>
-#include <netapp/echo.h>
+#include <netapp/tcp_echo_srv2.h>
 
 #ifdef USE_TCP_ECHO_SRV2
@@ -161,9 +160,9 @@
 			snd_error = 1;
 			ena_rcv   = true;
-			syslog(LOG_NOTICE, "[TES:%02d CBN] connected:  %6ld, from: %s.%d",
+			syslog(LOG_NOTICE, "[TES:%02u CBN] connect: %6lu, from: %s.%d",
 			                   cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
 			}
 		else
-			syslog(LOG_NOTICE, "[TES:%02d CBN] accept error: %s\n", cepid, itron_strerror(rcv_error));
+			syslog(LOG_NOTICE, "[TES:%02u CBN] accept error: %s\n", cepid, itron_strerror(rcv_error));
 
 		syscall(sig_sem(SEM_TCP_ECHO_SRV_RCV_READY));
@@ -176,5 +175,5 @@
 			tail = *(sptr + slen - 1);
 #ifdef SHOW_RCV_RANGE
-			syslog(LOG_NOTICE, "[TES:%02d CBN] send len: %4d, data %02x -> %02x",
+			syslog(LOG_NOTICE, "[TES:%02u CBN] send len: %4u, data %02x -> %02x",
 			                   cepid, (uint16_t)slen, head, tail);
 #endif	/* of #ifdef SHOW_RCV_RANGE */
@@ -205,5 +204,5 @@
 			}
 		else {
-			syslog(LOG_NOTICE, "[TES:%02d CBN] send error = %s", cepid, itron_strerror(snd_error));
+			syslog(LOG_NOTICE, "[TES:%02u CBN] send error = %s", cepid, itron_strerror(snd_error));
 			sig_sem(SEM_TCP_ECHO_SRV_SND_READY);
 			}
@@ -216,5 +215,5 @@
 			tail = *(rptr + rlen - 1);
 #ifdef SHOW_RCV_RANGE
-			syslog(LOG_NOTICE, "[TES:%02d CBN] recv len: %4d, data %02x -> %02x",
+			syslog(LOG_NOTICE, "[TES:%02u CBN] recv len: %4u, data %02x -> %02x",
 			                   cepid, (uint16_t)rlen, head, tail);
 #endif	/* of #ifdef SHOW_RCV_RANGE */
@@ -246,5 +245,5 @@
 		else {
 			if (rlen < 0)
-				syslog(LOG_NOTICE, "[TES:%02d CBN] recv error = %s", cepid, itron_strerror(rcv_error));
+				syslog(LOG_NOTICE, "[TES:%02u CBN] recv error = %s", cepid, itron_strerror(rcv_error));
 			sig_sem(SEM_TCP_ECHO_SRV_RCV_READY);
 			}
@@ -254,7 +253,7 @@
 		snd_error = *(ER*)p_parblk;
 		if (snd_error != E_OK)
-			syslog(LOG_NOTICE, "[TES:%02d CBN] close error = %s", cepid, itron_strerror(snd_error));
-
-		syslog(LOG_NOTICE, "[TES:%02d CBN] finished:   %6ld, snd: %4d, rcv: %4d, len: %ld",
+			syslog(LOG_NOTICE, "[TES:%02u CBN] close error = %s", cepid, itron_strerror(snd_error));
+
+		syslog(LOG_NOTICE, "[TES:%02u CBN] finish:  %6lu, snd: %4u, rcv: %4u, len: %ld",
 		                   cepid, now / SYSTIM_HZ, snd_count, rcv_count, snd_total);
 
@@ -283,10 +282,10 @@
 
 	if ((error = psnd_dtq(DTQ_TCP_ECHO_SRV_SND, (intptr_t)cepid)) != E_OK) {
-		syslog(LOG_NOTICE, "[TES:%02d RCV] sync error: %s", cepid, itron_strerror(error));
+		syslog(LOG_NOTICE, "[TES:%02u RCV] sync error: %s", cepid, itron_strerror(error));
 		return error;
 		}
 
 	if ((error = TCP_ACP_CEP(cepid, repid, &dst, TMO_NBLK)) != E_WBLK) {
-		syslog(LOG_NOTICE, "[TES:%02d ACP] accept error = %s", cepid, itron_strerror(error));
+		syslog(LOG_NOTICE, "[TES:%02u ACP] accept error = %s", cepid, itron_strerror(error));
 		return error;
 		}
@@ -300,6 +299,6 @@
 
 #ifdef USE_TCP_EXTENTIONS
-	if ((error = free_tcp_rep(repid, true)) != E_OK) {
-		syslog(LOG_NOTICE, "[TES:%02d DEL] REP delete error: %s", cepid, itron_strerror(error));
+	if ((error = FREE_TCP_REP(repid, true)) != E_OK) {
+		syslog(LOG_NOTICE, "[TES:%02u DEL] REP delete error: %s", cepid, itron_strerror(error));
 		return error;
 		}
@@ -318,5 +317,5 @@
 		/* 受信する。*/
 		if ((error = tcp_rcv_dat(cepid, rptr, blen, TMO_NBLK)) != E_WBLK) {
-			syslog(LOG_NOTICE, "[TES:%02d RCV] recv error = %s", cepid, itron_strerror(error));
+			syslog(LOG_NOTICE, "[TES:%02u RCV] recv error = %s", cepid, itron_strerror(error));
 			break;
 			}
@@ -359,5 +358,5 @@
 	while (true) {
 		if ((error = rcv_dtq(DTQ_TCP_ECHO_SRV_SND, (intptr_t*)&cepid)) != E_OK) {
-			syslog(LOG_NOTICE, "[TES:%02d SND] sync error: %s",
+			syslog(LOG_NOTICE, "[TES:%02u SND] sync error: %s",
 			                   cepid, itron_strerror(error));
 			continue;
@@ -387,5 +386,5 @@
 			/* 送信する。*/
 			if ((error = tcp_snd_dat(cepid, sptr, blen, TMO_NBLK)) != E_WBLK) {
-				syslog(LOG_NOTICE, "[TES:%02d SND] send error = %s", cepid, itron_strerror(error));
+				syslog(LOG_NOTICE, "[TES:%02u SND] send error = %s", cepid, itron_strerror(error));
 				break;
 				}
@@ -398,9 +397,9 @@
 #ifdef USE_TCP_SHT_CEP
 		if ((error = tcp_sht_cep(cepid)) != E_OK)
-			syslog(LOG_NOTICE, "[TES:%02d SND] shutdown error = %s", cepid, itron_strerror(error));
+			syslog(LOG_NOTICE, "[TES:%02u SND] shutdown error = %s", cepid, itron_strerror(error));
 #endif	/* of #ifdef USE_TCP_SHT_CEP */
 
 		if ((error = tcp_cls_cep(cepid, TMO_NBLK)) != E_WBLK) {
-			syslog(LOG_NOTICE, "[TES:%02d SND] close error = %s", cepid, itron_strerror(error));
+			syslog(LOG_NOTICE, "[TES:%02u SND] close error = %s", cepid, itron_strerror(error));
 			}
 
@@ -426,16 +425,16 @@
 
 	if ((error = psnd_dtq(DTQ_TCP_ECHO_SRV_SND, (intptr_t)cepid)) != E_OK) {
-		syslog(LOG_NOTICE, "[TES:%02d RCV] sync error: %s", cepid, itron_strerror(error));
+		syslog(LOG_NOTICE, "[TES:%02u RCV] sync error: %s", cepid, itron_strerror(error));
 		return error;
 		}
 
 	if ((error = TCP_ACP_CEP(cepid, repid, &dst, TMO_FEVR)) != E_OK) {
-		syslog(LOG_NOTICE, "[TES:%02d ACP] accept error = %s", cepid, itron_strerror(error));
+		syslog(LOG_NOTICE, "[TES:%02u ACP] accept error = %s", cepid, itron_strerror(error));
 		return error;
 		}
 
 #ifdef USE_TCP_EXTENTIONS
-	if ((error = free_tcp_rep(repid, true)) != E_OK) {
-		syslog(LOG_NOTICE, "[TES:%02d DEL] REP delete error: %s", cepid, itron_strerror(error));
+	if ((error = FREE_TCP_REP(repid, true)) != E_OK) {
+		syslog(LOG_NOTICE, "[TES:%02u DEL] REP delete error: %s", cepid, itron_strerror(error));
 		return error;
 		}
@@ -443,5 +442,5 @@
 
 	syscall(get_tim(&now));
-	syslog(LOG_NOTICE, "[TES:%02d ACP] connected:  %6ld, from: %s.%d",
+	syslog(LOG_NOTICE, "[TES:%02u ACP] connect: %6lu, from: %s.%d",
 	                   cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
 	sptr = rptr = buffer;
@@ -461,5 +460,5 @@
 		if ((rlen = tcp_rcv_dat(cepid, rptr, blen, TMO_FEVR)) <= 0) {
 			if (rlen < 0)
-				syslog(LOG_NOTICE, "[TES:%02d RCV] recv error = %s",
+				syslog(LOG_NOTICE, "[TES:%02u RCV] recv error = %s",
 				                   cepid, itron_strerror(rlen));
 			break;
@@ -468,5 +467,5 @@
 		tail = *(rptr + rlen - 1);
 #ifdef SHOW_RCV_RANGE
-		syslog(LOG_NOTICE, "[TES:%02d RCV] len: %4d, data %02x -> %02x",
+		syslog(LOG_NOTICE, "[TES:%02u RCV] len: %4u, data %02x -> %02x",
 		                   cepid, (uint16_t)rlen, head, tail);
 #endif	/* of #ifdef SHOW_RCV_RANGE */
@@ -531,5 +530,5 @@
 	while (true) {
 		if ((error = rcv_dtq(DTQ_TCP_ECHO_SRV_SND, (intptr_t*)&cepid)) != E_OK) {
-			syslog(LOG_NOTICE, "[TES:%02d SND] sync error: %s",
+			syslog(LOG_NOTICE, "[TES:%02u SND] sync error: %s",
 			                   cepid, itron_strerror(error));
 			continue;
@@ -554,5 +553,5 @@
 
 			if ((slen = tcp_snd_dat(cepid, sptr, blen, TMO_FEVR)) <= 0) {
-				syslog(LOG_NOTICE, "[TES:%02d SND] send error = %s", cepid, itron_strerror(slen));
+				syslog(LOG_NOTICE, "[TES:%02u SND] send error = %s", cepid, itron_strerror(slen));
 				break;
 				}
@@ -561,5 +560,5 @@
 			tail = *(sptr + slen - 1);
 #ifdef SHOW_RCV_RANGE
-			syslog(LOG_NOTICE, "[TES:%02d SND] len: %4d, data %02x -> %02x",
+			syslog(LOG_NOTICE, "[TES:%02u SND] len: %4u, data %02x -> %02x",
 			                   cepid, (uint16_t)slen, head, tail);
 #endif	/* of #ifdef SHOW_RCV_RANGE */
@@ -602,12 +601,12 @@
 #ifdef USE_TCP_SHT_CEP
 		if ((error = tcp_sht_cep(cepid)) != E_OK)
-			syslog(LOG_NOTICE, "[TES:%02d SND] shtudown error = %s", cepid, itron_strerror(error));
+			syslog(LOG_NOTICE, "[TES:%02u SND] shtudown error = %s", cepid, itron_strerror(error));
 #endif	/* of #ifdef USE_TCP_SHT_CEP */
 
 		if ((error = tcp_cls_cep(cepid, TMO_FEVR)) != E_OK)
-			syslog(LOG_NOTICE, "[TES:%02d SND] close error = %s", cepid, itron_strerror(error));
+			syslog(LOG_NOTICE, "[TES:%02u SND] close error = %s", cepid, itron_strerror(error));
 
 		get_tim(&now);
-		syslog(LOG_NOTICE, "[TES:%02d SND] finished:   %6ld, snd: %4d, rcv: %4d, len: %ld",
+		syslog(LOG_NOTICE, "[TES:%02u SND] finish:  %6lu, snd: %4u, rcv: %4u, len: %ld",
 		                   cepid, now / SYSTIM_HZ, snd_count, rcv_count, snd_total);
 
@@ -646,5 +645,5 @@
 #endif
 
-	return alloc_tcp_rep(repid, tskid, &crep);
+	return ALLOC_TCP_REP(repid, tskid, &crep);
 	}
 
@@ -681,5 +680,5 @@
 #endif
 
-	return alloc_tcp_cep(cepid, tskid, &ccep);
+	return ALLOC_TCP_CEP(cepid, tskid, &ccep);
 	}
 
@@ -711,5 +710,5 @@
 				}
 			else if ((error = tcp_echo_srv_rcv(cepid, repid)) != E_OK) {
-				error = free_tcp_rep(repid, error != E_DLT);
+				error = FREE_TCP_REP(repid, error != E_DLT);
 				break;
 				}
@@ -717,5 +716,5 @@
 
 		if ((error = free_tcp_cep(cepid)) != E_OK)
-			syslog(LOG_NOTICE, "[TES:%02d EXT] CEP delete error: %s", cepid, itron_strerror(error));
+			syslog(LOG_NOTICE, "[TES:%02u EXT] CEP delete error: %s", cepid, itron_strerror(error));
 
 		}
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tcp_echo_srv2.h	(revision 331)
@@ -0,0 +1,127 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#ifdef USE_TCP_ECHO_SRV2
+
+#ifndef _TCP_ECHO_SRV2_H_
+#define _TCP_ECHO_SRV2_H_
+
+/* 
+ *  TCP ECHO ãµã¼ã #2
+ *
+ *    ã»éåä¿¡ã¿ã¹ã¯åé¢å
+ *    ã»ãã³ãã­ãã­ã³ã°ã³ã¼ã«
+ *    ã»IPv4/IPv6
+ */
+
+/* ã¹ã¿ãã¯ãµã¤ãº */
+
+#define TCP_ECHO_SRV_STACK_SIZE		1024		/* TCP ECHO ãµã¼ãã¿ã¹ã¯ã®ã¹ã¿ãã¯ãµã¤ãº		*/
+
+/* åªå
+åº¦ */
+
+#define TCP_ECHO_SRV_MAIN_PRIORITY	5		/* TCP ECHO ãµã¼ãã¿ã¹ã¯ã®åªå
+åº¦			*/
+
+/*
+ *  TCP éåä¿¡ã¦ã¤ã³ããããã¡ãµã¤ãº
+ */
+
+#if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU)
+
+#if defined(SUPPORT_INET6)
+
+#define TCP_ECHO_SRV_SWBUF_SIZE		(1024)
+#define TCP_ECHO_SRV_RWBUF_SIZE		(1024)
+
+#elif defined(SUPPORT_INET4)
+
+#define TCP_ECHO_SRV_SWBUF_SIZE		(512)
+#define TCP_ECHO_SRV_RWBUF_SIZE		(512)
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#else	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+#define TCP_ECHO_SRV_SWBUF_SIZE		(1024)
+#define TCP_ECHO_SRV_RWBUF_SIZE		(1024)
+
+#endif	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
+
+/* ã¿ã¹ã¯æ° */
+
+#if defined(USE_TCP_ECHO_SRV2)
+#if defined(NUM_TCP_ECHO_SRV_TASKS)
+#undef  NUM_TCP_ECHO_SRV_TASKS
+#endif	/* of #if defined(NUM_TCP_ECHO_SRV_TASKS) */
+#define NUM_TCP_ECHO_SRV_TASKS		1
+#endif	/* of #if defined(USE_TCP_ECHO_SRV2) */
+
+/*
+ *  å¤æ°
+ */
+
+/* TCP éåä¿¡ã¦ã£ã³ããããã¡ */
+
+extern uint8_t tcp_echo_srv_swbuf[NUM_TCP_ECHO_SRV_TASKS][TCP_ECHO_SRV_SWBUF_SIZE];
+extern uint8_t tcp_echo_srv_rwbuf[NUM_TCP_ECHO_SRV_TASKS][TCP_ECHO_SRV_RWBUF_SIZE];
+
+/*
+ *  ã¿ã¹ã¯
+ */
+
+extern void	tcp_echo_srv_rcv_task(intptr_t exinf);
+extern void	tcp_echo_srv_snd_task(intptr_t exinf);
+
+/*
+ *  é¢æ°
+ */
+
+extern ER callback_nblk_tcp_echo_srv (ID cepid, FN fncd, void *p_parblk);
+
+#endif	/* of #ifndef _TCP_ECHO_SRV2_H_ */
+
+#endif	/* of #ifdef USE_TCP_ECHO_SRV2 */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_dbg_cons.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_dbg_cons.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_dbg_cons.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (UDP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -43,69 +43,69 @@
 /* TCP 受付口 */
 
+#ifdef SUPPORT_INET6
+
+#if NUM_VRID_TCP6_REPS >= 1
+VRID_TCP6_REP (TCP6_RSV_REPID1);
+#endif
+
+#if NUM_VRID_TCP6_REPS >= 2
+VRID_TCP6_REP (TCP6_RSV_REPID2);
+#endif
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
 #ifdef SUPPORT_INET4
 
-#if NUM_VRID_TCP_REPS >= 1
-VRID_TCP_REP (TCP_RSV_REPID1);
+#if NUM_VRID_TCP4_REPS >= 1
+VRID_TCP_REP (TCP4_RSV_REPID1);
 #endif
 
-#if NUM_VRID_TCP_REPS >= 2
-VRID_TCP_REP (TCP_RSV_REPID2);
+#if NUM_VRID_TCP4_REPS >= 2
+VRID_TCP_REP (TCP4_RSV_REPID2);
 #endif
 
 #endif	/* of #ifdef SUPPORT_INET4 */
 
+/* TCP 通信端点 */
+
 #ifdef SUPPORT_INET6
 
-#if NUM_VRID_TCP_REPS >= 1
-VRID_TCP6_REP (TCP_RSV_REPID1);
+#if NUM_VRID_TCP6_CEPS >= 1
+VRID_TCP6_CEP (TCP6_RSV_CEPID1);
 #endif
 
-#if NUM_VRID_TCP_REPS >= 2
-VRID_TCP6_REP (TCP_RSV_REPID2);
+#if NUM_VRID_TCP6_CEPS >= 2
+VRID_TCP6_CEP (TCP6_RSV_CEPID2);
+#endif
+
+#if NUM_VRID_TCP6_CEPS >= 3
+VRID_TCP6_CEP (TCP6_RSV_CEPID3);
+#endif
+
+#if NUM_VRID_TCP6_CEPS >= 4
+VRID_TCP6_CEP (TCP6_RSV_CEPID4);
 #endif
 
 #endif	/* of #ifdef SUPPORT_INET6 */
 
-/* TCP 通信端点 */
-
 #ifdef SUPPORT_INET4
 
-#if NUM_VRID_TCP_CEPS >= 1
-VRID_TCP_CEP (TCP_RSV_CEPID1);
+#if NUM_VRID_TCP4_CEPS >= 1
+VRID_TCP_CEP (TCP4_RSV_CEPID1);
 #endif
 
-#if NUM_VRID_TCP_CEPS >= 2
-VRID_TCP_CEP (TCP_RSV_CEPID2);
+#if NUM_VRID_TCP4_CEPS >= 2
+VRID_TCP_CEP (TCP4_RSV_CEPID2);
 #endif
 
-#if NUM_VRID_TCP_CEPS >= 3
-VRID_TCP_CEP (TCP_RSV_CEPID3);
+#if NUM_VRID_TCP4_CEPS >= 3
+VRID_TCP_CEP (TCP4_RSV_CEPID3);
 #endif
 
-#if NUM_VRID_TCP_CEPS >= 4
-VRID_TCP_CEP (TCP_RSV_CEPID4);
+#if NUM_VRID_TCP4_CEPS >= 4
+VRID_TCP_CEP (TCP4_RSV_CEPID4);
 #endif
 
 #endif	/* of #ifdef SUPPORT_INET4 */
-
-#ifdef SUPPORT_INET6
-
-#if NUM_VRID_TCP_CEPS >= 1
-VRID_TCP6_CEP (TCP_RSV_CEPID1);
-#endif
-
-#if NUM_VRID_TCP_CEPS >= 2
-VRID_TCP6_CEP (TCP_RSV_CEPID2);
-#endif
-
-#if NUM_VRID_TCP_CEPS >= 3
-VRID_TCP6_CEP (TCP_RSV_CEPID3);
-#endif
-
-#if NUM_VRID_TCP_CEPS >= 4
-VRID_TCP6_CEP (TCP_RSV_CEPID4);
-#endif
-
-#endif	/* of #ifdef SUPPORT_INET6 */
 
 #endif	/* of #ifdef USE_TCP_EXTENTIONS */
@@ -115,28 +115,28 @@
 /* UDP 通信端点 */
 
+#ifdef SUPPORT_INET6
+
+#if NUM_VRID_UDP6_CEPS >= 1
+VRID_UDP6_CEP (UDP6_RSV_CEPID1);
+#endif
+
+#if NUM_VRID_UDP6_CEPS >= 2
+VRID_UDP6_CEP (UDP6_RSV_CEPID2);
+#endif
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
 #ifdef SUPPORT_INET4
 
-#if NUM_VRID_UDP_CEPS >= 1
-VRID_UDP_CEP (UDP_RSV_CEPID1);
+#if NUM_VRID_UDP4_CEPS >= 1
+VRID_UDP_CEP (UDP4_RSV_CEPID1);
 #endif
 
-#if NUM_VRID_UDP_CEPS >= 2
-VRID_UDP_CEP (UDP_RSV_CEPID2);
+#if NUM_VRID_UDP4_CEPS >= 2
+VRID_UDP_CEP (UDP4_RSV_CEPID2);
 #endif
 
 #endif	/* of #ifdef SUPPORT_INET4 */
 
-#ifdef SUPPORT_INET6
-
-#if NUM_VRID_UDP_CEPS >= 1
-VRID_UDP6_CEP (UDP_RSV_CEPID1);
-#endif
-
-#if NUM_VRID_UDP_CEPS >= 2
-VRID_UDP6_CEP (UDP_RSV_CEPID2);
-#endif
-
-#endif	/* of #ifdef SUPPORT_INET6 */
-
 #endif	/* of #ifdef USE_UDP_EXTENTIONS */
 
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_dhcp4_cli.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_dhcp4_cli.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_dhcp4_cli.cfg	(revision 331)
@@ -0,0 +1,61 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2011 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  DHCP ã¯ã©ã¤ã¢ã³ã
+ *  TCP/IP ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ */
+
+#ifdef DHCP4_CLI_CFG
+
+/* UDP éä¿¡ç«¯ç¹ */
+
+UDP_CRE_CEP (UDP4_DHCP_CLI_CEPID, {
+	0,
+	{ IPV4_ADDRANY, DHCP4_CLI_CFG_PORTNO },
+	callback_nblk_dhcp4_cli
+	} );
+
+#endif	/* of #ifdef DHCP4_CLI_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_dhcp6_cli.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_dhcp6_cli.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_dhcp6_cli.cfg	(revision 331)
@@ -0,0 +1,61 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2011 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  DHCP/DHCPv6 ã¯ã©ã¤ã¢ã³ã
+ *  TCP/IP ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ */
+
+#ifdef DHCP6_CLI_CFG
+
+/* UDP éä¿¡ç«¯ç¹ */
+
+UDP6_CRE_CEP (UDP6_DHCP_CLI_CEPID, {
+	0,
+	{ IPV6_ADDRANY, DHCP6_CLI_CFG_PORTNO },
+	callback_nblk_dhcp6_cli
+	} );
+
+#endif	/* of #ifdef DHCP6_CLI_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_net_cons.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_net_cons.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_net_cons.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -41,4 +41,13 @@
 /* TCP 受付口 */
 
+#ifdef SUPPORT_INET6
+
+TCP6_CRE_REP (NET_CONS_REPID, {
+	0,
+	{ IPV6_ADDRANY, 23 }
+	} );
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
 #ifdef SUPPORT_INET4
 
@@ -50,14 +59,35 @@
 #endif	/* of #ifdef SUPPORT_INET4 */
 
-#ifdef SUPPORT_INET6
-
-TCP6_CRE_REP (NET_CONS_REPID, {
-	0,
-	{ IPV6_ADDRANY, 23 }
-	} );
-
 #endif	/* of #ifdef SUPPORT_INET6 */
 
 /* TCP 通信端点 */
+
+#ifdef SUPPORT_INET6
+
+#ifdef TCP_CFG_SWBUF_CSAVE
+
+TCP6_CRE_CEP (NET_CONS_CEPID, {
+	0,
+	NADR,
+	NET_CONS_SWBUF_SIZE,
+	NADR,
+	NET_CONS_RWBUF_SIZE,
+	callback_nblk_net_cons
+	} );
+
+#else	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+TCP6_CRE_CEP (NET_CONS_CEPID, {
+	0,
+	net_cons_swbuf,
+	NET_CONS_SWBUF_SIZE,
+	net_cons_rwbuf,
+	NET_CONS_RWBUF_SIZE,
+	callback_nblk_net_cons
+	} );
+
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+#else	/* of #ifdef SUPPORT_INET6 */
 
 #ifdef SUPPORT_INET4
@@ -89,30 +119,4 @@
 #endif	/* of #ifdef SUPPORT_INET4 */
 
-#ifdef SUPPORT_INET6
-
-#ifdef TCP_CFG_SWBUF_CSAVE
-
-TCP6_CRE_CEP (NET_CONS_CEPID, {
-	0,
-	NADR,
-	NET_CONS_SWBUF_SIZE,
-	NADR,
-	NET_CONS_RWBUF_SIZE,
-	callback_nblk_net_cons
-	} );
-
-#else	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
-
-TCP6_CRE_CEP (NET_CONS_CEPID, {
-	0,
-	net_cons_swbuf,
-	NET_CONS_SWBUF_SIZE,
-	net_cons_rwbuf,
-	NET_CONS_RWBUF_SIZE,
-	callback_nblk_net_cons
-	} );
-
-#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
-
 #endif	/* of #ifdef SUPPORT_INET6 */
 
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_resolver.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_resolver.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_resolver.cfg	(revision 331)
@@ -0,0 +1,75 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  RESOLVER ã¯ã©ã¤ã¢ã³ã
+ *  TCP/IP ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ */
+
+#ifdef USE_RESOLVER
+
+/* UDP éä¿¡ç«¯ç¹ */
+
+#ifdef SUPPORT_INET6
+
+UDP6_CRE_CEP (UDP6_RESOLVER_CEPID, {
+	0,
+	{ IPV6_ADDRANY, UDP_PORTANY },
+	NULL
+	} );
+
+#endif	/* of #ifdef SUPPORT_INET6 */
+
+#ifdef SUPPORT_INET4
+
+UDP_CRE_CEP (UDP4_RESOLVER_CEPID, {
+	0,
+	{ IPV4_ADDRANY, UDP_PORTANY },
+	NULL
+	} );
+
+#endif	/* of #ifdef SUPPORT_INET4 */
+
+#endif	/* of #ifdef USE_RESOLVER */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp4_echo_srv1.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp4_echo_srv1.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp4_echo_srv1.cfg	(revision 331)
@@ -0,0 +1,488 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP ECHO ãµã¼ãã® TCP/IP ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ *
+ *    SUPPORT_INET4
+ *    USE_TCP_NON_BLOCKING: OFF
+ *    USE_TCP_EXTENTIONS:   OFF
+ *    TCP éä¿¡ç«¯ç¹ãNUM_TCP_ECHO_SRV_TASKS >= 2 ä»¥é
+ * 
+ */
+
+/* TCP éä¿¡ç«¯ç¹ */
+
+#if defined(USE_TCP_ECHO_SRV1)
+
+#if defined(USE_TCP_EXTENTIONS)
+
+#else	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#if defined(SUPPORT_INET6)
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+#if defined(USE_TCP_NON_BLOCKING)
+
+#else	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 2
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[1],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[1],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[1],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[1],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 2 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 3
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[2],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[2],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[2],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[2],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 3 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 4
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[3],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[3],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[3],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[3],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 4 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 5
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[4],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[4],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[4],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[4],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 5 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 6
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[5],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[5],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[5],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[5],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 6 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 7
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[6],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[6],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[6],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[6],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 7 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 8
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[7],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[7],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[7],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[7],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 8 */
+
+#endif	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#endif	/* of #if defined(USE_TCP_ECHO_SRV1) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp4_echo_srv1_nblk.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp4_echo_srv1_nblk.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp4_echo_srv1_nblk.cfg	(revision 331)
@@ -0,0 +1,486 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP ECHO ãµã¼ãã® TCP/IP ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ *
+ *    SUPPORT_INET4
+ *    USE_TCP_NON_BLOCKING: ON
+ *    USE_TCP_EXTENTIONS:   OFF
+ *    TCP éä¿¡ç«¯ç¹ãNUM_TCP_ECHO_SRV_TASKS >= 2 ä»¥é
+ * 
+ */
+
+/* TCP éä¿¡ç«¯ç¹ */
+
+#if defined(USE_TCP_ECHO_SRV1)
+
+#if defined(USE_TCP_EXTENTIONS)
+
+#else	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#if defined(SUPPORT_INET6)
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+#if defined(USE_TCP_NON_BLOCKING)
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 2
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[1],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[1],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[1],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[1],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 2 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 3
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[2],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[2],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[2],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[2],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 3 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 4
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[3],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[3],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[3],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[3],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 4 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 5
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[4],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[4],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[4],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[4],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 5 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 6
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[5],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[5],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[5],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[5],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 6 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 7
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[6],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[6],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[6],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[6],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 7 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 8
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[7],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[7],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[7],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[7],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 8 */
+
+#endif	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#endif	/* of #if defined(USE_TCP_ECHO_SRV1) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp64_echo_srv1.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp64_echo_srv1.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp64_echo_srv1.cfg	(revision 331)
@@ -0,0 +1,362 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP ECHO ãµã¼ãã® TCP/IP ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ *
+ *    SUPPORT_INET6
+ *    SUPPORT_INET4
+ *    USE_TCP_NON_BLOCKING: OFF
+ *    USE_TCP_EXTENTIONS:   OFF
+ *    TCP åä»å£
+ *    TCP éä¿¡ç«¯ç¹ãNUM_TCP_ECHO_SRV_TASKS == 1
+ * 
+ */
+
+#if defined(USE_TCP_ECHO_SRV1)
+
+/*
+ * TCP åä»å£
+ */
+
+#if defined(USE_TCP_EXTENTIONS)
+
+#else	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#if defined(SUPPORT_INET6)
+
+TCP6_CRE_REP (TCP_ECHO_SRV_REPID, {
+	TA_NULL,
+	{ IPV6_ADDRANY, 7 }
+	} );
+
+#if defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV)
+
+TCP_CRE_REP (TCP4_ECHO_SRV_REPID, {
+	TA_NULL,
+	{ IPV4_ADDRANY, 7 }
+	} );
+
+#endif	/* of #if defined(SUPPORT_INET4) && defined(USE_TCP4_ECHO_SRV) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+TCP_CRE_REP (TCP_ECHO_SRV_REPID, {
+	TA_NULL,
+	{ IPV4_ADDRANY, 7 }
+	} );
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+/*
+ * TCP éä¿¡ç«¯ç¹
+ *
+ * å®ç¾©ãã TCP éä¿¡ç«¯ç¹ï¼TCP?_ECHO_SRV_CEPID1ï¼ã®é¸æ
+ *
+ *   INET6 INET4 USE_TCP4  TCP6_CRE_CEP TCP_CRE_CEP
+ *     â    â     â          Ã         TCP4
+ *     â    â     Ã          TCP        Ã
+ *     â    Ã     â          TCP        Ã
+ *     â    Ã     Ã          TCP        Ã
+ *     Ã    â     â          Ã         TCP
+ *     Ã    â     Ã          Ã         TCP
+ *     Ã    Ã     â          Ã         Ã
+ *     Ã    Ã     Ã          Ã         Ã
+ *
+ */
+
+#if defined(USE_TCP_EXTENTIONS)
+
+#else	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#if defined(USE_TCP_NON_BLOCKING)
+
+#else	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#if defined(SUPPORT_INET6)
+
+#if defined(SUPPORT_INET4)
+
+#if defined(USE_TCP4_ECHO_SRV)
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP4_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP4_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP4_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP4_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#else	/* of #if defined(USE_TCP4_ECHO_SRV) */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if defined(USE_TCP4_ECHO_SRV) */
+
+#else	/* of #if defined(SUPPORT_INET4) */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#elif defined(SUPPORT_INET4)	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#endif	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#endif	/* of #if defined(USE_TCP_ECHO_SRV1) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp64_echo_srv1_nblk.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp64_echo_srv1_nblk.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp64_echo_srv1_nblk.cfg	(revision 331)
@@ -0,0 +1,320 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP ECHO ãµã¼ãã® TCP/IP ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ *
+ *    SUPPORT_INET6
+ *    SUPPORT_INET4
+ *    USE_TCP_NON_BLOCKING: ON
+ *    USE_TCP_EXTENTIONS:   OFF
+ *    TCP éä¿¡ç«¯ç¹ãNUM_TCP_ECHO_SRV_TASKS == 1
+ * 
+ */
+
+#if defined(USE_TCP_ECHO_SRV1)
+
+/*
+ * TCP éä¿¡ç«¯ç¹
+ *
+ * å®ç¾©ãã TCP éä¿¡ç«¯ç¹ï¼TCP?_ECHO_SRV_CEPID1ï¼ã®é¸æ
+ *
+ *   INET6 INET4 USE_TCP4  TCP6_CRE_CEP TCP_CRE_CEP
+ *     â    â     â          Ã         TCP4
+ *     â    â     Ã          TCP        Ã
+ *     â    Ã     â          TCP        Ã
+ *     â    Ã     Ã          TCP        Ã
+ *     Ã    â     â          Ã         TCP
+ *     Ã    â     Ã          Ã         TCP
+ *     Ã    Ã     â          Ã         Ã
+ *     Ã    Ã     Ã          Ã         Ã
+ *
+ */
+
+#if defined(USE_TCP_EXTENTIONS)
+
+#else	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#if defined(USE_TCP_NON_BLOCKING)
+
+#if defined(SUPPORT_INET6)
+
+#if defined(SUPPORT_INET4)
+
+#if defined(USE_TCP4_ECHO_SRV)
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP4_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP4_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP4_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP4_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#else	/* of #if defined(USE_TCP4_ECHO_SRV) */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if defined(USE_TCP4_ECHO_SRV) */
+
+#else	/* of #if defined(SUPPORT_INET4) */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#elif defined(SUPPORT_INET4)	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#endif	/* of #if !defined(USE_TCP_EXTENTIONS) */
+
+#endif	/* of #if defined(USE_TCP_ECHO_SRV1) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp6_echo_srv1.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp6_echo_srv1.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp6_echo_srv1.cfg	(revision 331)
@@ -0,0 +1,482 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP ECHO ãµã¼ãã® TCP/IP ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ *
+ *    SUPPORT_INET6
+ *    USE_TCP_NON_BLOCKING: OFF
+ *    USE_TCP_EXTENTIONS:   OFF
+ *    TCP éä¿¡ç«¯ç¹ãNUM_TCP_ECHO_SRV_TASKS >= 2 ä»¥é
+ * 
+ */
+
+/* TCP éä¿¡ç«¯ç¹ */
+
+#if defined(USE_TCP_ECHO_SRV1)
+
+#if defined(USE_TCP_EXTENTIONS)
+
+#else	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#if defined(SUPPORT_INET6)
+
+#if defined(USE_TCP_NON_BLOCKING)
+
+#else	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 2
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[1],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[1],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[1],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[1],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 2 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 3
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[2],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[2],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[2],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[2],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 3 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 4
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[3],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[3],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[3],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[3],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 4 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 5
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[4],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[4],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[4],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[4],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 5 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 6
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[5],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[5],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[5],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[5],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 6 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 7
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[6],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[6],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[6],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[6],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 7 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 8
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[7],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[7],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[7],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[7],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 8 */
+
+#endif	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#endif	/* of #if defined(USE_TCP_ECHO_SRV1) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp6_echo_srv1_nblk.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp6_echo_srv1_nblk.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp6_echo_srv1_nblk.cfg	(revision 331)
@@ -0,0 +1,482 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP ECHO ãµã¼ãã® TCP/IP ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ *
+ *    SUPPORT_INET6
+ *    USE_TCP_NON_BLOCKING: ON
+ *    USE_TCP_EXTENTIONS:   OFF
+ *    TCP éä¿¡ç«¯ç¹ãNUM_TCP_ECHO_SRV_TASKS >= 2 ä»¥é
+ * 
+ */
+
+/* TCP éä¿¡ç«¯ç¹ */
+
+#if defined(USE_TCP_ECHO_SRV1)
+
+#if defined(USE_TCP_EXTENTIONS)
+
+#else	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#if defined(SUPPORT_INET6)
+
+#if defined(USE_TCP_NON_BLOCKING)
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 2
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[1],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[1],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[1],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[1],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 2 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 3
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[2],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[2],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[2],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[2],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 3 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 4
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[3],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[3],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[3],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[3],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 4 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 5
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[4],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[4],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[4],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[4],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 5 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 6
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[5],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[5],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[5],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[5],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 6 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 7
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[6],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[6],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[6],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[6],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 7 */
+
+#if NUM_TCP_ECHO_SRV_TASKS >= 8
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[7],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[7],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
+	TA_NULL,
+	tcp_echo_srv_swbuf[7],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[7],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 8 */
+
+#else	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#endif	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#endif	/* of #if defined(USE_TCP_ECHO_SRV1) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp_discard_cli.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp_discard_cli.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp_discard_cli.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -43,4 +43,62 @@
 /* TCP 通信端点 */
 
+#ifdef SUPPORT_INET6
+
+#ifdef USE_TCP_NON_BLOCKING
+
+#ifdef TCP_CFG_SWBUF_CSAVE_ONLY
+
+TCP6_CRE_CEP (TCP_DISCARD_CLI_CEPID, {
+	TA_NULL,
+	NADR,
+	TCP_DISCARD_CLI_SWBUF_SIZE,
+	NADR,
+	0,
+	callback_nblk_tcp_discard_cli
+	} );
+
+#else	/* of #ifdef TCP_CFG_SWBUF_CSAVE_ONLY */
+
+TCP6_CRE_CEP (TCP_DISCARD_CLI_CEPID, {
+	TA_NULL,
+	tcp_discard_cli_swbuf,
+	TCP_DISCARD_CLI_SWBUF_SIZE,
+	NADR,
+	0,
+	callback_nblk_tcp_discard_cli
+	} );
+
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE_ONLY */
+
+#else	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#ifdef TCP_CFG_SWBUF_CSAVE_ONLY
+
+TCP6_CRE_CEP (TCP_DISCARD_CLI_CEPID, {
+	TA_NULL,
+	NADR,
+	TCP_DISCARD_CLI_SWBUF_SIZE,
+	NADR,
+	0,
+	NULL
+	} );
+
+#else	/* of #ifdef TCP_CFG_SWBUF_CSAVE_ONLY */
+
+TCP6_CRE_CEP (TCP_DISCARD_CLI_CEPID, {
+	TA_NULL,
+	tcp_discard_cli_swbuf,
+	TCP_DISCARD_CLI_SWBUF_SIZE,
+	NADR,
+	0,
+	NULL
+	} );
+
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
 #ifdef SUPPORT_INET4
 
@@ -50,5 +108,5 @@
 
 TCP_CRE_CEP (TCP_DISCARD_CLI_CEPID, {
-	0,
+	TA_NULL,
 	NADR,
 	TCP_DISCARD_CLI_SWBUF_SIZE,
@@ -61,5 +119,5 @@
 
 TCP_CRE_CEP (TCP_DISCARD_CLI_CEPID, {
-	0,
+	TA_NULL,
 	tcp_discard_cli_swbuf,
 	TCP_DISCARD_CLI_SWBUF_SIZE,
@@ -76,5 +134,5 @@
 
 TCP_CRE_CEP (TCP_DISCARD_CLI_CEPID, {
-	0,
+	TA_NULL,
 	NADR,
 	TCP_DISCARD_CLI_SWBUF_SIZE,
@@ -87,5 +145,5 @@
 
 TCP_CRE_CEP (TCP_DISCARD_CLI_CEPID, {
-	0,
+	TA_NULL,
 	tcp_discard_cli_swbuf,
 	TCP_DISCARD_CLI_SWBUF_SIZE,
@@ -101,60 +159,4 @@
 #endif	/* of #ifdef SUPPORT_INET4 */
 
-#ifdef SUPPORT_INET6
-
-#ifdef USE_TCP_NON_BLOCKING
-
-#ifdef TCP_CFG_SWBUF_CSAVE_ONLY
-
-TCP6_CRE_CEP (TCP_DISCARD_CLI_CEPID, {
-	0,
-	NADR,
-	TCP_DISCARD_CLI_SWBUF_SIZE,
-	NADR,
-	0,
-	callback_nblk_tcp_discard_cli
-	} );
-
-#else	/* of #ifdef TCP_CFG_SWBUF_CSAVE_ONLY */
-
-TCP6_CRE_CEP (TCP_DISCARD_CLI_CEPID, {
-	0,
-	tcp_discard_cli_swbuf,
-	TCP_DISCARD_CLI_SWBUF_SIZE,
-	NADR,
-	0,
-	callback_nblk_tcp_discard_cli
-	} );
-
-#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE_ONLY */
-
-#else	/* of #ifdef USE_TCP_NON_BLOCKING */
-
-#ifdef TCP_CFG_SWBUF_CSAVE_ONLY
-
-TCP6_CRE_CEP (TCP_DISCARD_CLI_CEPID, {
-	0,
-	NADR,
-	TCP_DISCARD_CLI_SWBUF_SIZE,
-	NADR,
-	0,
-	NULL
-	} );
-
-#else	/* of #ifdef TCP_CFG_SWBUF_CSAVE_ONLY */
-
-TCP6_CRE_CEP (TCP_DISCARD_CLI_CEPID, {
-	0,
-	tcp_discard_cli_swbuf,
-	TCP_DISCARD_CLI_SWBUF_SIZE,
-	NADR,
-	0,
-	NULL
-	} );
-
-#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
-
-#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
-
 #endif	/* of #ifdef SUPPORT_INET6 */
 
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp_discard_srv.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp_discard_srv.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp_discard_srv.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -42,8 +42,17 @@
 /* TCP 受付口 */
 
+#ifdef SUPPORT_INET6
+
+TCP6_CRE_REP (TCP_DISCARD_SRV_REPID, {
+	TA_NULL,
+	{ IPV6_ADDRANY, 9 }
+	} );
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
 #ifdef SUPPORT_INET4
 
 TCP_CRE_REP (TCP_DISCARD_SRV_REPID, {
-	0,
+	TA_NULL,
 	{ IPV4_ADDRANY, 9 }
 	} );
@@ -51,14 +60,35 @@
 #endif	/* of #ifdef SUPPORT_INET4 */
 
-#ifdef SUPPORT_INET6
-
-TCP6_CRE_REP (TCP_DISCARD_SRV_REPID, {
-	0,
-	{ IPV6_ADDRANY, 9 }
-	} );
-
 #endif	/* of #ifdef SUPPORT_INET6 */
 
 /* TCP 通信端点 */
+
+#ifdef SUPPORT_INET6
+
+#ifdef TCP_CFG_RWBUF_CSAVE_ONLY
+
+TCP6_CRE_CEP (TCP_DISCARD_SRV_CEPID, {
+	TA_NULL,
+	NADR,
+	0,
+	NADR,
+	TCP_DISCARD_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #ifdef TCP_CFG_RWBUF_CSAVE_ONLY */
+
+TCP6_CRE_CEP (TCP_DISCARD_SRV_CEPID, {
+	TA_NULL,
+	NADR,
+	0,
+	tcp_discard_srv_rwbuf,
+	TCP_DISCARD_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #ifdef TCP_CFG_RWBUF_CSAVE_ONLY */
+
+#else	/* of #ifdef SUPPORT_INET6 */
 
 #ifdef SUPPORT_INET4
@@ -67,5 +97,5 @@
 
 TCP_CRE_CEP (TCP_DISCARD_SRV_CEPID, {
-	0,
+	TA_NULL,
 	NADR,
 	0,
@@ -78,5 +108,5 @@
 
 TCP_CRE_CEP (TCP_DISCARD_SRV_CEPID, {
-	0,
+	TA_NULL,
 	NADR,
 	0,
@@ -90,30 +120,4 @@
 #endif	/* of #ifdef SUPPORT_INET4 */
 
-#ifdef SUPPORT_INET6
-
-#ifdef TCP_CFG_RWBUF_CSAVE_ONLY
-
-TCP6_CRE_CEP (TCP_DISCARD_SRV_CEPID, {
-	0,
-	NADR,
-	0,
-	NADR,
-	TCP_DISCARD_SRV_RWBUF_SIZE,
-	NULL
-	} );
-
-#else	/* of #ifdef TCP_CFG_RWBUF_CSAVE_ONLY */
-
-TCP6_CRE_CEP (TCP_DISCARD_SRV_CEPID, {
-	0,
-	NADR,
-	0,
-	tcp_discard_srv_rwbuf,
-	TCP_DISCARD_SRV_RWBUF_SIZE,
-	NULL
-	} );
-
-#endif	/* of #ifdef TCP_CFG_RWBUF_CSAVE_ONLY */
-
 #endif	/* of #ifdef SUPPORT_INET6 */
 
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp_echo_cli.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp_echo_cli.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp_echo_cli.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -43,6 +43,124 @@
 /* TCP 通信端点 */
 
+#ifdef SUPPORT_INET6
+
+#ifdef USE_TCP_NON_BLOCKING
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	tcp_echo_cli_rwbuf,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	tcp_echo_cli_swbuf,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	tcp_echo_cli_swbuf,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	tcp_echo_cli_rwbuf,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#else	/* of #ifdef USE_TCP_NON_BLOCKING */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	tcp_echo_cli_rwbuf,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	tcp_echo_cli_swbuf,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	tcp_echo_cli_swbuf,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	tcp_echo_cli_rwbuf,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
+
 #ifdef SUPPORT_INET4
 
+#ifdef USE_TCP4_ECHO_CLI
+
 #ifdef USE_TCP_NON_BLOCKING
 
@@ -51,42 +169,42 @@
 #if defined(TCP_CFG_RWBUF_CSAVE)
 
-TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
-	0,
-	NADR,
-	TCP_ECHO_CLI_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_CLI_RWBUF_SIZE,
-	callback_nblk_tcp_echo_cli
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
-	0,
-	NADR,
-	TCP_ECHO_CLI_SWBUF_SIZE,
-	tcp_echo_cli_rwbuf,
-	TCP_ECHO_CLI_RWBUF_SIZE,
-	callback_nblk_tcp_echo_cli
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
-	0,
-	tcp_echo_cli_swbuf,
-	TCP_ECHO_CLI_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_CLI_RWBUF_SIZE,
-	callback_nblk_tcp_echo_cli
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+TCP_CRE_CEP (TCP4_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP4_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	tcp_echo_cli_rwbuf,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP4_ECHO_CLI_CEPID, {
+	0,
+	tcp_echo_cli_swbuf,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP4_ECHO_CLI_CEPID, {
 	0,
 	tcp_echo_cli_swbuf,
@@ -107,42 +225,42 @@
 #if defined(TCP_CFG_RWBUF_CSAVE)
 
-TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
-	0,
-	NADR,
-	TCP_ECHO_CLI_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_CLI_RWBUF_SIZE,
-	NULL
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
-	0,
-	NADR,
-	TCP_ECHO_CLI_SWBUF_SIZE,
-	tcp_echo_cli_rwbuf,
-	TCP_ECHO_CLI_RWBUF_SIZE,
-	NULL
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
-	0,
-	tcp_echo_cli_swbuf,
-	TCP_ECHO_CLI_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_CLI_RWBUF_SIZE,
-	NULL
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+TCP_CRE_CEP (TCP4_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP4_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	tcp_echo_cli_rwbuf,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP4_ECHO_CLI_CEPID, {
+	0,
+	tcp_echo_cli_swbuf,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP4_ECHO_CLI_CEPID, {
 	0,
 	tcp_echo_cli_swbuf,
@@ -159,7 +277,11 @@
 #endif	/* of #ifdef USE_TCP_NON_BLOCKING */
 
+#endif	/* of #ifdef USE_TCP4_ECHO_CLI */
+
 #endif	/* of #ifdef SUPPORT_INET4 */
 
-#ifdef SUPPORT_INET6
+#else	/* of #ifdef SUPPORT_INET6 */
+
+#ifdef SUPPORT_INET4
 
 #ifdef USE_TCP_NON_BLOCKING
@@ -169,42 +291,42 @@
 #if defined(TCP_CFG_RWBUF_CSAVE)
 
-TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
-	0,
-	NADR,
-	TCP_ECHO_CLI_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_CLI_RWBUF_SIZE,
-	callback_nblk_tcp_echo_cli
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
-	0,
-	NADR,
-	TCP_ECHO_CLI_SWBUF_SIZE,
-	tcp_echo_cli_rwbuf,
-	TCP_ECHO_CLI_RWBUF_SIZE,
-	callback_nblk_tcp_echo_cli
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
-	0,
-	tcp_echo_cli_swbuf,
-	TCP_ECHO_CLI_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_CLI_RWBUF_SIZE,
-	callback_nblk_tcp_echo_cli
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	tcp_echo_cli_rwbuf,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	tcp_echo_cli_swbuf,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	callback_nblk_tcp_echo_cli
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
 	0,
 	tcp_echo_cli_swbuf,
@@ -225,42 +347,42 @@
 #if defined(TCP_CFG_RWBUF_CSAVE)
 
-TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
-	0,
-	NADR,
-	TCP_ECHO_CLI_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_CLI_RWBUF_SIZE,
-	NULL
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
-	0,
-	NADR,
-	TCP_ECHO_CLI_SWBUF_SIZE,
-	tcp_echo_cli_rwbuf,
-	TCP_ECHO_CLI_RWBUF_SIZE,
-	NULL
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
-	0,
-	tcp_echo_cli_swbuf,
-	TCP_ECHO_CLI_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_CLI_RWBUF_SIZE,
-	NULL
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	NADR,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	tcp_echo_cli_rwbuf,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
+	0,
+	tcp_echo_cli_swbuf,
+	TCP_ECHO_CLI_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_CLI_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_CLI_CEPID, {
 	0,
 	tcp_echo_cli_swbuf,
@@ -277,4 +399,6 @@
 #endif	/* of #ifdef USE_TCP_NON_BLOCKING */
 
+#endif	/* of #ifdef SUPPORT_INET4 */
+
 #endif	/* of #ifdef SUPPORT_INET6 */
 
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp_echo_srv.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp_echo_srv.cfg	(revision 321)
+++ 	(revision )
@@ -1,1122 +1,0 @@
-/*
- *  TINET (TCP/IP Protocol Stack)
- * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
- *                   Tomakomai National College of Technology, JAPAN
- *
- *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
- *  によって公表されている GNU General Public License の Version 2 に記
- *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
- *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
- *  利用と呼ぶ）することを無償で許諾する．
- *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
- *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
- *      スコード中に含まれていること．
- *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
- *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
- *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
- *      の無保証規定を掲載すること．
- *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
- *      用できない形で再配布する場合には，次の条件を満たすこと．
- *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
- *        作権表示，この利用条件および下記の無保証規定を掲載すること．
- *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
- *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
- *
- *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
- *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
- *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
- *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
- * 
- *  @(#) $Id$
- */
-
-/*
- *  TCP ECHO サーバの TCP/IP コンフィギュレーションファイル
- */
-
-#if defined(USE_TCP_ECHO_SRV1) || defined(USE_TCP_ECHO_SRV2)
-
-#ifndef USE_TCP_EXTENTIONS
-
-/* TCP 受付口 */
-
-#ifdef SUPPORT_INET4
-
-TCP_CRE_REP (TCP_ECHO_SRV_REPID, {
-	0,
-	{ IPV4_ADDRANY, 7 }
-	} );
-
-#endif	/* of #ifdef SUPPORT_INET4 */
-
-#ifdef SUPPORT_INET6
-
-TCP6_CRE_REP (TCP_ECHO_SRV_REPID, {
-	0,
-	{ IPV6_ADDRANY, 7 }
-	} );
-
-#endif	/* of #ifdef SUPPORT_INET6 */
-
-/* TCP 通信端点 */
-
-#ifdef SUPPORT_INET4
-
-#ifdef USE_TCP_NON_BLOCKING
-
-#if defined(TCP_CFG_SWBUF_CSAVE)
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	callback_nblk_tcp_echo_srv
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	callback_nblk_tcp_echo_srv
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
-	0,
-	tcp_echo_srv_swbuf,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	callback_nblk_tcp_echo_srv
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
-	0,
-	tcp_echo_srv_swbuf,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	callback_nblk_tcp_echo_srv
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#else	/* of #ifdef USE_TCP_NON_BLOCKING */
-
-#if defined(TCP_CFG_SWBUF_CSAVE)
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[0],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
-	0,
-	tcp_echo_srv_swbuf[0],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
-	0,
-	tcp_echo_srv_swbuf[0],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[0],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#ifdef USE_TCP_ECHO_SRV1
-
-#if NUM_TCP_ECHO_SRV_TASKS >= 2
-
-#if defined(TCP_CFG_SWBUF_CSAVE)
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[1],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
-	0,
-	tcp_echo_srv_swbuf[1],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
-	0,
-	tcp_echo_srv_swbuf[1],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[1],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 2 */
-
-#if NUM_TCP_ECHO_SRV_TASKS >= 3
-
-#if defined(TCP_CFG_SWBUF_CSAVE)
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[2],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
-	0,
-	tcp_echo_srv_swbuf[2],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
-	0,
-	tcp_echo_srv_swbuf[2],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[2],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 3 */
-
-#if NUM_TCP_ECHO_SRV_TASKS >= 4
-
-#if defined(TCP_CFG_SWBUF_CSAVE)
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[3],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
-	0,
-	tcp_echo_srv_swbuf[3],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
-	0,
-	tcp_echo_srv_swbuf[3],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[3],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 4 */
-
-#if NUM_TCP_ECHO_SRV_TASKS >= 5
-
-#if defined(TCP_CFG_SWBUF_CSAVE)
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[4],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
-	0,
-	tcp_echo_srv_swbuf[4],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
-	0,
-	tcp_echo_srv_swbuf[4],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[4],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 5 */
-
-#if NUM_TCP_ECHO_SRV_TASKS >= 6
-
-#if defined(TCP_CFG_SWBUF_CSAVE)
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[5],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
-	0,
-	tcp_echo_srv_swbuf[5],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
-	0,
-	tcp_echo_srv_swbuf[5],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[5],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 6 */
-
-#if NUM_TCP_ECHO_SRV_TASKS >= 7
-
-#if defined(TCP_CFG_SWBUF_CSAVE)
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[6],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
-	0,
-	tcp_echo_srv_swbuf[6],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
-	0,
-	tcp_echo_srv_swbuf[6],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[6],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 7 */
-
-#if NUM_TCP_ECHO_SRV_TASKS >= 8
-
-#if defined(TCP_CFG_SWBUF_CSAVE)
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[7],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
-	0,
-	tcp_echo_srv_swbuf[7],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
-	0,
-	tcp_echo_srv_swbuf[7],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[7],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 8 */
-
-#endif	/* of #ifdef USE_TCP_ECHO_SRV1 */
-
-#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
-
-#endif	/* of #ifdef SUPPORT_INET4 */
-
-#ifdef SUPPORT_INET6
-
-#ifdef USE_TCP_NON_BLOCKING
-
-#if defined(TCP_CFG_SWBUF_CSAVE)
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	callback_nblk_tcp_echo_srv
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	callback_nblk_tcp_echo_srv
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
-	0,
-	tcp_echo_srv_swbuf,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	callback_nblk_tcp_echo_srv
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
-	0,
-	tcp_echo_srv_swbuf,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	callback_nblk_tcp_echo_srv
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#else	/* of #ifdef USE_TCP_NON_BLOCKING */
-
-#if defined(TCP_CFG_SWBUF_CSAVE)
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[0],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
-	0,
-	tcp_echo_srv_swbuf[0],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
-	0,
-	tcp_echo_srv_swbuf[0],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[0],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#ifdef USE_TCP_ECHO_SRV1
-
-#if NUM_TCP_ECHO_SRV_TASKS >= 2
-
-#if defined(TCP_CFG_SWBUF_CSAVE)
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[1],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
-	0,
-	tcp_echo_srv_swbuf[1],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID2, {
-	0,
-	tcp_echo_srv_swbuf[1],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[1],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 2 */
-
-#if NUM_TCP_ECHO_SRV_TASKS >= 3
-
-#if defined(TCP_CFG_SWBUF_CSAVE)
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[2],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
-	0,
-	tcp_echo_srv_swbuf[2],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID3, {
-	0,
-	tcp_echo_srv_swbuf[2],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[2],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 3 */
-
-#if NUM_TCP_ECHO_SRV_TASKS >= 4
-
-#if defined(TCP_CFG_SWBUF_CSAVE)
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[3],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
-	0,
-	tcp_echo_srv_swbuf[3],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID4, {
-	0,
-	tcp_echo_srv_swbuf[3],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[3],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 4 */
-
-#if NUM_TCP_ECHO_SRV_TASKS >= 5
-
-#if defined(TCP_CFG_SWBUF_CSAVE)
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[4],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
-	0,
-	tcp_echo_srv_swbuf[4],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID5, {
-	0,
-	tcp_echo_srv_swbuf[4],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[4],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 5 */
-
-#if NUM_TCP_ECHO_SRV_TASKS >= 6
-
-#if defined(TCP_CFG_SWBUF_CSAVE)
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[5],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
-	0,
-	tcp_echo_srv_swbuf[5],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID6, {
-	0,
-	tcp_echo_srv_swbuf[5],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[5],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 6 */
-
-#if NUM_TCP_ECHO_SRV_TASKS >= 7
-
-#if defined(TCP_CFG_SWBUF_CSAVE)
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[6],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
-	0,
-	tcp_echo_srv_swbuf[6],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID7, {
-	0,
-	tcp_echo_srv_swbuf[6],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[6],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 7 */
-
-#if NUM_TCP_ECHO_SRV_TASKS >= 8
-
-#if defined(TCP_CFG_SWBUF_CSAVE)
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
-	0,
-	NADR,
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[7],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
-	0,
-	tcp_echo_srv_swbuf[7],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	NADR,
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID8, {
-	0,
-	tcp_echo_srv_swbuf[7],
-	TCP_ECHO_SRV_SWBUF_SIZE,
-	tcp_echo_srv_rwbuf[7],
-	TCP_ECHO_SRV_RWBUF_SIZE,
-	NULL 
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#endif	/* of #if NUM_TCP_ECHO_SRV_TASKS >= 8 */
-
-#endif	/* of #ifdef USE_TCP_ECHO_SRV1 */
-
-#endif	/* of #ifdef USE_TCP_NON_BLOCKING */
-
-#endif	/* of #ifdef SUPPORT_INET6 */
-
-#endif	/* of #ifndef USE_TCP_EXTENTIONS */
-
-#endif	/* of #if defined(USE_TCP_ECHO_SRV1) || defined(USE_TCP_ECHO_SRV2) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp_echo_srv2.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp_echo_srv2.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_tcp_echo_srv2.cfg	(revision 331)
@@ -0,0 +1,318 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  TCP ECHO ãµã¼ãã® TCP/IP ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ */
+
+#if defined(USE_TCP_ECHO_SRV2)
+
+#ifndef USE_TCP_EXTENTIONS
+
+/* TCP åä»å£ */
+
+#if defined(SUPPORT_INET6)
+
+TCP6_CRE_REP (TCP_ECHO_SRV_REPID, {
+	0,
+	{ IPV6_ADDRANY, 7 }
+	} );
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+TCP_CRE_REP (TCP_ECHO_SRV_REPID, {
+	0,
+	{ IPV4_ADDRANY, 7 }
+	} );
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+/* TCP éä¿¡ç«¯ç¹ */
+
+#if defined(SUPPORT_INET6)
+
+#if defined(USE_TCP_NON_BLOCKING)
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#else	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+#if defined(USE_TCP_NON_BLOCKING)
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	callback_nblk_tcp_echo_srv
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#else	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	NADR,
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	NADR,
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (TCP_ECHO_SRV_CEPID1, {
+	0,
+	tcp_echo_srv_swbuf[0],
+	TCP_ECHO_SRV_SWBUF_SIZE,
+	tcp_echo_srv_rwbuf[0],
+	TCP_ECHO_SRV_RWBUF_SIZE,
+	NULL 
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if defined(USE_TCP_NON_BLOCKING) */
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #ifndef USE_TCP_EXTENTIONS */
+
+#endif	/* of #defined(USE_TCP_ECHO_SRV2) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_udp4_echo_cli.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_udp4_echo_cli.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_udp4_echo_cli.cfg	(revision 331)
@@ -0,0 +1,89 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  UDP ECHO ã¯ã©ã¤ã¢ã³ã
+ *  TCP/IP ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ */
+
+#if defined(USE_UDP4_ECHO_CLI_TSK)
+
+#if !defined(USE_UDP_EXTENTIONS)
+
+/* UDP éä¿¡ç«¯ç¹ */
+
+#if defined(USE_UDP_NON_BLOCKING)
+
+UDP_CRE_CEP (UDP4_ECHO_CLI_CEPID, {
+	0,
+	{ IPV4_ADDRANY, UDP_PORTANY },
+	callback_nblk_udp4_echo_cli
+	} );
+
+#else	/* of #if defined(USE_UDP_NON_BLOCKING) */
+
+#if defined(USE_UDP_CALL_BACK)
+
+UDP_CRE_CEP (UDP4_ECHO_CLI_CEPID, {
+	0,
+	{ IPV4_ADDRANY, UDP_PORTANY },
+	callback_udp4_echo_cli
+	} );
+
+#else	/* of #if defined(USE_UDP_CALL_BACK) */
+
+UDP_CRE_CEP (UDP4_ECHO_CLI_CEPID, {
+	0,
+	{ IPV4_ADDRANY, UDP_PORTANY },
+	NULL
+	} );
+
+#endif	/* of #if defined(USE_UDP_CALL_BACK) */
+
+#endif	/* of #if defined(USE_UDP_NON_BLOCKING) */
+
+#endif	/* of #if !defined(USE_UDP_EXTENTIONS) */
+
+#endif	/* of #if defined(USE_UDP4_ECHO_CLI_TSK) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_udp4_echo_srv.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_udp4_echo_srv.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_udp4_echo_srv.cfg	(revision 331)
@@ -0,0 +1,91 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  UDP ECHO ãµã¼ã
+ *  UDP/IP ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ *
+ *    IPv4
+ */
+
+#ifdef USE_UDP4_ECHO_SRV_TSK
+
+#ifndef USE_UDP_EXTENTIONS
+
+/* UDP éä¿¡ç«¯ç¹ */
+
+#ifdef USE_UDP_NON_BLOCKING
+
+UDP_CRE_CEP (UDP4_ECHO_SRV_CEPID, {
+	0,
+	{ IPV4_ADDRANY, 7 },
+	callback_nblk_udp4_echo_srv
+	} );
+
+#else	/* of #ifdef USE_UDP_NON_BLOCKING */
+
+#ifdef USE_UDP_CALL_BACK
+
+UDP_CRE_CEP (UDP4_ECHO_SRV_CEPID, {
+	0,
+	{ IPV4_ADDRANY, 7 },
+	callback_udp4_echo_srv
+	} );
+
+#else	/* of #ifdef USE_UDP_CALL_BACK */
+
+UDP_CRE_CEP (UDP4_ECHO_SRV_CEPID, {
+	0,
+	{ IPV4_ADDRANY, 7 },
+	NULL
+	} );
+
+#endif	/* of #ifdef USE_UDP_CALL_BACK */
+
+#endif	/* of #ifdef USE_UDP_NON_BLOCKING */
+
+#endif	/* of #ifndef USE_UDP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_UDP4_ECHO_SRV_TSK */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_udp6_echo_cli.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_udp6_echo_cli.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_udp6_echo_cli.cfg	(revision 331)
@@ -0,0 +1,89 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  UDP ECHO ã¯ã©ã¤ã¢ã³ã
+ *  TCP/IP ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ */
+
+#if defined(USE_UDP6_ECHO_CLI_TSK)
+
+#if !defined(USE_UDP_EXTENTIONS)
+
+/* UDP éä¿¡ç«¯ç¹ */
+
+#if defined(USE_UDP_NON_BLOCKING)
+
+UDP6_CRE_CEP (UDP6_ECHO_CLI_CEPID, {
+	0,
+	{ IPV6_ADDRANY, UDP_PORTANY },
+	callback_nblk_udp6_echo_cli
+	} );
+
+#else	/* of #if defined(USE_UDP_NON_BLOCKING) */
+
+#if defined(USE_UDP_CALL_BACK)
+
+UDP6_CRE_CEP (UDP6_ECHO_CLI_CEPID, {
+	0,
+	{ IPV6_ADDRANY, UDP_PORTANY },
+	callback_udp6_echo_cli
+	} );
+
+#else	/* of #if defined(USE_UDP_CALL_BACK) */
+
+UDP6_CRE_CEP (UDP6_ECHO_CLI_CEPID, {
+	0,
+	{ IPV6_ADDRANY, UDP_PORTANY },
+	NULL
+	} );
+
+#endif	/* of #if defined(USE_UDP_CALL_BACK) */
+
+#endif	/* of #if defined(USE_UDP_NON_BLOCKING) */
+
+#endif	/* of #if !defined(USE_UDP_EXTENTIONS) */
+
+#endif	/* of #if defined(USE_UDP6_ECHO_CLI_TSK) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_udp6_echo_srv.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_udp6_echo_srv.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_udp6_echo_srv.cfg	(revision 331)
@@ -0,0 +1,91 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  UDP ECHO ãµã¼ã
+ *  UDP/IP ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ *
+ *    IPv6
+ */
+
+#ifdef USE_UDP6_ECHO_SRV_TSK
+
+#ifndef USE_UDP_EXTENTIONS
+
+/* UDP éä¿¡ç«¯ç¹ */
+
+#ifdef USE_UDP_NON_BLOCKING
+
+UDP6_CRE_CEP (UDP6_ECHO_SRV_CEPID, {
+	0,
+	{ IPV6_ADDRANY, 7 },
+	callback_nblk_udp6_echo_srv
+	} );
+
+#else	/* of #ifdef USE_UDP_NON_BLOCKING */
+
+#ifdef USE_UDP_CALL_BACK
+
+UDP6_CRE_CEP (UDP6_ECHO_SRV_CEPID, {
+	0,
+	{ IPV6_ADDRANY, 7 },
+	callback_udp6_echo_srv
+	} );
+
+#else	/* of #ifdef USE_UDP_CALL_BACK */
+
+UDP6_CRE_CEP (UDP6_ECHO_SRV_CEPID, {
+	0,
+	{ IPV6_ADDRANY, 7 },
+	NULL
+	} );
+
+#endif	/* of #ifdef USE_UDP_CALL_BACK */
+
+#endif	/* of #ifdef USE_UDP_NON_BLOCKING */
+
+#endif	/* of #ifndef USE_UDP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_UDP6_ECHO_SRV_TSK */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_udp_discard_cli.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_udp_discard_cli.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_udp_discard_cli.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (UDP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -43,4 +43,14 @@
 /* UDP 通信端点 */
 
+#ifdef SUPPORT_INET6
+
+UDP6_CRE_CEP (UDP_DISCARD_CLI_CEPID, { 
+	0,
+	{ IPV6_ADDRANY, UDP_PORTANY },
+	NULL
+	} );
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
 #ifdef SUPPORT_INET4
 
@@ -53,12 +63,4 @@
 #endif	/* of #ifdef SUPPORT_INET4 */
 
-#ifdef SUPPORT_INET6
-
-UDP6_CRE_CEP (UDP_DISCARD_CLI_CEPID, { 
-	0,
-	{ IPV6_ADDRANY, UDP_PORTANY },
-	NULL
-	} );
-
 #endif	/* of #ifdef SUPPORT_INET6 */
 
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_udp_echo_cli.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_udp_echo_cli.cfg	(revision 321)
+++ 	(revision )
@@ -1,115 +1,0 @@
-/*
- *  TINET (UDP/IP Protocol Stack)
- * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
- *                   Tomakomai National College of Technology, JAPAN
- *
- *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
- *  によって公表されている GNU General Public License の Version 2 に記
- *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
- *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
- *  利用と呼ぶ）することを無償で許諾する．
- *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
- *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
- *      スコード中に含まれていること．
- *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
- *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
- *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
- *      の無保証規定を掲載すること．
- *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
- *      用できない形で再配布する場合には，次の条件を満たすこと．
- *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
- *        作権表示，この利用条件および下記の無保証規定を掲載すること．
- *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
- *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
- *
- *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
- *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
- *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
- *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
- * 
- *  @(#) $Id$
- */
-
-/*
- *  UDP ECHO クライアント
- *  TCP/IP コンフィギュレーションファイル
- */
-
-#ifdef USE_UDP_ECHO_CLI
-
-#ifndef USE_UDP_EXTENTIONS
-
-/* UDP 通信端点 */
-
-#ifdef SUPPORT_INET4
-
-#ifdef USE_UDP_NON_BLOCKING
-
-UDP_CRE_CEP (UDP_ECHO_CLI_CEPID, {
-	0,
-	{ IPV4_ADDRANY, UDP_PORTANY },
-	callback_nblk_udp_echo_cli
-	} );
-
-#else	/* of #ifdef USE_UDP_NON_BLOCKING */
-
-#ifdef USE_UDP_CALL_BACK
-
-UDP_CRE_CEP (UDP_ECHO_CLI_CEPID, {
-	0,
-	{ IPV4_ADDRANY, UDP_PORTANY },
-	callback_udp_echo_cli
-	} );
-
-#else	/* of #ifdef USE_UDP_CALL_BACK */
-
-UDP_CRE_CEP (UDP_ECHO_CLI_CEPID, {
-	0,
-	{ IPV4_ADDRANY, UDP_PORTANY },
-	NULL
-	} );
-
-#endif	/* of #ifdef USE_UDP_CALL_BACK */
-
-#endif	/* of #ifdef USE_UDP_NON_BLOCKING */
-
-#endif	/* of #ifdef SUPPORT_INET4 */
-
-#ifdef SUPPORT_INET6
-
-#ifdef USE_UDP_NON_BLOCKING
-
-UDP6_CRE_CEP (UDP_ECHO_CLI_CEPID, {
-	0,
-	{ IPV6_ADDRANY, UDP_PORTANY },
-	callback_nblk_udp_echo_cli
-	} );
-
-#else	/* of #ifdef USE_UDP_NON_BLOCKING */
-
-#ifdef USE_UDP_CALL_BACK
-
-UDP6_CRE_CEP (UDP_ECHO_CLI_CEPID, {
-	0,
-	{ IPV6_ADDRANY, UDP_PORTANY },
-	callback_udp_echo_cli
-	} );
-
-#else	/* of #ifdef USE_UDP_CALL_BACK */
-
-UDP6_CRE_CEP (UDP_ECHO_CLI_CEPID, {
-	0,
-	{ IPV6_ADDRANY, UDP_PORTANY },
-	NULL
-	} );
-
-#endif	/* of #ifdef USE_UDP_CALL_BACK */
-
-#endif	/* of #ifdef USE_UDP_NON_BLOCKING */
-
-#endif	/* of #ifdef SUPPORT_INET6 */
-
-#endif	/* of #ifndef USE_UDP_EXTENTIONS */
-
-#endif	/* of #ifdef USE_UDP_ECHO_CLI */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_udp_echo_srv.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_udp_echo_srv.cfg	(revision 321)
+++ 	(revision )
@@ -1,115 +1,0 @@
-/*
- *  TINET (UDP/IP Protocol Stack)
- * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
- *                   Tomakomai National College of Technology, JAPAN
- *
- *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
- *  によって公表されている GNU General Public License の Version 2 に記
- *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
- *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
- *  利用と呼ぶ）することを無償で許諾する．
- *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
- *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
- *      スコード中に含まれていること．
- *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
- *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
- *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
- *      の無保証規定を掲載すること．
- *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
- *      用できない形で再配布する場合には，次の条件を満たすこと．
- *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
- *        作権表示，この利用条件および下記の無保証規定を掲載すること．
- *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
- *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
- *
- *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
- *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
- *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
- *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
- * 
- *  @(#) $Id$
- */
-
-/*
- *  UDP ECHO サーバ
- *  UDP/IP コンフィギュレーションファイル
- */
-
-#ifdef USE_UDP_ECHO_SRV
-
-#ifndef USE_UDP_EXTENTIONS
-
-/* UDP 通信端点 */
-
-#ifdef SUPPORT_INET4
-
-#ifdef USE_UDP_NON_BLOCKING
-
-UDP_CRE_CEP (UDP_ECHO_SRV_CEPID, {
-	0,
-	{ IPV4_ADDRANY, 7 },
-	callback_nblk_udp_echo_srv
-	} );
-
-#else	/* of #ifdef USE_UDP_NON_BLOCKING */
-
-#ifdef USE_UDP_CALL_BACK
-
-UDP_CRE_CEP (UDP_ECHO_SRV_CEPID, {
-	0,
-	{ IPV4_ADDRANY, 7 },
-	callback_udp_echo_srv
-	} );
-
-#else	/* of #ifdef USE_UDP_CALL_BACK */
-
-UDP_CRE_CEP (UDP_ECHO_SRV_CEPID, {
-	0,
-	{ IPV4_ADDRANY, 7 },
-	NULL
-	} );
-
-#endif	/* of #ifdef USE_UDP_CALL_BACK */
-
-#endif	/* of #ifdef USE_UDP_NON_BLOCKING */
-
-#endif	/* of #ifdef SUPPORT_INET4 */
-
-#ifdef SUPPORT_INET6
-
-#ifdef USE_UDP_NON_BLOCKING
-
-UDP6_CRE_CEP (UDP_ECHO_SRV_CEPID, {
-	0,
-	{ IPV6_ADDRANY, 7 },
-	callback_nblk_udp_echo_srv
-	} );
-
-#else	/* of #ifdef USE_UDP_NON_BLOCKING */
-
-#ifdef USE_UDP_CALL_BACK
-
-UDP6_CRE_CEP (UDP_ECHO_SRV_CEPID, {
-	0,
-	{ IPV6_ADDRANY, 7 },
-	callback_udp_echo_srv
-	} );
-
-#else	/* of #ifdef USE_UDP_CALL_BACK */
-
-UDP6_CRE_CEP (UDP_ECHO_SRV_CEPID, {
-	0,
-	{ IPV6_ADDRANY, 7 },
-	NULL
-	} );
-
-#endif	/* of #ifdef USE_UDP_CALL_BACK */
-
-#endif	/* of #ifdef USE_UDP_NON_BLOCKING */
-
-#endif	/* of #ifdef SUPPORT_INET6 */
-
-#endif	/* of #ifndef USE_UDP_EXTENTIONS */
-
-#endif	/* of #ifdef USE_UDP_ECHO_SRV */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_wwws.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_wwws.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/tinet_wwws.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -34,13 +34,43 @@
 /*
  *  WWW サーバの TCP/IP コンフィギュレーションファイル
+ *
+ *    SUPPORT_INET6
+ *    SUPPORT_INET4
+ *    USE_TCP_NON_BLOCKING: OFF
+ *    USE_TCP_EXTENTIONS:   OFF
+ *    TCP 受付口
+ *    TCP 通信端点
+ * 
  */
 
-#ifdef USE_WWW_SRV
-
-#ifndef USE_TCP_EXTENTIONS
-
-/* TCP 受付口 */
-
-#ifdef SUPPORT_INET4
+#if defined(USE_WWW_SRV)
+
+/*
+ * TCP 受付口
+ */
+
+#if defined(USE_TCP_EXTENTIONS)
+
+#else	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#if defined(SUPPORT_INET6)
+
+TCP6_CRE_REP (WWW_SRV_REPID, {
+	0,
+	{ IPV6_ADDRANY, 80 }
+	} );
+
+#if defined(SUPPORT_INET4) && defined(USE_WWW4_SRV)
+
+TCP_CRE_REP (WWW4_SRV_REPID, {
+	0,
+	{ IPV4_ADDRANY, 80 }
+	} );
+
+#endif	/* of #if defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+#else	/* of #if defined(SUPPORT_INET6 */
+
+#if defined(SUPPORT_INET4)
 
 TCP_CRE_REP (WWW_SRV_REPID, {
@@ -49,18 +79,266 @@
 	} );
 
-#endif	/* of #ifdef SUPPORT_INET4 */
-
-#ifdef SUPPORT_INET6
-
-TCP6_CRE_REP (WWW_SRV_REPID, {
-	0,
-	{ IPV6_ADDRANY, 80 }
-	} );
-
-#endif	/* of #ifdef SUPPORT_INET6 */
-
-/* TCP 通信端点 */
-
-#ifdef SUPPORT_INET4
+#endif	/* of #if defined(SUPPORT_INET4 */
+
+#endif	/* of #if defined(SUPPORT_INET6 */
+
+#endif	/* of #if defined(USE_TCP_EXTENTIONS */
+
+/*
+ * TCP 通信端点
+ *
+ * 定義する TCP 通信端点（WWW?_CEPID1）の選択
+ *
+ *   INET6 INET4 USE_TCP4  TCP6_CRE_CEP TCP_CRE_CEP
+ *     ○    ○     ○          ×         WWW4
+ *     ○    ○     ×          WWW        ×
+ *     ○    ×     ○          WWW        ×
+ *     ○    ×     ×          WWW        ×
+ *     ×    ○     ○          ×         WWW
+ *     ×    ○     ×          ×         WWW
+ *     ×    ×     ○          ×         ×
+ *     ×    ×     ×          ×         ×
+ *
+ */
+
+#if defined(USE_TCP_EXTENTIONS)
+
+#else	/* of #if defined(USE_TCP_EXTENTIONS */
+
+#if defined(SUPPORT_INET6)
+
+#if defined(SUPPORT_INET4)
+
+#if defined(USE_WWW4_SRV)
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (WWW4_SRV_CEPID1, {
+	0,
+	NADR,
+	WWW_SRV_SWBUF_SIZE,
+	NADR,
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (WWW4_SRV_CEPID1, {
+	0,
+	NADR,
+	WWW_SRV_SWBUF_SIZE,
+	www_srv_rwbuf[0],
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP_CRE_CEP (WWW4_SRV_CEPID1, {
+	0,
+	www_srv_swbuf[0],
+	WWW_SRV_SWBUF_SIZE,
+	NADR,
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP_CRE_CEP (WWW4_SRV_CEPID1, {
+	0,
+	www_srv_swbuf[0],
+	WWW_SRV_SWBUF_SIZE,
+	www_srv_rwbuf[0],
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#else	/* of #if defined(USE_WWW4_SRV) */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (WWW_SRV_CEPID1, {
+	0,
+	NADR,
+	WWW_SRV_SWBUF_SIZE,
+	NADR,
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (WWW_SRV_CEPID1, {
+	0,
+	NADR,
+	WWW_SRV_SWBUF_SIZE,
+	www_srv_rwbuf[0],
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (WWW_SRV_CEPID1, {
+	0,
+	www_srv_swbuf[0],
+	WWW_SRV_SWBUF_SIZE,
+	NADR,
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (WWW_SRV_CEPID1, {
+	0,
+	www_srv_swbuf[0],
+	WWW_SRV_SWBUF_SIZE,
+	www_srv_rwbuf[0],
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if defined(USE_WWW4_SRV) */
+
+#else	/* of #if defined(SUPPORT_INET4 */
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (WWW_SRV_CEPID1, {
+	0,
+	NADR,
+	WWW_SRV_SWBUF_SIZE,
+	NADR,
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (WWW_SRV_CEPID1, {
+	0,
+	NADR,
+	WWW_SRV_SWBUF_SIZE,
+	www_srv_rwbuf[0],
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (WWW_SRV_CEPID1, {
+	0,
+	www_srv_swbuf[0],
+	WWW_SRV_SWBUF_SIZE,
+	NADR,
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (WWW_SRV_CEPID1, {
+	0,
+	www_srv_swbuf[0],
+	WWW_SRV_SWBUF_SIZE,
+	www_srv_rwbuf[0],
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if defined(SUPPORT_INET4 */
+
+#if NUM_WWW_SRV_TASKS >= 2
+
+#if defined(TCP_CFG_SWBUF_CSAVE)
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (WWW_SRV_CEPID2, {
+	0,
+	NADR,
+	WWW_SRV_SWBUF_SIZE,
+	NADR,
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (WWW_SRV_CEPID2, {
+	0,
+	NADR,
+	WWW_SRV_SWBUF_SIZE,
+	www_srv_rwbuf[1],
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#if defined(TCP_CFG_RWBUF_CSAVE)
+
+TCP6_CRE_CEP (WWW_SRV_CEPID2, {
+	0,
+	www_srv_swbuf[1],
+	WWW_SRV_SWBUF_SIZE,
+	NADR,
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+TCP6_CRE_CEP (WWW_SRV_CEPID2, {
+	0,
+	www_srv_swbuf[1],
+	WWW_SRV_SWBUF_SIZE,
+	www_srv_rwbuf[1],
+	WWW_SRV_RWBUF_SIZE,
+	NULL
+	} );
+
+#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
+
+#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
+
+#endif	/* of #if NUM_WWW_SRV_TASKS >= 2 */
+
+#elif defined(SUPPORT_INET4)	/* of #if defined(SUPPORT_INET6) */
 
 #if defined(TCP_CFG_SWBUF_CSAVE)
@@ -176,123 +454,7 @@
 #endif	/* of #if NUM_WWW_SRV_TASKS >= 2 */
 
-#endif	/* of #ifdef SUPPORT_INET4 */
-
-#ifdef SUPPORT_INET6
-
-#if defined(TCP_CFG_SWBUF_CSAVE)
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (WWW_SRV_CEPID1, {
-	0,
-	NADR,
-	WWW_SRV_SWBUF_SIZE,
-	NADR,
-	WWW_SRV_RWBUF_SIZE,
-	NULL
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (WWW_SRV_CEPID1, {
-	0,
-	NADR,
-	WWW_SRV_SWBUF_SIZE,
-	www_srv_rwbuf[0],
-	WWW_SRV_RWBUF_SIZE,
-	NULL
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (WWW_SRV_CEPID1, {
-	0,
-	www_srv_swbuf[0],
-	WWW_SRV_SWBUF_SIZE,
-	NADR,
-	WWW_SRV_RWBUF_SIZE,
-	NULL
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (WWW_SRV_CEPID1, {
-	0,
-	www_srv_swbuf[0],
-	WWW_SRV_SWBUF_SIZE,
-	www_srv_rwbuf[0],
-	WWW_SRV_RWBUF_SIZE,
-	NULL
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if NUM_WWW_SRV_TASKS >= 2
-
-#if defined(TCP_CFG_SWBUF_CSAVE)
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (WWW_SRV_CEPID2, {
-	0,
-	NADR,
-	WWW_SRV_SWBUF_SIZE,
-	NADR,
-	WWW_SRV_RWBUF_SIZE,
-	NULL
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (WWW_SRV_CEPID2, {
-	0,
-	NADR,
-	WWW_SRV_SWBUF_SIZE,
-	www_srv_rwbuf[1],
-	WWW_SRV_RWBUF_SIZE,
-	NULL
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#else	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#if defined(TCP_CFG_RWBUF_CSAVE)
-
-TCP6_CRE_CEP (WWW_SRV_CEPID2, {
-	0,
-	www_srv_swbuf[1],
-	WWW_SRV_SWBUF_SIZE,
-	NADR,
-	WWW_SRV_RWBUF_SIZE,
-	NULL
-	} );
-
-#else	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-TCP6_CRE_CEP (WWW_SRV_CEPID2, {
-	0,
-	www_srv_swbuf[1],
-	WWW_SRV_SWBUF_SIZE,
-	www_srv_rwbuf[1],
-	WWW_SRV_RWBUF_SIZE,
-	NULL
-	} );
-
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) */
-
-#endif	/* of #if defined(TCP_CFG_SWBUF_CSAVE) */
-
-#endif	/* of #if NUM_WWW_SRV_TASKS >= 2 */
-
-#endif	/* of #ifdef SUPPORT_INET6 */
-
-#endif	/* of #ifndef USE_TCP_EXTENTIONS */
-
-#endif	/* of #ifdef USE_WWW_SRV */
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#endif	/* of #if defined(USE_TCP_EXTENTIONS) */
+
+#endif	/* of #if defined(USE_WWW_SRV) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp4_echo_cli.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp4_echo_cli.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp4_echo_cli.c	(revision 331)
@@ -0,0 +1,490 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  UDP4 ECHO ã¯ã©ã¤ã¢ã³ã
+ */
+
+#include <string.h>
+
+#if defined(TARGET_KERNEL_ASP)
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #if defined(TARGET_KERNEL_ASP) */
+
+#if defined(TARGET_KERNEL_JSP)
+
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #if defined(TARGET_KERNEL_JSP) */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/udp4_echo_cli.h>
+
+#if defined(USE_UDP4_ECHO_CLI_TSK)
+
+/* echo ãµã¼ãã®ãã¼ãçªå· */
+
+#define ECHO_SRV_PORTNO		UINT_C(7)
+
+/* éä¿¡éé */
+
+#if defined(TOPPERS_S810_CLG3_85)
+
+#define SLP_ITV		(30*SYSTIM_HZ)
+
+#else	/* of #if defined(TOPPERS_S810_CLG3_85) */
+
+#define SLP_ITV		(60*SYSTIM_HZ)
+
+#endif	/* of #if defined(TOPPERS_S810_CLG3_85) */
+
+/* èªåå®è¡ */
+
+#if defined(UDP4_ECHO_CLI_AUTO_RUN_STR)
+#else
+#if 0
+#define UDP4_ECHO_CLI_AUTO_RUN_STR	"172.25.193.140 - 1000"
+#endif
+#endif
+
+/*
+ *  å
+¨åå¤æ°
+ */
+
+bool_t udp4_echo_cli_valid;
+
+/*
+ * å¤æ°
+ */
+
+#define BUF_SIZE	2048
+
+static char		udp_buf[BUF_SIZE];
+static T_IPV4EP		dst;
+
+#if defined(USE_UDP_NON_BLOCKING)
+
+static ER_UINT		nblk_len;
+static ID		nblk_tskid;
+
+/*
+ *  ãã³ãã­ãã­ã³ã°ã³ã¼ã«ã®ã³ã¼ã«ããã¯é¢æ°
+ */
+
+ER
+callback_nblk_udp4_echo_cli (ID cepid, FN fncd, void *p_parblk)
+{
+	nblk_len = *(ER_UINT*)p_parblk;
+	syscall(wup_tsk(nblk_tskid));
+	return E_OK;
+	}
+
+/*
+ *  udp4_echo_cli -- ECHO/UDP ãµã¼ãã«ã¡ãã»ã¼ã¸ãéä¿¡ãã (ãã³ãã­ãã­ã³ã°ã³ã¼ã«ä½¿ç¨)ã
+ */
+
+ER
+udp4_echo_cli (ID cepid, T_IN4_ADDR *ipaddr, uint16_t portno, char *line)
+{
+	ER_UINT	error;
+	SYSTIM	time;
+	uint_t	len;
+
+	dst.ipaddr = *ipaddr;
+	dst.portno = portno;
+	len         = strlen(line);
+	get_tim(&time);
+	get_tid(&nblk_tskid);
+	if ((error = udp_snd_dat(cepid, &dst, line, len, TMO_NBLK)) != E_WBLK) {
+		syslog(LOG_NOTICE, "[UEC4:%02u SND(NBLK)] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(nblk_len));
+		return error;
+		}
+	else
+		syslog(LOG_NOTICE, "[UEC4:%02u SND(NBLK)] send:  %7lu,  to: %s.%d\n"
+		                   "                                    msg: %s",
+		                   cepid, time / SYSTIM_HZ, ip2str(NULL, &dst.ipaddr), dst.portno, line);
+
+	syscall(slp_tsk());
+	get_tim(&time);
+	if (nblk_len < 0) {	/* 0 ä»¥ä¸ã®å ´åã¯ãã¨ã©ã¼ã³ã¼ã */
+		syslog(LOG_NOTICE, "[UEC4:%02u CBR(NBLK)] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(nblk_len));
+		return nblk_len;
+		}
+
+	if ((error = udp_rcv_dat(cepid, &dst, udp_buf, sizeof(udp_buf), TMO_NBLK)) != E_WBLK) {
+		syslog(LOG_NOTICE, "[UEC4:%02u RCV(NBLK)] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(nblk_len));
+		return error;
+		}
+
+	syscall(slp_tsk());
+	get_tim(&time);
+	if (nblk_len < 0) {	/* 0 ä»¥ä¸ã®å ´åã¯ãã¨ã©ã¼ã³ã¼ã */
+		syslog(LOG_NOTICE, "[UEC4:%02u RCV(NBLK)] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(nblk_len));
+		return nblk_len;
+		}
+	else {
+		udp_buf[nblk_len] = '\0';
+		get_tim(&time);
+		syslog(LOG_NOTICE, "[UEC4:%02u RCV(NBLK)] recv:  %7lu,from: %s.%d\n"
+		                   "                                    msg: %s",
+		                   cepid, time / SYSTIM_HZ, ip2str(NULL, &dst.ipaddr), dst.portno, udp_buf);
+		nblk_len = E_OK;
+		}
+
+	return nblk_len;
+	}
+
+#else	/* of #if defined(USE_UDP_NON_BLOCKING) */
+
+#if defined(USE_UDP_CALL_BACK)
+
+/*
+ *  ã³ã¼ã«ããã¯é¢æ°
+ */
+
+ER
+callback_udp4_echo_cli (ID cepid, FN fncd, void *p_parblk)
+{
+	SYSTIM	time;
+	ER_UINT	len;
+
+	get_tim(&time);
+	if ((len = udp_rcv_dat(cepid, &dst, udp_buf, sizeof(udp_buf), TMO_FEVR)) >= 0) {
+		*(udp_buf + len) = '\0';
+		syslog(LOG_NOTICE, "[UEC4:%02u RCV(CB)] recv:  %7lu,from: %s.%d\n"
+		                   "                                  msg: %s",
+		                   cepid, time / SYSTIM_HZ, ip2str(NULL, &dst.ipaddr), dst.portno, udp_buf);
+		}
+	else
+		syslog(LOG_NOTICE, "[UEC4:%02u RCV(CB)] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(len));
+
+	return E_OK;
+	}
+
+/*
+ *  udp4_echo_cli -- ECHO/UDP ãµã¼ãã«ã¡ãã»ã¼ã¸ãéä¿¡ãã (ã³ã¼ã«ããã¯é¢æ°ä½¿ç¨)ã
+ */
+
+ER
+udp4_echo_cli (ID cepid, T_IN4_ADDR *ipaddr, uint16_t portno, char *line)
+{
+	SYSTIM	time;
+	ER_UINT	len;
+
+	dst.ipaddr = *ipaddr;
+	dst.portno = portno;
+	len        = strlen(line);
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[UEC4:%02u SND(CB)] send:  %7lu,  to: %s.%d\n"
+	                   "                                  msg: %s",
+	                   cepid, time / SYSTIM_HZ, ip2str(NULL, &dst.ipaddr), dst.portno, line);
+	if ((len = udp_snd_dat(cepid, &dst, line, len, TMO_FEVR)) < 0)
+		syslog(LOG_NOTICE, "[UEC4:%02u SND(CB)] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(len));
+
+	return E_OK;
+	}
+
+#else	/* of #if defined(USE_UDP_CALL_BACK) */
+
+/*
+ *  udp4_echo_cli -- ECHO/UDP ãµã¼ãã«ã¡ãã»ã¼ã¸ãéä¿¡ãã (ã³ã¼ã«ããã¯é¢æ°æªä½¿ç¨)ã
+ */
+
+ER
+udp4_echo_cli (ID cepid, T_IN4_ADDR *ipaddr, uint16_t portno, char *line)
+{
+	SYSTIM	time;
+	ER_UINT	len;
+
+	dst.ipaddr = *ipaddr;
+	dst.portno = portno;
+	len         = strlen(line);
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[UEC4:%02u SND] send:  %7lu,  to: %s.%d\n"
+	                   "                              msg: %s",
+	                   cepid, time / SYSTIM_HZ, ip2str(NULL, &dst.ipaddr), dst.portno, line);
+	if ((len = udp_snd_dat(cepid, &dst, line, len, TMO_FEVR)) < 0) {
+		syslog(LOG_NOTICE, "[UEC4:%02u SND] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(len));
+		return len;
+		}
+
+	if ((len = udp_rcv_dat(cepid, &dst, udp_buf, sizeof(udp_buf), 10*1000)) >= 0) {
+		*(udp_buf + len) = '\0';
+		get_tim(&time);
+		syslog(LOG_NOTICE, "[UEC4:%02u RCV] recv:  %7lu,from: %s.%d\n"
+		                   "                              msg: %s",
+		                   cepid, time / SYSTIM_HZ, ip2str(NULL, &dst.ipaddr), dst.portno, udp_buf);
+		return E_OK;
+		}
+	else {
+		get_tim(&time);
+		syslog(LOG_NOTICE, "[UEC4:%02u RCV] error: %7lu,%s",
+		       cepid, time / SYSTIM_HZ, itron_strerror(len));
+		return len;
+		}
+	}
+
+#endif	/* of #if defined(USE_UDP_CALL_BACK) */
+
+#endif	/* of #if defined(USE_UDP_NON_BLOCKING) */
+
+/*
+ *  getcomd -- ã³ãã³ããå¾ãã
+ */
+
+#if defined(UDP4_ECHO_CLI_AUTO_RUN_STR)
+
+static char *
+getcomd (ID cepid, bool_t retry)
+{
+	ER		error;
+	char		*line = NULL;
+	static char	auto_run_str[] = UDP4_ECHO_CLI_AUTO_RUN_STR;
+	static int_t	count = 0;
+
+	if (retry || count == 0) {
+		line = auto_run_str;
+		dly_tsk(6 * 1000);
+		}
+	else {
+		while ((error = rcv_dtq(DTQ_UDP4_ECHO_CLI, (intptr_t*)&line)) != E_OK) {
+			syslog(LOG_NOTICE, "[UEC4:%02u TSK] error:%s", cepid, itron_strerror(error));
+			dly_tsk(SLP_ITV);
+			}
+		}
+
+	count ++;
+	return line;
+	}
+
+#else	/* of #if defined(UDP4_ECHO_CLI_AUTO_RUN_STR) */
+
+static char *
+getcomd (ID cepid, bool_t retry)
+{
+	ER	error;
+	char	*line = NULL;
+
+	while ((error = rcv_dtq(DTQ_UDP4_ECHO_CLI, (intptr_t*)&line)) != E_OK) {
+		syslog(LOG_NOTICE, "[UEC4:%02u TSK] error:%s", cepid, itron_strerror(error));
+		dly_tsk(SLP_ITV);
+		}
+	return line;
+	}
+
+#endif	/* of #if defined(UDP4_ECHO_CLI_AUTO_RUN_STR) */
+
+#define MESSAGE_FORMAT	"MSG 1000000"
+
+/*
+ *  UDP4 ECHO ã¯ã©ã¤ã¢ã³ãéä¿¡ã¿ã¹ã¯
+ */
+
+void
+udp4_echo_cli_task (intptr_t exinf)
+{
+	static char msg[sizeof(MESSAGE_FORMAT)] = MESSAGE_FORMAT;
+
+	ID		tskid, cepid;
+	ER		error = E_OK;
+	SYSTIM		time;
+	T_IN4_ADDR	addr;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+	T_IN6_ADDR	addr6;
+#endif
+
+	char		*line, *p;
+	int_t		rep;
+	uint32_t	count, msgno;
+	bool_t		retry = false;
+	uint16_t	portno = ECHO_SRV_PORTNO;
+
+#if defined(USE_UDP_EXTENTIONS)
+	T_UDP_CCEP	ccep;
+#endif
+
+	dly_tsk(10*1000);
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[UDP4 ECHO CLI:%d,%d] started.", tskid, (ID)exinf);
+	while (true) {
+		line = skip_blanks(getcomd((ID)exinf, retry));
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+		line = lookup_ipaddr(&addr6, line, API_PROTO_IPV4);
+		if (line == NULL || !in6_is_addr_ipv4mapped(&addr6)) {
+			syslog(LOG_NOTICE, "[UEC4:%02u TSK] sleep %d.%03u[s], unknown host.",
+			       (ID)exinf, SLP_ITV / SYSTIM_HZ, SLP_ITV % SYSTIM_HZ);
+			dly_tsk(SLP_ITV);
+			syslog(LOG_NOTICE, "[UEC4:%02u TSK] resume.", (ID)exinf);
+			retry = true;
+			continue;
+			}
+		addr = ntohl(addr6.s6_addr32[3]);
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+		if ((line = lookup_ipaddr(&addr, line, DEFAULT_API_PROTO)) == NULL) {
+			syslog(LOG_NOTICE, "[UEC4:%02u TSK] sleep %d.%03u[s], unknown host.",
+			       (ID)exinf, SLP_ITV / SYSTIM_HZ, SLP_ITV % SYSTIM_HZ);
+			dly_tsk(SLP_ITV);
+			syslog(LOG_NOTICE, "[UEC4:%02u TSK] resume.", (ID)exinf);
+			retry = true;
+			continue;
+			}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+		line = skip_blanks(line);
+		if ('0' <= *line && *line <= '9') {	/* Port No */
+			line = get_int(&rep, line);
+			portno = (uint16_t)rep;
+			}
+		else if (*line == '-')
+			line ++;
+
+#if defined(USE_UDP_EXTENTIONS)
+
+		ccep.cepatr = UINT_C(0);
+		ccep.myaddr.portno = UDP_PORTANY;
+
+#if defined(SUPPORT_INET6)
+
+		memcpy(&ccep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
+
+#else	/* #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+		ccep.myaddr.ipaddr = IPV4_ADDRANY;
+#endif
+
+#endif	/* #if defined(SUPPORT_INET6) */
+
+#if defined(USE_UDP_NON_BLOCKING)
+		ccep.callback = (FP)callback_nblk_udp4_echo_cli;
+#else
+		ccep.callback = NULL;
+#endif
+
+		if ((error = alloc_udp4_cep(&cepid, tskid, &ccep)) != E_OK) {
+			syslog(LOG_NOTICE, "[UEC4:%02u TSK] CEP create error:%s", cepid, itron_strerror(error));
+			continue;
+			}
+
+#else/* of #if defined(USE_UDP_EXTENTIONS) */
+
+		cepid = (ID)exinf;
+
+#endif/* of #if defined(USE_UDP_EXTENTIONS) */
+
+		line = skip_blanks(line);
+		if ('0' <= *line && *line <= '9') {				/* Repeat */
+			line = get_int(&rep, line);
+#if 0
+			if (rep > 1000000)
+				rep = 1000000;
+#endif
+			udp4_echo_cli_valid = true;
+			count = 0;
+			while (rep == 0 || count < rep) {
+				if (!udp4_echo_cli_valid) {
+					syslog(LOG_NOTICE, "[UEC4:%02u TSK] canceled.", cepid);
+					break;
+					}
+					
+				count ++;
+				p = &msg[sizeof(MESSAGE_FORMAT)] - 1;
+				for (msgno = count; msgno > 0; msgno /= 10)
+					*(-- p) = msgno % 10 + '0';
+				while (*(p - 2) != 'G')
+					*(-- p) = ' ';
+
+				if ((error = udp4_echo_cli(cepid, &addr, portno, msg)) != E_OK)
+					dly_tsk(30 * SYSTIM_HZ);
+
+				dly_tsk(25 * SYSTIM_HZ + netapp_rand() % (10 * SYSTIM_HZ));
+				}
+			}
+
+		else								/* Single Message */
+			error = udp4_echo_cli(cepid, &addr, portno, line);
+
+		if (error != E_OK) {
+			get_tim(&time);
+			syslog(LOG_NOTICE, "[UEC4:%02u SND] error: %7lu,%s",
+			                   cepid, time / SYSTIM_HZ, itron_strerror(error));
+			}
+
+#if defined(USE_UDP_EXTENTIONS)
+
+		if ((error = free_udp4_cep(cepid, !(error == E_NOEXS || error == E_DLT))) != E_OK)
+			syslog(LOG_NOTICE, "[UEC4:%02u TSK] CEP delete error:%s", cepid, itron_strerror(error));
+
+#endif	/* of #if defined(USE_UDP_EXTENTIONS) */
+
+		}
+	}
+
+#endif	/* of #if defined(USE_UDP4_ECHO_CLI_TSK) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp4_echo_cli.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp4_echo_cli.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp4_echo_cli.cfg	(revision 331)
@@ -0,0 +1,82 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ECHO ãµã¼ãè©¦é¨ãã­ã°ã©ã ã®ã·ã¹ãã ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ */
+
+#ifdef USE_UDP4_ECHO_CLI_TSK
+
+/* ã¿ã¹ã¯ */
+
+#ifdef USE_UDP_EXTENTIONS
+
+CRE_TSK(UDP4_ECHO_CLI_TASK, {
+	TA_HLNG|TA_ACT,
+	0,
+	udp4_echo_cli_task,
+	UDP4_ECHO_CLI_MAIN_PRIORITY,
+	UDP4_ECHO_CLI_STACK_SIZE,
+	NULL
+	});
+
+#else	/* of #ifdef USE_UDP_EXTENTIONS */
+
+CRE_TSK(UDP4_ECHO_CLI_TASK, {
+	TA_HLNG|TA_ACT,
+	UDP4_ECHO_CLI_CEPID,
+	udp4_echo_cli_task,
+	UDP4_ECHO_CLI_MAIN_PRIORITY,
+	UDP4_ECHO_CLI_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
+
+/* ã³ãã³ãã­ã¥ã¼ */
+
+CRE_DTQ(DTQ_UDP4_ECHO_CLI,  { TA_TFIFO, 1, NULL });
+
+#endif	/* of #ifdef USE_UDP4_ECHO_CLI_TSK */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp4_echo_cli.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp4_echo_cli.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp4_echo_cli.h	(revision 331)
@@ -0,0 +1,76 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _UDP4_ECHO_CLI_H_
+#define _UDP4_ECHO_CLI_H_
+
+/* ã¹ã¿ãã¯ãµã¤ãº */
+
+#define UDP4_ECHO_CLI_STACK_SIZE	1024		/* UDP ECHO ã¯ã©ã¤ã¢ã³ãã¿ã¹ã¯ï¼IPv4ï¼ã®ã¹ã¿ãã¯ãµã¤ãº	*/
+
+/* åªå
+åº¦ */
+
+#define UDP4_ECHO_CLI_MAIN_PRIORITY	5		/* UDP ECHO ã¯ã©ã¤ã¢ã³ãã¿ã¹ã¯ï¼IPv4ï¼ã®åªå
+åº¦		*/
+
+/* å¤æ° */
+
+extern bool_t	udp4_echo_cli_valid;
+
+/* ã¿ã¹ã¯ */
+
+extern void	udp4_echo_cli_task(intptr_t exinf);
+
+/* é¢æ° */
+
+extern ER callback_udp4_echo_cli (ID cepid, FN fncd, void *p_parblk);
+extern ER callback_nblk_udp4_echo_cli (ID cepid, FN fncd, void *p_parblk);
+
+#ifdef T_IN4_ADDR_DEFINED
+extern ER udp4_echo_cli (ID cepid, T_IN4_ADDR *ipaddr, uint16_t portno, char *line);
+#endif
+
+#endif	/* of #ifndef _UDP4_ECHO_CLI_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp4_echo_srv.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp4_echo_srv.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp4_echo_srv.c	(revision 331)
@@ -0,0 +1,315 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  UDP ECHO ãµã¼ã
+ *
+ *    IPv4
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/udp4_echo_srv.h>
+
+#ifdef USE_UDP4_ECHO_SRV_TSK
+
+/*
+ *  åä¿¡ã¿ã¤ã ã¢ã¦ã
+ */
+
+#define RCV_TMOUT	TMO_FEVR
+//#define RCV_TMOUT	(30*ULONG_C(1000))
+
+#define BUF_SIZE	2048
+
+static char	echo_rcv_buf[BUF_SIZE];
+static T_IPV4EP	dst;
+
+#ifdef USE_UDP_CALL_BACK
+
+/*
+ *  ã³ã¼ã«ããã¯é¢æ°
+ */
+
+ER
+callback_udp4_echo_srv (ID cepid, FN fncd, void *p_parblk)
+{
+	ER_UINT	len;
+	SYSTIM	now;
+
+	if ((len = udp_rcv_dat(cepid, &dst, echo_rcv_buf, sizeof(echo_rcv_buf), TMO_FEVR)) >= 0) {
+		echo_rcv_buf[len] = '\0';
+		get_tim(&now);
+		syslog(LOG_NOTICE, "[UES4:%02u UCB] recv:  %7lu,from: %s.%d\n"
+		                   "                              msg: %s",
+		                   cepid, now / SYSTIM_HZ, ip2str(NULL, &dst.ipaddr), dst.portno, echo_rcv_buf);
+		if (len > 0) {
+			len = udp_snd_dat(cepid, &dst, echo_rcv_buf, len, TMO_FEVR);
+			get_tim(&now);
+			if (len >= 0)
+				syslog(LOG_NOTICE, "[UES4:%02u UCB] send:  %7lu, len: %d",
+				                   cepid, now / SYSTIM_HZ, len);
+			else
+				syslog(LOG_NOTICE, "[UES4:%02u UCB] error: %7lu,%s",
+				                   cepid, now / SYSTIM_HZ, itron_strerror(len));
+			}
+		len = E_OK;
+		}
+	else {
+		get_tim(&now);
+		syslog(LOG_NOTICE, "[UES4:%02u UCB] error: %7lu,%s",
+		                   cepid, now / SYSTIM_HZ, itron_strerror(len));
+		}
+
+	return len;
+	}
+
+#else	/* of #ifdef USE_UDP_CALL_BACK */
+
+#ifdef USE_UDP_NON_BLOCKING
+
+/*
+ *  å¤æ°
+ */
+
+static ER_UINT		nblk_len;
+
+/*
+ *  ãã³ãã­ãã­ã³ã°ã³ã¼ã«ã®ã³ã¼ã«ããã¯é¢æ°
+ */
+
+ER
+callback_nblk_udp4_echo_srv (ID cepid, FN fncd, void *p_parblk)
+{
+	SYSTIM	now;
+
+	get_tim(&now);
+	nblk_len = *(ER_UINT*)p_parblk;
+	if (nblk_len < 0) {	/* 0 ä»¥ä¸ã®å ´åã¯ãã¨ã©ã¼ã³ã¼ã */
+		syslog(LOG_NOTICE, "[UES4:%02u CBR] error,      %7lu,%s, fncd: %s",
+		                   cepid, now / SYSTIM_HZ, itron_strerror(nblk_len), in_strtfn(fncd));
+		}
+	else if (fncd == TFN_UDP_RCV_DAT) {
+		echo_rcv_buf[nblk_len] = '\0';
+		syslog(LOG_NOTICE, "[UES4:%02u CBR] recv:  %7lu,from: %s.%d\n"
+		                   "                              msg: %s",
+		                   cepid, now / SYSTIM_HZ, ip2str(NULL, &dst.ipaddr), dst.portno, echo_rcv_buf);
+		}
+	syscall(wup_tsk(UDP4_ECHO_SRV_TASK));
+	return E_OK;
+	}
+
+/*
+ *  UDP ECHO ãµã¼ã
+ */
+
+ER
+udp4_echo_srv (ID cepid)
+{
+	ER	error;
+	SYSTIM	now;
+
+	if ((error = udp_rcv_dat(cepid, &dst, echo_rcv_buf, sizeof(echo_rcv_buf), TMO_NBLK)) != E_WBLK) {
+		get_tim(&now);
+		syslog(LOG_NOTICE, "[UES4:%02u RCV] error: %7lu,%s",
+		                   cepid, now / SYSTIM_HZ, itron_strerror(error));
+		return error;
+		}
+
+	syscall(slp_tsk());
+	if (nblk_len < 0)
+		error = nblk_len;
+	else {
+		if ((error = udp_snd_dat(cepid, &dst, echo_rcv_buf, nblk_len, TMO_NBLK)) != E_WBLK) {
+			get_tim(&now);
+			syslog(LOG_NOTICE, "[UES4:%02u SND] error: %7lu,%s",
+			                   cepid, now / SYSTIM_HZ, itron_strerror(error));
+			return error;
+			}
+
+		syscall(slp_tsk());
+		if (nblk_len < 0)
+			error = nblk_len;
+		else {
+			get_tim(&now);
+			syslog(LOG_NOTICE, "[UES4:%02u SND] send:  %7lu, len: %d",
+			                   cepid, now / SYSTIM_HZ, nblk_len);
+			error = E_OK;
+			}
+		}
+
+	return error;
+	}
+
+#else	/* of #ifdef USE_UDP_NON_BLOCKING */
+
+/*
+ *  UDP ECHO ãµã¼ã
+ */
+
+ER
+udp4_echo_srv (ID cepid)
+{
+	ER_UINT	len;
+	SYSTIM	now;
+
+	if ((len = udp_rcv_dat(cepid, &dst, echo_rcv_buf, sizeof(echo_rcv_buf), RCV_TMOUT)) >= 0) {
+		get_tim(&now);
+		echo_rcv_buf[len] = '\0';
+		syslog(LOG_NOTICE, "[UES4:%02u RCV] recv:  %7lu,from: %s.%d\n"
+		                   "                              msg: %s",
+		                   cepid, now / SYSTIM_HZ, ip2str(NULL, &dst.ipaddr), dst.portno, echo_rcv_buf);
+		if (len > 0) {
+			len = udp_snd_dat(cepid, &dst, echo_rcv_buf, len, TMO_FEVR);
+			get_tim(&now);
+			if (len >= 0)
+				syslog(LOG_NOTICE, "[UES4:%02u SND] send:  %7lu, len: %d",
+				                   cepid, now / SYSTIM_HZ, (uint16_t)len);
+			else
+				syslog(LOG_NOTICE, "[UES4:%02u SND] error: %7lu,%s",
+				                   cepid, now / SYSTIM_HZ, itron_strerror(len));
+			}
+		}
+	else {
+		get_tim(&now);
+		syslog(LOG_NOTICE, "[UES4:%02u RCV] error: %7lu,%s",
+		                   cepid, now / SYSTIM_HZ, itron_strerror(len));
+		}
+
+	return len >= 0 || len == E_TMOUT ? E_OK : len;
+	}
+
+#endif	/* of #ifdef USE_UDP_NON_BLOCKING */
+
+/*
+ *  UDP ECHO ãµã¼ãã¿ã¹ã¯
+ */
+
+#ifdef USE_UDP_EXTENTIONS
+
+void
+udp4_echo_srv_task (intptr_t exinf)
+{
+	ID		tskid, cepid;
+	ER		error;
+	T_UDP_CCEP	ccep;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[UDP4 ECHO SRV(EXT):%d] started.", tskid);
+	while (true) {
+
+		syscall(slp_tsk());
+		syslog(LOG_NOTICE, "[UDP4 ECHO SRV(EXT):%d] wake up.", tskid);
+
+		ccep.cepatr = UINT_C(0);
+		ccep.myaddr.portno = UINT_C(7);
+		ccep.myaddr.ipaddr = IPV4_ADDRANY;
+
+#ifdef USE_UDP_NON_BLOCKING
+		ccep.callback = (FP)callback_nblk_udp4_echo_srv;
+#else
+		ccep.callback = NULL;
+#endif
+
+		if ((error = alloc_udp4_cep(&cepid, tskid, &ccep)) != E_OK) {
+			syslog(LOG_NOTICE, "[UES4:%02u TSK] CEP create error:%s", cepid, itron_strerror(error));
+			continue;
+			}
+
+		while (error == E_OK) {
+			if ((error = udp4_echo_srv(cepid)) != E_OK) {
+				if ((error = free_udp4_cep(cepid, !(error == E_NOEXS || error == E_DLT))) != E_OK)
+					syslog(LOG_NOTICE, "[UES4:%02u TSK] CEP delete error:%s", cepid, itron_strerror(error));
+				break;
+				}
+			}
+
+		}
+	slp_tsk();
+	}
+
+#else	/* of #ifdef USE_UDP_EXTENTIONS */
+
+void
+udp4_echo_srv_task (intptr_t exinf)
+{
+	ID	tskid;
+	ER	error = E_OK;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[UDP4 ECHO SRV:%d,%d] started.", tskid, (ID)exinf);
+	while (error == E_OK) {
+		error = udp4_echo_srv((ID)exinf);
+		}
+	slp_tsk();
+	}
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_UDP_CALL_BACK */
+
+#endif	/* of #ifdef USE_UDP4_ECHO_SRV_TSK */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp4_echo_srv.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp4_echo_srv.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp4_echo_srv.cfg	(revision 331)
@@ -0,0 +1,88 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  UDP ECHO ãµã¼ãã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ *
+ *    IPv4
+ */
+
+#ifdef USE_UDP4_ECHO_SRV_TSK
+
+/*
+ * ã¿ã¹ã¯
+ */
+
+#ifdef USE_UDP_CALL_BACK
+
+#else	/* of #ifdef USE_UDP_CALL_BACK */
+
+#ifdef USE_UDP_EXTENTIONS
+
+CRE_TSK(UDP4_ECHO_SRV_TASK, {
+	TA_HLNG | TA_ACT,
+	0,
+	udp4_echo_srv_task,
+	UDP4_ECHO_SRV_MAIN_PRIORITY,
+	UDP4_ECHO_SRV_STACK_SIZE,
+	NULL
+	});
+
+#else	/* of #ifdef USE_UDP_EXTENTIONS */
+
+CRE_TSK(UDP4_ECHO_SRV_TASK, {
+	TA_HLNG | TA_ACT,
+	UDP4_ECHO_SRV_CEPID,
+	udp4_echo_srv_task,
+	UDP4_ECHO_SRV_MAIN_PRIORITY,
+	UDP4_ECHO_SRV_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_UDP_CALL_BACK */
+
+#endif	/* of #ifdef USE_UDP4_ECHO_SRV_TSK */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp4_echo_srv.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp4_echo_srv.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp4_echo_srv.h	(revision 331)
@@ -0,0 +1,68 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _UDP4_ECHO_SRV_H_
+#define _UDP4_ECHO_SRV_H_
+
+/* ã¹ã¿ãã¯ãµã¤ãº */
+
+#define UDP4_ECHO_SRV_STACK_SIZE	1024		/* UDP ECHO ãµã¼ãã¿ã¹ã¯ï¼IPV4ï¼ã®ã¹ã¿ãã¯ãµã¤ãº	*/
+
+/* åªå
+åº¦ */
+
+#define UDP4_ECHO_SRV_MAIN_PRIORITY	5		/* UDP ECHO ãµã¼ãã¿ã¹ã¯ï¼IPV4ï¼ã®åªå
+åº¦		*/
+
+/* ã¿ã¹ã¯ */
+
+extern void	udp4_echo_srv_task(intptr_t exinf);
+
+/* é¢æ° */
+
+extern ER callback_udp4_echo_srv (ID cepid, FN fncd, void *p_parblk);
+extern ER callback_nblk_udp4_echo_srv (ID cepid, FN fncd, void *p_parblk);
+
+#endif	/* of #ifndef _UDP4_ECHO_SRV_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp6_echo_cli.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp6_echo_cli.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp6_echo_cli.c	(revision 331)
@@ -0,0 +1,460 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  UDP6 ECHO ã¯ã©ã¤ã¢ã³ã
+ */
+
+#include <string.h>
+
+#if defined(TARGET_KERNEL_ASP)
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #if defined(TARGET_KERNEL_ASP) */
+
+#if defined(TARGET_KERNEL_JSP)
+
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #if defined(TARGET_KERNEL_JSP) */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/udp4_echo_cli.h>
+#include <netapp/udp6_echo_cli.h>
+
+#if defined(USE_UDP6_ECHO_CLI_TSK)
+
+/* echo ãµã¼ãã®ãã¼ãçªå· */
+
+#define ECHO_SRV_PORTNO		UINT_C(7)
+
+/* éä¿¡éé */
+
+#if defined(TOPPERS_S810_CLG3_85)
+
+#define SLP_ITV		(30*SYSTIM_HZ)
+
+#else	/* of #if defined(TOPPERS_S810_CLG3_85) */
+
+#define SLP_ITV		(60*SYSTIM_HZ)
+
+#endif	/* of #if defined(TOPPERS_S810_CLG3_85) */
+
+/* èªåå®è¡ */
+
+#if defined(UDP6_ECHO_CLI_AUTO_RUN_STR)
+#else
+#if 0
+#define UDP6_ECHO_CLI_AUTO_RUN_STR	"fe80::211:2fff:fe8a:e8c0 - 1000"
+#endif
+#endif
+
+/*
+ *  å
+¨åå¤æ°
+ */
+
+bool_t udp6_echo_cli_valid;
+
+/*
+ * å¤æ°
+ */
+
+#define BUF_SIZE	2048
+
+static char		udp_buf[BUF_SIZE];
+static T_IPV6EP		dst;
+
+#if defined(USE_UDP_NON_BLOCKING)
+
+static ER_UINT		nblk_len;
+static ID		nblk_tskid;
+
+/*
+ *  ãã³ãã­ãã­ã³ã°ã³ã¼ã«ã®ã³ã¼ã«ããã¯é¢æ°
+ */
+
+ER
+callback_nblk_udp6_echo_cli (ID cepid, FN fncd, void *p_parblk)
+{
+	nblk_len = *(ER_UINT*)p_parblk;
+	syscall(wup_tsk(nblk_tskid));
+	return E_OK;
+	}
+
+/*
+ *  udp6_echo_cli -- ECHO/UDP ãµã¼ãã«ã¡ãã»ã¼ã¸ãéä¿¡ãã (ãã³ãã­ãã­ã³ã°ã³ã¼ã«ä½¿ç¨)ã
+ */
+
+static ER
+udp6_echo_cli (ID cepid, T_IN6_ADDR *ipaddr, uint16_t portno, char *line)
+{
+	ER_UINT	error;
+	SYSTIM	time;
+	uint_t	len;
+
+	dst.ipaddr = *ipaddr;
+	dst.portno = portno;
+	len         = strlen(line);
+	get_tim(&time);
+	get_tid(&nblk_tskid);
+	if ((error = udp6_snd_dat(cepid, &dst, line, len, TMO_NBLK)) != E_WBLK) {
+		syslog(LOG_NOTICE, "[UEC6:%02u SDN] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(nblk_len));
+		return error;
+		}
+	else
+		syslog(LOG_NOTICE, "[UEC6:%02u SDN] send:  %7lu,  to: %s.%d\n"
+		                   "                                    msg: %s",
+		                   cepid, time / SYSTIM_HZ, ipv62str(NULL, &dst.ipaddr), dst.portno, line);
+
+	syscall(slp_tsk());
+	get_tim(&time);
+	if (nblk_len < 0) {	/* 0 ä»¥ä¸ã®å ´åã¯ãã¨ã©ã¼ã³ã¼ã */
+		syslog(LOG_NOTICE, "[UEC6:%02u CBR] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(nblk_len));
+		return nblk_len;
+		}
+
+	if ((error = udp6_rcv_dat(cepid, &dst, udp_buf, sizeof(udp_buf), TMO_NBLK)) != E_WBLK) {
+		syslog(LOG_NOTICE, "[UEC6:%02u RVN] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(nblk_len));
+		return error;
+		}
+
+	syscall(slp_tsk());
+	get_tim(&time);
+	if (nblk_len < 0) {	/* 0 ä»¥ä¸ã®å ´åã¯ãã¨ã©ã¼ã³ã¼ã */
+		syslog(LOG_NOTICE, "[UEC6:%02u RVN] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(nblk_len));
+		return nblk_len;
+		}
+	else {
+		udp_buf[nblk_len] = '\0';
+		get_tim(&time);
+		syslog(LOG_NOTICE, "[UEC6:%02u RVN] recv:  %7lu,from: %s.%d\n"
+		                   "                                    msg: %s",
+		                   cepid, time / SYSTIM_HZ, ipv62str(NULL, &dst.ipaddr), dst.portno, udp_buf);
+		nblk_len = E_OK;
+		}
+
+	return nblk_len;
+	}
+
+#else	/* of #if defined(USE_UDP_NON_BLOCKING) */
+
+#if defined(USE_UDP_CALL_BACK)
+
+/*
+ *  ã³ã¼ã«ããã¯é¢æ°
+ */
+
+ER
+callback_udp6_echo_cli (ID cepid, FN fncd, void *p_parblk)
+{
+	SYSTIM	time;
+	ER_UINT	len;
+
+	get_tim(&time);
+	if ((len = udp6_rcv_dat(cepid, &dst, udp_buf, sizeof(udp_buf), TMO_FEVR)) >= 0) {
+		*(udp_buf + len) = '\0';
+		syslog(LOG_NOTICE, "[UEC6:%02u RVC)] recv:  %7lu,from: %s.%d\n"
+		                   "                                  msg: %s",
+		                   cepid, time / SYSTIM_HZ, ipv62str(NULL, &dst.ipaddr), dst.portno, udp_buf);
+		}
+	else
+		syslog(LOG_NOTICE, "[UEC6:%02u RVC] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(len));
+
+	return E_OK;
+	}
+
+/*
+ *  udp6_echo_cli -- ECHO/UDP ãµã¼ãã«ã¡ãã»ã¼ã¸ãéä¿¡ãã (ã³ã¼ã«ããã¯é¢æ°ä½¿ç¨)ã
+ */
+
+static ER
+udp6_echo_cli (ID cepid, T_IN6_ADDR *ipaddr, uint16_t portno, char *line)
+{
+	SYSTIM	time;
+	ER_UINT	len;
+
+	dst.ipaddr = *ipaddr;
+	dst.portno = portno;
+	len        = strlen(line);
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[UEC6:%02u SDC)] send:  %7lu,  to: %s.%d\n"
+		           "                                  msg: %s",
+	                   cepid, time / SYSTIM_HZ, ipv62str(NULL, &dst.ipaddr), dst.portno, line);
+	if ((len = udp6_snd_dat(cepid, &dst, line, len, TMO_FEVR)) < 0)
+		syslog(LOG_NOTICE, "[UEC6:%02u SDC] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(len));
+
+	return E_OK;
+	}
+
+#else	/* of #if defined(USE_UDP_CALL_BACK) */
+
+/*
+ *  udp6_echo_cli -- ECHO/UDP ãµã¼ãã«ã¡ãã»ã¼ã¸ãéä¿¡ãã (ã³ã¼ã«ããã¯é¢æ°æªä½¿ç¨)ã
+ */
+
+static ER
+udp6_echo_cli (ID cepid, T_IN6_ADDR *ipaddr, uint16_t portno, char *line)
+{
+	SYSTIM	time;
+	ER_UINT	len;
+
+	dst.ipaddr = *ipaddr;
+	dst.portno = portno;
+	len         = strlen(line);
+	get_tim(&time);
+	syslog(LOG_NOTICE, "[UEC6:%02u SND] send:  %7lu,  to: %s.%d\n"
+		           "                              msg: %s",
+	                   cepid, time / SYSTIM_HZ, ipv62str(NULL, &dst.ipaddr), dst.portno, line);
+	if ((len = udp6_snd_dat(cepid, &dst, line, len, TMO_FEVR)) < 0) {
+		syslog(LOG_NOTICE, "[UEC6:%02u SND] error: %7lu,%s",
+		                   cepid, time / SYSTIM_HZ, itron_strerror(len));
+		return len;
+		}
+
+	if ((len = udp6_rcv_dat(cepid, &dst, udp_buf, sizeof(udp_buf), 10*1000)) >= 0) {
+		*(udp_buf + len) = '\0';
+		get_tim(&time);
+		syslog(LOG_NOTICE, "[UEC6:%02u RCV] recv:  %7lu,from: %s.%d\n"
+		                   "                              msg: %s",
+		                   cepid, time / SYSTIM_HZ, ipv62str(NULL, &dst.ipaddr), dst.portno, udp_buf);
+		return E_OK;
+		}
+	else {
+		get_tim(&time);
+		syslog(LOG_NOTICE, "[UEC6:%02u RCV] error: %7lu,%s",
+		       cepid, time / SYSTIM_HZ, itron_strerror(len));
+		return len;
+		}
+	}
+
+#endif	/* of #if defined(USE_UDP_CALL_BACK) */
+
+#endif	/* of #if defined(USE_UDP_NON_BLOCKING) */
+
+/*
+ *  getcomd -- ã³ãã³ããå¾ãã
+ */
+
+#if defined(UDP6_ECHO_CLI_AUTO_RUN_STR)
+
+static char *
+getcomd (ID cepid, bool_t retry)
+{
+	ER		error;
+	char		*line = NULL;
+	static char	auto_run_str[] = UDP6_ECHO_CLI_AUTO_RUN_STR;
+	static int_t	count = 0;
+
+	if (retry || count == 0) {
+		line = auto_run_str;
+		dly_tsk(6 * 1000);
+		}
+	else {
+		while ((error = rcv_dtq(DTQ_UDP6_ECHO_CLI, (intptr_t*)&line)) != E_OK) {
+			syslog(LOG_NOTICE, "[UEC6:%02u TSK] error:%s", cepid, itron_strerror(error));
+			dly_tsk(SLP_ITV);
+			}
+		}
+
+	count ++;
+	return line;
+	}
+
+#else	/* of #if defined(UDP6_ECHO_CLI_AUTO_RUN_STR) */
+
+static char *
+getcomd (ID cepid, bool_t retry)
+{
+	ER	error;
+	char	*line = NULL;
+
+	while ((error = rcv_dtq(DTQ_UDP6_ECHO_CLI, (intptr_t*)&line)) != E_OK) {
+		syslog(LOG_NOTICE, "[UEC6:%02u TSK] error:%s", cepid, itron_strerror(error));
+		dly_tsk(SLP_ITV);
+		}
+	return line;
+	}
+
+#endif	/* of #if defined(UDP6_ECHO_CLI_AUTO_RUN_STR) */
+
+#define MESSAGE_FORMAT	"MSG 1000000"
+
+/*
+ *  UDP6 ECHO ã¯ã©ã¤ã¢ã³ãéä¿¡ã¿ã¹ã¯
+ */
+
+void
+udp6_echo_cli_task (intptr_t exinf)
+{
+	static char msg[sizeof(MESSAGE_FORMAT)] = MESSAGE_FORMAT;
+
+	ID		tskid, cepid;
+	ER		error = E_OK;
+	SYSTIM		time;
+	T_IN6_ADDR	addr;
+	char		*line, *p;
+	int_t		rep;
+	uint32_t	count, msgno;
+	bool_t		retry = false;
+	uint16_t	portno = ECHO_SRV_PORTNO;
+
+#if defined(USE_UDP_EXTENTIONS)
+	T_UDP6_CCEP	ccep;
+#endif
+
+	dly_tsk(10*1000);
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[UDP6 ECHO CLI:%d,%d] started.", tskid, (ID)exinf);
+	while (true) {
+		line = skip_blanks(getcomd((ID)exinf, retry));
+
+		if ((line = lookup_ipaddr(&addr, line, API_PROTO_IPV6)) == NULL) {
+			syslog(LOG_NOTICE, "[UEC6:%02u TSK] sleep %d.%03u[s], unknown host.",
+			       (ID)exinf, SLP_ITV / SYSTIM_HZ, SLP_ITV % SYSTIM_HZ);
+			dly_tsk(SLP_ITV);
+			syslog(LOG_NOTICE, "[UEC6:%02u TSK] resume.", (ID)exinf);
+			retry = true;
+			continue;
+			}
+
+		line = skip_blanks(line);
+		if ('0' <= *line && *line <= '9') {	/* Port No */
+			line = get_int(&rep, line);
+			portno = (uint16_t)rep;
+			}
+		else if (*line == '-')
+			line ++;
+
+#if defined(USE_UDP_EXTENTIONS)
+
+		ccep.cepatr = UINT_C(0);
+		ccep.myaddr.portno = UDP_PORTANY;
+		memcpy(&ccep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
+
+#ifdef USE_UDP_NON_BLOCKING
+		ccep.callback = (FP)callback_nblk_udp6_echo_cli;
+#else
+		ccep.callback = NULL;
+#endif
+
+		if ((error = alloc_udp6_cep(&cepid, tskid, &ccep)) != E_OK) {
+			syslog(LOG_NOTICE, "[UEC6:%02u TSK] CEP create error:%s", cepid, itron_strerror(error));
+			continue;
+			}
+
+#else/* of #ifdef USE_UDP_EXTENTIONS */
+
+		cepid = (ID)exinf;
+
+#endif	/* of #if defined(USE_UDP_EXTENTIONS) */
+
+		line = skip_blanks(line);
+		if ('0' <= *line && *line <= '9') {				/* Repeat */
+			line = get_int(&rep, line);
+#if 0
+			if (rep > 1000000)
+				rep = 1000000;
+#endif
+			udp6_echo_cli_valid = true;
+			count = 0;
+			while (rep == 0 || count < rep) {
+				if (!udp6_echo_cli_valid) {
+					syslog(LOG_NOTICE, "[UEC6:%02u TSK] canceled.", cepid);
+					break;
+					}
+					
+				count ++;
+				p = &msg[sizeof(MESSAGE_FORMAT)] - 1;
+				for (msgno = count; msgno > 0; msgno /= 10)
+					*(-- p) = msgno % 10 + '0';
+				while (*(p - 2) != 'G')
+					*(-- p) = ' ';
+
+				if ((error = udp6_echo_cli(cepid, &addr, portno, msg)) != E_OK)
+					dly_tsk(30 * SYSTIM_HZ);
+
+				dly_tsk(25 * SYSTIM_HZ + netapp_rand() % (10 * SYSTIM_HZ));
+				}
+			}
+
+		else								/* Single Message */
+
+			error = udp6_echo_cli(cepid, &addr, portno, line);
+
+		if (error != E_OK) {
+			get_tim(&time);
+			syslog(LOG_NOTICE, "[UEC6:%02u SND] error: %7lu,%s",
+			                   cepid, time / SYSTIM_HZ, itron_strerror(error));
+			}
+
+#if defined(USE_UDP_EXTENTIONS)
+
+		if ((error = free_udp6_cep(cepid, !(error == E_NOEXS || error == E_DLT))) != E_OK)
+			syslog(LOG_NOTICE, "[UEC6:%02u TSK] CEP delete error:%s", cepid, itron_strerror(error));
+
+#endif	/* of #if defined(USE_UDP_EXTENTIONS) */
+
+		}
+	}
+
+#endif	/* of #if defined(USE_UDP6_ECHO_CLI_TSK) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp6_echo_cli.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp6_echo_cli.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp6_echo_cli.cfg	(revision 331)
@@ -0,0 +1,82 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  ECHO ãµã¼ãè©¦é¨ãã­ã°ã©ã ã®ã·ã¹ãã ã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ */
+
+#ifdef USE_UDP6_ECHO_CLI_TSK
+
+/* ã¿ã¹ã¯ */
+
+#ifdef USE_UDP_EXTENTIONS
+
+CRE_TSK(UDP6_ECHO_CLI_TASK, {
+	TA_HLNG|TA_ACT,
+	0,
+	udp6_echo_cli_task,
+	UDP6_ECHO_CLI_MAIN_PRIORITY,
+	UDP6_ECHO_CLI_STACK_SIZE,
+	NULL
+	});
+
+#else	/* of #ifdef USE_UDP_EXTENTIONS */
+
+CRE_TSK(UDP6_ECHO_CLI_TASK, {
+	TA_HLNG|TA_ACT,
+	UDP6_ECHO_CLI_CEPID,
+	udp6_echo_cli_task,
+	UDP6_ECHO_CLI_MAIN_PRIORITY,
+	UDP6_ECHO_CLI_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
+
+/* ã³ãã³ãã­ã¥ã¼ */
+
+CRE_DTQ(DTQ_UDP6_ECHO_CLI,  { TA_TFIFO, 1, NULL });
+
+#endif	/* of #ifdef USE_UDP6_ECHO_CLI_TSK */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp6_echo_cli.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp6_echo_cli.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp6_echo_cli.h	(revision 331)
@@ -0,0 +1,72 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _UDP6_ECHO_CLI_H_
+#define _UDP6_ECHO_CLI_H_
+
+/* ã¹ã¿ãã¯ãµã¤ãº */
+
+#define UDP6_ECHO_CLI_STACK_SIZE	1024		/* UDP ECHO ã¯ã©ã¤ã¢ã³ãã¿ã¹ã¯ï¼IPv6ï¼ã®ã¹ã¿ãã¯ãµã¤ãº	*/
+
+/* åªå
+åº¦ */
+
+#define UDP6_ECHO_CLI_MAIN_PRIORITY	5		/* UDP ECHO ã¯ã©ã¤ã¢ã³ãã¿ã¹ã¯ï¼IPv6ï¼ã®åªå
+åº¦		*/
+
+/* å¤æ° */
+
+extern bool_t	udp6_echo_cli_valid;
+
+/* ã¿ã¹ã¯ */
+
+extern void	udp6_echo_cli_task(intptr_t exinf);
+
+/* é¢æ° */
+
+extern ER callback_udp6_echo_cli (ID cepid, FN fncd, void *p_parblk);
+extern ER callback_nblk_udp6_echo_cli (ID cepid, FN fncd, void *p_parblk);
+
+#endif	/* of #ifndef _UDP6_ECHO_CLI_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp6_echo_srv.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp6_echo_srv.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp6_echo_srv.c	(revision 331)
@@ -0,0 +1,314 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/* 
+ *  UDP ECHO ãµã¼ã
+ *
+ *    IPv6
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <t_services.h>
+#include "kernel_id.h"
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <netinet/in.h>
+#include <netinet/in_itron.h>
+
+#include <netapp/netapp.h>
+#include <netapp/netapp_var.h>
+#include <netapp/udp6_echo_srv.h>
+
+#ifdef USE_UDP6_ECHO_SRV_TSK
+
+/*
+ *  åä¿¡ã¿ã¤ã ã¢ã¦ã
+ */
+
+#define RCV_TMOUT	TMO_FEVR
+//#define RCV_TMOUT	(30*ULONG_C(1000))
+
+#define BUF_SIZE	2048
+
+static char	echo_rcv_buf[BUF_SIZE];
+static T_IPV6EP	dst;
+
+#ifdef USE_UDP_CALL_BACK
+
+/*
+ *  ã³ã¼ã«ããã¯é¢æ°
+ */
+
+ER
+callback_udp6_echo_srv (ID cepid, FN fncd, void *p_parblk)
+{
+	ER_UINT	len;
+	SYSTIM	now;
+
+	if ((len = udp6_rcv_dat(cepid, &dst, echo_rcv_buf, sizeof(echo_rcv_buf), TMO_FEVR)) >= 0) {
+		echo_rcv_buf[len] = '\0';
+		get_tim(&now);
+		syslog(LOG_NOTICE, "[UES6:%02u UCB] recv:  %7lu,from: %s.%d\n"
+		                   "                              msg: %s",
+		                   cepid, now / SYSTIM_HZ, ipv62str(NULL, &dst.ipaddr), dst.portno, echo_rcv_buf);
+		if (len > 0) {
+			len = udp6_snd_dat(cepid, &dst, echo_rcv_buf, len, TMO_FEVR);
+			get_tim(&now);
+			if (len >= 0)
+				syslog(LOG_NOTICE, "[UES6:%02u UCB] send:  %7lu, len: %d",
+				                   cepid, now / SYSTIM_HZ, len);
+			else
+				syslog(LOG_NOTICE, "[UES6:%02u UCB] error: %7lu,%s",
+				                   cepid, now / SYSTIM_HZ, itron_strerror(len));
+			}
+		len = E_OK;
+		}
+	else {
+		get_tim(&now);
+		syslog(LOG_NOTICE, "[UES6:%02u UCB] recv:  %7lu,%s",
+		                   cepid, now / SYSTIM_HZ, itron_strerror(len));
+		}
+
+	return len;
+	}
+
+#else	/* of #ifdef USE_UDP_CALL_BACK */
+
+#ifdef USE_UDP_NON_BLOCKING
+
+/*
+ *  å¤æ°
+ */
+
+static ER_UINT		nblk_len;
+
+/*
+ *  ãã³ãã­ãã­ã³ã°ã³ã¼ã«ã®ã³ã¼ã«ããã¯é¢æ°
+ */
+
+ER
+callback_nblk_udp6_echo_srv (ID cepid, FN fncd, void *p_parblk)
+{
+	SYSTIM	now;
+
+	get_tim(&now);
+	nblk_len = *(ER_UINT*)p_parblk;
+	if (nblk_len < 0) {	/* 0 ä»¥ä¸ã®å ´åã¯ãã¨ã©ã¼ã³ã¼ã */
+		syslog(LOG_NOTICE, "[UES6:%02u CBR] error: %7lu,%s, fncd: %s",
+		                   cepid, now / SYSTIM_HZ, itron_strerror(nblk_len), in_strtfn(fncd));
+		}
+	else if (fncd == TFN_UDP_RCV_DAT) {
+		echo_rcv_buf[nblk_len] = '\0';
+		syslog(LOG_NOTICE, "[UES6:%02u CBR] recv:  %7lu,from: %s.%d\n"
+		                   "                              msg: %s",
+		                   cepid, now / SYSTIM_HZ, ipv62str(NULL, &dst.ipaddr), dst.portno, echo_rcv_buf);
+		}
+	syscall(wup_tsk(UDP6_ECHO_SRV_TASK));
+	return E_OK;
+	}
+
+/*
+ *  UDP ECHO ãµã¼ã
+ */
+
+ER
+udp6_echo_srv (ID cepid)
+{
+	ER	error;
+	SYSTIM	now;
+
+	if ((error = udp6_rcv_dat(cepid, &dst, echo_rcv_buf, sizeof(echo_rcv_buf), TMO_NBLK)) != E_WBLK) {
+		get_tim(&now);
+		syslog(LOG_NOTICE, "[UES6:%02u RCV] error: %7lu,%s", cepid, now / SYSTIM_HZ, itron_strerror(error));
+		return error;
+		}
+
+	syscall(slp_tsk());
+	if (nblk_len < 0)
+		error = nblk_len;
+	else {
+		if ((error = udp6_snd_dat(cepid, &dst, echo_rcv_buf, nblk_len, TMO_NBLK)) != E_WBLK) {
+			get_tim(&now);
+			syslog(LOG_NOTICE, "[UES6:%02u SND] error  %7lu,%s",
+			                   cepid, now / SYSTIM_HZ, itron_strerror(error));
+			return error;
+			}
+
+		syscall(slp_tsk());
+		if (nblk_len < 0)
+			error = nblk_len;
+		else {
+			get_tim(&now);
+			syslog(LOG_NOTICE, "[UES6:%02u SND] send:  %7lu, len: %d",
+			                   cepid, now / SYSTIM_HZ, nblk_len);
+			error = E_OK;
+			}
+		}
+
+	return error;
+	}
+
+#else	/* of #ifdef USE_UDP_NON_BLOCKING */
+
+/*
+ *  UDP ECHO ãµã¼ã
+ */
+
+ER
+udp6_echo_srv (ID cepid)
+{
+	ER_UINT	len;
+	SYSTIM	now;
+
+	if ((len = udp6_rcv_dat(cepid, &dst, echo_rcv_buf, sizeof(echo_rcv_buf), RCV_TMOUT)) >= 0) {
+		get_tim(&now);
+		echo_rcv_buf[len] = '\0';
+		syslog(LOG_NOTICE, "[UES6:%02u RCV] recv:  %7lu,from: %s.%d\n"
+		                   "                              msg: %s",
+		                   cepid, now / SYSTIM_HZ, ipv62str(NULL, &dst.ipaddr), dst.portno, echo_rcv_buf);
+		if (len > 0) {
+			len = udp6_snd_dat(cepid, &dst, echo_rcv_buf, len, TMO_FEVR);
+			get_tim(&now);
+			if (len >= 0)
+				syslog(LOG_NOTICE, "[UES6:%02u SND] send:  %7lu, len: %d",
+				                   cepid, now / SYSTIM_HZ, (uint16_t)len);
+			else
+				syslog(LOG_NOTICE, "[UES6:%02u SND] error: %7lu,%s",
+				                   cepid, now / SYSTIM_HZ, itron_strerror(len));
+			}
+		}
+	else {
+		get_tim(&now);
+		syslog(LOG_NOTICE, "[UES6:%02u RCV] error: %7lu,%s",
+		                   cepid, now / SYSTIM_HZ, itron_strerror(len));
+		}
+
+	return len >= 0 || len == E_TMOUT ? E_OK : len;
+	}
+
+#endif	/* of #ifdef USE_UDP_NON_BLOCKING */
+
+/*
+ *  UDP ECHO ãµã¼ãã¿ã¹ã¯
+ */
+
+#ifdef USE_UDP_EXTENTIONS
+
+void
+udp6_echo_srv_task (intptr_t exinf)
+{
+	ID		tskid, cepid;
+	ER		error;
+	T_UDP6_CCEP	ccep;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[UDP6 ECHO SRV(EXT):%d] started.", tskid);
+	while (true) {
+
+		syscall(slp_tsk());
+		syslog(LOG_NOTICE, "[UDP6 ECHO SRV(EXT):%d] wake up.", tskid);
+
+		ccep.cepatr = UINT_C(0);
+		ccep.myaddr.portno = UINT_C(7);
+		memcpy(&ccep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
+
+#ifdef USE_UDP_NON_BLOCKING
+		ccep.callback = (FP)callback_nblk_udp6_echo_srv;
+#else
+		ccep.callback = NULL;
+#endif
+
+		if ((error = alloc_udp6_cep(&cepid, tskid, &ccep)) != E_OK) {
+			syslog(LOG_NOTICE, "[UES6:%02u TSK] CEP create error:%s", cepid, itron_strerror(error));
+			continue;
+			}
+
+		while (error == E_OK) {
+			if ((error = udp6_echo_srv(cepid)) != E_OK) {
+				if ((error = free_udp6_cep(cepid, !(error == E_NOEXS || error == E_DLT))) != E_OK)
+					syslog(LOG_NOTICE, "[UES6:%02u TSK] CEP delete error:%s", cepid, itron_strerror(error));
+				break;
+				}
+			}
+
+		}
+	slp_tsk();
+	}
+
+#else	/* of #ifdef USE_UDP_EXTENTIONS */
+
+void
+udp6_echo_srv_task (intptr_t exinf)
+{
+	ID	tskid;
+	ER	error = E_OK;
+
+	get_tid(&tskid);
+	syslog(LOG_NOTICE, "[UDP6 ECHO SRV:%d,%d] started.", tskid, (ID)exinf);
+	while (error == E_OK) {
+		error = udp6_echo_srv((ID)exinf);
+		}
+	slp_tsk();
+	}
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_UDP_CALL_BACK */
+
+#endif	/* of #ifdef USE_UDP6_ECHO_SRV_TSK */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp6_echo_srv.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp6_echo_srv.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp6_echo_srv.cfg	(revision 331)
@@ -0,0 +1,88 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  UDP ECHO ãµã¼ãã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«
+ *
+ *    IPv6
+ */
+
+#ifdef USE_UDP6_ECHO_SRV_TSK
+
+/*
+ * ã¿ã¹ã¯
+ */
+
+#ifdef USE_UDP_CALL_BACK
+
+#else	/* of #ifdef USE_UDP_CALL_BACK */
+
+#ifdef USE_UDP_EXTENTIONS
+
+CRE_TSK(UDP6_ECHO_SRV_TASK, {
+	TA_HLNG | TA_ACT,
+	0,
+	udp6_echo_srv_task,
+	UDP6_ECHO_SRV_MAIN_PRIORITY,
+	UDP6_ECHO_SRV_STACK_SIZE,
+	NULL
+	});
+
+#else	/* of #ifdef USE_UDP_EXTENTIONS */
+
+CRE_TSK(UDP6_ECHO_SRV_TASK, {
+	TA_HLNG | TA_ACT,
+	UDP6_ECHO_SRV_CEPID,
+	udp6_echo_srv_task,
+	UDP6_ECHO_SRV_MAIN_PRIORITY,
+	UDP6_ECHO_SRV_STACK_SIZE,
+	NULL
+	});
+
+#endif	/* of #ifdef USE_UDP_EXTENTIONS */
+
+#endif	/* of #ifdef USE_UDP_CALL_BACK */
+
+#endif	/* of #ifdef USE_UDP6_ECHO_SRV_TSK */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp6_echo_srv.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp6_echo_srv.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp6_echo_srv.h	(revision 331)
@@ -0,0 +1,68 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _UDP6_ECHO_SRV_H_
+#define _UDP6_ECHO_SRV_H_
+
+/* ã¹ã¿ãã¯ãµã¤ãº */
+
+#define UDP6_ECHO_SRV_STACK_SIZE	1024		/* UDP ECHO ãµã¼ãã¿ã¹ã¯ï¼IPv6ï¼ã®ã¹ã¿ãã¯ãµã¤ãº		*/
+
+/* åªå
+åº¦ */
+
+#define UDP6_ECHO_SRV_MAIN_PRIORITY	5		/* UDP ECHO ãµã¼ãã¿ã¹ã¯ï¼IPv6ï¼ã®åªå
+åº¦			*/
+
+/* ã¿ã¹ã¯ */
+
+extern void	udp6_echo_srv_task(intptr_t exinf);
+
+/* é¢æ° */
+
+extern ER callback_udp6_echo_srv (ID cepid, FN fncd, void *p_parblk);
+extern ER callback_nblk_udp6_echo_srv (ID cepid, FN fncd, void *p_parblk);
+
+#endif	/* of #ifndef _UDP6_ECHO_SRV_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp_discard_cli.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp_discard_cli.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp_discard_cli.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -56,25 +56,12 @@
 #endif	/* of #ifdef TARGET_KERNEL_JSP */
 
-#include <tinet_defs.h>
-#include <tinet_config.h>
-
-#include <net/if.h>
-#include <net/if_ppp.h>
-#include <net/if_loop.h>
-#include <net/ethernet.h>
-#include <net/net.h>
-#include <net/net_var.h>
-#include <net/net_timer.h>
-
 #include <netinet/in.h>
+#include <netinet/in_itron.h>
 #include <netinet/ip.h>
-#include <netinet/ip6.h>
 #include <netinet/udp.h>
-#include <netinet/udp_var.h>
-#include <netinet/in_itron.h>
 
 #include <netapp/netapp.h>
 #include <netapp/netapp_var.h>
-#include <netapp/discard.h>
+#include <netapp/udp_discard_cli.h>
 
 #ifdef USE_UDP_DISCARD_CLI
@@ -90,4 +77,10 @@
 #define PAT_BEGIN	' '
 #define PAT_END		'~'
+
+#if defined(SUPPORT_INET6)
+#define API_PROTO		'6'
+#else
+#define API_PROTO		'4'
+#endif
 
 /*
@@ -104,5 +97,9 @@
 send_udp_discard (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno)
 {
-	static char smsg[IF_MTU - IP_UDP_HDR_SIZE];
+#if defined(SUPPORT_INET6)
+	static char smsg[IPV6_MMTU - (IP6_HDR_SIZE + UDP_HDR_SIZE)];
+#else
+	static char smsg[IP4_MSS - (IP4_HDR_SIZE + UDP_HDR_SIZE)];
+#endif
 
 	T_IPEP		dst;
@@ -117,29 +114,29 @@
 
 	p = smsg;
-	for (slen = IF_MTU - IP_UDP_HDR_SIZE; slen > 0; )
+	for (slen = sizeof(smsg); slen > 0; )
 		for (pat = PAT_BEGIN; slen > 0 && pat <= PAT_END; pat ++, slen --)
 			*p ++ = pat;
 
 	get_tim(&time);
-	syslog(LOG_NOTICE, "[UDC:%02d SND] sending:    %6ld, to:   %s.%d",
-	                   cepid, time / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
+	syslog(LOG_NOTICE, "[UDC%c:%02u SND] send:  %7lu, to:   %s.%d",
+	                   API_PROTO, cepid, time / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
 
 	scount = total = 0;
 	udp_discard_cli_valid = true;
-	for (slen = IF_MTU - IP_UDP_HDR_SIZE; udp_discard_cli_valid && slen > 0; slen --) {
+	for (slen = sizeof(smsg); udp_discard_cli_valid && slen > 0; slen --) {
 		scount ++;
 		if ((len = UDP_SND_DAT(cepid, &dst, smsg, slen, TMO_FEVR)) < 0) {
-			syslog(LOG_NOTICE, "[UDC:%02d SND] send error: %s", cepid, itron_strerror(len));
+			syslog(LOG_NOTICE, "[UDC%c:%02u SND] error: %s", API_PROTO, cepid, itron_strerror(len));
 			return len;
 			}
 		else
-			syslog(LOG_NOTICE, "[UDC:%02d SND] send: %4d, %4d", cepid, scount, slen);
+			syslog(LOG_NOTICE, "[UDC%c:%02u SND] send:  %7lu, %4u", API_PROTO, cepid, scount, slen);
 		total += len;
-		dly_tsk(10 * SYSTIM_HZ + net_rand() % (10 * SYSTIM_HZ));
+		dly_tsk(10 * SYSTIM_HZ + netapp_rand() % (10 * SYSTIM_HZ));
 		}
 
 	get_tim(&time);
-	syslog(LOG_NOTICE, "[UDC:%02d SND] finished:   %6ld, snd: %4d,            len: %ld",
-		           cepid, time / SYSTIM_HZ, scount, total);
+	syslog(LOG_NOTICE, "[UDC%c:%02u SND] finsh: %7lu, snd: %4u,            len: %ld",
+		           API_PROTO, cepid, time / SYSTIM_HZ, scount, total);
 	return E_OK;
 	}
@@ -158,10 +155,21 @@
 	int_t		no;
 	uint16_t	portno;
+	char		apip;
 
 #ifdef USE_UDP_EXTENTIONS
 
+#if defined(SUPPORT_INET6)
+	T_UDP6_CCEP	ccep;
+#else
 	T_UDP_CCEP	ccep;
+#endif
 
 #endif	/* of #ifdef USE_UDP_EXTENTIONS */
+
+#if defined(SUPPORT_INET6)
+	apip = API_PROTO_IPV6;
+#else
+	apip = API_PROTO_IPV4;
+#endif
 
 	get_tid(&tskid);
@@ -171,4 +179,9 @@
 			line = skip_blanks(GET_IPADDR(&addr, skip_blanks(line)));	/* IP Address */
 
+			if ((line = lookup_ipaddr(&addr, line, apip)) == NULL) {
+				syslog(LOG_NOTICE, "[UDC%c:%02u TSK] unknown host.", (ID)exinf);
+				continue;
+				}
+
 			if ('0' <= *line && *line <= '9') {				/* Port No */
 				line = get_int(&no, line);
@@ -186,14 +199,18 @@
 			ccep.myaddr.portno = UDP_PORTANY;
 
+#if defined(SUPPORT_INET6)
+
+			memcpy(&ccep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
+
+#else	/* #if defined(SUPPORT_INET6) */
+
 #if defined(SUPPORT_INET4)
 			ccep.myaddr.ipaddr = IPV4_ADDRANY;
 #endif
 
-#if defined(SUPPORT_INET6)
-			memcpy(&ccep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
-#endif
-
-			if ((error = alloc_udp_cep(&cepid, tskid, &ccep)) != E_OK) {
-				syslog(LOG_NOTICE, "[UDC:%02d TSK] CEP create error: %s", cepid, itron_strerror(error));
+#endif	/* #if defined(SUPPORT_INET6) */
+
+			if ((error = ALLOC_UDP_CEP(&cepid, tskid, &ccep)) != E_OK) {
+				syslog(LOG_NOTICE, "[UDC%c:%02u TSK] CEP create error: %s", API_PROTO, cepid, itron_strerror(error));
 				continue;
 				}
@@ -206,10 +223,10 @@
 
 			if ((error = send_udp_discard(cepid, &addr, portno)) != E_OK)
-				syslog(LOG_NOTICE, "[UDC:%02d TSK] error: %s", cepid, itron_strerror(error));
+				syslog(LOG_NOTICE, "[UDC%c:%02u TSK] error: %s", API_PROTO, cepid, itron_strerror(error));
 
 #ifdef USE_UDP_EXTENTIONS
 
-			if ((error = free_udp_cep(cepid, !(error == E_NOEXS || error == E_DLT))) != E_OK)
-				syslog(LOG_NOTICE, "[UDC:%02d TSK] CEP delete error: %s", cepid, itron_strerror(error));
+			if ((error = FREE_UDP_CEP(cepid, !(error == E_NOEXS || error == E_DLT))) != E_OK)
+				syslog(LOG_NOTICE, "[UDC%c:%02u TSK] CEP delete error: %s", API_PROTO, cepid, itron_strerror(error));
 
 #endif	/* of #ifdef USE_UDP_EXTENTIONS */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp_discard_cli.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp_discard_cli.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp_discard_cli.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp_discard_cli.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp_discard_cli.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp_discard_cli.h	(revision 331)
@@ -0,0 +1,72 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+#ifndef _UDP_DISCARD_CLI_H_
+#define _UDP_DISCARD_CLI_H_
+
+/* ã¹ã¿ãã¯ãµã¤ãº */
+
+#define UDP_DISCARD_CLI_STACK_SIZE	1024		/* UDP DISCARD ã¯ã©ã¤ã¢ã³ãã¿ã¹ã¯ã®ã¹ã¿ãã¯ãµã¤ãº	*/
+
+/* åªå
+åº¦ */
+
+#define UDP_DISCARD_CLI_MAIN_PRIORITY	5		/* UDP DISCARD ã¯ã©ã¤ã¢ã³ãã¿ã¹ã¯ã®åªå
+åº¦		*/
+
+/* å¤æ° */
+
+extern bool_t	udp_discard_cli_valid;
+
+/* ã¿ã¹ã¯ */
+
+extern void	udp_discard_cli_task(intptr_t exinf);
+
+/* é¢æ° */
+
+extern ER callback_udp_discard_cli (ID cepid, FN fncd, void *p_parblk);
+extern ER callback_nblk_udp_discard_cli (ID cepid, FN fncd, void *p_parblk);
+
+#endif	/* of #ifndef _UDP_DISCARD_CLI_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp_echo_cli.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp_echo_cli.c	(revision 321)
+++ 	(revision )
@@ -1,349 +1,0 @@
-/*
- *  TINET (TCP/IP Protocol Stack)
- * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
- *                   Tomakomai National College of Technology, JAPAN
- *
- *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
- *  によって公表されている GNU General Public License の Version 2 に記
- *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
- *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
- *  利用と呼ぶ）することを無償で許諾する．
- *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
- *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
- *      スコード中に含まれていること．
- *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
- *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
- *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
- *      の無保証規定を掲載すること．
- *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
- *      用できない形で再配布する場合には，次の条件を満たすこと．
- *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
- *        作権表示，この利用条件および下記の無保証規定を掲載すること．
- *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
- *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
- *
- *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
- *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
- *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
- *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
- * 
- *  @(#) $Id$
- */
-
-/* 
- *  UDP ECHO クライアント
- */
-
-#include <string.h>
-
-#ifdef TARGET_KERNEL_ASP
-
-#include <kernel.h>
-#include <sil.h>
-#include <t_syslog.h>
-#include "kernel_cfg.h"
-
-#endif	/* of #ifdef TARGET_KERNEL_ASP */
-
-#ifdef TARGET_KERNEL_JSP
-
-#include <t_services.h>
-#include "kernel_id.h"
-#include "tinet_id.h"
-
-#endif	/* of #ifdef TARGET_KERNEL_JSP */
-
-#include <tinet_defs.h>
-#include <tinet_config.h>
-
-#include <net/net.h>
-#include <net/net_var.h>
-#include <net/net_timer.h>
-
-#include <netinet/in.h>
-#include <netinet/in_itron.h>
-
-#include <netapp/netapp.h>
-#include <netapp/netapp_var.h>
-#include <netapp/echo.h>
-
-#ifdef USE_UDP_ECHO_CLI
-
-/* echo サーバのポート番号 */
-
-#define ECHO_SRV_PORTNO		UINT_C(7)
-
-/*
- *  全域変数
- */
-
-bool_t udp_echo_cli_valid;
-
-/*
- * 変数
- */
-
-#define BUF_SIZE	2048
-
-static char		udp_buf[BUF_SIZE];
-static T_IPEP		dst;
-
-#ifdef USE_UDP_NON_BLOCKING
-
-static ER_UINT		nblk_len;
-
-/*
- *  ノンブロッキングコールのコールバック関数
- */
-
-ER
-callback_nblk_udp_echo_cli (ID cepid, FN fncd, void *p_parblk)
-{
-	nblk_len = *(ER_UINT*)p_parblk;
-	syscall(wup_tsk(UDP_ECHO_CLI_TASK));
-	return E_OK;
-	}
-
-/*
- *  send_udp_echo -- ECHO/UDP サーバにメッセージを送信する (ノンブロッキングコール使用)。
- */
-
-static ER
-send_udp_echo (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno, char *line)
-{
-	ER_UINT	error;
-	uint_t	len;
-
-	dst.ipaddr = *ipaddr;
-	dst.portno = portno;
-	len         = strlen(line);
-	if ((error = UDP_SND_DAT(cepid, &dst, line, len, TMO_NBLK)) != E_WBLK) {
-		syslog(LOG_NOTICE, "[UEC:%02d SND] error: %s", cepid, itron_strerror(error));
-		return error;
-		}
-	else
-		syslog(LOG_NOTICE, "[UEC:%02d SND] sending:            to:   %s.%d: %s",
-		                   cepid, IP2STR(NULL, &dst.ipaddr), dst.portno, line);
-
-	syscall(slp_tsk());
-	if (nblk_len < 0) {	/* 0 以下の場合は、エラーコード */
-		syslog(LOG_NOTICE, "[UEC:%02d CBR] error: %s", cepid, itron_strerror(nblk_len));
-		return nblk_len;
-		}
-
-	if ((error = UDP_RCV_DAT(cepid, &dst, udp_buf, sizeof(udp_buf), TMO_NBLK)) != E_WBLK) {
-		syslog(LOG_NOTICE, "[UEC:%02d RCV] error: %s", cepid, itron_strerror(error));
-		return error;
-		}
-
-	syscall(slp_tsk());
-	if (nblk_len < 0) {	/* 0 以下の場合は、エラーコード */
-		syslog(LOG_NOTICE, "[UEC:%02d RCV] error: %s", cepid, itron_strerror(nblk_len));
-		return nblk_len;
-		}
-	else {
-		udp_buf[nblk_len] = '\0';
-		syslog(LOG_NOTICE, "[UEC:%02d RCV] received:           from: %s.%d: %s",
-		                   cepid, IP2STR(NULL, &dst.ipaddr), dst.portno, udp_buf);
-		nblk_len = E_OK;
-		}
-
-	return nblk_len;
-	}
-
-#else	/* of #ifdef USE_UDP_NON_BLOCKING */
-
-#ifdef USE_UDP_CALL_BACK
-
-/*
- *  コールバック関数
- */
-
-ER
-callback_udp_echo_cli (ID cepid, FN fncd, void *p_parblk)
-{
-	ER_UINT	len;
-
-	if ((len = UDP_RCV_DAT(cepid, &dst, udp_buf, sizeof(udp_buf), TMO_FEVR)) >= 0) {
-		*(udp_buf + len) = '\0';
-		syslog(LOG_NOTICE, "[UEC:%02d RCV] recv: addr: %s.%d: %s",
-		                   cepid, IP2STR(NULL, &dst.ipaddr), dst.portno, udp_buf);
-		}
-	else
-		syslog(LOG_NOTICE, "[UEC:%02d RCV] recv: error: %s", cepid, itron_strerror(len));
-
-	return E_OK;
-	}
-
-/*
- *  send_udp_echo -- ECHO/UDP サーバにメッセージを送信する (コールバック関数使用)。
- */
-
-static ER
-send_udp_echo (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno, char *line)
-{
-	ER_UINT	len;
-
-	dst.ipaddr = *ipaddr;
-	dst.portno = portno;
-	len        = strlen(line);
-	syslog(LOG_NOTICE, "[UEC:%02d SND] sending:            to:   %s.%d: %s",
-	                   cepid, IP2STR(NULL, &dst.ipaddr), dst.portno, line);
-	if ((len = UDP_SND_DAT(cepid, &dst, line, len, TMO_FEVR)) < 0)
-		syslog(LOG_NOTICE, "[UEC:%02d SND] error: %s", cepid, itron_strerror(len));
-
-	return E_OK;
-	}
-
-#else	/* of #ifdef USE_UDP_CALL_BACK */
-
-/*
- *  send_udp_echo -- ECHO/UDP サーバにメッセージを送信する (コールバック関数未使用)。
- */
-
-static ER
-send_udp_echo (ID cepid, T_IN_ADDR *ipaddr, uint16_t portno, char *line)
-{
-	ER_UINT	len;
-
-	dst.ipaddr = *ipaddr;
-	dst.portno = portno;
-	len         = strlen(line);
-	syslog(LOG_NOTICE, "[UEC:%02d SND] sending:            to:   %s.%d: %s",
-	                   cepid, IP2STR(NULL, &dst.ipaddr), dst.portno, line);
-	if ((len = UDP_SND_DAT(cepid, &dst, line, len, TMO_FEVR)) < 0) {
-		syslog(LOG_NOTICE, "[UEC:%02d SND] error: %s", cepid, itron_strerror(len));
-		return len;
-		}
-
-	if ((len = UDP_RCV_DAT(cepid, &dst, udp_buf, sizeof(udp_buf), 10*1000)) >= 0) {
-		*(udp_buf + len) = '\0';
-		syslog(LOG_NOTICE, "[UEC:%02d RCV] received:           from: %s.%d: %s",
-		                   cepid, IP2STR(NULL, &dst.ipaddr), dst.portno, line);
-		return E_OK;
-		}
-	else {
-		syslog(LOG_NOTICE, "[UEC:%02d RCV] error: %s", cepid, itron_strerror(len));
-		return len;
-		}
-	}
-
-#endif	/* of #ifdef USE_UDP_CALL_BACK */
-
-#endif	/* of #ifdef USE_UDP_NON_BLOCKING */
-
-#define MESSAGE_FORMAT	"MSG 1000000"
-
-/*
- *  UDP ECHO クライアント送信タスク
- */
-
-void
-udp_echo_cli_task (intptr_t exinf)
-{
-	static char msg[sizeof(MESSAGE_FORMAT)] = MESSAGE_FORMAT;
-
-	T_IN_ADDR	addr;
-	ID		tskid, cepid;
-	ER		error = E_OK;
-	char		*line, *p;
-	int_t		rep;
-	uint32_t	count, msgno;
-	uint16_t	portno;
-
-#ifdef USE_UDP_EXTENTIONS
-
-	T_UDP_CCEP	ccep;
-
-#endif	/* of #ifdef USE_UDP_EXTENTIONS */
-
-	get_tid(&tskid);
-	syslog(LOG_NOTICE, "[UDP ECHO CLI:%d,%d] started.", tskid, (ID)exinf);
-	while (true) {
-		if (rcv_dtq(DTQ_UDP_ECHO_CLI, (intptr_t*)&line) == E_OK) {
-
-#ifdef USE_UDP_EXTENTIONS
-
-			ccep.cepatr = UINT_C(0);
-			ccep.myaddr.portno = UDP_PORTANY;
-
-#if defined(SUPPORT_INET4)
-			ccep.myaddr.ipaddr = IPV4_ADDRANY;
-#endif
-
-#if defined(SUPPORT_INET6)
-			memcpy(&ccep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
-#endif
-
-#ifdef USE_UDP_NON_BLOCKING
-			ccep.callback = (FP)callback_nblk_udp_echo_cli;
-#else
-			ccep.callback = NULL;
-#endif
-
-			if ((error = alloc_udp_cep(&cepid, tskid, &ccep)) != E_OK) {
-				syslog(LOG_NOTICE, "[UEC:%02d TSK] CEP create error: %s", cepid, itron_strerror(error));
-				continue;
-				}
-
-#else	/* of #ifdef USE_UDP_EXTENTIONS */
-
-			cepid = (ID)exinf;
-
-#endif	/* of #ifdef USE_UDP_EXTENTIONS */
-
-			line = skip_blanks(GET_IPADDR(&addr, skip_blanks(line)));	/* IP Address */
-
-			if ('0' <= *line && *line <= '9') {				/* Port No */
-				line = get_int(&rep, line);
-				portno = (uint16_t)rep;
-				}
-			else {
-				line ++;
-				portno = ECHO_SRV_PORTNO;
-				}
-
-			line = skip_blanks(line);
-			if ('0' <= *line && *line <= '9') {				/* Repeat */
-				line = get_int(&rep, line);
-				if (rep > 1000000)
-					rep = 1000000;
-				udp_echo_cli_valid = true;
-				for (count = 0;  count ++ < rep; ) {
-					if (!udp_echo_cli_valid) {
-						syslog(LOG_NOTICE, "[UEC:%02d TSK] canceled.", cepid);
-						break;
-						}
-						
-					p = &msg[sizeof(MESSAGE_FORMAT)] - 1;
-					for (msgno = count; msgno > 0; msgno /= 10)
-						*(-- p) = msgno % 10 + '0';
-					while (*(p - 2) != 'G')
-						*(-- p) = ' ';
-
-					if ((error = send_udp_echo(cepid, &addr, portno, msg)) != E_OK)
-						break;
-
-					dly_tsk(10 * SYSTIM_HZ + net_rand() % (10 * SYSTIM_HZ));
-					}
-				}
-
-			else								/* Single Message */
-				error = send_udp_echo(cepid, &addr, portno, line);
-
-			if (error != E_OK)
-				syslog(LOG_NOTICE, "[UEC:%02d TSK] error: %s", cepid, itron_strerror(error));
-
-#ifdef USE_UDP_EXTENTIONS
-
-			if ((error = free_udp_cep(cepid, !(error == E_NOEXS || error == E_DLT))) != E_OK)
-				syslog(LOG_NOTICE, "[UEC:%02d TSK] CEP delete error: %s", cepid, itron_strerror(error));
-
-#endif	/* of #ifdef USE_UDP_EXTENTIONS */
-
-			}
-		}
-	}
-
-#endif	/* of #ifdef USE_UDP_ECHO_CLI */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp_echo_cli.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp_echo_cli.cfg	(revision 321)
+++ 	(revision )
@@ -1,70 +1,0 @@
-/*
- *  TINET (TCP/IP Protocol Stack)
- * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
- *                   Tomakomai National College of Technology, JAPAN
- *
- *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
- *  によって公表されている GNU General Public License の Version 2 に記
- *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
- *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
- *  利用と呼ぶ）することを無償で許諾する．
- *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
- *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
- *      スコード中に含まれていること．
- *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
- *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
- *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
- *      の無保証規定を掲載すること．
- *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
- *      用できない形で再配布する場合には，次の条件を満たすこと．
- *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
- *        作権表示，この利用条件および下記の無保証規定を掲載すること．
- *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
- *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
- *
- *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
- *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
- *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
- *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
- * 
- *  @(#) $Id$
- */
-
-/*
- *  ECHO サーバ試験プログラムのシステムコンフィギュレーションファイル
- */
-
-#ifdef USE_UDP_ECHO_CLI
-
-/* タスク */
-
-#ifdef USE_UDP_EXTENTIONS
-
-CRE_TSK(UDP_ECHO_CLI_TASK, {
-	TA_HLNG|TA_ACT,
-	0,
-	udp_echo_cli_task,
-	UDP_ECHO_CLI_MAIN_PRIORITY,
-	UDP_ECHO_CLI_STACK_SIZE,
-	NULL
-	});
-
-#else	/* of #ifdef USE_UDP_EXTENTIONS */
-
-CRE_TSK(UDP_ECHO_CLI_TASK, {
-	TA_HLNG|TA_ACT,
-	UDP_ECHO_CLI_CEPID,
-	udp_echo_cli_task,
-	UDP_ECHO_CLI_MAIN_PRIORITY,
-	UDP_ECHO_CLI_STACK_SIZE,
-	NULL
-	});
-
-#endif	/* of #ifdef USE_UDP_EXTENTIONS */
-
-/* コマンドキュー */
-
-CRE_DTQ(DTQ_UDP_ECHO_CLI,  { TA_TFIFO, 1, NULL });
-
-#endif	/* of #ifdef USE_UDP_ECHO_CLI */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp_echo_srv.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp_echo_srv.c	(revision 321)
+++ 	(revision )
@@ -1,310 +1,0 @@
-/*
- *  TINET (TCP/IP Protocol Stack)
- * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
- *                   Tomakomai National College of Technology, JAPAN
- *
- *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
- *  によって公表されている GNU General Public License の Version 2 に記
- *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
- *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
- *  利用と呼ぶ）することを無償で許諾する．
- *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
- *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
- *      スコード中に含まれていること．
- *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
- *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
- *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
- *      の無保証規定を掲載すること．
- *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
- *      用できない形で再配布する場合には，次の条件を満たすこと．
- *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
- *        作権表示，この利用条件および下記の無保証規定を掲載すること．
- *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
- *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
- *
- *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
- *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
- *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
- *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
- * 
- *  @(#) $Id$
- */
-
-/* 
- *  UDP ECHO サーバ
- */
-
-#include <string.h>
-
-#ifdef TARGET_KERNEL_ASP
-
-#include <kernel.h>
-#include <sil.h>
-#include <t_syslog.h>
-#include "kernel_cfg.h"
-
-#endif	/* of #ifdef TARGET_KERNEL_ASP */
-
-#ifdef TARGET_KERNEL_JSP
-
-#include <t_services.h>
-#include "kernel_id.h"
-#include "tinet_id.h"
-
-#endif	/* of #ifdef TARGET_KERNEL_JSP */
-
-#include <tinet_defs.h>
-#include <tinet_config.h>
-
-#include <net/net.h>
-#include <net/net_timer.h>
-
-#include <netinet/in.h>
-#include <netinet/in_itron.h>
-
-#include <netapp/netapp.h>
-#include <netapp/netapp_var.h>
-#include <netapp/echo.h>
-
-#ifdef USE_UDP_ECHO_SRV
-
-/*
- *  受信タイムアウト
- */
-
-#define RCV_TMOUT	TMO_FEVR
-//#define RCV_TMOUT	(30*ULONG_C(1000))
-
-#define BUF_SIZE	2048
-
-static char	echo_rcv_buf[BUF_SIZE];
-static T_IPEP	dst;
-
-#ifdef USE_UDP_CALL_BACK
-
-/*
- *  コールバック関数
- */
-
-ER
-callback_udp_echo_srv (ID cepid, FN fncd, void *p_parblk)
-{
-	ER_UINT	len;
-	SYSTIM	now;
-
-	if ((len = UDP_RCV_DAT(cepid, &dst, echo_rcv_buf, sizeof(echo_rcv_buf), TMO_FEVR)) >= 0) {
-		echo_rcv_buf[len] = '\0';
-		get_tim(&now);
-		syslog(LOG_NOTICE, "[UES:%02d UCB] received,   %6ld, from: %s.%d,\n"
-		                   "                                 msg: '%s'",
-		                   cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno, echo_rcv_buf);
-		if (len > 0) {
-			len = UDP_SND_DAT(cepid, &dst, echo_rcv_buf, len, TMO_FEVR);
-			get_tim(&now);
-			if (len >= 0)
-				syslog(LOG_NOTICE, "[UES:%02d UCB] sent,       %6ld, len: %d",
-				                   cepid, now / SYSTIM_HZ, len);
-			else
-				syslog(LOG_NOTICE, "[UES:%02d UCB] send error, %6ld: %s",
-				                   cepid, now / SYSTIM_HZ, itron_strerror(len));
-			}
-		len = E_OK;
-		}
-	else {
-		get_tim(&now);
-		syslog(LOG_NOTICE, "[UES:%02d UCB] recv error, %6ld: %s",
-		                   cepid, now / SYSTIM_HZ, itron_strerror(len));
-		}
-
-	return len;
-	}
-
-#else	/* of #ifdef USE_UDP_CALL_BACK */
-
-#ifdef USE_UDP_NON_BLOCKING
-
-/*
- *  変数
- */
-
-static ER_UINT		nblk_len;
-
-/*
- *  ノンブロッキングコールのコールバック関数
- */
-
-ER
-callback_nblk_udp_echo_srv (ID cepid, FN fncd, void *p_parblk)
-{
-	SYSTIM	now;
-
-	get_tim(&now);
-	nblk_len = *(ER_UINT*)p_parblk;
-	if (nblk_len < 0) {	/* 0 以下の場合は、エラーコード */
-		syslog(LOG_NOTICE, "[UES:%02d CBR] error,      %6ld: %s, fncd: %s",
-		                   cepid, now / SYSTIM_HZ, itron_strerror(nblk_len), in_strtfn(fncd));
-		}
-	else if (fncd == TFN_UDP_RCV_DAT) {
-		echo_rcv_buf[nblk_len] = '\0';
-		syslog(LOG_NOTICE, "[UES:%02d CBR] received,   %6ld, from: %s.%d,\n"
-		                   "                                 msg: '%s'",
-		                   cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno, echo_rcv_buf);
-		}
-	syscall(wup_tsk(UDP_ECHO_SRV_TASK));
-	return E_OK;
-	}
-
-/*
- *  UDP ECHO サーバ
- */
-
-ER
-udp_echo_srv (ID cepid)
-{
-	ER	error;
-	SYSTIM	now;
-
-	if ((error = UDP_RCV_DAT(cepid, &dst, echo_rcv_buf, sizeof(echo_rcv_buf), TMO_NBLK)) != E_WBLK) {
-		get_tim(&now);
-		syslog(LOG_NOTICE, "[UES:%02d RCV] recv error, %6ld: %s", cepid, now / SYSTIM_HZ, itron_strerror(error));
-		return error;
-		}
-
-	syscall(slp_tsk());
-	if (nblk_len < 0)
-		error = nblk_len;
-	else {
-		if ((error = UDP_SND_DAT(cepid, &dst, echo_rcv_buf, nblk_len, TMO_NBLK)) != E_WBLK) {
-			get_tim(&now);
-			syslog(LOG_NOTICE, "[UES:%02d SND] send error, %6ld: %s",
-			                   cepid, now / SYSTIM_HZ, itron_strerror(error));
-			return error;
-			}
-
-		syscall(slp_tsk());
-		if (nblk_len < 0)
-			error = nblk_len;
-		else {
-			get_tim(&now);
-			syslog(LOG_NOTICE, "[UES:%02d SND] sent,       %6ld, len: %d", cepid, now / SYSTIM_HZ, nblk_len);
-			error = E_OK;
-			}
-		}
-
-	return error;
-	}
-
-#else	/* of #ifdef USE_UDP_NON_BLOCKING */
-
-/*
- *  UDP ECHO サーバ
- */
-
-ER
-udp_echo_srv (ID cepid)
-{
-	ER_UINT	len;
-	SYSTIM	now;
-
-	if ((len = UDP_RCV_DAT(cepid, &dst, echo_rcv_buf, sizeof(echo_rcv_buf), RCV_TMOUT)) >= 0) {
-		get_tim(&now);
-		echo_rcv_buf[len] = '\0';
-		syslog(LOG_NOTICE, "[UES:%02d RCV] received,   %6ld, from: %s.%d,\n"
-		                   "                                 msg: '%s'",
-		                   cepid, now / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno, echo_rcv_buf);
-		if (len > 0) {
-			len = UDP_SND_DAT(cepid, &dst, echo_rcv_buf, len, TMO_FEVR);
-			get_tim(&now);
-			if (len >= 0)
-				syslog(LOG_NOTICE, "[UES:%02d SND] sent,       %6ld, len: %d",
-				                   cepid, now / SYSTIM_HZ, (uint16_t)len);
-			else
-				syslog(LOG_NOTICE, "[UES:%02d SND] send error, %6ld: %s",
-				                   cepid, now / SYSTIM_HZ, itron_strerror(len));
-			}
-		}
-	else {
-		get_tim(&now);
-		syslog(LOG_NOTICE, "[UES:%02d RCV] recv error, %6ld: %s", cepid, now / SYSTIM_HZ, itron_strerror(len));
-		}
-
-	return len >= 0 || len == E_TMOUT ? E_OK : len;
-	}
-
-#endif	/* of #ifdef USE_UDP_NON_BLOCKING */
-
-/*
- *  UDP ECHO サーバタスク
- */
-
-#ifdef USE_UDP_EXTENTIONS
-
-void
-udp_echo_srv_task (intptr_t exinf)
-{
-	ID		tskid, cepid;
-	ER		error;
-	T_UDP_CCEP	ccep;
-
-	get_tid(&tskid);
-	syslog(LOG_NOTICE, "[UDP ECHO SRV:%d,%d] started.", tskid, (ID)exinf);
-	while (true) {
-
-		syscall(slp_tsk());
-
-		ccep.cepatr = UINT_C(0);
-		ccep.myaddr.portno = UINT_C(7);
-
-#if defined(SUPPORT_INET4)
-		ccep.myaddr.ipaddr = IPV4_ADDRANY;
-#endif
-
-#if defined(SUPPORT_INET6)
-		memcpy(&ccep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
-#endif
-
-#ifdef USE_UDP_NON_BLOCKING
-		ccep.callback = (FP)callback_nblk_udp_echo_srv;
-#else
-		ccep.callback = NULL;
-#endif
-
-		if ((error = alloc_udp_cep(&cepid, tskid, &ccep)) != E_OK) {
-			syslog(LOG_NOTICE, "[UES:%02d TSK] CEP create error: %s", cepid, itron_strerror(error));
-			continue;
-			}
-
-		while (error == E_OK) {
-			if ((error = udp_echo_srv(cepid)) != E_OK) {
-				if ((error = free_udp_cep(cepid, !(error == E_NOEXS || error == E_DLT))) != E_OK)
-					syslog(LOG_NOTICE, "[UEC:%02d TSK] CEP delete error: %s", cepid, itron_strerror(error));
-				break;
-				}
-			}
-
-		}
-	slp_tsk();
-	}
-
-#else	/* of #ifdef USE_UDP_EXTENTIONS */
-
-void
-udp_echo_srv_task (intptr_t exinf)
-{
-	ID	tskid;
-	ER	error = E_OK;
-
-	get_tid(&tskid);
-	syslog(LOG_NOTICE, "[UDP ECHO SRV:%d,%d] started.", tskid, (ID)exinf);
-	while (error == E_OK) {
-		error = udp_echo_srv((ID)exinf);
-		}
-	slp_tsk();
-	}
-
-#endif	/* of #ifdef USE_UDP_EXTENTIONS */
-
-#endif	/* of #ifdef USE_UDP_CALL_BACK */
-
-#endif	/* of #ifdef USE_UDP_ECHO_SRV */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp_echo_srv.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/udp_echo_srv.cfg	(revision 321)
+++ 	(revision )
@@ -1,74 +1,0 @@
-/*
- *  TINET (TCP/IP Protocol Stack)
- * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
- *                   Tomakomai National College of Technology, JAPAN
- *
- *  上記著作権者は，以下の (1)～(4) の条件か，Free Software Foundation 
- *  によって公表されている GNU General Public License の Version 2 に記
- *  述されている条件を満たす場合に限り，本ソフトウェア（本ソフトウェア
- *  を改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，
- *  利用と呼ぶ）することを無償で許諾する．
- *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
- *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
- *      スコード中に含まれていること．
- *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
- *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
- *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
- *      の無保証規定を掲載すること．
- *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
- *      用できない形で再配布する場合には，次の条件を満たすこと．
- *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
- *        作権表示，この利用条件および下記の無保証規定を掲載すること．
- *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
- *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
- *
- *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
- *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，その適用可能性も
- *  含めて，いかなる保証も行わない．また，本ソフトウェアの利用により直
- *  接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
- * 
- *  @(#) $Id$
- */
-
-/*
- *  UDP ECHO サーバコンフィギュレーションファイル
- */
-
-#ifdef USE_UDP_ECHO_SRV
-
-/*
- * タスク
- */
-
-#ifdef USE_UDP_CALL_BACK
-
-#else	/* of #ifdef USE_UDP_CALL_BACK */
-
-#ifdef USE_UDP_EXTENTIONS
-
-CRE_TSK(UDP_ECHO_SRV_TASK, {
-	TA_HLNG | TA_ACT,
-	0,
-	udp_echo_srv_task,
-	UDP_ECHO_SRV_MAIN_PRIORITY,
-	UDP_ECHO_SRV_STACK_SIZE,
-	NULL
-	});
-
-#else	/* of #ifdef USE_UDP_EXTENTIONS */
-
-CRE_TSK(UDP_ECHO_SRV_TASK, {
-	TA_HLNG | TA_ACT,
-	UDP_ECHO_SRV_CEPID,
-	udp_echo_srv_task,
-	UDP_ECHO_SRV_MAIN_PRIORITY,
-	UDP_ECHO_SRV_STACK_SIZE,
-	NULL
-	});
-
-#endif	/* of #ifdef USE_UDP_EXTENTIONS */
-
-#endif	/* of #ifdef USE_UDP_CALL_BACK */
-
-#endif	/* of #ifdef USE_UDP_ECHO_SRV */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/wwws.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/wwws.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/wwws.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -75,14 +75,12 @@
 #include <net/ethernet.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
-#include <net/net_timer.h>
 #include <net/net_count.h>
 
 #include <netinet/in.h>
 #include <netinet/in_itron.h>
-#include <netinet/ip.h>
-#include <netinet/ip6.h>
-#include <netinet/tcp.h>
-
+
+#include <netapp/netapp.h>
 #include <netapp/netapp_var.h>
 #include <netapp/wwws.h>
@@ -118,4 +116,30 @@
 #endif	/* of #if NET_COUNT_ENABLE */
 
+#ifdef USE_TCP_EXTENTIONS
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV)
+
+#if NUM_WWW_SRV_TASKS >= 2		/* 2 を超える個数は想定していない。	*/
+
+#define WWW4_SRV_TASK	WWW_SRV_TASK1
+#define WWW6_SRV_TASK	WWW_SRV_TASK2
+
+#else	/* of #if NUM_WWW_SRV_TASKS >= 2 */
+
+#define WWW4_SRV_TASK	WWW_SRV_TASK1
+#define WWW6_SRV_TASK	WWW_SRV_TASK1
+
+#endif	/* of #if NUM_WWW_SRV_TASKS >= 2 */
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+#define WWW4_SRV_TASK	WWW_SRV_TASK1
+#define WWW6_SRV_TASK	WWW_SRV_TASK1
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+
 /*
  *  全域変数
@@ -161,4 +185,48 @@
 #define ST_NOT_FOUND	1
 
+/*
+ *  接続相手の情報構造体
+ */
+
+#ifdef  NUM_WWW4_SRV_TASKS
+#undef  NUM_WWW4_SRV_TASKS
+#endif
+#define NUM_WWW4_SRV_TASKS		1
+
+typedef struct t_www_srv_info {
+	ID	cepid;		/* 通信端点 ID		*/
+	ID	repid;		/* 受付口   ID		*/
+	T_IPEP	dst;		/* 接続相手アドレス情報	*/
+	} T_WWW_SRV_INFO;
+
+#define INDEX_SRV_INFO(id)	((id)-1)
+
+#ifdef USE_TCP_EXTENTIONS
+
+static T_WWW_SRV_INFO www_srv_info[NUM_WWW_SRV_TASKS];
+					/* 2 を超える個数は想定していない。	*/
+
+#else	/* of #ifdef USE_TCP_EXTENTIONS */
+
+static T_WWW_SRV_INFO www_srv_info[] = {
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV)
+
+	{ WWW4_SRV_CEPID1, WWW4_SRV_REPID },
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+	{ WWW_SRV_CEPID1, WWW_SRV_REPID },
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+#if NUM_WWW_SRV_TASKS >= 2		/* 2 を超える個数は想定していない。	*/
+	{ WWW_SRV_CEPID2, WWW_SRV_REPID },
+#endif
+
+	};
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
 #ifdef USE_COPYSAVE_API
 
@@ -180,10 +248,10 @@
 		if (srbuf->rbuf.index >= srbuf->rbuf.len) {
 			if ((error = tcp_rel_buf(cepid, srbuf->rbuf.len)) != E_OK)
-				syslog(LOG_WARNING, "[WWW:%02d] tcp_rel_buf error: %s",
+				syslog(LOG_WARNING, "[WWWn:%02u REL] tcp_rel_buf error: %s",
 				       cepid, itron_strerror(error));
 			srbuf->rbuf.index = 0;
 			if ((len = tcp_rcv_buf(cepid, (void**)&srbuf->rbuf.buf, TMO_FEVR)) <= 0) {
 				if (len < 0)
-					syslog(LOG_WARNING, "[WWW:%02d] tcp_rcv_buf error: %s",
+					syslog(LOG_WARNING, "[WWWn:%02u RCV] tcp_rcv_buf error: %s",
 					       cepid, itron_strerror(len));
 				srbuf->rbuf.len = 0;
@@ -228,5 +296,5 @@
 		if (srbuf->sbuf.index >= srbuf->sbuf.len)
 			if ((error = flush_sbuf(cepid, srbuf)) != E_OK) {
-				syslog(LOG_WARNING, "[WWW:%02d] tcp_snd_dat error: %s", cepid, itron_strerror(error));
+				syslog(LOG_WARNING, "[WWWn:%02u SND] error: %s", cepid, itron_strerror(error));
 			return 0;
 			}
@@ -234,5 +302,5 @@
 		if (srbuf->sbuf.len == 0) {
 			if ((blen = tcp_get_buf(cepid, (void**)&srbuf->sbuf.buf, TMO_FEVR)) < 0) {
-				syslog(LOG_WARNING, "[WWW:%02d] tcp_get_buf error: %s", cepid, itron_strerror(srbuf->sbuf.len));
+				syslog(LOG_WARNING, "[WWWn:%02u GET] error: %s", cepid, itron_strerror(srbuf->sbuf.len));
 				return 0;
 				}
@@ -272,5 +340,5 @@
 			if ((len = tcp_rcv_dat(cepid, srbuf->rbuf.buf, sizeof(srbuf->rbuf.buf), TMO_FEVR)) <= 0) {
 				if (len < 0) {
-					syslog(LOG_WARNING, "[WWW:%02d] tcp_rcv_dat error: %s",
+					syslog(LOG_WARNING, "[WWWn:%02u RCV] error: %s",
 					       cepid, itron_strerror(len));
 					}
@@ -321,5 +389,5 @@
 		if (srbuf->sbuf.index >= srbuf->sbuf.len)
 			if ((error = flush_sbuf(cepid, srbuf)) != E_OK) {
-				syslog(LOG_WARNING, "[WWW:%02d] tcp_snd_dat error: %s", cepid, itron_strerror(error));
+				syslog(LOG_WARNING, "[WWWn:%02u SND] error: %s", cepid, itron_strerror(error));
 			return 0;
 			}
@@ -476,8 +544,10 @@
 	int_t	ix;
 
-	for (ix = NUM_FILES; ix -- > 0; )
+	for (ix = NUM_FILES; ix -- > 0; ) {
 		if (!strcmp(file[ix].uri, &line->buf[line->off[1]])) {
+			//syslog(LOG_NOTICE, "[WWWn:%02u PTH] '%s'", cepid, &line->buf[line->off[1]]);
 			return (*file[ix].func)(cepid, srbuf);
 			}
+		}
 	put_status(cepid, srbuf, ST_NOT_FOUND);
 	return E_NOEXS;
@@ -494,15 +564,14 @@
 	ER		error = E_OK;
 	int_t		blen = 0;
-	uint16_t	len;
 
 	if ((error = tget_mpf(MPF_WWW_LINE, (void*)&method, TMO_FEVR)) != E_OK) {
-		syslog(LOG_CRIT, "[WWW:%02d] get line error: %s.",
+		syslog(LOG_CRIT, "[WWWn:%02u MPF] get line error: %s.",
 		       cepid, itron_strerror(error));
 		return error;
 		}
 
-	if ((len = get_line(cepid, method, srbuf)) == 0) {
+	if (get_line(cepid, method, srbuf) == 0) {
 		if ((error = rel_mpf(MPF_WWW_LINE, method)) != E_OK)
-			syslog(LOG_WARNING, "[WWW:%02d] release line buffer error: %s.",
+			syslog(LOG_WARNING, "[WWWn:%02u MPF] release line buffer error: %s.",
 			       cepid, itron_strerror(error));
 		return error;
@@ -510,18 +579,18 @@
 
 	if ((error = tget_mpf(MPF_WWW_LINE, (void*)&line, TMO_FEVR)) != E_OK) {
-		syslog(LOG_CRIT, "[WWW:%02d] get line buffer error: %s.",
+		syslog(LOG_CRIT, "[WWWn:%02u MPF] get line buffer error: %s.",
 		       cepid, itron_strerror(error));
 		if ((error = rel_mpf(MPF_WWW_LINE, method)) != E_OK)
-			syslog(LOG_WARNING, "[WWW:%02d] release line buffer error: %s.",
+			syslog(LOG_WARNING, "[WWWn:%02u MPF] release line buffer error: %s.",
 			       cepid, itron_strerror(error));
 		return error;
 		}
 
-	while ((len = get_line(cepid, line, srbuf)) > 0) {	/* ヘッダをスキップする。*/
+	while (get_line(cepid, line, srbuf) > 0) {	/* ヘッダをスキップする。*/
 		split_fields(line, ": ");
 		if (strcmp("Content-Length", &line->buf[line->off[0]]) == 0)
 			blen = atoi(&line->buf[line->off[1]]);
 		}
-	while (blen > 0 && (len = get_line(cepid, line, srbuf)) > 0) {
+	while (blen > 0 && get_line(cepid, line, srbuf) > 0) {
 		/* エンティティ・ボディをスキップする。*/
 		blen -= line->len;
@@ -529,5 +598,5 @@
 
 	if ((error = rel_mpf(MPF_WWW_LINE, line)) != E_OK)
-		syslog(LOG_WARNING, "[WWW:%02d] release line buffer error: %s.",
+		syslog(LOG_WARNING, "[WWWn:%02u MPF] release line buffer error: %s.",
 		       cepid, itron_strerror(error));
 	
@@ -539,5 +608,5 @@
 
 	if ((error = rel_mpf(MPF_WWW_LINE, method)) != E_OK)
-		syslog(LOG_WARNING, "[WWW:%02d] release line buffer error: %s.",
+		syslog(LOG_WARNING, "[WWWn:%02u MPF] release line buffer error: %s.",
 		       cepid, itron_strerror(error));
 
@@ -567,13 +636,23 @@
 
 #ifdef TARGET_KERNEL_ASP
-		"ASP Kernel Release 1.3 (patchlevel = 2) for " TARGET_NAME " (" __DATE__ "," __TIME__ ") と<br>\r\n"
+		"ASP Kernel for " TARGET_NAME " (" __DATE__ "," __TIME__ ") と<br>\r\n"
 #endif
 
 #ifdef TARGET_KERNEL_JSP
-		"JSP Kernel Release 1.4 (patchlevel = 3) for " TARGET_NAME " (" __DATE__ "," __TIME__ ") と<br>\r\n"
+		"JSP Kernel for " TARGET_NAME " (" __DATE__ "," __TIME__ ") と<br>\r\n"
 #endif
 
 		"TINET TCP/IP プロトコルスタックによりサービスしています。<br><hr>\r\n"
+
+#if NET_COUNT_ENABLE
+
 		"<ul><li type=\"square\"><a href=\"stat.html\">ネットワーク統計情報</a></ul><hr>\r\n"
+
+#else	/* of #if NET_COUNT_ENABLE */
+
+		"<ul><li type=\"square\">ネットワーク統計情報</ul><hr>\r\n"
+
+#endif	/* of #if NET_COUNT_ENABLE */
+
 		"FreeBSD: Copyright (c) 1982, 1986, 1988, 1990, 1993, 1994, 1995<br>\r\n"
 		"The Regents of the University of California.  All rights reserved.<br><br>\r\n"
@@ -629,5 +708,5 @@
 	len += put_str(cepid, srbuf, response);
 	get_tim(&finish);
-	syslog(LOG_NOTICE, "[WWW:%02u]     send:               index.html, len: %4u, time: %lu [ms]",
+	syslog(LOG_NOTICE, "[WWWn:%02u SND] send: index.html, len: %4u, time: %lu [ms]",
 	                   cepid, len, (finish - start) * 1000 / SYSTIM_HZ);
 	return E_OK;
@@ -1530,5 +1609,5 @@
 
 	get_tim(&finish);
-	syslog(LOG_NOTICE, "[WWW:%02u]     send:               stat.html,  len: %4u, time: %lu [ms]",
+	syslog(LOG_NOTICE, "[WWWn:%02u SND]send: stat.html,  len: %4u, time: %lu [ms]",
 	                   cepid, len, (finish - start) * 1000 / SYSTIM_HZ);
 	return E_OK;
@@ -1537,78 +1616,4 @@
 #endif	/* of #if NET_COUNT_ENABLE */
 
-/*
- *  WWW サーバ
- */
-
-static ER
-www_srv (ID cepid, ID repid)
-{
-#if defined(SUPPORT_INET4)
-
-	T_IPV4EP	dst;
-
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
-
-	T_IPV6EP	dst;
-
-#endif	/* of #if defined(SUPPORT_INET6) */
-
-	T_WWW_RWBUF	*srbuf;
-	ER		error;
-	SYSTIM		time;
-
-	if ((error = TCP_ACP_CEP(cepid, repid, &dst, TMO_FEVR)) != E_OK) {
-		syslog(LOG_WARNING, "[WWW:%02d] accept error: %s", cepid, itron_strerror(error));
-		return error;
-		}
-
-	get_tim(&time);
-	syslog(LOG_NOTICE, "[WWW:%02u]     connected:  %6lu, from: %s.%u",
-	                   cepid, time / SYSTIM_HZ, IP2STR(NULL, &dst.ipaddr), dst.portno);
-
-	if ((error = tget_mpf(MPF_WWW_RWBUF, (void*)&srbuf, TMO_FEVR)) != E_OK) {
-		syslog(LOG_CRIT, "[WWW:%02d] get buffer error: %s.", cepid, itron_strerror(error));
-		srbuf = NULL;
-		}
-	else {
-		srbuf->rbuf.len = srbuf->rbuf.index = srbuf->sbuf.index = srbuf->unget = 0;
-
-#ifdef USE_COPYSAVE_API
-
-		srbuf->sbuf.len = 0;
-
-#else	/* of #ifdef USE_COPYSAVE_API */
-
-		srbuf->sbuf.len = sizeof(srbuf->sbuf.buf);
-
-#endif	/* of #ifdef USE_COPYSAVE_API */
-
-		if ((error = parse_request(cepid, srbuf)) != E_OK)
-			syslog(LOG_WARNING, "[WWW:%02d] parse request error: %s",
-			       cepid, itron_strerror(error));
-		}
-
-	if ((error = tcp_sht_cep(cepid)) != E_OK)
-		syslog(LOG_WARNING, "[WWW:%02d] shutdown error: %s", cepid, itron_strerror(error));
-
-	if (srbuf != NULL) {
-		while (get_char(cepid, srbuf) != EOF)
-			;
-		if (srbuf != NULL && (error = rel_mpf(MPF_WWW_RWBUF, srbuf)) != E_OK)
-			syslog(LOG_WARNING, "[WWW:%02d] release buffer error: %s.",
-			       cepid, itron_strerror(error));
-		}
-
-	if ((error = tcp_cls_cep(cepid, TMO_FEVR)) != E_OK)
-		syslog(LOG_WARNING, "[WWW:%02d] close error: %s", cepid, itron_strerror(error));
-
-	get_tim(&time);
-	syslog(LOG_NOTICE, "[WWW:%02u]     finished:   %6lu", cepid, time / SYSTIM_HZ);
-
-	return error;
-	}
-
 #ifdef USE_TCP_EXTENTIONS
 
@@ -1616,4 +1621,6 @@
  *  get_tcp_rep -- TCP 受付口を獲得する。
  */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
 
 static ER
@@ -1621,5 +1628,29 @@
 {
 	ID		tskid;
-	T_TCP_CREP	crep;
+	T_TCP6_CREP	crep6;
+	T_TCP_CREP	crep4;
+
+	get_tid(&tskid);
+	if (tskid == WWW4_SRV_TASK) {
+		crep4.repatr = UINT_C(0);
+		crep4.myaddr.portno = UINT_C(80);
+		crep4.myaddr.ipaddr = IPV4_ADDRANY;
+		return alloc_tcp4_rep(repid, tskid, &crep4);
+		}
+	else {
+		crep6.repatr = UINT_C(0);
+		crep6.myaddr.portno = UINT_C(80);
+		memcpy(&crep6.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
+		return alloc_tcp6_rep(repid, tskid, &crep6);
+		}
+	}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+static ER
+get_tcp_rep (ID *repid)
+{
+	ID		tskid;
+	T_TCPN_CREP	crep;
 
 	get_tid(&tskid);
@@ -1627,4 +1658,10 @@
 	crep.repatr = UINT_C(0);
 	crep.myaddr.portno = UINT_C(80);
+
+#if defined(SUPPORT_INET6)
+
+	memcpy(&crep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
+
+#else	/* #if defined(SUPPORT_INET6) */
 
 #if defined(SUPPORT_INET4)
@@ -1632,14 +1669,13 @@
 #endif
 
-#if defined(SUPPORT_INET6)
-	memcpy(&crep.myaddr.ipaddr, &ipv6_addrany, sizeof(T_IN6_ADDR));
-#endif
-
-
-	return alloc_tcp_rep(repid, tskid, &crep);
-	}
-
-/*
- *  get_tcp_cep -- TCP 通信端点とを獲得する。
+#endif	/* #if defined(SUPPORT_INET6) */
+
+	return ALLOC_TCP_REP(repid, tskid, &crep);
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+/*
+ *  get_tcp_cep -- TCP 通信端点を獲得する。
  */
 
@@ -1668,6 +1704,167 @@
 #endif
 
-	return alloc_tcp_cep(cepid, tskid, &ccep);
-	}
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+	if (tskid == WWW4_SRV_TASK)
+		return alloc_tcp4_cep(cepid, tskid, &ccep);
+	else
+		return alloc_tcp6_cep(cepid, tskid, &ccep);
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	return ALLOC_TCP_CEP(cepid, tskid, &ccep);
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	}
+
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+/*
+ *  tcp_passive_open -- 受動オープンを実行する。
+ *
+ *    USE_TCP_NON_BLOCKING	OFF
+ */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+static ER
+tcp_passive_open (T_WWW_SRV_INFO *info, char apip)
+{
+	ER		error = E_OK;
+	T_IPV4EP	dst4;
+
+	if (apip == API_PROTO_IPV6) {
+		/* 受付口は IPv6 */
+		if ((error = tcp6_acp_cep(info->cepid, info->repid, &info->dst, TMO_FEVR)) != E_OK)
+			return error;
+
+#ifdef USE_TCP_EXTENTIONS
+		if ((error = free_tcp6_rep(info->repid, true)) != E_OK)
+			return error;
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+		}
+	else {
+		/* 受付口は IPv4 */
+		if ((error = tcp_acp_cep(info->cepid, info->repid, &dst4, TMO_FEVR)) != E_OK)
+			return error;
+		in6_make_ipv4mapped (&info->dst.ipaddr, dst4.ipaddr);
+		info->dst.portno = dst4.portno;
+
+#ifdef USE_TCP_EXTENTIONS
+		if ((error = free_tcp4_rep(info->repid, true)) != E_OK)
+			return error;
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+		}
+
+	return error;
+	}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+static ER
+tcp_passive_open (T_WWW_SRV_INFO *info, char apip)
+{
+	ER		error = E_OK;
+
+	if ((error = TCP_ACP_CEP(info->cepid, info->repid, &info->dst, TMO_FEVR)) != E_OK)
+		return error;
+
+#ifdef USE_TCP_EXTENTIONS
+	if ((error = FREE_TCP_REP(info->repid, true)) != E_OK)
+		return error;
+#endif	/* of #ifdef USE_TCP_EXTENTIONS */
+
+	return error;
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+/*
+ *  WWW サーバ
+ */
+
+static ER
+www_srv (uint_t six, char apip)
+{
+	T_WWW_RWBUF	*srbuf;
+	ER		error;
+	SYSTIM		now;
+
+	if ((error = tcp_passive_open(&www_srv_info[six], apip)) != E_OK)
+		return error;
+
+	syscall(get_tim(&now));
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV)
+
+	if (apip == API_PROTO_IPV6)
+		syslog(LOG_NOTICE, "[WWW6:%02u ACP] conct:  %6lu,from: %s.%u",
+		                   www_srv_info[six].cepid, now / SYSTIM_HZ,
+		                   ipv62str(NULL, &www_srv_info[six].dst.ipaddr),
+		                   www_srv_info[six].dst.portno);
+	else
+		syslog(LOG_NOTICE, "[WWW4:%02u ACP] conct:  %6lu,from: %s.%u",
+		                   www_srv_info[six].cepid, now / SYSTIM_HZ,
+		                   ip2str(NULL, &www_srv_info[six].dst.ipaddr.s6_addr32[3]),
+		                   www_srv_info[six].dst.portno);
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+	syslog(LOG_NOTICE, "[WWWn:%02u ACP] conct:  %6lu,from: %s.%u",
+	                   www_srv_info[six].cepid, now / SYSTIM_HZ,
+	                   IP2STR(NULL, &www_srv_info[six].dst.ipaddr),
+	                   www_srv_info[six].dst.portno);
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+	if ((error = tget_mpf(MPF_WWW_RWBUF, (void*)&srbuf, TMO_FEVR)) != E_OK) {
+		syslog(LOG_CRIT, "[WWWn:%02u MPF] get buffer error: %s.",
+		                 www_srv_info[six].cepid, itron_strerror(error));
+		srbuf = NULL;
+		}
+	else {
+		srbuf->rbuf.len = srbuf->rbuf.index = srbuf->sbuf.index = srbuf->unget = 0;
+
+#ifdef USE_COPYSAVE_API
+
+		srbuf->sbuf.len = 0;
+
+#else	/* of #ifdef USE_COPYSAVE_API */
+
+		srbuf->sbuf.len = sizeof(srbuf->sbuf.buf);
+
+#endif	/* of #ifdef USE_COPYSAVE_API */
+
+		if ((error = parse_request(www_srv_info[six].cepid, srbuf)) != E_OK)
+			syslog(LOG_WARNING, "[WWWn:%02u RCV] parse request error: %s",
+			                    www_srv_info[six].cepid, itron_strerror(error));
+		}
+
+	if ((error = tcp_sht_cep(www_srv_info[six].cepid)) != E_OK)
+		syslog(LOG_WARNING, "[WWWn:%02u SHD] shutdown error: %s", 
+		                    www_srv_info[six].cepid, itron_strerror(error));
+
+	if (srbuf != NULL) {
+		while (get_char(www_srv_info[six].cepid, srbuf) != EOF)
+			;
+		if (srbuf != NULL && (error = rel_mpf(MPF_WWW_RWBUF, srbuf)) != E_OK)
+			syslog(LOG_WARNING, "[WWWn:%02u REL] release buffer error: %s.",
+			                    www_srv_info[six].cepid, itron_strerror(error));
+		}
+
+	if ((error = tcp_cls_cep(www_srv_info[six].cepid, TMO_FEVR)) != E_OK)
+		syslog(LOG_WARNING, "[WWWn:%02u CLS] close error: %s",
+ 		                    www_srv_info[six].cepid, itron_strerror(error));
+
+	get_tim(&now);
+	syslog(LOG_NOTICE, "[WWWn:%02u FIN] finsh:  %6lu",
+	                   www_srv_info[six].cepid, now / SYSTIM_HZ);
+
+	return error;
+	}
+
+#ifdef USE_TCP_EXTENTIONS
 
 /*
@@ -1678,33 +1875,106 @@
 www_srv_task(intptr_t exinf)
 {
-	ID	tskid, cepid, repid;
+	ID	tskid;
 	ER	error = E_OK;
+	uint_t	six;
+	char	apip;
 
 	syscall(get_tid(&tskid));
-	syslog(LOG_NOTICE, "[WWW:%d] started.", tskid);
+	six = INDEX_SRV_INFO((ID)exinf);
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV)
+
+	if (six >= NUM_WWW4_SRV_TASKS)
+		apip = API_PROTO_IPV6;
+	else
+		apip = API_PROTO_IPV4;
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+	apip = API_PROTO_IPVn;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+	syslog(LOG_NOTICE, "[WWW%c:%d] started.", apip, tskid);
 	while (true) {
 
 		syscall(slp_tsk());
-		if ((error = get_tcp_cep (&cepid)) != E_OK) {
-			syslog(LOG_NOTICE, "[WWW:00 EXT] CEP create error: %s", itron_strerror(error));
+		if ((error = get_tcp_cep(&www_srv_info[six].cepid)) != E_OK) {
+			syslog(LOG_NOTICE, "[WWW%c:%02u EXT] create CEP error: %s",
+				           apip, www_srv_info[six].cepid, itron_strerror(error));
 			continue;
 			}
 
-		if ((error = get_tcp_rep (&repid)) != E_OK) {
-			syslog(LOG_NOTICE, "[WWW:00 EXT] REP create error: %s", itron_strerror(error));
-			free_tcp_cep(cepid);
-			continue;
-			}
-
-		while (true)
-			if ((error = www_srv(cepid, repid)) != E_OK) {
-				error = free_tcp_rep(repid, error != E_DLT);
+		while (true) {
+
+			if ((error = get_tcp_rep(&www_srv_info[six].repid)) != E_OK) {
+				syslog(LOG_NOTICE, "[WWW%c:%02u EXT] create REP error: %02u, %s",
+				                   apip, www_srv_info[six].cepid, www_srv_info[six].repid, itron_strerror(error));
 				break;
 				}
-
-		if ((error = free_tcp_cep(cepid)) != E_OK)
-			syslog(LOG_NOTICE, "[WWW:%02d EXT] CEP delete error: %s", cepid, itron_strerror(error));
-
-		}
+			else if ((error = www_srv(six, apip)) != E_OK) {
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+				if (tskid == WWW4_SRV_TASK)
+					error = free_tcp4_rep(www_srv_info[six].repid, error != E_DLT);
+				else
+					error = free_tcp6_rep(www_srv_info[six].repid, error != E_DLT);
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+				error = FREE_TCP_REP(www_srv_info[six].repid, error != E_DLT);
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+				if (error != E_OK) {
+					syslog(LOG_NOTICE, "[WWW%c:%02u EXT] delete REP error: %02u, %s",
+				                           apip, www_srv_info[six].cepid,
+				                                              www_srv_info[six].repid, itron_strerror(error));
+
+					}
+				break;
+				}
+			}
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+		if (tskid == WWW4_SRV_TASK) {
+			if ((error = free_tcp4_cep(www_srv_info[six].cepid)) != E_OK)
+				syslog(LOG_NOTICE, "[WWW%c:%02u EXT] delete CEP error: %s",
+					           apip, www_srv_info[six].cepid, itron_strerror(error));
+			}
+		else {
+			if ((error = free_tcp6_cep(www_srv_info[six].cepid)) != E_OK)
+				syslog(LOG_NOTICE, "[WWW%c:%02u EXT] delete CEP error: %s",
+					           apip, www_srv_info[six].cepid, itron_strerror(error));
+			}
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+		if ((error = FREE_TCP_CEP(www_srv_info[six].cepid)) != E_OK)
+			syslog(LOG_NOTICE, "[WWW%c:%02u EXT] delete CEP error: %s",
+				           apip, www_srv_info[six].cepid, itron_strerror(error));
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+		}
+	}
+
+/*
+ *  wakeup_www_srv -- WWW サーバタスクの休止解除
+ */
+
+ER
+wakeup_www_srv (char apip)
+{
+	ID	taskid;
+
+	if (apip == API_PROTO_IPV6)
+		taskid = WWW6_SRV_TASK;
+	else
+		taskid = WWW4_SRV_TASK;
+	syslog(LOG_NOTICE, "[WWW%c(EXT):%d] wake up.", apip, taskid);
+	return wup_tsk(taskid);
 	}
 
@@ -1718,11 +1988,30 @@
 www_srv_task(intptr_t exinf)
 {
-	ID	tskid;
+	ID	tskid, cepid;
+	uint_t	six;
+	char	apip;
 
 	get_tim(&srv_start);
 	get_tid(&tskid);
-	syslog(LOG_NOTICE, "[WWW:%d,%d] started.", tskid, (int_t)exinf);
+	six = INDEX_SRV_INFO((ID)exinf);
+	cepid = www_srv_info[INDEX_SRV_INFO((ID)exinf)].cepid;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV)
+
+	if (six >= NUM_WWW4_SRV_TASKS)
+		apip = API_PROTO_IPV6;
+	else
+		apip = API_PROTO_IPV4;
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+	apip = API_PROTO_IPVn;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && defined(USE_WWW4_SRV) */
+
+	syslog(LOG_NOTICE, "[WWW%c SRV:%d,%d] started.", apip, tskid, cepid);
+
 	while (true) {
-		while (www_srv((int_t)exinf, WWW_SRV_REPID) == E_OK)
+		while (www_srv(six, apip) == E_OK)
 			;
 		}
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/wwws.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/wwws.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/wwws.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -40,9 +40,7 @@
 /* タスク */
 
-#ifdef USE_TCP_EXTENTIONS
-
 CRE_TSK(WWW_SRV_TASK1,  {
 	TA_HLNG | TA_ACT,
-	0,
+	1,
 	www_srv_task,
 	WWW_SRV_MAIN_PRIORITY,
@@ -51,22 +49,9 @@
 	});
 
-#else	/* of #ifdef USE_TCP_EXTENTIONS */
-
-CRE_TSK(WWW_SRV_TASK1,  {
-	TA_HLNG | TA_ACT,
-	WWW_SRV_CEPID1,
-	www_srv_task,
-	WWW_SRV_MAIN_PRIORITY,
-	WWW_SRV_STACK_SIZE,
-	NULL
-	});
-
-#endif	/* of #ifdef USE_TCP_EXTENTIONS */
-
 #if NUM_WWW_SRV_TASKS >= 2
 
 CRE_TSK(WWW_SRV_TASK2,  {
 	TA_HLNG | TA_ACT,
-	WWW_SRV_CEPID2,
+	2,
 	www_srv_task,
 	WWW_SRV_MAIN_PRIORITY,
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/wwws.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/wwws.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/wwws.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -39,16 +39,4 @@
  */
 
-#include <tinet_defs.h>
-
-#include <net/if.h>
-#include <net/if_ppp.h>
-#include <net/if_loop.h>
-#include <net/ethernet.h>
-
-#include <netinet6/in6.h>
-#include <netinet/ip.h>
-#include <netinet/ip6.h>
-#include <netinet/tcp.h>
-
 #ifdef TOPPERS_S810_CLG3_85
 #define	WWW_SRV_STACK_SIZE		768		/* タスクのスタックサイズ	*/
@@ -62,26 +50,22 @@
  */
 
-#if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0
+#if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU)
 
-#define WWW_SRV_SWBUF_SIZE	((IF_MTU-(IP_HDR_SIZE+TCP_HDR_SIZE))*1)
-
-#else	/* of #if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0 */
-
-#if defined(SUPPORT_INET4)
-#define WWW_SRV_SWBUF_SIZE	(TCP_MSS)
+#if defined(SUPPORT_INET6)
+#define WWW_SRV_SWBUF_SIZE	(1024)
+#elif defined(SUPPORT_INET4)
+#define WWW_SRV_SWBUF_SIZE	(512)
 #endif
 
-#if defined(SUPPORT_INET6)
-#define WWW_SRV_SWBUF_SIZE	(TCP6_MSS)
-#endif
+#else	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
 
-#endif	/* of #if defined(NUM_MPF_NET_BUF_IF_PDU) && NUM_MPF_NET_BUF_IF_PDU > 0 */
+#define WWW_SRV_SWBUF_SIZE	(2048)
 
-#if defined(SUPPORT_INET4)
-#define WWW_SRV_RWBUF_SIZE	(TCP_MSS)
-#endif
+#endif	/* of #if defined(USE_TCP_MSS_SEG) || defined(USE_IPV6_MMTU) */
 
 #if defined(SUPPORT_INET6)
-#define WWW_SRV_RWBUF_SIZE	(TCP6_MSS)
+#define WWW_SRV_RWBUF_SIZE	(1024)
+#elif defined(SUPPORT_INET4)
+#define WWW_SRV_RWBUF_SIZE	(512)
 #endif
 
@@ -89,4 +73,8 @@
 #define WWW_LINE_SIZE		80
 #define WWW_NUM_FIELDS		4
+
+/*
+ *  タスク数
+ */
 
 #ifndef _MACRO_ONLY
@@ -128,10 +116,22 @@
 
 /*
- *  TCP 送受信バッファ
+ *  変数
  */
+
+/* TCP 送受信ウィンドバッファ */
+
+#ifdef NUM_WWW_SRV_TASKS
 
 extern uint8_t www_srv_swbuf[NUM_WWW_SRV_TASKS][WWW_SRV_SWBUF_SIZE];
 extern uint8_t www_srv_rwbuf[NUM_WWW_SRV_TASKS][WWW_SRV_RWBUF_SIZE];
 
+#endif	/* of #ifdef NUM_WWW_SRV_TASKS */
+
+/*
+ *  関数
+ */
+
+extern ER	wakeup_www_srv (char apip);
+
 #endif	/* of #ifndef _MACRO_ONLY */
 
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/wwws_asp.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/wwws_asp.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/wwws_asp.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -42,4 +42,6 @@
 INCLUDE("netapp/wwws.cfg");
 
+#ifdef USE_WWW_SRV
+
 /*
  * 固定メモリプール
@@ -65,2 +67,4 @@
 	NULL
 	});
+
+#endif	/* of #ifdef USE_WWW_SRV */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/wwws_jsp.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/wwws_jsp.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netapp/wwws_jsp.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netdev/if_mbed/Makefile.tinet
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netdev/if_mbed/Makefile.tinet	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netdev/if_mbed/Makefile.tinet	(revision 331)
@@ -36,5 +36,5 @@
 #
 INCLUDES	:= $(INCLUDES) -I$(TINET_ROOT)/netdev/$(NET_DEV)
-TINET_DIR	:= $(TINET_DIR):$(TINET_ROOT)/netdev/$(NET_DEV)
+TINET_DIRS	:= $(TINET_DIRS):$(TINET_ROOT)/netdev/$(NET_DEV)
 TINET_COBJS	:= $(TINET_COBJS) if_mbed.o
 TINET_KERNEL_CFG := $(TINET_KERNEL_CFG) $(TINET_ROOT)/netdev/$(NET_DEV)/if_mbed.cfg
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netdev/if_mbed/if_mbed.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netdev/if_mbed/if_mbed.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netdev/if_mbed/if_mbed.c	(revision 331)
@@ -210,5 +210,5 @@
 if_mbed_addmulti(T_IF_SOFTC *ic)
 {
-	mbed_setrcr(ic);
+	if_mbed_setrcr(ic);
 	return E_OK;
 }
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/icmp6.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/icmp6.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/icmp6.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -102,6 +102,4 @@
 #define _IP_ICMP6_H_
 
-#ifdef SUPPORT_INET6
-
 /*
  *  ICMPv6 ヘッダ
@@ -117,5 +115,5 @@
 		uint8_t		data8[4];
 		} data;
-	} __attribute__((packed, aligned(2)))T_ICMP6_HDR;
+	} __attribute__((packed, aligned(2))) T_ICMP6_HDR;
 
 #define icmp6_data32			data.data32
@@ -133,5 +131,5 @@
 #define GET_ICMP6_SDU(nbuf,ihoff)	((uint8_t*)((nbuf)->buf) + ihoff + ICMP6_HDR_SIZE)
 
-#define GET_IP6_ICMP6_HDR_SIZE(nbuf)	(GET_IP6_HDR_SIZE(GET_IP6_HDR(nbuf)) + ICMP6_HDR_SIZE)
+#define GET_IP6_ICMP6_HDR_SIZE(nbuf)	(GET_IP6_HDR_SIZE(nbuf) + ICMP6_HDR_SIZE)
 #define GET_IF_IP6_ICMP6_HDR_SIZE(nbuf)	(IF_HDR_SIZE + GET_IP6_ICMP6_HDR_SIZE(nbuf))
 
@@ -218,5 +216,5 @@
 	T_IN6_ADDR	target;
 	/* この後にオプションが続く */
-	} __attribute__((packed, aligned(2)))T_NEIGHBOR_SOLICIT_HDR;
+	} T_NEIGHBOR_SOLICIT_HDR;
 
 #define NEIGHBOR_SOLICIT_HDR_SIZE	(sizeof(T_NEIGHBOR_SOLICIT_HDR))
@@ -230,5 +228,5 @@
 
 #define GET_IP6_NEIGHBOR_SOLICIT_HDR_SIZE(nbuf)		\
-					(GET_IP6_HDR_SIZE(GET_IP6_HDR(nbuf)) + NEIGHBOR_SOLICIT_HDR_SIZE)
+					(GET_IP6_HDR_SIZE(nbuf) + NEIGHBOR_SOLICIT_HDR_SIZE)
 #define GET_IF_IP6_NEIGHBOR_SOLICIT_HDR_SIZE(nbuf)	\
 					(GET_IP6_NEIGHBOR_SOLICIT_HDR_SIZE(nbuf) + IF_HDR_SIZE)
@@ -242,5 +240,5 @@
 	T_IN6_ADDR	target;
 	/* この後にオプションが続く */
-	} __attribute__((packed, aligned(2)))T_NEIGHBOR_ADVERT_HDR;
+	} __attribute__((packed, aligned(2))) T_NEIGHBOR_ADVERT_HDR;
 
 /* ICMP6 ヘッダのデータ部の定義 */
@@ -261,5 +259,5 @@
 
 #define GET_IP6_NEIGHBOR_ADVERT_HDR_SIZE(nbuf)		\
-					(GET_IP6_HDR_SIZE(GET_IP6_HDR(nbuf)) + NEIGHBOR_ADVERT_HDR_SIZE)
+					(GET_IP6_HDR_SIZE(nbuf) + NEIGHBOR_ADVERT_HDR_SIZE)
 #define GET_IF_IP6_NEIGHBOR_ADVERT_HDR_SIZE(nbuf)	\
 					(GET_IP6_NEIGHBOR_ADVERT_HDR_SIZE(nbuf) + IF_HDR_SIZE)
@@ -285,4 +283,8 @@
 /*
  *  ルータ通知
+ *
+ *    RFC4291: IP Version 6 Addressing Architecture
+ *    RFC4941: Privacy Extensions for Stateless Address Autoconfiguration in IPv6
+ *    RFC6106: IPv6 Router Advertisement Options for DNS Configuration
  */
 
@@ -292,5 +294,5 @@
 	uint32_t	retransmit;		/* [ms] 近隣要請送信間隔	*/
 	/* この後にオプションが続く */
-	} __attribute__((packed, aligned(2)))T_ROUTER_ADVERT_HDR;
+	} __attribute__((packed, aligned(2))) T_ROUTER_ADVERT_HDR;
 
 /* ICMP6 ヘッダのデータ部の定義 */
@@ -311,5 +313,5 @@
 
 #define GET_IP6_ROUTER_ADVERT_HDR_SIZE(nbuf)	\
-					(GET_IP6_HDR_SIZE(GET_IP6_HDR(nbuf)) + ROUTER_ADVERT_HDR_SIZE)
+					(GET_IP6_HDR_SIZE(nbuf) + ROUTER_ADVERT_HDR_SIZE)
 #define GET_IF_IP6_ROUTER_ADVERT_HDR_SIZE(nbuf)	\
 					(GET_IP6_ROUTER_ADVERT_HDR_SIZE(nbuf) + IF_HDR_SIZE)
@@ -324,4 +326,15 @@
 
 /*
+ *  M: RA以外の方法で自動的にアドレスを設定することを許可する。
+ *  O: RA以外の方法で自動的にアドレス以外の情報を設定することをを許可する。
+ *
+ *   M   O
+ *  ON  ON	アドレスとそれ以外の情報をDHCPv6で設定する（statefull）
+ *  ON  OFF	アドレスはDHCPv6で設定するが、それ以外は手動で設定する。
+ *  OFF ON	アドレスは RA で設定するが、それ以外の情報をDHCPv6で設定する（stateless）
+ *  OFF OFF	DHCPv6 は使用しない。
+ */
+
+/*
  *  ルータ要請
  */
@@ -329,5 +342,5 @@
 typedef struct t_router_solicit_hdr {
 	T_ICMP6_HDR	hdr;
-	} __attribute__((packed, aligned(2)))T_ROUTER_SOLICIT_HDR;
+	} __attribute__((packed, aligned(2))) T_ROUTER_SOLICIT_HDR;
 
 /* ICMP6 ヘッダのデータ部の定義 */
@@ -347,5 +360,5 @@
 
 #define GET_IP6_ROUTER_SOLICIT_HDR_SIZE(nbuf)		\
-					(GET_IP6_HDR_SIZE(GET_IP6_HDR(nbuf)) + ROUTER_SOLICIT_HDR_SIZE)
+					(GET_IP6_HDR_SIZE(nbuf) + ROUTER_SOLICIT_HDR_SIZE)
 #define GET_IF_IP6_ROUTER_SOLICIT_HDR_SIZE(nbuf)	\
 					(GET_IP6_ROUTER_SOLICIT_HDR_SIZE(nbuf) + IF_HDR_SIZE)
@@ -360,5 +373,5 @@
 	T_ICMP6_HDR	hdr;
 	T_IN6_ADDR	target;
-	} __attribute__((packed, aligned(2)))T_NEIGHBOR_HDR;
+	} __attribute__((packed, aligned(2))) T_NEIGHBOR_HDR;
 
 /* 近隣探索オプションヘッダ */
@@ -367,5 +380,5 @@
 	uint8_t		type;			/* オプションタイプ			*/
 	uint8_t		len;			/* オプション長、単位は 8 バイト	*/
-	} __attribute__((packed, aligned(2)))T_ND_OPT_HDR;
+	} __attribute__((packed, aligned(2))) T_ND_OPT_HDR;
 
 #define ND_OPT_HDR_SIZE			(sizeof(T_ND_OPT_HDR))
@@ -393,5 +406,5 @@
 	uint32_t	reserved;
 	T_IN6_ADDR	prefix;		/* プレフィックス		*/
-	} __attribute__((packed, aligned(2)))T_ND_OPT_PREFIX_INFO;
+	} __attribute__((packed, aligned(2))) T_ND_OPT_PREFIX_INFO;
 
 #define ND_OPT_PI_FLAG_ONLINK	UINT_C(0x80)		/* オンリンクプレフィックス	*/
@@ -405,5 +418,5 @@
 	uint16_t	reserved;
 	uint32_t	mtu;		/* MTU				*/
-	} __attribute__((packed, aligned(2)))T_ND_OPT_MTU_HDR;
+	} __attribute__((packed, aligned(2))) T_ND_OPT_MTU_HDR;
 
 /*
@@ -416,5 +429,5 @@
 	T_IN6_ADDR	dst;		/* 向け直しの終点アドレス		*/
 	/* この後にオプションが続く */
-	} __attribute__((packed, aligned(2)))T_ND_REDIRECT_HDR;
+	} __attribute__((packed, aligned(2))) T_ND_REDIRECT_HDR;
 
 #define ND_REDIRECT_HDR_SIZE		(sizeof(T_ND_REDIRECT_HDR))
@@ -480,5 +493,3 @@
 #endif	/* of #ifdef ICMP_CFG_CALLBACK_ECHO_REPLY */
 
-#endif	/* of #ifdef SUPPORT_INET6 */
-
 #endif	/* of #ifndef _IP_ICMP6_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/icmp_var.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/icmp_var.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/icmp_var.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/if_ether.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/if_ether.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/if_ether.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -94,4 +94,5 @@
 #include <net/if_arp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_var.h>
@@ -106,5 +107,5 @@
 #include <net/if_var.h>
 
-#if defined(SUPPORT_INET4) && defined(SUPPORT_ETHER)
+#if defined(_IP4_CFG) && defined(SUPPORT_ETHER)
 
 /*
@@ -118,9 +119,168 @@
  */
 
-static T_ARP_ENTRY *arp_lookup (T_IN4_ADDR addr, bool_t create);
 static void in_arpinput (T_IF_ADDR *ifaddr, T_NET_BUF *input);
 static void arp_timer (void *ignore);
 
 /*
+ *  in_arpinput -- TCP/IP 用 ARP の入力関数
+ */
+
+static void
+in_arpinput (T_IF_ADDR *ifaddr, T_NET_BUF *input)
+{
+	T_NET_BUF	*pending;
+	T_ETHER_HDR	*eth;
+	T_ARP_HDR	*arph;
+	T_ETHER_ARP_HDR	*et_arph;
+	T_ARP_ENTRY	*ent;
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_IN4_ADDR	saddr, taddr;
+
+	et_arph = GET_ETHER_ARP_HDR(input);
+
+	ntoahl(saddr, et_arph->sproto);		/* 送信元 IP アドレス	*/
+	ntoahl(taddr, et_arph->tproto);		/* 解決対象 IP アドレス	*/
+
+	/*
+	 *  以下の場合はエラー
+	 *    ・送信ホストの物理アドレスが自分
+	 *    ・送信ホストの物理アドレスがブロードキャスト
+	 */
+	if (memcmp(et_arph->shost, ifaddr->lladdr,        ETHER_ADDR_LEN) == 0 ||
+	    memcmp(et_arph->shost, ether_broad_cast_addr, ETHER_ADDR_LEN) == 0)
+		goto err_ret;
+
+	/*
+	 *  送信ホストの IP アドレスが自分の場合は、重複しているので
+	 *  相手にも知らせる。
+	 *  ただし、自分と相手のアドレスが未定義（IPV4_ADDRANY）の時は何もしない。
+	 */
+	if ((saddr == ifp->in4_ifaddr.addr) && (saddr != IPV4_ADDRANY)) {
+
+#ifdef ARP_CFG_CALLBACK_DUPLICATED
+
+		if (arp_callback_duplicated(et_arph->shost)) {
+			syslog(LOG_ERROR, "[ARP] IP address duplicated: %s",
+			                  ip2str(NULL, &ifp->in4_ifaddr.addr),
+			                  mac2str(NULL, et_arph->shost));
+			taddr = saddr;
+			goto reply;
+			}
+		else
+			goto buf_rel;
+
+#else	/* of #ifdef ARP_CFG_CALLBACK_DUPLICATED */
+
+		syslog(LOG_ERROR, "[ARP] IP address duplicated: %s",
+			          ip2str(NULL, &ifp->in4_ifaddr.addr),
+			          mac2str(NULL, et_arph->shost));
+		taddr = saddr;
+		goto reply;
+
+#endif	/* of #ifdef ARP_CFG_CALLBACK_DUPLICATED */
+
+		}
+
+	/*
+	 *  以下の場合は何もしない。
+	 *    ・解決対象 IP アドレスが自分ではない、注: 元の FreeBSD の
+	 *      実装では、ARP PROXY 等のため、自分以外の IP アドレスの
+	 *      解決も行っているが、本実装では、自分以外の IP
+	 *      アドレスの解決は行わない。
+	 */
+	if (taddr != ifp->in4_ifaddr.addr)
+		goto buf_rel;
+
+	/*
+	 *  送信元 IP アドレスが ARP キャッシュにあるか調べる。
+	 *  キャッシュになければ、新たにエントリを登録する。
+	 */
+	syscall(wai_sem(SEM_ARP_CACHE_LOCK));
+	ent = arp_lookup(saddr, true);
+
+	memcpy(ent->mac_addr, et_arph->shost, ETHER_ADDR_LEN);
+	ent->expire = ARP_CACHE_KEEP;
+
+	/*
+	 *  送信がペンデングされているフレームがあれば送信する。
+	 */
+	if (ent->hold) {
+
+		/* フレームの Ethernet ヘッダを設定する。*/
+		memcpy(GET_ETHER_HDR(ent->hold)->dhost, ent->mac_addr, ETHER_ADDR_LEN);
+
+		pending = ent->hold;
+		ent->hold = NULL;
+		syscall(sig_sem(SEM_ARP_CACHE_LOCK));
+
+		/* ペンディングされているフレームを送信する。*/
+		IF_RAW_OUTPUT(pending, TMO_FEVR);
+
+		}
+	else
+		syscall(sig_sem(SEM_ARP_CACHE_LOCK));
+
+reply:
+
+	arph = GET_ARP_HDR(input);
+
+	/* アドレス解決要求でなければ終了 */
+	if (ntohs(arph->opcode) != ARPOP_REQUEST)
+		goto buf_rel;
+
+	/* Ethernet ARP ヘッダを設定する。*/
+	memcpy(et_arph->thost, et_arph->shost, ETHER_ADDR_LEN);
+	memcpy(et_arph->shost, ifaddr->lladdr, ETHER_ADDR_LEN);
+	memcpy(et_arph->tproto, (uint8_t*)&et_arph->sproto, sizeof(T_IN_ADDR));
+	ahtonl(et_arph->sproto, taddr);
+
+	/* Ethernet ARP ヘッダを設定する。*/
+	arph->opcode = htons(ARPOP_REPLY);
+
+	/* Ethernet ヘッダを設定する。*/
+	eth = GET_ETHER_HDR(input);
+	memcpy(eth->dhost, eth->shost,     ETHER_ADDR_LEN);
+	memcpy(eth->shost, ifaddr->lladdr, ETHER_ADDR_LEN);
+
+	/* ARP 応答を送信する。*/
+	IF_RAW_OUTPUT(input, TMO_FEVR);
+	return;
+
+err_ret:
+	NET_COUNT_ARP(net_count_arp.in_err_packets, 1);
+buf_rel:
+	syscall(rel_net_buf(input));
+	}
+
+/*
+ *  arp_timer -- ARP キャッシュの更新
+ */
+
+static void
+arp_timer (void *ignore)
+{
+	int_t	ix;
+
+	syscall(wai_sem(SEM_ARP_CACHE_LOCK));
+
+	for (ix = NUM_ARP_ENTRY; ix -- > 0; ) {
+		if (arp_cache[ix].expire) {
+			arp_cache[ix].expire -= ARP_TIMER_TMO;
+			if (arp_cache[ix].expire == 0) {
+				/* 送信がペンデングされているフレームがあれば捨てる。*/
+				if (arp_cache[ix].hold) {
+					NET_COUNT_IP4(net_count_ip4[NC_IP4_OUT_ERR_PACKETS], 1);
+					syscall(rel_net_buf(arp_cache[ix].hold));
+					}
+				memset(&arp_cache[ix], 0, sizeof(T_ARP_ENTRY));
+				}
+			}
+		}
+
+	syscall(sig_sem(SEM_ARP_CACHE_LOCK));
+	timeout(arp_timer, NULL, ARP_TIMER_TMO);
+	}
+
+/*
  *  arp_lookup -- ARP キャッシュの探索と登録
  *
@@ -128,5 +288,5 @@
  */
 
-static T_ARP_ENTRY *
+T_ARP_ENTRY *
 arp_lookup (T_IN4_ADDR addr, bool_t create)
 {
@@ -170,159 +330,4 @@
 
 /*
- *  in_arpinput -- TCP/IP 用 ARP の入力関数
- */
-
-static void
-in_arpinput (T_IF_ADDR *ifaddr, T_NET_BUF *input)
-{
-	T_NET_BUF	*pending;
-	T_ETHER_HDR	*eth;
-	T_ARP_HDR	*arph;
-	T_ETHER_ARP_HDR	*et_arph;
-	T_ARP_ENTRY	*ent;
-	T_IFNET		*ifp = IF_GET_IFNET();
-	T_IN4_ADDR	saddr, taddr;
-
-	et_arph = GET_ETHER_ARP_HDR(input);
-
-	ntoahl(saddr, et_arph->sproto);		/* 送信元 IP アドレス	*/
-	ntoahl(taddr, et_arph->tproto);		/* 解決対象 IP アドレス	*/
-
-	/*
-	 *  以下の場合はエラー
-	 *    ・送信ホストの物理アドレスが自分
-	 *    ・送信ホストの物理アドレスがブロードキャスト
-	 */
-	if (memcmp(et_arph->shost, ifaddr->lladdr,        ETHER_ADDR_LEN) == 0 ||
-	    memcmp(et_arph->shost, ether_broad_cast_addr, ETHER_ADDR_LEN) == 0)
-		goto err_ret;
-
-	/*
-	 *  送信ホストの IP アドレスが自分の場合は、重複しているので
-	 *  相手にも知らせる。
-	 */
-	if (saddr == ifp->in_ifaddr.addr) {
-
-#ifdef ARP_CFG_CALLBACK_DUPLICATED
-
-		if (arp_callback_duplicated(et_arph->shost)) {
-			syslog(LOG_ERROR, "[ARP] IP address duplicated: %s", mac2str(NULL, et_arph->shost));
-			taddr = saddr;
-			goto reply;
-			}
-		else
-			goto buf_rel;
-
-#else	/* of #ifdef ARP_CFG_CALLBACK_DUPLICATED */
-
-		syslog(LOG_ERROR, "[ARP] IP address duplicated: %s", mac2str(NULL, et_arph->shost));
-		taddr = saddr;
-		goto reply;
-
-#endif	/* of #ifdef ARP_CFG_CALLBACK_DUPLICATED */
-
-		}
-
-	/*
-	 *  以下の場合は何もしない。
-	 *    ・解決対象 IP アドレスが自分ではない、注: 元の FreeBSD の
-	 *      実装では、ARP PROXY 等のため、自分以外の IP アドレスの
-	 *      解決も行っているが、本実装では、自分以外の IP
-	 *      アドレスの解決は行わない。
-	 */
-	if (taddr != ifp->in_ifaddr.addr)
-		goto buf_rel;
-
-	/*
-	 *  送信元 IP アドレスが ARP キャッシュにあるか調べる。
-	 *  キャッシュになければ、新たにエントリを登録する。
-	 */
-	syscall(wai_sem(SEM_ARP_CACHE_LOCK));
-	ent = arp_lookup(saddr, true);
-
-	memcpy(ent->mac_addr, et_arph->shost, ETHER_ADDR_LEN);
-	ent->expire = ARP_CACHE_KEEP;
-
-	/*
-	 *  送信がペンデングされているフレームがあれば送信する。
-	 */
-	if (ent->hold) {
-
-		/* フレームの Ethernet ヘッダを設定する。*/
-		memcpy(GET_ETHER_HDR(ent->hold)->dhost, ent->mac_addr, ETHER_ADDR_LEN);
-
-		pending = ent->hold;
-		ent->hold = NULL;
-		syscall(sig_sem(SEM_ARP_CACHE_LOCK));
-
-		/* ペンディングされているフレームを送信する。*/
-		IF_RAW_OUTPUT(pending, TMO_FEVR);
-
-		}
-	else
-		syscall(sig_sem(SEM_ARP_CACHE_LOCK));
-
-reply:
-
-	arph = GET_ARP_HDR(input);
-
-	/* アドレス解決要求でなければ終了 */
-	if (ntohs(arph->opcode) != ARPOP_REQUEST)
-		goto buf_rel;
-
-	/* Ethernet ARP ヘッダを設定する。*/
-	memcpy(et_arph->thost, et_arph->shost, ETHER_ADDR_LEN);
-	memcpy(et_arph->shost, ifaddr->lladdr, ETHER_ADDR_LEN);
-	memcpy(et_arph->tproto, (uint8_t*)&et_arph->sproto, sizeof(T_IN_ADDR));
-	ahtonl(et_arph->sproto, taddr);
-
-	/* Ethernet ARP ヘッダを設定する。*/
-	arph->opcode = htons(ARPOP_REPLY);
-
-	/* Ethernet ヘッダを設定する。*/
-	eth = GET_ETHER_HDR(input);
-	memcpy(eth->dhost, eth->shost,     ETHER_ADDR_LEN);
-	memcpy(eth->shost, ifaddr->lladdr, ETHER_ADDR_LEN);
-
-	/* ARP 応答を送信する。*/
-	IF_RAW_OUTPUT(input, TMO_FEVR);
-	return;
-
-err_ret:
-	NET_COUNT_ARP(net_count_arp.in_err_packets, 1);
-buf_rel:
-	syscall(rel_net_buf(input));
-	}
-
-/*
- *  arp_timer -- ARP キャッシュの更新
- */
-
-static void
-arp_timer (void *ignore)
-{
-	int_t	ix;
-
-	syscall(wai_sem(SEM_ARP_CACHE_LOCK));
-
-	for (ix = NUM_ARP_ENTRY; ix -- > 0; ) {
-		if (arp_cache[ix].expire) {
-			arp_cache[ix].expire -= ARP_TIMER_TMO;
-			if (arp_cache[ix].expire == 0) {
-				/* 送信がペンデングされているフレームがあれば捨てる。*/
-				if (arp_cache[ix].hold) {
-					NET_COUNT_IP4(net_count_ip4[NC_IP4_OUT_ERR_PACKETS], 1);
-					syscall(rel_net_buf(arp_cache[ix].hold));
-					}
-				memset(&arp_cache[ix], 0, sizeof(T_ARP_ENTRY));
-				}
-			}
-		}
-
-	syscall(sig_sem(SEM_ARP_CACHE_LOCK));
-	timeout(arp_timer, NULL, ARP_TIMER_TMO);
-	}
-
-/*
  *  arp_request -- MAC アドレス解決要求
  */
@@ -359,5 +364,5 @@
 		/* イーサネット ARP ヘッダを設定する。*/
 		et_arph = GET_ETHER_ARP_HDR(arp_req);
-		src     = IF_GET_IFNET()->in_ifaddr.addr;
+		src     = IF_GET_IFNET()->in4_ifaddr.addr;
 		memcpy(et_arph->shost, ifaddr->lladdr, ETHER_ADDR_LEN);
 		memset(et_arph->thost, 0,              ETHER_ADDR_LEN);
@@ -444,5 +449,5 @@
 	 */
 	if (gw == IPV4_ADDR_BROADCAST ||
-	    gw == ((ifp->in_ifaddr.addr & ifp->in_ifaddr.mask) | ~ifp->in_ifaddr.mask)) {
+	    gw == ((ifp->in4_ifaddr.addr & ifp->in4_ifaddr.mask) | ~ifp->in4_ifaddr.mask)) {
 		memcpy(eth->dhost, ether_broad_cast_addr, ETHER_ADDR_LEN);
 		return true;
@@ -504,9 +509,9 @@
 	eaddr->lladdr[1] = UINT_C(0x00);
 	eaddr->lladdr[2] = UINT_C(0x5E);
-	eaddr->lladdr[3] = (maddr & 0x7F0000) >> 16;
-	eaddr->lladdr[4] = (maddr & 0xFF00) >> 8;
-	eaddr->lladdr[5] = maddr & 0xFF;
+	eaddr->lladdr[3] = (uint8_t)((maddr & 0x7F0000) >> 16);
+	eaddr->lladdr[4] = (uint8_t)((maddr & 0xFF00) >> 8);
+	eaddr->lladdr[5] = (uint8_t)(maddr & 0xFF);
 	}
 #endif	/* ETHER_CFG_MULTICAST */
 
-#endif	/* of #if defined(SUPPORT_INET4) && defined(SUPPORT_ETHER) */
+#endif	/* of #if defined(_IP4_CFG) && defined(SUPPORT_ETHER) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/if_ether.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/if_ether.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/if_ether.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -36,5 +36,5 @@
  */
 
-#ifdef SUPPORT_ETHER
+#if defined(_IP4_CFG) && defined(SUPPORT_ETHER)
 
 /* ARP キャッシュ更新用セマフォ */
@@ -42,3 +42,3 @@
 CRE_SEM(SEM_ARP_CACHE_LOCK, { TA_TPRI, 1, 1 });
 
-#endif	/* of #ifdef SUPPORT_ETHER */
+#endif	/* of #if defined(_IP4_CFG) && defined(SUPPORT_ETHER) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/if_ether.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/if_ether.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/if_ether.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -106,4 +106,5 @@
  */
 
+extern T_ARP_ENTRY *arp_lookup (T_IN4_ADDR addr, bool_t create);
 extern ER arp_request (T_IF_ADDR *ifaddr, T_IN4_ADDR dst);
 extern void arp_input (T_IF_ADDR *ifaddr, T_NET_BUF *input);
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -73,4 +73,5 @@
 #include <tinet_kernel_defs.h>
 
+#include <netinet/in4.h>
 #include <netinet6/in6.h>
 
@@ -79,5 +80,5 @@
  */
 
-#define TINET_PRVER		UINT_C(0x1054)	/* TINET のバージョン番号 */
+#define TINET_PRVER		UINT_C(0x1070)	/* TINET のバージョン番号 */
 
 /*
@@ -92,4 +93,5 @@
 #define IPPROTO_HOPOPTS		UINT_C(0)	/* IPv6 中継点 (Hop-by-Hop) オプション	*/
 #define IPPROTO_ICMP		UINT_C(1)	/* ICMP					*/
+#define IPPROTO_IGMP		UINT_C(2)	/* IGMP					*/
 #define IPPROTO_TCP		UINT_C(6)	/* TCP					*/
 #define IPPROTO_UDP		UINT_C(17)	/* UDP					*/
@@ -107,31 +109,7 @@
 
 /*
- *  IPv4 アドレス
+ *  ポートの長さ
  */
 
-/* 前方参照 */
-
-#ifndef T_IN4_ADDR_DEFINED
-
-typedef uint32_t T_IN4_ADDR;
-
-#define T_IN4_ADDR_DEFINED
-
-#endif	/* of #ifndef T_IN4_ADDR_DEFINED */
-
-/*
- *  ITRON TCP/IPv4 アドレス/ポート番号の定義
- */
-
-typedef struct t_ipv4ep {
-	uint32_t	ipaddr;		/* IPv4 アドレス	*/
-	uint16_t	portno;		/* ポート番号		*/
-	} T_IPV4EP;
-
-/*
- *  アドレス/ポートの長さ
- */
-
-#define IPV4_ADDR_LEN		4
 #define PORT_NUM_LEN		2
 
@@ -152,109 +130,43 @@
 
 /*
- *  IP アドレスの定義
+ *  API IPプロトコルの指定
  */
 
-#define IPV4_ADDRANY		ULONG_C(0x00000000)	/* ITRON TCP/IP 標準	*/
-
-#define IPV4_ADDR_LOOPBACK	ULONG_C(0x7f000001)
-#define IPV4_ADDR_LOOPBACK_MASK	IPV4_CLASS_A_MASK
-#define IPV4_ADDR_BROADCAST	ULONG_C(0xffffffff)
-
-#define IPV4_CLASS_A(i)		(((i) & ULONG_C(0x80000000)) == 0)
-#define IPV4_CLASS_A_NET	ULONG_C(0xff000000)
-#define IPV4_CLASS_A_MASK	ULONG_C(0xff000000)
-#define IPV4_CLASS_A_HOST	ULONG_C(0x00ffffff)
-
-#define IPV4_CLASS_B(i)		(((i) & ULONG_C(0xc0000000)) == ULONG_C(0x80000000))
-#define IPV4_CLASS_B_NET	ULONG_C(0xffff0000)
-#define IPV4_CLASS_B_MASK	ULONG_C(0xffff0000)
-#define IPV4_CLASS_B_HOST	ULONG_C(0x0000ffff)
-
-#define IPV4_CLASS_C(i)		(((i) & ULONG_C(0xe0000000)) == ULONG_C(0xc0000000))
-#define IPV4_CLASS_C_NET	ULONG_C(0xffffff00)
-#define IPV4_CLASS_C_MASK	ULONG_C(0xffffff00)
-#define IPV4_CLASS_C_HOST	ULONG_C(0x000000ff)
-
-#define IPV4_CLASS_D(i)		(((i) & ULONG_C(0xf0000000)) == ULONG_C(0xe0000000))
-
-#define IN4_IS_ADDR_MULTICAST(i)	IPV4_CLASS_D(i)
-
-#define MAKE_IPV4_LOCAL_BROADCAST(i)	(IPV4_CLASS_A(i)?((i)|IPV4_CLASS_A_HOST):\
-					 IPV4_CLASS_B(i)?((i)|IPV4_CLASS_B_HOST):\
-					 IPV4_CLASS_C(i)?((i)|IPV4_CLASS_C_HOST):\
-					 IPV4_ADDR_BROADCAST)
-
-#define MAKE_IPV4_LOCAL_MASK(i)		(IPV4_CLASS_A(i)?IPV4_CLASS_A_MASK:\
-					 IPV4_CLASS_B(i)?IPV4_CLASS_B_MASK:\
-					 IPV4_CLASS_C(i)?IPV4_CLASS_C_MASK:\
-					 IPV4_ADDRANY)
-
-#define MAKE_IPV4_ADDR(a,b,c,d)		((T_IN4_ADDR)(((uint32_t)(a)<<24)|((uint32_t)(b)<<16)|((uint32_t)(c)<<8)|(d)))
+#define API_PROTO_IPVn			'n'
+#define API_PROTO_IPV6			'6'
+#define API_PROTO_IPV4			'4'
 
 /*
- *  動的生成用 TCP 通信端点
+ *  動的生成用 TCP/IPv6 通信端点
  */
 
-typedef struct t_tcp_ccep {
-	/* 標準 */
-	ATR		cepatr;		/* 通信端点属性			*/
-	void		*sbuf;		/* 送信用ウィンドバッファ	*/
-	int_t		sbufsz;		/* 送信用ウィンドバッファサイズ	*/
-	void		*rbuf;		/* 受信用ウィンドバッファ	*/
-	int_t		rbufsz;		/* 受信用ウィンドバッファサイズ	*/
-	FP		callback;	/* コールバック			*/
-	/* 実装依存 */
-	} T_TCP_CCEP;
+#define T_TCP6_CCEP			T_TCP_CCEP
 
 /*
- *  動的生成用 TCP 受付口
+ *  バイトオーダ関数の定義
+ *
+ *    tinet/net/net.h でもバイトオーダの定義を行っているが、
+ *    tinet/net/net.h をインクルードしない
+ *    アプリケーションプログラム用に
+ *    ターゲット依存しないバイトオーダ関数を定義する。
  */
 
-#if defined(SUPPORT_INET4)
+#if defined(_NET_CFG_BYTE_ORDER)
 
-typedef struct t_tcp_crep {
-	/* 標準 */
-	ATR		repatr;		/* 受付口属性		*/
-	T_IPV4EP	myaddr;		/* 自分のアドレス	*/
-	/* 実装依存 */
-	} T_TCP_CREP;
+/*  tinet/net/net.h をインクルードしている。*/
 
-#endif	/* of #if defined(SUPPORT_INET4) */
+#else	/* of #if defined(_NET_CFG_BYTE_ORDER) */
 
-/*
- *  動的生成用 UDP 通信端点
- */
+extern uint16_t ntohs (uint16_t net);
+extern uint16_t htons (uint16_t host);
+extern uint32_t ntohl (uint32_t net);
+extern uint32_t htonl (uint32_t host);
 
-#if defined(SUPPORT_INET4)
+#define NTOHS(n)	(n=ntohs(n))
+#define HTONS(h)	(h=htons(h))
+#define NTOHL(n)	(n=ntohl(n))
+#define HTONL(h)	(h=htonl(h))
 
-typedef struct t_udp_ccep {
-	/* 標準 */
-	ATR		cepatr;		/* UDP 通信端点属性		*/
-	T_IPV4EP	myaddr;		/* 自分のアドレス		*/
-	FP		callback;	/* コールバック関数		*/
-	/* 実装依存 */
-	} T_UDP_CCEP;
-
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-/*
- *  IPv4 と IPv6 をコンパイル時に選択するためのマクロ
- */
-
-#if defined(SUPPORT_INET4)
-
-#define T_IN_ADDR			T_IN4_ADDR
-#define T_IPEP				T_IPV4EP
-#define IP_ADDRANY			IPV4_ADDRANY
-
-#define IN_ARE_ADDR_EQUAL(n,h)		(*(n)==*(h))
-#define IN_ARE_NET_ADDR_EQUAL(n,h)	(ntohl(*(n))==*(h))
-#define IN_COPY_TO_NET(d,s)		(*(d)=htonl(*(s)))
-#define IN_COPY_TO_HOST(d,s)		(*(d)=ntohl(*(s)))
-#define IN_IS_ADDR_MULTICAST(a)		IN4_IS_ADDR_MULTICAST(*(a))
-#define IN_IS_NET_ADDR_MULTICAST(a)	IN4_IS_ADDR_MULTICAST(ntohl(*(a)))
-#define IN_IS_ADDR_ANY(a)		(*(a)==IPV4_ADDRANY)
-
-#endif	/* of #if defined(SUPPORT_INET4) */
+#endif	/* of #if defined(_NET_CFG_BYTE_ORDER) */
 
 /*
@@ -264,13 +176,3 @@
 extern const char *in_strtfn (FN fncd);
 
-#if defined(SUPPORT_INET4)
-
-extern ER in4_add_ifaddr (T_IN4_ADDR addr, T_IN4_ADDR mask);
-extern ER in4_add_route (int_t index, T_IN4_ADDR target,
-                                      T_IN4_ADDR mask, T_IN4_ADDR gateway);
-extern char *ip2str (char *buf, const T_IN4_ADDR *p_ipaddr);
-extern const T_IN4_ADDR *in4_get_ifaddr (int_t index);
-
-#endif	/* of #if defined(SUPPORT_INET4) */
-
 #endif	/* of #ifndef _IN_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in4.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in4.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in4.h	(revision 331)
@@ -0,0 +1,220 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)in.h	8.3 (Berkeley) 1/3/94
+ * $FreeBSD: src/sys/netinet/in.h,v 1.38.2.3 1999/08/29 16:29:34 peter Exp $
+ */
+ 
+#ifndef _IN4_H_
+#define _IN4_H_
+
+/*
+ *  IPv4 ã¢ãã¬ã¹
+ */
+
+/* åæ¹åç
+§ */
+
+#ifndef T_IN4_ADDR_DEFINED
+
+typedef uint32_t T_IN4_ADDR;
+
+#define T_IN4_ADDR_DEFINED
+
+#endif	/* of #ifndef T_IN4_ADDR_DEFINED */
+
+/*
+ *  ITRON TCP/IPv4 ã¢ãã¬ã¹/ãã¼ãçªå·ã®å®ç¾©
+ */
+
+typedef struct t_ipv4ep {
+	uint32_t	ipaddr;		/* IPv4 ã¢ãã¬ã¹	*/
+	uint16_t	portno;		/* ãã¼ãçªå·		*/
+	} T_IPV4EP;
+
+#define T_IPV4EP_DEFINED
+
+/*
+ *  ã¢ãã¬ã¹ã®é·ã
+ */
+
+#define IPV4_ADDR_LEN		4
+
+/*
+ *  IPv4 ã¢ãã¬ã¹ã®å®ç¾©
+ */
+
+#define IPV4_ADDRANY		ULONG_C(0x00000000)	/* ITRON TCP/IP æ¨æº	*/
+#define IPV4_ADDRBROADCAST	ULONG_C(0xffffffff)
+
+#define IPV4_ADDR_LOOPBACK	ULONG_C(0x7f000001)
+#define IPV4_ADDR_LOOPBACK_MASK	IPV4_CLASS_A_MASK
+#define IPV4_ADDR_BROADCAST	ULONG_C(0xffffffff)
+
+#define IPV4_CLASS_A(i)		(((i) & ULONG_C(0x80000000)) == 0)
+#define IPV4_CLASS_A_NET	ULONG_C(0xff000000)
+#define IPV4_CLASS_A_MASK	ULONG_C(0xff000000)
+#define IPV4_CLASS_A_HOST	ULONG_C(0x00ffffff)
+
+#define IPV4_CLASS_B(i)		(((i) & ULONG_C(0xc0000000)) == ULONG_C(0x80000000))
+#define IPV4_CLASS_B_NET	ULONG_C(0xffff0000)
+#define IPV4_CLASS_B_MASK	ULONG_C(0xffff0000)
+#define IPV4_CLASS_B_HOST	ULONG_C(0x0000ffff)
+
+#define IPV4_CLASS_C(i)		(((i) & ULONG_C(0xe0000000)) == ULONG_C(0xc0000000))
+#define IPV4_CLASS_C_NET	ULONG_C(0xffffff00)
+#define IPV4_CLASS_C_MASK	ULONG_C(0xffffff00)
+#define IPV4_CLASS_C_HOST	ULONG_C(0x000000ff)
+
+#define IPV4_CLASS_D(i)		(((i) & ULONG_C(0xf0000000)) == ULONG_C(0xe0000000))
+
+#define IN4_IS_ADDR_MULTICAST(i)	IPV4_CLASS_D(i)
+
+#define MAKE_IPV4_LOCAL_BROADCAST(i)	(IPV4_CLASS_A(i)?((i)|IPV4_CLASS_A_HOST):\
+					 IPV4_CLASS_B(i)?((i)|IPV4_CLASS_B_HOST):\
+					 IPV4_CLASS_C(i)?((i)|IPV4_CLASS_C_HOST):\
+					 IPV4_ADDR_BROADCAST)
+
+#define MAKE_IPV4_LOCAL_MASK(i)		(IPV4_CLASS_A(i)?IPV4_CLASS_A_MASK:\
+					 IPV4_CLASS_B(i)?IPV4_CLASS_B_MASK:\
+					 IPV4_CLASS_C(i)?IPV4_CLASS_C_MASK:\
+					 IPV4_ADDRANY)
+
+#define MAKE_IPV4_ADDR(a,b,c,d)		((T_IN4_ADDR)(((uint32_t)(a)<<24)|((uint32_t)(b)<<16)|((uint32_t)(c)<<8)|(d)))
+
+/*
+ *  é¢æ°ã·ãã¥ã¬ã¼ã·ã§ã³ãã¯ã­
+ */
+
+#define IN4_ARE_ADDR_EQUAL(dst,src)	(*(dst)==*(src))
+#define IN4_IS_ADDR_ANY(addr)		(*(addr)==IPV4_ADDRANY)
+#define IN4_IS_ADDR_BROADCAST(addr)	(*(addr)==IPV4_ADDRBROADCAST)
+#define ip2str(buf,p_ipaddr)		(ipv42str(buf,p_ipaddr))
+
+/*
+ *  åççæç¨ TCP éä¿¡ç«¯ç¹
+ */
+
+typedef struct t_tcp_ccep {
+	/* æ¨æº */
+	ATR		cepatr;		/* éä¿¡ç«¯ç¹å±æ§			*/
+	void		*sbuf;		/* éä¿¡ç¨ã¦ã£ã³ããããã¡	*/
+	int_t		sbufsz;		/* éä¿¡ç¨ã¦ã£ã³ããããã¡ãµã¤ãº	*/
+	void		*rbuf;		/* åä¿¡ç¨ã¦ã£ã³ããããã¡	*/
+	int_t		rbufsz;		/* åä¿¡ç¨ã¦ã£ã³ããããã¡ãµã¤ãº	*/
+	FP		callback;	/* ã³ã¼ã«ããã¯			*/
+	/* å®è£
+ä¾å­ */
+	} T_TCP_CCEP;
+
+/*
+ *  åççæç¨ TCP åä»å£
+ */
+
+typedef struct t_tcp_crep {
+	/* æ¨æº */
+	ATR		repatr;		/* åä»å£å±æ§		*/
+	T_IPV4EP	myaddr;		/* èªåã®ã¢ãã¬ã¹	*/
+	/* å®è£
+ä¾å­ */
+	} T_TCP_CREP;
+
+/*
+ *  åççæç¨ UDP éä¿¡ç«¯ç¹
+ */
+
+typedef struct t_udp_ccep {
+	/* æ¨æº */
+	ATR		cepatr;		/* UDP éä¿¡ç«¯ç¹å±æ§		*/
+	T_IPV4EP	myaddr;		/* èªåã®ã¢ãã¬ã¹		*/
+	FP		callback;	/* ã³ã¼ã«ããã¯é¢æ°		*/
+	/* å®è£
+ä¾å­ */
+	} T_UDP_CCEP;
+
+/*
+ *  TINET ç¬èª API
+ */
+
+extern char *ipv42str (char *buf, const T_IN4_ADDR *p_ipaddr);
+extern uint_t in4_get_maxnum_ifaddr (void);
+extern const T_IN4_ADDR *in4_get_ifaddr (int_t index);
+extern ER in4_add_ifaddr (T_IN4_ADDR addr, T_IN4_ADDR mask);
+extern ER in4_add_route (int_t index, T_IN4_ADDR target,
+                                      T_IN4_ADDR mask, T_IN4_ADDR gateway);
+
+#endif	/* of #ifndef _IN4_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in4_subr.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in4_subr.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in4_subr.c	(revision 331)
@@ -0,0 +1,535 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include "kernel_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "kernel_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+//#include <net/ppp_ipcp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+
+#include <net/if_var.h>
+
+#if defined(_IP4_CFG)
+
+#if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0
+
+/*
+ *  in_rtinit -- ã«ã¼ãã£ã³ã°è¡¨ãåæåããã
+ */
+
+void
+in_rtinit (void)
+{
+	int_t ix;
+
+	for (ix = 0; ix < NUM_IN4_STATIC_ROUTE_ENTRY; ix ++)
+		routing4_tbl[ix].flags = IN_RTF_DEFINED;
+
+	for ( ; ix < NUM_IN4_ROUTE_ENTRY; ix ++)
+		routing4_tbl[ix].flags = 0;
+	}
+
+/*
+ *  in_rtnewentry -- æ°ããã¨ã³ããªãç²å¾ããã
+ */
+
+T_IN4_RTENTRY *
+in_rtnewentry (uint8_t flags, uint32_t tmo)
+{
+	SYSTIM		now;
+	T_IN4_RTENTRY	*rt, *frt = NULL;
+	int_t		ix;
+
+	/* ç©ºãã¨ã³ããªãæ¢ãã*/
+	for (ix = NUM_IN4_STATIC_ROUTE_ENTRY; ix < NUM_IN4_ROUTE_ENTRY; ix ++) {
+		rt = &routing4_tbl[ix];
+		if ((routing4_tbl[ix].flags & IN_RTF_DEFINED) == 0) {
+			frt = rt;
+			break;
+			}
+		}
+
+	/* expire ã®åä½ã¯ [s]ã*/
+	syscall(get_tim(&now));
+	now /= SYSTIM_HZ;
+
+	if (frt == NULL) {
+		/* ç©ºãããªããã°ãæå¹æéããã£ã¨ãç­ãã¨ã³ããªãç©ºãã«ããã*/
+		T_IN4_RTENTRY	*srt = NULL;
+		int_t		diff, sdiff = INT_MAX;
+
+		syscall(wai_sem(SEM_IN4_ROUTING_TBL));
+		for (ix = NUM_IN4_STATIC_ROUTE_ENTRY; ix < NUM_IN4_ROUTE_ENTRY; ix ++) {
+			rt = &routing4_tbl[ix];
+			diff = (int_t)(rt->expire - now);
+			if (diff <= 0) {	/* rt->expire <= now */
+				/* æ¢ã«ãæå¹æéãéãã¦ããã*/
+				frt = rt;
+				break;
+				}
+			else if (diff < sdiff) {
+				srt = rt;
+				sdiff = diff;
+				}
+			}
+		if (frt == NULL)
+			frt = srt;
+		frt->flags = 0;
+		syscall(sig_sem(SEM_IN4_ROUTING_TBL));
+		}
+
+	frt->flags  = (uint8_t)(flags | IN_RTF_DEFINED);
+	frt->expire = now + tmo / SYSTIM_HZ;
+	return frt;
+	}
+
+/*
+ *  in_rttimer -- ã«ã¼ãã£ã³ã°è¡¨ã®ç®¡çã¿ã¤ãã¼
+ */
+
+void
+in_rttimer (void)
+{
+	SYSTIM	now;
+	int_t	ix;
+
+	/* expire ã®åä½ã¯ [s]ã*/
+	syscall(get_tim(&now));
+	now /= SYSTIM_HZ;
+
+	syscall(wai_sem(SEM_IN4_ROUTING_TBL));
+	for (ix = NUM_IN4_STATIC_ROUTE_ENTRY; ix < NUM_IN4_ROUTE_ENTRY; ix ++)
+		if ((routing4_tbl[ix].flags & IN_RTF_DEFINED) &&
+		    (int_t)(routing4_tbl[ix].expire - now) <= 0)
+			routing4_tbl[ix].flags = 0;
+	syscall(sig_sem(SEM_IN4_ROUTING_TBL));
+	}
+
+#endif	/* of #if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0 */
+
+/*
+ *  in4_get_maxnum_ifaddr -- ã¤ã³ã¿ãã§ã¼ã¹ã«è¨­å®å¯è½ãªæå¤§ã¢ãã¬ã¹æ°ãè¿ãã
+ */
+
+uint_t
+in4_get_maxnum_ifaddr (void)
+{
+	return 1;
+	}
+
+/*
+ *  in4_get_ifaddr -- ã¤ã³ã¿ãã§ã¼ã¹ã«è¨­å®ããã¦ããã¢ãã¬ã¹ãè¿ãã
+ */
+
+const T_IN4_ADDR *
+in4_get_ifaddr (int_t index)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+
+	return &ifp->in4_ifaddr.addr;
+	}
+
+/*
+ *  in4_set_header -- IPv4 ããããè¨­å®ããã
+ */
+
+ER
+in4_set_header (T_NET_BUF *nbuf, uint_t len,
+                T_IN4_ADDR *dstaddr, T_IN4_ADDR *srcaddr, uint8_t proto, uint8_t ttl)
+{
+	T_IP4_HDR	*ip4h = GET_IP4_HDR(nbuf);
+	T_IFNET		*ifp = IF_GET_IFNET();
+
+	/* IP ããããè¨­å®ããã*/
+	ip4h->vhl	= IP4_MAKE_VHL(IPV4_VERSION, IP4_HDR_SIZE >> 2);
+	ip4h->len	= htons(IP4_HDR_SIZE + len);
+	ip4h->proto	= proto;
+	ip4h->ttl	= ttl;
+	ip4h->type	= 0;
+	ip4h->id	= ip4h->flg_off = ip4h->sum = 0;
+
+	/* IP ã¢ãã¬ã¹ãè¨­å®ããã*/
+	ip4h->dst	= htonl(*dstaddr);
+
+	if (srcaddr == NULL || *srcaddr == IPV4_ADDRANY)
+		ip4h->src = htonl(ifp->in4_ifaddr.addr);
+	else
+		ip4h->src = htonl(*srcaddr);
+
+	return E_OK;
+	}
+
+/*
+ *  in4_get_datagram -- IPv4 ãã¼ã¿ã°ã©ã ãç²å¾ããããããè¨­å®ããã
+ */
+
+ER
+in4_get_datagram (T_NET_BUF **nbuf, uint_t len, uint_t maxlen,
+                  T_IN4_ADDR *dstaddr, T_IN4_ADDR *srcaddr,
+                  uint8_t proto, uint8_t ttl, ATR nbatr, TMO tmout)
+{
+	ER	error;
+	uint_t	align;
+
+	/* ãã¼ã¿é·ã 4 ãªã¯ãããå¢çã«èª¿æ´ããã*/
+	align = (len + 3) >> 2 << 2;
+
+	/* ãããã¯ã¼ã¯ãããã¡ãç²å¾ããã*/
+	if ((error = tget_net_buf_ex(nbuf, (uint_t)(IF_IP4_HDR_SIZE + align),
+	                                   (uint_t)(IF_IP4_HDR_SIZE + maxlen), nbatr, tmout)) != E_OK)
+		return error;
+
+	/*
+	 *  ããå¤§ããªãµã¤ãºã®ãããã¯ã¼ã¯ãããã¡ãç²å¾ããå ´åã®ã¿é·ããèª¿æ´ããã
+	 *  ããå°ããªãµã¤ãºã®ãããã¯ã¼ã¯ãããã¡ã®ç²å¾ã¯ãéä¿¡ã¦ã£ã³ããããã¡ã®
+	 *  çã³ãã¼æ©è½ã§ä½¿ç¨ãããå®éã«éä¿¡ããã¾ã§ããã¼ã¿ãµã¤ãºã¯æ±ºå®ã§ããªãã
+	 */
+	if ((nbatr & NBA_SEARCH_ASCENT) != 0)
+		(*nbuf)->len = (uint16_t)(IF_IP4_HDR_SIZE + len);
+
+	/* IP ããããè¨­å®ããã*/
+	if ((error = in4_set_header(*nbuf, len, dstaddr, srcaddr, proto, ttl)) != E_OK)
+		return error;
+
+	/* 4 ãªã¯ãããå¢çã¾ã§ããã£ã³ã°ã§åããã*/
+	if (align > len)
+		memset((GET_IP4_SDU(*nbuf) + len), 0, (size_t)(align - len));
+
+	return E_OK;
+	}
+
+/*
+ *  in4_cksum -- IPv4 ã®ãã©ã³ã¹ãã¼ãå±¤ãããã®ãã§ãã¯ãµã ãè¨ç®ããã
+ *
+ *  æ³¨æ: æ»ãå¤ã¯ãããã¯ã¼ã¯ãã¤ããªã¼ã
+ */
+
+uint16_t
+in4_cksum (T_NET_BUF *nbuf, uint8_t proto, uint_t off, uint_t len)
+{
+	uint32_t	sum;
+	uint_t		align;
+
+	/* 4 ãªã¯ãããå¢çã®ãã¼ã¿é· */
+	align = (len + 3) >> 2 << 2;
+
+	/* 4 ãªã¯ãããå¢çã¾ã§ããã£ã³ã°ã§åããã*/
+	if (align > len)
+		memset((uint8_t*)nbuf->buf + off + len, 0, (size_t)(align - len));
+
+	sum = in_cksum_sum(nbuf->buf + off, align)
+	    + in_cksum_sum(&GET_IP4_HDR(nbuf)->src, sizeof(T_IN4_ADDR) * 2)
+	    + len + proto;
+	sum = in_cksum_carry(sum);
+
+	return (uint16_t)(~htons((uint16_t)sum));
+	}
+
+/*
+ *  in_cksum -- ãã§ãã¯ãµã è¨ç®é¢æ°ãIPv4ãICMPv4 ç¨
+ *
+ *  æ³¨æ: data ã¯ 4 ãªã¯ãããåä½ã§ããã£ã³ã°ãããã¨ã
+ *        data ã 2 ãªã¯ãããåä½ã«ã¢ã©ã¤ã³ããã¦ããªãã¨
+ *        ä¾å¤ãçºçããå¯è½æ§ãããã
+ *        len  ã¯ 4 ãªã¯ãããåä½ã«ã¢ã©ã¤ã³ããã¦ãããã¨ã
+ *
+ *        æ»ãå¤ã¯ãããã¯ã¼ã¯ãã¤ããªã¼ã
+ */
+
+uint16_t
+in_cksum (void *data, uint_t len /*ãªã¯ãããåä½*/)
+{
+	uint16_t	sum;
+
+	sum = (uint16_t)in_cksum_carry(in_cksum_sum(data, len));
+	return (uint16_t)(~htons(sum));
+	}
+
+/*
+ *  in4_is_dstaddr_accept -- å®å
+ã¢ãã¬ã¹ã¨ãã¦æ­£ããããã§ãã¯ããã
+ *
+ *    æ³¨æ: dstaddr ã¯ã
+ *          TINET-1.2 ãããããã¯ã¼ã¯ãã¤ããªã¼ãã
+ *          TINET-1.1 ã¾ã§ã¯ããã¹ããã¤ããªã¼ã
+ */
+
+bool_t
+in4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_IN4_ADDR *dstaddr)
+{
+	if (*myaddr == IPV4_ADDRANY)
+		return ntohl(*dstaddr) == IF_GET_IFNET()->in4_ifaddr.addr;
+	else
+		return ntohl(*dstaddr) == *myaddr;
+	}
+
+/*
+ *  inn4_is_dstaddr_accept -- å®å
+ã¢ãã¬ã¹ã¨ãã¦æ­£ããããã§ãã¯ããã
+ *
+ *    æ³¨æ: dstaddr ã¯ã
+ *          TINET-1.2 ãããããã¯ã¼ã¯ãã¤ããªã¼ãã
+ *          TINET-1.1 ã¾ã§ã¯ããã¹ããã¤ããªã¼ã
+ */
+
+bool_t
+inn4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_NET_BUF *nbuf)
+{
+	T_IP4_HDR	*iph;
+
+	iph  = GET_IP4_HDR(nbuf);
+	if (*myaddr == IPV4_ADDRANY)
+		return ntohl(iph->dst) == IF_GET_IFNET()->in4_ifaddr.addr;
+	else
+		return ntohl(iph->dst) == *myaddr;
+	}
+
+/*
+ * in4_addrwithifp -- å®å
+ã¢ãã¬ã¹ã«ãµããããéä¿¡å
+ã¢ãã¬ã¹ãã
+ *                   ãããã¯ã¼ã¯ã¤ã³ã¿ãã§ã¼ã¹ããæ¢ç´¢ããã
+ *                   in6_addrwithifp ãã·ãã¥ã¬ã¼ãããã ãã§ã
+ *                   ã¨ã©ã¼ãè¿ããã¨ã¯ãªãã
+ */
+
+T_IN4_ADDR *
+in4_addrwithifp (T_IFNET *ifp, T_IN4_ADDR *src, T_IN4_ADDR *dst)
+{
+	*src = ifp->in4_ifaddr.addr;
+	return src;
+	}
+
+/*
+ *  in4_add_ifaddr -- ã¤ã³ã¿ãã§ã¼ã¹ã« IPv4 ã¢ãã¬ã¹ãè¨­å®ããã
+ */
+
+ER
+in4_add_ifaddr (T_IN4_ADDR addr, T_IN4_ADDR mask)
+{
+	T_IFNET	*ifp = IF_GET_IFNET();
+
+	ifp->in4_ifaddr.addr = addr;
+	ifp->in4_ifaddr.mask = mask;
+	return E_OK;
+	}
+
+#if NUM_IN4_ROUTE_ENTRY > 0
+
+/*
+ *  in4_add_route -- çµè·¯è¡¨ã«ã¨ã³ããªãè¨­å®ããã
+ */
+
+ER
+in4_add_route (int_t index, T_IN4_ADDR target, T_IN4_ADDR mask, T_IN4_ADDR gateway)
+{
+
+	if (0 <= index && index < NUM_IN4_STATIC_ROUTE_ENTRY) {
+		routing4_tbl[index].target  = target;
+		routing4_tbl[index].mask    = mask;
+		routing4_tbl[index].gateway = gateway;
+		return E_OK;
+		}
+	else
+		return E_PAR;
+	}
+
+#endif	/* of #if NUM_IN4_ROUTE_ENTRY > 0 */
+
+/*
+ *  in4_rtalloc -- ã«ã¼ãã£ã³ã°è¡¨ãæ¢ç´¢ããã
+ */
+
+T_IN4_ADDR
+in4_rtalloc (T_IN4_ADDR dst)
+{
+	int_t ix;
+#ifdef ETHER_CFG_MULTICAST
+	if(IN4_IS_ADDR_MULTICAST(dst))
+		return dst;
+#endif /* of #ifdef ETHER_CFG_MULTICAST */
+	for (ix = NUM_IN4_ROUTE_ENTRY; ix --; )
+		if ((routing4_tbl[ix].flags & IN_RTF_DEFINED) &&
+		    (dst & routing4_tbl[ix].mask) == routing4_tbl[ix].target) {
+			if (routing4_tbl[ix].gateway == 0)
+				return dst;
+			else {
+				return routing4_tbl[ix].gateway;
+				}
+			}
+	return dst;
+	}
+
+#if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0
+
+/*
+ *  in4_rtredirect -- ã«ã¼ãã£ã³ã°è¡¨ã«ã¨ã³ããªãç»é²ããã
+ *
+ *    æ³¨æ: å¼æ° tmo ã®åä½ã¯ [ms]ã
+ */
+
+void
+in4_rtredirect (T_IN4_ADDR gateway, T_IN4_ADDR target, uint8_t flags, uint32_t tmo)
+{
+	T_IN4_RTENTRY	*frt;
+
+	frt = in_rtnewentry(flags, tmo);
+	frt->gateway    = gateway;
+	frt->target     = target;
+	frt->mask       = 0xffffffff;
+	}
+
+#endif	/* of #if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0 */
+
+/*
+ *  in4_timer -- IPv4 å
+±éã¿ã¤ãã¼
+ *
+ *    1ç§å¨æã§èµ·åãããã
+ */
+
+static void
+in4_timer (void *ignore)
+{
+#if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0
+
+	in_rttimer();
+
+#endif	/* of #if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0 */
+
+#ifdef IP4_CFG_FRAGMENT
+
+	ip_frag_timer();
+
+#endif	/* of #ifdef IP4_CFG_FRAGMENT */
+
+	timeout(in4_timer, NULL, IN_TIMER_TMO);
+	}
+
+/*
+ *  in4_init -- IPv4 å
+±éæ©è½ãåæåããã
+ */
+
+void
+in4_init (void)
+{
+#if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0
+
+	in_rtinit();
+
+#endif	/* of #if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0 */
+
+#ifdef SUPPORT_IGMP
+	igmp_init();
+#endif /* of #ifdef SUPPORT_IGMP */
+
+	timeout(in4_timer, NULL, IN_TIMER_TMO);
+	}
+
+#endif	/* of #if defined(_IP4_CFG) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in4_var.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in4_var.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in4_var.h	(revision 331)
@@ -0,0 +1,215 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1985, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)in_var.h	8.2 (Berkeley) 1/9/95
+ * $FreeBSD: src/sys/netinet/in_var.h,v 1.29.2.1 1999/08/29 16:29:38 peter Exp $
+ */
+ 
+#ifndef _IN4_VAR_H_
+#define _IN4_VAR_H_
+
+#ifndef _MACRO_ONLY
+
+/*
+ *  ã¤ã³ã¿ãã§ã¼ã¹ã¢ãã¬ã¹æ§é ä½
+ */
+
+typedef struct t_in4_ifaddr {
+	T_IN4_ADDR		addr;		/* IPv4 ã¢ãã¬ã¹	*/
+	T_IN4_ADDR		mask;		/* ãµãããããã¹ã¯	*/
+	} T_IN4_IFADDR;
+
+/*
+ *  ã«ã¼ãã£ã³ã°è¡¨ã¨ã³ããªæ§é ä½
+ */
+
+typedef struct t_in4_rtentry {
+	T_IN4_ADDR	target;		/* ç®æ¨ãããã¯ã¼ã¯ã¢ãã¬ã¹			*/
+	T_IN4_ADDR	mask;		/* ç®æ¨ãããã¯ã¼ã¯ã¢ãã¬ã¹ã®ãµãããããã¹ã¯	*/
+	T_IN4_ADDR	gateway;	/* ã²ã¼ãã¦ã§ã¤ã® IP ã¢ãã¬ã¹			*/
+	uint32_t	expire;		/* æå¹æéãåããæå» [s]			*/
+	uint8_t		flags;		/* ãã©ã°					*/
+	} T_IN4_RTENTRY;
+/*
+ *  TINET 1.1 ã¨ã®äºææ§ã®ããã®å®ç¾©
+ *
+ *  TINET 1.5 ã¨ã®äºææ§ã®ããã«å®ç¾©ãç¡å¹ã«ããã
+ */
+
+#if 0
+#ifdef NUM_ROUTE_ENTRY
+
+#define NUM_IN4_ROUTE_ENTRY		NUM_ROUTE_ENTRY
+#define NUM_IN4_STATIC_ROUTE_ENTRY	NUM_ROUTE_ENTRY
+#define NUM_IN4_REDIRECT_ROUTE_ENTRY	0
+#define T_RT_ENTRY			T_IN4_RTENTRY
+
+#endif	/* of #ifdef NUM_ROUTE_ENTRY */
+#endif
+
+/*
+ *  ã«ã¼ãã£ã³ã°è¡¨
+ */
+
+#ifdef SUPPORT_INET4
+
+extern T_IN4_RTENTRY routing4_tbl[];
+
+#endif	/* of #ifdef SUPPORT_INET4 */
+
+/*
+ *  åæ¹åç
+§
+ */
+
+#ifndef T_NET_BUF_DEFINED
+typedef struct t_net_buf T_NET_BUF;
+#define T_NET_BUF_DEFINED
+#endif
+
+#ifndef T_IFNET_DEFINED
+typedef struct t_ifnet T_IFNET;
+#define T_IFNET_DEFINED
+#endif
+
+/*
+ *  é¢æ°ã·ãã¥ã¬ã¼ã·ã§ã³ãã¯ã­
+ */
+
+#define IN4_COPY_TO_HOST(dst,nbuf)	(*(dst)=ntohl(GET_IP4_HDR(nbuf)->src))
+
+/*
+ *  é¢æ°
+ */
+
+extern void ip_input (T_NET_BUF *data);
+extern ER in4_set_header (T_NET_BUF *nbuf, uint_t len,
+                          T_IN4_ADDR *dstaddr, T_IN4_ADDR *srcaddr, uint8_t proto, uint8_t ttl);
+extern ER in4_get_datagram (T_NET_BUF **nbuf, uint_t len, uint_t maxlen,
+                            T_IN4_ADDR *dstaddr, T_IN4_ADDR *srcaddr,
+                            uint8_t proto, uint8_t ttl, ATR nbatr, TMO tmout);
+extern uint16_t in4_cksum (T_NET_BUF *nbuf, uint8_t proto, uint_t off, uint_t len);
+extern T_IN4_ADDR in4_rtalloc (T_IN4_ADDR dst);
+extern void in4_rtredirect (T_IN4_ADDR gateway, T_IN4_ADDR target, uint8_t flags, uint32_t tmo);
+extern void in4_init (void);
+extern T_IN4_ADDR *in4_addrwithifp (T_IFNET *ifp, T_IN4_ADDR *src, T_IN4_ADDR *dst);
+extern const T_NET_BUF**ip_get_frag_queue (void);
+
+/*
+ *  in4_is_dstaddr_accept -- å®å
+ã¢ãã¬ã¹ã¨ãã¦æ­£ããããã§ãã¯ããã
+ *
+ *    æ³¨æ: dstaddr ã¯ã
+ *          TINET-1.2 ãããããã¯ã¼ã¯ãã¤ããªã¼ãã
+ *          TINET-1.1 ã¾ã§ã¯ããã¹ããã¤ããªã¼ã
+ */
+extern bool_t in4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_IN4_ADDR *dstaddr);
+extern bool_t inn4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_NET_BUF *input);
+
+/*
+ *  in_cksum -- ãã§ãã¯ãµã è¨ç®é¢æ°ãIPv4ãICMPv4 ç¨
+ *
+ *  æ³¨æ: data ã¯ 4 ãªã¯ãããåä½ã§ããã£ã³ã°ãããã¨ã
+ *        data ã 2 ãªã¯ãããåä½ã«ã¢ã©ã¤ã³ããã¦ããªãã¨
+ *        ä¾å¤ãçºçããå¯è½æ§ãããã
+ *        len  ã¯ 4 ãªã¯ãããåä½ã«ã¢ã©ã¤ã³ããã¦ãããã¨ã
+ */
+extern uint16_t in_cksum(void *data, uint_t len /*ãªã¯ãããåä½*/);
+
+/*
+ *  in_cksum_sum -- ãã§ãã¯ãµã ã®åè¨è¨ç®é¢æ°
+ *
+ *  æ³¨æ: data ã¯ 4 ãªã¯ãããåä½ã§ããã£ã³ã°ãããã¨ã
+ *        data ã 2 ãªã¯ãããåä½ã«ã¢ã©ã¤ã³ããã¦ããªãã¨
+ *        ä¾å¤ãçºçããå¯è½æ§ãããã
+ *        len  ã¯ 4 ãªã¯ãããåä½ã«ã¢ã©ã¤ã³ããã¦ãããã¨ã
+ */
+extern uint32_t in_cksum_sum (void *data, uint_t len /*ãªã¯ãããåä½*/);
+
+/*
+ *  in_cksum_carry -- ãã§ãã¯ãµã ã®æ¡ä¸ãè¨ç®é¢æ°
+ *
+ *  æ³¨æ: data ã¯ 4 ãªã¯ãããåä½ã§ããã£ã³ã°ãããã¨ã
+ *        data ã 2 ãªã¯ãããåä½ã«ã¢ã©ã¤ã³ããã¦ããªãã¨
+ *        ä¾å¤ãçºçããå¯è½æ§ãããã
+ *        len  ã¯ 4 ãªã¯ãããåä½ã«ã¢ã©ã¤ã³ããã¦ãããã¨ã
+ */
+extern uint32_t in_cksum_carry (uint32_t sum);
+
+#endif	/* of #ifndef _MACRO_ONLY */
+
+#endif	/* of #ifndef _IN4_VAR_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in_itron.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in_itron.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in_itron.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in_rename.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in_rename.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in_rename.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -66,10 +66,8 @@
 #define tcp_drop		_tinet_tcp_drop
 #define tcp_respond		_tinet_tcp_respond
-#define tcp_set_header		_tinet_tcp_set_header
 #define	tcp_get_segment		_tinet_tcp_get_segment
 #define tcp_rexmt_val		_tinet_tcp_rexmt_val
 #define tcp_init_cep		_tinet_tcp_init_cep
 #define tcp_notify		_tinet_tcp_notify
-#define tcp_find_cep		_tinet_tcp_find_cep
 #define tcp_alloc_auto_port	_tinet_tcp_alloc_auto_port
 #define tcp_alloc_port		_tinet_tcp_alloc_port
@@ -83,4 +81,9 @@
 #define tcp_output_trace	_tinet_tcp_output_trace
 #define tcp_input_trace		_tinet_tcp_input_trace
+#define tcp_find_cep		_tinet_tcp_find_cep
+#define tcp_find_twcep		_tinet_tcp_find_twcep
+#define tcp_is_addr_accept	_tinet_tcp_is_addr_accept
+#define tcp_move_twcep		_tinet_tcp_move_twcep
+#define tcpn_get_segment	_tinet_tcpn_get_segment
 
 /* netinet/tcp_subr_cs.c */
@@ -136,5 +139,6 @@
 /* tcp_cfg.c */
 
-#define tcp_rep			_tinet_tcp_rep
+#define tcp6_rep		_tinet_tcp6_rep
+#define tcp4_rep		_tinet_tcp4_rep
 #define tcp_cep			_tinet_tcp_cep
 #define tcp_twcep		_tinet_tcp_twcep
@@ -146,10 +150,21 @@
 /* netinet/udp_input.c */
 
-#define udp_input		_tinet_udp_input
+#define udp6_reply_no_port	_tinet_udp6_reply_no_port
+#define udp6_input_select	_tinet_udp6_input_select
+#define udp6_input		_tinet_udp6_input
+#define udp4_reply_no_port	_tinet_udp4_reply_no_port
+#define udp4_input_select	_tinet_udp4_input_select
+#define udp4_input		_tinet_udp4_input
 
 /* netinet/udp_subr.c */
 
-#define udp_alloc_port		_tinet_udp_alloc_port
-#define udp_alloc_auto_port	_tinet_udp_alloc_auto_port
+#define udp6_alloc_port		_tinet_udp6_alloc_port
+#define udp6_alloc_auto_port	_tinet_udp6_alloc_auto_port
+#define udp6_notify		_tinet_udp6_notify
+#define udp6_find_cep		_tinet_udp6_find_cep
+#define udp4_alloc_port		_tinet_udp4_alloc_port
+#define udp4_alloc_auto_port	_tinet_udp4_alloc_auto_port
+#define udp4_notify		_tinet_udp4_notify
+#define udp4_find_cep		_tinet_udp4_find_cep
 
 /* netinet/udp_usrreq.c */
@@ -164,5 +179,6 @@
 /* udp_cfg.c */
 
-#define udp_cep			_tinet_udp_cep
+#define udp6_cep		_tinet_udp6_cep
+#define udp4_cep		_tinet_udp4_cep
 #define tmax_udp_cepid		_tinet_tmax_udp_cepid
 #define tmax_udp_ccepid		_tinet_tmax_udp_cepid	/* TINET 1.3 との互換性のための定義 */
@@ -188,18 +204,33 @@
 /* netinet/in_subr.c */
 
+#define inn_addrwithifp		_tinet_inn_addrwithifp
+#define in_cksum_carry		_tinet_in_cksum_carry
+#define inn_is_addr_multicast	_tinet_inn_is_addr_multicast
+#define inn_get_datagram	_tinet_inn_get_datagram
+#define inn_is_dstaddr_accept	_tinet_inn_is_dstaddr_accept
+#define ip_exchg_addr		_tinet_ip_exchg_addr
+#define inn_copy_to_host	_tinet_inn_copy_to_host
+#define in_cksum_sum		_tinet_in_cksum_sum
+#define inn_are_net_srcaddr_equal	\
+				_tinet_inn_are_net_srcaddr_equal
+
+/* netinet/in4_subr.c */
+
+#define in4_add_ifaddr		_tinet_in4_add_ifaddr
 #define in4_set_header		_tinet_in4_set_header
+#define inn4_is_dstaddr_accept	_tinet_inn4_is_dstaddr_accept
+#define in4_rtredirect		_tinet_in4_rtredirect
+#define in_rtnewentry		_tinet_in_rtnewentry
+#define in_cksum		_tinet_in_cksum
+#define	in4_addrwithifp		_tinet_in4_addrwithifp
+#define in4_rtalloc		_tinet_in4_rtalloc
+#define in4_init		_tinet_in4_init
+#define in_rttimer		_tinet_in_rttimer
+#define in4_get_ifaddr		_tinet_in4_get_ifaddr
 #define in4_get_datagram	_tinet_in4_get_datagram
+#define in4_is_dstaddr_accept	_tinet_in4_is_dstaddr_accept
 #define in4_cksum		_tinet_in4_cksum
-#define in4_rtalloc		_tinet_in4_rtalloc
-#define in4_rtredirect		_tinet_in4_rtredirect
-#define in4_init		_tinet_in4_init
-#define in4_is_dstaddr_accept	_tinet_in4_is_dstaddr_accept
+#define in_rtinit		_tinet_in_rtinit
 #define in4_ifawithifp		_tinet_in4_ifawithifp
-#define in_cksum		_tinet_in_cksum
-#define in_cksum_carry		_tinet_in_cksum_carry
-#define in_cksum_sum		_tinet_in_cksum_sum
-#define in_rtnewentry		_tinet_in_rtnewentry
-#define in_rtinit		_tinet_in_rtinit
-#define in_rttimer		_tinet_in_rttimer
 
 /* netinet/if_ether.c */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in_subr.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in_subr.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in_subr.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -71,5 +71,4 @@
 #include <kernel.h>
 #include <sil.h>
-#include <t_syslog.h>
 #include "kernel_cfg.h"
 
@@ -91,6 +90,6 @@
 #include <net/if_ppp.h>
 #include <net/ethernet.h>
-#include <net/ppp_ipcp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_var.h>
 #include <net/net_buf.h>
@@ -98,33 +97,122 @@
 
 #include <netinet/in.h>
-#include <netinet6/in6.h>
 #include <netinet/in_var.h>
-#include <netinet/in_itron.h>
 #include <netinet/ip.h>
 #include <netinet/ip_var.h>
-#include <netinet/tcp_timer.h>
+#include <netinet/in_itron.h>
 
 #include <net/if_var.h>
 
-#if defined(SUPPORT_INET4)
-
-/*
- *  in4_get_ifaddr -- インタフェースに設定されているアドレスを返す。
- */
-
-const T_IN4_ADDR *
-in4_get_ifaddr (int_t index)
-{
-	T_IFNET		*ifp = IF_GET_IFNET();
-
-	return &ifp->in_ifaddr.addr;
-	}
-
-/*
- *  ip2str -- IPv4 アドレスを文字列に変換する。
+/*
+ *  in_cksum_sum -- チェックサムの合計計算関数
+ *
+ *  注意: data は 4 オクテット単位でパディングすること。
+ *        data が 2 オクテット単位にアラインされていないと
+ *        例外が発生する可能性がある。
+ *        len  は 4 オクテット単位にアラインされていること。
+ *
+ *        戻り値はホストバイトオーダ
+ */
+
+uint32_t
+in_cksum_sum (void *data, uint_t len /*オクテット単位*/)
+{
+	uint32_t sum = 0;
+
+	for ( ; len > 0; len -= 2) {
+		sum += *((uint16_t*)data);
+		data = (uint8_t*)data + 2;
+		}
+
+#if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN
+	return sum;
+#elif _NET_CFG_BYTE_ORDER == _NET_CFG_LITTLE_ENDIAN
+	return ((sum >> 8) & 0xffff) + ((sum & 0xff) << 8) + ((sum >> 24) & 0xff);
+#endif	/* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
+
+	}
+
+/*
+ *  in_cksum_carry -- チェックサムの桁上げ計算関数
+ *
+ *  注意: data は 4 オクテット単位でパディングすること。
+ *        data が 2 オクテット単位にアラインされていないと
+ *        例外が発生する可能性がある。
+ *        len  は 4 オクテット単位にアラインされていること。
+ */
+
+uint32_t
+in_cksum_carry (uint32_t sum)
+{
+	uint32_t	carry;
+
+	while (sum >= 0x00010000) {
+		carry = sum >> 16;
+		sum   = (sum & 0xffff) + carry;
+		}
+
+	return sum;
+	}
+
+/*
+ *  in_strtfn -- API 機能コードの文字表現を返す。
+ */
+
+typedef struct t_strtfn {
+	FN		fncd;	/* API 機能コード	*/
+	const char	*str;	/* 文字表現		*/
+	} T_STRTFN;
+
+const T_STRTFN strtfn[] = {
+	{ TEV_TCP_RCV_OOB,	"TEV_TCP_RCV_OOB" },
+	{ TFN_TCP_DEL_REP,	"TFN_TCP_DEL_REP" },
+	{ TFN_TCP_CRE_CEP,	"TFN_TCP_CRE_CEP" },
+	{ TFN_TCP_DEL_CEP,	"TFN_TCP_DEL_CEP" },
+	{ TFN_TCP_ACP_CEP,	"TFN_TCP_ACP_CEP" },
+	{ TFN_TCP_CON_CEP,	"TFN_TCP_CON_CEP" },
+	{ TFN_TCP_SHT_CEP,	"TFN_TCP_SHT_CEP" },
+	{ TFN_TCP_CLS_CEP,	"TFN_TCP_CLS_CEP" },
+	{ TFN_TCP_SND_DAT,	"TFN_TCP_SND_DAT" },
+	{ TFN_TCP_RCV_DAT,	"TFN_TCP_RCV_DAT" },
+	{ TFN_TCP_GET_BUF,	"TFN_TCP_GET_BUF" },
+	{ TFN_TCP_SND_BUF,	"TFN_TCP_SND_BUF" },
+	{ TFN_TCP_RCV_BUF,	"TFN_TCP_RCV_BUF" },
+	{ TFN_TCP_REL_BUF,	"TFN_TCP_REL_BUF" },
+	{ TFN_TCP_SND_OOB,	"TFN_TCP_SND_OOB" },
+	{ TFN_TCP_RCV_OOB,	"TFN_TCP_RCV_OOB" },
+	{ TFN_TCP_CAN_CEP,	"TFN_TCP_CAN_CEP" },
+	{ TFN_TCP_SET_OPT,	"TFN_TCP_SET_OPT" },
+	{ TFN_TCP_GET_OPT,	"TFN_TCP_GET_OPT" },
+	{ TFN_TCP_ALL,		"TFN_TCP_ALL"     },
+
+	{ TEV_UDP_RCV_DAT,	"TEV_UDP_RCV_DAT" },
+	{ TFN_UDP_DEL_CEP,	"TFN_UDP_DEL_CEP" },
+	{ TFN_UDP_SND_DAT,	"TFN_UDP_SND_DAT" },
+	{ TFN_UDP_RCV_DAT,	"TFN_UDP_RCV_DAT" },
+	{ TFN_UDP_CAN_CEP,	"TFN_UDP_CAN_CEP" },
+	{ TFN_UDP_SET_OPT,	"TFN_UDP_SET_OPT" },
+	{ TFN_UDP_GET_OPT,	"TFN_UDP_GET_OPT" },
+	};
+
+const char *
+in_strtfn (FN fncd)
+{
+	int_t	ix;
+
+	for (ix = sizeof(strtfn) / sizeof(T_STRTFN); ix -- > 0; )
+		if (strtfn[ix].fncd == fncd)
+			return strtfn[ix].str;
+
+	return "unknown TFN";
+	}
+
+#if defined(_IP4_CFG)
+
+/*
+ *  ipv42str -- IPv4 アドレスを文字列に変換する。
  */
 
 char *
-ip2str (char *buf, const T_IN4_ADDR *ipaddr)
+ipv42str (char *buf, const T_IN4_ADDR *ipaddr)
 {
 	static char	addr_sbuf[NUM_IPV4ADDR_STR_BUFF][sizeof("123.123.123.123")];
@@ -153,515 +241,271 @@
 	}
 
-/*
- *  in4_set_header -- IPv4 ヘッダを設定する。
+#endif	/* of #if defined(_IP4_CFG) */
+
+/*
+ *  in6_is_addr_ipv4mapped -- IPv4 射影アドレスである事を検査する。
+ */
+
+bool_t
+in6_is_addr_ipv4mapped (const T_IN6_ADDR *addr)
+{
+	return IN6_IS_ADDR_V4MAPPED(addr);
+	}
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+
+/*
+ *  ip_exchg_addr -- IP アドレスを交換する。
+ */
+
+static void
+ip6_exchg_addr (T_NET_BUF *nbuf)
+{
+	T_IP6_HDR	*iph;
+	T_IN6_ADDR	ipaddr;
+
+	iph  = GET_IP6_HDR(nbuf);
+
+	/* IPv6 アドレスを交換する。*/
+	ipaddr = iph->src;
+	iph->src = iph->dst;
+	iph->dst = ipaddr;
+	}
+
+static void
+ip4_exchg_addr (T_NET_BUF *nbuf)
+{
+	T_IP4_HDR	*iph;
+	T_IN4_ADDR	ipaddr;
+
+	iph  = GET_IP4_HDR(nbuf);
+
+	/* IPv4 アドレスを交換する。*/
+	ipaddr = iph->src;
+	iph->src = iph->dst;
+	iph->dst = ipaddr;
+	}
+
+void
+ip_exchg_addr (T_NET_BUF *nbuf)
+{
+	if (GET_IP_VER(nbuf) == 6)
+		ip6_exchg_addr(nbuf);
+	else
+		ip4_exchg_addr(nbuf);
+	}
+
+#else	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
+
+/*
+ *  ip_exchg_addr -- IP アドレスを交換する。
+ */
+
+void
+ip_exchg_addr (T_NET_BUF *nbuf)
+{
+	T_IP_HDR	*iph;
+	T_IN_ADDR	ipaddr;
+
+	iph  = GET_IP_HDR(nbuf);
+
+	/* IP アドレスを交換する。*/
+	ipaddr = iph->src;
+	iph->src = iph->dst;
+	iph->dst = ipaddr;
+	}
+
+#endif	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+
+/*
+ *  inn_is_dstaddr_accept -- 宛先アドレスとして正しいかチェックする。
+ */
+
+bool_t
+inn_is_dstaddr_accept (T_IN6_ADDR *myaddr, T_NET_BUF *nbuf)
+{
+	if        (GET_IP_VER(nbuf)==IPV6_VERSION)
+		return INN6_IS_DSTADDR_ACCEPT(myaddr, nbuf);
+	else /*if (GET_IP_VER(nbuf)==IPV4_VERSION)*/ {
+		T_IP4_HDR	*ip4h;
+
+		ip4h  = GET_IP4_HDR(nbuf);
+		if (IN6_IS_ADDR_UNSPECIFIED(myaddr))
+			return ntohl(ip4h->dst) == IF_GET_IFNET()->in4_ifaddr.addr;
+		else {
+			T_IN6_ADDR	dstaddr;
+
+			return IN6_ARE_ADDR_EQUAL(myaddr, in6_make_ipv4mapped(&dstaddr, ntohl(ip4h->dst)));
+			}
+		}
+	}
+
+/*
+ *  inn_are_net_srcaddr_equal -- アドレスが同一かチェックする。
+ */
+
+bool_t
+inn_are_net_srcaddr_equal (T_IN6_ADDR *ipaddr, T_NET_BUF *nbuf)
+{
+	if        (GET_IP_VER(nbuf)==IPV6_VERSION)
+		return IN6_ARE_ADDR_EQUAL(ipaddr, &GET_IP6_HDR(nbuf)->src);
+	else /*if (GET_IP_VER(nbuf)==IPV4_VERSION)*/ {
+
+
+		T_IN6_ADDR	srcaddr;
+
+		return IN6_ARE_ADDR_EQUAL(ipaddr, in6_make_ipv4mapped(&srcaddr, ntohl(GET_IP4_HDR(nbuf)->src)));
+		}
+	}
+
+/*
+ *  inn_copy_to_host -- IP ヘッダからホスト表現変換して、IP アドレスをコピーする。
+ */
+
+void
+inn_copy_to_host (T_IN6_ADDR *dst, T_NET_BUF *nbuf)
+{
+	if        (GET_IP_VER(nbuf)==IPV6_VERSION)
+		memcpy(dst, &GET_IP6_HDR(nbuf)->src, sizeof(T_IN6_ADDR));
+	else /*if (GET_IP_VER(nbuf)==IPV4_VERSION)*/
+		in6_make_ipv4mapped(dst, ntohl(GET_IP4_HDR(nbuf)->src));
+
+	}
+
+/*
+ *  inn_get_datagram -- IPv6/IPv4 データグラムを獲得し、ヘッダを設定する。
  */
 
 ER
-in4_set_header (T_NET_BUF *nbuf, uint_t len,
-                T_IN4_ADDR *dstaddr, T_IN4_ADDR *srcaddr, uint8_t proto, uint8_t ttl)
-{
-	T_IP4_HDR	*ip4h = GET_IP4_HDR(nbuf);
-	T_IFNET		*ifp = IF_GET_IFNET();
-
-	/* IP ヘッダを設定する。*/
-	ip4h->vhl	= IP4_MAKE_VHL(IPV4_VERSION, IP4_HDR_SIZE >> 2);
-	ip4h->len	= htons(IP4_HDR_SIZE + len);
-	ip4h->proto	= proto;
-	ip4h->ttl	= ttl;
-	ip4h->type	= 0;
-	ip4h->id	= ip4h->flg_off = ip4h->sum = 0;
-
-	/* IP アドレスを設定する。*/
-	ip4h->dst	= htonl(*dstaddr);
-
-	if (srcaddr == NULL || *srcaddr == IPV4_ADDRANY)
-		ip4h->src = htonl(ifp->in_ifaddr.addr);
+inn_get_datagram (T_NET_BUF **nbuf, uint_t len, uint_t maxlen,
+                  T_IN6_ADDR *dstaddr, T_IN6_ADDR *srcaddr,
+                  uint8_t next, uint8_t hlim, ATR nbatr, TMO tmout)
+{
+	if (IN6_IS_ADDR_V4MAPPED(dstaddr)) {
+		T_IN4_ADDR ip4dstaddr, ip4srcaddr;
+
+		ip4dstaddr = ntohl(dstaddr->s6_addr32[3]);
+		if (IN6_IS_ADDR_UNSPECIFIED(srcaddr))
+			ip4srcaddr = IF_GET_IFNET()->in4_ifaddr.addr;
+		else
+			ip4srcaddr = ntohl(srcaddr->s6_addr32[3]);
+
+		return in4_get_datagram(nbuf, len, maxlen, &ip4dstaddr, &ip4srcaddr, next, hlim, nbatr, tmout);
+		}
 	else
-		ip4h->src = htonl(*srcaddr);
-
-	return E_OK;
-	}
-
-/*
- *  in4_get_datagram -- IPv4 データグラムを獲得し、ヘッダを設定する。
- */
-
-ER
-in4_get_datagram (T_NET_BUF **nbuf, uint_t len, uint_t maxlen,
-                  T_IN4_ADDR *dstaddr, T_IN4_ADDR *srcaddr,
-                  uint8_t proto, uint8_t ttl, ATR nbatr, TMO tmout)
-{
-	ER	error;
-	uint_t	align;
-
-	/* データ長を 4 オクテット境界に調整する。*/
-	align = (len + 3) >> 2 << 2;
-
-	/* ネットワークバッファを獲得する。*/
-	if ((error = tget_net_buf_ex(nbuf, (uint_t)(IF_IP4_HDR_SIZE + align),
-	                                   (uint_t)(IF_IP4_HDR_SIZE + maxlen), nbatr, tmout)) != E_OK)
-		return error;
-
-	/*
-	 *  より大きなサイズのネットワークバッファを獲得する場合のみ長さを調整する。
-	 *  より小さなサイズのネットワークバッファの獲得は、送信ウィンドバッファの
-	 *  省コピー機能で使用され、実際に送信するまで、データサイズは決定できない。
-	 */
-	if ((nbatr & NBA_SEARCH_ASCENT) != 0)
-		(*nbuf)->len = (uint16_t)(IF_IP4_HDR_SIZE + len);
-
-	/* IP ヘッダを設定する。*/
-	if ((error = in4_set_header(*nbuf, len, dstaddr, srcaddr, proto, ttl)) != E_OK)
-		return error;
-
-	/* 4 オクテット境界までパディングで埋める。*/
-	if (align > len)
-		memset((GET_IP4_SDU(*nbuf) + len), 0, (size_t)(align - len));
-
-	return E_OK;
-	}
-
-/*
- *  in4_cksum -- IPv4 のトランスポート層ヘッダのチェックサムを計算する。
- *
- *  注意: 戻り値はネットワークバイトオーダ
- */
+		return in6_get_datagram(nbuf, len, maxlen, dstaddr, srcaddr, next, hlim, nbatr, tmout);
+	}
+
+/*
+ * inn_addrwithifp -- 宛先アドレスにふさわしい送信元アドレスを、
+ *                   ネットワークインタフェースから探索する。
+ */
+
+T_IN6_ADDR *
+inn_addrwithifp (T_IFNET *ifp, T_IN6_ADDR *src, T_IN6_ADDR *dst)
+{
+	T_IN6_IFADDR *ifaddr;
+
+	if (IN6_IS_ADDR_V4MAPPED(dst))
+		return in6_make_ipv4mapped (src, ifp->in4_ifaddr.addr);
+	else if ((ifaddr = in6_ifawithifp(ifp, dst)) == NULL)
+		return NULL;
+	else {
+		*src = ifaddr->addr;
+		return src;
+		}
+	}
+
+/*
+ *  inn_is_addr_multicast -- アドレスがマルチキャストアドレスかチェックする。
+ */
+
+bool_t
+inn_is_addr_multicast (T_IN6_ADDR *addr)
+{
+
+	if (IN6_IS_ADDR_V4MAPPED(addr))
+		return IN4_IS_ADDR_MULTICAST(ntohl(addr->s6_addr32[3]));
+	else
+		return IN6_IS_ADDR_MULTICAST(addr);
+	}
+
+#endif	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
+
+/*
+ *  バイトオーダ関数の定義
+ *
+ *    tinet/net/net.h でもバイトオーダの定義を行っているが、
+ *    tinet/net/net.h をインクルードしない
+ *    アプリケーションプログラム用に
+ *    ターゲット依存しないバイトオーダ関数を定義する。
+ */
+
+#if defined(_NET_CFG_BYTE_ORDER)
+
+#undef ntohs
+#undef htons
+#undef ntohl
+#undef htonl
+
+#if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN
 
 uint16_t
-in4_cksum (T_NET_BUF *nbuf, uint8_t proto, uint_t off, uint_t len)
-{
-	uint32_t	sum;
-	uint_t		align;
-
-	/* 4 オクテット境界のデータ長 */
-	align = (len + 3) >> 2 << 2;
-
-	/* 4 オクテット境界までパディングで埋める。*/
-	if (align > len)
-		memset((uint8_t*)nbuf->buf + off + len, 0, (size_t)(align - len));
-
-	sum = in_cksum_sum(nbuf->buf + off, align)
-	    + in_cksum_sum(&GET_IP4_HDR(nbuf)->src, sizeof(T_IN4_ADDR) * 2)
-	    + len + proto;
-	sum = in_cksum_carry(sum);
-
-	return (uint16_t)(~htons((uint16_t)sum));
-	}
-
-/*
- *  in_cksum -- チェックサム計算関数、IPv4、ICMPv4 用
- *
- *  注意: data は 4 オクテット単位でパディングすること。
- *        data が 2 オクテット単位にアラインされていないと
- *        例外が発生する可能性がある。
- *        len  は 4 オクテット単位にアラインされていること。
- *
- *        戻り値はネットワークバイトオーダ
- */
+ntohs (uint16_t net)
+{
+	return net;
+	}
 
 uint16_t
-in_cksum (void *data, uint_t len /*オクテット単位*/)
-{
-	uint16_t	sum;
-
-	sum = (uint16_t)in_cksum_carry(in_cksum_sum(data, len));
-	return (uint16_t)(~htons(sum));
-	}
-
-/*
- *  in4_is_dstaddr_accept -- 宛先アドレスとして正しいかチェックする。
- *
- *    注意: dstaddr は、
- *          TINET-1.2 からネットワークバイトオーダ、
- *          TINET-1.1 までは、ホストバイトオーダ
- */
-
-bool_t
-in4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_IN4_ADDR *dstaddr)
-{
-	if (*myaddr == IPV4_ADDRANY)
-		return ntohl(*dstaddr) == IF_GET_IFNET()->in_ifaddr.addr;
-	else
-		return ntohl(*dstaddr) == *myaddr;
-	}
-
-/*
- * in4_ifawithifp -- 宛先アドレスにふさわしい送信元アドレスを、
- *                   ネットワークインタフェースから探索する。
- *                   in6_ifawithifp をシミュレートするだけで、
- *                   エラーを返すことはない。
- */
-
-T_IN4_IFADDR *
-in4_ifawithifp (T_IFNET *ifp, T_IN4_ADDR *dst)
-{
-	return &ifp->in_ifaddr;
-	}
-
-/*
- *  in4_add_ifaddr -- インタフェースに IPv4 アドレスを設定する。
- */
-
-ER
-in4_add_ifaddr (T_IN4_ADDR addr, T_IN4_ADDR mask)
-{
-	T_IFNET	*ifp = IF_GET_IFNET();
-
-	ifp->in_ifaddr.addr = addr;
-	ifp->in_ifaddr.mask = mask;
-	return E_OK;
-	}
-
-#if NUM_ROUTE_ENTRY > 0
-
-/*
- *  in4_add_route -- 経路表にエントリを設定する。
- */
-
-ER
-in4_add_route (int_t index, T_IN4_ADDR target, T_IN4_ADDR mask, T_IN4_ADDR gateway)
-{
-
-	if (0 <= index && index < NUM_STATIC_ROUTE_ENTRY) {
-		routing_tbl[index].target  = target;
-		routing_tbl[index].mask    = mask;
-		routing_tbl[index].gateway = gateway;
-		return E_OK;
-		}
-	else
-		return E_PAR;
-	}
-
-#endif	/* of #if NUM_ROUTE_ENTRY > 0 */
-
-/*
- *  in4_rtalloc -- ルーティング表を探索する。
- */
-
-T_IN4_ADDR
-in4_rtalloc (T_IN4_ADDR dst)
-{
-	int_t ix;
-
-	for (ix = NUM_ROUTE_ENTRY; ix --; )
-		if ((routing_tbl[ix].flags & IN_RTF_DEFINED) &&
-		    (dst & routing_tbl[ix].mask) == routing_tbl[ix].target) {
-			if (routing_tbl[ix].gateway == 0)
-				return dst;
-			else {
-				return routing_tbl[ix].gateway;
-				}
-			}
-	return dst;
-	}
-
-#if NUM_REDIRECT_ROUTE_ENTRY > 0
-
-/*
- *  in4_rtredirect -- ルーティング表にエントリを登録する。
- *
- *    注意: 引数 tmo の単位は [ms]。
- */
-
-void
-in4_rtredirect (T_IN4_ADDR gateway, T_IN4_ADDR target, uint8_t flags, uint32_t tmo)
-{
-	T_IN_RTENTRY	*frt;
-
-	frt = in_rtnewentry(flags, tmo);
-	frt->gateway    = gateway;
-	frt->target     = target;
-	frt->mask       = 0xffffffff;
-	}
-
-#endif	/* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
-
-/*
- *  in4_timer -- IPv4 共通タイマー
- *
- *    1秒周期で起動される。
- */
-
-static void
-in4_timer (void *ignore)
-{
-#if NUM_REDIRECT_ROUTE_ENTRY > 0
-
-	in_rttimer();
-
-#endif	/* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
-
-#ifdef IP4_CFG_FRAGMENT
-
-	ip_frag_timer();
-
-#endif	/* of #ifdef IP4_CFG_FRAGMENT */
-
-	timeout(in4_timer, NULL, IN_TIMER_TMO);
-	}
-
-/*
- *  in4_init -- IPv4 共通機能を初期化する。
- */
-
-void
-in4_init (void)
-{
-#if NUM_REDIRECT_ROUTE_ENTRY > 0
-
-	in_rtinit();
-
-#endif	/* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
-
-	timeout(in4_timer, NULL, IN_TIMER_TMO);
-	}
-
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if NUM_REDIRECT_ROUTE_ENTRY > 0
-
-/*
- *  in_rtinit -- ルーティング表を初期化する。
- */
-
-void
-in_rtinit (void)
-{
-	int_t ix;
-
-	for (ix = 0; ix < NUM_STATIC_ROUTE_ENTRY; ix ++)
-		routing_tbl[ix].flags = IN_RTF_DEFINED;
-
-	for ( ; ix < NUM_ROUTE_ENTRY; ix ++)
-		routing_tbl[ix].flags = 0;
-	}
-
-/*
- *  in_rtnewentry -- 新しいエントリを獲得する。
- */
-
-T_IN_RTENTRY *
-in_rtnewentry (uint8_t flags, uint32_t tmo)
-{
-	SYSTIM		now;
-	T_IN_RTENTRY	*rt, *frt = NULL;
-	int_t		ix;
-
-	/* 空きエントリを探す。*/
-	for (ix = NUM_STATIC_ROUTE_ENTRY; ix < NUM_ROUTE_ENTRY; ix ++) {
-		rt = &routing_tbl[ix];
-		if ((routing_tbl[ix].flags & IN_RTF_DEFINED) == 0) {
-			frt = rt;
-			break;
-			}
-		}
-
-	/* expire の単位は [s]。*/
-	syscall(get_tim(&now));
-	now /= SYSTIM_HZ;
-
-	if (frt == NULL) {
-		/* 空きがなければ、有効時間がもっとも短いエントリを空きにする。*/
-		T_IN_RTENTRY	*srt = NULL;
-		int_t		diff, sdiff = INT_MAX;
-
-		syscall(wai_sem(SEM_IN_ROUTING_TBL));
-		for (ix = NUM_STATIC_ROUTE_ENTRY; ix < NUM_ROUTE_ENTRY; ix ++) {
-			rt = &routing_tbl[ix];
-			diff = (int_t)(rt->expire - now);
-			if (diff <= 0) {	/* rt->expire <= now */
-				/* 既に、有効時間が過ぎている。*/
-				frt = rt;
-				break;
-				}
-			else if (diff < sdiff) {
-				srt = rt;
-				sdiff = diff;
-				}
-			}
-		if (frt == NULL)
-			frt = srt;
-		frt->flags = 0;
-		syscall(sig_sem(SEM_IN_ROUTING_TBL));
-		}
-
-	frt->flags  = (uint8_t)(flags | IN_RTF_DEFINED);
-	frt->expire = now + tmo / SYSTIM_HZ;
-	return frt;
-	}
-
-/*
- *  in_rttimer -- ルーティング表の管理タイマー
- */
-
-void
-in_rttimer (void)
-{
-	SYSTIM	now;
-	int_t	ix;
-
-	/* expire の単位は [s]。*/
-	syscall(get_tim(&now));
-	now /= SYSTIM_HZ;
-
-	syscall(wai_sem(SEM_IN_ROUTING_TBL));
-	for (ix = NUM_STATIC_ROUTE_ENTRY; ix < NUM_ROUTE_ENTRY; ix ++)
-		if ((routing_tbl[ix].flags & IN_RTF_DEFINED) &&
-		    (int_t)(routing_tbl[ix].expire - now) <= 0)
-			routing_tbl[ix].flags = 0;
-	syscall(sig_sem(SEM_IN_ROUTING_TBL));
-	}
-
-#endif	/* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
-
-/*
- *  in_cksum_sum -- チェックサムの合計計算関数
- *
- *  注意: data は 4 オクテット単位でパディングすること。
- *        data が 2 オクテット単位にアラインされていないと
- *        例外が発生する可能性がある。
- *        len  は 4 オクテット単位にアラインされていること。
- *
- *        戻り値はホストバイトオーダ
- */
+htons (uint16_t host)
+{
+	return host;
+	}
 
 uint32_t
-in_cksum_sum (void *data, uint_t len /*オクテット単位*/)
-{
-	uint32_t sum = 0;
-
-	for ( ; len > 0; len -= 2) {
-		sum += *((uint16_t*)data);
-		data = (uint8_t*)data + 2;
-		}
-
-#if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN
-	return sum;
-#elif _NET_CFG_BYTE_ORDER == _NET_CFG_LITTLE_ENDIAN
-	return ((sum >> 8) & 0xffff) + ((sum & 0xff) << 8) + ((sum >> 24) & 0xff);
+ntohl (uint32_t net)
+{
+	return net;
+	}
+
+uint32_t
+htonl (uint32_t host)
+{
+	return host;
+	}
+
+#elif _NET_CFG_BYTE_ORDER == _NET_CFG_LITTLE_ENDIAN	/* of #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
+
+uint16_t
+ntohs (uint16_t net)
+{
+	return NET_REV_ENDIAN_HWORD(net);
+	}
+
+uint16_t
+htons (uint16_t host)
+{
+	return NET_REV_ENDIAN_HWORD(host);
+	}
+
+uint32_t
+ntohl (uint32_t net)
+{
+	return NET_REV_ENDIAN_WORD(net);
+	}
+
+uint32_t
+htonl (uint32_t host)
+{
+	return NET_REV_ENDIAN_WORD(host);
+	}
+
+#else	/* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
+
+#error "_NET_CFG_BYTE_ORDER expected."
+
 #endif	/* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
 
-	}
-
-/*
- *  in_cksum_carry -- チェックサムの桁上げ計算関数
- *
- *  注意: data は 4 オクテット単位でパディングすること。
- *        data が 2 オクテット単位にアラインされていないと
- *        例外が発生する可能性がある。
- *        len  は 4 オクテット単位にアラインされていること。
- */
-
-uint32_t
-in_cksum_carry (uint32_t sum)
-{
-	uint32_t	carry;
-
-	while (sum >= 0x00010000) {
-		carry = sum >> 16;
-		sum   = (sum & 0xffff) + carry;
-		}
-
-	return sum;
-	}
-
-/*
- *  in_strtfn -- API 機能コードの文字表現を返す。
- */
-
-const char *
-in_strtfn (FN fncd)
-{
-	switch (fncd) {
-
-	/* TCP 関係 */
-
-	case TFN_TCP_CRE_REP:
-		return "TFN_TCP_CRE_REP";
-		break;
-	case TFN_TCP_DEL_REP:
-		return "TFN_TCP_DEL_REP";
-		break;
-	case TFN_TCP_CRE_CEP:
-		return "TFN_TCP_CRE_CEP";
-		break;
-	case TFN_TCP_DEL_CEP:
-		return "TFN_TCP_DEL_CEP";
-		break;
-	case TFN_TCP_ACP_CEP:
-		return "TFN_TCP_ACP_CEP";
-		break;
-	case TFN_TCP_CON_CEP:
-		return "TFN_TCP_CON_CEP";
-		break;
-	case TFN_TCP_SHT_CEP:
-		return "TFN_TCP_SHT_CEP";
-		break;
-	case TFN_TCP_CLS_CEP:
-		return "TFN_TCP_CLS_CEP";
-		break;
-	case TFN_TCP_SND_DAT:
-		return "TFN_TCP_SND_DAT";
-		break;
-	case TFN_TCP_RCV_DAT:
-		return "TFN_TCP_RCV_DAT";
-		break;
-	case TFN_TCP_GET_BUF:
-		return "TFN_TCP_GET_BUF";
-		break;
-	case TFN_TCP_SND_BUF:
-		return "TFN_TCP_SND_BUF";
-		break;
-	case TFN_TCP_RCV_BUF:
-		return "TFN_TCP_RCV_BUF";
-		break;
-	case TFN_TCP_REL_BUF:
-		return "TFN_TCP_REL_BUF";
-		break;
-	case TFN_TCP_SND_OOB:
-		return "TFN_TCP_SND_OOB";
-		break;
-	case TFN_TCP_RCV_OOB:
-		return "TFN_TCP_RCV_OOB";
-		break;
-	case TFN_TCP_CAN_CEP:
-		return "TFN_TCP_CAN_CEP";
-		break;
-	case TFN_TCP_SET_OPT:
-		return "TFN_TCP_SET_OPT";
-		break;
-	case TFN_TCP_GET_OPT:
-		return "TFN_TCP_GET_OPT";
-		break;
-	case TFN_TCP_ALL:
-		return "ALL";
-		break;
-
-	/* UDP 関係 */
-
-	case TFN_UDP_CRE_CEP:
-		return "TFN_UDP_CRE_CEP";
-		break;
-	case TFN_UDP_DEL_CEP:
-		return "TFN_UDP_DEL_CEP";
-		break;
-	case TFN_UDP_SND_DAT:
-		return "TFN_UDP_SND_DAT";
-		break;
-	case TFN_UDP_RCV_DAT:
-		return "TFN_UDP_RCV_DAT";
-		break;
-	case TFN_UDP_CAN_CEP:
-		return "TFN_UDP_CAN_CEP";
-		break;
-	case TFN_UDP_SET_OPT:
-		return "TFN_UDP_SET_OPT";
-		break;
-	case TFN_UDP_GET_OPT:
-		return "TFN_UDP_GET_OPT";
-		break;
-
-	default:
-		return "unknown TFN";
-		}
-	}
+#endif	/* of #if defined(_NET_CFG_BYTE_ORDER) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in_var.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in_var.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/in_var.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -71,9 +71,6 @@
 #define _IN_VAR_H_
 
-#if defined(SUPPORT_INET6)
-
+#include <netinet/in4_var.h>
 #include <netinet6/in6_var.h>
-
-#endif	/* of #if defined(SUPPORT_INET6) */
 
 /*
@@ -102,43 +99,4 @@
 
 /*
- *  インタフェースアドレス構造体
- */
-
-typedef struct t_in4_ifaddr {
-	T_IN4_ADDR		addr;		/* IPv4 アドレス	*/
-	T_IN4_ADDR		mask;		/* サブネットマスク	*/
-	} T_IN4_IFADDR;
-
-/*
- *  ルーティング表エントリ構造体
- */
-
-typedef struct t_in4_rtentry {
-	T_IN4_ADDR	target;		/* 目標ネットワークアドレス			*/
-	T_IN4_ADDR	mask;		/* 目標ネットワークアドレスのサブネットマスク	*/
-	T_IN4_ADDR	gateway;	/* ゲートウェイの IP アドレス			*/
-	uint32_t	expire;		/* 有効時間が切れる時刻 [s]			*/
-	uint8_t		flags;		/* フラグ					*/
-	} T_IN4_RTENTRY;
-
-/*
- *  TINET 1.1 との互換性のための定義
- */
-
-#ifdef NUM_ROUTE_ENTRY
-
-#define NUM_STATIC_ROUTE_ENTRY		NUM_ROUTE_ENTRY
-#define NUM_REDIRECT_ROUTE_ENTRY	0
-#define T_RT_ENTRY			T_IN_RTENTRY
-
-#else	/* of #ifdef NUM_ROUTE_ENTRY */
-
-#define NUM_ROUTE_ENTRY			\
-	(NUM_STATIC_ROUTE_ENTRY + NUM_REDIRECT_ROUTE_ENTRY)
-					/* ルーティング表のエントリ数	*/
-
-#endif	/* of #ifdef NUM_ROUTE_ENTRY */
-
-/*
  *  ルーティングエントリ状態フラグ
  */
@@ -151,97 +109,99 @@
  */
 
-#if defined(SUPPORT_INET4)
-
-#define IN_SET_HEADER(nbuf,len,dst,src,proto,ttl)	\
-					in4_set_header(nbuf,len,dst,src,proto,ttl)
+#if defined(_IP6_CFG)
+
+#define T_IN_ADDR			T_IN6_ADDR
+#define T_IPEP				T_IPV6EP
+#define IP_ADDRANY			IPV6_ADDRANY
+
+#elif defined(_IP4_CFG)	/* of #if defined(_IP6_CFG) */
+
+#define T_IN_ADDR			T_IN4_ADDR
+#define T_IPEP				T_IPV4EP
+#define IP_ADDRANY			IPV4_ADDRANY
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+#if defined(_IP6_CFG)
+
+#if defined(_IP4_CFG)
+
+#define IN_CKSUM(nbuf,proto,off,len)	(GET_IP_VER(nbuf)==IPV6_VERSION	\
+					?in6_cksum(nbuf,proto,off,len)	\
+					:in4_cksum(nbuf,proto,off,len))
+#define IN_IS_DSTADDR_ACCEPT(myaddr,nbuf)	\
+					inn_is_dstaddr_accept(myaddr,nbuf)
+#define IN_ARE_HDR_ADDR_EQUAL(nbuf)	(GET_IP_VER(nbuf)==IPV6_VERSION	\
+					?IN6_ARE_ADDR_EQUAL(&GET_IP6_HDR(nbuf)->dst,&GET_IP6_HDR(nbuf)->src)	\
+					:IN4_ARE_ADDR_EQUAL(&GET_IP4_HDR(nbuf)->dst,&GET_IP4_HDR(nbuf)->src))
+#define IN_ARE_NET_SRCADDR_EQUAL(ipaddr,nbuf)	\
+		    			inn_are_net_srcaddr_equal(ipaddr,nbuf)
+#define IN_COPY_TO_HOST(dst,nbuf)	inn_copy_to_host(dst,nbuf)
+#define IN_GET_DATAGRAM(nbuf,len,maxlen,dst,src,next,hlim,nbatr,tmout)	\
+					inn_get_datagram(nbuf,len,maxlen,dst,src,next,hlim,nbatr,tmout)
+#define IN_IS_ADDR_MULTICAST(addr)	inn_is_addr_multicast(addr)
+#define IN_IS_NET_ADDR_MULTICAST(nbuf)	IN_IS_ADDR_MULTICAST(&GET_IP6_HDR(nbuf)->dst)
+#define IN_ADDRWITHIFP(ifp,src,dst)	inn_addrwithifp(ifp,src,dst)
+#define IN_IS_ADDR_ANY(addr)		IN6_IS_ADDR_UNSPECIFIED(addr)
+
+#else	/* of #if defined(_IP4_CFG) */
+
+#define IN_CKSUM(nbuf,proto,off,len)	in6_cksum(nbuf,proto,off,len)
+#define IN_IS_DSTADDR_ACCEPT(myaddr,nbuf)	\
+					INN6_IS_DSTADDR_ACCEPT(myaddr,nbuf)
+#define IN_ARE_HDR_ADDR_EQUAL(nbuf)	IN6_ARE_ADDR_EQUAL(&GET_IP6_HDR(nbuf)->dst,&GET_IP6_HDR(nbuf)->src)
+#define IN_ARE_NET_SRCADDR_EQUAL(ipaddr,nbuf)	\
+		    			IN6_ARE_ADDR_EQUAL(ipaddr,&GET_IP6_HDR(nbuf)->src)
+#define IN_COPY_TO_HOST(dst,nbuf)	IN6_COPY_TO_HOST(dst, nbuf)
+#define IN_GET_DATAGRAM(nbuf,len,maxlen,dst,src,next,hlim,nbatr,tmout)	\
+					in6_get_datagram(nbuf,len,maxlen,dst,src,next,hlim,nbatr,tmout)
+#define IN_IS_ADDR_MULTICAST(addr)	IN6_IS_ADDR_MULTICAST(addr)
+#define IN_IS_NET_ADDR_MULTICAST(nbuf)	IN6_IS_ADDR_MULTICAST(&GET_IP6_HDR(nbuf)->dst)
+#define IN_ADDRWITHIFP(ifp,src,dst)	in6_addrwithifp(ifp,src,dst)
+#define IN_IS_ADDR_ANY(addr)		IN6_IS_ADDR_UNSPECIFIED(addr)
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#else	/* of #if defined(_IP6_CFG) */
+
+#if defined(_IP4_CFG)
+
+#define IN_CKSUM(nbuf,proto,off,len)	in4_cksum(nbuf,proto,off,len)
+#define IN_IS_DSTADDR_ACCEPT(myaddr,nbuf)	\
+					inn4_is_dstaddr_accept(myaddr,nbuf)
+#define IN_ARE_HDR_ADDR_EQUAL(nbuf)	IN4_ARE_ADDR_EQUAL(&GET_IP4_HDR(nbuf)->dst,&GET_IP4_HDR(nbuf)->src)
+#define IN_ARE_NET_SRCADDR_EQUAL(ipaddr,nbuf)	\
+					(*(ipaddr)==ntohl(GET_IP4_HDR(nbuf)->src))
+#define IN_COPY_TO_HOST(dst,nbuf)	IN4_COPY_TO_HOST(dst, nbuf)
 #define IN_GET_DATAGRAM(nbuf,len,maxlen, dst,src,proto,ttl,nbatr,tmout)	\
 					in4_get_datagram(nbuf,len,maxlen, dst,src,proto,ttl,nbatr,tmout)
-#define IN_CKSUM(nbuf,proto,off,len)	in4_cksum(nbuf,proto,off,len)
-#define IN_IS_DSTADDR_ACCEPT(myaddr,dstaddr)			\
-					in4_is_dstaddr_accept(myaddr,dstaddr)
-#define IN_IFAWITHIFP(ifp,dst)		in4_ifawithifp(ifp,dst)
-#define T_IN_IFADDR			T_IN4_IFADDR
-#define T_IN_RTENTRY			T_IN4_RTENTRY
-
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-/*
- *  ルーティング表
- */
-
-extern T_IN_RTENTRY routing_tbl[];
-
-/*
- *  前方参照
- */
-
-#ifndef T_NET_BUF_DEFINED
-typedef struct t_net_buf T_NET_BUF;
-#define T_NET_BUF_DEFINED
-#endif
-
-#ifndef T_IFNET_DEFINED
-typedef struct t_ifnet T_IFNET;
-#define T_IFNET_DEFINED
-#endif
+#define IN_IS_ADDR_MULTICAST(addr)	IN4_IS_ADDR_MULTICAST(*(addr))
+#define IN_IS_NET_ADDR_MULTICAST(nbuf)	IN4_IS_ADDR_MULTICAST(ntohl(GET_IP4_HDR(nbuf)->dst))
+#define IN_ADDRWITHIFP(ifp,src,dst)	in4_addrwithifp(ifp,src,dst)
+#define IN_IS_ADDR_ANY(addr)		IN4_IS_ADDR_ANY(addr)
+
+#else	/* of #if defined(_IP4_CFG) */
+
+#error "not implemented."
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+#ifndef _MACRO_ONLY
 
 /*
  *  関数
  */
-
-extern void ip_input (T_NET_BUF *data);
-extern ER in4_set_header (T_NET_BUF *nbuf, uint_t len,
-                          T_IN4_ADDR *dstaddr, T_IN4_ADDR *srcaddr, uint8_t proto, uint8_t ttl);
-extern ER in4_get_datagram (T_NET_BUF **nbuf, uint_t len, uint_t maxlen,
-                            T_IN4_ADDR *dstaddr, T_IN4_ADDR *srcaddr,
-                            uint8_t proto, uint8_t ttl, ATR nbatr, TMO tmout);
-extern uint16_t in4_cksum (T_NET_BUF *nbuf, uint8_t proto, uint_t off, uint_t len);
-extern T_IN4_ADDR in4_rtalloc (T_IN4_ADDR dst);
-extern void in4_rtredirect (T_IN4_ADDR gateway, T_IN4_ADDR target, uint8_t flags, uint32_t tmo);
-extern void in4_init (void);
-extern T_IN4_IFADDR *in4_ifawithifp (T_IFNET *ifp, T_IN4_ADDR *dst);
-extern T_IN_RTENTRY *in_rtnewentry (uint8_t flags, uint32_t tmo);
-extern void in_rttimer (void);
-extern void in_rtinit (void);
-extern const T_NET_BUF**ip_get_frag_queue (void);
-
-/*
- *  in4_is_dstaddr_accept -- 宛先アドレスとして正しいかチェックする。
- *
- *    注意: dstaddr は、
- *          TINET-1.2 からネットワークバイトオーダ、
- *          TINET-1.1 までは、ホストバイトオーダ
- */
-extern bool_t in4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_IN4_ADDR *dstaddr);
-
-/*
- *  in_cksum -- チェックサム計算関数、IPv4、ICMPv4 用
- *
- *  注意: data は 4 オクテット単位でパディングすること。
- *        data が 2 オクテット単位にアラインされていないと
- *        例外が発生する可能性がある。
- *        len  は 4 オクテット単位にアラインされていること。
- */
-extern uint16_t in_cksum(void *data, uint_t len /*オクテット単位*/);
-
-/*
- *  in_cksum_sum -- チェックサムの合計計算関数
- *
- *  注意: data は 4 オクテット単位でパディングすること。
- *        data が 2 オクテット単位にアラインされていないと
- *        例外が発生する可能性がある。
- *        len  は 4 オクテット単位にアラインされていること。
- */
-extern uint32_t in_cksum_sum (void *data, uint_t len /*オクテット単位*/);
-
-/*
- *  in_cksum_carry -- チェックサムの桁上げ計算関数
- *
- *  注意: data は 4 オクテット単位でパディングすること。
- *        data が 2 オクテット単位にアラインされていないと
- *        例外が発生する可能性がある。
- *        len  は 4 オクテット単位にアラインされていること。
- */
-extern uint32_t in_cksum_carry (uint32_t sum);
+extern bool_t	inn_is_dstaddr_accept (T_IN6_ADDR *myaddr, T_NET_BUF *nbuf);
+extern bool_t	inn_is_addr_multicast (T_IN6_ADDR *addr);
+extern bool_t	inn_are_net_srcaddr_equal (T_IN6_ADDR *ipaddr, T_NET_BUF *nbuf);
+extern void	inn_copy_to_host (T_IN6_ADDR *dst, T_NET_BUF *nbuf);
+extern ER	inn_get_datagram (T_NET_BUF **nbuf, uint_t len, uint_t maxlen,
+		                  T_IN6_ADDR *dstaddr, T_IN6_ADDR *srcaddr,
+		                  uint8_t next, uint8_t hlim, ATR nbatr, TMO tmout);
+extern T_IN6_ADDR *inn_addrwithifp (T_IFNET *ifp, T_IN6_ADDR *src, T_IN6_ADDR *dst);
+
+#endif	/* of #ifndef _MACRO_ONLY */
 
 #endif	/* of #ifndef _IN_VAR_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -36,5 +36,5 @@
  */
 
-#if defined(SUPPORT_INET4)
+#if defined(_IP4_CFG)
 
 #ifdef IP4_CFG_FRAGMENT
@@ -46,11 +46,11 @@
 #endif	/* of #ifdef IP4_CFG_FRAGMENT */
 
-#if NUM_REDIRECT_ROUTE_ENTRY > 0
+#if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0
 
 /* ルーティング表（向け直し）*/
 
-CRE_SEM(SEM_IN_ROUTING_TBL, { TA_TPRI, 1, 1 });
+CRE_SEM(SEM_IN4_ROUTING_TBL, { TA_TPRI, 1, 1 });
 
-#endif	/* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
+#endif	/* of #if NUM_IN4_REDIRECT_ROUTE_ENTRY > 0 */
 
-#endif	/* of #if defined(SUPPORT_INET4) */
+#endif	/* of #if defined(_IP4_CFG) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -71,4 +71,6 @@
 #define _IP4_H_
 
+#include <netinet/ip6.h>
+
 /*
  *  IPv4 の定義、RFC791 参照
@@ -134,5 +136,5 @@
 /* IPv4 と IPv6 をコンパイル時に選択するためのマクロ */
 
-#if defined(SUPPORT_INET4)
+#if !defined(_IP6_CFG) && defined(_IP4_CFG)
 
 #define IP_HDR_SIZE	IP4_HDR_SIZE
@@ -140,5 +142,5 @@
 #define IP_DEFTTL	IP4_DEFTTL
 
-#endif	/* of #if defined(SUPPORT_INET4) */
+#endif	/* of #if !defined(_IP6_CFG) && defined(_IP4_CFG) */
 
 #endif	/* of #ifndef _IP4_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip4_var.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip4_var.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip4_var.h	(revision 331)
@@ -0,0 +1,268 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)ip_var.h	8.2 (Berkeley) 1/9/95
+ * $FreeBSD: src/sys/netinet/ip_var.h,v 1.45.2.1 1999/08/29 16:29:51 peter Exp $
+ */
+ 
+#ifndef _IP4_VAR_H_
+#define _IP4_VAR_H_
+
+/*
+ *  IPv4 ãããã»ãã¤ã­ã¼ãã¢ã¯ã»ã¹ãã¯ã­
+ */
+
+#define IF_IP4_HDR_SIZE			(IF_HDR_SIZE + IP4_HDR_SIZE)
+
+#define GET_IP4_HDR(nbuf)		((T_IP4_HDR*)((nbuf)->buf + IF_HDR_SIZE))
+#define GET_IP4_SDU(nbuf)		((uint8_t*)((nbuf)->buf) + GET_IF_IP4_HDR_SIZE(nbuf))
+
+#define GET_IP4_HDR_SIZE(nbuf)		((uint8_t)IP4_VHL_HL(GET_IP4_HDR(nbuf)->vhl) << 2)
+#define GET_IP4_SDU_SIZE(nbuf)		(ntohs(GET_IP4_HDR(nbuf)->len) - GET_IP4_HDR_SIZE(nbuf))
+#define GET_IF_IP4_HDR_SIZE(nbuf)	(IF_HDR_SIZE + (GET_IP4_HDR_SIZE(nbuf)))
+
+#define SET_IP4_SDU_SIZE(nbuf,slen)	(GET_IP4_HDR(nbuf)->len=(uint16_t)htons((slen) + IP4_HDR_SIZE))
+
+/*
+ *  IP ã® MSS ãµã¤ãºã®ãããã¯ã¼ã¯ãããã¡
+ */
+
+typedef struct t_net_buf_ip_mss {
+	uint16_t	len;	/* ãã¼ã¿ã®é·ã		*/
+	uint8_t		idix;	/* mpfid ã®ã¤ã³ããã¯ã¹	*/
+	uint8_t		flags;	/* ãã©ã°		*/
+#ifdef IF_ETHER_NIC_NET_BUF_ALIGN
+	uint8_t		nalign[IF_ETHER_NIC_NET_BUF_ALIGN];
+#endif
+#if CPU_NET_ALIGN == 4 && IF_HDR_ALIGN != 4
+	uint8_t		halign[4 - IF_HDR_ALIGN];
+#endif
+	uint8_t		buf[IF_HDR_SIZE + IP4_MSS];
+				/* ãããã¡æ¬ä½		*/
+	} T_NET_BUF_IP_MSS;
+
+/*
+ *  65536 ãªã¯ããããµã¤ãºã®ãããã¯ã¼ã¯ãããã¡
+ */
+
+typedef struct t_net_buf4_65536 {
+	uint16_t	len;	/* ãã¼ã¿ã®é·ã		*/
+	uint8_t		idix;	/* mpfid ã®ã¤ã³ããã¯ã¹	*/
+	uint8_t		flags;	/* ãã©ã°		*/
+#ifdef IF_ETHER_NIC_NET_BUF_ALIGN
+	uint8_t		nalign[IF_ETHER_NIC_NET_BUF_ALIGN];
+#endif
+#if CPU_NET_ALIGN == 4 && IF_HDR_ALIGN != 4
+	uint8_t		halign[4 - IF_HDR_ALIGN];
+#endif
+	uint8_t		buf[IF_IP4_HDR_SIZE + 65536];
+				/* ãããã¡æ¬ä½		*/
+#if defined(IF_PDU_HDR_PADDING)
+	uint8_t		padding[IF_PDU_HDR_PADDING];
+#endif				/* ãããã®ä½å		*/
+	} T_NET_BUF4_65536;
+
+#ifdef IP4_CFG_FRAGMENT
+
+/*
+ *  åæ§æã­ã¥ã¼ç¨ IPv4 ãããã®å®ç¾©
+ */
+
+typedef struct t_qip4_hdr {
+	uint8_t		vhl;		/* version << 4 | header length >> 2	*/
+					/* length ã¯ 4 octets åä½		*/
+	uint8_t		type;		/* type of services			*/
+	uint16_t	len;		/* total length				*/
+
+	uint16_t	id;		/* identification			*/
+	uint16_t	flg_off;	/* fragment flag & offset		*/
+
+	uint8_t		ttl;		/* time to live				*/
+	uint8_t		proto;		/* protocol				*/
+	uint16_t	sum;		/* checksum				*/
+
+	uint32_t	src;		/* source address			*/
+
+	T_NET_BUF	*next;		/* æ¬¡ã® IPv4 ãã©ã°ã¡ã³ã			*/
+	} __attribute__((packed, aligned(2))) T_QIP4_HDR;
+
+#define QIP4_HDR_SIZE			(sizeof(T_QIP4_HDR))
+#define IF_QIP4_HDR_SIZE		(IF_HDR_SIZE + QIP4_HDR_SIZE)
+
+#define GET_QIP4_HDR(nbuf)		((T_QIP4_HDR*)((nbuf)->buf + IF_HDR_SIZE))
+#define GET_QIP4_SDU(nbuf)		((uint8_t*)(nbuf)->buf + GET_IF_QIP4_HDR_SIZE(nbuf))
+
+#define GET_QIP4_HDR_SIZE(iph)		((uint8_t)IP4_VHL_HL((iph)->vhl) << 2)
+#define GET_IF_QIP4_HDR_SIZE(nbuf)	(IF_HDR_SIZE + (GET_QIP4_HDR_SIZE(GET_QIP4_HDR(nbuf))))
+
+/*
+ *  ãã¼ã¿ã°ã©ã åæ§æç¨ãããã¯ã¼ã¯ãããã¡
+ */
+
+typedef struct t_net_buf4_reassm {
+	uint16_t	len;	/* ãã¼ã¿ã®é·ã		*/
+	uint8_t		idix;	/* mpfid ã®ã¤ã³ããã¯ã¹	*/
+	uint8_t		flags;	/* ãã©ã°		*/
+#ifdef IF_ETHER_NIC_NET_BUF_ALIGN
+	uint8_t		nalign[IF_ETHER_NIC_NET_BUF_ALIGN];
+#endif
+#if CPU_NET_ALIGN == 4 && IF_HDR_ALIGN != 4
+	uint8_t		align[4 - IF_HDR_ALIGN];
+#endif
+	uint8_t		buf[IP4_CFG_FRAG_REASSM_SIZE];
+				/* ãããã¡æ¬ä½		*/
+	} __attribute__((packed, aligned(2))) T_NET_BUF4_REASSM;
+
+#endif	/* of #ifdef IP4_CFG_FRAGMENT */
+
+/*
+ *  TCP ã®åæ§æã­ã¥ã¼ã«ããã IPv4 ãããã®å®ç¾©
+ */
+
+typedef struct t_ip4_tcp_q_hdr {
+	uint8_t		vhl;		/* version << 4 | header length >> 2	*/
+					/* length ã¯ 4 octets åä½		*/
+	uint8_t		type;		/* type of services			*/
+	uint16_t	len;		/* total length				*/
+
+	uint16_t	id;		/* identification			*/
+	uint16_t	flg_off;	/* fragment flag & offset		*/
+
+	uint8_t		ttl;		/* time to live				*/
+	uint8_t		proto;		/* protocol				*/
+	uint16_t	thoff;		/* TCP ãããã®ãªãã»ãã		*/
+
+	T_IN4_ADDR	src;		/* source address			*/
+	T_IN4_ADDR	dst;		/* destination address			*/
+	} __attribute__((packed, aligned(2))) T_IP4_TCP_Q_HDR;
+
+#ifdef SUPPORT_MIB
+
+/*
+ *  SNMP ã® ç®¡çæ
+å ±ãã¼ã¹ (MIB)
+ */
+
+typedef struct t_ip_stats {
+	uint32_t	ipInReceives;
+	uint32_t	ipInHdrErrors;
+	uint32_t	ipInAddrErrors;
+/*	uint32_t	ipForwDatagrams;*/
+	uint32_t	ipInUnknownProtos;
+/*	uint32_t	ipInDiscards;*/
+	uint32_t	ipInDelivers;
+	uint32_t	ipOutRequests;
+	uint32_t	ipOutDiscards;
+/*	uint32_t	ipOutNoRoutes;*/
+
+#ifdef IP4_CFG_FRAGMENT
+
+	uint32_t	ipReasmReqds;
+	uint32_t	ipReasmOKs;
+	uint32_t	ipReasmFails;
+	uint32_t	ipFragOKs;
+	uint32_t	ipFragFails;
+	uint32_t	ipFragCreates;
+
+#else	/* of #ifdef IP4_CFG_FRAGMENT */
+
+	uint32_t	ipReasmReqds;
+/*	uint32_t	ipReasmOKs;*/
+	uint32_t	ipReasmFails;
+/*	uint32_t	ipFragOKs;*/
+/*	uint32_t	ipFragFails;*/
+/*	uint32_t	ipFragCreates;*/
+
+#endif	/* of #ifdef IP4_CFG_FRAGMENT */
+
+} T_IP_STATS;
+
+extern T_IP_STATS ip_stats;
+
+#endif	/* of #ifdef SUPPORT_MIB */
+
+/*
+ *  é¢æ°
+ */
+
+extern void ip_frag_timer (void);
+extern void ip_init (void);
+extern ER ip_remove_options (T_NET_BUF *nbuf);
+extern ER ip_output (T_NET_BUF *nbuf, TMO tmout);
+extern void ip_exchg_addr (T_NET_BUF *nbuf);
+
+#endif	/* of #ifndef _IP4_VAR_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip6.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip6.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip6.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -102,6 +102,4 @@
 #define _IP6_H_
 
-#ifdef SUPPORT_INET6
-
 /*
  *  IPv6 の定義、RFC2460 参照
@@ -262,5 +260,5 @@
 
 /*
- *  IPv4 と IPv6 をコンパイル時に選択するためのマクロ
+ *  IPv6 と IPv4 をコンパイル時に選択するためのマクロ
  */
 
@@ -273,5 +271,5 @@
 /* ルータ通知を受信する場合は、通知された値 */
 
-#define IP_DEFTTL	ip6_defhlim
+#define IP6_DEFTTL	ip6_defhlim
 
 #else	/* #if NUM_ND6_DEF_RTR_ENTRY > 0 */
@@ -279,12 +277,17 @@
 /* ルータ通知を受信しない場合の値は既定値 */
 
-#define IP_DEFTTL	IPV6_DEFHLIM
+#define IP6_DEFTTL	IPV6_DEFHLIM
 
 #endif	/* #if NUM_ND6_DEF_RTR_ENTRY > 0 */
+
+/* IPv4 と IPv6 をコンパイル時に選択するためのマクロ */
+
+#ifdef _IP6_CFG
 
 #define IP_HDR_SIZE	IP6_HDR_SIZE
 #define T_IP_HDR	T_IP6_HDR
-
-#endif	/* of #ifdef SUPPORT_INET6 */
+#define IP_DEFTTL	IP6_DEFTTL
+
+#endif	/* of #ifdef _IP6_CFG */
 
 #endif	/* of #ifndef _IP6_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_icmp.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_icmp.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_icmp.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -76,4 +76,5 @@
 #include <t_syslog.h>
 #include "kernel_cfg.h"
+#include "tinet_cfg.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_ASP */
@@ -83,4 +84,5 @@
 #include <s_services.h>
 #include <t_services.h>
+#include "tinet_id.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_JSP */
@@ -95,4 +97,5 @@
 #include <net/ppp_ipcp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_timer.h>
@@ -106,6 +109,10 @@
 #include <netinet/icmp_var.h>
 #include <netinet/tcp.h>
-#include <netinet/tcp_timer.h>
 #include <netinet/tcp_var.h>
+#include <netinet/udp_var.h>
+
+#include <net/if_var.h>
+
+#if defined(_IP4_CFG)
 
 /*
@@ -130,4 +137,5 @@
 static void icmp_unreach (T_NET_BUF *input, uint_t ihoff);
 
+#if defined(NUM_REDIRECT_ROUTE_ENTRY)
 #if NUM_REDIRECT_ROUTE_ENTRY > 0
 
@@ -135,4 +143,5 @@
 
 #endif	/* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
+#endif	/* of #if defined(NUM_REDIRECT_ROUTE_ENTRY) */
 
 /*
@@ -147,32 +156,40 @@
 	T_IP4_HDR	*ip4h;
 	T_ICMP4_HDR	*icmp4h;
-	T_IN4_ADDR	addr;
+	T_IFNET		*ifp = IF_GET_IFNET();
 
 	NET_COUNT_MIB(icmp_stats.icmpInEchos, 1);
 
-	/* メッセージの型をエコー要求 (8) から エコー応答 (0) に	*/
-	/* 変更して送り返す。					*/
-
-	icmp4h = GET_ICMP4_HDR(input, ihoff);
-	icmp4h->type = ICMP4_ECHO_REPLY;
-
-	/* IP ヘッダの宛先と発信元を交換する。*/
-	ip4h      = GET_IP4_HDR(input);
-	addr      = ip4h->src;
-	ip4h->src = ip4h->dst;
-	ip4h->dst = addr;
-
-	/* チェックサムを計算する。*/
-	icmp4h->sum = 0;
-	icmp4h->sum = in_cksum(icmp4h,
-	                       (uint_t)(((input->len - GET_IF_IP4_HDR_SIZE(input)) + 3) >> 2 << 2));
-
-	/* 送信する。*/
-	NET_COUNT_ICMP4(net_count_icmp4.out_octets,
-	               input->len - GET_IF_IP4_HDR_SIZE(input));
-	NET_COUNT_ICMP4(net_count_icmp4.out_packets, 1);
-	NET_COUNT_MIB(icmp_stats.icmpOutMsgs, 1);
-	NET_COUNT_MIB(icmp_stats.icmpOutEchoReps, 1);
-	ip_output(input, TMO_ICMP_OUTPUT);
+	/* IPv4 アドレスが未定義の時は応答しない。*/
+	if (!IN4_IS_ADDR_ANY(&ifp->in4_ifaddr.addr)) {
+
+		/*
+		 *  メッセージの型をエコー要求 (8) から
+		 *  エコー応答 (0) に変更して送り返す。
+		 */
+
+		icmp4h = GET_ICMP4_HDR(input, ihoff);
+		icmp4h->type = ICMP4_ECHO_REPLY;
+
+		/*
+		 *  宛先アドレスは受信したメッセージの送信元アドレス。
+		 *  送信元アドレスは自 IPv4 アドレス。
+		 */
+		ip4h      = GET_IP4_HDR(input);
+		ip4h->dst = ip4h->src;
+		ip4h->src = htonl(ifp->in4_ifaddr.addr);
+
+		/* チェックサムを計算する。*/
+		icmp4h->sum = 0;
+		icmp4h->sum = in_cksum(icmp4h,
+		                       (uint_t)(((input->len - GET_IF_IP4_HDR_SIZE(input)) + 3) >> 2 << 2));
+
+		/* 送信する。*/
+		NET_COUNT_ICMP4(net_count_icmp4.out_octets,
+		               input->len - GET_IF_IP4_HDR_SIZE(input));
+		NET_COUNT_ICMP4(net_count_icmp4.out_packets, 1);
+		NET_COUNT_MIB(icmp_stats.icmpOutMsgs, 1);
+		NET_COUNT_MIB(icmp_stats.icmpOutEchoReps, 1);
+		ip_output(input, TMO_ICMP_OUTPUT);
+		}
 	}
 
@@ -212,13 +229,24 @@
 	code  = GET_ICMP4_HDR(input, ihoff)->code;
 	error = code2error[code];
-	if (ip4h->proto == IPPROTO_TCP) {
-
-#ifdef SUPPORT_TCP
+
+	/* 最終ヘッダが TCP/UDP のみ対応する。*/
+	if (ip4h->proto == IPPROTO_TCP || ip4h->proto == IPPROTO_UDP) {
 
 		memcpy(GET_IP4_HDR(input), ip4h, input->len - (IP4_HDR_SIZE + ICMP4_HDR_SIZE));
 		input->len -= IP4_HDR_SIZE + ICMP4_HDR_SIZE;
-		tcp_notify(input, error);
-
-#endif	/* of #ifdef SUPPORT_TCP */
+
+#if defined(SUPPORT_TCP)
+
+		if (ip4h->proto == IPPROTO_TCP)
+			tcp_notify(input, error);
+
+#endif	/* of #if defined(SUPPORT_TCP) */
+
+#if defined(SUPPORT_UDP) && TNUM_UDP4_CEPID > 0
+
+		if (ip4h->proto == IPPROTO_UDP)
+			udp4_notify(input, error);
+
+#endif	/* of #if defined(SUPPORT_UDP) && TNUM_UDP4_CEPID > 0 */
 
 		}
@@ -227,4 +255,5 @@
 	}
 
+#if defined(NUM_REDIRECT_ROUTE_ENTRY)
 #if NUM_REDIRECT_ROUTE_ENTRY > 0
 
@@ -264,4 +293,5 @@
 
 #endif	/* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
+#endif	/* of #if defined(NUM_REDIRECT_ROUTE_ENTRY) */
 
 /*
@@ -314,9 +344,9 @@
 	case ICMP4_ECHO_REPLY:
 
-#ifdef ICMP_CFG_CALLBACK_ECHO_REPLY
+#if defined(SUPPORT_INET4) && defined(ICMP_CFG_CALLBACK_ECHO_REPLY)
 
 		icmp_echo_reply(input, *offp);
 
-#endif	/* of #ifdef ICMP_CFG_CALLBACK_ECHO_REPLY */
+#endif	/* of #if defined(SUPPORT_INET4) && defined(ICMP_CFG_CALLBACK_ECHO_REPLY) */
 
 		break;
@@ -326,4 +356,5 @@
 	case ICMP4_REDIRECT:
 
+#if defined(NUM_REDIRECT_ROUTE_ENTRY)
 #if NUM_REDIRECT_ROUTE_ENTRY > 0
 
@@ -338,4 +369,10 @@
 
 #endif	/* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
+#else	/* of #if defined(NUM_REDIRECT_ROUTE_ENTRY) */
+
+		addr = ntohl(icmp4h->data.addr);
+		syslog(LOG_INFO, "[ICMP] redirect ignored, addr: %s.", ip2str(NULL, &addr));
+
+#endif	/* of #if defined(NUM_REDIRECT_ROUTE_ENTRY) */
 
 		break;
@@ -371,5 +408,5 @@
 
 	ip4h  = GET_IP4_HDR(input);
-	ip4hl = GET_IP4_HDR_SIZE(ip4h);
+	ip4hl = GET_IP4_HDR_SIZE(input);
 
 	/* 送信用の IP データグラムを獲得する。*/
@@ -378,5 +415,5 @@
 	else
 		len = 8;
-
+	
 	saddr = ntohl(ip4h->src);
 	if (in4_get_datagram(&output, (uint_t)(ICMP4_HDR_SIZE + ip4hl + len), 0,
@@ -417,2 +454,4 @@
 
 #endif	/* of #ifdef ICMP_REPLY_ERROR */
+
+#endif	/* of #if defined(_IP4_CFG) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_icmp.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_icmp.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_icmp.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -71,4 +71,6 @@
 #define _IP_ICMP_H_
 
+#include <netinet/icmp6.h>
+
 /*
  *  ICMP ヘッダの定義、RFC 792
@@ -96,7 +98,7 @@
 #define GET_ICMP4_SDU(nbuf,ihoff)	((uint8_t*)((nbuf)->buf) + ihoff + ICMP4_HDR_SIZE)
 
-#define GET_ICMP4_HDR_OFFSET(nbuf)	(GET_IF_IP_HDR_SIZE(nbuf))
+#define GET_ICMP4_HDR_OFFSET(nbuf)	(GET_IF_IP4_HDR_SIZE(nbuf))
 
-#define GET_IP4_ICMP4_HDR_SIZE(nbuf)	(GET_IP4_HDR_SIZE(GET_IP4_HDR(nbuf)) + ICMP4_HDR_SIZE)
+#define GET_IP4_ICMP4_HDR_SIZE(nbuf)	(GET_IP4_HDR_SIZE(nbuf) + ICMP4_HDR_SIZE)
 #define GET_IF_IP4_ICMP4_HDR_SIZE(nbuf)	(IF_HDR_SIZE + GET_IP4_ICMP4_HDR_SIZE(nbuf))
 
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_igmp.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_igmp.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_igmp.c	(revision 331)
@@ -0,0 +1,409 @@
+/*
+*  TINET (TCP/IP Protocol Stack)
+*
+*  Copyright (C) 2001-2012 by Dep. of Computer Science and Engineering
+*                   Tomakomai National College of Technology, JAPAN
+*
+*  ãLì ÒÍCÈºÌ (1)`(4) Ìð©CFree Software Foundation
+*  ÉæÁÄö\³êÄ¢é GNU General Public License Ì Version 2 ÉL
+*  q³êÄ¢éðð½·êÉÀèC{\tgEFAi{\tgEFA
+*  ðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»EüÏEÄzziÈºC
+*  pÆÄÔj·é±Æð³Åø·éD
+*  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+*       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+*      XR[hÉÜÜêÄ¢é±ÆD
+*  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+*      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+*      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+*      Ì³ÛØKèðfÚ·é±ÆD
+*  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+*      pÅ«È¢`ÅÄzz·éêÉÍCÌðð½·±ÆD
+*    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+*        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+*  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+*      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+*
+*  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+*  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄC»ÌKpÂ\«à
+*  ÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEFAÌpÉæè¼
+*  ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»ÌÓCðíÈ¢D
+*
+*  @(#) $Id$
+*/
+
+#include <string.h>
+
+#ifdef TARGET_KERNEL_ASP
+
+#include <kernel.h>
+#include <sil.h>
+#include <t_syslog.h>
+#include "kernel_cfg.h"
+#include "tinet_cfg.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_ASP */
+
+#ifdef TARGET_KERNEL_JSP
+
+#include <s_services.h>
+#include <t_services.h>
+#include "tinet_id.h"
+
+#endif	/* of #ifdef TARGET_KERNEL_JSP */
+
+#include <tinet_defs.h>
+#include <tinet_config.h>
+
+#include <net/if.h>
+#include <net/if_loop.h>
+#include <net/if_ppp.h>
+#include <net/ethernet.h>
+#include <net/ppp_ipcp.h>
+#include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_buf.h>
+#include <net/net_timer.h>
+#include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/udp_var.h>
+#include <netinet/ip_igmp.h>
+
+#include <net/if_var.h>
+#include <net/net_var.h>
+
+#ifdef SUPPORT_IGMP
+
+static T_IGMP_ENTRY igmp_groups[NUM_IGMP_ENTRY];
+static T_IN4_ADDR igmp_send_addrs[NUM_IGMP_ENTRY];
+
+static bool_t igmp_send_report_v2(T_IN4_ADDR dst);
+static uint16_t igmp_get_timer(T_IGMP_ENTRY *entry);
+
+ER igmp_set_loop(T_UDP_CEP *cep, uint8_t optval)
+{
+	switch (optval) {
+	case 0:
+		cep->igmp_loopback = false;
+		return E_OK;
+	case 1:
+		cep->igmp_loopback = true;
+		return E_OK;
+	}
+
+	return E_PAR;
+}
+
+ER igmp_get_loop(T_UDP_CEP *cep, uint8_t *optval)
+{
+	if (optval == NULL)
+		return E_PAR;
+
+	*optval = cep->igmp_loopback ? 1 : 0;
+
+	return E_OK;
+}
+
+ER igmp_set_ttl(T_UDP_CEP *cep, uint8_t optval)
+{
+	cep->igmp_ttl = optval;
+
+	return E_OK;
+}
+
+ER igmp_get_ttl(T_UDP_CEP *cep, uint8_t *optval)
+{
+	if (optval == NULL)
+		return E_PAR;
+
+	*optval = cep->igmp_ttl;
+
+	return E_OK;
+}
+
+ER igmp_set_if(T_UDP_CEP *cep, T_IN4_ADDR *optval)
+{
+	if (optval == NULL)
+		return E_PAR;
+
+	cep->igmp_mcaddr = *optval;
+
+	return E_OK;
+}
+
+ER igmp_get_if(T_UDP_CEP *cep, T_IN4_ADDR *optval)
+{
+	if (optval == NULL)
+		return E_PAR;
+
+	*optval = cep->igmp_mcaddr;
+
+	return E_OK;
+}
+
+ER igmp_add_membership(T_UDP_CEP *cep, T_IP_MREQ *optval)
+{
+	T_IGMP_ENTRY *entry = NULL;
+	int		i;
+	uint16_t	min;
+	T_IFNET	*ifp = IF_GET_IFNET();
+	ER ret = E_NOMEM;
+
+	if ((optval->imr_interface != IPV4_ADDRANY)
+		&& (optval->imr_interface != ifp->in4_ifaddr.addr))
+		return E_PAR;
+
+	syscall(wai_sem(SEM_IGMP_GROUP_LOCK));
+
+	for (i = 0; i < NUM_IGMP_ENTRY; i++) {
+		entry = &igmp_groups[i];
+		if (entry->timer == -1) {
+			entry->timer = igmp_get_timer(entry);
+			entry->ip_addr = optval->imr_multiaddr;
+			ret = E_OK;
+			break;
+		}
+	}
+
+	syscall(sig_sem(SEM_IGMP_GROUP_LOCK));
+
+	return ret;
+}
+
+ER igmp_drop_membership(T_UDP_CEP *cep, T_IP_MREQ *optval)
+{
+	T_IGMP_ENTRY *entry = NULL;
+	int		i;
+	uint16_t	min;
+	ER ret = E_PAR;
+	T_IFNET	*ifp = IF_GET_IFNET();
+
+	if ((optval->imr_interface != IPV4_ADDRANY)
+		&& (optval->imr_interface != ifp->in4_ifaddr.addr))
+		return E_PAR;
+
+	syscall(wai_sem(SEM_IGMP_GROUP_LOCK));
+
+	for (i = 0; i < NUM_IGMP_ENTRY; i++) {
+		entry = &igmp_groups[i];
+		if ((entry->timer >= 0) && (entry->ip_addr == optval->imr_multiaddr)) {
+			entry->timer = -1;
+			entry->ip_addr = 0;
+			ret = E_OK;
+			break;
+		}
+	}
+
+	syscall(sig_sem(SEM_IGMP_GROUP_LOCK));
+
+	return ret;
+}
+
+ER igmp_set_ip_msfilter(T_UDP_CEP *cep, const T_IP_MSFILTER *optval)
+{
+	return E_PAR;
+}
+
+ER igmp_get_ip_msfilter(T_UDP_CEP *cep, T_IP_MSFILTER *optval)
+{
+	return E_PAR;
+}
+
+uint_t igmp_input(T_NET_BUF **inputp, uint_t *offp, uint_t *nextp)
+{
+	T_NET_BUF	*input = *inputp;
+	T_IGMPV2_HDR	*igmph;
+	T_IN4_ADDR	addr;
+	uint_t		len, align;
+	T_IP4_HDR	*ip4h;
+	int i;
+	T_IGMP_ENTRY *entry;
+	bool_t ret;
+
+	NET_COUNT_IGMP(net_count_igmp.in_octets,
+		input->len - GET_IF_IP4_HDR_SIZE(input));
+	NET_COUNT_IGMP(net_count_igmp.in_packets, 1);
+
+	/* ICMP wb_Ì·³ð`FbN·éB*/
+	if (input->len < IF_IP4_IGMP_HDR_SIZE) {
+		NET_COUNT_IGMP(net_count_igmp.in_err_packets, 1);
+		NET_COUNT_MIB(igmp_stats.igmpInErrors, 1);
+		goto buf_rel;
+	}
+
+	igmph = (T_IGMPV2_HDR *)(input->buf + *offp);
+
+	/* 4 INebg«EÌf[^· */
+	len = input->len - *offp;
+	align = (len + 3) >> 2 << 2;
+
+	/* 4 INebg«EÜÅpfBOÅßéB*/
+	if (align > len)
+		memset((uint8_t*)input->buf + input->len, 0, (size_t)(align - len));
+
+	/* `FbNTðvZ·éB*/
+	if (in_cksum(igmph, align) != 0) {
+		NET_COUNT_IGMP(net_count_igmp.in_err_packets, 1);
+		goto buf_rel;
+	}
+
+	/* bZ[WÌ^Éæèªò·éB*/
+	switch (igmph->type) {
+	case IGMP_MEMBERSHIP_QUERY:
+		ip4h = GET_IP4_HDR(input);
+		ret = false;
+
+		/* QÁÌO[vAhX©çÌNG[Ìê */
+		syscall(wai_sem(SEM_IGMP_GROUP_LOCK));
+
+		for (i = 0; i < NUM_IGMP_ENTRY; i++) {
+			entry = &igmp_groups[i];
+			if ((entry->timer >= 0) && (entry->ip_addr == addr)) {
+				entry->resptime = igmph->time;
+				ret = true;
+				break;
+			}
+		}
+
+		syscall(sig_sem(SEM_IGMP_GROUP_LOCK));
+
+		if (ret) {
+			/* o[Vbv|[gðM */
+			igmp_send_report_v2(ip4h->src);
+		}
+		break;
+	}
+
+buf_rel:
+	syscall(rel_net_buf(input));
+	return IPPROTO_DONE;
+}
+
+static bool_t igmp_send_report_v2(T_IN4_ADDR dst)
+{
+	T_IGMPV2_HDR	*igmph;
+	T_NET_BUF		*output;
+	uint_t			len, align;
+
+	if (in4_get_datagram(&output, (uint_t)(IF_IP4_IGMP_HDR_SIZE + len), 0,
+		&dst, NULL, IPPROTO_IGMP, IP4_DEFTTL,
+		NBA_SEARCH_ASCENT, TMO_IGMP_OUTPUT) != E_OK)
+		return false;
+
+	/* IGMP wb_ðÝè·éB*/
+	igmph = GET_IGMPV2_HDR(output, IF_IP4_IGMP_HDR_OFFSET);
+	igmph->type = IGMP_MEMBERSHIP_REPORT_V2;
+	igmph->time = 0;
+	igmph->addr = dst;
+
+	/* 4 INebg«EÌf[^· */
+	align = (len + 3) >> 2 << 2;
+
+	/* 4 INebg«EÜÅpfBOÅßéB*/
+	if (align > len)
+		memset((uint8_t*)GET_IGMP_SDU(output, IF_IP4_IGMP_HDR_OFFSET) + IP4_HDR_SIZE + len,
+			0, (size_t)(align - len));
+
+	/* `FbNTðvZ·éB*/
+	igmph->sum = 0;
+	igmph->sum = in_cksum(igmph, (uint_t)(IF_IP4_IGMP_HDR_SIZE + align));
+
+	/* M·éB*/
+	NET_COUNT_IGMP(net_count_igmp.out_octets,
+		output->len - GET_IF_IP4_HDR_SIZE(output));
+	NET_COUNT_IGMP(net_count_igmp.out_packets, 1);
+	NET_COUNT_MIB(icmp_stats.icmpOutMsgs, 1);
+	NET_COUNT_MIB(icmp_stats.icmpOutDestUnreachs, 1);
+	ip_output(output, TMO_IGMP_OUTPUT);
+
+	return true;
+}
+
+/*
+*  igmp_timer -- IGMP ¤Ê^C}[
+*/
+static void igmp_timer(void *ignore)
+{
+	T_IGMP_ENTRY *entry = NULL;
+	int i, j = 0;
+
+	/* memset(igmp_send_addrs, 0, sizeof(igmp_send_addrs)); */
+
+	syscall(wai_sem(SEM_IGMP_GROUP_LOCK));
+
+	for (i = 0; i < NUM_IGMP_ENTRY; i++) {
+		entry = &igmp_groups[i];
+		if (entry->timer > 0)
+			entry->timer--;
+		if (entry->timer == 0) {
+			entry->timer = igmp_get_timer(entry);
+			igmp_send_addrs[j++] = entry->ip_addr;
+		}
+	}
+
+	syscall(sig_sem(SEM_IGMP_GROUP_LOCK));
+
+	for (i = 0; i < j; i++) {
+		igmp_send_report_v2(igmp_send_addrs[i]);
+	}
+
+	timeout(igmp_timer, NULL, NET_TIMER_HZ / 1);
+}
+
+/*
+*  igmp_init -- IGMP @\ðú»·éB
+*/
+
+void igmp_init(void)
+{
+	T_IGMP_ENTRY *entry = NULL;
+	int i;
+
+	for (i = 0; i < NUM_IGMP_ENTRY; i++) {
+		igmp_groups[i].timer = -1;
+	}
+
+	timeout(igmp_timer, NULL, NET_TIMER_HZ / 1);
+}
+
+bool_t igmp_is_joined_group(T_IN4_ADDR addr)
+{
+	T_IGMP_ENTRY *entry = NULL;
+	int		i;
+	bool_t ret = false;
+
+	syscall(wai_sem(SEM_IGMP_GROUP_LOCK));
+
+	for (i = 0; i < NUM_IGMP_ENTRY; i++) {
+		entry = &igmp_groups[i];
+		if ((entry->timer >= 0) && (entry->ip_addr == addr)) {
+			ret = true;
+			break;
+		}
+	}
+
+	syscall(sig_sem(SEM_IGMP_GROUP_LOCK));
+
+	return ret;
+}
+
+uint16_t igmp_get_timer(T_IGMP_ENTRY *entry)
+{
+	uint16_t time = entry->resptime;
+
+	if (time == 0)
+		time = 10;
+
+	return net_rand() / (0x7fffffff / time);
+}
+
+#endif /* of #ifdef SUPPORT_IGMP */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_igmp.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_igmp.cfg	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_igmp.cfg	(revision 331)
@@ -0,0 +1,49 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2012 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ãLì ÒÍCÈºÌ (1)`(4) Ìð©CFree Software Foundation 
+ *  ÉæÁÄö\³êÄ¢é GNU General Public License Ì Version 2 ÉL
+ *  q³êÄ¢éðð½·êÉÀèC{\tgEFAi{\tgEFA
+ *  ðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»EüÏEÄzziÈºC
+ *  pÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌðð½·±ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄC»ÌKpÂ\«à
+ *  ÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEFAÌpÉæè¼
+ *  ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»ÌÓCðíÈ¢D
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ *  IGMP RtBM
+[Vt@C
+ */
+
+#if defined(_IP4_CFG) && defined(SUPPORT_IGMP)
+
+/* IGMP O[vXVpZ}tH */
+
+CRE_SEM(SEM_IGMP_GROUP_LOCK, { TA_TPRI, 1, 1 });
+
+#endif	/* of #if defined(_IP4_CFG) && defined(SUPPORT_IGMP) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_igmp.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_igmp.h	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_igmp.h	(revision 331)
@@ -0,0 +1,184 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ *
+ *  Copyright (C) 2001-2012 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ãLì ÒÍCÈºÌ (1)`(4) Ìð©CFree Software Foundation
+ *  ÉæÁÄö\³êÄ¢é GNU General Public License Ì Version 2 ÉL
+ *  q³êÄ¢éðð½·êÉÀèC{\tgEFAi{\tgEFA
+ *  ðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»EüÏEÄzziÈºC
+ *  pÆÄÔj·é±Æð³Åø·éD
+ *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
+ *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
+ *      XR[hÉÜÜêÄ¢é±ÆD
+ *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
+gip
+ *      Ò}j
+AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
+ *      Ì³ÛØKèðfÚ·é±ÆD
+ *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
+ *      pÅ«È¢`ÅÄzz·éêÉÍCÌðð½·±ÆD
+ *    (a) ÄzzÉº¤hL
+gipÒ}j
+AÈÇjÉCãLÌ
+ *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
+ *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
+ *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
+ *
+ *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
+ *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄC»ÌKpÂ\«à
+ *  ÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEFAÌpÉæè¼
+ *  ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»ÌÓCðíÈ¢D
+ *
+ *  @(#) $Id$
+ */
+
+#ifndef _IP_IGMP_H_
+#define _IP_IGMP_H_
+
+#define NUM_IGMP_ENTRY				5	/* }`LXgO[vÌGg */
+
+#ifdef __CA850__
+#pragma pack(1)
+#elif __RX
+#pragma pack
+#elif _MSC_VER
+#pragma pack(push, 1)
+#endif
+
+ /*
+  *  IGMPv1 wb_Ìè`ARFC 1112
+  */
+
+typedef struct t_igmpv1_hdr
+{
+	uint8_t		type;		/* bZ[WÌ^	*/
+	uint8_t		unused;		/* ¢gp			*/
+	uint16_t	sum;		/* `FbNT		*/
+	T_IN4_ADDR	addr;		/* O[vAhX */
+} T_IGMPV1_HDR;
+
+/*
+*  IGMPv2 wb_Ìè`ARFC 2236
+*/
+
+typedef struct t_igmpv2_hdr
+{
+	uint8_t		type;		/* bZ[WÌ^	*/
+	uint8_t		time;		/* ÅåÔ		*/
+	uint16_t	sum;		/* `FbNT		*/
+	T_IN4_ADDR	addr;		/* O[vAhX */
+} T_IGMPV2_HDR;
+
+typedef struct t_igmpv3_query_hdr
+{
+	uint8_t		type;		/* bZ[WÌ^	*/
+	uint8_t		time;		/* ÅåÔ		*/
+	uint16_t	sum;		/* `FbNT		*/
+	T_IN4_ADDR	grpaddr;	/* O[vAhX */
+	uint8_t		sqrv;		/* StOAQuerier Robustness Value */
+	uint8_t		qqic;		/* Qurier's Query Interval Code */
+	uint16_t	num;		/* M³Ì */
+	T_IN4_ADDR	sdraddr;	/* M³AhX */
+} T_IGMPV3Q_HDR;
+
+typedef struct t_igmp_group_record
+{
+	uint8_t		type;		/* bZ[WÌ^	*/
+	uint8_t		len;		/* âf[^·		*/
+	uint16_t	num;		/* M³Ì */
+	T_IN4_ADDR	grpaddr;	/* O[vAhX */
+	T_IN4_ADDR	sdraddr;	/* M³AhX	*/
+							/* âf[^		*/
+} T_IGMP_GROUP_RECORD;
+
+typedef struct t_igmpv3_report_hdr
+{
+	uint8_t		type;		/* bZ[WÌ^	*/
+	uint8_t		rsv1;		/* \ñ				*/
+	uint16_t	sum;		/* `FbNT		*/
+	uint16_t	rsv2;		/* \ñ				*/
+	uint16_t	num;		/* O[vR[hÌ */
+	T_IGMP_GROUP_RECORD record;	/* O[vR[h */
+} T_IGMPV3R_HDR;
+
+#ifdef __CA850__
+#pragma pack(8)
+#elif __RX
+#pragma unpack
+#elif _MSC_VER
+#pragma pack(pop)
+#endif
+
+#define IGMP_HDR_SIZE			(sizeof(T_IGMPV1_HDR))
+#define IP4_IGMP_HDR_SIZE		(IP4_HDR_SIZE + IGMP_HDR_SIZE)
+#define IF_IP4_IGMP_HDR_SIZE		(IF_IP4_HDR_SIZE + IGMP_HDR_SIZE)
+#define IF_IP4_IGMP_HDR_OFFSET		(IF_IP4_HDR_SIZE)
+
+#define GET_IGMPV1_HDR(nbuf,ihoff)	((T_IGMPV1_HDR*)((uint8_t*)((nbuf)->buf) + ihoff))
+#define GET_IGMPV2_HDR(nbuf,ihoff)	((T_IGMPV2_HDR*)((uint8_t*)((nbuf)->buf) + ihoff))
+#define GET_IGMPV3Q_HDR(nbuf,ihoff)	((T_IGMPV3Q_HDR*)((uint8_t*)((nbuf)->buf) + ihoff))
+#define GET_IGMPV3R_HDR(nbuf,ihoff)	((T_IGMPV3R_HDR*)((uint8_t*)((nbuf)->buf) + ihoff))
+#define GET_IGMP_SDU(nbuf,ihoff)	((uint8_t*)((nbuf)->buf) + ihoff + IGMP_HDR_SIZE)
+
+/*
+*  bZ[WÌ^
+*/
+
+#define IGMP_MEMBERSHIP_QUERY		0x11	/* o[VbvNG[		*/
+#define IGMP_MEMBERSHIP_REPORT		0x12	/* o[Vbv|[g		*/
+#define IGMP_MEMBERSHIP_REPORT_V2	0x16	/* o[Vbv|[g		*/
+#define IGMP_LEAVE_GROUP			0x17	/* [uO[v				*/
+#define IGMP_MEMBERSHIP_REPORT_V3	0x22	/* o[Vbv|[g		*/
+
+/*
+*  UDPÊM[_IvV
+*/
+
+typedef struct ip_mreq
+{
+	T_IN4_ADDR imr_multiaddr; /* IP multicast address of group */
+	T_IN4_ADDR imr_interface; /* local IP address of interface */
+} T_IP_MREQ;
+
+typedef struct ip_msfilter
+{
+	T_IN4_ADDR imsf_multiaddr;     /* IP multicast group address */
+	T_IN4_ADDR imsf_interface;     /* IP address of local interface */
+	uint32_t   imsf_fmode;         /* Filter-mode */
+	uint32_t   imsf_numsrc;        /* Number of sources in the following array */
+	T_IN4_ADDR imsf_slist[1];      /* Array of source addresses */
+} T_IP_MSFILTER;
+
+#define MCAST_INCLUDE     1
+#define MCAST_EXCLUDE     2
+
+extern ER igmp_set_loop(T_UDP_CEP *cep, uint8_t optval);
+extern ER igmp_get_loop(T_UDP_CEP *cep, uint8_t *optval);
+extern ER igmp_set_ttl(T_UDP_CEP *cep, uint8_t optval);
+extern ER igmp_get_ttl(T_UDP_CEP *cep, uint8_t *optval);
+extern ER igmp_set_if(T_UDP_CEP *cep, T_IN4_ADDR *optval);
+extern ER igmp_get_if(T_UDP_CEP *cep, T_IN4_ADDR *optval);
+extern ER igmp_add_membership(T_UDP_CEP *cep, T_IP_MREQ *optval);
+extern ER igmp_drop_membership(T_UDP_CEP *cep, T_IP_MREQ *optval);
+extern ER igmp_set_ip_msfilter(T_UDP_CEP *cep, const T_IP_MSFILTER *optval);
+extern ER igmp_get_ip_msfilter(T_UDP_CEP *cep, T_IP_MSFILTER *optval);
+
+/*
+ *  IGMP O[vGg
+ */
+
+typedef struct igmp_entry
+{
+	uint16_t	timer;		/* MÜÅÌÔ[b]	*/
+	uint16_t	resptime;	/* ÅåÔ[b]	*/
+	T_IN4_ADDR	ip_addr;	/* IP AhX			*/
+} T_IGMP_ENTRY;
+
+extern void igmp_init(void);
+extern bool_t igmp_is_joined_group(T_IN4_ADDR addr);
+extern uint_t igmp_input(T_NET_BUF **inputp, uint_t *offp, uint_t *nextp);
+
+#endif	/* of #ifndef _IP_IGMP_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_input.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_input.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_input.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -77,4 +77,5 @@
 #include <t_syslog.h>
 #include "kernel_cfg.h"
+#include "tinet_cfg.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_ASP */
@@ -85,4 +86,5 @@
 #include <t_services.h>
 #include "kernel_id.h"
+#include "tinet_id.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_JSP */
@@ -97,4 +99,5 @@
 #include <net/ppp_ipcp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_count.h>
@@ -107,8 +110,8 @@
 #include <netinet/ip_icmp.h>
 #include <netinet/tcp.h>
-#include <netinet/tcp_timer.h>
 #include <netinet/tcp_var.h>
 #include <netinet/udp.h>
 #include <netinet/udp_var.h>
+#include <netinet/ip_igmp.h>
 
 #if defined(SUPPORT_IPSEC)
@@ -122,4 +125,6 @@
 
 #include <net/if_var.h>
+
+#if defined(_IP4_CFG)
 
 /*
@@ -345,14 +350,16 @@
 ip_remove_options (T_NET_BUF *nbuf)
 {
-	T_IP_HDR	*iph;
-
-	iph  = GET_IP_HDR(nbuf);
-
-	if (GET_IP_HDR_SIZE(iph) > IP4_HDR_SIZE) {
-		memmove((char *)iph + IP4_HDR_SIZE, GET_IP_SDU(nbuf),
-		        (size_t)(iph->len - GET_IP_HDR_SIZE(iph)));
+	T_IP4_HDR	*iph;
+	uint_t		hdr_size;
+
+	iph  = GET_IP4_HDR(nbuf);
+	hdr_size = GET_IP4_HDR_SIZE(nbuf);
+
+	if (hdr_size > IP4_HDR_SIZE) {
+		memmove((char *)iph + IP4_HDR_SIZE, GET_IP4_SDU(nbuf),
+		        (size_t)(iph->len - hdr_size));
 		iph->vhl   = IP4_MAKE_VHL(IPV4_VERSION, IP4_HDR_SIZE >> 2);
-		iph->len  -= (uint16_t)(GET_IP_HDR_SIZE(iph) - IP4_HDR_SIZE);
-		nbuf->len -= (uint16_t)(GET_IP_HDR_SIZE(iph) - IP4_HDR_SIZE);
+		iph->len  -= (uint16_t)(hdr_size - IP4_HDR_SIZE);
+		nbuf->len -= (uint16_t)(hdr_size - IP4_HDR_SIZE);
 		}
 
@@ -389,6 +396,6 @@
 		}
 
-	ip4h  = GET_IP4_HDR(input);
-	hlen = GET_IP4_HDR_SIZE(ip4h);
+	ip4h = GET_IP4_HDR(input);
+	hlen = GET_IP4_HDR_SIZE(input);
 
 	/* バージョンをチェックする。*/
@@ -429,5 +436,5 @@
 	/* 送信元アドレスをチェックする。*/
 	src = ntohl(ip4h->src);
-	bc  = (ifp->in_ifaddr.addr & ifp->in_ifaddr.mask) | ~ifp->in_ifaddr.mask;
+	bc  = (ifp->in4_ifaddr.addr & ifp->in4_ifaddr.mask) | ~ifp->in4_ifaddr.mask;
 
 #ifdef SUPPORT_LOOP
@@ -441,5 +448,5 @@
 #else	/* of #ifdef SUPPORT_LOOP */
 
-	if (src == ifp->in_ifaddr.addr || src == bc || src == IPV4_ADDR_BROADCAST || src == IPV4_ADDRANY) {
+	if (src == ifp->in4_ifaddr.addr || src == bc || src == IPV4_ADDR_BROADCAST || src == IPV4_ADDRANY) {
 		NET_COUNT_IP4(net_count_ip4[NC_IP4_IN_ERR_ADDR], 1);
 		NET_COUNT_MIB(ip_stats.ipInAddrErrors, 1);
@@ -459,16 +466,27 @@
 	 */
 
-	if ((ifp->in_ifaddr.addr != IPV4_ADDRANY) &&
-	    (!(dst == ifp->in_ifaddr.addr || dst == bc ||
-	       dst == IPV4_ADDR_BROADCAST || dst == IPV4_ADDRANY))) {
+#if defined(ETHER_CFG_MULTICAST)
+	if ((ifp->in4_ifaddr.addr != IPV4_ADDRANY) &&
+		(!(dst == ifp->in4_ifaddr.addr || dst == bc ||
+		   dst == IPV4_ADDR_BROADCAST  || dst == IPV4_ADDRANY ||
+		  IN4_IS_ADDR_MULTICAST(dst)))) {
 		NET_COUNT_IP4(net_count_ip4[NC_IP4_IN_ERR_ADDR], 1);
 		NET_COUNT_MIB(ip_stats.ipInAddrErrors, 1);
 		goto buf_rel;
 		}
+#else
+	if ((ifp->in4_ifaddr.addr != IPV4_ADDRANY) &&
+	    (!(dst == ifp->in4_ifaddr.addr || dst == bc ||
+	       dst == IPV4_ADDR_BROADCAST  || dst == IPV4_ADDRANY))) {
+		NET_COUNT_IP4(net_count_ip4[NC_IP4_IN_ERR_ADDR], 1);
+		NET_COUNT_MIB(ip_stats.ipInAddrErrors, 1);
+		goto buf_rel;
+		}
+#endif
 
 #else	/* of #ifdef DHCP_CFG */
 
 #if defined(ETHER_CFG_MULTICAST)
-	if (!(dst == ifp->in_ifaddr.addr || dst == bc ||
+	if (!(dst == ifp->in4_ifaddr.addr || dst == bc ||
 		  dst == IPV4_ADDR_BROADCAST || dst == IPV4_ADDRANY ||
 		  IN4_IS_ADDR_MULTICAST(dst))) {
@@ -478,6 +496,6 @@
 		}
 #else
-	if (!(dst == ifp->in_ifaddr.addr || dst == bc ||
-	      dst == IPV4_ADDR_BROADCAST || dst == IPV4_ADDRANY)) {
+	if (!(dst == ifp->in4_ifaddr.addr || dst == bc ||
+	      dst == IPV4_ADDR_BROADCAST  || dst == IPV4_ADDRANY)) {
 		NET_COUNT_IP4(net_count_ip4[NC_IP4_IN_ERR_ADDR], 1);
 		NET_COUNT_MIB(ip_stats.ipInAddrErrors, 1);
@@ -525,13 +543,5 @@
 	switch (ip4h->proto) {
 
-#ifdef SUPPORT_UDP
-	case IPPROTO_UDP:
-		NET_COUNT_MIB(ip_stats.ipInDelivers, 1);
-		udp_input(&input, &off, NULL);
-		return;
-		break;
-#endif	/* of #ifdef SUPPORT_UDP */
-
-#ifdef SUPPORT_TCP
+#if defined(SUPPORT_TCP)
 	case IPPROTO_TCP:
 		NET_COUNT_MIB(ip_stats.ipInDelivers, 1);
@@ -539,5 +549,14 @@
 		return;
 		break;
-#endif	/* of #ifdef SUPPORT_UDP */
+#endif	/* of #if defined(SUPPORT_TCP) */
+
+#if defined(SUPPORT_UDP) && ( (TNUM_UDP4_CEPID > 0) || \
+                             ((TNUM_UDP6_CEPID > 0) && defined(API_CFG_IP4MAPPED_ADDR)))
+	case IPPROTO_UDP:
+		NET_COUNT_MIB(ip_stats.ipInDelivers, 1);
+		udp4_input(&input, &off, NULL);
+		return;
+		break;
+#endif	/* of #if defined(SUPPORT_UDP) && TNUM_UDP4_CEPID > 0 */
 
 	case IPPROTO_ICMP:
@@ -546,4 +565,12 @@
 		return;
 		break;
+
+#if defined(SUPPORT_IGMP)
+	case IPPROTO_IGMP:
+		NET_COUNT_MIB(ip_stats.ipInDelivers, 1);
+		igmp_input(&input, &off, NULL);
+		return;
+		break;
+#endif /* of #ifdef UDP_CFG_EXTENTIONS */
 
 #if defined(SUPPORT_IPSEC)
@@ -560,5 +587,5 @@
 
 		/* ローカル IP アドレスに届いたデータグラムのみ ICMP エラーを通知する。*/
-		if (dst == ifp->in_ifaddr.addr) {
+		if (dst == ifp->in4_ifaddr.addr) {
 			T_IN4_ADDR	src;
 
@@ -578,2 +605,4 @@
 	syscall(rel_net_buf(input));
 	}
+
+#endif	/* of #if defined(_IP4_CFG) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_output.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_output.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_output.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -93,4 +93,5 @@
 #include <net/ppp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_count.h>
@@ -104,4 +105,6 @@
 #include <netinet6/ipsec.h>
 #endif
+
+#if defined(_IP4_CFG)
 
 static uint16_t frag_id = 0;
@@ -221,5 +224,5 @@
 
 		len  = ntohs(ip4h->len);
-		off  = hlen = GET_IP4_HDR_SIZE(ip4h);
+		off  = hlen = GET_IP4_HDR_SIZE(output);
 		while (off < len) {
 			if (off + (IF_MTU - IP4_HDR_SIZE) < len)
@@ -245,5 +248,5 @@
 				fip4h->id	= htons(frag_id);
 				fip4h->sum	= 0;
-				fip4h->sum	= in_cksum(fip4h, GET_IP4_HDR_SIZE(fip4h));
+				fip4h->sum	= in_cksum(fip4h, GET_IP4_HDR_SIZE(frag));
 
 				NET_COUNT_IP4(net_count_ip4[NC_IP4_OUT_OCTETS], ntohs(fip4h->len));
@@ -279,5 +282,5 @@
 		frag_id ++;
 		ip4h->sum = 0;
-		ip4h->sum = in_cksum(ip4h, GET_IP4_HDR_SIZE(ip4h));
+		ip4h->sum = in_cksum(ip4h, GET_IP4_HDR_SIZE(output));
 
 		NET_COUNT_IP4(net_count_ip4[NC_IP4_OUT_OCTETS], ntohs(ip4h->len));
@@ -301,5 +304,5 @@
 	frag_id ++;
 	ip4h->sum = 0;
-	ip4h->sum = in_cksum(ip4h, (uint_t)GET_IP4_HDR_SIZE(ip4h));
+	ip4h->sum = in_cksum(ip4h, (uint_t)GET_IP4_HDR_SIZE(output));
 
 	NET_COUNT_IP4(net_count_ip4[NC_IP4_OUT_OCTETS], ntohs(ip4h->len));
@@ -327,2 +330,4 @@
 	return error;
 	}
+
+#endif	/* of #if defined(_IP4_CFG) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_var.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_var.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/ip_var.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -71,18 +71,6 @@
 #define _IP_VAR_H_
 
-/*
- *  IPv4 ヘッダ・ペイロードアクセスマクロ
- */
-
-#define IF_IP4_HDR_SIZE			(IF_HDR_SIZE + IP4_HDR_SIZE)
-
-#define GET_IP4_HDR(nbuf)		((T_IP4_HDR*)((nbuf)->buf + IF_HDR_SIZE))
-#define GET_IP4_SDU(nbuf)		((uint8_t*)((nbuf)->buf) + GET_IF_IP4_HDR_SIZE(nbuf))
-
-#define GET_IP4_HDR_SIZE(iph)		((uint8_t)IP4_VHL_HL((iph)->vhl) << 2)
-#define GET_IP4_SDU_SIZE(iph)		(ntohs((iph)->len) - GET_IP4_HDR_SIZE(iph))
-#define GET_IF_IP4_HDR_SIZE(nbuf)	(IF_HDR_SIZE + (GET_IP4_HDR_SIZE(GET_IP4_HDR(nbuf))))
-
-#define SET_IP4_SDU_SIZE(iph,slen)	((iph)->len=(uint16_t)htons((slen) + IP4_HDR_SIZE))
+#include <netinet/ip4_var.h>
+#include <netinet6/ip6_var.h>
 
 /*
@@ -90,190 +78,78 @@
  */
 
-#if defined(SUPPORT_INET4)
+#define GET_IP_VER(nbuf)		(*(uint8_t*)((nbuf)->buf+IF_HDR_SIZE)>>4)
 
-#define T_TCP_IP_Q_HDR			T_TCP_IP4_Q_HDR
+#if defined(_IP6_CFG)
 
-#define IF_IP_HDR_SIZE			IF_IP4_HDR_SIZE
+#if defined(_IP4_CFG)
+
+#define IF_IP_HDR_SIZE(nbuf)		(GET_IP_VER(nbuf)==IPV6_VERSION?IF_IP6_HDR_SIZE:IF_IP4_HDR_SIZE)
+#define IF_IP_NET_HDR_SIZE(addr)	(IN6_IS_ADDR_V4MAPPED(addr)?IF_IP4_HDR_SIZE:IF_IP6_HDR_SIZE)
+
+#define IP_OUTPUT(nbuf,tmout)		(GET_IP_VER(nbuf)==IPV6_VERSION?ip6_output(nbuf,0,tmout):ip_output(nbuf,tmout))
+#define IP_REMOVE_OPTIONS(nbuf)		(GET_IP_VER(nbuf)==IPV6_VERSION?ip6_remove_exthdrs(nbuf):ip_remove_options(nbuf))
+
+#define GET_IP_HDR(nbuf)		(GET_IP_VER(nbuf)==IPV6_VERSION?GET_IP6_HDR(nbuf):GET_IP4_HDR(nbuf))
+#define GET_IP_HDR_SIZE(nbuf)		(GET_IP_VER(nbuf)==IPV6_VERSION?GET_IP6_HDR_SIZE(nbuf):GET_IP4_HDR_SIZE(nbuf))
+#define GET_IP_SDU_SIZE(nbuf)		(GET_IP_VER(nbuf)==IPV6_VERSION?GET_IP6_SDU_SIZE(nbuf):GET_IP4_SDU_SIZE(nbuf))
+#define GET_IF_IP_HDR_SIZE(nbuf)	(GET_IP_VER(nbuf)==IPV6_VERSION?GET_IF_IP6_HDR_SIZE(nbuf):GET_IF_IP4_HDR_SIZE(nbuf))
+#define GET_IP_TCP_Q_HDR_OFFSET(nbuf)	(GET_IP_VER(nbuf)==IPV6_VERSION?\
+					((T_IP6_TCP_Q_HDR*)GET_IP6_HDR(nbuf))->thoff:((T_IP4_TCP_Q_HDR*)GET_IP4_HDR(nbuf))->thoff)
+
+#define SET_IP_CF(nbuf,cf)		(GET_IP_VER(nbuf)==IPV6_VERSION?SET_IP6_CF(nbuf,cf):(0))
+#define SET_IP_SDU_SIZE(nbuf,len)	(GET_IP_VER(nbuf)==IPV6_VERSION?SET_IP6_SDU_SIZE(nbuf,len):SET_IP4_SDU_SIZE(nbuf,len))
+#define SET_IP_TCP_Q_HDR_OFFSET(nbuf,thoff)	\
+					(GET_IP_VER(nbuf)==IPV6_VERSION\
+						?(((T_IP6_TCP_Q_HDR*)GET_IP6_HDR(nbuf))->thoff=thoff)\
+						:(((T_IP4_TCP_Q_HDR*)GET_IP4_HDR(nbuf))->thoff=thoff))
+
+#else	/* of #if defined(_IP4_CFG) */
+
+#define IF_IP_HDR_SIZE(nbuf)		IF_IP6_HDR_SIZE
+#define IF_IP_NET_HDR_SIZE(addr)	IF_IP6_HDR_SIZE
+
+#define IP_OUTPUT(nbuf,tmout)		ip6_output(nbuf,0,tmout)
+#define IP_REMOVE_OPTIONS(nbuf)		ip6_remove_exthdrs(nbuf)
+
+#define GET_IP_HDR(nbuf)		GET_IP6_HDR(nbuf)
+#define GET_IP_HDR_SIZE(nbuf)		GET_IP6_HDR_SIZE(nbuf)
+#define GET_IP_SDU_SIZE(nbuf)		GET_IP6_SDU_SIZE(nbuf)
+#define GET_IF_IP_HDR_SIZE(nbuf)	GET_IF_IP6_HDR_SIZE(nbuf)
+#define GET_IP_TCP_Q_HDR_OFFSET(nbuf)	(((T_IP6_TCP_Q_HDR*)GET_IP6_HDR(nbuf))->thoff)
+
+#define SET_IP_CF(nbuf,cf)		SET_IP6_CF(nbuf,cf)
+#define SET_IP_SDU_SIZE(nbuf,len)	SET_IP6_SDU_SIZE(nbuf,len)
+#define SET_IP_TCP_Q_HDR_OFFSET(nbuf,thoff)	\
+					(((T_IP6_TCP_Q_HDR*)GET_IP6_HDR(nbuf))->thoff=thoff)
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#else	/* of #if defined(_IP6_CFG) */
+
+#if defined(_IP4_CFG)
+
+#define IF_IP_HDR_SIZE(nbuf)		IF_IP4_HDR_SIZE
+#define IF_IP_NET_HDR_SIZE(addr)	IF_IP4_HDR_SIZE
+
+#define IP_OUTPUT(nbuf,tmout)		ip_output(nbuf,tmout)
+#define IP_REMOVE_OPTIONS(nbuf)		ip_remove_options(nbuf)
 
 #define GET_IP_HDR(nbuf)		GET_IP4_HDR(nbuf)
-#define GET_IP_SDU(nbuf)		GET_IP4_SDU(nbuf)
+#define GET_IP_HDR_SIZE(nbuf)		GET_IP4_HDR_SIZE(nbuf)
+#define GET_IP_SDU_SIZE(nbuf)		GET_IP4_SDU_SIZE(nbuf)
+#define GET_IF_IP_HDR_SIZE(nbuf)	GET_IF_IP4_HDR_SIZE(nbuf)
+#define GET_IP_TCP_Q_HDR_OFFSET(nbuf)	(((T_IP4_TCP_Q_HDR*)GET_IP4_HDR(nbuf))->thoff)
 
-#define GET_IP_HDR_SIZE(iph)		GET_IP4_HDR_SIZE(iph)
-#define GET_IP_SDU_SIZE(iph)		GET_IP4_SDU_SIZE(iph)
-#define GET_IF_IP_HDR_SIZE(nbuf)	GET_IF_IP4_HDR_SIZE(nbuf)
+#define SET_IP_SDU_SIZE(nbuf,len)	SET_IP4_SDU_SIZE(nbuf,len)
+#define SET_IP_TCP_Q_HDR_OFFSET(nbuf,thoff)	\
+					(((T_IP4_TCP_Q_HDR*)GET_IP4_HDR(nbuf))->thoff=thoff)
 
-#define SET_IP_SDU_SIZE(iph,len)	SET_IP4_SDU_SIZE(iph,len)
+#else	/* of #if defined(_IP4_CFG) */
 
-#define IP_OUTPUT(nbuf,tmout)		ip_output(nbuf,tmout)
-#define IP_INIT()			ip_init()
-#define IP_REMOVE_OPTIONS(nbuf)		ip_remove_options(nbuf)
+#error "not implemented."
 
-#endif	/* of #if defined(SUPPORT_INET4) */
+#endif	/* of #if defined(_IP4_CFG) */
 
-/*
- *  IP の MSS サイズのネットワークバッファ
- */
-
-typedef struct t_net_buf_ip_mss {
-	uint16_t	len;	/* データの長さ		*/
-	uint8_t		idix;	/* mpfid のインデックス	*/
-	uint8_t		flags;	/* フラグ		*/
-#ifdef IF_ETHER_NIC_NET_BUF_ALIGN
-	uint8_t		nalign[IF_ETHER_NIC_NET_BUF_ALIGN];
-#endif
-#if CPU_NET_ALIGN == 4 && IF_HDR_ALIGN != 4
-	uint8_t		halign[4 - IF_HDR_ALIGN];
-#endif
-	uint8_t		buf[IF_HDR_SIZE + IP4_MSS];
-				/* バッファ本体		*/
-	} T_NET_BUF_IP_MSS;
-
-/*
- *  65536 オクテットサイズのネットワークバッファ
- */
-
-typedef struct t_net_buf4_65536 {
-	uint16_t	len;	/* データの長さ		*/
-	uint8_t		idix;	/* mpfid のインデックス	*/
-	uint8_t		flags;	/* フラグ		*/
-#ifdef IF_ETHER_NIC_NET_BUF_ALIGN
-	uint8_t		nalign[IF_ETHER_NIC_NET_BUF_ALIGN];
-#endif
-#if CPU_NET_ALIGN == 4 && IF_HDR_ALIGN != 4
-	uint8_t		halign[4 - IF_HDR_ALIGN];
-#endif
-	uint8_t		buf[IF_IP4_HDR_SIZE + 65536];
-				/* バッファ本体		*/
-#if defined(IF_PDU_HDR_PADDING)
-	uint8_t		padding[IF_PDU_HDR_PADDING];
-#endif				/* ヘッダの余分		*/
-	} T_NET_BUF4_65536;
-
-#ifdef IP4_CFG_FRAGMENT
-
-/*
- *  再構成キュー用 IPv4 ヘッダの定義
- */
-
-typedef struct t_qip4_hdr {
-	uint8_t		vhl;		/* version << 4 | header length >> 2	*/
-					/* length は 4 octets 単位		*/
-	uint8_t		type;		/* type of services			*/
-	uint16_t	len;		/* total length				*/
-
-	uint16_t	id;		/* identification			*/
-	uint16_t	flg_off;	/* fragment flag & offset		*/
-
-	uint8_t		ttl;		/* time to live				*/
-	uint8_t		proto;		/* protocol				*/
-	uint16_t	sum;		/* checksum				*/
-
-	uint32_t	src;		/* source address			*/
-
-	T_NET_BUF	*next;		/* 次の IPv4 フラグメント			*/
-	} __attribute__((packed, aligned(2)))T_QIP4_HDR;
-
-#define QIP4_HDR_SIZE			(sizeof(T_QIP4_HDR))
-#define IF_QIP4_HDR_SIZE		(IF_HDR_SIZE + QIP4_HDR_SIZE)
-
-#define GET_QIP4_HDR(nbuf)		((T_QIP4_HDR*)((nbuf)->buf + IF_HDR_SIZE))
-#define GET_QIP4_SDU(nbuf)		((uint8_t*)(nbuf)->buf + GET_IF_QIP4_HDR_SIZE(nbuf))
-
-#define GET_QIP4_HDR_SIZE(iph)		((uint8_t)IP4_VHL_HL((iph)->vhl) << 2)
-#define GET_IF_QIP4_HDR_SIZE(nbuf)	(IF_HDR_SIZE + (GET_QIP4_HDR_SIZE(GET_QIP4_HDR(nbuf))))
-
-/*
- *  データグラム再構成用ネットワークバッファ
- */
-
-typedef struct t_net_buf4_reassm {
-	uint16_t	len;	/* データの長さ		*/
-	uint8_t		idix;	/* mpfid のインデックス	*/
-	uint8_t		flags;	/* フラグ		*/
-#ifdef IF_ETHER_NIC_NET_BUF_ALIGN
-	uint8_t		nalign[IF_ETHER_NIC_NET_BUF_ALIGN];
-#endif
-#if CPU_NET_ALIGN == 4 && IF_HDR_ALIGN != 4
-	uint8_t		align[4 - IF_HDR_ALIGN];
-#endif
-	uint8_t		buf[IP4_CFG_FRAG_REASSM_SIZE];
-				/* バッファ本体		*/
-	} T_NET_BUF4_REASSM;
-
-#endif	/* of #ifdef IP4_CFG_FRAGMENT */
-
-/*
- *  TCP の再構成キューにおける IPv4 ヘッダの定義
- */
-
-typedef struct t_tcp_ip4_q_hdr {
-	uint8_t		vhl;		/* version << 4 | header length >> 2	*/
-					/* length は 4 octets 単位		*/
-	uint8_t		type;		/* type of services			*/
-	uint16_t	len;		/* total length				*/
-
-	uint16_t	id;		/* identification			*/
-	uint16_t	flg_off;	/* fragment flag & offset		*/
-
-	uint8_t		ttl;		/* time to live				*/
-	uint8_t		proto;		/* protocol				*/
-	uint16_t	thoff;		/* TCP ヘッダのオフセット		*/
-
-	T_IN4_ADDR	src;		/* source address			*/
-	T_IN4_ADDR	dst;		/* destination address			*/
-	} __attribute__((packed, aligned(2)))T_TCP_IP4_Q_HDR;
-
-#ifdef SUPPORT_MIB
-
-/*
- *  SNMP の 管理情報ベース (MIB)
- */
-
-typedef struct t_ip_stats {
-	uint32_t	ipInReceives;
-	uint32_t	ipInHdrErrors;
-	uint32_t	ipInAddrErrors;
-/*	uint32_t	ipForwDatagrams;*/
-	uint32_t	ipInUnknownProtos;
-/*	uint32_t	ipInDiscards;*/
-	uint32_t	ipInDelivers;
-	uint32_t	ipOutRequests;
-	uint32_t	ipOutDiscards;
-/*	uint32_t	ipOutNoRoutes;*/
-
-#ifdef IP4_CFG_FRAGMENT
-
-	uint32_t	ipReasmReqds;
-	uint32_t	ipReasmOKs;
-	uint32_t	ipReasmFails;
-	uint32_t	ipFragOKs;
-	uint32_t	ipFragFails;
-	uint32_t	ipFragCreates;
-
-#else	/* of #ifdef IP4_CFG_FRAGMENT */
-
-	uint32_t	ipReasmReqds;
-/*	uint32_t	ipReasmOKs;*/
-	uint32_t	ipReasmFails;
-/*	uint32_t	ipFragOKs;*/
-/*	uint32_t	ipFragFails;*/
-/*	uint32_t	ipFragCreates;*/
-
-#endif	/* of #ifdef IP4_CFG_FRAGMENT */
-
-} T_IP_STATS;
-
-extern T_IP_STATS ip_stats;
-
-#endif	/* of #ifdef SUPPORT_MIB */
-
-/*
- *  関数
- */
-
-extern void ip_frag_timer (void);
-extern void ip_init (void);
-extern ER ip_remove_options (T_NET_BUF *nbuf);
-extern ER ip_output (T_NET_BUF *nbuf, TMO tmout);
+#endif	/* of #if defined(_IP6_CFG) */
 
 #endif	/* of #ifndef _IP_VAR_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_fsm.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_fsm.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_fsm.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_input.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_input.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_input.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -95,4 +95,5 @@
 #include <net/ethernet.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_var.h>
 #include <net/net_buf.h>
@@ -102,18 +103,13 @@
 #include <netinet/in.h>
 #include <netinet/in_var.h>
-#include <netinet6/in6.h>
-#include <netinet6/in6_var.h>
-#include <netinet6/nd6.h>
 #include <netinet/in_itron.h>
 #include <netinet/ip.h>
 #include <netinet/ip_var.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
 #include <netinet/ip_icmp.h>
 #include <netinet/tcp.h>
-#include <netinet/tcp_timer.h>
 #include <netinet/tcp_var.h>
 #include <netinet/tcp_fsm.h>
 #include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
 
 #ifdef SUPPORT_TCP
@@ -139,5 +135,5 @@
 static void close_connection	(T_TCP_CEP *cep, bool_t *needoutput);
 static void set_rexmt_timer	(T_TCP_CEP *cep,  T_TCP_TIME rtt);
-static uint8_t reassemble		(T_NET_BUF *input, T_TCP_CEP *cep, uint_t thoff, uint8_t flags);
+static uint8_t reassemble	(T_NET_BUF *input, T_TCP_CEP *cep, uint_t thoff, uint8_t flags);
 static ER drop_after_ack	(T_NET_BUF *input, T_TCP_CEP *cep, uint_t thoff);
 static ER listening		(T_NET_BUF *input, T_TCP_CEP *cep, uint_t thoff, T_TCP_SEQ iss);
@@ -147,93 +143,6 @@
 static void trim_length		(T_TCP_HDR *tcph,  T_TCP_CEP *cep);
 static void parse_option	(T_TCP_HDR *tcph,  T_TCP_CEP *cep);
-static bool_t update_wnd		(T_TCP_HDR *tcph,  T_TCP_CEP *cep);
+static bool_t update_wnd	(T_TCP_HDR *tcph,  T_TCP_CEP *cep);
 static void proc_urg		(T_TCP_HDR *tcph,  T_TCP_CEP *cep);
-
-#if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0
-
-/*
- *  タスクからの Time Wait 状態 CEP 分離機能
- */
-
-/*
- *  関数
- */
-
-static T_TCP_TWCEP*tcp_find_twcep (T_IN_ADDR *dstaddr,  uint16_t dstport,
-                                   T_IN_ADDR *peeraddr, uint16_t peerport);
-
-/*
- *  変数
- */
-
-T_TCP_TWCEP tcp_twcep[NUM_TCP_TW_CEP_ENTRY];
-
-/*
- *  tcp_find_twcep -- ポート番号から Time Wait 用 TCP 通信端点を得る。
- *
- *    注意: dstaddr は、ネットワークバイトオーダ
- */
-
-static T_TCP_TWCEP*
-tcp_find_twcep (T_IN_ADDR *dstaddr, uint16_t dstport, T_IN_ADDR *peeraddr, uint16_t peerport)
-{
-	T_TCP_TWCEP*	twcep;
-	
-	/*
-	 *  状態が TIME WAIT で、
-	 *  IP アドレスとポート番号が一致する通信端点を探索する。
-	 */
-	for (twcep = &tcp_twcep[NUM_TCP_TW_CEP_ENTRY]; twcep -- != tcp_twcep; ) {
-		if (twcep->fsm_state == TCP_FSM_TIME_WAIT                   &&
-		    IN_IS_DSTADDR_ACCEPT (&twcep->myaddr.ipaddr,  dstaddr)  &&
-		    IN_ARE_NET_ADDR_EQUAL(&twcep->dstaddr.ipaddr, peeraddr) &&
-		    dstport  == twcep->myaddr.portno                        &&
-		    peerport == twcep->dstaddr.portno)
-			return twcep;
-		}
-
-	return NULL;
-	}
-
-/*
- *  必要な情報を Time Wait 用 TCP 通信端点に移して、
- *  標準の TCP 通信端点を開放する。
- */
-
-void
-tcp_move_twcep (T_TCP_CEP *cep)
-{
-	T_TCP_TWCEP*	twcep;
-
-	/* 空きの Time Wait 用 TCP 通信端点を探索する。*/
-	for (twcep = &tcp_twcep[NUM_TCP_TW_CEP_ENTRY]; twcep -- != tcp_twcep; ) {
-		if (twcep->fsm_state != TCP_FSM_TIME_WAIT) {
-
-			/*
-			 *  通信端点をロックし、
-			 *  必要な情報を Time Wait 用 TCP 通信端点に移す。
-			 */
-			syscall(wai_sem(cep->semid_lock));
-			twcep->rbufsz		= cep->rbufsz;
-			twcep->dstaddr		= cep->dstaddr;
-			twcep->myaddr		= cep->myaddr;
-			twcep->snd_una		= cep->snd_una;
-			twcep->rcv_nxt		= cep->rcv_nxt;
-			twcep->rwbuf_count	= cep->rwbuf_count;
-			twcep->fsm_state	= cep->fsm_state;
-			twcep->timer_2msl	= cep->timer[TCP_TIM_2MSL];
-
-			/* 通信端点をロックを解除する。*/
-			syscall(sig_sem(cep->semid_lock));
-
-			/* 標準 TCP 通信端点を開放する。*/
-			tcp_close(cep);
-
-			break;
-			}
-		}
-	}
-
-#endif	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
 
 /*
@@ -421,5 +330,5 @@
 
 		/*  TCP ヘッダの位置を保存する。*/
-		GET_TCP_IP_Q_HDR(input)->thoff = thoff;
+		SET_IP_TCP_Q_HDR_OFFSET(input, thoff);
 
 		/* SDU のオフセット（元はウィンドサイズ）をリセットする。*/
@@ -448,8 +357,6 @@
 listening (T_NET_BUF *input, T_TCP_CEP *cep, uint_t thoff, T_TCP_SEQ iss)
 {
-	T_IP_HDR	*iph;
 	T_TCP_HDR	*tcph;
 
-	iph  = GET_IP_HDR(input);
 	tcph = GET_TCP_HDR(input, thoff);
 
@@ -473,52 +380,12 @@
 		return RET_DROP;
 
-#if defined(SUPPORT_INET4)
-
-#ifdef SUPPORT_LOOP
-
 	/*
-	 *  次のときは破棄する。
-	 *    ・ポート番号が同一で、送受信 IP アドレス が同一。
-	 *      ただし、ローカルループバック (127.0.0.1) なら良い。
-	 *    ・マルチキャストアドレス
-	 */
-
-	if (tcph->dport == tcph->sport &&
-	    (iph->dst == iph->src && ntohl(iph->src) != IPV4_ADDR_LOOPBACK))
+	 *  受信可能な IP アドレスとポート番号であることを確認する。
+	 */
+	if (!tcp_is_addr_accept(input, thoff))
 		return RET_DROP;
 
-#else	/* of #ifdef SUPPORT_LOOP */
-
-	/*
-	 *  次のときは破棄する。
-	 *    ・ポート番号が同一で、送受信 IP アドレス が同一。
-	 *    ・マルチキャストアドレス
-	 */
-
-	if (tcph->dport == tcph->sport && iph->dst == iph->src)
-		return RET_DROP;
-
-#endif	/* of #ifdef SUPPORT_LOOP */
-
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
-
-	/*
-	 *  次のときは破棄する。
-	 *    ・ポート番号が同一で、送受信 IP アドレス が同一。
-	 *    ・マルチキャストアドレス
-	 */
-
-	if (tcph->dport == tcph->sport && IN_ARE_ADDR_EQUAL(&iph->dst, &iph->src))
-		return RET_DROP;
-
-#endif	/* of #if defined(SUPPORT_INET6) */
-
-	if (IN_IS_NET_ADDR_MULTICAST(&iph->dst))
-		return RET_DROP;
-
 	/* 相手のアドレスを記録する。*/
-	IN_COPY_TO_HOST(&cep->dstaddr.ipaddr, &iph->src);
+	IN_COPY_TO_HOST(&cep->dstaddr.ipaddr, input);
 	cep->dstaddr.portno = tcph->sport;
 
@@ -919,4 +786,8 @@
 			cep->rep = NULL;
 
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+			cep->rep4 = NULL;
+#endif
+
 			syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_ESTABLISHED));
 
@@ -926,5 +797,19 @@
 
 				/* 相手のアドレスをコピーする。*/
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+
+				if (cep->flags & TCP_CEP_FLG_IPV4) {
+					(*cep->p_dstaddr4).ipaddr = ntohl(cep->dstaddr.ipaddr.s6_addr32[3]);
+					(*cep->p_dstaddr4).portno = cep->dstaddr.portno;
+					}
+				else
+					*cep->p_dstaddr = cep->dstaddr;
+
+#else	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
+
 				*cep->p_dstaddr = cep->dstaddr;
+
+#endif	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
 
 				if (IS_PTR_DEFINED(cep->callback)) {
@@ -1369,4 +1254,5 @@
 	case TCP_FSM_ESTABLISHED:	/* コネクション開設完了		*/
 		cep->fsm_state = TCP_FSM_CLOSE_WAIT;
+		syscall(set_flg(cep->snd_flgid, TCP_CEP_EVT_RWBUF_READY));
 		break;
 
@@ -1421,5 +1307,4 @@
 {
 	T_NET_BUF	*input = *inputp;
-	T_IP_HDR	*iph;
 	T_TCP_HDR	*tcph;
 	T_TCP_CEP	*cep = NULL;
@@ -1442,10 +1327,9 @@
 
 	/* ヘッダ長をチェックする。*/
-	if (input->len < IF_IP_TCP_HDR_SIZE) {
+	if (input->len < IF_IP_TCP_HDR_SIZE(input)) {
 		NET_COUNT_TCP(net_count_tcp[NC_TCP_RECV_BAD_HEADERS], 1);
 		goto drop;
 		}
 
-	iph  = GET_IP_HDR(input);
 	tcph = GET_TCP_HDR(input, *offp);
 
@@ -1487,5 +1371,5 @@
 	 *  状態が Time Wait 中の CEP を探索する。
 	 */
-	twcep = tcp_find_twcep(&iph->dst, tcph->dport, &iph->src, tcph->sport);
+	twcep = tcp_find_twcep(input, *offp);
 	if (twcep != NULL) {
 
@@ -1510,10 +1394,10 @@
 	else
 		/* 標準の TCP 通信端点を得る。*/
-		cep = tcp_find_cep(&iph->dst, tcph->dport, &iph->src, tcph->sport);
+		cep = tcp_find_cep(input, *offp);
 
 #else	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
 
 	/* TCP 通信端点を得る。*/
-	cep = tcp_find_cep(&iph->dst, tcph->dport, &iph->src, tcph->sport);
+	cep = tcp_find_cep(input, *offp);
 
 #endif	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
@@ -1894,5 +1778,5 @@
 	 */
 
-	if ((tcph->flags & TCP_FLG_RST) || IN_IS_NET_ADDR_MULTICAST(&iph->dst))
+	if ((tcph->flags & TCP_FLG_RST) || IN_IS_NET_ADDR_MULTICAST(input))
 		goto drop;
 
@@ -1907,7 +1791,6 @@
 		rbfree = cep->rbufsz - cep->rwbuf_count;
 
-	if (tcph->flags & TCP_FLG_ACK) {
+	if (tcph->flags & TCP_FLG_ACK)
 		tcp_respond(input, cep, 0, tcph->ack, rbfree, TCP_FLG_RST);
-		}
 	else {
 		if (tcph->flags & TCP_FLG_SYN)
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_output.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_output.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_output.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -93,4 +93,6 @@
 #include <net/ethernet.h>
 #include <net/net.h>
+#include <net/net_endian.h>
+#include <net/net_var.h>
 #include <net/net_buf.h>
 #include <net/net_timer.h>
@@ -98,17 +100,13 @@
 
 #include <netinet/in.h>
-#include <netinet6/in6.h>
 #include <netinet/in_var.h>
 #include <netinet/in_itron.h>
 #include <netinet/ip.h>
 #include <netinet/ip_var.h>
-#include <netinet6/in6_var.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
 #include <netinet/tcp.h>
-#include <netinet/tcp_timer.h>
 #include <netinet/tcp_var.h>
 #include <netinet/tcp_fsm.h>
 #include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
 
 #ifdef SUPPORT_TCP
@@ -150,5 +148,5 @@
 	T_NET_BUF	*output;
 	T_TCP_HDR	*tcph;
-	uint_t		optlen;
+	uint_t		optlen, hdr_offset;
 	ER		error;
 
@@ -210,6 +208,6 @@
 		 */
 		len = 0;
-		if ((error = tcp_get_segment(&output, cep, optlen,
-	                                    len, (uint_t)(net_buf_max_siz() - IF_IP_TCP_HDR_SIZE),
+		if ((error = tcpn_get_segment(&output, cep, optlen,
+	                                    len, (uint_t)net_buf_max_siz(),
 	                                    NBA_SEARCH_ASCENT, TMO_TCP_GET_NET_BUF)) != E_OK) {
 			if (cep->timer[TCP_TIM_REXMT] == 0)
@@ -222,6 +220,6 @@
 
 	if (IS_PTR_DEFINED(cep->sbuf)) {
-		if ((error = tcp_get_segment(&output, cep, optlen,
-		                             len, (uint_t)(net_buf_max_siz() - IF_IP_TCP_HDR_SIZE),
+		if ((error = tcpn_get_segment(&output, cep, optlen,
+		                             len, (uint_t)net_buf_max_siz(),
 		                             NBA_SEARCH_ASCENT, TMO_TCP_GET_NET_BUF)) != E_OK) {
 			if (cep->timer[TCP_TIM_REXMT] == 0)
@@ -247,6 +245,6 @@
 		 */
 		len = 0;
-		if ((error = tcp_get_segment(&output, cep, optlen,
-	                                    len, (uint_t)(net_buf_max_siz() - IF_IP_TCP_HDR_SIZE),
+		if ((error = tcpn_get_segment(&output, cep, optlen,
+	                                    len, (uint_t)net_buf_max_siz(),
 	                                    NBA_SEARCH_ASCENT, TMO_TCP_GET_NET_BUF)) != E_OK) {
 			if (cep->timer[TCP_TIM_REXMT] == 0)
@@ -258,6 +256,6 @@
 #else	/* of #if defined(TCP_CFG_SWBUF_CSAVE_ONLY) */
 
-	if ((error = tcp_get_segment(&output, cep, optlen,
-	                             len, (uint_t)(net_buf_max_siz() - IF_IP_TCP_HDR_SIZE),
+	if ((error = tcpn_get_segment(&output, cep, optlen,
+	                             len, (uint_t)net_buf_max_siz(),
 	                             NBA_SEARCH_ASCENT, TMO_TCP_GET_NET_BUF)) != E_OK) {
 		if (cep->timer[TCP_TIM_REXMT] == 0)
@@ -272,4 +270,5 @@
 	 *  本実装では、最大セグメントサイズのみ設定する。
 	 */
+	hdr_offset = IF_IP_TCP_HDR_OFFSET(output);
 	if (flags & TCP_FLG_SYN) {
 		cep->snd_nxt = cep->iss;
@@ -277,5 +276,5 @@
 #ifdef TCP_CFG_OPT_MSS
 
-		optp = GET_TCP_OPT(output, IF_IP_TCP_HDR_OFFSET);
+		optp = GET_TCP_OPT(output, hdr_offset);
 		*optp ++ = TCP_OPT_MAXSEG;
 		*optp ++ = TCP_OPT_LEN_MAXSEG;
@@ -324,5 +323,5 @@
 		}
 
-	tcph = GET_TCP_HDR(output, IF_IP_TCP_HDR_OFFSET);
+	tcph = GET_TCP_HDR(output, hdr_offset);
 
 	/*
@@ -379,9 +378,8 @@
 	 */
 	tcph->sum = 0;
-	tcph->sum = IN_CKSUM(output, IPPROTO_TCP, (uint_t)GET_TCP_HDR_OFFSET(output),
-		             GET_TCP_HDR_SIZE2(output, IF_IP_TCP_HDR_OFFSET) + len);
+	tcph->sum = IN_CKSUM(output, IPPROTO_TCP, hdr_offset, GET_TCP_HDR_SIZE(output, hdr_offset) + len);
 
 	/* ネットワークバッファ長を調整する。*/
-	output->len = (uint16_t)(GET_IF_IP_TCP_HDR_SIZE2(output, IF_IP_TCP_HDR_OFFSET) + len);
+	output->len = (uint16_t)(GET_IF_IP_TCP_HDR_SIZE(output, hdr_offset) + len);
 
 	/*
@@ -490,6 +488,5 @@
 	 * ・動的な通信端点の生成・削除機能
 	 */
-	cep->flags &= (TCP_CEP_FLG_WBCS_NBUF_REQ | TCP_CEP_FLG_WBCS_MASK | 
-	               TCP_CEP_FLG_DYNAMIC       | TCP_CEP_FLG_VALID);
+	cep->flags &= TCP_CEP_FLG_NOT_CLEAR;
 
 	return error;
@@ -864,7 +861,7 @@
 #endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
 
-		if ((error = tcp_get_segment(&cep->swbufq, cep, 0,
-		                             (uint_t) TCP_CFG_SWBUF_CSAVE_MIN_SIZE,
-		                             (uint_t)(TCP_CFG_SWBUF_CSAVE_MAX_SIZE - IF_IP_TCP_HDR_SIZE),
+		if ((error = tcpn_get_segment(&cep->swbufq, cep, 0,
+		                             (uint_t)TCP_CFG_SWBUF_CSAVE_MIN_SIZE,
+		                             (uint_t)TCP_CFG_SWBUF_CSAVE_MAX_SIZE,
 		                             (ATR)(NBA_SEARCH_DESCENT |
 		                                   NBA_RESERVE_TCP    |
@@ -888,15 +885,10 @@
 				len = TCP_GET_SWBUF_ADDR(cep, cep->snd_p_buf);
 
+				/* コールバック関数を呼び出す。*/
 #ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
-				/* コールバック関数を呼び出す。*/
 				(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)(uint32_t)len);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-				/* コールバック関数を呼び出す。*/
+#else
 				(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)&len);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+#endif
 
 
@@ -924,15 +916,11 @@
 				/* フラグを、送信可能に設定し、強制的に送信する。*/
 				cep->flags |= TCP_CEP_FLG_FORCE | TCP_CEP_FLG_FORCE_CLEAR | TCP_CEP_FLG_POST_OUTPUT;
+
+				/* コールバック関数を呼び出す。*/
 #ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
-				/* コールバック関数を呼び出す。*/
 				(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)(uint32_t)len);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-				/* コールバック関数を呼び出す。*/
+#else
 				(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)&len);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+#endif
 
 
@@ -999,10 +987,10 @@
 	tcp_init();
 
-#ifdef SUPPORT_INET6
+#ifdef _IP6_CFG
 
 	/* IPv6 のステートレス・アドレス自動設定を実行する。*/
 	in6_if_up(IF_GET_IFNET());
 
-#endif	/* of #ifdef SUPPORT_INET6 */
+#endif	/* of #ifdef _IP6_CFG */
 
 	while (true) {
@@ -1083,15 +1071,9 @@
 
 						if (IS_PTR_DEFINED(cep->callback))
-
 #ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
 							(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)error);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#else
 							(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)&error);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#endif
 						else
 							syslog(LOG_WARNING, "[TCP] no call back, CEP: %d.", GET_TCP_CEPID(cep));
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_seq.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_seq.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_seq.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_subr.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_subr.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_subr.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -96,7 +96,6 @@
 #include <net/if_loop.h>
 #include <net/ethernet.h>
-#include <net/if_arp.h>
-#include <net/ppp_ipcp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_var.h>
 #include <net/net_buf.h>
@@ -105,18 +104,13 @@
 
 #include <netinet/in.h>
-#include <netinet6/in6.h>
-#include <netinet6/in6_var.h>
 #include <netinet/in_var.h>
+#include <netinet/in_itron.h>
 #include <netinet/ip.h>
 #include <netinet/ip_var.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#include <netinet6/nd6.h>
 #include <netinet/tcp.h>
-#include <netinet/tcp_timer.h>
 #include <netinet/tcp_var.h>
 #include <netinet/tcp_fsm.h>
 #include <netinet/tcp_seq.h>
-#include <netinet/in_itron.h>
+#include <netinet/tcp_timer.h>
 
 #ifdef SUPPORT_TCP
@@ -147,4 +141,208 @@
 
 static uint16_t tcp_port_auto = TCP_PORT_FIRST_AUTO;	/* 自動割り当て番号	*/
+
+#if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0
+
+/*
+ *  タスクからの Time Wait 状態 CEP 分離機能
+ */
+
+/*
+ *  変数
+ */
+
+T_TCP_TWCEP tcp_twcep[NUM_TCP_TW_CEP_ENTRY];
+
+/*
+ *  tcp_move_twcep -- 必要な情報を Time Wait 用 TCP 通信端点に移して、
+ *                    標準の TCP 通信端点を開放する。
+ */
+
+void
+tcp_move_twcep (T_TCP_CEP *cep)
+{
+	T_TCP_TWCEP*	twcep;
+
+	/* 空きの Time Wait 用 TCP 通信端点を探索する。*/
+	for (twcep = &tcp_twcep[NUM_TCP_TW_CEP_ENTRY]; twcep -- != tcp_twcep; ) {
+		if (twcep->fsm_state != TCP_FSM_TIME_WAIT) {
+
+			/*
+			 *  通信端点をロックし、
+			 *  必要な情報を Time Wait 用 TCP 通信端点に移す。
+			 */
+			syscall(wai_sem(cep->semid_lock));
+			twcep->flags		= (uint8_t)cep->flags;
+			twcep->rbufsz		= cep->rbufsz;
+			twcep->dstaddr		= cep->dstaddr;
+			twcep->myaddr		= cep->myaddr;
+			twcep->snd_una		= cep->snd_una;
+			twcep->rcv_nxt		= cep->rcv_nxt;
+			twcep->rwbuf_count	= cep->rwbuf_count;
+			twcep->fsm_state	= cep->fsm_state;
+			twcep->timer_2msl	= cep->timer[TCP_TIM_2MSL];
+
+			/* 通信端点をロックを解除する。*/
+			syscall(sig_sem(cep->semid_lock));
+
+			/* 標準 TCP 通信端点を開放する。*/
+			tcp_close(cep);
+
+			break;
+			}
+		}
+	}
+
+/*
+ *  tcp_find_twcep -- ポート番号から Time Wait 用 TCP 通信端点を得る。
+ */
+
+T_TCP_TWCEP*
+tcp_find_twcep (T_NET_BUF *input, uint_t off)
+{
+	T_TCP_TWCEP*	twcep;
+	T_TCP_HDR	*tcph;
+
+	tcph = GET_TCP_HDR(input, off);
+	
+	/*
+	 *  状態が TIME WAIT で、
+	 *  IP アドレスとポート番号が一致する通信端点を探索する。
+	 */
+	for (twcep = &tcp_twcep[NUM_TCP_TW_CEP_ENTRY]; twcep -- != tcp_twcep; ) {
+		if (twcep->fsm_state == TCP_FSM_TIME_WAIT                   &&
+		    IN_IS_DSTADDR_ACCEPT    (&twcep->myaddr.ipaddr,  input) &&
+		    IN_ARE_NET_SRCADDR_EQUAL(&twcep->dstaddr.ipaddr, input) &&
+		    tcph->dport == twcep->myaddr.portno                     &&
+		    tcph->sport == twcep->dstaddr.portno)
+			return twcep;
+		}
+
+	return NULL;
+	}
+
+#endif	/* of #if defined(NUM_TCP_TW_CEP_ENTRY) && NUM_TCP_TW_CEP_ENTRY > 0 */
+
+/*
+ *  tcp_find_cep -- ポート番号から TCP 通信端点を得る。
+ */
+
+T_TCP_CEP*
+tcp_find_cep (T_NET_BUF *input, uint_t off)
+{
+	T_TCP_CEP*	cep;
+	T_TCP_HDR	*tcph;
+
+	tcph = GET_TCP_HDR(input, off);
+	
+	/*
+	 *  状態が SYN 送信済み以後は、
+	 *  IP アドレスとポート番号が一致する TCP 通信端点を探索する。
+	 */
+	for (cep = &tcp_cep[tmax_tcp_cepid]; cep -- != tcp_cep; ) {
+		if (cep->fsm_state >= TCP_FSM_SYN_SENT                    &&
+		    IN_IS_DSTADDR_ACCEPT    (&cep->myaddr.ipaddr,  input) &&
+		    IN_ARE_NET_SRCADDR_EQUAL(&cep->dstaddr.ipaddr, input) &&
+		    tcph->dport == cep->myaddr.portno                     &&
+		    tcph->sport == cep->dstaddr.portno)
+			return cep;
+		}
+
+	/* IPv4 で受動オープン中の TCP 通信端点を先に探索する。*/	
+	for (cep = &tcp_cep[tmax_tcp_cepid]; cep -- != tcp_cep; ) {
+		if ((cep->flags & TCP_CEP_FLG_IPV4)                   &&
+		     cep->fsm_state == TCP_FSM_LISTEN                 &&
+		     GET_IP_VER(input) == IPV4_VERSION                &&
+		     IN_IS_DSTADDR_ACCEPT(&cep->myaddr.ipaddr, input) &&
+		     tcph->dport == cep->myaddr.portno)
+			return cep;
+		}
+
+	/* 受動オープン中の TCP 通信端点を探索する。*/	
+	for (cep = &tcp_cep[tmax_tcp_cepid]; cep -- != tcp_cep; ) {
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+
+		if (cep->flags & TCP_CEP_FLG_IPV4) {
+			if (cep->fsm_state == TCP_FSM_LISTEN                 &&
+		            GET_IP_VER(input) == IPV4_VERSION                &&
+			    IN_IS_DSTADDR_ACCEPT(&cep->myaddr.ipaddr, input) &&
+			    tcph->dport == cep->myaddr.portno)
+				return cep;
+			}
+		else {
+
+#if defined(API_CFG_IP4MAPPED_ADDR)
+
+			if (cep->fsm_state == TCP_FSM_LISTEN                 &&
+			    IN_IS_DSTADDR_ACCEPT(&cep->myaddr.ipaddr, input) &&
+			    tcph->dport == cep->myaddr.portno)
+				return cep;
+
+#else	/* of #if defined(API_CFG_IP4MAPPED_ADDR) */
+
+			if (cep->fsm_state == TCP_FSM_LISTEN                   &&
+			    INN6_IS_DSTADDR_ACCEPT(&cep->myaddr.ipaddr, input) &&
+			    tcph->dport == cep->myaddr.portno)
+				return cep;
+
+#endif	/* of #if defined(API_CFG_IP4MAPPED_ADDR) */
+
+			}
+
+#else	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
+
+		if (cep->fsm_state == TCP_FSM_LISTEN                 &&
+		    IN_IS_DSTADDR_ACCEPT(&cep->myaddr.ipaddr, input) &&
+		    tcph->dport == cep->myaddr.portno)
+			return cep;
+
+#endif	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) */
+		}
+
+	return NULL;
+	}
+
+/*
+ *  tcp_is_addr_accept -- 受信可能な IP アドレスとポート番号であることを確認する。
+ */
+
+bool_t
+tcp_is_addr_accept (T_NET_BUF *input, uint_t off)
+{
+	T_TCP_HDR	*tcph;
+
+	tcph = GET_TCP_HDR(input, off);
+
+#if !defined(_IP6_CFG) && defined(_IP4_CFG) && defined(SUPPORT_LOOP)
+
+	/*
+	 *  次のときは破棄する。
+	 *    ・ポート番号が同一で、送受信 IP アドレス が同一。
+	 *      ただし、送信元 IP アドレスがローカルループバックなら良い。
+	 *    ・マルチキャストアドレス
+	 */
+
+	if (tcph->dport == tcph->sport && 
+	    (IN4_ARE_HDR_ADDR_EQUAL(input) && !IN4_ARE_NET_ADDR_EQUAL(&GET_IP4_HDR(input)->dst, &IPV4_ADDR_LOOPBACK)))
+		return RET_DROP;
+
+#else	/* of #if !defined(_IP6_CFG) && defined(_IP4_CFG) && defined(SUPPORT_LOOP) */
+
+	/*
+	 *  次のときは、受信可能ではない。
+	 *    ・ポート番号が同一で、送受信 IP アドレス が同一。
+	 *    ・マルチキャストアドレス
+	 */
+	if (tcph->dport == tcph->sport && IN_ARE_HDR_ADDR_EQUAL(input))
+		return false;
+
+#endif	/* of #if !defined(_IP6_CFG) && defined(_IP4_CFG) && defined(SUPPORT_LOOP) */
+
+	if (IN_IS_NET_ADDR_MULTICAST(input))
+		return false;
+	else
+		return true;
+	}
 
 /*
@@ -162,5 +360,5 @@
 
 	for (q = cep->reassq; q != NULL; q = nq) {
-		nq = GET_TCP_Q_HDR(q, GET_TCP_IP_Q_HDR(q)->thoff)->next;
+		nq = GET_TCP_Q_HDR(q, GET_IP_TCP_Q_HDR_OFFSET(q))->next;
 		syscall(rel_net_buf(q));
 		}
@@ -184,11 +382,12 @@
 			tcp_port_auto = TCP_PORT_FIRST_AUTO;
 
-#ifdef TCP_CFG_PASSIVE_OPEN
-
-		for (ix = tmax_tcp_repid; ix -- > 0; ) {
+#if defined(TNUM_TCP6_REPID)
+#if TNUM_TCP6_REPID > 0
+
+		for (ix = tmax_tcp6_repid; ix -- > 0; ) {
 
 #ifdef TCP_CFG_EXTENTIONS
 
-			if (VALID_TCP_REP(&tcp_rep[ix]) && tcp_rep[ix].myaddr.portno == portno) {
+			if (VALID_TCP_REP(&tcp6_rep[ix]) && tcp6_rep[ix].myaddr.portno == portno) {
 				portno = TCP_PORTANY;
 				break;
@@ -197,5 +396,5 @@
 #else	/* of #ifdef TCP_CFG_EXTENTIONS */
 
-			if (tcp_rep[ix].myaddr.portno == portno) {
+			if (tcp6_rep[ix].myaddr.portno == portno) {
 				portno = TCP_PORTANY;
 				break;
@@ -206,5 +405,32 @@
 			}
 
-#endif	/* of #ifdef TCP_CFG_PASSIVE_OPEN */
+#endif	/* of #if TNUM_TCP6_REPID > 0 */
+#endif	/* of #if defined(TNUM_TCP6_REPID) */
+
+#if defined(TNUM_TCP4_REPID)
+#if TNUM_TCP4_REPID > 0
+
+		for (ix = tmax_tcp4_repid; ix -- > 0; ) {
+
+#ifdef TCP_CFG_EXTENTIONS
+
+			if (VALID_TCP_REP(&tcp4_rep[ix]) && tcp4_rep[ix].myaddr.portno == portno) {
+				portno = TCP_PORTANY;
+				break;
+				}
+
+#else	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+			if (tcp4_rep[ix].myaddr.portno == portno) {
+				portno = TCP_PORTANY;
+				break;
+				}
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+			}
+
+#endif	/* of #if TNUM_TCP4_REPID > 0 */
+#endif	/* of #if defined(TNUM_TCP4_REPID) */
 
 		if (portno != TCP_PORTANY) {
@@ -273,22 +499,6 @@
 	SYSTIM now;
 
-#ifdef SUPPORT_ETHER
-
-	T_IF_SOFTC	*ic;
-
-	ic = IF_ETHER_NIC_GET_SOFTC();
-	syscall(get_tim(&now));
-	net_srand(now + (ic->ifaddr.lladdr[2] << 24)
-	              + (ic->ifaddr.lladdr[3] << 16)
-	              + (ic->ifaddr.lladdr[4] <<  8)
-	              + (ic->ifaddr.lladdr[5]      ));
-
-#else	/* of #ifdef SUPPORT_ETHER */
-
 	syscall(get_tim(&now));
 	net_srand(now);
-
-#endif	/* of #ifdef SUPPORT_ETHER */
-
 	tcp_iss = net_rand();
 	}
@@ -319,7 +529,7 @@
 	 * ・送受信ウィンドバッファの省コピー機能
 	 * ・動的な通信端点の生成・削除機能
+	 * ・通信端点のネットワーク層プロトコル
 	 */
-	cep->flags &= (TCP_CEP_FLG_WBCS_NBUF_REQ | TCP_CEP_FLG_WBCS_MASK | 
-	               TCP_CEP_FLG_DYNAMIC       | TCP_CEP_FLG_VALID);
+	cep->flags &= TCP_CEP_FLG_NOT_CLEAR;
 
 #ifdef TCP_CFG_NON_BLOCKING
@@ -341,4 +551,9 @@
 					/* TCP 通信端点からTCP 受付口を解放する。*/
 					cep->rep = NULL;
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+					cep->rep4 = NULL;
+#endif
+
 					(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)E_CLS);
 					break;
@@ -397,4 +612,9 @@
 					/* TCP 通信端点から TCP 受付口を解放する。*/
 					cep->rep = NULL;
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+					cep->rep4 = NULL;
+#endif
+
 					(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)E_CLS);
 					break;
@@ -431,6 +651,13 @@
 
 				case TFN_TCP_ACP_CEP:
+
 					/* TCP 通信端点からTCP 受付口を解放する。*/
 					cep->rep = NULL;
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+					cep->rep4 = NULL;
+#endif
+
+					/* 接続エラーを設定する。*/
 					len      = E_CLS;
 					(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&len);
@@ -489,6 +716,13 @@
 
 				case TFN_TCP_CON_CEP:
-					/* TCP 通信端点から TCP 受付口を解放する。*/
+
+					/* TCP 通信端点からTCP 受付口を解放する。*/
 					cep->rep = NULL;
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+					cep->rep4 = NULL;
+#endif
+
+					/* 接続エラーを設定する。*/
 					len      = E_CLS;
 					(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)&len);
@@ -589,6 +823,7 @@
 		sig_sem(SEM_TCP_POST_OUTPUT);
 		}
-	else
+	else {
 		cep = tcp_close(cep);
+		}
 	return cep;
 	}
@@ -602,7 +837,7 @@
              T_TCP_SEQ ack, T_TCP_SEQ seq, uint_t rbfree, uint8_t flags)
 {
-	T_IP_HDR	*iph;
 	T_TCP_HDR	*tcph;
 	uint_t		win = 0;
+	uint_t		hdr_offset;
 
 	if ((flags & TCP_FLG_RST) == 0)
@@ -614,6 +849,5 @@
 	 */
 	if (output != NULL) {
-		T_IN_ADDR	ipaddr;
-		uint16_t		portno;
+		uint16_t	portno;
 
 		/*
@@ -626,22 +860,17 @@
 			}
 
-		iph  = GET_IP_HDR(output);
-
-		/* IP アドレスを交換する。*/
-		ipaddr = iph->src;
-		iph->src = iph->dst;
-		iph->dst = ipaddr;
-
-#if defined(SUPPORT_INET6)
+		ip_exchg_addr(output);
+
+#if defined(_IP6_CFG)
 
 		/* トラヒッククラスとフローラベルをクリアする。*/
-		iph->vcf = htonl(IP6_MAKE_VCF(IP6_VCF_V(ntohl(iph->vcf)), 0));
-
-#endif	/* of #if defined(SUPPORT_INET6) */
+		SET_IP_CF(output, 0);
+
+#endif	/* of #if defined(_IP6_CFG) */
 
 		/* TCP SDU 長を 0 にする。*/
-		SET_IP_SDU_SIZE(iph, TCP_HDR_SIZE);
-
-		tcph = GET_TCP_HDR(output, IF_IP_TCP_HDR_OFFSET);
+		SET_IP_SDU_SIZE(output, TCP_HDR_SIZE);
+
+		tcph = GET_TCP_HDR(output, IF_IP_TCP_HDR_OFFSET(output));
 
 		/* ポート番号を交換する。*/
@@ -658,9 +887,9 @@
 		return;
 	else {
-		if (tcp_get_segment(&output, cep, 0,
-		                    0, (uint_t)(net_buf_max_siz() - IF_IP_TCP_HDR_SIZE),
+		if (tcpn_get_segment(&output, cep, 0,
+		                    0, (uint_t)net_buf_max_siz(),
 		                    NBA_SEARCH_ASCENT, TMO_TCP_GET_NET_BUF) != E_OK)
 			return;
-		tcph = GET_TCP_HDR(output, IF_IP_TCP_HDR_OFFSET);
+		tcph = GET_TCP_HDR(output, IF_IP_TCP_HDR_OFFSET(output));
 		flags |= TCP_FLG_ACK;
 		}
@@ -675,9 +904,10 @@
 	 *  チェックサムを設定する。
 	 */
-	tcph->sum = IN_CKSUM(output, IPPROTO_TCP, IF_IP_TCP_HDR_OFFSET, 
-	                     (uint_t)GET_TCP_HDR_SIZE2(output, IF_IP_TCP_HDR_OFFSET));
+	hdr_offset = IF_IP_TCP_HDR_OFFSET(output);
+	tcph->sum = IN_CKSUM(output, IPPROTO_TCP, hdr_offset, 
+	                     (uint_t)GET_TCP_HDR_SIZE(output, hdr_offset));
 
 	/* ネットワークバッファ長を調整する。*/
-	output->len = (uint16_t)GET_IF_IP_TCP_HDR_SIZE2(output, IF_IP_TCP_HDR_OFFSET);
+	output->len = (uint16_t)GET_IF_IP_TCP_HDR_SIZE(output, hdr_offset);
 
 #ifdef TCP_CFG_TRACE
@@ -690,21 +920,5 @@
 	IP_OUTPUT(output, TMO_TCP_OUTPUT);
 	}
-
-/*
- *  tcp_set_header -- TCP ヘッダを設定する。
- */
-
-void
-tcp_set_header (T_NET_BUF *nbuf, T_TCP_CEP *cep, uint_t thoff, uint_t optlen)
-{
-	T_TCP_HDR	*tcph = GET_TCP_HDR(nbuf, thoff);
-
-	/* TCP ヘッダに情報を設定する。*/
-	tcph->sport	= htons(cep->myaddr.portno);
-	tcph->dport	= htons(cep->dstaddr.portno);
-	tcph->doff	= TCP_MAKE_DATA_OFF(TCP_HDR_SIZE + optlen);
-	tcph->sum	= tcph->flags = 0;
-	}
-
+#if 0
 /*
  *  tcp_get_segment -- TCP セグメントを獲得し、ヘッダを設定する。
@@ -712,4 +926,5 @@
  *    戻り値	エラーコード
  *    optlen	オプションサイズ、4 オクテット単位
+ *    maxlen	最大セグメントサイズ（IF/IP/TCP ヘッダサイズを含まない）
  *    len	TCP SDU サイズ
  */
@@ -719,4 +934,5 @@
                  uint_t optlen, uint_t len, uint_t maxlen, ATR nbatr, TMO tmout)
 {
+	T_TCP_HDR	*tcph;
 	ER		error;
 
@@ -728,4 +944,44 @@
 	                             &cep->myaddr.ipaddr,
 	                             IPPROTO_TCP, IP_DEFTTL, nbatr, tmout)) != E_OK) {
+		syslog(LOG_WARNING, "[TCP] NET BUF busy, len: %d, CEP: %d.",
+		                    (uint16_t)(TCP_HDR_SIZE + optlen + len), GET_TCP_CEPID(cep));
+		return error;
+		}
+
+	/* TCP ヘッダに情報を設定する。*/
+
+	/* TCP ヘッダに情報を設定する。*/
+	tcph = GET_TCP_HDR(*nbuf, IF_IP_TCP_HDR_OFFSET(*nbuf));
+	tcph->sport	= htons(cep->myaddr.portno);
+	tcph->dport	= htons(cep->dstaddr.portno);
+	tcph->doff	= TCP_MAKE_DATA_OFF(TCP_HDR_SIZE + optlen);
+	tcph->sum	= tcph->flags = 0;
+
+	return E_OK;
+	}
+#endif
+/*
+ *  tcpn_get_segment -- TCP セグメントを獲得し、ヘッダを設定する。
+ *
+ *    戻り値	エラーコード
+ *    optlen	オプションサイズ、4 オクテット単位
+ *    maxlen	最大セグメントサイズ（IF/IP/TCP ヘッダサイズを含む）
+ *    len	TCP SDU サイズ
+ */
+
+ER
+tcpn_get_segment (T_NET_BUF **nbuf, T_TCP_CEP *cep,
+                 uint_t optlen, uint_t len, uint_t maxlen, ATR nbatr, TMO tmout)
+{
+	T_TCP_HDR	*tcph;
+	ER		error;
+
+	/* IP データグラムを獲得する。*/
+	if ((error = IN_GET_DATAGRAM(nbuf,
+	                             (uint_t)(TCP_HDR_SIZE + optlen + len),
+	                             (uint_t)(maxlen - IF_IP_NET_HDR_SIZE(&cep->dstaddr.ipaddr)),
+	                             &cep->dstaddr.ipaddr,
+	                             &cep->myaddr.ipaddr,
+	                             IPPROTO_TCP, IP_DEFTTL, nbatr, tmout)) != E_OK) {
 		syslog(LOG_WARNING, "[TCP] NET BUF busy,  len:%4d, CEP: %d.",
 		                    (uint16_t)(TCP_HDR_SIZE + optlen + len), GET_TCP_CEPID(cep));
@@ -734,5 +990,11 @@
 
 	/* TCP ヘッダに情報を設定する。*/
-	tcp_set_header(*nbuf, cep, IF_IP_TCP_HDR_OFFSET, optlen);
+
+	/* TCP ヘッダに情報を設定する。*/
+	tcph = GET_TCP_HDR(*nbuf, IF_IP_TCP_HDR_OFFSET(*nbuf));
+	tcph->sport	= htons(cep->myaddr.portno);
+	tcph->dport	= htons(cep->dstaddr.portno);
+	tcph->doff	= TCP_MAKE_DATA_OFF(TCP_HDR_SIZE + optlen);
+	tcph->sum	= tcph->flags = 0;
 
 	return E_OK;
@@ -761,17 +1023,10 @@
 				error = E_OBJ;
 			else {
-
+				/* コールバック関数を呼び出す。*/
 #ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
-				/* コールバック関数を呼び出す。*/
 				(*cep->callback)(GET_TCP_CEPID(cep), fncd, (void*)error);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-				/* コールバック関数を呼び出す。*/
+#else
 				(*cep->callback)(GET_TCP_CEPID(cep), fncd, (void*)&error);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#endif
 				error = E_WBLK;
 				}
@@ -798,18 +1053,12 @@
 					error = E_OBJ;
 				else {
-
+					error = E_OBJ;
+
+					/* コールバック関数を呼び出す。*/
 #ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
-					/* コールバック関数を呼び出す。*/
-					(*cep->callback)(GET_TCP_CEPID(cep), fncd, (void*)E_OBJ);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-					/* コールバック関数を呼び出す。*/
-					error = E_OBJ;
+					(*cep->callback)(GET_TCP_CEPID(cep), fncd, (void*)error);
+#else
 					(*cep->callback)(GET_TCP_CEPID(cep), fncd, (void*)&error);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#endif
 					error = E_WBLK;
 					}
@@ -859,16 +1108,10 @@
 				*error = E_OBJ;
 			else {
+				/* コールバック関数を呼び出す。*/
 #ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
-				/* コールバック関数を呼び出す。*/
 				(*cep->callback)(GET_TCP_CEPID(cep), fncd, (void*)*error);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-				/* コールバック関数を呼び出す。*/
+#else
 				(*cep->callback)(GET_TCP_CEPID(cep), fncd, (void*)error);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#endif
 				*error = E_WBLK;
 				}
@@ -900,18 +1143,12 @@
 					*error = E_OBJ;
 				else {
-
+					*error = E_OBJ;
+
+					/* コールバック関数を呼び出す。*/
 #ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
-					/* コールバック関数を呼び出す。*/
-					(*cep->callback)(GET_TCP_CEPID(cep), fncd, (void*)E_OBJ);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-					/* コールバック関数を呼び出す。*/
-					*error = E_OBJ;
+					(*cep->callback)(GET_TCP_CEPID(cep), fncd, (void*)*error);
+#else
 					(*cep->callback)(GET_TCP_CEPID(cep), fncd, (void*)error);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#endif
 					*error = E_WBLK;
 					}
@@ -961,6 +1198,4 @@
 				 *  受信ウィンドバッファキューのネットワークバッファを解放する。
 				 */
-#ifdef TCP_CFG_RWBUF_CSAVE
-#endif
 				syscall(wai_sem(cep->semid_lock));
 				TCP_FREE_RWBUFQ(cep);
@@ -971,6 +1206,7 @@
 			}
 		}
-	else
+	else {
 		syscall(clr_flg(cep->rcv_flgid, (FLGPTN)(~TCP_CEP_EVT_RWBUF_READY)));
+		}
 
 	return E_OK;
@@ -994,5 +1230,5 @@
 		while (cep->reassq != NULL) {
 			q = cep->reassq;
-			qhdr = GET_TCP_Q_HDR(q, GET_TCP_IP_Q_HDR(q)->thoff);
+			qhdr = GET_TCP_Q_HDR(q, GET_IP_TCP_Q_HDR_OFFSET(q));
 			if (qhdr->seq != cep->rcv_nxt)
 				break;
@@ -1005,5 +1241,5 @@
 
 			/* データを受信ウィンドバッファに書き込む。*/
-			TCP_WRITE_RWBUF(cep, q, (uint_t)(GET_TCP_IP_Q_HDR(q)->thoff));
+			TCP_WRITE_RWBUF(cep, q, (uint_t)(GET_IP_TCP_Q_HDR_OFFSET(q)));
 			}
 		}
@@ -1028,5 +1264,5 @@
 
 	/*  TCP ヘッダの位置を保存する。*/
-	GET_TCP_IP_Q_HDR(input)->thoff = thoff;
+	SET_IP_TCP_Q_HDR_OFFSET(input, thoff);
 
 	/*
@@ -1035,5 +1271,5 @@
 	 *  このとき、IP のオプション（拡張ヘッダ）と TCP のオプションは削除する。
 	 */
-	len  = IF_IP_TCP_HDR_SIZE + inqhdr->slen;
+	len  = IF_IP_TCP_HDR_SIZE(input) + inqhdr->slen;
 
 	if (len <= MAX_TCP_REALLOC_SIZE) {
@@ -1080,5 +1316,5 @@
 	 */
 	for (q = cep->reassq, p = NULL; q != NULL; ) {
-		qhdr = GET_TCP_Q_HDR(q, GET_TCP_IP_Q_HDR(q)->thoff);
+		qhdr = GET_TCP_Q_HDR(q, GET_IP_TCP_Q_HDR_OFFSET(q));
 		if (SEQ_GT(qhdr->seq, inqhdr->seq))
 			break;
@@ -1106,5 +1342,5 @@
 	 */
 	if (p != NULL) {
-		qhdr = GET_TCP_Q_HDR(p, GET_TCP_IP_Q_HDR(p)->thoff);
+		qhdr = GET_TCP_Q_HDR(p, GET_IP_TCP_Q_HDR_OFFSET(p));
 		len = qhdr->seq + qhdr->slen - inqhdr->seq;
 		if (len > 0) {
@@ -1169,5 +1405,5 @@
 	 */
 	while (q != NULL) {
-		qhdr = GET_TCP_Q_HDR(q, GET_TCP_IP_Q_HDR(q)->thoff);
+		qhdr = GET_TCP_Q_HDR(q, GET_IP_TCP_Q_HDR_OFFSET(q));
 		len = inqhdr->seq + inqhdr->slen - qhdr->seq;
 		if (len <= 0)
@@ -1201,5 +1437,5 @@
 		nq = qhdr->next;
 		if (p)
-			GET_TCP_Q_HDR(p, GET_TCP_IP_Q_HDR(p)->thoff)->next = nq;
+			GET_TCP_Q_HDR(p, GET_IP_TCP_Q_HDR_OFFSET(p))->next = nq;
 		else
 			cep->reassq = nq;
@@ -1213,6 +1449,6 @@
 		}
 	else {
-		inqhdr->next = GET_TCP_Q_HDR(p, GET_TCP_IP_Q_HDR(p)->thoff)->next;
-		GET_TCP_Q_HDR(p, GET_TCP_IP_Q_HDR(p)->thoff)->next = input;
+		inqhdr->next = GET_TCP_Q_HDR(p, GET_IP_TCP_Q_HDR_OFFSET(p))->next;
+		GET_TCP_Q_HDR(p, GET_IP_TCP_Q_HDR_OFFSET(p))->next = input;
 		}
 
@@ -1243,4 +1479,5 @@
 tcp_init_cep (T_TCP_CEP *cep)
 {
+
 #ifdef TCP_CFG_RWBUF_CSAVE
 	/*
@@ -1255,4 +1492,5 @@
 #endif	/* of #ifdef TCP_CFG_RWBUF_CSAVE */
 
+
 	memset((uint8_t*)cep + offsetof(T_TCP_CEP, timer), 0,
 	       sizeof(T_TCP_CEP) - offsetof(T_TCP_CEP, timer));
@@ -1273,10 +1511,10 @@
 	 * ・送受信ウィンドバッファの省コピー機能
 	 * ・動的な通信端点の生成・削除機能
+	 * ・通信端点のネットワーク層プロトコル
 	 */
-	cep->flags &= (TCP_CEP_FLG_WBCS_NBUF_REQ | TCP_CEP_FLG_WBCS_MASK | 
-	               TCP_CEP_FLG_DYNAMIC       | TCP_CEP_FLG_VALID);
+	cep->flags &= TCP_CEP_FLG_NOT_CLEAR;
 
 	/* セマフォを初期化する。*/
-	sig_sem (cep->semid_lock);
+	sig_sem(cep->semid_lock);
 
 	/* フラグを初期化する。*/
@@ -1292,12 +1530,7 @@
 tcp_notify (T_NET_BUF *input, ER error)
 {
-	T_IP_HDR	*iph;
-	T_TCP_HDR	*tcph;
 	T_TCP_CEP	*cep;
 
-	iph  = GET_IP_HDR(input);
-	tcph = GET_TCP_HDR(input, GET_TCP_HDR_OFFSET(input));
-
-	if ((cep = tcp_find_cep(&iph->src, tcph->sport, &iph->dst, tcph->dport)) != NULL) {
+	if ((cep = tcp_find_cep(input, GET_TCP_HDR_OFFSET(input))) != NULL) {
 
 		/*
@@ -1328,41 +1561,4 @@
 
 /*
- *  tcp_find_cep -- ポート番号から TCP 通信端点を得る。
- *
- *    注意: dstaddr は、
- *          TINET-1.2 からネットワークバイトオーダ、
- *          TINET-1.1 までは、ホストバイトオーダ
- */
-
-T_TCP_CEP*
-tcp_find_cep (T_IN_ADDR *dstaddr, uint16_t dstport, T_IN_ADDR *peeraddr, uint16_t peerport)
-{
-	T_TCP_CEP*	cep;
-	
-	/*
-	 *  状態が SYN 送信済み以後は、
-	 *  IP アドレスとポート番号が一致する通信端点を探索する。
-	 */
-	for (cep = &tcp_cep[tmax_tcp_cepid]; cep -- != tcp_cep; ) {
-		if (cep->fsm_state >= TCP_FSM_SYN_SENT                    &&
-		    IN_IS_DSTADDR_ACCEPT (&cep->myaddr.ipaddr,  dstaddr)  &&
-		    IN_ARE_NET_ADDR_EQUAL(&cep->dstaddr.ipaddr, peeraddr) &&
-		    dstport  == cep->myaddr.portno                        &&
-		    peerport == cep->dstaddr.portno)
-			return cep;
-		}
-
-	/* 受動オープン中の通信端点を探索する。*/	
-	for (cep = &tcp_cep[tmax_tcp_cepid]; cep -- != tcp_cep; ) {
-		if (cep->fsm_state == TCP_FSM_LISTEN &&
-		    IN_IS_DSTADDR_ACCEPT(&cep->myaddr.ipaddr, dstaddr) &&
-		    dstport == cep->myaddr.portno)
-			return cep;
-		}
-
-	return NULL;
-	}
-
-/*
  *  tcp_lock_cep -- TCP 通信端点をロックする。
  */
@@ -1377,5 +1573,5 @@
 
 	/* TCP 通信端点 ID をチェックする。*/
-	if (!VAID_TCP_CEPID(cepid))
+	if (!VALID_TCP_CEPID(cepid))
 		return E_ID;
 
@@ -1424,4 +1620,8 @@
 
 #ifdef TCP_CFG_TRACE
+
+/*
+ *  トレース出力に用いるシリアルポート番号
+ */
 
 #ifndef CONSOLE_PORTID
@@ -1624,5 +1824,4 @@
 {
 	SYSTIM		time;
-	T_IP_HDR	*iph;
 	T_TCP_HDR	*tcph;
 	char		buf[9];
@@ -1632,14 +1831,25 @@
 		return;
 
-#if defined(SUPPORT_INET4)
+#if defined(_IP4_CFG)
+
+#if defined(_IP6_CFG)
+
+	if (!((TCP_CFG_TRACE_IPV4_RADDR == IPV4_ADDRANY) ||
+	     ((cep->flags & TCP_CEP_FLG_IPV4) && 
+	      IN6_IS_ADDR_V4MAPPED(&cep->dstaddr.ipaddr) &&
+	      (ntohl(cep->dstaddr.ipaddr.s6_addr32[3]) == TCP_CFG_TRACE_IPV4_RADDR))))
+		return;
+
+#else	/* of #if defined(_IP6_CFG) */
 
 	if (!(TCP_CFG_TRACE_IPV4_RADDR == IPV4_ADDRANY || cep->dstaddr.ipaddr == TCP_CFG_TRACE_IPV4_RADDR))
 		return;
 
-#endif	/* of #if defined(SUPPORT_INET4) */
+#endif	/* of #if defined(_IP6_CFG) */
+
+#endif	/* of #if defined(_IP4_CFG) */
 
 	syscall(wai_sem(SEM_TCP_TRACE));
 	syscall(get_tim(&time));
-	iph  = GET_IP_HDR(output);
 	tcph = GET_TCP_HDR(output, GET_TCP_HDR_OFFSET(output));
 	if (time > 99999999)
@@ -1648,7 +1858,7 @@
 		trace_printf(CONSOLE_PORTID, "=O%6d.%03d", time / 1000, time % 1000);
 	if (cep == NULL)
-		trace_printf(CONSOLE_PORTID, "=c:-- s:-- f:-----");
+		trace_printf(CONSOLE_PORTID, "=c:-- s:-- f:--------");
 	else
-		trace_printf(CONSOLE_PORTID, "=c:%2d s:%s f:%05x",
+		trace_printf(CONSOLE_PORTID, "=c:%2d s:%s f:%08x",
 		                             GET_TCP_CEPID(cep),
 		                             tcp_strfsm[cep->fsm_state], cep->flags);
@@ -1663,5 +1873,5 @@
 	trace_printf(CONSOLE_PORTID, " w:%5d l:%4d>\n", 
 	                             ntohs(tcph->win),
-	                             GET_IP_SDU_SIZE(iph) - TCP_HDR_LEN(tcph->doff));
+	                             GET_IP_SDU_SIZE(output) - TCP_HDR_LEN(tcph->doff));
 	syscall(sig_sem(SEM_TCP_TRACE));
 	}
@@ -1677,5 +1887,4 @@
 {
 	SYSTIM		time;
-	T_IP_HDR	*iph;
 	T_TCP_HDR	*tcph;
 	char		buf[9];
@@ -1685,14 +1894,25 @@
 		return;
 
-#if defined(SUPPORT_INET4)
+#if defined(_IP4_CFG)
+
+#if defined(_IP6_CFG)
+
+	if (!((TCP_CFG_TRACE_IPV4_RADDR == IPV4_ADDRANY) ||
+	     ((cep->flags & TCP_CEP_FLG_IPV4) && 
+	      IN6_IS_ADDR_V4MAPPED(&cep->dstaddr.ipaddr) &&
+	      (ntohl(cep->dstaddr.ipaddr.s6_addr32[3]) == TCP_CFG_TRACE_IPV4_RADDR))))
+		return;
+
+#else	/* of #if defined(_IP6_CFG) */
 
 	if (!(TCP_CFG_TRACE_IPV4_RADDR == IPV4_ADDRANY || cep->dstaddr.ipaddr == TCP_CFG_TRACE_IPV4_RADDR))
 		return;
 
-#endif	/* of #if defined(SUPPORT_INET4) */
+#endif	/* of #if defined(_IP6_CFG) */
+
+#endif	/* of #if defined(_IP4_CFG) */
 
 	syscall(wai_sem(SEM_TCP_TRACE));
 	syscall(get_tim(&time));
-	iph  = GET_IP_HDR(input);
 	tcph = GET_TCP_HDR(input, GET_TCP_HDR_OFFSET(input));
 	if (time > 99999999)
@@ -1701,7 +1921,7 @@
 		trace_printf(CONSOLE_PORTID, "<I%6d.%03d", time / 1000, time % 1000);
 	if (cep == NULL)
-		trace_printf(CONSOLE_PORTID, "=c:-- s:-- f:-----");
+		trace_printf(CONSOLE_PORTID, "=c:-- s:-- f:--------");
 	else
-		trace_printf(CONSOLE_PORTID, "=c:%2d s:%s f:%05x",
+		trace_printf(CONSOLE_PORTID, "=c:%2d s:%s f:%08x",
 		                             GET_TCP_CEPID(cep),
 		                             tcp_strfsm[cep->fsm_state], cep->flags);
@@ -1712,5 +1932,5 @@
 		trace_printf(CONSOLE_PORTID, " a:%10u s:%10u", tcph->ack, tcph->seq);
 	trace_printf(CONSOLE_PORTID, " w:%5d l:%4d=\n", 
-	                             tcph->win, GET_IP_SDU_SIZE(iph) - TCP_HDR_LEN(tcph->doff));
+	                             tcph->win, GET_IP_SDU_SIZE(input) - TCP_HDR_LEN(tcph->doff));
 	syscall(sig_sem(SEM_TCP_TRACE));
 	}
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_subr_cs.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_subr_cs.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_subr_cs.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -95,6 +95,6 @@
 #include <net/ethernet.h>
 #include <net/if_arp.h>
-#include <net/ppp_ipcp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_var.h>
 #include <net/net_buf.h>
@@ -103,18 +103,13 @@
 
 #include <netinet/in.h>
-#include <netinet6/in6.h>
-#include <netinet6/in6_var.h>
 #include <netinet/in_var.h>
+#include <netinet/in_itron.h>
 #include <netinet/ip.h>
 #include <netinet/ip_var.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#include <netinet6/nd6.h>
 #include <netinet/tcp.h>
-#include <netinet/tcp_timer.h>
 #include <netinet/tcp_var.h>
 #include <netinet/tcp_fsm.h>
 #include <netinet/tcp_seq.h>
-#include <netinet/in_itron.h>
+#include <netinet/tcp_timer.h>
 
 #ifdef SUPPORT_TCP
@@ -122,5 +117,7 @@
 #ifdef TCP_CFG_SWBUF_CSAVE
 
-#ifndef TCP_CFG_SWBUF_CSAVE_ONLY
+#ifdef TCP_CFG_SWBUF_CSAVE_ONLY
+
+#else	/* of #ifdef TCP_CFG_SWBUF_CSAVE_ONLY */
 
 /*
@@ -242,5 +239,5 @@
 	}
 
-#endif	/* of #ifndef TCP_CFG_SWBUF_CSAVE_ONLY */
+#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE_ONLY */
 
 /*
@@ -270,10 +267,10 @@
 {
 	ER_UINT	error;
+	uint_t	hdr_size = IF_IP_TCP_NET_HDR_SIZE(&cep->dstaddr.ipaddr);
 
 	/* 通信端点をロックする。*/
 	syscall(wai_sem(cep->semid_lock));
 
-	if ((error = net_buf_siz(cep->swbufq)) > 0 && error >= IF_IP_TCP_HDR_SIZE) {
-
+	if ((error = net_buf_siz(cep->swbufq)) > 0 && error >= hdr_size) {
 
 		/*
@@ -291,10 +288,10 @@
 		 *  空きサイズを 4 オクテット境界に調整する。
 		 */
-		error = (uint_t)(((error - IF_IP_TCP_HDR_SIZE) >> 2 << 2) + IF_IP_TCP_HDR_SIZE);
+		error = (uint_t)(((error - hdr_size) >> 2 << 2) + hdr_size);
 
 		if (len > cep->sbufsz - cep->swbuf_count)
 			len = (uint_t)(cep->sbufsz - cep->swbuf_count);
-		if (len > (error - IF_IP_TCP_HDR_SIZE))
-			len = (uint_t)(error - IF_IP_TCP_HDR_SIZE);
+		if (len > (error - hdr_size))
+			len = (uint_t)(error - hdr_size);
 
 		/* 送信ウインドサイズによりサイズを調整する。*/
@@ -315,6 +312,6 @@
 
 		/* ネットワークバッファ長と IP データグラム長を設定する。*/
-		cep->swbufq->len = (uint16_t)(cep->swbuf_count + IF_IP_TCP_HDR_SIZE);
-		SET_IP_SDU_SIZE(GET_IP_HDR(cep->swbufq), cep->swbuf_count + TCP_HDR_SIZE);
+		cep->swbufq->len = (uint16_t)(cep->swbuf_count + hdr_size);
+		SET_IP_SDU_SIZE(cep->swbufq, cep->swbuf_count + TCP_HDR_SIZE);
 
 		/* フラグを、送信可能に設定する。*/
@@ -324,5 +321,5 @@
 	else {	/* 送信ウインドバッファが不正 */
 		syslog(LOG_WARNING, "[TCP] illegal window buff for send, CEP: %d, %4d < %4d.",
-		                    GET_TCP_CEPID(cep), error, IF_IP_TCP_HDR_SIZE);
+		                    GET_TCP_CEPID(cep), error, hdr_size);
 
 		/* 送信ウィンドバッファキューのネットワークバッファを解放する。*/
@@ -348,8 +345,7 @@
 	int_t	win;
 
-
 	/* 送信ウィンドバッファが割当て済みで、空きがあれば終了する。*/
 	if ((cep->flags & TCP_CEP_FLG_WBCS_MASK) == TCP_CEP_FLG_WBCS_NBUF_READY &&
-	    (cep->swbuf_count + IF_IP_TCP_HDR_SIZE) < net_buf_siz(cep->swbufq))
+	    (cep->swbuf_count + IF_IP_TCP_NET_HDR_SIZE(&cep->dstaddr.ipaddr)) < net_buf_siz(cep->swbufq))
 		return E_OK;
 
@@ -423,7 +419,7 @@
 
 	/* ネットワークバッファを獲得する。*/
-	if ((error = tcp_get_segment(&cep->swbufq, cep, 0,
+	if ((error = tcpn_get_segment(&cep->swbufq, cep, 0,
 	                             TCP_CFG_SWBUF_CSAVE_MIN_SIZE,
-	                             TCP_CFG_SWBUF_CSAVE_MAX_SIZE - IF_IP_TCP_HDR_SIZE,
+	                             TCP_CFG_SWBUF_CSAVE_MAX_SIZE,
 	                             NBA_SEARCH_DESCENT, tmout)) != E_OK)
 		return error;
@@ -463,5 +459,5 @@
 		 *  空きサイズを 4 オクテット境界に調整する。
 		 */
-		error = (uint_t)(((error - IF_IP_TCP_HDR_SIZE) >> 2 << 2) - cep->swbuf_count);
+		error = (uint_t)(((error - IF_IP_TCP_NET_HDR_SIZE(&cep->dstaddr.ipaddr)) >> 2 << 2) - cep->swbuf_count);
 
 		/* 送信ウインドサイズによりサイズを調整する。*/
@@ -508,6 +504,6 @@
 
 	/* ネットワークバッファ長と IP データグラム長を設定する。*/
-	cep->swbufq->len = (uint16_t)(cep->swbuf_count + IF_IP_TCP_HDR_SIZE);
-	SET_IP_SDU_SIZE(GET_IP_HDR(cep->swbufq), len + TCP_HDR_SIZE);
+	cep->swbufq->len = (uint16_t)(cep->swbuf_count + IF_IP_TCP_NET_HDR_SIZE(&cep->dstaddr.ipaddr));
+	SET_IP_SDU_SIZE(cep->swbufq, len + TCP_HDR_SIZE);
 
 	/* tcp_get_buf の割当て長をリセットする。*/
@@ -573,5 +569,5 @@
 {
 	return (cep->flags & TCP_CEP_FLG_WBCS_MASK) != TCP_CEP_FLG_WBCS_NBUF_READY ||
-	        cep->swbuf_count >= cep->swbufq->len - IF_IP_TCP_HDR_SIZE;
+	        cep->swbuf_count >= cep->swbufq->len - IF_IP_TCP_NET_HDR_SIZE(&cep->dstaddr.ipaddr);
 	}
 
@@ -590,5 +586,5 @@
 
 	/* 送信ウインドバッファのアドレスを設定する。*/
-	cep->sbuf_wptr = cep->sbuf_rptr = GET_TCP_SDU(cep->swbufq, IF_IP_TCP_HDR_OFFSET);
+	cep->sbuf_wptr = cep->sbuf_rptr = GET_TCP_SDU(cep->swbufq, IF_IP_TCP_NET_HDR_OFFSET(&cep->dstaddr.ipaddr));
 
 	/* フラグを、ネットワークバッファ割当て済みに設定する。*/
@@ -664,5 +660,7 @@
 #ifdef TCP_CFG_RWBUF_CSAVE 
 
-#ifndef TCP_CFG_RWBUF_CSAVE_ONLY
+#ifdef TCP_CFG_RWBUF_CSAVE_ONLY
+
+#else	/* of #ifdef TCP_CFG_RWBUF_CSAVE_ONLY */
 
 /*
@@ -736,5 +734,5 @@
 	}
 
-#endif	/* of #ifndef TCP_CFG_RWBUF_CSAVE_ONLY */
+#endif	/* of #ifdef TCP_CFG_RWBUF_CSAVE_ONLY */
 
 /*
@@ -753,5 +751,5 @@
 	if (cep->rwbufq != NULL) {
 
-		qhdr = GET_TCP_Q_HDR(cep->rwbufq, GET_TCP_IP_Q_HDR(cep->rwbufq)->thoff);
+		qhdr = GET_TCP_Q_HDR(cep->rwbufq, GET_IP_TCP_Q_HDR_OFFSET(cep->rwbufq));
 		cep->rwbuf_count -= len;
 
@@ -796,5 +794,5 @@
 	 */
 	while (cep->rwbufq != NULL && len > 0) {
-		qhdr = GET_TCP_Q_HDR(cep->rwbufq, GET_TCP_IP_Q_HDR(cep->rwbufq)->thoff);
+		qhdr = GET_TCP_Q_HDR(cep->rwbufq, GET_IP_TCP_Q_HDR_OFFSET(cep->rwbufq));
 
 		/*
@@ -808,5 +806,5 @@
 
 		memcpy(buf,
-		       GET_TCP_SDU(cep->rwbufq, GET_TCP_IP_Q_HDR(cep->rwbufq)->thoff) + qhdr->soff,
+		       GET_TCP_SDU(cep->rwbufq, GET_IP_TCP_Q_HDR_OFFSET(cep->rwbufq)) + qhdr->soff,
 		       (size_t)blen);
 
@@ -850,6 +848,6 @@
 
 		/* 受信ウィンドバッファのデータのアドレスの先頭を設定する。*/
-		qhdr = GET_TCP_Q_HDR(cep->rwbufq, GET_TCP_IP_Q_HDR(cep->rwbufq)->thoff);
-		*p_buf = GET_TCP_SDU(cep->rwbufq, GET_TCP_IP_Q_HDR(cep->rwbufq)->thoff) + qhdr->soff;
+		qhdr = GET_TCP_Q_HDR(cep->rwbufq, GET_IP_TCP_Q_HDR_OFFSET(cep->rwbufq));
+		*p_buf = GET_TCP_SDU(cep->rwbufq, GET_IP_TCP_Q_HDR_OFFSET(cep->rwbufq)) + qhdr->soff;
 
 		/* 受信ウィンドバッファのデータ長を計算する。*/
@@ -880,5 +878,5 @@
 	if (cep->rwbuf_count == 0 && cep->reassq == NULL) {
 		while (cep->rwbufq != NULL) {
-			next = GET_TCP_Q_HDR(cep->rwbufq, GET_TCP_IP_Q_HDR(cep->rwbufq)->thoff)->next;
+			next = GET_TCP_Q_HDR(cep->rwbufq, GET_IP_TCP_Q_HDR_OFFSET(cep->rwbufq))->next;
 
 #ifdef TCP_CFG_RWBUF_CSAVE_MAX_QUEUES
@@ -961,5 +959,5 @@
 	nextp = &cep->rwbufq;
 	while (*nextp)
-		nextp = &GET_TCP_Q_HDR(*nextp, GET_TCP_IP_Q_HDR(*nextp)->thoff)->next;
+		nextp = &GET_TCP_Q_HDR(*nextp, GET_IP_TCP_Q_HDR_OFFSET(*nextp))->next;
 	*nextp = input;
 
@@ -984,5 +982,5 @@
 		int_t	len;
 
-		qhdr = GET_TCP_Q_HDR(cep->rwbufq, GET_TCP_IP_Q_HDR(cep->rwbufq)->thoff);
+		qhdr = GET_TCP_Q_HDR(cep->rwbufq, GET_IP_TCP_Q_HDR_OFFSET(cep->rwbufq));
 		len = qhdr->slen;
 
@@ -999,18 +997,13 @@
 			/* 受信ウィンドバッファのアドレスを返す。*/
 			*cep->rcv_p_buf = GET_TCP_SDU(cep->rwbufq,
-			                  GET_TCP_IP_Q_HDR(cep->rwbufq)->thoff) + qhdr->soff;
+			                  GET_IP_TCP_Q_HDR_OFFSET(cep->rwbufq)) + qhdr->soff;
 
 			if (IS_PTR_DEFINED(cep->callback))
 
 #ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
 				(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)len);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#else
 				(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&len);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#endif
 			else
 				syslog(LOG_WARNING, "[TCP] no call back, CEP: %d.", GET_TCP_CEPID(cep));
@@ -1053,13 +1046,8 @@
 
 #ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
 				(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)len);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#else
 				(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&len);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#endif
 			else
 				syslog(LOG_WARNING, "[TCP] no call back, CEP: %d.", GET_TCP_CEPID(cep));
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_subr_ncs.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_subr_ncs.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_subr_ncs.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -95,6 +95,6 @@
 #include <net/ethernet.h>
 #include <net/if_arp.h>
-#include <net/ppp_ipcp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_var.h>
 #include <net/net_buf.h>
@@ -103,18 +103,13 @@
 
 #include <netinet/in.h>
-#include <netinet6/in6.h>
-#include <netinet6/in6_var.h>
 #include <netinet/in_var.h>
+#include <netinet/in_itron.h>
 #include <netinet/ip.h>
 #include <netinet/ip_var.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#include <netinet6/nd6.h>
 #include <netinet/tcp.h>
-#include <netinet/tcp_timer.h>
 #include <netinet/tcp_var.h>
 #include <netinet/tcp_fsm.h>
 #include <netinet/tcp_seq.h>
-#include <netinet/in_itron.h>
+#include <netinet/tcp_timer.h>
 
 #ifdef SUPPORT_TCP
@@ -134,13 +129,15 @@
 {
 	uint8_t	*wptr, *rptr;
+	uint_t	sdu_size   = GET_IP_SDU_SIZE(output);
+	uint_t	hdr_offset = IF_IP_TCP_HDR_OFFSET(output);
 
 	/* SDU の大きさをチェックする。*/
-	if (GET_IP_SDU_SIZE(GET_IP_HDR(output)) < GET_TCP_HDR_SIZE2(output, IF_IP_TCP_HDR_OFFSET) + len) {
+	if (sdu_size < GET_TCP_HDR_SIZE(output, hdr_offset) + len) {
 		syslog(LOG_INFO, "[TCP] shrink SUD len: %d -> %d",
-		       (uint16_t)len, (uint16_t)(GET_IP_SDU_SIZE(GET_IP_HDR(output)) - GET_TCP_HDR_SIZE2(output, IF_IP_TCP_HDR_OFFSET)));
-		len = GET_IP_SDU_SIZE(GET_IP_HDR(output)) - GET_TCP_HDR_SIZE2(output, IF_IP_TCP_HDR_OFFSET);
-		}
-
-	wptr = GET_TCP_SDU(output, IF_IP_TCP_HDR_OFFSET);
+		       (uint16_t)len, (uint16_t)(sdu_size - GET_TCP_HDR_SIZE(output, hdr_offset)));
+		len = sdu_size - GET_TCP_HDR_SIZE(output, hdr_offset);
+		}
+
+	wptr = GET_TCP_SDU(output, hdr_offset);
 
 	/* 通信端点をロックする。*/
@@ -222,14 +219,10 @@
 
 			if (IS_PTR_DEFINED(cep->callback))
+
 #ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
 				(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)(uint32_t)len);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#else
 				(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)&len);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#endif
 			else
 				syslog(LOG_WARNING, "[TCP] no call back, CEP: %d.", GET_TCP_CEPID(cep));
@@ -268,13 +261,8 @@
 
 #ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
 			(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)error);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#else
 			(*cep->callback)(GET_TCP_CEPID(cep), cep->snd_nblk_tfn, (void*)&error);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#endif
 		else
 			syslog(LOG_WARNING, "[TCP] no call back, CEP: %d.", GET_TCP_CEPID(cep));
@@ -628,13 +616,8 @@
 
 #ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
 				(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)(uint32_t)len);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#else
 				(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&len);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#endif
 			else
 				syslog(LOG_WARNING, "[TCP] no call back, CEP: %d.", GET_TCP_CEPID(cep));
@@ -680,13 +663,8 @@
 
 #ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
 				(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)(uint32_t)len);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#else
 				(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&len);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#endif
 			else
 				syslog(LOG_WARNING, "[TCP] no call back, CEP: %d.", GET_TCP_CEPID(cep));
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_timer.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_timer.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_timer.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -91,20 +91,16 @@
 #include <net/if_loop.h>
 #include <net/ethernet.h>
-#include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_var.h>
-#include <net/net_buf.h>
 #include <net/net_timer.h>
 
 #include <netinet/in.h>
 #include <netinet/in_var.h>
-#include <netinet6/in6.h>
-#include <netinet6/in6_var.h>
 #include <netinet/ip.h>
-#include <netinet/ip6.h>
 #include <netinet/tcp.h>
-#include <netinet/tcp_timer.h>
 #include <netinet/tcp_var.h>
 #include <netinet/tcp_fsm.h>
 #include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
 
 #ifdef SUPPORT_TCP
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_timer.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_timer.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_timer.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -73,5 +73,5 @@
 /* TCP タイマ変数 */
 
-#define NUM_TCP_TIMERS		4	/* TCP のタイマ数	*/
+//#define NUM_TCP_TIMERS		4	/* TCP のタイマ数	*/
 
 #define TCP_TIM_REXMT		0	/* 再送タイマ		*/
@@ -135,8 +135,4 @@
 #define TCP_MAX_REXMT_SHIFT	12	/* 最大再送回数		*/
 
-/* TCP タイマ値の型 */
-
-typedef int16_t T_TCP_TIME;
-
 /*
  *  関数
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_usrreq.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_usrreq.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_usrreq.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -75,4 +75,5 @@
 #include <sil.h>
 #include "kernel_cfg.h"
+#include "tinet_cfg.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_ASP */
@@ -83,4 +84,5 @@
 #include <t_services.h>
 #include "kernel_id.h"
+#include "tinet_id.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_JSP */
@@ -93,6 +95,6 @@
 #include <net/if_loop.h>
 #include <net/ethernet.h>
-#include <net/ppp_ipcp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_var.h>
 #include <net/net_buf.h>
@@ -102,40 +104,16 @@
 #include <netinet/in.h>
 #include <netinet/in_var.h>
-#include <netinet6/in6.h>
-#include <netinet6/in6_var.h>
 #include <netinet/in_itron.h>
 #include <netinet/ip.h>
 #include <netinet/ip_var.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
 #include <netinet/tcp.h>
-#include <netinet/tcp_timer.h>
 #include <netinet/tcp_var.h>
 #include <netinet/tcp_fsm.h>
 #include <netinet/tcp_seq.h>
+#include <netinet/tcp_timer.h>
 
 #include <net/if_var.h>
 
 #ifdef SUPPORT_TCP
-
-/*
- *  IPv4 と IPv6 の切り替えマクロ
- */
-
-#if defined(SUPPORT_INET4)
-
-#define TCP_CRE_REP	tcp_cre_rep
-#define TCP_ACP_CEP	tcp_acp_cep
-#define TCP_CON_CEP	tcp_con_cep
-
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
-
-#define TCP_CRE_REP	tcp6_cre_rep
-#define TCP_ACP_CEP	tcp6_acp_cep
-#define TCP_CON_CEP	tcp6_con_cep
-
-#endif	/* of #if defined(SUPPORT_INET6) */
 
 /*
@@ -169,588 +147,68 @@
 
 /*
- *  tcp_cre_rep -- TCP 受付口の生成【拡張機能】
- */
-
-#ifdef __tcp_cre_rep
-
-#ifdef TCP_CFG_EXTENTIONS
-
-ER
-TCP_CRE_REP (ID repid, T_TCP_CREP *pk_crep)
-{
-	T_TCP_REP	*rep;
-	ER		error;
-
-	/* TCP 受付口 ID をチェックする。*/
-	if (!VAID_TCP_REPID(repid))
-		return E_ID;
-
-	/* pk_crep が NULL ならエラー */
-	if (pk_crep == NULL)
-		return E_PAR;
-
-	/* TCP 受付口を得る。*/
-	rep = GET_TCP_REP(repid);
-
-	/* TCP 受付口が、動的生成用でなければエラー */
-	if (!DYNAMIC_TCP_REP(rep))
-		return E_ID;
-
-	/* 受付口をロックする。*/
-	syscall(wai_sem(rep->semid_lock));
-
-	/*
-	 * TCP 受付口をチェックする。生成済みであればエラー
-	 */
-	if (VALID_TCP_REP(rep))
-		error = E_OBJ;
-	else {
-
-		/* TCP 受付口生成情報をコピーする。*/
-		rep->repatr = pk_crep->repatr;		/* 受付口属性		*/
-		rep->myaddr = pk_crep->myaddr;		/* 自分のアドレス	*/
-
-		/* TCP 受付口を生成済みにする。*/
-		rep->flags |= TCP_REP_FLG_VALID;
-		error = E_OK;
-		}
-
-	/* 受付口のロックを解除する。*/
-	syscall(sig_sem(rep->semid_lock));
-
-	return error;
-	}
-
-#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
-
-#endif	/* of #ifdef __tcp_cre_cep */
-
-#ifdef __tcp_del_rep
-
-#ifdef TCP_CFG_EXTENTIONS
-
-/*
- *  tcp_find_cep_rep -- TCP 受付口をリンクしている TCP 通信端点を得る。
- */
-
-static T_TCP_CEP*
-tcp_find_cep_rep (T_TCP_REP* rep)
-{
-	T_TCP_CEP*	cep;
-
-	for (cep = &tcp_cep[tmax_tcp_cepid]; cep -- != tcp_cep; ) {
-		if (cep->rep == rep)
-			return cep;
-		}
-
-	return NULL;
-	}
-
-/*
- *  tcp_del_rep -- TCP 受付口の削除【拡張機能】
- */
-
-
-ER
-tcp_del_rep (ID repid)
-{
-	T_TCP_CEP	*cep;
-	T_TCP_REP	*rep;
-	ER		error = E_OK;
-
-	/* TCP 受付口 ID をチェックする。*/
-	if (!VAID_TCP_REPID(repid))
-		return E_ID;
-
-	/* TCP 受付口を得る。*/
-	rep = GET_TCP_REP(repid);
-
-	/* TCP 受付口が、動的生成用でなければエラー */
-	if (!DYNAMIC_TCP_REP(rep))
-		return E_ID;
-
-	/* 受付口をロックする。*/
-	syscall(wai_sem(rep->semid_lock));
-
-	/* TCP 受付口をチェックする。未生成の場合はエラー */
-	if (!VALID_TCP_REP(rep))
-		error = E_NOEXS;
-	else {
-		if ((cep = tcp_find_cep_rep(rep)) != NULL) {
-			/*
-			 * すでに受動オープンしているとき
-			 *（tcp_acp_cep が呼ばれているとき）は、
-			 * tcp_acp_cep を終了させる。
-			 */
-
-			/* 通信端点をロックする。*/
-			syscall(wai_sem(cep->semid_lock));
-
-			/*
-			 *  通信端点から受付口を解放し、
-			 *  イベントフラグをクローズに設定する。
-			 */
-			cep->rep = NULL;
-			cep->fsm_state = TCP_FSM_CLOSED;
-			cep->error = E_DLT;
-			syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
-
-#ifdef TCP_CFG_NON_BLOCKING
-
-			if (cep->rcv_nblk_tfn != TFN_TCP_UNDEF) {
-				if (IS_PTR_DEFINED(cep->callback)) {
-
-#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
-					(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)E_DLT);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-					ER	error = E_DLT;
-
-					(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&error);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-					}
-				else
-					error = E_OBJ;
-				cep->rcv_nblk_tfn = TFN_TCP_UNDEF;
-				}
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
-
-			cep->rcv_tskid = TA_NULL;
-			cep->rcv_tfn   = TFN_TCP_UNDEF;
-
-			/* 通信端点のロックを解除する。*/
-			syscall(sig_sem(cep->semid_lock));
-
-			}
-		else
-			error = E_OK;
-
-		/* TCP 受付口を未生成にする。*/
-		rep->flags &= ~TCP_REP_FLG_VALID;
-		}
-
-	/* 受付口のロックを解除する。*/
-	syscall(sig_sem(rep->semid_lock));
-
-	return error;
-	}
-
-#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
-
-#endif	/* of #ifdef __tcp_del_rep */
-
-/*
- *  tcp_cre_cep -- TCP 通信端点の生成【拡張機能】
- */
-
-#ifdef __tcp_cre_cep
-
-#ifdef TCP_CFG_EXTENTIONS
-
-ER
-tcp_cre_cep (ID cepid, T_TCP_CCEP *pk_ccep)
-{
-	T_TCP_CEP	*cep;
-	ER		error;
-
-	/* TCP 通信端点 ID をチェックする。*/
-	if (!VAID_TCP_CEPID(cepid))
-		return E_ID;
-
-	/* pk_ccep が NULL ならエラー */
-	if (pk_ccep == NULL)
-		return E_PAR;
-
-	/* TCP 通信端点を得る。*/
-	cep = GET_TCP_CEP(cepid);
-
-	/* TCP 通信端点が、動的生成用でなければエラー */
-	if (!DYNAMIC_TCP_CEP(cep))
-		return E_ID;
-
-	/* 通信端点をロックする。*/
-	syscall(wai_sem(cep->semid_lock));
-
-	/*
-	 * TCP 通信端点をチェックする。生成済みであればエラー
-	 */
-	if (VALID_TCP_CEP(cep))
-		error = E_OBJ;
-	else {
-
-		/* TCP 通信端点生成情報をコピーする。*/
-		cep->cepatr   = pk_ccep->cepatr;		/* 通信端点属性			*/
-		cep->sbuf     = pk_ccep->sbuf;			/* 送信用ウィンドバッファ	*/
-		cep->sbufsz   = pk_ccep->sbufsz;		/* 送信用ウィンドバッファサイズ	*/
-		cep->rbuf     = pk_ccep->rbuf;			/* 受信用ウィンドバッファ	*/
-		cep->rbufsz   = pk_ccep->rbufsz;		/* 受信用ウィンドバッファサイズ	*/
-		cep->callback = (void*)pk_ccep->callback;	/* コールバック			*/
-
-		/* TCP 通信端点を生成済みにする。*/
-		cep->flags |= TCP_CEP_FLG_VALID;
-		error = E_OK;
-		}
-
-	/* 通信端点のロックを解除する。*/
-	syscall(sig_sem(cep->semid_lock));
-
-	return error;
-	}
-
-#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
-
-#endif	/* of #ifdef __tcp_cre_cep */
-
-/*
- *  tcp_del_cep -- TCP 通信端点の削除【拡張機能】
- */
-
-#ifdef __tcp_del_cep
-
-#ifdef TCP_CFG_EXTENTIONS
-
-ER
-tcp_del_cep (ID cepid)
-{
-	T_TCP_CEP	*cep;
-	ER		error;
-
-	/* TCP 通信端点 ID をチェックする。*/
-	if (!VAID_TCP_CEPID(cepid))
-		return E_ID;
-
-	/* TCP 通信端点を得る。*/
-	cep = GET_TCP_CEP(cepid);
-
-	/* TCP 通信端点が、動的生成用でなければエラー */
-	if (!DYNAMIC_TCP_CEP(cep))
-		return E_ID;
-
-	/* 通信端点をロックする。*/
-	syscall(wai_sem(cep->semid_lock));
-
-	/*
-	 * TCP 通信端点をチェックする。以下の場合はエラー
-	 * ・未生成。
-	 * ・使用中。
-	 */
-	if (!VALID_TCP_CEP(cep))
-		error = E_NOEXS;
-	else if (cep->fsm_state != TCP_FSM_CLOSED)
-		error = E_OBJ;
-	else {
-
-		/* TCP 通信端点を未生成にする。*/
-		cep->flags &= ~TCP_CEP_FLG_VALID;
-		error = E_OK;
-		}
-
-	/* 通信端点のロックを解除する。*/
-	syscall(sig_sem(cep->semid_lock));
-
-	return error;
-	}
-
-#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
-
-#endif	/* of #ifdef __tcp_del_cep */
-
-#ifdef TCP_CFG_PASSIVE_OPEN
-
-/*
- *  tcp_acp_cep -- 接続要求待ち (受動オープン)【標準機能】
- */
-
-#ifdef __tcp_acp_cep
-
-ER
-TCP_ACP_CEP (ID cepid, ID repid, T_IPEP *p_dstaddr, TMO tmout)
-{
-	T_TCP_REP	*rep;
-	T_TCP_CEP	*cep;
-	ER		error;
-	FLGPTN		flag;
-
-	/* TCP 受付口をチェックする。*/
-	if (!VAID_TCP_REPID(repid))
-		return E_ID;
-
-#ifdef TCP_CFG_NON_BLOCKING
-
-	/* p_dstaddr が NULL ならエラー */
-	if (p_dstaddr == NULL)
-		return E_PAR;
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING */
-
-	/* p_dstaddr が NULL か、tmout が TMO_NBLK ならエラー */
-	if (p_dstaddr == NULL || tmout == TMO_NBLK)
-		return E_PAR;
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
-
-	/*
-	 *  CEP をロックし、API 機能コードとタスク識別子を記録する。
-	 *  すでに記録されていれば、ペンディング中なのでエラー
-	 */
-	if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_ACP_CEP)) != E_OK)
-		return error;
-
-	/* CEP の FSM がクローズ状態でなければエラー。*/
-	if (cep->fsm_state != TCP_FSM_CLOSED) {
-		error = E_OBJ;
-		goto err_ret;
-		}
-	syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_CLOSED)));
-
-	/* TCP 通信端点を初期化する。*/
-	tcp_init_cep(cep);
-
-	/* TCP 受付口を得る。*/
-	rep = GET_TCP_REP(repid);
-
-#ifdef TCP_CFG_EXTENTIONS
-
-	/* TCP 受付口をロックする。*/
-	syscall(wai_sem(rep->semid_lock));
-
-	/* TCP 受付口をチェックする。*/
-	if (!VALID_TCP_REP(rep)) {
-		syscall(sig_sem(rep->semid_lock));
-		error = E_NOEXS;
-		goto err_ret;
-		}
-
-#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
-
-	/* TCP 通信端点にTCP受付口を記録する。*/
-	cep->rep = rep;
-
-#ifdef TCP_CFG_EXTENTIONS
-
-	/* TCP 受付口のロックを解除する。*/
-	syscall(sig_sem(rep->semid_lock));
-
-#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
-
-	/* TCP 受付口のアドレスをコピーする。*/
-	cep->myaddr = rep->myaddr;
-
-	/* 通信端点を設定する。*/
-	cep->fsm_state = TCP_FSM_LISTEN;
-
-#ifdef TCP_CFG_NON_BLOCKING
-
-	/* タイムアウトをチェックする。*/
-	if (tmout == TMO_NBLK) {
-		/* ノンブロッキングコール */
-		cep->p_dstaddr    = p_dstaddr;
-		cep->rcv_nblk_tfn = TFN_TCP_ACP_CEP;
-		return E_WBLK;
-		}
-	else {
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
-
-		/*
-		 *  FSM が ESTABLISHED になるまで待つ。
-		 *  FSM が CLOSED になった場合は、エラーが発生したことを意味している。
-		 */
-		error = twai_flg(cep->est_flgid, (TCP_CEP_EVT_CLOSED |
-		                                  TCP_CEP_EVT_ESTABLISHED), TWF_ORW, &flag, tmout);
-		if (error == E_OK) {
-			if (cep->error != E_OK)
-				error = cep->error;
-			else if (cep->fsm_state == TCP_FSM_CLOSED)
-				error = E_TMOUT;
-			}
-
-		syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_ESTABLISHED)));
-
-		if (error == E_OK) {
-			/* 相手のアドレスをコピーする。*/
-			*p_dstaddr = cep->dstaddr;
-			}
-		else {
-			/*
-			 *  通信端点から受付口を解放し、
-			 *  イベントフラグをクローズに設定する。
-			 */
-			cep->rep = NULL;
-			cep->fsm_state = TCP_FSM_CLOSED;
-			syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
-			}
-
-#ifdef TCP_CFG_NON_BLOCKING
-
-		}
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
-
-err_ret:
-	cep->rcv_tskid = TA_NULL;
-	cep->rcv_tfn   = TFN_TCP_UNDEF;
-	return error;
-	}
-
-#endif	/* of #ifdef __tcp_acp_cep */
-
-#endif	/* of #ifdef TCP_CFG_PASSIVE_OPEN */
-
-/*
- *  tcp_con_cep -- 接続要求 (能動オープン)【標準機能】
- */
-
-#ifdef __tcp_con_cep
-
-ER
-TCP_CON_CEP (ID cepid, T_IPEP *p_myaddr, T_IPEP *p_dstaddr, TMO tmout)
-{
-	T_TCP_CEP	*cep;
-	ER		error;
-	FLGPTN		flag;
-
-#ifdef TCP_CFG_NON_BLOCKING
-
-	/*
-	 *  p_dstaddr または p_myaddr が NULL か、
-	 *  あて先がマルチキャストアドレスならエラー
-	 */
-	if (p_myaddr == NULL || p_dstaddr == NULL || IN_IS_ADDR_MULTICAST(&p_dstaddr->ipaddr))
-		return E_PAR;
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING */
-
-	/*
-	 *  p_dstaddr または p_myaddr が NULL 、
-	 *  あて先がマルチキャストアドレスか、
-	 *  tmout が TMO_NBLK ならエラー
-	 */
-	if (p_myaddr == NULL || p_dstaddr == NULL ||
-	    IN_IS_ADDR_MULTICAST(&p_dstaddr->ipaddr) || tmout == TMO_NBLK)
-		return E_PAR;
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
-
-	/*
-	 *  CEP をロックし、API 機能コードとタスク識別子を記録する。
-	 *  すでに記録されていれば、ペンディング中なのでエラー
-	 */
-	if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_CON_CEP)) != E_OK)
-		return error;
-
-	/* CEP の FSM がクローズ状態でなければエラー。*/
-	if (cep->fsm_state != TCP_FSM_CLOSED) {
-		error = E_OBJ;
-		goto err_ret;
-		}
-	syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_CLOSED)));
-
-	/* シーケンス番号を初期化する。*/
-	if (tcp_iss == 0)
-		tcp_init_iss();
-
-	/* 通信端点を初期化する。*/
-	tcp_init_cep(cep);
-
-	/*
-	 *  p_myaddr が NADR (-1) ではなく、自 IP アドレスが ANY でなければ、
-	 *  指定された IP アドレスを割り当てる。
-	 */
-	if (p_myaddr != NADR && !IN_IS_ADDR_ANY(&p_myaddr->ipaddr))
-		cep->myaddr.ipaddr = p_myaddr->ipaddr;
-	else {
-		T_IN_IFADDR	*ia;
-
-		if ((ia = IN_IFAWITHIFP(IF_GET_IFNET(), &p_dstaddr->ipaddr)) == NULL) {
-			error = E_PAR;
-			goto err_ret;
-			}
-		cep->myaddr.ipaddr = ia->addr;
-		}
-
-	/* 通信端点を設定する。*/
-	cep->fsm_state = TCP_FSM_SYN_SENT;
-	cep->dstaddr   = *p_dstaddr;
-	cep->iss       = tcp_iss;
-	cep->timer[TCP_TIM_KEEP] = TCP_TVAL_KEEP_INIT;
-	tcp_iss += TCP_ISS_INCR() / 2;
-	init_send_seq(cep);
-
-#ifdef TCP_CFG_NON_BLOCKING
-
-	/* タイムアウトをチェックする。*/
-	if (tmout == TMO_NBLK) {
-		/* ノンブロッキングコール */
-		cep->p_dstaddr    = p_dstaddr;
-		cep->p_myaddr     = p_myaddr;
-		cep->snd_nblk_tfn = TFN_TCP_CON_CEP;
-
-		/* コネクションの開設をポストする。*/
-		cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
-		sig_sem(SEM_TCP_POST_OUTPUT);
-		return E_WBLK;
-		}
-	else {
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
-
-		/*
-		 *  p_myaddr が NADR (-1) か、
-		 *  自ポート番号が TCP_PORTANY なら、自動で割り当てる。
-		 */
-		if (p_myaddr == NADR || p_myaddr->portno == TCP_PORTANY)
-			tcp_alloc_auto_port(cep);
-		else if ((error = tcp_alloc_port(cep, p_myaddr->portno)) != E_OK)
-			goto err_ret;
-
-		/* コネクションの開設をポストする。*/
-		cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
-		sig_sem(SEM_TCP_POST_OUTPUT);
-
-		/*
-		 *  イベントが ESTABLISHED になるまで待つ。
-		 *  イベントが CLOSED になった場合は、何らかのエラーが発生したか、
-		 *  接続要求が拒否されたことを意味している。
-		 */
-		error = twai_flg(cep->est_flgid, (TCP_CEP_EVT_CLOSED |
-		                                  TCP_CEP_EVT_ESTABLISHED), TWF_ORW, &flag, tmout);
-		if (error == E_OK) {
-			if (cep->error != E_OK)
-				error = cep->error;
-			else if (cep->fsm_state == TCP_FSM_CLOSED)
-				error = E_CLS;
-			}
-
-		syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_ESTABLISHED)));
-
-		if (error != E_OK) {
-			/*
-			 *  通信端点から受付口を解放し、
-			 *  イベントフラグをクローズに設定する。
-			 */
-			cep->rep = NULL;
-			cep->fsm_state = TCP_FSM_CLOSED;
-			syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
-			}
-
-#ifdef TCP_CFG_NON_BLOCKING
-
-		}
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
-
-err_ret:
-	cep->snd_tskid = TA_NULL;
-	cep->snd_tfn   = TFN_TCP_UNDEF;
-	return error;
-	}
-
-#endif	/* of #ifdef __tcp_con_cep */
+ *  IPv6 と IPv4 で引数が異なる関数のコンパイル
+ */
+
+#if defined(SUPPORT_INET6)
+
+#define T_IPEP			T_IPV6EP
+#define TCP_ACP_CEP		tcp6_acp_cep
+#define TCP_CON_CEP		tcp6_con_cep
+#define TCP_FIND_CEP_REP	tcp6_find_cep_rep
+
+#if defined(SUPPORT_INET4)
+
+#undef	T_TCP_REP
+#define T_TCP_REP		T_TCP6_REP
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#define TCP_CRE_REP		tcp6_cre_rep
+#define TCP_DEL_REP_BODY	tcp6_del_rep_body
+#define GET_TCP_REP		GET_TCP6_REP
+#define VALID_TCP_REPID		VALID_TCP6_REPID
+#define T_TCPN_CREP		T_TCP6_CREP
+#define API_PROTO		API_PROTO_IPV6
+
+#include <netinet/tcpn_usrreq.c>
+
+#undef  T_IPEP
+#undef  TCP_ACP_CEP
+#undef  TCP_CON_CEP
+#undef	TCP_FIND_CEP_REP
+
+#undef  TCP_CRE_REP
+#undef	TCP_DEL_REP_BODY
+#undef	GET_TCP_REP
+#undef	VALID_TCP_REPID
+#undef	T_TCPN_CREP
+#undef  API_PROTO
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+#define T_IPEP			T_IPV4EP
+#define TCP_ACP_CEP		tcp_acp_cep
+#define TCP_CON_CEP		tcp_con_cep
+#define TCP_FIND_CEP_REP	tcp4_find_cep_rep
+
+#if defined(SUPPORT_INET6)
+
+#undef	T_TCP_REP
+#define T_TCP_REP		T_TCP4_REP
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+#define TCP_CRE_REP		tcp_cre_rep
+#define TCP_DEL_REP_BODY	tcp4_del_rep_body
+#define GET_TCP_REP		GET_TCP4_REP
+#define VALID_TCP_REPID		VALID_TCP4_REPID
+#define T_TCPN_CREP		T_TCP_CREP
+#define API_PROTO		API_PROTO_IPV4
+
+#include <netinet/tcpn_usrreq.c>
+
+#endif	/* of #if defined(SUPPORT_INET4) */
 
 #ifdef __tcp_cls_cep
@@ -904,6 +362,5 @@
 				 * ・動的な通信端点の生成・削除機能
 				 */
-				cep->flags &= (TCP_CEP_FLG_WBCS_NBUF_REQ | TCP_CEP_FLG_WBCS_MASK | 
-				               TCP_CEP_FLG_DYNAMIC       | TCP_CEP_FLG_VALID);
+				cep->flags &= TCP_CEP_FLG_NOT_CLEAR;
 
 				/* 
@@ -1025,16 +482,10 @@
 			sig_sem(SEM_TCP_POST_OUTPUT);
 
+			/* コールバック関数を呼び出す。*/
 #ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
-			/* コールバック関数を呼び出す。*/
 			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_SND_DAT, (void*)error);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-			/* コールバック関数を呼び出す。*/
+#else
 			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_SND_DAT, (void*)&error);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#endif
 			error = E_WBLK;
 			goto err_ret;
@@ -1082,124 +533,4 @@
 
 #endif	/* of #ifdef __tcp_snd_dat */
-
-#ifdef __tcp_snd_oob
-
-#ifdef TCP_CFG_EXTENTIONS
-
-/*
- *  tcp_snd_oob -- 緊急データの送信【拡張機能】
- */
-
-ER_UINT
-tcp_snd_oob (ID cepid, void *data, int_t len, TMO tmout)
-{
-	T_TCP_CEP	*cep;
-	ER_UINT		error;
-
-#ifdef TCP_CFG_NON_BLOCKING
-
-	/* data が NULL か、len < 0 ならエラー */
-	if (data == NULL || len < 0)
-		return E_PAR;
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING */
-
-	/* data が NULL、len < 0 か、tmout が TMO_NBLK ならエラー */
-	if (data == NULL || len < 0 || tmout == TMO_NBLK)
-		return E_PAR;
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
-
-	/*
-	 *  CEP をロックし、API 機能コードとタスク識別子を記録する。
-	 *  すでに記録されていれば、ペンディング中なのでエラー
-	 */
-	if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_SND_OOB)) != E_OK)
-		return error;
-
-	/* 送信できるか、通信端点の状態を見る。*/
-	if ((error = tcp_can_send_more(cep, TFN_TCP_SND_OOB, tmout)) != E_OK)
-		goto err_ret;
-
-#ifdef TCP_CFG_NON_BLOCKING
-
-	/* タイムアウトをチェックする。*/
-	if (tmout == TMO_NBLK) {		/* ノンブロッキングコール */
-
-		/* 送信ウィンドバッファに空きがあればコールバック関数を呼び出す。*/
-		if (!TCP_IS_SWBUF_FULL(cep)) {
-
-		 	/* 送信ウィンドバッファにデータを書き込む。*/
-			error = TCP_WRITE_SWBUF(cep, data, (uint_t)len);
-
-			/* 送信緊急ポインタを設定する。*/
-			cep->snd_up = cep->snd_una + cep->swbuf_count;
-
-			/* 出力をポストする。*/
-			cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
-			sig_sem(SEM_TCP_POST_OUTPUT);
-
-#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
-			/* コールバック関数を呼び出す。*/
-			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_SND_OOB, (void*)error);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-			/* コールバック関数を呼び出す。*/
-			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_SND_OOB, (void*)&error);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-			error = E_WBLK;
-			goto err_ret;
-			}
-		else {
-			cep->snd_data     = data;
-			cep->snd_len      = len;
-			cep->snd_nblk_tfn = TFN_TCP_SND_OOB;
-			TCP_ALLOC_SWBUF(cep);
-
-			return E_WBLK;
-			}
-		}
-	else {		/* 非ノンブロッキングコール */
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
-
-	 	/* 送信ウィンドバッファが空くのを待つ。*/
-		if ((error = TCP_WAIT_SWBUF(cep, tmout)) != E_OK)
-			goto err_ret;
-
-	 	/* 送信ウィンドバッファにデータを書き込む。*/
-		if ((error = TCP_WRITE_SWBUF(cep, data, (uint_t)len)) > 0) {
-
-			/* 送信緊急ポインタを設定する。*/
-			cep->snd_up = cep->snd_una + cep->swbuf_count;
-
-			/* データを送信する。送信ウィンドバッファがフルのときは強制的に送信する。*/
-			if (TCP_IS_SWBUF_FULL(cep))
-				cep->flags |= TCP_CEP_FLG_FORCE | TCP_CEP_FLG_FORCE_CLEAR;
-
-			/* 出力をポストする。*/
-			cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
-			sig_sem(SEM_TCP_POST_OUTPUT);
-			}
-
-#ifdef TCP_CFG_NON_BLOCKING
-
-		}
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
-
-err_ret:
-	cep->snd_tskid = TA_NULL;
-	cep->snd_tfn   = TFN_TCP_UNDEF;
-	return error;
-	}
-
-#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
-
-#endif	/* of #ifdef __tcp_snd_oob */
 
 #ifdef __tcp_get_buf
@@ -1250,16 +581,10 @@
 			error = TCP_GET_SWBUF_ADDR(cep, p_buf);
 
+			/* コールバック関数を呼び出す。*/
 #ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
-			/* コールバック関数を呼び出す。*/
 			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_GET_BUF, (void*)error);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-			/* コールバック関数を呼び出す。*/
+#else
 			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_GET_BUF, (void*)&error);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#endif
 			error = E_WBLK;
 			goto err_ret;
@@ -1401,14 +726,10 @@
 			len = TCP_READ_RWBUF(cep, data, (uint_t)len);
 
+			/* コールバック関数を呼び出す。*/
 #ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
 			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_RCV_DAT, (void*)(uint32_t)len);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#else
 			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_RCV_DAT, (void*)&len);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#endif
 			error = E_WBLK;
 			goto err_ret;
@@ -1449,65 +770,4 @@
 
 #endif	/* of #ifdef __tcp_rcv_dat */
-
-#ifdef __tcp_rcv_oob
-
-#ifdef TCP_CFG_EXTENTIONS
-
-/*
- *  tcp_rcv_oob -- 緊急データの受信【拡張機能】
- *
- *    注意: 送信側が複数オクテットのデータを送信しても、
- *          緊急ポインタが指す 1 オクテットのデータのみ受信する。
- */
-
-ER_UINT
-tcp_rcv_oob (ID cepid, void *data, int_t len)
-{
-	T_TCP_CEP	*cep;
-	uint8_t		*urg;
-
-	/* TCP 通信端点 ID をチェックする。*/
-	if (!VAID_TCP_CEPID(cepid))
-		return E_ID;
-
-	/* data が NULL か、len < 0 ならエラー */
-	if (data == NULL || len < 0)
-		return E_PAR;
-
-	/* TCP 通信端点を得る。*/
-	cep = GET_TCP_CEP(cepid);
-
-	/* 受信できるか、通信端点の状態を見る。*/
-	/* 受信できるか、fsm_state を見る。*/
-	if (!TCP_FSM_CAN_RECV_MORE(cep->fsm_state))
-		return E_OBJ;
-
-	/*
-	 *  緊急データ入りのセグメントの TCP ヘッダが
-	 *  設定されていなければ、緊急データを受信していない。
-	 */
-	if (cep->urg_tcph == NULL)
-		return E_OBJ;
-
-	/* len == 0 ならバッファオーバーフロー */
-	if (len == 0)
-		return E_BOVR;
-
-	/* 緊急ポインタが指す 1 オクテットのデータを読み取る。*/
-	urg = (uint8_t*)cep->urg_tcph + TCP_DATA_OFF(cep->urg_tcph->doff) + cep->urg_tcph->urp + TCP_CFG_URG_OFFSET;
-	*(uint8_t*)data = *urg;
-
-	/* 読み取ったデータから後ろの SDU を前に詰める。*/
-	memcpy(urg, urg + 1, cep->urg_tcph->sum - (cep->urg_tcph->urp + TCP_CFG_URG_OFFSET) - 1);
-
-	/* tcp_rcv_oob() が呼出されたこと知らせるために、NULL を設定する。*/
-	cep->urg_tcph = NULL;
-
-	return 1;
-	}
-
-#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
-
-#endif	/* of #ifdef __tcp_rcv_oob */
 
 #ifdef __tcp_rcv_buf
@@ -1559,16 +819,10 @@
 			error = TCP_GET_RWBUF_ADDR(cep, p_buf);
 
+			/* コールバック関数を呼び出す。*/
 #ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
-			/* コールバック関数を呼び出す。*/
 			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_RCV_BUF, (void*)error);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-			/* コールバック関数を呼び出す。*/
+#else
 			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_RCV_BUF, (void*)&error);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
+#endif
 			error = E_WBLK;
 			goto err_ret;
@@ -1705,6 +959,14 @@
 
 			case TFN_TCP_CON_CEP:
-				/*  通信端点から受付口を解放する。*/
+				/*
+				 *  通信端点から受付口を解放し、
+				 *  イベントフラグをクローズに設定する。
+				 */
 				cep->rep = NULL;
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+				cep->rep4 = NULL;
+#endif
+
 				cep->fsm_state = TCP_FSM_CLOSED;
 				syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
@@ -1800,4 +1062,9 @@
 				 */
 				cep->rep = NULL;
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+				cep->rep4 = NULL;
+#endif
+
 				cep->fsm_state = TCP_FSM_CLOSED;
 				syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
@@ -1866,5 +1133,5 @@
 
 	/* TCP 通信端点 ID をチェックする。*/
-	if (!VAID_TCP_CEPID(cepid))
+	if (!VALID_TCP_CEPID(cepid))
 		return E_ID;
 
@@ -1914,4 +1181,357 @@
 #endif	/* of #ifdef __tcp_can_cep */
 
+#ifdef TCP_CFG_EXTENTIONS
+
+#ifdef __tcp_cre_cep
+
+/*
+ *  tcp_cre_cep -- TCP 通信端点の生成【拡張機能】
+ */
+
+ER
+tcp_cre_cep (ID cepid, T_TCP_CCEP *pk_ccep)
+{
+	T_TCP_CEP	*cep;
+	ER		error;
+
+	/* TCP 通信端点 ID をチェックする。*/
+	if (!VALID_TCP_CEPID(cepid))
+		return E_ID;
+
+	/* pk_ccep が NULL ならエラー */
+	if (pk_ccep == NULL)
+		return E_PAR;
+
+	/* TCP 通信端点を得る。*/
+	cep = GET_TCP_CEP(cepid);
+
+	/* TCP 通信端点が、動的生成用でなければエラー */
+	if (!DYNAMIC_TCP_CEP(cep))
+		return E_ID;
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	/*
+	 * TCP 通信端点をチェックする。生成済みであればエラー
+	 */
+	if (VALID_TCP_CEP(cep))
+		error = E_OBJ;
+	else {
+
+		/* TCP 通信端点生成情報をコピーする。*/
+		cep->cepatr   = pk_ccep->cepatr;		/* 通信端点属性			*/
+		cep->sbuf     = pk_ccep->sbuf;			/* 送信用ウィンドバッファ	*/
+		cep->sbufsz   = pk_ccep->sbufsz;		/* 送信用ウィンドバッファサイズ	*/
+		cep->rbuf     = pk_ccep->rbuf;			/* 受信用ウィンドバッファ	*/
+		cep->rbufsz   = pk_ccep->rbufsz;		/* 受信用ウィンドバッファサイズ	*/
+		cep->callback = (void*)pk_ccep->callback;	/* コールバック			*/
+
+		/* TCP 通信端点を生成済みにする。*/
+		cep->flags |= TCP_CEP_FLG_VALID;
+		error = E_OK;
+		}
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_cre_cep */
+
+/*
+ *  tcp_del_cep -- TCP 通信端点の削除【拡張機能】
+ */
+
+#ifdef __tcp_del_cep
+
+ER
+tcp_del_cep (ID cepid)
+{
+	T_TCP_CEP	*cep;
+	ER		error;
+
+	/* TCP 通信端点 ID をチェックする。*/
+	if (!VALID_TCP_CEPID(cepid))
+		return E_ID;
+
+	/* TCP 通信端点を得る。*/
+	cep = GET_TCP_CEP(cepid);
+
+	/* TCP 通信端点が、動的生成用でなければエラー */
+	if (!DYNAMIC_TCP_CEP(cep))
+		return E_ID;
+
+	/* 通信端点をロックする。*/
+	syscall(wai_sem(cep->semid_lock));
+
+	/*
+	 * TCP 通信端点をチェックする。以下の場合はエラー
+	 * ・未生成。
+	 * ・使用中。
+	 */
+	if (!VALID_TCP_CEP(cep))
+		error = E_NOEXS;
+	else if (cep->fsm_state != TCP_FSM_CLOSED)
+		error = E_OBJ;
+	else {
+
+		/* TCP 通信端点を未生成にする。*/
+		cep->flags &= ~TCP_CEP_FLG_VALID;
+		error = E_OK;
+		}
+
+	/* 通信端点のロックを解除する。*/
+	syscall(sig_sem(cep->semid_lock));
+
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_del_cep */
+
+#ifdef __tcp_snd_oob
+
+/*
+ *  tcp_snd_oob -- 緊急データの送信【拡張機能】
+ */
+
+ER_UINT
+tcp_snd_oob (ID cepid, void *data, int_t len, TMO tmout)
+{
+	T_TCP_CEP	*cep;
+	ER_UINT		error;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/* data が NULL か、len < 0 ならエラー */
+	if (data == NULL || len < 0)
+		return E_PAR;
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	/* data が NULL、len < 0 か、tmout が TMO_NBLK ならエラー */
+	if (data == NULL || len < 0 || tmout == TMO_NBLK)
+		return E_PAR;
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	/*
+	 *  CEP をロックし、API 機能コードとタスク識別子を記録する。
+	 *  すでに記録されていれば、ペンディング中なのでエラー
+	 */
+	if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_SND_OOB)) != E_OK)
+		return error;
+
+	/* 送信できるか、通信端点の状態を見る。*/
+	if ((error = tcp_can_send_more(cep, TFN_TCP_SND_OOB, tmout)) != E_OK)
+		goto err_ret;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/* タイムアウトをチェックする。*/
+	if (tmout == TMO_NBLK) {		/* ノンブロッキングコール */
+
+		/* 送信ウィンドバッファに空きがあればコールバック関数を呼び出す。*/
+		if (!TCP_IS_SWBUF_FULL(cep)) {
+
+		 	/* 送信ウィンドバッファにデータを書き込む。*/
+			error = TCP_WRITE_SWBUF(cep, data, (uint_t)len);
+
+			/* 送信緊急ポインタを設定する。*/
+			cep->snd_up = cep->snd_una + cep->swbuf_count;
+
+			/* 出力をポストする。*/
+			cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+			sig_sem(SEM_TCP_POST_OUTPUT);
+
+			/* コールバック関数を呼び出す。*/
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_SND_OOB, (void*)error);
+#else
+			(*cep->callback)(GET_TCP_CEPID(cep), TFN_TCP_SND_OOB, (void*)&error);
+#endif
+			error = E_WBLK;
+			goto err_ret;
+			}
+		else {
+			cep->snd_data     = data;
+			cep->snd_len      = len;
+			cep->snd_nblk_tfn = TFN_TCP_SND_OOB;
+			TCP_ALLOC_SWBUF(cep);
+
+			return E_WBLK;
+			}
+		}
+	else {		/* 非ノンブロッキングコール */
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	 	/* 送信ウィンドバッファが空くのを待つ。*/
+		if ((error = TCP_WAIT_SWBUF(cep, tmout)) != E_OK)
+			goto err_ret;
+
+	 	/* 送信ウィンドバッファにデータを書き込む。*/
+		if ((error = TCP_WRITE_SWBUF(cep, data, (uint_t)len)) > 0) {
+
+			/* 送信緊急ポインタを設定する。*/
+			cep->snd_up = cep->snd_una + cep->swbuf_count;
+
+			/* データを送信する。送信ウィンドバッファがフルのときは強制的に送信する。*/
+			if (TCP_IS_SWBUF_FULL(cep))
+				cep->flags |= TCP_CEP_FLG_FORCE | TCP_CEP_FLG_FORCE_CLEAR;
+
+			/* 出力をポストする。*/
+			cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+			sig_sem(SEM_TCP_POST_OUTPUT);
+			}
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+		}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+err_ret:
+	cep->snd_tskid = TA_NULL;
+	cep->snd_tfn   = TFN_TCP_UNDEF;
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_snd_oob */
+
+#ifdef __tcp_rcv_oob
+
+/*
+ *  tcp_rcv_oob -- 緊急データの受信【拡張機能】
+ *
+ *    注意: 送信側が複数オクテットのデータを送信しても、
+ *          緊急ポインタが指す 1 オクテットのデータのみ受信する。
+ */
+
+ER_UINT
+tcp_rcv_oob (ID cepid, void *data, int_t len)
+{
+	T_TCP_CEP	*cep;
+	uint8_t		*urg;
+
+	/* TCP 通信端点 ID をチェックする。*/
+	if (!VALID_TCP_CEPID(cepid))
+		return E_ID;
+
+	/* data が NULL か、len < 0 ならエラー */
+	if (data == NULL || len < 0)
+		return E_PAR;
+
+	/* TCP 通信端点を得る。*/
+	cep = GET_TCP_CEP(cepid);
+
+	/* 受信できるか、通信端点の状態を見る。*/
+	/* 受信できるか、fsm_state を見る。*/
+	if (!TCP_FSM_CAN_RECV_MORE(cep->fsm_state))
+		return E_OBJ;
+
+	/*
+	 *  緊急データ入りのセグメントの TCP ヘッダが
+	 *  設定されていなければ、緊急データを受信していない。
+	 */
+	if (cep->urg_tcph == NULL)
+		return E_OBJ;
+
+	/* len == 0 ならバッファオーバーフロー */
+	if (len == 0)
+		return E_BOVR;
+
+	/* 緊急ポインタが指す 1 オクテットのデータを読み取る。*/
+	urg = (uint8_t*)cep->urg_tcph + TCP_DATA_OFF(cep->urg_tcph->doff) + cep->urg_tcph->urp + TCP_CFG_URG_OFFSET;
+	*(uint8_t*)data = *urg;
+
+	/* 読み取ったデータから後ろの SDU を前に詰める。*/
+	memcpy(urg, urg + 1, cep->urg_tcph->sum - (cep->urg_tcph->urp + TCP_CFG_URG_OFFSET) - 1);
+
+	/* tcp_rcv_oob() が呼出されたこと知らせるために、NULL を設定する。*/
+	cep->urg_tcph = NULL;
+
+	return 1;
+	}
+
+#endif	/* of #ifdef __tcp_rcv_oob */
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+#ifdef TCP_CFG_EXTENTIONS
+
+#ifdef __tcp_del_rep
+
+/*
+ *  tcp_del_rep -- TCP 受付口の削除【拡張機能】
+ */
+
+#if defined(SUPPORT_INET6) && TNUM_TCP6_REPID > 0
+
+#if defined(SUPPORT_INET4) && TNUM_TCP4_REPID > 0
+
+ER
+tcp_del_rep (ID repid)
+{
+
+	/*
+	 *  TCP 受付口 ID をチェックする。
+	 *  IPv6 用 TCP 受付口であれば、
+	 *  IPv6 用の「TCP 受付口の削除関数（本体）」を呼出す。
+	 */
+	//NET_DEBUG_TCP3("tcp_del_rep1[r=%d,n=%d,x=%d]\n",
+	//               repid, TMIN_TCP6_REPID, tmax_tcp6_repid);
+	//NET_DEBUG_TCP3("tcp_del_rep2[r=%d,n=%d,x=%d]\n",
+	//               repid, TMIN_TCP4_REPID, tmax_tcp4_repid);
+	if (VALID_TCP6_REPID(repid))
+		return tcp6_del_rep_body(repid);
+
+	/*
+	 *  TCP 受付口 ID をチェックする。
+	 *  IPv4 用 TCP 受付口であれば、
+	 *  IPv4 用の「TCP 受付口の削除関数（本体）」を呼出す。
+	 */
+	else if (VALID_TCP4_REPID(repid))
+		return tcp4_del_rep_body(repid);
+	else
+		return E_ID;
+
+	}
+
+#else	/* of #if defined(SUPPORT_INET4) && TNUM_TCP4_REPID > 0 */
+
+ER
+tcp_del_rep (ID repid)
+{
+
+	/* TCP 受付口 ID をチェックする。*/
+	if (VALID_TCP6_REPID(repid))
+		return tcp6_del_rep_body(repid);
+	else
+		return E_ID;
+
+	}
+
+#endif	/* of #if defined(SUPPORT_INET4) && TNUM_TCP4_REPID > 0 */
+
+#else	/* of #if defined(SUPPORT_INET6) && TNUM_TCP6_REPID > 0 */
+
+ER
+tcp_del_rep (ID repid)
+{
+
+	/* TCP 受付口 ID をチェックする。*/
+	if (VALID_TCP4_REPID(repid))
+		return tcp4_del_rep_body(repid);
+	else
+		return E_ID;
+
+	}
+
+#endif	/* of #if defined(SUPPORT_INET6) && TNUM_TCP6_REPID > 0 */
+
+#endif	/* of #ifdef __tcp_del_rep */
+
 /*
  *  tcp_set_opt -- TCP 通信端点オプションの設定【拡張機能】
@@ -1922,6 +1542,4 @@
 #ifdef __tcp_set_opt
 
-#ifdef TCP_CFG_EXTENTIONS
-
 ER
 tcp_set_opt (ID cepid, int_t optname, void *optval, int_t optlen)
@@ -1930,5 +1548,5 @@
 
 	/* TCP 通信端点 ID をチェックする。*/
-	if (!VAID_TCP_CEPID(cepid))
+	if (!VALID_TCP_CEPID(cepid))
 		return E_ID;
 
@@ -1943,6 +1561,4 @@
 	}
 
-#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
-
 #endif	/* of #ifdef __tcp_set_opt */
 
@@ -1955,6 +1571,4 @@
 #ifdef __tcp_get_opt
 
-#ifdef TCP_CFG_EXTENTIONS
-
 ER
 tcp_get_opt (ID cepid, int_t optname, void *optval, int_t optlen)
@@ -1963,5 +1577,5 @@
 
 	/* TCP 通信端点 ID をチェックする。*/
-	if (!VAID_TCP_CEPID(cepid))
+	if (!VALID_TCP_CEPID(cepid))
 		return E_ID;
 
@@ -1976,7 +1590,7 @@
 	}
 
+#endif	/* of #ifdef __tcp_get_opt */
+
 #endif	/* of #ifdef TCP_CFG_EXTENTIONS */
 
-#endif	/* of #ifdef __tcp_get_opt */
-
 #endif	/* of #ifdef SUPPORT_TCP */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_var.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_var.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcp_var.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -75,20 +75,19 @@
  */
 
-#define IP_TCP_HDR_SIZE			(IP_HDR_SIZE + TCP_HDR_SIZE)
-#define IF_IP_TCP_HDR_SIZE		(IF_IP_HDR_SIZE + TCP_HDR_SIZE)
-#define IF_IP_TCP_HDR_OFFSET		(IF_IP_HDR_SIZE)
-#define IF_IP_TCP_SDU_OFFSET		(IF_IP_TCP_HDR_SIZE)
-
 #define GET_TCP_HDR(nbuf,thoff)		((T_TCP_HDR*)((uint8_t*)((nbuf)->buf) + thoff))
 #define GET_TCP_OPT(nbuf,thoff)		((uint8_t*)((nbuf)->buf) + thoff + TCP_HDR_SIZE)
-#define GET_TCP_SDU(nbuf,thoff)		((uint8_t*)((nbuf)->buf) + thoff + GET_TCP_HDR_SIZE2(nbuf,thoff))
+#define GET_TCP_SDU(nbuf,thoff)		((uint8_t*)((nbuf)->buf) + thoff + GET_TCP_HDR_SIZE(nbuf,thoff))
 
 #define GET_TCP_HDR_OFFSET(nbuf)	(GET_IF_IP_HDR_SIZE(nbuf))
 
-#define GET_TCP_HDR_SIZE2(nbuf,thoff)	(TCP_HDR_LEN(GET_TCP_HDR(nbuf,thoff)->doff))
-#define GET_IP_TCP_HDR_SIZE2(nbuf,thoff) \
-					(GET_IP_HDR_SIZE(GET_IP_HDR(nbuf)) + GET_TCP_HDR_SIZE2(nbuf,thoff))
-#define GET_IF_IP_TCP_HDR_SIZE2(nbuf,thoff) \
-					(IF_HDR_SIZE + GET_IP_TCP_HDR_SIZE2(nbuf,thoff))
+#define GET_TCP_HDR_SIZE(nbuf,thoff)	(TCP_HDR_LEN(GET_TCP_HDR(nbuf,thoff)->doff))
+
+#define GET_IP_TCP_HDR_SIZE(nbuf,thoff) (GET_IP_HDR_SIZE(nbuf) + GET_TCP_HDR_SIZE(nbuf,thoff))
+#define GET_IF_IP_TCP_HDR_SIZE(nbuf,thoff) \
+					(IF_HDR_SIZE + GET_IP_TCP_HDR_SIZE(nbuf,thoff))
+#define IF_IP_TCP_HDR_SIZE(nbuf)	(IF_IP_HDR_SIZE(nbuf) + TCP_HDR_SIZE)
+#define IF_IP_TCP_HDR_OFFSET(nbuf)	(IF_IP_HDR_SIZE(nbuf))
+#define IF_IP_TCP_NET_HDR_SIZE(addr)	(IF_IP_NET_HDR_SIZE(addr) + TCP_HDR_SIZE)
+#define IF_IP_TCP_NET_HDR_OFFSET(addr)	(IF_IP_NET_HDR_SIZE(addr))
 
 /*
@@ -96,12 +95,12 @@
  */
 
-#if defined(SUPPORT_INET4)
+#if !defined(_IP6_CFG) && defined(_IP4_CFG)
 
 #define IP4_TCP_HDR_SIZE		IP_TCP_HDR_SIZE
 #define IF_IP4_TCP_HDR_SIZE		IF_IP_TCP_HDR_SIZE
-#define GET_IP4_TCP_HDR_SIZE(nbuf)	GET_IP_TCP_HDR_SIZE(nbuf)	
-#define GET_IF_IP4_TCP_HDR_SIZE(nbuf)	GET_IF_IP_TCP_HDR_SIZE(nbuf)	
-
-#endif	/* of #if defined(SUPPORT_INET4) */
+#define GET_IP4_TCP_HDR_SIZE(nbuf)	GET_IP_TCP_HDR_SIZE1(nbuf)	
+#define GET_IF_IP4_TCP_HDR_SIZE(nbuf)	GET_IF_IP_TCP_HDR_SIZE1(nbuf)	
+
+#endif	/* of #if !defined(_IP6_CFG) && defined(_IP4_CFG) */
 
 /*
@@ -110,6 +109,7 @@
 
 #define	TMIN_TCP_CREPID			TMIN_TCP_REPID
+#define	TNUM_TCP_CREPID			TNUM_TCP_REPID
+
 #define	TMIN_TCP_CCEPID			TMIN_TCP_CEPID
-#define	TNUM_TCP_CREPID			TNUM_TCP_REPID
 #define	TNUM_TCP_CCEPID			TNUM_TCP_CEPID
 
@@ -121,8 +121,41 @@
 
 /*
+ * TCP で使用する変数の型の定義
+ */
+
+typedef uint32_t T_TCP_SEQ;
+typedef uint16_t T_TCP_SEG;
+typedef uint16_t T_TCP_WND;
+typedef int16_t T_TCP_TIME;
+
+/*
+ *  TCP タイマ変数
+ */
+
+#define NUM_TCP_TIMERS		4	/* TCP のタイマ数	*/
+
+/*
  *  TCP 受付口
  */
 
+/* IPv6 用 TCP 受付口 */
+
+typedef struct t_tcp6_rep {
+
+	/*
+	 * ITRON TCP/IP API、TCP 受付口と同じメンバ
+	 */
+	ATR		repatr;		/* 受付口属性		*/
+	T_IPV6EP	myaddr;		/* 自分のアドレス	*/
+
+#ifdef TCP_CFG_EXTENTIONS
+	uint16_t	flags;		/* 受付口フラグ		*/
+	ID		semid_lock;	/* 受付口ロック		*/
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+	} T_TCP6_REP;
+
 /* IPv4 用 TCP 受付口 */
+
 typedef struct t_tcp4_rep {
 
@@ -140,27 +173,19 @@
 	} T_TCP4_REP;
 
-/* IPv6 用 TCP 受付口 */
-typedef struct t_tcp6_rep {
-
-	/*
-	 * ITRON TCP/IP API、TCP 受付口と同じメンバ
-	 */
-	ATR		repatr;		/* 受付口属性		*/
-	T_IPV6EP	myaddr;		/* 自分のアドレス	*/
-
-#ifdef TCP_CFG_EXTENTIONS
-	uint16_t	flags;		/* 受付口フラグ		*/
-	ID		semid_lock;	/* 受付口ロック		*/
-#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
-
-	} T_TCP6_REP;
-
-#if defined(SUPPORT_INET4)
+#if defined(_IP6_CFG)
+
+#define T_TCP_REP	T_TCP6_REP
+
+#else	/* of #if defined(_IP6_CFG) */
+
+#if defined(_IP4_CFG)
+
 #define T_TCP_REP	T_TCP4_REP
-#endif
-
-#if defined(SUPPORT_INET6)
-#define T_TCP_REP	T_TCP6_REP
-#endif
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#endif	/* of #if defined(_IP6_CFG) */
+
+#define T_TCP_REP_DEFINED
 
 /*
@@ -175,12 +200,13 @@
  */
 
-typedef uint32_t T_TCP_SEQ;
-typedef uint16_t T_TCP_SEG;
-typedef uint16_t T_TCP_WND;
-
-/*
- * 通常の IPv4 TCP 通信端点
- */
-typedef struct t_tcp4_cep {
+#ifndef T_NET_BUF_DEFINED
+
+typedef struct t_net_buf T_NET_BUF;
+
+#define T_NET_BUF_DEFINED
+
+#endif	/* of #ifndef T_NET_BUF_DEFINED */
+
+typedef struct t_tcp_cep {
 
 	/*
@@ -232,6 +258,12 @@
 #ifdef TCP_CFG_NON_BLOCKING
 
-	T_IPV4EP 	*p_dstaddr;	/* 相手のアドレスへのポインタ	*/
-	T_IPV4EP 	*p_myaddr;	/* 自分のアドレスへのポインタ	*/
+	T_IPEP 		*p_dstaddr;	/* 相手のアドレスへのポインタ	*/
+	T_IPEP	 	*p_myaddr;	/* 自分のアドレスへのポインタ	*/
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG)
+	T_IPV4EP	*p_dstaddr4;	/* 相手のアドレスへのポインタ	*/
+	T_IPV4EP 	*p_myaddr4;	/* 自分のアドレスへのポインタ	*/
+#endif
+	
 	int16_t		snd_nblk_tfn;	/* 送信動作中の API 機能コード	*/
 	int16_t		rcv_nblk_tfn;	/* 受信動作中の API 機能コード	*/
@@ -247,5 +279,5 @@
 #ifdef TCP_CFG_SWBUF_CSAVE
 	T_NET_BUF	*swbufq;	/* 送信ウィンドバッファキュー	*/
-#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
+#endif
 
 	/*
@@ -254,12 +286,32 @@
 
 	T_TCP_TIME	timer[NUM_TCP_TIMERS];	/* TCP のタイマ		*/
-	T_IPV4EP	dstaddr;	/* 相手のアドレス		*/
-	T_IPV4EP	myaddr;		/* 自分のアドレス		*/
-	T_TCP4_REP	*rep;		/* 受付口			*/
+	T_IPEP		dstaddr;	/* 相手のアドレス		*/
+	T_IPEP		myaddr;		/* 自分のアドレス		*/
 	T_NET_BUF	*reassq;	/* 受信再構成キュー		*/
+
+#if defined(_IP6_CFG)
+
+#if defined(_IP4_CFG)
+
+	T_TCP4_REP	*rep4;		/* IPv4 用受付口		*/
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+	T_TCP6_REP	*rep;		/* IPv6 用受付口		*/
+
+#else	/* of #if defined(_IP6_CFG) */
+
+#if defined(_IP4_CFG)
+
+	T_TCP4_REP	*rep;		/* IPv4 用受付口		*/
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#endif	/* of #if defined(_IP6_CFG) */
+
 
 #ifdef TCP_CFG_RWBUF_CSAVE
 	T_NET_BUF	*rwbufq;	/* 受信ウィンドバッファキュー	*/
-#endif	/* of #ifdef TCP_CFG_RWBUF_CSAVE */
+#endif
 
 #ifdef TCP_CFG_EXTENTIONS
@@ -298,17 +350,21 @@
 
 #if defined(TCP_CFG_RWBUF_CSAVE) && defined(TCP_CFG_RWBUF_CSAVE_MAX_QUEUES)
-	uint8_t		rwbufq_entries;	/* 受信ウィンドバッファキューのエントリ数	*/
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) && defined(TCP_CFG_RWBUF_CSAVE_MAX_QUEUES)	*/
-
-	} T_TCP4_CEP;
-
-/*
- * Time Wait 用 IPv4 TCP 通信端点
- */
-typedef struct t_tcp4_twcep {
+	uint16_t	rwbufq_entries;	/* 受信ウィンドバッファキューのエントリ数	*/
+#endif
+
+	} T_TCP_CEP;
+
+#define T_TCP6_CEP	T_TCP_CEP
+#define T_TCP4_CEP	T_TCP_CEP
+
+/*
+ * Time Wait 用 TCP 通信端点
+ */
+
+typedef struct t_tcp_twcep {
 	int_t		rbufsz;		/* 受信用ウィンドバッファサイズ	*/
 	T_TCP_TIME	timer_2msl;	/* 2MSL タイマ			*/
-	T_IPV4EP	dstaddr;	/* 相手のアドレス		*/
-	T_IPV4EP	myaddr;		/* 自分のアドレス		*/
+	T_IPEP		dstaddr;	/* 相手のアドレス		*/
+	T_IPEP		myaddr;		/* 自分のアドレス		*/
 	T_TCP_SEQ	snd_una;	/* 未確認の最小送信 SEQ つまり	*/
 					/* 確認された最大送信 SEQ	*/
@@ -316,159 +372,7 @@
 	uint16_t	rwbuf_count;	/* 受信ウィンドバッファの使用中サイズ	*/
 	uint8_t		fsm_state;	/* FSM 状態			*/
-
-	} T_TCP4_TWCEP;
-
-/*
- * 通常の IPv6 TCP 通信端点
- */
-typedef struct t_tcp6_cep {
-
-	/*
-	 * ITRON TCP/IP API、TCP 通信端点と同じメンバ
-	 */
-	ATR		cepatr;		/* 通信端点属性			*/
-	void		*sbuf;		/* 送信用ウィンドバッファ	*/
-	int_t		sbufsz;		/* 送信用ウィンドバッファサイズ	*/
-	void		*rbuf;		/* 受信用ウィンドバッファ	*/
-	int_t		rbufsz;		/* 受信用ウィンドバッファサイズ	*/
-	t_tcp_callback	callback;	/* コールバック関数		*/
-
-	/*
-	 * TINET 独自のメンバ
-	 */
-	uint32_t	flags;		/* 通信端点フラグ		*/
-	ID		semid_lock;	/* 通信端点ロック		*/
-	ID		est_flgid;	/* コネクション状態イベントフラグ	*/
-	ID		snd_flgid;	/* 送信イベントフラグ		*/
-	ID		rcv_flgid;	/* 受信イベントフラグ		*/
-	ID		snd_tskid;	/* 送信タスク識別子		*/
-	ID		rcv_tskid;	/* 受信タスク識別子		*/
-	uint8_t		*sbuf_rptr;	/* 送信用読み出しポインタ		*/
-	uint8_t		*sbuf_wptr;	/* 送信用書き込みポインタ		*/
-	uint8_t		*rbuf_rptr;	/* 受信用読み出しポインタ		*/
-	uint8_t		*rbuf_wptr;	/* 受信用書き込みポインタ		*/
-	T_TCP_SEQ	snd_ssthresh;	/* 輻輳ウィンドサイズ(snd_cwnd)	*/
-					/* のしきい値			*/
-	T_TCP_TIME	rxtcur;		/* 現在の再送タイムアウト		*/
-	T_TCP_TIME	srtt;		/* 平滑化された RTT		*/
-	T_TCP_TIME	rttvar;		/* 平滑化された分散		*/
-	T_TCP_WND	snd_cwnd;	/* 輻輳ウィンドサイズ		*/
-
-	/*
-	 *  相手の最大受信セグメントサイズ	
-	 *
-	 *    オリジナルでは、一般のセグメントの最大サイズ (t_maxseg) と、
-	 *    オプション付きのセグメントの最大サイズ (t_maxopd) が別に
-	 *    なっている。これは、現在のインターネットでは、オプション付きの
-	 *    セグメントのほうが多いからと説明されているためである。
-	 *    本実装では、最大セグメントサイズオプション以外のオプションは
-	 *    実装しないので、t_maxseg の使用する。
-	 */
-	T_TCP_SEG	maxseg;
-
-	T_IPV6EP 	*p_dstaddr;	/* 相手のアドレスへのポインタ	*/
-	T_IPV6EP 	*p_myaddr;	/* 自分のアドレスへのポインタ	*/
-	int16_t		snd_tfn;	/* 送信動作中の API 機能コード	*/
-	int16_t		rcv_tfn;	/* 受信動作中の API 機能コード	*/
-
-#ifdef TCP_CFG_NON_BLOCKING
-
-	int16_t		snd_nblk_tfn;	/* 送信動作中の API 機能コード	*/
-	int16_t		rcv_nblk_tfn;	/* 受信動作中の API 機能コード	*/
-	void		*snd_data;	/* 送信データ領域の先頭アドレス	*/
-	int_t		snd_len;	/* 送信データ領域の長さ		*/
-	void		*rcv_data;	/* 受信データ領域の先頭アドレス	*/
-	int_t		rcv_len;	/* 受信データ領域の長さ		*/
-	void		**snd_p_buf;	/* 送信バッファへのポインタ	*/
-	void		**rcv_p_buf;	/* 受信バッファへのポインタ	*/
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
-
-#ifdef TCP_CFG_SWBUF_CSAVE
-	T_NET_BUF	*swbufq;	/* 送信ウィンドバッファキュー	*/
-#endif	/* of #ifdef TCP_CFG_SWBUF_CSAVE */
-
-	/*
-	 *  これ以降のメンバーは tcp_init_cep() 関数でゼロクリアーされる。
-	 */
-
-	T_TCP_TIME	timer[NUM_TCP_TIMERS];	/* TCP のタイマ		*/
-	T_IPV6EP	dstaddr;	/* 相手のアドレス		*/
-	T_IPV6EP	myaddr;		/* 自分のアドレス		*/
-	T_TCP6_REP	*rep;		/* 受付口			*/
-	T_NET_BUF	*reassq;	/* 受信再構成キュー		*/
-
-#ifdef TCP_CFG_RWBUF_CSAVE
-	T_NET_BUF	*rwbufq;	/* 受信ウィンドバッファキュー	*/
-#endif	/* of #ifdef TCP_CFG_RWBUF_CSAVE */
-
-#ifdef TCP_CFG_EXTENTIONS
-	T_TCP_HDR	*urg_tcph;	/* 緊急データ入りのセグメントの TCP ヘッダ	*/
-	T_TCP_SEQ	snd_up;		/* 送信した緊急ポインタ		*/
-	T_TCP_SEQ	rcv_up;		/* 受信した緊急ポインタ		*/
-#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
-
-	T_TCP_SEQ	snd_una;	/* 未確認の最小送信 SEQ つまり	*/
-					/* 確認された最大送信 SEQ	*/
-	T_TCP_SEQ	snd_max;	/* 送信した最大 SEQ		*/
-	T_TCP_SEQ	snd_nxt;	/* 次に送信する SEQ		*/
-	T_TCP_SEQ	snd_old_nxt;	/* 元の snd_nxt			*/
-	T_TCP_SEQ	snd_wl1;	/* 前回ウィンドを更新した SEQ	*/
-	T_TCP_SEQ	snd_wl2;	/* 前回ウィンドを更新した ACK	*/
-	T_TCP_SEQ	iss;		/* 自分の SEQ の初期値		*/
-	T_TCP_SEQ	irs;		/* 相手の SEQ の初期値		*/
-	T_TCP_SEQ	rcv_nxt;	/* 受信を期待している最小の SEQ	*/
-	T_TCP_SEQ	rcv_adv;	/* 受信を期待している最大の SEQ	*/
-	T_TCP_SEQ	rcv_wnd;	/* 受信可能なウィンドサイズ	*/
-	T_TCP_SEQ	rtseq;		/* 時間計測を始めた SEQ		*/
-	T_TCP_SEQ	last_ack_sent;	/* 最後に送信した ACK		*/
-	T_TCP_TIME	idle;		/* アイドル時間			*/
-	ER		error;		/* 非同期に発生したエラー		*/
-	ER		net_error;	/* ネットワークのエラー状態	*/
-	T_TCP_WND	snd_wnd;	/* 相手の受信可能ウィンドサイズ	*/
-	T_TCP_WND	max_sndwnd;	/* 今までの最大送信ウィンドサイズ	*/
-	T_TCP_TIME	rtt;		/* 往復時間			*/
-	uint16_t	swbuf_count;	/* 送信ウィンドバッファの使用中サイズ	*/
-	uint16_t	rwbuf_count;	/* 受信ウィンドバッファの使用中サイズ	*/
-	uint16_t	rcv_buf_len;	/* tcp_rcv_buf の割当て長	*/
-	uint16_t	get_buf_len;	/* tcp_rcv_buf の割当て長	*/
-	uint8_t		rxtshift;	/* 再送信回数の log(2)		*/
-	uint8_t		fsm_state;	/* FSM 状態			*/
-	uint8_t		dupacks;	/* 再送 ACK 数			*/
-
-#if defined(TCP_CFG_RWBUF_CSAVE) && defined(TCP_CFG_RWBUF_CSAVE_MAX_QUEUES)
-	uint8_t		rwbufq_entries;	/* 受信ウィンドバッファキューのエントリ数	*/
-#endif	/* of #if defined(TCP_CFG_RWBUF_CSAVE) && defined(TCP_CFG_RWBUF_CSAVE_MAX_QUEUES)	*/
-
-	} T_TCP6_CEP;
-
-/*
- * Time Wait 用 IPv6 TCP 通信端点
- */
-typedef struct t_tcp6_twcep {
-	int_t		rbufsz;		/* 受信用ウィンドバッファサイズ	*/
-	T_TCP_TIME	timer_2msl;	/* 2MSL タイマ			*/
-	T_IPV6EP	dstaddr;	/* 相手のアドレス		*/
-	T_IPV6EP	myaddr;		/* 自分のアドレス		*/
-	T_TCP_SEQ	snd_una;	/* 未確認の最小送信 SEQ つまり	*/
-					/* 確認された最大送信 SEQ	*/
-	T_TCP_SEQ	iss;		/* 自分の SEQ の初期値		*/
-	T_TCP_SEQ	irs;		/* 相手の SEQ の初期値		*/
-	T_TCP_SEQ	rcv_nxt;	/* 受信を期待している最小の SEQ	*/
-	T_TCP_WND	snd_wnd;	/* 相手の受信可能ウィンドサイズ	*/
-	uint16_t	rwbuf_count;	/* 受信ウィンドバッファの使用中サイズ	*/
-	uint8_t		fsm_state;	/* FSM 状態			*/
-
-	} T_TCP6_TWCEP;
-
-#if defined(SUPPORT_INET4)
-#define T_TCP_CEP	T_TCP4_CEP
-#define T_TCP_TWCEP	T_TCP4_TWCEP
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
-#define T_TCP_CEP	T_TCP6_CEP
-#define T_TCP_TWCEP	T_TCP6_TWCEP
-#endif	/* of #if defined(SUPPORT_INET6) */
+	uint8_t	flags;			/* 通信端点フラグ		*/
+
+	} T_TCP_TWCEP;
 
 #define T_TCP_CEP_DEFINED
@@ -478,31 +382,36 @@
  */
 
-#define TCP_CEP_FLG_ACK_NOW		ULONG_C(0x00000001)	/* 直ちに相手に ACK を送る。	*/
-#define TCP_CEP_FLG_DEL_ACK		ULONG_C(0x00000002)	/* ACK を遅延する。		*/
-#define TCP_CEP_FLG_SENT_FIN		ULONG_C(0x00000004)	/* FIN を送ってある。		*/
-#define TCP_CEP_FLG_NEED_SYN		ULONG_C(0x00000008)	/* SYN を送信する。		*/
-#define TCP_CEP_FLG_NEED_FIN		ULONG_C(0x00000010)	/* FIN を送信する。		*/
-#define TCP_CEP_FLG_FORCE		ULONG_C(0x00000020)	/* 強制送信。			*/
-#define TCP_CEP_FLG_NO_PUSH		ULONG_C(0x00000040)	/* push しない。		*/
-#define TCP_CEP_FLG_NO_DELAY		ULONG_C(0x00000080)	/* 遅延しない。			*/
-#define TCP_CEP_FLG_FORCE_CLEAR		ULONG_C(0x00000100)	/* 強制送信した後フラグをクリアーする。*/
-#define TCP_CEP_FLG_POST_OUTPUT		ULONG_C(0x00000200)	/* 送信を開始する。		*/
-#define TCP_CEP_FLG_RESERVE_OUTPUT	ULONG_C(0x00000400)	/* 送信を予約する。		*/
-#define TCP_CEP_FLG_DYNAMIC		ULONG_C(0x00001000)	/* 動的生成・削除可能通信端点。	*/
-#define TCP_CEP_FLG_VALID		ULONG_C(0x00002000)	/* 生成済みで有効な通信端点。	*/
-#define TCP_CEP_FLG_CLOSE_AFTER_OUTPUT	ULONG_C(0x00004000)	/* 送信した後コネクションを閉じる。*/
-#define TCP_CEP_FLG_RESTORE_NEXT_OUTPUT	ULONG_C(0x00008000)	/* 送信した後、snd_nxt を元に戻す。*/
+#define TCP_CEP_FLG_IPV4		ULONG_C(0x00000001)	/* IPv4 用。			*/
+#define TCP_CEP_FLG_ACK_NOW		ULONG_C(0x00000100)	/* 直ちに相手に ACK を送る。	*/
+#define TCP_CEP_FLG_DEL_ACK		ULONG_C(0x00000200)	/* ACK を遅延する。		*/
+#define TCP_CEP_FLG_SENT_FIN		ULONG_C(0x00000400)	/* FIN を送ってある。		*/
+#define TCP_CEP_FLG_NEED_SYN		ULONG_C(0x00000800)	/* SYN を送信する。		*/
+#define TCP_CEP_FLG_NEED_FIN		ULONG_C(0x00001000)	/* FIN を送信する。		*/
+#define TCP_CEP_FLG_FORCE		ULONG_C(0x00002000)	/* 強制送信。			*/
+#define TCP_CEP_FLG_NO_PUSH		ULONG_C(0x00004000)	/* push しない。		*/
+#define TCP_CEP_FLG_NO_DELAY		ULONG_C(0x00008000)	/* 遅延しない。			*/
+#define TCP_CEP_FLG_FORCE_CLEAR		ULONG_C(0x00010000)	/* 強制送信した後フラグをクリアーする。*/
+#define TCP_CEP_FLG_POST_OUTPUT		ULONG_C(0x00020000)	/* 送信を開始する。		*/
+#define TCP_CEP_FLG_RESERVE_OUTPUT	ULONG_C(0x00040000)	/* 送信を予約する。		*/
+#define TCP_CEP_FLG_DYNAMIC		ULONG_C(0x00100000)	/* 動的生成・削除可能通信端点。	*/
+#define TCP_CEP_FLG_VALID		ULONG_C(0x00200000)	/* 生成済みで有効な通信端点。	*/
+#define TCP_CEP_FLG_CLOSE_AFTER_OUTPUT	ULONG_C(0x00400000)	/* 送信した後コネクションを閉じる。*/
+#define TCP_CEP_FLG_RESTORE_NEXT_OUTPUT	ULONG_C(0x00800000)	/* 送信した後、snd_nxt を元に戻す。*/
 
 /* 送受信ウィンドバッファの省コピー機能 */
-#define TCP_CEP_FLG_WBCS_NBUF_REQ	ULONG_C(0x00080000)	/* ネットワークバッファ割当て要求	*/
-#define TCP_CEP_FLG_WBCS_MASK		ULONG_C(0x00070000)	/* マスク			*/
+#define TCP_CEP_FLG_WBCS_NBUF_REQ	ULONG_C(0x80000000)	/* ネットワークバッファ割当て要求*/
+#define TCP_CEP_FLG_WBCS_MASK		ULONG_C(0x70000000)	/* マスク			*/
 #define TCP_CEP_FLG_WBCS_FREE		ULONG_C(0x00000000)	/* 送信ウィンドバッファ未使用	*/
-#define TCP_CEP_FLG_WBCS_WOPEN_PEND	ULONG_C(0x00010000)	/* 相手の受信ウィンドの開き待ち	*/
-#define TCP_CEP_FLG_WBCS_NBUF_PEND	ULONG_C(0x00020000)	/* ネットワークバッファ予約待ち	*/
-#define TCP_CEP_FLG_WBCS_NBUF_RSVD	ULONG_C(0x00030000)	/* ネットワークバッファ予約済み	*/
-#define TCP_CEP_FLG_WBCS_NBUF_READY	ULONG_C(0x00040000)	/* ネットワークバッファ割当て済み	*/
-#define TCP_CEP_FLG_WBCS_SEND_READY	ULONG_C(0x00050000)	/* 送信可能			*/
-#define TCP_CEP_FLG_WBCS_SENT		ULONG_C(0x00060000)	/* 送信済みで、ACK待ち		*/
-#define TCP_CEP_FLG_WBCS_ACKED		ULONG_C(0x00070000)	/* 送信済みで、ACK完了		*/
+#define TCP_CEP_FLG_WBCS_WOPEN_PEND	ULONG_C(0x10000000)	/* 相手の受信ウィンドの開き待ち	*/
+#define TCP_CEP_FLG_WBCS_NBUF_PEND	ULONG_C(0x20000000)	/* ネットワークバッファ予約待ち	*/
+#define TCP_CEP_FLG_WBCS_NBUF_RSVD	ULONG_C(0x30000000)	/* ネットワークバッファ予約済み	*/
+#define TCP_CEP_FLG_WBCS_NBUF_READY	ULONG_C(0x40000000)	/* ネットワークバッファ割当て済み*/
+#define TCP_CEP_FLG_WBCS_SEND_READY	ULONG_C(0x50000000)	/* 送信可能			*/
+#define TCP_CEP_FLG_WBCS_SENT		ULONG_C(0x60000000)	/* 送信済みで、ACK待ち		*/
+#define TCP_CEP_FLG_WBCS_ACKED		ULONG_C(0x70000000)	/* 送信済みで、ACK完了		*/
+
+/* 初期化から除外するフラグの定義 */
+#define TCP_CEP_FLG_NOT_CLEAR		(TCP_CEP_FLG_WBCS_NBUF_REQ|TCP_CEP_FLG_WBCS_MASK|\
+					 TCP_CEP_FLG_DYNAMIC|TCP_CEP_FLG_VALID|TCP_CEP_FLG_IPV4)
 
 /*
@@ -513,5 +422,5 @@
 #define TCP_CEP_EVT_CLOSED		ULONG_C(0x00000002)	/* 未使用状態			*/
 #define TCP_CEP_EVT_SWBUF_READY		ULONG_C(0x00000004)	/* 送信ウィンドバッファ空き	*/
-#define TCP_CEP_EVT_RWBUF_READY		ULONG_C(0x00000008)	/* 送信ウィンドバッファデータあり	*/
+#define TCP_CEP_EVT_RWBUF_READY		ULONG_C(0x00000008)	/* 送信ウィンドバッファデータあり*/
 #define TCP_CEP_EVT_ALL			ULONG_C(0xffffffff)	/* 全イベント			*/
 
@@ -571,5 +480,4 @@
 
 #define GET_TCP_Q_HDR(nbuf,thoff)	((T_TCP_Q_HDR*)((uint8_t*)((nbuf)->buf) + thoff))
-#define GET_TCP_IP_Q_HDR(nbuf)		((T_TCP_IP_Q_HDR*)GET_IP_HDR(nbuf))
 
 /*
@@ -577,11 +485,19 @@
  */
 
-#define	TMIN_TCP_REPID		1	/* TCP 受付口   ID の最小値			*/
-#define	TMIN_TCP_CEPID		1	/* TCP 通信端点 ID の最小値			*/
-#define	TMIN_TCP_TWCEPID	1	/* Time Wait 用 TCP 通信端点 ID の最小値	*/
+#define	TMIN_TCP_REPID		1			/* TCP      受付口 ID の最小値			*/
+#define	TMIN_TCP6_REPID		1			/* TCP/IPv6 受付口 ID の最小値			*/
+#define	TMIN_TCP4_REPID		(TNUM_TCP6_REPID+1)	/* TCP/IPv4 受付口 ID の最小値			*/
+
+#define	TMIN_TCP_CEPID		1			/* TCP      通信端点 ID の最小値			*/
+#define	TMIN_TCP6_CEPID		1			/* TCP/IPv6 通信端点 ID の最小値			*/
+#define	TMIN_TCP4_CEPID		(TNUM_TCP6_CEPID+1)	/* TCP/IPv4 通信端点 ID の最小値			*/
+
+#define	TMIN_TCP_TWCEPID	1			/* Time Wait 用 TCP 通信端点 ID の最小値	*/
 
 /*
  *  制御セグメント（データなし）サイズのネットワークバッファ
  */
+
+#if defined(IF_HDR_SIZE) && defined(IP_HDR_SIZE)
 
 typedef struct t_net_buf_cseg {
@@ -599,5 +515,5 @@
 	} T_NET_BUF_CSEG;
 
-#ifdef SUPPORT_MIB
+#endif	/* of #if defined(IF_HDR_SIZE) && defined(IP_HDR_SIZE) */
 
 /*
@@ -618,22 +534,48 @@
 } T_TCP_STATS;
 
-#endif	/* of #ifdef SUPPORT_MIB */
-
 /*
  *  関数シミュレーションマクロ
  */
 
-#define VAID_TCP_REPID(id)	(TMIN_TCP_REPID<=(id)&&(id)<=tmax_tcp_repid)
-#define VAID_TCP_CEPID(id)	(TMIN_TCP_CEPID<=(id)&&(id)<=tmax_tcp_cepid)
-
-#define INDEX_TCP_REP(id)	((id)-TMIN_TCP_REPID)
+/* TCP 受付口 */
+
+#define VALID_TCP6_REPID(id)	(TMIN_TCP6_REPID<=(id)&&(id)<=tmax_tcp6_repid)
+#define VALID_TCP4_REPID(id)	(TMIN_TCP4_REPID<=(id)&&(id)<=tmax_tcp4_repid)
+
+#define INDEX_TCP6_REP(id)	((id)-TMIN_TCP6_REPID)
+#define INDEX_TCP4_REP(id)	((id)-TMIN_TCP4_REPID)
+
+#define GET_TCP6_REP(id)	(&(tcp6_rep[INDEX_TCP6_REP(id)]))
+#define GET_TCP4_REP(id)	(&(tcp4_rep[INDEX_TCP4_REP(id)]))
+
+#define GET_TCP6_REPID(rep)	((ID)(((rep)-tcp6_rep)+TMIN_TCP6_REPID))
+#define GET_TCP4_REPID(rep)	((ID)(((rep)-tcp4_rep)+TMIN_TCP4_REPID))
+
+#ifdef TCP_CFG_EXTENTIONS
+
+#define VALID_TCP_REP(rep)	(((rep)->flags&TCP_REP_FLG_VALID)!=0)
+#define DYNAMIC_TCP_REP(rep)	(((rep)->flags&TCP_REP_FLG_DYNAMIC)!=0)
+
+#else	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+#define VALID_TCP_REP(rep)	(true)
+#define DYNAMIC_TCP_REP(rep)	(false)
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+/* TCP 通信端点 */
+
+#define VALID_TCP_CEPID(id)	(TMIN_TCP_CEPID<=(id)&&(id)<=tmax_tcp_cepid)
 #define INDEX_TCP_CEP(id)	((id)-TMIN_TCP_CEPID)
 
-#define GET_TCP_REP(id)		(&(tcp_rep[INDEX_TCP_REP(id)]))
 #define GET_TCP_CEP(id)		(&(tcp_cep[INDEX_TCP_CEP(id)]))
 
-#define GET_TCP_REPID(rep)	((ID)(((rep)-tcp_rep)+TMIN_TCP_REPID))
 #define GET_TCP_CEPID(cep)	((ID)(((cep)-tcp_cep)+TMIN_TCP_CEPID))
 #define GET_TCP_TWCEPID(cep)	((ID)(((cep)-tcp_twcep)+TMIN_TCP_TWCEPID))
+
+#define VALID_TCP_CEP(cep)	(((cep)->flags&TCP_CEP_FLG_VALID)!=0)
+#define DYNAMIC_TCP_CEP(cep)	(((cep)->flags&TCP_CEP_FLG_DYNAMIC)!=0)
+#define TCP_IS_CEP_IPV6(cep)	(((cep)->flags&TCP_CEP_FLG_IPV4)==0)
+#define TCP_IS_CEP_IPV4(cep)	(((cep)->flags&TCP_CEP_FLG_IPV4)!=0)
 
 #define IS_TFN_TCP_RCV(t)	((t)==TFN_TCP_ACP_CEP||(t)==TFN_TCP_RCV_DAT||\
@@ -651,35 +593,47 @@
 #define VALID_URG_POINTER(urg)	(TCP_CFG_URG_OFFSET==0||urg!=0)
 
-#define VALID_TCP_CEP(cep)	(((cep)->flags&TCP_CEP_FLG_VALID)!=0)
-#define DYNAMIC_TCP_CEP(cep)	(((cep)->flags&TCP_CEP_FLG_DYNAMIC)!=0)
-
-#ifdef TCP_CFG_EXTENTIONS
-
-#define VALID_TCP_REP(rep)	(((rep)->flags&TCP_REP_FLG_VALID)!=0)
-#define DYNAMIC_TCP_REP(rep)	(((rep)->flags&TCP_REP_FLG_DYNAMIC)!=0)
-
-#else	/* of #ifdef TCP_CFG_EXTENTIONS */
-
-#define VALID_TCP_REP(rep)	(true)
-#define DYNAMIC_TCP_REP(rep)	(false)
-
-#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
-
 /*
  *  全域変数
  */
 
-extern T_TCP_REP tcp_rep[];
+extern uint8_t tcp_initialized;
+
+extern T_TCP_STATS tcp_stats;
+
+/* TCP 受付口 */
+
+extern T_TCP6_REP tcp6_rep[];
+extern T_TCP4_REP tcp4_rep[];
+
+#if defined(SUPPORT_INET6)
+#define tcp_rep	tcp6_rep
+#elif defined(SUPPORT_INET4)
+#define tcp_rep	tcp4_rep
+#endif
+
+extern const ID tmax_tcp_repid;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+extern const ID tmax_tcp6_repid;
+extern const ID tmax_tcp4_repid;
+#else
+#define tmax_tcp6_repid	tmax_tcp_repid
+#define tmax_tcp4_repid	tmax_tcp_repid
+#endif
+
+/* TCP 通信端点 */
+
 extern T_TCP_CEP tcp_cep[];
-extern uint8_t tcp_initialized;
-extern const ID tmax_tcp_repid;
+extern T_TCP_TWCEP tcp_twcep[];
+
 extern const ID tmax_tcp_cepid;
-extern T_TCP_TWCEP tcp_twcep[];
-
-#ifdef SUPPORT_MIB
-
-extern T_TCP_STATS tcp_stats;
-
-#endif	/* of #ifdef SUPPORT_MIB */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+extern const ID tmax_tcp6_cepid;
+extern const ID tmax_tcp4_cepid;
+#else
+#define tmax_tcp6_cepid	tmax_tcp_cepid
+#define tmax_tcp4_cepid	tmax_tcp_cepid
+#endif
 
 /*
@@ -866,7 +820,8 @@
 extern void tcp_respond (T_NET_BUF *nbuf, T_TCP_CEP *cep,
                          T_TCP_SEQ ack, T_TCP_SEQ seq, uint_t rbfree, uint8_t flags);
-extern void tcp_set_header (T_NET_BUF *nbuf, T_TCP_CEP *cep, uint_t thoff, uint_t optlen);
 extern ER tcp_get_segment (T_NET_BUF **nbuf, T_TCP_CEP *cep,
                            uint_t optlen, uint_t len, uint_t maxlen, ATR nbatr, TMO tmout);
+extern ER tcpn_get_segment (T_NET_BUF **nbuf, T_TCP_CEP *cep,
+                            uint_t optlen, uint_t len, uint_t maxlen, ATR nbatr, TMO tmout);
 extern void tcp_init_cep (T_TCP_CEP *cep);
 extern void tcp_notify (T_NET_BUF *input, int code);
@@ -876,5 +831,4 @@
 extern void tcp_alloc_auto_port (T_TCP_CEP *cep);
 extern ER tcp_alloc_port (T_TCP_CEP *cep, uint16_t portno);
-extern void tcp_move_twcep (T_TCP_CEP *cep);
 extern ER tcp_lock_cep (ID cepid, T_TCP_CEP **p_cep, FN tfn);
 extern void tcp_free_reassq (T_TCP_CEP *cep);
@@ -885,4 +839,8 @@
 extern ER tcp_wait_rwbuf (T_TCP_CEP *cep, TMO tmout);
 extern T_TCP_CEP *tcp_user_closed (T_TCP_CEP *cep);
+extern T_TCP_CEP *tcp_find_cep (T_NET_BUF *input, uint_t off);
+extern T_TCP_TWCEP*tcp_find_twcep (T_NET_BUF *input, uint_t off);
+extern bool_t tcp_is_addr_accept (T_NET_BUF *input, uint_t off);
+extern void tcp_move_twcep (T_TCP_CEP *cep);
 
 /*
@@ -974,14 +932,4 @@
 
 /*
- *  tcp_find_cep -- ポート番号から TCP 通信端点を得る。
- *
- *    注意: myaddr は、
- *          TINET-1.2 からネットワークバイトオーダ、
- *          TINET-1.1 までは、ホストバイトオーダ
- */
-extern T_TCP_CEP *tcp_find_cep (T_IN_ADDR *dstaddr,  uint16_t dstport,
-                                T_IN_ADDR *peeraddr, uint16_t peerport);
-
-/*
  *  TCP ヘッダのトレース出力機能用関数
  */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcpn_usrreq.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcpn_usrreq.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/tcpn_usrreq.c	(revision 331)
@@ -0,0 +1,777 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	From: @(#)tcp_usrreq.c	8.2 (Berkeley) 1/3/94
+ * $FreeBSD: src/sys/netinet/tcp_usrreq.c,v 1.40.2.3 1999/08/29 16:29:57 peter Exp $
+ */
+
+#ifdef TCP_CFG_EXTENTIONS
+
+#if (API_PROTO == API_PROTO_IPV6 && TNUM_TCP6_REPID > 0) || (API_PROTO == API_PROTO_IPV4 && TNUM_TCP4_REPID > 0)
+
+/*
+ *  tcp_cre_rep -- TCP åä»å£ã®çæãæ¡å¼µæ©è½ã
+ */
+
+#ifdef __tcp_cre_rep
+
+ER
+TCP_CRE_REP (ID repid, T_TCPN_CREP *pk_crep)
+{
+	T_TCP_REP	*rep;
+	ER		error;
+
+	/* TCP åä»å£ ID ããã§ãã¯ããã*/
+	if (!VALID_TCP_REPID(repid))
+		return E_ID;
+
+	/* pk_crep ã NULL ãªãã¨ã©ã¼ */
+	if (pk_crep == NULL)
+		return E_PAR;
+
+#if (API_PROTO == API_PROTO_IPV6) && !defined(API_CFG_IP4MAPPED_ADDR)
+
+	/*
+	 * API ã IPv6 ã§ IPv4 å°å½±ã¢ãã¬ã¹ãèªãããã¦ããªãã®ã«ããããããã
+	 * IPv4 å°å½±ã¢ãã¬ã¹ãæå®ããããã¨ã©ã¼
+	 */
+	if (in6_is_addr_ipv4mapped(&pk_crep->myaddr.ipaddr))
+		return E_PAR;
+
+#endif	/* of #if (API_PROTO == API_PROTO_IPV6) && !defined(DAPI_CFG_IP4MAPPED_ADDR) */
+
+	/* TCP åä»å£ãå¾ãã*/
+	rep = GET_TCP_REP(repid);
+
+	/* TCP åä»å£ããåççæç¨ã§ãªããã°ã¨ã©ã¼ */
+	if (!DYNAMIC_TCP_REP(rep))
+		return E_ID;
+
+	/* åä»å£ãã­ãã¯ããã*/
+	syscall(wai_sem(rep->semid_lock));
+
+	/*
+	 * TCP åä»å£ããã§ãã¯ãããçææ¸ã¿ã§ããã°ã¨ã©ã¼
+	 */
+	if (VALID_TCP_REP(rep))
+		error = E_OBJ;
+	else {
+
+		/* TCP åä»å£çææ
+å ±ãã³ãã¼ããã*/
+		rep->repatr = pk_crep->repatr;			/* åä»å£å±æ§		*/
+		rep->myaddr.ipaddr = pk_crep->myaddr.ipaddr;	/* èªåã®ã¢ãã¬ã¹	*/
+		rep->myaddr.portno = pk_crep->myaddr.portno;	/* èªåã®ã¢ãã¬ã¹	*/
+
+		/* TCP åä»å£ãçææ¸ã¿ã«ããã*/
+		rep->flags |= TCP_REP_FLG_VALID;
+		error = E_OK;
+		}
+
+	/* åä»å£ã®ã­ãã¯ãè§£é¤ããã*/
+	syscall(sig_sem(rep->semid_lock));
+
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_cre_rep */
+
+#ifdef __tcp_del_rep
+
+/*
+ *  tcp_find_cep_rep -- TCP åä»å£ããªã³ã¯ãã¦ãã TCP éä¿¡ç«¯ç¹ãå¾ãã
+ */
+
+static T_TCP_CEP*
+TCP_FIND_CEP_REP (T_TCP_REP* rep)
+{
+	T_TCP_CEP*	cep;
+
+	for (cep = &tcp_cep[tmax_tcp_cepid]; cep -- != tcp_cep; ) {
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4)
+		if (cep->rep4 == rep)
+#else
+		if (cep->rep == rep)
+#endif
+			return cep;
+		}
+
+	return NULL;
+	}
+
+/*
+ *  tcp_del_rep_body -- TCP åä»å£ã®åé¤ãæ¡å¼µæ©è½ãã®æ¬ä½
+ */
+
+static ER
+TCP_DEL_REP_BODY (ID repid)
+{
+	T_TCP_CEP	*cep;
+	T_TCP_REP	*rep;
+	ER		error = E_OK;
+
+	/* TCP åä»å£ ID ã®ãã§ãã¯ã¯çµäºãã¦ããã*/
+
+	/* TCP åä»å£ãå¾ãã*/
+	rep = GET_TCP_REP(repid);
+
+	/* TCP åä»å£ããåççæç¨ã§ãªããã°ã¨ã©ã¼ */
+	if (!DYNAMIC_TCP_REP(rep))
+		return E_ID;
+
+	/* åä»å£ãã­ãã¯ããã*/
+	syscall(wai_sem(rep->semid_lock));
+
+	/* TCP åä»å£ããã§ãã¯ãããæªçæã®å ´åã¯ã¨ã©ã¼ */
+	if (!VALID_TCP_REP(rep))
+		error = E_NOEXS;
+	else {
+		if ((cep = TCP_FIND_CEP_REP(rep)) != NULL) {
+			/*
+			 * ãã§ã«ååãªã¼ãã³ãã¦ããã¨ã
+			 *ï¼tcp_acp_cep ãå¼ã°ãã¦ããã¨ãï¼ã¯ã
+			 * tcp_acp_cep ãçµäºãããã
+			 */
+
+			/* éä¿¡ç«¯ç¹ãã­ãã¯ããã*/
+			syscall(wai_sem(cep->semid_lock));
+
+			/*
+			 *  éä¿¡ç«¯ç¹ããåä»å£ãè§£æ¾ãã
+			 *  ã¤ãã³ããã©ã°ãã¯ã­ã¼ãºã«è¨­å®ããã
+			 */
+			cep->rep = NULL;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+			cep->rep4 = NULL;
+#endif
+
+			cep->fsm_state = TCP_FSM_CLOSED;
+			cep->error = E_DLT;
+			syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+			if (cep->rcv_nblk_tfn != TFN_TCP_UNDEF) {
+				if (IS_PTR_DEFINED(cep->callback)) {
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+
+					(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)E_DLT);
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+					ER	error = E_DLT;
+
+					(*cep->callback)(GET_TCP_CEPID(cep), cep->rcv_nblk_tfn, (void*)&error);
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+					}
+				else
+					error = E_OBJ;
+				cep->rcv_nblk_tfn = TFN_TCP_UNDEF;
+				}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+			cep->rcv_tskid = TA_NULL;
+			cep->rcv_tfn   = TFN_TCP_UNDEF;
+
+			/* éä¿¡ç«¯ç¹ã®ã­ãã¯ãè§£é¤ããã*/
+			syscall(sig_sem(cep->semid_lock));
+
+			}
+		else
+			error = E_OK;
+
+		/* TCP åä»å£ãæªçæã«ããã*/
+		rep->flags &= ~TCP_REP_FLG_VALID;
+		}
+
+	/* åä»å£ã®ã­ãã¯ãè§£é¤ããã*/
+	syscall(sig_sem(rep->semid_lock));
+
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_del_rep */
+
+#endif	/* of #if (API_PROTO == API_PROTO_IPV6 && TNUM_TCP6_REPID > 0) || (API_PROTO == API_PROTO_IPV4 && TNUM_TCP4_REPID > 0) */
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+#if (API_PROTO == API_PROTO_IPV6 && TNUM_TCP6_REPID > 0) || (API_PROTO == API_PROTO_IPV4 && TNUM_TCP4_REPID > 0)
+
+/*
+ *  tcp_acp_cep -- æ¥ç¶è¦æ±å¾
+ã¡ (ååãªã¼ãã³)ãæ¨æºæ©è½ã
+ */
+
+#ifdef __tcp_acp_cep
+
+ER
+TCP_ACP_CEP (ID cepid, ID repid, T_IPEP *p_dstaddr, TMO tmout)
+{
+	T_TCP_REP	*rep;
+	T_TCP_CEP	*cep;
+	ER		error;
+	FLGPTN		flag;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+	/*
+	 * API (tcp6_acp_cep ã¨ tcp_acp_cep) ã¨ã
+	 * TCPéä¿¡ç«¯ç¹ã®ãã­ãã³ã«ãçç¾ãã¦ããã°ã¨ã©ã¼
+	 */
+
+#if API_PROTO == API_PROTO_IPV6
+
+	if (GET_TCP_CEP(cepid)->flags & TCP_CEP_FLG_IPV4)
+		return E_ID;
+
+#endif	/* of #if API_PROTO == API_PROTO_IPV6 */
+
+#if API_PROTO == API_PROTO_IPV4
+
+	if ((GET_TCP_CEP(cepid)->flags & TCP_CEP_FLG_IPV4) == 0)
+		return E_ID;
+
+#endif	/* of #if API_PROTO == API_PROTO_IPV4 */
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	/* TCP åä»å£ããã§ãã¯ããã*/
+	if (!VALID_TCP_REPID(repid))
+		return E_ID;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/* p_dstaddr ã NULL ãªãã¨ã©ã¼ */
+	if (p_dstaddr == NULL)
+		return E_PAR;
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	/* p_dstaddr ã NULL ããtmout ã TMO_NBLK ãªãã¨ã©ã¼ */
+	if (p_dstaddr == NULL || tmout == TMO_NBLK)
+		return E_PAR;
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+#if (API_PROTO == API_PROTO_IPV6) && !defined(API_CFG_IP4MAPPED_ADDR)
+
+	/*
+	 * API ã IPv6 ã§ IPv4 å°å½±ã¢ãã¬ã¹ãèªãããã¦ããªãã®ã«ããããããã
+	 * IPv4 å°å½±ã¢ãã¬ã¹ãæå®ããããã¨ã©ã¼
+	 */
+	if (in6_is_addr_ipv4mapped(&p_dstaddr->ipaddr))
+		return E_PAR;
+
+#endif	/* of #if (API_PROTO == API_PROTO_IPV6) && !defined(DAPI_CFG_IP4MAPPED_ADDR) */
+
+	/*
+	 *  CEP ãã­ãã¯ããAPI æ©è½ã³ã¼ãã¨ã¿ã¹ã¯è­å¥å­ãè¨é²ããã
+	 *  ãã§ã«è¨é²ããã¦ããã°ããã³ãã£ã³ã°ä¸­ãªã®ã§ã¨ã©ã¼
+	 */
+	if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_ACP_CEP)) != E_OK)
+		return error;
+
+	/* CEP ã® FSM ãã¯ã­ã¼ãºç¶æ
+ã§ãªããã°ã¨ã©ã¼ã*/
+	if (cep->fsm_state != TCP_FSM_CLOSED) {
+		error = E_OBJ;
+		goto err_ret;
+		}
+	syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_CLOSED)));
+
+	/* TCP éä¿¡ç«¯ç¹ãåæåããã*/
+	tcp_init_cep(cep);
+
+	/* TCP åä»å£ãå¾ãã*/
+
+	rep = GET_TCP_REP(repid);
+
+#ifdef TCP_CFG_EXTENTIONS
+
+	/* TCP åä»å£ãã­ãã¯ããã*/
+	syscall(wai_sem(rep->semid_lock));
+
+	/* TCP åä»å£ããã§ãã¯ããã*/
+	if (!VALID_TCP_REP(rep)) {
+		syscall(sig_sem(rep->semid_lock));
+		error = E_NOEXS;
+		goto err_ret;
+		}
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+	/* TCP éä¿¡ç«¯ç¹ã«TCPåä»å£ãè¨é²ããã*/
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+#if API_PROTO == API_PROTO_IPV6
+
+	cep->rep = rep;
+
+#else	/* of #if API_PROTO == API_PROTO_IPV6 */
+
+	cep->rep4 = rep;
+
+#endif	/*of #if API_PROTO == API_PROTO_IPV6 */
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	cep->rep = rep;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+#ifdef TCP_CFG_EXTENTIONS
+
+	/* TCP åä»å£ã®ã­ãã¯ãè§£é¤ããã*/
+	syscall(sig_sem(rep->semid_lock));
+
+#endif	/* of #ifdef TCP_CFG_EXTENTIONS */
+
+	/* TCP åä»å£ã®ã¢ãã¬ã¹ãã³ãã¼ããã*/
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4)
+
+	if (rep->myaddr.ipaddr == IPV4_ADDRANY)
+		memcpy(&cep->myaddr.ipaddr, &in6_addr_unspecified,
+		                      sizeof(in6_addr_unspecified));
+	else
+		in6_make_ipv4mapped(&cep->myaddr.ipaddr, rep->myaddr.ipaddr);
+	cep->myaddr.portno = rep->myaddr.portno;
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
+
+	cep->myaddr = rep->myaddr;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
+
+#if API_PROTO == API_PROTO_IPV4
+
+	/* TCP éä¿¡ç«¯ç¹ã®ãããã¯ã¼ã¯å±¤ãã­ãã³ã«ãè¨­å®ããã*/
+	cep->flags |= TCP_CEP_FLG_IPV4;
+
+#endif	/* of #if API_PROTO == API_PROTO_IPV4 */
+
+	/* éä¿¡ç«¯ç¹ãè¨­å®ããã*/
+	cep->fsm_state = TCP_FSM_LISTEN;
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/* ã¿ã¤ã ã¢ã¦ãããã§ãã¯ããã*/
+	if (tmout == TMO_NBLK) {
+		/* ãã³ãã­ãã­ã³ã°ã³ã¼ã« */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+#if API_PROTO == API_PROTO_IPV4
+
+		cep->p_dstaddr4   = p_dstaddr;
+		cep->p_dstaddr    = NULL;
+
+#else	/* of #if API_PROTO == API_PROTO_IPV4 */
+
+		cep->p_dstaddr4   = NULL;
+		cep->p_dstaddr    = p_dstaddr;
+
+#endif	/* of #if API_PROTO == API_PROTO_IPV4 */
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+		cep->p_dstaddr    = p_dstaddr;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+		cep->rcv_nblk_tfn = TFN_TCP_ACP_CEP;
+		return E_WBLK;
+		}
+	else {
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+		/*
+		 *  FSM ã ESTABLISHED ã«ãªãã¾ã§å¾
+ã¤ã
+		 *  FSM ã CLOSED ã«ãªã£ãå ´åã¯ãã¨ã©ã¼ãçºçãããã¨ãæå³ãã¦ããã
+		 */
+		error = twai_flg(cep->est_flgid, (TCP_CEP_EVT_CLOSED |
+		                                  TCP_CEP_EVT_ESTABLISHED), TWF_ORW, &flag, tmout);
+		if (error == E_OK) {
+			if (cep->error != E_OK)
+				error = cep->error;
+			else if (cep->fsm_state == TCP_FSM_CLOSED)
+				error = E_TMOUT;
+			}
+
+		syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_ESTABLISHED)));
+
+		if (error == E_OK) {
+			/* ç¸æã®ã¢ãã¬ã¹ãã³ãã¼ããã*/
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4)
+			p_dstaddr->ipaddr = ntohl(cep->dstaddr.ipaddr.s6_addr32[3]);
+			p_dstaddr->portno = cep->dstaddr.portno;
+#else
+			*p_dstaddr = cep->dstaddr;
+#endif
+			}
+		else {
+			/*
+			 *  éä¿¡ç«¯ç¹ããåä»å£ãè§£æ¾ãã
+			 *  ã¤ãã³ããã©ã°ãã¯ã­ã¼ãºã«è¨­å®ããã
+			 */
+			cep->rep = NULL;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+			cep->rep4 = NULL;
+#endif
+
+			cep->fsm_state = TCP_FSM_CLOSED;
+			syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
+			}
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+		}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+err_ret:
+	cep->rcv_tskid = TA_NULL;
+	cep->rcv_tfn   = TFN_TCP_UNDEF;
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_acp_cep */
+
+#endif	/* of #if (API_PROTO == API_PROTO_IPV6 && TNUM_TCP6_REPID > 0) || (API_PROTO == API_PROTO_IPV4 && TNUM_TCP4_REPID > 0) */
+
+/*
+ *  tcp_con_cep -- æ¥ç¶è¦æ± (è½åãªã¼ãã³)ãæ¨æºæ©è½ã
+ */
+
+#ifdef __tcp_con_cep
+
+ER
+TCP_CON_CEP (ID cepid, T_IPEP *p_myaddr, T_IPEP *p_dstaddr, TMO tmout)
+{
+	T_TCP_CEP	*cep;
+	ER		error;
+	FLGPTN		flag;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+	/*
+	 * API (tcp6_acp_cep ã¨ tcp_acp_cep) ã¨ã
+	 * TCPéä¿¡ç«¯ç¹ã®ãã­ãã³ã«ãçç¾ãã¦ããã°ã¨ã©ã¼
+	 */
+
+#if API_PROTO == API_PROTO_IPV6
+
+	if (GET_TCP_CEP(cepid)->flags & TCP_CEP_FLG_IPV4)
+		return E_ID;
+
+#endif	/* of #if API_PROTO == API_PROTO_IPV6 */
+
+#if API_PROTO == API_PROTO_IPV4
+
+	if ((GET_TCP_CEP(cepid)->flags & TCP_CEP_FLG_IPV4) == 0)
+		return E_ID;
+
+#endif	/* of #if API_PROTO == API_PROTO_IPV4 */
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+	/*
+	 *  ãã¦å
+ããã«ãã­ã£ã¹ãã¢ãã¬ã¹ãªãã¨ã©ã¼
+	 */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4)
+
+	if (IN4_IS_ADDR_MULTICAST(p_dstaddr->ipaddr))
+		return E_PAR;
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
+
+	if (IN_IS_ADDR_MULTICAST(&p_dstaddr->ipaddr))
+		return E_PAR;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
+
+#if (API_PROTO == API_PROTO_IPV6) && !defined(API_CFG_IP4MAPPED_ADDR)
+
+	/*
+	 * API ã IPv6 ã§ IPv4 å°å½±ã¢ãã¬ã¹ãèªãããã¦ããªãã®ã«ããããããã
+	 * IPv4 å°å½±ã¢ãã¬ã¹ãæå®ããããã¨ã©ã¼
+	 */
+	if (in6_is_addr_ipv4mapped(&p_dstaddr->ipaddr))
+		return E_PAR;
+
+#endif	/* of #if (API_PROTO == API_PROTO_IPV6) && !defined(DAPI_CFG_IP4MAPPED_ADDR) */
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/*
+	 *  p_dstaddr ã¾ãã¯ p_myaddr ã NULL ãªãã¨ã©ã¼
+	 */
+	if (p_myaddr == NULL || p_dstaddr == NULL)
+		return E_PAR;
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	/*
+	 *  p_dstaddr ã¾ãã¯ p_myaddr ã NULL ã
+	 *  tmout ã TMO_NBLK ãªãã¨ã©ã¼
+	 */
+	if (p_myaddr == NULL || p_dstaddr == NULL || tmout == TMO_NBLK)
+		return E_PAR;
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+	/*
+	 *  CEP ãã­ãã¯ããAPI æ©è½ã³ã¼ãã¨ã¿ã¹ã¯è­å¥å­ãè¨é²ããã
+	 *  ãã§ã«è¨é²ããã¦ããã°ããã³ãã£ã³ã°ä¸­ãªã®ã§ã¨ã©ã¼
+	 */
+	if ((error = tcp_lock_cep(cepid, &cep, TFN_TCP_CON_CEP)) != E_OK)
+		return error;
+
+	/* CEP ã® FSM ãã¯ã­ã¼ãºç¶æ
+ã§ãªããã°ã¨ã©ã¼ã*/
+	if (cep->fsm_state != TCP_FSM_CLOSED) {
+		error = E_OBJ;
+		goto err_ret;
+		}
+	syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_CLOSED)));
+
+	/* ã·ã¼ã±ã³ã¹çªå·ãåæåããã*/
+	if (tcp_iss == 0)
+		tcp_init_iss();
+
+	/* éä¿¡ç«¯ç¹ãåæåããã*/
+	tcp_init_cep(cep);
+
+	/*
+	 *  IP ã¢ãã¬ã¹ãè¨­å®ããã
+	 *  p_myaddr ã NADR (-1) ã§ã¯ãªããèª IP ã¢ãã¬ã¹ã ANY ã§ãªããã°ã
+	 *  æå®ããã IP ã¢ãã¬ã¹ãå²ãå½ã¦ãã
+	 */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4)
+
+	if (p_myaddr != NADR && !IN4_IS_ADDR_ANY(&p_myaddr->ipaddr))
+		in6_make_ipv4mapped(&cep->myaddr.ipaddr, p_myaddr->ipaddr);
+	else
+		in6_make_ipv4mapped(&cep->myaddr.ipaddr, IF_GET_IFNET()->in4_ifaddr.addr);
+
+	in6_make_ipv4mapped(&cep->dstaddr.ipaddr, p_dstaddr->ipaddr);
+	cep->dstaddr.portno = p_dstaddr->portno;
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
+
+	if (p_myaddr != NADR && !IN_IS_ADDR_ANY(&p_myaddr->ipaddr))
+		cep->myaddr.ipaddr = p_myaddr->ipaddr;
+	else {
+		if (IN_ADDRWITHIFP(IF_GET_IFNET(), &cep->myaddr.ipaddr, &p_dstaddr->ipaddr) == NULL) {
+			error = E_PAR;
+			goto err_ret;
+			}
+		}
+
+	cep->dstaddr   = *p_dstaddr;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) && (API_PROTO == API_PROTO_IPV4) */
+
+#if API_PROTO == API_PROTO_IPV4
+
+	/* TCP éä¿¡ç«¯ç¹ã®ãããã¯ã¼ã¯å±¤ãã­ãã³ã«ãè¨­å®ããã*/
+	cep->flags |= TCP_CEP_FLG_IPV4;
+
+#endif	/* of #if API_PROTO == API_PROTO_IPV4 */
+
+	/* éä¿¡ç«¯ç¹ãè¨­å®ããã*/
+	//NET_DEBUG_TCP5("tcp_con_cep3[c=%d,d=%lI.%d,s=%lI.%d]\n",
+	cep->fsm_state = TCP_FSM_SYN_SENT;
+	cep->iss       = tcp_iss;
+	cep->timer[TCP_TIM_KEEP] = TCP_TVAL_KEEP_INIT;
+	tcp_iss += TCP_ISS_INCR() / 2;
+	init_send_seq(cep);
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+	/* ã¿ã¤ã ã¢ã¦ãããã§ãã¯ããã*/
+	if (tmout == TMO_NBLK) {
+		/* ãã³ãã­ãã­ã³ã°ã³ã¼ã« */
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+
+#if API_PROTO == API_PROTO_IPV4
+
+		cep->p_dstaddr4   = p_dstaddr;
+		cep->p_myaddr4    = p_myaddr;
+		cep->p_dstaddr    = NULL;
+		cep->p_myaddr     = NULL;
+
+#else	/* of #if API_PROTO == API_PROTO_IPV4 */
+
+		cep->p_dstaddr4   = NULL;
+		cep->p_myaddr4    = NULL;
+		cep->p_dstaddr    = p_dstaddr;
+		cep->p_myaddr     = p_myaddr;
+
+#endif	/* of #if API_PROTO == API_PROTO_IPV4 */
+
+#else	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+		cep->p_dstaddr    = p_dstaddr;
+		cep->p_myaddr     = p_myaddr;
+
+#endif	/* of #if defined(SUPPORT_INET6) && defined(SUPPORT_INET4) */
+
+		cep->snd_nblk_tfn = TFN_TCP_CON_CEP;
+
+		/* ã³ãã¯ã·ã§ã³ã®éè¨­ããã¹ãããã*/
+		cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+		sig_sem(SEM_TCP_POST_OUTPUT);
+		return E_WBLK;
+		}
+	else {
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+		/*
+		 *  p_myaddr ã NADR (-1) ãã
+		 *  èªãã¼ãçªå·ã TCP_PORTANY ãªããèªåã§å²ãå½ã¦ãã
+		 */
+		if (p_myaddr == NADR || p_myaddr->portno == TCP_PORTANY)
+			tcp_alloc_auto_port(cep);
+		else if ((error = tcp_alloc_port(cep, p_myaddr->portno)) != E_OK)
+			goto err_ret;
+
+		/* ã³ãã¯ã·ã§ã³ã®éè¨­ããã¹ãããã*/
+		cep->flags |= TCP_CEP_FLG_POST_OUTPUT;
+		sig_sem(SEM_TCP_POST_OUTPUT);
+
+		/*
+		 *  ã¤ãã³ãã ESTABLISHED ã«ãªãã¾ã§å¾
+ã¤ã
+		 *  ã¤ãã³ãã CLOSED ã«ãªã£ãå ´åã¯ãä½ããã®ã¨ã©ã¼ãçºçãããã
+		 *  æ¥ç¶è¦æ±ãæå¦ããããã¨ãæå³ãã¦ããã
+		 */
+		error = twai_flg(cep->est_flgid, (TCP_CEP_EVT_CLOSED |
+		                                  TCP_CEP_EVT_ESTABLISHED), TWF_ORW, &flag, tmout);
+		if (error == E_OK) {
+			if (cep->error != E_OK)
+				error = cep->error;
+			else if (cep->fsm_state == TCP_FSM_CLOSED)
+				error = E_CLS;
+			}
+
+		syscall(clr_flg(cep->est_flgid, (FLGPTN)(~TCP_CEP_EVT_ESTABLISHED)));
+
+		if (error != E_OK) {
+			/*
+			 *  éä¿¡ç«¯ç¹ããåä»å£ãè§£æ¾ãã
+			 *  ã¤ãã³ããã©ã°ãã¯ã­ã¼ãºã«è¨­å®ããã
+			 */
+			cep->rep = NULL;
+
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+			cep->rep4 = NULL;
+#endif
+
+			cep->fsm_state = TCP_FSM_CLOSED;
+			syscall(set_flg(cep->est_flgid, TCP_CEP_EVT_CLOSED));
+			}
+
+#ifdef TCP_CFG_NON_BLOCKING
+
+		}
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING */
+
+err_ret:
+	cep->snd_tskid = TA_NULL;
+	cep->snd_tfn   = TFN_TCP_UNDEF;
+	return error;
+	}
+
+#endif	/* of #ifdef __tcp_con_cep */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp4_input.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp4_input.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp4_input.c	(revision 331)
@@ -0,0 +1,106 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ *  udp_reply_no_port -- éä¿¡å
+ã«ãã¼ããå®ç¾©ããã¦ããªããã¨ãéç¥ããã
+ */
+
+void
+UDP_REPLY_NO_PORT (T_NET_BUF *input, uint_t off)
+{
+	T_UDP_HDR	*udph;
+
+	udph = (T_UDP_HDR *)(input->buf + off);
+
+	NET_COUNT_MIB(udp_stats.udpNoPorts, 1);
+
+	/* ã­ã¼ã«ã« IP ã¢ãã¬ã¹ã«å±ãããã¼ã¿ã°ã©ã ã®ã¿ ICMP ã¨ã©ã¼ãéç¥ããã*/
+	if (ntohl(GET_IP4_HDR(input)->dst) == IF_GET_IFNET()->in4_ifaddr.addr) {
+		syslog(LOG_INFO, "[UDP] unexp port: %d.", ntohs(udph->dport));
+
+		icmp_error(ICMP4_UNREACH_PORT, input);
+		/* icmp_error ã§ã¯ããããã¯ã¼ã¯ãããã¡ input ãè¿å´ããªãã®ã§ä¸ã¸æããã*/
+	
+		}
+	syscall(rel_net_buf(input));
+
+	NET_COUNT_UDP(net_count_udp.in_err_packets, 1);
+	NET_COUNT_MIB(udp_stats.udpInErrors, 1);
+	NET_COUNT_MIB(udp_stats.udpNoPorts, 1);
+	}
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp4_subr.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp4_subr.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp4_subr.c	(revision 331)
@@ -0,0 +1,203 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must ceproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef SUPPORT_IGMP
+#define UDP4_IS_ADDR_MULTICAST igmp_is_joined_group
+#else
+#define UDP4_IS_ADDR_MULTICAST IN4_IS_ADDR_MULTICAST
+#endif
+
+#ifdef DHCP_CFG
+#ifdef ETHER_CFG_MULTICAST
+/*
+ *  udp4_is_dstaddr_accept -- UDP ã®ãã¦å
+ã¢ãã¬ã¹ãæ­£ããããã§ãã¯ããã
+ *
+ *    DHCP_CFG ãå®ç¾©ããã¦ããã¨ãã¯ãä»¥ä¸ã®ãã¼ã¿ã°ã©ã ãåä¿¡ããã
+ *
+ *      ã»ãã¦å
+ã¢ãã¬ã¹ããã­ã¼ãã­ã£ã¹ã
+ *      ã»ã­ã¼ã«ã«ã¢ãã¬ã¹ãæªå®ç¾©
+ */
+
+static bool_t
+udp4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_NET_BUF *input)
+{
+	T_IP4_HDR	*ip4h;
+	T_IN4_ADDR	dst;
+	T_IFNET	*ifp = IF_GET_IFNET();
+
+	ip4h = GET_IP4_HDR(input);
+	dst = ntohl(ip4h->dst);
+
+	if (ifp->in4_ifaddr.addr == IPV4_ADDRANY    ||
+		dst == IPV4_ADDR_BROADCAST ||
+		dst == ((ifp->in4_ifaddr.addr & ifp->in4_ifaddr.mask) | ~ifp->in4_ifaddr.mask) ||
+		UDP4_IS_ADDR_MULTICAST(dst))
+		return true;
+	else
+		return inn4_is_dstaddr_accept(myaddr, input);
+	}
+#else
+/*
+ *  udp4_is_dstaddr_accept -- UDP ã®ãã¦å
+ã¢ãã¬ã¹ãæ­£ããããã§ãã¯ããã
+ *
+ *    DHCP_CFG ãå®ç¾©ããã¦ããã¨ãã¯ãä»¥ä¸ã®ãã¼ã¿ã°ã©ã ãåä¿¡ããã
+ *
+ *      ã»ãã¦å
+ã¢ãã¬ã¹ããã­ã¼ãã­ã£ã¹ã
+ *      ã»ã­ã¼ã«ã«ã¢ãã¬ã¹ãæªå®ç¾©
+ */
+
+static bool_t
+udp4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_NET_BUF *input)
+{
+	T_IP4_HDR	*ip4h;
+	T_IFNET	*ifp = IF_GET_IFNET();
+
+	ip4h = GET_IP4_HDR(input);
+
+	if (ifp->in4_ifaddr.addr == IPV4_ADDRANY    ||
+	    ntohl(ip4h->dst) == IPV4_ADDR_BROADCAST ||
+	    ntohl(ip4h->dst) == ((ifp->in4_ifaddr.addr & ifp->in4_ifaddr.mask) | ~ifp->in4_ifaddr.mask))
+		return true;
+	else
+		return inn4_is_dstaddr_accept(myaddr, input);
+	}
+#endif	/* of #ifdef ETHER_CFG_MULTICAST */
+#else
+#ifdef ETHER_CFG_MULTICAST
+
+/*
+ *  udp_dstaddr_accept -- UDP ã®ãã¦å
+ã¢ãã¬ã¹ãæ­£ããããã§ãã¯ããã
+ *
+ *    ä»¥ä¸ã®å ´åããã¼ã¿ã°ã©ã ãåä¿¡ããã
+ *
+ *      ã»ãã¦å
+ã¢ãã¬ã¹ããã­ã¼ãã­ã£ã¹ã
+ */
+
+static bool_t
+udp4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_NET_BUF *input)
+{
+	T_IP4_HDR	*ip4h;
+	T_IN4_ADDR	dst;
+	T_IFNET	*ifp = IF_GET_IFNET();
+
+	ip4h = GET_IP4_HDR(input);
+	dst = ntohl(ip4h->dst);
+
+	if (dst == IPV4_ADDR_BROADCAST ||
+	    dst == ((ifp->in4_ifaddr.addr & ifp->in4_ifaddr.mask) | ~ifp->in4_ifaddr.mask) ||
+		UDP4_IS_ADDR_MULTICAST(dst))
+		return true;
+	else
+		return inn4_is_dstaddr_accept(myaddr, input);
+	}
+
+#else	/* of #ifdef ETHER_CFG_MULTICAST */
+
+/*
+ *  udp4_is_dstaddr_accept -- UDP ã®ãã¦å
+ã¢ãã¬ã¹ãæ­£ããããã§ãã¯ããã
+ *
+ *    ä»¥ä¸ã®å ´åããã¼ã¿ã°ã©ã ãåä¿¡ããã
+ *
+ *      ã»ãã¦å
+ã¢ãã¬ã¹ããã­ã¼ãã­ã£ã¹ã
+ */
+
+static bool_t
+udp4_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_NET_BUF *input)
+{
+	T_IP4_HDR	*ip4h;
+	T_IFNET		*ifp = IF_GET_IFNET();
+
+	ip4h = GET_IP4_HDR(input);
+
+	if (ntohl(ip4h->dst) == IPV4_ADDR_BROADCAST ||
+	    ntohl(ip4h->dst) == ((ifp->in4_ifaddr.addr & ifp->in4_ifaddr.mask) | ~ifp->in4_ifaddr.mask))
+		return true;
+	else
+		return inn4_is_dstaddr_accept(myaddr, input);
+	}
+
+#endif	/* of #ifdef ETHER_CFG_MULTICAST */
+#endif	/* of #ifdef DHCP_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_input.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_input.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_input.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -72,4 +72,5 @@
 #include <sil.h>
 #include <t_syslog.h>
+#include "tinet_cfg.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_ASP */
@@ -79,5 +80,5 @@
 #include <s_services.h>
 #include <t_services.h>
-#include "kernel_id.h"
+#include "tinet_id.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_JSP */
@@ -92,4 +93,5 @@
 #include <net/ppp_ipcp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_count.h>
@@ -97,14 +99,8 @@
 #include <netinet/in.h>
 #include <netinet/in_var.h>
-#include <netinet6/in6.h>
-#include <netinet6/in6_var.h>
 #include <netinet/in_itron.h>
 #include <netinet/ip.h>
 #include <netinet/ip_var.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
 #include <netinet/ip_icmp.h>
-#include <netinet/icmp6.h>
-
 #include <netinet/udp.h>
 #include <netinet/udp_var.h>
@@ -124,256 +120,56 @@
 #endif	/* of #ifdef SUPPORT_MIB */
 
-#if defined(SUPPORT_INET4)
-
-#ifdef DHCP_CFG
-
 /*
- *  udp_dstaddr_accept -- UDP のあて先アドレスが正しいかチェックする。
- *
- *    DHCP_CFG が定義されているときは、以下のデータグラムを受信する。
- *
- *      ・あて先アドレスがブロードキャスト
- *      ・ローカルアドレスが未定義
+ *  IPv6 と IPv4 で引数が異なる関数のコンパイル
  */
 
-static bool_t
-udp_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_IN4_ADDR *dstaddr)
-{
-	T_IFNET	*ifp = IF_GET_IFNET();
+#undef	IN_COPY_TO_HOST
 
-	if (ifp->in_ifaddr.addr == IPV4_ADDRANY ||
-	    ntohl(*dstaddr) == IPV4_ADDR_BROADCAST ||
-	    ntohl(*dstaddr) == ((ifp->in_ifaddr.addr & ifp->in_ifaddr.mask) | ~ifp->in_ifaddr.mask))
-		return true;
-	else
-		return IN_IS_DSTADDR_ACCEPT(myaddr, dstaddr);
-	}
+#if defined(_IP6_CFG) && TNUM_UDP6_CEPID > 0
 
-#elif defined(ETHER_CFG_MULTICAST)
+#define UDP_INPUT		udp6_input
+#define UDP_INPUT_SELECT	udp6_input_select
+#define UDP_REPLY_NO_PORT	udp6_reply_no_port
+#define UDP_FIND_CEP		udp6_find_cep
+#define GET_UDP_CEPID		GET_UDP6_CEPID
+#define T_UDP_CEP		T_UDP6_CEP
+#define API_PROTO		API_PROTO_IPV6
 
-/*
- *  udp_dstaddr_accept -- UDP のあて先アドレスが正しいかチェックする。
- *
- *    以下の場合もデータグラムを受信する。
- *
- *      ・あて先アドレスがブロードキャスト
- */
+#if defined(_IP4_CFG)
+#define IN_COPY_TO_HOST		inn_copy_to_host
+#else
+#define IN_COPY_TO_HOST		IN6_COPY_TO_HOST
+#endif
 
-static bool_t
-udp_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_IN4_ADDR *dstaddr)
-{
-	T_IFNET	*ifp = IF_GET_IFNET();
-	T_IN4_ADDR	dst = ntohl(*dstaddr);
+#include <netinet6/udp6_input.c>
+#include <netinet/udpn_input.c>
 
-	if (dst == IPV4_ADDR_BROADCAST ||
-	    dst == ((ifp->in_ifaddr.addr & ifp->in_ifaddr.mask) | ~ifp->in_ifaddr.mask) ||
-		IN4_IS_ADDR_MULTICAST(dst))
-		return true;
-	else
-		return IN_IS_DSTADDR_ACCEPT(myaddr, dstaddr);
-	}
+#undef	UDP_INPUT
+#undef	UDP_INPUT_SELECT
+#undef	UDP_REPLY_NO_PORT
+#undef	UDP_FIND_CEP
+#undef	GET_UDP_CEPID
+#undef	T_UDP_CEP
+#undef	IN_COPY_TO_HOST
+#undef  API_PROTO
 
-#else	/* of #ifdef DHCP_CFG */
+#endif	/* of #if defined(_IP6_CFG) && TNUM_UDP6_CEPID > 0 */
 
-/*
- *  udp_dstaddr_accept -- UDP のあて先アドレスが正しいかチェックする。
- *
- *    以下の場合もデータグラムを受信する。
- *
- *      ・あて先アドレスがブロードキャスト
- */
+#if defined(_IP4_CFG) && ( (TNUM_UDP4_CEPID > 0) || \
+                          ((TNUM_UDP6_CEPID > 0) && defined(API_CFG_IP4MAPPED_ADDR)))
 
-static bool_t
-udp_is_dstaddr_accept (T_IN4_ADDR *myaddr, T_IN4_ADDR *dstaddr)
-{
-	T_IFNET	*ifp = IF_GET_IFNET();
+#define UDP_INPUT		udp4_input
+#define UDP_INPUT_SELECT	udp4_input_select
+#define UDP_REPLY_NO_PORT	udp4_reply_no_port
+#define UDP_FIND_CEP		udp4_find_cep
+#define GET_UDP_CEPID		GET_UDP4_CEPID
+#define T_UDP_CEP		T_UDP4_CEP
+#define IN_COPY_TO_HOST		IN4_COPY_TO_HOST
+#define API_PROTO		API_PROTO_IPV4
 
-	if (ntohl(*dstaddr) == IPV4_ADDR_BROADCAST ||
-	    ntohl(*dstaddr) == ((ifp->in_ifaddr.addr & ifp->in_ifaddr.mask) | ~ifp->in_ifaddr.mask))
-		return true;
-	else
-		return IN_IS_DSTADDR_ACCEPT(myaddr, dstaddr);
-	}
+#include <netinet/udp4_input.c>
+#include <netinet/udpn_input.c>
 
-#endif	/* of #ifdef DHCP_CFG */
-
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
-
-/*
- *  udp_dstaddr_accept -- UDP のあて先アドレスが正しいかチェックする。
- *
- *    以下の場合もデータグラムを受信する。
- *
- *      ・あて先アドレスがマルチキャスト
- */
-
-static bool_t
-udp_is_dstaddr_accept (T_IN6_ADDR *myaddr, T_IN6_ADDR *dstaddr)
-{
-	if (IN6_IS_ADDR_MULTICAST(dstaddr))
-		return true;
-	else
-		return IN_IS_DSTADDR_ACCEPT(myaddr, dstaddr);
-	}
-
-#endif	/* of #if defined(SUPPORT_INET6) */
-
-/*
- *  udp_input -- UDP の入力関数
- */
-
-uint_t
-udp_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp)
-{
-	T_NET_BUF	*input = *inputp;
-	T_UDP_CEP	*cep;
-	T_UDP_HDR	*udph;
-	T_IP_HDR	*iph;
-	int_t		ix;
-	uint_t		len, hlen, ulen;
-
-	hlen = (uint_t)GET_IF_IP_HDR_SIZE(input);
-
-	NET_COUNT_UDP(net_count_udp.in_octets,  input->len - hlen);
-	NET_COUNT_UDP(net_count_udp.in_packets, 1);
-	NET_COUNT_MIB(udp_stats.udpInDatagrams, 1);
-
-	/* ヘッダ長をチェックする。*/
-	if (input->len < hlen + UDP_HDR_SIZE)
-		goto buf_rel;
-
-	udph = (T_UDP_HDR *)(input->buf + *offp);
-
-	/* データグラム長をチェックする */
-	ulen  = ntohs(udph->ulen);
-	if (ulen != input->len - hlen)
-		goto buf_rel;
-
-	/* 宛先ポートが 0 のデータグラムは破棄する。RFC768 */
-	if (udph->dport == 0)
-		goto buf_rel;
-
-#ifdef UDP_CFG_IN_CHECKSUM
-
-	/* チェックサムをチェックする */
-	if (udph->sum && IN_CKSUM(input, IPPROTO_UDP, *offp, ulen) != 0)
-		goto buf_rel;
-
-#endif	/* of #ifdef UDP_CFG_IN_CHECKSUM */
-
-	iph = GET_IP_HDR(input);
-
-	/* 宛先アドレスとポートをチェックする */
-	for (ix = tmax_udp_ccepid; ix -- > 0; ) {
-		cep = &udp_cep[ix];
-		if (VALID_UDP_CEP(cep) &&
-		    udp_is_dstaddr_accept(&cep->myaddr.ipaddr, &iph->dst) &&
-		    ntohs(udph->dport) == cep->myaddr.portno) {
-			len = (uint_t)(ntohs(udph->ulen) - UDP_HDR_SIZE);
-
-			if (cep->rcv_tskid != TA_NULL) {	/* 非ノンブロッキングコールでペンディング中 */
-				if (psnd_dtq(cep->rcvqid, (intptr_t)input) != E_OK)
-					goto buf_rel;
-				}
-
-#ifdef UDP_CFG_NON_BLOCKING
-
-			else if (cep->rcv_p_dstaddr != NULL) {	/* ノンブロッキングコールでペンディング中 */
-
-				/* p_dstaddr を設定する。*/
-				cep->rcv_p_dstaddr->portno = ntohs(udph->sport);
-				IN_COPY_TO_HOST(&cep->rcv_p_dstaddr->ipaddr, &GET_IP_HDR(input)->src);
-
-				/* データをバッファに移す。*/
-				memcpy(cep->rcv_data, GET_UDP_SDU(input, *offp),
-				       (size_t)(len < cep->rcv_len ? len : cep->rcv_len));
-				syscall(rel_net_buf(input));
-
-				if (IS_PTR_DEFINED(cep->callback))
-
-#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
-					(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_RCV_DAT, (void*)(uint32_t)len);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-					(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_RCV_DAT, (void*)&len);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-				else
-					syslog(LOG_WARNING, "[UDP] no call back, CEP: %d.", GET_UDP_CEPID(cep));
-				cep->rcv_p_dstaddr = NULL;
-				}
-
-#endif	/* of #ifdef UDP_CFG_NON_BLOCKING */
-
-			else if (IS_PTR_DEFINED(cep->callback)) {
-
-				/* コールバック関数を呼び出す。*/
-				cep->cb_netbuf = input;
-
-#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
-				(*cep->callback)(GET_UDP_CEPID(cep), TEV_UDP_RCV_DAT, (void*)(uint32_t)len);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-				(*cep->callback)(GET_UDP_CEPID(cep), TEV_UDP_RCV_DAT, (void*)&len);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-				/*
-				 *  ネットワークバッファがそのままであれば、コールバック関数内で
-				 *  データを読み出さなかったことになるので、捨てる。
-				 */
-				if (cep->cb_netbuf != NULL)
-					syscall(rel_net_buf(cep->cb_netbuf));
-				}
-			else
-				goto buf_rel;
-
-			return IPPROTO_DONE;
-			}
-		}
-
-	NET_COUNT_MIB(udp_stats.udpNoPorts, 1);
-
-#if defined(SUPPORT_INET4)
-
-	/* ローカル IP アドレスに届いたデータグラムのみ ICMP エラーを通知する。*/
-	if (ntohl(iph->dst) == IF_GET_IFNET()->in_ifaddr.addr) {
-		syslog(LOG_INFO, "[UDP] unexp port: %d.", ntohs(udph->dport));
-
-		icmp_error(ICMP4_UNREACH_PORT, input);
-		/* icmp_error では、ネットワークバッファ input を返却しないので下へ抜ける。*/
-		}
-
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
-
-	/* マルチキャストアドレスに届いたデータグラムは ICMP エラーを通知しない。*/
-	if (!IN6_IS_ADDR_MULTICAST(&iph->dst)) {
-		syslog(LOG_INFO, "[UDP] unexp port: %d.", ntohs(udph->dport));
-
-		/* icmp6_error で、ネットワークバッファ input を返却する。*/
-		icmp6_error(input, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0);
-
-		NET_COUNT_UDP(net_count_udp.in_err_packets, 1);
-		NET_COUNT_MIB(udp_stats.udpInErrors, 1);
-		return IPPROTO_DONE;
-		}
-
-#endif	/* of #if defined(SUPPORT_INET6) */
-
-buf_rel:
-	NET_COUNT_UDP(net_count_udp.in_err_packets, 1);
-	NET_COUNT_MIB(udp_stats.udpInErrors, 1);
-	syscall(rel_net_buf(input));
-	return IPPROTO_DONE;
-	}
+#endif	/* of #if defined(_IP4_CFG) && TNUM_UDP4_CEPID > 0 */
 
 #endif	/* of #ifdef SUPPORT_UDP */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_output.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_output.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_output.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -73,4 +73,5 @@
 #include <t_syslog.h>
 #include "kernel_cfg.h"
+#include "tinet_cfg.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_ASP */
@@ -81,4 +82,5 @@
 #include <t_services.h>
 #include "kernel_id.h"
+#include "tinet_id.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_JSP */
@@ -92,9 +94,9 @@
 #include <net/ethernet.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_count.h>
 
 #include <netinet/in.h>
-#include <netinet6/in6.h>
 #include <netinet/in_var.h>
 #include <netinet/in_itron.h>
@@ -102,9 +104,4 @@
 #include <netinet/ip_var.h>
 #include <netinet/ip_icmp.h>
-#include <netinet6/in6_var.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#include <netinet6/nd6.h>
-#include <netinet/icmp6.h>
 #include <netinet/udp.h>
 #include <netinet/udp_var.h>
@@ -115,109 +112,44 @@
 
 /*
- *  関数
- */
-
-static void udp_output (T_UDP_CEP *cep);
-
-/*
- *  UDP 出力タスク
- *  ノンブロッキングコールを組み込んだとき使用する。
- */
-
-static void
-udp_output (T_UDP_CEP *cep)
-{
-	T_NET_BUF	*output;
-	T_UDP_HDR	*udph;
-	ER_UINT		error;
-
-#ifdef UDP_CFG_OUT_CHECKSUM
-	uint16_t	sum;
-#endif	/* of #ifdef UDP_CFG_OUT_CHECKSUM */
-
-	/* IP データグラムを割り当てる。*/
-	if ((error = IN_GET_DATAGRAM(&output, (uint_t)(UDP_HDR_SIZE + cep->snd_len), 0,
-	                             &cep->snd_p_dstaddr->ipaddr,
-	                             &cep->myaddr.ipaddr,
-	                             IPPROTO_UDP, IP_DEFTTL, 
-	                             NBA_SEARCH_ASCENT, TMO_UDP_OUTPUT)) != E_OK) {
-		goto err_ret;
-		}
-
-	/* UDP ヘッダに情報を設定する。*/
-	udph		= GET_UDP_HDR(output, IF_IP_UDP_HDR_OFFSET);
-	udph->sport	= htons(cep->myaddr.portno);
-	udph->dport	= htons(cep->snd_p_dstaddr->portno);
-	udph->ulen	= htons(UDP_HDR_SIZE + cep->snd_len);
-	udph->sum	= 0;
-
-	/* データをコピーする。*/
-	memcpy((void*)GET_UDP_SDU(output, IF_IP_UDP_HDR_OFFSET),
-	       cep->snd_data, (size_t)cep->snd_len);
-
-#ifdef UDP_CFG_OUT_CHECKSUM
-
-	sum = IN_CKSUM(output, IPPROTO_UDP, IF_IP_UDP_HDR_OFFSET,
-	               (uint_t)(UDP_HDR_SIZE + cep->snd_len));
-
-	/* 計算したチェックサムの値が 0 なら 0xffff を入れる。*/
-	if (sum == 0)
-		sum = UINT_C(0xffff);
-	udph->sum = sum;
-
-#endif/* of #ifdef UDP_CFG_OUT_CHECKSUM */
-
-	/* ネットワークバッファ長を調整する。*/
-	output->len = (uint16_t)(IF_IP_UDP_HDR_SIZE + cep->snd_len);
-
-	/* ネットワーク層 (IP) の出力関数を呼び出す。*/
-	if ((error = IP_OUTPUT(output, TMO_UDP_OUTPUT)) != E_OK)
-		goto err_ret;
-
-
-	NET_COUNT_MIB(udp_stats.udpOutDatagrams, 1);
-
-	if (IS_PTR_DEFINED(cep->callback)) {
-
-		if (error == E_OK)
-			error = cep->snd_len;
-
-#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
-		(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_SND_DAT, (void*)error);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-		(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_SND_DAT, (void*)&error);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-		}
-	else
-		syslog(LOG_WARNING, "[UDP] no call back, CEP: %d.", GET_UDP_CEPID(cep));
-	cep->snd_p_dstaddr = NULL;
-	return;
-
-err_ret:
-	NET_COUNT_UDP(net_count_udp.out_err_packets, 1);
-	if (IS_PTR_DEFINED(cep->callback)) {
-
-#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
-		(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_SND_DAT, (void*)E_NOMEM);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-		error = E_NOMEM;
-		(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_SND_DAT, (void*)&error);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-		}
-	else
-		syslog(LOG_WARNING, "[UDP] no call back, CEP: %d.", GET_UDP_CEPID(cep));
-	cep->snd_p_dstaddr = NULL;
-	return;
-	}
+ *  IPv6 と IPv4 で引数が異なる関数のコンパイル
+ */
+
+#undef	IN_GET_DATAGRAM
+
+#if defined(_IP6_CFG) 
+
+#define UDP_OUTPUT		udp6_output
+#define GET_UDP_CEPID		GET_UDP6_CEPID
+#define T_UDP_CEP		T_UDP6_CEP
+#define API_PROTO		API_PROTO_IPV6
+
+#if defined(_IP4_CFG)
+#define	IN_GET_DATAGRAM		inn_get_datagram
+#else
+#define	IN_GET_DATAGRAM		in6_get_datagram
+#endif
+
+#include <netinet/udpn_output.c>
+
+#undef	UDP_OUTPUT
+#undef	GET_UDP_CEPID
+#undef	T_UDP_CEP
+#undef  API_PROTO
+#undef	IN_GET_DATAGRAM
+
+#endif	/* of #if defined(_IP6_CFG)  */
+
+#if defined(_IP4_CFG) && TNUM_UDP4_CEPID > 0
+
+#define UDP_OUTPUT		udp4_output
+#define GET_UDP_CEPID		GET_UDP4_CEPID
+#define T_UDP_CEP		T_UDP4_CEP
+#define API_PROTO		API_PROTO_IPV4
+
+#define	IN_GET_DATAGRAM		in4_get_datagram
+
+#include <netinet/udpn_output.c>
+
+#endif	/* of #if defined(_IP4_CFG) && TNUM_UDP4_CEPID > 0 */
 
 /*
@@ -236,10 +168,10 @@
 
 
-#if defined(SUPPORT_INET6) && !defined(SUPPORT_TCP)
+#if defined(_IP6_CFG) && !defined(SUPPORT_TCP)
 
 	/* IPv6 のステートレス・アドレス自動設定を実行する。*/
 	in6_if_up(IF_GET_IFNET());
 
-#endif	/* of #if defined(SUPPORT_INET6) && !defined(SUPPORT_TCP) */
+#endif	/* of #if defined(_IP6_CFG) && !defined(SUPPORT_TCP) */
 
 	while (true) {
@@ -248,11 +180,28 @@
 		syscall(wai_sem(SEM_UDP_POST_OUTPUT));
 
-		for (ix = tmax_udp_ccepid; ix -- > 0; ) {
-
-			if (udp_cep[ix].flags & UDP_CEP_FLG_POST_OUTPUT) {
-				udp_cep[ix].flags &= ~UDP_CEP_FLG_POST_OUTPUT;
-				udp_output(&udp_cep[ix]);
+#if defined(_IP6_CFG) && TNUM_UDP6_CEPID > 0
+
+		for (ix = tmax_udp6_cepid; ix -- > 0; ) {
+
+			if (udp6_cep[ix].flags & UDP_CEP_FLG_POST_OUTPUT) {
+				udp6_cep[ix].flags &= ~UDP_CEP_FLG_POST_OUTPUT;
+				udp6_output(&udp6_cep[ix]);
 				}
 			}
+
+#endif	/* of #if defined(_IP6_CFG) && TNUM_UDP6_CEPID > 0 */
+
+#if defined(_IP4_CFG) && TNUM_UDP4_CEPID > 0
+
+		for (ix = tmax_udp4_cepid; ix -- > 0; ) {
+
+			if (udp4_cep[ix].flags & UDP_CEP_FLG_POST_OUTPUT) {
+				udp4_cep[ix].flags &= ~UDP_CEP_FLG_POST_OUTPUT;
+				udp4_output(&udp4_cep[ix]);
+				}
+			}
+
+#endif	/* of #if defined(_IP4_CFG) && TNUM_UDP4_CEPID > 0 */
+
 		}
 	}
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_subr.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_subr.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_subr.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (UDP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -71,5 +71,7 @@
 #include <kernel.h>
 #include <sil.h>
+#include <t_syslog.h>
 #include "kernel_cfg.h"
+#include "tinet_cfg.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_ASP */
@@ -80,4 +82,5 @@
 #include <t_services.h>
 #include "kernel_id.h"
+#include "tinet_id.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_JSP */
@@ -91,4 +94,5 @@
 #include <net/ethernet.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_count.h>
@@ -96,5 +100,4 @@
 
 #include <netinet/in.h>
-#include <netinet6/in6.h>
 #include <netinet/in_var.h>
 #include <netinet/in_itron.h>
@@ -102,11 +105,9 @@
 #include <netinet/ip_var.h>
 #include <netinet/ip_icmp.h>
-#include <netinet6/in6_var.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#include <netinet6/nd6.h>
-#include <netinet/icmp6.h>
 #include <netinet/udp.h>
 #include <netinet/udp_var.h>
+#include <netinet/ip_igmp.h>
+
+#include <net/if_var.h>
 
 #ifdef SUPPORT_UDP
@@ -116,61 +117,80 @@
  */
 
+#if (defined(_IP6_CFG) && TNUM_UDP6_CEPID > 0) || (defined(_IP4_CFG) && TNUM_UDP4_CEPID > 0)
+
 static uint16_t udp_port_auto = UDP_PORT_FIRST_AUTO;	/* 自動割り当て番号	*/
 
+#endif	/* of #if (defined(_IP6_CFG) && TNUM_UDP6_CEPID > 0) || (defined(_IP4_CFG) && TNUM_UDP4_CEPID > 0) */
+
 /*
- *  udp_alloc_auto_port -- 自動割り当てポート番号を設定する。
+ *  IPv6 と IPv4 で引数が異なる関数のコンパイル
  */
 
-ER
-udp_alloc_auto_port (T_UDP_CEP *cep)
-{
-	int_t	ix;
-	uint16_t	portno, portno_start;
+#if defined(_IP6_CFG) && TNUM_UDP6_CEPID > 0
 
-	portno_start = udp_port_auto;
-	do {
-		portno = udp_port_auto ++;
-		if (udp_port_auto > UDP_PORT_LAST_AUTO)
-			udp_port_auto = UDP_PORT_FIRST_AUTO;
+#if defined(_IP4_CFG) && defined(API_CFG_IP4MAPPED_ADDR)
 
-		syscall(wai_sem(SEM_UDP_CEP));
-		for (ix = tmax_udp_ccepid; ix -- > 0; ) {
-			if (VALID_UDP_CEP(&udp_cep[ix]) && udp_cep[ix].myaddr.portno == portno) {
-				portno = UDP_PORTANY;
-				break;
-				}
-			}
+#define UDP_IS_DSTADDR_ACCEPT	udpn_is_dstaddr_accept
 
-		if (portno != UDP_PORTANY) {
-			cep->myaddr.portno = portno;
-			syscall(sig_sem(SEM_UDP_CEP));
-			return E_OK;
-			}
-		syscall(sig_sem(SEM_UDP_CEP));
+#else	/* of #if defined(_IP4_CFG) */
 
-		} while (portno_start != udp_port_auto);
+#define UDP_IS_DSTADDR_ACCEPT	udp6_is_dstaddr_accept
 
-	return E_NOID;
-	}
+#endif	/* of #if defined(_IP4_CFG) */
 
-/*
- *  udp_alloc_port -- 指定されたポート番号を設定する。
- */
+#define UDP_SEND_DATA		udp6_send_data
+#define UDP_CAN_SND		udp6_can_snd
+#define UDP_CAN_RCV		udp6_can_rcv
+#define UDP_ALLOC_AUTO_PORT	udp6_alloc_auto_port
+#define UDP_ALLOC_PORT		udp6_alloc_port
+#define UDP_FIND_CEP		udp6_find_cep
+#define UDP_NOTIFY		udp6_notify
+#define TMAX_UDP_CEPID		tmax_udp6_cepid
+#define UDP_CEP			udp6_cep
+#define T_UDP_CEP		T_UDP6_CEP
+#define T_IPEP			T_IPV6EP
+#define API_PROTO		API_PROTO_IPV6
 
-ER
-udp_alloc_port (T_UDP_CEP *cep, uint16_t portno)
-{
-	int_t	ix;
+#include <netinet6/udp6_subr.c>
+#include <netinet/udpn_subr.c>
 
-	syscall(wai_sem(SEM_UDP_CEP));
-	for (ix = tmax_udp_ccepid; ix -- > 0; )
-		if (VALID_UDP_CEP(&udp_cep[ix]) && udp_cep[ix].myaddr.portno == portno) {
-			syscall(sig_sem(SEM_UDP_CEP));
-			return E_PAR;
-			}
-	cep->myaddr.portno = portno;
-	syscall(sig_sem(SEM_UDP_CEP));
-	return E_OK;
-	}
+#undef	UDP_SEND_DATA
+#undef	UDP_CAN_SND
+#undef	UDP_CAN_RCV
+#undef	UDP_ALLOC_AUTO_PORT
+#undef	UDP_ALLOC_PORT
+#undef	UDP_FIND_CEP
+#undef	UDP_NOTIFY
+#undef	UDP_IS_DSTADDR_ACCEPT
+#undef	TMAX_UDP_CEPID
+#undef	UDP_CEP
+#undef	T_UDP_CEP
+#undef  T_IPEP
+#undef  API_PROTO
+
+#endif	/* of #if defined(_IP6_CFG) && TNUM_UDP6_CEPID > 0 */
+
+#if defined(_IP4_CFG) && ( (TNUM_UDP4_CEPID > 0) || \
+                          ((TNUM_UDP6_CEPID > 0) && defined(API_CFG_IP4MAPPED_ADDR)))
+
+#define UDP_IS_DSTADDR_ACCEPT	udp4_is_dstaddr_accept
+
+#define UDP_SEND_DATA		udp4_send_data
+#define UDP_CAN_SND		udp4_can_snd
+#define UDP_CAN_RCV		udp4_can_rcv
+#define UDP_ALLOC_AUTO_PORT	udp4_alloc_auto_port
+#define UDP_ALLOC_PORT		udp4_alloc_port
+#define UDP_FIND_CEP		udp4_find_cep
+#define UDP_NOTIFY		udp4_notify
+#define TMAX_UDP_CEPID		tmax_udp4_cepid
+#define T_UDP_CEP		T_UDP4_CEP
+#define UDP_CEP			udp4_cep
+#define T_IPEP			T_IPV4EP
+#define API_PROTO		API_PROTO_IPV4
+
+#include <netinet/udp4_subr.c>
+#include <netinet/udpn_subr.c>
+
+#endif	/* of #if defined(_IP4_CFG) && TNUM_UDP4_CEPID > 0 */
 
 #endif	/* of #ifdef SUPPORT_UDP */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_usrreq.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_usrreq.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_usrreq.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (UDP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -78,4 +78,5 @@
 #include <kernel.h>
 #include <sil.h>
+#include "tinet_cfg.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_ASP */
@@ -85,5 +86,5 @@
 #include <s_services.h>
 #include <t_services.h>
-#include "kernel_id.h"
+#include "tinet_id.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_JSP */
@@ -97,4 +98,5 @@
 #include <net/ethernet.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_count.h>
@@ -102,5 +104,4 @@
 
 #include <netinet/in.h>
-#include <netinet6/in6.h>
 #include <netinet/in_var.h>
 #include <netinet/in_itron.h>
@@ -108,33 +109,9 @@
 #include <netinet/ip_var.h>
 #include <netinet/ip_icmp.h>
-#include <netinet6/in6_var.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#include <netinet6/nd6.h>
-#include <netinet/icmp6.h>
 #include <netinet/udp.h>
 #include <netinet/udp_var.h>
+#include <netinet/ip_igmp.h>
 
 #ifdef SUPPORT_UDP
-
-/*
- *  IPv4 と IPv6 の切り替えマクロ
- */
-
-#if defined(SUPPORT_INET4)
-
-#define UDP_CRE_CEP	udp_cre_cep
-#define UDP_SND_DAT	udp_snd_dat
-#define UDP_RCV_DAT	udp_rcv_dat
-
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
-
-#define UDP_CRE_CEP	udp6_cre_cep
-#define UDP_SND_DAT	udp6_snd_dat
-#define UDP_RCV_DAT	udp6_rcv_dat
-
-#endif	/* of #if defined(SUPPORT_INET6) */
 
 /*
@@ -158,609 +135,137 @@
 #endif	/* of #ifndef UDP_CFG_LIBRARY */
 
-#ifdef __udp_send_data
-
-/*
- *  udp_send_data -- パケット送信の主要部
- */
-
-ER_UINT
-udp_send_data (T_UDP_CEP *cep, T_IPEP *p_dstaddr, void *data, int_t len, TMO tmout)
-{
-	T_NET_BUF	*output;
-	T_UDP_HDR	*udph;
-	SYSTIM		before, after;
-	ER		error = E_OK;
-
-#ifdef UDP_CFG_OUT_CHECKSUM
-	uint16_t	sum;
-#endif	/* of #ifdef UDP_CFG_OUT_CHECKSUM */
-
-	NET_COUNT_UDP(net_count_udp.out_octets,  len);
-	NET_COUNT_UDP(net_count_udp.out_packets, 1);
-
-	/* IP データグラム割り当ての時間を tmout から減ずる。*/
-	if (!(tmout == TMO_POL || tmout == TMO_FEVR))
-		syscall(get_tim(&before));
-
-	/* IP データグラムを割り当てる。*/
-	if ((error = IN_GET_DATAGRAM(&output, (uint_t)(UDP_HDR_SIZE + len), 0,
-	                             &p_dstaddr->ipaddr,
-	                             &cep->myaddr.ipaddr,
-	                             IPPROTO_UDP, IP_DEFTTL, 
-	                             NBA_SEARCH_ASCENT, tmout)) != E_OK)
-		goto err_ret;
-
-	/* IP データグラム割り当ての時間を tmout から減ずる。*/
-	if (!(tmout == TMO_POL || tmout == TMO_FEVR)) {
-		syscall(get_tim(&after));
-		if (after - before > tmout) {
-			syscall(rel_net_buf(output));
-			error = E_TMOUT;
-			goto err_ret;
-			}
-		tmout -= (TMO)(after - before);
-		}
-
-	/* UDP ヘッダに情報を設定する。*/
-	udph		= GET_UDP_HDR(output, IF_IP_UDP_HDR_OFFSET);
-	udph->sport	= htons(cep->myaddr.portno);
-	udph->dport	= htons(p_dstaddr->portno);
-	udph->ulen	= htons(UDP_HDR_SIZE + len);
-	udph->sum	= 0;
-
-	/* データをコピーする。*/
-	memcpy((void*)GET_UDP_SDU(output, IF_IP_UDP_HDR_OFFSET), data, (size_t)len);
-
-#ifdef UDP_CFG_OUT_CHECKSUM
-
-	sum = IN_CKSUM(output, IPPROTO_UDP, IF_IP_UDP_HDR_OFFSET, (uint_t)(UDP_HDR_SIZE + len));
-
-	/* 計算したチェックサムの値が 0 なら 0xffff を入れる。*/
-	if (sum == 0)
-		sum = 0xffff;
-	udph->sum = sum;
-
-#endif	/* of #ifdef UDP_CFG_OUT_CHECKSUM */
-
-	/* ネットワークバッファ長を調整する。*/
-	output->len = (uint16_t)(IF_IP_UDP_HDR_SIZE + len);
-
-	/* ネットワーク層 (IP) の出力関数を呼び出す。*/
-	if ((error = IP_OUTPUT(output, tmout)) == E_OK) {
-		NET_COUNT_MIB(udp_stats.udpOutDatagrams, 1);
-		cep->snd_tskid = TA_NULL;
-		return len;
-		}
-
-err_ret:
-	NET_COUNT_UDP(net_count_udp.out_err_packets, 1);
-	cep->snd_tskid = TA_NULL;
-	return error;
-	}
-
-#endif	/* of #ifdef __udp_send_data */
-
-/*
- *  udp_cre_cep -- UDP 通信端点の生成【拡張機能】
- */
-
-#ifdef __udp_cre_cep
-
-#ifdef UDP_CFG_EXTENTIONS
-
-ER
-UDP_CRE_CEP (ID cepid, T_UDP_CCEP *pk_ccep)
-{
-	T_UDP_CEP	*cep;
-	ER		error;
-
-	/* UDP 通信端点 ID をチェックする。*/
-	if (!VALID_UDP_CEPID(cepid))
-		return E_ID;
-
-	/* pk_ccep が NULL ならエラー */
-	if (pk_ccep == NULL)
-		return E_PAR;
-
-	/* UDP 通信端点を得る。*/
-	cep = GET_UDP_CEP(cepid);
-
-	/* UDP 通信端点をチェックする。*/
-	if (VALID_UDP_CEP(cep))
-		return E_OBJ;
-
-	/* UDP 通信端点が、動的生成用でなければエラー */
-	if (!DYNAMIC_UDP_CEP(cep))
-		return E_ID;
-
-	/* 通信端点をロックする。*/
-	syscall(wai_sem(cep->semid_lock));
-
-	/*
-	 * UDP 通信端点をチェックする。生成済みであればエラー
-	 */
-	if (VALID_UDP_CEP(cep))
-		error = E_OBJ;
-	else {
-
-		/*
-		 *  自ポート番号が UDP_PORTANY なら、自動で割り当てる。
-		 */
-		if (pk_ccep->myaddr.portno == UDP_PORTANY)
-			error = udp_alloc_auto_port(cep);
-		else 
-			error = udp_alloc_port(cep, pk_ccep->myaddr.portno);
-		
-                if (error == E_OK) {
-
-			/* UDP 通信端点生成情報をコピーする。*/
-			cep->cepatr        = pk_ccep->cepatr;			/* 通信端点属性		*/
-			cep->myaddr.ipaddr = pk_ccep->myaddr.ipaddr;		/* 自分のアドレス	*/
-			cep->callback      = (void*)pk_ccep->callback;		/* コールバック		*/
-
-			/* UDP 通信端点を生成済みにする。*/
-			cep->flags |= UDP_CEP_FLG_VALID;
-			}
-		}
-
-	/* 通信端点のロックを解除する。*/
-	syscall(sig_sem(cep->semid_lock));
-
-	return error;
-	}
-
-#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
-
-#endif	/* of #ifdef __udp_cre_cep */
-
-/*
- *  udp_del_cep -- UDP 通信端点の削除【拡張機能】
- */
-
-#ifdef __udp_del_cep
-
-#ifdef UDP_CFG_EXTENTIONS
-
-ER
-udp_del_cep (ID cepid)
-{
-	T_UDP_CEP	*cep;
-	ER		error;
-
-	/* UDP 通信端点 ID をチェックする。*/
-	if (!VALID_UDP_CEPID(cepid))
-		return E_ID;
-
-	/* UDP 通信端点を得る。*/
-	cep = GET_UDP_CEP(cepid);
-
-	/* UDP 通信端点をチェックする。*/
-	if (!VALID_UDP_CEP(cep))
-		return E_NOEXS;
-
-	/* UDP 通信端点が、動的生成用でなければエラー */
-	if (!DYNAMIC_UDP_CEP(cep))
-		return E_ID;
-
-	/* 通信端点をロックする。*/
-	syscall(wai_sem(cep->semid_lock));
-
-	/*
-	 * UDP 通信端点をチェックする。未生成の場合はエラー
-	 * ・未生成。
-	 */
-	if (!VALID_UDP_CEP(cep))
-		error = E_NOEXS;
-	else {
-		udp_can_snd(cep, E_DLT);
-		udp_can_rcv(cep, E_DLT);
-
-		/* UDP 通信端点を未生成にする。*/
-		cep->flags &= ~UDP_CEP_FLG_VALID;
-		error = E_OK;
-		}
-
-	/* 通信端点のロックを解除する。*/
-	syscall(sig_sem(cep->semid_lock));
-
-	return error;
-	}
-
-#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
-
-#endif	/* of #ifdef __udp_del_cep */
+/*
+ *  IPv6 と IPv4 で引数が異なる関数のコンパイル
+ */
+
+#undef	IN_GET_DATAGRAM
+#undef	IN_COPY_TO_HOST
+
+#if defined(SUPPORT_INET6) && TNUM_UDP6_CEPID > 0
+
+#define UDP_CANCEL_CEP		udp6_cancel_cep
+#define UDP_DELETE_CEP		udp6_delete_cep
+#define UDP_SET_OPTION		udp6_set_option
+#define UDP_GET_OPTION		udp6_get_option
+#define UDP_CRE_CEP		udp6_cre_cep
+#define UDP_DEL_CEP		udp6_del_cep
+#define UDP_SET_OPT		udp6_set_opt
+#define UDP_GET_OPT		udp6_get_opt
+#define UDP_SND_DAT		udp6_snd_dat
+#define UDP_RCV_DAT		udp6_rcv_dat
+#define UDP_CAN_SND		udp6_can_snd
+#define UDP_CAN_RCV		udp6_can_rcv
+#define UDP_ALLOC_AUTO_PORT	udp6_alloc_auto_port
+#define UDP_ALLOC_PORT		udp6_alloc_port
+#define UDP_SEND_DATA		udp6_send_data
+#define VALID_UDP_CEPID		VALID_UDP6_CEPID
+#define GET_UDP_CEP		GET_UDP6_CEP
+#define GET_UDP_CEPID		GET_UDP6_CEPID
+#define T_UDP_CEP		T_UDP6_CEP
+#define T_UDPN_CCEP		T_UDP6_CCEP
+#define T_IPEP			T_IPV6EP
+#define API_PROTO		API_PROTO_IPV6
+
+#if defined(_IP4_CFG)
+#define	IN_GET_DATAGRAM		inn_get_datagram
+#define IN_COPY_TO_HOST		inn_copy_to_host
+#else
+#define	IN_GET_DATAGRAM		in6_get_datagram
+#define IN_COPY_TO_HOST		IN6_COPY_TO_HOST
+#endif
+
+#include <netinet/udpn_usrreq.c>
+
+#undef	UDP_CANCEL_CEP
+#undef	UDP_DELETE_CEP
+#undef	UDP_SET_OPTION
+#undef	UDP_GET_OPTION
+#undef	UDP_CRE_CEP
+#undef	UDP_DEL_CEP
+#undef	UDP_SET_OPT
+#undef	UDP_GET_OPT
+#undef	UDP_SND_DAT
+#undef	UDP_RCV_DAT
+#undef	UDP_CAN_SND
+#undef	UDP_CAN_RCV
+#undef	UDP_ALLOC_AUTO_PORT
+#undef	UDP_ALLOC_PORT
+#undef	UDP_SEND_DATA
+#undef	VALID_UDP_CEPID
+#undef	GET_UDP_CEP
+#undef	GET_UDP_CEPID
+#undef	T_UDP_CEP
+#undef	T_UDPN_CCEP
+#undef  T_IPEP
+#undef  API_PROTO
+#undef	IN_GET_DATAGRAM
+#undef	IN_COPY_TO_HOST
+
+#endif	/* of #if defined(SUPPORT_INET6) && TNUM_UDP6_CEPID > 0 */
+
+#if defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0
+
+#define UDP_CANCEL_CEP		udp4_cancel_cep
+#define UDP_DELETE_CEP		udp4_delete_cep
+#define UDP_SET_OPTION		udp4_set_option
+#define UDP_GET_OPTION		udp4_get_option
+#define UDP_CRE_CEP		udp_cre_cep
+#define UDP_DEL_CEP		udp_del_cep
+#define UDP_SET_OPT		udp_set_opt
+#define UDP_GET_OPT		udp_get_opt
+#define UDP_SND_DAT		udp_snd_dat
+#define UDP_RCV_DAT		udp_rcv_dat
+#define UDP_CAN_SND		udp4_can_snd
+#define UDP_CAN_RCV		udp4_can_rcv
+#define UDP_ALLOC_AUTO_PORT	udp4_alloc_auto_port
+#define UDP_ALLOC_PORT		udp4_alloc_port
+#define UDP_SEND_DATA		udp4_send_data
+#define VALID_UDP_CEPID		VALID_UDP4_CEPID
+#define GET_UDP_CEP		GET_UDP4_CEP
+#define GET_UDP_CEPID		GET_UDP4_CEPID
+#define T_UDP_CEP		T_UDP4_CEP
+#define T_UDPN_CCEP		T_UDP_CCEP
+#define T_IPEP			T_IPV4EP
+#define API_PROTO		API_PROTO_IPV4
+
+#define IN_COPY_TO_HOST		IN4_COPY_TO_HOST
+#define	IN_GET_DATAGRAM		in4_get_datagram
+
+#include <netinet/udpn_usrreq.c>
+
+#endif	/* of #if defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0 */
+
+#if defined(SUPPORT_INET6) && (defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0)
+
+/*
+ *  udp_can_cep -- ペンディングしている処理のキャンセル【標準機能】
+ */
 
 #ifdef __udp_can_cep
-
-/*
- *  udp_can_cep -- ペンディングしている処理のキャンセル【標準機能】
- */
 
 ER
 udp_can_cep (ID cepid, FN fncd)
 {
-	T_UDP_CEP	*cep;
-	ER		error = E_OK, snd_err, rcv_err;
-
-	/* API 機能コードをチェックする。*/
-	if (!VALID_TFN_UDP_CAN(fncd))
-		return E_PAR;
-
-	/* UDP 通信端点 ID をチェックする。*/
-	if (!VALID_UDP_CEPID(cepid))
+	/* IPv6 用の UDP 通信端点 ID をチェックする。*/
+	if (VALID_UDP6_CEPID(cepid)) {
+
+		/* UDP 通信端点を得てメイン関数を呼び出す。*/
+		return udp6_cancel_cep(GET_UDP6_CEP(cepid), fncd);
+		}
+
+	/* IPv4 用の UDP 通信端点 ID をチェックする。*/
+	else if (VALID_UDP4_CEPID(cepid)) {
+
+		/* UDP 通信端点を得てメイン関数を呼び出す。*/
+		return udp4_cancel_cep(GET_UDP4_CEP(cepid), fncd);
+		}
+
+	else
 		return E_ID;
-
-	/* UDP 通信端点を得る。*/
-	cep = GET_UDP_CEP(cepid);
-
-	/* UDP 通信端点をチェックする。*/
-	if (!VALID_UDP_CEP(cep))
-		return E_NOEXS;
-
-	/* 通信端点をロックする。*/
-	syscall(wai_sem(cep->semid_lock));
-
-	if (fncd == TFN_UDP_ALL) {	/* TFN_UDP_ALL の処理 */
-
-		snd_err = udp_can_snd(cep, E_RLWAI);
-		rcv_err = udp_can_rcv(cep, E_RLWAI);
-
-		/*
-		 *  snd_err と rcv_err のどちらも EV_NOPND
-		 *  なら、ペンディングしていないのでエラー
-		 */
-		if (snd_err == EV_NOPND && rcv_err == EV_NOPND)
-			error = E_OBJ;
-		else {
-			if (snd_err == EV_NOPND)
-				snd_err = E_OK;
-			if (rcv_err == EV_NOPND)
-				rcv_err = E_OK;
-
-			if (snd_err != E_OK)
-				error = snd_err;
-			else if (rcv_err != E_OK)
-				error = rcv_err;
-			}
-		}
-	else if (fncd == TFN_UDP_SND_DAT) {	/* 送信処理のキャンセル */
-		if ((error = udp_can_snd(cep, E_RLWAI)) == EV_NOPND)
-			error = E_OBJ;
-		}
-	else if (fncd == TFN_UDP_RCV_DAT) {	/* 受信処理のキャンセル */
-		if ((error = udp_can_rcv(cep, E_RLWAI)) == EV_NOPND)
-			error = E_OBJ;
-		}
-	else
-		error = E_PAR;
-
-	/* 通信端点をロックを解除する。*/
-	syscall(sig_sem(cep->semid_lock));
-
-	return error;
 	}
 
 #endif	/* of #ifdef __udp_can_cep */
 
-/*
- *  udp_set_opt -- UDP 通信端点オプションの設定【拡張機能】
- *
- *  注意: 設定可能な UDP 通信端点オプションは無いため、E_PAR が返される。
- */
-
-#ifdef __udp_set_opt
-
-#ifdef UDP_CFG_EXTENTIONS
-
-ER
-udp_set_opt (ID cepid, int_t optname, void *optval, int_t optlen)
-{
-	T_UDP_CEP	*cep;
-
-	/* UDP 通信端点 ID をチェックする。*/
-	if (!VALID_UDP_CEPID(cepid))
-		return E_ID;
-
-	/* UDP 通信端点を得る。*/
-	cep = GET_UDP_CEP(cepid);
-
-	/* UDP 通信端点をチェックする。*/
-	if (!VALID_UDP_CEP(cep))
-		return E_NOEXS;
-
-	return E_OK/*E_PAR*/;
-	}
-
-#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
-
-#endif	/* of #ifdef __udp_set_opt */
-
-/*
- *  udp_get_opt -- UDP 通信端点オプションの設定【拡張機能】
- *
- *  注意: 設定可能な UDP 通信端点オプションは無いため、E_PAR が返される。
- */
-
-#ifdef __udp_get_opt
-
-#ifdef UDP_CFG_EXTENTIONS
-
-ER
-udp_get_opt (ID cepid, int_t optname, void *optval, int_t optlen)
-{
-	T_UDP_CEP	*cep;
-
-	/* UDP 通信端点 ID をチェックする。*/
-	if (!VALID_UDP_CEPID(cepid))
-		return E_ID;
-
-	/* UDP 通信端点を得る。*/
-	cep = GET_UDP_CEP(cepid);
-
-	/* UDP 通信端点をチェックする。*/
-	if (!VALID_UDP_CEP(cep))
-		return E_NOEXS;
-
-	return E_OK/*E_PAR*/;
-	}
-
-#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
-
-#endif	/* of #ifdef __udp_get_opt */
-
-#ifdef UDP_CFG_NON_BLOCKING
-
-#include "udp_usrreq_nblk.c"
-
-#else	/* of #ifdef UDP_CFG_NON_BLOCKING */
-
-#ifdef __udp_can_snd
-
-/*
- *  udp_can_snd -- ペンディングしている送信のキャンセル
- */
-
-ER
-udp_can_snd (T_UDP_CEP *cep, ER error)
-{
-	if (cep->snd_tskid != TA_NULL) {	/* 非ノンブロッキングコールでペンディング中 */
-
-#ifdef UDP_CFG_EXTENTIONS
-
-		/* 待ち中に発生したエラー情報を設定する。*/
-		cep->error = error;
-
-#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
-
-		error = rel_wai(cep->snd_tskid);
-		cep->snd_tskid = TA_NULL;
-		}
-	else					/* どちらでもないならペンディングしていない */
-		error = EV_NOPND;
-
-	return error;
-	}
-
-#endif	/* of #ifdef __udp_can_snd */
-
-#ifdef __udp_can_rcv
-
-/*
- *  udp_can_rcv -- ペンディングしている受信のキャンセル
- */
-
-ER
-udp_can_rcv (T_UDP_CEP *cep, ER error)
-{
-	if (cep->rcv_tskid != TA_NULL) {	/* 非ノンブロッキングコールでペンディング中 */
-
-#ifdef UDP_CFG_EXTENTIONS
-
-		/* 待ち中に発生したエラー情報を設定する。*/
-		cep->error = error;
-
-#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
-
-		error = rel_wai(cep->rcv_tskid);
-		cep->rcv_tskid = TA_NULL;
-		}
-	else					/* どちらでもないならペンディングしていない */
-		error = EV_NOPND;
-
-	return error;
-	}
-
-#endif	/* of #ifdef __udp_can_rcv */
-
-#ifdef __udp_snd_dat
-
-/*
- *  udp_snd_dat -- パケットの送信【標準機能】
- */
-
-ER_UINT
-UDP_SND_DAT (ID cepid, T_IPEP *p_dstaddr, void *data, int_t len, TMO tmout)
-{
-	T_UDP_CEP	*cep;
-	ER		error;
-
-	/* p_dstaddr または data が NULL か、tmout が TMO_NBLK ならエラー */
-	if (p_dstaddr == NULL || data == NULL || tmout == TMO_NBLK)
-		return E_PAR;
-
-	/* データ長をチェックする。*/
-	if (len < 0 || len + IP_HDR_SIZE + UDP_HDR_SIZE > IF_MTU)
-		return E_PAR;
-
-	/* UDP 通信端点 ID をチェックする。*/
-	if (!VALID_UDP_CEPID(cepid))
-		return E_ID;
-
-	/* UDP 通信端点を得る。*/
-	cep = GET_UDP_CEP(cepid);
-
-	/* UDP 通信端点をチェックする。*/
-	if (!VALID_UDP_CEP(cep))
-		return E_NOEXS;
-
-	/*
-	 *  自ポート番号が UDP_PORTANY なら、自動で割り当てる。
-	 */
-	if (cep->myaddr.portno == UDP_PORTANY) {
-		if ((error = udp_alloc_auto_port(cep)) != E_OK)
-			return error;
-		}
-	
-	/* 通信端点をロックする。*/
-	syscall(wai_sem(cep->semid_lock));
-
-	if (cep->snd_tskid != TA_NULL) {
-
-		/* 非ノンブロッキングコールでペンディング中 */
-		error = E_QOVR;
-
-		/* 通信端点をロックを解除する。*/
-		syscall(sig_sem(cep->semid_lock));
-		}
-	else {
-		/* 現在のタスク識別子を記録する。*/
-		get_tid(&(cep->snd_tskid));
-
-#ifdef UDP_CFG_EXTENTIONS
-
-		/* 待ち中に発生したエラー情報をリセットする。*/
-		cep->error = E_OK;
-
-#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
-
-		/* 通信端点をロックを解除する。*/
-		syscall(sig_sem(cep->semid_lock));
-
-		/* パケットを送信する。*/
-		error = udp_send_data(cep, p_dstaddr, data, len, tmout);
-
-#ifdef UDP_CFG_EXTENTIONS
-
-		/* 待ち中に発生したエラー情報を返す。*/
-		if (error == E_RLWAI)
-			error = cep->error;
-
-#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
-		}
-
-	return error;
-	}
-
-#endif	/* of #ifdef __udp_snd_dat */
-
-#ifdef __udp_rcv_dat
-
-/*
- *  udp_rcv_dat -- パケットの受信【標準機能】
- */
-
-ER_UINT
-UDP_RCV_DAT (ID cepid, T_IPEP *p_dstaddr, void *data, int_t len, TMO tmout)
-{
-	T_NET_BUF	*input;
-	T_UDP_CEP	*cep;
-	T_UDP_HDR	*udph;
-	ER_UINT		error;
-	uint_t		ulen, uhoff;
-
-	/* p_dstaddr または data が NULL 、len < 0 か、tmout が TMO_NBLK ならエラー */
-	if (p_dstaddr == NULL || data == NULL || len < 0 || tmout == TMO_NBLK)
-		return E_PAR;
-
-	/* UDP 通信端点 ID をチェックする。*/
-	if (!VALID_UDP_CEPID(cepid))
-		return E_ID;
-
-	/* UDP 通信端点を得る。*/
-	cep = GET_UDP_CEP(cepid);
-
-	/* UDP 通信端点をチェックする。*/
-	if (!VALID_UDP_CEP(cep))
-		return E_NOEXS;
-
-	/* 通信端点をロックする。*/
-	syscall(wai_sem(cep->semid_lock));
-
-	if (cep->rcv_tskid != TA_NULL) {
-
-		/* 非ノンブロッキングコールでペンディング中 */
-		error = E_QOVR;
-
-		/* 通信端点をロックを解除する。*/
-		syscall(sig_sem(cep->semid_lock));
-		}
-	else {
-
-		/* 現在のタスク識別子を記録する。*/
-		get_tid(&(cep->rcv_tskid));
-
-#ifdef UDP_CFG_EXTENTIONS
-
-		/* 待ち中に発生したエラー情報をリセットする。*/
-		cep->error = E_OK;
-
-#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
-
-		/* 通信端点をロックを解除する。*/
-		syscall(sig_sem(cep->semid_lock));
-
-		/* 入力があるまで待つ。*/
-		if (cep->cb_netbuf != NULL) {
-
-			/*
-			 *  ここにくる場合は、コールバック関数の中から
-			 *  udp_rcv_dat を呼び出していることになり、
-			 *  すでに入力済みである。
-			 */
-			input = cep->cb_netbuf;
-			cep->cb_netbuf = NULL;
-			}
-		else if ((error = trcv_dtq(cep->rcvqid, (intptr_t*)&input, tmout)) != E_OK) {
-
-#ifdef UDP_CFG_EXTENTIONS
-
-			/* 待ち中に発生したエラー情報を返す。*/
-			if (error == E_RLWAI)
-				error = cep->error;
-
-#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
-
-			cep->rcv_tskid = TA_NULL;
-			return error;
-			}
-
-		/* p_dstaddr を設定する。*/
-		uhoff = (uint_t)GET_UDP_HDR_OFFSET(input);
-		udph = GET_UDP_HDR(input, uhoff);
-		p_dstaddr->portno = ntohs(udph->sport);
-		IN_COPY_TO_HOST(&p_dstaddr->ipaddr, &GET_IP_HDR(input)->src);
-
-		/* データをバッファに移す。*/
-		ulen = ntohs(udph->ulen);
-		if (ulen - UDP_HDR_SIZE > len)
-			error = E_BOVR;
-		else {
-			len   =    (uint_t)(ulen - UDP_HDR_SIZE);
-			error = (ER_UINT)(ulen - UDP_HDR_SIZE);
-			}
-
-		memcpy(data, GET_UDP_SDU(input, uhoff), (size_t)len);
-
-		syscall(rel_net_buf(input));
-
-		cep->rcv_tskid = TA_NULL;
-		}
-
-	return error;
-	}
-
-#endif	/* of #ifdef __udp_rcv_dat */
-
-#endif	/* of #ifdef UDP_CFG_NON_BLOCKING */
+#endif	/* of #if defined(SUPPORT_INET6) && (defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0) */
 
 #endif	/* of #ifdef SUPPORT_UDP */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_usrreq_nblk.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_usrreq_nblk.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_usrreq_nblk.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (UDP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -75,4 +75,5 @@
 #include <sil.h>
 #include "kernel_cfg.h"
+#include "tinet_cfg.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_ASP */
@@ -83,4 +84,5 @@
 #include <t_services.h>
 #include "kernel_id.h"
+#include "tinet_id.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_JSP */
@@ -94,4 +96,5 @@
 #include <net/ethernet.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_count.h>
@@ -99,5 +102,4 @@
 
 #include <netinet/in.h>
-#include <netinet6/in6.h>
 #include <netinet/in_var.h>
 #include <netinet/in_itron.h>
@@ -105,31 +107,8 @@
 #include <netinet/ip_var.h>
 #include <netinet/ip_icmp.h>
-#include <netinet6/in6_var.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#include <netinet6/nd6.h>
-#include <netinet/icmp6.h>
 #include <netinet/udp.h>
 #include <netinet/udp_var.h>
 
 #ifdef SUPPORT_UDP
-
-/*
- *  IPv4 と IPv6 の切り替えマクロ
- */
-
-#if defined(SUPPORT_INET4)
-
-#define UDP_SND_DAT	udp_snd_dat
-#define UDP_RCV_DAT	udp_rcv_dat
-
-#endif	/* of #if defined(SUPPORT_INET4) */
-
-#if defined(SUPPORT_INET6)
-
-#define UDP_SND_DAT	udp6_snd_dat
-#define UDP_RCV_DAT	udp6_rcv_dat
-
-#endif	/* of #if defined(SUPPORT_INET6) */
 
 /*
@@ -140,8 +119,8 @@
 #ifndef UDP_CFG_LIBRARY
 
-#define __udp_can_snd
-#define __udp_can_rcv
-#define __udp_snd_dat
-#define __udp_rcv_dat
+#define __udp_can_snd_nblk
+#define __udp_can_rcv_nblk
+#define __udp_snd_dat_nblk
+#define __udp_rcv_dat_nblk
 
 #endif	/* of #ifndef UDP_CFG_LIBRARY */
@@ -149,343 +128,69 @@
 #ifdef UDP_CFG_NON_BLOCKING
 
-#ifdef __udp_can_snd
-
 /*
- *  udp_can_snd -- ペンディングしている送信のキャンセル
+ *  IPv6 と IPv4 で引数が異なる関数のコンパイル
  */
 
-ER
-udp_can_snd (T_UDP_CEP *cep, ER error)
-{
-	if (cep->snd_p_dstaddr != NULL) {	/* ノンブロッキングコールでペンディング中 */
-		if (IS_PTR_DEFINED(cep->callback))
+#undef	IN_COPY_TO_HOST
 
-#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+#if defined(SUPPORT_INET6) && TNUM_UDP6_CEPID > 0
 
-			(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_SND_DAT, (void*)error);
+#define UDP_SND_DAT		udp6_snd_dat
+#define UDP_RCV_DAT		udp6_rcv_dat
+#define UDP_CAN_SND		udp6_can_snd
+#define UDP_CAN_RCV		udp6_can_rcv
+#define UDP_ALLOC_AUTO_PORT	udp6_alloc_auto_port
+#define UDP_SEND_DATA		udp6_send_data
+#define VALID_UDP_CEPID		VALID_UDP6_CEPID
+#define GET_UDP_CEP		GET_UDP6_CEP
+#define GET_UDP_CEPID		GET_UDP6_CEPID
+#define T_UDP_CEP		T_UDP6_CEP
+#define T_IPEP			T_IPV6EP
+#define API_PROTO		API_PROTO_IPV6
 
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+#if defined(SUPPORT_INET4)
+#define IN_COPY_TO_HOST		inn_copy_to_host
+#else
+#define IN_COPY_TO_HOST		IN6_COPY_TO_HOST
+#endif
 
-			(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_SND_DAT, (void*)&error);
+#include <netinet/udpn_usrreq_nblk.c>
 
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+#undef	UDP_SND_DAT
+#undef	UDP_RCV_DAT
+#undef	UDP_CAN_SND
+#undef	UDP_CAN_RCV
+#undef	UDP_ALLOC_AUTO_PORT
+#undef	UDP_SEND_DATA
+#undef	VALID_UDP_CEPID
+#undef	GET_UDP_CEP
+#undef	GET_UDP_CEPID
+#undef	T_UDP_CEP
+#undef  T_IPEP
+#undef  API_PROTO
+#undef	IN_COPY_TO_HOST
 
-		else
-			error = E_OBJ;
-		cep->snd_p_dstaddr = NULL;
-		}
-	else if (cep->snd_tskid != TA_NULL) {	/* 非ノンブロッキングコールでペンディング中 */
+#endif	/* of #if defined(SUPPORT_INET6) && TNUM_UDP6_CEPID > 0 */
 
-#ifdef UDP_CFG_EXTENTIONS
+#if defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0
 
-		/* 待ち中に発生したエラー情報を設定する。*/
-		cep->error = error;
+#define UDP_SND_DAT		udp_snd_dat
+#define UDP_RCV_DAT		udp_rcv_dat
+#define UDP_CAN_SND		udp4_can_snd
+#define UDP_CAN_RCV		udp4_can_rcv
+#define UDP_ALLOC_AUTO_PORT	udp4_alloc_auto_port
+#define UDP_SEND_DATA		udp4_send_data
+#define VALID_UDP_CEPID		VALID_UDP4_CEPID
+#define GET_UDP_CEP		GET_UDP4_CEP
+#define GET_UDP_CEPID		GET_UDP4_CEPID
+#define T_UDP_CEP		T_UDP4_CEP
+#define T_IPEP			T_IPV4EP
+#define API_PROTO		API_PROTO_IPV4
 
-#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
+#define IN_COPY_TO_HOST		IN4_COPY_TO_HOST
 
-		error = rel_wai(cep->snd_tskid);
-		cep->snd_tskid = TA_NULL;
-		}
-	else					/* どちらでもないならペンディングしていない */
-		error = EV_NOPND;
+#include <netinet/udpn_usrreq_nblk.c>
 
-	return error;
-	}
-
-#endif	/* of #ifdef __udp_can_snd */
-
-#ifdef __udp_can_rcv
-
-/*
- *  udp_can_rcv -- ペンディングしている受信のキャンセル
- */
-
-ER
-udp_can_rcv (T_UDP_CEP *cep, ER error)
-{
-	if (cep->rcv_p_dstaddr != NULL) {	/* ノンブロッキングコールでペンディング中 */
-		if (IS_PTR_DEFINED(cep->callback))
-
-#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
-
-			(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_RCV_DAT, (void*)error);
-
-#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-			(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_RCV_DAT, (void*)&error);
-
-#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
-
-		else
-			error = E_OBJ;
-		cep->rcv_p_dstaddr = NULL;
-		}
-	else if (cep->rcv_tskid != TA_NULL) {	/* 非ノンブロッキングコールでペンディング中 */
-
-#ifdef UDP_CFG_EXTENTIONS
-
-		/* 待ち中に発生したエラー情報を設定する。*/
-		cep->error = error;
-
-#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
-
-		error = rel_wai(cep->rcv_tskid);
-		cep->rcv_tskid = TA_NULL;
-		}
-	else					/* どちらでもないならペンディングしていない */
-		error = EV_NOPND;
-
-	return error;
-	}
-
-#endif	/* of #ifdef __udp_can_rcv */
-
-#ifdef __udp_snd_dat
-
-/*
- *  udp_snd_dat -- パケットの送信【標準機能】
- */
-
-ER_UINT
-UDP_SND_DAT (ID cepid, T_IPEP *p_dstaddr, void *data, int_t len, TMO tmout)
-{
-	T_UDP_CEP	*cep;
-	ER		error;
-
-	/* p_dstaddr または data が NULL ならエラー */
-	if (p_dstaddr == NULL || data == NULL)
-		return E_PAR;
-
-	/* データ長をチェックする。*/
-	if (len < 0 || len + IP_HDR_SIZE + UDP_HDR_SIZE > IF_MTU)
-		return E_PAR;
-
-	/* UDP 通信端点 ID をチェックする。*/
-	if (!VALID_UDP_CEPID(cepid))
-		return E_ID;
-
-	/* UDP 通信端点を得る。*/
-	cep = GET_UDP_CEP(cepid);
-
-	/* UDP 通信端点をチェックする。*/
-	if (!VALID_UDP_CEP(cep))
-		return E_NOEXS;
-
-	/*
-	 *  自ポート番号が UDP_PORTANY なら、自動で割り当てる。
-	 */
-	if (cep->myaddr.portno == UDP_PORTANY) {
-		if ((error = udp_alloc_auto_port(cep)) != E_OK)
-			return error;
-		}
-
-	/*
-	 * タイムアウトをチェックする。
-	 */
-
-	if (tmout == TMO_NBLK) {	/* ノンブロッキングコール */
-
-		/* 通信端点をロックする。*/
-		syscall(wai_sem(cep->semid_lock));
-
-		if (cep->snd_p_dstaddr != NULL) {
-
-			/* ノンブロッキングコールでペンディング中 */
-			error = E_QOVR;
-
-			/* 通信端点をロックを解除する。*/
-			syscall(sig_sem(cep->semid_lock));
-			}
-		else if (cep->snd_tskid != TA_NULL) {
-
-			/* 非ノンブロッキングコールでペンディング中 */
-			error = E_OBJ;
-
-			/* 通信端点をロックを解除する。*/
-			syscall(sig_sem(cep->semid_lock));
-			}
-		else {
-
-			cep->snd_p_dstaddr = p_dstaddr;
-			cep->snd_data	= data;
-			cep->snd_len	= len;
-
-			/* 通信端点をロックを解除する。*/
-			syscall(sig_sem(cep->semid_lock));
-
-			cep->flags |= UDP_CEP_FLG_POST_OUTPUT;
-			sig_sem(SEM_UDP_POST_OUTPUT);
-			error = E_WBLK;
-			}
-		}
-	else {				/* 非ノンブロッキングコール */
-	
-		/* 通信端点をロックする。*/
-		syscall(wai_sem(cep->semid_lock));
-
-		if (cep->snd_p_dstaddr != NULL) {
-
-			/* ノンブロッキングコールでペンディング中 */
-			error = E_OBJ;
-
-			/* 通信端点をロックを解除する。*/
-			syscall(sig_sem(cep->semid_lock));
-			}
-		else if (cep->snd_tskid != TA_NULL) {
-
-			/* 非ノンブロッキングコールでペンディング中 */
-			error = E_QOVR;
-
-			/* 通信端点をロックを解除する。*/
-			syscall(sig_sem(cep->semid_lock));
-			}
-		else {
-
-			/* 現在のタスク識別子を記録する。*/
-			get_tid(&(cep->snd_tskid));
-
-			/* 通信端点をロックを解除する。*/
-			syscall(sig_sem(cep->semid_lock));
-
-			/* パケットを送信する。*/
-			error = udp_send_data(cep, p_dstaddr, data, len, tmout);
-			}
-		}
-
-	return error;
-	}
-
-#endif	/* of #ifdef __udp_snd_dat */
-
-#ifdef __udp_rcv_dat
-
-/*
- *  udp_rcv_dat -- パケットの受信【標準機能】
- */
-
-ER_UINT
-UDP_RCV_DAT (ID cepid, T_IPEP *p_dstaddr, void *data, int_t len, TMO tmout)
-{
-	T_NET_BUF	*input;
-	T_UDP_CEP	*cep;
-	T_UDP_HDR	*udph;
-	ER_UINT		error;
-	uint_t		ulen, uhoff;
-
-	/* p_dstaddr または data が NULL か、len < 0 ならエラー */
-	if (p_dstaddr == NULL || data == NULL || len < 0)
-		return E_PAR;
-
-	/* UDP 通信端点 ID をチェックする。*/
-	if (!VALID_UDP_CEPID(cepid))
-		return E_ID;
-
-	/* UDP 通信端点を得る。*/
-	cep = GET_UDP_CEP(cepid);
-
-	/* UDP 通信端点をチェックする。*/
-	if (!VALID_UDP_CEP(cep))
-		return E_NOEXS;
-
-	/*
-	 * タイムアウトをチェックする。
-	 */
-
-	if (tmout == TMO_NBLK) {	/* ノンブロッキングコール */
-
-		/* 通信端点をロックする。*/
-		syscall(wai_sem(cep->semid_lock));
-
-		if (cep->rcv_p_dstaddr != NULL)
-
-			/* ノンブロッキングコールでペンディング中 */
-			error = E_QOVR;
-
-		else if (cep->rcv_tskid != TA_NULL)
-
-			/* 非ノンブロッキングコールでペンディング中 */
-			error = E_OBJ;
-		else {
-			cep->rcv_p_dstaddr = p_dstaddr;
-			cep->rcv_data	= data;
-			cep->rcv_len	= len;
-			error = E_WBLK;
-			}
-
-		/* 通信端点をロックを解除する。*/
-		syscall(sig_sem(cep->semid_lock));
-		return error;
-		}
-	else {				/* 非ノンブロッキングコール */
-
-		/* 通信端点をロックする。*/
-		syscall(wai_sem(cep->semid_lock));
-
-		if (cep->rcv_p_dstaddr != NULL) {
-
-			/* ノンブロッキングコールでペンディング中 */
-			error = E_OBJ;
-
-			/* 通信端点をロックを解除する。*/
-			syscall(sig_sem(cep->semid_lock));
-			}
-		else if (cep->rcv_tskid != TA_NULL) {
-
-			/* 非ノンブロッキングコールでペンディング中 */
-			error = E_QOVR;
-
-			/* 通信端点をロックを解除する。*/
-			syscall(sig_sem(cep->semid_lock));
-			}
-		else {
-
-			/* 現在のタスク識別子を記録する。*/
-			get_tid(&(cep->rcv_tskid));
-
-			/* 通信端点をロックを解除する。*/
-			syscall(sig_sem(cep->semid_lock));
-
-			/* 入力があるまで待つ。*/
-			if (cep->cb_netbuf != NULL) {
-
-				/*
-				 *  ここにくる場合は、コールバック関数の中から
-				 *  udp_rcv_dat を呼び出していることになり、
-				 *  すでに入力済みである。
-				 */
-				input = cep->cb_netbuf;
-				cep->cb_netbuf = NULL;
-				}
-			else if ((error = trcv_dtq(cep->rcvqid, (intptr_t*)&input, tmout)) != E_OK) {
-				cep->rcv_tskid = TA_NULL;
-				return error;
-				}
-
-			/* p_dstaddr を設定する。*/
-			uhoff = (uint_t)GET_UDP_HDR_OFFSET(input);
-			udph = GET_UDP_HDR(input, uhoff);
-			p_dstaddr->portno = ntohs(udph->sport);
-			IN_COPY_TO_HOST(&p_dstaddr->ipaddr, &GET_IP_HDR(input)->src);
-
-			/* データをバッファに移す。*/
-			ulen = ntohs(udph->ulen);
-			if (ulen - UDP_HDR_SIZE > len)
-				error = E_BOVR;
-			else {
-				len   =     (int_t)(ulen - UDP_HDR_SIZE);
-				error = (ER_UINT)(ulen - UDP_HDR_SIZE);
-				}
-
-			memcpy(data, GET_UDP_SDU(input, uhoff), (size_t)len);
-
-			syscall(rel_net_buf(input));
-
-			cep->rcv_tskid = TA_NULL;
-			}
-		return error;
-		}
-	}
-
-#endif	/* of #ifdef __udp_rcv_dat */
+#endif	/* of #if defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0 */
 
 #endif	/* of #ifdef UDP_CFG_NON_BLOCKING */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_var.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_var.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udp_var.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -75,15 +75,10 @@
  */
 
-#define IP_UDP_HDR_SIZE			(IP_HDR_SIZE + UDP_HDR_SIZE)
-#define IF_IP_UDP_HDR_SIZE		(IF_IP_HDR_SIZE + UDP_HDR_SIZE)
-#define IF_IP_UDP_HDR_OFFSET		(IF_IP_HDR_SIZE)
-
 #define GET_UDP_HDR(nbuf,uhoff)		((T_UDP_HDR*)((uint8_t*)((nbuf)->buf) + uhoff))
+#define GET_UDP_HDR_OFFSET(nbuf)	(GET_IF_IP_HDR_SIZE(nbuf))
 #define GET_UDP_SDU(nbuf,uhoff)		((uint8_t*)((nbuf)->buf) + uhoff+ UDP_HDR_SIZE)
 
-#define GET_UDP_HDR_OFFSET(nbuf)	(GET_IF_IP_HDR_SIZE(nbuf))
-
-#define GET_IP_UDP_HDR_SIZE(nbuf)	(GET_IP_HDR_SIZE(GET_IP_HDR(nbuf)) + UDP_HDR_SIZE)
-#define GET_IF_IP_UDP_HDR_SIZE(nbuf)	(IF_HDR_SIZE + GET_IP_UDP_HDR_SIZE(nbuf))
+#define IF_IP_UDP_HDR_SIZE(nbuf)	(IF_IP_HDR_SIZE(nbuf) + UDP_HDR_SIZE)
+#define IF_IP_UDP_HDR_OFFSET(nbuf)	(IF_IP_HDR_SIZE(nbuf))
 
 /*
@@ -91,5 +86,5 @@
  */
 
-#if defined(SUPPORT_INET4)
+#if defined(_IP4_CFG)
 
 #define IP4_UDP_HDR_SIZE		IP_UDP_HDR_SIZE
@@ -98,5 +93,5 @@
 #define GET_IF_IP4_UDP_HDR_SIZE(nbuf)	GET_IF_IP_UDP_HDR_SIZE(nbuf)
 
-#endif	/* of #if defined(SUPPORT_INET4) */
+#endif	/* of #if defined(_IP4_CFG) */
 
 /*
@@ -110,9 +105,7 @@
  */
 
-
-/*
- *  IPv4 UDP 通信端点
- */
-typedef struct t_udp4_cep {
+/* IPv6 用 UDP 通信端点 */
+
+typedef struct t_udp6_cep {
 
 	/*
@@ -120,5 +113,5 @@
 	 */
 	ATR		cepatr;		/* UDP 通信端点属性		*/
-	T_IPV4EP	myaddr;		/* 自分のアドレス		*/
+	T_IPV6EP	myaddr;		/* 自分のアドレス		*/
 	t_udp_callback	callback;	/* コールバック関数		*/
 
@@ -135,6 +128,6 @@
 #ifdef UDP_CFG_NON_BLOCKING
 
-	T_IPV4EP 	*snd_p_dstaddr;	/* 送信相手のアドレスへのポインタ*/
-	T_IPV4EP 	*rcv_p_dstaddr;	/* 受信相手のアドレスへのポインタ*/
+	T_IPV6EP 	*snd_p_dstaddr;	/* 送信相手のアドレスへのポインタ*/
+	T_IPV6EP 	*rcv_p_dstaddr;	/* 受信相手のアドレスへのポインタ*/
 	void		*snd_data;	/* 送信データ領域の先頭アドレス	*/
 	int_t		snd_len;	/* 送信データ領域の長さ		*/
@@ -148,15 +141,9 @@
 #endif
 
-	} T_UDP4_CEP;
-
-#if defined(SUPPORT_INET4)
-#define T_UDP_CEP	T_UDP4_CEP
-#endif
-
-/*
- *  IPv6 UDP 通信端点
- */
-
-typedef struct t_udp6_cep {
+	} T_UDP6_CEP;
+
+/* IPv4 用 UDP 通信端点 */
+
+typedef struct t_udp4_cep {
 
 	/*
@@ -164,5 +151,5 @@
 	 */
 	ATR		cepatr;		/* UDP 通信端点属性		*/
-	T_IPV6EP	myaddr;		/* 自分のアドレス		*/
+	T_IPV4EP	myaddr;		/* 自分のアドレス		*/
 	t_udp_callback	callback;	/* コールバック関数		*/
 
@@ -179,6 +166,6 @@
 #ifdef UDP_CFG_NON_BLOCKING
 
-	T_IPV6EP 	*snd_p_dstaddr;	/* 送信相手のアドレスへのポインタ*/
-	T_IPV6EP 	*rcv_p_dstaddr;	/* 受信相手のアドレスへのポインタ*/
+	T_IPV4EP 	*snd_p_dstaddr;	/* 送信相手のアドレスへのポインタ*/
+	T_IPV4EP	*rcv_p_dstaddr;	/* 受信相手のアドレスへのポインタ*/
 	void		*snd_data;	/* 送信データ領域の先頭アドレス	*/
 	int_t		snd_len;	/* 送信データ領域の長さ		*/
@@ -191,10 +178,24 @@
 	ER		error;		/* 待ち中に発生したエラー	*/
 #endif
-
-	} T_UDP6_CEP;
-
-#if defined(SUPPORT_INET6)
+#ifdef SUPPORT_IGMP
+	bool_t igmp_loopback;
+	uint8_t igmp_ttl;
+	T_IN4_ADDR 	igmp_mcaddr;	/*  */
+#endif
+	} T_UDP4_CEP;
+
+#if defined(_IP6_CFG)
+
 #define T_UDP_CEP	T_UDP6_CEP
-#endif
+
+#else	/* of #if defined(_IP6_CFG) */
+
+#if defined(_IP4_CFG)
+
+#define T_UDP_CEP	T_UDP4_CEP
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+#endif	/* of #if defined(_IP6_CFG) */
 
 /*
@@ -210,7 +211,7 @@
  */
 
-#define	TMIN_UDP_CEPID		1	/* UDP 通信端点 ID の最小値 */
-
-#ifdef SUPPORT_MIB
+#define	TMIN_UDP_CEPID		1			/* UDP      通信端点 ID の最小値 */
+#define	TMIN_UDP6_CEPID		1			/* UDP/IPv6 通信端点 ID の最小値 */
+#define	TMIN_UDP4_CEPID		(TNUM_UDP6_CEPID+1)	/* UDP/IPv4 通信端点 ID の最小値 */
 
 /*
@@ -225,17 +226,19 @@
 } T_UDP_STATS;
 
-#endif	/* of #ifdef SUPPORT_MIB */
-
 /*
  *  関数シミュレーションマクロ
  */
 
-#define VALID_UDP_CEPID(id)	(TMIN_UDP_CEPID<=(id)&&(id)<=tmax_udp_cepid)
-
-#define INDEX_UDP_CEP(id)	((id)-TMIN_UDP_CEPID)
-
-#define GET_UDP_CEP(id)		(&(udp_cep[INDEX_UDP_CEP(id)]))
-
-#define GET_UDP_CEPID(cep)	((ID)(((cep)-udp_cep)+TMIN_UDP_CEPID))
+#define VALID_UDP6_CEPID(id)	(TMIN_UDP6_CEPID<=(id)&&(id)<=tmax_udp6_cepid)
+#define VALID_UDP4_CEPID(id)	(TMIN_UDP4_CEPID<=(id)&&(id)<=tmax_udp4_cepid)
+
+#define INDEX_UDP6_CEP(id)	((id)-TMIN_UDP6_CEPID)
+#define INDEX_UDP4_CEP(id)	((id)-TMIN_UDP4_CEPID)
+
+#define GET_UDP6_CEP(id)	(&(udp6_cep[INDEX_UDP6_CEP(id)]))
+#define GET_UDP4_CEP(id)	(&(udp4_cep[INDEX_UDP4_CEP(id)]))
+
+#define GET_UDP6_CEPID(cep)	((ID)(((cep)-udp6_cep)+TMIN_UDP6_CEPID))
+#define GET_UDP4_CEPID(cep)	((ID)(((cep)-udp4_cep)+TMIN_UDP4_CEPID))
 
 #define VALID_TFN_UDP_CAN(t)	((t)==TFN_UDP_SND_DAT||(t)==TFN_UDP_RCV_DAT||\
@@ -249,12 +252,26 @@
  */
 
-extern T_UDP_CEP udp_cep[];
+extern T_UDP_STATS udp_stats;
+
+/* UDP 通信端点 */
+
+extern T_UDP6_CEP udp6_cep[];
+extern T_UDP4_CEP udp4_cep[];
+
+#if defined(SUPPORT_INET6)
+#define udp_cep	udp6_cep
+#elif defined(SUPPORT_INET4)
+#define udp_cep	udp4_cep
+#endif
+
 extern const ID tmax_udp_cepid;
 
-#ifdef SUPPORT_MIB
-
-extern T_UDP_STATS udp_stats;
-
-#endif	/* of #ifdef SUPPORT_MIB */
+#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)
+extern const ID tmax_udp6_cepid;
+extern const ID tmax_udp4_cepid;
+#else
+#define tmax_udp6_cepid	tmax_udp_cepid
+#define tmax_udp4_cepid	tmax_udp_cepid
+#endif
 
 /*
@@ -269,11 +286,29 @@
  */
 
-extern uint_t udp_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp);
-extern ER_UINT udp_send_data (T_UDP_CEP *cep, T_IPEP *p_dstaddr,
-                              void *data, int_t len, TMO tmout);
-extern ER udp_can_snd (T_UDP_CEP *cep, ER error);
-extern ER udp_can_rcv (T_UDP_CEP *cep, ER error);
-extern ER udp_alloc_auto_port (T_UDP_CEP *cep);
-extern ER udp_alloc_port (T_UDP_CEP *cep, uint16_t portno);
+/* IPv6 */
+
+extern uint_t udp6_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp);
+extern ER_UINT udp6_send_data (T_UDP6_CEP *cep, T_IPV6EP *p_dstaddr,
+                               void *data, int_t len, TMO tmout);
+extern ER udp6_can_snd (T_UDP6_CEP *cep, ER error);
+extern ER udp6_can_rcv (T_UDP6_CEP *cep, ER error);
+extern ER udp6_alloc_auto_port (T_UDP6_CEP *cep);
+extern ER udp6_alloc_port (T_UDP6_CEP *cep, uint16_t portno);
+extern T_UDP6_CEP*udp6_find_cep (T_NET_BUF *input, uint_t off);
+extern void udp6_notify (T_NET_BUF *input, ER error);
+extern void udp6_input_select (T_UDP6_CEP *cep, T_NET_BUF *input, uint_t off);
+
+/* IPv4 */
+
+extern uint_t udp4_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp);
+extern ER_UINT udp4_send_data (T_UDP4_CEP *cep, T_IPV4EP *p_dstaddr,
+                               void *data, int_t len, TMO tmout);
+extern ER udp4_can_snd (T_UDP4_CEP *cep, ER error);
+extern ER udp4_can_rcv (T_UDP4_CEP *cep, ER error);
+extern ER udp4_alloc_auto_port (T_UDP4_CEP *cep);
+extern ER udp4_alloc_port (T_UDP4_CEP *cep, uint16_t portno);
+extern T_UDP4_CEP*udp4_find_cep (T_NET_BUF *input, uint_t off);
+extern void udp4_notify (T_NET_BUF *input, ER error);
+extern void udp4_input_select (T_UDP4_CEP *cep, T_NET_BUF *input, uint_t off);
 
 /* ノンブロッキングコールを行う場合に組み込むタスク */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udpn_input.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udpn_input.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udpn_input.c	(revision 331)
@@ -0,0 +1,252 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if (API_PROTO == API_PROTO_IPV6) || (TNUM_UDP4_CEPID > 0)
+
+/*
+ *  udp_input_select -- UDP ã®å
+¥åå¦çã®é¸æ
+ */
+
+void
+UDP_INPUT_SELECT (T_UDP_CEP *cep, T_NET_BUF *input, uint_t off)
+{
+	T_UDP_HDR	*udph;
+	uint_t		len;
+
+	udph = (T_UDP_HDR *)(input->buf + off);
+	len  = (uint_t)(ntohs(udph->ulen) - UDP_HDR_SIZE);
+
+	if (cep->rcv_tskid != TA_NULL) {	/* éãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ãã³ãã£ã³ã°ä¸­ */
+		if (psnd_dtq(cep->rcvqid, (intptr_t)input) != E_OK) {
+			NET_COUNT_UDP(net_count_udp.in_err_packets, 1);
+			NET_COUNT_MIB(udp_stats.udpInErrors, 1);
+			syscall(rel_net_buf(input));
+			}
+		}
+
+#ifdef UDP_CFG_NON_BLOCKING
+
+	else if (cep->rcv_p_dstaddr != NULL) {	/* ãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ãã³ãã£ã³ã°ä¸­ */
+
+		/* p_dstaddr ãè¨­å®ããã*/
+		cep->rcv_p_dstaddr->portno = ntohs(udph->sport);
+		IN_COPY_TO_HOST(&cep->rcv_p_dstaddr->ipaddr, input);
+
+		/* ãã¼ã¿ããããã¡ã«ç§»ãã*/
+		memcpy(cep->rcv_data, GET_UDP_SDU(input, off),
+		       (size_t)(len < cep->rcv_len ? len : cep->rcv_len));
+		syscall(rel_net_buf(input));
+
+		if (IS_PTR_DEFINED(cep->callback))
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+			(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_RCV_DAT, (void*)(uint32_t)len);
+#else
+			(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_RCV_DAT, (void*)&len);
+#endif
+		else
+			syslog(LOG_WARNING, "[UDP] no call back, CEP: %d.", GET_UDP_CEPID(cep));
+		cep->rcv_p_dstaddr = NULL;
+		}
+
+#endif/* of #ifdef UDP_CFG_NON_BLOCKING */
+
+	else if (IS_PTR_DEFINED(cep->callback)) {
+
+		/* ã³ã¼ã«ããã¯é¢æ°ãå¼ã³åºãã*/
+		cep->cb_netbuf = input;
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+		(*cep->callback)(GET_UDP_CEPID(cep), TEV_UDP_RCV_DAT, (void*)(uint32_t)len);
+#else
+		(*cep->callback)(GET_UDP_CEPID(cep), TEV_UDP_RCV_DAT, (void*)&len);
+#endif
+		/*
+		 *  ãããã¯ã¼ã¯ãããã¡ããã®ã¾ã¾ã§ããã°ãã³ã¼ã«ããã¯é¢æ°å
+ã§
+		 *  ãã¼ã¿ãèª­ã¿åºããªãã£ããã¨ã«ãªãã®ã§ãæ¨ã¦ãã
+		 */
+		if (cep->cb_netbuf != NULL)
+			syscall(rel_net_buf(cep->cb_netbuf));
+		}
+	else {
+		NET_COUNT_UDP(net_count_udp.in_err_packets, 1);
+		NET_COUNT_MIB(udp_stats.udpInErrors, 1);
+		syscall(rel_net_buf(input));
+		}
+
+	}
+
+#endif	/* of #if (API_PROTO == API_PROTO_IPV6) || (TNUM_UDP4_CEPID > 0) */
+
+/*
+ *  udp_input -- UDP ã®å
+¥åé¢æ°
+ */
+
+uint_t
+UDP_INPUT (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp)
+{
+	T_NET_BUF	*input = *inputp;
+	T_UDP_CEP	*cep;
+	T_UDP_HDR	*udph;
+	uint_t		hlen, ulen;
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG) && API_PROTO == API_PROTO_IPV4
+	T_UDP6_CEP	*cep6;
+#endif
+
+	hlen = (uint_t)GET_IF_IP_HDR_SIZE(input);
+
+	NET_COUNT_UDP(net_count_udp.in_octets,  input->len - hlen);
+	NET_COUNT_UDP(net_count_udp.in_packets, 1);
+	NET_COUNT_MIB(udp_stats.udpInDatagrams, 1);
+
+	/* ãããé·ããã§ãã¯ããã*/
+	if (input->len < hlen + UDP_HDR_SIZE)
+		goto buf_rel;
+
+	udph = (T_UDP_HDR *)(input->buf + *offp);
+
+	/* ãã¼ã¿ã°ã©ã é·ããã§ãã¯ãã */
+	ulen  = ntohs(udph->ulen);
+	if (ulen != input->len - hlen)
+		goto buf_rel;
+
+	/* å®å
+ãã¼ãã 0 ã®ãã¼ã¿ã°ã©ã ã¯ç ´æ£ãããRFC768 */
+	if (udph->dport == 0)
+		goto buf_rel;
+
+#ifdef UDP_CFG_IN_CHECKSUM
+
+	/* ãã§ãã¯ãµã ããã§ãã¯ãã */
+	if (udph->sum && IN_CKSUM(input, IPPROTO_UDP, *offp, ulen) != 0)
+		goto buf_rel;
+
+#endif	/* of #ifdef UDP_CFG_IN_CHECKSUM */
+
+#if defined(_IP6_CFG) && defined(_IP4_CFG) && API_PROTO == API_PROTO_IPV4
+
+#if TNUM_UDP4_CEPID > 0
+
+	/* UDP éä¿¡ç«¯ç¹ãå¾ãã*/
+	cep = udp4_find_cep(input, *offp);
+
+	if (cep != NULL)
+		udp4_input_select(cep, input, *offp);
+	else if ((cep6 = udp6_find_cep(input, *offp)) != NULL)
+		udp6_input_select(cep6, input, *offp);
+	else
+		udp4_reply_no_port(input, *offp);
+
+	return IPPROTO_DONE;
+
+#else	/* of #if TNUM_UDP4_CEPID > 0 */
+
+	cep = 0;	/* warning åé¿ç¨ã®ããã¼ */
+	if ((cep6 = udp6_find_cep(input, *offp)) != NULL)
+		udp6_input_select(cep6, input, *offp);
+	else
+		udp4_reply_no_port(input, *offp);
+
+	return IPPROTO_DONE;
+
+#endif	/* of #if TNUM_UDP4_CEPID > 0 */
+
+#else	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) && API_PROTO == API_PROTO_IPV4 */
+
+	/* UDP éä¿¡ç«¯ç¹ãå¾ãã*/
+	cep = UDP_FIND_CEP(input, *offp);
+
+	if (cep != NULL)
+		UDP_INPUT_SELECT(cep, input, *offp);
+	else
+		UDP_REPLY_NO_PORT(input, *offp);
+
+	return IPPROTO_DONE;
+
+#endif	/* of #if defined(_IP6_CFG) && defined(_IP4_CFG) && API_PROTO == API_PROTO_IPV4 */
+
+buf_rel:
+	NET_COUNT_UDP(net_count_udp.in_err_packets, 1);
+	NET_COUNT_MIB(udp_stats.udpInErrors, 1);
+	syscall(rel_net_buf(input));
+	return IPPROTO_DONE;
+	}
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udpn_output.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udpn_output.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udpn_output.c	(revision 331)
@@ -0,0 +1,175 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ *  udp_output -- UDP ã®åºåé¢æ°
+ *  ãã³ãã­ãã­ã³ã°ã³ã¼ã«ãçµã¿è¾¼ãã ã¨ãä½¿ç¨ããã
+ */
+
+static void
+UDP_OUTPUT (T_UDP_CEP *cep)
+{
+	T_NET_BUF	*output;
+	T_UDP_HDR	*udph;
+	ER_UINT		error;
+
+#ifdef UDP_CFG_OUT_CHECKSUM
+	uint16_t	sum;
+#endif	/* of #ifdef UDP_CFG_OUT_CHECKSUM */
+
+	/* IP ãã¼ã¿ã°ã©ã ãå²ãå½ã¦ãã*/
+	if ((error = IN_GET_DATAGRAM(&output, (uint_t)(UDP_HDR_SIZE + cep->snd_len), 0,
+	                             &cep->snd_p_dstaddr->ipaddr,
+	                             &cep->myaddr.ipaddr,
+	                             IPPROTO_UDP, IP_DEFTTL, 
+	                             NBA_SEARCH_ASCENT, TMO_UDP_OUTPUT)) != E_OK) {
+		goto err_ret;
+		}
+
+	/* UDP ãããã«æ
+å ±ãè¨­å®ããã*/
+	udph		= GET_UDP_HDR(output, IF_IP_UDP_HDR_OFFSET(output));
+	udph->sport	= htons(cep->myaddr.portno);
+	udph->dport	= htons(cep->snd_p_dstaddr->portno);
+	udph->ulen	= htons(UDP_HDR_SIZE + cep->snd_len);
+	udph->sum	= 0;
+
+	/* ãã¼ã¿ãã³ãã¼ããã*/
+	memcpy((void*)GET_UDP_SDU(output, IF_IP_UDP_HDR_OFFSET(output)),
+	       cep->snd_data, (size_t)cep->snd_len);
+
+#ifdef UDP_CFG_OUT_CHECKSUM
+
+	sum = IN_CKSUM(output, IPPROTO_UDP, IF_IP_UDP_HDR_OFFSET(output),
+	               (uint_t)(UDP_HDR_SIZE + cep->snd_len));
+
+	/* è¨ç®ãããã§ãã¯ãµã ã®å¤ã 0 ãªã 0xffff ãå
+¥ããã*/
+	if (sum == 0)
+		sum = UINT_C(0xffff);
+	udph->sum = sum;
+
+#endif/* of #ifdef UDP_CFG_OUT_CHECKSUM */
+
+	/* ãããã¯ã¼ã¯ãããã¡é·ãèª¿æ´ããã*/
+	output->len = (uint16_t)(IF_IP_UDP_HDR_SIZE(output) + cep->snd_len);
+
+	/* ãããã¯ã¼ã¯å±¤ (IP) ã®åºåé¢æ°ãå¼ã³åºãã*/
+	if ((error = IP_OUTPUT(output, TMO_UDP_OUTPUT)) != E_OK)
+		goto err_ret;
+
+
+	NET_COUNT_MIB(udp_stats.udpOutDatagrams, 1);
+
+	if (IS_PTR_DEFINED(cep->callback)) {
+
+		if (error == E_OK)
+			error = cep->snd_len;
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+		(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_SND_DAT, (void*)error);
+#else
+		(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_SND_DAT, (void*)&error);
+#endif
+		}
+	else
+		syslog(LOG_WARNING, "[UDP] no call back, CEP: %d.", GET_UDP_CEPID(cep));
+	cep->snd_p_dstaddr = NULL;
+	return;
+
+err_ret:
+	NET_COUNT_UDP(net_count_udp.out_err_packets, 1);
+	if (IS_PTR_DEFINED(cep->callback)) {
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+
+		(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_SND_DAT, (void*)E_NOMEM);
+
+#else	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+		error = E_NOMEM;
+		(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_SND_DAT, (void*)&error);
+
+#endif	/* of #ifdef TCP_CFG_NON_BLOCKING_COMPAT14 */
+
+		}
+	else
+		syslog(LOG_WARNING, "[UDP] no call back, CEP: %d.", GET_UDP_CEPID(cep));
+	cep->snd_p_dstaddr = NULL;
+	return;
+	}
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udpn_subr.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udpn_subr.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udpn_subr.c	(revision 331)
@@ -0,0 +1,170 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must ceproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ *  udp_alloc_auto_port -- èªåå²ãå½ã¦ãã¼ãçªå·ãè¨­å®ããã
+ */
+
+ER
+UDP_ALLOC_AUTO_PORT (T_UDP_CEP *cep)
+{
+	int_t	ix;
+	uint16_t	portno, portno_start;
+
+	portno_start = udp_port_auto;
+	do {
+		portno = udp_port_auto ++;
+		if (udp_port_auto > UDP_PORT_LAST_AUTO)
+			udp_port_auto = UDP_PORT_FIRST_AUTO;
+
+		syscall(wai_sem(SEM_UDP_CEP));
+		for (ix = TMAX_UDP_CEPID; ix -- > 0; ) {
+			if (VALID_UDP_CEP(&UDP_CEP[ix]) && UDP_CEP[ix].myaddr.portno == portno) {
+				portno = UDP_PORTANY;
+				break;
+				}
+			}
+
+		if (portno != UDP_PORTANY) {
+			cep->myaddr.portno = portno;
+			syscall(sig_sem(SEM_UDP_CEP));
+			return E_OK;
+			}
+		syscall(sig_sem(SEM_UDP_CEP));
+
+		} while (portno_start != udp_port_auto);
+
+	return E_NOID;
+	}
+
+/*
+ *  udp_alloc_port -- æå®ããããã¼ãçªå·ãè¨­å®ããã
+ */
+
+ER
+UDP_ALLOC_PORT (T_UDP_CEP *cep, uint16_t portno)
+{
+	int_t	ix;
+
+	syscall(wai_sem(SEM_UDP_CEP));
+	for (ix = TMAX_UDP_CEPID; ix -- > 0; )
+		if (VALID_UDP_CEP(&UDP_CEP[ix]) && UDP_CEP[ix].myaddr.portno == portno) {
+			syscall(sig_sem(SEM_UDP_CEP));
+			return E_PAR;
+			}
+	cep->myaddr.portno = portno;
+	syscall(sig_sem(SEM_UDP_CEP));
+	return E_OK;
+	}
+
+/*
+ *  udp_find_cep -- ãã¼ãçªå·ãã UDP éä¿¡ç«¯ç¹ãå¾ãã
+ */
+
+T_UDP_CEP*
+UDP_FIND_CEP (T_NET_BUF *input, uint_t off)
+{
+	T_UDP_CEP*	cep;
+	T_UDP_HDR	*udph;
+
+	udph = GET_UDP_HDR(input, off);
+	
+	/*
+	 *  IP ã¢ãã¬ã¹ã¨ãã¼ãçªå·ãä¸è´ããéä¿¡ç«¯ç¹ãæ¢ç´¢ããã
+	 */
+	for (cep = &UDP_CEP[TMAX_UDP_CEPID]; cep -- != UDP_CEP; ) {
+		if (VALID_UDP_CEP(cep)                                &&
+		    UDP_IS_DSTADDR_ACCEPT(&cep->myaddr.ipaddr, input) &&
+		    ntohs(udph->dport) == cep->myaddr.portno)
+			return cep;
+		}
+
+	return NULL;
+	}
+
+/*
+ *  udp_notify -- ICMP ã¨ã©ã¼ã®å¦ç
+ */
+
+void
+UDP_NOTIFY (T_NET_BUF *input, ER error)
+{
+	if (UDP_FIND_CEP(input, GET_UDP_HDR_OFFSET(input)) != NULL) {
+		syslog(LOG_NOTICE, "[UDP] error, code: %d.", error);
+		}
+	}
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udpn_usrreq.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udpn_usrreq.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udpn_usrreq.c	(revision 331)
@@ -0,0 +1,836 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must ceproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)udp_usrreq.c	8.6 (Berkeley) 5/23/95
+ * $FreeBSD: src/sys/netinet/udp_usrreq.c,v 1.49.2.2 1999/08/29 16:29:58 peter Exp $
+ */
+
+#ifdef __udp_send_data
+
+/*
+ *  udp_send_data -- ãã±ããéä¿¡ã®ä¸»è¦é¨
+ */
+
+ER_UINT
+UDP_SEND_DATA (T_UDP_CEP *cep, T_IPEP *p_dstaddr, void *data, int_t len, TMO tmout)
+{
+	T_NET_BUF	*output;
+	T_UDP_HDR	*udph;
+	SYSTIM		before, after;
+	ER		error = E_OK;
+
+#ifdef UDP_CFG_OUT_CHECKSUM
+	uint16_t	sum;
+#endif	/* of #ifdef UDP_CFG_OUT_CHECKSUM */
+
+	NET_COUNT_UDP(net_count_udp.out_octets,  len);
+	NET_COUNT_UDP(net_count_udp.out_packets, 1);
+
+	/* IP ãã¼ã¿ã°ã©ã å²ãå½ã¦ã®æéã tmout ããæ¸ããã*/
+	if (!(tmout == TMO_POL || tmout == TMO_FEVR))
+		syscall(get_tim(&before));
+
+	/* IP ãã¼ã¿ã°ã©ã ãå²ãå½ã¦ãã*/
+	if ((error = IN_GET_DATAGRAM(&output, (uint_t)(UDP_HDR_SIZE + len), 0,
+	                             &p_dstaddr->ipaddr,
+	                             &cep->myaddr.ipaddr,
+	                             IPPROTO_UDP, IP_DEFTTL, 
+	                             NBA_SEARCH_ASCENT, tmout)) != E_OK)
+		goto err_ret;
+
+	/* IP ãã¼ã¿ã°ã©ã å²ãå½ã¦ã®æéã tmout ããæ¸ããã*/
+	if (!(tmout == TMO_POL || tmout == TMO_FEVR)) {
+		syscall(get_tim(&after));
+		if (after - before > tmout) {
+			syscall(rel_net_buf(output));
+			error = E_TMOUT;
+			goto err_ret;
+			}
+		tmout -= (TMO)(after - before);
+		}
+
+	/* UDP ãããã«æ
+å ±ãè¨­å®ããã*/
+	udph		= GET_UDP_HDR(output, IF_IP_UDP_HDR_OFFSET(output));
+	udph->sport	= htons(cep->myaddr.portno);
+	udph->dport	= htons(p_dstaddr->portno);
+	udph->ulen	= htons(UDP_HDR_SIZE + len);
+	udph->sum	= 0;
+
+	/* ãã¼ã¿ãã³ãã¼ããã*/
+	memcpy((void*)GET_UDP_SDU(output, IF_IP_UDP_HDR_OFFSET(output)), data, (size_t)len);
+
+#ifdef UDP_CFG_OUT_CHECKSUM
+
+	sum = IN_CKSUM(output, IPPROTO_UDP, IF_IP_UDP_HDR_OFFSET(output), (uint_t)(UDP_HDR_SIZE + len));
+
+	/* è¨ç®ãããã§ãã¯ãµã ã®å¤ã 0 ãªã 0xffff ãå
+¥ããã*/
+	if (sum == 0)
+		sum = 0xffff;
+	udph->sum = sum;
+
+#endif	/* of #ifdef UDP_CFG_OUT_CHECKSUM */
+
+	/* ãããã¯ã¼ã¯ãããã¡é·ãèª¿æ´ããã*/
+	output->len = (uint16_t)(IF_IP_UDP_HDR_SIZE(output) + len);
+
+	/* ãããã¯ã¼ã¯å±¤ (IP) ã®åºåé¢æ°ãå¼ã³åºãã*/
+	if ((error = IP_OUTPUT(output, tmout)) == E_OK) {
+		NET_COUNT_MIB(udp_stats.udpOutDatagrams, 1);
+		cep->snd_tskid = TA_NULL;
+		return len;
+		}
+
+err_ret:
+	NET_COUNT_UDP(net_count_udp.out_err_packets, 1);
+	cep->snd_tskid = TA_NULL;
+	return error;
+	}
+
+#endif	/* of #ifdef __udp_send_data */
+
+/*
+ *  udp_cancel_cep -- ãã³ãã£ã³ã°ãã¦ããå¦çãã­ã£ã³ã»ã«ããã
+ *
+ *    udp_can_cep ããå¼åºãããã¡ã¤ã³é¢æ°
+ */
+
+#ifdef __udp_can_cep
+
+static ER
+UDP_CANCEL_CEP (T_UDP_CEP *cep, FN fncd)
+{
+	ER	error = E_OK, snd_err, rcv_err;
+
+	/* UDP éä¿¡ç«¯ç¹ããã§ãã¯ããã*/
+	if (!VALID_UDP_CEP(cep))
+		return E_NOEXS;
+
+	/* API æ©è½ã³ã¼ãããã§ãã¯ããã*/
+	if (!VALID_TFN_UDP_CAN(fncd))
+		return E_PAR;
+
+	/* éä¿¡ç«¯ç¹ãã­ãã¯ããã*/
+	syscall(wai_sem(cep->semid_lock));
+
+	if (fncd == TFN_UDP_ALL) {	/* TFN_UDP_ALL ã®å¦ç */
+
+		snd_err = UDP_CAN_SND(cep, E_RLWAI);
+		rcv_err = UDP_CAN_RCV(cep, E_RLWAI);
+
+		/*
+		 *  snd_err ã¨ rcv_err ã®ã©ã¡ãã EV_NOPND
+		 *  ãªãããã³ãã£ã³ã°ãã¦ããªãã®ã§ã¨ã©ã¼
+		 */
+		if (snd_err == EV_NOPND && rcv_err == EV_NOPND)
+			error = E_OBJ;
+		else {
+			if (snd_err == EV_NOPND)
+				snd_err = E_OK;
+			if (rcv_err == EV_NOPND)
+				rcv_err = E_OK;
+
+			if (snd_err != E_OK)
+				error = snd_err;
+			else if (rcv_err != E_OK)
+				error = rcv_err;
+			}
+		}
+	else if (fncd == TFN_UDP_SND_DAT) {	/* éä¿¡å¦çã®ã­ã£ã³ã»ã« */
+		if ((error = UDP_CAN_SND(cep, E_RLWAI)) == EV_NOPND)
+			error = E_OBJ;
+		}
+	else if (fncd == TFN_UDP_RCV_DAT) {	/* åä¿¡å¦çã®ã­ã£ã³ã»ã« */
+		if ((error = UDP_CAN_RCV(cep, E_RLWAI)) == EV_NOPND)
+			error = E_OBJ;
+		}
+	else
+		error = E_PAR;
+
+	/* éä¿¡ç«¯ç¹ãã­ãã¯ãè§£é¤ããã*/
+	syscall(sig_sem(cep->semid_lock));
+
+	return error;
+	}
+
+#endif	/* of #ifdef __udp_can_cep */
+
+#if defined(SUPPORT_INET6) && (defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0)
+
+#else	/* of #if defined(SUPPORT_INET6) && (defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0) */
+
+/*
+ *  udp_can_cep -- ãã³ãã£ã³ã°ãã¦ããå¦çã®ã­ã£ã³ã»ã«ãæ¨æºæ©è½ã
+ */
+
+#ifdef __udp_can_cep
+
+ER
+udp_can_cep (ID cepid, FN fncd)
+{
+	T_UDP_CEP	*cep;
+
+	/* UDP éä¿¡ç«¯ç¹ ID ããã§ãã¯ããã*/
+	if (!VALID_UDP_CEPID(cepid))
+		return E_ID;
+
+	/* UDP éä¿¡ç«¯ç¹ãå¾ãã*/
+	cep = GET_UDP_CEP(cepid);
+
+	/* ã¡ã¤ã³é¢æ°ãå¼ã³åºãã*/
+	return UDP_CANCEL_CEP(cep, fncd);
+	}
+
+#endif	/* of #ifdef __udp_can_cep */
+
+#endif	/* of #if defined(SUPPORT_INET6) && (defined(SUPPORT_INET4) && TNUM_UDP4_CEPID > 0) */
+
+#ifdef UDP_CFG_EXTENTIONS
+
+/*
+ *  udp_cre_cep -- UDP éä¿¡ç«¯ç¹ã®çæãæ¡å¼µæ©è½ã
+ */
+
+#ifdef __udp_cre_cep
+
+ER
+UDP_CRE_CEP (ID cepid, T_UDPN_CCEP *pk_ccep)
+{
+	T_UDP_CEP	*cep;
+	ER		error;
+
+	/* UDP éä¿¡ç«¯ç¹ ID ããã§ãã¯ããã*/
+	if (!VALID_UDP_CEPID(cepid))
+		return E_ID;
+
+	/* pk_ccep ã NULL ãªãã¨ã©ã¼ */
+	if (pk_ccep == NULL)
+		return E_PAR;
+
+#if (API_PROTO == API_PROTO_IPV6) && !defined(API_CFG_IP4MAPPED_ADDR)
+
+	/*
+	 * API ã IPv6 ã§ IPv4 å°å½±ã¢ãã¬ã¹ãèªãããã¦ããªãã®ã«ããããããã
+	 * IPv4 å°å½±ã¢ãã¬ã¹ãæå®ããããã¨ã©ã¼
+	 */
+	if (in6_is_addr_ipv4mapped(&pk_ccep->myaddr.ipaddr))
+		return E_PAR;
+
+#endif	/* of #if (API_PROTO == API_PROTO_IPV6) && !defined(DAPI_CFG_IP4MAPPED_ADDR) */
+
+	/* UDP éä¿¡ç«¯ç¹ãå¾ãã*/
+	cep = GET_UDP_CEP(cepid);
+
+	/* UDP éä¿¡ç«¯ç¹ããã§ãã¯ããã*/
+	if (VALID_UDP_CEP(cep))
+		return E_OBJ;
+
+	/* UDP éä¿¡ç«¯ç¹ããåççæç¨ã§ãªããã°ã¨ã©ã¼ */
+	if (!DYNAMIC_UDP_CEP(cep))
+		return E_ID;
+
+	/* éä¿¡ç«¯ç¹ãã­ãã¯ããã*/
+	syscall(wai_sem(cep->semid_lock));
+
+	/*
+	 * UDP éä¿¡ç«¯ç¹ããã§ãã¯ãããçææ¸ã¿ã§ããã°ã¨ã©ã¼
+	 */
+	if (VALID_UDP_CEP(cep))
+		error = E_OBJ;
+	else {
+
+		/*
+		 *  èªãã¼ãçªå·ã UDP_PORTANY ãªããèªåã§å²ãå½ã¦ãã
+		 */
+		if (pk_ccep->myaddr.portno == UDP_PORTANY)
+			error = UDP_ALLOC_AUTO_PORT(cep);
+		else 
+			error = UDP_ALLOC_PORT(cep, pk_ccep->myaddr.portno);
+		
+                if (error == E_OK) {
+
+			/* UDP éä¿¡ç«¯ç¹çææ
+å ±ãã³ãã¼ããã*/
+			cep->cepatr        = pk_ccep->cepatr;			/* éä¿¡ç«¯ç¹å±æ§		*/
+			cep->myaddr.ipaddr = pk_ccep->myaddr.ipaddr;		/* èªåã®ã¢ãã¬ã¹	*/
+			cep->callback      = (void*)pk_ccep->callback;		/* ã³ã¼ã«ããã¯		*/
+
+			/* UDP éä¿¡ç«¯ç¹ãçææ¸ã¿ã«ããã*/
+			cep->flags |= UDP_CEP_FLG_VALID;
+			}
+		}
+
+	/* éä¿¡ç«¯ç¹ã®ã­ãã¯ãè§£é¤ããã*/
+	syscall(sig_sem(cep->semid_lock));
+
+	return error;
+	}
+
+#endif	/* of #ifdef __udp_cre_cep */
+
+#ifdef __udp_del_cep
+
+/*
+ *  udp_delete_cep -- UDP éä¿¡ç«¯ç¹ãåé¤ããã
+ *
+ *    udp_del_cep ããå¼åºãããã¡ã¤ã³é¢æ°
+ */
+
+static ER
+UDP_DELETE_CEP (T_UDP_CEP *cep)
+{
+	ER	error;
+
+	/* UDP éä¿¡ç«¯ç¹ããã§ãã¯ããã*/
+	if (!VALID_UDP_CEP(cep))
+		return E_NOEXS;
+
+	/* UDP éä¿¡ç«¯ç¹ããåççæç¨ã§ãªããã°ã¨ã©ã¼ */
+	if (!DYNAMIC_UDP_CEP(cep))
+		return E_ID;
+
+	/* éä¿¡ç«¯ç¹ãã­ãã¯ããã*/
+	syscall(wai_sem(cep->semid_lock));
+
+	/*
+	 * UDP éä¿¡ç«¯ç¹ããã§ãã¯ãããæªçæã®å ´åã¯ã¨ã©ã¼
+	 * ã»æªçæã
+	 */
+	if (!VALID_UDP_CEP(cep))
+		error = E_NOEXS;
+	else {
+		UDP_CAN_SND(cep, E_DLT);
+		UDP_CAN_RCV(cep, E_DLT);
+
+		/* UDP éä¿¡ç«¯ç¹ãæªçæã«ããã*/
+		cep->flags &= ~UDP_CEP_FLG_VALID;
+		error = E_OK;
+		}
+
+	/* éä¿¡ç«¯ç¹ã®ã­ãã¯ãè§£é¤ããã*/
+	syscall(sig_sem(cep->semid_lock));
+
+	return error;
+	}
+
+/*
+ *  udp_del_cep -- UDP éä¿¡ç«¯ç¹ã®åé¤ãæ¡å¼µæ©è½ã
+ */
+
+ER
+UDP_DEL_CEP (ID cepid)
+{
+	T_UDP_CEP	*cep;
+
+	/* UDP éä¿¡ç«¯ç¹ ID ããã§ãã¯ããã*/
+	if (!VALID_UDP_CEPID(cepid))
+		return E_ID;
+
+	/* UDP éä¿¡ç«¯ç¹ãå¾ãã*/
+	cep = GET_UDP_CEP(cepid);
+
+	/* ã¡ã¤ã³é¢æ°ãå¼ã³åºãã*/
+	return UDP_DELETE_CEP(cep);
+	}
+
+#endif	/* of #ifdef __udp_del_cep */
+
+#ifdef __udp_set_opt
+
+/*
+ *  udp_set_option -- UDP éä¿¡ç«¯ç¹ãªãã·ã§ã³ãè¨­å®ããã
+ *
+ *    udp_set_opt ããå¼åºãããã¡ã¤ã³é¢æ°
+ */
+
+static ER
+UDP_SET_OPTION (T_UDP_CEP *cep, int_t optname, void *optval, int_t optlen)
+{
+	/* UDP éä¿¡ç«¯ç¹ããã§ãã¯ããã*/
+	if (!VALID_UDP_CEP(cep))
+		return E_NOEXS;
+#if defined(SUPPORT_INET6)
+#endif
+#if defined(SUPPORT_INET4) && defined(SUPPORT_IGMP) && TNUM_UDP4_CEPID > 0
+	switch (optname) {
+	case IP_MULTICAST_LOOP:
+		if (optlen >= sizeof(uint8_t)) {
+			return igmp_set_loop(cep, *(uint8_t *)optval);
+			}
+		break;
+	case IP_MULTICAST_TTL:
+		if (optlen >= sizeof(uint8_t)) {
+			return igmp_set_ttl(cep, *(uint8_t *)optval);
+			}
+		break;
+	case IP_MULTICAST_IF:
+		if (optlen >= sizeof(T_IN4_ADDR)) {
+			return igmp_set_if(cep, (T_IN4_ADDR *)optval);
+			}
+		break;
+	case IP_ADD_MEMBERSHIP:
+		if (optlen >= sizeof(T_IP_MREQ)) {
+			return igmp_add_membership(cep, (T_IP_MREQ *)optval);
+			}
+		break;
+	case IP_DROP_MEMBERSHIP:
+		if (optlen >= sizeof(T_IP_MREQ)) {
+			return igmp_drop_membership(cep, (T_IP_MREQ *)optval);
+			}
+		break;
+	case IP_MSFILTER:
+		if (optlen >= sizeof(T_IP_MSFILTER)) {
+			return igmp_set_ip_msfilter(cep, (T_IP_MSFILTER *)optval);
+			}
+		break;
+		}
+#endif
+	return E_PAR;
+	}
+
+/*
+ *  udp_set_opt -- UDP éä¿¡ç«¯ç¹ãªãã·ã§ã³ã®è¨­å®ãæ¡å¼µæ©è½ã
+ *
+ *  æ³¨æ: è¨­å®å¯è½ãª UDP éä¿¡ç«¯ç¹ãªãã·ã§ã³ã¯ç¡ããããE_PAR ãè¿ãããã
+ */
+
+ER
+UDP_SET_OPT (ID cepid, int_t optname, void *optval, int_t optlen)
+{
+	T_UDP_CEP	*cep;
+
+	/* UDP éä¿¡ç«¯ç¹ ID ããã§ãã¯ããã*/
+	if (!VALID_UDP_CEPID(cepid))
+		return E_ID;
+
+	/* UDP éä¿¡ç«¯ç¹ãå¾ãã*/
+	cep = GET_UDP_CEP(cepid);
+
+	/* ã¡ã¤ã³é¢æ°ãå¼ã³åºãã*/
+	return UDP_SET_OPTION(cep, optname, optval, optlen);
+	}
+
+#endif	/* of #ifdef __udp_set_opt */
+
+#ifdef __udp_get_opt
+
+/*
+ *  udp_get_option -- UDP éä¿¡ç«¯ç¹ãªãã·ã§ã³ãç²å¾ããã
+ *
+ *    udp_get_opt ããå¼åºãããã¡ã¤ã³é¢æ°
+ */
+
+static ER
+UDP_GET_OPTION (T_UDP_CEP *cep, int_t optname, void *optval, int_t optlen)
+{
+	/* UDP éä¿¡ç«¯ç¹ããã§ãã¯ããã*/
+	if (!VALID_UDP_CEP(cep))
+		return E_NOEXS;
+#if defined(SUPPORT_INET6)
+#endif
+#if defined(SUPPORT_INET4) && defined(SUPPORT_IGMP) && TNUM_UDP4_CEPID > 0
+	switch (optname) {
+	case IP_MULTICAST_LOOP:
+		if (optlen >= sizeof(uint8_t)) {
+			return igmp_get_loop(cep, (uint8_t *)optval);
+			}
+		break;
+	case IP_MULTICAST_TTL:
+		if (optlen >= sizeof(uint8_t)) {
+			return igmp_get_ttl(cep, (uint8_t *)optval);
+			}
+		break;
+	case IP_MULTICAST_IF:
+		if (optlen >= sizeof(uint32_t)) {
+			return igmp_get_if(cep, (uint32_t *)optval);
+			}
+		break;
+	case IP_MSFILTER:
+		if (optlen >= sizeof(T_IP_MSFILTER)) {
+			return igmp_get_ip_msfilter(cep, (T_IP_MSFILTER *)optval);
+			}
+		break;
+		}
+#endif
+	return E_PAR;
+	}
+
+/*
+ *  udp_get_opt -- UDP éä¿¡ç«¯ç¹ãªãã·ã§ã³ã®ç²å¾ãæ¡å¼µæ©è½ã
+ *
+ *  æ³¨æ: è¨­å®å¯è½ãª UDP éä¿¡ç«¯ç¹ãªãã·ã§ã³ã¯ç¡ããããE_PAR ãè¿ãããã
+ */
+
+ER
+UDP_GET_OPT (ID cepid, int_t optname, void *optval, int_t optlen)
+{
+	T_UDP_CEP	*cep;
+
+	/* UDP éä¿¡ç«¯ç¹ ID ããã§ãã¯ããã*/
+	if (!VALID_UDP_CEPID(cepid))
+		return E_ID;
+
+	/* UDP éä¿¡ç«¯ç¹ãå¾ãã*/
+	cep = GET_UDP_CEP(cepid);
+
+	/* ã¡ã¤ã³é¢æ°ãå¼ã³åºãã*/
+	return UDP_GET_OPTION(cep, optname, optval, optlen);
+	}
+
+#endif	/* of #ifdef __udp_get_opt */
+
+#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
+
+#ifdef UDP_CFG_NON_BLOCKING
+
+#else	/* of #ifdef UDP_CFG_NON_BLOCKING */
+
+#ifdef __udp_can_snd
+
+/*
+ *  udp_can_snd -- ãã³ãã£ã³ã°ãã¦ããéä¿¡ã®ã­ã£ã³ã»ã«
+ */
+
+ER
+UDP_CAN_SND (T_UDP_CEP *cep, ER error)
+{
+	if (cep->snd_tskid != TA_NULL) {	/* éãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ãã³ãã£ã³ã°ä¸­ */
+
+#ifdef UDP_CFG_EXTENTIONS
+
+		/* å¾
+ã¡ä¸­ã«çºçããã¨ã©ã¼æ
+å ±ãè¨­å®ããã*/
+		cep->error = error;
+
+#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
+
+		error = rel_wai(cep->snd_tskid);
+		cep->snd_tskid = TA_NULL;
+		}
+	else					/* ã©ã¡ãã§ããªããªããã³ãã£ã³ã°ãã¦ããªã */
+		error = EV_NOPND;
+
+	return error;
+	}
+
+#endif	/* of #ifdef __udp_can_snd */
+
+#ifdef __udp_can_rcv
+
+/*
+ *  udp_can_rcv -- ãã³ãã£ã³ã°ãã¦ããåä¿¡ã®ã­ã£ã³ã»ã«
+ */
+
+ER
+UDP_CAN_RCV (T_UDP_CEP *cep, ER error)
+{
+	if (cep->rcv_tskid != TA_NULL) {	/* éãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ãã³ãã£ã³ã°ä¸­ */
+
+#ifdef UDP_CFG_EXTENTIONS
+
+		/* å¾
+ã¡ä¸­ã«çºçããã¨ã©ã¼æ
+å ±ãè¨­å®ããã*/
+		cep->error = error;
+
+#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
+
+		error = rel_wai(cep->rcv_tskid);
+		cep->rcv_tskid = TA_NULL;
+		}
+	else					/* ã©ã¡ãã§ããªããªããã³ãã£ã³ã°ãã¦ããªã */
+		error = EV_NOPND;
+
+	return error;
+	}
+
+#endif	/* of #ifdef __udp_can_rcv */
+
+#ifdef __udp_snd_dat
+
+/*
+ *  udp_snd_dat -- ãã±ããã®éä¿¡ãæ¨æºæ©è½ã
+ */
+
+ER_UINT
+UDP_SND_DAT (ID cepid, T_IPEP *p_dstaddr, void *data, int_t len, TMO tmout)
+{
+	T_UDP_CEP	*cep;
+	ER		error;
+
+	/* p_dstaddr ã¾ãã¯ data ã NULL ããtmout ã TMO_NBLK ãªãã¨ã©ã¼ */
+	if (p_dstaddr == NULL || data == NULL || tmout == TMO_NBLK)
+		return E_PAR;
+
+	/* ãã¼ã¿é·ããã§ãã¯ããã*/
+	if (len < 0 || len + IP_HDR_SIZE + UDP_HDR_SIZE > IF_MTU)
+		return E_PAR;
+
+#if (API_PROTO == API_PROTO_IPV6) && !defined(API_CFG_IP4MAPPED_ADDR)
+
+	/*
+	 * API ã IPv6 ã§ IPv4 å°å½±ã¢ãã¬ã¹ãèªãããã¦ããªãã®ã«ããããããã
+	 * IPv4 å°å½±ã¢ãã¬ã¹ãæå®ããããã¨ã©ã¼
+	 */
+	if (in6_is_addr_ipv4mapped(&p_dstaddr->ipaddr))
+		return E_PAR;
+
+#endif	/* of #if (API_PROTO == API_PROTO_IPV6) && !defined(DAPI_CFG_IP4MAPPED_ADDR) */
+
+	/* UDP éä¿¡ç«¯ç¹ ID ããã§ãã¯ããã*/
+	if (!VALID_UDP_CEPID(cepid))
+		return E_ID;
+
+	/* UDP éä¿¡ç«¯ç¹ãå¾ãã*/
+	cep = GET_UDP_CEP(cepid);
+
+	/* UDP éä¿¡ç«¯ç¹ããã§ãã¯ããã*/
+	if (!VALID_UDP_CEP(cep))
+		return E_NOEXS;
+
+	/*
+	 *  èªãã¼ãçªå·ã UDP_PORTANY ãªããèªåã§å²ãå½ã¦ãã
+	 */
+	if (cep->myaddr.portno == UDP_PORTANY) {
+		if ((error = UDP_ALLOC_AUTO_PORT(cep)) != E_OK)
+			return error;
+		}
+	
+	/* éä¿¡ç«¯ç¹ãã­ãã¯ããã*/
+	syscall(wai_sem(cep->semid_lock));
+
+	if (cep->snd_tskid != TA_NULL) {
+
+		/* éãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ãã³ãã£ã³ã°ä¸­ */
+		error = E_QOVR;
+
+		/* éä¿¡ç«¯ç¹ãã­ãã¯ãè§£é¤ããã*/
+		syscall(sig_sem(cep->semid_lock));
+		}
+	else {
+		/* ç¾å¨ã®ã¿ã¹ã¯è­å¥å­ãè¨é²ããã*/
+		get_tid(&(cep->snd_tskid));
+
+#ifdef UDP_CFG_EXTENTIONS
+
+		/* å¾
+ã¡ä¸­ã«çºçããã¨ã©ã¼æ
+å ±ããªã»ããããã*/
+		cep->error = E_OK;
+
+#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
+
+		/* éä¿¡ç«¯ç¹ãã­ãã¯ãè§£é¤ããã*/
+		syscall(sig_sem(cep->semid_lock));
+
+		/* ãã±ãããéä¿¡ããã*/
+		error = UDP_SEND_DATA(cep, p_dstaddr, data, len, tmout);
+
+#ifdef UDP_CFG_EXTENTIONS
+
+		/* å¾
+ã¡ä¸­ã«çºçããã¨ã©ã¼æ
+å ±ãè¿ãã*/
+		if (error == E_RLWAI)
+			error = cep->error;
+
+#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
+		}
+
+	return error;
+	}
+
+#endif	/* of #ifdef __udp_snd_dat */
+
+#ifdef __udp_rcv_dat
+
+/*
+ *  udp_rcv_dat -- ãã±ããã®åä¿¡ãæ¨æºæ©è½ã
+ */
+
+ER_UINT
+UDP_RCV_DAT (ID cepid, T_IPEP *p_dstaddr, void *data, int_t len, TMO tmout)
+{
+	T_NET_BUF	*input;
+	T_UDP_CEP	*cep;
+	T_UDP_HDR	*udph;
+	ER_UINT		error;
+	uint_t		ulen, uhoff;
+
+	/* p_dstaddr ã¾ãã¯ data ã NULL ãlen < 0 ããtmout ã TMO_NBLK ãªãã¨ã©ã¼ */
+	if (p_dstaddr == NULL || data == NULL || len < 0 || tmout == TMO_NBLK)
+		return E_PAR;
+
+	/* UDP éä¿¡ç«¯ç¹ ID ããã§ãã¯ããã*/
+	if (!VALID_UDP_CEPID(cepid))
+		return E_ID;
+
+	/* UDP éä¿¡ç«¯ç¹ãå¾ãã*/
+	cep = GET_UDP_CEP(cepid);
+
+	/* UDP éä¿¡ç«¯ç¹ããã§ãã¯ããã*/
+	if (!VALID_UDP_CEP(cep))
+		return E_NOEXS;
+
+	/* éä¿¡ç«¯ç¹ãã­ãã¯ããã*/
+	syscall(wai_sem(cep->semid_lock));
+
+	if (cep->rcv_tskid != TA_NULL) {
+
+		/* éãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ãã³ãã£ã³ã°ä¸­ */
+		error = E_QOVR;
+
+		/* éä¿¡ç«¯ç¹ãã­ãã¯ãè§£é¤ããã*/
+		syscall(sig_sem(cep->semid_lock));
+		}
+	else {
+
+		/* ç¾å¨ã®ã¿ã¹ã¯è­å¥å­ãè¨é²ããã*/
+		get_tid(&(cep->rcv_tskid));
+
+#ifdef UDP_CFG_EXTENTIONS
+
+		/* å¾
+ã¡ä¸­ã«çºçããã¨ã©ã¼æ
+å ±ããªã»ããããã*/
+		cep->error = E_OK;
+
+#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
+
+		/* éä¿¡ç«¯ç¹ãã­ãã¯ãè§£é¤ããã*/
+		syscall(sig_sem(cep->semid_lock));
+
+		/* å
+¥åãããã¾ã§å¾
+ã¤ã*/
+		if (cep->cb_netbuf != NULL) {
+
+			/*
+			 *  ããã«ããå ´åã¯ãã³ã¼ã«ããã¯é¢æ°ã®ä¸­ãã
+			 *  udp_rcv_dat ãå¼ã³åºãã¦ãããã¨ã«ãªãã
+			 *  ãã§ã«å
+¥åæ¸ã¿ã§ããã
+			 */
+			input = cep->cb_netbuf;
+			cep->cb_netbuf = NULL;
+			}
+		else if ((error = trcv_dtq(cep->rcvqid, (intptr_t*)&input, tmout)) != E_OK) {
+
+#ifdef UDP_CFG_EXTENTIONS
+
+			/* å¾
+ã¡ä¸­ã«çºçããã¨ã©ã¼æ
+å ±ãè¿ãã*/
+			if (error == E_RLWAI)
+				error = cep->error;
+
+#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
+
+			cep->rcv_tskid = TA_NULL;
+			return error;
+			}
+
+		/* p_dstaddr ãè¨­å®ããã*/
+		uhoff = (uint_t)GET_UDP_HDR_OFFSET(input);
+		udph = GET_UDP_HDR(input, uhoff);
+		p_dstaddr->portno = ntohs(udph->sport);
+		IN_COPY_TO_HOST(&p_dstaddr->ipaddr, input);
+
+		/* ãã¼ã¿ããããã¡ã«ç§»ãã*/
+		ulen = ntohs(udph->ulen);
+		if (ulen - UDP_HDR_SIZE > len)
+			error = E_BOVR;
+		else {
+			len   =    (uint_t)(ulen - UDP_HDR_SIZE);
+			error = (ER_UINT)(ulen - UDP_HDR_SIZE);
+			}
+
+		memcpy(data, GET_UDP_SDU(input, uhoff), (size_t)len);
+
+		syscall(rel_net_buf(input));
+
+		cep->rcv_tskid = TA_NULL;
+		}
+
+	return error;
+	}
+
+#endif	/* of #ifdef __udp_rcv_dat */
+
+#endif	/* of #ifdef UDP_CFG_NON_BLOCKING */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udpn_usrreq_nblk.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udpn_usrreq_nblk.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet/udpn_usrreq_nblk.c	(revision 331)
@@ -0,0 +1,427 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must ceproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)udp_usrreq.c	8.6 (Berkeley) 5/23/95
+ * $FreeBSD: src/sys/netinet/udp_usrreq.c,v 1.49.2.2 1999/08/29 16:29:58 peter Exp $
+ */
+
+#ifdef __udp_can_snd_nblk
+
+/*
+ *  udp_can_snd -- ãã³ãã£ã³ã°ãã¦ããéä¿¡ã®ã­ã£ã³ã»ã«
+ */
+
+ER
+UDP_CAN_SND (T_UDP_CEP *cep, ER error)
+{
+	if (cep->snd_p_dstaddr != NULL) {	/* ãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ãã³ãã£ã³ã°ä¸­ */
+		if (IS_PTR_DEFINED(cep->callback))
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+			(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_SND_DAT, (void*)error);
+#else
+			(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_SND_DAT, (void*)&error);
+#endif
+		else
+			error = E_OBJ;
+		cep->snd_p_dstaddr = NULL;
+		}
+	else if (cep->snd_tskid != TA_NULL) {	/* éãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ãã³ãã£ã³ã°ä¸­ */
+
+#ifdef UDP_CFG_EXTENTIONS
+
+		/* å¾
+ã¡ä¸­ã«çºçããã¨ã©ã¼æ
+å ±ãè¨­å®ããã*/
+		cep->error = error;
+
+#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
+
+		error = rel_wai(cep->snd_tskid);
+		cep->snd_tskid = TA_NULL;
+		}
+	else					/* ã©ã¡ãã§ããªããªããã³ãã£ã³ã°ãã¦ããªã */
+		error = EV_NOPND;
+
+	return error;
+	}
+
+#endif	/* of #ifdef __udp_can_snd_nblk */
+
+#ifdef __udp_can_rcv_nblk
+
+/*
+ *  udp_can_rcv -- ãã³ãã£ã³ã°ãã¦ããåä¿¡ã®ã­ã£ã³ã»ã«
+ */
+
+ER
+UDP_CAN_RCV (T_UDP_CEP *cep, ER error)
+{
+	if (cep->rcv_p_dstaddr != NULL) {	/* ãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ãã³ãã£ã³ã°ä¸­ */
+		if (IS_PTR_DEFINED(cep->callback))
+
+#ifdef TCP_CFG_NON_BLOCKING_COMPAT14
+			(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_RCV_DAT, (void*)error);
+#else
+			(*cep->callback)(GET_UDP_CEPID(cep), TFN_UDP_RCV_DAT, (void*)&error);
+#endif
+		else
+			error = E_OBJ;
+		cep->rcv_p_dstaddr = NULL;
+		}
+	else if (cep->rcv_tskid != TA_NULL) {	/* éãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ãã³ãã£ã³ã°ä¸­ */
+
+#ifdef UDP_CFG_EXTENTIONS
+
+		/* å¾
+ã¡ä¸­ã«çºçããã¨ã©ã¼æ
+å ±ãè¨­å®ããã*/
+		cep->error = error;
+
+#endif	/* of #ifdef UDP_CFG_EXTENTIONS */
+
+		error = rel_wai(cep->rcv_tskid);
+		cep->rcv_tskid = TA_NULL;
+		}
+	else					/* ã©ã¡ãã§ããªããªããã³ãã£ã³ã°ãã¦ããªã */
+		error = EV_NOPND;
+
+	return error;
+	}
+
+#endif	/* of #ifdef __udp_can_rcv_nblk */
+
+#ifdef __udp_snd_dat_nblk
+
+/*
+ *  udp_snd_dat -- ãã±ããã®éä¿¡ãæ¨æºæ©è½ã
+ */
+
+ER_UINT
+UDP_SND_DAT (ID cepid, T_IPEP *p_dstaddr, void *data, int_t len, TMO tmout)
+{
+	T_UDP_CEP	*cep;
+	ER		error;
+
+	/* p_dstaddr ã¾ãã¯ data ã NULL ãªãã¨ã©ã¼ */
+	if (p_dstaddr == NULL || data == NULL)
+		return E_PAR;
+
+	/* ãã¼ã¿é·ããã§ãã¯ããã*/
+	if (len < 0 || len + IP_HDR_SIZE + UDP_HDR_SIZE > IF_MTU)
+		return E_PAR;
+
+#if (API_PROTO == API_PROTO_IPV6) && !defined(API_CFG_IP4MAPPED_ADDR)
+
+	/*
+	 * API ã IPv6 ã§ IPv4 å°å½±ã¢ãã¬ã¹ãèªãããã¦ããªãã®ã«ããããããã
+	 * IPv4 å°å½±ã¢ãã¬ã¹ãæå®ããããã¨ã©ã¼
+	 */
+	if (in6_is_addr_ipv4mapped(&p_dstaddr->ipaddr))
+		return E_PAR;
+
+#endif	/* of #if (API_PROTO == API_PROTO_IPV6) && !defined(DAPI_CFG_IP4MAPPED_ADDR) */
+
+	/* UDP éä¿¡ç«¯ç¹ ID ããã§ãã¯ããã*/
+	if (!VALID_UDP_CEPID(cepid))
+		return E_ID;
+
+	/* UDP éä¿¡ç«¯ç¹ãå¾ãã*/
+	cep = GET_UDP_CEP(cepid);
+
+	/* UDP éä¿¡ç«¯ç¹ããã§ãã¯ããã*/
+	if (!VALID_UDP_CEP(cep))
+		return E_NOEXS;
+
+	/*
+	 *  èªãã¼ãçªå·ã UDP_PORTANY ãªããèªåã§å²ãå½ã¦ãã
+	 */
+	if (cep->myaddr.portno == UDP_PORTANY) {
+		if ((error = UDP_ALLOC_AUTO_PORT(cep)) != E_OK)
+			return error;
+		}
+
+	/*
+	 * ã¿ã¤ã ã¢ã¦ãããã§ãã¯ããã
+	 */
+	if (tmout == TMO_NBLK) {	/* ãã³ãã­ãã­ã³ã°ã³ã¼ã« */
+
+		/* éä¿¡ç«¯ç¹ãã­ãã¯ããã*/
+		syscall(wai_sem(cep->semid_lock));
+
+		if (cep->snd_p_dstaddr != NULL) {
+
+			/* ãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ãã³ãã£ã³ã°ä¸­ */
+			error = E_QOVR;
+
+			/* éä¿¡ç«¯ç¹ãã­ãã¯ãè§£é¤ããã*/
+			syscall(sig_sem(cep->semid_lock));
+			}
+		else if (cep->snd_tskid != TA_NULL) {
+
+			/* éãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ãã³ãã£ã³ã°ä¸­ */
+			error = E_OBJ;
+
+			/* éä¿¡ç«¯ç¹ãã­ãã¯ãè§£é¤ããã*/
+			syscall(sig_sem(cep->semid_lock));
+			}
+		else {
+
+			cep->snd_p_dstaddr = p_dstaddr;
+			cep->snd_data	= data;
+			cep->snd_len	= len;
+
+			/* éä¿¡ç«¯ç¹ãã­ãã¯ãè§£é¤ããã*/
+			syscall(sig_sem(cep->semid_lock));
+
+			cep->flags |= UDP_CEP_FLG_POST_OUTPUT;
+			sig_sem(SEM_UDP_POST_OUTPUT);
+			error = E_WBLK;
+			}
+		}
+	else {				/* éãã³ãã­ãã­ã³ã°ã³ã¼ã« */
+	
+		/* éä¿¡ç«¯ç¹ãã­ãã¯ããã*/
+		syscall(wai_sem(cep->semid_lock));
+
+		if (cep->snd_p_dstaddr != NULL) {
+
+			/* ãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ãã³ãã£ã³ã°ä¸­ */
+			error = E_OBJ;
+
+			/* éä¿¡ç«¯ç¹ãã­ãã¯ãè§£é¤ããã*/
+			syscall(sig_sem(cep->semid_lock));
+			}
+		else if (cep->snd_tskid != TA_NULL) {
+
+			/* éãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ãã³ãã£ã³ã°ä¸­ */
+			error = E_QOVR;
+
+			/* éä¿¡ç«¯ç¹ãã­ãã¯ãè§£é¤ããã*/
+			syscall(sig_sem(cep->semid_lock));
+			}
+		else {
+
+			/* ç¾å¨ã®ã¿ã¹ã¯è­å¥å­ãè¨é²ããã*/
+			get_tid(&(cep->snd_tskid));
+
+			/* éä¿¡ç«¯ç¹ãã­ãã¯ãè§£é¤ããã*/
+			syscall(sig_sem(cep->semid_lock));
+
+			/* ãã±ãããéä¿¡ããã*/
+			error = UDP_SEND_DATA(cep, p_dstaddr, data, len, tmout);
+			}
+		}
+
+	return error;
+	}
+
+#endif	/* of #ifdef __udp_snd_dat_nblk */
+
+#ifdef __udp_rcv_dat_nblk
+
+/*
+ *  udp_rcv_dat -- ãã±ããã®åä¿¡ãæ¨æºæ©è½ã
+ */
+
+ER_UINT
+UDP_RCV_DAT (ID cepid, T_IPEP *p_dstaddr, void *data, int_t len, TMO tmout)
+{
+	T_NET_BUF	*input;
+	T_UDP_CEP	*cep;
+	T_UDP_HDR	*udph;
+	ER_UINT		error;
+	uint_t		ulen, uhoff;
+
+	/* p_dstaddr ã¾ãã¯ data ã NULL ããlen < 0 ãªãã¨ã©ã¼ */
+	if (p_dstaddr == NULL || data == NULL || len < 0)
+		return E_PAR;
+
+	/* UDP éä¿¡ç«¯ç¹ ID ããã§ãã¯ããã*/
+	if (!VALID_UDP_CEPID(cepid))
+		return E_ID;
+
+	/* UDP éä¿¡ç«¯ç¹ãå¾ãã*/
+	cep = GET_UDP_CEP(cepid);
+
+	/* UDP éä¿¡ç«¯ç¹ããã§ãã¯ããã*/
+	if (!VALID_UDP_CEP(cep))
+		return E_NOEXS;
+
+	/*
+	 * ã¿ã¤ã ã¢ã¦ãããã§ãã¯ããã
+	 */
+
+	if (tmout == TMO_NBLK) {	/* ãã³ãã­ãã­ã³ã°ã³ã¼ã« */
+
+		/* éä¿¡ç«¯ç¹ãã­ãã¯ããã*/
+		syscall(wai_sem(cep->semid_lock));
+
+		if (cep->rcv_p_dstaddr != NULL)
+
+			/* ãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ãã³ãã£ã³ã°ä¸­ */
+			error = E_QOVR;
+
+		else if (cep->rcv_tskid != TA_NULL)
+
+			/* éãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ãã³ãã£ã³ã°ä¸­ */
+			error = E_OBJ;
+		else {
+			cep->rcv_p_dstaddr = p_dstaddr;
+			cep->rcv_data	= data;
+			cep->rcv_len	= len;
+			error = E_WBLK;
+			}
+
+		/* éä¿¡ç«¯ç¹ãã­ãã¯ãè§£é¤ããã*/
+		syscall(sig_sem(cep->semid_lock));
+		return error;
+		}
+	else {				/* éãã³ãã­ãã­ã³ã°ã³ã¼ã« */
+
+		/* éä¿¡ç«¯ç¹ãã­ãã¯ããã*/
+		syscall(wai_sem(cep->semid_lock));
+
+		if (cep->rcv_p_dstaddr != NULL) {
+
+			/* ãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ãã³ãã£ã³ã°ä¸­ */
+			error = E_OBJ;
+
+			/* éä¿¡ç«¯ç¹ãã­ãã¯ãè§£é¤ããã*/
+			syscall(sig_sem(cep->semid_lock));
+			}
+		else if (cep->rcv_tskid != TA_NULL) {
+
+			/* éãã³ãã­ãã­ã³ã°ã³ã¼ã«ã§ãã³ãã£ã³ã°ä¸­ */
+			error = E_QOVR;
+
+			/* éä¿¡ç«¯ç¹ãã­ãã¯ãè§£é¤ããã*/
+			syscall(sig_sem(cep->semid_lock));
+			}
+		else {
+
+			/* ç¾å¨ã®ã¿ã¹ã¯è­å¥å­ãè¨é²ããã*/
+			get_tid(&(cep->rcv_tskid));
+
+			/* éä¿¡ç«¯ç¹ãã­ãã¯ãè§£é¤ããã*/
+			syscall(sig_sem(cep->semid_lock));
+
+			/* å
+¥åãããã¾ã§å¾
+ã¤ã*/
+			if (cep->cb_netbuf != NULL) {
+
+				/*
+				 *  ããã«ããå ´åã¯ãã³ã¼ã«ããã¯é¢æ°ã®ä¸­ãã
+				 *  udp_rcv_dat ãå¼ã³åºãã¦ãããã¨ã«ãªãã
+				 *  ãã§ã«å
+¥åæ¸ã¿ã§ããã
+				 */
+				input = cep->cb_netbuf;
+				cep->cb_netbuf = NULL;
+				}
+			else if ((error = trcv_dtq(cep->rcvqid, (intptr_t*)&input, tmout)) != E_OK) {
+				cep->rcv_tskid = TA_NULL;
+				return error;
+				}
+
+			/* p_dstaddr ãè¨­å®ããã*/
+			uhoff = (uint_t)GET_UDP_HDR_OFFSET(input);
+			udph = GET_UDP_HDR(input, uhoff);
+			p_dstaddr->portno = ntohs(udph->sport);
+			IN_COPY_TO_HOST(&p_dstaddr->ipaddr, input);
+
+			/* ãã¼ã¿ããããã¡ã«ç§»ãã*/
+			ulen = ntohs(udph->ulen);
+			if (ulen - UDP_HDR_SIZE > len)
+				error = E_BOVR;
+			else {
+				len   =     (int_t)(ulen - UDP_HDR_SIZE);
+				error = (ER_UINT)(ulen - UDP_HDR_SIZE);
+				}
+
+			memcpy(data, GET_UDP_SDU(input, uhoff), (size_t)len);
+
+			syscall(rel_net_buf(input));
+
+			cep->rcv_tskid = TA_NULL;
+			}
+		return error;
+		}
+	}
+
+#endif	/* of #ifdef __udp_rcv_dat_nblk */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ah.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ah.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ah.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -67,6 +67,4 @@
 #define _AH_H_
 
-#ifdef SUPPORT_INET6
-
 /*
  *  RFC2402 認証ヘッダ
@@ -80,7 +78,5 @@
 	uint32_t	spi;	/* Security Parameter Index (SPI)	*/
 	uint32_t	seq;	/* シーケンス番号			*/
-	} __attribute__((packed, aligned(2)))T_IP6_AH_HDR;
-
-#endif	/* of #ifdef SUPPORT_INET6 */
+	} __attribute__((packed, aligned(2))) T_IP6_AH_HDR;
 
 #endif	/* of #ifndef _AH_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ah6.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ah6.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ah6.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -67,6 +67,4 @@
 #define _AH6_H_
 
-#ifdef SUPPORT_INET6
-
 /*
  *  関数
@@ -75,5 +73,3 @@
 extern uint_t ah6_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp);
 
-#endif	/* of #ifdef SUPPORT_INET6 */
-
 #endif	/* of #ifndef _AH6_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ah_input.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ah_input.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ah_input.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -82,4 +82,5 @@
 
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/if.h>
 #include <net/if_loop.h>
@@ -92,14 +93,13 @@
 
 #include <netinet/in.h>
-#include <netinet6/in6.h>
-#include <netinet6/in6_var.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
 #include <netinet6/nd6.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#include <netinet/icmp6.h>
 #include <netinet6/ah.h>
 #include <netinet6/ah6.h>
 
-#ifdef SUPPORT_INET6
+#ifdef _IP6_CFG
 
 /*
@@ -116,3 +116,3 @@
 	}
 
-#endif /* of #ifdef SUPPORT_INET6 */
+#endif /* of #ifdef _IP6_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/dest6.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/dest6.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/dest6.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -88,16 +88,16 @@
 #include <net/ppp_ipcp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_count.h>
 
 #include <netinet/in.h>
-#include <netinet6/in6.h>
-#include <netinet6/in6_var.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
 #include <netinet6/nd6.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#include <netinet/icmp6.h>
 
-#ifdef SUPPORT_INET6
+#ifdef _IP6_CFG
 
 /*
@@ -163,3 +163,3 @@
 	}
 
-#endif /* of #ifdef SUPPORT_INET6 */
+#endif /* of #ifdef _IP6_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/esp.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/esp.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/esp.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *  Copyright (C) 2008-2009 by Hokkaido Industrial Research Institute, JAPAN
@@ -68,6 +68,4 @@
 #define _ESP_H_
 
-#if defined(SUPPORT_INET6) || defined(SUPPORT_IPSEC)
-
 /*
  *  RFC2406 暗号化ヘッダ
@@ -129,5 +127,3 @@
 #endif	/* of #ifdef T_IPSEC_REQUEST_DEFINED */
 
-#endif /* defined(SUPPORT_INET6) || defined(SUPPORT_IPSEC) */
-
 #endif	/* of #ifndef _ESP_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/esp6.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/esp6.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/esp6.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -67,6 +67,4 @@
 #define _ESP6_H_
 
-#ifdef SUPPORT_INET6
-
 /*
  *  関数
@@ -75,5 +73,3 @@
 extern uint_t esp6_input (T_NET_BUF **inputp, uint_t *offp, uint_t *nextp);
 
-#endif	/* of #ifdef SUPPORT_INET6 */
-
 #endif	/* of #ifndef _ESP6_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/esp_input.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/esp_input.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/esp_input.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -88,14 +88,14 @@
 #include <net/ppp_ipcp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_count.h>
 
 #include <netinet/in.h>
-#include <netinet6/in6.h>
-#include <netinet6/in6_var.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
 #include <netinet6/nd6.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#include <netinet/icmp6.h>
 #include <netinet6/ah.h>
 #include <netinet6/ah6.h>
@@ -103,5 +103,5 @@
 #include <netinet6/esp6.h>
 
-#ifdef SUPPORT_INET6
+#ifdef _IP6_CFG
 
 /*
@@ -122,3 +122,3 @@
 	}
 
-#endif /* of #ifdef SUPPORT_INET6 */
+#endif /* of #ifdef _IP6_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/frag6.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/frag6.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/frag6.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -92,4 +92,5 @@
 #include <net/ppp_ipcp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_var.h>
@@ -97,12 +98,11 @@
 
 #include <netinet/in.h>
-#include <netinet6/in6.h>
-#include <netinet6/in6_var.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
 #include <netinet6/nd6.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#include <netinet/icmp6.h>
-
-#ifdef SUPPORT_INET6
+
+#ifdef _IP6_CFG
 
 #ifdef IP6_CFG_FRAGMENT
@@ -606,5 +606,5 @@
 			/* 送信先アドレスを元に戻す。*/
 			ip6h = GET_IP6_HDR(input);
-			ip6h->dst = ip6_frag_dest[ip6fq - ip6_frag_queue];
+			memcpy(&ip6h->dst, &ip6_frag_dest[ip6fq - ip6_frag_queue], sizeof(T_IN6_ADDR));
 
 			/* offp を、再構成した断片の先頭に設定する。*/
@@ -669,3 +669,3 @@
 	}
 
-#endif /* of #ifdef SUPPORT_INET6 */
+#endif /* of #ifdef _IP6_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/icmp6.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/icmp6.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/icmp6.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -106,4 +106,5 @@
 #include <sil.h>
 #include <t_syslog.h>
+#include "tinet_cfg.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_ASP */
@@ -113,4 +114,5 @@
 #include <s_services.h>
 #include <t_services.h>
+#include "tinet_id.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_JSP */
@@ -124,4 +126,5 @@
 #include <net/ethernet.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_timer.h>
@@ -130,15 +133,14 @@
 #include <netinet/in.h>
 #include <netinet/in_var.h>
-#include <netinet6/in6.h>
-#include <netinet6/in6_var.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#include <netinet/icmp6.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/udp_var.h>
+
 #include <netinet6/nd6.h>
-#include <netinet/tcp.h>
-#include <netinet/tcp_timer.h>
-#include <netinet/tcp_var.h>
-
-#ifdef SUPPORT_INET6
+
+#ifdef _IP6_CFG
 
 /*
@@ -178,5 +180,5 @@
 		return;
 		}
-	ip6h->src = ia->addr;
+	memcpy(&ip6h->src, &ia->addr, sizeof(T_IN6_ADDR));
 
 	icmp6h = GET_ICMP6_HDR(output, off);
@@ -241,7 +243,7 @@
 
 	/* IPv6 ヘッダの発信元アドレスと宛先アドレスを入替える。*/
-	dst 	  = ip6h->dst;
-	ip6h->dst = ip6h->src;
-	ip6h->src = dst;
+	memcpy(&dst, &ip6h->dst, sizeof(T_IN6_ADDR));
+	memcpy(&ip6h->dst, &ip6h->src, sizeof(T_IN6_ADDR));
+	memcpy(&ip6h->src, &dst, sizeof(T_IN6_ADDR));
 
 	/*
@@ -256,10 +258,10 @@
 			}
 		else
-			ip6h->src = ia->addr;
+			memcpy(&ip6h->src, &ia->addr, sizeof(T_IN6_ADDR));
 		}
 
 	/* 次ヘッダとホップリミットを設定する。*/
 	ip6h->next = IPPROTO_ICMPV6;
-	ip6h->hlim = IP_DEFTTL;
+	ip6h->hlim = IP6_DEFTTL;
 
 	/* チェックサムを計算する。*/
@@ -299,15 +301,26 @@
 	loff = ip6_lasthdr(input, poff + ICMP6_HDR_SIZE, IPPROTO_IPV6, &next);
 
-	/* 最終ヘッダが TCP のみ対応する。*/
-	if (loff >= 0 && next == IPPROTO_TCP) {
-
-#ifdef SUPPORT_TCP
+	/* 最終ヘッダが TCP/UDP のみ対応する。*/
+	if (loff >= 0 && (next == IPPROTO_TCP || next == IPPROTO_UDP)) {
 
 		memcpy(GET_IP6_HDR(input), input->buf + (loff + ICMP6_HDR_SIZE),
 		                           input->len - (loff + ICMP6_HDR_SIZE));
 		input->len -= loff + ICMP6_HDR_SIZE;
-		tcp_notify(input, icmp6h->code == ICMP6_DST_UNREACH_NOPORT ? EV_CNNRF : EV_HURCH);
-
-#endif	/* of #ifdef SUPPORT_TCP */
+
+#if defined(SUPPORT_TCP)
+
+		if (next == IPPROTO_TCP)
+
+			tcp_notify(input, icmp6h->code == ICMP6_DST_UNREACH_NOPORT ? EV_CNNRF : EV_HURCH);
+
+#endif	/* of #if defined(SUPPORT_TCP) */
+
+#if defined(SUPPORT_UDP) && TNUM_UDP6_CEPID > 0
+
+		if (next == IPPROTO_UDP)
+
+			udp6_notify(input, icmp6h->code == ICMP6_DST_UNREACH_NOPORT ? EV_CNNRF : EV_HURCH);
+
+#endif	/* of #if defined(SUPPORT_UDP) && TNUM_UDP6_CEPID > 0 */
 
 		}
@@ -340,5 +353,6 @@
 #endif	/* of #if NUM_IN6_HOSTCACHE_ENTRY > 0 */
 
-#if NUM_REDIRECT_ROUTE_ENTRY > 0
+#if defined(NUM_IN6_REDIRECT_ROUTE_ENTRY)
+#if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0
 
 /*
@@ -350,5 +364,5 @@
 {
 	T_IP6_HDR		*ip6h;
-	T_IN6_ADDR		*gw;
+	const T_IN6_ADDR	*gw;
 	T_ND_REDIRECT_HDR	*rdh;
 	T_ND_OPT_HDR		*opth;
@@ -440,5 +454,6 @@
 	}
 
-#endif	/* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
+#endif	/* of #if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0 */
+#endif	/* of #if defined(NUM_IN6_REDIRECT_ROUTE_ENTRY) */
 
 /*
@@ -472,5 +487,5 @@
 
 	/* チェックサムを計算する。*/
-	if ((in6_cksum(input, IPPROTO_ICMPV6, off, ntohs(ip6h->plen) - (off - IF_IP_HDR_SIZE)) & 0xffff) != 0) {
+	if ((in6_cksum(input, IPPROTO_ICMPV6, off, ntohs(ip6h->plen) - (off - IF_IP6_HDR_SIZE)) & 0xffff) != 0) {
 		NET_COUNT_ICMP6(net_count_icmp6[NC_ICMP6_IN_ERR_PACKETS], 1);
 		NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpInErrors, 1);
@@ -530,5 +545,6 @@
 		NET_COUNT_MIB(icmp6_ifstat.ipv6IfIcmpInRedirects, 1);
 
-#if NUM_REDIRECT_ROUTE_ENTRY > 0
+#if defined(NUM_IN6_REDIRECT_ROUTE_ENTRY)
+#if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0
 
 		if (code != 0 || len < ND_REDIRECT_HDR_SIZE)
@@ -537,9 +553,14 @@
 		return IPPROTO_DONE;
 
-#else	/* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
+#else	/* of #if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0 */
 
 		syslog(LOG_WARNING, "[ICMP6] redirect ignored.");
 
-#endif	/* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
+#endif	/* of #if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0 */
+#else	/* of #if defined(NUM_IN6_REDIRECT_ROUTE_ENTRY) */
+
+		syslog(LOG_WARNING, "[ICMP6] redirect ignored.");
+
+#endif	/* of #if defined(NUM_IN6_REDIRECT_ROUTE_ENTRY) */
 
 		break;
@@ -571,5 +592,5 @@
 	case ICMP6_FQDN_QUERY:			/* FQDN 照会			*/
 	case ICMP6_FQDN_REPLY:			/* FQDN 応答			*/
-		syslog(LOG_WARNING, "[ICMP6] unsupported type: %d.", icmp6h->type);
+		syslog(LOG_INFO, "[ICMP6] unsupported type: %d.", icmp6h->type);
 		break;
 
@@ -693,3 +714,3 @@
 	}
 
-#endif /* of #ifdef SUPPORT_INET6 */
+#endif /* of #ifdef _IP6_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/if6_ether.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/if6_ether.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/if6_ether.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -87,4 +87,5 @@
 #include <net/if_arp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_timer.h>
 #include <net/net_buf.h>
@@ -92,4 +93,5 @@
 
 #include <netinet/in.h>
+#include <netinet/in_var.h>
 #include <netinet/ip.h>
 #include <netinet/if_ether.h>
@@ -98,7 +100,7 @@
 #include <netinet6/in6_var.h>
 
-#include <net/if6_var.h>
+#include <net/if_var.h>
 
-#if defined(SUPPORT_INET6) && defined(SUPPORT_ETHER)
+#if defined(_IP6_CFG) && defined(SUPPORT_ETHER)
 
 /*
@@ -107,5 +109,5 @@
 
 void
-ether_map_ipv6_multicast (T_ETHER_ADDR *eaddr, T_IN6_ADDR *maddr)
+ether_map_ipv6_multicast (T_ETHER_ADDR *eaddr, const T_IN6_ADDR *maddr)
 {
 	eaddr->lladdr[0] = UINT_C(0x33);
@@ -117,3 +119,3 @@
 	}
 
-#endif /* of #if defined(SUPPORT_INET6) && defined(SUPPORT_ETHER) */
+#endif /* of #if defined(_IP6_CFG) && defined(SUPPORT_ETHER) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/if6_ether.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/if6_ether.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/if6_ether.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -68,13 +68,9 @@
 #define _IF6_ETHER_H_
 
-#ifdef SUPPORT_INET6
-
 /*
  *  関数
  */
 
-extern void ether_map_ipv6_multicast (T_ETHER_ADDR *eaddr, T_IN6_ADDR *maddr);
-
-#endif	/* of #ifdef SUPPORT_INET6 */
+extern void ether_map_ipv6_multicast (T_ETHER_ADDR *eaddr, const T_IN6_ADDR *maddr);
 
 #endif	/* of #ifndef _IF6_ETHER_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -126,7 +126,11 @@
 #include <net/ppp_ipcp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_timer.h>
 #include <net/net_count.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
 
 #include <netinet6/in6.h>
@@ -135,7 +139,7 @@
 #include <netinet6/in6_ifattach.h>
 
-#include <net/if6_var.h>
-
-#ifdef SUPPORT_INET6
+#include <net/if_var.h>
+
+#ifdef _IP6_CFG
 
 /*
@@ -143,11 +147,11 @@
  */
 
-T_IN6_ADDR in6_addr_unspecified =
+const T_IN6_ADDR in6_addr_unspecified =
 	IPV6_ADDR_UNSPECIFIED_INIT;
 
-T_IN6_ADDR in6_addr_linklocal_allnodes =
+const T_IN6_ADDR in6_addr_linklocal_allnodes =
 	IPV6_ADDR_LINKLOCAL_ALLNODES_INIT;
 
-T_IN6_ADDR in6_addr_linklocal_allrouters =
+const T_IN6_ADDR in6_addr_linklocal_allrouters =
 	IPV6_ADDR_LINKLOCAL_ALLROUTERS_INIT;
 
@@ -172,5 +176,5 @@
 
 static ER
-in6_ifinit (T_IFNET *ifp, T_IN6_IFADDR *ia, T_IN6_ADDR *addr, uint_t prefix_len)
+in6_ifinit (T_IFNET *ifp, T_IN6_IFADDR *ia, const T_IN6_ADDR *addr, uint_t prefix_len)
 {
 	/* アドレスとプレフィックス長を設定する。*/
@@ -200,5 +204,5 @@
 
 	for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
-		ia = &ifp->in_ifaddrs[ix];
+		ia = &ifp->in6_ifaddrs[ix];
 		memset(ia, sizeof(T_IN6_IFADDR), 0);
 		ia->router_index = IN6_RTR_IX_UNREACH;
@@ -226,5 +230,5 @@
 
 int_t
-in6_addr2ifaix (T_IN6_ADDR *addr)
+in6_addr2ifaix (const T_IN6_ADDR *addr)
 {
 	T_IFNET		*ifp = IF_GET_IFNET();
@@ -233,5 +237,5 @@
 
 	for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
-		ia = &ifp->in_ifaddrs[ix];
+		ia = &ifp->in6_ifaddrs[ix];
 		if ((ia->flags & IN6_IFF_DEFINED) != 0 &&
 		    in6_are_prefix_equal(addr, &ia->addr, ia->prefix_len))
@@ -247,5 +251,5 @@
 
 int_t
-in6_addr2maix (T_IN6_ADDR *addr)
+in6_addr2maix (const T_IN6_ADDR *addr)
 {
 	if (addr->s6_addr8[0] == 0xff) {
@@ -268,5 +272,5 @@
 
 ER
-in6_update_ifa (T_IFNET *ifp, T_IN6_IFADDR *ia, T_IN6_ADDR *addr,
+in6_update_ifa (T_IFNET *ifp, T_IN6_IFADDR *ia, const T_IN6_ADDR *addr,
                 uint_t prefix_len, uint32_t vltime, uint32_t pltime,
                 int_t router_index, int_t prefix_index, uint_t flags)
@@ -365,5 +369,5 @@
 in6ifa_ifpwithix (T_IFNET *ifp, int_t ix)
 {
-	return ix < NUM_IN6_IFADDR_ENTRY? &ifp->in_ifaddrs[ix] : NULL;
+	return ix < NUM_IN6_IFADDR_ENTRY? &ifp->in6_ifaddrs[ix] : NULL;
 	}
 
@@ -379,16 +383,16 @@
 
 	for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; )
-		if (ifp->in_ifaddrs[ix].router_index == router_index)
-			return &ifp->in_ifaddrs[ix];
+		if (ifp->in6_ifaddrs[ix].router_index == router_index)
+			return &ifp->in6_ifaddrs[ix];
 	return NULL;
 	}
 
 /*
- * in6_ifawithifp -- 宛先アドレスにふさわしい送信元アドレスを、
+ * in6_ifawithifp -- 宛先アドレスにふさわしい送信元アドレス情報を、
  *                   ネットワークインタフェースから探索する。
  */
 
 T_IN6_IFADDR *
-in6_ifawithifp (T_IFNET *ifp, T_IN6_ADDR *dst)
+in6_ifawithifp (T_IFNET *ifp, const T_IN6_ADDR *dst)
 {
 	uint_t	scope;
@@ -397,18 +401,36 @@
 	/* 宛先アドレスと同じスコープのアドレスを返す。*/
 	if ((ix = in6_addr2ifaix(dst)) != IPV6_IFADDR_IX_INVALID)
-		return &ifp->in_ifaddrs[ix];
+		return &ifp->in6_ifaddrs[ix];
 	else if ((ix = in6_addr2maix(dst)) == IPV6_MADDR_IX_SOL_NODE ||
 	          ix                       == IPV6_MADDR_IX_LL_ALL_NODE)
-		return &ifp->in_ifaddrs[IPV6_IFADDR_IX_LINKLOCAL];
+		return &ifp->in6_ifaddrs[IPV6_IFADDR_IX_LINKLOCAL];
 	else {
 		scope = in6_addrscope(dst);
 		for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
-			if ((ifp->in_ifaddrs[ix].flags & IN6_IFF_DEFINED) &&
-			    (ifp->in_ifaddrs[ix].flags & IN6_IFF_DETACHED) == 0 &&
-			    in6_addrscope(&ifp->in_ifaddrs[ix].addr) == scope) {
-				return &ifp->in_ifaddrs[ix];
+			if ((ifp->in6_ifaddrs[ix].flags & IN6_IFF_DEFINED) &&
+			    (ifp->in6_ifaddrs[ix].flags & IN6_IFF_DETACHED) == 0 &&
+			    in6_addrscope(&ifp->in6_ifaddrs[ix].addr) == scope) {
+				return &ifp->in6_ifaddrs[ix];
 				}
 			}
 		return NULL;
+		}
+	}
+
+/*
+ * in6_addrwithifp -- 宛先アドレスにふさわしい送信元アドレスを、
+ *                    ネットワークインタフェースから探索する。
+ */
+
+const T_IN6_ADDR *
+in6_addrwithifp (T_IFNET *ifp, T_IN6_ADDR *src, const T_IN6_ADDR *dst)
+{
+	T_IN6_IFADDR *ifaddr;
+
+	if ((ifaddr = in6_ifawithifp(ifp, dst)) == NULL)
+		return NULL;
+	else {
+		*src = ifaddr->addr;
+		return src;
 		}
 	}
@@ -431,7 +453,7 @@
 	dad_delay = 0;
 	for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; )
-		if ((ifp->in_ifaddrs[ix].flags & IN6_IFF_DEFINED) &&
-		    (ifp->in_ifaddrs[ix].flags & IN6_IFF_TENTATIVE))
-			nd6_dad_start(ifp, &ifp->in_ifaddrs[ix], &dad_delay);
+		if ((ifp->in6_ifaddrs[ix].flags & IN6_IFF_DEFINED) &&
+		    (ifp->in6_ifaddrs[ix].flags & IN6_IFF_TENTATIVE))
+			nd6_dad_start(ifp, &ifp->in6_ifaddrs[ix], &dad_delay);
 #endif	/* of #if 0 */
 
@@ -449,5 +471,5 @@
 
 bool_t
-in6_are_prefix_equal (T_IN6_ADDR *addr, T_IN6_ADDR *prefix, uint_t prefix_len)
+in6_are_prefix_equal (const T_IN6_ADDR *addr, const T_IN6_ADDR *prefix, uint_t prefix_len)
 {
 	uint_t bitlen, bytelen;
@@ -478,5 +500,5 @@
 	syscall(get_tim(&now));
 	for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
-		ia = &ifp->in_ifaddrs[ix];
+		ia = &ifp->in6_ifaddrs[ix];
 
 		if ((ia->flags & IN6_IFF_DEFINED) == 0)
@@ -500,3 +522,3 @@
 	}
 
-#endif /* of #ifdef SUPPORT_INET6 */
+#endif /* of #ifdef _IP6_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -103,4 +103,10 @@
 
 /*
+ *  IPv6 アドレス構造
+ *
+ *    RFC4291（RFC1884、RFC2373、RFC3513 のアップデート）
+ */
+
+/*
  *  IPv6 アドレス
  */
@@ -150,38 +156,4 @@
 
 /*
- *  アドレスの定義
- */
-
-#ifdef _NET_CFG_BYTE_ORDER
-
-#if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN
-
-#define IPV6_ADDR_INT32_ONE		ULONG_C(0x00000001)
-#define IPV6_ADDR_INT32_TWO		ULONG_C(0x00000002)
-#define IPV6_ADDR_INT32_0000FFFF	ULONG_C(0x0000ffff)
-#define IPV6_ADDR_INT32_MNL		ULONG_C(0xff010000)
-#define IPV6_ADDR_INT32_MLL		ULONG_C(0xff020000)
-#define IPV6_ADDR_INT32_ULL		ULONG_C(0xfe800000)
-#define IPV6_ADDR_INT16_ULL		UINT_C(0xfe80)
-#define IPV6_ADDR_INT16_USL		UINT_C(0xfec0)
-#define IPV6_ADDR_INT16_MLL		UINT_C(0xff02)
-
-#elif _NET_CFG_BYTE_ORDER == _NET_CFG_LITTLE_ENDIAN
-
-#define IPV6_ADDR_INT32_ONE		ULONG_C(0x01000000)
-#define IPV6_ADDR_INT32_TWO		ULONG_C(0x02000000)
-#define IPV6_ADDR_INT32_0000FFFF	ULONG_C(0xffff0000)
-#define IPV6_ADDR_INT32_MNL		ULONG_C(0x000001ff)
-#define IPV6_ADDR_INT32_MLL		ULONG_C(0x000002ff)
-#define IPV6_ADDR_INT32_ULL		ULONG_C(0x000080fe)
-#define IPV6_ADDR_INT16_ULL		UINT_C(0x80fe)
-#define IPV6_ADDR_INT16_USL		UINT_C(0xc0fe)
-#define IPV6_ADDR_INT16_MLL		UINT_C(0x02ff)
-
-#endif	/* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
-
-#endif	/* of #ifdef _NET_CFG_BYTE_ORDER */
-
-/*
  *  特別なアドレスのチェック
  */
@@ -197,17 +169,4 @@
 	(memcmp((void *)(a), (void *)&in6_addr_unspecified, sizeof(T_IN6_ADDR) - 1) == 0 && \
 	 (a)->s6_addr8[15] == 0x01)
-
-/* IPv4 互換 */
-
-#define IN6_IS_ADDR_V4COMPAT(a)		\
-	(memcmp((void *)(a), (void *)&in6_addr_unspecified, sizeof(T_IN6_ADDR) - 4) == 0 && \
-	 (a)->s6_addr32[3] > IPV6_ADDR_INT32_ONE)
-
-/* IPv4 マップ */
-
-#define IN6_IS_ADDR_V4MAPPED(a)		\
-	(((a)->s6_addr32[0] == ULONG_C(0x00000000)) && \
-	 ((a)->s6_addr32[1] == ULONG_C(0x00000000)) && \
-	 ((a)->s6_addr32[2] == IPV6_ADDR_INT32_0000FFFF))
 
 /*
@@ -248,12 +207,4 @@
 #define IN6_IS_ADDR_MULTICAST(a)	((a)->s6_addr8[0] == UINT_C(0xff))
 
-/* 要請マルチキャスト */
-
-#define IN6_IS_ADDR_NS_MULTICAST(a)	\
-	(((a)->s6_addr32[0] == IPV6_ADDR_INT32_MLL) && \
-	 ((a)->s6_addr32[1] == ULONG_C(0x00000000)) && \
-	 ((a)->s6_addr32[2] == IPV6_ADDR_INT32_ONE) && \
-	 ((a)->s6_addr8[12] == UINT_C(0xff)))
-
 /*
  *  同一のチェック
@@ -272,5 +223,6 @@
  */
 
-#define IPV6_DEFAULT_MULTICAST_HOPS	1	/* マルチキャスト時のホップリミットの規定値 */
+#define IPV6_DEFAULT_MULTICAST_HOPS	1	/* マルチキャスト時のホップリミットの規定値	*/
+#define ND6_INFINITE_LIFETIME		0xffffffff	/* アドレスの無制限有効時間		*/
 
 /*
@@ -282,4 +234,6 @@
 	uint16_t	portno;		/* ポート番号	*/
 	} T_IPV6EP;
+
+#define T_IPV6EP_DEFINED
 
 /*
@@ -299,8 +253,4 @@
 	/* 実装依存 */
 	} T_TCP6_CREP;
-
-#if defined(SUPPORT_INET6)
-#define T_TCP_CREP	T_TCP6_CREP
-#endif
 
 /*
@@ -316,28 +266,4 @@
 	} T_UDP6_CCEP;
 
-#if defined(SUPPORT_INET6)
-#define T_UDP_CCEP	T_UDP6_CCEP
-#endif
-
-/*
- *  IPv4 と IPv6 をコンパイル時に選択するためのマクロ
- */
-
-#if defined(SUPPORT_INET6)
-
-#define T_IN_ADDR			T_IN6_ADDR
-#define T_IPEP				T_IPV6EP
-#define IP_ADDRANY			IPV6_ADDRANY
-
-#define IN_ARE_ADDR_EQUAL(n,h)		IN6_ARE_ADDR_EQUAL(n,h)
-#define IN_ARE_NET_ADDR_EQUAL(n,h)	IN6_ARE_ADDR_EQUAL(n,h)
-#define IN_COPY_TO_NET(d,s)		memcpy(d,s,sizeof(T_IN6_ADDR))
-#define IN_COPY_TO_HOST(d,s)		memcpy(d,s,sizeof(T_IN6_ADDR))
-#define IN_IS_ADDR_MULTICAST(a)		IN6_IS_ADDR_MULTICAST(a)
-#define IN_IS_NET_ADDR_MULTICAST(a)	IN6_IS_ADDR_MULTICAST(a)
-#define IN_IS_ADDR_ANY(a)		IN6_IS_ADDR_UNSPECIFIED(a)
-
-#endif	/* of #if defined(SUPPORT_INET6) */
-
 /*
  *  前方参照
@@ -356,7 +282,7 @@
  */
 
-extern T_IN6_ADDR in6_addr_unspecified;
-extern T_IN6_ADDR in6_addr_linklocal_allnodes;
-extern T_IN6_ADDR in6_addr_linklocal_allrouters;
+extern const T_IN6_ADDR in6_addr_unspecified;
+extern const T_IN6_ADDR in6_addr_linklocal_allnodes;
+extern const T_IN6_ADDR in6_addr_linklocal_allrouters;
 
 #define ipv6_addrany	in6_addr_unspecified
@@ -366,7 +292,12 @@
  */
 
-extern char *ipv62str (char *buf, const T_IN6_ADDR *p_ip6addr);
-extern ER_UINT in6_get_maxnum_ifaddr (void);
+extern char *ipv62str (char *buf, const T_IN6_ADDR *p_addr);
+extern uint_t in6_get_maxnum_ifaddr (void);
 extern const T_IN6_ADDR *in6_get_ifaddr (int_t index);
+extern ER in6_upd_ifaddr (T_IN6_ADDR *addr, uint_t prefixlen,
+                          uint32_t vltime, uint32_t pltime);
+extern ER in6_del_ifaddr (T_IN6_ADDR *addr);
+extern T_IN6_ADDR *in6_make_ipv4mapped (T_IN6_ADDR *dst, T_IN4_ADDR src);
+extern bool_t in6_is_addr_ipv4mapped (const T_IN6_ADDR *addr);
 
 #endif	/* of #ifndef _IN6_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6_ifattach.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6_ifattach.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6_ifattach.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -87,4 +87,8 @@
 #include <net/if_arp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
 
 #include <netinet6/in6.h>
@@ -93,7 +97,7 @@
 #include <netinet6/in6_ifattach.h>
 
-#include <net/if6_var.h>
-
-#ifdef SUPPORT_INET6
+#include <net/if_var.h>
+
+#ifdef _IP6_CFG
 
 /*
@@ -126,4 +130,18 @@
 #endif	/* of #ifdef SUPPORT_ETHER */
 
+#ifdef SUPPORT_PPP
+
+/*
+ * get_rand_ifid -- 乱数により、インタフェース識別子を設定する。
+ */
+
+static ER
+get_rand_ifid (T_IFNET *ifp, T_IN6_ADDR *ifra_addr)
+{
+	return E_OK;
+	}
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
 #ifdef IP6_CFG_AUTO_LINKLOCAL
 
@@ -149,5 +167,5 @@
 
 	/* インタフェースのアドレス情報を更新する。*/
-	if ((error = in6_update_ifa(ifp, &ifp->in_ifaddrs[IPV6_IFADDR_IX_LINKLOCAL],
+	if ((error = in6_update_ifa(ifp, &ifp->in6_ifaddrs[IPV6_IFADDR_IX_LINKLOCAL],
 	                            &addr, 64, ND6_INFINITE_LIFETIME,
 	                                       ND6_INFINITE_LIFETIME, 
@@ -171,5 +189,5 @@
 #ifdef IP6_CFG_AUTO_LINKLOCAL
 
-	if ((ifp->in_ifaddrs[IPV6_IFADDR_IX_LINKLOCAL].flags & IN6_IFF_DEFINED) == 0)
+	if ((ifp->in6_ifaddrs[IPV6_IFADDR_IX_LINKLOCAL].flags & IN6_IFF_DEFINED) == 0)
 		if ((error = in6_ifattach_linklocal(ifp)) != E_OK)
 			return error;
@@ -180,3 +198,3 @@
 	}
 
-#endif /* of #ifdef SUPPORT_INET6 */
+#endif /* of #ifdef _IP6_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6_ifattach.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6_ifattach.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6_ifattach.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6_rename.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6_rename.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6_rename.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -41,20 +41,17 @@
 /* netinet6/in6.c */
 
+#define in6_are_prefix_equal	_tinet_in6_are_prefix_equal
+#define in6ifa_ifpwithrtrix	_tinet_in6ifa_ifpwithrtrix
+#define in6_if_up		_tinet_in6_if_up
+#define in6_if2idlen		_tinet_in6_if2idlen
+#define in6_ifaddr_timer	_tinet_in6_ifaddr_timer
+#define in6ifa_ifpwithix	_tinet_in6ifa_ifpwithix
+#define in6_addr2maix		_tinet_in6_addr2maix
+#define in6_ifawithifp		_tinet_in6_ifawithifp
+#define in6_addr2ifaix		_tinet_in6_addr2ifaix
+#define in6_update_ifa		_tinet_in6_update_ifa
+#define in6_ifainit		_tinet_in6_ifainit
+#define in6_addrwithifp		_tinet_in6_addrwithifp
 #define in6_addr_loopback	_tinet_in6_addr_loopback
-#define in6_ifainit		_tinet_in6_ifainit
-#define in6_addr2ifaix		_tinet_in6_addr2ifaix
-#define in6_addr2maix		_tinet_in6_addr2maix
-#define in6_update_ifa		_tinet_in6_update_ifa
-#define in6ifa_ifpwithix	_tinet_in6ifa_ifpwithix
-#define in6ifa_ifpwithrtrix	_tinet_in6ifa_ifpwithrtrix
-#define in6_ifawithifp		_tinet_in6_ifawithifp
-#define in6_if_up		_tinet_in6_if_up
-#define in6_rtalloc		_tinet_in6_rtalloc
-#define in6_are_prefix_equal	_tinet_in6_are_prefix_equal
-#define in6_addr_linklocal_allrouters	\
-				_tinet_in6_addr_linklocal_allrouters
-#define in6_addr_linklocal_allnodes	\
-				_tinet_in6_addr_linklocal_allnodes
-#define in6_ifaddr_timer	_tinet_in6_ifaddr_timer
 
 /* netinet6/in6_ifattach.c */
@@ -64,17 +61,23 @@
 /* netinet6/in6_subr.c */
 
+#define inn6_is_dstaddr_accept	_tinet_inn6_is_dstaddr_accept
+#define in6_lookup_ifaddr	_tinet_in6_lookup_ifaddr
+#define in6_rtalloc		_tinet_in6_rtalloc
+#define in6_get_ifaddr		_tinet_in6_get_ifaddr
+#define in6_cksum		_tinet_in6_cksum
+#define in6_gateway_lookup	_tinet_in6_gateway_lookup
+#define in6_is_dstaddr_accept	_tinet_in6_is_dstaddr_accept
+#define in6_hostcache_getmtu	_tinet_in6_hostcache_getmtu
+#define in6_set_header		_tinet_in6_set_header
+#define in6_get_datagram	_tinet_in6_get_datagram
+#define in6_rtredirect		_tinet_in6_rtredirect
+#define get_ip6_hdr_size	_tinet_get_ip6_hdr_size
+#define in6_plen2pmask		_tinet_in6_plen2pmask
+#define in6_rtnewentry		_tinet_in6_rtnewentry
+#define in6_rtinit		_tinet_in6_rtinit
+#define in6_rttimer		_tinet_in6_rttimer
 #define in6_lookup_multi	_tinet_in6_lookup_multi
-#define get_ip6_hdr_size	_tinet_get_ip6_hdr_size
-#define in6_lookup_ifaddr	_tinet_in6_lookup_ifaddr
-#define in6_get_datagram	_tinet_in6_get_datagram
-#define in6_cksum		_tinet_in6_cksum
-#define in6_is_dstaddr_accept	_tinet_in6_is_dstaddr_accept
-#define in6_plen2pmask		_tinet_in6_plen2pmask
+#define in6_hostcache_update	_tinet_in6_hostcache_update
 #define in6_init		_tinet_in6_init
-#define in6_rtredirect		_tinet_in6_rtredirect
-#define in6_gateway_lookup	_tinet_in6_gateway_lookup
-#define in6_set_header		_tinet_in6_set_header
-#define in6_hostcache_getmtu	_tinet_in6_hostcache_getmtu
-#define in6_hostcache_update	_tinet_in6_hostcache_update
 
 /* netinet6/if6_ether.c */
@@ -151,9 +154,17 @@
 /* netinet6/nd6_rtr.c */
 
+#define nd6_get_prl		_tinet_nd6_get_prl
 #define nd6_router_lookup	_tinet_nd6_router_lookup
+#define nd6_onlink_prefix_lookup	\
+				_tinet_nd6_onlink_prefix_lookup
+#define nd6_defrtrlist_del	_tinet_nd6_defrtrlist_del
+#define nd6_prefix_onlink	_tinet_nd6_prefix_onlink
+#define nd6_get_drl		_tinet_nd6_get_drl
+#define nd6_rtrsol_ctl		_tinet_nd6_rtrsol_ctl
 #define nd6_defrtrlist_timer	_tinet_nd6_defrtrlist_timer
+#define nd6_ra_input		_tinet_nd6_ra_input
 #define nd6_prelist_timer	_tinet_nd6_prelist_timer
-#define nd6_ra_input		_tinet_nd6_ra_input
-#define nd6_rtrsol_ctl		_tinet_nd6_rtrsol_ctl
+#define nd6_prefix_offlink	_tinet_nd6_prefix_offlink
+#define nd6_defrtrlist_lookup	_tinet_nd6_defrtrlist_lookup
 #define ip6_defhlim		_tinet_ip6_defhlim
 #define nd6_reachable_time	_tinet_nd6_reachable_time
@@ -162,10 +173,4 @@
 				_tinet_nd6_recalc_reachtm_interval
 #define nd6_retrans_time	_tinet_nd6_retrans_time
-#define nd6_defrtrlist_lookup	_tinet_nd6_defrtrlist_lookup
-#define nd6_prefix_onlink	_tinet_nd6_prefix_onlink
-#define nd6_prefix_offlink	_tinet_nd6_prefix_offlink
-#define nd6_get_prl		_tinet_nd6_get_prl
-#define nd6_get_drl		_tinet_nd6_get_drl
-#define nd6_defrtrlist_del	_tinet_nd6_defrtrlist_del
 
 /* netinet6/scope6.c */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6_subr.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6_subr.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6_subr.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -122,4 +122,5 @@
 #include <net/if_arp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_var.h>
 #include <net/net_buf.h>
@@ -128,15 +129,128 @@
 #include <netinet/in.h>
 #include <netinet/in_var.h>
-
-#include <netinet6/in6.h>
-#include <netinet6/in6_var.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+
+#include <netinet6/nd6.h>
 #include <netinet6/ah.h>
-#include <netinet6/nd6.h>
-
-#include <net/if6_var.h>
-
-#ifdef SUPPORT_INET6
+
+#include <net/if_var.h>
+
+/*
+ *  in6_make_ipv4mapped -- IPv4 射影アドレスを生成する。
+ *
+ *  注意:
+ *    src はホストバイトオーダー
+ *
+ */
+
+T_IN6_ADDR *
+in6_make_ipv4mapped (T_IN6_ADDR *dst, T_IN4_ADDR src)
+{
+	dst->s6_addr32[0] = ULONG_C(0x00000000);
+	dst->s6_addr32[1] = ULONG_C(0x00000000);
+	dst->s6_addr32[2] = IPV6_ADDR_INT32_0000FFFF;
+	dst->s6_addr32[3] = htonl(src);
+
+	return dst;
+	}
+
+#ifdef _IP6_CFG
+
+#if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0
+
+/*
+ *  in6_rtinit -- ルーティング表を初期化する。
+ */
+
+void
+in6_rtinit (void)
+{
+	int_t ix;
+
+	for (ix = 0; ix < NUM_IN6_STATIC_ROUTE_ENTRY; ix ++)
+		routing6_tbl[ix].flags = IN_RTF_DEFINED;
+
+	for ( ; ix < NUM_IN6_ROUTE_ENTRY; ix ++)
+		routing6_tbl[ix].flags = 0;
+	}
+
+/*
+ *  in6_rtnewentry -- 新しいエントリを獲得する。
+ */
+
+T_IN6_RTENTRY *
+in6_rtnewentry (uint8_t flags, uint32_t tmo)
+{
+	SYSTIM		now;
+	T_IN6_RTENTRY	*rt, *frt = NULL;
+	int_t		ix;
+
+	/* 空きエントリを探す。*/
+	for (ix = NUM_IN6_STATIC_ROUTE_ENTRY; ix < NUM_IN6_ROUTE_ENTRY; ix ++) {
+		rt = &routing6_tbl[ix];
+		if ((routing6_tbl[ix].flags & IN_RTF_DEFINED) == 0) {
+			frt = rt;
+			break;
+			}
+		}
+
+	/* expire の単位は [s]。*/
+	syscall(get_tim(&now));
+	now /= SYSTIM_HZ;
+
+	if (frt == NULL) {
+		/* 空きがなければ、有効時間がもっとも短いエントリを空きにする。*/
+		T_IN6_RTENTRY	*srt = NULL;
+		int_t		diff, sdiff = INT_MAX;
+
+		syscall(wai_sem(SEM_IN6_ROUTING_TBL));
+		for (ix = NUM_IN6_STATIC_ROUTE_ENTRY; ix < NUM_IN6_ROUTE_ENTRY; ix ++) {
+			rt = &routing6_tbl[ix];
+			diff = (int_t)(rt->expire - now);
+			if (diff <= 0) {	/* rt->expire <= now */
+				/* 既に、有効時間が過ぎている。*/
+				frt = rt;
+				break;
+				}
+			else if (diff < sdiff) {
+				srt = rt;
+				sdiff = diff;
+				}
+			}
+		if (frt == NULL)
+			frt = srt;
+		frt->flags = 0;
+		syscall(sig_sem(SEM_IN6_ROUTING_TBL));
+		}
+
+	frt->flags  = (uint8_t)(flags | IN_RTF_DEFINED);
+	frt->expire = now + tmo / SYSTIM_HZ;
+	return frt;
+	}
+
+/*
+ *  in6_rttimer -- ルーティング表の管理タイマー
+ */
+
+void
+in6_rttimer (void)
+{
+	SYSTIM	now;
+	int_t	ix;
+
+	/* expire の単位は [s]。*/
+	syscall(get_tim(&now));
+	now /= SYSTIM_HZ;
+
+	syscall(wai_sem(SEM_IN6_ROUTING_TBL));
+	for (ix = NUM_IN6_STATIC_ROUTE_ENTRY; ix < NUM_IN6_ROUTE_ENTRY; ix ++)
+		if ((routing6_tbl[ix].flags & IN_RTF_DEFINED) &&
+		    (int_t)(routing6_tbl[ix].expire - now) <= 0)
+			routing6_tbl[ix].flags = 0;
+	syscall(sig_sem(SEM_IN6_ROUTING_TBL));
+	}
+
+#endif	/* of #if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0 */
 
 #if NUM_IN6_HOSTCACHE_ENTRY > 0
@@ -155,12 +269,12 @@
 
 T_IN6_IFADDR *
-in6_lookup_ifaddr (T_IFNET *ifp, T_IN6_ADDR *addr)
+in6_lookup_ifaddr (T_IFNET *ifp, const T_IN6_ADDR *addr)
 {
 	int_t ix;
 
 	for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
-		if ((ifp->in_ifaddrs[ix].flags & IN6_IFF_DEFINED) &&
-		    IN6_ARE_ADDR_EQUAL(addr, &ifp->in_ifaddrs[ix].addr))
-			return &ifp->in_ifaddrs[ix];
+		if ((ifp->in6_ifaddrs[ix].flags & IN6_IFF_DEFINED) &&
+		    IN6_ARE_ADDR_EQUAL(addr, &ifp->in6_ifaddrs[ix].addr))
+			return &ifp->in6_ifaddrs[ix];
 		}
 	return NULL;
@@ -172,10 +286,10 @@
 
 bool_t
-in6_lookup_multi (T_IFNET *ifp, T_IN6_ADDR *maddr)
+in6_lookup_multi (T_IFNET *ifp, const T_IN6_ADDR *maddr)
 {
 	int_t ix;
 
 	for (ix = MAX_IN6_MADDR_CNT; ix -- > 0; )
-		if (IN6_ARE_ADDR_EQUAL(maddr, &ifp->in_maddrs[ix]))
+		if (IN6_ARE_ADDR_EQUAL(maddr, &ifp->in6_maddrs[ix]))
 			return true;
 	return false;
@@ -188,5 +302,5 @@
 ER
 in6_set_header (T_NET_BUF *nbuf, uint_t len,
-                T_IN6_ADDR *dstaddr, T_IN6_ADDR *srcaddr,
+                const T_IN6_ADDR *dstaddr, const T_IN6_ADDR *srcaddr,
                 uint8_t next, uint8_t hlim)
 {
@@ -216,10 +330,10 @@
 		memset(&ip6h->dst, 0, sizeof(T_IN6_ADDR));
 	else
-		ip6h->dst = *dstaddr;
+		memcpy(&ip6h->dst, dstaddr, sizeof(T_IN6_ADDR));
 
 	if (srcaddr == NULL)
 		memset(&ip6h->src, 0, sizeof(T_IN6_ADDR));
 	else
-		ip6h->src = *srcaddr;
+		memcpy(&ip6h->src, srcaddr, sizeof(T_IN6_ADDR));
 
 	return E_OK;
@@ -232,5 +346,5 @@
 ER
 in6_get_datagram (T_NET_BUF **nbuf, uint_t len, uint_t maxlen,
-                  T_IN6_ADDR *dstaddr, T_IN6_ADDR *srcaddr,
+                  const T_IN6_ADDR *dstaddr, const T_IN6_ADDR *srcaddr,
                   uint8_t next, uint8_t hlim, ATR nbatr, TMO tmout)
 {
@@ -269,5 +383,5 @@
  */
 
-ER_UINT
+uint_t
 in6_get_maxnum_ifaddr (void)
 {
@@ -285,6 +399,6 @@
 
 	if (index < NUM_IN6_IFADDR_ENTRY &&
-	    (ifp->in_ifaddrs[index].flags & IN6_IFF_DEFINED))
-		return &ifp->in_ifaddrs[index].addr;
+	    (ifp->in6_ifaddrs[index].flags & IN6_IFF_DEFINED))
+		return &ifp->in6_ifaddrs[index].addr;
 	else
 		return NULL;
@@ -296,12 +410,12 @@
 
 char *
-ipv62str (char *buf, const T_IN6_ADDR *p_ip6addr)
-{
-	static char	addr_sbuf[NUM_IPV6ADDR_STR_BUFF][sizeof("0123:4567:89ab:cdef:0123:4567:89ab:cdef")];
+ipv62str (char *buf, const T_IN6_ADDR *p_addr)
+{
+	static char	addr_sbuf[NUM_IPV6ADDR_STR_BUFF][sizeof("0123:4567:89ab:cdef:0123:4567:255.255.255.255")];
 	static int_t	bix = NUM_IPV6ADDR_STR_BUFF;
 
 	bool_t	omit = false, zero = false;
 	char	*start;
-	int_t	ix;
+	int_t	ix, len6;
 
 	if (buf == NULL) {
@@ -314,16 +428,22 @@
 
 	start = buf;
-	if (p_ip6addr == NULL) {
+	if (p_addr == NULL || IN6_IS_ADDR_UNSPECIFIED(p_addr)) {
+		*buf ++ = '0';
 		*buf ++ = ':';
 		*buf ++ = ':';
+		*buf ++ = '0';
 		}
 	else {
-		for (ix = 0; ix < sizeof(T_IN6_ADDR) / 2; ix ++) {
+		if (IN6_IS_ADDR_V4MAPPED(p_addr))
+			len6 = sizeof(T_IN6_ADDR) / 2 - 2;
+		else
+			len6 = sizeof(T_IN6_ADDR) / 2;
+		for (ix = 0; ix < len6; ix ++) {
 			if (omit) {
-				buf += convert_hexdigit(buf, ntohs(p_ip6addr->s6_addr16[ix]), 16, 0, ' '); 
+				buf += convert_hexdigit(buf, ntohs(p_addr->s6_addr16[ix]), 16, 0, ' '); 
 				if (ix < 7)
 					*buf ++ = ':';
 				}
-			else if (ix > 0 && ix < 7 && p_ip6addr->s6_addr16[ix] == 0)
+			else if (ix > 0 && ix < 7 && p_addr->s6_addr16[ix] == 0)
 				zero = true;
 			else {
@@ -332,9 +452,22 @@
 					*buf ++ = ':';
 					}
-				buf += convert_hexdigit(buf, ntohs(p_ip6addr->s6_addr16[ix]), 16, 0, ' '); 
+				buf += convert_hexdigit(buf, ntohs(p_addr->s6_addr16[ix]), 16, 0, ' '); 
 				if (ix < 7)
 					*buf ++ = ':';
 				}
 			}
+
+		if (len6 == sizeof(T_IN6_ADDR) / 2 - 2) {
+			T_IN4_ADDR ipv4addr;
+
+			ipv4addr = ntohl(p_addr->s6_addr32[3]);
+			buf += convert_hexdigit(buf, (uint_t)((ipv4addr >> 24) & 0xff), 10, 0, ' ');
+			*(buf ++) = '.';
+			buf += convert_hexdigit(buf, (uint_t)((ipv4addr >> 16) & 0xff), 10, 0, ' ');
+			*(buf ++) = '.';
+			buf += convert_hexdigit(buf, (uint_t)((ipv4addr >>  8) & 0xff), 10, 0, ' ');
+			*(buf ++) = '.';
+			buf += convert_hexdigit(buf, (uint_t)((ipv4addr      ) & 0xff), 10, 0, ' ');
+			}
 		}
 	*buf = '\0';
@@ -370,26 +503,14 @@
 
 /*
- *  in6_is_dstaddr_accept -- 宛先アドレスとして正しいかチェックする。
- */
-
-bool_t
-in6_is_dstaddr_accept (T_IN6_ADDR *myaddr, T_IN6_ADDR *dstaddr)
-{
-	if (IN6_IS_ADDR_UNSPECIFIED(myaddr))
-		return in6_lookup_ifaddr(IF_GET_IFNET(), dstaddr) != NULL;
-	else
-		return IN6_ARE_ADDR_EQUAL(dstaddr, myaddr);
-	}
-
-/*
  *  get_ip6_hdr_size -- 拡張ヘッダも含めた IPv6 ヘッダ長を返す。
  */
 
 uint_t
-get_ip6_hdr_size (T_IP6_HDR *iph)
-{
-	uint_t	size = IP6_HDR_SIZE, hsize;
-	uint8_t	curr = iph->next, next;
-	uint8_t	*hdr = ((uint8_t *)iph) + IP6_HDR_SIZE;
+get_ip6_hdr_size (T_NET_BUF *nbuf)
+{
+	T_IP6_HDR	*iph = GET_IP6_HDR(nbuf);
+	uint_t		size = IP6_HDR_SIZE, hsize;
+	uint8_t		curr = iph->next, next;
+	uint8_t		*hdr = ((uint8_t *)iph) + IP6_HDR_SIZE;
 
 	while (1) {
@@ -436,6 +557,6 @@
  */
 
-T_IN6_ADDR *
-in6_rtalloc (T_IFNET *ifp, T_IN6_ADDR *dst)
+const T_IN6_ADDR *
+in6_rtalloc (T_IFNET *ifp, const T_IN6_ADDR *dst)
 {
 	if (IN6_IS_ADDR_LINKLOCAL(dst) || IN6_IS_ADDR_MULTICAST(dst))
@@ -456,5 +577,5 @@
 		/* 推奨有効時間内のアドレスを探索する。*/
 		for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
-			ia = &ifp->in_ifaddrs[ix];
+			ia = &ifp->in6_ifaddrs[ix];
 			if (IFA6_IS_READY(ia) &&
 			    in6_are_prefix_equal(dst, &ia->addr, ia->prefix_len) &&
@@ -467,5 +588,5 @@
 		/* 有効時間内のアドレスを探索する。*/
 		for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
-			ia = &ifp->in_ifaddrs[ix];
+			ia = &ifp->in6_ifaddrs[ix];
 			if (IFA6_IS_READY(ia) &&
 			    in6_are_prefix_equal(dst, &ia->addr, ia->prefix_len) &&
@@ -485,11 +606,11 @@
 		 */
 
-#if NUM_ROUTE_ENTRY > 0
-
-		syscall(wai_sem(SEM_IN_ROUTING_TBL));
-		for (ix = NUM_ROUTE_ENTRY; ix --; ) {
-			if ((routing_tbl[ix].flags & IN_RTF_DEFINED) &&
-			    in6_are_prefix_equal(dst, &routing_tbl[ix].target,
-			                               routing_tbl[ix].prefix_len)) {
+#if NUM_IN6_ROUTE_ENTRY > 0
+
+		syscall(wai_sem(SEM_IN6_ROUTING_TBL));
+		for (ix = NUM_IN6_ROUTE_ENTRY; ix --; ) {
+			if ((routing6_tbl[ix].flags & IN_RTF_DEFINED) &&
+			    in6_are_prefix_equal(dst, &routing6_tbl[ix].target,
+			                               routing6_tbl[ix].prefix_len)) {
 
 				/*
@@ -498,18 +619,18 @@
 				 *  TMO_IN_REDIRECT の単位は [ms]。
 				 */
-				if (ix > NUM_STATIC_ROUTE_ENTRY) {
+				if (ix > NUM_IN6_STATIC_ROUTE_ENTRY) {
 					SYSTIM	now;
 
 					syscall(get_tim(&now));
-					routing_tbl[ix].expire = now / SYSTIM_HZ + TMO_IN_REDIRECT / 1000;
+					routing6_tbl[ix].expire = now / SYSTIM_HZ + TMO_IN_REDIRECT / 1000;
 					}
 
-				syscall(sig_sem(SEM_IN_ROUTING_TBL));
-				return &routing_tbl[ix].gateway;
+				syscall(sig_sem(SEM_IN6_ROUTING_TBL));
+				return &routing6_tbl[ix].gateway;
 				}
 			}
-		syscall(sig_sem(SEM_IN_ROUTING_TBL));
-
-#endif	/* of #if NUM_ROUTE_ENTRY > 0 */
+		syscall(sig_sem(SEM_IN6_ROUTING_TBL));
+
+#endif	/* of #if NUM_IN6_ROUTE_ENTRY > 0 */
 
 		/*
@@ -520,5 +641,5 @@
 	}
 
-#if NUM_REDIRECT_ROUTE_ENTRY > 0
+#if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0
 
 /*
@@ -526,13 +647,13 @@
  */
 
-T_IN_RTENTRY *
-in6_gateway_lookup (T_IN6_ADDR *gw)
+T_IN6_RTENTRY *
+in6_gateway_lookup (const T_IN6_ADDR *gw)
 {
 	int_t	ix;
 
-	for (ix = NUM_ROUTE_ENTRY; ix --; )
-		if ((routing_tbl[ix].flags & IN_RTF_DEFINED) &&
-		    IN6_ARE_ADDR_EQUAL(&routing_tbl[ix].gateway, gw))
-			return &routing_tbl[ix];
+	for (ix = NUM_IN6_ROUTE_ENTRY; ix --; )
+		if ((routing6_tbl[ix].flags & IN_RTF_DEFINED) &&
+		    IN6_ARE_ADDR_EQUAL(&routing6_tbl[ix].gateway, gw))
+			return &routing6_tbl[ix];
 	return NULL;
 	}
@@ -545,15 +666,15 @@
 
 void
-in6_rtredirect (T_IN6_ADDR *gateway, T_IN6_ADDR *target, uint_t prefix_len, uint8_t flags, uint32_t tmo)
-{
-	T_IN_RTENTRY	*frt;
-
-	frt = in_rtnewentry(flags, tmo);
-	frt->gateway    = *gateway;
-	frt->target     = *target;
+in6_rtredirect (const T_IN6_ADDR *gateway, const T_IN6_ADDR *target, uint_t prefix_len, uint8_t flags, uint32_t tmo)
+{
+	T_IN6_RTENTRY	*frt;
+
+	frt = in6_rtnewentry(flags, tmo);
+	memcpy(&frt->gateway, gateway, sizeof(T_IN6_ADDR));
+	memcpy(&frt->target, target, sizeof(T_IN6_ADDR));
 	frt->prefix_len = prefix_len;
 	}
 
-#endif	/* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
+#endif	/* of #if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0 */
 
 #if NUM_IN6_HOSTCACHE_ENTRY > 0
@@ -564,5 +685,5 @@
 
 static T_IN6_HOSTCACHE_ENTRY*
-in6_hostcache_lookup (T_IN6_ADDR *dst)
+in6_hostcache_lookup (const T_IN6_ADDR *dst)
 {
 	int_t ix;
@@ -625,5 +746,5 @@
 		return;
 		}
-	hc->dst    = *dst;
+	memcpy(&hc->dst, dst, sizeof(T_IN6_ADDR));
 	hc->expire = now + IN6_HOSTCACHE_EXPIRE;
 	hc->mtu    = mtu;
@@ -637,5 +758,5 @@
 
 uint32_t
-in6_hostcache_getmtu (T_IN6_ADDR *dst)
+in6_hostcache_getmtu (const T_IN6_ADDR *dst)
 {
 	T_IN6_HOSTCACHE_ENTRY	*hc;
@@ -679,9 +800,9 @@
 in6_timer (void)
 {
-#if NUM_REDIRECT_ROUTE_ENTRY > 0
-
-	in_rttimer();
-
-#endif	/* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
+#if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0
+
+	in6_rttimer();
+
+#endif	/* of #if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0 */
 
 #ifdef IP6_CFG_FRAGMENT
@@ -707,9 +828,9 @@
 in6_init (void)
 {
-#if NUM_REDIRECT_ROUTE_ENTRY > 0
-
-	in_rtinit();
-
-#endif	/* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
+#if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0
+
+	in6_rtinit();
+
+#endif	/* of #if NUM_IN6_REDIRECT_ROUTE_ENTRY > 0 */
 
 	timeout((callout_func)nd6_timer, NULL, ND6_TIMER_TMO);
@@ -717,3 +838,106 @@
 	}
 
-#endif /* of #ifdef SUPPORT_INET6 */
+/*
+ *  in6_is_dstaddr_accept -- 宛先アドレスとして正しいかチェックする。
+ */
+
+bool_t
+in6_is_dstaddr_accept (const T_IN6_ADDR *myaddr, const T_IN6_ADDR *dstaddr)
+{
+	if (IN6_IS_ADDR_UNSPECIFIED(myaddr))
+		return in6_lookup_ifaddr(IF_GET_IFNET(), dstaddr) != NULL;
+	else
+		return IN6_ARE_ADDR_EQUAL(dstaddr, myaddr);
+	}
+
+#if defined(DHCP6_CLI_CFG)
+
+/*
+ *  in6_add_ifaddr -- インタフェースに IPv6 アドレスを設定する。
+ *
+ *    vltime と pltime の単位は[s]
+ */
+
+static ER
+in6_add_ifaddr (T_IN6_ADDR *addr, uint_t prefix_len,
+                uint32_t vltime, uint32_t pltime)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_IN6_IFADDR	*ia = NULL;
+	int_t		ix;
+
+	/* 空きのエントリーを探す。*/
+	ix = 0;
+	while (true) {
+		ia = in6ifa_ifpwithix(ifp, ix ++);
+
+		/* 空きが無ければエラー */
+		if (ia == NULL)
+			return E_OBJ;
+
+		if ((ia->flags & IN6_IFF_DEFINED) == 0)
+			break;
+		}
+
+	/* 登録する。*/
+	return in6_update_ifa(ifp, ia, addr, prefix_len, vltime, pltime,
+	                      IN6_RTR_IX_UNREACH, ND6_PREFIX_IX_INVALID, 0);
+	}
+
+/*
+ *  in6_upd_ifaddr -- インタフェースに設定されている IPv6 アドレスを更新する。
+ *
+ *    登録されていなければ、追加する。
+ *    vltime と pltime の単位は[s]
+ */
+
+ER
+in6_upd_ifaddr (T_IN6_ADDR *addr, uint_t prefix_len,
+                uint32_t vltime, uint32_t pltime)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+	T_IN6_IFADDR	*ia;
+	int_t		ix;
+
+	/*
+	 *  アドレスが一致するエントリーを探す。
+	 *  無ければ登録する。
+	 */
+	if ((ix = in6_addr2ifaix(addr)) == IPV6_IFADDR_IX_INVALID)
+		return in6_add_ifaddr(addr, prefix_len, vltime, pltime);
+
+	/*
+	 *  インデックス番号から、エントリーに変換する。
+	 *  エラーにならないはずであるが、確認する。
+	 */
+	if ((ia = in6ifa_ifpwithix (ifp, ix)) == NULL)
+		return E_OBJ;
+
+	/* 更新する。*/
+	return in6_update_ifa(ifp, ia, addr, prefix_len, vltime, pltime,
+	                      IN6_RTR_IX_UNREACH, ND6_PREFIX_IX_INVALID, 0);
+	}
+
+/*
+ *  in6_del_ifaddr -- インタフェースに設定されている IPv6 アドレスを削除する。
+ */
+
+ER
+in6_del_ifaddr (T_IN6_ADDR *addr)
+{
+	T_IFNET		*ifp = IF_GET_IFNET();
+	int_t		ix;
+
+	/* アドレスが一致するエントリーを探す。*/
+	if ((ix = in6_addr2ifaix(addr)) != IPV6_IFADDR_IX_INVALID) {
+
+		/* エントリーを無効にする。*/
+		ifp->in6_ifaddrs[ix].flags &= ~IN6_IFF_DEFINED;
+		return E_OK;
+		}
+	return E_PAR;
+	}
+
+#endif	/* of #if defined(DHCP6_CLI_CFG) */
+
+#endif /* of #ifdef _IP6_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6_var.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6_var.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/in6_var.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -102,5 +102,70 @@
 #define _IN6_VAR_H_
 
-#ifdef SUPPORT_INET6
+/*
+ *  アドレスの定義
+ */
+
+#ifdef _NET_CFG_BYTE_ORDER
+
+#if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN
+
+#define IPV6_ADDR_INT32_ONE		ULONG_C(0x00000001)
+#define IPV6_ADDR_INT32_TWO		ULONG_C(0x00000002)
+#define IPV6_ADDR_INT32_0000FFFF	ULONG_C(0x0000ffff)
+#define IPV6_ADDR_INT32_MNL		ULONG_C(0xff010000)
+#define IPV6_ADDR_INT32_MLL		ULONG_C(0xff020000)
+#define IPV6_ADDR_INT32_ULL		ULONG_C(0xfe800000)
+#define IPV6_ADDR_INT16_ULL		UINT_C(0xfe80)
+#define IPV6_ADDR_INT16_USL		UINT_C(0xfec0)
+#define IPV6_ADDR_INT16_MLL		UINT_C(0xff02)
+
+#elif _NET_CFG_BYTE_ORDER == _NET_CFG_LITTLE_ENDIAN
+
+#define IPV6_ADDR_INT32_ONE		ULONG_C(0x01000000)
+#define IPV6_ADDR_INT32_TWO		ULONG_C(0x02000000)
+#define IPV6_ADDR_INT32_0000FFFF	ULONG_C(0xffff0000)
+#define IPV6_ADDR_INT32_MNL		ULONG_C(0x000001ff)
+#define IPV6_ADDR_INT32_MLL		ULONG_C(0x000002ff)
+#define IPV6_ADDR_INT32_ULL		ULONG_C(0x000080fe)
+#define IPV6_ADDR_INT16_ULL		UINT_C(0x80fe)
+#define IPV6_ADDR_INT16_USL		UINT_C(0xc0fe)
+#define IPV6_ADDR_INT16_MLL		UINT_C(0x02ff)
+
+#endif	/* #if _NET_CFG_BYTE_ORDER == _NET_CFG_BIG_ENDIAN */
+
+#endif	/* of #ifdef _NET_CFG_BYTE_ORDER */
+
+/*
+ *  特別なアドレスのチェック
+ */
+
+/* IPv4 互換 */
+
+#ifdef _NET_CFG_BYTE_ORDER
+#define IN6_IS_ADDR_V4COMPAT(a)		\
+	(memcmp((void *)(a), (void *)&in6_addr_unspecified, sizeof(T_IN6_ADDR) - 4) == 0 && \
+	 (a)->s6_addr32[3] > IPV6_ADDR_INT32_ONE)
+#endif
+
+/* IPv4 射影 */
+
+#ifdef _NET_CFG_BYTE_ORDER
+#define IN6_IS_ADDR_V4MAPPED(a)		\
+	(((a)->s6_addr32[0] == ULONG_C(0x00000000)) && \
+	 ((a)->s6_addr32[1] == ULONG_C(0x00000000)) && \
+	 ((a)->s6_addr32[2] == IPV6_ADDR_INT32_0000FFFF))
+#endif
+
+/* 要請マルチキャスト */
+
+#ifdef _NET_CFG_BYTE_ORDER
+#define IN6_IS_ADDR_NS_MULTICAST(a)	\
+	(((a)->s6_addr32[0] == IPV6_ADDR_INT32_MLL) && \
+	 ((a)->s6_addr32[1] == ULONG_C(0x00000000)) && \
+	 ((a)->s6_addr32[2] == IPV6_ADDR_INT32_ONE) && \
+	 ((a)->s6_addr8[12] == UINT_C(0xff)))
+#endif
+
+#ifndef _MACRO_ONLY
 
 /*
@@ -197,8 +262,4 @@
 						/* IPv6 マルチキャストアドレス配列の最大サイズ	*/
 
-/*
- *  ルーティングの制御
- */
-
 /* ルーティング表エントリ構造体 */
 
@@ -231,17 +292,8 @@
 
 /*
- *  IPv4 と IPv6 をコンパイル時に選択するためのマクロ
- */
-
-#define IN_SET_HEADER(nbuf,len,dst,src,next,hlim)	\
-					in6_set_header(nbuf,len,dst,src,next,hlim)
-#define IN_GET_DATAGRAM(nbuf,len,maxlen,dst,src,next,hlim,nbatr,tmout)	\
-					in6_get_datagram(nbuf,len,maxlen,dst,src,next,hlim,nbatr,tmout)
-#define IN_CKSUM(nbuf,proto,off,len)	in6_cksum(nbuf,proto,off,len)
-#define IN_IS_DSTADDR_ACCEPT(myaddr,dstaddr)			\
-					in6_is_dstaddr_accept(myaddr,dstaddr)
-#define IN_IFAWITHIFP(ifp,dst)		in6_ifawithifp(ifp,dst)
-#define T_IN_IFADDR			T_IN6_IFADDR
-#define T_IN_RTENTRY			T_IN6_RTENTRY
+ *  ルーティング表
+ */
+
+extern T_IN6_RTENTRY routing6_tbl[];
 
 /*
@@ -264,44 +316,54 @@
 
 /*
+ *  関数シミュレーションマクロ
+ */
+
+#define IN6_COPY_TO_HOST(dst,nbuf)	memcpy(dst,&GET_IP6_HDR(nbuf)->src,sizeof(T_IN6_ADDR))
+#define INN6_IS_DSTADDR_ACCEPT(addr,nbuf)	\
+					in6_is_dstaddr_accept(addr,&GET_IP6_HDR(nbuf)->dst)
+
+/*
  *  関数
  */
 
 extern void in6_ifainit (void);
-extern int_t in6_addr2maix (T_IN6_ADDR *addr);
-extern ER in6_update_ifa (T_IFNET *ifp, T_IN6_IFADDR *ia, T_IN6_ADDR *addr,
+extern int_t in6_addr2maix (const T_IN6_ADDR *addr);
+extern ER in6_update_ifa (T_IFNET *ifp, T_IN6_IFADDR *ia, const T_IN6_ADDR *addr,
                           uint_t prefix_len, uint32_t vltime, uint32_t pltime,
                           int_t router_index, int_t prefix_index, uint_t flags);
 extern ER in6_set_header (T_NET_BUF *nbuf, uint_t len,
-                          T_IN6_ADDR *dstaddr, T_IN6_ADDR *srcaddr,
+                          const T_IN6_ADDR *dstaddr, const T_IN6_ADDR *srcaddr,
                           uint8_t next, uint8_t hlim);
 extern ER in6_get_datagram (T_NET_BUF **nbuf, uint_t len, uint_t maxlen,
-                            T_IN6_ADDR *dstaddr, T_IN6_ADDR *srcaddr,
+                            const T_IN6_ADDR *dstaddr, const T_IN6_ADDR *srcaddr,
                             uint8_t next, uint8_t hlim, ATR nbatr, TMO tmout);
 extern uint16_t in6_cksum (T_NET_BUF *nbuf, uint8_t proto, uint_t off, uint_t len);
 extern T_IN6_IFADDR *in6ifa_ifpwithix (T_IFNET *ifp, int_t ix);
 extern T_IN6_IFADDR *in6ifa_ifpwithrtrix (T_IFNET *ifp, int_t rtr_ix);
-extern T_IN6_IFADDR *in6_ifawithifp (T_IFNET *ifp, T_IN6_ADDR *dst);
+extern T_IN6_IFADDR *in6_ifawithifp (T_IFNET *ifp, const T_IN6_ADDR *dst);
+extern const T_IN6_ADDR *in6_addrwithifp (T_IFNET *ifp, T_IN6_ADDR *src, const T_IN6_ADDR *dst);
 extern void ip6_input (T_NET_BUF *input);
-extern T_IN6_IFADDR *in6_lookup_ifaddr (T_IFNET *ifp, T_IN6_ADDR *addr);
-extern bool_t in6_lookup_multi (T_IFNET *ifp, T_IN6_ADDR *maddr);
-extern bool_t in6_is_dstaddr_accept (T_IN6_ADDR *myaddr, T_IN6_ADDR *dstaddr);
-extern T_IN6_ADDR *in6_rtalloc (T_IFNET *ifp, T_IN6_ADDR *dst);
+extern T_IN6_IFADDR *in6_lookup_ifaddr (T_IFNET *ifp, const T_IN6_ADDR *addr);
+extern bool_t in6_lookup_multi (T_IFNET *ifp, const T_IN6_ADDR *maddr);
+extern bool_t in6_is_dstaddr_accept (const T_IN6_ADDR *myaddr, const T_IN6_ADDR *dstaddr);
+extern bool_t inn6_is_dstaddr_accept (const T_IN6_ADDR *myaddr, T_NET_BUF *input);
+extern const T_IN6_ADDR *in6_rtalloc (T_IFNET *ifp, const T_IN6_ADDR *dst);
 extern int_t in6_if2idlen (T_IFNET *ifp);
-extern int_t in6_addr2ifaix (T_IN6_ADDR *addr);
+extern int_t in6_addr2ifaix (const T_IN6_ADDR *addr);
 extern void in6_plen2pmask (T_IN6_ADDR *mask, uint_t prefix_len);
-extern bool_t in6_are_prefix_equal (T_IN6_ADDR *addr, T_IN6_ADDR *prefix,
+extern bool_t in6_are_prefix_equal (const T_IN6_ADDR *addr, const T_IN6_ADDR *prefix,
                                   uint_t prefix_len);
 extern void in6_ifaddr_timer (T_IFNET *ifp);
-extern T_IN6_RTENTRY *in6_gateway_lookup (T_IN6_ADDR *src);
-extern void in6_rtredirect (T_IN6_ADDR *gateway, T_IN6_ADDR *target,
+extern T_IN6_RTENTRY *in6_gateway_lookup (const T_IN6_ADDR *src);
+extern void in6_rtredirect (const T_IN6_ADDR *gateway, const T_IN6_ADDR *target,
                             uint_t prefix_len, uint8_t flags, uint32_t tmo);
 extern void in6_init (void);
 extern void in6_if_up (T_IFNET *ifp);
 extern void in6_hostcache_update (T_IN6_ADDR *dst, uint32_t mtu);
-extern uint32_t in6_hostcache_getmtu (T_IN6_ADDR *dst);
-extern uint_t in6_addrscope (T_IN6_ADDR *addr);
+extern uint32_t in6_hostcache_getmtu (const T_IN6_ADDR *dst);
+extern uint_t in6_addrscope (const T_IN6_ADDR *addr);
 extern const T_NET_BUF**ip6_get_frag_queue (void);
 
-#endif	/* of #ifdef SUPPORT_INET6 */
+#endif	/* of #ifndef _MACRO_ONLY */
 
 #endif	/* of #ifndef _IN6_VAR_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ip6.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ip6.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ip6.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -36,5 +36,5 @@
  */
 
-#ifdef SUPPORT_INET6
+#ifdef _IP6_CFG
 
 /* 近隣キャッシュ */
@@ -58,11 +58,11 @@
 #endif	/* of #ifdef IP6_CFG_FRAGMENT */
 
-#if NUM_REDIRECT_ROUTE_ENTRY > 0
+#if NUM_IN6_ROUTE_ENTRY > 0
 
-/* ルーティング表（向け直し）*/
+/* ルーティング表 */
 
-CRE_SEM(SEM_IN_ROUTING_TBL, { TA_TPRI, 1, 1 });
+CRE_SEM(SEM_IN6_ROUTING_TBL, { TA_TPRI, 1, 1 });
 
-#endif	/* of #if NUM_REDIRECT_ROUTE_ENTRY > 0 */
+#endif	/* of #if NUM_IN6_ROUTE_ENTRY > 0 */
 
-#endif	/* of #ifdef SUPPORT_INET6 */
+#endif	/* of #ifdef _IP6_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ip6_input.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ip6_input.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ip6_input.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -105,4 +105,6 @@
 #include <kernel.h>
 #include <sil.h>
+#include <t_syslog.h>
+#include "tinet_cfg.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_ASP */
@@ -112,4 +114,5 @@
 #include <s_services.h>
 #include <t_services.h>
+#include "tinet_id.h"
 
 #endif	/* of #ifdef TARGET_KERNEL_JSP */
@@ -124,24 +127,24 @@
 #include <net/ppp_ipcp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_count.h>
 
 #include <netinet/in.h>
-#include <netinet6/in6.h>
-#include <netinet6/in6_var.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_var.h>
+#include <netinet/udp_var.h>
+
 #include <netinet6/nd6.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#include <netinet/icmp6.h>
 #include <netinet6/ah6.h>
 #include <netinet6/esp6.h>
-#include <netinet/tcp.h>
-#include <netinet/tcp_timer.h>
-#include <netinet/tcp_var.h>
-#include <netinet/udp_var.h>
-
-#include <net/if6_var.h>
-
-#ifdef SUPPORT_INET6
+
+#include <net/if_var.h>
+
+#ifdef _IP6_CFG
 
 /*
@@ -170,15 +173,15 @@
 	{ icmp6_input,	IPPROTO_ICMPV6		},
 
-#ifdef SUPPORT_UDP
-
-	{ udp_input,	IPPROTO_UDP		},
-
-#endif	/* of #ifdef SUPPORT_UDP */
-
-#ifdef SUPPORT_TCP
+#if defined(SUPPORT_TCP)
 
 	{ tcp_input,	IPPROTO_TCP		},
 
-#endif	/* of #ifdef SUPPORT_TCP */
+#endif	/* of #if defined(SUPPORT_TCP) */
+
+#if defined(SUPPORT_UDP) && TNUM_UDP6_CEPID > 0
+
+	{ udp6_input,	IPPROTO_UDP		},
+
+#endif	/* of #if defined(SUPPORT_UDP) && TNUM_UDP6_CEPID > 0 */
 
 	};
@@ -640,5 +643,5 @@
 
 	/* 開始オフセットを IP ヘッダに設定する。*/
-	off = ((uint8_t *)GET_IP_HDR(nbuf)) - nbuf->buf;
+	off = ((uint8_t *)GET_IP6_HDR(nbuf)) - nbuf->buf;
 
 	/* 最終ヘッダを探索する。*/
@@ -650,8 +653,8 @@
 		uint_t sdu;
 
-		sdu = GET_IP_SDU(nbuf) - nbuf->buf;
+		sdu = GET_IP6_SDU(nbuf) - nbuf->buf;
 		if (off > sdu) {
 			memmove(nbuf->buf + sdu, nbuf->buf + off, off - sdu);
-			GET_IP_HDR(nbuf)->plen -= off - sdu;
+			GET_IP6_HDR(nbuf)->plen -= off - sdu;
 			nbuf->len              -= off - sdu;
 			}
@@ -660,3 +663,3 @@
 	}
 
-#endif /* of #ifdef SUPPORT_INET6 */
+#endif /* of #ifdef _IP6_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ip6_output.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ip6_output.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ip6_output.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -125,18 +125,19 @@
 #include <net/ppp_ipcp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_count.h>
 
 #include <netinet/in.h>
-#include <netinet6/in6.h>
-#include <netinet6/in6_var.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+
 #include <netinet6/nd6.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#include <netinet/icmp6.h>
-
-#include <net/if6_var.h>
-
-#ifdef SUPPORT_INET6
+
+#include <net/if_var.h>
+
+#ifdef _IP6_CFG
 
 /*
@@ -165,8 +166,8 @@
 ip6_output (T_NET_BUF *output, uint16_t flags, TMO tmout)
 {
-	T_IP6_HDR	*ip6h;
-	T_IN6_ADDR	*gw;
-	T_IFNET		*ifp = IF_GET_IFNET();
-	ER		error = E_OK;
+	T_IP6_HDR		*ip6h;
+	const T_IN6_ADDR	*gw;
+	T_IFNET			*ifp = IF_GET_IFNET();
+	ER			error = E_OK;
 
 #ifdef IP6_CFG_FRAGMENT
@@ -185,5 +186,5 @@
 
 	NET_COUNT_IP6(net_count_ip6[NC_IP6_OUT_OCTETS],
-	              GET_IP_HDR_SIZE(ip6h) + GET_IP_SDU_SIZE(ip6h));
+	              GET_IP6_HDR_SIZE(output) + GET_IP6_SDU_SIZE(output));
 	NET_COUNT_IP6(net_count_ip6[NC_IP6_OUT_PACKETS], 1);
 	NET_COUNT_MIB(in6_ifstat.ipv6IfStatsOutRequests, 1);
@@ -371,3 +372,3 @@
 	}
 
-#endif /* of #ifdef SUPPORT_INET6 */
+#endif /* of #ifdef _IP6_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ip6_var.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ip6_var.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ip6_var.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -102,6 +102,4 @@
 #define _IP6_VAR_H_
 
-#ifdef SUPPORT_INET6
-
 /*
  *  IPv6 ヘッダ・ペイロードアクセスマクロ
@@ -114,9 +112,10 @@
 #define GET_IP6_NEXT_HDR(nbuf)		((uint8_t*)((nbuf)->buf) + IF_IP6_HDR_SIZE)
 
-#define GET_IP6_HDR_SIZE(iph)		(get_ip6_hdr_size(iph))
-#define GET_IP6_SDU_SIZE(iph)		(ntohs((iph)->plen))
-#define GET_IF_IP6_HDR_SIZE(nbuf)	(IF_HDR_SIZE + (GET_IP6_HDR_SIZE(GET_IP6_HDR(nbuf))))
-
-#define SET_IP6_SDU_SIZE(iph,slen)	((iph)->plen=htons(slen))
+#define GET_IP6_HDR_SIZE(nbuf)		(get_ip6_hdr_size(nbuf))
+#define GET_IP6_SDU_SIZE(nbuf)		(ntohs(GET_IP6_HDR(nbuf)->plen))
+#define GET_IF_IP6_HDR_SIZE(nbuf)	(IF_HDR_SIZE + (GET_IP6_HDR_SIZE(nbuf)))
+
+#define SET_IP6_CF(nbuf,cf)		(GET_IP6_HDR(nbuf)->vcf=htonl(IP6_MAKE_VCF(IP6_VCF_V(ntohl(GET_IP6_HDR(nbuf)->vcf)),cf)))
+#define SET_IP6_SDU_SIZE(nbuf,slen)	(GET_IP6_HDR(nbuf)->plen=htons(slen))
 
 /* ip6_output のフラグ */
@@ -144,27 +143,8 @@
 
 /*
- *  IPv4 と IPv6 をコンパイル時に選択するためのマクロ
- */
-
-#define T_TCP_IP_Q_HDR			T_TCP_IP6_Q_HDR
-
-#define IF_IP_HDR_SIZE			IF_IP6_HDR_SIZE
-
-#define GET_IP_HDR(nbuf)		GET_IP6_HDR(nbuf)
-#define GET_IP_SDU(nbuf)		GET_IP6_SDU(nbuf)
-
-#define GET_IP_HDR_SIZE(iph)		GET_IP6_HDR_SIZE(iph)
-#define GET_IP_SDU_SIZE(iph)		GET_IP6_SDU_SIZE(iph)
-#define GET_IF_IP_HDR_SIZE(nbuf)	GET_IF_IP6_HDR_SIZE(nbuf)
-
-#define SET_IP_SDU_SIZE(iph,len)	SET_IP6_SDU_SIZE(iph,len)
-
-#define IP_OUTPUT(nbuf,tmout)		ip6_output(nbuf,0,tmout)
-#define IP_INIT()			ip6_init()
-#define IP_REMOVE_OPTIONS(nbuf)		ip6_remove_exthdrs(nbuf)
-
-/*
  *  IPv6 の MMTU サイズのネットワークバッファ
  */
+
+#if defined(IF_HDR_SIZE)
 
 typedef struct t_net_buf_ipv6_mmtu {
@@ -181,4 +161,6 @@
 				/* バッファ本体		*/
 	} T_NET_BUF_IPV6_MMTU;
+
+#endif	/* of #if defined(IF_HDR_SIZE) */
 
 /*
@@ -258,5 +240,5 @@
  */
 
-typedef struct t_tcp_ip6_q_hdr {
+typedef struct t_ip6_tcp_q_hdr {
 	uint8_t vc;		/* Version:        4 bit		*/
 	uint8_t cf;		/* Traffic Class:  8 bit		*/
@@ -268,5 +250,5 @@
 	T_IN6_ADDR src;	/* Source Address			*/
 	T_IN6_ADDR dst;	/* Destination Address			*/
-	} __attribute__((packed, aligned(2)))T_TCP_IP6_Q_HDR;
+	} __attribute__((packed, aligned(2))) T_IP6_TCP_Q_HDR;
 
 #ifdef SUPPORT_MIB
@@ -304,4 +286,10 @@
 
 /*
+ *  変数
+ */
+
+extern uint8_t	ip6_defhlim;
+
+/*
  *  関数
  */
@@ -310,5 +298,5 @@
 extern void ip6_init (void);
 extern uint8_t *ip6_get_prev_hdr (T_NET_BUF *nbuf, uint_t off);
-extern uint_t get_ip6_hdr_size (T_IP6_HDR *iph);
+extern uint_t get_ip6_hdr_size (T_NET_BUF *nbuf);
 extern ER_UINT ip6_nexthdr (T_NET_BUF *nbuf, uint_t off, uint_t proto, uint_t *nextp);
 extern ER_UINT ip6_lasthdr (T_NET_BUF *nbuf, uint_t off, uint_t proto, uint_t *nextp);
@@ -320,5 +308,3 @@
 extern ER ip6_remove_exthdrs (T_NET_BUF *nbuf);
 
-#endif	/* of #ifdef SUPPORT_INET6 */
-
 #endif	/* of #ifndef _IP6_VAR_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ipsec.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ipsec.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/ipsec.cfg	(revision 331)
@@ -3,5 +3,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *  Copyright (C) 2008-2009 by Hokkaido Industrial Research Institute, JAPAN
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/nd6.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/nd6.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/nd6.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -98,6 +98,8 @@
 #include <net/ethernet.h>
 #include <net/if_arp.h>
+#include <net/ppp.h>
 #include <net/ppp_ipcp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_var.h>
 #include <net/net_buf.h>
@@ -107,15 +109,13 @@
 #include <netinet/in.h>
 #include <netinet/in_var.h>
-#include <netinet6/in6.h>
-#include <netinet6/in6_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+
 #include <netinet6/nd6.h>
 
-#include <netinet/ip6.h>
-#include <netinet/icmp6.h>
-#include <netinet6/ip6_var.h>
-
-#include <net/if6_var.h>
-
-#ifdef SUPPORT_INET6
+#include <net/if_var.h>
+
+#ifdef _IP6_CFG
 
 /*
@@ -328,5 +328,5 @@
 
 T_LLINFO_ND6 *
-nd6_lookup (T_IN6_ADDR *addr, bool_t create)
+nd6_lookup (const T_IN6_ADDR *addr, bool_t create)
 {
 	SYSTIM	min = 0xffffffff;
@@ -370,5 +370,5 @@
 
 T_LLINFO_ND6 *
-nd6_cache_lladdr (T_IFNET *ifp, T_IN6_ADDR *from,
+nd6_cache_lladdr (T_IFNET *ifp, const T_IN6_ADDR *from,
                   T_IF_ADDR *lladdr, uint8_t type, uint8_t code)
 {
@@ -487,5 +487,5 @@
 
 bool_t
-nd6_is_addr_neighbor (T_IFNET *ifp, T_IN6_ADDR *addr)
+nd6_is_addr_neighbor (T_IFNET *ifp, const T_IN6_ADDR *addr)
 {
 	if (IN6_IS_ADDR_LINKLOCAL(addr))
@@ -508,5 +508,5 @@
 
 ER
-nd6_output (T_IFNET *ifp, T_NET_BUF *output, T_IN6_ADDR *dst, T_LLINFO_ND6 *ln, TMO tmout)
+nd6_output (T_IFNET *ifp, T_NET_BUF *output, const T_IN6_ADDR *dst, T_LLINFO_ND6 *ln, TMO tmout)
 {
 	ER	error = E_OK;
@@ -622,5 +622,5 @@
 
 ER
-nd6_storelladdr (T_IF_ADDR *out, T_IN6_ADDR *dst, T_IF_ADDR *ifa)
+nd6_storelladdr (T_IF_ADDR *out, const T_IN6_ADDR *dst, T_IF_ADDR *ifa)
 {
 	if (IN6_IS_ADDR_MULTICAST(dst)) {
@@ -696,3 +696,3 @@
 	}
 
-#endif /* of #ifdef SUPPORT_INET6 */
+#endif /* of #ifdef _IP6_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/nd6.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/nd6.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/nd6.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -67,6 +67,4 @@
 #define _ND6_H_
 
-#ifdef SUPPORT_INET6
-
 /*
  *  ネットワークインタフェース構造体（T_IFNET）のフラグ
@@ -118,6 +116,4 @@
 #define ND6_MAX_UCAST_QUERY		3		/* ユニキャストアドレス要請の再送回数	*/
 
-#define ND6_INFINITE_LIFETIME		0xffffffff
-
 #define ND6_GCOLLECTION_TIME		(60*60*24*SYSTIM_HZ)
 							/* ゴミ拾い周期、1 日			*/
@@ -234,5 +230,4 @@
 extern SYSTIM	nd6_recalc_reachtm_interval;
 extern SYSTIM	nd6_retrans_time;
-extern uint8_t	ip6_defhlim;
 
 /*
@@ -241,25 +236,25 @@
 
 extern void nd6_ifattach (T_IFNET *ifp);
-extern void nd6_ns_output (T_IFNET *ifp, T_IN6_ADDR *daddr,
-                           T_IN6_ADDR *taddr, T_LLINFO_ND6 *ln, bool_t dad);
-extern void nd6_na_output (T_IFNET *ifp, T_IN6_ADDR *daddr,
-                           T_IN6_ADDR *taddr, uint32_t flags, bool_t tlladdr);
+extern void nd6_ns_output (T_IFNET *ifp, const T_IN6_ADDR *daddr,
+                           const T_IN6_ADDR *taddr, T_LLINFO_ND6 *ln, bool_t dad);
+extern void nd6_na_output (T_IFNET *ifp, const T_IN6_ADDR *daddr,
+                           const T_IN6_ADDR *taddr, uint32_t flags, bool_t tlladdr);
 extern void nd6_dad_start (T_IFNET *ifp, T_IN6_IFADDR *ia, int_t *tick);
 extern ER nd6_output (T_IFNET *ifp, T_NET_BUF *output,
-                      T_IN6_ADDR *dst, T_LLINFO_ND6 *ln, TMO tmout);
+                      const T_IN6_ADDR *dst, T_LLINFO_ND6 *ln, TMO tmout);
 extern void nd6_na_input (T_NET_BUF *input, uint_t off);
 extern void nd6_ns_input (T_NET_BUF *input, uint_t off);
 extern void nd6_ra_input (T_NET_BUF *input, uint_t off);
-extern ER nd6_storelladdr (T_IF_ADDR *out, T_IN6_ADDR *dst, T_IF_ADDR *ifa);
+extern ER nd6_storelladdr (T_IF_ADDR *out, const T_IN6_ADDR *dst, T_IF_ADDR *ifa);
 extern ER nd6_options (uint8_t *opt, void *nh, uint_t len);
-extern T_LLINFO_ND6 *nd6_lookup (T_IN6_ADDR *addr, bool_t create);
+extern T_LLINFO_ND6 *nd6_lookup (const T_IN6_ADDR *addr, bool_t create);
 extern ER nd6_output_hold (T_IFNET *ifp, T_LLINFO_ND6 *ln);
-extern T_LLINFO_ND6 *nd6_cache_lladdr (T_IFNET *ifp, T_IN6_ADDR *from, 
+extern T_LLINFO_ND6 *nd6_cache_lladdr (T_IFNET *ifp, const T_IN6_ADDR *from, 
                                        T_IF_ADDR *lladdr, uint8_t type, uint8_t code);
 extern void nd6_defrtrlist_timer (void);
 extern void nd6_prelist_timer (void);
 extern void nd6_rtrsol_ctl (void);
-extern T_IN6_ADDR *nd6_router_lookup (void);
-extern T_DEF_ROUTER *nd6_defrtrlist_lookup (T_IN6_ADDR *src);
+extern const T_IN6_ADDR *nd6_router_lookup (void);
+extern T_DEF_ROUTER *nd6_defrtrlist_lookup (const T_IN6_ADDR *src);
 extern void nd6_defrtrlist_del (T_DEF_ROUTER *dr);
 extern void nd6_timer (void);
@@ -269,7 +264,5 @@
 extern ER nd6_prefix_onlink (T_ND6_PREFIX *pr);
 extern ER nd6_prefix_offlink (T_ND6_PREFIX *pr);
-extern T_ND6_PREFIX *nd6_onlink_prefix_lookup (T_IN6_ADDR *dst);
-
-#endif	/* of #ifdef SUPPORT_INET6 */
+extern T_ND6_PREFIX *nd6_onlink_prefix_lookup (const T_IN6_ADDR *dst);
 
 #endif	/* of #ifndef _ND6_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/nd6_nbr.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/nd6_nbr.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/nd6_nbr.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -93,4 +93,5 @@
 #include <net/ppp_ipcp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_var.h>
 #include <net/net_buf.h>
@@ -100,16 +101,13 @@
 #include <netinet/in.h>
 #include <netinet/in_var.h>
-
-#include <netinet6/in6.h>
-#include <netinet6/in6_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+
 #include <netinet6/nd6.h>
 
-#include <netinet/ip6.h>
-#include <netinet/icmp6.h>
-#include <netinet6/ip6_var.h>
-
 #include <net/if6_var.h>
 
-#ifdef SUPPORT_INET6
+#ifdef _IP6_CFG
 
 /*
@@ -363,6 +361,6 @@
 
 void
-nd6_ns_output (T_IFNET *ifp, T_IN6_ADDR *daddr,
-               T_IN6_ADDR *taddr, T_LLINFO_ND6 *ln, bool_t dad)
+nd6_ns_output (T_IFNET *ifp, const T_IN6_ADDR *daddr,
+               const T_IN6_ADDR *taddr, T_LLINFO_ND6 *ln, bool_t dad)
 {
 	T_NEIGHBOR_SOLICIT_HDR	*nsh;
@@ -429,5 +427,5 @@
 
 		if (saddr && in6_lookup_ifaddr(ifp, saddr))
-			ip6h->src = *saddr;
+			memcpy(&ip6h->src, saddr, sizeof(T_IN6_ADDR));
 		else {
 			/*
@@ -441,5 +439,5 @@
 				return;
 				}
-			ip6h->src = ifa->addr;
+			memcpy(&ip6h->src, &ifa->addr, sizeof(T_IN6_ADDR));
 			}
 		}
@@ -455,5 +453,5 @@
  	nsh->hdr.code        = 0;
  	nsh->hdr.data.data32 = 0;
- 	nsh->target          = *taddr;
+	memcpy(&nsh->target, taddr, sizeof(T_IN6_ADDR));
 
 	if (!dad && (mac = IF_SOFTC_TO_IFADDR(ifp->ic)) != NULL) {
@@ -699,6 +697,6 @@
 
 void
-nd6_na_output (T_IFNET *ifp, T_IN6_ADDR *daddr,
-               T_IN6_ADDR *taddr, uint32_t flags, bool_t tlladdr)
+nd6_na_output (T_IFNET *ifp, const T_IN6_ADDR *daddr,
+               const T_IN6_ADDR *taddr, uint32_t flags, bool_t tlladdr)
 {
 	T_NEIGHBOR_ADVERT_HDR	*nah;
@@ -747,5 +745,5 @@
 		}
 	else
-		ip6h->dst = *daddr;
+		memcpy(&ip6h->dst, daddr, sizeof(T_IN6_ADDR));
 
 	/*
@@ -757,11 +755,11 @@
 		return;
 		}
-	ip6h->src = ifa->addr;
-
- 	/* 近隣通知ヘッダを設定する。*/
- 	nah = GET_NEIGHBOR_ADVERT_HDR(output, IF_IP6_NEIGHBOR_ADVERT_HDR_OFFSET);
- 	nah->hdr.type        = ND_NEIGHBOR_ADVERT;
- 	nah->hdr.code        = 0;
- 	nah->target          = *taddr;
+	memcpy(&ip6h->src, &ifa->addr, sizeof(T_IN6_ADDR));
+
+	/* 近隣通知ヘッダを設定する。*/
+	nah = GET_NEIGHBOR_ADVERT_HDR(output, IF_IP6_NEIGHBOR_ADVERT_HDR_OFFSET);
+	nah->hdr.type        = ND_NEIGHBOR_ADVERT;
+	nah->hdr.code        = 0;
+	memcpy(&nah->target, taddr, sizeof(T_IN6_ADDR));
 
 	/* tlladdr が真ならネットワークインタフェースのアドレスを追加する。*/
@@ -851,3 +849,3 @@
 	}
 
-#endif /* of #ifdef SUPPORT_INET6 */
+#endif /* of #ifdef _IP6_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/nd6_rtr.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/nd6_rtr.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/nd6_rtr.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -93,4 +93,5 @@
 #include <net/ppp_ipcp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_var.h>
 #include <net/net_buf.h>
@@ -100,13 +101,12 @@
 #include <netinet/in.h>
 #include <netinet/in_var.h>
-#include <netinet6/in6.h>
-#include <netinet6/in6_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+
 #include <netinet6/nd6.h>
 #include <netinet6/in6_ifattach.h>
-#include <netinet/ip6.h>
-#include <netinet/icmp6.h>
-#include <netinet6/ip6_var.h>
-
-#include <net/if6_var.h>
+
+#include <net/if_var.h>
 
 /*
@@ -116,5 +116,5 @@
 extern const char *itron_strerror (ER ercd);
 
-#ifdef SUPPORT_INET6
+#ifdef _IP6_CFG
 
 #if NUM_ND6_DEF_RTR_ENTRY > 0
@@ -284,5 +284,5 @@
 	 */
 	for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
-		ia = &ifp->in_ifaddrs[ix];
+		ia = &ifp->in6_ifaddrs[ix];
 		if ((ia->flags & (IN6_IFF_DEFINED | IN6_IFF_AUTOCONF)) != 0 &&
 		     ia->prefix_index != ND6_PREFIX_IX_INVALID) {
@@ -299,5 +299,5 @@
 		 */
 		for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
-			ia = &ifp->in_ifaddrs[ix];
+			ia = &ifp->in6_ifaddrs[ix];
 			if ((ia->flags & (IN6_IFF_DEFINED | IN6_IFF_AUTOCONF)) != 0 &&
 			     ia->prefix_index != ND6_PREFIX_IX_INVALID) {
@@ -316,5 +316,5 @@
 		 */
 		for (ix = NUM_IN6_IFADDR_ENTRY; ix -- > 0; ) {
-			ia = &ifp->in_ifaddrs[ix];
+			ia = &ifp->in6_ifaddrs[ix];
 			if ((ia->flags & (IN6_IFF_DEFINED | IN6_IFF_AUTOCONF)) != 0)
 				ia->flags &= ~IN6_IFF_DETACHED;
@@ -448,5 +448,5 @@
 	/* 各メンバに値を設定する。*/
 	fdr->plistmap = 0;
-	fdr->addr     = *src;
+	memcpy(&fdr->addr, src, sizeof(T_IN6_ADDR));
 	fdr->lifetime = lifetime * SYSTIM_HZ;		/* lifetime の単位は秒 */
 	fdr->flags    = flags;
@@ -478,5 +478,5 @@
 	int_t		ix;
 
-	lla = &ifp->in_ifaddrs[IPV6_IFADDR_IX_LINKLOCAL];
+	lla = &ifp->in6_ifaddrs[IPV6_IFADDR_IX_LINKLOCAL];
 
 	/*
@@ -585,5 +585,5 @@
 
 	/* リンクローカルアドレスが未登録であれば何もしない。*/
-	lla = &ifp->in_ifaddrs[IPV6_IFADDR_IX_LINKLOCAL];
+	lla = &ifp->in6_ifaddrs[IPV6_IFADDR_IX_LINKLOCAL];
 	if ((lla->flags & IN6_IFF_DEFINED) == 0)
 		return E_OK;
@@ -594,5 +594,5 @@
 	 */
 	for (ix = NUM_IN6_IFADDR_ENTRY; ix --; ) {
-		ia = &ifp->in_ifaddrs[ix];
+		ia = &ifp->in6_ifaddrs[ix];
 		if (ia->prefix_index == (pr - nd6_prefix))
 			break;
@@ -634,5 +634,5 @@
 	 */
 	for (ix = NUM_IN6_IFADDR_ENTRY; ix --; ) {
-		ia = &ifp->in_ifaddrs[ix];
+		ia = &ifp->in6_ifaddrs[ix];
 		if (ia->prefix_index == (pr - nd6_prefix))
 			break;
@@ -692,5 +692,4 @@
 	T_ND6_PREFIX	*pr = NULL;
 	int_t		ix;
-	ER		error;
 
 	/* プレフィックスリストから空きのプレフィックスエントリを探索する。*/
@@ -723,5 +722,5 @@
 
 	if ((pr->flags & ND6_PREFIX_FLAG_ONLINK) != 0) {
-		if ((error = nd6_prefix_onlink(pr)) != E_OK)
+		if (nd6_prefix_onlink(pr) != E_OK)
 			return NULL;
 		}
@@ -812,4 +811,11 @@
 			}
 
+#if 1		/* プレフィックスが未登録の場合だけ表示する。*/
+		syslog(LOG_NOTICE, "[ND6 RTR] add prefix: flags[MOH]: %02x, addr: %s\n"
+		                   "                                      from: %s.",
+		                   nd6_def_router[router_index].flags,
+		                   ipv62str(NULL, &pi->prefix),
+		                   ipv62str(NULL, &nd6_def_router[router_index].addr));
+#endif
 		if ((pr->flags & ND6_PREFIX_FLAG_ONLINK) == 0) {
 			/*
@@ -836,5 +842,5 @@
 	 */
 	for (ix = NUM_IN6_IFADDR_ENTRY; ix --; ) {
-		ia = &ifp->in_ifaddrs[ix];
+		ia = &ifp->in6_ifaddrs[ix];
 		if ((ia->flags & IN6_IFF_DEFINED) != 0 &&
 		    ia->prefix_len == pr->prefix_len &&
@@ -892,5 +898,5 @@
 				}
 
-			lla = &ifp->in_ifaddrs[IPV6_IFADDR_IX_LINKLOCAL];
+			lla = &ifp->in6_ifaddrs[IPV6_IFADDR_IX_LINKLOCAL];
 
 			/* プレフィックスマスクを生成する。*/
@@ -922,5 +928,5 @@
 
 			for (ix = NUM_IN6_IFADDR_ENTRY; ix --; ) {
-				ia = &ifp->in_ifaddrs[ix];
+				ia = &ifp->in6_ifaddrs[ix];
 				if ((ia->flags & IN6_IFF_DEFINED) == 0) {
 					in6_ifadd(pr, ia, router_index);
@@ -971,5 +977,5 @@
 	T_NET_BUF		*output;
 	T_IN6_IFADDR		*ifa;
-	T_IN6_ADDR		*saddr;
+	const T_IN6_ADDR	*saddr;
 	uint16_t		len;
 
@@ -1017,5 +1023,5 @@
 
 T_DEF_ROUTER *
-nd6_defrtrlist_lookup (T_IN6_ADDR *src)
+nd6_defrtrlist_lookup (const T_IN6_ADDR *src)
 {
 	T_DEF_ROUTER	*dr = NULL;
@@ -1036,5 +1042,5 @@
  */
 
-T_IN6_ADDR *
+const T_IN6_ADDR *
 nd6_router_lookup (void)
 {
@@ -1260,6 +1266,9 @@
 				syslog(LOG_NOTICE, "[ND6 RTR] preferred(%d) > valid time(%d).", ntohl(pi->preferred), ntohl(pi->valid));
 			else {
-				syslog(LOG_NOTICE, "[ND6 RTR] update prefix: %s from %s.",
-				                   ipv62str(NULL, &pi->prefix), ipv62str(NULL, &ip6h->src));
+#if 0	/* プレフィックスが未登録の場合だけ表示する。*/
+				syslog(LOG_NOTICE, "[ND6 RTR] update prefix: flags[MOH]: %02x, addr: %s\n"
+				                   "                                         from: %s.",
+				                   rah->nd_ra_flags, ipv62str(NULL, &pi->prefix), ipv62str(NULL, &ip6h->src));
+#endif
 				if (rix >= 0) {
 					/*
@@ -1391,5 +1400,5 @@
 
 T_ND6_PREFIX *
-nd6_onlink_prefix_lookup (T_IN6_ADDR *dst)
+nd6_onlink_prefix_lookup (const T_IN6_ADDR *dst)
 {
 	SYSTIM		now;
@@ -1427,3 +1436,3 @@
 	}
 
-#endif /* of #ifdef SUPPORT_INET6 */
+#endif /* of #ifdef _IP6_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/route6.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/route6.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/route6.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -82,4 +82,5 @@
 
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/if.h>
 #include <net/if_loop.h>
@@ -92,18 +93,17 @@
 
 #include <netinet/in.h>
-#include <netinet6/in6.h>
-#include <netinet6/in6_var.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
 #include <netinet6/nd6.h>
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#include <netinet/icmp6.h>
-
-#ifdef SUPPORT_INET6
+
+#ifdef _IP6_CFG
 
 #if 0
-	/*
-	 *  通信帯域を食いつぶす攻撃への対応のため、
-	 *  タイプ 0 経路制御ヘッダの処理を行わない。
-	 */
+/*
+ *  通信帯域を食いつぶす攻撃への対応のため、
+ *  タイプ 0 経路制御ヘッダの処理を行わない。
+ */
 
 /*
@@ -229,3 +229,3 @@
 	}
 
-#endif /* of #ifdef SUPPORT_INET6 */
+#endif /* of #ifdef _IP6_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/scope6.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/scope6.c	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/scope6.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -123,10 +123,14 @@
 #include <net/ethernet.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
+
+#include <netinet/in.h>
+#include <netinet/in_var.h>
 
 #include <netinet6/in6.h>
 #include <netinet6/in6_var.h>
 
-#ifdef SUPPORT_INET6
+#ifdef _IP6_CFG
 
 /*
@@ -135,5 +139,5 @@
 
 uint_t
-in6_addrscope (T_IN6_ADDR *addr)
+in6_addrscope (const T_IN6_ADDR *addr)
 {
 	uint_t scope;
@@ -168,3 +172,3 @@
 	}
 
-#endif /* of #ifdef SUPPORT_INET6 */
+#endif /* of #ifdef _IP6_CFG */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/udp6_input.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/udp6_input.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/udp6_input.c	(revision 331)
@@ -0,0 +1,136 @@
+/*
+ *  TINET (TCP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ *  udp_reply_no_port -- éä¿¡å
+ã«ãã¼ããå®ç¾©ããã¦ããªããã¨ãéç¥ããã
+ */
+
+void
+UDP_REPLY_NO_PORT (T_NET_BUF *input, uint_t off)
+{
+	T_UDP_HDR	*udph;
+
+	udph = (T_UDP_HDR *)(input->buf + off);
+
+#if defined(_IP4_CFG)
+
+	if (GET_IP_VER(input)==IPV6_VERSION) {
+
+		/* ãã«ãã­ã£ã¹ãã¢ãã¬ã¹ã«å±ãããã¼ã¿ã°ã©ã ã¯ ICMP ã¨ã©ã¼ãéç¥ããªãã*/
+		if (!IN6_IS_ADDR_MULTICAST(&GET_IP6_HDR(input)->dst)) {
+			syslog(LOG_INFO, "[UDP] unexp port: %d.", ntohs(udph->dport));
+
+			/* icmp6_error ã§ããããã¯ã¼ã¯ãããã¡ input ãè¿å´ããã*/
+			icmp6_error(input, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0);
+			}
+		else
+			syscall(rel_net_buf(input));
+		}
+	else /*if (GET_IP_VER(input)==IPV4_VERSION)*/ {
+
+		/* ã­ã¼ã«ã« IP ã¢ãã¬ã¹ã«å±ãããã¼ã¿ã°ã©ã ã®ã¿ ICMP ã¨ã©ã¼ãéç¥ããã*/
+		if (ntohl(GET_IP4_HDR(input)->dst) == IF_GET_IFNET()->in4_ifaddr.addr) {
+			syslog(LOG_INFO, "[UDP] unexp port: %d.", ntohs(udph->dport));
+
+			icmp_error(ICMP4_UNREACH_PORT, input);
+			/* icmp_error ã§ã¯ããããã¯ã¼ã¯ãããã¡ input ãè¿å´ããªãã®ã§ä¸ã¸æããã*/
+			}
+		syscall(rel_net_buf(input));
+		}
+
+#else	/* of #if defined(_IP4_CFG) */
+
+	NET_COUNT_MIB(udp_stats.udpNoPorts, 1);
+
+	/* ãã«ãã­ã£ã¹ãã¢ãã¬ã¹ã«å±ãããã¼ã¿ã°ã©ã ã¯ ICMP ã¨ã©ã¼ãéç¥ããªãã*/
+	if (!IN6_IS_ADDR_MULTICAST(&GET_IP6_HDR(input)->dst)) {
+		syslog(LOG_INFO, "[UDP] unexp port: %d.", ntohs(udph->dport));
+
+		/* icmp6_error ã§ããããã¯ã¼ã¯ãããã¡ input ãè¿å´ããã*/
+		icmp6_error(input, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0);
+		}
+	else
+		syscall(rel_net_buf(input));
+
+#endif	/* of #if defined(_IP4_CFG) */
+
+	NET_COUNT_UDP(net_count_udp.in_err_packets, 1);
+	NET_COUNT_MIB(udp_stats.udpInErrors, 1);
+	NET_COUNT_MIB(udp_stats.udpNoPorts, 1);
+	}
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/udp6_subr.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/udp6_subr.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/netinet6/udp6_subr.c	(revision 331)
@@ -0,0 +1,172 @@
+/*
+ *  TINET (UDP/IP Protocol Stack)
+ * 
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
+ *                   Tomakomai National College of Technology, JAPAN
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã® (1)ï½(4) ã®æ¡ä»¶ãï¼Free Software Foundation 
+ *  ã«ãã£ã¦å
+¬è¡¨ããã¦ãã GNU General Public License ã® Version 2 ã«è¨
+ *  è¿°ããã¦ããæ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§ã¢ï¼æ¬ã½ããã¦ã§ã¢
+ *  ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼
+ *  å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®æ¡ä»¶ãæºãããã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ãã®é©ç¨å¯è½æ§ã
+ *  å«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´
+ *  æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ãã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must ceproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ *  udp6_is_dstaddr_accept -- UDP ã®ãã¦å
+ã¢ãã¬ã¹ãæ­£ããããã§ãã¯ããã
+ *
+ *    ä»¥ä¸ã®å ´åããã¼ã¿ã°ã©ã ãåä¿¡ããã
+ *
+ *      ã»ãã¦å
+ã¢ãã¬ã¹ããã«ãã­ã£ã¹ã
+ */
+
+static bool_t
+udp6_is_dstaddr_accept (T_IN6_ADDR *myaddr, T_NET_BUF *input)
+{
+	T_IP6_HDR	*ip6h;
+
+	ip6h = GET_IP6_HDR(input);
+
+	if (IN6_IS_ADDR_MULTICAST(&ip6h->dst))
+		return true;
+	else
+		return INN6_IS_DSTADDR_ACCEPT(myaddr, input);
+	}
+
+#if defined(_IP4_CFG) && defined(API_CFG_IP4MAPPED_ADDR)
+
+#ifdef DHCP_CFG
+
+/*
+ *  udpn_is_dstaddr_accept -- UDP ã®ãã¦å
+ã¢ãã¬ã¹ãæ­£ããããã§ãã¯ããã
+ *
+ *    DHCP_CFG ãå®ç¾©ããã¦ããã¨ãã¯ãä»¥ä¸ã®ãã¼ã¿ã°ã©ã ãåä¿¡ããã
+ *
+ *      ã»ãã¦å
+ã¢ãã¬ã¹ããã­ã¼ãã­ã£ã¹ã
+ *      ã»ã­ã¼ã«ã«ã¢ãã¬ã¹ãæªå®ç¾©
+ */
+
+static bool_t
+udpn_is_dstaddr_accept (T_IN6_ADDR *myaddr, T_NET_BUF *input)
+{
+	T_IFNET *ifp = IF_GET_IFNET();
+
+	if        (GET_IP_VER(input)==IPV6_VERSION)
+		return udp6_is_dstaddr_accept(myaddr, input);
+	else /*if (GET_IP_VER(input)==IPV4_VERSION)*/ {
+		T_IP4_HDR	*ip4h;
+
+		ip4h = GET_IP4_HDR(input);
+
+		if (ifp->in4_ifaddr.addr == IPV4_ADDRANY    ||
+		    ntohl(ip4h->dst) == IPV4_ADDR_BROADCAST ||
+		    ntohl(ip4h->dst) == ((ifp->in4_ifaddr.addr & ifp->in4_ifaddr.mask) | ~ifp->in4_ifaddr.mask))
+			return true;
+		else
+			return inn_is_dstaddr_accept(myaddr, input);
+		}
+	}
+
+#else	/* of #ifdef DHCP_CFG */
+
+/*
+ *  udpn_is_dstaddr_accept -- UDP ã®ãã¦å
+ã¢ãã¬ã¹ãæ­£ããããã§ãã¯ããã
+ *
+ *    ä»¥ä¸ã®å ´åããã¼ã¿ã°ã©ã ãåä¿¡ããã
+ *
+ *      ã»ãã¦å
+ã¢ãã¬ã¹ããã­ã¼ãã­ã£ã¹ã
+ */
+
+static bool_t
+udpn_is_dstaddr_accept (T_IN6_ADDR *myaddr, T_NET_BUF *input)
+{
+	T_IFNET *ifp = IF_GET_IFNET();
+
+	if        (GET_IP_VER(input) == IPV6_VERSION)
+		return udp6_is_dstaddr_accept(myaddr, input);
+	else /*if (GET_IP_VER(input) == IPV4_VERSION)*/ {
+		T_IP4_HDR	*ip4h;
+
+		ip4h = GET_IP4_HDR(input);
+
+		if (ntohl(ip4h->dst) == IPV4_ADDR_BROADCAST ||
+		    ntohl(ip4h->dst) == ((ifp->in4_ifaddr.addr & ifp->in4_ifaddr.mask) | ~ifp->in4_ifaddr.mask))
+			return true;
+		else
+			return inn_is_dstaddr_accept(myaddr, input);
+		}
+	}
+
+#endif	/* of #ifdef DHCP_CFG */
+
+#endif	/* of #if defined(_IP4_CFG) && defined(API_CFG_IP4MAPPED_ADDR) */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/tcpip_api.csv
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/tcpip_api.csv	(revision 321)
+++ 	(revision )
@@ -1,12 +1,0 @@
-tcp4_rep,TCP_CRE_REP, #tcp4_repid { .tcp4_repatr { &ipv4addr &portno } },,
-tcp6_rep,TCP6_CRE_REP,#tcp6_repid { .tcp6_repatr { &ipv6addr &portno } },,
-tcp4_cep,TCP_CRE_CEP, #tcp4_cepid { .tcp4_cepatr &sbuf &sbufsz &rbuf &rbufsz &callback },,
-tcp6_cep,TCP6_CRE_CEP,#tcp6_cepid { .tcp6_cepatr &sbuf &sbufsz &rbuf &rbufsz &callback },,
-udp4_cep,UDP_CRE_CEP, #udp4_cepid { .udp4_cepatr { &ipv4addr &portno } &callback },,
-udp6_cep,UDP6_CRE_CEP,#udp6_cepid { .udp6_cepatr { &ipv6addr &portno } &callback },,
-vrid_tcp4_rep,VRID_TCP_REP, #vrid_tcp4_repid,,
-vrid_tcp4_cep,VRID_TCP_CEP, #vrid_tcp4_cepid,,
-vrid_tcp6_rep,VRID_TCP6_REP,#vrid_tcp6_repid,,
-vrid_tcp6_cep,VRID_TCP6_CEP,#vrid_tcp6_cepid,,
-vrid_udp4_cep,VRID_UDP_CEP, #vrid_udp4_cepid,,
-vrid_udp6_cep,VRID_UDP6_CEP,#vrid_udp6_cepid,,
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/tcpip_api.def
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/tcpip_api.def	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/tcpip_api.def	(revision 331)
@@ -1,12 +1,12 @@
-TCP_CRE_REP  #tcp4_repid* { .tcp4_repatr { &ipv4addr &portno } }
-TCP6_CRE_REP #tcp6_repid* { .tcp6_repatr { &ipv6addr &portno } }
-TCP_CRE_CEP  #tcp4_cepid* { .tcp4_cepatr &sbuf &sbufsz &rbuf &rbufsz &callback }
-TCP6_CRE_CEP #tcp6_cepid* { .tcp6_cepatr &sbuf &sbufsz &rbuf &rbufsz &callback }
-UDP_CRE_CEP  #udp4_cepid* { .udp4_cepatr { &ipv4addr &portno } &callback }
-UDP6_CRE_CEP #udp6_cepid* { .udp6_cepatr { &ipv6addr &portno } &callback }
-VRID_TCP4_REP  #vrid_tcp4_repid*
-VRID_TCP4_CEP  #vrid_tcp4_cepid*
-VRID_TCP6_REP #vrid_tcp6_repid*
-VRID_TCP6_CEP #vrid_tcp6_cepid*
-VRID_UDP4_CEP  #vrid_udp4_cepid*
-VRID_UDP6_CEP #vrid_udp6_cepid*
+TCP_CRE_REP  #tcp4_repid* { .tcp4_repatr { &ipv4addr &portno } }  
+TCP6_CRE_REP #tcp6_repid* { .tcp6_repatr { &ipv6addr &portno } }  
+TCP_CRE_CEP  #tcp4_cepid* { .tcp4_cepatr &sbuf &sbufsz &rbuf &rbufsz &callback }  
+TCP6_CRE_CEP #tcp6_cepid* { .tcp6_cepatr &sbuf &sbufsz &rbuf &rbufsz &callback }  
+UDP_CRE_CEP  #udp4_cepid* { .udp4_cepatr { &ipv4addr &portno } &callback }  
+UDP6_CRE_CEP #udp6_cepid* { .udp6_cepatr { &ipv6addr &portno } &callback }  
+VRID_TCP_REP  #vrid_tcp4_repid*  
+VRID_TCP_CEP  #vrid_tcp4_cepid*  
+VRID_TCP6_REP #vrid_tcp6_repid*  
+VRID_TCP6_CEP #vrid_tcp6_cepid*  
+VRID_UDP_CEP  #vrid_udp4_cepid*  
+VRID_UDP6_CEP #vrid_udp6_cepid*  
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/tcpip_sym.def
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/tcpip_sym.def	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/tcpip_sym.def	(revision 331)
@@ -48,4 +48,5 @@
 TCP_REP_FLG_DYNAMIC
 TCP_REP_FLG_VALID
+TCP_CEP_FLG_IPV4
 TCP_CEP_FLG_ACK_NOW
 TCP_CEP_FLG_DEL_ACK
@@ -73,4 +74,5 @@
 TCP_CEP_FLG_WBCS_SENT
 TCP_CEP_FLG_WBCS_ACKED
+TCP_CEP_FLG_NOT_CLEAR
 TCP_CEP_EVT_ESTABLISHED
 TCP_CEP_EVT_CLOSED
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/tinet.tf
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/tinet.tf	(revision 321)
+++ 	(revision )
@@ -1,439 +1,0 @@
-$ ======================================================================
-$ 
-$   TINET (TCP/IP Protocol Stack)
-$ 
-$   Copyright (C) 2001-2007 by Dep. of Computer Science and Engineering
-$                    Tomakomai National College of Technology, JAPAN
-$  
-$   上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
-$   ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
-$   変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
-$   (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
-$       権表示，この利用条件および下記の無保証規定が，そのままの形でソー
-$       スコード中に含まれていること．
-$   (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
-$       用できる形で再配布する場合には，再配布に伴うドキュメント（利用
-$       者マニュアルなど）に，上記の著作権表示，この利用条件および下記
-$       の無保証規定を掲載すること．
-$   (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
-$       用できない形で再配布する場合には，次のいずれかの条件を満たすこ
-$       と．
-$     (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
-$         作権表示，この利用条件および下記の無保証規定を掲載すること．
-$   (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
-$       害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
-$       また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
-$       由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
-$       免責すること．
-$  
-$   本ソフトウェアは，無保証で提供されているものである．上記著作権者お
-$   よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
-$   に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
-$   アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
-$   の責任を負わない．
-$ 
-$   @(#) $Id$
-$  
-$ =====================================================================
-
-$ =====================================================================
-$ tinet_cfg.h の生成
-$ =====================================================================
-
-$FILE "tinet_cfg.h"$
-/* tinet_cfg.h */$NL$
-#ifndef _TINET_CFG_H_$NL$
-#define _TINET_CFG_H_$NL$
-$NL$
-$FOREACH id TCP4_REP.ID_LIST$
-	#define $id$	$+id$$NL$
-$END$
-$FOREACH id TCP6_REP.ID_LIST$
-	#define $id$	$+id$$NL$
-$END$
-$FOREACH id TCP4_CEP.ID_LIST$
-	#define $id$	$+id$$NL$
-$END$
-$FOREACH id TCP6_CEP.ID_LIST$
-	#define $id$	$+id$$NL$
-$END$
-$FOREACH id UDP4_CEP.ID_LIST$
-	#define $id$	$+id$$NL$
-$END$
-$FOREACH id UDP6_CEP.ID_LIST$
-	#define $id$	$+id$$NL$
-$END$
-$FOREACH id VRID_TCP4_REP.ID_LIST$
-	#define $id$	$+id + LENGTH(TCP4_REP.ID_LIST)$$NL$
-$END$
-$FOREACH id VRID_TCP4_CEP.ID_LIST$
-	#define $id$	$+id + LENGTH(TCP4_CEP.ID_LIST)$$NL$
-$END$
-$FOREACH id VRID_TCP6_REP.ID_LIST$
-	#define $id$	$+id + LENGTH(TCP6_REP.ID_LIST)$$NL$
-$END$
-$FOREACH id VRID_TCP6_CEP.ID_LIST$
-	#define $id$	$+id + LENGTH(TCP6_CEP.ID_LIST)$$NL$
-$END$
-$FOREACH id VRID_UDP4_CEP.ID_LIST$
-	#define $id$	$+id + LENGTH(UDP4_CEP.ID_LIST)$$NL$
-$END$
-$FOREACH id VRID_UDP6_CEP.ID_LIST$
-	#define $id$	$+id + LENGTH(UDP6_CEP.ID_LIST)$$NL$
-$END$
-$NL$
-#endif /* _TINET_CFG_H_ */$NL$
-
-$ =====================================================================
-$ tinet_cfg.c の生成
-$ =====================================================================
-
-$FILE "tinet_cfg.c"$
-/* tinet_cfg.c */$NL$
-$NL$
-#include <kernel.h>$NL$
-#include <sil.h>$NL$
-#include "kernel_cfg.h"$NL$
-#include "tinet_cfg.h"$NL$
-#include <tinet_defs.h>$NL$
-#include <tinet_config.h>$NL$
-#include <net/if.h>$NL$
-#include <net/if_ppp.h>$NL$
-#include <net/if_loop.h>$NL$
-#include <net/ethernet.h>$NL$
-#include <net/net.h>$NL$
-#include <net/net_buf.h>$NL$
-#include <netinet/in.h>$NL$
-#include <netinet/in_itron.h>$NL$
-#include <netinet/ip.h>$NL$
-#include <netinet/ip6.h>$NL$
-#include <netinet/tcp.h>$NL$
-#include <netinet/tcp_timer.h>$NL$
-#include <netinet/tcp_var.h>$NL$
-#include <netinet/tcp_fsm.h>$NL$
-#include <netinet/udp_var.h>$NL$
-
-$ 
-$  インクルードディレクティブ（#include）
-$ 
-$NL$
-/*$NL$
-$SPC$*  Include Directives (#include)$NL$
-$SPC$*/$NL$
-$NL$
-$INCLUDES$
-
-$	// TCP (IPv4) 受付口
-$IF LENGTH(TCP4_REP.ID_LIST) + LENGTH(VRID_TCP4_REP.ID_LIST)$
-	$NL$
-	#define TNUM_TCP_REPID	$LENGTH(TCP4_REP.ID_LIST) + LENGTH(VRID_TCP4_REP.ID_LIST)$$NL$
-	$NL$
-	const ID tmax_tcp_repid = (TMIN_TCP_REPID + TNUM_TCP_REPID - 1);$NL$
-	$NL$
-	T_TCP4_REP tcp_rep[TNUM_TCP_REPID] = {$NL$
-	$FOREACH id TCP4_REP.ID_LIST$
-		$TAB${$NL$
-			$TAB$$TAB$$TCP4_REP.TCP4_REPATR[id]$,$NL$
-			$TAB$$TAB${ $TCP4_REP.IPV4ADDR[id]$, $TCP4_REP.PORTNO[id]$ },$NL$
-	#if defined(TCP_CFG_EXTENTIONS)$NL$
-			$TAB$$TAB$TCP_REP_FLG_VALID,$NL$
-			$TAB$$TAB$SEM_TCP_REP_LOCK$+id$,$NL$
-	#endif$NL$
-			$TAB$$TAB$},$NL$
-	$END$
-	$FOREACH id VRID_TCP4_REP.ID_LIST$
-		$TAB${$NL$
-			$TAB$$TAB$0,$NL$
-			$TAB$$TAB${ IPV4_ADDRANY, TCP_PORTANY },$NL$
-	#if defined(TCP_CFG_EXTENTIONS)$NL$
-			$TAB$$TAB$TCP_REP_FLG_DYNAMIC,$NL$
-			$TAB$$TAB$SEM_TCP_REP_LOCK$+id + LENGTH(TCP4_REP.ID_LIST)$,$NL$
-	#endif$NL$
-			$TAB$$TAB$},$NL$
-	$END$
-		$TAB$};$NL$
-$END$
-
-$	// TCP (IPv6) 受付口
-$IF LENGTH(TCP6_REP.ID_LIST) + LENGTH(VRID_TCP6_REP.ID_LIST)$
-	$NL$
-	#define TNUM_TCP_REPID	$LENGTH(TCP6_REP.ID_LIST) + LENGTH(VRID_TCP6_REP.ID_LIST)$$NL$
-	$NL$
-	const ID tmax_tcp_repid = (TMIN_TCP_REPID + TNUM_TCP_REPID - 1);$NL$
-	$NL$
-	T_TCP6_REP tcp_rep[TNUM_TCP_REPID] = {$NL$
-	$FOREACH id TCP6_REP.ID_LIST$
-		$TAB${$NL$
-			$TAB$$TAB$$TCP6_REP.TCP6_REPATR[id]$,$NL$
-			$TAB$$TAB${ $TCP6_REP.IPV6ADDR[id]$, $TCP6_REP.PORTNO[id]$ },$NL$
-	#if defined(TCP_CFG_EXTENTIONS)$NL$
-			$TAB$$TAB$TCP_REP_FLG_VALID,$NL$
-			$TAB$$TAB$SEM_TCP_REP_LOCK$+id$,$NL$
-	#endif$NL$
-			$TAB$$TAB$},$NL$
-	$END$
-	$FOREACH id VRID_TCP6_REP.ID_LIST$
-		$TAB${$NL$
-			$TAB$$TAB$0,$NL$
-			$TAB$$TAB${ IPV6_ADDRANY, TCP_PORTANY },$NL$
-	#if defined(TCP_CFG_EXTENTIONS)$NL$
-			$TAB$$TAB$TCP_REP_FLG_DYNAMIC,$NL$
-			$TAB$$TAB$SEM_TCP_REP_LOCK$+id + LENGTH(TCP6_REP.ID_LIST)$,$NL$
-	#endif$NL$
-			$TAB$$TAB$},$NL$
-	$END$
-		$TAB$};$NL$
-$END$
-
-$	// TCP (IPv4) 通信端点
-$IF LENGTH(TCP4_CEP.ID_LIST) + LENGTH(VRID_TCP4_CEP.ID_LIST)$
-	$NL$
-	#define TNUM_TCP_CEPID	$LENGTH(TCP4_CEP.ID_LIST) + LENGTH(VRID_TCP4_CEP.ID_LIST)$$NL$
-	$NL$
-	const ID tmax_tcp_cepid = (TMIN_TCP_CEPID + TNUM_TCP_CEPID - 1);$NL$
-	$NL$
-	T_TCP4_CEP tcp_cep[TNUM_TCP_CEPID] = {$NL$
-	$FOREACH id TCP4_CEP.ID_LIST$
-		$TAB${$NL$
-			$TAB$$TAB$$TCP4_CEP.TCP4_CEPATR[id]$,$NL$
-			$TAB$$TAB$(void*)$TCP4_CEP.SBUF[id]$,$NL$
-			$TAB$$TAB$$TCP4_CEP.SBUFSZ[id]$,$NL$
-			$TAB$$TAB$(void*)$TCP4_CEP.RBUF[id]$,$NL$
-			$TAB$$TAB$$TCP4_CEP.RBUFSZ[id]$,$NL$
-			$TAB$$TAB$(t_tcp_callback)(FP)$TCP4_CEP.CALLBACK[id]$,$NL$
-			$TAB$$TAB$TCP_CEP_FLG_VALID,$NL$
-			$TAB$$TAB$SEM_TCP_CEP_LOCK$+id$,$NL$
-			$TAB$$TAB$FLG_TCP_CEP_EST$+id$,$NL$
-			$TAB$$TAB$FLG_TCP_CEP_SND$+id$,$NL$
-			$TAB$$TAB$FLG_TCP_CEP_RCV$+id$,$NL$
-			$TAB$$TAB$},$NL$
-	$END$
-	$FOREACH id VRID_TCP4_CEP.ID_LIST$
-		$TAB${$NL$
-			$TAB$$TAB$0,$NL$
-			$TAB$$TAB$(void*)NULL,$NL$
-			$TAB$$TAB$0,$NL$
-			$TAB$$TAB$(void*)NULL,$NL$
-			$TAB$$TAB$0,$NL$
-			$TAB$$TAB$(t_tcp_callback)(FP)NULL,$NL$
-			$TAB$$TAB$TCP_CEP_FLG_DYNAMIC,$NL$
-			$TAB$$TAB$SEM_TCP_CEP_LOCK$+id + LENGTH(TCP4_CEP.ID_LIST)$,$NL$
-			$TAB$$TAB$FLG_TCP_CEP_EST$+id + LENGTH(TCP4_CEP.ID_LIST)$,$NL$
-			$TAB$$TAB$FLG_TCP_CEP_SND$+id + LENGTH(TCP4_CEP.ID_LIST)$,$NL$
-			$TAB$$TAB$FLG_TCP_CEP_RCV$+id + LENGTH(TCP4_CEP.ID_LIST)$,$NL$
-			$TAB$$TAB$},$NL$
-	$END$
-		$TAB$};$NL$
-$END$
-
-$	// TCP (IPv6) 通信端点
-$IF LENGTH(TCP6_CEP.ID_LIST) + LENGTH(VRID_TCP6_CEP.ID_LIST)$
-	$NL$
-	#define TNUM_TCP_CEPID	$LENGTH(TCP6_CEP.ID_LIST) + LENGTH(VRID_TCP6_CEP.ID_LIST)$$NL$
-	$NL$
-	const ID tmax_tcp_cepid = (TMIN_TCP_CEPID + TNUM_TCP_CEPID - 1);$NL$
-	$NL$
-	T_TCP6_CEP tcp_cep[TNUM_TCP_CEPID] = {$NL$
-	$FOREACH id TCP6_CEP.ID_LIST$
-		$TAB${$NL$
-			$TAB$$TAB$$TCP6_CEP.TCP6_CEPATR[id]$,$NL$
-			$TAB$$TAB$(void*)$TCP6_CEP.SBUF[id]$,$NL$
-			$TAB$$TAB$$TCP6_CEP.SBUFSZ[id]$,$NL$
-			$TAB$$TAB$(void*)$TCP6_CEP.RBUF[id]$,$NL$
-			$TAB$$TAB$$TCP6_CEP.RBUFSZ[id]$,$NL$
-			$TAB$$TAB$(t_tcp_callback)(FP)$TCP6_CEP.CALLBACK[id]$,$NL$
-			$TAB$$TAB$TCP_CEP_FLG_VALID,$NL$
-			$TAB$$TAB$SEM_TCP_CEP_LOCK$+id$,$NL$
-			$TAB$$TAB$FLG_TCP_CEP_EST$+id$,$NL$
-			$TAB$$TAB$FLG_TCP_CEP_SND$+id$,$NL$
-			$TAB$$TAB$FLG_TCP_CEP_RCV$+id$,$NL$
-			$TAB$$TAB$},$NL$
-	$END$
-	$FOREACH id VRID_TCP6_CEP.ID_LIST$
-		$TAB${$NL$
-			$TAB$$TAB$0,$NL$
-			$TAB$$TAB$(void*)NULL,$NL$
-			$TAB$$TAB$0,$NL$
-			$TAB$$TAB$(void*)NULL,$NL$
-			$TAB$$TAB$0,$NL$
-			$TAB$$TAB$(t_tcp_callback)(FP)NULL,$NL$
-			$TAB$$TAB$TCP_CEP_FLG_DYNAMIC,$NL$
-			$TAB$$TAB$SEM_TCP_CEP_LOCK$+id + LENGTH(TCP6_CEP.ID_LIST)$,$NL$
-			$TAB$$TAB$FLG_TCP_CEP_EST$+id + LENGTH(TCP6_CEP.ID_LIST)$,$NL$
-			$TAB$$TAB$FLG_TCP_CEP_SND$+id + LENGTH(TCP6_CEP.ID_LIST)$,$NL$
-			$TAB$$TAB$FLG_TCP_CEP_RCV$+id + LENGTH(TCP6_CEP.ID_LIST)$,$NL$
-			$TAB$$TAB$},$NL$
-	$END$
-		$TAB$};$NL$
-$END$
-
-$	// UDP (IPv4) 通信端点
-$IF LENGTH(UDP4_CEP.ID_LIST) + LENGTH(VRID_UDP4_CEP.ID_LIST)$
-	$NL$
-	#define TNUM_UDP_CEPID	$LENGTH(UDP4_CEP.ID_LIST) + LENGTH(VRID_UDP4_CEP.ID_LIST)$$NL$
-	$NL$
-	const ID tmax_udp_cepid = (TMIN_UDP_CEPID + TNUM_UDP_CEPID - 1);$NL$
-	$NL$
-	T_UDP4_CEP udp_cep[TNUM_UDP_CEPID] = {$NL$
-	$FOREACH id UDP4_CEP.ID_LIST$
-		$TAB${$NL$
-			$TAB$$TAB$$UDP4_CEP.UDP4_CEPATR[id]$,$NL$
-			$TAB$$TAB${ $UDP4_CEP.IPV4ADDR[id]$, $UDP4_CEP.PORTNO[id]$ },$NL$
-			$TAB$$TAB$(t_udp_callback)(FP)$UDP4_CEP.CALLBACK[id]$,$NL$
-			$TAB$$TAB$UDP_CEP_FLG_VALID,$NL$
-			$TAB$$TAB$SEM_UDP_CEP_LOCK$+id$,$NL$
-			$TAB$$TAB$TA_NULL,$NL$
-			$TAB$$TAB$TA_NULL,$NL$
-			$TAB$$TAB$DTQ_UDP_RCVQ$+id$,$NL$
-			$TAB$$TAB$},$NL$
-	$END$
-	$FOREACH id VRID_UDP4_CEP.ID_LIST$
-		$TAB${$NL$
-			$TAB$$TAB$0,$NL$
-			$TAB$$TAB${ IPV4_ADDRANY, UDP_PORTANY },$NL$
-			$TAB$$TAB$(t_udp_callback)(FP)NULL,$NL$
-			$TAB$$TAB$UDP_CEP_FLG_DYNAMIC,$NL$
-			$TAB$$TAB$SEM_UDP_CEP_LOCK$+id + LENGTH(UDP4_CEP.ID_LIST)$,$NL$
-			$TAB$$TAB$TA_NULL,$NL$
-			$TAB$$TAB$TA_NULL,$NL$
-			$TAB$$TAB$DTQ_UDP_RCVQ$+id + LENGTH(UDP4_CEP.ID_LIST)$,$NL$
-			$TAB$$TAB$},$NL$
-	$END$
-		$TAB$};$NL$
-$END$
-
-$	// UDP (IPv6) 通信端点
-$IF LENGTH(UDP6_CEP.ID_LIST) + LENGTH(VRID_UDP6_CEP.ID_LIST)$
-	$NL$
-	#define TNUM_UDP_CEPID	$LENGTH(UDP6_CEP.ID_LIST) + LENGTH(VRID_UDP6_CEP.ID_LIST)$$NL$
-	$NL$
-	const ID tmax_udp_cepid = (TMIN_UDP_CEPID + TNUM_UDP_CEPID - 1);$NL$
-	$NL$
-	T_UDP6_CEP udp_cep[TNUM_UDP_CEPID] = {$NL$
-	$FOREACH id UDP6_CEP.ID_LIST$
-		$TAB${$NL$
-			$TAB$$TAB$$UDP6_CEP.UDP6_CEPATR[id]$,$NL$
-			$TAB$$TAB${ $UDP6_CEP.IPV6ADDR[id]$, $UDP6_CEP.PORTNO[id]$ },$NL$
-			$TAB$$TAB$(t_udp_callback)(FP)$UDP6_CEP.CALLBACK[id]$,$NL$
-			$TAB$$TAB$UDP_CEP_FLG_VALID,$NL$
-			$TAB$$TAB$SEM_UDP_CEP_LOCK$+id$,$NL$
-			$TAB$$TAB$TA_NULL,$NL$
-			$TAB$$TAB$TA_NULL,$NL$
-			$TAB$$TAB$DTQ_UDP_RCVQ$+id$,$NL$
-			$TAB$$TAB$},$NL$
-	$END$
-	$FOREACH id VRID_UDP6_CEP.ID_LIST$
-		$TAB${$NL$
-			$TAB$$TAB$0,$NL$
-			$TAB$$TAB${ IPV6_ADDRANY, UDP_PORTANY },$NL$
-			$TAB$$TAB$(t_udp_callback)(FP)NULL,$NL$
-			$TAB$$TAB$UDP_CEP_FLG_DYNAMIC,$NL$
-			$TAB$$TAB$SEM_UDP_CEP_LOCK$+id + LENGTH(UDP6_CEP.ID_LIST)$,$NL$
-			$TAB$$TAB$TA_NULL,$NL$
-			$TAB$$TAB$TA_NULL,$NL$
-			$TAB$$TAB$DTQ_UDP_RCVQ$+id + LENGTH(UDP6_CEP.ID_LIST)$,$NL$
-			$TAB$$TAB$},$NL$
-	$END$
-		$TAB$};$NL$
-$END$
-
-$ =====================================================================
-$ tinet_kern.cfg の生成
-$ =====================================================================
-
-$FILE "tinet_kern.cfg"$
-/* tinet_kern.cfg */$NL$
-
-$	// TCP (IPv4) 受付口
-$IF LENGTH(TCP4_REP.ID_LIST) + LENGTH(VRID_TCP4_REP.ID_LIST)$
-	$NL$
-	#if defined(TCP_CFG_EXTENTIONS)$NL$
-	$FOREACH id TCP4_REP.ID_LIST$
-		CRE_SEM(SEM_TCP_REP_LOCK$+id$, { TA_TPRI, 1, 1 });$NL$
-	$END$
-	$FOREACH id VRID_TCP4_REP.ID_LIST$
-		CRE_SEM(SEM_TCP_REP_LOCK$+id + LENGTH(TCP4_REP.ID_LIST)$, { TA_TPRI, 1, 1 });$NL$
-	$END$
-	#endif$NL$
-$END$
-
-$	// TCP (IPv4) 受付口
-$IF LENGTH(TCP6_REP.ID_LIST) + LENGTH(VRID_TCP6_REP.ID_LIST)$
-	$NL$
-	#if defined(TCP_CFG_EXTENTIONS)$NL$
-	$FOREACH id TCP6_REP.ID_LIST$
-		CRE_SEM(SEM_TCP_REP_LOCK$+id$, { TA_TPRI, 1, 1 });$NL$
-	$END$
-	$FOREACH id VRID_TCP6_REP.ID_LIST$
-		CRE_SEM(SEM_TCP_REP_LOCK$+id + LENGTH(TCP6_REP.ID_LIST)$, { TA_TPRI, 1, 1 });$NL$
-	$END$
-	#endif$NL$
-$END$
-
-$	// TCP (IPv4) 通信端点
-$IF LENGTH(TCP4_CEP.ID_LIST) + LENGTH(VRID_TCP4_CEP.ID_LIST)$
-	$NL$
-	$FOREACH id TCP4_CEP.ID_LIST$
-		$NL$
-		CRE_SEM(SEM_TCP_CEP_LOCK$+id$,{ TA_TPRI, 1, 1 });$NL$
-		CRE_FLG(FLG_TCP_CEP_EST$+id$,{ TA_TFIFO|TA_WSGL, TCP_CEP_EVT_CLOSED });$NL$
-		CRE_FLG(FLG_TCP_CEP_SND$+id$,{ TA_TFIFO|TA_WSGL, TCP_CEP_EVT_SWBUF_READY });$NL$
-		CRE_FLG(FLG_TCP_CEP_RCV$+id$,{ TA_TFIFO|TA_WSGL, 0 });$NL$
-	$END$
-	$FOREACH id VRID_TCP4_CEP.ID_LIST$
-		$NL$
-		CRE_SEM(SEM_TCP_CEP_LOCK$+id + LENGTH(TCP4_CEP.ID_LIST)$,{ TA_TPRI, 1, 1 });$NL$
-		CRE_FLG(FLG_TCP_CEP_EST$+id + LENGTH(TCP4_CEP.ID_LIST)$,{ TA_TFIFO|TA_WSGL, TCP_CEP_EVT_CLOSED });$NL$
-		CRE_FLG(FLG_TCP_CEP_SND$+id + LENGTH(TCP4_CEP.ID_LIST)$,{ TA_TFIFO|TA_WSGL, TCP_CEP_EVT_SWBUF_READY });$NL$
-		CRE_FLG(FLG_TCP_CEP_RCV$+id + LENGTH(TCP4_CEP.ID_LIST)$,{ TA_TFIFO|TA_WSGL, 0 });$NL$
-	$END$
-$END$
-
-$	// TCP (IPv6) 通信端点
-$IF LENGTH(TCP6_CEP.ID_LIST) + LENGTH(VRID_TCP6_CEP.ID_LIST)$
-	$NL$
-	$FOREACH id TCP6_CEP.ID_LIST$
-		$NL$
-		CRE_SEM(SEM_TCP_CEP_LOCK$+id$,{ TA_TPRI, 1, 1 });$NL$
-		CRE_FLG(FLG_TCP_CEP_EST$+id$,{ TA_TFIFO|TA_WSGL, TCP_CEP_EVT_CLOSED });$NL$
-		CRE_FLG(FLG_TCP_CEP_SND$+id$,{ TA_TFIFO|TA_WSGL, TCP_CEP_EVT_SWBUF_READY });$NL$
-		CRE_FLG(FLG_TCP_CEP_RCV$+id$,{ TA_TFIFO|TA_WSGL, 0 });$NL$
-	$END$
-	$FOREACH id VRID_TCP6_CEP.ID_LIST$
-		$NL$
-		CRE_SEM(SEM_TCP_CEP_LOCK$+id + LENGTH(TCP6_CEP.ID_LIST)$,{ TA_TPRI, 1, 1 });$NL$
-		CRE_FLG(FLG_TCP_CEP_EST$+id + LENGTH(TCP6_CEP.ID_LIST)$,{ TA_TFIFO|TA_WSGL, TCP_CEP_EVT_CLOSED });$NL$
-		CRE_FLG(FLG_TCP_CEP_SND$+id + LENGTH(TCP6_CEP.ID_LIST)$,{ TA_TFIFO|TA_WSGL, TCP_CEP_EVT_SWBUF_READY });$NL$
-		CRE_FLG(FLG_TCP_CEP_RCV$+id + LENGTH(TCP6_CEP.ID_LIST)$,{ TA_TFIFO|TA_WSGL, 0 });$NL$
-	$END$
-$END$
-
-$	// UDP (IPv4) 通信端点
-$IF LENGTH(UDP4_CEP.ID_LIST) + LENGTH(VRID_UDP4_CEP.ID_LIST)$
-	$NL$
-	$FOREACH id UDP4_CEP.ID_LIST$
-		CRE_SEM(SEM_UDP_CEP_LOCK$+id$,{ TA_TPRI, 1, 1 });$NL$
-		CRE_DTQ(DTQ_UDP_RCVQ$+id$,{ TA_TFIFO, NUM_DTQ_UDP_RCVQ, NULL });$NL$
-		$NL$
-	$END$
-	$FOREACH id VRID_UDP4_CEP.ID_LIST$
-		CRE_SEM(SEM_UDP_CEP_LOCK$+id + LENGTH(UDP4_CEP.ID_LIST)$,{ TA_TPRI, 1, 1 });$NL$
-		CRE_DTQ(DTQ_UDP_RCVQ$+id + LENGTH(UDP4_CEP.ID_LIST)$,{ TA_TFIFO, NUM_DTQ_UDP_RCVQ, NULL });$NL$
-		$NL$
-	$END$
-$END$
-
-$	// UDP (IPv6) 通信端点
-$IF LENGTH(UDP6_CEP.ID_LIST) + LENGTH(VRID_UDP6_CEP.ID_LIST)$
-	$NL$
-	$FOREACH id UDP6_CEP.ID_LIST$
-		CRE_SEM(SEM_UDP_CEP_LOCK$+id$,{ TA_TPRI, 1, 1 });$NL$
-		CRE_DTQ(DTQ_UDP_RCVQ$+id$,{ TA_TFIFO, NUM_DTQ_UDP_RCVQ, NULL });$NL$
-		$NL$
-	$END$
-	$FOREACH id VRID_UDP6_CEP.ID_LIST$
-		CRE_SEM(SEM_UDP_CEP_LOCK$+id + LENGTH(UDP6_CEP.ID_LIST)$,{ TA_TPRI, 1, 1 });$NL$
-		CRE_DTQ(DTQ_UDP_RCVQ$+id + LENGTH(UDP6_CEP.ID_LIST)$,{ TA_TFIFO, NUM_DTQ_UDP_RCVQ, NULL });$NL$
-		$NL$
-	$END$
-$END$
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/tinet.trb
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/tinet.trb	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/tinet.trb	(revision 331)
@@ -47,39 +47,58 @@
 $tinetCfgH.add()
 
-$cfgData[:TCP_CRE_REP].each do |key, params|
-	$tinetCfgH.add("#define #{params[:tcp4_repid]}	#{params[:tcp4_repid].val}")
-end
+$tinetCfgH.add("#define TNUM_TCP6_REPID	#{$cfgData[:TCP6_CRE_REP].size + $cfgData[:VRID_TCP6_REP].size}")
+$tinetCfgH.add("#define TNUM_TCP4_REPID	#{$cfgData[:TCP_CRE_REP].size + $cfgData[:VRID_TCP_REP].size}")
+$tinetCfgH.add("#define TNUM_TCP_REPID	#{$cfgData[:TCP6_CRE_REP].size + $cfgData[:VRID_TCP6_REP].size + $cfgData[:TCP_CRE_REP].size + $cfgData[:VRID_TCP_REP].size}")
+$tinetCfgH.add()
+
+$tinetCfgH.add("#define TNUM_TCP6_CEPID	#{$cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}")
+$tinetCfgH.add("#define TNUM_TCP4_CEPID	#{$cfgData[:TCP_CRE_CEP].size + $cfgData[:VRID_TCP_CEP].size}")
+$tinetCfgH.add("#define TNUM_TCP_CEPID	#{$cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size + $cfgData[:TCP_CRE_CEP].size + $cfgData[:VRID_TCP_CEP].size}")
+$tinetCfgH.add()
+
+$tinetCfgH.add("#define TNUM_UDP6_CEPID	#{$cfgData[:UDP6_CRE_CEP].size + $cfgData[:VRID_UDP6_CEP].size}")
+$tinetCfgH.add("#define TNUM_UDP4_CEPID	#{$cfgData[:UDP_CRE_CEP].size + $cfgData[:VRID_UDP_CEP].size}")
+$tinetCfgH.add("#define TNUM_UDP_CEPID	#{$cfgData[:UDP6_CRE_CEP].size + $cfgData[:VRID_UDP6_CEP].size + $cfgData[:UDP_CRE_CEP].size + $cfgData[:VRID_UDP_CEP].size}")
+$tinetCfgH.add()
+
 $cfgData[:TCP6_CRE_REP].each do |key, params|
 	$tinetCfgH.add("#define #{params[:tcp6_repid]}	#{params[:tcp6_repid].val}")
 end
-$cfgData[:TCP_CRE_CEP].each do |key, params|
-	$tinetCfgH.add("#define #{params[:tcp4_cepid]}	#{params[:tcp4_cepid].val}")
-end
+$cfgData[:VRID_TCP6_REP].each do |key, params|
+	$tinetCfgH.add("#define #{params[:vrid_tcp6_repid]}	#{params[:vrid_tcp6_repid].val + $cfgData[:TCP6_CRE_REP].size}")
+end
+$cfgData[:TCP_CRE_REP].each do |key, params|
+	$tinetCfgH.add("#define #{params[:tcp4_repid]}	#{params[:tcp4_repid].val + $cfgData[:TCP6_CRE_REP].size + $cfgData[:VRID_TCP6_REP].size}")
+end
+$cfgData[:VRID_TCP_REP].each do |key, params|
+	$tinetCfgH.add("#define #{params[:vrid_tcp4_repid]}	#{params[:vrid_tcp4_repid].val + $cfgData[:TCP_CRE_REP].size + $cfgData[:TCP6_CRE_REP].size + $cfgData[:VRID_TCP6_REP].size}")
+end
+$tinetCfgH.add()
+
 $cfgData[:TCP6_CRE_CEP].each do |key, params|
 	$tinetCfgH.add("#define #{params[:tcp6_cepid]}	#{params[:tcp6_cepid].val}")
 end
-$cfgData[:UDP_CRE_CEP].each do |key, params|
-	$tinetCfgH.add("#define #{params[:udp4_cepid]}	#{params[:udp4_cepid].val}")
-end
+$cfgData[:VRID_TCP6_CEP].each do |key, params|
+	$tinetCfgH.add("#define #{params[:vrid_tcp6_cepid]}	#{params[:vrid_tcp6_cepid].val + $cfgData[:TCP6_CRE_CEP].size}")
+end
+$cfgData[:TCP_CRE_CEP].each do |key, params|
+	$tinetCfgH.add("#define #{params[:tcp4_cepid]}	#{params[:tcp4_cepid].val + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}")
+end
+$cfgData[:VRID_TCP_CEP].each do |key, params|
+	$tinetCfgH.add("#define #{params[:vrid_tcp4_cepid]}	#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}")
+end
+$tinetCfgH.add()
+
 $cfgData[:UDP6_CRE_CEP].each do |key, params|
 	$tinetCfgH.add("#define #{params[:udp6_cepid]}	#{params[:udp6_cepid].val}")
 end
-$cfgData[:VRID_TCP4_REP].each do |key, params|
-	$tinetCfgH.add("#define #{params[:vrid_tcp4_repid]}	#{params[:vrid_tcp4_repid].val + $cfgData[:TCP_CRE_REP].size}")
-end
-$cfgData[:VRID_TCP4_CEP].each do |key, params|
-	$tinetCfgH.add("#define #{params[:vrid_tcp4_cepid]}	#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size}")
-end
-$cfgData[:VRID_TCP6_REP].each do |key, params|
-	$tinetCfgH.add("#define #{params[:vrid_tcp6_repid]}	#{params[:vrid_tcp6_repid].val + $cfgData[:TCP6_CRE_REP].size}")
-end
-$cfgData[:VRID_TCP6_CEP].each do |key, params|
-	$tinetCfgH.add("#define #{params[:vrid_tcp6_cepid]}	#{params[:vrid_tcp6_cepid].val + $cfgData[:TCP6_CRE_CEP].size}")
-end
-$cfgData[:VRID_UDP4_CEP].each do |key, params|
-	$tinetCfgH.add("#define #{params[:vrid_udp4_cepid]}	#{params[:vrid_udp4_cepid].val + $cfgData[:UDP_CRE_CEP].size}")
-end
 $cfgData[:VRID_UDP6_CEP].each do |key, params|
 	$tinetCfgH.add("#define #{params[:vrid_udp6_cepid]}	#{params[:vrid_udp6_cepid].val + $cfgData[:UDP6_CRE_CEP].size}")
+end
+$cfgData[:UDP_CRE_CEP].each do |key, params|
+	$tinetCfgH.add("#define #{params[:udp4_cepid]}	#{params[:udp4_cepid].val + $cfgData[:UDP6_CRE_CEP].size + $cfgData[:VRID_UDP6_CEP].size}")
+end
+$cfgData[:VRID_UDP_CEP].each do |key, params|
+	$tinetCfgH.add("#define #{params[:vrid_udp4_cepid]}	#{params[:vrid_udp4_cepid].val + $cfgData[:UDP_CRE_CEP].size + $cfgData[:UDP6_CRE_CEP].size + $cfgData[:VRID_UDP6_CEP].size}")
 end
 $tinetCfgH.add()
@@ -110,9 +129,6 @@
 #include <netinet/in_itron.h>
 #include <netinet/ip.h>
-#include <netinet/ip6.h>
 #include <netinet/tcp.h>
-#include <netinet/tcp_timer.h>
 #include <netinet/tcp_var.h>
-#include <netinet/tcp_fsm.h>
 #include <netinet/udp_var.h>
 
@@ -130,12 +146,65 @@
 end
 
+$tinetCfgC.add()
+$tinetCfgC.add("const ID tmax_tcp_repid = (TMIN_TCP_REPID + TNUM_TCP6_REPID + TNUM_TCP4_REPID - 1);")
+
+$tinetCfgC.add()
+$tinetCfgC.add("#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)")
+$tinetCfgC.add("const ID tmax_tcp6_repid = (TMIN_TCP6_REPID + TNUM_TCP6_REPID - 1);")
+$tinetCfgC.add("const ID tmax_tcp4_repid = (TMIN_TCP4_REPID + TNUM_TCP4_REPID - 1);")
+$tinetCfgC.add("#endif")
+
+$tinetCfgC.add()
+$tinetCfgC.add("const ID tmax_tcp_cepid = (TMIN_TCP_CEPID + TNUM_TCP6_CEPID + TNUM_TCP4_CEPID - 1);")
+
+$tinetCfgC.add()
+$tinetCfgC.add("#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)")
+$tinetCfgC.add("const ID tmax_tcp6_cepid = (TMIN_TCP_CEPID + TNUM_TCP6_CEPID - 1);")
+$tinetCfgC.add("const ID tmax_tcp4_cepid = (TMIN_TCP_CEPID + TNUM_TCP4_CEPID - 1);")
+$tinetCfgC.add("#endif")
+
+$tinetCfgC.add()
+$tinetCfgC.add("const ID tmax_udp_cepid = (TMIN_UDP_CEPID + TNUM_UDP6_CEPID + TNUM_UDP4_CEPID - 1);")
+
+$tinetCfgC.add()
+$tinetCfgC.add("#if defined(SUPPORT_INET6) && defined(SUPPORT_INET4)")
+$tinetCfgC.add("const ID tmax_udp6_cepid = (TMIN_UDP6_CEPID + TNUM_UDP6_CEPID - 1);")
+$tinetCfgC.add("const ID tmax_udp4_cepid = (TMIN_UDP4_CEPID + TNUM_UDP4_CEPID - 1);")
+$tinetCfgC.add("#endif")
+
+#	// TCP (IPv6) 受付口
+$sem_tcp_rep_lock_id = 0
+if $cfgData[:TCP6_CRE_REP].size > 0 || $cfgData[:VRID_TCP6_REP].size > 0
+	$tinetCfgC.add()
+	$tinetCfgC.add("T_TCP6_REP tcp6_rep[TNUM_TCP6_REPID] = {")
+	$cfgData[:TCP6_CRE_REP].each do |key, params|
+		$tinetCfgC.add("\t{")
+			$tinetCfgC.add("\t\t#{params[:tcp6_repatr]},")
+			$tinetCfgC.add("\t\t{ #{params[:ipv6addr]}, #{params[:portno]} },")
+		$tinetCfgC.add("#if defined(TCP_CFG_EXTENTIONS)")
+			$tinetCfgC.add("\t\tTCP_REP_FLG_VALID,")
+			$tinetCfgC.add("\t\tSEM_TCP_REP_LOCK#{$sem_tcp_rep_lock_id},")
+		$tinetCfgC.add("#endif")
+			$tinetCfgC.add("\t\t},")
+		$sem_tcp_rep_lock_id = $sem_tcp_rep_lock_id + 1
+	end
+	$cfgData[:VRID_TCP6_REP].each do |key, params|
+		$tinetCfgC.add("\t{")
+			$tinetCfgC.add("\t\t0,")
+			$tinetCfgC.add("\t\t{ IPV6_ADDRANY, TCP_PORTANY },")
+	$tinetCfgC.add("#if defined(TCP_CFG_EXTENTIONS)")
+			$tinetCfgC.add("\t\tTCP_REP_FLG_DYNAMIC,")
+			$tinetCfgC.add("\t\tSEM_TCP_REP_LOCK#{$sem_tcp_rep_lock_id},")
+	$tinetCfgC.add("#endif")
+			$tinetCfgC.add("\t\t},")
+		$sem_tcp_rep_lock_id = $sem_tcp_rep_lock_id + 1
+	end
+	$tinetCfgC.add("\t};")
+end
+
 #	// TCP (IPv4) 受付口
-if $cfgData[:TCP_CRE_REP].size > 0 || $cfgData[:VRID_TCP4_REP].size > 0
+if $cfgData[:TCP_CRE_REP].size > 0 || $cfgData[:VRID_TCP_REP].size > 0
 	$tinetCfgC.add()
-	$tinetCfgC.add("#define TNUM_TCP_REPID	#{$cfgData[:TCP_CRE_REP].size + $cfgData[:VRID_TCP4_REP].size}")
-	$tinetCfgC.add()
-	$tinetCfgC.add("const ID tmax_tcp_repid = (TMIN_TCP_REPID + TNUM_TCP_REPID - 1);")
-	$tinetCfgC.add()
-	$tinetCfgC.add("T_TCP_REP tcp_rep[TNUM_TCP_REPID] = {")
+	$tinetCfgC.add("T_TCP4_REP tcp4_rep[TNUM_TCP4_REPID] = {")
 	$cfgData[:TCP_CRE_REP].each do |key, params|
 		$tinetCfgC.add("\t{")
@@ -144,9 +213,10 @@
 	$tinetCfgC.add("#if defined(TCP_CFG_EXTENTIONS)")
 			$tinetCfgC.add("\t\tTCP_REP_FLG_VALID,")
-			$tinetCfgC.add("\t\tSEM_TCP_REP_LOCK#{params[:tcp4_repid].val},")
+			$tinetCfgC.add("\t\tSEM_TCP_REP_LOCK#{$sem_tcp_rep_lock_id},")
 	$tinetCfgC.add("#endif")
 			$tinetCfgC.add("\t\t},")
-	end
-	$cfgData[:VRID_TCP4_REP].each do |key, params|
+		$sem_tcp_rep_lock_id = $sem_tcp_rep_lock_id + 1
+	end
+	$cfgData[:VRID_TCP_REP].each do |key, params|
 		$tinetCfgC.add("\t{")
 			$tinetCfgC.add("\t\t0,")
@@ -154,91 +224,16 @@
 	$tinetCfgC.add("#if defined(TCP_CFG_EXTENTIONS)")
 			$tinetCfgC.add("\t\tTCP_REP_FLG_DYNAMIC,")
-			$tinetCfgC.add("\t\tSEM_TCP_REP_LOCK#{params[:vrid_tcp4_repid].val + $cfgData[:TCP_CRE_REP].size},")
+			$tinetCfgC.add("\t\tSEM_TCP_REP_LOCK#{$sem_tcp_rep_lock_id},")
 	$tinetCfgC.add("#endif")
 			$tinetCfgC.add("\t\t},")
-	end
-		$tinetCfgC.add("\t};")
-end
-
-#	// TCP (IPv6) 受付口
-if $cfgData[:TCP6_CRE_REP].size > 0 || $cfgData[:VRID_TCP6_REP].size > 0
+		$sem_tcp_rep_lock_id = $sem_tcp_rep_lock_id + 1
+	end
+	$tinetCfgC.add("\t};")
+end
+
+#	// TCP 通信端点
+if $cfgData[:TCP6_CRE_CEP].size > 0 || $cfgData[:VRID_TCP6_CEP].size > 0 || $cfgData[:TCP_CRE_CEP].size > 0 || $cfgData[:VRID_TCP_CEP].size > 0
 	$tinetCfgC.add()
-	$tinetCfgC.add("#define TNUM_TCP_REPID	#{$cfgData[:TCP6_CRE_REP].size + $cfgData[:VRID_TCP6_REP].size}")
-	$tinetCfgC.add()
-	$tinetCfgC.add("const ID tmax_tcp_repid = (TMIN_TCP_REPID + TNUM_TCP_REPID - 1);")
-	$tinetCfgC.add()
-	$tinetCfgC.add("T_TCP6_REP tcp_rep[TNUM_TCP_REPID] = {")
-	$cfgData[:TCP6_CRE_REP].each do |key, params|
-		$tinetCfgC.add("\t{")
-			$tinetCfgC.add("\t\t#{params[:tcp6_repatr]},")
-			$tinetCfgC.add("\t\t{ #{params[:ipv6addr]}, #{params[:portno]} },")
-	$tinetCfgC.add("#if defined(TCP_CFG_EXTENTIONS)")
-			$tinetCfgC.add("\t\tTCP_REP_FLG_VALID,")
-			$tinetCfgC.add("\t\tSEM_TCP_REP_LOCK#{params[:tcp6_repid].val},")
-	$tinetCfgC.add("#endif")
-			$tinetCfgC.add("\t\t},")
-	end
-	$cfgData[:VRID_TCP6_REP].each do |key, params|
-		$tinetCfgC.add("\t{")
-			$tinetCfgC.add("\t\t0,")
-			$tinetCfgC.add("\t\t{ IPV6_ADDRANY, TCP_PORTANY },")
-	$tinetCfgC.add("#if defined(TCP_CFG_EXTENTIONS)")
-			$tinetCfgC.add("\t\tTCP_REP_FLG_DYNAMIC,")
-			$tinetCfgC.add("\t\tSEM_TCP_REP_LOCK#{params[:vrid_tcp6_repid].val + $cfgData[:TCP6_CRE_REP].size},")
-	$tinetCfgC.add("#endif")
-			$tinetCfgC.add("\t\t},")
-	end
-		$tinetCfgC.add("\t};")
-end
-
-#	// TCP (IPv4) 通信端点
-if $cfgData[:TCP_CRE_CEP].size > 0 || $cfgData[:VRID_TCP4_CEP].size > 0
-	$tinetCfgC.add()
-	$tinetCfgC.add("#define TNUM_TCP_CEPID	#{$cfgData[:TCP_CRE_CEP].size + $cfgData[:VRID_TCP4_CEP].size}")
-	$tinetCfgC.add()
-	$tinetCfgC.add("const ID tmax_tcp_cepid = (TMIN_TCP_CEPID + TNUM_TCP_CEPID - 1);")
-	$tinetCfgC.add()
-	$tinetCfgC.add("T_TCP_CEP tcp_cep[TNUM_TCP_CEPID] = {")
-	$cfgData[:TCP_CRE_CEP].each do |key, params|
-		$tinetCfgC.add("\t{")
-			$tinetCfgC.add("\t\t#{params[:tcp4_cepatr]},")
-			$tinetCfgC.add("\t\t(void*)#{params[:sbuf]},")
-			$tinetCfgC.add("\t\t#{params[:sbufsz]},")
-			$tinetCfgC.add("\t\t(void*)#{params[:rbuf]},")
-			$tinetCfgC.add("\t\t#{params[:rbufsz]},")
-			$tinetCfgC.add("\t\t(t_tcp_callback)(FP)#{params[:callback]},")
-			$tinetCfgC.add("\t\tTCP_CEP_FLG_VALID,")
-			$tinetCfgC.add("\t\tSEM_TCP_CEP_LOCK#{params[:tcp4_cepid].val},")
-			$tinetCfgC.add("\t\tFLG_TCP_CEP_EST#{params[:tcp4_cepid].val},")
-			$tinetCfgC.add("\t\tFLG_TCP_CEP_SND#{params[:tcp4_cepid].val},")
-			$tinetCfgC.add("\t\tFLG_TCP_CEP_RCV#{params[:tcp4_cepid].val},")
-			$tinetCfgC.add("\t\t},")
-	end
-	$cfgData[:VRID_TCP4_CEP].each do |key, params|
-		$tinetCfgC.add("\t{")
-			$tinetCfgC.add("\t\t0,")
-			$tinetCfgC.add("\t\t(void*)NULL,")
-			$tinetCfgC.add("\t\t0,")
-			$tinetCfgC.add("\t\t(void*)NULL,")
-			$tinetCfgC.add("\t\t0,")
-			$tinetCfgC.add("\t\t(t_tcp_callback)(FP)NULL,")
-			$tinetCfgC.add("\t\tTCP_CEP_FLG_DYNAMIC,")
-			$tinetCfgC.add("\t\tSEM_TCP_CEP_LOCK#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size},")
-			$tinetCfgC.add("\t\tFLG_TCP_CEP_EST#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size},")
-			$tinetCfgC.add("\t\tFLG_TCP_CEP_SND#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size},")
-			$tinetCfgC.add("\t\tFLG_TCP_CEP_RCV#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size},")
-			$tinetCfgC.add("\t\t},")
-	end
-		$tinetCfgC.add("\t};")
-end
-
-#	// TCP (IPv6) 通信端点
-if $cfgData[:TCP6_CRE_CEP].size > 0 || $cfgData[:VRID_TCP6_CEP].size > 0
-	$tinetCfgC.add()
-	$tinetCfgC.add("#define TNUM_TCP_CEPID	#{$cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}")
-	$tinetCfgC.add()
-	$tinetCfgC.add("const ID tmax_tcp_cepid = (TMIN_TCP_CEPID + TNUM_TCP_CEPID - 1);")
-	$tinetCfgC.add()
-	$tinetCfgC.add("T_TCP6_CEP tcp_cep[TNUM_TCP_CEPID] = {")
+	$tinetCfgC.add("T_TCP_CEP tcp_cep[TNUM_TCP6_CEPID + TNUM_TCP4_CEPID] = {")
 	$cfgData[:TCP6_CRE_CEP].each do |key, params|
 		$tinetCfgC.add("\t{")
@@ -271,15 +266,72 @@
 			$tinetCfgC.add("\t\t},")
 	end
+	$cfgData[:TCP_CRE_CEP].each do |key, params|
+		$tinetCfgC.add("\t{")
+			$tinetCfgC.add("\t\t#{params[:tcp4_cepatr]},")
+			$tinetCfgC.add("\t\t(void*)#{params[:sbuf]},")
+			$tinetCfgC.add("\t\t#{params[:sbufsz]},")
+			$tinetCfgC.add("\t\t(void*)#{params[:rbuf]},")
+			$tinetCfgC.add("\t\t#{params[:rbufsz]},")
+			$tinetCfgC.add("\t\t(t_tcp_callback)(FP)#{params[:callback]},")
+			$tinetCfgC.add("\t\tTCP_CEP_FLG_VALID|TCP_CEP_FLG_IPV4,")
+			$tinetCfgC.add("\t\tSEM_TCP_CEP_LOCK#{params[:tcp4_cepid].val + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size},")
+			$tinetCfgC.add("\t\tFLG_TCP_CEP_EST#{params[:tcp4_cepid].val + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size},")
+			$tinetCfgC.add("\t\tFLG_TCP_CEP_SND#{params[:tcp4_cepid].val + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size},")
+			$tinetCfgC.add("\t\tFLG_TCP_CEP_RCV#{params[:tcp4_cepid].val + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size},")
+			$tinetCfgC.add("\t\t},")
+	end
+	$cfgData[:VRID_TCP_CEP].each do |key, params|
+		$tinetCfgC.add("\t{")
+			$tinetCfgC.add("\t\t0,")
+			$tinetCfgC.add("\t\t(void*)NULL,")
+			$tinetCfgC.add("\t\t0,")
+			$tinetCfgC.add("\t\t(void*)NULL,")
+			$tinetCfgC.add("\t\t0,")
+			$tinetCfgC.add("\t\t(t_tcp_callback)(FP)NULL,")
+			$tinetCfgC.add("\t\tTCP_CEP_FLG_DYNAMIC|TCP_CEP_FLG_IPV4,")
+			$tinetCfgC.add("\t\tSEM_TCP_CEP_LOCK#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size},")
+			$tinetCfgC.add("\t\tFLG_TCP_CEP_EST#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size},")
+			$tinetCfgC.add("\t\tFLG_TCP_CEP_SND#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size},")
+			$tinetCfgC.add("\t\tFLG_TCP_CEP_RCV#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size},")
+			$tinetCfgC.add("\t\t},")
+	end
 		$tinetCfgC.add("\t};")
 end
 
+#	// UDP (IPv6) 通信端点
+if $cfgData[:UDP6_CRE_CEP].size > 0 || $cfgData[:VRID_UDP6_CEP].size > 0
+	$tinetCfgC.add()
+	$tinetCfgC.add("T_UDP6_CEP udp6_cep[TNUM_UDP6_CEPID] = {")
+	$cfgData[:UDP6_CRE_CEP].each do |key, params|
+		$tinetCfgC.add("\t{")
+			$tinetCfgC.add("\t\t#{params[:udp6_cepatr]},")
+			$tinetCfgC.add("\t\t{ #{params[:ipv6addr]}, #{params[:portno]} },")
+			$tinetCfgC.add("\t\t(t_udp_callback)(FP)#{params[:callback]},")
+			$tinetCfgC.add("\t\tUDP_CEP_FLG_VALID,")
+			$tinetCfgC.add("\t\tSEM_UDP6_CEP_LOCK#{params[:udp6_cepid].val},")
+			$tinetCfgC.add("\t\tTA_NULL,")
+			$tinetCfgC.add("\t\tTA_NULL,")
+			$tinetCfgC.add("\t\tDTQ_UDP6_RCVQ#{params[:udp6_cepid].val},")
+			$tinetCfgC.add("\t\t},")
+	end
+	$cfgData[:VRID_UDP6_CEP].each do |key, params|
+		$tinetCfgC.add("\t{")
+			$tinetCfgC.add("\t\t0,")
+			$tinetCfgC.add("\t\t{ IPV6_ADDRANY, UDP_PORTANY },")
+			$tinetCfgC.add("\t\t(t_udp_callback)(FP)NULL,")
+			$tinetCfgC.add("\t\tUDP_CEP_FLG_DYNAMIC,")
+			$tinetCfgC.add("\t\tSEM_UDP6_CEP_LOCK#{params[:vrid_udp6_cepid].val + $cfgData[:UDP6_CRE_CEP].size},")
+			$tinetCfgC.add("\t\tTA_NULL,")
+			$tinetCfgC.add("\t\tTA_NULL,")
+			$tinetCfgC.add("\t\tDTQ_UDP6_RCVQ#{params[:vrid_udp6_cepid].val + $cfgData[:UDP6_CRE_CEP].size},")
+			$tinetCfgC.add("\t\t},")
+	end
+		$tinetCfgC.add("\t};")
+end
+
 #	// UDP (IPv4) 通信端点
-if $cfgData[:UDP_CRE_CEP].size > 0 || $cfgData[:VRID_UDP4_CEP].size > 0
+if $cfgData[:UDP_CRE_CEP].size > 0 || $cfgData[:VRID_UDP_CEP].size > 0
 	$tinetCfgC.add()
-	$tinetCfgC.add("#define TNUM_UDP_CEPID	#{$cfgData[:UDP_CRE_CEP].size + $cfgData[:VRID_UDP4_CEP].size}")
-	$tinetCfgC.add()
-	$tinetCfgC.add("const ID tmax_udp_cepid = (TMIN_UDP_CEPID + TNUM_UDP_CEPID - 1);")
-	$tinetCfgC.add()
-	$tinetCfgC.add("T_UDP_CEP udp_cep[TNUM_UDP_CEPID] = {")
+	$tinetCfgC.add("T_UDP4_CEP udp4_cep[TNUM_UDP4_CEPID] = {")
 	$cfgData[:UDP_CRE_CEP].each do |key, params|
 		$tinetCfgC.add("\t{")
@@ -288,11 +340,11 @@
 			$tinetCfgC.add("\t\t(t_udp_callback)(FP)#{params[:callback]},")
 			$tinetCfgC.add("\t\tUDP_CEP_FLG_VALID,")
-			$tinetCfgC.add("\t\tSEM_UDP_CEP_LOCK#{params[:udp4_cepid].val},")
-			$tinetCfgC.add("\t\tTA_NULL,")
-			$tinetCfgC.add("\t\tTA_NULL,")
-			$tinetCfgC.add("\t\tDTQ_UDP_RCVQ#{params[:udp4_cepid].val},")
-			$tinetCfgC.add("\t\t},")
-	end
-	$cfgData[:VRID_UDP4_CEP].each do |key, params|
+			$tinetCfgC.add("\t\tSEM_UDP4_CEP_LOCK#{params[:udp4_cepid].val},")
+			$tinetCfgC.add("\t\tTA_NULL,")
+			$tinetCfgC.add("\t\tTA_NULL,")
+			$tinetCfgC.add("\t\tDTQ_UDP4_RCVQ#{params[:udp4_cepid].val},")
+			$tinetCfgC.add("\t\t},")
+	end
+	$cfgData[:VRID_UDP_CEP].each do |key, params|
 		$tinetCfgC.add("\t{")
 			$tinetCfgC.add("\t\t0,")
@@ -300,8 +352,8 @@
 			$tinetCfgC.add("\t\t(t_udp_callback)(FP)NULL,")
 			$tinetCfgC.add("\t\tUDP_CEP_FLG_DYNAMIC,")
-			$tinetCfgC.add("\t\tSEM_UDP_CEP_LOCK#{params[:vrid_udp4_cepid].val + $cfgData[:UDP_CRE_CEP].size},")
-			$tinetCfgC.add("\t\tTA_NULL,")
-			$tinetCfgC.add("\t\tTA_NULL,")
-			$tinetCfgC.add("\t\tDTQ_UDP_RCVQ#{params[:vrid_udp4_cepid].val + $cfgData[:UDP_CRE_CEP].size},")
+			$tinetCfgC.add("\t\tSEM_UDP4_CEP_LOCK#{params[:vrid_udp4_cepid].val + $cfgData[:UDP_CRE_CEP].size},")
+			$tinetCfgC.add("\t\tTA_NULL,")
+			$tinetCfgC.add("\t\tTA_NULL,")
+			$tinetCfgC.add("\t\tDTQ_UDP4_RCVQ#{params[:vrid_udp4_cepid].val + $cfgData[:UDP_CRE_CEP].size},")
 			$tinetCfgC.add("\t\t},")
 	end
@@ -309,136 +361,54 @@
 end
 
-#	// UDP (IPv6) 通信端点
-if $cfgData[:UDP6_CRE_CEP].size > 0 || $cfgData[:VRID_UDP6_CEP].size > 0
-	$tinetCfgC.add()
-	$tinetCfgC.add("#define TNUM_UDP_CEPID	#{cfgData[:UDP6_CRE_CEP].size + $cfgData[:VRID_UDP6_CEP].size}")
-	$tinetCfgC.add()
-	$tinetCfgC.add("const ID tmax_udp_cepid = (TMIN_UDP_CEPID + TNUM_UDP_CEPID - 1);")
-	$tinetCfgC.add()
-	$tinetCfgC.add("T_UDP6_CEP udp_cep[TNUM_UDP_CEPID] = {")
-	$cfgData[:UDP6_CRE_CEP].each do |key, params|
-		$tinetCfgC.add("\t{")
-			$tinetCfgC.add("\t\t#{params[:udp6_cepatr]},")
-			$tinetCfgC.add("\t\t{ #{params[:ipv6addr]}, #{params[:portno]} },")
-			$tinetCfgC.add("\t\t(t_udp_callback)(FP)#{params[:callback]},")
-			$tinetCfgC.add("\t\tUDP_CEP_FLG_VALID,")
-			$tinetCfgC.add("\t\tSEM_UDP_CEP_LOCK#{params[:udp6_cepid].val},")
-			$tinetCfgC.add("\t\tTA_NULL,")
-			$tinetCfgC.add("\t\tTA_NULL,")
-			$tinetCfgC.add("\t\tDTQ_UDP_RCVQ#{params[:udp6_cepid].val},")
-			$tinetCfgC.add("\t\t},")
-	end
-	$cfgData[:VRID_UDP6_CEP].each do |key, params|
-		$tinetCfgC.add("\t{")
-			$tinetCfgC.add("\t\t0,")
-			$tinetCfgC.add("\t\t{ IPV6_ADDRANY, UDP_PORTANY },")
-			$tinetCfgC.add("\t\t(t_udp_callback)(FP)NULL,")
-			$tinetCfgC.add("\t\tUDP_CEP_FLG_DYNAMIC,")
-			$tinetCfgC.add("\t\tSEM_UDP_CEP_LOCK#{params[:vrid_udp6_cepid].val + $cfgData[:UDP6_CRE_CEP].size},")
-			$tinetCfgC.add("\t\tTA_NULL,")
-			$tinetCfgC.add("\t\tTA_NULL,")
-			$tinetCfgC.add("\t\tDTQ_UDP_RCVQ#{params[:vrid_udp6_cepid].val + $cfgData[:UDP6_CRE_CEP].size},")
-			$tinetCfgC.add("\t\t},")
-	end
-		$tinetCfgC.add("\t};")
-end
-
 # =====================================================================
 # tinet_kern.cfg の生成
 # =====================================================================
 
-#	// TCP (IPv4) 受付口
-if $cfgData[:TCP_CRE_REP].size > 0 || $cfgData[:VRID_TCP4_REP].size > 0
-	$cfgData[:TCP_CRE_REP].each do |key, params|
-		cfgInfo = { APINAME: "CRE_SEM" }
-		cfgInfo["semid"] = "SEM_TCP_REP_LOCK#{params[:tcp4_repid].val}"
-		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
-		cfgInfo["isemcnt"] = 1
-		cfgInfo["maxsem"] = 1
-		$cfgFileInfo.push(cfgInfo)
-	end
-	$cfgData[:VRID_TCP4_REP].each do |key, params|
-		cfgInfo = { APINAME: "CRE_SEM" }
-		cfgInfo["semid"] = "SEM_TCP_REP_LOCK#{params[:vrid_tcp4_repid].val + $cfgData[:TCP_CRE_REP].size}"
-		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
-		cfgInfo["isemcnt"] = 1
-		cfgInfo["maxsem"] = 1
-		$cfgFileInfo.push(cfgInfo)
-	end
-end
-
 #	// TCP (IPv6) 受付口
+$sem_tcp_rep_lock_id = 0
 if $cfgData[:TCP6_CRE_REP].size > 0 || $cfgData[:VRID_TCP6_REP].size > 0
 	$cfgData[:TCP6_CRE_REP].each do |key, params|
 		cfgInfo = { APINAME: "CRE_SEM" }
-		cfgInfo["semid"] = "SEM_TCP_REP_LOCK#{params[:tcp6_repid].val}"
-		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
-		cfgInfo["isemcnt"] = 1
-		cfgInfo["maxsem"] = 1
-		$cfgFileInfo.push(cfgInfo)
+		cfgInfo["semid"] = "SEM_TCP_REP_LOCK#{$sem_tcp_rep_lock_id}"
+		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
+		cfgInfo["isemcnt"] = 1
+		cfgInfo["maxsem"] = 1
+		$cfgFileInfo.push(cfgInfo)
+
+		$sem_tcp_rep_lock_id = $sem_tcp_rep_lock_id + 1
 	end
 	$cfgData[:VRID_TCP6_REP].each do |key, params|
 		cfgInfo = { APINAME: "CRE_SEM" }
-		cfgInfo["semid"] = "SEM_TCP_REP_LOCK#{params[:vrid_tcp6_repid].val + $cfgData[:TCP6_CRE_REP].size}"
-		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
-		cfgInfo["isemcnt"] = 1
-		cfgInfo["maxsem"] = 1
-		$cfgFileInfo.push(cfgInfo)
-	end
-end
-
-#	// TCP (IPv4) 通信端点
-if $cfgData[:TCP_CRE_CEP].size > 0 || $cfgData[:VRID_TCP4_CEP].size > 0
-	$cfgData[:TCP_CRE_CEP].each do |key, params|
-		cfgInfo = { APINAME: "CRE_SEM" }
-		cfgInfo["semid"] = "SEM_TCP_CEP_LOCK#{params[:tcp4_cepid].val}"
-		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
-		cfgInfo["isemcnt"] = 1
-		cfgInfo["maxsem"] = 1
-		$cfgFileInfo.push(cfgInfo)
-
-		cfgInfo = { APINAME: "CRE_FLG" }
-		cfgInfo["flgid"] = "FLG_TCP_CEP_EST#{params[:tcp4_cepid].val}"
-		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
-		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_CLOSED, "TCP_CEP_EVT_CLOSED")
-		$cfgFileInfo.push(cfgInfo)
-
-		cfgInfo = { APINAME: "CRE_FLG" }
-		cfgInfo["flgid"] = "FLG_TCP_CEP_SND#{params[:tcp4_cepid].val}"
-		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
-		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_CLOSED, "TCP_CEP_EVT_CLOSED")
-		$cfgFileInfo.push(cfgInfo)
-
-		cfgInfo = { APINAME: "CRE_FLG" }
-		cfgInfo["flgid"] = "FLG_TCP_CEP_RCV#{params[:tcp4_cepid].val}"
-		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
-		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_CLOSED, "TCP_CEP_EVT_CLOSED")
-		$cfgFileInfo.push(cfgInfo)
-	end
-	$cfgData[:VRID_TCP4_CEP].each do |key, params|
-		cfgInfo = { APINAME: "CRE_SEM" }
-		cfgInfo["semid"] = "SEM_TCP_CEP_LOCK#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size}"
-		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
-		cfgInfo["isemcnt"] = 1
-		cfgInfo["maxsem"] = 1
-		$cfgFileInfo.push(cfgInfo)
-
-		cfgInfo = { APINAME: "CRE_FLG" }
-		cfgInfo["flgid"] = "FLG_TCP_CEP_EST#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size}"
-		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
-		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_CLOSED, "TCP_CEP_EVT_CLOSED")
-		$cfgFileInfo.push(cfgInfo)
-
-		cfgInfo = { APINAME: "CRE_FLG" }
-		cfgInfo["flgid"] = "FLG_TCP_CEP_SND#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size}"
-		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
-		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_CLOSED, "TCP_CEP_EVT_CLOSED")
-		$cfgFileInfo.push(cfgInfo)
-
-		cfgInfo = { APINAME: "CRE_FLG" }
-		cfgInfo["flgid"] = "FLG_TCP_CEP_RCV#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size}"
-		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
-		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_CLOSED, "TCP_CEP_EVT_CLOSED")
-		$cfgFileInfo.push(cfgInfo)
+		cfgInfo["semid"] = "SEM_TCP_REP_LOCK#{$sem_tcp_rep_lock_id}"
+		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
+		cfgInfo["isemcnt"] = 1
+		cfgInfo["maxsem"] = 1
+		$cfgFileInfo.push(cfgInfo)
+
+		$sem_tcp_rep_lock_id = $sem_tcp_rep_lock_id + 1
+	end
+end
+
+#	// TCP (IPv4) 受付口
+if $cfgData[:TCP_CRE_REP].size > 0 || $cfgData[:VRID_TCP_REP].size > 0
+	$cfgData[:TCP_CRE_REP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_TCP_REP_LOCK#{$sem_tcp_rep_lock_id}"
+		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
+		cfgInfo["isemcnt"] = 1
+		cfgInfo["maxsem"] = 1
+		$cfgFileInfo.push(cfgInfo)
+
+		$sem_tcp_rep_lock_id = $sem_tcp_rep_lock_id + 1
+	end
+	$cfgData[:VRID_TCP_REP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_TCP_REP_LOCK#{$sem_tcp_rep_lock_id}"
+		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
+		cfgInfo["isemcnt"] = 1
+		cfgInfo["maxsem"] = 1
+		$cfgFileInfo.push(cfgInfo)
+
+		$sem_tcp_rep_lock_id = $sem_tcp_rep_lock_id + 1
 	end
 end
@@ -463,23 +433,79 @@
 		cfgInfo["flgid"] = "FLG_TCP_CEP_SND#{params[:tcp6_cepid].val}"
 		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
+		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_SWBUF_READY, "TCP_CEP_EVT_SWBUF_READY")
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_FLG" }
+		cfgInfo["flgid"] = "FLG_TCP_CEP_RCV#{params[:tcp6_cepid].val}"
+		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
+		cfgInfo["iflgptn"] = 0
+		$cfgFileInfo.push(cfgInfo)
+	end
+	$cfgData[:VRID_TCP6_CEP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_TCP_CEP_LOCK#{params[:vrid_tcp6_cepid].val + $cfgData[:TCP6_CRE_CEP].size}"
+		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
+		cfgInfo["isemcnt"] = 1
+		cfgInfo["maxsem"] = 1
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_FLG" }
+		cfgInfo["flgid"] = "FLG_TCP_CEP_EST#{params[:vrid_tcp6_cepid].val + $cfgData[:TCP6_CRE_CEP].size}"
+		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
 		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_CLOSED, "TCP_CEP_EVT_CLOSED")
 		$cfgFileInfo.push(cfgInfo)
 
 		cfgInfo = { APINAME: "CRE_FLG" }
-		cfgInfo["flgid"] = "FLG_TCP_CEP_RCV#{params[:tcp6_cepid].val}"
+		cfgInfo["flgid"] = "FLG_TCP_CEP_SND#{params[:vrid_tcp6_cepid].val + $cfgData[:TCP6_CRE_CEP].size}"
+		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
+		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_SWBUF_READY, "TCP_CEP_EVT_SWBUF_READY")
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_FLG" }
+		cfgInfo["flgid"] = "FLG_TCP_CEP_RCV#{params[:vrid_tcp6_cepid].val + $cfgData[:TCP6_CRE_CEP].size}"
+		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
+		cfgInfo["iflgptn"] = 0
+		$cfgFileInfo.push(cfgInfo)
+	end
+end
+
+#	// TCP (IPv4) 通信端点
+if $cfgData[:TCP_CRE_CEP].size > 0 || $cfgData[:VRID_TCP_CEP].size > 0
+	$cfgData[:TCP_CRE_CEP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_TCP_CEP_LOCK#{params[:tcp4_cepid].val + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}"
+		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
+		cfgInfo["isemcnt"] = 1
+		cfgInfo["maxsem"] = 1
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_FLG" }
+		cfgInfo["flgid"] = "FLG_TCP_CEP_EST#{params[:tcp4_cepid].val + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}"
 		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
 		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_CLOSED, "TCP_CEP_EVT_CLOSED")
 		$cfgFileInfo.push(cfgInfo)
-	end
-	$cfgData[:VRID_TCP6_CEP].each do |key, params|
-		cfgInfo = { APINAME: "CRE_SEM" }
-		cfgInfo["semid"] = "SEM_TCP_CEP_LOCK#{params[:vrid_tcp6_cepid].val + $cfgData[:TCP6_CRE_CEP].size}"
-		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
-		cfgInfo["isemcnt"] = 1
-		cfgInfo["maxsem"] = 1
-		$cfgFileInfo.push(cfgInfo)
-
-		cfgInfo = { APINAME: "CRE_FLG" }
-		cfgInfo["flgid"] = "FLG_TCP_CEP_EST#{params[:vrid_tcp6_cepid].val + $cfgData[:TCP6_CRE_CEP].size}"
+
+		cfgInfo = { APINAME: "CRE_FLG" }
+		cfgInfo["flgid"] = "FLG_TCP_CEP_SND#{params[:tcp4_cepid].val + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}"
+		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
+		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_SWBUF_READY, "TCP_CEP_EVT_SWBUF_READY")
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_FLG" }
+		cfgInfo["flgid"] = "FLG_TCP_CEP_RCV#{params[:tcp4_cepid].val + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}"
+		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
+		cfgInfo["iflgptn"] = 0
+		$cfgFileInfo.push(cfgInfo)
+	end
+	$cfgData[:VRID_TCP_CEP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_TCP_CEP_LOCK#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}"
+		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
+		cfgInfo["isemcnt"] = 1
+		cfgInfo["maxsem"] = 1
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_FLG" }
+		cfgInfo["flgid"] = "FLG_TCP_CEP_EST#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}"
 		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
 		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_CLOSED, "TCP_CEP_EVT_CLOSED")
@@ -487,22 +513,22 @@
 
 		cfgInfo = { APINAME: "CRE_FLG" }
-		cfgInfo["flgid"] = "FLG_TCP_CEP_SND#{params[:vrid_tcp6_cepid].val + $cfgData[:TCP6_CRE_CEP].size}"
-		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
-		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_CLOSED, "TCP_CEP_EVT_CLOSED")
-		$cfgFileInfo.push(cfgInfo)
-
-		cfgInfo = { APINAME: "CRE_FLG" }
-		cfgInfo["flgid"] = "FLG_TCP_CEP_RCV#{params[:vrid_tcp6_cepid].val + $cfgData[:TCP6_CRE_CEP].size}"
-		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
-		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_CLOSED, "TCP_CEP_EVT_CLOSED")
-		$cfgFileInfo.push(cfgInfo)
-	end
-end
-
-#	// UDP (IPv4) 通信端点
-if $cfgData[:UDP_CRE_CEP].size > 0 || $cfgData[:VRID_UDP4_CEP].size > 0
-	$cfgData[:UDP_CRE_CEP].each do |key, params|
-		cfgInfo = { APINAME: "CRE_SEM" }
-		cfgInfo["semid"] = "SEM_UDP_CEP_LOCK#{params[:udp4_cepid].val}"
+		cfgInfo["flgid"] = "FLG_TCP_CEP_SND#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}"
+		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
+		cfgInfo["iflgptn"] = NumStr.new($TCP_CEP_EVT_SWBUF_READY, "TCP_CEP_EVT_SWBUF_READY")
+		$cfgFileInfo.push(cfgInfo)
+
+		cfgInfo = { APINAME: "CRE_FLG" }
+		cfgInfo["flgid"] = "FLG_TCP_CEP_RCV#{params[:vrid_tcp4_cepid].val + $cfgData[:TCP_CRE_CEP].size + $cfgData[:TCP6_CRE_CEP].size + $cfgData[:VRID_TCP6_CEP].size}"
+		cfgInfo["flgatr"] = NumStr.new($TA_TFIFO | $TA_WSGL, "TA_TFIFO|TA_WSGL")
+		cfgInfo["iflgptn"] = 0
+		$cfgFileInfo.push(cfgInfo)
+	end
+end
+
+#	// UDP (IPv6) 通信端点
+if $cfgData[:UDP6_CRE_CEP].size > 0 || $cfgData[:VRID_UDP6_CEP].size > 0
+	$cfgData[:UDP6_CRE_CEP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_UDP6_CEP_LOCK#{params[:udp6_cepid].val}"
 		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
 		cfgInfo["isemcnt"] = 1
@@ -511,5 +537,5 @@
 
 		cfgInfo = { APINAME: "CRE_DTQ" }
-		cfgInfo["dtqid"] = "DTQ_UDP_RCVQ#{params[:udp4_cepid].val}"
+		cfgInfo["dtqid"] = "DTQ_UDP6_RCVQ#{params[:udp6_cepid].val}"
 		cfgInfo["dtqatr"] = NumStr.new($TA_TFIFO, "TA_TFIFO")
 		cfgInfo["dtqcnt"] = NumStr.new($NUM_DTQ_UDP_RCVQ, "NUM_DTQ_UDP_RCVQ")
@@ -517,7 +543,7 @@
 		$cfgFileInfo.push(cfgInfo)
 	end
-	$cfgData[:VRID_UDP4_CEP].each do |key, params|
-		cfgInfo = { APINAME: "CRE_SEM" }
-		cfgInfo["semid"] = "SEM_UDP_CEP_LOCK#{params[:vrid_udp4_cepid].val + $cfgData[:UDP_CRE_CEP].size}"
+	$cfgData[:VRID_UDP6_CEP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_UDP6_CEP_LOCK#{params[:vrid_udp6_cepid].val + $cfgData[:UDP6_CRE_CEP].size}"
 		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
 		cfgInfo["isemcnt"] = 1
@@ -526,5 +552,5 @@
 
 		cfgInfo = { APINAME: "CRE_DTQ" }
-		cfgInfo["dtqid"] = "DTQ_UDP_RCVQ#{params[:vrid_udp4_cepid].val + $cfgData[:UDP_CRE_CEP].size}"
+		cfgInfo["dtqid"] = "DTQ_UDP6_RCVQ#{params[:vrid_udp6_cepid].val + $cfgData[:UDP6_CRE_CEP].size}"
 		cfgInfo["dtqatr"] = NumStr.new($TA_TFIFO, "TA_TFIFO")
 		cfgInfo["dtqcnt"] = NumStr.new($NUM_DTQ_UDP_RCVQ, "NUM_DTQ_UDP_RCVQ")
@@ -534,9 +560,9 @@
 end
 
-#	// UDP (IPv6) 通信端点
-if $cfgData[:UDP6_CRE_CEP].size > 0 || $cfgData[:VRID_UDP6_CEP].size > 0
-	$cfgData[:UDP6_CRE_CEP].each do |key, params|
-		cfgInfo = { APINAME: "CRE_SEM" }
-		cfgInfo["semid"] = "SEM_UDP_CEP_LOCK#{params[:udp6_cepid].val}"
+#	// UDP (IPv4) 通信端点
+if $cfgData[:UDP_CRE_CEP].size > 0 || $cfgData[:VRID_UDP_CEP].size > 0
+	$cfgData[:UDP_CRE_CEP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_UDP4_CEP_LOCK#{params[:udp4_cepid].val}"
 		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
 		cfgInfo["isemcnt"] = 1
@@ -545,5 +571,5 @@
 
 		cfgInfo = { APINAME: "CRE_DTQ" }
-		cfgInfo["dtqid"] = "DTQ_UDP_RCVQ#{params[:udp6_cepid].val}"
+		cfgInfo["dtqid"] = "DTQ_UDP4_RCVQ#{params[:udp4_cepid].val}"
 		cfgInfo["dtqatr"] = NumStr.new($TA_TFIFO, "TA_TFIFO")
 		cfgInfo["dtqcnt"] = NumStr.new($NUM_DTQ_UDP_RCVQ, "NUM_DTQ_UDP_RCVQ")
@@ -551,7 +577,7 @@
 		$cfgFileInfo.push(cfgInfo)
 	end
-	$cfgData[:VRID_UDP6_CEP].each do |key, params|
-		cfgInfo = { APINAME: "CRE_SEM" }
-		cfgInfo["semid"] = "SEM_UDP_CEP_LOCK#{params[:vrid_udp6_cepid].val + $cfgData[:UDP6_CRE_CEP].size}"
+	$cfgData[:VRID_UDP_CEP].each do |key, params|
+		cfgInfo = { APINAME: "CRE_SEM" }
+		cfgInfo["semid"] = "SEM_UDP4_CEP_LOCK#{params[:vrid_udp4_cepid].val + $cfgData[:UDP_CRE_CEP].size}"
 		cfgInfo["sematr"] = NumStr.new($TA_TPRI, "TA_TPRI")
 		cfgInfo["isemcnt"] = 1
@@ -560,5 +586,5 @@
 
 		cfgInfo = { APINAME: "CRE_DTQ" }
-		cfgInfo["dtqid"] = "DTQ_UDP_RCVQ#{params[:vrid_udp6_cepid].val + $cfgData[:UDP6_CRE_CEP].size}"
+		cfgInfo["dtqid"] = "DTQ_UDP4_RCVQ#{params[:vrid_udp4_cepid].val + $cfgData[:UDP_CRE_CEP].size}"
 		cfgInfo["dtqatr"] = NumStr.new($TA_TFIFO, "TA_TFIFO")
 		cfgInfo["dtqcnt"] = NumStr.new($NUM_DTQ_UDP_RCVQ, "NUM_DTQ_UDP_RCVQ")
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/tinet_asp.cfg
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/tinet_asp.cfg	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/tinet_asp.cfg	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2007 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -36,4 +36,6 @@
  */
 
+#include "target_sil.h"
+
 #include <itron.h>
 
@@ -47,4 +49,5 @@
 #include <net/if_arp.h>
 #include <net/net.h>
+#include <net/net_endian.h>
 #include <net/net_buf.h>
 #include <net/net_timer.h>
@@ -52,13 +55,10 @@
 #include <net/ether_var.h>
 #include <netinet/in.h>
+#include <netinet/in_var.h>
 #include <netinet/ip.h>
-#include <netinet/ip6.h>
 #include <netinet/ip_var.h>
 #include <netinet/tcp.h>
-#include <netinet/tcp_timer.h>
 #include <netinet/tcp_var.h>
 #include <netinet/udp_var.h>
-#include <netinet6/in6.h>
-#include <netinet6/ip6_var.h>
 
 /*
@@ -69,6 +69,6 @@
 
 INCLUDE("net/net_asp.cfg");
+INCLUDE("net/ethernet.cfg");
 
-INCLUDE("net/ethernet.cfg");
 INCLUDE("netinet/if_ether.cfg");
 INCLUDE("netinet/ip.cfg");
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/tinet_asp_configure
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/tinet_asp_configure	(revision 321)
+++ 	(revision )
@@ -1,488 +1,0 @@
-#! /usr/bin/perl
-#
-#   TINET (TCP/IP Protocol Stack)
-#  
-#  Copyright (C) 2001-2003 by Embedded and Real-Time Systems Laboratory
-#                              Toyohashi Univ. of Technology, JAPAN
-#  Copyright (C) 2006-2008 by Embedded and Real-Time Systems Laboratory
-#              Graduate School of Information Science, Nagoya Univ., JAPAN
-#  Copyright (C) 2001-2007 by Dep. of Computer Science and Engineering
-#                   Tomakomai National College of Technology, JAPAN
-# 
-#  上記著作権者は，以下の(1)〜(4)の条件を満たす場合に限り，本ソフトウェ
-#  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
-#  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
-#  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
-#      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
-#      スコード中に含まれていること．
-#  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
-#      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
-#      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
-#      の無保証規定を掲載すること．
-#  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
-#      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
-#      と．
-#    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
-#        作権表示，この利用条件および下記の無保証規定を掲載すること．
-#  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
-#      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
-#      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
-#      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
-#      免責すること．
-# 
-#  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
-#  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
-#  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
-#  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
-#  の責任を負わない．
-# 
-#  @(#) $Id: tinet_asp_configure,v 1.5 2009/12/24 06:42:46 abe Exp abe $
-# 
-
-require "getopt.pl";
-
-#  オプションの定義
-#
-#  -T <target>		ターゲット名（必須）
-#  -A <applname>	アプリケーションプログラム名
-#  -a <appldir>		アプリケーションのディレクトリ名
-#  -U <applobjs>	他のアプリケーションプログラムファイル
-#			（.oファイル名で指定．複数指定可）
-#  -L <kernel_lib>	カーネルライブラリ（libkernel.a）のディレクトリ名
-#			（省略した場合，カーネルライブラリもmakeする）
-#  -f			カーネルを関数単位でコンパイルするかどうかの指定
-#  -D <srcdir>		カーネル等のソースの置かれているディレクトリ
-#  -l <srclang>		プログラミング言語（現時点ではcとc++のみサポート）
-#  -t <templatedir>	テンプレートディレクトリを指定（デフォルトはtinet/asp_sample）
-#  -d <dbgenv>		実行環境の名称
-#  -r			トレースログ記録のサンプルコードを使用するかどうかの指定
-#  -p <perl>		perlのパス名（明示的に指定する場合）
-#  -g <cfg>		コンフィギュレータ（cfg）のパス名
-#  -e <tinetdir>	TINET のソースの置かれているディレクトリ
-#  -i <net_if>		ネットワークインタフェース（必須）
-#			ether、ppp、loop の何れかを指定する。
-#  -v <net_dev>		イーサネット・ディバイスドライバ
-#  			（ネットワークインタフェースに ether を指定した場合は必須）
-#  -n <net_proto>	ネットワーク層プロトコル（必須）
-#			inet4、inet6 の何れかを指定する。
-#  -s <trans_proto>	トランスポート層プロトコル（必須）
-#			tcp、udp、tcp/udp の何れかを指定する。
-
-#  使用例(1)
-#
-#  % ../tinet/tinet_asp_configure -T akih8_3069f_gcc -A echos4 -i ether -v if_ed -n inet4 -s tcp
-
-#
-#  オプションの処理
-#
-do Getopt("TAaULDltdpgiensv");
-
-#
-#  変数の初期化
-#
-
-$target = $opt_T;
-$applname = $opt_A ? $opt_A : "";
-$appldir = $opt_a ? $opt_a : "";
-$applobjs = $opt_U ? $opt_U : "";
-$kernel_lib = $opt_L ? $opt_L : "";
-$kernel_funcobjs = $opt_f ? "true" : "";
-$srclang = $opt_l ? $opt_l : "c";
-$templatedir = $opt_t ? $opt_t : "asp_sample";
-$dbgenv = $opt_d ? "TOPPERS_".$opt_d : "";
-$enable_trace = $opt_r ? "true" : "";
-$net_if = $opt_i;
-$net_dev = $opt_v;
-$net_proto = $opt_n;
-$trans_proto = $opt_s;
-$aspsampledir = "sample";
-
-#
-#  オブジェクトファイル名の拡張子を返す
-#
-sub get_objext {
-	local(@uname);
-
-	use POSIX;
-	@uname = do uname();
-	if ($uname[0] =~ /^cygwin/i) {
-		return("exe");
-	}
-	else {
-		return("");
-	}
-}
-
-#
-#  プログラムの場所を検索する
-#
-sub get_path {
-	local($progname, @pathlist) = @_;
-	local($path);
-
-	foreach $path (@pathlist) {
-		if (-x $path."/".$progname) {
-			return($path."/".$progname);
-		}
-	}
-	return("");
-}
-
-#
-#  Makefile を変換する
-#
-sub convMakefileSub {
-	local($infile, $outfile) = @_;
-	local($line, $varname, $varval);
-
-	unless (open(INFILE, $infile)) {
-		print STDERR "tinet_asp_configure: can't open $infile\n";
-		exit(1);
-	}
-	unless (open(OUTFILE, ">> ".$outfile)) {
-		print STDERR "tinet_asp_configure: can't open $outfile\n";
-		exit(1);
-	}
-
-	while ($line = <INFILE>) {
-		chop $line;
-		while ($line =~ /^(.*)\@\(([A-Za-z0-9_]+)\)(.*)$/) {
-			$line = $1.$vartable{$2}.$3;
-		}
-		print OUTFILE $line,"\n";
-	}
-
-	close(INFILE);
-	close(OUTFILE);
-}
-
-#
-#  Makefile を変換する
-#
-sub convMakefile {
-	local($infile, $copyright, $outfile) = @_;
-	local($aspMakefile);
-
-	# Mekfile 有ればリネームする。
-	print STDERR "tinet_asp_configure: Generating $outfile from $infile.\n";
-	if (-f $outfile) {
-		print STDERR "tinet_asp_configure: $outfile exists.",
-						"  Save as $outfile.bak.\n";
-		rename($outfile, $outfile.".bak");
-	}
-
-	# TINET のコピーライトを書き込む
-	&convMakefileSub($copyright, $outfile);
-
-	# 出力する Makefile をオープンする
-	unless (open(OUTFILE, ">> ".$outfile)) {
-		print STDERR "tinet_asp_configure: can't open $outfile\n";
-		exit(1);
-	}
-
-	# 参照する sample/Makefile をオープンする。
-	$aspMakefile = $aspsampledir."/Makefile";
-	unless (open(ASPFILE, $aspMakefile)) {
-		print STDERR "tinet_asp_configure: can't open $aspMakefile\n";
-		exit(1);
-	}
-
-	# 参照する sample/Makefile のコピーライトを読み飛ばす。
-	while ($line = <ASPFILE>) {
-		chop $line;
-		if ($line !~ /^#/) {
-			print OUTFILE $line,"\n";
-			last;
-		}
-	}
-
-	# 'APPLNAME = @(APPLNAME)' の行まで書き込む
-	while ($line = <ASPFILE>) {
-		chop $line;
-		while ($line =~ /^(.*)\@\(([A-Za-z0-9_]+)\)(.*)$/) {
-			$line = $1.$vartable{$2}.$3;
-		}
-		print OUTFILE $line,"\n";
-		if ($line =~ /^APPLNAME = /) {
-			last;
-		}
-	}
-
-	# '#' 前の行まで書き込む
-	while ($line = <ASPFILE>) {
-		chop $line;
-		while ($line =~ /^(.*)\@\(([A-Za-z0-9_]+)\)(.*)$/) {
-			$line = $1.$vartable{$2}.$3;
-		}
-		if ($line =~ /^#/) {
-			last;
-		}
-		print OUTFILE $line,"\n";
-	}
-
-	# 一度出力する Makefile をクローズする。
-	close(OUTFILE);
-
-	# TINET の Makefile を書き込む
-	&convMakefileSub($infile, $outfile);
-
-	# もう一度出力する Makefile をオープンする
-	unless (open(OUTFILE, ">> ".$outfile)) {
-		print STDERR "tinet_asp_configure: can't open $outfile\n";
-		exit(1);
-	}
-
-	# 参照する sample/Makefile の最終行まで書き込む
-	while ($line = <ASPFILE>) {
-		chop $line;
-		while ($line =~ /^(.*)\@\(([A-Za-z0-9_]+)\)(.*)$/) {
-			$line = $1.$vartable{$2}.$3;
-		}
-		print OUTFILE $line,"\n";
-	}
-
-	close(OUTFILE);
-	close(ASPFILE);
-}
-
-#
-#  Makefile を生成する
-#
-sub genMakefile {
-	local($file, $mandatory) = @_;
-	local($path, $copyright);
-
-	$path = $sampledir.$file.".".$applname;
-	$copyright = $sampledir.$file.".copyright";
-	if (-f $path) {
-		&convMakefile($path, $copyright, $file);
-		return;
-	}	
-
-	$path = $sampledir.$file;
-	if ($mandatory || -f $path) {
-		&convMakefile($path, $copyright, $file);
-	}	
-}
-
-#
-#  ファイルを変換する
-#
-sub convert {
-	local($infile, $outfile) = @_;
-	local($line, $varname, $varval);
-
-	print STDERR "tinet_asp_configure: Generating $outfile from $infile.\n";
-	if (-f $outfile) {
-		print STDERR "tinet_asp_configure: $outfile exists.",
-						"  Save as $outfile.bak.\n";
-		rename($outfile, $outfile.".bak");
-	}
-	unless (open(INFILE, $infile)) {
-		print STDERR "tinet_asp_configure: can't open $infile\n";
-		exit(1);
-	}
-	unless (open(OUTFILE, "> ".$outfile)) {
-		print STDERR "tinet_asp_configure: can't open $outfile\n";
-		exit(1);
-	}
-
-	while ($line = <INFILE>) {
-		chop $line;
-		while ($line =~ /^(.*)\@\(([A-Za-z0-9_]+)\)(.*)$/) {
-			$line = $1.$vartable{$2}.$3;
-		}
-		print OUTFILE $line,"\n";
-	}
-
-	close(INFILE);
-	close(OUTFILE);
-}
-
-#
-#  サンプルを見つけてファイルを生成する
-#
-sub generate {
-	local($file, $mandatory) = @_;
-	local($path);
-
-	$path = $sampledir.$file.".".$applname;
-	if (-f $path) {
-		do convert($path, $file);
-		return;
-	}	
-
-	$path = $sampledir.$file;
-	if ($mandatory || -f $path) {
-		do convert($path, $file);
-	}	
-}
-
-#
-#  TINET のソースディレクトリ名を取り出す
-#
-$pwd = `pwd`; chop $pwd;
-if ($opt_e) {
-	$tinetabsdir = $tinetdir = $opt_e;
-}
-elsif ($0 =~ /(.*)\/tinet_asp_configure/) {
-	$tinetdir = $1;
-	if ($tinetdir =~ /^\//) {
-		$tinetabsdir = $tinetdir;
-	}
-	else {
-		$tinetabsdir = $pwd."/".$tinetdir;
-	}
-}
-else {
-	$tinetabsdir = $tinetdir = $pwd;
-}
-$sampledir = $tinetdir."/".$templatedir."/";
-
-#
-#  ソースディレクトリ名を取り出す
-#
-$pwd = `pwd`; chop $pwd;
-if ($opt_D) {
-	$srcabsdir = $srcdir = $opt_D;
-}
-elsif ($0 =~ /(.*)\/tinet\/tinet_asp_configure/) {
-	$srcdir = $1;
-	if ($srcdir =~ /^\//) {
-		$srcabsdir = $srcdir;
-	}
-	else {
-		$srcabsdir = $pwd."/".$srcdir;
-	}
-}
-else {
-	$srcabsdir = $srcdir = $pwd;
-}
-$aspsampledir = $srcdir."/".$aspsampledir;
-
-$perl = $opt_p ? $opt_p : do get_path("perl", ("/usr/local/bin", "/usr/bin"));
-$cfg = $opt_g ? $opt_g : "\$(SRCDIR)/cfg/cfg/cfg";
-$cfgfile = $opt_g ? $opt_g : $srcdir."/cfg/cfg/cfg";
-
-#
-#  オプションの確認
-#
-unless ($opt_T) {
-	print STDERR "tinet_asp_configure: -T option is mandatory\n";
-	print STDERR "Installed targets are:\n";
-	foreach $targetname (<$srcdir/target/[a-zA-Z1-9]*>) {
-		$targetname =~ s|$srcdir/target/||;
-		print STDERR "\t$targetname\n";
-	}
-	exit(1);
-}
-unless ($opt_i) {
-	print STDERR "tinet_jsp_configure: -i option is mandatory\n";
-	exit(1);
-}
-else {
-	unless ($opt_v) {
-		print STDERR "tinet_jsp_configure: -v option is mandatory\n";
-		exit(1);
-	}
-}
-if ($opt_n) {
-	unless ($opt_n eq "inet4" || $opt_n eq "inet6") {
-		print STDERR "tinet_jsp_configure: inet4 or inet6 expected in -n option\n";
-		exit(1);
-	}
-}
-else {
-	print STDERR "tinet_jsp_configure: -n option is mandatory\n";
-	exit(1);
-}
-if ($opt_s) {
-	unless ($opt_s eq "tcp" || $opt_s eq "udp" || $opt_s eq "tcp/udp") {
-		print STDERR "tinet_jsp_configure: tcp, udp or tcp/udp expected in -s option\n";
-		exit(1);
-	}
-}
-else {
-	print STDERR "tinet_jsp_configure: -s option is mandatory\n";
-	exit(1);
-}
-
-#
-#  変数テーブルの作成
-#
-%vartable = ();
-$vartable{"TARGET"} = $target;
-$vartable{"APPLNAME"} = $applname;
-$vartable{"APPLDIR"} = $appldir;
-$vartable{"APPLOBJS"} = $applobjs;
-$vartable{"KERNEL_LIB"} = $kernel_lib;
-$vartable{"KERNEL_FUNCOBJS"} = $kernel_funcobjs;
-$vartable{"SRCDIR"} = $srcdir;
-$vartable{"SRCABSDIR"} = $srcabsdir;
-$vartable{"SRCLANG"} = $srclang;
-$vartable{"DBGENV"} = $dbgenv;
-$vartable{"ENABLE_TRACE"} = $enable_trace;
-$vartable{"PERL"} = $perl;
-$vartable{"CFG"} = $cfg;
-$objext = do get_objext();
-$vartable{"OBJEXT"} = $objext;
-$vartable{"TINETDIR"} = $tinetdir;
-$vartable{"TINETABSDIR"} = $tinetabsdir;
-$vartable{"NET_IF"} = $net_if;
-$vartable{"NET_DEV"} = $net_dev;
-
-#
-#  -n オプションの処理
-#
-
-$vartable{"SUPPORT_INET4"} = "#SUPPORT_INET4 = true";
-$vartable{"SUPPORT_INET6"} = "#SUPPORT_INET6 = true";
-if ($net_proto eq "inet4") {
-	$vartable{"SUPPORT_INET4"} = "SUPPORT_INET4 = true";
-}
-if ($net_proto eq "inet6") {
-	$vartable{"SUPPORT_INET6"} = "SUPPORT_INET6 = true";
-}
-
-#
-#  -s オプションの処理
-#
-
-$vartable{"SUPPORT_TCP"} = "#SUPPORT_TCP = true";
-$vartable{"SUPPORT_UDP"} = "#SUPPORT_UDP = true";
-if ($trans_proto eq "tcp" || $trans_proto eq "tcp/udp") {
-	$vartable{"SUPPORT_TCP"} = "SUPPORT_TCP = true";
-}
-if ($trans_proto eq "udp" || $trans_proto eq "tcp/udp") {
-	$vartable{"SUPPORT_UDP"} = "SUPPORT_UDP = true";
-}
-
-#
-#  ターゲットディレクトリのチェック
-#
-
-if (! -d $srcdir."/target/".$target) {
-	print STDERR "tinet_asp_configure: $srcdir/target/$target not exist\n";
-	exit(1);
-}
-
-#
-#  Makefile とアプリケーションファイルの生成
-#
-
-&genMakefile("Makefile", 1);
-do generate($applname.".c", 0);
-do generate($applname.".cpp", 0);
-do generate($applname.".h", 0);
-do generate($applname.".cfg", 0);
-do generate("tinet_".$applname.".cfg", 0);
-do generate("route_cfg.c", 0);
-do generate("tinet_app_config.h", 0);
-
-#
-#  cfg ができているかのチェック
-#
-
-if (!(-x ($objext == "" ? $cfgfile : $cfgfile.".".$objext))) {
-	print STDERR "Please compile the configurator (cfg).\n";
-}
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/tinet_config.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/tinet_config.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/tinet_config.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -39,7 +39,9 @@
  */
 
-/* TCPの受動オープンをサポートする。*/
-
+/* TCPの受動オープンをサポートする【TINET 1.7 以降不要になった】。*/
+
+#if 0
 #define TCP_CFG_PASSIVE_OPEN
+#endif
 
 /* TCPのノンブロッキングコール機能を組込む。*/
@@ -104,4 +106,94 @@
 #endif
  */
+
+/*
+ *  TINET 1.5 との互換性のための定義
+ */
+
+/* ルーティング表のエントリ数の定義 */
+
+#define NUM_IN6_ROUTE_ENTRY			\
+	(NUM_IN6_STATIC_ROUTE_ENTRY + NUM_IN6_REDIRECT_ROUTE_ENTRY)
+					/* ルーティング表のエントリ数	*/
+
+#define NUM_IN4_ROUTE_ENTRY		\
+	(NUM_IN4_STATIC_ROUTE_ENTRY + NUM_IN4_REDIRECT_ROUTE_ENTRY)
+					/* ルーティング表のエントリ数	*/
+
+#if defined(SUPPORT_INET6)
+
+#if defined(SUPPORT_INET4)
+
+#else	/* #if defined(SUPPORT_INET4) */
+
+#ifndef NUM_IN6_STATIC_ROUTE_ENTRY
+#define NUM_IN6_STATIC_ROUTE_ENTRY	NUM_STATIC_ROUTE_ENTRY
+#endif
+
+#ifndef NUM_IN6_REDIRECT_ROUTE_ENTRY
+#define NUM_IN6_REDIRECT_ROUTE_ENTRY	NUM_REDIRECT_ROUTE_ENTRY
+#endif
+
+#ifdef  NUM_ROUTE_ENTRY
+#undef  NUM_ROUTE_ENTRY
+#endif
+#define NUM_ROUTE_ENTRY			NUM_IN6_ROUTE_ENTRY
+
+#endif	/* #if defined(SUPPORT_INET4) */
+
+#else	/* of #if defined(SUPPORT_INET6) */
+
+#if defined(SUPPORT_INET4)
+
+#ifndef NUM_IN4_STATIC_ROUTE_ENTRY
+#define NUM_IN4_STATIC_ROUTE_ENTRY	NUM_STATIC_ROUTE_ENTRY
+#endif
+
+#ifndef NUM_IN4_REDIRECT_ROUTE_ENTRY
+#define NUM_IN4_REDIRECT_ROUTE_ENTRY	NUM_REDIRECT_ROUTE_ENTRY
+#endif
+
+#ifdef  NUM_ROUTE_ENTRY
+#undef  NUM_ROUTE_ENTRY
+#endif
+#define NUM_ROUTE_ENTRY			NUM_IN4_ROUTE_ENTRY
+
+#endif	/* of #if defined(SUPPORT_INET4) */
+
+#endif	/* of #if defined(SUPPORT_INET6) */
+
+/* DHCP の定義 */
+
+#ifdef  DHCP4_CLI_CFG
+#define DHCP_CFG
+#endif
+
+/*
+ *  IPv6/IPv4 に関する定義
+ */
+
+/*
+ *  指定されたマクロに対する TINET 内部のマクロの定義
+ *
+ *    SUPPORT_INET6		 .   .  ON  ON  ON  ON
+ *    SUPPORT_INET4		ON  ON   .   .  ON  ON
+ *    API_CFG_IP4MAPPED_ADDR	 .  ON   .  ON   .  ON
+ *    ----------------------    ----------------------
+ *    _IP6_CFG                   .   .  ON  ON  ON  ON
+ *    _IP4_CFG                  ON  ON   .  ON  ON  ON
+ *    
+ */
+
+#if !defined(SUPPORT_INET6) && defined(API_CFG_IP4MAPPED_ADDR)
+#error option selection: !defined(SUPPORT_INET6) && defined(API_CFG_IP4MAPPED_ADDR)
+#endif
+
+#if defined(SUPPORT_INET6)
+#define	_IP6_CFG
+#endif
+
+#if defined(SUPPORT_INET4) || (defined(SUPPORT_INET6) && defined(API_CFG_IP4MAPPED_ADDR))
+#define _IP4_CFG
+#endif
 
 /*
@@ -211,57 +303,61 @@
 
 #ifndef TMO_IP4_FRAG_GET_NET_BUF
-#define TMO_IP4_FRAG_GET_NET_BUF	ULONG_C(1000*1000)	/* [ms]、IPv4 データグラム再構成用ネットワークバッファ獲得タイムアウト	*/
+#define TMO_IP4_FRAG_GET_NET_BUF	ULONG_C(1000000)	/* [us]、IPv4 データグラム再構成用ネットワークバッファ獲得タイムアウト	*/
 #endif
 
 #ifndef TMO_IP6_FRAG_GET_NET_BUF
-#define TMO_IP6_FRAG_GET_NET_BUF	ULONG_C(1000*1000)	/* [ms]、IPv6 データグラム再構成用ネットワークバッファ獲得タイムアウト	*/
+#define TMO_IP6_FRAG_GET_NET_BUF	ULONG_C(1000000)	/* [us]、IPv6 データグラム再構成用ネットワークバッファ獲得タイムアウト	*/
 #endif
 
 #ifndef TMO_PPP_GET_NET_BUF
-#define TMO_PPP_GET_NET_BUF		ULONG_C(1000*1000)	/* [ms]、PPP 受信用ネットワークバッファ獲得タイムアウト	*/
+#define TMO_PPP_GET_NET_BUF		ULONG_C(1000000)	/* [us]、PPP 受信用ネットワークバッファ獲得タイムアウト	*/
 #endif
 
 #ifndef TMO_ARP_GET_NET_BUF
-#define TMO_ARP_GET_NET_BUF		ULONG_C(1000*1000)	/* [ms]、ARP のネットワークバッファ獲得タイムアウト	*/
+#define TMO_ARP_GET_NET_BUF		ULONG_C(1000000)	/* [us]、ARP のネットワークバッファ獲得タイムアウト	*/
 #endif
 
 #ifndef TMO_TCP_GET_NET_BUF
-#define TMO_TCP_GET_NET_BUF		ULONG_C(1000*1000)	/* [ms]、TCP のネットワークバッファ獲得タイムアウト	*/
+#define TMO_TCP_GET_NET_BUF		ULONG_C(1000000)	/* [us]、TCP のネットワークバッファ獲得タイムアウト	*/
 #endif
 
 #ifndef TMO_TCP_OUTPUT
-#define TMO_TCP_OUTPUT			ULONG_C(1000*1000)	/* [ms]、TCP 出力タイムアウト				*/
+#define TMO_TCP_OUTPUT			ULONG_C(1000000)	/* [us]、TCP 出力タイムアウト				*/
 #endif
 
 #ifndef TMO_UDP_OUTPUT
-#define TMO_UDP_OUTPUT			ULONG_C(1000*1000)	/* [ms]、UDP 出力タイムアウト				*/
+#define TMO_UDP_OUTPUT			ULONG_C(1000000)	/* [us]、UDP 出力タイムアウト				*/
 #endif
 
 #ifndef TMO_ICMP_OUTPUT
-#define TMO_ICMP_OUTPUT			ULONG_C(1000*1000)	/* [ms]、ICMP 出力タイムアウト				*/
+#define TMO_ICMP_OUTPUT			ULONG_C(1000000)	/* [us]、ICMP 出力タイムアウト				*/
+#endif
+
+#ifndef TMO_IGMP_OUTPUT
+#define TMO_IGMP_OUTPUT			ULONG_C(1000000)	/* [us]、IGMP 出力タイムアウト				*/
 #endif
 
 #ifndef TMO_ND6_NS_OUTPUT
-#define TMO_ND6_NS_OUTPUT		ULONG_C(1000*1000)	/* [ms]、近隣要請出力タイムアウト			*/
+#define TMO_ND6_NS_OUTPUT		ULONG_C(1000000)	/* [us]、近隣要請出力タイムアウト			*/
 #endif
 
 #ifndef TMO_ND6_NA_OUTPUT
-#define TMO_ND6_NA_OUTPUT		ULONG_C(1000*1000)	/* [ms]、近隣通知出力タイムアウト			*/
+#define TMO_ND6_NA_OUTPUT		ULONG_C(1000000)	/* [us]、近隣通知出力タイムアウト			*/
 #endif
 
 #ifndef TMO_ND6_RS_OUTPUT
-#define TMO_ND6_RS_OUTPUT		ULONG_C(1000*1000)	/* [ms]、ルータ要請出力タイムアウト			*/
+#define TMO_ND6_RS_OUTPUT		ULONG_C(1000000)	/* [us]、ルータ要請出力タイムアウト			*/
 #endif
 
 #ifndef TMO_ARP_OUTPUT
-#define TMO_ARP_OUTPUT			ULONG_C(1000*1000)	/* [ms]、アドレス解決要求出力タイムアウト		*/
+#define TMO_ARP_OUTPUT			ULONG_C(1000000)	/* [us]、アドレス解決要求出力タイムアウト		*/
 #endif
 
 #ifndef TMO_ND6_RTR_SOL_DELAY
-#define TMO_ND6_RTR_SOL_DELAY		ULONG_C(1000*1000)	/* [ms]、ルータ要請出力遅延				*/
+#define TMO_ND6_RTR_SOL_DELAY		ULONG_C(1000000)	/* [us]、ルータ要請出力遅延				*/
 #endif
 
 #ifndef TMO_ND6_RTR_SOL_INTERVAL
-#define TMO_ND6_RTR_SOL_INTERVAL	ULONG_C(4000*1000)	/* [ms]、ルータ要請出力間隔				*/
+#define TMO_ND6_RTR_SOL_INTERVAL	ULONG_C(4000000)	/* [us]、ルータ要請出力間隔				*/
 #endif
 
@@ -387,10 +483,5 @@
 #include <net/net_rename.h>
 #include <netinet/in_rename.h>
-
-#ifdef SUPPORT_INET6
-
 #include <netinet6/in6_rename.h>
 
-#endif	/* of #ifdef SUPPORT_INET6 */
-
 #endif /* _TINET_CONFIG_H_ */
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/tinet_defs.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/tinet_defs.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/tinet_defs.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/tinet/tinet_kernel_defs.h
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/tinet/tinet_kernel_defs.h	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/tinet/tinet_kernel_defs.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
Index: EcnlProtoTool/trunk/asp3_dcre/utils/gentest.rb
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/utils/gentest.rb	(revision 321)
+++ EcnlProtoTool/trunk/asp3_dcre/utils/gentest.rb	(revision 331)
@@ -124,4 +124,8 @@
     when /^OVR$/
       @count_var = "overrun_count"
+    when /^ISR([0-9]*)$/
+      @count_var = "isr#{$1}_count"
+    when /^INTHDR([0-9]*)$/
+      @count_var = "inthdr#{$1}_count"
     when /^CPUEXC([0-9]*)$/
       @count_var = "cpuexc#{$1}_count"
@@ -187,4 +191,10 @@
       print("\nvoid\n")
       print("overrun_handler(ID tskid, intptr_t exinf)\n")
+    when /^ISR([0-9]*)$/
+      print("\nvoid\n")
+      print("isr#{$1}(intptr_t exinf)\n")
+    when /^INTHDR([0-9]*)$/
+      print("\nvoid\n")
+      print("inthdr#{$1}_handler(void)\n")
     when /^CPUEXC([0-9]*)$/
       print("\nvoid\n")
Index: EcnlProtoTool/trunk/curl-7.57.0/.cproject
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/.cproject	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/.cproject	(revision 331)
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.708002717">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.708002717" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactExtension="a" artifactName="curl" buildArtefactType="com.renesas.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=com.renesas.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf *.lst *.lis *.lpp *.map" description="" id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.708002717" name="Debug" parent="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id">
+					<folderInfo id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.708002717." name="/" resourcePath="">
+						<toolChain id="com.renesas.cdt.library.rz.debug.win32.toolchain.Id.1452274765" name="KPIT GNUARM-NONE-EABI Toolchain" superClass="com.renesas.cdt.library.rz.debug.win32.toolchain.Id">
+							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.PE" id="com.renesas.cdt.rz.libraryProject.debug.win32.targetplatform.Id.2013208034" name="Target Platform" osList="win32,linux" superClass="com.renesas.cdt.rz.libraryProject.debug.win32.targetplatform.Id"/>
+							<builder buildPath="${workspace_loc:/curl-7.57.0}/Debug" id="com.renesas.cdt.rz.library.project.debug.win32.builder.Id.1277849763" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.renesas.cdt.rz.library.project.debug.win32.builder.Id"/>
+							<tool id="com.renesas.cdt.rz.libraryProject.debug.win32.tool.compiler.Id.1582792245" name="Compiler" superClass="com.renesas.cdt.rz.libraryProject.debug.win32.tool.compiler.Id">
+								<option defaultValue="true" id="com.renesas.cdt.core.Compiler.option.misc2.1394220045" name="æ¨æºã·ã¹ãã ã»ãã£ã¬ã¯ããªã¼ã§ãããã¼ã»ãã¡ã¤ã«ãæ¤ç´¢ããªã (-nostdinc)" superClass="com.renesas.cdt.core.Compiler.option.misc2" valueType="boolean"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.dataEndian.1799201559" name="ã¨ã³ãã£ã¢ã³" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.dataEndian" value="Little-endian" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.instructionset.670440721" name="å½ä»¤ã»ãã" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.instructionset" value="ARM" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.interworking.1789987423" name="ã¤ã³ã¿ã¼ã»ã¯ã¼ã­ã³ã°" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.interworking" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.targetfpu.964367930" name="ã¿ã¼ã²ãã FPU (-mfpu)" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.targetfpu" value="vfpv3-d16" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.floatingpointabi.1225178372" name="æµ®åå°æ°ç¹ ABI (-mfloat-abi=name)" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.floatingpointabi" value="Hard" valueType="enumerated"/>
+								<option id="com.renesas.cdt.core.Compiler.option.warnStackSize.103534362" name="Warn if stack size exceeds the limit (-Wstack-usage) (H')" superClass="com.renesas.cdt.core.Compiler.option.warnStackSize" value="100" valueType="string"/>
+								<option id="com.renesas.cdt.core.Compiler.option.CPUSeries.751954334" name="CPU ã·ãªã¼ãº" superClass="com.renesas.cdt.core.Compiler.option.CPUSeries" value="RZ/A" valueType="string"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.architecture.1090813455" name="ã¢ã¼ã­ãã¯ãã£ã¼" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.architecture" value="armv7-a" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.cpuType.1080807903" name="CPU ã¿ã¤ã" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.cpuType" value="cortex-a9" valueType="enumerated"/>
+								<option id="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal.926924923" name="Decimal representation of '-Wstack-usage'" superClass="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal" value="256" valueType="string"/>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.rz.Debug.Compiler.option.library.macroDefines.1119501601" name="ãã¯ã­å®ç¾©" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.macroDefines" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="HAVE_CONFIG_H"/>
+									<listOptionValue builtIn="false" value="BUILDING_LIBCURL"/>
+								</option>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.core.Compiler.option.includeFileDir.1227661554" name="ã¤ã³ã¯ã«ã¼ãã»ãã¡ã¤ã«ã»ãã£ã¬ã¯ããªã¼" superClass="com.renesas.cdt.core.Compiler.option.includeFileDir" valueType="includePath">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/musl-1.1.18/include}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/openssl-1.1.0e/include}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/zlib-1.2.11}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/include}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/lib}&quot;"/>
+								</option>
+								<inputType id="%Base.Compiler.C.InputType.Id.1293793216" name="C å
+¥å" superClass="%Base.Compiler.C.InputType.Id"/>
+								<inputType id="Base.Compiler.CPP.InputType.Id.1257293022" name="C++ å
+¥å" superClass="Base.Compiler.CPP.InputType.Id"/>
+							</tool>
+							<tool id="com.renesas.cdt.library.rz.Debug.win32.tool.assembler.Id.446393242" name="Assembler" superClass="com.renesas.cdt.library.rz.Debug.win32.tool.assembler.Id">
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.dataEndian.1986221263" name="ã¨ã³ãã£ã¢ã³" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.dataEndian" value="Little-endian" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.instructionset.1954220000" name="å½ä»¤ã»ãã" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.instructionset" value="ARM" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.targetfpu.2117544333" name="ã¿ã¼ã²ãã FPU (-mfpu)" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.targetfpu" value="vfpv3-d16" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.floatingpointabi.1866435465" name="æµ®åå°æ°ç¹ ABI (-mfloat-abi=name)" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.floatingpointabi" value="Hard" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.architecture.171624983" name="ã¢ã¼ã­ãã¯ãã£ã¼" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.architecture" value="armv7-a" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.cpuType.999288829" name="CPU ã¿ã¤ã" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.cpuType" value="cortex-a9" valueType="enumerated"/>
+								<inputType id="%Base.Assembler.inputType.Id.1664729182" name="ã¢ã»ã³ãã©ã¼å
+¥åã¿ã¤ã" superClass="%Base.Assembler.inputType.Id"/>
+							</tool>
+							<tool id="com.renesas.cdt.library.rz.debug.win32.tool.archive.Id.720064253" name="Archive Generator" superClass="com.renesas.cdt.library.rz.debug.win32.tool.archive.Id"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="curl-7.57.0.com.renesas.cdt.rz.library.projectType.Id.1586819345" name="Static Library (Renesas)" projectType="com.renesas.cdt.rz.library.projectType.Id"/>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+	<storageModule moduleId="refreshScope" versionNumber="2">
+		<configuration configurationName="Debug">
+			<resource resourceType="PROJECT" workspacePath="/curl-7.57.0"/>
+		</configuration>
+	</storageModule>
+</cproject>
Index: EcnlProtoTool/trunk/curl-7.57.0/.info
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/.info	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/.info	(revision 331)
@@ -0,0 +1,7 @@
+TOOL_CHAIN=KPIT GNUARM-NONE-EABI Toolchain
+VERSION=v16.01
+TC_INSTALL=C:\Program Files (x86)\KPIT\GNUARM-NONEv16.01-EABI\arm-none-eabi\arm-none-eabi\
+GCC_STRING=5.2-GNUARM-NONE_v16.01
+VERSION_IDE=
+E2STUDIO_VERSION=5.4.0.018
+ACTIVE_CONFIGURATION=Debug
Index: EcnlProtoTool/trunk/curl-7.57.0/.project
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/.project	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/.project	(revision 331)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>curl-7.57.0</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>com.renesas.cdt.core.genmakebuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>com.renesas.cdt.core.kpitcnature</nature>
+		<nature>com.renesas.cdt.core.kpitccnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+	</natures>
+</projectDescription>
Index: EcnlProtoTool/trunk/curl-7.57.0/CHANGES
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/CHANGES	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/CHANGES	(revision 331)
@@ -0,0 +1,6845 @@
+                                  _   _ ____  _
+                              ___| | | |  _ \| |
+                             / __| | | | |_) | |
+                            | (__| |_| |  _ <| |___
+                             \___|\___/|_| \_\_____|
+
+                                  Changelog
+
+Version 7.57.0 (29 Nov 2017)
+
+Daniel Stenberg (29 Nov 2017)
+- RELEASE-NOTES: curl 7.57.0
+
+- THANKS: added contributors from 7.57.0 release
+
+- openssl: fix boringssl build again
+  
+  commit d3ab7c5a21e broke the boringssl build since it doesn't have
+  RSA_flags(), so we disable that code block for boringssl builds.
+  
+  Reported-by: W.âMark Kubacki
+  Fixes #2117
+
+- curl_ntlm_core.c: use the limits.h's SIZE_T_MAX if provided
+
+- libcurl-share.3: the connection cache is shareable now
+
+- global_init: ignore CURL_GLOBAL_SSL's absense
+  
+  This bit is no longer used. It is not clear what it meant for users to
+  "init the TLS" in a world with different TLS backends and since the
+  introduction of multissl, libcurl didn't properly work if inited without
+  this bit set.
+  
+  Not a single user responded to the call for users of it:
+  https://curl.haxx.se/mail/lib-2017-11/0072.html
+  
+  Reported-by: Evgeny Grin
+  Assisted-by: Jay Satiro
+  
+  Fixes #2089
+  Fixes #2083
+  Closes #2107
+
+- ntlm: avoid integer overflow for malloc size
+  
+  Reported-by: Alex Nichols
+  Assisted-by: Kamil Dudka and Max Dymond
+  
+  CVE-2017-8816
+  
+  Bug: https://curl.haxx.se/docs/adv_2017-11e7.html
+
+- wildcardmatch: fix heap buffer overflow in setcharset
+  
+  The code would previous read beyond the end of the pattern string if the
+  match pattern ends with an open bracket when the default pattern
+  matching function is used.
+  
+  Detected by OSS-Fuzz:
+  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4161
+  
+  CVE-2017-8817
+  
+  Bug: https://curl.haxx.se/docs/adv_2017-ae72.html
+
+- [Jay Satiro brought this change]
+
+  url: fix alignment of ssl_backend_data struct
+  
+  - Align the array of ssl_backend_data on a max 32 byte boundary.
+  
+  8 is likely to be ok but I went with 32 for posterity should one of
+  the ssl_backend_data structs change to contain a larger sized variable
+  in the future.
+  
+  Prior to this change (since dev 70f1db3, release 7.56) the connectdata
+  structure was undersized by 4 bytes in 32-bit builds with ssl enabled
+  because long long * was mistakenly used for alignment instead of
+  long long, with the intention being an 8 byte boundary. Also long long
+  may not be an available type.
+  
+  The undersized connectdata could lead to oob read/write past the end in
+  what was expected to be the last 4 bytes of the connection's secondary
+  socket https proxy ssl_backend_data struct (the secondary socket in a
+  connection is used by ftp, others?).
+  
+  Closes https://github.com/curl/curl/issues/2093
+  
+  CVE-2017-8818
+  
+  Bug: https://curl.haxx.se/docs/adv_2017-af0a.html
+
+- ssh: remove check for a NULL pointer (!)
+  
+  With this check present, scan-build warns that we might dereference this
+  point in other places where it isn't first checked for NULL. Thus, if it
+  *can* be NULL we have a problem on a few places. However, this pointer
+  should not be possible to be NULL here so I remove the check and thus
+  also three different scan-build warnings.
+  
+  Closes #2111
+
+- [Matthew Kerwin brought this change]
+
+  test: add test for bad UNC/SMB path in file: URL
+
+- [Matthew Kerwin brought this change]
+
+  test: add tests to ensure basic file: URLs
+
+- [Matthew Kerwin brought this change]
+
+  URL: update "file:" URL handling
+  
+  * LOTS of comment updates
+  * explicit error for SMB shares (e.g. "file:////share/path/file")
+  * more strict handling of authority (i.e. "//localhost/")
+  * now accepts dodgy old "C:|" drive letters
+  * more precise handling of drive letters in and out of Windows
+    (especially recognising both "file:c:/" and "file:/c:/")
+  
+  Closes #2110
+
+- metalink: fix memory-leak and NULL pointer dereference
+  
+  Reported by scan-build
+  
+  Closes #2109
+
+- [Alessandro Ghedini brought this change]
+
+  connect: add support for new TCP Fast Open API on Linux
+  
+  The new API added in Linux 4.11 only requires setting a socket option
+  before connecting, without the whole sento() machinery.
+  
+  Notably, this makes it possible to use TFO with SSL connections on Linux
+  as well, without the need to mess around with OpenSSL (or whatever other
+  SSL library) internals.
+  
+  Closes #2056
+
+- make: fix "make distclean"
+  
+  Fixes #2097
+  Closes #2108
+
+- RELEASE-NOTES: synced with 31f18d272
+
+Jay Satiro (23 Nov 2017)
+- connect: improve the bind error message
+  
+  eg consider a non-existent interface eth8, curl --interface eth8
+  
+  Before: curl: (45) Could not resolve host: eth8
+  After: curl: (45) Couldn't bind to 'eth8'
+  
+  Bug: https://github.com/curl/curl/issues/2104
+  Reported-by: Alfonso Martone
+
+Daniel Stenberg (23 Nov 2017)
+- examples/rtsp: clear RANGE again after use
+  
+  Fixes #2106
+  Reported-by: youngchopin on github
+
+- [Michael Kaufmann brought this change]
+
+  test1264: verify URL with space in host name being rejected
+
+- url: reject ASCII control characters and space in host names
+  
+  Host names like "127.0.0.1 moo" would otherwise be accepted by some
+  getaddrinfo() implementations.
+  
+  Updated test 1034 and 1035 accordingly.
+  
+  Fixes #2073
+  Closes #2092
+
+- Curl_open: fix OOM return error correctly
+  
+  Closes #2098
+
+- http2: fix "Value stored to 'end' is never read" scan-build error
+
+- http2: fix "Value stored to 'hdbuf' is never read" scan-build error
+
+- openssl: fix "Value stored to 'rc' is never read" scan-build error
+
+- mime: fix "Value stored to 'sz' is never read" scan-build error
+
+- Curl_llist_remove: fix potential NULL pointer deref
+  
+  Fixes a scan-build warning.
+
+- ntlm: remove unnecessary NULL-check to please scan-build
+
+- BUGS: spellchecked
+
+Jay Satiro (18 Nov 2017)
+- [fmmedeiros brought this change]
+
+  examples/curlx: Fix code style
+  
+  - Add braces around multi-line if statement.
+  
+  Closes https://github.com/curl/curl/pull/2096
+
+Daniel Stenberg (17 Nov 2017)
+- resolve: allow IP address within [] brackets
+  
+  ... so that IPv6 addresses can be passed like they can for connect-to
+  and how they're used in URLs.
+  
+  Added test 1324 to verify
+  Reported-by: Alex Malinovich
+  
+  Fixes #2087
+  Closes #2091
+
+- [Pavol Markovic brought this change]
+
+  macOS: Fix missing connectx function with Xcode version older than 9.0
+  
+  The previous fix https://github.com/curl/curl/pull/1788 worked just for
+  Xcode 9. This commit extends the fix to older Xcode versions effectively
+  by not using connectx function.
+  
+  Fixes https://github.com/curl/curl/issues/1330
+  Fixes https://github.com/curl/curl/issues/2080
+  Closes https://github.com/curl/curl/pull/1336
+  Closes #2082
+
+- [Dirk Feytons brought this change]
+
+  openssl: fix too broad use of HAVE_OPAQUE_EVP_PKEY
+  
+  Fixes #2079
+  Closes #2081
+
+- TODO: ignore private IP addresses in PASV response
+  
+  Closes #1455
+
+- RELEASE-NOTES: synced with ae7369b6d
+
+Michael Kaufmann (14 Nov 2017)
+- URL: return error on malformed URLs with junk after IPv6 bracket
+  
+  Follow-up to aadb7c7. Verified by new test 1263.
+  
+  Closes #2072
+
+Daniel Stenberg (14 Nov 2017)
+- INTERNALS: we may use libidn2 now, not libidn
+
+Patrick Monnerat (13 Nov 2017)
+- zlib/brotli: only include header files in modules needing them
+  
+  There is a conflict on symbol 'free_func' between openssl/crypto.h and
+  zlib.h on AIX. This is an attempt to resolve it.
+  
+  Bug: https://curl.haxx.se/mail/lib-2017-11/0032.html
+  Reported-By: Michael Felt
+
+Daniel Stenberg (13 Nov 2017)
+- SMB: fix uninitialized local variable
+  
+  Reported-by: Brian Carpenter
+
+- [Orgad Shaneh brought this change]
+
+  connect.c: remove executable bit on file
+  
+  Closes #2071
+
+- [hsiao yi brought this change]
+
+  README.md: fixed layout
+  
+  Closes #2069
+
+- setopt: split out curl_easy_setopt() to its own file
+  
+  ... to make url.c smaller.
+  
+  Closes #1944
+
+Jay Satiro (10 Nov 2017)
+- [John Starks brought this change]
+
+  cmake: Add missing setmode check
+  
+  Ensure HAVE_SETMODE is set to 1 on OSes that have setmode. Without this,
+  curl will corrupt binary files when writing them to stdout on Windows.
+  
+  Closes https://github.com/curl/curl/pull/2067
+
+Daniel Stenberg (10 Nov 2017)
+- curl_share_setopt: va_end was not called if conncache errors
+  
+  CID 984459, detected by Coverity
+
+Sergei Nikulov (10 Nov 2017)
+- [John Starks brought this change]
+
+  cmake: Correctly include curl.rc in Windows builds (#2064)
+  
+  Update CMakeLists.txt to add curl.rc to the correct list.
+
+Daniel Stenberg (9 Nov 2017)
+- RELEASE-NOTES: synced with 32828cc4f
+
+- [Luca Boccassi brought this change]
+
+  --interface: add support for Linux VRF
+  
+  The --interface command (CURLOPT_INTERFACE option) already uses
+  SO_BINDTODEVICE on Linux, but it tries to parse it as an interface or IP
+  address first, which fails in case the user passes a VRF.
+  
+  Try to use the socket option immediately and parse it as a fallback
+  instead.  Update the documentation to mention this feature, and that it
+  requires the binary to be ran by root or with CAP_NET_RAW capabilities
+  for this to work.
+  
+  Closes #2024
+
+- curl_share_setopt.3: document CURL_LOCK_DATA_CONNECT
+  
+  Closes #2043
+
+- examples: add shared-connection-cache
+
+- test1554: verify connection cache sharing
+
+- share: add support for sharing the connection cache
+
+- imap: deal with commands case insensitively
+  
+  As documented in RFC 3501 section 9:
+  https://tools.ietf.org/html/rfc3501#section-9
+  
+  Closes #2061
+
+- connect: store IPv6 connection status after valid connection
+  
+  ... previously it would store it already in the happy eyeballs stage
+  which could lead to the IPv6 bit being set for an IPv4 connection,
+  leading to curl not wanting to do EPSV=>PASV for FTP transfers.
+  
+  Closes #2053
+
+- curl_multi_fdset.3: emphasize curl_multi_timeout
+  
+  ... even when there's no socket to wait for, the timeout can still be
+  very short.
+
+Jay Satiro (9 Nov 2017)
+- content_encoding: fix inflate_stream for no bytes available
+  
+  - Don't call zlib's inflate() when avail_in stream bytes is 0.
+  
+  This is a follow up to the parent commit 19e66e5. Prior to that change
+  libcurl's inflate_stream could call zlib's inflate even when no bytes
+  were available, causing inflate to return Z_BUF_ERROR, and then
+  inflate_stream would treat that as a hard error and return
+  CURLE_BAD_CONTENT_ENCODING.
+  
+  According to the zlib FAQ, Z_BUF_ERROR is not fatal.
+  
+  This bug would happen randomly since packet sizes are arbitrary. A test
+  of 10,000 transfers had 55 fail (ie 0.55%).
+  
+  Ref: https://zlib.net/zlib_faq.html#faq05
+  
+  Closes https://github.com/curl/curl/pull/2060
+
+Patrick Monnerat (7 Nov 2017)
+- content_encoding: do not write 0 length data
+
+Daniel Stenberg (6 Nov 2017)
+- fnmatch: remove dead code
+  
+  There was a duplicate check for backslashes in the setcharset()
+  function.
+  
+  Coverity CID 1420611
+
+- url: remove unncessary NULL-check
+  
+  Since 'conn' won't be NULL in there and we also access the pointer in
+  there without the check.
+  
+  Coverity CID 1420610
+
+Viktor Szakats (6 Nov 2017)
+- src/Makefile.m32: fix typo in brotli lib customization
+  
+  Ref cc1f4436099decb9d1a7034b2bb773a9f8379d31
+
+- Makefile.m32: allow to customize brotli libs
+  
+  It adds the ability to link against static brotli libs.
+  
+  Also fix brotli include path.
+
+Patrick Monnerat (5 Nov 2017)
+- travis: add a job with brotli enabled
+
+- [Viktor Szakats brought this change]
+
+  Makefile.m32: add brotli support
+
+- HTTP: implement Brotli content encoding
+  
+  This uses the brotli external library (https://github.com/google/brotli).
+  Brotli becomes a feature: additional curl_version_info() bit and
+  structure fields are provided for it and CURLVERSION_NOW bumped.
+  
+  Tests 314 and 315 check Brotli content unencoding with correct and
+  erroneous data.
+  
+  Some tests are updated to accomodate with the now configuration dependent
+  parameters of the Accept-Encoding header.
+
+- HTTP: support multiple Content-Encodings
+  
+  This is implemented as an output streaming stack of unencoders, the last
+  calling the client write procedure.
+  
+  New test 230 checks this feature.
+  
+  Bug: https://github.com/curl/curl/pull/2002
+  Reported-By: Daniel Bankhead
+
+Jay Satiro (4 Nov 2017)
+- url: remove arg value check from CURLOPT_SSH_AUTH_TYPES
+  
+  Since CURLSSH_AUTH_ANY (aka CURLSSH_AUTH_DEFAULT) is ~0 an arg value
+  check on this option is incorrect; we have to accept any value.
+  
+  Prior to this change since f121575 (7.56.1+) CURLOPT_SSH_AUTH_TYPES
+  erroneously rejected CURLSSH_AUTH_ANY with CURLE_BAD_FUNCTION_ARGUMENT.
+  
+  Bug: https://github.com/curl/curl/commit/f121575#commitcomment-25347120
+
+Daniel Stenberg (4 Nov 2017)
+- ntlm: avoid malloc(0) for zero length passwords
+  
+  It triggers an assert() when built with memdebug since malloc(0) may
+  return NULL *or* a valid pointer.
+  
+  Detected by OSS-Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4054
+  
+  Assisted-by: Max Dymond
+  Closes #2054
+
+- RELEASE-NOTES: synced with ee8016b3d
+
+- curl: speed up handling of many URLs
+  
+  By properly keeping track of the last entry in the list of URLs/uploads
+  to handle, curl now avoids many meaningless traverses of the list which
+  speeds up many-URL handling *MASSIVELY* (several magnitudes on 100K
+  URLs).
+  
+  Added test 1291, to verify that it doesn't take ages - but we don't have
+  any detection of "too slow" command in the test suite.
+  
+  Reported-by: arainchik on github
+  Fixes #1959
+  Closes #2052
+
+- curl: pass through [] in URLs instead of calling globbing error
+  
+  Assisted-by: Per Lundberg
+  Fixes #2044
+  Closes #2046
+  Closes #2048
+
+- CURLOPT_INFILESIZE: accept -1
+  
+  Regression since f121575
+  
+  Reported-by: Petr Voytsik
+  Fixes #2047
+
+Jay Satiro (2 Nov 2017)
+- url: fix CURLOPT_DNS_CACHE_TIMEOUT arg value check to allow -1
+  
+  Prior to this change since f121575 (7.56.1+) CURLOPT_DNS_CACHE_TIMEOUT
+  erroneously rejected -1 with CURLE_BAD_FUNCTION_ARGUMENT.
+
+Dan Fandrich (1 Nov 2017)
+- http2: Fixed OOM handling in upgrade request
+  
+  This caused the torture tests on test 1800 to fail.
+
+- tests: Fixed torture tests on tests 556 and 650
+  
+  Test cleanup after OOM wasn't being consistently performed.
+
+Daniel Stenberg (1 Nov 2017)
+- CURLOPT_MAXREDIRS: allow -1 as a value
+  
+  ... which is valid according to documentation. Regression since
+  f121575c0b5f.
+  
+  Verified now in test 501.
+  
+  Reported-by: cbartl on github
+  Fixes #2038
+  Closes #2039
+
+- include: remove conncache.h inclusion from where its not needed
+
+Jay Satiro (1 Nov 2017)
+- url: fix CURLOPT_POSTFIELDSIZE arg value check to allow -1
+  
+  .. also add same arg value check to CURLOPT_POSTFIELDSIZE_LARGE.
+  
+  Prior to this change since f121575 (7.56.1+) CURLOPT_POSTFIELDSIZE
+  erroneously rejected -1 value with CURLE_BAD_FUNCTION_ARGUMENT.
+  
+  Bug: https://curl.haxx.se/mail/lib-2017-11/0000.html
+  Reported-by: Andrew Lambert
+
+Daniel Stenberg (31 Oct 2017)
+- cookie: avoid NULL dereference
+  
+  ... when expiring old cookies.
+  
+  Reported-by: Pavel Gushchin
+  Fixes #2032
+  Closes #2035
+
+Marcel Raad (30 Oct 2017)
+- memdebug: use send/recv signature for curl_dosend/curl_dorecv
+  
+  This avoids build errors and warnings caused by implicit casts.
+  
+  Closes https://github.com/curl/curl/pull/2031
+
+Daniel Stenberg (30 Oct 2017)
+- [Juro Bystricky brought this change]
+
+  mkhelp.pl: support reproducible build
+  
+  Do not generate line with the current date, such as:
+  
+  * Generation time: Tue Oct-24 18:01:41 2017
+  
+  This will improve reproducibility. The generated string is only
+  part of a comment, so there should be no adverse consequences.
+  
+  Signed-off-by: Juro Bystricky <juro.bystricky@intel.com>
+  
+  closes #2026
+
+Dan Fandrich (30 Oct 2017)
+- runtests.pl: Fixed typo in message
+
+Daniel Stenberg (30 Oct 2017)
+- curlx: the timeval functions are no longer provided as curlx_*
+  
+  Pointed-out-by: Dmitri Tikhonov
+  Bug: #2034
+
+- select: update comments
+  
+  s/curlx_tvnow/Curl_now
+
+- INTERNALS: remove curlx_tv* functions no longer provided
+
+- [Dmitri Tikhonov brought this change]
+
+  timeval: use mach time on MacOS
+  
+  If clock_gettime() is not supported, use mach_absolute_time() on MacOS.
+  
+  closes #2033
+
+monnerat (29 Oct 2017)
+- [Patrick Monnerat brought this change]
+
+  cli tool: improve ";type=" handling in -F option arguments
+
+- [Patrick Monnerat brought this change]
+
+  cli tool: in -F option arg, comma is a delimiter for files only
+  
+  Also upgrade test 1133 to cover this case and clarify man page about
+  form data quoting.
+  
+  Bug: https://github.com/curl/curl/issues/2022
+  Reported-By: omau on github
+
+Daniel Stenberg (29 Oct 2017)
+- timeleft: made two more users of Curl_timeleft use timediff_t
+
+Jakub Zakrzewski (28 Oct 2017)
+- cmake: Export libcurl and curl targets to use by other cmake projects
+  
+  The config files define curl and libcurl targets as imported targets
+  CURL::curl and CURL::libcurl. For backward compatibility with CMake-
+  provided find-module the CURL_INCLUDE_DIRS and CURL_LIBRARIES are
+  also set.
+  
+  Closes #1879
+
+Daniel Stenberg (28 Oct 2017)
+- RELEASE-NOTES: synced with f20cbac97
+
+- [Florin brought this change]
+
+  auth: Added test cases for RFC7616
+  
+  Updated docs to include support for RFC7616
+  
+  Signed-off-by: Florin <petriuc.florin@gmail.com>
+  
+  Closes #1934
+
+- [Florin brought this change]
+
+  auth: add support for RFC7616 - HTTP Digest access authentication
+  
+  Signed-off-by: Florin <petriuc.florin@gmail.com>
+
+- [Daniel Bankhead brought this change]
+
+  TODO: support multiple Content-Encodings
+  
+  Closes #2002
+
+- ROADMAP: cleanup
+  
+  Removed done stuff. Removed entries no longer considered for the near
+  term.
+
+- [Magicansk brought this change]
+
+  ROADMAP.md: spelling fixes
+  
+  Closes #2028
+
+- Curl_timeleft: change return type to timediff_t
+  
+  returning 'time_t' is problematic when that type is unsigned and we
+  return values less than zero to signal "already expired", used in
+  several places in the code.
+  
+  Closes #2021
+
+- appveyor: add a win32 build
+
+- setopt: fix CURLOPT_SSH_AUTH_TYPES option read
+  
+  Regression since f121575c0b5f
+  
+  Reported-by: Rob Cotrone
+
+Marcel Raad (27 Oct 2017)
+- resolvers: only include anything if needed
+  
+  This avoids warnings about unused stuff.
+  
+  Closes https://github.com/curl/curl/pull/2023
+
+Daniel Stenberg (27 Oct 2017)
+- HELP-US: rename the subtitle too since the label is changed
+  
+  "PR-welcome" was the former name.
+
+- curl_setup.h: oops, shorten the too long line
+
+- [Martin Storsjo brought this change]
+
+  curl_setup: Improve detection of CURL_WINDOWS_APP
+  
+  If WINAPI_FAMILY is defined, it should be safe to try to include
+  winapifamily.h to check what the define evaluates to.
+  
+  This should fix detection of CURL_WINDOWS_APP if building with
+  _WIN32_WINNT set to 0x0600.
+  
+  Closes #2025
+
+Jay Satiro (26 Oct 2017)
+- transfer: Fix chunked-encoding upload bug
+  
+  - When uploading via chunked-encoding don't compare file size to bytes
+    sent to determine whether the upload has finished.
+  
+  Chunked-encoding adds its own overhead which why the bytes sent is not
+  equal to the file size. Prior to this change if a file was uploaded in
+  chunked-encoding and its size was known it was possible that the upload
+  could end prematurely without sending the final few chunks. That would
+  result in a server hang waiting for the remaining data, likely followed
+  by a disconnect.
+  
+  The scope of this bug is limited to some arbitrary file sizes which have
+  not been determined. One size that triggers the bug is 475020.
+  
+  Bug: https://github.com/curl/curl/issues/2001
+  Reported-by: moohoorama@users.noreply.github.com
+  
+  Closes https://github.com/curl/curl/pull/2010
+
+Daniel Stenberg (26 Oct 2017)
+- timeval: make timediff_t also work on 32bit windows
+  
+  ... by using curl_off_t for the typedef if time_t is larger than 4
+  bytes.
+  
+  Reported-by: Gisle Vanem
+  Bug: https://github.com/curl/curl/commit/b9d25f9a6b3ca791385b80a6a3c3fa5ae113e1e0#co
+  mmitcomment-25205058
+  Closes #2019
+
+- curl_fnmatch: return error on illegal wildcard pattern
+  
+  ... instead of doing an infinite loop!
+  
+  Added test 1162 to verify.
+  
+  Reported-by: Max Dymond
+  Fixes #2015
+  Closes #2017
+
+- [Max Dymond brought this change]
+
+  wildcards: don't use with non-supported protocols
+  
+  Fixes timeouts in the fuzzing tests for non-FTP protocols.
+  
+  Closes #2016
+
+- [Max Dymond brought this change]
+
+  multi: allow table handle sizes to be overridden
+  
+  Allow users to specify their own hash define for
+  CURL_CONNECTION_HASH_SIZE so that both values can be overridden.
+  
+  Closes #1982
+
+- time: rename Curl_tvnow to Curl_now
+  
+  ... since the 'tv' stood for timeval and this function does not return a
+  timeval struct anymore.
+  
+  Also, cleaned up the Curl_timediff*() functions to avoid typecasts and
+  clean up the descriptive comments.
+  
+  Closes #2011
+
+- ftplistparser: follow-up cleanup to remove PL_ERROR()
+
+- [Max Dymond brought this change]
+
+  ftplistparser: free off temporary memory always
+  
+  When using the FTP list parser, ensure that the memory that's
+  allocated is always freed.
+  
+  Detected by OSS-fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3682
+  Closes #2013
+
+- timediff: return timediff_t from the time diff functions
+  
+  ... to cater for systems with unsigned time_t variables.
+  
+  - Renamed the functions to curlx_timediff and Curl_timediff_us.
+  
+  - Added overflow protection for both of them in either direction for
+    both 32 bit and 64 bit time_ts
+  
+  - Reprefixed the curlx_time functions to use Curl_*
+  
+  Reported-by: Peter Piekarski
+  Fixes #2004
+  Closes #2005
+
+- [Paul Howarth brought this change]
+
+  libtest: Add required test libraries for lib1552 and lib1553
+  
+  They use $(TESTUTIL) and thus should use $(TESTUTIL_LIBS) too.
+  
+  This fixes build failures on Fedora 13.
+  
+  Closes #2006
+
+- [Alessandro Ghedini brought this change]
+
+  libcurl-tutorial.3: fix typo
+  
+  closes #2008
+
+Alessandro Ghedini (23 Oct 2017)
+- curl_mime_filedata.3: fix typos
+
+Daniel Stenberg (23 Oct 2017)
+- RELEASE-NOTES: clean slate towards 7.57.0
+
+- [Max Dymond brought this change]
+
+  travis: exit if any steps fail
+  
+  We don't expect any steps to fail in travis. Exit the script if they do.
+  
+  Closes #1966
+
+Version 7.56.1 (23 Oct 2017)
+
+Daniel Stenberg (23 Oct 2017)
+- RELEASE-NOTES: 7.56.1
+
+- THANKS: update at 7.56.1 release time
+
+- [Jon DeVree brought this change]
+
+  mk-ca-bundle: Remove URL for aurora
+  
+  Aurora is no longer used by Mozilla
+  https://hacks.mozilla.org/2017/04/simplifying-firefox-release-channels/
+
+- [Jon DeVree brought this change]
+
+  mk-ca-bundle: Fix URL for NSS
+  
+  The 'tip' is the most recent branch committed to, this should be
+  'default' like the URLs for the browser are.
+  
+  Closes #1998
+
+- imap: if a FETCH response has no size, don't call write callback
+  
+  CVE-2017-1000257
+  
+  Reported-by: Brian Carpenter and 0xd34db347
+  Also detected by OSS-Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3586
+
+- ftp: reject illegal IP/port in PASV 227 response
+  
+  ... by using range checks. Among other things, this avoids an undefined
+  behavior for a left shift that could happen on negative or very large
+  values.
+  
+  Closes #1997
+  
+  Detected by OSS-fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3694
+
+Patrick Monnerat (20 Oct 2017)
+- test653: check reuse of easy handle after mime data change
+  
+  See issue #1999
+
+- mime: do not reuse previously computed multipart size
+  
+  The contents might have changed: size must be recomputed.
+  
+  Reported-by: moteus on github
+  Fixes #1999
+
+- test308: disable if MultiSSL feature enabled
+  
+  Even if OpenSSL is enabled, it might not be the default backend when
+  multi-ssl is enabled, causing the test to fail.
+
+- runtests: support MultiSSL client feature
+
+- vtls: change struct Curl_ssl `close' field name to `close_one'.
+  
+  On OS/400, `close' is an ASCII system macro that corrupts the code if
+  not used in a context not targetting the close() system API.
+
+- os400: add missing symbols in config file.
+  
+  Also adjust makefile to renamed files and warn about installation dirs mix-up.
+
+- test652: curl_mime_data + base64 encoder with large contents
+
+- mime: limit bas64-encoded lines length to 76 characters
+
+Daniel Stenberg (16 Oct 2017)
+- RELEASE-NOTES: synced with f121575c0
+
+- setopt: range check most long options
+  
+  ... filter early instead of risking "funny values" having to be dealt
+  with elsewhere.
+
+- setopt: avoid integer overflows when setting millsecond values
+  
+  ... that are multiplied by 1000 when stored.
+  
+  For 32 bit long systems, the max value accepted (2147483 seconds) is >
+  596 hours which is unlikely to ever be set by a legitimate application -
+  and previously it didn't work either, it just caused undefined behavior.
+  
+  Also updated the man pages for these timeout options to mention the
+  return code.
+  
+  Closes #1938
+
+Viktor Szakats (15 Oct 2017)
+- makefile.m32: allow to override gcc, ar and ranlib
+  
+  Allow to ovverride certain build tools, making it possible to
+  use LLVM/Clang to build curl. The default behavior is unchanged.
+  To build with clang (as offered by MSYS2), these settings can
+  be used:
+  
+  CURL_CC=clang
+  CURL_AR=llvm-ar
+  CURL_RANLIB=llvm-ranlib
+  
+  Closes https://github.com/curl/curl/pull/1993
+
+- ldap: silence clang warning
+  
+  Use memset() to initialize a structure to avoid LLVM/Clang warning:
+  ldap.c:193:39: warning: missing field 'UserLength' initializer [-Wmissing-field-initializers]
+  
+  Closes https://github.com/curl/curl/pull/1992
+
+Daniel Stenberg (14 Oct 2017)
+- runtests: use valgrind for torture as well
+  
+  NOTE: it makes them terribly slow. I recommend only using valgrind for
+  specific torture tests or using lots of patience.
+
+- memdebug: trace send, recv and socket
+  
+  ... to allow them to be included in torture tests too.
+  
+  closes #1980
+
+- configure: remove the C++ compiler check
+  
+  ... we used it only for the fuzzer, which we now have in a separate git
+  repo.
+  
+  Closes #1990
+
+Patrick Monnerat (13 Oct 2017)
+- mime: do not call failf() if easy handle is NULL.
+
+Daniel Stenberg (13 Oct 2017)
+- test651: curl_formadd with huge COPYCONTENTS
+
+- mime: fix the content reader to handle >16K data properly
+  
+  Reported-by: Jeroen Ooms
+  Closes #1988
+
+Patrick Monnerat (12 Oct 2017)
+- mime: keep "text/plain" content type if user-specified.
+  
+  Include test cases in 554, 587, 650.
+  
+  Fixes https://github.com/curl/curl/issues/1986
+
+- cli tool: use file2memory() to buffer stdin in -F option.
+  
+  Closes PR https://github.com/curl/curl/pull/1985
+
+- cli tool: reimplement stdin buffering in -F option.
+  
+  If stdin is not a regular file, its content is memory-buffered to enable
+  a possible data "rewind".
+  In all cases, stdin data size is determined before real use to avoid
+  having an unknown part's size.
+  
+  --libcurl generated code is left as an unbuffered stdin fread/fseek callback
+  part with unknown data size.
+  
+  Buffering is not supported in deprecated curl_formadd() API.
+
+Daniel Stenberg (12 Oct 2017)
+- winbuild/BUILD.WINDOWS.txt: mention WITH_NGHTTP2
+
+- HELP-US: the label "PR-welcome" is now renamed to "help wanted"
+  
+  following the new github "standard"
+
+- RELEASE-NOTES: synced with 5505df7d2
+
+Jay Satiro (11 Oct 2017)
+- [Artak Galoyan brought this change]
+
+  url: Update current connection SSL verify params in setopt
+  
+  Now VERIFYHOST, VERIFYPEER and VERIFYSTATUS options change during active
+  connection updates the current connection's (i.e.'connectdata'
+  structure) appropriate ssl_config (and ssl_proxy_config) structures
+  variables, making these options effective for ongoing connection.
+  
+  This functionality was available before and was broken by the
+  following change:
+  "proxy: Support HTTPS proxy and SOCKS+HTTP(s)"
+  CommitId: cb4e2be7c6d42ca0780f8e0a747cecf9ba45f151.
+  
+  Bug: https://github.com/curl/curl/issues/1941
+  
+  Closes https://github.com/curl/curl/pull/1951
+
+Daniel Stenberg (11 Oct 2017)
+- [David Benjamin brought this change]
+
+  openssl: don't use old BORINGSSL_YYYYMM macros
+  
+  Those were temporary things we'd add and remove for our own convenience
+  long ago. The last few stayed around for too long as an oversight but
+  have since been removed. These days we have a running
+  BORINGSSL_API_VERSION counter which is bumped when we find it
+  convenient, but 2015-11-19 was quite some time ago, so just check
+  OPENSSL_IS_BORINGSSL.
+  
+  Closes #1979
+
+- test950; verify SMTP with custom request
+
+- ftpserver: support case insensitive commands
+
+- smtp_done: free data before returning (on send failure)
+  
+  ... as otherwise it could leak that memory.
+  
+  Detected by OSS-fuzz:
+  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3600
+  
+  Assisted-by: Max Dymond
+  Closes #1977
+
+- FTP: URL decode path for dir listing in nocwd mode
+  
+  Reported-by: Zenju on github
+  
+  Test 244 added to verify
+  Fixes #1974
+  Closes #1976
+
+- test298: verify --ftp-method nowcwd with URL encoded path
+  
+  Ref: #1974
+
+- CURLOPT_XFERINFODATA.3: fix duplicate see also
+
+- CURLOPT_NOPROGRESS.3: also refer to xferinfofunction
+
+- FAQ: s/CURLOPT_PROGRESSFUNCTION/CURLOPT_XFERINFOFUNCTION
+
+- openssl: enable PKCS12 support for !BoringSSL
+  
+  Enable PKCS12 for all non-boringssl builds without relying on configure
+  or cmake checks.
+  
+  Bug: https://curl.haxx.se/mail/lib-2017-10/0007.html
+  Reported-by: Christian Schmitz
+  Closes #1948
+
+- [Kristiyan Tsaklev brought this change]
+
+  curl: don't pass semicolons when parsing Content-Disposition
+  
+  Test 1422 updated to verify.
+  
+  Closes #1964
+
+Patrick Monnerat (9 Oct 2017)
+- mime: properly unbind mime structure in curl_mime_free().
+  
+  This allows freeing a mime structure bound to the easy handle before
+  curl_easy_cleanup().
+  
+  Fixes #1970.
+
+Daniel Stenberg (9 Oct 2017)
+- RTSP: avoid integer overflow on funny RTSP response
+  
+  ... like a very large non-existing RTSP version number.
+  
+  Added test 577 to verify.
+  
+  Detected by OSS-fuzz.
+  Closes #1969
+
+Patrick Monnerat (8 Oct 2017)
+- ftpserver: properly reset $ftptargetdir.
+
+- test643: verify curl_mime_subparts() rejects cyclic additions.
+
+- mime: refuse to add subparts to one of their own descendants.
+  
+  Reported-by: Alexey Melnichuk
+  Fixes #1962
+
+- mime: avoid resetting a part's encoder when part's contents change.
+
+- mime: improve unbinding top multipart from easy handle.
+  
+  Also avoid dangling pointers in referencing parts.
+
+Daniel Stenberg (8 Oct 2017)
+- RELEASE-NOTES: synced with a4c1c75da30af1
+
+- curlver.h: next expected release is 7.57.0
+
+Patrick Monnerat (8 Oct 2017)
+- mime: be tolerant about setting twice the same header list in a part.
+
+- docs: clarify form/mime usage of non-regular data files.
+
+Daniel Stenberg (8 Oct 2017)
+- Revert "multi_done: wait for name resolve to finish if still ongoing"
+  
+  This reverts commit f3e03f6c0ac52a1bf396e03f7d7e9b5b3b7165fe.
+  
+  Caused memory leaks in the fuzzer, needs to be done differently.
+  
+  Disable test 1553 for now too, as it causes memory leaks without this
+  commit!
+
+- remove_handle: call multi_done() first, then clear dns cache pointer
+  
+  Closes #1960
+
+- multi_done: wait for name resolve to finish if still ongoing
+  
+  ... as we must clean up memory.
+
+- pingpong: return error when trying to send without connection
+  
+  When imap_done() got called before a connection is setup, it would try
+  to "finish up" and dereffed a NULL pointer.
+  
+  Test case 1553 managed to reproduce. I had to actually use a host name
+  to try to resolve to slow it down, as using the normal local server IP
+  will make libcurl get a connection in the first curl_multi_perform()
+  loop and then the bug doesn't trigger.
+  
+  Fixes #1953
+  Assisted-by: Max Dymond
+
+Dan Fandrich (6 Oct 2017)
+- tests: added flaky keyword to tests 587 and 644
+  
+  These are around 5% flaky in my Linux x86 autobuilds.
+
+Marcel Raad (6 Oct 2017)
+- vtls: fix warnings with --disable-crypto-auth
+  
+  When CURL_DISABLE_CRYPTO_AUTH is defined, Curl_none_md5sum's parameters
+  are not used.
+
+Daniel Stenberg (6 Oct 2017)
+- multi_cleanup: call DONE on handles that never got that
+  
+  ... fixes a memory leak with at least IMAP when remove_handle is never
+  called and the transfer is abruptly just abandoned early.
+  
+  Test 1552 added to verify
+  
+  Detected by OSS-fuzz
+  Assisted-by: Max Dymond
+  Closes #1954
+
+- [Benbuck Nason brought this change]
+
+  strtoofft: Remove extraneous null check
+  
+  Fixes #1950: curlx_strtoofft() doesn't fully protect against null 'str'
+  argument.
+  
+  Closes #1952
+
+- openssl: fix build without HAVE_OPAQUE_EVP_PKEY
+  
+  Reported-by: Javier Sixto
+  Fixes #1955
+  Closes #1956
+
+Viktor Szakats (6 Oct 2017)
+- lib/config-win32.h: let SMB/SMBS be enabled with OpenSSL/NSS
+  
+  The source code is now prepared to handle the case when both
+  Win32 Crypto and OpenSSL/NSS crypto backends are enabled
+  at the same time, making it now possible to enable `USE_WIN32_CRYPTO`
+  whenever the targeted Windows version supports it. Since this
+  matches the minimum Windows version supported by curl
+  (Windows 2000), enable it unconditionally for the Win32 platform.
+  
+  This in turn enables SMB (and SMBS) protocol support whenever
+  Win32 Crypto is available, regardless of what other crypto backends
+  are enabled.
+  
+  Ref: https://github.com/curl/curl/pull/1840#issuecomment-325682052
+  
+  Closes https://github.com/curl/curl/pull/1943
+
+Daniel Stenberg (5 Oct 2017)
+- build: fix --disable-crypto-auth
+  
+  Reported-by: Wyatt O'Day
+  Fixes #1945
+  Closes #1947
+
+Jay Satiro (5 Oct 2017)
+- [Nick Zitzmann brought this change]
+
+  darwinssl: add support for TLSv1.3
+  
+  Closes https://github.com/curl/curl/pull/1794
+
+Daniel Stenberg (4 Oct 2017)
+- [Felix Kaiser brought this change]
+
+  docs: fix typo in curl_mime_data_cb man page
+  
+  Closes #1946
+
+Viktor Szakats (4 Oct 2017)
+- lib/Makefile.m32: allow customizing dll suffixes
+  
+  - New `CURL_DLL_SUFFIX` envvar will add a suffix to the generated
+    libcurl dll name. Useful to add `-x64` to 64-bit builds so that
+    it can live in the same directory as the 32-bit one. By default
+    this is empty.
+  
+  - New `CURL_DLL_A_SUFFIX` envvar to customize the suffix of the
+    generated import library (implib) for libcurl .dll. It defaults
+    to `dll`, and it's useful to modify that to `.dll` to have the
+    standard naming scheme for mingw-built .dlls, i.e. `libcurl.dll.a`.
+  
+  Closes https://github.com/curl/curl/pull/1942
+
+Daniel Stenberg (4 Oct 2017)
+- [Max Dymond brought this change]
+
+  fuzzer: move to using external curl-fuzzer
+  
+  Use the external curl-fuzzer repository for fuzzing.
+  
+  Closes #1923
+
+- failf: skip the sprintf() if there are no consumers
+  
+  Closes #1936
+
+- ftp: UBsan fixup 'pointer index expression overflowed'
+  
+  Closes #1939
+
+- RELEASE-PROCEDURE: update the release schedule
+
+Version 7.56.0 (4 Oct 2017)
+
+Daniel Stenberg (4 Oct 2017)
+- RELEASE-NOTES: curl 7.56.0
+
+- THANKS: added new 7.56.0 contributors
+
+Jay Satiro (4 Oct 2017)
+- build-openssl.bat: Warn OpenSSL 1.1.0 not yet supported
+  
+  Ref: https://github.com/curl/curl/issues/1002
+
+Michael Kaufmann (3 Oct 2017)
+- idn: fix source code comment
+
+- vtls: compare and clone ssl configs properly
+  
+  Compare these settings in Curl_ssl_config_matches():
+  - verifystatus (CURLOPT_SSL_VERIFYSTATUS)
+  - random_file (CURLOPT_RANDOM_FILE)
+  - egdsocket (CURLOPT_EGDSOCKET)
+  
+  Also copy the setting "verifystatus" in Curl_clone_primary_ssl_config(),
+  and copy the setting "sessionid" unconditionally.
+  
+  This means that reusing connections that are secured with a client
+  certificate is now possible, and the statement "TLS session resumption
+  is disabled when a client certificate is used" in the old advisory at
+  https://curl.haxx.se/docs/adv_20170419.html is obsolete.
+  
+  Reviewed-by: Daniel Stenberg
+  
+  Closes #1917
+
+- proxy: read the "no_proxy" variable only if necessary
+  
+  Reviewed-by: Daniel Stenberg
+  
+  Closes #1919
+
+Patrick Monnerat (3 Oct 2017)
+- libcurl-tutorial: add casts in example to avoid compilation warnings.
+
+Daniel Stenberg (3 Oct 2017)
+- examples: bring back curl_formadd-using examples
+  
+  ... now with a -formadd suffix. While the new mime API is introduced in
+  7.56.0 we must acknowledge that lots of users can't upgrade their curl
+  versions immediately.
+
+- test1153: verify quoted double-qoutes in PWD response
+
+- FTP: zero terminate the entry path even on bad input
+  
+  ... a single double quote could leave the entry path buffer without a zero
+  terminating byte. CVE-2017-1000254
+  
+  Test 1152 added to verify.
+  
+  Reported-by: Max Dymond
+  Bug: https://curl.haxx.se/docs/adv_20171004.html
+
+Jay Satiro (2 Oct 2017)
+- [Sergei Nikulov brought this change]
+
+  cmake: disable tests and man generation if perl/nroff not found
+  
+  Fixes https://github.com/curl/curl/issues/1500
+  Reported-by: Jay Satiro
+  
+  Fixes https://github.com/curl/curl/pull/1662
+  Assisted-by: Tom Seddon
+  Assisted-by: dpull@users.noreply.github.com
+  Assisted-by: elelel@users.noreply.github.com
+  
+  Closes https://github.com/curl/curl/pull/1924
+
+Patrick Monnerat (2 Oct 2017)
+- libcurl-tutorial: fix two typos.
+
+- TODO: remove deprecated form API items.
+
+- libcurl-tutorial: describe MIME API and deprecate form API.
+  
+  Include a guide to form/mime API conversion.
+
+Daniel Stenberg (30 Sep 2017)
+- cookie: fix memory leak if path was set twice in header
+  
+  ... this will let the second occurance override the first.
+  
+  Added test 1161 to verify.
+  
+  Reported-by: Max Dymond
+  Fixes #1932
+  Closes #1933
+
+Dan Fandrich (30 Sep 2017)
+- test650: Use variable replacement to set the host address and port
+  
+  Otherwise, the test fails when the -b test option is used to set a
+  different test port range.
+
+- Set and use more necessary options when some protocols are disabled
+  
+  When curl and libcurl are built with some protocols disabled, they stop
+  setting and receiving some options that don't make sense with those
+  protocols.  In particular, when HTTP is disabled many options aren't set
+  that are used only by HTTP.  However, some options that appear to be
+  HTTP-only are actually used by other protocols as well (some despite
+  having HTTP in the name) and should be set, but weren't. This change now
+  causes some of these options to be set and used for more (or for all)
+  protocols. In particular, this fixes tests 646 through 649 in an
+  HTTP-disabled build, which use the MIME API in the mail protocols.
+
+Daniel Stenberg (29 Sep 2017)
+- test1160: verifies cookie leak for large cookies
+  
+  The fix done in 20ea22ff735
+
+- cookie: fix memory leak on oversized rejection
+  
+  Regression brought by 2bc230de63b
+  
+  Detected by OSS-fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3513
+  Assisted-by: Max Dymond
+  
+  Closes #1930
+
+- [Anders Bakken brought this change]
+
+  connect: fix race condition with happy eyeballs timeout
+  
+  The timer should be started after conn->connecttime is set. Otherwise
+  the timer could expire without this condition being true:
+  
+      /* should we try another protocol family? */
+      if(i == 0 && conn->tempaddr[1] == NULL &&
+        curlx_tvdiff(now, conn->connecttime) >= HAPPY_EYEBALLS_TIMEOUT) {
+  
+  Ref: #1928
+
+Michael Kaufmann (28 Sep 2017)
+- docs: link CURLOPT_CONNECTTIMEOUT and CURLOPT_CONNECTTIMEOUT_MS
+  
+  Closes #1922
+
+- docs: clarify the use of environment variables for proxy
+  
+  Closes #1921
+
+- http: add custom empty headers to repeated requests
+  
+  Closes #1920
+
+- reuse_conn: don't copy flags that are known to be equal
+  
+  A connection can only be reused if the flags "conn_to_host" and
+  "conn_to_port" match. Therefore it is not necessary to copy these flags
+  in reuse_conn().
+  
+  Closes #1918
+
+Daniel Stenberg (27 Sep 2017)
+- curl.h: include <sys/select.h> on cygwin too
+  
+  When building with -std=c++14 on cygwin, this header won't be
+  automatically included as it otherwise is.
+  
+  The <sys/select.h> include decision should ideally be reversed and be
+  avoided where that header file doesn't exist.
+  
+  Reported-by: Ian Fette
+  Fixes #1925
+
+- RELEASE-NOTES: synced with d8ab5dc50
+
+Michael Kaufmann (24 Sep 2017)
+- tests: adjust .gitignore for new tests
+
+Jay Satiro (23 Sep 2017)
+- ntlm: move NTLM_NEEDS_NSS_INIT define into core NTLM header
+  
+  .. and include the core NTLM header in all NTLM-related source files.
+  
+  Follow up to 6f86022. Since then http_ntlm checks NTLM_NEEDS_NSS_INIT
+  but did not include vtls.h where it was defined.
+  
+  Closes https://github.com/curl/curl/pull/1911
+
+Daniel Stenberg (23 Sep 2017)
+- file_range: avoid integer overflow when figuring out byte range
+  
+  When trying to bump the value with one and the value is already at max,
+  it causes an integer overflow.
+  
+  Closes #1908
+  Detected by oss-fuzz:
+  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3465
+  
+  Assisted-by: Max Dymond
+
+Michael Kaufmann (23 Sep 2017)
+- tests: fix a compiler warning in test 643
+
+Jay Satiro (23 Sep 2017)
+- symbols-in-versions: fix CURLSSLSET_NO_BACKENDS entry
+  
+  - Use spaces instead of tabs as the delimiter.
+  
+  Follow up to 7c52b12 which added the entry. The entry had used tabs but
+  the symbol-scan parser doesn't recognize tabs and would fail the symbol.
+
+Viktor Szakats (22 Sep 2017)
+- metalink: fix NSS issue in MultiSSL builds
+  
+  In MultiSSL mode (i.e. when more than one SSL backend is compiled
+  in), we cannot use the compile time flag `USE_NSS` as indicator that
+  the NSS backend is in use. As far as Metalink is concerned, the SSL
+  backend is only used for MD5, SHA-1 and SHA-256 calculations,
+  therefore one of the available SSL backends is selected at compile
+  time, in a strict order of preference.
+  
+  Let's introduce a new `HAVE_NSS_CONTEXT` constant that can be used
+  to determine whether the SSL backend used for Metalink is the NSS
+  backend, and use that to guard the code that wants to de-initialize
+  the NSS-specific data structure.
+  
+  Ref: https://github.com/curl/curl/pull/1848
+
+- ntlm: use strict order for SSL backend #if branches
+  
+  With the recently introduced MultiSSL support multiple SSL backends
+  can be compiled into cURL That means that now the order of the SSL
+  
+  One option would be to use the same SSL backend as was configured
+  via `curl_global_sslset()`, however, NTLMv2 support would appear
+  to be available only with some SSL backends. For example, when
+  eb88d778e (ntlm: Use Windows Crypt API, 2014-12-02) introduced
+  support for NTLMv1 using Windows' Crypt API, it specifically did
+  *not* introduce NTLMv2 support using Crypt API at the same time.
+  
+  So let's select one specific SSL backend for NTLM support when
+  compiled with multiple SSL backends, using a priority order such
+  that we support NTLMv2 even if only one compiled-in SSL backend can
+  be used for that.
+  
+  Ref: https://github.com/curl/curl/pull/1848
+
+Daniel Stenberg (22 Sep 2017)
+- symbols-in-versions: add CURLSSLSET_NO_BACKENDS
+  
+  ...fixup from b8e0fe19ec
+
+- imap: quote atoms properly when escaping characters
+  
+  Updates test 800 to verify
+  
+  Fixes #1902
+  Closes #1903
+
+- tests: make the imap server not verify user+password
+  
+  ... as the test cases themselves do that and it makes it easier to add
+  crazy test cases.
+  
+  Test 800 updated to use user name + password that need quoting.
+  
+  Test 856 updated to trigger an auth fail differently.
+  
+  Ref: #1902
+
+- vtls: provide curl_global_sslset() even in non-SSL builds
+  
+  ... it just returns error:
+  
+  Bug: https://github.com/curl/curl/commit/1328f69d53f2f2e937696ea954c480412b018451#commitcomment-24470367
+  Reported-by: Marcel Raad
+  
+  Closes #1906
+
+Patrick Monnerat (22 Sep 2017)
+- form/mime: field names are not allowed to contain zero-valued bytes.
+  
+  Also suppress length argument of curl_mime_name() (names are always
+  zero-terminated).
+
+Daniel Stenberg (21 Sep 2017)
+- [Dirk Feytons brought this change]
+
+  openssl: only verify RSA private key if supported
+  
+  In some cases the RSA key does not support verifying it because it's
+  located on a smart card, an engine wants to hide it, ...
+  Check the flags on the key before trying to verify it.
+  OpenSSL does the same thing internally; see ssl/ssl_rsa.c
+  
+  Closes #1904
+
+Marcel Raad (21 Sep 2017)
+- examples/post-callback: use long for CURLOPT_POSTFIELDSIZE
+  
+  Otherwise, typecheck-gcc.h warns on MinGW-w64.
+
+Patrick Monnerat (20 Sep 2017)
+- mime: rephrase the multipart output state machine (#1898) ...
+  
+  ... in hope coverity will like it much.
+
+- mime: fix an explicit null dereference (#1899)
+
+Daniel Stenberg (20 Sep 2017)
+- curl: check fseek() return code and bail on error
+  
+  Detected by coverity. CID 1418137.
+
+- smtp: fix memory leak in OOM
+  
+  Regression since ce0881edee
+  
+  Coverity CID 1418139 and CID 1418136 found it, but it was also seen in
+  torture testing.
+
+- RELEASE-NOTES: synced with 5fe85587c
+
+- [Pavel P brought this change]
+
+  cookies: use lock when using CURLINFO_COOKIELIST
+  
+  Closes #1896
+
+- [Max Dymond brought this change]
+
+  ossfuzz: changes before merging the generated corpora
+  
+  Before merging in the oss-fuzz corpora from Google, there are some changes
+  to the fuzzer.
+  - Add a read corpus script, to display corpus files nicely.
+  - Change the behaviour of the fuzzer so that TLV parse failures all now
+    go down the same execution paths, which should reduce the size of the
+    corpora.
+  - Make unknown TLVs a failure to parse, which should decrease the size
+    of the corpora as well.
+  
+  Closes #1881
+
+- mime:escape_string minor clarification change
+  
+  ... as it also removes a warning with old gcc versions.
+  
+  Bug: https://curl.haxx.se/mail/lib-2017-09/0049.html
+  Reported-by: Ben Greear
+
+- [Max Dymond brought this change]
+
+  ossfuzz: don't write out to stdout
+  
+  Don't make the fuzzer write out to stdout - instead write some of the
+  contents to a memory block so we exercise the data output code but
+  quietly.
+  
+  Closes #1885
+
+- cookies: reject oversized cookies
+  
+  ... instead of truncating them.
+  
+  There's no fixed limit for acceptable cookie names in RFC 6265, but the
+  entire cookie is said to be less than 4096 bytes (section 6.1). This is
+  also what browsers seem to implement.
+  
+  We now allow max 5000 bytes cookie header. Max 4095 bytes length per
+  cookie name and value. Name + value together may not exceed 4096 bytes.
+  
+  Added test 1151 to verify
+  
+  Bug: https://curl.haxx.se/mail/lib-2017-09/0062.html
+  Reported-by: Kevin Smith
+  
+  Closes #1894
+
+- travis: on mac, don't install openssl or libidn
+  
+  - openssl is already installed and causes warnings when trying to
+    install again
+  
+  - libidn isn't used these days, and homebrew doesn't seem to have a
+    libidn2 package to replace with easily
+  
+  Closes #1895
+
+- curl: make str2udouble not return values on error
+  
+  ... previously it would store a return value even when it returned
+  error, which could make the value get used anyway!
+  
+  Reported-by: Brian Carpenter
+  Closes #1893
+
+Jay Satiro (18 Sep 2017)
+- socks: fix incorrect port number in SOCKS4 error message
+  
+  Prior to this change it appears the SOCKS5 port parsing was erroneously
+  used for the SOCKS4 error message, and as a result an incorrect port
+  would be shown in the error message.
+  
+  Bug: https://github.com/curl/curl/issues/1892
+  Reported-by: Jackarain@users.noreply.github.com
+
+- [Marc Aldorasi brought this change]
+
+  schannel: Support partial send for when data is too large
+  
+  Schannel can only encrypt a certain amount of data at once.  Instead of
+  failing when too much data is to be sent at once, send as much data as
+  we can and let the caller send the remaining data by calling send again.
+  
+  Bug: https://curl.haxx.se/mail/lib-2014-07/0033.html
+  
+  Closes https://github.com/curl/curl/pull/1890
+
+- [David Benjamin brought this change]
+
+  openssl: add missing includes
+  
+  lib/vtls/openssl.c uses OpenSSL APIs from BUF_MEM and BIO APIs. Include
+  their headers directly rather than relying on other OpenSSL headers
+  including things.
+  
+  Closes https://github.com/curl/curl/pull/1891
+
+Daniel Stenberg (15 Sep 2017)
+- conversions: fix several compiler warnings
+
+- server/getpart: provide dummy function to build conversion enabled
+
+- non-ascii: use iconv() with 'char **' argument
+  
+  Bug: https://curl.haxx.se/mail/lib-2017-09/0031.html
+
+- escape.c: error: pointer targets differ in signedness
+
+- docs: clarify the CURLOPT_INTERLEAVE* options behavior
+
+- [Max Dymond brought this change]
+
+  rtsp: Segfault in rtsp.c when using WRITEDATA
+  
+  If the INTERLEAVEFUNCTION is defined, then use that plus the
+  INTERLEAVEDATA information when writing RTP. Otherwise, use
+  WRITEFUNCTION and WRITEDATA.
+  
+  Fixes #1880
+  Closes #1884
+
+Marcel Raad (15 Sep 2017)
+- [Isaac Boukris brought this change]
+
+  tests: enable gssapi in travis-ci linux build
+  
+  Closes https://github.com/curl/curl/pull/1687
+
+- [Isaac Boukris brought this change]
+
+  tests: add initial gssapi test using stub implementation
+  
+  The stub implementation is pre-loaded using LD_PRELOAD
+  and emulates common gssapi uses (only builds if curl is
+  initially built with gssapi support).
+  
+  The initial tests are currently disabled for debug builds
+  as LD_PRELOAD is not used then.
+  
+  Ref: https://github.com/curl/curl/pull/1687
+
+Daniel Stenberg (15 Sep 2017)
+- test1150: verify same host fetch using different ports over proxy
+  
+  Closes #1889
+
+- URL: on connection re-use, still pick the new remote port
+  
+  ... as when a proxy connection is being re-used, it can still get a
+  different remote port.
+  
+  Fixes #1887
+  Reported-by: Oli Kingshott
+
+- RELEASE-NOTES: synced with 87501e57f
+
+- code style: remove wrong uses of multiple spaces
+  
+  Closes #1878
+
+- checksrc: detect and warn for multiple spaces
+
+- code style: use space after semicolon
+
+- checksrc: verify space after semicolons
+
+- code style: use spaces around pluses
+
+- checksrc: detect and warn for lack of spaces next to plus signs
+
+- code style: use spaces around equals signs
+
+- checksrc: verify spaces around equals signs
+  
+  ... as the code style mandates.
+
+- Curl_checkheaders: make it available for IMAP and SMTP too
+  
+  ... not only HTTP uses this now.
+  
+  Closes #1875
+
+- travis: add build without HTTP/SMTP/IMAP
+
+Jay Satiro (10 Sep 2017)
+- mbedtls: enable CA path processing
+  
+  CA path processing was implemented when mbedtls.c was added to libcurl
+  in fe7590f, but it was never enabled.
+  
+  Bug: https://github.com/curl/curl/issues/1877
+  Reported-by: SBKarr@users.noreply.github.com
+
+Daniel Stenberg (8 Sep 2017)
+- rtsp: do not call fwrite() with NULL pointer FILE *
+  
+  If the default write callback is used and no destination has been set, a
+  NULL pointer would be passed to fwrite()'s 4th argument.
+  
+  OSS-fuzz bug https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3327
+  (not publicly open yet)
+  
+  Detected by OSS-fuzz
+  Closes #1874
+
+- configure: use -Wno-varargs on clang 3.9[.X] debug builds
+  
+  ... to avoid a clang bug
+
+- [Max Dymond brought this change]
+
+  ossfuzz: add some more handled CURL options
+  
+  Add support for HEADER, COOKIE, RANGE, CUSTOMREQUEST, MAIL_RECIPIENT,
+  MAIL_FROM and uploading data.
+
+- configure: check for C++ compiler after C, to make it non-fatal
+  
+  The tests for object file/executable file extensions are presumably only
+  done for the first of these macros in the configure file.
+  
+  Bug: https://github.com/curl/curl/pull/1851#issuecomment-327597515
+  Reported-by: Marcel Raad
+  Closes #1873
+
+Patrick Monnerat (7 Sep 2017)
+- form API: add new test 650.
+  
+  Now that the form API is deprecated and not used anymore in curl tool,
+  a lot of its features left untested. Test 650 attempts to check all these
+  features not tested elsewhere.
+
+Jay Satiro (7 Sep 2017)
+- configure: fix curl_off_t check's include order
+  
+  - Prepend srcdir include path instead of append.
+  
+  Prior to this change it was possible that during the check for the size
+  of curl_off_t the include path of a user's already installed curl could
+  come before the include path of the to-be-built curl, resulting in the
+  system.h of the former being incorrectly included for that check.
+  
+  Closes https://github.com/curl/curl/pull/1870
+
+Daniel Stenberg (7 Sep 2017)
+- [Jakub Zakrzewski brought this change]
+
+  KNOWN_BUGS: Remove CMake symbol hiding issue
+  
+  It has already been fixed in 6140dfc
+
+- http-proxy: when not doing CONNECT, that phase is done immediately
+  
+  `conn->connect_state` is NULL when doing a regular non-CONNECT request
+  over the proxy and should therefor be considered complete at once.
+  
+  Fixes #1853
+  Closes #1862
+  Reported-by: Lawrence Wagerfield
+
+- [Johannes Schindelin brought this change]
+
+  OpenSSL: fix yet another mistake while encapsulating SSL backend data
+  
+  Another mistake in my manual fixups of the largely mechanical
+  search-and-replace ("connssl->" -> "BACKEND->"), just like the previous
+  commit concerning HTTPS proxies (and hence not caught during my
+  earlier testing).
+  
+  Fixes #1855
+  Closes #1871
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  OpenSSL: fix erroneous SSL backend encapsulation
+  
+  In d65e6cc4f (vtls: prepare the SSL backends for encapsulated private
+  data, 2017-06-21), this developer prepared for a separation of the
+  private data of the SSL backends from the general connection data.
+  
+  This conversion was partially automated (search-and-replace) and
+  partially manual (e.g. proxy_ssl's backend data).
+  
+  Sadly, there was a crucial error in the manual part, where the wrong
+  handle was used: rather than connecting ssl[sockindex]' BIO to the
+  proxy_ssl[sockindex]', we reconnected proxy_ssl[sockindex]. The reason
+  was an incorrect location to paste "BACKEND->"... d'oh.
+  
+  Reported by Jay Satiro in https://github.com/curl/curl/issues/1855.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Jay Satiro brought this change]
+
+  vtls: fix memory corruption
+  
+  Ever since 70f1db321 (vtls: encapsulate SSL backend-specific data,
+  2017-07-28), the code handling HTTPS proxies was broken because the
+  pointer to the SSL backend data was not swapped between
+  conn->ssl[sockindex] and conn->proxy_ssl[sockindex] as intended, but
+  instead set to NULL (causing segmentation faults).
+  
+  [jes: provided the commit message, tested and verified the patch]
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- vtls: switch to CURL_SHA256_DIGEST_LENGTH define
+  
+  ... instead of the prefix-less version since WolfSSL 3.12 now uses an
+  enum with that name that causes build failures for us.
+  
+  Fixes #1865
+  Closes #1867
+  Reported-by: Gisle Vanem
+
+- travis: add c-ares enabled builds linux + osx
+  
+  Closes #1868
+
+- HISTORY: added some recent items
+
+Jay Satiro (6 Sep 2017)
+- SSL: fix unused parameter warnings
+
+Patrick Monnerat (6 Sep 2017)
+- mime: drop internal FILE * support.
+  
+  - The part kind MIMEKIND_FILE and associated code are suppressed.
+  - Seek data origin offset not used anymore: suppressed.
+  - MIMEKIND_NAMEDFILE renamed MIMEKIND_FILE; associated fields/functions
+    renamed accordingly.
+  - Curl_getformdata() processes stdin via a callback.
+
+Daniel Stenberg (6 Sep 2017)
+- configure: remove --enable-soname-bump and SONAME_BUMP
+  
+  Back in 2008, (and commit 3f3d6ebe665f3) we changed the logic in how we
+  determine the native type for `curl_off_t`. To really make sure we
+  didn't break ABI without bumping SONAME, we introduced logic that
+  attempted to detect that it would use a different size and thus not be
+  compatible. We also provided a manual switch that allowed users to tell
+  configure to bump SONAME by force.
+  
+  Today, we know of no one who ever got a SONAME bump auto-detected and we
+  don't know of anyone who's using the manual bump feature. The auto-
+  detection is also no longer working since we introduced defining
+  curl_off_t in system.h (7.55.0).
+  
+  Finally, this bumping logic is not present in the cmake build.
+  
+  Closes #1861
+
+Jay Satiro (6 Sep 2017)
+- [Gisle Vanem brought this change]
+
+  vtls: select ssl backend case-insensitive (follow-up)
+  
+  - Do a case-insensitive comparison of CURL_SSL_BACKEND env as well.
+  
+  - Change Curl_strcasecompare calls to strcasecompare
+    (maps to the former but shorter).
+  
+  Follow-up to c290b8f.
+  
+  Bug: https://github.com/curl/curl/commit/c290b8f#commitcomment-24094313
+  
+  Co-authored-by: Jay Satiro
+
+- openssl: Integrate Peter Wu's SSLKEYLOGFILE implementation
+  
+  This is an adaptation of 2 of Peter Wu's SSLKEYLOGFILE implementations.
+  
+  The first one, written for old OpenSSL versions:
+  https://git.lekensteyn.nl/peter/wireshark-notes/tree/src/sslkeylog.c
+  
+  The second one, written for BoringSSL and new OpenSSL versions:
+  https://github.com/curl/curl/pull/1346
+  
+  Note the first one is GPL licensed but the author gave permission to
+  waive that license for libcurl.
+  
+  As of right now this feature is disabled by default, and does not have
+  a configure option to enable it. To enable this feature define
+  ENABLE_SSLKEYLOGFILE when building libcurl and set environment
+  variable SSLKEYLOGFILE to a pathname that will receive the keys.
+  
+  And in Wireshark change your preferences to point to that key file:
+  Edit > Preferences > Protocols > SSL > Master-Secret
+  
+  Co-authored-by: Peter Wu
+  
+  Ref: https://github.com/curl/curl/pull/1030
+  Ref: https://github.com/curl/curl/pull/1346
+  
+  Closes https://github.com/curl/curl/pull/1866
+
+Patrick Monnerat (5 Sep 2017)
+- mime: fix a trivial warning.
+
+- mime: replace 'struct Curl_mimepart' by 'curl_mimepart' in encoder code.
+  
+  mime_state is now a typedef.
+
+- mime: implement encoders.
+  
+  curl_mime_encoder() is operational and documented.
+  curl tool -F option is extended with ";encoder=".
+  curl tool --libcurl option generates calls to curl_mime_encoder().
+  New encoder tests 648 & 649.
+  Test 1404 extended with an encoder specification.
+
+- runtests.pl: support attribute "nonewline" in part verify/upload.
+
+- [Daniel Stenberg brought this change]
+
+  fixup data/test1135
+
+- [Daniel Stenberg brought this change]
+
+  mime: unified to use the typedef'd mime structs everywhere
+  
+  ... and slightly edited to follow our code style better.
+
+- [Daniel Stenberg brought this change]
+
+  curl.h: use lower case curl_mime* as for all public symbols
+
+- [Daniel Stenberg brought this change]
+
+  docs/curl_mime_*.3: use correct variable types in examples
+
+Kamil Dudka (5 Sep 2017)
+- openssl: use OpenSSL's default ciphers by default
+  
+  Up2date versions of OpenSSL maintain the default reasonably secure
+  without breaking compatibility, so it is better not to override the
+  default by curl.  Suggested at https://bugzilla.redhat.com/1483972
+  
+  Closes #1846
+
+Viktor Szakats (5 Sep 2017)
+- examples/mime: minor example code fixes
+
+Daniel Stenberg (5 Sep 2017)
+- docs/curl_mime_*.3: added examples
+
+- configure: add MultiSSL to FEATURES when enabled
+  
+  ...for curl-config and its corresponding test 1014
+
+- http-proxy: treat all 2xx as CONNECT success
+  
+  Added test 1904 to verify.
+  
+  Reported-by: Lawrence Wagerfield
+  Fixes #1859
+  Closes #1860
+
+- MAIL-ETIQUETTE: added "1.9 Your emails are public"
+
+- curl.h: fix "unused checksrc ignore", remove dangling reference
+  
+  ... to a README file that doesn't exist anymore
+
+Viktor Szakats (4 Sep 2017)
+- docs: Update to secure URL versions
+
+- mime: use CURL_ZERO_TERMINATED in examples
+  
+  and some minor whitespace fixes
+
+Daniel Stenberg (4 Sep 2017)
+- schannel: return CURLE_SSL_CACERT on failed verification
+  
+  ... not *CACERT_BADFILE as it isn't really because of a bad file.
+  
+  Bug: https://curl.haxx.se/mail/lib-2017-09/0002.html
+  Closes #1858
+
+- test1135: fixed after bd8070085f9
+
+- examples/post-callback: stop returning one byte at a time
+  
+  ... since people copy and paste code from this example and thus they get
+  an inefficient POST operation without a good reason and sometimes
+  without understanding why.
+  
+  Instead this now returns as much data as possible.
+
+- RELEASE-NOTES: fixed the function counter script
+
+- curl.h: make the curl_strequal() protos use the same style
+  
+  ... as the other functions. Makes it easier to machine-parse!
+
+- docs: curl_mime_*.3 man page formatting edits
+
+- RELEASE-NOTES: synced with 1ab9e9b50
+
+Patrick Monnerat (4 Sep 2017)
+- lib: bump version info (soname). Adapt and reenable test 1135.
+
+Daniel Stenberg (3 Sep 2017)
+- headers: move the global_sslset() proto from multi.h to curl.h
+  
+  As it was added to multi.h simply to not break test 1135, which now has
+  been disabled due to the mime API addition anyway and su we can now move
+  the sslset stuff to where the other curl_global_* prototypes are.
+
+Patrick Monnerat (3 Sep 2017)
+- mime: fix signed/unsigned conversions.
+  
+  Use and generate CURL_ZERO_TERMINATED in curl tool and tests.
+
+Jay Satiro (3 Sep 2017)
+- tool_formparse: fix some trivial warnings
+
+Patrick Monnerat (3 Sep 2017)
+- mime: use size_t instead of ssize_t in public API interface.
+  
+  To support telling a string is nul-terminated, symbol CURL_ZERO_TERMINATED
+  has been introduced.
+  
+  Documentation updated accordingly.
+  
+  symbols in versions updated. Added form API symbols deprecation info.
+
+- mime: remove support "-" stdin pseudo-file name in curl_mime_filedata().
+  
+  This feature is badly supported in Windows: as a replacement, a caller has
+  to use curl_mime_data_cb() with fread, fseek and possibly fclose
+  callbacks to process opened files.
+  
+  The cli tool and documentation are updated accordingly.
+  
+  The feature is however kept internally for form API compatibility, with
+  the known caveats it always had.
+  
+  As a side effect, stdin size is not determined by the cli tool even if
+  possible and this results in a chunked transfer encoding. Test 173 is
+  updated accordingly.
+
+- mime: fix some implicit curl_off_t --> size_t conversion warnings.
+
+- mime: tests and examples.
+  
+  Additional mime-specific tests.
+  Existing tests updated to reflect small differences (Expect: 100-continue,
+  data size change due to empty lines, etc).
+  Option -F headers= keyword added to tests.
+  test1135 disabled until the entry point order change is resolved.
+  New example smtp-mime.
+  Examples postit2 and multi-post converted from form API to mime API.
+
+- mime: use in curl cli tool instead of form API.
+  
+  Extended -F option syntax to support multipart mail messages.
+  -F keyword headers= added to include custom headers in parts.
+  Documentation upgraded.
+
+- mime: new MIME API.
+  
+  Available in HTTP, SMTP and IMAP.
+  Deprecates the FORM API.
+  See CURLOPT_MIMEPOST.
+  Lib code and associated documentation.
+
+- test564: Add a warning comment about shell profile output.
+  
+  Shell profile output makes the SSH server failing and this problem reason
+  is not easy to find when no hint is given.
+
+- checksrc: disable SPACEBEFOREPAREN for case statement.
+  
+  The case keyword may be followed by a constant expression and thus should
+  allow it to start with an open parenthesis.
+
+- runtests.pl: allow <file[1-4]> tags in client section.
+  
+  This enables tests to create more than one file on the client side.
+
+- runtests.pl: Apply strippart to upload too.
+  
+  This will allow substitution of boundaries in mail messages.
+
+- Curl_base64_encode: always call with a real data handle.
+  
+  Some calls in different modules were setting the data handle to NULL, causing
+  segmentation faults when using builds that enable character code conversions.
+
+- non-ascii: allow conversion functions to be called with a NULL data handle.
+
+- http: fix a memory leakage in checkrtspprefix().
+
+Daniel Stenberg (2 Sep 2017)
+- [Max Dymond brought this change]
+
+  ossfuzz: Move to C++ for curl_fuzzer.
+  
+  Automake gets confused if you want to use C++ static libraries with C
+  code - basically we need to involve the clang++ linker. The easiest way
+  of achieving this is to rename the C code as C++ code. This gets us a
+  bit further along the path and ought to be compatible with Google's
+  version of clang.
+
+- curl_global_sslset: select backend by name case insensitively
+  
+  Closes #1849
+
+- [Max Dymond brought this change]
+
+  ossfuzz: additional seed corpora
+  
+  Create simple seed corpora for:
+  - FTP
+  - telnet
+  - dict
+  - tftp
+  - imap
+  - pop3
+  
+  based off the tests of the same number.
+  
+  Closes #1842
+
+- [Max Dymond brought this change]
+
+  ossfuzz: moving towards the ideal integration
+  
+  - Start with the basic code from the ossfuzz project.
+  - Rewrite fuzz corpora to be binary files full of Type-Length-Value
+    data, and write a glue layer in the fuzzing function to convert
+    corpora into CURL options.
+  - Have supporting functions to generate corpora from existing tests
+  - Integrate with Makefile.am
+
+- strcase: corrected comment header for Curl_strcasecompare()
+
+- unit1301: fix error message on first test
+
+- curl_global_sslset.3: show the struct and enum too
+  
+  ... so that users can actually write code based on the man page alone,
+  not having to read the header file.
+
+Jay Satiro (31 Aug 2017)
+- darwinssl: handle long strings in TLS certs (follow-up)
+  
+  - Fix handling certificate subjects that are already UTF-8 encoded.
+  
+  Follow-up to b3b75d1 from two days ago. Since then a copy would be
+  skipped if the subject was already UTF-8, possibly resulting in a NULL
+  deref later on.
+  
+  Ref: https://github.com/curl/curl/issues/1823
+  Ref: https://github.com/curl/curl/pull/1831
+  
+  Closes https://github.com/curl/curl/pull/1836
+
+Daniel Stenberg (31 Aug 2017)
+- cyassl: call it the "WolfSSL" backend
+  
+  ... instead of cyassl, as this is the current name for it.
+  
+  Closes #1844
+
+- polarssl: fix multissl breakage
+  
+  Reported-by: Dan Fandrich
+  Bug: https://curl.haxx.se/mail/lib-2017-08/0121.html
+  Closes #1843
+
+- configure: remove the leading comma from the backends list
+  
+  ... when darwinssl is used.
+  
+  Reported-by: Viktor Szakats
+  Bug: https://github.com/curl/curl/commit/b0989cd3abaff4f9a0717b4875022fa79e33b481#commitcomment-23943493
+  
+  Closes #1845
+
+Kamil Dudka (30 Aug 2017)
+- examples/sslbackend.c: fix failure of 'make checksrc'
+  
+  ./sslbackend.c:58:3: warning: else after closing brace on same line (BRACEELSE)
+     } else if(isdigit(*name)) {
+     ^
+  ./sslbackend.c:62:3: warning: else after closing brace on same line (BRACEELSE)
+     } else
+     ^
+
+Viktor Szakats (30 Aug 2017)
+- makefile.m32: add multissl support
+  
+  Closes https://github.com/curl/curl/pull/1840
+
+Daniel Stenberg (30 Aug 2017)
+- curl.h: CURLSSLBACKEND_WOLFSSL used wrong value
+  
+  The CURLSSLBACKEND_WOLFSSL is supposed to be an alias for
+  CURLSSLBACKEND_CYASSL, but used an erronous value. To reduce the risk
+  for a similar mistake, define the backend aliases to use the enum values
+  instead.
+  
+  Reported-by: Gisle Vanem
+  Bug: https://curl.haxx.se/mail/lib-2017-08/0120.html
+
+- curl_global_sslset.3: clarify
+  
+  it is a one time *set*, not necessarily a one time use... it can be
+  called again if the first call failed or just listed the alternatives.
+  
+  clarify that the available backends are the ones this build supports
+  
+  plus add some formatting
+  
+  Reported-by: Rich Gray
+  Bug: https://curl.haxx.se/mail/lib-2017-08/0119.html
+
+- curl/multi.h: remove duplicated closing c++ brace
+  
+  Regression since 1328f69d53f2f2e93
+  
+  Fixes #1841
+  Reported-by: Andrei Karas
+
+- RELEASE-NOTES: synced with 8c33c963a
+
+- HELP-US.md: spelling
+
+- HELP-US.md: "How to get started helping out in the curl project"
+  
+  Closes #1837
+
+Dan Fandrich (29 Aug 2017)
+- asyn-thread: Fixed cleanup after OOM
+  
+  destroy_async_data() assumes that if the flag "done" is not set yet, the
+  thread itself will clean up once the request is complete.  But if an
+  error (generally OOM) occurs before the thread even has a chance to
+  start, it will never get a chance to clean up and memory will be leaked.
+  By clearing "done" only just before starting the thread, the correct
+  cleanup sequence will happen in all cases.
+
+Daniel Stenberg (28 Aug 2017)
+- curl_global_init.3: mention curl_global_sslset(3)
+
+Dan Fandrich (28 Aug 2017)
+- unit1606: Fixed shadowed variable warning
+
+- asyn-thread: Improved cleanup after OOM situations
+
+- asyn-thread: Set errno to the proper value ENOMEM in OOM situation
+  
+  This used to be set in some configurations to EAI_MEMORY which is not a
+  valid value for errno and caused Curl_strerror to fail an assertion.
+
+Daniel Stenberg (28 Aug 2017)
+- [Johannes Schindelin brought this change]
+
+  configure: Handle "MultiSSL" specially When versioning symbols
+  
+  There is a mode in which libcurl is compiled with versioned symbols,
+  depending on the active SSL backend.
+  
+  When multiple SSL backends are active, it does not make sense to favor
+  one over the others, so let's not: introduce a new prefix for the case
+  where multiple SSL backends are compiled into cURL.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  configure: allow setting the default SSL backend
+  
+  Previously, we used as default SSL backend whatever was first in the
+  `available_backends` array.
+  
+  However, some users may want to override that default without patching
+  the source code.
+  
+  Now they can: with the --with-default-ssl-backend=<backend> option of
+  the ./configure script.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  vtls: use Curl_ssl_multi pseudo backend only when needed
+  
+  When only one SSL backend is configured, it is totally unnecessary to
+  let multissl_init() configure the backend at runtime, we can select the
+  correct backend at build time already.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  version: if built with more than one SSL backend, report all of them
+  
+  To discern the active one from the inactive ones, put the latter into
+  parentheses.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  version: add the CURL_VERSION_MULTI_SSL feature flag
+  
+  This new feature flag reports When cURL was built with multiple SSL
+  backends.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  metalink: allow compiling with multiple SSL backends
+  
+  Previously, the code assumed that at most one of the SSL backends would
+  be compiled in, emulating OpenSSL's functions if the configured backend
+  was not OpenSSL itself.
+  
+  However, now we allow building with multiple SSL backends and choosing
+  one at runtime. Therefore, metalink needs to be adjusted to handle this
+  scenario, too.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  docs/examples: demonstrate how to select SSL backends
+  
+  The newly-introduced curl_global_sslset() function deserves to be
+  show-cased.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  Add a man page for curl_global_sslset()
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  vtls: introduce curl_global_sslset()
+  
+  Let's add a compile time safe API to select an SSL backend. This
+  function needs to be called *before* curl_global_init(), and can be
+  called only once.
+  
+  Side note: we do not explicitly test that it is called before
+  curl_global_init(), but we do verify that it is not called multiple times
+  (even implicitly).
+  
+  If SSL is used before the function was called, it will use whatever the
+  CURL_SSL_BACKEND environment variable says (or default to the first
+  available SSL backend), and if a subsequent call to
+  curl_global_sslset() disagrees with the previous choice, it will fail
+  with CURLSSLSET_TOO_LATE.
+  
+  The function also accepts an "avail" parameter to point to a (read-only)
+  NULL-terminated list of available backends. This comes in real handy if
+  an application wants to let the user choose between whatever SSL backends
+  the currently available libcurl has to offer: simply call
+  
+          curl_global_sslset(-1, NULL, &avail);
+  
+  which will return CURLSSLSET_UNKNOWN_BACKEND and populate the avail
+  variable to point to the relevant information to present to the user.
+  
+  Just like with the HTTP/2 push functions, we have to add the function
+  declaration of curl_global_sslset() function to the header file
+  *multi.h* because VMS and OS/400 require a stable order of functions
+  declared in include/curl/*.h (where the header files are sorted
+  alphabetically). This looks a bit funny, but it cannot be helped.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  vtls: refactor out essential information about the SSL backends
+  
+  There is information about the compiled-in SSL backends that is really
+  no concern of any code other than the SSL backend itself, such as which
+  function (if any) implements SHA-256 summing.
+  
+  And there is information that is really interesting to the user, such as
+  the name, or the curl_sslbackend value.
+  
+  Let's factor out the latter into a publicly visible struct. This
+  information will be used in the upcoming API to set the SSL backend
+  globally.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  vtls: allow selecting which SSL backend to use at runtime
+  
+  When building software for the masses, it is sometimes not possible to
+  decide for all users which SSL backend is appropriate.
+  
+  Git for Windows, for example,  uses cURL to perform clones, fetches and
+  pushes via HTTPS, and some users strongly prefer OpenSSL, while other
+  users really need to use Secure Channel because it offers
+  enterprise-ready tools to manage credentials via Windows' Credential
+  Store.
+  
+  The current Git for Windows versions use the ugly work-around of
+  building libcurl once with OpenSSL support and once with Secure Channel
+  support, and switching out the binaries in the installer depending on
+  the user's choice.
+  
+  Needless to say, this is a super ugly workaround that actually only
+  works in some cases: Git for Windows also comes in a portable form, and
+  in a form intended for third-party applications requiring Git
+  functionality, in which cases this "swap out libcurl-4.dll" simply is
+  not an option.
+  
+  Therefore, the Git for Windows project has a vested interest in teaching
+  cURL to make the SSL backend a *runtime* option.
+  
+  This patch makes that possible.
+  
+  By running ./configure with multiple --with-<backend> options, cURL will
+  be built with multiple backends.
+  
+  For the moment, the backend can be configured using the environment
+  variable CURL_SSL_BACKEND (valid values are e.g. "openssl" and
+  "schannel").
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  vtls: fold the backend ID into the Curl_ssl structure
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  curl_ntlm_core: don't complain but #include OpenSSL header if needed
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  vtls: encapsulate SSL backend-specific data
+  
+  So far, all of the SSL backends' private data has been declared as
+  part of the ssl_connect_data struct, in one big #if .. #elif .. #endif
+  block.
+  
+  This can only work as long as the SSL backend is a compile-time option,
+  something we want to change in the next commits.
+  
+  Therefore, let's encapsulate the exact data needed by each SSL backend
+  into a private struct, and let's avoid bleeding any SSL backend-specific
+  information into urldata.h. This is also necessary to allow multiple SSL
+  backends to be compiled in at the same time, as e.g. OpenSSL's and
+  CyaSSL's headers cannot be included in the same .c file.
+  
+  To avoid too many malloc() calls, we simply append the private structs
+  to the connectdata struct in allocate_conn().
+  
+  This requires us to take extra care of alignment issues: struct fields
+  often need to be aligned on certain boundaries e.g. 32-bit values need to
+  be stored at addresses that divide evenly by 4 (= 32 bit / 8
+  bit-per-byte).
+  
+  We do that by assuming that no SSL backend's private data contains any
+  fields that need to be aligned on boundaries larger than `long long`
+  (typically 64-bit) would need. Under this assumption, we simply add a
+  dummy field of type `long long` to the `struct connectdata` struct. This
+  field will never be accessed but acts as a placeholder for the four
+  instances of ssl_backend_data instead. the size of each ssl_backend_data
+  struct is stored in the SSL backend-specific metadata, to allow
+  allocate_conn() to know how much extra space to allocate, and how to
+  initialize the ssl[sockindex]->backend and proxy_ssl[sockindex]->backend
+  pointers.
+  
+  This would appear to be a little complicated at first, but is really
+  necessary to encapsulate the private data of each SSL backend correctly.
+  And we need to encapsulate thusly if we ever want to allow selecting
+  CyaSSL and OpenSSL at runtime, as their headers cannot be included within
+  the same .c file (there are just too many conflicting definitions and
+  declarations for that).
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  vtls: prepare the SSL backends for encapsulated private data
+  
+  At the moment, cURL's SSL backend needs to be configured at build time.
+  As such, it is totally okay for them to hard-code their backend-specific
+  data in the ssl_connect_data struct.
+  
+  In preparation for making the SSL backend a runtime option, let's make
+  the access of said private data a bit more abstract so that it can be
+  adjusted later in an easy manner.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  urldata.h: move SSPI-specific #include to correct location
+  
+  In 86b889485 (sasl_gssapi: Added GSS-API based Kerberos V5 variables,
+  2014-12-03), an SSPI-specific field was added to the kerberos5data
+  struct without moving the #include "curl_sspi.h" later in the same file.
+  
+  This broke the build when SSPI was enabled, unless Secure Channel was
+  used as SSL backend, because it just so happens that Secure Channel also
+  requires "curl_sspi.h" to be #included.
+  
+  In f4739f639 (urldata: include curl_sspi.h when Windows SSPI is enabled,
+  2017-02-21), this bug was fixed incorrectly: Instead of moving the
+  appropriate conditional #include, the Secure Channel-conditional part
+  was now also SSPI-conditional.
+  
+  Fix this problem by moving the correct #include instead.
+  
+  This is also required for an upcoming patch that moves all the Secure
+  Channel-specific stuff out of urldata.h and encapsulates it properly in
+  vtls/schannel.c instead.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  urldata.h: remove support for obsolete PolarSSL version
+  
+  Since 5017d5ada (polarssl: now require 1.3.0+, 2014-03-17), we require
+  a newer PolarSSL version. No need to keep code trying to support any
+  older version.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  getinfo: access SSL internals via Curl_ssl
+  
+  In the ongoing endeavor to abstract out all SSL backend-specific
+  functionality, this is the next step: Instead of hard-coding how the
+  different SSL backends access their internal data in getinfo.c, let's
+  implement backend-specific functions to do that task.
+  
+  This will also allow for switching SSL backends as a runtime option.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  vtls: move SSL backends' private constants out of their header files
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  axtls: use Curl_none_* versions of init() and cleanup()
+  
+  There are convenient no-op versions of the init/cleanup functions now,
+  no need to define private ones for axTLS.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  vtls: remove obsolete declarations of SSL backend functionality
+  
+  These functions are all available via the Curl_ssl struct now, no need
+  to declare them separately anymore.
+  
+  As the global declarations are removed, the corresponding function
+  definitions are marked as file-local. The only two exceptions here are
+  Curl_mbedtls_shutdown() and Curl_polarssl_shutdown(): only the
+  declarations were removed, there are no function definitions to mark
+  file-local.
+  
+  Please note that Curl_nss_force_init() is *still* declared globally, as
+  the only SSL backend-specific function, because it was introduced
+  specifically for the use case where cURL was compiled with
+  `--without-ssl --with-nss`. For details, see f3b77e561 (http_ntlm: add
+  support for NSS, 2010-06-27).
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  schannel: reorder functions topologically
+  
+  The _shutdown() function calls the _session_free() function; While this
+  is not a problem now (because schannel.h declares both functions), a
+  patch looming in the immediate future with make all of these functions
+  file-local.
+  
+  So let's just move the _session_free() function's definition before it
+  is called.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  axtls: reorder functions topologically
+  
+  The connect_finish() function (like many other functions after it) calls
+  the Curl_axtls_close() function; While this is not a problem now
+  (because axtls.h declares the latter function), a patch looming in the
+  immediate future with make all of these functions file-local.
+  
+  So let's just move the Curl_axtls_close() function's definition before
+  it is called.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  vtls: move the SUPPORT_HTTPS_PROXY flag into the Curl_ssl struct
+  
+  That will allow us to choose the SSL backend at runtime.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  vtls: convert the have_curlssl_* constants to runtime flags
+  
+  The entire idea of introducing the Curl_ssl struct to describe SSL
+  backends is to prepare for choosing the SSL backend at runtime.
+  
+  To that end, convert all the #ifdef have_curlssl_* style conditionals
+  to use bit flags instead.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  vtls: move sha256sum into the Curl_ssl struct
+  
+  The SHA-256 checksumming is also an SSL backend-specific function.
+  Let's include it in the struct declaring the functionality of SSL
+  backends.
+  
+  In contrast to MD5, there is no fall-back code. To indicate this, the
+  respective entries are NULL for those backends that offer no support for
+  SHA-256 checksumming.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  vtls: move md5sum into the Curl_ssl struct
+  
+  The MD5 summing is also an SSL backend-specific function. So let's
+  include it, offering the previous fall-back code as a separate function
+  now: Curl_none_md5sum(). To allow for that, the signature had to be
+  changed so that an error could be returned from the implementation
+  (Curl_none_md5sum() can run out of memory).
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  vtls: use the Curl_ssl struct to access all SSL backends' functionality
+  
+  This is the first step to unify the SSL backend handling. Now all the
+  SSL backend-specific functionality is accessed via a global instance of
+  the Curl_ssl struct.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  vtls: declare Curl_ssl structs for every SSL backend
+  
+  The idea of introducing the Curl_ssl struct was to unify how the SSL
+  backends are declared and called. To this end, we now provide an
+  instance of the Curl_ssl struct for each and every SSL backend.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  vtls: introduce a new struct for SSL backends
+  
+  This new struct is similar in nature to Curl_handler: it will define the
+  functions and capabilities of all the SSL backends (where Curl_handler
+  defines the functions and capabilities of protocol handlers).
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  vtls: make sure every _sha256sum()'s first arg is const
+  
+  This patch makes the signature of the _sha256sum() functions consistent
+  among the SSL backends, in preparation for unifying the way all SSL
+  backends are accessed.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  vtls: make sure all _data_pending() functions return bool
+  
+  This patch makes the signature of the _data_pending() functions
+  consistent among the SSL backends, in preparation for unifying the way
+  all SSL backends are accessed.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  vtls: make sure all _cleanup() functions return void
+  
+  This patch makes the signature of the _cleanup() functions consistent
+  among the SSL backends, in preparation for unifying the way all SSL
+  backends are accessed.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Johannes Schindelin brought this change]
+
+  vtls: use consistent signature for _random() implementations
+  
+  This will make the upcoming multissl backend much easier to implement.
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- strtooff: fix build for systems with long long but no strtoll option
+  
+  Closes #1829
+  
+  Reported-by: Dan Fandrich
+  Bug: https://github.com/curl/curl/pull/1758#issuecomment-324861615
+
+- darwinssl: handle long strings in TLS certs
+  
+  ... as the previous fixed length 128 bytes buffer was sometimes too
+  small.
+  
+  Fixes #1823
+  Closes #1831
+  
+  Reported-by: Benjamin Sergeant
+  Assisted-by: Bill Pyne, Ray Satiro, Nick Zitzmann
+
+- system.h: include sys/poll.h for AIX
+  
+  ... to get the event/revent defines that might be used for the poll
+  struct.
+  
+  Reported-by: Michael Smith
+  Fixes #1828
+  Closes #1833
+
+Dan Fandrich (26 Aug 2017)
+- tests: Make sure libtests & unittests call curl_global_cleanup()
+  
+  These were missed in commit c468c27b.
+
+Jay Satiro (26 Aug 2017)
+- [theantigod brought this change]
+
+  winbuild: fix embedded manifest option
+  
+  Embedded manifest option didn't work due to incorrect path.
+  
+  Fixes https://github.com/curl/curl/issues/1832
+
+Daniel Stenberg (25 Aug 2017)
+- fuzz/Makefile.am: remove curlbuild.h leftovers
+
+- examples/threaded-ssl: mention that this is for openssl before 1.1
+
+- imap: use defined names for response codes
+  
+  When working on this code I found the previous setup a bit weird while
+  using proper defines increases readability.
+  
+  Closes #1824
+
+- CURLOPT_USERPWD.3: see also CURLOPT_PROXYUSERPWD
+
+- imap: support PREAUTH
+  
+  It is a defined possible greeting at server startup that means the
+  connection is already authenticated. See
+  https://tools.ietf.org/html/rfc3501#section-7.1.4
+  
+  Test 846 added to verify.
+  
+  Fixes #1818
+  Closes #1820
+
+Jay Satiro (23 Aug 2017)
+- config-tpf: define SIZEOF_LONG
+  
+  Recent changes that replaced CURL_SIZEOF_LONG in the source with
+  SIZEOF_LONG broke builds that use the premade configuration files and
+  don't have SIZEOF_LONG defined.
+  
+  Bug: https://github.com/curl/curl/issues/1816
+
+Dan Fandrich (23 Aug 2017)
+- test1453: Fixed <features>
+
+Daniel Stenberg (22 Aug 2017)
+- [Gisle Vanem brought this change]
+
+  config-dos: add missing defines, SIZEOF_* and two others
+  
+  Bug: #1816
+
+- curl: shorten and clean up CA cert verification error message
+  
+  The previous message was just too long for ordinary people and it was
+  encouraging users to use `--insecure` a little too easy.
+  
+  Based-on-work-by: Frank Denis
+  
+  Closes #1810
+  Closes #1817
+
+- request-target.d: mention added in 7.55.0
+
+Marcel Raad (22 Aug 2017)
+- tool_main: turn off MinGW CRT's globbing
+  
+  By default, the MinGW CRT globs command-line arguments. This prevents
+  getting a single asterisk into an argument as test 1299 does. Turn off
+  globbing by setting the global variable _CRT_glob to 0 for MinGW.
+  
+  Fixes https://github.com/curl/curl/issues/1751
+  Closes https://github.com/curl/curl/pull/1813
+
+Viktor Szakats (22 Aug 2017)
+- makefile.m32: add support for libidn2
+  
+  libidn was replaced with libidn2 last year in configure.
+  Caveat: libidn2 may depend on a list of further libs.
+  These can be manually specified via CURL_LDFLAG_EXTRAS.
+  
+  Closes https://github.com/curl/curl/pull/1815
+
+Jay Satiro (22 Aug 2017)
+- [Viktor Szakats brought this change]
+
+  config-win32: define SIZEOF_LONG
+  
+  Recent changes that replaced CURL_SIZEOF_LONG in the source with
+  SIZEOF_LONG broke builds that use the premade configuration files and
+  don't have SIZEOF_LONG defined.
+  
+  Closes https://github.com/curl/curl/pull/1814
+
+Daniel Stenberg (20 Aug 2017)
+- cmake: enable picky compiler options with clang and gcc
+  
+  closes #1799
+
+- curl/system.h: fix build for hppa
+  
+  Reported-by: John David Anglin
+  Bug: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=872502#10
+
+- [Even Rouault brought this change]
+
+  tftp: fix memory leak on too long filename
+  
+  Fixes
+  
+  $ valgrind --leak-check=full ~/install-curl-git/bin/curl tftp://localhost/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz
+  
+  ==9752== Memcheck, a memory error detector
+  ==9752== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
+  ==9752== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
+  ==9752== Command: /home/even/install-curl-git/bin/curl tftp://localhost/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz
+  ==9752==
+  curl: (71) TFTP file name too long
+  
+  ==9752==
+  ==9752== HEAP SUMMARY:
+  ==9752== 505 bytes in 1 blocks are definitely lost in loss record 11 of 11
+  ==9752==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
+  ==9752==    by 0x4E61CED: Curl_urldecode (in /home/even/install-curl-git/lib/libcurl.so.4.4.0)
+  ==9752==    by 0x4E75868: tftp_state_machine (in /home/even/install-curl-git/lib/libcurl.so.4.4.0)
+  ==9752==    by 0x4E761B6: tftp_do (in /home/even/install-curl-git/lib/libcurl.so.4.4.0)
+  ==9752==    by 0x4E711B6: multi_runsingle (in /home/even/install-curl-git/lib/libcurl.so.4.4.0)
+  ==9752==    by 0x4E71D00: curl_multi_perform (in /home/even/install-curl-git/lib/libcurl.so.4.4.0)
+  ==9752==    by 0x4E6950D: curl_easy_perform (in /home/even/install-curl-git/lib/libcurl.so.4.4.0)
+  ==9752==    by 0x40E0B7: operate_do (in /home/even/install-curl-git/bin/curl)
+  ==9752==    by 0x40E849: operate (in /home/even/install-curl-git/bin/curl)
+  ==9752==    by 0x402693: main (in /home/even/install-curl-git/bin/curl)
+  
+  Fixes https://oss-fuzz.com/v2/testcase-detail/5232311106797568
+  Credit to OSS Fuzz
+  
+  Closes #1808
+
+Dan Fandrich (19 Aug 2017)
+- runtests: fixed case insensitive matching of keywords
+  
+  Commit 5c2aac71 didn't work in the case of mixed-case keywords given on
+  the command-line.
+
+- tests: Make sure libtests call curl_global_cleanup()
+  
+  This ensures that global data allocations are freed so Valgrind stays
+  happy. This was a problem with at least PolarSSL and mbedTLS.
+
+Daniel Stenberg (18 Aug 2017)
+- RELEASE-NOTES: synced with 8baead425
+
+- scripts/contri*sh: use "git log --use-mailmap"
+
+- mailmap: de-duplify some git authors
+
+- http2_recv: return error better on fatal h2 errors
+  
+  Ref #1012
+  Figured-out-by: Tatsuhiro Tsujikawa
+
+- KNOWN_BUGS: HTTP test server 'connection-monitor' problems
+  
+  Closes #868
+
+- curl/system.h: check for __ppc__ as well
+  
+  ... regression since issue #1774 (commit 10b3df10596a) since obviously
+  some older gcc doesn't know __powerpc__ while some newer doesn't know
+  __ppc__ ...
+  
+  Fixes #1797
+  Closes #1798
+  Reported-by: Ryan Schmidt
+
+- [Jan Alexander Steffens (heftig) brought this change]
+
+  http: Don't wait on CONNECT when there is no proxy
+  
+  Since curl 7.55.0, NetworkManager almost always failed its connectivity
+  check by timeout. I bisected this to 5113ad04 (http-proxy: do the HTTP
+  CONNECT process entirely non-blocking).
+  
+  This patch replaces !Curl_connect_complete with Curl_connect_ongoing,
+  which returns false if the CONNECT state was left uninitialized and lets
+  the connection continue.
+  
+  Closes #1803
+  Fixes #1804
+  
+  Also-fixed-by: Gergely Nagy
+
+- [Johannes Schindelin brought this change]
+
+  metalink: adjust source code style
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- CURL_SIZEOF_LONG: removed, use only SIZEOF_LONG
+
+- lib557: no longer use CURL_SIZEOF_* defines
+
+- config-win32: define SIZEOF_CURL_OFF_T
+
+- cmake: sizeof curl_off_t, remove unused detections
+
+- system.h: remove all CURL_SIZEOF_* defines
+  
+  ... as they're not used externally and internally we check for the sizes
+  already in configure etc.
+  
+  Closes #1767
+
+- ftp: fix CWD when doing multicwd then nocwd on same connection
+  
+  Fixes #1782
+  Closes #1787
+  Reported-by: Peter Lamare
+
+- CURLOPT_SSH_COMPRESSION.3: enable with 1L
+  
+  (leaves other values reserved for the future)
+
+- compressed-ssh.d: "Added: 7.56.0"
+
+- curl/system.h: checksrc compliance
+
+Jay Satiro (17 Aug 2017)
+- [Viktor Szakats brought this change]
+
+  ssh: add the ability to enable compression (for SCP/SFTP)
+  
+  The required low-level logic was already available as part of
+  `libssh2` (via `LIBSSH2_FLAG_COMPRESS` `libssh2_session_flag()`[1]
+  option.)
+  
+  This patch adds the new `libcurl` option `CURLOPT_SSH_COMPRESSION`
+  (boolean) and the new `curl` command-line option `--compressed-ssh`
+  to request this `libssh2` feature. To have compression enabled, it
+  is required that the SSH server supports a (zlib) compatible
+  compression method and that `libssh2` was built with `zlib` support
+  enabled.
+  
+  [1] https://www.libssh2.org/libssh2_session_flag.html
+  
+  Ref: https://github.com/curl/curl/issues/1732
+  Closes https://github.com/curl/curl/pull/1735
+
+- examples/ftpuploadresume: checksrc compliance
+
+- [Maksim Stsepanenka brought this change]
+
+  http_proxy: fix build error for CURL_DOES_CONVERSIONS
+  
+  Closes https://github.com/curl/curl/pull/1793
+
+GitHub (16 Aug 2017)
+- [Nick Zitzmann brought this change]
+
+  configure: check for __builtin_available() availability (#1788)
+  
+  This change does two things:
+  1. It un-breaks the build in Xcode 9.0. (Xcode 9.0 is currently
+     failing trying to compile connectx() in lib/connect.c.)
+  2. It finally weak-links the connectx() function, and falls back on
+     connect() when run on older operating systems.
+
+Daniel Stenberg (16 Aug 2017)
+- travis: add metalink to some osx builds
+  
+  Closes #1790
+
+- [Max Dymond brought this change]
+
+  coverage: Use two coveralls commands to get lib/vtls results
+  
+  closes #1747
+
+- darwinssi: fix error: variable length array used
+
+- m4/curl-compilers.m4: use proper quotes around string, not backticks
+  
+  ... when setting clang version to assume 3.7
+  
+  Caused a lot of "integer expression expected" warnings by configure.
+
+- [Benbuck Nason brought this change]
+
+  cmake: remove dead code for DISABLED_THREADSAFE
+  
+  Closes #1786
+
+Jay Satiro (15 Aug 2017)
+- [Jakub Zakrzewski brought this change]
+
+  curl-confopts.m4: fix --disable-threaded-resolver
+  
+  Closes https://github.com/curl/curl/issues/1784
+
+Daniel Stenberg (15 Aug 2017)
+- [Ryan Winograd brought this change]
+
+  progress: Track total times following redirects
+  
+  Update the progress timers `t_nslookup`, `t_connect`, `t_appconnect`,
+  `t_pretransfer`, and `t_starttransfer` to track the total times for
+  these activities when a redirect is followed. Previously, only the times
+  for the most recent request would be tracked.
+  
+  Related changes:
+  
+    - Rename `Curl_pgrsResetTimesSizes` to `Curl_pgrsResetTransferSizes`
+      now that the function only resets transfer sizes and no longer
+      modifies any of the progress timers.
+  
+    - Add a bool to the `Progress` struct that is used to prevent
+      double-counting `t_starttransfer` times.
+  
+  Added test case 1399.
+  
+  Fixes #522 and Known Bug 1.8
+  Closes #1602
+  Reported-by: joshhe on github
+
+- [Benbuck Nason brought this change]
+
+  cmake: remove dead code for CURL_DISABLE_RTMP
+  
+  Closes #1785
+
+Kamil Dudka (15 Aug 2017)
+- zsh.pl: produce a working completion script again
+  
+  Commit curl-7_54_0-118-g8b2f22e changed the output format of curl --help
+  to use <file> and <dir> instead of FILE and DIR, which caused zsh.pl to
+  produce a broken completion script:
+  
+  % curl --<TAB>
+  _curl:10: no such file or directory: seconds
+  
+  Closes #1779
+
+Daniel Stenberg (15 Aug 2017)
+- curlver: toward 7.56.0?
+
+- RELEASE-NOTES: synced with 91c46dc44
+
+- test1449: FTP download range with an too large size
+
+- strtoofft: reduce integer overflow risks globally
+  
+  ... make sure we bail out on overflows.
+  
+  Reported-by: Brian Carpenter
+  Closes #1758
+
+- travis: build the examples too
+  
+  to make sure they keep building warning-free
+  
+  Closes #1777
+
+- runtests: match keywords case insensitively
+
+- examples/ftpuploadresume.c: use portable code
+  
+  ... converted from the MS specific _snscanf()
+
+Version 7.55.1 (13 Aug 2017)
+
+Daniel Stenberg (13 Aug 2017)
+- RELEASE-NOTES/THANKS: curl 7.55.1 release time
+
+- gitignore: ignore .xz now instead of .lzma
+
+- [Sergei Nikulov brought this change]
+
+  cmake: Threads detection update. ref: #1702
+  
+  Closes #1719
+
+- ipv6_scope: support unique local addresses
+  
+  Fixes #1764
+  Closes #1773
+  Reported-by: James Slaughter
+
+- [Alex Potapenko brought this change]
+
+  curl/system.h: GCC doesn't define __ppc__ on PowerPC, uses __powerpc__
+  
+  Closes #1774
+
+- test1448: verify redirect to IDN using URL
+  
+  Closes #1772
+
+- [Salah-Eddin Shaban brought this change]
+
+  redirect: skip URL encoding for host names
+  
+  This fixes redirects to IDN URLs
+  
+  Fixes #1441
+  Closes #1762
+  Reported by: David Lord
+
+- test2032: mark as flaky (again)
+
+- travis: test cmake build on tarball too
+  
+  Could've prevented #1755
+
+- [Simon Warta brought this change]
+
+  cmake: allow user to override CMAKE_DEBUG_POSTFIX
+  
+  Closes #1763
+
+- connect-to.d: better language
+
+- connect-to.d: clarified
+
+- bagder/Curl_tvdiff_us: fix the math
+  
+  Regression since adef394ac5 (released in 7.55.0)
+  
+  Reported-by: Han Qiao
+  Fixes #1769
+  Closes #1771
+
+- curl/system.h: add Oracle Solaris Studio
+  
+  Fixes #1752
+
+- [Alessandro Ghedini brought this change]
+
+  docs: fix typo funtion -> function
+  
+  Closes #1770
+
+Alessandro Ghedini (12 Aug 2017)
+- docs: fix grammar in CURL_SSLVERSION_MAX_DEFAULT description
+
+- docs: fix typo stuct -> struct
+
+Dan Fandrich (12 Aug 2017)
+- test1447: require a curl with http support
+
+Daniel Stenberg (11 Aug 2017)
+- [Thomas Petazzoni brought this change]
+
+  curl/system.h: support more architectures
+  
+  The long list of architectures in include/curl/system.h is annoying to
+  maintain, and needs to be extended for each and every architecture to
+  support.
+  
+  Instead, let's rely on the __SIZEOF_LONG__ define of the gcc compiler
+  (we are in the GNUC condition anyway), which tells us if long is 4
+  bytes or 8 bytes.
+  
+  This fixes the build of libcurl 7.55.0 on architectures such as
+  OpenRISC or ARC.
+  
+  Closes #1766
+  
+  Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+
+- test2033: this went flaky again
+  
+  Suspicion: when we enabled the threaded resolver by default.
+
+- test1447: verifies the parse proxy fix in 6e0e152ce5c
+
+- [Even Rouault brought this change]
+
+  parse_proxy(): fix memory leak in case of invalid proxy server name
+  
+  Fixes the below leak:
+  
+  $ valgrind --leak-check=full ~/install-curl-git/bin/curl --proxy "http://a:b@/x" http://127.0.0.1
+  curl: (5) Couldn't resolve proxy name
+  ==5048==
+  ==5048== HEAP SUMMARY:
+  ==5048==     in use at exit: 532 bytes in 12 blocks
+  ==5048==   total heap usage: 5,288 allocs, 5,276 frees, 445,271 bytes allocated
+  ==5048==
+  ==5048== 2 bytes in 1 blocks are definitely lost in loss record 1 of 12
+  ==5048==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
+  ==5048==    by 0x4E6CB79: parse_login_details (url.c:5614)
+  ==5048==    by 0x4E6BA82: parse_proxy (url.c:5091)
+  ==5048==    by 0x4E6C46D: create_conn_helper_init_proxy (url.c:5346)
+  ==5048==    by 0x4E6EA18: create_conn (url.c:6498)
+  ==5048==    by 0x4E6F9B4: Curl_connect (url.c:6967)
+  ==5048==    by 0x4E86D05: multi_runsingle (multi.c:1436)
+  ==5048==    by 0x4E88432: curl_multi_perform (multi.c:2160)
+  ==5048==    by 0x4E7C515: easy_transfer (easy.c:708)
+  ==5048==    by 0x4E7C74A: easy_perform (easy.c:794)
+  ==5048==    by 0x4E7C7B1: curl_easy_perform (easy.c:813)
+  ==5048==    by 0x414025: operate_do (tool_operate.c:1563)
+  ==5048==
+  ==5048== 2 bytes in 1 blocks are definitely lost in loss record 2 of 12
+  ==5048==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
+  ==5048==    by 0x4E6CBB6: parse_login_details (url.c:5621)
+  ==5048==    by 0x4E6BA82: parse_proxy (url.c:5091)
+  ==5048==    by 0x4E6C46D: create_conn_helper_init_proxy (url.c:5346)
+  ==5048==    by 0x4E6EA18: create_conn (url.c:6498)
+  ==5048==    by 0x4E6F9B4: Curl_connect (url.c:6967)
+  ==5048==    by 0x4E86D05: multi_runsingle (multi.c:1436)
+  ==5048==    by 0x4E88432: curl_multi_perform (multi.c:2160)
+  ==5048==    by 0x4E7C515: easy_transfer (easy.c:708)
+  ==5048==    by 0x4E7C74A: easy_perform (easy.c:794)
+  ==5048==    by 0x4E7C7B1: curl_easy_perform (easy.c:813)
+  ==5048==    by 0x414025: operate_do (tool_operate.c:1563)
+  
+  Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2984
+  Credit to OSS Fuzz for discovery
+  
+  Closes #1761
+
+- RELEASE-NOTES: synced with 37f2195a9
+
+- curlver: bump to 7.55.1
+
+- openssl: fix "error: this statement may fall through"
+  
+  A gcc7 warning.
+
+- [David Benjamin brought this change]
+
+  openssl: remove CONST_ASN1_BIT_STRING.
+  
+  Just making the pointer as const works for the pre-1.1.0 path too.
+  
+  Closes #1759
+
+- maketgz: remove old *.dist files before making the tarball
+  
+  To avoid "old crap" unintentionally getting shipped.
+  
+  Bug: https://curl.haxx.se/mail/lib-2017-08/0050.html
+  Reported-by: Christian Weisgerber
+
+Jay Satiro (10 Aug 2017)
+- mkhelp.pl: allow executing this script directly
+  
+  - Enable execute permission (chmod +x)
+  
+  - Change interpreter to /usr/bin/env perl
+  
+  Ref: https://github.com/curl/curl/issues/1743
+
+Daniel Stenberg (10 Aug 2017)
+- configure: use the threaded resolver backend by default if possible
+  
+  Closes #1647
+
+- cmake: move cmake_uninstall.cmake to CMake/
+  
+  Closes #1756
+
+- metalink: fix error: â*â in boolean context, suggest â&&â instead
+
+- dist: fix the cmake build by shipping cmake_uninstall.cmake.in too
+  
+  Fixes #1755
+
+- travis: verify "make install"
+  
+  Help-by: Jay Satiro
+  Closes #1753
+
+Marcel Raad (10 Aug 2017)
+- build: check out *.sln files with Windows line endings
+  
+  Visual Studio doesn't like LF line endings in solution files and always
+  converts them to CRLF when doing changes to the solution. Notably, this
+  affects the solutions in the release archive.
+  
+  Closes https://github.com/curl/curl/pull/1746
+
+- gitignore: ignore top-level .vs folder
+  
+  This folder is generated when using the CMake build system from within
+  Visual Studio.
+  
+  Closes https://github.com/curl/curl/pull/1746
+
+Jay Satiro (10 Aug 2017)
+- digest_sspi: Don't reuse context if the user/passwd has changed
+  
+  Bug: https://github.com/curl/curl/issues/1685
+  Reported-by: paulharris@users.noreply.github.com
+  
+  Assisted-by: Isaac Boukris
+  
+  Closes https://github.com/curl/curl/pull/1742
+
+Daniel Stenberg (9 Aug 2017)
+- [Adam Sampson brought this change]
+
+  dist: Add dictserver.py/negtelnetserver.py to EXTRA_DIST
+  
+  These weren't included in the 7.55.0 release, but are required in order
+  to run the full test suite.
+  
+  Closes #1744
+
+- [Adam Sampson brought this change]
+
+  curl: do bounds check using a double comparison
+  
+  The fix for this in 8661a0aacc01492e0436275ff36a21734f2541bb wasn't
+  complete: if the parsed number in num is larger than will fit in a long,
+  the conversion is undefined behaviour (causing test1427 to fail for me
+  on IA32 with GCC 7.1, although it passes on AMD64 and ARMv7).  Getting
+  rid of the cast means the comparison will be done using doubles.
+  
+  It might make more sense for the max argument to also be a double...
+  
+  Fixes #1750
+  Closes #1749
+
+- make install: add 8 missing man pages to the installation
+
+- build: fix 'make install' with configure, install docs/libcurl/* too
+  
+  Broken since d24838d4da9faa
+  
+  Reported-by: Bernard Spil
+
+Version 7.55.0 (9 Aug 2017)
+
+Daniel Stenberg (9 Aug 2017)
+- RELEASE-NOTES: curl 7.55.0
+
+- THANKS: 20 new contributors in 7.55.0
+
+- [Viktor Szakats brought this change]
+
+  docs/comments: Update to secure URL versions
+  
+  Closes #1741
+
+- configure: fix recv/send/select detection on Android
+  
+  ... since they now provide several functions as
+  __attribute__((overloadable)), the argument detection logic need
+  updates.
+  
+  Patched-by: destman at github
+  
+  Fixes #1738
+  Closes #1739
+
+Marcel Raad (8 Aug 2017)
+- ax_code_coverage.m4: update to latest version
+  
+  This updates the script to aad5ad5fedb306b39f901a899b7bd305b66c418d
+  from August 01, 2017. Notably, this removes the lconv version whitelist.
+  
+  Closes https://github.com/curl/curl/pull/1716
+
+Daniel Stenberg (7 Aug 2017)
+- test1427: verify command line parser integer overflow detection
+
+- curl: detect and bail out early on parameter integer overflows
+  
+  Make the number parser aware of the maximum limit curl accepts for a
+  value and return an error immediately if larger, instead of running an
+  integer overflow later.
+  
+  Fixes #1730
+  Closes #1736
+
+- glob: do not continue parsing after a strtoul() overflow range
+  
+  Added test 1289 to verify.
+  
+  CVE-2017-1000101
+  
+  Bug: https://curl.haxx.se/docs/adv_20170809A.html
+  Reported-by: Brian Carpenter
+
+- tftp: reject file name lengths that don't fit
+  
+  ... and thereby avoid telling send() to send off more bytes than the
+  size of the buffer!
+  
+  CVE-2017-1000100
+  
+  Bug: https://curl.haxx.se/docs/adv_20170809B.html
+  Reported-by: Even Rouault
+  
+  Credit to OSS-Fuzz for the discovery
+
+- [Even Rouault brought this change]
+
+  file: output the correct buffer to the user
+  
+  Regression brought by 7c312f84ea930d8 (April 2017)
+  
+  CVE-2017-1000099
+  
+  Bug: https://curl.haxx.se/docs/adv_20170809C.html
+  
+  Credit to OSS-Fuzz for the discovery
+
+- easy_events: make event data static
+  
+  First: this function is only used in debug-builds and not in
+  release/real builds. It is used to drive tests using the event-based
+  API.
+  
+  A pointer to the local struct is passed to CURLMOPT_TIMERDATA, but the
+  CURLMOPT_TIMERFUNCTION calback can in fact be called even after this
+  funtion returns, namely when curl_multi_remove_handle() is called.
+  
+  Reported-by: Brian Carpenter
+
+- getparameter: avoid returning uninitialized 'usedarg'
+  
+  Fixes #1728
+
+Marcel Raad (5 Aug 2017)
+- [Isaac Boukris brought this change]
+
+  gssapi: fix memory leak of output token in multi round context
+  
+  When multiple rounds are needed to establish a security context
+  (usually ntlm), we overwrite old token with a new one without free.
+  Found by proposed gss tests using stub a gss implementation (by
+  valgrind error), though I have confirmed the leak with a real
+  gssapi implementation as well.
+  
+  Closes https://github.com/curl/curl/pull/1733
+
+- darwinssl: fix compiler warning
+  
+  clang complains:
+  vtls/darwinssl.c:40:8: error: extra tokens at end of #endif directive
+  [-Werror,-Wextra-tokens]
+  
+  This breaks the darwinssl build on Travis. Fix it by making this token
+  a comment.
+  
+  Closes https://github.com/curl/curl/pull/1734
+
+- CMake: fix CURL_WERROR for MSVC
+  
+  When using CURL_WERROR in MSVC builds, the debug flags were overridden
+  by the release flags and /WX got added twice in debug mode.
+  
+  Closes https://github.com/curl/curl/pull/1715
+
+Daniel Stenberg (4 Aug 2017)
+- RELEASE-NOTES: synced with 561e9217c
+
+- test1010: verify that #1718 is fixed
+  
+  ... by doing two transfers in nocwd mode and check that there's no
+  superfluous CWD command.
+
+- FTP: skip unnecessary CWD when in nocwd mode
+  
+  ... when reusing a connection. If it didn't do any CWD previously.
+  
+  Fixes #1718
+
+Marcel Raad (4 Aug 2017)
+- travis: explicitly specify dist
+  
+  This makes the builds more reproducible as travis is currently rolling
+  out trusty as default dist [1]. Specifically, this avoids coverage
+  check failures when trusty is used as seen in [2] until we figure out
+  what's wrong.
+  
+  [1] https://blog.travis-ci.com/2017-07-11-trusty-as-default-linux-is-coming
+  [2] https://github.com/curl/curl/pull/1692
+  
+  Closes https://github.com/curl/curl/pull/1725
+
+Daniel Stenberg (4 Aug 2017)
+- travis: BUILD_TYPE => T
+  
+  (to make the full line appear nicer on travis web UI)
+
+- travis: add osx build with darwinssl
+  
+  Closes #1706
+
+- darwin: silence compiler warnings
+  
+  With a clang pragma and three type fixes
+  
+  Fixes #1722
+
+- BUILD.WINDOWS: mention buildconf.bat for builds off git
+
+- darwinssl: fix curlssl_sha256sum() compiler warnings on first argument
+
+- test130: verify comments in .netrc
+
+- [Gisle Vanem brought this change]
+
+  netrc: skip lines starting with '#'
+  
+  Bug: https://curl.haxx.se/mail/lib-2017-08/0008.html
+
+Marcel Raad (3 Aug 2017)
+- CMake: set MSVC warning level to 4
+  
+  The MSVC warning level defaults to 3 in CMake. Change it to 4, which is
+  consistent with the Visual Studio and NMake builds. Disable level 4
+  warning C4127 for the library and additionally C4306 for the test
+  servers to get a clean CURL_WERROR build as that warning is raised in
+  some macros in older Visual Studio versions.
+  
+  Ref: https://github.com/curl/curl/pull/1667#issuecomment-314082794
+  Closes https://github.com/curl/curl/pull/1711
+
+Daniel Stenberg (2 Aug 2017)
+- CURLOPT_NETRC.3: fix typo in 7e48aa386156f9c2
+  
+  Reported-by: Viktor Szakats
+
+- CURLOPT_NETRC.3: mention the file name on windows
+  
+  ... and CURLOPT_NETRC_FILE(3).
+
+- travis: build osx with libressl too
+
+- travis: build osx with openssl too
+
+- tests/server/util: fix curltime mistake from 4dee50b9c80f9
+
+Marcel Raad (1 Aug 2017)
+- curl_threads: fix MSVC compiler warning
+  
+  Use LongToHandle to convert from long to HANDLE in the Win32
+  implementation.
+  This should fix the following warning when compiling with
+  MSVC 11 (2012) in 64-bit mode:
+  lib\curl_threads.c(113): warning C4306:
+  'type cast' : conversion from 'long' to 'HANDLE' of greater size
+  
+  Closes https://github.com/curl/curl/pull/1717
+
+Daniel Stenberg (1 Aug 2017)
+- BUGS: improved phrasing about security bugs
+  
+  Reported-by: Max Dymond
+
+- BUGS: clarify how to report security related bugs
+
+- [Brad Spencer brought this change]
+
+  multi: fix request timer management
+  
+  There are some bugs in how timers are managed for a single easy handle
+  that causes the wrong "next timeout" value to be reported to the
+  application when a new minimum needs to be recomputed and that new
+  minimum should be an existing timer that isn't currently set for the
+  easy handle.  When the application drives a set of easy handles via the
+  `curl_multi_socket_action()` API (for example), it gets told to wait the
+  wrong amount of time before the next call, which causes requests to
+  linger for a long time (or, it is my guess, possibly forever).
+  
+  Bug: https://curl.haxx.se/mail/lib-2017-07/0033.html
+
+Jay Satiro (1 Aug 2017)
+- curl_setup: Define CURL_NO_OLDIES for building libcurl
+  
+  .. to catch accidental use of deprecated error codes.
+  
+  Ref: https://github.com/curl/curl/issues/1688#issuecomment-316764237
+
+Daniel Stenberg (1 Aug 2017)
+- [Jeremy Tan brought this change]
+
+  configure: fix the check for IdnToUnicode
+  
+  Fixes #1669
+  Closes #1713
+
+- http: fix response code parser to avoid integer overflow
+  
+  test 1429 and 1433 were updated to work with the stricter HTTP status line
+  parser.
+  
+  Closes #1714
+  Reported-by: Brian Carpenter
+
+Jay Satiro (31 Jul 2017)
+- [Dwarakanath Yadavalli brought this change]
+
+  libcurl: Stop using error codes defined under CURL_NO_OLDIES
+  
+  Fixes https://github.com/curl/curl/issues/1688
+  Closes https://github.com/curl/curl/pull/1712
+
+- include.d: clarify --include is only for response headers
+  
+  Follow-up to 171f8de and de6de94.
+  
+  Bug: https://github.com/curl/curl/commit/de6de94#commitcomment-23370851
+  Reported-by: Daniel Stenberg
+
+Daniel Stenberg (30 Jul 2017)
+- [jasjuang brought this change]
+
+  cmake: support make uninstall
+  
+  Closes #1674
+
+- RELEASE-NOTES: synced with 001701c47
+
+Marcel Raad (29 Jul 2017)
+- AppVeyor: now really use CURL_WERROR
+  
+  It was misspelled as CURL_ERROR in commit
+  2d86e8d1286e0fbe3d811e2e87fa0b5e53722db4.
+  
+  Closes https://github.com/curl/curl/pull/1686
+
+Jay Satiro (29 Jul 2017)
+- tool_help: clarify --include is only for response headers
+  
+  Follow-up to 171f8de.
+  
+  Ref: https://github.com/curl/curl/issues/1704
+
+- splay: fix signed/unsigned mismatch warning
+  
+  Follow-up to 4dee50b.
+  
+  Ref: https://github.com/curl/curl/pull/1693
+
+Daniel Stenberg (28 Jul 2017)
+- include.d: clarify that it concerns the response headers
+  
+  Reported-by: olesteban at github
+  Fixes #1704
+
+- [Johannes Schindelin brought this change]
+
+  curl_rtmp: fix a compiler warning
+  
+  The headers of librtmp declare the socket as `int`, and on Windows, that
+  disagrees with curl_socket_t.
+  
+  Bug: #1652
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- test1323: verify curlx_tvdiff
+
+- timeval: struct curltime is a struct timeval replacement
+  
+  ... to make all libcurl internals able to use the same data types for
+  the struct members. The timeval struct differs subtly on several
+  platforms so it makes it cumbersome to use everywhere.
+  
+  Ref: #1652
+  Closes #1693
+
+- darwinssl: fix variable type mistake (regression)
+  
+  ... which made --tlsv1.2 not work because it would blank the max tls
+  version variable.
+  
+  Reported-by: Nick Miyake
+  Bug: #1703
+
+- multi: mention integer overflow risk if using > 500 million sockets
+  
+  Reported-by: ovidiu-benea@users.noreply.github.com
+  
+  Closes #1675
+  Closes #1683
+
+- checksrc: escape open brace in regex
+  
+  ... to silence warning.
+
+Kamil Dudka (20 Jul 2017)
+- nss: fix a possible use-after-free in SelectClientCert()
+  
+  ... causing a SIGSEGV in showit() in case the handle used to initiate
+  the connection has already been freed.
+  
+  This commit fixes a bug introduced in curl-7_19_5-204-g5f0cae803.
+  
+  Reported-by: Rob Sanders
+  Bug: https://bugzilla.redhat.com/1436158
+
+- nss: unify the coding style of nss_send() and nss_recv()
+  
+  No changes in behavior intended by this commit.
+
+Marcel Raad (18 Jul 2017)
+- tests/server/resolve.c: fix deprecation warning
+  
+  MSVC warns that gethostbyname is deprecated. Always use getaddrinfo
+  instead to fix this when IPv6 is enabled, also for IPv4 resolves. This
+  is also consistent with what libcurl does.
+  
+  Closes https://github.com/curl/curl/pull/1682
+
+Jay Satiro (17 Jul 2017)
+- darwinssl: fix pinnedpubkey build error
+  
+  - s/SessionHandle/Curl_easy/
+  
+  Bug: https://github.com/curl/curl/commit/eb16305#commitcomment-23035670
+  Reported-by: Gisle Vanem
+
+Marcel Raad (16 Jul 2017)
+- rtspd: fix GCC warning after MSVC warning fix
+  
+  Older GCC warns:
+  /tests/server/rtspd.c:1194:10: warning: missing braces around
+  initializer [-Wmissing-braces]
+  
+  Fix this by using memset instead of an initializer.
+
+- libtest: fix MSVC warning C4706
+  
+  With warning level 4, MSVC warns about assignments within conditional
+  expressions. Change the while loop to a do-while loop to fix this. This
+  change is also consistent with CODE_STYLE.md.
+
+- sockfilt: suppress conversion warning with explicit cast
+  
+  MSVC warns when implicitly casting -1 to unsigned long.
+
+- rtspd: fix MSVC level 4 warning
+  
+  warning C4701: potentially uninitialized local variable 'req' used
+
+- winbuild: re-enable warning C4127 for curl tool
+  
+  Disabled in cda19a345f6970e22fe8b7a808aeb8f086a21eac. It only needs to
+  be disabled for libcurl.
+
+- winbuild: build with warning level 4
+  
+  This is consistent with 7bc64561a2e63ca93e4b0b31d350773ba80955c2, which
+  changed the warning level from 3 to 4 for the Visual Studio project
+  files. But disable the level 4 warning C4127 "conditional expression is
+  constant", as that one is issued by older versions of the Windows SDK
+  as well as curl itself under some circumstances.
+  
+  Closes https://github.com/curl/curl/pull/1667
+
+Jay Satiro (12 Jul 2017)
+- [Max Dymond brought this change]
+
+  travis: install libidn2
+  
+  Install libidn2 to increase test coverage (IDN tests)
+  
+  Closes https://github.com/curl/curl/pull/1673
+
+Marcel Raad (12 Jul 2017)
+- travis: enable warnings also in release mode
+  
+  ... to get warnings also on Linux/GCC and OSX/clang.
+  
+  Closes https://github.com/curl/curl/pull/1666
+
+Daniel Stenberg (12 Jul 2017)
+- [Max Dymond brought this change]
+
+  travis: install libssh2
+  
+  Install libssh2 to increase test coverage (SFTP, SCP)
+
+Marcel Raad (12 Jul 2017)
+- system.h: include winsock2.h before windows.h
+  
+  ... to avoid compiler warnings if the user doesn't want
+  WIN32_LEAN_AND_MEAN.
+
+- build: remove WIN32_LEAN_AND_MEAN from individual build systems
+  
+  It's defined for all build systems in curl_setup.h since commit
+  beb08481d01a07a8b10938b1078a5e298b1c2912. This caused macro
+  redefinition warnings in the configure builds.
+  
+  Closes https://github.com/curl/curl/pull/1677
+
+Jay Satiro (11 Jul 2017)
+- ISSUE_TEMPLATE: Add a comment not to file security issues on github
+
+Marcel Raad (11 Jul 2017)
+- curl_setup: always define WIN32_LEAN_AND_MEAN on Windows
+  
+  Make sure to always define WIN32_LEAN_AND_MEAN before including any
+  Windows headers to avoid pulling in unnecessary headers. This avoids
+  unnecessary macro clashes and compiler warnings.
+  
+  Ref: https://github.com/curl/curl/issues/1562
+  Closes https://github.com/curl/curl/pull/1672
+
+Jay Satiro (11 Jul 2017)
+- strerror: Preserve Windows error code in some functions
+  
+  This is a follow-up to af02162 which removed (SET_)ERRNO macros. That
+  commit was an earlier draft that I committed by mistake, which was then
+  remedied by a5834e5 and e909de6, and now this commit. With this commit
+  there is now no difference between the current code and the changes that
+  were approved in the final draft.
+  
+  Thanks-to: Max Dymond, Marcel Raad, Daniel Stenberg, Gisle Vanem
+  Ref: https://github.com/curl/curl/pull/1589
+
+Marcel Raad (10 Jul 2017)
+- [Max Dymond brought this change]
+
+  tests: Fix up issues with errno in test files
+  
+  Closes https://github.com/curl/curl/pull/1671
+
+Daniel Stenberg (10 Jul 2017)
+- errno: fix non-windows builds after af0216251b94e7
+
+- [Ryan Winograd brought this change]
+
+  make: fix docs build on OpenBSD
+  
+  Ref: #1591
+
+Marcel Raad (10 Jul 2017)
+- ldap: fix MinGW compiler warning
+  
+  ldap_bind_s is marked as deprecated in w32api's winldap.h shipping with
+  the latest original MinGW, resulting in compiler warnings since commit
+  f0fe66f13c93d3d0af45d9fb1231c9164e0f9dc8. Fix this for the non-SSPI
+  case by using ldap_simple_bind_s again instead of ldap_bind_s with
+  LDAP_AUTH_SIMPLE.
+  
+  Closes https://github.com/curl/curl/pull/1664
+
+- curl-compilers.m4: disable warning spam with Cygwin's clang
+  
+  When building with Cygwin or MinGW, libtool uses a wrapper executable
+  instead of a wrapper script [1], which is written in C and throws
+  missing-variable-declarations warnings. Don't enable these warnings on
+  Cygwin and MinGW in order to avoid warnings for every executable built,
+  which spams the test suite output when using Cygwin's clang.
+  
+  [1] https://www.gnu.org/software/libtool/manual/html_node/Wrapper-executables.html
+  
+  Closes https://github.com/curl/curl/pull/1665
+
+Jay Satiro (10 Jul 2017)
+- curl_setup_once: Remove ERRNO/SET_ERRNO macros
+  
+  Prior to this change (SET_)ERRNO mapped to GetLastError/SetLastError
+  for Win32 and regular errno otherwise.
+  
+  I reviewed the code and found no justifiable reason for conflating errno
+  on WIN32 with GetLastError/SetLastError. All Win32 CRTs support errno,
+  and any Win32 multithreaded CRT supports thread-local errno.
+  
+  Fixes https://github.com/curl/curl/issues/895
+  Closes https://github.com/curl/curl/pull/1589
+
+- tool_getparam: fix potentially uninitialized err
+
+Marcel Raad (9 Jul 2017)
+- smb: rename variable to fix shadowing warning
+  
+  GCC 4.6.3 on travis complains:
+  smb.c: In function âget_posix_timeâ:
+  smb.c:725:13: error: declaration of âtimeâ shadows a global declaration
+  [-Werror=shadow]
+  
+  Fix this by renaming the variable.
+
+- tool_cb_wrt: fix variable shadowing warning
+  
+  GCC 4.4 complains:
+  tool_cb_wrt.c:81: error: declaration of âisattyâ shadows a global
+  declaration
+  /usr/include/unistd.h:782: error: shadowed declaration is here
+  
+  Fix this by renaming the variable.
+  
+  Closes https://github.com/curl/curl/pull/1661
+
+Daniel Stenberg (8 Jul 2017)
+- RELEASE-NOTES: synced with be2c999b8
+
+- travis: install stunnel
+
+- valgrind.supp: supress OpenSSL false positive seen on travis
+
+- travis: detect and use valgrind for normal builds
+  
+  Closes #1653
+
+- travis: add SMB, DICT, TELNET torture to coverage test
+
+- [Paul Harris brought this change]
+
+  cmake: offer CMAKE_DEBUG_POSTFIX when building with MSVC
+  
+  Removes BUILD_RELEASE_DEBUG_DIRS since it wasn't used anywhere.
+  
+  Closes #1649
+
+- CURLOPT_POSTFIELDS.3: explain the 100-continue magic better
+
+- [Max Dymond brought this change]
+
+  test1452: add telnet negotiation
+  
+  Add a basic telnet server for negotiating some telnet options before
+  echoing back any data that's sent to it.
+  
+  Closes #1645
+
+- travis: do more tests in the coverage run
+  
+  I added a selection of torture and event tests that run "fast enough"
+
+- curl_easy_escape.3: mention the (lack of) encoding
+  
+  Fixes #1612
+  Reported-by: Jeroen Ooms
+
+- [Gisle Vanem brought this change]
+
+  memdebug: don't setbuf() if the file open failed
+  
+  Bug: https://github.com/curl/curl/issues/828#issuecomment-313475151
+
+- appveyor: enable CURL_WERROR on all builds
+
+- cmake: add CURL_WERROR for enabling "warning as errors"
+
+- [Hannes Magnusson brought this change]
+
+  cmake: remove spurious "-l" from linker flags
+  
+  Fixes #1552
+
+- test506: skip if threaded-resolver
+
+- runtests: support "threaded-resolver" as a feature
+  
+  ... to let tests require it or skip if present
+
+- asyn-thread.c: fix unused variable warnings on macOS
+
+- http: s/TINY_INITIAL_POST_SIZE/EXPECT_100_THRESHOLD
+  
+  Make the name reflect its use better, and add a short comment describing
+  what it's for.
+
+- cmake: if inet_pton is used, bump _WIN32_WINNT
+  
+  ... and make sure inet_pton is always checked for when *not* using Windows,
+  which is a regression from 4fc6ebe18.
+  
+  Idea-by: Sergei Nikulov
+
+- select.h: avoid macro redefinition harder
+  
+  ... by checking the POLLIN define, as the header file checks don't work
+  on Windows.
+
+- inet_pton: fix include on windows to get prototype
+  
+  inet_pton() exists on Windows and gets used by our cmake builds. Make
+  sure the correct header file is included to avoid compiler warnings.
+  
+  Closes #1639
+
+- TODO: 1.10 auto-detect proxy
+  
+  Closes #1572
+
+- TODO: HTTP proxy CONNECT is non-blocking now
+
+- cmake: fix send/recv argument scanner for windows
+  
+  ... by simply trying the Windows argument types first.
+  
+  Fixes #1640
+
+- RELEASE-NOTES: synced with 596cfb6c0
+
+- [Gisle Vanem brought this change]
+
+  smb: add support for CURLOPT_FILETIME
+  
+  Bug: https://curl.haxx.se/mail/lib-2017-07/0005.html
+  
+  Closes #1643
+
+- travis: install nghttp2 on linux builds
+  
+  Closes #1642
+
+- [Gisle Vanem brought this change]
+
+  smb: fix build for djgpp/MSDOS
+  
+  bug: https://curl.haxx.se/mail/lib-2017-07/0005.html
+
+- configure: try ldap/lber in reversed order first
+  
+  When scanning for which LDAP libraries to use, try the -lldap -llber
+  combination before the reversed order since it has a greater chance of
+  working when linking with libcurl statically.
+  
+  Fixes #1619
+  Closes #1634
+  Reported-by: David E. NarvÃ¡ez
+
+- configure: remove checks for 5 functions never used
+  
+  fork, getprotobyname, inet_addr, perror, uname
+  
+  closes #1638
+
+- dist: add SMB python deps into the tarball
+
+- [Max Dymond brought this change]
+
+  test1451: add SMB support to the testbed
+  
+  Add test 1451 which does some very basic SMB testing using the impacket
+  SMB server.
+  
+  Closes #1630
+
+- [Max Dymond brought this change]
+
+  test: add impacket for SMB testing
+  
+  Import impacket 0.9.15 for use in SMB testing. This was generated by
+  doing "pip2.7 install -t . impacket"
+  
+  Unnecessary files for current testing were deleted.
+
+- travis.yml: use --enable-werror on debug builds
+  
+  ... to better detect and fault on compiler warnings/errors
+  
+  Closes #1637
+
+- tool_sleep: typecast to avoid macos compiler warning
+  
+  tool_sleep.c:54:24: error: implicit conversion loses integer precision:
+  'long' to '__darwin_suseconds_t' (aka 'int')
+  [-Werror,-Wshorten-64-to-32]
+
+- [Martin Kepplinger brought this change]
+
+  timeval.c: Use long long constant type for timeval assignment
+  
+  On a 64 bit host, sparse says:
+  
+  timeval.c:148:15: warning: constant 0x7fffffffffffffff is so big it is long
+  timeval.c:149:12: warning: constant 0x7fffffffffffffff is so big it is long
+  
+  so let's use long long constant types in order to prevent undesired overflow
+  failures.
+  
+  Bug: https://curl.haxx.se/mail/lib-2017-07/0003.html
+  
+  Closes #1636
+  
+  Signed-off-by: Martin Kepplinger <martink@posteo.de>
+
+- url: make the original string get used on subsequent transfers
+  
+  ... since CURLOPT_URL should follow the same rules as other options:
+  they remain set until changed or cleared.
+  
+  Added test 1551 to verify.
+  
+  Fixes #1631
+  Closes #1632
+  Reported-by: Pavel Rochnyak
+
+- [Johannes Schindelin brought this change]
+
+  gtls: fix build when sizeof(long) < sizeof(void *)
+  
+  - Change gnutls pointer/int macros to pointer/curl_socket_t.
+    Prior to this change they used long type as well.
+  
+  The size of the `long` data type can be shorter than that of pointer
+  types. This is the case most notably on Windows.
+  
+  If C99 were acceptable, we could simply use `intptr_t` here. But we
+  want to retain C89 compatibility.
+  
+  Simply use the trick of performing pointer arithmetic with the NULL
+  pointer: to convert an integer `i` to a pointer, simply take the
+  address of the `i`th element of a hypothetical character array
+  starting at address NULL. To convert back, simply cast the pointer
+  difference.
+  
+  Thanks to Jay Satiro for the initial modification to use curl_socket_t
+  instead of int/long.
+  
+  Closes #1617
+  
+  Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
+
+- [Ryan Winograd brought this change]
+
+  unit1399: fix integer overflow
+  
+  Bug: #1616
+  Closes #1633
+
+- [Per Malmberg brought this change]
+
+  cmake: Added compatibility options for older Windows versions
+  
+  CURL_STATIC_CRT and ENABLE_INET_PTON
+  
+  Closes #1621
+
+- unit1399: add logging to time comparison
+  
+  ... to enable tracking down why autobuilds fail on this
+  
+  Bug: #1616
+
+- make: build the docs subdir only from within src
+  
+  ... and don't build at all in include
+  
+  Prompted-by-work-by: Simon Warta
+  Ref: #1590
+  Closes #1591
+
+- [Max Dymond brought this change]
+
+  test1450: fix up DICT server in torture mode
+  
+  As per https://github.com/curl/curl/pull/1615, the DICT server is a
+  little spammy in torture mode due to the sockets being torn down
+  unexpectedly. Fix this by adding some error handling to the handling
+  function.
+  
+  Closes #1629
+
+- [Max Dymond brought this change]
+
+  test1450: add simple testing for DICT
+  
+  Add a new server which provides a DICT interface. This is intended to
+  begin coverage testing for lib/dict.c
+  
+  Closes #1615
+
+- [Dan Fandrich brought this change]
+
+  test1521: fix out-of-tree builds, broken with 467da3af
+  
+  The test.h file is no longer in the same directory as the source file,
+  so that directory needs to be added to the include path.
+  
+  Fixes #1627
+  Closes #1628
+
+- [Max Dymond brought this change]
+
+  http2: handle PING frames
+  
+  Add a connection check function to HTTP2 based off RTSP. This causes
+  PINGs to be handled the next time the connection is reused.
+  
+  Closes #1521
+
+- [Max Dymond brought this change]
+
+  handler: refactor connection checking
+  
+  Add a new type of callback to Curl_handler which performs checks on
+  the connection. Alter RTSP so that it uses this callback to do its
+  own check on connection health.
+
+- [dmitrykos brought this change]
+
+  openssl: improve fallback seed of PRNG with a time based hash
+  
+  Fixes #1620
+
+- [Ryan Winograd brought this change]
+
+  progress: prevent resetting t_starttransfer
+  
+  Prevent `Curl_pgrsTime` from modifying `t_starttransfer` when invoked
+  with `TIMER_STARTTRANSFER` more than once during a single request.
+  
+  When a redirect occurs, this is considered a new request and
+  `t_starttransfer` can be updated to reflect the `t_starttransfer` time
+  of the redirect request.
+  
+  Closes #1616
+  
+  Bug: https://github.com/curl/curl/pull/1602#issuecomment-310267370
+
+- curl_strequal.3: fix typo in SYNOPSIS
+  
+  Reported-by: Jesse Chisholm
+  
+  Fixes #1623
+
+- RELEASE-NOTES: synced with ce2c3ebda
+
+Kamil Dudka (28 Jun 2017)
+- curl --socks5-{basic,gssapi}: control socks5 auth
+  
+  Closes https://github.com/curl/curl/pull/1454
+
+- CURLOPT_SOCKS5_AUTH: allowed methods for SOCKS5 proxy auth
+  
+  If libcurl was built with GSS-API support, it unconditionally advertised
+  GSS-API authentication while connecting to a SOCKS5 proxy.  This caused
+  problems in environments with improperly configured Kerberos: a stock
+  libcurl failed to connect, despite libcurl built without GSS-API
+  connected fine using username and password.
+  
+  This commit introduces the CURLOPT_SOCKS5_AUTH option to control the
+  allowed methods for SOCKS5 authentication at run time.
+  
+  Note that a new option was preferred over reusing CURLOPT_PROXYAUTH
+  for compatibility reasons because the set of authentication methods
+  allowed by default was different for HTTP and SOCKS5 proxies.
+  
+  Bug: https://curl.haxx.se/mail/lib-2017-01/0005.html
+  Closes https://github.com/curl/curl/pull/1454
+
+- socks: deduplicate the code for auth request
+
+- socks: use proxy_user instead of proxy_name
+  
+  ... to make it obvious what the data is used for
+
+Daniel Stenberg (27 Jun 2017)
+- libtest/make: generate lib1521.c
+  
+  ... instead of having the generated code checked in. This saves space in
+  the tarball but primarily automatically adapts to newly added options.
+  
+  Closes #1614
+
+Jay Satiro (26 Jun 2017)
+- tool_getparam: fix memory leak on test 1147 OOM (torture tests)
+  
+  Bug: https://github.com/curl/curl/pull/1486#issuecomment-310926872
+  Reported-by: Dan Fandrich
+
+Dan Fandrich (25 Jun 2017)
+- test1537: fixed memory leak on OOM
+
+Marcel Raad (25 Jun 2017)
+- test1521: fix compiler warnings
+  
+  The integer literal 3123123123 doesn't fit into a 32-bit signed
+  integer, so GCC with 32-bit long warns in C90 mode:
+  this decimal constant is unsigned only in ISO C90 [enabled by default]
+  Fix this by using ULONG_MAX, which should fit in any curl_off_t and has
+  the correct suffix to not issue any warnings.
+  Also adds the missing CURLOPT_REQUEST_TARGET from commit
+  9b167fd090f596eac828817d48c247eeae53407f.
+  
+  Closes https://github.com/curl/curl/pull/1611
+
+Daniel Stenberg (24 Jun 2017)
+- curl/system.h: add check for XTENSA for 32bit gcc
+  
+  Reported-by: Neil Kolban
+  Fixes: 1598
+
+- [Henrik S. GaÃmann brought this change]
+
+  winbuild: fix boringssl build
+  
+  Compile with `WIN32_LEAN_AND_MEAN` which prevents `windows.h` from
+  including too much clutter including `wincrypt.h` which in turn contains
+  some preprocessor macros that clash with boringssl symbols.
+  
+  Detect boringssl by checking the existance of `is_boringssl.h` and set
+  the corresponding `HAVE_BORINGSSL` for compilation which is used in
+  `ldap.c` to undefine the evil macros.
+  
+  Closes #1610
+
+- progress: progress.timespent needs to be us
+  
+  follow-up to 64ed44a815e4e to fix test 500 failures
+
+Marcel Raad (24 Jun 2017)
+- curl-compilers.m4: fix unknown-warning-option on Apple clang
+  
+  Since 5598b0bd63f690c151074494ce47ef872f004ab4, clang -v is used to
+  detect the clang version. The version number was expected to come after
+  the word "version". For Apple clang, this doesn't work as it has its
+  own versioning scheme.
+  The version number is now first searched after the string
+  "based on LLVM". This works for Apple clang before version 7, and also
+  for e.g. Ubuntu's clang up to version 3.7. If it's not found and the
+  version string contains "Apple LLVM version", clang version 3.7 is
+  assumed, which is the version that comes with Xcode 7. Otherwise, the
+  version number is still expected after the word "version", which works
+  for very old Apple clang versions.
+  
+  Ref: https://trac.macports.org/wiki/XcodeVersionInfo
+  Fixes https://github.com/curl/curl/issues/1606
+  Closes https://github.com/curl/curl/pull/1607
+
+Daniel Stenberg (24 Jun 2017)
+- progress: fix "time spent", broke in adef394ac
+
+- CURLINFO_REDIRECT_URL.3: mention the CURLOPT_MAXREDIRS case
+  
+  ... supported since 7.54.1
+
+- maketgz: switch to -6e for xz
+  
+  To reduce the memory requirement for decompress, and still do almost as
+  good compression as with -9e.
+  
+  Pointed-out-by: Dan Fandrich
+
+- libtest/Makefile: remove unused lib1541 variables
+
+- CONTRIBUTE.md: mention the out-of-tree build test too
+
+- maketgz: switch to xz instead of lzma
+  
+  The compressed output size seems to be a tad bit smaller, but generally
+  xz seems more preferred these days and is used directly by for example
+  gentoo instead of bz2.
+  
+  "Users of LZMA Utils should move to XZ Utils" =>
+  https://tukaani.org/lzma/
+  
+  Closes #1604
+
+- --request-target: instead of --strip-path-slash
+  
+  ... and CURLOPT_REQUEST_TARGET instead of CURLOPT_STRIP_PATH_SLASH.
+  
+  This option instead provides the full "alternative" target to use in the
+  request, instead of extracting the path from the URL.
+  
+  Test 1298 and 1299 updated accordingly.
+  
+  Idea-by: Evert Pot
+  Suggestion: https://daniel.haxx.se/blog/2017/06/19/options-with-curl/comment-page-1/#comment-18373
+  
+  Closes #1593
+
+Marcel Raad (21 Jun 2017)
+- lib1521: fix missing-variable-declarations clang warnings
+  
+  Declare TU-local variables static.
+
+- travis: enable typecheck-gcc warnings
+  
+  - switch debug and release configurations so that we get an optimized
+    build with GCC 4.3+ as required by typecheck-gcc
+  - enable warnings-as-errors for release builds
+    (which have warnings disabled)
+  
+  Closes https://github.com/curl/curl/pull/1595
+
+- typecheck-gcc: add support for CURLINFO_OFF_T
+  
+  typecheck-gcc expected curl_socket_t instead of curl_off_t arguments
+  for CURLINFO_OFF_T. Detected by test1521, unfortunately only when run
+  locally.
+  
+  Closes https://github.com/curl/curl/pull/1592
+
+Daniel Stenberg (21 Jun 2017)
+- [Simon Warta brought this change]
+
+  ci: whitelist branches to avoid testing feature branches twice
+
+- [Gisle Vanem brought this change]
+
+  lib: fix the djgpp build
+  
+  Bug: https://github.com/curl/curl/commit/73a2fcea0b4adea6ba342cd7ed1149782c214ae3#commitcomment-22655993
+
+Marcel Raad (20 Jun 2017)
+- if2ip: fix compiler warning in ISO C90 mode
+  
+  remote_scope_id is only used when both HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+  and ENABLE_IPV6 are defined instead of only one of them.
+
+Daniel Stenberg (20 Jun 2017)
+- travis: do the distcheck test build out-of-tree as well
+
+- http: add --strip-path-slash and CURLOPT_STRIP_PATH_SLASH
+  
+  ... to enable sending "OPTIONS *" which wasn't possible previously.
+  
+  This option currently only works for HTTP.
+  
+  Added test cases 1298 + 1299 to verify
+  
+  Fixes #1280
+  Closes #1462
+
+- test1521: test getinfo's OFF_T types too
+  
+  Closes #1588
+
+- lib1521: add curl_easy_getinfo calls to the test set
+  
+  Also added return value checks to make sure no unexpected return codes
+  are used.
+
+- [Simon Warta brought this change]
+
+  automake: use $(MKHELP) variable instead if constant mkhelp.pl
+  
+  this improves symmetry with the rule above
+
+- [Simon Warta brought this change]
+
+  mkhelp.pl: fix script name in usage text
+
+- RELEASE-NOTES: synced with 3b80d3ca4
+
+- getinfo: return sizes as curl_off_t
+  
+  This change introduces new alternatives for the existing six
+  curl_easy_getinfo() options that return sizes or speeds as doubles. The
+  new versions are named like the old ones but with an appended '_T':
+  
+  CURLINFO_CONTENT_LENGTH_DOWNLOAD_T
+  CURLINFO_CONTENT_LENGTH_UPLOAD_T
+  CURLINFO_SIZE_DOWNLOAD_T
+  CURLINFO_SIZE_UPLOAD_T
+  CURLINFO_SPEED_DOWNLOAD_T
+  CURLINFO_SPEED_UPLOAD_T
+  
+  Closes #1511
+
+- PIPELINING_SERVER_BL: cleanup the internal list use
+  
+  The list was freed incorrectly since the llist refactor of
+  cbae73e1dd959. Added test 1550 to verify that it works and avoid future
+  regressions.
+  
+  Reported-by: Pascal Terjan
+  
+  Fixes #1584
+  Closes #1585
+
+- http2: fix OOM crash
+  
+  torture mode with test 1021 found it
+
+- CURLOPT_PREQUOTE.3: spellfix man page reference
+
+Marcel Raad (18 Jun 2017)
+- http_proxy: fix build with http and proxy
+  
+  After deff7de0eb0e22d2d142b96b9cc84cd8db5d2a48, the build without
+  CURL_DISABLE_PROXY and CURL_DISABLE_HTTP was failing because of missing
+  includes.
+
+- http_proxy: fix compiler warning
+  
+  With CURL_DISABLE_PROXY or CURL_DISABLE_HTTP, GCC complained about a
+  missing prototype for Curl_connect_free.
+
+Daniel Stenberg (18 Jun 2017)
+- TODO: update the TOC too
+
+- TODO: implement support for CURLOPT_PREQUOTE with SFTP
+  
+  ... also updated the CURLOPT_PREQUOTE.3 man page to mention the correct
+  protocol support.
+  
+  Closes #1514
+
+- tool_wrte_cb: remove check for config == NULL
+  
+  ... as it really cannot have reached this far with config being NULL,
+  thus this is unnecesary and misleading.
+  
+  Bug: https://news.ycombinator.com/item?id=14577585 and
+  https://daniel.haxx.se/blog/2017/06/17/curl-doesnt-spew-binary-anymore/comment-page-1/#comment-18356
+  
+  Forwarded-to-us-by: Jakub Wilk
+
+- curl: prevent binary output spewed to terminal
+  
+  ... unless "--output -" is used. Binary detection is done by simply
+  checking for a binary zero in early data.
+  
+  Added test 1425 1426 to verify.
+  
+  Closes #1512
+
+Marcel Raad (16 Jun 2017)
+- Makefile.m32: enable -W for MinGW32 build
+  
+  The configure-based build also has this in addition to -Wall.
+  
+  Closes https://github.com/curl/curl/pull/1578
+
+- curl-compilers.m4: enable comma clang warning
+  
+  It usually warns when using commas instead of semicolons or other
+  operators by accident.
+  
+  Closes https://github.com/curl/curl/pull/1578
+
+- curl-compilers.m4: enable missing-variable-declarations clang warning
+  
+  It usually warns when forgetting to declare TU-local variables static.
+  
+  Closes https://github.com/curl/curl/pull/1578
+
+- curl-compilers.m4: enable double-promotion warning
+  
+  Enable -Wdouble-promotion for both GCC and clang. It warns on implicit
+  promotion from float to double.
+  
+  Closes https://github.com/curl/curl/pull/1578
+
+- curl-compilers.m4: enable vla warning for clang
+  
+  Previously, that warning was only implicitly active in C90 mode.
+  Enable it unconditionally as already done for GCC.
+  
+  Closes https://github.com/curl/curl/pull/1578
+
+Daniel Stenberg (16 Jun 2017)
+- http-proxy: fix chunked-encoded CONNECT responses
+  
+  Regression since 5113ad0424.
+  
+  ... and remove 'flaky' from test 1061 again
+  
+  Closes #1579
+
+- http-proxy: deal with EAGAIN
+  
+  ... the previous code would reset the header length wrongly (since
+  5113ad0424). This makes test 1060 reliable again.
+  
+  Also: make sws send even smaller chunks of data to increase the
+  likeliness of this happening.
+
+- libtest/libntlmconnect: fix compiler warnings from f94fcdb
+
+- [Jay Satiro brought this change]
+
+  HTTPS-Proxy: don't offer h2 for https proxy connections
+  
+  Bug: https://github.com/curl/curl/issues/1254
+  
+  Closes #1546
+
+- tests: stabilize test 2032 and 2033
+  
+  Both these tests run the same underlying test code: libntlmconnect.c -
+  this test code made some assumptions about socket ordering when it used
+  curl_easy_fdset() and when we changed timing or got accidental changes
+  in libcurl the tests would fail.
+  
+  The tests verify that the different transfers keep using the same
+  connections, which I now instead made sure by adding the number of bytes
+  each transfer gets and then verifies that they always get the same
+  amount as when these tests worked.
+  
+  Closes #1576
+
+- test1148: verify the -# progressbar
+  
+  Closes #1569
+
+- test1061: mark as flaky
+  
+  Fails intermittently on travis builds since a few days. Likely due to
+  5113ad0424.
+
+Jay Satiro (16 Jun 2017)
+- url: refactor the check for Windows drive letter in path
+  
+  - Move the logic to detect a Windows drive letter prefix
+    (eg c: in c:foo) into a function-like macro.
+  
+  Closes https://github.com/curl/curl/pull/1571
+
+- mk-ca-bundle.pl: Check curl's exit code after certdata download
+  
+  - No longer allow partial downloads of certdata.
+  
+  Prior to this change partial downloads were (erroneously?) allowed since
+  only the server code was checked to be 200.
+  
+  Bug: https://github.com/curl/curl/pull/1577
+  Reported-by: Matteo B.
+
+Daniel Stenberg (16 Jun 2017)
+- dist: add the fuzz dir to the tarball
+
+- configure: disable nghttp2 too if HTTP has been disabled
+
+- http-proxy: fix build with --disable-proxy or --disable-http
+  
+  Reported-by: Dan Fandrich
+
+- fuzz/README: document how to build
+  
+  Fixes #1476
+
+- [Frederik B brought this change]
+
+  fuzz: corpora file structure, initial commit
+
+- [Frederik B brought this change]
+
+  fuzz: bring oss-fuzz initial code converted to C89
+
+- http-proxy: only attempt FTP over HTTP proxy
+  
+  ... all other non-HTTP protocol schemes are now defaulting to "tunnel
+  trough" mode if a HTTP proxy is specified. In reality there are no HTTP
+  proxies out there that allow those other schemes.
+  
+  Assisted-by: Ray Satiro, Michael Kaufmann
+  
+  Closes #1505
+
+- TODO: the generated include file is gone
+  
+  ... since commit 73a2fcea0b
+
+- curl_setup.h: error out on CURL_WANTS_CA_BUNDLE_ENV use
+  
+  ... to make it really apparent if there's any user using this on purpose.
+  
+  Suggested-by: Jay Satiro
+  
+  Closes #1542
+
+- lib/curl_setup.h: remove CURL_WANTS_CA_BUNDLE_ENV
+  
+  When this define was set, libcurl would check the environment variable
+  named CURL_CA_BUNDLE at run-time and use that CA cert bundle. This
+  feature was only defined by the watcom and m32 makefiles and caused
+  inconsistent behaviours among libcurls built on different platforms.
+  
+  The curl tool does already feature its own similar logic and the library
+  does not really need it, and it isn't documented libcurl behavior. So
+  this change removes it.
+  
+  Ref: #1538
+
+- test1147: verify -H on a file
+
+- curl: allow --header and --proxy-header read from file
+  
+  So many headers can be provided as @filename.
+  
+  Suggested-by: Timothe Litt
+  
+  Closes #1486
+
+- RELEASE-NOTES: synced with 2ad80eec5
+
+- curl/curlver.h: start working on 7.55.0
+
+- http-proxy: do the HTTP CONNECT process entirely non-blocking
+  
+  Mentioned as a problem since 2007 (8f87c15bdac63) and of course it
+  existed even before that.
+  
+  Closes #1547
+
+- progress: let "current speed" be UL + DL speeds combined
+  
+  Bug #1556
+  Reported-by: Paul Harris
+  Closes #1559
+
+Marcel Raad (14 Jun 2017)
+- system.h: fix MinGW build
+  
+  CURLSYS_PULL_WS2TCPIP_H got renamed to CURL_PULL_WS2TCPIP_H in commit
+  73a2fcea0b4adea6ba342cd7ed1149782c214ae3.
+
+Daniel Stenberg (14 Jun 2017)
+- timers: store internal time stamps as time_t instead of doubles
+  
+  This gives us accurate precision and it allows us to avoid storing "no
+  time" for systems with too low timer resolution as we then bump the time
+  up to 1 microsecond. Should fix test 573 on windows.
+  
+  Remove the now unused curlx_tvdiff_secs() function.
+  
+  Maintains the external getinfo() API with using doubles.
+  
+  Fixes #1531
+
+- dist: make the hugehelp.c not get regenerated unnecessarily
+  
+  The maketgz script now makes sure the generated hugehelp.c file in the
+  tarball is newer than the generated curl.1 man page, so that it doesn't
+  have to get unnecessarily rebuilt first thing in a typical build. It
+  thus also removes the need for perl to build off a plain release
+  tarball.
+  
+  Fixes #1565
+
+- includes: remove curl/curlbuild.h and curl/curlrules.h
+  
+  Rely entirely on curl/system.h now.
+  
+  Introduced in Aug 2008 with commit 14240e9e109f. Now gone.
+  
+  Fixes #1456
+
+Version 7.54.1 (14 Jun 2017)
+
+Daniel Stenberg (14 Jun 2017)
+- release: 7.54.1
+
+Dan Fandrich (13 Jun 2017)
+- mk-lib1521.pl: updated to match the test changes in 916ec30a
+
+Daniel Stenberg (13 Jun 2017)
+- [Stuart Henderson brought this change]
+
+  libressl: OCSP and intermediate certs workaround no longer needed
+  
+  lib/vtls/openssl.c has a workaround for a bug with OCSP responses signed
+  by intermediate certs, this was fixed in LibreSSL in
+  https://github.com/libressl-portable/openbsd/commit/912c64f68f7ac4f225b7d1fdc8fbd43168912ba0
+  
+  Bug: https://curl.haxx.se/mail/lib-2017-06/0038.html
+
+- url: fix buffer overwrite with file protocol (CVE-2017-9502)
+  
+  Bug: https://github.com/curl/curl/issues/1540
+  Advisory: https://curl.haxx.se/docs/adv_20170614.html
+  
+  Assisted-by: Ray Satiro
+  Reported-by: Marcel Raad
+
+- urlglob: fix division by zero
+  
+  The multiply() function that is used to avoid integer overflows, was
+  itself reason for a possible division by zero error when passed a
+  specially formatted glob.
+  
+  Reported-by: GwanYeong Kim
+
+- configure: update the copyright year in the output
+
+- [ygrek brought this change]
+
+  BINDINGS: update SP-Forth and OCaml urls
+
+Michael Kaufmann (11 Jun 2017)
+- FindWin32CACert: Use a temporary buffer on the stack
+  
+  Don't malloc() the temporary buffer, and use the correct type:
+  SearchPath() works with TCHAR, but SearchPathA() works with char.
+  Set the buffer size to MAX_PATH, because the terminating null byte
+  is already included in MAX_PATH.
+  
+  Reviewed-by: Daniel Stenberg
+  Reviewed-by: Marcel Raad
+  
+  Closes #1548
+
+Dan Fandrich (11 Jun 2017)
+- test1521: fixed OOM handling
+
+Daniel Stenberg (9 Jun 2017)
+- RELEASE-PROCEDURE: updated future release dates
+
+- [Paul Harris brought this change]
+
+  gitignore: ignore all vim swap files
+  
+  Closes #1561
+
+- lib1521: fix compiler warnings on the use of bad 'long' values
+  
+  Reported-by: Marcel Raad
+  Bug: https://github.com/curl/curl/commit/cccac4fb2b20d6ed87da7978408c3ecacc464fe4#commitcomment-22453387
+
+- setopt: check CURLOPT_ADDRESS_SCOPE option range
+  
+  ... and return error instead of triggering an assert() when being way
+  out of range.
+
+Jay Satiro (8 Jun 2017)
+- [TheAssassin brought this change]
+
+  cmake: Fix inconsistency regarding mbed TLS include directory
+  
+  Previously, one had to set MBEDTLS_INCLUDE_DIR to make CMake find the
+  headers, but the system complained that mbed TLS wasn't found due to
+  MBEDTLS_INCLUDE_DIRS (note the trailing s) was not set. This commit
+  attempts to fix that.
+  
+  Closes https://github.com/curl/curl/pull/1541
+
+Daniel Stenberg (8 Jun 2017)
+- [Ryuichi KAWAMATA brought this change]
+
+  examples/multi-uv.c: fix deprecated symbol
+  
+  Closes #1557
+
+- asyn-ares: s/Curl_expire_latest/Curl_expire
+
+- expire: remove Curl_expire_latest()
+  
+  With the introduction of expire IDs and the fact that existing timers
+  can be removed now and thus never expire, the concept with adding a
+  "latest" timer is not working anymore as it risks to not expire at all.
+  
+  So, to be certain the timers actually are in line and will expire, the
+  plain Curl_expire() needs to be used. The _latest() function was added
+  as a sort of shortcut in the past that's quite simply not necessary
+  anymore.
+  
+  Follow-up to 31b39c40cf90
+  
+  Reported-by: Paul Harris
+  
+  Closes #1555
+
+- [Chris Carlmar brought this change]
+
+  configure: fix link with librtmp when specifying path
+  
+  Bug: https://curl.haxx.se/mail/lib-2017-06/0017.html
+
+- file: make speedcheck use current time for checks
+  
+  ... as it would previously just get the "now" timestamp before the
+  transfer starts and then not update it again.
+  
+  Closes #1550
+
+- metalink: remove unused printf() argument
+
+- travis: let some builds *not* use --enable-debug
+  
+  typecheck-gcc and other things require optimized builds
+  
+  Closes #1544
+
+- README.md: show the coverall coverage on github
+
+- lib1521: fix compiler warnings
+
+- test1521: make the code < 80 columns wide
+
+- test1121: use stricter types to work with typcheck-gcc
+
+- typecheck-gcc: allow CURLOPT_STDERR to be NULL too
+
+- test1521: test *all* curl_easy_setopt options
+  
+  mk-lib1521.pl generates a test program (lib1521.c) that calls
+  curl_easy_setopt() for every known option with a few typical values to
+  make sure they work (ignoring the return codes).
+  
+  Some small changes were necessary to avoid asserts and NULL accesses
+  when doing this.
+  
+  The perl script needs to be manually rerun when we add new options.
+  
+  Closes #1543
+
+Dan Fandrich (5 Jun 2017)
+- test1538: added "verbose logs" keyword
+  
+  These error messages are not displayed with --disable-verbose
+
+Daniel Stenberg (5 Jun 2017)
+- test1262: verify ftp download with -z for "if older than this"
+
+Marcel Raad (5 Jun 2017)
+- curl_ntlm_core: use Curl_raw_toupper instead of toupper
+  
+  This was the only remaining use of toupper in the entire source code.
+  
+  Suggested-by: Daniel Stenberg
+
+Daniel Stenberg (4 Jun 2017)
+- RELEASE-NOTES: synced with 65ba92650
+
+Marcel Raad (4 Jun 2017)
+- curl_ntlm_core: pass unsigned char to toupper
+  
+  Otherwise, clang on Cygwin64 warns:
+  curl_ntlm_core.c:525:35: error: array subscript is of type 'char'
+  [-Werror,-Wchar-subscripts]
+      dest[2 * i] = (unsigned char)(toupper(src[i]));
+                                    ^~~~~~~~~~~~~~~
+  /usr/include/ctype.h:152:25: note: expanded from macro 'toupper'
+        (void) __CTYPE_PTR[__x]; (toupper) (__x);})
+                          ^~~~
+
+Jay Satiro (3 Jun 2017)
+- [Mahmoud Samir Fayed brought this change]
+
+  BINDINGS: add Ring binding
+  
+  Closes https://github.com/curl/curl/pull/1539
+
+Daniel Stenberg (4 Jun 2017)
+- CONTRIBUTE.md: mention tests done on pull requests
+
+- travis: add coverage, distcheck and cmake builds
+  
+  Closes #1534
+
+Marcel Raad (3 Jun 2017)
+- libtest: fix int-in-bool-context warnings
+  
+  GCC 7 complained:
+  â*â in boolean context, suggest â&&â instead [-Wint-in-bool-context]
+
+- libtest: fix implicit-fallthrough warnings with GCC 7
+
+- x509asn1: fix implicit-fallthrough warning with GCC 7
+
+- curl_sasl: fix unused-variable warning
+  
+  This fixes the following warning with CURL_DISABLE_CRYPTO_AUTH,
+  as seen in the autobuilds:
+  
+  curl_sasl.c:417:9: warning: unused variable 'serverdata'
+  [-Wunused-variable]
+
+Daniel Stenberg (3 Jun 2017)
+- updatemanpages.pl: error out on too old git version
+
+Marcel Raad (3 Jun 2017)
+- cyassl: define build macros before including ssl.h
+  
+  cyassl/ssl.h needs the macros from cyassl/options.h, so define them
+  before including cyassl/ssl.h the first time, which happens in
+  urldata.h.
+  This broke the build on Ubuntu Xenial, which comes with WolfSSL 3.4.8
+  and therefore redefines the symbols from cyassl/options.h instead of
+  including the header.
+  
+  Closes https://github.com/curl/curl/pull/1536
+
+Daniel Stenberg (3 Jun 2017)
+- tool_util: remove unused tvdiff_secs and remove tool_ prefix
+  
+  Closes #1532
+
+- dedotdot: fixed output for ".." and "." only input
+  
+  Found when updating test 1395, which I did to increase test coverage of
+  this source file...
+  
+  Closes #1535
+
+Marcel Raad (2 Jun 2017)
+- mbedtls: make TU-local variable static
+  
+  mbedtls_x509_crt_profile_fr is only used locally.
+  This fixes a missing-variable-declarations warning with clang.
+
+- MD(4|5): silence cast-align clang warning
+  
+  Unaligned access is on purpose here and the warning is harmless on
+  affected architectures. GCC knows that, while clang warns on all
+  architectures.
+
+Daniel Stenberg (2 Jun 2017)
+- test1538: fix typo
+
+- test1538: verify the libcurl strerror API calls
+
+- curl_endian: remove unused functions
+  
+  Closes #1529
+
+- test1537: dedicated tests of the URL (un)escape API calls
+  
+  Closes #1530
+
+- coverage: run event tests too
+  
+  ... the torture ones are commented out only because they are slooooow.
+
+- build: provide easy code coverage measuring
+  
+  Closes #1528
+
+- typecheck-gcc.h: check CURLINFO_CERTINFO
+  
+  ... and update the certinfo.c example accordingly.
+  
+  Fixes https://github.com/curl/curl/issues/846
+
+- typecheck-gcc.h: check CURLINFO_TLS_SSL_PTR and CURLINFO_TLS_SESSION
+  
+  ... so that they get the required "struct curl_tlssessioninfo **"
+  arguments.
+
+- typecheck-gcc.h: separate getinfo slist checks from other pointers
+  
+  Fixes #1524
+
+Marcel Raad (1 Jun 2017)
+- curl-compilers.m4: escape square brackets in regex
+  
+  Otherwise, they are removed in the final configure file.
+  Also changed sed to "$SED" like in most other calls in this file.
+
+- curl-compilers.m4: fix compiler_num for clang
+  
+  "clang -dumpversion" always returns "4.2.1", the GCC version that clang
+  was initially compatible to. Use "clang -v" instead, which returns the
+  actual clang version.
+  
+  Fixes https://github.com/curl/curl/issues/1522
+  Closes https://github.com/curl/curl/pull/1523
+
+Daniel Stenberg (31 May 2017)
+- examples/externalsocket.c: s/closesocket/closecb
+  
+  ... since closesocket is a function in WinSock.
+  
+  Reported-by: Marcel Raad
+  Bug: https://github.com/curl/curl/commit/55fcb8485914700132fd1854c9509b66c955efbe#co
+  mmitcomment-22347818
+
+Marcel Raad (31 May 2017)
+- lib583: fix compiler warning
+  
+  Use CURLMcode for variable 'res' and cast to int where necessary
+  instead of the other way around. Other tests do the same.
+  
+  This fixes the following clang warning:
+  lib583.c:68:15: warning: cast from function call of type 'CURLMcode' to
+  non-matching type 'int' [-Wbad-function-cast]
+
+Daniel Stenberg (31 May 2017)
+- CURLOPT_SSH_KEY*.3: typos
+  
+  Reported-by: Gisle Vanem
+
+- CURLOPT_STREAM_DEPENDS.3: typo
+
+- CURLOPT_FNMATCH_FUNCTION.3: also modified example to avoid fcpp issues
+
+- CURLOPT_FNMATCH_DATA.3: modified example to avoid fcpp issues
+
+- opts: more than 100 more examples for man pages...
+
+- libtest/lib574.c: use correct callback proto
+
+- examples/sampleconv.c: indent changes, made callbacks static
+
+- example/externalsocket.c: make it use CLOSESOCKETFUNCTION too
+
+Marcel Raad (31 May 2017)
+- curl-compilers.m4: enable -Wshift-sign-overflow for clang
+  
+  clang 2.9+ supports -Wshift-sign-overflow, which warns about undefined
+  behavior on signed left shifts when shifting by too many places.
+  
+  Ref: https://github.com/curl/curl/issues/1516
+  Closes https://github.com/curl/curl/pull/1517
+
+Daniel Stenberg (31 May 2017)
+- CURLOPT_PROXY.3: fix test 1140 breakage
+
+Jay Satiro (31 May 2017)
+- build-wolfssl: Sync config with wolfSSL 3.11
+  
+  wolfSSL configure script relevant changes from 3.10 to 3.11:
+  
+  - Async threading support added; disabled by default without async
+    crypto, which continues to be disabled by default.
+  
+  wolfSSL configure script relevant changes from 3.11 to 3.11.1 (beta):
+  
+  - TLS 1.3 beta support added; disabled by default.
+  
+  For experimenting I put in a comment block the defines needed to enable
+  TLS 1.3 support (ie the equivalent of --enable-tls13).
+
+Daniel Stenberg (30 May 2017)
+- opts: more examples added to man pages
+
+- docs: clarify NO_PROXY further
+  
+  Fixes #1208
+
+- CURLOPT_PROXY.3: describe the environment variables more
+
+- transfer: init the infilesize from the postfields...
+  
+  ... with a strlen() if no size was set, and do this in the pretransfer
+  function so that the info is set early. Otherwise, the default strlen()
+  done on the POSTFIELDS data never sets state.infilesize.
+  
+  Reported-by: Vincas Razma
+  Bug: #1294
+
+Jay Satiro (29 May 2017)
+- test557: fix ubsan runtime error due to int left shift
+  
+  - Test curl_msnprintf negative int width arg using INT_MIN instead of
+    1 << 31 which is undefined behavior.
+  
+  Closes https://github.com/curl/curl/issues/1516
+
+- mbedtls: fix variable shadow warning
+  
+  vtls/mbedtls.c:804:69: warning: declaration of 'entropy' shadows a global declaration [-Wshadow]
+   CURLcode Curl_mbedtls_random(struct Curl_easy *data, unsigned char *entropy,
+                                                                       ^~~~~~~
+
+Daniel Stenberg (29 May 2017)
+- RELEASE-NOTES: synced with 3aaac8c2f
+
+Dan Fandrich (28 May 2017)
+- tests: removed some redundant empty <stdout> sections
+
+- runtests.pl: removed <precommand> feature
+  
+  This hasn't been used in over a decade. <precheck> can still be used to
+  run commands before the main test.
+
+Daniel Stenberg (27 May 2017)
+- opts: more examples added in option man pages
+
+Dan Fandrich (27 May 2017)
+- runtests.pl: removed unused arguments to valgrindparse
+
+Daniel Stenberg (25 May 2017)
+- TODO: 6.4 is done, send telnet data in chunks
+
+- [Phil Crump brought this change]
+
+  docs/CURLOPT_SSLVERSION.3: Correct define name in example
+  
+  Closes #1509
+
+- ssh: fix 'left' may be used uninitialized
+  
+  follow-up to f31760e63b4e
+  
+  Reported-by: Michael Kaufmann
+  Bug: https://github.com/curl/curl/pull/1495#issuecomment-303982793
+
+Michael Kaufmann (24 May 2017)
+- time: fix type conversions and compiler warnings
+  
+  Fix bugs and compiler warnings on systems with 32-bit long and
+  64-bit time_t.
+  
+  Reviewed-by: Daniel Stenberg
+  
+  Closes #1499
+
+Marcel Raad (24 May 2017)
+- examples: fix Wimplicit-fallthrough warnings
+  
+  This is contained in -Wextra with GCC 7.
+
+Daniel Stenberg (24 May 2017)
+- [Anatol Belski brought this change]
+
+  winbuild: fix the nghttp2 build
+  
+  Closes #1321
+
+GitHub (24 May 2017)
+- [Sergei Nikulov brought this change]
+
+  LDAP: documentation update per #878 changes (#1506)
+
+Daniel Stenberg (23 May 2017)
+- redirect: store the "would redirect to" URL when max redirs is reached
+  
+  Test 1261 added to verify.
+  
+  Reported-by: Lloyd Fournier
+  
+  Fixes #1489
+  Closes #1497
+
+GitHub (24 May 2017)
+- [Sergei Nikulov brought this change]
+
+  LDAP: fixed checksrc issue
+
+- [Sergei Nikulov brought this change]
+
+  LDAP: using ldap_bind_s on Windows with methods (#878)
+  
+  * LDAP: using ldap_bind_s on Windows with methods(BASIC/DIGEST/NTLM/AUTONEG)
+  
+  * ldap: updated per build options handling
+  
+  * ldap: fixed logic for auth selection
+
+Daniel Stenberg (23 May 2017)
+- [Akhil Kedia brought this change]
+
+  cmake: fix build on Ubuntu 14.04
+  
+  Fixed a syntax error with setting cache variables (The type and
+  docstring were missing), resulting in build errors.  Quoted the
+  CURL_CA_PATH and CURL_CA_BUNDLE otherwise the path was written without
+  quotes in C code, resulting in build errors.
+  
+  Closes #1503
+  
+  Signed-off-by: Akhil <akhil.kedia@samsung.com>
+
+- url: fix declaration of 'pipe' shadows a global declaration
+  
+  follow-up to 4cdb1be8246c
+
+Kamil Dudka (22 May 2017)
+- memdebug: fix compilation failure
+  
+  .... caused by a typo in the last commit (fixing issue #1504):
+  
+  memdebug.c: In function âcurl_fcloseâ:
+  memdebug.c:444:3: error: implicit declaration of function
+  âDEBUGDEBUGASSERTâ [-Werror=implicit-function-declaration]
+
+Daniel Stenberg (22 May 2017)
+- assert: avoid, use DEBUGASSERT instead!
+  
+  ... as it does extra checks to actually work.
+  
+  Reported-by: jonrumsey at github
+  Fixes #1504
+
+- [Simon Warta brought this change]
+
+  cmake: remove unused variables: GNUTLS_ENABLED, NSS_ENABLED
+
+- [Simon Warta brought this change]
+
+  cmake: remove CURL_CA_BUNDLE from cmake TODO
+
+- [Simon Warta brought this change]
+
+  cmake: auto detection of CURL_CA_BUNDLE/CURL_CA_PATH
+  
+  Closes #1461
+
+- [Simon Warta brought this change]
+
+  cmake: add CURL_CA_BUNDLE/CURL_CA_FALLBACK/CURL_CA_PATH options
+
+- [Simon Warta brought this change]
+
+  cmake: Add CURL_CA_FALLBACK to curl_config.h.cmake
+  
+  This is for symmetry with the autoconf generated curl_config.h.in
+
+- RELEASE-NOTES: synced with 052a14e3c
+
+Michael Kaufmann (20 May 2017)
+- tests: stabilize test 1034
+  
+  Pass the invalid domain name on stdin. On some systems, the test
+  framework cannot pass invalid UTF-8 sequences on the command line.
+  
+  Closes #1488
+
+Daniel Stenberg (20 May 2017)
+- ssh: ignore timeouts during disconnect
+  
+  ... as otherwise it risks not cleaning up the libssh2 handle properly
+  which leads to memory leak!
+  
+  Assisted-by: Joel Depooter
+  
+  Closes #1495
+  Closes #1479
+  
+  Bug: https://curl.haxx.se/mail/lib-2017-04/0024.html
+
+- ghiper.c/hiperfifo.c: add comment about missing timer functionality
+  
+  It takes someone to read up on the APIs of these libraries to figure out
+  how to do this correctly.
+  
+  Reported-by: Michael Kaufmann
+  
+  Closes #1253
+
+- asiohiper.cpp / evhiperfifo.c: deal with negative timerfunction input
+  
+  That means delete the timer.
+  
+  Reported-by: Michael Kaufmann
+  Ref: #1253
+
+- cmdline-opts/write-out.d: s/-L/--location
+  
+  Since the man page generator wants the long option name version to
+  generate the proper output.
+
+- [Bernhard M. Wiedemann brought this change]
+
+  mkhelp.pl: do not add current time into curl binary
+  
+  ... as part of hugehelpgz rodata to make build reproducible.
+  
+  See https://reproducible-builds.org/ for why this is good
+  
+  Closes #1490
+
+- oauth2-bearer.d: mention the <token> argument
+
+Nick Zitzmann (16 May 2017)
+- darwinssl: Fix exception when processing a client-side certificate file
+  if no error was raised by the API but the SecIdentityRef was null
+  
+  Fixes #1450
+
+Daniel Stenberg (16 May 2017)
+- curl_sasl: fix build error with CURL_DISABLE_CRYPTO_AUTH + USE_NTLM
+  
+  Reported-by: wyattoday at github
+  Fixes #1487
+
+- docs/cmdline-opts/config.d: edit for language
+
+- RELEASE-NOTES: synced with eb16305e6
+
+- [moparisthebest brought this change]
+
+  SecureTransport/DarwinSSL: Implement public key pinning
+  
+  Closes #1400
+
+- man pages: fix example syntax errors
+  
+  follow-up to 5ddad099b42b50
+
+- docs/libcurl/opts: added more examples in man pages
+
+- CURLOPT_HTTPPROXYTUNNEL: clarify, add example
+
+- curl: show the libcurl release date in --version output
+  
+  ... and support and additional "security patched" date for those who
+  enhance older versions that way. Pass on the define CURL_PATCHSTAMP with
+  a date for that.
+  
+  Building with non-release headers shows the date as [unreleased].
+  
+  Also: this changes the date format generated in the curlver.h file to be
+  "YYYY-MM-DD" (no name of the day or month, no time, no time zone) to
+  make it easier on the eye and easier to parse. Example (new) date
+  string: 2017-05-09
+  
+  Suggested-by: Brian Childs
+  
+  Closes #1474
+
+Dan Fandrich (13 May 2017)
+- url.c: add a compile-time check that CURL_MAX_WRITE_SIZE is large enough
+  
+  Some code (e.g. Curl_fillreadbuffer) assumes that this buffer is not
+  exceedingly tiny and will break if it is. This same check is already
+  done at run time in the CURLOPT_BUFFERSIZE option.
+
+- lib510: don't write past the end of the buffer if it's too small
+
+- tests: added missing keywords "chunked Transfer-Encoding"
+
+Daniel Stenberg (13 May 2017)
+- THANKS: add a few missing names
+  
+  ... I found them in the commit logs from the early years
+
+Dan Fandrich (13 May 2017)
+- tests: made a couple of prechecks consistent with others
+  
+  Also removed a TODO suggesting caching the precheck results. Tests
+  showed this would save about 0.1 sec on the total test run time on a
+  relatively modern system, an unnoticeable gain at the cost of longer and
+  more complicated code. There would also be a danger that a cached test
+  result would be inappropriately returned, such as when other test
+  dependencies (like environment variables) are different or when the
+  precheck causes side effects (like filesystem changes).
+
+Daniel Stenberg (12 May 2017)
+- FAQ: add 7.4 to toc
+  
+  ... and delete trailing whitespace
+  
+  Fixes #1484
+
+- multi: remove leftover debug infof() calls from e9fd794a6
+
+- pipeline: fix mistakenly trying to pipeline POSTs
+  
+  The function IsPipeliningPossible() would return TRUE if either
+  pipelining OR HTTP/2 were possible on a connection, which would lead to
+  it returning TRUE even for POSTs on HTTP/1 connections.
+  
+  It now returns a bitmask so that the caller can differentiate which kind
+  the connection allows.
+  
+  Fixes #1481
+  Closes #1483
+  Reported-by: stootill at github
+
+Jay Satiro (12 May 2017)
+- [Ron Eldor brought this change]
+
+  mbedtls: Support server renegotiation request
+  
+  Tested with servers: IIS 7.5; OpenSSL 1.0.2.
+  
+  Closes https://github.com/curl/curl/pull/1475
+
+Marcel Raad (11 May 2017)
+- cookie_interface: fix -Wcomma warning
+  
+  clang 5.0 complains:
+  possible misuse of comma operator here [-Wcomma]
+
+- formdata: fix -Wcomma warning
+  
+  clang 5.0 complains:
+  possible misuse of comma operator here [-Wcomma]
+  
+  Change the comma to a semicolon to fix that.
+
+Daniel Stenberg (10 May 2017)
+- multi: use a fixed array of timers instead of malloc
+  
+  ... since the total amount is low this is faster, easier and reduces
+  memory overhead.
+  
+  Also, Curl_expire_done() can now mark an expire timeout as done so that
+  it never times out.
+  
+  Closes #1472
+
+- multi: assign IDs to all timers and make each timer singleton
+  
+   A) reduces the timeout lists drastically
+  
+   B) prevents a lot of superfluous loops for timers that expires "in vain"
+      when it has actually already been extended to fire later on
+
+- [Richard Hsu brought this change]
+
+  tests: remove superfluous test 1399
+  
+  @MarcelRaad noted that `test1399` causes infinite loop on MinGW.
+  Looking into this, seems like it is related to how Windows handles
+  CRLF. See https://github.com/curl/curl/commit/9e093f by @mback2k.
+  Removing `test1399` as it's identical to `test1326` then with such a
+  fix.
+  
+  Test 1399 was broughy by commit 862b02f8947039e
+  
+  Closes #1478
+
+Dan Fandrich (9 May 2017)
+- tests: make test file names more unique
+  
+  Include the test number in the names of files written out by tests to
+  reduce the chance of accidental duplication and to make it more clear
+  which test is associated with which file.
+
+- tests: removed redundant --trace-ascii arguments
+  
+  This is already added by the test suite; it's not clear why all these
+  tests had it, unless it's cargo-culting.
+
+Marcel Raad (9 May 2017)
+- tool: fix remaining -Wcast-qual warnings
+  
+  Avoid casting away low-level const.
+
+Daniel Stenberg (9 May 2017)
+- formboundary: convert assert into run-time check
+  
+  ... to really make sure the boundary fits in the target buffer.
+  
+  Fixes unused parameter 'buflen' warning.
+  
+  Reported-by: Michael Kaufmann
+  Bug: https://github.com/curl/curl/pull/1468#issuecomment-300078754
+
+Dan Fandrich (9 May 2017)
+- tests: list the primary server first in the server section
+
+Daniel Stenberg (8 May 2017)
+- curl: generate the --help output
+  
+  ... using the docs/cmdline-opts/gen.pl script, so that we get all the
+  command line option documentation from the same source.
+  
+  The generation of the list has to be done manually and pasted into the
+  source code.
+  
+  Closes #1465
+
+- tests: updated for modified fake random
+
+- [Jay Satiro brought this change]
+
+  rand: treat fake entropy the same regardless of endianness
+  
+  When the random seed is purposely made predictable for testing purposes
+  by using the CURL_ENTROPY environment variable, process that data in an
+  endian agnostic way so the the initial random seed is the same
+  regardless of endianness.
+  
+  - Change Curl_rand to write to a char array instead of int array.
+  
+  - Add Curl_rand_hex to write random hex characters to a buffer.
+  
+  Fixes #1315
+  Closes #1468
+  
+  Co-authored-by: Daniel Stenberg
+  Reported-by: Michael Kaufmann
+
+Dan Fandrich (8 May 2017)
+- tests: give each stunnel.conf file a unique name
+  
+  Otherwise, subsequent uses of stunnel overwrite the configuration file
+  of previous invocations so they can no longer be inspected.
+
+Marcel Raad (8 May 2017)
+- tool_msgs: remove wrong cast
+  
+  Commit 481e0de00a9003b9c5220b120e3fc302d9b0932d changed the variable
+  type from int to size_t, so don't cast the result of strlen to int
+  anymore.
+
+- tftpd: fix signed/unsigned mismatch warnings
+  
+  alarm's argument is unsigned.
+
+- libtest: fix MinGW-w64 warnings
+  
+  long is 32 bits while size_t is 64 bits on MinGW-w64, so
+  typecheck-gcc.h complains when using size_t for a long option.
+  Also, curl_socket_t is unsigned long long rather than int.
+
+Daniel Stenberg (8 May 2017)
+- curl.1: depend the build on the Makefile.inc too
+  
+  ... to also make it update when we remove files, like we did for
+  --environment in commit a8e388dd1095.
+
+- RELEASE-NOTES: synced with e3f84efc32d6b01a
+
+- runtests: fix "use of undefined value" warning in -R handling
+
+Marcel Raad (8 May 2017)
+- test537: use correct variable type
+  
+  Avoids narrowing conversion warnings because rlim_t is usually
+  unsigned long.
+  
+  Closes https://github.com/curl/curl/pull/1469
+
+- sendrecv: fix MinGW-w64 warning
+  
+  The first argument to select is an int, while curl_socket_t is
+  unsigned long long when using WinSock. It's ignored anyway [1].
+  
+  [1] https://msdn.microsoft.com/en-us/library/windows/desktop/ms740141.aspx
+
+- tool_parsecfg: fix -Wcast-qual warning
+  
+  Don't convert string literal to char * before assigning it to
+  const char *.
+
+- asyn-thread: fix unused macro warnings
+  
+  Don't do anything in this file if CURLRES_THREADED is not defined.
+
+- tftp: silence bad-function-cast warning
+  
+  The cases this warns about are handled elsewhere, so just use an
+  intermediate variable to silence the warning.
+
+Daniel Stenberg (7 May 2017)
+- [canavan at github brought this change]
+
+  buildconf: fix hang on IRIX
+  
+  Apparently, /usr/bin/m4 ignores the --version parameter and waits for
+  input from stdin.
+  
+  Fixes #1471
+
+- opts: fix bad example formatting \n => \\n
+  
+  ...to render properly nroff.
+
+- opts: examples added to 8 more libcurl option man pages
+
+- curl: remove tool_writeenv.[ch]
+  
+  ... and USE_ENVIRONMENT and --environment. It was once added for RISC OS
+  support and its platform specific behavior has been annoying ever
+  since. Added in commit c3c8bbd3b2688da8e, mostly unchanged since
+  then. Most probably not actually used for years.
+  
+  Closes #1463
+
+Dan Fandrich (6 May 2017)
+- runtests.pl: simplify the datacheck read section
+  
+  Also, document that numbered datacheck sections are possible.
+
+Marcel Raad (5 May 2017)
+- tests: fix -Wcast-qual warnings
+  
+  Avoid casting string literals to non-const char *.
+
+Daniel Stenberg (5 May 2017)
+- docs/opts: 24 more man pages now have examples
+
+- docs/opts: 23 more man pages now have examples
+
+- tests/server: run checksrc by default in debug-builds
+
+- curl_slist_append.3: clarify a NULL input creates a new list
+
+Marcel Raad (5 May 2017)
+- unit1305: fix compiler warning
+  
+  calloc and ai_addrlen expect different (usually unsigned) types.
+
+Daniel Stenberg (5 May 2017)
+- runtests: use -R for random order
+  
+  Suggested-by: Dan Fandrich
+
+- runtests: add -o to run test cases in scrambled order
+  
+  ... instead of numerical order.
+  
+  Closes #1466
+
+Dan Fandrich (4 May 2017)
+- sockfilt.c: shortened too long line
+
+Marcel Raad (4 May 2017)
+- tests/server: make string literals const
+  
+  assign string literals to const char * instead of char * in order to
+  avoid a lot of these warnings:
+  cast from 'const char *' to 'char *' drops const qualifier
+  [-Wcast-qual]
+
+Dan Fandrich (4 May 2017)
+- schannel: return a more specific error code for SEC_E_UNTRUSTED_ROOT
+
+- test557: set a known good numeric locale
+  
+  Windows does not allow setting the locale with environment variables (as
+  the test attempted to do), so the test failed when run with a user
+  locale that has a comma as radixchar. Changed the test to call
+  setlocale() explicitly to ensure that a known working locale is set even
+  on Windows.
+
+Daniel Stenberg (4 May 2017)
+- curl: fix warning "comma at end of enumerator list"
+
+- test559: verify use of minimum CURLOPT_BUFFERSIZE
+
+Marcel Raad (4 May 2017)
+- curl_setup_once: use SEND_QUAL_ARG2 for swrite
+  
+  SEND_QUAL_ARG2 had to be set, but was never used. Use it in swrite to
+  avoid warnings about casting away low-level const.
+  
+  Closes https://github.com/curl/curl/pull/1464
+
+Daniel Stenberg (4 May 2017)
+- CURLINFO_REDIRECT_URL.3: add example
+
+- CURLINFO_EFFECTIVE_URL.3: add example
+
+Marcel Raad (3 May 2017)
+- lib: fix compiler warnings
+  
+  Fix the following warnings when building the tests by using the correct
+  types:
+  cast from 'const char *' to 'void *' drops const qualifier
+  [-Wcast-qual]
+  implicit conversion changes signedness [-Wsign-conversion]
+
+- typecheck-gcc: add support for CURLINFO_SOCKET
+  
+  Closes https://github.com/curl/curl/pull/1452
+
+- typecheck-gcc: add missing string options
+  
+  Closes https://github.com/curl/curl/pull/1452
+
+Daniel Stenberg (3 May 2017)
+- abstract-unix-socket.d: shorten the help text to fit within 79 cols
+
+- RELEASE-NOTES: synced with 862b02f89
+
+- [Richard Hsu brought this change]
+
+  Telnet: Write full buffer instead of byte-by-byte
+  
+  Previous TODO wanting to write in chunks. We should support writing more
+  at once since some TELNET servers may respond immediately upon first
+  byte written such as WHOIS servers.
+  
+  Closes #1389
+
+- curl: non-boolean command line args reject --no- prefixes
+  
+  ... and instead properly respond with an error message to the user
+  instead of silently ignoring.
+  
+  Fixes #1453
+  Closes #1458
+
+Marcel Raad (2 May 2017)
+- testpart: remove _MPRINTF_REPLACE
+  
+  Support for _MPRINTF_REPLACE in mprintf.h was removed in
+  55452ebdff47f98bf3cc383f1dfc3623fcaefefd, replaced with curl_printf.h.
+
+Dan Fandrich (2 May 2017)
+- gtls: fixed a lingering BUFSIZE reference
+
+Daniel Stenberg (2 May 2017)
+- ssh: fix compiler warning from e40e9d7f0de
+
+- url: let CURLOPT_BUFFERSIZE realloc to smaller sizes too
+  
+  Closes #1449
+
+- BUFSIZE: rename to READBUFFER_*, make separate MASTERBUF_SIZE
+
+- openssl: use local stack for temp storage
+
+- sendf: remove use of BUFSIZE from debug data conversions
+  
+  The buffer can have other sizes.
+
+- buffer: use data->set.buffer_size instead of BUFSIZE
+  
+  ... to properly use the dynamically set buffer size!
+
+- krb5: use private buffer for temp string, not receive buffer
+
+- upload: UPLOAD_BUFSIZE is now for the upload buffer
+
+- unit1606: do not print/access buffer
+  
+  It was a wrong assumption that it could do that!
+
+- http-proxy: use a dedicated CONNECT response buffer
+  
+  To make it suitably independent of the receive buffer and its flexible
+  size.
+
+- transfer: fix minor buffer_size mistake
+
+- failf: use private buffer, don't clobber receive buffer
+
+- pingpong: use the set buffer size
+
+- http2: use the correct set buffer size
+
+- http: don't clobber the receive buffer for timecond
+
+- buffer_size: make sure it always has the correct size
+  
+  Removes the need for CURL_BUFSIZE
+
+- file: use private buffer for C-L output
+  
+  ... instead of clobbering the download buffer.
+
+- CURLOPT_BUFFERSIZE: 1024 bytes is now the minimum size
+  
+  The buffer is needed to receive FTP, HTTP CONNECT responses etc so
+  already at this size things risk breaking and smaller is certainly not
+  wise.
+
+- ftp: use private buffer for temp storage, not receive buffer
+
+- http: use private user:password output buffer
+  
+  Don't clobber the receive buffer.
+
+Marcel Raad (1 May 2017)
+- anyauthput: remove unused code
+  
+  The definition of TRUE was introduced in
+  4a728747e6f8845e500910e397dfc99aaf4a7984 and is not used anymore since
+  e664cd5826d43930fcc5b5dbaedbec94af33184b.
+  The usage of intptr_t was removed in
+  32e38b8f42477cf5ce3c3fef2fcc9db82f7fb7be.
+
+Jay Satiro (1 May 2017)
+- tool: Fix missing prototype warnings for CURL_DOES_CONVERSIONS
+  
+  - Include tool_convert.h where needed.
+  
+  Bug: https://github.com/curl/curl/issues/1460
+  Reported-by: Gisle Vanem
+
+- curl_setup: Ensure no more than one IDN lib is enabled
+  
+  Prior to this change it was possible for libcurl to be built with both
+  Windows' native IDN lib (normaliz) and libidn2 enabled. It appears that
+  doesn't offer any benefit --and could cause a bug-- since libcurl's IDN
+  handling is written to use either one but not both.
+  
+  Bug: https://github.com/curl/curl/issues/1441#issuecomment-297689856
+  Reported-by: Gisle Vanem
+
+Marcel Raad (1 May 2017)
+- getpart: use correct variable type
+  
+  This fixes the following clang warning:
+  getpart.c:201:17: warning: cast from function call of type 'CURLcode'
+  to non-matching type 'int' [-Wbad-function-cast]
+
+- tests: declare TU-local variables static
+  
+  This fixes missing-variable-declarations warnings when building with
+  clang.
+
+- tool_cb_prg: fix double-promotion warning
+  
+  clang complains:
+  tool_cb_prg.c:86:22: error: implicit conversion increases
+  floating-point precision: 'float' to 'double'
+  [-Werror,-Wdouble-promotion]
+  
+  Fix this by using a double instead of a float constant.
+
+Dan Fandrich (1 May 2017)
+- examples: fixed too long line and too long string warnings
+
+Marcel Raad (30 Apr 2017)
+- examples: declare TU-local variables static
+  
+  This fixes missing-variable-declarations warnings when building with
+  clang.
+
+- http2: declare TU-local variables static
+  
+  This fixes the following clang warnings:
+  
+  http2.c:184:27: error: no previous extern declaration for non-static
+  variable 'Curl_handler_http2' [-Werror,-Wmissing-variable-declarations]
+  http2.c:204:27: error: no previous extern declaration for non-static
+  variable 'Curl_handler_http2_ssl'
+  [-Werror,-Wmissing-variable-declarations]
+
+Dan Fandrich (30 Apr 2017)
+- unit1604: fixed indentation
+
+- unit1604: fixed compilation under Windows, broken in the previous commit
+
+- tests: fixed OOM handling of unit tests to abort test
+  
+  It's dangerous to continue to run the test when a memory alloc fails.
+
+Marcel Raad (29 Apr 2017)
+- curl_rtmp: fix missing-variable-declarations warnings
+  
+  clang complains:
+  
+  curl_rtmp.c:61:27: error: no previous extern declaration for non-static variable 'Curl_handler_rtmp' [-Werror,-Wmissing-variable-declarations]
+  curl_rtmp.c:81:27: error: no previous extern declaration for non-static variable 'Curl_handler_rtmpt' [-Werror,-Wmissing-variable-declarations]
+  curl_rtmp.c:101:27: error: no previous extern declaration for non-static variable 'Curl_handler_rtmpe' [-Werror,-Wmissing-variable-declarations]
+  curl_rtmp.c:121:27: error: no previous extern declaration for non-static variable 'Curl_handler_rtmpte' [-Werror,-Wmissing-variable-declarations]
+  curl_rtmp.c:141:27: error: no previous extern declaration for non-static variable 'Curl_handler_rtmps' [-Werror,-Wmissing-variable-declarations]
+  curl_rtmp.c:161:27: error: no previous extern declaration for non-static variable 'Curl_handler_rtmpts' [-Werror,-Wmissing-variable-declarations]
+  
+  Fix this by including the header file.
+
+Dan Fandrich (29 Apr 2017)
+- url: fixed a memory leak on OOM while setting CURLOPT_BUFFERSIZE
+
+- tests: added --remote-time tests for remaining protocols that support it
+
+- runtests.pl: support multiline <postcheck> commands
+
+- tool_operate: use utimes instead of obsolescent utime when available
+
+- test1443: test --remote-time
+
+- http-proxy: removed unused argument in CURL_DISABLE_PROXY case
+  
+  Missed in commit 55c3c02e
+
+Daniel Stenberg (27 Apr 2017)
+- cookie_interface.c: changed the other domain to example.com too
+
+- cookie_interface.c: fix cookie domain so the example works
+
+Dan Fandrich (26 Apr 2017)
+- Makefile: fix make dist
+  
+  Commit 80a87e8a broke 'make dist' as it can't handle installing from
+  absolute target names. Rearranged the dependencies so the absolute name
+  is used for building but the relative name is use for distributing.
+
+Marcel Raad (26 Apr 2017)
+- lib: remove unused code
+  
+  This fixes the following clang warnings:
+  macro is not used [-Wunused-macros]
+  will never be executed [-Wunreachable-code]
+  
+  Closes https://github.com/curl/curl/pull/1448
+
+Daniel Stenberg (26 Apr 2017)
+- http-proxy: remove unused argument from Curl_proxyCONNECT()
+
+- [Martin Kepplinger brought this change]
+
+  url: declare get_protocol_family() static
+  
+  get_protocol_family() is not defined static even though there is a
+  static local forward declaration. Let's simply make the definition match
+  it's declaration.
+  
+  Bug: https://curl.haxx.se/mail/lib-2017-04/0127.html
+
+- examples: ftpuploadfrommem.c
+  
+  Uploads data to an FTP site, directly from memory.
+  
+  Closes #1451
+
+Kamil Dudka (25 Apr 2017)
+- nss: load libnssckbi.so if no other trust is specified
+  
+  The module contains a more comprehensive set of trust information than
+  supported by nss-pem, because libnssckbi.so also includes information
+  about distrusted certificates.
+  
+  Reviewed-by: Kai Engert
+  Closes #1414
+
+- nss: factorize out nss_{un,}load_module to separate fncs
+  
+  No change of behavior is intended by this commit.
+
+- nss: do not leak PKCS #11 slot while loading a key
+  
+  It could prevent nss-pem from being unloaded later on.
+  
+  Bug: https://bugzilla.redhat.com/1444860
+
+Marcel Raad (25 Apr 2017)
+- typecheck-gcc: fix _curl_is_slist_info
+  
+  Info values starting with CURLINFO_SOCKET expect a curl_socket_t, not a
+  curl_slist argument.
+  
+  This fixes the following GCC warning when building the examples with
+  --enable-optimize:
+  
+  ../../include/curl/typecheck-gcc.h:126:42: warning: call to
+  â_curl_easy_getinfo_err_curl_slistâ declared with attribute warning:
+  curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this
+  info [enabled by default]
+  sendrecv.c:90:11: note: in expansion of macro âcurl_easy_getinfoâ
+  res = curl_easy_getinfo(curl, CURLINFO_ACTIVESOCKET, &sockfd);
+  
+  Closes https://github.com/curl/curl/pull/1447
+
+Daniel Stenberg (25 Apr 2017)
+- curl: set a 100K buffer size by default
+  
+  Test command 'time curl http://localhost/80GB -so /dev/null' on a Debian
+  Linux.
+  
+  Before (middle performing run out 9):
+  
+   real    0m28.078s
+   user    0m11.240s
+   sys     0m12.876s
+  
+  After (middle performing run out 9)
+  
+   real    0m26.356s (93.9%)
+   user    0m5.324s  (47.4%)
+   sys     0m8.368s  (65.0%)
+  
+  Also, doing SFTP over a 200 millsecond latency link is now about 6 times
+  faster.
+  
+  Closes #1446
+
+- transfer: remove 'uploadbuf' pointer and cleanup readwrite_upload()
+  
+  The data->req.uploadbuf struct member served no good purpose, instead we
+  use ->state.uploadbuffer directly. It makes it clearer in the code which
+  buffer that's being used.
+  
+  Removed the 'SingleRequest *' argument from the readwrite_upload() proto
+  as it can be derived from the Curl_easy struct. Also made the code in
+  the readwrite_upload() function use the 'k->' shortcut to all references
+  to struct fields in 'data->req', which previously was made with a mix of
+  both.
+
+Jay Satiro (25 Apr 2017)
+- configure: stop prepending to LDFLAGS, CPPFLAGS
+  
+  - Change prepends to appends because user's LDFLAGS and CPPFLAGS should
+    always come first so they're searched before ours.
+  
+  Bug: https://github.com/curl/curl/issues/1420
+  Reported-by: Helmut K. C. Tessarek
+
+Marcel Raad (25 Apr 2017)
+- if2ip: fix -Wcast-align warning
+  
+  Follow-up to 119037325de02579f5c58256ca2ed2a0aa592c86, which fixed the
+  warning in the HAVE_GETIFADDRS block, but not in the
+  HAVE_IOCTL_SIOCGIFADDR block.
+
+Dan Fandrich (24 Apr 2017)
+- Makefile: avoid use of GNU-specific form of $<
+  
+  $< is only allowed in implicit rules in some non-GNU makes (e.g. BSD,
+  AIX) so avoid use elsewhere by referencing the dependent curl.1 file
+  directly instead. This is somewhat tricky because the file is supplied
+  in the packaged tar ball (but not in git) but must still be able to be
+  rebuilt when its dependencies change. The right thing must happen in
+  both tar ball and git source trees, as well as in both in-tree and
+  out-of-tree builds.
+
+Kamil Dudka (24 Apr 2017)
+- nss: adapt to the new Curl_llist API
+  
+  This commit fixes compilation failure caused by
+  cbae73e1dd95946597ea74ccb580c30f78e3fa73.
+
+Marcel Raad (24 Apr 2017)
+- curl-compilers.m4: accept -Og and -Ofast GCC flags
+  
+  -Og, introduced in GCC 4.8, optimizes for debugging experience.
+  -Ofast, introduced in GCC 4.7, builds on -O3 and enables further
+  optimizations breaking strict standards compliance.
+  When specified in CFLAGS, these were always overridden by -O0 or -O2.
+  Fix this by adding them to flags_opt_all.
+  
+  Ref: https://gcc.gnu.org/onlinedocs/gcc-4.8.0/gcc/Optimize-Options.html
+  Ref: https://github.com/curl/curl/pull/1404#issuecomment-296401570
+  Closes https://github.com/curl/curl/pull/1440
+
+Daniel Stenberg (24 Apr 2017)
+- RELEASE-NOTES: synced with c68fed875
+
+- configure: fix the -ldl check for openssl, add -lpthread check
+  
+  The check for if -ldl is needed to build with (a statically built)
+  openssl was broken. This repairs the check, and adds a check for
+  -lpthread as well since OpenSSL 1.1.0+ does in fact require -lpthread so
+  only adding -ldl for a static openssl build is no longer enough.
+  
+  Reported-by: Jay Satiro
+  Ref: #1426
+  Closes #1427
+
+- llist: fix a comment after cbae73e1dd9
+  
+  Pointed-it-by: Kevin Ji
+  URL: https://github.com/curl/curl/commit/cbae73e1dd95946597ea74ccb580c30f78e3fa73#commitcomment-21872622
+
+Jay Satiro (22 Apr 2017)
+- schannel: Don't treat encrypted partial record as pending data
+  
+  - Track when the cached encrypted data contains only a partial record
+    that can't be decrypted without more data (SEC_E_INCOMPLETE_MESSAGE).
+  
+  - Change Curl_schannel_data_pending to return false in such a case.
+  
+  Other SSL libraries have pending data functions that behave similarly.
+  
+  Ref: https://github.com/curl/curl/pull/1387
+  
+  Closes https://github.com/curl/curl/pull/1392
+
+Daniel Stenberg (22 Apr 2017)
+- [Alan Jenkins brought this change]
+
+  multi: clarify condition in curl_multi_wait
+  
+  `if(nfds || extra_nfds) {` is followed by `malloc(nfds * ...)`.
+  
+  If `extra_fs` could be non-zero when `nfds` was zero, then we have
+  `malloc(0)` which is allowed to return `NULL`. But, malloc returning
+  NULL can be confusing. In this code, the next line would treat the NULL
+  as an allocation failure.
+  
+  It turns out, if `nfds` is zero then `extra_nfds` must also be zero.
+  The final value of `nfds` includes `extra_nfds`.  So the test for
+  `extra_nfds` is redundant.  It can only confuse the reader.
+  
+  Closes #1439
+
+Marcel Raad (22 Apr 2017)
+- lib: fix maybe-uninitialized warnings
+  
+  With -Og, GCC complains:
+  
+  easy.c:628:7: error: âmcodeâ may be used uninitialized in this function [-Werror=maybe-uninitialized]
+  
+  ../lib/strcase.h:35:29: error: âtok_bufâ may be used uninitialized in this function [-Werror=maybe-uninitialized]
+  vauth/digest.c:208:9: note: âtok_bufâ was declared here
+  
+  ../lib/strcase.h:35:29: error: âtok_bufâ may be used uninitialized in this function [-Werror=maybe-uninitialized]
+  vauth/digest.c:566:15: note: âtok_bufâ was declared here
+  
+  Fix this by initializing the variables.
+
+Dan Fandrich (22 Apr 2017)
+- gnutls: removed some code when --disable-verbose is configured
+  
+  This reduces the binary size and fixes a compile warning.
+
+Daniel Stenberg (22 Apr 2017)
+- llist: no longer uses malloc
+  
+  The 'list element' struct now has to be within the data that is being
+  added to the list. Removes 16.6% (tiny) mallocs from a simple HTTP
+  transfer. (96 => 80)
+  
+  Also removed return codes since the llist functions can't fail now.
+  
+  Test 1300 updated accordingly.
+  
+  Closes #1435
+
+Marcel Raad (21 Apr 2017)
+- typecheck-gcc: handle function pointers properly
+  
+  All the callbacks passed to curl_easy_setopt are defined as function
+  pointers. The possibility to pass both functions and function pointers
+  was handled for the callbacks that typecheck-gcc.h defined as
+  compatible, but not for the public callback types themselves.
+  
+  This makes all compatible callback types defined in typecheck-gcc.h
+  function pointers too and checks all functions uniformly with
+  _curl_callback_compatible, which handles both functions and function
+  pointers.
+  
+  A symptom of the problem was a warning in tool_operate.c with
+  --disable-libcurl-option and without --enable-debug as that file
+  passes the callback functions to curl_easy_setopt directly.
+  
+  Fixes https://github.com/curl/curl/issues/1403
+  Closes https://github.com/curl/curl/pull/1404
+
+Dan Fandrich (21 Apr 2017)
+- mbedtls: enable NTLM (& SMB) even if MD4 support is unavailable
+  
+  In that case, use libcurl's internal MD4 routine. This fixes tests 1013
+  and 1014 which were failing due to configure assuming NTLM and SMB were
+  always available whenever mbed TLS was in use (which is now true).
+
+Daniel Stenberg (21 Apr 2017)
+- tests: remove the html and PDF versions from the tarball
+
+- openssl: fix memory leak in servercert
+  
+  ... when failing to get the server certificate.
+
+- Revert "src/Makefile.am: avoid explicit $<"
+  
+  This reverts commit 5b4cbcf11d5100ff793a8e9edbaa6fe1fc7495f5.
+  
+  Since it broke out-of-tree builds from tarballs. See discussion in #1432
+
+- bump: start working on next release
+
+- src/Makefile.am: avoid explicit $<
+  
+  ... since apparently "BSD make" doesn't support it.
+  
+  Reported-by: Thomas Klausner
+  Fixes #1432
+
+Version 7.54.0 (19 Apr 2017)
+
+Daniel Stenberg (19 Apr 2017)
+- THANKS: add contributors from 7.54.0 release notes
+
+- RELEASE-NOTES: curl 7.54.0
+
+Marcel Raad (18 Apr 2017)
+- nss: fix MinGW compiler warnings
+  
+  This fixes 3 warnings issued by MinGW:
+  1. PR_ImportTCPSocket actually has a paramter of type PROsfd instead of
+  PRInt32, which is 64 bits on Windows. Fixed this by including the
+  corresponding header file instead of redeclaring the function, which is
+  supported even though it is in the private include folder. [1]
+  2. In 64-bit mode, size_t is 64 bits while CK_ULONG is 32 bits, so an explicit
+  narrowing cast is needed.
+  3. Curl_timeleft returns time_t instead of long since commit
+  21aa32d30dbf319f2d336e0cb68d3a3235869fbb.
+  
+  [1] https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSPR/Reference/PR_ImportTCPSocket
+  
+  Closes https://github.com/curl/curl/pull/1393
+
+Daniel Stenberg (18 Apr 2017)
+- [Jay Satiro brought this change]
+
+  TLS: Fix switching off SSL session id when client cert is used
+  
+  Move the sessionid flag to ssl_primary_config so that ssl and proxy_ssl
+  will each have their own sessionid flag.
+  
+  Regression since HTTPS-Proxy support was added in cb4e2be. Prior to that
+  this issue had been fixed in 247d890, CVE-2016-5419.
+  
+  Bug: https://github.com/curl/curl/issues/1341
+  Reported-by: lijian996@users.noreply.github.com
+  
+  The new incarnation of this bug is called CVE-2017-7468 and is documented
+  here: https://curl.haxx.se/docs/adv_20170419.html
+
+- [David Benjamin brought this change]
+
+  openssl: don't try to print nonexistant peer private keys
+  
+  X.509 certificates carry public keys, not private keys. Fields
+  corresponding to the private half of the key will always be NULL.
+  
+  Closes #1425
+
+- [David Benjamin brought this change]
+
+  openssl: fix thread-safety bugs in error-handling
+  
+  ERR_error_string with NULL parameter is not thread-safe. The library
+  writes the string into some static buffer. Two threads doing this at
+  once may clobber each other and run into problems. Switch to
+  ERR_error_string_n which avoids this problem and is explicitly
+  bounds-checked.
+  
+  Also clean up some remnants of OpenSSL 0.9.5 around here. A number of
+  comments (fixed buffer size, explaining that ERR_error_string_n was
+  added in a particular version) date to when ossl_strerror tried to
+  support pre-ERR_error_string_n OpenSSLs.
+  
+  Closes #1424
+
+- [David Benjamin brought this change]
+
+  openssl: make SSL_ERROR_to_str more future-proof
+  
+  Rather than making assumptions about the values, use a switch-case.
+  
+  Closes #1424
+
+- [Daniel Gustafsson brought this change]
+
+  code: fix typos and style in comments
+  
+  A few random typos, and minor whitespace cleanups, found in comments
+  while reading code.
+  
+  Closes #1423
+
+Marcel Raad (17 Apr 2017)
+- extern-scan.pl: strip trailing CR
+  
+  This makes test 1135 pass with CRLF checkouts.
+  
+  Ref: https://github.com/curl/curl/pull/1344#issuecomment-289243166
+  Closes https://github.com/curl/curl/pull/1422
+
+- configure.ac: ignore CR after version numbers
+  
+  Ignore everything after the version numbers in LIBCURL_VERSION and
+  LIBCURL_VERSION_NUM to ged rid of the extra CR character.
+  This makes tests 1022 and 1023 pass on Linux with a CRLF checkout.
+  
+  Ref: https://github.com/curl/curl/pull/1344#issuecomment-289243166
+  Closes https://github.com/curl/curl/pull/1422
+
+- .gitattributes: force shell scripts to LF
+  
+  Bash on Linux errors out on CR characters.
+  This makes tests 1221 and 1222 pass on Linux with a CRLF checkout.
+  
+  Ref: https://github.com/curl/curl/pull/1344#issuecomment-289243166
+  Closes https://github.com/curl/curl/pull/1422
+
+- unit1303: fix compiler warning
+  
+  MinGW-w64 complains:
+  warning: conversion to 'long int' from 'time_t {aka long long int}' may
+  alter its value [-Wconversion]
+  Fix this by using the correct type.
+
+Daniel Stenberg (16 Apr 2017)
+- RELEASE-NOTES: synced with 1451271e0
+
+- [Larry Stefani brought this change]
+
+  http2: fix handle leak in error path
+  
+  Add missing newhandle free call in push_promise().
+  
+  Closes #1416
+
+- [Larry Stefani brought this change]
+
+  mbedtls: fix memory leak in error path
+  
+  Add missing our_ssl_sessionid free call in mbed_connect_step3().
+  
+  Closes #1417
+
+Marcel Raad (15 Apr 2017)
+- curl-compilers.m4: turn implicit function declarations into errors
+  
+  This adds -Werror-implicit-function-declaration for GCC 2.95+ so that
+  these errors are visible at the point where they occur instead of only
+  at link time.
+  Implicit function declarations are illegal in C99 and C++ anyway, and
+  the same warning has been turned into an error for ICC in commit
+  3072c5b8a127057aa922b7c51051bbb4a630b091.
+  
+  Ref: https://gcc.gnu.org/onlinedocs/gcc-2.95.2/gcc_2.html#SEC8
+  Ref: https://curl.haxx.se/mail/lib-2017-04/0001.html
+  Closes https://github.com/curl/curl/pull/1419
+
+- test1541: also test for CURL_PULL_WS2TCPIP_H
+  
+  Ref: https://github.com/curl/curl/issues/1408
+  Closes https://github.com/curl/curl/pull/1412
+
+- tests/server/util: prefer <poll.h> over <sys/poll.h>
+  
+  Follow-up to aa573c3c55cda72ec5ef677d87f6f46a53385f0c
+  
+  Ref: https://github.com/curl/curl/pull/1406
+
+Daniel Stenberg (11 Apr 2017)
+- Curl_expire_latest: ignore already expired timers
+  
+  If the existing timer is still in there but has expired, the new timer
+  should be added.
+  
+  Reported-by: Rainer Canavan
+  Bug: https://curl.haxx.se/mail/lib-2017-04/0030.html
+  Closes #1407
+
+- system.h: fix mingw section
+  
+  Reported-by: Marcel Raad
+  Fixes #1408
+  Closes #1409
+
+Marcel Raad (11 Apr 2017)
+- polarssl: unbreak build with versions < 1.3.8
+  
+  ssl_session_init was only introduced in version 1.3.8, the penultimate
+  version. The function only contains a memset, so replace it with that.
+  
+  Suggested-by: Jay Satiro
+  Fixes https://github.com/curl/curl/issues/1401
+
+- poll: prefer <poll.h> over <sys/poll.h>
+  
+  The POSIX standard location is <poll.h>. Using <sys/poll.h> results in
+  warning spam when using the musl standard library.
+  
+  Closes https://github.com/curl/curl/pull/1406
+
+Daniel Stenberg (10 Apr 2017)
+- [Alexis La Goutte brought this change]
+
+  openssl: fix this statement may fall through [-Wimplicit-fallthrough=]
+  
+  Closes #1402
+
+Kamil Dudka (10 Apr 2017)
+- nss: load CA certificates even with --insecure
+  
+  ... because they may include an intermediate certificate for a client
+  certificate and the intermediate certificate needs to be presented to
+  the server, no matter if we verify the peer or not.
+  
+  Reported-by: thraidh
+  Closes #851
+
+Daniel Stenberg (10 Apr 2017)
+- RELEASE-NOTES: synced with f9d1e9a27f7e1
+
+Dan Fandrich (10 Apr 2017)
+- libcurl-thread.3: fixed a bad macro that caused test 1140 to fail
+
+Daniel Stenberg (9 Apr 2017)
+- libcurl-thread.3: also mention threaded-resolver
+  
+  Reported-by: Alex Bligh
+  Bug: https://curl.haxx.se/mail/lib-2017-04/0044.html
+
+- .github/stale.yml: enable the stale bot
+  
+  Issues and PRs with no activity for 180 days will get marked as stale,
+  and if no further activity happens within 14 more days, the issue gets
+  closed.
+  
+  This follows our established policy of not letting stalled bugs "get in
+  the way": https://curl.haxx.se/docs/bugs.html#Closing_off_stalled_bugs
+  
+  Closes #1398
+
+Jay Satiro (8 Apr 2017)
+- CURLINFO_SCHEME.3: fix variable type
+  
+  - Change documented param type to char ** from incorrect long *.
+
+Marcel Raad (8 Apr 2017)
+- INSTALL.md: fix secure transport configure arguments
+  
+  --without-ssl is needed instead of --with-winssl.
+
+- vtls: fix unreferenced variable warnings
+  
+  ... by moving the variables into the correct #ifdef block.
+
+Daniel Stenberg (7 Apr 2017)
+- BUGS: "Bugs in old versions"
+
+- system.h: add section for tcc
+  
+  Closes #1397
+
+Marcel Raad (7 Apr 2017)
+- schannel: fix compiler warnings
+  
+  When UNICODE is not defined, the Curl_convert_UTF8_to_tchar macro maps
+  directly to its argument. As it is declared as a pointer to const and
+  InitializeSecurityContext expects a pointer to non-const, both MSVC and MinGW
+  issue a warning about implicitly casting away the const. Fix this by declaring
+  the variables as pointers to non-const.
+  
+  Closes https://github.com/curl/curl/pull/1394
+
+- [Isaac Boukris brought this change]
+
+  sspi: print out InitializeSecurityContext() error message
+  
+  Reported-by: Carsten (talksinmath)
+  
+  Fixes #1384
+  Closes #1395
+
+- gtls: fix compiler warning
+  
+  Curl_timeleft returns time_t instead of long since commit
+  21aa32d30dbf319f2d336e0cb68d3a3235869fbb.
+
+Daniel Stenberg (6 Apr 2017)
+- test1606: verify speedcheck
+
+- low_speed_limit: improved function for longer time periods
+  
+  Previously, periods of fast speed between periods of slow speed would
+  not count and could still erroneously trigger a timeout.
+  
+  Reported-by: Paul Harris
+  Fixes #1345
+  Closes #1390
+
+- system.h: set sizeof long to 4 on "default 32 bit" systems
+  
+  Triggered a test failure on test 1541 for the build known as
+  "Linux 4.4 i686 tcc 0.9.26 glibc 2.20"
+
+Marcel Raad (6 Apr 2017)
+- nss: fix build after e60fe20fdf94e829ba5fce33f7a9d6c281149f7d
+  
+  Curl_llist_alloc is now Curl_llist_init.
+  
+  Closes https://github.com/curl/curl/pull/1391
+
+Daniel Stenberg (6 Apr 2017)
+- INSTALL.cmake: more problems
+  
+  and mention specific issues where they are discussed
+
+- test1541: ignore the curl_off_t variable type name comparison
+  
+  ... the sizes and the formatting strings are what's really important and
+  avoids problems with int64_t vs "long long".
+  
+  Bug: https://curl.haxx.se/mail/lib-2017-04/0019.html
+
+- Revert "configure: prefer 'long long' to int64_t for curl_off_t"
+  
+  This reverts commit 81284374bf3c670d2050f8562edeb69f060b07cc.
+  
+  Due to mingw32 brekage.
+
+Marcel Raad (5 Apr 2017)
+- tool_operate: fix MinGW compiler warning
+  
+  MinGW complains:
+  tool_operate.c:197:15: error: comparison is always true due to limited range
+  of data type [-Werror=type-limits]
+  
+  Fix this by only doing the comparison if 'long' is large enough to hold the
+  constant it is compared with.
+  
+  Closes https://github.com/curl/curl/pull/1378
+
+- tool_operate: move filetime code to its own function
+  
+  Ref: https://github.com/curl/curl/pull/1378
+
+Daniel Stenberg (5 Apr 2017)
+- configure: prefer 'long long' to int64_t for curl_off_t
+  
+  Since it is a native type and it makes it less complicated to find a
+  matching one in system.h
+  
+  Bug: https://curl.haxx.se/mail/lib-2017-04/0010.html
+  Reported-by: Dan Fandrich
+  
+  Closes #1388
+
+- [DÃ¡niel Bakai brought this change]
+
+  tests: added test for Curl_splaygetbest to unit1309
+  
+  This checks the new behavior of Curl_splaygetbest, so that the smallest
+  node not larger than the key is removed, and FIFO behavior is kept even
+  when there are multiple nodes with the same key.
+  
+  Closes #1358
+
+- [DÃ¡niel Bakai brought this change]
+
+  multi: fix queueing of pending easy handles
+  
+  Multi handles repeatedly invert the queue of pending easy handles when
+  used with CURLMOPT_MAX_TOTAL_CONNECTIONS. This is caused by a multistep
+  process involving Curl_splaygetbest and violates the FIFO property of
+  the multi handle.
+  This patch fixes this issue by redefining the "best" node in the
+  context of timeouts as the "smallest not larger than now", and
+  implementing the necessary data structure modifications to do this
+  effectively, namely:
+   - splay nodes with the same key are now stored in a doubly-linked
+     circular list instead of a non-circular one to enable O(1)
+     insertion to the tail of the list
+   - Curl_splayinsert inserts nodes with the same key to the tail of
+     the same list
+   - in case of multiple nodes with the same key, the one on the head of
+     the list gets selected
+
+Marcel Raad (4 Apr 2017)
+- tool: fix Windows Unicode build
+  
+  ... by explicitly calling the ANSI versions of Windows API functions where
+  required.
+
+Daniel Stenberg (4 Apr 2017)
+- [Martin Kepplinger brought this change]
+
+  curl_sasl: declare mechtable static
+  
+  struct mechtable is only used locally here. It can be declared static.
+
+Jay Satiro (4 Apr 2017)
+- [Antti HÃ¤tÃ¤lÃ¤ brought this change]
+
+  url: don't free postponed data on connection reuse
+  
+  - Don't free postponed data on a connection that will be reused since
+    doing so can cause data loss when pipelining.
+  
+  Only Windows builds are affected by this.
+  
+  Closes https://github.com/curl/curl/issues/1380
+
+Daniel Stenberg (4 Apr 2017)
+- RELEASE-NOTES: synced with 4f2e348f9b42c69c480
+
+- hash: move key into hash struct to reduce mallocs
+  
+  This removes one tiny malloc for each hash struct allocated. In a simple
+  case like "curl localhost", this save three mallocs.
+  
+  Closes #1376
+
+- llist: replace Curl_llist_alloc with Curl_llist_init
+  
+  No longer allocate the curl_llist head struct for lists separately.
+  
+  Removes 17 (15%) tiny allocations in a normal "curl localhost" invoke.
+  
+  closes #1381
+
+Jay Satiro (4 Apr 2017)
+- easy: silence compiler warning
+  
+  Safe to silence warning adding time delta of poll, which can trigger on
+  Windows since sizeof time_t > sizeof long.
+  
+  warning C4244: '+=' : conversion from 'time_t' to 'long', possible loss
+  of data
+
+Daniel Stenberg (4 Apr 2017)
+- [Richlv brought this change]
+
+  docs: minor typo in write-out.d
+  
+  Closes #1382
+
+- include: curl/system.h is a run-time version of curlbuild.h
+  
+  system.h is aimed to replace curlbuild.h at a later point in time when
+  we feel confident system.h works sufficiently well.
+  
+  curl/system.h is currently used in parallel with curl/curlbuild.h
+  
+  curl/system.h determines a data sizes, data types and include file
+  status based on available preprocessor defines instead of getting
+  generated at build-time. This, in order to avoid relying on a build-time
+  generated file that makes it complicated to do 32 and 64 bit bields from
+  the same installed set of headers.
+  
+  Test 1541 verifies that system.h comes to the same conclusion that
+  curlbuild.h offers.
+  
+  Closes #1373
+
+- multi: make curl_multi_wait avoid malloc in the typical case
+  
+  When only a few additional file descriptors are used, avoid the malloc.
+  
+  Closes #1377
Index: EcnlProtoTool/trunk/curl-7.57.0/COPYING
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/COPYING	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/COPYING	(revision 331)
@@ -0,0 +1,22 @@
+COPYRIGHT AND PERMISSION NOTICE
+
+Copyright (c) 1996 - 2017, Daniel Stenberg, <daniel@haxx.se>, and many
+contributors, see the THANKS file.
+
+All rights reserved.
+
+Permission to use, copy, modify, and distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright
+notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
+NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder shall not
+be used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization of the copyright holder.
Index: EcnlProtoTool/trunk/curl-7.57.0/README
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/README	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/README	(revision 331)
@@ -0,0 +1,49 @@
+                                  _   _ ____  _
+                              ___| | | |  _ \| |
+                             / __| | | | |_) | |
+                            | (__| |_| |  _ <| |___
+                             \___|\___/|_| \_\_____|
+
+README
+
+  Curl is a command line tool for transferring data specified with URL
+  syntax. Find out how to use curl by reading the curl.1 man page or the
+  MANUAL document. Find out how to install Curl by reading the INSTALL
+  document.
+
+  libcurl is the library curl is using to do its job. It is readily
+  available to be used by your software. Read the libcurl.3 man page to
+  learn how!
+
+  You find answers to the most frequent questions we get in the FAQ document.
+
+  Study the COPYING file for distribution terms and similar. If you distribute
+  curl binaries or other binaries that involve libcurl, you might enjoy the
+  LICENSE-MIXING document.
+
+CONTACT
+
+  If you have problems, questions, ideas or suggestions, please contact us
+  by posting to a suitable mailing list. See https://curl.haxx.se/mail/
+
+  All contributors to the project are listed in the THANKS document.
+
+WEB SITE
+
+  Visit the curl web site for the latest news and downloads:
+
+        https://curl.haxx.se/
+
+GIT
+
+  To download the very latest source off the GIT server do this:
+
+    git clone https://github.com/curl/curl.git
+
+  (you'll get a directory named curl created, filled with the source code)
+
+NOTICE
+
+  Curl contains pieces of source code that is Copyright (c) 1998, 1999
+  Kungliga Tekniska H旦gskolan. This notice is included here to comply with the
+  distribution terms.
Index: EcnlProtoTool/trunk/curl-7.57.0/RELEASE-NOTES
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/RELEASE-NOTES	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/RELEASE-NOTES	(revision 331)
@@ -0,0 +1,163 @@
+Curl and libcurl 7.57.0
+
+ Public curl releases:         171
+ Command line options:         211
+ curl_easy_setopt() options:   249
+ Public functions in libcurl:  74
+ Contributors:                 1649
+
+This release includes the following changes:
+
+ o auth: add support for RFC7616 - HTTP Digest access authentication [12]
+ o share: add support for sharing the connection cache [31]
+ o HTTP: implement Brotli content encoding [28]
+
+This release includes the following bugfixes:
+
+ o CVE-2017-8816: NTLM buffer overflow via integer overflow [47]
+ o CVE-2017-8817: FTP wildcard out of bounds read [48]
+ o CVE-2017-8818: SSL out of buffer access [49]
+ o curl_mime_filedata.3: fix typos [1]
+ o libtest: Add required test libraries for lib1552 and lib1553 [2]
+ o fix time diffs for systems using unsigned time_t [3]
+ o ftplistparser: memory leak fix: free temporary memory always [4]
+ o multi: allow table handle sizes to be overridden [5]
+ o wildcards: don't use with non-supported protocols [6]
+ o curl_fnmatch: return error on illegal wildcard pattern [7]
+ o transfer: Fix chunked-encoding upload too early exit [8]
+ o curl_setup: Improve detection of CURL_WINDOWS_APP [9]
+ o resolvers: only include anything if needed [10]
+ o setopt: fix CURLOPT_SSH_AUTH_TYPES option read
+ o appveyor: add a win32 build
+ o Curl_timeleft: change return type to timediff_t [11]
+ o cmake: Export libcurl and curl targets to use by other cmake projects [13]
+ o curl: in -F option arg, comma is a delimiter for files only [14]
+ o curl: improved ";type=" handling in -F option arguments
+ o timeval: use mach_absolute_time() on MacOS [15]
+ o curlx: the timeval functions are no longer provided as curlx_* [16]
+ o mkhelp.pl: do not generate comment with current date [17]
+ o memdebug: use send/recv signature for curl_dosend/curl_dorecv [18]
+ o cookie: avoid NULL dereference [19]
+ o url: fix CURLOPT_POSTFIELDSIZE arg value check to allow -1 [20]
+ o include: remove conncache.h inclusion from where its not needed
+ o CURLOPT_MAXREDIRS: allow -1 as a value [21]
+ o tests: Fixed torture tests on tests 556 and 650
+ o http2: Fixed OOM handling in upgrade request
+ o url: fix CURLOPT_DNS_CACHE_TIMEOUT arg value check to allow -1
+ o CURLOPT_INFILESIZE: accept -1 [22]
+ o curl: pass through [] in URLs instead of calling globbing error [23]
+ o curl: speed up handling of many URLs [24]
+ o ntlm: avoid malloc(0) for zero length passwords [25]
+ o url: remove faulty arg value check from CURLOPT_SSH_AUTH_TYPES [26]
+ o HTTP: support multiple Content-Encodings [27]
+ o travis: add a job with brotli enabled
+ o url: remove unncessary NULL-check
+ o fnmatch: remove dead code
+ o connect: store IPv6 connection status after valid connection [29]
+ o imap: deal with commands case insensitively [30]
+ o --interface: add support for Linux VRF [32]
+ o content_encoding: fix inflate_stream for no bytes available [33]
+ o cmake: Correctly include curl.rc in Windows builds [34]
+ o cmake: Add missing setmode check [35]
+ o connect.c: remove executable bit on file [36]
+ o SMB: fix uninitialized local variable
+ o zlib/brotli: only include header files in modules needing them [37]
+ o URL: return error on malformed URLs with junk after IPv6 bracket [38]
+ o openssl: fix too broad use of HAVE_OPAQUE_EVP_PKEY [39]
+ o macOS: Fix missing connectx function with Xcode version older than 9.0 [40]
+ o --resolve: allow IP address within [] brackets [41]
+ o examples/curlx: Fix code style [42]
+ o ntlm: remove unnecessary NULL-check to please scan-build [43]
+ o Curl_llist_remove: fix potential NULL pointer deref [43]
+ o mime: fix "Value stored to 'sz' is never read" scan-build error [43]
+ o openssl: fix "Value stored to 'rc' is never read" scan-build error [43]
+ o http2: fix "Value stored to 'hdbuf' is never read" scan-build error [43]
+ o http2: fix "Value stored to 'end' is never read" scan-build error [43]
+ o Curl_open: fix OOM return error correctly [43]
+ o url: reject ASCII control characters and space in host names [44]
+ o examples/rtsp: clear RANGE again after use [45]
+ o connect: improve the bind error message [46]
+ o make: fix "make distclean" [50]
+ o connect: add support for new TCP Fast Open API on Linux [51]
+ o metalink: fix memory-leak and NULL pointer dereference [52]
+ o URL: update "file:" URL handling [53]
+ o ssh: remove check for a NULL pointer [54]
+ o global_init: ignore CURL_GLOBAL_SSL's absense [55]
+
+This release includes the following known bugs:
+
+ o see docs/KNOWN_BUGS (https://curl.haxx.se/docs/knownbugs.html)
+
+This release would not have looked like this without help, code, reports and
+advice from friends like these:
+
+  Alessandro Ghedini, Alex Malinovich, Alex Nichols, Alfonso Martone,
+  Andrew Lambert, arainchik on github, Brian Carpenter, cbartl on github,
+  Dan Fandrich, Daniel Bankhead, Daniel Stenberg, Dirk Feytons,
+  Dmitri Tikhonov, Evgeny Grin, Gisle Vanem, hsiao yi, Jakub Zakrzewski,
+  John Starks, Juro Bystricky, Kamil Dudka, Luca Boccassi, Marcel Raad,
+  Martin Storsj旦, Matthew Kerwin, Max Dymond, Michael Felt, Michael Kaufmann,
+  moohoorama on github, omau on github, Orgad Shaneh, Patrick Monnerat,
+  Paul Howarth, Pavel Gushchin, Pavol Markovic, Per Lundberg, Peter Piekarski,
+  Petr Voytsik, Ray Satiro, Rob Cotrone, Viktor Szak叩ts, youngchopin on github,
+  (41 contributors)
+
+        Thanks! (and sorry if I forgot to mention someone)
+
+References to bug reports and discussions on issues:
+
+ [1] = https://curl.haxx.se/bug/?i=2008
+ [2] = https://curl.haxx.se/bug/?i=2006
+ [3] = https://curl.haxx.se/bug/?i=2004
+ [4] = https://curl.haxx.se/bug/?i=2013
+ [5] = https://curl.haxx.se/bug/?i=1982
+ [6] = https://curl.haxx.se/bug/?i=2016
+ [7] = https://curl.haxx.se/bug/?i=2015
+ [8] = https://curl.haxx.se/bug/?i=2001
+ [9] = https://curl.haxx.se/bug/?i=2025
+ [10] = https://curl.haxx.se/bug/?i=2023
+ [11] = https://curl.haxx.se/bug/?i=2021
+ [12] = https://curl.haxx.se/bug/?i=1934
+ [13] = https://curl.haxx.se/bug/?i=1879
+ [14] = https://curl.haxx.se/bug/?i=2022
+ [15] = https://curl.haxx.se/bug/?i=2033
+ [16] = https://curl.haxx.se/bug/?i=2034
+ [17] = https://curl.haxx.se/bug/?i=2026
+ [18] = https://curl.haxx.se/bug/?i=2031
+ [19] = https://curl.haxx.se/bug/?i=2032
+ [20] = https://curl.haxx.se/mail/lib-2017-11/0000.html
+ [21] = https://curl.haxx.se/bug/?i=2038
+ [22] = https://curl.haxx.se/bug/?i=2047
+ [23] = https://curl.haxx.se/bug/?i=2044
+ [24] = https://curl.haxx.se/bug/?i=1959
+ [25] = https://curl.haxx.se/bug/?i=2054
+ [26] = https://github.com/curl/curl/commit/f121575#commitcomment-25347120
+ [27] = https://curl.haxx.se/bug/?i=2002
+ [28] = https://curl.haxx.se/bug/?i=2045
+ [29] = https://curl.haxx.se/bug/?i=2053
+ [30] = https://curl.haxx.se/bug/?i=2061
+ [31] = https://curl.haxx.se/bug/?i=2043
+ [32] = https://curl.haxx.se/bug/?i=2024
+ [33] = https://curl.haxx.se/bug/?i=2060
+ [34] = https://curl.haxx.se/bug/?i=2064
+ [35] = https://curl.haxx.se/bug/?i=2067
+ [36] = https://curl.haxx.se/bug/?i=2071
+ [37] = https://curl.haxx.se/mail/lib-2017-11/0032.html
+ [38] = https://curl.haxx.se/bug/?i=2072
+ [39] = https://curl.haxx.se/bug/?i=2079
+ [40] = https://curl.haxx.se/bug/?i=2080
+ [41] = https://curl.haxx.se/bug/?i=2087
+ [42] = https://curl.haxx.se/bug/?i=2096
+ [43] = https://curl.haxx.se/bug/?i=2098
+ [44] = https://curl.haxx.se/bug/?i=2073
+ [45] = https://curl.haxx.se/bug/?i=2106
+ [46] = https://curl.haxx.se/bug/?i=2104
+ [47] = https://curl.haxx.se/docs/adv_2017-11e7.html
+ [48] = https://curl.haxx.se/docs/adv_2017-ae72.html
+ [49] = https://curl.haxx.se/docs/adv_2017-af0a.html
+ [50] = https://curl.haxx.se/bug/?i=2097
+ [51] = https://curl.haxx.se/bug/?i=2056
+ [52] = https://curl.haxx.se/bug/?i=2109
+ [53] = https://curl.haxx.se/bug/?i=2110
+ [54] = https://curl.haxx.se/bug/?i=2111
+ [55] = https://curl.haxx.se/bug/?i=2083
Index: EcnlProtoTool/trunk/curl-7.57.0/include/README
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/include/README	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/include/README	(revision 331)
@@ -0,0 +1,33 @@
+                                  _   _ ____  _
+                              ___| | | |  _ \| |
+                             / __| | | | |_) | |
+                            | (__| |_| |  _ <| |___
+                             \___|\___/|_| \_\_____|
+
+Include files for libcurl, external users.
+
+They're all placed in the curl subdirectory here for better fit in any kind
+of environment. You must include files from here using...
+
+        #include <curl/curl.h>
+
+... style and point the compiler's include path to the directory holding the
+curl subdirectory. It makes it more likely to survive future modifications.
+
+NOTE FOR LIBCURL HACKERS
+
+* If you check out from git on a non-configure platform, you must run the
+  appropriate buildconf* script to set up files before being able of compiling
+  the library.
+
+* We cannot assume anything else but very basic compiler features being
+  present. While libcurl requires an ANSI C compiler to build, some of the
+  earlier ANSI compilers clearly can't deal with some preprocessor operators.
+
+* Newlines must remain unix-style for older compilers' sake.
+
+* Comments must be written in the old-style /* unnested C-fashion */
+
+To figure out how to do good and portable checks for features, operating
+systems or specific hardwarare, a very good resource is Bjorn Reese's
+collection at https://sourceforge.net/p/predef/wiki/
Index: EcnlProtoTool/trunk/curl-7.57.0/include/curl/curl.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/include/curl/curl.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/include/curl/curl.h	(revision 331)
@@ -0,0 +1,2748 @@
+#ifndef __CURL_CURL_H
+#define __CURL_CURL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * If you have libcurl problems, all docs and details are found here:
+ *   https://curl.haxx.se/libcurl/
+ *
+ * curl-library mailing list subscription and unsubscription web interface:
+ *   https://cool.haxx.se/mailman/listinfo/curl-library/
+ */
+
+#ifdef CURL_NO_OLDIES
+#define CURL_STRICTER
+#endif
+
+#include "curlver.h"         /* libcurl version defines   */
+#include "system.h"          /* determine things run-time */
+
+/*
+ * Define WIN32 when build target is Win32 API
+ */
+
+#if (defined(_WIN32) || defined(__WIN32__)) && \
+     !defined(WIN32) && !defined(__SYMBIAN32__)
+#define WIN32
+#endif
+
+#include <stdio.h>
+#include <limits.h>
+
+#if defined(__FreeBSD__) && (__FreeBSD__ >= 2)
+/* Needed for __FreeBSD_version symbol definition */
+#include <osreldate.h>
+#endif
+
+/* The include stuff here below is mainly for time_t! */
+#include <sys/types.h>
+#include <time.h>
+
+#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__)
+#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \
+      defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H))
+/* The check above prevents the winsock2 inclusion if winsock.h already was
+   included, since they can't co-exist without problems */
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#endif
+#endif
+
+/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish
+   libc5-based Linux systems. Only include it on systems that are known to
+   require it! */
+#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \
+    defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \
+    defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \
+    defined(__CYGWIN__) || \
+   (defined(__FreeBSD_version) && (__FreeBSD_version < 800000))
+#include <sys/select.h>
+#endif
+
+#if !defined(WIN32) && !defined(_WIN32_WCE)
+#include <sys/socket.h>
+#endif
+
+#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__)
+#include <sys/time.h>
+#endif
+
+#ifdef __BEOS__
+#include <support/SupportDefs.h>
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
+typedef struct Curl_easy CURL;
+typedef struct Curl_share CURLSH;
+#else
+typedef void CURL;
+typedef void CURLSH;
+#endif
+
+/*
+ * libcurl external API function linkage decorations.
+ */
+
+#ifdef CURL_STATICLIB
+#  define CURL_EXTERN
+#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)
+#  if defined(BUILDING_LIBCURL)
+#    define CURL_EXTERN  __declspec(dllexport)
+#  else
+#    define CURL_EXTERN  __declspec(dllimport)
+#  endif
+#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS)
+#  define CURL_EXTERN CURL_EXTERN_SYMBOL
+#else
+#  define CURL_EXTERN
+#endif
+
+#ifndef curl_socket_typedef
+/* socket typedef */
+#if defined(WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H)
+typedef SOCKET curl_socket_t;
+#define CURL_SOCKET_BAD INVALID_SOCKET
+#else
+typedef int curl_socket_t;
+#define CURL_SOCKET_BAD -1
+#endif
+#define curl_socket_typedef
+#endif /* curl_socket_typedef */
+
+/* enum for the different supported SSL backends */
+typedef enum {
+  CURLSSLBACKEND_NONE = 0,
+  CURLSSLBACKEND_OPENSSL = 1,
+  CURLSSLBACKEND_GNUTLS = 2,
+  CURLSSLBACKEND_NSS = 3,
+  CURLSSLBACKEND_OBSOLETE4 = 4,  /* Was QSOSSL. */
+  CURLSSLBACKEND_GSKIT = 5,
+  CURLSSLBACKEND_POLARSSL = 6,
+  CURLSSLBACKEND_WOLFSSL = 7,
+  CURLSSLBACKEND_SCHANNEL = 8,
+  CURLSSLBACKEND_DARWINSSL = 9,
+  CURLSSLBACKEND_AXTLS = 10,
+  CURLSSLBACKEND_MBEDTLS = 11
+} curl_sslbackend;
+
+/* aliases for library clones and renames */
+#define CURLSSLBACKEND_LIBRESSL CURLSSLBACKEND_OPENSSL
+#define CURLSSLBACKEND_BORINGSSL CURLSSLBACKEND_OPENSSL
+#define CURLSSLBACKEND_CYASSL CURLSSLBACKEND_WOLFSSL
+
+struct curl_httppost {
+  struct curl_httppost *next;       /* next entry in the list */
+  char *name;                       /* pointer to allocated name */
+  long namelength;                  /* length of name length */
+  char *contents;                   /* pointer to allocated data contents */
+  long contentslength;              /* length of contents field, see also
+                                       CURL_HTTPPOST_LARGE */
+  char *buffer;                     /* pointer to allocated buffer contents */
+  long bufferlength;                /* length of buffer field */
+  char *contenttype;                /* Content-Type */
+  struct curl_slist *contentheader; /* list of extra headers for this form */
+  struct curl_httppost *more;       /* if one field name has more than one
+                                       file, this link should link to following
+                                       files */
+  long flags;                       /* as defined below */
+
+/* specified content is a file name */
+#define CURL_HTTPPOST_FILENAME (1<<0)
+/* specified content is a file name */
+#define CURL_HTTPPOST_READFILE (1<<1)
+/* name is only stored pointer do not free in formfree */
+#define CURL_HTTPPOST_PTRNAME (1<<2)
+/* contents is only stored pointer do not free in formfree */
+#define CURL_HTTPPOST_PTRCONTENTS (1<<3)
+/* upload file from buffer */
+#define CURL_HTTPPOST_BUFFER (1<<4)
+/* upload file from pointer contents */
+#define CURL_HTTPPOST_PTRBUFFER (1<<5)
+/* upload file contents by using the regular read callback to get the data and
+   pass the given pointer as custom pointer */
+#define CURL_HTTPPOST_CALLBACK (1<<6)
+/* use size in 'contentlen', added in 7.46.0 */
+#define CURL_HTTPPOST_LARGE (1<<7)
+
+  char *showfilename;               /* The file name to show. If not set, the
+                                       actual file name will be used (if this
+                                       is a file part) */
+  void *userp;                      /* custom pointer used for
+                                       HTTPPOST_CALLBACK posts */
+  curl_off_t contentlen;            /* alternative length of contents
+                                       field. Used if CURL_HTTPPOST_LARGE is
+                                       set. Added in 7.46.0 */
+};
+
+/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered
+   deprecated but was the only choice up until 7.31.0 */
+typedef int (*curl_progress_callback)(void *clientp,
+                                      double dltotal,
+                                      double dlnow,
+                                      double ultotal,
+                                      double ulnow);
+
+/* This is the CURLOPT_XFERINFOFUNCTION callback proto. It was introduced in
+   7.32.0, it avoids floating point and provides more detailed information. */
+typedef int (*curl_xferinfo_callback)(void *clientp,
+                                      curl_off_t dltotal,
+                                      curl_off_t dlnow,
+                                      curl_off_t ultotal,
+                                      curl_off_t ulnow);
+
+#ifndef CURL_MAX_READ_SIZE
+  /* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */
+#define CURL_MAX_READ_SIZE 524288
+#endif
+
+#ifndef CURL_MAX_WRITE_SIZE
+  /* Tests have proven that 20K is a very bad buffer size for uploads on
+     Windows, while 16K for some odd reason performed a lot better.
+     We do the ifndef check to allow this value to easier be changed at build
+     time for those who feel adventurous. The practical minimum is about
+     400 bytes since libcurl uses a buffer of this size as a scratch area
+     (unrelated to network send operations). */
+#define CURL_MAX_WRITE_SIZE 16384
+#endif
+
+#ifndef CURL_MAX_HTTP_HEADER
+/* The only reason to have a max limit for this is to avoid the risk of a bad
+   server feeding libcurl with a never-ending header that will cause reallocs
+   infinitely */
+#define CURL_MAX_HTTP_HEADER (100*1024)
+#endif
+
+/* This is a magic return code for the write callback that, when returned,
+   will signal libcurl to pause receiving on the current transfer. */
+#define CURL_WRITEFUNC_PAUSE 0x10000001
+
+typedef size_t (*curl_write_callback)(char *buffer,
+                                      size_t size,
+                                      size_t nitems,
+                                      void *outstream);
+
+
+
+/* enumeration of file types */
+typedef enum {
+  CURLFILETYPE_FILE = 0,
+  CURLFILETYPE_DIRECTORY,
+  CURLFILETYPE_SYMLINK,
+  CURLFILETYPE_DEVICE_BLOCK,
+  CURLFILETYPE_DEVICE_CHAR,
+  CURLFILETYPE_NAMEDPIPE,
+  CURLFILETYPE_SOCKET,
+  CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */
+
+  CURLFILETYPE_UNKNOWN /* should never occur */
+} curlfiletype;
+
+#define CURLFINFOFLAG_KNOWN_FILENAME    (1<<0)
+#define CURLFINFOFLAG_KNOWN_FILETYPE    (1<<1)
+#define CURLFINFOFLAG_KNOWN_TIME        (1<<2)
+#define CURLFINFOFLAG_KNOWN_PERM        (1<<3)
+#define CURLFINFOFLAG_KNOWN_UID         (1<<4)
+#define CURLFINFOFLAG_KNOWN_GID         (1<<5)
+#define CURLFINFOFLAG_KNOWN_SIZE        (1<<6)
+#define CURLFINFOFLAG_KNOWN_HLINKCOUNT  (1<<7)
+
+/* Content of this structure depends on information which is known and is
+   achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man
+   page for callbacks returning this structure -- some fields are mandatory,
+   some others are optional. The FLAG field has special meaning. */
+struct curl_fileinfo {
+  char *filename;
+  curlfiletype filetype;
+  time_t time;
+  unsigned int perm;
+  int uid;
+  int gid;
+  curl_off_t size;
+  long int hardlinks;
+
+  struct {
+    /* If some of these fields is not NULL, it is a pointer to b_data. */
+    char *time;
+    char *perm;
+    char *user;
+    char *group;
+    char *target; /* pointer to the target filename of a symlink */
+  } strings;
+
+  unsigned int flags;
+
+  /* used internally */
+  char *b_data;
+  size_t b_size;
+  size_t b_used;
+};
+
+/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */
+#define CURL_CHUNK_BGN_FUNC_OK      0
+#define CURL_CHUNK_BGN_FUNC_FAIL    1 /* tell the lib to end the task */
+#define CURL_CHUNK_BGN_FUNC_SKIP    2 /* skip this chunk over */
+
+/* if splitting of data transfer is enabled, this callback is called before
+   download of an individual chunk started. Note that parameter "remains" works
+   only for FTP wildcard downloading (for now), otherwise is not used */
+typedef long (*curl_chunk_bgn_callback)(const void *transfer_info,
+                                        void *ptr,
+                                        int remains);
+
+/* return codes for CURLOPT_CHUNK_END_FUNCTION */
+#define CURL_CHUNK_END_FUNC_OK      0
+#define CURL_CHUNK_END_FUNC_FAIL    1 /* tell the lib to end the task */
+
+/* If splitting of data transfer is enabled this callback is called after
+   download of an individual chunk finished.
+   Note! After this callback was set then it have to be called FOR ALL chunks.
+   Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC.
+   This is the reason why we don't need "transfer_info" parameter in this
+   callback and we are not interested in "remains" parameter too. */
+typedef long (*curl_chunk_end_callback)(void *ptr);
+
+/* return codes for FNMATCHFUNCTION */
+#define CURL_FNMATCHFUNC_MATCH    0 /* string corresponds to the pattern */
+#define CURL_FNMATCHFUNC_NOMATCH  1 /* pattern doesn't match the string */
+#define CURL_FNMATCHFUNC_FAIL     2 /* an error occurred */
+
+/* callback type for wildcard downloading pattern matching. If the
+   string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */
+typedef int (*curl_fnmatch_callback)(void *ptr,
+                                     const char *pattern,
+                                     const char *string);
+
+/* These are the return codes for the seek callbacks */
+#define CURL_SEEKFUNC_OK       0
+#define CURL_SEEKFUNC_FAIL     1 /* fail the entire transfer */
+#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so
+                                    libcurl might try other means instead */
+typedef int (*curl_seek_callback)(void *instream,
+                                  curl_off_t offset,
+                                  int origin); /* 'whence' */
+
+/* This is a return code for the read callback that, when returned, will
+   signal libcurl to immediately abort the current transfer. */
+#define CURL_READFUNC_ABORT 0x10000000
+/* This is a return code for the read callback that, when returned, will
+   signal libcurl to pause sending data on the current transfer. */
+#define CURL_READFUNC_PAUSE 0x10000001
+
+typedef size_t (*curl_read_callback)(char *buffer,
+                                      size_t size,
+                                      size_t nitems,
+                                      void *instream);
+
+typedef enum {
+  CURLSOCKTYPE_IPCXN,  /* socket created for a specific IP connection */
+  CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */
+  CURLSOCKTYPE_LAST    /* never use */
+} curlsocktype;
+
+/* The return code from the sockopt_callback can signal information back
+   to libcurl: */
+#define CURL_SOCKOPT_OK 0
+#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return
+                                CURLE_ABORTED_BY_CALLBACK */
+#define CURL_SOCKOPT_ALREADY_CONNECTED 2
+
+typedef int (*curl_sockopt_callback)(void *clientp,
+                                     curl_socket_t curlfd,
+                                     curlsocktype purpose);
+
+struct curl_sockaddr {
+  int family;
+  int socktype;
+  int protocol;
+  unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it
+                           turned really ugly and painful on the systems that
+                           lack this type */
+  struct sockaddr addr;
+};
+
+typedef curl_socket_t
+(*curl_opensocket_callback)(void *clientp,
+                            curlsocktype purpose,
+                            struct curl_sockaddr *address);
+
+typedef int
+(*curl_closesocket_callback)(void *clientp, curl_socket_t item);
+
+typedef enum {
+  CURLIOE_OK,            /* I/O operation successful */
+  CURLIOE_UNKNOWNCMD,    /* command was unknown to callback */
+  CURLIOE_FAILRESTART,   /* failed to restart the read */
+  CURLIOE_LAST           /* never use */
+} curlioerr;
+
+typedef enum {
+  CURLIOCMD_NOP,         /* no operation */
+  CURLIOCMD_RESTARTREAD, /* restart the read stream from start */
+  CURLIOCMD_LAST         /* never use */
+} curliocmd;
+
+typedef curlioerr (*curl_ioctl_callback)(CURL *handle,
+                                         int cmd,
+                                         void *clientp);
+
+#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS
+/*
+ * The following typedef's are signatures of malloc, free, realloc, strdup and
+ * calloc respectively.  Function pointers of these types can be passed to the
+ * curl_global_init_mem() function to set user defined memory management
+ * callback routines.
+ */
+typedef void *(*curl_malloc_callback)(size_t size);
+typedef void (*curl_free_callback)(void *ptr);
+typedef void *(*curl_realloc_callback)(void *ptr, size_t size);
+typedef char *(*curl_strdup_callback)(const char *str);
+typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size);
+
+#define CURL_DID_MEMORY_FUNC_TYPEDEFS
+#endif
+
+/* the kind of data that is passed to information_callback*/
+typedef enum {
+  CURLINFO_TEXT = 0,
+  CURLINFO_HEADER_IN,    /* 1 */
+  CURLINFO_HEADER_OUT,   /* 2 */
+  CURLINFO_DATA_IN,      /* 3 */
+  CURLINFO_DATA_OUT,     /* 4 */
+  CURLINFO_SSL_DATA_IN,  /* 5 */
+  CURLINFO_SSL_DATA_OUT, /* 6 */
+  CURLINFO_END
+} curl_infotype;
+
+typedef int (*curl_debug_callback)
+       (CURL *handle,      /* the handle/transfer this concerns */
+        curl_infotype type, /* what kind of data */
+        char *data,        /* points to the data */
+        size_t size,       /* size of the data pointed to */
+        void *userptr);    /* whatever the user please */
+
+/* All possible error codes from all sorts of curl functions. Future versions
+   may return other values, stay prepared.
+
+   Always add new return codes last. Never *EVER* remove any. The return
+   codes must remain the same!
+ */
+
+typedef enum {
+  CURLE_OK = 0,
+  CURLE_UNSUPPORTED_PROTOCOL,    /* 1 */
+  CURLE_FAILED_INIT,             /* 2 */
+  CURLE_URL_MALFORMAT,           /* 3 */
+  CURLE_NOT_BUILT_IN,            /* 4 - [was obsoleted in August 2007 for
+                                    7.17.0, reused in April 2011 for 7.21.5] */
+  CURLE_COULDNT_RESOLVE_PROXY,   /* 5 */
+  CURLE_COULDNT_RESOLVE_HOST,    /* 6 */
+  CURLE_COULDNT_CONNECT,         /* 7 */
+  CURLE_WEIRD_SERVER_REPLY,      /* 8 */
+  CURLE_REMOTE_ACCESS_DENIED,    /* 9 a service was denied by the server
+                                    due to lack of access - when login fails
+                                    this is not returned. */
+  CURLE_FTP_ACCEPT_FAILED,       /* 10 - [was obsoleted in April 2006 for
+                                    7.15.4, reused in Dec 2011 for 7.24.0]*/
+  CURLE_FTP_WEIRD_PASS_REPLY,    /* 11 */
+  CURLE_FTP_ACCEPT_TIMEOUT,      /* 12 - timeout occurred accepting server
+                                    [was obsoleted in August 2007 for 7.17.0,
+                                    reused in Dec 2011 for 7.24.0]*/
+  CURLE_FTP_WEIRD_PASV_REPLY,    /* 13 */
+  CURLE_FTP_WEIRD_227_FORMAT,    /* 14 */
+  CURLE_FTP_CANT_GET_HOST,       /* 15 */
+  CURLE_HTTP2,                   /* 16 - A problem in the http2 framing layer.
+                                    [was obsoleted in August 2007 for 7.17.0,
+                                    reused in July 2014 for 7.38.0] */
+  CURLE_FTP_COULDNT_SET_TYPE,    /* 17 */
+  CURLE_PARTIAL_FILE,            /* 18 */
+  CURLE_FTP_COULDNT_RETR_FILE,   /* 19 */
+  CURLE_OBSOLETE20,              /* 20 - NOT USED */
+  CURLE_QUOTE_ERROR,             /* 21 - quote command failure */
+  CURLE_HTTP_RETURNED_ERROR,     /* 22 */
+  CURLE_WRITE_ERROR,             /* 23 */
+  CURLE_OBSOLETE24,              /* 24 - NOT USED */
+  CURLE_UPLOAD_FAILED,           /* 25 - failed upload "command" */
+  CURLE_READ_ERROR,              /* 26 - couldn't open/read from file */
+  CURLE_OUT_OF_MEMORY,           /* 27 */
+  /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
+           instead of a memory allocation error if CURL_DOES_CONVERSIONS
+           is defined
+  */
+  CURLE_OPERATION_TIMEDOUT,      /* 28 - the timeout time was reached */
+  CURLE_OBSOLETE29,              /* 29 - NOT USED */
+  CURLE_FTP_PORT_FAILED,         /* 30 - FTP PORT operation failed */
+  CURLE_FTP_COULDNT_USE_REST,    /* 31 - the REST command failed */
+  CURLE_OBSOLETE32,              /* 32 - NOT USED */
+  CURLE_RANGE_ERROR,             /* 33 - RANGE "command" didn't work */
+  CURLE_HTTP_POST_ERROR,         /* 34 */
+  CURLE_SSL_CONNECT_ERROR,       /* 35 - wrong when connecting with SSL */
+  CURLE_BAD_DOWNLOAD_RESUME,     /* 36 - couldn't resume download */
+  CURLE_FILE_COULDNT_READ_FILE,  /* 37 */
+  CURLE_LDAP_CANNOT_BIND,        /* 38 */
+  CURLE_LDAP_SEARCH_FAILED,      /* 39 */
+  CURLE_OBSOLETE40,              /* 40 - NOT USED */
+  CURLE_FUNCTION_NOT_FOUND,      /* 41 - NOT USED starting with 7.53.0 */
+  CURLE_ABORTED_BY_CALLBACK,     /* 42 */
+  CURLE_BAD_FUNCTION_ARGUMENT,   /* 43 */
+  CURLE_OBSOLETE44,              /* 44 - NOT USED */
+  CURLE_INTERFACE_FAILED,        /* 45 - CURLOPT_INTERFACE failed */
+  CURLE_OBSOLETE46,              /* 46 - NOT USED */
+  CURLE_TOO_MANY_REDIRECTS,      /* 47 - catch endless re-direct loops */
+  CURLE_UNKNOWN_OPTION,          /* 48 - User specified an unknown option */
+  CURLE_TELNET_OPTION_SYNTAX,    /* 49 - Malformed telnet option */
+  CURLE_OBSOLETE50,              /* 50 - NOT USED */
+  CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint
+                                     wasn't verified fine */
+  CURLE_GOT_NOTHING,             /* 52 - when this is a specific error */
+  CURLE_SSL_ENGINE_NOTFOUND,     /* 53 - SSL crypto engine not found */
+  CURLE_SSL_ENGINE_SETFAILED,    /* 54 - can not set SSL crypto engine as
+                                    default */
+  CURLE_SEND_ERROR,              /* 55 - failed sending network data */
+  CURLE_RECV_ERROR,              /* 56 - failure in receiving network data */
+  CURLE_OBSOLETE57,              /* 57 - NOT IN USE */
+  CURLE_SSL_CERTPROBLEM,         /* 58 - problem with the local certificate */
+  CURLE_SSL_CIPHER,              /* 59 - couldn't use specified cipher */
+  CURLE_SSL_CACERT,              /* 60 - problem with the CA cert (path?) */
+  CURLE_BAD_CONTENT_ENCODING,    /* 61 - Unrecognized/bad encoding */
+  CURLE_LDAP_INVALID_URL,        /* 62 - Invalid LDAP URL */
+  CURLE_FILESIZE_EXCEEDED,       /* 63 - Maximum file size exceeded */
+  CURLE_USE_SSL_FAILED,          /* 64 - Requested FTP SSL level failed */
+  CURLE_SEND_FAIL_REWIND,        /* 65 - Sending the data requires a rewind
+                                    that failed */
+  CURLE_SSL_ENGINE_INITFAILED,   /* 66 - failed to initialise ENGINE */
+  CURLE_LOGIN_DENIED,            /* 67 - user, password or similar was not
+                                    accepted and we failed to login */
+  CURLE_TFTP_NOTFOUND,           /* 68 - file not found on server */
+  CURLE_TFTP_PERM,               /* 69 - permission problem on server */
+  CURLE_REMOTE_DISK_FULL,        /* 70 - out of disk space on server */
+  CURLE_TFTP_ILLEGAL,            /* 71 - Illegal TFTP operation */
+  CURLE_TFTP_UNKNOWNID,          /* 72 - Unknown transfer ID */
+  CURLE_REMOTE_FILE_EXISTS,      /* 73 - File already exists */
+  CURLE_TFTP_NOSUCHUSER,         /* 74 - No such user */
+  CURLE_CONV_FAILED,             /* 75 - conversion failed */
+  CURLE_CONV_REQD,               /* 76 - caller must register conversion
+                                    callbacks using curl_easy_setopt options
+                                    CURLOPT_CONV_FROM_NETWORK_FUNCTION,
+                                    CURLOPT_CONV_TO_NETWORK_FUNCTION, and
+                                    CURLOPT_CONV_FROM_UTF8_FUNCTION */
+  CURLE_SSL_CACERT_BADFILE,      /* 77 - could not load CACERT file, missing
+                                    or wrong format */
+  CURLE_REMOTE_FILE_NOT_FOUND,   /* 78 - remote file not found */
+  CURLE_SSH,                     /* 79 - error from the SSH layer, somewhat
+                                    generic so the error message will be of
+                                    interest when this has happened */
+
+  CURLE_SSL_SHUTDOWN_FAILED,     /* 80 - Failed to shut down the SSL
+                                    connection */
+  CURLE_AGAIN,                   /* 81 - socket is not ready for send/recv,
+                                    wait till it's ready and try again (Added
+                                    in 7.18.2) */
+  CURLE_SSL_CRL_BADFILE,         /* 82 - could not load CRL file, missing or
+                                    wrong format (Added in 7.19.0) */
+  CURLE_SSL_ISSUER_ERROR,        /* 83 - Issuer check failed.  (Added in
+                                    7.19.0) */
+  CURLE_FTP_PRET_FAILED,         /* 84 - a PRET command failed */
+  CURLE_RTSP_CSEQ_ERROR,         /* 85 - mismatch of RTSP CSeq numbers */
+  CURLE_RTSP_SESSION_ERROR,      /* 86 - mismatch of RTSP Session Ids */
+  CURLE_FTP_BAD_FILE_LIST,       /* 87 - unable to parse FTP file list */
+  CURLE_CHUNK_FAILED,            /* 88 - chunk callback reported error */
+  CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the
+                                    session will be queued */
+  CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not
+                                     match */
+  CURLE_SSL_INVALIDCERTSTATUS,   /* 91 - invalid certificate status */
+  CURLE_HTTP2_STREAM,            /* 92 - stream error in HTTP/2 framing layer
+                                    */
+  CURL_LAST /* never use! */
+} CURLcode;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+                          the obsolete stuff removed! */
+
+/* Previously obsolete error code re-used in 7.38.0 */
+#define CURLE_OBSOLETE16 CURLE_HTTP2
+
+/* Previously obsolete error codes re-used in 7.24.0 */
+#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED
+#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT
+
+/*  compatibility with older names */
+#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING
+#define CURLE_FTP_WEIRD_SERVER_REPLY CURLE_WEIRD_SERVER_REPLY
+
+/* The following were added in 7.21.5, April 2011 */
+#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION
+
+/* The following were added in 7.17.1 */
+/* These are scheduled to disappear by 2009 */
+#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION
+
+/* The following were added in 7.17.0 */
+/* These are scheduled to disappear by 2009 */
+#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */
+#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46
+#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44
+#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10
+#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16
+#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32
+#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29
+#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12
+#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20
+#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40
+#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24
+#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57
+#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN
+
+#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED
+#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE
+#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR
+#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL
+#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS
+#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR
+#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED
+
+/* The following were added earlier */
+
+#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT
+
+#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR
+#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED
+#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED
+
+#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE
+#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME
+
+/* This was the error code 50 in 7.7.3 and a few earlier versions, this
+   is no longer used by libcurl but is instead #defined here only to not
+   make programs break */
+#define CURLE_ALREADY_COMPLETE 99999
+
+/* Provide defines for really old option names */
+#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */
+#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */
+#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA
+
+/* Since long deprecated options with no code in the lib that does anything
+   with them. */
+#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40
+#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72
+
+#endif /*!CURL_NO_OLDIES*/
+
+/* This prototype applies to all conversion callbacks */
+typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length);
+
+typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl,    /* easy handle */
+                                          void *ssl_ctx, /* actually an
+                                                            OpenSSL SSL_CTX */
+                                          void *userptr);
+
+typedef enum {
+  CURLPROXY_HTTP = 0,   /* added in 7.10, new in 7.19.4 default is to use
+                           CONNECT HTTP/1.1 */
+  CURLPROXY_HTTP_1_0 = 1,   /* added in 7.19.4, force to use CONNECT
+                               HTTP/1.0  */
+  CURLPROXY_HTTPS = 2, /* added in 7.52.0 */
+  CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already
+                           in 7.10 */
+  CURLPROXY_SOCKS5 = 5, /* added in 7.10 */
+  CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */
+  CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the
+                                   host name rather than the IP address. added
+                                   in 7.18.0 */
+} curl_proxytype;  /* this enum was added in 7.10 */
+
+/*
+ * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options:
+ *
+ * CURLAUTH_NONE         - No HTTP authentication
+ * CURLAUTH_BASIC        - HTTP Basic authentication (default)
+ * CURLAUTH_DIGEST       - HTTP Digest authentication
+ * CURLAUTH_NEGOTIATE    - HTTP Negotiate (SPNEGO) authentication
+ * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated)
+ * CURLAUTH_NTLM         - HTTP NTLM authentication
+ * CURLAUTH_DIGEST_IE    - HTTP Digest authentication with IE flavour
+ * CURLAUTH_NTLM_WB      - HTTP NTLM authentication delegated to winbind helper
+ * CURLAUTH_ONLY         - Use together with a single other type to force no
+ *                         authentication or just that single type
+ * CURLAUTH_ANY          - All fine types set
+ * CURLAUTH_ANYSAFE      - All fine types except Basic
+ */
+
+#define CURLAUTH_NONE         ((unsigned long)0)
+#define CURLAUTH_BASIC        (((unsigned long)1)<<0)
+#define CURLAUTH_DIGEST       (((unsigned long)1)<<1)
+#define CURLAUTH_NEGOTIATE    (((unsigned long)1)<<2)
+/* Deprecated since the advent of CURLAUTH_NEGOTIATE */
+#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE
+/* Used for CURLOPT_SOCKS5_AUTH to stay terminologically correct */
+#define CURLAUTH_GSSAPI CURLAUTH_NEGOTIATE
+#define CURLAUTH_NTLM         (((unsigned long)1)<<3)
+#define CURLAUTH_DIGEST_IE    (((unsigned long)1)<<4)
+#define CURLAUTH_NTLM_WB      (((unsigned long)1)<<5)
+#define CURLAUTH_ONLY         (((unsigned long)1)<<31)
+#define CURLAUTH_ANY          (~CURLAUTH_DIGEST_IE)
+#define CURLAUTH_ANYSAFE      (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
+
+#define CURLSSH_AUTH_ANY       ~0     /* all types supported by the server */
+#define CURLSSH_AUTH_NONE      0      /* none allowed, silly but complete */
+#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */
+#define CURLSSH_AUTH_PASSWORD  (1<<1) /* password */
+#define CURLSSH_AUTH_HOST      (1<<2) /* host key files */
+#define CURLSSH_AUTH_KEYBOARD  (1<<3) /* keyboard interactive */
+#define CURLSSH_AUTH_AGENT     (1<<4) /* agent (ssh-agent, pageant...) */
+#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY
+
+#define CURLGSSAPI_DELEGATION_NONE        0      /* no delegation (default) */
+#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */
+#define CURLGSSAPI_DELEGATION_FLAG        (1<<1) /* delegate always */
+
+#define CURL_ERROR_SIZE 256
+
+enum curl_khtype {
+  CURLKHTYPE_UNKNOWN,
+  CURLKHTYPE_RSA1,
+  CURLKHTYPE_RSA,
+  CURLKHTYPE_DSS
+};
+
+struct curl_khkey {
+  const char *key; /* points to a zero-terminated string encoded with base64
+                      if len is zero, otherwise to the "raw" data */
+  size_t len;
+  enum curl_khtype keytype;
+};
+
+/* this is the set of return values expected from the curl_sshkeycallback
+   callback */
+enum curl_khstat {
+  CURLKHSTAT_FINE_ADD_TO_FILE,
+  CURLKHSTAT_FINE,
+  CURLKHSTAT_REJECT, /* reject the connection, return an error */
+  CURLKHSTAT_DEFER,  /* do not accept it, but we can't answer right now so
+                        this causes a CURLE_DEFER error but otherwise the
+                        connection will be left intact etc */
+  CURLKHSTAT_LAST    /* not for use, only a marker for last-in-list */
+};
+
+/* this is the set of status codes pass in to the callback */
+enum curl_khmatch {
+  CURLKHMATCH_OK,       /* match */
+  CURLKHMATCH_MISMATCH, /* host found, key mismatch! */
+  CURLKHMATCH_MISSING,  /* no matching host/key found */
+  CURLKHMATCH_LAST      /* not for use, only a marker for last-in-list */
+};
+
+typedef int
+  (*curl_sshkeycallback) (CURL *easy,     /* easy handle */
+                          const struct curl_khkey *knownkey, /* known */
+                          const struct curl_khkey *foundkey, /* found */
+                          enum curl_khmatch, /* libcurl's view on the keys */
+                          void *clientp); /* custom pointer passed from app */
+
+/* parameter for the CURLOPT_USE_SSL option */
+typedef enum {
+  CURLUSESSL_NONE,    /* do not attempt to use SSL */
+  CURLUSESSL_TRY,     /* try using SSL, proceed anyway otherwise */
+  CURLUSESSL_CONTROL, /* SSL for the control connection or fail */
+  CURLUSESSL_ALL,     /* SSL for all communication or fail */
+  CURLUSESSL_LAST     /* not an option, never use */
+} curl_usessl;
+
+/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */
+
+/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the
+   name of improving interoperability with older servers. Some SSL libraries
+   have introduced work-arounds for this flaw but those work-arounds sometimes
+   make the SSL communication fail. To regain functionality with those broken
+   servers, a user can this way allow the vulnerability back. */
+#define CURLSSLOPT_ALLOW_BEAST (1<<0)
+
+/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those
+   SSL backends where such behavior is present. */
+#define CURLSSLOPT_NO_REVOKE (1<<1)
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+                          the obsolete stuff removed! */
+
+/* Backwards compatibility with older names */
+/* These are scheduled to disappear by 2009 */
+
+#define CURLFTPSSL_NONE CURLUSESSL_NONE
+#define CURLFTPSSL_TRY CURLUSESSL_TRY
+#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL
+#define CURLFTPSSL_ALL CURLUSESSL_ALL
+#define CURLFTPSSL_LAST CURLUSESSL_LAST
+#define curl_ftpssl curl_usessl
+#endif /*!CURL_NO_OLDIES*/
+
+/* parameter for the CURLOPT_FTP_SSL_CCC option */
+typedef enum {
+  CURLFTPSSL_CCC_NONE,    /* do not send CCC */
+  CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */
+  CURLFTPSSL_CCC_ACTIVE,  /* Initiate the shutdown */
+  CURLFTPSSL_CCC_LAST     /* not an option, never use */
+} curl_ftpccc;
+
+/* parameter for the CURLOPT_FTPSSLAUTH option */
+typedef enum {
+  CURLFTPAUTH_DEFAULT, /* let libcurl decide */
+  CURLFTPAUTH_SSL,     /* use "AUTH SSL" */
+  CURLFTPAUTH_TLS,     /* use "AUTH TLS" */
+  CURLFTPAUTH_LAST /* not an option, never use */
+} curl_ftpauth;
+
+/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */
+typedef enum {
+  CURLFTP_CREATE_DIR_NONE,  /* do NOT create missing dirs! */
+  CURLFTP_CREATE_DIR,       /* (FTP/SFTP) if CWD fails, try MKD and then CWD
+                               again if MKD succeeded, for SFTP this does
+                               similar magic */
+  CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD
+                               again even if MKD failed! */
+  CURLFTP_CREATE_DIR_LAST   /* not an option, never use */
+} curl_ftpcreatedir;
+
+/* parameter for the CURLOPT_FTP_FILEMETHOD option */
+typedef enum {
+  CURLFTPMETHOD_DEFAULT,   /* let libcurl pick */
+  CURLFTPMETHOD_MULTICWD,  /* single CWD operation for each path part */
+  CURLFTPMETHOD_NOCWD,     /* no CWD at all */
+  CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */
+  CURLFTPMETHOD_LAST       /* not an option, never use */
+} curl_ftpmethod;
+
+/* bitmask defines for CURLOPT_HEADEROPT */
+#define CURLHEADER_UNIFIED  0
+#define CURLHEADER_SEPARATE (1<<0)
+
+/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
+#define CURLPROTO_HTTP   (1<<0)
+#define CURLPROTO_HTTPS  (1<<1)
+#define CURLPROTO_FTP    (1<<2)
+#define CURLPROTO_FTPS   (1<<3)
+#define CURLPROTO_SCP    (1<<4)
+#define CURLPROTO_SFTP   (1<<5)
+#define CURLPROTO_TELNET (1<<6)
+#define CURLPROTO_LDAP   (1<<7)
+#define CURLPROTO_LDAPS  (1<<8)
+#define CURLPROTO_DICT   (1<<9)
+#define CURLPROTO_FILE   (1<<10)
+#define CURLPROTO_TFTP   (1<<11)
+#define CURLPROTO_IMAP   (1<<12)
+#define CURLPROTO_IMAPS  (1<<13)
+#define CURLPROTO_POP3   (1<<14)
+#define CURLPROTO_POP3S  (1<<15)
+#define CURLPROTO_SMTP   (1<<16)
+#define CURLPROTO_SMTPS  (1<<17)
+#define CURLPROTO_RTSP   (1<<18)
+#define CURLPROTO_RTMP   (1<<19)
+#define CURLPROTO_RTMPT  (1<<20)
+#define CURLPROTO_RTMPE  (1<<21)
+#define CURLPROTO_RTMPTE (1<<22)
+#define CURLPROTO_RTMPS  (1<<23)
+#define CURLPROTO_RTMPTS (1<<24)
+#define CURLPROTO_GOPHER (1<<25)
+#define CURLPROTO_SMB    (1<<26)
+#define CURLPROTO_SMBS   (1<<27)
+#define CURLPROTO_ALL    (~0) /* enable everything */
+
+/* long may be 32 or 64 bits, but we should never depend on anything else
+   but 32 */
+#define CURLOPTTYPE_LONG          0
+#define CURLOPTTYPE_OBJECTPOINT   10000
+#define CURLOPTTYPE_STRINGPOINT   10000
+#define CURLOPTTYPE_FUNCTIONPOINT 20000
+#define CURLOPTTYPE_OFF_T         30000
+
+/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the
+   string options from the header file */
+
+/* name is uppercase CURLOPT_<name>,
+   type is one of the defined CURLOPTTYPE_<type>
+   number is unique identifier */
+#ifdef CINIT
+#undef CINIT
+#endif
+
+#ifdef CURL_ISOCPP
+#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define LONG          CURLOPTTYPE_LONG
+#define OBJECTPOINT   CURLOPTTYPE_OBJECTPOINT
+#define STRINGPOINT   CURLOPTTYPE_OBJECTPOINT
+#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
+#define OFF_T         CURLOPTTYPE_OFF_T
+#define CINIT(name,type,number) CURLOPT_/**/name = type + number
+#endif
+
+/*
+ * This macro-mania below setups the CURLOPT_[what] enum, to be used with
+ * curl_easy_setopt(). The first argument in the CINIT() macro is the [what]
+ * word.
+ */
+
+typedef enum {
+  /* This is the FILE * or void * the regular output should be written to. */
+  CINIT(WRITEDATA, OBJECTPOINT, 1),
+
+  /* The full URL to get/put */
+  CINIT(URL, STRINGPOINT, 2),
+
+  /* Port number to connect to, if other than default. */
+  CINIT(PORT, LONG, 3),
+
+  /* Name of proxy to use. */
+  CINIT(PROXY, STRINGPOINT, 4),
+
+  /* "user:password;options" to use when fetching. */
+  CINIT(USERPWD, STRINGPOINT, 5),
+
+  /* "user:password" to use with proxy. */
+  CINIT(PROXYUSERPWD, STRINGPOINT, 6),
+
+  /* Range to get, specified as an ASCII string. */
+  CINIT(RANGE, STRINGPOINT, 7),
+
+  /* not used */
+
+  /* Specified file stream to upload from (use as input): */
+  CINIT(READDATA, OBJECTPOINT, 9),
+
+  /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE
+   * bytes big. If this is not used, error messages go to stderr instead: */
+  CINIT(ERRORBUFFER, OBJECTPOINT, 10),
+
+  /* Function that will be called to store the output (instead of fwrite). The
+   * parameters will use fwrite() syntax, make sure to follow them. */
+  CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11),
+
+  /* Function that will be called to read the input (instead of fread). The
+   * parameters will use fread() syntax, make sure to follow them. */
+  CINIT(READFUNCTION, FUNCTIONPOINT, 12),
+
+  /* Time-out the read operation after this amount of seconds */
+  CINIT(TIMEOUT, LONG, 13),
+
+  /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about
+   * how large the file being sent really is. That allows better error
+   * checking and better verifies that the upload was successful. -1 means
+   * unknown size.
+   *
+   * For large file support, there is also a _LARGE version of the key
+   * which takes an off_t type, allowing platforms with larger off_t
+   * sizes to handle larger files.  See below for INFILESIZE_LARGE.
+   */
+  CINIT(INFILESIZE, LONG, 14),
+
+  /* POST static input fields. */
+  CINIT(POSTFIELDS, OBJECTPOINT, 15),
+
+  /* Set the referrer page (needed by some CGIs) */
+  CINIT(REFERER, STRINGPOINT, 16),
+
+  /* Set the FTP PORT string (interface name, named or numerical IP address)
+     Use i.e '-' to use default address. */
+  CINIT(FTPPORT, STRINGPOINT, 17),
+
+  /* Set the User-Agent string (examined by some CGIs) */
+  CINIT(USERAGENT, STRINGPOINT, 18),
+
+  /* If the download receives less than "low speed limit" bytes/second
+   * during "low speed time" seconds, the operations is aborted.
+   * You could i.e if you have a pretty high speed connection, abort if
+   * it is less than 2000 bytes/sec during 20 seconds.
+   */
+
+  /* Set the "low speed limit" */
+  CINIT(LOW_SPEED_LIMIT, LONG, 19),
+
+  /* Set the "low speed time" */
+  CINIT(LOW_SPEED_TIME, LONG, 20),
+
+  /* Set the continuation offset.
+   *
+   * Note there is also a _LARGE version of this key which uses
+   * off_t types, allowing for large file offsets on platforms which
+   * use larger-than-32-bit off_t's.  Look below for RESUME_FROM_LARGE.
+   */
+  CINIT(RESUME_FROM, LONG, 21),
+
+  /* Set cookie in request: */
+  CINIT(COOKIE, STRINGPOINT, 22),
+
+  /* This points to a linked list of headers, struct curl_slist kind. This
+     list is also used for RTSP (in spite of its name) */
+  CINIT(HTTPHEADER, OBJECTPOINT, 23),
+
+  /* This points to a linked list of post entries, struct curl_httppost */
+  CINIT(HTTPPOST, OBJECTPOINT, 24),
+
+  /* name of the file keeping your private SSL-certificate */
+  CINIT(SSLCERT, STRINGPOINT, 25),
+
+  /* password for the SSL or SSH private key */
+  CINIT(KEYPASSWD, STRINGPOINT, 26),
+
+  /* send TYPE parameter? */
+  CINIT(CRLF, LONG, 27),
+
+  /* send linked-list of QUOTE commands */
+  CINIT(QUOTE, OBJECTPOINT, 28),
+
+  /* send FILE * or void * to store headers to, if you use a callback it
+     is simply passed to the callback unmodified */
+  CINIT(HEADERDATA, OBJECTPOINT, 29),
+
+  /* point to a file to read the initial cookies from, also enables
+     "cookie awareness" */
+  CINIT(COOKIEFILE, STRINGPOINT, 31),
+
+  /* What version to specifically try to use.
+     See CURL_SSLVERSION defines below. */
+  CINIT(SSLVERSION, LONG, 32),
+
+  /* What kind of HTTP time condition to use, see defines */
+  CINIT(TIMECONDITION, LONG, 33),
+
+  /* Time to use with the above condition. Specified in number of seconds
+     since 1 Jan 1970 */
+  CINIT(TIMEVALUE, LONG, 34),
+
+  /* 35 = OBSOLETE */
+
+  /* Custom request, for customizing the get command like
+     HTTP: DELETE, TRACE and others
+     FTP: to use a different list command
+     */
+  CINIT(CUSTOMREQUEST, STRINGPOINT, 36),
+
+  /* FILE handle to use instead of stderr */
+  CINIT(STDERR, OBJECTPOINT, 37),
+
+  /* 38 is not used */
+
+  /* send linked-list of post-transfer QUOTE commands */
+  CINIT(POSTQUOTE, OBJECTPOINT, 39),
+
+  CINIT(OBSOLETE40, OBJECTPOINT, 40), /* OBSOLETE, do not use! */
+
+  CINIT(VERBOSE, LONG, 41),      /* talk a lot */
+  CINIT(HEADER, LONG, 42),       /* throw the header out too */
+  CINIT(NOPROGRESS, LONG, 43),   /* shut off the progress meter */
+  CINIT(NOBODY, LONG, 44),       /* use HEAD to get http document */
+  CINIT(FAILONERROR, LONG, 45),  /* no output on http error codes >= 400 */
+  CINIT(UPLOAD, LONG, 46),       /* this is an upload */
+  CINIT(POST, LONG, 47),         /* HTTP POST method */
+  CINIT(DIRLISTONLY, LONG, 48),  /* bare names when listing directories */
+
+  CINIT(APPEND, LONG, 50),       /* Append instead of overwrite on upload! */
+
+  /* Specify whether to read the user+password from the .netrc or the URL.
+   * This must be one of the CURL_NETRC_* enums below. */
+  CINIT(NETRC, LONG, 51),
+
+  CINIT(FOLLOWLOCATION, LONG, 52),  /* use Location: Luke! */
+
+  CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */
+  CINIT(PUT, LONG, 54),          /* HTTP PUT */
+
+  /* 55 = OBSOLETE */
+
+  /* DEPRECATED
+   * Function that will be called instead of the internal progress display
+   * function. This function should be defined as the curl_progress_callback
+   * prototype defines. */
+  CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56),
+
+  /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION
+     callbacks */
+  CINIT(PROGRESSDATA, OBJECTPOINT, 57),
+#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA
+
+  /* We want the referrer field set automatically when following locations */
+  CINIT(AUTOREFERER, LONG, 58),
+
+  /* Port of the proxy, can be set in the proxy string as well with:
+     "[host]:[port]" */
+  CINIT(PROXYPORT, LONG, 59),
+
+  /* size of the POST input data, if strlen() is not good to use */
+  CINIT(POSTFIELDSIZE, LONG, 60),
+
+  /* tunnel non-http operations through a HTTP proxy */
+  CINIT(HTTPPROXYTUNNEL, LONG, 61),
+
+  /* Set the interface string to use as outgoing network interface */
+  CINIT(INTERFACE, STRINGPOINT, 62),
+
+  /* Set the krb4/5 security level, this also enables krb4/5 awareness.  This
+   * is a string, 'clear', 'safe', 'confidential' or 'private'.  If the string
+   * is set but doesn't match one of these, 'private' will be used.  */
+  CINIT(KRBLEVEL, STRINGPOINT, 63),
+
+  /* Set if we should verify the peer in ssl handshake, set 1 to verify. */
+  CINIT(SSL_VERIFYPEER, LONG, 64),
+
+  /* The CApath or CAfile used to validate the peer certificate
+     this option is used only if SSL_VERIFYPEER is true */
+  CINIT(CAINFO, STRINGPOINT, 65),
+
+  /* 66 = OBSOLETE */
+  /* 67 = OBSOLETE */
+
+  /* Maximum number of http redirects to follow */
+  CINIT(MAXREDIRS, LONG, 68),
+
+  /* Pass a long set to 1 to get the date of the requested document (if
+     possible)! Pass a zero to shut it off. */
+  CINIT(FILETIME, LONG, 69),
+
+  /* This points to a linked list of telnet options */
+  CINIT(TELNETOPTIONS, OBJECTPOINT, 70),
+
+  /* Max amount of cached alive connections */
+  CINIT(MAXCONNECTS, LONG, 71),
+
+  CINIT(OBSOLETE72, LONG, 72), /* OBSOLETE, do not use! */
+
+  /* 73 = OBSOLETE */
+
+  /* Set to explicitly use a new connection for the upcoming transfer.
+     Do not use this unless you're absolutely sure of this, as it makes the
+     operation slower and is less friendly for the network. */
+  CINIT(FRESH_CONNECT, LONG, 74),
+
+  /* Set to explicitly forbid the upcoming transfer's connection to be re-used
+     when done. Do not use this unless you're absolutely sure of this, as it
+     makes the operation slower and is less friendly for the network. */
+  CINIT(FORBID_REUSE, LONG, 75),
+
+  /* Set to a file name that contains random data for libcurl to use to
+     seed the random engine when doing SSL connects. */
+  CINIT(RANDOM_FILE, STRINGPOINT, 76),
+
+  /* Set to the Entropy Gathering Daemon socket pathname */
+  CINIT(EGDSOCKET, STRINGPOINT, 77),
+
+  /* Time-out connect operations after this amount of seconds, if connects are
+     OK within this time, then fine... This only aborts the connect phase. */
+  CINIT(CONNECTTIMEOUT, LONG, 78),
+
+  /* Function that will be called to store headers (instead of fwrite). The
+   * parameters will use fwrite() syntax, make sure to follow them. */
+  CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79),
+
+  /* Set this to force the HTTP request to get back to GET. Only really usable
+     if POST, PUT or a custom request have been used first.
+   */
+  CINIT(HTTPGET, LONG, 80),
+
+  /* Set if we should verify the Common name from the peer certificate in ssl
+   * handshake, set 1 to check existence, 2 to ensure that it matches the
+   * provided hostname. */
+  CINIT(SSL_VERIFYHOST, LONG, 81),
+
+  /* Specify which file name to write all known cookies in after completed
+     operation. Set file name to "-" (dash) to make it go to stdout. */
+  CINIT(COOKIEJAR, STRINGPOINT, 82),
+
+  /* Specify which SSL ciphers to use */
+  CINIT(SSL_CIPHER_LIST, STRINGPOINT, 83),
+
+  /* Specify which HTTP version to use! This must be set to one of the
+     CURL_HTTP_VERSION* enums set below. */
+  CINIT(HTTP_VERSION, LONG, 84),
+
+  /* Specifically switch on or off the FTP engine's use of the EPSV command. By
+     default, that one will always be attempted before the more traditional
+     PASV command. */
+  CINIT(FTP_USE_EPSV, LONG, 85),
+
+  /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */
+  CINIT(SSLCERTTYPE, STRINGPOINT, 86),
+
+  /* name of the file keeping your private SSL-key */
+  CINIT(SSLKEY, STRINGPOINT, 87),
+
+  /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */
+  CINIT(SSLKEYTYPE, STRINGPOINT, 88),
+
+  /* crypto engine for the SSL-sub system */
+  CINIT(SSLENGINE, STRINGPOINT, 89),
+
+  /* set the crypto engine for the SSL-sub system as default
+     the param has no meaning...
+   */
+  CINIT(SSLENGINE_DEFAULT, LONG, 90),
+
+  /* Non-zero value means to use the global dns cache */
+  CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */
+
+  /* DNS cache timeout */
+  CINIT(DNS_CACHE_TIMEOUT, LONG, 92),
+
+  /* send linked-list of pre-transfer QUOTE commands */
+  CINIT(PREQUOTE, OBJECTPOINT, 93),
+
+  /* set the debug function */
+  CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94),
+
+  /* set the data for the debug function */
+  CINIT(DEBUGDATA, OBJECTPOINT, 95),
+
+  /* mark this as start of a cookie session */
+  CINIT(COOKIESESSION, LONG, 96),
+
+  /* The CApath directory used to validate the peer certificate
+     this option is used only if SSL_VERIFYPEER is true */
+  CINIT(CAPATH, STRINGPOINT, 97),
+
+  /* Instruct libcurl to use a smaller receive buffer */
+  CINIT(BUFFERSIZE, LONG, 98),
+
+  /* Instruct libcurl to not use any signal/alarm handlers, even when using
+     timeouts. This option is useful for multi-threaded applications.
+     See libcurl-the-guide for more background information. */
+  CINIT(NOSIGNAL, LONG, 99),
+
+  /* Provide a CURLShare for mutexing non-ts data */
+  CINIT(SHARE, OBJECTPOINT, 100),
+
+  /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default),
+     CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and
+     CURLPROXY_SOCKS5. */
+  CINIT(PROXYTYPE, LONG, 101),
+
+  /* Set the Accept-Encoding string. Use this to tell a server you would like
+     the response to be compressed. Before 7.21.6, this was known as
+     CURLOPT_ENCODING */
+  CINIT(ACCEPT_ENCODING, STRINGPOINT, 102),
+
+  /* Set pointer to private data */
+  CINIT(PRIVATE, OBJECTPOINT, 103),
+
+  /* Set aliases for HTTP 200 in the HTTP Response header */
+  CINIT(HTTP200ALIASES, OBJECTPOINT, 104),
+
+  /* Continue to send authentication (user+password) when following locations,
+     even when hostname changed. This can potentially send off the name
+     and password to whatever host the server decides. */
+  CINIT(UNRESTRICTED_AUTH, LONG, 105),
+
+  /* Specifically switch on or off the FTP engine's use of the EPRT command (
+     it also disables the LPRT attempt). By default, those ones will always be
+     attempted before the good old traditional PORT command. */
+  CINIT(FTP_USE_EPRT, LONG, 106),
+
+  /* Set this to a bitmask value to enable the particular authentications
+     methods you like. Use this in combination with CURLOPT_USERPWD.
+     Note that setting multiple bits may cause extra network round-trips. */
+  CINIT(HTTPAUTH, LONG, 107),
+
+  /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx
+     in second argument. The function must be matching the
+     curl_ssl_ctx_callback proto. */
+  CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108),
+
+  /* Set the userdata for the ssl context callback function's third
+     argument */
+  CINIT(SSL_CTX_DATA, OBJECTPOINT, 109),
+
+  /* FTP Option that causes missing dirs to be created on the remote server.
+     In 7.19.4 we introduced the convenience enums for this option using the
+     CURLFTP_CREATE_DIR prefix.
+  */
+  CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110),
+
+  /* Set this to a bitmask value to enable the particular authentications
+     methods you like. Use this in combination with CURLOPT_PROXYUSERPWD.
+     Note that setting multiple bits may cause extra network round-trips. */
+  CINIT(PROXYAUTH, LONG, 111),
+
+  /* FTP option that changes the timeout, in seconds, associated with
+     getting a response.  This is different from transfer timeout time and
+     essentially places a demand on the FTP server to acknowledge commands
+     in a timely manner. */
+  CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112),
+#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT
+
+  /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to
+     tell libcurl to resolve names to those IP versions only. This only has
+     affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */
+  CINIT(IPRESOLVE, LONG, 113),
+
+  /* Set this option to limit the size of a file that will be downloaded from
+     an HTTP or FTP server.
+
+     Note there is also _LARGE version which adds large file support for
+     platforms which have larger off_t sizes.  See MAXFILESIZE_LARGE below. */
+  CINIT(MAXFILESIZE, LONG, 114),
+
+  /* See the comment for INFILESIZE above, but in short, specifies
+   * the size of the file being uploaded.  -1 means unknown.
+   */
+  CINIT(INFILESIZE_LARGE, OFF_T, 115),
+
+  /* Sets the continuation offset.  There is also a LONG version of this;
+   * look above for RESUME_FROM.
+   */
+  CINIT(RESUME_FROM_LARGE, OFF_T, 116),
+
+  /* Sets the maximum size of data that will be downloaded from
+   * an HTTP or FTP server.  See MAXFILESIZE above for the LONG version.
+   */
+  CINIT(MAXFILESIZE_LARGE, OFF_T, 117),
+
+  /* Set this option to the file name of your .netrc file you want libcurl
+     to parse (using the CURLOPT_NETRC option). If not set, libcurl will do
+     a poor attempt to find the user's home directory and check for a .netrc
+     file in there. */
+  CINIT(NETRC_FILE, STRINGPOINT, 118),
+
+  /* Enable SSL/TLS for FTP, pick one of:
+     CURLUSESSL_TRY     - try using SSL, proceed anyway otherwise
+     CURLUSESSL_CONTROL - SSL for the control connection or fail
+     CURLUSESSL_ALL     - SSL for all communication or fail
+  */
+  CINIT(USE_SSL, LONG, 119),
+
+  /* The _LARGE version of the standard POSTFIELDSIZE option */
+  CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120),
+
+  /* Enable/disable the TCP Nagle algorithm */
+  CINIT(TCP_NODELAY, LONG, 121),
+
+  /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+  /* 123 OBSOLETE. Gone in 7.16.0 */
+  /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+  /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+  /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
+  /* 127 OBSOLETE. Gone in 7.16.0 */
+  /* 128 OBSOLETE. Gone in 7.16.0 */
+
+  /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option
+     can be used to change libcurl's default action which is to first try
+     "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK
+     response has been received.
+
+     Available parameters are:
+     CURLFTPAUTH_DEFAULT - let libcurl decide
+     CURLFTPAUTH_SSL     - try "AUTH SSL" first, then TLS
+     CURLFTPAUTH_TLS     - try "AUTH TLS" first, then SSL
+  */
+  CINIT(FTPSSLAUTH, LONG, 129),
+
+  CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130),
+  CINIT(IOCTLDATA, OBJECTPOINT, 131),
+
+  /* 132 OBSOLETE. Gone in 7.16.0 */
+  /* 133 OBSOLETE. Gone in 7.16.0 */
+
+  /* zero terminated string for pass on to the FTP server when asked for
+     "account" info */
+  CINIT(FTP_ACCOUNT, STRINGPOINT, 134),
+
+  /* feed cookie into cookie engine */
+  CINIT(COOKIELIST, STRINGPOINT, 135),
+
+  /* ignore Content-Length */
+  CINIT(IGNORE_CONTENT_LENGTH, LONG, 136),
+
+  /* Set to non-zero to skip the IP address received in a 227 PASV FTP server
+     response. Typically used for FTP-SSL purposes but is not restricted to
+     that. libcurl will then instead use the same IP address it used for the
+     control connection. */
+  CINIT(FTP_SKIP_PASV_IP, LONG, 137),
+
+  /* Select "file method" to use when doing FTP, see the curl_ftpmethod
+     above. */
+  CINIT(FTP_FILEMETHOD, LONG, 138),
+
+  /* Local port number to bind the socket to */
+  CINIT(LOCALPORT, LONG, 139),
+
+  /* Number of ports to try, including the first one set with LOCALPORT.
+     Thus, setting it to 1 will make no additional attempts but the first.
+  */
+  CINIT(LOCALPORTRANGE, LONG, 140),
+
+  /* no transfer, set up connection and let application use the socket by
+     extracting it with CURLINFO_LASTSOCKET */
+  CINIT(CONNECT_ONLY, LONG, 141),
+
+  /* Function that will be called to convert from the
+     network encoding (instead of using the iconv calls in libcurl) */
+  CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142),
+
+  /* Function that will be called to convert to the
+     network encoding (instead of using the iconv calls in libcurl) */
+  CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143),
+
+  /* Function that will be called to convert from UTF8
+     (instead of using the iconv calls in libcurl)
+     Note that this is used only for SSL certificate processing */
+  CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144),
+
+  /* if the connection proceeds too quickly then need to slow it down */
+  /* limit-rate: maximum number of bytes per second to send or receive */
+  CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145),
+  CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146),
+
+  /* Pointer to command string to send if USER/PASS fails. */
+  CINIT(FTP_ALTERNATIVE_TO_USER, STRINGPOINT, 147),
+
+  /* callback function for setting socket options */
+  CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148),
+  CINIT(SOCKOPTDATA, OBJECTPOINT, 149),
+
+  /* set to 0 to disable session ID re-use for this transfer, default is
+     enabled (== 1) */
+  CINIT(SSL_SESSIONID_CACHE, LONG, 150),
+
+  /* allowed SSH authentication methods */
+  CINIT(SSH_AUTH_TYPES, LONG, 151),
+
+  /* Used by scp/sftp to do public/private key authentication */
+  CINIT(SSH_PUBLIC_KEYFILE, STRINGPOINT, 152),
+  CINIT(SSH_PRIVATE_KEYFILE, STRINGPOINT, 153),
+
+  /* Send CCC (Clear Command Channel) after authentication */
+  CINIT(FTP_SSL_CCC, LONG, 154),
+
+  /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */
+  CINIT(TIMEOUT_MS, LONG, 155),
+  CINIT(CONNECTTIMEOUT_MS, LONG, 156),
+
+  /* set to zero to disable the libcurl's decoding and thus pass the raw body
+     data to the application even when it is encoded/compressed */
+  CINIT(HTTP_TRANSFER_DECODING, LONG, 157),
+  CINIT(HTTP_CONTENT_DECODING, LONG, 158),
+
+  /* Permission used when creating new files and directories on the remote
+     server for protocols that support it, SFTP/SCP/FILE */
+  CINIT(NEW_FILE_PERMS, LONG, 159),
+  CINIT(NEW_DIRECTORY_PERMS, LONG, 160),
+
+  /* Set the behaviour of POST when redirecting. Values must be set to one
+     of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */
+  CINIT(POSTREDIR, LONG, 161),
+
+  /* used by scp/sftp to verify the host's public key */
+  CINIT(SSH_HOST_PUBLIC_KEY_MD5, STRINGPOINT, 162),
+
+  /* Callback function for opening socket (instead of socket(2)). Optionally,
+     callback is able change the address or refuse to connect returning
+     CURL_SOCKET_BAD.  The callback should have type
+     curl_opensocket_callback */
+  CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163),
+  CINIT(OPENSOCKETDATA, OBJECTPOINT, 164),
+
+  /* POST volatile input fields. */
+  CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165),
+
+  /* set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy */
+  CINIT(PROXY_TRANSFER_MODE, LONG, 166),
+
+  /* Callback function for seeking in the input stream */
+  CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167),
+  CINIT(SEEKDATA, OBJECTPOINT, 168),
+
+  /* CRL file */
+  CINIT(CRLFILE, STRINGPOINT, 169),
+
+  /* Issuer certificate */
+  CINIT(ISSUERCERT, STRINGPOINT, 170),
+
+  /* (IPv6) Address scope */
+  CINIT(ADDRESS_SCOPE, LONG, 171),
+
+  /* Collect certificate chain info and allow it to get retrievable with
+     CURLINFO_CERTINFO after the transfer is complete. */
+  CINIT(CERTINFO, LONG, 172),
+
+  /* "name" and "pwd" to use when fetching. */
+  CINIT(USERNAME, STRINGPOINT, 173),
+  CINIT(PASSWORD, STRINGPOINT, 174),
+
+    /* "name" and "pwd" to use with Proxy when fetching. */
+  CINIT(PROXYUSERNAME, STRINGPOINT, 175),
+  CINIT(PROXYPASSWORD, STRINGPOINT, 176),
+
+  /* Comma separated list of hostnames defining no-proxy zones. These should
+     match both hostnames directly, and hostnames within a domain. For
+     example, local.com will match local.com and www.local.com, but NOT
+     notlocal.com or www.notlocal.com. For compatibility with other
+     implementations of this, .local.com will be considered to be the same as
+     local.com. A single * is the only valid wildcard, and effectively
+     disables the use of proxy. */
+  CINIT(NOPROXY, STRINGPOINT, 177),
+
+  /* block size for TFTP transfers */
+  CINIT(TFTP_BLKSIZE, LONG, 178),
+
+  /* Socks Service */
+  CINIT(SOCKS5_GSSAPI_SERVICE, STRINGPOINT, 179), /* DEPRECATED, do not use! */
+
+  /* Socks Service */
+  CINIT(SOCKS5_GSSAPI_NEC, LONG, 180),
+
+  /* set the bitmask for the protocols that are allowed to be used for the
+     transfer, which thus helps the app which takes URLs from users or other
+     external inputs and want to restrict what protocol(s) to deal
+     with. Defaults to CURLPROTO_ALL. */
+  CINIT(PROTOCOLS, LONG, 181),
+
+  /* set the bitmask for the protocols that libcurl is allowed to follow to,
+     as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
+     to be set in both bitmasks to be allowed to get redirected to. Defaults
+     to all protocols except FILE and SCP. */
+  CINIT(REDIR_PROTOCOLS, LONG, 182),
+
+  /* set the SSH knownhost file name to use */
+  CINIT(SSH_KNOWNHOSTS, STRINGPOINT, 183),
+
+  /* set the SSH host key callback, must point to a curl_sshkeycallback
+     function */
+  CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184),
+
+  /* set the SSH host key callback custom pointer */
+  CINIT(SSH_KEYDATA, OBJECTPOINT, 185),
+
+  /* set the SMTP mail originator */
+  CINIT(MAIL_FROM, STRINGPOINT, 186),
+
+  /* set the list of SMTP mail receiver(s) */
+  CINIT(MAIL_RCPT, OBJECTPOINT, 187),
+
+  /* FTP: send PRET before PASV */
+  CINIT(FTP_USE_PRET, LONG, 188),
+
+  /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */
+  CINIT(RTSP_REQUEST, LONG, 189),
+
+  /* The RTSP session identifier */
+  CINIT(RTSP_SESSION_ID, STRINGPOINT, 190),
+
+  /* The RTSP stream URI */
+  CINIT(RTSP_STREAM_URI, STRINGPOINT, 191),
+
+  /* The Transport: header to use in RTSP requests */
+  CINIT(RTSP_TRANSPORT, STRINGPOINT, 192),
+
+  /* Manually initialize the client RTSP CSeq for this handle */
+  CINIT(RTSP_CLIENT_CSEQ, LONG, 193),
+
+  /* Manually initialize the server RTSP CSeq for this handle */
+  CINIT(RTSP_SERVER_CSEQ, LONG, 194),
+
+  /* The stream to pass to INTERLEAVEFUNCTION. */
+  CINIT(INTERLEAVEDATA, OBJECTPOINT, 195),
+
+  /* Let the application define a custom write method for RTP data */
+  CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196),
+
+  /* Turn on wildcard matching */
+  CINIT(WILDCARDMATCH, LONG, 197),
+
+  /* Directory matching callback called before downloading of an
+     individual file (chunk) started */
+  CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198),
+
+  /* Directory matching callback called after the file (chunk)
+     was downloaded, or skipped */
+  CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199),
+
+  /* Change match (fnmatch-like) callback for wildcard matching */
+  CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200),
+
+  /* Let the application define custom chunk data pointer */
+  CINIT(CHUNK_DATA, OBJECTPOINT, 201),
+
+  /* FNMATCH_FUNCTION user pointer */
+  CINIT(FNMATCH_DATA, OBJECTPOINT, 202),
+
+  /* send linked-list of name:port:address sets */
+  CINIT(RESOLVE, OBJECTPOINT, 203),
+
+  /* Set a username for authenticated TLS */
+  CINIT(TLSAUTH_USERNAME, STRINGPOINT, 204),
+
+  /* Set a password for authenticated TLS */
+  CINIT(TLSAUTH_PASSWORD, STRINGPOINT, 205),
+
+  /* Set authentication type for authenticated TLS */
+  CINIT(TLSAUTH_TYPE, STRINGPOINT, 206),
+
+  /* Set to 1 to enable the "TE:" header in HTTP requests to ask for
+     compressed transfer-encoded responses. Set to 0 to disable the use of TE:
+     in outgoing requests. The current default is 0, but it might change in a
+     future libcurl release.
+
+     libcurl will ask for the compressed methods it knows of, and if that
+     isn't any, it will not ask for transfer-encoding at all even if this
+     option is set to 1.
+
+  */
+  CINIT(TRANSFER_ENCODING, LONG, 207),
+
+  /* Callback function for closing socket (instead of close(2)). The callback
+     should have type curl_closesocket_callback */
+  CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208),
+  CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209),
+
+  /* allow GSSAPI credential delegation */
+  CINIT(GSSAPI_DELEGATION, LONG, 210),
+
+  /* Set the name servers to use for DNS resolution */
+  CINIT(DNS_SERVERS, STRINGPOINT, 211),
+
+  /* Time-out accept operations (currently for FTP only) after this amount
+     of milliseconds. */
+  CINIT(ACCEPTTIMEOUT_MS, LONG, 212),
+
+  /* Set TCP keepalive */
+  CINIT(TCP_KEEPALIVE, LONG, 213),
+
+  /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */
+  CINIT(TCP_KEEPIDLE, LONG, 214),
+  CINIT(TCP_KEEPINTVL, LONG, 215),
+
+  /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */
+  CINIT(SSL_OPTIONS, LONG, 216),
+
+  /* Set the SMTP auth originator */
+  CINIT(MAIL_AUTH, STRINGPOINT, 217),
+
+  /* Enable/disable SASL initial response */
+  CINIT(SASL_IR, LONG, 218),
+
+  /* Function that will be called instead of the internal progress display
+   * function. This function should be defined as the curl_xferinfo_callback
+   * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */
+  CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219),
+
+  /* The XOAUTH2 bearer token */
+  CINIT(XOAUTH2_BEARER, STRINGPOINT, 220),
+
+  /* Set the interface string to use as outgoing network
+   * interface for DNS requests.
+   * Only supported by the c-ares DNS backend */
+  CINIT(DNS_INTERFACE, STRINGPOINT, 221),
+
+  /* Set the local IPv4 address to use for outgoing DNS requests.
+   * Only supported by the c-ares DNS backend */
+  CINIT(DNS_LOCAL_IP4, STRINGPOINT, 222),
+
+  /* Set the local IPv4 address to use for outgoing DNS requests.
+   * Only supported by the c-ares DNS backend */
+  CINIT(DNS_LOCAL_IP6, STRINGPOINT, 223),
+
+  /* Set authentication options directly */
+  CINIT(LOGIN_OPTIONS, STRINGPOINT, 224),
+
+  /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */
+  CINIT(SSL_ENABLE_NPN, LONG, 225),
+
+  /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */
+  CINIT(SSL_ENABLE_ALPN, LONG, 226),
+
+  /* Time to wait for a response to a HTTP request containing an
+   * Expect: 100-continue header before sending the data anyway. */
+  CINIT(EXPECT_100_TIMEOUT_MS, LONG, 227),
+
+  /* This points to a linked list of headers used for proxy requests only,
+     struct curl_slist kind */
+  CINIT(PROXYHEADER, OBJECTPOINT, 228),
+
+  /* Pass in a bitmask of "header options" */
+  CINIT(HEADEROPT, LONG, 229),
+
+  /* The public key in DER form used to validate the peer public key
+     this option is used only if SSL_VERIFYPEER is true */
+  CINIT(PINNEDPUBLICKEY, STRINGPOINT, 230),
+
+  /* Path to Unix domain socket */
+  CINIT(UNIX_SOCKET_PATH, STRINGPOINT, 231),
+
+  /* Set if we should verify the certificate status. */
+  CINIT(SSL_VERIFYSTATUS, LONG, 232),
+
+  /* Set if we should enable TLS false start. */
+  CINIT(SSL_FALSESTART, LONG, 233),
+
+  /* Do not squash dot-dot sequences */
+  CINIT(PATH_AS_IS, LONG, 234),
+
+  /* Proxy Service Name */
+  CINIT(PROXY_SERVICE_NAME, STRINGPOINT, 235),
+
+  /* Service Name */
+  CINIT(SERVICE_NAME, STRINGPOINT, 236),
+
+  /* Wait/don't wait for pipe/mutex to clarify */
+  CINIT(PIPEWAIT, LONG, 237),
+
+  /* Set the protocol used when curl is given a URL without a protocol */
+  CINIT(DEFAULT_PROTOCOL, STRINGPOINT, 238),
+
+  /* Set stream weight, 1 - 256 (default is 16) */
+  CINIT(STREAM_WEIGHT, LONG, 239),
+
+  /* Set stream dependency on another CURL handle */
+  CINIT(STREAM_DEPENDS, OBJECTPOINT, 240),
+
+  /* Set E-xclusive stream dependency on another CURL handle */
+  CINIT(STREAM_DEPENDS_E, OBJECTPOINT, 241),
+
+  /* Do not send any tftp option requests to the server */
+  CINIT(TFTP_NO_OPTIONS, LONG, 242),
+
+  /* Linked-list of host:port:connect-to-host:connect-to-port,
+     overrides the URL's host:port (only for the network layer) */
+  CINIT(CONNECT_TO, OBJECTPOINT, 243),
+
+  /* Set TCP Fast Open */
+  CINIT(TCP_FASTOPEN, LONG, 244),
+
+  /* Continue to send data if the server responds early with an
+   * HTTP status code >= 300 */
+  CINIT(KEEP_SENDING_ON_ERROR, LONG, 245),
+
+  /* The CApath or CAfile used to validate the proxy certificate
+     this option is used only if PROXY_SSL_VERIFYPEER is true */
+  CINIT(PROXY_CAINFO, STRINGPOINT, 246),
+
+  /* The CApath directory used to validate the proxy certificate
+     this option is used only if PROXY_SSL_VERIFYPEER is true */
+  CINIT(PROXY_CAPATH, STRINGPOINT, 247),
+
+  /* Set if we should verify the proxy in ssl handshake,
+     set 1 to verify. */
+  CINIT(PROXY_SSL_VERIFYPEER, LONG, 248),
+
+  /* Set if we should verify the Common name from the proxy certificate in ssl
+   * handshake, set 1 to check existence, 2 to ensure that it matches
+   * the provided hostname. */
+  CINIT(PROXY_SSL_VERIFYHOST, LONG, 249),
+
+  /* What version to specifically try to use for proxy.
+     See CURL_SSLVERSION defines below. */
+  CINIT(PROXY_SSLVERSION, LONG, 250),
+
+  /* Set a username for authenticated TLS for proxy */
+  CINIT(PROXY_TLSAUTH_USERNAME, STRINGPOINT, 251),
+
+  /* Set a password for authenticated TLS for proxy */
+  CINIT(PROXY_TLSAUTH_PASSWORD, STRINGPOINT, 252),
+
+  /* Set authentication type for authenticated TLS for proxy */
+  CINIT(PROXY_TLSAUTH_TYPE, STRINGPOINT, 253),
+
+  /* name of the file keeping your private SSL-certificate for proxy */
+  CINIT(PROXY_SSLCERT, STRINGPOINT, 254),
+
+  /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for
+     proxy */
+  CINIT(PROXY_SSLCERTTYPE, STRINGPOINT, 255),
+
+  /* name of the file keeping your private SSL-key for proxy */
+  CINIT(PROXY_SSLKEY, STRINGPOINT, 256),
+
+  /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for
+     proxy */
+  CINIT(PROXY_SSLKEYTYPE, STRINGPOINT, 257),
+
+  /* password for the SSL private key for proxy */
+  CINIT(PROXY_KEYPASSWD, STRINGPOINT, 258),
+
+  /* Specify which SSL ciphers to use for proxy */
+  CINIT(PROXY_SSL_CIPHER_LIST, STRINGPOINT, 259),
+
+  /* CRL file for proxy */
+  CINIT(PROXY_CRLFILE, STRINGPOINT, 260),
+
+  /* Enable/disable specific SSL features with a bitmask for proxy, see
+     CURLSSLOPT_* */
+  CINIT(PROXY_SSL_OPTIONS, LONG, 261),
+
+  /* Name of pre proxy to use. */
+  CINIT(PRE_PROXY, STRINGPOINT, 262),
+
+  /* The public key in DER form used to validate the proxy public key
+     this option is used only if PROXY_SSL_VERIFYPEER is true */
+  CINIT(PROXY_PINNEDPUBLICKEY, STRINGPOINT, 263),
+
+  /* Path to an abstract Unix domain socket */
+  CINIT(ABSTRACT_UNIX_SOCKET, STRINGPOINT, 264),
+
+  /* Suppress proxy CONNECT response headers from user callbacks */
+  CINIT(SUPPRESS_CONNECT_HEADERS, LONG, 265),
+
+  /* The request target, instead of extracted from the URL */
+  CINIT(REQUEST_TARGET, STRINGPOINT, 266),
+
+  /* bitmask of allowed auth methods for connections to SOCKS5 proxies */
+  CINIT(SOCKS5_AUTH, LONG, 267),
+
+  /* Enable/disable SSH compression */
+  CINIT(SSH_COMPRESSION, LONG, 268),
+
+  /* Post MIME data. */
+  CINIT(MIMEPOST, OBJECTPOINT, 269),
+
+  CURLOPT_LASTENTRY /* the last unused */
+} CURLoption;
+
+#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all
+                          the obsolete stuff removed! */
+
+/* Backwards compatibility with older names */
+/* These are scheduled to disappear by 2011 */
+
+/* This was added in version 7.19.1 */
+#define CURLOPT_POST301 CURLOPT_POSTREDIR
+
+/* These are scheduled to disappear by 2009 */
+
+/* The following were added in 7.17.0 */
+#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD
+#define CURLOPT_FTPAPPEND CURLOPT_APPEND
+#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY
+#define CURLOPT_FTP_SSL CURLOPT_USE_SSL
+
+/* The following were added earlier */
+
+#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD
+#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL
+
+#else
+/* This is set if CURL_NO_OLDIES is defined at compile-time */
+#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */
+#endif
+
+
+  /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host
+     name resolves addresses using more than one IP protocol version, this
+     option might be handy to force libcurl to use a specific IP version. */
+#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP
+                                     versions that your system allows */
+#define CURL_IPRESOLVE_V4       1 /* resolve to IPv4 addresses */
+#define CURL_IPRESOLVE_V6       2 /* resolve to IPv6 addresses */
+
+  /* three convenient "aliases" that follow the name scheme better */
+#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER
+
+  /* These enums are for use with the CURLOPT_HTTP_VERSION option. */
+enum {
+  CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd
+                             like the library to choose the best possible
+                             for us! */
+  CURL_HTTP_VERSION_1_0,  /* please use HTTP 1.0 in the request */
+  CURL_HTTP_VERSION_1_1,  /* please use HTTP 1.1 in the request */
+  CURL_HTTP_VERSION_2_0,  /* please use HTTP 2 in the request */
+  CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */
+  CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE,  /* please use HTTP 2 without HTTP/1.1
+                                           Upgrade */
+
+  CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
+};
+
+/* Convenience definition simple because the name of the version is HTTP/2 and
+   not 2.0. The 2_0 version of the enum name was set while the version was
+   still planned to be 2.0 and we stick to it for compatibility. */
+#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0
+
+/*
+ * Public API enums for RTSP requests
+ */
+enum {
+    CURL_RTSPREQ_NONE, /* first in list */
+    CURL_RTSPREQ_OPTIONS,
+    CURL_RTSPREQ_DESCRIBE,
+    CURL_RTSPREQ_ANNOUNCE,
+    CURL_RTSPREQ_SETUP,
+    CURL_RTSPREQ_PLAY,
+    CURL_RTSPREQ_PAUSE,
+    CURL_RTSPREQ_TEARDOWN,
+    CURL_RTSPREQ_GET_PARAMETER,
+    CURL_RTSPREQ_SET_PARAMETER,
+    CURL_RTSPREQ_RECORD,
+    CURL_RTSPREQ_RECEIVE,
+    CURL_RTSPREQ_LAST /* last in list */
+};
+
+  /* These enums are for use with the CURLOPT_NETRC option. */
+enum CURL_NETRC_OPTION {
+  CURL_NETRC_IGNORED,     /* The .netrc will never be read.
+                           * This is the default. */
+  CURL_NETRC_OPTIONAL,    /* A user:password in the URL will be preferred
+                           * to one in the .netrc. */
+  CURL_NETRC_REQUIRED,    /* A user:password in the URL will be ignored.
+                           * Unless one is set programmatically, the .netrc
+                           * will be queried. */
+  CURL_NETRC_LAST
+};
+
+enum {
+  CURL_SSLVERSION_DEFAULT,
+  CURL_SSLVERSION_TLSv1, /* TLS 1.x */
+  CURL_SSLVERSION_SSLv2,
+  CURL_SSLVERSION_SSLv3,
+  CURL_SSLVERSION_TLSv1_0,
+  CURL_SSLVERSION_TLSv1_1,
+  CURL_SSLVERSION_TLSv1_2,
+  CURL_SSLVERSION_TLSv1_3,
+
+  CURL_SSLVERSION_LAST /* never use, keep last */
+};
+
+enum {
+  CURL_SSLVERSION_MAX_NONE =     0,
+  CURL_SSLVERSION_MAX_DEFAULT =  (CURL_SSLVERSION_TLSv1   << 16),
+  CURL_SSLVERSION_MAX_TLSv1_0 =  (CURL_SSLVERSION_TLSv1_0 << 16),
+  CURL_SSLVERSION_MAX_TLSv1_1 =  (CURL_SSLVERSION_TLSv1_1 << 16),
+  CURL_SSLVERSION_MAX_TLSv1_2 =  (CURL_SSLVERSION_TLSv1_2 << 16),
+  CURL_SSLVERSION_MAX_TLSv1_3 =  (CURL_SSLVERSION_TLSv1_3 << 16),
+
+  /* never use, keep last */
+  CURL_SSLVERSION_MAX_LAST =     (CURL_SSLVERSION_LAST    << 16)
+};
+
+enum CURL_TLSAUTH {
+  CURL_TLSAUTH_NONE,
+  CURL_TLSAUTH_SRP,
+  CURL_TLSAUTH_LAST /* never use, keep last */
+};
+
+/* symbols to use with CURLOPT_POSTREDIR.
+   CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303
+   can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302
+   | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */
+
+#define CURL_REDIR_GET_ALL  0
+#define CURL_REDIR_POST_301 1
+#define CURL_REDIR_POST_302 2
+#define CURL_REDIR_POST_303 4
+#define CURL_REDIR_POST_ALL \
+    (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303)
+
+typedef enum {
+  CURL_TIMECOND_NONE,
+
+  CURL_TIMECOND_IFMODSINCE,
+  CURL_TIMECOND_IFUNMODSINCE,
+  CURL_TIMECOND_LASTMOD,
+
+  CURL_TIMECOND_LAST
+} curl_TimeCond;
+
+/* Special size_t value signaling a zero-terminated string. */
+#define CURL_ZERO_TERMINATED ((size_t) -1)
+
+/* curl_strequal() and curl_strnequal() are subject for removal in a future
+   release */
+CURL_EXTERN int curl_strequal(const char *s1, const char *s2);
+CURL_EXTERN int curl_strnequal(const char *s1, const char *s2, size_t n);
+
+/* Mime/form handling support. */
+typedef struct curl_mime_s      curl_mime;      /* Mime context. */
+typedef struct curl_mimepart_s  curl_mimepart;  /* Mime part context. */
+
+/*
+ * NAME curl_mime_init()
+ *
+ * DESCRIPTION
+ *
+ * Create a mime context and return its handle. The easy parameter is the
+ * target handle.
+ */
+CURL_EXTERN curl_mime *curl_mime_init(CURL *easy);
+
+/*
+ * NAME curl_mime_free()
+ *
+ * DESCRIPTION
+ *
+ * release a mime handle and its substructures.
+ */
+CURL_EXTERN void curl_mime_free(curl_mime *mime);
+
+/*
+ * NAME curl_mime_addpart()
+ *
+ * DESCRIPTION
+ *
+ * Append a new empty part to the given mime context and return a handle to
+ * the created part.
+ */
+CURL_EXTERN curl_mimepart *curl_mime_addpart(curl_mime *mime);
+
+/*
+ * NAME curl_mime_name()
+ *
+ * DESCRIPTION
+ *
+ * Set mime/form part name.
+ */
+CURL_EXTERN CURLcode curl_mime_name(curl_mimepart *part, const char *name);
+
+/*
+ * NAME curl_mime_filename()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part remote file name.
+ */
+CURL_EXTERN CURLcode curl_mime_filename(curl_mimepart *part,
+                                        const char *filename);
+
+/*
+ * NAME curl_mime_type()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part type.
+ */
+CURL_EXTERN CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype);
+
+/*
+ * NAME curl_mime_encoder()
+ *
+ * DESCRIPTION
+ *
+ * Set mime data transfer encoder.
+ */
+CURL_EXTERN CURLcode curl_mime_encoder(curl_mimepart *part,
+                                       const char *encoding);
+
+/*
+ * NAME curl_mime_data()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part data source from memory data,
+ */
+CURL_EXTERN CURLcode curl_mime_data(curl_mimepart *part,
+                                    const char *data, size_t datasize);
+
+/*
+ * NAME curl_mime_filedata()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part data source from named file.
+ */
+CURL_EXTERN CURLcode curl_mime_filedata(curl_mimepart *part,
+                                        const char *filename);
+
+/*
+ * NAME curl_mime_data_cb()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part data source from callback function.
+ */
+CURL_EXTERN CURLcode curl_mime_data_cb(curl_mimepart *part,
+                                       curl_off_t datasize,
+                                       curl_read_callback readfunc,
+                                       curl_seek_callback seekfunc,
+                                       curl_free_callback freefunc,
+                                       void *arg);
+
+/*
+ * NAME curl_mime_subparts()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part data source from subparts.
+ */
+CURL_EXTERN CURLcode curl_mime_subparts(curl_mimepart *part,
+                                        curl_mime *subparts);
+/*
+ * NAME curl_mime_headers()
+ *
+ * DESCRIPTION
+ *
+ * Set mime part headers.
+ */
+CURL_EXTERN CURLcode curl_mime_headers(curl_mimepart *part,
+                                       struct curl_slist *headers,
+                                       int take_ownership);
+
+/* Old form API. */
+/* name is uppercase CURLFORM_<name> */
+#ifdef CFINIT
+#undef CFINIT
+#endif
+
+#ifdef CURL_ISOCPP
+#define CFINIT(name) CURLFORM_ ## name
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define CFINIT(name) CURLFORM_/**/name
+#endif
+
+typedef enum {
+  CFINIT(NOTHING),        /********* the first one is unused ************/
+
+  /*  */
+  CFINIT(COPYNAME),
+  CFINIT(PTRNAME),
+  CFINIT(NAMELENGTH),
+  CFINIT(COPYCONTENTS),
+  CFINIT(PTRCONTENTS),
+  CFINIT(CONTENTSLENGTH),
+  CFINIT(FILECONTENT),
+  CFINIT(ARRAY),
+  CFINIT(OBSOLETE),
+  CFINIT(FILE),
+
+  CFINIT(BUFFER),
+  CFINIT(BUFFERPTR),
+  CFINIT(BUFFERLENGTH),
+
+  CFINIT(CONTENTTYPE),
+  CFINIT(CONTENTHEADER),
+  CFINIT(FILENAME),
+  CFINIT(END),
+  CFINIT(OBSOLETE2),
+
+  CFINIT(STREAM),
+  CFINIT(CONTENTLEN), /* added in 7.46.0, provide a curl_off_t length */
+
+  CURLFORM_LASTENTRY /* the last unused */
+} CURLformoption;
+
+#undef CFINIT /* done */
+
+/* structure to be used as parameter for CURLFORM_ARRAY */
+struct curl_forms {
+  CURLformoption option;
+  const char     *value;
+};
+
+/* use this for multipart formpost building */
+/* Returns code for curl_formadd()
+ *
+ * Returns:
+ * CURL_FORMADD_OK             on success
+ * CURL_FORMADD_MEMORY         if the FormInfo allocation fails
+ * CURL_FORMADD_OPTION_TWICE   if one option is given twice for one Form
+ * CURL_FORMADD_NULL           if a null pointer was given for a char
+ * CURL_FORMADD_MEMORY         if the allocation of a FormInfo struct failed
+ * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
+ * CURL_FORMADD_INCOMPLETE     if the some FormInfo is not complete (or error)
+ * CURL_FORMADD_MEMORY         if a curl_httppost struct cannot be allocated
+ * CURL_FORMADD_MEMORY         if some allocation for string copying failed.
+ * CURL_FORMADD_ILLEGAL_ARRAY  if an illegal option is used in an array
+ *
+ ***************************************************************************/
+typedef enum {
+  CURL_FORMADD_OK, /* first, no error */
+
+  CURL_FORMADD_MEMORY,
+  CURL_FORMADD_OPTION_TWICE,
+  CURL_FORMADD_NULL,
+  CURL_FORMADD_UNKNOWN_OPTION,
+  CURL_FORMADD_INCOMPLETE,
+  CURL_FORMADD_ILLEGAL_ARRAY,
+  CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */
+
+  CURL_FORMADD_LAST /* last */
+} CURLFORMcode;
+
+/*
+ * NAME curl_formadd()
+ *
+ * DESCRIPTION
+ *
+ * Pretty advanced function for building multi-part formposts. Each invoke
+ * adds one part that together construct a full post. Then use
+ * CURLOPT_HTTPPOST to send it off to libcurl.
+ */
+CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost,
+                                      struct curl_httppost **last_post,
+                                      ...);
+
+/*
+ * callback function for curl_formget()
+ * The void *arg pointer will be the one passed as second argument to
+ *   curl_formget().
+ * The character buffer passed to it must not be freed.
+ * Should return the buffer length passed to it as the argument "len" on
+ *   success.
+ */
+typedef size_t (*curl_formget_callback)(void *arg, const char *buf,
+                                        size_t len);
+
+/*
+ * NAME curl_formget()
+ *
+ * DESCRIPTION
+ *
+ * Serialize a curl_httppost struct built with curl_formadd().
+ * Accepts a void pointer as second argument which will be passed to
+ * the curl_formget_callback function.
+ * Returns 0 on success.
+ */
+CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg,
+                             curl_formget_callback append);
+/*
+ * NAME curl_formfree()
+ *
+ * DESCRIPTION
+ *
+ * Free a multipart formpost previously built with curl_formadd().
+ */
+CURL_EXTERN void curl_formfree(struct curl_httppost *form);
+
+/*
+ * NAME curl_getenv()
+ *
+ * DESCRIPTION
+ *
+ * Returns a malloc()'ed string that MUST be curl_free()ed after usage is
+ * complete. DEPRECATED - see lib/README.curlx
+ */
+CURL_EXTERN char *curl_getenv(const char *variable);
+
+/*
+ * NAME curl_version()
+ *
+ * DESCRIPTION
+ *
+ * Returns a static ascii string of the libcurl version.
+ */
+CURL_EXTERN char *curl_version(void);
+
+/*
+ * NAME curl_easy_escape()
+ *
+ * DESCRIPTION
+ *
+ * Escapes URL strings (converts all letters consider illegal in URLs to their
+ * %XX versions). This function returns a new allocated string or NULL if an
+ * error occurred.
+ */
+CURL_EXTERN char *curl_easy_escape(CURL *handle,
+                                   const char *string,
+                                   int length);
+
+/* the previous version: */
+CURL_EXTERN char *curl_escape(const char *string,
+                              int length);
+
+
+/*
+ * NAME curl_easy_unescape()
+ *
+ * DESCRIPTION
+ *
+ * Unescapes URL encoding in strings (converts all %XX codes to their 8bit
+ * versions). This function returns a new allocated string or NULL if an error
+ * occurred.
+ * Conversion Note: On non-ASCII platforms the ASCII %XX codes are
+ * converted into the host encoding.
+ */
+CURL_EXTERN char *curl_easy_unescape(CURL *handle,
+                                     const char *string,
+                                     int length,
+                                     int *outlength);
+
+/* the previous version */
+CURL_EXTERN char *curl_unescape(const char *string,
+                                int length);
+
+/*
+ * NAME curl_free()
+ *
+ * DESCRIPTION
+ *
+ * Provided for de-allocation in the same translation unit that did the
+ * allocation. Added in libcurl 7.10
+ */
+CURL_EXTERN void curl_free(void *p);
+
+/*
+ * NAME curl_global_init()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_init() should be invoked exactly once for each application that
+ * uses libcurl and before any call of other libcurl functions.
+ *
+ * This function is not thread-safe!
+ */
+CURL_EXTERN CURLcode curl_global_init(long flags);
+
+/*
+ * NAME curl_global_init_mem()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_init() or curl_global_init_mem() should be invoked exactly once
+ * for each application that uses libcurl.  This function can be used to
+ * initialize libcurl and set user defined memory management callback
+ * functions.  Users can implement memory management routines to check for
+ * memory leaks, check for mis-use of the curl library etc.  User registered
+ * callback routines with be invoked by this library instead of the system
+ * memory management routines like malloc, free etc.
+ */
+CURL_EXTERN CURLcode curl_global_init_mem(long flags,
+                                          curl_malloc_callback m,
+                                          curl_free_callback f,
+                                          curl_realloc_callback r,
+                                          curl_strdup_callback s,
+                                          curl_calloc_callback c);
+
+/*
+ * NAME curl_global_cleanup()
+ *
+ * DESCRIPTION
+ *
+ * curl_global_cleanup() should be invoked exactly once for each application
+ * that uses libcurl
+ */
+CURL_EXTERN void curl_global_cleanup(void);
+
+/* linked-list structure for the CURLOPT_QUOTE option (and other) */
+struct curl_slist {
+  char *data;
+  struct curl_slist *next;
+};
+
+/*
+ * NAME curl_global_sslset()
+ *
+ * DESCRIPTION
+ *
+ * When built with multiple SSL backends, curl_global_sslset() allows to
+ * choose one. This function can only be called once, and it must be called
+ * *before* curl_global_init().
+ *
+ * The backend can be identified by the id (e.g. CURLSSLBACKEND_OPENSSL). The
+ * backend can also be specified via the name parameter (passing -1 as id).
+ * If both id and name are specified, the name will be ignored. If neither id
+ * nor name are specified, the function will fail with
+ * CURLSSLSET_UNKNOWN_BACKEND and set the "avail" pointer to the
+ * NULL-terminated list of available backends.
+ *
+ * Upon success, the function returns CURLSSLSET_OK.
+ *
+ * If the specified SSL backend is not available, the function returns
+ * CURLSSLSET_UNKNOWN_BACKEND and sets the "avail" pointer to a NULL-terminated
+ * list of available SSL backends.
+ *
+ * The SSL backend can be set only once. If it has already been set, a
+ * subsequent attempt to change it will result in a CURLSSLSET_TOO_LATE.
+ */
+
+typedef struct {
+  curl_sslbackend id;
+  const char *name;
+} curl_ssl_backend;
+
+typedef enum {
+  CURLSSLSET_OK = 0,
+  CURLSSLSET_UNKNOWN_BACKEND,
+  CURLSSLSET_TOO_LATE,
+  CURLSSLSET_NO_BACKENDS /* libcurl was built without any SSL support */
+} CURLsslset;
+
+CURL_EXTERN CURLsslset curl_global_sslset(curl_sslbackend id, const char *name,
+                                          const curl_ssl_backend ***avail);
+
+/*
+ * NAME curl_slist_append()
+ *
+ * DESCRIPTION
+ *
+ * Appends a string to a linked list. If no list exists, it will be created
+ * first. Returns the new list, after appending.
+ */
+CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *,
+                                                 const char *);
+
+/*
+ * NAME curl_slist_free_all()
+ *
+ * DESCRIPTION
+ *
+ * free a previously built curl_slist.
+ */
+CURL_EXTERN void curl_slist_free_all(struct curl_slist *);
+
+/*
+ * NAME curl_getdate()
+ *
+ * DESCRIPTION
+ *
+ * Returns the time, in seconds since 1 Jan 1970 of the time string given in
+ * the first argument. The time argument in the second parameter is unused
+ * and should be set to NULL.
+ */
+CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused);
+
+/* info about the certificate chain, only for OpenSSL builds. Asked
+   for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */
+struct curl_certinfo {
+  int num_of_certs;             /* number of certificates with information */
+  struct curl_slist **certinfo; /* for each index in this array, there's a
+                                   linked list with textual information in the
+                                   format "name: value" */
+};
+
+/* Information about the SSL library used and the respective internal SSL
+   handle, which can be used to obtain further information regarding the
+   connection. Asked for with CURLINFO_TLS_SSL_PTR or CURLINFO_TLS_SESSION. */
+struct curl_tlssessioninfo {
+  curl_sslbackend backend;
+  void *internals;
+};
+
+#define CURLINFO_STRING   0x100000
+#define CURLINFO_LONG     0x200000
+#define CURLINFO_DOUBLE   0x300000
+#define CURLINFO_SLIST    0x400000
+#define CURLINFO_PTR      0x400000 /* same as SLIST */
+#define CURLINFO_SOCKET   0x500000
+#define CURLINFO_OFF_T    0x600000
+#define CURLINFO_MASK     0x0fffff
+#define CURLINFO_TYPEMASK 0xf00000
+
+typedef enum {
+  CURLINFO_NONE, /* first, never use this */
+  CURLINFO_EFFECTIVE_URL    = CURLINFO_STRING + 1,
+  CURLINFO_RESPONSE_CODE    = CURLINFO_LONG   + 2,
+  CURLINFO_TOTAL_TIME       = CURLINFO_DOUBLE + 3,
+  CURLINFO_NAMELOOKUP_TIME  = CURLINFO_DOUBLE + 4,
+  CURLINFO_CONNECT_TIME     = CURLINFO_DOUBLE + 5,
+  CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6,
+  CURLINFO_SIZE_UPLOAD      = CURLINFO_DOUBLE + 7,
+  CURLINFO_SIZE_UPLOAD_T    = CURLINFO_OFF_T  + 7,
+  CURLINFO_SIZE_DOWNLOAD    = CURLINFO_DOUBLE + 8,
+  CURLINFO_SIZE_DOWNLOAD_T  = CURLINFO_OFF_T  + 8,
+  CURLINFO_SPEED_DOWNLOAD   = CURLINFO_DOUBLE + 9,
+  CURLINFO_SPEED_DOWNLOAD_T = CURLINFO_OFF_T  + 9,
+  CURLINFO_SPEED_UPLOAD     = CURLINFO_DOUBLE + 10,
+  CURLINFO_SPEED_UPLOAD_T   = CURLINFO_OFF_T  + 10,
+  CURLINFO_HEADER_SIZE      = CURLINFO_LONG   + 11,
+  CURLINFO_REQUEST_SIZE     = CURLINFO_LONG   + 12,
+  CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG   + 13,
+  CURLINFO_FILETIME         = CURLINFO_LONG   + 14,
+  CURLINFO_CONTENT_LENGTH_DOWNLOAD   = CURLINFO_DOUBLE + 15,
+  CURLINFO_CONTENT_LENGTH_DOWNLOAD_T = CURLINFO_OFF_T  + 15,
+  CURLINFO_CONTENT_LENGTH_UPLOAD     = CURLINFO_DOUBLE + 16,
+  CURLINFO_CONTENT_LENGTH_UPLOAD_T   = CURLINFO_OFF_T  + 16,
+  CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17,
+  CURLINFO_CONTENT_TYPE     = CURLINFO_STRING + 18,
+  CURLINFO_REDIRECT_TIME    = CURLINFO_DOUBLE + 19,
+  CURLINFO_REDIRECT_COUNT   = CURLINFO_LONG   + 20,
+  CURLINFO_PRIVATE          = CURLINFO_STRING + 21,
+  CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG   + 22,
+  CURLINFO_HTTPAUTH_AVAIL   = CURLINFO_LONG   + 23,
+  CURLINFO_PROXYAUTH_AVAIL  = CURLINFO_LONG   + 24,
+  CURLINFO_OS_ERRNO         = CURLINFO_LONG   + 25,
+  CURLINFO_NUM_CONNECTS     = CURLINFO_LONG   + 26,
+  CURLINFO_SSL_ENGINES      = CURLINFO_SLIST  + 27,
+  CURLINFO_COOKIELIST       = CURLINFO_SLIST  + 28,
+  CURLINFO_LASTSOCKET       = CURLINFO_LONG   + 29,
+  CURLINFO_FTP_ENTRY_PATH   = CURLINFO_STRING + 30,
+  CURLINFO_REDIRECT_URL     = CURLINFO_STRING + 31,
+  CURLINFO_PRIMARY_IP       = CURLINFO_STRING + 32,
+  CURLINFO_APPCONNECT_TIME  = CURLINFO_DOUBLE + 33,
+  CURLINFO_CERTINFO         = CURLINFO_PTR    + 34,
+  CURLINFO_CONDITION_UNMET  = CURLINFO_LONG   + 35,
+  CURLINFO_RTSP_SESSION_ID  = CURLINFO_STRING + 36,
+  CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG   + 37,
+  CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG   + 38,
+  CURLINFO_RTSP_CSEQ_RECV   = CURLINFO_LONG   + 39,
+  CURLINFO_PRIMARY_PORT     = CURLINFO_LONG   + 40,
+  CURLINFO_LOCAL_IP         = CURLINFO_STRING + 41,
+  CURLINFO_LOCAL_PORT       = CURLINFO_LONG   + 42,
+  CURLINFO_TLS_SESSION      = CURLINFO_PTR    + 43,
+  CURLINFO_ACTIVESOCKET     = CURLINFO_SOCKET + 44,
+  CURLINFO_TLS_SSL_PTR      = CURLINFO_PTR    + 45,
+  CURLINFO_HTTP_VERSION     = CURLINFO_LONG   + 46,
+  CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47,
+  CURLINFO_PROTOCOL         = CURLINFO_LONG   + 48,
+  CURLINFO_SCHEME           = CURLINFO_STRING + 49,
+  /* Fill in new entries below here! */
+
+  CURLINFO_LASTONE          = 49
+} CURLINFO;
+
+/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as
+   CURLINFO_HTTP_CODE */
+#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE
+
+typedef enum {
+  CURLCLOSEPOLICY_NONE, /* first, never use this */
+
+  CURLCLOSEPOLICY_OLDEST,
+  CURLCLOSEPOLICY_LEAST_RECENTLY_USED,
+  CURLCLOSEPOLICY_LEAST_TRAFFIC,
+  CURLCLOSEPOLICY_SLOWEST,
+  CURLCLOSEPOLICY_CALLBACK,
+
+  CURLCLOSEPOLICY_LAST /* last, never use this */
+} curl_closepolicy;
+
+#define CURL_GLOBAL_SSL (1<<0) /* no purpose since since 7.57.0 */
+#define CURL_GLOBAL_WIN32 (1<<1)
+#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32)
+#define CURL_GLOBAL_NOTHING 0
+#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL
+#define CURL_GLOBAL_ACK_EINTR (1<<2)
+
+
+/*****************************************************************************
+ * Setup defines, protos etc for the sharing stuff.
+ */
+
+/* Different data locks for a single share */
+typedef enum {
+  CURL_LOCK_DATA_NONE = 0,
+  /*  CURL_LOCK_DATA_SHARE is used internally to say that
+   *  the locking is just made to change the internal state of the share
+   *  itself.
+   */
+  CURL_LOCK_DATA_SHARE,
+  CURL_LOCK_DATA_COOKIE,
+  CURL_LOCK_DATA_DNS,
+  CURL_LOCK_DATA_SSL_SESSION,
+  CURL_LOCK_DATA_CONNECT,
+  CURL_LOCK_DATA_LAST
+} curl_lock_data;
+
+/* Different lock access types */
+typedef enum {
+  CURL_LOCK_ACCESS_NONE = 0,   /* unspecified action */
+  CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */
+  CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */
+  CURL_LOCK_ACCESS_LAST        /* never use */
+} curl_lock_access;
+
+typedef void (*curl_lock_function)(CURL *handle,
+                                   curl_lock_data data,
+                                   curl_lock_access locktype,
+                                   void *userptr);
+typedef void (*curl_unlock_function)(CURL *handle,
+                                     curl_lock_data data,
+                                     void *userptr);
+
+
+typedef enum {
+  CURLSHE_OK,  /* all is fine */
+  CURLSHE_BAD_OPTION, /* 1 */
+  CURLSHE_IN_USE,     /* 2 */
+  CURLSHE_INVALID,    /* 3 */
+  CURLSHE_NOMEM,      /* 4 out of memory */
+  CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */
+  CURLSHE_LAST        /* never use */
+} CURLSHcode;
+
+typedef enum {
+  CURLSHOPT_NONE,  /* don't use */
+  CURLSHOPT_SHARE,   /* specify a data type to share */
+  CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */
+  CURLSHOPT_LOCKFUNC,   /* pass in a 'curl_lock_function' pointer */
+  CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */
+  CURLSHOPT_USERDATA,   /* pass in a user data pointer used in the lock/unlock
+                           callback functions */
+  CURLSHOPT_LAST  /* never use */
+} CURLSHoption;
+
+CURL_EXTERN CURLSH *curl_share_init(void);
+CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...);
+CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *);
+
+/****************************************************************************
+ * Structures for querying information about the curl library at runtime.
+ */
+
+typedef enum {
+  CURLVERSION_FIRST,
+  CURLVERSION_SECOND,
+  CURLVERSION_THIRD,
+  CURLVERSION_FOURTH,
+  CURLVERSION_FIFTH,
+  CURLVERSION_LAST /* never actually use this */
+} CURLversion;
+
+/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by
+   basically all programs ever that want to get version information. It is
+   meant to be a built-in version number for what kind of struct the caller
+   expects. If the struct ever changes, we redefine the NOW to another enum
+   from above. */
+#define CURLVERSION_NOW CURLVERSION_FIFTH
+
+typedef struct {
+  CURLversion age;          /* age of the returned struct */
+  const char *version;      /* LIBCURL_VERSION */
+  unsigned int version_num; /* LIBCURL_VERSION_NUM */
+  const char *host;         /* OS/host/cpu/machine when configured */
+  int features;             /* bitmask, see defines below */
+  const char *ssl_version;  /* human readable string */
+  long ssl_version_num;     /* not used anymore, always 0 */
+  const char *libz_version; /* human readable string */
+  /* protocols is terminated by an entry with a NULL protoname */
+  const char * const *protocols;
+
+  /* The fields below this were added in CURLVERSION_SECOND */
+  const char *ares;
+  int ares_num;
+
+  /* This field was added in CURLVERSION_THIRD */
+  const char *libidn;
+
+  /* These field were added in CURLVERSION_FOURTH */
+
+  /* Same as '_libiconv_version' if built with HAVE_ICONV */
+  int iconv_ver_num;
+
+  const char *libssh_version; /* human readable string */
+
+  /* These fields were added in CURLVERSION_FIFTH */
+
+  unsigned int brotli_ver_num; /* Numeric Brotli version
+                                  (MAJOR << 24) | (MINOR << 12) | PATCH */
+  const char *brotli_version; /* human readable string. */
+
+} curl_version_info_data;
+
+#define CURL_VERSION_IPV6         (1<<0)  /* IPv6-enabled */
+#define CURL_VERSION_KERBEROS4    (1<<1)  /* Kerberos V4 auth is supported
+                                             (deprecated) */
+#define CURL_VERSION_SSL          (1<<2)  /* SSL options are present */
+#define CURL_VERSION_LIBZ         (1<<3)  /* libz features are present */
+#define CURL_VERSION_NTLM         (1<<4)  /* NTLM auth is supported */
+#define CURL_VERSION_GSSNEGOTIATE (1<<5)  /* Negotiate auth is supported
+                                             (deprecated) */
+#define CURL_VERSION_DEBUG        (1<<6)  /* Built with debug capabilities */
+#define CURL_VERSION_ASYNCHDNS    (1<<7)  /* Asynchronous DNS resolves */
+#define CURL_VERSION_SPNEGO       (1<<8)  /* SPNEGO auth is supported */
+#define CURL_VERSION_LARGEFILE    (1<<9)  /* Supports files larger than 2GB */
+#define CURL_VERSION_IDN          (1<<10) /* Internationized Domain Names are
+                                             supported */
+#define CURL_VERSION_SSPI         (1<<11) /* Built against Windows SSPI */
+#define CURL_VERSION_CONV         (1<<12) /* Character conversions supported */
+#define CURL_VERSION_CURLDEBUG    (1<<13) /* Debug memory tracking supported */
+#define CURL_VERSION_TLSAUTH_SRP  (1<<14) /* TLS-SRP auth is supported */
+#define CURL_VERSION_NTLM_WB      (1<<15) /* NTLM delegation to winbind helper
+                                             is supported */
+#define CURL_VERSION_HTTP2        (1<<16) /* HTTP2 support built-in */
+#define CURL_VERSION_GSSAPI       (1<<17) /* Built against a GSS-API library */
+#define CURL_VERSION_KERBEROS5    (1<<18) /* Kerberos V5 auth is supported */
+#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */
+#define CURL_VERSION_PSL          (1<<20) /* Mozilla's Public Suffix List, used
+                                             for cookie domain verification */
+#define CURL_VERSION_HTTPS_PROXY  (1<<21) /* HTTPS-proxy support built-in */
+#define CURL_VERSION_MULTI_SSL    (1<<22) /* Multiple SSL backends available */
+#define CURL_VERSION_BROTLI       (1<<23) /* Brotli features are present. */
+
+ /*
+ * NAME curl_version_info()
+ *
+ * DESCRIPTION
+ *
+ * This function returns a pointer to a static copy of the version info
+ * struct. See above.
+ */
+CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion);
+
+/*
+ * NAME curl_easy_strerror()
+ *
+ * DESCRIPTION
+ *
+ * The curl_easy_strerror function may be used to turn a CURLcode value
+ * into the equivalent human readable error string.  This is useful
+ * for printing meaningful error messages.
+ */
+CURL_EXTERN const char *curl_easy_strerror(CURLcode);
+
+/*
+ * NAME curl_share_strerror()
+ *
+ * DESCRIPTION
+ *
+ * The curl_share_strerror function may be used to turn a CURLSHcode value
+ * into the equivalent human readable error string.  This is useful
+ * for printing meaningful error messages.
+ */
+CURL_EXTERN const char *curl_share_strerror(CURLSHcode);
+
+/*
+ * NAME curl_easy_pause()
+ *
+ * DESCRIPTION
+ *
+ * The curl_easy_pause function pauses or unpauses transfers. Select the new
+ * state by setting the bitmask, use the convenience defines below.
+ *
+ */
+CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask);
+
+#define CURLPAUSE_RECV      (1<<0)
+#define CURLPAUSE_RECV_CONT (0)
+
+#define CURLPAUSE_SEND      (1<<2)
+#define CURLPAUSE_SEND_CONT (0)
+
+#define CURLPAUSE_ALL       (CURLPAUSE_RECV|CURLPAUSE_SEND)
+#define CURLPAUSE_CONT      (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT)
+
+#ifdef  __cplusplus
+}
+#endif
+
+/* unfortunately, the easy.h and multi.h include files need options and info
+  stuff before they can be included! */
+#include "easy.h" /* nothing in curl is fun without the easy stuff */
+#include "multi.h"
+
+/* the typechecker doesn't work in C++ (yet) */
+#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
+    ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \
+    !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK)
+#include "typecheck-gcc.h"
+#else
+#if defined(__STDC__) && (__STDC__ >= 1)
+/* This preprocessor magic that replaces a call with the exact same call is
+   only done to make sure application authors pass exactly three arguments
+   to these functions. */
+#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param)
+#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg)
+#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
+#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
+#endif /* __STDC__ >= 1 */
+#endif /* gcc >= 4.3 && !__cplusplus */
+
+#endif /* __CURL_CURL_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/include/curl/curlver.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/include/curl/curlver.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/include/curl/curlver.h	(revision 331)
@@ -0,0 +1,77 @@
+#ifndef __CURL_CURLVER_H
+#define __CURL_CURLVER_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* This header file contains nothing but libcurl version info, generated by
+   a script at release-time. This was made its own header file in 7.11.2 */
+
+/* This is the global package copyright */
+#define LIBCURL_COPYRIGHT "1996 - 2017 Daniel Stenberg, <daniel@haxx.se>."
+
+/* This is the version number of the libcurl package from which this header
+   file origins: */
+#define LIBCURL_VERSION "7.57.0"
+
+/* The numeric version number is also available "in parts" by using these
+   defines: */
+#define LIBCURL_VERSION_MAJOR 7
+#define LIBCURL_VERSION_MINOR 57
+#define LIBCURL_VERSION_PATCH 0
+
+/* This is the numeric version of the libcurl version number, meant for easier
+   parsing and comparions by programs. The LIBCURL_VERSION_NUM define will
+   always follow this syntax:
+
+         0xXXYYZZ
+
+   Where XX, YY and ZZ are the main version, release and patch numbers in
+   hexadecimal (using 8 bits each). All three numbers are always represented
+   using two digits.  1.2 would appear as "0x010200" while version 9.11.7
+   appears as "0x090b07".
+
+   This 6-digit (24 bits) hexadecimal number does not show pre-release number,
+   and it is always a greater number in a more recent release. It makes
+   comparisons with greater than and less than work.
+
+   Note: This define is the full hex number and _does not_ use the
+   CURL_VERSION_BITS() macro since curl's own configure script greps for it
+   and needs it to contain the full number.
+*/
+#define LIBCURL_VERSION_NUM 0x073900
+
+/*
+ * This is the date and time when the full source package was created. The
+ * timestamp is not stored in git, as the timestamp is properly set in the
+ * tarballs by the maketgz script.
+ *
+ * The format of the date follows this template:
+ *
+ * "2007-11-23"
+ */
+#define LIBCURL_TIMESTAMP "2017-11-29"
+
+#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z)
+#define CURL_AT_LEAST_VERSION(x,y,z) \
+  (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z))
+
+#endif /* __CURL_CURLVER_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/include/curl/easy.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/include/curl/easy.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/include/curl/easy.h	(revision 331)
@@ -0,0 +1,102 @@
+#ifndef __CURL_EASY_H
+#define __CURL_EASY_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+CURL_EXTERN CURL *curl_easy_init(void);
+CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);
+CURL_EXTERN CURLcode curl_easy_perform(CURL *curl);
+CURL_EXTERN void curl_easy_cleanup(CURL *curl);
+
+/*
+ * NAME curl_easy_getinfo()
+ *
+ * DESCRIPTION
+ *
+ * Request internal information from the curl session with this function.  The
+ * third argument MUST be a pointer to a long, a pointer to a char * or a
+ * pointer to a double (as the documentation describes elsewhere).  The data
+ * pointed to will be filled in accordingly and can be relied upon only if the
+ * function returns CURLE_OK.  This function is intended to get used *AFTER* a
+ * performed transfer, all results from this function are undefined until the
+ * transfer is completed.
+ */
+CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
+
+
+/*
+ * NAME curl_easy_duphandle()
+ *
+ * DESCRIPTION
+ *
+ * Creates a new curl session handle with the same options set for the handle
+ * passed in. Duplicating a handle could only be a matter of cloning data and
+ * options, internal state info and things like persistent connections cannot
+ * be transferred. It is useful in multithreaded applications when you can run
+ * curl_easy_duphandle() for each new thread to avoid a series of identical
+ * curl_easy_setopt() invokes in every thread.
+ */
+CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl);
+
+/*
+ * NAME curl_easy_reset()
+ *
+ * DESCRIPTION
+ *
+ * Re-initializes a CURL handle to the default values. This puts back the
+ * handle to the same state as it was in when it was just created.
+ *
+ * It does keep: live connections, the Session ID cache, the DNS cache and the
+ * cookies.
+ */
+CURL_EXTERN void curl_easy_reset(CURL *curl);
+
+/*
+ * NAME curl_easy_recv()
+ *
+ * DESCRIPTION
+ *
+ * Receives data from the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen,
+                                    size_t *n);
+
+/*
+ * NAME curl_easy_send()
+ *
+ * DESCRIPTION
+ *
+ * Sends data over the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer,
+                                    size_t buflen, size_t *n);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/curl-7.57.0/include/curl/mprintf.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/include/curl/mprintf.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/include/curl/mprintf.h	(revision 331)
@@ -0,0 +1,50 @@
+#ifndef __CURL_MPRINTF_H
+#define __CURL_MPRINTF_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <stdarg.h>
+#include <stdio.h> /* needed for FILE */
+#include "curl.h"  /* for CURL_EXTERN */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+CURL_EXTERN int curl_mprintf(const char *format, ...);
+CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...);
+CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...);
+CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength,
+                               const char *format, ...);
+CURL_EXTERN int curl_mvprintf(const char *format, va_list args);
+CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args);
+CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args);
+CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength,
+                                const char *format, va_list args);
+CURL_EXTERN char *curl_maprintf(const char *format, ...);
+CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* __CURL_MPRINTF_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/include/curl/multi.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/include/curl/multi.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/include/curl/multi.h	(revision 331)
@@ -0,0 +1,439 @@
+#ifndef __CURL_MULTI_H
+#define __CURL_MULTI_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/*
+  This is an "external" header file. Don't give away any internals here!
+
+  GOALS
+
+  o Enable a "pull" interface. The application that uses libcurl decides where
+    and when to ask libcurl to get/send data.
+
+  o Enable multiple simultaneous transfers in the same thread without making it
+    complicated for the application.
+
+  o Enable the application to select() on its own file descriptors and curl's
+    file descriptors simultaneous easily.
+
+*/
+
+/*
+ * This header file should not really need to include "curl.h" since curl.h
+ * itself includes this file and we expect user applications to do #include
+ * <curl/curl.h> without the need for especially including multi.h.
+ *
+ * For some reason we added this include here at one point, and rather than to
+ * break existing (wrongly written) libcurl applications, we leave it as-is
+ * but with this warning attached.
+ */
+#include "curl.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
+typedef struct Curl_multi CURLM;
+#else
+typedef void CURLM;
+#endif
+
+typedef enum {
+  CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
+                                    curl_multi_socket*() soon */
+  CURLM_OK,
+  CURLM_BAD_HANDLE,      /* the passed-in handle is not a valid CURLM handle */
+  CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
+  CURLM_OUT_OF_MEMORY,   /* if you ever get this, you're in deep sh*t */
+  CURLM_INTERNAL_ERROR,  /* this is a libcurl bug */
+  CURLM_BAD_SOCKET,      /* the passed in socket argument did not match */
+  CURLM_UNKNOWN_OPTION,  /* curl_multi_setopt() with unsupported option */
+  CURLM_ADDED_ALREADY,   /* an easy handle already added to a multi handle was
+                            attempted to get added - again */
+  CURLM_LAST
+} CURLMcode;
+
+/* just to make code nicer when using curl_multi_socket() you can now check
+   for CURLM_CALL_MULTI_SOCKET too in the same style it works for
+   curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */
+#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM
+
+/* bitmask bits for CURLMOPT_PIPELINING */
+#define CURLPIPE_NOTHING   0L
+#define CURLPIPE_HTTP1     1L
+#define CURLPIPE_MULTIPLEX 2L
+
+typedef enum {
+  CURLMSG_NONE, /* first, not used */
+  CURLMSG_DONE, /* This easy handle has completed. 'result' contains
+                   the CURLcode of the transfer */
+  CURLMSG_LAST /* last, not used */
+} CURLMSG;
+
+struct CURLMsg {
+  CURLMSG msg;       /* what this message means */
+  CURL *easy_handle; /* the handle it concerns */
+  union {
+    void *whatever;    /* message-specific data */
+    CURLcode result;   /* return code for transfer */
+  } data;
+};
+typedef struct CURLMsg CURLMsg;
+
+/* Based on poll(2) structure and values.
+ * We don't use pollfd and POLL* constants explicitly
+ * to cover platforms without poll(). */
+#define CURL_WAIT_POLLIN    0x0001
+#define CURL_WAIT_POLLPRI   0x0002
+#define CURL_WAIT_POLLOUT   0x0004
+
+struct curl_waitfd {
+  curl_socket_t fd;
+  short events;
+  short revents; /* not supported yet */
+};
+
+/*
+ * Name:    curl_multi_init()
+ *
+ * Desc:    inititalize multi-style curl usage
+ *
+ * Returns: a new CURLM handle to use in all 'curl_multi' functions.
+ */
+CURL_EXTERN CURLM *curl_multi_init(void);
+
+/*
+ * Name:    curl_multi_add_handle()
+ *
+ * Desc:    add a standard curl handle to the multi stack
+ *
+ * Returns: CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle,
+                                            CURL *curl_handle);
+
+ /*
+  * Name:    curl_multi_remove_handle()
+  *
+  * Desc:    removes a curl handle from the multi stack again
+  *
+  * Returns: CURLMcode type, general multi error code.
+  */
+CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
+                                               CURL *curl_handle);
+
+ /*
+  * Name:    curl_multi_fdset()
+  *
+  * Desc:    Ask curl for its fd_set sets. The app can use these to select() or
+  *          poll() on. We want curl_multi_perform() called as soon as one of
+  *          them are ready.
+  *
+  * Returns: CURLMcode type, general multi error code.
+  */
+CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle,
+                                       fd_set *read_fd_set,
+                                       fd_set *write_fd_set,
+                                       fd_set *exc_fd_set,
+                                       int *max_fd);
+
+/*
+ * Name:     curl_multi_wait()
+ *
+ * Desc:     Poll on all fds within a CURLM set as well as any
+ *           additional fds passed to the function.
+ *
+ * Returns:  CURLMcode type, general multi error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle,
+                                      struct curl_waitfd extra_fds[],
+                                      unsigned int extra_nfds,
+                                      int timeout_ms,
+                                      int *ret);
+
+ /*
+  * Name:    curl_multi_perform()
+  *
+  * Desc:    When the app thinks there's data available for curl it calls this
+  *          function to read/write whatever there is right now. This returns
+  *          as soon as the reads and writes are done. This function does not
+  *          require that there actually is data available for reading or that
+  *          data can be written, it can be called just in case. It returns
+  *          the number of handles that still transfer data in the second
+  *          argument's integer-pointer.
+  *
+  * Returns: CURLMcode type, general multi error code. *NOTE* that this only
+  *          returns errors etc regarding the whole multi stack. There might
+  *          still have occurred problems on invidual transfers even when this
+  *          returns OK.
+  */
+CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle,
+                                         int *running_handles);
+
+ /*
+  * Name:    curl_multi_cleanup()
+  *
+  * Desc:    Cleans up and removes a whole multi stack. It does not free or
+  *          touch any individual easy handles in any way. We need to define
+  *          in what state those handles will be if this function is called
+  *          in the middle of a transfer.
+  *
+  * Returns: CURLMcode type, general multi error code.
+  */
+CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle);
+
+/*
+ * Name:    curl_multi_info_read()
+ *
+ * Desc:    Ask the multi handle if there's any messages/informationals from
+ *          the individual transfers. Messages include informationals such as
+ *          error code from the transfer or just the fact that a transfer is
+ *          completed. More details on these should be written down as well.
+ *
+ *          Repeated calls to this function will return a new struct each
+ *          time, until a special "end of msgs" struct is returned as a signal
+ *          that there is no more to get at this point.
+ *
+ *          The data the returned pointer points to will not survive calling
+ *          curl_multi_cleanup().
+ *
+ *          The 'CURLMsg' struct is meant to be very simple and only contain
+ *          very basic information. If more involved information is wanted,
+ *          we will provide the particular "transfer handle" in that struct
+ *          and that should/could/would be used in subsequent
+ *          curl_easy_getinfo() calls (or similar). The point being that we
+ *          must never expose complex structs to applications, as then we'll
+ *          undoubtably get backwards compatibility problems in the future.
+ *
+ * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out
+ *          of structs. It also writes the number of messages left in the
+ *          queue (after this read) in the integer the second argument points
+ *          to.
+ */
+CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle,
+                                          int *msgs_in_queue);
+
+/*
+ * Name:    curl_multi_strerror()
+ *
+ * Desc:    The curl_multi_strerror function may be used to turn a CURLMcode
+ *          value into the equivalent human readable error string.  This is
+ *          useful for printing meaningful error messages.
+ *
+ * Returns: A pointer to a zero-terminated error message.
+ */
+CURL_EXTERN const char *curl_multi_strerror(CURLMcode);
+
+/*
+ * Name:    curl_multi_socket() and
+ *          curl_multi_socket_all()
+ *
+ * Desc:    An alternative version of curl_multi_perform() that allows the
+ *          application to pass in one of the file descriptors that have been
+ *          detected to have "action" on them and let libcurl perform.
+ *          See man page for details.
+ */
+#define CURL_POLL_NONE   0
+#define CURL_POLL_IN     1
+#define CURL_POLL_OUT    2
+#define CURL_POLL_INOUT  3
+#define CURL_POLL_REMOVE 4
+
+#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD
+
+#define CURL_CSELECT_IN   0x01
+#define CURL_CSELECT_OUT  0x02
+#define CURL_CSELECT_ERR  0x04
+
+typedef int (*curl_socket_callback)(CURL *easy,      /* easy handle */
+                                    curl_socket_t s, /* socket */
+                                    int what,        /* see above */
+                                    void *userp,     /* private callback
+                                                        pointer */
+                                    void *socketp);  /* private socket
+                                                        pointer */
+/*
+ * Name:    curl_multi_timer_callback
+ *
+ * Desc:    Called by libcurl whenever the library detects a change in the
+ *          maximum number of milliseconds the app is allowed to wait before
+ *          curl_multi_socket() or curl_multi_perform() must be called
+ *          (to allow libcurl's timed events to take place).
+ *
+ * Returns: The callback should return zero.
+ */
+typedef int (*curl_multi_timer_callback)(CURLM *multi,    /* multi handle */
+                                         long timeout_ms, /* see above */
+                                         void *userp);    /* private callback
+                                                             pointer */
+
+CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s,
+                                        int *running_handles);
+
+CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle,
+                                               curl_socket_t s,
+                                               int ev_bitmask,
+                                               int *running_handles);
+
+CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle,
+                                            int *running_handles);
+
+#ifndef CURL_ALLOW_OLD_MULTI_SOCKET
+/* This macro below was added in 7.16.3 to push users who recompile to use
+   the new curl_multi_socket_action() instead of the old curl_multi_socket()
+*/
+#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z)
+#endif
+
+/*
+ * Name:    curl_multi_timeout()
+ *
+ * Desc:    Returns the maximum number of milliseconds the app is allowed to
+ *          wait before curl_multi_socket() or curl_multi_perform() must be
+ *          called (to allow libcurl's timed events to take place).
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle,
+                                         long *milliseconds);
+
+#undef CINIT /* re-using the same name as in curl.h */
+
+#ifdef CURL_ISOCPP
+#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num
+#else
+/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */
+#define LONG          CURLOPTTYPE_LONG
+#define OBJECTPOINT   CURLOPTTYPE_OBJECTPOINT
+#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
+#define OFF_T         CURLOPTTYPE_OFF_T
+#define CINIT(name,type,number) CURLMOPT_/**/name = type + number
+#endif
+
+typedef enum {
+  /* This is the socket callback function pointer */
+  CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1),
+
+  /* This is the argument passed to the socket callback */
+  CINIT(SOCKETDATA, OBJECTPOINT, 2),
+
+    /* set to 1 to enable pipelining for this multi handle */
+  CINIT(PIPELINING, LONG, 3),
+
+   /* This is the timer callback function pointer */
+  CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4),
+
+  /* This is the argument passed to the timer callback */
+  CINIT(TIMERDATA, OBJECTPOINT, 5),
+
+  /* maximum number of entries in the connection cache */
+  CINIT(MAXCONNECTS, LONG, 6),
+
+  /* maximum number of (pipelining) connections to one host */
+  CINIT(MAX_HOST_CONNECTIONS, LONG, 7),
+
+  /* maximum number of requests in a pipeline */
+  CINIT(MAX_PIPELINE_LENGTH, LONG, 8),
+
+  /* a connection with a content-length longer than this
+     will not be considered for pipelining */
+  CINIT(CONTENT_LENGTH_PENALTY_SIZE, OFF_T, 9),
+
+  /* a connection with a chunk length longer than this
+     will not be considered for pipelining */
+  CINIT(CHUNK_LENGTH_PENALTY_SIZE, OFF_T, 10),
+
+  /* a list of site names(+port) that are blacklisted from
+     pipelining */
+  CINIT(PIPELINING_SITE_BL, OBJECTPOINT, 11),
+
+  /* a list of server types that are blacklisted from
+     pipelining */
+  CINIT(PIPELINING_SERVER_BL, OBJECTPOINT, 12),
+
+  /* maximum number of open connections in total */
+  CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13),
+
+   /* This is the server push callback function pointer */
+  CINIT(PUSHFUNCTION, FUNCTIONPOINT, 14),
+
+  /* This is the argument passed to the server push callback */
+  CINIT(PUSHDATA, OBJECTPOINT, 15),
+
+  CURLMOPT_LASTENTRY /* the last unused */
+} CURLMoption;
+
+
+/*
+ * Name:    curl_multi_setopt()
+ *
+ * Desc:    Sets options for the multi handle.
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle,
+                                        CURLMoption option, ...);
+
+
+/*
+ * Name:    curl_multi_assign()
+ *
+ * Desc:    This function sets an association in the multi handle between the
+ *          given socket and a private pointer of the application. This is
+ *          (only) useful for curl_multi_socket uses.
+ *
+ * Returns: CURLM error code.
+ */
+CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle,
+                                        curl_socket_t sockfd, void *sockp);
+
+
+/*
+ * Name: curl_push_callback
+ *
+ * Desc: This callback gets called when a new stream is being pushed by the
+ *       server. It approves or denies the new stream.
+ *
+ * Returns: CURL_PUSH_OK or CURL_PUSH_DENY.
+ */
+#define CURL_PUSH_OK   0
+#define CURL_PUSH_DENY 1
+
+struct curl_pushheaders;  /* forward declaration only */
+
+CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h,
+                                        size_t num);
+CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h,
+                                         const char *name);
+
+typedef int (*curl_push_callback)(CURL *parent,
+                                  CURL *easy,
+                                  size_t num_headers,
+                                  struct curl_pushheaders *headers,
+                                  void *userp);
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/curl-7.57.0/include/curl/stdcheaders.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/include/curl/stdcheaders.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/include/curl/stdcheaders.h	(revision 331)
@@ -0,0 +1,33 @@
+#ifndef __STDC_HEADERS_H
+#define __STDC_HEADERS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <sys/types.h>
+
+size_t fread(void *, size_t, size_t, FILE *);
+size_t fwrite(const void *, size_t, size_t, FILE *);
+
+int strcasecmp(const char *, const char *);
+int strncasecmp(const char *, const char *, size_t);
+
+#endif /* __STDC_HEADERS_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/include/curl/system.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/include/curl/system.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/include/curl/system.h	(revision 331)
@@ -0,0 +1,471 @@
+#ifndef __CURL_SYSTEM_H
+#define __CURL_SYSTEM_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Try to keep one section per platform, compiler and architecture, otherwise,
+ * if an existing section is reused for a different one and later on the
+ * original is adjusted, probably the piggybacking one can be adversely
+ * changed.
+ *
+ * In order to differentiate between platforms/compilers/architectures use
+ * only compiler built in predefined preprocessor symbols.
+ *
+ * curl_off_t
+ * ----------
+ *
+ * For any given platform/compiler curl_off_t must be typedef'ed to a 64-bit
+ * wide signed integral data type. The width of this data type must remain
+ * constant and independent of any possible large file support settings.
+ *
+ * As an exception to the above, curl_off_t shall be typedef'ed to a 32-bit
+ * wide signed integral data type if there is no 64-bit type.
+ *
+ * As a general rule, curl_off_t shall not be mapped to off_t. This rule shall
+ * only be violated if off_t is the only 64-bit data type available and the
+ * size of off_t is independent of large file support settings. Keep your
+ * build on the safe side avoiding an off_t gating.  If you have a 64-bit
+ * off_t then take for sure that another 64-bit data type exists, dig deeper
+ * and you will find it.
+ *
+ */
+
+#if defined(__DJGPP__) || defined(__GO32__)
+#  if defined(__DJGPP__) && (__DJGPP__ > 1)
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  else
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__SALFORDC__)
+#  define CURL_TYPEOF_CURL_OFF_T     long
+#  define CURL_FORMAT_CURL_OFF_T     "ld"
+#  define CURL_FORMAT_CURL_OFF_TU    "lu"
+#  define CURL_SUFFIX_CURL_OFF_T     L
+#  define CURL_SUFFIX_CURL_OFF_TU    UL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__BORLANDC__)
+#  if (__BORLANDC__ < 0x520)
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  else
+#    define CURL_TYPEOF_CURL_OFF_T     __int64
+#    define CURL_FORMAT_CURL_OFF_T     "I64d"
+#    define CURL_FORMAT_CURL_OFF_TU    "I64u"
+#    define CURL_SUFFIX_CURL_OFF_T     i64
+#    define CURL_SUFFIX_CURL_OFF_TU    ui64
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__TURBOC__)
+#  define CURL_TYPEOF_CURL_OFF_T     long
+#  define CURL_FORMAT_CURL_OFF_T     "ld"
+#  define CURL_FORMAT_CURL_OFF_TU    "lu"
+#  define CURL_SUFFIX_CURL_OFF_T     L
+#  define CURL_SUFFIX_CURL_OFF_TU    UL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__WATCOMC__)
+#  if defined(__386__)
+#    define CURL_TYPEOF_CURL_OFF_T     __int64
+#    define CURL_FORMAT_CURL_OFF_T     "I64d"
+#    define CURL_FORMAT_CURL_OFF_TU    "I64u"
+#    define CURL_SUFFIX_CURL_OFF_T     i64
+#    define CURL_SUFFIX_CURL_OFF_TU    ui64
+#  else
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__POCC__)
+#  if (__POCC__ < 280)
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  elif defined(_MSC_VER)
+#    define CURL_TYPEOF_CURL_OFF_T     __int64
+#    define CURL_FORMAT_CURL_OFF_T     "I64d"
+#    define CURL_FORMAT_CURL_OFF_TU    "I64u"
+#    define CURL_SUFFIX_CURL_OFF_T     i64
+#    define CURL_SUFFIX_CURL_OFF_TU    ui64
+#  else
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__LCC__)
+#  define CURL_TYPEOF_CURL_OFF_T     long
+#  define CURL_FORMAT_CURL_OFF_T     "ld"
+#  define CURL_FORMAT_CURL_OFF_TU    "lu"
+#  define CURL_SUFFIX_CURL_OFF_T     L
+#  define CURL_SUFFIX_CURL_OFF_TU    UL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__SYMBIAN32__)
+#  if defined(__EABI__)  /* Treat all ARM compilers equally */
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  elif defined(__CW32__)
+#    pragma longlong on
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  elif defined(__VC32__)
+#    define CURL_TYPEOF_CURL_OFF_T     __int64
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
+
+#elif defined(__MWERKS__)
+#  define CURL_TYPEOF_CURL_OFF_T     long long
+#  define CURL_FORMAT_CURL_OFF_T     "lld"
+#  define CURL_FORMAT_CURL_OFF_TU    "llu"
+#  define CURL_SUFFIX_CURL_OFF_T     LL
+#  define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(_WIN32_WCE)
+#  define CURL_TYPEOF_CURL_OFF_T     __int64
+#  define CURL_FORMAT_CURL_OFF_T     "I64d"
+#  define CURL_FORMAT_CURL_OFF_TU    "I64u"
+#  define CURL_SUFFIX_CURL_OFF_T     i64
+#  define CURL_SUFFIX_CURL_OFF_TU    ui64
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__MINGW32__)
+#  define CURL_TYPEOF_CURL_OFF_T     long long
+#  define CURL_FORMAT_CURL_OFF_T     "I64d"
+#  define CURL_FORMAT_CURL_OFF_TU    "I64u"
+#  define CURL_SUFFIX_CURL_OFF_T     LL
+#  define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#  define CURL_PULL_SYS_TYPES_H      1
+#  define CURL_PULL_WS2TCPIP_H       1
+
+#elif defined(__VMS)
+#  if defined(__VAX)
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  else
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int
+
+#elif defined(__OS400__)
+#  if defined(__ILEC400__)
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#    define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#    define CURL_PULL_SYS_TYPES_H      1
+#    define CURL_PULL_SYS_SOCKET_H     1
+#  endif
+
+#elif defined(__MVS__)
+#  if defined(__IBMC__) || defined(__IBMCPP__)
+#    if defined(_ILP32)
+#    elif defined(_LP64)
+#    endif
+#    if defined(_LONG_LONG)
+#      define CURL_TYPEOF_CURL_OFF_T     long long
+#      define CURL_FORMAT_CURL_OFF_T     "lld"
+#      define CURL_FORMAT_CURL_OFF_TU    "llu"
+#      define CURL_SUFFIX_CURL_OFF_T     LL
+#      define CURL_SUFFIX_CURL_OFF_TU    ULL
+#    elif defined(_LP64)
+#      define CURL_TYPEOF_CURL_OFF_T     long
+#      define CURL_FORMAT_CURL_OFF_T     "ld"
+#      define CURL_FORMAT_CURL_OFF_TU    "lu"
+#      define CURL_SUFFIX_CURL_OFF_T     L
+#      define CURL_SUFFIX_CURL_OFF_TU    UL
+#    else
+#      define CURL_TYPEOF_CURL_OFF_T     long
+#      define CURL_FORMAT_CURL_OFF_T     "ld"
+#      define CURL_FORMAT_CURL_OFF_TU    "lu"
+#      define CURL_SUFFIX_CURL_OFF_T     L
+#      define CURL_SUFFIX_CURL_OFF_TU    UL
+#    endif
+#    define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#    define CURL_PULL_SYS_TYPES_H      1
+#    define CURL_PULL_SYS_SOCKET_H     1
+#  endif
+
+#elif defined(__370__)
+#  if defined(__IBMC__) || defined(__IBMCPP__)
+#    if defined(_ILP32)
+#    elif defined(_LP64)
+#    endif
+#    if defined(_LONG_LONG)
+#      define CURL_TYPEOF_CURL_OFF_T     long long
+#      define CURL_FORMAT_CURL_OFF_T     "lld"
+#      define CURL_FORMAT_CURL_OFF_TU    "llu"
+#      define CURL_SUFFIX_CURL_OFF_T     LL
+#      define CURL_SUFFIX_CURL_OFF_TU    ULL
+#    elif defined(_LP64)
+#      define CURL_TYPEOF_CURL_OFF_T     long
+#      define CURL_FORMAT_CURL_OFF_T     "ld"
+#      define CURL_FORMAT_CURL_OFF_TU    "lu"
+#      define CURL_SUFFIX_CURL_OFF_T     L
+#      define CURL_SUFFIX_CURL_OFF_TU    UL
+#    else
+#      define CURL_TYPEOF_CURL_OFF_T     long
+#      define CURL_FORMAT_CURL_OFF_T     "ld"
+#      define CURL_FORMAT_CURL_OFF_TU    "lu"
+#      define CURL_SUFFIX_CURL_OFF_T     L
+#      define CURL_SUFFIX_CURL_OFF_TU    UL
+#    endif
+#    define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#    define CURL_PULL_SYS_TYPES_H      1
+#    define CURL_PULL_SYS_SOCKET_H     1
+#  endif
+
+#elif defined(TPF)
+#  define CURL_TYPEOF_CURL_OFF_T     long
+#  define CURL_FORMAT_CURL_OFF_T     "ld"
+#  define CURL_FORMAT_CURL_OFF_TU    "lu"
+#  define CURL_SUFFIX_CURL_OFF_T     L
+#  define CURL_SUFFIX_CURL_OFF_TU    UL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+#elif defined(__TINYC__) /* also known as tcc */
+
+#  define CURL_TYPEOF_CURL_OFF_T     long long
+#  define CURL_FORMAT_CURL_OFF_T     "lld"
+#  define CURL_FORMAT_CURL_OFF_TU    "llu"
+#  define CURL_SUFFIX_CURL_OFF_T     LL
+#  define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#  define CURL_PULL_SYS_TYPES_H      1
+#  define CURL_PULL_SYS_SOCKET_H     1
+
+#elif defined(__SUNPRO_C) /* Oracle Solaris Studio */
+#  if !defined(__LP64) && (defined(__ILP32) ||                          \
+                           defined(__i386) || defined(__sparcv8))
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  elif defined(__LP64) || \
+        defined(__amd64) || defined(__sparcv9)
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#  define CURL_PULL_SYS_TYPES_H      1
+#  define CURL_PULL_SYS_SOCKET_H     1
+
+/* ===================================== */
+/*    KEEP MSVC THE PENULTIMATE ENTRY    */
+/* ===================================== */
+
+#elif defined(_MSC_VER)
+#  if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
+#    define CURL_TYPEOF_CURL_OFF_T     __int64
+#    define CURL_FORMAT_CURL_OFF_T     "I64d"
+#    define CURL_FORMAT_CURL_OFF_TU    "I64u"
+#    define CURL_SUFFIX_CURL_OFF_T     i64
+#    define CURL_SUFFIX_CURL_OFF_TU    ui64
+#  else
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T int
+
+/* ===================================== */
+/*    KEEP GENERIC GCC THE LAST ENTRY    */
+/* ===================================== */
+
+#elif defined(__GNUC__)
+#  if !defined(__LP64__) &&                                             \
+  (defined(__ILP32__) || defined(__i386__) || defined(__hppa__) ||      \
+   defined(__ppc__) || defined(__powerpc__) || defined(__arm__) ||      \
+   defined(__sparc__) || defined(__mips__) || defined(__sh__) ||        \
+   defined(__XTENSA__) ||                                               \
+   (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 4))
+#    define CURL_TYPEOF_CURL_OFF_T     long long
+#    define CURL_FORMAT_CURL_OFF_T     "lld"
+#    define CURL_FORMAT_CURL_OFF_TU    "llu"
+#    define CURL_SUFFIX_CURL_OFF_T     LL
+#    define CURL_SUFFIX_CURL_OFF_TU    ULL
+#  elif defined(__LP64__) || \
+        defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) || \
+        (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ == 8)
+#    define CURL_TYPEOF_CURL_OFF_T     long
+#    define CURL_FORMAT_CURL_OFF_T     "ld"
+#    define CURL_FORMAT_CURL_OFF_TU    "lu"
+#    define CURL_SUFFIX_CURL_OFF_T     L
+#    define CURL_SUFFIX_CURL_OFF_TU    UL
+#  endif
+#  define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t
+#  define CURL_PULL_SYS_TYPES_H      1
+#  define CURL_PULL_SYS_SOCKET_H     1
+
+#else
+/* generic "safe guess" on old 32 bit style */
+# define CURL_TYPEOF_CURL_OFF_T     long
+# define CURL_FORMAT_CURL_OFF_T     "ld"
+# define CURL_FORMAT_CURL_OFF_TU    "lu"
+# define CURL_SUFFIX_CURL_OFF_T     L
+# define CURL_SUFFIX_CURL_OFF_TU    UL
+# define CURL_TYPEOF_CURL_SOCKLEN_T int
+#endif
+
+#ifdef _AIX
+/* AIX needs <sys/poll.h> */
+#define CURL_PULL_SYS_POLL_H
+#endif
+
+
+/* CURL_PULL_WS2TCPIP_H is defined above when inclusion of header file  */
+/* ws2tcpip.h is required here to properly make type definitions below. */
+#ifdef CURL_PULL_WS2TCPIP_H
+#  include <winsock2.h>
+#  include <windows.h>
+#  include <ws2tcpip.h>
+#endif
+
+/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file  */
+/* sys/types.h is required here to properly make type definitions below. */
+#ifdef CURL_PULL_SYS_TYPES_H
+#  include <sys/types.h>
+#endif
+
+/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file  */
+/* sys/socket.h is required here to properly make type definitions below. */
+#ifdef CURL_PULL_SYS_SOCKET_H
+#  include <sys/socket.h>
+#endif
+
+/* CURL_PULL_SYS_POLL_H is defined above when inclusion of header file    */
+/* sys/poll.h is required here to properly make type definitions below.   */
+#ifdef CURL_PULL_SYS_POLL_H
+#  include <sys/poll.h>
+#endif
+
+/* Data type definition of curl_socklen_t. */
+#ifdef CURL_TYPEOF_CURL_SOCKLEN_T
+  typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t;
+#endif
+
+/* Data type definition of curl_off_t. */
+
+#ifdef CURL_TYPEOF_CURL_OFF_T
+  typedef CURL_TYPEOF_CURL_OFF_T curl_off_t;
+#endif
+
+/*
+ * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow
+ * these to be visible and exported by the external libcurl interface API,
+ * while also making them visible to the library internals, simply including
+ * curl_setup.h, without actually needing to include curl.h internally.
+ * If some day this section would grow big enough, all this should be moved
+ * to its own header file.
+ */
+
+/*
+ * Figure out if we can use the ## preprocessor operator, which is supported
+ * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__
+ * or  __cplusplus so we need to carefully check for them too.
+ */
+
+#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \
+  defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \
+  defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \
+  defined(__ILEC400__)
+  /* This compiler is believed to have an ISO compatible preprocessor */
+#define CURL_ISOCPP
+#else
+  /* This compiler is believed NOT to have an ISO compatible preprocessor */
+#undef CURL_ISOCPP
+#endif
+
+/*
+ * Macros for minimum-width signed and unsigned curl_off_t integer constants.
+ */
+
+#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551)
+#  define __CURL_OFF_T_C_HLPR2(x) x
+#  define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x)
+#  define CURL_OFF_T_C(Val)  __CURL_OFF_T_C_HLPR1(Val) ## \
+                             __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T)
+#  define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \
+                             __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU)
+#else
+#  ifdef CURL_ISOCPP
+#    define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix
+#  else
+#    define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix
+#  endif
+#  define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix)
+#  define CURL_OFF_T_C(Val)  __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T)
+#  define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU)
+#endif
+
+#endif /* __CURL_SYSTEM_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/include/curl/typecheck-gcc.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/include/curl/typecheck-gcc.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/include/curl/typecheck-gcc.h	(revision 331)
@@ -0,0 +1,683 @@
+#ifndef __CURL_TYPECHECK_GCC_H
+#define __CURL_TYPECHECK_GCC_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* wraps curl_easy_setopt() with typechecking */
+
+/* To add a new kind of warning, add an
+ *   if(_curl_is_sometype_option(_curl_opt))
+ *     if(!_curl_is_sometype(value))
+ *       _curl_easy_setopt_err_sometype();
+ * block and define _curl_is_sometype_option, _curl_is_sometype and
+ * _curl_easy_setopt_err_sometype below
+ *
+ * NOTE: We use two nested 'if' statements here instead of the && operator, in
+ *       order to work around gcc bug #32061.  It affects only gcc 4.3.x/4.4.x
+ *       when compiling with -Wlogical-op.
+ *
+ * To add an option that uses the same type as an existing option, you'll just
+ * need to extend the appropriate _curl_*_option macro
+ */
+#define curl_easy_setopt(handle, option, value)                               \
+__extension__ ({                                                              \
+  __typeof__(option) _curl_opt = option;                                     \
+  if(__builtin_constant_p(_curl_opt)) {                                       \
+    if(_curl_is_long_option(_curl_opt))                                       \
+      if(!_curl_is_long(value))                                               \
+        _curl_easy_setopt_err_long();                                         \
+    if(_curl_is_off_t_option(_curl_opt))                                      \
+      if(!_curl_is_off_t(value))                                              \
+        _curl_easy_setopt_err_curl_off_t();                                   \
+    if(_curl_is_string_option(_curl_opt))                                     \
+      if(!_curl_is_string(value))                                             \
+        _curl_easy_setopt_err_string();                                       \
+    if(_curl_is_write_cb_option(_curl_opt))                                   \
+      if(!_curl_is_write_cb(value))                                           \
+        _curl_easy_setopt_err_write_callback();                               \
+    if((_curl_opt) == CURLOPT_READFUNCTION)                                   \
+      if(!_curl_is_read_cb(value))                                            \
+        _curl_easy_setopt_err_read_cb();                                      \
+    if((_curl_opt) == CURLOPT_IOCTLFUNCTION)                                  \
+      if(!_curl_is_ioctl_cb(value))                                           \
+        _curl_easy_setopt_err_ioctl_cb();                                     \
+    if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION)                                \
+      if(!_curl_is_sockopt_cb(value))                                         \
+        _curl_easy_setopt_err_sockopt_cb();                                   \
+    if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION)                             \
+      if(!_curl_is_opensocket_cb(value))                                      \
+        _curl_easy_setopt_err_opensocket_cb();                                \
+    if((_curl_opt) == CURLOPT_PROGRESSFUNCTION)                               \
+      if(!_curl_is_progress_cb(value))                                        \
+        _curl_easy_setopt_err_progress_cb();                                  \
+    if((_curl_opt) == CURLOPT_DEBUGFUNCTION)                                  \
+      if(!_curl_is_debug_cb(value))                                           \
+        _curl_easy_setopt_err_debug_cb();                                     \
+    if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION)                               \
+      if(!_curl_is_ssl_ctx_cb(value))                                         \
+        _curl_easy_setopt_err_ssl_ctx_cb();                                   \
+    if(_curl_is_conv_cb_option(_curl_opt))                                    \
+      if(!_curl_is_conv_cb(value))                                            \
+        _curl_easy_setopt_err_conv_cb();                                      \
+    if((_curl_opt) == CURLOPT_SEEKFUNCTION)                                   \
+      if(!_curl_is_seek_cb(value))                                            \
+        _curl_easy_setopt_err_seek_cb();                                      \
+    if(_curl_is_cb_data_option(_curl_opt))                                    \
+      if(!_curl_is_cb_data(value))                                            \
+        _curl_easy_setopt_err_cb_data();                                      \
+    if((_curl_opt) == CURLOPT_ERRORBUFFER)                                    \
+      if(!_curl_is_error_buffer(value))                                       \
+        _curl_easy_setopt_err_error_buffer();                                 \
+    if((_curl_opt) == CURLOPT_STDERR)                                         \
+      if(!_curl_is_FILE(value))                                               \
+        _curl_easy_setopt_err_FILE();                                         \
+    if(_curl_is_postfields_option(_curl_opt))                                 \
+      if(!_curl_is_postfields(value))                                         \
+        _curl_easy_setopt_err_postfields();                                   \
+    if((_curl_opt) == CURLOPT_HTTPPOST)                                       \
+      if(!_curl_is_arr((value), struct curl_httppost))                        \
+        _curl_easy_setopt_err_curl_httpost();                                 \
+    if((_curl_opt) == CURLOPT_MIMEPOST)                                       \
+      if(!_curl_is_ptr((value), curl_mime))                                   \
+        _curl_easy_setopt_err_curl_mimepost();                                \
+    if(_curl_is_slist_option(_curl_opt))                                      \
+      if(!_curl_is_arr((value), struct curl_slist))                           \
+        _curl_easy_setopt_err_curl_slist();                                   \
+    if((_curl_opt) == CURLOPT_SHARE)                                          \
+      if(!_curl_is_ptr((value), CURLSH))                                      \
+        _curl_easy_setopt_err_CURLSH();                                       \
+  }                                                                           \
+  curl_easy_setopt(handle, _curl_opt, value);                                 \
+})
+
+/* wraps curl_easy_getinfo() with typechecking */
+/* FIXME: don't allow const pointers */
+#define curl_easy_getinfo(handle, info, arg)                                  \
+__extension__ ({                                                              \
+  __typeof__(info) _curl_info = info;                                         \
+  if(__builtin_constant_p(_curl_info)) {                                      \
+    if(_curl_is_string_info(_curl_info))                                      \
+      if(!_curl_is_arr((arg), char *))                                        \
+        _curl_easy_getinfo_err_string();                                      \
+    if(_curl_is_long_info(_curl_info))                                        \
+      if(!_curl_is_arr((arg), long))                                          \
+        _curl_easy_getinfo_err_long();                                        \
+    if(_curl_is_double_info(_curl_info))                                      \
+      if(!_curl_is_arr((arg), double))                                        \
+        _curl_easy_getinfo_err_double();                                      \
+    if(_curl_is_slist_info(_curl_info))                                       \
+      if(!_curl_is_arr((arg), struct curl_slist *))                           \
+        _curl_easy_getinfo_err_curl_slist();                                  \
+    if(_curl_is_tlssessioninfo_info(_curl_info))                              \
+      if(!_curl_is_arr((arg), struct curl_tlssessioninfo *))                  \
+        _curl_easy_getinfo_err_curl_tlssesssioninfo();                        \
+    if(_curl_is_certinfo_info(_curl_info))                                    \
+      if(!_curl_is_arr((arg), struct curl_certinfo *))                        \
+        _curl_easy_getinfo_err_curl_certinfo();                               \
+    if(_curl_is_socket_info(_curl_info))                                      \
+      if(!_curl_is_arr((arg), curl_socket_t))                                 \
+        _curl_easy_getinfo_err_curl_socket();                                 \
+    if(_curl_is_off_t_info(_curl_info))                                       \
+      if(!_curl_is_arr((arg), curl_off_t))                                    \
+        _curl_easy_getinfo_err_curl_off_t();                                  \
+  }                                                                           \
+  curl_easy_getinfo(handle, _curl_info, arg);                                 \
+})
+
+/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(),
+ * for now just make sure that the functions are called with three
+ * arguments
+ */
+#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
+#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
+
+
+/* the actual warnings, triggered by calling the _curl_easy_setopt_err*
+ * functions */
+
+/* To define a new warning, use _CURL_WARNING(identifier, "message") */
+#define _CURL_WARNING(id, message)                                            \
+  static void __attribute__((__warning__(message)))                           \
+  __attribute__((__unused__)) __attribute__((__noinline__))                   \
+  id(void) { __asm__(""); }
+
+_CURL_WARNING(_curl_easy_setopt_err_long,
+  "curl_easy_setopt expects a long argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_off_t,
+  "curl_easy_setopt expects a curl_off_t argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_string,
+              "curl_easy_setopt expects a "
+              "string ('char *' or char[]) argument for this option"
+  )
+_CURL_WARNING(_curl_easy_setopt_err_write_callback,
+  "curl_easy_setopt expects a curl_write_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_read_cb,
+  "curl_easy_setopt expects a curl_read_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb,
+  "curl_easy_setopt expects a curl_ioctl_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb,
+  "curl_easy_setopt expects a curl_sockopt_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb,
+              "curl_easy_setopt expects a "
+              "curl_opensocket_callback argument for this option"
+  )
+_CURL_WARNING(_curl_easy_setopt_err_progress_cb,
+  "curl_easy_setopt expects a curl_progress_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_debug_cb,
+  "curl_easy_setopt expects a curl_debug_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb,
+  "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_conv_cb,
+  "curl_easy_setopt expects a curl_conv_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_seek_cb,
+  "curl_easy_setopt expects a curl_seek_callback argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_cb_data,
+              "curl_easy_setopt expects a "
+              "private data pointer as argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_error_buffer,
+              "curl_easy_setopt expects a "
+              "char buffer of CURL_ERROR_SIZE as argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_FILE,
+  "curl_easy_setopt expects a 'FILE *' argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_postfields,
+  "curl_easy_setopt expects a 'void *' or 'char *' argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_httpost,
+              "curl_easy_setopt expects a 'struct curl_httppost *' "
+              "argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_mimepost,
+              "curl_easy_setopt expects a 'curl_mime *' "
+              "argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_curl_slist,
+  "curl_easy_setopt expects a 'struct curl_slist *' argument for this option")
+_CURL_WARNING(_curl_easy_setopt_err_CURLSH,
+  "curl_easy_setopt expects a CURLSH* argument for this option")
+
+_CURL_WARNING(_curl_easy_getinfo_err_string,
+  "curl_easy_getinfo expects a pointer to 'char *' for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_long,
+  "curl_easy_getinfo expects a pointer to long for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_double,
+  "curl_easy_getinfo expects a pointer to double for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
+  "curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_curl_tlssesssioninfo,
+              "curl_easy_getinfo expects a pointer to "
+              "'struct curl_tlssessioninfo *' for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_curl_certinfo,
+              "curl_easy_getinfo expects a pointer to "
+              "'struct curl_certinfo *' for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_curl_socket,
+  "curl_easy_getinfo expects a pointer to curl_socket_t for this info")
+_CURL_WARNING(_curl_easy_getinfo_err_curl_off_t,
+  "curl_easy_getinfo expects a pointer to curl_off_t for this info")
+
+/* groups of curl_easy_setops options that take the same type of argument */
+
+/* To add a new option to one of the groups, just add
+ *   (option) == CURLOPT_SOMETHING
+ * to the or-expression. If the option takes a long or curl_off_t, you don't
+ * have to do anything
+ */
+
+/* evaluates to true if option takes a long argument */
+#define _curl_is_long_option(option)                                          \
+  (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
+
+#define _curl_is_off_t_option(option)                                         \
+  ((option) > CURLOPTTYPE_OFF_T)
+
+/* evaluates to true if option takes a char* argument */
+#define _curl_is_string_option(option)                                        \
+  ((option) == CURLOPT_ABSTRACT_UNIX_SOCKET ||                                \
+   (option) == CURLOPT_ACCEPT_ENCODING ||                                     \
+   (option) == CURLOPT_CAINFO ||                                              \
+   (option) == CURLOPT_CAPATH ||                                              \
+   (option) == CURLOPT_COOKIE ||                                              \
+   (option) == CURLOPT_COOKIEFILE ||                                          \
+   (option) == CURLOPT_COOKIEJAR ||                                           \
+   (option) == CURLOPT_COOKIELIST ||                                          \
+   (option) == CURLOPT_CRLFILE ||                                             \
+   (option) == CURLOPT_CUSTOMREQUEST ||                                       \
+   (option) == CURLOPT_DEFAULT_PROTOCOL ||                                    \
+   (option) == CURLOPT_DNS_INTERFACE ||                                       \
+   (option) == CURLOPT_DNS_LOCAL_IP4 ||                                       \
+   (option) == CURLOPT_DNS_LOCAL_IP6 ||                                       \
+   (option) == CURLOPT_DNS_SERVERS ||                                         \
+   (option) == CURLOPT_EGDSOCKET ||                                           \
+   (option) == CURLOPT_FTPPORT ||                                             \
+   (option) == CURLOPT_FTP_ACCOUNT ||                                         \
+   (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER ||                             \
+   (option) == CURLOPT_INTERFACE ||                                           \
+   (option) == CURLOPT_ISSUERCERT ||                                          \
+   (option) == CURLOPT_KEYPASSWD ||                                           \
+   (option) == CURLOPT_KRBLEVEL ||                                            \
+   (option) == CURLOPT_LOGIN_OPTIONS ||                                       \
+   (option) == CURLOPT_MAIL_AUTH ||                                           \
+   (option) == CURLOPT_MAIL_FROM ||                                           \
+   (option) == CURLOPT_NETRC_FILE ||                                          \
+   (option) == CURLOPT_NOPROXY ||                                             \
+   (option) == CURLOPT_PASSWORD ||                                            \
+   (option) == CURLOPT_PINNEDPUBLICKEY ||                                     \
+   (option) == CURLOPT_PRE_PROXY ||                                           \
+   (option) == CURLOPT_PROXY ||                                               \
+   (option) == CURLOPT_PROXYPASSWORD ||                                       \
+   (option) == CURLOPT_PROXYUSERNAME ||                                       \
+   (option) == CURLOPT_PROXYUSERPWD ||                                        \
+   (option) == CURLOPT_PROXY_CAINFO ||                                        \
+   (option) == CURLOPT_PROXY_CAPATH ||                                        \
+   (option) == CURLOPT_PROXY_CRLFILE ||                                       \
+   (option) == CURLOPT_PROXY_KEYPASSWD ||                                     \
+   (option) == CURLOPT_PROXY_PINNEDPUBLICKEY ||                               \
+   (option) == CURLOPT_PROXY_SERVICE_NAME ||                                  \
+   (option) == CURLOPT_PROXY_SSLCERT ||                                       \
+   (option) == CURLOPT_PROXY_SSLCERTTYPE ||                                   \
+   (option) == CURLOPT_PROXY_SSLKEY ||                                        \
+   (option) == CURLOPT_PROXY_SSLKEYTYPE ||                                    \
+   (option) == CURLOPT_PROXY_SSL_CIPHER_LIST ||                               \
+   (option) == CURLOPT_PROXY_TLSAUTH_PASSWORD ||                              \
+   (option) == CURLOPT_PROXY_TLSAUTH_USERNAME ||                              \
+   (option) == CURLOPT_PROXY_TLSAUTH_TYPE ||                                  \
+   (option) == CURLOPT_RANDOM_FILE ||                                         \
+   (option) == CURLOPT_RANGE ||                                               \
+   (option) == CURLOPT_REFERER ||                                             \
+   (option) == CURLOPT_RTSP_SESSION_ID ||                                     \
+   (option) == CURLOPT_RTSP_STREAM_URI ||                                     \
+   (option) == CURLOPT_RTSP_TRANSPORT ||                                      \
+   (option) == CURLOPT_SERVICE_NAME ||                                        \
+   (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE ||                               \
+   (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 ||                             \
+   (option) == CURLOPT_SSH_KNOWNHOSTS ||                                      \
+   (option) == CURLOPT_SSH_PRIVATE_KEYFILE ||                                 \
+   (option) == CURLOPT_SSH_PUBLIC_KEYFILE ||                                  \
+   (option) == CURLOPT_SSLCERT ||                                             \
+   (option) == CURLOPT_SSLCERTTYPE ||                                         \
+   (option) == CURLOPT_SSLENGINE ||                                           \
+   (option) == CURLOPT_SSLKEY ||                                              \
+   (option) == CURLOPT_SSLKEYTYPE ||                                          \
+   (option) == CURLOPT_SSL_CIPHER_LIST ||                                     \
+   (option) == CURLOPT_TLSAUTH_PASSWORD ||                                    \
+   (option) == CURLOPT_TLSAUTH_TYPE ||                                        \
+   (option) == CURLOPT_TLSAUTH_USERNAME ||                                    \
+   (option) == CURLOPT_UNIX_SOCKET_PATH ||                                    \
+   (option) == CURLOPT_URL ||                                                 \
+   (option) == CURLOPT_USERAGENT ||                                           \
+   (option) == CURLOPT_USERNAME ||                                            \
+   (option) == CURLOPT_USERPWD ||                                             \
+   (option) == CURLOPT_XOAUTH2_BEARER ||                                      \
+   0)
+
+/* evaluates to true if option takes a curl_write_callback argument */
+#define _curl_is_write_cb_option(option)                                      \
+  ((option) == CURLOPT_HEADERFUNCTION ||                                      \
+   (option) == CURLOPT_WRITEFUNCTION)
+
+/* evaluates to true if option takes a curl_conv_callback argument */
+#define _curl_is_conv_cb_option(option)                                       \
+  ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION ||                            \
+   (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION ||                          \
+   (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION)
+
+/* evaluates to true if option takes a data argument to pass to a callback */
+#define _curl_is_cb_data_option(option)                                       \
+  ((option) == CURLOPT_CHUNK_DATA ||                                          \
+   (option) == CURLOPT_CLOSESOCKETDATA ||                                     \
+   (option) == CURLOPT_DEBUGDATA ||                                           \
+   (option) == CURLOPT_FNMATCH_DATA ||                                        \
+   (option) == CURLOPT_HEADERDATA ||                                          \
+   (option) == CURLOPT_INTERLEAVEDATA ||                                      \
+   (option) == CURLOPT_IOCTLDATA ||                                           \
+   (option) == CURLOPT_OPENSOCKETDATA ||                                      \
+   (option) == CURLOPT_PRIVATE ||                                             \
+   (option) == CURLOPT_PROGRESSDATA ||                                        \
+   (option) == CURLOPT_READDATA ||                                            \
+   (option) == CURLOPT_SEEKDATA ||                                            \
+   (option) == CURLOPT_SOCKOPTDATA ||                                         \
+   (option) == CURLOPT_SSH_KEYDATA ||                                         \
+   (option) == CURLOPT_SSL_CTX_DATA ||                                        \
+   (option) == CURLOPT_WRITEDATA ||                                           \
+   0)
+
+/* evaluates to true if option takes a POST data argument (void* or char*) */
+#define _curl_is_postfields_option(option)                                    \
+  ((option) == CURLOPT_POSTFIELDS ||                                          \
+   (option) == CURLOPT_COPYPOSTFIELDS ||                                      \
+   0)
+
+/* evaluates to true if option takes a struct curl_slist * argument */
+#define _curl_is_slist_option(option)                                         \
+  ((option) == CURLOPT_HTTP200ALIASES ||                                      \
+   (option) == CURLOPT_HTTPHEADER ||                                          \
+   (option) == CURLOPT_MAIL_RCPT ||                                           \
+   (option) == CURLOPT_POSTQUOTE ||                                           \
+   (option) == CURLOPT_PREQUOTE ||                                            \
+   (option) == CURLOPT_PROXYHEADER ||                                         \
+   (option) == CURLOPT_QUOTE ||                                               \
+   (option) == CURLOPT_RESOLVE ||                                             \
+   (option) == CURLOPT_TELNETOPTIONS ||                                       \
+   0)
+
+/* groups of curl_easy_getinfo infos that take the same type of argument */
+
+/* evaluates to true if info expects a pointer to char * argument */
+#define _curl_is_string_info(info)                                            \
+  (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG)
+
+/* evaluates to true if info expects a pointer to long argument */
+#define _curl_is_long_info(info)                                              \
+  (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE)
+
+/* evaluates to true if info expects a pointer to double argument */
+#define _curl_is_double_info(info)                                            \
+  (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST)
+
+/* true if info expects a pointer to struct curl_slist * argument */
+#define _curl_is_slist_info(info)                                       \
+  (((info) == CURLINFO_SSL_ENGINES) || ((info) == CURLINFO_COOKIELIST))
+
+/* true if info expects a pointer to struct curl_tlssessioninfo * argument */
+#define _curl_is_tlssessioninfo_info(info)                              \
+  (((info) == CURLINFO_TLS_SSL_PTR) || ((info) == CURLINFO_TLS_SESSION))
+
+/* true if info expects a pointer to struct curl_certinfo * argument */
+#define _curl_is_certinfo_info(info) ((info) == CURLINFO_CERTINFO)
+
+/* true if info expects a pointer to struct curl_socket_t argument */
+#define _curl_is_socket_info(info)                                            \
+  (CURLINFO_SOCKET < (info) && (info) < CURLINFO_OFF_T)
+
+/* true if info expects a pointer to curl_off_t argument */
+#define _curl_is_off_t_info(info)                                             \
+  (CURLINFO_OFF_T < (info))
+
+
+/* typecheck helpers -- check whether given expression has requested type*/
+
+/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros,
+ * otherwise define a new macro. Search for __builtin_types_compatible_p
+ * in the GCC manual.
+ * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is
+ * the actual expression passed to the curl_easy_setopt macro. This
+ * means that you can only apply the sizeof and __typeof__ operators, no
+ * == or whatsoever.
+ */
+
+/* XXX: should evaluate to true iff expr is a pointer */
+#define _curl_is_any_ptr(expr)                                                \
+  (sizeof(expr) == sizeof(void *))
+
+/* evaluates to true if expr is NULL */
+/* XXX: must not evaluate expr, so this check is not accurate */
+#define _curl_is_NULL(expr)                                                   \
+  (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL)))
+
+/* evaluates to true if expr is type*, const type* or NULL */
+#define _curl_is_ptr(expr, type)                                              \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), type *) ||                  \
+   __builtin_types_compatible_p(__typeof__(expr), const type *))
+
+/* evaluates to true if expr is one of type[], type*, NULL or const type* */
+#define _curl_is_arr(expr, type)                                              \
+  (_curl_is_ptr((expr), type) ||                                              \
+   __builtin_types_compatible_p(__typeof__(expr), type []))
+
+/* evaluates to true if expr is a string */
+#define _curl_is_string(expr)                                                 \
+  (_curl_is_arr((expr), char) ||                                              \
+   _curl_is_arr((expr), signed char) ||                                       \
+   _curl_is_arr((expr), unsigned char))
+
+/* evaluates to true if expr is a long (no matter the signedness)
+ * XXX: for now, int is also accepted (and therefore short and char, which
+ * are promoted to int when passed to a variadic function) */
+#define _curl_is_long(expr)                                                   \
+  (__builtin_types_compatible_p(__typeof__(expr), long) ||                    \
+   __builtin_types_compatible_p(__typeof__(expr), signed long) ||             \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned long) ||           \
+   __builtin_types_compatible_p(__typeof__(expr), int) ||                     \
+   __builtin_types_compatible_p(__typeof__(expr), signed int) ||              \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned int) ||            \
+   __builtin_types_compatible_p(__typeof__(expr), short) ||                   \
+   __builtin_types_compatible_p(__typeof__(expr), signed short) ||            \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned short) ||          \
+   __builtin_types_compatible_p(__typeof__(expr), char) ||                    \
+   __builtin_types_compatible_p(__typeof__(expr), signed char) ||             \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned char))
+
+/* evaluates to true if expr is of type curl_off_t */
+#define _curl_is_off_t(expr)                                                  \
+  (__builtin_types_compatible_p(__typeof__(expr), curl_off_t))
+
+/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
+/* XXX: also check size of an char[] array? */
+#define _curl_is_error_buffer(expr)                                           \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), char *) ||                  \
+   __builtin_types_compatible_p(__typeof__(expr), char[]))
+
+/* evaluates to true if expr is of type (const) void* or (const) FILE* */
+#if 0
+#define _curl_is_cb_data(expr)                                                \
+  (_curl_is_ptr((expr), void) ||                                              \
+   _curl_is_ptr((expr), FILE))
+#else /* be less strict */
+#define _curl_is_cb_data(expr)                                                \
+  _curl_is_any_ptr(expr)
+#endif
+
+/* evaluates to true if expr is of type FILE* */
+#define _curl_is_FILE(expr)                                             \
+  (_curl_is_NULL(expr) ||                                              \
+   (__builtin_types_compatible_p(__typeof__(expr), FILE *)))
+
+/* evaluates to true if expr can be passed as POST data (void* or char*) */
+#define _curl_is_postfields(expr)                                             \
+  (_curl_is_ptr((expr), void) ||                                              \
+   _curl_is_arr((expr), char))
+
+/* FIXME: the whole callback checking is messy...
+ * The idea is to tolerate char vs. void and const vs. not const
+ * pointers in arguments at least
+ */
+/* helper: __builtin_types_compatible_p distinguishes between functions and
+ * function pointers, hide it */
+#define _curl_callback_compatible(func, type)                                 \
+  (__builtin_types_compatible_p(__typeof__(func), type) ||                    \
+   __builtin_types_compatible_p(__typeof__(func) *, type))
+
+/* evaluates to true if expr is of type curl_read_callback or "similar" */
+#define _curl_is_read_cb(expr)                                          \
+  (_curl_is_NULL(expr) ||                                                     \
+   _curl_callback_compatible((expr), __typeof__(fread) *) ||                  \
+   _curl_callback_compatible((expr), curl_read_callback) ||                   \
+   _curl_callback_compatible((expr), _curl_read_callback1) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback2) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback3) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback4) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback5) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback6))
+typedef size_t (*_curl_read_callback1)(char *, size_t, size_t, void *);
+typedef size_t (*_curl_read_callback2)(char *, size_t, size_t, const void *);
+typedef size_t (*_curl_read_callback3)(char *, size_t, size_t, FILE *);
+typedef size_t (*_curl_read_callback4)(void *, size_t, size_t, void *);
+typedef size_t (*_curl_read_callback5)(void *, size_t, size_t, const void *);
+typedef size_t (*_curl_read_callback6)(void *, size_t, size_t, FILE *);
+
+/* evaluates to true if expr is of type curl_write_callback or "similar" */
+#define _curl_is_write_cb(expr)                                               \
+  (_curl_is_read_cb(expr) ||                                            \
+   _curl_callback_compatible((expr), __typeof__(fwrite) *) ||                 \
+   _curl_callback_compatible((expr), curl_write_callback) ||                  \
+   _curl_callback_compatible((expr), _curl_write_callback1) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback2) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback3) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback4) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback5) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback6))
+typedef size_t (*_curl_write_callback1)(const char *, size_t, size_t, void *);
+typedef size_t (*_curl_write_callback2)(const char *, size_t, size_t,
+                                       const void *);
+typedef size_t (*_curl_write_callback3)(const char *, size_t, size_t, FILE *);
+typedef size_t (*_curl_write_callback4)(const void *, size_t, size_t, void *);
+typedef size_t (*_curl_write_callback5)(const void *, size_t, size_t,
+                                       const void *);
+typedef size_t (*_curl_write_callback6)(const void *, size_t, size_t, FILE *);
+
+/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
+#define _curl_is_ioctl_cb(expr)                                         \
+  (_curl_is_NULL(expr) ||                                                     \
+   _curl_callback_compatible((expr), curl_ioctl_callback) ||                  \
+   _curl_callback_compatible((expr), _curl_ioctl_callback1) ||                \
+   _curl_callback_compatible((expr), _curl_ioctl_callback2) ||                \
+   _curl_callback_compatible((expr), _curl_ioctl_callback3) ||                \
+   _curl_callback_compatible((expr), _curl_ioctl_callback4))
+typedef curlioerr (*_curl_ioctl_callback1)(CURL *, int, void *);
+typedef curlioerr (*_curl_ioctl_callback2)(CURL *, int, const void *);
+typedef curlioerr (*_curl_ioctl_callback3)(CURL *, curliocmd, void *);
+typedef curlioerr (*_curl_ioctl_callback4)(CURL *, curliocmd, const void *);
+
+/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
+#define _curl_is_sockopt_cb(expr)                                       \
+  (_curl_is_NULL(expr) ||                                                     \
+   _curl_callback_compatible((expr), curl_sockopt_callback) ||                \
+   _curl_callback_compatible((expr), _curl_sockopt_callback1) ||              \
+   _curl_callback_compatible((expr), _curl_sockopt_callback2))
+typedef int (*_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
+typedef int (*_curl_sockopt_callback2)(const void *, curl_socket_t,
+                                      curlsocktype);
+
+/* evaluates to true if expr is of type curl_opensocket_callback or
+   "similar" */
+#define _curl_is_opensocket_cb(expr)                                    \
+  (_curl_is_NULL(expr) ||                                                     \
+   _curl_callback_compatible((expr), curl_opensocket_callback) ||             \
+   _curl_callback_compatible((expr), _curl_opensocket_callback1) ||           \
+   _curl_callback_compatible((expr), _curl_opensocket_callback2) ||           \
+   _curl_callback_compatible((expr), _curl_opensocket_callback3) ||           \
+   _curl_callback_compatible((expr), _curl_opensocket_callback4))
+typedef curl_socket_t (*_curl_opensocket_callback1)
+  (void *, curlsocktype, struct curl_sockaddr *);
+typedef curl_socket_t (*_curl_opensocket_callback2)
+  (void *, curlsocktype, const struct curl_sockaddr *);
+typedef curl_socket_t (*_curl_opensocket_callback3)
+  (const void *, curlsocktype, struct curl_sockaddr *);
+typedef curl_socket_t (*_curl_opensocket_callback4)
+  (const void *, curlsocktype, const struct curl_sockaddr *);
+
+/* evaluates to true if expr is of type curl_progress_callback or "similar" */
+#define _curl_is_progress_cb(expr)                                      \
+  (_curl_is_NULL(expr) ||                                                     \
+   _curl_callback_compatible((expr), curl_progress_callback) ||               \
+   _curl_callback_compatible((expr), _curl_progress_callback1) ||             \
+   _curl_callback_compatible((expr), _curl_progress_callback2))
+typedef int (*_curl_progress_callback1)(void *,
+    double, double, double, double);
+typedef int (*_curl_progress_callback2)(const void *,
+    double, double, double, double);
+
+/* evaluates to true if expr is of type curl_debug_callback or "similar" */
+#define _curl_is_debug_cb(expr)                                         \
+  (_curl_is_NULL(expr) ||                                                     \
+   _curl_callback_compatible((expr), curl_debug_callback) ||                  \
+   _curl_callback_compatible((expr), _curl_debug_callback1) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback2) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback3) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback4) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback5) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback6) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback7) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback8))
+typedef int (*_curl_debug_callback1) (CURL *,
+    curl_infotype, char *, size_t, void *);
+typedef int (*_curl_debug_callback2) (CURL *,
+    curl_infotype, char *, size_t, const void *);
+typedef int (*_curl_debug_callback3) (CURL *,
+    curl_infotype, const char *, size_t, void *);
+typedef int (*_curl_debug_callback4) (CURL *,
+    curl_infotype, const char *, size_t, const void *);
+typedef int (*_curl_debug_callback5) (CURL *,
+    curl_infotype, unsigned char *, size_t, void *);
+typedef int (*_curl_debug_callback6) (CURL *,
+    curl_infotype, unsigned char *, size_t, const void *);
+typedef int (*_curl_debug_callback7) (CURL *,
+    curl_infotype, const unsigned char *, size_t, void *);
+typedef int (*_curl_debug_callback8) (CURL *,
+    curl_infotype, const unsigned char *, size_t, const void *);
+
+/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
+/* this is getting even messier... */
+#define _curl_is_ssl_ctx_cb(expr)                                       \
+  (_curl_is_NULL(expr) ||                                                     \
+   _curl_callback_compatible((expr), curl_ssl_ctx_callback) ||                \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback8))
+typedef CURLcode (*_curl_ssl_ctx_callback1)(CURL *, void *, void *);
+typedef CURLcode (*_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
+typedef CURLcode (*_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
+typedef CURLcode (*_curl_ssl_ctx_callback4)(CURL *, const void *,
+                                            const void *);
+#ifdef HEADER_SSL_H
+/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX
+ * this will of course break if we're included before OpenSSL headers...
+ */
+typedef CURLcode (*_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *);
+typedef CURLcode (*_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *);
+typedef CURLcode (*_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *);
+typedef CURLcode (*_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX,
+                                           const void *);
+#else
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8;
+#endif
+
+/* evaluates to true if expr is of type curl_conv_callback or "similar" */
+#define _curl_is_conv_cb(expr)                                          \
+  (_curl_is_NULL(expr) ||                                                     \
+   _curl_callback_compatible((expr), curl_conv_callback) ||                   \
+   _curl_callback_compatible((expr), _curl_conv_callback1) ||                 \
+   _curl_callback_compatible((expr), _curl_conv_callback2) ||                 \
+   _curl_callback_compatible((expr), _curl_conv_callback3) ||                 \
+   _curl_callback_compatible((expr), _curl_conv_callback4))
+typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
+typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
+typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
+typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
+
+/* evaluates to true if expr is of type curl_seek_callback or "similar" */
+#define _curl_is_seek_cb(expr)                                          \
+  (_curl_is_NULL(expr) ||                                                     \
+   _curl_callback_compatible((expr), curl_seek_callback) ||                   \
+   _curl_callback_compatible((expr), _curl_seek_callback1) ||                 \
+   _curl_callback_compatible((expr), _curl_seek_callback2))
+typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
+typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
+
+
+#endif /* __CURL_TYPECHECK_GCC_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/amigaos.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/amigaos.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/amigaos.c	(revision 331)
@@ -0,0 +1,77 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(__AMIGA__) && !defined(__ixemul__)
+
+#include <amitcp/socketbasetags.h>
+
+#include "amigaos.h"
+
+struct Library *SocketBase = NULL;
+extern int errno, h_errno;
+
+#ifdef __libnix__
+#include <stabs.h>
+void __request(const char *msg);
+#else
+# define __request(msg)       Printf(msg "\n\a")
+#endif
+
+void Curl_amiga_cleanup()
+{
+  if(SocketBase) {
+    CloseLibrary(SocketBase);
+    SocketBase = NULL;
+  }
+}
+
+bool Curl_amiga_init()
+{
+  if(!SocketBase)
+    SocketBase = OpenLibrary("bsdsocket.library", 4);
+
+  if(!SocketBase) {
+    __request("No TCP/IP Stack running!");
+    return FALSE;
+  }
+
+  if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno,
+                    SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "curl",
+                    TAG_DONE)) {
+    __request("SocketBaseTags ERROR");
+    return FALSE;
+  }
+
+#ifndef __libnix__
+  atexit(Curl_amiga_cleanup);
+#endif
+
+  return TRUE;
+}
+
+#ifdef __libnix__
+ADD2EXIT(Curl_amiga_cleanup, -50);
+#endif
+
+#endif /* __AMIGA__ && ! __ixemul__ */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/amigaos.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/amigaos.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/amigaos.h	(revision 331)
@@ -0,0 +1,39 @@
+#ifndef HEADER_CURL_AMIGAOS_H
+#define HEADER_CURL_AMIGAOS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if defined(__AMIGA__) && !defined(__ixemul__)
+
+bool Curl_amiga_init();
+void Curl_amiga_cleanup();
+
+#else
+
+#define Curl_amiga_init() 1
+#define Curl_amiga_cleanup() Curl_nop_stmt
+
+#endif
+
+#endif /* HEADER_CURL_AMIGAOS_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/arpa_telnet.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/arpa_telnet.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/arpa_telnet.h	(revision 331)
@@ -0,0 +1,104 @@
+#ifndef HEADER_CURL_ARPA_TELNET_H
+#define HEADER_CURL_ARPA_TELNET_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifndef CURL_DISABLE_TELNET
+/*
+ * Telnet option defines. Add more here if in need.
+ */
+#define CURL_TELOPT_BINARY   0  /* binary 8bit data */
+#define CURL_TELOPT_ECHO     1  /* just echo! */
+#define CURL_TELOPT_SGA      3  /* Suppress Go Ahead */
+#define CURL_TELOPT_EXOPL  255  /* EXtended OPtions List */
+#define CURL_TELOPT_TTYPE   24  /* Terminal TYPE */
+#define CURL_TELOPT_NAWS    31  /* Negotiate About Window Size */
+#define CURL_TELOPT_XDISPLOC 35 /* X DISPlay LOCation */
+
+#define CURL_TELOPT_NEW_ENVIRON 39  /* NEW ENVIRONment variables */
+#define CURL_NEW_ENV_VAR   0
+#define CURL_NEW_ENV_VALUE 1
+
+/*
+ * The telnet options represented as strings
+ */
+static const char * const telnetoptions[]=
+{
+  "BINARY",      "ECHO",           "RCP",           "SUPPRESS GO AHEAD",
+  "NAME",        "STATUS",         "TIMING MARK",   "RCTE",
+  "NAOL",        "NAOP",           "NAOCRD",        "NAOHTS",
+  "NAOHTD",      "NAOFFD",         "NAOVTS",        "NAOVTD",
+  "NAOLFD",      "EXTEND ASCII",   "LOGOUT",        "BYTE MACRO",
+  "DE TERMINAL", "SUPDUP",         "SUPDUP OUTPUT", "SEND LOCATION",
+  "TERM TYPE",   "END OF RECORD",  "TACACS UID",    "OUTPUT MARKING",
+  "TTYLOC",      "3270 REGIME",    "X3 PAD",        "NAWS",
+  "TERM SPEED",  "LFLOW",          "LINEMODE",      "XDISPLOC",
+  "OLD-ENVIRON", "AUTHENTICATION", "ENCRYPT",       "NEW-ENVIRON"
+};
+
+#define CURL_TELOPT_MAXIMUM CURL_TELOPT_NEW_ENVIRON
+
+#define CURL_TELOPT_OK(x) ((x) <= CURL_TELOPT_MAXIMUM)
+#define CURL_TELOPT(x)    telnetoptions[x]
+
+#define CURL_NTELOPTS 40
+
+/*
+ * First some defines
+ */
+#define CURL_xEOF 236 /* End Of File */
+#define CURL_SE   240 /* Sub negotiation End */
+#define CURL_NOP  241 /* No OPeration */
+#define CURL_DM   242 /* Data Mark */
+#define CURL_GA   249 /* Go Ahead, reverse the line */
+#define CURL_SB   250 /* SuBnegotiation */
+#define CURL_WILL 251 /* Our side WILL use this option */
+#define CURL_WONT 252 /* Our side WON'T use this option */
+#define CURL_DO   253 /* DO use this option! */
+#define CURL_DONT 254 /* DON'T use this option! */
+#define CURL_IAC  255 /* Interpret As Command */
+
+/*
+ * Then those numbers represented as strings:
+ */
+static const char * const telnetcmds[]=
+{
+  "EOF",  "SUSP",  "ABORT", "EOR",  "SE",
+  "NOP",  "DMARK", "BRK",   "IP",   "AO",
+  "AYT",  "EC",    "EL",    "GA",   "SB",
+  "WILL", "WONT",  "DO",    "DONT", "IAC"
+};
+
+#define CURL_TELCMD_MINIMUM CURL_xEOF /* the first one */
+#define CURL_TELCMD_MAXIMUM CURL_IAC  /* surprise, 255 is the last one! ;-) */
+
+#define CURL_TELQUAL_IS   0
+#define CURL_TELQUAL_SEND 1
+#define CURL_TELQUAL_INFO 2
+#define CURL_TELQUAL_NAME 3
+
+#define CURL_TELCMD_OK(x) ( ((unsigned int)(x) >= CURL_TELCMD_MINIMUM) && \
+                       ((unsigned int)(x) <= CURL_TELCMD_MAXIMUM) )
+#define CURL_TELCMD(x)    telnetcmds[(x)-CURL_TELCMD_MINIMUM]
+
+#endif /* CURL_DISABLE_TELNET */
+
+#endif /* HEADER_CURL_ARPA_TELNET_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/asyn-ares.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/asyn-ares.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/asyn-ares.c	(revision 331)
@@ -0,0 +1,700 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+/***********************************************************************
+ * Only for ares-enabled builds
+ * And only for functions that fulfill the asynch resolver backend API
+ * as defined in asyn.h, nothing else belongs in this file!
+ **********************************************************************/
+
+#ifdef CURLRES_ARES
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "multiif.h"
+#include "inet_pton.h"
+#include "connect.h"
+#include "select.h"
+#include "progress.h"
+
+#  if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
+     (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
+#    define CARES_STATICLIB
+#  endif
+#  include <ares.h>
+#  include <ares_version.h> /* really old c-ares didn't include this by
+                               itself */
+
+#if ARES_VERSION >= 0x010500
+/* c-ares 1.5.0 or later, the callback proto is modified */
+#define HAVE_CARES_CALLBACK_TIMEOUTS 1
+#endif
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+struct ResolverResults {
+  int num_pending; /* number of ares_gethostbyname() requests */
+  Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares parts */
+  int last_status;
+};
+
+/*
+ * Curl_resolver_global_init() - the generic low-level asynchronous name
+ * resolve API.  Called from curl_global_init() to initialize global resolver
+ * environment.  Initializes ares library.
+ */
+int Curl_resolver_global_init(void)
+{
+#ifdef CARES_HAVE_ARES_LIBRARY_INIT
+  if(ares_library_init(ARES_LIB_INIT_ALL)) {
+    return CURLE_FAILED_INIT;
+  }
+#endif
+  return CURLE_OK;
+}
+
+/*
+ * Curl_resolver_global_cleanup()
+ *
+ * Called from curl_global_cleanup() to destroy global resolver environment.
+ * Deinitializes ares library.
+ */
+void Curl_resolver_global_cleanup(void)
+{
+#ifdef CARES_HAVE_ARES_LIBRARY_CLEANUP
+  ares_library_cleanup();
+#endif
+}
+
+/*
+ * Curl_resolver_init()
+ *
+ * Called from curl_easy_init() -> Curl_open() to initialize resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure).  Fills the passed pointer by the initialized ares_channel.
+ */
+CURLcode Curl_resolver_init(void **resolver)
+{
+  int status = ares_init((ares_channel*)resolver);
+  if(status != ARES_SUCCESS) {
+    if(status == ARES_ENOMEM)
+      return CURLE_OUT_OF_MEMORY;
+    else
+      return CURLE_FAILED_INIT;
+  }
+  return CURLE_OK;
+  /* make sure that all other returns from this function should destroy the
+     ares channel before returning error! */
+}
+
+/*
+ * Curl_resolver_cleanup()
+ *
+ * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure).  Destroys the ares channel.
+ */
+void Curl_resolver_cleanup(void *resolver)
+{
+  ares_destroy((ares_channel)resolver);
+}
+
+/*
+ * Curl_resolver_duphandle()
+ *
+ * Called from curl_easy_duphandle() to duplicate resolver URL-state specific
+ * environment ('resolver' member of the UrlState structure).  Duplicates the
+ * 'from' ares channel and passes the resulting channel to the 'to' pointer.
+ */
+int Curl_resolver_duphandle(void **to, void *from)
+{
+  /* Clone the ares channel for the new handle */
+  if(ARES_SUCCESS != ares_dup((ares_channel*)to, (ares_channel)from))
+    return CURLE_FAILED_INIT;
+  return CURLE_OK;
+}
+
+static void destroy_async_data(struct Curl_async *async);
+
+/*
+ * Cancel all possibly still on-going resolves for this connection.
+ */
+void Curl_resolver_cancel(struct connectdata *conn)
+{
+  if(conn->data && conn->data->state.resolver)
+    ares_cancel((ares_channel)conn->data->state.resolver);
+  destroy_async_data(&conn->async);
+}
+
+/*
+ * destroy_async_data() cleans up async resolver data.
+ */
+static void destroy_async_data(struct Curl_async *async)
+{
+  free(async->hostname);
+
+  if(async->os_specific) {
+    struct ResolverResults *res = (struct ResolverResults *)async->os_specific;
+    if(res) {
+      if(res->temp_ai) {
+        Curl_freeaddrinfo(res->temp_ai);
+        res->temp_ai = NULL;
+      }
+      free(res);
+    }
+    async->os_specific = NULL;
+  }
+
+  async->hostname = NULL;
+}
+
+/*
+ * Curl_resolver_getsock() is called when someone from the outside world
+ * (using curl_multi_fdset()) wants to get our fd_set setup and we're talking
+ * with ares. The caller must make sure that this function is only called when
+ * we have a working ares channel.
+ *
+ * Returns: sockets-in-use-bitmap
+ */
+
+int Curl_resolver_getsock(struct connectdata *conn,
+                          curl_socket_t *socks,
+                          int numsocks)
+
+{
+  struct timeval maxtime;
+  struct timeval timebuf;
+  struct timeval *timeout;
+  long milli;
+  int max = ares_getsock((ares_channel)conn->data->state.resolver,
+                         (ares_socket_t *)socks, numsocks);
+
+  maxtime.tv_sec = CURL_TIMEOUT_RESOLVE;
+  maxtime.tv_usec = 0;
+
+  timeout = ares_timeout((ares_channel)conn->data->state.resolver, &maxtime,
+                         &timebuf);
+  milli = (timeout->tv_sec * 1000) + (timeout->tv_usec/1000);
+  if(milli == 0)
+    milli += 10;
+  Curl_expire(conn->data, milli, EXPIRE_ASYNC_NAME);
+
+  return max;
+}
+
+/*
+ * waitperform()
+ *
+ * 1) Ask ares what sockets it currently plays with, then
+ * 2) wait for the timeout period to check for action on ares' sockets.
+ * 3) tell ares to act on all the sockets marked as "with action"
+ *
+ * return number of sockets it worked on
+ */
+
+static int waitperform(struct connectdata *conn, int timeout_ms)
+{
+  struct Curl_easy *data = conn->data;
+  int nfds;
+  int bitmask;
+  ares_socket_t socks[ARES_GETSOCK_MAXNUM];
+  struct pollfd pfd[ARES_GETSOCK_MAXNUM];
+  int i;
+  int num = 0;
+
+  bitmask = ares_getsock((ares_channel)data->state.resolver, socks,
+                         ARES_GETSOCK_MAXNUM);
+
+  for(i = 0; i < ARES_GETSOCK_MAXNUM; i++) {
+    pfd[i].events = 0;
+    pfd[i].revents = 0;
+    if(ARES_GETSOCK_READABLE(bitmask, i)) {
+      pfd[i].fd = socks[i];
+      pfd[i].events |= POLLRDNORM|POLLIN;
+    }
+    if(ARES_GETSOCK_WRITABLE(bitmask, i)) {
+      pfd[i].fd = socks[i];
+      pfd[i].events |= POLLWRNORM|POLLOUT;
+    }
+    if(pfd[i].events != 0)
+      num++;
+    else
+      break;
+  }
+
+  if(num)
+    nfds = Curl_poll(pfd, num, timeout_ms);
+  else
+    nfds = 0;
+
+  if(!nfds)
+    /* Call ares_process() unconditonally here, even if we simply timed out
+       above, as otherwise the ares name resolve won't timeout! */
+    ares_process_fd((ares_channel)data->state.resolver, ARES_SOCKET_BAD,
+                    ARES_SOCKET_BAD);
+  else {
+    /* move through the descriptors and ask for processing on them */
+    for(i = 0; i < num; i++)
+      ares_process_fd((ares_channel)data->state.resolver,
+                      pfd[i].revents & (POLLRDNORM|POLLIN)?
+                      pfd[i].fd:ARES_SOCKET_BAD,
+                      pfd[i].revents & (POLLWRNORM|POLLOUT)?
+                      pfd[i].fd:ARES_SOCKET_BAD);
+  }
+  return nfds;
+}
+
+/*
+ * Curl_resolver_is_resolved() is called repeatedly to check if a previous
+ * name resolve request has completed. It should also make sure to time-out if
+ * the operation seems to take too long.
+ *
+ * Returns normal CURLcode errors.
+ */
+CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
+                                   struct Curl_dns_entry **dns)
+{
+  struct Curl_easy *data = conn->data;
+  struct ResolverResults *res = (struct ResolverResults *)
+    conn->async.os_specific;
+  CURLcode result = CURLE_OK;
+
+  *dns = NULL;
+
+  waitperform(conn, 0);
+
+  if(res && !res->num_pending) {
+    (void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai);
+    /* temp_ai ownership is moved to the connection, so we need not free-up
+       them */
+    res->temp_ai = NULL;
+    if(!conn->async.dns) {
+      failf(data, "Could not resolve: %s (%s)",
+            conn->async.hostname, ares_strerror(conn->async.status));
+      result = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY:
+        CURLE_COULDNT_RESOLVE_HOST;
+    }
+    else
+      *dns = conn->async.dns;
+
+    destroy_async_data(&conn->async);
+  }
+
+  return result;
+}
+
+/*
+ * Curl_resolver_wait_resolv()
+ *
+ * waits for a resolve to finish. This function should be avoided since using
+ * this risk getting the multi interface to "hang".
+ *
+ * If 'entry' is non-NULL, make it point to the resolved dns entry
+ *
+ * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and
+ * CURLE_OPERATION_TIMEDOUT if a time-out occurred.
+ */
+CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
+                                   struct Curl_dns_entry **entry)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  timediff_t timeout;
+  struct curltime now = Curl_now();
+  struct Curl_dns_entry *temp_entry;
+
+  if(entry)
+    *entry = NULL; /* clear on entry */
+
+  timeout = Curl_timeleft(data, &now, TRUE);
+  if(timeout < 0) {
+    /* already expired! */
+    connclose(conn, "Timed out before name resolve started");
+    return CURLE_OPERATION_TIMEDOUT;
+  }
+  if(!timeout)
+    timeout = CURL_TIMEOUT_RESOLVE * 1000; /* default name resolve timeout */
+
+  /* Wait for the name resolve query to complete. */
+  while(!result) {
+    struct timeval *tvp, tv, store;
+    int itimeout;
+    int timeout_ms;
+
+    itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout;
+
+    store.tv_sec = itimeout/1000;
+    store.tv_usec = (itimeout%1000)*1000;
+
+    tvp = ares_timeout((ares_channel)data->state.resolver, &store, &tv);
+
+    /* use the timeout period ares returned to us above if less than one
+       second is left, otherwise just use 1000ms to make sure the progress
+       callback gets called frequent enough */
+    if(!tvp->tv_sec)
+      timeout_ms = (int)(tvp->tv_usec/1000);
+    else
+      timeout_ms = 1000;
+
+    waitperform(conn, timeout_ms);
+    result = Curl_resolver_is_resolved(conn, &temp_entry);
+
+    if(result || conn->async.done)
+      break;
+
+    if(Curl_pgrsUpdate(conn))
+      result = CURLE_ABORTED_BY_CALLBACK;
+    else {
+      struct curltime now2 = Curl_now();
+      timediff_t timediff = Curl_timediff(now2, now); /* spent time */
+      if(timediff <= 0)
+        timeout -= 1; /* always deduct at least 1 */
+      else if(timediff > timeout)
+        timeout = -1;
+      else
+        timeout -= (long)timediff;
+      now = now2; /* for next loop */
+    }
+    if(timeout < 0)
+      result = CURLE_OPERATION_TIMEDOUT;
+  }
+  if(result)
+    /* failure, so we cancel the ares operation */
+    ares_cancel((ares_channel)data->state.resolver);
+
+  /* Operation complete, if the lookup was successful we now have the entry
+     in the cache. */
+  if(entry)
+    *entry = conn->async.dns;
+
+  if(result)
+    /* close the connection, since we can't return failure here without
+       cleaning up this connection properly.
+       TODO: remove this action from here, it is not a name resolver decision.
+    */
+    connclose(conn, "c-ares resolve failed");
+
+  return result;
+}
+
+/* Connects results to the list */
+static void compound_results(struct ResolverResults *res,
+                             Curl_addrinfo *ai)
+{
+  Curl_addrinfo *ai_tail;
+  if(!ai)
+    return;
+  ai_tail = ai;
+
+  while(ai_tail->ai_next)
+    ai_tail = ai_tail->ai_next;
+
+  /* Add the new results to the list of old results. */
+  ai_tail->ai_next = res->temp_ai;
+  res->temp_ai = ai;
+}
+
+/*
+ * ares_query_completed_cb() is the callback that ares will call when
+ * the host query initiated by ares_gethostbyname() from Curl_getaddrinfo(),
+ * when using ares, is completed either successfully or with failure.
+ */
+static void query_completed_cb(void *arg,  /* (struct connectdata *) */
+                               int status,
+#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
+                               int timeouts,
+#endif
+                               struct hostent *hostent)
+{
+  struct connectdata *conn = (struct connectdata *)arg;
+  struct ResolverResults *res;
+
+#ifdef HAVE_CARES_CALLBACK_TIMEOUTS
+  (void)timeouts; /* ignored */
+#endif
+
+  if(ARES_EDESTRUCTION == status)
+    /* when this ares handle is getting destroyed, the 'arg' pointer may not
+       be valid so only defer it when we know the 'status' says its fine! */
+    return;
+
+  res = (struct ResolverResults *)conn->async.os_specific;
+  res->num_pending--;
+
+  if(CURL_ASYNC_SUCCESS == status) {
+    Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port);
+    if(ai) {
+      compound_results(res, ai);
+    }
+  }
+  /* A successful result overwrites any previous error */
+  if(res->last_status != ARES_SUCCESS)
+    res->last_status = status;
+}
+
+/*
+ * Curl_resolver_getaddrinfo() - when using ares
+ *
+ * Returns name information about the given hostname and port number. If
+ * successful, the 'hostent' is returned and the forth argument will point to
+ * memory we need to free after use. That memory *MUST* be freed with
+ * Curl_freeaddrinfo(), nothing else.
+ */
+Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
+                                         const char *hostname,
+                                         int port,
+                                         int *waitp)
+{
+  char *bufp;
+  struct Curl_easy *data = conn->data;
+  struct in_addr in;
+  int family = PF_INET;
+#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
+  struct in6_addr in6;
+#endif /* CURLRES_IPV6 */
+
+  *waitp = 0; /* default to synchronous response */
+
+  /* First check if this is an IPv4 address string */
+  if(Curl_inet_pton(AF_INET, hostname, &in) > 0) {
+    /* This is a dotted IP address 123.123.123.123-style */
+    return Curl_ip2addr(AF_INET, &in, hostname, port);
+  }
+
+#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
+  /* Otherwise, check if this is an IPv6 address string */
+  if(Curl_inet_pton (AF_INET6, hostname, &in6) > 0)
+    /* This must be an IPv6 address literal.  */
+    return Curl_ip2addr(AF_INET6, &in6, hostname, port);
+
+  switch(conn->ip_version) {
+  default:
+#if ARES_VERSION >= 0x010601
+    family = PF_UNSPEC; /* supported by c-ares since 1.6.1, so for older
+                           c-ares versions this just falls through and defaults
+                           to PF_INET */
+    break;
+#endif
+  case CURL_IPRESOLVE_V4:
+    family = PF_INET;
+    break;
+  case CURL_IPRESOLVE_V6:
+    family = PF_INET6;
+    break;
+  }
+#endif /* CURLRES_IPV6 */
+
+  bufp = strdup(hostname);
+  if(bufp) {
+    struct ResolverResults *res = NULL;
+    free(conn->async.hostname);
+    conn->async.hostname = bufp;
+    conn->async.port = port;
+    conn->async.done = FALSE;   /* not done */
+    conn->async.status = 0;     /* clear */
+    conn->async.dns = NULL;     /* clear */
+    res = calloc(sizeof(struct ResolverResults), 1);
+    if(!res) {
+      free(conn->async.hostname);
+      conn->async.hostname = NULL;
+      return NULL;
+    }
+    conn->async.os_specific = res;
+
+    /* initial status - failed */
+    res->last_status = ARES_ENOTFOUND;
+#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */
+    if(family == PF_UNSPEC) {
+      if(Curl_ipv6works()) {
+        res->num_pending = 2;
+
+        /* areschannel is already setup in the Curl_open() function */
+        ares_gethostbyname((ares_channel)data->state.resolver, hostname,
+                            PF_INET, query_completed_cb, conn);
+        ares_gethostbyname((ares_channel)data->state.resolver, hostname,
+                            PF_INET6, query_completed_cb, conn);
+      }
+      else {
+        res->num_pending = 1;
+
+        /* areschannel is already setup in the Curl_open() function */
+        ares_gethostbyname((ares_channel)data->state.resolver, hostname,
+                            PF_INET, query_completed_cb, conn);
+      }
+    }
+    else
+#endif /* CURLRES_IPV6 */
+    {
+      res->num_pending = 1;
+
+      /* areschannel is already setup in the Curl_open() function */
+      ares_gethostbyname((ares_channel)data->state.resolver, hostname, family,
+                         query_completed_cb, conn);
+    }
+
+    *waitp = 1; /* expect asynchronous response */
+  }
+  return NULL; /* no struct yet */
+}
+
+CURLcode Curl_set_dns_servers(struct Curl_easy *data,
+                              char *servers)
+{
+  CURLcode result = CURLE_NOT_BUILT_IN;
+  int ares_result;
+
+  /* If server is NULL or empty, this would purge all DNS servers
+   * from ares library, which will cause any and all queries to fail.
+   * So, just return OK if none are configured and don't actually make
+   * any changes to c-ares.  This lets c-ares use it's defaults, which
+   * it gets from the OS (for instance from /etc/resolv.conf on Linux).
+   */
+  if(!(servers && servers[0]))
+    return CURLE_OK;
+
+#if (ARES_VERSION >= 0x010704)
+  ares_result = ares_set_servers_csv(data->state.resolver, servers);
+  switch(ares_result) {
+  case ARES_SUCCESS:
+    result = CURLE_OK;
+    break;
+  case ARES_ENOMEM:
+    result = CURLE_OUT_OF_MEMORY;
+    break;
+  case ARES_ENOTINITIALIZED:
+  case ARES_ENODATA:
+  case ARES_EBADSTR:
+  default:
+    result = CURLE_BAD_FUNCTION_ARGUMENT;
+    break;
+  }
+#else /* too old c-ares version! */
+  (void)data;
+  (void)(ares_result);
+#endif
+  return result;
+}
+
+CURLcode Curl_set_dns_interface(struct Curl_easy *data,
+                                const char *interf)
+{
+#if (ARES_VERSION >= 0x010704)
+  if(!interf)
+    interf = "";
+
+  ares_set_local_dev((ares_channel)data->state.resolver, interf);
+
+  return CURLE_OK;
+#else /* c-ares version too old! */
+  (void)data;
+  (void)interf;
+  return CURLE_NOT_BUILT_IN;
+#endif
+}
+
+CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data,
+                                const char *local_ip4)
+{
+#if (ARES_VERSION >= 0x010704)
+  struct in_addr a4;
+
+  if((!local_ip4) || (local_ip4[0] == 0)) {
+    a4.s_addr = 0; /* disabled: do not bind to a specific address */
+  }
+  else {
+    if(Curl_inet_pton(AF_INET, local_ip4, &a4) != 1) {
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    }
+  }
+
+  ares_set_local_ip4((ares_channel)data->state.resolver, ntohl(a4.s_addr));
+
+  return CURLE_OK;
+#else /* c-ares version too old! */
+  (void)data;
+  (void)local_ip4;
+  return CURLE_NOT_BUILT_IN;
+#endif
+}
+
+CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data,
+                                const char *local_ip6)
+{
+#if (ARES_VERSION >= 0x010704) && defined(ENABLE_IPV6)
+  unsigned char a6[INET6_ADDRSTRLEN];
+
+  if((!local_ip6) || (local_ip6[0] == 0)) {
+    /* disabled: do not bind to a specific address */
+    memset(a6, 0, sizeof(a6));
+  }
+  else {
+    if(Curl_inet_pton(AF_INET6, local_ip6, a6) != 1) {
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    }
+  }
+
+  ares_set_local_ip6((ares_channel)data->state.resolver, a6);
+
+  return CURLE_OK;
+#else /* c-ares version too old! */
+  (void)data;
+  (void)local_ip6;
+  return CURLE_NOT_BUILT_IN;
+#endif
+}
+#endif /* CURLRES_ARES */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/asyn-thread.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/asyn-thread.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/asyn-thread.c	(revision 331)
@@ -0,0 +1,719 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+/***********************************************************************
+ * Only for threaded name resolves builds
+ **********************************************************************/
+#ifdef CURLRES_THREADED
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if defined(USE_THREADS_POSIX)
+#  ifdef HAVE_PTHREAD_H
+#    include <pthread.h>
+#  endif
+#elif defined(USE_THREADS_WIN32)
+#  ifdef HAVE_PROCESS_H
+#    include <process.h>
+#  endif
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#ifdef HAVE_GETADDRINFO
+#  define RESOLVER_ENOMEM  EAI_MEMORY
+#else
+#  define RESOLVER_ENOMEM  ENOMEM
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "multiif.h"
+#include "inet_pton.h"
+#include "inet_ntop.h"
+#include "curl_threads.h"
+#include "connect.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * Curl_resolver_global_init()
+ * Called from curl_global_init() to initialize global resolver environment.
+ * Does nothing here.
+ */
+int Curl_resolver_global_init(void)
+{
+  return CURLE_OK;
+}
+
+/*
+ * Curl_resolver_global_cleanup()
+ * Called from curl_global_cleanup() to destroy global resolver environment.
+ * Does nothing here.
+ */
+void Curl_resolver_global_cleanup(void)
+{
+}
+
+/*
+ * Curl_resolver_init()
+ * Called from curl_easy_init() -> Curl_open() to initialize resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure).  Does nothing here.
+ */
+CURLcode Curl_resolver_init(void **resolver)
+{
+  (void)resolver;
+  return CURLE_OK;
+}
+
+/*
+ * Curl_resolver_cleanup()
+ * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure).  Does nothing here.
+ */
+void Curl_resolver_cleanup(void *resolver)
+{
+  (void)resolver;
+}
+
+/*
+ * Curl_resolver_duphandle()
+ * Called from curl_easy_duphandle() to duplicate resolver URL state-specific
+ * environment ('resolver' member of the UrlState structure).  Does nothing
+ * here.
+ */
+int Curl_resolver_duphandle(void **to, void *from)
+{
+  (void)to;
+  (void)from;
+  return CURLE_OK;
+}
+
+static void destroy_async_data(struct Curl_async *);
+
+/*
+ * Cancel all possibly still on-going resolves for this connection.
+ */
+void Curl_resolver_cancel(struct connectdata *conn)
+{
+  destroy_async_data(&conn->async);
+}
+
+/* This function is used to init a threaded resolve */
+static bool init_resolve_thread(struct connectdata *conn,
+                                const char *hostname, int port,
+                                const struct addrinfo *hints);
+
+
+/* Data for synchronization between resolver thread and its parent */
+struct thread_sync_data {
+  curl_mutex_t * mtx;
+  int done;
+
+  char *hostname;        /* hostname to resolve, Curl_async.hostname
+                            duplicate */
+  int port;
+  int sock_error;
+  Curl_addrinfo *res;
+#ifdef HAVE_GETADDRINFO
+  struct addrinfo hints;
+#endif
+  struct thread_data *td; /* for thread-self cleanup */
+};
+
+struct thread_data {
+  curl_thread_t thread_hnd;
+  unsigned int poll_interval;
+  time_t interval_end;
+  struct thread_sync_data tsd;
+};
+
+static struct thread_sync_data *conn_thread_sync_data(struct connectdata *conn)
+{
+  return &(((struct thread_data *)conn->async.os_specific)->tsd);
+}
+
+#define CONN_THREAD_SYNC_DATA(conn) &(((conn)->async.os_specific)->tsd);
+
+/* Destroy resolver thread synchronization data */
+static
+void destroy_thread_sync_data(struct thread_sync_data * tsd)
+{
+  if(tsd->mtx) {
+    Curl_mutex_destroy(tsd->mtx);
+    free(tsd->mtx);
+  }
+
+  free(tsd->hostname);
+
+  if(tsd->res)
+    Curl_freeaddrinfo(tsd->res);
+
+  memset(tsd, 0, sizeof(*tsd));
+}
+
+/* Initialize resolver thread synchronization data */
+static
+int init_thread_sync_data(struct thread_data * td,
+                           const char *hostname,
+                           int port,
+                           const struct addrinfo *hints)
+{
+  struct thread_sync_data *tsd = &td->tsd;
+
+  memset(tsd, 0, sizeof(*tsd));
+
+  tsd->td = td;
+  tsd->port = port;
+  /* Treat the request as done until the thread actually starts so any early
+   * cleanup gets done properly.
+   */
+  tsd->done = 1;
+#ifdef HAVE_GETADDRINFO
+  DEBUGASSERT(hints);
+  tsd->hints = *hints;
+#else
+  (void) hints;
+#endif
+
+  tsd->mtx = malloc(sizeof(curl_mutex_t));
+  if(tsd->mtx == NULL)
+    goto err_exit;
+
+  Curl_mutex_init(tsd->mtx);
+
+  tsd->sock_error = CURL_ASYNC_SUCCESS;
+
+  /* Copying hostname string because original can be destroyed by parent
+   * thread during gethostbyname execution.
+   */
+  tsd->hostname = strdup(hostname);
+  if(!tsd->hostname)
+    goto err_exit;
+
+  return 1;
+
+ err_exit:
+  /* Memory allocation failed */
+  destroy_thread_sync_data(tsd);
+  return 0;
+}
+
+static int getaddrinfo_complete(struct connectdata *conn)
+{
+  struct thread_sync_data *tsd = conn_thread_sync_data(conn);
+  int rc;
+
+  rc = Curl_addrinfo_callback(conn, tsd->sock_error, tsd->res);
+  /* The tsd->res structure has been copied to async.dns and perhaps the DNS
+     cache.  Set our copy to NULL so destroy_thread_sync_data doesn't free it.
+  */
+  tsd->res = NULL;
+
+  return rc;
+}
+
+
+#ifdef HAVE_GETADDRINFO
+
+/*
+ * getaddrinfo_thread() resolves a name and then exits.
+ *
+ * For builds without ARES, but with ENABLE_IPV6, create a resolver thread
+ * and wait on it.
+ */
+static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
+{
+  struct thread_sync_data *tsd = (struct thread_sync_data*)arg;
+  struct thread_data *td = tsd->td;
+  char service[12];
+  int rc;
+
+  snprintf(service, sizeof(service), "%d", tsd->port);
+
+  rc = Curl_getaddrinfo_ex(tsd->hostname, service, &tsd->hints, &tsd->res);
+
+  if(rc != 0) {
+    tsd->sock_error = SOCKERRNO?SOCKERRNO:rc;
+    if(tsd->sock_error == 0)
+      tsd->sock_error = RESOLVER_ENOMEM;
+  }
+  else {
+    Curl_addrinfo_set_port(tsd->res, tsd->port);
+  }
+
+  Curl_mutex_acquire(tsd->mtx);
+  if(tsd->done) {
+    /* too late, gotta clean up the mess */
+    Curl_mutex_release(tsd->mtx);
+    destroy_thread_sync_data(tsd);
+    free(td);
+  }
+  else {
+    tsd->done = 1;
+    Curl_mutex_release(tsd->mtx);
+  }
+
+  return 0;
+}
+
+#else /* HAVE_GETADDRINFO */
+
+/*
+ * gethostbyname_thread() resolves a name and then exits.
+ */
+static unsigned int CURL_STDCALL gethostbyname_thread(void *arg)
+{
+  struct thread_sync_data *tsd = (struct thread_sync_data *)arg;
+  struct thread_data *td = tsd->td;
+
+  tsd->res = Curl_ipv4_resolve_r(tsd->hostname, tsd->port);
+
+  if(!tsd->res) {
+    tsd->sock_error = SOCKERRNO;
+    if(tsd->sock_error == 0)
+      tsd->sock_error = RESOLVER_ENOMEM;
+  }
+
+  Curl_mutex_acquire(tsd->mtx);
+  if(tsd->done) {
+    /* too late, gotta clean up the mess */
+    Curl_mutex_release(tsd->mtx);
+    destroy_thread_sync_data(tsd);
+    free(td);
+  }
+  else {
+    tsd->done = 1;
+    Curl_mutex_release(tsd->mtx);
+  }
+
+  return 0;
+}
+
+#endif /* HAVE_GETADDRINFO */
+
+/*
+ * destroy_async_data() cleans up async resolver data and thread handle.
+ */
+static void destroy_async_data(struct Curl_async *async)
+{
+  if(async->os_specific) {
+    struct thread_data *td = (struct thread_data*) async->os_specific;
+    int done;
+
+    /*
+     * if the thread is still blocking in the resolve syscall, detach it and
+     * let the thread do the cleanup...
+     */
+    Curl_mutex_acquire(td->tsd.mtx);
+    done = td->tsd.done;
+    td->tsd.done = 1;
+    Curl_mutex_release(td->tsd.mtx);
+
+    if(!done) {
+      Curl_thread_destroy(td->thread_hnd);
+    }
+    else {
+      if(td->thread_hnd != curl_thread_t_null)
+        Curl_thread_join(&td->thread_hnd);
+
+      destroy_thread_sync_data(&td->tsd);
+
+      free(async->os_specific);
+    }
+  }
+  async->os_specific = NULL;
+
+  free(async->hostname);
+  async->hostname = NULL;
+}
+
+/*
+ * init_resolve_thread() starts a new thread that performs the actual
+ * resolve. This function returns before the resolve is done.
+ *
+ * Returns FALSE in case of failure, otherwise TRUE.
+ */
+static bool init_resolve_thread(struct connectdata *conn,
+                                const char *hostname, int port,
+                                const struct addrinfo *hints)
+{
+  struct thread_data *td = calloc(1, sizeof(struct thread_data));
+  int err = ENOMEM;
+
+  conn->async.os_specific = (void *)td;
+  if(!td)
+    goto errno_exit;
+
+  conn->async.port = port;
+  conn->async.done = FALSE;
+  conn->async.status = 0;
+  conn->async.dns = NULL;
+  td->thread_hnd = curl_thread_t_null;
+
+  if(!init_thread_sync_data(td, hostname, port, hints)) {
+    conn->async.os_specific = NULL;
+    free(td);
+    goto errno_exit;
+  }
+
+  free(conn->async.hostname);
+  conn->async.hostname = strdup(hostname);
+  if(!conn->async.hostname)
+    goto err_exit;
+
+  /* The thread will set this to 1 when complete. */
+  td->tsd.done = 0;
+
+#ifdef HAVE_GETADDRINFO
+  td->thread_hnd = Curl_thread_create(getaddrinfo_thread, &td->tsd);
+#else
+  td->thread_hnd = Curl_thread_create(gethostbyname_thread, &td->tsd);
+#endif
+
+  if(!td->thread_hnd) {
+    /* The thread never started, so mark it as done here for proper cleanup. */
+    td->tsd.done = 1;
+    err = errno;
+    goto err_exit;
+  }
+
+  return TRUE;
+
+ err_exit:
+  destroy_async_data(&conn->async);
+
+ errno_exit:
+  errno = err;
+  return FALSE;
+}
+
+/*
+ * resolver_error() calls failf() with the appropriate message after a resolve
+ * error
+ */
+
+static CURLcode resolver_error(struct connectdata *conn)
+{
+  const char *host_or_proxy;
+  CURLcode result;
+
+  if(conn->bits.httpproxy) {
+    host_or_proxy = "proxy";
+    result = CURLE_COULDNT_RESOLVE_PROXY;
+  }
+  else {
+    host_or_proxy = "host";
+    result = CURLE_COULDNT_RESOLVE_HOST;
+  }
+
+  failf(conn->data, "Could not resolve %s: %s", host_or_proxy,
+        conn->async.hostname);
+
+  return result;
+}
+
+/*
+ * Curl_resolver_wait_resolv()
+ *
+ * waits for a resolve to finish. This function should be avoided since using
+ * this risk getting the multi interface to "hang".
+ *
+ * If 'entry' is non-NULL, make it point to the resolved dns entry
+ *
+ * This is the version for resolves-in-a-thread.
+ */
+CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
+                                   struct Curl_dns_entry **entry)
+{
+  struct thread_data   *td = (struct thread_data*) conn->async.os_specific;
+  CURLcode result = CURLE_OK;
+
+  DEBUGASSERT(conn && td);
+
+  /* wait for the thread to resolve the name */
+  if(Curl_thread_join(&td->thread_hnd))
+    result = getaddrinfo_complete(conn);
+  else
+    DEBUGASSERT(0);
+
+  conn->async.done = TRUE;
+
+  if(entry)
+    *entry = conn->async.dns;
+
+  if(!conn->async.dns)
+    /* a name was not resolved, report error */
+    result = resolver_error(conn);
+
+  destroy_async_data(&conn->async);
+
+  if(!conn->async.dns)
+    connclose(conn, "asynch resolve failed");
+
+  return result;
+}
+
+/*
+ * Curl_resolver_is_resolved() is called repeatedly to check if a previous
+ * name resolve request has completed. It should also make sure to time-out if
+ * the operation seems to take too long.
+ */
+CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
+                                   struct Curl_dns_entry **entry)
+{
+  struct Curl_easy *data = conn->data;
+  struct thread_data   *td = (struct thread_data*) conn->async.os_specific;
+  int done = 0;
+
+  *entry = NULL;
+
+  if(!td) {
+    DEBUGASSERT(td);
+    return CURLE_COULDNT_RESOLVE_HOST;
+  }
+
+  Curl_mutex_acquire(td->tsd.mtx);
+  done = td->tsd.done;
+  Curl_mutex_release(td->tsd.mtx);
+
+  if(done) {
+    getaddrinfo_complete(conn);
+
+    if(!conn->async.dns) {
+      CURLcode result = resolver_error(conn);
+      destroy_async_data(&conn->async);
+      return result;
+    }
+    destroy_async_data(&conn->async);
+    *entry = conn->async.dns;
+  }
+  else {
+    /* poll for name lookup done with exponential backoff up to 250ms */
+    timediff_t elapsed = Curl_timediff(Curl_now(),
+                                       data->progress.t_startsingle);
+    if(elapsed < 0)
+      elapsed = 0;
+
+    if(td->poll_interval == 0)
+      /* Start at 1ms poll interval */
+      td->poll_interval = 1;
+    else if(elapsed >= td->interval_end)
+      /* Back-off exponentially if last interval expired  */
+      td->poll_interval *= 2;
+
+    if(td->poll_interval > 250)
+      td->poll_interval = 250;
+
+    td->interval_end = elapsed + td->poll_interval;
+    Curl_expire(conn->data, td->poll_interval, EXPIRE_ASYNC_NAME);
+  }
+
+  return CURLE_OK;
+}
+
+int Curl_resolver_getsock(struct connectdata *conn,
+                          curl_socket_t *socks,
+                          int numsocks)
+{
+  (void)conn;
+  (void)socks;
+  (void)numsocks;
+  return 0;
+}
+
+#ifndef HAVE_GETADDRINFO
+/*
+ * Curl_getaddrinfo() - for platforms without getaddrinfo
+ */
+Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
+                                         const char *hostname,
+                                         int port,
+                                         int *waitp)
+{
+  struct in_addr in;
+
+  *waitp = 0; /* default to synchronous response */
+
+  if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
+    /* This is a dotted IP address 123.123.123.123-style */
+    return Curl_ip2addr(AF_INET, &in, hostname, port);
+
+  /* fire up a new resolver thread! */
+  if(init_resolve_thread(conn, hostname, port, NULL)) {
+    *waitp = 1; /* expect asynchronous response */
+    return NULL;
+  }
+
+  /* fall-back to blocking version */
+  return Curl_ipv4_resolve_r(hostname, port);
+}
+
+#else /* !HAVE_GETADDRINFO */
+
+/*
+ * Curl_resolver_getaddrinfo() - for getaddrinfo
+ */
+Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
+                                         const char *hostname,
+                                         int port,
+                                         int *waitp)
+{
+  struct addrinfo hints;
+  Curl_addrinfo *res;
+  int error;
+  char sbuf[12];
+  int pf = PF_INET;
+
+  *waitp = 0; /* default to synchronous response */
+
+#ifndef USE_RESOLVE_ON_IPS
+  {
+    struct in_addr in;
+    /* First check if this is an IPv4 address string */
+    if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
+      /* This is a dotted IP address 123.123.123.123-style */
+      return Curl_ip2addr(AF_INET, &in, hostname, port);
+  }
+#ifdef CURLRES_IPV6
+  {
+    struct in6_addr in6;
+    /* check if this is an IPv6 address string */
+    if(Curl_inet_pton(AF_INET6, hostname, &in6) > 0)
+      /* This is an IPv6 address literal */
+      return Curl_ip2addr(AF_INET6, &in6, hostname, port);
+  }
+#endif /* CURLRES_IPV6 */
+#endif /* !USE_RESOLVE_ON_IPS */
+
+#ifdef CURLRES_IPV6
+  /*
+   * Check if a limited name resolve has been requested.
+   */
+  switch(conn->ip_version) {
+  case CURL_IPRESOLVE_V4:
+    pf = PF_INET;
+    break;
+  case CURL_IPRESOLVE_V6:
+    pf = PF_INET6;
+    break;
+  default:
+    pf = PF_UNSPEC;
+    break;
+  }
+
+  if((pf != PF_INET) && !Curl_ipv6works())
+    /* The stack seems to be a non-IPv6 one */
+    pf = PF_INET;
+#endif /* CURLRES_IPV6 */
+
+  memset(&hints, 0, sizeof(hints));
+  hints.ai_family = pf;
+  hints.ai_socktype = conn->socktype;
+
+  snprintf(sbuf, sizeof(sbuf), "%d", port);
+
+  /* fire up a new resolver thread! */
+  if(init_resolve_thread(conn, hostname, port, &hints)) {
+    *waitp = 1; /* expect asynchronous response */
+    return NULL;
+  }
+
+  /* fall-back to blocking version */
+  infof(conn->data, "init_resolve_thread() failed for %s; %s\n",
+        hostname, Curl_strerror(conn, errno));
+
+  error = Curl_getaddrinfo_ex(hostname, sbuf, &hints, &res);
+  if(error) {
+    infof(conn->data, "getaddrinfo() failed for %s:%d; %s\n",
+          hostname, port, Curl_strerror(conn, SOCKERRNO));
+    return NULL;
+  }
+  else {
+    Curl_addrinfo_set_port(res, port);
+  }
+
+  return res;
+}
+
+#endif /* !HAVE_GETADDRINFO */
+
+CURLcode Curl_set_dns_servers(struct Curl_easy *data,
+                              char *servers)
+{
+  (void)data;
+  (void)servers;
+  return CURLE_NOT_BUILT_IN;
+
+}
+
+CURLcode Curl_set_dns_interface(struct Curl_easy *data,
+                                const char *interf)
+{
+  (void)data;
+  (void)interf;
+  return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data,
+                                const char *local_ip4)
+{
+  (void)data;
+  (void)local_ip4;
+  return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data,
+                                const char *local_ip6)
+{
+  (void)data;
+  (void)local_ip6;
+  return CURLE_NOT_BUILT_IN;
+}
+
+#endif /* CURLRES_THREADED */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/asyn.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/asyn.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/asyn.h	(revision 331)
@@ -0,0 +1,168 @@
+#ifndef HEADER_CURL_ASYN_H
+#define HEADER_CURL_ASYN_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "curl_addrinfo.h"
+
+struct addrinfo;
+struct hostent;
+struct Curl_easy;
+struct connectdata;
+struct Curl_dns_entry;
+
+/*
+ * This header defines all functions in the internal asynch resolver interface.
+ * All asynch resolvers need to provide these functions.
+ * asyn-ares.c and asyn-thread.c are the current implementations of asynch
+ * resolver backends.
+ */
+
+/*
+ * Curl_resolver_global_init()
+ *
+ * Called from curl_global_init() to initialize global resolver environment.
+ * Returning anything else than CURLE_OK fails curl_global_init().
+ */
+int Curl_resolver_global_init(void);
+
+/*
+ * Curl_resolver_global_cleanup()
+ * Called from curl_global_cleanup() to destroy global resolver environment.
+ */
+void Curl_resolver_global_cleanup(void);
+
+/*
+ * Curl_resolver_init()
+ * Called from curl_easy_init() -> Curl_open() to initialize resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure).  Should fill the passed pointer by the initialized handler.
+ * Returning anything else than CURLE_OK fails curl_easy_init() with the
+ * correspondent code.
+ */
+CURLcode Curl_resolver_init(void **resolver);
+
+/*
+ * Curl_resolver_cleanup()
+ * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver
+ * URL-state specific environment ('resolver' member of the UrlState
+ * structure).  Should destroy the handler and free all resources connected to
+ * it.
+ */
+void Curl_resolver_cleanup(void *resolver);
+
+/*
+ * Curl_resolver_duphandle()
+ * Called from curl_easy_duphandle() to duplicate resolver URL-state specific
+ * environment ('resolver' member of the UrlState structure).  Should
+ * duplicate the 'from' handle and pass the resulting handle to the 'to'
+ * pointer.  Returning anything else than CURLE_OK causes failed
+ * curl_easy_duphandle() call.
+ */
+int Curl_resolver_duphandle(void **to, void *from);
+
+/*
+ * Curl_resolver_cancel().
+ *
+ * It is called from inside other functions to cancel currently performing
+ * resolver request. Should also free any temporary resources allocated to
+ * perform a request.
+ */
+void Curl_resolver_cancel(struct connectdata *conn);
+
+/* Curl_resolver_getsock()
+ *
+ * This function is called from the multi_getsock() function.  'sock' is a
+ * pointer to an array to hold the file descriptors, with 'numsock' being the
+ * size of that array (in number of entries). This function is supposed to
+ * return bitmask indicating what file descriptors (referring to array indexes
+ * in the 'sock' array) to wait for, read/write.
+ */
+int Curl_resolver_getsock(struct connectdata *conn, curl_socket_t *sock,
+                          int numsocks);
+
+/*
+ * Curl_resolver_is_resolved()
+ *
+ * Called repeatedly to check if a previous name resolve request has
+ * completed. It should also make sure to time-out if the operation seems to
+ * take too long.
+ *
+ * Returns normal CURLcode errors.
+ */
+CURLcode Curl_resolver_is_resolved(struct connectdata *conn,
+                                   struct Curl_dns_entry **dns);
+
+/*
+ * Curl_resolver_wait_resolv()
+ *
+ * waits for a resolve to finish. This function should be avoided since using
+ * this risk getting the multi interface to "hang".
+ *
+ * If 'entry' is non-NULL, make it point to the resolved dns entry
+ *
+ * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and
+ * CURLE_OPERATION_TIMEDOUT if a time-out occurred.
+
+ */
+CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
+                                   struct Curl_dns_entry **dnsentry);
+
+/*
+ * Curl_resolver_getaddrinfo() - when using this resolver
+ *
+ * Returns name information about the given hostname and port number. If
+ * successful, the 'hostent' is returned and the forth argument will point to
+ * memory we need to free after use. That memory *MUST* be freed with
+ * Curl_freeaddrinfo(), nothing else.
+ *
+ * Each resolver backend must of course make sure to return data in the
+ * correct format to comply with this.
+ */
+Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
+                                         const char *hostname,
+                                         int port,
+                                         int *waitp);
+
+#ifndef CURLRES_ASYNCH
+/* convert these functions if an asynch resolver isn't used */
+#define Curl_resolver_cancel(x) Curl_nop_stmt
+#define Curl_resolver_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST
+#define Curl_resolver_wait_resolv(x,y) CURLE_COULDNT_RESOLVE_HOST
+#define Curl_resolver_getsock(x,y,z) 0
+#define Curl_resolver_duphandle(x,y) CURLE_OK
+#define Curl_resolver_init(x) CURLE_OK
+#define Curl_resolver_global_init() CURLE_OK
+#define Curl_resolver_global_cleanup() Curl_nop_stmt
+#define Curl_resolver_cleanup(x) Curl_nop_stmt
+#endif
+
+#ifdef CURLRES_ASYNCH
+#define Curl_resolver_asynch() 1
+#else
+#define Curl_resolver_asynch() 0
+#endif
+
+
+/********** end of generic resolver interface functions *****************/
+#endif /* HEADER_CURL_ASYN_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/base64.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/base64.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/base64.c	(revision 331)
@@ -0,0 +1,320 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* Base64 encoding/decoding */
+
+#include "curl_setup.h"
+#include "urldata.h" /* for the Curl_easy definition */
+#include "warnless.h"
+#include "curl_base64.h"
+#include "non-ascii.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* ---- Base64 Encoding/Decoding Table --- */
+static const char base64[]=
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/* The Base 64 encoding with an URL and filename safe alphabet, RFC 4648
+   section 5 */
+static const char base64url[]=
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
+
+static size_t decodeQuantum(unsigned char *dest, const char *src)
+{
+  size_t padding = 0;
+  const char *s, *p;
+  unsigned long i, x = 0;
+
+  for(i = 0, s = src; i < 4; i++, s++) {
+    unsigned long v = 0;
+
+    if(*s == '=') {
+      x = (x << 6);
+      padding++;
+    }
+    else {
+      p = base64;
+
+      while(*p && (*p != *s)) {
+        v++;
+        p++;
+      }
+
+      if(*p == *s)
+        x = (x << 6) + v;
+      else
+        return 0;
+    }
+  }
+
+  if(padding < 1)
+    dest[2] = curlx_ultouc(x & 0xFFUL);
+
+  x >>= 8;
+  if(padding < 2)
+    dest[1] = curlx_ultouc(x & 0xFFUL);
+
+  x >>= 8;
+  dest[0] = curlx_ultouc(x & 0xFFUL);
+
+  return 3 - padding;
+}
+
+/*
+ * Curl_base64_decode()
+ *
+ * Given a base64 NUL-terminated string at src, decode it and return a
+ * pointer in *outptr to a newly allocated memory area holding decoded
+ * data. Size of decoded data is returned in variable pointed by outlen.
+ *
+ * Returns CURLE_OK on success, otherwise specific error code. Function
+ * output shall not be considered valid unless CURLE_OK is returned.
+ *
+ * When decoded data length is 0, returns NULL in *outptr.
+ *
+ * @unittest: 1302
+ */
+CURLcode Curl_base64_decode(const char *src,
+                            unsigned char **outptr, size_t *outlen)
+{
+  size_t srclen = 0;
+  size_t length = 0;
+  size_t padding = 0;
+  size_t i;
+  size_t numQuantums;
+  size_t rawlen = 0;
+  unsigned char *pos;
+  unsigned char *newstr;
+
+  *outptr = NULL;
+  *outlen = 0;
+  srclen = strlen(src);
+
+  /* Check the length of the input string is valid */
+  if(!srclen || srclen % 4)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  /* Find the position of any = padding characters */
+  while((src[length] != '=') && src[length])
+    length++;
+
+  /* A maximum of two = padding characters is allowed */
+  if(src[length] == '=') {
+    padding++;
+    if(src[length + 1] == '=')
+      padding++;
+  }
+
+  /* Check the = padding characters weren't part way through the input */
+  if(length + padding != srclen)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  /* Calculate the number of quantums */
+  numQuantums = srclen / 4;
+
+  /* Calculate the size of the decoded string */
+  rawlen = (numQuantums * 3) - padding;
+
+  /* Allocate our buffer including room for a zero terminator */
+  newstr = malloc(rawlen + 1);
+  if(!newstr)
+    return CURLE_OUT_OF_MEMORY;
+
+  pos = newstr;
+
+  /* Decode the quantums */
+  for(i = 0; i < numQuantums; i++) {
+    size_t result = decodeQuantum(pos, src);
+    if(!result) {
+      free(newstr);
+
+      return CURLE_BAD_CONTENT_ENCODING;
+    }
+
+    pos += result;
+    src += 4;
+  }
+
+  /* Zero terminate */
+  *pos = '\0';
+
+  /* Return the decoded data */
+  *outptr = newstr;
+  *outlen = rawlen;
+
+  return CURLE_OK;
+}
+
+static CURLcode base64_encode(const char *table64,
+                              struct Curl_easy *data,
+                              const char *inputbuff, size_t insize,
+                              char **outptr, size_t *outlen)
+{
+  CURLcode result;
+  unsigned char ibuf[3];
+  unsigned char obuf[4];
+  int i;
+  int inputparts;
+  char *output;
+  char *base64data;
+  char *convbuf = NULL;
+
+  const char *indata = inputbuff;
+
+  *outptr = NULL;
+  *outlen = 0;
+
+  if(!insize)
+    insize = strlen(indata);
+
+#if SIZEOF_SIZE_T == 4
+  if(insize > UINT_MAX/4)
+    return CURLE_OUT_OF_MEMORY;
+#endif
+
+  base64data = output = malloc(insize * 4 / 3 + 4);
+  if(!output)
+    return CURLE_OUT_OF_MEMORY;
+
+  /*
+   * The base64 data needs to be created using the network encoding
+   * not the host encoding.  And we can't change the actual input
+   * so we copy it to a buffer, translate it, and use that instead.
+   */
+  result = Curl_convert_clone(data, indata, insize, &convbuf);
+  if(result) {
+    free(output);
+    return result;
+  }
+
+  if(convbuf)
+    indata = (char *)convbuf;
+
+  while(insize > 0) {
+    for(i = inputparts = 0; i < 3; i++) {
+      if(insize > 0) {
+        inputparts++;
+        ibuf[i] = (unsigned char) *indata;
+        indata++;
+        insize--;
+      }
+      else
+        ibuf[i] = 0;
+    }
+
+    obuf[0] = (unsigned char)  ((ibuf[0] & 0xFC) >> 2);
+    obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \
+                               ((ibuf[1] & 0xF0) >> 4));
+    obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \
+                               ((ibuf[2] & 0xC0) >> 6));
+    obuf[3] = (unsigned char)   (ibuf[2] & 0x3F);
+
+    switch(inputparts) {
+    case 1: /* only one byte read */
+      snprintf(output, 5, "%c%c==",
+               table64[obuf[0]],
+               table64[obuf[1]]);
+      break;
+
+    case 2: /* two bytes read */
+      snprintf(output, 5, "%c%c%c=",
+               table64[obuf[0]],
+               table64[obuf[1]],
+               table64[obuf[2]]);
+      break;
+
+    default:
+      snprintf(output, 5, "%c%c%c%c",
+               table64[obuf[0]],
+               table64[obuf[1]],
+               table64[obuf[2]],
+               table64[obuf[3]]);
+      break;
+    }
+    output += 4;
+  }
+
+  /* Zero terminate */
+  *output = '\0';
+
+  /* Return the pointer to the new data (allocated memory) */
+  *outptr = base64data;
+
+  free(convbuf);
+
+  /* Return the length of the new data */
+  *outlen = strlen(base64data);
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_base64_encode()
+ *
+ * Given a pointer to an input buffer and an input size, encode it and
+ * return a pointer in *outptr to a newly allocated memory area holding
+ * encoded data. Size of encoded data is returned in variable pointed by
+ * outlen.
+ *
+ * Input length of 0 indicates input buffer holds a NUL-terminated string.
+ *
+ * Returns CURLE_OK on success, otherwise specific error code. Function
+ * output shall not be considered valid unless CURLE_OK is returned.
+ *
+ * When encoded data length is 0, returns NULL in *outptr.
+ *
+ * @unittest: 1302
+ */
+CURLcode Curl_base64_encode(struct Curl_easy *data,
+                            const char *inputbuff, size_t insize,
+                            char **outptr, size_t *outlen)
+{
+  return base64_encode(base64, data, inputbuff, insize, outptr, outlen);
+}
+
+/*
+ * Curl_base64url_encode()
+ *
+ * Given a pointer to an input buffer and an input size, encode it and
+ * return a pointer in *outptr to a newly allocated memory area holding
+ * encoded data. Size of encoded data is returned in variable pointed by
+ * outlen.
+ *
+ * Input length of 0 indicates input buffer holds a NUL-terminated string.
+ *
+ * Returns CURLE_OK on success, otherwise specific error code. Function
+ * output shall not be considered valid unless CURLE_OK is returned.
+ *
+ * When encoded data length is 0, returns NULL in *outptr.
+ *
+ * @unittest: 1302
+ */
+CURLcode Curl_base64url_encode(struct Curl_easy *data,
+                               const char *inputbuff, size_t insize,
+                               char **outptr, size_t *outlen)
+{
+  return base64_encode(base64url, data, inputbuff, insize, outptr, outlen);
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/config-dos.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/config-dos.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/config-dos.h	(revision 331)
@@ -0,0 +1,185 @@
+#ifndef HEADER_CURL_CONFIG_DOS_H
+#define HEADER_CURL_CONFIG_DOS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+
+/* ================================================================ */
+/*       lib/config-dos.h - Hand crafted config file for DOS        */
+/* ================================================================ */
+
+#if defined(DJGPP)
+  #define OS  "MSDOS/djgpp"
+#elif defined(__HIGHC__)
+  #define OS  "MSDOS/HighC"
+#elif defined(__WATCOMC__)
+  #define OS  "MSDOS/Watcom"
+#else
+  #define OS  "MSDOS/?"
+#endif
+
+#define PACKAGE  "curl"
+
+#define HAVE_ARPA_INET_H       1
+#define HAVE_ASSERT_H          1
+#define HAVE_ERRNO_H           1
+#define HAVE_FCNTL_H           1
+#define HAVE_FREEADDRINFO      1
+#define HAVE_GETADDRINFO       1
+#define HAVE_GETNAMEINFO       1
+#define HAVE_GETPROTOBYNAME    1
+#define HAVE_GETTIMEOFDAY      1
+#define HAVE_IO_H              1
+#define HAVE_IOCTL             1
+#define HAVE_IOCTL_FIONBIO     1
+#define HAVE_IOCTLSOCKET       1
+#define HAVE_IOCTLSOCKET_FIONBIO   1
+#define HAVE_LIMITS_H          1
+#define HAVE_LOCALE_H          1
+#define HAVE_LONGLONG          1
+#define HAVE_MEMORY_H          1
+#define HAVE_NETDB_H           1
+#define HAVE_NETINET_IN_H      1
+#define HAVE_NETINET_TCP_H     1
+#define HAVE_NET_IF_H          1
+#define HAVE_PROCESS_H         1
+#define HAVE_RECV              1
+#define HAVE_RECVFROM          1
+#define HAVE_SELECT            1
+#define HAVE_SEND              1
+#define HAVE_SETJMP_H          1
+#define HAVE_SETLOCALE         1
+#define HAVE_SETMODE           1
+#define HAVE_SIGNAL            1
+#define HAVE_SOCKET            1
+#define HAVE_STRDUP            1
+#define HAVE_STRICMP           1
+#define HAVE_STRTOLL           1
+#define HAVE_STRUCT_TIMEVAL    1
+#define HAVE_STRUCT_IN6_ADDR   1
+#define HAVE_SYS_IOCTL_H       1
+#define HAVE_SYS_SOCKET_H      1
+#define HAVE_SYS_STAT_H        1
+#define HAVE_SYS_TYPES_H       1
+#define HAVE_TIME_H            1
+#define HAVE_UNISTD_H          1
+
+#define NEED_MALLOC_H          1
+
+#define RETSIGTYPE             void
+#define SIZEOF_INT             4
+#define SIZEOF_LONG            4
+#define SIZEOF_LONG_DOUBLE     16
+#define SIZEOF_SHORT           2
+#define SIZEOF_SIZE_T          4
+#define SIZEOF_CURL_OFF_T      4
+#define STDC_HEADERS           1
+#define TIME_WITH_SYS_TIME     1
+
+/* Qualifiers for send(), recv(), recvfrom() and getnameinfo(). */
+
+#define SEND_TYPE_ARG1         int
+#define SEND_QUAL_ARG2         const
+#define SEND_TYPE_ARG2         void *
+#define SEND_TYPE_ARG3         int
+#define SEND_TYPE_ARG4         int
+#define SEND_TYPE_RETV         int
+
+#define RECV_TYPE_ARG1         int
+#define RECV_TYPE_ARG2         void *
+#define RECV_TYPE_ARG3         int
+#define RECV_TYPE_ARG4         int
+#define RECV_TYPE_RETV         int
+
+#define RECVFROM_TYPE_ARG1     int
+#define RECVFROM_TYPE_ARG2     void
+#define RECVFROM_TYPE_ARG3     int
+#define RECVFROM_TYPE_ARG4     int
+#define RECVFROM_TYPE_ARG5     struct sockaddr
+#define RECVFROM_TYPE_ARG6     int
+#define RECVFROM_TYPE_RETV     int
+#define RECVFROM_TYPE_ARG2_IS_VOID 1
+
+#define GETNAMEINFO_QUAL_ARG1  const
+#define GETNAMEINFO_TYPE_ARG1  struct sockaddr *
+#define GETNAMEINFO_TYPE_ARG2  int
+#define GETNAMEINFO_TYPE_ARG46 int
+#define GETNAMEINFO_TYPE_ARG7  int
+
+#define BSD
+
+/* CURLDEBUG definition enables memory tracking */
+/* #define CURLDEBUG */
+
+/* USE_ZLIB on cmd-line */
+#ifdef USE_ZLIB
+  #define HAVE_ZLIB_H            1
+  #define HAVE_LIBZ              1
+#endif
+
+/* USE_OPENSSL on cmd-line */
+#ifdef USE_OPENSSL
+  #define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1
+  #define HAVE_OPENSSL_ENGINE_H  1
+  #define OPENSSL_NO_KRB5        1
+#endif
+
+/* to disable LDAP */
+#define CURL_DISABLE_LDAP        1
+
+#define in_addr_t  u_long
+
+#if defined(__HIGHC__) || \
+    (defined(__GNUC__) && (__GNUC__ < 4))
+  #define ssize_t  int
+#endif
+
+#define CURL_CA_BUNDLE  getenv("CURL_CA_BUNDLE")
+
+/* Target HAVE_x section */
+
+#if defined(DJGPP)
+  #define HAVE_BASENAME   1
+  #define HAVE_STRCASECMP 1
+  #define HAVE_SIGACTION  1
+  #define HAVE_SIGSETJMP  1
+  #define HAVE_SYS_TIME_H 1
+  #define HAVE_TERMIOS_H  1
+  #define HAVE_VARIADIC_MACROS_GCC 1
+
+#elif defined(__WATCOMC__)
+  #define HAVE_STRCASECMP 1
+
+#elif defined(__HIGHC__)
+  #define HAVE_SYS_TIME_H 1
+  #define strerror(e) strerror_s_((e))
+#endif
+
+#ifdef MSDOS  /* Watt-32 */
+  #define HAVE_CLOSE_S    1
+#endif
+
+#undef word
+#undef byte
+
+#endif /* HEADER_CURL_CONFIG_DOS_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/config-mac.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/config-mac.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/config-mac.h	(revision 331)
@@ -0,0 +1,125 @@
+#ifndef HEADER_CURL_CONFIG_MAC_H
+#define HEADER_CURL_CONFIG_MAC_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* =================================================================== */
+/*                Hand crafted config file for Mac OS 9                */
+/* =================================================================== */
+/*  On Mac OS X you must run configure to generate curl_config.h file  */
+/* =================================================================== */
+
+#define OS "mac"
+
+/* Define if you want the built-in manual */
+#define USE_MANUAL              1
+
+#define HAVE_ERRNO_H            1
+#define HAVE_NETINET_IN_H       1
+#define HAVE_SYS_SOCKET_H       1
+#define HAVE_SYS_SELECT_H       1
+#define HAVE_NETDB_H            1
+#define HAVE_ARPA_INET_H        1
+#define HAVE_UNISTD_H           1
+#define HAVE_NET_IF_H           1
+#define HAVE_SYS_TYPES_H        1
+#define HAVE_GETTIMEOFDAY       1
+#define HAVE_FCNTL_H            1
+#define HAVE_SYS_STAT_H         1
+#define HAVE_ALLOCA_H           1
+#define HAVE_STDLIB_H           1
+#define HAVE_TIME_H             1
+#define HAVE_UTIME_H            1
+#define HAVE_SYS_TIME_H         1
+#define HAVE_SYS_UTIME_H        1
+
+#define TIME_WITH_SYS_TIME      1
+
+#define HAVE_ALARM              1
+#define HAVE_FTRUNCATE          1
+#define HAVE_UTIME              1
+#define HAVE_SETVBUF            1
+#define HAVE_STRFTIME           1
+#define HAVE_INET_ADDR          1
+#define HAVE_MEMCPY             1
+#define HAVE_SELECT             1
+#define HAVE_SOCKET             1
+#define HAVE_STRUCT_TIMEVAL     1
+
+#define HAVE_SIGACTION          1
+#define HAVE_SIGNAL_H           1
+#define HAVE_SIG_ATOMIC_T       1
+
+#ifdef MACOS_SSL_SUPPORT
+#  define USE_OPENSSL           1
+#endif
+
+#define CURL_DISABLE_LDAP       1
+
+#define HAVE_RAND_STATUS        1
+#define HAVE_RAND_EGD           1
+
+#define HAVE_IOCTL              1
+#define HAVE_IOCTL_FIONBIO      1
+
+#define RETSIGTYPE void
+
+#define SIZEOF_INT              4
+#define SIZEOF_SHORT            2
+#define SIZEOF_SIZE_T           4
+
+#define HAVE_GETNAMEINFO 1
+#define GETNAMEINFO_QUAL_ARG1 const
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+#define GETNAMEINFO_TYPE_ARG2 socklen_t
+#define GETNAMEINFO_TYPE_ARG46 size_t
+#define GETNAMEINFO_TYPE_ARG7 int
+
+#define HAVE_RECV 1
+#define RECV_TYPE_ARG1 int
+#define RECV_TYPE_ARG2 void *
+#define RECV_TYPE_ARG3 size_t
+#define RECV_TYPE_ARG4 int
+#define RECV_TYPE_RETV ssize_t
+
+#define HAVE_RECVFROM 1
+#define RECVFROM_TYPE_ARG1 int
+#define RECVFROM_TYPE_ARG2 void
+#define RECVFROM_TYPE_ARG3 size_t
+#define RECVFROM_TYPE_ARG4 int
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+#define RECVFROM_TYPE_ARG6 int
+#define RECVFROM_TYPE_RETV ssize_t
+#define RECVFROM_TYPE_ARG2_IS_VOID 1
+
+#define HAVE_SEND 1
+#define SEND_TYPE_ARG1 int
+#define SEND_QUAL_ARG2 const
+#define SEND_TYPE_ARG2 void *
+#define SEND_TYPE_ARG3 size_T
+#define SEND_TYPE_ARG4 int
+#define SEND_TYPE_RETV ssize_t
+
+#define HAVE_EXTRA_STRICMP_H 1
+#define HAVE_EXTRA_STRDUP_H  1
+
+#endif /* HEADER_CURL_CONFIG_MAC_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/config-os400.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/config-os400.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/config-os400.h	(revision 331)
@@ -0,0 +1,569 @@
+#ifndef HEADER_CURL_CONFIG_OS400_H
+#define HEADER_CURL_CONFIG_OS400_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/*                Hand crafted config file for OS/400               */
+/* ================================================================ */
+
+#pragma enum(int)
+
+#undef PACKAGE
+
+/* Version number of this archive. */
+#undef VERSION
+
+/* Define if you have the getpass function.  */
+#undef HAVE_GETPASS
+
+/* Define cpu-machine-OS */
+#define OS "OS/400"
+
+/* Define if you have the gethostbyaddr_r() function with 5 arguments */
+#define HAVE_GETHOSTBYADDR_R_5
+
+/* Define if you have the gethostbyaddr_r() function with 7 arguments */
+#undef HAVE_GETHOSTBYADDR_R_7
+
+/* Define if you have the gethostbyaddr_r() function with 8 arguments */
+#undef HAVE_GETHOSTBYADDR_R_8
+
+/* OS400 supports a 3-argument ASCII version of gethostbyaddr_r(), but its
+ *  prototype is incompatible with the "standard" one (1st argument is not
+ *  const). However, getaddrinfo() is supported (ASCII version defined as
+ *  a local wrapper in setup-os400.h) in a threadsafe way: we can then
+ *  configure getaddrinfo() as such and get rid of gethostbyname_r() without
+ *  loss of threadsafeness. */
+#undef HAVE_GETHOSTBYNAME_R
+#undef HAVE_GETHOSTBYNAME_R_3
+#undef HAVE_GETHOSTBYNAME_R_5
+#undef HAVE_GETHOSTBYNAME_R_6
+#define HAVE_GETADDRINFO
+#define HAVE_GETADDRINFO_THREADSAFE
+
+/* Define if you need the _REENTRANT define for some functions */
+#undef NEED_REENTRANT
+
+/* Define if you have the Kerberos4 libraries (including -ldes) */
+#undef HAVE_KRB4
+
+/* Define if you want to enable IPv6 support */
+#define ENABLE_IPV6
+
+/* Define if struct sockaddr_in6 has the sin6_scope_id member */
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+
+/* Define this to 'int' if ssize_t is not an available typedefed type */
+#undef ssize_t
+
+/* Define this as a suitable file to read random data from */
+#undef RANDOM_FILE
+
+/* Define this to your Entropy Gathering Daemon socket pathname */
+#undef EGD_SOCKET
+
+/* Define to 1 if you have the alarm function. */
+#define HAVE_ALARM 1
+
+/* Define if you have the <alloca.h> header file. */
+#undef HAVE_ALLOCA_H
+
+/* Define if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H
+
+/* Define if you have the `closesocket' function. */
+#undef HAVE_CLOSESOCKET
+
+/* Define if you have the <crypto.h> header file. */
+#undef HAVE_CRYPTO_H
+
+/* Define if you have the <des.h> header file. */
+#undef HAVE_DES_H
+
+/* Define if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H
+
+/* Define if you have the <err.h> header file. */
+#undef HAVE_ERR_H
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H
+
+/* Define if you have the `geteuid' function. */
+#define HAVE_GETEUID
+
+/* Define if you have the `gethostbyaddr' function. */
+#define HAVE_GETHOSTBYADDR
+
+/* Define if you have the `gethostbyaddr_r' function. */
+#define HAVE_GETHOSTBYADDR_R
+
+/* Define if you have the `gethostname' function. */
+#define HAVE_GETHOSTNAME
+
+/* Define if you have the <getopt.h> header file. */
+#undef HAVE_GETOPT_H
+
+/* Define if you have the `getpass_r' function. */
+#undef HAVE_GETPASS_R
+
+/* Define if you have the `getpwuid' function. */
+#define HAVE_GETPWUID
+
+/* Define if you have the `getservbyname' function. */
+#define HAVE_GETSERVBYNAME
+
+/* Define if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY
+
+/* Define if you have the `timeval' struct. */
+#define HAVE_STRUCT_TIMEVAL
+
+/* Define if you have the `inet_addr' function. */
+#define HAVE_INET_ADDR
+
+/* Define if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H
+
+/* Define if you have the <io.h> header file. */
+#undef HAVE_IO_H
+
+/* Define if you have the `krb_get_our_ip_for_realm' function. */
+#undef HAVE_KRB_GET_OUR_IP_FOR_REALM
+
+/* Define if you have the <krb.h> header file. */
+#undef HAVE_KRB_H
+
+/* Define if you have the `crypto' library (-lcrypto). */
+#undef HAVE_LIBCRYPTO
+
+/* Define if you have the `nsl' library (-lnsl). */
+#undef HAVE_LIBNSL
+
+/* Define if you have the `resolv' library (-lresolv). */
+#undef HAVE_LIBRESOLV
+
+/* Define if you have the `resolve' library (-lresolve). */
+#undef HAVE_LIBRESOLVE
+
+/* Define if you have the `socket' library (-lsocket). */
+#undef HAVE_LIBSOCKET
+
+/* Define if you have the `ssl' library (-lssl). */
+#undef HAVE_LIBSSL
+
+/* Define if you have GSS API. */
+#define HAVE_GSSAPI
+
+/* Define if you have the GNU gssapi libraries */
+#undef HAVE_GSSGNU
+
+/* Define if you have the Heimdal gssapi libraries */
+#define HAVE_GSSHEIMDAL
+
+/* Define if you have the MIT gssapi libraries */
+#undef HAVE_GSSMIT
+
+/* Define if you have the `ucb' library (-lucb). */
+#undef HAVE_LIBUCB
+
+/* Define if you have the `localtime_r' function. */
+#define HAVE_LOCALTIME_R
+
+/* Define if you have the <malloc.h> header file. */
+#define HAVE_MALLOC_H
+
+/* Define if you need the malloc.h header file even with stdlib.h  */
+/* #define NEED_MALLOC_H 1 */
+
+/* Define if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H
+
+/* Define if you have the <netinet/if_ether.h> header file. */
+#undef HAVE_NETINET_IF_ETHER_H
+
+/* Define if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H
+
+/* Define if you have the <net/if.h> header file. */
+#define HAVE_NET_IF_H
+
+/* Define if you have the <openssl/crypto.h> header file. */
+#undef HAVE_OPENSSL_CRYPTO_H
+
+/* Define if you have the <openssl/err.h> header file. */
+#undef HAVE_OPENSSL_ERR_H
+
+/* Define if you have the <openssl/pem.h> header file. */
+#undef HAVE_OPENSSL_PEM_H
+
+/* Define if you have the <openssl/rsa.h> header file. */
+#undef HAVE_OPENSSL_RSA_H
+
+/* Define if you have the <openssl/ssl.h> header file. */
+#undef HAVE_OPENSSL_SSL_H
+
+/* Define if you have the <openssl/x509.h> header file. */
+#undef HAVE_OPENSSL_X509_H
+
+/* Define if you have the <pem.h> header file. */
+#undef HAVE_PEM_H
+
+/* Define if you have the `perror' function. */
+#define HAVE_PERROR
+
+/* Define if you have the <pwd.h> header file. */
+#define HAVE_PWD_H
+
+/* Define if you have the `RAND_egd' function. */
+#undef HAVE_RAND_EGD
+
+/* Define if you have the `RAND_screen' function. */
+#undef HAVE_RAND_SCREEN
+
+/* Define if you have the `RAND_status' function. */
+#undef HAVE_RAND_STATUS
+
+/* Define if you have the <rsa.h> header file. */
+#undef HAVE_RSA_H
+
+/* Define if you have the `select' function. */
+#define HAVE_SELECT
+
+/* Define if you have the `setvbuf' function. */
+#define HAVE_SETVBUF
+
+/* Define if you have the <sgtty.h> header file. */
+#undef HAVE_SGTTY_H
+
+/* Define if you have the `sigaction' function. */
+#define HAVE_SIGACTION
+
+/* Define if you have the `signal' function. */
+#undef HAVE_SIGNAL
+
+/* Define if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H
+
+/* Define if sig_atomic_t is an available typedef. */
+#define HAVE_SIG_ATOMIC_T
+
+/* Define if sig_atomic_t is already defined as volatile. */
+#undef HAVE_SIG_ATOMIC_T_VOLATILE
+
+/* Define if you have the `socket' function. */
+#define HAVE_SOCKET
+
+/* Define if you have the <ssl.h> header file. */
+#undef HAVE_SSL_H
+
+/* Define if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H
+
+
+/* The following define is needed on OS400 to enable strcmpi(), stricmp() and
+   strdup(). */
+#define __cplusplus__strings__
+
+/* Define if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the `strcmpi' function. */
+#define HAVE_STRCMPI
+
+/* Define if you have the `stricmp' function. */
+#define HAVE_STRICMP
+
+/* Define if you have the `strdup' function. */
+#define HAVE_STRDUP
+
+
+/* Define if you have the `strftime' function. */
+#define HAVE_STRFTIME
+
+/* Define if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H
+
+/* Define if you have the `strlcpy' function. */
+#undef HAVE_STRLCPY
+
+/* Define if you have the <stropts.h> header file. */
+#undef HAVE_STROPTS_H
+
+/* Define if you have the `strstr' function. */
+#define HAVE_STRSTR
+
+/* Define if you have the `strtok_r' function. */
+#define HAVE_STRTOK_R
+
+/* Define if you have the `strtoll' function. */
+#undef HAVE_STRTOLL             /* Allows ASCII compile on V5R1. */
+
+/* Define if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H
+
+/* Define if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H
+
+/* Define if you have the <sys/sockio.h> header file. */
+#undef HAVE_SYS_SOCKIO_H
+
+/* Define if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H
+
+/* Define if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H
+
+/* Define if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H
+
+/* Define if you have the <sys/un.h> header file. */
+#define HAVE_SYS_UN_H
+
+/* Define if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H
+
+/* Define if you have the `tcgetattr' function. */
+#undef HAVE_TCGETATTR
+
+/* Define if you have the `tcsetattr' function. */
+#undef HAVE_TCSETATTR
+
+/* Define if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define if you have the <termio.h> header file. */
+#undef HAVE_TERMIO_H
+
+/* Define if you have the <time.h> header file. */
+#define HAVE_TIME_H
+
+/* Define if you have the `uname' function. */
+#undef HAVE_UNAME
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H
+
+/* Define if you have the <winsock.h> header file. */
+#undef HAVE_WINSOCK_H
+
+/* Define if you have the <x509.h> header file. */
+#undef HAVE_X509_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* The size of `int', as computed by sizeof. */
+#define SIZEOF_INT              4
+
+/* The size of a `long double', as computed by sizeof. */
+#define SIZEOF_LONG_DOUBLE      8
+
+/* Define if the compiler supports the 'long long' data type. */
+#define HAVE_LONGLONG
+
+/* The size of a `long long', as computed by sizeof. */
+#define SIZEOF_LONG_LONG        8
+
+/* The size of `short', as computed by sizeof. */
+#define SIZEOF_SHORT            2
+
+/* The size of `long', as computed by sizeof. */
+#define SIZEOF_LONG             4
+
+/* The size of `size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T           4
+
+/* The size of `curl_off_t', as computed by sizeof. */
+#define SIZEOF_CURL_OFF_T       8
+
+/* Whether long long constants must be suffixed by LL. */
+
+#define HAVE_LL
+
+/* Define this if you have struct sockaddr_storage */
+#define HAVE_STRUCT_SOCKADDR_STORAGE
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME
+
+/* Version number of package */
+#undef VERSION
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#define _LARGE_FILES
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* type to use in place of in_addr_t if not defined */
+#define in_addr_t       unsigned long
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define if you have the ioctl function. */
+#define HAVE_IOCTL
+
+/* Define if you have a working ioctl FIONBIO function. */
+#define HAVE_IOCTL_FIONBIO
+
+/* Define if you have a working ioctl SIOCGIFADDR function. */
+#define HAVE_IOCTL_SIOCGIFADDR
+
+/* To disable LDAP */
+#undef CURL_DISABLE_LDAP
+
+/* Definition to make a library symbol externally visible. */
+#define CURL_EXTERN_SYMBOL
+
+/* Define if you have the ldap_url_parse procedure. */
+/* #define HAVE_LDAP_URL_PARSE */    /* Disabled because of an IBM bug. */
+
+/* Define if you have the getnameinfo function. */
+/* OS400 has no ASCII version of this procedure: wrapped in setup-os400.h. */
+#define HAVE_GETNAMEINFO
+
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+#define GETNAMEINFO_QUAL_ARG1 const
+
+/* Define to the type of arg 1 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+
+/* Define to the type of arg 2 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG2 socklen_t
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG46 socklen_t
+
+/* Define to the type of arg 7 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG7 int
+
+/* Define if you have the recv function. */
+#define HAVE_RECV
+
+/* Define to the type of arg 1 for recv. */
+#define RECV_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for recv. */
+#define RECV_TYPE_ARG2 char *
+
+/* Define to the type of arg 3 for recv. */
+#define RECV_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for recv. */
+#define RECV_TYPE_ARG4 int
+
+/* Define to the function return type for recv. */
+#define RECV_TYPE_RETV int
+
+/* Define if you have the recvfrom function. */
+#define HAVE_RECVFROM
+
+/* Define to the type of arg 1 for recvfrom. */
+#define RECVFROM_TYPE_ARG1 int
+
+/* Define to the type pointed by arg 2 for recvfrom. */
+#define RECVFROM_TYPE_ARG2 char
+
+/* Define to the type of arg 3 for recvfrom. */
+#define RECVFROM_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for recvfrom. */
+#define RECVFROM_TYPE_ARG4 int
+
+/* Define to the type pointed by arg 5 for recvfrom. */
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+
+/* Define to the type pointed by arg 6 for recvfrom. */
+#define RECVFROM_TYPE_ARG6 int
+
+/* Define to the function return type for recvfrom. */
+#define RECVFROM_TYPE_RETV int
+
+/* Define if you have the send function. */
+#define HAVE_SEND
+
+/* Define to the type of arg 1 for send. */
+#define SEND_TYPE_ARG1 int
+
+/* Define to the type qualifier of arg 2 for send. */
+#define SEND_QUAL_ARG2
+
+/* Define to the type of arg 2 for send. */
+#define SEND_TYPE_ARG2 char *
+
+/* Define to the type of arg 3 for send. */
+#define SEND_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for send. */
+#define SEND_TYPE_ARG4 int
+
+/* Define to the function return type for send. */
+#define SEND_TYPE_RETV int
+
+/* Define to use the GSKit package. */
+#define USE_GSKIT
+
+/* Define to use the OS/400 crypto library. */
+#define USE_OS400CRYPTO
+
+/* Define to use Unix sockets. */
+#define USE_UNIX_SOCKETS
+
+/* Use the system keyring as the default CA bundle. */
+#define CURL_CA_BUNDLE  "/QIBM/UserData/ICSS/Cert/Server/DEFAULT.KDB"
+
+/* ---------------------------------------------------------------- */
+/*                       ADDITIONAL DEFINITIONS                     */
+/* ---------------------------------------------------------------- */
+
+/* The following must be defined BEFORE system header files inclusion. */
+
+#define __ptr128                       /* No teraspace. */
+#define qadrt_use_fputc_inline         /* Generate fputc() wrapper inline. */
+#define qadrt_use_fread_inline         /* Generate fread() wrapper inline. */
+#define qadrt_use_fwrite_inline        /* Generate fwrite() wrapper inline. */
+
+#endif /* HEADER_CURL_CONFIG_OS400_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/config-riscos.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/config-riscos.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/config-riscos.h	(revision 331)
@@ -0,0 +1,513 @@
+#ifndef HEADER_CURL_CONFIG_RISCOS_H
+#define HEADER_CURL_CONFIG_RISCOS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/*               Hand crafted config file for RISC OS               */
+/* ================================================================ */
+
+/* Name of this package! */
+#undef PACKAGE
+
+/* Version number of this archive. */
+#undef VERSION
+
+/* Define if you have the getpass function.  */
+#undef HAVE_GETPASS
+
+/* Define cpu-machine-OS */
+#define OS "ARM-RISC OS"
+
+/* Define if you want the built-in manual */
+#define USE_MANUAL
+
+/* Define if you have the gethostbyaddr_r() function with 5 arguments */
+#undef HAVE_GETHOSTBYADDR_R_5
+
+/* Define if you have the gethostbyaddr_r() function with 7 arguments */
+#undef HAVE_GETHOSTBYADDR_R_7
+
+/* Define if you have the gethostbyaddr_r() function with 8 arguments */
+#undef HAVE_GETHOSTBYADDR_R_8
+
+/* Define if you have the gethostbyname_r() function with 3 arguments */
+#undef HAVE_GETHOSTBYNAME_R_3
+
+/* Define if you have the gethostbyname_r() function with 5 arguments */
+#undef HAVE_GETHOSTBYNAME_R_5
+
+/* Define if you have the gethostbyname_r() function with 6 arguments */
+#undef HAVE_GETHOSTBYNAME_R_6
+
+/* Define if you need the _REENTRANT define for some functions */
+#undef NEED_REENTRANT
+
+/* Define if you have the Kerberos4 libraries (including -ldes) */
+#undef HAVE_KRB4
+
+/* Define if you want to enable IPv6 support */
+#undef ENABLE_IPV6
+
+/* Define if struct sockaddr_in6 has the sin6_scope_id member */
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+
+/* Define this to 'int' if ssize_t is not an available typedefed type */
+#undef ssize_t
+
+/* Define this as a suitable file to read random data from */
+#undef RANDOM_FILE
+
+/* Define this to your Entropy Gathering Daemon socket pathname */
+#undef EGD_SOCKET
+
+/* Define if you want to enable IPv6 support */
+#undef ENABLE_IPV6
+
+/* Define if you have the alarm function. */
+#define HAVE_ALARM
+
+/* Define if you have the <alloca.h> header file. */
+#define HAVE_ALLOCA_H
+
+/* Define if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H
+
+/* Define if you have the `closesocket' function. */
+#undef HAVE_CLOSESOCKET
+
+/* Define if you have the <crypto.h> header file. */
+#undef HAVE_CRYPTO_H
+
+/* Define if you have the <des.h> header file. */
+#undef HAVE_DES_H
+
+/* Define if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H
+
+/* Define if you have the <err.h> header file. */
+#undef HAVE_ERR_H
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H
+
+/* Define if you have the `ftruncate' function. */
+#define HAVE_FTRUNCATE
+
+/* Define if getaddrinfo exists and works */
+#define HAVE_GETADDRINFO
+
+/* Define if you have the `geteuid' function. */
+#undef HAVE_GETEUID
+
+/* Define if you have the `gethostbyaddr' function. */
+#define HAVE_GETHOSTBYADDR
+
+/* Define if you have the `gethostbyaddr_r' function. */
+#undef HAVE_GETHOSTBYADDR_R
+
+/* Define if you have the `gethostbyname_r' function. */
+#undef HAVE_GETHOSTBYNAME_R
+
+/* Define if you have the `gethostname' function. */
+#define HAVE_GETHOSTNAME
+
+/* Define if you have the <getopt.h> header file. */
+#define HAVE_GETOPT_H
+
+/* Define if you have the `getpass_r' function. */
+#undef HAVE_GETPASS_R
+
+/* Define if you have the `getpwuid' function. */
+#undef HAVE_GETPWUID
+
+/* Define if you have the `getservbyname' function. */
+#undef HAVE_GETSERVBYNAME
+
+/* Define if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY
+
+/* Define if you have the `timeval' struct. */
+#define HAVE_STRUCT_TIMEVAL
+
+/* Define if you have the `inet_addr' function. */
+#undef HAVE_INET_ADDR
+
+/* Define if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H
+
+/* Define if you have the <io.h> header file. */
+#undef HAVE_IO_H
+
+/* Define if you have the `krb_get_our_ip_for_realm' function. */
+#undef HAVE_KRB_GET_OUR_IP_FOR_REALM
+
+/* Define if you have the <krb.h> header file. */
+#undef HAVE_KRB_H
+
+/* Define if you have the `crypto' library (-lcrypto). */
+#undef HAVE_LIBCRYPTO
+
+/* Define if you have the `nsl' library (-lnsl). */
+#undef HAVE_LIBNSL
+
+/* Define if you have the `resolv' library (-lresolv). */
+#undef HAVE_LIBRESOLV
+
+/* Define if you have the `resolve' library (-lresolve). */
+#undef HAVE_LIBRESOLVE
+
+/* Define if you have the `socket' library (-lsocket). */
+#undef HAVE_LIBSOCKET
+
+/* Define if you have the `ssl' library (-lssl). */
+#undef HAVE_LIBSSL
+
+/* Define if you have the `ucb' library (-lucb). */
+#undef HAVE_LIBUCB
+
+/* Define if you have the `localtime_r' function. */
+#undef HAVE_LOCALTIME_R
+
+/* Define if you have the <malloc.h> header file. */
+#define HAVE_MALLOC_H
+
+/* Define if you need the malloc.h header file even with stdlib.h  */
+/* #define NEED_MALLOC_H 1 */
+
+/* Define if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H
+
+/* Define if you have the <netinet/if_ether.h> header file. */
+#undef HAVE_NETINET_IF_ETHER_H
+
+/* Define if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H
+
+/* Define if you have the <net/if.h> header file. */
+#define HAVE_NET_IF_H
+
+/* Define if you have the <openssl/crypto.h> header file. */
+#undef HAVE_OPENSSL_CRYPTO_H
+
+/* Define if you have the <openssl/err.h> header file. */
+#undef HAVE_OPENSSL_ERR_H
+
+/* Define if you have the <openssl/pem.h> header file. */
+#undef HAVE_OPENSSL_PEM_H
+
+/* Define if you have the <openssl/rsa.h> header file. */
+#undef HAVE_OPENSSL_RSA_H
+
+/* Define if you have the <openssl/ssl.h> header file. */
+#undef HAVE_OPENSSL_SSL_H
+
+/* Define if you have the <openssl/x509.h> header file. */
+#undef HAVE_OPENSSL_X509_H
+
+/* Define if you have the <pem.h> header file. */
+#undef HAVE_PEM_H
+
+/* Define if you have the `perror' function. */
+#undef HAVE_PERROR
+
+/* Define if you have the <pwd.h> header file. */
+#undef HAVE_PWD_H
+
+/* Define if you have the `RAND_egd' function. */
+#undef HAVE_RAND_EGD
+
+/* Define if you have the `RAND_screen' function. */
+#undef HAVE_RAND_SCREEN
+
+/* Define if you have the `RAND_status' function. */
+#undef HAVE_RAND_STATUS
+
+/* Define if you have the <rsa.h> header file. */
+#undef HAVE_RSA_H
+
+/* Define if you have the `select' function. */
+#define HAVE_SELECT
+
+/* Define if you have the `setvbuf' function. */
+#undef HAVE_SETVBUF
+
+/* Define if you have the <sgtty.h> header file. */
+#define HAVE_SGTTY_H
+
+/* Define if you have the `sigaction' function. */
+#undef HAVE_SIGACTION
+
+/* Define if you have the `signal' function. */
+#define HAVE_SIGNAL
+
+/* Define if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H
+
+/* Define if sig_atomic_t is an available typedef. */
+#define HAVE_SIG_ATOMIC_T
+
+/* Define if sig_atomic_t is already defined as volatile. */
+#undef HAVE_SIG_ATOMIC_T_VOLATILE
+
+/* Define if you have the `socket' function. */
+#define HAVE_SOCKET
+
+/* Define if you have the <ssl.h> header file. */
+#undef HAVE_SSL_H
+
+/* Define if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H
+
+/* Define if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the `strcmpi' function. */
+#undef HAVE_STRCMPI
+
+/* Define if you have the `strdup' function. */
+#define HAVE_STRDUP
+
+/* Define if you have the `strftime' function. */
+#define HAVE_STRFTIME
+
+/* Define if you have the `stricmp' function. */
+#define HAVE_STRICMP
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <string.h> header file. */
+#define HAVE_STRING_H
+
+/* Define if you have the `strlcpy' function. */
+#undef HAVE_STRLCPY
+
+/* Define if you have the `strstr' function. */
+#define HAVE_STRSTR
+
+/* Define if you have the `strtok_r' function. */
+#undef HAVE_STRTOK_R
+
+/* Define if you have the `strtoll' function. */
+#undef HAVE_STRTOLL
+
+/* Define if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H
+
+/* Define if you have the <sys/sockio.h> header file. */
+#undef HAVE_SYS_SOCKIO_H
+
+/* Define if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H
+
+/* Define if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H
+
+/* Define if you have the `tcgetattr' function. */
+#define HAVE_TCGETATTR
+
+/* Define if you have the `tcsetattr' function. */
+#define HAVE_TCSETATTR
+
+/* Define if you have the <termios.h> header file. */
+#define HAVE_TERMIOS_H
+
+/* Define if you have the <termio.h> header file. */
+#undef HAVE_TERMIO_H
+
+/* Define if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
+/* Define if you have the `uname' function. */
+#define HAVE_UNAME
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H
+
+/* Define if you have the <winsock.h> header file. */
+#undef HAVE_WINSOCK_H
+
+/* Define if you have the <x509.h> header file. */
+#undef HAVE_X509_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* The size of `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of `long double', as computed by sizeof. */
+#undef SIZEOF_LONG_DOUBLE
+
+/* The size of `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
+
+/* The size of `short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* The size of `size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T 4
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Version number of package */
+#undef VERSION
+
+/* Define if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef ssize_t
+
+/* Define if you have the ioctl function. */
+#define HAVE_IOCTL
+
+/* Define if you have a working ioctl FIONBIO function. */
+#define HAVE_IOCTL_FIONBIO
+
+/* to disable LDAP */
+#define CURL_DISABLE_LDAP
+
+/* Define if you have the getnameinfo function. */
+#define HAVE_GETNAMEINFO 1
+
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+#define GETNAMEINFO_QUAL_ARG1 const
+
+/* Define to the type of arg 1 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+
+/* Define to the type of arg 2 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG2 socklen_t
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG46 size_t
+
+/* Define to the type of arg 7 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG7 int
+
+/* Define if you have the recv function. */
+#define HAVE_RECV 1
+
+/* Define to the type of arg 1 for recv. */
+#define RECV_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for recv. */
+#define RECV_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for recv. */
+#define RECV_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recv. */
+#define RECV_TYPE_ARG4 int
+
+/* Define to the function return type for recv. */
+#define RECV_TYPE_RETV ssize_t
+
+/* Define 1 if you have the recvfrom function. */
+#define HAVE_RECVFROM 1
+
+/* Define to the type of arg 1 for recvfrom. */
+#define RECVFROM_TYPE_ARG1 int
+
+/* Define to the type pointed by arg 2 for recvfrom. */
+#define RECVFROM_TYPE_ARG2 void
+
+/* Define if the type pointed by arg 2 for recvfrom is void. */
+#define RECVFROM_TYPE_ARG2_IS_VOID
+
+/* Define to the type of arg 3 for recvfrom. */
+#define RECVFROM_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recvfrom. */
+#define RECVFROM_TYPE_ARG4 int
+
+/* Define to the type pointed by arg 5 for recvfrom. */
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+
+/* Define to the type pointed by arg 6 for recvfrom. */
+#define RECVFROM_TYPE_ARG6 int
+
+/* Define to the function return type for recvfrom. */
+#define RECVFROM_TYPE_RETV ssize_t
+
+/* Define if you have the send function. */
+#define HAVE_SEND 1
+
+/* Define to the type of arg 1 for send. */
+#define SEND_TYPE_ARG1 int
+
+/* Define to the type qualifier of arg 2 for send. */
+#define SEND_QUAL_ARG2 const
+
+/* Define to the type of arg 2 for send. */
+#define SEND_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for send. */
+#define SEND_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for send. */
+#define SEND_TYPE_ARG4 int
+
+/* Define to the function return type for send. */
+#define SEND_TYPE_RETV ssize_t
+
+#endif /* HEADER_CURL_CONFIG_RISCOS_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/config-tpf.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/config-tpf.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/config-tpf.h	(revision 331)
@@ -0,0 +1,775 @@
+#ifndef HEADER_CURL_CONFIG_TPF_H
+#define HEADER_CURL_CONFIG_TPF_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* ================================================================ */
+/*                 Hand crafted config file for TPF                 */
+/* ================================================================ */
+
+/* ---------------------------------------------------------------- */
+/*            FEATURES, FUNCTIONS, and DEFINITIONS                  */
+/* ---------------------------------------------------------------- */
+
+/* NOTE: Refer also to the .mak file for some of the flags below */
+
+/* to disable cookies support */
+/* #undef CURL_DISABLE_COOKIES */
+
+/* to disable cryptographic authentication */
+/* #undef CURL_DISABLE_CRYPTO_AUTH */
+
+/* to disable DICT */
+/* #undef CURL_DISABLE_DICT */
+
+/* to disable FILE */
+/* #undef CURL_DISABLE_FILE */
+
+/* to disable FTP */
+/* #undef CURL_DISABLE_FTP */
+
+/* to disable HTTP */
+/* #undef CURL_DISABLE_HTTP */
+
+/* to disable LDAP */
+/* #undef CURL_DISABLE_LDAP */
+
+/* to disable TELNET */
+/* #undef CURL_DISABLE_TELNET */
+
+/* to disable TFTP */
+/* #undef CURL_DISABLE_TFTP */
+
+/* to disable verbose strings */
+/* #undef CURL_DISABLE_VERBOSE_STRINGS */
+
+/* lber dynamic library file */
+/* #undef DL_LBER_FILE */
+
+/* ldap dynamic library file */
+/* #undef DL_LDAP_FILE */
+
+/* your Entropy Gathering Daemon socket pathname */
+/* #undef EGD_SOCKET */
+
+/* Define if you want to enable IPv6 support */
+/* #undef ENABLE_IPV6 */
+
+/* Define if struct sockaddr_in6 has the sin6_scope_id member */
+/* #undef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID */
+
+/* Define to the type of arg 1 for getnameinfo. */
+/* #undef GETNAMEINFO_TYPE_ARG1 */
+
+/* Define to the type of arg 2 for getnameinfo. */
+/* #undef GETNAMEINFO_TYPE_ARG2 */
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+/* #undef GETNAMEINFO_TYPE_ARG46 */
+
+/* Define to the type of arg 7 for getnameinfo. */
+/* #undef GETNAMEINFO_TYPE_ARG7 */
+
+/* Define to 1 if you have the alarm function. */
+#define HAVE_ALARM 1
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <arpa/tftp.h> header file. */
+/* #undef HAVE_ARPA_TFTP_H */
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the `basename' function. */
+#define HAVE_BASENAME 1
+
+/* Define to 1 if you have the `closesocket' function. */
+/* #undef HAVE_CLOSESOCKET */
+
+/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
+/* #undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA */
+#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1
+
+/* Define to 1 if you have the <crypto.h> header file. */
+/* #undef HAVE_CRYPTO_H */
+#define HAVE_CRYPTO_H 1
+
+/* Define to 1 if you have the <des.h> header file. */
+/* #undef HAVE_DES_H */
+#define HAVE_DES_H 1
+
+/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
+/* #undef HAVE_ENGINE_LOAD_BUILTIN_ENGINES */
+#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the <err.h> header file. */
+/* #undef HAVE_ERR_H */
+#define HAVE_ERR_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the fcntl function. */
+#define HAVE_FCNTL 1
+
+/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
+#define HAVE_FCNTL_O_NONBLOCK 1
+
+/* Define to 1 if you have the `fork' function. */
+/* #undef HAVE_FORK */
+#define HAVE_FORK 1
+
+/* Define to 1 if you have the `ftruncate' function. */
+#define HAVE_FTRUNCATE 1
+
+/* Define if getaddrinfo exists and works */
+/* #undef HAVE_GETADDRINFO */
+
+/* Define to 1 if you have the `geteuid' function. */
+#define HAVE_GETEUID 1
+
+/* Define to 1 if you have the `gethostbyaddr' function. */
+#define HAVE_GETHOSTBYADDR 1
+
+/* If you have gethostbyname */
+#define HAVE_GETHOSTBYNAME 1
+
+/* Define to 1 if you have the `gethostbyname_r' function. */
+/* #undef HAVE_GETHOSTBYNAME_R */
+
+/* gethostbyname_r() takes 3 args */
+/* #undef HAVE_GETHOSTBYNAME_R_3 */
+
+/* gethostbyname_r() takes 5 args */
+/* #undef HAVE_GETHOSTBYNAME_R_5 */
+
+/* gethostbyname_r() takes 6 args */
+/* #undef HAVE_GETHOSTBYNAME_R_6 1 */
+
+/* Define to 1 if you have the getnameinfo function. */
+/* #undef HAVE_GETNAMEINFO */
+
+/* Define to 1 if you have the `getpass_r' function. */
+/* #undef HAVE_GETPASS_R */
+
+/* Define to 1 if you have the `getprotobyname' function. */
+/* #undef HAVE_GETPROTOBYNAME */
+
+/* Define to 1 if you have the `getpwuid' function. */
+#define HAVE_GETPWUID 1
+
+/* Define to 1 if you have the `getrlimit' function. */
+/* #undef HAVE_GETRLIMIT */
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* we have a glibc-style strerror_r() */
+/* #undef HAVE_GLIBC_STRERROR_R */
+#define HAVE_GLIBC_STRERROR_R 1
+
+/* Define to 1 if you have the `gmtime_r' function. */
+#define HAVE_GMTIME_R 1
+
+/* if you have the gssapi libraries */
+/* #undef HAVE_GSSAPI */
+
+/* if you have the GNU gssapi libraries */
+/* #undef HAVE_GSSGNU */
+
+/* if you have the Heimdal gssapi libraries */
+/* #undef HAVE_GSSHEIMDAL */
+
+/* if you have the MIT gssapi libraries */
+/* #undef HAVE_GSSMIT */
+
+/* Define to 1 if you have the `iconv' functions. */
+#define HAVE_ICONV 1
+
+/* Define to 1 if you have the `idna_strerror' function. */
+/* #undef HAVE_IDNA_STRERROR */
+
+/* Define to 1 if you have the `idn_free' function. */
+/* #undef HAVE_IDN_FREE */
+
+/* Define to 1 if you have the <idn-free.h> header file. */
+/* #undef HAVE_IDN_FREE_H */
+
+/* Define to 1 if you have the `inet_addr' function. */
+#define HAVE_INET_ADDR 1
+
+/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
+/* #undef HAVE_INET_NTOP */
+
+/* Define to 1 if you have a IPv6 capable working inet_pton function. */
+/* #undef HAVE_INET_PTON */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the ioctl function. */
+#define HAVE_IOCTL 1
+
+/* Define to 1 if you have a working ioctl FIONBIO function. */
+#define HAVE_IOCTL_FIONBIO 1
+
+/* Define to 1 if you have the ioctlsocket function. */
+/* #undef HAVE_IOCTLSOCKET */
+
+/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
+/* #undef HAVE_IOCTLSOCKET_FIONBIO */
+
+/* Define to 1 if you have the IoctlSocket camel case function. */
+/* #undef HAVE_IOCTLSOCKET_CAMEL */
+
+/* Define to 1 if you have a working IoctlSocket camel case FIONBIO
+   function. */
+/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
+
+/* Define to 1 if you have the <io.h> header file. */
+/* #undef HAVE_IO_H */
+
+/* if you have the Kerberos4 libraries (including -ldes) */
+/* #undef HAVE_KRB4 */
+
+/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
+/* #undef HAVE_KRB_GET_OUR_IP_FOR_REALM */
+
+/* Define to 1 if you have the <krb.h> header file. */
+/* #undef HAVE_KRB_H */
+
+/* Define to 1 if you have the <libgen.h> header file. */
+/* #undef HAVE_LIBGEN_H 1 */
+
+/* Define to 1 if you have the `idn' library (-lidn). */
+/* #undef HAVE_LIBIDN */
+
+/* Define to 1 if you have the `resolv' library (-lresolv). */
+/* #undef HAVE_LIBRESOLV */
+
+/* Define to 1 if you have the `resolve' library (-lresolve). */
+/* #undef HAVE_LIBRESOLVE */
+
+/* Define to 1 if you have the `socket' library (-lsocket). */
+/* #undef HAVE_LIBSOCKET */
+
+/* Define to 1 if you have the `ssl' library (-lssl). */
+/* #undef HAVE_LIBSSL */
+#define HAVE_LIBSSL 1
+
+/* if zlib is available */
+/* #undef HAVE_LIBZ */
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* if your compiler supports LL */
+#define HAVE_LL 1
+
+/* Define to 1 if you have the <locale.h> header file. */
+#define HAVE_LOCALE_H 1
+
+/* Define to 1 if you have the `localtime_r' function. */
+#define HAVE_LOCALTIME_R 1
+
+/* Define to 1 if the compiler supports the 'long long' data type. */
+#define HAVE_LONGLONG 1
+
+/* Define to 1 if you need the malloc.h header file even with stdlib.h  */
+/* #undef NEED_MALLOC_H */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+/* undef HAVE_NETINET_TCP_H */
+
+/* Define to 1 if you have the <net/if.h> header file. */
+#define HAVE_NET_IF_H 1
+
+/* Define if NI_WITHSCOPEID exists and works */
+/* #undef HAVE_NI_WITHSCOPEID */
+
+/* we have no strerror_r() proto */
+/* #undef HAVE_NO_STRERROR_R_DECL */
+
+/* Define to 1 if you have the <openssl/crypto.h> header file. */
+/* #undef HAVE_OPENSSL_CRYPTO_H */
+#define HAVE_OPENSSL_CRYPTO_H 1
+
+/* Define to 1 if you have the <openssl/engine.h> header file. */
+/* #undef HAVE_OPENSSL_ENGINE_H */
+#define HAVE_OPENSSL_ENGINE_H 1
+
+/* Define to 1 if you have the <openssl/err.h> header file. */
+/* #undef HAVE_OPENSSL_ERR_H */
+#define HAVE_OPENSSL_ERR_H 1
+
+/* Define to 1 if you have the <openssl/pem.h> header file. */
+/* #undef HAVE_OPENSSL_PEM_H */
+#define HAVE_OPENSSL_PEM_H 1
+
+/* Define to 1 if you have the <openssl/pkcs12.h> header file. */
+/* #undef HAVE_OPENSSL_PKCS12_H */
+#define HAVE_OPENSSL_PKCS12_H 1
+
+/* Define to 1 if you have the <openssl/rsa.h> header file. */
+/* #undef HAVE_OPENSSL_RSA_H */
+#define HAVE_OPENSSL_RSA_H 1
+
+/* Define to 1 if you have the <openssl/ssl.h> header file. */
+/* #undef HAVE_OPENSSL_SSL_H */
+#define HAVE_OPENSSL_SSL_H 1
+
+/* Define to 1 if you have the <openssl/x509.h> header file. */
+/* #undef HAVE_OPENSSL_X509_H */
+#define HAVE_OPENSSL_X509_H 1
+
+/* Define to 1 if you have the <pem.h> header file. */
+/* #undef HAVE_PEM_H */
+#define HAVE_PEM_H 1
+
+/* Define to 1 if you have the `perror' function. */
+#define HAVE_PERROR 1
+
+/* Define to 1 if you have the `pipe' function. */
+#define HAVE_PIPE 1
+
+/* Define to 1 if you have the `poll' function. */
+/* #undef HAVE_POLL */
+
+/* If you have a fine poll */
+/* #undef HAVE_POLL_FINE */
+
+/* we have a POSIX-style strerror_r() */
+/* #undef HAVE_POSIX_STRERROR_R */
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#define HAVE_PWD_H 1
+
+/* Define to 1 if you have the `RAND_egd' function. */
+/* #undef HAVE_RAND_EGD */
+#define HAVE_RAND_EGD 1
+
+/* Define to 1 if you have the `RAND_screen' function. */
+/* #undef HAVE_RAND_SCREEN */
+
+/* Define to 1 if you have the `RAND_status' function. */
+/* #undef HAVE_RAND_STATUS */
+#define HAVE_RAND_STATUS 1
+
+/* Define to 1 if you have the <rsa.h> header file. */
+/* #undef HAVE_RSA_H */
+#define HAVE_RSA_H 1
+
+/* Define to 1 if you have the `select' function. */
+#define HAVE_SELECT 1
+
+/* Define to 1 if you have the <setjmp.h> header file. */
+#define HAVE_SETJMP_H 1
+
+/* Define to 1 if you have the `setlocale' function. */
+#define HAVE_SETLOCALE 1
+
+/* Define to 1 if you have the `setrlimit' function. */
+#define HAVE_SETRLIMIT 1
+
+/* Define to 1 if you have the setsockopt function. */
+/* #undef HAVE_SETSOCKOPT */
+
+/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
+/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */
+
+/* Define to 1 if you have the <sgtty.h> header file. */
+/* #undef HAVE_SGTTY_H 1 */
+
+/* Define to 1 if you have the `sigaction' function. */
+#define HAVE_SIGACTION 1
+
+/* Define to 1 if you have the `siginterrupt' function. */
+/* #undef HAVE_SIGINTERRUPT */
+
+/* Define to 1 if you have the `signal' function. */
+#define HAVE_SIGNAL 1
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define to 1 if sig_atomic_t is an available typedef. */
+#define HAVE_SIG_ATOMIC_T 1
+
+/* Define to 1 if sig_atomic_t is already defined as volatile. */
+/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */
+
+/* If you have sigsetjmp */
+/* #undef HAVE_SIGSETJMP */
+
+/* Define to 1 if you have the `socket' function. */
+#define HAVE_SOCKET 1
+
+/* Define to 1 if you have the <ssl.h> header file. */
+/* #undef HAVE_SSL_H */
+#define HAVE_SSL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the `strcmpi' function. */
+/* #undef HAVE_STRCMPI */
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strerror_r' function. */
+#define HAVE_STRERROR_R 1
+
+/* Define to 1 if you have the `stricmp' function. */
+/* #undef HAVE_STRICMP */
+#define HAVE_STRICMP 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strlcpy' function. */
+/* #undef HAVE_STRLCPY */
+
+/* Define to 1 if you have the `strstr' function. */
+#define HAVE_STRSTR 1
+
+/* Define to 1 if you have the `strtok_r' function. */
+#define HAVE_STRTOK_R 1
+
+/* Define to 1 if you have the `strtoll' function. */
+#define HAVE_STRTOLL 1
+
+/* if struct sockaddr_storage is defined */
+/* #undef HAVE_STRUCT_SOCKADDR_STORAGE */
+
+/* Define this if you have struct timeval */
+#define HAVE_STRUCT_TIMEVAL 1
+
+/* Define to 1 if you have the <sys/filio.h> header file. */
+#define HAVE_SYS_FILIO_H 1
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+/* #undef HAVE_SYS_POLL_H */
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/sockio.h> header file. */
+/* #undef HAVE_SYS_SOCKIO_H */
+#define HAVE_SYS_SOCKIO_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/utime.h> header file. */
+/* #undef HAVE_SYS_UTIME_H */
+
+/* Define to 1 if you have the <termios.h> header file. */
+/* #undef HAVE_TERMIOS_H */
+
+/* Define to 1 if you have the <termio.h> header file. */
+/* #undef HAVE_TERMIO_H */
+
+/* Define to 1 if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Define to 1 if you have the <tld.h> header file. */
+/* #undef HAVE_TLD_H */
+
+/* Define to 1 if you have the `tld_strerror' function. */
+/* #undef HAVE_TLD_STRERROR */
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `utime' function. */
+#define HAVE_UTIME 1
+
+/* Define to 1 if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* Define to 1 if you have the <winsock2.h> header file. */
+/* #undef HAVE_WINSOCK2_H */
+
+/* Define to 1 if you have the <winsock.h> header file. */
+/* #undef HAVE_WINSOCK_H */
+
+/* Define this symbol if your OS supports changing the contents of argv */
+/* #undef HAVE_WRITABLE_ARGV */
+
+/* Define to 1 if you have the ws2tcpip.h header file. */
+/* #undef HAVE_WS2TCPIP_H */
+
+/* Define to 1 if you have the <x509.h> header file. */
+/* #undef HAVE_X509_H */
+
+/* if you have the zlib.h header file */
+/* #undef HAVE_ZLIB_H */
+
+/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
+/* #undef NEED_REENTRANT */
+
+/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */
+/* #undef NEED_THREAD_SAFE */
+
+/* cpu-machine-OS */
+#define OS "s390x-ibm-tpf"
+
+/* Name of package */
+#define PACKAGE "curl"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT \
+  "a suitable curl mailing list => https://curl.haxx.se/mail/"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "curl"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "curl -"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "curl"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "-"
+
+/* a suitable file to read random data from */
+/* #undef RANDOM_FILE */
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* Define to the type of arg 1 for `select'. */
+#define SELECT_TYPE_ARG1 int
+
+/* Define to the type of args 2, 3 and 4 for `select'. */
+#define SELECT_TYPE_ARG234 (fd_set *)
+
+/* Define to the type of arg 5 for `select'. */
+#define SELECT_TYPE_ARG5 (struct timeval *)
+
+/* The size of `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of `off_t', as computed by sizeof. */
+#define SIZEOF_OFF_T 8
+
+/* The size of `short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* Define to the size of `long', as computed by sizeof. */
+#define SIZEOF_LONG 8
+
+/* The size of `size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T 8
+
+/* The size of `time_t', as computed by sizeof. */
+#define SIZEOF_TIME_T 8
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define if you want to enable ares support */
+/* #undef USE_ARES */
+
+/* Define to disable non-blocking sockets */
+/* #undef USE_BLOCKING_SOCKETS */
+
+/* if GnuTLS is enabled */
+/* #undef USE_GNUTLS */
+
+/* If you want to build curl with the built-in manual */
+/* #undef USE_MANUAL */
+
+/* if OpenSSL is in use */
+/* #undef USE_OPENSSL */
+
+/* if SSL is enabled */
+/* #undef USE_OPENSSL */
+
+/* to enable SSPI support */
+/* #undef USE_WINDOWS_SSPI */
+
+/* Version number of package */
+#define VERSION "not-used"
+
+/* Define to avoid automatic inclusion of winsock.h */
+/* #undef WIN32_LEAN_AND_MEAN */
+
+/* Define to 1 if on AIX 3.
+   System headers sometimes define this.
+   We just want to avoid a redefinition error message.  */
+#ifndef _ALL_SOURCE
+/* # undef _ALL_SOURCE */
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* type to use in place of in_addr_t if not defined */
+/* #undef in_addr_t */
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* the signed version of size_t */
+/* #undef ssize_t */
+
+/* Define to 1 if you have the getnameinfo function. */
+/* #undef HAVE_GETNAMEINFO 1 */
+
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+/* #undef GETNAMEINFO_QUAL_ARG1 const */
+
+/* Define to the type of arg 1 for getnameinfo. */
+/* #undef GETNAMEINFO_TYPE_ARG1 struct sockaddr * */
+
+/* Define to the type of arg 2 for getnameinfo. */
+/* #undef GETNAMEINFO_TYPE_ARG2 socklen_t */
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+/* #undef GETNAMEINFO_TYPE_ARG46 size_t */
+
+/* Define to the type of arg 7 for getnameinfo. */
+/* #undef GETNAMEINFO_TYPE_ARG7 int */
+
+/* Define to 1 if you have the recv function. */
+#define HAVE_RECV 1
+
+/* Define to the type of arg 1 for recv. */
+#define RECV_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for recv. */
+#define RECV_TYPE_ARG2 char *
+
+/* Define to the type of arg 3 for recv. */
+#define RECV_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for recv. */
+#define RECV_TYPE_ARG4 int
+
+/* Define to the function return type for recv. */
+#define RECV_TYPE_RETV int
+
+/* Define to 1 if you have the recvfrom function. */
+#define HAVE_RECVFROM 1
+
+/* Define to the type of arg 1 for recvfrom. */
+#define RECVFROM_TYPE_ARG1 int
+
+/* Define to the type pointed by arg 2 for recvfrom. */
+#define RECVFROM_TYPE_ARG2 char
+
+/* Define to the type of arg 3 for recvfrom. */
+#define RECVFROM_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for recvfrom. */
+#define RECVFROM_TYPE_ARG4 int
+
+/* Define to the type pointed by arg 5 for recvfrom. */
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+
+/* Define to the type pointed by arg 6 for recvfrom. */
+#define RECVFROM_TYPE_ARG6 int
+
+/* Define to the function return type for recvfrom. */
+#define RECVFROM_TYPE_RETV int
+
+/* Define to 1 if you have the send function. */
+#define HAVE_SEND 1
+
+/* Define to the type of arg 1 for send. */
+#define SEND_TYPE_ARG1 int
+
+/* Define to the type qualifier of arg 2 for send. */
+#define SEND_QUAL_ARG2 const
+
+/* Define to the type of arg 2 for send. */
+#define SEND_TYPE_ARG2 char *
+
+/* Define to the type of arg 3 for send. */
+#define SEND_TYPE_ARG3 int
+
+/* Define to the type of arg 4 for send. */
+#define SEND_TYPE_ARG4 int
+
+/* Define to the function return type for send. */
+#define SEND_TYPE_RETV int
+
+#define CURL_DOES_CONVERSIONS
+#ifndef CURL_ICONV_CODESET_OF_HOST
+#define CURL_ICONV_CODESET_OF_HOST "IBM-1047"
+#endif
+
+
+#endif /* HEADER_CURL_CONFIG_TPF_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/config-vxworks.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/config-vxworks.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/config-vxworks.h	(revision 331)
@@ -0,0 +1,928 @@
+#ifndef HEADER_CURL_CONFIG_VXWORKS_H
+#define HEADER_CURL_CONFIG_VXWORKS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* =============================================================== */
+/*               Hand crafted config file for VxWorks              */
+/* =============================================================== */
+
+/* Location of default ca bundle */
+/* #undef CURL_CA_BUNDLE */
+
+/* Location of default ca path */
+/* #undef CURL_CA_PATH */
+
+/* to disable cookies support */
+/* #undef CURL_DISABLE_COOKIES */
+
+/* to disable cryptographic authentication */
+/* #undef CURL_DISABLE_CRYPTO_AUTH */
+
+/* to disable DICT */
+/* #undef CURL_DISABLE_DICT */
+
+/* to disable FILE */
+/* #undef CURL_DISABLE_FILE */
+
+/* to disable FTP */
+#define CURL_DISABLE_FTP 1
+
+/* to disable HTTP */
+/* #undef CURL_DISABLE_HTTP */
+
+/* to disable LDAP */
+#define CURL_DISABLE_LDAP 1
+
+/* to disable LDAPS */
+#define CURL_DISABLE_LDAPS 1
+
+/* to disable NTLM authentication */
+#define CURL_DISABLE_NTLM 1
+
+/* to disable proxies */
+/* #undef CURL_DISABLE_PROXY */
+
+/* to disable TELNET */
+#define CURL_DISABLE_TELNET 1
+
+/* to disable TFTP */
+#define CURL_DISABLE_TFTP 1
+
+/* to disable verbose strings */
+/* #undef CURL_DISABLE_VERBOSE_STRINGS */
+
+/* Definition to make a library symbol externally visible. */
+/* #undef CURL_EXTERN_SYMBOL */
+
+/* Use Windows LDAP implementation */
+/* #undef USE_WIN32_LDAP */
+
+/* your Entropy Gathering Daemon socket pathname */
+/* #undef EGD_SOCKET */
+
+/* Define if you want to enable IPv6 support */
+#define ENABLE_IPV6 1
+
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+#define GETNAMEINFO_QUAL_ARG1 const
+
+/* Define to the type of arg 1 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+
+/* Define to the type of arg 2 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG2 socklen_t
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG46 size_t
+
+/* Define to the type of arg 7 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG7 unsigned int
+
+/* Specifies the number of arguments to getservbyport_r */
+#define GETSERVBYPORT_R_ARGS 6
+
+/* Specifies the size of the buffer to pass to getservbyport_r */
+#define GETSERVBYPORT_R_BUFSIZE 4096
+
+/* Define to 1 if you have the alarm function. */
+#define HAVE_ALARM 1
+
+/* Define to 1 if you have the <alloca.h> header file. */
+#define HAVE_ALLOCA_H 1
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <arpa/tftp.h> header file. */
+/* #undef HAVE_ARPA_TFTP_H */
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the `basename' function. */
+/* #undef HAVE_BASENAME */
+
+/* Define to 1 if bool is an available type. */
+#define HAVE_BOOL_T 1
+
+/* Define to 1 if you have the clock_gettime function and monotonic timer. */
+/* #undef HAVE_CLOCK_GETTIME_MONOTONIC */
+
+/* Define to 1 if you have the `closesocket' function. */
+/* #undef HAVE_CLOSESOCKET */
+
+/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
+#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1
+
+/* Define to 1 if you have the <crypto.h> header file. */
+/* #undef HAVE_CRYPTO_H */
+
+/* Define to 1 if you have the <des.h> header file. */
+/* #undef HAVE_DES_H */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
+#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the <err.h> header file. */
+/* #undef HAVE_ERR_H */
+
+/* Define to 1 if you have the fcntl function. */
+#define HAVE_FCNTL 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
+#define HAVE_FCNTL_O_NONBLOCK 1
+
+/* Define to 1 if you have the fdopen function. */
+#define HAVE_FDOPEN 1
+
+/* Define to 1 if you have the `fork' function. */
+#define HAVE_FORK 1
+
+/* Define to 1 if you have the freeaddrinfo function. */
+#define HAVE_FREEADDRINFO 1
+
+/* Define to 1 if you have the freeifaddrs function. */
+#define HAVE_FREEIFADDRS 1
+
+/* Define to 1 if you have the ftruncate function. */
+#define HAVE_FTRUNCATE 1
+
+/* Define to 1 if you have a working getaddrinfo function. */
+#define HAVE_GETADDRINFO 1
+
+/* Define to 1 if you have the `geteuid' function. */
+/* #undef HAVE_GETEUID */
+
+/* Define to 1 if you have the gethostbyaddr function. */
+#define HAVE_GETHOSTBYADDR 1
+
+/* Define to 1 if you have the gethostbyaddr_r function. */
+#define HAVE_GETHOSTBYADDR_R 1
+
+/* gethostbyaddr_r() takes 5 args */
+/* #undef HAVE_GETHOSTBYADDR_R_5 */
+
+/* gethostbyaddr_r() takes 7 args */
+/* #undef HAVE_GETHOSTBYADDR_R_7 */
+
+/* gethostbyaddr_r() takes 8 args */
+#define HAVE_GETHOSTBYADDR_R_8 1
+
+/* Define to 1 if you have the gethostbyname function. */
+#define HAVE_GETHOSTBYNAME 1
+
+/* Define to 1 if you have the gethostbyname_r function. */
+/* #undef HAVE_GETHOSTBYNAME_R */
+
+/* gethostbyname_r() takes 3 args */
+/* #undef HAVE_GETHOSTBYNAME_R_3 */
+
+/* gethostbyname_r() takes 5 args */
+/* #undef HAVE_GETHOSTBYNAME_R_5 */
+
+/* gethostbyname_r() takes 6 args */
+/* #undef HAVE_GETHOSTBYNAME_R_6 */
+
+/* Define to 1 if you have the gethostname function. */
+#define HAVE_GETHOSTNAME 1
+
+/* Define to 1 if you have a working getifaddrs function. */
+/* #undef HAVE_GETIFADDRS */
+
+/* Define to 1 if you have the getnameinfo function. */
+#define HAVE_GETNAMEINFO 1
+
+/* Define to 1 if you have the `getpass_r' function. */
+/* #undef HAVE_GETPASS_R */
+
+/* Define to 1 if you have the `getppid' function. */
+#define HAVE_GETPPID 1
+
+/* Define to 1 if you have the `getprotobyname' function. */
+#define HAVE_GETPROTOBYNAME 1
+
+/* Define to 1 if you have the `getpwuid' function. */
+/* #undef HAVE_GETPWUID */
+
+/* Define to 1 if you have the `getrlimit' function. */
+#define HAVE_GETRLIMIT 1
+
+/* Define to 1 if you have the getservbyport_r function. */
+/* #undef HAVE_GETSERVBYPORT_R */
+
+/* Define to 1 if you have the `gettimeofday' function. */
+/* #undef HAVE_GETTIMEOFDAY */
+
+/* Define to 1 if you have a working glibc-style strerror_r function. */
+/* #undef HAVE_GLIBC_STRERROR_R */
+
+/* Define to 1 if you have a working gmtime_r function. */
+#define HAVE_GMTIME_R 1
+
+/* if you have the gssapi libraries */
+/* #undef HAVE_GSSAPI */
+
+/* Define to 1 if you have the <gssapi/gssapi_generic.h> header file. */
+/* #undef HAVE_GSSAPI_GSSAPI_GENERIC_H */
+
+/* Define to 1 if you have the <gssapi/gssapi.h> header file. */
+/* #undef HAVE_GSSAPI_GSSAPI_H */
+
+/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */
+/* #undef HAVE_GSSAPI_GSSAPI_KRB5_H */
+
+/* if you have the GNU gssapi libraries */
+/* #undef HAVE_GSSGNU */
+
+/* if you have the Heimdal gssapi libraries */
+/* #undef HAVE_GSSHEIMDAL */
+
+/* if you have the MIT gssapi libraries */
+/* #undef HAVE_GSSMIT */
+
+/* Define to 1 if you have the `idna_strerror' function. */
+/* #undef HAVE_IDNA_STRERROR */
+
+/* Define to 1 if you have the `idn_free' function. */
+/* #undef HAVE_IDN_FREE */
+
+/* Define to 1 if you have the <idn-free.h> header file. */
+/* #undef HAVE_IDN_FREE_H */
+
+/* Define to 1 if you have the <ifaddrs.h> header file. */
+/* #undef HAVE_IFADDRS_H */
+
+/* Define to 1 if you have the `inet_addr' function. */
+#define HAVE_INET_ADDR 1
+
+/* Define to 1 if you have the inet_ntoa_r function. */
+/* #undef HAVE_INET_NTOA_R */
+
+/* inet_ntoa_r() takes 2 args */
+/* #undef HAVE_INET_NTOA_R_2 */
+
+/* inet_ntoa_r() takes 3 args */
+/* #undef HAVE_INET_NTOA_R_3 */
+
+/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
+/* #undef HAVE_INET_NTOP */
+
+/* Define to 1 if you have a IPv6 capable working inet_pton function. */
+/* #undef HAVE_INET_PTON */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the ioctl function. */
+#define HAVE_IOCTL 1
+
+/* Define to 1 if you have the ioctlsocket function. */
+/* #undef HAVE_IOCTLSOCKET */
+
+/* Define to 1 if you have the IoctlSocket camel case function. */
+/* #undef HAVE_IOCTLSOCKET_CAMEL */
+
+/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function.
+   */
+/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
+
+/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
+/* #undef HAVE_IOCTLSOCKET_FIONBIO */
+
+/* Define to 1 if you have a working ioctl FIONBIO function. */
+#define HAVE_IOCTL_FIONBIO 1
+
+/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */
+#define HAVE_IOCTL_SIOCGIFADDR 1
+
+/* Define to 1 if you have the <io.h> header file. */
+#define HAVE_IO_H 1
+
+/* if you have the Kerberos4 libraries (including -ldes) */
+/* #undef HAVE_KRB4 */
+
+/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */
+/* #undef HAVE_KRB_GET_OUR_IP_FOR_REALM */
+
+/* Define to 1 if you have the <krb.h> header file. */
+/* #undef HAVE_KRB_H */
+
+/* Define to 1 if you have the lber.h header file. */
+/* #undef HAVE_LBER_H */
+
+/* Define to 1 if you have the ldapssl.h header file. */
+/* #undef HAVE_LDAPSSL_H */
+
+/* Define to 1 if you have the ldap.h header file. */
+/* #undef HAVE_LDAP_H */
+
+/* Use LDAPS implementation */
+/* #undef HAVE_LDAP_SSL */
+
+/* Define to 1 if you have the ldap_ssl.h header file. */
+/* #undef HAVE_LDAP_SSL_H */
+
+/* Define to 1 if you have the `ldap_url_parse' function. */
+/* #undef HAVE_LDAP_URL_PARSE */
+
+/* Define to 1 if you have the <libgen.h> header file. */
+/* #undef HAVE_LIBGEN_H */
+
+/* Define to 1 if you have the `idn' library (-lidn). */
+/* #undef HAVE_LIBIDN */
+
+/* Define to 1 if you have the `resolv' library (-lresolv). */
+/* #undef HAVE_LIBRESOLV */
+
+/* Define to 1 if you have the `resolve' library (-lresolve). */
+/* #undef HAVE_LIBRESOLVE */
+
+/* Define to 1 if you have the `socket' library (-lsocket). */
+/* #undef HAVE_LIBSOCKET */
+
+/* Define to 1 if you have the `ssh2' library (-lssh2). */
+/* #undef HAVE_LIBSSH2 */
+
+/* Define to 1 if you have the <libssh2.h> header file. */
+/* #undef HAVE_LIBSSH2_H */
+
+/* Define to 1 if you have the `libssh2_version' function. */
+/* #undef HAVE_LIBSSH2_VERSION */
+
+/* Define to 1 if you have the `ssl' library (-lssl). */
+#define HAVE_LIBSSL 1
+
+/* if zlib is available */
+#define HAVE_LIBZ 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* if your compiler supports LL */
+#define HAVE_LL 1
+
+/* Define to 1 if you have the <locale.h> header file. */
+#define HAVE_LOCALE_H 1
+
+/* Define to 1 if you have a working localtime_r function. */
+#define HAVE_LOCALTIME_R 1
+
+/* Define to 1 if the compiler supports the 'long long' data type. */
+#define HAVE_LONGLONG 1
+
+/* Define to 1 if you have the malloc.h header file. */
+#define HAVE_MALLOC_H 1
+
+/* Define to 1 if you have the memory.h header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the MSG_NOSIGNAL flag. */
+/* #undef HAVE_MSG_NOSIGNAL */
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+#define HAVE_NETINET_TCP_H 1
+
+/* Define to 1 if you have the <net/if.h> header file. */
+#define HAVE_NET_IF_H 1
+
+/* Define to 1 if NI_WITHSCOPEID exists and works. */
+/* #undef HAVE_NI_WITHSCOPEID */
+
+/* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE
+   */
+/* #undef HAVE_OLD_GSSMIT */
+
+/* Define to 1 if you have the <openssl/crypto.h> header file. */
+#define HAVE_OPENSSL_CRYPTO_H 1
+
+/* Define to 1 if you have the <openssl/engine.h> header file. */
+#define HAVE_OPENSSL_ENGINE_H 1
+
+/* Define to 1 if you have the <openssl/err.h> header file. */
+#define HAVE_OPENSSL_ERR_H 1
+
+/* Define to 1 if you have the <openssl/pem.h> header file. */
+#define HAVE_OPENSSL_PEM_H 1
+
+/* Define to 1 if you have the <openssl/pkcs12.h> header file. */
+#define HAVE_OPENSSL_PKCS12_H 1
+
+/* Define to 1 if you have the <openssl/rsa.h> header file. */
+#define HAVE_OPENSSL_RSA_H 1
+
+/* Define to 1 if you have the <openssl/ssl.h> header file. */
+#define HAVE_OPENSSL_SSL_H 1
+
+/* Define to 1 if you have the <openssl/x509.h> header file. */
+#define HAVE_OPENSSL_X509_H 1
+
+/* Define to 1 if you have the <pem.h> header file. */
+/* #undef HAVE_PEM_H */
+
+/* Define to 1 if you have the `perror' function. */
+#define HAVE_PERROR 1
+
+/* Define to 1 if you have the `pipe' function. */
+#define HAVE_PIPE 1
+
+/* Define to 1 if you have a working poll function. */
+/* #undef HAVE_POLL */
+
+/* If you have a fine poll */
+/* #undef HAVE_POLL_FINE */
+
+/* Define to 1 if you have the <poll.h> header file. */
+/* #undef HAVE_POLL_H */
+
+/* Define to 1 if you have a working POSIX-style strerror_r function. */
+/* #undef HAVE_POSIX_STRERROR_R */
+
+/* Define to 1 if you have the <pwd.h> header file. */
+/* #undef HAVE_PWD_H */
+
+/* Define to 1 if you have the `RAND_egd' function. */
+#define HAVE_RAND_EGD 1
+
+/* Define to 1 if you have the `RAND_screen' function. */
+/* #undef HAVE_RAND_SCREEN */
+
+/* Define to 1 if you have the `RAND_status' function. */
+#define HAVE_RAND_STATUS 1
+
+/* Define to 1 if you have the recv function. */
+#define HAVE_RECV 1
+
+/* Define to 1 if you have the recvfrom function. */
+#define HAVE_RECVFROM 1
+
+/* Define to 1 if you have the <rsa.h> header file. */
+/* #undef HAVE_RSA_H */
+
+/* Define to 1 if you have the select function. */
+#define HAVE_SELECT 1
+
+/* Define to 1 if you have the send function. */
+#define HAVE_SEND 1
+
+/* Define to 1 if you have the <setjmp.h> header file. */
+#define HAVE_SETJMP_H 1
+
+/* Define to 1 if you have the `setlocale' function. */
+#define HAVE_SETLOCALE 1
+
+/* Define to 1 if you have the `setmode' function. */
+#define HAVE_SETMODE 1
+
+/* Define to 1 if you have the `setrlimit' function. */
+#define HAVE_SETRLIMIT 1
+
+/* Define to 1 if you have the setsockopt function. */
+#define HAVE_SETSOCKOPT 1
+
+/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
+/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */
+
+/* Define to 1 if you have the <sgtty.h> header file. */
+/* #undef HAVE_SGTTY_H */
+
+/* Define to 1 if you have the sigaction function. */
+#define HAVE_SIGACTION 1
+
+/* Define to 1 if you have the siginterrupt function. */
+#define HAVE_SIGINTERRUPT 1
+
+/* Define to 1 if you have the signal function. */
+#define HAVE_SIGNAL 1
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define to 1 if you have the sigsetjmp function or macro. */
+/* #undef HAVE_SIGSETJMP */
+
+/* Define to 1 if sig_atomic_t is an available typedef. */
+#define HAVE_SIG_ATOMIC_T 1
+
+/* Define to 1 if sig_atomic_t is already defined as volatile. */
+/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */
+
+/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+
+/* Define to 1 if you have the `socket' function. */
+#define HAVE_SOCKET 1
+
+/* Define to 1 if you have the `SSL_get_shutdown' function. */
+#define HAVE_SSL_GET_SHUTDOWN 1
+
+/* Define to 1 if you have the <ssl.h> header file. */
+/* #undef HAVE_SSL_H */
+
+/* Define to 1 if you have the <stdbool.h> header file. */
+#define HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+/* #undef HAVE_STDINT_H */
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#define HAVE_STDIO_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the strcasecmp function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the strcmpi function. */
+/* #undef HAVE_STRCMPI */
+
+/* Define to 1 if you have the strdup function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the strerror_r function. */
+#define HAVE_STRERROR_R 1
+
+/* Define to 1 if you have the stricmp function. */
+/* #undef HAVE_STRICMP */
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strlcpy' function. */
+/* #undef HAVE_STRLCPY */
+
+/* Define to 1 if you have the strncasecmp function. */
+#define HAVE_STRNCASECMP 1
+
+/* Define to 1 if you have the strncmpi function. */
+/* #undef HAVE_STRNCMPI */
+
+/* Define to 1 if you have the strnicmp function. */
+/* #undef HAVE_STRNICMP */
+
+/* Define to 1 if you have the <stropts.h> header file. */
+/* #undef HAVE_STROPTS_H */
+
+/* Define to 1 if you have the strstr function. */
+#define HAVE_STRSTR 1
+
+/* Define to 1 if you have the strtok_r function. */
+#define HAVE_STRTOK_R 1
+
+/* Define to 1 if you have the strtoll function. */
+/* #undef HAVE_STRTOLL */
+
+/* if struct sockaddr_storage is defined */
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+
+/* Define to 1 if you have the timeval struct. */
+#define HAVE_STRUCT_TIMEVAL 1
+
+/* Define to 1 if you have the <sys/filio.h> header file. */
+/* #undef HAVE_SYS_FILIO_H */
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+/* #undef HAVE_SYS_PARAM_H */
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+/* #undef HAVE_SYS_POLL_H */
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+/* #undef HAVE_SYS_SELECT_H */
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/sockio.h> header file. */
+/* #undef HAVE_SYS_SOCKIO_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+/* #undef HAVE_SYS_TIME_H */
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#define HAVE_SYS_UIO_H 1
+
+/* Define to 1 if you have the <sys/un.h> header file. */
+#define HAVE_SYS_UN_H 1
+
+/* Define to 1 if you have the <sys/utime.h> header file. */
+#define HAVE_SYS_UTIME_H 1
+
+/* Define to 1 if you have the <termios.h> header file. */
+#define HAVE_TERMIOS_H 1
+
+/* Define to 1 if you have the <termio.h> header file. */
+#define HAVE_TERMIO_H 1
+
+/* Define to 1 if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Define to 1 if you have the <tld.h> header file. */
+/* #undef HAVE_TLD_H */
+
+/* Define to 1 if you have the `tld_strerror' function. */
+/* #undef HAVE_TLD_STRERROR */
+
+/* Define to 1 if you have the `uname' function. */
+#define HAVE_UNAME 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `utime' function. */
+#define HAVE_UTIME 1
+
+/* Define to 1 if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* Define to 1 if compiler supports C99 variadic macro style. */
+#define HAVE_VARIADIC_MACROS_C99 1
+
+/* Define to 1 if compiler supports old gcc variadic macro style. */
+#define HAVE_VARIADIC_MACROS_GCC 1
+
+/* Define to 1 if you have a working vxworks-style strerror_r function. */
+#define HAVE_VXWORKS_STRERROR_R 1
+
+/* Define to 1 if you have the winber.h header file. */
+/* #undef HAVE_WINBER_H */
+
+/* Define to 1 if you have the windows.h header file. */
+/* #undef HAVE_WINDOWS_H */
+
+/* Define to 1 if you have the winldap.h header file. */
+/* #undef HAVE_WINLDAP_H */
+
+/* Define to 1 if you have the winsock2.h header file. */
+/* #undef HAVE_WINSOCK2_H */
+
+/* Define to 1 if you have the winsock.h header file. */
+/* #undef HAVE_WINSOCK_H */
+
+/* Define this symbol if your OS supports changing the contents of argv */
+#define HAVE_WRITABLE_ARGV 1
+
+/* Define to 1 if you have the writev function. */
+#define HAVE_WRITEV 1
+
+/* Define to 1 if you have the ws2tcpip.h header file. */
+/* #undef HAVE_WS2TCPIP_H */
+
+/* Define to 1 if you have the <x509.h> header file. */
+/* #undef HAVE_X509_H */
+
+/* if you have the zlib.h header file */
+#define HAVE_ZLIB_H 1
+
+/* Define to 1 if you need the lber.h header file even with ldap.h */
+/* #undef NEED_LBER_H */
+
+/* Define to 1 if you need the malloc.h header file even with stdlib.h */
+/* #undef NEED_MALLOC_H */
+
+/* Define to 1 if you need the memory.h header file even with stdlib.h */
+/* #undef NEED_MEMORY_H */
+
+/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
+/* #undef NEED_REENTRANT */
+
+/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */
+/* #undef NEED_THREAD_SAFE */
+
+/* Define to 1 if the open function requires three arguments. */
+#define OPEN_NEEDS_ARG3 1
+
+/* cpu-machine-OS */
+#define OS "unknown-unknown-vxworks"
+
+/* Name of package */
+#define PACKAGE "curl"
+
+/* a suitable file to read random data from */
+#define RANDOM_FILE "/dev/urandom"
+
+/* Define to the type of arg 1 for recvfrom. */
+#define RECVFROM_TYPE_ARG1 int
+
+/* Define to the type pointed by arg 2 for recvfrom. */
+#define RECVFROM_TYPE_ARG2 void
+
+/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */
+#define RECVFROM_TYPE_ARG2_IS_VOID 1
+
+/* Define to the type of arg 3 for recvfrom. */
+#define RECVFROM_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recvfrom. */
+#define RECVFROM_TYPE_ARG4 int
+
+/* Define to the type pointed by arg 5 for recvfrom. */
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+
+/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */
+/* #undef RECVFROM_TYPE_ARG5_IS_VOID */
+
+/* Define to the type pointed by arg 6 for recvfrom. */
+#define RECVFROM_TYPE_ARG6 socklen_t
+
+/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */
+/* #undef RECVFROM_TYPE_ARG6_IS_VOID */
+
+/* Define to the function return type for recvfrom. */
+#define RECVFROM_TYPE_RETV int
+
+/* Define to the type of arg 1 for recv. */
+#define RECV_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for recv. */
+#define RECV_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for recv. */
+#define RECV_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recv. */
+#define RECV_TYPE_ARG4 int
+
+/* Define to the function return type for recv. */
+#define RECV_TYPE_RETV int
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* Define to the type qualifier of arg 5 for select. */
+#define SELECT_QUAL_ARG5
+
+/* Define to the type of arg 1 for select. */
+#define SELECT_TYPE_ARG1 int
+
+/* Define to the type of args 2, 3 and 4 for select. */
+#define SELECT_TYPE_ARG234 fd_set *
+
+/* Define to the type of arg 5 for select. */
+#define SELECT_TYPE_ARG5 struct timeval *
+
+/* Define to the function return type for select. */
+#define SELECT_TYPE_RETV int
+
+/* Define to the type qualifier of arg 2 for send. */
+#define SEND_QUAL_ARG2 const
+
+/* Define to the type of arg 1 for send. */
+#define SEND_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for send. */
+#define SEND_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for send. */
+#define SEND_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for send. */
+#define SEND_TYPE_ARG4 int
+
+/* Define to the function return type for send. */
+#define SEND_TYPE_RETV int
+
+/* The size of `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of `long', as computed by sizeof. */
+#define SIZEOF_LONG 4
+
+/* The size of `off_t', as computed by sizeof. */
+#define SIZEOF_OFF_T 8
+
+/* The size of `short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* The size of `size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T 4
+
+/* The size of `time_t', as computed by sizeof. */
+#define SIZEOF_TIME_T 4
+
+/* The size of `void*', as computed by sizeof. */
+#define SIZEOF_VOIDP 4
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to the type of arg 3 for strerror_r. */
+/* #undef STRERROR_R_TYPE_ARG3 */
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+/* #undef TIME_WITH_SYS_TIME */
+
+/* Define if you want to enable c-ares support */
+/* #undef USE_ARES */
+
+/* Define to disable non-blocking sockets. */
+/* #undef USE_BLOCKING_SOCKETS */
+
+/* if GnuTLS is enabled */
+/* #undef USE_GNUTLS */
+
+/* if libSSH2 is in use */
+/* #undef USE_LIBSSH2 */
+
+/* If you want to build curl with the built-in manual */
+#define USE_MANUAL 1
+
+/* if NSS is enabled */
+/* #undef USE_NSS */
+
+/* if OpenSSL is in use */
+#define USE_OPENSSL 1
+
+/* Define to 1 if you are building a Windows target without large file
+   support. */
+/* #undef USE_WIN32_LARGE_FILES */
+
+/* to enable SSPI support */
+/* #undef USE_WINDOWS_SSPI */
+
+/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */
+/* #undef USE_YASSLEMUL */
+
+/* Define to avoid automatic inclusion of winsock.h */
+/* #undef WIN32_LEAN_AND_MEAN */
+
+/* Define to 1 if OS is AIX. */
+#ifndef _ALL_SOURCE
+/* #  undef _ALL_SOURCE */
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Type to use in place of in_addr_t when system does not provide it. */
+/* #undef in_addr_t */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* the signed version of size_t */
+/* #undef ssize_t */
+
+#endif /* HEADER_CURL_CONFIG_VXWORKS_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/conncache.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/conncache.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/conncache.c	(revision 331)
@@ -0,0 +1,485 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2016, Linus Nielsen Feltzing, <linus@haxx.se>
+ * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "url.h"
+#include "progress.h"
+#include "multiif.h"
+#include "sendf.h"
+#include "conncache.h"
+#include "share.h"
+#include "sigpipe.h"
+#include "connect.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define CONN_LOCK(x) if((x)->share)                                     \
+    Curl_share_lock((x), CURL_LOCK_DATA_CONNECT, CURL_LOCK_ACCESS_SINGLE)
+#define CONN_UNLOCK(x) if((x)->share)                   \
+    Curl_share_unlock((x), CURL_LOCK_DATA_CONNECT)
+
+
+static void conn_llist_dtor(void *user, void *element)
+{
+  struct connectdata *data = element;
+  (void)user;
+
+  data->bundle = NULL;
+}
+
+static CURLcode bundle_create(struct Curl_easy *data,
+                              struct connectbundle **cb_ptr)
+{
+  (void)data;
+  DEBUGASSERT(*cb_ptr == NULL);
+  *cb_ptr = malloc(sizeof(struct connectbundle));
+  if(!*cb_ptr)
+    return CURLE_OUT_OF_MEMORY;
+
+  (*cb_ptr)->num_connections = 0;
+  (*cb_ptr)->multiuse = BUNDLE_UNKNOWN;
+
+  Curl_llist_init(&(*cb_ptr)->conn_list, (curl_llist_dtor) conn_llist_dtor);
+  return CURLE_OK;
+}
+
+static void bundle_destroy(struct connectbundle *cb_ptr)
+{
+  if(!cb_ptr)
+    return;
+
+  Curl_llist_destroy(&cb_ptr->conn_list, NULL);
+
+  free(cb_ptr);
+}
+
+/* Add a connection to a bundle */
+static CURLcode bundle_add_conn(struct connectbundle *cb_ptr,
+                                struct connectdata *conn)
+{
+  Curl_llist_insert_next(&cb_ptr->conn_list, cb_ptr->conn_list.tail, conn,
+                         &conn->bundle_node);
+  conn->bundle = cb_ptr;
+  cb_ptr->num_connections++;
+  return CURLE_OK;
+}
+
+/* Remove a connection from a bundle */
+static int bundle_remove_conn(struct connectbundle *cb_ptr,
+                              struct connectdata *conn)
+{
+  struct curl_llist_element *curr;
+
+  curr = cb_ptr->conn_list.head;
+  while(curr) {
+    if(curr->ptr == conn) {
+      Curl_llist_remove(&cb_ptr->conn_list, curr, NULL);
+      cb_ptr->num_connections--;
+      conn->bundle = NULL;
+      return 1; /* we removed a handle */
+    }
+    curr = curr->next;
+  }
+  return 0;
+}
+
+static void free_bundle_hash_entry(void *freethis)
+{
+  struct connectbundle *b = (struct connectbundle *) freethis;
+
+  bundle_destroy(b);
+}
+
+int Curl_conncache_init(struct conncache *connc, int size)
+{
+  int rc;
+
+  /* allocate a new easy handle to use when closing cached connections */
+  connc->closure_handle = curl_easy_init();
+  if(!connc->closure_handle)
+    return 1; /* bad */
+
+  rc = Curl_hash_init(&connc->hash, size, Curl_hash_str,
+                      Curl_str_key_compare, free_bundle_hash_entry);
+  if(rc) {
+    Curl_close(connc->closure_handle);
+    connc->closure_handle = NULL;
+  }
+  else
+    connc->closure_handle->state.conn_cache = connc;
+
+  return rc;
+}
+
+void Curl_conncache_destroy(struct conncache *connc)
+{
+  if(connc)
+    Curl_hash_destroy(&connc->hash);
+}
+
+/* creates a key to find a bundle for this connection */
+static void hashkey(struct connectdata *conn, char *buf,
+                    size_t len) /* something like 128 is fine */
+{
+  const char *hostname;
+
+  if(conn->bits.socksproxy)
+    hostname = conn->socks_proxy.host.name;
+  else if(conn->bits.httpproxy)
+    hostname = conn->http_proxy.host.name;
+  else if(conn->bits.conn_to_host)
+    hostname = conn->conn_to_host.name;
+  else
+    hostname = conn->host.name;
+
+  DEBUGASSERT(len > 32);
+
+  /* put the number first so that the hostname gets cut off if too long */
+  snprintf(buf, len, "%ld%s", conn->port, hostname);
+}
+
+/* Look up the bundle with all the connections to the same host this
+   connectdata struct is setup to use. */
+struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
+                                                 struct conncache *connc)
+{
+  struct connectbundle *bundle = NULL;
+  if(connc) {
+    char key[128];
+    hashkey(conn, key, sizeof(key));
+    CONN_LOCK(conn->data);
+    bundle = Curl_hash_pick(&connc->hash, key, strlen(key));
+    CONN_UNLOCK(conn->data);
+  }
+
+  return bundle;
+}
+
+static bool conncache_add_bundle(struct conncache *connc,
+                                 char *key,
+                                 struct connectbundle *bundle)
+{
+  void *p = Curl_hash_add(&connc->hash, key, strlen(key), bundle);
+
+  return p?TRUE:FALSE;
+}
+
+static void conncache_remove_bundle(struct conncache *connc,
+                                    struct connectbundle *bundle)
+{
+  struct curl_hash_iterator iter;
+  struct curl_hash_element *he;
+
+  if(!connc)
+    return;
+
+  Curl_hash_start_iterate(&connc->hash, &iter);
+
+  he = Curl_hash_next_element(&iter);
+  while(he) {
+    if(he->ptr == bundle) {
+      /* The bundle is destroyed by the hash destructor function,
+         free_bundle_hash_entry() */
+      Curl_hash_delete(&connc->hash, he->key, he->key_len);
+      return;
+    }
+
+    he = Curl_hash_next_element(&iter);
+  }
+}
+
+CURLcode Curl_conncache_add_conn(struct conncache *connc,
+                                 struct connectdata *conn)
+{
+  CURLcode result;
+  struct connectbundle *bundle;
+  struct connectbundle *new_bundle = NULL;
+  struct Curl_easy *data = conn->data;
+
+  bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
+  if(!bundle) {
+    int rc;
+    char key[128];
+
+    result = bundle_create(data, &new_bundle);
+    if(result)
+      return result;
+
+    hashkey(conn, key, sizeof(key));
+    CONN_LOCK(data);
+    rc = conncache_add_bundle(data->state.conn_cache, key, new_bundle);
+    CONN_UNLOCK(data);
+
+    if(!rc) {
+      bundle_destroy(new_bundle);
+      return CURLE_OUT_OF_MEMORY;
+    }
+    bundle = new_bundle;
+  }
+
+  CONN_LOCK(data);
+  result = bundle_add_conn(bundle, conn);
+  if(result) {
+    if(new_bundle)
+      conncache_remove_bundle(data->state.conn_cache, new_bundle);
+    CONN_UNLOCK(data);
+    return result;
+  }
+  CONN_UNLOCK(data);
+
+  conn->connection_id = connc->next_connection_id++;
+  connc->num_connections++;
+
+  DEBUGF(infof(conn->data, "Added connection %ld. "
+               "The cache now contains %" CURL_FORMAT_CURL_OFF_TU " members\n",
+               conn->connection_id, (curl_off_t) connc->num_connections));
+
+  return CURLE_OK;
+}
+
+void Curl_conncache_remove_conn(struct conncache *connc,
+                                struct connectdata *conn)
+{
+  struct connectbundle *bundle = conn->bundle;
+
+  /* The bundle pointer can be NULL, since this function can be called
+     due to a failed connection attempt, before being added to a bundle */
+  if(bundle) {
+    CONN_LOCK(conn->data);
+    bundle_remove_conn(bundle, conn);
+    if(bundle->num_connections == 0)
+      conncache_remove_bundle(connc, bundle);
+    CONN_UNLOCK(conn->data);
+    if(connc) {
+      connc->num_connections--;
+
+      DEBUGF(infof(conn->data, "The cache now contains %"
+                   CURL_FORMAT_CURL_OFF_TU " members\n",
+                   (curl_off_t) connc->num_connections));
+    }
+  }
+}
+
+/* This function iterates the entire connection cache and calls the
+   function func() with the connection pointer as the first argument
+   and the supplied 'param' argument as the other,
+
+   Return 0 from func() to continue the loop, return 1 to abort it.
+ */
+void Curl_conncache_foreach(struct Curl_easy *data,
+                            struct conncache *connc,
+                            void *param,
+                            int (*func)(struct connectdata *conn, void *param))
+{
+  struct curl_hash_iterator iter;
+  struct curl_llist_element *curr;
+  struct curl_hash_element *he;
+
+  if(!connc)
+    return;
+
+  CONN_LOCK(data);
+  Curl_hash_start_iterate(&connc->hash, &iter);
+
+  he = Curl_hash_next_element(&iter);
+  while(he) {
+    struct connectbundle *bundle;
+
+    bundle = he->ptr;
+    he = Curl_hash_next_element(&iter);
+
+    curr = bundle->conn_list.head;
+    while(curr) {
+      /* Yes, we need to update curr before calling func(), because func()
+         might decide to remove the connection */
+      struct connectdata *conn = curr->ptr;
+      curr = curr->next;
+
+      if(1 == func(conn, param)) {
+        CONN_UNLOCK(data);
+        return;
+      }
+    }
+  }
+  CONN_UNLOCK(data);
+}
+
+/* Return the first connection found in the cache. Used when closing all
+   connections.
+
+   NOTE: no locking is done here as this is presumably only done when cleaning
+   up a cache!
+*/
+struct connectdata *
+Curl_conncache_find_first_connection(struct conncache *connc)
+{
+  struct curl_hash_iterator iter;
+  struct curl_hash_element *he;
+  struct connectbundle *bundle;
+
+  Curl_hash_start_iterate(&connc->hash, &iter);
+
+  he = Curl_hash_next_element(&iter);
+  while(he) {
+    struct curl_llist_element *curr;
+    bundle = he->ptr;
+
+    curr = bundle->conn_list.head;
+    if(curr) {
+      return curr->ptr;
+    }
+
+    he = Curl_hash_next_element(&iter);
+  }
+
+  return NULL;
+}
+
+/*
+ * This function finds the connection in the connection
+ * cache that has been unused for the longest time.
+ *
+ * Returns the pointer to the oldest idle connection, or NULL if none was
+ * found.
+ */
+struct connectdata *
+Curl_conncache_oldest_idle(struct Curl_easy *data)
+{
+  struct conncache *bc = data->state.conn_cache;
+  struct curl_hash_iterator iter;
+  struct curl_llist_element *curr;
+  struct curl_hash_element *he;
+  timediff_t highscore =- 1;
+  timediff_t score;
+  struct curltime now;
+  struct connectdata *conn_candidate = NULL;
+  struct connectbundle *bundle;
+
+  now = Curl_now();
+
+  CONN_LOCK(data);
+  Curl_hash_start_iterate(&bc->hash, &iter);
+
+  he = Curl_hash_next_element(&iter);
+  while(he) {
+    struct connectdata *conn;
+
+    bundle = he->ptr;
+
+    curr = bundle->conn_list.head;
+    while(curr) {
+      conn = curr->ptr;
+
+      if(!conn->inuse) {
+        /* Set higher score for the age passed since the connection was used */
+        score = Curl_timediff(now, conn->now);
+
+        if(score > highscore) {
+          highscore = score;
+          conn_candidate = conn;
+        }
+      }
+      curr = curr->next;
+    }
+
+    he = Curl_hash_next_element(&iter);
+  }
+  CONN_UNLOCK(data);
+
+  return conn_candidate;
+}
+
+void Curl_conncache_close_all_connections(struct conncache *connc)
+{
+  struct connectdata *conn;
+
+  conn = Curl_conncache_find_first_connection(connc);
+  while(conn) {
+    SIGPIPE_VARIABLE(pipe_st);
+    conn->data = connc->closure_handle;
+
+    sigpipe_ignore(conn->data, &pipe_st);
+    conn->data->easy_conn = NULL; /* clear the easy handle's connection
+                                     pointer */
+    /* This will remove the connection from the cache */
+    connclose(conn, "kill all");
+    (void)Curl_disconnect(conn, FALSE);
+    sigpipe_restore(&pipe_st);
+
+    conn = Curl_conncache_find_first_connection(connc);
+  }
+
+  if(connc->closure_handle) {
+    SIGPIPE_VARIABLE(pipe_st);
+    sigpipe_ignore(connc->closure_handle, &pipe_st);
+
+    Curl_hostcache_clean(connc->closure_handle,
+                         connc->closure_handle->dns.hostcache);
+    Curl_close(connc->closure_handle);
+    sigpipe_restore(&pipe_st);
+  }
+}
+
+#if 0
+/* Useful for debugging the connection cache */
+void Curl_conncache_print(struct conncache *connc)
+{
+  struct curl_hash_iterator iter;
+  struct curl_llist_element *curr;
+  struct curl_hash_element *he;
+
+  if(!connc)
+    return;
+
+  fprintf(stderr, "=Bundle cache=\n");
+
+  Curl_hash_start_iterate(connc->hash, &iter);
+
+  he = Curl_hash_next_element(&iter);
+  while(he) {
+    struct connectbundle *bundle;
+    struct connectdata *conn;
+
+    bundle = he->ptr;
+
+    fprintf(stderr, "%s -", he->key);
+    curr = bundle->conn_list->head;
+    while(curr) {
+      conn = curr->ptr;
+
+      fprintf(stderr, " [%p %d]", (void *)conn, conn->inuse);
+      curr = curr->next;
+    }
+    fprintf(stderr, "\n");
+
+    he = Curl_hash_next_element(&iter);
+  }
+}
+#endif
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/conncache.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/conncache.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/conncache.h	(revision 331)
@@ -0,0 +1,74 @@
+#ifndef HEADER_CURL_CONNCACHE_H
+#define HEADER_CURL_CONNCACHE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2015 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+struct conncache {
+  struct curl_hash hash;
+  size_t num_connections;
+  long next_connection_id;
+  struct curltime last_cleanup;
+  /* handle used for closing cached connections */
+  struct Curl_easy *closure_handle;
+};
+
+#define BUNDLE_NO_MULTIUSE -1
+#define BUNDLE_UNKNOWN     0  /* initial value */
+#define BUNDLE_PIPELINING  1
+#define BUNDLE_MULTIPLEX   2
+
+struct connectbundle {
+  int multiuse;                 /* supports multi-use */
+  size_t num_connections;       /* Number of connections in the bundle */
+  struct curl_llist conn_list;  /* The connectdata members of the bundle */
+};
+
+/* returns 1 on error, 0 is fine */
+int Curl_conncache_init(struct conncache *, int size);
+void Curl_conncache_destroy(struct conncache *connc);
+
+/* return the correct bundle, to a host or a proxy */
+struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn,
+                                                 struct conncache *connc);
+
+CURLcode Curl_conncache_add_conn(struct conncache *connc,
+                                 struct connectdata *conn);
+
+void Curl_conncache_remove_conn(struct conncache *connc,
+                                struct connectdata *conn);
+
+void Curl_conncache_foreach(struct Curl_easy *data,
+                            struct conncache *connc,
+                            void *param,
+                            int (*func)(struct connectdata *conn,
+                                        void *param));
+
+struct connectdata *
+Curl_conncache_find_first_connection(struct conncache *connc);
+
+struct connectdata *
+Curl_conncache_oldest_idle(struct Curl_easy *data);
+void Curl_conncache_close_all_connections(struct conncache *connc);
+void Curl_conncache_print(struct conncache *connc);
+
+#endif /* HEADER_CURL_CONNCACHE_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/connect.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/connect.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/connect.c	(revision 331)
@@ -0,0 +1,1433 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h> /* <netinet/tcp.h> may need it */
+#endif
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h> /* for sockaddr_un */
+#endif
+#ifdef HAVE_LINUX_TCP_H
+#include <linux/tcp.h>
+#elif defined(HAVE_NETINET_TCP_H)
+#include <netinet/tcp.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#if (defined(HAVE_IOCTL_FIONBIO) && defined(NETWARE))
+#include <sys/filio.h>
+#endif
+#ifdef NETWARE
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "if2ip.h"
+#include "strerror.h"
+#include "connect.h"
+#include "select.h"
+#include "url.h" /* for Curl_safefree() */
+#include "multiif.h"
+#include "sockaddr.h" /* required for Curl_sockaddr_storage */
+#include "inet_ntop.h"
+#include "inet_pton.h"
+#include "vtls/vtls.h" /* for Curl_ssl_check_cxn() */
+#include "progress.h"
+#include "warnless.h"
+#include "conncache.h"
+#include "multihandle.h"
+#include "system_win32.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifdef __SYMBIAN32__
+/* This isn't actually supported under Symbian OS */
+#undef SO_NOSIGPIPE
+#endif
+
+static bool verifyconnect(curl_socket_t sockfd, int *error);
+
+#if defined(__DragonFly__) || defined(HAVE_WINSOCK_H)
+/* DragonFlyBSD and Windows use millisecond units */
+#define KEEPALIVE_FACTOR(x) (x *= 1000)
+#else
+#define KEEPALIVE_FACTOR(x)
+#endif
+
+#if defined(HAVE_WINSOCK2_H) && !defined(SIO_KEEPALIVE_VALS)
+#define SIO_KEEPALIVE_VALS    _WSAIOW(IOC_VENDOR,4)
+
+struct tcp_keepalive {
+  u_long onoff;
+  u_long keepalivetime;
+  u_long keepaliveinterval;
+};
+#endif
+
+static void
+tcpkeepalive(struct Curl_easy *data,
+             curl_socket_t sockfd)
+{
+  int optval = data->set.tcp_keepalive?1:0;
+
+  /* only set IDLE and INTVL if setting KEEPALIVE is successful */
+  if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,
+        (void *)&optval, sizeof(optval)) < 0) {
+    infof(data, "Failed to set SO_KEEPALIVE on fd %d\n", sockfd);
+  }
+  else {
+#if defined(SIO_KEEPALIVE_VALS)
+    struct tcp_keepalive vals;
+    DWORD dummy;
+    vals.onoff = 1;
+    optval = curlx_sltosi(data->set.tcp_keepidle);
+    KEEPALIVE_FACTOR(optval);
+    vals.keepalivetime = optval;
+    optval = curlx_sltosi(data->set.tcp_keepintvl);
+    KEEPALIVE_FACTOR(optval);
+    vals.keepaliveinterval = optval;
+    if(WSAIoctl(sockfd, SIO_KEEPALIVE_VALS, (LPVOID) &vals, sizeof(vals),
+                NULL, 0, &dummy, NULL, NULL) != 0) {
+      infof(data, "Failed to set SIO_KEEPALIVE_VALS on fd %d: %d\n",
+            (int)sockfd, WSAGetLastError());
+    }
+#else
+#ifdef TCP_KEEPIDLE
+    optval = curlx_sltosi(data->set.tcp_keepidle);
+    KEEPALIVE_FACTOR(optval);
+    if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE,
+          (void *)&optval, sizeof(optval)) < 0) {
+      infof(data, "Failed to set TCP_KEEPIDLE on fd %d\n", sockfd);
+    }
+#endif
+#ifdef TCP_KEEPINTVL
+    optval = curlx_sltosi(data->set.tcp_keepintvl);
+    KEEPALIVE_FACTOR(optval);
+    if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL,
+          (void *)&optval, sizeof(optval)) < 0) {
+      infof(data, "Failed to set TCP_KEEPINTVL on fd %d\n", sockfd);
+    }
+#endif
+#ifdef TCP_KEEPALIVE
+    /* Mac OS X style */
+    optval = curlx_sltosi(data->set.tcp_keepidle);
+    KEEPALIVE_FACTOR(optval);
+    if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE,
+          (void *)&optval, sizeof(optval)) < 0) {
+      infof(data, "Failed to set TCP_KEEPALIVE on fd %d\n", sockfd);
+    }
+#endif
+#endif
+  }
+}
+
+static CURLcode
+singleipconnect(struct connectdata *conn,
+                const Curl_addrinfo *ai, /* start connecting to this */
+                curl_socket_t *sock);
+
+/*
+ * Curl_timeleft() returns the amount of milliseconds left allowed for the
+ * transfer/connection. If the value is negative, the timeout time has already
+ * elapsed.
+ *
+ * The start time is stored in progress.t_startsingle - as set with
+ * Curl_pgrsTime(..., TIMER_STARTSINGLE);
+ *
+ * If 'nowp' is non-NULL, it points to the current time.
+ * 'duringconnect' is FALSE if not during a connect, as then of course the
+ * connect timeout is not taken into account!
+ *
+ * @unittest: 1303
+ */
+timediff_t Curl_timeleft(struct Curl_easy *data,
+                         struct curltime *nowp,
+                         bool duringconnect)
+{
+  int timeout_set = 0;
+  timediff_t timeout_ms = duringconnect?DEFAULT_CONNECT_TIMEOUT:0;
+  struct curltime now;
+
+  /* if a timeout is set, use the most restrictive one */
+
+  if(data->set.timeout > 0)
+    timeout_set |= 1;
+  if(duringconnect && (data->set.connecttimeout > 0))
+    timeout_set |= 2;
+
+  switch(timeout_set) {
+  case 1:
+    timeout_ms = data->set.timeout;
+    break;
+  case 2:
+    timeout_ms = data->set.connecttimeout;
+    break;
+  case 3:
+    if(data->set.timeout < data->set.connecttimeout)
+      timeout_ms = data->set.timeout;
+    else
+      timeout_ms = data->set.connecttimeout;
+    break;
+  default:
+    /* use the default */
+    if(!duringconnect)
+      /* if we're not during connect, there's no default timeout so if we're
+         at zero we better just return zero and not make it a negative number
+         by the math below */
+      return 0;
+    break;
+  }
+
+  if(!nowp) {
+    now = Curl_now();
+    nowp = &now;
+  }
+
+  /* subtract elapsed time */
+  if(duringconnect)
+    /* since this most recent connect started */
+    timeout_ms -= Curl_timediff(*nowp, data->progress.t_startsingle);
+  else
+    /* since the entire operation started */
+    timeout_ms -= Curl_timediff(*nowp, data->progress.t_startop);
+  if(!timeout_ms)
+    /* avoid returning 0 as that means no timeout! */
+    return -1;
+
+  return timeout_ms;
+}
+
+static CURLcode bindlocal(struct connectdata *conn,
+                          curl_socket_t sockfd, int af, unsigned int scope)
+{
+  struct Curl_easy *data = conn->data;
+
+  struct Curl_sockaddr_storage sa;
+  struct sockaddr *sock = (struct sockaddr *)&sa;  /* bind to this address */
+  curl_socklen_t sizeof_sa = 0; /* size of the data sock points to */
+  struct sockaddr_in *si4 = (struct sockaddr_in *)&sa;
+#ifdef ENABLE_IPV6
+  struct sockaddr_in6 *si6 = (struct sockaddr_in6 *)&sa;
+#endif
+
+  struct Curl_dns_entry *h = NULL;
+  unsigned short port = data->set.localport; /* use this port number, 0 for
+                                                "random" */
+  /* how many port numbers to try to bind to, increasing one at a time */
+  int portnum = data->set.localportrange;
+  const char *dev = data->set.str[STRING_DEVICE];
+  int error;
+
+  /*************************************************************
+   * Select device to bind socket to
+   *************************************************************/
+  if(!dev && !port)
+    /* no local kind of binding was requested */
+    return CURLE_OK;
+
+  memset(&sa, 0, sizeof(struct Curl_sockaddr_storage));
+
+  if(dev && (strlen(dev)<255) ) {
+    char myhost[256] = "";
+    int done = 0; /* -1 for error, 1 for address found */
+    bool is_interface = FALSE;
+    bool is_host = FALSE;
+    static const char *if_prefix = "if!";
+    static const char *host_prefix = "host!";
+
+    if(strncmp(if_prefix, dev, strlen(if_prefix)) == 0) {
+      dev += strlen(if_prefix);
+      is_interface = TRUE;
+    }
+    else if(strncmp(host_prefix, dev, strlen(host_prefix)) == 0) {
+      dev += strlen(host_prefix);
+      is_host = TRUE;
+    }
+
+    /* interface */
+    if(!is_host) {
+#ifdef SO_BINDTODEVICE
+      /* I am not sure any other OSs than Linux that provide this feature,
+       * and at the least I cannot test. --Ben
+       *
+       * This feature allows one to tightly bind the local socket to a
+       * particular interface.  This will force even requests to other
+       * local interfaces to go out the external interface.
+       *
+       *
+       * Only bind to the interface when specified as interface, not just
+       * as a hostname or ip address.
+       *
+       * interface might be a VRF, eg: vrf-blue, which means it cannot be
+       * converted to an IP address and would fail Curl_if2ip. Simply try
+       * to use it straight away.
+       */
+      if(setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
+                    dev, (curl_socklen_t)strlen(dev) + 1) == 0) {
+        /* This is typically "errno 1, error: Operation not permitted" if
+         * you're not running as root or another suitable privileged
+         * user.
+         * If it succeeds it means the parameter was a valid interface and
+         * not an IP address. Return immediately.
+         */
+        return CURLE_OK;
+      }
+#endif
+
+      switch(Curl_if2ip(af, scope, conn->scope_id, dev,
+                        myhost, sizeof(myhost))) {
+        case IF2IP_NOT_FOUND:
+          if(is_interface) {
+            /* Do not fall back to treating it as a host name */
+            failf(data, "Couldn't bind to interface '%s'", dev);
+            return CURLE_INTERFACE_FAILED;
+          }
+          break;
+        case IF2IP_AF_NOT_SUPPORTED:
+          /* Signal the caller to try another address family if available */
+          return CURLE_UNSUPPORTED_PROTOCOL;
+        case IF2IP_FOUND:
+          is_interface = TRUE;
+          /*
+           * We now have the numerical IP address in the 'myhost' buffer
+           */
+          infof(data, "Local Interface %s is ip %s using address family %i\n",
+                dev, myhost, af);
+          done = 1;
+          break;
+      }
+    }
+    if(!is_interface) {
+      /*
+       * This was not an interface, resolve the name as a host name
+       * or IP number
+       *
+       * Temporarily force name resolution to use only the address type
+       * of the connection. The resolve functions should really be changed
+       * to take a type parameter instead.
+       */
+      long ipver = conn->ip_version;
+      int rc;
+
+      if(af == AF_INET)
+        conn->ip_version = CURL_IPRESOLVE_V4;
+#ifdef ENABLE_IPV6
+      else if(af == AF_INET6)
+        conn->ip_version = CURL_IPRESOLVE_V6;
+#endif
+
+      rc = Curl_resolv(conn, dev, 0, &h);
+      if(rc == CURLRESOLV_PENDING)
+        (void)Curl_resolver_wait_resolv(conn, &h);
+      conn->ip_version = ipver;
+
+      if(h) {
+        /* convert the resolved address, sizeof myhost >= INET_ADDRSTRLEN */
+        Curl_printable_address(h->addr, myhost, sizeof(myhost));
+        infof(data, "Name '%s' family %i resolved to '%s' family %i\n",
+              dev, af, myhost, h->addr->ai_family);
+        Curl_resolv_unlock(data, h);
+        done = 1;
+      }
+      else {
+        /*
+         * provided dev was no interface (or interfaces are not supported
+         * e.g. solaris) no ip address and no domain we fail here
+         */
+        done = -1;
+      }
+    }
+
+    if(done > 0) {
+#ifdef ENABLE_IPV6
+      /* IPv6 address */
+      if(af == AF_INET6) {
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+        char *scope_ptr = strchr(myhost, '%');
+        if(scope_ptr)
+          *(scope_ptr++) = 0;
+#endif
+        if(Curl_inet_pton(AF_INET6, myhost, &si6->sin6_addr) > 0) {
+          si6->sin6_family = AF_INET6;
+          si6->sin6_port = htons(port);
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+          if(scope_ptr)
+            /* The "myhost" string either comes from Curl_if2ip or from
+               Curl_printable_address. The latter returns only numeric scope
+               IDs and the former returns none at all.  So the scope ID, if
+               present, is known to be numeric */
+            si6->sin6_scope_id = atoi(scope_ptr);
+#endif
+        }
+        sizeof_sa = sizeof(struct sockaddr_in6);
+      }
+      else
+#endif
+      /* IPv4 address */
+      if((af == AF_INET) &&
+         (Curl_inet_pton(AF_INET, myhost, &si4->sin_addr) > 0)) {
+        si4->sin_family = AF_INET;
+        si4->sin_port = htons(port);
+        sizeof_sa = sizeof(struct sockaddr_in);
+      }
+    }
+
+    if(done < 1) {
+      /* errorbuf is set false so failf will overwrite any message already in
+         the error buffer, so the user receives this error message instead of a
+         generic resolve error. */
+      data->state.errorbuf = FALSE;
+      failf(data, "Couldn't bind to '%s'", dev);
+      return CURLE_INTERFACE_FAILED;
+    }
+  }
+  else {
+    /* no device was given, prepare sa to match af's needs */
+#ifdef ENABLE_IPV6
+    if(af == AF_INET6) {
+      si6->sin6_family = AF_INET6;
+      si6->sin6_port = htons(port);
+      sizeof_sa = sizeof(struct sockaddr_in6);
+    }
+    else
+#endif
+    if(af == AF_INET) {
+      si4->sin_family = AF_INET;
+      si4->sin_port = htons(port);
+      sizeof_sa = sizeof(struct sockaddr_in);
+    }
+  }
+
+  for(;;) {
+    if(bind(sockfd, sock, sizeof_sa) >= 0) {
+      /* we succeeded to bind */
+      struct Curl_sockaddr_storage add;
+      curl_socklen_t size = sizeof(add);
+      memset(&add, 0, sizeof(struct Curl_sockaddr_storage));
+      if(getsockname(sockfd, (struct sockaddr *) &add, &size) < 0) {
+        data->state.os_errno = error = SOCKERRNO;
+        failf(data, "getsockname() failed with errno %d: %s",
+              error, Curl_strerror(conn, error));
+        return CURLE_INTERFACE_FAILED;
+      }
+      infof(data, "Local port: %hu\n", port);
+      conn->bits.bound = TRUE;
+      return CURLE_OK;
+    }
+
+    if(--portnum > 0) {
+      infof(data, "Bind to local port %hu failed, trying next\n", port);
+      port++; /* try next port */
+      /* We re-use/clobber the port variable here below */
+      if(sock->sa_family == AF_INET)
+        si4->sin_port = ntohs(port);
+#ifdef ENABLE_IPV6
+      else
+        si6->sin6_port = ntohs(port);
+#endif
+    }
+    else
+      break;
+  }
+
+  data->state.os_errno = error = SOCKERRNO;
+  failf(data, "bind failed with errno %d: %s",
+        error, Curl_strerror(conn, error));
+
+  return CURLE_INTERFACE_FAILED;
+}
+
+/*
+ * verifyconnect() returns TRUE if the connect really has happened.
+ */
+static bool verifyconnect(curl_socket_t sockfd, int *error)
+{
+  bool rc = TRUE;
+#ifdef SO_ERROR
+  int err = 0;
+  curl_socklen_t errSize = sizeof(err);
+
+#ifdef WIN32
+  /*
+   * In October 2003 we effectively nullified this function on Windows due to
+   * problems with it using all CPU in multi-threaded cases.
+   *
+   * In May 2004, we bring it back to offer more info back on connect failures.
+   * Gisle Vanem could reproduce the former problems with this function, but
+   * could avoid them by adding this SleepEx() call below:
+   *
+   *    "I don't have Rational Quantify, but the hint from his post was
+   *    ntdll::NtRemoveIoCompletion(). So I'd assume the SleepEx (or maybe
+   *    just Sleep(0) would be enough?) would release whatever
+   *    mutex/critical-section the ntdll call is waiting on.
+   *
+   *    Someone got to verify this on Win-NT 4.0, 2000."
+   */
+
+#ifdef _WIN32_WCE
+  Sleep(0);
+#else
+  SleepEx(0, FALSE);
+#endif
+
+#endif
+
+  if(0 != getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *)&err, &errSize))
+    err = SOCKERRNO;
+#ifdef _WIN32_WCE
+  /* Old WinCE versions don't support SO_ERROR */
+  if(WSAENOPROTOOPT == err) {
+    SET_SOCKERRNO(0);
+    err = 0;
+  }
+#endif
+#ifdef __minix
+  /* Minix 3.1.x doesn't support getsockopt on UDP sockets */
+  if(EBADIOCTL == err) {
+    SET_SOCKERRNO(0);
+    err = 0;
+  }
+#endif
+  if((0 == err) || (EISCONN == err))
+    /* we are connected, awesome! */
+    rc = TRUE;
+  else
+    /* This wasn't a successful connect */
+    rc = FALSE;
+  if(error)
+    *error = err;
+#else
+  (void)sockfd;
+  if(error)
+    *error = SOCKERRNO;
+#endif
+  return rc;
+}
+
+/* Used within the multi interface. Try next IP address, return TRUE if no
+   more address exists or error */
+static CURLcode trynextip(struct connectdata *conn,
+                          int sockindex,
+                          int tempindex)
+{
+  const int other = tempindex ^ 1;
+  CURLcode result = CURLE_COULDNT_CONNECT;
+
+  /* First clean up after the failed socket.
+     Don't close it yet to ensure that the next IP's socket gets a different
+     file descriptor, which can prevent bugs when the curl_multi_socket_action
+     interface is used with certain select() replacements such as kqueue. */
+  curl_socket_t fd_to_close = conn->tempsock[tempindex];
+  conn->tempsock[tempindex] = CURL_SOCKET_BAD;
+
+  if(sockindex == FIRSTSOCKET) {
+    Curl_addrinfo *ai = NULL;
+    int family = AF_UNSPEC;
+
+    if(conn->tempaddr[tempindex]) {
+      /* find next address in the same protocol family */
+      family = conn->tempaddr[tempindex]->ai_family;
+      ai = conn->tempaddr[tempindex]->ai_next;
+    }
+#ifdef ENABLE_IPV6
+    else if(conn->tempaddr[0]) {
+      /* happy eyeballs - try the other protocol family */
+      int firstfamily = conn->tempaddr[0]->ai_family;
+      family = (firstfamily == AF_INET) ? AF_INET6 : AF_INET;
+      ai = conn->tempaddr[0]->ai_next;
+    }
+#endif
+
+    while(ai) {
+      if(conn->tempaddr[other]) {
+        /* we can safely skip addresses of the other protocol family */
+        while(ai && ai->ai_family != family)
+          ai = ai->ai_next;
+      }
+
+      if(ai) {
+        result = singleipconnect(conn, ai, &conn->tempsock[tempindex]);
+        if(result == CURLE_COULDNT_CONNECT) {
+          ai = ai->ai_next;
+          continue;
+        }
+
+        conn->tempaddr[tempindex] = ai;
+      }
+      break;
+    }
+  }
+
+  if(fd_to_close != CURL_SOCKET_BAD)
+    Curl_closesocket(conn, fd_to_close);
+
+  return result;
+}
+
+/* Copies connection info into the session handle to make it available
+   when the session handle is no longer associated with a connection. */
+void Curl_persistconninfo(struct connectdata *conn)
+{
+  memcpy(conn->data->info.conn_primary_ip, conn->primary_ip, MAX_IPADR_LEN);
+  memcpy(conn->data->info.conn_local_ip, conn->local_ip, MAX_IPADR_LEN);
+  conn->data->info.conn_scheme = conn->handler->scheme;
+  conn->data->info.conn_protocol = conn->handler->protocol;
+  conn->data->info.conn_primary_port = conn->primary_port;
+  conn->data->info.conn_local_port = conn->local_port;
+}
+
+/* retrieves ip address and port from a sockaddr structure.
+   note it calls Curl_inet_ntop which sets errno on fail, not SOCKERRNO. */
+static bool getaddressinfo(struct sockaddr *sa, char *addr,
+                           long *port)
+{
+  unsigned short us_port;
+  struct sockaddr_in *si = NULL;
+#ifdef ENABLE_IPV6
+  struct sockaddr_in6 *si6 = NULL;
+#endif
+#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
+  struct sockaddr_un *su = NULL;
+#endif
+
+  switch(sa->sa_family) {
+    case AF_INET:
+      si = (struct sockaddr_in *)(void *) sa;
+      if(Curl_inet_ntop(sa->sa_family, &si->sin_addr,
+                        addr, MAX_IPADR_LEN)) {
+        us_port = ntohs(si->sin_port);
+        *port = us_port;
+        return TRUE;
+      }
+      break;
+#ifdef ENABLE_IPV6
+    case AF_INET6:
+      si6 = (struct sockaddr_in6 *)(void *) sa;
+      if(Curl_inet_ntop(sa->sa_family, &si6->sin6_addr,
+                        addr, MAX_IPADR_LEN)) {
+        us_port = ntohs(si6->sin6_port);
+        *port = us_port;
+        return TRUE;
+      }
+      break;
+#endif
+#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
+    case AF_UNIX:
+      su = (struct sockaddr_un*)sa;
+      snprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path);
+      *port = 0;
+      return TRUE;
+#endif
+    default:
+      break;
+  }
+
+  addr[0] = '\0';
+  *port = 0;
+  errno = EAFNOSUPPORT;
+  return FALSE;
+}
+
+/* retrieves the start/end point information of a socket of an established
+   connection */
+void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
+{
+  curl_socklen_t len;
+  struct Curl_sockaddr_storage ssrem;
+  struct Curl_sockaddr_storage ssloc;
+  struct Curl_easy *data = conn->data;
+
+  if(conn->socktype == SOCK_DGRAM)
+    /* there's no connection! */
+    return;
+
+  if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
+    len = sizeof(struct Curl_sockaddr_storage);
+    if(getpeername(sockfd, (struct sockaddr*) &ssrem, &len)) {
+      int error = SOCKERRNO;
+      failf(data, "getpeername() failed with errno %d: %s",
+            error, Curl_strerror(conn, error));
+      return;
+    }
+
+    len = sizeof(struct Curl_sockaddr_storage);
+    memset(&ssloc, 0, sizeof(ssloc));
+    if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) {
+      int error = SOCKERRNO;
+      failf(data, "getsockname() failed with errno %d: %s",
+            error, Curl_strerror(conn, error));
+      return;
+    }
+
+    if(!getaddressinfo((struct sockaddr*)&ssrem,
+                        conn->primary_ip, &conn->primary_port)) {
+      failf(data, "ssrem inet_ntop() failed with errno %d: %s",
+            errno, Curl_strerror(conn, errno));
+      return;
+    }
+    memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
+
+    if(!getaddressinfo((struct sockaddr*)&ssloc,
+                       conn->local_ip, &conn->local_port)) {
+      failf(data, "ssloc inet_ntop() failed with errno %d: %s",
+            errno, Curl_strerror(conn, errno));
+      return;
+    }
+
+  }
+
+  /* persist connection info in session handle */
+  Curl_persistconninfo(conn);
+}
+
+/*
+ * Curl_is_connected() checks if the socket has connected.
+ */
+
+CURLcode Curl_is_connected(struct connectdata *conn,
+                           int sockindex,
+                           bool *connected)
+{
+  struct Curl_easy *data = conn->data;
+  CURLcode result = CURLE_OK;
+  timediff_t allow;
+  int error = 0;
+  struct curltime now;
+  int rc;
+  int i;
+
+  DEBUGASSERT(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET);
+
+  *connected = FALSE; /* a very negative world view is best */
+
+  if(conn->bits.tcpconnect[sockindex]) {
+    /* we are connected already! */
+    *connected = TRUE;
+    return CURLE_OK;
+  }
+
+  now = Curl_now();
+
+  /* figure out how long time we have left to connect */
+  allow = Curl_timeleft(data, &now, TRUE);
+
+  if(allow < 0) {
+    /* time-out, bail out, go home */
+    failf(data, "Connection time-out");
+    return CURLE_OPERATION_TIMEDOUT;
+  }
+
+  for(i = 0; i<2; i++) {
+    const int other = i ^ 1;
+    if(conn->tempsock[i] == CURL_SOCKET_BAD)
+      continue;
+
+#ifdef mpeix
+    /* Call this function once now, and ignore the results. We do this to
+       "clear" the error state on the socket so that we can later read it
+       reliably. This is reported necessary on the MPE/iX operating system. */
+    (void)verifyconnect(conn->tempsock[i], NULL);
+#endif
+
+    /* check socket for connect */
+    rc = SOCKET_WRITABLE(conn->tempsock[i], 0);
+
+    if(rc == 0) { /* no connection yet */
+      error = 0;
+      if(Curl_timediff(now, conn->connecttime) >= conn->timeoutms_per_addr) {
+        infof(data, "After %ldms connect time, move on!\n",
+              conn->timeoutms_per_addr);
+        error = ETIMEDOUT;
+      }
+
+      /* should we try another protocol family? */
+      if(i == 0 && conn->tempaddr[1] == NULL &&
+         Curl_timediff(now, conn->connecttime) >= HAPPY_EYEBALLS_TIMEOUT) {
+        trynextip(conn, sockindex, 1);
+      }
+    }
+    else if(rc == CURL_CSELECT_OUT || conn->bits.tcp_fastopen) {
+      if(verifyconnect(conn->tempsock[i], &error)) {
+        /* we are connected with TCP, awesome! */
+
+        /* use this socket from now on */
+        conn->sock[sockindex] = conn->tempsock[i];
+        conn->ip_addr = conn->tempaddr[i];
+        conn->tempsock[i] = CURL_SOCKET_BAD;
+#ifdef ENABLE_IPV6
+        conn->bits.ipv6 = (conn->ip_addr->ai_family == AF_INET6)?TRUE:FALSE;
+#endif
+
+        /* close the other socket, if open */
+        if(conn->tempsock[other] != CURL_SOCKET_BAD) {
+          Curl_closesocket(conn, conn->tempsock[other]);
+          conn->tempsock[other] = CURL_SOCKET_BAD;
+        }
+
+        /* see if we need to do any proxy magic first once we connected */
+        result = Curl_connected_proxy(conn, sockindex);
+        if(result)
+          return result;
+
+        conn->bits.tcpconnect[sockindex] = TRUE;
+
+        *connected = TRUE;
+        if(sockindex == FIRSTSOCKET)
+          Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
+        Curl_updateconninfo(conn, conn->sock[sockindex]);
+        Curl_verboseconnect(conn);
+
+        return CURLE_OK;
+      }
+      infof(data, "Connection failed\n");
+    }
+    else if(rc & CURL_CSELECT_ERR)
+      (void)verifyconnect(conn->tempsock[i], &error);
+
+    /*
+     * The connection failed here, we should attempt to connect to the "next
+     * address" for the given host. But first remember the latest error.
+     */
+    if(error) {
+      data->state.os_errno = error;
+      SET_SOCKERRNO(error);
+      if(conn->tempaddr[i]) {
+        CURLcode status;
+        char ipaddress[MAX_IPADR_LEN];
+        Curl_printable_address(conn->tempaddr[i], ipaddress, MAX_IPADR_LEN);
+        infof(data, "connect to %s port %ld failed: %s\n",
+              ipaddress, conn->port, Curl_strerror(conn, error));
+
+        conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ?
+                                   allow : allow / 2;
+
+        status = trynextip(conn, sockindex, i);
+        if(status != CURLE_COULDNT_CONNECT
+            || conn->tempsock[other] == CURL_SOCKET_BAD)
+          /* the last attempt failed and no other sockets remain open */
+          result = status;
+      }
+    }
+  }
+
+  if(result) {
+    /* no more addresses to try */
+
+    const char *hostname;
+
+    /* if the first address family runs out of addresses to try before
+       the happy eyeball timeout, go ahead and try the next family now */
+    if(conn->tempaddr[1] == NULL) {
+      result = trynextip(conn, sockindex, 1);
+      if(!result)
+        return result;
+    }
+
+    if(conn->bits.socksproxy)
+      hostname = conn->socks_proxy.host.name;
+    else if(conn->bits.httpproxy)
+      hostname = conn->http_proxy.host.name;
+    else if(conn->bits.conn_to_host)
+      hostname = conn->conn_to_host.name;
+    else
+      hostname = conn->host.name;
+
+    failf(data, "Failed to connect to %s port %ld: %s",
+        hostname, conn->port, Curl_strerror(conn, error));
+  }
+
+  return result;
+}
+
+void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
+{
+#if defined(TCP_NODELAY)
+#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  struct Curl_easy *data = conn->data;
+#endif
+  curl_socklen_t onoff = (curl_socklen_t) 1;
+  int level = IPPROTO_TCP;
+
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void) conn;
+#endif
+
+  if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff,
+                sizeof(onoff)) < 0)
+    infof(data, "Could not set TCP_NODELAY: %s\n",
+          Curl_strerror(conn, SOCKERRNO));
+  else
+    infof(data, "TCP_NODELAY set\n");
+#else
+  (void)conn;
+  (void)sockfd;
+#endif
+}
+
+#ifdef SO_NOSIGPIPE
+/* The preferred method on Mac OS X (10.2 and later) to prevent SIGPIPEs when
+   sending data to a dead peer (instead of relying on the 4th argument to send
+   being MSG_NOSIGNAL). Possibly also existing and in use on other BSD
+   systems? */
+static void nosigpipe(struct connectdata *conn,
+                      curl_socket_t sockfd)
+{
+  struct Curl_easy *data = conn->data;
+  int onoff = 1;
+  if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff,
+                sizeof(onoff)) < 0)
+    infof(data, "Could not set SO_NOSIGPIPE: %s\n",
+          Curl_strerror(conn, SOCKERRNO));
+}
+#else
+#define nosigpipe(x,y) Curl_nop_stmt
+#endif
+
+#ifdef USE_WINSOCK
+/* When you run a program that uses the Windows Sockets API, you may
+   experience slow performance when you copy data to a TCP server.
+
+   https://support.microsoft.com/kb/823764
+
+   Work-around: Make the Socket Send Buffer Size Larger Than the Program Send
+   Buffer Size
+
+   The problem described in this knowledge-base is applied only to pre-Vista
+   Windows.  Following function trying to detect OS version and skips
+   SO_SNDBUF adjustment for Windows Vista and above.
+*/
+#define DETECT_OS_NONE 0
+#define DETECT_OS_PREVISTA 1
+#define DETECT_OS_VISTA_OR_LATER 2
+
+void Curl_sndbufset(curl_socket_t sockfd)
+{
+  int val = CURL_MAX_WRITE_SIZE + 32;
+  int curval = 0;
+  int curlen = sizeof(curval);
+
+  static int detectOsState = DETECT_OS_NONE;
+
+  if(detectOsState == DETECT_OS_NONE) {
+    if(Curl_verify_windows_version(6, 0, PLATFORM_WINNT,
+                                   VERSION_GREATER_THAN_EQUAL))
+      detectOsState = DETECT_OS_VISTA_OR_LATER;
+    else
+      detectOsState = DETECT_OS_PREVISTA;
+  }
+
+  if(detectOsState == DETECT_OS_VISTA_OR_LATER)
+    return;
+
+  if(getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&curval, &curlen) == 0)
+    if(curval > val)
+      return;
+
+  setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const char *)&val, sizeof(val));
+}
+#endif
+
+/*
+ * singleipconnect()
+ *
+ * Note that even on connect fail it returns CURLE_OK, but with 'sock' set to
+ * CURL_SOCKET_BAD. Other errors will however return proper errors.
+ *
+ * singleipconnect() connects to the given IP only, and it may return without
+ * having connected.
+ */
+static CURLcode singleipconnect(struct connectdata *conn,
+                                const Curl_addrinfo *ai,
+                                curl_socket_t *sockp)
+{
+  struct Curl_sockaddr_ex addr;
+  int rc = -1;
+  int error = 0;
+  bool isconnected = FALSE;
+  struct Curl_easy *data = conn->data;
+  curl_socket_t sockfd;
+  CURLcode result;
+  char ipaddress[MAX_IPADR_LEN];
+  long port;
+  bool is_tcp;
+#ifdef TCP_FASTOPEN_CONNECT
+  int optval = 1;
+#endif
+
+  *sockp = CURL_SOCKET_BAD;
+
+  result = Curl_socket(conn, ai, &addr, &sockfd);
+  if(result)
+    /* Failed to create the socket, but still return OK since we signal the
+       lack of socket as well. This allows the parent function to keep looping
+       over alternative addresses/socket families etc. */
+    return CURLE_OK;
+
+  /* store remote address and port used in this connection attempt */
+  if(!getaddressinfo((struct sockaddr*)&addr.sa_addr,
+                     ipaddress, &port)) {
+    /* malformed address or bug in inet_ntop, try next address */
+    failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
+          errno, Curl_strerror(conn, errno));
+    Curl_closesocket(conn, sockfd);
+    return CURLE_OK;
+  }
+  infof(data, "  Trying %s...\n", ipaddress);
+
+#ifdef ENABLE_IPV6
+  is_tcp = (addr.family == AF_INET || addr.family == AF_INET6) &&
+    addr.socktype == SOCK_STREAM;
+#else
+  is_tcp = (addr.family == AF_INET) && addr.socktype == SOCK_STREAM;
+#endif
+  if(is_tcp && data->set.tcp_nodelay)
+    Curl_tcpnodelay(conn, sockfd);
+
+  nosigpipe(conn, sockfd);
+
+  Curl_sndbufset(sockfd);
+
+  if(is_tcp && data->set.tcp_keepalive)
+    tcpkeepalive(data, sockfd);
+
+  if(data->set.fsockopt) {
+    /* activate callback for setting socket options */
+    error = data->set.fsockopt(data->set.sockopt_client,
+                               sockfd,
+                               CURLSOCKTYPE_IPCXN);
+
+    if(error == CURL_SOCKOPT_ALREADY_CONNECTED)
+      isconnected = TRUE;
+    else if(error) {
+      Curl_closesocket(conn, sockfd); /* close the socket and bail out */
+      return CURLE_ABORTED_BY_CALLBACK;
+    }
+  }
+
+  /* possibly bind the local end to an IP, interface or port */
+  if(addr.family == AF_INET
+#ifdef ENABLE_IPV6
+     || addr.family == AF_INET6
+#endif
+    ) {
+    result = bindlocal(conn, sockfd, addr.family,
+                       Curl_ipv6_scope((struct sockaddr*)&addr.sa_addr));
+    if(result) {
+      Curl_closesocket(conn, sockfd); /* close socket and bail out */
+      if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+        /* The address family is not supported on this interface.
+           We can continue trying addresses */
+        return CURLE_COULDNT_CONNECT;
+      }
+      return result;
+    }
+  }
+
+  /* set socket non-blocking */
+  (void)curlx_nonblock(sockfd, TRUE);
+
+  conn->connecttime = Curl_now();
+  if(conn->num_addr > 1)
+    Curl_expire(data, conn->timeoutms_per_addr, EXPIRE_DNS_PER_NAME);
+
+  /* Connect TCP sockets, bind UDP */
+  if(!isconnected && (conn->socktype == SOCK_STREAM)) {
+    if(conn->bits.tcp_fastopen) {
+#if defined(CONNECT_DATA_IDEMPOTENT) /* Darwin */
+#  if defined(HAVE_BUILTIN_AVAILABLE)
+      /* while connectx function is available since macOS 10.11 / iOS 9,
+         it did not have the interface declared correctly until
+         Xcode 9 / macOS SDK 10.13 */
+      if(__builtin_available(macOS 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *)) {
+        sa_endpoints_t endpoints;
+        endpoints.sae_srcif = 0;
+        endpoints.sae_srcaddr = NULL;
+        endpoints.sae_srcaddrlen = 0;
+        endpoints.sae_dstaddr = &addr.sa_addr;
+        endpoints.sae_dstaddrlen = addr.addrlen;
+
+        rc = connectx(sockfd, &endpoints, SAE_ASSOCID_ANY,
+                      CONNECT_RESUME_ON_READ_WRITE | CONNECT_DATA_IDEMPOTENT,
+                      NULL, 0, NULL, NULL);
+      }
+      else {
+        rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
+      }
+#  else
+      rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
+#  endif /* HAVE_BUILTIN_AVAILABLE */
+#elif defined(TCP_FASTOPEN_CONNECT) /* Linux >= 4.11 */
+      if(setsockopt(sockfd, IPPROTO_TCP, TCP_FASTOPEN_CONNECT,
+                    (void *)&optval, sizeof(optval)) < 0)
+        infof(data, "Failed to enable TCP Fast Open on fd %d\n", sockfd);
+      else
+        infof(data, "TCP_FASTOPEN_CONNECT set\n");
+
+      rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
+#elif defined(MSG_FASTOPEN) /* old Linux */
+      if(conn->given->flags & PROTOPT_SSL)
+        rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
+      else
+        rc = 0; /* Do nothing */
+#endif
+    }
+    else {
+      rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
+    }
+
+    if(-1 == rc)
+      error = SOCKERRNO;
+  }
+  else {
+    *sockp = sockfd;
+    return CURLE_OK;
+  }
+
+  if(-1 == rc) {
+    switch(error) {
+    case EINPROGRESS:
+    case EWOULDBLOCK:
+#if defined(EAGAIN)
+#if (EAGAIN) != (EWOULDBLOCK)
+      /* On some platforms EAGAIN and EWOULDBLOCK are the
+       * same value, and on others they are different, hence
+       * the odd #if
+       */
+    case EAGAIN:
+#endif
+#endif
+      result = CURLE_OK;
+      break;
+
+    default:
+      /* unknown error, fallthrough and try another address! */
+      infof(data, "Immediate connect fail for %s: %s\n",
+            ipaddress, Curl_strerror(conn, error));
+      data->state.os_errno = error;
+
+      /* connect failed */
+      Curl_closesocket(conn, sockfd);
+      result = CURLE_COULDNT_CONNECT;
+    }
+  }
+
+  if(!result)
+    *sockp = sockfd;
+
+  return result;
+}
+
+/*
+ * TCP connect to the given host with timeout, proxy or remote doesn't matter.
+ * There might be more than one IP address to try out. Fill in the passed
+ * pointer with the connected socket.
+ */
+
+CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
+                          const struct Curl_dns_entry *remotehost)
+{
+  struct Curl_easy *data = conn->data;
+  struct curltime before = Curl_now();
+  CURLcode result = CURLE_COULDNT_CONNECT;
+
+  timediff_t timeout_ms = Curl_timeleft(data, &before, TRUE);
+
+  if(timeout_ms < 0) {
+    /* a precaution, no need to continue if time already is up */
+    failf(data, "Connection time-out");
+    return CURLE_OPERATION_TIMEDOUT;
+  }
+
+  conn->num_addr = Curl_num_addresses(remotehost->addr);
+  conn->tempaddr[0] = remotehost->addr;
+  conn->tempaddr[1] = NULL;
+  conn->tempsock[0] = CURL_SOCKET_BAD;
+  conn->tempsock[1] = CURL_SOCKET_BAD;
+
+  /* Max time for the next connection attempt */
+  conn->timeoutms_per_addr =
+    conn->tempaddr[0]->ai_next == NULL ? timeout_ms : timeout_ms / 2;
+
+  /* start connecting to first IP */
+  while(conn->tempaddr[0]) {
+    result = singleipconnect(conn, conn->tempaddr[0], &(conn->tempsock[0]));
+    if(!result)
+      break;
+    conn->tempaddr[0] = conn->tempaddr[0]->ai_next;
+  }
+
+  if(conn->tempsock[0] == CURL_SOCKET_BAD) {
+    if(!result)
+      result = CURLE_COULDNT_CONNECT;
+    return result;
+  }
+
+  data->info.numconnects++; /* to track the number of connections made */
+  Curl_expire(conn->data, HAPPY_EYEBALLS_TIMEOUT, EXPIRE_HAPPY_EYEBALLS);
+
+  return CURLE_OK;
+}
+
+struct connfind {
+  struct connectdata *tofind;
+  bool found;
+};
+
+static int conn_is_conn(struct connectdata *conn, void *param)
+{
+  struct connfind *f = (struct connfind *)param;
+  if(conn == f->tofind) {
+    f->found = TRUE;
+    return 1;
+  }
+  return 0;
+}
+
+/*
+ * Used to extract socket and connectdata struct for the most recent
+ * transfer on the given Curl_easy.
+ *
+ * The returned socket will be CURL_SOCKET_BAD in case of failure!
+ */
+curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
+                                  struct connectdata **connp)
+{
+  curl_socket_t sockfd;
+
+  DEBUGASSERT(data);
+
+  /* this works for an easy handle:
+   * - that has been used for curl_easy_perform()
+   * - that is associated with a multi handle, and whose connection
+   *   was detached with CURLOPT_CONNECT_ONLY
+   */
+  if(data->state.lastconnect && (data->multi_easy || data->multi)) {
+    struct connectdata *c = data->state.lastconnect;
+    struct connfind find;
+    find.tofind = data->state.lastconnect;
+    find.found = FALSE;
+
+    Curl_conncache_foreach(data, data->multi_easy?
+                           &data->multi_easy->conn_cache:
+                           &data->multi->conn_cache, &find, conn_is_conn);
+
+    if(!find.found) {
+      data->state.lastconnect = NULL;
+      return CURL_SOCKET_BAD;
+    }
+
+    if(connp)
+      /* only store this if the caller cares for it */
+      *connp = c;
+    sockfd = c->sock[FIRSTSOCKET];
+  }
+  else
+    return CURL_SOCKET_BAD;
+
+  return sockfd;
+}
+
+/*
+ * Check if a connection seems to be alive.
+ */
+bool Curl_connalive(struct connectdata *conn)
+{
+  /* First determine if ssl */
+  if(conn->ssl[FIRSTSOCKET].use) {
+    /* use the SSL context */
+    if(!Curl_ssl_check_cxn(conn))
+      return false;   /* FIN received */
+  }
+/* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */
+#ifdef MSG_PEEK
+  else if(conn->sock[FIRSTSOCKET] == CURL_SOCKET_BAD)
+    return false;
+  else {
+    /* use the socket */
+    char buf;
+    if(recv((RECV_TYPE_ARG1)conn->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf,
+            (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) {
+      return false;   /* FIN received */
+    }
+  }
+#endif
+  return true;
+}
+
+/*
+ * Close a socket.
+ *
+ * 'conn' can be NULL, beware!
+ */
+int Curl_closesocket(struct connectdata *conn,
+                      curl_socket_t sock)
+{
+  if(conn && conn->fclosesocket) {
+    if((sock == conn->sock[SECONDARYSOCKET]) &&
+       conn->sock_accepted[SECONDARYSOCKET])
+      /* if this socket matches the second socket, and that was created with
+         accept, then we MUST NOT call the callback but clear the accepted
+         status */
+      conn->sock_accepted[SECONDARYSOCKET] = FALSE;
+    else {
+      Curl_multi_closed(conn, sock);
+      return conn->fclosesocket(conn->closesocket_client, sock);
+    }
+  }
+
+  if(conn)
+    /* tell the multi-socket code about this */
+    Curl_multi_closed(conn, sock);
+
+  sclose(sock);
+
+  return 0;
+}
+
+/*
+ * Create a socket based on info from 'conn' and 'ai'.
+ *
+ * 'addr' should be a pointer to the correct struct to get data back, or NULL.
+ * 'sockfd' must be a pointer to a socket descriptor.
+ *
+ * If the open socket callback is set, used that!
+ *
+ */
+CURLcode Curl_socket(struct connectdata *conn,
+                     const Curl_addrinfo *ai,
+                     struct Curl_sockaddr_ex *addr,
+                     curl_socket_t *sockfd)
+{
+  struct Curl_easy *data = conn->data;
+  struct Curl_sockaddr_ex dummy;
+
+  if(!addr)
+    /* if the caller doesn't want info back, use a local temp copy */
+    addr = &dummy;
+
+  /*
+   * The Curl_sockaddr_ex structure is basically libcurl's external API
+   * curl_sockaddr structure with enough space available to directly hold
+   * any protocol-specific address structures. The variable declared here
+   * will be used to pass / receive data to/from the fopensocket callback
+   * if this has been set, before that, it is initialized from parameters.
+   */
+
+  addr->family = ai->ai_family;
+  addr->socktype = conn->socktype;
+  addr->protocol = conn->socktype == SOCK_DGRAM?IPPROTO_UDP:ai->ai_protocol;
+  addr->addrlen = ai->ai_addrlen;
+
+  if(addr->addrlen > sizeof(struct Curl_sockaddr_storage))
+     addr->addrlen = sizeof(struct Curl_sockaddr_storage);
+  memcpy(&addr->sa_addr, ai->ai_addr, addr->addrlen);
+
+  if(data->set.fopensocket)
+   /*
+    * If the opensocket callback is set, all the destination address
+    * information is passed to the callback. Depending on this information the
+    * callback may opt to abort the connection, this is indicated returning
+    * CURL_SOCKET_BAD; otherwise it will return a not-connected socket. When
+    * the callback returns a valid socket the destination address information
+    * might have been changed and this 'new' address will actually be used
+    * here to connect.
+    */
+    *sockfd = data->set.fopensocket(data->set.opensocket_client,
+                                    CURLSOCKTYPE_IPCXN,
+                                    (struct curl_sockaddr *)addr);
+  else
+    /* opensocket callback not set, so simply create the socket now */
+    *sockfd = socket(addr->family, addr->socktype, addr->protocol);
+
+  if(*sockfd == CURL_SOCKET_BAD)
+    /* no socket, no connection */
+    return CURLE_COULDNT_CONNECT;
+
+#if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
+  if(conn->scope_id && (addr->family == AF_INET6)) {
+    struct sockaddr_in6 * const sa6 = (void *)&addr->sa_addr;
+    sa6->sin6_scope_id = conn->scope_id;
+  }
+#endif
+
+  return CURLE_OK;
+
+}
+
+/*
+ * Curl_conncontrol() marks streams or connection for closure.
+ */
+void Curl_conncontrol(struct connectdata *conn,
+                      int ctrl /* see defines in header */
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+                      , const char *reason
+#endif
+  )
+{
+  /* close if a connection, or a stream that isn't multiplexed */
+  bool closeit = (ctrl == CONNCTRL_CONNECTION) ||
+    ((ctrl == CONNCTRL_STREAM) && !(conn->handler->flags & PROTOPT_STREAM));
+  if((ctrl == CONNCTRL_STREAM) &&
+     (conn->handler->flags & PROTOPT_STREAM))
+    DEBUGF(infof(conn->data, "Kill stream: %s\n", reason));
+  else if(closeit != conn->bits.close) {
+    DEBUGF(infof(conn->data, "Marked for [%s]: %s\n",
+                 closeit?"closure":"keep alive", reason));
+    conn->bits.close = closeit; /* the only place in the source code that
+                                   should assign this bit */
+  }
+}
+
+/* Data received can be cached at various levels, so check them all here. */
+bool Curl_conn_data_pending(struct connectdata *conn, int sockindex)
+{
+  int readable;
+
+  if(Curl_ssl_data_pending(conn, sockindex) ||
+     Curl_recv_has_postponed_data(conn, sockindex))
+    return true;
+
+  readable = SOCKET_READABLE(conn->sock[sockindex], 0);
+  return (readable > 0 && (readable & CURL_CSELECT_IN));
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/connect.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/connect.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/connect.h	(revision 331)
@@ -0,0 +1,148 @@
+#ifndef HEADER_CURL_CONNECT_H
+#define HEADER_CURL_CONNECT_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#include "nonblock.h" /* for curlx_nonblock(), formerly Curl_nonblock() */
+#include "sockaddr.h"
+#include "timeval.h"
+
+CURLcode Curl_is_connected(struct connectdata *conn,
+                           int sockindex,
+                           bool *connected);
+
+CURLcode Curl_connecthost(struct connectdata *conn,
+                          const struct Curl_dns_entry *host);
+
+/* generic function that returns how much time there's left to run, according
+   to the timeouts set */
+timediff_t Curl_timeleft(struct Curl_easy *data,
+                         struct curltime *nowp,
+                         bool duringconnect);
+
+#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
+#define HAPPY_EYEBALLS_TIMEOUT     200 /* milliseconds to wait between
+                                          IPv4/IPv6 connection attempts */
+
+/*
+ * Used to extract socket and connectdata struct for the most recent
+ * transfer on the given Curl_easy.
+ *
+ * The returned socket will be CURL_SOCKET_BAD in case of failure!
+ */
+curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
+                                  struct connectdata **connp);
+
+/*
+ * Check if a connection seems to be alive.
+ */
+bool Curl_connalive(struct connectdata *conn);
+
+#ifdef USE_WINSOCK
+/* When you run a program that uses the Windows Sockets API, you may
+   experience slow performance when you copy data to a TCP server.
+
+   https://support.microsoft.com/kb/823764
+
+   Work-around: Make the Socket Send Buffer Size Larger Than the Program Send
+   Buffer Size
+
+*/
+void Curl_sndbufset(curl_socket_t sockfd);
+#else
+#define Curl_sndbufset(y) Curl_nop_stmt
+#endif
+
+void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd);
+void Curl_persistconninfo(struct connectdata *conn);
+int Curl_closesocket(struct connectdata *conn, curl_socket_t sock);
+
+/*
+ * The Curl_sockaddr_ex structure is basically libcurl's external API
+ * curl_sockaddr structure with enough space available to directly hold any
+ * protocol-specific address structures. The variable declared here will be
+ * used to pass / receive data to/from the fopensocket callback if this has
+ * been set, before that, it is initialized from parameters.
+ */
+struct Curl_sockaddr_ex {
+  int family;
+  int socktype;
+  int protocol;
+  unsigned int addrlen;
+  union {
+    struct sockaddr addr;
+    struct Curl_sockaddr_storage buff;
+  } _sa_ex_u;
+};
+#define sa_addr _sa_ex_u.addr
+
+/*
+ * Create a socket based on info from 'conn' and 'ai'.
+ *
+ * Fill in 'addr' and 'sockfd' accordingly if OK is returned. If the open
+ * socket callback is set, used that!
+ *
+ */
+CURLcode Curl_socket(struct connectdata *conn,
+                     const Curl_addrinfo *ai,
+                     struct Curl_sockaddr_ex *addr,
+                     curl_socket_t *sockfd);
+
+void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd);
+
+/*
+ * Curl_conncontrol() marks the end of a connection/stream. The 'closeit'
+ * argument specifies if it is the end of a connection or a stream.
+ *
+ * For stream-based protocols (such as HTTP/2), a stream close will not cause
+ * a connection close. Other protocols will close the connection for both
+ * cases.
+ *
+ * It sets the bit.close bit to TRUE (with an explanation for debug builds),
+ * when the connection will close.
+ */
+
+#define CONNCTRL_KEEP 0 /* undo a marked closure */
+#define CONNCTRL_CONNECTION 1
+#define CONNCTRL_STREAM 2
+
+void Curl_conncontrol(struct connectdata *conn,
+                      int closeit
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+                      , const char *reason
+#endif
+  );
+
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+#define streamclose(x,y) Curl_conncontrol(x, CONNCTRL_STREAM, y)
+#define connclose(x,y) Curl_conncontrol(x, CONNCTRL_CONNECTION, y)
+#define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP, y)
+#else /* if !DEBUGBUILD || CURL_DISABLE_VERBOSE_STRINGS */
+#define streamclose(x,y) Curl_conncontrol(x, CONNCTRL_STREAM)
+#define connclose(x,y) Curl_conncontrol(x, CONNCTRL_CONNECTION)
+#define connkeep(x,y) Curl_conncontrol(x, CONNCTRL_KEEP)
+#endif
+
+bool Curl_conn_data_pending(struct connectdata *conn, int sockindex);
+
+#endif /* HEADER_CURL_CONNECT_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/content_encoding.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/content_encoding.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/content_encoding.c	(revision 331)
@@ -0,0 +1,960 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include <stddef.h>
+
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#ifdef __SYMBIAN32__
+/* zlib pollutes the namespace with this definition */
+#undef WIN32
+#endif
+#endif
+
+#ifdef HAVE_BROTLI
+#include <brotli/decode.h>
+#endif
+
+#include "sendf.h"
+#include "http.h"
+#include "content_encoding.h"
+#include "strdup.h"
+#include "strcase.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define CONTENT_ENCODING_DEFAULT  "identity"
+
+#ifndef CURL_DISABLE_HTTP
+
+#define DSIZ CURL_MAX_WRITE_SIZE /* buffer size for decompressed data */
+
+
+#ifdef HAVE_LIBZ
+
+/* Comment this out if zlib is always going to be at least ver. 1.2.0.4
+   (doing so will reduce code size slightly). */
+#define OLD_ZLIB_SUPPORT 1
+
+#define GZIP_MAGIC_0 0x1f
+#define GZIP_MAGIC_1 0x8b
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC     0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define RESERVED     0xE0 /* bits 5..7: reserved */
+
+typedef enum {
+  ZLIB_UNINIT,          /* uninitialized */
+  ZLIB_INIT,            /* initialized */
+  ZLIB_GZIP_HEADER,     /* reading gzip header */
+  ZLIB_GZIP_INFLATING,  /* inflating gzip stream */
+  ZLIB_INIT_GZIP        /* initialized in transparent gzip mode */
+} zlibInitState;
+
+/* Writer parameters. */
+typedef struct {
+  zlibInitState zlib_init;    /* zlib init state */
+  z_stream z;                /* State structure for zlib. */
+}  zlib_params;
+
+
+static voidpf
+zalloc_cb(voidpf opaque, unsigned int items, unsigned int size)
+{
+  (void) opaque;
+  /* not a typo, keep it calloc() */
+  return (voidpf) calloc(items, size);
+}
+
+static void
+zfree_cb(voidpf opaque, voidpf ptr)
+{
+  (void) opaque;
+  free(ptr);
+}
+
+static CURLcode
+process_zlib_error(struct connectdata *conn, z_stream *z)
+{
+  struct Curl_easy *data = conn->data;
+  if(z->msg)
+    failf(data, "Error while processing content unencoding: %s",
+          z->msg);
+  else
+    failf(data, "Error while processing content unencoding: "
+          "Unknown failure within decompression software.");
+
+  return CURLE_BAD_CONTENT_ENCODING;
+}
+
+static CURLcode
+exit_zlib(struct connectdata *conn,
+          z_stream *z, zlibInitState *zlib_init, CURLcode result)
+{
+  if(*zlib_init == ZLIB_GZIP_HEADER)
+    Curl_safefree(z->next_in);
+
+  if(*zlib_init != ZLIB_UNINIT) {
+    if(inflateEnd(z) != Z_OK && result == CURLE_OK)
+      result = process_zlib_error(conn, z);
+    *zlib_init = ZLIB_UNINIT;
+  }
+
+  return result;
+}
+
+static CURLcode
+inflate_stream(struct connectdata *conn, contenc_writer *writer)
+{
+  zlib_params *zp = (zlib_params *) &writer->params;
+  int allow_restart = 1;
+  z_stream *z = &zp->z;         /* zlib state structure */
+  uInt nread = z->avail_in;
+  Bytef *orig_in = z->next_in;
+  int status;                   /* zlib status */
+  CURLcode result = CURLE_OK;   /* Curl_client_write status */
+  char *decomp;                 /* Put the decompressed data here. */
+
+  /* Dynamically allocate a buffer for decompression because it's uncommonly
+     large to hold on the stack */
+  decomp = malloc(DSIZ);
+  if(decomp == NULL) {
+    return exit_zlib(conn, z, &zp->zlib_init, CURLE_OUT_OF_MEMORY);
+  }
+
+  /* because the buffer size is fixed, iteratively decompress and transfer to
+     the client via client_write. */
+  for(;;) {
+    if(z->avail_in == 0) {
+      free(decomp);
+      return result;
+    }
+
+    /* (re)set buffer for decompressed output for every iteration */
+    z->next_out = (Bytef *) decomp;
+    z->avail_out = DSIZ;
+
+    status = inflate(z, Z_SYNC_FLUSH);
+    if(status == Z_OK || status == Z_STREAM_END) {
+      allow_restart = 0;
+      result = Curl_unencode_write(conn, writer->downstream, decomp,
+                                   DSIZ - z->avail_out);
+      /* if !CURLE_OK, clean up, return */
+      if(result) {
+        free(decomp);
+        return exit_zlib(conn, z, &zp->zlib_init, result);
+      }
+
+      /* Done? clean up, return */
+      if(status == Z_STREAM_END) {
+        free(decomp);
+        return exit_zlib(conn, z, &zp->zlib_init, result);
+      }
+
+      /* Done with these bytes, exit */
+
+      /* status is always Z_OK at this point! */
+      continue;
+    }
+    else if(allow_restart && status == Z_DATA_ERROR) {
+      /* some servers seem to not generate zlib headers, so this is an attempt
+         to fix and continue anyway */
+
+      (void) inflateEnd(z);     /* don't care about the return code */
+      if(inflateInit2(z, -MAX_WBITS) != Z_OK) {
+        free(decomp);
+        zp->zlib_init = ZLIB_UNINIT;  /* inflateEnd() already called. */
+        return exit_zlib(conn, z, &zp->zlib_init, process_zlib_error(conn, z));
+      }
+      z->next_in = orig_in;
+      z->avail_in = nread;
+      allow_restart = 0;
+      continue;
+    }
+    else {                      /* Error; exit loop, handle below */
+      free(decomp);
+      return exit_zlib(conn, z, &zp->zlib_init, process_zlib_error(conn, z));
+    }
+  }
+  /* UNREACHED */
+}
+
+
+/* Deflate handler. */
+static CURLcode deflate_init_writer(struct connectdata *conn,
+                                    contenc_writer *writer)
+{
+  zlib_params *zp = (zlib_params *) &writer->params;
+  z_stream *z = &zp->z;     /* zlib state structure */
+
+  if(!writer->downstream)
+    return CURLE_WRITE_ERROR;
+
+  /* Initialize zlib */
+  z->zalloc = (alloc_func) zalloc_cb;
+  z->zfree = (free_func) zfree_cb;
+
+  if(inflateInit(z) != Z_OK)
+    return process_zlib_error(conn, z);
+  zp->zlib_init = ZLIB_INIT;
+  return CURLE_OK;
+}
+
+static CURLcode deflate_unencode_write(struct connectdata *conn,
+                                       contenc_writer *writer,
+                                       const char *buf, size_t nbytes)
+{
+  zlib_params *zp = (zlib_params *) &writer->params;
+  z_stream *z = &zp->z;     /* zlib state structure */
+
+  /* Set the compressed input when this function is called */
+  z->next_in = (Bytef *) buf;
+  z->avail_in = (uInt) nbytes;
+
+  /* Now uncompress the data */
+  return inflate_stream(conn, writer);
+}
+
+static void deflate_close_writer(struct connectdata *conn,
+                                 contenc_writer *writer)
+{
+  zlib_params *zp = (zlib_params *) &writer->params;
+  z_stream *z = &zp->z;     /* zlib state structure */
+
+  exit_zlib(conn, z, &zp->zlib_init, CURLE_OK);
+}
+
+static const content_encoding deflate_encoding = {
+  "deflate",
+  NULL,
+  deflate_init_writer,
+  deflate_unencode_write,
+  deflate_close_writer,
+  sizeof(zlib_params)
+};
+
+
+/* Gzip handler. */
+static CURLcode gzip_init_writer(struct connectdata *conn,
+                                 contenc_writer *writer)
+{
+  zlib_params *zp = (zlib_params *) &writer->params;
+  z_stream *z = &zp->z;     /* zlib state structure */
+
+  if(!writer->downstream)
+    return CURLE_WRITE_ERROR;
+
+  /* Initialize zlib */
+  z->zalloc = (alloc_func) zalloc_cb;
+  z->zfree = (free_func) zfree_cb;
+
+  if(strcmp(zlibVersion(), "1.2.0.4") >= 0) {
+    /* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */
+    if(inflateInit2(z, MAX_WBITS + 32) != Z_OK) {
+      return process_zlib_error(conn, z);
+    }
+    zp->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */
+  }
+  else {
+    /* we must parse the gzip header ourselves */
+    if(inflateInit2(z, -MAX_WBITS) != Z_OK) {
+      return process_zlib_error(conn, z);
+    }
+    zp->zlib_init = ZLIB_INIT;   /* Initial call state */
+  }
+
+  return CURLE_OK;
+}
+
+#ifdef OLD_ZLIB_SUPPORT
+/* Skip over the gzip header */
+static enum {
+  GZIP_OK,
+  GZIP_BAD,
+  GZIP_UNDERFLOW
+} check_gzip_header(unsigned char const *data, ssize_t len, ssize_t *headerlen)
+{
+  int method, flags;
+  const ssize_t totallen = len;
+
+  /* The shortest header is 10 bytes */
+  if(len < 10)
+    return GZIP_UNDERFLOW;
+
+  if((data[0] != GZIP_MAGIC_0) || (data[1] != GZIP_MAGIC_1))
+    return GZIP_BAD;
+
+  method = data[2];
+  flags = data[3];
+
+  if(method != Z_DEFLATED || (flags & RESERVED) != 0) {
+    /* Can't handle this compression method or unknown flag */
+    return GZIP_BAD;
+  }
+
+  /* Skip over time, xflags, OS code and all previous bytes */
+  len -= 10;
+  data += 10;
+
+  if(flags & EXTRA_FIELD) {
+    ssize_t extra_len;
+
+    if(len < 2)
+      return GZIP_UNDERFLOW;
+
+    extra_len = (data[1] << 8) | data[0];
+
+    if(len < (extra_len + 2))
+      return GZIP_UNDERFLOW;
+
+    len -= (extra_len + 2);
+    data += (extra_len + 2);
+  }
+
+  if(flags & ORIG_NAME) {
+    /* Skip over NUL-terminated file name */
+    while(len && *data) {
+      --len;
+      ++data;
+    }
+    if(!len || *data)
+      return GZIP_UNDERFLOW;
+
+    /* Skip over the NUL */
+    --len;
+    ++data;
+  }
+
+  if(flags & COMMENT) {
+    /* Skip over NUL-terminated comment */
+    while(len && *data) {
+      --len;
+      ++data;
+    }
+    if(!len || *data)
+      return GZIP_UNDERFLOW;
+
+    /* Skip over the NUL */
+    --len;
+  }
+
+  if(flags & HEAD_CRC) {
+    if(len < 2)
+      return GZIP_UNDERFLOW;
+
+    len -= 2;
+  }
+
+  *headerlen = totallen - len;
+  return GZIP_OK;
+}
+#endif
+
+static CURLcode gzip_unencode_write(struct connectdata *conn,
+                                    contenc_writer *writer,
+                                    const char *buf, size_t nbytes)
+{
+  zlib_params *zp = (zlib_params *) &writer->params;
+  z_stream *z = &zp->z;     /* zlib state structure */
+
+  if(zp->zlib_init == ZLIB_INIT_GZIP) {
+    /* Let zlib handle the gzip decompression entirely */
+    z->next_in = (Bytef *) buf;
+    z->avail_in = (uInt) nbytes;
+    /* Now uncompress the data */
+    return inflate_stream(conn, writer);
+  }
+
+#ifndef OLD_ZLIB_SUPPORT
+  /* Support for old zlib versions is compiled away and we are running with
+     an old version, so return an error. */
+  return exit_zlib(conn, z, &zp->zlib_init, CURLE_WRITE_ERROR);
+
+#else
+  /* This next mess is to get around the potential case where there isn't
+   * enough data passed in to skip over the gzip header.  If that happens, we
+   * malloc a block and copy what we have then wait for the next call.  If
+   * there still isn't enough (this is definitely a worst-case scenario), we
+   * make the block bigger, copy the next part in and keep waiting.
+   *
+   * This is only required with zlib versions < 1.2.0.4 as newer versions
+   * can handle the gzip header themselves.
+   */
+
+  switch(zp->zlib_init) {
+  /* Skip over gzip header? */
+  case ZLIB_INIT:
+  {
+    /* Initial call state */
+    ssize_t hlen;
+
+    switch(check_gzip_header((unsigned char *) buf, nbytes, &hlen)) {
+    case GZIP_OK:
+      z->next_in = (Bytef *) buf + hlen;
+      z->avail_in = (uInt) (nbytes - hlen);
+      zp->zlib_init = ZLIB_GZIP_INFLATING; /* Inflating stream state */
+      break;
+
+    case GZIP_UNDERFLOW:
+      /* We need more data so we can find the end of the gzip header.  It's
+       * possible that the memory block we malloc here will never be freed if
+       * the transfer abruptly aborts after this point.  Since it's unlikely
+       * that circumstances will be right for this code path to be followed in
+       * the first place, and it's even more unlikely for a transfer to fail
+       * immediately afterwards, it should seldom be a problem.
+       */
+      z->avail_in = (uInt) nbytes;
+      z->next_in = malloc(z->avail_in);
+      if(z->next_in == NULL) {
+        return exit_zlib(conn, z, &zp->zlib_init, CURLE_OUT_OF_MEMORY);
+      }
+      memcpy(z->next_in, buf, z->avail_in);
+      zp->zlib_init = ZLIB_GZIP_HEADER;  /* Need more gzip header data state */
+      /* We don't have any data to inflate yet */
+      return CURLE_OK;
+
+    case GZIP_BAD:
+    default:
+      return exit_zlib(conn, z, &zp->zlib_init, process_zlib_error(conn, z));
+    }
+
+  }
+  break;
+
+  case ZLIB_GZIP_HEADER:
+  {
+    /* Need more gzip header data state */
+    ssize_t hlen;
+    z->avail_in += (uInt) nbytes;
+    z->next_in = Curl_saferealloc(z->next_in, z->avail_in);
+    if(z->next_in == NULL) {
+      return exit_zlib(conn, z, &zp->zlib_init, CURLE_OUT_OF_MEMORY);
+    }
+    /* Append the new block of data to the previous one */
+    memcpy(z->next_in + z->avail_in - nbytes, buf, nbytes);
+
+    switch(check_gzip_header(z->next_in, z->avail_in, &hlen)) {
+    case GZIP_OK:
+      /* This is the zlib stream data */
+      free(z->next_in);
+      /* Don't point into the malloced block since we just freed it */
+      z->next_in = (Bytef *) buf + hlen + nbytes - z->avail_in;
+      z->avail_in = (uInt) (z->avail_in - hlen);
+      zp->zlib_init = ZLIB_GZIP_INFLATING;   /* Inflating stream state */
+      break;
+
+    case GZIP_UNDERFLOW:
+      /* We still don't have any data to inflate! */
+      return CURLE_OK;
+
+    case GZIP_BAD:
+    default:
+      return exit_zlib(conn, z, &zp->zlib_init, process_zlib_error(conn, z));
+    }
+
+  }
+  break;
+
+  case ZLIB_GZIP_INFLATING:
+  default:
+    /* Inflating stream state */
+    z->next_in = (Bytef *) buf;
+    z->avail_in = (uInt) nbytes;
+    break;
+  }
+
+  if(z->avail_in == 0) {
+    /* We don't have any data to inflate; wait until next time */
+    return CURLE_OK;
+  }
+
+  /* We've parsed the header, now uncompress the data */
+  return inflate_stream(conn, writer);
+#endif
+}
+
+static void gzip_close_writer(struct connectdata *conn,
+                              contenc_writer *writer)
+{
+  zlib_params *zp = (zlib_params *) &writer->params;
+  z_stream *z = &zp->z;     /* zlib state structure */
+
+  exit_zlib(conn, z, &zp->zlib_init, CURLE_OK);
+}
+
+static const content_encoding gzip_encoding = {
+  "gzip",
+  "x-gzip",
+  gzip_init_writer,
+  gzip_unencode_write,
+  gzip_close_writer,
+  sizeof(zlib_params)
+};
+
+#endif /* HAVE_LIBZ */
+
+
+#ifdef HAVE_BROTLI
+
+/* Writer parameters. */
+typedef struct {
+  BrotliDecoderState *br;    /* State structure for brotli. */
+}  brotli_params;
+
+
+static CURLcode brotli_map_error(BrotliDecoderErrorCode be)
+{
+  switch(be) {
+  case BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE:
+  case BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE:
+  case BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET:
+  case BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME:
+  case BROTLI_DECODER_ERROR_FORMAT_CL_SPACE:
+  case BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE:
+  case BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT:
+  case BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1:
+  case BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2:
+  case BROTLI_DECODER_ERROR_FORMAT_TRANSFORM:
+  case BROTLI_DECODER_ERROR_FORMAT_DICTIONARY:
+  case BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS:
+  case BROTLI_DECODER_ERROR_FORMAT_PADDING_1:
+  case BROTLI_DECODER_ERROR_FORMAT_PADDING_2:
+  case BROTLI_DECODER_ERROR_COMPOUND_DICTIONARY:
+  case BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET:
+  case BROTLI_DECODER_ERROR_INVALID_ARGUMENTS:
+    return CURLE_BAD_CONTENT_ENCODING;
+  case BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES:
+  case BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS:
+  case BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP:
+  case BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1:
+  case BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2:
+  case BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES:
+    return CURLE_OUT_OF_MEMORY;
+  default:
+    break;
+  }
+  return CURLE_WRITE_ERROR;
+}
+
+static CURLcode brotli_init_writer(struct connectdata *conn,
+                                   contenc_writer *writer)
+{
+  brotli_params *bp = (brotli_params *) &writer->params;
+
+  (void) conn;
+
+  if(!writer->downstream)
+    return CURLE_WRITE_ERROR;
+
+  bp->br = BrotliDecoderCreateInstance(NULL, NULL, NULL);
+  return bp->br? CURLE_OK: CURLE_OUT_OF_MEMORY;
+}
+
+static CURLcode brotli_unencode_write(struct connectdata *conn,
+                                      contenc_writer *writer,
+                                      const char *buf, size_t nbytes)
+{
+  brotli_params *bp = (brotli_params *) &writer->params;
+  const uint8_t *src = (const uint8_t *) buf;
+  char *decomp;
+  uint8_t *dst;
+  size_t dstleft;
+  CURLcode result = CURLE_OK;
+
+  if(!bp->br)
+    return CURLE_WRITE_ERROR;  /* Stream already ended. */
+
+  decomp = malloc(DSIZ);
+  if(!decomp)
+    return CURLE_OUT_OF_MEMORY;
+
+  while(nbytes && result == CURLE_OK) {
+    BrotliDecoderResult r;
+
+    dst = (uint8_t *) decomp;
+    dstleft = DSIZ;
+    r = BrotliDecoderDecompressStream(bp->br,
+                                      &nbytes, &src, &dstleft, &dst, NULL);
+    result = Curl_unencode_write(conn, writer->downstream,
+                                 decomp, DSIZ - dstleft);
+    if(result)
+      break;
+    switch(r) {
+    case BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT:
+    case BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT:
+      break;
+    case BROTLI_DECODER_RESULT_SUCCESS:
+      BrotliDecoderDestroyInstance(bp->br);
+      bp->br = NULL;
+      if(nbytes)
+        result = CURLE_WRITE_ERROR;
+      break;
+    default:
+      result = brotli_map_error(BrotliDecoderGetErrorCode(bp->br));
+      break;
+    }
+  }
+  free(decomp);
+  return result;
+}
+
+static void brotli_close_writer(struct connectdata *conn,
+                                contenc_writer *writer)
+{
+  brotli_params *bp = (brotli_params *) &writer->params;
+
+  (void) conn;
+
+  if(bp->br) {
+    BrotliDecoderDestroyInstance(bp->br);
+    bp->br = NULL;
+  }
+}
+
+static const content_encoding brotli_encoding = {
+  "br",
+  NULL,
+  brotli_init_writer,
+  brotli_unencode_write,
+  brotli_close_writer,
+  sizeof(brotli_params)
+};
+#endif
+
+
+/* Identity handler. */
+static CURLcode identity_init_writer(struct connectdata *conn,
+                                     contenc_writer *writer)
+{
+  (void) conn;
+  return writer->downstream? CURLE_OK: CURLE_WRITE_ERROR;
+}
+
+static CURLcode identity_unencode_write(struct connectdata *conn,
+                                        contenc_writer *writer,
+                                        const char *buf, size_t nbytes)
+{
+  return Curl_unencode_write(conn, writer->downstream, buf, nbytes);
+}
+
+static void identity_close_writer(struct connectdata *conn,
+                                  contenc_writer *writer)
+{
+  (void) conn;
+  (void) writer;
+}
+
+static const content_encoding identity_encoding = {
+  "identity",
+  NULL,
+  identity_init_writer,
+  identity_unencode_write,
+  identity_close_writer,
+  0
+};
+
+
+/* supported content encodings table. */
+static const content_encoding * const encodings[] = {
+  &identity_encoding,
+#ifdef HAVE_LIBZ
+  &deflate_encoding,
+  &gzip_encoding,
+#endif
+#ifdef HAVE_BROTLI
+  &brotli_encoding,
+#endif
+  NULL
+};
+
+
+/* Return a list of comma-separated names of supported encodings. */
+char *Curl_all_content_encodings(void)
+{
+  size_t len = 0;
+  const content_encoding * const *cep;
+  const content_encoding *ce;
+  char *ace;
+  char *p;
+
+  for(cep = encodings; *cep; cep++) {
+    ce = *cep;
+    if(!strcasecompare(ce->name, CONTENT_ENCODING_DEFAULT))
+      len += strlen(ce->name) + 2;
+  }
+
+  if(!len)
+    return strdup(CONTENT_ENCODING_DEFAULT);
+
+  ace = malloc(len);
+  if(ace) {
+    p = ace;
+    for(cep = encodings; *cep; cep++) {
+      ce = *cep;
+      if(!strcasecompare(ce->name, CONTENT_ENCODING_DEFAULT)) {
+        strcpy(p, ce->name);
+        p += strlen(p);
+        *p++ = ',';
+        *p++ = ' ';
+      }
+    }
+    p[-2] = '\0';
+  }
+
+  return ace;
+}
+
+
+/* Real client writer: no downstream. */
+static CURLcode client_init_writer(struct connectdata *conn,
+                                   contenc_writer *writer)
+{
+  (void) conn;
+  return writer->downstream? CURLE_WRITE_ERROR: CURLE_OK;
+}
+
+static CURLcode client_unencode_write(struct connectdata *conn,
+                                      contenc_writer *writer,
+                                      const char *buf, size_t nbytes)
+{
+  struct Curl_easy *data = conn->data;
+  struct SingleRequest *k = &data->req;
+
+  (void) writer;
+
+  if(!nbytes || k->ignorebody)
+    return CURLE_OK;
+
+  return Curl_client_write(conn, CLIENTWRITE_BODY, (char *) buf, nbytes);
+}
+
+static void client_close_writer(struct connectdata *conn,
+                                contenc_writer *writer)
+{
+  (void) conn;
+  (void) writer;
+}
+
+static const content_encoding client_encoding = {
+  NULL,
+  NULL,
+  client_init_writer,
+  client_unencode_write,
+  client_close_writer,
+  0
+};
+
+
+/* Deferred error dummy writer. */
+static CURLcode error_init_writer(struct connectdata *conn,
+                                  contenc_writer *writer)
+{
+  (void) conn;
+  return writer->downstream? CURLE_OK: CURLE_WRITE_ERROR;
+}
+
+static CURLcode error_unencode_write(struct connectdata *conn,
+                                     contenc_writer *writer,
+                                     const char *buf, size_t nbytes)
+{
+  char *all = Curl_all_content_encodings();
+
+  (void) writer;
+  (void) buf;
+  (void) nbytes;
+
+  if(!all)
+    return CURLE_OUT_OF_MEMORY;
+  failf(conn->data, "Unrecognized content encoding type. "
+                    "libcurl understands %s content encodings.", all);
+  free(all);
+  return CURLE_BAD_CONTENT_ENCODING;
+}
+
+static void error_close_writer(struct connectdata *conn,
+                               contenc_writer *writer)
+{
+  (void) conn;
+  (void) writer;
+}
+
+static const content_encoding error_encoding = {
+  NULL,
+  NULL,
+  error_init_writer,
+  error_unencode_write,
+  error_close_writer,
+  0
+};
+
+/* Create an unencoding writer stage using the given handler. */
+static contenc_writer *new_unencoding_writer(struct connectdata *conn,
+                                             const content_encoding *handler,
+                                             contenc_writer *downstream)
+{
+  size_t sz = offsetof(contenc_writer, params) + handler->paramsize;
+  contenc_writer *writer = (contenc_writer *) malloc(sz);
+
+  if(writer) {
+    memset(writer, 0, sz);
+    writer->handler = handler;
+    writer->downstream = downstream;
+    if(handler->init_writer(conn, writer)) {
+      free(writer);
+      writer = NULL;
+    }
+  }
+
+  return writer;
+}
+
+/* Write data using an unencoding writer stack. */
+CURLcode Curl_unencode_write(struct connectdata *conn, contenc_writer *writer,
+                             const char *buf, size_t nbytes)
+{
+  if(!nbytes)
+    return CURLE_OK;
+  return writer->handler->unencode_write(conn, writer, buf, nbytes);
+}
+
+/* Close and clean-up the connection's writer stack. */
+void Curl_unencode_cleanup(struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  struct SingleRequest *k = &data->req;
+  contenc_writer *writer = k->writer_stack;
+
+  while(writer) {
+    k->writer_stack = writer->downstream;
+    writer->handler->close_writer(conn, writer);
+    free(writer);
+    writer = k->writer_stack;
+  }
+}
+
+/* Find the content encoding by name. */
+static const content_encoding *find_encoding(const char *name, size_t len)
+{
+  const content_encoding * const *cep;
+  const content_encoding *ce;
+
+  for(cep = encodings; *cep; cep++) {
+    ce = *cep;
+    if((strncasecompare(name, ce->name, len) && !ce->name[len]) ||
+       (ce->alias && strncasecompare(name, ce->alias, len) && !ce->alias[len]))
+      return ce;
+  }
+  return NULL;
+}
+
+/* Set-up the unencoding stack from the Content-Encoding header value.
+ * See RFC 7231 section 3.1.2.2. */
+CURLcode Curl_build_unencoding_stack(struct connectdata *conn,
+                                     const char *enclist, int maybechunked)
+{
+  struct Curl_easy *data = conn->data;
+  struct SingleRequest *k = &data->req;
+
+  do {
+    const char *name;
+    size_t namelen;
+
+    /* Parse a single encoding name. */
+    while(ISSPACE(*enclist) || *enclist == ',')
+      enclist++;
+
+    name = enclist;
+
+    for(namelen = 0; *enclist && *enclist != ','; enclist++)
+      if(!ISSPACE(*enclist))
+        namelen = enclist - name + 1;
+
+    /* Special case: chunked encoding is handled at the reader level. */
+    if(maybechunked && namelen == 7 && strncasecompare(name, "chunked", 7)) {
+      k->chunk = TRUE;             /* chunks coming our way. */
+      Curl_httpchunk_init(conn);   /* init our chunky engine. */
+    }
+    else if(namelen) {
+      const content_encoding *encoding = find_encoding(name, namelen);
+      contenc_writer *writer;
+
+      if(!k->writer_stack) {
+        k->writer_stack = new_unencoding_writer(conn, &client_encoding, NULL);
+
+        if(!k->writer_stack)
+          return CURLE_OUT_OF_MEMORY;
+      }
+
+      if(!encoding)
+        encoding = &error_encoding;  /* Defer error at stack use. */
+
+      /* Stack the unencoding stage. */
+      writer = new_unencoding_writer(conn, encoding, k->writer_stack);
+      if(!writer)
+        return CURLE_OUT_OF_MEMORY;
+      k->writer_stack = writer;
+    }
+  } while(*enclist);
+
+  return CURLE_OK;
+}
+
+#else
+/* Stubs for builds without HTTP. */
+CURLcode Curl_build_unencoding_stack(struct connectdata *conn,
+                                     const char *enclist, int maybechunked)
+{
+  (void) conn;
+  (void) enclist;
+  (void) maybechunked;
+  return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode Curl_unencode_write(struct connectdata *conn, contenc_writer *writer,
+                             const char *buf, size_t nbytes)
+{
+  (void) conn;
+  (void) writer;
+  (void) buf;
+  (void) nbytes;
+  return CURLE_NOT_BUILT_IN;
+}
+
+void Curl_unencode_cleanup(struct connectdata *conn)
+{
+  (void) conn;
+}
+
+char *Curl_all_content_encodings(void)
+{
+  return strdup(CONTENT_ENCODING_DEFAULT);  /* Satisfy caller. */
+}
+
+#endif /* CURL_DISABLE_HTTP */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/content_encoding.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/content_encoding.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/content_encoding.h	(revision 331)
@@ -0,0 +1,55 @@
+#ifndef HEADER_CURL_CONTENT_ENCODING_H
+#define HEADER_CURL_CONTENT_ENCODING_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+/* Decoding writer. */
+typedef struct contenc_writer_s contenc_writer;
+typedef struct content_encoding_s content_encoding;
+
+struct contenc_writer_s {
+  const content_encoding *handler;  /* Encoding handler. */
+  contenc_writer *downstream;  /* Downstream writer. */
+  void *params;  /* Encoding-specific storage (variable length). */
+};
+
+/* Content encoding writer. */
+struct content_encoding_s {
+  const char *name;        /* Encoding name. */
+  const char *alias;       /* Encoding name alias. */
+  CURLcode (*init_writer)(struct connectdata *conn, contenc_writer *writer);
+  CURLcode (*unencode_write)(struct connectdata *conn, contenc_writer *writer,
+                             const char *buf, size_t nbytes);
+  void (*close_writer)(struct connectdata *conn, contenc_writer *writer);
+  size_t paramsize;
+};
+
+
+CURLcode Curl_build_unencoding_stack(struct connectdata *conn,
+                                     const char *enclist, int maybechunked);
+CURLcode Curl_unencode_write(struct connectdata *conn, contenc_writer *writer,
+                             const char *buf, size_t nbytes);
+void Curl_unencode_cleanup(struct connectdata *conn);
+char *Curl_all_content_encodings(void);
+
+#endif /* HEADER_CURL_CONTENT_ENCODING_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/cookie.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/cookie.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/cookie.c	(revision 331)
@@ -0,0 +1,1479 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/***
+
+
+RECEIVING COOKIE INFORMATION
+============================
+
+struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
+                    const char *file, struct CookieInfo *inc, bool newsession);
+
+        Inits a cookie struct to store data in a local file. This is always
+        called before any cookies are set.
+
+struct Cookie *Curl_cookie_add(struct Curl_easy *data,
+                 struct CookieInfo *c, bool httpheader, char *lineptr,
+                 const char *domain, const char *path);
+
+        The 'lineptr' parameter is a full "Set-cookie:" line as
+        received from a server.
+
+        The function need to replace previously stored lines that this new
+        line superceeds.
+
+        It may remove lines that are expired.
+
+        It should return an indication of success/error.
+
+
+SENDING COOKIE INFORMATION
+==========================
+
+struct Cookies *Curl_cookie_getlist(struct CookieInfo *cookie,
+                                    char *host, char *path, bool secure);
+
+        For a given host and path, return a linked list of cookies that
+        the client should send to the server if used now. The secure
+        boolean informs the cookie if a secure connection is achieved or
+        not.
+
+        It shall only return cookies that haven't expired.
+
+
+Example set of cookies:
+
+    Set-cookie: PRODUCTINFO=webxpress; domain=.fidelity.com; path=/; secure
+    Set-cookie: PERSONALIZE=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
+    domain=.fidelity.com; path=/ftgw; secure
+    Set-cookie: FidHist=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
+    domain=.fidelity.com; path=/; secure
+    Set-cookie: FidOrder=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
+    domain=.fidelity.com; path=/; secure
+    Set-cookie: DisPend=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
+    domain=.fidelity.com; path=/; secure
+    Set-cookie: FidDis=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
+    domain=.fidelity.com; path=/; secure
+    Set-cookie:
+    Session_Key@6791a9e0-901a-11d0-a1c8-9b012c88aa77=none;expires=Monday,
+    13-Jun-1988 03:04:55 GMT; domain=.fidelity.com; path=/; secure
+****/
+
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+
+#ifdef USE_LIBPSL
+# include <libpsl.h>
+#endif
+
+#include "urldata.h"
+#include "cookie.h"
+#include "strtok.h"
+#include "sendf.h"
+#include "slist.h"
+#include "share.h"
+#include "strtoofft.h"
+#include "strcase.h"
+#include "curl_memrchr.h"
+#include "inet_pton.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+static void freecookie(struct Cookie *co)
+{
+  free(co->expirestr);
+  free(co->domain);
+  free(co->path);
+  free(co->spath);
+  free(co->name);
+  free(co->value);
+  free(co->maxage);
+  free(co->version);
+  free(co);
+}
+
+static bool tailmatch(const char *cooke_domain, const char *hostname)
+{
+  size_t cookie_domain_len = strlen(cooke_domain);
+  size_t hostname_len = strlen(hostname);
+
+  if(hostname_len < cookie_domain_len)
+    return FALSE;
+
+  if(!strcasecompare(cooke_domain, hostname + hostname_len-cookie_domain_len))
+    return FALSE;
+
+  /* A lead char of cookie_domain is not '.'.
+     RFC6265 4.1.2.3. The Domain Attribute says:
+       For example, if the value of the Domain attribute is
+       "example.com", the user agent will include the cookie in the Cookie
+       header when making HTTP requests to example.com, www.example.com, and
+       www.corp.example.com.
+   */
+  if(hostname_len == cookie_domain_len)
+    return TRUE;
+  if('.' == *(hostname + hostname_len - cookie_domain_len - 1))
+    return TRUE;
+  return FALSE;
+}
+
+/*
+ * matching cookie path and url path
+ * RFC6265 5.1.4 Paths and Path-Match
+ */
+static bool pathmatch(const char *cookie_path, const char *request_uri)
+{
+  size_t cookie_path_len;
+  size_t uri_path_len;
+  char *uri_path = NULL;
+  char *pos;
+  bool ret = FALSE;
+
+  /* cookie_path must not have last '/' separator. ex: /sample */
+  cookie_path_len = strlen(cookie_path);
+  if(1 == cookie_path_len) {
+    /* cookie_path must be '/' */
+    return TRUE;
+  }
+
+  uri_path = strdup(request_uri);
+  if(!uri_path)
+    return FALSE;
+  pos = strchr(uri_path, '?');
+  if(pos)
+    *pos = 0x0;
+
+  /* #-fragments are already cut off! */
+  if(0 == strlen(uri_path) || uri_path[0] != '/') {
+    free(uri_path);
+    uri_path = strdup("/");
+    if(!uri_path)
+      return FALSE;
+  }
+
+  /* here, RFC6265 5.1.4 says
+     4. Output the characters of the uri-path from the first character up
+        to, but not including, the right-most %x2F ("/").
+     but URL path /hoge?fuga=xxx means /hoge/index.cgi?fuga=xxx in some site
+     without redirect.
+     Ignore this algorithm because /hoge is uri path for this case
+     (uri path is not /).
+   */
+
+  uri_path_len = strlen(uri_path);
+
+  if(uri_path_len < cookie_path_len) {
+    ret = FALSE;
+    goto pathmatched;
+  }
+
+  /* not using checkprefix() because matching should be case-sensitive */
+  if(strncmp(cookie_path, uri_path, cookie_path_len)) {
+    ret = FALSE;
+    goto pathmatched;
+  }
+
+  /* The cookie-path and the uri-path are identical. */
+  if(cookie_path_len == uri_path_len) {
+    ret = TRUE;
+    goto pathmatched;
+  }
+
+  /* here, cookie_path_len < url_path_len */
+  if(uri_path[cookie_path_len] == '/') {
+    ret = TRUE;
+    goto pathmatched;
+  }
+
+  ret = FALSE;
+
+pathmatched:
+  free(uri_path);
+  return ret;
+}
+
+/*
+ * cookie path sanitize
+ */
+static char *sanitize_cookie_path(const char *cookie_path)
+{
+  size_t len;
+  char *new_path = strdup(cookie_path);
+  if(!new_path)
+    return NULL;
+
+  /* some stupid site sends path attribute with '"'. */
+  len = strlen(new_path);
+  if(new_path[0] == '\"') {
+    memmove((void *)new_path, (const void *)(new_path + 1), len);
+    len--;
+  }
+  if(len && (new_path[len - 1] == '\"')) {
+    new_path[len - 1] = 0x0;
+    len--;
+  }
+
+  /* RFC6265 5.2.4 The Path Attribute */
+  if(new_path[0] != '/') {
+    /* Let cookie-path be the default-path. */
+    free(new_path);
+    new_path = strdup("/");
+    return new_path;
+  }
+
+  /* convert /hoge/ to /hoge */
+  if(len && new_path[len - 1] == '/') {
+    new_path[len - 1] = 0x0;
+  }
+
+  return new_path;
+}
+
+/*
+ * Load cookies from all given cookie files (CURLOPT_COOKIEFILE).
+ *
+ * NOTE: OOM or cookie parsing failures are ignored.
+ */
+void Curl_cookie_loadfiles(struct Curl_easy *data)
+{
+  struct curl_slist *list = data->change.cookielist;
+  if(list) {
+    Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+    while(list) {
+      struct CookieInfo *newcookies = Curl_cookie_init(data,
+                                        list->data,
+                                        data->cookies,
+                                        data->set.cookiesession);
+      if(!newcookies)
+        /* Failure may be due to OOM or a bad cookie; both are ignored
+         * but only the first should be
+         */
+        infof(data, "ignoring failed cookie_init for %s\n", list->data);
+      else
+        data->cookies = newcookies;
+      list = list->next;
+    }
+    curl_slist_free_all(data->change.cookielist); /* clean up list */
+    data->change.cookielist = NULL; /* don't do this again! */
+    Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+  }
+}
+
+/*
+ * strstore() makes a strdup() on the 'newstr' and if '*str' is non-NULL
+ * that will be freed before the allocated string is stored there.
+ *
+ * It is meant to easily replace strdup()
+ */
+static void strstore(char **str, const char *newstr)
+{
+  free(*str);
+  *str = strdup(newstr);
+}
+
+/*
+ * remove_expired() removes expired cookies.
+ */
+static void remove_expired(struct CookieInfo *cookies)
+{
+  struct Cookie *co, *nx, *pv;
+  curl_off_t now = (curl_off_t)time(NULL);
+
+  co = cookies->cookies;
+  pv = NULL;
+  while(co) {
+    nx = co->next;
+    if(co->expires && co->expires < now) {
+      if(!pv) {
+        cookies->cookies = co->next;
+      }
+      else {
+        pv->next = co->next;
+      }
+      cookies->numcookies--;
+      freecookie(co);
+    }
+    else {
+      pv = co;
+    }
+    co = nx;
+  }
+}
+
+/*
+ * Return true if the given string is an IP(v4|v6) address.
+ */
+static bool isip(const char *domain)
+{
+  struct in_addr addr;
+#ifdef ENABLE_IPV6
+  struct in6_addr addr6;
+#endif
+
+  if(Curl_inet_pton(AF_INET, domain, &addr)
+#ifdef ENABLE_IPV6
+     || Curl_inet_pton(AF_INET6, domain, &addr6)
+#endif
+    ) {
+    /* domain name given as IP address */
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/****************************************************************************
+ *
+ * Curl_cookie_add()
+ *
+ * Add a single cookie line to the cookie keeping object.
+ *
+ * Be aware that sometimes we get an IP-only host name, and that might also be
+ * a numerical IPv6 address.
+ *
+ * Returns NULL on out of memory or invalid cookie. This is suboptimal,
+ * as they should be treated separately.
+ ***************************************************************************/
+
+struct Cookie *
+Curl_cookie_add(struct Curl_easy *data,
+                /* The 'data' pointer here may be NULL at times, and thus
+                   must only be used very carefully for things that can deal
+                   with data being NULL. Such as infof() and similar */
+
+                struct CookieInfo *c,
+                bool httpheader, /* TRUE if HTTP header-style line */
+                char *lineptr,   /* first character of the line */
+                const char *domain, /* default domain */
+                const char *path)   /* full path used when this cookie is set,
+                                       used to get default path for the cookie
+                                       unless set */
+{
+  struct Cookie *clist;
+  struct Cookie *co;
+  struct Cookie *lastc = NULL;
+  time_t now = time(NULL);
+  bool replace_old = FALSE;
+  bool badcookie = FALSE; /* cookies are good by default. mmmmm yummy */
+
+#ifdef USE_LIBPSL
+  const psl_ctx_t *psl;
+#endif
+
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+  (void)data;
+#endif
+
+  /* First, alloc and init a new struct for it */
+  co = calloc(1, sizeof(struct Cookie));
+  if(!co)
+    return NULL; /* bail out if we're this low on memory */
+
+  if(httpheader) {
+    /* This line was read off a HTTP-header */
+    char name[MAX_NAME];
+    char what[MAX_NAME];
+    const char *ptr;
+    const char *semiptr;
+
+    size_t linelength = strlen(lineptr);
+    if(linelength > MAX_COOKIE_LINE) {
+      /* discard overly long lines at once */
+      free(co);
+      return NULL;
+    }
+
+    semiptr = strchr(lineptr, ';'); /* first, find a semicolon */
+
+    while(*lineptr && ISBLANK(*lineptr))
+      lineptr++;
+
+    ptr = lineptr;
+    do {
+      /* we have a <what>=<this> pair or a stand-alone word here */
+      name[0] = what[0] = 0; /* init the buffers */
+      if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;\r\n=] =%"
+                     MAX_NAME_TXT "[^;\r\n]",
+                     name, what)) {
+        /* Use strstore() below to properly deal with received cookie
+           headers that have the same string property set more than once,
+           and then we use the last one. */
+        const char *whatptr;
+        bool done = FALSE;
+        bool sep;
+        size_t len = strlen(what);
+        size_t nlen = strlen(name);
+        const char *endofn = &ptr[ nlen ];
+
+        infof(data, "cookie size: name/val %d + %d bytes\n",
+              nlen, len);
+
+        if(nlen >= (MAX_NAME-1) || len >= (MAX_NAME-1) ||
+           ((nlen + len) > MAX_NAME)) {
+          /* too long individual name or contents, or too long combination of
+             name + contents. Chrome and Firefox support 4095 or 4096 bytes
+             combo. */
+          freecookie(co);
+          infof(data, "oversized cookie dropped, name/val %d + %d bytes\n",
+                nlen, len);
+          return NULL;
+        }
+
+        /* name ends with a '=' ? */
+        sep = (*endofn == '=')?TRUE:FALSE;
+
+        if(nlen) {
+          endofn--; /* move to the last character */
+          if(ISBLANK(*endofn)) {
+            /* skip trailing spaces in name */
+            while(*endofn && ISBLANK(*endofn) && nlen) {
+              endofn--;
+              nlen--;
+            }
+            name[nlen] = 0; /* new end of name */
+          }
+        }
+
+        /* Strip off trailing whitespace from the 'what' */
+        while(len && ISBLANK(what[len-1])) {
+          what[len-1] = 0;
+          len--;
+        }
+
+        /* Skip leading whitespace from the 'what' */
+        whatptr = what;
+        while(*whatptr && ISBLANK(*whatptr))
+          whatptr++;
+
+        if(!co->name && sep) {
+          /* The very first name/value pair is the actual cookie name */
+          co->name = strdup(name);
+          co->value = strdup(whatptr);
+          if(!co->name || !co->value) {
+            badcookie = TRUE;
+            break;
+          }
+        }
+        else if(!len) {
+          /* this was a "<name>=" with no content, and we must allow
+             'secure' and 'httponly' specified this weirdly */
+          done = TRUE;
+          if(strcasecompare("secure", name))
+            co->secure = TRUE;
+          else if(strcasecompare("httponly", name))
+            co->httponly = TRUE;
+          else if(sep)
+            /* there was a '=' so we're not done parsing this field */
+            done = FALSE;
+        }
+        if(done)
+          ;
+        else if(strcasecompare("path", name)) {
+          strstore(&co->path, whatptr);
+          if(!co->path) {
+            badcookie = TRUE; /* out of memory bad */
+            break;
+          }
+          free(co->spath); /* if this is set again */
+          co->spath = sanitize_cookie_path(co->path);
+          if(!co->spath) {
+            badcookie = TRUE; /* out of memory bad */
+            break;
+          }
+        }
+        else if(strcasecompare("domain", name)) {
+          bool is_ip;
+
+          /* Now, we make sure that our host is within the given domain,
+             or the given domain is not valid and thus cannot be set. */
+
+          if('.' == whatptr[0])
+            whatptr++; /* ignore preceding dot */
+
+#ifndef USE_LIBPSL
+          /*
+           * Without PSL we don't know when the incoming cookie is set on a
+           * TLD or otherwise "protected" suffix. To reduce risk, we require a
+           * dot OR the exact host name being "localhost".
+           */
+          {
+            const char *dotp;
+            /* check for more dots */
+            dotp = strchr(whatptr, '.');
+            if(!dotp && !strcasecompare("localhost", whatptr))
+              domain = ":";
+          }
+#endif
+
+          is_ip = isip(domain ? domain : whatptr);
+
+          if(!domain
+             || (is_ip && !strcmp(whatptr, domain))
+             || (!is_ip && tailmatch(whatptr, domain))) {
+            strstore(&co->domain, whatptr);
+            if(!co->domain) {
+              badcookie = TRUE;
+              break;
+            }
+            if(!is_ip)
+              co->tailmatch = TRUE; /* we always do that if the domain name was
+                                       given */
+          }
+          else {
+            /* we did not get a tailmatch and then the attempted set domain
+               is not a domain to which the current host belongs. Mark as
+               bad. */
+            badcookie = TRUE;
+            infof(data, "skipped cookie with bad tailmatch domain: %s\n",
+                  whatptr);
+          }
+        }
+        else if(strcasecompare("version", name)) {
+          strstore(&co->version, whatptr);
+          if(!co->version) {
+            badcookie = TRUE;
+            break;
+          }
+        }
+        else if(strcasecompare("max-age", name)) {
+          /* Defined in RFC2109:
+
+             Optional.  The Max-Age attribute defines the lifetime of the
+             cookie, in seconds.  The delta-seconds value is a decimal non-
+             negative integer.  After delta-seconds seconds elapse, the
+             client should discard the cookie.  A value of zero means the
+             cookie should be discarded immediately.
+
+          */
+          strstore(&co->maxage, whatptr);
+          if(!co->maxage) {
+            badcookie = TRUE;
+            break;
+          }
+        }
+        else if(strcasecompare("expires", name)) {
+          strstore(&co->expirestr, whatptr);
+          if(!co->expirestr) {
+            badcookie = TRUE;
+            break;
+          }
+        }
+        /*
+          else this is the second (or more) name we don't know
+          about! */
+      }
+      else {
+        /* this is an "illegal" <what>=<this> pair */
+      }
+
+      if(!semiptr || !*semiptr) {
+        /* we already know there are no more cookies */
+        semiptr = NULL;
+        continue;
+      }
+
+      ptr = semiptr + 1;
+      while(*ptr && ISBLANK(*ptr))
+        ptr++;
+      semiptr = strchr(ptr, ';'); /* now, find the next semicolon */
+
+      if(!semiptr && *ptr)
+        /* There are no more semicolons, but there's a final name=value pair
+           coming up */
+        semiptr = strchr(ptr, '\0');
+    } while(semiptr);
+
+    if(co->maxage) {
+      CURLofft offt;
+      offt = curlx_strtoofft((*co->maxage == '\"')?
+                             &co->maxage[1]:&co->maxage[0], NULL, 10,
+                             &co->expires);
+      if(offt == CURL_OFFT_FLOW)
+        /* overflow, used max value */
+        co->expires = CURL_OFF_T_MAX;
+      else if(!offt) {
+        if(CURL_OFF_T_MAX - now < co->expires)
+          /* would overflow */
+          co->expires = CURL_OFF_T_MAX;
+        else
+          co->expires += now;
+      }
+    }
+    else if(co->expirestr) {
+      /* Note that if the date couldn't get parsed for whatever reason,
+         the cookie will be treated as a session cookie */
+      co->expires = curl_getdate(co->expirestr, NULL);
+
+      /* Session cookies have expires set to 0 so if we get that back
+         from the date parser let's add a second to make it a
+         non-session cookie */
+      if(co->expires == 0)
+        co->expires = 1;
+      else if(co->expires < 0)
+        co->expires = 0;
+    }
+
+    if(!badcookie && !co->domain) {
+      if(domain) {
+        /* no domain was given in the header line, set the default */
+        co->domain = strdup(domain);
+        if(!co->domain)
+          badcookie = TRUE;
+      }
+    }
+
+    if(!badcookie && !co->path && path) {
+      /* No path was given in the header line, set the default.
+         Note that the passed-in path to this function MAY have a '?' and
+         following part that MUST not be stored as part of the path. */
+      char *queryp = strchr(path, '?');
+
+      /* queryp is where the interesting part of the path ends, so now we
+         want to the find the last */
+      char *endslash;
+      if(!queryp)
+        endslash = strrchr(path, '/');
+      else
+        endslash = memrchr(path, '/', (size_t)(queryp - path));
+      if(endslash) {
+        size_t pathlen = (size_t)(endslash-path + 1); /* include end slash */
+        co->path = malloc(pathlen + 1); /* one extra for the zero byte */
+        if(co->path) {
+          memcpy(co->path, path, pathlen);
+          co->path[pathlen] = 0; /* zero terminate */
+          co->spath = sanitize_cookie_path(co->path);
+          if(!co->spath)
+            badcookie = TRUE; /* out of memory bad */
+        }
+        else
+          badcookie = TRUE;
+      }
+    }
+
+    if(badcookie || !co->name) {
+      /* we didn't get a cookie name or a bad one,
+         this is an illegal line, bail out */
+      freecookie(co);
+      return NULL;
+    }
+
+  }
+  else {
+    /* This line is NOT a HTTP header style line, we do offer support for
+       reading the odd netscape cookies-file format here */
+    char *ptr;
+    char *firstptr;
+    char *tok_buf = NULL;
+    int fields;
+
+    /* IE introduced HTTP-only cookies to prevent XSS attacks. Cookies
+       marked with httpOnly after the domain name are not accessible
+       from javascripts, but since curl does not operate at javascript
+       level, we include them anyway. In Firefox's cookie files, these
+       lines are preceded with #HttpOnly_ and then everything is
+       as usual, so we skip 10 characters of the line..
+    */
+    if(strncmp(lineptr, "#HttpOnly_", 10) == 0) {
+      lineptr += 10;
+      co->httponly = TRUE;
+    }
+
+    if(lineptr[0]=='#') {
+      /* don't even try the comments */
+      free(co);
+      return NULL;
+    }
+    /* strip off the possible end-of-line characters */
+    ptr = strchr(lineptr, '\r');
+    if(ptr)
+      *ptr = 0; /* clear it */
+    ptr = strchr(lineptr, '\n');
+    if(ptr)
+      *ptr = 0; /* clear it */
+
+    firstptr = strtok_r(lineptr, "\t", &tok_buf); /* tokenize it on the TAB */
+
+    /* Now loop through the fields and init the struct we already have
+       allocated */
+    for(ptr = firstptr, fields = 0; ptr && !badcookie;
+        ptr = strtok_r(NULL, "\t", &tok_buf), fields++) {
+      switch(fields) {
+      case 0:
+        if(ptr[0]=='.') /* skip preceding dots */
+          ptr++;
+        co->domain = strdup(ptr);
+        if(!co->domain)
+          badcookie = TRUE;
+        break;
+      case 1:
+        /* This field got its explanation on the 23rd of May 2001 by
+           Andrés García:
+
+           flag: A TRUE/FALSE value indicating if all machines within a given
+           domain can access the variable. This value is set automatically by
+           the browser, depending on the value you set for the domain.
+
+           As far as I can see, it is set to true when the cookie says
+           .domain.com and to false when the domain is complete www.domain.com
+        */
+        co->tailmatch = strcasecompare(ptr, "TRUE")?TRUE:FALSE;
+        break;
+      case 2:
+        /* It turns out, that sometimes the file format allows the path
+           field to remain not filled in, we try to detect this and work
+           around it! Andrés García made us aware of this... */
+        if(strcmp("TRUE", ptr) && strcmp("FALSE", ptr)) {
+          /* only if the path doesn't look like a boolean option! */
+          co->path = strdup(ptr);
+          if(!co->path)
+            badcookie = TRUE;
+          else {
+            co->spath = sanitize_cookie_path(co->path);
+            if(!co->spath) {
+              badcookie = TRUE; /* out of memory bad */
+            }
+          }
+          break;
+        }
+        /* this doesn't look like a path, make one up! */
+        co->path = strdup("/");
+        if(!co->path)
+          badcookie = TRUE;
+        co->spath = strdup("/");
+        if(!co->spath)
+          badcookie = TRUE;
+        fields++; /* add a field and fall down to secure */
+        /* FALLTHROUGH */
+      case 3:
+        co->secure = strcasecompare(ptr, "TRUE")?TRUE:FALSE;
+        break;
+      case 4:
+        if(curlx_strtoofft(ptr, NULL, 10, &co->expires))
+          badcookie = TRUE;
+        break;
+      case 5:
+        co->name = strdup(ptr);
+        if(!co->name)
+          badcookie = TRUE;
+        break;
+      case 6:
+        co->value = strdup(ptr);
+        if(!co->value)
+          badcookie = TRUE;
+        break;
+      }
+    }
+    if(6 == fields) {
+      /* we got a cookie with blank contents, fix it */
+      co->value = strdup("");
+      if(!co->value)
+        badcookie = TRUE;
+      else
+        fields++;
+    }
+
+    if(!badcookie && (7 != fields))
+      /* we did not find the sufficient number of fields */
+      badcookie = TRUE;
+
+    if(badcookie) {
+      freecookie(co);
+      return NULL;
+    }
+
+  }
+
+  if(!c->running &&    /* read from a file */
+     c->newsession &&  /* clean session cookies */
+     !co->expires) {   /* this is a session cookie since it doesn't expire! */
+    freecookie(co);
+    return NULL;
+  }
+
+  co->livecookie = c->running;
+
+  /* now, we have parsed the incoming line, we must now check if this
+     superceeds an already existing cookie, which it may if the previous have
+     the same domain and path as this */
+
+  /* at first, remove expired cookies */
+  remove_expired(c);
+
+#ifdef USE_LIBPSL
+  /* Check if the domain is a Public Suffix and if yes, ignore the cookie.
+     This needs a libpsl compiled with builtin data. */
+  if(domain && co->domain && !isip(co->domain)) {
+    psl = psl_builtin();
+    if(psl && !psl_is_cookie_domain_acceptable(psl, domain, co->domain)) {
+      infof(data,
+            "cookie '%s' dropped, domain '%s' must not set cookies for '%s'\n",
+            co->name, domain, co->domain);
+      freecookie(co);
+      return NULL;
+    }
+  }
+#endif
+
+  clist = c->cookies;
+  replace_old = FALSE;
+  while(clist) {
+    if(strcasecompare(clist->name, co->name)) {
+      /* the names are identical */
+
+      if(clist->domain && co->domain) {
+        if(strcasecompare(clist->domain, co->domain) &&
+          (clist->tailmatch == co->tailmatch))
+          /* The domains are identical */
+          replace_old = TRUE;
+      }
+      else if(!clist->domain && !co->domain)
+        replace_old = TRUE;
+
+      if(replace_old) {
+        /* the domains were identical */
+
+        if(clist->spath && co->spath) {
+          if(strcasecompare(clist->spath, co->spath)) {
+            replace_old = TRUE;
+          }
+          else
+            replace_old = FALSE;
+        }
+        else if(!clist->spath && !co->spath)
+          replace_old = TRUE;
+        else
+          replace_old = FALSE;
+
+      }
+
+      if(replace_old && !co->livecookie && clist->livecookie) {
+        /* Both cookies matched fine, except that the already present
+           cookie is "live", which means it was set from a header, while
+           the new one isn't "live" and thus only read from a file. We let
+           live cookies stay alive */
+
+        /* Free the newcomer and get out of here! */
+        freecookie(co);
+        return NULL;
+      }
+
+      if(replace_old) {
+        co->next = clist->next; /* get the next-pointer first */
+
+        /* then free all the old pointers */
+        free(clist->name);
+        free(clist->value);
+        free(clist->domain);
+        free(clist->path);
+        free(clist->spath);
+        free(clist->expirestr);
+        free(clist->version);
+        free(clist->maxage);
+
+        *clist = *co;  /* then store all the new data */
+
+        free(co);   /* free the newly alloced memory */
+        co = clist; /* point to the previous struct instead */
+
+        /* We have replaced a cookie, now skip the rest of the list but
+           make sure the 'lastc' pointer is properly set */
+        do {
+          lastc = clist;
+          clist = clist->next;
+        } while(clist);
+        break;
+      }
+    }
+    lastc = clist;
+    clist = clist->next;
+  }
+
+  if(c->running)
+    /* Only show this when NOT reading the cookies from a file */
+    infof(data, "%s cookie %s=\"%s\" for domain %s, path %s, "
+          "expire %" CURL_FORMAT_CURL_OFF_T "\n",
+          replace_old?"Replaced":"Added", co->name, co->value,
+          co->domain, co->path, co->expires);
+
+  if(!replace_old) {
+    /* then make the last item point on this new one */
+    if(lastc)
+      lastc->next = co;
+    else
+      c->cookies = co;
+    c->numcookies++; /* one more cookie in the jar */
+  }
+
+  return co;
+}
+
+/*
+ * get_line() makes sure to only return complete whole lines that fit in 'len'
+ * bytes and end with a newline.
+ */
+static char *get_line(char *buf, int len, FILE *input)
+{
+  bool partial = FALSE;
+  while(1) {
+    char *b = fgets(buf, len, input);
+    if(b) {
+      size_t rlen = strlen(b);
+      if(rlen && (b[rlen-1] == '\n')) {
+        if(partial) {
+          partial = FALSE;
+          continue;
+        }
+        return b;
+      }
+      /* read a partial, discard the next piece that ends with newline */
+      partial = TRUE;
+    }
+    else
+      break;
+  }
+  return NULL;
+}
+
+
+/*****************************************************************************
+ *
+ * Curl_cookie_init()
+ *
+ * Inits a cookie struct to read data from a local file. This is always
+ * called before any cookies are set. File may be NULL.
+ *
+ * If 'newsession' is TRUE, discard all "session cookies" on read from file.
+ *
+ * Returns NULL on out of memory. Invalid cookies are ignored.
+ ****************************************************************************/
+struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
+                                    const char *file,
+                                    struct CookieInfo *inc,
+                                    bool newsession)
+{
+  struct CookieInfo *c;
+  FILE *fp = NULL;
+  bool fromfile = TRUE;
+  char *line = NULL;
+
+  if(NULL == inc) {
+    /* we didn't get a struct, create one */
+    c = calloc(1, sizeof(struct CookieInfo));
+    if(!c)
+      return NULL; /* failed to get memory */
+    c->filename = strdup(file?file:"none"); /* copy the name just in case */
+    if(!c->filename)
+      goto fail; /* failed to get memory */
+  }
+  else {
+    /* we got an already existing one, use that */
+    c = inc;
+  }
+  c->running = FALSE; /* this is not running, this is init */
+
+  if(file && !strcmp(file, "-")) {
+    fp = stdin;
+    fromfile = FALSE;
+  }
+  else if(file && !*file) {
+    /* points to a "" string */
+    fp = NULL;
+  }
+  else
+    fp = file?fopen(file, FOPEN_READTEXT):NULL;
+
+  c->newsession = newsession; /* new session? */
+
+  if(fp) {
+    char *lineptr;
+    bool headerline;
+
+    line = malloc(MAX_COOKIE_LINE);
+    if(!line)
+      goto fail;
+    while(get_line(line, MAX_COOKIE_LINE, fp)) {
+      if(checkprefix("Set-Cookie:", line)) {
+        /* This is a cookie line, get it! */
+        lineptr = &line[11];
+        headerline = TRUE;
+      }
+      else {
+        lineptr = line;
+        headerline = FALSE;
+      }
+      while(*lineptr && ISBLANK(*lineptr))
+        lineptr++;
+
+      Curl_cookie_add(data, c, headerline, lineptr, NULL, NULL);
+    }
+    free(line); /* free the line buffer */
+
+    if(fromfile)
+      fclose(fp);
+  }
+
+  c->running = TRUE;          /* now, we're running */
+
+  return c;
+
+fail:
+  free(line);
+  if(!inc)
+    /* Only clean up if we allocated it here, as the original could still be in
+     * use by a share handle */
+    Curl_cookie_cleanup(c);
+  if(fromfile && fp)
+    fclose(fp);
+  return NULL; /* out of memory */
+}
+
+/* sort this so that the longest path gets before the shorter path */
+static int cookie_sort(const void *p1, const void *p2)
+{
+  struct Cookie *c1 = *(struct Cookie **)p1;
+  struct Cookie *c2 = *(struct Cookie **)p2;
+  size_t l1, l2;
+
+  /* 1 - compare cookie path lengths */
+  l1 = c1->path ? strlen(c1->path) : 0;
+  l2 = c2->path ? strlen(c2->path) : 0;
+
+  if(l1 != l2)
+    return (l2 > l1) ? 1 : -1 ; /* avoid size_t <=> int conversions */
+
+  /* 2 - compare cookie domain lengths */
+  l1 = c1->domain ? strlen(c1->domain) : 0;
+  l2 = c2->domain ? strlen(c2->domain) : 0;
+
+  if(l1 != l2)
+    return (l2 > l1) ? 1 : -1 ;  /* avoid size_t <=> int conversions */
+
+  /* 3 - compare cookie names */
+  if(c1->name && c2->name)
+    return strcmp(c1->name, c2->name);
+
+  /* sorry, can't be more deterministic */
+  return 0;
+}
+
+#define CLONE(field)                     \
+  do {                                   \
+    if(src->field) {                     \
+      d->field = strdup(src->field);     \
+      if(!d->field)                      \
+        goto fail;                       \
+    }                                    \
+  } while(0)
+
+static struct Cookie *dup_cookie(struct Cookie *src)
+{
+  struct Cookie *d = calloc(sizeof(struct Cookie), 1);
+  if(d) {
+    CLONE(expirestr);
+    CLONE(domain);
+    CLONE(path);
+    CLONE(spath);
+    CLONE(name);
+    CLONE(value);
+    CLONE(maxage);
+    CLONE(version);
+    d->expires = src->expires;
+    d->tailmatch = src->tailmatch;
+    d->secure = src->secure;
+    d->livecookie = src->livecookie;
+    d->httponly = src->httponly;
+  }
+  return d;
+
+  fail:
+  freecookie(d);
+  return NULL;
+}
+
+/*****************************************************************************
+ *
+ * Curl_cookie_getlist()
+ *
+ * For a given host and path, return a linked list of cookies that the
+ * client should send to the server if used now. The secure boolean informs
+ * the cookie if a secure connection is achieved or not.
+ *
+ * It shall only return cookies that haven't expired.
+ *
+ ****************************************************************************/
+
+struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
+                                   const char *host, const char *path,
+                                   bool secure)
+{
+  struct Cookie *newco;
+  struct Cookie *co;
+  time_t now = time(NULL);
+  struct Cookie *mainco = NULL;
+  size_t matches = 0;
+  bool is_ip;
+
+  if(!c || !c->cookies)
+    return NULL; /* no cookie struct or no cookies in the struct */
+
+  /* at first, remove expired cookies */
+  remove_expired(c);
+
+  /* check if host is an IP(v4|v6) address */
+  is_ip = isip(host);
+
+  co = c->cookies;
+
+  while(co) {
+    /* only process this cookie if it is not expired or had no expire
+       date AND that if the cookie requires we're secure we must only
+       continue if we are! */
+    if((!co->expires || (co->expires > now)) &&
+       (co->secure?secure:TRUE)) {
+
+      /* now check if the domain is correct */
+      if(!co->domain ||
+         (co->tailmatch && !is_ip && tailmatch(co->domain, host)) ||
+         ((!co->tailmatch || is_ip) && strcasecompare(host, co->domain)) ) {
+        /* the right part of the host matches the domain stuff in the
+           cookie data */
+
+        /* now check the left part of the path with the cookies path
+           requirement */
+        if(!co->spath || pathmatch(co->spath, path) ) {
+
+          /* and now, we know this is a match and we should create an
+             entry for the return-linked-list */
+
+          newco = dup_cookie(co);
+          if(newco) {
+            /* then modify our next */
+            newco->next = mainco;
+
+            /* point the main to us */
+            mainco = newco;
+
+            matches++;
+          }
+          else {
+            fail:
+            /* failure, clear up the allocated chain and return NULL */
+            Curl_cookie_freelist(mainco);
+            return NULL;
+          }
+        }
+      }
+    }
+    co = co->next;
+  }
+
+  if(matches) {
+    /* Now we need to make sure that if there is a name appearing more than
+       once, the longest specified path version comes first. To make this
+       the swiftest way, we just sort them all based on path length. */
+    struct Cookie **array;
+    size_t i;
+
+    /* alloc an array and store all cookie pointers */
+    array = malloc(sizeof(struct Cookie *) * matches);
+    if(!array)
+      goto fail;
+
+    co = mainco;
+
+    for(i = 0; co; co = co->next)
+      array[i++] = co;
+
+    /* now sort the cookie pointers in path length order */
+    qsort(array, matches, sizeof(struct Cookie *), cookie_sort);
+
+    /* remake the linked list order according to the new order */
+
+    mainco = array[0]; /* start here */
+    for(i = 0; i<matches-1; i++)
+      array[i]->next = array[i + 1];
+    array[matches-1]->next = NULL; /* terminate the list */
+
+    free(array); /* remove the temporary data again */
+  }
+
+  return mainco; /* return the new list */
+}
+
+/*****************************************************************************
+ *
+ * Curl_cookie_clearall()
+ *
+ * Clear all existing cookies and reset the counter.
+ *
+ ****************************************************************************/
+void Curl_cookie_clearall(struct CookieInfo *cookies)
+{
+  if(cookies) {
+    Curl_cookie_freelist(cookies->cookies);
+    cookies->cookies = NULL;
+    cookies->numcookies = 0;
+  }
+}
+
+/*****************************************************************************
+ *
+ * Curl_cookie_freelist()
+ *
+ * Free a list of cookies previously returned by Curl_cookie_getlist();
+ *
+ ****************************************************************************/
+
+void Curl_cookie_freelist(struct Cookie *co)
+{
+  struct Cookie *next;
+  while(co) {
+    next = co->next;
+    freecookie(co);
+    co = next;
+  }
+}
+
+
+/*****************************************************************************
+ *
+ * Curl_cookie_clearsess()
+ *
+ * Free all session cookies in the cookies list.
+ *
+ ****************************************************************************/
+void Curl_cookie_clearsess(struct CookieInfo *cookies)
+{
+  struct Cookie *first, *curr, *next, *prev = NULL;
+
+  if(!cookies || !cookies->cookies)
+    return;
+
+  first = curr = prev = cookies->cookies;
+
+  for(; curr; curr = next) {
+    next = curr->next;
+    if(!curr->expires) {
+      if(first == curr)
+        first = next;
+
+      if(prev == curr)
+        prev = next;
+      else
+        prev->next = next;
+
+      freecookie(curr);
+      cookies->numcookies--;
+    }
+    else
+      prev = curr;
+  }
+
+  cookies->cookies = first;
+}
+
+
+/*****************************************************************************
+ *
+ * Curl_cookie_cleanup()
+ *
+ * Free a "cookie object" previous created with Curl_cookie_init().
+ *
+ ****************************************************************************/
+void Curl_cookie_cleanup(struct CookieInfo *c)
+{
+  if(c) {
+    free(c->filename);
+    Curl_cookie_freelist(c->cookies);
+    free(c); /* free the base struct as well */
+  }
+}
+
+/* get_netscape_format()
+ *
+ * Formats a string for Netscape output file, w/o a newline at the end.
+ *
+ * Function returns a char * to a formatted line. Has to be free()d
+*/
+static char *get_netscape_format(const struct Cookie *co)
+{
+  return aprintf(
+    "%s"     /* httponly preamble */
+    "%s%s\t" /* domain */
+    "%s\t"   /* tailmatch */
+    "%s\t"   /* path */
+    "%s\t"   /* secure */
+    "%" CURL_FORMAT_CURL_OFF_T "\t"   /* expires */
+    "%s\t"   /* name */
+    "%s",    /* value */
+    co->httponly?"#HttpOnly_":"",
+    /* Make sure all domains are prefixed with a dot if they allow
+       tailmatching. This is Mozilla-style. */
+    (co->tailmatch && co->domain && co->domain[0] != '.')? ".":"",
+    co->domain?co->domain:"unknown",
+    co->tailmatch?"TRUE":"FALSE",
+    co->path?co->path:"/",
+    co->secure?"TRUE":"FALSE",
+    co->expires,
+    co->name,
+    co->value?co->value:"");
+}
+
+/*
+ * cookie_output()
+ *
+ * Writes all internally known cookies to the specified file. Specify
+ * "-" as file name to write to stdout.
+ *
+ * The function returns non-zero on write failure.
+ */
+static int cookie_output(struct CookieInfo *c, const char *dumphere)
+{
+  struct Cookie *co;
+  FILE *out;
+  bool use_stdout = FALSE;
+  char *format_ptr;
+
+  if((NULL == c) || (0 == c->numcookies))
+    /* If there are no known cookies, we don't write or even create any
+       destination file */
+    return 0;
+
+  /* at first, remove expired cookies */
+  remove_expired(c);
+
+  if(!strcmp("-", dumphere)) {
+    /* use stdout */
+    out = stdout;
+    use_stdout = TRUE;
+  }
+  else {
+    out = fopen(dumphere, FOPEN_WRITETEXT);
+    if(!out)
+      return 1; /* failure */
+  }
+
+  fputs("# Netscape HTTP Cookie File\n"
+        "# https://curl.haxx.se/docs/http-cookies.html\n"
+        "# This file was generated by libcurl! Edit at your own risk.\n\n",
+        out);
+
+  for(co = c->cookies; co; co = co->next) {
+    if(!co->domain)
+      continue;
+    format_ptr = get_netscape_format(co);
+    if(format_ptr == NULL) {
+      fprintf(out, "#\n# Fatal libcurl error\n");
+      if(!use_stdout)
+        fclose(out);
+      return 1;
+    }
+    fprintf(out, "%s\n", format_ptr);
+    free(format_ptr);
+  }
+
+  if(!use_stdout)
+    fclose(out);
+
+  return 0;
+}
+
+static struct curl_slist *cookie_list(struct Curl_easy *data)
+{
+  struct curl_slist *list = NULL;
+  struct curl_slist *beg;
+  struct Cookie *c;
+  char *line;
+
+  if((data->cookies == NULL) ||
+      (data->cookies->numcookies == 0))
+    return NULL;
+
+  for(c = data->cookies->cookies; c; c = c->next) {
+    if(!c->domain)
+      continue;
+    line = get_netscape_format(c);
+    if(!line) {
+      curl_slist_free_all(list);
+      return NULL;
+    }
+    beg = Curl_slist_append_nodup(list, line);
+    if(!beg) {
+      free(line);
+      curl_slist_free_all(list);
+      return NULL;
+    }
+    list = beg;
+  }
+
+  return list;
+}
+
+struct curl_slist *Curl_cookie_list(struct Curl_easy *data)
+{
+  struct curl_slist *list;
+  Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+  list = cookie_list(data);
+  Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+  return list;
+}
+
+void Curl_flush_cookies(struct Curl_easy *data, int cleanup)
+{
+  if(data->set.str[STRING_COOKIEJAR]) {
+    if(data->change.cookielist) {
+      /* If there is a list of cookie files to read, do it first so that
+         we have all the told files read before we write the new jar.
+         Curl_cookie_loadfiles() LOCKS and UNLOCKS the share itself! */
+      Curl_cookie_loadfiles(data);
+    }
+
+    Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+
+    /* if we have a destination file for all the cookies to get dumped to */
+    if(cookie_output(data->cookies, data->set.str[STRING_COOKIEJAR]))
+      infof(data, "WARNING: failed to save cookies in %s\n",
+            data->set.str[STRING_COOKIEJAR]);
+  }
+  else {
+    if(cleanup && data->change.cookielist) {
+      /* since nothing is written, we can just free the list of cookie file
+         names */
+      curl_slist_free_all(data->change.cookielist); /* clean up list */
+      data->change.cookielist = NULL;
+    }
+    Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+  }
+
+  if(cleanup && (!data->share || (data->cookies != data->share->cookies))) {
+    Curl_cookie_cleanup(data->cookies);
+  }
+  Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+}
+
+#endif /* CURL_DISABLE_HTTP || CURL_DISABLE_COOKIES */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/cookie.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/cookie.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/cookie.h	(revision 331)
@@ -0,0 +1,107 @@
+#ifndef HEADER_CURL_COOKIE_H
+#define HEADER_CURL_COOKIE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+struct Cookie {
+  struct Cookie *next; /* next in the chain */
+  char *name;        /* <this> = value */
+  char *value;       /* name = <this> */
+  char *path;         /* path = <this> which is in Set-Cookie: */
+  char *spath;        /* sanitized cookie path */
+  char *domain;      /* domain = <this> */
+  curl_off_t expires;  /* expires = <this> */
+  char *expirestr;   /* the plain text version */
+  bool tailmatch;    /* weather we do tail-matchning of the domain name */
+
+  /* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */
+  char *version;     /* Version = <value> */
+  char *maxage;      /* Max-Age = <value> */
+
+  bool secure;       /* whether the 'secure' keyword was used */
+  bool livecookie;   /* updated from a server, not a stored file */
+  bool httponly;     /* true if the httponly directive is present */
+};
+
+struct CookieInfo {
+  /* linked list of cookies we know of */
+  struct Cookie *cookies;
+
+  char *filename;  /* file we read from/write to */
+  bool running;    /* state info, for cookie adding information */
+  long numcookies; /* number of cookies in the "jar" */
+  bool newsession; /* new session, discard session cookies on load */
+};
+
+/* This is the maximum line length we accept for a cookie line. RFC 2109
+   section 6.3 says:
+
+   "at least 4096 bytes per cookie (as measured by the size of the characters
+   that comprise the cookie non-terminal in the syntax description of the
+   Set-Cookie header)"
+
+   We allow max 5000 bytes cookie header. Max 4095 bytes length per cookie
+   name and value. Name + value may not exceed 4096 bytes.
+
+*/
+#define MAX_COOKIE_LINE 5000
+#define MAX_COOKIE_LINE_TXT "4999"
+
+/* This is the maximum length of a cookie name or content we deal with: */
+#define MAX_NAME 4096
+#define MAX_NAME_TXT "4095"
+
+struct Curl_easy;
+/*
+ * Add a cookie to the internal list of cookies. The domain and path arguments
+ * are only used if the header boolean is TRUE.
+ */
+
+struct Cookie *Curl_cookie_add(struct Curl_easy *data,
+                               struct CookieInfo *, bool header, char *lineptr,
+                               const char *domain, const char *path);
+
+struct Cookie *Curl_cookie_getlist(struct CookieInfo *, const char *,
+                                   const char *, bool);
+void Curl_cookie_freelist(struct Cookie *cookies);
+void Curl_cookie_clearall(struct CookieInfo *cookies);
+void Curl_cookie_clearsess(struct CookieInfo *cookies);
+
+#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES)
+#define Curl_cookie_list(x) NULL
+#define Curl_cookie_loadfiles(x) Curl_nop_stmt
+#define Curl_cookie_init(x,y,z,w) NULL
+#define Curl_cookie_cleanup(x) Curl_nop_stmt
+#define Curl_flush_cookies(x,y) Curl_nop_stmt
+#else
+void Curl_flush_cookies(struct Curl_easy *data, int cleanup);
+void Curl_cookie_cleanup(struct CookieInfo *);
+struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
+                                    const char *, struct CookieInfo *, bool);
+struct curl_slist *Curl_cookie_list(struct Curl_easy *data);
+void Curl_cookie_loadfiles(struct Curl_easy *data);
+#endif
+
+#endif /* HEADER_CURL_COOKIE_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_addrinfo.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_addrinfo.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_addrinfo.c	(revision 331)
@@ -0,0 +1,616 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#  include <sys/un.h>
+#endif
+
+#ifdef __VMS
+#  include <in.h>
+#  include <inet.h>
+#endif
+
+#if defined(NETWARE) && defined(__NOVELL_LIBC__)
+#  undef  in_addr_t
+#  define in_addr_t unsigned long
+#endif
+
+#include <stddef.h>
+
+#include "curl_addrinfo.h"
+#include "inet_pton.h"
+#include "warnless.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * Curl_freeaddrinfo()
+ *
+ * This is used to free a linked list of Curl_addrinfo structs along
+ * with all its associated allocated storage. This function should be
+ * called once for each successful call to Curl_getaddrinfo_ex() or to
+ * any function call which actually allocates a Curl_addrinfo struct.
+ */
+
+#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
+    defined(__OPTIMIZE__) && defined(__unix__) &&  defined(__i386__)
+  /* workaround icc 9.1 optimizer issue */
+# define vqualifier volatile
+#else
+# define vqualifier
+#endif
+
+void
+Curl_freeaddrinfo(Curl_addrinfo *cahead)
+{
+  Curl_addrinfo *vqualifier canext;
+  Curl_addrinfo *ca;
+
+  for(ca = cahead; ca != NULL; ca = canext) {
+    free(ca->ai_addr);
+    free(ca->ai_canonname);
+    canext = ca->ai_next;
+
+    free(ca);
+  }
+}
+
+
+#ifdef HAVE_GETADDRINFO
+/*
+ * Curl_getaddrinfo_ex()
+ *
+ * This is a wrapper function around system's getaddrinfo(), with
+ * the only difference that instead of returning a linked list of
+ * addrinfo structs this one returns a linked list of Curl_addrinfo
+ * ones. The memory allocated by this function *MUST* be free'd with
+ * Curl_freeaddrinfo().  For each successful call to this function
+ * there must be an associated call later to Curl_freeaddrinfo().
+ *
+ * There should be no single call to system's getaddrinfo() in the
+ * whole library, any such call should be 'routed' through this one.
+ */
+
+int
+Curl_getaddrinfo_ex(const char *nodename,
+                    const char *servname,
+                    const struct addrinfo *hints,
+                    Curl_addrinfo **result)
+{
+  const struct addrinfo *ai;
+  struct addrinfo *aihead;
+  Curl_addrinfo *cafirst = NULL;
+  Curl_addrinfo *calast = NULL;
+  Curl_addrinfo *ca;
+  size_t ss_size;
+  int error;
+
+  *result = NULL; /* assume failure */
+
+  error = getaddrinfo(nodename, servname, hints, &aihead);
+  if(error)
+    return error;
+
+  /* traverse the addrinfo list */
+
+  for(ai = aihead; ai != NULL; ai = ai->ai_next) {
+
+    /* ignore elements with unsupported address family, */
+    /* settle family-specific sockaddr structure size.  */
+    if(ai->ai_family == AF_INET)
+      ss_size = sizeof(struct sockaddr_in);
+#ifdef ENABLE_IPV6
+    else if(ai->ai_family == AF_INET6)
+      ss_size = sizeof(struct sockaddr_in6);
+#endif
+    else
+      continue;
+
+    /* ignore elements without required address info */
+    if((ai->ai_addr == NULL) || !(ai->ai_addrlen > 0))
+      continue;
+
+    /* ignore elements with bogus address size */
+    if((size_t)ai->ai_addrlen < ss_size)
+      continue;
+
+    ca = malloc(sizeof(Curl_addrinfo));
+    if(!ca) {
+      error = EAI_MEMORY;
+      break;
+    }
+
+    /* copy each structure member individually, member ordering, */
+    /* size, or padding might be different for each platform.    */
+
+    ca->ai_flags     = ai->ai_flags;
+    ca->ai_family    = ai->ai_family;
+    ca->ai_socktype  = ai->ai_socktype;
+    ca->ai_protocol  = ai->ai_protocol;
+    ca->ai_addrlen   = (curl_socklen_t)ss_size;
+    ca->ai_addr      = NULL;
+    ca->ai_canonname = NULL;
+    ca->ai_next      = NULL;
+
+    ca->ai_addr = malloc(ss_size);
+    if(!ca->ai_addr) {
+      error = EAI_MEMORY;
+      free(ca);
+      break;
+    }
+    memcpy(ca->ai_addr, ai->ai_addr, ss_size);
+
+    if(ai->ai_canonname != NULL) {
+      ca->ai_canonname = strdup(ai->ai_canonname);
+      if(!ca->ai_canonname) {
+        error = EAI_MEMORY;
+        free(ca->ai_addr);
+        free(ca);
+        break;
+      }
+    }
+
+    /* if the return list is empty, this becomes the first element */
+    if(!cafirst)
+      cafirst = ca;
+
+    /* add this element last in the return list */
+    if(calast)
+      calast->ai_next = ca;
+    calast = ca;
+
+  }
+
+  /* destroy the addrinfo list */
+  if(aihead)
+    freeaddrinfo(aihead);
+
+  /* if we failed, also destroy the Curl_addrinfo list */
+  if(error) {
+    Curl_freeaddrinfo(cafirst);
+    cafirst = NULL;
+  }
+  else if(!cafirst) {
+#ifdef EAI_NONAME
+    /* rfc3493 conformant */
+    error = EAI_NONAME;
+#else
+    /* rfc3493 obsoleted */
+    error = EAI_NODATA;
+#endif
+#ifdef USE_WINSOCK
+    SET_SOCKERRNO(error);
+#endif
+  }
+
+  *result = cafirst;
+
+  /* This is not a CURLcode */
+  return error;
+}
+#endif /* HAVE_GETADDRINFO */
+
+
+/*
+ * Curl_he2ai()
+ *
+ * This function returns a pointer to the first element of a newly allocated
+ * Curl_addrinfo struct linked list filled with the data of a given hostent.
+ * Curl_addrinfo is meant to work like the addrinfo struct does for a IPv6
+ * stack, but usable also for IPv4, all hosts and environments.
+ *
+ * The memory allocated by this function *MUST* be free'd later on calling
+ * Curl_freeaddrinfo().  For each successful call to this function there
+ * must be an associated call later to Curl_freeaddrinfo().
+ *
+ *   Curl_addrinfo defined in "lib/curl_addrinfo.h"
+ *
+ *     struct Curl_addrinfo {
+ *       int                   ai_flags;
+ *       int                   ai_family;
+ *       int                   ai_socktype;
+ *       int                   ai_protocol;
+ *       curl_socklen_t        ai_addrlen;   * Follow rfc3493 struct addrinfo *
+ *       char                 *ai_canonname;
+ *       struct sockaddr      *ai_addr;
+ *       struct Curl_addrinfo *ai_next;
+ *     };
+ *     typedef struct Curl_addrinfo Curl_addrinfo;
+ *
+ *   hostent defined in <netdb.h>
+ *
+ *     struct hostent {
+ *       char    *h_name;
+ *       char    **h_aliases;
+ *       int     h_addrtype;
+ *       int     h_length;
+ *       char    **h_addr_list;
+ *     };
+ *
+ *   for backward compatibility:
+ *
+ *     #define h_addr  h_addr_list[0]
+ */
+
+Curl_addrinfo *
+Curl_he2ai(const struct hostent *he, int port)
+{
+  Curl_addrinfo *ai;
+  Curl_addrinfo *prevai = NULL;
+  Curl_addrinfo *firstai = NULL;
+  struct sockaddr_in *addr;
+#ifdef ENABLE_IPV6
+  struct sockaddr_in6 *addr6;
+#endif
+  CURLcode result = CURLE_OK;
+  int i;
+  char *curr;
+
+  if(!he)
+    /* no input == no output! */
+    return NULL;
+
+  DEBUGASSERT((he->h_name != NULL) && (he->h_addr_list != NULL));
+
+  for(i=0; (curr = he->h_addr_list[i]) != NULL; i++) {
+
+    size_t ss_size;
+#ifdef ENABLE_IPV6
+    if(he->h_addrtype == AF_INET6)
+      ss_size = sizeof(struct sockaddr_in6);
+    else
+#endif
+      ss_size = sizeof(struct sockaddr_in);
+
+    ai = calloc(1, sizeof(Curl_addrinfo));
+    if(!ai) {
+      result = CURLE_OUT_OF_MEMORY;
+      break;
+    }
+    ai->ai_canonname = strdup(he->h_name);
+    if(!ai->ai_canonname) {
+      result = CURLE_OUT_OF_MEMORY;
+      free(ai);
+      break;
+    }
+    ai->ai_addr = calloc(1, ss_size);
+    if(!ai->ai_addr) {
+      result = CURLE_OUT_OF_MEMORY;
+      free(ai->ai_canonname);
+      free(ai);
+      break;
+    }
+
+    if(!firstai)
+      /* store the pointer we want to return from this function */
+      firstai = ai;
+
+    if(prevai)
+      /* make the previous entry point to this */
+      prevai->ai_next = ai;
+
+    ai->ai_family = he->h_addrtype;
+
+    /* we return all names as STREAM, so when using this address for TFTP
+       the type must be ignored and conn->socktype be used instead! */
+    ai->ai_socktype = SOCK_STREAM;
+
+    ai->ai_addrlen = (curl_socklen_t)ss_size;
+
+    /* leave the rest of the struct filled with zero */
+
+    switch(ai->ai_family) {
+    case AF_INET:
+      addr = (void *)ai->ai_addr; /* storage area for this info */
+
+      memcpy(&addr->sin_addr, curr, sizeof(struct in_addr));
+      addr->sin_family = (unsigned short)(he->h_addrtype);
+      addr->sin_port = htons((unsigned short)port);
+      break;
+
+#ifdef ENABLE_IPV6
+    case AF_INET6:
+      addr6 = (void *)ai->ai_addr; /* storage area for this info */
+
+      memcpy(&addr6->sin6_addr, curr, sizeof(struct in6_addr));
+      addr6->sin6_family = (unsigned short)(he->h_addrtype);
+      addr6->sin6_port = htons((unsigned short)port);
+      break;
+#endif
+    }
+
+    prevai = ai;
+  }
+
+  if(result) {
+    Curl_freeaddrinfo(firstai);
+    firstai = NULL;
+  }
+
+  return firstai;
+}
+
+
+struct namebuff {
+  struct hostent hostentry;
+  union {
+    struct in_addr  ina4;
+#ifdef ENABLE_IPV6
+    struct in6_addr ina6;
+#endif
+  } addrentry;
+  char *h_addr_list[2];
+};
+
+
+/*
+ * Curl_ip2addr()
+ *
+ * This function takes an internet address, in binary form, as input parameter
+ * along with its address family and the string version of the address, and it
+ * returns a Curl_addrinfo chain filled in correctly with information for the
+ * given address/host
+ */
+
+Curl_addrinfo *
+Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port)
+{
+  Curl_addrinfo *ai;
+
+#if defined(__VMS) && \
+    defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
+#pragma pointer_size save
+#pragma pointer_size short
+#pragma message disable PTRMISMATCH
+#endif
+
+  struct hostent  *h;
+  struct namebuff *buf;
+  char  *addrentry;
+  char  *hoststr;
+  size_t addrsize;
+
+  DEBUGASSERT(inaddr && hostname);
+
+  buf = malloc(sizeof(struct namebuff));
+  if(!buf)
+    return NULL;
+
+  hoststr = strdup(hostname);
+  if(!hoststr) {
+    free(buf);
+    return NULL;
+  }
+
+  switch(af) {
+  case AF_INET:
+    addrsize = sizeof(struct in_addr);
+    addrentry = (void *)&buf->addrentry.ina4;
+    memcpy(addrentry, inaddr, sizeof(struct in_addr));
+    break;
+#ifdef ENABLE_IPV6
+  case AF_INET6:
+    addrsize = sizeof(struct in6_addr);
+    addrentry = (void *)&buf->addrentry.ina6;
+    memcpy(addrentry, inaddr, sizeof(struct in6_addr));
+    break;
+#endif
+  default:
+    free(hoststr);
+    free(buf);
+    return NULL;
+  }
+
+  h = &buf->hostentry;
+  h->h_name = hoststr;
+  h->h_aliases = NULL;
+  h->h_addrtype = (short)af;
+  h->h_length = (short)addrsize;
+  h->h_addr_list = &buf->h_addr_list[0];
+  h->h_addr_list[0] = addrentry;
+  h->h_addr_list[1] = NULL; /* terminate list of entries */
+
+#if defined(__VMS) && \
+    defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64)
+#pragma pointer_size restore
+#pragma message enable PTRMISMATCH
+#endif
+
+  ai = Curl_he2ai(h, port);
+
+  free(hoststr);
+  free(buf);
+
+  return ai;
+}
+
+/*
+ * Given an IPv4 or IPv6 dotted string address, this converts it to a proper
+ * allocated Curl_addrinfo struct and returns it.
+ */
+Curl_addrinfo *Curl_str2addr(char *address, int port)
+{
+  struct in_addr in;
+  if(Curl_inet_pton(AF_INET, address, &in) > 0)
+    /* This is a dotted IP address 123.123.123.123-style */
+    return Curl_ip2addr(AF_INET, &in, address, port);
+#ifdef ENABLE_IPV6
+  {
+    struct in6_addr in6;
+    if(Curl_inet_pton(AF_INET6, address, &in6) > 0)
+      /* This is a dotted IPv6 address ::1-style */
+      return Curl_ip2addr(AF_INET6, &in6, address, port);
+  }
+#endif
+  return NULL; /* bad input format */
+}
+
+#ifdef USE_UNIX_SOCKETS
+/**
+ * Given a path to a Unix domain socket, return a newly allocated Curl_addrinfo
+ * struct initialized with this path.
+ * Set '*longpath' to TRUE if the error is a too long path.
+ */
+Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract)
+{
+  Curl_addrinfo *ai;
+  struct sockaddr_un *sa_un;
+  size_t path_len;
+
+  *longpath = FALSE;
+
+  ai = calloc(1, sizeof(Curl_addrinfo));
+  if(!ai)
+    return NULL;
+  ai->ai_addr = calloc(1, sizeof(struct sockaddr_un));
+  if(!ai->ai_addr) {
+    free(ai);
+    return NULL;
+  }
+
+  sa_un = (void *) ai->ai_addr;
+  sa_un->sun_family = AF_UNIX;
+
+  /* sun_path must be able to store the NUL-terminated path */
+  path_len = strlen(path) + 1;
+  if(path_len > sizeof(sa_un->sun_path)) {
+    free(ai->ai_addr);
+    free(ai);
+    *longpath = TRUE;
+    return NULL;
+  }
+
+  ai->ai_family = AF_UNIX;
+  ai->ai_socktype = SOCK_STREAM; /* assume reliable transport for HTTP */
+  ai->ai_addrlen = (curl_socklen_t)
+    ((offsetof(struct sockaddr_un, sun_path) + path_len) & 0x7FFFFFFF);
+
+  /* Abstract Unix domain socket have NULL prefix instead of suffix */
+  if(abstract)
+    memcpy(sa_un->sun_path + 1, path, path_len - 1);
+  else
+    memcpy(sa_un->sun_path, path, path_len); /* copy NUL byte */
+
+  return ai;
+}
+#endif
+
+#if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO)
+/*
+ * curl_dofreeaddrinfo()
+ *
+ * This is strictly for memory tracing and are using the same style as the
+ * family otherwise present in memdebug.c. I put these ones here since they
+ * require a bunch of structs I didn't want to include in memdebug.c
+ */
+
+void
+curl_dofreeaddrinfo(struct addrinfo *freethis,
+                    int line, const char *source)
+{
+#ifdef USE_LWIPSOCK
+  lwip_freeaddrinfo(freethis);
+#else
+  (freeaddrinfo)(freethis);
+#endif
+  curl_memlog("ADDR %s:%d freeaddrinfo(%p)\n",
+              source, line, (void *)freethis);
+}
+#endif /* defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO) */
+
+
+#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO)
+/*
+ * curl_dogetaddrinfo()
+ *
+ * This is strictly for memory tracing and are using the same style as the
+ * family otherwise present in memdebug.c. I put these ones here since they
+ * require a bunch of structs I didn't want to include in memdebug.c
+ */
+
+int
+curl_dogetaddrinfo(const char *hostname,
+                   const char *service,
+                   const struct addrinfo *hints,
+                   struct addrinfo **result,
+                   int line, const char *source)
+{
+#ifdef USE_LWIPSOCK
+  int res=lwip_getaddrinfo(hostname, service, hints, result);
+#else
+  int res=(getaddrinfo)(hostname, service, hints, result);
+#endif
+  if(0 == res)
+    /* success */
+    curl_memlog("ADDR %s:%d getaddrinfo() = %p\n",
+                source, line, (void *)*result);
+  else
+    curl_memlog("ADDR %s:%d getaddrinfo() failed\n",
+                source, line);
+  return res;
+}
+#endif /* defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) */
+
+#if defined(HAVE_GETADDRINFO) && defined(USE_RESOLVE_ON_IPS)
+/*
+ * Work-arounds the sin6_port is always zero bug on iOS 9.3.2 and Mac OS X
+ * 10.11.5.
+ */
+void Curl_addrinfo_set_port(Curl_addrinfo *addrinfo, int port)
+{
+  Curl_addrinfo *ca;
+  struct sockaddr_in *addr;
+#ifdef ENABLE_IPV6
+  struct sockaddr_in6 *addr6;
+#endif
+  for(ca = addrinfo; ca != NULL; ca = ca->ai_next) {
+    switch(ca->ai_family) {
+    case AF_INET:
+      addr = (void *)ca->ai_addr; /* storage area for this info */
+      addr->sin_port = htons((unsigned short)port);
+      break;
+
+#ifdef ENABLE_IPV6
+    case AF_INET6:
+      addr6 = (void *)ca->ai_addr; /* storage area for this info */
+      addr6->sin6_port = htons((unsigned short)port);
+      break;
+#endif
+    }
+  }
+}
+#endif
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_addrinfo.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_addrinfo.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_addrinfo.h	(revision 331)
@@ -0,0 +1,110 @@
+#ifndef HEADER_CURL_ADDRINFO_H
+#define HEADER_CURL_ADDRINFO_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif
+
+#ifdef __VMS
+#  include <in.h>
+#  include <inet.h>
+#  include <stdlib.h>
+#endif
+
+
+/*
+ * Curl_addrinfo is our internal struct definition that we use to allow
+ * consistent internal handling of this data. We use this even when the
+ * system provides an addrinfo structure definition. And we use this for
+ * all sorts of IPv4 and IPV6 builds.
+ */
+
+struct Curl_addrinfo {
+  int                   ai_flags;
+  int                   ai_family;
+  int                   ai_socktype;
+  int                   ai_protocol;
+  curl_socklen_t        ai_addrlen;   /* Follow rfc3493 struct addrinfo */
+  char                 *ai_canonname;
+  struct sockaddr      *ai_addr;
+  struct Curl_addrinfo *ai_next;
+};
+typedef struct Curl_addrinfo Curl_addrinfo;
+
+void
+Curl_freeaddrinfo(Curl_addrinfo *cahead);
+
+#ifdef HAVE_GETADDRINFO
+int
+Curl_getaddrinfo_ex(const char *nodename,
+                    const char *servname,
+                    const struct addrinfo *hints,
+                    Curl_addrinfo **result);
+#endif
+
+Curl_addrinfo *
+Curl_he2ai(const struct hostent *he, int port);
+
+Curl_addrinfo *
+Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);
+
+Curl_addrinfo *Curl_str2addr(char *dotted, int port);
+
+#ifdef USE_UNIX_SOCKETS
+Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract);
+#endif
+
+#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
+    defined(HAVE_FREEADDRINFO)
+void
+curl_dofreeaddrinfo(struct addrinfo *freethis,
+                    int line, const char *source);
+#endif
+
+#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO)
+int
+curl_dogetaddrinfo(const char *hostname,
+                   const char *service,
+                   const struct addrinfo *hints,
+                   struct addrinfo **result,
+                   int line, const char *source);
+#endif
+
+#ifdef HAVE_GETADDRINFO
+#ifdef USE_RESOLVE_ON_IPS
+void Curl_addrinfo_set_port(Curl_addrinfo *addrinfo, int port);
+#else
+#define Curl_addrinfo_set_port(x,y)
+#endif
+#endif
+
+#endif /* HEADER_CURL_ADDRINFO_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_base64.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_base64.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_base64.h	(revision 331)
@@ -0,0 +1,35 @@
+#ifndef HEADER_CURL_BASE64_H
+#define HEADER_CURL_BASE64_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+CURLcode Curl_base64_encode(struct Curl_easy *data,
+                            const char *inputbuff, size_t insize,
+                            char **outptr, size_t *outlen);
+CURLcode Curl_base64url_encode(struct Curl_easy *data,
+                               const char *inputbuff, size_t insize,
+                               char **outptr, size_t *outlen);
+
+CURLcode Curl_base64_decode(const char *src,
+                            unsigned char **outptr, size_t *outlen);
+
+#endif /* HEADER_CURL_BASE64_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_config.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_config.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_config.h	(revision 331)
@@ -0,0 +1,1043 @@
+/* lib/curl_config.h.  Generated from curl_config.h.in by configure.  */
+/* lib/curl_config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Location of default ca bundle */
+/* #undef CURL_CA_BUNDLE */
+
+/* define "1" to use built in CA store of SSL library */
+/* #undef CURL_CA_FALLBACK */
+
+/* Location of default ca path */
+/* #undef CURL_CA_PATH */
+
+/* Default SSL backend */
+/* #undef CURL_DEFAULT_SSL_BACKEND */
+
+/* to disable cookies support */
+/* #undef CURL_DISABLE_COOKIES */
+
+/* to disable cryptographic authentication */
+/* #undef CURL_DISABLE_CRYPTO_AUTH */
+
+/* to disable DICT */
+/* #undef CURL_DISABLE_DICT */
+
+/* to disable FILE */
+/* #undef CURL_DISABLE_FILE */
+
+/* to disable FTP */
+/* #undef CURL_DISABLE_FTP */
+
+/* to disable Gopher */
+/* #undef CURL_DISABLE_GOPHER */
+
+/* to disable HTTP */
+/* #undef CURL_DISABLE_HTTP */
+
+/* to disable IMAP */
+/* #undef CURL_DISABLE_IMAP */
+
+/* to disable LDAP */
+#define CURL_DISABLE_LDAP 1
+
+/* to disable LDAPS */
+#define CURL_DISABLE_LDAPS 1
+
+/* to disable --libcurl C code generation option */
+/* #undef CURL_DISABLE_LIBCURL_OPTION */
+
+/* to disable POP3 */
+/* #undef CURL_DISABLE_POP3 */
+
+/* to disable proxies */
+/* #undef CURL_DISABLE_PROXY */
+
+/* to disable RTSP */
+/* #undef CURL_DISABLE_RTSP */
+
+/* to disable SMB/CIFS */
+/* #undef CURL_DISABLE_SMB */
+
+/* to disable SMTP */
+/* #undef CURL_DISABLE_SMTP */
+
+/* to disable TELNET */
+/* #undef CURL_DISABLE_TELNET */
+
+/* to disable TFTP */
+/* #undef CURL_DISABLE_TFTP */
+
+/* to disable TLS-SRP authentication */
+/* #undef CURL_DISABLE_TLS_SRP */
+
+/* to disable verbose strings */
+/* #undef CURL_DISABLE_VERBOSE_STRINGS */
+
+/* Definition to make a library symbol externally visible. */
+#define CURL_EXTERN_SYMBOL __attribute__ ((__visibility__ ("default")))
+
+/* built with multiple SSL backends */
+/* #undef CURL_WITH_MULTI_SSL */
+
+/* your Entropy Gathering Daemon socket pathname */
+/* #undef EGD_SOCKET */
+
+/* Define if you want to enable IPv6 support */
+/* #undef ENABLE_IPV6 */
+
+/* Define to the type of arg 2 for gethostname. */
+/* #undef GETHOSTNAME_TYPE_ARG2 */
+
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+#define GETNAMEINFO_QUAL_ARG1 const
+
+/* Define to the type of arg 1 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+
+/* Define to the type of arg 2 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG2 socklen_t
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG46 size_t
+
+/* Define to the type of arg 7 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG7 int
+
+/* Specifies the number of arguments to getservbyport_r */
+/* #undef GETSERVBYPORT_R_ARGS */
+
+/* Specifies the size of the buffer to pass to getservbyport_r */
+/* #undef GETSERVBYPORT_R_BUFSIZE */
+
+/* Define to 1 if you have the alarm function. */
+#define HAVE_ALARM 1
+
+/* Define to 1 if you have the <alloca.h> header file. */
+#define HAVE_ALLOCA_H 1
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <arpa/tftp.h> header file. */
+#define HAVE_ARPA_TFTP_H 1
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the basename function. */
+#define HAVE_BASENAME 1
+
+/* Define to 1 if bool is an available type. */
+#define HAVE_BOOL_T 1
+
+/* Define to 1 if using BoringSSL. */
+/* #undef HAVE_BORINGSSL */
+
+/* if BROTLI is in use */
+/* #undef HAVE_BROTLI */
+
+/* Define to 1 if you have the <brotli/decode.h> header file. */
+/* #undef HAVE_BROTLI_DECODE_H */
+
+/* Define to 1 if you have the __builtin_available function. */
+/* #undef HAVE_BUILTIN_AVAILABLE */
+
+/* Define to 1 if you have the clock_gettime function and monotonic timer. */
+#define HAVE_CLOCK_GETTIME_MONOTONIC 1
+
+/* Define to 1 if you have the closesocket function. */
+/* #undef HAVE_CLOSESOCKET */
+
+/* Define to 1 if you have the CloseSocket camel case function. */
+/* #undef HAVE_CLOSESOCKET_CAMEL */
+
+/* Define to 1 if you have the connect function. */
+/* #undef HAVE_CONNECT */
+
+/* Define to 1 if you have the <crypto.h> header file. */
+/* #undef HAVE_CRYPTO_H */
+
+/* Define to 1 if you have the `CyaSSL_CTX_UseSupportedCurve' function. */
+/* #undef HAVE_CYASSL_CTX_USESUPPORTEDCURVE */
+
+/* Define to 1 if you have the <cyassl/error-ssl.h> header file. */
+/* #undef HAVE_CYASSL_ERROR_SSL_H */
+
+/* Define to 1 if you have the `CyaSSL_get_peer_certificate' function. */
+/* #undef HAVE_CYASSL_GET_PEER_CERTIFICATE */
+
+/* Define to 1 if you have the <cyassl/options.h> header file. */
+/* #undef HAVE_CYASSL_OPTIONS_H */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the `ENGINE_cleanup' function. */
+/* #undef HAVE_ENGINE_CLEANUP */
+
+/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */
+#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the <err.h> header file. */
+/* #undef HAVE_ERR_H */
+
+/* Define to 1 if you have the fcntl function. */
+#define HAVE_FCNTL 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
+#define HAVE_FCNTL_O_NONBLOCK 1
+
+/* Define to 1 if you have the fdopen function. */
+#define HAVE_FDOPEN 1
+
+/* Define to 1 if you have the freeaddrinfo function. */
+/* #undef HAVE_FREEADDRINFO */
+
+/* Define to 1 if you have the freeifaddrs function. */
+/* #undef HAVE_FREEIFADDRS */
+
+/* Define to 1 if you have the fsetxattr function. */
+/* #undef HAVE_FSETXATTR */
+
+/* fsetxattr() takes 5 args */
+/* #undef HAVE_FSETXATTR_5 */
+
+/* fsetxattr() takes 6 args */
+/* #undef HAVE_FSETXATTR_6 */
+
+/* Define to 1 if you have the ftruncate function. */
+#define HAVE_FTRUNCATE 1
+
+/* Define to 1 if you have the gai_strerror function. */
+/* #undef HAVE_GAI_STRERROR */
+
+/* Define to 1 if you have a working getaddrinfo function. */
+/* #undef HAVE_GETADDRINFO */
+
+/* Define to 1 if the getaddrinfo function is threadsafe. */
+/* #undef HAVE_GETADDRINFO_THREADSAFE */
+
+/* Define to 1 if you have the `geteuid' function. */
+/* #undef HAVE_GETEUID */
+
+/* Define to 1 if you have the gethostbyaddr function. */
+/* #undef HAVE_GETHOSTBYADDR */
+
+/* Define to 1 if you have the gethostbyaddr_r function. */
+/* #undef HAVE_GETHOSTBYADDR_R */
+
+/* gethostbyaddr_r() takes 5 args */
+/* #undef HAVE_GETHOSTBYADDR_R_5 */
+
+/* gethostbyaddr_r() takes 7 args */
+/* #undef HAVE_GETHOSTBYADDR_R_7 */
+
+/* gethostbyaddr_r() takes 8 args */
+/* #undef HAVE_GETHOSTBYADDR_R_8 */
+
+/* Define to 1 if you have the gethostbyname function. */
+/* #undef HAVE_GETHOSTBYNAME */
+
+/* Define to 1 if you have the gethostbyname_r function. */
+/* #undef HAVE_GETHOSTBYNAME_R */
+
+/* gethostbyname_r() takes 3 args */
+/* #undef HAVE_GETHOSTBYNAME_R_3 */
+
+/* gethostbyname_r() takes 5 args */
+/* #undef HAVE_GETHOSTBYNAME_R_5 */
+
+/* gethostbyname_r() takes 6 args */
+/* #undef HAVE_GETHOSTBYNAME_R_6 */
+
+/* Define to 1 if you have the gethostname function. */
+/* #undef HAVE_GETHOSTNAME */
+
+/* Define to 1 if you have a working getifaddrs function. */
+/* #undef HAVE_GETIFADDRS */
+
+/* Define to 1 if you have the getnameinfo function. */
+#define HAVE_GETNAMEINFO 1
+
+/* Define to 1 if you have the `getpass_r' function. */
+/* #undef HAVE_GETPASS_R */
+
+/* Define to 1 if you have the `getppid' function. */
+/* #define HAVE_GETPPID */
+
+/* Define to 1 if you have the `getpwuid' function. */
+/* #define HAVE_GETPWUID */
+
+/* Define to 1 if you have the `getpwuid_r' function. */
+/* #undef HAVE_GETPWUID_R */
+
+/* Define to 1 if you have the `getrlimit' function. */
+#define HAVE_GETRLIMIT 1
+
+/* Define to 1 if you have the getservbyport_r function. */
+/* #undef HAVE_GETSERVBYPORT_R */
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define to 1 if you have a working glibc-style strerror_r function. */
+/* #undef HAVE_GLIBC_STRERROR_R */
+
+/* Define to 1 if you have a working gmtime_r function. */
+#define HAVE_GMTIME_R 1
+
+/* Define to 1 if you have the `gnutls_alpn_set_protocols' function. */
+/* #undef HAVE_GNUTLS_ALPN_SET_PROTOCOLS */
+
+/* Define to 1 if you have the `gnutls_certificate_set_x509_key_file2'
+   function. */
+/* #undef HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2 */
+
+/* Define to 1 if you have the `gnutls_ocsp_req_init' function. */
+/* #undef HAVE_GNUTLS_OCSP_REQ_INIT */
+
+/* if you have the function gnutls_srp_verifier */
+/* #undef HAVE_GNUTLS_SRP */
+
+/* if you have GSS-API libraries */
+/* #undef HAVE_GSSAPI */
+
+/* Define to 1 if you have the <gssapi/gssapi_generic.h> header file. */
+/* #undef HAVE_GSSAPI_GSSAPI_GENERIC_H */
+
+/* Define to 1 if you have the <gssapi/gssapi.h> header file. */
+/* #undef HAVE_GSSAPI_GSSAPI_H */
+
+/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */
+/* #undef HAVE_GSSAPI_GSSAPI_KRB5_H */
+
+/* if you have GNU GSS */
+/* #undef HAVE_GSSGNU */
+
+/* if you have Heimdal */
+/* #undef HAVE_GSSHEIMDAL */
+
+/* if you have MIT Kerberos */
+/* #undef HAVE_GSSMIT */
+
+/* Define to 1 if you have the <idn2.h> header file. */
+/* #undef HAVE_IDN2_H */
+
+/* Define to 1 if you have the <ifaddrs.h> header file. */
+#define HAVE_IFADDRS_H 1
+
+/* Define to 1 if you have the `if_nametoindex' function. */
+#define HAVE_IF_NAMETOINDEX 1
+
+/* Define to 1 if you have the inet_ntoa_r function. */
+/* #undef HAVE_INET_NTOA_R */
+
+/* inet_ntoa_r() takes 2 args */
+/* #undef HAVE_INET_NTOA_R_2 */
+
+/* inet_ntoa_r() takes 3 args */
+/* #undef HAVE_INET_NTOA_R_3 */
+
+/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
+/* #undef HAVE_INET_NTOP */
+
+/* Define to 1 if you have a IPv6 capable working inet_pton function. */
+/* #undef HAVE_INET_PTON */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the ioctl function. */
+/* #undef HAVE_IOCTL */
+
+/* Define to 1 if you have the ioctlsocket function. */
+/* #undef HAVE_IOCTLSOCKET */
+
+/* Define to 1 if you have the IoctlSocket camel case function. */
+/* #undef HAVE_IOCTLSOCKET_CAMEL */
+
+/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function.
+   */
+/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
+
+/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
+/* #undef HAVE_IOCTLSOCKET_FIONBIO */
+
+/* Define to 1 if you have a working ioctl FIONBIO function. */
+/* #undef HAVE_IOCTL_FIONBIO */
+
+/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */
+/* #undef HAVE_IOCTL_SIOCGIFADDR */
+
+/* Define to 1 if you have the <io.h> header file. */
+/* #undef HAVE_IO_H */
+
+/* Define to 1 if you have the lber.h header file. */
+/* #undef HAVE_LBER_H */
+
+/* Define to 1 if you have the ldapssl.h header file. */
+/* #undef HAVE_LDAPSSL_H */
+
+/* Define to 1 if you have the ldap.h header file. */
+/* #undef HAVE_LDAP_H */
+
+/* Define to 1 if you have the `ldap_init_fd' function. */
+/* #undef HAVE_LDAP_INIT_FD */
+
+/* Use LDAPS implementation */
+#define HAVE_LDAP_SSL 1
+
+/* Define to 1 if you have the ldap_ssl.h header file. */
+/* #undef HAVE_LDAP_SSL_H */
+
+/* Define to 1 if you have the `ldap_url_parse' function. */
+/* #undef HAVE_LDAP_URL_PARSE */
+
+/* Define to 1 if you have the `brotlidec' library (-lbrotlidec). */
+/* #undef HAVE_LIBBROTLIDEC */
+
+/* Define to 1 if you have the <libgen.h> header file. */
+#define HAVE_LIBGEN_H 1
+
+/* Define to 1 if you have the `idn2' library (-lidn2). */
+/* #undef HAVE_LIBIDN2 */
+
+/* Define to 1 if using libressl. */
+/* #undef HAVE_LIBRESSL */
+
+/* Define to 1 if you have the <librtmp/rtmp.h> header file. */
+/* #undef HAVE_LIBRTMP_RTMP_H */
+
+/* Define to 1 if you have the `ssh2' library (-lssh2). */
+/* #undef HAVE_LIBSSH2 */
+
+/* Define to 1 if you have the <libssh2.h> header file. */
+/* #undef HAVE_LIBSSH2_H */
+
+/* Define to 1 if you have the `ssl' library (-lssl). */
+#define HAVE_LIBSSL 1
+
+/* if zlib is available */
+#define HAVE_LIBZ 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the <linux/tcp.h> header file. */
+/* #undef HAVE_LINUX_TCP_H */
+
+/* if your compiler supports LL */
+#define HAVE_LL 1
+
+/* Define to 1 if you have the <locale.h> header file. */
+#define HAVE_LOCALE_H 1
+
+/* Define to 1 if you have a working localtime_r function. */
+#define HAVE_LOCALTIME_R 1
+
+/* Define to 1 if the compiler supports the 'long long' data type. */
+#define HAVE_LONGLONG 1
+
+/* Define to 1 if you have the `mach_absolute_time' function. */
+/* #undef HAVE_MACH_ABSOLUTE_TIME */
+
+/* Define to 1 if you have the malloc.h header file. */
+#define HAVE_MALLOC_H 1
+
+/* Define to 1 if you have the memory.h header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the memrchr function or macro. */
+/* #undef HAVE_MEMRCHR */
+
+/* Define to 1 if you have the MSG_NOSIGNAL flag. */
+#define HAVE_MSG_NOSIGNAL 1
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+#define HAVE_NETINET_TCP_H 1
+
+/* Define to 1 if you have the <net/if.h> header file. */
+#define HAVE_NET_IF_H 1
+
+/* Define to 1 if you have the <nghttp2/nghttp2.h> header file. */
+/* #undef HAVE_NGHTTP2_NGHTTP2_H */
+
+/* Define to 1 if NI_WITHSCOPEID exists and works. */
+/* #undef HAVE_NI_WITHSCOPEID */
+
+/* if you have an old MIT Kerberos version, lacking GSS_C_NT_HOSTBASED_SERVICE
+   */
+/* #undef HAVE_OLD_GSSMIT */
+
+/* Define to 1 if you have the <openssl/crypto.h> header file. */
+#define HAVE_OPENSSL_CRYPTO_H 1
+
+/* Define to 1 if you have the <openssl/engine.h> header file. */
+#define HAVE_OPENSSL_ENGINE_H 1
+
+/* Define to 1 if you have the <openssl/err.h> header file. */
+#define HAVE_OPENSSL_ERR_H 1
+
+/* Define to 1 if you have the <openssl/pem.h> header file. */
+#define HAVE_OPENSSL_PEM_H 1
+
+/* Define to 1 if you have the <openssl/rsa.h> header file. */
+#define HAVE_OPENSSL_RSA_H 1
+
+/* if you have the function SRP_Calc_client_key */
+#define HAVE_OPENSSL_SRP 1
+
+/* Define to 1 if you have the <openssl/ssl.h> header file. */
+#define HAVE_OPENSSL_SSL_H 1
+
+/* Define to 1 if you have the <openssl/x509.h> header file. */
+#define HAVE_OPENSSL_X509_H 1
+
+/* Define to 1 if you have the <pem.h> header file. */
+/* #undef HAVE_PEM_H */
+
+/* Define to 1 if you have the `pipe' function. */
+/* #undef HAVE_PIPE */
+
+/* Define to 1 if you have a working poll function. */
+/* #undef HAVE_POLL */
+
+/* If you have a fine poll */
+/* #undef HAVE_POLL_FINE */
+
+/* Define to 1 if you have the <poll.h> header file. */
+#define HAVE_POLL_H 1
+
+/* Define to 1 if you have a working POSIX-style strerror_r function. */
+#define HAVE_POSIX_STRERROR_R 1
+
+/* if you have <pthread.h> */
+/* #undef HAVE_PTHREAD_H */
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#define HAVE_PWD_H 1
+
+/* Define to 1 if you have the `RAND_egd' function. */
+/* #undef HAVE_RAND_EGD */
+
+/* Define to 1 if you have the recv function. */
+#define HAVE_RECV 1
+
+/* Define to 1 if you have the <rsa.h> header file. */
+/* #undef HAVE_RSA_H */
+
+/* Define to 1 if you have the select function. */
+#define HAVE_SELECT 1
+
+/* Define to 1 if you have the send function. */
+#define HAVE_SEND 1
+
+/* Define to 1 if you have the <setjmp.h> header file. */
+#define HAVE_SETJMP_H 1
+
+/* Define to 1 if you have the `setlocale' function. */
+#define HAVE_SETLOCALE 1
+
+/* Define to 1 if you have the `setmode' function. */
+/* #undef HAVE_SETMODE */
+
+/* Define to 1 if you have the `setrlimit' function. */
+#define HAVE_SETRLIMIT 1
+
+/* Define to 1 if you have the setsockopt function. */
+/* #undef HAVE_SETSOCKOPT */
+
+/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
+/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */
+
+/* Define to 1 if you have the <sgtty.h> header file. */
+/* #undef HAVE_SGTTY_H */
+
+/* Define to 1 if you have the sigaction function. */
+#define HAVE_SIGACTION 1
+
+/* Define to 1 if you have the siginterrupt function. */
+/* #undef HAVE_SIGINTERRUPT */
+
+/* Define to 1 if you have the signal function. */
+#define HAVE_SIGNAL 1
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define to 1 if you have the sigsetjmp function or macro. */
+/* #undef HAVE_SIGSETJMP */
+
+/* Define to 1 if sig_atomic_t is an available typedef. */
+#define HAVE_SIG_ATOMIC_T 1
+
+/* Define to 1 if sig_atomic_t is already defined as volatile. */
+/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */
+
+/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+
+/* Define to 1 if you have the socket function. */
+#define HAVE_SOCKET 1
+
+/* Define to 1 if you have the socketpair function. */
+/* #undef HAVE_SOCKETPAIR */
+
+/* Define to 1 if you have the <socket.h> header file. */
+/* #undef HAVE_SOCKET_H */
+
+/* Define to 1 if you have the `SSLv2_client_method' function. */
+/* #undef HAVE_SSLV2_CLIENT_METHOD */
+
+/* Define to 1 if you have the `SSL_get_shutdown' function. */
+#define HAVE_SSL_GET_SHUTDOWN 1
+
+/* Define to 1 if you have the <ssl.h> header file. */
+/* #undef HAVE_SSL_H */
+
+/* Define to 1 if you have the <stdbool.h> header file. */
+#define HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#define HAVE_STDIO_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the strcasecmp function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the strcmpi function. */
+/* #undef HAVE_STRCMPI */
+
+/* Define to 1 if you have the strdup function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the strerror_r function. */
+#define HAVE_STRERROR_R 1
+
+/* Define to 1 if you have the stricmp function. */
+/* #undef HAVE_STRICMP */
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the strncasecmp function. */
+#define HAVE_STRNCASECMP 1
+
+/* Define to 1 if you have the strncmpi function. */
+/* #undef HAVE_STRNCMPI */
+
+/* Define to 1 if you have the strnicmp function. */
+/* #undef HAVE_STRNICMP */
+
+/* Define to 1 if you have the <stropts.h> header file. */
+#define HAVE_STROPTS_H 1
+
+/* Define to 1 if you have the strstr function. */
+#define HAVE_STRSTR 1
+
+/* Define to 1 if you have the strtok_r function. */
+#define HAVE_STRTOK_R 1
+
+/* Define to 1 if you have the strtoll function. */
+#define HAVE_STRTOLL 1
+
+/* if struct sockaddr_storage is defined */
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+
+/* Define to 1 if you have the timeval struct. */
+#define HAVE_STRUCT_TIMEVAL 1
+
+/* Define to 1 if you have the <sys/filio.h> header file. */
+/* #undef HAVE_SYS_FILIO_H */
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+#define HAVE_SYS_POLL_H 1
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/sockio.h> header file. */
+/* #undef HAVE_SYS_SOCKIO_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#define HAVE_SYS_UIO_H 1
+
+/* Define to 1 if you have the <sys/un.h> header file. */
+#define HAVE_SYS_UN_H 1
+
+/* Define to 1 if you have the <sys/utime.h> header file. */
+/* #undef HAVE_SYS_UTIME_H */
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define to 1 if you have the <sys/xattr.h> header file. */
+#define HAVE_SYS_XATTR_H 1
+
+/* Define to 1 if you have the <termios.h> header file. */
+#define HAVE_TERMIOS_H 1
+
+/* Define to 1 if you have the <termio.h> header file. */
+/* #undef HAVE_TERMIO_H */
+
+/* Define to 1 if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `utime' function. */
+#define HAVE_UTIME 1
+
+/* Define to 1 if you have the `utimes' function. */
+#define HAVE_UTIMES 1
+
+/* Define to 1 if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* Define to 1 if compiler supports C99 variadic macro style. */
+#define HAVE_VARIADIC_MACROS_C99 1
+
+/* Define to 1 if compiler supports old gcc variadic macro style. */
+#define HAVE_VARIADIC_MACROS_GCC 1
+
+/* Define to 1 if you have the winber.h header file. */
+/* #undef HAVE_WINBER_H */
+
+/* Define to 1 if you have the windows.h header file. */
+/* #undef HAVE_WINDOWS_H */
+
+/* Define to 1 if you have the winldap.h header file. */
+/* #undef HAVE_WINLDAP_H */
+
+/* Define to 1 if you have the winsock2.h header file. */
+/* #undef HAVE_WINSOCK2_H */
+
+/* Define to 1 if you have the winsock.h header file. */
+/* #undef HAVE_WINSOCK_H */
+
+/* Define to 1 if you have the `wolfSSLv3_client_method' function. */
+/* #undef HAVE_WOLFSSLV3_CLIENT_METHOD */
+
+/* Define to 1 if you have the `wolfSSL_CTX_UseSupportedCurve' function. */
+/* #undef HAVE_WOLFSSL_CTX_USESUPPORTEDCURVE */
+
+/* Define to 1 if you have the `wolfSSL_get_peer_certificate' function. */
+/* #undef HAVE_WOLFSSL_GET_PEER_CERTIFICATE */
+
+/* Define to 1 if you have the `wolfSSL_UseALPN' function. */
+/* #undef HAVE_WOLFSSL_USEALPN */
+
+/* Define this symbol if your OS supports changing the contents of argv */
+/* #undef HAVE_WRITABLE_ARGV */
+
+/* Define to 1 if you have the writev function. */
+/* #undef HAVE_WRITEV */
+
+/* Define to 1 if you have the ws2tcpip.h header file. */
+/* #undef HAVE_WS2TCPIP_H */
+
+/* Define to 1 if you have the <x509.h> header file. */
+/* #undef HAVE_X509_H */
+
+/* if you have the zlib.h header file */
+#define HAVE_ZLIB_H 1
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#define LT_OBJDIR ".libs/"
+
+/* Define to 1 if you need the lber.h header file even with ldap.h */
+/* #undef NEED_LBER_H */
+
+/* Define to 1 if you need the malloc.h header file even with stdlib.h */
+/* #undef NEED_MALLOC_H */
+
+/* Define to 1 if you need the memory.h header file even with stdlib.h */
+/* #undef NEED_MEMORY_H */
+
+/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
+/* #undef NEED_REENTRANT */
+
+/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */
+/* #undef NEED_THREAD_SAFE */
+
+/* Define to enable NTLM delegation to winbind's ntlm_auth helper. */
+#define NTLM_WB_ENABLED 1
+
+/* Define absolute filename for winbind's ntlm_auth helper. */
+#define NTLM_WB_FILE "/usr/bin/ntlm_auth"
+
+/* cpu-machine-OS */
+#define OS "arm-none-eabi"
+
+/* Name of package */
+#define PACKAGE "curl"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "a suitable curl mailing list: https://curl.haxx.se/mail/"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "curl"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "curl -"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "curl"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "-"
+
+/* a suitable file to read random data from */
+/* #undef RANDOM_FILE */
+
+/* Define to the type of arg 1 for recv. */
+#define RECV_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for recv. */
+#define RECV_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for recv. */
+#define RECV_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recv. */
+#define RECV_TYPE_ARG4 int
+
+/* Define to the function return type for recv. */
+#define RECV_TYPE_RETV int
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* Define to the type qualifier of arg 5 for select. */
+#define SELECT_QUAL_ARG5 
+
+/* Define to the type of arg 1 for select. */
+#define SELECT_TYPE_ARG1 int
+
+/* Define to the type of args 2, 3 and 4 for select. */
+#define SELECT_TYPE_ARG234 fd_set *
+
+/* Define to the type of arg 5 for select. */
+#define SELECT_TYPE_ARG5 struct timeval *
+
+/* Define to the function return type for select. */
+#define SELECT_TYPE_RETV int
+
+/* Define to the type qualifier of arg 2 for send. */
+#define SEND_QUAL_ARG2 const
+
+/* Define to the type of arg 1 for send. */
+#define SEND_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for send. */
+#define SEND_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for send. */
+#define SEND_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for send. */
+#define SEND_TYPE_ARG4 int
+
+/* Define to the function return type for send. */
+#define SEND_TYPE_RETV int
+
+/* The size of `curl_off_t', as computed by sizeof. */
+#define SIZEOF_CURL_OFF_T 8
+
+/* The size of `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of `long', as computed by sizeof. */
+#define SIZEOF_LONG 4
+
+/* The size of `long long', as computed by sizeof. */
+/* #undef SIZEOF_LONG_LONG */
+
+/* The size of `off_t', as computed by sizeof. */
+#define SIZEOF_OFF_T 8
+
+/* The size of `short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* The size of `size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T 4
+
+/* The size of `time_t', as computed by sizeof. */
+#define SIZEOF_TIME_T 4
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to the type of arg 3 for strerror_r. */
+#define STRERROR_R_TYPE_ARG3 size_t
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define to enable c-ares support */
+/* #undef USE_ARES */
+
+/* if axTLS is enabled */
+/* #undef USE_AXTLS */
+
+/* if CyaSSL/WolfSSL is enabled */
+/* #undef USE_CYASSL */
+
+/* to enable Apple OS native SSL/TLS support */
+/* #undef USE_DARWINSSL */
+
+/* if GnuTLS is enabled */
+/* #undef USE_GNUTLS */
+
+/* if GnuTLS uses nettle as crypto backend */
+/* #undef USE_GNUTLS_NETTLE */
+
+/* PSL support enabled */
+/* #undef USE_LIBPSL */
+
+/* if librtmp is in use */
+/* #undef USE_LIBRTMP */
+
+/* if libSSH2 is in use */
+/* #undef USE_LIBSSH2 */
+
+/* If you want to build curl with the built-in manual */
+#define USE_MANUAL 1
+
+/* if mbedTLS is enabled */
+/* #undef USE_MBEDTLS */
+
+/* Define to enable metalink support */
+/* #undef USE_METALINK */
+
+/* if nghttp2 is in use */
+/* #undef USE_NGHTTP2 */
+
+/* if NSS is enabled */
+/* #undef USE_NSS */
+
+/* Use OpenLDAP-specific code */
+/* #undef USE_OPENLDAP */
+
+/* if OpenSSL is in use */
+#define USE_OPENSSL 1
+
+/* if PolarSSL is enabled */
+/* #undef USE_POLARSSL */
+
+/* to enable Windows native SSL/TLS support */
+/* #undef USE_SCHANNEL */
+
+/* if you want POSIX threaded DNS lookup */
+/* #undef USE_THREADS_POSIX */
+
+/* if you want Win32 threaded DNS lookup */
+/* #undef USE_THREADS_WIN32 */
+
+/* Use TLS-SRP authentication */
+#define USE_TLS_SRP 1
+
+/* Use Unix domain sockets */
+#define USE_UNIX_SOCKETS 1
+
+/* Define to 1 if you have the `normaliz' (WinIDN) library (-lnormaliz). */
+/* #undef USE_WIN32_IDN */
+
+/* Define to 1 if you are building a Windows target with large file support.
+   */
+/* #undef USE_WIN32_LARGE_FILES */
+
+/* Use Windows LDAP implementation */
+/* #undef USE_WIN32_LDAP */
+
+/* Define to 1 if you are building a Windows target without large file
+   support. */
+/* #undef USE_WIN32_SMALL_FILES */
+
+/* to enable SSPI support */
+/* #undef USE_WINDOWS_SSPI */
+
+/* Version number of package */
+#define VERSION "-"
+
+/* Define to 1 to provide own prototypes. */
+/* #undef WANT_IDN_PROTOTYPES */
+
+/* Define to 1 if OS is AIX. */
+#ifndef _ALL_SOURCE
+/* #  undef _ALL_SOURCE */
+#endif
+
+/* Enable large inode numbers on Mac OS X 10.5.  */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Type to use in place of in_addr_t when system does not provide it. */
+/* #undef in_addr_t */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* the signed version of size_t */
+/* #undef ssize_t */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_des.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_des.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_des.c	(revision 331)
@@ -0,0 +1,63 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2015, Steve Holme, <steve_holme@hotmail.com>.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_NTLM) && !defined(USE_OPENSSL)
+
+#include "curl_des.h"
+
+/*
+ * Curl_des_set_odd_parity()
+ *
+ * This is used to apply odd parity to the given byte array. It is typically
+ * used by when a cryptography engines doesn't have it's own version.
+ *
+ * The function is a port of the Java based oddParity() function over at:
+ *
+ * https://davenport.sourceforge.io/ntlm.html
+ *
+ * Parameters:
+ *
+ * bytes       [in/out] - The data whose parity bits are to be adjusted for
+ *                        odd parity.
+ * len         [out]    - The length of the data.
+ */
+void Curl_des_set_odd_parity(unsigned char *bytes, size_t len)
+{
+  size_t i;
+
+  for(i = 0; i < len; i++) {
+    unsigned char b = bytes[i];
+
+    bool needs_parity = (((b >> 7) ^ (b >> 6) ^ (b >> 5) ^
+                          (b >> 4) ^ (b >> 3) ^ (b >> 2) ^
+                          (b >> 1)) & 0x01) == 0;
+
+    if(needs_parity)
+      bytes[i] |= 0x01;
+    else
+      bytes[i] &= 0xfe;
+  }
+}
+
+#endif /* USE_NTLM && !USE_OPENSSL */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_des.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_des.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_des.h	(revision 331)
@@ -0,0 +1,34 @@
+#ifndef HEADER_CURL_DES_H
+#define HEADER_CURL_DES_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2015, Steve Holme, <steve_holme@hotmail.com>.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_NTLM) && !defined(USE_OPENSSL)
+
+/* Applies odd parity to the given byte array */
+void Curl_des_set_odd_parity(unsigned char *bytes, size_t length);
+
+#endif /* USE_NTLM && !USE_OPENSSL */
+
+#endif /* HEADER_CURL_DES_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_endian.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_endian.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_endian.c	(revision 331)
@@ -0,0 +1,124 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "curl_endian.h"
+
+/*
+ * Curl_read16_le()
+ *
+ * This function converts a 16-bit integer from the little endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf      [in]     - A pointer to a 2 byte buffer.
+ *
+ * Returns the integer.
+ */
+unsigned short Curl_read16_le(const unsigned char *buf)
+{
+  return (unsigned short)(((unsigned short)buf[0]) |
+                          ((unsigned short)buf[1] << 8));
+}
+
+/*
+ * Curl_read32_le()
+ *
+ * This function converts a 32-bit integer from the little endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf      [in]     - A pointer to a 4 byte buffer.
+ *
+ * Returns the integer.
+ */
+unsigned int Curl_read32_le(const unsigned char *buf)
+{
+  return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) |
+         ((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24);
+}
+
+/*
+ * Curl_read16_be()
+ *
+ * This function converts a 16-bit integer from the big endian format, as
+ * used in the incoming package to whatever endian format we're using
+ * natively.
+ *
+ * Parameters:
+ *
+ * buf      [in]     - A pointer to a 2 byte buffer.
+ *
+ * Returns the integer.
+ */
+unsigned short Curl_read16_be(const unsigned char *buf)
+{
+  return (unsigned short)(((unsigned short)buf[0] << 8) |
+                          ((unsigned short)buf[1]));
+}
+
+/*
+ * Curl_write32_le()
+ *
+ * This function converts a 32-bit integer from the native endian format,
+ * to little endian format ready for sending down the wire.
+ *
+ * Parameters:
+ *
+ * value    [in]     - The 32-bit integer value.
+ * buffer   [in]     - A pointer to the output buffer.
+ */
+void Curl_write32_le(const int value, unsigned char *buffer)
+{
+  buffer[0] = (char)(value & 0x000000FF);
+  buffer[1] = (char)((value & 0x0000FF00) >> 8);
+  buffer[2] = (char)((value & 0x00FF0000) >> 16);
+  buffer[3] = (char)((value & 0xFF000000) >> 24);
+}
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+/*
+ * Curl_write64_le()
+ *
+ * This function converts a 64-bit integer from the native endian format,
+ * to little endian format ready for sending down the wire.
+ *
+ * Parameters:
+ *
+ * value    [in]     - The 64-bit integer value.
+ * buffer   [in]     - A pointer to the output buffer.
+ */
+#if defined(HAVE_LONGLONG)
+void Curl_write64_le(const long long value, unsigned char *buffer)
+#else
+void Curl_write64_le(const __int64 value, unsigned char *buffer)
+#endif
+{
+  Curl_write32_le((int)value, buffer);
+  Curl_write32_le((int)(value >> 32), buffer + 4);
+}
+#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_endian.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_endian.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_endian.h	(revision 331)
@@ -0,0 +1,46 @@
+#ifndef HEADER_CURL_ENDIAN_H
+#define HEADER_CURL_ENDIAN_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* Converts a 16-bit integer from little endian */
+unsigned short Curl_read16_le(const unsigned char *buf);
+
+/* Converts a 32-bit integer from little endian */
+unsigned int Curl_read32_le(const unsigned char *buf);
+
+/* Converts a 16-bit integer from big endian */
+unsigned short Curl_read16_be(const unsigned char *buf);
+
+/* Converts a 32-bit integer to little endian */
+void Curl_write32_le(const int value, unsigned char *buffer);
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+/* Converts a 64-bit integer to little endian */
+#if defined(HAVE_LONGLONG)
+void Curl_write64_le(const long long value, unsigned char *buffer);
+#else
+void Curl_write64_le(const __int64 value, unsigned char *buffer);
+#endif
+#endif
+
+#endif /* HEADER_CURL_ENDIAN_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_fnmatch.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_fnmatch.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_fnmatch.c	(revision 331)
@@ -0,0 +1,418 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "curl_fnmatch.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#define CURLFNM_CHARSET_LEN (sizeof(char) * 256)
+#define CURLFNM_CHSET_SIZE (CURLFNM_CHARSET_LEN + 15)
+
+#define CURLFNM_NEGATE  CURLFNM_CHARSET_LEN
+
+#define CURLFNM_ALNUM   (CURLFNM_CHARSET_LEN + 1)
+#define CURLFNM_DIGIT   (CURLFNM_CHARSET_LEN + 2)
+#define CURLFNM_XDIGIT  (CURLFNM_CHARSET_LEN + 3)
+#define CURLFNM_ALPHA   (CURLFNM_CHARSET_LEN + 4)
+#define CURLFNM_PRINT   (CURLFNM_CHARSET_LEN + 5)
+#define CURLFNM_BLANK   (CURLFNM_CHARSET_LEN + 6)
+#define CURLFNM_LOWER   (CURLFNM_CHARSET_LEN + 7)
+#define CURLFNM_GRAPH   (CURLFNM_CHARSET_LEN + 8)
+#define CURLFNM_SPACE   (CURLFNM_CHARSET_LEN + 9)
+#define CURLFNM_UPPER   (CURLFNM_CHARSET_LEN + 10)
+
+typedef enum {
+  CURLFNM_LOOP_DEFAULT = 0,
+  CURLFNM_LOOP_BACKSLASH
+} loop_state;
+
+typedef enum {
+  CURLFNM_SCHS_DEFAULT = 0,
+  CURLFNM_SCHS_MAYRANGE,
+  CURLFNM_SCHS_MAYRANGE2,
+  CURLFNM_SCHS_RIGHTBR,
+  CURLFNM_SCHS_RIGHTBRLEFTBR
+} setcharset_state;
+
+typedef enum {
+  CURLFNM_PKW_INIT = 0,
+  CURLFNM_PKW_DDOT
+} parsekey_state;
+
+#define SETCHARSET_OK     1
+#define SETCHARSET_FAIL   0
+
+static int parsekeyword(unsigned char **pattern, unsigned char *charset)
+{
+  parsekey_state state = CURLFNM_PKW_INIT;
+#define KEYLEN 10
+  char keyword[KEYLEN] = { 0 };
+  int found = FALSE;
+  int i;
+  unsigned char *p = *pattern;
+  for(i = 0; !found; i++) {
+    char c = *p++;
+    if(i >= KEYLEN)
+      return SETCHARSET_FAIL;
+    switch(state) {
+    case CURLFNM_PKW_INIT:
+      if(ISALPHA(c) && ISLOWER(c))
+        keyword[i] = c;
+      else if(c == ':')
+        state = CURLFNM_PKW_DDOT;
+      else
+        return 0;
+      break;
+    case CURLFNM_PKW_DDOT:
+      if(c == ']')
+        found = TRUE;
+      else
+        return SETCHARSET_FAIL;
+    }
+  }
+#undef KEYLEN
+
+  *pattern = p; /* move caller's pattern pointer */
+  if(strcmp(keyword, "digit") == 0)
+    charset[CURLFNM_DIGIT] = 1;
+  else if(strcmp(keyword, "alnum") == 0)
+    charset[CURLFNM_ALNUM] = 1;
+  else if(strcmp(keyword, "alpha") == 0)
+    charset[CURLFNM_ALPHA] = 1;
+  else if(strcmp(keyword, "xdigit") == 0)
+    charset[CURLFNM_XDIGIT] = 1;
+  else if(strcmp(keyword, "print") == 0)
+    charset[CURLFNM_PRINT] = 1;
+  else if(strcmp(keyword, "graph") == 0)
+    charset[CURLFNM_GRAPH] = 1;
+  else if(strcmp(keyword, "space") == 0)
+    charset[CURLFNM_SPACE] = 1;
+  else if(strcmp(keyword, "blank") == 0)
+    charset[CURLFNM_BLANK] = 1;
+  else if(strcmp(keyword, "upper") == 0)
+    charset[CURLFNM_UPPER] = 1;
+  else if(strcmp(keyword, "lower") == 0)
+    charset[CURLFNM_LOWER] = 1;
+  else
+    return SETCHARSET_FAIL;
+  return SETCHARSET_OK;
+}
+
+/* returns 1 (true) if pattern is OK, 0 if is bad ("p" is pattern pointer) */
+static int setcharset(unsigned char **p, unsigned char *charset)
+{
+  setcharset_state state = CURLFNM_SCHS_DEFAULT;
+  unsigned char rangestart = 0;
+  unsigned char lastchar   = 0;
+  bool something_found = FALSE;
+  unsigned char c;
+  for(;;) {
+    c = **p;
+    if(!c)
+      return SETCHARSET_FAIL;
+
+    switch(state) {
+    case CURLFNM_SCHS_DEFAULT:
+      if(ISALNUM(c)) { /* ASCII value */
+        rangestart = c;
+        charset[c] = 1;
+        (*p)++;
+        state = CURLFNM_SCHS_MAYRANGE;
+        something_found = TRUE;
+      }
+      else if(c == ']') {
+        if(something_found)
+          return SETCHARSET_OK;
+        something_found = TRUE;
+        state = CURLFNM_SCHS_RIGHTBR;
+        charset[c] = 1;
+        (*p)++;
+      }
+      else if(c == '[') {
+        char c2 = *((*p) + 1);
+        if(c2 == ':') { /* there has to be a keyword */
+          (*p) += 2;
+          if(parsekeyword(p, charset)) {
+            state = CURLFNM_SCHS_DEFAULT;
+          }
+          else
+            return SETCHARSET_FAIL;
+        }
+        else {
+          charset[c] = 1;
+          (*p)++;
+        }
+        something_found = TRUE;
+      }
+      else if(c == '?' || c == '*') {
+        something_found = TRUE;
+        charset[c] = 1;
+        (*p)++;
+      }
+      else if(c == '^' || c == '!') {
+        if(!something_found) {
+          if(charset[CURLFNM_NEGATE]) {
+            charset[c] = 1;
+            something_found = TRUE;
+          }
+          else
+            charset[CURLFNM_NEGATE] = 1; /* negate charset */
+        }
+        else
+          charset[c] = 1;
+        (*p)++;
+      }
+      else if(c == '\\') {
+        c = *(++(*p));
+        if(ISPRINT((c))) {
+          something_found = TRUE;
+          state = CURLFNM_SCHS_MAYRANGE;
+          charset[c] = 1;
+          rangestart = c;
+          (*p)++;
+        }
+        else
+          return SETCHARSET_FAIL;
+      }
+      else {
+        charset[c] = 1;
+        (*p)++;
+        something_found = TRUE;
+      }
+      break;
+    case CURLFNM_SCHS_MAYRANGE:
+      if(c == '-') {
+        charset[c] = 1;
+        (*p)++;
+        lastchar = '-';
+        state = CURLFNM_SCHS_MAYRANGE2;
+      }
+      else if(c == '[') {
+        state = CURLFNM_SCHS_DEFAULT;
+      }
+      else if(ISALNUM(c)) {
+        charset[c] = 1;
+        (*p)++;
+      }
+      else if(c == '\\') {
+        c = *(++(*p));
+        if(ISPRINT(c)) {
+          charset[c] = 1;
+          (*p)++;
+        }
+        else
+          return SETCHARSET_FAIL;
+      }
+      else if(c == ']') {
+        return SETCHARSET_OK;
+      }
+      else
+        return SETCHARSET_FAIL;
+      break;
+    case CURLFNM_SCHS_MAYRANGE2:
+      if(c == ']') {
+        return SETCHARSET_OK;
+      }
+      else if(c == '\\') {
+        c = *(++(*p));
+        if(ISPRINT(c)) {
+          charset[c] = 1;
+          state = CURLFNM_SCHS_DEFAULT;
+          (*p)++;
+        }
+        else
+          return SETCHARSET_FAIL;
+      }
+      else if(c >= rangestart) {
+        if((ISLOWER(c) && ISLOWER(rangestart)) ||
+           (ISDIGIT(c) && ISDIGIT(rangestart)) ||
+           (ISUPPER(c) && ISUPPER(rangestart))) {
+          charset[lastchar] = 0;
+          rangestart++;
+          while(rangestart++ <= c)
+            charset[rangestart-1] = 1;
+          (*p)++;
+          state = CURLFNM_SCHS_DEFAULT;
+        }
+        else
+          return SETCHARSET_FAIL;
+      }
+      else
+        return SETCHARSET_FAIL;
+      break;
+    case CURLFNM_SCHS_RIGHTBR:
+      if(c == '[') {
+        state = CURLFNM_SCHS_RIGHTBRLEFTBR;
+        charset[c] = 1;
+        (*p)++;
+      }
+      else if(c == ']') {
+        return SETCHARSET_OK;
+      }
+      else if(ISPRINT(c)) {
+        charset[c] = 1;
+        (*p)++;
+        state = CURLFNM_SCHS_DEFAULT;
+      }
+      else
+        /* used 'goto fail' instead of 'return SETCHARSET_FAIL' to avoid a
+         * nonsense warning 'statement not reached' at end of the fnc when
+         * compiling on Solaris */
+        goto fail;
+      break;
+    case CURLFNM_SCHS_RIGHTBRLEFTBR:
+      if(c == ']') {
+        return SETCHARSET_OK;
+      }
+      else {
+        state  = CURLFNM_SCHS_DEFAULT;
+        charset[c] = 1;
+        (*p)++;
+      }
+      break;
+    }
+  }
+fail:
+  return SETCHARSET_FAIL;
+}
+
+static int loop(const unsigned char *pattern, const unsigned char *string)
+{
+  loop_state state = CURLFNM_LOOP_DEFAULT;
+  unsigned char *p = (unsigned char *)pattern;
+  unsigned char *s = (unsigned char *)string;
+  unsigned char charset[CURLFNM_CHSET_SIZE] = { 0 };
+  int rc = 0;
+
+  for(;;) {
+    switch(state) {
+    case CURLFNM_LOOP_DEFAULT:
+      if(*p == '*') {
+        while(*(p + 1) == '*') /* eliminate multiple stars */
+          p++;
+        if(*s == '\0' && *(p + 1) == '\0')
+          return CURL_FNMATCH_MATCH;
+        rc = loop(p + 1, s); /* *.txt matches .txt <=> .txt matches .txt */
+        if(rc == CURL_FNMATCH_MATCH)
+          return CURL_FNMATCH_MATCH;
+        if(*s) /* let the star eat up one character */
+          s++;
+        else
+          return CURL_FNMATCH_NOMATCH;
+      }
+      else if(*p == '?') {
+        if(ISPRINT(*s)) {
+          s++;
+          p++;
+        }
+        else if(*s == '\0')
+          return CURL_FNMATCH_NOMATCH;
+        else
+          return CURL_FNMATCH_FAIL; /* cannot deal with other character */
+      }
+      else if(*p == '\0') {
+        if(*s == '\0')
+          return CURL_FNMATCH_MATCH;
+        return CURL_FNMATCH_NOMATCH;
+      }
+      else if(*p == '\\') {
+        state = CURLFNM_LOOP_BACKSLASH;
+        p++;
+      }
+      else if(*p == '[') {
+        unsigned char *pp = p + 1; /* cannot handle with pointer to register */
+        if(setcharset(&pp, charset)) {
+          int found = FALSE;
+          if(charset[(unsigned int)*s])
+            found = TRUE;
+          else if(charset[CURLFNM_ALNUM])
+            found = ISALNUM(*s);
+          else if(charset[CURLFNM_ALPHA])
+            found = ISALPHA(*s);
+          else if(charset[CURLFNM_DIGIT])
+            found = ISDIGIT(*s);
+          else if(charset[CURLFNM_XDIGIT])
+            found = ISXDIGIT(*s);
+          else if(charset[CURLFNM_PRINT])
+            found = ISPRINT(*s);
+          else if(charset[CURLFNM_SPACE])
+            found = ISSPACE(*s);
+          else if(charset[CURLFNM_UPPER])
+            found = ISUPPER(*s);
+          else if(charset[CURLFNM_LOWER])
+            found = ISLOWER(*s);
+          else if(charset[CURLFNM_BLANK])
+            found = ISBLANK(*s);
+          else if(charset[CURLFNM_GRAPH])
+            found = ISGRAPH(*s);
+
+          if(charset[CURLFNM_NEGATE])
+            found = !found;
+
+          if(found) {
+            p = pp + 1;
+            s++;
+            memset(charset, 0, CURLFNM_CHSET_SIZE);
+          }
+          else
+            return CURL_FNMATCH_NOMATCH;
+        }
+        else
+          return CURL_FNMATCH_FAIL;
+      }
+      else {
+        if(*p++ != *s++)
+          return CURL_FNMATCH_NOMATCH;
+      }
+      break;
+    case CURLFNM_LOOP_BACKSLASH:
+      if(ISPRINT(*p)) {
+        if(*p++ == *s++)
+          state = CURLFNM_LOOP_DEFAULT;
+        else
+          return CURL_FNMATCH_NOMATCH;
+      }
+      else
+        return CURL_FNMATCH_FAIL;
+      break;
+    }
+  }
+}
+
+/*
+ * @unittest: 1307
+ */
+int Curl_fnmatch(void *ptr, const char *pattern, const char *string)
+{
+  (void)ptr; /* the argument is specified by the curl_fnmatch_callback
+                prototype, but not used by Curl_fnmatch() */
+  if(!pattern || !string) {
+    return CURL_FNMATCH_FAIL;
+  }
+  return loop((unsigned char *)pattern, (unsigned char *)string);
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_fnmatch.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_fnmatch.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_fnmatch.h	(revision 331)
@@ -0,0 +1,44 @@
+#ifndef HEADER_CURL_FNMATCH_H
+#define HEADER_CURL_FNMATCH_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#define CURL_FNMATCH_MATCH    0
+#define CURL_FNMATCH_NOMATCH  1
+#define CURL_FNMATCH_FAIL     2
+
+/* default pattern matching function
+ * =================================
+ * Implemented with recursive backtracking, if you want to use Curl_fnmatch,
+ * please note that there is not implemented UTF/UNICODE support.
+ *
+ * Implemented features:
+ * '?' notation, does not match UTF characters
+ * '*' can also work with UTF string
+ * [a-zA-Z0-9] enumeration support
+ *
+ * keywords: alnum, digit, xdigit, alpha, print, blank, lower, graph, space
+ *           and upper (use as "[[:alnum:]]")
+ */
+int Curl_fnmatch(void *ptr, const char *pattern, const char *string);
+
+#endif /* HEADER_CURL_FNMATCH_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_gethostname.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_gethostname.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_gethostname.c	(revision 331)
@@ -0,0 +1,100 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "curl_gethostname.h"
+
+/*
+ * Curl_gethostname() is a wrapper around gethostname() which allows
+ * overriding the host name that the function would normally return.
+ * This capability is used by the test suite to verify exact matching
+ * of NTLM authentication, which exercises libcurl's MD4 and DES code
+ * as well as by the SMTP module when a hostname is not provided.
+ *
+ * For libcurl debug enabled builds host name overriding takes place
+ * when environment variable CURL_GETHOSTNAME is set, using the value
+ * held by the variable to override returned host name.
+ *
+ * Note: The function always returns the un-qualified hostname rather
+ * than being provider dependent.
+ *
+ * For libcurl shared library release builds the test suite preloads
+ * another shared library named libhostname using the LD_PRELOAD
+ * mechanism which intercepts, and might override, the gethostname()
+ * function call. In this case a given platform must support the
+ * LD_PRELOAD mechanism and additionally have environment variable
+ * CURL_GETHOSTNAME set in order to override the returned host name.
+ *
+ * For libcurl static library release builds no overriding takes place.
+ */
+
+int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen)
+{
+#ifndef HAVE_GETHOSTNAME
+
+  /* Allow compilation and return failure when unavailable */
+  (void) name;
+  (void) namelen;
+  return -1;
+
+#else
+  int err;
+  char *dot;
+
+#ifdef DEBUGBUILD
+
+  /* Override host name when environment variable CURL_GETHOSTNAME is set */
+  const char *force_hostname = getenv("CURL_GETHOSTNAME");
+  if(force_hostname) {
+    strncpy(name, force_hostname, namelen);
+    err = 0;
+  }
+  else {
+    name[0] = '\0';
+    err = gethostname(name, namelen);
+  }
+
+#else /* DEBUGBUILD */
+
+  /* The call to system's gethostname() might get intercepted by the
+     libhostname library when libcurl is built as a non-debug shared
+     library when running the test suite. */
+  name[0] = '\0';
+  err = gethostname(name, namelen);
+
+#endif
+
+  name[namelen - 1] = '\0';
+
+  if(err)
+    return err;
+
+  /* Truncate domain, leave only machine name */
+  dot = strchr(name, '.');
+  if(dot)
+    *dot = '\0';
+
+  return 0;
+#endif
+
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_gethostname.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_gethostname.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_gethostname.h	(revision 331)
@@ -0,0 +1,31 @@
+#ifndef HEADER_CURL_GETHOSTNAME_H
+#define HEADER_CURL_GETHOSTNAME_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* Hostname buffer size */
+#define HOSTNAME_MAX 1024
+
+/* This returns the local machine's un-qualified hostname */
+int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen);
+
+#endif /* HEADER_CURL_GETHOSTNAME_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_gssapi.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_gssapi.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_gssapi.c	(revision 331)
@@ -0,0 +1,131 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2011 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_GSSAPI
+
+#include "curl_gssapi.h"
+#include "sendf.h"
+
+static char spnego_oid_bytes[] = "\x2b\x06\x01\x05\x05\x02";
+gss_OID_desc Curl_spnego_mech_oid = { 6, &spnego_oid_bytes };
+static char krb5_oid_bytes[] = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02";
+gss_OID_desc Curl_krb5_mech_oid = { 9, &krb5_oid_bytes };
+
+OM_uint32 Curl_gss_init_sec_context(
+    struct Curl_easy *data,
+    OM_uint32 *minor_status,
+    gss_ctx_id_t *context,
+    gss_name_t target_name,
+    gss_OID mech_type,
+    gss_channel_bindings_t input_chan_bindings,
+    gss_buffer_t input_token,
+    gss_buffer_t output_token,
+    const bool mutual_auth,
+    OM_uint32 *ret_flags)
+{
+  OM_uint32 req_flags = GSS_C_REPLAY_FLAG;
+
+  if(mutual_auth)
+    req_flags |= GSS_C_MUTUAL_FLAG;
+
+  if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_POLICY_FLAG) {
+#ifdef GSS_C_DELEG_POLICY_FLAG
+    req_flags |= GSS_C_DELEG_POLICY_FLAG;
+#else
+    infof(data, "warning: support for CURLGSSAPI_DELEGATION_POLICY_FLAG not "
+        "compiled in\n");
+#endif
+  }
+
+  if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_FLAG)
+    req_flags |= GSS_C_DELEG_FLAG;
+
+  return gss_init_sec_context(minor_status,
+                              GSS_C_NO_CREDENTIAL, /* cred_handle */
+                              context,
+                              target_name,
+                              mech_type,
+                              req_flags,
+                              0, /* time_req */
+                              input_chan_bindings,
+                              input_token,
+                              NULL, /* actual_mech_type */
+                              output_token,
+                              ret_flags,
+                              NULL /* time_rec */);
+}
+
+#define GSS_LOG_BUFFER_LEN 1024
+static size_t display_gss_error(OM_uint32 status, int type,
+                                char *buf, size_t len) {
+  OM_uint32 maj_stat;
+  OM_uint32 min_stat;
+  OM_uint32 msg_ctx = 0;
+  gss_buffer_desc status_string;
+
+  do {
+    maj_stat = gss_display_status(&min_stat,
+                                  status,
+                                  type,
+                                  GSS_C_NO_OID,
+                                  &msg_ctx,
+                                  &status_string);
+    if(GSS_LOG_BUFFER_LEN > len + status_string.length + 3) {
+      len += snprintf(buf + len, GSS_LOG_BUFFER_LEN - len,
+                      "%.*s. ", (int)status_string.length,
+                      (char *)status_string.value);
+    }
+    gss_release_buffer(&min_stat, &status_string);
+  } while(!GSS_ERROR(maj_stat) && msg_ctx != 0);
+
+  return len;
+}
+
+/*
+ * Curl_gss_log_error()
+ *
+ * This is used to log a GSS-API error status.
+ *
+ * Parameters:
+ *
+ * data    [in] - The session handle.
+ * prefix  [in] - The prefix of the log message.
+ * major   [in] - The major status code.
+ * minor   [in] - The minor status code.
+ */
+void Curl_gss_log_error(struct Curl_easy *data, const char *prefix,
+                        OM_uint32 major, OM_uint32 minor)
+{
+  char buf[GSS_LOG_BUFFER_LEN];
+  size_t len = 0;
+
+  if(major != GSS_S_FAILURE)
+    len = display_gss_error(major, GSS_C_GSS_CODE, buf, len);
+
+  display_gss_error(minor, GSS_C_MECH_CODE, buf, len);
+
+  infof(data, "%s%s\n", prefix, buf);
+}
+
+#endif /* HAVE_GSSAPI */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_gssapi.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_gssapi.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_gssapi.h	(revision 331)
@@ -0,0 +1,75 @@
+#ifndef HEADER_CURL_GSSAPI_H
+#define HEADER_CURL_GSSAPI_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2011 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "urldata.h"
+
+#ifdef HAVE_GSSAPI
+
+#ifdef HAVE_GSSGNU
+#  include <gss.h>
+#elif defined HAVE_GSSMIT
+   /* MIT style */
+#  include <gssapi/gssapi.h>
+#  include <gssapi/gssapi_generic.h>
+#  include <gssapi/gssapi_krb5.h>
+#else
+   /* Heimdal-style */
+#  include <gssapi.h>
+#endif
+
+extern gss_OID_desc Curl_spnego_mech_oid;
+extern gss_OID_desc Curl_krb5_mech_oid;
+
+/* Common method for using GSS-API */
+OM_uint32 Curl_gss_init_sec_context(
+    struct Curl_easy *data,
+    OM_uint32 *minor_status,
+    gss_ctx_id_t *context,
+    gss_name_t target_name,
+    gss_OID mech_type,
+    gss_channel_bindings_t input_chan_bindings,
+    gss_buffer_t input_token,
+    gss_buffer_t output_token,
+    const bool mutual_auth,
+    OM_uint32 *ret_flags);
+
+/* Helper to log a GSS-API error status */
+void Curl_gss_log_error(struct Curl_easy *data, const char *prefix,
+                        OM_uint32 major, OM_uint32 minor);
+
+/* Provide some definitions missing in old headers */
+#ifdef HAVE_OLD_GSSMIT
+#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
+#define NCOMPAT 1
+#endif
+
+/* Define our privacy and integrity protection values */
+#define GSSAUTH_P_NONE      1
+#define GSSAUTH_P_INTEGRITY 2
+#define GSSAUTH_P_PRIVACY   4
+
+#endif /* HAVE_GSSAPI */
+
+#endif /* HEADER_CURL_GSSAPI_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_hmac.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_hmac.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_hmac.h	(revision 331)
@@ -0,0 +1,67 @@
+#ifndef HEADER_CURL_HMAC_H
+#define HEADER_CURL_HMAC_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+
+typedef void    (* HMAC_hinit_func)(void *context);
+typedef void    (* HMAC_hupdate_func)(void *context,
+                                      const unsigned char *data,
+                                      unsigned int len);
+typedef void    (* HMAC_hfinal_func)(unsigned char *result, void *context);
+
+
+/* Per-hash function HMAC parameters. */
+
+typedef struct {
+  HMAC_hinit_func       hmac_hinit;     /* Initialize context procedure. */
+  HMAC_hupdate_func     hmac_hupdate;   /* Update context with data. */
+  HMAC_hfinal_func      hmac_hfinal;    /* Get final result procedure. */
+  unsigned int          hmac_ctxtsize;  /* Context structure size. */
+  unsigned int          hmac_maxkeylen; /* Maximum key length (bytes). */
+  unsigned int          hmac_resultlen; /* Result length (bytes). */
+} HMAC_params;
+
+
+/* HMAC computation context. */
+
+typedef struct {
+  const HMAC_params *hmac_hash; /* Hash function definition. */
+  void *hmac_hashctxt1;         /* Hash function context 1. */
+  void *hmac_hashctxt2;         /* Hash function context 2. */
+} HMAC_context;
+
+
+/* Prototypes. */
+
+HMAC_context * Curl_HMAC_init(const HMAC_params *hashparams,
+                              const unsigned char *key,
+                              unsigned int keylen);
+int Curl_HMAC_update(HMAC_context *context,
+                     const unsigned char *data,
+                     unsigned int len);
+int Curl_HMAC_final(HMAC_context *context, unsigned char *result);
+
+#endif
+
+#endif /* HEADER_CURL_HMAC_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_ldap.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_ldap.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_ldap.h	(revision 331)
@@ -0,0 +1,35 @@
+#ifndef HEADER_CURL_LDAP_H
+#define HEADER_CURL_LDAP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifndef CURL_DISABLE_LDAP
+extern const struct Curl_handler Curl_handler_ldap;
+
+#if !defined(CURL_DISABLE_LDAPS) && \
+    ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
+     (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
+extern const struct Curl_handler Curl_handler_ldaps;
+#endif
+
+#endif
+#endif /* HEADER_CURL_LDAP_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_md4.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_md4.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_md4.h	(revision 331)
@@ -0,0 +1,35 @@
+#ifndef HEADER_CURL_MD4_H
+#define HEADER_CURL_MD4_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_NSS) || defined(USE_OS400CRYPTO) || \
+    (defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C))
+
+void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len);
+
+#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) ||
+    (defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C)) */
+
+#endif /* HEADER_CURL_MD4_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_md5.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_md5.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_md5.h	(revision 331)
@@ -0,0 +1,63 @@
+#ifndef HEADER_CURL_MD5_H
+#define HEADER_CURL_MD5_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+#include "curl_hmac.h"
+
+#define MD5_DIGEST_LEN  16
+
+typedef void (* Curl_MD5_init_func)(void *context);
+typedef void (* Curl_MD5_update_func)(void *context,
+                                      const unsigned char *data,
+                                      unsigned int len);
+typedef void (* Curl_MD5_final_func)(unsigned char *result, void *context);
+
+typedef struct {
+  Curl_MD5_init_func     md5_init_func;   /* Initialize context procedure */
+  Curl_MD5_update_func   md5_update_func; /* Update context with data */
+  Curl_MD5_final_func    md5_final_func;  /* Get final result procedure */
+  unsigned int           md5_ctxtsize;  /* Context structure size */
+  unsigned int           md5_resultlen; /* Result length (bytes) */
+} MD5_params;
+
+typedef struct {
+  const MD5_params      *md5_hash;      /* Hash function definition */
+  void                  *md5_hashctx;   /* Hash function context */
+} MD5_context;
+
+extern const MD5_params Curl_DIGEST_MD5[1];
+extern const HMAC_params Curl_HMAC_MD5[1];
+
+void Curl_md5it(unsigned char *output,
+                const unsigned char *input);
+
+MD5_context * Curl_MD5_init(const MD5_params *md5params);
+int Curl_MD5_update(MD5_context *context,
+                    const unsigned char *data,
+                    unsigned int len);
+int Curl_MD5_final(MD5_context *context, unsigned char *result);
+
+#endif
+
+#endif /* HEADER_CURL_MD5_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_memory.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_memory.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_memory.h	(revision 331)
@@ -0,0 +1,156 @@
+#ifndef HEADER_CURL_MEMORY_H
+#define HEADER_CURL_MEMORY_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Nasty internal details ahead...
+ *
+ * File curl_memory.h must be included by _all_ *.c source files
+ * that use memory related functions strdup, malloc, calloc, realloc
+ * or free, and given source file is used to build libcurl library.
+ * It should be included immediately before memdebug.h as the last files
+ * included to avoid undesired interaction with other memory function
+ * headers in dependent libraries.
+ *
+ * There is nearly no exception to above rule. All libcurl source
+ * files in 'lib' subdirectory as well as those living deep inside
+ * 'packages' subdirectories and linked together in order to build
+ * libcurl library shall follow it.
+ *
+ * File lib/strdup.c is an exception, given that it provides a strdup
+ * clone implementation while using malloc. Extra care needed inside
+ * this one. TODO: revisit this paragraph and related code.
+ *
+ * The need for curl_memory.h inclusion is due to libcurl's feature
+ * of allowing library user to provide memory replacement functions,
+ * memory callbacks, at runtime with curl_global_init_mem()
+ *
+ * Any *.c source file used to build libcurl library that does not
+ * include curl_memory.h and uses any memory function of the five
+ * mentioned above will compile without any indication, but it will
+ * trigger weird memory related issues at runtime.
+ *
+ * OTOH some source files from 'lib' subdirectory may additionally be
+ * used directly as source code when using some curlx_ functions by
+ * third party programs that don't even use libcurl at all. When using
+ * these source files in this way it is necessary these are compiled
+ * with CURLX_NO_MEMORY_CALLBACKS defined, in order to ensure that no
+ * attempt of calling libcurl's memory callbacks is done from code
+ * which can not use this machinery.
+ *
+ * Notice that libcurl's 'memory tracking' system works chaining into
+ * the memory callback machinery. This implies that when compiling
+ * 'lib' source files with CURLX_NO_MEMORY_CALLBACKS defined this file
+ * disengages usage of libcurl's 'memory tracking' system, defining
+ * MEMDEBUG_NODEFINES and overriding CURLDEBUG purpose.
+ *
+ * CURLX_NO_MEMORY_CALLBACKS takes precedence over CURLDEBUG. This is
+ * done in order to allow building a 'memory tracking' enabled libcurl
+ * and at the same time allow building programs which do not use it.
+ *
+ * Programs and libraries in 'tests' subdirectories have specific
+ * purposes and needs, and as such each one will use whatever fits
+ * best, depending additionally whether it links with libcurl or not.
+ *
+ * Caveat emptor. Proper curlx_* separation is a work in progress
+ * the same as CURLX_NO_MEMORY_CALLBACKS usage, some adjustments may
+ * still be required. IOW don't use them yet, there are sharp edges.
+ */
+
+#ifdef HEADER_CURL_MEMDEBUG_H
+#error "Header memdebug.h shall not be included before curl_memory.h"
+#endif
+
+#ifndef CURLX_NO_MEMORY_CALLBACKS
+
+#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS /* only if not already done */
+/*
+ * The following memory function replacement typedef's are COPIED from
+ * curl/curl.h and MUST match the originals. We copy them to avoid having to
+ * include curl/curl.h here. We avoid that include since it includes stdio.h
+ * and other headers that may get messed up with defines done here.
+ */
+typedef void *(*curl_malloc_callback)(size_t size);
+typedef void (*curl_free_callback)(void *ptr);
+typedef void *(*curl_realloc_callback)(void *ptr, size_t size);
+typedef char *(*curl_strdup_callback)(const char *str);
+typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size);
+#define CURL_DID_MEMORY_FUNC_TYPEDEFS
+#endif
+
+extern curl_malloc_callback Curl_cmalloc;
+extern curl_free_callback Curl_cfree;
+extern curl_realloc_callback Curl_crealloc;
+extern curl_strdup_callback Curl_cstrdup;
+extern curl_calloc_callback Curl_ccalloc;
+#if defined(WIN32) && defined(UNICODE)
+extern curl_wcsdup_callback Curl_cwcsdup;
+#endif
+
+#ifndef CURLDEBUG
+
+/*
+ * libcurl's 'memory tracking' system defines strdup, malloc, calloc,
+ * realloc and free, along with others, in memdebug.h in a different
+ * way although still using memory callbacks forward declared above.
+ * When using the 'memory tracking' system (CURLDEBUG defined) we do
+ * not define here the five memory functions given that definitions
+ * from memdebug.h are the ones that shall be used.
+ */
+
+#undef strdup
+#define strdup(ptr) Curl_cstrdup(ptr)
+#undef malloc
+#define malloc(size) Curl_cmalloc(size)
+#undef calloc
+#define calloc(nbelem,size) Curl_ccalloc(nbelem, size)
+#undef realloc
+#define realloc(ptr,size) Curl_crealloc(ptr, size)
+#undef free
+#define free(ptr) Curl_cfree(ptr)
+
+#ifdef WIN32
+#  ifdef UNICODE
+#    undef wcsdup
+#    define wcsdup(ptr) Curl_cwcsdup(ptr)
+#    undef _wcsdup
+#    define _wcsdup(ptr) Curl_cwcsdup(ptr)
+#    undef _tcsdup
+#    define _tcsdup(ptr) Curl_cwcsdup(ptr)
+#  else
+#    undef _tcsdup
+#    define _tcsdup(ptr) Curl_cstrdup(ptr)
+#  endif
+#endif
+
+#endif /* CURLDEBUG */
+
+#else /* CURLX_NO_MEMORY_CALLBACKS */
+
+#ifndef MEMDEBUG_NODEFINES
+#define MEMDEBUG_NODEFINES
+#endif
+
+#endif /* CURLX_NO_MEMORY_CALLBACKS */
+
+#endif /* HEADER_CURL_MEMORY_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_memrchr.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_memrchr.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_memrchr.c	(revision 331)
@@ -0,0 +1,61 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "curl_memrchr.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifndef HAVE_MEMRCHR
+
+/*
+ * Curl_memrchr()
+ *
+ * Our memrchr() function clone for systems which lack this function. The
+ * memrchr() function is like the memchr() function, except that it searches
+ * backwards from the end of the n bytes pointed to by s instead of forward
+ * from the beginning.
+ */
+
+void *
+Curl_memrchr(const void *s, int c, size_t n)
+{
+  const unsigned char *p = s;
+  const unsigned char *q = s;
+
+  p += n - 1;
+
+  while(p >= q) {
+    if(*p == (unsigned char)c)
+      return (void *)p;
+    p--;
+  }
+
+  return NULL;
+}
+
+#endif /* HAVE_MEMRCHR */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_memrchr.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_memrchr.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_memrchr.h	(revision 331)
@@ -0,0 +1,44 @@
+#ifndef HEADER_CURL_MEMRCHR_H
+#define HEADER_CURL_MEMRCHR_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_MEMRCHR
+
+#ifdef HAVE_STRING_H
+#  include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+#  include <strings.h>
+#endif
+
+#else /* HAVE_MEMRCHR */
+
+void *Curl_memrchr(const void *s, int c, size_t n);
+
+#define memrchr(x,y,z) Curl_memrchr((x),(y),(z))
+
+#endif /* HAVE_MEMRCHR */
+
+#endif /* HEADER_CURL_MEMRCHR_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_multibyte.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_multibyte.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_multibyte.c	(revision 331)
@@ -0,0 +1,84 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \
+                                defined(USE_WIN32_LDAP)) && defined(UNICODE))
+
+ /*
+  * MultiByte conversions using Windows kernel32 library.
+  */
+
+#include "curl_multibyte.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8)
+{
+  wchar_t *str_w = NULL;
+
+  if(str_utf8) {
+    int str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
+                                        str_utf8, -1, NULL, 0);
+    if(str_w_len > 0) {
+      str_w = malloc(str_w_len * sizeof(wchar_t));
+      if(str_w) {
+        if(MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w,
+                               str_w_len) == 0) {
+          free(str_w);
+          return NULL;
+        }
+      }
+    }
+  }
+
+  return str_w;
+}
+
+char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w)
+{
+  char *str_utf8 = NULL;
+
+  if(str_w) {
+    int str_utf8_len = WideCharToMultiByte(CP_UTF8, 0, str_w, -1, NULL,
+                                           0, NULL, NULL);
+    if(str_utf8_len > 0) {
+      str_utf8 = malloc(str_utf8_len * sizeof(wchar_t));
+      if(str_utf8) {
+        if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, str_utf8_len,
+                               NULL, FALSE) == 0) {
+          free(str_utf8);
+          return NULL;
+        }
+      }
+    }
+  }
+
+  return str_utf8;
+}
+
+#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_multibyte.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_multibyte.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_multibyte.h	(revision 331)
@@ -0,0 +1,92 @@
+#ifndef HEADER_CURL_MULTIBYTE_H
+#define HEADER_CURL_MULTIBYTE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \
+                                defined(USE_WIN32_LDAP)) && defined(UNICODE))
+
+ /*
+  * MultiByte conversions using Windows kernel32 library.
+  */
+
+wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8);
+char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w);
+
+#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */
+
+
+#if defined(USE_WIN32_IDN) || defined(USE_WINDOWS_SSPI) || \
+    defined(USE_WIN32_LDAP)
+
+/*
+ * Macros Curl_convert_UTF8_to_tchar(), Curl_convert_tchar_to_UTF8()
+ * and Curl_unicodefree() main purpose is to minimize the number of
+ * preprocessor conditional directives needed by code using these
+ * to differentiate UNICODE from non-UNICODE builds.
+ *
+ * When building with UNICODE defined, this two macros
+ * Curl_convert_UTF8_to_tchar() and Curl_convert_tchar_to_UTF8()
+ * return a pointer to a newly allocated memory area holding result.
+ * When the result is no longer needed, allocated memory is intended
+ * to be free'ed with Curl_unicodefree().
+ *
+ * When building without UNICODE defined, this macros
+ * Curl_convert_UTF8_to_tchar() and Curl_convert_tchar_to_UTF8()
+ * return the pointer received as argument. Curl_unicodefree() does
+ * no actual free'ing of this pointer it is simply set to NULL.
+ */
+
+#ifdef UNICODE
+
+#define Curl_convert_UTF8_to_tchar(ptr) Curl_convert_UTF8_to_wchar((ptr))
+#define Curl_convert_tchar_to_UTF8(ptr) Curl_convert_wchar_to_UTF8((ptr))
+#define Curl_unicodefree(ptr) \
+  do {if((ptr)) {free((ptr)); (ptr) = NULL;}} WHILE_FALSE
+
+typedef union {
+  unsigned short       *tchar_ptr;
+  const unsigned short *const_tchar_ptr;
+  unsigned short       *tbyte_ptr;
+  const unsigned short *const_tbyte_ptr;
+} xcharp_u;
+
+#else
+
+#define Curl_convert_UTF8_to_tchar(ptr) (ptr)
+#define Curl_convert_tchar_to_UTF8(ptr) (ptr)
+#define Curl_unicodefree(ptr) \
+  do {(ptr) = NULL;} WHILE_FALSE
+
+typedef union {
+  char                *tchar_ptr;
+  const char          *const_tchar_ptr;
+  unsigned char       *tbyte_ptr;
+  const unsigned char *const_tbyte_ptr;
+} xcharp_u;
+
+#endif /* UNICODE */
+
+#endif /* USE_WIN32_IDN || USE_WINDOWS_SSPI || USE_WIN32_LDAP */
+
+#endif /* HEADER_CURL_MULTIBYTE_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_ntlm_core.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_ntlm_core.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_ntlm_core.c	(revision 331)
@@ -0,0 +1,837 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_NTLM)
+
+/*
+ * NTLM details:
+ *
+ * https://davenport.sourceforge.io/ntlm.html
+ * https://www.innovation.ch/java/ntlm.html
+ */
+
+/* Please keep the SSL backend-specific #if branches in this order:
+
+   1. USE_OPENSSL
+   2. USE_GNUTLS_NETTLE
+   3. USE_GNUTLS
+   4. USE_NSS
+   5. USE_MBEDTLS
+   6. USE_DARWINSSL
+   7. USE_OS400CRYPTO
+   8. USE_WIN32_CRYPTO
+
+   This ensures that:
+   - the same SSL branch gets activated throughout this source
+     file even if multiple backends are enabled at the same time.
+   - OpenSSL and NSS have higher priority than Windows Crypt, due
+     to issues with the latter supporting NTLM2Session responses
+     in NTLM type-3 messages.
+ */
+
+#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
+
+#ifdef USE_OPENSSL
+
+#  ifdef USE_OPENSSL
+#    include <openssl/des.h>
+#    ifndef OPENSSL_NO_MD4
+#      include <openssl/md4.h>
+#    endif
+#    include <openssl/md5.h>
+#    include <openssl/ssl.h>
+#    include <openssl/rand.h>
+#  else
+#    include <des.h>
+#    ifndef OPENSSL_NO_MD4
+#      include <md4.h>
+#    endif
+#    include <md5.h>
+#    include <ssl.h>
+#    include <rand.h>
+#  endif
+#  if (OPENSSL_VERSION_NUMBER < 0x00907001L)
+#    define DES_key_schedule des_key_schedule
+#    define DES_cblock des_cblock
+#    define DES_set_odd_parity des_set_odd_parity
+#    define DES_set_key des_set_key
+#    define DES_ecb_encrypt des_ecb_encrypt
+#    define DESKEY(x) x
+#    define DESKEYARG(x) x
+#  else
+#    define DESKEYARG(x) *x
+#    define DESKEY(x) &x
+#  endif
+
+#elif defined(USE_GNUTLS_NETTLE)
+
+#  include <nettle/des.h>
+#  include <nettle/md4.h>
+
+#elif defined(USE_GNUTLS)
+
+#  include <gcrypt.h>
+#  define MD5_DIGEST_LENGTH 16
+#  define MD4_DIGEST_LENGTH 16
+
+#elif defined(USE_NSS)
+
+#  include <nss.h>
+#  include <pk11pub.h>
+#  include <hasht.h>
+#  include "curl_md4.h"
+#  define MD5_DIGEST_LENGTH MD5_LENGTH
+
+#elif defined(USE_MBEDTLS)
+
+#  include <mbedtls/des.h>
+#  include <mbedtls/md4.h>
+#  if !defined(MBEDTLS_MD4_C)
+#    include "curl_md4.h"
+#  endif
+
+#elif defined(USE_DARWINSSL)
+
+#  include <CommonCrypto/CommonCryptor.h>
+#  include <CommonCrypto/CommonDigest.h>
+
+#elif defined(USE_OS400CRYPTO)
+#  include "cipher.mih"  /* mih/cipher */
+#  include "curl_md4.h"
+#elif defined(USE_WIN32_CRYPTO)
+#  include <wincrypt.h>
+#else
+#  error "Can't compile NTLM support without a crypto library."
+#endif
+
+#include "urldata.h"
+#include "non-ascii.h"
+#include "strcase.h"
+#include "curl_ntlm_core.h"
+#include "curl_md5.h"
+#include "curl_hmac.h"
+#include "warnless.h"
+#include "curl_endian.h"
+#include "curl_des.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define NTLM_HMAC_MD5_LEN     (16)
+#define NTLMv2_BLOB_SIGNATURE "\x01\x01\x00\x00"
+#define NTLMv2_BLOB_LEN       (44 -16 + ntlm->target_info_len + 4)
+
+/*
+* Turns a 56-bit key into being 64-bit wide.
+*/
+static void extend_key_56_to_64(const unsigned char *key_56, char *key)
+{
+  key[0] = key_56[0];
+  key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1));
+  key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2));
+  key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3));
+  key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4));
+  key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5));
+  key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6));
+  key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
+}
+
+#ifdef USE_OPENSSL
+/*
+ * Turns a 56 bit key into the 64 bit, odd parity key and sets the key.  The
+ * key schedule ks is also set.
+ */
+static void setup_des_key(const unsigned char *key_56,
+                          DES_key_schedule DESKEYARG(ks))
+{
+  DES_cblock key;
+
+  /* Expand the 56-bit key to 64-bits */
+  extend_key_56_to_64(key_56, (char *) &key);
+
+  /* Set the key parity to odd */
+  DES_set_odd_parity(&key);
+
+  /* Set the key */
+  DES_set_key(&key, ks);
+}
+
+#elif defined(USE_GNUTLS_NETTLE)
+
+static void setup_des_key(const unsigned char *key_56,
+                          struct des_ctx *des)
+{
+  char key[8];
+
+  /* Expand the 56-bit key to 64-bits */
+  extend_key_56_to_64(key_56, key);
+
+  /* Set the key parity to odd */
+  Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
+
+  /* Set the key */
+  des_set_key(des, (const uint8_t *) key);
+}
+
+#elif defined(USE_GNUTLS)
+
+/*
+ * Turns a 56 bit key into the 64 bit, odd parity key and sets the key.
+ */
+static void setup_des_key(const unsigned char *key_56,
+                          gcry_cipher_hd_t *des)
+{
+  char key[8];
+
+  /* Expand the 56-bit key to 64-bits */
+  extend_key_56_to_64(key_56, key);
+
+  /* Set the key parity to odd */
+  Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
+
+  /* Set the key */
+  gcry_cipher_setkey(*des, key, sizeof(key));
+}
+
+#elif defined(USE_NSS)
+
+/*
+ * Expands a 56 bit key KEY_56 to 64 bit and encrypts 64 bit of data, using
+ * the expanded key.  The caller is responsible for giving 64 bit of valid
+ * data is IN and (at least) 64 bit large buffer as OUT.
+ */
+static bool encrypt_des(const unsigned char *in, unsigned char *out,
+                        const unsigned char *key_56)
+{
+  const CK_MECHANISM_TYPE mech = CKM_DES_ECB; /* DES cipher in ECB mode */
+  PK11SlotInfo *slot = NULL;
+  char key[8];                                /* expanded 64 bit key */
+  SECItem key_item;
+  PK11SymKey *symkey = NULL;
+  SECItem *param = NULL;
+  PK11Context *ctx = NULL;
+  int out_len;                                /* not used, required by NSS */
+  bool rv = FALSE;
+
+  /* use internal slot for DES encryption (requires NSS to be initialized) */
+  slot = PK11_GetInternalKeySlot();
+  if(!slot)
+    return FALSE;
+
+  /* Expand the 56-bit key to 64-bits */
+  extend_key_56_to_64(key_56, key);
+
+  /* Set the key parity to odd */
+  Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
+
+  /* Import the key */
+  key_item.data = (unsigned char *)key;
+  key_item.len = sizeof(key);
+  symkey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap, CKA_ENCRYPT,
+                             &key_item, NULL);
+  if(!symkey)
+    goto fail;
+
+  /* Create the DES encryption context */
+  param = PK11_ParamFromIV(mech, /* no IV in ECB mode */ NULL);
+  if(!param)
+    goto fail;
+  ctx = PK11_CreateContextBySymKey(mech, CKA_ENCRYPT, symkey, param);
+  if(!ctx)
+    goto fail;
+
+  /* Perform the encryption */
+  if(SECSuccess == PK11_CipherOp(ctx, out, &out_len, /* outbuflen */ 8,
+                                 (unsigned char *)in, /* inbuflen */ 8)
+      && SECSuccess == PK11_Finalize(ctx))
+    rv = /* all OK */ TRUE;
+
+fail:
+  /* cleanup */
+  if(ctx)
+    PK11_DestroyContext(ctx, PR_TRUE);
+  if(symkey)
+    PK11_FreeSymKey(symkey);
+  if(param)
+    SECITEM_FreeItem(param, PR_TRUE);
+  PK11_FreeSlot(slot);
+  return rv;
+}
+
+#elif defined(USE_MBEDTLS)
+
+static bool encrypt_des(const unsigned char *in, unsigned char *out,
+                        const unsigned char *key_56)
+{
+  mbedtls_des_context ctx;
+  char key[8];
+
+  /* Expand the 56-bit key to 64-bits */
+  extend_key_56_to_64(key_56, key);
+
+  /* Set the key parity to odd */
+  mbedtls_des_key_set_parity((unsigned char *) key);
+
+  /* Perform the encryption */
+  mbedtls_des_init(&ctx);
+  mbedtls_des_setkey_enc(&ctx, (unsigned char *) key);
+  return mbedtls_des_crypt_ecb(&ctx, in, out) == 0;
+}
+
+#elif defined(USE_DARWINSSL)
+
+static bool encrypt_des(const unsigned char *in, unsigned char *out,
+                        const unsigned char *key_56)
+{
+  char key[8];
+  size_t out_len;
+  CCCryptorStatus err;
+
+  /* Expand the 56-bit key to 64-bits */
+  extend_key_56_to_64(key_56, key);
+
+  /* Set the key parity to odd */
+  Curl_des_set_odd_parity((unsigned char *) key, sizeof(key));
+
+  /* Perform the encryption */
+  err = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionECBMode, key,
+                kCCKeySizeDES, NULL, in, 8 /* inbuflen */, out,
+                8 /* outbuflen */, &out_len);
+
+  return err == kCCSuccess;
+}
+
+#elif defined(USE_OS400CRYPTO)
+
+static bool encrypt_des(const unsigned char *in, unsigned char *out,
+                        const unsigned char *key_56)
+{
+  char key[8];
+  _CIPHER_Control_T ctl;
+
+  /* Setup the cipher control structure */
+  ctl.Func_ID = ENCRYPT_ONLY;
+  ctl.Data_Len = sizeof(key);
+
+  /* Expand the 56-bit key to 64-bits */
+  extend_key_56_to_64(key_56, ctl.Crypto_Key);
+
+  /* Set the key parity to odd */
+  Curl_des_set_odd_parity((unsigned char *) ctl.Crypto_Key, ctl.Data_Len);
+
+  /* Perform the encryption */
+  _CIPHER((_SPCPTR *) &out, &ctl, (_SPCPTR *) &in);
+
+  return TRUE;
+}
+
+#elif defined(USE_WIN32_CRYPTO)
+
+static bool encrypt_des(const unsigned char *in, unsigned char *out,
+                        const unsigned char *key_56)
+{
+  HCRYPTPROV hprov;
+  HCRYPTKEY hkey;
+  struct {
+    BLOBHEADER hdr;
+    unsigned int len;
+    char key[8];
+  } blob;
+  DWORD len = 8;
+
+  /* Acquire the crypto provider */
+  if(!CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
+                          CRYPT_VERIFYCONTEXT))
+    return FALSE;
+
+  /* Setup the key blob structure */
+  memset(&blob, 0, sizeof(blob));
+  blob.hdr.bType = PLAINTEXTKEYBLOB;
+  blob.hdr.bVersion = 2;
+  blob.hdr.aiKeyAlg = CALG_DES;
+  blob.len = sizeof(blob.key);
+
+  /* Expand the 56-bit key to 64-bits */
+  extend_key_56_to_64(key_56, blob.key);
+
+  /* Set the key parity to odd */
+  Curl_des_set_odd_parity((unsigned char *) blob.key, sizeof(blob.key));
+
+  /* Import the key */
+  if(!CryptImportKey(hprov, (BYTE *) &blob, sizeof(blob), 0, 0, &hkey)) {
+    CryptReleaseContext(hprov, 0);
+
+    return FALSE;
+  }
+
+  memcpy(out, in, 8);
+
+  /* Perform the encryption */
+  CryptEncrypt(hkey, 0, FALSE, 0, out, &len, len);
+
+  CryptDestroyKey(hkey);
+  CryptReleaseContext(hprov, 0);
+
+  return TRUE;
+}
+
+#endif /* defined(USE_WIN32_CRYPTO) */
+
+ /*
+  * takes a 21 byte array and treats it as 3 56-bit DES keys. The
+  * 8 byte plaintext is encrypted with each key and the resulting 24
+  * bytes are stored in the results array.
+  */
+void Curl_ntlm_core_lm_resp(const unsigned char *keys,
+                            const unsigned char *plaintext,
+                            unsigned char *results)
+{
+#ifdef USE_OPENSSL
+  DES_key_schedule ks;
+
+  setup_des_key(keys, DESKEY(ks));
+  DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results,
+                  DESKEY(ks), DES_ENCRYPT);
+
+  setup_des_key(keys + 7, DESKEY(ks));
+  DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 8),
+                  DESKEY(ks), DES_ENCRYPT);
+
+  setup_des_key(keys + 14, DESKEY(ks));
+  DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 16),
+                  DESKEY(ks), DES_ENCRYPT);
+#elif defined(USE_GNUTLS_NETTLE)
+  struct des_ctx des;
+  setup_des_key(keys, &des);
+  des_encrypt(&des, 8, results, plaintext);
+  setup_des_key(keys + 7, &des);
+  des_encrypt(&des, 8, results + 8, plaintext);
+  setup_des_key(keys + 14, &des);
+  des_encrypt(&des, 8, results + 16, plaintext);
+#elif defined(USE_GNUTLS)
+  gcry_cipher_hd_t des;
+
+  gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
+  setup_des_key(keys, &des);
+  gcry_cipher_encrypt(des, results, 8, plaintext, 8);
+  gcry_cipher_close(des);
+
+  gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
+  setup_des_key(keys + 7, &des);
+  gcry_cipher_encrypt(des, results + 8, 8, plaintext, 8);
+  gcry_cipher_close(des);
+
+  gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
+  setup_des_key(keys + 14, &des);
+  gcry_cipher_encrypt(des, results + 16, 8, plaintext, 8);
+  gcry_cipher_close(des);
+#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_DARWINSSL) \
+  || defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
+  encrypt_des(plaintext, results, keys);
+  encrypt_des(plaintext, results + 8, keys + 7);
+  encrypt_des(plaintext, results + 16, keys + 14);
+#endif
+}
+
+/*
+ * Set up lanmanager hashed password
+ */
+CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
+                                   const char *password,
+                                   unsigned char *lmbuffer /* 21 bytes */)
+{
+  CURLcode result;
+  unsigned char pw[14];
+  static const unsigned char magic[] = {
+    0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
+  };
+  size_t len = CURLMIN(strlen(password), 14);
+
+  Curl_strntoupper((char *)pw, password, len);
+  memset(&pw[len], 0, 14 - len);
+
+  /*
+   * The LanManager hashed password needs to be created using the
+   * password in the network encoding not the host encoding.
+   */
+  result = Curl_convert_to_network(data, (char *)pw, 14);
+  if(result)
+    return result;
+
+  {
+    /* Create LanManager hashed password. */
+
+#ifdef USE_OPENSSL
+    DES_key_schedule ks;
+
+    setup_des_key(pw, DESKEY(ks));
+    DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
+                    DESKEY(ks), DES_ENCRYPT);
+
+    setup_des_key(pw + 7, DESKEY(ks));
+    DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer + 8),
+                    DESKEY(ks), DES_ENCRYPT);
+#elif defined(USE_GNUTLS_NETTLE)
+    struct des_ctx des;
+    setup_des_key(pw, &des);
+    des_encrypt(&des, 8, lmbuffer, magic);
+    setup_des_key(pw + 7, &des);
+    des_encrypt(&des, 8, lmbuffer + 8, magic);
+#elif defined(USE_GNUTLS)
+    gcry_cipher_hd_t des;
+
+    gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
+    setup_des_key(pw, &des);
+    gcry_cipher_encrypt(des, lmbuffer, 8, magic, 8);
+    gcry_cipher_close(des);
+
+    gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
+    setup_des_key(pw + 7, &des);
+    gcry_cipher_encrypt(des, lmbuffer + 8, 8, magic, 8);
+    gcry_cipher_close(des);
+#elif defined(USE_NSS) || defined(USE_MBEDTLS) || defined(USE_DARWINSSL) \
+  || defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO)
+    encrypt_des(magic, lmbuffer, pw);
+    encrypt_des(magic, lmbuffer + 8, pw + 7);
+#endif
+
+    memset(lmbuffer + 16, 0, 21 - 16);
+  }
+
+  return CURLE_OK;
+}
+
+#ifdef USE_NTRESPONSES
+static void ascii_to_unicode_le(unsigned char *dest, const char *src,
+                                size_t srclen)
+{
+  size_t i;
+  for(i = 0; i < srclen; i++) {
+    dest[2 * i] = (unsigned char)src[i];
+    dest[2 * i + 1] = '\0';
+  }
+}
+
+#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
+
+static void ascii_uppercase_to_unicode_le(unsigned char *dest,
+                                          const char *src, size_t srclen)
+{
+  size_t i;
+  for(i = 0; i < srclen; i++) {
+    dest[2 * i] = (unsigned char)(Curl_raw_toupper(src[i]));
+    dest[2 * i + 1] = '\0';
+  }
+}
+
+#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
+
+/*
+ * Set up nt hashed passwords
+ * @unittest: 1600
+ */
+CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
+                                   const char *password,
+                                   unsigned char *ntbuffer /* 21 bytes */)
+{
+  size_t len = strlen(password);
+  unsigned char *pw = len ? malloc(len * 2) : strdup("");
+  CURLcode result;
+  if(!pw)
+    return CURLE_OUT_OF_MEMORY;
+
+  ascii_to_unicode_le(pw, password, len);
+
+  /*
+   * The NT hashed password needs to be created using the password in the
+   * network encoding not the host encoding.
+   */
+  result = Curl_convert_to_network(data, (char *)pw, len * 2);
+  if(result)
+    return result;
+
+  {
+    /* Create NT hashed password. */
+#ifdef USE_OPENSSL
+    MD4_CTX MD4pw;
+    MD4_Init(&MD4pw);
+    MD4_Update(&MD4pw, pw, 2 * len);
+    MD4_Final(ntbuffer, &MD4pw);
+#elif defined(USE_GNUTLS_NETTLE)
+    struct md4_ctx MD4pw;
+    md4_init(&MD4pw);
+    md4_update(&MD4pw, (unsigned int)(2 * len), pw);
+    md4_digest(&MD4pw, MD4_DIGEST_SIZE, ntbuffer);
+#elif defined(USE_GNUTLS)
+    gcry_md_hd_t MD4pw;
+    gcry_md_open(&MD4pw, GCRY_MD_MD4, 0);
+    gcry_md_write(MD4pw, pw, 2 * len);
+    memcpy(ntbuffer, gcry_md_read(MD4pw, 0), MD4_DIGEST_LENGTH);
+    gcry_md_close(MD4pw);
+#elif defined(USE_NSS)
+    Curl_md4it(ntbuffer, pw, 2 * len);
+#elif defined(USE_MBEDTLS)
+#if defined(MBEDTLS_MD4_C)
+    mbedtls_md4(pw, 2 * len, ntbuffer);
+#else
+    Curl_md4it(ntbuffer, pw, 2 * len);
+#endif
+#elif defined(USE_DARWINSSL)
+    (void)CC_MD4(pw, (CC_LONG)(2 * len), ntbuffer);
+#elif defined(USE_OS400CRYPTO)
+    Curl_md4it(ntbuffer, pw, 2 * len);
+#elif defined(USE_WIN32_CRYPTO)
+    HCRYPTPROV hprov;
+    if(CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL,
+                           CRYPT_VERIFYCONTEXT)) {
+      HCRYPTHASH hhash;
+      if(CryptCreateHash(hprov, CALG_MD4, 0, 0, &hhash)) {
+        DWORD length = 16;
+        CryptHashData(hhash, pw, (unsigned int)len * 2, 0);
+        CryptGetHashParam(hhash, HP_HASHVAL, ntbuffer, &length, 0);
+        CryptDestroyHash(hhash);
+      }
+      CryptReleaseContext(hprov, 0);
+    }
+#endif
+
+    memset(ntbuffer + 16, 0, 21 - 16);
+  }
+
+  free(pw);
+
+  return CURLE_OK;
+}
+
+#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
+
+/* This returns the HMAC MD5 digest */
+CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
+                       const unsigned char *data, unsigned int datalen,
+                       unsigned char *output)
+{
+  HMAC_context *ctxt = Curl_HMAC_init(Curl_HMAC_MD5, key, keylen);
+
+  if(!ctxt)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Update the digest with the given challenge */
+  Curl_HMAC_update(ctxt, data, datalen);
+
+  /* Finalise the digest */
+  Curl_HMAC_final(ctxt, output);
+
+  return CURLE_OK;
+}
+
+#ifndef SIZE_T_MAX
+/* some limits.h headers have this defined, some don't */
+#if defined(SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > 4)
+#define SIZE_T_MAX 18446744073709551615U
+#else
+#define SIZE_T_MAX 4294967295U
+#endif
+#endif
+
+/* This creates the NTLMv2 hash by using NTLM hash as the key and Unicode
+ * (uppercase UserName + Domain) as the data
+ */
+CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
+                                       const char *domain, size_t domlen,
+                                       unsigned char *ntlmhash,
+                                       unsigned char *ntlmv2hash)
+{
+  /* Unicode representation */
+  size_t identity_len;
+  unsigned char *identity;
+  CURLcode result = CURLE_OK;
+
+  /* we do the length checks below separately to avoid integer overflow risk
+     on extreme data lengths */
+  if((userlen > SIZE_T_MAX/2) ||
+     (domlen > SIZE_T_MAX/2) ||
+     ((userlen + domlen) > SIZE_T_MAX/2))
+    return CURLE_OUT_OF_MEMORY;
+
+  identity_len = (userlen + domlen) * 2;
+  identity = malloc(identity_len);
+
+  if(!identity)
+    return CURLE_OUT_OF_MEMORY;
+
+  ascii_uppercase_to_unicode_le(identity, user, userlen);
+  ascii_to_unicode_le(identity + (userlen << 1), domain, domlen);
+
+  result = Curl_hmac_md5(ntlmhash, 16, identity, curlx_uztoui(identity_len),
+                         ntlmv2hash);
+
+  free(identity);
+
+  return result;
+}
+
+/*
+ * Curl_ntlm_core_mk_ntlmv2_resp()
+ *
+ * This creates the NTLMv2 response as set in the ntlm type-3 message.
+ *
+ * Parameters:
+ *
+ * ntlmv2hash       [in] - The ntlmv2 hash (16 bytes)
+ * challenge_client [in] - The client nonce (8 bytes)
+ * ntlm             [in] - The ntlm data struct being used to read TargetInfo
+                           and Server challenge received in the type-2 message
+ * ntresp          [out] - The address where a pointer to newly allocated
+ *                         memory holding the NTLMv2 response.
+ * ntresp_len      [out] - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
+                                       unsigned char *challenge_client,
+                                       struct ntlmdata *ntlm,
+                                       unsigned char **ntresp,
+                                       unsigned int *ntresp_len)
+{
+/* NTLMv2 response structure :
+------------------------------------------------------------------------------
+0     HMAC MD5         16 bytes
+------BLOB--------------------------------------------------------------------
+16    Signature        0x01010000
+20    Reserved         long (0x00000000)
+24    Timestamp        LE, 64-bit signed value representing the number of
+                       tenths of a microsecond since January 1, 1601.
+32    Client Nonce     8 bytes
+40    Unknown          4 bytes
+44    Target Info      N bytes (from the type-2 message)
+44+N  Unknown          4 bytes
+------------------------------------------------------------------------------
+*/
+
+  unsigned int len = 0;
+  unsigned char *ptr = NULL;
+  unsigned char hmac_output[NTLM_HMAC_MD5_LEN];
+  curl_off_t tw;
+
+  CURLcode result = CURLE_OK;
+
+#if CURL_SIZEOF_CURL_OFF_T < 8
+#error "this section needs 64bit support to work"
+#endif
+
+  /* Calculate the timestamp */
+#ifdef DEBUGBUILD
+  char *force_timestamp = getenv("CURL_FORCETIME");
+  if(force_timestamp)
+    tw = CURL_OFF_T_C(11644473600) * 10000000;
+  else
+#endif
+    tw = ((curl_off_t)time(NULL) + CURL_OFF_T_C(11644473600)) * 10000000;
+
+  /* Calculate the response len */
+  len = NTLM_HMAC_MD5_LEN + NTLMv2_BLOB_LEN;
+
+  /* Allocate the response */
+  ptr = malloc(len);
+  if(!ptr)
+    return CURLE_OUT_OF_MEMORY;
+
+  memset(ptr, 0, len);
+
+  /* Create the BLOB structure */
+  snprintf((char *)ptr + NTLM_HMAC_MD5_LEN, NTLMv2_BLOB_LEN,
+           "%c%c%c%c"   /* NTLMv2_BLOB_SIGNATURE */
+           "%c%c%c%c",  /* Reserved = 0 */
+           NTLMv2_BLOB_SIGNATURE[0], NTLMv2_BLOB_SIGNATURE[1],
+           NTLMv2_BLOB_SIGNATURE[2], NTLMv2_BLOB_SIGNATURE[3],
+           0, 0, 0, 0);
+
+  Curl_write64_le(tw, ptr + 24);
+  memcpy(ptr + 32, challenge_client, 8);
+  memcpy(ptr + 44, ntlm->target_info, ntlm->target_info_len);
+
+  /* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */
+  memcpy(ptr + 8, &ntlm->nonce[0], 8);
+  result = Curl_hmac_md5(ntlmv2hash, NTLM_HMAC_MD5_LEN, ptr + 8,
+                         NTLMv2_BLOB_LEN + 8, hmac_output);
+  if(result) {
+    free(ptr);
+    return result;
+  }
+
+  /* Concatenate the HMAC MD5 output  with the BLOB */
+  memcpy(ptr, hmac_output, NTLM_HMAC_MD5_LEN);
+
+  /* Return the response */
+  *ntresp = ptr;
+  *ntresp_len = len;
+
+  return result;
+}
+
+/*
+ * Curl_ntlm_core_mk_lmv2_resp()
+ *
+ * This creates the LMv2 response as used in the ntlm type-3 message.
+ *
+ * Parameters:
+ *
+ * ntlmv2hash        [in] - The ntlmv2 hash (16 bytes)
+ * challenge_client  [in] - The client nonce (8 bytes)
+ * challenge_client  [in] - The server challenge (8 bytes)
+ * lmresp           [out] - The LMv2 response (24 bytes)
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode  Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
+                                      unsigned char *challenge_client,
+                                      unsigned char *challenge_server,
+                                      unsigned char *lmresp)
+{
+  unsigned char data[16];
+  unsigned char hmac_output[16];
+  CURLcode result = CURLE_OK;
+
+  memcpy(&data[0], challenge_server, 8);
+  memcpy(&data[8], challenge_client, 8);
+
+  result = Curl_hmac_md5(ntlmv2hash, 16, &data[0], 16, hmac_output);
+  if(result)
+    return result;
+
+  /* Concatenate the HMAC MD5 output  with the client nonce */
+  memcpy(lmresp, hmac_output, 16);
+  memcpy(lmresp + 16, challenge_client, 8);
+
+  return result;
+}
+
+#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
+
+#endif /* USE_NTRESPONSES */
+
+#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
+
+#endif /* USE_NTLM */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_ntlm_core.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_ntlm_core.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_ntlm_core.h	(revision 331)
@@ -0,0 +1,107 @@
+#ifndef HEADER_CURL_NTLM_CORE_H
+#define HEADER_CURL_NTLM_CORE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_NTLM)
+
+/* If NSS is the first available SSL backend (see order in curl_ntlm_core.c)
+   then it must be initialized to be used by NTLM. */
+#if !defined(USE_OPENSSL) && \
+    !defined(USE_GNUTLS_NETTLE) && \
+    !defined(USE_GNUTLS) && \
+    defined(USE_NSS)
+#define NTLM_NEEDS_NSS_INIT
+#endif
+
+#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
+
+#ifdef USE_OPENSSL
+#  include <openssl/ssl.h>
+#endif
+
+/* Define USE_NTRESPONSES in order to make the type-3 message include
+ * the NT response message. */
+#if !defined(USE_OPENSSL) || !defined(OPENSSL_NO_MD4)
+#define USE_NTRESPONSES
+#endif
+
+/* Define USE_NTLM2SESSION in order to make the type-3 message include the
+   NTLM2Session response message, requires USE_NTRESPONSES defined to 1 and a
+   Crypto engine that we have curl_ssl_md5sum() for. */
+#if defined(USE_NTRESPONSES) && !defined(USE_WIN32_CRYPTO)
+#define USE_NTLM2SESSION
+#endif
+
+/* Define USE_NTLM_V2 in order to allow the type-3 message to include the
+   LMv2 and NTLMv2 response messages, requires USE_NTRESPONSES defined to 1
+   and support for 64-bit integers. */
+#if defined(USE_NTRESPONSES) && (CURL_SIZEOF_CURL_OFF_T > 4)
+#define USE_NTLM_V2
+#endif
+
+void Curl_ntlm_core_lm_resp(const unsigned char *keys,
+                            const unsigned char *plaintext,
+                            unsigned char *results);
+
+CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
+                                   const char *password,
+                                   unsigned char *lmbuffer /* 21 bytes */);
+
+#ifdef USE_NTRESPONSES
+CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
+                                   const char *password,
+                                   unsigned char *ntbuffer /* 21 bytes */);
+
+#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
+
+CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
+                       const unsigned char *data, unsigned int datalen,
+                       unsigned char *output);
+
+CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
+                                       const char *domain, size_t domlen,
+                                       unsigned char *ntlmhash,
+                                       unsigned char *ntlmv2hash);
+
+CURLcode  Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
+                                        unsigned char *challenge_client,
+                                        struct ntlmdata *ntlm,
+                                        unsigned char **ntresp,
+                                        unsigned int *ntresp_len);
+
+CURLcode  Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash,
+                                      unsigned char *challenge_client,
+                                      unsigned char *challenge_server,
+                                      unsigned char *lmresp);
+
+#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */
+
+#endif /* USE_NTRESPONSES */
+
+#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
+
+#endif /* USE_NTLM */
+
+#endif /* HEADER_CURL_NTLM_CORE_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_ntlm_wb.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_ntlm_wb.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_ntlm_wb.c	(revision 331)
@@ -0,0 +1,425 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
+    defined(NTLM_WB_ENABLED)
+
+/*
+ * NTLM details:
+ *
+ * https://davenport.sourceforge.io/ntlm.html
+ * https://www.innovation.ch/java/ntlm.html
+ */
+
+#define DEBUG_ME 0
+
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "select.h"
+#include "vauth/ntlm.h"
+#include "curl_ntlm_core.h"
+#include "curl_ntlm_wb.h"
+#include "url.h"
+#include "strerror.h"
+#include "strdup.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#if DEBUG_ME
+# define DEBUG_OUT(x) x
+#else
+# define DEBUG_OUT(x) Curl_nop_stmt
+#endif
+
+/* Portable 'sclose_nolog' used only in child process instead of 'sclose'
+   to avoid fooling the socket leak detector */
+#if defined(HAVE_CLOSESOCKET)
+#  define sclose_nolog(x)  closesocket((x))
+#elif defined(HAVE_CLOSESOCKET_CAMEL)
+#  define sclose_nolog(x)  CloseSocket((x))
+#else
+#  define sclose_nolog(x)  close((x))
+#endif
+
+void Curl_ntlm_wb_cleanup(struct connectdata *conn)
+{
+  if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD) {
+    sclose(conn->ntlm_auth_hlpr_socket);
+    conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
+  }
+
+  if(conn->ntlm_auth_hlpr_pid) {
+    int i;
+    for(i = 0; i < 4; i++) {
+      pid_t ret = waitpid(conn->ntlm_auth_hlpr_pid, NULL, WNOHANG);
+      if(ret == conn->ntlm_auth_hlpr_pid || errno == ECHILD)
+        break;
+      switch(i) {
+      case 0:
+        kill(conn->ntlm_auth_hlpr_pid, SIGTERM);
+        break;
+      case 1:
+        /* Give the process another moment to shut down cleanly before
+           bringing down the axe */
+        Curl_wait_ms(1);
+        break;
+      case 2:
+        kill(conn->ntlm_auth_hlpr_pid, SIGKILL);
+        break;
+      case 3:
+        break;
+      }
+    }
+    conn->ntlm_auth_hlpr_pid = 0;
+  }
+
+  free(conn->challenge_header);
+  conn->challenge_header = NULL;
+  free(conn->response_header);
+  conn->response_header = NULL;
+}
+
+static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
+{
+  curl_socket_t sockfds[2];
+  pid_t child_pid;
+  const char *username;
+  char *slash, *domain = NULL;
+  const char *ntlm_auth = NULL;
+  char *ntlm_auth_alloc = NULL;
+#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
+  struct passwd pw, *pw_res;
+  char pwbuf[1024];
+#endif
+
+  /* Return if communication with ntlm_auth already set up */
+  if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD ||
+     conn->ntlm_auth_hlpr_pid)
+    return CURLE_OK;
+
+  username = userp;
+  /* The real ntlm_auth really doesn't like being invoked with an
+     empty username. It won't make inferences for itself, and expects
+     the client to do so (mostly because it's really designed for
+     servers like squid to use for auth, and client support is an
+     afterthought for it). So try hard to provide a suitable username
+     if we don't already have one. But if we can't, provide the
+     empty one anyway. Perhaps they have an implementation of the
+     ntlm_auth helper which *doesn't* need it so we might as well try */
+  if(!username || !username[0]) {
+    username = getenv("NTLMUSER");
+    if(!username || !username[0])
+      username = getenv("LOGNAME");
+    if(!username || !username[0])
+      username = getenv("USER");
+#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
+    if((!username || !username[0]) &&
+       !getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) &&
+       pw_res) {
+      username = pw.pw_name;
+    }
+#endif
+    if(!username || !username[0])
+      username = userp;
+  }
+  slash = strpbrk(username, "\\/");
+  if(slash) {
+    domain = strdup(username);
+    if(!domain)
+      return CURLE_OUT_OF_MEMORY;
+    slash = domain + (slash - username);
+    *slash = '\0';
+    username = username + (slash - domain) + 1;
+  }
+
+  /* For testing purposes, when DEBUGBUILD is defined and environment
+     variable CURL_NTLM_WB_FILE is set a fake_ntlm is used to perform
+     NTLM challenge/response which only accepts commands and output
+     strings pre-written in test case definitions */
+#ifdef DEBUGBUILD
+  ntlm_auth_alloc = curl_getenv("CURL_NTLM_WB_FILE");
+  if(ntlm_auth_alloc)
+    ntlm_auth = ntlm_auth_alloc;
+  else
+#endif
+    ntlm_auth = NTLM_WB_FILE;
+
+  if(access(ntlm_auth, X_OK) != 0) {
+    failf(conn->data, "Could not access ntlm_auth: %s errno %d: %s",
+          ntlm_auth, errno, Curl_strerror(conn, errno));
+    goto done;
+  }
+
+  if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) {
+    failf(conn->data, "Could not open socket pair. errno %d: %s",
+          errno, Curl_strerror(conn, errno));
+    goto done;
+  }
+
+  child_pid = fork();
+  if(child_pid == -1) {
+    sclose(sockfds[0]);
+    sclose(sockfds[1]);
+    failf(conn->data, "Could not fork. errno %d: %s",
+          errno, Curl_strerror(conn, errno));
+    goto done;
+  }
+  else if(!child_pid) {
+    /*
+     * child process
+     */
+
+    /* Don't use sclose in the child since it fools the socket leak detector */
+    sclose_nolog(sockfds[0]);
+    if(dup2(sockfds[1], STDIN_FILENO) == -1) {
+      failf(conn->data, "Could not redirect child stdin. errno %d: %s",
+            errno, Curl_strerror(conn, errno));
+      exit(1);
+    }
+
+    if(dup2(sockfds[1], STDOUT_FILENO) == -1) {
+      failf(conn->data, "Could not redirect child stdout. errno %d: %s",
+            errno, Curl_strerror(conn, errno));
+      exit(1);
+    }
+
+    if(domain)
+      execl(ntlm_auth, ntlm_auth,
+            "--helper-protocol", "ntlmssp-client-1",
+            "--use-cached-creds",
+            "--username", username,
+            "--domain", domain,
+            NULL);
+    else
+      execl(ntlm_auth, ntlm_auth,
+            "--helper-protocol", "ntlmssp-client-1",
+            "--use-cached-creds",
+            "--username", username,
+            NULL);
+
+    sclose_nolog(sockfds[1]);
+    failf(conn->data, "Could not execl(). errno %d: %s",
+          errno, Curl_strerror(conn, errno));
+    exit(1);
+  }
+
+  sclose(sockfds[1]);
+  conn->ntlm_auth_hlpr_socket = sockfds[0];
+  conn->ntlm_auth_hlpr_pid = child_pid;
+  free(domain);
+  free(ntlm_auth_alloc);
+  return CURLE_OK;
+
+done:
+  free(domain);
+  free(ntlm_auth_alloc);
+  return CURLE_REMOTE_ACCESS_DENIED;
+}
+
+static CURLcode ntlm_wb_response(struct connectdata *conn,
+                                 const char *input, curlntlm state)
+{
+  char *buf = malloc(NTLM_BUFSIZE);
+  size_t len_in = strlen(input), len_out = 0;
+
+  if(!buf)
+    return CURLE_OUT_OF_MEMORY;
+
+  while(len_in > 0) {
+    ssize_t written = swrite(conn->ntlm_auth_hlpr_socket, input, len_in);
+    if(written == -1) {
+      /* Interrupted by a signal, retry it */
+      if(errno == EINTR)
+        continue;
+      /* write failed if other errors happen */
+      goto done;
+    }
+    input += written;
+    len_in -= written;
+  }
+  /* Read one line */
+  while(1) {
+    ssize_t size;
+    char *newbuf;
+
+    size = sread(conn->ntlm_auth_hlpr_socket, buf + len_out, NTLM_BUFSIZE);
+    if(size == -1) {
+      if(errno == EINTR)
+        continue;
+      goto done;
+    }
+    else if(size == 0)
+      goto done;
+
+    len_out += size;
+    if(buf[len_out - 1] == '\n') {
+      buf[len_out - 1] = '\0';
+      break;
+    }
+    newbuf = Curl_saferealloc(buf, len_out + NTLM_BUFSIZE);
+    if(!newbuf)
+      return CURLE_OUT_OF_MEMORY;
+
+    buf = newbuf;
+  }
+
+  /* Samba/winbind installed but not configured */
+  if(state == NTLMSTATE_TYPE1 &&
+     len_out == 3 &&
+     buf[0] == 'P' && buf[1] == 'W')
+    goto done;
+  /* invalid response */
+  if(len_out < 4)
+    goto done;
+  if(state == NTLMSTATE_TYPE1 &&
+     (buf[0]!='Y' || buf[1]!='R' || buf[2]!=' '))
+    goto done;
+  if(state == NTLMSTATE_TYPE2 &&
+     (buf[0]!='K' || buf[1]!='K' || buf[2]!=' ') &&
+     (buf[0]!='A' || buf[1]!='F' || buf[2]!=' '))
+    goto done;
+
+  conn->response_header = aprintf("NTLM %.*s", len_out - 4, buf + 3);
+  free(buf);
+  return CURLE_OK;
+done:
+  free(buf);
+  return CURLE_REMOTE_ACCESS_DENIED;
+}
+
+/*
+ * This is for creating ntlm header output by delegating challenge/response
+ * to Samba's winbind daemon helper ntlm_auth.
+ */
+CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
+                              bool proxy)
+{
+  /* point to the address of the pointer that holds the string to send to the
+     server, which is for a plain host or for a HTTP proxy */
+  char **allocuserpwd;
+  /* point to the name and password for this */
+  const char *userp;
+  /* point to the correct struct with this */
+  struct ntlmdata *ntlm;
+  struct auth *authp;
+
+  CURLcode res = CURLE_OK;
+  char *input;
+
+  DEBUGASSERT(conn);
+  DEBUGASSERT(conn->data);
+
+  if(proxy) {
+    allocuserpwd = &conn->allocptr.proxyuserpwd;
+    userp = conn->http_proxy.user;
+    ntlm = &conn->proxyntlm;
+    authp = &conn->data->state.authproxy;
+  }
+  else {
+    allocuserpwd = &conn->allocptr.userpwd;
+    userp = conn->user;
+    ntlm = &conn->ntlm;
+    authp = &conn->data->state.authhost;
+  }
+  authp->done = FALSE;
+
+  /* not set means empty */
+  if(!userp)
+    userp = "";
+
+  switch(ntlm->state) {
+  case NTLMSTATE_TYPE1:
+  default:
+    /* Use Samba's 'winbind' daemon to support NTLM authentication,
+     * by delegating the NTLM challenge/response protocal to a helper
+     * in ntlm_auth.
+     * http://devel.squid-cache.org/ntlm/squid_helper_protocol.html
+     * https://www.samba.org/samba/docs/man/manpages-3/winbindd.8.html
+     * https://www.samba.org/samba/docs/man/manpages-3/ntlm_auth.1.html
+     * Preprocessor symbol 'NTLM_WB_ENABLED' is defined when this
+     * feature is enabled and 'NTLM_WB_FILE' symbol holds absolute
+     * filename of ntlm_auth helper.
+     * If NTLM authentication using winbind fails, go back to original
+     * request handling process.
+     */
+    /* Create communication with ntlm_auth */
+    res = ntlm_wb_init(conn, userp);
+    if(res)
+      return res;
+    res = ntlm_wb_response(conn, "YR\n", ntlm->state);
+    if(res)
+      return res;
+
+    free(*allocuserpwd);
+    *allocuserpwd = aprintf("%sAuthorization: %s\r\n",
+                            proxy ? "Proxy-" : "",
+                            conn->response_header);
+    DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
+    free(conn->response_header);
+    conn->response_header = NULL;
+    break;
+  case NTLMSTATE_TYPE2:
+    input = aprintf("TT %s\n", conn->challenge_header);
+    if(!input)
+      return CURLE_OUT_OF_MEMORY;
+    res = ntlm_wb_response(conn, input, ntlm->state);
+    free(input);
+    input = NULL;
+    if(res)
+      return res;
+
+    free(*allocuserpwd);
+    *allocuserpwd = aprintf("%sAuthorization: %s\r\n",
+                            proxy ? "Proxy-" : "",
+                            conn->response_header);
+    DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
+    ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
+    authp->done = TRUE;
+    Curl_ntlm_wb_cleanup(conn);
+    break;
+  case NTLMSTATE_TYPE3:
+    /* connection is already authenticated,
+     * don't send a header in future requests */
+    free(*allocuserpwd);
+    *allocuserpwd = NULL;
+    authp->done = TRUE;
+    break;
+  }
+
+  return CURLE_OK;
+}
+
+#endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_ntlm_wb.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_ntlm_wb.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_ntlm_wb.h	(revision 331)
@@ -0,0 +1,38 @@
+#ifndef HEADER_CURL_NTLM_WB_H
+#define HEADER_CURL_NTLM_WB_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
+    defined(NTLM_WB_ENABLED)
+
+/* this is for creating ntlm header output by delegating challenge/response
+   to Samba's winbind daemon helper ntlm_auth */
+CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy);
+
+void Curl_ntlm_wb_cleanup(struct connectdata *conn);
+
+#endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */
+
+#endif /* HEADER_CURL_NTLM_WB_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_printf.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_printf.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_printf.h	(revision 331)
@@ -0,0 +1,56 @@
+#ifndef HEADER_CURL_PRINTF_H
+#define HEADER_CURL_PRINTF_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * This header should be included by ALL code in libcurl that uses any
+ * *rintf() functions.
+ */
+
+#include <curl/mprintf.h>
+
+# undef printf
+# undef fprintf
+# undef snprintf
+# undef vprintf
+# undef vfprintf
+# undef vsnprintf
+# undef aprintf
+# undef vaprintf
+# define printf curl_mprintf
+# define fprintf curl_mfprintf
+# define snprintf curl_msnprintf
+# define vprintf curl_mvprintf
+# define vfprintf curl_mvfprintf
+# define vsnprintf curl_mvsnprintf
+# define aprintf curl_maprintf
+# define vaprintf curl_mvaprintf
+
+/* We define away the sprintf functions unconditonally since we don't want
+   internal code to be using them, intentionally or by mistake!*/
+# undef sprintf
+# undef vsprintf
+# define sprintf sprintf_was_used
+# define vsprintf vsprintf_was_used
+
+#endif /* HEADER_CURL_PRINTF_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_rtmp.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_rtmp.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_rtmp.c	(revision 331)
@@ -0,0 +1,313 @@
+/***************************************************************************
+ *                      _   _ ____  _
+ *  Project         ___| | | |  _ \| |
+ *                 / __| | | | |_) | |
+ *                | (__| |_| |  _ <| |___
+ *                 \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_LIBRTMP
+
+#include "curl_rtmp.h"
+#include "urldata.h"
+#include "nonblock.h" /* for curlx_nonblock */
+#include "progress.h" /* for Curl_pgrsSetUploadSize */
+#include "transfer.h"
+#include "warnless.h"
+#include <curl/curl.h>
+#include <librtmp/rtmp.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifdef _WIN32
+#define setsockopt(a,b,c,d,e) (setsockopt)(a,b,c,(const char *)d,(int)e)
+#define SET_RCVTIMEO(tv,s)   int tv = s*1000
+#else
+#define SET_RCVTIMEO(tv,s)   struct timeval tv = {s,0}
+#endif
+
+#define DEF_BUFTIME    (2*60*60*1000)    /* 2 hours */
+
+static CURLcode rtmp_setup_connection(struct connectdata *conn);
+static CURLcode rtmp_do(struct connectdata *conn, bool *done);
+static CURLcode rtmp_done(struct connectdata *conn, CURLcode, bool premature);
+static CURLcode rtmp_connect(struct connectdata *conn, bool *done);
+static CURLcode rtmp_disconnect(struct connectdata *conn, bool dead);
+
+static Curl_recv rtmp_recv;
+static Curl_send rtmp_send;
+
+/*
+ * RTMP protocol handler.h, based on https://rtmpdump.mplayerhq.hu
+ */
+
+const struct Curl_handler Curl_handler_rtmp = {
+  "RTMP",                               /* scheme */
+  rtmp_setup_connection,                /* setup_connection */
+  rtmp_do,                              /* do_it */
+  rtmp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  rtmp_connect,                         /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  rtmp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_RTMP,                            /* defport */
+  CURLPROTO_RTMP,                       /* protocol */
+  PROTOPT_NONE                          /* flags*/
+};
+
+const struct Curl_handler Curl_handler_rtmpt = {
+  "RTMPT",                              /* scheme */
+  rtmp_setup_connection,                /* setup_connection */
+  rtmp_do,                              /* do_it */
+  rtmp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  rtmp_connect,                         /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  rtmp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_RTMPT,                           /* defport */
+  CURLPROTO_RTMPT,                      /* protocol */
+  PROTOPT_NONE                          /* flags*/
+};
+
+const struct Curl_handler Curl_handler_rtmpe = {
+  "RTMPE",                              /* scheme */
+  rtmp_setup_connection,                /* setup_connection */
+  rtmp_do,                              /* do_it */
+  rtmp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  rtmp_connect,                         /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  rtmp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_RTMP,                            /* defport */
+  CURLPROTO_RTMPE,                      /* protocol */
+  PROTOPT_NONE                          /* flags*/
+};
+
+const struct Curl_handler Curl_handler_rtmpte = {
+  "RTMPTE",                             /* scheme */
+  rtmp_setup_connection,                /* setup_connection */
+  rtmp_do,                              /* do_it */
+  rtmp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  rtmp_connect,                         /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  rtmp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_RTMPT,                           /* defport */
+  CURLPROTO_RTMPTE,                     /* protocol */
+  PROTOPT_NONE                          /* flags*/
+};
+
+const struct Curl_handler Curl_handler_rtmps = {
+  "RTMPS",                              /* scheme */
+  rtmp_setup_connection,                /* setup_connection */
+  rtmp_do,                              /* do_it */
+  rtmp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  rtmp_connect,                         /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  rtmp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_RTMPS,                           /* defport */
+  CURLPROTO_RTMPS,                      /* protocol */
+  PROTOPT_NONE                          /* flags*/
+};
+
+const struct Curl_handler Curl_handler_rtmpts = {
+  "RTMPTS",                             /* scheme */
+  rtmp_setup_connection,                /* setup_connection */
+  rtmp_do,                              /* do_it */
+  rtmp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  rtmp_connect,                         /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  rtmp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_RTMPS,                           /* defport */
+  CURLPROTO_RTMPTS,                     /* protocol */
+  PROTOPT_NONE                          /* flags*/
+};
+
+static CURLcode rtmp_setup_connection(struct connectdata *conn)
+{
+  RTMP *r = RTMP_Alloc();
+  if(!r)
+    return CURLE_OUT_OF_MEMORY;
+
+  RTMP_Init(r);
+  RTMP_SetBufferMS(r, DEF_BUFTIME);
+  if(!RTMP_SetupURL(r, conn->data->change.url)) {
+    RTMP_Free(r);
+    return CURLE_URL_MALFORMAT;
+  }
+  conn->proto.generic = r;
+  return CURLE_OK;
+}
+
+static CURLcode rtmp_connect(struct connectdata *conn, bool *done)
+{
+  RTMP *r = conn->proto.generic;
+  SET_RCVTIMEO(tv, 10);
+
+  r->m_sb.sb_socket = (int)conn->sock[FIRSTSOCKET];
+
+  /* We have to know if it's a write before we send the
+   * connect request packet
+   */
+  if(conn->data->set.upload)
+    r->Link.protocol |= RTMP_FEATURE_WRITE;
+
+  /* For plain streams, use the buffer toggle trick to keep data flowing */
+  if(!(r->Link.lFlags & RTMP_LF_LIVE) &&
+     !(r->Link.protocol & RTMP_FEATURE_HTTP))
+    r->Link.lFlags |= RTMP_LF_BUFX;
+
+  (void)curlx_nonblock(r->m_sb.sb_socket, FALSE);
+  setsockopt(r->m_sb.sb_socket, SOL_SOCKET, SO_RCVTIMEO,
+             (char *)&tv, sizeof(tv));
+
+  if(!RTMP_Connect1(r, NULL))
+    return CURLE_FAILED_INIT;
+
+  /* Clients must send a periodic BytesReceived report to the server */
+  r->m_bSendCounter = true;
+
+  *done = TRUE;
+  conn->recv[FIRSTSOCKET] = rtmp_recv;
+  conn->send[FIRSTSOCKET] = rtmp_send;
+  return CURLE_OK;
+}
+
+static CURLcode rtmp_do(struct connectdata *conn, bool *done)
+{
+  RTMP *r = conn->proto.generic;
+
+  if(!RTMP_ConnectStream(r, 0))
+    return CURLE_FAILED_INIT;
+
+  if(conn->data->set.upload) {
+    Curl_pgrsSetUploadSize(conn->data, conn->data->state.infilesize);
+    Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
+  }
+  else
+    Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL);
+  *done = TRUE;
+  return CURLE_OK;
+}
+
+static CURLcode rtmp_done(struct connectdata *conn, CURLcode status,
+                          bool premature)
+{
+  (void)conn; /* unused */
+  (void)status; /* unused */
+  (void)premature; /* unused */
+
+  return CURLE_OK;
+}
+
+static CURLcode rtmp_disconnect(struct connectdata *conn,
+                                bool dead_connection)
+{
+  RTMP *r = conn->proto.generic;
+  (void)dead_connection;
+  if(r) {
+    conn->proto.generic = NULL;
+    RTMP_Close(r);
+    RTMP_Free(r);
+  }
+  return CURLE_OK;
+}
+
+static ssize_t rtmp_recv(struct connectdata *conn, int sockindex, char *buf,
+                         size_t len, CURLcode *err)
+{
+  RTMP *r = conn->proto.generic;
+  ssize_t nread;
+
+  (void)sockindex; /* unused */
+
+  nread = RTMP_Read(r, buf, curlx_uztosi(len));
+  if(nread < 0) {
+    if(r->m_read.status == RTMP_READ_COMPLETE ||
+        r->m_read.status == RTMP_READ_EOF) {
+      conn->data->req.size = conn->data->req.bytecount;
+      nread = 0;
+    }
+    else
+      *err = CURLE_RECV_ERROR;
+  }
+  return nread;
+}
+
+static ssize_t rtmp_send(struct connectdata *conn, int sockindex,
+                         const void *buf, size_t len, CURLcode *err)
+{
+  RTMP *r = conn->proto.generic;
+  ssize_t num;
+
+  (void)sockindex; /* unused */
+
+  num = RTMP_Write(r, (char *)buf, curlx_uztosi(len));
+  if(num < 0)
+    *err = CURLE_SEND_ERROR;
+
+  return num;
+}
+#endif  /* USE_LIBRTMP */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_rtmp.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_rtmp.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_rtmp.h	(revision 331)
@@ -0,0 +1,33 @@
+#ifndef HEADER_CURL_RTMP_H
+#define HEADER_CURL_RTMP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010, Howard Chu, <hyc@highlandsun.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifdef USE_LIBRTMP
+extern const struct Curl_handler Curl_handler_rtmp;
+extern const struct Curl_handler Curl_handler_rtmpt;
+extern const struct Curl_handler Curl_handler_rtmpe;
+extern const struct Curl_handler Curl_handler_rtmpte;
+extern const struct Curl_handler Curl_handler_rtmps;
+extern const struct Curl_handler Curl_handler_rtmpts;
+#endif
+
+#endif /* HEADER_CURL_RTMP_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_sasl.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_sasl.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_sasl.c	(revision 331)
@@ -0,0 +1,628 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC2195 CRAM-MD5 authentication
+ * RFC2617 Basic and Digest Access Authentication
+ * RFC2831 DIGEST-MD5 authentication
+ * RFC4422 Simple Authentication and Security Layer (SASL)
+ * RFC4616 PLAIN authentication
+ * RFC6749 OAuth 2.0 Authorization Framework
+ * RFC7628 A Set of SASL Mechanisms for OAuth
+ * Draft   LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+#include "urldata.h"
+
+#include "curl_base64.h"
+#include "curl_md5.h"
+#include "vauth/vauth.h"
+#include "vtls/vtls.h"
+#include "curl_hmac.h"
+#include "curl_sasl.h"
+#include "warnless.h"
+#include "strtok.h"
+#include "sendf.h"
+#include "non-ascii.h" /* included for Curl_convert_... prototypes */
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Supported mechanisms */
+static const struct {
+  const char   *name;  /* Name */
+  size_t        len;   /* Name length */
+  unsigned int  bit;   /* Flag bit */
+} mechtable[] = {
+  { "LOGIN",        5,  SASL_MECH_LOGIN },
+  { "PLAIN",        5,  SASL_MECH_PLAIN },
+  { "CRAM-MD5",     8,  SASL_MECH_CRAM_MD5 },
+  { "DIGEST-MD5",   10, SASL_MECH_DIGEST_MD5 },
+  { "GSSAPI",       6,  SASL_MECH_GSSAPI },
+  { "EXTERNAL",     8,  SASL_MECH_EXTERNAL },
+  { "NTLM",         4,  SASL_MECH_NTLM },
+  { "XOAUTH2",      7,  SASL_MECH_XOAUTH2 },
+  { "OAUTHBEARER",  11, SASL_MECH_OAUTHBEARER },
+  { ZERO_NULL,      0,  0 }
+};
+
+/*
+ * Curl_sasl_cleanup()
+ *
+ * This is used to cleanup any libraries or curl modules used by the sasl
+ * functions.
+ *
+ * Parameters:
+ *
+ * conn     [in]     - The connection data.
+ * authused [in]     - The authentication mechanism used.
+ */
+void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused)
+{
+#if defined(USE_KERBEROS5)
+  /* Cleanup the gssapi structure */
+  if(authused == SASL_MECH_GSSAPI) {
+    Curl_auth_gssapi_cleanup(&conn->krb5);
+  }
+#endif
+
+#if defined(USE_NTLM)
+  /* Cleanup the NTLM structure */
+  if(authused == SASL_MECH_NTLM) {
+    Curl_auth_ntlm_cleanup(&conn->ntlm);
+  }
+#endif
+
+#if !defined(USE_KERBEROS5) && !defined(USE_NTLM)
+  /* Reserved for future use */
+  (void)conn;
+  (void)authused;
+#endif
+}
+
+/*
+ * Curl_sasl_decode_mech()
+ *
+ * Convert a SASL mechanism name into a token.
+ *
+ * Parameters:
+ *
+ * ptr    [in]     - The mechanism string.
+ * maxlen [in]     - Maximum mechanism string length.
+ * len    [out]    - If not NULL, effective name length.
+ *
+ * Returns the SASL mechanism token or 0 if no match.
+ */
+unsigned int Curl_sasl_decode_mech(const char *ptr, size_t maxlen, size_t *len)
+{
+  unsigned int i;
+  char c;
+
+  for(i = 0; mechtable[i].name; i++) {
+    if(maxlen >= mechtable[i].len &&
+       !memcmp(ptr, mechtable[i].name, mechtable[i].len)) {
+      if(len)
+        *len = mechtable[i].len;
+
+      if(maxlen == mechtable[i].len)
+        return mechtable[i].bit;
+
+      c = ptr[mechtable[i].len];
+      if(!ISUPPER(c) && !ISDIGIT(c) && c != '-' && c != '_')
+        return mechtable[i].bit;
+    }
+  }
+
+  return 0;
+}
+
+/*
+ * Curl_sasl_parse_url_auth_option()
+ *
+ * Parse the URL login options.
+ */
+CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
+                                         const char *value, size_t len)
+{
+  CURLcode result = CURLE_OK;
+  unsigned int mechbit;
+  size_t mechlen;
+
+  if(!len)
+    return CURLE_URL_MALFORMAT;
+
+  if(sasl->resetprefs) {
+    sasl->resetprefs = FALSE;
+    sasl->prefmech = SASL_AUTH_NONE;
+  }
+
+  if(!strncmp(value, "*", len))
+    sasl->prefmech = SASL_AUTH_DEFAULT;
+  else {
+    mechbit = Curl_sasl_decode_mech(value, len, &mechlen);
+    if(mechbit && mechlen == len)
+      sasl->prefmech |= mechbit;
+    else
+      result = CURLE_URL_MALFORMAT;
+  }
+
+  return result;
+}
+
+/*
+ * Curl_sasl_init()
+ *
+ * Initializes the SASL structure.
+ */
+void Curl_sasl_init(struct SASL *sasl, const struct SASLproto *params)
+{
+  sasl->params = params;           /* Set protocol dependent parameters */
+  sasl->state = SASL_STOP;         /* Not yet running */
+  sasl->authmechs = SASL_AUTH_NONE; /* No known authentication mechanism yet */
+  sasl->prefmech = SASL_AUTH_DEFAULT; /* Prefer all mechanisms */
+  sasl->authused = SASL_AUTH_NONE; /* No the authentication mechanism used */
+  sasl->resetprefs = TRUE;         /* Reset prefmech upon AUTH parsing. */
+  sasl->mutual_auth = FALSE;       /* No mutual authentication (GSSAPI only) */
+  sasl->force_ir = FALSE;          /* Respect external option */
+}
+
+/*
+ * state()
+ *
+ * This is the ONLY way to change SASL state!
+ */
+static void state(struct SASL *sasl, struct connectdata *conn,
+                  saslstate newstate)
+{
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* for debug purposes */
+  static const char * const names[]={
+    "STOP",
+    "PLAIN",
+    "LOGIN",
+    "LOGIN_PASSWD",
+    "EXTERNAL",
+    "CRAMMD5",
+    "DIGESTMD5",
+    "DIGESTMD5_RESP",
+    "NTLM",
+    "NTLM_TYPE2MSG",
+    "GSSAPI",
+    "GSSAPI_TOKEN",
+    "GSSAPI_NO_DATA",
+    "OAUTH2",
+    "OAUTH2_RESP",
+    "CANCEL",
+    "FINAL",
+    /* LAST */
+  };
+
+  if(sasl->state != newstate)
+    infof(conn->data, "SASL %p state change from %s to %s\n",
+          (void *)sasl, names[sasl->state], names[newstate]);
+#else
+  (void) conn;
+#endif
+
+  sasl->state = newstate;
+}
+
+/*
+ * Curl_sasl_can_authenticate()
+ *
+ * Check if we have enough auth data and capabilities to authenticate.
+ */
+bool Curl_sasl_can_authenticate(struct SASL *sasl, struct connectdata *conn)
+{
+  /* Have credentials been provided? */
+  if(conn->bits.user_passwd)
+    return TRUE;
+
+  /* EXTERNAL can authenticate without a user name and/or password */
+  if(sasl->authmechs & sasl->prefmech & SASL_MECH_EXTERNAL)
+    return TRUE;
+
+  return FALSE;
+}
+
+/*
+ * Curl_sasl_start()
+ *
+ * Calculate the required login details for SASL authentication.
+ */
+CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
+                         bool force_ir, saslprogress *progress)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  unsigned int enabledmechs;
+  const char *mech = NULL;
+  char *resp = NULL;
+  size_t len = 0;
+  saslstate state1 = SASL_STOP;
+  saslstate state2 = SASL_FINAL;
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+  const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
+#if defined(USE_KERBEROS5)
+  const char *service = data->set.str[STRING_SERVICE_NAME] ?
+    data->set.str[STRING_SERVICE_NAME] :
+    sasl->params->service;
+#endif
+
+  sasl->force_ir = force_ir;    /* Latch for future use */
+  sasl->authused = 0;           /* No mechanism used yet */
+  enabledmechs = sasl->authmechs & sasl->prefmech;
+  *progress = SASL_IDLE;
+
+  /* Calculate the supported authentication mechanism, by decreasing order of
+     security, as well as the initial response where appropriate */
+  if((enabledmechs & SASL_MECH_EXTERNAL) && !conn->passwd[0]) {
+    mech = SASL_MECH_STRING_EXTERNAL;
+    state1 = SASL_EXTERNAL;
+    sasl->authused = SASL_MECH_EXTERNAL;
+
+    if(force_ir || data->set.sasl_ir)
+      result = Curl_auth_create_external_message(data, conn->user, &resp,
+                                                 &len);
+  }
+  else if(conn->bits.user_passwd) {
+#if defined(USE_KERBEROS5)
+    if((enabledmechs & SASL_MECH_GSSAPI) && Curl_auth_is_gssapi_supported() &&
+       Curl_auth_user_contains_domain(conn->user)) {
+      sasl->mutual_auth = FALSE; /* TODO: Calculate mutual authentication */
+      mech = SASL_MECH_STRING_GSSAPI;
+      state1 = SASL_GSSAPI;
+      state2 = SASL_GSSAPI_TOKEN;
+      sasl->authused = SASL_MECH_GSSAPI;
+
+      if(force_ir || data->set.sasl_ir)
+        result = Curl_auth_create_gssapi_user_message(data, conn->user,
+                                                      conn->passwd,
+                                                      service,
+                                                      data->easy_conn->
+                                                            host.name,
+                                                      sasl->mutual_auth,
+                                                      NULL, &conn->krb5,
+                                                      &resp, &len);
+    }
+    else
+#endif
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+    if((enabledmechs & SASL_MECH_DIGEST_MD5) &&
+       Curl_auth_is_digest_supported()) {
+      mech = SASL_MECH_STRING_DIGEST_MD5;
+      state1 = SASL_DIGESTMD5;
+      sasl->authused = SASL_MECH_DIGEST_MD5;
+    }
+    else if(enabledmechs & SASL_MECH_CRAM_MD5) {
+      mech = SASL_MECH_STRING_CRAM_MD5;
+      state1 = SASL_CRAMMD5;
+      sasl->authused = SASL_MECH_CRAM_MD5;
+    }
+    else
+#endif
+#ifdef USE_NTLM
+    if((enabledmechs & SASL_MECH_NTLM) && Curl_auth_is_ntlm_supported()) {
+      mech = SASL_MECH_STRING_NTLM;
+      state1 = SASL_NTLM;
+      state2 = SASL_NTLM_TYPE2MSG;
+      sasl->authused = SASL_MECH_NTLM;
+
+      if(force_ir || data->set.sasl_ir)
+        result = Curl_auth_create_ntlm_type1_message(data,
+                                                     conn->user, conn->passwd,
+                                                     &conn->ntlm, &resp, &len);
+      }
+    else
+#endif
+    if((enabledmechs & SASL_MECH_OAUTHBEARER) && conn->oauth_bearer) {
+      mech = SASL_MECH_STRING_OAUTHBEARER;
+      state1 = SASL_OAUTH2;
+      state2 = SASL_OAUTH2_RESP;
+      sasl->authused = SASL_MECH_OAUTHBEARER;
+
+      if(force_ir || data->set.sasl_ir)
+        result = Curl_auth_create_oauth_bearer_message(data, conn->user,
+                                                       hostname,
+                                                       port,
+                                                       conn->oauth_bearer,
+                                                       &resp, &len);
+    }
+    else if((enabledmechs & SASL_MECH_XOAUTH2) && conn->oauth_bearer) {
+      mech = SASL_MECH_STRING_XOAUTH2;
+      state1 = SASL_OAUTH2;
+      sasl->authused = SASL_MECH_XOAUTH2;
+
+      if(force_ir || data->set.sasl_ir)
+        result = Curl_auth_create_oauth_bearer_message(data, conn->user,
+                                                       NULL, 0,
+                                                       conn->oauth_bearer,
+                                                       &resp, &len);
+    }
+    else if(enabledmechs & SASL_MECH_LOGIN) {
+      mech = SASL_MECH_STRING_LOGIN;
+      state1 = SASL_LOGIN;
+      state2 = SASL_LOGIN_PASSWD;
+      sasl->authused = SASL_MECH_LOGIN;
+
+      if(force_ir || data->set.sasl_ir)
+        result = Curl_auth_create_login_message(data, conn->user, &resp, &len);
+    }
+    else if(enabledmechs & SASL_MECH_PLAIN) {
+      mech = SASL_MECH_STRING_PLAIN;
+      state1 = SASL_PLAIN;
+      sasl->authused = SASL_MECH_PLAIN;
+
+      if(force_ir || data->set.sasl_ir)
+        result = Curl_auth_create_plain_message(data, conn->user, conn->passwd,
+                                                &resp, &len);
+    }
+  }
+
+  if(!result && mech) {
+    if(resp && sasl->params->maxirlen &&
+       strlen(mech) + len > sasl->params->maxirlen) {
+      free(resp);
+      resp = NULL;
+    }
+
+    result = sasl->params->sendauth(conn, mech, resp);
+    if(!result) {
+      *progress = SASL_INPROGRESS;
+      state(sasl, conn, resp ? state2 : state1);
+    }
+  }
+
+  free(resp);
+
+  return result;
+}
+
+/*
+ * Curl_sasl_continue()
+ *
+ * Continue the authentication.
+ */
+CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
+                            int code, saslprogress *progress)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  saslstate newstate = SASL_FINAL;
+  char *resp = NULL;
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+  const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+  char *chlg = NULL;
+  size_t chlglen = 0;
+#endif
+#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5)
+  const char *service = data->set.str[STRING_SERVICE_NAME] ?
+                        data->set.str[STRING_SERVICE_NAME] :
+                        sasl->params->service;
+#endif
+#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \
+    defined(USE_NTLM)
+  char *serverdata;
+#endif
+  size_t len = 0;
+
+  *progress = SASL_INPROGRESS;
+
+  if(sasl->state == SASL_FINAL) {
+    if(code != sasl->params->finalcode)
+      result = CURLE_LOGIN_DENIED;
+    *progress = SASL_DONE;
+    state(sasl, conn, SASL_STOP);
+    return result;
+  }
+
+  if(sasl->state != SASL_CANCEL && sasl->state != SASL_OAUTH2_RESP &&
+     code != sasl->params->contcode) {
+    *progress = SASL_DONE;
+    state(sasl, conn, SASL_STOP);
+    return CURLE_LOGIN_DENIED;
+  }
+
+  switch(sasl->state) {
+  case SASL_STOP:
+    *progress = SASL_DONE;
+    return result;
+  case SASL_PLAIN:
+    result = Curl_auth_create_plain_message(data, conn->user, conn->passwd,
+                                            &resp,
+                                            &len);
+    break;
+  case SASL_LOGIN:
+    result = Curl_auth_create_login_message(data, conn->user, &resp, &len);
+    newstate = SASL_LOGIN_PASSWD;
+    break;
+  case SASL_LOGIN_PASSWD:
+    result = Curl_auth_create_login_message(data, conn->passwd, &resp, &len);
+    break;
+  case SASL_EXTERNAL:
+    result = Curl_auth_create_external_message(data, conn->user, &resp, &len);
+    break;
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+  case SASL_CRAMMD5:
+    sasl->params->getmessage(data->state.buffer, &serverdata);
+    result = Curl_auth_decode_cram_md5_message(serverdata, &chlg, &chlglen);
+    if(!result)
+      result = Curl_auth_create_cram_md5_message(data, chlg, conn->user,
+                                                 conn->passwd, &resp, &len);
+    free(chlg);
+    break;
+  case SASL_DIGESTMD5:
+    sasl->params->getmessage(data->state.buffer, &serverdata);
+    result = Curl_auth_create_digest_md5_message(data, serverdata,
+                                                 conn->user, conn->passwd,
+                                                 service,
+                                                 &resp, &len);
+    newstate = SASL_DIGESTMD5_RESP;
+    break;
+  case SASL_DIGESTMD5_RESP:
+    resp = strdup("");
+    if(!resp)
+      result = CURLE_OUT_OF_MEMORY;
+    break;
+#endif
+
+#ifdef USE_NTLM
+  case SASL_NTLM:
+    /* Create the type-1 message */
+    result = Curl_auth_create_ntlm_type1_message(data,
+                                                 conn->user, conn->passwd,
+                                                 &conn->ntlm, &resp, &len);
+    newstate = SASL_NTLM_TYPE2MSG;
+    break;
+  case SASL_NTLM_TYPE2MSG:
+    /* Decode the type-2 message */
+    sasl->params->getmessage(data->state.buffer, &serverdata);
+    result = Curl_auth_decode_ntlm_type2_message(data, serverdata,
+                                                 &conn->ntlm);
+    if(!result)
+      result = Curl_auth_create_ntlm_type3_message(data, conn->user,
+                                                   conn->passwd, &conn->ntlm,
+                                                   &resp, &len);
+    break;
+#endif
+
+#if defined(USE_KERBEROS5)
+  case SASL_GSSAPI:
+    result = Curl_auth_create_gssapi_user_message(data, conn->user,
+                                                  conn->passwd,
+                                                  service,
+                                                  data->easy_conn->host.name,
+                                                  sasl->mutual_auth, NULL,
+                                                  &conn->krb5,
+                                                  &resp, &len);
+    newstate = SASL_GSSAPI_TOKEN;
+    break;
+  case SASL_GSSAPI_TOKEN:
+    sasl->params->getmessage(data->state.buffer, &serverdata);
+    if(sasl->mutual_auth) {
+      /* Decode the user token challenge and create the optional response
+         message */
+      result = Curl_auth_create_gssapi_user_message(data, NULL, NULL,
+                                                    NULL, NULL,
+                                                    sasl->mutual_auth,
+                                                    serverdata, &conn->krb5,
+                                                    &resp, &len);
+      newstate = SASL_GSSAPI_NO_DATA;
+    }
+    else
+      /* Decode the security challenge and create the response message */
+      result = Curl_auth_create_gssapi_security_message(data, serverdata,
+                                                        &conn->krb5,
+                                                        &resp, &len);
+    break;
+  case SASL_GSSAPI_NO_DATA:
+    sasl->params->getmessage(data->state.buffer, &serverdata);
+    /* Decode the security challenge and create the response message */
+    result = Curl_auth_create_gssapi_security_message(data, serverdata,
+                                                      &conn->krb5,
+                                                      &resp, &len);
+    break;
+#endif
+
+  case SASL_OAUTH2:
+    /* Create the authorisation message */
+    if(sasl->authused == SASL_MECH_OAUTHBEARER) {
+      result = Curl_auth_create_oauth_bearer_message(data, conn->user,
+                                                     hostname,
+                                                     port,
+                                                     conn->oauth_bearer,
+                                                     &resp, &len);
+
+      /* Failures maybe sent by the server as continuations for OAUTHBEARER */
+      newstate = SASL_OAUTH2_RESP;
+    }
+    else
+      result = Curl_auth_create_oauth_bearer_message(data, conn->user,
+                                                     NULL, 0,
+                                                     conn->oauth_bearer,
+                                                     &resp, &len);
+    break;
+
+  case SASL_OAUTH2_RESP:
+    /* The continuation is optional so check the response code */
+    if(code == sasl->params->finalcode) {
+      /* Final response was received so we are done */
+      *progress = SASL_DONE;
+      state(sasl, conn, SASL_STOP);
+      return result;
+    }
+    else if(code == sasl->params->contcode) {
+      /* Acknowledge the continuation by sending a 0x01 response base64
+         encoded */
+      resp = strdup("AQ==");
+      if(!resp)
+        result = CURLE_OUT_OF_MEMORY;
+      break;
+    }
+    else {
+      *progress = SASL_DONE;
+      state(sasl, conn, SASL_STOP);
+      return CURLE_LOGIN_DENIED;
+    }
+
+  case SASL_CANCEL:
+    /* Remove the offending mechanism from the supported list */
+    sasl->authmechs ^= sasl->authused;
+
+    /* Start an alternative SASL authentication */
+    result = Curl_sasl_start(sasl, conn, sasl->force_ir, progress);
+    newstate = sasl->state;   /* Use state from Curl_sasl_start() */
+    break;
+  default:
+    failf(data, "Unsupported SASL authentication mechanism");
+    result = CURLE_UNSUPPORTED_PROTOCOL;  /* Should not happen */
+    break;
+  }
+
+  switch(result) {
+  case CURLE_BAD_CONTENT_ENCODING:
+    /* Cancel dialog */
+    result = sasl->params->sendcont(conn, "*");
+    newstate = SASL_CANCEL;
+    break;
+  case CURLE_OK:
+    if(resp)
+      result = sasl->params->sendcont(conn, resp);
+    break;
+  default:
+    newstate = SASL_STOP;    /* Stop on error */
+    *progress = SASL_DONE;
+    break;
+  }
+
+  free(resp);
+
+  state(sasl, conn, newstate);
+
+  return result;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_sasl.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_sasl.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_sasl.h	(revision 331)
@@ -0,0 +1,143 @@
+#ifndef HEADER_CURL_SASL_H
+#define HEADER_CURL_SASL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h>
+
+struct Curl_easy;
+struct connectdata;
+
+/* Authentication mechanism flags */
+#define SASL_MECH_LOGIN             (1 << 0)
+#define SASL_MECH_PLAIN             (1 << 1)
+#define SASL_MECH_CRAM_MD5          (1 << 2)
+#define SASL_MECH_DIGEST_MD5        (1 << 3)
+#define SASL_MECH_GSSAPI            (1 << 4)
+#define SASL_MECH_EXTERNAL          (1 << 5)
+#define SASL_MECH_NTLM              (1 << 6)
+#define SASL_MECH_XOAUTH2           (1 << 7)
+#define SASL_MECH_OAUTHBEARER       (1 << 8)
+
+/* Authentication mechanism values */
+#define SASL_AUTH_NONE          0
+#define SASL_AUTH_ANY           ~0U
+#define SASL_AUTH_DEFAULT       (SASL_AUTH_ANY & ~SASL_MECH_EXTERNAL)
+
+/* Authentication mechanism strings */
+#define SASL_MECH_STRING_LOGIN        "LOGIN"
+#define SASL_MECH_STRING_PLAIN        "PLAIN"
+#define SASL_MECH_STRING_CRAM_MD5     "CRAM-MD5"
+#define SASL_MECH_STRING_DIGEST_MD5   "DIGEST-MD5"
+#define SASL_MECH_STRING_GSSAPI       "GSSAPI"
+#define SASL_MECH_STRING_EXTERNAL     "EXTERNAL"
+#define SASL_MECH_STRING_NTLM         "NTLM"
+#define SASL_MECH_STRING_XOAUTH2      "XOAUTH2"
+#define SASL_MECH_STRING_OAUTHBEARER  "OAUTHBEARER"
+
+/* SASL machine states */
+typedef enum {
+  SASL_STOP,
+  SASL_PLAIN,
+  SASL_LOGIN,
+  SASL_LOGIN_PASSWD,
+  SASL_EXTERNAL,
+  SASL_CRAMMD5,
+  SASL_DIGESTMD5,
+  SASL_DIGESTMD5_RESP,
+  SASL_NTLM,
+  SASL_NTLM_TYPE2MSG,
+  SASL_GSSAPI,
+  SASL_GSSAPI_TOKEN,
+  SASL_GSSAPI_NO_DATA,
+  SASL_OAUTH2,
+  SASL_OAUTH2_RESP,
+  SASL_CANCEL,
+  SASL_FINAL
+} saslstate;
+
+/* Progress indicator */
+typedef enum {
+  SASL_IDLE,
+  SASL_INPROGRESS,
+  SASL_DONE
+} saslprogress;
+
+/* Protocol dependent SASL parameters */
+struct SASLproto {
+  const char *service;     /* The service name */
+  int contcode;            /* Code to receive when continuation is expected */
+  int finalcode;           /* Code to receive upon authentication success */
+  size_t maxirlen;         /* Maximum initial response length */
+  CURLcode (*sendauth)(struct connectdata *conn,
+                       const char *mech, const char *ir);
+                           /* Send authentication command */
+  CURLcode (*sendcont)(struct connectdata *conn, const char *contauth);
+                           /* Send authentication continuation */
+  void (*getmessage)(char *buffer, char **outptr);
+                           /* Get SASL response message */
+};
+
+/* Per-connection parameters */
+struct SASL {
+  const struct SASLproto *params; /* Protocol dependent parameters */
+  saslstate state;         /* Current machine state */
+  unsigned int authmechs;  /* Accepted authentication mechanisms */
+  unsigned int prefmech;   /* Preferred authentication mechanism */
+  unsigned int authused;   /* Auth mechanism used for the connection */
+  bool resetprefs;         /* For URL auth option parsing. */
+  bool mutual_auth;        /* Mutual authentication enabled (GSSAPI only) */
+  bool force_ir;           /* Protocol always supports initial response */
+};
+
+/* This is used to test whether the line starts with the given mechanism */
+#define sasl_mech_equal(line, wordlen, mech) \
+  (wordlen == (sizeof(mech) - 1) / sizeof(char) && \
+   !memcmp(line, mech, wordlen))
+
+/* This is used to cleanup any libraries or curl modules used by the sasl
+   functions */
+void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused);
+
+/* Convert a mechanism name to a token */
+unsigned int Curl_sasl_decode_mech(const char *ptr,
+                                   size_t maxlen, size_t *len);
+
+/* Parse the URL login options */
+CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
+                                         const char *value, size_t len);
+
+/* Initializes an SASL structure */
+void Curl_sasl_init(struct SASL *sasl, const struct SASLproto *params);
+
+/* Check if we have enough auth data and capabilities to authenticate */
+bool Curl_sasl_can_authenticate(struct SASL *sasl, struct connectdata *conn);
+
+/* Calculate the required login details for SASL authentication  */
+CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
+                         bool force_ir, saslprogress *progress);
+
+/* Continue an SASL authentication  */
+CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
+                            int code, saslprogress *progress);
+
+#endif /* HEADER_CURL_SASL_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_sec.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_sec.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_sec.h	(revision 331)
@@ -0,0 +1,51 @@
+#ifndef HEADER_CURL_SECURITY_H
+#define HEADER_CURL_SECURITY_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+struct Curl_sec_client_mech {
+  const char *name;
+  size_t size;
+  int (*init)(void *);
+  int (*auth)(void *, struct connectdata *);
+  void (*end)(void *);
+  int (*check_prot)(void *, int);
+  int (*overhead)(void *, int, int);
+  int (*encode)(void *, const void *, int, int, void **);
+  int (*decode)(void *, void *, int, int, struct connectdata *);
+};
+
+#define AUTH_OK         0
+#define AUTH_CONTINUE   1
+#define AUTH_ERROR      2
+
+#ifdef HAVE_GSSAPI
+int Curl_sec_read_msg(struct connectdata *conn, char *,
+                      enum protection_level);
+void Curl_sec_end(struct connectdata *);
+CURLcode Curl_sec_login(struct connectdata *);
+int Curl_sec_request_prot(struct connectdata *conn, const char *level);
+
+extern struct Curl_sec_client_mech Curl_krb5_client_mech;
+#endif
+
+#endif /* HEADER_CURL_SECURITY_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_setup.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_setup.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_setup.h	(revision 331)
@@ -0,0 +1,763 @@
+#ifndef HEADER_CURL_SETUP_H
+#define HEADER_CURL_SETUP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#if defined(BUILDING_LIBCURL) && !defined(CURL_NO_OLDIES)
+#define CURL_NO_OLDIES
+#endif
+
+/*
+ * Define WIN32 when build target is Win32 API
+ */
+
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) && \
+    !defined(__SYMBIAN32__)
+#define WIN32
+#endif
+
+#ifdef WIN32
+/*
+ * Don't include unneeded stuff in Windows headers to avoid compiler
+ * warnings and macro clashes.
+ * Make sure to define this macro before including any Windows headers.
+ */
+#  ifndef WIN32_LEAN_AND_MEAN
+#    define WIN32_LEAN_AND_MEAN
+#  endif
+#endif
+
+/*
+ * Include configuration script results or hand-crafted
+ * configuration file for platforms which lack config tool.
+ */
+
+#ifdef HAVE_CONFIG_H
+
+#include "curl_config.h"
+
+#else /* HAVE_CONFIG_H */
+
+#ifdef _WIN32_WCE
+#  include "config-win32ce.h"
+#else
+#  ifdef WIN32
+#    include "config-win32.h"
+#  endif
+#endif
+
+#if defined(macintosh) && defined(__MRC__)
+#  include "config-mac.h"
+#endif
+
+#ifdef __riscos__
+#  include "config-riscos.h"
+#endif
+
+#ifdef __AMIGA__
+#  include "config-amigaos.h"
+#endif
+
+#ifdef __SYMBIAN32__
+#  include "config-symbian.h"
+#endif
+
+#ifdef __OS400__
+#  include "config-os400.h"
+#endif
+
+#ifdef TPF
+#  include "config-tpf.h"
+#endif
+
+#ifdef __VXWORKS__
+#  include "config-vxworks.h"
+#endif
+
+#endif /* HAVE_CONFIG_H */
+
+/* ================================================================ */
+/* Definition of preprocessor macros/symbols which modify compiler  */
+/* behavior or generated code characteristics must be done here,   */
+/* as appropriate, before any system header file is included. It is */
+/* also possible to have them defined in the config file included   */
+/* before this point. As a result of all this we frown inclusion of */
+/* system header files in our config files, avoid this at any cost. */
+/* ================================================================ */
+
+/*
+ * AIX 4.3 and newer needs _THREAD_SAFE defined to build
+ * proper reentrant code. Others may also need it.
+ */
+
+#ifdef NEED_THREAD_SAFE
+#  ifndef _THREAD_SAFE
+#    define _THREAD_SAFE
+#  endif
+#endif
+
+/*
+ * Tru64 needs _REENTRANT set for a few function prototypes and
+ * things to appear in the system header files. Unixware needs it
+ * to build proper reentrant code. Others may also need it.
+ */
+
+#ifdef NEED_REENTRANT
+#  ifndef _REENTRANT
+#    define _REENTRANT
+#  endif
+#endif
+
+/* Solaris needs this to get a POSIX-conformant getpwuid_r */
+#if defined(sun) || defined(__sun)
+#  ifndef _POSIX_PTHREAD_SEMANTICS
+#    define _POSIX_PTHREAD_SEMANTICS 1
+#  endif
+#endif
+
+/* ================================================================ */
+/*  If you need to include a system header file for your platform,  */
+/*  please, do it beyond the point further indicated in this file.  */
+/* ================================================================ */
+
+#include <curl/curl.h>
+
+#define CURL_SIZEOF_CURL_OFF_T SIZEOF_CURL_OFF_T
+
+/*
+ * Disable other protocols when http is the only one desired.
+ */
+
+#ifdef HTTP_ONLY
+#  ifndef CURL_DISABLE_TFTP
+#    define CURL_DISABLE_TFTP
+#  endif
+#  ifndef CURL_DISABLE_FTP
+#    define CURL_DISABLE_FTP
+#  endif
+#  ifndef CURL_DISABLE_LDAP
+#    define CURL_DISABLE_LDAP
+#  endif
+#  ifndef CURL_DISABLE_TELNET
+#    define CURL_DISABLE_TELNET
+#  endif
+#  ifndef CURL_DISABLE_DICT
+#    define CURL_DISABLE_DICT
+#  endif
+#  ifndef CURL_DISABLE_FILE
+#    define CURL_DISABLE_FILE
+#  endif
+#  ifndef CURL_DISABLE_RTSP
+#    define CURL_DISABLE_RTSP
+#  endif
+#  ifndef CURL_DISABLE_POP3
+#    define CURL_DISABLE_POP3
+#  endif
+#  ifndef CURL_DISABLE_IMAP
+#    define CURL_DISABLE_IMAP
+#  endif
+#  ifndef CURL_DISABLE_SMTP
+#    define CURL_DISABLE_SMTP
+#  endif
+#  ifndef CURL_DISABLE_GOPHER
+#    define CURL_DISABLE_GOPHER
+#  endif
+#  ifndef CURL_DISABLE_SMB
+#    define CURL_DISABLE_SMB
+#  endif
+#endif
+
+/*
+ * When http is disabled rtsp is not supported.
+ */
+
+#if defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_RTSP)
+#  define CURL_DISABLE_RTSP
+#endif
+
+/* ================================================================ */
+/* No system header file shall be included in this file before this */
+/* point. The only allowed ones are those included from curl/system.h */
+/* ================================================================ */
+
+/*
+ * OS/400 setup file includes some system headers.
+ */
+
+#ifdef __OS400__
+#  include "setup-os400.h"
+#endif
+
+/*
+ * VMS setup file includes some system headers.
+ */
+
+#ifdef __VMS
+#  include "setup-vms.h"
+#endif
+
+/*
+ * Use getaddrinfo to resolve the IPv4 address literal. If the current network
+ * interface doesnât support IPv4, but supports IPv6, NAT64, and DNS64,
+ * performing this task will result in a synthesized IPv6 address.
+ */
+#ifdef  __APPLE__
+#define USE_RESOLVE_ON_IPS 1
+#endif
+
+/*
+ * Include header files for windows builds before redefining anything.
+ * Use this preprocessor block only to include or exclude windows.h,
+ * winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs
+ * to any other further and independent block.  Under Cygwin things work
+ * just as under linux (e.g. <sys/socket.h>) and the winsock headers should
+ * never be included when __CYGWIN__ is defined.  configure script takes
+ * care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H,
+ * neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined.
+ */
+
+#ifdef HAVE_WINDOWS_H
+#  if defined(UNICODE) && !defined(_UNICODE)
+#    define _UNICODE
+#  endif
+#  if defined(_UNICODE) && !defined(UNICODE)
+#    define UNICODE
+#  endif
+#  include <windows.h>
+#  ifdef HAVE_WINSOCK2_H
+#    include <winsock2.h>
+#    ifdef HAVE_WS2TCPIP_H
+#      include <ws2tcpip.h>
+#    endif
+#  else
+#    ifdef HAVE_WINSOCK_H
+#      include <winsock.h>
+#    endif
+#  endif
+#  include <tchar.h>
+#  ifdef UNICODE
+     typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str);
+#  endif
+#endif
+
+/*
+ * Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else
+ * define USE_WINSOCK to 1 if we have and use WINSOCK  API, else
+ * undefine USE_WINSOCK.
+ */
+
+#undef USE_WINSOCK
+
+#ifdef HAVE_WINSOCK2_H
+#  define USE_WINSOCK 2
+#else
+#  ifdef HAVE_WINSOCK_H
+#    define USE_WINSOCK 1
+#  endif
+#endif
+
+#ifdef USE_LWIPSOCK
+#  include <lwip/init.h>
+#  include <lwip/sockets.h>
+#  include <lwip/netdb.h>
+#endif
+
+#ifdef HAVE_EXTRA_STRICMP_H
+#  include <extra/stricmp.h>
+#endif
+
+#ifdef HAVE_EXTRA_STRDUP_H
+#  include <extra/strdup.h>
+#endif
+
+#ifdef TPF
+#  include <strings.h>    /* for bzero, strcasecmp, and strncasecmp */
+#  include <string.h>     /* for strcpy and strlen */
+#  include <stdlib.h>     /* for rand and srand */
+#  include <sys/socket.h> /* for select and ioctl*/
+#  include <netdb.h>      /* for in_addr_t definition */
+#  include <tpf/sysapi.h> /* for tpf_process_signals */
+   /* change which select is used for libcurl */
+#  define select(a,b,c,d,e) tpf_select_libcurl(a,b,c,d,e)
+#endif
+
+#ifdef __VXWORKS__
+#  include <sockLib.h>    /* for generic BSD socket functions */
+#  include <ioLib.h>      /* for basic I/O interface functions */
+#endif
+
+#ifdef __AMIGA__
+#  ifndef __ixemul__
+#    include <exec/types.h>
+#    include <exec/execbase.h>
+#    include <proto/exec.h>
+#    include <proto/dos.h>
+#    define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0)
+#  endif
+#endif
+
+#include <stdio.h>
+#ifdef HAVE_ASSERT_H
+#include <assert.h>
+#endif
+
+#ifdef __TANDEM /* for nsr-tandem-nsk systems */
+#include <floss.h>
+#endif
+
+#ifndef STDC_HEADERS /* no standard C headers! */
+#include <curl/stdcheaders.h>
+#endif
+
+#ifdef __POCC__
+#  include <sys/types.h>
+#  include <unistd.h>
+#  define sys_nerr EILSEQ
+#endif
+
+/*
+ * Salford-C kludge section (mostly borrowed from wxWidgets).
+ */
+#ifdef __SALFORDC__
+  #pragma suppress 353             /* Possible nested comments */
+  #pragma suppress 593             /* Define not used */
+  #pragma suppress 61              /* enum has no name */
+  #pragma suppress 106             /* unnamed, unused parameter */
+  #include <clib.h>
+#endif
+
+/*
+ * Large file (>2Gb) support using WIN32 functions.
+ */
+
+#ifdef USE_WIN32_LARGE_FILES
+#  include <io.h>
+#  include <sys/types.h>
+#  include <sys/stat.h>
+#  undef  lseek
+#  define lseek(fdes,offset,whence)  _lseeki64(fdes, offset, whence)
+#  undef  fstat
+#  define fstat(fdes,stp)            _fstati64(fdes, stp)
+#  undef  stat
+#  define stat(fname,stp)            _stati64(fname, stp)
+#  define struct_stat                struct _stati64
+#  define LSEEK_ERROR                (__int64)-1
+#endif
+
+/*
+ * Small file (<2Gb) support using WIN32 functions.
+ */
+
+#ifdef USE_WIN32_SMALL_FILES
+#  include <io.h>
+#  include <sys/types.h>
+#  include <sys/stat.h>
+#  ifndef _WIN32_WCE
+#    undef  lseek
+#    define lseek(fdes,offset,whence)  _lseek(fdes, (long)offset, whence)
+#    define fstat(fdes,stp)            _fstat(fdes, stp)
+#    define stat(fname,stp)            _stat(fname, stp)
+#    define struct_stat                struct _stat
+#  endif
+#  define LSEEK_ERROR                (long)-1
+#endif
+
+#ifndef struct_stat
+#  define struct_stat struct stat
+#endif
+
+#ifndef LSEEK_ERROR
+#  define LSEEK_ERROR (off_t)-1
+#endif
+
+/*
+ * Default sizeof(off_t) in case it hasn't been defined in config file.
+ */
+
+#ifndef SIZEOF_OFF_T
+#  if defined(__VMS) && !defined(__VAX)
+#    if defined(_LARGEFILE)
+#      define SIZEOF_OFF_T 8
+#    endif
+#  elif defined(__OS400__) && defined(__ILEC400__)
+#    if defined(_LARGE_FILES)
+#      define SIZEOF_OFF_T 8
+#    endif
+#  elif defined(__MVS__) && defined(__IBMC__)
+#    if defined(_LP64) || defined(_LARGE_FILES)
+#      define SIZEOF_OFF_T 8
+#    endif
+#  elif defined(__370__) && defined(__IBMC__)
+#    if defined(_LP64) || defined(_LARGE_FILES)
+#      define SIZEOF_OFF_T 8
+#    endif
+#  endif
+#  ifndef SIZEOF_OFF_T
+#    define SIZEOF_OFF_T 4
+#  endif
+#endif
+
+/*
+ * Arg 2 type for gethostname in case it hasn't been defined in config file.
+ */
+
+#ifndef GETHOSTNAME_TYPE_ARG2
+#  ifdef USE_WINSOCK
+#    define GETHOSTNAME_TYPE_ARG2 int
+#  else
+#    define GETHOSTNAME_TYPE_ARG2 size_t
+#  endif
+#endif
+
+/* Below we define some functions. They should
+
+   4. set the SIGALRM signal timeout
+   5. set dir/file naming defines
+   */
+
+#ifdef WIN32
+
+#  define DIR_CHAR      "\\"
+#  define DOT_CHAR      "_"
+
+#else /* WIN32 */
+
+#  ifdef MSDOS  /* Watt-32 */
+
+#    include <sys/ioctl.h>
+#    define select(n,r,w,x,t) select_s(n,r,w,x,t)
+#    define ioctl(x,y,z) ioctlsocket(x,y,(char *)(z))
+#    include <tcp.h>
+#    ifdef word
+#      undef word
+#    endif
+#    ifdef byte
+#      undef byte
+#    endif
+
+#  endif /* MSDOS */
+
+#  ifdef __minix
+     /* Minix 3 versions up to at least 3.1.3 are missing these prototypes */
+     extern char *strtok_r(char *s, const char *delim, char **last);
+     extern struct tm *gmtime_r(const time_t * const timep, struct tm *tmp);
+#  endif
+
+#  define DIR_CHAR      "/"
+#  ifndef DOT_CHAR
+#    define DOT_CHAR      "."
+#  endif
+
+#  ifdef MSDOS
+#    undef DOT_CHAR
+#    define DOT_CHAR      "_"
+#  endif
+
+#  ifndef fileno /* sunos 4 have this as a macro! */
+     int fileno(FILE *stream);
+#  endif
+
+#endif /* WIN32 */
+
+/*
+ * msvc 6.0 requires PSDK in order to have INET6_ADDRSTRLEN
+ * defined in ws2tcpip.h as well as to provide IPv6 support.
+ * Does not apply if lwIP is used.
+ */
+
+#if defined(_MSC_VER) && !defined(__POCC__) && !defined(USE_LWIPSOCK)
+#  if !defined(HAVE_WS2TCPIP_H) || \
+     ((_MSC_VER < 1300) && !defined(INET6_ADDRSTRLEN))
+#    undef HAVE_GETADDRINFO_THREADSAFE
+#    undef HAVE_FREEADDRINFO
+#    undef HAVE_GETADDRINFO
+#    undef HAVE_GETNAMEINFO
+#    undef ENABLE_IPV6
+#  endif
+#endif
+
+/* ---------------------------------------------------------------- */
+/*             resolver specialty compile-time defines              */
+/*         CURLRES_* defines to use in the host*.c sources          */
+/* ---------------------------------------------------------------- */
+
+/*
+ * lcc-win32 doesn't have _beginthreadex(), lacks threads support.
+ */
+
+#if defined(__LCC__) && defined(WIN32)
+#  undef USE_THREADS_POSIX
+#  undef USE_THREADS_WIN32
+#endif
+
+/*
+ * MSVC threads support requires a multi-threaded runtime library.
+ * _beginthreadex() is not available in single-threaded ones.
+ */
+
+#if defined(_MSC_VER) && !defined(__POCC__) && !defined(_MT)
+#  undef USE_THREADS_POSIX
+#  undef USE_THREADS_WIN32
+#endif
+
+/*
+ * Mutually exclusive CURLRES_* definitions.
+ */
+
+#ifdef USE_ARES
+#  define CURLRES_ASYNCH
+#  define CURLRES_ARES
+/* now undef the stock libc functions just to avoid them being used */
+#  undef HAVE_GETADDRINFO
+#  undef HAVE_FREEADDRINFO
+#  undef HAVE_GETHOSTBYNAME
+#elif defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
+#  define CURLRES_ASYNCH
+#  define CURLRES_THREADED
+#else
+#  define CURLRES_SYNCH
+#endif
+
+#ifdef ENABLE_IPV6
+#  define CURLRES_IPV6
+#else
+#  define CURLRES_IPV4
+#endif
+
+/* ---------------------------------------------------------------- */
+
+/*
+ * When using WINSOCK, TELNET protocol requires WINSOCK2 API.
+ */
+
+#if defined(USE_WINSOCK) && (USE_WINSOCK != 2)
+#  define CURL_DISABLE_TELNET 1
+#endif
+
+/*
+ * msvc 6.0 does not have struct sockaddr_storage and
+ * does not define IPPROTO_ESP in winsock2.h. But both
+ * are available if PSDK is properly installed.
+ */
+
+#if defined(_MSC_VER) && !defined(__POCC__)
+#  if !defined(HAVE_WINSOCK2_H) || ((_MSC_VER < 1300) && !defined(IPPROTO_ESP))
+#    undef HAVE_STRUCT_SOCKADDR_STORAGE
+#  endif
+#endif
+
+/*
+ * Intentionally fail to build when using msvc 6.0 without PSDK installed.
+ * The brave of heart can circumvent this, defining ALLOW_MSVC6_WITHOUT_PSDK
+ * in lib/config-win32.h although absolutely discouraged and unsupported.
+ */
+
+#if defined(_MSC_VER) && !defined(__POCC__)
+#  if !defined(HAVE_WINDOWS_H) || ((_MSC_VER < 1300) && !defined(_FILETIME_))
+#    if !defined(ALLOW_MSVC6_WITHOUT_PSDK)
+#      error MSVC 6.0 requires "February 2003 Platform SDK" a.k.a. \
+             "Windows Server 2003 PSDK"
+#    else
+#      define CURL_DISABLE_LDAP 1
+#    endif
+#  endif
+#endif
+
+#ifdef NETWARE
+int netware_init(void);
+#ifndef __NOVELL_LIBC__
+#include <sys/bsdskt.h>
+#include <sys/timeval.h>
+#endif
+#endif
+
+#if defined(HAVE_LIBIDN2) && defined(HAVE_IDN2_H) && !defined(USE_WIN32_IDN)
+/* The lib and header are present */
+#define USE_LIBIDN2
+#endif
+
+#if defined(USE_LIBIDN2) && defined(USE_WIN32_IDN)
+#error "Both libidn2 and WinIDN are enabled, choose one."
+#endif
+
+#ifndef SIZEOF_TIME_T
+/* assume default size of time_t to be 32 bit */
+#define SIZEOF_TIME_T 4
+#endif
+
+#define LIBIDN_REQUIRED_VERSION "0.4.1"
+
+#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \
+    defined(USE_POLARSSL) || defined(USE_AXTLS) || defined(USE_MBEDTLS) || \
+    defined(USE_CYASSL) || defined(USE_SCHANNEL) || \
+    defined(USE_DARWINSSL) || defined(USE_GSKIT)
+#define USE_SSL    /* SSL support has been enabled */
+#endif
+
+/* Single point where USE_SPNEGO definition might be defined */
+#if !defined(CURL_DISABLE_CRYPTO_AUTH) && \
+    (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI))
+#define USE_SPNEGO
+#endif
+
+/* Single point where USE_KERBEROS5 definition might be defined */
+#if !defined(CURL_DISABLE_CRYPTO_AUTH) && \
+    (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI))
+#define USE_KERBEROS5
+#endif
+
+/* Single point where USE_NTLM definition might be defined */
+#if !defined(CURL_DISABLE_NTLM) && !defined(CURL_DISABLE_CRYPTO_AUTH)
+#if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) || \
+    defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_DARWINSSL) || \
+    defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) || \
+    defined(USE_MBEDTLS)
+
+#define USE_NTLM
+
+#  if defined(USE_MBEDTLS)
+/* Get definition of MBEDTLS_MD4_C */
+#  include <mbedtls/md4.h>
+#  endif
+
+#endif
+#endif
+
+#ifdef CURL_WANTS_CA_BUNDLE_ENV
+#error "No longer supported. Set CURLOPT_CAINFO at runtime instead."
+#endif
+
+/*
+ * Provide a mechanism to silence picky compilers, such as gcc 4.6+.
+ * Parameters should of course normally not be unused, but for example when
+ * we have multiple implementations of the same interface it may happen.
+ */
+
+#if defined(__GNUC__) && ((__GNUC__ >= 3) || \
+  ((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 7)))
+#  define UNUSED_PARAM __attribute__((__unused__))
+#  define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+#  define UNUSED_PARAM /*NOTHING*/
+#  define WARN_UNUSED_RESULT
+#endif
+
+/*
+ * Include macros and defines that should only be processed once.
+ */
+
+#ifndef HEADER_CURL_SETUP_ONCE_H
+#include "curl_setup_once.h"
+#endif
+
+/*
+ * Definition of our NOP statement Object-like macro
+ */
+
+#ifndef Curl_nop_stmt
+#  define Curl_nop_stmt do { } WHILE_FALSE
+#endif
+
+/*
+ * Ensure that Winsock and lwIP TCP/IP stacks are not mixed.
+ */
+
+#if defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H)
+#  if defined(SOCKET) || \
+     defined(USE_WINSOCK) || \
+     defined(HAVE_WINSOCK_H) || \
+     defined(HAVE_WINSOCK2_H) || \
+     defined(HAVE_WS2TCPIP_H)
+#    error "Winsock and lwIP TCP/IP stack definitions shall not coexist!"
+#  endif
+#endif
+
+/*
+ * Portable symbolic names for Winsock shutdown() mode flags.
+ */
+
+#ifdef USE_WINSOCK
+#  define SHUT_RD   0x00
+#  define SHUT_WR   0x01
+#  define SHUT_RDWR 0x02
+#endif
+
+/* Define S_ISREG if not defined by system headers, f.e. MSVC */
+#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+
+/* Define S_ISDIR if not defined by system headers, f.e. MSVC */
+#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+
+/* In Windows the default file mode is text but an application can override it.
+Therefore we specify it explicitly. https://github.com/curl/curl/pull/258
+*/
+#if defined(WIN32) || defined(MSDOS)
+#define FOPEN_READTEXT "rt"
+#define FOPEN_WRITETEXT "wt"
+#define FOPEN_APPENDTEXT "at"
+#elif defined(__CYGWIN__)
+/* Cygwin has specific behavior we need to address when WIN32 is not defined.
+https://cygwin.com/cygwin-ug-net/using-textbinary.html
+For write we want our output to have line endings of LF and be compatible with
+other Cygwin utilities. For read we want to handle input that may have line
+endings either CRLF or LF so 't' is appropriate.
+*/
+#define FOPEN_READTEXT "rt"
+#define FOPEN_WRITETEXT "w"
+#define FOPEN_APPENDTEXT "a"
+#else
+#define FOPEN_READTEXT "r"
+#define FOPEN_WRITETEXT "w"
+#define FOPEN_APPENDTEXT "a"
+#endif
+
+/* WinSock destroys recv() buffer when send() failed.
+ * Enabled automatically for Windows and for Cygwin as Cygwin sockets are
+ * wrappers for WinSock sockets. https://github.com/curl/curl/issues/657
+ * Define DONT_USE_RECV_BEFORE_SEND_WORKAROUND to force disable workaround.
+ */
+#if !defined(DONT_USE_RECV_BEFORE_SEND_WORKAROUND)
+#  if defined(WIN32) || defined(__CYGWIN__)
+#    define USE_RECV_BEFORE_SEND_WORKAROUND
+#  endif
+#else  /* DONT_USE_RECV_BEFORE_SEND_WORKAROUNDS */
+#  ifdef USE_RECV_BEFORE_SEND_WORKAROUND
+#    undef USE_RECV_BEFORE_SEND_WORKAROUND
+#  endif
+#endif /* DONT_USE_RECV_BEFORE_SEND_WORKAROUNDS */
+
+/* Detect Windows App environment which has a restricted access
+ * to the Win32 APIs. */
+# if (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)) || \
+  defined(WINAPI_FAMILY)
+#  include <winapifamily.h>
+#  if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) &&  \
+     !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+#    define CURL_WINDOWS_APP
+#  endif
+# endif
+
+#endif /* HEADER_CURL_SETUP_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_setup_once.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_setup_once.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_setup_once.h	(revision 331)
@@ -0,0 +1,537 @@
+#ifndef HEADER_CURL_SETUP_ONCE_H
+#define HEADER_CURL_SETUP_ONCE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+
+/*
+ * Inclusion of common header files.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef NEED_MALLOC_H
+#include <malloc.h>
+#endif
+
+#ifdef NEED_MEMORY_H
+#include <memory.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#ifdef TIME_WITH_SYS_TIME
+#include <time.h>
+#endif
+#else
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#endif
+
+#ifdef WIN32
+#include <io.h>
+#include <fcntl.h>
+#endif
+
+#if defined(HAVE_STDBOOL_H) && defined(HAVE_BOOL_T)
+#include <stdbool.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef __hpux
+#  if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL)
+#    ifdef _APP32_64BIT_OFF_T
+#      define OLD_APP32_64BIT_OFF_T _APP32_64BIT_OFF_T
+#      undef _APP32_64BIT_OFF_T
+#    else
+#      undef OLD_APP32_64BIT_OFF_T
+#    endif
+#  endif
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#ifdef __hpux
+#  if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL)
+#    ifdef OLD_APP32_64BIT_OFF_T
+#      define _APP32_64BIT_OFF_T OLD_APP32_64BIT_OFF_T
+#      undef OLD_APP32_64BIT_OFF_T
+#    endif
+#  endif
+#endif
+
+
+/*
+ * Definition of timeval struct for platforms that don't have it.
+ */
+
+#ifndef HAVE_STRUCT_TIMEVAL
+struct timeval {
+ long tv_sec;
+ long tv_usec;
+};
+#endif
+
+
+/*
+ * If we have the MSG_NOSIGNAL define, make sure we use
+ * it as the fourth argument of function send()
+ */
+
+#ifdef HAVE_MSG_NOSIGNAL
+#define SEND_4TH_ARG MSG_NOSIGNAL
+#else
+#define SEND_4TH_ARG 0
+#endif
+
+
+#if defined(__minix)
+/* Minix doesn't support recv on TCP sockets */
+#define sread(x,y,z) (ssize_t)read((RECV_TYPE_ARG1)(x), \
+                                   (RECV_TYPE_ARG2)(y), \
+                                   (RECV_TYPE_ARG3)(z))
+
+#elif defined(HAVE_RECV)
+/*
+ * The definitions for the return type and arguments types
+ * of functions recv() and send() belong and come from the
+ * configuration file. Do not define them in any other place.
+ *
+ * HAVE_RECV is defined if you have a function named recv()
+ * which is used to read incoming data from sockets. If your
+ * function has another name then don't define HAVE_RECV.
+ *
+ * If HAVE_RECV is defined then RECV_TYPE_ARG1, RECV_TYPE_ARG2,
+ * RECV_TYPE_ARG3, RECV_TYPE_ARG4 and RECV_TYPE_RETV must also
+ * be defined.
+ *
+ * HAVE_SEND is defined if you have a function named send()
+ * which is used to write outgoing data on a connected socket.
+ * If yours has another name then don't define HAVE_SEND.
+ *
+ * If HAVE_SEND is defined then SEND_TYPE_ARG1, SEND_QUAL_ARG2,
+ * SEND_TYPE_ARG2, SEND_TYPE_ARG3, SEND_TYPE_ARG4 and
+ * SEND_TYPE_RETV must also be defined.
+ */
+
+#if !defined(RECV_TYPE_ARG1) || \
+    !defined(RECV_TYPE_ARG2) || \
+    !defined(RECV_TYPE_ARG3) || \
+    !defined(RECV_TYPE_ARG4) || \
+    !defined(RECV_TYPE_RETV)
+  /* */
+  Error Missing_definition_of_return_and_arguments_types_of_recv
+  /* */
+#else
+#define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \
+                                   (RECV_TYPE_ARG2)(y), \
+                                   (RECV_TYPE_ARG3)(z), \
+                                   (RECV_TYPE_ARG4)(0))
+#endif
+#else /* HAVE_RECV */
+#ifndef sread
+  /* */
+  Error Missing_definition_of_macro_sread
+  /* */
+#endif
+#endif /* HAVE_RECV */
+
+
+#if defined(__minix)
+/* Minix doesn't support send on TCP sockets */
+#define swrite(x,y,z) (ssize_t)write((SEND_TYPE_ARG1)(x), \
+                                    (SEND_TYPE_ARG2)(y), \
+                                    (SEND_TYPE_ARG3)(z))
+
+#elif defined(HAVE_SEND)
+#if !defined(SEND_TYPE_ARG1) || \
+    !defined(SEND_QUAL_ARG2) || \
+    !defined(SEND_TYPE_ARG2) || \
+    !defined(SEND_TYPE_ARG3) || \
+    !defined(SEND_TYPE_ARG4) || \
+    !defined(SEND_TYPE_RETV)
+  /* */
+  Error Missing_definition_of_return_and_arguments_types_of_send
+  /* */
+#else
+#define swrite(x,y,z) (ssize_t)send((SEND_TYPE_ARG1)(x), \
+                                    (SEND_QUAL_ARG2 SEND_TYPE_ARG2)(y), \
+                                    (SEND_TYPE_ARG3)(z), \
+                                    (SEND_TYPE_ARG4)(SEND_4TH_ARG))
+#endif
+#else /* HAVE_SEND */
+#ifndef swrite
+  /* */
+  Error Missing_definition_of_macro_swrite
+  /* */
+#endif
+#endif /* HAVE_SEND */
+
+
+#if 0
+#if defined(HAVE_RECVFROM)
+/*
+ * Currently recvfrom is only used on udp sockets.
+ */
+#if !defined(RECVFROM_TYPE_ARG1) || \
+    !defined(RECVFROM_TYPE_ARG2) || \
+    !defined(RECVFROM_TYPE_ARG3) || \
+    !defined(RECVFROM_TYPE_ARG4) || \
+    !defined(RECVFROM_TYPE_ARG5) || \
+    !defined(RECVFROM_TYPE_ARG6) || \
+    !defined(RECVFROM_TYPE_RETV)
+  /* */
+  Error Missing_definition_of_return_and_arguments_types_of_recvfrom
+  /* */
+#else
+#define sreadfrom(s,b,bl,f,fl) (ssize_t)recvfrom((RECVFROM_TYPE_ARG1)  (s),  \
+                                                 (RECVFROM_TYPE_ARG2 *)(b),  \
+                                                 (RECVFROM_TYPE_ARG3)  (bl), \
+                                                 (RECVFROM_TYPE_ARG4)  (0),  \
+                                                 (RECVFROM_TYPE_ARG5 *)(f),  \
+                                                 (RECVFROM_TYPE_ARG6 *)(fl))
+#endif
+#else /* HAVE_RECVFROM */
+#ifndef sreadfrom
+  /* */
+  Error Missing_definition_of_macro_sreadfrom
+  /* */
+#endif
+#endif /* HAVE_RECVFROM */
+
+
+#ifdef RECVFROM_TYPE_ARG6_IS_VOID
+#  define RECVFROM_ARG6_T int
+#else
+#  define RECVFROM_ARG6_T RECVFROM_TYPE_ARG6
+#endif
+#endif /* if 0 */
+
+
+/*
+ * Function-like macro definition used to close a socket.
+ */
+
+#if defined(HAVE_CLOSESOCKET)
+#  define sclose(x)  closesocket((x))
+#elif defined(HAVE_CLOSESOCKET_CAMEL)
+#  define sclose(x)  CloseSocket((x))
+#elif defined(HAVE_CLOSE_S)
+#  define sclose(x)  close_s((x))
+#elif defined(USE_LWIPSOCK)
+#  define sclose(x)  lwip_close((x))
+#else
+#  define sclose(x)  close((x))
+#endif
+
+/*
+ * Stack-independent version of fcntl() on sockets:
+ */
+#if defined(USE_LWIPSOCK)
+#  define sfcntl  lwip_fcntl
+#else
+#  define sfcntl  fcntl
+#endif
+
+/*
+ * Uppercase macro versions of ANSI/ISO is*() functions/macros which
+ * avoid negative number inputs with argument byte codes > 127.
+ */
+
+#define ISSPACE(x)  (isspace((int)  ((unsigned char)x)))
+#define ISDIGIT(x)  (isdigit((int)  ((unsigned char)x)))
+#define ISALNUM(x)  (isalnum((int)  ((unsigned char)x)))
+#define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x)))
+#define ISGRAPH(x)  (isgraph((int)  ((unsigned char)x)))
+#define ISALPHA(x)  (isalpha((int)  ((unsigned char)x)))
+#define ISPRINT(x)  (isprint((int)  ((unsigned char)x)))
+#define ISUPPER(x)  (isupper((int)  ((unsigned char)x)))
+#define ISLOWER(x)  (islower((int)  ((unsigned char)x)))
+#define ISASCII(x)  (isascii((int)  ((unsigned char)x)))
+
+#define ISBLANK(x)  (int)((((unsigned char)x) == ' ') || \
+                          (((unsigned char)x) == '\t'))
+
+#define TOLOWER(x)  (tolower((int)  ((unsigned char)x)))
+
+
+/*
+ * 'bool' stuff compatible with HP-UX headers.
+ */
+
+#if defined(__hpux) && !defined(HAVE_BOOL_T)
+   typedef int bool;
+#  define false 0
+#  define true 1
+#  define HAVE_BOOL_T
+#endif
+
+
+/*
+ * 'bool' exists on platforms with <stdbool.h>, i.e. C99 platforms.
+ * On non-C99 platforms there's no bool, so define an enum for that.
+ * On C99 platforms 'false' and 'true' also exist. Enum uses a
+ * global namespace though, so use bool_false and bool_true.
+ */
+
+#ifndef HAVE_BOOL_T
+  typedef enum {
+      bool_false = 0,
+      bool_true  = 1
+  } bool;
+
+/*
+ * Use a define to let 'true' and 'false' use those enums.  There
+ * are currently no use of true and false in libcurl proper, but
+ * there are some in the examples. This will cater for any later
+ * code happening to use true and false.
+ */
+#  define false bool_false
+#  define true  bool_true
+#  define HAVE_BOOL_T
+#endif
+
+
+/*
+ * Redefine TRUE and FALSE too, to catch current use. With this
+ * change, 'bool found = 1' will give a warning on MIPSPro, but
+ * 'bool found = TRUE' will not. Change tested on IRIX/MIPSPro,
+ * AIX 5.1/Xlc, Tru64 5.1/cc, w/make test too.
+ */
+
+#ifndef TRUE
+#define TRUE true
+#endif
+#ifndef FALSE
+#define FALSE false
+#endif
+
+
+/*
+ * Macro WHILE_FALSE may be used to build single-iteration do-while loops,
+ * avoiding compiler warnings. Mostly intended for other macro definitions.
+ */
+
+#define WHILE_FALSE  while(0)
+
+#if defined(_MSC_VER) && !defined(__POCC__)
+#  undef WHILE_FALSE
+#  if (_MSC_VER < 1500)
+#    define WHILE_FALSE  while(1, 0)
+#  else
+#    define WHILE_FALSE \
+__pragma(warning(push)) \
+__pragma(warning(disable:4127)) \
+while(0) \
+__pragma(warning(pop))
+#  endif
+#endif
+
+
+/*
+ * Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type.
+ */
+
+#ifndef HAVE_SIG_ATOMIC_T
+typedef int sig_atomic_t;
+#define HAVE_SIG_ATOMIC_T
+#endif
+
+
+/*
+ * Convenience SIG_ATOMIC_T definition
+ */
+
+#ifdef HAVE_SIG_ATOMIC_T_VOLATILE
+#define SIG_ATOMIC_T static sig_atomic_t
+#else
+#define SIG_ATOMIC_T static volatile sig_atomic_t
+#endif
+
+
+/*
+ * Default return type for signal handlers.
+ */
+
+#ifndef RETSIGTYPE
+#define RETSIGTYPE void
+#endif
+
+
+/*
+ * Macro used to include code only in debug builds.
+ */
+
+#ifdef DEBUGBUILD
+#define DEBUGF(x) x
+#else
+#define DEBUGF(x) do { } WHILE_FALSE
+#endif
+
+
+/*
+ * Macro used to include assertion code only in debug builds.
+ */
+
+#if defined(DEBUGBUILD) && defined(HAVE_ASSERT_H)
+#define DEBUGASSERT(x) assert(x)
+#else
+#define DEBUGASSERT(x) do { } WHILE_FALSE
+#endif
+
+
+/*
+ * Macro SOCKERRNO / SET_SOCKERRNO() returns / sets the *socket-related* errno
+ * (or equivalent) on this platform to hide platform details to code using it.
+ */
+
+#ifdef USE_WINSOCK
+#define SOCKERRNO         ((int)WSAGetLastError())
+#define SET_SOCKERRNO(x)  (WSASetLastError((int)(x)))
+#else
+#define SOCKERRNO         (errno)
+#define SET_SOCKERRNO(x)  (errno = (x))
+#endif
+
+
+/*
+ * Portable error number symbolic names defined to Winsock error codes.
+ */
+
+#ifdef USE_WINSOCK
+#undef  EBADF            /* override definition in errno.h */
+#define EBADF            WSAEBADF
+#undef  EINTR            /* override definition in errno.h */
+#define EINTR            WSAEINTR
+#undef  EINVAL           /* override definition in errno.h */
+#define EINVAL           WSAEINVAL
+#undef  EWOULDBLOCK      /* override definition in errno.h */
+#define EWOULDBLOCK      WSAEWOULDBLOCK
+#undef  EINPROGRESS      /* override definition in errno.h */
+#define EINPROGRESS      WSAEINPROGRESS
+#undef  EALREADY         /* override definition in errno.h */
+#define EALREADY         WSAEALREADY
+#undef  ENOTSOCK         /* override definition in errno.h */
+#define ENOTSOCK         WSAENOTSOCK
+#undef  EDESTADDRREQ     /* override definition in errno.h */
+#define EDESTADDRREQ     WSAEDESTADDRREQ
+#undef  EMSGSIZE         /* override definition in errno.h */
+#define EMSGSIZE         WSAEMSGSIZE
+#undef  EPROTOTYPE       /* override definition in errno.h */
+#define EPROTOTYPE       WSAEPROTOTYPE
+#undef  ENOPROTOOPT      /* override definition in errno.h */
+#define ENOPROTOOPT      WSAENOPROTOOPT
+#undef  EPROTONOSUPPORT  /* override definition in errno.h */
+#define EPROTONOSUPPORT  WSAEPROTONOSUPPORT
+#define ESOCKTNOSUPPORT  WSAESOCKTNOSUPPORT
+#undef  EOPNOTSUPP       /* override definition in errno.h */
+#define EOPNOTSUPP       WSAEOPNOTSUPP
+#define EPFNOSUPPORT     WSAEPFNOSUPPORT
+#undef  EAFNOSUPPORT     /* override definition in errno.h */
+#define EAFNOSUPPORT     WSAEAFNOSUPPORT
+#undef  EADDRINUSE       /* override definition in errno.h */
+#define EADDRINUSE       WSAEADDRINUSE
+#undef  EADDRNOTAVAIL    /* override definition in errno.h */
+#define EADDRNOTAVAIL    WSAEADDRNOTAVAIL
+#undef  ENETDOWN         /* override definition in errno.h */
+#define ENETDOWN         WSAENETDOWN
+#undef  ENETUNREACH      /* override definition in errno.h */
+#define ENETUNREACH      WSAENETUNREACH
+#undef  ENETRESET        /* override definition in errno.h */
+#define ENETRESET        WSAENETRESET
+#undef  ECONNABORTED     /* override definition in errno.h */
+#define ECONNABORTED     WSAECONNABORTED
+#undef  ECONNRESET       /* override definition in errno.h */
+#define ECONNRESET       WSAECONNRESET
+#undef  ENOBUFS          /* override definition in errno.h */
+#define ENOBUFS          WSAENOBUFS
+#undef  EISCONN          /* override definition in errno.h */
+#define EISCONN          WSAEISCONN
+#undef  ENOTCONN         /* override definition in errno.h */
+#define ENOTCONN         WSAENOTCONN
+#define ESHUTDOWN        WSAESHUTDOWN
+#define ETOOMANYREFS     WSAETOOMANYREFS
+#undef  ETIMEDOUT        /* override definition in errno.h */
+#define ETIMEDOUT        WSAETIMEDOUT
+#undef  ECONNREFUSED     /* override definition in errno.h */
+#define ECONNREFUSED     WSAECONNREFUSED
+#undef  ELOOP            /* override definition in errno.h */
+#define ELOOP            WSAELOOP
+#ifndef ENAMETOOLONG     /* possible previous definition in errno.h */
+#define ENAMETOOLONG     WSAENAMETOOLONG
+#endif
+#define EHOSTDOWN        WSAEHOSTDOWN
+#undef  EHOSTUNREACH     /* override definition in errno.h */
+#define EHOSTUNREACH     WSAEHOSTUNREACH
+#ifndef ENOTEMPTY        /* possible previous definition in errno.h */
+#define ENOTEMPTY        WSAENOTEMPTY
+#endif
+#define EPROCLIM         WSAEPROCLIM
+#define EUSERS           WSAEUSERS
+#define EDQUOT           WSAEDQUOT
+#define ESTALE           WSAESTALE
+#define EREMOTE          WSAEREMOTE
+#endif
+
+/*
+ * Macro argv_item_t hides platform details to code using it.
+ */
+
+#ifdef __VMS
+#define argv_item_t  __char_ptr32
+#else
+#define argv_item_t  char *
+#endif
+
+
+/*
+ * We use this ZERO_NULL to avoid picky compiler warnings,
+ * when assigning a NULL pointer to a function pointer var.
+ */
+
+#define ZERO_NULL 0
+
+
+#endif /* HEADER_CURL_SETUP_ONCE_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_sha256.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_sha256.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_sha256.h	(revision 331)
@@ -0,0 +1,32 @@
+#ifndef HEADER_CURL_SHA256_H
+#define HEADER_CURL_SHA256_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Florin Petriuc, <petriuc.florin@gmail.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+
+void Curl_sha256it(unsigned char *outbuffer,
+                const unsigned char *input);
+
+#endif
+
+#endif /* HEADER_CURL_SHA256_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_sspi.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_sspi.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_sspi.c	(revision 331)
@@ -0,0 +1,235 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_WINDOWS_SSPI
+
+#include <curl/curl.h>
+#include "curl_sspi.h"
+#include "curl_multibyte.h"
+#include "system_win32.h"
+#include "warnless.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* We use our own typedef here since some headers might lack these */
+typedef PSecurityFunctionTable (APIENTRY *INITSECURITYINTERFACE_FN)(VOID);
+
+/* See definition of SECURITY_ENTRYPOINT in sspi.h */
+#ifdef UNICODE
+#  ifdef _WIN32_WCE
+#    define SECURITYENTRYPOINT L"InitSecurityInterfaceW"
+#  else
+#    define SECURITYENTRYPOINT "InitSecurityInterfaceW"
+#  endif
+#else
+#  define SECURITYENTRYPOINT "InitSecurityInterfaceA"
+#endif
+
+/* Handle of security.dll or secur32.dll, depending on Windows version */
+HMODULE s_hSecDll = NULL;
+
+/* Pointer to SSPI dispatch table */
+PSecurityFunctionTable s_pSecFn = NULL;
+
+/*
+ * Curl_sspi_global_init()
+ *
+ * This is used to load the Security Service Provider Interface (SSPI)
+ * dynamic link library portably across all Windows versions, without
+ * the need to directly link libcurl, nor the application using it, at
+ * build time.
+ *
+ * Once this function has been executed, Windows SSPI functions can be
+ * called through the Security Service Provider Interface dispatch table.
+ *
+ * Parameters:
+ *
+ * None.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sspi_global_init(void)
+{
+  INITSECURITYINTERFACE_FN pInitSecurityInterface;
+
+  /* If security interface is not yet initialized try to do this */
+  if(!s_hSecDll) {
+    /* Security Service Provider Interface (SSPI) functions are located in
+     * security.dll on WinNT 4.0 and in secur32.dll on Win9x. Win2K and XP
+     * have both these DLLs (security.dll forwards calls to secur32.dll) */
+
+    /* Load SSPI dll into the address space of the calling process */
+    if(Curl_verify_windows_version(4, 0, PLATFORM_WINNT, VERSION_EQUAL))
+      s_hSecDll = Curl_load_library(TEXT("security.dll"));
+    else
+      s_hSecDll = Curl_load_library(TEXT("secur32.dll"));
+    if(!s_hSecDll)
+      return CURLE_FAILED_INIT;
+
+    /* Get address of the InitSecurityInterfaceA function from the SSPI dll */
+    pInitSecurityInterface = (INITSECURITYINTERFACE_FN)
+      GetProcAddress(s_hSecDll, SECURITYENTRYPOINT);
+    if(!pInitSecurityInterface)
+      return CURLE_FAILED_INIT;
+
+    /* Get pointer to Security Service Provider Interface dispatch table */
+    s_pSecFn = pInitSecurityInterface();
+    if(!s_pSecFn)
+      return CURLE_FAILED_INIT;
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_sspi_global_cleanup()
+ *
+ * This deinitializes the Security Service Provider Interface from libcurl.
+ *
+ * Parameters:
+ *
+ * None.
+ */
+void Curl_sspi_global_cleanup(void)
+{
+  if(s_hSecDll) {
+    FreeLibrary(s_hSecDll);
+    s_hSecDll = NULL;
+    s_pSecFn = NULL;
+  }
+}
+
+/*
+ * Curl_create_sspi_identity()
+ *
+ * This is used to populate a SSPI identity structure based on the supplied
+ * username and password.
+ *
+ * Parameters:
+ *
+ * userp    [in]     - The user name in the format User or Domain\User.
+ * passdwp  [in]     - The user's password.
+ * identity [in/out] - The identity structure.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
+                                   SEC_WINNT_AUTH_IDENTITY *identity)
+{
+  xcharp_u useranddomain;
+  xcharp_u user, dup_user;
+  xcharp_u domain, dup_domain;
+  xcharp_u passwd, dup_passwd;
+  size_t domlen = 0;
+
+  domain.const_tchar_ptr = TEXT("");
+
+  /* Initialize the identity */
+  memset(identity, 0, sizeof(*identity));
+
+  useranddomain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)userp);
+  if(!useranddomain.tchar_ptr)
+    return CURLE_OUT_OF_MEMORY;
+
+  user.const_tchar_ptr = _tcschr(useranddomain.const_tchar_ptr, TEXT('\\'));
+  if(!user.const_tchar_ptr)
+    user.const_tchar_ptr = _tcschr(useranddomain.const_tchar_ptr, TEXT('/'));
+
+  if(user.tchar_ptr) {
+    domain.tchar_ptr = useranddomain.tchar_ptr;
+    domlen = user.tchar_ptr - useranddomain.tchar_ptr;
+    user.tchar_ptr++;
+  }
+  else {
+    user.tchar_ptr = useranddomain.tchar_ptr;
+    domain.const_tchar_ptr = TEXT("");
+    domlen = 0;
+  }
+
+  /* Setup the identity's user and length */
+  dup_user.tchar_ptr = _tcsdup(user.tchar_ptr);
+  if(!dup_user.tchar_ptr) {
+    Curl_unicodefree(useranddomain.tchar_ptr);
+    return CURLE_OUT_OF_MEMORY;
+  }
+  identity->User = dup_user.tbyte_ptr;
+  identity->UserLength = curlx_uztoul(_tcslen(dup_user.tchar_ptr));
+  dup_user.tchar_ptr = NULL;
+
+  /* Setup the identity's domain and length */
+  dup_domain.tchar_ptr = malloc(sizeof(TCHAR) * (domlen + 1));
+  if(!dup_domain.tchar_ptr) {
+    Curl_unicodefree(useranddomain.tchar_ptr);
+    return CURLE_OUT_OF_MEMORY;
+  }
+  _tcsncpy(dup_domain.tchar_ptr, domain.tchar_ptr, domlen);
+  *(dup_domain.tchar_ptr + domlen) = TEXT('\0');
+  identity->Domain = dup_domain.tbyte_ptr;
+  identity->DomainLength = curlx_uztoul(domlen);
+  dup_domain.tchar_ptr = NULL;
+
+  Curl_unicodefree(useranddomain.tchar_ptr);
+
+  /* Setup the identity's password and length */
+  passwd.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)passwdp);
+  if(!passwd.tchar_ptr)
+    return CURLE_OUT_OF_MEMORY;
+  dup_passwd.tchar_ptr = _tcsdup(passwd.tchar_ptr);
+  if(!dup_passwd.tchar_ptr) {
+    Curl_unicodefree(passwd.tchar_ptr);
+    return CURLE_OUT_OF_MEMORY;
+  }
+  identity->Password = dup_passwd.tbyte_ptr;
+  identity->PasswordLength = curlx_uztoul(_tcslen(dup_passwd.tchar_ptr));
+  dup_passwd.tchar_ptr = NULL;
+
+  Curl_unicodefree(passwd.tchar_ptr);
+
+  /* Setup the identity's flags */
+  identity->Flags = SECFLAG_WINNT_AUTH_IDENTITY;
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_sspi_free_identity()
+ *
+ * This is used to free the contents of a SSPI identifier structure.
+ *
+ * Parameters:
+ *
+ * identity [in/out] - The identity structure.
+ */
+void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity)
+{
+  if(identity) {
+    Curl_safefree(identity->User);
+    Curl_safefree(identity->Password);
+    Curl_safefree(identity->Domain);
+  }
+}
+
+#endif /* USE_WINDOWS_SSPI */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_sspi.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_sspi.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_sspi.h	(revision 331)
@@ -0,0 +1,350 @@
+#ifndef HEADER_CURL_SSPI_H
+#define HEADER_CURL_SSPI_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_WINDOWS_SSPI
+
+#include <curl/curl.h>
+
+/*
+ * When including the following three headers, it is mandatory to define either
+ * SECURITY_WIN32 or SECURITY_KERNEL, indicating who is compiling the code.
+ */
+
+#undef SECURITY_WIN32
+#undef SECURITY_KERNEL
+#define SECURITY_WIN32 1
+#include <security.h>
+#include <sspi.h>
+#include <rpc.h>
+
+CURLcode Curl_sspi_global_init(void);
+void Curl_sspi_global_cleanup(void);
+
+/* This is used to populate the domain in a SSPI identity structure */
+CURLcode Curl_override_sspi_http_realm(const char *chlg,
+                                       SEC_WINNT_AUTH_IDENTITY *identity);
+
+/* This is used to generate an SSPI identity structure */
+CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
+                                   SEC_WINNT_AUTH_IDENTITY *identity);
+
+/* This is used to free an SSPI identity structure */
+void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity);
+
+/* Forward-declaration of global variables defined in curl_sspi.c */
+extern HMODULE s_hSecDll;
+extern PSecurityFunctionTable s_pSecFn;
+
+/* Provide some definitions missing in old headers */
+#define SP_NAME_DIGEST              "WDigest"
+#define SP_NAME_NTLM                "NTLM"
+#define SP_NAME_NEGOTIATE           "Negotiate"
+#define SP_NAME_KERBEROS            "Kerberos"
+
+#ifndef ISC_REQ_USE_HTTP_STYLE
+#define ISC_REQ_USE_HTTP_STYLE                0x01000000
+#endif
+
+#ifndef ISC_RET_REPLAY_DETECT
+#define ISC_RET_REPLAY_DETECT                 0x00000004
+#endif
+
+#ifndef ISC_RET_SEQUENCE_DETECT
+#define ISC_RET_SEQUENCE_DETECT               0x00000008
+#endif
+
+#ifndef ISC_RET_CONFIDENTIALITY
+#define ISC_RET_CONFIDENTIALITY               0x00000010
+#endif
+
+#ifndef ISC_RET_ALLOCATED_MEMORY
+#define ISC_RET_ALLOCATED_MEMORY              0x00000100
+#endif
+
+#ifndef ISC_RET_STREAM
+#define ISC_RET_STREAM                        0x00008000
+#endif
+
+#ifndef SEC_E_INSUFFICIENT_MEMORY
+# define SEC_E_INSUFFICIENT_MEMORY            ((HRESULT)0x80090300L)
+#endif
+#ifndef SEC_E_INVALID_HANDLE
+# define SEC_E_INVALID_HANDLE                 ((HRESULT)0x80090301L)
+#endif
+#ifndef SEC_E_UNSUPPORTED_FUNCTION
+# define SEC_E_UNSUPPORTED_FUNCTION           ((HRESULT)0x80090302L)
+#endif
+#ifndef SEC_E_TARGET_UNKNOWN
+# define SEC_E_TARGET_UNKNOWN                 ((HRESULT)0x80090303L)
+#endif
+#ifndef SEC_E_INTERNAL_ERROR
+# define SEC_E_INTERNAL_ERROR                 ((HRESULT)0x80090304L)
+#endif
+#ifndef SEC_E_SECPKG_NOT_FOUND
+# define SEC_E_SECPKG_NOT_FOUND               ((HRESULT)0x80090305L)
+#endif
+#ifndef SEC_E_NOT_OWNER
+# define SEC_E_NOT_OWNER                      ((HRESULT)0x80090306L)
+#endif
+#ifndef SEC_E_CANNOT_INSTALL
+# define SEC_E_CANNOT_INSTALL                 ((HRESULT)0x80090307L)
+#endif
+#ifndef SEC_E_INVALID_TOKEN
+# define SEC_E_INVALID_TOKEN                  ((HRESULT)0x80090308L)
+#endif
+#ifndef SEC_E_CANNOT_PACK
+# define SEC_E_CANNOT_PACK                    ((HRESULT)0x80090309L)
+#endif
+#ifndef SEC_E_QOP_NOT_SUPPORTED
+# define SEC_E_QOP_NOT_SUPPORTED              ((HRESULT)0x8009030AL)
+#endif
+#ifndef SEC_E_NO_IMPERSONATION
+# define SEC_E_NO_IMPERSONATION               ((HRESULT)0x8009030BL)
+#endif
+#ifndef SEC_E_LOGON_DENIED
+# define SEC_E_LOGON_DENIED                   ((HRESULT)0x8009030CL)
+#endif
+#ifndef SEC_E_UNKNOWN_CREDENTIALS
+# define SEC_E_UNKNOWN_CREDENTIALS            ((HRESULT)0x8009030DL)
+#endif
+#ifndef SEC_E_NO_CREDENTIALS
+# define SEC_E_NO_CREDENTIALS                 ((HRESULT)0x8009030EL)
+#endif
+#ifndef SEC_E_MESSAGE_ALTERED
+# define SEC_E_MESSAGE_ALTERED                ((HRESULT)0x8009030FL)
+#endif
+#ifndef SEC_E_OUT_OF_SEQUENCE
+# define SEC_E_OUT_OF_SEQUENCE                ((HRESULT)0x80090310L)
+#endif
+#ifndef SEC_E_NO_AUTHENTICATING_AUTHORITY
+# define SEC_E_NO_AUTHENTICATING_AUTHORITY    ((HRESULT)0x80090311L)
+#endif
+#ifndef SEC_E_BAD_PKGID
+# define SEC_E_BAD_PKGID                      ((HRESULT)0x80090316L)
+#endif
+#ifndef SEC_E_CONTEXT_EXPIRED
+# define SEC_E_CONTEXT_EXPIRED                ((HRESULT)0x80090317L)
+#endif
+#ifndef SEC_E_INCOMPLETE_MESSAGE
+# define SEC_E_INCOMPLETE_MESSAGE             ((HRESULT)0x80090318L)
+#endif
+#ifndef SEC_E_INCOMPLETE_CREDENTIALS
+# define SEC_E_INCOMPLETE_CREDENTIALS         ((HRESULT)0x80090320L)
+#endif
+#ifndef SEC_E_BUFFER_TOO_SMALL
+# define SEC_E_BUFFER_TOO_SMALL               ((HRESULT)0x80090321L)
+#endif
+#ifndef SEC_E_WRONG_PRINCIPAL
+# define SEC_E_WRONG_PRINCIPAL                ((HRESULT)0x80090322L)
+#endif
+#ifndef SEC_E_TIME_SKEW
+# define SEC_E_TIME_SKEW                      ((HRESULT)0x80090324L)
+#endif
+#ifndef SEC_E_UNTRUSTED_ROOT
+# define SEC_E_UNTRUSTED_ROOT                 ((HRESULT)0x80090325L)
+#endif
+#ifndef SEC_E_ILLEGAL_MESSAGE
+# define SEC_E_ILLEGAL_MESSAGE                ((HRESULT)0x80090326L)
+#endif
+#ifndef SEC_E_CERT_UNKNOWN
+# define SEC_E_CERT_UNKNOWN                   ((HRESULT)0x80090327L)
+#endif
+#ifndef SEC_E_CERT_EXPIRED
+# define SEC_E_CERT_EXPIRED                   ((HRESULT)0x80090328L)
+#endif
+#ifndef SEC_E_ENCRYPT_FAILURE
+# define SEC_E_ENCRYPT_FAILURE                ((HRESULT)0x80090329L)
+#endif
+#ifndef SEC_E_DECRYPT_FAILURE
+# define SEC_E_DECRYPT_FAILURE                ((HRESULT)0x80090330L)
+#endif
+#ifndef SEC_E_ALGORITHM_MISMATCH
+# define SEC_E_ALGORITHM_MISMATCH             ((HRESULT)0x80090331L)
+#endif
+#ifndef SEC_E_SECURITY_QOS_FAILED
+# define SEC_E_SECURITY_QOS_FAILED            ((HRESULT)0x80090332L)
+#endif
+#ifndef SEC_E_UNFINISHED_CONTEXT_DELETED
+# define SEC_E_UNFINISHED_CONTEXT_DELETED     ((HRESULT)0x80090333L)
+#endif
+#ifndef SEC_E_NO_TGT_REPLY
+# define SEC_E_NO_TGT_REPLY                   ((HRESULT)0x80090334L)
+#endif
+#ifndef SEC_E_NO_IP_ADDRESSES
+# define SEC_E_NO_IP_ADDRESSES                ((HRESULT)0x80090335L)
+#endif
+#ifndef SEC_E_WRONG_CREDENTIAL_HANDLE
+# define SEC_E_WRONG_CREDENTIAL_HANDLE        ((HRESULT)0x80090336L)
+#endif
+#ifndef SEC_E_CRYPTO_SYSTEM_INVALID
+# define SEC_E_CRYPTO_SYSTEM_INVALID          ((HRESULT)0x80090337L)
+#endif
+#ifndef SEC_E_MAX_REFERRALS_EXCEEDED
+# define SEC_E_MAX_REFERRALS_EXCEEDED         ((HRESULT)0x80090338L)
+#endif
+#ifndef SEC_E_MUST_BE_KDC
+# define SEC_E_MUST_BE_KDC                    ((HRESULT)0x80090339L)
+#endif
+#ifndef SEC_E_STRONG_CRYPTO_NOT_SUPPORTED
+# define SEC_E_STRONG_CRYPTO_NOT_SUPPORTED    ((HRESULT)0x8009033AL)
+#endif
+#ifndef SEC_E_TOO_MANY_PRINCIPALS
+# define SEC_E_TOO_MANY_PRINCIPALS            ((HRESULT)0x8009033BL)
+#endif
+#ifndef SEC_E_NO_PA_DATA
+# define SEC_E_NO_PA_DATA                     ((HRESULT)0x8009033CL)
+#endif
+#ifndef SEC_E_PKINIT_NAME_MISMATCH
+# define SEC_E_PKINIT_NAME_MISMATCH           ((HRESULT)0x8009033DL)
+#endif
+#ifndef SEC_E_SMARTCARD_LOGON_REQUIRED
+# define SEC_E_SMARTCARD_LOGON_REQUIRED       ((HRESULT)0x8009033EL)
+#endif
+#ifndef SEC_E_SHUTDOWN_IN_PROGRESS
+# define SEC_E_SHUTDOWN_IN_PROGRESS           ((HRESULT)0x8009033FL)
+#endif
+#ifndef SEC_E_KDC_INVALID_REQUEST
+# define SEC_E_KDC_INVALID_REQUEST            ((HRESULT)0x80090340L)
+#endif
+#ifndef SEC_E_KDC_UNABLE_TO_REFER
+# define SEC_E_KDC_UNABLE_TO_REFER            ((HRESULT)0x80090341L)
+#endif
+#ifndef SEC_E_KDC_UNKNOWN_ETYPE
+# define SEC_E_KDC_UNKNOWN_ETYPE              ((HRESULT)0x80090342L)
+#endif
+#ifndef SEC_E_UNSUPPORTED_PREAUTH
+# define SEC_E_UNSUPPORTED_PREAUTH            ((HRESULT)0x80090343L)
+#endif
+#ifndef SEC_E_DELEGATION_REQUIRED
+# define SEC_E_DELEGATION_REQUIRED            ((HRESULT)0x80090345L)
+#endif
+#ifndef SEC_E_BAD_BINDINGS
+# define SEC_E_BAD_BINDINGS                   ((HRESULT)0x80090346L)
+#endif
+#ifndef SEC_E_MULTIPLE_ACCOUNTS
+# define SEC_E_MULTIPLE_ACCOUNTS              ((HRESULT)0x80090347L)
+#endif
+#ifndef SEC_E_NO_KERB_KEY
+# define SEC_E_NO_KERB_KEY                    ((HRESULT)0x80090348L)
+#endif
+#ifndef SEC_E_CERT_WRONG_USAGE
+# define SEC_E_CERT_WRONG_USAGE               ((HRESULT)0x80090349L)
+#endif
+#ifndef SEC_E_DOWNGRADE_DETECTED
+# define SEC_E_DOWNGRADE_DETECTED             ((HRESULT)0x80090350L)
+#endif
+#ifndef SEC_E_SMARTCARD_CERT_REVOKED
+# define SEC_E_SMARTCARD_CERT_REVOKED         ((HRESULT)0x80090351L)
+#endif
+#ifndef SEC_E_ISSUING_CA_UNTRUSTED
+# define SEC_E_ISSUING_CA_UNTRUSTED           ((HRESULT)0x80090352L)
+#endif
+#ifndef SEC_E_REVOCATION_OFFLINE_C
+# define SEC_E_REVOCATION_OFFLINE_C           ((HRESULT)0x80090353L)
+#endif
+#ifndef SEC_E_PKINIT_CLIENT_FAILURE
+# define SEC_E_PKINIT_CLIENT_FAILURE          ((HRESULT)0x80090354L)
+#endif
+#ifndef SEC_E_SMARTCARD_CERT_EXPIRED
+# define SEC_E_SMARTCARD_CERT_EXPIRED         ((HRESULT)0x80090355L)
+#endif
+#ifndef SEC_E_NO_S4U_PROT_SUPPORT
+# define SEC_E_NO_S4U_PROT_SUPPORT            ((HRESULT)0x80090356L)
+#endif
+#ifndef SEC_E_CROSSREALM_DELEGATION_FAILURE
+# define SEC_E_CROSSREALM_DELEGATION_FAILURE  ((HRESULT)0x80090357L)
+#endif
+#ifndef SEC_E_REVOCATION_OFFLINE_KDC
+# define SEC_E_REVOCATION_OFFLINE_KDC         ((HRESULT)0x80090358L)
+#endif
+#ifndef SEC_E_ISSUING_CA_UNTRUSTED_KDC
+# define SEC_E_ISSUING_CA_UNTRUSTED_KDC       ((HRESULT)0x80090359L)
+#endif
+#ifndef SEC_E_KDC_CERT_EXPIRED
+# define SEC_E_KDC_CERT_EXPIRED               ((HRESULT)0x8009035AL)
+#endif
+#ifndef SEC_E_KDC_CERT_REVOKED
+# define SEC_E_KDC_CERT_REVOKED               ((HRESULT)0x8009035BL)
+#endif
+#ifndef SEC_E_INVALID_PARAMETER
+# define SEC_E_INVALID_PARAMETER              ((HRESULT)0x8009035DL)
+#endif
+#ifndef SEC_E_DELEGATION_POLICY
+# define SEC_E_DELEGATION_POLICY              ((HRESULT)0x8009035EL)
+#endif
+#ifndef SEC_E_POLICY_NLTM_ONLY
+# define SEC_E_POLICY_NLTM_ONLY               ((HRESULT)0x8009035FL)
+#endif
+
+#ifndef SEC_I_CONTINUE_NEEDED
+# define SEC_I_CONTINUE_NEEDED                ((HRESULT)0x00090312L)
+#endif
+#ifndef SEC_I_COMPLETE_NEEDED
+# define SEC_I_COMPLETE_NEEDED                ((HRESULT)0x00090313L)
+#endif
+#ifndef SEC_I_COMPLETE_AND_CONTINUE
+# define SEC_I_COMPLETE_AND_CONTINUE          ((HRESULT)0x00090314L)
+#endif
+#ifndef SEC_I_LOCAL_LOGON
+# define SEC_I_LOCAL_LOGON                    ((HRESULT)0x00090315L)
+#endif
+#ifndef SEC_I_CONTEXT_EXPIRED
+# define SEC_I_CONTEXT_EXPIRED                ((HRESULT)0x00090317L)
+#endif
+#ifndef SEC_I_INCOMPLETE_CREDENTIALS
+# define SEC_I_INCOMPLETE_CREDENTIALS         ((HRESULT)0x00090320L)
+#endif
+#ifndef SEC_I_RENEGOTIATE
+# define SEC_I_RENEGOTIATE                    ((HRESULT)0x00090321L)
+#endif
+#ifndef SEC_I_NO_LSA_CONTEXT
+# define SEC_I_NO_LSA_CONTEXT                 ((HRESULT)0x00090323L)
+#endif
+#ifndef SEC_I_SIGNATURE_NEEDED
+# define SEC_I_SIGNATURE_NEEDED               ((HRESULT)0x0009035CL)
+#endif
+
+#ifndef CRYPT_E_REVOKED
+# define CRYPT_E_REVOKED                      ((HRESULT)0x80092010L)
+#endif
+
+#ifdef UNICODE
+#  define SECFLAG_WINNT_AUTH_IDENTITY \
+     (unsigned long)SEC_WINNT_AUTH_IDENTITY_UNICODE
+#else
+#  define SECFLAG_WINNT_AUTH_IDENTITY \
+     (unsigned long)SEC_WINNT_AUTH_IDENTITY_ANSI
+#endif
+
+/*
+ * Definitions required from ntsecapi.h are directly provided below this point
+ * to avoid including ntsecapi.h due to a conflict with OpenSSL's safestack.h
+ */
+#define KERB_WRAP_NO_ENCRYPT 0x80000001
+
+#endif /* USE_WINDOWS_SSPI */
+
+#endif /* HEADER_CURL_SSPI_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_threads.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_threads.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_threads.c	(revision 331)
@@ -0,0 +1,146 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#if defined(USE_THREADS_POSIX)
+#  ifdef HAVE_PTHREAD_H
+#    include <pthread.h>
+#  endif
+#elif defined(USE_THREADS_WIN32)
+#  ifdef HAVE_PROCESS_H
+#    include <process.h>
+#  endif
+#endif
+
+#include "curl_threads.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#if defined(USE_THREADS_POSIX)
+
+struct curl_actual_call {
+  unsigned int (*func)(void *);
+  void *arg;
+};
+
+static void *curl_thread_create_thunk(void *arg)
+{
+  struct curl_actual_call * ac = arg;
+  unsigned int (*func)(void *) = ac->func;
+  void *real_arg = ac->arg;
+
+  free(ac);
+
+  (*func)(real_arg);
+
+  return 0;
+}
+
+curl_thread_t Curl_thread_create(unsigned int (*func) (void *), void *arg)
+{
+  curl_thread_t t = malloc(sizeof(pthread_t));
+  struct curl_actual_call *ac = malloc(sizeof(struct curl_actual_call));
+  if(!(ac && t))
+    goto err;
+
+  ac->func = func;
+  ac->arg = arg;
+
+  if(pthread_create(t, NULL, curl_thread_create_thunk, ac) != 0)
+    goto err;
+
+  return t;
+
+err:
+  free(t);
+  free(ac);
+  return curl_thread_t_null;
+}
+
+void Curl_thread_destroy(curl_thread_t hnd)
+{
+  if(hnd != curl_thread_t_null) {
+    pthread_detach(*hnd);
+    free(hnd);
+  }
+}
+
+int Curl_thread_join(curl_thread_t *hnd)
+{
+  int ret = (pthread_join(**hnd, NULL) == 0);
+
+  free(*hnd);
+  *hnd = curl_thread_t_null;
+
+  return ret;
+}
+
+#elif defined(USE_THREADS_WIN32)
+
+/* !checksrc! disable SPACEBEFOREPAREN 1 */
+curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void *),
+                                 void *arg)
+{
+  curl_thread_t t;
+#ifdef _WIN32_WCE
+  t = CreateThread(NULL, 0, func, arg, 0, NULL);
+#else
+  t = (curl_thread_t)_beginthreadex(NULL, 0, func, arg, 0, NULL);
+#endif
+  if((t == 0) || (t == LongToHandle(-1L))) {
+#ifdef _WIN32_WCE
+    DWORD gle = GetLastError();
+    errno = ((gle == ERROR_ACCESS_DENIED ||
+              gle == ERROR_NOT_ENOUGH_MEMORY) ?
+             EACCES : EINVAL);
+#endif
+    return curl_thread_t_null;
+  }
+  return t;
+}
+
+void Curl_thread_destroy(curl_thread_t hnd)
+{
+  CloseHandle(hnd);
+}
+
+int Curl_thread_join(curl_thread_t *hnd)
+{
+#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \
+    (_WIN32_WINNT < _WIN32_WINNT_VISTA)
+  int ret = (WaitForSingleObject(*hnd, INFINITE) == WAIT_OBJECT_0);
+#else
+  int ret = (WaitForSingleObjectEx(*hnd, INFINITE, FALSE) == WAIT_OBJECT_0);
+#endif
+
+  Curl_thread_destroy(*hnd);
+
+  *hnd = curl_thread_t_null;
+
+  return ret;
+}
+
+#endif /* USE_THREADS_* */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curl_threads.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curl_threads.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curl_threads.h	(revision 331)
@@ -0,0 +1,63 @@
+#ifndef HEADER_CURL_THREADS_H
+#define HEADER_CURL_THREADS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if defined(USE_THREADS_POSIX)
+#  define CURL_STDCALL
+#  define curl_mutex_t           pthread_mutex_t
+#  define curl_thread_t          pthread_t *
+#  define curl_thread_t_null     (pthread_t *)0
+#  define Curl_mutex_init(m)     pthread_mutex_init(m, NULL)
+#  define Curl_mutex_acquire(m)  pthread_mutex_lock(m)
+#  define Curl_mutex_release(m)  pthread_mutex_unlock(m)
+#  define Curl_mutex_destroy(m)  pthread_mutex_destroy(m)
+#elif defined(USE_THREADS_WIN32)
+#  define CURL_STDCALL           __stdcall
+#  define curl_mutex_t           CRITICAL_SECTION
+#  define curl_thread_t          HANDLE
+#  define curl_thread_t_null     (HANDLE)0
+#  if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \
+      (_WIN32_WINNT < _WIN32_WINNT_VISTA)
+#    define Curl_mutex_init(m)   InitializeCriticalSection(m)
+#  else
+#    define Curl_mutex_init(m)   InitializeCriticalSectionEx(m, 0, 1)
+#  endif
+#  define Curl_mutex_acquire(m)  EnterCriticalSection(m)
+#  define Curl_mutex_release(m)  LeaveCriticalSection(m)
+#  define Curl_mutex_destroy(m)  DeleteCriticalSection(m)
+#endif
+
+#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
+
+/* !checksrc! disable SPACEBEFOREPAREN 1 */
+curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void *),
+                                 void *arg);
+
+void Curl_thread_destroy(curl_thread_t hnd);
+
+int Curl_thread_join(curl_thread_t *hnd);
+
+#endif /* USE_THREADS_POSIX || USE_THREADS_WIN32 */
+
+#endif /* HEADER_CURL_THREADS_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/curlx.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/curlx.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/curlx.h	(revision 331)
@@ -0,0 +1,105 @@
+#ifndef HEADER_CURL_CURLX_H
+#define HEADER_CURL_CURLX_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Defines protos and includes all header files that provide the curlx_*
+ * functions. The curlx_* functions are not part of the libcurl API, but are
+ * stand-alone functions whose sources can be built and linked by apps if need
+ * be.
+ */
+
+#include <curl/mprintf.h>
+/* this is still a public header file that provides the curl_mprintf()
+   functions while they still are offered publicly. They will be made library-
+   private one day */
+
+#include "strcase.h"
+/* "strcase.h" provides the strcasecompare protos */
+
+#include "strtoofft.h"
+/* "strtoofft.h" provides this function: curlx_strtoofft(), returns a
+   curl_off_t number from a given string.
+*/
+
+#include "nonblock.h"
+/* "nonblock.h" provides curlx_nonblock() */
+
+#include "warnless.h"
+/* "warnless.h" provides functions:
+
+  curlx_ultous()
+  curlx_ultouc()
+  curlx_uztosi()
+*/
+
+/* Now setup curlx_ * names for the functions that are to become curlx_ and
+   be removed from a future libcurl official API:
+   curlx_getenv
+   curlx_mprintf (and its variations)
+   curlx_strcasecompare
+   curlx_strncasecompare
+
+*/
+
+#define curlx_getenv curl_getenv
+#define curlx_mvsnprintf curl_mvsnprintf
+#define curlx_msnprintf curl_msnprintf
+#define curlx_maprintf curl_maprintf
+#define curlx_mvaprintf curl_mvaprintf
+#define curlx_msprintf curl_msprintf
+#define curlx_mprintf curl_mprintf
+#define curlx_mfprintf curl_mfprintf
+#define curlx_mvsprintf curl_mvsprintf
+#define curlx_mvprintf curl_mvprintf
+#define curlx_mvfprintf curl_mvfprintf
+
+#ifdef ENABLE_CURLX_PRINTF
+/* If this define is set, we define all "standard" printf() functions to use
+   the curlx_* version instead. It makes the source code transparent and
+   easier to understand/patch. Undefine them first. */
+# undef printf
+# undef fprintf
+# undef sprintf
+# undef snprintf
+# undef vprintf
+# undef vfprintf
+# undef vsprintf
+# undef vsnprintf
+# undef aprintf
+# undef vaprintf
+
+# define printf curlx_mprintf
+# define fprintf curlx_mfprintf
+# define sprintf curlx_msprintf
+# define snprintf curlx_msnprintf
+# define vprintf curlx_mvprintf
+# define vfprintf curlx_mvfprintf
+# define vsprintf curlx_mvsprintf
+# define vsnprintf curlx_mvsnprintf
+# define aprintf curlx_maprintf
+# define vaprintf curlx_mvaprintf
+#endif /* ENABLE_CURLX_PRINTF */
+
+#endif /* HEADER_CURL_CURLX_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/dict.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/dict.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/dict.c	(revision 331)
@@ -0,0 +1,279 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_DICT
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "sendf.h"
+#include "escape.h"
+#include "progress.h"
+#include "dict.h"
+#include "strcase.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Forward declarations.
+ */
+
+static CURLcode dict_do(struct connectdata *conn, bool *done);
+
+/*
+ * DICT protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_dict = {
+  "DICT",                               /* scheme */
+  ZERO_NULL,                            /* setup_connection */
+  dict_do,                              /* do_it */
+  ZERO_NULL,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_DICT,                            /* defport */
+  CURLPROTO_DICT,                       /* protocol */
+  PROTOPT_NONE | PROTOPT_NOURLQUERY      /* flags */
+};
+
+static char *unescape_word(struct Curl_easy *data, const char *inputbuff)
+{
+  char *newp = NULL;
+  char *dictp;
+  char *ptr;
+  size_t len;
+  char ch;
+  int olen = 0;
+
+  CURLcode result = Curl_urldecode(data, inputbuff, 0, &newp, &len, FALSE);
+  if(!newp || result)
+    return NULL;
+
+  dictp = malloc(((size_t)len)*2 + 1); /* add one for terminating zero */
+  if(dictp) {
+    /* According to RFC2229 section 2.2, these letters need to be escaped with
+       \[letter] */
+    for(ptr = newp;
+        (ch = *ptr) != 0;
+        ptr++) {
+      if((ch <= 32) || (ch == 127) ||
+          (ch == '\'') || (ch == '\"') || (ch == '\\')) {
+        dictp[olen++] = '\\';
+      }
+      dictp[olen++] = ch;
+    }
+    dictp[olen] = 0;
+  }
+  free(newp);
+  return dictp;
+}
+
+static CURLcode dict_do(struct connectdata *conn, bool *done)
+{
+  char *word;
+  char *eword;
+  char *ppath;
+  char *database = NULL;
+  char *strategy = NULL;
+  char *nthdef = NULL; /* This is not part of the protocol, but required
+                          by RFC 2229 */
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+
+  char *path = data->state.path;
+  curl_off_t *bytecount = &data->req.bytecount;
+
+  *done = TRUE; /* unconditionally */
+
+  if(conn->bits.user_passwd) {
+    /* AUTH is missing */
+  }
+
+  if(strncasecompare(path, DICT_MATCH, sizeof(DICT_MATCH)-1) ||
+     strncasecompare(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) ||
+     strncasecompare(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) {
+
+    word = strchr(path, ':');
+    if(word) {
+      word++;
+      database = strchr(word, ':');
+      if(database) {
+        *database++ = (char)0;
+        strategy = strchr(database, ':');
+        if(strategy) {
+          *strategy++ = (char)0;
+          nthdef = strchr(strategy, ':');
+          if(nthdef) {
+            *nthdef = (char)0;
+          }
+        }
+      }
+    }
+
+    if((word == NULL) || (*word == (char)0)) {
+      infof(data, "lookup word is missing\n");
+      word = (char *)"default";
+    }
+    if((database == NULL) || (*database == (char)0)) {
+      database = (char *)"!";
+    }
+    if((strategy == NULL) || (*strategy == (char)0)) {
+      strategy = (char *)".";
+    }
+
+    eword = unescape_word(data, word);
+    if(!eword)
+      return CURLE_OUT_OF_MEMORY;
+
+    result = Curl_sendf(sockfd, conn,
+                        "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
+                        "MATCH "
+                        "%s "    /* database */
+                        "%s "    /* strategy */
+                        "%s\r\n" /* word */
+                        "QUIT\r\n",
+
+                        database,
+                        strategy,
+                        eword
+                        );
+
+    free(eword);
+
+    if(result) {
+      failf(data, "Failed sending DICT request");
+      return result;
+    }
+    Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
+                        -1, NULL); /* no upload */
+  }
+  else if(strncasecompare(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) ||
+          strncasecompare(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) ||
+          strncasecompare(path, DICT_DEFINE3, sizeof(DICT_DEFINE3)-1)) {
+
+    word = strchr(path, ':');
+    if(word) {
+      word++;
+      database = strchr(word, ':');
+      if(database) {
+        *database++ = (char)0;
+        nthdef = strchr(database, ':');
+        if(nthdef) {
+          *nthdef = (char)0;
+        }
+      }
+    }
+
+    if((word == NULL) || (*word == (char)0)) {
+      infof(data, "lookup word is missing\n");
+      word = (char *)"default";
+    }
+    if((database == NULL) || (*database == (char)0)) {
+      database = (char *)"!";
+    }
+
+    eword = unescape_word(data, word);
+    if(!eword)
+      return CURLE_OUT_OF_MEMORY;
+
+    result = Curl_sendf(sockfd, conn,
+                        "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
+                        "DEFINE "
+                        "%s "     /* database */
+                        "%s\r\n"  /* word */
+                        "QUIT\r\n",
+                        database,
+                        eword);
+
+    free(eword);
+
+    if(result) {
+      failf(data, "Failed sending DICT request");
+      return result;
+    }
+    Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
+                        -1, NULL); /* no upload */
+  }
+  else {
+
+    ppath = strchr(path, '/');
+    if(ppath) {
+      int i;
+
+      ppath++;
+      for(i = 0; ppath[i]; i++) {
+        if(ppath[i] == ':')
+          ppath[i] = ' ';
+      }
+      result = Curl_sendf(sockfd, conn,
+                          "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n"
+                          "%s\r\n"
+                          "QUIT\r\n", ppath);
+      if(result) {
+        failf(data, "Failed sending DICT request");
+        return result;
+      }
+
+      Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount, -1, NULL);
+    }
+  }
+
+  return CURLE_OK;
+}
+#endif /*CURL_DISABLE_DICT*/
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/dict.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/dict.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/dict.h	(revision 331)
@@ -0,0 +1,29 @@
+#ifndef HEADER_CURL_DICT_H
+#define HEADER_CURL_DICT_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifndef CURL_DISABLE_DICT
+extern const struct Curl_handler Curl_handler_dict;
+#endif
+
+#endif /* HEADER_CURL_DICT_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/dotdot.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/dotdot.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/dotdot.c	(revision 331)
@@ -0,0 +1,180 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "dotdot.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * "Remove Dot Segments"
+ * https://tools.ietf.org/html/rfc3986#section-5.2.4
+ */
+
+/*
+ * Curl_dedotdotify()
+ * @unittest: 1395
+ *
+ * This function gets a zero-terminated path with dot and dotdot sequences
+ * passed in and strips them off according to the rules in RFC 3986 section
+ * 5.2.4.
+ *
+ * The function handles a query part ('?' + stuff) appended but it expects
+ * that fragments ('#' + stuff) have already been cut off.
+ *
+ * RETURNS
+ *
+ * an allocated dedotdotified output string
+ */
+char *Curl_dedotdotify(const char *input)
+{
+  size_t inlen = strlen(input);
+  char *clone;
+  size_t clen = inlen; /* the length of the cloned input */
+  char *out = malloc(inlen + 1);
+  char *outptr;
+  char *orgclone;
+  char *queryp;
+  if(!out)
+    return NULL; /* out of memory */
+
+  /* get a cloned copy of the input */
+  clone = strdup(input);
+  if(!clone) {
+    free(out);
+    return NULL;
+  }
+  orgclone = clone;
+  outptr = out;
+
+  if(!*clone) {
+    /* zero length string, return that */
+    free(out);
+    return clone;
+  }
+
+  /*
+   * To handle query-parts properly, we must find it and remove it during the
+   * dotdot-operation and then append it again at the end to the output
+   * string.
+   */
+  queryp = strchr(clone, '?');
+  if(queryp)
+    *queryp = 0;
+
+  do {
+
+    /*  A.  If the input buffer begins with a prefix of "../" or "./", then
+        remove that prefix from the input buffer; otherwise, */
+
+    if(!strncmp("./", clone, 2)) {
+      clone += 2;
+      clen -= 2;
+    }
+    else if(!strncmp("../", clone, 3)) {
+      clone += 3;
+      clen -= 3;
+    }
+
+    /*  B.  if the input buffer begins with a prefix of "/./" or "/.", where
+        "."  is a complete path segment, then replace that prefix with "/" in
+        the input buffer; otherwise, */
+    else if(!strncmp("/./", clone, 3)) {
+      clone += 2;
+      clen -= 2;
+    }
+    else if(!strcmp("/.", clone)) {
+      clone[1]='/';
+      clone++;
+      clen -= 1;
+    }
+
+    /*  C.  if the input buffer begins with a prefix of "/../" or "/..", where
+        ".." is a complete path segment, then replace that prefix with "/" in
+        the input buffer and remove the last segment and its preceding "/" (if
+        any) from the output buffer; otherwise, */
+
+    else if(!strncmp("/../", clone, 4)) {
+      clone += 3;
+      clen -= 3;
+      /* remove the last segment from the output buffer */
+      while(outptr > out) {
+        outptr--;
+        if(*outptr == '/')
+          break;
+      }
+      *outptr = 0; /* zero-terminate where it stops */
+    }
+    else if(!strcmp("/..", clone)) {
+      clone[2]='/';
+      clone += 2;
+      clen -= 2;
+      /* remove the last segment from the output buffer */
+      while(outptr > out) {
+        outptr--;
+        if(*outptr == '/')
+          break;
+      }
+      *outptr = 0; /* zero-terminate where it stops */
+    }
+
+    /*  D.  if the input buffer consists only of "." or "..", then remove
+        that from the input buffer; otherwise, */
+
+    else if(!strcmp(".", clone) || !strcmp("..", clone)) {
+      *clone = 0;
+      *out = 0;
+    }
+
+    else {
+      /*  E.  move the first path segment in the input buffer to the end of
+          the output buffer, including the initial "/" character (if any) and
+          any subsequent characters up to, but not including, the next "/"
+          character or the end of the input buffer. */
+
+      do {
+        *outptr++ = *clone++;
+        clen--;
+      } while(*clone && (*clone != '/'));
+      *outptr = 0;
+    }
+
+  } while(*clone);
+
+  if(queryp) {
+    size_t qlen;
+    /* There was a query part, append that to the output. The 'clone' string
+       may now have been altered so we copy from the original input string
+       from the correct index. */
+    size_t oindex = queryp - orgclone;
+    qlen = strlen(&input[oindex]);
+    memcpy(outptr, &input[oindex], qlen + 1); /* include the end zero byte */
+  }
+
+  free(orgclone);
+  return out;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/dotdot.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/dotdot.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/dotdot.h	(revision 331)
@@ -0,0 +1,25 @@
+#ifndef HEADER_CURL_DOTDOT_H
+#define HEADER_CURL_DOTDOT_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+char *Curl_dedotdotify(const char *input);
+#endif
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/easy.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/easy.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/easy.c	(revision 331)
@@ -0,0 +1,1150 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+/*
+ * See comment in curl_memory.h for the explanation of this sanity check.
+ */
+
+#ifdef CURLX_NO_MEMORY_CALLBACKS
+#error "libcurl shall not ever be built with CURLX_NO_MEMORY_CALLBACKS defined"
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "vtls/vtls.h"
+#include "url.h"
+#include "getinfo.h"
+#include "hostip.h"
+#include "share.h"
+#include "strdup.h"
+#include "progress.h"
+#include "easyif.h"
+#include "select.h"
+#include "sendf.h" /* for failf function prototype */
+#include "connect.h" /* for Curl_getconnectinfo */
+#include "slist.h"
+#include "amigaos.h"
+#include "non-ascii.h"
+#include "warnless.h"
+#include "multiif.h"
+#include "sigpipe.h"
+#include "ssh.h"
+#include "setopt.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+void Curl_version_init(void);
+
+/* win32_cleanup() is for win32 socket cleanup functionality, the opposite
+   of win32_init() */
+static void win32_cleanup(void)
+{
+#ifdef USE_WINSOCK
+  WSACleanup();
+#endif
+#ifdef USE_WINDOWS_SSPI
+  Curl_sspi_global_cleanup();
+#endif
+}
+
+/* win32_init() performs win32 socket initialization to properly setup the
+   stack to allow networking */
+static CURLcode win32_init(void)
+{
+#ifdef USE_WINSOCK
+  WORD wVersionRequested;
+  WSADATA wsaData;
+  int res;
+
+#if defined(ENABLE_IPV6) && (USE_WINSOCK < 2)
+  Error IPV6_requires_winsock2
+#endif
+
+  wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK);
+
+  res = WSAStartup(wVersionRequested, &wsaData);
+
+  if(res != 0)
+    /* Tell the user that we couldn't find a useable */
+    /* winsock.dll.     */
+    return CURLE_FAILED_INIT;
+
+  /* Confirm that the Windows Sockets DLL supports what we need.*/
+  /* Note that if the DLL supports versions greater */
+  /* than wVersionRequested, it will still return */
+  /* wVersionRequested in wVersion. wHighVersion contains the */
+  /* highest supported version. */
+
+  if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
+     HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) {
+    /* Tell the user that we couldn't find a useable */
+
+    /* winsock.dll. */
+    WSACleanup();
+    return CURLE_FAILED_INIT;
+  }
+  /* The Windows Sockets DLL is acceptable. Proceed. */
+#elif defined(USE_LWIPSOCK)
+  lwip_init();
+#endif
+
+#ifdef USE_WINDOWS_SSPI
+  {
+    CURLcode result = Curl_sspi_global_init();
+    if(result)
+      return result;
+  }
+#endif
+
+  return CURLE_OK;
+}
+
+/* true globals -- for curl_global_init() and curl_global_cleanup() */
+static unsigned int  initialized;
+static long          init_flags;
+
+/*
+ * strdup (and other memory functions) is redefined in complicated
+ * ways, but at this point it must be defined as the system-supplied strdup
+ * so the callback pointer is initialized correctly.
+ */
+#if defined(_WIN32_WCE)
+#define system_strdup _strdup
+#elif !defined(HAVE_STRDUP)
+#define system_strdup curlx_strdup
+#else
+#define system_strdup strdup
+#endif
+
+#if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
+#  pragma warning(disable:4232) /* MSVC extension, dllimport identity */
+#endif
+
+#ifndef __SYMBIAN32__
+/*
+ * If a memory-using function (like curl_getenv) is used before
+ * curl_global_init() is called, we need to have these pointers set already.
+ */
+curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc;
+curl_free_callback Curl_cfree = (curl_free_callback)free;
+curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc;
+curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup;
+curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc;
+#if defined(WIN32) && defined(UNICODE)
+curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
+#endif
+#else
+/*
+ * Symbian OS doesn't support initialization to code in writable static data.
+ * Initialization will occur in the curl_global_init() call.
+ */
+curl_malloc_callback Curl_cmalloc;
+curl_free_callback Curl_cfree;
+curl_realloc_callback Curl_crealloc;
+curl_strdup_callback Curl_cstrdup;
+curl_calloc_callback Curl_ccalloc;
+#endif
+
+#if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__)
+#  pragma warning(default:4232) /* MSVC extension, dllimport identity */
+#endif
+
+/**
+ * curl_global_init() globally initializes curl given a bitwise set of the
+ * different features of what to initialize.
+ */
+static CURLcode global_init(long flags, bool memoryfuncs)
+{
+  if(initialized++)
+    return CURLE_OK;
+
+  if(memoryfuncs) {
+    /* Setup the default memory functions here (again) */
+    Curl_cmalloc = (curl_malloc_callback)malloc;
+    Curl_cfree = (curl_free_callback)free;
+    Curl_crealloc = (curl_realloc_callback)realloc;
+    Curl_cstrdup = (curl_strdup_callback)system_strdup;
+    Curl_ccalloc = (curl_calloc_callback)calloc;
+#if defined(WIN32) && defined(UNICODE)
+    Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup;
+#endif
+  }
+
+  if(!Curl_ssl_init()) {
+    DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n"));
+    return CURLE_FAILED_INIT;
+  }
+
+  if(flags & CURL_GLOBAL_WIN32)
+    if(win32_init()) {
+      DEBUGF(fprintf(stderr, "Error: win32_init failed\n"));
+      return CURLE_FAILED_INIT;
+    }
+
+#ifdef __AMIGA__
+  if(!Curl_amiga_init()) {
+    DEBUGF(fprintf(stderr, "Error: Curl_amiga_init failed\n"));
+    return CURLE_FAILED_INIT;
+  }
+#endif
+
+#ifdef NETWARE
+  if(netware_init()) {
+    DEBUGF(fprintf(stderr, "Warning: LONG namespace not available\n"));
+  }
+#endif
+
+  if(Curl_resolver_global_init()) {
+    DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
+    return CURLE_FAILED_INIT;
+  }
+
+  (void)Curl_ipv6works();
+
+#if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_INIT)
+  if(libssh2_init(0)) {
+    DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n"));
+    return CURLE_FAILED_INIT;
+  }
+#endif
+
+  if(flags & CURL_GLOBAL_ACK_EINTR)
+    Curl_ack_eintr = 1;
+
+  init_flags = flags;
+
+  Curl_version_init();
+
+  return CURLE_OK;
+}
+
+
+/**
+ * curl_global_init() globally initializes curl given a bitwise set of the
+ * different features of what to initialize.
+ */
+CURLcode curl_global_init(long flags)
+{
+  return global_init(flags, TRUE);
+}
+
+/*
+ * curl_global_init_mem() globally initializes curl and also registers the
+ * user provided callback routines.
+ */
+CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
+                              curl_free_callback f, curl_realloc_callback r,
+                              curl_strdup_callback s, curl_calloc_callback c)
+{
+  /* Invalid input, return immediately */
+  if(!m || !f || !r || !s || !c)
+    return CURLE_FAILED_INIT;
+
+  if(initialized) {
+    /* Already initialized, don't do it again, but bump the variable anyway to
+       work like curl_global_init() and require the same amount of cleanup
+       calls. */
+    initialized++;
+    return CURLE_OK;
+  }
+
+  /* set memory functions before global_init() in case it wants memory
+     functions */
+  Curl_cmalloc = m;
+  Curl_cfree = f;
+  Curl_cstrdup = s;
+  Curl_crealloc = r;
+  Curl_ccalloc = c;
+
+  /* Call the actual init function, but without setting */
+  return global_init(flags, FALSE);
+}
+
+/**
+ * curl_global_cleanup() globally cleanups curl, uses the value of
+ * "init_flags" to determine what needs to be cleaned up and what doesn't.
+ */
+void curl_global_cleanup(void)
+{
+  if(!initialized)
+    return;
+
+  if(--initialized)
+    return;
+
+  Curl_global_host_cache_dtor();
+  Curl_ssl_cleanup();
+  Curl_resolver_global_cleanup();
+
+  if(init_flags & CURL_GLOBAL_WIN32)
+    win32_cleanup();
+
+  Curl_amiga_cleanup();
+
+#if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_EXIT)
+  (void)libssh2_exit();
+#endif
+
+  init_flags  = 0;
+}
+
+/*
+ * curl_easy_init() is the external interface to alloc, setup and init an
+ * easy handle that is returned. If anything goes wrong, NULL is returned.
+ */
+struct Curl_easy *curl_easy_init(void)
+{
+  CURLcode result;
+  struct Curl_easy *data;
+
+  /* Make sure we inited the global SSL stuff */
+  if(!initialized) {
+    result = curl_global_init(CURL_GLOBAL_DEFAULT);
+    if(result) {
+      /* something in the global init failed, return nothing */
+      DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n"));
+      return NULL;
+    }
+  }
+
+  /* We use curl_open() with undefined URL so far */
+  result = Curl_open(&data);
+  if(result) {
+    DEBUGF(fprintf(stderr, "Error: Curl_open failed\n"));
+    return NULL;
+  }
+
+  return data;
+}
+
+#ifdef CURLDEBUG
+
+struct socketmonitor {
+  struct socketmonitor *next; /* the next node in the list or NULL */
+  struct pollfd socket; /* socket info of what to monitor */
+};
+
+struct events {
+  long ms;              /* timeout, run the timeout function when reached */
+  bool msbump;          /* set TRUE when timeout is set by callback */
+  int num_sockets;      /* number of nodes in the monitor list */
+  struct socketmonitor *list; /* list of sockets to monitor */
+  int running_handles;  /* store the returned number */
+};
+
+/* events_timer
+ *
+ * Callback that gets called with a new value when the timeout should be
+ * updated.
+ */
+
+static int events_timer(struct Curl_multi *multi,    /* multi handle */
+                        long timeout_ms, /* see above */
+                        void *userp)    /* private callback pointer */
+{
+  struct events *ev = userp;
+  (void)multi;
+  if(timeout_ms == -1)
+    /* timeout removed */
+    timeout_ms = 0;
+  else if(timeout_ms == 0)
+    /* timeout is already reached! */
+    timeout_ms = 1; /* trigger asap */
+
+  ev->ms = timeout_ms;
+  ev->msbump = TRUE;
+  return 0;
+}
+
+
+/* poll2cselect
+ *
+ * convert from poll() bit definitions to libcurl's CURL_CSELECT_* ones
+ */
+static int poll2cselect(int pollmask)
+{
+  int omask = 0;
+  if(pollmask & POLLIN)
+    omask |= CURL_CSELECT_IN;
+  if(pollmask & POLLOUT)
+    omask |= CURL_CSELECT_OUT;
+  if(pollmask & POLLERR)
+    omask |= CURL_CSELECT_ERR;
+  return omask;
+}
+
+
+/* socketcb2poll
+ *
+ * convert from libcurl' CURL_POLL_* bit definitions to poll()'s
+ */
+static short socketcb2poll(int pollmask)
+{
+  short omask = 0;
+  if(pollmask & CURL_POLL_IN)
+    omask |= POLLIN;
+  if(pollmask & CURL_POLL_OUT)
+    omask |= POLLOUT;
+  return omask;
+}
+
+/* events_socket
+ *
+ * Callback that gets called with information about socket activity to
+ * monitor.
+ */
+static int events_socket(struct Curl_easy *easy,      /* easy handle */
+                         curl_socket_t s, /* socket */
+                         int what,        /* see above */
+                         void *userp,     /* private callback
+                                             pointer */
+                         void *socketp)   /* private socket
+                                             pointer */
+{
+  struct events *ev = userp;
+  struct socketmonitor *m;
+  struct socketmonitor *prev = NULL;
+
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void) easy;
+#endif
+  (void)socketp;
+
+  m = ev->list;
+  while(m) {
+    if(m->socket.fd == s) {
+
+      if(what == CURL_POLL_REMOVE) {
+        struct socketmonitor *nxt = m->next;
+        /* remove this node from the list of monitored sockets */
+        if(prev)
+          prev->next = nxt;
+        else
+          ev->list = nxt;
+        free(m);
+        m = nxt;
+        infof(easy, "socket cb: socket %d REMOVED\n", s);
+      }
+      else {
+        /* The socket 's' is already being monitored, update the activity
+           mask. Convert from libcurl bitmask to the poll one. */
+        m->socket.events = socketcb2poll(what);
+        infof(easy, "socket cb: socket %d UPDATED as %s%s\n", s,
+              what&CURL_POLL_IN?"IN":"",
+              what&CURL_POLL_OUT?"OUT":"");
+      }
+      break;
+    }
+    prev = m;
+    m = m->next; /* move to next node */
+  }
+  if(!m) {
+    if(what == CURL_POLL_REMOVE) {
+      /* this happens a bit too often, libcurl fix perhaps? */
+      /* fprintf(stderr,
+         "%s: socket %d asked to be REMOVED but not present!\n",
+                 __func__, s); */
+    }
+    else {
+      m = malloc(sizeof(struct socketmonitor));
+      if(m) {
+        m->next = ev->list;
+        m->socket.fd = s;
+        m->socket.events = socketcb2poll(what);
+        m->socket.revents = 0;
+        ev->list = m;
+        infof(easy, "socket cb: socket %d ADDED as %s%s\n", s,
+              what&CURL_POLL_IN?"IN":"",
+              what&CURL_POLL_OUT?"OUT":"");
+      }
+      else
+        return CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  return 0;
+}
+
+
+/*
+ * events_setup()
+ *
+ * Do the multi handle setups that only event-based transfers need.
+ */
+static void events_setup(struct Curl_multi *multi, struct events *ev)
+{
+  /* timer callback */
+  curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, events_timer);
+  curl_multi_setopt(multi, CURLMOPT_TIMERDATA, ev);
+
+  /* socket callback */
+  curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, events_socket);
+  curl_multi_setopt(multi, CURLMOPT_SOCKETDATA, ev);
+}
+
+
+/* wait_or_timeout()
+ *
+ * waits for activity on any of the given sockets, or the timeout to trigger.
+ */
+
+static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
+{
+  bool done = FALSE;
+  CURLMcode mcode = CURLM_OK;
+  CURLcode result = CURLE_OK;
+
+  while(!done) {
+    CURLMsg *msg;
+    struct socketmonitor *m;
+    struct pollfd *f;
+    struct pollfd fds[4];
+    int numfds = 0;
+    int pollrc;
+    int i;
+    struct curltime before;
+    struct curltime after;
+
+    /* populate the fds[] array */
+    for(m = ev->list, f = &fds[0]; m; m = m->next) {
+      f->fd = m->socket.fd;
+      f->events = m->socket.events;
+      f->revents = 0;
+      /* fprintf(stderr, "poll() %d check socket %d\n", numfds, f->fd); */
+      f++;
+      numfds++;
+    }
+
+    /* get the time stamp to use to figure out how long poll takes */
+    before = Curl_now();
+
+    /* wait for activity or timeout */
+    pollrc = Curl_poll(fds, numfds, (int)ev->ms);
+
+    after = Curl_now();
+
+    ev->msbump = FALSE; /* reset here */
+
+    if(0 == pollrc) {
+      /* timeout! */
+      ev->ms = 0;
+      /* fprintf(stderr, "call curl_multi_socket_action(TIMEOUT)\n"); */
+      mcode = curl_multi_socket_action(multi, CURL_SOCKET_TIMEOUT, 0,
+                                       &ev->running_handles);
+    }
+    else if(pollrc > 0) {
+      /* loop over the monitored sockets to see which ones had activity */
+      for(i = 0; i< numfds; i++) {
+        if(fds[i].revents) {
+          /* socket activity, tell libcurl */
+          int act = poll2cselect(fds[i].revents); /* convert */
+          infof(multi->easyp, "call curl_multi_socket_action(socket %d)\n",
+                fds[i].fd);
+          mcode = curl_multi_socket_action(multi, fds[i].fd, act,
+                                           &ev->running_handles);
+        }
+      }
+
+      if(!ev->msbump) {
+        /* If nothing updated the timeout, we decrease it by the spent time.
+         * If it was updated, it has the new timeout time stored already.
+         */
+        timediff_t timediff = Curl_timediff(after, before);
+        if(timediff > 0) {
+          if(timediff > ev->ms)
+            ev->ms = 0;
+          else
+            ev->ms -= (long)timediff;
+        }
+      }
+    }
+    else
+      return CURLE_RECV_ERROR;
+
+    if(mcode)
+      return CURLE_URL_MALFORMAT; /* TODO: return a proper error! */
+
+    /* we don't really care about the "msgs_in_queue" value returned in the
+       second argument */
+    msg = curl_multi_info_read(multi, &pollrc);
+    if(msg) {
+      result = msg->data.result;
+      done = TRUE;
+    }
+  }
+
+  return result;
+}
+
+
+/* easy_events()
+ *
+ * Runs a transfer in a blocking manner using the events-based API
+ */
+static CURLcode easy_events(struct Curl_multi *multi)
+{
+  /* this struct is made static to allow it to be used after this function
+     returns and curl_multi_remove_handle() is called */
+  static struct events evs = {2, FALSE, 0, NULL, 0};
+
+  /* if running event-based, do some further multi inits */
+  events_setup(multi, &evs);
+
+  return wait_or_timeout(multi, &evs);
+}
+#else /* CURLDEBUG */
+/* when not built with debug, this function doesn't exist */
+#define easy_events(x) CURLE_NOT_BUILT_IN
+#endif
+
+static CURLcode easy_transfer(struct Curl_multi *multi)
+{
+  bool done = FALSE;
+  CURLMcode mcode = CURLM_OK;
+  CURLcode result = CURLE_OK;
+  struct curltime before;
+  int without_fds = 0;  /* count number of consecutive returns from
+                           curl_multi_wait() without any filedescriptors */
+
+  while(!done && !mcode) {
+    int still_running = 0;
+    int rc;
+
+    before = Curl_now();
+    mcode = curl_multi_wait(multi, NULL, 0, 1000, &rc);
+
+    if(!mcode) {
+      if(!rc) {
+        struct curltime after = Curl_now();
+
+        /* If it returns without any filedescriptor instantly, we need to
+           avoid busy-looping during periods where it has nothing particular
+           to wait for */
+        if(Curl_timediff(after, before) <= 10) {
+          without_fds++;
+          if(without_fds > 2) {
+            int sleep_ms = without_fds < 10 ? (1 << (without_fds - 1)) : 1000;
+            Curl_wait_ms(sleep_ms);
+          }
+        }
+        else
+          /* it wasn't "instant", restart counter */
+          without_fds = 0;
+      }
+      else
+        /* got file descriptor, restart counter */
+        without_fds = 0;
+
+      mcode = curl_multi_perform(multi, &still_running);
+    }
+
+    /* only read 'still_running' if curl_multi_perform() return OK */
+    if(!mcode && !still_running) {
+      CURLMsg *msg = curl_multi_info_read(multi, &rc);
+      if(msg) {
+        result = msg->data.result;
+        done = TRUE;
+      }
+    }
+  }
+
+  /* Make sure to return some kind of error if there was a multi problem */
+  if(mcode) {
+    result = (mcode == CURLM_OUT_OF_MEMORY) ? CURLE_OUT_OF_MEMORY :
+              /* The other multi errors should never happen, so return
+                 something suitably generic */
+              CURLE_BAD_FUNCTION_ARGUMENT;
+  }
+
+  return result;
+}
+
+
+/*
+ * easy_perform() is the external interface that performs a blocking
+ * transfer as previously setup.
+ *
+ * CONCEPT: This function creates a multi handle, adds the easy handle to it,
+ * runs curl_multi_perform() until the transfer is done, then detaches the
+ * easy handle, destroys the multi handle and returns the easy handle's return
+ * code.
+ *
+ * REALITY: it can't just create and destroy the multi handle that easily. It
+ * needs to keep it around since if this easy handle is used again by this
+ * function, the same multi handle must be re-used so that the same pools and
+ * caches can be used.
+ *
+ * DEBUG: if 'events' is set TRUE, this function will use a replacement engine
+ * instead of curl_multi_perform() and use curl_multi_socket_action().
+ */
+static CURLcode easy_perform(struct Curl_easy *data, bool events)
+{
+  struct Curl_multi *multi;
+  CURLMcode mcode;
+  CURLcode result = CURLE_OK;
+  SIGPIPE_VARIABLE(pipe_st);
+
+  if(!data)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  if(data->multi) {
+    failf(data, "easy handle already used in multi handle");
+    return CURLE_FAILED_INIT;
+  }
+
+  if(data->multi_easy)
+    multi = data->multi_easy;
+  else {
+    /* this multi handle will only ever have a single easy handled attached
+       to it, so make it use minimal hashes */
+    multi = Curl_multi_handle(1, 3);
+    if(!multi)
+      return CURLE_OUT_OF_MEMORY;
+    data->multi_easy = multi;
+  }
+
+  /* Copy the MAXCONNECTS option to the multi handle */
+  curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, data->set.maxconnects);
+
+  mcode = curl_multi_add_handle(multi, data);
+  if(mcode) {
+    curl_multi_cleanup(multi);
+    if(mcode == CURLM_OUT_OF_MEMORY)
+      return CURLE_OUT_OF_MEMORY;
+    return CURLE_FAILED_INIT;
+  }
+
+  sigpipe_ignore(data, &pipe_st);
+
+  /* assign this after curl_multi_add_handle() since that function checks for
+     it and rejects this handle otherwise */
+  data->multi = multi;
+
+  /* run the transfer */
+  result = events ? easy_events(multi) : easy_transfer(multi);
+
+  /* ignoring the return code isn't nice, but atm we can't really handle
+     a failure here, room for future improvement! */
+  (void)curl_multi_remove_handle(multi, data);
+
+  sigpipe_restore(&pipe_st);
+
+  /* The multi handle is kept alive, owned by the easy handle */
+  return result;
+}
+
+
+/*
+ * curl_easy_perform() is the external interface that performs a blocking
+ * transfer as previously setup.
+ */
+CURLcode curl_easy_perform(struct Curl_easy *data)
+{
+  return easy_perform(data, FALSE);
+}
+
+#ifdef CURLDEBUG
+/*
+ * curl_easy_perform_ev() is the external interface that performs a blocking
+ * transfer using the event-based API internally.
+ */
+CURLcode curl_easy_perform_ev(struct Curl_easy *data)
+{
+  return easy_perform(data, TRUE);
+}
+
+#endif
+
+/*
+ * curl_easy_cleanup() is the external interface to cleaning/freeing the given
+ * easy handle.
+ */
+void curl_easy_cleanup(struct Curl_easy *data)
+{
+  SIGPIPE_VARIABLE(pipe_st);
+
+  if(!data)
+    return;
+
+  sigpipe_ignore(data, &pipe_st);
+  Curl_close(data);
+  sigpipe_restore(&pipe_st);
+}
+
+/*
+ * curl_easy_getinfo() is an external interface that allows an app to retrieve
+ * information from a performed transfer and similar.
+ */
+#undef curl_easy_getinfo
+CURLcode curl_easy_getinfo(struct Curl_easy *data, CURLINFO info, ...)
+{
+  va_list arg;
+  void *paramp;
+  CURLcode result;
+
+  va_start(arg, info);
+  paramp = va_arg(arg, void *);
+
+  result = Curl_getinfo(data, info, paramp);
+
+  va_end(arg);
+  return result;
+}
+
+static CURLcode dupset(struct Curl_easy *dst, struct Curl_easy *src)
+{
+  CURLcode result = CURLE_OK;
+  enum dupstring i;
+
+  /* Copy src->set into dst->set first, then deal with the strings
+     afterwards */
+  dst->set = src->set;
+
+  /* clear all string pointers first */
+  memset(dst->set.str, 0, STRING_LAST * sizeof(char *));
+
+  /* duplicate all strings */
+  for(i = (enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) {
+    result = Curl_setstropt(&dst->set.str[i], src->set.str[i]);
+    if(result)
+      return result;
+  }
+
+  /* duplicate memory areas pointed to */
+  i = STRING_COPYPOSTFIELDS;
+  if(src->set.postfieldsize && src->set.str[i]) {
+    /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */
+    dst->set.str[i] = Curl_memdup(src->set.str[i],
+                                  curlx_sotouz(src->set.postfieldsize));
+    if(!dst->set.str[i])
+      return CURLE_OUT_OF_MEMORY;
+    /* point to the new copy */
+    dst->set.postfields = dst->set.str[i];
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * curl_easy_duphandle() is an external interface to allow duplication of a
+ * given input easy handle. The returned handle will be a new working handle
+ * with all options set exactly as the input source handle.
+ */
+struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
+{
+  struct Curl_easy *outcurl = calloc(1, sizeof(struct Curl_easy));
+  if(NULL == outcurl)
+    goto fail;
+
+  /*
+   * We setup a few buffers we need. We should probably make them
+   * get setup on-demand in the code, as that would probably decrease
+   * the likeliness of us forgetting to init a buffer here in the future.
+   */
+  outcurl->set.buffer_size = data->set.buffer_size;
+  outcurl->state.buffer = malloc(outcurl->set.buffer_size + 1);
+  if(!outcurl->state.buffer)
+    goto fail;
+
+  outcurl->state.headerbuff = malloc(HEADERSIZE);
+  if(!outcurl->state.headerbuff)
+    goto fail;
+  outcurl->state.headersize = HEADERSIZE;
+
+  /* copy all userdefined values */
+  if(dupset(outcurl, data))
+    goto fail;
+
+  /* the connection cache is setup on demand */
+  outcurl->state.conn_cache = NULL;
+
+  outcurl->state.lastconnect = NULL;
+
+  outcurl->progress.flags    = data->progress.flags;
+  outcurl->progress.callback = data->progress.callback;
+
+  if(data->cookies) {
+    /* If cookies are enabled in the parent handle, we enable them
+       in the clone as well! */
+    outcurl->cookies = Curl_cookie_init(data,
+                                        data->cookies->filename,
+                                        outcurl->cookies,
+                                        data->set.cookiesession);
+    if(!outcurl->cookies)
+      goto fail;
+  }
+
+  /* duplicate all values in 'change' */
+  if(data->change.cookielist) {
+    outcurl->change.cookielist =
+      Curl_slist_duplicate(data->change.cookielist);
+    if(!outcurl->change.cookielist)
+      goto fail;
+  }
+
+  if(data->change.url) {
+    outcurl->change.url = strdup(data->change.url);
+    if(!outcurl->change.url)
+      goto fail;
+    outcurl->change.url_alloc = TRUE;
+  }
+
+  if(data->change.referer) {
+    outcurl->change.referer = strdup(data->change.referer);
+    if(!outcurl->change.referer)
+      goto fail;
+    outcurl->change.referer_alloc = TRUE;
+  }
+
+  /* Clone the resolver handle, if present, for the new handle */
+  if(Curl_resolver_duphandle(&outcurl->state.resolver,
+                             data->state.resolver))
+    goto fail;
+
+  Curl_convert_setup(outcurl);
+
+  Curl_initinfo(outcurl);
+
+  outcurl->magic = CURLEASY_MAGIC_NUMBER;
+
+  /* we reach this point and thus we are OK */
+
+  return outcurl;
+
+  fail:
+
+  if(outcurl) {
+    curl_slist_free_all(outcurl->change.cookielist);
+    outcurl->change.cookielist = NULL;
+    Curl_safefree(outcurl->state.buffer);
+    Curl_safefree(outcurl->state.headerbuff);
+    Curl_safefree(outcurl->change.url);
+    Curl_safefree(outcurl->change.referer);
+    Curl_freeset(outcurl);
+    free(outcurl);
+  }
+
+  return NULL;
+}
+
+/*
+ * curl_easy_reset() is an external interface that allows an app to re-
+ * initialize a session handle to the default values.
+ */
+void curl_easy_reset(struct Curl_easy *data)
+{
+  Curl_safefree(data->state.pathbuffer);
+
+  data->state.path = NULL;
+
+  Curl_free_request_state(data);
+
+  /* zero out UserDefined data: */
+  Curl_freeset(data);
+  memset(&data->set, 0, sizeof(struct UserDefined));
+  (void)Curl_init_userdefined(&data->set);
+
+  /* zero out Progress data: */
+  memset(&data->progress, 0, sizeof(struct Progress));
+
+  /* zero out PureInfo data: */
+  Curl_initinfo(data);
+
+  data->progress.flags |= PGRS_HIDE;
+  data->state.current_speed = -1; /* init to negative == impossible */
+
+  /* zero out authentication data: */
+  memset(&data->state.authhost, 0, sizeof(struct auth));
+  memset(&data->state.authproxy, 0, sizeof(struct auth));
+}
+
+/*
+ * curl_easy_pause() allows an application to pause or unpause a specific
+ * transfer and direction. This function sets the full new state for the
+ * current connection this easy handle operates on.
+ *
+ * NOTE: if you have the receiving paused and you call this function to remove
+ * the pausing, you may get your write callback called at this point.
+ *
+ * Action is a bitmask consisting of CURLPAUSE_* bits in curl/curl.h
+ */
+CURLcode curl_easy_pause(struct Curl_easy *data, int action)
+{
+  struct SingleRequest *k = &data->req;
+  CURLcode result = CURLE_OK;
+
+  /* first switch off both pause bits */
+  int newstate = k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE);
+
+  /* set the new desired pause bits */
+  newstate |= ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) |
+    ((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0);
+
+  /* put it back in the keepon */
+  k->keepon = newstate;
+
+  if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempcount) {
+    /* there are buffers for sending that can be delivered as the receive
+       pausing is lifted! */
+    unsigned int i;
+    unsigned int count = data->state.tempcount;
+    struct tempbuf writebuf[3]; /* there can only be three */
+
+    /* copy the structs to allow for immediate re-pausing */
+    for(i = 0; i < data->state.tempcount; i++) {
+      writebuf[i] = data->state.tempwrite[i];
+      data->state.tempwrite[i].buf = NULL;
+    }
+    data->state.tempcount = 0;
+
+    for(i = 0; i < count; i++) {
+      /* even if one function returns error, this loops through and frees all
+         buffers */
+      if(!result)
+        result = Curl_client_chop_write(data->easy_conn,
+                                        writebuf[i].type,
+                                        writebuf[i].buf,
+                                        writebuf[i].len);
+      free(writebuf[i].buf);
+    }
+    if(result)
+      return result;
+  }
+
+  /* if there's no error and we're not pausing both directions, we want
+     to have this handle checked soon */
+  if(!result &&
+     ((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
+      (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) )
+    Curl_expire(data, 0, EXPIRE_RUN_NOW); /* get this handle going again */
+
+  return result;
+}
+
+
+static CURLcode easy_connection(struct Curl_easy *data,
+                                curl_socket_t *sfd,
+                                struct connectdata **connp)
+{
+  if(data == NULL)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  /* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */
+  if(!data->set.connect_only) {
+    failf(data, "CONNECT_ONLY is required!");
+    return CURLE_UNSUPPORTED_PROTOCOL;
+  }
+
+  *sfd = Curl_getconnectinfo(data, connp);
+
+  if(*sfd == CURL_SOCKET_BAD) {
+    failf(data, "Failed to get recent socket");
+    return CURLE_UNSUPPORTED_PROTOCOL;
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Receives data from the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ * Returns CURLE_OK on success, error code on error.
+ */
+CURLcode curl_easy_recv(struct Curl_easy *data, void *buffer, size_t buflen,
+                        size_t *n)
+{
+  curl_socket_t sfd;
+  CURLcode result;
+  ssize_t n1;
+  struct connectdata *c;
+
+  result = easy_connection(data, &sfd, &c);
+  if(result)
+    return result;
+
+  *n = 0;
+  result = Curl_read(c, sfd, buffer, buflen, &n1);
+
+  if(result)
+    return result;
+
+  *n = (size_t)n1;
+
+  return CURLE_OK;
+}
+
+/*
+ * Sends data over the connected socket. Use after successful
+ * curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
+ */
+CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer,
+                        size_t buflen, size_t *n)
+{
+  curl_socket_t sfd;
+  CURLcode result;
+  ssize_t n1;
+  struct connectdata *c = NULL;
+
+  result = easy_connection(data, &sfd, &c);
+  if(result)
+    return result;
+
+  *n = 0;
+  result = Curl_write(c, sfd, buffer, buflen, &n1);
+
+  if(n1 == -1)
+    return CURLE_SEND_ERROR;
+
+  /* detect EAGAIN */
+  if(!result && !n1)
+    return CURLE_AGAIN;
+
+  *n = (size_t)n1;
+
+  return result;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/easyif.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/easyif.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/easyif.h	(revision 331)
@@ -0,0 +1,33 @@
+#ifndef HEADER_CURL_EASYIF_H
+#define HEADER_CURL_EASYIF_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Prototypes for library-wide functions provided by easy.c
+ */
+#ifdef CURLDEBUG
+CURL_EXTERN CURLcode curl_easy_perform_ev(struct Curl_easy *easy);
+#endif
+
+#endif /* HEADER_CURL_EASYIF_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/escape.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/escape.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/escape.c	(revision 331)
@@ -0,0 +1,242 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* Escape and unescape URL encoding in strings. The functions return a new
+ * allocated string or NULL if an error occurred.  */
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "warnless.h"
+#include "non-ascii.h"
+#include "escape.h"
+#include "strdup.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Portable character check (remember EBCDIC). Do not use isalnum() because
+   its behavior is altered by the current locale.
+   See https://tools.ietf.org/html/rfc3986#section-2.3
+*/
+static bool Curl_isunreserved(unsigned char in)
+{
+  switch(in) {
+    case '0': case '1': case '2': case '3': case '4':
+    case '5': case '6': case '7': case '8': case '9':
+    case 'a': case 'b': case 'c': case 'd': case 'e':
+    case 'f': case 'g': case 'h': case 'i': case 'j':
+    case 'k': case 'l': case 'm': case 'n': case 'o':
+    case 'p': case 'q': case 'r': case 's': case 't':
+    case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
+    case 'A': case 'B': case 'C': case 'D': case 'E':
+    case 'F': case 'G': case 'H': case 'I': case 'J':
+    case 'K': case 'L': case 'M': case 'N': case 'O':
+    case 'P': case 'Q': case 'R': case 'S': case 'T':
+    case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z':
+    case '-': case '.': case '_': case '~':
+      return TRUE;
+    default:
+      break;
+  }
+  return FALSE;
+}
+
+/* for ABI-compatibility with previous versions */
+char *curl_escape(const char *string, int inlength)
+{
+  return curl_easy_escape(NULL, string, inlength);
+}
+
+/* for ABI-compatibility with previous versions */
+char *curl_unescape(const char *string, int length)
+{
+  return curl_easy_unescape(NULL, string, length, NULL);
+}
+
+char *curl_easy_escape(struct Curl_easy *data, const char *string,
+                       int inlength)
+{
+  size_t alloc;
+  char *ns;
+  char *testing_ptr = NULL;
+  unsigned char in; /* we need to treat the characters unsigned */
+  size_t newlen;
+  size_t strindex = 0;
+  size_t length;
+  CURLcode result;
+
+  if(inlength < 0)
+    return NULL;
+
+  alloc = (inlength?(size_t)inlength:strlen(string)) + 1;
+  newlen = alloc;
+
+  ns = malloc(alloc);
+  if(!ns)
+    return NULL;
+
+  length = alloc-1;
+  while(length--) {
+    in = *string;
+
+    if(Curl_isunreserved(in))
+      /* just copy this */
+      ns[strindex++] = in;
+    else {
+      /* encode it */
+      newlen += 2; /* the size grows with two, since this'll become a %XX */
+      if(newlen > alloc) {
+        alloc *= 2;
+        testing_ptr = Curl_saferealloc(ns, alloc);
+        if(!testing_ptr)
+          return NULL;
+        ns = testing_ptr;
+      }
+
+      result = Curl_convert_to_network(data, (char *)&in, 1);
+      if(result) {
+        /* Curl_convert_to_network calls failf if unsuccessful */
+        free(ns);
+        return NULL;
+      }
+
+      snprintf(&ns[strindex], 4, "%%%02X", in);
+
+      strindex += 3;
+    }
+    string++;
+  }
+  ns[strindex] = 0; /* terminate it */
+  return ns;
+}
+
+/*
+ * Curl_urldecode() URL decodes the given string.
+ *
+ * Optionally detects control characters (byte codes lower than 32) in the
+ * data and rejects such data.
+ *
+ * Returns a pointer to a malloced string in *ostring with length given in
+ * *olen. If length == 0, the length is assumed to be strlen(string).
+ *
+ */
+CURLcode Curl_urldecode(struct Curl_easy *data,
+                        const char *string, size_t length,
+                        char **ostring, size_t *olen,
+                        bool reject_ctrl)
+{
+  size_t alloc = (length?length:strlen(string)) + 1;
+  char *ns = malloc(alloc);
+  unsigned char in;
+  size_t strindex = 0;
+  unsigned long hex;
+  CURLcode result;
+
+  if(!ns)
+    return CURLE_OUT_OF_MEMORY;
+
+  while(--alloc > 0) {
+    in = *string;
+    if(('%' == in) && (alloc > 2) &&
+       ISXDIGIT(string[1]) && ISXDIGIT(string[2])) {
+      /* this is two hexadecimal digits following a '%' */
+      char hexstr[3];
+      char *ptr;
+      hexstr[0] = string[1];
+      hexstr[1] = string[2];
+      hexstr[2] = 0;
+
+      hex = strtoul(hexstr, &ptr, 16);
+
+      in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */
+
+      result = Curl_convert_from_network(data, (char *)&in, 1);
+      if(result) {
+        /* Curl_convert_from_network calls failf if unsuccessful */
+        free(ns);
+        return result;
+      }
+
+      string += 2;
+      alloc -= 2;
+    }
+
+    if(reject_ctrl && (in < 0x20)) {
+      free(ns);
+      return CURLE_URL_MALFORMAT;
+    }
+
+    ns[strindex++] = in;
+    string++;
+  }
+  ns[strindex] = 0; /* terminate it */
+
+  if(olen)
+    /* store output size */
+    *olen = strindex;
+
+  /* store output string */
+  *ostring = ns;
+
+  return CURLE_OK;
+}
+
+/*
+ * Unescapes the given URL escaped string of given length. Returns a
+ * pointer to a malloced string with length given in *olen.
+ * If length == 0, the length is assumed to be strlen(string).
+ * If olen == NULL, no output length is stored.
+ */
+char *curl_easy_unescape(struct Curl_easy *data, const char *string,
+                         int length, int *olen)
+{
+  char *str = NULL;
+  if(length >= 0) {
+    size_t inputlen = length;
+    size_t outputlen;
+    CURLcode res = Curl_urldecode(data, string, inputlen, &str, &outputlen,
+                                  FALSE);
+    if(res)
+      return NULL;
+
+    if(olen) {
+      if(outputlen <= (size_t) INT_MAX)
+        *olen = curlx_uztosi(outputlen);
+      else
+        /* too large to return in an int, fail! */
+        Curl_safefree(str);
+    }
+  }
+  return str;
+}
+
+/* For operating systems/environments that use different malloc/free
+   systems for the app and for this library, we provide a free that uses
+   the library's memory system */
+void curl_free(void *p)
+{
+  free(p);
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/escape.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/escape.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/escape.h	(revision 331)
@@ -0,0 +1,33 @@
+#ifndef HEADER_CURL_ESCAPE_H
+#define HEADER_CURL_ESCAPE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/* Escape and unescape URL encoding in strings. The functions return a new
+ * allocated string or NULL if an error occurred.  */
+
+CURLcode Curl_urldecode(struct Curl_easy *data,
+                        const char *string, size_t length,
+                        char **ostring, size_t *olen,
+                        bool reject_crlf);
+
+#endif /* HEADER_CURL_ESCAPE_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/file.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/file.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/file.c	(revision 331)
@@ -0,0 +1,600 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_FILE
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include "strtoofft.h"
+#include "urldata.h"
+#include <curl/curl.h>
+#include "progress.h"
+#include "sendf.h"
+#include "escape.h"
+#include "file.h"
+#include "speedcheck.h"
+#include "getinfo.h"
+#include "transfer.h"
+#include "url.h"
+#include "parsedate.h" /* for the week day and month names */
+#include "warnless.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#if defined(WIN32) || defined(MSDOS) || defined(__EMX__) || \
+  defined(__SYMBIAN32__)
+#define DOS_FILESYSTEM 1
+#endif
+
+#ifdef OPEN_NEEDS_ARG3
+#  define open_readonly(p,f) open((p),(f),(0))
+#else
+#  define open_readonly(p,f) open((p),(f))
+#endif
+
+/*
+ * Forward declarations.
+ */
+
+static CURLcode file_do(struct connectdata *, bool *done);
+static CURLcode file_done(struct connectdata *conn,
+                          CURLcode status, bool premature);
+static CURLcode file_connect(struct connectdata *conn, bool *done);
+static CURLcode file_disconnect(struct connectdata *conn,
+                                bool dead_connection);
+static CURLcode file_setup_connection(struct connectdata *conn);
+
+/*
+ * FILE scheme handler.
+ */
+
+const struct Curl_handler Curl_handler_file = {
+  "FILE",                               /* scheme */
+  file_setup_connection,                /* setup_connection */
+  file_do,                              /* do_it */
+  file_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  file_connect,                         /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  file_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  0,                                    /* defport */
+  CURLPROTO_FILE,                       /* protocol */
+  PROTOPT_NONETWORK | PROTOPT_NOURLQUERY /* flags */
+};
+
+
+static CURLcode file_setup_connection(struct connectdata *conn)
+{
+  /* allocate the FILE specific struct */
+  conn->data->req.protop = calloc(1, sizeof(struct FILEPROTO));
+  if(!conn->data->req.protop)
+    return CURLE_OUT_OF_MEMORY;
+
+  return CURLE_OK;
+}
+
+ /*
+  Check if this is a range download, and if so, set the internal variables
+  properly. This code is copied from the FTP implementation and might as
+  well be factored out.
+ */
+static CURLcode file_range(struct connectdata *conn)
+{
+  curl_off_t from, to;
+  curl_off_t totalsize = -1;
+  char *ptr;
+  char *ptr2;
+  struct Curl_easy *data = conn->data;
+
+  if(data->state.use_range && data->state.range) {
+    CURLofft from_t;
+    CURLofft to_t;
+    from_t = curlx_strtoofft(data->state.range, &ptr, 0, &from);
+    if(from_t == CURL_OFFT_FLOW)
+      return CURLE_RANGE_ERROR;
+    while(*ptr && (ISSPACE(*ptr) || (*ptr == '-')))
+      ptr++;
+    to_t = curlx_strtoofft(ptr, &ptr2, 0, &to);
+    if(to_t == CURL_OFFT_FLOW)
+      return CURLE_RANGE_ERROR;
+    if((to_t == CURL_OFFT_INVAL) && !from_t) {
+      /* X - */
+      data->state.resume_from = from;
+      DEBUGF(infof(data, "RANGE %" CURL_FORMAT_CURL_OFF_T " to end of file\n",
+                   from));
+    }
+    else if((from_t == CURL_OFFT_INVAL) && !to_t) {
+      /* -Y */
+      data->req.maxdownload = to;
+      data->state.resume_from = -to;
+      DEBUGF(infof(data, "RANGE the last %" CURL_FORMAT_CURL_OFF_T " bytes\n",
+                   to));
+    }
+    else {
+      /* X-Y */
+      totalsize = to-from;
+      if(totalsize == CURL_OFF_T_MAX)
+        /* this is too big to increase, so bail out */
+        return CURLE_RANGE_ERROR;
+      data->req.maxdownload = totalsize + 1; /* include last byte */
+      data->state.resume_from = from;
+      DEBUGF(infof(data, "RANGE from %" CURL_FORMAT_CURL_OFF_T
+                   " getting %" CURL_FORMAT_CURL_OFF_T " bytes\n",
+                   from, data->req.maxdownload));
+    }
+    DEBUGF(infof(data, "range-download from %" CURL_FORMAT_CURL_OFF_T
+                 " to %" CURL_FORMAT_CURL_OFF_T ", totally %"
+                 CURL_FORMAT_CURL_OFF_T " bytes\n",
+                 from, to, data->req.maxdownload));
+  }
+  else
+    data->req.maxdownload = -1;
+  return CURLE_OK;
+}
+
+/*
+ * file_connect() gets called from Curl_protocol_connect() to allow us to
+ * do protocol-specific actions at connect-time.  We emulate a
+ * connect-then-transfer protocol and "connect" to the file here
+ */
+static CURLcode file_connect(struct connectdata *conn, bool *done)
+{
+  struct Curl_easy *data = conn->data;
+  char *real_path;
+  struct FILEPROTO *file = data->req.protop;
+  int fd;
+#ifdef DOS_FILESYSTEM
+  size_t i;
+  char *actual_path;
+#endif
+  size_t real_path_len;
+
+  CURLcode result = Curl_urldecode(data, data->state.path, 0, &real_path,
+                                   &real_path_len, FALSE);
+  if(result)
+    return result;
+
+#ifdef DOS_FILESYSTEM
+  /* If the first character is a slash, and there's
+     something that looks like a drive at the beginning of
+     the path, skip the slash.  If we remove the initial
+     slash in all cases, paths without drive letters end up
+     relative to the current directory which isn't how
+     browsers work.
+
+     Some browsers accept | instead of : as the drive letter
+     separator, so we do too.
+
+     On other platforms, we need the slash to indicate an
+     absolute pathname.  On Windows, absolute paths start
+     with a drive letter.
+  */
+  actual_path = real_path;
+  if((actual_path[0] == '/') &&
+      actual_path[1] &&
+     (actual_path[2] == ':' || actual_path[2] == '|')) {
+    actual_path[2] = ':';
+    actual_path++;
+    real_path_len--;
+  }
+
+  /* change path separators from '/' to '\\' for DOS, Windows and OS/2 */
+  for(i = 0; i < real_path_len; ++i)
+    if(actual_path[i] == '/')
+      actual_path[i] = '\\';
+    else if(!actual_path[i]) { /* binary zero */
+      Curl_safefree(real_path);
+      return CURLE_URL_MALFORMAT;
+    }
+
+  fd = open_readonly(actual_path, O_RDONLY|O_BINARY);
+  file->path = actual_path;
+#else
+  if(memchr(real_path, 0, real_path_len)) {
+    /* binary zeroes indicate foul play */
+    Curl_safefree(real_path);
+    return CURLE_URL_MALFORMAT;
+  }
+
+  fd = open_readonly(real_path, O_RDONLY);
+  file->path = real_path;
+#endif
+  file->freepath = real_path; /* free this when done */
+
+  file->fd = fd;
+  if(!data->set.upload && (fd == -1)) {
+    failf(data, "Couldn't open file %s", data->state.path);
+    file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE);
+    return CURLE_FILE_COULDNT_READ_FILE;
+  }
+  *done = TRUE;
+
+  return CURLE_OK;
+}
+
+static CURLcode file_done(struct connectdata *conn,
+                               CURLcode status, bool premature)
+{
+  struct FILEPROTO *file = conn->data->req.protop;
+  (void)status; /* not used */
+  (void)premature; /* not used */
+
+  if(file) {
+    Curl_safefree(file->freepath);
+    file->path = NULL;
+    if(file->fd != -1)
+      close(file->fd);
+    file->fd = -1;
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode file_disconnect(struct connectdata *conn,
+                                bool dead_connection)
+{
+  struct FILEPROTO *file = conn->data->req.protop;
+  (void)dead_connection; /* not used */
+
+  if(file) {
+    Curl_safefree(file->freepath);
+    file->path = NULL;
+    if(file->fd != -1)
+      close(file->fd);
+    file->fd = -1;
+  }
+
+  return CURLE_OK;
+}
+
+#ifdef DOS_FILESYSTEM
+#define DIRSEP '\\'
+#else
+#define DIRSEP '/'
+#endif
+
+static CURLcode file_upload(struct connectdata *conn)
+{
+  struct FILEPROTO *file = conn->data->req.protop;
+  const char *dir = strchr(file->path, DIRSEP);
+  int fd;
+  int mode;
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  char *buf = data->state.buffer;
+  size_t nread;
+  size_t nwrite;
+  curl_off_t bytecount = 0;
+  struct_stat file_stat;
+  const char *buf2;
+
+  /*
+   * Since FILE: doesn't do the full init, we need to provide some extra
+   * assignments here.
+   */
+  conn->data->req.upload_fromhere = buf;
+
+  if(!dir)
+    return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
+
+  if(!dir[1])
+    return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
+
+#ifdef O_BINARY
+#define MODE_DEFAULT O_WRONLY|O_CREAT|O_BINARY
+#else
+#define MODE_DEFAULT O_WRONLY|O_CREAT
+#endif
+
+  if(data->state.resume_from)
+    mode = MODE_DEFAULT|O_APPEND;
+  else
+    mode = MODE_DEFAULT|O_TRUNC;
+
+  fd = open(file->path, mode, conn->data->set.new_file_perms);
+  if(fd < 0) {
+    failf(data, "Can't open %s for writing", file->path);
+    return CURLE_WRITE_ERROR;
+  }
+
+  if(-1 != data->state.infilesize)
+    /* known size of data to "upload" */
+    Curl_pgrsSetUploadSize(data, data->state.infilesize);
+
+  /* treat the negative resume offset value as the case of "-" */
+  if(data->state.resume_from < 0) {
+    if(fstat(fd, &file_stat)) {
+      close(fd);
+      failf(data, "Can't get the size of %s", file->path);
+      return CURLE_WRITE_ERROR;
+    }
+    data->state.resume_from = (curl_off_t)file_stat.st_size;
+  }
+
+  while(!result) {
+    int readcount;
+    result = Curl_fillreadbuffer(conn, (int)data->set.buffer_size, &readcount);
+    if(result)
+      break;
+
+    if(readcount <= 0)  /* fix questionable compare error. curlvms */
+      break;
+
+    nread = (size_t)readcount;
+
+    /*skip bytes before resume point*/
+    if(data->state.resume_from) {
+      if((curl_off_t)nread <= data->state.resume_from) {
+        data->state.resume_from -= nread;
+        nread = 0;
+        buf2 = buf;
+      }
+      else {
+        buf2 = buf + data->state.resume_from;
+        nread -= (size_t)data->state.resume_from;
+        data->state.resume_from = 0;
+      }
+    }
+    else
+      buf2 = buf;
+
+    /* write the data to the target */
+    nwrite = write(fd, buf2, nread);
+    if(nwrite != nread) {
+      result = CURLE_SEND_ERROR;
+      break;
+    }
+
+    bytecount += nread;
+
+    Curl_pgrsSetUploadCounter(data, bytecount);
+
+    if(Curl_pgrsUpdate(conn))
+      result = CURLE_ABORTED_BY_CALLBACK;
+    else
+      result = Curl_speedcheck(data, Curl_now());
+  }
+  if(!result && Curl_pgrsUpdate(conn))
+    result = CURLE_ABORTED_BY_CALLBACK;
+
+  close(fd);
+
+  return result;
+}
+
+/*
+ * file_do() is the protocol-specific function for the do-phase, separated
+ * from the connect-phase above. Other protocols merely setup the transfer in
+ * the do-phase, to have it done in the main transfer loop but since some
+ * platforms we support don't allow select()ing etc on file handles (as
+ * opposed to sockets) we instead perform the whole do-operation in this
+ * function.
+ */
+static CURLcode file_do(struct connectdata *conn, bool *done)
+{
+  /* This implementation ignores the host name in conformance with
+     RFC 1738. Only local files (reachable via the standard file system)
+     are supported. This means that files on remotely mounted directories
+     (via NFS, Samba, NT sharing) can be accessed through a file:// URL
+  */
+  CURLcode result = CURLE_OK;
+  struct_stat statbuf; /* struct_stat instead of struct stat just to allow the
+                          Windows version to have a different struct without
+                          having to redefine the simple word 'stat' */
+  curl_off_t expected_size = 0;
+  bool size_known;
+  bool fstated = FALSE;
+  ssize_t nread;
+  struct Curl_easy *data = conn->data;
+  char *buf = data->state.buffer;
+  curl_off_t bytecount = 0;
+  int fd;
+  struct FILEPROTO *file;
+
+  *done = TRUE; /* unconditionally */
+
+  Curl_initinfo(data);
+  Curl_pgrsStartNow(data);
+
+  if(data->set.upload)
+    return file_upload(conn);
+
+  file = conn->data->req.protop;
+
+  /* get the fd from the connection phase */
+  fd = file->fd;
+
+  /* VMS: This only works reliable for STREAMLF files */
+  if(-1 != fstat(fd, &statbuf)) {
+    /* we could stat it, then read out the size */
+    expected_size = statbuf.st_size;
+    /* and store the modification time */
+    data->info.filetime = (long)statbuf.st_mtime;
+    fstated = TRUE;
+  }
+
+  if(fstated && !data->state.range && data->set.timecondition) {
+    if(!Curl_meets_timecondition(data, (time_t)data->info.filetime)) {
+      *done = TRUE;
+      return CURLE_OK;
+    }
+  }
+
+  /* If we have selected NOBODY and HEADER, it means that we only want file
+     information. Which for FILE can't be much more than the file size and
+     date. */
+  if(data->set.opt_no_body && data->set.include_header && fstated) {
+    time_t filetime;
+    struct tm buffer;
+    const struct tm *tm = &buffer;
+    char header[80];
+    snprintf(header, sizeof(header),
+             "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", expected_size);
+    result = Curl_client_write(conn, CLIENTWRITE_BOTH, header, 0);
+    if(result)
+      return result;
+
+    result = Curl_client_write(conn, CLIENTWRITE_BOTH,
+                               (char *)"Accept-ranges: bytes\r\n", 0);
+    if(result)
+      return result;
+
+    filetime = (time_t)statbuf.st_mtime;
+    result = Curl_gmtime(filetime, &buffer);
+    if(result)
+      return result;
+
+    /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
+    snprintf(header, sizeof(header),
+             "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
+             Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
+             tm->tm_mday,
+             Curl_month[tm->tm_mon],
+             tm->tm_year + 1900,
+             tm->tm_hour,
+             tm->tm_min,
+             tm->tm_sec);
+    result = Curl_client_write(conn, CLIENTWRITE_BOTH, header, 0);
+    if(!result)
+      /* set the file size to make it available post transfer */
+      Curl_pgrsSetDownloadSize(data, expected_size);
+    return result;
+  }
+
+  /* Check whether file range has been specified */
+  file_range(conn);
+
+  /* Adjust the start offset in case we want to get the N last bytes
+   * of the stream iff the filesize could be determined */
+  if(data->state.resume_from < 0) {
+    if(!fstated) {
+      failf(data, "Can't get the size of file.");
+      return CURLE_READ_ERROR;
+    }
+    data->state.resume_from += (curl_off_t)statbuf.st_size;
+  }
+
+  if(data->state.resume_from <= expected_size)
+    expected_size -= data->state.resume_from;
+  else {
+    failf(data, "failed to resume file:// transfer");
+    return CURLE_BAD_DOWNLOAD_RESUME;
+  }
+
+  /* A high water mark has been specified so we obey... */
+  if(data->req.maxdownload > 0)
+    expected_size = data->req.maxdownload;
+
+  if(!fstated || (expected_size == 0))
+    size_known = FALSE;
+  else
+    size_known = TRUE;
+
+  /* The following is a shortcut implementation of file reading
+     this is both more efficient than the former call to download() and
+     it avoids problems with select() and recv() on file descriptors
+     in Winsock */
+  if(fstated)
+    Curl_pgrsSetDownloadSize(data, expected_size);
+
+  if(data->state.resume_from) {
+    if(data->state.resume_from !=
+       lseek(fd, data->state.resume_from, SEEK_SET))
+      return CURLE_BAD_DOWNLOAD_RESUME;
+  }
+
+  Curl_pgrsTime(data, TIMER_STARTTRANSFER);
+
+  while(!result) {
+    /* Don't fill a whole buffer if we want less than all data */
+    size_t bytestoread;
+
+    if(size_known) {
+      bytestoread = (expected_size < data->set.buffer_size) ?
+        curlx_sotouz(expected_size) : (size_t)data->set.buffer_size;
+    }
+    else
+      bytestoread = data->set.buffer_size-1;
+
+    nread = read(fd, buf, bytestoread);
+
+    if(nread > 0)
+      buf[nread] = 0;
+
+    if(nread <= 0 || (size_known && (expected_size == 0)))
+      break;
+
+    bytecount += nread;
+    if(size_known)
+      expected_size -= nread;
+
+    result = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread);
+    if(result)
+      return result;
+
+    Curl_pgrsSetDownloadCounter(data, bytecount);
+
+    if(Curl_pgrsUpdate(conn))
+      result = CURLE_ABORTED_BY_CALLBACK;
+    else
+      result = Curl_speedcheck(data, Curl_now());
+  }
+  if(Curl_pgrsUpdate(conn))
+    result = CURLE_ABORTED_BY_CALLBACK;
+
+  return result;
+}
+
+#endif
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/file.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/file.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/file.h	(revision 331)
@@ -0,0 +1,41 @@
+#ifndef HEADER_CURL_FILE_H
+#define HEADER_CURL_FILE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+
+/****************************************************************************
+ * FILE unique setup
+ ***************************************************************************/
+struct FILEPROTO {
+  char *path; /* the path we operate on */
+  char *freepath; /* pointer to the allocated block we must free, this might
+                     differ from the 'path' pointer */
+  int fd;     /* open file descriptor to read from! */
+};
+
+#ifndef CURL_DISABLE_FILE
+extern const struct Curl_handler Curl_handler_file;
+#endif
+
+#endif /* HEADER_CURL_FILE_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/fileinfo.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/fileinfo.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/fileinfo.c	(revision 331)
@@ -0,0 +1,46 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "strdup.h"
+#include "fileinfo.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+struct fileinfo *Curl_fileinfo_alloc(void)
+{
+  return calloc(1, sizeof(struct fileinfo));
+}
+
+void Curl_fileinfo_dtor(void *user, void *element)
+{
+  struct fileinfo *finfo = element;
+  (void) user;
+  if(!finfo)
+    return;
+
+  Curl_safefree(finfo->info.b_data);
+
+  free(finfo);
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/fileinfo.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/fileinfo.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/fileinfo.h	(revision 331)
@@ -0,0 +1,37 @@
+#ifndef HEADER_CURL_FILEINFO_H
+#define HEADER_CURL_FILEINFO_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010, 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h>
+#include "llist.h"
+
+struct fileinfo {
+  struct curl_fileinfo info;
+  struct curl_llist_element list;
+};
+
+struct fileinfo *Curl_fileinfo_alloc(void);
+
+void Curl_fileinfo_dtor(void *, void *);
+
+#endif /* HEADER_CURL_FILEINFO_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/formdata.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/formdata.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/formdata.c	(revision 331)
@@ -0,0 +1,1000 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#ifndef CURL_DISABLE_HTTP
+
+#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
+#include <libgen.h>
+#endif
+
+#include "urldata.h" /* for struct Curl_easy */
+#include "formdata.h"
+#include "mime.h"
+#include "non-ascii.h"
+#include "vtls/vtls.h"
+#include "strcase.h"
+#include "sendf.h"
+#include "strdup.h"
+#include "rand.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+
+/* What kind of Content-Type to use on un-specified files with unrecognized
+   extensions. */
+#define HTTPPOST_CONTENTTYPE_DEFAULT "application/octet-stream"
+
+#define HTTPPOST_PTRNAME CURL_HTTPPOST_PTRNAME
+#define HTTPPOST_FILENAME CURL_HTTPPOST_FILENAME
+#define HTTPPOST_PTRCONTENTS CURL_HTTPPOST_PTRCONTENTS
+#define HTTPPOST_READFILE CURL_HTTPPOST_READFILE
+#define HTTPPOST_PTRBUFFER CURL_HTTPPOST_PTRBUFFER
+#define HTTPPOST_CALLBACK CURL_HTTPPOST_CALLBACK
+#define HTTPPOST_BUFFER CURL_HTTPPOST_BUFFER
+
+/***************************************************************************
+ *
+ * AddHttpPost()
+ *
+ * Adds a HttpPost structure to the list, if parent_post is given becomes
+ * a subpost of parent_post instead of a direct list element.
+ *
+ * Returns newly allocated HttpPost on success and NULL if malloc failed.
+ *
+ ***************************************************************************/
+static struct curl_httppost *
+AddHttpPost(char *name, size_t namelength,
+            char *value, curl_off_t contentslength,
+            char *buffer, size_t bufferlength,
+            char *contenttype,
+            long flags,
+            struct curl_slist *contentHeader,
+            char *showfilename, char *userp,
+            struct curl_httppost *parent_post,
+            struct curl_httppost **httppost,
+            struct curl_httppost **last_post)
+{
+  struct curl_httppost *post;
+  post = calloc(1, sizeof(struct curl_httppost));
+  if(post) {
+    post->name = name;
+    post->namelength = (long)(name?(namelength?namelength:strlen(name)):0);
+    post->contents = value;
+    post->contentlen = contentslength;
+    post->buffer = buffer;
+    post->bufferlength = (long)bufferlength;
+    post->contenttype = contenttype;
+    post->contentheader = contentHeader;
+    post->showfilename = showfilename;
+    post->userp = userp;
+    post->flags = flags | CURL_HTTPPOST_LARGE;
+  }
+  else
+    return NULL;
+
+  if(parent_post) {
+    /* now, point our 'more' to the original 'more' */
+    post->more = parent_post->more;
+
+    /* then move the original 'more' to point to ourselves */
+    parent_post->more = post;
+  }
+  else {
+    /* make the previous point to this */
+    if(*last_post)
+      (*last_post)->next = post;
+    else
+      (*httppost) = post;
+
+    (*last_post) = post;
+  }
+  return post;
+}
+
+/***************************************************************************
+ *
+ * AddFormInfo()
+ *
+ * Adds a FormInfo structure to the list presented by parent_form_info.
+ *
+ * Returns newly allocated FormInfo on success and NULL if malloc failed/
+ * parent_form_info is NULL.
+ *
+ ***************************************************************************/
+static FormInfo * AddFormInfo(char *value,
+                              char *contenttype,
+                              FormInfo *parent_form_info)
+{
+  FormInfo *form_info;
+  form_info = calloc(1, sizeof(struct FormInfo));
+  if(form_info) {
+    if(value)
+      form_info->value = value;
+    if(contenttype)
+      form_info->contenttype = contenttype;
+    form_info->flags = HTTPPOST_FILENAME;
+  }
+  else
+    return NULL;
+
+  if(parent_form_info) {
+    /* now, point our 'more' to the original 'more' */
+    form_info->more = parent_form_info->more;
+
+    /* then move the original 'more' to point to ourselves */
+    parent_form_info->more = form_info;
+  }
+
+  return form_info;
+}
+
+/***************************************************************************
+ *
+ * ContentTypeForFilename()
+ *
+ * Provides content type for filename if one of the known types (else
+ * (either the prevtype or the default is returned).
+ *
+ * Returns some valid contenttype for filename.
+ *
+ ***************************************************************************/
+static const char *ContentTypeForFilename(const char *filename,
+                                          const char *prevtype)
+{
+  const char *contenttype = NULL;
+  unsigned int i;
+  /*
+   * No type was specified, we scan through a few well-known
+   * extensions and pick the first we match!
+   */
+  struct ContentType {
+    const char *extension;
+    const char *type;
+  };
+  static const struct ContentType ctts[]={
+    {".gif",  "image/gif"},
+    {".jpg",  "image/jpeg"},
+    {".jpeg", "image/jpeg"},
+    {".txt",  "text/plain"},
+    {".html", "text/html"},
+    {".xml", "application/xml"}
+  };
+
+  if(prevtype)
+    /* default to the previously set/used! */
+    contenttype = prevtype;
+  else
+    contenttype = HTTPPOST_CONTENTTYPE_DEFAULT;
+
+  if(filename) { /* in case a NULL was passed in */
+    for(i = 0; i<sizeof(ctts)/sizeof(ctts[0]); i++) {
+      if(strlen(filename) >= strlen(ctts[i].extension)) {
+        if(strcasecompare(filename +
+                          strlen(filename) - strlen(ctts[i].extension),
+                          ctts[i].extension)) {
+          contenttype = ctts[i].type;
+          break;
+        }
+      }
+    }
+  }
+  /* we have a contenttype by now */
+  return contenttype;
+}
+
+/***************************************************************************
+ *
+ * FormAdd()
+ *
+ * Stores a formpost parameter and builds the appropriate linked list.
+ *
+ * Has two principal functionalities: using files and byte arrays as
+ * post parts. Byte arrays are either copied or just the pointer is stored
+ * (as the user requests) while for files only the filename and not the
+ * content is stored.
+ *
+ * While you may have only one byte array for each name, multiple filenames
+ * are allowed (and because of this feature CURLFORM_END is needed after
+ * using CURLFORM_FILE).
+ *
+ * Examples:
+ *
+ * Simple name/value pair with copied contents:
+ * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
+ * CURLFORM_COPYCONTENTS, "value", CURLFORM_END);
+ *
+ * name/value pair where only the content pointer is remembered:
+ * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
+ * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10, CURLFORM_END);
+ * (if CURLFORM_CONTENTSLENGTH is missing strlen () is used)
+ *
+ * storing a filename (CONTENTTYPE is optional!):
+ * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
+ * CURLFORM_FILE, "filename1", CURLFORM_CONTENTTYPE, "plain/text",
+ * CURLFORM_END);
+ *
+ * storing multiple filenames:
+ * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
+ * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END);
+ *
+ * Returns:
+ * CURL_FORMADD_OK             on success
+ * CURL_FORMADD_MEMORY         if the FormInfo allocation fails
+ * CURL_FORMADD_OPTION_TWICE   if one option is given twice for one Form
+ * CURL_FORMADD_NULL           if a null pointer was given for a char
+ * CURL_FORMADD_MEMORY         if the allocation of a FormInfo struct failed
+ * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
+ * CURL_FORMADD_INCOMPLETE     if the some FormInfo is not complete (or error)
+ * CURL_FORMADD_MEMORY         if a HttpPost struct cannot be allocated
+ * CURL_FORMADD_MEMORY         if some allocation for string copying failed.
+ * CURL_FORMADD_ILLEGAL_ARRAY  if an illegal option is used in an array
+ *
+ ***************************************************************************/
+
+static
+CURLFORMcode FormAdd(struct curl_httppost **httppost,
+                     struct curl_httppost **last_post,
+                     va_list params)
+{
+  FormInfo *first_form, *current_form, *form = NULL;
+  CURLFORMcode return_value = CURL_FORMADD_OK;
+  const char *prevtype = NULL;
+  struct curl_httppost *post = NULL;
+  CURLformoption option;
+  struct curl_forms *forms = NULL;
+  char *array_value = NULL; /* value read from an array */
+
+  /* This is a state variable, that if TRUE means that we're parsing an
+     array that we got passed to us. If FALSE we're parsing the input
+     va_list arguments. */
+  bool array_state = FALSE;
+
+  /*
+   * We need to allocate the first struct to fill in.
+   */
+  first_form = calloc(1, sizeof(struct FormInfo));
+  if(!first_form)
+    return CURL_FORMADD_MEMORY;
+
+  current_form = first_form;
+
+  /*
+   * Loop through all the options set. Break if we have an error to report.
+   */
+  while(return_value == CURL_FORMADD_OK) {
+
+    /* first see if we have more parts of the array param */
+    if(array_state && forms) {
+      /* get the upcoming option from the given array */
+      option = forms->option;
+      array_value = (char *)forms->value;
+
+      forms++; /* advance this to next entry */
+      if(CURLFORM_END == option) {
+        /* end of array state */
+        array_state = FALSE;
+        continue;
+      }
+    }
+    else {
+      /* This is not array-state, get next option */
+      option = va_arg(params, CURLformoption);
+      if(CURLFORM_END == option)
+        break;
+    }
+
+    switch(option) {
+    case CURLFORM_ARRAY:
+      if(array_state)
+        /* we don't support an array from within an array */
+        return_value = CURL_FORMADD_ILLEGAL_ARRAY;
+      else {
+        forms = va_arg(params, struct curl_forms *);
+        if(forms)
+          array_state = TRUE;
+        else
+          return_value = CURL_FORMADD_NULL;
+      }
+      break;
+
+      /*
+       * Set the Name property.
+       */
+    case CURLFORM_PTRNAME:
+#ifdef CURL_DOES_CONVERSIONS
+      /* Treat CURLFORM_PTR like CURLFORM_COPYNAME so that libcurl will copy
+       * the data in all cases so that we'll have safe memory for the eventual
+       * conversion.
+       */
+#else
+      current_form->flags |= HTTPPOST_PTRNAME; /* fall through */
+#endif
+      /* FALLTHROUGH */
+    case CURLFORM_COPYNAME:
+      if(current_form->name)
+        return_value = CURL_FORMADD_OPTION_TWICE;
+      else {
+        char *name = array_state?
+          array_value:va_arg(params, char *);
+        if(name)
+          current_form->name = name; /* store for the moment */
+        else
+          return_value = CURL_FORMADD_NULL;
+      }
+      break;
+    case CURLFORM_NAMELENGTH:
+      if(current_form->namelength)
+        return_value = CURL_FORMADD_OPTION_TWICE;
+      else
+        current_form->namelength =
+          array_state?(size_t)array_value:(size_t)va_arg(params, long);
+      break;
+
+      /*
+       * Set the contents property.
+       */
+    case CURLFORM_PTRCONTENTS:
+      current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */
+    case CURLFORM_COPYCONTENTS:
+      if(current_form->value)
+        return_value = CURL_FORMADD_OPTION_TWICE;
+      else {
+        char *value =
+          array_state?array_value:va_arg(params, char *);
+        if(value)
+          current_form->value = value; /* store for the moment */
+        else
+          return_value = CURL_FORMADD_NULL;
+      }
+      break;
+    case CURLFORM_CONTENTSLENGTH:
+      current_form->contentslength =
+        array_state?(size_t)array_value:(size_t)va_arg(params, long);
+      break;
+
+    case CURLFORM_CONTENTLEN:
+      current_form->flags |= CURL_HTTPPOST_LARGE;
+      current_form->contentslength =
+        array_state?(curl_off_t)(size_t)array_value:va_arg(params, curl_off_t);
+      break;
+
+      /* Get contents from a given file name */
+    case CURLFORM_FILECONTENT:
+      if(current_form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE))
+        return_value = CURL_FORMADD_OPTION_TWICE;
+      else {
+        const char *filename = array_state?
+          array_value:va_arg(params, char *);
+        if(filename) {
+          current_form->value = strdup(filename);
+          if(!current_form->value)
+            return_value = CURL_FORMADD_MEMORY;
+          else {
+            current_form->flags |= HTTPPOST_READFILE;
+            current_form->value_alloc = TRUE;
+          }
+        }
+        else
+          return_value = CURL_FORMADD_NULL;
+      }
+      break;
+
+      /* We upload a file */
+    case CURLFORM_FILE:
+      {
+        const char *filename = array_state?array_value:
+          va_arg(params, char *);
+
+        if(current_form->value) {
+          if(current_form->flags & HTTPPOST_FILENAME) {
+            if(filename) {
+              char *fname = strdup(filename);
+              if(!fname)
+                return_value = CURL_FORMADD_MEMORY;
+              else {
+                form = AddFormInfo(fname, NULL, current_form);
+                if(!form) {
+                  free(fname);
+                  return_value = CURL_FORMADD_MEMORY;
+                }
+                else {
+                  form->value_alloc = TRUE;
+                  current_form = form;
+                  form = NULL;
+                }
+              }
+            }
+            else
+              return_value = CURL_FORMADD_NULL;
+          }
+          else
+            return_value = CURL_FORMADD_OPTION_TWICE;
+        }
+        else {
+          if(filename) {
+            current_form->value = strdup(filename);
+            if(!current_form->value)
+              return_value = CURL_FORMADD_MEMORY;
+            else {
+              current_form->flags |= HTTPPOST_FILENAME;
+              current_form->value_alloc = TRUE;
+            }
+          }
+          else
+            return_value = CURL_FORMADD_NULL;
+        }
+        break;
+      }
+
+    case CURLFORM_BUFFERPTR:
+      current_form->flags |= HTTPPOST_PTRBUFFER|HTTPPOST_BUFFER;
+      if(current_form->buffer)
+        return_value = CURL_FORMADD_OPTION_TWICE;
+      else {
+        char *buffer =
+          array_state?array_value:va_arg(params, char *);
+        if(buffer) {
+          current_form->buffer = buffer; /* store for the moment */
+          current_form->value = buffer; /* make it non-NULL to be accepted
+                                           as fine */
+        }
+        else
+          return_value = CURL_FORMADD_NULL;
+      }
+      break;
+
+    case CURLFORM_BUFFERLENGTH:
+      if(current_form->bufferlength)
+        return_value = CURL_FORMADD_OPTION_TWICE;
+      else
+        current_form->bufferlength =
+          array_state?(size_t)array_value:(size_t)va_arg(params, long);
+      break;
+
+    case CURLFORM_STREAM:
+      current_form->flags |= HTTPPOST_CALLBACK;
+      if(current_form->userp)
+        return_value = CURL_FORMADD_OPTION_TWICE;
+      else {
+        char *userp =
+          array_state?array_value:va_arg(params, char *);
+        if(userp) {
+          current_form->userp = userp;
+          current_form->value = userp; /* this isn't strictly true but we
+                                          derive a value from this later on
+                                          and we need this non-NULL to be
+                                          accepted as a fine form part */
+        }
+        else
+          return_value = CURL_FORMADD_NULL;
+      }
+      break;
+
+    case CURLFORM_CONTENTTYPE:
+      {
+        const char *contenttype =
+          array_state?array_value:va_arg(params, char *);
+        if(current_form->contenttype) {
+          if(current_form->flags & HTTPPOST_FILENAME) {
+            if(contenttype) {
+              char *type = strdup(contenttype);
+              if(!type)
+                return_value = CURL_FORMADD_MEMORY;
+              else {
+                form = AddFormInfo(NULL, type, current_form);
+                if(!form) {
+                  free(type);
+                  return_value = CURL_FORMADD_MEMORY;
+                }
+                else {
+                  form->contenttype_alloc = TRUE;
+                  current_form = form;
+                  form = NULL;
+                }
+              }
+            }
+            else
+              return_value = CURL_FORMADD_NULL;
+          }
+          else
+            return_value = CURL_FORMADD_OPTION_TWICE;
+        }
+        else {
+          if(contenttype) {
+            current_form->contenttype = strdup(contenttype);
+            if(!current_form->contenttype)
+              return_value = CURL_FORMADD_MEMORY;
+            else
+              current_form->contenttype_alloc = TRUE;
+          }
+          else
+            return_value = CURL_FORMADD_NULL;
+        }
+        break;
+      }
+    case CURLFORM_CONTENTHEADER:
+      {
+        /* this "cast increases required alignment of target type" but
+           we consider it OK anyway */
+        struct curl_slist *list = array_state?
+          (struct curl_slist *)(void *)array_value:
+          va_arg(params, struct curl_slist *);
+
+        if(current_form->contentheader)
+          return_value = CURL_FORMADD_OPTION_TWICE;
+        else
+          current_form->contentheader = list;
+
+        break;
+      }
+    case CURLFORM_FILENAME:
+    case CURLFORM_BUFFER:
+      {
+        const char *filename = array_state?array_value:
+          va_arg(params, char *);
+        if(current_form->showfilename)
+          return_value = CURL_FORMADD_OPTION_TWICE;
+        else {
+          current_form->showfilename = strdup(filename);
+          if(!current_form->showfilename)
+            return_value = CURL_FORMADD_MEMORY;
+          else
+            current_form->showfilename_alloc = TRUE;
+        }
+        break;
+      }
+    default:
+      return_value = CURL_FORMADD_UNKNOWN_OPTION;
+      break;
+    }
+  }
+
+  if(CURL_FORMADD_OK != return_value) {
+    /* On error, free allocated fields for all nodes of the FormInfo linked
+       list without deallocating nodes. List nodes are deallocated later on */
+    FormInfo *ptr;
+    for(ptr = first_form; ptr != NULL; ptr = ptr->more) {
+      if(ptr->name_alloc) {
+        Curl_safefree(ptr->name);
+        ptr->name_alloc = FALSE;
+      }
+      if(ptr->value_alloc) {
+        Curl_safefree(ptr->value);
+        ptr->value_alloc = FALSE;
+      }
+      if(ptr->contenttype_alloc) {
+        Curl_safefree(ptr->contenttype);
+        ptr->contenttype_alloc = FALSE;
+      }
+      if(ptr->showfilename_alloc) {
+        Curl_safefree(ptr->showfilename);
+        ptr->showfilename_alloc = FALSE;
+      }
+    }
+  }
+
+  if(CURL_FORMADD_OK == return_value) {
+    /* go through the list, check for completeness and if everything is
+     * alright add the HttpPost item otherwise set return_value accordingly */
+
+    post = NULL;
+    for(form = first_form;
+        form != NULL;
+        form = form->more) {
+      if(((!form->name || !form->value) && !post) ||
+         ( (form->contentslength) &&
+           (form->flags & HTTPPOST_FILENAME) ) ||
+         ( (form->flags & HTTPPOST_FILENAME) &&
+           (form->flags & HTTPPOST_PTRCONTENTS) ) ||
+
+         ( (!form->buffer) &&
+           (form->flags & HTTPPOST_BUFFER) &&
+           (form->flags & HTTPPOST_PTRBUFFER) ) ||
+
+         ( (form->flags & HTTPPOST_READFILE) &&
+           (form->flags & HTTPPOST_PTRCONTENTS) )
+        ) {
+        return_value = CURL_FORMADD_INCOMPLETE;
+        break;
+      }
+      if(((form->flags & HTTPPOST_FILENAME) ||
+          (form->flags & HTTPPOST_BUFFER)) &&
+         !form->contenttype) {
+        char *f = form->flags & HTTPPOST_BUFFER?
+          form->showfilename : form->value;
+
+        /* our contenttype is missing */
+        form->contenttype = strdup(ContentTypeForFilename(f, prevtype));
+        if(!form->contenttype) {
+          return_value = CURL_FORMADD_MEMORY;
+          break;
+        }
+        form->contenttype_alloc = TRUE;
+      }
+      if(form->name && form->namelength) {
+        /* Name should not contain nul bytes. */
+        size_t i;
+        for(i = 0; i < form->namelength; i++)
+          if(!form->name[i]) {
+            return_value = CURL_FORMADD_NULL;
+            break;
+          }
+        if(return_value != CURL_FORMADD_OK)
+          break;
+      }
+      if(!(form->flags & HTTPPOST_PTRNAME) &&
+         (form == first_form) ) {
+        /* Note that there's small risk that form->name is NULL here if the
+           app passed in a bad combo, so we better check for that first. */
+        if(form->name) {
+          /* copy name (without strdup; possibly not nul-terminated) */
+          form->name = Curl_memdup(form->name, form->namelength?
+                                   form->namelength:
+                                   strlen(form->name) + 1);
+        }
+        if(!form->name) {
+          return_value = CURL_FORMADD_MEMORY;
+          break;
+        }
+        form->name_alloc = TRUE;
+      }
+      if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE |
+                          HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER |
+                          HTTPPOST_CALLBACK)) && form->value) {
+        /* copy value (without strdup; possibly contains null characters) */
+        size_t clen  = (size_t) form->contentslength;
+        if(!clen)
+          clen = strlen(form->value) + 1;
+
+        form->value = Curl_memdup(form->value, clen);
+
+        if(!form->value) {
+          return_value = CURL_FORMADD_MEMORY;
+          break;
+        }
+        form->value_alloc = TRUE;
+      }
+      post = AddHttpPost(form->name, form->namelength,
+                         form->value, form->contentslength,
+                         form->buffer, form->bufferlength,
+                         form->contenttype, form->flags,
+                         form->contentheader, form->showfilename,
+                         form->userp,
+                         post, httppost,
+                         last_post);
+
+      if(!post) {
+        return_value = CURL_FORMADD_MEMORY;
+        break;
+      }
+
+      if(form->contenttype)
+        prevtype = form->contenttype;
+    }
+    if(CURL_FORMADD_OK != return_value) {
+      /* On error, free allocated fields for nodes of the FormInfo linked
+         list which are not already owned by the httppost linked list
+         without deallocating nodes. List nodes are deallocated later on */
+      FormInfo *ptr;
+      for(ptr = form; ptr != NULL; ptr = ptr->more) {
+        if(ptr->name_alloc) {
+          Curl_safefree(ptr->name);
+          ptr->name_alloc = FALSE;
+        }
+        if(ptr->value_alloc) {
+          Curl_safefree(ptr->value);
+          ptr->value_alloc = FALSE;
+        }
+        if(ptr->contenttype_alloc) {
+          Curl_safefree(ptr->contenttype);
+          ptr->contenttype_alloc = FALSE;
+        }
+        if(ptr->showfilename_alloc) {
+          Curl_safefree(ptr->showfilename);
+          ptr->showfilename_alloc = FALSE;
+        }
+      }
+    }
+  }
+
+  /* Always deallocate FormInfo linked list nodes without touching node
+     fields given that these have either been deallocated or are owned
+     now by the httppost linked list */
+  while(first_form) {
+    FormInfo *ptr = first_form->more;
+    free(first_form);
+    first_form = ptr;
+  }
+
+  return return_value;
+}
+
+/*
+ * curl_formadd() is a public API to add a section to the multipart formpost.
+ *
+ * @unittest: 1308
+ */
+
+CURLFORMcode curl_formadd(struct curl_httppost **httppost,
+                          struct curl_httppost **last_post,
+                          ...)
+{
+  va_list arg;
+  CURLFORMcode result;
+  va_start(arg, last_post);
+  result = FormAdd(httppost, last_post, arg);
+  va_end(arg);
+  return result;
+}
+
+/*
+ * curl_formget()
+ * Serialize a curl_httppost struct.
+ * Returns 0 on success.
+ *
+ * @unittest: 1308
+ */
+int curl_formget(struct curl_httppost *form, void *arg,
+                 curl_formget_callback append)
+{
+  CURLcode result;
+  curl_mimepart toppart;
+
+  Curl_mime_initpart(&toppart, NULL); /* default form is empty */
+  result = Curl_getformdata(NULL, &toppart, form, NULL);
+  if(!result)
+    result = Curl_mime_prepare_headers(&toppart, "multipart/form-data",
+                                       NULL, MIMESTRATEGY_FORM);
+
+  while(!result) {
+    char buffer[8192];
+    size_t nread = Curl_mime_read(buffer, 1, sizeof buffer, &toppart);
+
+    if(!nread)
+      break;
+
+    switch(nread) {
+    default:
+      if(append(arg, buffer, nread) != nread)
+        result = CURLE_READ_ERROR;
+      break;
+    case CURL_READFUNC_ABORT:
+    case CURL_READFUNC_PAUSE:
+      break;
+    }
+  }
+
+  Curl_mime_cleanpart(&toppart);
+  return (int) result;
+}
+
+/*
+ * curl_formfree() is an external function to free up a whole form post
+ * chain
+ */
+void curl_formfree(struct curl_httppost *form)
+{
+  struct curl_httppost *next;
+
+  if(!form)
+    /* no form to free, just get out of this */
+    return;
+
+  do {
+    next = form->next;  /* the following form line */
+
+    /* recurse to sub-contents */
+    curl_formfree(form->more);
+
+    if(!(form->flags & HTTPPOST_PTRNAME))
+      free(form->name); /* free the name */
+    if(!(form->flags &
+         (HTTPPOST_PTRCONTENTS|HTTPPOST_BUFFER|HTTPPOST_CALLBACK))
+      )
+      free(form->contents); /* free the contents */
+    free(form->contenttype); /* free the content type */
+    free(form->showfilename); /* free the faked file name */
+    free(form);       /* free the struct */
+    form = next;
+  } while(form); /* continue */
+}
+
+
+/* Set mime part name, taking care of non nul-terminated name string. */
+static CURLcode setname(curl_mimepart *part, const char *name, size_t len)
+{
+  char *zname;
+  CURLcode res;
+
+  if(!name || !len)
+    return curl_mime_name(part, name);
+  zname = malloc(len + 1);
+  if(!zname)
+    return CURLE_OUT_OF_MEMORY;
+  memcpy(zname, name, len);
+  zname[len] = '\0';
+  res = curl_mime_name(part, zname);
+  free(zname);
+  return res;
+}
+
+/*
+ * Curl_getformdata() converts a linked list of "meta data" into a mime
+ * structure. The input list is in 'post', while the output is stored in
+ * mime part at '*finalform'.
+ *
+ * This function will not do a failf() for the potential memory failures but
+ * should for all other errors it spots. Just note that this function MAY get
+ * a NULL pointer in the 'data' argument.
+ */
+
+CURLcode Curl_getformdata(struct Curl_easy *data,
+                          curl_mimepart *finalform,
+                          struct curl_httppost *post,
+                          curl_read_callback fread_func)
+{
+  CURLcode result = CURLE_OK;
+  curl_mime *form = NULL;
+  curl_mime *multipart;
+  curl_mimepart *part;
+  struct curl_httppost *file;
+
+  Curl_mime_cleanpart(finalform); /* default form is empty */
+
+  if(!post)
+    return result; /* no input => no output! */
+
+  form = curl_mime_init(data);
+  if(!form)
+    result = CURLE_OUT_OF_MEMORY;
+
+  if(!result)
+    result = curl_mime_subparts(finalform, form);
+
+  /* Process each top part. */
+  for(; !result && post; post = post->next) {
+    /* If we have more than a file here, create a mime subpart and fill it. */
+    multipart = form;
+    if(post->more) {
+      part = curl_mime_addpart(form);
+      if(!part)
+        result = CURLE_OUT_OF_MEMORY;
+      if(!result)
+        result = setname(part, post->name, post->namelength);
+      if(!result) {
+        multipart = curl_mime_init(data);
+        if(!multipart)
+          result = CURLE_OUT_OF_MEMORY;
+      }
+      if(!result)
+        result = curl_mime_subparts(part, multipart);
+    }
+
+    /* Generate all the part contents. */
+    for(file = post; !result && file; file = file->more) {
+      /* Create the part. */
+      part = curl_mime_addpart(multipart);
+      if(!part)
+        result = CURLE_OUT_OF_MEMORY;
+
+      /* Set the headers. */
+      if(!result)
+        result = curl_mime_headers(part, file->contentheader, 0);
+
+      /* Set the content type. */
+      if(!result && file->contenttype)
+        result = curl_mime_type(part, file->contenttype);
+
+      /* Set field name. */
+      if(!result && !post->more)
+        result = setname(part, post->name, post->namelength);
+
+      /* Process contents. */
+      if(!result) {
+        curl_off_t clen = post->contentslength;
+
+        if(post->flags & CURL_HTTPPOST_LARGE)
+          clen = post->contentlen;
+        if(!clen)
+          clen = -1;
+
+        if(post->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE)) {
+          if(!strcmp(file->contents, "-")) {
+            /* There are a few cases where the code below won't work; in
+               particular, freopen(stdin) by the caller is not guaranteed
+               to result as expected. This feature has been kept for backward
+               compatibility: use of "-" pseudo file name should be avoided. */
+            result = curl_mime_data_cb(part, (curl_off_t) -1,
+                                       (curl_read_callback) fread,
+                                       (curl_seek_callback) fseek,
+                                       NULL, (void *) stdin);
+          }
+          else
+            result = curl_mime_filedata(part, file->contents);
+          if(!result && (post->flags & HTTPPOST_READFILE))
+            result = curl_mime_filename(part, NULL);
+        }
+        else if(post->flags & HTTPPOST_BUFFER)
+          result = curl_mime_data(part, post->buffer,
+                                  post->bufferlength? post->bufferlength: -1);
+        else if(post->flags & HTTPPOST_CALLBACK)
+          /* the contents should be read with the callback and the size is set
+             with the contentslength */
+          result = curl_mime_data_cb(part, clen,
+                                     fread_func, NULL, NULL, post->userp);
+        else {
+          result = curl_mime_data(part, post->contents, (ssize_t) clen);
+#ifdef CURL_DOES_CONVERSIONS
+          /* Convert textual contents now. */
+          if(!result && data && part->datasize)
+            result = Curl_convert_to_network(data, part->data, part->datasize);
+#endif
+        }
+      }
+
+      /* Set fake file name. */
+      if(!result && post->showfilename)
+        if(post->more || (post->flags & (HTTPPOST_FILENAME | HTTPPOST_BUFFER |
+                                        HTTPPOST_CALLBACK)))
+          result = curl_mime_filename(part, post->showfilename);
+    }
+  }
+
+  if(result)
+    Curl_mime_cleanpart(finalform);
+
+  return result;
+}
+
+#else  /* CURL_DISABLE_HTTP */
+CURLFORMcode curl_formadd(struct curl_httppost **httppost,
+                          struct curl_httppost **last_post,
+                          ...)
+{
+  (void)httppost;
+  (void)last_post;
+  return CURL_FORMADD_DISABLED;
+}
+
+int curl_formget(struct curl_httppost *form, void *arg,
+                 curl_formget_callback append)
+{
+  (void) form;
+  (void) arg;
+  (void) append;
+  return CURL_FORMADD_DISABLED;
+}
+
+void curl_formfree(struct curl_httppost *form)
+{
+  (void)form;
+  /* does nothing HTTP is disabled */
+}
+
+
+#endif  /* !defined(CURL_DISABLE_HTTP) */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/formdata.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/formdata.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/formdata.h	(revision 331)
@@ -0,0 +1,51 @@
+#ifndef HEADER_CURL_FORMDATA_H
+#define HEADER_CURL_FORMDATA_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* used by FormAdd for temporary storage */
+typedef struct FormInfo {
+  char *name;
+  bool name_alloc;
+  size_t namelength;
+  char *value;
+  bool value_alloc;
+  curl_off_t contentslength;
+  char *contenttype;
+  bool contenttype_alloc;
+  long flags;
+  char *buffer;      /* pointer to existing buffer used for file upload */
+  size_t bufferlength;
+  char *showfilename; /* The file name to show. If not set, the actual
+                         file name will be used */
+  bool showfilename_alloc;
+  char *userp;        /* pointer for the read callback */
+  struct curl_slist *contentheader;
+  struct FormInfo *more;
+} FormInfo;
+
+CURLcode Curl_getformdata(struct Curl_easy *data,
+                          curl_mimepart *,
+                          struct curl_httppost *post,
+                          curl_read_callback fread_func);
+
+#endif /* HEADER_CURL_FORMDATA_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/ftp.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/ftp.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/ftp.c	(revision 331)
@@ -0,0 +1,4480 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_FTP
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "if2ip.h"
+#include "hostip.h"
+#include "progress.h"
+#include "transfer.h"
+#include "escape.h"
+#include "http.h" /* for HTTP proxy tunnel stuff */
+#include "socks.h"
+#include "ftp.h"
+#include "fileinfo.h"
+#include "ftplistparser.h"
+#include "curl_sec.h"
+#include "strtoofft.h"
+#include "strcase.h"
+#include "vtls/vtls.h"
+#include "connect.h"
+#include "strerror.h"
+#include "inet_ntop.h"
+#include "inet_pton.h"
+#include "select.h"
+#include "parsedate.h" /* for the week day and month names */
+#include "sockaddr.h" /* required for Curl_sockaddr_storage */
+#include "multiif.h"
+#include "url.h"
+#include "strcase.h"
+#include "speedcheck.h"
+#include "warnless.h"
+#include "http_proxy.h"
+#include "non-ascii.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifndef NI_MAXHOST
+#define NI_MAXHOST 1025
+#endif
+#ifndef INET_ADDRSTRLEN
+#define INET_ADDRSTRLEN 16
+#endif
+
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+#define ftp_pasv_verbose(a,b,c,d)  Curl_nop_stmt
+#endif
+
+/* Local API functions */
+#ifndef DEBUGBUILD
+static void _state(struct connectdata *conn,
+                   ftpstate newstate);
+#define state(x,y) _state(x,y)
+#else
+static void _state(struct connectdata *conn,
+                   ftpstate newstate,
+                   int lineno);
+#define state(x,y) _state(x,y,__LINE__)
+#endif
+
+static CURLcode ftp_sendquote(struct connectdata *conn,
+                              struct curl_slist *quote);
+static CURLcode ftp_quit(struct connectdata *conn);
+static CURLcode ftp_parse_url_path(struct connectdata *conn);
+static CURLcode ftp_regular_transfer(struct connectdata *conn, bool *done);
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+static void ftp_pasv_verbose(struct connectdata *conn,
+                             Curl_addrinfo *ai,
+                             char *newhost, /* ascii version */
+                             int port);
+#endif
+static CURLcode ftp_state_prepare_transfer(struct connectdata *conn);
+static CURLcode ftp_state_mdtm(struct connectdata *conn);
+static CURLcode ftp_state_quote(struct connectdata *conn,
+                                bool init, ftpstate instate);
+static CURLcode ftp_nb_type(struct connectdata *conn,
+                            bool ascii, ftpstate newstate);
+static int ftp_need_type(struct connectdata *conn,
+                         bool ascii);
+static CURLcode ftp_do(struct connectdata *conn, bool *done);
+static CURLcode ftp_done(struct connectdata *conn,
+                         CURLcode, bool premature);
+static CURLcode ftp_connect(struct connectdata *conn, bool *done);
+static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection);
+static CURLcode ftp_do_more(struct connectdata *conn, int *completed);
+static CURLcode ftp_multi_statemach(struct connectdata *conn, bool *done);
+static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks,
+                       int numsocks);
+static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
+                              int numsocks);
+static CURLcode ftp_doing(struct connectdata *conn,
+                          bool *dophase_done);
+static CURLcode ftp_setup_connection(struct connectdata * conn);
+
+static CURLcode init_wc_data(struct connectdata *conn);
+static CURLcode wc_statemach(struct connectdata *conn);
+
+static void wc_data_dtor(void *ptr);
+
+static CURLcode ftp_state_retr(struct connectdata *conn, curl_off_t filesize);
+
+static CURLcode ftp_readresp(curl_socket_t sockfd,
+                             struct pingpong *pp,
+                             int *ftpcode,
+                             size_t *size);
+static CURLcode ftp_dophase_done(struct connectdata *conn,
+                                 bool connected);
+
+/* easy-to-use macro: */
+#define PPSENDF(x,y,z)  result = Curl_pp_sendf(x,y,z); \
+                        if(result)                     \
+                          return result
+
+
+/*
+ * FTP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_ftp = {
+  "FTP",                           /* scheme */
+  ftp_setup_connection,            /* setup_connection */
+  ftp_do,                          /* do_it */
+  ftp_done,                        /* done */
+  ftp_do_more,                     /* do_more */
+  ftp_connect,                     /* connect_it */
+  ftp_multi_statemach,             /* connecting */
+  ftp_doing,                       /* doing */
+  ftp_getsock,                     /* proto_getsock */
+  ftp_getsock,                     /* doing_getsock */
+  ftp_domore_getsock,              /* domore_getsock */
+  ZERO_NULL,                       /* perform_getsock */
+  ftp_disconnect,                  /* disconnect */
+  ZERO_NULL,                       /* readwrite */
+  ZERO_NULL,                       /* connection_check */
+  PORT_FTP,                        /* defport */
+  CURLPROTO_FTP,                   /* protocol */
+  PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD |
+  PROTOPT_NOURLQUERY | PROTOPT_PROXY_AS_HTTP |
+  PROTOPT_WILDCARD /* flags */
+};
+
+
+#ifdef USE_SSL
+/*
+ * FTPS protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_ftps = {
+  "FTPS",                          /* scheme */
+  ftp_setup_connection,            /* setup_connection */
+  ftp_do,                          /* do_it */
+  ftp_done,                        /* done */
+  ftp_do_more,                     /* do_more */
+  ftp_connect,                     /* connect_it */
+  ftp_multi_statemach,             /* connecting */
+  ftp_doing,                       /* doing */
+  ftp_getsock,                     /* proto_getsock */
+  ftp_getsock,                     /* doing_getsock */
+  ftp_domore_getsock,              /* domore_getsock */
+  ZERO_NULL,                       /* perform_getsock */
+  ftp_disconnect,                  /* disconnect */
+  ZERO_NULL,                       /* readwrite */
+  ZERO_NULL,                       /* connection_check */
+  PORT_FTPS,                       /* defport */
+  CURLPROTO_FTPS,                  /* protocol */
+  PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION |
+  PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY | PROTOPT_WILDCARD /* flags */
+};
+#endif
+
+static void close_secondarysocket(struct connectdata *conn)
+{
+  if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) {
+    Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
+    conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
+  }
+  conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
+}
+
+/*
+ * NOTE: back in the old days, we added code in the FTP code that made NOBODY
+ * requests on files respond with headers passed to the client/stdout that
+ * looked like HTTP ones.
+ *
+ * This approach is not very elegant, it causes confusion and is error-prone.
+ * It is subject for removal at the next (or at least a future) soname bump.
+ * Until then you can test the effects of the removal by undefining the
+ * following define named CURL_FTP_HTTPSTYLE_HEAD.
+ */
+#define CURL_FTP_HTTPSTYLE_HEAD 1
+
+static void freedirs(struct ftp_conn *ftpc)
+{
+  int i;
+  if(ftpc->dirs) {
+    for(i = 0; i < ftpc->dirdepth; i++) {
+      free(ftpc->dirs[i]);
+      ftpc->dirs[i] = NULL;
+    }
+    free(ftpc->dirs);
+    ftpc->dirs = NULL;
+    ftpc->dirdepth = 0;
+  }
+  Curl_safefree(ftpc->file);
+
+  /* no longer of any use */
+  Curl_safefree(ftpc->newhost);
+}
+
+/* Returns non-zero if the given string contains CR (\r) or LF (\n),
+   which are not allowed within RFC 959 <string>.
+   Note: The input string is in the client's encoding which might
+   not be ASCII, so escape sequences \r & \n must be used instead
+   of hex values 0x0d & 0x0a.
+*/
+static bool isBadFtpString(const char *string)
+{
+  return ((NULL != strchr(string, '\r')) ||
+          (NULL != strchr(string, '\n'))) ? TRUE : FALSE;
+}
+
+/***********************************************************************
+ *
+ * AcceptServerConnect()
+ *
+ * After connection request is received from the server this function is
+ * called to accept the connection and close the listening socket
+ *
+ */
+static CURLcode AcceptServerConnect(struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  curl_socket_t sock = conn->sock[SECONDARYSOCKET];
+  curl_socket_t s = CURL_SOCKET_BAD;
+#ifdef ENABLE_IPV6
+  struct Curl_sockaddr_storage add;
+#else
+  struct sockaddr_in add;
+#endif
+  curl_socklen_t size = (curl_socklen_t) sizeof(add);
+
+  if(0 == getsockname(sock, (struct sockaddr *) &add, &size)) {
+    size = sizeof(add);
+
+    s = accept(sock, (struct sockaddr *) &add, &size);
+  }
+  Curl_closesocket(conn, sock); /* close the first socket */
+
+  if(CURL_SOCKET_BAD == s) {
+    failf(data, "Error accept()ing server connect");
+    return CURLE_FTP_PORT_FAILED;
+  }
+  infof(data, "Connection accepted from server\n");
+  /* when this happens within the DO state it is important that we mark us as
+     not needing DO_MORE anymore */
+  conn->bits.do_more = FALSE;
+
+  conn->sock[SECONDARYSOCKET] = s;
+  (void)curlx_nonblock(s, TRUE); /* enable non-blocking */
+  conn->sock_accepted[SECONDARYSOCKET] = TRUE;
+
+  if(data->set.fsockopt) {
+    int error = 0;
+
+    /* activate callback for setting socket options */
+    error = data->set.fsockopt(data->set.sockopt_client,
+                               s,
+                               CURLSOCKTYPE_ACCEPT);
+
+    if(error) {
+      close_secondarysocket(conn);
+      return CURLE_ABORTED_BY_CALLBACK;
+    }
+  }
+
+  return CURLE_OK;
+
+}
+
+/*
+ * ftp_timeleft_accept() returns the amount of milliseconds left allowed for
+ * waiting server to connect. If the value is negative, the timeout time has
+ * already elapsed.
+ *
+ * The start time is stored in progress.t_acceptdata - as set with
+ * Curl_pgrsTime(..., TIMER_STARTACCEPT);
+ *
+ */
+static timediff_t ftp_timeleft_accept(struct Curl_easy *data)
+{
+  timediff_t timeout_ms = DEFAULT_ACCEPT_TIMEOUT;
+  timediff_t other;
+  struct curltime now;
+
+  if(data->set.accepttimeout > 0)
+    timeout_ms = data->set.accepttimeout;
+
+  now = Curl_now();
+
+  /* check if the generic timeout possibly is set shorter */
+  other =  Curl_timeleft(data, &now, FALSE);
+  if(other && (other < timeout_ms))
+    /* note that this also works fine for when other happens to be negative
+       due to it already having elapsed */
+    timeout_ms = other;
+  else {
+    /* subtract elapsed time */
+    timeout_ms -= Curl_timediff(now, data->progress.t_acceptdata);
+    if(!timeout_ms)
+      /* avoid returning 0 as that means no timeout! */
+      return -1;
+  }
+
+  return timeout_ms;
+}
+
+
+/***********************************************************************
+ *
+ * ReceivedServerConnect()
+ *
+ * After allowing server to connect to us from data port, this function
+ * checks both data connection for connection establishment and ctrl
+ * connection for a negative response regarding a failure in connecting
+ *
+ */
+static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received)
+{
+  struct Curl_easy *data = conn->data;
+  curl_socket_t ctrl_sock = conn->sock[FIRSTSOCKET];
+  curl_socket_t data_sock = conn->sock[SECONDARYSOCKET];
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  struct pingpong *pp = &ftpc->pp;
+  int result;
+  time_t timeout_ms;
+  ssize_t nread;
+  int ftpcode;
+
+  *received = FALSE;
+
+  timeout_ms = ftp_timeleft_accept(data);
+  infof(data, "Checking for server connect\n");
+  if(timeout_ms < 0) {
+    /* if a timeout was already reached, bail out */
+    failf(data, "Accept timeout occurred while waiting server connect");
+    return CURLE_FTP_ACCEPT_TIMEOUT;
+  }
+
+  /* First check whether there is a cached response from server */
+  if(pp->cache_size && pp->cache && pp->cache[0] > '3') {
+    /* Data connection could not be established, let's return */
+    infof(data, "There is negative response in cache while serv connect\n");
+    Curl_GetFTPResponse(&nread, conn, &ftpcode);
+    return CURLE_FTP_ACCEPT_FAILED;
+  }
+
+  result = Curl_socket_check(ctrl_sock, data_sock, CURL_SOCKET_BAD, 0);
+
+  /* see if the connection request is already here */
+  switch(result) {
+  case -1: /* error */
+    /* let's die here */
+    failf(data, "Error while waiting for server connect");
+    return CURLE_FTP_ACCEPT_FAILED;
+  case 0:  /* Server connect is not received yet */
+    break; /* loop */
+  default:
+
+    if(result & CURL_CSELECT_IN2) {
+      infof(data, "Ready to accept data connection from server\n");
+      *received = TRUE;
+    }
+    else if(result & CURL_CSELECT_IN) {
+      infof(data, "Ctrl conn has data while waiting for data conn\n");
+      Curl_GetFTPResponse(&nread, conn, &ftpcode);
+
+      if(ftpcode/100 > 3)
+        return CURLE_FTP_ACCEPT_FAILED;
+
+      return CURLE_WEIRD_SERVER_REPLY;
+    }
+
+    break;
+  } /* switch() */
+
+  return CURLE_OK;
+}
+
+
+/***********************************************************************
+ *
+ * InitiateTransfer()
+ *
+ * After connection from server is accepted this function is called to
+ * setup transfer parameters and initiate the data transfer.
+ *
+ */
+static CURLcode InitiateTransfer(struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  struct FTP *ftp = data->req.protop;
+  CURLcode result = CURLE_OK;
+
+  if(conn->bits.ftp_use_data_ssl) {
+    /* since we only have a plaintext TCP connection here, we must now
+     * do the TLS stuff */
+    infof(data, "Doing the SSL/TLS handshake on the data stream\n");
+    result = Curl_ssl_connect(conn, SECONDARYSOCKET);
+    if(result)
+      return result;
+  }
+
+  if(conn->proto.ftpc.state_saved == FTP_STOR) {
+    *(ftp->bytecountp) = 0;
+
+    /* When we know we're uploading a specified file, we can get the file
+       size prior to the actual upload. */
+
+    Curl_pgrsSetUploadSize(data, data->state.infilesize);
+
+    /* set the SO_SNDBUF for the secondary socket for those who need it */
+    Curl_sndbufset(conn->sock[SECONDARYSOCKET]);
+
+    Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
+                        SECONDARYSOCKET, ftp->bytecountp);
+  }
+  else {
+    /* FTP download: */
+    Curl_setup_transfer(conn, SECONDARYSOCKET,
+                        conn->proto.ftpc.retr_size_saved, FALSE,
+                        ftp->bytecountp, -1, NULL); /* no upload here */
+  }
+
+  conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */
+  state(conn, FTP_STOP);
+
+  return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * AllowServerConnect()
+ *
+ * When we've issue the PORT command, we have told the server to connect to
+ * us. This function checks whether data connection is established if so it is
+ * accepted.
+ *
+ */
+static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected)
+{
+  struct Curl_easy *data = conn->data;
+  time_t timeout_ms;
+  CURLcode result = CURLE_OK;
+
+  *connected = FALSE;
+  infof(data, "Preparing for accepting server on data port\n");
+
+  /* Save the time we start accepting server connect */
+  Curl_pgrsTime(data, TIMER_STARTACCEPT);
+
+  timeout_ms = ftp_timeleft_accept(data);
+  if(timeout_ms < 0) {
+    /* if a timeout was already reached, bail out */
+    failf(data, "Accept timeout occurred while waiting server connect");
+    return CURLE_FTP_ACCEPT_TIMEOUT;
+  }
+
+  /* see if the connection request is already here */
+  result = ReceivedServerConnect(conn, connected);
+  if(result)
+    return result;
+
+  if(*connected) {
+    result = AcceptServerConnect(conn);
+    if(result)
+      return result;
+
+    result = InitiateTransfer(conn);
+    if(result)
+      return result;
+  }
+  else {
+    /* Add timeout to multi handle and break out of the loop */
+    if(!result && *connected == FALSE) {
+      Curl_expire(data, data->set.accepttimeout > 0 ?
+                  data->set.accepttimeout: DEFAULT_ACCEPT_TIMEOUT, 0);
+    }
+  }
+
+  return result;
+}
+
+/* macro to check for a three-digit ftp status code at the start of the
+   given string */
+#define STATUSCODE(line) (ISDIGIT(line[0]) && ISDIGIT(line[1]) &&       \
+                          ISDIGIT(line[2]))
+
+/* macro to check for the last line in an FTP server response */
+#define LASTLINE(line) (STATUSCODE(line) && (' ' == line[3]))
+
+static bool ftp_endofresp(struct connectdata *conn, char *line, size_t len,
+                          int *code)
+{
+  (void)conn;
+
+  if((len > 3) && LASTLINE(line)) {
+    *code = curlx_sltosi(strtol(line, NULL, 10));
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+static CURLcode ftp_readresp(curl_socket_t sockfd,
+                             struct pingpong *pp,
+                             int *ftpcode, /* return the ftp-code if done */
+                             size_t *size) /* size of the response */
+{
+  struct connectdata *conn = pp->conn;
+  struct Curl_easy *data = conn->data;
+#ifdef HAVE_GSSAPI
+  char * const buf = data->state.buffer;
+#endif
+  CURLcode result = CURLE_OK;
+  int code;
+
+  result = Curl_pp_readresp(sockfd, pp, &code, size);
+
+#if defined(HAVE_GSSAPI)
+  /* handle the security-oriented responses 6xx ***/
+  /* FIXME: some errorchecking perhaps... ***/
+  switch(code) {
+  case 631:
+    code = Curl_sec_read_msg(conn, buf, PROT_SAFE);
+    break;
+  case 632:
+    code = Curl_sec_read_msg(conn, buf, PROT_PRIVATE);
+    break;
+  case 633:
+    code = Curl_sec_read_msg(conn, buf, PROT_CONFIDENTIAL);
+    break;
+  default:
+    /* normal ftp stuff we pass through! */
+    break;
+  }
+#endif
+
+  /* store the latest code for later retrieval */
+  data->info.httpcode = code;
+
+  if(ftpcode)
+    *ftpcode = code;
+
+  if(421 == code) {
+    /* 421 means "Service not available, closing control connection." and FTP
+     * servers use it to signal that idle session timeout has been exceeded.
+     * If we ignored the response, it could end up hanging in some cases.
+     *
+     * This response code can come at any point so having it treated
+     * generically is a good idea.
+     */
+    infof(data, "We got a 421 - timeout!\n");
+    state(conn, FTP_STOP);
+    return CURLE_OPERATION_TIMEDOUT;
+  }
+
+  return result;
+}
+
+/* --- parse FTP server responses --- */
+
+/*
+ * Curl_GetFTPResponse() is a BLOCKING function to read the full response
+ * from a server after a command.
+ *
+ */
+
+CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
+                             struct connectdata *conn,
+                             int *ftpcode) /* return the ftp-code */
+{
+  /*
+   * We cannot read just one byte per read() and then go back to select() as
+   * the OpenSSL read() doesn't grok that properly.
+   *
+   * Alas, read as much as possible, split up into lines, use the ending
+   * line in a response or continue reading.  */
+
+  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+  time_t timeout;              /* timeout in milliseconds */
+  time_t interval_ms;
+  struct Curl_easy *data = conn->data;
+  CURLcode result = CURLE_OK;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  struct pingpong *pp = &ftpc->pp;
+  size_t nread;
+  int cache_skip = 0;
+  int value_to_be_ignored = 0;
+
+  if(ftpcode)
+    *ftpcode = 0; /* 0 for errors */
+  else
+    /* make the pointer point to something for the rest of this function */
+    ftpcode = &value_to_be_ignored;
+
+  *nreadp = 0;
+
+  while(!*ftpcode && !result) {
+    /* check and reset timeout value every lap */
+    timeout = Curl_pp_state_timeout(pp);
+
+    if(timeout <= 0) {
+      failf(data, "FTP response timeout");
+      return CURLE_OPERATION_TIMEDOUT; /* already too little time */
+    }
+
+    interval_ms = 1000;  /* use 1 second timeout intervals */
+    if(timeout < interval_ms)
+      interval_ms = timeout;
+
+    /*
+     * Since this function is blocking, we need to wait here for input on the
+     * connection and only then we call the response reading function. We do
+     * timeout at least every second to make the timeout check run.
+     *
+     * A caution here is that the ftp_readresp() function has a cache that may
+     * contain pieces of a response from the previous invoke and we need to
+     * make sure we don't just wait for input while there is unhandled data in
+     * that cache. But also, if the cache is there, we call ftp_readresp() and
+     * the cache wasn't good enough to continue we must not just busy-loop
+     * around this function.
+     *
+     */
+
+    if(pp->cache && (cache_skip < 2)) {
+      /*
+       * There's a cache left since before. We then skipping the wait for
+       * socket action, unless this is the same cache like the previous round
+       * as then the cache was deemed not enough to act on and we then need to
+       * wait for more data anyway.
+       */
+    }
+    else if(!Curl_conn_data_pending(conn, FIRSTSOCKET)) {
+      switch(SOCKET_READABLE(sockfd, interval_ms)) {
+      case -1: /* select() error, stop reading */
+        failf(data, "FTP response aborted due to select/poll error: %d",
+              SOCKERRNO);
+        return CURLE_RECV_ERROR;
+
+      case 0: /* timeout */
+        if(Curl_pgrsUpdate(conn))
+          return CURLE_ABORTED_BY_CALLBACK;
+        continue; /* just continue in our loop for the timeout duration */
+
+      default: /* for clarity */
+        break;
+      }
+    }
+    result = ftp_readresp(sockfd, pp, ftpcode, &nread);
+    if(result)
+      break;
+
+    if(!nread && pp->cache)
+      /* bump cache skip counter as on repeated skips we must wait for more
+         data */
+      cache_skip++;
+    else
+      /* when we got data or there is no cache left, we reset the cache skip
+         counter */
+      cache_skip = 0;
+
+    *nreadp += nread;
+
+  } /* while there's buffer left and loop is requested */
+
+  pp->pending_resp = FALSE;
+
+  return result;
+}
+
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* for debug purposes */
+static const char * const ftp_state_names[]={
+  "STOP",
+  "WAIT220",
+  "AUTH",
+  "USER",
+  "PASS",
+  "ACCT",
+  "PBSZ",
+  "PROT",
+  "CCC",
+  "PWD",
+  "SYST",
+  "NAMEFMT",
+  "QUOTE",
+  "RETR_PREQUOTE",
+  "STOR_PREQUOTE",
+  "POSTQUOTE",
+  "CWD",
+  "MKD",
+  "MDTM",
+  "TYPE",
+  "LIST_TYPE",
+  "RETR_TYPE",
+  "STOR_TYPE",
+  "SIZE",
+  "RETR_SIZE",
+  "STOR_SIZE",
+  "REST",
+  "RETR_REST",
+  "PORT",
+  "PRET",
+  "PASV",
+  "LIST",
+  "RETR",
+  "STOR",
+  "QUIT"
+};
+#endif
+
+/* This is the ONLY way to change FTP state! */
+static void _state(struct connectdata *conn,
+                   ftpstate newstate
+#ifdef DEBUGBUILD
+                   , int lineno
+#endif
+  )
+{
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+#if defined(DEBUGBUILD)
+
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void) lineno;
+#else
+  if(ftpc->state != newstate)
+    infof(conn->data, "FTP %p (line %d) state change from %s to %s\n",
+          (void *)ftpc, lineno, ftp_state_names[ftpc->state],
+          ftp_state_names[newstate]);
+#endif
+#endif
+
+  ftpc->state = newstate;
+}
+
+static CURLcode ftp_state_user(struct connectdata *conn)
+{
+  CURLcode result;
+  struct FTP *ftp = conn->data->req.protop;
+  /* send USER */
+  PPSENDF(&conn->proto.ftpc.pp, "USER %s", ftp->user?ftp->user:"");
+
+  state(conn, FTP_USER);
+  conn->data->state.ftp_trying_alternative = FALSE;
+
+  return CURLE_OK;
+}
+
+static CURLcode ftp_state_pwd(struct connectdata *conn)
+{
+  CURLcode result;
+
+  /* send PWD to discover our entry point */
+  PPSENDF(&conn->proto.ftpc.pp, "%s", "PWD");
+  state(conn, FTP_PWD);
+
+  return CURLE_OK;
+}
+
+/* For the FTP "protocol connect" and "doing" phases only */
+static int ftp_getsock(struct connectdata *conn,
+                       curl_socket_t *socks,
+                       int numsocks)
+{
+  return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks);
+}
+
+/* For the FTP "DO_MORE" phase only */
+static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
+                              int numsocks)
+{
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  if(!numsocks)
+    return GETSOCK_BLANK;
+
+  /* When in DO_MORE state, we could be either waiting for us to connect to a
+   * remote site, or we could wait for that site to connect to us. Or just
+   * handle ordinary commands.
+   */
+
+  if(FTP_STOP == ftpc->state) {
+    int bits = GETSOCK_READSOCK(0);
+
+    /* if stopped and still in this state, then we're also waiting for a
+       connect on the secondary connection */
+    socks[0] = conn->sock[FIRSTSOCKET];
+
+    if(!conn->data->set.ftp_use_port) {
+      int s;
+      int i;
+      /* PORT is used to tell the server to connect to us, and during that we
+         don't do happy eyeballs, but we do if we connect to the server */
+      for(s = 1, i = 0; i<2; i++) {
+        if(conn->tempsock[i] != CURL_SOCKET_BAD) {
+          socks[s] = conn->tempsock[i];
+          bits |= GETSOCK_WRITESOCK(s++);
+        }
+      }
+    }
+    else {
+      socks[1] = conn->sock[SECONDARYSOCKET];
+      bits |= GETSOCK_WRITESOCK(1) | GETSOCK_READSOCK(1);
+    }
+
+    return bits;
+  }
+  return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks);
+}
+
+/* This is called after the FTP_QUOTE state is passed.
+
+   ftp_state_cwd() sends the range of CWD commands to the server to change to
+   the correct directory. It may also need to send MKD commands to create
+   missing ones, if that option is enabled.
+*/
+static CURLcode ftp_state_cwd(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  if(ftpc->cwddone)
+    /* already done and fine */
+    result = ftp_state_mdtm(conn);
+  else {
+    ftpc->count2 = 0; /* count2 counts failed CWDs */
+
+    /* count3 is set to allow a MKD to fail once. In the case when first CWD
+       fails and then MKD fails (due to another session raced it to create the
+       dir) this then allows for a second try to CWD to it */
+    ftpc->count3 = (conn->data->set.ftp_create_missing_dirs == 2)?1:0;
+
+    if((conn->data->set.ftp_filemethod == FTPFILE_NOCWD) && !ftpc->cwdcount)
+      /* No CWD necessary */
+      result = ftp_state_mdtm(conn);
+    else if(conn->bits.reuse && ftpc->entrypath) {
+      /* This is a re-used connection. Since we change directory to where the
+         transfer is taking place, we must first get back to the original dir
+         where we ended up after login: */
+      ftpc->cwdcount = 0; /* we count this as the first path, then we add one
+                             for all upcoming ones in the ftp->dirs[] array */
+      PPSENDF(&conn->proto.ftpc.pp, "CWD %s", ftpc->entrypath);
+      state(conn, FTP_CWD);
+    }
+    else {
+      if(ftpc->dirdepth) {
+        ftpc->cwdcount = 1;
+        /* issue the first CWD, the rest is sent when the CWD responses are
+           received... */
+        PPSENDF(&conn->proto.ftpc.pp, "CWD %s", ftpc->dirs[ftpc->cwdcount -1]);
+        state(conn, FTP_CWD);
+      }
+      else {
+        /* No CWD necessary */
+        result = ftp_state_mdtm(conn);
+      }
+    }
+  }
+  return result;
+}
+
+typedef enum {
+  EPRT,
+  PORT,
+  DONE
+} ftpport;
+
+static CURLcode ftp_state_use_port(struct connectdata *conn,
+                                   ftpport fcmd) /* start with this */
+
+{
+  CURLcode result = CURLE_OK;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  struct Curl_easy *data = conn->data;
+  curl_socket_t portsock = CURL_SOCKET_BAD;
+  char myhost[256] = "";
+
+  struct Curl_sockaddr_storage ss;
+  Curl_addrinfo *res, *ai;
+  curl_socklen_t sslen;
+  char hbuf[NI_MAXHOST];
+  struct sockaddr *sa = (struct sockaddr *)&ss;
+  struct sockaddr_in * const sa4 = (void *)sa;
+#ifdef ENABLE_IPV6
+  struct sockaddr_in6 * const sa6 = (void *)sa;
+#endif
+  char tmp[1024];
+  static const char mode[][5] = { "EPRT", "PORT" };
+  int rc;
+  int error;
+  char *host = NULL;
+  char *string_ftpport = data->set.str[STRING_FTPPORT];
+  struct Curl_dns_entry *h = NULL;
+  unsigned short port_min = 0;
+  unsigned short port_max = 0;
+  unsigned short port;
+  bool possibly_non_local = TRUE;
+
+  char *addr = NULL;
+
+  /* Step 1, figure out what is requested,
+   * accepted format :
+   * (ipv4|ipv6|domain|interface)?(:port(-range)?)?
+   */
+
+  if(data->set.str[STRING_FTPPORT] &&
+     (strlen(data->set.str[STRING_FTPPORT]) > 1)) {
+
+#ifdef ENABLE_IPV6
+    size_t addrlen = INET6_ADDRSTRLEN > strlen(string_ftpport) ?
+      INET6_ADDRSTRLEN : strlen(string_ftpport);
+#else
+    size_t addrlen = INET_ADDRSTRLEN > strlen(string_ftpport) ?
+      INET_ADDRSTRLEN : strlen(string_ftpport);
+#endif
+    char *ip_start = string_ftpport;
+    char *ip_end = NULL;
+    char *port_start = NULL;
+    char *port_sep = NULL;
+
+    addr = calloc(addrlen + 1, 1);
+    if(!addr)
+      return CURLE_OUT_OF_MEMORY;
+
+#ifdef ENABLE_IPV6
+    if(*string_ftpport == '[') {
+      /* [ipv6]:port(-range) */
+      ip_start = string_ftpport + 1;
+      ip_end = strchr(string_ftpport, ']');
+      if(ip_end)
+        strncpy(addr, ip_start, ip_end - ip_start);
+    }
+    else
+#endif
+      if(*string_ftpport == ':') {
+        /* :port */
+        ip_end = string_ftpport;
+      }
+      else {
+        ip_end = strchr(string_ftpport, ':');
+        if(ip_end) {
+          /* either ipv6 or (ipv4|domain|interface):port(-range) */
+#ifdef ENABLE_IPV6
+          if(Curl_inet_pton(AF_INET6, string_ftpport, sa6) == 1) {
+            /* ipv6 */
+            port_min = port_max = 0;
+            strcpy(addr, string_ftpport);
+            ip_end = NULL; /* this got no port ! */
+          }
+          else
+#endif
+            /* (ipv4|domain|interface):port(-range) */
+            strncpy(addr, string_ftpport, ip_end - ip_start);
+        }
+        else
+          /* ipv4|interface */
+          strcpy(addr, string_ftpport);
+      }
+
+    /* parse the port */
+    if(ip_end != NULL) {
+      port_start = strchr(ip_end, ':');
+      if(port_start) {
+        port_min = curlx_ultous(strtoul(port_start + 1, NULL, 10));
+        port_sep = strchr(port_start, '-');
+        if(port_sep) {
+          port_max = curlx_ultous(strtoul(port_sep + 1, NULL, 10));
+        }
+        else
+          port_max = port_min;
+      }
+    }
+
+    /* correct errors like:
+     *  :1234-1230
+     *  :-4711,  in this case port_min is (unsigned)-1,
+     *           therefore port_min > port_max for all cases
+     *           but port_max = (unsigned)-1
+     */
+    if(port_min > port_max)
+      port_min = port_max = 0;
+
+
+    if(*addr != '\0') {
+      /* attempt to get the address of the given interface name */
+      switch(Curl_if2ip(conn->ip_addr->ai_family,
+                        Curl_ipv6_scope(conn->ip_addr->ai_addr),
+                        conn->scope_id, addr, hbuf, sizeof(hbuf))) {
+        case IF2IP_NOT_FOUND:
+          /* not an interface, use the given string as host name instead */
+          host = addr;
+          break;
+        case IF2IP_AF_NOT_SUPPORTED:
+          return CURLE_FTP_PORT_FAILED;
+        case IF2IP_FOUND:
+          host = hbuf; /* use the hbuf for host name */
+      }
+    }
+    else
+      /* there was only a port(-range) given, default the host */
+      host = NULL;
+  } /* data->set.ftpport */
+
+  if(!host) {
+    /* not an interface and not a host name, get default by extracting
+       the IP from the control connection */
+
+    sslen = sizeof(ss);
+    if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
+      failf(data, "getsockname() failed: %s",
+          Curl_strerror(conn, SOCKERRNO) );
+      free(addr);
+      return CURLE_FTP_PORT_FAILED;
+    }
+    switch(sa->sa_family) {
+#ifdef ENABLE_IPV6
+    case AF_INET6:
+      Curl_inet_ntop(sa->sa_family, &sa6->sin6_addr, hbuf, sizeof(hbuf));
+      break;
+#endif
+    default:
+      Curl_inet_ntop(sa->sa_family, &sa4->sin_addr, hbuf, sizeof(hbuf));
+      break;
+    }
+    host = hbuf; /* use this host name */
+    possibly_non_local = FALSE; /* we know it is local now */
+  }
+
+  /* resolv ip/host to ip */
+  rc = Curl_resolv(conn, host, 0, &h);
+  if(rc == CURLRESOLV_PENDING)
+    (void)Curl_resolver_wait_resolv(conn, &h);
+  if(h) {
+    res = h->addr;
+    /* when we return from this function, we can forget about this entry
+       to we can unlock it now already */
+    Curl_resolv_unlock(data, h);
+  } /* (h) */
+  else
+    res = NULL; /* failure! */
+
+  if(res == NULL) {
+    failf(data, "failed to resolve the address provided to PORT: %s", host);
+    free(addr);
+    return CURLE_FTP_PORT_FAILED;
+  }
+
+  free(addr);
+  host = NULL;
+
+  /* step 2, create a socket for the requested address */
+
+  portsock = CURL_SOCKET_BAD;
+  error = 0;
+  for(ai = res; ai; ai = ai->ai_next) {
+    result = Curl_socket(conn, ai, NULL, &portsock);
+    if(result) {
+      error = SOCKERRNO;
+      continue;
+    }
+    break;
+  }
+  if(!ai) {
+    failf(data, "socket failure: %s", Curl_strerror(conn, error));
+    return CURLE_FTP_PORT_FAILED;
+  }
+
+  /* step 3, bind to a suitable local address */
+
+  memcpy(sa, ai->ai_addr, ai->ai_addrlen);
+  sslen = ai->ai_addrlen;
+
+  for(port = port_min; port <= port_max;) {
+    if(sa->sa_family == AF_INET)
+      sa4->sin_port = htons(port);
+#ifdef ENABLE_IPV6
+    else
+      sa6->sin6_port = htons(port);
+#endif
+    /* Try binding the given address. */
+    if(bind(portsock, sa, sslen) ) {
+      /* It failed. */
+      error = SOCKERRNO;
+      if(possibly_non_local && (error == EADDRNOTAVAIL)) {
+        /* The requested bind address is not local.  Use the address used for
+         * the control connection instead and restart the port loop
+         */
+
+        infof(data, "bind(port=%hu) on non-local address failed: %s\n", port,
+              Curl_strerror(conn, error) );
+
+        sslen = sizeof(ss);
+        if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
+          failf(data, "getsockname() failed: %s",
+                Curl_strerror(conn, SOCKERRNO) );
+          Curl_closesocket(conn, portsock);
+          return CURLE_FTP_PORT_FAILED;
+        }
+        port = port_min;
+        possibly_non_local = FALSE; /* don't try this again */
+        continue;
+      }
+      if(error != EADDRINUSE && error != EACCES) {
+        failf(data, "bind(port=%hu) failed: %s", port,
+              Curl_strerror(conn, error) );
+        Curl_closesocket(conn, portsock);
+        return CURLE_FTP_PORT_FAILED;
+      }
+    }
+    else
+      break;
+
+    port++;
+  }
+
+  /* maybe all ports were in use already*/
+  if(port > port_max) {
+    failf(data, "bind() failed, we ran out of ports!");
+    Curl_closesocket(conn, portsock);
+    return CURLE_FTP_PORT_FAILED;
+  }
+
+  /* get the name again after the bind() so that we can extract the
+     port number it uses now */
+  sslen = sizeof(ss);
+  if(getsockname(portsock, (struct sockaddr *)sa, &sslen)) {
+    failf(data, "getsockname() failed: %s",
+          Curl_strerror(conn, SOCKERRNO) );
+    Curl_closesocket(conn, portsock);
+    return CURLE_FTP_PORT_FAILED;
+  }
+
+  /* step 4, listen on the socket */
+
+  if(listen(portsock, 1)) {
+    failf(data, "socket failure: %s", Curl_strerror(conn, SOCKERRNO));
+    Curl_closesocket(conn, portsock);
+    return CURLE_FTP_PORT_FAILED;
+  }
+
+  /* step 5, send the proper FTP command */
+
+  /* get a plain printable version of the numerical address to work with
+     below */
+  Curl_printable_address(ai, myhost, sizeof(myhost));
+
+#ifdef ENABLE_IPV6
+  if(!conn->bits.ftp_use_eprt && conn->bits.ipv6)
+    /* EPRT is disabled but we are connected to a IPv6 host, so we ignore the
+       request and enable EPRT again! */
+    conn->bits.ftp_use_eprt = TRUE;
+#endif
+
+  for(; fcmd != DONE; fcmd++) {
+
+    if(!conn->bits.ftp_use_eprt && (EPRT == fcmd))
+      /* if disabled, goto next */
+      continue;
+
+    if((PORT == fcmd) && sa->sa_family != AF_INET)
+      /* PORT is IPv4 only */
+      continue;
+
+    switch(sa->sa_family) {
+    case AF_INET:
+      port = ntohs(sa4->sin_port);
+      break;
+#ifdef ENABLE_IPV6
+    case AF_INET6:
+      port = ntohs(sa6->sin6_port);
+      break;
+#endif
+    default:
+      continue; /* might as well skip this */
+    }
+
+    if(EPRT == fcmd) {
+      /*
+       * Two fine examples from RFC2428;
+       *
+       * EPRT |1|132.235.1.2|6275|
+       *
+       * EPRT |2|1080::8:800:200C:417A|5282|
+       */
+
+      result = Curl_pp_sendf(&ftpc->pp, "%s |%d|%s|%hu|", mode[fcmd],
+                             sa->sa_family == AF_INET?1:2,
+                             myhost, port);
+      if(result) {
+        failf(data, "Failure sending EPRT command: %s",
+              curl_easy_strerror(result));
+        Curl_closesocket(conn, portsock);
+        /* don't retry using PORT */
+        ftpc->count1 = PORT;
+        /* bail out */
+        state(conn, FTP_STOP);
+        return result;
+      }
+      break;
+    }
+    if(PORT == fcmd) {
+      char *source = myhost;
+      char *dest = tmp;
+
+      /* translate x.x.x.x to x,x,x,x */
+      while(source && *source) {
+        if(*source == '.')
+          *dest = ',';
+        else
+          *dest = *source;
+        dest++;
+        source++;
+      }
+      *dest = 0;
+      snprintf(dest, 20, ",%d,%d", (int)(port>>8), (int)(port&0xff));
+
+      result = Curl_pp_sendf(&ftpc->pp, "%s %s", mode[fcmd], tmp);
+      if(result) {
+        failf(data, "Failure sending PORT command: %s",
+              curl_easy_strerror(result));
+        Curl_closesocket(conn, portsock);
+        /* bail out */
+        state(conn, FTP_STOP);
+        return result;
+      }
+      break;
+    }
+  }
+
+  /* store which command was sent */
+  ftpc->count1 = fcmd;
+
+  close_secondarysocket(conn);
+
+  /* we set the secondary socket variable to this for now, it is only so that
+     the cleanup function will close it in case we fail before the true
+     secondary stuff is made */
+  conn->sock[SECONDARYSOCKET] = portsock;
+
+  /* this tcpconnect assignment below is a hackish work-around to make the
+     multi interface with active FTP work - as it will not wait for a
+     (passive) connect in Curl_is_connected().
+
+     The *proper* fix is to make sure that the active connection from the
+     server is done in a non-blocking way. Currently, it is still BLOCKING.
+  */
+  conn->bits.tcpconnect[SECONDARYSOCKET] = TRUE;
+
+  state(conn, FTP_PORT);
+  return result;
+}
+
+static CURLcode ftp_state_use_pasv(struct connectdata *conn)
+{
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  CURLcode result = CURLE_OK;
+  /*
+    Here's the excecutive summary on what to do:
+
+    PASV is RFC959, expect:
+    227 Entering Passive Mode (a1,a2,a3,a4,p1,p2)
+
+    LPSV is RFC1639, expect:
+    228 Entering Long Passive Mode (4,4,a1,a2,a3,a4,2,p1,p2)
+
+    EPSV is RFC2428, expect:
+    229 Entering Extended Passive Mode (|||port|)
+
+  */
+
+  static const char mode[][5] = { "EPSV", "PASV" };
+  int modeoff;
+
+#ifdef PF_INET6
+  if(!conn->bits.ftp_use_epsv && conn->bits.ipv6)
+    /* EPSV is disabled but we are connected to a IPv6 host, so we ignore the
+       request and enable EPSV again! */
+    conn->bits.ftp_use_epsv = TRUE;
+#endif
+
+  modeoff = conn->bits.ftp_use_epsv?0:1;
+
+  PPSENDF(&ftpc->pp, "%s", mode[modeoff]);
+
+  ftpc->count1 = modeoff;
+  state(conn, FTP_PASV);
+  infof(conn->data, "Connect data stream passively\n");
+
+  return result;
+}
+
+/*
+ * ftp_state_prepare_transfer() starts PORT, PASV or PRET etc.
+ *
+ * REST is the last command in the chain of commands when a "head"-like
+ * request is made. Thus, if an actual transfer is to be made this is where we
+ * take off for real.
+ */
+static CURLcode ftp_state_prepare_transfer(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct FTP *ftp = conn->data->req.protop;
+  struct Curl_easy *data = conn->data;
+
+  if(ftp->transfer != FTPTRANSFER_BODY) {
+    /* doesn't transfer any data */
+
+    /* still possibly do PRE QUOTE jobs */
+    state(conn, FTP_RETR_PREQUOTE);
+    result = ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE);
+  }
+  else if(data->set.ftp_use_port) {
+    /* We have chosen to use the PORT (or similar) command */
+    result = ftp_state_use_port(conn, EPRT);
+  }
+  else {
+    /* We have chosen (this is default) to use the PASV (or similar) command */
+    if(data->set.ftp_use_pret) {
+      /* The user has requested that we send a PRET command
+         to prepare the server for the upcoming PASV */
+      if(!conn->proto.ftpc.file) {
+        PPSENDF(&conn->proto.ftpc.pp, "PRET %s",
+                data->set.str[STRING_CUSTOMREQUEST]?
+                data->set.str[STRING_CUSTOMREQUEST]:
+                (data->set.ftp_list_only?"NLST":"LIST"));
+      }
+      else if(data->set.upload) {
+        PPSENDF(&conn->proto.ftpc.pp, "PRET STOR %s", conn->proto.ftpc.file);
+      }
+      else {
+        PPSENDF(&conn->proto.ftpc.pp, "PRET RETR %s", conn->proto.ftpc.file);
+      }
+      state(conn, FTP_PRET);
+    }
+    else {
+      result = ftp_state_use_pasv(conn);
+    }
+  }
+  return result;
+}
+
+static CURLcode ftp_state_rest(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct FTP *ftp = conn->data->req.protop;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  if((ftp->transfer != FTPTRANSFER_BODY) && ftpc->file) {
+    /* if a "head"-like request is being made (on a file) */
+
+    /* Determine if server can respond to REST command and therefore
+       whether it supports range */
+    PPSENDF(&conn->proto.ftpc.pp, "REST %d", 0);
+
+    state(conn, FTP_REST);
+  }
+  else
+    result = ftp_state_prepare_transfer(conn);
+
+  return result;
+}
+
+static CURLcode ftp_state_size(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct FTP *ftp = conn->data->req.protop;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  if((ftp->transfer == FTPTRANSFER_INFO) && ftpc->file) {
+    /* if a "head"-like request is being made (on a file) */
+
+    /* we know ftpc->file is a valid pointer to a file name */
+    PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file);
+
+    state(conn, FTP_SIZE);
+  }
+  else
+    result = ftp_state_rest(conn);
+
+  return result;
+}
+
+static CURLcode ftp_state_list(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  /* If this output is to be machine-parsed, the NLST command might be better
+     to use, since the LIST command output is not specified or standard in any
+     way. It has turned out that the NLST list output is not the same on all
+     servers either... */
+
+  /*
+     if FTPFILE_NOCWD was specified, we are currently in
+     the user's home directory, so we should add the path
+     as argument for the LIST / NLST / or custom command.
+     Whether the server will support this, is uncertain.
+
+     The other ftp_filemethods will CWD into dir/dir/ first and
+     then just do LIST (in that case: nothing to do here)
+  */
+  char *cmd, *lstArg, *slashPos;
+  const char *inpath = data->state.path;
+
+  lstArg = NULL;
+  if((data->set.ftp_filemethod == FTPFILE_NOCWD) &&
+     inpath && inpath[0] && strchr(inpath, '/')) {
+    size_t n = strlen(inpath);
+
+    /* Check if path does not end with /, as then we cut off the file part */
+    if(inpath[n - 1] != '/') {
+      /* chop off the file part if format is dir/dir/file */
+      slashPos = strrchr(inpath, '/');
+      n = slashPos - inpath;
+    }
+    result = Curl_urldecode(data, inpath, n, &lstArg, NULL, FALSE);
+    if(result)
+      return result;
+  }
+
+  cmd = aprintf("%s%s%s",
+                data->set.str[STRING_CUSTOMREQUEST]?
+                data->set.str[STRING_CUSTOMREQUEST]:
+                (data->set.ftp_list_only?"NLST":"LIST"),
+                lstArg? " ": "",
+                lstArg? lstArg: "");
+
+  if(!cmd) {
+    free(lstArg);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", cmd);
+
+  free(lstArg);
+  free(cmd);
+
+  if(result)
+    return result;
+
+  state(conn, FTP_LIST);
+
+  return result;
+}
+
+static CURLcode ftp_state_retr_prequote(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  /* We've sent the TYPE, now we must send the list of prequote strings */
+
+  result = ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE);
+
+  return result;
+}
+
+static CURLcode ftp_state_stor_prequote(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  /* We've sent the TYPE, now we must send the list of prequote strings */
+
+  result = ftp_state_quote(conn, TRUE, FTP_STOR_PREQUOTE);
+
+  return result;
+}
+
+static CURLcode ftp_state_type(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct FTP *ftp = conn->data->req.protop;
+  struct Curl_easy *data = conn->data;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  /* If we have selected NOBODY and HEADER, it means that we only want file
+     information. Which in FTP can't be much more than the file size and
+     date. */
+  if(data->set.opt_no_body && ftpc->file &&
+     ftp_need_type(conn, data->set.prefer_ascii)) {
+    /* The SIZE command is _not_ RFC 959 specified, and therefor many servers
+       may not support it! It is however the only way we have to get a file's
+       size! */
+
+    ftp->transfer = FTPTRANSFER_INFO;
+    /* this means no actual transfer will be made */
+
+    /* Some servers return different sizes for different modes, and thus we
+       must set the proper type before we check the size */
+    result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_TYPE);
+    if(result)
+      return result;
+  }
+  else
+    result = ftp_state_size(conn);
+
+  return result;
+}
+
+/* This is called after the CWD commands have been done in the beginning of
+   the DO phase */
+static CURLcode ftp_state_mdtm(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  /* Requested time of file or time-depended transfer? */
+  if((data->set.get_filetime || data->set.timecondition) && ftpc->file) {
+
+    /* we have requested to get the modified-time of the file, this is a white
+       spot as the MDTM is not mentioned in RFC959 */
+    PPSENDF(&ftpc->pp, "MDTM %s", ftpc->file);
+
+    state(conn, FTP_MDTM);
+  }
+  else
+    result = ftp_state_type(conn);
+
+  return result;
+}
+
+
+/* This is called after the TYPE and possible quote commands have been sent */
+static CURLcode ftp_state_ul_setup(struct connectdata *conn,
+                                   bool sizechecked)
+{
+  CURLcode result = CURLE_OK;
+  struct FTP *ftp = conn->data->req.protop;
+  struct Curl_easy *data = conn->data;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  int seekerr = CURL_SEEKFUNC_OK;
+
+  if((data->state.resume_from && !sizechecked) ||
+     ((data->state.resume_from > 0) && sizechecked)) {
+    /* we're about to continue the uploading of a file */
+    /* 1. get already existing file's size. We use the SIZE command for this
+       which may not exist in the server!  The SIZE command is not in
+       RFC959. */
+
+    /* 2. This used to set REST. But since we can do append, we
+       don't another ftp command. We just skip the source file
+       offset and then we APPEND the rest on the file instead */
+
+    /* 3. pass file-size number of bytes in the source file */
+    /* 4. lower the infilesize counter */
+    /* => transfer as usual */
+
+    if(data->state.resume_from < 0) {
+      /* Got no given size to start from, figure it out */
+      PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file);
+      state(conn, FTP_STOR_SIZE);
+      return result;
+    }
+
+    /* enable append */
+    data->set.ftp_append = TRUE;
+
+    /* Let's read off the proper amount of bytes from the input. */
+    if(conn->seek_func) {
+      seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
+                                SEEK_SET);
+    }
+
+    if(seekerr != CURL_SEEKFUNC_OK) {
+      curl_off_t passed = 0;
+      if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
+        failf(data, "Could not seek stream");
+        return CURLE_FTP_COULDNT_USE_REST;
+      }
+      /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
+      do {
+        size_t readthisamountnow =
+          (data->state.resume_from - passed > data->set.buffer_size) ?
+          (size_t)data->set.buffer_size :
+          curlx_sotouz(data->state.resume_from - passed);
+
+        size_t actuallyread =
+          data->state.fread_func(data->state.buffer, 1, readthisamountnow,
+                                 data->state.in);
+
+        passed += actuallyread;
+        if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
+          /* this checks for greater-than only to make sure that the
+             CURL_READFUNC_ABORT return code still aborts */
+          failf(data, "Failed to read data");
+          return CURLE_FTP_COULDNT_USE_REST;
+        }
+      } while(passed < data->state.resume_from);
+    }
+    /* now, decrease the size of the read */
+    if(data->state.infilesize>0) {
+      data->state.infilesize -= data->state.resume_from;
+
+      if(data->state.infilesize <= 0) {
+        infof(data, "File already completely uploaded\n");
+
+        /* no data to transfer */
+        Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+
+        /* Set ->transfer so that we won't get any error in
+         * ftp_done() because we didn't transfer anything! */
+        ftp->transfer = FTPTRANSFER_NONE;
+
+        state(conn, FTP_STOP);
+        return CURLE_OK;
+      }
+    }
+    /* we've passed, proceed as normal */
+  } /* resume_from */
+
+  PPSENDF(&ftpc->pp, data->set.ftp_append?"APPE %s":"STOR %s",
+          ftpc->file);
+
+  state(conn, FTP_STOR);
+
+  return result;
+}
+
+static CURLcode ftp_state_quote(struct connectdata *conn,
+                                bool init,
+                                ftpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct FTP *ftp = data->req.protop;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  bool quote = FALSE;
+  struct curl_slist *item;
+
+  switch(instate) {
+  case FTP_QUOTE:
+  default:
+    item = data->set.quote;
+    break;
+  case FTP_RETR_PREQUOTE:
+  case FTP_STOR_PREQUOTE:
+    item = data->set.prequote;
+    break;
+  case FTP_POSTQUOTE:
+    item = data->set.postquote;
+    break;
+  }
+
+  /*
+   * This state uses:
+   * 'count1' to iterate over the commands to send
+   * 'count2' to store whether to allow commands to fail
+   */
+
+  if(init)
+    ftpc->count1 = 0;
+  else
+    ftpc->count1++;
+
+  if(item) {
+    int i = 0;
+
+    /* Skip count1 items in the linked list */
+    while((i< ftpc->count1) && item) {
+      item = item->next;
+      i++;
+    }
+    if(item) {
+      char *cmd = item->data;
+      if(cmd[0] == '*') {
+        cmd++;
+        ftpc->count2 = 1; /* the sent command is allowed to fail */
+      }
+      else
+        ftpc->count2 = 0; /* failure means cancel operation */
+
+      PPSENDF(&ftpc->pp, "%s", cmd);
+      state(conn, instate);
+      quote = TRUE;
+    }
+  }
+
+  if(!quote) {
+    /* No more quote to send, continue to ... */
+    switch(instate) {
+    case FTP_QUOTE:
+    default:
+      result = ftp_state_cwd(conn);
+      break;
+    case FTP_RETR_PREQUOTE:
+      if(ftp->transfer != FTPTRANSFER_BODY)
+        state(conn, FTP_STOP);
+      else {
+        if(ftpc->known_filesize != -1) {
+          Curl_pgrsSetDownloadSize(data, ftpc->known_filesize);
+          result = ftp_state_retr(conn, ftpc->known_filesize);
+        }
+        else {
+          if(data->set.ignorecl) {
+            /* This code is to support download of growing files.  It prevents
+               the state machine from requesting the file size from the
+               server.  With an unknown file size the download continues until
+               the server terminates it, otherwise the client stops if the
+               received byte count exceeds the reported file size.  Set option
+               CURLOPT_IGNORE_CONTENT_LENGTH to 1 to enable this behavior.*/
+            PPSENDF(&ftpc->pp, "RETR %s", ftpc->file);
+            state(conn, FTP_RETR);
+          }
+          else {
+            PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file);
+            state(conn, FTP_RETR_SIZE);
+          }
+        }
+      }
+      break;
+    case FTP_STOR_PREQUOTE:
+      result = ftp_state_ul_setup(conn, FALSE);
+      break;
+    case FTP_POSTQUOTE:
+      break;
+    }
+  }
+
+  return result;
+}
+
+/* called from ftp_state_pasv_resp to switch to PASV in case of EPSV
+   problems */
+static CURLcode ftp_epsv_disable(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  if(conn->bits.ipv6) {
+    /* We can't disable EPSV when doing IPv6, so this is instead a fail */
+    failf(conn->data, "Failed EPSV attempt, exiting\n");
+    return CURLE_WEIRD_SERVER_REPLY;
+  }
+
+  infof(conn->data, "Failed EPSV attempt. Disabling EPSV\n");
+  /* disable it for next transfer */
+  conn->bits.ftp_use_epsv = FALSE;
+  conn->data->state.errorbuf = FALSE; /* allow error message to get
+                                         rewritten */
+  PPSENDF(&conn->proto.ftpc.pp, "%s", "PASV");
+  conn->proto.ftpc.count1++;
+  /* remain in/go to the FTP_PASV state */
+  state(conn, FTP_PASV);
+  return result;
+}
+
+
+static char *control_address(struct connectdata *conn)
+{
+  /* Returns the control connection IP address.
+     If a proxy tunnel is used, returns the original host name instead, because
+     the effective control connection address is the proxy address,
+     not the ftp host. */
+  if(conn->bits.tunnel_proxy || conn->bits.socksproxy)
+    return conn->host.name;
+
+  return conn->ip_addr_str;
+}
+
+static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
+                                    int ftpcode)
+{
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  CURLcode result;
+  struct Curl_easy *data = conn->data;
+  struct Curl_dns_entry *addr = NULL;
+  int rc;
+  unsigned short connectport; /* the local port connect() should use! */
+  char *str = &data->state.buffer[4];  /* start on the first letter */
+
+  /* if we come here again, make sure the former name is cleared */
+  Curl_safefree(ftpc->newhost);
+
+  if((ftpc->count1 == 0) &&
+     (ftpcode == 229)) {
+    /* positive EPSV response */
+    char *ptr = strchr(str, '(');
+    if(ptr) {
+      unsigned int num;
+      char separator[4];
+      ptr++;
+      if(5 == sscanf(ptr, "%c%c%c%u%c",
+                     &separator[0],
+                     &separator[1],
+                     &separator[2],
+                     &num,
+                     &separator[3])) {
+        const char sep1 = separator[0];
+        int i;
+
+        /* The four separators should be identical, or else this is an oddly
+           formatted reply and we bail out immediately. */
+        for(i = 1; i<4; i++) {
+          if(separator[i] != sep1) {
+            ptr = NULL; /* set to NULL to signal error */
+            break;
+          }
+        }
+        if(num > 0xffff) {
+          failf(data, "Illegal port number in EPSV reply");
+          return CURLE_FTP_WEIRD_PASV_REPLY;
+        }
+        if(ptr) {
+          ftpc->newport = (unsigned short)(num & 0xffff);
+          ftpc->newhost = strdup(control_address(conn));
+          if(!ftpc->newhost)
+            return CURLE_OUT_OF_MEMORY;
+        }
+      }
+      else
+        ptr = NULL;
+    }
+    if(!ptr) {
+      failf(data, "Weirdly formatted EPSV reply");
+      return CURLE_FTP_WEIRD_PASV_REPLY;
+    }
+  }
+  else if((ftpc->count1 == 1) &&
+          (ftpcode == 227)) {
+    /* positive PASV response */
+    unsigned int ip[4];
+    unsigned int port[2];
+
+    /*
+     * Scan for a sequence of six comma-separated numbers and use them as
+     * IP+port indicators.
+     *
+     * Found reply-strings include:
+     * "227 Entering Passive Mode (127,0,0,1,4,51)"
+     * "227 Data transfer will passively listen to 127,0,0,1,4,51"
+     * "227 Entering passive mode. 127,0,0,1,4,51"
+     */
+    while(*str) {
+      if(6 == sscanf(str, "%u,%u,%u,%u,%u,%u",
+                     &ip[0], &ip[1], &ip[2], &ip[3],
+                     &port[0], &port[1]))
+        break;
+      str++;
+    }
+
+    if(!*str || (ip[0] > 255) || (ip[1] > 255)  || (ip[2] > 255)  ||
+       (ip[3] > 255) || (port[0] > 255)  || (port[1] > 255) ) {
+      failf(data, "Couldn't interpret the 227-response");
+      return CURLE_FTP_WEIRD_227_FORMAT;
+    }
+
+    /* we got OK from server */
+    if(data->set.ftp_skip_ip) {
+      /* told to ignore the remotely given IP but instead use the host we used
+         for the control connection */
+      infof(data, "Skip %d.%d.%d.%d for data connection, re-use %s instead\n",
+            ip[0], ip[1], ip[2], ip[3],
+            conn->host.name);
+      ftpc->newhost = strdup(control_address(conn));
+    }
+    else
+      ftpc->newhost = aprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
+
+    if(!ftpc->newhost)
+      return CURLE_OUT_OF_MEMORY;
+
+    ftpc->newport = (unsigned short)(((port[0]<<8) + port[1]) & 0xffff);
+  }
+  else if(ftpc->count1 == 0) {
+    /* EPSV failed, move on to PASV */
+    return ftp_epsv_disable(conn);
+  }
+  else {
+    failf(data, "Bad PASV/EPSV response: %03d", ftpcode);
+    return CURLE_FTP_WEIRD_PASV_REPLY;
+  }
+
+  if(conn->bits.proxy) {
+    /*
+     * This connection uses a proxy and we need to connect to the proxy again
+     * here. We don't want to rely on a former host lookup that might've
+     * expired now, instead we remake the lookup here and now!
+     */
+    const char * const host_name = conn->bits.socksproxy ?
+      conn->socks_proxy.host.name : conn->http_proxy.host.name;
+    rc = Curl_resolv(conn, host_name, (int)conn->port, &addr);
+    if(rc == CURLRESOLV_PENDING)
+      /* BLOCKING, ignores the return code but 'addr' will be NULL in
+         case of failure */
+      (void)Curl_resolver_wait_resolv(conn, &addr);
+
+    connectport =
+      (unsigned short)conn->port; /* we connect to the proxy's port */
+
+    if(!addr) {
+      failf(data, "Can't resolve proxy host %s:%hu", host_name, connectport);
+      return CURLE_COULDNT_RESOLVE_PROXY;
+    }
+  }
+  else {
+    /* normal, direct, ftp connection */
+    rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, &addr);
+    if(rc == CURLRESOLV_PENDING)
+      /* BLOCKING */
+      (void)Curl_resolver_wait_resolv(conn, &addr);
+
+    connectport = ftpc->newport; /* we connect to the remote port */
+
+    if(!addr) {
+      failf(data, "Can't resolve new host %s:%hu", ftpc->newhost, connectport);
+      return CURLE_FTP_CANT_GET_HOST;
+    }
+  }
+
+  conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE;
+  result = Curl_connecthost(conn, addr);
+
+  if(result) {
+    Curl_resolv_unlock(data, addr); /* we're done using this address */
+    if(ftpc->count1 == 0 && ftpcode == 229)
+      return ftp_epsv_disable(conn);
+
+    return result;
+  }
+
+
+  /*
+   * When this is used from the multi interface, this might've returned with
+   * the 'connected' set to FALSE and thus we are now awaiting a non-blocking
+   * connect to connect.
+   */
+
+  if(data->set.verbose)
+    /* this just dumps information about this second connection */
+    ftp_pasv_verbose(conn, addr->addr, ftpc->newhost, connectport);
+
+  Curl_resolv_unlock(data, addr); /* we're done using this address */
+
+  Curl_safefree(conn->secondaryhostname);
+  conn->secondary_port = ftpc->newport;
+  conn->secondaryhostname = strdup(ftpc->newhost);
+  if(!conn->secondaryhostname)
+    return CURLE_OUT_OF_MEMORY;
+
+  conn->bits.do_more = TRUE;
+  state(conn, FTP_STOP); /* this phase is completed */
+
+  return result;
+}
+
+static CURLcode ftp_state_port_resp(struct connectdata *conn,
+                                    int ftpcode)
+{
+  struct Curl_easy *data = conn->data;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  ftpport fcmd = (ftpport)ftpc->count1;
+  CURLcode result = CURLE_OK;
+
+  /* The FTP spec tells a positive response should have code 200.
+     Be more permissive here to tolerate deviant servers. */
+  if(ftpcode / 100 != 2) {
+    /* the command failed */
+
+    if(EPRT == fcmd) {
+      infof(data, "disabling EPRT usage\n");
+      conn->bits.ftp_use_eprt = FALSE;
+    }
+    fcmd++;
+
+    if(fcmd == DONE) {
+      failf(data, "Failed to do PORT");
+      result = CURLE_FTP_PORT_FAILED;
+    }
+    else
+      /* try next */
+      result = ftp_state_use_port(conn, fcmd);
+  }
+  else {
+    infof(data, "Connect data stream actively\n");
+    state(conn, FTP_STOP); /* end of DO phase */
+    result = ftp_dophase_done(conn, FALSE);
+  }
+
+  return result;
+}
+
+static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
+                                    int ftpcode)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct FTP *ftp = data->req.protop;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  switch(ftpcode) {
+  case 213:
+    {
+      /* we got a time. Format should be: "YYYYMMDDHHMMSS[.sss]" where the
+         last .sss part is optional and means fractions of a second */
+      int year, month, day, hour, minute, second;
+      if(6 == sscanf(&data->state.buffer[4], "%04d%02d%02d%02d%02d%02d",
+                     &year, &month, &day, &hour, &minute, &second)) {
+        /* we have a time, reformat it */
+        char timebuf[24];
+        time_t secs = time(NULL);
+
+        snprintf(timebuf, sizeof(timebuf),
+                 "%04d%02d%02d %02d:%02d:%02d GMT",
+                 year, month, day, hour, minute, second);
+        /* now, convert this into a time() value: */
+        data->info.filetime = (long)curl_getdate(timebuf, &secs);
+      }
+
+#ifdef CURL_FTP_HTTPSTYLE_HEAD
+      /* If we asked for a time of the file and we actually got one as well,
+         we "emulate" a HTTP-style header in our output. */
+
+      if(data->set.opt_no_body &&
+         ftpc->file &&
+         data->set.get_filetime &&
+         (data->info.filetime >= 0) ) {
+        char headerbuf[128];
+        time_t filetime = (time_t)data->info.filetime;
+        struct tm buffer;
+        const struct tm *tm = &buffer;
+
+        result = Curl_gmtime(filetime, &buffer);
+        if(result)
+          return result;
+
+        /* format: "Tue, 15 Nov 1994 12:45:26" */
+        snprintf(headerbuf, sizeof(headerbuf),
+                 "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
+                 Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
+                 tm->tm_mday,
+                 Curl_month[tm->tm_mon],
+                 tm->tm_year + 1900,
+                 tm->tm_hour,
+                 tm->tm_min,
+                 tm->tm_sec);
+        result = Curl_client_write(conn, CLIENTWRITE_BOTH, headerbuf, 0);
+        if(result)
+          return result;
+      } /* end of a ridiculous amount of conditionals */
+#endif
+    }
+    break;
+  default:
+    infof(data, "unsupported MDTM reply format\n");
+    break;
+  case 550: /* "No such file or directory" */
+    failf(data, "Given file does not exist");
+    result = CURLE_FTP_COULDNT_RETR_FILE;
+    break;
+  }
+
+  if(data->set.timecondition) {
+    if((data->info.filetime > 0) && (data->set.timevalue > 0)) {
+      switch(data->set.timecondition) {
+      case CURL_TIMECOND_IFMODSINCE:
+      default:
+        if(data->info.filetime <= data->set.timevalue) {
+          infof(data, "The requested document is not new enough\n");
+          ftp->transfer = FTPTRANSFER_NONE; /* mark to not transfer data */
+          data->info.timecond = TRUE;
+          state(conn, FTP_STOP);
+          return CURLE_OK;
+        }
+        break;
+      case CURL_TIMECOND_IFUNMODSINCE:
+        if(data->info.filetime > data->set.timevalue) {
+          infof(data, "The requested document is not old enough\n");
+          ftp->transfer = FTPTRANSFER_NONE; /* mark to not transfer data */
+          data->info.timecond = TRUE;
+          state(conn, FTP_STOP);
+          return CURLE_OK;
+        }
+        break;
+      } /* switch */
+    }
+    else {
+      infof(data, "Skipping time comparison\n");
+    }
+  }
+
+  if(!result)
+    result = ftp_state_type(conn);
+
+  return result;
+}
+
+static CURLcode ftp_state_type_resp(struct connectdata *conn,
+                                    int ftpcode,
+                                    ftpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  if(ftpcode/100 != 2) {
+    /* "sasserftpd" and "(u)r(x)bot ftpd" both responds with 226 after a
+       successful 'TYPE I'. While that is not as RFC959 says, it is still a
+       positive response code and we allow that. */
+    failf(data, "Couldn't set desired mode");
+    return CURLE_FTP_COULDNT_SET_TYPE;
+  }
+  if(ftpcode != 200)
+    infof(data, "Got a %03d response code instead of the assumed 200\n",
+          ftpcode);
+
+  if(instate == FTP_TYPE)
+    result = ftp_state_size(conn);
+  else if(instate == FTP_LIST_TYPE)
+    result = ftp_state_list(conn);
+  else if(instate == FTP_RETR_TYPE)
+    result = ftp_state_retr_prequote(conn);
+  else if(instate == FTP_STOR_TYPE)
+    result = ftp_state_stor_prequote(conn);
+
+  return result;
+}
+
+static CURLcode ftp_state_retr(struct connectdata *conn,
+                                         curl_off_t filesize)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct FTP *ftp = data->req.protop;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  if(data->set.max_filesize && (filesize > data->set.max_filesize)) {
+    failf(data, "Maximum file size exceeded");
+    return CURLE_FILESIZE_EXCEEDED;
+  }
+  ftp->downloadsize = filesize;
+
+  if(data->state.resume_from) {
+    /* We always (attempt to) get the size of downloads, so it is done before
+       this even when not doing resumes. */
+    if(filesize == -1) {
+      infof(data, "ftp server doesn't support SIZE\n");
+      /* We couldn't get the size and therefore we can't know if there really
+         is a part of the file left to get, although the server will just
+         close the connection when we start the connection so it won't cause
+         us any harm, just not make us exit as nicely. */
+    }
+    else {
+      /* We got a file size report, so we check that there actually is a
+         part of the file left to get, or else we go home.  */
+      if(data->state.resume_from< 0) {
+        /* We're supposed to download the last abs(from) bytes */
+        if(filesize < -data->state.resume_from) {
+          failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
+                ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
+                data->state.resume_from, filesize);
+          return CURLE_BAD_DOWNLOAD_RESUME;
+        }
+        /* convert to size to download */
+        ftp->downloadsize = -data->state.resume_from;
+        /* download from where? */
+        data->state.resume_from = filesize - ftp->downloadsize;
+      }
+      else {
+        if(filesize < data->state.resume_from) {
+          failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
+                ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
+                data->state.resume_from, filesize);
+          return CURLE_BAD_DOWNLOAD_RESUME;
+        }
+        /* Now store the number of bytes we are expected to download */
+        ftp->downloadsize = filesize-data->state.resume_from;
+      }
+    }
+
+    if(ftp->downloadsize == 0) {
+      /* no data to transfer */
+      Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+      infof(data, "File already completely downloaded\n");
+
+      /* Set ->transfer so that we won't get any error in ftp_done()
+       * because we didn't transfer the any file */
+      ftp->transfer = FTPTRANSFER_NONE;
+      state(conn, FTP_STOP);
+      return CURLE_OK;
+    }
+
+    /* Set resume file transfer offset */
+    infof(data, "Instructs server to resume from offset %"
+          CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from);
+
+    PPSENDF(&ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T,
+            data->state.resume_from);
+
+    state(conn, FTP_RETR_REST);
+  }
+  else {
+    /* no resume */
+    PPSENDF(&ftpc->pp, "RETR %s", ftpc->file);
+    state(conn, FTP_RETR);
+  }
+
+  return result;
+}
+
+static CURLcode ftp_state_size_resp(struct connectdata *conn,
+                                    int ftpcode,
+                                    ftpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  curl_off_t filesize = -1;
+  char *buf = data->state.buffer;
+
+  /* get the size from the ascii string: */
+  if(ftpcode == 213)
+    /* ignores parsing errors, which will make the size remain unknown */
+    (void)curlx_strtoofft(buf + 4, NULL, 0, &filesize);
+
+  if(instate == FTP_SIZE) {
+#ifdef CURL_FTP_HTTPSTYLE_HEAD
+    if(-1 != filesize) {
+      char clbuf[128];
+      snprintf(clbuf, sizeof(clbuf),
+               "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", filesize);
+      result = Curl_client_write(conn, CLIENTWRITE_BOTH, clbuf, 0);
+      if(result)
+        return result;
+    }
+#endif
+    Curl_pgrsSetDownloadSize(data, filesize);
+    result = ftp_state_rest(conn);
+  }
+  else if(instate == FTP_RETR_SIZE) {
+    Curl_pgrsSetDownloadSize(data, filesize);
+    result = ftp_state_retr(conn, filesize);
+  }
+  else if(instate == FTP_STOR_SIZE) {
+    data->state.resume_from = filesize;
+    result = ftp_state_ul_setup(conn, TRUE);
+  }
+
+  return result;
+}
+
+static CURLcode ftp_state_rest_resp(struct connectdata *conn,
+                                    int ftpcode,
+                                    ftpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  switch(instate) {
+  case FTP_REST:
+  default:
+#ifdef CURL_FTP_HTTPSTYLE_HEAD
+    if(ftpcode == 350) {
+      char buffer[24]= { "Accept-ranges: bytes\r\n" };
+      result = Curl_client_write(conn, CLIENTWRITE_BOTH, buffer, 0);
+      if(result)
+        return result;
+    }
+#endif
+    result = ftp_state_prepare_transfer(conn);
+    break;
+
+  case FTP_RETR_REST:
+    if(ftpcode != 350) {
+      failf(conn->data, "Couldn't use REST");
+      result = CURLE_FTP_COULDNT_USE_REST;
+    }
+    else {
+      PPSENDF(&ftpc->pp, "RETR %s", ftpc->file);
+      state(conn, FTP_RETR);
+    }
+    break;
+  }
+
+  return result;
+}
+
+static CURLcode ftp_state_stor_resp(struct connectdata *conn,
+                                    int ftpcode, ftpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  if(ftpcode >= 400) {
+    failf(data, "Failed FTP upload: %0d", ftpcode);
+    state(conn, FTP_STOP);
+    /* oops, we never close the sockets! */
+    return CURLE_UPLOAD_FAILED;
+  }
+
+  conn->proto.ftpc.state_saved = instate;
+
+  /* PORT means we are now awaiting the server to connect to us. */
+  if(data->set.ftp_use_port) {
+    bool connected;
+
+    state(conn, FTP_STOP); /* no longer in STOR state */
+
+    result = AllowServerConnect(conn, &connected);
+    if(result)
+      return result;
+
+    if(!connected) {
+      struct ftp_conn *ftpc = &conn->proto.ftpc;
+      infof(data, "Data conn was not available immediately\n");
+      ftpc->wait_data_conn = TRUE;
+    }
+
+    return CURLE_OK;
+  }
+  return InitiateTransfer(conn);
+}
+
+/* for LIST and RETR responses */
+static CURLcode ftp_state_get_resp(struct connectdata *conn,
+                                    int ftpcode,
+                                    ftpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct FTP *ftp = data->req.protop;
+
+  if((ftpcode == 150) || (ftpcode == 125)) {
+
+    /*
+      A;
+      150 Opening BINARY mode data connection for /etc/passwd (2241
+      bytes).  (ok, the file is being transferred)
+
+      B:
+      150 Opening ASCII mode data connection for /bin/ls
+
+      C:
+      150 ASCII data connection for /bin/ls (137.167.104.91,37445) (0 bytes).
+
+      D:
+      150 Opening ASCII mode data connection for [file] (0.0.0.0,0) (545 bytes)
+
+      E:
+      125 Data connection already open; Transfer starting. */
+
+    curl_off_t size = -1; /* default unknown size */
+
+
+    /*
+     * It appears that there are FTP-servers that return size 0 for files when
+     * SIZE is used on the file while being in BINARY mode. To work around
+     * that (stupid) behavior, we attempt to parse the RETR response even if
+     * the SIZE returned size zero.
+     *
+     * Debugging help from Salvatore Sorrentino on February 26, 2003.
+     */
+
+    if((instate != FTP_LIST) &&
+       !data->set.prefer_ascii &&
+       (ftp->downloadsize < 1)) {
+      /*
+       * It seems directory listings either don't show the size or very
+       * often uses size 0 anyway. ASCII transfers may very well turn out
+       * that the transferred amount of data is not the same as this line
+       * tells, why using this number in those cases only confuses us.
+       *
+       * Example D above makes this parsing a little tricky */
+      char *bytes;
+      char *buf = data->state.buffer;
+      bytes = strstr(buf, " bytes");
+      if(bytes) {
+        long in = (long)(--bytes-buf);
+        /* this is a hint there is size information in there! ;-) */
+        while(--in) {
+          /* scan for the left parenthesis and break there */
+          if('(' == *bytes)
+            break;
+          /* skip only digits */
+          if(!ISDIGIT(*bytes)) {
+            bytes = NULL;
+            break;
+          }
+          /* one more estep backwards */
+          bytes--;
+        }
+        /* if we have nothing but digits: */
+        if(bytes++) {
+          /* get the number! */
+          (void)curlx_strtoofft(bytes, NULL, 0, &size);
+        }
+      }
+    }
+    else if(ftp->downloadsize > -1)
+      size = ftp->downloadsize;
+
+    if(size > data->req.maxdownload && data->req.maxdownload > 0)
+      size = data->req.size = data->req.maxdownload;
+    else if((instate != FTP_LIST) && (data->set.prefer_ascii))
+      size = -1; /* kludge for servers that understate ASCII mode file size */
+
+    infof(data, "Maxdownload = %" CURL_FORMAT_CURL_OFF_T "\n",
+          data->req.maxdownload);
+
+    if(instate != FTP_LIST)
+      infof(data, "Getting file with size: %" CURL_FORMAT_CURL_OFF_T "\n",
+            size);
+
+    /* FTP download: */
+    conn->proto.ftpc.state_saved = instate;
+    conn->proto.ftpc.retr_size_saved = size;
+
+    if(data->set.ftp_use_port) {
+      bool connected;
+
+      result = AllowServerConnect(conn, &connected);
+      if(result)
+        return result;
+
+      if(!connected) {
+        struct ftp_conn *ftpc = &conn->proto.ftpc;
+        infof(data, "Data conn was not available immediately\n");
+        state(conn, FTP_STOP);
+        ftpc->wait_data_conn = TRUE;
+      }
+    }
+    else
+      return InitiateTransfer(conn);
+  }
+  else {
+    if((instate == FTP_LIST) && (ftpcode == 450)) {
+      /* simply no matching files in the dir listing */
+      ftp->transfer = FTPTRANSFER_NONE; /* don't download anything */
+      state(conn, FTP_STOP); /* this phase is over */
+    }
+    else {
+      failf(data, "RETR response: %03d", ftpcode);
+      return instate == FTP_RETR && ftpcode == 550?
+        CURLE_REMOTE_FILE_NOT_FOUND:
+        CURLE_FTP_COULDNT_RETR_FILE;
+    }
+  }
+
+  return result;
+}
+
+/* after USER, PASS and ACCT */
+static CURLcode ftp_state_loggedin(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  if(conn->ssl[FIRSTSOCKET].use) {
+    /* PBSZ = PROTECTION BUFFER SIZE.
+
+    The 'draft-murray-auth-ftp-ssl' (draft 12, page 7) says:
+
+    Specifically, the PROT command MUST be preceded by a PBSZ
+    command and a PBSZ command MUST be preceded by a successful
+    security data exchange (the TLS negotiation in this case)
+
+    ... (and on page 8):
+
+    Thus the PBSZ command must still be issued, but must have a
+    parameter of '0' to indicate that no buffering is taking place
+    and the data connection should not be encapsulated.
+    */
+    PPSENDF(&conn->proto.ftpc.pp, "PBSZ %d", 0);
+    state(conn, FTP_PBSZ);
+  }
+  else {
+    result = ftp_state_pwd(conn);
+  }
+  return result;
+}
+
+/* for USER and PASS responses */
+static CURLcode ftp_state_user_resp(struct connectdata *conn,
+                                    int ftpcode,
+                                    ftpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct FTP *ftp = data->req.protop;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  (void)instate; /* no use for this yet */
+
+  /* some need password anyway, and others just return 2xx ignored */
+  if((ftpcode == 331) && (ftpc->state == FTP_USER)) {
+    /* 331 Password required for ...
+       (the server requires to send the user's password too) */
+    PPSENDF(&ftpc->pp, "PASS %s", ftp->passwd?ftp->passwd:"");
+    state(conn, FTP_PASS);
+  }
+  else if(ftpcode/100 == 2) {
+    /* 230 User ... logged in.
+       (the user logged in with or without password) */
+    result = ftp_state_loggedin(conn);
+  }
+  else if(ftpcode == 332) {
+    if(data->set.str[STRING_FTP_ACCOUNT]) {
+      PPSENDF(&ftpc->pp, "ACCT %s", data->set.str[STRING_FTP_ACCOUNT]);
+      state(conn, FTP_ACCT);
+    }
+    else {
+      failf(data, "ACCT requested but none available");
+      result = CURLE_LOGIN_DENIED;
+    }
+  }
+  else {
+    /* All other response codes, like:
+
+    530 User ... access denied
+    (the server denies to log the specified user) */
+
+    if(conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER] &&
+        !conn->data->state.ftp_trying_alternative) {
+      /* Ok, USER failed.  Let's try the supplied command. */
+      PPSENDF(&conn->proto.ftpc.pp, "%s",
+              conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]);
+      conn->data->state.ftp_trying_alternative = TRUE;
+      state(conn, FTP_USER);
+      result = CURLE_OK;
+    }
+    else {
+      failf(data, "Access denied: %03d", ftpcode);
+      result = CURLE_LOGIN_DENIED;
+    }
+  }
+  return result;
+}
+
+/* for ACCT response */
+static CURLcode ftp_state_acct_resp(struct connectdata *conn,
+                                    int ftpcode)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  if(ftpcode != 230) {
+    failf(data, "ACCT rejected by server: %03d", ftpcode);
+    result = CURLE_FTP_WEIRD_PASS_REPLY; /* FIX */
+  }
+  else
+    result = ftp_state_loggedin(conn);
+
+  return result;
+}
+
+
+static CURLcode ftp_statemach_act(struct connectdata *conn)
+{
+  CURLcode result;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  struct Curl_easy *data = conn->data;
+  int ftpcode;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  struct pingpong *pp = &ftpc->pp;
+  static const char ftpauth[][4]  = { "SSL", "TLS" };
+  size_t nread = 0;
+
+  if(pp->sendleft)
+    return Curl_pp_flushsend(pp);
+
+  result = ftp_readresp(sock, pp, &ftpcode, &nread);
+  if(result)
+    return result;
+
+  if(ftpcode) {
+    /* we have now received a full FTP server response */
+    switch(ftpc->state) {
+    case FTP_WAIT220:
+      if(ftpcode == 230)
+        /* 230 User logged in - already! */
+        return ftp_state_user_resp(conn, ftpcode, ftpc->state);
+      else if(ftpcode != 220) {
+        failf(data, "Got a %03d ftp-server response when 220 was expected",
+              ftpcode);
+        return CURLE_WEIRD_SERVER_REPLY;
+      }
+
+      /* We have received a 220 response fine, now we proceed. */
+#ifdef HAVE_GSSAPI
+      if(data->set.krb) {
+        /* If not anonymous login, try a secure login. Note that this
+           procedure is still BLOCKING. */
+
+        Curl_sec_request_prot(conn, "private");
+        /* We set private first as default, in case the line below fails to
+           set a valid level */
+        Curl_sec_request_prot(conn, data->set.str[STRING_KRB_LEVEL]);
+
+        if(Curl_sec_login(conn))
+          infof(data, "Logging in with password in cleartext!\n");
+        else
+          infof(data, "Authentication successful\n");
+      }
+#endif
+
+      if(data->set.use_ssl &&
+         (!conn->ssl[FIRSTSOCKET].use ||
+          (conn->bits.proxy_ssl_connected[FIRSTSOCKET] &&
+           !conn->proxy_ssl[FIRSTSOCKET].use))) {
+        /* We don't have a SSL/TLS connection yet, but FTPS is
+           requested. Try a FTPS connection now */
+
+        ftpc->count3 = 0;
+        switch(data->set.ftpsslauth) {
+        case CURLFTPAUTH_DEFAULT:
+        case CURLFTPAUTH_SSL:
+          ftpc->count2 = 1; /* add one to get next */
+          ftpc->count1 = 0;
+          break;
+        case CURLFTPAUTH_TLS:
+          ftpc->count2 = -1; /* subtract one to get next */
+          ftpc->count1 = 1;
+          break;
+        default:
+          failf(data, "unsupported parameter to CURLOPT_FTPSSLAUTH: %d",
+                (int)data->set.ftpsslauth);
+          return CURLE_UNKNOWN_OPTION; /* we don't know what to do */
+        }
+        PPSENDF(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]);
+        state(conn, FTP_AUTH);
+      }
+      else {
+        result = ftp_state_user(conn);
+        if(result)
+          return result;
+      }
+
+      break;
+
+    case FTP_AUTH:
+      /* we have gotten the response to a previous AUTH command */
+
+      /* RFC2228 (page 5) says:
+       *
+       * If the server is willing to accept the named security mechanism,
+       * and does not require any security data, it must respond with
+       * reply code 234/334.
+       */
+
+      if((ftpcode == 234) || (ftpcode == 334)) {
+        /* Curl_ssl_connect is BLOCKING */
+        result = Curl_ssl_connect(conn, FIRSTSOCKET);
+        if(!result) {
+          conn->bits.ftp_use_data_ssl = FALSE; /* clear-text data */
+          result = ftp_state_user(conn);
+        }
+      }
+      else if(ftpc->count3 < 1) {
+        ftpc->count3++;
+        ftpc->count1 += ftpc->count2; /* get next attempt */
+        result = Curl_pp_sendf(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]);
+        /* remain in this same state */
+      }
+      else {
+        if(data->set.use_ssl > CURLUSESSL_TRY)
+          /* we failed and CURLUSESSL_CONTROL or CURLUSESSL_ALL is set */
+          result = CURLE_USE_SSL_FAILED;
+        else
+          /* ignore the failure and continue */
+          result = ftp_state_user(conn);
+      }
+
+      if(result)
+        return result;
+      break;
+
+    case FTP_USER:
+    case FTP_PASS:
+      result = ftp_state_user_resp(conn, ftpcode, ftpc->state);
+      break;
+
+    case FTP_ACCT:
+      result = ftp_state_acct_resp(conn, ftpcode);
+      break;
+
+    case FTP_PBSZ:
+      PPSENDF(&ftpc->pp, "PROT %c",
+              data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P');
+      state(conn, FTP_PROT);
+
+      break;
+
+    case FTP_PROT:
+      if(ftpcode/100 == 2)
+        /* We have enabled SSL for the data connection! */
+        conn->bits.ftp_use_data_ssl =
+          (data->set.use_ssl != CURLUSESSL_CONTROL) ? TRUE : FALSE;
+      /* FTP servers typically responds with 500 if they decide to reject
+         our 'P' request */
+      else if(data->set.use_ssl > CURLUSESSL_CONTROL)
+        /* we failed and bails out */
+        return CURLE_USE_SSL_FAILED;
+
+      if(data->set.ftp_ccc) {
+        /* CCC - Clear Command Channel
+         */
+        PPSENDF(&ftpc->pp, "%s", "CCC");
+        state(conn, FTP_CCC);
+      }
+      else {
+        result = ftp_state_pwd(conn);
+        if(result)
+          return result;
+      }
+      break;
+
+    case FTP_CCC:
+      if(ftpcode < 500) {
+        /* First shut down the SSL layer (note: this call will block) */
+        result = Curl_ssl_shutdown(conn, FIRSTSOCKET);
+
+        if(result) {
+          failf(conn->data, "Failed to clear the command channel (CCC)");
+          return result;
+        }
+      }
+
+      /* Then continue as normal */
+      result = ftp_state_pwd(conn);
+      if(result)
+        return result;
+      break;
+
+    case FTP_PWD:
+      if(ftpcode == 257) {
+        char *ptr = &data->state.buffer[4];  /* start on the first letter */
+        const size_t buf_size = data->set.buffer_size;
+        char *dir;
+        char *store;
+        bool entry_extracted = FALSE;
+
+        dir = malloc(nread + 1);
+        if(!dir)
+          return CURLE_OUT_OF_MEMORY;
+
+        /* Reply format is like
+           257<space>[rubbish]"<directory-name>"<space><commentary> and the
+           RFC959 says
+
+           The directory name can contain any character; embedded
+           double-quotes should be escaped by double-quotes (the
+           "quote-doubling" convention).
+        */
+
+        /* scan for the first double-quote for non-standard responses */
+        while(ptr < &data->state.buffer[buf_size]
+              && *ptr != '\n' && *ptr != '\0' && *ptr != '"')
+          ptr++;
+
+        if('\"' == *ptr) {
+          /* it started good */
+          ptr++;
+          for(store = dir; *ptr;) {
+            if('\"' == *ptr) {
+              if('\"' == ptr[1]) {
+                /* "quote-doubling" */
+                *store = ptr[1];
+                ptr++;
+              }
+              else {
+                /* end of path */
+                entry_extracted = TRUE;
+                break; /* get out of this loop */
+              }
+            }
+            else
+              *store = *ptr;
+            store++;
+            ptr++;
+          }
+          *store = '\0'; /* zero terminate */
+        }
+        if(entry_extracted) {
+          /* If the path name does not look like an absolute path (i.e.: it
+             does not start with a '/'), we probably need some server-dependent
+             adjustments. For example, this is the case when connecting to
+             an OS400 FTP server: this server supports two name syntaxes,
+             the default one being incompatible with standard paths. In
+             addition, this server switches automatically to the regular path
+             syntax when one is encountered in a command: this results in
+             having an entrypath in the wrong syntax when later used in CWD.
+               The method used here is to check the server OS: we do it only
+             if the path name looks strange to minimize overhead on other
+             systems. */
+
+          if(!ftpc->server_os && dir[0] != '/') {
+
+            result = Curl_pp_sendf(&ftpc->pp, "%s", "SYST");
+            if(result) {
+              free(dir);
+              return result;
+            }
+            Curl_safefree(ftpc->entrypath);
+            ftpc->entrypath = dir; /* remember this */
+            infof(data, "Entry path is '%s'\n", ftpc->entrypath);
+            /* also save it where getinfo can access it: */
+            data->state.most_recent_ftp_entrypath = ftpc->entrypath;
+            state(conn, FTP_SYST);
+            break;
+          }
+
+          Curl_safefree(ftpc->entrypath);
+          ftpc->entrypath = dir; /* remember this */
+          infof(data, "Entry path is '%s'\n", ftpc->entrypath);
+          /* also save it where getinfo can access it: */
+          data->state.most_recent_ftp_entrypath = ftpc->entrypath;
+        }
+        else {
+          /* couldn't get the path */
+          free(dir);
+          infof(data, "Failed to figure out path\n");
+        }
+      }
+      state(conn, FTP_STOP); /* we are done with the CONNECT phase! */
+      DEBUGF(infof(data, "protocol connect phase DONE\n"));
+      break;
+
+    case FTP_SYST:
+      if(ftpcode == 215) {
+        char *ptr = &data->state.buffer[4];  /* start on the first letter */
+        char *os;
+        char *store;
+
+        os = malloc(nread + 1);
+        if(!os)
+          return CURLE_OUT_OF_MEMORY;
+
+        /* Reply format is like
+           215<space><OS-name><space><commentary>
+        */
+        while(*ptr == ' ')
+          ptr++;
+        for(store = os; *ptr && *ptr != ' ';)
+          *store++ = *ptr++;
+        *store = '\0'; /* zero terminate */
+
+        /* Check for special servers here. */
+
+        if(strcasecompare(os, "OS/400")) {
+          /* Force OS400 name format 1. */
+          result = Curl_pp_sendf(&ftpc->pp, "%s", "SITE NAMEFMT 1");
+          if(result) {
+            free(os);
+            return result;
+          }
+          /* remember target server OS */
+          Curl_safefree(ftpc->server_os);
+          ftpc->server_os = os;
+          state(conn, FTP_NAMEFMT);
+          break;
+        }
+        /* Nothing special for the target server. */
+        /* remember target server OS */
+        Curl_safefree(ftpc->server_os);
+        ftpc->server_os = os;
+      }
+      else {
+        /* Cannot identify server OS. Continue anyway and cross fingers. */
+      }
+
+      state(conn, FTP_STOP); /* we are done with the CONNECT phase! */
+      DEBUGF(infof(data, "protocol connect phase DONE\n"));
+      break;
+
+    case FTP_NAMEFMT:
+      if(ftpcode == 250) {
+        /* Name format change successful: reload initial path. */
+        ftp_state_pwd(conn);
+        break;
+      }
+
+      state(conn, FTP_STOP); /* we are done with the CONNECT phase! */
+      DEBUGF(infof(data, "protocol connect phase DONE\n"));
+      break;
+
+    case FTP_QUOTE:
+    case FTP_POSTQUOTE:
+    case FTP_RETR_PREQUOTE:
+    case FTP_STOR_PREQUOTE:
+      if((ftpcode >= 400) && !ftpc->count2) {
+        /* failure response code, and not allowed to fail */
+        failf(conn->data, "QUOT command failed with %03d", ftpcode);
+        return CURLE_QUOTE_ERROR;
+      }
+      result = ftp_state_quote(conn, FALSE, ftpc->state);
+      if(result)
+        return result;
+
+      break;
+
+    case FTP_CWD:
+      if(ftpcode/100 != 2) {
+        /* failure to CWD there */
+        if(conn->data->set.ftp_create_missing_dirs &&
+           ftpc->cwdcount && !ftpc->count2) {
+          /* try making it */
+          ftpc->count2++; /* counter to prevent CWD-MKD loops */
+          PPSENDF(&ftpc->pp, "MKD %s", ftpc->dirs[ftpc->cwdcount - 1]);
+          state(conn, FTP_MKD);
+        }
+        else {
+          /* return failure */
+          failf(data, "Server denied you to change to the given directory");
+          ftpc->cwdfail = TRUE; /* don't remember this path as we failed
+                                   to enter it */
+          return CURLE_REMOTE_ACCESS_DENIED;
+        }
+      }
+      else {
+        /* success */
+        ftpc->count2 = 0;
+        if(++ftpc->cwdcount <= ftpc->dirdepth) {
+          /* send next CWD */
+          PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->cwdcount - 1]);
+        }
+        else {
+          result = ftp_state_mdtm(conn);
+          if(result)
+            return result;
+        }
+      }
+      break;
+
+    case FTP_MKD:
+      if((ftpcode/100 != 2) && !ftpc->count3--) {
+        /* failure to MKD the dir */
+        failf(data, "Failed to MKD dir: %03d", ftpcode);
+        return CURLE_REMOTE_ACCESS_DENIED;
+      }
+      state(conn, FTP_CWD);
+      /* send CWD */
+      PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->cwdcount - 1]);
+      break;
+
+    case FTP_MDTM:
+      result = ftp_state_mdtm_resp(conn, ftpcode);
+      break;
+
+    case FTP_TYPE:
+    case FTP_LIST_TYPE:
+    case FTP_RETR_TYPE:
+    case FTP_STOR_TYPE:
+      result = ftp_state_type_resp(conn, ftpcode, ftpc->state);
+      break;
+
+    case FTP_SIZE:
+    case FTP_RETR_SIZE:
+    case FTP_STOR_SIZE:
+      result = ftp_state_size_resp(conn, ftpcode, ftpc->state);
+      break;
+
+    case FTP_REST:
+    case FTP_RETR_REST:
+      result = ftp_state_rest_resp(conn, ftpcode, ftpc->state);
+      break;
+
+    case FTP_PRET:
+      if(ftpcode != 200) {
+        /* there only is this one standard OK return code. */
+        failf(data, "PRET command not accepted: %03d", ftpcode);
+        return CURLE_FTP_PRET_FAILED;
+      }
+      result = ftp_state_use_pasv(conn);
+      break;
+
+    case FTP_PASV:
+      result = ftp_state_pasv_resp(conn, ftpcode);
+      break;
+
+    case FTP_PORT:
+      result = ftp_state_port_resp(conn, ftpcode);
+      break;
+
+    case FTP_LIST:
+    case FTP_RETR:
+      result = ftp_state_get_resp(conn, ftpcode, ftpc->state);
+      break;
+
+    case FTP_STOR:
+      result = ftp_state_stor_resp(conn, ftpcode, ftpc->state);
+      break;
+
+    case FTP_QUIT:
+      /* fallthrough, just stop! */
+    default:
+      /* internal error */
+      state(conn, FTP_STOP);
+      break;
+    }
+  } /* if(ftpcode) */
+
+  return result;
+}
+
+
+/* called repeatedly until done from multi.c */
+static CURLcode ftp_multi_statemach(struct connectdata *conn,
+                                    bool *done)
+{
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  CURLcode result = Curl_pp_statemach(&ftpc->pp, FALSE);
+
+  /* Check for the state outside of the Curl_socket_check() return code checks
+     since at times we are in fact already in this state when this function
+     gets called. */
+  *done = (ftpc->state == FTP_STOP) ? TRUE : FALSE;
+
+  return result;
+}
+
+static CURLcode ftp_block_statemach(struct connectdata *conn)
+{
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  struct pingpong *pp = &ftpc->pp;
+  CURLcode result = CURLE_OK;
+
+  while(ftpc->state != FTP_STOP) {
+    result = Curl_pp_statemach(pp, TRUE);
+    if(result)
+      break;
+  }
+
+  return result;
+}
+
+/*
+ * ftp_connect() should do everything that is to be considered a part of
+ * the connection phase.
+ *
+ * The variable 'done' points to will be TRUE if the protocol-layer connect
+ * phase is done when this function returns, or FALSE if not.
+ *
+ */
+static CURLcode ftp_connect(struct connectdata *conn,
+                                 bool *done) /* see description above */
+{
+  CURLcode result;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  struct pingpong *pp = &ftpc->pp;
+
+  *done = FALSE; /* default to not done yet */
+
+  /* We always support persistent connections on ftp */
+  connkeep(conn, "FTP default");
+
+  pp->response_time = RESP_TIMEOUT; /* set default response time-out */
+  pp->statemach_act = ftp_statemach_act;
+  pp->endofresp = ftp_endofresp;
+  pp->conn = conn;
+
+  if(conn->handler->flags & PROTOPT_SSL) {
+    /* BLOCKING */
+    result = Curl_ssl_connect(conn, FIRSTSOCKET);
+    if(result)
+      return result;
+  }
+
+  Curl_pp_init(pp); /* init the generic pingpong data */
+
+  /* When we connect, we start in the state where we await the 220
+     response */
+  state(conn, FTP_WAIT220);
+
+  result = ftp_multi_statemach(conn, done);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * ftp_done()
+ *
+ * The DONE function. This does what needs to be done after a single DO has
+ * performed.
+ *
+ * Input argument is already checked for validity.
+ */
+static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
+                         bool premature)
+{
+  struct Curl_easy *data = conn->data;
+  struct FTP *ftp = data->req.protop;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  struct pingpong *pp = &ftpc->pp;
+  ssize_t nread;
+  int ftpcode;
+  CURLcode result = CURLE_OK;
+  char *path = NULL;
+  const char *path_to_use = data->state.path;
+
+  if(!ftp)
+    return CURLE_OK;
+
+  switch(status) {
+  case CURLE_BAD_DOWNLOAD_RESUME:
+  case CURLE_FTP_WEIRD_PASV_REPLY:
+  case CURLE_FTP_PORT_FAILED:
+  case CURLE_FTP_ACCEPT_FAILED:
+  case CURLE_FTP_ACCEPT_TIMEOUT:
+  case CURLE_FTP_COULDNT_SET_TYPE:
+  case CURLE_FTP_COULDNT_RETR_FILE:
+  case CURLE_PARTIAL_FILE:
+  case CURLE_UPLOAD_FAILED:
+  case CURLE_REMOTE_ACCESS_DENIED:
+  case CURLE_FILESIZE_EXCEEDED:
+  case CURLE_REMOTE_FILE_NOT_FOUND:
+  case CURLE_WRITE_ERROR:
+    /* the connection stays alive fine even though this happened */
+    /* fall-through */
+  case CURLE_OK: /* doesn't affect the control connection's status */
+    if(!premature)
+      break;
+
+    /* until we cope better with prematurely ended requests, let them
+     * fallback as if in complete failure */
+    /* FALLTHROUGH */
+  default:       /* by default, an error means the control connection is
+                    wedged and should not be used anymore */
+    ftpc->ctl_valid = FALSE;
+    ftpc->cwdfail = TRUE; /* set this TRUE to prevent us to remember the
+                             current path, as this connection is going */
+    connclose(conn, "FTP ended with bad error code");
+    result = status;      /* use the already set error code */
+    break;
+  }
+
+  /* now store a copy of the directory we are in */
+  free(ftpc->prevpath);
+
+  if(data->state.wildcardmatch) {
+    if(data->set.chunk_end && ftpc->file) {
+      data->set.chunk_end(data->wildcard.customptr);
+    }
+    ftpc->known_filesize = -1;
+  }
+
+  if(!result)
+    /* get the "raw" path */
+    result = Curl_urldecode(data, path_to_use, 0, &path, NULL, FALSE);
+  if(result) {
+    /* We can limp along anyway (and should try to since we may already be in
+     * the error path) */
+    ftpc->ctl_valid = FALSE; /* mark control connection as bad */
+    connclose(conn, "FTP: out of memory!"); /* mark for connection closure */
+    ftpc->prevpath = NULL; /* no path remembering */
+  }
+  else {
+    size_t flen = ftpc->file?strlen(ftpc->file):0; /* file is "raw" already */
+    size_t dlen = strlen(path)-flen;
+    if(!ftpc->cwdfail) {
+      ftpc->prevmethod = data->set.ftp_filemethod;
+      if(dlen && (data->set.ftp_filemethod != FTPFILE_NOCWD)) {
+        ftpc->prevpath = path;
+        if(flen)
+          /* if 'path' is not the whole string */
+          ftpc->prevpath[dlen] = 0; /* terminate */
+      }
+      else {
+        /* we never changed dir */
+        ftpc->prevpath = strdup("");
+        free(path);
+      }
+      if(ftpc->prevpath)
+        infof(data, "Remembering we are in dir \"%s\"\n", ftpc->prevpath);
+    }
+    else {
+      ftpc->prevpath = NULL; /* no path */
+      free(path);
+    }
+  }
+  /* free the dir tree and file parts */
+  freedirs(ftpc);
+
+  /* shut down the socket to inform the server we're done */
+
+#ifdef _WIN32_WCE
+  shutdown(conn->sock[SECONDARYSOCKET], 2);  /* SD_BOTH */
+#endif
+
+  if(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD) {
+    if(!result && ftpc->dont_check && data->req.maxdownload > 0) {
+      /* partial download completed */
+      result = Curl_pp_sendf(pp, "%s", "ABOR");
+      if(result) {
+        failf(data, "Failure sending ABOR command: %s",
+              curl_easy_strerror(result));
+        ftpc->ctl_valid = FALSE; /* mark control connection as bad */
+        connclose(conn, "ABOR command failed"); /* connection closure */
+      }
+    }
+
+    if(conn->ssl[SECONDARYSOCKET].use) {
+      /* The secondary socket is using SSL so we must close down that part
+         first before we close the socket for real */
+      Curl_ssl_close(conn, SECONDARYSOCKET);
+
+      /* Note that we keep "use" set to TRUE since that (next) connection is
+         still requested to use SSL */
+    }
+    close_secondarysocket(conn);
+  }
+
+  if(!result && (ftp->transfer == FTPTRANSFER_BODY) && ftpc->ctl_valid &&
+     pp->pending_resp && !premature) {
+    /*
+     * Let's see what the server says about the transfer we just performed,
+     * but lower the timeout as sometimes this connection has died while the
+     * data has been transferred. This happens when doing through NATs etc that
+     * abandon old silent connections.
+     */
+    long old_time = pp->response_time;
+
+    pp->response_time = 60*1000; /* give it only a minute for now */
+    pp->response = Curl_now(); /* timeout relative now */
+
+    result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+
+    pp->response_time = old_time; /* set this back to previous value */
+
+    if(!nread && (CURLE_OPERATION_TIMEDOUT == result)) {
+      failf(data, "control connection looks dead");
+      ftpc->ctl_valid = FALSE; /* mark control connection as bad */
+      connclose(conn, "Timeout or similar in FTP DONE operation"); /* close */
+    }
+
+    if(result)
+      return result;
+
+    if(ftpc->dont_check && data->req.maxdownload > 0) {
+      /* we have just sent ABOR and there is no reliable way to check if it was
+       * successful or not; we have to close the connection now */
+      infof(data, "partial download completed, closing connection\n");
+      connclose(conn, "Partial download with no ability to check");
+      return result;
+    }
+
+    if(!ftpc->dont_check) {
+      /* 226 Transfer complete, 250 Requested file action okay, completed. */
+      if((ftpcode != 226) && (ftpcode != 250)) {
+        failf(data, "server did not report OK, got %d", ftpcode);
+        result = CURLE_PARTIAL_FILE;
+      }
+    }
+  }
+
+  if(result || premature)
+    /* the response code from the transfer showed an error already so no
+       use checking further */
+    ;
+  else if(data->set.upload) {
+    if((-1 != data->state.infilesize) &&
+       (data->state.infilesize != *ftp->bytecountp) &&
+       !data->set.crlf &&
+       (ftp->transfer == FTPTRANSFER_BODY)) {
+      failf(data, "Uploaded unaligned file size (%" CURL_FORMAT_CURL_OFF_T
+            " out of %" CURL_FORMAT_CURL_OFF_T " bytes)",
+            *ftp->bytecountp, data->state.infilesize);
+      result = CURLE_PARTIAL_FILE;
+    }
+  }
+  else {
+    if((-1 != data->req.size) &&
+       (data->req.size != *ftp->bytecountp) &&
+#ifdef CURL_DO_LINEEND_CONV
+       /* Most FTP servers don't adjust their file SIZE response for CRLFs, so
+        * we'll check to see if the discrepancy can be explained by the number
+        * of CRLFs we've changed to LFs.
+        */
+       ((data->req.size + data->state.crlf_conversions) !=
+        *ftp->bytecountp) &&
+#endif /* CURL_DO_LINEEND_CONV */
+       (data->req.maxdownload != *ftp->bytecountp)) {
+      failf(data, "Received only partial file: %" CURL_FORMAT_CURL_OFF_T
+            " bytes", *ftp->bytecountp);
+      result = CURLE_PARTIAL_FILE;
+    }
+    else if(!ftpc->dont_check &&
+            !*ftp->bytecountp &&
+            (data->req.size>0)) {
+      failf(data, "No data was received!");
+      result = CURLE_FTP_COULDNT_RETR_FILE;
+    }
+  }
+
+  /* clear these for next connection */
+  ftp->transfer = FTPTRANSFER_BODY;
+  ftpc->dont_check = FALSE;
+
+  /* Send any post-transfer QUOTE strings? */
+  if(!status && !result && !premature && data->set.postquote)
+    result = ftp_sendquote(conn, data->set.postquote);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * ftp_sendquote()
+ *
+ * Where a 'quote' means a list of custom commands to send to the server.
+ * The quote list is passed as an argument.
+ *
+ * BLOCKING
+ */
+
+static
+CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote)
+{
+  struct curl_slist *item;
+  ssize_t nread;
+  int ftpcode;
+  CURLcode result;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  struct pingpong *pp = &ftpc->pp;
+
+  item = quote;
+  while(item) {
+    if(item->data) {
+      char *cmd = item->data;
+      bool acceptfail = FALSE;
+
+      /* if a command starts with an asterisk, which a legal FTP command never
+         can, the command will be allowed to fail without it causing any
+         aborts or cancels etc. It will cause libcurl to act as if the command
+         is successful, whatever the server reponds. */
+
+      if(cmd[0] == '*') {
+        cmd++;
+        acceptfail = TRUE;
+      }
+
+      PPSENDF(&conn->proto.ftpc.pp, "%s", cmd);
+
+      pp->response = Curl_now(); /* timeout relative now */
+
+      result = Curl_GetFTPResponse(&nread, conn, &ftpcode);
+      if(result)
+        return result;
+
+      if(!acceptfail && (ftpcode >= 400)) {
+        failf(conn->data, "QUOT string not accepted: %s", cmd);
+        return CURLE_QUOTE_ERROR;
+      }
+    }
+
+    item = item->next;
+  }
+
+  return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * ftp_need_type()
+ *
+ * Returns TRUE if we in the current situation should send TYPE
+ */
+static int ftp_need_type(struct connectdata *conn,
+                         bool ascii_wanted)
+{
+  return conn->proto.ftpc.transfertype != (ascii_wanted?'A':'I');
+}
+
+/***********************************************************************
+ *
+ * ftp_nb_type()
+ *
+ * Set TYPE. We only deal with ASCII or BINARY so this function
+ * sets one of them.
+ * If the transfer type is not sent, simulate on OK response in newstate
+ */
+static CURLcode ftp_nb_type(struct connectdata *conn,
+                            bool ascii, ftpstate newstate)
+{
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  CURLcode result;
+  char want = (char)(ascii?'A':'I');
+
+  if(ftpc->transfertype == want) {
+    state(conn, newstate);
+    return ftp_state_type_resp(conn, 200, newstate);
+  }
+
+  PPSENDF(&ftpc->pp, "TYPE %c", want);
+  state(conn, newstate);
+
+  /* keep track of our current transfer type */
+  ftpc->transfertype = want;
+  return CURLE_OK;
+}
+
+/***************************************************************************
+ *
+ * ftp_pasv_verbose()
+ *
+ * This function only outputs some informationals about this second connection
+ * when we've issued a PASV command before and thus we have connected to a
+ * possibly new IP address.
+ *
+ */
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+static void
+ftp_pasv_verbose(struct connectdata *conn,
+                 Curl_addrinfo *ai,
+                 char *newhost, /* ascii version */
+                 int port)
+{
+  char buf[256];
+  Curl_printable_address(ai, buf, sizeof(buf));
+  infof(conn->data, "Connecting to %s (%s) port %d\n", newhost, buf, port);
+}
+#endif
+
+/*
+  Check if this is a range download, and if so, set the internal variables
+  properly.
+ */
+
+static CURLcode ftp_range(struct connectdata *conn)
+{
+  curl_off_t from, to;
+  char *ptr;
+  struct Curl_easy *data = conn->data;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  if(data->state.use_range && data->state.range) {
+    CURLofft from_t;
+    CURLofft to_t;
+    from_t = curlx_strtoofft(data->state.range, &ptr, 0, &from);
+    if(from_t == CURL_OFFT_FLOW)
+      return CURLE_RANGE_ERROR;
+    while(*ptr && (ISSPACE(*ptr) || (*ptr == '-')))
+      ptr++;
+    to_t = curlx_strtoofft(ptr, NULL, 0, &to);
+    if(to_t == CURL_OFFT_FLOW)
+      return CURLE_RANGE_ERROR;
+    if((to_t == CURL_OFFT_INVAL) && !from_t) {
+      /* X - */
+      data->state.resume_from = from;
+      DEBUGF(infof(conn->data, "FTP RANGE %" CURL_FORMAT_CURL_OFF_T
+                   " to end of file\n", from));
+    }
+    else if(!to_t && (from_t == CURL_OFFT_INVAL)) {
+      /* -Y */
+      data->req.maxdownload = to;
+      data->state.resume_from = -to;
+      DEBUGF(infof(conn->data, "FTP RANGE the last %" CURL_FORMAT_CURL_OFF_T
+                   " bytes\n", to));
+    }
+    else {
+      /* X-Y */
+      data->req.maxdownload = (to - from) + 1; /* include last byte */
+      data->state.resume_from = from;
+      DEBUGF(infof(conn->data, "FTP RANGE from %" CURL_FORMAT_CURL_OFF_T
+                   " getting %" CURL_FORMAT_CURL_OFF_T " bytes\n",
+                   from, data->req.maxdownload));
+    }
+    DEBUGF(infof(conn->data, "range-download from %" CURL_FORMAT_CURL_OFF_T
+                 " to %" CURL_FORMAT_CURL_OFF_T ", totally %"
+                 CURL_FORMAT_CURL_OFF_T " bytes\n",
+                 from, to, data->req.maxdownload));
+    ftpc->dont_check = TRUE; /* don't check for successful transfer */
+  }
+  else
+    data->req.maxdownload = -1;
+  return CURLE_OK;
+}
+
+
+/*
+ * ftp_do_more()
+ *
+ * This function shall be called when the second FTP (data) connection is
+ * connected.
+ *
+ * 'complete' can return 0 for incomplete, 1 for done and -1 for go back
+ * (which basically is only for when PASV is being sent to retry a failed
+ * EPSV).
+ */
+
+static CURLcode ftp_do_more(struct connectdata *conn, int *completep)
+{
+  struct Curl_easy *data = conn->data;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  CURLcode result = CURLE_OK;
+  bool connected = FALSE;
+  bool complete = FALSE;
+
+  /* the ftp struct is inited in ftp_connect() */
+  struct FTP *ftp = data->req.protop;
+
+  /* if the second connection isn't done yet, wait for it */
+  if(!conn->bits.tcpconnect[SECONDARYSOCKET]) {
+    if(Curl_connect_ongoing(conn)) {
+      /* As we're in TUNNEL_CONNECT state now, we know the proxy name and port
+         aren't used so we blank their arguments. TODO: make this nicer */
+      result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, NULL, 0);
+
+      return result;
+    }
+
+    result = Curl_is_connected(conn, SECONDARYSOCKET, &connected);
+
+    /* Ready to do more? */
+    if(connected) {
+      DEBUGF(infof(data, "DO-MORE connected phase starts\n"));
+    }
+    else {
+      if(result && (ftpc->count1 == 0)) {
+        *completep = -1; /* go back to DOING please */
+        /* this is a EPSV connect failing, try PASV instead */
+        return ftp_epsv_disable(conn);
+      }
+      return result;
+    }
+  }
+
+  result = Curl_proxy_connect(conn, SECONDARYSOCKET);
+  if(result)
+    return result;
+
+  if(CONNECT_SECONDARYSOCKET_PROXY_SSL())
+    return result;
+
+  if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
+     Curl_connect_ongoing(conn))
+    return result;
+
+
+  if(ftpc->state) {
+    /* already in a state so skip the initial commands.
+       They are only done to kickstart the do_more state */
+    result = ftp_multi_statemach(conn, &complete);
+
+    *completep = (int)complete;
+
+    /* if we got an error or if we don't wait for a data connection return
+       immediately */
+    if(result || (ftpc->wait_data_conn != TRUE))
+      return result;
+
+    if(ftpc->wait_data_conn)
+      /* if we reach the end of the FTP state machine here, *complete will be
+         TRUE but so is ftpc->wait_data_conn, which says we need to wait for
+         the data connection and therefore we're not actually complete */
+      *completep = 0;
+  }
+
+  if(ftp->transfer <= FTPTRANSFER_INFO) {
+    /* a transfer is about to take place, or if not a file name was given
+       so we'll do a SIZE on it later and then we need the right TYPE first */
+
+    if(ftpc->wait_data_conn == TRUE) {
+      bool serv_conned;
+
+      result = ReceivedServerConnect(conn, &serv_conned);
+      if(result)
+        return result; /* Failed to accept data connection */
+
+      if(serv_conned) {
+        /* It looks data connection is established */
+        result = AcceptServerConnect(conn);
+        ftpc->wait_data_conn = FALSE;
+        if(!result)
+          result = InitiateTransfer(conn);
+
+        if(result)
+          return result;
+
+        *completep = 1; /* this state is now complete when the server has
+                           connected back to us */
+      }
+    }
+    else if(data->set.upload) {
+      result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_STOR_TYPE);
+      if(result)
+        return result;
+
+      result = ftp_multi_statemach(conn, &complete);
+      if(ftpc->wait_data_conn)
+        /* if we reach the end of the FTP state machine here, *complete will be
+           TRUE but so is ftpc->wait_data_conn, which says we need to wait for
+           the data connection and therefore we're not actually complete */
+        *completep = 0;
+      else
+        *completep = (int)complete;
+    }
+    else {
+      /* download */
+      ftp->downloadsize = -1; /* unknown as of yet */
+
+      result = ftp_range(conn);
+      if(result)
+        ;
+      else if(data->set.ftp_list_only || !ftpc->file) {
+        /* The specified path ends with a slash, and therefore we think this
+           is a directory that is requested, use LIST. But before that we
+           need to set ASCII transfer mode. */
+
+        /* But only if a body transfer was requested. */
+        if(ftp->transfer == FTPTRANSFER_BODY) {
+          result = ftp_nb_type(conn, TRUE, FTP_LIST_TYPE);
+          if(result)
+            return result;
+        }
+        /* otherwise just fall through */
+      }
+      else {
+        result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_RETR_TYPE);
+        if(result)
+          return result;
+      }
+
+      result = ftp_multi_statemach(conn, &complete);
+      *completep = (int)complete;
+    }
+    return result;
+  }
+
+  if(!result && (ftp->transfer != FTPTRANSFER_BODY))
+    /* no data to transfer. FIX: it feels like a kludge to have this here
+       too! */
+    Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+
+  if(!ftpc->wait_data_conn) {
+    /* no waiting for the data connection so this is now complete */
+    *completep = 1;
+    DEBUGF(infof(data, "DO-MORE phase ends with %d\n", (int)result));
+  }
+
+  return result;
+}
+
+
+
+/***********************************************************************
+ *
+ * ftp_perform()
+ *
+ * This is the actual DO function for FTP. Get a file/directory according to
+ * the options previously setup.
+ */
+
+static
+CURLcode ftp_perform(struct connectdata *conn,
+                     bool *connected,  /* connect status after PASV / PORT */
+                     bool *dophase_done)
+{
+  /* this is FTP and no proxy */
+  CURLcode result = CURLE_OK;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  if(conn->data->set.opt_no_body) {
+    /* requested no body means no transfer... */
+    struct FTP *ftp = conn->data->req.protop;
+    ftp->transfer = FTPTRANSFER_INFO;
+  }
+
+  *dophase_done = FALSE; /* not done yet */
+
+  /* start the first command in the DO phase */
+  result = ftp_state_quote(conn, TRUE, FTP_QUOTE);
+  if(result)
+    return result;
+
+  /* run the state-machine */
+  result = ftp_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[SECONDARYSOCKET];
+
+  infof(conn->data, "ftp_perform ends with SECONDARY: %d\n", *connected);
+
+  if(*dophase_done)
+    DEBUGF(infof(conn->data, "DO phase is complete1\n"));
+
+  return result;
+}
+
+static void wc_data_dtor(void *ptr)
+{
+  struct ftp_wc_tmpdata *tmp = ptr;
+  if(tmp)
+    Curl_ftp_parselist_data_free(&tmp->parser);
+  free(tmp);
+}
+
+static CURLcode init_wc_data(struct connectdata *conn)
+{
+  char *last_slash;
+  char *path = conn->data->state.path;
+  struct WildcardData *wildcard = &(conn->data->wildcard);
+  CURLcode result = CURLE_OK;
+  struct ftp_wc_tmpdata *ftp_tmp;
+
+  last_slash = strrchr(conn->data->state.path, '/');
+  if(last_slash) {
+    last_slash++;
+    if(last_slash[0] == '\0') {
+      wildcard->state = CURLWC_CLEAN;
+      result = ftp_parse_url_path(conn);
+      return result;
+    }
+    wildcard->pattern = strdup(last_slash);
+    if(!wildcard->pattern)
+      return CURLE_OUT_OF_MEMORY;
+    last_slash[0] = '\0'; /* cut file from path */
+  }
+  else { /* there is only 'wildcard pattern' or nothing */
+    if(path[0]) {
+      wildcard->pattern = strdup(path);
+      if(!wildcard->pattern)
+        return CURLE_OUT_OF_MEMORY;
+      path[0] = '\0';
+    }
+    else { /* only list */
+      wildcard->state = CURLWC_CLEAN;
+      result = ftp_parse_url_path(conn);
+      return result;
+    }
+  }
+
+  /* program continues only if URL is not ending with slash, allocate needed
+     resources for wildcard transfer */
+
+  /* allocate ftp protocol specific temporary wildcard data */
+  ftp_tmp = calloc(1, sizeof(struct ftp_wc_tmpdata));
+  if(!ftp_tmp) {
+    Curl_safefree(wildcard->pattern);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* INITIALIZE parselist structure */
+  ftp_tmp->parser = Curl_ftp_parselist_data_alloc();
+  if(!ftp_tmp->parser) {
+    Curl_safefree(wildcard->pattern);
+    free(ftp_tmp);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  wildcard->tmp = ftp_tmp; /* put it to the WildcardData tmp pointer */
+  wildcard->tmp_dtor = wc_data_dtor;
+
+  /* wildcard does not support NOCWD option (assert it?) */
+  if(conn->data->set.ftp_filemethod == FTPFILE_NOCWD)
+    conn->data->set.ftp_filemethod = FTPFILE_MULTICWD;
+
+  /* try to parse ftp url */
+  result = ftp_parse_url_path(conn);
+  if(result) {
+    Curl_safefree(wildcard->pattern);
+    wildcard->tmp_dtor(wildcard->tmp);
+    wildcard->tmp_dtor = ZERO_NULL;
+    wildcard->tmp = NULL;
+    return result;
+  }
+
+  wildcard->path = strdup(conn->data->state.path);
+  if(!wildcard->path) {
+    Curl_safefree(wildcard->pattern);
+    wildcard->tmp_dtor(wildcard->tmp);
+    wildcard->tmp_dtor = ZERO_NULL;
+    wildcard->tmp = NULL;
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* backup old write_function */
+  ftp_tmp->backup.write_function = conn->data->set.fwrite_func;
+  /* parsing write function */
+  conn->data->set.fwrite_func = Curl_ftp_parselist;
+  /* backup old file descriptor */
+  ftp_tmp->backup.file_descriptor = conn->data->set.out;
+  /* let the writefunc callback know what curl pointer is working with */
+  conn->data->set.out = conn;
+
+  infof(conn->data, "Wildcard - Parsing started\n");
+  return CURLE_OK;
+}
+
+/* This is called recursively */
+static CURLcode wc_statemach(struct connectdata *conn)
+{
+  struct WildcardData * const wildcard = &(conn->data->wildcard);
+  CURLcode result = CURLE_OK;
+
+  switch(wildcard->state) {
+  case CURLWC_INIT:
+    result = init_wc_data(conn);
+    if(wildcard->state == CURLWC_CLEAN)
+      /* only listing! */
+      break;
+    wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING;
+    break;
+
+  case CURLWC_MATCHING: {
+    /* In this state is LIST response successfully parsed, so lets restore
+       previous WRITEFUNCTION callback and WRITEDATA pointer */
+    struct ftp_wc_tmpdata *ftp_tmp = wildcard->tmp;
+    conn->data->set.fwrite_func = ftp_tmp->backup.write_function;
+    conn->data->set.out = ftp_tmp->backup.file_descriptor;
+    ftp_tmp->backup.write_function = ZERO_NULL;
+    ftp_tmp->backup.file_descriptor = NULL;
+    wildcard->state = CURLWC_DOWNLOADING;
+
+    if(Curl_ftp_parselist_geterror(ftp_tmp->parser)) {
+      /* error found in LIST parsing */
+      wildcard->state = CURLWC_CLEAN;
+      return wc_statemach(conn);
+    }
+    if(wildcard->filelist.size == 0) {
+      /* no corresponding file */
+      wildcard->state = CURLWC_CLEAN;
+      return CURLE_REMOTE_FILE_NOT_FOUND;
+    }
+    return wc_statemach(conn);
+  }
+
+  case CURLWC_DOWNLOADING: {
+    /* filelist has at least one file, lets get first one */
+    struct ftp_conn *ftpc = &conn->proto.ftpc;
+    struct curl_fileinfo *finfo = wildcard->filelist.head->ptr;
+
+    char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename);
+    if(!tmp_path)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* switch default "state.pathbuffer" and tmp_path, good to see
+       ftp_parse_url_path function to understand this trick */
+    Curl_safefree(conn->data->state.pathbuffer);
+    conn->data->state.pathbuffer = tmp_path;
+    conn->data->state.path = tmp_path;
+
+    infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename);
+    if(conn->data->set.chunk_bgn) {
+      long userresponse = conn->data->set.chunk_bgn(
+        finfo, wildcard->customptr, (int)wildcard->filelist.size);
+      switch(userresponse) {
+      case CURL_CHUNK_BGN_FUNC_SKIP:
+        infof(conn->data, "Wildcard - \"%s\" skipped by user\n",
+              finfo->filename);
+        wildcard->state = CURLWC_SKIP;
+        return wc_statemach(conn);
+      case CURL_CHUNK_BGN_FUNC_FAIL:
+        return CURLE_CHUNK_FAILED;
+      }
+    }
+
+    if(finfo->filetype != CURLFILETYPE_FILE) {
+      wildcard->state = CURLWC_SKIP;
+      return wc_statemach(conn);
+    }
+
+    if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE)
+      ftpc->known_filesize = finfo->size;
+
+    result = ftp_parse_url_path(conn);
+    if(result)
+      return result;
+
+    /* we don't need the Curl_fileinfo of first file anymore */
+    Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
+
+    if(wildcard->filelist.size == 0) { /* remains only one file to down. */
+      wildcard->state = CURLWC_CLEAN;
+      /* after that will be ftp_do called once again and no transfer
+         will be done because of CURLWC_CLEAN state */
+      return CURLE_OK;
+    }
+  } break;
+
+  case CURLWC_SKIP: {
+    if(conn->data->set.chunk_end)
+      conn->data->set.chunk_end(conn->data->wildcard.customptr);
+    Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
+    wildcard->state = (wildcard->filelist.size == 0) ?
+                      CURLWC_CLEAN : CURLWC_DOWNLOADING;
+    return wc_statemach(conn);
+  }
+
+  case CURLWC_CLEAN: {
+    struct ftp_wc_tmpdata *ftp_tmp = wildcard->tmp;
+    result = CURLE_OK;
+    if(ftp_tmp)
+      result = Curl_ftp_parselist_geterror(ftp_tmp->parser);
+
+    wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE;
+  } break;
+
+  case CURLWC_DONE:
+  case CURLWC_ERROR:
+  case CURLWC_CLEAR:
+    break;
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * ftp_do()
+ *
+ * This function is registered as 'curl_do' function. It decodes the path
+ * parts etc as a wrapper to the actual DO function (ftp_perform).
+ *
+ * The input argument is already checked for validity.
+ */
+static CURLcode ftp_do(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  *done = FALSE; /* default to false */
+  ftpc->wait_data_conn = FALSE; /* default to no such wait */
+
+  if(conn->data->state.wildcardmatch) {
+    result = wc_statemach(conn);
+    if(conn->data->wildcard.state == CURLWC_SKIP ||
+      conn->data->wildcard.state == CURLWC_DONE) {
+      /* do not call ftp_regular_transfer */
+      return CURLE_OK;
+    }
+    if(result) /* error, loop or skipping the file */
+      return result;
+  }
+  else { /* no wildcard FSM needed */
+    result = ftp_parse_url_path(conn);
+    if(result)
+      return result;
+  }
+
+  result = ftp_regular_transfer(conn, done);
+
+  return result;
+}
+
+
+CURLcode Curl_ftpsend(struct connectdata *conn, const char *cmd)
+{
+  ssize_t bytes_written;
+#define SBUF_SIZE 1024
+  char s[SBUF_SIZE];
+  size_t write_len;
+  char *sptr = s;
+  CURLcode result = CURLE_OK;
+#ifdef HAVE_GSSAPI
+  enum protection_level data_sec = conn->data_prot;
+#endif
+
+  write_len = strlen(cmd);
+  if(write_len > (sizeof(s) -3))
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  strcpy(&s[write_len], "\r\n"); /* append a trailing CRLF */
+  write_len += 2;
+  bytes_written = 0;
+
+  result = Curl_convert_to_network(conn->data, s, write_len);
+  /* Curl_convert_to_network calls failf if unsuccessful */
+  if(result)
+    return result;
+
+  for(;;) {
+#ifdef HAVE_GSSAPI
+    conn->data_prot = PROT_CMD;
+#endif
+    result = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len,
+                        &bytes_written);
+#ifdef HAVE_GSSAPI
+    DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST);
+    conn->data_prot = data_sec;
+#endif
+
+    if(result)
+      break;
+
+    if(conn->data->set.verbose)
+      Curl_debug(conn->data, CURLINFO_HEADER_OUT,
+                 sptr, (size_t)bytes_written, conn);
+
+    if(bytes_written != (ssize_t)write_len) {
+      write_len -= bytes_written;
+      sptr += bytes_written;
+    }
+    else
+      break;
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * ftp_quit()
+ *
+ * This should be called before calling sclose() on an ftp control connection
+ * (not data connections). We should then wait for the response from the
+ * server before returning. The calling code should then try to close the
+ * connection.
+ *
+ */
+static CURLcode ftp_quit(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  if(conn->proto.ftpc.ctl_valid) {
+    result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", "QUIT");
+    if(result) {
+      failf(conn->data, "Failure sending QUIT command: %s",
+            curl_easy_strerror(result));
+      conn->proto.ftpc.ctl_valid = FALSE; /* mark control connection as bad */
+      connclose(conn, "QUIT command failed"); /* mark for connection closure */
+      state(conn, FTP_STOP);
+      return result;
+    }
+
+    state(conn, FTP_QUIT);
+
+    result = ftp_block_statemach(conn);
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * ftp_disconnect()
+ *
+ * Disconnect from an FTP server. Cleanup protocol-specific per-connection
+ * resources. BLOCKING.
+ */
+static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  struct pingpong *pp = &ftpc->pp;
+
+  /* We cannot send quit unconditionally. If this connection is stale or
+     bad in any way, sending quit and waiting around here will make the
+     disconnect wait in vain and cause more problems than we need to.
+
+     ftp_quit() will check the state of ftp->ctl_valid. If it's ok it
+     will try to send the QUIT command, otherwise it will just return.
+  */
+  if(dead_connection)
+    ftpc->ctl_valid = FALSE;
+
+  /* The FTP session may or may not have been allocated/setup at this point! */
+  (void)ftp_quit(conn); /* ignore errors on the QUIT */
+
+  if(ftpc->entrypath) {
+    struct Curl_easy *data = conn->data;
+    if(data->state.most_recent_ftp_entrypath == ftpc->entrypath) {
+      data->state.most_recent_ftp_entrypath = NULL;
+    }
+    free(ftpc->entrypath);
+    ftpc->entrypath = NULL;
+  }
+
+  freedirs(ftpc);
+  free(ftpc->prevpath);
+  ftpc->prevpath = NULL;
+  free(ftpc->server_os);
+  ftpc->server_os = NULL;
+
+  Curl_pp_disconnect(pp);
+
+#ifdef HAVE_GSSAPI
+  Curl_sec_end(conn);
+#endif
+
+  return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * ftp_parse_url_path()
+ *
+ * Parse the URL path into separate path components.
+ *
+ */
+static
+CURLcode ftp_parse_url_path(struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  /* the ftp struct is already inited in ftp_connect() */
+  struct FTP *ftp = data->req.protop;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  const char *slash_pos;  /* position of the first '/' char in curpos */
+  const char *path_to_use = data->state.path;
+  const char *cur_pos;
+  const char *filename = NULL;
+
+  cur_pos = path_to_use; /* current position in path. point at the begin of
+                            next path component */
+
+  ftpc->ctl_valid = FALSE;
+  ftpc->cwdfail = FALSE;
+
+  switch(data->set.ftp_filemethod) {
+  case FTPFILE_NOCWD:
+    /* fastest, but less standard-compliant */
+
+    /*
+      The best time to check whether the path is a file or directory is right
+      here. so:
+
+      the first condition in the if() right here, is there just in case
+      someone decides to set path to NULL one day
+   */
+    if(path_to_use[0] &&
+       (path_to_use[strlen(path_to_use) - 1] != '/') )
+      filename = path_to_use;  /* this is a full file path */
+    /*
+      else {
+        ftpc->file is not used anywhere other than for operations on a file.
+        In other words, never for directory operations.
+        So we can safely leave filename as NULL here and use it as a
+        argument in dir/file decisions.
+      }
+    */
+    break;
+
+  case FTPFILE_SINGLECWD:
+    /* get the last slash */
+    if(!path_to_use[0]) {
+      /* no dir, no file */
+      ftpc->dirdepth = 0;
+      break;
+    }
+    slash_pos = strrchr(cur_pos, '/');
+    if(slash_pos || !*cur_pos) {
+      size_t dirlen = slash_pos-cur_pos;
+      CURLcode result;
+
+      ftpc->dirs = calloc(1, sizeof(ftpc->dirs[0]));
+      if(!ftpc->dirs)
+        return CURLE_OUT_OF_MEMORY;
+
+      if(!dirlen)
+        dirlen++;
+
+      result = Curl_urldecode(conn->data, slash_pos ? cur_pos : "/",
+                              slash_pos ? dirlen : 1,
+                              &ftpc->dirs[0], NULL,
+                              FALSE);
+      if(result) {
+        freedirs(ftpc);
+        return result;
+      }
+      ftpc->dirdepth = 1; /* we consider it to be a single dir */
+      filename = slash_pos ? slash_pos + 1 : cur_pos; /* rest is file name */
+    }
+    else
+      filename = cur_pos;  /* this is a file name only */
+    break;
+
+  default: /* allow pretty much anything */
+  case FTPFILE_MULTICWD:
+    ftpc->dirdepth = 0;
+    ftpc->diralloc = 5; /* default dir depth to allocate */
+    ftpc->dirs = calloc(ftpc->diralloc, sizeof(ftpc->dirs[0]));
+    if(!ftpc->dirs)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* we have a special case for listing the root dir only */
+    if(!strcmp(path_to_use, "/")) {
+      cur_pos++; /* make it point to the zero byte */
+      ftpc->dirs[0] = strdup("/");
+      ftpc->dirdepth++;
+    }
+    else {
+      /* parse the URL path into separate path components */
+      while((slash_pos = strchr(cur_pos, '/')) != NULL) {
+        /* 1 or 0 pointer offset to indicate absolute directory */
+        ssize_t absolute_dir = ((cur_pos - data->state.path > 0) &&
+                                (ftpc->dirdepth == 0))?1:0;
+
+        /* seek out the next path component */
+        if(slash_pos-cur_pos) {
+          /* we skip empty path components, like "x//y" since the FTP command
+             CWD requires a parameter and a non-existent parameter a) doesn't
+             work on many servers and b) has no effect on the others. */
+          size_t len = slash_pos - cur_pos + absolute_dir;
+          CURLcode result =
+            Curl_urldecode(conn->data, cur_pos - absolute_dir, len,
+                           &ftpc->dirs[ftpc->dirdepth], NULL,
+                           TRUE);
+          if(result) {
+            freedirs(ftpc);
+            return result;
+          }
+        }
+        else {
+          cur_pos = slash_pos + 1; /* jump to the rest of the string */
+          if(!ftpc->dirdepth) {
+            /* path starts with a slash, add that as a directory */
+            ftpc->dirs[ftpc->dirdepth] = strdup("/");
+            if(!ftpc->dirs[ftpc->dirdepth++]) { /* run out of memory ... */
+              failf(data, "no memory");
+              freedirs(ftpc);
+              return CURLE_OUT_OF_MEMORY;
+            }
+          }
+          continue;
+        }
+
+        cur_pos = slash_pos + 1; /* jump to the rest of the string */
+        if(++ftpc->dirdepth >= ftpc->diralloc) {
+          /* enlarge array */
+          char **bigger;
+          ftpc->diralloc *= 2; /* double the size each time */
+          bigger = realloc(ftpc->dirs, ftpc->diralloc * sizeof(ftpc->dirs[0]));
+          if(!bigger) {
+            freedirs(ftpc);
+            return CURLE_OUT_OF_MEMORY;
+          }
+          ftpc->dirs = bigger;
+        }
+      }
+    }
+    filename = cur_pos;  /* the rest is the file name */
+    break;
+  } /* switch */
+
+  if(filename && *filename) {
+    CURLcode result =
+      Curl_urldecode(conn->data, filename, 0,  &ftpc->file, NULL, TRUE);
+
+    if(result) {
+      freedirs(ftpc);
+      return result;
+    }
+  }
+  else
+    ftpc->file = NULL; /* instead of point to a zero byte, we make it a NULL
+                          pointer */
+
+  if(data->set.upload && !ftpc->file && (ftp->transfer == FTPTRANSFER_BODY)) {
+    /* We need a file name when uploading. Return error! */
+    failf(data, "Uploading to a URL without a file name!");
+    return CURLE_URL_MALFORMAT;
+  }
+
+  ftpc->cwddone = FALSE; /* default to not done */
+
+  if(ftpc->prevpath) {
+    /* prevpath is "raw" so we convert the input path before we compare the
+       strings */
+    size_t dlen;
+    char *path;
+    CURLcode result =
+      Curl_urldecode(conn->data, data->state.path, 0, &path, &dlen, FALSE);
+    if(result) {
+      freedirs(ftpc);
+      return result;
+    }
+
+    dlen -= ftpc->file?strlen(ftpc->file):0;
+    if((dlen == strlen(ftpc->prevpath)) &&
+       !strncmp(path, ftpc->prevpath, dlen) &&
+       (ftpc->prevmethod == data->set.ftp_filemethod)) {
+      infof(data, "Request has same path as previous transfer\n");
+      ftpc->cwddone = TRUE;
+    }
+    free(path);
+  }
+
+  return CURLE_OK;
+}
+
+/* call this when the DO phase has completed */
+static CURLcode ftp_dophase_done(struct connectdata *conn,
+                                 bool connected)
+{
+  struct FTP *ftp = conn->data->req.protop;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+
+  if(connected) {
+    int completed;
+    CURLcode result = ftp_do_more(conn, &completed);
+
+    if(result) {
+      close_secondarysocket(conn);
+      return result;
+    }
+  }
+
+  if(ftp->transfer != FTPTRANSFER_BODY)
+    /* no data to transfer */
+    Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+  else if(!connected)
+    /* since we didn't connect now, we want do_more to get called */
+    conn->bits.do_more = TRUE;
+
+  ftpc->ctl_valid = TRUE; /* seems good */
+
+  return CURLE_OK;
+}
+
+/* called from multi.c while DOing */
+static CURLcode ftp_doing(struct connectdata *conn,
+                          bool *dophase_done)
+{
+  CURLcode result = ftp_multi_statemach(conn, dophase_done);
+
+  if(result)
+    DEBUGF(infof(conn->data, "DO phase failed\n"));
+  else if(*dophase_done) {
+    result = ftp_dophase_done(conn, FALSE /* not connected */);
+
+    DEBUGF(infof(conn->data, "DO phase is complete2\n"));
+  }
+  return result;
+}
+
+/***********************************************************************
+ *
+ * ftp_regular_transfer()
+ *
+ * The input argument is already checked for validity.
+ *
+ * Performs all commands done before a regular transfer between a local and a
+ * remote host.
+ *
+ * ftp->ctl_valid starts out as FALSE, and gets set to TRUE if we reach the
+ * ftp_done() function without finding any major problem.
+ */
+static
+CURLcode ftp_regular_transfer(struct connectdata *conn,
+                              bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+  bool connected = FALSE;
+  struct Curl_easy *data = conn->data;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
+  data->req.size = -1; /* make sure this is unknown at this point */
+
+  Curl_pgrsSetUploadCounter(data, 0);
+  Curl_pgrsSetDownloadCounter(data, 0);
+  Curl_pgrsSetUploadSize(data, -1);
+  Curl_pgrsSetDownloadSize(data, -1);
+
+  ftpc->ctl_valid = TRUE; /* starts good */
+
+  result = ftp_perform(conn,
+                       &connected, /* have we connected after PASV/PORT */
+                       dophase_done); /* all commands in the DO-phase done? */
+
+  if(!result) {
+
+    if(!*dophase_done)
+      /* the DO phase has not completed yet */
+      return CURLE_OK;
+
+    result = ftp_dophase_done(conn, connected);
+
+    if(result)
+      return result;
+  }
+  else
+    freedirs(ftpc);
+
+  return result;
+}
+
+static CURLcode ftp_setup_connection(struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  char *type;
+  char command;
+  struct FTP *ftp;
+
+  conn->data->req.protop = ftp = malloc(sizeof(struct FTP));
+  if(NULL == ftp)
+    return CURLE_OUT_OF_MEMORY;
+
+  data->state.path++;   /* don't include the initial slash */
+  data->state.slash_removed = TRUE; /* we've skipped the slash */
+
+  /* FTP URLs support an extension like ";type=<typecode>" that
+   * we'll try to get now! */
+  type = strstr(data->state.path, ";type=");
+
+  if(!type)
+    type = strstr(conn->host.rawalloc, ";type=");
+
+  if(type) {
+    *type = 0;                     /* it was in the middle of the hostname */
+    command = Curl_raw_toupper(type[6]);
+    conn->bits.type_set = TRUE;
+
+    switch(command) {
+    case 'A': /* ASCII mode */
+      data->set.prefer_ascii = TRUE;
+      break;
+
+    case 'D': /* directory mode */
+      data->set.ftp_list_only = TRUE;
+      break;
+
+    case 'I': /* binary mode */
+    default:
+      /* switch off ASCII */
+      data->set.prefer_ascii = FALSE;
+      break;
+    }
+  }
+
+  /* get some initial data into the ftp struct */
+  ftp->bytecountp = &conn->data->req.bytecount;
+  ftp->transfer = FTPTRANSFER_BODY;
+  ftp->downloadsize = 0;
+
+  /* No need to duplicate user+password, the connectdata struct won't change
+     during a session, but we re-init them here since on subsequent inits
+     since the conn struct may have changed or been replaced.
+  */
+  ftp->user = conn->user;
+  ftp->passwd = conn->passwd;
+  if(isBadFtpString(ftp->user))
+    return CURLE_URL_MALFORMAT;
+  if(isBadFtpString(ftp->passwd))
+    return CURLE_URL_MALFORMAT;
+
+  conn->proto.ftpc.known_filesize = -1; /* unknown size for now */
+
+  return CURLE_OK;
+}
+
+#endif /* CURL_DISABLE_FTP */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/ftp.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/ftp.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/ftp.h	(revision 331)
@@ -0,0 +1,161 @@
+#ifndef HEADER_CURL_FTP_H
+#define HEADER_CURL_FTP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "pingpong.h"
+
+#ifndef CURL_DISABLE_FTP
+extern const struct Curl_handler Curl_handler_ftp;
+
+#ifdef USE_SSL
+extern const struct Curl_handler Curl_handler_ftps;
+#endif
+
+CURLcode Curl_ftpsend(struct connectdata *, const char *cmd);
+CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn,
+                             int *ftpcode);
+#endif /* CURL_DISABLE_FTP */
+
+/****************************************************************************
+ * FTP unique setup
+ ***************************************************************************/
+typedef enum {
+  FTP_STOP,    /* do nothing state, stops the state machine */
+  FTP_WAIT220, /* waiting for the initial 220 response immediately after
+                  a connect */
+  FTP_AUTH,
+  FTP_USER,
+  FTP_PASS,
+  FTP_ACCT,
+  FTP_PBSZ,
+  FTP_PROT,
+  FTP_CCC,
+  FTP_PWD,
+  FTP_SYST,
+  FTP_NAMEFMT,
+  FTP_QUOTE, /* waiting for a response to a command sent in a quote list */
+  FTP_RETR_PREQUOTE,
+  FTP_STOR_PREQUOTE,
+  FTP_POSTQUOTE,
+  FTP_CWD,  /* change dir */
+  FTP_MKD,  /* if the dir didn't exist */
+  FTP_MDTM, /* to figure out the datestamp */
+  FTP_TYPE, /* to set type when doing a head-like request */
+  FTP_LIST_TYPE, /* set type when about to do a dir list */
+  FTP_RETR_TYPE, /* set type when about to RETR a file */
+  FTP_STOR_TYPE, /* set type when about to STOR a file */
+  FTP_SIZE, /* get the remote file's size for head-like request */
+  FTP_RETR_SIZE, /* get the remote file's size for RETR */
+  FTP_STOR_SIZE, /* get the size for STOR */
+  FTP_REST, /* when used to check if the server supports it in head-like */
+  FTP_RETR_REST, /* when asking for "resume" in for RETR */
+  FTP_PORT, /* generic state for PORT, LPRT and EPRT, check count1 */
+  FTP_PRET, /* generic state for PRET RETR, PRET STOR and PRET LIST/NLST */
+  FTP_PASV, /* generic state for PASV and EPSV, check count1 */
+  FTP_LIST, /* generic state for LIST, NLST or a custom list command */
+  FTP_RETR,
+  FTP_STOR, /* generic state for STOR and APPE */
+  FTP_QUIT,
+  FTP_LAST  /* never used */
+} ftpstate;
+
+struct ftp_parselist_data; /* defined later in ftplistparser.c */
+
+struct ftp_wc_tmpdata {
+  struct ftp_parselist_data *parser;
+
+  struct {
+    curl_write_callback write_function;
+    FILE *file_descriptor;
+  } backup;
+};
+
+typedef enum {
+  FTPFILE_MULTICWD  = 1, /* as defined by RFC1738 */
+  FTPFILE_NOCWD     = 2, /* use SIZE / RETR / STOR on the full path */
+  FTPFILE_SINGLECWD = 3  /* make one CWD, then SIZE / RETR / STOR on the
+                            file */
+} curl_ftpfile;
+
+/* This FTP struct is used in the Curl_easy. All FTP data that is
+   connection-oriented must be in FTP_conn to properly deal with the fact that
+   perhaps the Curl_easy is changed between the times the connection is
+   used. */
+struct FTP {
+  curl_off_t *bytecountp;
+  char *user;    /* user name string */
+  char *passwd;  /* password string */
+
+  /* transfer a file/body or not, done as a typedefed enum just to make
+     debuggers display the full symbol and not just the numerical value */
+  curl_pp_transfer transfer;
+  curl_off_t downloadsize;
+};
+
+
+/* ftp_conn is used for struct connection-oriented data in the connectdata
+   struct */
+struct ftp_conn {
+  struct pingpong pp;
+  char *entrypath; /* the PWD reply when we logged on */
+  char **dirs;   /* realloc()ed array for path components */
+  int dirdepth;  /* number of entries used in the 'dirs' array */
+  int diralloc;  /* number of entries allocated for the 'dirs' array */
+  char *file;    /* decoded file */
+  bool dont_check;  /* Set to TRUE to prevent the final (post-transfer)
+                       file size and 226/250 status check. It should still
+                       read the line, just ignore the result. */
+  bool ctl_valid;   /* Tells Curl_ftp_quit() whether or not to do anything. If
+                       the connection has timed out or been closed, this
+                       should be FALSE when it gets to Curl_ftp_quit() */
+  bool cwddone;     /* if it has been determined that the proper CWD combo
+                       already has been done */
+  int cwdcount;     /* number of CWD commands issued */
+  bool cwdfail;     /* set TRUE if a CWD command fails, as then we must prevent
+                       caching the current directory */
+  bool wait_data_conn; /* this is set TRUE if data connection is waited */
+  char *prevpath;   /* conn->path from the previous transfer */
+  curl_ftpfile prevmethod; /* ftp method in previous transfer  */
+  char transfertype; /* set by ftp_transfertype for use by Curl_client_write()a
+                        and others (A/I or zero) */
+  int count1; /* general purpose counter for the state machine */
+  int count2; /* general purpose counter for the state machine */
+  int count3; /* general purpose counter for the state machine */
+  ftpstate state; /* always use ftp.c:state() to change state! */
+  ftpstate state_saved; /* transfer type saved to be reloaded after
+                           data connection is established */
+  curl_off_t retr_size_saved; /* Size of retrieved file saved */
+  char *server_os;     /* The target server operating system. */
+  curl_off_t known_filesize; /* file size is different from -1, if wildcard
+                                LIST parsing was done and wc_statemach set
+                                it */
+  /* newhost is the (allocated) IP addr or host name to connect the data
+     connection to */
+  char *newhost;          /* this is the pair to connect the DATA... */
+  unsigned short newport; /* connection to */
+
+};
+
+#define DEFAULT_ACCEPT_TIMEOUT   60000 /* milliseconds == one minute */
+
+#endif /* HEADER_CURL_FTP_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/ftplistparser.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/ftplistparser.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/ftplistparser.c	(revision 331)
@@ -0,0 +1,1015 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/**
+ * Now implemented:
+ *
+ * 1) Unix version 1
+ * drwxr-xr-x 1 user01 ftp  512 Jan 29 23:32 prog
+ * 2) Unix version 2
+ * drwxr-xr-x 1 user01 ftp  512 Jan 29 1997  prog
+ * 3) Unix version 3
+ * drwxr-xr-x 1      1   1  512 Jan 29 23:32 prog
+ * 4) Unix symlink
+ * lrwxr-xr-x 1 user01 ftp  512 Jan 29 23:32 prog -> prog2000
+ * 5) DOS style
+ * 01-29-97 11:32PM <DIR> prog
+ */
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_FTP
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "fileinfo.h"
+#include "llist.h"
+#include "strtoofft.h"
+#include "ftp.h"
+#include "ftplistparser.h"
+#include "curl_fnmatch.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* allocs buffer which will contain one line of LIST command response */
+#define FTP_BUFFER_ALLOCSIZE 160
+
+typedef enum {
+  PL_UNIX_TOTALSIZE = 0,
+  PL_UNIX_FILETYPE,
+  PL_UNIX_PERMISSION,
+  PL_UNIX_HLINKS,
+  PL_UNIX_USER,
+  PL_UNIX_GROUP,
+  PL_UNIX_SIZE,
+  PL_UNIX_TIME,
+  PL_UNIX_FILENAME,
+  PL_UNIX_SYMLINK
+} pl_unix_mainstate;
+
+typedef union {
+  enum {
+    PL_UNIX_TOTALSIZE_INIT = 0,
+    PL_UNIX_TOTALSIZE_READING
+  } total_dirsize;
+
+  enum {
+    PL_UNIX_HLINKS_PRESPACE = 0,
+    PL_UNIX_HLINKS_NUMBER
+  } hlinks;
+
+  enum {
+    PL_UNIX_USER_PRESPACE = 0,
+    PL_UNIX_USER_PARSING
+  } user;
+
+  enum {
+    PL_UNIX_GROUP_PRESPACE = 0,
+    PL_UNIX_GROUP_NAME
+  } group;
+
+  enum {
+    PL_UNIX_SIZE_PRESPACE = 0,
+    PL_UNIX_SIZE_NUMBER
+  } size;
+
+  enum {
+    PL_UNIX_TIME_PREPART1 = 0,
+    PL_UNIX_TIME_PART1,
+    PL_UNIX_TIME_PREPART2,
+    PL_UNIX_TIME_PART2,
+    PL_UNIX_TIME_PREPART3,
+    PL_UNIX_TIME_PART3
+  } time;
+
+  enum {
+    PL_UNIX_FILENAME_PRESPACE = 0,
+    PL_UNIX_FILENAME_NAME,
+    PL_UNIX_FILENAME_WINDOWSEOL
+  } filename;
+
+  enum {
+    PL_UNIX_SYMLINK_PRESPACE = 0,
+    PL_UNIX_SYMLINK_NAME,
+    PL_UNIX_SYMLINK_PRETARGET1,
+    PL_UNIX_SYMLINK_PRETARGET2,
+    PL_UNIX_SYMLINK_PRETARGET3,
+    PL_UNIX_SYMLINK_PRETARGET4,
+    PL_UNIX_SYMLINK_TARGET,
+    PL_UNIX_SYMLINK_WINDOWSEOL
+  } symlink;
+} pl_unix_substate;
+
+typedef enum {
+  PL_WINNT_DATE = 0,
+  PL_WINNT_TIME,
+  PL_WINNT_DIRORSIZE,
+  PL_WINNT_FILENAME
+} pl_winNT_mainstate;
+
+typedef union {
+  enum {
+    PL_WINNT_TIME_PRESPACE = 0,
+    PL_WINNT_TIME_TIME
+  } time;
+  enum {
+    PL_WINNT_DIRORSIZE_PRESPACE = 0,
+    PL_WINNT_DIRORSIZE_CONTENT
+  } dirorsize;
+  enum {
+    PL_WINNT_FILENAME_PRESPACE = 0,
+    PL_WINNT_FILENAME_CONTENT,
+    PL_WINNT_FILENAME_WINEOL
+  } filename;
+} pl_winNT_substate;
+
+/* This struct is used in wildcard downloading - for parsing LIST response */
+struct ftp_parselist_data {
+  enum {
+    OS_TYPE_UNKNOWN = 0,
+    OS_TYPE_UNIX,
+    OS_TYPE_WIN_NT
+  } os_type;
+
+  union {
+    struct {
+      pl_unix_mainstate main;
+      pl_unix_substate sub;
+    } UNIX;
+
+    struct {
+      pl_winNT_mainstate main;
+      pl_winNT_substate sub;
+    } NT;
+  } state;
+
+  CURLcode error;
+  struct fileinfo *file_data;
+  unsigned int item_length;
+  size_t item_offset;
+  struct {
+    size_t filename;
+    size_t user;
+    size_t group;
+    size_t time;
+    size_t perm;
+    size_t symlink_target;
+  } offsets;
+};
+
+struct ftp_parselist_data *Curl_ftp_parselist_data_alloc(void)
+{
+  return calloc(1, sizeof(struct ftp_parselist_data));
+}
+
+
+void Curl_ftp_parselist_data_free(struct ftp_parselist_data **pl_data)
+{
+  free(*pl_data);
+  *pl_data = NULL;
+}
+
+
+CURLcode Curl_ftp_parselist_geterror(struct ftp_parselist_data *pl_data)
+{
+  return pl_data->error;
+}
+
+
+#define FTP_LP_MALFORMATED_PERM 0x01000000
+
+static int ftp_pl_get_permission(const char *str)
+{
+  int permissions = 0;
+  /* USER */
+  if(str[0] == 'r')
+    permissions |= 1 << 8;
+  else if(str[0] != '-')
+    permissions |= FTP_LP_MALFORMATED_PERM;
+  if(str[1] == 'w')
+    permissions |= 1 << 7;
+  else if(str[1] != '-')
+    permissions |= FTP_LP_MALFORMATED_PERM;
+
+  if(str[2] == 'x')
+    permissions |= 1 << 6;
+  else if(str[2] == 's') {
+    permissions |= 1 << 6;
+    permissions |= 1 << 11;
+  }
+  else if(str[2] == 'S')
+    permissions |= 1 << 11;
+  else if(str[2] != '-')
+    permissions |= FTP_LP_MALFORMATED_PERM;
+  /* GROUP */
+  if(str[3] == 'r')
+    permissions |= 1 << 5;
+  else if(str[3] != '-')
+    permissions |= FTP_LP_MALFORMATED_PERM;
+  if(str[4] == 'w')
+    permissions |= 1 << 4;
+  else if(str[4] != '-')
+    permissions |= FTP_LP_MALFORMATED_PERM;
+  if(str[5] == 'x')
+    permissions |= 1 << 3;
+  else if(str[5] == 's') {
+    permissions |= 1 << 3;
+    permissions |= 1 << 10;
+  }
+  else if(str[5] == 'S')
+    permissions |= 1 << 10;
+  else if(str[5] != '-')
+    permissions |= FTP_LP_MALFORMATED_PERM;
+  /* others */
+  if(str[6] == 'r')
+    permissions |= 1 << 2;
+  else if(str[6] != '-')
+    permissions |= FTP_LP_MALFORMATED_PERM;
+  if(str[7] == 'w')
+    permissions |= 1 << 1;
+  else if(str[7] != '-')
+      permissions |= FTP_LP_MALFORMATED_PERM;
+  if(str[8] == 'x')
+    permissions |= 1;
+  else if(str[8] == 't') {
+    permissions |= 1;
+    permissions |= 1 << 9;
+  }
+  else if(str[8] == 'T')
+    permissions |= 1 << 9;
+  else if(str[8] != '-')
+    permissions |= FTP_LP_MALFORMATED_PERM;
+
+  return permissions;
+}
+
+static CURLcode ftp_pl_insert_finfo(struct connectdata *conn,
+                                    struct fileinfo *infop)
+{
+  curl_fnmatch_callback compare;
+  struct WildcardData *wc = &conn->data->wildcard;
+  struct ftp_wc_tmpdata *tmpdata = wc->tmp;
+  struct curl_llist *llist = &wc->filelist;
+  struct ftp_parselist_data *parser = tmpdata->parser;
+  bool add = TRUE;
+  struct curl_fileinfo *finfo = &infop->info;
+
+  /* move finfo pointers to b_data */
+  char *str = finfo->b_data;
+  finfo->filename       = str + parser->offsets.filename;
+  finfo->strings.group  = parser->offsets.group ?
+                          str + parser->offsets.group : NULL;
+  finfo->strings.perm   = parser->offsets.perm ?
+                          str + parser->offsets.perm : NULL;
+  finfo->strings.target = parser->offsets.symlink_target ?
+                          str + parser->offsets.symlink_target : NULL;
+  finfo->strings.time   = str + parser->offsets.time;
+  finfo->strings.user   = parser->offsets.user ?
+                          str + parser->offsets.user : NULL;
+
+  /* get correct fnmatch callback */
+  compare = conn->data->set.fnmatch;
+  if(!compare)
+    compare = Curl_fnmatch;
+
+  /* filter pattern-corresponding filenames */
+  if(compare(conn->data->set.fnmatch_data, wc->pattern,
+             finfo->filename) == 0) {
+    /* discard symlink which is containing multiple " -> " */
+    if((finfo->filetype == CURLFILETYPE_SYMLINK) && finfo->strings.target &&
+       (strstr(finfo->strings.target, " -> "))) {
+      add = FALSE;
+    }
+  }
+  else {
+    add = FALSE;
+  }
+
+  if(add) {
+    Curl_llist_insert_next(llist, llist->tail, finfo, &infop->list);
+  }
+  else {
+    Curl_fileinfo_dtor(NULL, finfo);
+  }
+
+  tmpdata->parser->file_data = NULL;
+  return CURLE_OK;
+}
+
+size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
+                          void *connptr)
+{
+  size_t bufflen = size*nmemb;
+  struct connectdata *conn = (struct connectdata *)connptr;
+  struct ftp_wc_tmpdata *tmpdata = conn->data->wildcard.tmp;
+  struct ftp_parselist_data *parser = tmpdata->parser;
+  struct fileinfo *infop;
+  struct curl_fileinfo *finfo;
+  unsigned long i = 0;
+  CURLcode result;
+  size_t retsize = bufflen;
+
+  if(parser->error) { /* error in previous call */
+    /* scenario:
+     * 1. call => OK..
+     * 2. call => OUT_OF_MEMORY (or other error)
+     * 3. (last) call => is skipped RIGHT HERE and the error is hadled later
+     *    in wc_statemach()
+     */
+    goto fail;
+  }
+
+  if(parser->os_type == OS_TYPE_UNKNOWN && bufflen > 0) {
+    /* considering info about FILE response format */
+    parser->os_type = (buffer[0] >= '0' && buffer[0] <= '9') ?
+                       OS_TYPE_WIN_NT : OS_TYPE_UNIX;
+  }
+
+  while(i < bufflen) { /* FSM */
+
+    char c = buffer[i];
+    if(!parser->file_data) { /* tmp file data is not allocated yet */
+      parser->file_data = Curl_fileinfo_alloc();
+      if(!parser->file_data) {
+        parser->error = CURLE_OUT_OF_MEMORY;
+        goto fail;
+      }
+      parser->file_data->info.b_data = malloc(FTP_BUFFER_ALLOCSIZE);
+      if(!parser->file_data->info.b_data) {
+        parser->error = CURLE_OUT_OF_MEMORY;
+        goto fail;
+      }
+      parser->file_data->info.b_size = FTP_BUFFER_ALLOCSIZE;
+      parser->item_offset = 0;
+      parser->item_length = 0;
+    }
+
+    infop = parser->file_data;
+    finfo = &infop->info;
+    finfo->b_data[finfo->b_used++] = c;
+
+    if(finfo->b_used >= finfo->b_size - 1) {
+      /* if it is important, extend buffer space for file data */
+      char *tmp = realloc(finfo->b_data,
+                          finfo->b_size + FTP_BUFFER_ALLOCSIZE);
+      if(tmp) {
+        finfo->b_size += FTP_BUFFER_ALLOCSIZE;
+        finfo->b_data = tmp;
+      }
+      else {
+        Curl_fileinfo_dtor(NULL, parser->file_data);
+        parser->file_data = NULL;
+        parser->error = CURLE_OUT_OF_MEMORY;
+        goto fail;
+      }
+    }
+
+    switch(parser->os_type) {
+    case OS_TYPE_UNIX:
+      switch(parser->state.UNIX.main) {
+      case PL_UNIX_TOTALSIZE:
+        switch(parser->state.UNIX.sub.total_dirsize) {
+        case PL_UNIX_TOTALSIZE_INIT:
+          if(c == 't') {
+            parser->state.UNIX.sub.total_dirsize = PL_UNIX_TOTALSIZE_READING;
+            parser->item_length++;
+          }
+          else {
+            parser->state.UNIX.main = PL_UNIX_FILETYPE;
+            /* start FSM again not considering size of directory */
+            finfo->b_used = 0;
+            i--;
+          }
+          break;
+        case PL_UNIX_TOTALSIZE_READING:
+          parser->item_length++;
+          if(c == '\r') {
+            parser->item_length--;
+            finfo->b_used--;
+          }
+          else if(c == '\n') {
+            finfo->b_data[parser->item_length - 1] = 0;
+            if(strncmp("total ", finfo->b_data, 6) == 0) {
+              char *endptr = finfo->b_data + 6;
+              /* here we can deal with directory size, pass the leading white
+                 spaces and then the digits */
+              while(ISSPACE(*endptr))
+                endptr++;
+              while(ISDIGIT(*endptr))
+                endptr++;
+              if(*endptr != 0) {
+                parser->error = CURLE_FTP_BAD_FILE_LIST;
+                goto fail;
+              }
+              parser->state.UNIX.main = PL_UNIX_FILETYPE;
+              finfo->b_used = 0;
+            }
+            else {
+              parser->error = CURLE_FTP_BAD_FILE_LIST;
+              goto fail;
+            }
+          }
+          break;
+        }
+        break;
+      case PL_UNIX_FILETYPE:
+        switch(c) {
+        case '-':
+          finfo->filetype = CURLFILETYPE_FILE;
+          break;
+        case 'd':
+          finfo->filetype = CURLFILETYPE_DIRECTORY;
+          break;
+        case 'l':
+          finfo->filetype = CURLFILETYPE_SYMLINK;
+          break;
+        case 'p':
+          finfo->filetype = CURLFILETYPE_NAMEDPIPE;
+          break;
+        case 's':
+          finfo->filetype = CURLFILETYPE_SOCKET;
+          break;
+        case 'c':
+          finfo->filetype = CURLFILETYPE_DEVICE_CHAR;
+          break;
+        case 'b':
+          finfo->filetype = CURLFILETYPE_DEVICE_BLOCK;
+          break;
+        case 'D':
+          finfo->filetype = CURLFILETYPE_DOOR;
+          break;
+        default:
+          parser->error = CURLE_FTP_BAD_FILE_LIST;
+          goto fail;
+        }
+        parser->state.UNIX.main = PL_UNIX_PERMISSION;
+        parser->item_length = 0;
+        parser->item_offset = 1;
+        break;
+      case PL_UNIX_PERMISSION:
+        parser->item_length++;
+        if(parser->item_length <= 9) {
+          if(!strchr("rwx-tTsS", c)) {
+            parser->error = CURLE_FTP_BAD_FILE_LIST;
+            goto fail;
+          }
+        }
+        else if(parser->item_length == 10) {
+          unsigned int perm;
+          if(c != ' ') {
+            parser->error = CURLE_FTP_BAD_FILE_LIST;
+            goto fail;
+          }
+          finfo->b_data[10] = 0; /* terminate permissions */
+          perm = ftp_pl_get_permission(finfo->b_data + parser->item_offset);
+          if(perm & FTP_LP_MALFORMATED_PERM) {
+            parser->error = CURLE_FTP_BAD_FILE_LIST;
+            goto fail;
+          }
+          parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_PERM;
+          parser->file_data->info.perm = perm;
+          parser->offsets.perm = parser->item_offset;
+
+          parser->item_length = 0;
+          parser->state.UNIX.main = PL_UNIX_HLINKS;
+          parser->state.UNIX.sub.hlinks = PL_UNIX_HLINKS_PRESPACE;
+        }
+        break;
+      case PL_UNIX_HLINKS:
+        switch(parser->state.UNIX.sub.hlinks) {
+        case PL_UNIX_HLINKS_PRESPACE:
+          if(c != ' ') {
+            if(c >= '0' && c <= '9') {
+              parser->item_offset = finfo->b_used - 1;
+              parser->item_length = 1;
+              parser->state.UNIX.sub.hlinks = PL_UNIX_HLINKS_NUMBER;
+            }
+            else {
+              parser->error = CURLE_FTP_BAD_FILE_LIST;
+              goto fail;
+            }
+          }
+          break;
+        case PL_UNIX_HLINKS_NUMBER:
+          parser->item_length ++;
+          if(c == ' ') {
+            char *p;
+            long int hlinks;
+            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+            hlinks = strtol(finfo->b_data + parser->item_offset, &p, 10);
+            if(p[0] == '\0' && hlinks != LONG_MAX && hlinks != LONG_MIN) {
+              parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_HLINKCOUNT;
+              parser->file_data->info.hardlinks = hlinks;
+            }
+            parser->item_length = 0;
+            parser->item_offset = 0;
+            parser->state.UNIX.main = PL_UNIX_USER;
+            parser->state.UNIX.sub.user = PL_UNIX_USER_PRESPACE;
+          }
+          else if(c < '0' || c > '9') {
+            parser->error = CURLE_FTP_BAD_FILE_LIST;
+            goto fail;
+          }
+          break;
+        }
+        break;
+      case PL_UNIX_USER:
+        switch(parser->state.UNIX.sub.user) {
+        case PL_UNIX_USER_PRESPACE:
+          if(c != ' ') {
+            parser->item_offset = finfo->b_used - 1;
+            parser->item_length = 1;
+            parser->state.UNIX.sub.user = PL_UNIX_USER_PARSING;
+          }
+          break;
+        case PL_UNIX_USER_PARSING:
+          parser->item_length++;
+          if(c == ' ') {
+            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+            parser->offsets.user = parser->item_offset;
+            parser->state.UNIX.main = PL_UNIX_GROUP;
+            parser->state.UNIX.sub.group = PL_UNIX_GROUP_PRESPACE;
+            parser->item_offset = 0;
+            parser->item_length = 0;
+          }
+          break;
+        }
+        break;
+      case PL_UNIX_GROUP:
+        switch(parser->state.UNIX.sub.group) {
+        case PL_UNIX_GROUP_PRESPACE:
+          if(c != ' ') {
+            parser->item_offset = finfo->b_used - 1;
+            parser->item_length = 1;
+            parser->state.UNIX.sub.group = PL_UNIX_GROUP_NAME;
+          }
+          break;
+        case PL_UNIX_GROUP_NAME:
+          parser->item_length++;
+          if(c == ' ') {
+            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+            parser->offsets.group = parser->item_offset;
+            parser->state.UNIX.main = PL_UNIX_SIZE;
+            parser->state.UNIX.sub.size = PL_UNIX_SIZE_PRESPACE;
+            parser->item_offset = 0;
+            parser->item_length = 0;
+          }
+          break;
+        }
+        break;
+      case PL_UNIX_SIZE:
+        switch(parser->state.UNIX.sub.size) {
+        case PL_UNIX_SIZE_PRESPACE:
+          if(c != ' ') {
+            if(c >= '0' && c <= '9') {
+              parser->item_offset = finfo->b_used - 1;
+              parser->item_length = 1;
+              parser->state.UNIX.sub.size = PL_UNIX_SIZE_NUMBER;
+            }
+            else {
+              parser->error = CURLE_FTP_BAD_FILE_LIST;
+              goto fail;
+            }
+          }
+          break;
+        case PL_UNIX_SIZE_NUMBER:
+          parser->item_length++;
+          if(c == ' ') {
+            char *p;
+            curl_off_t fsize;
+            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+            if(!curlx_strtoofft(finfo->b_data + parser->item_offset,
+                                &p, 10, &fsize)) {
+              if(p[0] == '\0' && fsize != CURL_OFF_T_MAX &&
+                 fsize != CURL_OFF_T_MIN) {
+                parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_SIZE;
+                parser->file_data->info.size = fsize;
+              }
+              parser->item_length = 0;
+              parser->item_offset = 0;
+              parser->state.UNIX.main = PL_UNIX_TIME;
+              parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART1;
+            }
+          }
+          else if(!ISDIGIT(c)) {
+            parser->error = CURLE_FTP_BAD_FILE_LIST;
+            goto fail;
+          }
+          break;
+        }
+        break;
+      case PL_UNIX_TIME:
+        switch(parser->state.UNIX.sub.time) {
+        case PL_UNIX_TIME_PREPART1:
+          if(c != ' ') {
+            if(ISALNUM(c)) {
+              parser->item_offset = finfo->b_used -1;
+              parser->item_length = 1;
+              parser->state.UNIX.sub.time = PL_UNIX_TIME_PART1;
+            }
+            else {
+              parser->error = CURLE_FTP_BAD_FILE_LIST;
+              goto fail;
+            }
+          }
+          break;
+        case PL_UNIX_TIME_PART1:
+          parser->item_length++;
+          if(c == ' ') {
+            parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART2;
+          }
+          else if(!ISALNUM(c) && c != '.') {
+            parser->error = CURLE_FTP_BAD_FILE_LIST;
+            goto fail;
+          }
+          break;
+        case PL_UNIX_TIME_PREPART2:
+          parser->item_length++;
+          if(c != ' ') {
+            if(ISALNUM(c)) {
+              parser->state.UNIX.sub.time = PL_UNIX_TIME_PART2;
+            }
+            else {
+              parser->error = CURLE_FTP_BAD_FILE_LIST;
+              goto fail;
+            }
+          }
+          break;
+        case PL_UNIX_TIME_PART2:
+          parser->item_length++;
+          if(c == ' ') {
+            parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART3;
+          }
+          else if(!ISALNUM(c) && c != '.') {
+            parser->error = CURLE_FTP_BAD_FILE_LIST;
+            goto fail;
+          }
+          break;
+        case PL_UNIX_TIME_PREPART3:
+          parser->item_length++;
+          if(c != ' ') {
+            if(ISALNUM(c)) {
+              parser->state.UNIX.sub.time = PL_UNIX_TIME_PART3;
+            }
+            else {
+              parser->error = CURLE_FTP_BAD_FILE_LIST;
+              goto fail;
+            }
+          }
+          break;
+        case PL_UNIX_TIME_PART3:
+          parser->item_length++;
+          if(c == ' ') {
+            finfo->b_data[parser->item_offset + parser->item_length -1] = 0;
+            parser->offsets.time = parser->item_offset;
+            /*
+              if(ftp_pl_gettime(parser, finfo->b_data + parser->item_offset)) {
+                parser->file_data->flags |= CURLFINFOFLAG_KNOWN_TIME;
+              }
+            */
+            if(finfo->filetype == CURLFILETYPE_SYMLINK) {
+              parser->state.UNIX.main = PL_UNIX_SYMLINK;
+              parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRESPACE;
+            }
+            else {
+              parser->state.UNIX.main = PL_UNIX_FILENAME;
+              parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_PRESPACE;
+            }
+          }
+          else if(!ISALNUM(c) && c != '.' && c != ':') {
+            parser->error = CURLE_FTP_BAD_FILE_LIST;
+            goto fail;
+          }
+          break;
+        }
+        break;
+      case PL_UNIX_FILENAME:
+        switch(parser->state.UNIX.sub.filename) {
+        case PL_UNIX_FILENAME_PRESPACE:
+          if(c != ' ') {
+            parser->item_offset = finfo->b_used - 1;
+            parser->item_length = 1;
+            parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_NAME;
+          }
+          break;
+        case PL_UNIX_FILENAME_NAME:
+          parser->item_length++;
+          if(c == '\r') {
+            parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_WINDOWSEOL;
+          }
+          else if(c == '\n') {
+            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+            parser->offsets.filename = parser->item_offset;
+            parser->state.UNIX.main = PL_UNIX_FILETYPE;
+            result = ftp_pl_insert_finfo(conn, infop);
+            if(result) {
+              parser->error = result;
+              goto fail;
+            }
+          }
+          break;
+        case PL_UNIX_FILENAME_WINDOWSEOL:
+          if(c == '\n') {
+            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+            parser->offsets.filename = parser->item_offset;
+            parser->state.UNIX.main = PL_UNIX_FILETYPE;
+            result = ftp_pl_insert_finfo(conn, infop);
+            if(result) {
+              parser->error = result;
+              goto fail;
+            }
+          }
+          else {
+            parser->error = CURLE_FTP_BAD_FILE_LIST;
+            goto fail;
+          }
+          break;
+        }
+        break;
+      case PL_UNIX_SYMLINK:
+        switch(parser->state.UNIX.sub.symlink) {
+        case PL_UNIX_SYMLINK_PRESPACE:
+          if(c != ' ') {
+            parser->item_offset = finfo->b_used - 1;
+            parser->item_length = 1;
+            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME;
+          }
+          break;
+        case PL_UNIX_SYMLINK_NAME:
+          parser->item_length++;
+          if(c == ' ') {
+            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET1;
+          }
+          else if(c == '\r' || c == '\n') {
+            parser->error = CURLE_FTP_BAD_FILE_LIST;
+            goto fail;
+          }
+          break;
+        case PL_UNIX_SYMLINK_PRETARGET1:
+          parser->item_length++;
+          if(c == '-') {
+            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET2;
+          }
+          else if(c == '\r' || c == '\n') {
+            parser->error = CURLE_FTP_BAD_FILE_LIST;
+            goto fail;
+          }
+          else {
+            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME;
+          }
+          break;
+        case PL_UNIX_SYMLINK_PRETARGET2:
+          parser->item_length++;
+          if(c == '>') {
+            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET3;
+          }
+          else if(c == '\r' || c == '\n') {
+            parser->error = CURLE_FTP_BAD_FILE_LIST;
+            goto fail;
+          }
+          else {
+            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME;
+          }
+          break;
+        case PL_UNIX_SYMLINK_PRETARGET3:
+          parser->item_length++;
+          if(c == ' ') {
+            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET4;
+            /* now place where is symlink following */
+            finfo->b_data[parser->item_offset + parser->item_length - 4] = 0;
+            parser->offsets.filename = parser->item_offset;
+            parser->item_length = 0;
+            parser->item_offset = 0;
+          }
+          else if(c == '\r' || c == '\n') {
+            parser->error = CURLE_FTP_BAD_FILE_LIST;
+            goto fail;
+          }
+          else {
+            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME;
+          }
+          break;
+        case PL_UNIX_SYMLINK_PRETARGET4:
+          if(c != '\r' && c != '\n') {
+            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_TARGET;
+            parser->item_offset = finfo->b_used - 1;
+            parser->item_length = 1;
+          }
+          else {
+            parser->error = CURLE_FTP_BAD_FILE_LIST;
+            goto fail;
+          }
+          break;
+        case PL_UNIX_SYMLINK_TARGET:
+          parser->item_length++;
+          if(c == '\r') {
+            parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_WINDOWSEOL;
+          }
+          else if(c == '\n') {
+            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+            parser->offsets.symlink_target = parser->item_offset;
+            result = ftp_pl_insert_finfo(conn, infop);
+            if(result) {
+              parser->error = result;
+              goto fail;
+            }
+            parser->state.UNIX.main = PL_UNIX_FILETYPE;
+          }
+          break;
+        case PL_UNIX_SYMLINK_WINDOWSEOL:
+          if(c == '\n') {
+            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+            parser->offsets.symlink_target = parser->item_offset;
+            result = ftp_pl_insert_finfo(conn, infop);
+            if(result) {
+              parser->error = result;
+              goto fail;
+            }
+            parser->state.UNIX.main = PL_UNIX_FILETYPE;
+          }
+          else {
+            parser->error = CURLE_FTP_BAD_FILE_LIST;
+            goto fail;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    case OS_TYPE_WIN_NT:
+      switch(parser->state.NT.main) {
+      case PL_WINNT_DATE:
+        parser->item_length++;
+        if(parser->item_length < 9) {
+          if(!strchr("0123456789-", c)) { /* only simple control */
+            parser->error = CURLE_FTP_BAD_FILE_LIST;
+            goto fail;
+          }
+        }
+        else if(parser->item_length == 9) {
+          if(c == ' ') {
+            parser->state.NT.main = PL_WINNT_TIME;
+            parser->state.NT.sub.time = PL_WINNT_TIME_PRESPACE;
+          }
+          else {
+            parser->error = CURLE_FTP_BAD_FILE_LIST;
+            goto fail;
+          }
+        }
+        else {
+          parser->error = CURLE_FTP_BAD_FILE_LIST;
+          goto fail;
+        }
+        break;
+      case PL_WINNT_TIME:
+        parser->item_length++;
+        switch(parser->state.NT.sub.time) {
+        case PL_WINNT_TIME_PRESPACE:
+          if(!ISSPACE(c)) {
+            parser->state.NT.sub.time = PL_WINNT_TIME_TIME;
+          }
+          break;
+        case PL_WINNT_TIME_TIME:
+          if(c == ' ') {
+            parser->offsets.time = parser->item_offset;
+            finfo->b_data[parser->item_offset + parser->item_length -1] = 0;
+            parser->state.NT.main = PL_WINNT_DIRORSIZE;
+            parser->state.NT.sub.dirorsize = PL_WINNT_DIRORSIZE_PRESPACE;
+            parser->item_length = 0;
+          }
+          else if(!strchr("APM0123456789:", c)) {
+            parser->error = CURLE_FTP_BAD_FILE_LIST;
+            goto fail;
+          }
+          break;
+        }
+        break;
+      case PL_WINNT_DIRORSIZE:
+        switch(parser->state.NT.sub.dirorsize) {
+        case PL_WINNT_DIRORSIZE_PRESPACE:
+          if(c == ' ') {
+
+          }
+          else {
+            parser->item_offset = finfo->b_used - 1;
+            parser->item_length = 1;
+            parser->state.NT.sub.dirorsize = PL_WINNT_DIRORSIZE_CONTENT;
+          }
+          break;
+        case PL_WINNT_DIRORSIZE_CONTENT:
+          parser->item_length ++;
+          if(c == ' ') {
+            finfo->b_data[parser->item_offset + parser->item_length - 1] = 0;
+            if(strcmp("<DIR>", finfo->b_data + parser->item_offset) == 0) {
+              finfo->filetype = CURLFILETYPE_DIRECTORY;
+              finfo->size = 0;
+            }
+            else {
+              char *endptr;
+              if(curlx_strtoofft(finfo->b_data +
+                                 parser->item_offset,
+                                 &endptr, 10, &finfo->size)) {
+                parser->error = CURLE_FTP_BAD_FILE_LIST;
+                goto fail;
+              }
+              /* correct file type */
+              parser->file_data->info.filetype = CURLFILETYPE_FILE;
+            }
+
+            parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_SIZE;
+            parser->item_length = 0;
+            parser->state.NT.main = PL_WINNT_FILENAME;
+            parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE;
+          }
+          break;
+        }
+        break;
+      case PL_WINNT_FILENAME:
+        switch(parser->state.NT.sub.filename) {
+        case PL_WINNT_FILENAME_PRESPACE:
+          if(c != ' ') {
+            parser->item_offset = finfo->b_used -1;
+            parser->item_length = 1;
+            parser->state.NT.sub.filename = PL_WINNT_FILENAME_CONTENT;
+          }
+          break;
+        case PL_WINNT_FILENAME_CONTENT:
+          parser->item_length++;
+          if(c == '\r') {
+            parser->state.NT.sub.filename = PL_WINNT_FILENAME_WINEOL;
+            finfo->b_data[finfo->b_used - 1] = 0;
+          }
+          else if(c == '\n') {
+            parser->offsets.filename = parser->item_offset;
+            finfo->b_data[finfo->b_used - 1] = 0;
+            parser->offsets.filename = parser->item_offset;
+            result = ftp_pl_insert_finfo(conn, infop);
+            if(result) {
+              parser->error = result;
+              goto fail;
+            }
+            parser->state.NT.main = PL_WINNT_DATE;
+            parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE;
+          }
+          break;
+        case PL_WINNT_FILENAME_WINEOL:
+          if(c == '\n') {
+            parser->offsets.filename = parser->item_offset;
+            result = ftp_pl_insert_finfo(conn, infop);
+            if(result) {
+              parser->error = result;
+              goto fail;
+            }
+            parser->state.NT.main = PL_WINNT_DATE;
+            parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE;
+          }
+          else {
+            parser->error = CURLE_FTP_BAD_FILE_LIST;
+            goto fail;
+          }
+          break;
+        }
+        break;
+      }
+      break;
+    default:
+      retsize = bufflen + 1;
+      goto fail;
+    }
+
+    i++;
+  }
+
+fail:
+
+  /* Clean up any allocated memory. */
+  if(parser->file_data) {
+    Curl_fileinfo_dtor(NULL, parser->file_data);
+    parser->file_data = NULL;
+  }
+
+  return retsize;
+}
+
+#endif /* CURL_DISABLE_FTP */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/ftplistparser.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/ftplistparser.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/ftplistparser.h	(revision 331)
@@ -0,0 +1,41 @@
+#ifndef HEADER_CURL_FTPLISTPARSER_H
+#define HEADER_CURL_FTPLISTPARSER_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_FTP
+
+/* WRITEFUNCTION callback for parsing LIST responses */
+size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
+                          void *connptr);
+
+struct ftp_parselist_data; /* defined inside ftplibparser.c */
+
+CURLcode Curl_ftp_parselist_geterror(struct ftp_parselist_data *pl_data);
+
+struct ftp_parselist_data *Curl_ftp_parselist_data_alloc(void);
+
+void Curl_ftp_parselist_data_free(struct ftp_parselist_data **pl_data);
+
+#endif /* CURL_DISABLE_FTP */
+#endif /* HEADER_CURL_FTPLISTPARSER_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/getenv.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/getenv.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/getenv.c	(revision 331)
@@ -0,0 +1,54 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+#include "curl_memory.h"
+
+#include "memdebug.h"
+
+static
+char *GetEnv(const char *variable)
+{
+#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP)
+  (void)variable;
+  return NULL;
+#else
+#ifdef WIN32
+  char env[MAX_PATH]; /* MAX_PATH is from windef.h */
+  char *temp = getenv(variable);
+  env[0] = '\0';
+  if(temp != NULL)
+    ExpandEnvironmentStringsA(temp, env, sizeof(env));
+  return (env[0] != '\0')?strdup(env):NULL;
+#else
+  char *env = getenv(variable);
+  return (env && env[0])?strdup(env):NULL;
+#endif
+#endif
+}
+
+char *curl_getenv(const char *v)
+{
+  return GetEnv(v);
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/getinfo.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/getinfo.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/getinfo.c	(revision 331)
@@ -0,0 +1,461 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "getinfo.h"
+
+#include "vtls/vtls.h"
+#include "connect.h" /* Curl_getconnectinfo() */
+#include "progress.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * Initialize statistical and informational data.
+ *
+ * This function is called in curl_easy_reset, curl_easy_duphandle and at the
+ * beginning of a perform session. It must reset the session-info variables,
+ * in particular all variables in struct PureInfo.
+ */
+CURLcode Curl_initinfo(struct Curl_easy *data)
+{
+  struct Progress *pro = &data->progress;
+  struct PureInfo *info = &data->info;
+
+  pro->t_nslookup = 0;
+  pro->t_connect = 0;
+  pro->t_appconnect = 0;
+  pro->t_pretransfer = 0;
+  pro->t_starttransfer = 0;
+  pro->timespent = 0;
+  pro->t_redirect = 0;
+  pro->is_t_startransfer_set = false;
+
+  info->httpcode = 0;
+  info->httpproxycode = 0;
+  info->httpversion = 0;
+  info->filetime = -1; /* -1 is an illegal time and thus means unknown */
+  info->timecond = FALSE;
+
+  info->header_size = 0;
+  info->request_size = 0;
+  info->proxyauthavail = 0;
+  info->httpauthavail = 0;
+  info->numconnects = 0;
+
+  free(info->contenttype);
+  info->contenttype = NULL;
+
+  free(info->wouldredirect);
+  info->wouldredirect = NULL;
+
+  info->conn_primary_ip[0] = '\0';
+  info->conn_local_ip[0] = '\0';
+  info->conn_primary_port = 0;
+  info->conn_local_port = 0;
+
+  info->conn_scheme = 0;
+  info->conn_protocol = 0;
+
+#ifdef USE_SSL
+  Curl_ssl_free_certinfo(data);
+#endif
+
+  return CURLE_OK;
+}
+
+static CURLcode getinfo_char(struct Curl_easy *data, CURLINFO info,
+                             const char **param_charp)
+{
+  switch(info) {
+  case CURLINFO_EFFECTIVE_URL:
+    *param_charp = data->change.url?data->change.url:(char *)"";
+    break;
+  case CURLINFO_CONTENT_TYPE:
+    *param_charp = data->info.contenttype;
+    break;
+  case CURLINFO_PRIVATE:
+    *param_charp = (char *) data->set.private_data;
+    break;
+  case CURLINFO_FTP_ENTRY_PATH:
+    /* Return the entrypath string from the most recent connection.
+       This pointer was copied from the connectdata structure by FTP.
+       The actual string may be free()ed by subsequent libcurl calls so
+       it must be copied to a safer area before the next libcurl call.
+       Callers must never free it themselves. */
+    *param_charp = data->state.most_recent_ftp_entrypath;
+    break;
+  case CURLINFO_REDIRECT_URL:
+    /* Return the URL this request would have been redirected to if that
+       option had been enabled! */
+    *param_charp = data->info.wouldredirect;
+    break;
+  case CURLINFO_PRIMARY_IP:
+    /* Return the ip address of the most recent (primary) connection */
+    *param_charp = data->info.conn_primary_ip;
+    break;
+  case CURLINFO_LOCAL_IP:
+    /* Return the source/local ip address of the most recent (primary)
+       connection */
+    *param_charp = data->info.conn_local_ip;
+    break;
+  case CURLINFO_RTSP_SESSION_ID:
+    *param_charp = data->set.str[STRING_RTSP_SESSION_ID];
+    break;
+  case CURLINFO_SCHEME:
+    *param_charp = data->info.conn_scheme;
+    break;
+
+  default:
+    return CURLE_UNKNOWN_OPTION;
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
+                             long *param_longp)
+{
+  curl_socket_t sockfd;
+
+  union {
+    unsigned long *to_ulong;
+    long          *to_long;
+  } lptr;
+
+  switch(info) {
+  case CURLINFO_RESPONSE_CODE:
+    *param_longp = data->info.httpcode;
+    break;
+  case CURLINFO_HTTP_CONNECTCODE:
+    *param_longp = data->info.httpproxycode;
+    break;
+  case CURLINFO_FILETIME:
+    *param_longp = data->info.filetime;
+    break;
+  case CURLINFO_HEADER_SIZE:
+    *param_longp = data->info.header_size;
+    break;
+  case CURLINFO_REQUEST_SIZE:
+    *param_longp = data->info.request_size;
+    break;
+  case CURLINFO_SSL_VERIFYRESULT:
+    *param_longp = data->set.ssl.certverifyresult;
+    break;
+  case CURLINFO_PROXY_SSL_VERIFYRESULT:
+    *param_longp = data->set.proxy_ssl.certverifyresult;
+    break;
+  case CURLINFO_REDIRECT_COUNT:
+    *param_longp = data->set.followlocation;
+    break;
+  case CURLINFO_HTTPAUTH_AVAIL:
+    lptr.to_long = param_longp;
+    *lptr.to_ulong = data->info.httpauthavail;
+    break;
+  case CURLINFO_PROXYAUTH_AVAIL:
+    lptr.to_long = param_longp;
+    *lptr.to_ulong = data->info.proxyauthavail;
+    break;
+  case CURLINFO_OS_ERRNO:
+    *param_longp = data->state.os_errno;
+    break;
+  case CURLINFO_NUM_CONNECTS:
+    *param_longp = data->info.numconnects;
+    break;
+  case CURLINFO_LASTSOCKET:
+    sockfd = Curl_getconnectinfo(data, NULL);
+
+    /* note: this is not a good conversion for systems with 64 bit sockets and
+       32 bit longs */
+    if(sockfd != CURL_SOCKET_BAD)
+      *param_longp = (long)sockfd;
+    else
+      /* this interface is documented to return -1 in case of badness, which
+         may not be the same as the CURL_SOCKET_BAD value */
+      *param_longp = -1;
+    break;
+  case CURLINFO_PRIMARY_PORT:
+    /* Return the (remote) port of the most recent (primary) connection */
+    *param_longp = data->info.conn_primary_port;
+    break;
+  case CURLINFO_LOCAL_PORT:
+    /* Return the local port of the most recent (primary) connection */
+    *param_longp = data->info.conn_local_port;
+    break;
+  case CURLINFO_CONDITION_UNMET:
+    /* return if the condition prevented the document to get transferred */
+    *param_longp = data->info.timecond ? 1L : 0L;
+    break;
+  case CURLINFO_RTSP_CLIENT_CSEQ:
+    *param_longp = data->state.rtsp_next_client_CSeq;
+    break;
+  case CURLINFO_RTSP_SERVER_CSEQ:
+    *param_longp = data->state.rtsp_next_server_CSeq;
+    break;
+  case CURLINFO_RTSP_CSEQ_RECV:
+    *param_longp = data->state.rtsp_CSeq_recv;
+    break;
+  case CURLINFO_HTTP_VERSION:
+    switch(data->info.httpversion) {
+    case 10:
+      *param_longp = CURL_HTTP_VERSION_1_0;
+      break;
+    case 11:
+      *param_longp = CURL_HTTP_VERSION_1_1;
+      break;
+    case 20:
+      *param_longp = CURL_HTTP_VERSION_2_0;
+      break;
+    default:
+      *param_longp = CURL_HTTP_VERSION_NONE;
+      break;
+    }
+    break;
+  case CURLINFO_PROTOCOL:
+    *param_longp = data->info.conn_protocol;
+    break;
+
+  default:
+    return CURLE_UNKNOWN_OPTION;
+  }
+
+  return CURLE_OK;
+}
+
+#define DOUBLE_SECS(x) (double)(x)/1000000
+
+static CURLcode getinfo_offt(struct Curl_easy *data, CURLINFO info,
+                             curl_off_t *param_offt)
+{
+  switch(info) {
+  case CURLINFO_SIZE_UPLOAD_T:
+    *param_offt = data->progress.uploaded;
+    break;
+  case CURLINFO_SIZE_DOWNLOAD_T:
+    *param_offt = data->progress.downloaded;
+    break;
+  case CURLINFO_SPEED_DOWNLOAD_T:
+    *param_offt =  data->progress.dlspeed;
+    break;
+  case CURLINFO_SPEED_UPLOAD_T:
+    *param_offt = data->progress.ulspeed;
+    break;
+  case CURLINFO_CONTENT_LENGTH_DOWNLOAD_T:
+    *param_offt = (data->progress.flags & PGRS_DL_SIZE_KNOWN)?
+      data->progress.size_dl:-1;
+    break;
+  case CURLINFO_CONTENT_LENGTH_UPLOAD_T:
+    *param_offt = (data->progress.flags & PGRS_UL_SIZE_KNOWN)?
+      data->progress.size_ul:-1;
+    break;
+  default:
+    return CURLE_UNKNOWN_OPTION;
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode getinfo_double(struct Curl_easy *data, CURLINFO info,
+                               double *param_doublep)
+{
+  switch(info) {
+  case CURLINFO_TOTAL_TIME:
+    *param_doublep = DOUBLE_SECS(data->progress.timespent);
+    break;
+  case CURLINFO_NAMELOOKUP_TIME:
+    *param_doublep = DOUBLE_SECS(data->progress.t_nslookup);
+    break;
+  case CURLINFO_CONNECT_TIME:
+    *param_doublep = DOUBLE_SECS(data->progress.t_connect);
+    break;
+  case CURLINFO_APPCONNECT_TIME:
+    *param_doublep = DOUBLE_SECS(data->progress.t_appconnect);
+    break;
+  case CURLINFO_PRETRANSFER_TIME:
+    *param_doublep = DOUBLE_SECS(data->progress.t_pretransfer);
+    break;
+  case CURLINFO_STARTTRANSFER_TIME:
+    *param_doublep = DOUBLE_SECS(data->progress.t_starttransfer);
+    break;
+  case CURLINFO_SIZE_UPLOAD:
+    *param_doublep =  (double)data->progress.uploaded;
+    break;
+  case CURLINFO_SIZE_DOWNLOAD:
+    *param_doublep = (double)data->progress.downloaded;
+    break;
+  case CURLINFO_SPEED_DOWNLOAD:
+    *param_doublep =  (double)data->progress.dlspeed;
+    break;
+  case CURLINFO_SPEED_UPLOAD:
+    *param_doublep = (double)data->progress.ulspeed;
+    break;
+  case CURLINFO_CONTENT_LENGTH_DOWNLOAD:
+    *param_doublep = (data->progress.flags & PGRS_DL_SIZE_KNOWN)?
+      (double)data->progress.size_dl:-1;
+    break;
+  case CURLINFO_CONTENT_LENGTH_UPLOAD:
+    *param_doublep = (data->progress.flags & PGRS_UL_SIZE_KNOWN)?
+      (double)data->progress.size_ul:-1;
+    break;
+  case CURLINFO_REDIRECT_TIME:
+    *param_doublep = DOUBLE_SECS(data->progress.t_redirect);
+    break;
+
+  default:
+    return CURLE_UNKNOWN_OPTION;
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode getinfo_slist(struct Curl_easy *data, CURLINFO info,
+                              struct curl_slist **param_slistp)
+{
+  union {
+    struct curl_certinfo *to_certinfo;
+    struct curl_slist    *to_slist;
+  } ptr;
+
+  switch(info) {
+  case CURLINFO_SSL_ENGINES:
+    *param_slistp = Curl_ssl_engines_list(data);
+    break;
+  case CURLINFO_COOKIELIST:
+    *param_slistp = Curl_cookie_list(data);
+    break;
+  case CURLINFO_CERTINFO:
+    /* Return the a pointer to the certinfo struct. Not really an slist
+       pointer but we can pretend it is here */
+    ptr.to_certinfo = &data->info.certs;
+    *param_slistp = ptr.to_slist;
+    break;
+  case CURLINFO_TLS_SESSION:
+  case CURLINFO_TLS_SSL_PTR:
+    {
+      struct curl_tlssessioninfo **tsip = (struct curl_tlssessioninfo **)
+                                          param_slistp;
+      struct curl_tlssessioninfo *tsi = &data->tsi;
+#ifdef USE_SSL
+      struct connectdata *conn = data->easy_conn;
+#endif
+
+      *tsip = tsi;
+      tsi->backend = Curl_ssl_backend();
+      tsi->internals = NULL;
+
+#ifdef USE_SSL
+      if(conn && tsi->backend != CURLSSLBACKEND_NONE) {
+        unsigned int i;
+        for(i = 0; i < (sizeof(conn->ssl) / sizeof(conn->ssl[0])); ++i) {
+          if(conn->ssl[i].use) {
+            tsi->internals = Curl_ssl->get_internals(&conn->ssl[i], info);
+            break;
+          }
+        }
+      }
+#endif
+    }
+    break;
+  default:
+    return CURLE_UNKNOWN_OPTION;
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode getinfo_socket(struct Curl_easy *data, CURLINFO info,
+                               curl_socket_t *param_socketp)
+{
+  switch(info) {
+  case CURLINFO_ACTIVESOCKET:
+    *param_socketp = Curl_getconnectinfo(data, NULL);
+    break;
+  default:
+    return CURLE_UNKNOWN_OPTION;
+  }
+
+  return CURLE_OK;
+}
+
+CURLcode Curl_getinfo(struct Curl_easy *data, CURLINFO info, ...)
+{
+  va_list arg;
+  long *param_longp = NULL;
+  double *param_doublep = NULL;
+  curl_off_t *param_offt = NULL;
+  const char **param_charp = NULL;
+  struct curl_slist **param_slistp = NULL;
+  curl_socket_t *param_socketp = NULL;
+  int type;
+  CURLcode result = CURLE_UNKNOWN_OPTION;
+
+  if(!data)
+    return result;
+
+  va_start(arg, info);
+
+  type = CURLINFO_TYPEMASK & (int)info;
+  switch(type) {
+  case CURLINFO_STRING:
+    param_charp = va_arg(arg, const char **);
+    if(param_charp)
+      result = getinfo_char(data, info, param_charp);
+    break;
+  case CURLINFO_LONG:
+    param_longp = va_arg(arg, long *);
+    if(param_longp)
+      result = getinfo_long(data, info, param_longp);
+    break;
+  case CURLINFO_DOUBLE:
+    param_doublep = va_arg(arg, double *);
+    if(param_doublep)
+      result = getinfo_double(data, info, param_doublep);
+    break;
+  case CURLINFO_OFF_T:
+    param_offt = va_arg(arg, curl_off_t *);
+    if(param_offt)
+      result = getinfo_offt(data, info, param_offt);
+    break;
+  case CURLINFO_SLIST:
+    param_slistp = va_arg(arg, struct curl_slist **);
+    if(param_slistp)
+      result = getinfo_slist(data, info, param_slistp);
+    break;
+  case CURLINFO_SOCKET:
+    param_socketp = va_arg(arg, curl_socket_t *);
+    if(param_socketp)
+      result = getinfo_socket(data, info, param_socketp);
+    break;
+  default:
+    break;
+  }
+
+  va_end(arg);
+
+  return result;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/getinfo.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/getinfo.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/getinfo.h	(revision 331)
@@ -0,0 +1,27 @@
+#ifndef HEADER_CURL_GETINFO_H
+#define HEADER_CURL_GETINFO_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+CURLcode Curl_getinfo(struct Curl_easy *data, CURLINFO info, ...);
+CURLcode Curl_initinfo(struct Curl_easy *data);
+
+#endif /* HEADER_CURL_GETINFO_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/gopher.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/gopher.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/gopher.c	(revision 331)
@@ -0,0 +1,167 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_GOPHER
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "sendf.h"
+#include "progress.h"
+#include "gopher.h"
+#include "select.h"
+#include "url.h"
+#include "escape.h"
+#include "warnless.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Forward declarations.
+ */
+
+static CURLcode gopher_do(struct connectdata *conn, bool *done);
+
+/*
+ * Gopher protocol handler.
+ * This is also a nice simple template to build off for simple
+ * connect-command-download protocols.
+ */
+
+const struct Curl_handler Curl_handler_gopher = {
+  "GOPHER",                             /* scheme */
+  ZERO_NULL,                            /* setup_connection */
+  gopher_do,                            /* do_it */
+  ZERO_NULL,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_GOPHER,                          /* defport */
+  CURLPROTO_GOPHER,                     /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+
+static CURLcode gopher_do(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+
+  curl_off_t *bytecount = &data->req.bytecount;
+  char *path = data->state.path;
+  char *sel = NULL;
+  char *sel_org = NULL;
+  ssize_t amount, k;
+  size_t len;
+
+  *done = TRUE; /* unconditionally */
+
+  /* Create selector. Degenerate cases: / and /1 => convert to "" */
+  if(strlen(path) <= 2) {
+    sel = (char *)"";
+    len = (int)strlen(sel);
+  }
+  else {
+    char *newp;
+    size_t j, i;
+
+    /* Otherwise, drop / and the first character (i.e., item type) ... */
+    newp = path;
+    newp += 2;
+
+    /* ... then turn ? into TAB for search servers, Veronica, etc. ... */
+    j = strlen(newp);
+    for(i = 0; i<j; i++)
+      if(newp[i] == '?')
+        newp[i] = '\x09';
+
+    /* ... and finally unescape */
+    result = Curl_urldecode(data, newp, 0, &sel, &len, FALSE);
+    if(result)
+      return result;
+    sel_org = sel;
+  }
+
+  /* We use Curl_write instead of Curl_sendf to make sure the entire buffer is
+     sent, which could be sizeable with long selectors. */
+  k = curlx_uztosz(len);
+
+  for(;;) {
+    result = Curl_write(conn, sockfd, sel, k, &amount);
+    if(!result) { /* Which may not have written it all! */
+      result = Curl_client_write(conn, CLIENTWRITE_HEADER, sel, amount);
+      if(result)
+        break;
+
+      k -= amount;
+      sel += amount;
+      if(k < 1)
+        break; /* but it did write it all */
+    }
+    else
+      break;
+
+    /* Don't busyloop. The entire loop thing is a work-around as it causes a
+       BLOCKING behavior which is a NO-NO. This function should rather be
+       split up in a do and a doing piece where the pieces that aren't
+       possible to send now will be sent in the doing function repeatedly
+       until the entire request is sent.
+
+       Wait a while for the socket to be writable. Note that this doesn't
+       acknowledge the timeout.
+    */
+    if(SOCKET_WRITABLE(sockfd, 100) < 0) {
+      result = CURLE_SEND_ERROR;
+      break;
+    }
+  }
+
+  free(sel_org);
+
+  if(!result)
+    /* We can use Curl_sendf to send the terminal \r\n relatively safely and
+       save allocing another string/doing another _write loop. */
+    result = Curl_sendf(sockfd, conn, "\r\n");
+  if(result) {
+    failf(data, "Failed sending Gopher request");
+    return result;
+  }
+  result = Curl_client_write(conn, CLIENTWRITE_HEADER, (char *)"\r\n", 2);
+  if(result)
+    return result;
+
+  Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
+                      -1, NULL); /* no upload */
+  return CURLE_OK;
+}
+#endif /*CURL_DISABLE_GOPHER*/
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/gopher.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/gopher.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/gopher.h	(revision 331)
@@ -0,0 +1,29 @@
+#ifndef HEADER_CURL_GOPHER_H
+#define HEADER_CURL_GOPHER_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifndef CURL_DISABLE_GOPHER
+extern const struct Curl_handler Curl_handler_gopher;
+#endif
+
+#endif /* HEADER_CURL_GOPHER_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/hash.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/hash.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/hash.c	(revision 331)
@@ -0,0 +1,354 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "hash.h"
+#include "llist.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+static void
+hash_element_dtor(void *user, void *element)
+{
+  struct curl_hash *h = (struct curl_hash *) user;
+  struct curl_hash_element *e = (struct curl_hash_element *) element;
+
+  if(e->ptr) {
+    h->dtor(e->ptr);
+    e->ptr = NULL;
+  }
+
+  e->key_len = 0;
+
+  free(e);
+}
+
+/* Initializes a hash structure.
+ * Return 1 on error, 0 is fine.
+ *
+ * @unittest: 1602
+ * @unittest: 1603
+ */
+int
+Curl_hash_init(struct curl_hash *h,
+               int slots,
+               hash_function hfunc,
+               comp_function comparator,
+               curl_hash_dtor dtor)
+{
+  int i;
+
+  if(!slots || !hfunc || !comparator ||!dtor) {
+    return 1; /* failure */
+  }
+
+  h->hash_func = hfunc;
+  h->comp_func = comparator;
+  h->dtor = dtor;
+  h->size = 0;
+  h->slots = slots;
+
+  h->table = malloc(slots * sizeof(struct curl_llist));
+  if(h->table) {
+    for(i = 0; i < slots; ++i)
+      Curl_llist_init(&h->table[i], (curl_llist_dtor) hash_element_dtor);
+    return 0; /* fine */
+  }
+  h->slots = 0;
+  return 1; /* failure */
+}
+
+static struct curl_hash_element *
+mk_hash_element(const void *key, size_t key_len, const void *p)
+{
+  /* allocate the struct plus memory after it to store the key */
+  struct curl_hash_element *he = malloc(sizeof(struct curl_hash_element) +
+                                        key_len);
+  if(he) {
+    /* copy the key */
+    memcpy(he->key, key, key_len);
+    he->key_len = key_len;
+    he->ptr = (void *) p;
+  }
+  return he;
+}
+
+#define FETCH_LIST(x,y,z) &x->table[x->hash_func(y, z, x->slots)]
+
+/* Insert the data in the hash. If there already was a match in the hash,
+ * that data is replaced.
+ *
+ * @unittest: 1305
+ * @unittest: 1602
+ * @unittest: 1603
+ */
+void *
+Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p)
+{
+  struct curl_hash_element  *he;
+  struct curl_llist_element *le;
+  struct curl_llist *l = FETCH_LIST(h, key, key_len);
+
+  for(le = l->head; le; le = le->next) {
+    he = (struct curl_hash_element *) le->ptr;
+    if(h->comp_func(he->key, he->key_len, key, key_len)) {
+      Curl_llist_remove(l, le, (void *)h);
+      --h->size;
+      break;
+    }
+  }
+
+  he = mk_hash_element(key, key_len, p);
+  if(he) {
+    Curl_llist_insert_next(l, l->tail, he, &he->list);
+    ++h->size;
+    return p; /* return the new entry */
+  }
+
+  return NULL; /* failure */
+}
+
+/* Remove the identified hash entry.
+ * Returns non-zero on failure.
+ *
+ * @unittest: 1603
+ */
+int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len)
+{
+  struct curl_llist_element *le;
+  struct curl_hash_element  *he;
+  struct curl_llist *l = FETCH_LIST(h, key, key_len);
+
+  for(le = l->head; le; le = le->next) {
+    he = le->ptr;
+    if(h->comp_func(he->key, he->key_len, key, key_len)) {
+      Curl_llist_remove(l, le, (void *) h);
+      --h->size;
+      return 0;
+    }
+  }
+  return 1;
+}
+
+/* Retrieves a hash element.
+ *
+ * @unittest: 1603
+ */
+void *
+Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len)
+{
+  struct curl_llist_element *le;
+  struct curl_hash_element  *he;
+  struct curl_llist *l;
+
+  if(h) {
+    l = FETCH_LIST(h, key, key_len);
+    for(le = l->head; le; le = le->next) {
+      he = le->ptr;
+      if(h->comp_func(he->key, he->key_len, key, key_len)) {
+        return he->ptr;
+      }
+    }
+  }
+
+  return NULL;
+}
+
+#if defined(DEBUGBUILD) && defined(AGGRESIVE_TEST)
+void
+Curl_hash_apply(curl_hash *h, void *user,
+                void (*cb)(void *user, void *ptr))
+{
+  struct curl_llist_element  *le;
+  int                  i;
+
+  for(i = 0; i < h->slots; ++i) {
+    for(le = (h->table[i])->head;
+        le;
+        le = le->next) {
+      curl_hash_element *el = le->ptr;
+      cb(user, el->ptr);
+    }
+  }
+}
+#endif
+
+/* Destroys all the entries in the given hash and resets its attributes,
+ * prepping the given hash for [static|dynamic] deallocation.
+ *
+ * @unittest: 1305
+ * @unittest: 1602
+ * @unittest: 1603
+ */
+void
+Curl_hash_destroy(struct curl_hash *h)
+{
+  int i;
+
+  for(i = 0; i < h->slots; ++i) {
+    Curl_llist_destroy(&h->table[i], (void *) h);
+  }
+
+  Curl_safefree(h->table);
+  h->size = 0;
+  h->slots = 0;
+}
+
+/* Removes all the entries in the given hash.
+ *
+ * @unittest: 1602
+ */
+void
+Curl_hash_clean(struct curl_hash *h)
+{
+  Curl_hash_clean_with_criterium(h, NULL, NULL);
+}
+
+/* Cleans all entries that pass the comp function criteria. */
+void
+Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
+                               int (*comp)(void *, void *))
+{
+  struct curl_llist_element *le;
+  struct curl_llist_element *lnext;
+  struct curl_llist *list;
+  int i;
+
+  if(!h)
+    return;
+
+  for(i = 0; i < h->slots; ++i) {
+    list = &h->table[i];
+    le = list->head; /* get first list entry */
+    while(le) {
+      struct curl_hash_element *he = le->ptr;
+      lnext = le->next;
+      /* ask the callback function if we shall remove this entry or not */
+      if(comp == NULL || comp(user, he->ptr)) {
+        Curl_llist_remove(list, le, (void *) h);
+        --h->size; /* one less entry in the hash now */
+      }
+      le = lnext;
+    }
+  }
+}
+
+size_t Curl_hash_str(void *key, size_t key_length, size_t slots_num)
+{
+  const char *key_str = (const char *) key;
+  const char *end = key_str + key_length;
+  unsigned long h = 5381;
+
+  while(key_str < end) {
+    h += h << 5;
+    h ^= (unsigned long) *key_str++;
+  }
+
+  return (h % slots_num);
+}
+
+size_t Curl_str_key_compare(void *k1, size_t key1_len,
+                            void *k2, size_t key2_len)
+{
+  if((key1_len == key2_len) && !memcmp(k1, k2, key1_len))
+    return 1;
+
+  return 0;
+}
+
+void Curl_hash_start_iterate(struct curl_hash *hash,
+                             struct curl_hash_iterator *iter)
+{
+  iter->hash = hash;
+  iter->slot_index = 0;
+  iter->current_element = NULL;
+}
+
+struct curl_hash_element *
+Curl_hash_next_element(struct curl_hash_iterator *iter)
+{
+  int i;
+  struct curl_hash *h = iter->hash;
+
+  /* Get the next element in the current list, if any */
+  if(iter->current_element)
+    iter->current_element = iter->current_element->next;
+
+  /* If we have reached the end of the list, find the next one */
+  if(!iter->current_element) {
+    for(i = iter->slot_index;i < h->slots;i++) {
+      if(h->table[i].head) {
+        iter->current_element = h->table[i].head;
+        iter->slot_index = i+1;
+        break;
+      }
+    }
+  }
+
+  if(iter->current_element) {
+    struct curl_hash_element *he = iter->current_element->ptr;
+    return he;
+  }
+  iter->current_element = NULL;
+  return NULL;
+}
+
+#if 0 /* useful function for debugging hashes and their contents */
+void Curl_hash_print(struct curl_hash *h,
+                     void (*func)(void *))
+{
+  struct curl_hash_iterator iter;
+  struct curl_hash_element *he;
+  int last_index = -1;
+
+  if(!h)
+    return;
+
+  fprintf(stderr, "=Hash dump=\n");
+
+  Curl_hash_start_iterate(h, &iter);
+
+  he = Curl_hash_next_element(&iter);
+  while(he) {
+    if(iter.slot_index != last_index) {
+      fprintf(stderr, "index %d:", iter.slot_index);
+      if(last_index >= 0) {
+        fprintf(stderr, "\n");
+      }
+      last_index = iter.slot_index;
+    }
+
+    if(func)
+      func(he->ptr);
+    else
+      fprintf(stderr, " [%p]", (void *)he->ptr);
+
+    he = Curl_hash_next_element(&iter);
+  }
+  fprintf(stderr, "\n");
+}
+#endif
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/hash.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/hash.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/hash.h	(revision 331)
@@ -0,0 +1,100 @@
+#ifndef HEADER_CURL_HASH_H
+#define HEADER_CURL_HASH_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <stddef.h>
+
+#include "llist.h"
+
+/* Hash function prototype */
+typedef size_t (*hash_function) (void *key,
+                                 size_t key_length,
+                                 size_t slots_num);
+
+/*
+   Comparator function prototype. Compares two keys.
+*/
+typedef size_t (*comp_function) (void *key1,
+                                 size_t key1_len,
+                                 void *key2,
+                                 size_t key2_len);
+
+typedef void (*curl_hash_dtor)(void *);
+
+struct curl_hash {
+  struct curl_llist *table;
+
+  /* Hash function to be used for this hash table */
+  hash_function hash_func;
+
+  /* Comparator function to compare keys */
+  comp_function comp_func;
+  curl_hash_dtor   dtor;
+  int slots;
+  size_t size;
+};
+
+struct curl_hash_element {
+  struct curl_llist_element list;
+  void   *ptr;
+  size_t key_len;
+  char   key[1]; /* allocated memory following the struct */
+};
+
+struct curl_hash_iterator {
+  struct curl_hash *hash;
+  int slot_index;
+  struct curl_llist_element *current_element;
+};
+
+int Curl_hash_init(struct curl_hash *h,
+                   int slots,
+                   hash_function hfunc,
+                   comp_function comparator,
+                   curl_hash_dtor dtor);
+
+void *Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p);
+int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len);
+void *Curl_hash_pick(struct curl_hash *, void *key, size_t key_len);
+void Curl_hash_apply(struct curl_hash *h, void *user,
+                     void (*cb)(void *user, void *ptr));
+int Curl_hash_count(struct curl_hash *h);
+void Curl_hash_destroy(struct curl_hash *h);
+void Curl_hash_clean(struct curl_hash *h);
+void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
+                                    int (*comp)(void *, void *));
+size_t Curl_hash_str(void *key, size_t key_length, size_t slots_num);
+size_t Curl_str_key_compare(void *k1, size_t key1_len, void *k2,
+                            size_t key2_len);
+void Curl_hash_start_iterate(struct curl_hash *hash,
+                             struct curl_hash_iterator *iter);
+struct curl_hash_element *
+Curl_hash_next_element(struct curl_hash_iterator *iter);
+
+void Curl_hash_print(struct curl_hash *h,
+                     void (*func)(void *));
+
+
+#endif /* HEADER_CURL_HASH_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/hmac.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/hmac.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/hmac.c	(revision 331)
@@ -0,0 +1,132 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC2104 Keyed-Hashing for Message Authentication
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+
+#include <curl/curl.h>
+
+#include "curl_hmac.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Generic HMAC algorithm.
+ *
+ *   This module computes HMAC digests based on any hash function. Parameters
+ * and computing procedures are set-up dynamically at HMAC computation
+ * context initialisation.
+ */
+
+static const unsigned char hmac_ipad = 0x36;
+static const unsigned char hmac_opad = 0x5C;
+
+
+
+HMAC_context *
+Curl_HMAC_init(const HMAC_params * hashparams,
+               const unsigned char *key,
+               unsigned int keylen)
+{
+  size_t i;
+  HMAC_context *ctxt;
+  unsigned char *hkey;
+  unsigned char b;
+
+  /* Create HMAC context. */
+  i = sizeof *ctxt + 2 * hashparams->hmac_ctxtsize +
+    hashparams->hmac_resultlen;
+  ctxt = malloc(i);
+
+  if(!ctxt)
+    return ctxt;
+
+  ctxt->hmac_hash = hashparams;
+  ctxt->hmac_hashctxt1 = (void *) (ctxt + 1);
+  ctxt->hmac_hashctxt2 = (void *) ((char *) ctxt->hmac_hashctxt1 +
+      hashparams->hmac_ctxtsize);
+
+  /* If the key is too long, replace it by its hash digest. */
+  if(keylen > hashparams->hmac_maxkeylen) {
+    (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt1);
+    (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, key, keylen);
+    hkey = (unsigned char *) ctxt->hmac_hashctxt2 + hashparams->hmac_ctxtsize;
+    (*hashparams->hmac_hfinal)(hkey, ctxt->hmac_hashctxt1);
+    key = hkey;
+    keylen = hashparams->hmac_resultlen;
+  }
+
+  /* Prime the two hash contexts with the modified key. */
+  (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt1);
+  (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt2);
+
+  for(i = 0; i < keylen; i++) {
+    b = (unsigned char)(*key ^ hmac_ipad);
+    (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, &b, 1);
+    b = (unsigned char)(*key++ ^ hmac_opad);
+    (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2, &b, 1);
+  }
+
+  for(; i < hashparams->hmac_maxkeylen; i++) {
+    (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, &hmac_ipad, 1);
+    (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2, &hmac_opad, 1);
+  }
+
+  /* Done, return pointer to HMAC context. */
+  return ctxt;
+}
+
+int Curl_HMAC_update(HMAC_context * ctxt,
+                     const unsigned char *data,
+                     unsigned int len)
+{
+  /* Update first hash calculation. */
+  (*ctxt->hmac_hash->hmac_hupdate)(ctxt->hmac_hashctxt1, data, len);
+  return 0;
+}
+
+
+int Curl_HMAC_final(HMAC_context *ctxt, unsigned char *result)
+{
+  const HMAC_params * hashparams = ctxt->hmac_hash;
+
+  /* Do not get result if called with a null parameter: only release
+     storage. */
+
+  if(!result)
+    result = (unsigned char *) ctxt->hmac_hashctxt2 +
+     ctxt->hmac_hash->hmac_ctxtsize;
+
+  (*hashparams->hmac_hfinal)(result, ctxt->hmac_hashctxt1);
+  (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2,
+   result, hashparams->hmac_resultlen);
+  (*hashparams->hmac_hfinal)(result, ctxt->hmac_hashctxt2);
+  free((char *) ctxt);
+  return 0;
+}
+
+#endif /* CURL_DISABLE_CRYPTO_AUTH */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/hostasyn.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/hostasyn.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/hostasyn.c	(revision 331)
@@ -0,0 +1,153 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+/***********************************************************************
+ * Only for builds using asynchronous name resolves
+ **********************************************************************/
+#ifdef CURLRES_ASYNCH
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Curl_addrinfo_callback() gets called by ares, gethostbyname_thread()
+ * or getaddrinfo_thread() when we got the name resolved (or not!).
+ *
+ * If the status argument is CURL_ASYNC_SUCCESS, this function takes
+ * ownership of the Curl_addrinfo passed, storing the resolved data
+ * in the DNS cache.
+ *
+ * The storage operation locks and unlocks the DNS cache.
+ */
+CURLcode Curl_addrinfo_callback(struct connectdata *conn,
+                                int status,
+                                struct Curl_addrinfo *ai)
+{
+  struct Curl_dns_entry *dns = NULL;
+  CURLcode result = CURLE_OK;
+
+  conn->async.status = status;
+
+  if(CURL_ASYNC_SUCCESS == status) {
+    if(ai) {
+      struct Curl_easy *data = conn->data;
+
+      if(data->share)
+        Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+      dns = Curl_cache_addr(data, ai,
+                            conn->async.hostname,
+                            conn->async.port);
+      if(!dns) {
+        /* failed to store, cleanup and return error */
+        Curl_freeaddrinfo(ai);
+        result = CURLE_OUT_OF_MEMORY;
+      }
+
+      if(data->share)
+        Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+    }
+    else {
+      result = CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  conn->async.dns = dns;
+
+ /* Set async.done TRUE last in this function since it may be used multi-
+    threaded and once this is TRUE the other thread may read fields from the
+    async struct */
+  conn->async.done = TRUE;
+
+  /* IPv4: The input hostent struct will be freed by ares when we return from
+     this function */
+  return result;
+}
+
+/* Call this function after Curl_connect() has returned async=TRUE and
+   then a successful name resolve has been received.
+
+   Note: this function disconnects and frees the conn data in case of
+   resolve failure */
+CURLcode Curl_async_resolved(struct connectdata *conn,
+                             bool *protocol_done)
+{
+  CURLcode result;
+
+  if(conn->async.dns) {
+    conn->dns_entry = conn->async.dns;
+    conn->async.dns = NULL;
+  }
+
+  result = Curl_setup_conn(conn, protocol_done);
+
+  if(result)
+    /* We're not allowed to return failure with memory left allocated
+       in the connectdata struct, free those here */
+    Curl_disconnect(conn, FALSE); /* close the connection */
+
+  return result;
+}
+
+/*
+ * Curl_getaddrinfo() is the generic low-level name resolve API within this
+ * source file. There are several versions of this function - for different
+ * name resolve layers (selected at build-time). They all take this same set
+ * of arguments
+ */
+Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+                                const char *hostname,
+                                int port,
+                                int *waitp)
+{
+  return Curl_resolver_getaddrinfo(conn, hostname, port, waitp);
+}
+
+#endif /* CURLRES_ASYNCH */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/hostcheck.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/hostcheck.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/hostcheck.c	(revision 331)
@@ -0,0 +1,150 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_OPENSSL)                                \
+  || defined(USE_AXTLS)                                 \
+  || defined(USE_GSKIT)                                 \
+  || (defined(USE_SCHANNEL) && defined(_WIN32_WCE))
+/* these backends use functions from this file */
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include "hostcheck.h"
+#include "strcase.h"
+#include "inet_pton.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Match a hostname against a wildcard pattern.
+ * E.g.
+ *  "foo.host.com" matches "*.host.com".
+ *
+ * We use the matching rule described in RFC6125, section 6.4.3.
+ * https://tools.ietf.org/html/rfc6125#section-6.4.3
+ *
+ * In addition: ignore trailing dots in the host names and wildcards, so that
+ * the names are used normalized. This is what the browsers do.
+ *
+ * Do not allow wildcard matching on IP numbers. There are apparently
+ * certificates being used with an IP address in the CN field, thus making no
+ * apparent distinction between a name and an IP. We need to detect the use of
+ * an IP address and not wildcard match on such names.
+ *
+ * NOTE: hostmatch() gets called with copied buffers so that it can modify the
+ * contents at will.
+ */
+
+static int hostmatch(char *hostname, char *pattern)
+{
+  const char *pattern_label_end, *pattern_wildcard, *hostname_label_end;
+  int wildcard_enabled;
+  size_t prefixlen, suffixlen;
+  struct in_addr ignored;
+#ifdef ENABLE_IPV6
+  struct sockaddr_in6 si6;
+#endif
+
+  /* normalize pattern and hostname by stripping off trailing dots */
+  size_t len = strlen(hostname);
+  if(hostname[len-1]=='.')
+    hostname[len-1] = 0;
+  len = strlen(pattern);
+  if(pattern[len-1]=='.')
+    pattern[len-1] = 0;
+
+  pattern_wildcard = strchr(pattern, '*');
+  if(pattern_wildcard == NULL)
+    return strcasecompare(pattern, hostname) ?
+      CURL_HOST_MATCH : CURL_HOST_NOMATCH;
+
+  /* detect IP address as hostname and fail the match if so */
+  if(Curl_inet_pton(AF_INET, hostname, &ignored) > 0)
+    return CURL_HOST_NOMATCH;
+#ifdef ENABLE_IPV6
+  if(Curl_inet_pton(AF_INET6, hostname, &si6.sin6_addr) > 0)
+    return CURL_HOST_NOMATCH;
+#endif
+
+  /* We require at least 2 dots in pattern to avoid too wide wildcard
+     match. */
+  wildcard_enabled = 1;
+  pattern_label_end = strchr(pattern, '.');
+  if(pattern_label_end == NULL || strchr(pattern_label_end + 1, '.') == NULL ||
+     pattern_wildcard > pattern_label_end ||
+     strncasecompare(pattern, "xn--", 4)) {
+    wildcard_enabled = 0;
+  }
+  if(!wildcard_enabled)
+    return strcasecompare(pattern, hostname) ?
+      CURL_HOST_MATCH : CURL_HOST_NOMATCH;
+
+  hostname_label_end = strchr(hostname, '.');
+  if(hostname_label_end == NULL ||
+     !strcasecompare(pattern_label_end, hostname_label_end))
+    return CURL_HOST_NOMATCH;
+
+  /* The wildcard must match at least one character, so the left-most
+     label of the hostname is at least as large as the left-most label
+     of the pattern. */
+  if(hostname_label_end - hostname < pattern_label_end - pattern)
+    return CURL_HOST_NOMATCH;
+
+  prefixlen = pattern_wildcard - pattern;
+  suffixlen = pattern_label_end - (pattern_wildcard + 1);
+  return strncasecompare(pattern, hostname, prefixlen) &&
+    strncasecompare(pattern_wildcard + 1, hostname_label_end - suffixlen,
+                    suffixlen) ?
+    CURL_HOST_MATCH : CURL_HOST_NOMATCH;
+}
+
+int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
+{
+  char *matchp;
+  char *hostp;
+  int res = 0;
+  if(!match_pattern || !*match_pattern ||
+      !hostname || !*hostname) /* sanity check */
+    ;
+  else {
+    matchp = strdup(match_pattern);
+    if(matchp) {
+      hostp = strdup(hostname);
+      if(hostp) {
+        if(hostmatch(hostp, matchp) == CURL_HOST_MATCH)
+          res = 1;
+        free(hostp);
+      }
+      free(matchp);
+    }
+  }
+
+  return res;
+}
+
+#endif /* OPENSSL, AXTLS, GSKIT or schannel+wince */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/hostcheck.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/hostcheck.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/hostcheck.h	(revision 331)
@@ -0,0 +1,32 @@
+#ifndef HEADER_CURL_HOSTCHECK_H
+#define HEADER_CURL_HOSTCHECK_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h>
+
+#define CURL_HOST_NOMATCH 0
+#define CURL_HOST_MATCH   1
+int Curl_cert_hostcheck(const char *match_pattern, const char *hostname);
+
+#endif /* HEADER_CURL_HOSTCHECK_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/hostip.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/hostip.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/hostip.c	(revision 331)
@@ -0,0 +1,895 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_SETJMP_H
+#include <setjmp.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "inet_ntop.h"
+#include "warnless.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#if defined(CURLRES_SYNCH) && \
+    defined(HAVE_ALARM) && defined(SIGALRM) && defined(HAVE_SIGSETJMP)
+/* alarm-based timeouts can only be used with all the dependencies satisfied */
+#define USE_ALARM_TIMEOUT
+#endif
+
+/*
+ * hostip.c explained
+ * ==================
+ *
+ * The main COMPILE-TIME DEFINES to keep in mind when reading the host*.c
+ * source file are these:
+ *
+ * CURLRES_IPV6 - this host has getaddrinfo() and family, and thus we use
+ * that. The host may not be able to resolve IPv6, but we don't really have to
+ * take that into account. Hosts that aren't IPv6-enabled have CURLRES_IPV4
+ * defined.
+ *
+ * CURLRES_ARES - is defined if libcurl is built to use c-ares for
+ * asynchronous name resolves. This can be Windows or *nix.
+ *
+ * CURLRES_THREADED - is defined if libcurl is built to run under (native)
+ * Windows, and then the name resolve will be done in a new thread, and the
+ * supported API will be the same as for ares-builds.
+ *
+ * If any of the two previous are defined, CURLRES_ASYNCH is defined too. If
+ * libcurl is not built to use an asynchronous resolver, CURLRES_SYNCH is
+ * defined.
+ *
+ * The host*.c sources files are split up like this:
+ *
+ * hostip.c   - method-independent resolver functions and utility functions
+ * hostasyn.c - functions for asynchronous name resolves
+ * hostsyn.c  - functions for synchronous name resolves
+ * hostip4.c  - IPv4 specific functions
+ * hostip6.c  - IPv6 specific functions
+ *
+ * The two asynchronous name resolver backends are implemented in:
+ * asyn-ares.c   - functions for ares-using name resolves
+ * asyn-thread.c - functions for threaded name resolves
+
+ * The hostip.h is the united header file for all this. It defines the
+ * CURLRES_* defines based on the config*.h and curl_setup.h defines.
+ */
+
+/* These two symbols are for the global DNS cache */
+static struct curl_hash hostname_cache;
+static int host_cache_initialized;
+
+static void freednsentry(void *freethis);
+
+/*
+ * Curl_global_host_cache_init() initializes and sets up a global DNS cache.
+ * Global DNS cache is general badness. Do not use. This will be removed in
+ * a future version. Use the share interface instead!
+ *
+ * Returns a struct curl_hash pointer on success, NULL on failure.
+ */
+struct curl_hash *Curl_global_host_cache_init(void)
+{
+  int rc = 0;
+  if(!host_cache_initialized) {
+    rc = Curl_hash_init(&hostname_cache, 7, Curl_hash_str,
+                        Curl_str_key_compare, freednsentry);
+    if(!rc)
+      host_cache_initialized = 1;
+  }
+  return rc?NULL:&hostname_cache;
+}
+
+/*
+ * Destroy and cleanup the global DNS cache
+ */
+void Curl_global_host_cache_dtor(void)
+{
+  if(host_cache_initialized) {
+    Curl_hash_destroy(&hostname_cache);
+    host_cache_initialized = 0;
+  }
+}
+
+/*
+ * Return # of addresses in a Curl_addrinfo struct
+ */
+int Curl_num_addresses(const Curl_addrinfo *addr)
+{
+  int i = 0;
+  while(addr) {
+    addr = addr->ai_next;
+    i++;
+  }
+  return i;
+}
+
+/*
+ * Curl_printable_address() returns a printable version of the 1st address
+ * given in the 'ai' argument. The result will be stored in the buf that is
+ * bufsize bytes big.
+ *
+ * If the conversion fails, it returns NULL.
+ */
+const char *
+Curl_printable_address(const Curl_addrinfo *ai, char *buf, size_t bufsize)
+{
+  const struct sockaddr_in *sa4;
+  const struct in_addr *ipaddr4;
+#ifdef ENABLE_IPV6
+  const struct sockaddr_in6 *sa6;
+  const struct in6_addr *ipaddr6;
+#endif
+
+  switch(ai->ai_family) {
+    case AF_INET:
+      sa4 = (const void *)ai->ai_addr;
+      ipaddr4 = &sa4->sin_addr;
+      return Curl_inet_ntop(ai->ai_family, (const void *)ipaddr4, buf,
+                            bufsize);
+#ifdef ENABLE_IPV6
+    case AF_INET6:
+      sa6 = (const void *)ai->ai_addr;
+      ipaddr6 = &sa6->sin6_addr;
+      return Curl_inet_ntop(ai->ai_family, (const void *)ipaddr6, buf,
+                            bufsize);
+#endif
+    default:
+      break;
+  }
+  return NULL;
+}
+
+/*
+ * Return a hostcache id string for the provided host + port, to be used by
+ * the DNS caching.
+ */
+static char *
+create_hostcache_id(const char *name, int port)
+{
+  /* create and return the new allocated entry */
+  char *id = aprintf("%s:%d", name, port);
+  char *ptr = id;
+  if(ptr) {
+    /* lower case the name part */
+    while(*ptr && (*ptr != ':')) {
+      *ptr = (char)TOLOWER(*ptr);
+      ptr++;
+    }
+  }
+  return id;
+}
+
+struct hostcache_prune_data {
+  long cache_timeout;
+  time_t now;
+};
+
+/*
+ * This function is set as a callback to be called for every entry in the DNS
+ * cache when we want to prune old unused entries.
+ *
+ * Returning non-zero means remove the entry, return 0 to keep it in the
+ * cache.
+ */
+static int
+hostcache_timestamp_remove(void *datap, void *hc)
+{
+  struct hostcache_prune_data *data =
+    (struct hostcache_prune_data *) datap;
+  struct Curl_dns_entry *c = (struct Curl_dns_entry *) hc;
+
+  return (0 != c->timestamp)
+    && (data->now - c->timestamp >= data->cache_timeout);
+}
+
+/*
+ * Prune the DNS cache. This assumes that a lock has already been taken.
+ */
+static void
+hostcache_prune(struct curl_hash *hostcache, long cache_timeout, time_t now)
+{
+  struct hostcache_prune_data user;
+
+  user.cache_timeout = cache_timeout;
+  user.now = now;
+
+  Curl_hash_clean_with_criterium(hostcache,
+                                 (void *) &user,
+                                 hostcache_timestamp_remove);
+}
+
+/*
+ * Library-wide function for pruning the DNS cache. This function takes and
+ * returns the appropriate locks.
+ */
+void Curl_hostcache_prune(struct Curl_easy *data)
+{
+  time_t now;
+
+  if((data->set.dns_cache_timeout == -1) || !data->dns.hostcache)
+    /* cache forever means never prune, and NULL hostcache means
+       we can't do it */
+    return;
+
+  if(data->share)
+    Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+  time(&now);
+
+  /* Remove outdated and unused entries from the hostcache */
+  hostcache_prune(data->dns.hostcache,
+                  data->set.dns_cache_timeout,
+                  now);
+
+  if(data->share)
+    Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+}
+
+#ifdef HAVE_SIGSETJMP
+/* Beware this is a global and unique instance. This is used to store the
+   return address that we can jump back to from inside a signal handler. This
+   is not thread-safe stuff. */
+sigjmp_buf curl_jmpenv;
+#endif
+
+/* lookup address, returns entry if found and not stale */
+static struct Curl_dns_entry *
+fetch_addr(struct connectdata *conn,
+                const char *hostname,
+                int port)
+{
+  char *entry_id = NULL;
+  struct Curl_dns_entry *dns = NULL;
+  size_t entry_len;
+  struct Curl_easy *data = conn->data;
+
+  /* Create an entry id, based upon the hostname and port */
+  entry_id = create_hostcache_id(hostname, port);
+  /* If we can't create the entry id, fail */
+  if(!entry_id)
+    return dns;
+
+  entry_len = strlen(entry_id);
+
+  /* See if its already in our dns cache */
+  dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1);
+
+  if(dns && (data->set.dns_cache_timeout != -1)) {
+    /* See whether the returned entry is stale. Done before we release lock */
+    struct hostcache_prune_data user;
+
+    time(&user.now);
+    user.cache_timeout = data->set.dns_cache_timeout;
+
+    if(hostcache_timestamp_remove(&user, dns)) {
+      infof(data, "Hostname in DNS cache was stale, zapped\n");
+      dns = NULL; /* the memory deallocation is being handled by the hash */
+      Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1);
+    }
+  }
+
+  /* free the allocated entry_id again */
+  free(entry_id);
+
+  return dns;
+}
+
+/*
+ * Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache.
+ *
+ * Curl_resolv() checks initially and multi_runsingle() checks each time
+ * it discovers the handle in the state WAITRESOLVE whether the hostname
+ * has already been resolved and the address has already been stored in
+ * the DNS cache. This short circuits waiting for a lot of pending
+ * lookups for the same hostname requested by different handles.
+ *
+ * Returns the Curl_dns_entry entry pointer or NULL if not in the cache.
+ *
+ * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after
+ * use, or we'll leak memory!
+ */
+struct Curl_dns_entry *
+Curl_fetch_addr(struct connectdata *conn,
+                const char *hostname,
+                int port)
+{
+  struct Curl_easy *data = conn->data;
+  struct Curl_dns_entry *dns = NULL;
+
+  if(data->share)
+    Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+  dns = fetch_addr(conn, hostname, port);
+
+  if(dns)
+    dns->inuse++; /* we use it! */
+
+  if(data->share)
+    Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+
+  return dns;
+}
+
+/*
+ * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
+ *
+ * When calling Curl_resolv() has resulted in a response with a returned
+ * address, we call this function to store the information in the dns
+ * cache etc
+ *
+ * Returns the Curl_dns_entry entry pointer or NULL if the storage failed.
+ */
+struct Curl_dns_entry *
+Curl_cache_addr(struct Curl_easy *data,
+                Curl_addrinfo *addr,
+                const char *hostname,
+                int port)
+{
+  char *entry_id;
+  size_t entry_len;
+  struct Curl_dns_entry *dns;
+  struct Curl_dns_entry *dns2;
+
+  /* Create an entry id, based upon the hostname and port */
+  entry_id = create_hostcache_id(hostname, port);
+  /* If we can't create the entry id, fail */
+  if(!entry_id)
+    return NULL;
+  entry_len = strlen(entry_id);
+
+  /* Create a new cache entry */
+  dns = calloc(1, sizeof(struct Curl_dns_entry));
+  if(!dns) {
+    free(entry_id);
+    return NULL;
+  }
+
+  dns->inuse = 1;   /* the cache has the first reference */
+  dns->addr = addr; /* this is the address(es) */
+  time(&dns->timestamp);
+  if(dns->timestamp == 0)
+    dns->timestamp = 1;   /* zero indicates CURLOPT_RESOLVE entry */
+
+  /* Store the resolved data in our DNS cache. */
+  dns2 = Curl_hash_add(data->dns.hostcache, entry_id, entry_len + 1,
+                       (void *)dns);
+  if(!dns2) {
+    free(dns);
+    free(entry_id);
+    return NULL;
+  }
+
+  dns = dns2;
+  dns->inuse++;         /* mark entry as in-use */
+
+  /* free the allocated entry_id */
+  free(entry_id);
+
+  return dns;
+}
+
+/*
+ * Curl_resolv() is the main name resolve function within libcurl. It resolves
+ * a name and returns a pointer to the entry in the 'entry' argument (if one
+ * is provided). This function might return immediately if we're using asynch
+ * resolves. See the return codes.
+ *
+ * The cache entry we return will get its 'inuse' counter increased when this
+ * function is used. You MUST call Curl_resolv_unlock() later (when you're
+ * done using this struct) to decrease the counter again.
+ *
+ * In debug mode, we specifically test for an interface name "LocalHost"
+ * and resolve "localhost" instead as a means to permit test cases
+ * to connect to a local test server with any host name.
+ *
+ * Return codes:
+ *
+ * CURLRESOLV_ERROR   (-1) = error, no pointer
+ * CURLRESOLV_RESOLVED (0) = OK, pointer provided
+ * CURLRESOLV_PENDING  (1) = waiting for response, no pointer
+ */
+
+int Curl_resolv(struct connectdata *conn,
+                const char *hostname,
+                int port,
+                struct Curl_dns_entry **entry)
+{
+  struct Curl_dns_entry *dns = NULL;
+  struct Curl_easy *data = conn->data;
+  CURLcode result;
+  int rc = CURLRESOLV_ERROR; /* default to failure */
+
+  *entry = NULL;
+
+  if(data->share)
+    Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+  dns = fetch_addr(conn, hostname, port);
+
+  if(dns) {
+    infof(data, "Hostname %s was found in DNS cache\n", hostname);
+    dns->inuse++; /* we use it! */
+    rc = CURLRESOLV_RESOLVED;
+  }
+
+  if(data->share)
+    Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+
+  if(!dns) {
+    /* The entry was not in the cache. Resolve it to IP address */
+
+    Curl_addrinfo *addr;
+    int respwait;
+
+    /* Check what IP specifics the app has requested and if we can provide it.
+     * If not, bail out. */
+    if(!Curl_ipvalid(conn))
+      return CURLRESOLV_ERROR;
+
+    /* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a
+       non-zero value indicating that we need to wait for the response to the
+       resolve call */
+    addr = Curl_getaddrinfo(conn,
+#ifdef DEBUGBUILD
+                            (data->set.str[STRING_DEVICE]
+                             && !strcmp(data->set.str[STRING_DEVICE],
+                                        "LocalHost"))?"localhost":
+#endif
+                            hostname, port, &respwait);
+
+    if(!addr) {
+      if(respwait) {
+        /* the response to our resolve call will come asynchronously at
+           a later time, good or bad */
+        /* First, check that we haven't received the info by now */
+        result = Curl_resolver_is_resolved(conn, &dns);
+        if(result) /* error detected */
+          return CURLRESOLV_ERROR;
+        if(dns)
+          rc = CURLRESOLV_RESOLVED; /* pointer provided */
+        else
+          rc = CURLRESOLV_PENDING; /* no info yet */
+      }
+    }
+    else {
+      if(data->share)
+        Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+      /* we got a response, store it in the cache */
+      dns = Curl_cache_addr(data, addr, hostname, port);
+
+      if(data->share)
+        Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+
+      if(!dns)
+        /* returned failure, bail out nicely */
+        Curl_freeaddrinfo(addr);
+      else
+        rc = CURLRESOLV_RESOLVED;
+    }
+  }
+
+  *entry = dns;
+
+  return rc;
+}
+
+#ifdef USE_ALARM_TIMEOUT
+/*
+ * This signal handler jumps back into the main libcurl code and continues
+ * execution.  This effectively causes the remainder of the application to run
+ * within a signal handler which is nonportable and could lead to problems.
+ */
+static
+RETSIGTYPE alarmfunc(int sig)
+{
+  /* this is for "-ansi -Wall -pedantic" to stop complaining!   (rabe) */
+  (void)sig;
+  siglongjmp(curl_jmpenv, 1);
+}
+#endif /* USE_ALARM_TIMEOUT */
+
+/*
+ * Curl_resolv_timeout() is the same as Curl_resolv() but specifies a
+ * timeout.  This function might return immediately if we're using asynch
+ * resolves. See the return codes.
+ *
+ * The cache entry we return will get its 'inuse' counter increased when this
+ * function is used. You MUST call Curl_resolv_unlock() later (when you're
+ * done using this struct) to decrease the counter again.
+ *
+ * If built with a synchronous resolver and use of signals is not
+ * disabled by the application, then a nonzero timeout will cause a
+ * timeout after the specified number of milliseconds. Otherwise, timeout
+ * is ignored.
+ *
+ * Return codes:
+ *
+ * CURLRESOLV_TIMEDOUT(-2) = warning, time too short or previous alarm expired
+ * CURLRESOLV_ERROR   (-1) = error, no pointer
+ * CURLRESOLV_RESOLVED (0) = OK, pointer provided
+ * CURLRESOLV_PENDING  (1) = waiting for response, no pointer
+ */
+
+int Curl_resolv_timeout(struct connectdata *conn,
+                        const char *hostname,
+                        int port,
+                        struct Curl_dns_entry **entry,
+                        time_t timeoutms)
+{
+#ifdef USE_ALARM_TIMEOUT
+#ifdef HAVE_SIGACTION
+  struct sigaction keep_sigact;   /* store the old struct here */
+  volatile bool keep_copysig = FALSE; /* whether old sigact has been saved */
+  struct sigaction sigact;
+#else
+#ifdef HAVE_SIGNAL
+  void (*keep_sigact)(int);       /* store the old handler here */
+#endif /* HAVE_SIGNAL */
+#endif /* HAVE_SIGACTION */
+  volatile long timeout;
+  volatile unsigned int prev_alarm = 0;
+  struct Curl_easy *data = conn->data;
+#endif /* USE_ALARM_TIMEOUT */
+  int rc;
+
+  *entry = NULL;
+
+  if(timeoutms < 0)
+    /* got an already expired timeout */
+    return CURLRESOLV_TIMEDOUT;
+
+#ifdef USE_ALARM_TIMEOUT
+  if(data->set.no_signal)
+    /* Ignore the timeout when signals are disabled */
+    timeout = 0;
+  else
+    timeout = (timeoutms > LONG_MAX) ? LONG_MAX : (long)timeoutms;
+
+  if(!timeout)
+    /* USE_ALARM_TIMEOUT defined, but no timeout actually requested */
+    return Curl_resolv(conn, hostname, port, entry);
+
+  if(timeout < 1000) {
+    /* The alarm() function only provides integer second resolution, so if
+       we want to wait less than one second we must bail out already now. */
+    failf(data,
+        "remaining timeout of %ld too small to resolve via SIGALRM method",
+        timeout);
+    return CURLRESOLV_TIMEDOUT;
+  }
+  /* This allows us to time-out from the name resolver, as the timeout
+     will generate a signal and we will siglongjmp() from that here.
+     This technique has problems (see alarmfunc).
+     This should be the last thing we do before calling Curl_resolv(),
+     as otherwise we'd have to worry about variables that get modified
+     before we invoke Curl_resolv() (and thus use "volatile"). */
+  if(sigsetjmp(curl_jmpenv, 1)) {
+    /* this is coming from a siglongjmp() after an alarm signal */
+    failf(data, "name lookup timed out");
+    rc = CURLRESOLV_ERROR;
+    goto clean_up;
+  }
+  else {
+    /*************************************************************
+     * Set signal handler to catch SIGALRM
+     * Store the old value to be able to set it back later!
+     *************************************************************/
+#ifdef HAVE_SIGACTION
+    sigaction(SIGALRM, NULL, &sigact);
+    keep_sigact = sigact;
+    keep_copysig = TRUE; /* yes, we have a copy */
+    sigact.sa_handler = alarmfunc;
+#ifdef SA_RESTART
+    /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */
+    sigact.sa_flags &= ~SA_RESTART;
+#endif
+    /* now set the new struct */
+    sigaction(SIGALRM, &sigact, NULL);
+#else /* HAVE_SIGACTION */
+    /* no sigaction(), revert to the much lamer signal() */
+#ifdef HAVE_SIGNAL
+    keep_sigact = signal(SIGALRM, alarmfunc);
+#endif
+#endif /* HAVE_SIGACTION */
+
+    /* alarm() makes a signal get sent when the timeout fires off, and that
+       will abort system calls */
+    prev_alarm = alarm(curlx_sltoui(timeout/1000L));
+  }
+
+#else
+#ifndef CURLRES_ASYNCH
+  if(timeoutms)
+    infof(conn->data, "timeout on name lookup is not supported\n");
+#else
+  (void)timeoutms; /* timeoutms not used with an async resolver */
+#endif
+#endif /* USE_ALARM_TIMEOUT */
+
+  /* Perform the actual name resolution. This might be interrupted by an
+   * alarm if it takes too long.
+   */
+  rc = Curl_resolv(conn, hostname, port, entry);
+
+#ifdef USE_ALARM_TIMEOUT
+clean_up:
+
+  if(!prev_alarm)
+    /* deactivate a possibly active alarm before uninstalling the handler */
+    alarm(0);
+
+#ifdef HAVE_SIGACTION
+  if(keep_copysig) {
+    /* we got a struct as it looked before, now put that one back nice
+       and clean */
+    sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */
+  }
+#else
+#ifdef HAVE_SIGNAL
+  /* restore the previous SIGALRM handler */
+  signal(SIGALRM, keep_sigact);
+#endif
+#endif /* HAVE_SIGACTION */
+
+  /* switch back the alarm() to either zero or to what it was before minus
+     the time we spent until now! */
+  if(prev_alarm) {
+    /* there was an alarm() set before us, now put it back */
+    timediff_t elapsed_secs = Curl_timediff(Curl_now(),
+                                            conn->created) / 1000;
+
+    /* the alarm period is counted in even number of seconds */
+    unsigned long alarm_set = prev_alarm - elapsed_secs;
+
+    if(!alarm_set ||
+       ((alarm_set >= 0x80000000) && (prev_alarm < 0x80000000)) ) {
+      /* if the alarm time-left reached zero or turned "negative" (counted
+         with unsigned values), we should fire off a SIGALRM here, but we
+         won't, and zero would be to switch it off so we never set it to
+         less than 1! */
+      alarm(1);
+      rc = CURLRESOLV_TIMEDOUT;
+      failf(data, "Previous alarm fired off!");
+    }
+    else
+      alarm((unsigned int)alarm_set);
+  }
+#endif /* USE_ALARM_TIMEOUT */
+
+  return rc;
+}
+
+/*
+ * Curl_resolv_unlock() unlocks the given cached DNS entry. When this has been
+ * made, the struct may be destroyed due to pruning. It is important that only
+ * one unlock is made for each Curl_resolv() call.
+ *
+ * May be called with 'data' == NULL for global cache.
+ */
+void Curl_resolv_unlock(struct Curl_easy *data, struct Curl_dns_entry *dns)
+{
+  if(data && data->share)
+    Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+  freednsentry(dns);
+
+  if(data && data->share)
+    Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+}
+
+/*
+ * File-internal: release cache dns entry reference, free if inuse drops to 0
+ */
+static void freednsentry(void *freethis)
+{
+  struct Curl_dns_entry *dns = (struct Curl_dns_entry *) freethis;
+  DEBUGASSERT(dns && (dns->inuse>0));
+
+  dns->inuse--;
+  if(dns->inuse == 0) {
+    Curl_freeaddrinfo(dns->addr);
+    free(dns);
+  }
+}
+
+/*
+ * Curl_mk_dnscache() inits a new DNS cache and returns success/failure.
+ */
+int Curl_mk_dnscache(struct curl_hash *hash)
+{
+  return Curl_hash_init(hash, 7, Curl_hash_str, Curl_str_key_compare,
+                        freednsentry);
+}
+
+/*
+ * Curl_hostcache_clean()
+ *
+ * This _can_ be called with 'data' == NULL but then of course no locking
+ * can be done!
+ */
+
+void Curl_hostcache_clean(struct Curl_easy *data,
+                          struct curl_hash *hash)
+{
+  if(data && data->share)
+    Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+  Curl_hash_clean(hash);
+
+  if(data && data->share)
+    Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+}
+
+
+CURLcode Curl_loadhostpairs(struct Curl_easy *data)
+{
+  struct curl_slist *hostp;
+  char hostname[256];
+  int port;
+
+  for(hostp = data->change.resolve; hostp; hostp = hostp->next) {
+    if(!hostp->data)
+      continue;
+    if(hostp->data[0] == '-') {
+      char *entry_id;
+      size_t entry_len;
+
+      if(2 != sscanf(hostp->data + 1, "%255[^:]:%d", hostname, &port)) {
+        infof(data, "Couldn't parse CURLOPT_RESOLVE removal entry '%s'!\n",
+              hostp->data);
+        continue;
+      }
+
+      /* Create an entry id, based upon the hostname and port */
+      entry_id = create_hostcache_id(hostname, port);
+      /* If we can't create the entry id, fail */
+      if(!entry_id) {
+        return CURLE_OUT_OF_MEMORY;
+      }
+
+      entry_len = strlen(entry_id);
+
+      if(data->share)
+        Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+      /* delete entry, ignore if it didn't exist */
+      Curl_hash_delete(data->dns.hostcache, entry_id, entry_len + 1);
+
+      if(data->share)
+        Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+
+      /* free the allocated entry_id again */
+      free(entry_id);
+    }
+    else {
+      struct Curl_dns_entry *dns;
+      Curl_addrinfo *addr;
+      char *entry_id;
+      size_t entry_len;
+      char buffer[256];
+      char *address = &buffer[0];
+
+      if(3 != sscanf(hostp->data, "%255[^:]:%d:%255s", hostname, &port,
+                     address)) {
+        infof(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'!\n",
+              hostp->data);
+        continue;
+      }
+
+      /* allow IP(v6) address within [brackets] */
+      if(address[0] == '[') {
+        size_t alen = strlen(address);
+        if(address[alen-1] != ']')
+          /* it needs to also end with ] to be valid */
+          continue;
+        address[alen-1] = 0; /* zero terminate there */
+        address++; /* pass the open bracket */
+      }
+
+      addr = Curl_str2addr(address, port);
+      if(!addr) {
+        infof(data, "Address in '%s' found illegal!\n", hostp->data);
+        continue;
+      }
+
+      /* Create an entry id, based upon the hostname and port */
+      entry_id = create_hostcache_id(hostname, port);
+      /* If we can't create the entry id, fail */
+      if(!entry_id) {
+        Curl_freeaddrinfo(addr);
+        return CURLE_OUT_OF_MEMORY;
+      }
+
+      entry_len = strlen(entry_id);
+
+      if(data->share)
+        Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
+
+      /* See if its already in our dns cache */
+      dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1);
+
+      /* free the allocated entry_id again */
+      free(entry_id);
+
+      if(!dns) {
+        /* if not in the cache already, put this host in the cache */
+        dns = Curl_cache_addr(data, addr, hostname, port);
+        if(dns) {
+          dns->timestamp = 0; /* mark as added by CURLOPT_RESOLVE */
+          /* release the returned reference; the cache itself will keep the
+           * entry alive: */
+          dns->inuse--;
+        }
+      }
+      else
+        /* this is a duplicate, free it again */
+        Curl_freeaddrinfo(addr);
+
+      if(data->share)
+        Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
+
+      if(!dns) {
+        Curl_freeaddrinfo(addr);
+        return CURLE_OUT_OF_MEMORY;
+      }
+      infof(data, "Added %s:%d:%s to DNS cache\n",
+            hostname, port, address);
+    }
+  }
+  data->change.resolve = NULL; /* dealt with now */
+
+  return CURLE_OK;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/hostip.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/hostip.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/hostip.h	(revision 331)
@@ -0,0 +1,250 @@
+#ifndef HEADER_CURL_HOSTIP_H
+#define HEADER_CURL_HOSTIP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "hash.h"
+#include "curl_addrinfo.h"
+#include "asyn.h"
+
+#ifdef HAVE_SETJMP_H
+#include <setjmp.h>
+#endif
+
+#ifdef NETWARE
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+/* Allocate enough memory to hold the full name information structs and
+ * everything. OSF1 is known to require at least 8872 bytes. The buffer
+ * required for storing all possible aliases and IP numbers is according to
+ * Stevens' Unix Network Programming 2nd edition, p. 304: 8192 bytes!
+ */
+#define CURL_HOSTENT_SIZE 9000
+
+#define CURL_TIMEOUT_RESOLVE 300 /* when using asynch methods, we allow this
+                                    many seconds for a name resolve */
+
+#define CURL_ASYNC_SUCCESS CURLE_OK
+
+struct addrinfo;
+struct hostent;
+struct Curl_easy;
+struct connectdata;
+
+/*
+ * Curl_global_host_cache_init() initializes and sets up a global DNS cache.
+ * Global DNS cache is general badness. Do not use. This will be removed in
+ * a future version. Use the share interface instead!
+ *
+ * Returns a struct curl_hash pointer on success, NULL on failure.
+ */
+struct curl_hash *Curl_global_host_cache_init(void);
+void Curl_global_host_cache_dtor(void);
+
+struct Curl_dns_entry {
+  Curl_addrinfo *addr;
+  /* timestamp == 0 -- CURLOPT_RESOLVE entry, doesn't timeout */
+  time_t timestamp;
+  /* use-counter, use Curl_resolv_unlock to release reference */
+  long inuse;
+};
+
+/*
+ * Curl_resolv() returns an entry with the info for the specified host
+ * and port.
+ *
+ * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after
+ * use, or we'll leak memory!
+ */
+/* return codes */
+#define CURLRESOLV_TIMEDOUT -2
+#define CURLRESOLV_ERROR    -1
+#define CURLRESOLV_RESOLVED  0
+#define CURLRESOLV_PENDING   1
+int Curl_resolv(struct connectdata *conn, const char *hostname,
+                int port, struct Curl_dns_entry **dnsentry);
+int Curl_resolv_timeout(struct connectdata *conn, const char *hostname,
+                        int port, struct Curl_dns_entry **dnsentry,
+                        time_t timeoutms);
+
+#ifdef CURLRES_IPV6
+/*
+ * Curl_ipv6works() returns TRUE if IPv6 seems to work.
+ */
+bool Curl_ipv6works(void);
+#else
+#define Curl_ipv6works() FALSE
+#endif
+
+/*
+ * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
+ * been set and returns TRUE if they are OK.
+ */
+bool Curl_ipvalid(struct connectdata *conn);
+
+
+/*
+ * Curl_getaddrinfo() is the generic low-level name resolve API within this
+ * source file. There are several versions of this function - for different
+ * name resolve layers (selected at build-time). They all take this same set
+ * of arguments
+ */
+Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+                                const char *hostname,
+                                int port,
+                                int *waitp);
+
+
+/* unlock a previously resolved dns entry */
+void Curl_resolv_unlock(struct Curl_easy *data,
+                        struct Curl_dns_entry *dns);
+
+/* for debugging purposes only: */
+void Curl_scan_cache_used(void *user, void *ptr);
+
+/* init a new dns cache and return success */
+int Curl_mk_dnscache(struct curl_hash *hash);
+
+/* prune old entries from the DNS cache */
+void Curl_hostcache_prune(struct Curl_easy *data);
+
+/* Return # of addresses in a Curl_addrinfo struct */
+int Curl_num_addresses(const Curl_addrinfo *addr);
+
+#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
+int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
+                       GETNAMEINFO_TYPE_ARG2 salen,
+                       char *host, GETNAMEINFO_TYPE_ARG46 hostlen,
+                       char *serv, GETNAMEINFO_TYPE_ARG46 servlen,
+                       GETNAMEINFO_TYPE_ARG7 flags,
+                       int line, const char *source);
+#endif
+
+/* IPv4 threadsafe resolve function used for synch and asynch builds */
+Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port);
+
+CURLcode Curl_async_resolved(struct connectdata *conn,
+                             bool *protocol_connect);
+
+#ifndef CURLRES_ASYNCH
+#define Curl_async_resolved(x,y) CURLE_OK
+#endif
+
+/*
+ * Curl_addrinfo_callback() is used when we build with any asynch specialty.
+ * Handles end of async request processing. Inserts ai into hostcache when
+ * status is CURL_ASYNC_SUCCESS. Twiddles fields in conn to indicate async
+ * request completed whether successful or failed.
+ */
+CURLcode Curl_addrinfo_callback(struct connectdata *conn,
+                                int status,
+                                Curl_addrinfo *ai);
+
+/*
+ * Curl_printable_address() returns a printable version of the 1st address
+ * given in the 'ip' argument. The result will be stored in the buf that is
+ * bufsize bytes big.
+ */
+const char *Curl_printable_address(const Curl_addrinfo *ip,
+                                   char *buf, size_t bufsize);
+
+/*
+ * Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache.
+ *
+ * Returns the Curl_dns_entry entry pointer or NULL if not in the cache.
+ *
+ * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after
+ * use, or we'll leak memory!
+ */
+struct Curl_dns_entry *
+Curl_fetch_addr(struct connectdata *conn,
+                const char *hostname,
+                int port);
+/*
+ * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache.
+ *
+ * Returns the Curl_dns_entry entry pointer or NULL if the storage failed.
+ */
+struct Curl_dns_entry *
+Curl_cache_addr(struct Curl_easy *data, Curl_addrinfo *addr,
+                const char *hostname, int port);
+
+#ifndef INADDR_NONE
+#define CURL_INADDR_NONE (in_addr_t) ~0
+#else
+#define CURL_INADDR_NONE INADDR_NONE
+#endif
+
+#ifdef HAVE_SIGSETJMP
+/* Forward-declaration of variable defined in hostip.c. Beware this
+ * is a global and unique instance. This is used to store the return
+ * address that we can jump back to from inside a signal handler.
+ * This is not thread-safe stuff.
+ */
+extern sigjmp_buf curl_jmpenv;
+#endif
+
+/*
+ * Function provided by the resolver backend to set DNS servers to use.
+ */
+CURLcode Curl_set_dns_servers(struct Curl_easy *data, char *servers);
+
+/*
+ * Function provided by the resolver backend to set
+ * outgoing interface to use for DNS requests
+ */
+CURLcode Curl_set_dns_interface(struct Curl_easy *data,
+                                const char *interf);
+
+/*
+ * Function provided by the resolver backend to set
+ * local IPv4 address to use as source address for DNS requests
+ */
+CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data,
+                                const char *local_ip4);
+
+/*
+ * Function provided by the resolver backend to set
+ * local IPv6 address to use as source address for DNS requests
+ */
+CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data,
+                                const char *local_ip6);
+
+/*
+ * Clean off entries from the cache
+ */
+void Curl_hostcache_clean(struct Curl_easy *data, struct curl_hash *hash);
+
+/*
+ * Destroy the hostcache of this handle.
+ */
+void Curl_hostcache_destroy(struct Curl_easy *data);
+
+/*
+ * Populate the cache with specified entries from CURLOPT_RESOLVE.
+ */
+CURLcode Curl_loadhostpairs(struct Curl_easy *data);
+
+#endif /* HEADER_CURL_HOSTIP_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/hostip4.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/hostip4.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/hostip4.c	(revision 331)
@@ -0,0 +1,308 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+/***********************************************************************
+ * Only for plain IPv4 builds
+ **********************************************************************/
+#ifdef CURLRES_IPV4 /* plain IPv4 code coming up */
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "inet_pton.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
+ * been set and returns TRUE if they are OK.
+ */
+bool Curl_ipvalid(struct connectdata *conn)
+{
+  if(conn->ip_version == CURL_IPRESOLVE_V6)
+    /* An IPv6 address was requested and we can't get/use one */
+    return FALSE;
+
+  return TRUE; /* OK, proceed */
+}
+
+#ifdef CURLRES_SYNCH
+
+/*
+ * Curl_getaddrinfo() - the IPv4 synchronous version.
+ *
+ * The original code to this function was from the Dancer source code, written
+ * by Bjorn Reese, it has since been patched and modified considerably.
+ *
+ * gethostbyname_r() is the thread-safe version of the gethostbyname()
+ * function. When we build for plain IPv4, we attempt to use this
+ * function. There are _three_ different gethostbyname_r() versions, and we
+ * detect which one this platform supports in the configure script and set up
+ * the HAVE_GETHOSTBYNAME_R_3, HAVE_GETHOSTBYNAME_R_5 or
+ * HAVE_GETHOSTBYNAME_R_6 defines accordingly. Note that HAVE_GETADDRBYNAME
+ * has the corresponding rules. This is primarily on *nix. Note that some unix
+ * flavours have thread-safe versions of the plain gethostbyname() etc.
+ *
+ */
+Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+                                const char *hostname,
+                                int port,
+                                int *waitp)
+{
+  Curl_addrinfo *ai = NULL;
+
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+  (void)conn;
+#endif
+
+  *waitp = 0; /* synchronous response only */
+
+  ai = Curl_ipv4_resolve_r(hostname, port);
+  if(!ai)
+    infof(conn->data, "Curl_ipv4_resolve_r failed for %s\n", hostname);
+
+  return ai;
+}
+#endif /* CURLRES_SYNCH */
+#endif /* CURLRES_IPV4 */
+
+#if defined(CURLRES_IPV4) && !defined(CURLRES_ARES)
+
+/*
+ * Curl_ipv4_resolve_r() - ipv4 threadsafe resolver function.
+ *
+ * This is used for both synchronous and asynchronous resolver builds,
+ * implying that only threadsafe code and function calls may be used.
+ *
+ */
+Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
+                                   int port)
+{
+#if !defined(HAVE_GETADDRINFO_THREADSAFE) && defined(HAVE_GETHOSTBYNAME_R_3)
+  int res;
+#endif
+  Curl_addrinfo *ai = NULL;
+  struct hostent *h = NULL;
+  struct in_addr in;
+  struct hostent *buf = NULL;
+
+  if(Curl_inet_pton(AF_INET, hostname, &in) > 0)
+    /* This is a dotted IP address 123.123.123.123-style */
+    return Curl_ip2addr(AF_INET, &in, hostname, port);
+
+#if defined(HAVE_GETADDRINFO_THREADSAFE)
+  else {
+    struct addrinfo hints;
+    char sbuf[12];
+    char *sbufptr = NULL;
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = PF_INET;
+    hints.ai_socktype = SOCK_STREAM;
+    if(port) {
+      snprintf(sbuf, sizeof(sbuf), "%d", port);
+      sbufptr = sbuf;
+    }
+
+    (void)Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &ai);
+
+#elif defined(HAVE_GETHOSTBYNAME_R)
+  /*
+   * gethostbyname_r() is the preferred resolve function for many platforms.
+   * Since there are three different versions of it, the following code is
+   * somewhat #ifdef-ridden.
+   */
+  else {
+    int h_errnop;
+
+    buf = calloc(1, CURL_HOSTENT_SIZE);
+    if(!buf)
+      return NULL; /* major failure */
+    /*
+     * The clearing of the buffer is a workaround for a gethostbyname_r bug in
+     * qnx nto and it is also _required_ for some of these functions on some
+     * platforms.
+     */
+
+#if defined(HAVE_GETHOSTBYNAME_R_5)
+    /* Solaris, IRIX and more */
+    h = gethostbyname_r(hostname,
+                        (struct hostent *)buf,
+                        (char *)buf + sizeof(struct hostent),
+                        CURL_HOSTENT_SIZE - sizeof(struct hostent),
+                        &h_errnop);
+
+    /* If the buffer is too small, it returns NULL and sets errno to
+     * ERANGE. The errno is thread safe if this is compiled with
+     * -D_REENTRANT as then the 'errno' variable is a macro defined to get
+     * used properly for threads.
+     */
+
+    if(h) {
+      ;
+    }
+    else
+#elif defined(HAVE_GETHOSTBYNAME_R_6)
+    /* Linux */
+
+    (void)gethostbyname_r(hostname,
+                        (struct hostent *)buf,
+                        (char *)buf + sizeof(struct hostent),
+                        CURL_HOSTENT_SIZE - sizeof(struct hostent),
+                        &h, /* DIFFERENCE */
+                        &h_errnop);
+    /* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a
+     * sudden this function returns EAGAIN if the given buffer size is too
+     * small. Previous versions are known to return ERANGE for the same
+     * problem.
+     *
+     * This wouldn't be such a big problem if older versions wouldn't
+     * sometimes return EAGAIN on a common failure case. Alas, we can't
+     * assume that EAGAIN *or* ERANGE means ERANGE for any given version of
+     * glibc.
+     *
+     * For now, we do that and thus we may call the function repeatedly and
+     * fail for older glibc versions that return EAGAIN, until we run out of
+     * buffer size (step_size grows beyond CURL_HOSTENT_SIZE).
+     *
+     * If anyone has a better fix, please tell us!
+     *
+     * -------------------------------------------------------------------
+     *
+     * On October 23rd 2003, Dan C dug up more details on the mysteries of
+     * gethostbyname_r() in glibc:
+     *
+     * In glibc 2.2.5 the interface is different (this has also been
+     * discovered in glibc 2.1.1-6 as shipped by Redhat 6). What I can't
+     * explain, is that tests performed on glibc 2.2.4-34 and 2.2.4-32
+     * (shipped/upgraded by Redhat 7.2) don't show this behavior!
+     *
+     * In this "buggy" version, the return code is -1 on error and 'errno'
+     * is set to the ERANGE or EAGAIN code. Note that 'errno' is not a
+     * thread-safe variable.
+     */
+
+    if(!h) /* failure */
+#elif defined(HAVE_GETHOSTBYNAME_R_3)
+    /* AIX, Digital Unix/Tru64, HPUX 10, more? */
+
+    /* For AIX 4.3 or later, we don't use gethostbyname_r() at all, because of
+     * the plain fact that it does not return unique full buffers on each
+     * call, but instead several of the pointers in the hostent structs will
+     * point to the same actual data! This have the unfortunate down-side that
+     * our caching system breaks down horribly. Luckily for us though, AIX 4.3
+     * and more recent versions have a "completely thread-safe"[*] libc where
+     * all the data is stored in thread-specific memory areas making calls to
+     * the plain old gethostbyname() work fine even for multi-threaded
+     * programs.
+     *
+     * This AIX 4.3 or later detection is all made in the configure script.
+     *
+     * Troels Walsted Hansen helped us work this out on March 3rd, 2003.
+     *
+     * [*] = much later we've found out that it isn't at all "completely
+     * thread-safe", but at least the gethostbyname() function is.
+     */
+
+    if(CURL_HOSTENT_SIZE >=
+       (sizeof(struct hostent) + sizeof(struct hostent_data))) {
+
+      /* August 22nd, 2000: Albert Chin-A-Young brought an updated version
+       * that should work! September 20: Richard Prescott worked on the buffer
+       * size dilemma.
+       */
+
+      res = gethostbyname_r(hostname,
+                            (struct hostent *)buf,
+                            (struct hostent_data *)((char *)buf +
+                                                    sizeof(struct hostent)));
+      h_errnop = SOCKERRNO; /* we don't deal with this, but set it anyway */
+    }
+    else
+      res = -1; /* failure, too smallish buffer size */
+
+    if(!res) { /* success */
+
+      h = buf; /* result expected in h */
+
+      /* This is the worst kind of the different gethostbyname_r() interfaces.
+       * Since we don't know how big buffer this particular lookup required,
+       * we can't realloc down the huge alloc without doing closer analysis of
+       * the returned data. Thus, we always use CURL_HOSTENT_SIZE for every
+       * name lookup. Fixing this would require an extra malloc() and then
+       * calling Curl_addrinfo_copy() that subsequent realloc()s down the new
+       * memory area to the actually used amount.
+       */
+    }
+    else
+#endif /* HAVE_...BYNAME_R_5 || HAVE_...BYNAME_R_6 || HAVE_...BYNAME_R_3 */
+    {
+      h = NULL; /* set return code to NULL */
+      free(buf);
+    }
+#else /* HAVE_GETADDRINFO_THREADSAFE || HAVE_GETHOSTBYNAME_R */
+    /*
+     * Here is code for platforms that don't have a thread safe
+     * getaddrinfo() nor gethostbyname_r() function or for which
+     * gethostbyname() is the preferred one.
+     */
+  else {
+    h = gethostbyname((void *)hostname);
+#endif /* HAVE_GETADDRINFO_THREADSAFE || HAVE_GETHOSTBYNAME_R */
+  }
+
+  if(h) {
+    ai = Curl_he2ai(h, port);
+
+    if(buf) /* used a *_r() function */
+      free(buf);
+  }
+
+  return ai;
+}
+#endif /* defined(CURLRES_IPV4) && !defined(CURLRES_ARES) */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/hostip6.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/hostip6.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/hostip6.c	(revision 331)
@@ -0,0 +1,234 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+/***********************************************************************
+ * Only for IPv6-enabled builds
+ **********************************************************************/
+#ifdef CURLRES_IPV6
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "inet_pton.h"
+#include "connect.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
+/* These are strictly for memory tracing and are using the same style as the
+ * family otherwise present in memdebug.c. I put these ones here since they
+ * require a bunch of structs I didn't want to include in memdebug.c
+ */
+
+/*
+ * For CURLRES_ARS, this should be written using ares_gethostbyaddr()
+ * (ignoring the fact c-ares doesn't return 'serv').
+ */
+
+int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
+                       GETNAMEINFO_TYPE_ARG2 salen,
+                       char *host, GETNAMEINFO_TYPE_ARG46 hostlen,
+                       char *serv, GETNAMEINFO_TYPE_ARG46 servlen,
+                       GETNAMEINFO_TYPE_ARG7 flags,
+                       int line, const char *source)
+{
+  int res = (getnameinfo)(sa, salen,
+                          host, hostlen,
+                          serv, servlen,
+                          flags);
+  if(0 == res)
+    /* success */
+    curl_memlog("GETNAME %s:%d getnameinfo()\n",
+                source, line);
+  else
+    curl_memlog("GETNAME %s:%d getnameinfo() failed = %d\n",
+                source, line, res);
+  return res;
+}
+#endif /* defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO) */
+
+/*
+ * Curl_ipv6works() returns TRUE if IPv6 seems to work.
+ */
+bool Curl_ipv6works(void)
+{
+  /* the nature of most system is that IPv6 status doesn't come and go
+     during a program's lifetime so we only probe the first time and then we
+     have the info kept for fast re-use */
+  static int ipv6_works = -1;
+  if(-1 == ipv6_works) {
+    /* probe to see if we have a working IPv6 stack */
+    curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0);
+    if(s == CURL_SOCKET_BAD)
+      /* an IPv6 address was requested but we can't get/use one */
+      ipv6_works = 0;
+    else {
+      ipv6_works = 1;
+      Curl_closesocket(NULL, s);
+    }
+  }
+  return (ipv6_works>0)?TRUE:FALSE;
+}
+
+/*
+ * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've
+ * been set and returns TRUE if they are OK.
+ */
+bool Curl_ipvalid(struct connectdata *conn)
+{
+  if(conn->ip_version == CURL_IPRESOLVE_V6)
+    return Curl_ipv6works();
+
+  return TRUE;
+}
+
+#if defined(CURLRES_SYNCH)
+
+#ifdef DEBUG_ADDRINFO
+static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai)
+{
+  printf("dump_addrinfo:\n");
+  for(; ai; ai = ai->ai_next) {
+    char  buf[INET6_ADDRSTRLEN];
+
+    printf("    fam %2d, CNAME %s, ",
+           ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>");
+    if(Curl_printable_address(ai, buf, sizeof(buf)))
+      printf("%s\n", buf);
+    else
+      printf("failed; %s\n", Curl_strerror(conn, SOCKERRNO));
+  }
+}
+#else
+#define dump_addrinfo(x,y) Curl_nop_stmt
+#endif
+
+/*
+ * Curl_getaddrinfo() when built IPv6-enabled (non-threading and
+ * non-ares version).
+ *
+ * Returns name information about the given hostname and port number. If
+ * successful, the 'addrinfo' is returned and the forth argument will point to
+ * memory we need to free after use. That memory *MUST* be freed with
+ * Curl_freeaddrinfo(), nothing else.
+ */
+Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
+                                const char *hostname,
+                                int port,
+                                int *waitp)
+{
+  struct addrinfo hints;
+  Curl_addrinfo *res;
+  int error;
+  char sbuf[12];
+  char *sbufptr = NULL;
+#ifndef USE_RESOLVE_ON_IPS
+  char addrbuf[128];
+#endif
+  int pf;
+#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  struct Curl_easy *data = conn->data;
+#endif
+
+  *waitp = 0; /* synchronous response only */
+
+  /* Check if a limited name resolve has been requested */
+  switch(conn->ip_version) {
+  case CURL_IPRESOLVE_V4:
+    pf = PF_INET;
+    break;
+  case CURL_IPRESOLVE_V6:
+    pf = PF_INET6;
+    break;
+  default:
+    pf = PF_UNSPEC;
+    break;
+  }
+
+  if((pf != PF_INET) && !Curl_ipv6works())
+    /* The stack seems to be a non-IPv6 one */
+    pf = PF_INET;
+
+  memset(&hints, 0, sizeof(hints));
+  hints.ai_family = pf;
+  hints.ai_socktype = conn->socktype;
+
+#ifndef USE_RESOLVE_ON_IPS
+  /*
+   * The AI_NUMERICHOST must not be set to get synthesized IPv6 address from
+   * an IPv4 address on iOS and Mac OS X.
+   */
+  if((1 == Curl_inet_pton(AF_INET, hostname, addrbuf)) ||
+     (1 == Curl_inet_pton(AF_INET6, hostname, addrbuf))) {
+    /* the given address is numerical only, prevent a reverse lookup */
+    hints.ai_flags = AI_NUMERICHOST;
+  }
+#endif
+
+  if(port) {
+    snprintf(sbuf, sizeof(sbuf), "%d", port);
+    sbufptr = sbuf;
+  }
+
+  error = Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &res);
+  if(error) {
+    infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port);
+    return NULL;
+  }
+
+  if(port) {
+    Curl_addrinfo_set_port(res, port);
+  }
+
+  dump_addrinfo(conn, res);
+
+  return res;
+}
+#endif /* CURLRES_SYNCH */
+
+#endif /* CURLRES_IPV6 */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/hostsyn.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/hostsyn.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/hostsyn.c	(revision 331)
@@ -0,0 +1,107 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+/***********************************************************************
+ * Only for builds using synchronous name resolves
+ **********************************************************************/
+#ifdef CURLRES_SYNCH
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "hash.h"
+#include "share.h"
+#include "strerror.h"
+#include "url.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Function provided by the resolver backend to set DNS servers to use.
+ */
+CURLcode Curl_set_dns_servers(struct Curl_easy *data,
+                              char *servers)
+{
+  (void)data;
+  (void)servers;
+  return CURLE_NOT_BUILT_IN;
+
+}
+
+/*
+ * Function provided by the resolver backend to set
+ * outgoing interface to use for DNS requests
+ */
+CURLcode Curl_set_dns_interface(struct Curl_easy *data,
+                                const char *interf)
+{
+  (void)data;
+  (void)interf;
+  return CURLE_NOT_BUILT_IN;
+}
+
+/*
+ * Function provided by the resolver backend to set
+ * local IPv4 address to use as source address for DNS requests
+ */
+CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data,
+                                const char *local_ip4)
+{
+  (void)data;
+  (void)local_ip4;
+  return CURLE_NOT_BUILT_IN;
+}
+
+/*
+ * Function provided by the resolver backend to set
+ * local IPv6 address to use as source address for DNS requests
+ */
+CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data,
+                                const char *local_ip6)
+{
+  (void)data;
+  (void)local_ip6;
+  return CURLE_NOT_BUILT_IN;
+}
+
+#endif /* truly sync */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/http.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/http.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/http.c	(revision 331)
@@ -0,0 +1,3767 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_HTTP
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "sendf.h"
+#include "formdata.h"
+#include "mime.h"
+#include "progress.h"
+#include "curl_base64.h"
+#include "cookie.h"
+#include "vauth/vauth.h"
+#include "vtls/vtls.h"
+#include "http_digest.h"
+#include "http_ntlm.h"
+#include "curl_ntlm_wb.h"
+#include "http_negotiate.h"
+#include "url.h"
+#include "share.h"
+#include "hostip.h"
+#include "http.h"
+#include "select.h"
+#include "parsedate.h" /* for the week day and month names */
+#include "strtoofft.h"
+#include "multiif.h"
+#include "strcase.h"
+#include "content_encoding.h"
+#include "http_proxy.h"
+#include "warnless.h"
+#include "non-ascii.h"
+#include "pipeline.h"
+#include "http2.h"
+#include "connect.h"
+#include "strdup.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * Forward declarations.
+ */
+
+static int http_getsock_do(struct connectdata *conn,
+                           curl_socket_t *socks,
+                           int numsocks);
+static int http_should_fail(struct connectdata *conn);
+
+#ifdef USE_SSL
+static CURLcode https_connecting(struct connectdata *conn, bool *done);
+static int https_getsock(struct connectdata *conn,
+                         curl_socket_t *socks,
+                         int numsocks);
+#else
+#define https_connecting(x,y) CURLE_COULDNT_CONNECT
+#endif
+
+/*
+ * HTTP handler interface.
+ */
+const struct Curl_handler Curl_handler_http = {
+  "HTTP",                               /* scheme */
+  Curl_http_setup_conn,                 /* setup_connection */
+  Curl_http,                            /* do_it */
+  Curl_http_done,                       /* done */
+  ZERO_NULL,                            /* do_more */
+  Curl_http_connect,                    /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  http_getsock_do,                      /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_HTTP,                            /* defport */
+  CURLPROTO_HTTP,                       /* protocol */
+  PROTOPT_CREDSPERREQUEST               /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * HTTPS handler interface.
+ */
+const struct Curl_handler Curl_handler_https = {
+  "HTTPS",                              /* scheme */
+  Curl_http_setup_conn,                 /* setup_connection */
+  Curl_http,                            /* do_it */
+  Curl_http_done,                       /* done */
+  ZERO_NULL,                            /* do_more */
+  Curl_http_connect,                    /* connect_it */
+  https_connecting,                     /* connecting */
+  ZERO_NULL,                            /* doing */
+  https_getsock,                        /* proto_getsock */
+  http_getsock_do,                      /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_HTTPS,                           /* defport */
+  CURLPROTO_HTTPS,                      /* protocol */
+  PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN /* flags */
+};
+#endif
+
+CURLcode Curl_http_setup_conn(struct connectdata *conn)
+{
+  /* allocate the HTTP-specific struct for the Curl_easy, only to survive
+     during this request */
+  struct HTTP *http;
+  DEBUGASSERT(conn->data->req.protop == NULL);
+
+  http = calloc(1, sizeof(struct HTTP));
+  if(!http)
+    return CURLE_OUT_OF_MEMORY;
+
+  Curl_mime_initpart(&http->form, conn->data);
+  conn->data->req.protop = http;
+
+  Curl_http2_setup_conn(conn);
+  Curl_http2_setup_req(conn->data);
+
+  return CURLE_OK;
+}
+
+
+/*
+ * checkProxyHeaders() checks the linked list of custom proxy headers
+ * if proxy headers are not available, then it will lookup into http header
+ * link list
+ *
+ * It takes a connectdata struct as input instead of the Curl_easy simply
+ * to know if this is a proxy request or not, as it then might check a
+ * different header list.
+ */
+char *Curl_checkProxyheaders(const struct connectdata *conn,
+                             const char *thisheader)
+{
+  struct curl_slist *head;
+  size_t thislen = strlen(thisheader);
+  struct Curl_easy *data = conn->data;
+
+  for(head = (conn->bits.proxy && data->set.sep_headers) ?
+        data->set.proxyheaders : data->set.headers;
+      head; head = head->next) {
+    if(strncasecompare(head->data, thisheader, thislen))
+      return head->data;
+  }
+
+  return NULL;
+}
+
+/*
+ * Strip off leading and trailing whitespace from the value in the
+ * given HTTP header line and return a strdupped copy. Returns NULL in
+ * case of allocation failure. Returns an empty string if the header value
+ * consists entirely of whitespace.
+ */
+char *Curl_copy_header_value(const char *header)
+{
+  const char *start;
+  const char *end;
+  char *value;
+  size_t len;
+
+  DEBUGASSERT(header);
+
+  /* Find the end of the header name */
+  while(*header && (*header != ':'))
+    ++header;
+
+  if(*header)
+    /* Skip over colon */
+    ++header;
+
+  /* Find the first non-space letter */
+  start = header;
+  while(*start && ISSPACE(*start))
+    start++;
+
+  /* data is in the host encoding so
+     use '\r' and '\n' instead of 0x0d and 0x0a */
+  end = strchr(start, '\r');
+  if(!end)
+    end = strchr(start, '\n');
+  if(!end)
+    end = strchr(start, '\0');
+  if(!end)
+    return NULL;
+
+  /* skip all trailing space letters */
+  while((end > start) && ISSPACE(*end))
+    end--;
+
+  /* get length of the type */
+  len = end - start + 1;
+
+  value = malloc(len + 1);
+  if(!value)
+    return NULL;
+
+  memcpy(value, start, len);
+  value[len] = 0; /* zero terminate */
+
+  return value;
+}
+
+/*
+ * http_output_basic() sets up an Authorization: header (or the proxy version)
+ * for HTTP Basic authentication.
+ *
+ * Returns CURLcode.
+ */
+static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
+{
+  size_t size = 0;
+  char *authorization = NULL;
+  struct Curl_easy *data = conn->data;
+  char **userp;
+  const char *user;
+  const char *pwd;
+  CURLcode result;
+  char *out;
+
+  if(proxy) {
+    userp = &conn->allocptr.proxyuserpwd;
+    user = conn->http_proxy.user;
+    pwd = conn->http_proxy.passwd;
+  }
+  else {
+    userp = &conn->allocptr.userpwd;
+    user = conn->user;
+    pwd = conn->passwd;
+  }
+
+  out = aprintf("%s:%s", user, pwd);
+  if(!out)
+    return CURLE_OUT_OF_MEMORY;
+
+  result = Curl_base64_encode(data, out, strlen(out), &authorization, &size);
+  if(result)
+    goto fail;
+
+  if(!authorization) {
+    result = CURLE_REMOTE_ACCESS_DENIED;
+    goto fail;
+  }
+
+  free(*userp);
+  *userp = aprintf("%sAuthorization: Basic %s\r\n",
+                   proxy ? "Proxy-" : "",
+                   authorization);
+  free(authorization);
+  if(!*userp) {
+    result = CURLE_OUT_OF_MEMORY;
+    goto fail;
+  }
+
+  fail:
+  free(out);
+  return result;
+}
+
+/* pickoneauth() selects the most favourable authentication method from the
+ * ones available and the ones we want.
+ *
+ * return TRUE if one was picked
+ */
+static bool pickoneauth(struct auth *pick)
+{
+  bool picked;
+  /* only deal with authentication we want */
+  unsigned long avail = pick->avail & pick->want;
+  picked = TRUE;
+
+  /* The order of these checks is highly relevant, as this will be the order
+     of preference in case of the existence of multiple accepted types. */
+  if(avail & CURLAUTH_NEGOTIATE)
+    pick->picked = CURLAUTH_NEGOTIATE;
+  else if(avail & CURLAUTH_DIGEST)
+    pick->picked = CURLAUTH_DIGEST;
+  else if(avail & CURLAUTH_NTLM)
+    pick->picked = CURLAUTH_NTLM;
+  else if(avail & CURLAUTH_NTLM_WB)
+    pick->picked = CURLAUTH_NTLM_WB;
+  else if(avail & CURLAUTH_BASIC)
+    pick->picked = CURLAUTH_BASIC;
+  else {
+    pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */
+    picked = FALSE;
+  }
+  pick->avail = CURLAUTH_NONE; /* clear it here */
+
+  return picked;
+}
+
+/*
+ * Curl_http_perhapsrewind()
+ *
+ * If we are doing POST or PUT {
+ *   If we have more data to send {
+ *     If we are doing NTLM {
+ *       Keep sending since we must not disconnect
+ *     }
+ *     else {
+ *       If there is more than just a little data left to send, close
+ *       the current connection by force.
+ *     }
+ *   }
+ *   If we have sent any data {
+ *     If we don't have track of all the data {
+ *       call app to tell it to rewind
+ *     }
+ *     else {
+ *       rewind internally so that the operation can restart fine
+ *     }
+ *   }
+ * }
+ */
+static CURLcode http_perhapsrewind(struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  struct HTTP *http = data->req.protop;
+  curl_off_t bytessent;
+  curl_off_t expectsend = -1; /* default is unknown */
+
+  if(!http)
+    /* If this is still NULL, we have not reach very far and we can safely
+       skip this rewinding stuff */
+    return CURLE_OK;
+
+  switch(data->set.httpreq) {
+  case HTTPREQ_GET:
+  case HTTPREQ_HEAD:
+    return CURLE_OK;
+  default:
+    break;
+  }
+
+  bytessent = http->writebytecount;
+
+  if(conn->bits.authneg) {
+    /* This is a state where we are known to be negotiating and we don't send
+       any data then. */
+    expectsend = 0;
+  }
+  else if(!conn->bits.protoconnstart) {
+    /* HTTP CONNECT in progress: there is no body */
+    expectsend = 0;
+  }
+  else {
+    /* figure out how much data we are expected to send */
+    switch(data->set.httpreq) {
+    case HTTPREQ_POST:
+      if(data->state.infilesize != -1)
+        expectsend = data->state.infilesize;
+      break;
+    case HTTPREQ_PUT:
+      if(data->state.infilesize != -1)
+        expectsend = data->state.infilesize;
+      break;
+    case HTTPREQ_POST_FORM:
+    case HTTPREQ_POST_MIME:
+      expectsend = http->postsize;
+      break;
+    default:
+      break;
+    }
+  }
+
+  conn->bits.rewindaftersend = FALSE; /* default */
+
+  if((expectsend == -1) || (expectsend > bytessent)) {
+#if defined(USE_NTLM)
+    /* There is still data left to send */
+    if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
+       (data->state.authhost.picked == CURLAUTH_NTLM) ||
+       (data->state.authproxy.picked == CURLAUTH_NTLM_WB) ||
+       (data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
+      if(((expectsend - bytessent) < 2000) ||
+         (conn->ntlm.state != NTLMSTATE_NONE) ||
+         (conn->proxyntlm.state != NTLMSTATE_NONE)) {
+        /* The NTLM-negotiation has started *OR* there is just a little (<2K)
+           data left to send, keep on sending. */
+
+        /* rewind data when completely done sending! */
+        if(!conn->bits.authneg) {
+          conn->bits.rewindaftersend = TRUE;
+          infof(data, "Rewind stream after send\n");
+        }
+
+        return CURLE_OK;
+      }
+
+      if(conn->bits.close)
+        /* this is already marked to get closed */
+        return CURLE_OK;
+
+      infof(data, "NTLM send, close instead of sending %"
+            CURL_FORMAT_CURL_OFF_T " bytes\n",
+            (curl_off_t)(expectsend - bytessent));
+    }
+#endif
+
+    /* This is not NTLM or many bytes left to send: close */
+    streamclose(conn, "Mid-auth HTTP and much data left to send");
+    data->req.size = 0; /* don't download any more than 0 bytes */
+
+    /* There still is data left to send, but this connection is marked for
+       closure so we can safely do the rewind right now */
+  }
+
+  if(bytessent)
+    /* we rewind now at once since if we already sent something */
+    return Curl_readrewind(conn);
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_http_auth_act() gets called when all HTTP headers have been received
+ * and it checks what authentication methods that are available and decides
+ * which one (if any) to use. It will set 'newurl' if an auth method was
+ * picked.
+ */
+
+CURLcode Curl_http_auth_act(struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  bool pickhost = FALSE;
+  bool pickproxy = FALSE;
+  CURLcode result = CURLE_OK;
+
+  if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
+    /* this is a transient response code, ignore */
+    return CURLE_OK;
+
+  if(data->state.authproblem)
+    return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
+
+  if(conn->bits.user_passwd &&
+     ((data->req.httpcode == 401) ||
+      (conn->bits.authneg && data->req.httpcode < 300))) {
+    pickhost = pickoneauth(&data->state.authhost);
+    if(!pickhost)
+      data->state.authproblem = TRUE;
+  }
+  if(conn->bits.proxy_user_passwd &&
+     ((data->req.httpcode == 407) ||
+      (conn->bits.authneg && data->req.httpcode < 300))) {
+    pickproxy = pickoneauth(&data->state.authproxy);
+    if(!pickproxy)
+      data->state.authproblem = TRUE;
+  }
+
+  if(pickhost || pickproxy) {
+    /* In case this is GSS auth, the newurl field is already allocated so
+       we must make sure to free it before allocating a new one. As figured
+       out in bug #2284386 */
+    Curl_safefree(data->req.newurl);
+    data->req.newurl = strdup(data->change.url); /* clone URL */
+    if(!data->req.newurl)
+      return CURLE_OUT_OF_MEMORY;
+
+    if((data->set.httpreq != HTTPREQ_GET) &&
+       (data->set.httpreq != HTTPREQ_HEAD) &&
+       !conn->bits.rewindaftersend) {
+      result = http_perhapsrewind(conn);
+      if(result)
+        return result;
+    }
+  }
+  else if((data->req.httpcode < 300) &&
+          (!data->state.authhost.done) &&
+          conn->bits.authneg) {
+    /* no (known) authentication available,
+       authentication is not "done" yet and
+       no authentication seems to be required and
+       we didn't try HEAD or GET */
+    if((data->set.httpreq != HTTPREQ_GET) &&
+       (data->set.httpreq != HTTPREQ_HEAD)) {
+      data->req.newurl = strdup(data->change.url); /* clone URL */
+      if(!data->req.newurl)
+        return CURLE_OUT_OF_MEMORY;
+      data->state.authhost.done = TRUE;
+    }
+  }
+  if(http_should_fail(conn)) {
+    failf(data, "The requested URL returned error: %d",
+          data->req.httpcode);
+    result = CURLE_HTTP_RETURNED_ERROR;
+  }
+
+  return result;
+}
+
+/*
+ * Output the correct authentication header depending on the auth type
+ * and whether or not it is to a proxy.
+ */
+static CURLcode
+output_auth_headers(struct connectdata *conn,
+                    struct auth *authstatus,
+                    const char *request,
+                    const char *path,
+                    bool proxy)
+{
+  const char *auth = NULL;
+  CURLcode result = CURLE_OK;
+#if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO)
+  struct Curl_easy *data = conn->data;
+#endif
+#ifdef USE_SPNEGO
+  struct negotiatedata *negdata = proxy ?
+    &data->state.proxyneg : &data->state.negotiate;
+#endif
+
+#ifdef CURL_DISABLE_CRYPTO_AUTH
+  (void)request;
+  (void)path;
+#endif
+
+#ifdef USE_SPNEGO
+  negdata->state = GSS_AUTHNONE;
+  if((authstatus->picked == CURLAUTH_NEGOTIATE) &&
+     negdata->context && !GSS_ERROR(negdata->status)) {
+    auth = "Negotiate";
+    result = Curl_output_negotiate(conn, proxy);
+    if(result)
+      return result;
+    authstatus->done = TRUE;
+    negdata->state = GSS_AUTHSENT;
+  }
+  else
+#endif
+#ifdef USE_NTLM
+  if(authstatus->picked == CURLAUTH_NTLM) {
+    auth = "NTLM";
+    result = Curl_output_ntlm(conn, proxy);
+    if(result)
+      return result;
+  }
+  else
+#endif
+#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
+  if(authstatus->picked == CURLAUTH_NTLM_WB) {
+    auth = "NTLM_WB";
+    result = Curl_output_ntlm_wb(conn, proxy);
+    if(result)
+      return result;
+  }
+  else
+#endif
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+  if(authstatus->picked == CURLAUTH_DIGEST) {
+    auth = "Digest";
+    result = Curl_output_digest(conn,
+                                proxy,
+                                (const unsigned char *)request,
+                                (const unsigned char *)path);
+    if(result)
+      return result;
+  }
+  else
+#endif
+  if(authstatus->picked == CURLAUTH_BASIC) {
+    /* Basic */
+    if((proxy && conn->bits.proxy_user_passwd &&
+        !Curl_checkProxyheaders(conn, "Proxy-authorization:")) ||
+       (!proxy && conn->bits.user_passwd &&
+        !Curl_checkheaders(conn, "Authorization:"))) {
+      auth = "Basic";
+      result = http_output_basic(conn, proxy);
+      if(result)
+        return result;
+    }
+
+    /* NOTE: this function should set 'done' TRUE, as the other auth
+       functions work that way */
+    authstatus->done = TRUE;
+  }
+
+  if(auth) {
+    infof(data, "%s auth using %s with user '%s'\n",
+          proxy ? "Proxy" : "Server", auth,
+          proxy ? (conn->http_proxy.user ? conn->http_proxy.user : "") :
+                  (conn->user ? conn->user : ""));
+    authstatus->multipass = (!authstatus->done) ? TRUE : FALSE;
+  }
+  else
+    authstatus->multipass = FALSE;
+
+  return CURLE_OK;
+}
+
+/**
+ * Curl_http_output_auth() setups the authentication headers for the
+ * host/proxy and the correct authentication
+ * method. conn->data->state.authdone is set to TRUE when authentication is
+ * done.
+ *
+ * @param conn all information about the current connection
+ * @param request pointer to the request keyword
+ * @param path pointer to the requested path
+ * @param proxytunnel boolean if this is the request setting up a "proxy
+ * tunnel"
+ *
+ * @returns CURLcode
+ */
+CURLcode
+Curl_http_output_auth(struct connectdata *conn,
+                      const char *request,
+                      const char *path,
+                      bool proxytunnel) /* TRUE if this is the request setting
+                                           up the proxy tunnel */
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct auth *authhost;
+  struct auth *authproxy;
+
+  DEBUGASSERT(data);
+
+  authhost = &data->state.authhost;
+  authproxy = &data->state.authproxy;
+
+  if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
+     conn->bits.user_passwd)
+    /* continue please */;
+  else {
+    authhost->done = TRUE;
+    authproxy->done = TRUE;
+    return CURLE_OK; /* no authentication with no user or password */
+  }
+
+  if(authhost->want && !authhost->picked)
+    /* The app has selected one or more methods, but none has been picked
+       so far by a server round-trip. Then we set the picked one to the
+       want one, and if this is one single bit it'll be used instantly. */
+    authhost->picked = authhost->want;
+
+  if(authproxy->want && !authproxy->picked)
+    /* The app has selected one or more methods, but none has been picked so
+       far by a proxy round-trip. Then we set the picked one to the want one,
+       and if this is one single bit it'll be used instantly. */
+    authproxy->picked = authproxy->want;
+
+#ifndef CURL_DISABLE_PROXY
+  /* Send proxy authentication header if needed */
+  if(conn->bits.httpproxy &&
+      (conn->bits.tunnel_proxy == proxytunnel)) {
+    result = output_auth_headers(conn, authproxy, request, path, TRUE);
+    if(result)
+      return result;
+  }
+  else
+#else
+  (void)proxytunnel;
+#endif /* CURL_DISABLE_PROXY */
+    /* we have no proxy so let's pretend we're done authenticating
+       with it */
+    authproxy->done = TRUE;
+
+  /* To prevent the user+password to get sent to other than the original
+     host due to a location-follow, we do some weirdo checks here */
+  if(!data->state.this_is_a_follow ||
+     conn->bits.netrc ||
+     !data->state.first_host ||
+     data->set.http_disable_hostname_check_before_authentication ||
+     strcasecompare(data->state.first_host, conn->host.name)) {
+    result = output_auth_headers(conn, authhost, request, path, FALSE);
+  }
+  else
+    authhost->done = TRUE;
+
+  return result;
+}
+
+/*
+ * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate:
+ * headers. They are dealt with both in the transfer.c main loop and in the
+ * proxy CONNECT loop.
+ */
+
+CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
+                              const char *auth) /* the first non-space */
+{
+  /*
+   * This resource requires authentication
+   */
+  struct Curl_easy *data = conn->data;
+
+#ifdef USE_SPNEGO
+  struct negotiatedata *negdata = proxy?
+    &data->state.proxyneg:&data->state.negotiate;
+#endif
+  unsigned long *availp;
+  struct auth *authp;
+
+  if(proxy) {
+    availp = &data->info.proxyauthavail;
+    authp = &data->state.authproxy;
+  }
+  else {
+    availp = &data->info.httpauthavail;
+    authp = &data->state.authhost;
+  }
+
+  /*
+   * Here we check if we want the specific single authentication (using ==) and
+   * if we do, we initiate usage of it.
+   *
+   * If the provided authentication is wanted as one out of several accepted
+   * types (using &), we OR this authentication type to the authavail
+   * variable.
+   *
+   * Note:
+   *
+   * ->picked is first set to the 'want' value (one or more bits) before the
+   * request is sent, and then it is again set _after_ all response 401/407
+   * headers have been received but then only to a single preferred method
+   * (bit).
+   */
+
+  while(*auth) {
+#ifdef USE_SPNEGO
+    if(checkprefix("Negotiate", auth)) {
+      if((authp->avail & CURLAUTH_NEGOTIATE) ||
+         Curl_auth_is_spnego_supported()) {
+        *availp |= CURLAUTH_NEGOTIATE;
+        authp->avail |= CURLAUTH_NEGOTIATE;
+
+        if(authp->picked == CURLAUTH_NEGOTIATE) {
+          if(negdata->state == GSS_AUTHSENT ||
+             negdata->state == GSS_AUTHNONE) {
+            CURLcode result = Curl_input_negotiate(conn, proxy, auth);
+            if(!result) {
+              DEBUGASSERT(!data->req.newurl);
+              data->req.newurl = strdup(data->change.url);
+              if(!data->req.newurl)
+                return CURLE_OUT_OF_MEMORY;
+              data->state.authproblem = FALSE;
+              /* we received a GSS auth token and we dealt with it fine */
+              negdata->state = GSS_AUTHRECV;
+            }
+            else
+              data->state.authproblem = TRUE;
+          }
+        }
+      }
+    }
+    else
+#endif
+#ifdef USE_NTLM
+      /* NTLM support requires the SSL crypto libs */
+      if(checkprefix("NTLM", auth)) {
+        if((authp->avail & CURLAUTH_NTLM) ||
+           (authp->avail & CURLAUTH_NTLM_WB) ||
+           Curl_auth_is_ntlm_supported()) {
+          *availp |= CURLAUTH_NTLM;
+          authp->avail |= CURLAUTH_NTLM;
+
+          if(authp->picked == CURLAUTH_NTLM ||
+             authp->picked == CURLAUTH_NTLM_WB) {
+            /* NTLM authentication is picked and activated */
+            CURLcode result = Curl_input_ntlm(conn, proxy, auth);
+            if(!result) {
+              data->state.authproblem = FALSE;
+#ifdef NTLM_WB_ENABLED
+              if(authp->picked == CURLAUTH_NTLM_WB) {
+                *availp &= ~CURLAUTH_NTLM;
+                authp->avail &= ~CURLAUTH_NTLM;
+                *availp |= CURLAUTH_NTLM_WB;
+                authp->avail |= CURLAUTH_NTLM_WB;
+
+                /* Get the challenge-message which will be passed to
+                 * ntlm_auth for generating the type 3 message later */
+                while(*auth && ISSPACE(*auth))
+                  auth++;
+                if(checkprefix("NTLM", auth)) {
+                  auth += strlen("NTLM");
+                  while(*auth && ISSPACE(*auth))
+                    auth++;
+                  if(*auth) {
+                    conn->challenge_header = strdup(auth);
+                    if(!conn->challenge_header)
+                      return CURLE_OUT_OF_MEMORY;
+                  }
+                }
+              }
+#endif
+            }
+            else {
+              infof(data, "Authentication problem. Ignoring this.\n");
+              data->state.authproblem = TRUE;
+            }
+          }
+        }
+      }
+      else
+#endif
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+        if(checkprefix("Digest", auth)) {
+          if((authp->avail & CURLAUTH_DIGEST) != 0)
+            infof(data, "Ignoring duplicate digest auth header.\n");
+          else if(Curl_auth_is_digest_supported()) {
+            CURLcode result;
+
+            *availp |= CURLAUTH_DIGEST;
+            authp->avail |= CURLAUTH_DIGEST;
+
+            /* We call this function on input Digest headers even if Digest
+             * authentication isn't activated yet, as we need to store the
+             * incoming data from this header in case we are going to use
+             * Digest */
+            result = Curl_input_digest(conn, proxy, auth);
+            if(result) {
+              infof(data, "Authentication problem. Ignoring this.\n");
+              data->state.authproblem = TRUE;
+            }
+          }
+        }
+        else
+#endif
+          if(checkprefix("Basic", auth)) {
+            *availp |= CURLAUTH_BASIC;
+            authp->avail |= CURLAUTH_BASIC;
+            if(authp->picked == CURLAUTH_BASIC) {
+              /* We asked for Basic authentication but got a 40X back
+                 anyway, which basically means our name+password isn't
+                 valid. */
+              authp->avail = CURLAUTH_NONE;
+              infof(data, "Authentication problem. Ignoring this.\n");
+              data->state.authproblem = TRUE;
+            }
+          }
+
+    /* there may be multiple methods on one line, so keep reading */
+    while(*auth && *auth != ',') /* read up to the next comma */
+      auth++;
+    if(*auth == ',') /* if we're on a comma, skip it */
+      auth++;
+    while(*auth && ISSPACE(*auth))
+      auth++;
+  }
+
+  return CURLE_OK;
+}
+
+/**
+ * http_should_fail() determines whether an HTTP response has gotten us
+ * into an error state or not.
+ *
+ * @param conn all information about the current connection
+ *
+ * @retval 0 communications should continue
+ *
+ * @retval 1 communications should not continue
+ */
+static int http_should_fail(struct connectdata *conn)
+{
+  struct Curl_easy *data;
+  int httpcode;
+
+  DEBUGASSERT(conn);
+  data = conn->data;
+  DEBUGASSERT(data);
+
+  httpcode = data->req.httpcode;
+
+  /*
+  ** If we haven't been asked to fail on error,
+  ** don't fail.
+  */
+  if(!data->set.http_fail_on_error)
+    return 0;
+
+  /*
+  ** Any code < 400 is never terminal.
+  */
+  if(httpcode < 400)
+    return 0;
+
+  /*
+  ** Any code >= 400 that's not 401 or 407 is always
+  ** a terminal error
+  */
+  if((httpcode != 401) && (httpcode != 407))
+    return 1;
+
+  /*
+  ** All we have left to deal with is 401 and 407
+  */
+  DEBUGASSERT((httpcode == 401) || (httpcode == 407));
+
+  /*
+  ** Examine the current authentication state to see if this
+  ** is an error.  The idea is for this function to get
+  ** called after processing all the headers in a response
+  ** message.  So, if we've been to asked to authenticate a
+  ** particular stage, and we've done it, we're OK.  But, if
+  ** we're already completely authenticated, it's not OK to
+  ** get another 401 or 407.
+  **
+  ** It is possible for authentication to go stale such that
+  ** the client needs to reauthenticate.  Once that info is
+  ** available, use it here.
+  */
+
+  /*
+  ** Either we're not authenticating, or we're supposed to
+  ** be authenticating something else.  This is an error.
+  */
+  if((httpcode == 401) && !conn->bits.user_passwd)
+    return TRUE;
+  if((httpcode == 407) && !conn->bits.proxy_user_passwd)
+    return TRUE;
+
+  return data->state.authproblem;
+}
+
+/*
+ * readmoredata() is a "fread() emulation" to provide POST and/or request
+ * data. It is used when a huge POST is to be made and the entire chunk wasn't
+ * sent in the first send(). This function will then be called from the
+ * transfer.c loop when more data is to be sent to the peer.
+ *
+ * Returns the amount of bytes it filled the buffer with.
+ */
+static size_t readmoredata(char *buffer,
+                           size_t size,
+                           size_t nitems,
+                           void *userp)
+{
+  struct connectdata *conn = (struct connectdata *)userp;
+  struct HTTP *http = conn->data->req.protop;
+  size_t fullsize = size * nitems;
+
+  if(!http->postsize)
+    /* nothing to return */
+    return 0;
+
+  /* make sure that a HTTP request is never sent away chunked! */
+  conn->data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
+
+  if(http->postsize <= (curl_off_t)fullsize) {
+    memcpy(buffer, http->postdata, (size_t)http->postsize);
+    fullsize = (size_t)http->postsize;
+
+    if(http->backup.postsize) {
+      /* move backup data into focus and continue on that */
+      http->postdata = http->backup.postdata;
+      http->postsize = http->backup.postsize;
+      conn->data->state.fread_func = http->backup.fread_func;
+      conn->data->state.in = http->backup.fread_in;
+
+      http->sending++; /* move one step up */
+
+      http->backup.postsize = 0;
+    }
+    else
+      http->postsize = 0;
+
+    return fullsize;
+  }
+
+  memcpy(buffer, http->postdata, fullsize);
+  http->postdata += fullsize;
+  http->postsize -= fullsize;
+
+  return fullsize;
+}
+
+/* ------------------------------------------------------------------------- */
+/* add_buffer functions */
+
+/*
+ * Curl_add_buffer_init() sets up and returns a fine buffer struct
+ */
+Curl_send_buffer *Curl_add_buffer_init(void)
+{
+  return calloc(1, sizeof(Curl_send_buffer));
+}
+
+/*
+ * Curl_add_buffer_free() frees all associated resources.
+ */
+void Curl_add_buffer_free(Curl_send_buffer *buff)
+{
+  if(buff) /* deal with NULL input */
+    free(buff->buffer);
+  free(buff);
+}
+
+/*
+ * Curl_add_buffer_send() sends a header buffer and frees all associated
+ * memory.  Body data may be appended to the header data if desired.
+ *
+ * Returns CURLcode
+ */
+CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
+                              struct connectdata *conn,
+
+                               /* add the number of sent bytes to this
+                                  counter */
+                              long *bytes_written,
+
+                               /* how much of the buffer contains body data */
+                              size_t included_body_bytes,
+                              int socketindex)
+
+{
+  ssize_t amount;
+  CURLcode result;
+  char *ptr;
+  size_t size;
+  struct HTTP *http = conn->data->req.protop;
+  size_t sendsize;
+  curl_socket_t sockfd;
+  size_t headersize;
+
+  DEBUGASSERT(socketindex <= SECONDARYSOCKET);
+
+  sockfd = conn->sock[socketindex];
+
+  /* The looping below is required since we use non-blocking sockets, but due
+     to the circumstances we will just loop and try again and again etc */
+
+  ptr = in->buffer;
+  size = in->size_used;
+
+  headersize = size - included_body_bytes; /* the initial part that isn't body
+                                              is header */
+
+  DEBUGASSERT(size > included_body_bytes);
+
+  result = Curl_convert_to_network(conn->data, ptr, headersize);
+  /* Curl_convert_to_network calls failf if unsuccessful */
+  if(result) {
+    /* conversion failed, free memory and return to the caller */
+    Curl_add_buffer_free(in);
+    return result;
+  }
+
+  if((conn->handler->flags & PROTOPT_SSL ||
+     conn->http_proxy.proxytype == CURLPROXY_HTTPS)
+     && conn->httpversion != 20) {
+    /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
+       when we speak HTTPS, as if only a fraction of it is sent now, this data
+       needs to fit into the normal read-callback buffer later on and that
+       buffer is using this size.
+    */
+
+    sendsize = CURLMIN(size, CURL_MAX_WRITE_SIZE);
+
+    /* OpenSSL is very picky and we must send the SAME buffer pointer to the
+       library when we attempt to re-send this buffer. Sending the same data
+       is not enough, we must use the exact same address. For this reason, we
+       must copy the data to the uploadbuffer first, since that is the buffer
+       we will be using if this send is retried later.
+    */
+    memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
+    ptr = conn->data->state.uploadbuffer;
+  }
+  else
+    sendsize = size;
+
+  result = Curl_write(conn, sockfd, ptr, sendsize, &amount);
+
+  if(!result) {
+    /*
+     * Note that we may not send the entire chunk at once, and we have a set
+     * number of data bytes at the end of the big buffer (out of which we may
+     * only send away a part).
+     */
+    /* how much of the header that was sent */
+    size_t headlen = (size_t)amount>headersize ? headersize : (size_t)amount;
+    size_t bodylen = amount - headlen;
+
+    if(conn->data->set.verbose) {
+      /* this data _may_ contain binary stuff */
+      Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn);
+      if(bodylen) {
+        /* there was body data sent beyond the initial header part, pass that
+           on to the debug callback too */
+        Curl_debug(conn->data, CURLINFO_DATA_OUT,
+                   ptr + headlen, bodylen, conn);
+      }
+    }
+
+    /* 'amount' can never be a very large value here so typecasting it so a
+       signed 31 bit value should not cause problems even if ssize_t is
+       64bit */
+    *bytes_written += (long)amount;
+
+    if(http) {
+      /* if we sent a piece of the body here, up the byte counter for it
+         accordingly */
+      http->writebytecount += bodylen;
+
+      if((size_t)amount != size) {
+        /* The whole request could not be sent in one system call. We must
+           queue it up and send it later when we get the chance. We must not
+           loop here and wait until it might work again. */
+
+        size -= amount;
+
+        ptr = in->buffer + amount;
+
+        /* backup the currently set pointers */
+        http->backup.fread_func = conn->data->state.fread_func;
+        http->backup.fread_in = conn->data->state.in;
+        http->backup.postdata = http->postdata;
+        http->backup.postsize = http->postsize;
+
+        /* set the new pointers for the request-sending */
+        conn->data->state.fread_func = (curl_read_callback)readmoredata;
+        conn->data->state.in = (void *)conn;
+        http->postdata = ptr;
+        http->postsize = (curl_off_t)size;
+
+        http->send_buffer = in;
+        http->sending = HTTPSEND_REQUEST;
+
+        return CURLE_OK;
+      }
+      http->sending = HTTPSEND_BODY;
+      /* the full buffer was sent, clean up and return */
+    }
+    else {
+      if((size_t)amount != size)
+        /* We have no continue-send mechanism now, fail. This can only happen
+           when this function is used from the CONNECT sending function. We
+           currently (stupidly) assume that the whole request is always sent
+           away in the first single chunk.
+
+           This needs FIXing.
+        */
+        return CURLE_SEND_ERROR;
+      Curl_pipeline_leave_write(conn);
+    }
+  }
+  Curl_add_buffer_free(in);
+
+  return result;
+}
+
+
+/*
+ * add_bufferf() add the formatted input to the buffer.
+ */
+CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
+{
+  char *s;
+  va_list ap;
+  va_start(ap, fmt);
+  s = vaprintf(fmt, ap); /* this allocs a new string to append */
+  va_end(ap);
+
+  if(s) {
+    CURLcode result = Curl_add_buffer(in, s, strlen(s));
+    free(s);
+    return result;
+  }
+  /* If we failed, we cleanup the whole buffer and return error */
+  free(in->buffer);
+  free(in);
+  return CURLE_OUT_OF_MEMORY;
+}
+
+/*
+ * add_buffer() appends a memory chunk to the existing buffer
+ */
+CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
+{
+  char *new_rb;
+  size_t new_size;
+
+  if(~size < in->size_used) {
+    /* If resulting used size of send buffer would wrap size_t, cleanup
+       the whole buffer and return error. Otherwise the required buffer
+       size will fit into a single allocatable memory chunk */
+    Curl_safefree(in->buffer);
+    free(in);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  if(!in->buffer ||
+     ((in->size_used + size) > (in->size_max - 1))) {
+
+    /* If current buffer size isn't enough to hold the result, use a
+       buffer size that doubles the required size. If this new size
+       would wrap size_t, then just use the largest possible one */
+
+    if((size > (size_t)-1 / 2) || (in->size_used > (size_t)-1 / 2) ||
+       (~(size * 2) < (in->size_used * 2)))
+      new_size = (size_t)-1;
+    else
+      new_size = (in->size_used + size) * 2;
+
+    if(in->buffer)
+      /* we have a buffer, enlarge the existing one */
+      new_rb = Curl_saferealloc(in->buffer, new_size);
+    else
+      /* create a new buffer */
+      new_rb = malloc(new_size);
+
+    if(!new_rb) {
+      /* If we failed, we cleanup the whole buffer and return error */
+      free(in);
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    in->buffer = new_rb;
+    in->size_max = new_size;
+  }
+  memcpy(&in->buffer[in->size_used], inptr, size);
+
+  in->size_used += size;
+
+  return CURLE_OK;
+}
+
+/* end of the add_buffer functions */
+/* ------------------------------------------------------------------------- */
+
+
+
+/*
+ * Curl_compareheader()
+ *
+ * Returns TRUE if 'headerline' contains the 'header' with given 'content'.
+ * Pass headers WITH the colon.
+ */
+bool
+Curl_compareheader(const char *headerline, /* line to check */
+                   const char *header,  /* header keyword _with_ colon */
+                   const char *content) /* content string to find */
+{
+  /* RFC2616, section 4.2 says: "Each header field consists of a name followed
+   * by a colon (":") and the field value. Field names are case-insensitive.
+   * The field value MAY be preceded by any amount of LWS, though a single SP
+   * is preferred." */
+
+  size_t hlen = strlen(header);
+  size_t clen;
+  size_t len;
+  const char *start;
+  const char *end;
+
+  if(!strncasecompare(headerline, header, hlen))
+    return FALSE; /* doesn't start with header */
+
+  /* pass the header */
+  start = &headerline[hlen];
+
+  /* pass all white spaces */
+  while(*start && ISSPACE(*start))
+    start++;
+
+  /* find the end of the header line */
+  end = strchr(start, '\r'); /* lines end with CRLF */
+  if(!end) {
+    /* in case there's a non-standard compliant line here */
+    end = strchr(start, '\n');
+
+    if(!end)
+      /* hm, there's no line ending here, use the zero byte! */
+      end = strchr(start, '\0');
+  }
+
+  len = end-start; /* length of the content part of the input line */
+  clen = strlen(content); /* length of the word to find */
+
+  /* find the content string in the rest of the line */
+  for(; len >= clen; len--, start++) {
+    if(strncasecompare(start, content, clen))
+      return TRUE; /* match! */
+  }
+
+  return FALSE; /* no match */
+}
+
+/*
+ * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
+ * the generic Curl_connect().
+ */
+CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
+{
+  CURLcode result;
+
+  /* We default to persistent connections. We set this already in this connect
+     function to make the re-use checks properly be able to check this bit. */
+  connkeep(conn, "HTTP default");
+
+  /* the CONNECT procedure might not have been completed */
+  result = Curl_proxy_connect(conn, FIRSTSOCKET);
+  if(result)
+    return result;
+
+  if(conn->bits.proxy_connect_closed)
+    /* this is not an error, just part of the connection negotiation */
+    return CURLE_OK;
+
+  if(CONNECT_FIRSTSOCKET_PROXY_SSL())
+    return CURLE_OK; /* wait for HTTPS proxy SSL initialization to complete */
+
+  if(Curl_connect_ongoing(conn))
+    /* nothing else to do except wait right now - we're not done here. */
+    return CURLE_OK;
+
+  if(conn->given->protocol & CURLPROTO_HTTPS) {
+    /* perform SSL initialization */
+    result = https_connecting(conn, done);
+    if(result)
+      return result;
+  }
+  else
+    *done = TRUE;
+
+  return CURLE_OK;
+}
+
+/* this returns the socket to wait for in the DO and DOING state for the multi
+   interface and then we're always _sending_ a request and thus we wait for
+   the single socket to become writable only */
+static int http_getsock_do(struct connectdata *conn,
+                           curl_socket_t *socks,
+                           int numsocks)
+{
+  /* write mode */
+  (void)numsocks; /* unused, we trust it to be at least 1 */
+  socks[0] = conn->sock[FIRSTSOCKET];
+  return GETSOCK_WRITESOCK(0);
+}
+
+#ifdef USE_SSL
+static CURLcode https_connecting(struct connectdata *conn, bool *done)
+{
+  CURLcode result;
+  DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
+
+  /* perform SSL initialization for this socket */
+  result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
+  if(result)
+    connclose(conn, "Failed HTTPS connection");
+
+  return result;
+}
+
+static int https_getsock(struct connectdata *conn,
+                         curl_socket_t *socks,
+                         int numsocks)
+{
+  if(conn->handler->flags & PROTOPT_SSL)
+    return Curl_ssl_getsock(conn, socks, numsocks);
+  return GETSOCK_BLANK;
+}
+#endif /* USE_SSL */
+
+/*
+ * Curl_http_done() gets called after a single HTTP request has been
+ * performed.
+ */
+
+CURLcode Curl_http_done(struct connectdata *conn,
+                        CURLcode status, bool premature)
+{
+  struct Curl_easy *data = conn->data;
+  struct HTTP *http = data->req.protop;
+
+  /* Clear multipass flag. If authentication isn't done yet, then it will get
+   * a chance to be set back to true when we output the next auth header */
+  data->state.authhost.multipass = FALSE;
+  data->state.authproxy.multipass = FALSE;
+
+  Curl_unencode_cleanup(conn);
+
+#ifdef USE_SPNEGO
+  if(data->state.proxyneg.state == GSS_AUTHSENT ||
+     data->state.negotiate.state == GSS_AUTHSENT) {
+    /* add forbid re-use if http-code != 401/407 as a WA only needed for
+     * 401/407 that signal auth failure (empty) otherwise state will be RECV
+     * with current code.
+     * Do not close CONNECT_ONLY connections. */
+    if((data->req.httpcode != 401) && (data->req.httpcode != 407) &&
+       !data->set.connect_only)
+      streamclose(conn, "Negotiate transfer completed");
+    Curl_cleanup_negotiate(data);
+  }
+#endif
+
+  /* set the proper values (possibly modified on POST) */
+  conn->seek_func = data->set.seek_func; /* restore */
+  conn->seek_client = data->set.seek_client; /* restore */
+
+  if(!http)
+    return CURLE_OK;
+
+  if(http->send_buffer) {
+    Curl_add_buffer_free(http->send_buffer);
+    http->send_buffer = NULL; /* clear the pointer */
+  }
+
+  Curl_http2_done(conn, premature);
+
+  Curl_mime_cleanpart(&http->form);
+
+  switch(data->set.httpreq) {
+  case HTTPREQ_PUT:
+  case HTTPREQ_POST_FORM:
+  case HTTPREQ_POST_MIME:
+    data->req.bytecount = http->readbytecount + http->writebytecount;
+    break;
+  default:
+    break;
+  }
+
+  if(status)
+    return status;
+
+  if(!premature && /* this check is pointless when DONE is called before the
+                      entire operation is complete */
+     !conn->bits.retry &&
+     !data->set.connect_only &&
+     (http->readbytecount +
+      data->req.headerbytecount -
+      data->req.deductheadercount) <= 0) {
+    /* If this connection isn't simply closed to be retried, AND nothing was
+       read from the HTTP server (that counts), this can't be right so we
+       return an error here */
+    failf(data, "Empty reply from server");
+    return CURLE_GOT_NOTHING;
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Determine if we should use HTTP 1.1 (OR BETTER) for this request. Reasons
+ * to avoid it include:
+ *
+ * - if the user specifically requested HTTP 1.0
+ * - if the server we are connected to only supports 1.0
+ * - if any server previously contacted to handle this request only supports
+ * 1.0.
+ */
+static bool use_http_1_1plus(const struct Curl_easy *data,
+                             const struct connectdata *conn)
+{
+  if((data->state.httpversion == 10) || (conn->httpversion == 10))
+    return FALSE;
+  if((data->set.httpversion == CURL_HTTP_VERSION_1_0) &&
+     (conn->httpversion <= 10))
+    return FALSE;
+  return ((data->set.httpversion == CURL_HTTP_VERSION_NONE) ||
+          (data->set.httpversion >= CURL_HTTP_VERSION_1_1));
+}
+
+static const char *get_http_string(const struct Curl_easy *data,
+                                   const struct connectdata *conn)
+{
+#ifdef USE_NGHTTP2
+  if(conn->proto.httpc.h2)
+    return "2";
+#endif
+
+  if(use_http_1_1plus(data, conn))
+    return "1.1";
+
+  return "1.0";
+}
+
+/* check and possibly add an Expect: header */
+static CURLcode expect100(struct Curl_easy *data,
+                          struct connectdata *conn,
+                          Curl_send_buffer *req_buffer)
+{
+  CURLcode result = CURLE_OK;
+  const char *ptr;
+  data->state.expect100header = FALSE; /* default to false unless it is set
+                                          to TRUE below */
+  if(use_http_1_1plus(data, conn) &&
+     (conn->httpversion != 20)) {
+    /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
+       Expect: 100-continue to the headers which actually speeds up post
+       operations (as there is one packet coming back from the web server) */
+    ptr = Curl_checkheaders(conn, "Expect:");
+    if(ptr) {
+      data->state.expect100header =
+        Curl_compareheader(ptr, "Expect:", "100-continue");
+    }
+    else {
+      result = Curl_add_bufferf(req_buffer,
+                         "Expect: 100-continue\r\n");
+      if(!result)
+        data->state.expect100header = TRUE;
+    }
+  }
+
+  return result;
+}
+
+enum proxy_use {
+  HEADER_SERVER,  /* direct to server */
+  HEADER_PROXY,   /* regular request to proxy */
+  HEADER_CONNECT  /* sending CONNECT to a proxy */
+};
+
+CURLcode Curl_add_custom_headers(struct connectdata *conn,
+                                 bool is_connect,
+                                 Curl_send_buffer *req_buffer)
+{
+  char *ptr;
+  struct curl_slist *h[2];
+  struct curl_slist *headers;
+  int numlists = 1; /* by default */
+  struct Curl_easy *data = conn->data;
+  int i;
+
+  enum proxy_use proxy;
+
+  if(is_connect)
+    proxy = HEADER_CONNECT;
+  else
+    proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy?
+      HEADER_PROXY:HEADER_SERVER;
+
+  switch(proxy) {
+  case HEADER_SERVER:
+    h[0] = data->set.headers;
+    break;
+  case HEADER_PROXY:
+    h[0] = data->set.headers;
+    if(data->set.sep_headers) {
+      h[1] = data->set.proxyheaders;
+      numlists++;
+    }
+    break;
+  case HEADER_CONNECT:
+    if(data->set.sep_headers)
+      h[0] = data->set.proxyheaders;
+    else
+      h[0] = data->set.headers;
+    break;
+  }
+
+  /* loop through one or two lists */
+  for(i = 0; i < numlists; i++) {
+    headers = h[i];
+
+    while(headers) {
+      ptr = strchr(headers->data, ':');
+      if(ptr) {
+        /* we require a colon for this to be a true header */
+
+        ptr++; /* pass the colon */
+        while(*ptr && ISSPACE(*ptr))
+          ptr++;
+
+        if(*ptr) {
+          /* only send this if the contents was non-blank */
+
+          if(conn->allocptr.host &&
+             /* a Host: header was sent already, don't pass on any custom Host:
+                header as that will produce *two* in the same request! */
+             checkprefix("Host:", headers->data))
+            ;
+          else if(data->set.httpreq == HTTPREQ_POST_FORM &&
+                  /* this header (extended by formdata.c) is sent later */
+                  checkprefix("Content-Type:", headers->data))
+            ;
+          else if(data->set.httpreq == HTTPREQ_POST_MIME &&
+                  /* this header is sent later */
+                  checkprefix("Content-Type:", headers->data))
+            ;
+          else if(conn->bits.authneg &&
+                  /* while doing auth neg, don't allow the custom length since
+                     we will force length zero then */
+                  checkprefix("Content-Length:", headers->data))
+            ;
+          else if(conn->allocptr.te &&
+                  /* when asking for Transfer-Encoding, don't pass on a custom
+                     Connection: */
+                  checkprefix("Connection:", headers->data))
+            ;
+          else if((conn->httpversion == 20) &&
+                  checkprefix("Transfer-Encoding:", headers->data))
+            /* HTTP/2 doesn't support chunked requests */
+            ;
+          else {
+            CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
+                                               headers->data);
+            if(result)
+              return result;
+          }
+        }
+      }
+      else {
+        ptr = strchr(headers->data, ';');
+        if(ptr) {
+
+          ptr++; /* pass the semicolon */
+          while(*ptr && ISSPACE(*ptr))
+            ptr++;
+
+          if(*ptr) {
+            /* this may be used for something else in the future */
+          }
+          else {
+            if(*(--ptr) == ';') {
+              CURLcode result;
+
+              /* send no-value custom header if terminated by semicolon */
+              *ptr = ':';
+              result = Curl_add_bufferf(req_buffer, "%s\r\n",
+                                        headers->data);
+
+              /* restore the previous value */
+              *ptr = ';';
+
+              if(result)
+                return result;
+            }
+          }
+        }
+      }
+      headers = headers->next;
+    }
+  }
+
+  return CURLE_OK;
+}
+
+CURLcode Curl_add_timecondition(struct Curl_easy *data,
+                                Curl_send_buffer *req_buffer)
+{
+  const struct tm *tm;
+  struct tm keeptime;
+  CURLcode result;
+  char datestr[80];
+  const char *condp;
+
+  if(data->set.timecondition == CURL_TIMECOND_NONE)
+    /* no condition was asked for */
+    return CURLE_OK;
+
+  result = Curl_gmtime(data->set.timevalue, &keeptime);
+  if(result) {
+    failf(data, "Invalid TIMEVALUE");
+    return result;
+  }
+  tm = &keeptime;
+
+  switch(data->set.timecondition) {
+  default:
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  case CURL_TIMECOND_IFMODSINCE:
+    condp = "If-Modified-Since";
+    break;
+  case CURL_TIMECOND_IFUNMODSINCE:
+    condp = "If-Unmodified-Since";
+    break;
+  case CURL_TIMECOND_LASTMOD:
+    condp = "Last-Modified";
+    break;
+  }
+
+  /* The If-Modified-Since header family should have their times set in
+   * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be
+   * represented in Greenwich Mean Time (GMT), without exception. For the
+   * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal
+   * Time)." (see page 20 of RFC2616).
+   */
+
+  /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
+  snprintf(datestr, sizeof(datestr),
+           "%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
+           condp,
+           Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
+           tm->tm_mday,
+           Curl_month[tm->tm_mon],
+           tm->tm_year + 1900,
+           tm->tm_hour,
+           tm->tm_min,
+           tm->tm_sec);
+
+  result = Curl_add_buffer(req_buffer, datestr, strlen(datestr));
+
+  return result;
+}
+
+/*
+ * Curl_http() gets called from the generic multi_do() function when a HTTP
+ * request is to be performed. This creates and sends a properly constructed
+ * HTTP request.
+ */
+CURLcode Curl_http(struct connectdata *conn, bool *done)
+{
+  struct Curl_easy *data = conn->data;
+  CURLcode result = CURLE_OK;
+  struct HTTP *http;
+  const char *ppath = data->state.path;
+  bool paste_ftp_userpwd = FALSE;
+  char ftp_typecode[sizeof("/;type=?")] = "";
+  const char *host = conn->host.name;
+  const char *te = ""; /* transfer-encoding */
+  const char *ptr;
+  const char *request;
+  Curl_HttpReq httpreq = data->set.httpreq;
+#if !defined(CURL_DISABLE_COOKIES)
+  char *addcookies = NULL;
+#endif
+  curl_off_t included_body = 0;
+  const char *httpstring;
+  Curl_send_buffer *req_buffer;
+  curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
+  int seekerr = CURL_SEEKFUNC_CANTSEEK;
+
+  /* Always consider the DO phase done after this function call, even if there
+     may be parts of the request that is not yet sent, since we can deal with
+     the rest of the request in the PERFORM phase. */
+  *done = TRUE;
+
+  if(conn->httpversion < 20) { /* unless the connection is re-used and already
+                                  http2 */
+    switch(conn->negnpn) {
+    case CURL_HTTP_VERSION_2:
+      conn->httpversion = 20; /* we know we're on HTTP/2 now */
+
+      result = Curl_http2_switched(conn, NULL, 0);
+      if(result)
+        return result;
+      break;
+    case CURL_HTTP_VERSION_1_1:
+      /* continue with HTTP/1.1 when explicitly requested */
+      break;
+    default:
+      /* Check if user wants to use HTTP/2 with clear TCP*/
+#ifdef USE_NGHTTP2
+      if(conn->data->set.httpversion ==
+         CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
+        DEBUGF(infof(data, "HTTP/2 over clean TCP\n"));
+        conn->httpversion = 20;
+
+        result = Curl_http2_switched(conn, NULL, 0);
+        if(result)
+          return result;
+      }
+#endif
+      break;
+    }
+  }
+  else {
+    /* prepare for a http2 request */
+    result = Curl_http2_setup(conn);
+    if(result)
+      return result;
+  }
+
+  http = data->req.protop;
+
+  if(!data->state.this_is_a_follow) {
+    /* Free to avoid leaking memory on multiple requests*/
+    free(data->state.first_host);
+
+    data->state.first_host = strdup(conn->host.name);
+    if(!data->state.first_host)
+      return CURLE_OUT_OF_MEMORY;
+
+    data->state.first_remote_port = conn->remote_port;
+  }
+  http->writebytecount = http->readbytecount = 0;
+
+  if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
+     data->set.upload) {
+    httpreq = HTTPREQ_PUT;
+  }
+
+  /* Now set the 'request' pointer to the proper request string */
+  if(data->set.str[STRING_CUSTOMREQUEST])
+    request = data->set.str[STRING_CUSTOMREQUEST];
+  else {
+    if(data->set.opt_no_body)
+      request = "HEAD";
+    else {
+      DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
+      switch(httpreq) {
+      case HTTPREQ_POST:
+      case HTTPREQ_POST_FORM:
+      case HTTPREQ_POST_MIME:
+        request = "POST";
+        break;
+      case HTTPREQ_PUT:
+        request = "PUT";
+        break;
+      case HTTPREQ_OPTIONS:
+        request = "OPTIONS";
+        break;
+      default: /* this should never happen */
+      case HTTPREQ_GET:
+        request = "GET";
+        break;
+      case HTTPREQ_HEAD:
+        request = "HEAD";
+        break;
+      }
+    }
+  }
+
+  /* The User-Agent string might have been allocated in url.c already, because
+     it might have been used in the proxy connect, but if we have got a header
+     with the user-agent string specified, we erase the previously made string
+     here. */
+  if(Curl_checkheaders(conn, "User-Agent:")) {
+    free(conn->allocptr.uagent);
+    conn->allocptr.uagent = NULL;
+  }
+
+  /* setup the authentication headers */
+  result = Curl_http_output_auth(conn, request, ppath, FALSE);
+  if(result)
+    return result;
+
+  if((data->state.authhost.multipass || data->state.authproxy.multipass) &&
+     (httpreq != HTTPREQ_GET) &&
+     (httpreq != HTTPREQ_HEAD)) {
+    /* Auth is required and we are not authenticated yet. Make a PUT or POST
+       with content-length zero as a "probe". */
+    conn->bits.authneg = TRUE;
+  }
+  else
+    conn->bits.authneg = FALSE;
+
+  Curl_safefree(conn->allocptr.ref);
+  if(data->change.referer && !Curl_checkheaders(conn, "Referer:")) {
+    conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
+    if(!conn->allocptr.ref)
+      return CURLE_OUT_OF_MEMORY;
+  }
+  else
+    conn->allocptr.ref = NULL;
+
+#if !defined(CURL_DISABLE_COOKIES)
+  if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie:"))
+    addcookies = data->set.str[STRING_COOKIE];
+#endif
+
+  if(!Curl_checkheaders(conn, "Accept-Encoding:") &&
+     data->set.str[STRING_ENCODING]) {
+    Curl_safefree(conn->allocptr.accept_encoding);
+    conn->allocptr.accept_encoding =
+      aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
+    if(!conn->allocptr.accept_encoding)
+      return CURLE_OUT_OF_MEMORY;
+  }
+  else {
+    Curl_safefree(conn->allocptr.accept_encoding);
+    conn->allocptr.accept_encoding = NULL;
+  }
+
+#ifdef HAVE_LIBZ
+  /* we only consider transfer-encoding magic if libz support is built-in */
+
+  if(!Curl_checkheaders(conn, "TE:") &&
+     data->set.http_transfer_encoding) {
+    /* When we are to insert a TE: header in the request, we must also insert
+       TE in a Connection: header, so we need to merge the custom provided
+       Connection: header and prevent the original to get sent. Note that if
+       the user has inserted his/hers own TE: header we don't do this magic
+       but then assume that the user will handle it all! */
+    char *cptr = Curl_checkheaders(conn, "Connection:");
+#define TE_HEADER "TE: gzip\r\n"
+
+    Curl_safefree(conn->allocptr.te);
+
+    /* Create the (updated) Connection: header */
+    conn->allocptr.te = cptr? aprintf("%s, TE\r\n" TE_HEADER, cptr):
+      strdup("Connection: TE\r\n" TE_HEADER);
+
+    if(!conn->allocptr.te)
+      return CURLE_OUT_OF_MEMORY;
+  }
+#endif
+
+  switch(httpreq) {
+  case HTTPREQ_POST_MIME:
+    http->sendit = &data->set.mimepost;
+    break;
+  case HTTPREQ_POST_FORM:
+    /* Convert the form structure into a mime structure. */
+    Curl_mime_cleanpart(&http->form);
+    result = Curl_getformdata(data, &http->form, data->set.httppost,
+                              data->state.fread_func);
+    if(result)
+      return result;
+    http->sendit = &http->form;
+    break;
+  default:
+    http->sendit = NULL;
+  }
+
+  if(http->sendit) {
+    const char *cthdr = Curl_checkheaders(conn, "Content-Type:");
+
+    /* Read and seek body only. */
+    http->sendit->flags |= MIME_BODY_ONLY;
+
+    /* Prepare the mime structure headers & set content type. */
+
+    if(cthdr)
+      for(cthdr += 13; *cthdr == ' '; cthdr++)
+        ;
+    else if(http->sendit->kind == MIMEKIND_MULTIPART)
+      cthdr = "multipart/form-data";
+
+    curl_mime_headers(http->sendit, data->set.headers, 0);
+    result = Curl_mime_prepare_headers(http->sendit, cthdr,
+                                       NULL, MIMESTRATEGY_FORM);
+    curl_mime_headers(http->sendit, NULL, 0);
+    if(!result)
+      result = Curl_mime_rewind(http->sendit);
+    if(result)
+      return result;
+    http->postsize = Curl_mime_size(http->sendit);
+  }
+
+  ptr = Curl_checkheaders(conn, "Transfer-Encoding:");
+  if(ptr) {
+    /* Some kind of TE is requested, check if 'chunked' is chosen */
+    data->req.upload_chunky =
+      Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
+  }
+  else {
+    if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
+       (((httpreq == HTTPREQ_POST_MIME || httpreq == HTTPREQ_POST_FORM) &&
+       http->postsize < 0) ||
+       (data->set.upload && data->state.infilesize == -1))) {
+      if(conn->bits.authneg)
+        /* don't enable chunked during auth neg */
+        ;
+      else if(use_http_1_1plus(data, conn)) {
+        /* HTTP, upload, unknown file size and not HTTP 1.0 */
+        data->req.upload_chunky = TRUE;
+      }
+      else {
+        failf(data, "Chunky upload is not supported by HTTP 1.0");
+        return CURLE_UPLOAD_FAILED;
+      }
+    }
+    else {
+      /* else, no chunky upload */
+      data->req.upload_chunky = FALSE;
+    }
+
+    if(data->req.upload_chunky)
+      te = "Transfer-Encoding: chunked\r\n";
+  }
+
+  Curl_safefree(conn->allocptr.host);
+
+  ptr = Curl_checkheaders(conn, "Host:");
+  if(ptr && (!data->state.this_is_a_follow ||
+             strcasecompare(data->state.first_host, conn->host.name))) {
+#if !defined(CURL_DISABLE_COOKIES)
+    /* If we have a given custom Host: header, we extract the host name in
+       order to possibly use it for cookie reasons later on. We only allow the
+       custom Host: header if this is NOT a redirect, as setting Host: in the
+       redirected request is being out on thin ice. Except if the host name
+       is the same as the first one! */
+    char *cookiehost = Curl_copy_header_value(ptr);
+    if(!cookiehost)
+      return CURLE_OUT_OF_MEMORY;
+    if(!*cookiehost)
+      /* ignore empty data */
+      free(cookiehost);
+    else {
+      /* If the host begins with '[', we start searching for the port after
+         the bracket has been closed */
+      int startsearch = 0;
+      if(*cookiehost == '[') {
+        char *closingbracket;
+        /* since the 'cookiehost' is an allocated memory area that will be
+           freed later we cannot simply increment the pointer */
+        memmove(cookiehost, cookiehost + 1, strlen(cookiehost) - 1);
+        closingbracket = strchr(cookiehost, ']');
+        if(closingbracket)
+          *closingbracket = 0;
+      }
+      else {
+        char *colon = strchr(cookiehost + startsearch, ':');
+        if(colon)
+          *colon = 0; /* The host must not include an embedded port number */
+      }
+      Curl_safefree(conn->allocptr.cookiehost);
+      conn->allocptr.cookiehost = cookiehost;
+    }
+#endif
+
+    if(strcmp("Host:", ptr)) {
+      conn->allocptr.host = aprintf("%s\r\n", ptr);
+      if(!conn->allocptr.host)
+        return CURLE_OUT_OF_MEMORY;
+    }
+    else
+      /* when clearing the header */
+      conn->allocptr.host = NULL;
+  }
+  else {
+    /* When building Host: headers, we must put the host name within
+       [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
+
+    if(((conn->given->protocol&CURLPROTO_HTTPS) &&
+        (conn->remote_port == PORT_HTTPS)) ||
+       ((conn->given->protocol&CURLPROTO_HTTP) &&
+        (conn->remote_port == PORT_HTTP)) )
+      /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
+         the port number in the host string */
+      conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
+                                    conn->bits.ipv6_ip?"[":"",
+                                    host,
+                                    conn->bits.ipv6_ip?"]":"");
+    else
+      conn->allocptr.host = aprintf("Host: %s%s%s:%hu\r\n",
+                                    conn->bits.ipv6_ip?"[":"",
+                                    host,
+                                    conn->bits.ipv6_ip?"]":"",
+                                    conn->remote_port);
+
+    if(!conn->allocptr.host)
+      /* without Host: we can't make a nice request */
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+#ifndef CURL_DISABLE_PROXY
+  if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
+    /* Using a proxy but does not tunnel through it */
+
+    /* The path sent to the proxy is in fact the entire URL. But if the remote
+       host is a IDN-name, we must make sure that the request we produce only
+       uses the encoded host name! */
+    if(conn->host.dispname != conn->host.name) {
+      char *url = data->change.url;
+      ptr = strstr(url, conn->host.dispname);
+      if(ptr) {
+        /* This is where the display name starts in the URL, now replace this
+           part with the encoded name. TODO: This method of replacing the host
+           name is rather crude as I believe there's a slight risk that the
+           user has entered a user name or password that contain the host name
+           string. */
+        size_t currlen = strlen(conn->host.dispname);
+        size_t newlen = strlen(conn->host.name);
+        size_t urllen = strlen(url);
+
+        char *newurl;
+
+        newurl = malloc(urllen + newlen - currlen + 1);
+        if(newurl) {
+          /* copy the part before the host name */
+          memcpy(newurl, url, ptr - url);
+          /* append the new host name instead of the old */
+          memcpy(newurl + (ptr - url), conn->host.name, newlen);
+          /* append the piece after the host name */
+          memcpy(newurl + newlen + (ptr - url),
+                 ptr + currlen, /* copy the trailing zero byte too */
+                 urllen - (ptr-url) - currlen + 1);
+          if(data->change.url_alloc) {
+            Curl_safefree(data->change.url);
+            data->change.url_alloc = FALSE;
+          }
+          data->change.url = newurl;
+          data->change.url_alloc = TRUE;
+        }
+        else
+          return CURLE_OUT_OF_MEMORY;
+      }
+    }
+    ppath = data->change.url;
+    if(checkprefix("ftp://", ppath)) {
+      if(data->set.proxy_transfer_mode) {
+        /* when doing ftp, append ;type=<a|i> if not present */
+        char *type = strstr(ppath, ";type=");
+        if(type && type[6] && type[7] == 0) {
+          switch(Curl_raw_toupper(type[6])) {
+          case 'A':
+          case 'D':
+          case 'I':
+            break;
+          default:
+            type = NULL;
+          }
+        }
+        if(!type) {
+          char *p = ftp_typecode;
+          /* avoid sending invalid URLs like ftp://example.com;type=i if the
+           * user specified ftp://example.com without the slash */
+          if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') {
+            *p++ = '/';
+          }
+          snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
+                   data->set.prefer_ascii ? 'a' : 'i');
+        }
+      }
+      if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
+        paste_ftp_userpwd = TRUE;
+    }
+  }
+#endif /* CURL_DISABLE_PROXY */
+
+  http->p_accept = Curl_checkheaders(conn, "Accept:")?NULL:"Accept: */*\r\n";
+
+  if((HTTPREQ_POST == httpreq || HTTPREQ_PUT == httpreq) &&
+     data->state.resume_from) {
+    /**********************************************************************
+     * Resuming upload in HTTP means that we PUT or POST and that we have
+     * got a resume_from value set. The resume value has already created
+     * a Range: header that will be passed along. We need to "fast forward"
+     * the file the given number of bytes and decrease the assume upload
+     * file size before we continue this venture in the dark lands of HTTP.
+     * Resuming mime/form posting at an offset > 0 has no sense and is ignored.
+     *********************************************************************/
+
+    if(data->state.resume_from < 0) {
+      /*
+       * This is meant to get the size of the present remote-file by itself.
+       * We don't support this now. Bail out!
+       */
+      data->state.resume_from = 0;
+    }
+
+    if(data->state.resume_from && !data->state.this_is_a_follow) {
+      /* do we still game? */
+
+      /* Now, let's read off the proper amount of bytes from the
+         input. */
+      if(conn->seek_func) {
+        seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
+                                  SEEK_SET);
+      }
+
+      if(seekerr != CURL_SEEKFUNC_OK) {
+        curl_off_t passed = 0;
+
+        if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
+          failf(data, "Could not seek stream");
+          return CURLE_READ_ERROR;
+        }
+        /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
+        do {
+          size_t readthisamountnow =
+            (data->state.resume_from - passed > data->set.buffer_size) ?
+            (size_t)data->set.buffer_size :
+            curlx_sotouz(data->state.resume_from - passed);
+
+          size_t actuallyread =
+            data->state.fread_func(data->state.buffer, 1, readthisamountnow,
+                                   data->state.in);
+
+          passed += actuallyread;
+          if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
+            /* this checks for greater-than only to make sure that the
+               CURL_READFUNC_ABORT return code still aborts */
+            failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T
+                  " bytes from the input", passed);
+            return CURLE_READ_ERROR;
+          }
+        } while(passed < data->state.resume_from);
+      }
+
+      /* now, decrease the size of the read */
+      if(data->state.infilesize>0) {
+        data->state.infilesize -= data->state.resume_from;
+
+        if(data->state.infilesize <= 0) {
+          failf(data, "File already completely uploaded");
+          return CURLE_PARTIAL_FILE;
+        }
+      }
+      /* we've passed, proceed as normal */
+    }
+  }
+  if(data->state.use_range) {
+    /*
+     * A range is selected. We use different headers whether we're downloading
+     * or uploading and we always let customized headers override our internal
+     * ones if any such are specified.
+     */
+    if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
+       !Curl_checkheaders(conn, "Range:")) {
+      /* if a line like this was already allocated, free the previous one */
+      free(conn->allocptr.rangeline);
+      conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
+                                         data->state.range);
+    }
+    else if((httpreq == HTTPREQ_POST || httpreq == HTTPREQ_PUT) &&
+            !Curl_checkheaders(conn, "Content-Range:")) {
+
+      /* if a line like this was already allocated, free the previous one */
+      free(conn->allocptr.rangeline);
+
+      if(data->set.set_resume_from < 0) {
+        /* Upload resume was asked for, but we don't know the size of the
+           remote part so we tell the server (and act accordingly) that we
+           upload the whole file (again) */
+        conn->allocptr.rangeline =
+          aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T
+                  "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
+                  data->state.infilesize - 1, data->state.infilesize);
+
+      }
+      else if(data->state.resume_from) {
+        /* This is because "resume" was selected */
+        curl_off_t total_expected_size =
+          data->state.resume_from + data->state.infilesize;
+        conn->allocptr.rangeline =
+          aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T
+                  "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
+                  data->state.range, total_expected_size-1,
+                  total_expected_size);
+      }
+      else {
+        /* Range was selected and then we just pass the incoming range and
+           append total size */
+        conn->allocptr.rangeline =
+          aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n",
+                  data->state.range, data->state.infilesize);
+      }
+      if(!conn->allocptr.rangeline)
+        return CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  httpstring = get_http_string(data, conn);
+
+  /* initialize a dynamic send-buffer */
+  req_buffer = Curl_add_buffer_init();
+
+  if(!req_buffer)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* add the main request stuff */
+  /* GET/HEAD/POST/PUT */
+  result = Curl_add_bufferf(req_buffer, "%s ", request);
+  if(result)
+    return result;
+
+  if(data->set.str[STRING_TARGET])
+    ppath = data->set.str[STRING_TARGET];
+
+  /* url */
+  if(paste_ftp_userpwd)
+    result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
+                              conn->user, conn->passwd,
+                              ppath + sizeof("ftp://") - 1);
+  else
+    result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
+  if(result)
+    return result;
+
+  result =
+    Curl_add_bufferf(req_buffer,
+                     "%s" /* ftp typecode (;type=x) */
+                     " HTTP/%s\r\n" /* HTTP version */
+                     "%s" /* host */
+                     "%s" /* proxyuserpwd */
+                     "%s" /* userpwd */
+                     "%s" /* range */
+                     "%s" /* user agent */
+                     "%s" /* accept */
+                     "%s" /* TE: */
+                     "%s" /* accept-encoding */
+                     "%s" /* referer */
+                     "%s" /* Proxy-Connection */
+                     "%s",/* transfer-encoding */
+
+                     ftp_typecode,
+                     httpstring,
+                     (conn->allocptr.host?conn->allocptr.host:""),
+                     conn->allocptr.proxyuserpwd?
+                     conn->allocptr.proxyuserpwd:"",
+                     conn->allocptr.userpwd?conn->allocptr.userpwd:"",
+                     (data->state.use_range && conn->allocptr.rangeline)?
+                     conn->allocptr.rangeline:"",
+                     (data->set.str[STRING_USERAGENT] &&
+                      *data->set.str[STRING_USERAGENT] &&
+                      conn->allocptr.uagent)?
+                     conn->allocptr.uagent:"",
+                     http->p_accept?http->p_accept:"",
+                     conn->allocptr.te?conn->allocptr.te:"",
+                     (data->set.str[STRING_ENCODING] &&
+                      *data->set.str[STRING_ENCODING] &&
+                      conn->allocptr.accept_encoding)?
+                     conn->allocptr.accept_encoding:"",
+                     (data->change.referer && conn->allocptr.ref)?
+                     conn->allocptr.ref:"" /* Referer: <data> */,
+                     (conn->bits.httpproxy &&
+                      !conn->bits.tunnel_proxy &&
+                      !Curl_checkProxyheaders(conn, "Proxy-Connection:"))?
+                     "Proxy-Connection: Keep-Alive\r\n":"",
+                     te
+      );
+
+  /* clear userpwd and proxyuserpwd to avoid re-using old credentials
+   * from re-used connections */
+  Curl_safefree(conn->allocptr.userpwd);
+  Curl_safefree(conn->allocptr.proxyuserpwd);
+
+  if(result)
+    return result;
+
+  if(!(conn->handler->flags&PROTOPT_SSL) &&
+     conn->httpversion != 20 &&
+     (data->set.httpversion == CURL_HTTP_VERSION_2)) {
+    /* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done
+       over SSL */
+    result = Curl_http2_request_upgrade(req_buffer, conn);
+    if(result)
+      return result;
+  }
+
+#if !defined(CURL_DISABLE_COOKIES)
+  if(data->cookies || addcookies) {
+    struct Cookie *co = NULL; /* no cookies from start */
+    int count = 0;
+
+    if(data->cookies) {
+      Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+      co = Curl_cookie_getlist(data->cookies,
+                               conn->allocptr.cookiehost?
+                               conn->allocptr.cookiehost:host,
+                               data->state.path,
+                               (conn->handler->protocol&CURLPROTO_HTTPS)?
+                               TRUE:FALSE);
+      Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+    }
+    if(co) {
+      struct Cookie *store = co;
+      /* now loop through all cookies that matched */
+      while(co) {
+        if(co->value) {
+          if(0 == count) {
+            result = Curl_add_bufferf(req_buffer, "Cookie: ");
+            if(result)
+              break;
+          }
+          result = Curl_add_bufferf(req_buffer,
+                                    "%s%s=%s", count?"; ":"",
+                                    co->name, co->value);
+          if(result)
+            break;
+          count++;
+        }
+        co = co->next; /* next cookie please */
+      }
+      Curl_cookie_freelist(store);
+    }
+    if(addcookies && !result) {
+      if(!count)
+        result = Curl_add_bufferf(req_buffer, "Cookie: ");
+      if(!result) {
+        result = Curl_add_bufferf(req_buffer, "%s%s", count?"; ":"",
+                                  addcookies);
+        count++;
+      }
+    }
+    if(count && !result)
+      result = Curl_add_buffer(req_buffer, "\r\n", 2);
+
+    if(result)
+      return result;
+  }
+#endif
+
+  result = Curl_add_timecondition(data, req_buffer);
+  if(result)
+    return result;
+
+  result = Curl_add_custom_headers(conn, FALSE, req_buffer);
+  if(result)
+    return result;
+
+  http->postdata = NULL;  /* nothing to post at this point */
+  Curl_pgrsSetUploadSize(data, -1); /* upload size is unknown atm */
+
+  /* If 'authdone' is FALSE, we must not set the write socket index to the
+     Curl_transfer() call below, as we're not ready to actually upload any
+     data yet. */
+
+  switch(httpreq) {
+
+  case HTTPREQ_PUT: /* Let's PUT the data to the server! */
+
+    if(conn->bits.authneg)
+      postsize = 0;
+    else
+      postsize = data->state.infilesize;
+
+    if((postsize != -1) && !data->req.upload_chunky &&
+       (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length:"))) {
+      /* only add Content-Length if not uploading chunked */
+      result = Curl_add_bufferf(req_buffer,
+                                "Content-Length: %" CURL_FORMAT_CURL_OFF_T
+                                "\r\n", postsize);
+      if(result)
+        return result;
+    }
+
+    if(postsize != 0) {
+      result = expect100(data, conn, req_buffer);
+      if(result)
+        return result;
+    }
+
+    result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */
+    if(result)
+      return result;
+
+    /* set the upload size to the progress meter */
+    Curl_pgrsSetUploadSize(data, postsize);
+
+    /* this sends the buffer and frees all the buffer resources */
+    result = Curl_add_buffer_send(req_buffer, conn,
+                                  &data->info.request_size, 0, FIRSTSOCKET);
+    if(result)
+      failf(data, "Failed sending PUT request");
+    else
+      /* prepare for transfer */
+      Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
+                          &http->readbytecount, postsize?FIRSTSOCKET:-1,
+                          postsize?&http->writebytecount:NULL);
+    if(result)
+      return result;
+    break;
+
+  case HTTPREQ_POST_FORM:
+  case HTTPREQ_POST_MIME:
+    /* This is form posting using mime data. */
+    if(conn->bits.authneg) {
+      /* nothing to post! */
+      result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
+      if(result)
+        return result;
+
+      result = Curl_add_buffer_send(req_buffer, conn,
+                                    &data->info.request_size, 0, FIRSTSOCKET);
+      if(result)
+        failf(data, "Failed sending POST request");
+      else
+        /* setup variables for the upcoming transfer */
+        Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
+                            -1, NULL);
+      break;
+    }
+
+    postsize = http->postsize;
+
+    /* We only set Content-Length and allow a custom Content-Length if
+       we don't upload data chunked, as RFC2616 forbids us to set both
+       kinds of headers (Transfer-Encoding: chunked and Content-Length) */
+    if(postsize != -1 && !data->req.upload_chunky &&
+       (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length:"))) {
+      /* we allow replacing this header if not during auth negotiation,
+         although it isn't very wise to actually set your own */
+      result = Curl_add_bufferf(req_buffer,
+                                "Content-Length: %" CURL_FORMAT_CURL_OFF_T
+                                "\r\n", postsize);
+      if(result)
+        return result;
+    }
+
+    /* Output mime-generated headers. */
+    {
+      struct curl_slist *hdr;
+
+      for(hdr = http->sendit->curlheaders; hdr; hdr = hdr->next) {
+        result = Curl_add_bufferf(req_buffer, "%s\r\n", hdr->data);
+        if(result)
+          return result;
+      }
+    }
+
+    /* For really small posts we don't use Expect: headers at all, and for
+       the somewhat bigger ones we allow the app to disable it. Just make
+       sure that the expect100header is always set to the preferred value
+       here. */
+    ptr = Curl_checkheaders(conn, "Expect:");
+    if(ptr) {
+      data->state.expect100header =
+        Curl_compareheader(ptr, "Expect:", "100-continue");
+    }
+    else if(postsize > EXPECT_100_THRESHOLD || postsize < 0) {
+      result = expect100(data, conn, req_buffer);
+      if(result)
+        return result;
+    }
+    else
+      data->state.expect100header = FALSE;
+
+    /* make the request end in a true CRLF */
+    result = Curl_add_buffer(req_buffer, "\r\n", 2);
+    if(result)
+      return result;
+
+    /* set the upload size to the progress meter */
+    Curl_pgrsSetUploadSize(data, postsize);
+
+    /* Read from mime structure. */
+    data->state.fread_func = (curl_read_callback) Curl_mime_read;
+    data->state.in = (void *) http->sendit;
+    http->sending = HTTPSEND_BODY;
+
+    /* this sends the buffer and frees all the buffer resources */
+    result = Curl_add_buffer_send(req_buffer, conn,
+                                  &data->info.request_size, 0, FIRSTSOCKET);
+    if(result)
+      failf(data, "Failed sending POST request");
+    else
+      /* prepare for transfer */
+      Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
+                          &http->readbytecount, postsize?FIRSTSOCKET:-1,
+                          postsize?&http->writebytecount:NULL);
+    if(result)
+      return result;
+
+    break;
+
+  case HTTPREQ_POST:
+    /* this is the simple POST, using x-www-form-urlencoded style */
+
+    if(conn->bits.authneg)
+      postsize = 0;
+    else
+      /* the size of the post body */
+      postsize = data->state.infilesize;
+
+    /* We only set Content-Length and allow a custom Content-Length if
+       we don't upload data chunked, as RFC2616 forbids us to set both
+       kinds of headers (Transfer-Encoding: chunked and Content-Length) */
+    if((postsize != -1) && !data->req.upload_chunky &&
+       (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length:"))) {
+      /* we allow replacing this header if not during auth negotiation,
+         although it isn't very wise to actually set your own */
+      result = Curl_add_bufferf(req_buffer,
+                                "Content-Length: %" CURL_FORMAT_CURL_OFF_T
+                                "\r\n", postsize);
+      if(result)
+        return result;
+    }
+
+    if(!Curl_checkheaders(conn, "Content-Type:")) {
+      result = Curl_add_bufferf(req_buffer,
+                                "Content-Type: application/"
+                                "x-www-form-urlencoded\r\n");
+      if(result)
+        return result;
+    }
+
+    /* For really small posts we don't use Expect: headers at all, and for
+       the somewhat bigger ones we allow the app to disable it. Just make
+       sure that the expect100header is always set to the preferred value
+       here. */
+    ptr = Curl_checkheaders(conn, "Expect:");
+    if(ptr) {
+      data->state.expect100header =
+        Curl_compareheader(ptr, "Expect:", "100-continue");
+    }
+    else if(postsize > EXPECT_100_THRESHOLD || postsize < 0) {
+      result = expect100(data, conn, req_buffer);
+      if(result)
+        return result;
+    }
+    else
+      data->state.expect100header = FALSE;
+
+    if(data->set.postfields) {
+
+      /* In HTTP2, we send request body in DATA frame regardless of
+         its size. */
+      if(conn->httpversion != 20 &&
+         !data->state.expect100header &&
+         (postsize < MAX_INITIAL_POST_SIZE)) {
+        /* if we don't use expect: 100  AND
+           postsize is less than MAX_INITIAL_POST_SIZE
+
+           then append the post data to the HTTP request header. This limit
+           is no magic limit but only set to prevent really huge POSTs to
+           get the data duplicated with malloc() and family. */
+
+        result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
+        if(result)
+          return result;
+
+        if(!data->req.upload_chunky) {
+          /* We're not sending it 'chunked', append it to the request
+             already now to reduce the number if send() calls */
+          result = Curl_add_buffer(req_buffer, data->set.postfields,
+                                   (size_t)postsize);
+          included_body = postsize;
+        }
+        else {
+          if(postsize) {
+            /* Append the POST data chunky-style */
+            result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
+            if(!result) {
+              result = Curl_add_buffer(req_buffer, data->set.postfields,
+                                       (size_t)postsize);
+              if(!result)
+                result = Curl_add_buffer(req_buffer, "\r\n", 2);
+              included_body = postsize + 2;
+            }
+          }
+          if(!result)
+            result = Curl_add_buffer(req_buffer, "\x30\x0d\x0a\x0d\x0a", 5);
+          /* 0  CR  LF  CR  LF */
+          included_body += 5;
+        }
+        if(result)
+          return result;
+        /* Make sure the progress information is accurate */
+        Curl_pgrsSetUploadSize(data, postsize);
+      }
+      else {
+        /* A huge POST coming up, do data separate from the request */
+        http->postsize = postsize;
+        http->postdata = data->set.postfields;
+
+        http->sending = HTTPSEND_BODY;
+
+        data->state.fread_func = (curl_read_callback)readmoredata;
+        data->state.in = (void *)conn;
+
+        /* set the upload size to the progress meter */
+        Curl_pgrsSetUploadSize(data, http->postsize);
+
+        result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
+        if(result)
+          return result;
+      }
+    }
+    else {
+      result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
+      if(result)
+        return result;
+
+      if(data->req.upload_chunky && conn->bits.authneg) {
+        /* Chunky upload is selected and we're negotiating auth still, send
+           end-of-data only */
+        result = Curl_add_buffer(req_buffer,
+                                 "\x30\x0d\x0a\x0d\x0a", 5);
+        /* 0  CR  LF  CR  LF */
+        if(result)
+          return result;
+      }
+
+      else if(data->state.infilesize) {
+        /* set the upload size to the progress meter */
+        Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
+
+        /* set the pointer to mark that we will send the post body using the
+           read callback, but only if we're not in authenticate
+           negotiation  */
+        if(!conn->bits.authneg) {
+          http->postdata = (char *)&http->postdata;
+          http->postsize = postsize;
+        }
+      }
+    }
+    /* issue the request */
+    result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size,
+                                  (size_t)included_body, FIRSTSOCKET);
+
+    if(result)
+      failf(data, "Failed sending HTTP POST request");
+    else
+      Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
+                          &http->readbytecount, http->postdata?FIRSTSOCKET:-1,
+                          http->postdata?&http->writebytecount:NULL);
+    break;
+
+  default:
+    result = Curl_add_buffer(req_buffer, "\r\n", 2);
+    if(result)
+      return result;
+
+    /* issue the request */
+    result = Curl_add_buffer_send(req_buffer, conn,
+                                  &data->info.request_size, 0, FIRSTSOCKET);
+
+    if(result)
+      failf(data, "Failed sending HTTP request");
+    else
+      /* HTTP GET/HEAD download: */
+      Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
+                          http->postdata?FIRSTSOCKET:-1,
+                          http->postdata?&http->writebytecount:NULL);
+  }
+  if(result)
+    return result;
+
+  if(http->writebytecount) {
+    /* if a request-body has been sent off, we make sure this progress is noted
+       properly */
+    Curl_pgrsSetUploadCounter(data, http->writebytecount);
+    if(Curl_pgrsUpdate(conn))
+      result = CURLE_ABORTED_BY_CALLBACK;
+
+    if(http->writebytecount >= postsize) {
+      /* already sent the entire request body, mark the "upload" as
+         complete */
+      infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T
+            " out of %" CURL_FORMAT_CURL_OFF_T " bytes\n",
+            http->writebytecount, postsize);
+      data->req.upload_done = TRUE;
+      data->req.keepon &= ~KEEP_SEND; /* we're done writing */
+      data->req.exp100 = EXP100_SEND_DATA; /* already sent */
+      Curl_expire_done(data, EXPIRE_100_TIMEOUT);
+    }
+  }
+
+  if((conn->httpversion == 20) && data->req.upload_chunky)
+    /* upload_chunky was set above to set up the request in a chunky fashion,
+       but is disabled here again to avoid that the chunked encoded version is
+       actually used when sending the request body over h2 */
+    data->req.upload_chunky = FALSE;
+  return result;
+}
+
+/*
+ * checkhttpprefix()
+ *
+ * Returns TRUE if member of the list matches prefix of string
+ */
+static bool
+checkhttpprefix(struct Curl_easy *data,
+                const char *s)
+{
+  struct curl_slist *head = data->set.http200aliases;
+  bool rc = FALSE;
+#ifdef CURL_DOES_CONVERSIONS
+  /* convert from the network encoding using a scratch area */
+  char *scratch = strdup(s);
+  if(NULL == scratch) {
+    failf(data, "Failed to allocate memory for conversion!");
+    return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
+  }
+  if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s) + 1)) {
+    /* Curl_convert_from_network calls failf if unsuccessful */
+    free(scratch);
+    return FALSE; /* can't return CURLE_foobar so return FALSE */
+  }
+  s = scratch;
+#endif /* CURL_DOES_CONVERSIONS */
+
+  while(head) {
+    if(checkprefix(head->data, s)) {
+      rc = TRUE;
+      break;
+    }
+    head = head->next;
+  }
+
+  if(!rc && (checkprefix("HTTP/", s)))
+    rc = TRUE;
+
+#ifdef CURL_DOES_CONVERSIONS
+  free(scratch);
+#endif /* CURL_DOES_CONVERSIONS */
+  return rc;
+}
+
+#ifndef CURL_DISABLE_RTSP
+static bool
+checkrtspprefix(struct Curl_easy *data,
+                const char *s)
+{
+  bool result = FALSE;
+
+#ifdef CURL_DOES_CONVERSIONS
+  /* convert from the network encoding using a scratch area */
+  char *scratch = strdup(s);
+  if(NULL == scratch) {
+    failf(data, "Failed to allocate memory for conversion!");
+    return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
+  }
+  if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s) + 1)) {
+    /* Curl_convert_from_network calls failf if unsuccessful */
+    result = FALSE; /* can't return CURLE_foobar so return FALSE */
+  }
+  else
+    result = checkprefix("RTSP/", scratch)? TRUE: FALSE;
+  free(scratch);
+#else
+  (void)data; /* unused */
+  result = checkprefix("RTSP/", s)? TRUE: FALSE;
+#endif /* CURL_DOES_CONVERSIONS */
+
+  return result;
+}
+#endif /* CURL_DISABLE_RTSP */
+
+static bool
+checkprotoprefix(struct Curl_easy *data, struct connectdata *conn,
+                 const char *s)
+{
+#ifndef CURL_DISABLE_RTSP
+  if(conn->handler->protocol & CURLPROTO_RTSP)
+    return checkrtspprefix(data, s);
+#else
+  (void)conn;
+#endif /* CURL_DISABLE_RTSP */
+
+  return checkhttpprefix(data, s);
+}
+
+/*
+ * header_append() copies a chunk of data to the end of the already received
+ * header. We make sure that the full string fit in the allocated header
+ * buffer, or else we enlarge it.
+ */
+static CURLcode header_append(struct Curl_easy *data,
+                              struct SingleRequest *k,
+                              size_t length)
+{
+  if(k->hbuflen + length >= data->state.headersize) {
+    /* We enlarge the header buffer as it is too small */
+    char *newbuff;
+    size_t hbufp_index;
+    size_t newsize;
+
+    if(k->hbuflen + length > CURL_MAX_HTTP_HEADER) {
+      /* The reason to have a max limit for this is to avoid the risk of a bad
+         server feeding libcurl with a never-ending header that will cause
+         reallocs infinitely */
+      failf(data, "Avoided giant realloc for header (max is %d)!",
+            CURL_MAX_HTTP_HEADER);
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    newsize = CURLMAX((k->hbuflen + length) * 3 / 2, data->state.headersize*2);
+    hbufp_index = k->hbufp - data->state.headerbuff;
+    newbuff = realloc(data->state.headerbuff, newsize);
+    if(!newbuff) {
+      failf(data, "Failed to alloc memory for big header!");
+      return CURLE_OUT_OF_MEMORY;
+    }
+    data->state.headersize = newsize;
+    data->state.headerbuff = newbuff;
+    k->hbufp = data->state.headerbuff + hbufp_index;
+  }
+  memcpy(k->hbufp, k->str_start, length);
+  k->hbufp += length;
+  k->hbuflen += length;
+  *k->hbufp = 0;
+
+  return CURLE_OK;
+}
+
+static void print_http_error(struct Curl_easy *data)
+{
+  struct SingleRequest *k = &data->req;
+  char *beg = k->p;
+
+  /* make sure that data->req.p points to the HTTP status line */
+  if(!strncmp(beg, "HTTP", 4)) {
+
+    /* skip to HTTP status code */
+    beg = strchr(beg, ' ');
+    if(beg && *++beg) {
+
+      /* find trailing CR */
+      char end_char = '\r';
+      char *end = strchr(beg, end_char);
+      if(!end) {
+        /* try to find LF (workaround for non-compliant HTTP servers) */
+        end_char = '\n';
+        end = strchr(beg, end_char);
+      }
+
+      if(end) {
+        /* temporarily replace CR or LF by NUL and print the error message */
+        *end = '\0';
+        failf(data, "The requested URL returned error: %s", beg);
+
+        /* restore the previously replaced CR or LF */
+        *end = end_char;
+        return;
+      }
+    }
+  }
+
+  /* fall-back to printing the HTTP status code only */
+  failf(data, "The requested URL returned error: %d", k->httpcode);
+}
+
+/*
+ * Read any HTTP header lines from the server and pass them to the client app.
+ */
+CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
+                                       struct connectdata *conn,
+                                       ssize_t *nread,
+                                       bool *stop_reading)
+{
+  CURLcode result;
+  struct SingleRequest *k = &data->req;
+
+  /* header line within buffer loop */
+  do {
+    size_t rest_length;
+    size_t full_length;
+    int writetype;
+
+    /* str_start is start of line within buf */
+    k->str_start = k->str;
+
+    /* data is in network encoding so use 0x0a instead of '\n' */
+    k->end_ptr = memchr(k->str_start, 0x0a, *nread);
+
+    if(!k->end_ptr) {
+      /* Not a complete header line within buffer, append the data to
+         the end of the headerbuff. */
+      result = header_append(data, k, *nread);
+      if(result)
+        return result;
+
+      if(!k->headerline && (k->hbuflen>5)) {
+        /* make a first check that this looks like a protocol header */
+        if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
+          /* this is not the beginning of a protocol first header line */
+          k->header = FALSE;
+          k->badheader = HEADER_ALLBAD;
+          break;
+        }
+      }
+
+      break; /* read more and try again */
+    }
+
+    /* decrease the size of the remaining (supposed) header line */
+    rest_length = (k->end_ptr - k->str) + 1;
+    *nread -= (ssize_t)rest_length;
+
+    k->str = k->end_ptr + 1; /* move past new line */
+
+    full_length = k->str - k->str_start;
+
+    result = header_append(data, k, full_length);
+    if(result)
+      return result;
+
+    k->end_ptr = k->hbufp;
+    k->p = data->state.headerbuff;
+
+    /****
+     * We now have a FULL header line that p points to
+     *****/
+
+    if(!k->headerline) {
+      /* the first read header */
+      if((k->hbuflen>5) &&
+         !checkprotoprefix(data, conn, data->state.headerbuff)) {
+        /* this is not the beginning of a protocol first header line */
+        k->header = FALSE;
+        if(*nread)
+          /* since there's more, this is a partial bad header */
+          k->badheader = HEADER_PARTHEADER;
+        else {
+          /* this was all we read so it's all a bad header */
+          k->badheader = HEADER_ALLBAD;
+          *nread = (ssize_t)rest_length;
+        }
+        break;
+      }
+    }
+
+    /* headers are in network encoding so
+       use 0x0a and 0x0d instead of '\n' and '\r' */
+    if((0x0a == *k->p) || (0x0d == *k->p)) {
+      size_t headerlen;
+      /* Zero-length header line means end of headers! */
+
+#ifdef CURL_DOES_CONVERSIONS
+      if(0x0d == *k->p) {
+        *k->p = '\r'; /* replace with CR in host encoding */
+        k->p++;       /* pass the CR byte */
+      }
+      if(0x0a == *k->p) {
+        *k->p = '\n'; /* replace with LF in host encoding */
+        k->p++;       /* pass the LF byte */
+      }
+#else
+      if('\r' == *k->p)
+        k->p++; /* pass the \r byte */
+      if('\n' == *k->p)
+        k->p++; /* pass the \n byte */
+#endif /* CURL_DOES_CONVERSIONS */
+
+      if(100 <= k->httpcode && 199 >= k->httpcode) {
+        /* "A user agent MAY ignore unexpected 1xx status responses." */
+        switch(k->httpcode) {
+        case 100:
+          /*
+           * We have made a HTTP PUT or POST and this is 1.1-lingo
+           * that tells us that the server is OK with this and ready
+           * to receive the data.
+           * However, we'll get more headers now so we must get
+           * back into the header-parsing state!
+           */
+          k->header = TRUE;
+          k->headerline = 0; /* restart the header line counter */
+
+          /* if we did wait for this do enable write now! */
+          if(k->exp100 > EXP100_SEND_DATA) {
+            k->exp100 = EXP100_SEND_DATA;
+            k->keepon |= KEEP_SEND;
+            Curl_expire_done(data, EXPIRE_100_TIMEOUT);
+          }
+          break;
+        case 101:
+          /* Switching Protocols */
+          if(k->upgr101 == UPGR101_REQUESTED) {
+            /* Switching to HTTP/2 */
+            infof(data, "Received 101\n");
+            k->upgr101 = UPGR101_RECEIVED;
+
+            /* we'll get more headers (HTTP/2 response) */
+            k->header = TRUE;
+            k->headerline = 0; /* restart the header line counter */
+
+            /* switch to http2 now. The bytes after response headers
+               are also processed here, otherwise they are lost. */
+            result = Curl_http2_switched(conn, k->str, *nread);
+            if(result)
+              return result;
+            *nread = 0;
+          }
+          else {
+            /* Switching to another protocol (e.g. WebSocket) */
+            k->header = FALSE; /* no more header to parse! */
+          }
+          break;
+        default:
+          /* the status code 1xx indicates a provisional response, so
+             we'll get another set of headers */
+          k->header = TRUE;
+          k->headerline = 0; /* restart the header line counter */
+          break;
+        }
+      }
+      else {
+        k->header = FALSE; /* no more header to parse! */
+
+        if((k->size == -1) && !k->chunk && !conn->bits.close &&
+           (conn->httpversion == 11) &&
+           !(conn->handler->protocol & CURLPROTO_RTSP) &&
+           data->set.httpreq != HTTPREQ_HEAD) {
+          /* On HTTP 1.1, when connection is not to get closed, but no
+             Content-Length nor Transfer-Encoding chunked have been
+             received, according to RFC2616 section 4.4 point 5, we
+             assume that the server will close the connection to
+             signal the end of the document. */
+          infof(data, "no chunk, no close, no size. Assume close to "
+                "signal end\n");
+          streamclose(conn, "HTTP: No end-of-message indicator");
+        }
+      }
+
+      /* At this point we have some idea about the fate of the connection.
+         If we are closing the connection it may result auth failure. */
+#if defined(USE_NTLM)
+      if(conn->bits.close &&
+         (((data->req.httpcode == 401) &&
+           (conn->ntlm.state == NTLMSTATE_TYPE2)) ||
+          ((data->req.httpcode == 407) &&
+           (conn->proxyntlm.state == NTLMSTATE_TYPE2)))) {
+        infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
+        data->state.authproblem = TRUE;
+      }
+#endif
+
+      /*
+       * When all the headers have been parsed, see if we should give
+       * up and return an error.
+       */
+      if(http_should_fail(conn)) {
+        failf(data, "The requested URL returned error: %d",
+              k->httpcode);
+        return CURLE_HTTP_RETURNED_ERROR;
+      }
+
+      /* now, only output this if the header AND body are requested:
+       */
+      writetype = CLIENTWRITE_HEADER;
+      if(data->set.include_header)
+        writetype |= CLIENTWRITE_BODY;
+
+      headerlen = k->p - data->state.headerbuff;
+
+      result = Curl_client_write(conn, writetype,
+                                 data->state.headerbuff,
+                                 headerlen);
+      if(result)
+        return result;
+
+      data->info.header_size += (long)headerlen;
+      data->req.headerbytecount += (long)headerlen;
+
+      data->req.deductheadercount =
+        (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
+
+      /* Curl_http_auth_act() checks what authentication methods
+       * that are available and decides which one (if any) to
+       * use. It will set 'newurl' if an auth method was picked. */
+      result = Curl_http_auth_act(conn);
+
+      if(result)
+        return result;
+
+      if(k->httpcode >= 300) {
+        if((!conn->bits.authneg) && !conn->bits.close &&
+           !conn->bits.rewindaftersend) {
+          /*
+           * General treatment of errors when about to send data. Including :
+           * "417 Expectation Failed", while waiting for 100-continue.
+           *
+           * The check for close above is done simply because of something
+           * else has already deemed the connection to get closed then
+           * something else should've considered the big picture and we
+           * avoid this check.
+           *
+           * rewindaftersend indicates that something has told libcurl to
+           * continue sending even if it gets discarded
+           */
+
+          switch(data->set.httpreq) {
+          case HTTPREQ_PUT:
+          case HTTPREQ_POST:
+          case HTTPREQ_POST_FORM:
+          case HTTPREQ_POST_MIME:
+            /* We got an error response. If this happened before the whole
+             * request body has been sent we stop sending and mark the
+             * connection for closure after we've read the entire response.
+             */
+            Curl_expire_done(data, EXPIRE_100_TIMEOUT);
+            if(!k->upload_done) {
+              if(data->set.http_keep_sending_on_error) {
+                infof(data, "HTTP error before end of send, keep sending\n");
+                if(k->exp100 > EXP100_SEND_DATA) {
+                  k->exp100 = EXP100_SEND_DATA;
+                  k->keepon |= KEEP_SEND;
+                }
+              }
+              else {
+                infof(data, "HTTP error before end of send, stop sending\n");
+                streamclose(conn, "Stop sending data before everything sent");
+                k->upload_done = TRUE;
+                k->keepon &= ~KEEP_SEND; /* don't send */
+                if(data->state.expect100header)
+                  k->exp100 = EXP100_FAILED;
+              }
+            }
+            break;
+
+          default: /* default label present to avoid compiler warnings */
+            break;
+          }
+        }
+
+        if(conn->bits.rewindaftersend) {
+          /* We rewind after a complete send, so thus we continue
+             sending now */
+          infof(data, "Keep sending data to get tossed away!\n");
+          k->keepon |= KEEP_SEND;
+        }
+      }
+
+      if(!k->header) {
+        /*
+         * really end-of-headers.
+         *
+         * If we requested a "no body", this is a good time to get
+         * out and return home.
+         */
+        if(data->set.opt_no_body)
+          *stop_reading = TRUE;
+#ifndef CURL_DISABLE_RTSP
+        else if((conn->handler->protocol & CURLPROTO_RTSP) &&
+                (data->set.rtspreq == RTSPREQ_DESCRIBE) &&
+                (k->size <= -1))
+          /* Respect section 4.4 of rfc2326: If the Content-Length header is
+             absent, a length 0 must be assumed.  It will prevent libcurl from
+             hanging on DESCRIBE request that got refused for whatever
+             reason */
+          *stop_reading = TRUE;
+#endif
+        else {
+          /* If we know the expected size of this document, we set the
+             maximum download size to the size of the expected
+             document or else, we won't know when to stop reading!
+
+             Note that we set the download maximum even if we read a
+             "Connection: close" header, to make sure that
+             "Content-Length: 0" still prevents us from attempting to
+             read the (missing) response-body.
+          */
+          /* According to RFC2616 section 4.4, we MUST ignore
+             Content-Length: headers if we are now receiving data
+             using chunked Transfer-Encoding.
+          */
+          if(k->chunk)
+            k->maxdownload = k->size = -1;
+        }
+        if(-1 != k->size) {
+          /* We do this operation even if no_body is true, since this
+             data might be retrieved later with curl_easy_getinfo()
+             and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
+
+          Curl_pgrsSetDownloadSize(data, k->size);
+          k->maxdownload = k->size;
+        }
+
+        /* If max download size is *zero* (nothing) we already have
+           nothing and can safely return ok now!  But for HTTP/2, we'd
+           like to call http2_handle_stream_close to properly close a
+           stream.  In order to do this, we keep reading until we
+           close the stream. */
+        if(0 == k->maxdownload
+#if defined(USE_NGHTTP2)
+           && !((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
+                conn->httpversion == 20)
+#endif
+           )
+          *stop_reading = TRUE;
+
+        if(*stop_reading) {
+          /* we make sure that this socket isn't read more now */
+          k->keepon &= ~KEEP_RECV;
+        }
+
+        if(data->set.verbose)
+          Curl_debug(data, CURLINFO_HEADER_IN,
+                     k->str_start, headerlen, conn);
+        break;          /* exit header line loop */
+      }
+
+      /* We continue reading headers, so reset the line-based
+         header parsing variables hbufp && hbuflen */
+      k->hbufp = data->state.headerbuff;
+      k->hbuflen = 0;
+      continue;
+    }
+
+    /*
+     * Checks for special headers coming up.
+     */
+
+    if(!k->headerline++) {
+      /* This is the first header, it MUST be the error code line
+         or else we consider this to be the body right away! */
+      int httpversion_major;
+      int rtspversion_major;
+      int nc = 0;
+#ifdef CURL_DOES_CONVERSIONS
+#define HEADER1 scratch
+#define SCRATCHSIZE 21
+      CURLcode res;
+      char scratch[SCRATCHSIZE + 1]; /* "HTTP/major.minor 123" */
+      /* We can't really convert this yet because we
+         don't know if it's the 1st header line or the body.
+         So we do a partial conversion into a scratch area,
+         leaving the data at k->p as-is.
+      */
+      strncpy(&scratch[0], k->p, SCRATCHSIZE);
+      scratch[SCRATCHSIZE] = 0; /* null terminate */
+      res = Curl_convert_from_network(data,
+                                      &scratch[0],
+                                      SCRATCHSIZE);
+      if(res)
+        /* Curl_convert_from_network calls failf if unsuccessful */
+        return res;
+#else
+#define HEADER1 k->p /* no conversion needed, just use k->p */
+#endif /* CURL_DOES_CONVERSIONS */
+
+      if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
+        /*
+         * https://tools.ietf.org/html/rfc7230#section-3.1.2
+         *
+         * The response code is always a three-digit number in HTTP as the spec
+         * says. We try to allow any number here, but we cannot make
+         * guarantees on future behaviors since it isn't within the protocol.
+         */
+        char separator;
+        nc = sscanf(HEADER1,
+                    " HTTP/%1d.%1d%c%3d",
+                    &httpversion_major,
+                    &conn->httpversion,
+                    &separator,
+                    &k->httpcode);
+
+        if(nc == 1 && httpversion_major == 2 &&
+           1 == sscanf(HEADER1, " HTTP/2 %d", &k->httpcode)) {
+          conn->httpversion = 0;
+          nc = 4;
+          separator = ' ';
+        }
+
+        if((nc == 4) && (' ' == separator)) {
+          conn->httpversion += 10 * httpversion_major;
+
+          if(k->upgr101 == UPGR101_RECEIVED) {
+            /* supposedly upgraded to http2 now */
+            if(conn->httpversion != 20)
+              infof(data, "Lying server, not serving HTTP/2\n");
+          }
+        }
+        else if(!nc) {
+          /* this is the real world, not a Nirvana
+             NCSA 1.5.x returns this crap when asked for HTTP/1.1
+          */
+          nc = sscanf(HEADER1, " HTTP %3d", &k->httpcode);
+          conn->httpversion = 10;
+
+          /* If user has set option HTTP200ALIASES,
+             compare header line against list of aliases
+          */
+          if(!nc) {
+            if(checkhttpprefix(data, k->p)) {
+              nc = 1;
+              k->httpcode = 200;
+              conn->httpversion = 10;
+            }
+          }
+        }
+        else {
+          failf(data, "Unsupported HTTP version in response\n");
+          return CURLE_UNSUPPORTED_PROTOCOL;
+        }
+      }
+      else if(conn->handler->protocol & CURLPROTO_RTSP) {
+        char separator;
+        nc = sscanf(HEADER1,
+                    " RTSP/%1d.%1d%c%3d",
+                    &rtspversion_major,
+                    &conn->rtspversion,
+                    &separator,
+                    &k->httpcode);
+        if((nc == 4) && (' ' == separator)) {
+          conn->rtspversion += 10 * rtspversion_major;
+          conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
+        }
+        else {
+          /* TODO: do we care about the other cases here? */
+          nc = 0;
+        }
+      }
+
+      if(nc) {
+        data->info.httpcode = k->httpcode;
+
+        data->info.httpversion = conn->httpversion;
+        if(!data->state.httpversion ||
+           data->state.httpversion > conn->httpversion)
+          /* store the lowest server version we encounter */
+          data->state.httpversion = conn->httpversion;
+
+        /*
+         * This code executes as part of processing the header.  As a
+         * result, it's not totally clear how to interpret the
+         * response code yet as that depends on what other headers may
+         * be present.  401 and 407 may be errors, but may be OK
+         * depending on how authentication is working.  Other codes
+         * are definitely errors, so give up here.
+         */
+        if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
+           ((k->httpcode != 401) || !conn->bits.user_passwd) &&
+           ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
+
+          if(data->state.resume_from &&
+             (data->set.httpreq == HTTPREQ_GET) &&
+             (k->httpcode == 416)) {
+            /* "Requested Range Not Satisfiable", just proceed and
+               pretend this is no error */
+          }
+          else {
+            /* serious error, go home! */
+            print_http_error(data);
+            return CURLE_HTTP_RETURNED_ERROR;
+          }
+        }
+
+        if(conn->httpversion == 10) {
+          /* Default action for HTTP/1.0 must be to close, unless
+             we get one of those fancy headers that tell us the
+             server keeps it open for us! */
+          infof(data, "HTTP 1.0, assume close after body\n");
+          connclose(conn, "HTTP/1.0 close after body");
+        }
+        else if(conn->httpversion == 20 ||
+                (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) {
+          DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n"));
+
+          /* HTTP/2 cannot blacklist multiplexing since it is a core
+             functionality of the protocol */
+          conn->bundle->multiuse = BUNDLE_MULTIPLEX;
+        }
+        else if(conn->httpversion >= 11 &&
+                !conn->bits.close) {
+          /* If HTTP version is >= 1.1 and connection is persistent
+             server supports pipelining. */
+          DEBUGF(infof(data,
+                       "HTTP 1.1 or later with persistent connection, "
+                       "pipelining supported\n"));
+          /* Activate pipelining if needed */
+          if(conn->bundle) {
+            if(!Curl_pipeline_site_blacklisted(data, conn))
+              conn->bundle->multiuse = BUNDLE_PIPELINING;
+          }
+        }
+
+        switch(k->httpcode) {
+        case 204:
+          /* (quote from RFC2616, section 10.2.5): The server has
+           * fulfilled the request but does not need to return an
+           * entity-body ... The 204 response MUST NOT include a
+           * message-body, and thus is always terminated by the first
+           * empty line after the header fields. */
+          /* FALLTHROUGH */
+        case 304:
+          /* (quote from RFC2616, section 10.3.5): The 304 response
+           * MUST NOT contain a message-body, and thus is always
+           * terminated by the first empty line after the header
+           * fields.  */
+          if(data->set.timecondition)
+            data->info.timecond = TRUE;
+          k->size = 0;
+          k->maxdownload = 0;
+          k->ignorecl = TRUE; /* ignore Content-Length headers */
+          break;
+        default:
+          /* nothing */
+          break;
+        }
+      }
+      else {
+        k->header = FALSE;   /* this is not a header line */
+        break;
+      }
+    }
+
+    result = Curl_convert_from_network(data, k->p, strlen(k->p));
+    /* Curl_convert_from_network calls failf if unsuccessful */
+    if(result)
+      return result;
+
+    /* Check for Content-Length: header lines to get size */
+    if(!k->ignorecl && !data->set.ignorecl &&
+       checkprefix("Content-Length:", k->p)) {
+      curl_off_t contentlength;
+      if(!curlx_strtoofft(k->p + 15, NULL, 10, &contentlength)) {
+        if(data->set.max_filesize &&
+           contentlength > data->set.max_filesize) {
+          failf(data, "Maximum file size exceeded");
+          return CURLE_FILESIZE_EXCEEDED;
+        }
+        if(contentlength >= 0) {
+          k->size = contentlength;
+          k->maxdownload = k->size;
+          /* we set the progress download size already at this point
+             just to make it easier for apps/callbacks to extract this
+             info as soon as possible */
+          Curl_pgrsSetDownloadSize(data, k->size);
+        }
+        else {
+          /* Negative Content-Length is really odd, and we know it
+             happens for example when older Apache servers send large
+             files */
+          streamclose(conn, "negative content-length");
+          infof(data, "Negative content-length: %" CURL_FORMAT_CURL_OFF_T
+                ", closing after transfer\n", contentlength);
+        }
+      }
+      else
+        infof(data, "Illegal Content-Length: header\n");
+    }
+    /* check for Content-Type: header lines to get the MIME-type */
+    else if(checkprefix("Content-Type:", k->p)) {
+      char *contenttype = Curl_copy_header_value(k->p);
+      if(!contenttype)
+        return CURLE_OUT_OF_MEMORY;
+      if(!*contenttype)
+        /* ignore empty data */
+        free(contenttype);
+      else {
+        Curl_safefree(data->info.contenttype);
+        data->info.contenttype = contenttype;
+      }
+    }
+    else if(checkprefix("Server:", k->p)) {
+      if(conn->httpversion < 20) {
+        /* only do this for non-h2 servers */
+        char *server_name = Curl_copy_header_value(k->p);
+
+        /* Turn off pipelining if the server version is blacklisted  */
+        if(conn->bundle && (conn->bundle->multiuse == BUNDLE_PIPELINING)) {
+          if(Curl_pipeline_server_blacklisted(data, server_name))
+            conn->bundle->multiuse = BUNDLE_NO_MULTIUSE;
+        }
+        free(server_name);
+      }
+    }
+    else if((conn->httpversion == 10) &&
+            conn->bits.httpproxy &&
+            Curl_compareheader(k->p,
+                               "Proxy-Connection:", "keep-alive")) {
+      /*
+       * When a HTTP/1.0 reply comes when using a proxy, the
+       * 'Proxy-Connection: keep-alive' line tells us the
+       * connection will be kept alive for our pleasure.
+       * Default action for 1.0 is to close.
+       */
+      connkeep(conn, "Proxy-Connection keep-alive"); /* don't close */
+      infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
+    }
+    else if((conn->httpversion == 11) &&
+            conn->bits.httpproxy &&
+            Curl_compareheader(k->p,
+                               "Proxy-Connection:", "close")) {
+      /*
+       * We get a HTTP/1.1 response from a proxy and it says it'll
+       * close down after this transfer.
+       */
+      connclose(conn, "Proxy-Connection: asked to close after done");
+      infof(data, "HTTP/1.1 proxy connection set close!\n");
+    }
+    else if((conn->httpversion == 10) &&
+            Curl_compareheader(k->p, "Connection:", "keep-alive")) {
+      /*
+       * A HTTP/1.0 reply with the 'Connection: keep-alive' line
+       * tells us the connection will be kept alive for our
+       * pleasure.  Default action for 1.0 is to close.
+       *
+       * [RFC2068, section 19.7.1] */
+      connkeep(conn, "Connection keep-alive");
+      infof(data, "HTTP/1.0 connection set to keep alive!\n");
+    }
+    else if(Curl_compareheader(k->p, "Connection:", "close")) {
+      /*
+       * [RFC 2616, section 8.1.2.1]
+       * "Connection: close" is HTTP/1.1 language and means that
+       * the connection will close when this request has been
+       * served.
+       */
+      streamclose(conn, "Connection: close used");
+    }
+    else if(checkprefix("Transfer-Encoding:", k->p)) {
+      /* One or more encodings. We check for chunked and/or a compression
+         algorithm. */
+      /*
+       * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
+       * means that the server will send a series of "chunks". Each
+       * chunk starts with line with info (including size of the
+       * coming block) (terminated with CRLF), then a block of data
+       * with the previously mentioned size. There can be any amount
+       * of chunks, and a chunk-data set to zero signals the
+       * end-of-chunks. */
+
+      result = Curl_build_unencoding_stack(conn, k->p + 18, TRUE);
+      if(result)
+        return result;
+    }
+    else if(checkprefix("Content-Encoding:", k->p) &&
+            data->set.str[STRING_ENCODING]) {
+      /*
+       * Process Content-Encoding. Look for the values: identity,
+       * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
+       * x-compress are the same as gzip and compress. (Sec 3.5 RFC
+       * 2616). zlib cannot handle compress.  However, errors are
+       * handled further down when the response body is processed
+       */
+      result = Curl_build_unencoding_stack(conn, k->p + 17, FALSE);
+      if(result)
+        return result;
+    }
+    else if(checkprefix("Content-Range:", k->p)) {
+      /* Content-Range: bytes [num]-
+         Content-Range: bytes: [num]-
+         Content-Range: [num]-
+         Content-Range: [asterisk]/[total]
+
+         The second format was added since Sun's webserver
+         JavaWebServer/1.1.1 obviously sends the header this way!
+         The third added since some servers use that!
+         The forth means the requested range was unsatisfied.
+      */
+
+      char *ptr = k->p + 14;
+
+      /* Move forward until first digit or asterisk */
+      while(*ptr && !ISDIGIT(*ptr) && *ptr != '*')
+        ptr++;
+
+      /* if it truly stopped on a digit */
+      if(ISDIGIT(*ptr)) {
+        if(!curlx_strtoofft(ptr, NULL, 10, &k->offset)) {
+          if(data->state.resume_from == k->offset)
+            /* we asked for a resume and we got it */
+            k->content_range = TRUE;
+        }
+      }
+      else
+        data->state.resume_from = 0; /* get everything */
+    }
+#if !defined(CURL_DISABLE_COOKIES)
+    else if(data->cookies &&
+            checkprefix("Set-Cookie:", k->p)) {
+      Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
+                      CURL_LOCK_ACCESS_SINGLE);
+      Curl_cookie_add(data,
+                      data->cookies, TRUE, k->p + 11,
+                      /* If there is a custom-set Host: name, use it
+                         here, or else use real peer host name. */
+                      conn->allocptr.cookiehost?
+                      conn->allocptr.cookiehost:conn->host.name,
+                      data->state.path);
+      Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+    }
+#endif
+    else if(checkprefix("Last-Modified:", k->p) &&
+            (data->set.timecondition || data->set.get_filetime) ) {
+      time_t secs = time(NULL);
+      k->timeofdoc = curl_getdate(k->p + strlen("Last-Modified:"),
+                                  &secs);
+      if(data->set.get_filetime)
+        data->info.filetime = (long)k->timeofdoc;
+    }
+    else if((checkprefix("WWW-Authenticate:", k->p) &&
+             (401 == k->httpcode)) ||
+            (checkprefix("Proxy-authenticate:", k->p) &&
+             (407 == k->httpcode))) {
+
+      bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
+      char *auth = Curl_copy_header_value(k->p);
+      if(!auth)
+        return CURLE_OUT_OF_MEMORY;
+
+      result = Curl_http_input_auth(conn, proxy, auth);
+
+      free(auth);
+
+      if(result)
+        return result;
+    }
+    else if((k->httpcode >= 300 && k->httpcode < 400) &&
+            checkprefix("Location:", k->p) &&
+            !data->req.location) {
+      /* this is the URL that the server advises us to use instead */
+      char *location = Curl_copy_header_value(k->p);
+      if(!location)
+        return CURLE_OUT_OF_MEMORY;
+      if(!*location)
+        /* ignore empty data */
+        free(location);
+      else {
+        data->req.location = location;
+
+        if(data->set.http_follow_location) {
+          DEBUGASSERT(!data->req.newurl);
+          data->req.newurl = strdup(data->req.location); /* clone */
+          if(!data->req.newurl)
+            return CURLE_OUT_OF_MEMORY;
+
+          /* some cases of POST and PUT etc needs to rewind the data
+             stream at this point */
+          result = http_perhapsrewind(conn);
+          if(result)
+            return result;
+        }
+      }
+    }
+    else if(conn->handler->protocol & CURLPROTO_RTSP) {
+      result = Curl_rtsp_parseheader(conn, k->p);
+      if(result)
+        return result;
+    }
+
+    /*
+     * End of header-checks. Write them to the client.
+     */
+
+    writetype = CLIENTWRITE_HEADER;
+    if(data->set.include_header)
+      writetype |= CLIENTWRITE_BODY;
+
+    if(data->set.verbose)
+      Curl_debug(data, CURLINFO_HEADER_IN,
+                 k->p, (size_t)k->hbuflen, conn);
+
+    result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
+    if(result)
+      return result;
+
+    data->info.header_size += (long)k->hbuflen;
+    data->req.headerbytecount += (long)k->hbuflen;
+
+    /* reset hbufp pointer && hbuflen */
+    k->hbufp = data->state.headerbuff;
+    k->hbuflen = 0;
+  }
+  while(*k->str); /* header line within buffer */
+
+  /* We might have reached the end of the header part here, but
+     there might be a non-header part left in the end of the read
+     buffer. */
+
+  return CURLE_OK;
+}
+
+#endif /* CURL_DISABLE_HTTP */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/http.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/http.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/http.h	(revision 331)
@@ -0,0 +1,261 @@
+#ifndef HEADER_CURL_HTTP_H
+#define HEADER_CURL_HTTP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_HTTP
+
+#ifdef USE_NGHTTP2
+#include <nghttp2/nghttp2.h>
+#endif
+
+extern const struct Curl_handler Curl_handler_http;
+
+#ifdef USE_SSL
+extern const struct Curl_handler Curl_handler_https;
+#endif
+
+/* Header specific functions */
+bool Curl_compareheader(const char *headerline,  /* line to check */
+                        const char *header,   /* header keyword _with_ colon */
+                        const char *content); /* content string to find */
+
+char *Curl_copy_header_value(const char *header);
+
+char *Curl_checkProxyheaders(const struct connectdata *conn,
+                             const char *thisheader);
+/* ------------------------------------------------------------------------- */
+/*
+ * The add_buffer series of functions are used to build one large memory chunk
+ * from repeated function invokes. Used so that the entire HTTP request can
+ * be sent in one go.
+ */
+struct Curl_send_buffer {
+  char *buffer;
+  size_t size_max;
+  size_t size_used;
+};
+typedef struct Curl_send_buffer Curl_send_buffer;
+
+Curl_send_buffer *Curl_add_buffer_init(void);
+void Curl_add_buffer_free(Curl_send_buffer *buff);
+CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...);
+CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size);
+CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
+                              struct connectdata *conn,
+                              long *bytes_written,
+                              size_t included_body_bytes,
+                              int socketindex);
+
+CURLcode Curl_add_timecondition(struct Curl_easy *data,
+                                Curl_send_buffer *buf);
+CURLcode Curl_add_custom_headers(struct connectdata *conn,
+                                 bool is_connect,
+                                 Curl_send_buffer *req_buffer);
+
+/* protocol-specific functions set up to be called by the main engine */
+CURLcode Curl_http(struct connectdata *conn, bool *done);
+CURLcode Curl_http_done(struct connectdata *, CURLcode, bool premature);
+CURLcode Curl_http_connect(struct connectdata *conn, bool *done);
+CURLcode Curl_http_setup_conn(struct connectdata *conn);
+
+/* The following functions are defined in http_chunks.c */
+void Curl_httpchunk_init(struct connectdata *conn);
+CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
+                              ssize_t length, ssize_t *wrote);
+
+/* These functions are in http.c */
+void Curl_http_auth_stage(struct Curl_easy *data, int stage);
+CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
+                              const char *auth);
+CURLcode Curl_http_auth_act(struct connectdata *conn);
+CURLcode Curl_http_perhapsrewind(struct connectdata *conn);
+
+/* If only the PICKNONE bit is set, there has been a round-trip and we
+   selected to use no auth at all. Ie, we actively select no auth, as opposed
+   to not having one selected. The other CURLAUTH_* defines are present in the
+   public curl/curl.h header. */
+#define CURLAUTH_PICKNONE (1<<30) /* don't use auth */
+
+/* MAX_INITIAL_POST_SIZE indicates the number of bytes that will make the POST
+   data get included in the initial data chunk sent to the server. If the
+   data is larger than this, it will automatically get split up in multiple
+   system calls.
+
+   This value used to be fairly big (100K), but we must take into account that
+   if the server rejects the POST due for authentication reasons, this data
+   will always be uncondtionally sent and thus it may not be larger than can
+   always be afforded to send twice.
+
+   It must not be greater than 64K to work on VMS.
+*/
+#ifndef MAX_INITIAL_POST_SIZE
+#define MAX_INITIAL_POST_SIZE (64*1024)
+#endif
+
+/* EXPECT_100_THRESHOLD is the request body size limit for when libcurl will
+ * automatically add an "Expect: 100-continue" header in HTTP requests. When
+ * the size is unknown, it will always add it.
+ *
+ */
+#ifndef EXPECT_100_THRESHOLD
+#define EXPECT_100_THRESHOLD 1024
+#endif
+
+#endif /* CURL_DISABLE_HTTP */
+
+/****************************************************************************
+ * HTTP unique setup
+ ***************************************************************************/
+struct HTTP {
+  curl_mimepart *sendit;
+  curl_off_t postsize; /* off_t to handle large file sizes */
+  const char *postdata;
+
+  const char *p_pragma;      /* Pragma: string */
+  const char *p_accept;      /* Accept: string */
+  curl_off_t readbytecount;
+  curl_off_t writebytecount;
+
+  /* For FORM posting */
+  curl_mimepart form;
+
+  struct back {
+    curl_read_callback fread_func; /* backup storage for fread pointer */
+    void *fread_in;           /* backup storage for fread_in pointer */
+    const char *postdata;
+    curl_off_t postsize;
+  } backup;
+
+  enum {
+    HTTPSEND_NADA,    /* init */
+    HTTPSEND_REQUEST, /* sending a request */
+    HTTPSEND_BODY,    /* sending body */
+    HTTPSEND_LAST     /* never use this */
+  } sending;
+
+  void *send_buffer; /* used if the request couldn't be sent in one chunk,
+                        points to an allocated send_buffer struct */
+
+#ifdef USE_NGHTTP2
+  /*********** for HTTP/2 we store stream-local data here *************/
+  int32_t stream_id; /* stream we are interested in */
+
+  bool bodystarted;
+  /* We store non-final and final response headers here, per-stream */
+  Curl_send_buffer *header_recvbuf;
+  size_t nread_header_recvbuf; /* number of bytes in header_recvbuf fed into
+                                  upper layer */
+  Curl_send_buffer *trailer_recvbuf;
+  int status_code; /* HTTP status code */
+  const uint8_t *pausedata; /* pointer to data received in on_data_chunk */
+  size_t pauselen; /* the number of bytes left in data */
+  bool closed; /* TRUE on HTTP2 stream close */
+  bool close_handled; /* TRUE if stream closure is handled by libcurl */
+  uint32_t error_code; /* HTTP/2 error code */
+
+  char *mem;     /* points to a buffer in memory to store received data */
+  size_t len;    /* size of the buffer 'mem' points to */
+  size_t memlen; /* size of data copied to mem */
+
+  const uint8_t *upload_mem; /* points to a buffer to read from */
+  size_t upload_len; /* size of the buffer 'upload_mem' points to */
+  curl_off_t upload_left; /* number of bytes left to upload */
+
+  char **push_headers;       /* allocated array */
+  size_t push_headers_used;  /* number of entries filled in */
+  size_t push_headers_alloc; /* number of entries allocated */
+#endif
+};
+
+typedef int (*sending)(void); /* Curl_send */
+typedef int (*recving)(void); /* Curl_recv */
+
+#ifdef USE_NGHTTP2
+/* h2 settings for this connection */
+struct h2settings {
+  uint32_t max_concurrent_streams;
+  bool enable_push;
+};
+#endif
+
+
+struct http_conn {
+#ifdef USE_NGHTTP2
+#define H2_BINSETTINGS_LEN 80
+  nghttp2_session *h2;
+  uint8_t binsettings[H2_BINSETTINGS_LEN];
+  size_t  binlen; /* length of the binsettings data */
+  sending send_underlying; /* underlying send Curl_send callback */
+  recving recv_underlying; /* underlying recv Curl_recv callback */
+  char *inbuf; /* buffer to receive data from underlying socket */
+  size_t inbuflen; /* number of bytes filled in inbuf */
+  size_t nread_inbuf; /* number of bytes read from in inbuf */
+  /* We need separate buffer for transmission and reception because we
+     may call nghttp2_session_send() after the
+     nghttp2_session_mem_recv() but mem buffer is still not full. In
+     this case, we wrongly sends the content of mem buffer if we share
+     them for both cases. */
+  int32_t pause_stream_id; /* stream ID which paused
+                              nghttp2_session_mem_recv */
+  size_t drain_total; /* sum of all stream's UrlState.drain */
+
+  /* this is a hash of all individual streams (Curl_easy structs) */
+  struct h2settings settings;
+
+  /* list of settings that will be sent */
+  nghttp2_settings_entry local_settings[3];
+  size_t local_settings_num;
+#else
+  int unused; /* prevent a compiler warning */
+#endif
+};
+
+CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
+                                     struct connectdata *conn,
+                                     ssize_t *nread,
+                                     bool *stop_reading);
+
+/**
+ * Curl_http_output_auth() setups the authentication headers for the
+ * host/proxy and the correct authentication
+ * method. conn->data->state.authdone is set to TRUE when authentication is
+ * done.
+ *
+ * @param conn all information about the current connection
+ * @param request pointer to the request keyword
+ * @param path pointer to the requested path
+ * @param proxytunnel boolean if this is the request setting up a "proxy
+ * tunnel"
+ *
+ * @returns CURLcode
+ */
+CURLcode
+Curl_http_output_auth(struct connectdata *conn,
+                      const char *request,
+                      const char *path,
+                      bool proxytunnel); /* TRUE if this is the request setting
+                                            up the proxy tunnel */
+
+#endif /* HEADER_CURL_HTTP_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/http2.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/http2.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/http2.c	(revision 331)
@@ -0,0 +1,2286 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_NGHTTP2
+#include <nghttp2/nghttp2.h>
+#include "urldata.h"
+#include "http2.h"
+#include "http.h"
+#include "sendf.h"
+#include "select.h"
+#include "curl_base64.h"
+#include "strcase.h"
+#include "multiif.h"
+#include "url.h"
+#include "connect.h"
+#include "strtoofft.h"
+#include "strdup.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define MIN(x,y) ((x)<(y)?(x):(y))
+
+#if (NGHTTP2_VERSION_NUM < 0x010000)
+#error too old nghttp2 version, upgrade!
+#endif
+
+#if (NGHTTP2_VERSION_NUM > 0x010800)
+#define NGHTTP2_HAS_HTTP2_STRERROR 1
+#endif
+
+#if (NGHTTP2_VERSION_NUM >= 0x010900)
+/* nghttp2_session_callbacks_set_error_callback is present in nghttp2 1.9.0 or
+   later */
+#define NGHTTP2_HAS_ERROR_CALLBACK 1
+#else
+#define nghttp2_session_callbacks_set_error_callback(x,y)
+#endif
+
+#if (NGHTTP2_VERSION_NUM >= 0x010c00)
+#define NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE 1
+#endif
+
+#define HTTP2_HUGE_WINDOW_SIZE (1 << 30)
+
+/*
+ * Curl_http2_init_state() is called when the easy handle is created and
+ * allows for HTTP/2 specific init of state.
+ */
+void Curl_http2_init_state(struct UrlState *state)
+{
+  state->stream_weight = NGHTTP2_DEFAULT_WEIGHT;
+}
+
+/*
+ * Curl_http2_init_userset() is called when the easy handle is created and
+ * allows for HTTP/2 specific user-set fields.
+ */
+void Curl_http2_init_userset(struct UserDefined *set)
+{
+  set->stream_weight = NGHTTP2_DEFAULT_WEIGHT;
+}
+
+static int http2_perform_getsock(const struct connectdata *conn,
+                                 curl_socket_t *sock, /* points to
+                                                         numsocks
+                                                         number of
+                                                         sockets */
+                                 int numsocks)
+{
+  const struct http_conn *c = &conn->proto.httpc;
+  int bitmap = GETSOCK_BLANK;
+  (void)numsocks;
+
+  /* TODO We should check underlying socket state if it is SSL socket
+     because of renegotiation. */
+  sock[0] = conn->sock[FIRSTSOCKET];
+
+  /* in a HTTP/2 connection we can basically always get a frame so we should
+     always be ready for one */
+  bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
+
+  if(nghttp2_session_want_write(c->h2))
+    bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
+
+  return bitmap;
+}
+
+static int http2_getsock(struct connectdata *conn,
+                         curl_socket_t *sock, /* points to numsocks
+                                                 number of sockets */
+                         int numsocks)
+{
+  return http2_perform_getsock(conn, sock, numsocks);
+}
+
+/*
+ * http2_stream_free() free HTTP2 stream related data
+ */
+static void http2_stream_free(struct HTTP *http)
+{
+  if(http) {
+    Curl_add_buffer_free(http->header_recvbuf);
+    http->header_recvbuf = NULL; /* clear the pointer */
+    Curl_add_buffer_free(http->trailer_recvbuf);
+    http->trailer_recvbuf = NULL; /* clear the pointer */
+    for(; http->push_headers_used > 0; --http->push_headers_used) {
+      free(http->push_headers[http->push_headers_used - 1]);
+    }
+    free(http->push_headers);
+    http->push_headers = NULL;
+  }
+}
+
+static CURLcode http2_disconnect(struct connectdata *conn,
+                                 bool dead_connection)
+{
+  struct http_conn *c = &conn->proto.httpc;
+  (void)dead_connection;
+
+  DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT starts now\n"));
+
+  nghttp2_session_del(c->h2);
+  Curl_safefree(c->inbuf);
+  http2_stream_free(conn->data->req.protop);
+
+  DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n"));
+
+  return CURLE_OK;
+}
+
+/*
+ * The server may send us data at any point (e.g. PING frames). Therefore,
+ * we cannot assume that an HTTP/2 socket is dead just because it is readable.
+ *
+ * Instead, if it is readable, run Curl_connalive() to peek at the socket
+ * and distinguish between closed and data.
+ */
+static bool http2_connisdead(struct connectdata *check)
+{
+  int sval;
+  bool ret_val = TRUE;
+
+  sval = SOCKET_READABLE(check->sock[FIRSTSOCKET], 0);
+  if(sval == 0) {
+    /* timeout */
+    ret_val = FALSE;
+  }
+  else if(sval & CURL_CSELECT_ERR) {
+    /* socket is in an error state */
+    ret_val = TRUE;
+  }
+  else if(sval & CURL_CSELECT_IN) {
+    /* readable with no error. could still be closed */
+    ret_val = !Curl_connalive(check);
+  }
+
+  return ret_val;
+}
+
+
+static unsigned int http2_conncheck(struct connectdata *check,
+                                    unsigned int checks_to_perform)
+{
+  unsigned int ret_val = CONNRESULT_NONE;
+
+  if(checks_to_perform & CONNCHECK_ISDEAD) {
+    if(http2_connisdead(check))
+      ret_val |= CONNRESULT_DEAD;
+  }
+
+  return ret_val;
+}
+
+/* called from Curl_http_setup_conn */
+void Curl_http2_setup_req(struct Curl_easy *data)
+{
+  struct HTTP *http = data->req.protop;
+
+  http->nread_header_recvbuf = 0;
+  http->bodystarted = FALSE;
+  http->status_code = -1;
+  http->pausedata = NULL;
+  http->pauselen = 0;
+  http->error_code = NGHTTP2_NO_ERROR;
+  http->closed = FALSE;
+  http->close_handled = FALSE;
+  http->mem = data->state.buffer;
+  http->len = data->set.buffer_size;
+  http->memlen = 0;
+}
+
+/* called from Curl_http_setup_conn */
+void Curl_http2_setup_conn(struct connectdata *conn)
+{
+  conn->proto.httpc.settings.max_concurrent_streams =
+    DEFAULT_MAX_CONCURRENT_STREAMS;
+}
+
+/*
+ * HTTP2 handler interface. This isn't added to the general list of protocols
+ * but will be used at run-time when the protocol is dynamically switched from
+ * HTTP to HTTP2.
+ */
+static const struct Curl_handler Curl_handler_http2 = {
+  "HTTP",                               /* scheme */
+  ZERO_NULL,                            /* setup_connection */
+  Curl_http,                            /* do_it */
+  Curl_http_done,                       /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  http2_getsock,                        /* proto_getsock */
+  http2_getsock,                        /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  http2_perform_getsock,                /* perform_getsock */
+  http2_disconnect,                     /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  http2_conncheck,                      /* connection_check */
+  PORT_HTTP,                            /* defport */
+  CURLPROTO_HTTP,                       /* protocol */
+  PROTOPT_STREAM                        /* flags */
+};
+
+static const struct Curl_handler Curl_handler_http2_ssl = {
+  "HTTPS",                              /* scheme */
+  ZERO_NULL,                            /* setup_connection */
+  Curl_http,                            /* do_it */
+  Curl_http_done,                       /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  http2_getsock,                        /* proto_getsock */
+  http2_getsock,                        /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  http2_perform_getsock,                /* perform_getsock */
+  http2_disconnect,                     /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  http2_conncheck,                      /* connection_check */
+  PORT_HTTP,                            /* defport */
+  CURLPROTO_HTTPS,                      /* protocol */
+  PROTOPT_SSL | PROTOPT_STREAM          /* flags */
+};
+
+/*
+ * Store nghttp2 version info in this buffer, Prefix with a space.  Return
+ * total length written.
+ */
+int Curl_http2_ver(char *p, size_t len)
+{
+  nghttp2_info *h2 = nghttp2_version(0);
+  return snprintf(p, len, " nghttp2/%s", h2->version_str);
+}
+
+/* HTTP/2 error code to name based on the Error Code Registry.
+https://tools.ietf.org/html/rfc7540#page-77
+nghttp2_error_code enums are identical.
+*/
+const char *Curl_http2_strerror(uint32_t err)
+{
+#ifndef NGHTTP2_HAS_HTTP2_STRERROR
+  const char *str[] = {
+    "NO_ERROR",             /* 0x0 */
+    "PROTOCOL_ERROR",       /* 0x1 */
+    "INTERNAL_ERROR",       /* 0x2 */
+    "FLOW_CONTROL_ERROR",   /* 0x3 */
+    "SETTINGS_TIMEOUT",     /* 0x4 */
+    "STREAM_CLOSED",        /* 0x5 */
+    "FRAME_SIZE_ERROR",     /* 0x6 */
+    "REFUSED_STREAM",       /* 0x7 */
+    "CANCEL",               /* 0x8 */
+    "COMPRESSION_ERROR",    /* 0x9 */
+    "CONNECT_ERROR",        /* 0xA */
+    "ENHANCE_YOUR_CALM",    /* 0xB */
+    "INADEQUATE_SECURITY",  /* 0xC */
+    "HTTP_1_1_REQUIRED"     /* 0xD */
+  };
+  return (err < sizeof str / sizeof str[0]) ? str[err] : "unknown";
+#else
+  return nghttp2_http2_strerror(err);
+#endif
+}
+
+/*
+ * The implementation of nghttp2_send_callback type. Here we write |data| with
+ * size |length| to the network and return the number of bytes actually
+ * written. See the documentation of nghttp2_send_callback for the details.
+ */
+static ssize_t send_callback(nghttp2_session *h2,
+                             const uint8_t *data, size_t length, int flags,
+                             void *userp)
+{
+  struct connectdata *conn = (struct connectdata *)userp;
+  struct http_conn *c = &conn->proto.httpc;
+  ssize_t written;
+  CURLcode result = CURLE_OK;
+
+  (void)h2;
+  (void)flags;
+
+  written = ((Curl_send*)c->send_underlying)(conn, FIRSTSOCKET,
+                                             data, length, &result);
+
+  if(result == CURLE_AGAIN) {
+    return NGHTTP2_ERR_WOULDBLOCK;
+  }
+
+  if(written == -1) {
+    failf(conn->data, "Failed sending HTTP2 data");
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
+
+  if(!written)
+    return NGHTTP2_ERR_WOULDBLOCK;
+
+  return written;
+}
+
+
+/* We pass a pointer to this struct in the push callback, but the contents of
+   the struct are hidden from the user. */
+struct curl_pushheaders {
+  struct Curl_easy *data;
+  const nghttp2_push_promise *frame;
+};
+
+/*
+ * push header access function. Only to be used from within the push callback
+ */
+char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num)
+{
+  /* Verify that we got a good easy handle in the push header struct, mostly to
+     detect rubbish input fast(er). */
+  if(!h || !GOOD_EASY_HANDLE(h->data))
+    return NULL;
+  else {
+    struct HTTP *stream = h->data->req.protop;
+    if(num < stream->push_headers_used)
+      return stream->push_headers[num];
+  }
+  return NULL;
+}
+
+/*
+ * push header access function. Only to be used from within the push callback
+ */
+char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
+{
+  /* Verify that we got a good easy handle in the push header struct,
+     mostly to detect rubbish input fast(er). Also empty header name
+     is just a rubbish too. We have to allow ":" at the beginning of
+     the header, but header == ":" must be rejected. If we have ':' in
+     the middle of header, it could be matched in middle of the value,
+     this is because we do prefix match.*/
+  if(!h || !GOOD_EASY_HANDLE(h->data) || !header || !header[0] ||
+     !strcmp(header, ":") || strchr(header + 1, ':'))
+    return NULL;
+  else {
+    struct HTTP *stream = h->data->req.protop;
+    size_t len = strlen(header);
+    size_t i;
+    for(i = 0; i<stream->push_headers_used; i++) {
+      if(!strncmp(header, stream->push_headers[i], len)) {
+        /* sub-match, make sure that it is followed by a colon */
+        if(stream->push_headers[i][len] != ':')
+          continue;
+        return &stream->push_headers[i][len + 1];
+      }
+    }
+  }
+  return NULL;
+}
+
+static struct Curl_easy *duphandle(struct Curl_easy *data)
+{
+  struct Curl_easy *second = curl_easy_duphandle(data);
+  if(second) {
+    /* setup the request struct */
+    struct HTTP *http = calloc(1, sizeof(struct HTTP));
+    if(!http) {
+      (void)Curl_close(second);
+      second = NULL;
+    }
+    else {
+      second->req.protop = http;
+      http->header_recvbuf = Curl_add_buffer_init();
+      if(!http->header_recvbuf) {
+        free(http);
+        (void)Curl_close(second);
+        second = NULL;
+      }
+      else {
+        Curl_http2_setup_req(second);
+        second->state.stream_weight = data->state.stream_weight;
+      }
+    }
+  }
+  return second;
+}
+
+
+static int push_promise(struct Curl_easy *data,
+                        struct connectdata *conn,
+                        const nghttp2_push_promise *frame)
+{
+  int rv;
+  DEBUGF(infof(data, "PUSH_PROMISE received, stream %u!\n",
+               frame->promised_stream_id));
+  if(data->multi->push_cb) {
+    struct HTTP *stream;
+    struct HTTP *newstream;
+    struct curl_pushheaders heads;
+    CURLMcode rc;
+    struct http_conn *httpc;
+    size_t i;
+    /* clone the parent */
+    struct Curl_easy *newhandle = duphandle(data);
+    if(!newhandle) {
+      infof(data, "failed to duplicate handle\n");
+      rv = 1; /* FAIL HARD */
+      goto fail;
+    }
+
+    heads.data = data;
+    heads.frame = frame;
+    /* ask the application */
+    DEBUGF(infof(data, "Got PUSH_PROMISE, ask application!\n"));
+
+    stream = data->req.protop;
+    if(!stream) {
+      failf(data, "Internal NULL stream!\n");
+      (void)Curl_close(newhandle);
+      rv = 1;
+      goto fail;
+    }
+
+    rv = data->multi->push_cb(data, newhandle,
+                              stream->push_headers_used, &heads,
+                              data->multi->push_userp);
+
+    /* free the headers again */
+    for(i = 0; i<stream->push_headers_used; i++)
+      free(stream->push_headers[i]);
+    free(stream->push_headers);
+    stream->push_headers = NULL;
+    stream->push_headers_used = 0;
+
+    if(rv) {
+      /* denied, kill off the new handle again */
+      http2_stream_free(newhandle->req.protop);
+      (void)Curl_close(newhandle);
+      goto fail;
+    }
+
+    newstream = newhandle->req.protop;
+    newstream->stream_id = frame->promised_stream_id;
+    newhandle->req.maxdownload = -1;
+    newhandle->req.size = -1;
+
+    /* approved, add to the multi handle and immediately switch to PERFORM
+       state with the given connection !*/
+    rc = Curl_multi_add_perform(data->multi, newhandle, conn);
+    if(rc) {
+      infof(data, "failed to add handle to multi\n");
+      http2_stream_free(newhandle->req.protop);
+      Curl_close(newhandle);
+      rv = 1;
+      goto fail;
+    }
+
+    httpc = &conn->proto.httpc;
+    nghttp2_session_set_stream_user_data(httpc->h2,
+                                         frame->promised_stream_id, newhandle);
+  }
+  else {
+    DEBUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n"));
+    rv = 1;
+  }
+  fail:
+  return rv;
+}
+
+static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
+                         void *userp)
+{
+  struct connectdata *conn = (struct connectdata *)userp;
+  struct http_conn *httpc = &conn->proto.httpc;
+  struct Curl_easy *data_s = NULL;
+  struct HTTP *stream = NULL;
+  static int lastStream = -1;
+  int rv;
+  size_t left, ncopy;
+  int32_t stream_id = frame->hd.stream_id;
+
+  if(!stream_id) {
+    /* stream ID zero is for connection-oriented stuff */
+    if(frame->hd.type == NGHTTP2_SETTINGS) {
+      uint32_t max_conn = httpc->settings.max_concurrent_streams;
+      DEBUGF(infof(conn->data, "Got SETTINGS\n"));
+      httpc->settings.max_concurrent_streams =
+        nghttp2_session_get_remote_settings(
+          session, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS);
+      httpc->settings.enable_push =
+        nghttp2_session_get_remote_settings(
+          session, NGHTTP2_SETTINGS_ENABLE_PUSH);
+      DEBUGF(infof(conn->data, "MAX_CONCURRENT_STREAMS == %d\n",
+                   httpc->settings.max_concurrent_streams));
+      DEBUGF(infof(conn->data, "ENABLE_PUSH == %s\n",
+                   httpc->settings.enable_push?"TRUE":"false"));
+      if(max_conn != httpc->settings.max_concurrent_streams) {
+        /* only signal change if the value actually changed */
+        infof(conn->data,
+              "Connection state changed (MAX_CONCURRENT_STREAMS updated)!\n");
+        Curl_multi_connchanged(conn->data->multi);
+      }
+    }
+    return 0;
+  }
+  data_s = nghttp2_session_get_stream_user_data(session, stream_id);
+  if(lastStream != stream_id) {
+    lastStream = stream_id;
+  }
+  if(!data_s) {
+    DEBUGF(infof(conn->data,
+                 "No Curl_easy associated with stream: %x\n",
+                 stream_id));
+    return 0;
+  }
+
+  stream = data_s->req.protop;
+  if(!stream) {
+    DEBUGF(infof(conn->data, "No proto pointer for stream: %x\n",
+                 stream_id));
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
+
+  DEBUGF(infof(data_s, "on_frame_recv() header %x stream %x\n",
+               frame->hd.type, stream_id));
+
+  switch(frame->hd.type) {
+  case NGHTTP2_DATA:
+    /* If body started on this stream, then receiving DATA is illegal. */
+    if(!stream->bodystarted) {
+      rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
+                                     stream_id, NGHTTP2_PROTOCOL_ERROR);
+
+      if(nghttp2_is_fatal(rv)) {
+        return NGHTTP2_ERR_CALLBACK_FAILURE;
+      }
+    }
+    break;
+  case NGHTTP2_HEADERS:
+    if(stream->bodystarted) {
+      /* Only valid HEADERS after body started is trailer HEADERS.  We
+         buffer them in on_header callback. */
+      break;
+    }
+
+    /* nghttp2 guarantees that :status is received, and we store it to
+       stream->status_code */
+    DEBUGASSERT(stream->status_code != -1);
+
+    /* Only final status code signals the end of header */
+    if(stream->status_code / 100 != 1) {
+      stream->bodystarted = TRUE;
+      stream->status_code = -1;
+    }
+
+    Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
+
+    left = stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
+    ncopy = MIN(stream->len, left);
+
+    memcpy(&stream->mem[stream->memlen],
+           stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
+           ncopy);
+    stream->nread_header_recvbuf += ncopy;
+
+    DEBUGF(infof(data_s, "Store %zu bytes headers from stream %u at %p\n",
+                 ncopy, stream_id, stream->mem));
+
+    stream->len -= ncopy;
+    stream->memlen += ncopy;
+
+    data_s->state.drain++;
+    httpc->drain_total++;
+    {
+      /* get the pointer from userp again since it was re-assigned above */
+      struct connectdata *conn_s = (struct connectdata *)userp;
+
+      /* if we receive data for another handle, wake that up */
+      if(conn_s->data != data_s)
+        Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
+    }
+    break;
+  case NGHTTP2_PUSH_PROMISE:
+    rv = push_promise(data_s, conn, &frame->push_promise);
+    if(rv) { /* deny! */
+      rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
+                                     frame->push_promise.promised_stream_id,
+                                     NGHTTP2_CANCEL);
+      if(nghttp2_is_fatal(rv)) {
+        return rv;
+      }
+    }
+    break;
+  default:
+    DEBUGF(infof(conn->data, "Got frame type %x for stream %u!\n",
+                 frame->hd.type, stream_id));
+    break;
+  }
+  return 0;
+}
+
+static int on_invalid_frame_recv(nghttp2_session *session,
+                                 const nghttp2_frame *frame,
+                                 int lib_error_code, void *userp)
+{
+  struct Curl_easy *data_s = NULL;
+  (void)userp;
+#if !defined(DEBUGBUILD) || defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void)lib_error_code;
+#endif
+
+  data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
+  if(data_s) {
+    DEBUGF(infof(data_s,
+                 "on_invalid_frame_recv() was called, error=%d:%s\n",
+                 lib_error_code, nghttp2_strerror(lib_error_code)));
+  }
+  return 0;
+}
+
+static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
+                              int32_t stream_id,
+                              const uint8_t *data, size_t len, void *userp)
+{
+  struct HTTP *stream;
+  struct Curl_easy *data_s;
+  size_t nread;
+  struct connectdata *conn = (struct connectdata *)userp;
+  (void)session;
+  (void)flags;
+  (void)data;
+
+  DEBUGASSERT(stream_id); /* should never be a zero stream ID here */
+
+  /* get the stream from the hash based on Stream ID */
+  data_s = nghttp2_session_get_stream_user_data(session, stream_id);
+  if(!data_s)
+    /* Receiving a Stream ID not in the hash should not happen, this is an
+       internal error more than anything else! */
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+  stream = data_s->req.protop;
+  if(!stream)
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+  nread = MIN(stream->len, len);
+  memcpy(&stream->mem[stream->memlen], data, nread);
+
+  stream->len -= nread;
+  stream->memlen += nread;
+
+  data_s->state.drain++;
+  conn->proto.httpc.drain_total++;
+
+  /* if we receive data for another handle, wake that up */
+  if(conn->data != data_s)
+    Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
+
+  DEBUGF(infof(data_s, "%zu data received for stream %u "
+               "(%zu left in buffer %p, total %zu)\n",
+               nread, stream_id,
+               stream->len, stream->mem,
+               stream->memlen));
+
+  if(nread < len) {
+    stream->pausedata = data + nread;
+    stream->pauselen = len - nread;
+    DEBUGF(infof(data_s, "NGHTTP2_ERR_PAUSE - %zu bytes out of buffer"
+                 ", stream %u\n",
+                 len - nread, stream_id));
+    data_s->easy_conn->proto.httpc.pause_stream_id = stream_id;
+
+    return NGHTTP2_ERR_PAUSE;
+  }
+
+  /* pause execution of nghttp2 if we received data for another handle
+     in order to process them first. */
+  if(conn->data != data_s) {
+    data_s->easy_conn->proto.httpc.pause_stream_id = stream_id;
+
+    return NGHTTP2_ERR_PAUSE;
+  }
+
+  return 0;
+}
+
+static int before_frame_send(nghttp2_session *session,
+                             const nghttp2_frame *frame,
+                             void *userp)
+{
+  struct Curl_easy *data_s;
+  (void)userp;
+
+  data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
+  if(data_s) {
+    DEBUGF(infof(data_s, "before_frame_send() was called\n"));
+  }
+
+  return 0;
+}
+static int on_frame_send(nghttp2_session *session,
+                         const nghttp2_frame *frame,
+                         void *userp)
+{
+  struct Curl_easy *data_s;
+  (void)userp;
+
+  data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
+  if(data_s) {
+    DEBUGF(infof(data_s, "on_frame_send() was called, length = %zd\n",
+                 frame->hd.length));
+  }
+  return 0;
+}
+static int on_frame_not_send(nghttp2_session *session,
+                             const nghttp2_frame *frame,
+                             int lib_error_code, void *userp)
+{
+  struct Curl_easy *data_s;
+  (void)userp;
+#if !defined(DEBUGBUILD) || defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void)lib_error_code;
+#endif
+
+  data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
+  if(data_s) {
+    DEBUGF(infof(data_s,
+                 "on_frame_not_send() was called, lib_error_code = %d\n",
+                 lib_error_code));
+  }
+  return 0;
+}
+static int on_stream_close(nghttp2_session *session, int32_t stream_id,
+                           uint32_t error_code, void *userp)
+{
+  struct Curl_easy *data_s;
+  struct HTTP *stream;
+  struct connectdata *conn = (struct connectdata *)userp;
+  (void)session;
+  (void)stream_id;
+
+  if(stream_id) {
+    /* get the stream from the hash based on Stream ID, stream ID zero is for
+       connection-oriented stuff */
+    data_s = nghttp2_session_get_stream_user_data(session, stream_id);
+    if(!data_s) {
+      /* We could get stream ID not in the hash.  For example, if we
+         decided to reject stream (e.g., PUSH_PROMISE). */
+      return 0;
+    }
+    DEBUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u\n",
+                 Curl_http2_strerror(error_code), error_code, stream_id));
+    stream = data_s->req.protop;
+    if(!stream)
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+    stream->error_code = error_code;
+    stream->closed = TRUE;
+    data_s->state.drain++;
+    conn->proto.httpc.drain_total++;
+
+    /* remove the entry from the hash as the stream is now gone */
+    nghttp2_session_set_stream_user_data(session, stream_id, 0);
+    DEBUGF(infof(data_s, "Removed stream %u hash!\n", stream_id));
+  }
+  return 0;
+}
+
+static int on_begin_headers(nghttp2_session *session,
+                            const nghttp2_frame *frame, void *userp)
+{
+  struct HTTP *stream;
+  struct Curl_easy *data_s = NULL;
+  (void)userp;
+
+  data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id);
+  if(!data_s) {
+    return 0;
+  }
+
+  DEBUGF(infof(data_s, "on_begin_headers() was called\n"));
+
+  if(frame->hd.type != NGHTTP2_HEADERS) {
+    return 0;
+  }
+
+  stream = data_s->req.protop;
+  if(!stream || !stream->bodystarted) {
+    return 0;
+  }
+
+  /* This is trailer HEADERS started.  Allocate buffer for them. */
+  DEBUGF(infof(data_s, "trailer field started\n"));
+
+  DEBUGASSERT(stream->trailer_recvbuf == NULL);
+
+  stream->trailer_recvbuf = Curl_add_buffer_init();
+  if(!stream->trailer_recvbuf) {
+    return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
+  }
+
+  return 0;
+}
+
+/* Decode HTTP status code.  Returns -1 if no valid status code was
+   decoded. */
+static int decode_status_code(const uint8_t *value, size_t len)
+{
+  int i;
+  int res;
+
+  if(len != 3) {
+    return -1;
+  }
+
+  res = 0;
+
+  for(i = 0; i < 3; ++i) {
+    char c = value[i];
+
+    if(c < '0' || c > '9') {
+      return -1;
+    }
+
+    res *= 10;
+    res += c - '0';
+  }
+
+  return res;
+}
+
+/* frame->hd.type is either NGHTTP2_HEADERS or NGHTTP2_PUSH_PROMISE */
+static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
+                     const uint8_t *name, size_t namelen,
+                     const uint8_t *value, size_t valuelen,
+                     uint8_t flags,
+                     void *userp)
+{
+  struct HTTP *stream;
+  struct Curl_easy *data_s;
+  int32_t stream_id = frame->hd.stream_id;
+  struct connectdata *conn = (struct connectdata *)userp;
+  (void)flags;
+
+  DEBUGASSERT(stream_id); /* should never be a zero stream ID here */
+
+  /* get the stream from the hash based on Stream ID */
+  data_s = nghttp2_session_get_stream_user_data(session, stream_id);
+  if(!data_s)
+    /* Receiving a Stream ID not in the hash should not happen, this is an
+       internal error more than anything else! */
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+  stream = data_s->req.protop;
+  if(!stream) {
+    failf(data_s, "Internal NULL stream! 5\n");
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
+
+  /* Store received PUSH_PROMISE headers to be used when the subsequent
+     PUSH_PROMISE callback comes */
+  if(frame->hd.type == NGHTTP2_PUSH_PROMISE) {
+    char *h;
+
+    if(!stream->push_headers) {
+      stream->push_headers_alloc = 10;
+      stream->push_headers = malloc(stream->push_headers_alloc *
+                                    sizeof(char *));
+      stream->push_headers_used = 0;
+    }
+    else if(stream->push_headers_used ==
+            stream->push_headers_alloc) {
+      char **headp;
+      stream->push_headers_alloc *= 2;
+      headp = Curl_saferealloc(stream->push_headers,
+                               stream->push_headers_alloc * sizeof(char *));
+      if(!headp) {
+        stream->push_headers = NULL;
+        return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
+      }
+      stream->push_headers = headp;
+    }
+    h = aprintf("%s:%s", name, value);
+    if(h)
+      stream->push_headers[stream->push_headers_used++] = h;
+    return 0;
+  }
+
+  if(stream->bodystarted) {
+    /* This is trailer fields. */
+    /* 3 is for ":" and "\r\n". */
+    uint32_t n = (uint32_t)(namelen + valuelen + 3);
+
+    DEBUGF(infof(data_s, "h2 trailer: %.*s: %.*s\n", namelen, name, valuelen,
+                 value));
+
+    Curl_add_buffer(stream->trailer_recvbuf, &n, sizeof(n));
+    Curl_add_buffer(stream->trailer_recvbuf, name, namelen);
+    Curl_add_buffer(stream->trailer_recvbuf, ": ", 2);
+    Curl_add_buffer(stream->trailer_recvbuf, value, valuelen);
+    Curl_add_buffer(stream->trailer_recvbuf, "\r\n\0", 3);
+
+    return 0;
+  }
+
+  if(namelen == sizeof(":status") - 1 &&
+     memcmp(":status", name, namelen) == 0) {
+    /* nghttp2 guarantees :status is received first and only once, and
+       value is 3 digits status code, and decode_status_code always
+       succeeds. */
+    stream->status_code = decode_status_code(value, valuelen);
+    DEBUGASSERT(stream->status_code != -1);
+
+    Curl_add_buffer(stream->header_recvbuf, "HTTP/2 ", 7);
+    Curl_add_buffer(stream->header_recvbuf, value, valuelen);
+    /* the space character after the status code is mandatory */
+    Curl_add_buffer(stream->header_recvbuf, " \r\n", 3);
+    /* if we receive data for another handle, wake that up */
+    if(conn->data != data_s)
+      Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
+
+    DEBUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)\n",
+                 stream->status_code, data_s));
+    return 0;
+  }
+
+  /* nghttp2 guarantees that namelen > 0, and :status was already
+     received, and this is not pseudo-header field . */
+  /* convert to a HTTP1-style header */
+  Curl_add_buffer(stream->header_recvbuf, name, namelen);
+  Curl_add_buffer(stream->header_recvbuf, ": ", 2);
+  Curl_add_buffer(stream->header_recvbuf, value, valuelen);
+  Curl_add_buffer(stream->header_recvbuf, "\r\n", 2);
+  /* if we receive data for another handle, wake that up */
+  if(conn->data != data_s)
+    Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
+
+  DEBUGF(infof(data_s, "h2 header: %.*s: %.*s\n", namelen, name, valuelen,
+               value));
+
+  return 0; /* 0 is successful */
+}
+
+static ssize_t data_source_read_callback(nghttp2_session *session,
+                                         int32_t stream_id,
+                                         uint8_t *buf, size_t length,
+                                         uint32_t *data_flags,
+                                         nghttp2_data_source *source,
+                                         void *userp)
+{
+  struct Curl_easy *data_s;
+  struct HTTP *stream = NULL;
+  size_t nread;
+  (void)source;
+  (void)userp;
+
+  if(stream_id) {
+    /* get the stream from the hash based on Stream ID, stream ID zero is for
+       connection-oriented stuff */
+    data_s = nghttp2_session_get_stream_user_data(session, stream_id);
+    if(!data_s)
+      /* Receiving a Stream ID not in the hash should not happen, this is an
+         internal error more than anything else! */
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+
+    stream = data_s->req.protop;
+    if(!stream)
+      return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
+  else
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+
+  nread = MIN(stream->upload_len, length);
+  if(nread > 0) {
+    memcpy(buf, stream->upload_mem, nread);
+    stream->upload_mem += nread;
+    stream->upload_len -= nread;
+    if(data_s->state.infilesize != -1)
+      stream->upload_left -= nread;
+  }
+
+  if(stream->upload_left == 0)
+    *data_flags = NGHTTP2_DATA_FLAG_EOF;
+  else if(nread == 0)
+    return NGHTTP2_ERR_DEFERRED;
+
+  DEBUGF(infof(data_s, "data_source_read_callback: "
+               "returns %zu bytes stream %u\n",
+               nread, stream_id));
+
+  return nread;
+}
+
+#define H2_BUFSIZE 32768
+
+#ifdef NGHTTP2_HAS_ERROR_CALLBACK
+static int error_callback(nghttp2_session *session,
+                          const char *msg,
+                          size_t len,
+                          void *userp)
+{
+  struct connectdata *conn = (struct connectdata *)userp;
+  (void)session;
+  infof(conn->data, "http2 error: %.*s\n", len, msg);
+  return 0;
+}
+#endif
+
+static void populate_settings(struct connectdata *conn,
+                              struct http_conn *httpc)
+{
+  nghttp2_settings_entry *iv = httpc->local_settings;
+
+  iv[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
+  iv[0].value = 100;
+
+  iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
+  iv[1].value = HTTP2_HUGE_WINDOW_SIZE;
+
+  iv[2].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH;
+  iv[2].value = conn->data->multi->push_cb != NULL;
+
+  httpc->local_settings_num = 3;
+}
+
+void Curl_http2_done(struct connectdata *conn, bool premature)
+{
+  struct Curl_easy *data = conn->data;
+  struct HTTP *http = data->req.protop;
+  struct http_conn *httpc = &conn->proto.httpc;
+
+  if(http->header_recvbuf) {
+    DEBUGF(infof(data, "free header_recvbuf!!\n"));
+    Curl_add_buffer_free(http->header_recvbuf);
+    http->header_recvbuf = NULL; /* clear the pointer */
+    Curl_add_buffer_free(http->trailer_recvbuf);
+    http->trailer_recvbuf = NULL; /* clear the pointer */
+    if(http->push_headers) {
+      /* if they weren't used and then freed before */
+      for(; http->push_headers_used > 0; --http->push_headers_used) {
+        free(http->push_headers[http->push_headers_used - 1]);
+      }
+      free(http->push_headers);
+      http->push_headers = NULL;
+    }
+  }
+
+  if(premature) {
+    /* RST_STREAM */
+    nghttp2_submit_rst_stream(httpc->h2, NGHTTP2_FLAG_NONE, http->stream_id,
+                              NGHTTP2_STREAM_CLOSED);
+    if(http->stream_id == httpc->pause_stream_id) {
+      infof(data, "stopped the pause stream!\n");
+      httpc->pause_stream_id = 0;
+    }
+  }
+  if(http->stream_id) {
+    nghttp2_session_set_stream_user_data(httpc->h2, http->stream_id, 0);
+    http->stream_id = 0;
+  }
+}
+
+/*
+ * Initialize nghttp2 for a Curl connection
+ */
+CURLcode Curl_http2_init(struct connectdata *conn)
+{
+  if(!conn->proto.httpc.h2) {
+    int rc;
+    nghttp2_session_callbacks *callbacks;
+
+    conn->proto.httpc.inbuf = malloc(H2_BUFSIZE);
+    if(conn->proto.httpc.inbuf == NULL)
+      return CURLE_OUT_OF_MEMORY;
+
+    rc = nghttp2_session_callbacks_new(&callbacks);
+
+    if(rc) {
+      failf(conn->data, "Couldn't initialize nghttp2 callbacks!");
+      return CURLE_OUT_OF_MEMORY; /* most likely at least */
+    }
+
+    /* nghttp2_send_callback */
+    nghttp2_session_callbacks_set_send_callback(callbacks, send_callback);
+    /* nghttp2_on_frame_recv_callback */
+    nghttp2_session_callbacks_set_on_frame_recv_callback
+      (callbacks, on_frame_recv);
+    /* nghttp2_on_invalid_frame_recv_callback */
+    nghttp2_session_callbacks_set_on_invalid_frame_recv_callback
+      (callbacks, on_invalid_frame_recv);
+    /* nghttp2_on_data_chunk_recv_callback */
+    nghttp2_session_callbacks_set_on_data_chunk_recv_callback
+      (callbacks, on_data_chunk_recv);
+    /* nghttp2_before_frame_send_callback */
+    nghttp2_session_callbacks_set_before_frame_send_callback
+      (callbacks, before_frame_send);
+    /* nghttp2_on_frame_send_callback */
+    nghttp2_session_callbacks_set_on_frame_send_callback
+      (callbacks, on_frame_send);
+    /* nghttp2_on_frame_not_send_callback */
+    nghttp2_session_callbacks_set_on_frame_not_send_callback
+      (callbacks, on_frame_not_send);
+    /* nghttp2_on_stream_close_callback */
+    nghttp2_session_callbacks_set_on_stream_close_callback
+      (callbacks, on_stream_close);
+    /* nghttp2_on_begin_headers_callback */
+    nghttp2_session_callbacks_set_on_begin_headers_callback
+      (callbacks, on_begin_headers);
+    /* nghttp2_on_header_callback */
+    nghttp2_session_callbacks_set_on_header_callback(callbacks, on_header);
+
+    nghttp2_session_callbacks_set_error_callback(callbacks, error_callback);
+
+    /* The nghttp2 session is not yet setup, do it */
+    rc = nghttp2_session_client_new(&conn->proto.httpc.h2, callbacks, conn);
+
+    nghttp2_session_callbacks_del(callbacks);
+
+    if(rc) {
+      failf(conn->data, "Couldn't initialize nghttp2!");
+      return CURLE_OUT_OF_MEMORY; /* most likely at least */
+    }
+  }
+  return CURLE_OK;
+}
+
+/*
+ * Append headers to ask for a HTTP1.1 to HTTP2 upgrade.
+ */
+CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
+                                    struct connectdata *conn)
+{
+  CURLcode result;
+  ssize_t binlen;
+  char *base64;
+  size_t blen;
+  struct SingleRequest *k = &conn->data->req;
+  uint8_t *binsettings = conn->proto.httpc.binsettings;
+  struct http_conn *httpc = &conn->proto.httpc;
+
+  populate_settings(conn, httpc);
+
+  /* this returns number of bytes it wrote */
+  binlen = nghttp2_pack_settings_payload(binsettings, H2_BINSETTINGS_LEN,
+                                         httpc->local_settings,
+                                         httpc->local_settings_num);
+  if(!binlen) {
+    failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload");
+    Curl_add_buffer_free(req);
+    return CURLE_FAILED_INIT;
+  }
+  conn->proto.httpc.binlen = binlen;
+
+  result = Curl_base64url_encode(conn->data, (const char *)binsettings, binlen,
+                                 &base64, &blen);
+  if(result) {
+    Curl_add_buffer_free(req);
+    return result;
+  }
+
+  result = Curl_add_bufferf(req,
+                            "Connection: Upgrade, HTTP2-Settings\r\n"
+                            "Upgrade: %s\r\n"
+                            "HTTP2-Settings: %s\r\n",
+                            NGHTTP2_CLEARTEXT_PROTO_VERSION_ID, base64);
+  free(base64);
+
+  k->upgr101 = UPGR101_REQUESTED;
+
+  return result;
+}
+
+/*
+ * Returns nonzero if current HTTP/2 session should be closed.
+ */
+static int should_close_session(struct http_conn *httpc)
+{
+  return httpc->drain_total == 0 && !nghttp2_session_want_read(httpc->h2) &&
+    !nghttp2_session_want_write(httpc->h2);
+}
+
+static int h2_session_send(struct Curl_easy *data,
+                           nghttp2_session *h2);
+
+/*
+ * h2_process_pending_input() processes pending input left in
+ * httpc->inbuf.  Then, call h2_session_send() to send pending data.
+ * This function returns 0 if it succeeds, or -1 and error code will
+ * be assigned to *err.
+ */
+static int h2_process_pending_input(struct Curl_easy *data,
+                                    struct http_conn *httpc,
+                                    CURLcode *err)
+{
+  ssize_t nread;
+  char *inbuf;
+  ssize_t rv;
+
+  nread = httpc->inbuflen - httpc->nread_inbuf;
+  inbuf = httpc->inbuf + httpc->nread_inbuf;
+
+  rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread);
+  if(rv < 0) {
+    failf(data,
+          "h2_process_pending_input: nghttp2_session_mem_recv() returned "
+          "%d:%s\n", rv, nghttp2_strerror((int)rv));
+    *err = CURLE_RECV_ERROR;
+    return -1;
+  }
+
+  if(nread == rv) {
+    DEBUGF(infof(data,
+                 "h2_process_pending_input: All data in connection buffer "
+                 "processed\n"));
+    httpc->inbuflen = 0;
+    httpc->nread_inbuf = 0;
+  }
+  else {
+    httpc->nread_inbuf += rv;
+    DEBUGF(infof(data,
+                 "h2_process_pending_input: %zu bytes left in connection "
+                 "buffer\n",
+                 httpc->inbuflen - httpc->nread_inbuf));
+  }
+
+  rv = h2_session_send(data, httpc->h2);
+  if(rv != 0) {
+    *err = CURLE_SEND_ERROR;
+    return -1;
+  }
+
+  if(should_close_session(httpc)) {
+    DEBUGF(infof(data,
+                 "h2_process_pending_input: nothing to do in this session\n"));
+    *err = CURLE_HTTP2;
+    return -1;
+  }
+
+  return 0;
+}
+
+/*
+ * Called from transfer.c:done_sending when we stop uploading.
+ */
+CURLcode Curl_http2_done_sending(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  if((conn->handler == &Curl_handler_http2_ssl) ||
+     (conn->handler == &Curl_handler_http2)) {
+    /* make sure this is only attempted for HTTP/2 transfers */
+
+    struct HTTP *stream = conn->data->req.protop;
+
+    if(stream->upload_left) {
+      /* If the stream still thinks there's data left to upload. */
+      struct http_conn *httpc = &conn->proto.httpc;
+      nghttp2_session *h2 = httpc->h2;
+
+      stream->upload_left = 0; /* DONE! */
+
+      /* resume sending here to trigger the callback to get called again so
+         that it can signal EOF to nghttp2 */
+      (void)nghttp2_session_resume_data(h2, stream->stream_id);
+
+      (void)h2_process_pending_input(conn->data, httpc, &result);
+    }
+  }
+  return result;
+}
+
+
+static ssize_t http2_handle_stream_close(struct connectdata *conn,
+                                         struct Curl_easy *data,
+                                         struct HTTP *stream, CURLcode *err)
+{
+  char *trailer_pos, *trailer_end;
+  CURLcode result;
+  struct http_conn *httpc = &conn->proto.httpc;
+
+  if(httpc->pause_stream_id == stream->stream_id) {
+    httpc->pause_stream_id = 0;
+  }
+
+  DEBUGASSERT(httpc->drain_total >= data->state.drain);
+  httpc->drain_total -= data->state.drain;
+  data->state.drain = 0;
+
+  if(httpc->pause_stream_id == 0) {
+    if(h2_process_pending_input(data, httpc, err) != 0) {
+      return -1;
+    }
+  }
+
+  DEBUGASSERT(data->state.drain == 0);
+
+  /* Reset to FALSE to prevent infinite loop in readwrite_data function. */
+  stream->closed = FALSE;
+  if(stream->error_code != NGHTTP2_NO_ERROR) {
+    failf(data, "HTTP/2 stream %u was not closed cleanly: %s (err %d)",
+          stream->stream_id, Curl_http2_strerror(stream->error_code),
+          stream->error_code);
+    *err = CURLE_HTTP2_STREAM;
+    return -1;
+  }
+
+  if(!stream->bodystarted) {
+    failf(data, "HTTP/2 stream %u was closed cleanly, but before getting "
+          " all response header fields, teated as error",
+          stream->stream_id);
+    *err = CURLE_HTTP2_STREAM;
+    return -1;
+  }
+
+  if(stream->trailer_recvbuf && stream->trailer_recvbuf->buffer) {
+    trailer_pos = stream->trailer_recvbuf->buffer;
+    trailer_end = trailer_pos + stream->trailer_recvbuf->size_used;
+
+    for(; trailer_pos < trailer_end;) {
+      uint32_t n;
+      memcpy(&n, trailer_pos, sizeof(n));
+      trailer_pos += sizeof(n);
+
+      result = Curl_client_write(conn, CLIENTWRITE_HEADER, trailer_pos, n);
+      if(result) {
+        *err = result;
+        return -1;
+      }
+
+      trailer_pos += n + 1;
+    }
+  }
+
+  stream->close_handled = TRUE;
+
+  DEBUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n"));
+  return 0;
+}
+
+/*
+ * h2_pri_spec() fills in the pri_spec struct, used by nghttp2 to send weight
+ * and dependency to the peer. It also stores the updated values in the state
+ * struct.
+ */
+
+static void h2_pri_spec(struct Curl_easy *data,
+                        nghttp2_priority_spec *pri_spec)
+{
+  struct HTTP *depstream = (data->set.stream_depends_on?
+                            data->set.stream_depends_on->req.protop:NULL);
+  int32_t depstream_id = depstream? depstream->stream_id:0;
+  nghttp2_priority_spec_init(pri_spec, depstream_id, data->set.stream_weight,
+                             data->set.stream_depends_e);
+  data->state.stream_weight = data->set.stream_weight;
+  data->state.stream_depends_e = data->set.stream_depends_e;
+  data->state.stream_depends_on = data->set.stream_depends_on;
+}
+
+/*
+ * h2_session_send() checks if there's been an update in the priority /
+ * dependency settings and if so it submits a PRIORITY frame with the updated
+ * info.
+ */
+static int h2_session_send(struct Curl_easy *data,
+                           nghttp2_session *h2)
+{
+  struct HTTP *stream = data->req.protop;
+  if((data->set.stream_weight != data->state.stream_weight) ||
+     (data->set.stream_depends_e != data->state.stream_depends_e) ||
+     (data->set.stream_depends_on != data->state.stream_depends_on) ) {
+    /* send new weight and/or dependency */
+    nghttp2_priority_spec pri_spec;
+    int rv;
+
+    h2_pri_spec(data, &pri_spec);
+
+    DEBUGF(infof(data, "Queuing PRIORITY on stream %u (easy %p)\n",
+                 stream->stream_id, data));
+    rv = nghttp2_submit_priority(h2, NGHTTP2_FLAG_NONE, stream->stream_id,
+                                 &pri_spec);
+    if(rv)
+      return rv;
+  }
+
+  return nghttp2_session_send(h2);
+}
+
+static ssize_t http2_recv(struct connectdata *conn, int sockindex,
+                          char *mem, size_t len, CURLcode *err)
+{
+  CURLcode result = CURLE_OK;
+  ssize_t rv;
+  ssize_t nread;
+  struct http_conn *httpc = &conn->proto.httpc;
+  struct Curl_easy *data = conn->data;
+  struct HTTP *stream = data->req.protop;
+
+  (void)sockindex; /* we always do HTTP2 on sockindex 0 */
+
+  if(should_close_session(httpc)) {
+    DEBUGF(infof(data,
+                 "http2_recv: nothing to do in this session\n"));
+    *err = CURLE_HTTP2;
+    return -1;
+  }
+
+  /* Nullify here because we call nghttp2_session_send() and they
+     might refer to the old buffer. */
+  stream->upload_mem = NULL;
+  stream->upload_len = 0;
+
+  /*
+   * At this point 'stream' is just in the Curl_easy the connection
+   * identifies as its owner at this time.
+   */
+
+  if(stream->bodystarted &&
+     stream->nread_header_recvbuf < stream->header_recvbuf->size_used) {
+    /* If there is body data pending for this stream to return, do that */
+    size_t left =
+      stream->header_recvbuf->size_used - stream->nread_header_recvbuf;
+    size_t ncopy = MIN(len, left);
+    memcpy(mem, stream->header_recvbuf->buffer + stream->nread_header_recvbuf,
+           ncopy);
+    stream->nread_header_recvbuf += ncopy;
+
+    DEBUGF(infof(data, "http2_recv: Got %d bytes from header_recvbuf\n",
+                 (int)ncopy));
+    return ncopy;
+  }
+
+  DEBUGF(infof(data, "http2_recv: easy %p (stream %u)\n",
+               data, stream->stream_id));
+
+  if((data->state.drain) && stream->memlen) {
+    DEBUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u!! (%p => %p)\n",
+                 stream->memlen, stream->stream_id,
+                 stream->mem, mem));
+    if(mem != stream->mem) {
+      /* if we didn't get the same buffer this time, we must move the data to
+         the beginning */
+      memmove(mem, stream->mem, stream->memlen);
+      stream->len = len - stream->memlen;
+      stream->mem = mem;
+    }
+    if(httpc->pause_stream_id == stream->stream_id && !stream->pausedata) {
+      /* We have paused nghttp2, but we have no pause data (see
+         on_data_chunk_recv). */
+      httpc->pause_stream_id = 0;
+      if(h2_process_pending_input(data, httpc, &result) != 0) {
+        *err = result;
+        return -1;
+      }
+    }
+  }
+  else if(stream->pausedata) {
+    DEBUGASSERT(httpc->pause_stream_id == stream->stream_id);
+    nread = MIN(len, stream->pauselen);
+    memcpy(mem, stream->pausedata, nread);
+
+    stream->pausedata += nread;
+    stream->pauselen -= nread;
+
+    infof(data, "%zu data bytes written\n", nread);
+    if(stream->pauselen == 0) {
+      DEBUGF(infof(data, "Unpaused by stream %u\n", stream->stream_id));
+      DEBUGASSERT(httpc->pause_stream_id == stream->stream_id);
+      httpc->pause_stream_id = 0;
+
+      stream->pausedata = NULL;
+      stream->pauselen = 0;
+
+      /* When NGHTTP2_ERR_PAUSE is returned from
+         data_source_read_callback, we might not process DATA frame
+         fully.  Calling nghttp2_session_mem_recv() again will
+         continue to process DATA frame, but if there is no incoming
+         frames, then we have to call it again with 0-length data.
+         Without this, on_stream_close callback will not be called,
+         and stream could be hanged. */
+      if(h2_process_pending_input(data, httpc, &result) != 0) {
+        *err = result;
+        return -1;
+      }
+    }
+    DEBUGF(infof(data, "http2_recv: returns unpaused %zd bytes on stream %u\n",
+                 nread, stream->stream_id));
+    return nread;
+  }
+  else if(httpc->pause_stream_id) {
+    /* If a stream paused nghttp2_session_mem_recv previously, and has
+       not processed all data, it still refers to the buffer in
+       nghttp2_session.  If we call nghttp2_session_mem_recv(), we may
+       overwrite that buffer.  To avoid that situation, just return
+       here with CURLE_AGAIN.  This could be busy loop since data in
+       socket is not read.  But it seems that usually streams are
+       notified with its drain property, and socket is read again
+       quickly. */
+    DEBUGF(infof(data, "stream %x is paused, pause id: %x\n",
+                 stream->stream_id, httpc->pause_stream_id));
+    *err = CURLE_AGAIN;
+    return -1;
+  }
+  else {
+    char *inbuf;
+    /* remember where to store incoming data for this stream and how big the
+       buffer is */
+    stream->mem = mem;
+    stream->len = len;
+    stream->memlen = 0;
+
+    if(httpc->inbuflen == 0) {
+      nread = ((Curl_recv *)httpc->recv_underlying)(
+          conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result);
+
+      if(nread == -1) {
+        if(result != CURLE_AGAIN)
+          failf(data, "Failed receiving HTTP2 data");
+        else if(stream->closed)
+          /* received when the stream was already closed! */
+          return http2_handle_stream_close(conn, data, stream, err);
+
+        *err = result;
+        return -1;
+      }
+
+      if(nread == 0) {
+        failf(data, "Unexpected EOF");
+        *err = CURLE_RECV_ERROR;
+        return -1;
+      }
+
+      DEBUGF(infof(data, "nread=%zd\n", nread));
+
+      httpc->inbuflen = nread;
+      inbuf = httpc->inbuf;
+    }
+    else {
+      nread = httpc->inbuflen - httpc->nread_inbuf;
+      inbuf = httpc->inbuf + httpc->nread_inbuf;
+
+      DEBUGF(infof(data, "Use data left in connection buffer, nread=%zd\n",
+                   nread));
+    }
+    rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread);
+
+    if(nghttp2_is_fatal((int)rv)) {
+      failf(data, "nghttp2_session_mem_recv() returned %d:%s\n",
+            rv, nghttp2_strerror((int)rv));
+      *err = CURLE_RECV_ERROR;
+      return -1;
+    }
+    DEBUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", rv));
+    if(nread == rv) {
+      DEBUGF(infof(data, "All data in connection buffer processed\n"));
+      httpc->inbuflen = 0;
+      httpc->nread_inbuf = 0;
+    }
+    else {
+      httpc->nread_inbuf += rv;
+      DEBUGF(infof(data, "%zu bytes left in connection buffer\n",
+                   httpc->inbuflen - httpc->nread_inbuf));
+    }
+    /* Always send pending frames in nghttp2 session, because
+       nghttp2_session_mem_recv() may queue new frame */
+    rv = h2_session_send(data, httpc->h2);
+    if(rv != 0) {
+      *err = CURLE_SEND_ERROR;
+      return -1;
+    }
+
+    if(should_close_session(httpc)) {
+      DEBUGF(infof(data, "http2_recv: nothing to do in this session\n"));
+      *err = CURLE_HTTP2;
+      return -1;
+    }
+  }
+  if(stream->memlen) {
+    ssize_t retlen = stream->memlen;
+    DEBUGF(infof(data, "http2_recv: returns %zd for stream %u\n",
+                 retlen, stream->stream_id));
+    stream->memlen = 0;
+
+    if(httpc->pause_stream_id == stream->stream_id) {
+      /* data for this stream is returned now, but this stream caused a pause
+         already so we need it called again asap */
+      DEBUGF(infof(data, "Data returned for PAUSED stream %u\n",
+                   stream->stream_id));
+    }
+    else if(!stream->closed) {
+      DEBUGASSERT(httpc->drain_total >= data->state.drain);
+      httpc->drain_total -= data->state.drain;
+      data->state.drain = 0; /* this stream is hereby drained */
+    }
+
+    return retlen;
+  }
+  /* If stream is closed, return 0 to signal the http routine to close
+     the connection */
+  if(stream->closed) {
+    return http2_handle_stream_close(conn, data, stream, err);
+  }
+  *err = CURLE_AGAIN;
+  DEBUGF(infof(data, "http2_recv returns AGAIN for stream %u\n",
+               stream->stream_id));
+  return -1;
+}
+
+/* Index where :authority header field will appear in request header
+   field list. */
+#define AUTHORITY_DST_IDX 3
+
+#define HEADER_OVERFLOW(x) \
+  (x.namelen > (uint16_t)-1 || x.valuelen > (uint16_t)-1 - x.namelen)
+
+/*
+ * Check header memory for the token "trailers".
+ * Parse the tokens as separated by comma and surrounded by whitespace.
+ * Returns TRUE if found or FALSE if not.
+ */
+static bool contains_trailers(const char *p, size_t len)
+{
+  const char *end = p + len;
+  for(;;) {
+    for(; p != end && (*p == ' ' || *p == '\t'); ++p)
+      ;
+    if(p == end || (size_t)(end - p) < sizeof("trailers") - 1)
+      return FALSE;
+    if(strncasecompare("trailers", p, sizeof("trailers") - 1)) {
+      p += sizeof("trailers") - 1;
+      for(; p != end && (*p == ' ' || *p == '\t'); ++p)
+        ;
+      if(p == end || *p == ',')
+        return TRUE;
+    }
+    /* skip to next token */
+    for(; p != end && *p != ','; ++p)
+      ;
+    if(p == end)
+      return FALSE;
+    ++p;
+  }
+}
+
+typedef enum {
+  /* Send header to server */
+  HEADERINST_FORWARD,
+  /* Don't send header to server */
+  HEADERINST_IGNORE,
+  /* Discard header, and replace it with "te: trailers" */
+  HEADERINST_TE_TRAILERS
+} header_instruction;
+
+/* Decides how to treat given header field. */
+static header_instruction inspect_header(const char *name, size_t namelen,
+                                         const char *value, size_t valuelen) {
+  switch(namelen) {
+  case 2:
+    if(!strncasecompare("te", name, namelen))
+      return HEADERINST_FORWARD;
+
+    return contains_trailers(value, valuelen) ?
+           HEADERINST_TE_TRAILERS : HEADERINST_IGNORE;
+  case 7:
+    return strncasecompare("upgrade", name, namelen) ?
+           HEADERINST_IGNORE : HEADERINST_FORWARD;
+  case 10:
+    return (strncasecompare("connection", name, namelen) ||
+            strncasecompare("keep-alive", name, namelen)) ?
+           HEADERINST_IGNORE : HEADERINST_FORWARD;
+  case 16:
+    return strncasecompare("proxy-connection", name, namelen) ?
+           HEADERINST_IGNORE : HEADERINST_FORWARD;
+  case 17:
+    return strncasecompare("transfer-encoding", name, namelen) ?
+           HEADERINST_IGNORE : HEADERINST_FORWARD;
+  default:
+    return HEADERINST_FORWARD;
+  }
+}
+
+static ssize_t http2_send(struct connectdata *conn, int sockindex,
+                          const void *mem, size_t len, CURLcode *err)
+{
+  /*
+   * BIG TODO: Currently, we send request in this function, but this
+   * function is also used to send request body. It would be nice to
+   * add dedicated function for request.
+   */
+  int rv;
+  struct http_conn *httpc = &conn->proto.httpc;
+  struct HTTP *stream = conn->data->req.protop;
+  nghttp2_nv *nva = NULL;
+  size_t nheader;
+  size_t i;
+  size_t authority_idx;
+  char *hdbuf = (char *)mem;
+  char *end, *line_end;
+  nghttp2_data_provider data_prd;
+  int32_t stream_id;
+  nghttp2_session *h2 = httpc->h2;
+  nghttp2_priority_spec pri_spec;
+
+  (void)sockindex;
+
+  DEBUGF(infof(conn->data, "http2_send len=%zu\n", len));
+
+  if(stream->stream_id != -1) {
+    if(stream->close_handled) {
+      infof(conn->data, "stream %d closed\n", stream->stream_id);
+      *err = CURLE_HTTP2_STREAM;
+      return -1;
+    }
+    else if(stream->closed) {
+      return http2_handle_stream_close(conn, conn->data, stream, err);
+    }
+    /* If stream_id != -1, we have dispatched request HEADERS, and now
+       are going to send or sending request body in DATA frame */
+    stream->upload_mem = mem;
+    stream->upload_len = len;
+    nghttp2_session_resume_data(h2, stream->stream_id);
+    rv = h2_session_send(conn->data, h2);
+    if(nghttp2_is_fatal(rv)) {
+      *err = CURLE_SEND_ERROR;
+      return -1;
+    }
+    len -= stream->upload_len;
+
+    /* Nullify here because we call nghttp2_session_send() and they
+       might refer to the old buffer. */
+    stream->upload_mem = NULL;
+    stream->upload_len = 0;
+
+    if(should_close_session(httpc)) {
+      DEBUGF(infof(conn->data, "http2_send: nothing to do in this session\n"));
+      *err = CURLE_HTTP2;
+      return -1;
+    }
+
+    if(stream->upload_left) {
+      /* we are sure that we have more data to send here.  Calling the
+         following API will make nghttp2_session_want_write() return
+         nonzero if remote window allows it, which then libcurl checks
+         socket is writable or not.  See http2_perform_getsock(). */
+      nghttp2_session_resume_data(h2, stream->stream_id);
+    }
+
+    DEBUGF(infof(conn->data, "http2_send returns %zu for stream %u\n", len,
+                 stream->stream_id));
+    return len;
+  }
+
+  /* Calculate number of headers contained in [mem, mem + len) */
+  /* Here, we assume the curl http code generate *correct* HTTP header
+     field block */
+  nheader = 0;
+  for(i = 1; i < len; ++i) {
+    if(hdbuf[i] == '\n' && hdbuf[i - 1] == '\r') {
+      ++nheader;
+      ++i;
+    }
+  }
+  if(nheader < 2)
+    goto fail;
+
+  /* We counted additional 2 \r\n in the first and last line. We need 3
+     new headers: :method, :path and :scheme. Therefore we need one
+     more space. */
+  nheader += 1;
+  nva = malloc(sizeof(nghttp2_nv) * nheader);
+  if(nva == NULL) {
+    *err = CURLE_OUT_OF_MEMORY;
+    return -1;
+  }
+
+  /* Extract :method, :path from request line */
+  line_end = strstr(hdbuf, "\r\n");
+
+  /* Method does not contain spaces */
+  end = memchr(hdbuf, ' ', line_end - hdbuf);
+  if(!end || end == hdbuf)
+    goto fail;
+  nva[0].name = (unsigned char *)":method";
+  nva[0].namelen = strlen((char *)nva[0].name);
+  nva[0].value = (unsigned char *)hdbuf;
+  nva[0].valuelen = (size_t)(end - hdbuf);
+  nva[0].flags = NGHTTP2_NV_FLAG_NONE;
+  if(HEADER_OVERFLOW(nva[0])) {
+    failf(conn->data, "Failed sending HTTP request: Header overflow");
+    goto fail;
+  }
+
+  hdbuf = end + 1;
+
+  /* Path may contain spaces so scan backwards */
+  end = NULL;
+  for(i = (size_t)(line_end - hdbuf); i; --i) {
+    if(hdbuf[i - 1] == ' ') {
+      end = &hdbuf[i - 1];
+      break;
+    }
+  }
+  if(!end || end == hdbuf)
+    goto fail;
+  nva[1].name = (unsigned char *)":path";
+  nva[1].namelen = strlen((char *)nva[1].name);
+  nva[1].value = (unsigned char *)hdbuf;
+  nva[1].valuelen = (size_t)(end - hdbuf);
+  nva[1].flags = NGHTTP2_NV_FLAG_NONE;
+  if(HEADER_OVERFLOW(nva[1])) {
+    failf(conn->data, "Failed sending HTTP request: Header overflow");
+    goto fail;
+  }
+
+  nva[2].name = (unsigned char *)":scheme";
+  nva[2].namelen = strlen((char *)nva[2].name);
+  if(conn->handler->flags & PROTOPT_SSL)
+    nva[2].value = (unsigned char *)"https";
+  else
+    nva[2].value = (unsigned char *)"http";
+  nva[2].valuelen = strlen((char *)nva[2].value);
+  nva[2].flags = NGHTTP2_NV_FLAG_NONE;
+  if(HEADER_OVERFLOW(nva[2])) {
+    failf(conn->data, "Failed sending HTTP request: Header overflow");
+    goto fail;
+  }
+
+  authority_idx = 0;
+  i = 3;
+  while(i < nheader) {
+    size_t hlen;
+
+    hdbuf = line_end + 2;
+
+    line_end = strstr(hdbuf, "\r\n");
+    if(line_end == hdbuf)
+      goto fail;
+
+    /* header continuation lines are not supported */
+    if(*hdbuf == ' ' || *hdbuf == '\t')
+      goto fail;
+
+    for(end = hdbuf; end < line_end && *end != ':'; ++end)
+      ;
+    if(end == hdbuf || end == line_end)
+      goto fail;
+    hlen = end - hdbuf;
+
+    if(hlen == 4 && strncasecompare("host", hdbuf, 4)) {
+      authority_idx = i;
+      nva[i].name = (unsigned char *)":authority";
+      nva[i].namelen = strlen((char *)nva[i].name);
+    }
+    else {
+      nva[i].name = (unsigned char *)hdbuf;
+      nva[i].namelen = (size_t)(end - hdbuf);
+    }
+    hdbuf = end + 1;
+    while(*hdbuf == ' ' || *hdbuf == '\t')
+      ++hdbuf;
+    end = line_end;
+
+    switch(inspect_header((const char *)nva[i].name, nva[i].namelen, hdbuf,
+                          end - hdbuf)) {
+    case HEADERINST_IGNORE:
+      /* skip header fields prohibited by HTTP/2 specification. */
+      --nheader;
+      continue;
+    case HEADERINST_TE_TRAILERS:
+      nva[i].value = (uint8_t*)"trailers";
+      nva[i].valuelen = sizeof("trailers") - 1;
+      break;
+    default:
+      nva[i].value = (unsigned char *)hdbuf;
+      nva[i].valuelen = (size_t)(end - hdbuf);
+    }
+
+    nva[i].flags = NGHTTP2_NV_FLAG_NONE;
+    if(HEADER_OVERFLOW(nva[i])) {
+      failf(conn->data, "Failed sending HTTP request: Header overflow");
+      goto fail;
+    }
+    ++i;
+  }
+
+  /* :authority must come before non-pseudo header fields */
+  if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) {
+    nghttp2_nv authority = nva[authority_idx];
+    for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) {
+      nva[i] = nva[i - 1];
+    }
+    nva[i] = authority;
+  }
+
+  /* Warn stream may be rejected if cumulative length of headers is too large.
+     It appears nghttp2 will not send a header frame larger than 64KB. */
+#define MAX_ACC 60000  /* <64KB to account for some overhead */
+  {
+    size_t acc = 0;
+
+    for(i = 0; i < nheader; ++i) {
+      acc += nva[i].namelen + nva[i].valuelen;
+
+      DEBUGF(infof(conn->data, "h2 header: %.*s:%.*s\n",
+                   nva[i].namelen, nva[i].name,
+                   nva[i].valuelen, nva[i].value));
+    }
+
+    if(acc > MAX_ACC) {
+      infof(conn->data, "http2_send: Warning: The cumulative length of all "
+            "headers exceeds %zu bytes and that could cause the "
+            "stream to be rejected.\n", MAX_ACC);
+    }
+  }
+
+  h2_pri_spec(conn->data, &pri_spec);
+
+  switch(conn->data->set.httpreq) {
+  case HTTPREQ_POST:
+  case HTTPREQ_POST_FORM:
+  case HTTPREQ_POST_MIME:
+  case HTTPREQ_PUT:
+    if(conn->data->state.infilesize != -1)
+      stream->upload_left = conn->data->state.infilesize;
+    else
+      /* data sending without specifying the data amount up front */
+      stream->upload_left = -1; /* unknown, but not zero */
+
+    data_prd.read_callback = data_source_read_callback;
+    data_prd.source.ptr = NULL;
+    stream_id = nghttp2_submit_request(h2, &pri_spec, nva, nheader,
+                                       &data_prd, conn->data);
+    break;
+  default:
+    stream_id = nghttp2_submit_request(h2, &pri_spec, nva, nheader,
+                                       NULL, conn->data);
+  }
+
+  Curl_safefree(nva);
+
+  if(stream_id < 0) {
+    DEBUGF(infof(conn->data, "http2_send() send error\n"));
+    *err = CURLE_SEND_ERROR;
+    return -1;
+  }
+
+  infof(conn->data, "Using Stream ID: %x (easy handle %p)\n",
+        stream_id, conn->data);
+  stream->stream_id = stream_id;
+
+  /* this does not call h2_session_send() since there can not have been any
+   * priority upodate since the nghttp2_submit_request() call above */
+  rv = nghttp2_session_send(h2);
+
+  if(rv != 0) {
+    *err = CURLE_SEND_ERROR;
+    return -1;
+  }
+
+  if(should_close_session(httpc)) {
+    DEBUGF(infof(conn->data, "http2_send: nothing to do in this session\n"));
+    *err = CURLE_HTTP2;
+    return -1;
+  }
+
+  if(stream->stream_id != -1) {
+    /* If whole HEADERS frame was sent off to the underlying socket,
+       the nghttp2 library calls data_source_read_callback. But only
+       it found that no data available, so it deferred the DATA
+       transmission. Which means that nghttp2_session_want_write()
+       returns 0 on http2_perform_getsock(), which results that no
+       writable socket check is performed. To workaround this, we
+       issue nghttp2_session_resume_data() here to bring back DATA
+       transmission from deferred state. */
+    nghttp2_session_resume_data(h2, stream->stream_id);
+  }
+
+  return len;
+
+fail:
+  free(nva);
+  *err = CURLE_SEND_ERROR;
+  return -1;
+}
+
+CURLcode Curl_http2_setup(struct connectdata *conn)
+{
+  CURLcode result;
+  struct http_conn *httpc = &conn->proto.httpc;
+  struct HTTP *stream = conn->data->req.protop;
+
+  stream->stream_id = -1;
+
+  if(!stream->header_recvbuf)
+    stream->header_recvbuf = Curl_add_buffer_init();
+
+  if((conn->handler == &Curl_handler_http2_ssl) ||
+     (conn->handler == &Curl_handler_http2))
+    return CURLE_OK; /* already done */
+
+  if(conn->handler->flags & PROTOPT_SSL)
+    conn->handler = &Curl_handler_http2_ssl;
+  else
+    conn->handler = &Curl_handler_http2;
+
+  result = Curl_http2_init(conn);
+  if(result)
+    return result;
+
+  infof(conn->data, "Using HTTP2, server supports multi-use\n");
+  stream->upload_left = 0;
+  stream->upload_mem = NULL;
+  stream->upload_len = 0;
+
+  httpc->inbuflen = 0;
+  httpc->nread_inbuf = 0;
+
+  httpc->pause_stream_id = 0;
+  httpc->drain_total = 0;
+
+  conn->bits.multiplex = TRUE; /* at least potentially multiplexed */
+  conn->httpversion = 20;
+  conn->bundle->multiuse = BUNDLE_MULTIPLEX;
+
+  infof(conn->data, "Connection state changed (HTTP/2 confirmed)\n");
+  Curl_multi_connchanged(conn->data->multi);
+
+  return CURLE_OK;
+}
+
+CURLcode Curl_http2_switched(struct connectdata *conn,
+                             const char *mem, size_t nread)
+{
+  CURLcode result;
+  struct http_conn *httpc = &conn->proto.httpc;
+  int rv;
+  ssize_t nproc;
+  struct Curl_easy *data = conn->data;
+  struct HTTP *stream = conn->data->req.protop;
+
+  result = Curl_http2_setup(conn);
+  if(result)
+    return result;
+
+  httpc->recv_underlying = (recving)conn->recv[FIRSTSOCKET];
+  httpc->send_underlying = (sending)conn->send[FIRSTSOCKET];
+  conn->recv[FIRSTSOCKET] = http2_recv;
+  conn->send[FIRSTSOCKET] = http2_send;
+
+  if(conn->data->req.upgr101 == UPGR101_RECEIVED) {
+    /* stream 1 is opened implicitly on upgrade */
+    stream->stream_id = 1;
+    /* queue SETTINGS frame (again) */
+    rv = nghttp2_session_upgrade(httpc->h2, httpc->binsettings,
+                                 httpc->binlen, NULL);
+    if(rv != 0) {
+      failf(data, "nghttp2_session_upgrade() failed: %s(%d)",
+            nghttp2_strerror(rv), rv);
+      return CURLE_HTTP2;
+    }
+
+    nghttp2_session_set_stream_user_data(httpc->h2,
+                                         stream->stream_id,
+                                         conn->data);
+  }
+  else {
+    populate_settings(conn, httpc);
+
+    /* stream ID is unknown at this point */
+    stream->stream_id = -1;
+    rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE,
+                                 httpc->local_settings,
+                                 httpc->local_settings_num);
+    if(rv != 0) {
+      failf(data, "nghttp2_submit_settings() failed: %s(%d)",
+            nghttp2_strerror(rv), rv);
+      return CURLE_HTTP2;
+    }
+  }
+
+#ifdef NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE
+  rv = nghttp2_session_set_local_window_size(httpc->h2, NGHTTP2_FLAG_NONE, 0,
+                                             HTTP2_HUGE_WINDOW_SIZE);
+  if(rv != 0) {
+    failf(data, "nghttp2_session_set_local_window_size() failed: %s(%d)",
+          nghttp2_strerror(rv), rv);
+    return CURLE_HTTP2;
+  }
+#endif
+
+  /* we are going to copy mem to httpc->inbuf.  This is required since
+     mem is part of buffer pointed by stream->mem, and callbacks
+     called by nghttp2_session_mem_recv() will write stream specific
+     data into stream->mem, overwriting data already there. */
+  if(H2_BUFSIZE < nread) {
+    failf(data, "connection buffer size is too small to store data following "
+                "HTTP Upgrade response header: buflen=%zu, datalen=%zu",
+          H2_BUFSIZE, nread);
+    return CURLE_HTTP2;
+  }
+
+  infof(conn->data, "Copying HTTP/2 data in stream buffer to connection buffer"
+                    " after upgrade: len=%zu\n",
+        nread);
+
+  if(nread)
+    memcpy(httpc->inbuf, mem, nread);
+  httpc->inbuflen = nread;
+
+  nproc = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)httpc->inbuf,
+                                   httpc->inbuflen);
+
+  if(nghttp2_is_fatal((int)nproc)) {
+    failf(data, "nghttp2_session_mem_recv() failed: %s(%d)",
+          nghttp2_strerror((int)nproc), (int)nproc);
+    return CURLE_HTTP2;
+  }
+
+  DEBUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", nproc));
+
+  if((ssize_t)nread == nproc) {
+    httpc->inbuflen = 0;
+    httpc->nread_inbuf = 0;
+  }
+  else {
+    httpc->nread_inbuf += nproc;
+  }
+
+  /* Try to send some frames since we may read SETTINGS already. */
+  rv = h2_session_send(data, httpc->h2);
+
+  if(rv != 0) {
+    failf(data, "nghttp2_session_send() failed: %s(%d)",
+          nghttp2_strerror(rv), rv);
+    return CURLE_HTTP2;
+  }
+
+  if(should_close_session(httpc)) {
+    DEBUGF(infof(data,
+                 "nghttp2_session_send(): nothing to do in this session\n"));
+    return CURLE_HTTP2;
+  }
+
+  return CURLE_OK;
+}
+
+CURLcode Curl_http2_add_child(struct Curl_easy *parent,
+                              struct Curl_easy *child,
+                              bool exclusive)
+{
+  if(parent) {
+    struct Curl_http2_dep **tail;
+    struct Curl_http2_dep *dep = calloc(1, sizeof(struct Curl_http2_dep));
+    if(!dep)
+      return CURLE_OUT_OF_MEMORY;
+    dep->data = child;
+
+    if(parent->set.stream_dependents && exclusive) {
+      struct Curl_http2_dep *node = parent->set.stream_dependents;
+      while(node) {
+        node->data->set.stream_depends_on = child;
+        node = node->next;
+      }
+
+      tail = &child->set.stream_dependents;
+      while(*tail)
+        tail = &(*tail)->next;
+
+      DEBUGASSERT(!*tail);
+      *tail = parent->set.stream_dependents;
+      parent->set.stream_dependents = 0;
+    }
+
+    tail = &parent->set.stream_dependents;
+    while(*tail) {
+      (*tail)->data->set.stream_depends_e = FALSE;
+      tail = &(*tail)->next;
+    }
+
+    DEBUGASSERT(!*tail);
+    *tail = dep;
+  }
+
+  child->set.stream_depends_on = parent;
+  child->set.stream_depends_e = exclusive;
+  return CURLE_OK;
+}
+
+void Curl_http2_remove_child(struct Curl_easy *parent, struct Curl_easy *child)
+{
+  struct Curl_http2_dep *last = 0;
+  struct Curl_http2_dep *data = parent->set.stream_dependents;
+  DEBUGASSERT(child->set.stream_depends_on == parent);
+
+  while(data && data->data != child) {
+    last = data;
+    data = data->next;
+  }
+
+  DEBUGASSERT(data);
+
+  if(data) {
+    if(last) {
+      last->next = data->next;
+    }
+    else {
+      parent->set.stream_dependents = data->next;
+    }
+    free(data);
+  }
+
+  child->set.stream_depends_on = 0;
+  child->set.stream_depends_e = FALSE;
+}
+
+void Curl_http2_cleanup_dependencies(struct Curl_easy *data)
+{
+  while(data->set.stream_dependents) {
+    struct Curl_easy *tmp = data->set.stream_dependents->data;
+    Curl_http2_remove_child(data, tmp);
+    if(data->set.stream_depends_on)
+      Curl_http2_add_child(data->set.stream_depends_on, tmp, FALSE);
+  }
+
+  if(data->set.stream_depends_on)
+    Curl_http2_remove_child(data->set.stream_depends_on, data);
+}
+
+#else /* !USE_NGHTTP2 */
+
+/* Satisfy external references even if http2 is not compiled in. */
+
+#define CURL_DISABLE_TYPECHECK
+#include <curl/curl.h>
+
+char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num)
+{
+  (void) h;
+  (void) num;
+  return NULL;
+}
+
+char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header)
+{
+  (void) h;
+  (void) header;
+  return NULL;
+}
+
+#endif /* USE_NGHTTP2 */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/http2.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/http2.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/http2.h	(revision 331)
@@ -0,0 +1,80 @@
+#ifndef HEADER_CURL_HTTP2_H
+#define HEADER_CURL_HTTP2_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_NGHTTP2
+#include "http.h"
+
+/* value for MAX_CONCURRENT_STREAMS we use until we get an updated setting
+   from the peer */
+#define DEFAULT_MAX_CONCURRENT_STREAMS 13
+
+/*
+ * Store nghttp2 version info in this buffer, Prefix with a space.  Return
+ * total length written.
+ */
+int Curl_http2_ver(char *p, size_t len);
+
+const char *Curl_http2_strerror(uint32_t err);
+
+CURLcode Curl_http2_init(struct connectdata *conn);
+void Curl_http2_init_state(struct UrlState *state);
+void Curl_http2_init_userset(struct UserDefined *set);
+CURLcode Curl_http2_send_request(struct connectdata *conn);
+CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req,
+                                    struct connectdata *conn);
+CURLcode Curl_http2_setup(struct connectdata *conn);
+CURLcode Curl_http2_switched(struct connectdata *conn,
+                             const char *data, size_t nread);
+/* called from Curl_http_setup_conn */
+void Curl_http2_setup_conn(struct connectdata *conn);
+void Curl_http2_setup_req(struct Curl_easy *data);
+void Curl_http2_done(struct connectdata *conn, bool premature);
+CURLcode Curl_http2_done_sending(struct connectdata *conn);
+CURLcode Curl_http2_add_child(struct Curl_easy *parent,
+                              struct Curl_easy *child,
+                              bool exclusive);
+void Curl_http2_remove_child(struct Curl_easy *parent,
+                             struct Curl_easy *child);
+void Curl_http2_cleanup_dependencies(struct Curl_easy *data);
+#else /* USE_NGHTTP2 */
+#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
+#define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL
+#define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL
+#define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL
+#define Curl_http2_switched(x,y,z) CURLE_UNSUPPORTED_PROTOCOL
+#define Curl_http2_setup_conn(x)
+#define Curl_http2_setup_req(x)
+#define Curl_http2_init_state(x)
+#define Curl_http2_init_userset(x)
+#define Curl_http2_done(x,y)
+#define Curl_http2_done_sending(x)
+#define Curl_http2_add_child(x, y, z)
+#define Curl_http2_remove_child(x, y)
+#define Curl_http2_cleanup_dependencies(x)
+#endif
+
+#endif /* HEADER_CURL_HTTP2_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/http_chunks.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/http_chunks.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/http_chunks.c	(revision 331)
@@ -0,0 +1,347 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_HTTP
+
+#include "urldata.h" /* it includes http_chunks.h */
+#include "sendf.h"   /* for the client write stuff */
+
+#include "content_encoding.h"
+#include "http.h"
+#include "non-ascii.h" /* for Curl_convert_to_network prototype */
+#include "strtoofft.h"
+#include "warnless.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * Chunk format (simplified):
+ *
+ * <HEX SIZE>[ chunk extension ] CRLF
+ * <DATA> CRLF
+ *
+ * Highlights from RFC2616 section 3.6 say:
+
+   The chunked encoding modifies the body of a message in order to
+   transfer it as a series of chunks, each with its own size indicator,
+   followed by an OPTIONAL trailer containing entity-header fields. This
+   allows dynamically produced content to be transferred along with the
+   information necessary for the recipient to verify that it has
+   received the full message.
+
+       Chunked-Body   = *chunk
+                        last-chunk
+                        trailer
+                        CRLF
+
+       chunk          = chunk-size [ chunk-extension ] CRLF
+                        chunk-data CRLF
+       chunk-size     = 1*HEX
+       last-chunk     = 1*("0") [ chunk-extension ] CRLF
+
+       chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
+       chunk-ext-name = token
+       chunk-ext-val  = token | quoted-string
+       chunk-data     = chunk-size(OCTET)
+       trailer        = *(entity-header CRLF)
+
+   The chunk-size field is a string of hex digits indicating the size of
+   the chunk. The chunked encoding is ended by any chunk whose size is
+   zero, followed by the trailer, which is terminated by an empty line.
+
+ */
+
+/* Check for an ASCII hex digit.
+ We avoid the use of isxdigit to accommodate non-ASCII hosts. */
+static bool Curl_isxdigit(char digit)
+{
+  return ( (digit >= 0x30 && digit <= 0x39) /* 0-9 */
+        || (digit >= 0x41 && digit <= 0x46) /* A-F */
+        || (digit >= 0x61 && digit <= 0x66) /* a-f */) ? TRUE : FALSE;
+}
+
+void Curl_httpchunk_init(struct connectdata *conn)
+{
+  struct Curl_chunker *chunk = &conn->chunk;
+  chunk->hexindex = 0;      /* start at 0 */
+  chunk->dataleft = 0;      /* no data left yet! */
+  chunk->state = CHUNK_HEX; /* we get hex first! */
+}
+
+/*
+ * chunk_read() returns a OK for normal operations, or a positive return code
+ * for errors. STOP means this sequence of chunks is complete.  The 'wrote'
+ * argument is set to tell the caller how many bytes we actually passed to the
+ * client (for byte-counting and whatever).
+ *
+ * The states and the state-machine is further explained in the header file.
+ *
+ * This function always uses ASCII hex values to accommodate non-ASCII hosts.
+ * For example, 0x0d and 0x0a are used instead of '\r' and '\n'.
+ */
+CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
+                              char *datap,
+                              ssize_t datalen,
+                              ssize_t *wrotep)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct Curl_chunker *ch = &conn->chunk;
+  struct SingleRequest *k = &data->req;
+  size_t piece;
+  curl_off_t length = (curl_off_t)datalen;
+  size_t *wrote = (size_t *)wrotep;
+
+  *wrote = 0; /* nothing's written yet */
+
+  /* the original data is written to the client, but we go on with the
+     chunk read process, to properly calculate the content length*/
+  if(data->set.http_te_skip && !k->ignorebody) {
+    result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, datalen);
+    if(result)
+      return CHUNKE_WRITE_ERROR;
+  }
+
+  while(length) {
+    switch(ch->state) {
+    case CHUNK_HEX:
+      if(Curl_isxdigit(*datap)) {
+        if(ch->hexindex < MAXNUM_SIZE) {
+          ch->hexbuffer[ch->hexindex] = *datap;
+          datap++;
+          length--;
+          ch->hexindex++;
+        }
+        else {
+          return CHUNKE_TOO_LONG_HEX; /* longer hex than we support */
+        }
+      }
+      else {
+        char *endptr;
+        if(0 == ch->hexindex)
+          /* This is illegal data, we received junk where we expected
+             a hexadecimal digit. */
+          return CHUNKE_ILLEGAL_HEX;
+
+        /* length and datap are unmodified */
+        ch->hexbuffer[ch->hexindex] = 0;
+
+        /* convert to host encoding before calling strtoul */
+        result = Curl_convert_from_network(conn->data, ch->hexbuffer,
+                                           ch->hexindex);
+        if(result) {
+          /* Curl_convert_from_network calls failf if unsuccessful */
+          /* Treat it as a bad hex character */
+          return CHUNKE_ILLEGAL_HEX;
+        }
+
+        if(curlx_strtoofft(ch->hexbuffer, &endptr, 16, &ch->datasize))
+          return CHUNKE_ILLEGAL_HEX;
+        ch->state = CHUNK_LF; /* now wait for the CRLF */
+      }
+      break;
+
+    case CHUNK_LF:
+      /* waiting for the LF after a chunk size */
+      if(*datap == 0x0a) {
+        /* we're now expecting data to come, unless size was zero! */
+        if(0 == ch->datasize) {
+          ch->state = CHUNK_TRAILER; /* now check for trailers */
+          conn->trlPos = 0;
+        }
+        else
+          ch->state = CHUNK_DATA;
+      }
+
+      datap++;
+      length--;
+      break;
+
+    case CHUNK_DATA:
+      /* We expect 'datasize' of data. We have 'length' right now, it can be
+         more or less than 'datasize'. Get the smallest piece.
+      */
+      piece = curlx_sotouz((ch->datasize >= length)?length:ch->datasize);
+
+      /* Write the data portion available */
+      if(conn->data->set.http_ce_skip || !k->writer_stack) {
+        if(!k->ignorebody)
+          result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, piece);
+      }
+      else
+        result = Curl_unencode_write(conn, k->writer_stack, datap, piece);
+
+      if(result)
+        return CHUNKE_WRITE_ERROR;
+
+      *wrote += piece;
+      ch->datasize -= piece; /* decrease amount left to expect */
+      datap += piece;    /* move read pointer forward */
+      length -= piece;   /* decrease space left in this round */
+
+      if(0 == ch->datasize)
+        /* end of data this round, we now expect a trailing CRLF */
+        ch->state = CHUNK_POSTLF;
+      break;
+
+    case CHUNK_POSTLF:
+      if(*datap == 0x0a) {
+        /* The last one before we go back to hex state and start all over. */
+        Curl_httpchunk_init(conn); /* sets state back to CHUNK_HEX */
+      }
+      else if(*datap != 0x0d)
+        return CHUNKE_BAD_CHUNK;
+      datap++;
+      length--;
+      break;
+
+    case CHUNK_TRAILER:
+      if((*datap == 0x0d) || (*datap == 0x0a)) {
+        /* this is the end of a trailer, but if the trailer was zero bytes
+           there was no trailer and we move on */
+
+        if(conn->trlPos) {
+          /* we allocate trailer with 3 bytes extra room to fit this */
+          conn->trailer[conn->trlPos++] = 0x0d;
+          conn->trailer[conn->trlPos++] = 0x0a;
+          conn->trailer[conn->trlPos] = 0;
+
+          /* Convert to host encoding before calling Curl_client_write */
+          result = Curl_convert_from_network(conn->data, conn->trailer,
+                                             conn->trlPos);
+          if(result)
+            /* Curl_convert_from_network calls failf if unsuccessful */
+            /* Treat it as a bad chunk */
+            return CHUNKE_BAD_CHUNK;
+
+          if(!data->set.http_te_skip) {
+            result = Curl_client_write(conn, CLIENTWRITE_HEADER,
+                                       conn->trailer, conn->trlPos);
+            if(result)
+              return CHUNKE_WRITE_ERROR;
+          }
+          conn->trlPos = 0;
+          ch->state = CHUNK_TRAILER_CR;
+          if(*datap == 0x0a)
+            /* already on the LF */
+            break;
+        }
+        else {
+          /* no trailer, we're on the final CRLF pair */
+          ch->state = CHUNK_TRAILER_POSTCR;
+          break; /* don't advance the pointer */
+        }
+      }
+      else {
+        /* conn->trailer is assumed to be freed in url.c on a
+           connection basis */
+        if(conn->trlPos >= conn->trlMax) {
+          /* we always allocate three extra bytes, just because when the full
+             header has been received we append CRLF\0 */
+          char *ptr;
+          if(conn->trlMax) {
+            conn->trlMax *= 2;
+            ptr = realloc(conn->trailer, conn->trlMax + 3);
+          }
+          else {
+            conn->trlMax = 128;
+            ptr = malloc(conn->trlMax + 3);
+          }
+          if(!ptr)
+            return CHUNKE_OUT_OF_MEMORY;
+          conn->trailer = ptr;
+        }
+        conn->trailer[conn->trlPos++]=*datap;
+      }
+      datap++;
+      length--;
+      break;
+
+    case CHUNK_TRAILER_CR:
+      if(*datap == 0x0a) {
+        ch->state = CHUNK_TRAILER_POSTCR;
+        datap++;
+        length--;
+      }
+      else
+        return CHUNKE_BAD_CHUNK;
+      break;
+
+    case CHUNK_TRAILER_POSTCR:
+      /* We enter this state when a CR should arrive so we expect to
+         have to first pass a CR before we wait for LF */
+      if((*datap != 0x0d) && (*datap != 0x0a)) {
+        /* not a CR then it must be another header in the trailer */
+        ch->state = CHUNK_TRAILER;
+        break;
+      }
+      if(*datap == 0x0d) {
+        /* skip if CR */
+        datap++;
+        length--;
+      }
+      /* now wait for the final LF */
+      ch->state = CHUNK_STOP;
+      break;
+
+    case CHUNK_STOP:
+      if(*datap == 0x0a) {
+        length--;
+
+        /* Record the length of any data left in the end of the buffer
+           even if there's no more chunks to read */
+        ch->dataleft = curlx_sotouz(length);
+
+        return CHUNKE_STOP; /* return stop */
+      }
+      else
+        return CHUNKE_BAD_CHUNK;
+    }
+  }
+  return CHUNKE_OK;
+}
+
+const char *Curl_chunked_strerror(CHUNKcode code)
+{
+  switch(code) {
+  default:
+    return "OK";
+  case CHUNKE_TOO_LONG_HEX:
+    return "Too long hexadecimal number";
+  case CHUNKE_ILLEGAL_HEX:
+    return "Illegal or missing hexadecimal sequence";
+  case CHUNKE_BAD_CHUNK:
+    return "Malformed encoding found";
+  case CHUNKE_WRITE_ERROR:
+    return "Write error";
+  case CHUNKE_BAD_ENCODING:
+    return "Bad content-encoding found";
+  case CHUNKE_OUT_OF_MEMORY:
+    return "Out of memory";
+  }
+}
+
+#endif /* CURL_DISABLE_HTTP */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/http_chunks.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/http_chunks.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/http_chunks.h	(revision 331)
@@ -0,0 +1,91 @@
+#ifndef HEADER_CURL_HTTP_CHUNKS_H
+#define HEADER_CURL_HTTP_CHUNKS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/*
+ * The longest possible hexadecimal number we support in a chunked transfer.
+ * Weird enough, RFC2616 doesn't set a maximum size! Since we use strtoul()
+ * to convert it, we "only" support 2^32 bytes chunk data.
+ */
+#define MAXNUM_SIZE 16
+
+typedef enum {
+  /* await and buffer all hexadecimal digits until we get one that isn't a
+     hexadecimal digit. When done, we go CHUNK_LF */
+  CHUNK_HEX,
+
+  /* wait for LF, ignore all else */
+  CHUNK_LF,
+
+  /* We eat the amount of data specified. When done, we move on to the
+     POST_CR state. */
+  CHUNK_DATA,
+
+  /* POSTLF should get a CR and then a LF and nothing else, then move back to
+     HEX as the CRLF combination marks the end of a chunk. A missing CR is no
+     big deal. */
+  CHUNK_POSTLF,
+
+  /* Used to mark that we're out of the game.  NOTE: that there's a 'dataleft'
+     field in the struct that will tell how many bytes that were not passed to
+     the client in the end of the last buffer! */
+  CHUNK_STOP,
+
+  /* At this point optional trailer headers can be found, unless the next line
+     is CRLF */
+  CHUNK_TRAILER,
+
+  /* A trailer CR has been found - next state is CHUNK_TRAILER_POSTCR.
+     Next char must be a LF */
+  CHUNK_TRAILER_CR,
+
+  /* A trailer LF must be found now, otherwise CHUNKE_BAD_CHUNK will be
+     signalled If this is an empty trailer CHUNKE_STOP will be signalled.
+     Otherwise the trailer will be broadcasted via Curl_client_write() and the
+     next state will be CHUNK_TRAILER */
+  CHUNK_TRAILER_POSTCR
+} ChunkyState;
+
+typedef enum {
+  CHUNKE_STOP = -1,
+  CHUNKE_OK = 0,
+  CHUNKE_TOO_LONG_HEX = 1,
+  CHUNKE_ILLEGAL_HEX,
+  CHUNKE_BAD_CHUNK,
+  CHUNKE_WRITE_ERROR,
+  CHUNKE_BAD_ENCODING,
+  CHUNKE_OUT_OF_MEMORY,
+  CHUNKE_LAST
+} CHUNKcode;
+
+const char *Curl_chunked_strerror(CHUNKcode code);
+
+struct Curl_chunker {
+  char hexbuffer[ MAXNUM_SIZE + 1];
+  int hexindex;
+  ChunkyState state;
+  curl_off_t datasize;
+  size_t dataleft; /* untouched data amount at the end of the last buffer */
+};
+
+#endif /* HEADER_CURL_HTTP_CHUNKS_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/http_digest.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/http_digest.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/http_digest.c	(revision 331)
@@ -0,0 +1,180 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
+
+#include "urldata.h"
+#include "strcase.h"
+#include "vauth/vauth.h"
+#include "http_digest.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Test example headers:
+
+WWW-Authenticate: Digest realm="testrealm", nonce="1053604598"
+Proxy-Authenticate: Digest realm="testrealm", nonce="1053604598"
+
+*/
+
+CURLcode Curl_input_digest(struct connectdata *conn,
+                           bool proxy,
+                           const char *header) /* rest of the *-authenticate:
+                                                  header */
+{
+  struct Curl_easy *data = conn->data;
+
+  /* Point to the correct struct with this */
+  struct digestdata *digest;
+
+  if(proxy) {
+    digest = &data->state.proxydigest;
+  }
+  else {
+    digest = &data->state.digest;
+  }
+
+  if(!checkprefix("Digest", header))
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  header += strlen("Digest");
+  while(*header && ISSPACE(*header))
+    header++;
+
+  return Curl_auth_decode_digest_http_message(header, digest);
+}
+
+CURLcode Curl_output_digest(struct connectdata *conn,
+                            bool proxy,
+                            const unsigned char *request,
+                            const unsigned char *uripath)
+{
+  CURLcode result;
+  struct Curl_easy *data = conn->data;
+  unsigned char *path = NULL;
+  char *tmp = NULL;
+  char *response;
+  size_t len;
+  bool have_chlg;
+
+  /* Point to the address of the pointer that holds the string to send to the
+     server, which is for a plain host or for a HTTP proxy */
+  char **allocuserpwd;
+
+  /* Point to the name and password for this */
+  const char *userp;
+  const char *passwdp;
+
+  /* Point to the correct struct with this */
+  struct digestdata *digest;
+  struct auth *authp;
+
+  if(proxy) {
+    digest = &data->state.proxydigest;
+    allocuserpwd = &conn->allocptr.proxyuserpwd;
+    userp = conn->http_proxy.user;
+    passwdp = conn->http_proxy.passwd;
+    authp = &data->state.authproxy;
+  }
+  else {
+    digest = &data->state.digest;
+    allocuserpwd = &conn->allocptr.userpwd;
+    userp = conn->user;
+    passwdp = conn->passwd;
+    authp = &data->state.authhost;
+  }
+
+  Curl_safefree(*allocuserpwd);
+
+  /* not set means empty */
+  if(!userp)
+    userp = "";
+
+  if(!passwdp)
+    passwdp = "";
+
+#if defined(USE_WINDOWS_SSPI)
+  have_chlg = digest->input_token ? TRUE : FALSE;
+#else
+  have_chlg = digest->nonce ? TRUE : FALSE;
+#endif
+
+  if(!have_chlg) {
+    authp->done = FALSE;
+    return CURLE_OK;
+  }
+
+  /* So IE browsers < v7 cut off the URI part at the query part when they
+     evaluate the MD5 and some (IIS?) servers work with them so we may need to
+     do the Digest IE-style. Note that the different ways cause different MD5
+     sums to get sent.
+
+     Apache servers can be set to do the Digest IE-style automatically using
+     the BrowserMatch feature:
+     https://httpd.apache.org/docs/2.2/mod/mod_auth_digest.html#msie
+
+     Further details on Digest implementation differences:
+     http://www.fngtps.com/2006/09/http-authentication
+  */
+
+  if(authp->iestyle) {
+    tmp = strchr((char *)uripath, '?');
+    if(tmp) {
+      size_t urilen = tmp - (char *)uripath;
+      path = (unsigned char *) aprintf("%.*s", urilen, uripath);
+    }
+  }
+  if(!tmp)
+    path = (unsigned char *) strdup((char *) uripath);
+
+  if(!path)
+    return CURLE_OUT_OF_MEMORY;
+
+  result = Curl_auth_create_digest_http_message(data, userp, passwdp, request,
+                                                path, digest, &response, &len);
+  free(path);
+  if(result)
+    return result;
+
+  *allocuserpwd = aprintf("%sAuthorization: Digest %s\r\n",
+                          proxy ? "Proxy-" : "",
+                          response);
+  free(response);
+  if(!*allocuserpwd)
+    return CURLE_OUT_OF_MEMORY;
+
+  authp->done = TRUE;
+
+  return CURLE_OK;
+}
+
+void Curl_digest_cleanup(struct Curl_easy *data)
+{
+  Curl_auth_digest_cleanup(&data->state.digest);
+  Curl_auth_digest_cleanup(&data->state.proxydigest);
+}
+
+#endif
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/http_digest.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/http_digest.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/http_digest.h	(revision 331)
@@ -0,0 +1,42 @@
+#ifndef HEADER_CURL_HTTP_DIGEST_H
+#define HEADER_CURL_HTTP_DIGEST_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+/* this is for digest header input */
+CURLcode Curl_input_digest(struct connectdata *conn,
+                           bool proxy, const char *header);
+
+/* this is for creating digest header output */
+CURLcode Curl_output_digest(struct connectdata *conn,
+                            bool proxy,
+                            const unsigned char *request,
+                            const unsigned char *uripath);
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
+void Curl_digest_cleanup(struct Curl_easy *data);
+#else
+#define Curl_digest_cleanup(x) Curl_nop_stmt
+#endif
+
+#endif /* HEADER_CURL_HTTP_DIGEST_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/http_negotiate.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/http_negotiate.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/http_negotiate.c	(revision 331)
@@ -0,0 +1,138 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO)
+
+#include "urldata.h"
+#include "sendf.h"
+#include "http_negotiate.h"
+#include "vauth/vauth.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
+                              const char *header)
+{
+  CURLcode result;
+  struct Curl_easy *data = conn->data;
+  size_t len;
+
+  /* Point to the username, password, service and host */
+  const char *userp;
+  const char *passwdp;
+  const char *service;
+  const char *host;
+
+  /* Point to the correct struct with this */
+  struct negotiatedata *neg_ctx;
+
+  if(proxy) {
+    userp = conn->http_proxy.user;
+    passwdp = conn->http_proxy.passwd;
+    service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
+              data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
+    host = conn->http_proxy.host.name;
+    neg_ctx = &data->state.proxyneg;
+  }
+  else {
+    userp = conn->user;
+    passwdp = conn->passwd;
+    service = data->set.str[STRING_SERVICE_NAME] ?
+              data->set.str[STRING_SERVICE_NAME] : "HTTP";
+    host = conn->host.name;
+    neg_ctx = &data->state.negotiate;
+  }
+
+  /* Not set means empty */
+  if(!userp)
+    userp = "";
+
+  if(!passwdp)
+    passwdp = "";
+
+  /* Obtain the input token, if any */
+  header += strlen("Negotiate");
+  while(*header && ISSPACE(*header))
+    header++;
+
+  len = strlen(header);
+  if(!len) {
+    /* Is this the first call in a new negotiation? */
+    if(neg_ctx->context) {
+      /* The server rejected our authentication and hasn't suppled any more
+      negotiation mechanisms */
+      return CURLE_LOGIN_DENIED;
+    }
+  }
+
+  /* Initilise the security context and decode our challenge */
+  result = Curl_auth_decode_spnego_message(data, userp, passwdp, service,
+                                           host, header, neg_ctx);
+
+  if(result)
+    Curl_auth_spnego_cleanup(neg_ctx);
+
+  return result;
+}
+
+CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
+{
+  struct negotiatedata *neg_ctx = proxy ? &conn->data->state.proxyneg :
+    &conn->data->state.negotiate;
+  char *base64 = NULL;
+  size_t len = 0;
+  char *userp;
+  CURLcode result;
+
+  result = Curl_auth_create_spnego_message(conn->data, neg_ctx, &base64, &len);
+  if(result)
+    return result;
+
+  userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "",
+                  base64);
+
+  if(proxy) {
+    Curl_safefree(conn->allocptr.proxyuserpwd);
+    conn->allocptr.proxyuserpwd = userp;
+  }
+  else {
+    Curl_safefree(conn->allocptr.userpwd);
+    conn->allocptr.userpwd = userp;
+  }
+
+  free(base64);
+
+  return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
+}
+
+void Curl_cleanup_negotiate(struct Curl_easy *data)
+{
+  Curl_auth_spnego_cleanup(&data->state.negotiate);
+  Curl_auth_spnego_cleanup(&data->state.proxyneg);
+}
+
+#endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/http_negotiate.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/http_negotiate.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/http_negotiate.h	(revision 331)
@@ -0,0 +1,38 @@
+#ifndef HEADER_CURL_HTTP_NEGOTIATE_H
+#define HEADER_CURL_HTTP_NEGOTIATE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifdef USE_SPNEGO
+
+/* this is for Negotiate header input */
+CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
+                              const char *header);
+
+/* this is for creating Negotiate header output */
+CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy);
+
+void Curl_cleanup_negotiate(struct Curl_easy *data);
+
+#endif /* USE_SPNEGO */
+
+#endif /* HEADER_CURL_HTTP_NEGOTIATE_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/http_ntlm.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/http_ntlm.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/http_ntlm.c	(revision 331)
@@ -0,0 +1,241 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
+
+/*
+ * NTLM details:
+ *
+ * https://davenport.sourceforge.io/ntlm.html
+ * https://www.innovation.ch/java/ntlm.html
+ */
+
+#define DEBUG_ME 0
+
+#include "urldata.h"
+#include "sendf.h"
+#include "strcase.h"
+#include "http_ntlm.h"
+#include "curl_ntlm_core.h"
+#include "curl_ntlm_wb.h"
+#include "vauth/vauth.h"
+#include "url.h"
+
+/* SSL backend-specific #if branches in this file must be kept in the order
+   documented in curl_ntlm_core. */
+#if defined(NTLM_NEEDS_NSS_INIT)
+#include "vtls/nssg.h"
+#elif defined(USE_WINDOWS_SSPI)
+#include "curl_sspi.h"
+#endif
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#if DEBUG_ME
+# define DEBUG_OUT(x) x
+#else
+# define DEBUG_OUT(x) Curl_nop_stmt
+#endif
+
+CURLcode Curl_input_ntlm(struct connectdata *conn,
+                         bool proxy,         /* if proxy or not */
+                         const char *header) /* rest of the www-authenticate:
+                                                header */
+{
+  /* point to the correct struct with this */
+  struct ntlmdata *ntlm;
+  CURLcode result = CURLE_OK;
+
+  ntlm = proxy ? &conn->proxyntlm : &conn->ntlm;
+
+  if(checkprefix("NTLM", header)) {
+    header += strlen("NTLM");
+
+    while(*header && ISSPACE(*header))
+      header++;
+
+    if(*header) {
+      result = Curl_auth_decode_ntlm_type2_message(conn->data, header, ntlm);
+      if(result)
+        return result;
+
+      ntlm->state = NTLMSTATE_TYPE2; /* We got a type-2 message */
+    }
+    else {
+      if(ntlm->state == NTLMSTATE_LAST) {
+        infof(conn->data, "NTLM auth restarted\n");
+        Curl_http_ntlm_cleanup(conn);
+      }
+      else if(ntlm->state == NTLMSTATE_TYPE3) {
+        infof(conn->data, "NTLM handshake rejected\n");
+        Curl_http_ntlm_cleanup(conn);
+        ntlm->state = NTLMSTATE_NONE;
+        return CURLE_REMOTE_ACCESS_DENIED;
+      }
+      else if(ntlm->state >= NTLMSTATE_TYPE1) {
+        infof(conn->data, "NTLM handshake failure (internal error)\n");
+        return CURLE_REMOTE_ACCESS_DENIED;
+      }
+
+      ntlm->state = NTLMSTATE_TYPE1; /* We should send away a type-1 */
+    }
+  }
+
+  return result;
+}
+
+/*
+ * This is for creating ntlm header output
+ */
+CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
+{
+  char *base64 = NULL;
+  size_t len = 0;
+  CURLcode result;
+
+  /* point to the address of the pointer that holds the string to send to the
+     server, which is for a plain host or for a HTTP proxy */
+  char **allocuserpwd;
+
+  /* point to the name and password for this */
+  const char *userp;
+  const char *passwdp;
+
+  /* point to the correct struct with this */
+  struct ntlmdata *ntlm;
+  struct auth *authp;
+
+  DEBUGASSERT(conn);
+  DEBUGASSERT(conn->data);
+
+#if defined(NTLM_NEEDS_NSS_INIT)
+  if(CURLE_OK != Curl_nss_force_init(conn->data))
+    return CURLE_OUT_OF_MEMORY;
+#endif
+
+  if(proxy) {
+    allocuserpwd = &conn->allocptr.proxyuserpwd;
+    userp = conn->http_proxy.user;
+    passwdp = conn->http_proxy.passwd;
+    ntlm = &conn->proxyntlm;
+    authp = &conn->data->state.authproxy;
+  }
+  else {
+    allocuserpwd = &conn->allocptr.userpwd;
+    userp = conn->user;
+    passwdp = conn->passwd;
+    ntlm = &conn->ntlm;
+    authp = &conn->data->state.authhost;
+  }
+  authp->done = FALSE;
+
+  /* not set means empty */
+  if(!userp)
+    userp = "";
+
+  if(!passwdp)
+    passwdp = "";
+
+#ifdef USE_WINDOWS_SSPI
+  if(s_hSecDll == NULL) {
+    /* not thread safe and leaks - use curl_global_init() to avoid */
+    CURLcode err = Curl_sspi_global_init();
+    if(s_hSecDll == NULL)
+      return err;
+  }
+#endif
+
+  switch(ntlm->state) {
+  case NTLMSTATE_TYPE1:
+  default: /* for the weird cases we (re)start here */
+    /* Create a type-1 message */
+    result = Curl_auth_create_ntlm_type1_message(conn->data, userp, passwdp,
+                                                 ntlm, &base64, &len);
+    if(result)
+      return result;
+
+    if(base64) {
+      free(*allocuserpwd);
+      *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
+                              proxy ? "Proxy-" : "",
+                              base64);
+      free(base64);
+      if(!*allocuserpwd)
+        return CURLE_OUT_OF_MEMORY;
+
+      DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
+    }
+    break;
+
+  case NTLMSTATE_TYPE2:
+    /* We already received the type-2 message, create a type-3 message */
+    result = Curl_auth_create_ntlm_type3_message(conn->data, userp, passwdp,
+                                                 ntlm, &base64, &len);
+    if(result)
+      return result;
+
+    if(base64) {
+      free(*allocuserpwd);
+      *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
+                              proxy ? "Proxy-" : "",
+                              base64);
+      free(base64);
+      if(!*allocuserpwd)
+        return CURLE_OUT_OF_MEMORY;
+
+      DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
+
+      ntlm->state = NTLMSTATE_TYPE3; /* we send a type-3 */
+      authp->done = TRUE;
+    }
+    break;
+
+  case NTLMSTATE_TYPE3:
+    /* connection is already authenticated,
+     * don't send a header in future requests */
+    ntlm->state = NTLMSTATE_LAST;
+    /* fall-through */
+  case NTLMSTATE_LAST:
+    Curl_safefree(*allocuserpwd);
+    authp->done = TRUE;
+    break;
+  }
+
+  return CURLE_OK;
+}
+
+void Curl_http_ntlm_cleanup(struct connectdata *conn)
+{
+  Curl_auth_ntlm_cleanup(&conn->ntlm);
+  Curl_auth_ntlm_cleanup(&conn->proxyntlm);
+
+#if defined(NTLM_WB_ENABLED)
+  Curl_ntlm_wb_cleanup(conn);
+#endif
+}
+
+#endif /* !CURL_DISABLE_HTTP && USE_NTLM */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/http_ntlm.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/http_ntlm.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/http_ntlm.h	(revision 331)
@@ -0,0 +1,40 @@
+#ifndef HEADER_CURL_NTLM_H
+#define HEADER_CURL_NTLM_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
+
+/* this is for ntlm header input */
+CURLcode Curl_input_ntlm(struct connectdata *conn, bool proxy,
+                         const char *header);
+
+/* this is for creating ntlm header output */
+CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy);
+
+void Curl_http_ntlm_cleanup(struct connectdata *conn);
+
+#endif /* !CURL_DISABLE_HTTP && USE_NTLM */
+
+#endif /* HEADER_CURL_NTLM_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/http_proxy.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/http_proxy.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/http_proxy.c	(revision 331)
@@ -0,0 +1,686 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "http_proxy.h"
+
+#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP)
+
+#include <curl/curl.h>
+#include "sendf.h"
+#include "http.h"
+#include "url.h"
+#include "select.h"
+#include "progress.h"
+#include "non-ascii.h"
+#include "connect.h"
+#include "curlx.h"
+#include "vtls/vtls.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * Perform SSL initialization for HTTPS proxy.  Sets
+ * proxy_ssl_connected connection bit when complete.  Can be
+ * called multiple times.
+ */
+static CURLcode https_proxy_connect(struct connectdata *conn, int sockindex)
+{
+#ifdef USE_SSL
+  CURLcode result = CURLE_OK;
+  DEBUGASSERT(conn->http_proxy.proxytype == CURLPROXY_HTTPS);
+  if(!conn->bits.proxy_ssl_connected[sockindex]) {
+    /* perform SSL initialization for this socket */
+    result =
+      Curl_ssl_connect_nonblocking(conn, sockindex,
+                                   &conn->bits.proxy_ssl_connected[sockindex]);
+    if(result)
+      conn->bits.close = TRUE; /* a failed connection is marked for closure to
+                                  prevent (bad) re-use or similar */
+  }
+  return result;
+#else
+  (void) conn;
+  (void) sockindex;
+  return CURLE_NOT_BUILT_IN;
+#endif
+}
+
+CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
+{
+  if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
+    const CURLcode result = https_proxy_connect(conn, sockindex);
+    if(result)
+      return result;
+    if(!conn->bits.proxy_ssl_connected[sockindex])
+      return result; /* wait for HTTPS proxy SSL initialization to complete */
+  }
+
+  if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
+#ifndef CURL_DISABLE_PROXY
+    /* for [protocol] tunneled through HTTP proxy */
+    struct HTTP http_proxy;
+    void *prot_save;
+    const char *hostname;
+    int remote_port;
+    CURLcode result;
+
+    /* BLOCKING */
+    /* We want "seamless" operations through HTTP proxy tunnel */
+
+    /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the
+     * member conn->proto.http; we want [protocol] through HTTP and we have
+     * to change the member temporarily for connecting to the HTTP
+     * proxy. After Curl_proxyCONNECT we have to set back the member to the
+     * original pointer
+     *
+     * This function might be called several times in the multi interface case
+     * if the proxy's CONNECT response is not instant.
+     */
+    prot_save = conn->data->req.protop;
+    memset(&http_proxy, 0, sizeof(http_proxy));
+    conn->data->req.protop = &http_proxy;
+    connkeep(conn, "HTTP proxy CONNECT");
+
+    /* for the secondary socket (FTP), use the "connect to host"
+     * but ignore the "connect to port" (use the secondary port)
+     */
+
+    if(conn->bits.conn_to_host)
+      hostname = conn->conn_to_host.name;
+    else if(sockindex == SECONDARYSOCKET)
+      hostname = conn->secondaryhostname;
+    else
+      hostname = conn->host.name;
+
+    if(sockindex == SECONDARYSOCKET)
+      remote_port = conn->secondary_port;
+    else if(conn->bits.conn_to_port)
+      remote_port = conn->conn_to_port;
+    else
+      remote_port = conn->remote_port;
+    result = Curl_proxyCONNECT(conn, sockindex, hostname, remote_port);
+    conn->data->req.protop = prot_save;
+    if(CURLE_OK != result)
+      return result;
+    Curl_safefree(conn->allocptr.proxyuserpwd);
+#else
+    return CURLE_NOT_BUILT_IN;
+#endif
+  }
+  /* no HTTP tunnel proxy, just return */
+  return CURLE_OK;
+}
+
+bool Curl_connect_complete(struct connectdata *conn)
+{
+  return !conn->connect_state ||
+    (conn->connect_state->tunnel_state == TUNNEL_COMPLETE);
+}
+
+bool Curl_connect_ongoing(struct connectdata *conn)
+{
+  return conn->connect_state &&
+    (conn->connect_state->tunnel_state != TUNNEL_COMPLETE);
+}
+
+static CURLcode connect_init(struct connectdata *conn, bool reinit)
+{
+  struct http_connect_state *s;
+  if(!reinit) {
+    DEBUGASSERT(!conn->connect_state);
+    s = calloc(1, sizeof(struct http_connect_state));
+    if(!s)
+      return CURLE_OUT_OF_MEMORY;
+    infof(conn->data, "allocate connect buffer!\n");
+    conn->connect_state = s;
+  }
+  else {
+    DEBUGASSERT(conn->connect_state);
+    s = conn->connect_state;
+  }
+  s->tunnel_state = TUNNEL_INIT;
+  s->keepon = TRUE;
+  s->line_start = s->connect_buffer;
+  s->ptr = s->line_start;
+  s->cl = 0;
+  return CURLE_OK;
+}
+
+static void connect_done(struct connectdata *conn)
+{
+  struct http_connect_state *s = conn->connect_state;
+  s->tunnel_state = TUNNEL_COMPLETE;
+  infof(conn->data, "CONNECT phase completed!\n");
+}
+
+static CURLcode CONNECT(struct connectdata *conn,
+                        int sockindex,
+                        const char *hostname,
+                        int remote_port)
+{
+  int subversion = 0;
+  struct Curl_easy *data = conn->data;
+  struct SingleRequest *k = &data->req;
+  CURLcode result;
+  curl_socket_t tunnelsocket = conn->sock[sockindex];
+  bool closeConnection = FALSE;
+  timediff_t check;
+  struct http_connect_state *s = conn->connect_state;
+
+#define SELECT_OK      0
+#define SELECT_ERROR   1
+#define SELECT_TIMEOUT 2
+
+  if(Curl_connect_complete(conn))
+    return CURLE_OK; /* CONNECT is already completed */
+
+  conn->bits.proxy_connect_closed = FALSE;
+
+  do {
+    if(TUNNEL_INIT == s->tunnel_state) {
+      /* BEGIN CONNECT PHASE */
+      char *host_port;
+      Curl_send_buffer *req_buffer;
+
+      infof(data, "Establish HTTP proxy tunnel to %s:%hu\n",
+            hostname, remote_port);
+
+        /* This only happens if we've looped here due to authentication
+           reasons, and we don't really use the newly cloned URL here
+           then. Just free() it. */
+      free(data->req.newurl);
+      data->req.newurl = NULL;
+
+      /* initialize a dynamic send-buffer */
+      req_buffer = Curl_add_buffer_init();
+
+      if(!req_buffer)
+        return CURLE_OUT_OF_MEMORY;
+
+      host_port = aprintf("%s:%hu", hostname, remote_port);
+      if(!host_port) {
+        Curl_add_buffer_free(req_buffer);
+        return CURLE_OUT_OF_MEMORY;
+      }
+
+      /* Setup the proxy-authorization header, if any */
+      result = Curl_http_output_auth(conn, "CONNECT", host_port, TRUE);
+
+      free(host_port);
+
+      if(!result) {
+        char *host = NULL;
+        const char *proxyconn = "";
+        const char *useragent = "";
+        const char *http = (conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ?
+          "1.0" : "1.1";
+        bool ipv6_ip = conn->bits.ipv6_ip;
+        char *hostheader;
+
+        /* the hostname may be different */
+        if(hostname != conn->host.name)
+          ipv6_ip = (strchr(hostname, ':') != NULL);
+        hostheader = /* host:port with IPv6 support */
+          aprintf("%s%s%s:%hu", ipv6_ip?"[":"", hostname, ipv6_ip?"]":"",
+                  remote_port);
+        if(!hostheader) {
+          Curl_add_buffer_free(req_buffer);
+          return CURLE_OUT_OF_MEMORY;
+        }
+
+        if(!Curl_checkProxyheaders(conn, "Host:")) {
+          host = aprintf("Host: %s\r\n", hostheader);
+          if(!host) {
+            free(hostheader);
+            Curl_add_buffer_free(req_buffer);
+            return CURLE_OUT_OF_MEMORY;
+          }
+        }
+        if(!Curl_checkProxyheaders(conn, "Proxy-Connection:"))
+          proxyconn = "Proxy-Connection: Keep-Alive\r\n";
+
+        if(!Curl_checkProxyheaders(conn, "User-Agent:") &&
+           data->set.str[STRING_USERAGENT])
+          useragent = conn->allocptr.uagent;
+
+        result =
+          Curl_add_bufferf(req_buffer,
+                           "CONNECT %s HTTP/%s\r\n"
+                           "%s"  /* Host: */
+                           "%s"  /* Proxy-Authorization */
+                           "%s"  /* User-Agent */
+                           "%s", /* Proxy-Connection */
+                           hostheader,
+                           http,
+                           host?host:"",
+                           conn->allocptr.proxyuserpwd?
+                           conn->allocptr.proxyuserpwd:"",
+                           useragent,
+                           proxyconn);
+
+        if(host)
+          free(host);
+        free(hostheader);
+
+        if(!result)
+          result = Curl_add_custom_headers(conn, TRUE, req_buffer);
+
+        if(!result)
+          /* CRLF terminate the request */
+          result = Curl_add_bufferf(req_buffer, "\r\n");
+
+        if(!result) {
+          /* Send the connect request to the proxy */
+          /* BLOCKING */
+          result =
+            Curl_add_buffer_send(req_buffer, conn,
+                                 &data->info.request_size, 0, sockindex);
+        }
+        req_buffer = NULL;
+        if(result)
+          failf(data, "Failed sending CONNECT to proxy");
+      }
+
+      Curl_add_buffer_free(req_buffer);
+      if(result)
+        return result;
+
+      s->tunnel_state = TUNNEL_CONNECT;
+      s->perline = 0;
+    } /* END CONNECT PHASE */
+
+    check = Curl_timeleft(data, NULL, TRUE);
+    if(check <= 0) {
+      failf(data, "Proxy CONNECT aborted due to timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    if(!Curl_conn_data_pending(conn, sockindex))
+      /* return so we'll be called again polling-style */
+      return CURLE_OK;
+
+    /* at this point, the tunnel_connecting phase is over. */
+
+    { /* READING RESPONSE PHASE */
+      int error = SELECT_OK;
+
+      while(s->keepon && !error) {
+        ssize_t gotbytes;
+
+        /* make sure we have space to read more data */
+        if(s->ptr >= &s->connect_buffer[CONNECT_BUFFER_SIZE]) {
+          failf(data, "CONNECT response too large!");
+          return CURLE_RECV_ERROR;
+        }
+
+        /* Read one byte at a time to avoid a race condition. Wait at most one
+           second before looping to ensure continuous pgrsUpdates. */
+        result = Curl_read(conn, tunnelsocket, s->ptr, 1, &gotbytes);
+        if(result == CURLE_AGAIN)
+          /* socket buffer drained, return */
+          return CURLE_OK;
+
+        if(Curl_pgrsUpdate(conn))
+          return CURLE_ABORTED_BY_CALLBACK;
+
+        if(result) {
+          s->keepon = FALSE;
+          break;
+        }
+        else if(gotbytes <= 0) {
+          if(data->set.proxyauth && data->state.authproxy.avail) {
+            /* proxy auth was requested and there was proxy auth available,
+               then deem this as "mere" proxy disconnect */
+            conn->bits.proxy_connect_closed = TRUE;
+            infof(data, "Proxy CONNECT connection closed\n");
+          }
+          else {
+            error = SELECT_ERROR;
+            failf(data, "Proxy CONNECT aborted");
+          }
+          s->keepon = FALSE;
+          break;
+        }
+
+
+        if(s->keepon > TRUE) {
+          /* This means we are currently ignoring a response-body */
+
+          s->ptr = s->connect_buffer;
+          if(s->cl) {
+            /* A Content-Length based body: simply count down the counter
+               and make sure to break out of the loop when we're done! */
+            s->cl--;
+            if(s->cl <= 0) {
+              s->keepon = FALSE;
+              s->tunnel_state = TUNNEL_COMPLETE;
+              break;
+            }
+          }
+          else {
+            /* chunked-encoded body, so we need to do the chunked dance
+               properly to know when the end of the body is reached */
+            CHUNKcode r;
+            ssize_t tookcareof = 0;
+
+            /* now parse the chunked piece of data so that we can
+               properly tell when the stream ends */
+            r = Curl_httpchunk_read(conn, s->ptr, 1, &tookcareof);
+            if(r == CHUNKE_STOP) {
+              /* we're done reading chunks! */
+              infof(data, "chunk reading DONE\n");
+              s->keepon = FALSE;
+              /* we did the full CONNECT treatment, go COMPLETE */
+              s->tunnel_state = TUNNEL_COMPLETE;
+            }
+          }
+          continue;
+        }
+
+        s->perline++; /* amount of bytes in this line so far */
+
+        /* if this is not the end of a header line then continue */
+        if(*s->ptr != 0x0a) {
+          s->ptr++;
+          continue;
+        }
+
+        /* convert from the network encoding */
+        result = Curl_convert_from_network(data, s->line_start,
+                                           (size_t)s->perline);
+        /* Curl_convert_from_network calls failf if unsuccessful */
+        if(result)
+          return result;
+
+        /* output debug if that is requested */
+        if(data->set.verbose)
+          Curl_debug(data, CURLINFO_HEADER_IN,
+                     s->line_start, (size_t)s->perline, conn);
+
+        if(!data->set.suppress_connect_headers) {
+          /* send the header to the callback */
+          int writetype = CLIENTWRITE_HEADER;
+          if(data->set.include_header)
+            writetype |= CLIENTWRITE_BODY;
+
+          result = Curl_client_write(conn, writetype,
+                                     s->line_start, s->perline);
+          if(result)
+            return result;
+        }
+
+        data->info.header_size += (long)s->perline;
+        data->req.headerbytecount += (long)s->perline;
+
+        /* Newlines are CRLF, so the CR is ignored as the line isn't
+           really terminated until the LF comes. Treat a following CR
+           as end-of-headers as well.*/
+
+        if(('\r' == s->line_start[0]) ||
+           ('\n' == s->line_start[0])) {
+          /* end of response-headers from the proxy */
+          s->ptr = s->connect_buffer;
+          if((407 == k->httpcode) && !data->state.authproblem) {
+            /* If we get a 407 response code with content length
+               when we have no auth problem, we must ignore the
+               whole response-body */
+            s->keepon = 2;
+
+            if(s->cl) {
+              infof(data, "Ignore %" CURL_FORMAT_CURL_OFF_T
+                    " bytes of response-body\n", s->cl);
+            }
+            else if(s->chunked_encoding) {
+              CHUNKcode r;
+
+              infof(data, "Ignore chunked response-body\n");
+
+              /* We set ignorebody true here since the chunked
+                 decoder function will acknowledge that. Pay
+                 attention so that this is cleared again when this
+                 function returns! */
+              k->ignorebody = TRUE;
+
+              if(s->line_start[1] == '\n') {
+                /* this can only be a LF if the letter at index 0
+                   was a CR */
+                s->line_start++;
+              }
+
+              /* now parse the chunked piece of data so that we can
+                 properly tell when the stream ends */
+              r = Curl_httpchunk_read(conn, s->line_start + 1, 1, &gotbytes);
+              if(r == CHUNKE_STOP) {
+                /* we're done reading chunks! */
+                infof(data, "chunk reading DONE\n");
+                s->keepon = FALSE;
+                /* we did the full CONNECT treatment, go to COMPLETE */
+                s->tunnel_state = TUNNEL_COMPLETE;
+              }
+            }
+            else {
+              /* without content-length or chunked encoding, we
+                 can't keep the connection alive since the close is
+                 the end signal so we bail out at once instead */
+              s->keepon = FALSE;
+            }
+          }
+          else
+            s->keepon = FALSE;
+          if(!s->cl)
+            /* we did the full CONNECT treatment, go to COMPLETE */
+            s->tunnel_state = TUNNEL_COMPLETE;
+          continue;
+        }
+
+        s->line_start[s->perline] = 0; /* zero terminate the buffer */
+        if((checkprefix("WWW-Authenticate:", s->line_start) &&
+            (401 == k->httpcode)) ||
+           (checkprefix("Proxy-authenticate:", s->line_start) &&
+            (407 == k->httpcode))) {
+
+          bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
+          char *auth = Curl_copy_header_value(s->line_start);
+          if(!auth)
+            return CURLE_OUT_OF_MEMORY;
+
+          result = Curl_http_input_auth(conn, proxy, auth);
+
+          free(auth);
+
+          if(result)
+            return result;
+        }
+        else if(checkprefix("Content-Length:", s->line_start)) {
+          if(k->httpcode/100 == 2) {
+            /* A client MUST ignore any Content-Length or Transfer-Encoding
+               header fields received in a successful response to CONNECT.
+               "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */
+            infof(data, "Ignoring Content-Length in CONNECT %03d response\n",
+                  k->httpcode);
+          }
+          else {
+            (void)curlx_strtoofft(s->line_start +
+                                  strlen("Content-Length:"), NULL, 10, &s->cl);
+          }
+        }
+        else if(Curl_compareheader(s->line_start, "Connection:", "close"))
+          closeConnection = TRUE;
+        else if(checkprefix("Transfer-Encoding:", s->line_start)) {
+          if(k->httpcode/100 == 2) {
+            /* A client MUST ignore any Content-Length or Transfer-Encoding
+               header fields received in a successful response to CONNECT.
+               "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */
+            infof(data, "Ignoring Transfer-Encoding in "
+                  "CONNECT %03d response\n", k->httpcode);
+          }
+          else if(Curl_compareheader(s->line_start,
+                                     "Transfer-Encoding:", "chunked")) {
+            infof(data, "CONNECT responded chunked\n");
+            s->chunked_encoding = TRUE;
+            /* init our chunky engine */
+            Curl_httpchunk_init(conn);
+          }
+        }
+        else if(Curl_compareheader(s->line_start,
+                                   "Proxy-Connection:", "close"))
+          closeConnection = TRUE;
+        else if(2 == sscanf(s->line_start, "HTTP/1.%d %d",
+                            &subversion,
+                            &k->httpcode)) {
+          /* store the HTTP code from the proxy */
+          data->info.httpproxycode = k->httpcode;
+        }
+
+        s->perline = 0; /* line starts over here */
+        s->ptr = s->connect_buffer;
+        s->line_start = s->ptr;
+      } /* while there's buffer left and loop is requested */
+
+      if(Curl_pgrsUpdate(conn))
+        return CURLE_ABORTED_BY_CALLBACK;
+
+      if(error)
+        return CURLE_RECV_ERROR;
+
+      if(data->info.httpproxycode/100 != 2) {
+        /* Deal with the possibly already received authenticate
+           headers. 'newurl' is set to a new URL if we must loop. */
+        result = Curl_http_auth_act(conn);
+        if(result)
+          return result;
+
+        if(conn->bits.close)
+          /* the connection has been marked for closure, most likely in the
+             Curl_http_auth_act() function and thus we can kill it at once
+             below */
+          closeConnection = TRUE;
+      }
+
+      if(closeConnection && data->req.newurl) {
+        /* Connection closed by server. Don't use it anymore */
+        Curl_closesocket(conn, conn->sock[sockindex]);
+        conn->sock[sockindex] = CURL_SOCKET_BAD;
+        break;
+      }
+    } /* END READING RESPONSE PHASE */
+
+    /* If we are supposed to continue and request a new URL, which basically
+     * means the HTTP authentication is still going on so if the tunnel
+     * is complete we start over in INIT state */
+    if(data->req.newurl && (TUNNEL_COMPLETE == s->tunnel_state)) {
+      connect_init(conn, TRUE); /* reinit */
+    }
+
+  } while(data->req.newurl);
+
+  if(data->info.httpproxycode/100 != 2) {
+    if(closeConnection && data->req.newurl) {
+      conn->bits.proxy_connect_closed = TRUE;
+      infof(data, "Connect me again please\n");
+      connect_done(conn);
+    }
+    else {
+      free(data->req.newurl);
+      data->req.newurl = NULL;
+      /* failure, close this connection to avoid re-use */
+      streamclose(conn, "proxy CONNECT failure");
+      Curl_closesocket(conn, conn->sock[sockindex]);
+      conn->sock[sockindex] = CURL_SOCKET_BAD;
+    }
+
+    /* to back to init state */
+    s->tunnel_state = TUNNEL_INIT;
+
+    if(conn->bits.proxy_connect_closed)
+      /* this is not an error, just part of the connection negotiation */
+      return CURLE_OK;
+    failf(data, "Received HTTP code %d from proxy after CONNECT",
+          data->req.httpcode);
+    return CURLE_RECV_ERROR;
+  }
+
+  s->tunnel_state = TUNNEL_COMPLETE;
+
+  /* If a proxy-authorization header was used for the proxy, then we should
+     make sure that it isn't accidentally used for the document request
+     after we've connected. So let's free and clear it here. */
+  Curl_safefree(conn->allocptr.proxyuserpwd);
+  conn->allocptr.proxyuserpwd = NULL;
+
+  data->state.authproxy.done = TRUE;
+
+  infof(data, "Proxy replied %d to CONNECT request\n",
+        data->info.httpproxycode);
+  data->req.ignorebody = FALSE; /* put it (back) to non-ignore state */
+  conn->bits.rewindaftersend = FALSE; /* make sure this isn't set for the
+                                         document request  */
+  return CURLE_OK;
+}
+
+void Curl_connect_free(struct Curl_easy *data)
+{
+  struct connectdata *conn = data->easy_conn;
+  struct http_connect_state *s = conn->connect_state;
+  if(s) {
+    free(s);
+    conn->connect_state = NULL;
+  }
+}
+
+/*
+ * Curl_proxyCONNECT() requires that we're connected to a HTTP proxy. This
+ * function will issue the necessary commands to get a seamless tunnel through
+ * this proxy. After that, the socket can be used just as a normal socket.
+ */
+
+CURLcode Curl_proxyCONNECT(struct connectdata *conn,
+                           int sockindex,
+                           const char *hostname,
+                           int remote_port)
+{
+  CURLcode result;
+  if(!conn->connect_state) {
+    result = connect_init(conn, FALSE);
+    if(result)
+      return result;
+  }
+  result = CONNECT(conn, sockindex, hostname, remote_port);
+
+  if(result || Curl_connect_complete(conn))
+    connect_done(conn);
+
+  return result;
+}
+
+#else
+void Curl_connect_free(struct Curl_easy *data)
+{
+  (void)data;
+}
+
+#endif /* CURL_DISABLE_PROXY */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/http_proxy.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/http_proxy.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/http_proxy.h	(revision 331)
@@ -0,0 +1,51 @@
+#ifndef HEADER_CURL_HTTP_PROXY_H
+#define HEADER_CURL_HTTP_PROXY_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "urldata.h"
+
+#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP)
+/* ftp can use this as well */
+CURLcode Curl_proxyCONNECT(struct connectdata *conn,
+                           int tunnelsocket,
+                           const char *hostname, int remote_port);
+
+/* Default proxy timeout in milliseconds */
+#define PROXY_TIMEOUT (3600*1000)
+
+CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex);
+
+bool Curl_connect_complete(struct connectdata *conn);
+bool Curl_connect_ongoing(struct connectdata *conn);
+
+#else
+#define Curl_proxyCONNECT(x,y,z,w) CURLE_NOT_BUILT_IN
+#define Curl_proxy_connect(x,y) CURLE_OK
+#define Curl_connect_complete(x) CURLE_OK
+#define Curl_connect_ongoing(x) FALSE
+#endif
+
+void Curl_connect_free(struct Curl_easy *data);
+
+#endif /* HEADER_CURL_HTTP_PROXY_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/idn_win32.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/idn_win32.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/idn_win32.c	(revision 331)
@@ -0,0 +1,111 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+ /*
+  * IDN conversions using Windows kernel32 and normaliz libraries.
+  */
+
+#include "curl_setup.h"
+
+#ifdef USE_WIN32_IDN
+
+#include "curl_multibyte.h"
+#include "curl_memory.h"
+#include "warnless.h"
+
+  /* The last #include file should be: */
+#include "memdebug.h"
+
+#ifdef WANT_IDN_PROTOTYPES
+#  if defined(_SAL_VERSION)
+WINNORMALIZEAPI int WINAPI
+IdnToAscii(_In_                           DWORD    dwFlags,
+           _In_reads_(cchUnicodeChar)     LPCWSTR  lpUnicodeCharStr,
+           _In_                           int      cchUnicodeChar,
+           _Out_writes_opt_(cchASCIIChar) LPWSTR   lpASCIICharStr,
+           _In_                           int      cchASCIIChar);
+WINNORMALIZEAPI int WINAPI
+IdnToUnicode(_In_                             DWORD   dwFlags,
+             _In_reads_(cchASCIIChar)         LPCWSTR lpASCIICharStr,
+             _In_                             int     cchASCIIChar,
+             _Out_writes_opt_(cchUnicodeChar) LPWSTR  lpUnicodeCharStr,
+             _In_                             int     cchUnicodeChar);
+#  else
+WINBASEAPI int WINAPI IdnToAscii(DWORD dwFlags,
+                                 const WCHAR *lpUnicodeCharStr,
+                                 int cchUnicodeChar,
+                                 WCHAR *lpASCIICharStr,
+                                 int cchASCIIChar);
+WINBASEAPI int WINAPI IdnToUnicode(DWORD dwFlags,
+                                   const WCHAR *lpASCIICharStr,
+                                   int cchASCIIChar,
+                                   WCHAR *lpUnicodeCharStr,
+                                   int cchUnicodeChar);
+#  endif
+#endif
+
+#define IDN_MAX_LENGTH 255
+
+bool curl_win32_idn_to_ascii(const char *in, char **out);
+bool curl_win32_ascii_to_idn(const char *in, char **out);
+
+bool curl_win32_idn_to_ascii(const char *in, char **out)
+{
+  bool success = FALSE;
+
+  wchar_t *in_w = Curl_convert_UTF8_to_wchar(in);
+  if(in_w) {
+    wchar_t punycode[IDN_MAX_LENGTH];
+    int chars = IdnToAscii(0, in_w, -1, punycode, IDN_MAX_LENGTH);
+    free(in_w);
+    if(chars) {
+      *out = Curl_convert_wchar_to_UTF8(punycode);
+      if(*out)
+        success = TRUE;
+    }
+  }
+
+  return success;
+}
+
+bool curl_win32_ascii_to_idn(const char *in, char **out)
+{
+  bool success = FALSE;
+
+  wchar_t *in_w = Curl_convert_UTF8_to_wchar(in);
+  if(in_w) {
+    size_t in_len = wcslen(in_w) + 1;
+    wchar_t unicode[IDN_MAX_LENGTH];
+    int chars = IdnToUnicode(0, in_w, curlx_uztosi(in_len),
+                             unicode, IDN_MAX_LENGTH);
+    free(in_w);
+    if(chars) {
+      *out = Curl_convert_wchar_to_UTF8(unicode);
+      if(*out)
+        success = TRUE;
+    }
+  }
+
+  return success;
+}
+
+#endif /* USE_WIN32_IDN */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/if2ip.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/if2ip.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/if2ip.c	(revision 331)
@@ -0,0 +1,274 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#  include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#  include <sys/ioctl.h>
+#endif
+#ifdef HAVE_NETDB_H
+#  include <netdb.h>
+#endif
+#ifdef HAVE_SYS_SOCKIO_H
+#  include <sys/sockio.h>
+#endif
+#ifdef HAVE_IFADDRS_H
+#  include <ifaddrs.h>
+#endif
+#ifdef HAVE_STROPTS_H
+#  include <stropts.h>
+#endif
+#ifdef __VMS
+#  include <inet.h>
+#endif
+
+#include "inet_ntop.h"
+#include "strcase.h"
+#include "if2ip.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* ------------------------------------------------------------------ */
+
+/* Return the scope of the given address. */
+unsigned int Curl_ipv6_scope(const struct sockaddr *sa)
+{
+#ifndef ENABLE_IPV6
+  (void) sa;
+#else
+  if(sa->sa_family == AF_INET6) {
+    const struct sockaddr_in6 * sa6 = (const struct sockaddr_in6 *)(void *) sa;
+    const unsigned char *b = sa6->sin6_addr.s6_addr;
+    unsigned short w = (unsigned short) ((b[0] << 8) | b[1]);
+
+    if((b[0] & 0xFE) == 0xFC) /* Handle ULAs */
+      return IPV6_SCOPE_UNIQUELOCAL;
+    switch(w & 0xFFC0) {
+    case 0xFE80:
+      return IPV6_SCOPE_LINKLOCAL;
+    case 0xFEC0:
+      return IPV6_SCOPE_SITELOCAL;
+    case 0x0000:
+      w = b[1] | b[2] | b[3] | b[4] | b[5] | b[6] | b[7] | b[8] | b[9] |
+          b[10] | b[11] | b[12] | b[13] | b[14];
+      if(w || b[15] != 0x01)
+        break;
+      return IPV6_SCOPE_NODELOCAL;
+    default:
+      break;
+    }
+  }
+#endif
+
+  return IPV6_SCOPE_GLOBAL;
+}
+
+
+#if defined(HAVE_GETIFADDRS)
+
+bool Curl_if_is_interface_name(const char *interf)
+{
+  bool result = FALSE;
+
+  struct ifaddrs *iface, *head;
+
+  if(getifaddrs(&head) >= 0) {
+    for(iface=head; iface != NULL; iface=iface->ifa_next) {
+      if(strcasecompare(iface->ifa_name, interf)) {
+        result = TRUE;
+        break;
+      }
+    }
+    freeifaddrs(head);
+  }
+  return result;
+}
+
+if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
+                          unsigned int remote_scope_id, const char *interf,
+                          char *buf, int buf_size)
+{
+  struct ifaddrs *iface, *head;
+  if2ip_result_t res = IF2IP_NOT_FOUND;
+
+#ifndef ENABLE_IPV6
+  (void) remote_scope;
+#endif
+
+#if !defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) || \
+    !defined(ENABLE_IPV6)
+  (void) remote_scope_id;
+#endif
+
+  if(getifaddrs(&head) >= 0) {
+    for(iface = head; iface != NULL; iface=iface->ifa_next) {
+      if(iface->ifa_addr != NULL) {
+        if(iface->ifa_addr->sa_family == af) {
+          if(strcasecompare(iface->ifa_name, interf)) {
+            void *addr;
+            char *ip;
+            char scope[12] = "";
+            char ipstr[64];
+#ifdef ENABLE_IPV6
+            if(af == AF_INET6) {
+              unsigned int scopeid = 0;
+              unsigned int ifscope = Curl_ipv6_scope(iface->ifa_addr);
+
+              if(ifscope != remote_scope) {
+                /* We are interested only in interface addresses whose
+                   scope matches the remote address we want to
+                   connect to: global for global, link-local for
+                   link-local, etc... */
+                if(res == IF2IP_NOT_FOUND) res = IF2IP_AF_NOT_SUPPORTED;
+                continue;
+              }
+
+              addr =
+                &((struct sockaddr_in6 *)(void *)iface->ifa_addr)->sin6_addr;
+#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID
+              /* Include the scope of this interface as part of the address */
+              scopeid = ((struct sockaddr_in6 *)(void *)iface->ifa_addr)
+                            ->sin6_scope_id;
+
+              /* If given, scope id should match. */
+              if(remote_scope_id && scopeid != remote_scope_id) {
+                if(res == IF2IP_NOT_FOUND)
+                  res = IF2IP_AF_NOT_SUPPORTED;
+
+                continue;
+              }
+#endif
+              if(scopeid)
+                snprintf(scope, sizeof(scope), "%%%u", scopeid);
+            }
+            else
+#endif
+              addr =
+                  &((struct sockaddr_in *)(void *)iface->ifa_addr)->sin_addr;
+            res = IF2IP_FOUND;
+            ip = (char *) Curl_inet_ntop(af, addr, ipstr, sizeof(ipstr));
+            snprintf(buf, buf_size, "%s%s", ip, scope);
+            break;
+          }
+        }
+        else if((res == IF2IP_NOT_FOUND) &&
+                strcasecompare(iface->ifa_name, interf)) {
+          res = IF2IP_AF_NOT_SUPPORTED;
+        }
+      }
+    }
+
+    freeifaddrs(head);
+  }
+
+  return res;
+}
+
+#elif defined(HAVE_IOCTL_SIOCGIFADDR)
+
+bool Curl_if_is_interface_name(const char *interf)
+{
+  /* This is here just to support the old interfaces */
+  char buf[256];
+
+  return (Curl_if2ip(AF_INET, 0 /* unused */, 0, interf, buf, sizeof(buf)) ==
+          IF2IP_NOT_FOUND) ? FALSE : TRUE;
+}
+
+if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
+                          unsigned int remote_scope_id, const char *interf,
+                          char *buf, int buf_size)
+{
+  struct ifreq req;
+  struct in_addr in;
+  struct sockaddr_in *s;
+  curl_socket_t dummy;
+  size_t len;
+
+  (void)remote_scope;
+  (void)remote_scope_id;
+
+  if(!interf || (af != AF_INET))
+    return IF2IP_NOT_FOUND;
+
+  len = strlen(interf);
+  if(len >= sizeof(req.ifr_name))
+    return IF2IP_NOT_FOUND;
+
+  dummy = socket(AF_INET, SOCK_STREAM, 0);
+  if(CURL_SOCKET_BAD == dummy)
+    return IF2IP_NOT_FOUND;
+
+  memset(&req, 0, sizeof(req));
+  memcpy(req.ifr_name, interf, len+1);
+  req.ifr_addr.sa_family = AF_INET;
+
+  if(ioctl(dummy, SIOCGIFADDR, &req) < 0) {
+    sclose(dummy);
+    /* With SIOCGIFADDR, we cannot tell the difference between an interface
+       that does not exist and an interface that has no address of the
+       correct family. Assume the interface does not exist */
+    return IF2IP_NOT_FOUND;
+  }
+
+  s = (struct sockaddr_in *)(void *)&req.ifr_addr;
+  memcpy(&in, &s->sin_addr, sizeof(in));
+  Curl_inet_ntop(s->sin_family, &in, buf, buf_size);
+
+  sclose(dummy);
+  return IF2IP_FOUND;
+}
+
+#else
+
+bool Curl_if_is_interface_name(const char *interf)
+{
+  (void) interf;
+
+  return FALSE;
+}
+
+if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
+                          unsigned int remote_scope_id, const char *interf,
+                          char *buf, int buf_size)
+{
+    (void) af;
+    (void) remote_scope;
+    (void) remote_scope_id;
+    (void) interf;
+    (void) buf;
+    (void) buf_size;
+    return IF2IP_NOT_FOUND;
+}
+
+#endif
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/if2ip.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/if2ip.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/if2ip.h	(revision 331)
@@ -0,0 +1,84 @@
+#ifndef HEADER_CURL_IF2IP_H
+#define HEADER_CURL_IF2IP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+/* IPv6 address scopes. */
+#define IPV6_SCOPE_GLOBAL       0       /* Global scope. */
+#define IPV6_SCOPE_LINKLOCAL    1       /* Link-local scope. */
+#define IPV6_SCOPE_SITELOCAL    2       /* Site-local scope (deprecated). */
+#define IPV6_SCOPE_UNIQUELOCAL  3       /* Unique local */
+#define IPV6_SCOPE_NODELOCAL    4       /* Loopback. */
+
+unsigned int Curl_ipv6_scope(const struct sockaddr *sa);
+
+bool Curl_if_is_interface_name(const char *interf);
+
+typedef enum {
+  IF2IP_NOT_FOUND = 0, /* Interface not found */
+  IF2IP_AF_NOT_SUPPORTED = 1, /* Int. exists but has no address for this af */
+  IF2IP_FOUND = 2 /* The address has been stored in "buf" */
+} if2ip_result_t;
+
+if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope,
+                          unsigned int remote_scope_id, const char *interf,
+                          char *buf, int buf_size);
+
+#ifdef __INTERIX
+
+/* Nedelcho Stanev's work-around for SFU 3.0 */
+struct ifreq {
+#define IFNAMSIZ 16
+#define IFHWADDRLEN 6
+  union {
+    char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+  } ifr_ifrn;
+
+ union {
+   struct sockaddr ifru_addr;
+   struct sockaddr ifru_broadaddr;
+   struct sockaddr ifru_netmask;
+   struct sockaddr ifru_hwaddr;
+   short ifru_flags;
+   int ifru_metric;
+   int ifru_mtu;
+ } ifr_ifru;
+};
+
+/* This define was added by Daniel to avoid an extra #ifdef INTERIX in the
+   C code. */
+
+#define ifr_name ifr_ifrn.ifrn_name /* interface name */
+#define ifr_addr ifr_ifru.ifru_addr /* address */
+#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
+#define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */
+#define ifr_flags ifr_ifru.ifru_flags /* flags */
+#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
+#define ifr_metric ifr_ifru.ifru_metric /* metric */
+#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
+
+#define SIOCGIFADDR _IOW('s', 102, struct ifreq) /* Get if addr */
+
+#endif /* __INTERIX */
+
+#endif /* HEADER_CURL_IF2IP_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/imap.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/imap.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/imap.c	(revision 331)
@@ -0,0 +1,2098 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC2195 CRAM-MD5 authentication
+ * RFC2595 Using TLS with IMAP, POP3 and ACAP
+ * RFC2831 DIGEST-MD5 authentication
+ * RFC3501 IMAPv4 protocol
+ * RFC4422 Simple Authentication and Security Layer (SASL)
+ * RFC4616 PLAIN authentication
+ * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
+ * RFC4959 IMAP Extension for SASL Initial Client Response
+ * RFC5092 IMAP URL Scheme
+ * RFC6749 OAuth 2.0 Authorization Framework
+ * Draft   LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_IMAP
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "progress.h"
+#include "transfer.h"
+#include "escape.h"
+#include "http.h" /* for HTTP proxy tunnel stuff */
+#include "socks.h"
+#include "imap.h"
+#include "mime.h"
+#include "strtoofft.h"
+#include "strcase.h"
+#include "vtls/vtls.h"
+#include "connect.h"
+#include "strerror.h"
+#include "select.h"
+#include "multiif.h"
+#include "url.h"
+#include "strcase.h"
+#include "curl_sasl.h"
+#include "warnless.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Local API functions */
+static CURLcode imap_regular_transfer(struct connectdata *conn, bool *done);
+static CURLcode imap_do(struct connectdata *conn, bool *done);
+static CURLcode imap_done(struct connectdata *conn, CURLcode status,
+                          bool premature);
+static CURLcode imap_connect(struct connectdata *conn, bool *done);
+static CURLcode imap_disconnect(struct connectdata *conn, bool dead);
+static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done);
+static int imap_getsock(struct connectdata *conn, curl_socket_t *socks,
+                        int numsocks);
+static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done);
+static CURLcode imap_setup_connection(struct connectdata *conn);
+static char *imap_atom(const char *str, bool escape_only);
+static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...);
+static CURLcode imap_parse_url_options(struct connectdata *conn);
+static CURLcode imap_parse_url_path(struct connectdata *conn);
+static CURLcode imap_parse_custom_request(struct connectdata *conn);
+static CURLcode imap_perform_authenticate(struct connectdata *conn,
+                                          const char *mech,
+                                          const char *initresp);
+static CURLcode imap_continue_authenticate(struct connectdata *conn,
+                                           const char *resp);
+static void imap_get_message(char *buffer, char **outptr);
+
+/*
+ * IMAP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_imap = {
+  "IMAP",                           /* scheme */
+  imap_setup_connection,            /* setup_connection */
+  imap_do,                          /* do_it */
+  imap_done,                        /* done */
+  ZERO_NULL,                        /* do_more */
+  imap_connect,                     /* connect_it */
+  imap_multi_statemach,             /* connecting */
+  imap_doing,                       /* doing */
+  imap_getsock,                     /* proto_getsock */
+  imap_getsock,                     /* doing_getsock */
+  ZERO_NULL,                        /* domore_getsock */
+  ZERO_NULL,                        /* perform_getsock */
+  imap_disconnect,                  /* disconnect */
+  ZERO_NULL,                        /* readwrite */
+  ZERO_NULL,                        /* connection_check */
+  PORT_IMAP,                        /* defport */
+  CURLPROTO_IMAP,                   /* protocol */
+  PROTOPT_CLOSEACTION|              /* flags */
+  PROTOPT_URLOPTIONS
+};
+
+#ifdef USE_SSL
+/*
+ * IMAPS protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_imaps = {
+  "IMAPS",                          /* scheme */
+  imap_setup_connection,            /* setup_connection */
+  imap_do,                          /* do_it */
+  imap_done,                        /* done */
+  ZERO_NULL,                        /* do_more */
+  imap_connect,                     /* connect_it */
+  imap_multi_statemach,             /* connecting */
+  imap_doing,                       /* doing */
+  imap_getsock,                     /* proto_getsock */
+  imap_getsock,                     /* doing_getsock */
+  ZERO_NULL,                        /* domore_getsock */
+  ZERO_NULL,                        /* perform_getsock */
+  imap_disconnect,                  /* disconnect */
+  ZERO_NULL,                        /* readwrite */
+  ZERO_NULL,                        /* connection_check */
+  PORT_IMAPS,                       /* defport */
+  CURLPROTO_IMAPS,                  /* protocol */
+  PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */
+};
+#endif
+
+#define IMAP_RESP_OK       1
+#define IMAP_RESP_NOT_OK   2
+#define IMAP_RESP_PREAUTH  3
+
+/* SASL parameters for the imap protocol */
+static const struct SASLproto saslimap = {
+  "imap",                     /* The service name */
+  '+',                        /* Code received when continuation is expected */
+  IMAP_RESP_OK,               /* Code to receive upon authentication success */
+  0,                          /* Maximum initial response length (no max) */
+  imap_perform_authenticate,  /* Send authentication command */
+  imap_continue_authenticate, /* Send authentication continuation */
+  imap_get_message            /* Get SASL response message */
+};
+
+
+#ifdef USE_SSL
+static void imap_to_imaps(struct connectdata *conn)
+{
+  /* Change the connection handler */
+  conn->handler = &Curl_handler_imaps;
+
+  /* Set the connection's upgraded to TLS flag */
+  conn->tls_upgraded = TRUE;
+}
+#else
+#define imap_to_imaps(x) Curl_nop_stmt
+#endif
+
+/***********************************************************************
+ *
+ * imap_matchresp()
+ *
+ * Determines whether the untagged response is related to the specified
+ * command by checking if it is in format "* <command-name> ..." or
+ * "* <number> <command-name> ...".
+ *
+ * The "* " marker is assumed to have already been checked by the caller.
+ */
+static bool imap_matchresp(const char *line, size_t len, const char *cmd)
+{
+  const char *end = line + len;
+  size_t cmd_len = strlen(cmd);
+
+  /* Skip the untagged response marker */
+  line += 2;
+
+  /* Do we have a number after the marker? */
+  if(line < end && ISDIGIT(*line)) {
+    /* Skip the number */
+    do
+      line++;
+    while(line < end && ISDIGIT(*line));
+
+    /* Do we have the space character? */
+    if(line == end || *line != ' ')
+      return FALSE;
+
+    line++;
+  }
+
+  /* Does the command name match and is it followed by a space character or at
+     the end of line? */
+  if(line + cmd_len <= end && strncasecompare(line, cmd, cmd_len) &&
+     (line[cmd_len] == ' ' || line + cmd_len + 2 == end))
+    return TRUE;
+
+  return FALSE;
+}
+
+/***********************************************************************
+ *
+ * imap_endofresp()
+ *
+ * Checks whether the given string is a valid tagged, untagged or continuation
+ * response which can be processed by the response handler.
+ */
+static bool imap_endofresp(struct connectdata *conn, char *line, size_t len,
+                           int *resp)
+{
+  struct IMAP *imap = conn->data->req.protop;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  const char *id = imapc->resptag;
+  size_t id_len = strlen(id);
+
+  /* Do we have a tagged command response? */
+  if(len >= id_len + 1 && !memcmp(id, line, id_len) && line[id_len] == ' ') {
+    line += id_len + 1;
+    len -= id_len + 1;
+
+    if(len >= 2 && !memcmp(line, "OK", 2))
+      *resp = IMAP_RESP_OK;
+    else if(len >= 7 && !memcmp(line, "PREAUTH", 7))
+      *resp = IMAP_RESP_PREAUTH;
+    else
+      *resp = IMAP_RESP_NOT_OK;
+
+    return TRUE;
+  }
+
+  /* Do we have an untagged command response? */
+  if(len >= 2 && !memcmp("* ", line, 2)) {
+    switch(imapc->state) {
+      /* States which are interested in untagged responses */
+      case IMAP_CAPABILITY:
+        if(!imap_matchresp(line, len, "CAPABILITY"))
+          return FALSE;
+        break;
+
+      case IMAP_LIST:
+        if((!imap->custom && !imap_matchresp(line, len, "LIST")) ||
+          (imap->custom && !imap_matchresp(line, len, imap->custom) &&
+           (!strcasecompare(imap->custom, "STORE") ||
+            !imap_matchresp(line, len, "FETCH")) &&
+           !strcasecompare(imap->custom, "SELECT") &&
+           !strcasecompare(imap->custom, "EXAMINE") &&
+           !strcasecompare(imap->custom, "SEARCH") &&
+           !strcasecompare(imap->custom, "EXPUNGE") &&
+           !strcasecompare(imap->custom, "LSUB") &&
+           !strcasecompare(imap->custom, "UID") &&
+           !strcasecompare(imap->custom, "NOOP")))
+          return FALSE;
+        break;
+
+      case IMAP_SELECT:
+        /* SELECT is special in that its untagged responses do not have a
+           common prefix so accept anything! */
+        break;
+
+      case IMAP_FETCH:
+        if(!imap_matchresp(line, len, "FETCH"))
+          return FALSE;
+        break;
+
+      case IMAP_SEARCH:
+        if(!imap_matchresp(line, len, "SEARCH"))
+          return FALSE;
+        break;
+
+      /* Ignore other untagged responses */
+      default:
+        return FALSE;
+    }
+
+    *resp = '*';
+    return TRUE;
+  }
+
+  /* Do we have a continuation response? This should be a + symbol followed by
+     a space and optionally some text as per RFC-3501 for the AUTHENTICATE and
+     APPEND commands and as outlined in Section 4. Examples of RFC-4959 but
+     some e-mail servers ignore this and only send a single + instead. */
+  if(imap && !imap->custom && ((len == 3 && !memcmp("+", line, 1)) ||
+     (len >= 2 && !memcmp("+ ", line, 2)))) {
+    switch(imapc->state) {
+      /* States which are interested in continuation responses */
+      case IMAP_AUTHENTICATE:
+      case IMAP_APPEND:
+        *resp = '+';
+        break;
+
+      default:
+        failf(conn->data, "Unexpected continuation response");
+        *resp = -1;
+        break;
+    }
+
+    return TRUE;
+  }
+
+  return FALSE; /* Nothing for us */
+}
+
+/***********************************************************************
+ *
+ * imap_get_message()
+ *
+ * Gets the authentication message from the response buffer.
+ */
+static void imap_get_message(char *buffer, char **outptr)
+{
+  size_t len = 0;
+  char *message = NULL;
+
+  /* Find the start of the message */
+  for(message = buffer + 2; *message == ' ' || *message == '\t'; message++)
+    ;
+
+  /* Find the end of the message */
+  for(len = strlen(message); len--;)
+    if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' &&
+        message[len] != '\t')
+      break;
+
+  /* Terminate the message */
+  if(++len) {
+    message[len] = '\0';
+  }
+
+  *outptr = message;
+}
+
+/***********************************************************************
+ *
+ * state()
+ *
+ * This is the ONLY way to change IMAP state!
+ */
+static void state(struct connectdata *conn, imapstate newstate)
+{
+  struct imap_conn *imapc = &conn->proto.imapc;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* for debug purposes */
+  static const char * const names[]={
+    "STOP",
+    "SERVERGREET",
+    "CAPABILITY",
+    "STARTTLS",
+    "UPGRADETLS",
+    "AUTHENTICATE",
+    "LOGIN",
+    "LIST",
+    "SELECT",
+    "FETCH",
+    "FETCH_FINAL",
+    "APPEND",
+    "APPEND_FINAL",
+    "SEARCH",
+    "LOGOUT",
+    /* LAST */
+  };
+
+  if(imapc->state != newstate)
+    infof(conn->data, "IMAP %p state change from %s to %s\n",
+          (void *)imapc, names[imapc->state], names[newstate]);
+#endif
+
+  imapc->state = newstate;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_capability()
+ *
+ * Sends the CAPABILITY command in order to obtain a list of server side
+ * supported capabilities.
+ */
+static CURLcode imap_perform_capability(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct imap_conn *imapc = &conn->proto.imapc;
+
+  imapc->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanisms yet */
+  imapc->sasl.authused = SASL_AUTH_NONE;  /* Clear the auth. mechanism used */
+  imapc->tls_supported = FALSE;           /* Clear the TLS capability */
+
+  /* Send the CAPABILITY command */
+  result = imap_sendf(conn, "CAPABILITY");
+
+  if(!result)
+    state(conn, IMAP_CAPABILITY);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_starttls()
+ *
+ * Sends the STARTTLS command to start the upgrade to TLS.
+ */
+static CURLcode imap_perform_starttls(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  /* Send the STARTTLS command */
+  result = imap_sendf(conn, "STARTTLS");
+
+  if(!result)
+    state(conn, IMAP_STARTTLS);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_upgrade_tls()
+ *
+ * Performs the upgrade to TLS.
+ */
+static CURLcode imap_perform_upgrade_tls(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct imap_conn *imapc = &conn->proto.imapc;
+
+  /* Start the SSL connection */
+  result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &imapc->ssldone);
+
+  if(!result) {
+    if(imapc->state != IMAP_UPGRADETLS)
+      state(conn, IMAP_UPGRADETLS);
+
+    if(imapc->ssldone) {
+      imap_to_imaps(conn);
+      result = imap_perform_capability(conn);
+    }
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_login()
+ *
+ * Sends a clear text LOGIN command to authenticate with.
+ */
+static CURLcode imap_perform_login(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  char *user;
+  char *passwd;
+
+  /* Check we have a username and password to authenticate with and end the
+     connect phase if we don't */
+  if(!conn->bits.user_passwd) {
+    state(conn, IMAP_STOP);
+
+    return result;
+  }
+
+  /* Make sure the username and password are in the correct atom format */
+  user = imap_atom(conn->user, false);
+  passwd = imap_atom(conn->passwd, false);
+
+  /* Send the LOGIN command */
+  result = imap_sendf(conn, "LOGIN %s %s", user ? user : "",
+                      passwd ? passwd : "");
+
+  free(user);
+  free(passwd);
+
+  if(!result)
+    state(conn, IMAP_LOGIN);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_authenticate()
+ *
+ * Sends an AUTHENTICATE command allowing the client to login with the given
+ * SASL authentication mechanism.
+ */
+static CURLcode imap_perform_authenticate(struct connectdata *conn,
+                                          const char *mech,
+                                          const char *initresp)
+{
+  CURLcode result = CURLE_OK;
+
+  if(initresp) {
+    /* Send the AUTHENTICATE command with the initial response */
+    result = imap_sendf(conn, "AUTHENTICATE %s %s", mech, initresp);
+  }
+  else {
+    /* Send the AUTHENTICATE command */
+    result = imap_sendf(conn, "AUTHENTICATE %s", mech);
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_continue_authenticate()
+ *
+ * Sends SASL continuation data or cancellation.
+ */
+static CURLcode imap_continue_authenticate(struct connectdata *conn,
+                                           const char *resp)
+{
+  struct imap_conn *imapc = &conn->proto.imapc;
+
+  return Curl_pp_sendf(&imapc->pp, "%s", resp);
+}
+
+/***********************************************************************
+ *
+ * imap_perform_authentication()
+ *
+ * Initiates the authentication sequence, with the appropriate SASL
+ * authentication mechanism, falling back to clear text should a common
+ * mechanism not be available between the client and server.
+ */
+static CURLcode imap_perform_authentication(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  saslprogress progress;
+
+  /* Check if already authenticated OR if there is enough data to authenticate
+     with and end the connect phase if we don't */
+  if(imapc->preauth ||
+     !Curl_sasl_can_authenticate(&imapc->sasl, conn)) {
+    state(conn, IMAP_STOP);
+    return result;
+  }
+
+  /* Calculate the SASL login details */
+  result = Curl_sasl_start(&imapc->sasl, conn, imapc->ir_supported, &progress);
+
+  if(!result) {
+    if(progress == SASL_INPROGRESS)
+      state(conn, IMAP_AUTHENTICATE);
+    else if(!imapc->login_disabled && (imapc->preftype & IMAP_TYPE_CLEARTEXT))
+      /* Perform clear text authentication */
+      result = imap_perform_login(conn);
+    else {
+      /* Other mechanisms not supported */
+      infof(conn->data, "No known authentication mechanisms supported!\n");
+      result = CURLE_LOGIN_DENIED;
+    }
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_list()
+ *
+ * Sends a LIST command or an alternative custom request.
+ */
+static CURLcode imap_perform_list(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct IMAP *imap = data->req.protop;
+  char *mailbox;
+
+  if(imap->custom)
+    /* Send the custom request */
+    result = imap_sendf(conn, "%s%s", imap->custom,
+                        imap->custom_params ? imap->custom_params : "");
+  else {
+    /* Make sure the mailbox is in the correct atom format if necessary */
+    mailbox = imap->mailbox ? imap_atom(imap->mailbox, true) : strdup("");
+    if(!mailbox)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* Send the LIST command */
+    result = imap_sendf(conn, "LIST \"%s\" *", mailbox);
+
+    free(mailbox);
+  }
+
+  if(!result)
+    state(conn, IMAP_LIST);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_select()
+ *
+ * Sends a SELECT command to ask the server to change the selected mailbox.
+ */
+static CURLcode imap_perform_select(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct IMAP *imap = data->req.protop;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  char *mailbox;
+
+  /* Invalidate old information as we are switching mailboxes */
+  Curl_safefree(imapc->mailbox);
+  Curl_safefree(imapc->mailbox_uidvalidity);
+
+  /* Check we have a mailbox */
+  if(!imap->mailbox) {
+    failf(conn->data, "Cannot SELECT without a mailbox.");
+    return CURLE_URL_MALFORMAT;
+  }
+
+  /* Make sure the mailbox is in the correct atom format */
+  mailbox = imap_atom(imap->mailbox, false);
+  if(!mailbox)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Send the SELECT command */
+  result = imap_sendf(conn, "SELECT %s", mailbox);
+
+  free(mailbox);
+
+  if(!result)
+    state(conn, IMAP_SELECT);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_fetch()
+ *
+ * Sends a FETCH command to initiate the download of a message.
+ */
+static CURLcode imap_perform_fetch(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct IMAP *imap = conn->data->req.protop;
+
+  /* Check we have a UID */
+  if(!imap->uid) {
+    failf(conn->data, "Cannot FETCH without a UID.");
+    return CURLE_URL_MALFORMAT;
+  }
+
+  /* Send the FETCH command */
+  if(imap->partial)
+    result = imap_sendf(conn, "FETCH %s BODY[%s]<%s>",
+                        imap->uid,
+                        imap->section ? imap->section : "",
+                        imap->partial);
+  else
+    result = imap_sendf(conn, "FETCH %s BODY[%s]",
+                        imap->uid,
+                        imap->section ? imap->section : "");
+
+  if(!result)
+    state(conn, IMAP_FETCH);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_append()
+ *
+ * Sends an APPEND command to initiate the upload of a message.
+ */
+static CURLcode imap_perform_append(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct IMAP *imap = data->req.protop;
+  char *mailbox;
+
+  /* Check we have a mailbox */
+  if(!imap->mailbox) {
+    failf(data, "Cannot APPEND without a mailbox.");
+    return CURLE_URL_MALFORMAT;
+  }
+
+  /* Prepare the mime data if some. */
+  if(data->set.mimepost.kind != MIMEKIND_NONE) {
+    /* Use the whole structure as data. */
+    data->set.mimepost.flags &= ~MIME_BODY_ONLY;
+
+    /* Add external headers and mime version. */
+    curl_mime_headers(&data->set.mimepost, data->set.headers, 0);
+    result = Curl_mime_prepare_headers(&data->set.mimepost, NULL,
+                                       NULL, MIMESTRATEGY_MAIL);
+
+    if(!result)
+      if(!Curl_checkheaders(conn, "Mime-Version"))
+        result = Curl_mime_add_header(&data->set.mimepost.curlheaders,
+                                      "Mime-Version: 1.0");
+
+    /* Make sure we will read the entire mime structure. */
+    if(!result)
+      result = Curl_mime_rewind(&data->set.mimepost);
+
+    if(result)
+      return result;
+
+    data->state.infilesize = Curl_mime_size(&data->set.mimepost);
+
+    /* Read from mime structure. */
+    data->state.fread_func = (curl_read_callback) Curl_mime_read;
+    data->state.in = (void *) &data->set.mimepost;
+  }
+
+  /* Check we know the size of the upload */
+  if(data->state.infilesize < 0) {
+    failf(data, "Cannot APPEND with unknown input file size\n");
+    return CURLE_UPLOAD_FAILED;
+  }
+
+  /* Make sure the mailbox is in the correct atom format */
+  mailbox = imap_atom(imap->mailbox, false);
+  if(!mailbox)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Send the APPEND command */
+  result = imap_sendf(conn, "APPEND %s (\\Seen) {%" CURL_FORMAT_CURL_OFF_T "}",
+                      mailbox, data->state.infilesize);
+
+  free(mailbox);
+
+  if(!result)
+    state(conn, IMAP_APPEND);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_search()
+ *
+ * Sends a SEARCH command.
+ */
+static CURLcode imap_perform_search(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct IMAP *imap = conn->data->req.protop;
+
+  /* Check we have a query string */
+  if(!imap->query) {
+    failf(conn->data, "Cannot SEARCH without a query string.");
+    return CURLE_URL_MALFORMAT;
+  }
+
+  /* Send the SEARCH command */
+  result = imap_sendf(conn, "SEARCH %s", imap->query);
+
+  if(!result)
+    state(conn, IMAP_SEARCH);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform_logout()
+ *
+ * Performs the logout action prior to sclose() being called.
+ */
+static CURLcode imap_perform_logout(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  /* Send the LOGOUT command */
+  result = imap_sendf(conn, "LOGOUT");
+
+  if(!result)
+    state(conn, IMAP_LOGOUT);
+
+  return result;
+}
+
+/* For the initial server greeting */
+static CURLcode imap_state_servergreet_resp(struct connectdata *conn,
+                                            int imapcode,
+                                            imapstate instate)
+{
+  struct Curl_easy *data = conn->data;
+  (void)instate; /* no use for this yet */
+
+  if(imapcode == IMAP_RESP_PREAUTH) {
+    /* PREAUTH */
+    struct imap_conn *imapc = &conn->proto.imapc;
+    imapc->preauth = TRUE;
+    infof(data, "PREAUTH connection, already authenticated!\n");
+  }
+  else if(imapcode != IMAP_RESP_OK) {
+    failf(data, "Got unexpected imap-server response");
+    return CURLE_WEIRD_SERVER_REPLY;
+  }
+
+  return imap_perform_capability(conn);
+}
+
+/* For CAPABILITY responses */
+static CURLcode imap_state_capability_resp(struct connectdata *conn,
+                                           int imapcode,
+                                           imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  const char *line = data->state.buffer;
+  size_t wordlen;
+
+  (void)instate; /* no use for this yet */
+
+  /* Do we have a untagged response? */
+  if(imapcode == '*') {
+    line += 2;
+
+    /* Loop through the data line */
+    for(;;) {
+      while(*line &&
+            (*line == ' ' || *line == '\t' ||
+              *line == '\r' || *line == '\n')) {
+
+        line++;
+      }
+
+      if(!*line)
+        break;
+
+      /* Extract the word */
+      for(wordlen = 0; line[wordlen] && line[wordlen] != ' ' &&
+            line[wordlen] != '\t' && line[wordlen] != '\r' &&
+            line[wordlen] != '\n';)
+        wordlen++;
+
+      /* Does the server support the STARTTLS capability? */
+      if(wordlen == 8 && !memcmp(line, "STARTTLS", 8))
+        imapc->tls_supported = TRUE;
+
+      /* Has the server explicitly disabled clear text authentication? */
+      else if(wordlen == 13 && !memcmp(line, "LOGINDISABLED", 13))
+        imapc->login_disabled = TRUE;
+
+      /* Does the server support the SASL-IR capability? */
+      else if(wordlen == 7 && !memcmp(line, "SASL-IR", 7))
+        imapc->ir_supported = TRUE;
+
+      /* Do we have a SASL based authentication mechanism? */
+      else if(wordlen > 5 && !memcmp(line, "AUTH=", 5)) {
+        size_t llen;
+        unsigned int mechbit;
+
+        line += 5;
+        wordlen -= 5;
+
+        /* Test the word for a matching authentication mechanism */
+        mechbit = Curl_sasl_decode_mech(line, wordlen, &llen);
+        if(mechbit && llen == wordlen)
+          imapc->sasl.authmechs |= mechbit;
+      }
+
+      line += wordlen;
+    }
+  }
+  else if(imapcode == IMAP_RESP_OK) {
+    if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
+      /* We don't have a SSL/TLS connection yet, but SSL is requested */
+      if(imapc->tls_supported)
+        /* Switch to TLS connection now */
+        result = imap_perform_starttls(conn);
+      else if(data->set.use_ssl == CURLUSESSL_TRY)
+        /* Fallback and carry on with authentication */
+        result = imap_perform_authentication(conn);
+      else {
+        failf(data, "STARTTLS not supported.");
+        result = CURLE_USE_SSL_FAILED;
+      }
+    }
+    else
+      result = imap_perform_authentication(conn);
+  }
+  else
+    result = imap_perform_authentication(conn);
+
+  return result;
+}
+
+/* For STARTTLS responses */
+static CURLcode imap_state_starttls_resp(struct connectdata *conn,
+                                         int imapcode,
+                                         imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(imapcode != IMAP_RESP_OK) {
+    if(data->set.use_ssl != CURLUSESSL_TRY) {
+      failf(data, "STARTTLS denied");
+      result = CURLE_USE_SSL_FAILED;
+    }
+    else
+      result = imap_perform_authentication(conn);
+  }
+  else
+    result = imap_perform_upgrade_tls(conn);
+
+  return result;
+}
+
+/* For SASL authentication responses */
+static CURLcode imap_state_auth_resp(struct connectdata *conn,
+                                     int imapcode,
+                                     imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  saslprogress progress;
+
+  (void)instate; /* no use for this yet */
+
+  result = Curl_sasl_continue(&imapc->sasl, conn, imapcode, &progress);
+  if(!result)
+    switch(progress) {
+    case SASL_DONE:
+      state(conn, IMAP_STOP);  /* Authenticated */
+      break;
+    case SASL_IDLE:            /* No mechanism left after cancellation */
+      if((!imapc->login_disabled) && (imapc->preftype & IMAP_TYPE_CLEARTEXT))
+        /* Perform clear text authentication */
+        result = imap_perform_login(conn);
+      else {
+        failf(data, "Authentication cancelled");
+        result = CURLE_LOGIN_DENIED;
+      }
+      break;
+    default:
+      break;
+    }
+
+  return result;
+}
+
+/* For LOGIN responses */
+static CURLcode imap_state_login_resp(struct connectdata *conn,
+                                      int imapcode,
+                                      imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(imapcode != IMAP_RESP_OK) {
+    failf(data, "Access denied. %c", imapcode);
+    result = CURLE_LOGIN_DENIED;
+  }
+  else
+    /* End of connect phase */
+    state(conn, IMAP_STOP);
+
+  return result;
+}
+
+/* For LIST and SEARCH responses */
+static CURLcode imap_state_listsearch_resp(struct connectdata *conn,
+                                           int imapcode,
+                                           imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+  char *line = conn->data->state.buffer;
+  size_t len = strlen(line);
+
+  (void)instate; /* No use for this yet */
+
+  if(imapcode == '*') {
+    /* Temporarily add the LF character back and send as body to the client */
+    line[len] = '\n';
+    result = Curl_client_write(conn, CLIENTWRITE_BODY, line, len + 1);
+    line[len] = '\0';
+  }
+  else if(imapcode != IMAP_RESP_OK)
+    result = CURLE_QUOTE_ERROR; /* TODO: Fix error code */
+  else
+    /* End of DO phase */
+    state(conn, IMAP_STOP);
+
+  return result;
+}
+
+/* For SELECT responses */
+static CURLcode imap_state_select_resp(struct connectdata *conn, int imapcode,
+                                       imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct IMAP *imap = conn->data->req.protop;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  const char *line = data->state.buffer;
+  char tmp[20];
+
+  (void)instate; /* no use for this yet */
+
+  if(imapcode == '*') {
+    /* See if this is an UIDVALIDITY response */
+    if(sscanf(line + 2, "OK [UIDVALIDITY %19[0123456789]]", tmp) == 1) {
+      Curl_safefree(imapc->mailbox_uidvalidity);
+      imapc->mailbox_uidvalidity = strdup(tmp);
+    }
+  }
+  else if(imapcode == IMAP_RESP_OK) {
+    /* Check if the UIDVALIDITY has been specified and matches */
+    if(imap->uidvalidity && imapc->mailbox_uidvalidity &&
+       !strcasecompare(imap->uidvalidity, imapc->mailbox_uidvalidity)) {
+      failf(conn->data, "Mailbox UIDVALIDITY has changed");
+      result = CURLE_REMOTE_FILE_NOT_FOUND;
+    }
+    else {
+      /* Note the currently opened mailbox on this connection */
+      imapc->mailbox = strdup(imap->mailbox);
+
+      if(imap->custom)
+        result = imap_perform_list(conn);
+      else if(imap->query)
+        result = imap_perform_search(conn);
+      else
+        result = imap_perform_fetch(conn);
+    }
+  }
+  else {
+    failf(data, "Select failed");
+    result = CURLE_LOGIN_DENIED;
+  }
+
+  return result;
+}
+
+/* For the (first line of the) FETCH responses */
+static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
+                                      imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  struct pingpong *pp = &imapc->pp;
+  const char *ptr = data->state.buffer;
+  bool parsed = FALSE;
+  curl_off_t size = 0;
+
+  (void)instate; /* no use for this yet */
+
+  if(imapcode != '*') {
+    Curl_pgrsSetDownloadSize(data, -1);
+    state(conn, IMAP_STOP);
+    return CURLE_REMOTE_FILE_NOT_FOUND; /* TODO: Fix error code */
+  }
+
+  /* Something like this is received "* 1 FETCH (BODY[TEXT] {2021}\r" so parse
+     the continuation data contained within the curly brackets */
+  while(*ptr && (*ptr != '{'))
+    ptr++;
+
+  if(*ptr == '{') {
+    char *endptr;
+    if(!curlx_strtoofft(ptr + 1, &endptr, 10, &size)) {
+      if(endptr - ptr > 1 && endptr[0] == '}' &&
+         endptr[1] == '\r' && endptr[2] == '\0')
+        parsed = TRUE;
+    }
+  }
+
+  if(parsed) {
+    infof(data, "Found %" CURL_FORMAT_CURL_OFF_TU " bytes to download\n",
+          size);
+    Curl_pgrsSetDownloadSize(data, size);
+
+    if(pp->cache) {
+      /* At this point there is a bunch of data in the header "cache" that is
+         actually body content, send it as body and then skip it. Do note
+         that there may even be additional "headers" after the body. */
+      size_t chunk = pp->cache_size;
+
+      if(chunk > (size_t)size)
+        /* The conversion from curl_off_t to size_t is always fine here */
+        chunk = (size_t)size;
+
+      if(!chunk) {
+        /* no size, we're done with the data */
+        state(conn, IMAP_STOP);
+        return CURLE_OK;
+      }
+      result = Curl_client_write(conn, CLIENTWRITE_BODY, pp->cache, chunk);
+      if(result)
+        return result;
+
+      data->req.bytecount += chunk;
+
+      infof(data, "Written %" CURL_FORMAT_CURL_OFF_TU
+            " bytes, %" CURL_FORMAT_CURL_OFF_TU
+            " bytes are left for transfer\n", (curl_off_t)chunk,
+            size - chunk);
+
+      /* Have we used the entire cache or just part of it?*/
+      if(pp->cache_size > chunk) {
+        /* Only part of it so shrink the cache to fit the trailing data */
+        memmove(pp->cache, pp->cache + chunk, pp->cache_size - chunk);
+        pp->cache_size -= chunk;
+      }
+      else {
+        /* Free the cache */
+        Curl_safefree(pp->cache);
+
+        /* Reset the cache size */
+        pp->cache_size = 0;
+      }
+    }
+
+    if(data->req.bytecount == size)
+      /* The entire data is already transferred! */
+      Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+    else {
+      /* IMAP download */
+      data->req.maxdownload = size;
+      Curl_setup_transfer(conn, FIRSTSOCKET, size, FALSE, NULL, -1, NULL);
+    }
+  }
+  else {
+    /* We don't know how to parse this line */
+    failf(pp->conn->data, "Failed to parse FETCH response.");
+    result = CURLE_WEIRD_SERVER_REPLY;
+  }
+
+  /* End of DO phase */
+  state(conn, IMAP_STOP);
+
+  return result;
+}
+
+/* For final FETCH responses performed after the download */
+static CURLcode imap_state_fetch_final_resp(struct connectdata *conn,
+                                            int imapcode,
+                                            imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+
+  (void)instate; /* No use for this yet */
+
+  if(imapcode != IMAP_RESP_OK)
+    result = CURLE_WEIRD_SERVER_REPLY;
+  else
+    /* End of DONE phase */
+    state(conn, IMAP_STOP);
+
+  return result;
+}
+
+/* For APPEND responses */
+static CURLcode imap_state_append_resp(struct connectdata *conn, int imapcode,
+                                       imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  (void)instate; /* No use for this yet */
+
+  if(imapcode != '+') {
+    result = CURLE_UPLOAD_FAILED;
+  }
+  else {
+    /* Set the progress upload size */
+    Curl_pgrsSetUploadSize(data, data->state.infilesize);
+
+    /* IMAP upload */
+    Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
+
+    /* End of DO phase */
+    state(conn, IMAP_STOP);
+  }
+
+  return result;
+}
+
+/* For final APPEND responses performed after the upload */
+static CURLcode imap_state_append_final_resp(struct connectdata *conn,
+                                             int imapcode,
+                                             imapstate instate)
+{
+  CURLcode result = CURLE_OK;
+
+  (void)instate; /* No use for this yet */
+
+  if(imapcode != IMAP_RESP_OK)
+    result = CURLE_UPLOAD_FAILED;
+  else
+    /* End of DONE phase */
+    state(conn, IMAP_STOP);
+
+  return result;
+}
+
+static CURLcode imap_statemach_act(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  int imapcode;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  struct pingpong *pp = &imapc->pp;
+  size_t nread = 0;
+
+  /* Busy upgrading the connection; right now all I/O is SSL/TLS, not IMAP */
+  if(imapc->state == IMAP_UPGRADETLS)
+    return imap_perform_upgrade_tls(conn);
+
+  /* Flush any data that needs to be sent */
+  if(pp->sendleft)
+    return Curl_pp_flushsend(pp);
+
+  do {
+    /* Read the response from the server */
+    result = Curl_pp_readresp(sock, pp, &imapcode, &nread);
+    if(result)
+      return result;
+
+    /* Was there an error parsing the response line? */
+    if(imapcode == -1)
+      return CURLE_WEIRD_SERVER_REPLY;
+
+    if(!imapcode)
+      break;
+
+    /* We have now received a full IMAP server response */
+    switch(imapc->state) {
+    case IMAP_SERVERGREET:
+      result = imap_state_servergreet_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_CAPABILITY:
+      result = imap_state_capability_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_STARTTLS:
+      result = imap_state_starttls_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_AUTHENTICATE:
+      result = imap_state_auth_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_LOGIN:
+      result = imap_state_login_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_LIST:
+      result = imap_state_listsearch_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_SELECT:
+      result = imap_state_select_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_FETCH:
+      result = imap_state_fetch_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_FETCH_FINAL:
+      result = imap_state_fetch_final_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_APPEND:
+      result = imap_state_append_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_APPEND_FINAL:
+      result = imap_state_append_final_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_SEARCH:
+      result = imap_state_listsearch_resp(conn, imapcode, imapc->state);
+      break;
+
+    case IMAP_LOGOUT:
+      /* fallthrough, just stop! */
+    default:
+      /* internal error */
+      state(conn, IMAP_STOP);
+      break;
+    }
+  } while(!result && imapc->state != IMAP_STOP && Curl_pp_moredata(pp));
+
+  return result;
+}
+
+/* Called repeatedly until done from multi.c */
+static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct imap_conn *imapc = &conn->proto.imapc;
+
+  if((conn->handler->flags & PROTOPT_SSL) && !imapc->ssldone) {
+    result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &imapc->ssldone);
+    if(result || !imapc->ssldone)
+      return result;
+  }
+
+  result = Curl_pp_statemach(&imapc->pp, FALSE);
+  *done = (imapc->state == IMAP_STOP) ? TRUE : FALSE;
+
+  return result;
+}
+
+static CURLcode imap_block_statemach(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct imap_conn *imapc = &conn->proto.imapc;
+
+  while(imapc->state != IMAP_STOP && !result)
+    result = Curl_pp_statemach(&imapc->pp, TRUE);
+
+  return result;
+}
+
+/* Allocate and initialize the struct IMAP for the current Curl_easy if
+   required */
+static CURLcode imap_init(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct IMAP *imap;
+
+  imap = data->req.protop = calloc(sizeof(struct IMAP), 1);
+  if(!imap)
+    result = CURLE_OUT_OF_MEMORY;
+
+  return result;
+}
+
+/* For the IMAP "protocol connect" and "doing" phases only */
+static int imap_getsock(struct connectdata *conn, curl_socket_t *socks,
+                        int numsocks)
+{
+  return Curl_pp_getsock(&conn->proto.imapc.pp, socks, numsocks);
+}
+
+/***********************************************************************
+ *
+ * imap_connect()
+ *
+ * This function should do everything that is to be considered a part of the
+ * connection phase.
+ *
+ * The variable 'done' points to will be TRUE if the protocol-layer connect
+ * phase is done when this function returns, or FALSE if not.
+ */
+static CURLcode imap_connect(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  struct pingpong *pp = &imapc->pp;
+
+  *done = FALSE; /* default to not done yet */
+
+  /* We always support persistent connections in IMAP */
+  connkeep(conn, "IMAP default");
+
+  /* Set the default response time-out */
+  pp->response_time = RESP_TIMEOUT;
+  pp->statemach_act = imap_statemach_act;
+  pp->endofresp = imap_endofresp;
+  pp->conn = conn;
+
+  /* Set the default preferred authentication type and mechanism */
+  imapc->preftype = IMAP_TYPE_ANY;
+  Curl_sasl_init(&imapc->sasl, &saslimap);
+
+  /* Initialise the pingpong layer */
+  Curl_pp_init(pp);
+
+  /* Parse the URL options */
+  result = imap_parse_url_options(conn);
+  if(result)
+    return result;
+
+  /* Start off waiting for the server greeting response */
+  state(conn, IMAP_SERVERGREET);
+
+  /* Start off with an response id of '*' */
+  strcpy(imapc->resptag, "*");
+
+  result = imap_multi_statemach(conn, done);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_done()
+ *
+ * The DONE function. This does what needs to be done after a single DO has
+ * performed.
+ *
+ * Input argument is already checked for validity.
+ */
+static CURLcode imap_done(struct connectdata *conn, CURLcode status,
+                          bool premature)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct IMAP *imap = data->req.protop;
+
+  (void)premature;
+
+  if(!imap)
+    return CURLE_OK;
+
+  if(status) {
+    connclose(conn, "IMAP done with bad status"); /* marked for closure */
+    result = status;         /* use the already set error code */
+  }
+  else if(!data->set.connect_only && !imap->custom &&
+          (imap->uid || data->set.upload ||
+          data->set.mimepost.kind != MIMEKIND_NONE)) {
+    /* Handle responses after FETCH or APPEND transfer has finished */
+    if(!data->set.upload && data->set.mimepost.kind == MIMEKIND_NONE)
+      state(conn, IMAP_FETCH_FINAL);
+    else {
+      /* End the APPEND command first by sending an empty line */
+      result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "");
+      if(!result)
+        state(conn, IMAP_APPEND_FINAL);
+    }
+
+    /* Run the state-machine
+
+       TODO: when the multi interface is used, this _really_ should be using
+       the imap_multi_statemach function but we have no general support for
+       non-blocking DONE operations!
+    */
+    if(!result)
+      result = imap_block_statemach(conn);
+  }
+
+  /* Cleanup our per-request based variables */
+  Curl_safefree(imap->mailbox);
+  Curl_safefree(imap->uidvalidity);
+  Curl_safefree(imap->uid);
+  Curl_safefree(imap->section);
+  Curl_safefree(imap->partial);
+  Curl_safefree(imap->query);
+  Curl_safefree(imap->custom);
+  Curl_safefree(imap->custom_params);
+
+  /* Clear the transfer mode for the next request */
+  imap->transfer = FTPTRANSFER_BODY;
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_perform()
+ *
+ * This is the actual DO function for IMAP. Fetch or append a message, or do
+ * other things according to the options previously setup.
+ */
+static CURLcode imap_perform(struct connectdata *conn, bool *connected,
+                             bool *dophase_done)
+{
+  /* This is IMAP and no proxy */
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct IMAP *imap = data->req.protop;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  bool selected = FALSE;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  if(conn->data->set.opt_no_body) {
+    /* Requested no body means no transfer */
+    imap->transfer = FTPTRANSFER_INFO;
+  }
+
+  *dophase_done = FALSE; /* not done yet */
+
+  /* Determine if the requested mailbox (with the same UIDVALIDITY if set)
+     has already been selected on this connection */
+  if(imap->mailbox && imapc->mailbox &&
+     strcasecompare(imap->mailbox, imapc->mailbox) &&
+     (!imap->uidvalidity || !imapc->mailbox_uidvalidity ||
+      strcasecompare(imap->uidvalidity, imapc->mailbox_uidvalidity)))
+    selected = TRUE;
+
+  /* Start the first command in the DO phase */
+  if(conn->data->set.upload || data->set.mimepost.kind != MIMEKIND_NONE)
+    /* APPEND can be executed directly */
+    result = imap_perform_append(conn);
+  else if(imap->custom && (selected || !imap->mailbox))
+    /* Custom command using the same mailbox or no mailbox */
+    result = imap_perform_list(conn);
+  else if(!imap->custom && selected && imap->uid)
+    /* FETCH from the same mailbox */
+    result = imap_perform_fetch(conn);
+  else if(!imap->custom && selected && imap->query)
+    /* SEARCH the current mailbox */
+    result = imap_perform_search(conn);
+  else if(imap->mailbox && !selected &&
+         (imap->custom || imap->uid || imap->query))
+    /* SELECT the mailbox */
+    result = imap_perform_select(conn);
+  else
+    /* LIST */
+    result = imap_perform_list(conn);
+
+  if(result)
+    return result;
+
+  /* Run the state-machine */
+  result = imap_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+  if(*dophase_done)
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_do()
+ *
+ * This function is registered as 'curl_do' function. It decodes the path
+ * parts etc as a wrapper to the actual DO function (imap_perform).
+ *
+ * The input argument is already checked for validity.
+ */
+static CURLcode imap_do(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+
+  *done = FALSE; /* default to false */
+
+  /* Parse the URL path */
+  result = imap_parse_url_path(conn);
+  if(result)
+    return result;
+
+  /* Parse the custom request */
+  result = imap_parse_custom_request(conn);
+  if(result)
+    return result;
+
+  result = imap_regular_transfer(conn, done);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_disconnect()
+ *
+ * Disconnect from an IMAP server. Cleanup protocol-specific per-connection
+ * resources. BLOCKING.
+ */
+static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  struct imap_conn *imapc = &conn->proto.imapc;
+
+  /* We cannot send quit unconditionally. If this connection is stale or
+     bad in any way, sending quit and waiting around here will make the
+     disconnect wait in vain and cause more problems than we need to. */
+
+  /* The IMAP session may or may not have been allocated/setup at this
+     point! */
+  if(!dead_connection && imapc->pp.conn && imapc->pp.conn->bits.protoconnstart)
+    if(!imap_perform_logout(conn))
+      (void)imap_block_statemach(conn); /* ignore errors on LOGOUT */
+
+  /* Disconnect from the server */
+  Curl_pp_disconnect(&imapc->pp);
+
+  /* Cleanup the SASL module */
+  Curl_sasl_cleanup(conn, imapc->sasl.authused);
+
+  /* Cleanup our connection based variables */
+  Curl_safefree(imapc->mailbox);
+  Curl_safefree(imapc->mailbox_uidvalidity);
+
+  return CURLE_OK;
+}
+
+/* Call this when the DO phase has completed */
+static CURLcode imap_dophase_done(struct connectdata *conn, bool connected)
+{
+  struct IMAP *imap = conn->data->req.protop;
+
+  (void)connected;
+
+  if(imap->transfer != FTPTRANSFER_BODY)
+    /* no data to transfer */
+    Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+
+  return CURLE_OK;
+}
+
+/* Called from multi.c while DOing */
+static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done)
+{
+  CURLcode result = imap_multi_statemach(conn, dophase_done);
+
+  if(result)
+    DEBUGF(infof(conn->data, "DO phase failed\n"));
+  else if(*dophase_done) {
+    result = imap_dophase_done(conn, FALSE /* not connected */);
+
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_regular_transfer()
+ *
+ * The input argument is already checked for validity.
+ *
+ * Performs all commands done before a regular transfer between a local and a
+ * remote host.
+ */
+static CURLcode imap_regular_transfer(struct connectdata *conn,
+                                      bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+  bool connected = FALSE;
+  struct Curl_easy *data = conn->data;
+
+  /* Make sure size is unknown at this point */
+  data->req.size = -1;
+
+  /* Set the progress data */
+  Curl_pgrsSetUploadCounter(data, 0);
+  Curl_pgrsSetDownloadCounter(data, 0);
+  Curl_pgrsSetUploadSize(data, -1);
+  Curl_pgrsSetDownloadSize(data, -1);
+
+  /* Carry out the perform */
+  result = imap_perform(conn, &connected, dophase_done);
+
+  /* Perform post DO phase operations if necessary */
+  if(!result && *dophase_done)
+    result = imap_dophase_done(conn, connected);
+
+  return result;
+}
+
+static CURLcode imap_setup_connection(struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+
+  /* Initialise the IMAP layer */
+  CURLcode result = imap_init(conn);
+  if(result)
+    return result;
+
+  /* Clear the TLS upgraded flag */
+  conn->tls_upgraded = FALSE;
+  data->state.path++;   /* don't include the initial slash */
+
+  return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * imap_sendf()
+ *
+ * Sends the formatted string as an IMAP command to the server.
+ *
+ * Designed to never block.
+ */
+static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...)
+{
+  CURLcode result = CURLE_OK;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  char *taggedfmt;
+  va_list ap;
+
+  DEBUGASSERT(fmt);
+
+  /* Calculate the next command ID wrapping at 3 digits */
+  imapc->cmdid = (imapc->cmdid + 1) % 1000;
+
+  /* Calculate the tag based on the connection ID and command ID */
+  snprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d",
+           'A' + curlx_sltosi(conn->connection_id % 26), imapc->cmdid);
+
+  /* Prefix the format with the tag */
+  taggedfmt = aprintf("%s %s", imapc->resptag, fmt);
+  if(!taggedfmt)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Send the data with the tag */
+  va_start(ap, fmt);
+  result = Curl_pp_vsendf(&imapc->pp, taggedfmt, ap);
+  va_end(ap);
+
+  free(taggedfmt);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_atom()
+ *
+ * Checks the input string for characters that need escaping and returns an
+ * atom ready for sending to the server.
+ *
+ * The returned string needs to be freed.
+ *
+ */
+static char *imap_atom(const char *str, bool escape_only)
+{
+  /* !checksrc! disable PARENBRACE 1 */
+  const char atom_specials[] = "(){ %*]";
+  const char *p1;
+  char *p2;
+  size_t backsp_count = 0;
+  size_t quote_count = 0;
+  bool others_exists = FALSE;
+  size_t newlen = 0;
+  char *newstr = NULL;
+
+  if(!str)
+    return NULL;
+
+  /* Look for "atom-specials", counting the backslash and quote characters as
+     these will need escapping */
+  p1 = str;
+  while(*p1) {
+    if(*p1 == '\\')
+      backsp_count++;
+    else if(*p1 == '"')
+      quote_count++;
+    else if(!escape_only) {
+      const char *p3 = atom_specials;
+
+      while(*p3 && !others_exists) {
+        if(*p1 == *p3)
+          others_exists = TRUE;
+
+        p3++;
+      }
+    }
+
+    p1++;
+  }
+
+  /* Does the input contain any "atom-special" characters? */
+  if(!backsp_count && !quote_count && !others_exists)
+    return strdup(str);
+
+  /* Calculate the new string length */
+  newlen = strlen(str) + backsp_count + quote_count + (escape_only ? 0 : 2);
+
+  /* Allocate the new string */
+  newstr = (char *) malloc((newlen + 1) * sizeof(char));
+  if(!newstr)
+    return NULL;
+
+  /* Surround the string in quotes if necessary */
+  p2 = newstr;
+  if(!escape_only) {
+    newstr[0] = '"';
+    newstr[newlen - 1] = '"';
+    p2++;
+  }
+
+  /* Copy the string, escaping backslash and quote characters along the way */
+  p1 = str;
+  while(*p1) {
+    if(*p1 == '\\' || *p1 == '"') {
+      *p2 = '\\';
+      p2++;
+    }
+
+   *p2 = *p1;
+
+    p1++;
+    p2++;
+  }
+
+  /* Terminate the string */
+  newstr[newlen] = '\0';
+
+  return newstr;
+}
+
+/***********************************************************************
+ *
+ * imap_is_bchar()
+ *
+ * Portable test of whether the specified char is a "bchar" as defined in the
+ * grammar of RFC-5092.
+ */
+static bool imap_is_bchar(char ch)
+{
+  switch(ch) {
+    /* bchar */
+    case ':': case '@': case '/':
+    /* bchar -> achar */
+    case '&': case '=':
+    /* bchar -> achar -> uchar -> unreserved */
+    case '0': case '1': case '2': case '3': case '4': case '5': case '6':
+    case '7': case '8': case '9':
+    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
+    case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
+    case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
+    case 'V': case 'W': case 'X': case 'Y': case 'Z':
+    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
+    case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
+    case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
+    case 'v': case 'w': case 'x': case 'y': case 'z':
+    case '-': case '.': case '_': case '~':
+    /* bchar -> achar -> uchar -> sub-delims-sh */
+    case '!': case '$': case '\'': case '(': case ')': case '*':
+    case '+': case ',':
+    /* bchar -> achar -> uchar -> pct-encoded */
+    case '%': /* HEXDIG chars are already included above */
+      return true;
+
+    default:
+      return false;
+  }
+}
+
+/***********************************************************************
+ *
+ * imap_parse_url_options()
+ *
+ * Parse the URL login options.
+ */
+static CURLcode imap_parse_url_options(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct imap_conn *imapc = &conn->proto.imapc;
+  const char *ptr = conn->options;
+
+  imapc->sasl.resetprefs = TRUE;
+
+  while(!result && ptr && *ptr) {
+    const char *key = ptr;
+    const char *value;
+
+    while(*ptr && *ptr != '=')
+        ptr++;
+
+    value = ptr + 1;
+
+    while(*ptr && *ptr != ';')
+      ptr++;
+
+    if(strncasecompare(key, "AUTH=", 5))
+      result = Curl_sasl_parse_url_auth_option(&imapc->sasl,
+                                               value, ptr - value);
+    else
+      result = CURLE_URL_MALFORMAT;
+
+    if(*ptr == ';')
+      ptr++;
+  }
+
+  switch(imapc->sasl.prefmech) {
+  case SASL_AUTH_NONE:
+    imapc->preftype = IMAP_TYPE_NONE;
+    break;
+  case SASL_AUTH_DEFAULT:
+    imapc->preftype = IMAP_TYPE_ANY;
+    break;
+  default:
+    imapc->preftype = IMAP_TYPE_SASL;
+    break;
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * imap_parse_url_path()
+ *
+ * Parse the URL path into separate path components.
+ *
+ */
+static CURLcode imap_parse_url_path(struct connectdata *conn)
+{
+  /* The imap struct is already initialised in imap_connect() */
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct IMAP *imap = data->req.protop;
+  const char *begin = data->state.path;
+  const char *ptr = begin;
+
+  /* See how much of the URL is a valid path and decode it */
+  while(imap_is_bchar(*ptr))
+    ptr++;
+
+  if(ptr != begin) {
+    /* Remove the trailing slash if present */
+    const char *end = ptr;
+    if(end > begin && end[-1] == '/')
+      end--;
+
+    result = Curl_urldecode(data, begin, end - begin, &imap->mailbox, NULL,
+                            TRUE);
+    if(result)
+      return result;
+  }
+  else
+    imap->mailbox = NULL;
+
+  /* There can be any number of parameters in the form ";NAME=VALUE" */
+  while(*ptr == ';') {
+    char *name;
+    char *value;
+    size_t valuelen;
+
+    /* Find the length of the name parameter */
+    begin = ++ptr;
+    while(*ptr && *ptr != '=')
+      ptr++;
+
+    if(!*ptr)
+      return CURLE_URL_MALFORMAT;
+
+    /* Decode the name parameter */
+    result = Curl_urldecode(data, begin, ptr - begin, &name, NULL, TRUE);
+    if(result)
+      return result;
+
+    /* Find the length of the value parameter */
+    begin = ++ptr;
+    while(imap_is_bchar(*ptr))
+      ptr++;
+
+    /* Decode the value parameter */
+    result = Curl_urldecode(data, begin, ptr - begin, &value, &valuelen, TRUE);
+    if(result) {
+      free(name);
+      return result;
+    }
+
+    DEBUGF(infof(conn->data, "IMAP URL parameter '%s' = '%s'\n", name, value));
+
+    /* Process the known hierarchical parameters (UIDVALIDITY, UID, SECTION and
+       PARTIAL) stripping of the trailing slash character if it is present.
+
+       Note: Unknown parameters trigger a URL_MALFORMAT error. */
+    if(strcasecompare(name, "UIDVALIDITY") && !imap->uidvalidity) {
+      if(valuelen > 0 && value[valuelen - 1] == '/')
+        value[valuelen - 1] = '\0';
+
+      imap->uidvalidity = value;
+      value = NULL;
+    }
+    else if(strcasecompare(name, "UID") && !imap->uid) {
+      if(valuelen > 0 && value[valuelen - 1] == '/')
+        value[valuelen - 1] = '\0';
+
+      imap->uid = value;
+      value = NULL;
+    }
+    else if(strcasecompare(name, "SECTION") && !imap->section) {
+      if(valuelen > 0 && value[valuelen - 1] == '/')
+        value[valuelen - 1] = '\0';
+
+      imap->section = value;
+      value = NULL;
+    }
+    else if(strcasecompare(name, "PARTIAL") && !imap->partial) {
+      if(valuelen > 0 && value[valuelen - 1] == '/')
+        value[valuelen - 1] = '\0';
+
+      imap->partial = value;
+      value = NULL;
+    }
+    else {
+      free(name);
+      free(value);
+
+      return CURLE_URL_MALFORMAT;
+    }
+
+    free(name);
+    free(value);
+  }
+
+  /* Does the URL contain a query parameter? Only valid when we have a mailbox
+     and no UID as per RFC-5092 */
+  if(imap->mailbox && !imap->uid && *ptr == '?') {
+    /* Find the length of the query parameter */
+    begin = ++ptr;
+    while(imap_is_bchar(*ptr))
+      ptr++;
+
+    /* Decode the query parameter */
+    result = Curl_urldecode(data, begin, ptr - begin, &imap->query, NULL,
+                            TRUE);
+    if(result)
+      return result;
+  }
+
+  /* Any extra stuff at the end of the URL is an error */
+  if(*ptr)
+    return CURLE_URL_MALFORMAT;
+
+  return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * imap_parse_custom_request()
+ *
+ * Parse the custom request.
+ */
+static CURLcode imap_parse_custom_request(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct IMAP *imap = data->req.protop;
+  const char *custom = data->set.str[STRING_CUSTOMREQUEST];
+
+  if(custom) {
+    /* URL decode the custom request */
+    result = Curl_urldecode(data, custom, 0, &imap->custom, NULL, TRUE);
+
+    /* Extract the parameters if specified */
+    if(!result) {
+      const char *params = imap->custom;
+
+      while(*params && *params != ' ')
+        params++;
+
+      if(*params) {
+        imap->custom_params = strdup(params);
+        imap->custom[params - imap->custom] = '\0';
+
+        if(!imap->custom_params)
+          result = CURLE_OUT_OF_MEMORY;
+      }
+    }
+  }
+
+  return result;
+}
+
+#endif /* CURL_DISABLE_IMAP */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/imap.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/imap.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/imap.h	(revision 331)
@@ -0,0 +1,97 @@
+#ifndef HEADER_CURL_IMAP_H
+#define HEADER_CURL_IMAP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2009 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "pingpong.h"
+#include "curl_sasl.h"
+
+/****************************************************************************
+ * IMAP unique setup
+ ***************************************************************************/
+typedef enum {
+  IMAP_STOP,         /* do nothing state, stops the state machine */
+  IMAP_SERVERGREET,  /* waiting for the initial greeting immediately after
+                        a connect */
+  IMAP_CAPABILITY,
+  IMAP_STARTTLS,
+  IMAP_UPGRADETLS,   /* asynchronously upgrade the connection to SSL/TLS
+                       (multi mode only) */
+  IMAP_AUTHENTICATE,
+  IMAP_LOGIN,
+  IMAP_LIST,
+  IMAP_SELECT,
+  IMAP_FETCH,
+  IMAP_FETCH_FINAL,
+  IMAP_APPEND,
+  IMAP_APPEND_FINAL,
+  IMAP_SEARCH,
+  IMAP_LOGOUT,
+  IMAP_LAST          /* never used */
+} imapstate;
+
+/* This IMAP struct is used in the Curl_easy. All IMAP data that is
+   connection-oriented must be in imap_conn to properly deal with the fact that
+   perhaps the Curl_easy is changed between the times the connection is
+   used. */
+struct IMAP {
+  curl_pp_transfer transfer;
+  char *mailbox;          /* Mailbox to select */
+  char *uidvalidity;      /* UIDVALIDITY to check in select */
+  char *uid;              /* Message UID to fetch */
+  char *section;          /* Message SECTION to fetch */
+  char *partial;          /* Message PARTIAL to fetch */
+  char *query;            /* Query to search for */
+  char *custom;           /* Custom request */
+  char *custom_params;    /* Parameters for the custom request */
+};
+
+/* imap_conn is used for struct connection-oriented data in the connectdata
+   struct */
+struct imap_conn {
+  struct pingpong pp;
+  imapstate state;            /* Always use imap.c:state() to change state! */
+  bool ssldone;               /* Is connect() over SSL done? */
+  bool preauth;               /* Is this connection PREAUTH? */
+  struct SASL sasl;           /* SASL-related parameters */
+  unsigned int preftype;      /* Preferred authentication type */
+  int cmdid;                  /* Last used command ID */
+  char resptag[5];            /* Response tag to wait for */
+  bool tls_supported;         /* StartTLS capability supported by server */
+  bool login_disabled;        /* LOGIN command disabled by server */
+  bool ir_supported;          /* Initial response supported by server */
+  char *mailbox;              /* The last selected mailbox */
+  char *mailbox_uidvalidity;  /* UIDVALIDITY parsed from select response */
+};
+
+extern const struct Curl_handler Curl_handler_imap;
+extern const struct Curl_handler Curl_handler_imaps;
+
+/* Authentication type flags */
+#define IMAP_TYPE_CLEARTEXT (1 << 0)
+#define IMAP_TYPE_SASL      (1 << 1)
+
+/* Authentication type values */
+#define IMAP_TYPE_NONE      0
+#define IMAP_TYPE_ANY       ~0U
+
+#endif /* HEADER_CURL_IMAP_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/inet_ntop.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/inet_ntop.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/inet_ntop.c	(revision 331)
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 1996-2001  Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * Original code by Paul Vixie. "curlified" by Gisle Vanem.
+ */
+
+#include "curl_setup.h"
+
+#ifndef HAVE_INET_NTOP
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include "inet_ntop.h"
+#include "curl_printf.h"
+
+#define IN6ADDRSZ       16
+#define INADDRSZ         4
+#define INT16SZ          2
+
+/*
+ * Format an IPv4 address, more or less like inet_ntoa().
+ *
+ * Returns `dst' (as a const)
+ * Note:
+ *  - uses no statics
+ *  - takes a unsigned char* not an in_addr as input
+ */
+static char *inet_ntop4 (const unsigned char *src, char *dst, size_t size)
+{
+  char tmp[sizeof "255.255.255.255"];
+  size_t len;
+
+  DEBUGASSERT(size >= 16);
+
+  tmp[0] = '\0';
+  (void)snprintf(tmp, sizeof(tmp), "%d.%d.%d.%d",
+                 ((int)((unsigned char)src[0])) & 0xff,
+                 ((int)((unsigned char)src[1])) & 0xff,
+                 ((int)((unsigned char)src[2])) & 0xff,
+                 ((int)((unsigned char)src[3])) & 0xff);
+
+  len = strlen(tmp);
+  if(len == 0 || len >= size) {
+    errno = ENOSPC;
+    return (NULL);
+  }
+  strcpy(dst, tmp);
+  return dst;
+}
+
+#ifdef ENABLE_IPV6
+/*
+ * Convert IPv6 binary address into presentation (printable) format.
+ */
+static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size)
+{
+  /*
+   * Note that int32_t and int16_t need only be "at least" large enough
+   * to contain a value of the specified size.  On some systems, like
+   * Crays, there is no such thing as an integer variable with 16 bits.
+   * Keep this in mind if you think this function should have been coded
+   * to use pointer overlays.  All the world's not a VAX.
+   */
+  char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
+  char *tp;
+  struct {
+    long base;
+    long len;
+  } best, cur;
+  unsigned long words[IN6ADDRSZ / INT16SZ];
+  int i;
+
+  /* Preprocess:
+   *  Copy the input (bytewise) array into a wordwise array.
+   *  Find the longest run of 0x00's in src[] for :: shorthanding.
+   */
+  memset(words, '\0', sizeof(words));
+  for(i = 0; i < IN6ADDRSZ; i++)
+    words[i/2] |= (src[i] << ((1 - (i % 2)) << 3));
+
+  best.base = -1;
+  cur.base  = -1;
+  best.len = 0;
+  cur.len = 0;
+
+  for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+    if(words[i] == 0) {
+      if(cur.base == -1)
+        cur.base = i, cur.len = 1;
+      else
+        cur.len++;
+    }
+    else if(cur.base != -1) {
+      if(best.base == -1 || cur.len > best.len)
+        best = cur;
+      cur.base = -1;
+    }
+  }
+  if((cur.base != -1) && (best.base == -1 || cur.len > best.len))
+    best = cur;
+  if(best.base != -1 && best.len < 2)
+    best.base = -1;
+  /* Format the result. */
+  tp = tmp;
+  for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+    /* Are we inside the best run of 0x00's? */
+    if(best.base != -1 && i >= best.base && i < (best.base + best.len)) {
+      if(i == best.base)
+        *tp++ = ':';
+      continue;
+    }
+
+    /* Are we following an initial run of 0x00s or any real hex?
+     */
+    if(i != 0)
+      *tp++ = ':';
+
+    /* Is this address an encapsulated IPv4?
+     */
+    if(i == 6 && best.base == 0 &&
+        (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
+      if(!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp))) {
+        errno = ENOSPC;
+        return (NULL);
+      }
+      tp += strlen(tp);
+      break;
+    }
+    tp += snprintf(tp, 5, "%lx", words[i]);
+  }
+
+  /* Was it a trailing run of 0x00's?
+   */
+  if(best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
+     *tp++ = ':';
+  *tp++ = '\0';
+
+  /* Check for overflow, copy, and we're done.
+   */
+  if((size_t)(tp - tmp) > size) {
+    errno = ENOSPC;
+    return (NULL);
+  }
+  strcpy(dst, tmp);
+  return dst;
+}
+#endif  /* ENABLE_IPV6 */
+
+/*
+ * Convert a network format address to presentation format.
+ *
+ * Returns pointer to presentation format address (`buf').
+ * Returns NULL on error and errno set with the specific
+ * error, EAFNOSUPPORT or ENOSPC.
+ *
+ * On Windows we store the error in the thread errno, not
+ * in the winsock error code. This is to avoid losing the
+ * actual last winsock error. So when this function returns
+ * NULL, check errno not SOCKERRNO.
+ */
+char *Curl_inet_ntop(int af, const void *src, char *buf, size_t size)
+{
+  switch(af) {
+  case AF_INET:
+    return inet_ntop4((const unsigned char *)src, buf, size);
+#ifdef ENABLE_IPV6
+  case AF_INET6:
+    return inet_ntop6((const unsigned char *)src, buf, size);
+#endif
+  default:
+    errno = EAFNOSUPPORT;
+    return NULL;
+  }
+}
+#endif  /* HAVE_INET_NTOP */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/inet_ntop.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/inet_ntop.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/inet_ntop.h	(revision 331)
@@ -0,0 +1,38 @@
+#ifndef HEADER_CURL_INET_NTOP_H
+#define HEADER_CURL_INET_NTOP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+char *Curl_inet_ntop(int af, const void *addr, char *buf, size_t size);
+
+#ifdef HAVE_INET_NTOP
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#define Curl_inet_ntop(af,addr,buf,size) \
+        inet_ntop(af, addr, buf, (curl_socklen_t)size)
+#endif
+
+#endif /* HEADER_CURL_INET_NTOP_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/inet_pton.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/inet_pton.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/inet_pton.c	(revision 331)
@@ -0,0 +1,236 @@
+/* This is from the BIND 4.9.4 release, modified to compile by itself */
+
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#include "curl_setup.h"
+
+#ifndef HAVE_INET_PTON
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include "inet_pton.h"
+
+#define IN6ADDRSZ       16
+#define INADDRSZ         4
+#define INT16SZ          2
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int      inet_pton4(const char *src, unsigned char *dst);
+#ifdef ENABLE_IPV6
+static int      inet_pton6(const char *src, unsigned char *dst);
+#endif
+
+/* int
+ * inet_pton(af, src, dst)
+ *      convert from presentation format (which usually means ASCII printable)
+ *      to network format (which is usually some kind of binary format).
+ * return:
+ *      1 if the address was valid for the specified address family
+ *      0 if the address wasn't valid (`dst' is untouched in this case)
+ *      -1 if some other error occurred (`dst' is untouched in this case, too)
+ * notice:
+ *      On Windows we store the error in the thread errno, not
+ *      in the winsock error code. This is to avoid losing the
+ *      actual last winsock error. So when this function returns
+ *      -1, check errno not SOCKERRNO.
+ * author:
+ *      Paul Vixie, 1996.
+ */
+int
+Curl_inet_pton(int af, const char *src, void *dst)
+{
+  switch(af) {
+  case AF_INET:
+    return (inet_pton4(src, (unsigned char *)dst));
+#ifdef ENABLE_IPV6
+  case AF_INET6:
+    return (inet_pton6(src, (unsigned char *)dst));
+#endif
+  default:
+    errno = EAFNOSUPPORT;
+    return (-1);
+  }
+  /* NOTREACHED */
+}
+
+/* int
+ * inet_pton4(src, dst)
+ *      like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ *      1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ *      does not touch `dst' unless it's returning 1.
+ * author:
+ *      Paul Vixie, 1996.
+ */
+static int
+inet_pton4(const char *src, unsigned char *dst)
+{
+  static const char digits[] = "0123456789";
+  int saw_digit, octets, ch;
+  unsigned char tmp[INADDRSZ], *tp;
+
+  saw_digit = 0;
+  octets = 0;
+  tp = tmp;
+  *tp = 0;
+  while((ch = *src++) != '\0') {
+    const char *pch;
+
+    pch = strchr(digits, ch);
+    if(pch) {
+      unsigned int val = *tp * 10 + (unsigned int)(pch - digits);
+
+      if(saw_digit && *tp == 0)
+        return (0);
+      if(val > 255)
+        return (0);
+      *tp = (unsigned char)val;
+      if(! saw_digit) {
+        if(++octets > 4)
+          return (0);
+        saw_digit = 1;
+      }
+    }
+    else if(ch == '.' && saw_digit) {
+      if(octets == 4)
+        return (0);
+      *++tp = 0;
+      saw_digit = 0;
+    }
+    else
+      return (0);
+  }
+  if(octets < 4)
+    return (0);
+  memcpy(dst, tmp, INADDRSZ);
+  return (1);
+}
+
+#ifdef ENABLE_IPV6
+/* int
+ * inet_pton6(src, dst)
+ *      convert presentation level address to network order binary form.
+ * return:
+ *      1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ *      (1) does not touch `dst' unless it's returning 1.
+ *      (2) :: in a full address is silently ignored.
+ * credit:
+ *      inspired by Mark Andrews.
+ * author:
+ *      Paul Vixie, 1996.
+ */
+static int
+inet_pton6(const char *src, unsigned char *dst)
+{
+  static const char xdigits_l[] = "0123456789abcdef",
+    xdigits_u[] = "0123456789ABCDEF";
+  unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
+  const char *xdigits, *curtok;
+  int ch, saw_xdigit;
+  size_t val;
+
+  memset((tp = tmp), 0, IN6ADDRSZ);
+  endp = tp + IN6ADDRSZ;
+  colonp = NULL;
+  /* Leading :: requires some special handling. */
+  if(*src == ':')
+    if(*++src != ':')
+      return (0);
+  curtok = src;
+  saw_xdigit = 0;
+  val = 0;
+  while((ch = *src++) != '\0') {
+    const char *pch;
+
+    pch = strchr((xdigits = xdigits_l), ch);
+    if(!pch)
+      pch = strchr((xdigits = xdigits_u), ch);
+    if(pch != NULL) {
+      val <<= 4;
+      val |= (pch - xdigits);
+      if(++saw_xdigit > 4)
+        return (0);
+      continue;
+    }
+    if(ch == ':') {
+      curtok = src;
+      if(!saw_xdigit) {
+        if(colonp)
+          return (0);
+        colonp = tp;
+        continue;
+      }
+      if(tp + INT16SZ > endp)
+        return (0);
+      *tp++ = (unsigned char) ((val >> 8) & 0xff);
+      *tp++ = (unsigned char) (val & 0xff);
+      saw_xdigit = 0;
+      val = 0;
+      continue;
+    }
+    if(ch == '.' && ((tp + INADDRSZ) <= endp) &&
+        inet_pton4(curtok, tp) > 0) {
+      tp += INADDRSZ;
+      saw_xdigit = 0;
+      break;    /* '\0' was seen by inet_pton4(). */
+    }
+    return (0);
+  }
+  if(saw_xdigit) {
+    if(tp + INT16SZ > endp)
+      return (0);
+    *tp++ = (unsigned char) ((val >> 8) & 0xff);
+    *tp++ = (unsigned char) (val & 0xff);
+  }
+  if(colonp != NULL) {
+    /*
+     * Since some memmove()'s erroneously fail to handle
+     * overlapping regions, we'll do the shift by hand.
+     */
+    const ssize_t n = tp - colonp;
+    ssize_t i;
+
+    if(tp == endp)
+      return (0);
+    for(i = 1; i <= n; i++) {
+      *(endp - i) = *(colonp + n - i);
+      *(colonp + n - i) = 0;
+    }
+    tp = endp;
+  }
+  if(tp != endp)
+    return (0);
+  memcpy(dst, tmp, IN6ADDRSZ);
+  return (1);
+}
+#endif /* ENABLE_IPV6 */
+
+#endif /* HAVE_INET_PTON */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/inet_pton.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/inet_pton.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/inet_pton.h	(revision 331)
@@ -0,0 +1,40 @@
+#ifndef HEADER_CURL_INET_PTON_H
+#define HEADER_CURL_INET_PTON_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+int Curl_inet_pton(int, const char *, void *);
+
+#ifdef HAVE_INET_PTON
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#elif defined(HAVE_WS2TCPIP_H)
+/* inet_pton() exists in Vista or later */
+#include <ws2tcpip.h>
+#endif
+#define Curl_inet_pton(x,y,z) inet_pton(x,y,z)
+#endif
+
+#endif /* HEADER_CURL_INET_PTON_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/krb5.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/krb5.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/krb5.c	(revision 331)
@@ -0,0 +1,342 @@
+/* GSSAPI/krb5 support for FTP - loosely based on old krb4.c
+ *
+ * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * Copyright (c) 2004 - 2016 Daniel Stenberg
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.  */
+
+#include "curl_setup.h"
+
+#if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_FTP)
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#include "urldata.h"
+#include "curl_base64.h"
+#include "ftp.h"
+#include "curl_gssapi.h"
+#include "sendf.h"
+#include "curl_sec.h"
+#include "warnless.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+static int
+krb5_init(void *app_data)
+{
+  gss_ctx_id_t *context = app_data;
+  /* Make sure our context is initialized for krb5_end. */
+  *context = GSS_C_NO_CONTEXT;
+  return 0;
+}
+
+static int
+krb5_check_prot(void *app_data, int level)
+{
+  (void)app_data; /* unused */
+  if(level == PROT_CONFIDENTIAL)
+    return -1;
+  return 0;
+}
+
+static int
+krb5_decode(void *app_data, void *buf, int len,
+            int level UNUSED_PARAM,
+            struct connectdata *conn UNUSED_PARAM)
+{
+  gss_ctx_id_t *context = app_data;
+  OM_uint32 maj, min;
+  gss_buffer_desc enc, dec;
+
+  (void)level;
+  (void)conn;
+
+  enc.value = buf;
+  enc.length = len;
+  maj = gss_unseal(&min, *context, &enc, &dec, NULL, NULL);
+  if(maj != GSS_S_COMPLETE) {
+    if(len >= 4)
+      strcpy(buf, "599 ");
+    return -1;
+  }
+
+  memcpy(buf, dec.value, dec.length);
+  len = curlx_uztosi(dec.length);
+  gss_release_buffer(&min, &dec);
+
+  return len;
+}
+
+static int
+krb5_overhead(void *app_data, int level, int len)
+{
+  /* no arguments are used */
+  (void)app_data;
+  (void)level;
+  (void)len;
+  return 0;
+}
+
+static int
+krb5_encode(void *app_data, const void *from, int length, int level, void **to)
+{
+  gss_ctx_id_t *context = app_data;
+  gss_buffer_desc dec, enc;
+  OM_uint32 maj, min;
+  int state;
+  int len;
+
+  /* NOTE that the cast is safe, neither of the krb5, gnu gss and heimdal
+   * libraries modify the input buffer in gss_seal()
+   */
+  dec.value = (void *)from;
+  dec.length = length;
+  maj = gss_seal(&min, *context,
+                 level == PROT_PRIVATE,
+                 GSS_C_QOP_DEFAULT,
+                 &dec, &state, &enc);
+
+  if(maj != GSS_S_COMPLETE)
+    return -1;
+
+  /* malloc a new buffer, in case gss_release_buffer doesn't work as
+     expected */
+  *to = malloc(enc.length);
+  if(!*to)
+    return -1;
+  memcpy(*to, enc.value, enc.length);
+  len = curlx_uztosi(enc.length);
+  gss_release_buffer(&min, &enc);
+  return len;
+}
+
+static int
+krb5_auth(void *app_data, struct connectdata *conn)
+{
+  int ret = AUTH_OK;
+  char *p;
+  const char *host = conn->host.name;
+  ssize_t nread;
+  curl_socklen_t l = sizeof(conn->local_addr);
+  struct Curl_easy *data = conn->data;
+  CURLcode result;
+  const char *service = data->set.str[STRING_SERVICE_NAME] ?
+                        data->set.str[STRING_SERVICE_NAME] :
+                        "ftp";
+  const char *srv_host = "host";
+  gss_buffer_desc input_buffer, output_buffer, _gssresp, *gssresp;
+  OM_uint32 maj, min;
+  gss_name_t gssname;
+  gss_ctx_id_t *context = app_data;
+  struct gss_channel_bindings_struct chan;
+  size_t base64_sz = 0;
+  struct sockaddr_in **remote_addr =
+    (struct sockaddr_in **)&conn->ip_addr->ai_addr;
+  char *stringp;
+
+  if(getsockname(conn->sock[FIRSTSOCKET],
+                 (struct sockaddr *)&conn->local_addr, &l) < 0)
+    perror("getsockname()");
+
+  chan.initiator_addrtype = GSS_C_AF_INET;
+  chan.initiator_address.length = l - 4;
+  chan.initiator_address.value = &conn->local_addr.sin_addr.s_addr;
+  chan.acceptor_addrtype = GSS_C_AF_INET;
+  chan.acceptor_address.length = l - 4;
+  chan.acceptor_address.value = &(*remote_addr)->sin_addr.s_addr;
+  chan.application_data.length = 0;
+  chan.application_data.value = NULL;
+
+  /* this loop will execute twice (once for service, once for host) */
+  for(;;) {
+    /* this really shouldn't be repeated here, but can't help it */
+    if(service == srv_host) {
+      result = Curl_ftpsend(conn, "AUTH GSSAPI");
+      if(result)
+        return -2;
+
+      if(Curl_GetFTPResponse(&nread, conn, NULL))
+        return -1;
+
+      if(data->state.buffer[0] != '3')
+        return -1;
+    }
+
+    stringp = aprintf("%s@%s", service, host);
+    if(!stringp)
+      return -2;
+
+    input_buffer.value = stringp;
+    input_buffer.length = strlen(stringp);
+    maj = gss_import_name(&min, &input_buffer, GSS_C_NT_HOSTBASED_SERVICE,
+                          &gssname);
+    free(stringp);
+    if(maj != GSS_S_COMPLETE) {
+      gss_release_name(&min, &gssname);
+      if(service == srv_host) {
+        Curl_failf(data, "Error importing service name %s@%s", service, host);
+        return AUTH_ERROR;
+      }
+      service = srv_host;
+      continue;
+    }
+    /* We pass NULL as |output_name_type| to avoid a leak. */
+    gss_display_name(&min, gssname, &output_buffer, NULL);
+    Curl_infof(data, "Trying against %s\n", output_buffer.value);
+    gssresp = GSS_C_NO_BUFFER;
+    *context = GSS_C_NO_CONTEXT;
+
+    do {
+      /* Release the buffer at each iteration to avoid leaking: the first time
+         we are releasing the memory from gss_display_name. The last item is
+         taken care by a final gss_release_buffer. */
+      gss_release_buffer(&min, &output_buffer);
+      ret = AUTH_OK;
+      maj = Curl_gss_init_sec_context(data,
+                                      &min,
+                                      context,
+                                      gssname,
+                                      &Curl_krb5_mech_oid,
+                                      &chan,
+                                      gssresp,
+                                      &output_buffer,
+                                      TRUE,
+                                      NULL);
+
+      if(gssresp) {
+        free(_gssresp.value);
+        gssresp = NULL;
+      }
+
+      if(GSS_ERROR(maj)) {
+        Curl_infof(data, "Error creating security context\n");
+        ret = AUTH_ERROR;
+        break;
+      }
+
+      if(output_buffer.length != 0) {
+        char *cmd;
+
+        result = Curl_base64_encode(data, (char *)output_buffer.value,
+                                    output_buffer.length, &p, &base64_sz);
+        if(result) {
+          Curl_infof(data, "base64-encoding: %s\n",
+                     curl_easy_strerror(result));
+          ret = AUTH_ERROR;
+          break;
+        }
+
+        cmd = aprintf("ADAT %s", p);
+        if(cmd)
+          result = Curl_ftpsend(conn, cmd);
+        else
+          result = CURLE_OUT_OF_MEMORY;
+
+        free(p);
+
+        if(result) {
+          ret = -2;
+          break;
+        }
+
+        if(Curl_GetFTPResponse(&nread, conn, NULL)) {
+          ret = -1;
+          break;
+        }
+
+        if(data->state.buffer[0] != '2' && data->state.buffer[0] != '3') {
+          Curl_infof(data, "Server didn't accept auth data\n");
+          ret = AUTH_ERROR;
+          break;
+        }
+
+        p = data->state.buffer + 4;
+        p = strstr(p, "ADAT=");
+        if(p) {
+          result = Curl_base64_decode(p + 5,
+                                      (unsigned char **)&_gssresp.value,
+                                      &_gssresp.length);
+          if(result) {
+            Curl_failf(data, "base64-decoding: %s",
+                       curl_easy_strerror(result));
+            ret = AUTH_CONTINUE;
+            break;
+          }
+        }
+
+        gssresp = &_gssresp;
+      }
+    } while(maj == GSS_S_CONTINUE_NEEDED);
+
+    gss_release_name(&min, &gssname);
+    gss_release_buffer(&min, &output_buffer);
+
+    if(gssresp)
+      free(_gssresp.value);
+
+    if(ret == AUTH_OK || service == srv_host)
+      return ret;
+
+    service = srv_host;
+  }
+  return ret;
+}
+
+static void krb5_end(void *app_data)
+{
+    OM_uint32 min;
+    gss_ctx_id_t *context = app_data;
+    if(*context != GSS_C_NO_CONTEXT) {
+#ifdef DEBUGBUILD
+      OM_uint32 maj =
+#endif
+      gss_delete_sec_context(&min, context, GSS_C_NO_BUFFER);
+      DEBUGASSERT(maj == GSS_S_COMPLETE);
+    }
+}
+
+struct Curl_sec_client_mech Curl_krb5_client_mech = {
+    "GSSAPI",
+    sizeof(gss_ctx_id_t),
+    krb5_init,
+    krb5_auth,
+    krb5_end,
+    krb5_check_prot,
+    krb5_overhead,
+    krb5_encode,
+    krb5_decode
+};
+
+#endif /* HAVE_GSSAPI && !CURL_DISABLE_FTP */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/ldap.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/ldap.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/ldap.c	(revision 331)
@@ -0,0 +1,1087 @@
+/***************************************************************************
+ *                      _   _ ____  _
+ *  Project         ___| | | |  _ \| |
+ *                 / __| | | | |_) | |
+ *                | (__| |_| |  _ <| |___
+ *                 \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_LDAP) && !defined(USE_OPENLDAP)
+
+/*
+ * Notice that USE_OPENLDAP is only a source code selection switch. When
+ * libcurl is built with USE_OPENLDAP defined the libcurl source code that
+ * gets compiled is the code from openldap.c, otherwise the code that gets
+ * compiled is the code from ldap.c.
+ *
+ * When USE_OPENLDAP is defined a recent version of the OpenLDAP library
+ * might be required for compilation and runtime. In order to use ancient
+ * OpenLDAP library versions, USE_OPENLDAP shall not be defined.
+ */
+
+#ifdef USE_WIN32_LDAP           /* Use Windows LDAP implementation. */
+# include <winldap.h>
+# ifndef LDAP_VENDOR_NAME
+#  error Your Platform SDK is NOT sufficient for LDAP support! \
+         Update your Platform SDK, or disable LDAP support!
+# else
+#  include <winber.h>
+# endif
+#else
+# define LDAP_DEPRECATED 1      /* Be sure ldap_init() is defined. */
+# ifdef HAVE_LBER_H
+#  include <lber.h>
+# endif
+# include <ldap.h>
+# if (defined(HAVE_LDAP_SSL) && defined(HAVE_LDAP_SSL_H))
+#  include <ldap_ssl.h>
+# endif /* HAVE_LDAP_SSL && HAVE_LDAP_SSL_H */
+#endif
+
+/* These are macros in both <wincrypt.h> (in above <winldap.h>) and typedefs
+ * in BoringSSL's <openssl/x509.h>
+ */
+#ifdef HAVE_BORINGSSL
+# undef X509_NAME
+# undef X509_CERT_PAIR
+# undef X509_EXTENSIONS
+#endif
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "sendf.h"
+#include "escape.h"
+#include "progress.h"
+#include "transfer.h"
+#include "strcase.h"
+#include "strtok.h"
+#include "curl_ldap.h"
+#include "curl_multibyte.h"
+#include "curl_base64.h"
+#include "connect.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifndef HAVE_LDAP_URL_PARSE
+
+/* Use our own implementation. */
+
+typedef struct {
+  char   *lud_host;
+  int     lud_port;
+#if defined(USE_WIN32_LDAP)
+  TCHAR  *lud_dn;
+  TCHAR **lud_attrs;
+#else
+  char   *lud_dn;
+  char  **lud_attrs;
+#endif
+  int     lud_scope;
+#if defined(USE_WIN32_LDAP)
+  TCHAR  *lud_filter;
+#else
+  char   *lud_filter;
+#endif
+  char  **lud_exts;
+  size_t    lud_attrs_dups; /* how many were dup'ed, this field is not in the
+                               "real" struct so can only be used in code
+                               without HAVE_LDAP_URL_PARSE defined */
+} CURL_LDAPURLDesc;
+
+#undef LDAPURLDesc
+#define LDAPURLDesc             CURL_LDAPURLDesc
+
+static int  _ldap_url_parse(const struct connectdata *conn,
+                            LDAPURLDesc **ludp);
+static void _ldap_free_urldesc(LDAPURLDesc *ludp);
+
+#undef ldap_free_urldesc
+#define ldap_free_urldesc       _ldap_free_urldesc
+#endif
+
+#ifdef DEBUG_LDAP
+  #define LDAP_TRACE(x)   do { \
+                            _ldap_trace("%u: ", __LINE__); \
+                            _ldap_trace x; \
+                          } WHILE_FALSE
+
+  static void _ldap_trace(const char *fmt, ...);
+#else
+  #define LDAP_TRACE(x)   Curl_nop_stmt
+#endif
+
+
+static CURLcode Curl_ldap(struct connectdata *conn, bool *done);
+
+/*
+ * LDAP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_ldap = {
+  "LDAP",                               /* scheme */
+  ZERO_NULL,                            /* setup_connection */
+  Curl_ldap,                            /* do_it */
+  ZERO_NULL,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_LDAP,                            /* defport */
+  CURLPROTO_LDAP,                       /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+
+#ifdef HAVE_LDAP_SSL
+/*
+ * LDAPS protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_ldaps = {
+  "LDAPS",                              /* scheme */
+  ZERO_NULL,                            /* setup_connection */
+  Curl_ldap,                            /* do_it */
+  ZERO_NULL,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_LDAPS,                           /* defport */
+  CURLPROTO_LDAPS,                      /* protocol */
+  PROTOPT_SSL                           /* flags */
+};
+#endif
+
+#if defined(USE_WIN32_LDAP)
+
+#if defined(USE_WINDOWS_SSPI)
+static int ldap_win_bind_auth(LDAP *server, const char *user,
+                              const char *passwd, unsigned long authflags)
+{
+  ULONG method = 0;
+  SEC_WINNT_AUTH_IDENTITY cred;
+  int rc = LDAP_AUTH_METHOD_NOT_SUPPORTED;
+
+  memset(&cred, 0, sizeof(cred));
+
+#if defined(USE_SPNEGO)
+  if(authflags & CURLAUTH_NEGOTIATE) {
+    method = LDAP_AUTH_NEGOTIATE;
+  }
+  else
+#endif
+#if defined(USE_NTLM)
+  if(authflags & CURLAUTH_NTLM) {
+    method = LDAP_AUTH_NTLM;
+  }
+  else
+#endif
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+  if(authflags & CURLAUTH_DIGEST) {
+    method = LDAP_AUTH_DIGEST;
+  }
+  else
+#endif
+  {
+    /* required anyway if one of upper preprocessor definitions enabled */
+  }
+
+  if(method && user && passwd) {
+    rc = Curl_create_sspi_identity(user, passwd, &cred);
+    if(!rc) {
+      rc = ldap_bind_s(server, NULL, (TCHAR *)&cred, method);
+      Curl_sspi_free_identity(&cred);
+    }
+  }
+  else {
+    /* proceed with current user credentials */
+    method = LDAP_AUTH_NEGOTIATE;
+    rc = ldap_bind_s(server, NULL, NULL, method);
+  }
+  return rc;
+}
+#endif /* #if defined(USE_WINDOWS_SSPI) */
+
+static int ldap_win_bind(struct connectdata *conn, LDAP *server,
+                         const char *user, const char *passwd)
+{
+  int rc = LDAP_INVALID_CREDENTIALS;
+
+  PTCHAR inuser = NULL;
+  PTCHAR inpass = NULL;
+
+  if(user && passwd && (conn->data->set.httpauth & CURLAUTH_BASIC)) {
+    inuser = Curl_convert_UTF8_to_tchar((char *) user);
+    inpass = Curl_convert_UTF8_to_tchar((char *) passwd);
+
+    rc = ldap_simple_bind_s(server, inuser, inpass);
+
+    Curl_unicodefree(inuser);
+    Curl_unicodefree(inpass);
+  }
+#if defined(USE_WINDOWS_SSPI)
+  else {
+    rc = ldap_win_bind_auth(server, user, passwd, conn->data->set.httpauth);
+  }
+#endif
+
+  return rc;
+}
+#endif /* #if defined(USE_WIN32_LDAP) */
+
+static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  int rc = 0;
+  LDAP *server = NULL;
+  LDAPURLDesc *ludp = NULL;
+  LDAPMessage *ldapmsg = NULL;
+  LDAPMessage *entryIterator;
+  int num = 0;
+  struct Curl_easy *data = conn->data;
+  int ldap_proto = LDAP_VERSION3;
+  int ldap_ssl = 0;
+  char *val_b64 = NULL;
+  size_t val_b64_sz = 0;
+  curl_off_t dlsize = 0;
+#ifdef LDAP_OPT_NETWORK_TIMEOUT
+  struct timeval ldap_timeout = {10, 0}; /* 10 sec connection/search timeout */
+#endif
+#if defined(USE_WIN32_LDAP)
+  TCHAR *host = NULL;
+#else
+  char *host = NULL;
+#endif
+  char *user = NULL;
+  char *passwd = NULL;
+
+  *done = TRUE; /* unconditionally */
+  infof(data, "LDAP local: LDAP Vendor = %s ; LDAP Version = %d\n",
+          LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION);
+  infof(data, "LDAP local: %s\n", data->change.url);
+
+#ifdef HAVE_LDAP_URL_PARSE
+  rc = ldap_url_parse(data->change.url, &ludp);
+#else
+  rc = _ldap_url_parse(conn, &ludp);
+#endif
+  if(rc != 0) {
+    failf(data, "LDAP local: %s", ldap_err2string(rc));
+    result = CURLE_LDAP_INVALID_URL;
+    goto quit;
+  }
+
+  /* Get the URL scheme (either ldap or ldaps) */
+  if(conn->given->flags & PROTOPT_SSL)
+    ldap_ssl = 1;
+  infof(data, "LDAP local: trying to establish %s connection\n",
+          ldap_ssl ? "encrypted" : "cleartext");
+
+#if defined(USE_WIN32_LDAP)
+  host = Curl_convert_UTF8_to_tchar(conn->host.name);
+  if(!host) {
+    result = CURLE_OUT_OF_MEMORY;
+
+    goto quit;
+  }
+#else
+  host = conn->host.name;
+#endif
+
+  if(conn->bits.user_passwd) {
+    user = conn->user;
+    passwd = conn->passwd;
+  }
+
+#ifdef LDAP_OPT_NETWORK_TIMEOUT
+  ldap_set_option(NULL, LDAP_OPT_NETWORK_TIMEOUT, &ldap_timeout);
+#endif
+  ldap_set_option(NULL, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
+
+  if(ldap_ssl) {
+#ifdef HAVE_LDAP_SSL
+#ifdef USE_WIN32_LDAP
+    /* Win32 LDAP SDK doesn't support insecure mode without CA! */
+    server = ldap_sslinit(host, (int)conn->port, 1);
+    ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON);
+#else
+    int ldap_option;
+    char *ldap_ca = conn->ssl_config.CAfile;
+#if defined(CURL_HAS_NOVELL_LDAPSDK)
+    rc = ldapssl_client_init(NULL, NULL);
+    if(rc != LDAP_SUCCESS) {
+      failf(data, "LDAP local: ldapssl_client_init %s", ldap_err2string(rc));
+      result = CURLE_SSL_CERTPROBLEM;
+      goto quit;
+    }
+    if(conn->ssl_config.verifypeer) {
+      /* Novell SDK supports DER or BASE64 files. */
+      int cert_type = LDAPSSL_CERT_FILETYPE_B64;
+      if((data->set.ssl.cert_type) &&
+         (strcasecompare(data->set.ssl.cert_type, "DER")))
+        cert_type = LDAPSSL_CERT_FILETYPE_DER;
+      if(!ldap_ca) {
+        failf(data, "LDAP local: ERROR %s CA cert not set!",
+              (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"));
+        result = CURLE_SSL_CERTPROBLEM;
+        goto quit;
+      }
+      infof(data, "LDAP local: using %s CA cert '%s'\n",
+              (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"),
+              ldap_ca);
+      rc = ldapssl_add_trusted_cert(ldap_ca, cert_type);
+      if(rc != LDAP_SUCCESS) {
+        failf(data, "LDAP local: ERROR setting %s CA cert: %s",
+                (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"),
+                ldap_err2string(rc));
+        result = CURLE_SSL_CERTPROBLEM;
+        goto quit;
+      }
+      ldap_option = LDAPSSL_VERIFY_SERVER;
+    }
+    else
+      ldap_option = LDAPSSL_VERIFY_NONE;
+    rc = ldapssl_set_verify_mode(ldap_option);
+    if(rc != LDAP_SUCCESS) {
+      failf(data, "LDAP local: ERROR setting cert verify mode: %s",
+              ldap_err2string(rc));
+      result = CURLE_SSL_CERTPROBLEM;
+      goto quit;
+    }
+    server = ldapssl_init(host, (int)conn->port, 1);
+    if(server == NULL) {
+      failf(data, "LDAP local: Cannot connect to %s:%ld",
+            conn->host.dispname, conn->port);
+      result = CURLE_COULDNT_CONNECT;
+      goto quit;
+    }
+#elif defined(LDAP_OPT_X_TLS)
+    if(conn->ssl_config.verifypeer) {
+      /* OpenLDAP SDK supports BASE64 files. */
+      if((data->set.ssl.cert_type) &&
+         (!strcasecompare(data->set.ssl.cert_type, "PEM"))) {
+        failf(data, "LDAP local: ERROR OpenLDAP only supports PEM cert-type!");
+        result = CURLE_SSL_CERTPROBLEM;
+        goto quit;
+      }
+      if(!ldap_ca) {
+        failf(data, "LDAP local: ERROR PEM CA cert not set!");
+        result = CURLE_SSL_CERTPROBLEM;
+        goto quit;
+      }
+      infof(data, "LDAP local: using PEM CA cert: %s\n", ldap_ca);
+      rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, ldap_ca);
+      if(rc != LDAP_SUCCESS) {
+        failf(data, "LDAP local: ERROR setting PEM CA cert: %s",
+                ldap_err2string(rc));
+        result = CURLE_SSL_CERTPROBLEM;
+        goto quit;
+      }
+      ldap_option = LDAP_OPT_X_TLS_DEMAND;
+    }
+    else
+      ldap_option = LDAP_OPT_X_TLS_NEVER;
+
+    rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &ldap_option);
+    if(rc != LDAP_SUCCESS) {
+      failf(data, "LDAP local: ERROR setting cert verify mode: %s",
+              ldap_err2string(rc));
+      result = CURLE_SSL_CERTPROBLEM;
+      goto quit;
+    }
+    server = ldap_init(host, (int)conn->port);
+    if(server == NULL) {
+      failf(data, "LDAP local: Cannot connect to %s:%ld",
+            conn->host.dispname, conn->port);
+      result = CURLE_COULDNT_CONNECT;
+      goto quit;
+    }
+    ldap_option = LDAP_OPT_X_TLS_HARD;
+    rc = ldap_set_option(server, LDAP_OPT_X_TLS, &ldap_option);
+    if(rc != LDAP_SUCCESS) {
+      failf(data, "LDAP local: ERROR setting SSL/TLS mode: %s",
+              ldap_err2string(rc));
+      result = CURLE_SSL_CERTPROBLEM;
+      goto quit;
+    }
+/*
+    rc = ldap_start_tls_s(server, NULL, NULL);
+    if(rc != LDAP_SUCCESS) {
+      failf(data, "LDAP local: ERROR starting SSL/TLS mode: %s",
+              ldap_err2string(rc));
+      result = CURLE_SSL_CERTPROBLEM;
+      goto quit;
+    }
+*/
+#else
+    /* we should probably never come up to here since configure
+       should check in first place if we can support LDAP SSL/TLS */
+    failf(data, "LDAP local: SSL/TLS not supported with this version "
+            "of the OpenLDAP toolkit\n");
+    result = CURLE_SSL_CERTPROBLEM;
+    goto quit;
+#endif
+#endif
+#endif /* CURL_LDAP_USE_SSL */
+  }
+  else {
+    server = ldap_init(host, (int)conn->port);
+    if(server == NULL) {
+      failf(data, "LDAP local: Cannot connect to %s:%ld",
+            conn->host.dispname, conn->port);
+      result = CURLE_COULDNT_CONNECT;
+      goto quit;
+    }
+  }
+#ifdef USE_WIN32_LDAP
+  ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
+#endif
+
+#ifdef USE_WIN32_LDAP
+  rc = ldap_win_bind(conn, server, user, passwd);
+#else
+  rc = ldap_simple_bind_s(server, user, passwd);
+#endif
+  if(!ldap_ssl && rc != 0) {
+    ldap_proto = LDAP_VERSION2;
+    ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
+#ifdef USE_WIN32_LDAP
+    rc = ldap_win_bind(conn, server, user, passwd);
+#else
+    rc = ldap_simple_bind_s(server, user, passwd);
+#endif
+  }
+  if(rc != 0) {
+    failf(data, "LDAP local: ldap_simple_bind_s %s", ldap_err2string(rc));
+    result = CURLE_LDAP_CANNOT_BIND;
+    goto quit;
+  }
+
+  rc = ldap_search_s(server, ludp->lud_dn, ludp->lud_scope,
+                     ludp->lud_filter, ludp->lud_attrs, 0, &ldapmsg);
+
+  if(rc != 0 && rc != LDAP_SIZELIMIT_EXCEEDED) {
+    failf(data, "LDAP remote: %s", ldap_err2string(rc));
+    result = CURLE_LDAP_SEARCH_FAILED;
+    goto quit;
+  }
+
+  for(num = 0, entryIterator = ldap_first_entry(server, ldapmsg);
+      entryIterator;
+      entryIterator = ldap_next_entry(server, entryIterator), num++) {
+    BerElement *ber = NULL;
+#if defined(USE_WIN32_LDAP)
+    TCHAR *attribute;
+#else
+    char  *attribute;       /*! suspicious that this isn't 'const' */
+#endif
+    int i;
+
+    /* Get the DN and write it to the client */
+    {
+      char *name;
+      size_t name_len;
+#if defined(USE_WIN32_LDAP)
+      TCHAR *dn = ldap_get_dn(server, entryIterator);
+      name = Curl_convert_tchar_to_UTF8(dn);
+      if(!name) {
+        ldap_memfree(dn);
+
+        result = CURLE_OUT_OF_MEMORY;
+
+        goto quit;
+      }
+#else
+      char *dn = name = ldap_get_dn(server, entryIterator);
+#endif
+      name_len = strlen(name);
+
+      result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
+      if(result) {
+#if defined(USE_WIN32_LDAP)
+        Curl_unicodefree(name);
+#endif
+        ldap_memfree(dn);
+
+        goto quit;
+      }
+
+      result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *) name,
+                                 name_len);
+      if(result) {
+#if defined(USE_WIN32_LDAP)
+        Curl_unicodefree(name);
+#endif
+        ldap_memfree(dn);
+
+        goto quit;
+      }
+
+      result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+      if(result) {
+#if defined(USE_WIN32_LDAP)
+        Curl_unicodefree(name);
+#endif
+        ldap_memfree(dn);
+
+        goto quit;
+      }
+
+      dlsize += name_len + 5;
+
+#if defined(USE_WIN32_LDAP)
+      Curl_unicodefree(name);
+#endif
+      ldap_memfree(dn);
+    }
+
+    /* Get the attributes and write them to the client */
+    for(attribute = ldap_first_attribute(server, entryIterator, &ber);
+        attribute;
+        attribute = ldap_next_attribute(server, entryIterator, ber)) {
+      BerValue **vals;
+      size_t attr_len;
+#if defined(USE_WIN32_LDAP)
+      char *attr = Curl_convert_tchar_to_UTF8(attribute);
+      if(!attr) {
+        if(ber)
+          ber_free(ber, 0);
+
+        result = CURLE_OUT_OF_MEMORY;
+
+        goto quit;
+    }
+#else
+      char *attr = attribute;
+#endif
+      attr_len = strlen(attr);
+
+      vals = ldap_get_values_len(server, entryIterator, attribute);
+      if(vals != NULL) {
+        for(i = 0; (vals[i] != NULL); i++) {
+          result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
+          if(result) {
+            ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+            Curl_unicodefree(attr);
+#endif
+            ldap_memfree(attribute);
+            if(ber)
+              ber_free(ber, 0);
+
+            goto quit;
+          }
+
+          result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                     (char *) attr, attr_len);
+          if(result) {
+            ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+            Curl_unicodefree(attr);
+#endif
+            ldap_memfree(attribute);
+            if(ber)
+              ber_free(ber, 0);
+
+            goto quit;
+          }
+
+          result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
+          if(result) {
+            ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+            Curl_unicodefree(attr);
+#endif
+            ldap_memfree(attribute);
+            if(ber)
+              ber_free(ber, 0);
+
+            goto quit;
+          }
+
+          dlsize += attr_len + 3;
+
+          if((attr_len > 7) &&
+             (strcmp(";binary", (char *) attr + (attr_len - 7)) == 0)) {
+            /* Binary attribute, encode to base64. */
+            result = Curl_base64_encode(data,
+                                        vals[i]->bv_val,
+                                        vals[i]->bv_len,
+                                        &val_b64,
+                                        &val_b64_sz);
+            if(result) {
+              ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+              Curl_unicodefree(attr);
+#endif
+              ldap_memfree(attribute);
+              if(ber)
+                ber_free(ber, 0);
+
+              goto quit;
+            }
+
+            if(val_b64_sz > 0) {
+              result = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
+                                         val_b64_sz);
+              free(val_b64);
+              if(result) {
+                ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+                Curl_unicodefree(attr);
+#endif
+                ldap_memfree(attribute);
+                if(ber)
+                  ber_free(ber, 0);
+
+                goto quit;
+              }
+
+              dlsize += val_b64_sz;
+            }
+          }
+          else {
+            result = Curl_client_write(conn, CLIENTWRITE_BODY, vals[i]->bv_val,
+                                       vals[i]->bv_len);
+            if(result) {
+              ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+              Curl_unicodefree(attr);
+#endif
+              ldap_memfree(attribute);
+              if(ber)
+                ber_free(ber, 0);
+
+              goto quit;
+            }
+
+            dlsize += vals[i]->bv_len;
+          }
+
+          result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+          if(result) {
+            ldap_value_free_len(vals);
+#if defined(USE_WIN32_LDAP)
+            Curl_unicodefree(attr);
+#endif
+            ldap_memfree(attribute);
+            if(ber)
+              ber_free(ber, 0);
+
+            goto quit;
+          }
+
+          dlsize++;
+        }
+
+        /* Free memory used to store values */
+        ldap_value_free_len(vals);
+      }
+
+      /* Free the attribute as we are done with it */
+#if defined(USE_WIN32_LDAP)
+      Curl_unicodefree(attr);
+#endif
+      ldap_memfree(attribute);
+
+      result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+      if(result)
+        goto quit;
+      dlsize++;
+      Curl_pgrsSetDownloadCounter(data, dlsize);
+    }
+
+    if(ber)
+       ber_free(ber, 0);
+  }
+
+quit:
+  if(ldapmsg) {
+    ldap_msgfree(ldapmsg);
+    LDAP_TRACE(("Received %d entries\n", num));
+  }
+  if(rc == LDAP_SIZELIMIT_EXCEEDED)
+    infof(data, "There are more than %d entries\n", num);
+  if(ludp)
+    ldap_free_urldesc(ludp);
+  if(server)
+    ldap_unbind_s(server);
+#if defined(HAVE_LDAP_SSL) && defined(CURL_HAS_NOVELL_LDAPSDK)
+  if(ldap_ssl)
+    ldapssl_client_deinit();
+#endif /* HAVE_LDAP_SSL && CURL_HAS_NOVELL_LDAPSDK */
+
+#if defined(USE_WIN32_LDAP)
+  Curl_unicodefree(host);
+#endif
+
+  /* no data to transfer */
+  Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+  connclose(conn, "LDAP connection always disable re-use");
+
+  return result;
+}
+
+#ifdef DEBUG_LDAP
+static void _ldap_trace(const char *fmt, ...)
+{
+  static int do_trace = -1;
+  va_list args;
+
+  if(do_trace == -1) {
+    const char *env = getenv("CURL_TRACE");
+    do_trace = (env && strtol(env, NULL, 10) > 0);
+  }
+  if(!do_trace)
+    return;
+
+  va_start(args, fmt);
+  vfprintf(stderr, fmt, args);
+  va_end(args);
+}
+#endif
+
+#ifndef HAVE_LDAP_URL_PARSE
+
+/*
+ * Return scope-value for a scope-string.
+ */
+static int str2scope(const char *p)
+{
+  if(strcasecompare(p, "one"))
+    return LDAP_SCOPE_ONELEVEL;
+  if(strcasecompare(p, "onetree"))
+    return LDAP_SCOPE_ONELEVEL;
+  if(strcasecompare(p, "base"))
+    return LDAP_SCOPE_BASE;
+  if(strcasecompare(p, "sub"))
+    return LDAP_SCOPE_SUBTREE;
+  if(strcasecompare(p, "subtree"))
+    return LDAP_SCOPE_SUBTREE;
+  return (-1);
+}
+
+/*
+ * Split 'str' into strings separated by commas.
+ * Note: out[] points into 'str'.
+ */
+static bool split_str(char *str, char ***out, size_t *count)
+{
+  char **res;
+  char *lasts;
+  char *s;
+  size_t  i;
+  size_t items = 1;
+
+  s = strchr(str, ',');
+  while(s) {
+    items++;
+    s = strchr(++s, ',');
+  }
+
+  res = calloc(items, sizeof(char *));
+  if(!res)
+    return FALSE;
+
+  for(i = 0, s = strtok_r(str, ",", &lasts); s && i < items;
+      s = strtok_r(NULL, ",", &lasts), i++)
+    res[i] = s;
+
+  *out = res;
+  *count = items;
+
+  return TRUE;
+}
+
+/*
+ * Break apart the pieces of an LDAP URL.
+ * Syntax:
+ *   ldap://<hostname>:<port>/<base_dn>?<attributes>?<scope>?<filter>?<ext>
+ *
+ * <hostname> already known from 'conn->host.name'.
+ * <port>     already known from 'conn->remote_port'.
+ * extract the rest from 'conn->data->state.path+1'. All fields are optional.
+ * e.g.
+ *   ldap://<hostname>:<port>/?<attributes>?<scope>?<filter>
+ * yields ludp->lud_dn = "".
+ *
+ * Defined in RFC4516 section 2.
+ */
+static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
+{
+  int rc = LDAP_SUCCESS;
+  char *path;
+  char *p;
+  char *q;
+  size_t i;
+
+  if(!conn->data ||
+     !conn->data->state.path ||
+     conn->data->state.path[0] != '/' ||
+     !checkprefix("LDAP", conn->data->change.url))
+    return LDAP_INVALID_SYNTAX;
+
+  ludp->lud_scope = LDAP_SCOPE_BASE;
+  ludp->lud_port  = conn->remote_port;
+  ludp->lud_host  = conn->host.name;
+
+  /* Duplicate the path */
+  p = path = strdup(conn->data->state.path + 1);
+  if(!path)
+    return LDAP_NO_MEMORY;
+
+  /* Parse the DN (Distinguished Name) */
+  q = strchr(p, '?');
+  if(q)
+    *q++ = '\0';
+
+  if(*p) {
+    char *dn = p;
+    char *unescaped;
+    CURLcode result;
+
+    LDAP_TRACE(("DN '%s'\n", dn));
+
+    /* Unescape the DN */
+    result = Curl_urldecode(conn->data, dn, 0, &unescaped, NULL, FALSE);
+    if(result) {
+      rc = LDAP_NO_MEMORY;
+
+      goto quit;
+    }
+
+#if defined(USE_WIN32_LDAP)
+    /* Convert the unescaped string to a tchar */
+    ludp->lud_dn = Curl_convert_UTF8_to_tchar(unescaped);
+
+    /* Free the unescaped string as we are done with it */
+    Curl_unicodefree(unescaped);
+
+    if(!ludp->lud_dn) {
+      rc = LDAP_NO_MEMORY;
+
+      goto quit;
+    }
+#else
+    ludp->lud_dn = unescaped;
+#endif
+  }
+
+  p = q;
+  if(!p)
+    goto quit;
+
+  /* Parse the attributes. skip "??" */
+  q = strchr(p, '?');
+  if(q)
+    *q++ = '\0';
+
+  if(*p) {
+    char **attributes;
+    size_t count = 0;
+
+    /* Split the string into an array of attributes */
+    if(!split_str(p, &attributes, &count)) {
+      rc = LDAP_NO_MEMORY;
+
+      goto quit;
+    }
+
+    /* Allocate our array (+1 for the NULL entry) */
+#if defined(USE_WIN32_LDAP)
+    ludp->lud_attrs = calloc(count + 1, sizeof(TCHAR *));
+#else
+    ludp->lud_attrs = calloc(count + 1, sizeof(char *));
+#endif
+    if(!ludp->lud_attrs) {
+      free(attributes);
+
+      rc = LDAP_NO_MEMORY;
+
+      goto quit;
+    }
+
+    for(i = 0; i < count; i++) {
+      char *unescaped;
+      CURLcode result;
+
+      LDAP_TRACE(("attr[%d] '%s'\n", i, attributes[i]));
+
+      /* Unescape the attribute */
+      result = Curl_urldecode(conn->data, attributes[i], 0, &unescaped, NULL,
+                              FALSE);
+      if(result) {
+        free(attributes);
+
+        rc = LDAP_NO_MEMORY;
+
+        goto quit;
+      }
+
+#if defined(USE_WIN32_LDAP)
+      /* Convert the unescaped string to a tchar */
+      ludp->lud_attrs[i] = Curl_convert_UTF8_to_tchar(unescaped);
+
+      /* Free the unescaped string as we are done with it */
+      Curl_unicodefree(unescaped);
+
+      if(!ludp->lud_attrs[i]) {
+        free(attributes);
+
+        rc = LDAP_NO_MEMORY;
+
+        goto quit;
+      }
+#else
+      ludp->lud_attrs[i] = unescaped;
+#endif
+
+      ludp->lud_attrs_dups++;
+    }
+
+    free(attributes);
+  }
+
+  p = q;
+  if(!p)
+    goto quit;
+
+  /* Parse the scope. skip "??" */
+  q = strchr(p, '?');
+  if(q)
+    *q++ = '\0';
+
+  if(*p) {
+    ludp->lud_scope = str2scope(p);
+    if(ludp->lud_scope == -1) {
+      rc = LDAP_INVALID_SYNTAX;
+
+      goto quit;
+    }
+    LDAP_TRACE(("scope %d\n", ludp->lud_scope));
+  }
+
+  p = q;
+  if(!p)
+    goto quit;
+
+  /* Parse the filter */
+  q = strchr(p, '?');
+  if(q)
+    *q++ = '\0';
+
+  if(*p) {
+    char *filter = p;
+    char *unescaped;
+    CURLcode result;
+
+    LDAP_TRACE(("filter '%s'\n", filter));
+
+    /* Unescape the filter */
+    result = Curl_urldecode(conn->data, filter, 0, &unescaped, NULL, FALSE);
+    if(result) {
+      rc = LDAP_NO_MEMORY;
+
+      goto quit;
+    }
+
+#if defined(USE_WIN32_LDAP)
+    /* Convert the unescaped string to a tchar */
+    ludp->lud_filter = Curl_convert_UTF8_to_tchar(unescaped);
+
+    /* Free the unescaped string as we are done with it */
+    Curl_unicodefree(unescaped);
+
+    if(!ludp->lud_filter) {
+      rc = LDAP_NO_MEMORY;
+
+      goto quit;
+    }
+#else
+    ludp->lud_filter = unescaped;
+#endif
+  }
+
+  p = q;
+  if(p && !*p) {
+    rc = LDAP_INVALID_SYNTAX;
+
+    goto quit;
+  }
+
+quit:
+  free(path);
+
+  return rc;
+}
+
+static int _ldap_url_parse(const struct connectdata *conn,
+                           LDAPURLDesc **ludpp)
+{
+  LDAPURLDesc *ludp = calloc(1, sizeof(*ludp));
+  int rc;
+
+  *ludpp = NULL;
+  if(!ludp)
+     return LDAP_NO_MEMORY;
+
+  rc = _ldap_url_parse2(conn, ludp);
+  if(rc != LDAP_SUCCESS) {
+    _ldap_free_urldesc(ludp);
+    ludp = NULL;
+  }
+  *ludpp = ludp;
+  return (rc);
+}
+
+static void _ldap_free_urldesc(LDAPURLDesc *ludp)
+{
+  size_t i;
+
+  if(!ludp)
+    return;
+
+  free(ludp->lud_dn);
+  free(ludp->lud_filter);
+
+  if(ludp->lud_attrs) {
+    for(i = 0; i < ludp->lud_attrs_dups; i++)
+      free(ludp->lud_attrs[i]);
+    free(ludp->lud_attrs);
+  }
+
+  free(ludp);
+}
+#endif  /* !HAVE_LDAP_URL_PARSE */
+#endif  /* !CURL_DISABLE_LDAP && !USE_OPENLDAP */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/llist.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/llist.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/llist.c	(revision 331)
@@ -0,0 +1,197 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "llist.h"
+#include "curl_memory.h"
+
+/* this must be the last include file */
+#include "memdebug.h"
+
+/*
+ * @unittest: 1300
+ */
+void
+Curl_llist_init(struct curl_llist *l, curl_llist_dtor dtor)
+{
+  l->size = 0;
+  l->dtor = dtor;
+  l->head = NULL;
+  l->tail = NULL;
+}
+
+/*
+ * Curl_llist_insert_next()
+ *
+ * Inserts a new list element after the given one 'e'. If the given existing
+ * entry is NULL and the list already has elements, the new one will be
+ * inserted first in the list.
+ *
+ * The 'ne' argument should be a pointer into the object to store.
+ *
+ * @unittest: 1300
+ */
+void
+Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e,
+                       const void *p,
+                       struct curl_llist_element *ne)
+{
+  ne->ptr = (void *) p;
+  if(list->size == 0) {
+    list->head = ne;
+    list->head->prev = NULL;
+    list->head->next = NULL;
+    list->tail = ne;
+  }
+  else {
+    /* if 'e' is NULL here, we insert the new element first in the list */
+    ne->next = e?e->next:list->head;
+    ne->prev = e;
+    if(!e) {
+      list->head->prev = ne;
+      list->head = ne;
+    }
+    else if(e->next) {
+      e->next->prev = ne;
+    }
+    else {
+      list->tail = ne;
+    }
+    if(e)
+      e->next = ne;
+  }
+
+  ++list->size;
+}
+
+/*
+ * @unittest: 1300
+ */
+void
+Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
+                  void *user)
+{
+  void *ptr;
+  if(e == NULL || list->size == 0)
+    return;
+
+  if(e == list->head) {
+    list->head = e->next;
+
+    if(list->head == NULL)
+      list->tail = NULL;
+    else
+      e->next->prev = NULL;
+  }
+  else {
+    if(!e->prev)
+      list->head = e->next;
+    else
+      e->prev->next = e->next;
+
+    if(!e->next)
+      list->tail = e->prev;
+    else
+      e->next->prev = e->prev;
+  }
+
+  ptr = e->ptr;
+
+  e->ptr  = NULL;
+  e->prev = NULL;
+  e->next = NULL;
+
+  --list->size;
+
+  /* call the dtor() last for when it actually frees the 'e' memory itself */
+  if(list->dtor)
+    list->dtor(user, ptr);
+}
+
+void
+Curl_llist_destroy(struct curl_llist *list, void *user)
+{
+  if(list) {
+    while(list->size > 0)
+      Curl_llist_remove(list, list->tail, user);
+  }
+}
+
+size_t
+Curl_llist_count(struct curl_llist *list)
+{
+  return list->size;
+}
+
+/*
+ * @unittest: 1300
+ */
+void Curl_llist_move(struct curl_llist *list, struct curl_llist_element *e,
+                     struct curl_llist *to_list,
+                     struct curl_llist_element *to_e)
+{
+  /* Remove element from list */
+  if(e == NULL || list->size == 0)
+    return;
+
+  if(e == list->head) {
+    list->head = e->next;
+
+    if(list->head == NULL)
+      list->tail = NULL;
+    else
+      e->next->prev = NULL;
+  }
+  else {
+    e->prev->next = e->next;
+    if(!e->next)
+      list->tail = e->prev;
+    else
+      e->next->prev = e->prev;
+  }
+
+  --list->size;
+
+  /* Add element to to_list after to_e */
+  if(to_list->size == 0) {
+    to_list->head = e;
+    to_list->head->prev = NULL;
+    to_list->head->next = NULL;
+    to_list->tail = e;
+  }
+  else {
+    e->next = to_e->next;
+    e->prev = to_e;
+    if(to_e->next) {
+      to_e->next->prev = e;
+    }
+    else {
+      to_list->tail = e;
+    }
+    to_e->next = e;
+  }
+
+  ++to_list->size;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/llist.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/llist.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/llist.h	(revision 331)
@@ -0,0 +1,54 @@
+#ifndef HEADER_CURL_LLIST_H
+#define HEADER_CURL_LLIST_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include <stddef.h>
+
+typedef void (*curl_llist_dtor)(void *, void *);
+
+struct curl_llist_element {
+  void *ptr;
+  struct curl_llist_element *prev;
+  struct curl_llist_element *next;
+};
+
+struct curl_llist {
+  struct curl_llist_element *head;
+  struct curl_llist_element *tail;
+  curl_llist_dtor dtor;
+  size_t size;
+};
+
+void Curl_llist_init(struct curl_llist *, curl_llist_dtor);
+void Curl_llist_insert_next(struct curl_llist *, struct curl_llist_element *,
+                            const void *, struct curl_llist_element *node);
+void Curl_llist_remove(struct curl_llist *, struct curl_llist_element *,
+                       void *);
+size_t Curl_llist_count(struct curl_llist *);
+void Curl_llist_destroy(struct curl_llist *, void *);
+void Curl_llist_move(struct curl_llist *, struct curl_llist_element *,
+                     struct curl_llist *, struct curl_llist_element *);
+
+#endif /* HEADER_CURL_LLIST_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/md4.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/md4.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/md4.c	(revision 331)
@@ -0,0 +1,307 @@
+/*
+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
+ * MD4 Message-Digest Algorithm (RFC 1320).
+ *
+ * Homepage:
+ http://openwall.info/wiki/people/solar/software/public-domain-source-code/md4
+ *
+ * Author:
+ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
+ *
+ * This software was written by Alexander Peslyak in 2001.  No copyright is
+ * claimed, and the software is hereby placed in the public domain.  In case
+ * this attempt to disclaim copyright and place the software in the public
+ * domain is deemed null and void, then the software is Copyright (c) 2001
+ * Alexander Peslyak and it is hereby released to the general public under the
+ * following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * (This is a heavily cut-down "BSD license".)
+ *
+ * This differs from Colin Plumb's older public domain implementation in that
+ * no exactly 32-bit integer data type is required (any 32-bit or wider
+ * unsigned integer data type will do), there's no compile-time endianness
+ * configuration, and the function prototypes match OpenSSL's.  No code from
+ * Colin Plumb's implementation has been reused; this comment merely compares
+ * the properties of the two independent implementations.
+ *
+ * The primary goals of this implementation are portability and ease of use.
+ * It is meant to be fast, but not as fast as possible.  Some known
+ * optimizations are not included to reduce source code size and avoid
+ * compile-time configuration.
+ */
+
+#include "curl_setup.h"
+
+/* The NSS, OS/400 and sometimes mbed TLS crypto libraries do not provide the
+ * MD4 hash algorithm, so we have a local implementation of it */
+#if defined(USE_NSS) || defined(USE_OS400CRYPTO) || \
+    (defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C))
+
+#include "curl_md4.h"
+#include "warnless.h"
+
+#ifndef HAVE_OPENSSL
+
+#include <string.h>
+
+/* Any 32-bit or wider unsigned integer data type will do */
+typedef unsigned int MD4_u32plus;
+
+typedef struct {
+  MD4_u32plus lo, hi;
+  MD4_u32plus a, b, c, d;
+  unsigned char buffer[64];
+  MD4_u32plus block[16];
+} MD4_CTX;
+
+static void MD4_Init(MD4_CTX *ctx);
+static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size);
+static void MD4_Final(unsigned char *result, MD4_CTX *ctx);
+
+/*
+ * The basic MD4 functions.
+ *
+ * F and G are optimized compared to their RFC 1320 definitions, with the
+ * optimization for F borrowed from Colin Plumb's MD5 implementation.
+ */
+#define F(x, y, z)                      ((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z)                      (((x) & ((y) | (z))) | ((y) & (z)))
+#define H(x, y, z)                      ((x) ^ (y) ^ (z))
+
+/*
+ * The MD4 transformation for all three rounds.
+ */
+#define STEP(f, a, b, c, d, x, s) \
+        (a) += f((b), (c), (d)) + (x); \
+        (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s))));
+
+/*
+ * SET reads 4 input bytes in little-endian byte order and stores them
+ * in a properly aligned word in host byte order.
+ *
+ * The check for little-endian architectures that tolerate unaligned
+ * memory accesses is just an optimization.  Nothing will break if it
+ * doesn't work.
+ */
+#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
+#define SET(n) \
+        (*(MD4_u32plus *)(void *)&ptr[(n) * 4])
+#define GET(n) \
+        SET(n)
+#else
+#define SET(n) \
+        (ctx->block[(n)] = \
+        (MD4_u32plus)ptr[(n) * 4] | \
+        ((MD4_u32plus)ptr[(n) * 4 + 1] << 8) | \
+        ((MD4_u32plus)ptr[(n) * 4 + 2] << 16) | \
+        ((MD4_u32plus)ptr[(n) * 4 + 3] << 24))
+#define GET(n) \
+        (ctx->block[(n)])
+#endif
+
+/*
+ * This processes one or more 64-byte data blocks, but does NOT update
+ * the bit counters.  There are no alignment requirements.
+ */
+static const void *body(MD4_CTX *ctx, const void *data, unsigned long size)
+{
+  const unsigned char *ptr;
+  MD4_u32plus a, b, c, d;
+  MD4_u32plus saved_a, saved_b, saved_c, saved_d;
+
+  ptr = (const unsigned char *)data;
+
+  a = ctx->a;
+  b = ctx->b;
+  c = ctx->c;
+  d = ctx->d;
+
+  do {
+    saved_a = a;
+    saved_b = b;
+    saved_c = c;
+    saved_d = d;
+
+/* Round 1 */
+    STEP(F, a, b, c, d, SET(0), 3)
+      STEP(F, d, a, b, c, SET(1), 7)
+      STEP(F, c, d, a, b, SET(2), 11)
+      STEP(F, b, c, d, a, SET(3), 19)
+      STEP(F, a, b, c, d, SET(4), 3)
+      STEP(F, d, a, b, c, SET(5), 7)
+      STEP(F, c, d, a, b, SET(6), 11)
+      STEP(F, b, c, d, a, SET(7), 19)
+      STEP(F, a, b, c, d, SET(8), 3)
+      STEP(F, d, a, b, c, SET(9), 7)
+      STEP(F, c, d, a, b, SET(10), 11)
+      STEP(F, b, c, d, a, SET(11), 19)
+      STEP(F, a, b, c, d, SET(12), 3)
+      STEP(F, d, a, b, c, SET(13), 7)
+      STEP(F, c, d, a, b, SET(14), 11)
+      STEP(F, b, c, d, a, SET(15), 19)
+
+/* Round 2 */
+      STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3)
+      STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5)
+      STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9)
+      STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13)
+      STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3)
+      STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5)
+      STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9)
+      STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13)
+      STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3)
+      STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5)
+      STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9)
+      STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13)
+      STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3)
+      STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5)
+      STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9)
+      STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13)
+
+/* Round 3 */
+      STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3)
+      STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9)
+      STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11)
+      STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15)
+      STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3)
+      STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9)
+      STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11)
+      STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15)
+      STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3)
+      STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9)
+      STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11)
+      STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15)
+      STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3)
+      STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9)
+      STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11)
+      STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15)
+
+      a += saved_a;
+    b += saved_b;
+    c += saved_c;
+    d += saved_d;
+
+    ptr += 64;
+  } while(size -= 64);
+
+  ctx->a = a;
+  ctx->b = b;
+  ctx->c = c;
+  ctx->d = d;
+
+  return ptr;
+}
+
+static void MD4_Init(MD4_CTX *ctx)
+{
+  ctx->a = 0x67452301;
+  ctx->b = 0xefcdab89;
+  ctx->c = 0x98badcfe;
+  ctx->d = 0x10325476;
+
+  ctx->lo = 0;
+  ctx->hi = 0;
+}
+
+static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
+{
+  MD4_u32plus saved_lo;
+  unsigned long used, available;
+
+  saved_lo = ctx->lo;
+  ctx->lo = (saved_lo + size) & 0x1fffffff;
+  if(ctx->lo < saved_lo)
+    ctx->hi++;
+  ctx->hi += (MD4_u32plus)size >> 29;
+
+  used = saved_lo & 0x3f;
+
+  if(used) {
+    available = 64 - used;
+
+    if(size < available) {
+      memcpy(&ctx->buffer[used], data, size);
+      return;
+    }
+
+    memcpy(&ctx->buffer[used], data, available);
+    data = (const unsigned char *)data + available;
+    size -= available;
+    body(ctx, ctx->buffer, 64);
+  }
+
+  if(size >= 64) {
+    data = body(ctx, data, size & ~(unsigned long)0x3f);
+    size &= 0x3f;
+  }
+
+  memcpy(ctx->buffer, data, size);
+}
+
+static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
+{
+  unsigned long used, available;
+
+  used = ctx->lo & 0x3f;
+
+  ctx->buffer[used++] = 0x80;
+
+  available = 64 - used;
+
+  if(available < 8) {
+    memset(&ctx->buffer[used], 0, available);
+    body(ctx, ctx->buffer, 64);
+    used = 0;
+    available = 64;
+  }
+
+  memset(&ctx->buffer[used], 0, available - 8);
+
+  ctx->lo <<= 3;
+  ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
+  ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
+  ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
+  ctx->buffer[59] = curlx_ultouc((ctx->lo >> 24)&0xff);
+  ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
+  ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
+  ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
+  ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
+
+  body(ctx, ctx->buffer, 64);
+
+  result[0] = curlx_ultouc((ctx->a)&0xff);
+  result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
+  result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
+  result[3] = curlx_ultouc(ctx->a >> 24);
+  result[4] = curlx_ultouc((ctx->b)&0xff);
+  result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
+  result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
+  result[7] = curlx_ultouc(ctx->b >> 24);
+  result[8] = curlx_ultouc((ctx->c)&0xff);
+  result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
+  result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
+  result[11] = curlx_ultouc(ctx->c >> 24);
+  result[12] = curlx_ultouc((ctx->d)&0xff);
+  result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
+  result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
+  result[15] = curlx_ultouc(ctx->d >> 24);
+
+  memset(ctx, 0, sizeof(*ctx));
+}
+
+#endif
+
+void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len)
+{
+  MD4_CTX ctx;
+  MD4_Init(&ctx);
+  MD4_Update(&ctx, input, curlx_uztoui(len));
+  MD4_Final(output, &ctx);
+}
+#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) ||
+    (defined(USE_MBEDTLS) && !defined(MBEDTLS_MD4_C)) */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/md5.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/md5.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/md5.c	(revision 331)
@@ -0,0 +1,563 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+
+#include <curl/curl.h>
+
+#include "curl_md5.h"
+#include "curl_hmac.h"
+#include "warnless.h"
+
+#if defined(USE_GNUTLS_NETTLE)
+
+#include <nettle/md5.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef struct md5_ctx MD5_CTX;
+
+static void MD5_Init(MD5_CTX * ctx)
+{
+  md5_init(ctx);
+}
+
+static void MD5_Update(MD5_CTX * ctx,
+                       const unsigned char *input,
+                       unsigned int inputLen)
+{
+  md5_update(ctx, inputLen, input);
+}
+
+static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
+{
+  md5_digest(ctx, 16, digest);
+}
+
+#elif defined(USE_GNUTLS)
+
+#include <gcrypt.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef gcry_md_hd_t MD5_CTX;
+
+static void MD5_Init(MD5_CTX * ctx)
+{
+  gcry_md_open(ctx, GCRY_MD_MD5, 0);
+}
+
+static void MD5_Update(MD5_CTX * ctx,
+                       const unsigned char *input,
+                       unsigned int inputLen)
+{
+  gcry_md_write(*ctx, input, inputLen);
+}
+
+static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx)
+{
+  memcpy(digest, gcry_md_read(*ctx, 0), 16);
+  gcry_md_close(*ctx);
+}
+
+#elif defined(USE_OPENSSL)
+/* When OpenSSL is available we use the MD5-function from OpenSSL */
+#include <openssl/md5.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
+              (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
+      (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
+              (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
+
+/* For Apple operating systems: CommonCrypto has the functions we need.
+   These functions are available on Tiger and later, as well as iOS 2.0
+   and later. If you're building for an older cat, well, sorry.
+
+   Declaring the functions as static like this seems to be a bit more
+   reliable than defining COMMON_DIGEST_FOR_OPENSSL on older cats. */
+#  include <CommonCrypto/CommonDigest.h>
+#  define MD5_CTX CC_MD5_CTX
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+static void MD5_Init(MD5_CTX *ctx)
+{
+  CC_MD5_Init(ctx);
+}
+
+static void MD5_Update(MD5_CTX *ctx,
+                       const unsigned char *input,
+                       unsigned int inputLen)
+{
+  CC_MD5_Update(ctx, input, inputLen);
+}
+
+static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
+{
+  CC_MD5_Final(digest, ctx);
+}
+
+#elif defined(_WIN32) && !defined(CURL_WINDOWS_APP)
+
+#include <wincrypt.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef struct {
+  HCRYPTPROV hCryptProv;
+  HCRYPTHASH hHash;
+} MD5_CTX;
+
+static void MD5_Init(MD5_CTX *ctx)
+{
+  if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
+                         PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
+    CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash);
+  }
+}
+
+static void MD5_Update(MD5_CTX *ctx,
+                       const unsigned char *input,
+                       unsigned int inputLen)
+{
+  CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
+}
+
+static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
+{
+  unsigned long length = 0;
+  CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
+  if(length == 16)
+    CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0);
+  if(ctx->hHash)
+    CryptDestroyHash(ctx->hHash);
+  if(ctx->hCryptProv)
+    CryptReleaseContext(ctx->hCryptProv, 0);
+}
+
+#elif defined(USE_AXTLS)
+#include <axTLS/config.h>
+#include <axTLS/os_int.h>
+#include <axTLS/crypto.h>
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+#else
+/* When no other crypto library is available we use this code segment */
+/*
+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
+ * MD5 Message-Digest Algorithm (RFC 1321).
+ *
+ * Homepage:
+ http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
+ *
+ * Author:
+ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
+ *
+ * This software was written by Alexander Peslyak in 2001.  No copyright is
+ * claimed, and the software is hereby placed in the public domain.
+ * In case this attempt to disclaim copyright and place the software in the
+ * public domain is deemed null and void, then the software is
+ * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
+ * general public under the following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * (This is a heavily cut-down "BSD license".)
+ *
+ * This differs from Colin Plumb's older public domain implementation in that
+ * no exactly 32-bit integer data type is required (any 32-bit or wider
+ * unsigned integer data type will do), there's no compile-time endianness
+ * configuration, and the function prototypes match OpenSSL's.  No code from
+ * Colin Plumb's implementation has been reused; this comment merely compares
+ * the properties of the two independent implementations.
+ *
+ * The primary goals of this implementation are portability and ease of use.
+ * It is meant to be fast, but not as fast as possible.  Some known
+ * optimizations are not included to reduce source code size and avoid
+ * compile-time configuration.
+ */
+
+#include <string.h>
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Any 32-bit or wider unsigned integer data type will do */
+typedef unsigned int MD5_u32plus;
+
+typedef struct {
+  MD5_u32plus lo, hi;
+  MD5_u32plus a, b, c, d;
+  unsigned char buffer[64];
+  MD5_u32plus block[16];
+} MD5_CTX;
+
+static void MD5_Init(MD5_CTX *ctx);
+static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
+static void MD5_Final(unsigned char *result, MD5_CTX *ctx);
+
+/*
+ * The basic MD5 functions.
+ *
+ * F and G are optimized compared to their RFC 1321 definitions for
+ * architectures that lack an AND-NOT instruction, just like in Colin Plumb's
+ * implementation.
+ */
+#define F(x, y, z)                      ((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z)                      ((y) ^ ((z) & ((x) ^ (y))))
+#define H(x, y, z)                      (((x) ^ (y)) ^ (z))
+#define H2(x, y, z)                     ((x) ^ ((y) ^ (z)))
+#define I(x, y, z)                      ((y) ^ ((x) | ~(z)))
+
+/*
+ * The MD5 transformation for all four rounds.
+ */
+#define STEP(f, a, b, c, d, x, t, s) \
+        (a) += f((b), (c), (d)) + (x) + (t); \
+        (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
+        (a) += (b);
+
+/*
+ * SET reads 4 input bytes in little-endian byte order and stores them
+ * in a properly aligned word in host byte order.
+ *
+ * The check for little-endian architectures that tolerate unaligned
+ * memory accesses is just an optimization.  Nothing will break if it
+ * doesn't work.
+ */
+#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
+#define SET(n) \
+        (*(MD5_u32plus *)(void *)&ptr[(n) * 4])
+#define GET(n) \
+        SET(n)
+#else
+#define SET(n) \
+        (ctx->block[(n)] = \
+        (MD5_u32plus)ptr[(n) * 4] | \
+        ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
+        ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
+        ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
+#define GET(n) \
+        (ctx->block[(n)])
+#endif
+
+/*
+ * This processes one or more 64-byte data blocks, but does NOT update
+ * the bit counters.  There are no alignment requirements.
+ */
+static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
+{
+  const unsigned char *ptr;
+  MD5_u32plus a, b, c, d;
+  MD5_u32plus saved_a, saved_b, saved_c, saved_d;
+
+  ptr = (const unsigned char *)data;
+
+  a = ctx->a;
+  b = ctx->b;
+  c = ctx->c;
+  d = ctx->d;
+
+  do {
+    saved_a = a;
+    saved_b = b;
+    saved_c = c;
+    saved_d = d;
+
+/* Round 1 */
+    STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
+      STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
+      STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
+      STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
+      STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
+      STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
+      STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
+      STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
+      STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
+      STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
+      STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
+      STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
+      STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
+      STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
+      STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
+      STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
+
+/* Round 2 */
+      STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
+      STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
+      STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
+      STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
+      STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
+      STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
+      STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
+      STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
+      STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
+      STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
+      STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
+      STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
+      STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
+      STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
+      STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
+      STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
+
+/* Round 3 */
+      STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
+      STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
+      STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
+      STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
+      STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
+      STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
+      STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
+      STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
+      STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
+      STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
+      STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
+      STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
+      STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
+      STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
+      STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
+      STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
+
+/* Round 4 */
+      STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
+      STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
+      STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
+      STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
+      STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
+      STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
+      STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
+      STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
+      STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
+      STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
+      STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
+      STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
+      STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
+      STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
+      STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
+      STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
+
+      a += saved_a;
+    b += saved_b;
+    c += saved_c;
+    d += saved_d;
+
+    ptr += 64;
+  } while(size -= 64);
+
+  ctx->a = a;
+  ctx->b = b;
+  ctx->c = c;
+  ctx->d = d;
+
+  return ptr;
+}
+
+static void MD5_Init(MD5_CTX *ctx)
+{
+  ctx->a = 0x67452301;
+  ctx->b = 0xefcdab89;
+  ctx->c = 0x98badcfe;
+  ctx->d = 0x10325476;
+
+  ctx->lo = 0;
+  ctx->hi = 0;
+}
+
+static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
+{
+  MD5_u32plus saved_lo;
+  unsigned long used, available;
+
+  saved_lo = ctx->lo;
+  ctx->lo = (saved_lo + size) & 0x1fffffff;
+  if(ctx->lo < saved_lo)
+    ctx->hi++;
+  ctx->hi += (MD5_u32plus)size >> 29;
+
+  used = saved_lo & 0x3f;
+
+  if(used) {
+    available = 64 - used;
+
+    if(size < available) {
+      memcpy(&ctx->buffer[used], data, size);
+      return;
+    }
+
+    memcpy(&ctx->buffer[used], data, available);
+    data = (const unsigned char *)data + available;
+    size -= available;
+    body(ctx, ctx->buffer, 64);
+  }
+
+  if(size >= 64) {
+    data = body(ctx, data, size & ~(unsigned long)0x3f);
+    size &= 0x3f;
+  }
+
+  memcpy(ctx->buffer, data, size);
+}
+
+static void MD5_Final(unsigned char *result, MD5_CTX *ctx)
+{
+  unsigned long used, available;
+
+  used = ctx->lo & 0x3f;
+
+  ctx->buffer[used++] = 0x80;
+
+  available = 64 - used;
+
+  if(available < 8) {
+    memset(&ctx->buffer[used], 0, available);
+    body(ctx, ctx->buffer, 64);
+    used = 0;
+    available = 64;
+  }
+
+  memset(&ctx->buffer[used], 0, available - 8);
+
+  ctx->lo <<= 3;
+  ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
+  ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
+  ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
+  ctx->buffer[59] = curlx_ultouc(ctx->lo >> 24);
+  ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
+  ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
+  ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
+  ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
+
+  body(ctx, ctx->buffer, 64);
+
+  result[0] = curlx_ultouc((ctx->a)&0xff);
+  result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
+  result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
+  result[3] = curlx_ultouc(ctx->a >> 24);
+  result[4] = curlx_ultouc((ctx->b)&0xff);
+  result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
+  result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
+  result[7] = curlx_ultouc(ctx->b >> 24);
+  result[8] = curlx_ultouc((ctx->c)&0xff);
+  result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
+  result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
+  result[11] = curlx_ultouc(ctx->c >> 24);
+  result[12] = curlx_ultouc((ctx->d)&0xff);
+  result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
+  result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
+  result[15] = curlx_ultouc(ctx->d >> 24);
+
+  memset(ctx, 0, sizeof(*ctx));
+}
+
+#endif /* CRYPTO LIBS */
+
+const HMAC_params Curl_HMAC_MD5[] = {
+  {
+    (HMAC_hinit_func) MD5_Init,           /* Hash initialization function. */
+    (HMAC_hupdate_func) MD5_Update,       /* Hash update function. */
+    (HMAC_hfinal_func) MD5_Final,         /* Hash computation end function. */
+    sizeof(MD5_CTX),                      /* Size of hash context structure. */
+    64,                                   /* Maximum key length. */
+    16                                    /* Result size. */
+  }
+};
+
+const MD5_params Curl_DIGEST_MD5[] = {
+  {
+    (Curl_MD5_init_func) MD5_Init,      /* Digest initialization function */
+    (Curl_MD5_update_func) MD5_Update,  /* Digest update function */
+    (Curl_MD5_final_func) MD5_Final,    /* Digest computation end function */
+    sizeof(MD5_CTX),                    /* Size of digest context struct */
+    16                                  /* Result size */
+  }
+};
+
+/*
+ * @unittest: 1601
+ */
+void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */
+                const unsigned char *input)
+{
+  MD5_CTX ctx;
+  MD5_Init(&ctx);
+  MD5_Update(&ctx, input, curlx_uztoui(strlen((char *)input)));
+  MD5_Final(outbuffer, &ctx);
+}
+
+MD5_context *Curl_MD5_init(const MD5_params *md5params)
+{
+  MD5_context *ctxt;
+
+  /* Create MD5 context */
+  ctxt = malloc(sizeof *ctxt);
+
+  if(!ctxt)
+    return ctxt;
+
+  ctxt->md5_hashctx = malloc(md5params->md5_ctxtsize);
+
+  if(!ctxt->md5_hashctx) {
+    free(ctxt);
+    return NULL;
+  }
+
+  ctxt->md5_hash = md5params;
+
+  (*md5params->md5_init_func)(ctxt->md5_hashctx);
+
+  return ctxt;
+}
+
+int Curl_MD5_update(MD5_context *context,
+                    const unsigned char *data,
+                    unsigned int len)
+{
+  (*context->md5_hash->md5_update_func)(context->md5_hashctx, data, len);
+
+  return 0;
+}
+
+int Curl_MD5_final(MD5_context *context, unsigned char *result)
+{
+  (*context->md5_hash->md5_final_func)(result, context->md5_hashctx);
+
+  free(context->md5_hashctx);
+  free(context);
+
+  return 0;
+}
+
+#endif /* CURL_DISABLE_CRYPTO_AUTH */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/memdebug.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/memdebug.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/memdebug.c	(revision 331)
@@ -0,0 +1,519 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef CURLDEBUG
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+
+#define MEMDEBUG_NODEFINES /* don't redefine the standard functions */
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * Until 2011-08-17 libcurl's Memory Tracking feature also performed
+ * automatic malloc and free filling operations using 0xA5 and 0x13
+ * values. Our own preinitialization of dynamically allocated memory
+ * might be useful when not using third party memory debuggers, but
+ * on the other hand this would fool memory debuggers into thinking
+ * that all dynamically allocated memory is properly initialized.
+ *
+ * As a default setting, libcurl's Memory Tracking feature no longer
+ * performs preinitialization of dynamically allocated memory on its
+ * own. If you know what you are doing, and really want to retain old
+ * behavior, you can achieve this compiling with preprocessor symbols
+ * CURL_MT_MALLOC_FILL and CURL_MT_FREE_FILL defined with appropriate
+ * values.
+ */
+
+#ifdef CURL_MT_MALLOC_FILL
+# if (CURL_MT_MALLOC_FILL < 0) || (CURL_MT_MALLOC_FILL > 0xff)
+#   error "invalid CURL_MT_MALLOC_FILL or out of range"
+# endif
+#endif
+
+#ifdef CURL_MT_FREE_FILL
+# if (CURL_MT_FREE_FILL < 0) || (CURL_MT_FREE_FILL > 0xff)
+#   error "invalid CURL_MT_FREE_FILL or out of range"
+# endif
+#endif
+
+#if defined(CURL_MT_MALLOC_FILL) && defined(CURL_MT_FREE_FILL)
+# if (CURL_MT_MALLOC_FILL == CURL_MT_FREE_FILL)
+#   error "CURL_MT_MALLOC_FILL same as CURL_MT_FREE_FILL"
+# endif
+#endif
+
+#ifdef CURL_MT_MALLOC_FILL
+#  define mt_malloc_fill(buf,len) memset((buf), CURL_MT_MALLOC_FILL, (len))
+#else
+#  define mt_malloc_fill(buf,len) Curl_nop_stmt
+#endif
+
+#ifdef CURL_MT_FREE_FILL
+#  define mt_free_fill(buf,len) memset((buf), CURL_MT_FREE_FILL, (len))
+#else
+#  define mt_free_fill(buf,len) Curl_nop_stmt
+#endif
+
+struct memdebug {
+  size_t size;
+  union {
+    curl_off_t o;
+    double d;
+    void *p;
+  } mem[1];
+  /* I'm hoping this is the thing with the strictest alignment
+   * requirements.  That also means we waste some space :-( */
+};
+
+/*
+ * Note that these debug functions are very simple and they are meant to
+ * remain so. For advanced analysis, record a log file and write perl scripts
+ * to analyze them!
+ *
+ * Don't use these with multithreaded test programs!
+ */
+
+#define logfile curl_debuglogfile
+FILE *curl_debuglogfile = NULL;
+static bool memlimit = FALSE; /* enable memory limit */
+static long memsize = 0;  /* set number of mallocs allowed */
+
+/* this sets the log file name */
+void curl_memdebug(const char *logname)
+{
+  if(!logfile) {
+    if(logname && *logname)
+      logfile = fopen(logname, FOPEN_WRITETEXT);
+    else
+      logfile = stderr;
+#ifdef MEMDEBUG_LOG_SYNC
+    /* Flush the log file after every line so the log isn't lost in a crash */
+    if(logfile)
+      setbuf(logfile, (char *)NULL);
+#endif
+  }
+}
+
+/* This function sets the number of malloc() calls that should return
+   successfully! */
+void curl_memlimit(long limit)
+{
+  if(!memlimit) {
+    memlimit = TRUE;
+    memsize = limit;
+  }
+}
+
+/* returns TRUE if this isn't allowed! */
+static bool countcheck(const char *func, int line, const char *source)
+{
+  /* if source is NULL, then the call is made internally and this check
+     should not be made */
+  if(memlimit && source) {
+    if(!memsize) {
+      if(source) {
+        /* log to file */
+        curl_memlog("LIMIT %s:%d %s reached memlimit\n",
+                    source, line, func);
+        /* log to stderr also */
+        fprintf(stderr, "LIMIT %s:%d %s reached memlimit\n",
+                source, line, func);
+        fflush(logfile); /* because it might crash now */
+      }
+      errno = ENOMEM;
+      return TRUE; /* RETURN ERROR! */
+    }
+    else
+      memsize--; /* countdown */
+
+
+  }
+
+  return FALSE; /* allow this */
+}
+
+void *curl_domalloc(size_t wantedsize, int line, const char *source)
+{
+  struct memdebug *mem;
+  size_t size;
+
+  DEBUGASSERT(wantedsize != 0);
+
+  if(countcheck("malloc", line, source))
+    return NULL;
+
+  /* alloc at least 64 bytes */
+  size = sizeof(struct memdebug) + wantedsize;
+
+  mem = (Curl_cmalloc)(size);
+  if(mem) {
+    /* fill memory with junk */
+    mt_malloc_fill(mem->mem, wantedsize);
+    mem->size = wantedsize;
+  }
+
+  if(source)
+    curl_memlog("MEM %s:%d malloc(%zu) = %p\n",
+                source, line, wantedsize,
+                mem ? (void *)mem->mem : (void *)0);
+
+  return (mem ? mem->mem : NULL);
+}
+
+void *curl_docalloc(size_t wanted_elements, size_t wanted_size,
+                    int line, const char *source)
+{
+  struct memdebug *mem;
+  size_t size, user_size;
+
+  DEBUGASSERT(wanted_elements != 0);
+  DEBUGASSERT(wanted_size != 0);
+
+  if(countcheck("calloc", line, source))
+    return NULL;
+
+  /* alloc at least 64 bytes */
+  user_size = wanted_size * wanted_elements;
+  size = sizeof(struct memdebug) + user_size;
+
+  mem = (Curl_ccalloc)(1, size);
+  if(mem)
+    mem->size = user_size;
+
+  if(source)
+    curl_memlog("MEM %s:%d calloc(%zu,%zu) = %p\n",
+                source, line, wanted_elements, wanted_size,
+                mem ? (void *)mem->mem : (void *)0);
+
+  return (mem ? mem->mem : NULL);
+}
+
+char *curl_dostrdup(const char *str, int line, const char *source)
+{
+  char *mem;
+  size_t len;
+
+  DEBUGASSERT(str != NULL);
+
+  if(countcheck("strdup", line, source))
+    return NULL;
+
+  len = strlen(str) + 1;
+
+  mem = curl_domalloc(len, 0, NULL); /* NULL prevents logging */
+  if(mem)
+    memcpy(mem, str, len);
+
+  if(source)
+    curl_memlog("MEM %s:%d strdup(%p) (%zu) = %p\n",
+                source, line, (const void *)str, len, (const void *)mem);
+
+  return mem;
+}
+
+#if defined(WIN32) && defined(UNICODE)
+wchar_t *curl_dowcsdup(const wchar_t *str, int line, const char *source)
+{
+  wchar_t *mem;
+  size_t wsiz, bsiz;
+
+  DEBUGASSERT(str != NULL);
+
+  if(countcheck("wcsdup", line, source))
+    return NULL;
+
+  wsiz = wcslen(str) + 1;
+  bsiz = wsiz * sizeof(wchar_t);
+
+  mem = curl_domalloc(bsiz, 0, NULL); /* NULL prevents logging */
+  if(mem)
+    memcpy(mem, str, bsiz);
+
+  if(source)
+    curl_memlog("MEM %s:%d wcsdup(%p) (%zu) = %p\n",
+                source, line, (void *)str, bsiz, (void *)mem);
+
+  return mem;
+}
+#endif
+
+/* We provide a realloc() that accepts a NULL as pointer, which then
+   performs a malloc(). In order to work with ares. */
+void *curl_dorealloc(void *ptr, size_t wantedsize,
+                     int line, const char *source)
+{
+  struct memdebug *mem = NULL;
+
+  size_t size = sizeof(struct memdebug) + wantedsize;
+
+  DEBUGASSERT(wantedsize != 0);
+
+  if(countcheck("realloc", line, source))
+    return NULL;
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:1684)
+   /* 1684: conversion from pointer to same-sized integral type */
+#endif
+
+  if(ptr)
+    mem = (void *)((char *)ptr - offsetof(struct memdebug, mem));
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+
+  mem = (Curl_crealloc)(mem, size);
+  if(source)
+    curl_memlog("MEM %s:%d realloc(%p, %zu) = %p\n",
+                source, line, (void *)ptr, wantedsize,
+                mem ? (void *)mem->mem : (void *)0);
+
+  if(mem) {
+    mem->size = wantedsize;
+    return mem->mem;
+  }
+
+  return NULL;
+}
+
+void curl_dofree(void *ptr, int line, const char *source)
+{
+  struct memdebug *mem;
+
+  if(ptr) {
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:1684)
+   /* 1684: conversion from pointer to same-sized integral type */
+#endif
+
+    mem = (void *)((char *)ptr - offsetof(struct memdebug, mem));
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+
+    /* destroy */
+    mt_free_fill(mem->mem, mem->size);
+
+    /* free for real */
+    (Curl_cfree)(mem);
+  }
+
+  if(source)
+    curl_memlog("MEM %s:%d free(%p)\n", source, line, (void *)ptr);
+}
+
+curl_socket_t curl_socket(int domain, int type, int protocol,
+                          int line, const char *source)
+{
+  const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
+    "FD %s:%d socket() = %d\n" :
+    (sizeof(curl_socket_t) == sizeof(long)) ?
+    "FD %s:%d socket() = %ld\n" :
+    "FD %s:%d socket() = %zd\n";
+
+  curl_socket_t sockfd;
+
+  if(countcheck("socket", line, source))
+    return CURL_SOCKET_BAD;
+
+  sockfd = socket(domain, type, protocol);
+
+  if(source && (sockfd != CURL_SOCKET_BAD))
+    curl_memlog(fmt, source, line, sockfd);
+
+  return sockfd;
+}
+
+SEND_TYPE_RETV curl_dosend(SEND_TYPE_ARG1 sockfd,
+                           SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf,
+                           SEND_TYPE_ARG3 len, SEND_TYPE_ARG4 flags, int line,
+                           const char *source)
+{
+  SEND_TYPE_RETV rc;
+  if(countcheck("send", line, source))
+    return -1;
+  rc = send(sockfd, buf, len, flags);
+  if(source)
+    curl_memlog("SEND %s:%d send(%lu) = %ld\n",
+                source, line, (unsigned long)len, (long)rc);
+  return rc;
+}
+
+RECV_TYPE_RETV curl_dorecv(RECV_TYPE_ARG1 sockfd, RECV_TYPE_ARG2 buf,
+                           RECV_TYPE_ARG3 len, RECV_TYPE_ARG4 flags, int line,
+                           const char *source)
+{
+  RECV_TYPE_RETV rc;
+  if(countcheck("recv", line, source))
+    return -1;
+  rc = recv(sockfd, buf, len, flags);
+  if(source)
+    curl_memlog("RECV %s:%d recv(%lu) = %ld\n",
+                source, line, (unsigned long)len, (long)rc);
+  return rc;
+}
+
+#ifdef HAVE_SOCKETPAIR
+int curl_socketpair(int domain, int type, int protocol,
+                    curl_socket_t socket_vector[2],
+                    int line, const char *source)
+{
+  const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
+    "FD %s:%d socketpair() = %d %d\n" :
+    (sizeof(curl_socket_t) == sizeof(long)) ?
+    "FD %s:%d socketpair() = %ld %ld\n" :
+    "FD %s:%d socketpair() = %zd %zd\n";
+
+  int res = socketpair(domain, type, protocol, socket_vector);
+
+  if(source && (0 == res))
+    curl_memlog(fmt, source, line, socket_vector[0], socket_vector[1]);
+
+  return res;
+}
+#endif
+
+curl_socket_t curl_accept(curl_socket_t s, void *saddr, void *saddrlen,
+                          int line, const char *source)
+{
+  const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
+    "FD %s:%d accept() = %d\n" :
+    (sizeof(curl_socket_t) == sizeof(long)) ?
+    "FD %s:%d accept() = %ld\n" :
+    "FD %s:%d accept() = %zd\n";
+
+  struct sockaddr *addr = (struct sockaddr *)saddr;
+  curl_socklen_t *addrlen = (curl_socklen_t *)saddrlen;
+
+  curl_socket_t sockfd = accept(s, addr, addrlen);
+
+  if(source && (sockfd != CURL_SOCKET_BAD))
+    curl_memlog(fmt, source, line, sockfd);
+
+  return sockfd;
+}
+
+/* separate function to allow libcurl to mark a "faked" close */
+void curl_mark_sclose(curl_socket_t sockfd, int line, const char *source)
+{
+  const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ?
+    "FD %s:%d sclose(%d)\n":
+    (sizeof(curl_socket_t) == sizeof(long)) ?
+    "FD %s:%d sclose(%ld)\n":
+    "FD %s:%d sclose(%zd)\n";
+
+  if(source)
+    curl_memlog(fmt, source, line, sockfd);
+}
+
+/* this is our own defined way to close sockets on *ALL* platforms */
+int curl_sclose(curl_socket_t sockfd, int line, const char *source)
+{
+  int res = sclose(sockfd);
+  curl_mark_sclose(sockfd, line, source);
+  return res;
+}
+
+FILE *curl_fopen(const char *file, const char *mode,
+                 int line, const char *source)
+{
+  FILE *res = fopen(file, mode);
+
+  if(source)
+    curl_memlog("FILE %s:%d fopen(\"%s\",\"%s\") = %p\n",
+                source, line, file, mode, (void *)res);
+
+  return res;
+}
+
+#ifdef HAVE_FDOPEN
+FILE *curl_fdopen(int filedes, const char *mode,
+                  int line, const char *source)
+{
+  FILE *res = fdopen(filedes, mode);
+
+  if(source)
+    curl_memlog("FILE %s:%d fdopen(\"%d\",\"%s\") = %p\n",
+                source, line, filedes, mode, (void *)res);
+
+  return res;
+}
+#endif
+
+int curl_fclose(FILE *file, int line, const char *source)
+{
+  int res;
+
+  DEBUGASSERT(file != NULL);
+
+  res = fclose(file);
+
+  if(source)
+    curl_memlog("FILE %s:%d fclose(%p)\n",
+                source, line, (void *)file);
+
+  return res;
+}
+
+#define LOGLINE_BUFSIZE  1024
+
+/* this does the writing to the memory tracking log file */
+void curl_memlog(const char *format, ...)
+{
+  char *buf;
+  int nchars;
+  va_list ap;
+
+  if(!logfile)
+    return;
+
+  buf = (Curl_cmalloc)(LOGLINE_BUFSIZE);
+  if(!buf)
+    return;
+
+  va_start(ap, format);
+  nchars = vsnprintf(buf, LOGLINE_BUFSIZE, format, ap);
+  va_end(ap);
+
+  if(nchars > LOGLINE_BUFSIZE - 1)
+    nchars = LOGLINE_BUFSIZE - 1;
+
+  if(nchars > 0)
+    fwrite(buf, 1, (size_t)nchars, logfile);
+
+  (Curl_cfree)(buf);
+}
+
+#endif /* CURLDEBUG */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/memdebug.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/memdebug.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/memdebug.h	(revision 331)
@@ -0,0 +1,186 @@
+#ifndef HEADER_CURL_MEMDEBUG_H
+#define HEADER_CURL_MEMDEBUG_H
+#ifdef CURLDEBUG
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * CAUTION: this header is designed to work when included by the app-side
+ * as well as the library. Do not mix with library internals!
+ */
+
+#define CURL_MT_LOGFNAME_BUFSIZE 512
+
+#define logfile curl_debuglogfile
+
+extern FILE *logfile;
+
+/* memory functions */
+CURL_EXTERN void *curl_domalloc(size_t size, int line, const char *source);
+CURL_EXTERN void *curl_docalloc(size_t elements, size_t size, int line,
+                                const char *source);
+CURL_EXTERN void *curl_dorealloc(void *ptr, size_t size, int line,
+                                 const char *source);
+CURL_EXTERN void curl_dofree(void *ptr, int line, const char *source);
+CURL_EXTERN char *curl_dostrdup(const char *str, int line, const char *source);
+#if defined(WIN32) && defined(UNICODE)
+CURL_EXTERN wchar_t *curl_dowcsdup(const wchar_t *str, int line,
+                                   const char *source);
+#endif
+
+CURL_EXTERN void curl_memdebug(const char *logname);
+CURL_EXTERN void curl_memlimit(long limit);
+CURL_EXTERN void curl_memlog(const char *format, ...);
+
+/* file descriptor manipulators */
+CURL_EXTERN curl_socket_t curl_socket(int domain, int type, int protocol,
+                                      int line, const char *source);
+CURL_EXTERN void curl_mark_sclose(curl_socket_t sockfd,
+                                  int line, const char *source);
+CURL_EXTERN int curl_sclose(curl_socket_t sockfd,
+                            int line, const char *source);
+CURL_EXTERN curl_socket_t curl_accept(curl_socket_t s, void *a, void *alen,
+                                      int line, const char *source);
+#ifdef HAVE_SOCKETPAIR
+CURL_EXTERN int curl_socketpair(int domain, int type, int protocol,
+                                curl_socket_t socket_vector[2],
+                                int line, const char *source);
+#endif
+
+/* send/receive sockets */
+CURL_EXTERN SEND_TYPE_RETV curl_dosend(SEND_TYPE_ARG1 sockfd,
+                                       SEND_QUAL_ARG2 SEND_TYPE_ARG2 buf,
+                                       SEND_TYPE_ARG3 len,
+                                       SEND_TYPE_ARG4 flags, int line,
+                                       const char *source);
+CURL_EXTERN RECV_TYPE_RETV curl_dorecv(RECV_TYPE_ARG1 sockfd,
+                                       RECV_TYPE_ARG2 buf, RECV_TYPE_ARG3 len,
+                                       RECV_TYPE_ARG4 flags, int line,
+                                       const char *source);
+
+/* FILE functions */
+CURL_EXTERN FILE *curl_fopen(const char *file, const char *mode, int line,
+                             const char *source);
+#ifdef HAVE_FDOPEN
+CURL_EXTERN FILE *curl_fdopen(int filedes, const char *mode, int line,
+                              const char *source);
+#endif
+CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source);
+
+#ifndef MEMDEBUG_NODEFINES
+
+/* Set this symbol on the command-line, recompile all lib-sources */
+#undef strdup
+#define strdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__)
+#define malloc(size) curl_domalloc(size, __LINE__, __FILE__)
+#define calloc(nbelem,size) curl_docalloc(nbelem, size, __LINE__, __FILE__)
+#define realloc(ptr,size) curl_dorealloc(ptr, size, __LINE__, __FILE__)
+#define free(ptr) curl_dofree(ptr, __LINE__, __FILE__)
+#define send(a,b,c,d) curl_dosend(a,b,c,d, __LINE__, __FILE__)
+#define recv(a,b,c,d) curl_dorecv(a,b,c,d, __LINE__, __FILE__)
+
+#ifdef WIN32
+#  ifdef UNICODE
+#    undef wcsdup
+#    define wcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
+#    undef _wcsdup
+#    define _wcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
+#    undef _tcsdup
+#    define _tcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__)
+#  else
+#    undef _tcsdup
+#    define _tcsdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__)
+#  endif
+#endif
+
+#undef socket
+#define socket(domain,type,protocol)\
+ curl_socket(domain, type, protocol, __LINE__, __FILE__)
+#undef accept /* for those with accept as a macro */
+#define accept(sock,addr,len)\
+ curl_accept(sock, addr, len, __LINE__, __FILE__)
+#ifdef HAVE_SOCKETPAIR
+#define socketpair(domain,type,protocol,socket_vector)\
+ curl_socketpair(domain, type, protocol, socket_vector, __LINE__, __FILE__)
+#endif
+
+#ifdef HAVE_GETADDRINFO
+#if defined(getaddrinfo) && defined(__osf__)
+/* OSF/1 and Tru64 have getaddrinfo as a define already, so we cannot define
+   our macro as for other platforms. Instead, we redefine the new name they
+   define getaddrinfo to become! */
+#define ogetaddrinfo(host,serv,hint,res) \
+  curl_dogetaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
+#else
+#undef getaddrinfo
+#define getaddrinfo(host,serv,hint,res) \
+  curl_dogetaddrinfo(host, serv, hint, res, __LINE__, __FILE__)
+#endif
+#endif /* HAVE_GETADDRINFO */
+
+#ifdef HAVE_GETNAMEINFO
+#undef getnameinfo
+#define getnameinfo(sa,salen,host,hostlen,serv,servlen,flags) \
+  curl_dogetnameinfo(sa, salen, host, hostlen, serv, servlen, flags, \
+                     __LINE__, __FILE__)
+#endif /* HAVE_GETNAMEINFO */
+
+#ifdef HAVE_FREEADDRINFO
+#undef freeaddrinfo
+#define freeaddrinfo(data) \
+  curl_dofreeaddrinfo(data, __LINE__, __FILE__)
+#endif /* HAVE_FREEADDRINFO */
+
+/* sclose is probably already defined, redefine it! */
+#undef sclose
+#define sclose(sockfd) curl_sclose(sockfd,__LINE__,__FILE__)
+
+#define fake_sclose(sockfd) curl_mark_sclose(sockfd,__LINE__,__FILE__)
+
+#undef fopen
+#define fopen(file,mode) curl_fopen(file,mode,__LINE__,__FILE__)
+#undef fdopen
+#define fdopen(file,mode) curl_fdopen(file,mode,__LINE__,__FILE__)
+#define fclose(file) curl_fclose(file,__LINE__,__FILE__)
+
+#endif /* MEMDEBUG_NODEFINES */
+
+#endif /* CURLDEBUG */
+
+/*
+** Following section applies even when CURLDEBUG is not defined.
+*/
+
+#ifndef fake_sclose
+#define fake_sclose(x)  Curl_nop_stmt
+#endif
+
+/*
+ * Curl_safefree defined as a macro to allow MemoryTracking feature
+ * to log free() calls at same location where Curl_safefree is used.
+ * This macro also assigns NULL to given pointer when free'd.
+ */
+
+#define Curl_safefree(ptr) \
+  do { free((ptr)); (ptr) = NULL;} WHILE_FALSE
+
+#endif /* HEADER_CURL_MEMDEBUG_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/mime.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/mime.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/mime.c	(revision 331)
@@ -0,0 +1,1908 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "mime.h"
+#include "non-ascii.h"
+#include "urldata.h"
+#include "sendf.h"
+
+#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_SMTP) || \
+    !defined(CURL_DISABLE_IMAP)
+
+#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
+#include <libgen.h>
+#endif
+
+#include "rand.h"
+#include "slist.h"
+#include "strcase.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifdef WIN32
+# ifndef R_OK
+#  define R_OK 4
+# endif
+#endif
+
+
+#define FILE_CONTENTTYPE_DEFAULT        "application/octet-stream"
+#define MULTIPART_CONTENTTYPE_DEFAULT   "multipart/mixed"
+#define DISPOSITION_DEFAULT             "attachment"
+
+#define READ_ERROR                      ((size_t) -1)
+
+/* Encoders. */
+static size_t encoder_nop_read(char *buffer, size_t size, bool ateof,
+                                curl_mimepart *part);
+static curl_off_t encoder_nop_size(curl_mimepart *part);
+static size_t encoder_7bit_read(char *buffer, size_t size, bool ateof,
+                                curl_mimepart *part);
+static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
+                                curl_mimepart *part);
+static curl_off_t encoder_base64_size(curl_mimepart *part);
+static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
+                              curl_mimepart *part);
+static curl_off_t encoder_qp_size(curl_mimepart *part);
+
+static const mime_encoder encoders[] = {
+  {"binary", encoder_nop_read, encoder_nop_size},
+  {"8bit", encoder_nop_read, encoder_nop_size},
+  {"7bit", encoder_7bit_read, encoder_nop_size},
+  {"base64", encoder_base64_read, encoder_base64_size},
+  {"quoted-printable", encoder_qp_read, encoder_qp_size},
+  {ZERO_NULL, ZERO_NULL, ZERO_NULL}
+};
+
+/* Base64 encoding table */
+static const char base64[] =
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/* Quoted-printable character class table.
+ *
+ * We cannot rely on ctype functions since quoted-printable input data
+ * is assumed to be ascii-compatible, even on non-ascii platforms. */
+#define QP_OK           1       /* Can be represented by itself. */
+#define QP_SP           2       /* Space or tab. */
+#define QP_CR           3       /* Carriage return. */
+#define QP_LF           4       /* Line-feed. */
+static const unsigned char qp_class[] = {
+ 0,     0,     0,     0,     0,     0,     0,     0,            /* 00 - 07 */
+ 0,     QP_SP, QP_LF, 0,     0,     QP_CR, 0,     0,            /* 08 - 0F */
+ 0,     0,     0,     0,     0,     0,     0,     0,            /* 10 - 17 */
+ 0,     0,     0,     0,     0,     0,     0,     0,            /* 18 - 1F */
+ QP_SP, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK,        /* 20 - 27 */
+ QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK,        /* 28 - 2F */
+ QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK,        /* 30 - 37 */
+ QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, 0    , QP_OK, QP_OK,        /* 38 - 3F */
+ QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK,        /* 40 - 47 */
+ QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK,        /* 48 - 4F */
+ QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK,        /* 50 - 57 */
+ QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK,        /* 58 - 5F */
+ QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK,        /* 60 - 67 */
+ QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK,        /* 68 - 6F */
+ QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK,        /* 70 - 77 */
+ QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, QP_OK, 0,            /* 78 - 7F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                /* 80 - 8F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                /* 90 - 9F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                /* A0 - AF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                /* B0 - BF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                /* C0 - CF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                /* D0 - DF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                /* E0 - EF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0                 /* F0 - FF */
+};
+
+
+/* Binary --> hexadecimal ASCII table. */
+static const char aschex[] =
+  "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x41\x42\x43\x44\x45\x46";
+
+
+
+#ifndef __VMS
+#define filesize(name, stat_data) (stat_data.st_size)
+#define fopen_read fopen
+
+#else
+
+#include <fabdef.h>
+/*
+ * get_vms_file_size does what it takes to get the real size of the file
+ *
+ * For fixed files, find out the size of the EOF block and adjust.
+ *
+ * For all others, have to read the entire file in, discarding the contents.
+ * Most posted text files will be small, and binary files like zlib archives
+ * and CD/DVD images should be either a STREAM_LF format or a fixed format.
+ *
+ */
+curl_off_t VmsRealFileSize(const char *name,
+                           const struct_stat *stat_buf)
+{
+  char buffer[8192];
+  curl_off_t count;
+  int ret_stat;
+  FILE * file;
+
+  file = fopen(name, FOPEN_READTEXT); /* VMS */
+  if(file == NULL)
+    return 0;
+
+  count = 0;
+  ret_stat = 1;
+  while(ret_stat > 0) {
+    ret_stat = fread(buffer, 1, sizeof(buffer), file);
+    if(ret_stat != 0)
+      count += ret_stat;
+  }
+  fclose(file);
+
+  return count;
+}
+
+/*
+ *
+ *  VmsSpecialSize checks to see if the stat st_size can be trusted and
+ *  if not to call a routine to get the correct size.
+ *
+ */
+static curl_off_t VmsSpecialSize(const char *name,
+                                 const struct_stat *stat_buf)
+{
+  switch(stat_buf->st_fab_rfm) {
+  case FAB$C_VAR:
+  case FAB$C_VFC:
+    return VmsRealFileSize(name, stat_buf);
+    break;
+  default:
+    return stat_buf->st_size;
+  }
+}
+
+#define filesize(name, stat_data) VmsSpecialSize(name, &stat_data)
+
+/*
+ * vmsfopenread
+ *
+ * For upload to work as expected on VMS, different optional
+ * parameters must be added to the fopen command based on
+ * record format of the file.
+ *
+ */
+static FILE * vmsfopenread(const char *file, const char *mode)
+{
+  struct_stat statbuf;
+  int result;
+
+  result = stat(file, &statbuf);
+
+  switch(statbuf.st_fab_rfm) {
+  case FAB$C_VAR:
+  case FAB$C_VFC:
+  case FAB$C_STMCR:
+    return fopen(file, FOPEN_READTEXT); /* VMS */
+    break;
+  default:
+    return fopen(file, FOPEN_READTEXT, "rfm=stmlf", "ctx=stm");
+  }
+}
+
+#define fopen_read vmsfopenread
+#endif
+
+
+#ifndef HAVE_BASENAME
+/*
+  (Quote from The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004
+  Edition)
+
+  The basename() function shall take the pathname pointed to by path and
+  return a pointer to the final component of the pathname, deleting any
+  trailing '/' characters.
+
+  If the string pointed to by path consists entirely of the '/' character,
+  basename() shall return a pointer to the string "/". If the string pointed
+  to by path is exactly "//", it is implementation-defined whether '/' or "//"
+  is returned.
+
+  If path is a null pointer or points to an empty string, basename() shall
+  return a pointer to the string ".".
+
+  The basename() function may modify the string pointed to by path, and may
+  return a pointer to static storage that may then be overwritten by a
+  subsequent call to basename().
+
+  The basename() function need not be reentrant. A function that is not
+  required to be reentrant is not required to be thread-safe.
+
+*/
+static char *Curl_basename(char *path)
+{
+  /* Ignore all the details above for now and make a quick and simple
+     implementaion here */
+  char *s1;
+  char *s2;
+
+  s1 = strrchr(path, '/');
+  s2 = strrchr(path, '\\');
+
+  if(s1 && s2) {
+    path = (s1 > s2? s1 : s2) + 1;
+  }
+  else if(s1)
+    path = s1 + 1;
+  else if(s2)
+    path = s2 + 1;
+
+  return path;
+}
+
+#define basename(x)  Curl_basename((x))
+#endif
+
+
+/* Set readback state. */
+static void mimesetstate(mime_state *state, enum mimestate tok, void *ptr)
+{
+  state->state = tok;
+  state->ptr = ptr;
+  state->offset = 0;
+}
+
+
+/* Escape header string into allocated memory. */
+static char *escape_string(const char *src)
+{
+  size_t bytecount = 0;
+  size_t i;
+  char *dst;
+
+  for(i = 0; src[i]; i++)
+    if(src[i] == '"' || src[i] == '\\')
+      bytecount++;
+
+  bytecount += i;
+  dst = malloc(bytecount + 1);
+  if(!dst)
+    return NULL;
+
+  for(i = 0; *src; src++) {
+    if(*src == '"' || *src == '\\')
+      dst[i++] = '\\';
+    dst[i++] = *src;
+  }
+
+  dst[i] = '\0';
+  return dst;
+}
+
+/* Check if header matches. */
+static char *match_header(struct curl_slist *hdr, const char *lbl, size_t len)
+{
+  char *value = NULL;
+
+  if(strncasecompare(hdr->data, lbl, len) && hdr->data[len] == ':')
+    for(value = hdr->data + len + 1; *value == ' '; value++)
+      ;
+  return value;
+}
+
+/* Get a header from an slist. */
+static char *search_header(struct curl_slist *hdrlist, const char *hdr)
+{
+  size_t len = strlen(hdr);
+  char *value = NULL;
+
+  for(; !value && hdrlist; hdrlist = hdrlist->next)
+    value = match_header(hdrlist, hdr, len);
+
+  return value;
+}
+
+static char *strippath(const char *fullfile)
+{
+  char *filename;
+  char *base;
+  filename = strdup(fullfile); /* duplicate since basename() may ruin the
+                                  buffer it works on */
+  if(!filename)
+    return NULL;
+  base = strdup(basename(filename));
+
+  free(filename); /* free temporary buffer */
+
+  return base; /* returns an allocated string or NULL ! */
+}
+
+/* Initialize data encoder state. */
+static void cleanup_encoder_state(mime_encoder_state *p)
+{
+  p->pos = 0;
+  p->bufbeg = 0;
+  p->bufend = 0;
+}
+
+
+/* Dummy encoder. This is used for 8bit and binary content encodings. */
+static size_t encoder_nop_read(char *buffer, size_t size, bool ateof,
+                               curl_mimepart *part)
+{
+  mime_encoder_state *st = &part->encstate;
+  size_t insize = st->bufend - st->bufbeg;
+
+  (void) ateof;
+
+  if(size > insize)
+    size = insize;
+  if(size)
+    memcpy(buffer, st->buf, size);
+  st->bufbeg += size;
+  return size;
+}
+
+static curl_off_t encoder_nop_size(curl_mimepart *part)
+{
+  return part->datasize;
+}
+
+
+/* 7bit encoder: the encoder is just a data validity check. */
+static size_t encoder_7bit_read(char *buffer, size_t size, bool ateof,
+                                curl_mimepart *part)
+{
+  mime_encoder_state *st = &part->encstate;
+  size_t cursize = st->bufend - st->bufbeg;
+
+  (void) ateof;
+
+  if(size > cursize)
+    size = cursize;
+
+  for(cursize = 0; cursize < size; cursize++) {
+    *buffer = st->buf[st->bufbeg];
+    if(*buffer++ & 0x80)
+      return cursize? cursize: READ_ERROR;
+    st->bufbeg++;
+  }
+
+  return cursize;
+}
+
+
+/* Base64 content encoder. */
+static size_t encoder_base64_read(char *buffer, size_t size, bool ateof,
+                                curl_mimepart *part)
+{
+  mime_encoder_state *st = &part->encstate;
+  size_t cursize = 0;
+  int i;
+  char *ptr = buffer;
+
+  while(st->bufbeg < st->bufend) {
+    /* Line full ? */
+    if(st->pos > MAX_ENCODED_LINE_LENGTH - 4) {
+      /* Yes, we need 2 characters for CRLF. */
+      if(size < 2)
+        break;
+      *ptr++ = '\r';
+      *ptr++ = '\n';
+      st->pos = 0;
+      cursize += 2;
+      size -= 2;
+    }
+
+    /* Be sure there is enough space and input data for a base64 group. */
+    if(size < 4 || st->bufend - st->bufbeg < 3)
+      break;
+
+    /* Encode three bytes as four characters. */
+    i = st->buf[st->bufbeg++] & 0xFF;
+    i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF);
+    i = (i << 8) | (st->buf[st->bufbeg++] & 0xFF);
+    *ptr++ = base64[(i >> 18) & 0x3F];
+    *ptr++ = base64[(i >> 12) & 0x3F];
+    *ptr++ = base64[(i >> 6) & 0x3F];
+    *ptr++ = base64[i & 0x3F];
+    cursize += 4;
+    st->pos += 4;
+    size -= 4;
+  }
+
+  /* If at eof, we have to flush the buffered data. */
+  if(ateof && size >= 4) {
+    /* Buffered data size can only be 0, 1 or 2. */
+    ptr[2] = ptr[3] = '=';
+    i = 0;
+    switch(st->bufend - st->bufbeg) {
+    case 2:
+      i = (st->buf[st->bufbeg + 1] & 0xFF) << 8;
+      /* FALLTHROUGH */
+    case 1:
+      i |= (st->buf[st->bufbeg] & 0xFF) << 16;
+      ptr[0] = base64[(i >> 18) & 0x3F];
+      ptr[1] = base64[(i >> 12) & 0x3F];
+      if(++st->bufbeg != st->bufend) {
+        ptr[2] = base64[(i >> 6) & 0x3F];
+        st->bufbeg++;
+      }
+      cursize += 4;
+      st->pos += 4;
+      break;
+    }
+  }
+
+#ifdef CURL_DOES_CONVERSIONS
+  /* This is now textual data, Convert character codes. */
+  if(part->easy && cursize) {
+    CURLcode result = Curl_convert_to_network(part->easy, buffer, cursize);
+    if(result)
+      return READ_ERROR;
+  }
+#endif
+
+  return cursize;
+}
+
+static curl_off_t encoder_base64_size(curl_mimepart *part)
+{
+  curl_off_t size = part->datasize;
+
+  if(size <= 0)
+    return size;    /* Unknown size or no data. */
+
+  /* Compute base64 character count. */
+  size = 4 * (1 + (size - 1) / 3);
+
+  /* Effective character count must include CRLFs. */
+  return size + 2 * ((size - 1) / MAX_ENCODED_LINE_LENGTH);
+}
+
+
+/* Quoted-printable lookahead.
+ *
+ * Check if a CRLF or end of data is in input buffer at current position + n.
+ * Return -1 if more data needed, 1 if CRLF or end of data, else 0.
+ */
+static int qp_lookahead_eol(mime_encoder_state *st, int ateof, size_t n)
+{
+  n += st->bufbeg;
+  if(n >= st->bufend && ateof)
+    return 1;
+  if(n + 2 > st->bufend)
+    return ateof? 0: -1;
+  if(qp_class[st->buf[n] & 0xFF] == QP_CR &&
+     qp_class[st->buf[n + 1] & 0xFF] == QP_LF)
+    return 1;
+  return 0;
+}
+
+/* Quoted-printable encoder. */
+static size_t encoder_qp_read(char *buffer, size_t size, bool ateof,
+                              curl_mimepart *part)
+{
+  mime_encoder_state *st = &part->encstate;
+  char *ptr = buffer;
+  size_t cursize = 0;
+  int i;
+  size_t len;
+  size_t consumed;
+  int softlinebreak;
+  char buf[4];
+
+  /* On all platforms, input is supposed to be ASCII compatible: for this
+     reason, we use hexadecimal ASCII codes in this function rather than
+     character constants that can be interpreted as non-ascii on some
+     platforms. Preserve ASCII encoding on output too. */
+  while(st->bufbeg < st->bufend) {
+    len = 1;
+    consumed = 1;
+    i = st->buf[st->bufbeg];
+    buf[0] = (char) i;
+    buf[1] = aschex[(i >> 4) & 0xF];
+    buf[2] = aschex[i & 0xF];
+
+    switch(qp_class[st->buf[st->bufbeg] & 0xFF]) {
+    case QP_OK:          /* Not a special character. */
+      break;
+    case QP_SP:          /* Space or tab. */
+      /* Spacing must be escaped if followed by CRLF. */
+      switch(qp_lookahead_eol(st, ateof, 1)) {
+      case -1:          /* More input data needed. */
+        return cursize;
+      case 0:           /* No encoding needed. */
+        break;
+      default:          /* CRLF after space or tab. */
+        buf[0] = '\x3D';    /* '=' */
+        len = 3;
+        break;
+      }
+      break;
+    case QP_CR:         /* Carriage return. */
+      /* If followed by a line-feed, output the CRLF pair.
+         Else escape it. */
+      switch(qp_lookahead_eol(st, ateof, 0)) {
+      case -1:          /* Need more data. */
+        return cursize;
+      case 1:           /* CRLF found. */
+        buf[len++] = '\x0A';    /* Append '\n'. */
+        consumed = 2;
+        break;
+      default:          /* Not followed by LF: escape. */
+        buf[0] = '\x3D';    /* '=' */
+        len = 3;
+        break;
+      }
+      break;
+    default:            /* Character must be escaped. */
+      buf[0] = '\x3D';    /* '=' */
+      len = 3;
+      break;
+    }
+
+    /* Be sure the encoded character fits within maximum line length. */
+    if(buf[len - 1] != '\x0A') {    /* '\n' */
+      softlinebreak = st->pos + len > MAX_ENCODED_LINE_LENGTH;
+      if(!softlinebreak && st->pos + len == MAX_ENCODED_LINE_LENGTH) {
+        /* We may use the current line only if end of data or followed by
+           a CRLF. */
+        switch(qp_lookahead_eol(st, ateof, consumed)) {
+        case -1:        /* Need more data. */
+          return cursize;
+          break;
+        case 0:         /* Not followed by a CRLF. */
+          softlinebreak = 1;
+          break;
+        }
+      }
+      if(softlinebreak) {
+        strcpy(buf, "\x3D\x0D\x0A");    /* "=\r\n" */
+        len = 3;
+        consumed = 0;
+      }
+    }
+
+    /* If the output buffer would overflow, do not store. */
+    if(len > size)
+      break;
+
+    /* Append to output buffer. */
+    memcpy(ptr, buf, len);
+    cursize += len;
+    ptr += len;
+    size -= len;
+    st->pos += len;
+    if(buf[len - 1] == '\x0A')    /* '\n' */
+      st->pos = 0;
+    st->bufbeg += consumed;
+  }
+
+  return cursize;
+}
+
+static curl_off_t encoder_qp_size(curl_mimepart *part)
+{
+  /* Determining the size can only be done by reading the data: unless the
+     data size is 0, we return it as unknown (-1). */
+  return part->datasize? -1: 0;
+}
+
+
+/* In-memory data callbacks. */
+/* Argument is a pointer to the mime part. */
+static size_t mime_mem_read(char *buffer, size_t size, size_t nitems,
+                            void *instream)
+{
+  curl_mimepart *part = (curl_mimepart *) instream;
+  size_t sz = (size_t) part->datasize - part->state.offset;
+  (void) size;   /* Always 1.*/
+
+  if(sz > nitems)
+    sz = nitems;
+
+  if(sz)
+    memcpy(buffer, (char *) &part->data[part->state.offset], sz);
+
+  part->state.offset += sz;
+  return sz;
+}
+
+static int mime_mem_seek(void *instream, curl_off_t offset, int whence)
+{
+  curl_mimepart *part = (curl_mimepart *) instream;
+
+  switch(whence) {
+  case SEEK_CUR:
+    offset += part->state.offset;
+    break;
+  case SEEK_END:
+    offset += part->datasize;
+    break;
+  }
+
+  if(offset < 0 || offset > part->datasize)
+    return CURL_SEEKFUNC_FAIL;
+
+  part->state.offset = (size_t) offset;
+  return CURL_SEEKFUNC_OK;
+}
+
+static void mime_mem_free(void *ptr)
+{
+  Curl_safefree(((curl_mimepart *) ptr)->data);
+}
+
+
+/* Named file callbacks. */
+/* Argument is a pointer to the mime part. */
+static int mime_open_file(curl_mimepart * part)
+{
+  /* Open a MIMEKIND_FILE part. */
+
+  if(part->fp)
+    return 0;
+  part->fp = fopen_read(part->data, "rb");
+  return part->fp? 0: -1;
+}
+
+static size_t mime_file_read(char *buffer, size_t size, size_t nitems,
+                             void *instream)
+{
+  curl_mimepart *part = (curl_mimepart *) instream;
+
+  if(mime_open_file(part))
+    return READ_ERROR;
+
+  return fread(buffer, size, nitems, part->fp);
+}
+
+static int mime_file_seek(void *instream, curl_off_t offset, int whence)
+{
+  curl_mimepart *part = (curl_mimepart *) instream;
+
+  if(whence == SEEK_SET && !offset && !part->fp)
+    return CURL_SEEKFUNC_OK;   /* Not open: implicitly already at BOF. */
+
+  if(mime_open_file(part))
+    return CURL_SEEKFUNC_FAIL;
+
+  return fseek(part->fp, (long) offset, whence)?
+               CURL_SEEKFUNC_CANTSEEK: CURL_SEEKFUNC_OK;
+}
+
+static void mime_file_free(void *ptr)
+{
+  curl_mimepart *part = (curl_mimepart *) ptr;
+
+  if(part->fp) {
+    fclose(part->fp);
+    part->fp = NULL;
+  }
+  Curl_safefree(part->data);
+  part->data = NULL;
+}
+
+
+/* Subparts callbacks. */
+/* Argument is a pointer to the mime structure. */
+
+/* Readback a byte string segment. */
+static size_t readback_bytes(mime_state *state,
+                             char *buffer, size_t bufsize,
+                             const char *bytes, size_t numbytes,
+                             const char *trail)
+{
+  size_t sz;
+
+  if(numbytes > state->offset) {
+    sz = numbytes - state->offset;
+    bytes += state->offset;
+  }
+  else {
+    size_t tsz = strlen(trail);
+
+    sz = state->offset - numbytes;
+    if(sz >= tsz)
+      return 0;
+    bytes = trail + sz;
+    sz = tsz - sz;
+  }
+
+  if(sz > bufsize)
+    sz = bufsize;
+
+  memcpy(buffer, bytes, sz);
+  state->offset += sz;
+  return sz;
+}
+
+/* Read a non-encoded part content. */
+static size_t read_part_content(curl_mimepart *part,
+                                char *buffer, size_t bufsize)
+{
+  size_t sz = 0;
+
+  if(part->readfunc)
+    sz = part->readfunc(buffer, 1, bufsize, part->arg);
+  return sz;
+}
+
+/* Read and encode part content. */
+static size_t read_encoded_part_content(curl_mimepart *part,
+                                        char *buffer, size_t bufsize)
+{
+  mime_encoder_state *st = &part->encstate;
+  size_t cursize = 0;
+  size_t sz;
+  bool ateof = FALSE;
+
+  while(bufsize) {
+    if(st->bufbeg < st->bufend || ateof) {
+      /* Encode buffered data. */
+      sz = part->encoder->encodefunc(buffer, bufsize, ateof, part);
+      switch(sz) {
+      case 0:
+        if(ateof)
+          return cursize;
+        break;
+      case CURL_READFUNC_ABORT:
+      case CURL_READFUNC_PAUSE:
+      case READ_ERROR:
+        return cursize? cursize: sz;
+      default:
+        cursize += sz;
+        buffer += sz;
+        bufsize -= sz;
+        continue;
+      }
+    }
+
+    /* We need more data in input buffer. */
+    if(st->bufbeg) {
+      size_t len = st->bufend - st->bufbeg;
+
+      if(len)
+        memmove(st->buf, st->buf + st->bufbeg, len);
+      st->bufbeg = 0;
+      st->bufend = len;
+    }
+    if(st->bufend >= sizeof st->buf)
+      return cursize? cursize: READ_ERROR;    /* Buffer full. */
+    sz = read_part_content(part, st->buf + st->bufend,
+                           sizeof st->buf - st->bufend);
+    switch(sz) {
+    case 0:
+      ateof = TRUE;
+      break;
+    case CURL_READFUNC_ABORT:
+    case CURL_READFUNC_PAUSE:
+    case READ_ERROR:
+      return cursize? cursize: sz;
+    default:
+      st->bufend += sz;
+      break;
+    }
+  }
+
+  return cursize;
+}
+
+/* Readback a mime part. */
+static size_t readback_part(curl_mimepart *part,
+                            char *buffer, size_t bufsize)
+{
+  size_t cursize = 0;
+  size_t sz;
+  struct curl_slist *hdr;
+#ifdef CURL_DOES_CONVERSIONS
+  char *convbuf = buffer;
+#endif
+
+  /* Readback from part. */
+
+  while(bufsize) {
+    sz = 0;
+    hdr = (struct curl_slist *) part->state.ptr;
+    switch(part->state.state) {
+    case MIMESTATE_BEGIN:
+      mimesetstate(&part->state, part->flags & MIME_BODY_ONLY? MIMESTATE_BODY:
+                                 MIMESTATE_CURLHEADERS, part->curlheaders);
+      break;
+    case MIMESTATE_USERHEADERS:
+      if(!hdr) {
+        mimesetstate(&part->state, MIMESTATE_EOH, NULL);
+        break;
+      }
+      if(match_header(hdr, "Content-Type", 12)) {
+        mimesetstate(&part->state, MIMESTATE_USERHEADERS, hdr->next);
+        break;
+      }
+      /* FALLTHROUGH */
+    case MIMESTATE_CURLHEADERS:
+      if(!hdr)
+        mimesetstate(&part->state, MIMESTATE_USERHEADERS, part->userheaders);
+      else {
+        sz = readback_bytes(&part->state, buffer, bufsize,
+                            hdr->data, strlen(hdr->data), "\r\n");
+        if(!sz)
+          mimesetstate(&part->state, part->state.state, hdr->next);
+      }
+      break;
+    case MIMESTATE_EOH:
+      sz = readback_bytes(&part->state, buffer, bufsize, "\r\n", 2, "");
+      if(!sz)
+        mimesetstate(&part->state, MIMESTATE_BODY, NULL);
+      break;
+    case MIMESTATE_BODY:
+#ifdef CURL_DOES_CONVERSIONS
+      if(part->easy && convbuf < buffer) {
+        CURLcode result = Curl_convert_to_network(part->easy, convbuf,
+                                                  buffer - convbuf);
+        if(result)
+          return READ_ERROR;
+        convbuf = buffer;
+      }
+#endif
+      cleanup_encoder_state(&part->encstate);
+      mimesetstate(&part->state, MIMESTATE_CONTENT, NULL);
+      break;
+    case MIMESTATE_CONTENT:
+      if(part->encoder)
+        sz = read_encoded_part_content(part, buffer, bufsize);
+      else
+        sz = read_part_content(part, buffer, bufsize);
+      switch(sz) {
+      case 0:
+        mimesetstate(&part->state, MIMESTATE_END, NULL);
+        /* Try sparing open file descriptors. */
+        if(part->kind == MIMEKIND_FILE && part->fp) {
+          fclose(part->fp);
+          part->fp = NULL;
+        }
+        /* FALLTHROUGH */
+      case CURL_READFUNC_ABORT:
+      case CURL_READFUNC_PAUSE:
+      case READ_ERROR:
+        return cursize? cursize: sz;
+      }
+      break;
+    case MIMESTATE_END:
+      return cursize;
+    default:
+      break;    /* Other values not in part state. */
+    }
+
+    /* Bump buffer and counters according to read size. */
+    cursize += sz;
+    buffer += sz;
+    bufsize -= sz;
+  }
+
+#ifdef CURL_DOES_CONVERSIONS
+      if(part->easy && convbuf < buffer &&
+         part->state.state < MIMESTATE_BODY) {
+        CURLcode result = Curl_convert_to_network(part->easy, convbuf,
+                                                  buffer - convbuf);
+        if(result)
+          return READ_ERROR;
+      }
+#endif
+
+  return cursize;
+}
+
+/* Readback from mime. */
+static size_t mime_subparts_read(char *buffer, size_t size, size_t nitems,
+                                 void *instream)
+{
+  curl_mime *mime = (curl_mime *) instream;
+  size_t cursize = 0;
+  size_t sz;
+  curl_mimepart *part;
+#ifdef CURL_DOES_CONVERSIONS
+  char *convbuf = buffer;
+#endif
+
+  (void) size;   /* Always 1. */
+
+  while(nitems) {
+    sz = 0;
+    part = mime->state.ptr;
+    switch(mime->state.state) {
+    case MIMESTATE_BEGIN:
+    case MIMESTATE_BODY:
+#ifdef CURL_DOES_CONVERSIONS
+      convbuf = buffer;
+#endif
+      mimesetstate(&mime->state, MIMESTATE_BOUNDARY1, mime->firstpart);
+      /* The first boundary always follows the header termination empty line,
+         so is always preceded by a CRLK. We can then spare 2 characters
+         by skipping the leading CRLF in boundary. */
+      mime->state.offset += 2;
+      break;
+    case MIMESTATE_BOUNDARY1:
+      sz = readback_bytes(&mime->state, buffer, nitems, "\r\n--", 4, "");
+      if(!sz)
+        mimesetstate(&mime->state, MIMESTATE_BOUNDARY2, part);
+      break;
+    case MIMESTATE_BOUNDARY2:
+      sz = readback_bytes(&mime->state, buffer, nitems, mime->boundary,
+                          strlen(mime->boundary), part? "\r\n": "--\r\n");
+      if(!sz) {
+#ifdef CURL_DOES_CONVERSIONS
+        if(mime->easy && convbuf < buffer) {
+          CURLcode result = Curl_convert_to_network(mime->easy, convbuf,
+                                                    buffer - convbuf);
+          if(result)
+            return READ_ERROR;
+          convbuf = buffer;
+        }
+#endif
+        mimesetstate(&mime->state, MIMESTATE_CONTENT, part);
+      }
+      break;
+    case MIMESTATE_CONTENT:
+      if(!part) {
+        mimesetstate(&mime->state, MIMESTATE_END, NULL);
+        break;
+      }
+      sz = readback_part(part, buffer, nitems);
+      switch(sz) {
+      case CURL_READFUNC_ABORT:
+      case CURL_READFUNC_PAUSE:
+      case READ_ERROR:
+        return cursize? cursize: sz;
+      case 0:
+#ifdef CURL_DOES_CONVERSIONS
+        convbuf = buffer;
+#endif
+        mimesetstate(&mime->state, MIMESTATE_BOUNDARY1, part->nextpart);
+        break;
+      }
+      break;
+    case MIMESTATE_END:
+      return cursize;
+    default:
+      break;    /* other values not used in mime state. */
+    }
+
+    /* Bump buffer and counters according to read size. */
+    cursize += sz;
+    buffer += sz;
+    nitems -= sz;
+  }
+
+#ifdef CURL_DOES_CONVERSIONS
+      if(mime->easy && convbuf < buffer &&
+         mime->state.state <= MIMESTATE_CONTENT) {
+        CURLcode result = Curl_convert_to_network(mime->easy, convbuf,
+                                                  buffer - convbuf);
+        if(result)
+          return READ_ERROR;
+      }
+#endif
+
+  return cursize;
+}
+
+static int mime_part_rewind(curl_mimepart *part)
+{
+  int res = CURL_SEEKFUNC_OK;
+  enum mimestate targetstate = MIMESTATE_BEGIN;
+
+  if(part->flags & MIME_BODY_ONLY)
+    targetstate = MIMESTATE_BODY;
+  cleanup_encoder_state(&part->encstate);
+  if(part->state.state > targetstate) {
+    res = CURL_SEEKFUNC_CANTSEEK;
+    if(part->seekfunc) {
+      res = part->seekfunc(part->arg, (curl_off_t) 0, SEEK_SET);
+      switch(res) {
+      case CURL_SEEKFUNC_OK:
+      case CURL_SEEKFUNC_FAIL:
+      case CURL_SEEKFUNC_CANTSEEK:
+        break;
+      case -1:    /* For fseek() error. */
+        res = CURL_SEEKFUNC_CANTSEEK;
+        break;
+      default:
+        res = CURL_SEEKFUNC_FAIL;
+        break;
+      }
+    }
+  }
+
+  if(res == CURL_SEEKFUNC_OK)
+    mimesetstate(&part->state, targetstate, NULL);
+
+  return res;
+}
+
+static int mime_subparts_seek(void *instream, curl_off_t offset, int whence)
+{
+  curl_mime *mime = (curl_mime *) instream;
+  curl_mimepart *part;
+  int result = CURL_SEEKFUNC_OK;
+  int res;
+
+  if(whence != SEEK_SET || offset)
+    return CURL_SEEKFUNC_CANTSEEK;    /* Only support full rewind. */
+
+  if(mime->state.state == MIMESTATE_BEGIN)
+   return CURL_SEEKFUNC_OK;           /* Already rewound. */
+
+  for(part = mime->firstpart; part; part = part->nextpart) {
+    res = mime_part_rewind(part);
+    if(res != CURL_SEEKFUNC_OK)
+      result = res;
+  }
+
+  if(result == CURL_SEEKFUNC_OK)
+    mimesetstate(&mime->state, MIMESTATE_BEGIN, NULL);
+
+  return result;
+}
+
+/* Release part content. */
+static void cleanup_part_content(curl_mimepart *part)
+{
+  if(part->freefunc)
+    part->freefunc(part->arg);
+
+  part->readfunc = NULL;
+  part->seekfunc = NULL;
+  part->freefunc = NULL;
+  part->arg = (void *) part;          /* Defaults to part itself. */
+  part->data = NULL;
+  part->fp = NULL;
+  part->datasize = (curl_off_t) 0;    /* No size yet. */
+  cleanup_encoder_state(&part->encstate);
+  part->kind = MIMEKIND_NONE;
+}
+
+static void mime_subparts_free(void *ptr)
+{
+  curl_mime *mime = (curl_mime *) ptr;
+
+  if(mime && mime->parent) {
+    mime->parent->freefunc = NULL;  /* Be sure we won't be called again. */
+    cleanup_part_content(mime->parent);  /* Avoid dangling pointer in part. */
+  }
+  curl_mime_free(mime);
+}
+
+/* Do not free subparts: unbind them. This is used for the top level only. */
+static void mime_subparts_unbind(void *ptr)
+{
+  curl_mime *mime = (curl_mime *) ptr;
+
+  if(mime && mime->parent) {
+    mime->parent->freefunc = NULL;  /* Be sure we won't be called again. */
+    cleanup_part_content(mime->parent);  /* Avoid dangling pointer in part. */
+    mime->parent = NULL;
+  }
+}
+
+
+void Curl_mime_cleanpart(curl_mimepart *part)
+{
+  cleanup_part_content(part);
+  curl_slist_free_all(part->curlheaders);
+  if(part->flags & MIME_USERHEADERS_OWNER)
+    curl_slist_free_all(part->userheaders);
+  Curl_safefree(part->mimetype);
+  Curl_safefree(part->name);
+  Curl_safefree(part->filename);
+  Curl_mime_initpart(part, part->easy);
+}
+
+/* Recursively delete a mime handle and its parts. */
+void curl_mime_free(curl_mime *mime)
+{
+  curl_mimepart *part;
+
+  if(mime) {
+    mime_subparts_unbind(mime);  /* Be sure it's not referenced anymore. */
+    while(mime->firstpart) {
+      part = mime->firstpart;
+      mime->firstpart = part->nextpart;
+      Curl_mime_cleanpart(part);
+      free(part);
+    }
+
+    free(mime->boundary);
+    free(mime);
+  }
+}
+
+/*
+ * Mime build functions.
+ */
+
+/* Create a mime handle. */
+curl_mime *curl_mime_init(struct Curl_easy *easy)
+{
+  curl_mime *mime;
+
+  mime = (curl_mime *) malloc(sizeof *mime);
+
+  if(mime) {
+    mime->easy = easy;
+    mime->parent = NULL;
+    mime->firstpart = NULL;
+    mime->lastpart = NULL;
+
+    /* Get a part boundary. */
+    mime->boundary = malloc(24 + MIME_RAND_BOUNDARY_CHARS + 1);
+    if(!mime->boundary) {
+      free(mime);
+      return NULL;
+    }
+
+    memset(mime->boundary, '-', 24);
+    Curl_rand_hex(easy, (unsigned char *) mime->boundary + 24,
+                  MIME_RAND_BOUNDARY_CHARS + 1);
+    mimesetstate(&mime->state, MIMESTATE_BEGIN, NULL);
+  }
+
+  return mime;
+}
+
+/* Initialize a mime part. */
+void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy)
+{
+  memset((char *) part, 0, sizeof *part);
+  part->easy = easy;
+  mimesetstate(&part->state, MIMESTATE_BEGIN, NULL);
+}
+
+/* Create a mime part and append it to a mime handle's part list. */
+curl_mimepart *curl_mime_addpart(curl_mime *mime)
+{
+  curl_mimepart *part;
+
+  if(!mime)
+    return NULL;
+
+  part = (curl_mimepart *) malloc(sizeof *part);
+
+  if(part) {
+    Curl_mime_initpart(part, mime->easy);
+    part->parent = mime;
+
+    if(mime->lastpart)
+      mime->lastpart->nextpart = part;
+    else
+      mime->firstpart = part;
+
+    mime->lastpart = part;
+  }
+
+  return part;
+}
+
+/* Set mime part name. */
+CURLcode curl_mime_name(curl_mimepart *part, const char *name)
+{
+  if(!part)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  Curl_safefree(part->name);
+  part->name = NULL;
+
+  if(name) {
+    part->name = strdup(name);
+    if(!part->name)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  return CURLE_OK;
+}
+
+/* Set mime part remote file name. */
+CURLcode curl_mime_filename(curl_mimepart *part, const char *filename)
+{
+  if(!part)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  Curl_safefree(part->filename);
+  part->filename = NULL;
+
+  if(filename) {
+    part->filename = strdup(filename);
+    if(!part->filename)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  return CURLE_OK;
+}
+
+/* Set mime part content from memory data. */
+CURLcode curl_mime_data(curl_mimepart *part,
+                        const char *data, size_t datasize)
+{
+  if(!part)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  cleanup_part_content(part);
+
+  if(data) {
+    if(datasize == CURL_ZERO_TERMINATED)
+      datasize = strlen(data);
+
+    part->data = malloc(datasize + 1);
+    if(!part->data)
+      return CURLE_OUT_OF_MEMORY;
+
+    part->datasize = datasize;
+
+    if(datasize)
+      memcpy(part->data, data, datasize);
+    part->data[datasize] = '\0';    /* Set a nul terminator as sentinel. */
+
+    part->readfunc = mime_mem_read;
+    part->seekfunc = mime_mem_seek;
+    part->freefunc = mime_mem_free;
+    part->kind = MIMEKIND_DATA;
+  }
+
+  return CURLE_OK;
+}
+
+/* Set mime part content from named local file. */
+CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename)
+{
+  CURLcode result = CURLE_OK;
+  char *base;
+
+  if(!part)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  cleanup_part_content(part);
+
+  if(filename) {
+    struct_stat sbuf;
+
+    if(stat(filename, &sbuf) || access(filename, R_OK))
+      result = CURLE_READ_ERROR;
+
+    part->data = strdup(filename);
+    if(!part->data)
+      result = CURLE_OUT_OF_MEMORY;
+
+    part->datasize = -1;
+    if(!result && S_ISREG(sbuf.st_mode)) {
+      part->datasize = filesize(filename, sbuf);
+      part->seekfunc = mime_file_seek;
+    }
+
+    part->readfunc = mime_file_read;
+    part->freefunc = mime_file_free;
+    part->kind = MIMEKIND_FILE;
+
+    /* As a side effect, set the filename to the current file's base name.
+       It is possible to withdraw this by explicitly calling
+       curl_mime_filename() with a NULL filename argument after the current
+       call. */
+    base = strippath(filename);
+    if(!base)
+      result = CURLE_OUT_OF_MEMORY;
+    else {
+      CURLcode res = curl_mime_filename(part, base);
+
+      if(res)
+        result = res;
+      free(base);
+    }
+  }
+  return result;
+}
+
+/* Set mime part type. */
+CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype)
+{
+  if(!part)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  Curl_safefree(part->mimetype);
+  part->mimetype = NULL;
+
+  if(mimetype) {
+    part->mimetype = strdup(mimetype);
+    if(!part->mimetype)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  return CURLE_OK;
+}
+
+/* Set mime data transfer encoder. */
+CURLcode curl_mime_encoder(curl_mimepart *part, const char *encoding)
+{
+  CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT;
+  const mime_encoder *mep;
+
+  if(!part)
+    return result;
+
+  part->encoder = NULL;
+
+  if(!encoding)
+    return CURLE_OK;    /* Removing current encoder. */
+
+  for(mep = encoders; mep->name; mep++)
+    if(strcasecompare(encoding, mep->name)) {
+      part->encoder = mep;
+      result = CURLE_OK;
+    }
+
+  return result;
+}
+
+/* Set mime part headers. */
+CURLcode curl_mime_headers(curl_mimepart *part,
+                           struct curl_slist *headers, int take_ownership)
+{
+  if(!part)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  if(part->flags & MIME_USERHEADERS_OWNER) {
+    if(part->userheaders != headers)  /* Allow setting twice the same list. */
+      curl_slist_free_all(part->userheaders);
+    part->flags &= ~MIME_USERHEADERS_OWNER;
+  }
+  part->userheaders = headers;
+  if(headers && take_ownership)
+    part->flags |= MIME_USERHEADERS_OWNER;
+  return CURLE_OK;
+}
+
+/* Set mime part content from callback. */
+CURLcode curl_mime_data_cb(curl_mimepart *part, curl_off_t datasize,
+                           curl_read_callback readfunc,
+                           curl_seek_callback seekfunc,
+                           curl_free_callback freefunc, void *arg)
+{
+  if(!part)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  cleanup_part_content(part);
+
+  if(readfunc) {
+    part->readfunc = readfunc;
+    part->seekfunc = seekfunc;
+    part->freefunc = freefunc;
+    part->arg = arg;
+    part->datasize = datasize;
+    part->kind = MIMEKIND_CALLBACK;
+  }
+
+  return CURLE_OK;
+}
+
+/* Set mime part content from subparts. */
+CURLcode Curl_mime_set_subparts(curl_mimepart *part,
+                                curl_mime *subparts, int take_ownership)
+{
+  curl_mime *root;
+
+  if(!part)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  /* Accept setting twice the same subparts. */
+  if(part->kind == MIMEKIND_MULTIPART && part->arg == subparts)
+    return CURLE_OK;
+
+  cleanup_part_content(part);
+
+  if(subparts) {
+    /* Must belong to the same data handle. */
+    if(part->easy && subparts->easy && part->easy != subparts->easy)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+
+    /* Should not have been attached already. */
+    if(subparts->parent)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+
+    /* Should not be the part's root. */
+    root = part->parent;
+    if(root) {
+      while(root->parent && root->parent->parent)
+        root = root->parent->parent;
+      if(subparts == root) {
+        if(part->easy)
+          failf(part->easy, "Can't add itself as a subpart!");
+        return CURLE_BAD_FUNCTION_ARGUMENT;
+      }
+    }
+
+    subparts->parent = part;
+    part->readfunc = mime_subparts_read;
+    part->seekfunc = mime_subparts_seek;
+    part->freefunc = take_ownership? mime_subparts_free: mime_subparts_unbind;
+    part->arg = subparts;
+    part->datasize = -1;
+    part->kind = MIMEKIND_MULTIPART;
+  }
+
+  return CURLE_OK;
+}
+
+CURLcode curl_mime_subparts(curl_mimepart *part, curl_mime *subparts)
+{
+  return Curl_mime_set_subparts(part, subparts, TRUE);
+}
+
+
+/* Readback from top mime. */
+/* Argument is the dummy top part. */
+size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream)
+{
+  curl_mimepart *part = (curl_mimepart *) instream;
+
+  (void) size;   /* Always 1. */
+  return readback_part(part, buffer, nitems);
+}
+
+/* Rewind mime stream. */
+CURLcode Curl_mime_rewind(curl_mimepart *part)
+{
+  return mime_part_rewind(part) == CURL_SEEKFUNC_OK?
+         CURLE_OK: CURLE_SEND_FAIL_REWIND;
+}
+
+/* Compute header list size. */
+static size_t slist_size(struct curl_slist *s,
+                         size_t overhead, const char *skip)
+{
+  size_t size = 0;
+  size_t skiplen = skip? strlen(skip): 0;
+
+  for(; s; s = s->next)
+    if(!skip || !match_header(s, skip, skiplen))
+      size += strlen(s->data) + overhead;
+  return size;
+}
+
+/* Get/compute multipart size. */
+static curl_off_t multipart_size(curl_mime *mime)
+{
+  curl_off_t size;
+  curl_off_t sz;
+  size_t boundarysize;
+  curl_mimepart *part;
+
+  if(!mime)
+    return 0;           /* Not present -> empty. */
+
+  boundarysize = 4 + strlen(mime->boundary) + 2;
+  size = boundarysize;  /* Final boundary - CRLF after headers. */
+
+  for(part = mime->firstpart; part; part = part->nextpart) {
+    sz = Curl_mime_size(part);
+
+    if(sz < 0)
+      size = sz;
+
+    if(size >= 0)
+      size += boundarysize + sz;
+  }
+
+  return size;
+}
+
+/* Get/compute mime size. */
+curl_off_t Curl_mime_size(curl_mimepart *part)
+{
+  curl_off_t size;
+
+  if(part->kind == MIMEKIND_MULTIPART)
+    part->datasize = multipart_size(part->arg);
+
+  size = part->datasize;
+
+  if(part->encoder)
+    size = part->encoder->sizefunc(part);
+
+  if(size >= 0 && !(part->flags & MIME_BODY_ONLY)) {
+    /* Compute total part size. */
+    size += slist_size(part->curlheaders, 2, NULL);
+    size += slist_size(part->userheaders, 2, "Content-Type");
+    size += 2;    /* CRLF after headers. */
+  }
+  return size;
+}
+
+/* Add a header. */
+/* VARARGS2 */
+CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...)
+{
+  struct curl_slist *hdr = NULL;
+  char *s = NULL;
+  va_list ap;
+
+  va_start(ap, fmt);
+  s = curl_mvaprintf(fmt, ap);
+  va_end(ap);
+
+  if(s) {
+    hdr = Curl_slist_append_nodup(*slp, s);
+    if(hdr)
+      *slp = hdr;
+    else
+      free(s);
+  }
+
+  return hdr? CURLE_OK: CURLE_OUT_OF_MEMORY;
+}
+
+/* Add a content type header. */
+static CURLcode add_content_type(struct curl_slist **slp,
+                                 const char *type, const char *boundary)
+{
+  return Curl_mime_add_header(slp, "Content-Type: %s%s%s", type,
+                              boundary? "; boundary=": "",
+                              boundary? boundary: "");
+}
+
+
+static const char *ContentTypeForFilename(const char *filename)
+{
+  unsigned int i;
+
+  /*
+   * If no content type was specified, we scan through a few well-known
+   * extensions and pick the first we match!
+   */
+  struct ContentType {
+    const char *extension;
+    const char *type;
+  };
+  static const struct ContentType ctts[] = {
+    {".gif",  "image/gif"},
+    {".jpg",  "image/jpeg"},
+    {".jpeg", "image/jpeg"},
+    {".png",  "image/png"},
+    {".svg",  "image/svg+xml"},
+    {".txt",  "text/plain"},
+    {".htm",  "text/html"},
+    {".html", "text/html"},
+    {".pdf",  "application/pdf"},
+    {".xml",  "application/xml"}
+  };
+
+  if(filename) {
+    size_t len1 = strlen(filename);
+    const char *nameend = filename + len1;
+
+    for(i = 0; i < sizeof ctts / sizeof ctts[0]; i++) {
+      size_t len2 = strlen(ctts[i].extension);
+
+      if(len1 >= len2 && strcasecompare(nameend - len2, ctts[i].extension))
+          return ctts[i].type;
+    }
+  }
+  return NULL;
+}
+
+CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
+                                   const char *contenttype,
+                                   const char *disposition,
+                                   enum mimestrategy strategy)
+{
+  curl_mime *mime = NULL;
+  const char *boundary = NULL;
+  char *customct;
+  const char *cte = NULL;
+  CURLcode ret = CURLE_OK;
+
+  /* Get rid of previously prepared headers. */
+  curl_slist_free_all(part->curlheaders);
+  part->curlheaders = NULL;
+
+  /* Be sure we won't access old headers later. */
+  if(part->state.state == MIMESTATE_CURLHEADERS)
+    mimesetstate(&part->state, MIMESTATE_CURLHEADERS, NULL);
+
+  /* Check if content type is specified. */
+  customct = part->mimetype;
+  if(!customct)
+    customct = search_header(part->userheaders, "Content-Type");
+  if(customct)
+    contenttype = customct;
+
+  /* If content type is not specified, try to determine it. */
+  if(!contenttype) {
+    switch(part->kind) {
+    case MIMEKIND_MULTIPART:
+      contenttype = MULTIPART_CONTENTTYPE_DEFAULT;
+      break;
+    case MIMEKIND_FILE:
+      contenttype = ContentTypeForFilename(part->filename);
+      if(!contenttype)
+        contenttype = ContentTypeForFilename(part->data);
+      if(!contenttype && part->filename)
+        contenttype = FILE_CONTENTTYPE_DEFAULT;
+      break;
+    default:
+      contenttype = ContentTypeForFilename(part->filename);
+      break;
+    }
+  }
+
+  if(part->kind == MIMEKIND_MULTIPART) {
+    mime = (curl_mime *) part->arg;
+    if(mime)
+      boundary = mime->boundary;
+  }
+  else if(contenttype && !customct &&
+          strcasecompare(contenttype, "text/plain"))
+    if(strategy == MIMESTRATEGY_MAIL || !part->filename)
+      contenttype = NULL;
+
+  /* Issue content-disposition header only if not already set by caller. */
+  if(!search_header(part->userheaders, "Content-Disposition")) {
+    if(!disposition)
+      if(part->filename || part->name ||
+        (contenttype && !strncasecompare(contenttype, "multipart/", 10)))
+          disposition = DISPOSITION_DEFAULT;
+    if(disposition && curl_strequal(disposition, "attachment") &&
+     !part->name && !part->filename)
+      disposition = NULL;
+    if(disposition) {
+      char *name = NULL;
+      char *filename = NULL;
+
+      if(part->name) {
+        name = escape_string(part->name);
+        if(!name)
+          ret = CURLE_OUT_OF_MEMORY;
+      }
+      if(!ret && part->filename) {
+        filename = escape_string(part->filename);
+        if(!filename)
+          ret = CURLE_OUT_OF_MEMORY;
+      }
+      if(!ret)
+        ret = Curl_mime_add_header(&part->curlheaders,
+                                   "Content-Disposition: %s%s%s%s%s%s%s",
+                                   disposition,
+                                   name? "; name=\"": "",
+                                   name? name: "",
+                                   name? "\"": "",
+                                   filename? "; filename=\"": "",
+                                   filename? filename: "",
+                                   filename? "\"": "");
+      Curl_safefree(name);
+      Curl_safefree(filename);
+      if(ret)
+        return ret;
+      }
+    }
+
+  /* Issue Content-Type header. */
+  if(contenttype) {
+    ret = add_content_type(&part->curlheaders, contenttype, boundary);
+    if(ret)
+      return ret;
+  }
+
+  /* Content-Transfer-Encoding header. */
+  if(!search_header(part->userheaders, "Content-Transfer-Encoding")) {
+    if(part->encoder)
+      cte = part->encoder->name;
+    else if(contenttype && strategy == MIMESTRATEGY_MAIL &&
+     part->kind != MIMEKIND_MULTIPART)
+      cte = "8bit";
+    if(cte) {
+      ret = Curl_mime_add_header(&part->curlheaders,
+                                 "Content-Transfer-Encoding: %s", cte);
+      if(ret)
+        return ret;
+    }
+  }
+
+  /* If we were reading curl-generated headers, restart with new ones (this
+     should not occur). */
+  if(part->state.state == MIMESTATE_CURLHEADERS)
+    mimesetstate(&part->state, MIMESTATE_CURLHEADERS, part->curlheaders);
+
+  /* Process subparts. */
+  if(part->kind == MIMEKIND_MULTIPART && mime) {
+    curl_mimepart *subpart;
+
+    disposition = NULL;
+    if(strcasecompare(contenttype, "multipart/form-data"))
+      disposition = "form-data";
+    for(subpart = mime->firstpart; subpart; subpart = subpart->nextpart) {
+      ret = Curl_mime_prepare_headers(subpart, NULL, disposition, strategy);
+      if(ret)
+        return ret;
+    }
+  }
+  return ret;
+}
+
+#else /* !CURL_DISABLE_HTTP || !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP */
+
+/* Mime not compiled in: define stubs for externally-referenced functions. */
+curl_mime *curl_mime_init(CURL *easy)
+{
+  (void) easy;
+  return NULL;
+}
+
+void curl_mime_free(curl_mime *mime)
+{
+  (void) mime;
+}
+
+curl_mimepart *curl_mime_addpart(curl_mime *mime)
+{
+  (void) mime;
+  return NULL;
+}
+
+CURLcode curl_mime_name(curl_mimepart *part, const char *name)
+{
+  (void) part;
+  (void) name;
+  return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode curl_mime_filename(curl_mimepart *part, const char *filename)
+{
+  (void) part;
+  (void) filename;
+  return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode curl_mime_type(curl_mimepart *part, const char *mimetype)
+{
+  (void) part;
+  (void) mimetype;
+  return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode curl_mime_encoder(curl_mimepart *part, const char *encoding)
+{
+  (void) part;
+  (void) encoding;
+  return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode curl_mime_data(curl_mimepart *part,
+                        const char *data, size_t datasize)
+{
+  (void) part;
+  (void) data;
+  (void) datasize;
+  return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode curl_mime_filedata(curl_mimepart *part, const char *filename)
+{
+  (void) part;
+  (void) filename;
+  return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode curl_mime_data_cb(curl_mimepart *part,
+                           curl_off_t datasize,
+                           curl_read_callback readfunc,
+                           curl_seek_callback seekfunc,
+                           curl_free_callback freefunc,
+                           void *arg)
+{
+  (void) part;
+  (void) datasize;
+  (void) readfunc;
+  (void) seekfunc;
+  (void) freefunc;
+  (void) arg;
+  return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode curl_mime_subparts(curl_mimepart *part, curl_mime *subparts)
+{
+  (void) part;
+  (void) subparts;
+  return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode curl_mime_headers(curl_mimepart *part,
+                           struct curl_slist *headers, int take_ownership)
+{
+  (void) part;
+  (void) headers;
+  (void) take_ownership;
+  return CURLE_NOT_BUILT_IN;
+}
+
+void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy)
+{
+  (void) part;
+  (void) easy;
+}
+
+void Curl_mime_cleanpart(curl_mimepart *part)
+{
+  (void) part;
+}
+
+CURLcode Curl_mime_set_subparts(curl_mimepart *part,
+                                curl_mime *subparts, int take_ownership)
+{
+  (void) part;
+  (void) subparts;
+  (void) take_ownership;
+  return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
+                                   const char *contenttype,
+                                   const char *disposition,
+                                   enum mimestrategy strategy)
+{
+  (void) part;
+  (void) contenttype;
+  (void) disposition;
+  (void) strategy;
+  return CURLE_NOT_BUILT_IN;
+}
+
+curl_off_t Curl_mime_size(curl_mimepart *part)
+{
+  (void) part;
+  return (curl_off_t) -1;
+}
+
+size_t Curl_mime_read(char *buffer, size_t size, size_t nitems, void *instream)
+{
+  (void) buffer;
+  (void) size;
+  (void) nitems;
+  (void) instream;
+  return 0;
+}
+
+CURLcode Curl_mime_rewind(curl_mimepart *part)
+{
+  (void) part;
+  return CURLE_NOT_BUILT_IN;
+}
+
+/* VARARGS2 */
+CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...)
+{
+  (void) slp;
+  (void) fmt;
+  return CURLE_NOT_BUILT_IN;
+}
+
+#endif /* !CURL_DISABLE_HTTP || !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/mime.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/mime.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/mime.h	(revision 331)
@@ -0,0 +1,137 @@
+#ifndef HEADER_CURL_MIME_H
+#define HEADER_CURL_MIME_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#define MIME_RAND_BOUNDARY_CHARS        16  /* Nb. of random boundary chars. */
+#define MAX_ENCODED_LINE_LENGTH         76  /* Maximum encoded line length. */
+#define ENCODING_BUFFER_SIZE            256 /* Encoding temp buffers size. */
+
+/* Part flags. */
+#define MIME_USERHEADERS_OWNER  (1 << 0)
+#define MIME_BODY_ONLY          (1 << 1)
+
+/* Part source kinds. */
+enum mimekind {
+  MIMEKIND_NONE = 0,            /* Part not set. */
+  MIMEKIND_DATA,                /* Allocated mime data. */
+  MIMEKIND_FILE,                /* Data from file. */
+  MIMEKIND_CALLBACK,            /* Data from `read' callback. */
+  MIMEKIND_MULTIPART,           /* Data is a mime subpart. */
+  MIMEKIND_LAST
+};
+
+/* Readback state tokens. */
+enum mimestate {
+  MIMESTATE_BEGIN,              /* Readback has not yet started. */
+  MIMESTATE_CURLHEADERS,        /* In curl-generated headers. */
+  MIMESTATE_USERHEADERS,        /* In caller's supplied headers. */
+  MIMESTATE_EOH,                /* End of headers. */
+  MIMESTATE_BODY,               /* Placeholder. */
+  MIMESTATE_BOUNDARY1,          /* In boundary prefix. */
+  MIMESTATE_BOUNDARY2,          /* In boundary. */
+  MIMESTATE_CONTENT,            /* In content. */
+  MIMESTATE_END,                /* End of part reached. */
+  MIMESTATE_LAST
+};
+
+/* Mime headers strategies. */
+enum mimestrategy {
+  MIMESTRATEGY_MAIL,            /* Mime mail. */
+  MIMESTRATEGY_FORM,            /* HTTP post form. */
+  MIMESTRATEGY_LAST
+};
+
+/* Content transfer encoder. */
+typedef struct {
+  const char *   name;          /* Encoding name. */
+  size_t         (*encodefunc)(char *buffer, size_t size, bool ateof,
+                             curl_mimepart *part);  /* Encoded read. */
+  curl_off_t     (*sizefunc)(curl_mimepart *part);  /* Encoded size. */
+}  mime_encoder;
+
+/* Content transfer encoder state. */
+typedef struct {
+  size_t         pos;           /* Position on output line. */
+  size_t         bufbeg;        /* Next data index in input buffer. */
+  size_t         bufend;        /* First unused byte index in input buffer. */
+  char           buf[ENCODING_BUFFER_SIZE]; /* Input buffer. */
+}  mime_encoder_state;
+
+/* Mime readback state. */
+typedef struct {
+  enum mimestate state;       /* Current state token. */
+  void *ptr;                  /* State-dependent pointer. */
+  size_t offset;              /* State-dependent offset. */
+}  mime_state;
+
+/* A mime multipart. */
+struct curl_mime_s {
+  struct Curl_easy *easy;          /* The associated easy handle. */
+  curl_mimepart *parent;           /* Parent part. */
+  curl_mimepart *firstpart;        /* First part. */
+  curl_mimepart *lastpart;         /* Last part. */
+  char *boundary;                  /* The part boundary. */
+  mime_state state;                /* Current readback state. */
+};
+
+/* A mime part. */
+struct curl_mimepart_s {
+  struct Curl_easy *easy;          /* The associated easy handle. */
+  curl_mime *parent;               /* Parent mime structure. */
+  curl_mimepart *nextpart;         /* Forward linked list. */
+  enum mimekind kind;              /* The part kind. */
+  char *data;                      /* Memory data or file name. */
+  curl_read_callback readfunc;     /* Read function. */
+  curl_seek_callback seekfunc;     /* Seek function. */
+  curl_free_callback freefunc;     /* Argument free function. */
+  void *arg;                       /* Argument to callback functions. */
+  FILE *fp;                        /* File pointer. */
+  struct curl_slist *curlheaders;  /* Part headers. */
+  struct curl_slist *userheaders;  /* Part headers. */
+  char *mimetype;                  /* Part mime type. */
+  char *filename;                  /* Remote file name. */
+  char *name;                      /* Data name. */
+  curl_off_t datasize;             /* Expected data size. */
+  unsigned int flags;              /* Flags. */
+  mime_state state;                /* Current readback state. */
+  const mime_encoder *encoder;     /* Content data encoder. */
+  mime_encoder_state encstate;     /* Data encoder state. */
+};
+
+
+/* Prototypes. */
+void Curl_mime_initpart(curl_mimepart *part, struct Curl_easy *easy);
+void Curl_mime_cleanpart(curl_mimepart *part);
+CURLcode Curl_mime_set_subparts(curl_mimepart *part,
+                                curl_mime *subparts, int take_ownership);
+CURLcode Curl_mime_prepare_headers(curl_mimepart *part,
+                                   const char *contenttype,
+                                   const char *disposition,
+                                   enum mimestrategy strategy);
+curl_off_t Curl_mime_size(curl_mimepart *part);
+size_t Curl_mime_read(char *buffer, size_t size, size_t nitems,
+                      void *instream);
+CURLcode Curl_mime_rewind(curl_mimepart *part);
+CURLcode Curl_mime_add_header(struct curl_slist **slp, const char *fmt, ...);
+
+#endif /* HEADER_CURL_MIME_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/mprintf.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/mprintf.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/mprintf.c	(revision 331)
@@ -0,0 +1,1173 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1999 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ *
+ * Purpose:
+ *  A merge of Bjorn Reese's format() function and Daniel's dsprintf()
+ *  1.0. A full blooded printf() clone with full support for <num>$
+ *  everywhere (parameters, widths and precisions) including variabled
+ *  sized parameters (like doubles, long longs, long doubles and even
+ *  void * in 64-bit architectures).
+ *
+ * Current restrictions:
+ * - Max 128 parameters
+ * - No 'long double' support.
+ *
+ * If you ever want truly portable and good *printf() clones, the project that
+ * took on from here is named 'Trio' and you find more details on the trio web
+ * page at https://daniel.haxx.se/projects/trio/
+ */
+
+#include "curl_setup.h"
+#include <curl/mprintf.h>
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * If SIZEOF_SIZE_T has not been defined, default to the size of long.
+ */
+
+#ifdef HAVE_LONGLONG
+#  define LONG_LONG_TYPE long long
+#  define HAVE_LONG_LONG_TYPE
+#else
+#  if defined(_MSC_VER) && (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)
+#    define LONG_LONG_TYPE __int64
+#    define HAVE_LONG_LONG_TYPE
+#  else
+#    undef LONG_LONG_TYPE
+#    undef HAVE_LONG_LONG_TYPE
+#  endif
+#endif
+
+/*
+ * Non-ANSI integer extensions
+ */
+
+#if (defined(__BORLANDC__) && (__BORLANDC__ >= 0x520)) || \
+    (defined(__WATCOMC__) && defined(__386__)) || \
+    (defined(__POCC__) && defined(_MSC_VER)) || \
+    (defined(_WIN32_WCE)) || \
+    (defined(__MINGW32__)) || \
+    (defined(_MSC_VER) && (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64))
+#  define MP_HAVE_INT_EXTENSIONS
+#endif
+
+/*
+ * Max integer data types that mprintf.c is capable
+ */
+
+#ifdef HAVE_LONG_LONG_TYPE
+#  define mp_intmax_t LONG_LONG_TYPE
+#  define mp_uintmax_t unsigned LONG_LONG_TYPE
+#else
+#  define mp_intmax_t long
+#  define mp_uintmax_t unsigned long
+#endif
+
+#define BUFFSIZE 326 /* buffer for long-to-str and float-to-str calcs, should
+                        fit negative DBL_MAX (317 letters) */
+#define MAX_PARAMETERS 128 /* lame static limit */
+
+#ifdef __AMIGA__
+# undef FORMAT_INT
+#endif
+
+/* Lower-case digits.  */
+static const char lower_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+/* Upper-case digits.  */
+static const char upper_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+#define OUTCHAR(x) \
+  do{ \
+    if(stream((unsigned char)(x), (FILE *)data) != -1) \
+      done++; \
+    else \
+     return done; /* return immediately on failure */ \
+  } WHILE_FALSE
+
+/* Data type to read from the arglist */
+typedef enum {
+  FORMAT_UNKNOWN = 0,
+  FORMAT_STRING,
+  FORMAT_PTR,
+  FORMAT_INT,
+  FORMAT_INTPTR,
+  FORMAT_LONG,
+  FORMAT_LONGLONG,
+  FORMAT_DOUBLE,
+  FORMAT_LONGDOUBLE,
+  FORMAT_WIDTH /* For internal use */
+} FormatType;
+
+/* conversion and display flags */
+enum {
+  FLAGS_NEW        = 0,
+  FLAGS_SPACE      = 1<<0,
+  FLAGS_SHOWSIGN   = 1<<1,
+  FLAGS_LEFT       = 1<<2,
+  FLAGS_ALT        = 1<<3,
+  FLAGS_SHORT      = 1<<4,
+  FLAGS_LONG       = 1<<5,
+  FLAGS_LONGLONG   = 1<<6,
+  FLAGS_LONGDOUBLE = 1<<7,
+  FLAGS_PAD_NIL    = 1<<8,
+  FLAGS_UNSIGNED   = 1<<9,
+  FLAGS_OCTAL      = 1<<10,
+  FLAGS_HEX        = 1<<11,
+  FLAGS_UPPER      = 1<<12,
+  FLAGS_WIDTH      = 1<<13, /* '*' or '*<num>$' used */
+  FLAGS_WIDTHPARAM = 1<<14, /* width PARAMETER was specified */
+  FLAGS_PREC       = 1<<15, /* precision was specified */
+  FLAGS_PRECPARAM  = 1<<16, /* precision PARAMETER was specified */
+  FLAGS_CHAR       = 1<<17, /* %c story */
+  FLAGS_FLOATE     = 1<<18, /* %e or %E */
+  FLAGS_FLOATG     = 1<<19  /* %g or %G */
+};
+
+typedef struct {
+  FormatType type;
+  int flags;
+  long width;     /* width OR width parameter number */
+  long precision; /* precision OR precision parameter number */
+  union {
+    char *str;
+    void *ptr;
+    union {
+      mp_intmax_t as_signed;
+      mp_uintmax_t as_unsigned;
+    } num;
+    double dnum;
+  } data;
+} va_stack_t;
+
+struct nsprintf {
+  char *buffer;
+  size_t length;
+  size_t max;
+};
+
+struct asprintf {
+  char *buffer; /* allocated buffer */
+  size_t len;   /* length of string */
+  size_t alloc; /* length of alloc */
+  int fail;     /* (!= 0) if an alloc has failed and thus
+                   the output is not the complete data */
+};
+
+static long dprintf_DollarString(char *input, char **end)
+{
+  int number = 0;
+  while(ISDIGIT(*input)) {
+    number *= 10;
+    number += *input-'0';
+    input++;
+  }
+  if(number && ('$'==*input++)) {
+    *end = input;
+    return number;
+  }
+  return 0;
+}
+
+static bool dprintf_IsQualifierNoDollar(const char *fmt)
+{
+#if defined(MP_HAVE_INT_EXTENSIONS)
+  if(!strncmp(fmt, "I32", 3) || !strncmp(fmt, "I64", 3)) {
+    return TRUE;
+  }
+#endif
+
+  switch(*fmt) {
+  case '-': case '+': case ' ': case '#': case '.':
+  case '0': case '1': case '2': case '3': case '4':
+  case '5': case '6': case '7': case '8': case '9':
+  case 'h': case 'l': case 'L': case 'z': case 'q':
+  case '*': case 'O':
+#if defined(MP_HAVE_INT_EXTENSIONS)
+  case 'I':
+#endif
+    return TRUE;
+
+  default:
+    return FALSE;
+  }
+}
+
+/******************************************************************
+ *
+ * Pass 1:
+ * Create an index with the type of each parameter entry and its
+ * value (may vary in size)
+ *
+ * Returns zero on success.
+ *
+ ******************************************************************/
+
+static int dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos,
+                         va_list arglist)
+{
+  char *fmt = (char *)format;
+  int param_num = 0;
+  long this_param;
+  long width;
+  long precision;
+  int flags;
+  long max_param = 0;
+  long i;
+
+  while(*fmt) {
+    if(*fmt++ == '%') {
+      if(*fmt == '%') {
+        fmt++;
+        continue; /* while */
+      }
+
+      flags = FLAGS_NEW;
+
+      /* Handle the positional case (N$) */
+
+      param_num++;
+
+      this_param = dprintf_DollarString(fmt, &fmt);
+      if(0 == this_param)
+        /* we got no positional, get the next counter */
+        this_param = param_num;
+
+      if(this_param > max_param)
+        max_param = this_param;
+
+      /*
+       * The parameter with number 'i' should be used. Next, we need
+       * to get SIZE and TYPE of the parameter. Add the information
+       * to our array.
+       */
+
+      width = 0;
+      precision = 0;
+
+      /* Handle the flags */
+
+      while(dprintf_IsQualifierNoDollar(fmt)) {
+#if defined(MP_HAVE_INT_EXTENSIONS)
+        if(!strncmp(fmt, "I32", 3)) {
+          flags |= FLAGS_LONG;
+          fmt += 3;
+        }
+        else if(!strncmp(fmt, "I64", 3)) {
+          flags |= FLAGS_LONGLONG;
+          fmt += 3;
+        }
+        else
+#endif
+
+        switch(*fmt++) {
+        case ' ':
+          flags |= FLAGS_SPACE;
+          break;
+        case '+':
+          flags |= FLAGS_SHOWSIGN;
+          break;
+        case '-':
+          flags |= FLAGS_LEFT;
+          flags &= ~FLAGS_PAD_NIL;
+          break;
+        case '#':
+          flags |= FLAGS_ALT;
+          break;
+        case '.':
+          if('*' == *fmt) {
+            /* The precision is picked from a specified parameter */
+
+            flags |= FLAGS_PRECPARAM;
+            fmt++;
+            param_num++;
+
+            i = dprintf_DollarString(fmt, &fmt);
+            if(i)
+              precision = i;
+            else
+              precision = param_num;
+
+            if(precision > max_param)
+              max_param = precision;
+          }
+          else {
+            flags |= FLAGS_PREC;
+            precision = strtol(fmt, &fmt, 10);
+          }
+          break;
+        case 'h':
+          flags |= FLAGS_SHORT;
+          break;
+#if defined(MP_HAVE_INT_EXTENSIONS)
+        case 'I':
+#if (SIZEOF_CURL_OFF_T > SIZEOF_LONG)
+          flags |= FLAGS_LONGLONG;
+#else
+          flags |= FLAGS_LONG;
+#endif
+          break;
+#endif
+        case 'l':
+          if(flags & FLAGS_LONG)
+            flags |= FLAGS_LONGLONG;
+          else
+            flags |= FLAGS_LONG;
+          break;
+        case 'L':
+          flags |= FLAGS_LONGDOUBLE;
+          break;
+        case 'q':
+          flags |= FLAGS_LONGLONG;
+          break;
+        case 'z':
+          /* the code below generates a warning if -Wunreachable-code is
+             used */
+#if (SIZEOF_SIZE_T > SIZEOF_LONG)
+          flags |= FLAGS_LONGLONG;
+#else
+          flags |= FLAGS_LONG;
+#endif
+          break;
+        case 'O':
+#if (SIZEOF_CURL_OFF_T > SIZEOF_LONG)
+          flags |= FLAGS_LONGLONG;
+#else
+          flags |= FLAGS_LONG;
+#endif
+          break;
+        case '0':
+          if(!(flags & FLAGS_LEFT))
+            flags |= FLAGS_PAD_NIL;
+          /* FALLTHROUGH */
+        case '1': case '2': case '3': case '4':
+        case '5': case '6': case '7': case '8': case '9':
+          flags |= FLAGS_WIDTH;
+          width = strtol(fmt-1, &fmt, 10);
+          break;
+        case '*':  /* Special case */
+          flags |= FLAGS_WIDTHPARAM;
+          param_num++;
+
+          i = dprintf_DollarString(fmt, &fmt);
+          if(i)
+            width = i;
+          else
+            width = param_num;
+          if(width > max_param)
+            max_param = width;
+          break;
+        default:
+          break;
+        }
+      } /* switch */
+
+      /* Handle the specifier */
+
+      i = this_param - 1;
+
+      if((i < 0) || (i >= MAX_PARAMETERS))
+        /* out of allowed range */
+        return 1;
+
+      switch (*fmt) {
+      case 'S':
+        flags |= FLAGS_ALT;
+        /* FALLTHROUGH */
+      case 's':
+        vto[i].type = FORMAT_STRING;
+        break;
+      case 'n':
+        vto[i].type = FORMAT_INTPTR;
+        break;
+      case 'p':
+        vto[i].type = FORMAT_PTR;
+        break;
+      case 'd': case 'i':
+        vto[i].type = FORMAT_INT;
+        break;
+      case 'u':
+        vto[i].type = FORMAT_INT;
+        flags |= FLAGS_UNSIGNED;
+        break;
+      case 'o':
+        vto[i].type = FORMAT_INT;
+        flags |= FLAGS_OCTAL;
+        break;
+      case 'x':
+        vto[i].type = FORMAT_INT;
+        flags |= FLAGS_HEX|FLAGS_UNSIGNED;
+        break;
+      case 'X':
+        vto[i].type = FORMAT_INT;
+        flags |= FLAGS_HEX|FLAGS_UPPER|FLAGS_UNSIGNED;
+        break;
+      case 'c':
+        vto[i].type = FORMAT_INT;
+        flags |= FLAGS_CHAR;
+        break;
+      case 'f':
+        vto[i].type = FORMAT_DOUBLE;
+        break;
+      case 'e':
+        vto[i].type = FORMAT_DOUBLE;
+        flags |= FLAGS_FLOATE;
+        break;
+      case 'E':
+        vto[i].type = FORMAT_DOUBLE;
+        flags |= FLAGS_FLOATE|FLAGS_UPPER;
+        break;
+      case 'g':
+        vto[i].type = FORMAT_DOUBLE;
+        flags |= FLAGS_FLOATG;
+        break;
+      case 'G':
+        vto[i].type = FORMAT_DOUBLE;
+        flags |= FLAGS_FLOATG|FLAGS_UPPER;
+        break;
+      default:
+        vto[i].type = FORMAT_UNKNOWN;
+        break;
+      } /* switch */
+
+      vto[i].flags = flags;
+      vto[i].width = width;
+      vto[i].precision = precision;
+
+      if(flags & FLAGS_WIDTHPARAM) {
+        /* we have the width specified from a parameter, so we make that
+           parameter's info setup properly */
+        long k = width - 1;
+        vto[i].width = k;
+        vto[k].type = FORMAT_WIDTH;
+        vto[k].flags = FLAGS_NEW;
+        /* can't use width or precision of width! */
+        vto[k].width = 0;
+        vto[k].precision = 0;
+      }
+      if(flags & FLAGS_PRECPARAM) {
+        /* we have the precision specified from a parameter, so we make that
+           parameter's info setup properly */
+        long k = precision - 1;
+        vto[i].precision = k;
+        vto[k].type = FORMAT_WIDTH;
+        vto[k].flags = FLAGS_NEW;
+        /* can't use width or precision of width! */
+        vto[k].width = 0;
+        vto[k].precision = 0;
+      }
+      *endpos++ = fmt + 1; /* end of this sequence */
+    }
+  }
+
+  /* Read the arg list parameters into our data list */
+  for(i = 0; i<max_param; i++) {
+    /* Width/precision arguments must be read before the main argument
+       they are attached to */
+    if(vto[i].flags & FLAGS_WIDTHPARAM) {
+      vto[vto[i].width].data.num.as_signed =
+        (mp_intmax_t)va_arg(arglist, int);
+    }
+    if(vto[i].flags & FLAGS_PRECPARAM) {
+      vto[vto[i].precision].data.num.as_signed =
+        (mp_intmax_t)va_arg(arglist, int);
+    }
+
+    switch(vto[i].type) {
+    case FORMAT_STRING:
+      vto[i].data.str = va_arg(arglist, char *);
+      break;
+
+    case FORMAT_INTPTR:
+    case FORMAT_UNKNOWN:
+    case FORMAT_PTR:
+      vto[i].data.ptr = va_arg(arglist, void *);
+      break;
+
+    case FORMAT_INT:
+#ifdef HAVE_LONG_LONG_TYPE
+      if((vto[i].flags & FLAGS_LONGLONG) && (vto[i].flags & FLAGS_UNSIGNED))
+        vto[i].data.num.as_unsigned =
+          (mp_uintmax_t)va_arg(arglist, mp_uintmax_t);
+      else if(vto[i].flags & FLAGS_LONGLONG)
+        vto[i].data.num.as_signed =
+          (mp_intmax_t)va_arg(arglist, mp_intmax_t);
+      else
+#endif
+      {
+        if((vto[i].flags & FLAGS_LONG) && (vto[i].flags & FLAGS_UNSIGNED))
+          vto[i].data.num.as_unsigned =
+            (mp_uintmax_t)va_arg(arglist, unsigned long);
+        else if(vto[i].flags & FLAGS_LONG)
+          vto[i].data.num.as_signed =
+            (mp_intmax_t)va_arg(arglist, long);
+        else if(vto[i].flags & FLAGS_UNSIGNED)
+          vto[i].data.num.as_unsigned =
+            (mp_uintmax_t)va_arg(arglist, unsigned int);
+        else
+          vto[i].data.num.as_signed =
+            (mp_intmax_t)va_arg(arglist, int);
+      }
+      break;
+
+    case FORMAT_DOUBLE:
+      vto[i].data.dnum = va_arg(arglist, double);
+      break;
+
+    case FORMAT_WIDTH:
+      /* Argument has been read. Silently convert it into an integer
+       * for later use
+       */
+      vto[i].type = FORMAT_INT;
+      break;
+
+    default:
+      break;
+    }
+  }
+
+  return 0;
+
+}
+
+static int dprintf_formatf(
+  void *data, /* untouched by format(), just sent to the stream() function in
+                 the second argument */
+  /* function pointer called for each output character */
+  int (*stream)(int, FILE *),
+  const char *format,    /* %-formatted string */
+  va_list ap_save) /* list of parameters */
+{
+  /* Base-36 digits for numbers.  */
+  const char *digits = lower_digits;
+
+  /* Pointer into the format string.  */
+  char *f;
+
+  /* Number of characters written.  */
+  int done = 0;
+
+  long param; /* current parameter to read */
+  long param_num = 0; /* parameter counter */
+
+  va_stack_t vto[MAX_PARAMETERS];
+  char *endpos[MAX_PARAMETERS];
+  char **end;
+
+  char work[BUFFSIZE];
+
+  va_stack_t *p;
+
+  /* 'workend' points to the final buffer byte position, but with an extra
+     byte as margin to avoid the (false?) warning Coverity gives us
+     otherwise */
+  char *workend = &work[sizeof(work) - 2];
+
+  /* Do the actual %-code parsing */
+  if(dprintf_Pass1(format, vto, endpos, ap_save))
+    return -1;
+
+  end = &endpos[0]; /* the initial end-position from the list dprintf_Pass1()
+                       created for us */
+
+  f = (char *)format;
+  while(*f != '\0') {
+    /* Format spec modifiers.  */
+    int is_alt;
+
+    /* Width of a field.  */
+    long width;
+
+    /* Precision of a field.  */
+    long prec;
+
+    /* Decimal integer is negative.  */
+    int is_neg;
+
+    /* Base of a number to be written.  */
+    unsigned long base;
+
+    /* Integral values to be written.  */
+    mp_uintmax_t num;
+
+    /* Used to convert negative in positive.  */
+    mp_intmax_t signed_num;
+
+    char *w;
+
+    if(*f != '%') {
+      /* This isn't a format spec, so write everything out until the next one
+         OR end of string is reached.  */
+      do {
+        OUTCHAR(*f);
+      } while(*++f && ('%' != *f));
+      continue;
+    }
+
+    ++f;
+
+    /* Check for "%%".  Note that although the ANSI standard lists
+       '%' as a conversion specifier, it says "The complete format
+       specification shall be `%%'," so we can avoid all the width
+       and precision processing.  */
+    if(*f == '%') {
+      ++f;
+      OUTCHAR('%');
+      continue;
+    }
+
+    /* If this is a positional parameter, the position must follow immediately
+       after the %, thus create a %<num>$ sequence */
+    param = dprintf_DollarString(f, &f);
+
+    if(!param)
+      param = param_num;
+    else
+      --param;
+
+    param_num++; /* increase this always to allow "%2$s %1$s %s" and then the
+                    third %s will pick the 3rd argument */
+
+    p = &vto[param];
+
+    /* pick up the specified width */
+    if(p->flags & FLAGS_WIDTHPARAM) {
+      width = (long)vto[p->width].data.num.as_signed;
+      param_num++; /* since the width is extracted from a parameter, we
+                      must skip that to get to the next one properly */
+      if(width < 0) {
+        /* "A negative field width is taken as a '-' flag followed by a
+           positive field width." */
+        width = -width;
+        p->flags |= FLAGS_LEFT;
+        p->flags &= ~FLAGS_PAD_NIL;
+      }
+    }
+    else
+      width = p->width;
+
+    /* pick up the specified precision */
+    if(p->flags & FLAGS_PRECPARAM) {
+      prec = (long)vto[p->precision].data.num.as_signed;
+      param_num++; /* since the precision is extracted from a parameter, we
+                      must skip that to get to the next one properly */
+      if(prec < 0)
+        /* "A negative precision is taken as if the precision were
+           omitted." */
+        prec = -1;
+    }
+    else if(p->flags & FLAGS_PREC)
+      prec = p->precision;
+    else
+      prec = -1;
+
+    is_alt = (p->flags & FLAGS_ALT) ? 1 : 0;
+
+    switch(p->type) {
+    case FORMAT_INT:
+      num = p->data.num.as_unsigned;
+      if(p->flags & FLAGS_CHAR) {
+        /* Character.  */
+        if(!(p->flags & FLAGS_LEFT))
+          while(--width > 0)
+            OUTCHAR(' ');
+        OUTCHAR((char) num);
+        if(p->flags & FLAGS_LEFT)
+          while(--width > 0)
+            OUTCHAR(' ');
+        break;
+      }
+      if(p->flags & FLAGS_OCTAL) {
+        /* Octal unsigned integer.  */
+        base = 8;
+        goto unsigned_number;
+      }
+      else if(p->flags & FLAGS_HEX) {
+        /* Hexadecimal unsigned integer.  */
+
+        digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
+        base = 16;
+        goto unsigned_number;
+      }
+      else if(p->flags & FLAGS_UNSIGNED) {
+        /* Decimal unsigned integer.  */
+        base = 10;
+        goto unsigned_number;
+      }
+
+      /* Decimal integer.  */
+      base = 10;
+
+      is_neg = (p->data.num.as_signed < (mp_intmax_t)0) ? 1 : 0;
+      if(is_neg) {
+        /* signed_num might fail to hold absolute negative minimum by 1 */
+        signed_num = p->data.num.as_signed + (mp_intmax_t)1;
+        signed_num = -signed_num;
+        num = (mp_uintmax_t)signed_num;
+        num += (mp_uintmax_t)1;
+      }
+
+      goto number;
+
+      unsigned_number:
+      /* Unsigned number of base BASE.  */
+      is_neg = 0;
+
+      number:
+      /* Number of base BASE.  */
+
+      /* Supply a default precision if none was given.  */
+      if(prec == -1)
+        prec = 1;
+
+      /* Put the number in WORK.  */
+      w = workend;
+      while(num > 0) {
+        *w-- = digits[num % base];
+        num /= base;
+      }
+      width -= (long)(workend - w);
+      prec -= (long)(workend - w);
+
+      if(is_alt && base == 8 && prec <= 0) {
+        *w-- = '0';
+        --width;
+      }
+
+      if(prec > 0) {
+        width -= prec;
+        while(prec-- > 0)
+          *w-- = '0';
+      }
+
+      if(is_alt && base == 16)
+        width -= 2;
+
+      if(is_neg || (p->flags & FLAGS_SHOWSIGN) || (p->flags & FLAGS_SPACE))
+        --width;
+
+      if(!(p->flags & FLAGS_LEFT) && !(p->flags & FLAGS_PAD_NIL))
+        while(width-- > 0)
+          OUTCHAR(' ');
+
+      if(is_neg)
+        OUTCHAR('-');
+      else if(p->flags & FLAGS_SHOWSIGN)
+        OUTCHAR('+');
+      else if(p->flags & FLAGS_SPACE)
+        OUTCHAR(' ');
+
+      if(is_alt && base == 16) {
+        OUTCHAR('0');
+        if(p->flags & FLAGS_UPPER)
+          OUTCHAR('X');
+        else
+          OUTCHAR('x');
+      }
+
+      if(!(p->flags & FLAGS_LEFT) && (p->flags & FLAGS_PAD_NIL))
+        while(width-- > 0)
+          OUTCHAR('0');
+
+      /* Write the number.  */
+      while(++w <= workend) {
+        OUTCHAR(*w);
+      }
+
+      if(p->flags & FLAGS_LEFT)
+        while(width-- > 0)
+          OUTCHAR(' ');
+      break;
+
+    case FORMAT_STRING:
+            /* String.  */
+      {
+        static const char null[] = "(nil)";
+        const char *str;
+        size_t len;
+
+        str = (char *) p->data.str;
+        if(str == NULL) {
+          /* Write null[] if there's space.  */
+          if(prec == -1 || prec >= (long) sizeof(null) - 1) {
+            str = null;
+            len = sizeof(null) - 1;
+            /* Disable quotes around (nil) */
+            p->flags &= (~FLAGS_ALT);
+          }
+          else {
+            str = "";
+            len = 0;
+          }
+        }
+        else if(prec != -1)
+          len = (size_t)prec;
+        else
+          len = strlen(str);
+
+        width -= (len > LONG_MAX) ? LONG_MAX : (long)len;
+
+        if(p->flags & FLAGS_ALT)
+          OUTCHAR('"');
+
+        if(!(p->flags&FLAGS_LEFT))
+          while(width-- > 0)
+            OUTCHAR(' ');
+
+        while((len-- > 0) && *str)
+          OUTCHAR(*str++);
+        if(p->flags&FLAGS_LEFT)
+          while(width-- > 0)
+            OUTCHAR(' ');
+
+        if(p->flags & FLAGS_ALT)
+          OUTCHAR('"');
+      }
+      break;
+
+    case FORMAT_PTR:
+      /* Generic pointer.  */
+      {
+        void *ptr;
+        ptr = (void *) p->data.ptr;
+        if(ptr != NULL) {
+          /* If the pointer is not NULL, write it as a %#x spec.  */
+          base = 16;
+          digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits;
+          is_alt = 1;
+          num = (size_t) ptr;
+          is_neg = 0;
+          goto number;
+        }
+        else {
+          /* Write "(nil)" for a nil pointer.  */
+          static const char strnil[] = "(nil)";
+          const char *point;
+
+          width -= (long)(sizeof(strnil) - 1);
+          if(p->flags & FLAGS_LEFT)
+            while(width-- > 0)
+              OUTCHAR(' ');
+          for(point = strnil; *point != '\0'; ++point)
+            OUTCHAR(*point);
+          if(! (p->flags & FLAGS_LEFT))
+            while(width-- > 0)
+              OUTCHAR(' ');
+        }
+      }
+      break;
+
+    case FORMAT_DOUBLE:
+      {
+        char formatbuf[32]="%";
+        char *fptr = &formatbuf[1];
+        size_t left = sizeof(formatbuf)-strlen(formatbuf);
+        int len;
+
+        width = -1;
+        if(p->flags & FLAGS_WIDTH)
+          width = p->width;
+        else if(p->flags & FLAGS_WIDTHPARAM)
+          width = (long)vto[p->width].data.num.as_signed;
+
+        prec = -1;
+        if(p->flags & FLAGS_PREC)
+          prec = p->precision;
+        else if(p->flags & FLAGS_PRECPARAM)
+          prec = (long)vto[p->precision].data.num.as_signed;
+
+        if(p->flags & FLAGS_LEFT)
+          *fptr++ = '-';
+        if(p->flags & FLAGS_SHOWSIGN)
+          *fptr++ = '+';
+        if(p->flags & FLAGS_SPACE)
+          *fptr++ = ' ';
+        if(p->flags & FLAGS_ALT)
+          *fptr++ = '#';
+
+        *fptr = 0;
+
+        if(width >= 0) {
+          if(width >= (long)sizeof(work))
+            width = sizeof(work)-1;
+          /* RECURSIVE USAGE */
+          len = curl_msnprintf(fptr, left, "%ld", width);
+          fptr += len;
+          left -= len;
+        }
+        if(prec >= 0) {
+          /* for each digit in the integer part, we can have one less
+             precision */
+          size_t maxprec = sizeof(work) - 2;
+          double val = p->data.dnum;
+          while(val >= 10.0) {
+            val /= 10;
+            maxprec--;
+          }
+
+          if(prec > (long)maxprec)
+            prec = (long)maxprec-1;
+          /* RECURSIVE USAGE */
+          len = curl_msnprintf(fptr, left, ".%ld", prec);
+          fptr += len;
+        }
+        if(p->flags & FLAGS_LONG)
+          *fptr++ = 'l';
+
+        if(p->flags & FLAGS_FLOATE)
+          *fptr++ = (char)((p->flags & FLAGS_UPPER) ? 'E':'e');
+        else if(p->flags & FLAGS_FLOATG)
+          *fptr++ = (char)((p->flags & FLAGS_UPPER) ? 'G' : 'g');
+        else
+          *fptr++ = 'f';
+
+        *fptr = 0; /* and a final zero termination */
+
+        /* NOTE NOTE NOTE!! Not all sprintf implementations return number of
+           output characters */
+        (sprintf)(work, formatbuf, p->data.dnum);
+        DEBUGASSERT(strlen(work) <= sizeof(work));
+        for(fptr = work; *fptr; fptr++)
+          OUTCHAR(*fptr);
+      }
+      break;
+
+    case FORMAT_INTPTR:
+      /* Answer the count of characters written.  */
+#ifdef HAVE_LONG_LONG_TYPE
+      if(p->flags & FLAGS_LONGLONG)
+        *(LONG_LONG_TYPE *) p->data.ptr = (LONG_LONG_TYPE)done;
+      else
+#endif
+        if(p->flags & FLAGS_LONG)
+          *(long *) p->data.ptr = (long)done;
+      else if(!(p->flags & FLAGS_SHORT))
+        *(int *) p->data.ptr = (int)done;
+      else
+        *(short *) p->data.ptr = (short)done;
+      break;
+
+    default:
+      break;
+    }
+    f = *end++; /* goto end of %-code */
+
+  }
+  return done;
+}
+
+/* fputc() look-alike */
+static int addbyter(int output, FILE *data)
+{
+  struct nsprintf *infop = (struct nsprintf *)data;
+  unsigned char outc = (unsigned char)output;
+
+  if(infop->length < infop->max) {
+    /* only do this if we haven't reached max length yet */
+    infop->buffer[0] = outc; /* store */
+    infop->buffer++; /* increase pointer */
+    infop->length++; /* we are now one byte larger */
+    return outc;     /* fputc() returns like this on success */
+  }
+  return -1;
+}
+
+int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format,
+                    va_list ap_save)
+{
+  int retcode;
+  struct nsprintf info;
+
+  info.buffer = buffer;
+  info.length = 0;
+  info.max = maxlength;
+
+  retcode = dprintf_formatf(&info, addbyter, format, ap_save);
+  if((retcode != -1) && info.max) {
+    /* we terminate this with a zero byte */
+    if(info.max == info.length)
+      /* we're at maximum, scrap the last letter */
+      info.buffer[-1] = 0;
+    else
+      info.buffer[0] = 0;
+  }
+  return retcode;
+}
+
+int curl_msnprintf(char *buffer, size_t maxlength, const char *format, ...)
+{
+  int retcode;
+  va_list ap_save; /* argument pointer */
+  va_start(ap_save, format);
+  retcode = curl_mvsnprintf(buffer, maxlength, format, ap_save);
+  va_end(ap_save);
+  return retcode;
+}
+
+/* fputc() look-alike */
+static int alloc_addbyter(int output, FILE *data)
+{
+  struct asprintf *infop = (struct asprintf *)data;
+  unsigned char outc = (unsigned char)output;
+
+  if(!infop->buffer) {
+    infop->buffer = malloc(32);
+    if(!infop->buffer) {
+      infop->fail = 1;
+      return -1; /* fail */
+    }
+    infop->alloc = 32;
+    infop->len = 0;
+  }
+  else if(infop->len + 1 >= infop->alloc) {
+    char *newptr = NULL;
+    size_t newsize = infop->alloc*2;
+
+    /* detect wrap-around or other overflow problems */
+    if(newsize > infop->alloc)
+      newptr = realloc(infop->buffer, newsize);
+
+    if(!newptr) {
+      infop->fail = 1;
+      return -1; /* fail */
+    }
+    infop->buffer = newptr;
+    infop->alloc = newsize;
+  }
+
+  infop->buffer[ infop->len ] = outc;
+
+  infop->len++;
+
+  return outc; /* fputc() returns like this on success */
+}
+
+char *curl_maprintf(const char *format, ...)
+{
+  va_list ap_save; /* argument pointer */
+  int retcode;
+  struct asprintf info;
+
+  info.buffer = NULL;
+  info.len = 0;
+  info.alloc = 0;
+  info.fail = 0;
+
+  va_start(ap_save, format);
+  retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
+  va_end(ap_save);
+  if((-1 == retcode) || info.fail) {
+    if(info.alloc)
+      free(info.buffer);
+    return NULL;
+  }
+  if(info.alloc) {
+    info.buffer[info.len] = 0; /* we terminate this with a zero byte */
+    return info.buffer;
+  }
+  return strdup("");
+}
+
+char *curl_mvaprintf(const char *format, va_list ap_save)
+{
+  int retcode;
+  struct asprintf info;
+
+  info.buffer = NULL;
+  info.len = 0;
+  info.alloc = 0;
+  info.fail = 0;
+
+  retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
+  if((-1 == retcode) || info.fail) {
+    if(info.alloc)
+      free(info.buffer);
+    return NULL;
+  }
+
+  if(info.alloc) {
+    info.buffer[info.len] = 0; /* we terminate this with a zero byte */
+    return info.buffer;
+  }
+  return strdup("");
+}
+
+static int storebuffer(int output, FILE *data)
+{
+  char **buffer = (char **)data;
+  unsigned char outc = (unsigned char)output;
+  **buffer = outc;
+  (*buffer)++;
+  return outc; /* act like fputc() ! */
+}
+
+int curl_msprintf(char *buffer, const char *format, ...)
+{
+  va_list ap_save; /* argument pointer */
+  int retcode;
+  va_start(ap_save, format);
+  retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save);
+  va_end(ap_save);
+  *buffer = 0; /* we terminate this with a zero byte */
+  return retcode;
+}
+
+int curl_mprintf(const char *format, ...)
+{
+  int retcode;
+  va_list ap_save; /* argument pointer */
+  va_start(ap_save, format);
+
+  retcode = dprintf_formatf(stdout, fputc, format, ap_save);
+  va_end(ap_save);
+  return retcode;
+}
+
+int curl_mfprintf(FILE *whereto, const char *format, ...)
+{
+  int retcode;
+  va_list ap_save; /* argument pointer */
+  va_start(ap_save, format);
+  retcode = dprintf_formatf(whereto, fputc, format, ap_save);
+  va_end(ap_save);
+  return retcode;
+}
+
+int curl_mvsprintf(char *buffer, const char *format, va_list ap_save)
+{
+  int retcode;
+  retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save);
+  *buffer = 0; /* we terminate this with a zero byte */
+  return retcode;
+}
+
+int curl_mvprintf(const char *format, va_list ap_save)
+{
+  return dprintf_formatf(stdout, fputc, format, ap_save);
+}
+
+int curl_mvfprintf(FILE *whereto, const char *format, va_list ap_save)
+{
+  return dprintf_formatf(whereto, fputc, format, ap_save);
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/multi.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/multi.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/multi.c	(revision 331)
@@ -0,0 +1,3114 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "transfer.h"
+#include "url.h"
+#include "connect.h"
+#include "progress.h"
+#include "easyif.h"
+#include "share.h"
+#include "multiif.h"
+#include "sendf.h"
+#include "timeval.h"
+#include "http.h"
+#include "select.h"
+#include "warnless.h"
+#include "speedcheck.h"
+#include "conncache.h"
+#include "multihandle.h"
+#include "pipeline.h"
+#include "sigpipe.h"
+#include "vtls/vtls.h"
+#include "connect.h"
+#include "http_proxy.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+  CURL_SOCKET_HASH_TABLE_SIZE should be a prime number. Increasing it from 97
+  to 911 takes on a 32-bit machine 4 x 804 = 3211 more bytes.  Still, every
+  CURL handle takes 45-50 K memory, therefore this 3K are not significant.
+*/
+#ifndef CURL_SOCKET_HASH_TABLE_SIZE
+#define CURL_SOCKET_HASH_TABLE_SIZE 911
+#endif
+
+#ifndef CURL_CONNECTION_HASH_SIZE
+#define CURL_CONNECTION_HASH_SIZE 97
+#endif
+
+#define CURL_MULTI_HANDLE 0x000bab1e
+
+#define GOOD_MULTI_HANDLE(x) \
+  ((x) && (x)->type == CURL_MULTI_HANDLE)
+
+static void singlesocket(struct Curl_multi *multi,
+                         struct Curl_easy *data);
+static int update_timer(struct Curl_multi *multi);
+
+static CURLMcode add_next_timeout(struct curltime now,
+                                  struct Curl_multi *multi,
+                                  struct Curl_easy *d);
+static CURLMcode multi_timeout(struct Curl_multi *multi,
+                               long *timeout_ms);
+
+#ifdef DEBUGBUILD
+static const char * const statename[]={
+  "INIT",
+  "CONNECT_PEND",
+  "CONNECT",
+  "WAITRESOLVE",
+  "WAITCONNECT",
+  "WAITPROXYCONNECT",
+  "SENDPROTOCONNECT",
+  "PROTOCONNECT",
+  "WAITDO",
+  "DO",
+  "DOING",
+  "DO_MORE",
+  "DO_DONE",
+  "WAITPERFORM",
+  "PERFORM",
+  "TOOFAST",
+  "DONE",
+  "COMPLETED",
+  "MSGSENT",
+};
+#endif
+
+/* function pointer called once when switching TO a state */
+typedef void (*init_multistate_func)(struct Curl_easy *data);
+
+/* always use this function to change state, to make debugging easier */
+static void mstate(struct Curl_easy *data, CURLMstate state
+#ifdef DEBUGBUILD
+                   , int lineno
+#endif
+)
+{
+  CURLMstate oldstate = data->mstate;
+  static const init_multistate_func finit[CURLM_STATE_LAST] = {
+    NULL,
+    NULL,
+    Curl_init_CONNECT, /* CONNECT */
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    Curl_connect_free /* DO */
+    /* the rest is NULL too */
+  };
+
+#if defined(DEBUGBUILD) && defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void) lineno;
+#endif
+
+  if(oldstate == state)
+    /* don't bother when the new state is the same as the old state */
+    return;
+
+  data->mstate = state;
+
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  if(data->mstate >= CURLM_STATE_CONNECT_PEND &&
+     data->mstate < CURLM_STATE_COMPLETED) {
+    long connection_id = -5000;
+
+    if(data->easy_conn)
+      connection_id = data->easy_conn->connection_id;
+
+    infof(data,
+          "STATE: %s => %s handle %p; line %d (connection #%ld)\n",
+          statename[oldstate], statename[data->mstate],
+          (void *)data, lineno, connection_id);
+  }
+#endif
+
+  if(state == CURLM_STATE_COMPLETED)
+    /* changing to COMPLETED means there's one less easy handle 'alive' */
+    data->multi->num_alive--;
+
+  /* if this state has an init-function, run it */
+  if(finit[state])
+    finit[state](data);
+}
+
+#ifndef DEBUGBUILD
+#define multistate(x,y) mstate(x,y)
+#else
+#define multistate(x,y) mstate(x,y, __LINE__)
+#endif
+
+/*
+ * We add one of these structs to the sockhash for a particular socket
+ */
+
+struct Curl_sh_entry {
+  struct Curl_easy *easy;
+  int action;  /* what action READ/WRITE this socket waits for */
+  curl_socket_t socket; /* mainly to ease debugging */
+  void *socketp; /* settable by users with curl_multi_assign() */
+};
+/* bits for 'action' having no bits means this socket is not expecting any
+   action */
+#define SH_READ  1
+#define SH_WRITE 2
+
+/* look up a given socket in the socket hash, skip invalid sockets */
+static struct Curl_sh_entry *sh_getentry(struct curl_hash *sh,
+                                         curl_socket_t s)
+{
+  if(s != CURL_SOCKET_BAD)
+    /* only look for proper sockets */
+    return Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t));
+  return NULL;
+}
+
+/* make sure this socket is present in the hash for this handle */
+static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh,
+                                         curl_socket_t s,
+                                         struct Curl_easy *data)
+{
+  struct Curl_sh_entry *there = sh_getentry(sh, s);
+  struct Curl_sh_entry *check;
+
+  if(there)
+    /* it is present, return fine */
+    return there;
+
+  /* not present, add it */
+  check = calloc(1, sizeof(struct Curl_sh_entry));
+  if(!check)
+    return NULL; /* major failure */
+
+  check->easy = data;
+  check->socket = s;
+
+  /* make/add new hash entry */
+  if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) {
+    free(check);
+    return NULL; /* major failure */
+  }
+
+  return check; /* things are good in sockhash land */
+}
+
+
+/* delete the given socket + handle from the hash */
+static void sh_delentry(struct curl_hash *sh, curl_socket_t s)
+{
+  /* We remove the hash entry. This will end up in a call to
+     sh_freeentry(). */
+  Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t));
+}
+
+/*
+ * free a sockhash entry
+ */
+static void sh_freeentry(void *freethis)
+{
+  struct Curl_sh_entry *p = (struct Curl_sh_entry *) freethis;
+
+  free(p);
+}
+
+static size_t fd_key_compare(void *k1, size_t k1_len, void *k2, size_t k2_len)
+{
+  (void) k1_len; (void) k2_len;
+
+  return (*((curl_socket_t *) k1)) == (*((curl_socket_t *) k2));
+}
+
+static size_t hash_fd(void *key, size_t key_length, size_t slots_num)
+{
+  curl_socket_t fd = *((curl_socket_t *) key);
+  (void) key_length;
+
+  return (fd % slots_num);
+}
+
+/*
+ * sh_init() creates a new socket hash and returns the handle for it.
+ *
+ * Quote from README.multi_socket:
+ *
+ * "Some tests at 7000 and 9000 connections showed that the socket hash lookup
+ * is somewhat of a bottle neck. Its current implementation may be a bit too
+ * limiting. It simply has a fixed-size array, and on each entry in the array
+ * it has a linked list with entries. So the hash only checks which list to
+ * scan through. The code I had used so for used a list with merely 7 slots
+ * (as that is what the DNS hash uses) but with 7000 connections that would
+ * make an average of 1000 nodes in each list to run through. I upped that to
+ * 97 slots (I believe a prime is suitable) and noticed a significant speed
+ * increase.  I need to reconsider the hash implementation or use a rather
+ * large default value like this. At 9000 connections I was still below 10us
+ * per call."
+ *
+ */
+static int sh_init(struct curl_hash *hash, int hashsize)
+{
+  return Curl_hash_init(hash, hashsize, hash_fd, fd_key_compare,
+                        sh_freeentry);
+}
+
+/*
+ * multi_addmsg()
+ *
+ * Called when a transfer is completed. Adds the given msg pointer to
+ * the list kept in the multi handle.
+ */
+static CURLMcode multi_addmsg(struct Curl_multi *multi,
+                              struct Curl_message *msg)
+{
+  Curl_llist_insert_next(&multi->msglist, multi->msglist.tail, msg,
+                         &msg->list);
+  return CURLM_OK;
+}
+
+/*
+ * multi_freeamsg()
+ *
+ * Callback used by the llist system when a single list entry is destroyed.
+ */
+static void multi_freeamsg(void *a, void *b)
+{
+  (void)a;
+  (void)b;
+}
+
+struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */
+                                     int chashsize) /* connection hash */
+{
+  struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi));
+
+  if(!multi)
+    return NULL;
+
+  multi->type = CURL_MULTI_HANDLE;
+
+  if(Curl_mk_dnscache(&multi->hostcache))
+    goto error;
+
+  if(sh_init(&multi->sockhash, hashsize))
+    goto error;
+
+  if(Curl_conncache_init(&multi->conn_cache, chashsize))
+    goto error;
+
+  Curl_llist_init(&multi->msglist, multi_freeamsg);
+  Curl_llist_init(&multi->pending, multi_freeamsg);
+
+  multi->max_pipeline_length = 5;
+
+  /* -1 means it not set by user, use the default value */
+  multi->maxconnects = -1;
+  return multi;
+
+  error:
+
+  Curl_hash_destroy(&multi->sockhash);
+  Curl_hash_destroy(&multi->hostcache);
+  Curl_conncache_destroy(&multi->conn_cache);
+  Curl_llist_destroy(&multi->msglist, NULL);
+  Curl_llist_destroy(&multi->pending, NULL);
+
+  free(multi);
+  return NULL;
+}
+
+struct Curl_multi *curl_multi_init(void)
+{
+  return Curl_multi_handle(CURL_SOCKET_HASH_TABLE_SIZE,
+                           CURL_CONNECTION_HASH_SIZE);
+}
+
+CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
+                                struct Curl_easy *data)
+{
+  /* First, make some basic checks that the CURLM handle is a good handle */
+  if(!GOOD_MULTI_HANDLE(multi))
+    return CURLM_BAD_HANDLE;
+
+  /* Verify that we got a somewhat good easy handle too */
+  if(!GOOD_EASY_HANDLE(data))
+    return CURLM_BAD_EASY_HANDLE;
+
+  /* Prevent users from adding same easy handle more than once and prevent
+     adding to more than one multi stack */
+  if(data->multi)
+    return CURLM_ADDED_ALREADY;
+
+  /* Initialize timeout list for this handle */
+  Curl_llist_init(&data->state.timeoutlist, NULL);
+
+  /*
+   * No failure allowed in this function beyond this point. And no
+   * modification of easy nor multi handle allowed before this except for
+   * potential multi's connection cache growing which won't be undone in this
+   * function no matter what.
+   */
+
+  /* set the easy handle */
+  multistate(data, CURLM_STATE_INIT);
+
+  if((data->set.global_dns_cache) &&
+     (data->dns.hostcachetype != HCACHE_GLOBAL)) {
+    /* global dns cache was requested but still isn't */
+    struct curl_hash *global = Curl_global_host_cache_init();
+    if(global) {
+      /* only do this if the global cache init works */
+      data->dns.hostcache = global;
+      data->dns.hostcachetype = HCACHE_GLOBAL;
+    }
+  }
+  /* for multi interface connections, we share DNS cache automatically if the
+     easy handle's one is currently not set. */
+  else if(!data->dns.hostcache ||
+     (data->dns.hostcachetype == HCACHE_NONE)) {
+    data->dns.hostcache = &multi->hostcache;
+    data->dns.hostcachetype = HCACHE_MULTI;
+  }
+
+  /* Point to the shared or multi handle connection cache */
+  if(data->share && (data->share->specifier & (1<< CURL_LOCK_DATA_CONNECT)))
+    data->state.conn_cache = &data->share->conn_cache;
+  else
+    data->state.conn_cache = &multi->conn_cache;
+
+  /* This adds the new entry at the 'end' of the doubly-linked circular
+     list of Curl_easy structs to try and maintain a FIFO queue so
+     the pipelined requests are in order. */
+
+  /* We add this new entry last in the list. */
+
+  data->next = NULL; /* end of the line */
+  if(multi->easyp) {
+    struct Curl_easy *last = multi->easylp;
+    last->next = data;
+    data->prev = last;
+    multi->easylp = data; /* the new last node */
+  }
+  else {
+    /* first node, make prev NULL! */
+    data->prev = NULL;
+    multi->easylp = multi->easyp = data; /* both first and last */
+  }
+
+  /* make the Curl_easy refer back to this multi handle */
+  data->multi = multi;
+
+  /* Set the timeout for this handle to expire really soon so that it will
+     be taken care of even when this handle is added in the midst of operation
+     when only the curl_multi_socket() API is used. During that flow, only
+     sockets that time-out or have actions will be dealt with. Since this
+     handle has no action yet, we make sure it times out to get things to
+     happen. */
+  Curl_expire(data, 0, EXPIRE_RUN_NOW);
+
+  /* increase the node-counter */
+  multi->num_easy++;
+
+  /* increase the alive-counter */
+  multi->num_alive++;
+
+  /* A somewhat crude work-around for a little glitch in update_timer() that
+     happens if the lastcall time is set to the same time when the handle is
+     removed as when the next handle is added, as then the check in
+     update_timer() that prevents calling the application multiple times with
+     the same timer infor will not trigger and then the new handle's timeout
+     will not be notified to the app.
+
+     The work-around is thus simply to clear the 'lastcall' variable to force
+     update_timer() to always trigger a callback to the app when a new easy
+     handle is added */
+  memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
+
+  /* The closure handle only ever has default timeouts set. To improve the
+     state somewhat we clone the timeouts from each added handle so that the
+     closure handle always has the same timeouts as the most recently added
+     easy handle. */
+  data->state.conn_cache->closure_handle->set.timeout = data->set.timeout;
+  data->state.conn_cache->closure_handle->set.server_response_timeout =
+    data->set.server_response_timeout;
+
+  update_timer(multi);
+  return CURLM_OK;
+}
+
+#if 0
+/* Debug-function, used like this:
+ *
+ * Curl_hash_print(multi->sockhash, debug_print_sock_hash);
+ *
+ * Enable the hash print function first by editing hash.c
+ */
+static void debug_print_sock_hash(void *p)
+{
+  struct Curl_sh_entry *sh = (struct Curl_sh_entry *)p;
+
+  fprintf(stderr, " [easy %p/magic %x/socket %d]",
+          (void *)sh->data, sh->data->magic, (int)sh->socket);
+}
+#endif
+
+/* Mark the connection as 'idle', or close it if the cache is full.
+   Returns TRUE if the connection is kept, or FALSE if it was closed. */
+static bool
+ConnectionDone(struct Curl_easy *data, struct connectdata *conn)
+{
+  /* data->multi->maxconnects can be negative, deal with it. */
+  size_t maxconnects =
+    (data->multi->maxconnects < 0) ? data->multi->num_easy * 4:
+    data->multi->maxconnects;
+  struct connectdata *conn_candidate = NULL;
+
+  /* Mark the current connection as 'unused' */
+  conn->inuse = FALSE;
+
+  if(maxconnects > 0 &&
+     data->state.conn_cache->num_connections > maxconnects) {
+    infof(data, "Connection cache is full, closing the oldest one.\n");
+
+    conn_candidate = Curl_conncache_oldest_idle(data);
+
+    if(conn_candidate) {
+      /* Set the connection's owner correctly */
+      conn_candidate->data = data;
+
+      /* the winner gets the honour of being disconnected */
+      (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
+    }
+  }
+
+  return (conn_candidate == conn) ? FALSE : TRUE;
+}
+
+static CURLcode multi_done(struct connectdata **connp,
+                          CURLcode status,  /* an error if this is called
+                                               after an error was detected */
+                          bool premature)
+{
+  CURLcode result;
+  struct connectdata *conn;
+  struct Curl_easy *data;
+  unsigned int i;
+
+  DEBUGASSERT(*connp);
+
+  conn = *connp;
+  data = conn->data;
+
+  DEBUGF(infof(data, "multi_done\n"));
+
+  if(data->state.done)
+    /* Stop if multi_done() has already been called */
+    return CURLE_OK;
+
+  Curl_getoff_all_pipelines(data, conn);
+
+  /* Cleanup possible redirect junk */
+  free(data->req.newurl);
+  data->req.newurl = NULL;
+  free(data->req.location);
+  data->req.location = NULL;
+
+  switch(status) {
+  case CURLE_ABORTED_BY_CALLBACK:
+  case CURLE_READ_ERROR:
+  case CURLE_WRITE_ERROR:
+    /* When we're aborted due to a callback return code it basically have to
+       be counted as premature as there is trouble ahead if we don't. We have
+       many callbacks and protocols work differently, we could potentially do
+       this more fine-grained in the future. */
+    premature = TRUE;
+  default:
+    break;
+  }
+
+  /* this calls the protocol-specific function pointer previously set */
+  if(conn->handler->done)
+    result = conn->handler->done(conn, status, premature);
+  else
+    result = status;
+
+  if(CURLE_ABORTED_BY_CALLBACK != result) {
+    /* avoid this if we already aborted by callback to avoid this calling
+       another callback */
+    CURLcode rc = Curl_pgrsDone(conn);
+    if(!result && rc)
+      result = CURLE_ABORTED_BY_CALLBACK;
+  }
+
+  if(conn->send_pipe.size + conn->recv_pipe.size != 0 &&
+     !data->set.reuse_forbid &&
+     !conn->bits.close) {
+    /* Stop if pipeline is not empty and we do not have to close
+       connection. */
+    data->easy_conn = NULL;
+    DEBUGF(infof(data, "Connection still in use, no more multi_done now!\n"));
+    return CURLE_OK;
+  }
+
+  data->state.done = TRUE; /* called just now! */
+  Curl_resolver_cancel(conn);
+
+  if(conn->dns_entry) {
+    Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
+    conn->dns_entry = NULL;
+  }
+
+  /* if the transfer was completed in a paused state there can be buffered
+     data left to free */
+  for(i = 0; i < data->state.tempcount; i++) {
+    free(data->state.tempwrite[i].buf);
+  }
+  data->state.tempcount = 0;
+
+  /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
+     forced us to close this connection. This is ignored for requests taking
+     place in a NTLM authentication handshake
+
+     if conn->bits.close is TRUE, it means that the connection should be
+     closed in spite of all our efforts to be nice, due to protocol
+     restrictions in our or the server's end
+
+     if premature is TRUE, it means this connection was said to be DONE before
+     the entire request operation is complete and thus we can't know in what
+     state it is for re-using, so we're forced to close it. In a perfect world
+     we can add code that keep track of if we really must close it here or not,
+     but currently we have no such detail knowledge.
+  */
+
+  if((data->set.reuse_forbid
+#if defined(USE_NTLM)
+      && !(conn->ntlm.state == NTLMSTATE_TYPE2 ||
+           conn->proxyntlm.state == NTLMSTATE_TYPE2)
+#endif
+     ) || conn->bits.close || premature) {
+    CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */
+
+    /* If we had an error already, make sure we return that one. But
+       if we got a new error, return that. */
+    if(!result && res2)
+      result = res2;
+  }
+  else {
+    /* the connection is no longer in use */
+    if(ConnectionDone(data, conn)) {
+      /* remember the most recently used connection */
+      data->state.lastconnect = conn;
+
+      infof(data, "Connection #%ld to host %s left intact\n",
+            conn->connection_id,
+            conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
+            conn->bits.httpproxy ? conn->http_proxy.host.dispname :
+            conn->bits.conn_to_host ? conn->conn_to_host.dispname :
+            conn->host.dispname);
+    }
+    else
+      data->state.lastconnect = NULL;
+  }
+
+  *connp = NULL; /* to make the caller of this function better detect that
+                    this was either closed or handed over to the connection
+                    cache here, and therefore cannot be used from this point on
+                 */
+  Curl_free_request_state(data);
+
+  return result;
+}
+
+CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
+                                   struct Curl_easy *data)
+{
+  struct Curl_easy *easy = data;
+  bool premature;
+  bool easy_owns_conn;
+  struct curl_llist_element *e;
+
+  /* First, make some basic checks that the CURLM handle is a good handle */
+  if(!GOOD_MULTI_HANDLE(multi))
+    return CURLM_BAD_HANDLE;
+
+  /* Verify that we got a somewhat good easy handle too */
+  if(!GOOD_EASY_HANDLE(data))
+    return CURLM_BAD_EASY_HANDLE;
+
+  /* Prevent users from trying to remove same easy handle more than once */
+  if(!data->multi)
+    return CURLM_OK; /* it is already removed so let's say it is fine! */
+
+  premature = (data->mstate < CURLM_STATE_COMPLETED) ? TRUE : FALSE;
+  easy_owns_conn = (data->easy_conn && (data->easy_conn->data == easy)) ?
+    TRUE : FALSE;
+
+  /* If the 'state' is not INIT or COMPLETED, we might need to do something
+     nice to put the easy_handle in a good known state when this returns. */
+  if(premature) {
+    /* this handle is "alive" so we need to count down the total number of
+       alive connections when this is removed */
+    multi->num_alive--;
+
+    /* When this handle gets removed, other handles may be able to get the
+       connection */
+    Curl_multi_process_pending_handles(multi);
+  }
+
+  if(data->easy_conn &&
+     data->mstate > CURLM_STATE_DO &&
+     data->mstate < CURLM_STATE_COMPLETED) {
+    /* Set connection owner so that the DONE function closes it.  We can
+       safely do this here since connection is killed. */
+    data->easy_conn->data = easy;
+    /* If the handle is in a pipeline and has started sending off its
+       request but not received its response yet, we need to close
+       connection. */
+    streamclose(data->easy_conn, "Removed with partial response");
+    easy_owns_conn = TRUE;
+  }
+
+  /* The timer must be shut down before data->multi is set to NULL,
+     else the timenode will remain in the splay tree after
+     curl_easy_cleanup is called. */
+  Curl_expire_clear(data);
+
+  if(data->easy_conn) {
+
+    /* we must call multi_done() here (if we still own the connection) so that
+       we don't leave a half-baked one around */
+    if(easy_owns_conn) {
+
+      /* multi_done() clears the conn->data field to lose the association
+         between the easy handle and the connection
+
+         Note that this ignores the return code simply because there's
+         nothing really useful to do with it anyway! */
+      (void)multi_done(&data->easy_conn, data->result, premature);
+    }
+    else
+      /* Clear connection pipelines, if multi_done above was not called */
+      Curl_getoff_all_pipelines(data, data->easy_conn);
+  }
+
+  if(data->dns.hostcachetype == HCACHE_MULTI) {
+    /* stop using the multi handle's DNS cache, *after* the possible
+       multi_done() call above */
+    data->dns.hostcache = NULL;
+    data->dns.hostcachetype = HCACHE_NONE;
+  }
+
+  Curl_wildcard_dtor(&data->wildcard);
+
+  /* destroy the timeout list that is held in the easy handle, do this *after*
+     multi_done() as that may actually call Curl_expire that uses this */
+  Curl_llist_destroy(&data->state.timeoutlist, NULL);
+
+  /* as this was using a shared connection cache we clear the pointer to that
+     since we're not part of that multi handle anymore */
+  data->state.conn_cache = NULL;
+
+  /* change state without using multistate(), only to make singlesocket() do
+     what we want */
+  data->mstate = CURLM_STATE_COMPLETED;
+  singlesocket(multi, easy); /* to let the application know what sockets that
+                                vanish with this handle */
+
+  /* Remove the association between the connection and the handle */
+  if(data->easy_conn) {
+    data->easy_conn->data = NULL;
+    data->easy_conn = NULL;
+  }
+
+  data->multi = NULL; /* clear the association to this multi handle */
+
+  /* make sure there's no pending message in the queue sent from this easy
+     handle */
+
+  for(e = multi->msglist.head; e; e = e->next) {
+    struct Curl_message *msg = e->ptr;
+
+    if(msg->extmsg.easy_handle == easy) {
+      Curl_llist_remove(&multi->msglist, e, NULL);
+      /* there can only be one from this specific handle */
+      break;
+    }
+  }
+
+  /* make the previous node point to our next */
+  if(data->prev)
+    data->prev->next = data->next;
+  else
+    multi->easyp = data->next; /* point to first node */
+
+  /* make our next point to our previous node */
+  if(data->next)
+    data->next->prev = data->prev;
+  else
+    multi->easylp = data->prev; /* point to last node */
+
+  /* NOTE NOTE NOTE
+     We do not touch the easy handle here! */
+  multi->num_easy--; /* one less to care about now */
+
+  update_timer(multi);
+  return CURLM_OK;
+}
+
+/* Return TRUE if the application asked for a certain set of pipelining */
+bool Curl_pipeline_wanted(const struct Curl_multi *multi, int bits)
+{
+  return (multi && (multi->pipelining & bits)) ? TRUE : FALSE;
+}
+
+void Curl_multi_handlePipeBreak(struct Curl_easy *data)
+{
+  data->easy_conn = NULL;
+}
+
+static int waitconnect_getsock(struct connectdata *conn,
+                               curl_socket_t *sock,
+                               int numsocks)
+{
+  int i;
+  int s = 0;
+  int rc = 0;
+
+  if(!numsocks)
+    return GETSOCK_BLANK;
+
+#ifdef USE_SSL
+  if(CONNECT_FIRSTSOCKET_PROXY_SSL())
+    return Curl_ssl_getsock(conn, sock, numsocks);
+#endif
+
+  for(i = 0; i<2; i++) {
+    if(conn->tempsock[i] != CURL_SOCKET_BAD) {
+      sock[s] = conn->tempsock[i];
+      rc |= GETSOCK_WRITESOCK(s++);
+    }
+  }
+
+  return rc;
+}
+
+static int waitproxyconnect_getsock(struct connectdata *conn,
+                                    curl_socket_t *sock,
+                                    int numsocks)
+{
+  if(!numsocks)
+    return GETSOCK_BLANK;
+
+  sock[0] = conn->sock[FIRSTSOCKET];
+
+  /* when we've sent a CONNECT to a proxy, we should rather wait for the
+     socket to become readable to be able to get the response headers */
+  if(conn->connect_state)
+    return GETSOCK_READSOCK(0);
+
+  return GETSOCK_WRITESOCK(0);
+}
+
+static int domore_getsock(struct connectdata *conn,
+                          curl_socket_t *socks,
+                          int numsocks)
+{
+  if(conn && conn->handler->domore_getsock)
+    return conn->handler->domore_getsock(conn, socks, numsocks);
+  return GETSOCK_BLANK;
+}
+
+/* returns bitmapped flags for this handle and its sockets */
+static int multi_getsock(struct Curl_easy *data,
+                         curl_socket_t *socks, /* points to numsocks number
+                                                  of sockets */
+                         int numsocks)
+{
+  /* If the pipe broke, or if there's no connection left for this easy handle,
+     then we MUST bail out now with no bitmask set. The no connection case can
+     happen when this is called from curl_multi_remove_handle() =>
+     singlesocket() => multi_getsock().
+  */
+  if(data->state.pipe_broke || !data->easy_conn)
+    return 0;
+
+  if(data->mstate > CURLM_STATE_CONNECT &&
+     data->mstate < CURLM_STATE_COMPLETED) {
+    /* Set up ownership correctly */
+    data->easy_conn->data = data;
+  }
+
+  switch(data->mstate) {
+  default:
+#if 0 /* switch back on these cases to get the compiler to check for all enums
+         to be present */
+  case CURLM_STATE_TOOFAST:  /* returns 0, so will not select. */
+  case CURLM_STATE_COMPLETED:
+  case CURLM_STATE_MSGSENT:
+  case CURLM_STATE_INIT:
+  case CURLM_STATE_CONNECT:
+  case CURLM_STATE_WAITDO:
+  case CURLM_STATE_DONE:
+  case CURLM_STATE_LAST:
+    /* this will get called with CURLM_STATE_COMPLETED when a handle is
+       removed */
+#endif
+    return 0;
+
+  case CURLM_STATE_WAITRESOLVE:
+    return Curl_resolver_getsock(data->easy_conn, socks, numsocks);
+
+  case CURLM_STATE_PROTOCONNECT:
+  case CURLM_STATE_SENDPROTOCONNECT:
+    return Curl_protocol_getsock(data->easy_conn, socks, numsocks);
+
+  case CURLM_STATE_DO:
+  case CURLM_STATE_DOING:
+    return Curl_doing_getsock(data->easy_conn, socks, numsocks);
+
+  case CURLM_STATE_WAITPROXYCONNECT:
+    return waitproxyconnect_getsock(data->easy_conn, socks, numsocks);
+
+  case CURLM_STATE_WAITCONNECT:
+    return waitconnect_getsock(data->easy_conn, socks, numsocks);
+
+  case CURLM_STATE_DO_MORE:
+    return domore_getsock(data->easy_conn, socks, numsocks);
+
+  case CURLM_STATE_DO_DONE: /* since is set after DO is completed, we switch
+                               to waiting for the same as the *PERFORM
+                               states */
+  case CURLM_STATE_PERFORM:
+  case CURLM_STATE_WAITPERFORM:
+    return Curl_single_getsock(data->easy_conn, socks, numsocks);
+  }
+
+}
+
+CURLMcode curl_multi_fdset(struct Curl_multi *multi,
+                           fd_set *read_fd_set, fd_set *write_fd_set,
+                           fd_set *exc_fd_set, int *max_fd)
+{
+  /* Scan through all the easy handles to get the file descriptors set.
+     Some easy handles may not have connected to the remote host yet,
+     and then we must make sure that is done. */
+  struct Curl_easy *data;
+  int this_max_fd = -1;
+  curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
+  int bitmap;
+  int i;
+  (void)exc_fd_set; /* not used */
+
+  if(!GOOD_MULTI_HANDLE(multi))
+    return CURLM_BAD_HANDLE;
+
+  data = multi->easyp;
+  while(data) {
+    bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
+
+    for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
+      curl_socket_t s = CURL_SOCKET_BAD;
+
+      if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK((sockbunch[i]))) {
+        FD_SET(sockbunch[i], read_fd_set);
+        s = sockbunch[i];
+      }
+      if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK((sockbunch[i]))) {
+        FD_SET(sockbunch[i], write_fd_set);
+        s = sockbunch[i];
+      }
+      if(s == CURL_SOCKET_BAD)
+        /* this socket is unused, break out of loop */
+        break;
+      if((int)s > this_max_fd)
+        this_max_fd = (int)s;
+    }
+
+    data = data->next; /* check next handle */
+  }
+
+  *max_fd = this_max_fd;
+
+  return CURLM_OK;
+}
+
+#define NUM_POLLS_ON_STACK 10
+
+CURLMcode curl_multi_wait(struct Curl_multi *multi,
+                          struct curl_waitfd extra_fds[],
+                          unsigned int extra_nfds,
+                          int timeout_ms,
+                          int *ret)
+{
+  struct Curl_easy *data;
+  curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE];
+  int bitmap;
+  unsigned int i;
+  unsigned int nfds = 0;
+  unsigned int curlfds;
+  struct pollfd *ufds = NULL;
+  bool ufds_malloc = FALSE;
+  long timeout_internal;
+  int retcode = 0;
+  struct pollfd a_few_on_stack[NUM_POLLS_ON_STACK];
+
+  if(!GOOD_MULTI_HANDLE(multi))
+    return CURLM_BAD_HANDLE;
+
+  /* If the internally desired timeout is actually shorter than requested from
+     the outside, then use the shorter time! But only if the internal timer
+     is actually larger than -1! */
+  (void)multi_timeout(multi, &timeout_internal);
+  if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms))
+    timeout_ms = (int)timeout_internal;
+
+  /* Count up how many fds we have from the multi handle */
+  data = multi->easyp;
+  while(data) {
+    bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
+
+    for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
+      curl_socket_t s = CURL_SOCKET_BAD;
+
+      if(bitmap & GETSOCK_READSOCK(i)) {
+        ++nfds;
+        s = sockbunch[i];
+      }
+      if(bitmap & GETSOCK_WRITESOCK(i)) {
+        ++nfds;
+        s = sockbunch[i];
+      }
+      if(s == CURL_SOCKET_BAD) {
+        break;
+      }
+    }
+
+    data = data->next; /* check next handle */
+  }
+
+  curlfds = nfds; /* number of internal file descriptors */
+  nfds += extra_nfds; /* add the externally provided ones */
+
+  if(nfds) {
+    if(nfds > NUM_POLLS_ON_STACK) {
+      /* 'nfds' is a 32 bit value and 'struct pollfd' is typically 8 bytes
+         big, so at 2^29 sockets this value might wrap. When a process gets
+         the capability to actually handle over 500 million sockets this
+         calculation needs a integer overflow check. */
+      ufds = malloc(nfds * sizeof(struct pollfd));
+      if(!ufds)
+        return CURLM_OUT_OF_MEMORY;
+      ufds_malloc = TRUE;
+    }
+    else
+      ufds = &a_few_on_stack[0];
+  }
+  nfds = 0;
+
+  /* only do the second loop if we found descriptors in the first stage run
+     above */
+
+  if(curlfds) {
+    /* Add the curl handles to our pollfds first */
+    data = multi->easyp;
+    while(data) {
+      bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE);
+
+      for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++) {
+        curl_socket_t s = CURL_SOCKET_BAD;
+
+        if(bitmap & GETSOCK_READSOCK(i)) {
+          ufds[nfds].fd = sockbunch[i];
+          ufds[nfds].events = POLLIN;
+          ++nfds;
+          s = sockbunch[i];
+        }
+        if(bitmap & GETSOCK_WRITESOCK(i)) {
+          ufds[nfds].fd = sockbunch[i];
+          ufds[nfds].events = POLLOUT;
+          ++nfds;
+          s = sockbunch[i];
+        }
+        if(s == CURL_SOCKET_BAD) {
+          break;
+        }
+      }
+
+      data = data->next; /* check next handle */
+    }
+  }
+
+  /* Add external file descriptions from poll-like struct curl_waitfd */
+  for(i = 0; i < extra_nfds; i++) {
+    ufds[nfds].fd = extra_fds[i].fd;
+    ufds[nfds].events = 0;
+    if(extra_fds[i].events & CURL_WAIT_POLLIN)
+      ufds[nfds].events |= POLLIN;
+    if(extra_fds[i].events & CURL_WAIT_POLLPRI)
+      ufds[nfds].events |= POLLPRI;
+    if(extra_fds[i].events & CURL_WAIT_POLLOUT)
+      ufds[nfds].events |= POLLOUT;
+    ++nfds;
+  }
+
+  if(nfds) {
+    int pollrc;
+    /* wait... */
+    pollrc = Curl_poll(ufds, nfds, timeout_ms);
+    DEBUGF(infof(data, "Curl_poll(%d ds, %d ms) == %d\n",
+                 nfds, timeout_ms, pollrc));
+
+    if(pollrc > 0) {
+      retcode = pollrc;
+      /* copy revents results from the poll to the curl_multi_wait poll
+         struct, the bit values of the actual underlying poll() implementation
+         may not be the same as the ones in the public libcurl API! */
+      for(i = 0; i < extra_nfds; i++) {
+        unsigned short mask = 0;
+        unsigned r = ufds[curlfds + i].revents;
+
+        if(r & POLLIN)
+          mask |= CURL_WAIT_POLLIN;
+        if(r & POLLOUT)
+          mask |= CURL_WAIT_POLLOUT;
+        if(r & POLLPRI)
+          mask |= CURL_WAIT_POLLPRI;
+
+        extra_fds[i].revents = mask;
+      }
+    }
+  }
+
+  if(ufds_malloc)
+    free(ufds);
+  if(ret)
+    *ret = retcode;
+  return CURLM_OK;
+}
+
+/*
+ * Curl_multi_connchanged() is called to tell that there is a connection in
+ * this multi handle that has changed state (pipelining become possible, the
+ * number of allowed streams changed or similar), and a subsequent use of this
+ * multi handle should move CONNECT_PEND handles back to CONNECT to have them
+ * retry.
+ */
+void Curl_multi_connchanged(struct Curl_multi *multi)
+{
+  multi->recheckstate = TRUE;
+}
+
+/*
+ * multi_ischanged() is called
+ *
+ * Returns TRUE/FALSE whether the state is changed to trigger a CONNECT_PEND
+ * => CONNECT action.
+ *
+ * Set 'clear' to TRUE to have it also clear the state variable.
+ */
+static bool multi_ischanged(struct Curl_multi *multi, bool clear)
+{
+  bool retval = multi->recheckstate;
+  if(clear)
+    multi->recheckstate = FALSE;
+  return retval;
+}
+
+CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
+                                 struct Curl_easy *data,
+                                 struct connectdata *conn)
+{
+  CURLMcode rc;
+
+  rc = curl_multi_add_handle(multi, data);
+  if(!rc) {
+    struct SingleRequest *k = &data->req;
+
+    /* pass in NULL for 'conn' here since we don't want to init the
+       connection, only this transfer */
+    Curl_init_do(data, NULL);
+
+    /* take this handle to the perform state right away */
+    multistate(data, CURLM_STATE_PERFORM);
+    data->easy_conn = conn;
+    k->keepon |= KEEP_RECV; /* setup to receive! */
+  }
+  return rc;
+}
+
+static CURLcode multi_reconnect_request(struct connectdata **connp)
+{
+  CURLcode result = CURLE_OK;
+  struct connectdata *conn = *connp;
+  struct Curl_easy *data = conn->data;
+
+  /* This was a re-use of a connection and we got a write error in the
+   * DO-phase. Then we DISCONNECT this connection and have another attempt to
+   * CONNECT and then DO again! The retry cannot possibly find another
+   * connection to re-use, since we only keep one possible connection for
+   * each.  */
+
+  infof(data, "Re-used connection seems dead, get a new one\n");
+
+  connclose(conn, "Reconnect dead connection"); /* enforce close */
+  result = multi_done(&conn, result, FALSE); /* we are so done with this */
+
+  /* conn may no longer be a good pointer, clear it to avoid mistakes by
+     parent functions */
+  *connp = NULL;
+
+  /*
+   * We need to check for CURLE_SEND_ERROR here as well. This could happen
+   * when the request failed on a FTP connection and thus multi_done() itself
+   * tried to use the connection (again).
+   */
+  if(!result || (CURLE_SEND_ERROR == result)) {
+    bool async;
+    bool protocol_done = TRUE;
+
+    /* Now, redo the connect and get a new connection */
+    result = Curl_connect(data, connp, &async, &protocol_done);
+    if(!result) {
+      /* We have connected or sent away a name resolve query fine */
+
+      conn = *connp; /* setup conn to again point to something nice */
+      if(async) {
+        /* Now, if async is TRUE here, we need to wait for the name
+           to resolve */
+        result = Curl_resolver_wait_resolv(conn, NULL);
+        if(result)
+          return result;
+
+        /* Resolved, continue with the connection */
+        result = Curl_async_resolved(conn, &protocol_done);
+        if(result)
+          return result;
+      }
+    }
+  }
+
+  return result;
+}
+
+/*
+ * do_complete is called when the DO actions are complete.
+ *
+ * We init chunking and trailer bits to their default values here immediately
+ * before receiving any header data for the current request in the pipeline.
+ */
+static void do_complete(struct connectdata *conn)
+{
+  conn->data->req.chunk = FALSE;
+  conn->data->req.maxfd = (conn->sockfd>conn->writesockfd?
+                           conn->sockfd:conn->writesockfd) + 1;
+  Curl_pgrsTime(conn->data, TIMER_PRETRANSFER);
+}
+
+static CURLcode multi_do(struct connectdata **connp, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct connectdata *conn = *connp;
+  struct Curl_easy *data = conn->data;
+
+  if(conn->handler->do_it) {
+    /* generic protocol-specific function pointer set in curl_connect() */
+    result = conn->handler->do_it(conn, done);
+
+    /* This was formerly done in transfer.c, but we better do it here */
+    if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
+      /*
+       * If the connection is using an easy handle, call reconnect
+       * to re-establish the connection.  Otherwise, let the multi logic
+       * figure out how to re-establish the connection.
+       */
+      if(!data->multi) {
+        result = multi_reconnect_request(connp);
+
+        if(!result) {
+          /* ... finally back to actually retry the DO phase */
+          conn = *connp; /* re-assign conn since multi_reconnect_request
+                            creates a new connection */
+          result = conn->handler->do_it(conn, done);
+        }
+      }
+      else
+        return result;
+    }
+
+    if(!result && *done)
+      /* do_complete must be called after the protocol-specific DO function */
+      do_complete(conn);
+  }
+  return result;
+}
+
+/*
+ * multi_do_more() is called during the DO_MORE multi state. It is basically a
+ * second stage DO state which (wrongly) was introduced to support FTP's
+ * second connection.
+ *
+ * TODO: A future libcurl should be able to work away this state.
+ *
+ * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to
+ * DOING state there's more work to do!
+ */
+
+static CURLcode multi_do_more(struct connectdata *conn, int *complete)
+{
+  CURLcode result = CURLE_OK;
+
+  *complete = 0;
+
+  if(conn->handler->do_more)
+    result = conn->handler->do_more(conn, complete);
+
+  if(!result && (*complete == 1))
+    /* do_complete must be called after the protocol-specific DO function */
+    do_complete(conn);
+
+  return result;
+}
+
+static CURLMcode multi_runsingle(struct Curl_multi *multi,
+                                 struct curltime now,
+                                 struct Curl_easy *data)
+{
+  struct Curl_message *msg = NULL;
+  bool connected;
+  bool async;
+  bool protocol_connect = FALSE;
+  bool dophase_done = FALSE;
+  bool done = FALSE;
+  CURLMcode rc;
+  CURLcode result = CURLE_OK;
+  struct SingleRequest *k;
+  time_t timeout_ms;
+  time_t recv_timeout_ms;
+  timediff_t send_timeout_ms;
+  int control;
+
+  if(!GOOD_EASY_HANDLE(data))
+    return CURLM_BAD_EASY_HANDLE;
+
+  do {
+    /* A "stream" here is a logical stream if the protocol can handle that
+       (HTTP/2), or the full connection for older protocols */
+    bool stream_error = FALSE;
+    rc = CURLM_OK;
+
+    /* Handle the case when the pipe breaks, i.e., the connection
+       we're using gets cleaned up and we're left with nothing. */
+    if(data->state.pipe_broke) {
+      infof(data, "Pipe broke: handle %p, url = %s\n",
+            (void *)data, data->state.path);
+
+      if(data->mstate < CURLM_STATE_COMPLETED) {
+        /* Head back to the CONNECT state */
+        multistate(data, CURLM_STATE_CONNECT);
+        rc = CURLM_CALL_MULTI_PERFORM;
+        result = CURLE_OK;
+      }
+
+      data->state.pipe_broke = FALSE;
+      data->easy_conn = NULL;
+      continue;
+    }
+
+    if(!data->easy_conn &&
+       data->mstate > CURLM_STATE_CONNECT &&
+       data->mstate < CURLM_STATE_DONE) {
+      /* In all these states, the code will blindly access 'data->easy_conn'
+         so this is precaution that it isn't NULL. And it silences static
+         analyzers. */
+      failf(data, "In state %d with no easy_conn, bail out!\n", data->mstate);
+      return CURLM_INTERNAL_ERROR;
+    }
+
+    if(multi_ischanged(multi, TRUE)) {
+      DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!\n"));
+      Curl_multi_process_pending_handles(multi);
+    }
+
+    if(data->easy_conn && data->mstate > CURLM_STATE_CONNECT &&
+       data->mstate < CURLM_STATE_COMPLETED)
+      /* Make sure we set the connection's current owner */
+      data->easy_conn->data = data;
+
+    if(data->easy_conn &&
+       (data->mstate >= CURLM_STATE_CONNECT) &&
+       (data->mstate < CURLM_STATE_COMPLETED)) {
+      /* we need to wait for the connect state as only then is the start time
+         stored, but we must not check already completed handles */
+
+      timeout_ms = Curl_timeleft(data, &now,
+                                 (data->mstate <= CURLM_STATE_WAITDO)?
+                                 TRUE:FALSE);
+
+      if(timeout_ms < 0) {
+        /* Handle timed out */
+        if(data->mstate == CURLM_STATE_WAITRESOLVE)
+          failf(data, "Resolving timed out after %ld milliseconds",
+                Curl_timediff(now, data->progress.t_startsingle));
+        else if(data->mstate == CURLM_STATE_WAITCONNECT)
+          failf(data, "Connection timed out after %ld milliseconds",
+                Curl_timediff(now, data->progress.t_startsingle));
+        else {
+          k = &data->req;
+          if(k->size != -1) {
+            failf(data, "Operation timed out after %ld milliseconds with %"
+                  CURL_FORMAT_CURL_OFF_T " out of %"
+                  CURL_FORMAT_CURL_OFF_T " bytes received",
+                  Curl_timediff(now, data->progress.t_startsingle),
+                  k->bytecount, k->size);
+          }
+          else {
+            failf(data, "Operation timed out after %ld milliseconds with %"
+                  CURL_FORMAT_CURL_OFF_T " bytes received",
+                  Curl_timediff(now, data->progress.t_startsingle),
+                  k->bytecount);
+          }
+        }
+
+        /* Force connection closed if the connection has indeed been used */
+        if(data->mstate > CURLM_STATE_DO) {
+          streamclose(data->easy_conn, "Disconnected with pending data");
+          stream_error = TRUE;
+        }
+        result = CURLE_OPERATION_TIMEDOUT;
+        (void)multi_done(&data->easy_conn, result, TRUE);
+        /* Skip the statemachine and go directly to error handling section. */
+        goto statemachine_end;
+      }
+    }
+
+    switch(data->mstate) {
+    case CURLM_STATE_INIT:
+      /* init this transfer. */
+      result = Curl_pretransfer(data);
+
+      if(!result) {
+        /* after init, go CONNECT */
+        multistate(data, CURLM_STATE_CONNECT);
+        Curl_pgrsTime(data, TIMER_STARTOP);
+        rc = CURLM_CALL_MULTI_PERFORM;
+      }
+      break;
+
+    case CURLM_STATE_CONNECT_PEND:
+      /* We will stay here until there is a connection available. Then
+         we try again in the CURLM_STATE_CONNECT state. */
+      break;
+
+    case CURLM_STATE_CONNECT:
+      /* Connect. We want to get a connection identifier filled in. */
+      Curl_pgrsTime(data, TIMER_STARTSINGLE);
+      result = Curl_connect(data, &data->easy_conn,
+                            &async, &protocol_connect);
+      if(CURLE_NO_CONNECTION_AVAILABLE == result) {
+        /* There was no connection available. We will go to the pending
+           state and wait for an available connection. */
+        multistate(data, CURLM_STATE_CONNECT_PEND);
+
+        /* add this handle to the list of connect-pending handles */
+        Curl_llist_insert_next(&multi->pending, multi->pending.tail, data,
+                               &data->connect_queue);
+        result = CURLE_OK;
+        break;
+      }
+
+      if(!result) {
+        /* Add this handle to the send or pend pipeline */
+        result = Curl_add_handle_to_pipeline(data, data->easy_conn);
+        if(result)
+          stream_error = TRUE;
+        else {
+          if(async)
+            /* We're now waiting for an asynchronous name lookup */
+            multistate(data, CURLM_STATE_WAITRESOLVE);
+          else {
+            /* after the connect has been sent off, go WAITCONNECT unless the
+               protocol connect is already done and we can go directly to
+               WAITDO or DO! */
+            rc = CURLM_CALL_MULTI_PERFORM;
+
+            if(protocol_connect)
+              multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
+                         CURLM_STATE_WAITDO:CURLM_STATE_DO);
+            else {
+#ifndef CURL_DISABLE_HTTP
+              if(Curl_connect_ongoing(data->easy_conn))
+                multistate(data, CURLM_STATE_WAITPROXYCONNECT);
+              else
+#endif
+                multistate(data, CURLM_STATE_WAITCONNECT);
+            }
+          }
+        }
+      }
+      break;
+
+    case CURLM_STATE_WAITRESOLVE:
+      /* awaiting an asynch name resolve to complete */
+    {
+      struct Curl_dns_entry *dns = NULL;
+      struct connectdata *conn = data->easy_conn;
+      const char *hostname;
+
+      if(conn->bits.httpproxy)
+        hostname = conn->http_proxy.host.name;
+      else if(conn->bits.conn_to_host)
+        hostname = conn->conn_to_host.name;
+      else
+        hostname = conn->host.name;
+
+      /* check if we have the name resolved by now */
+      dns = Curl_fetch_addr(conn, hostname, (int)conn->port);
+
+      if(dns) {
+#ifdef CURLRES_ASYNCH
+        conn->async.dns = dns;
+        conn->async.done = TRUE;
+#endif
+        result = CURLE_OK;
+        infof(data, "Hostname '%s' was found in DNS cache\n", hostname);
+      }
+
+      if(!dns)
+        result = Curl_resolver_is_resolved(data->easy_conn, &dns);
+
+      /* Update sockets here, because the socket(s) may have been
+         closed and the application thus needs to be told, even if it
+         is likely that the same socket(s) will again be used further
+         down.  If the name has not yet been resolved, it is likely
+         that new sockets have been opened in an attempt to contact
+         another resolver. */
+      singlesocket(multi, data);
+
+      if(dns) {
+        /* Perform the next step in the connection phase, and then move on
+           to the WAITCONNECT state */
+        result = Curl_async_resolved(data->easy_conn, &protocol_connect);
+
+        if(result)
+          /* if Curl_async_resolved() returns failure, the connection struct
+             is already freed and gone */
+          data->easy_conn = NULL;           /* no more connection */
+        else {
+          /* call again please so that we get the next socket setup */
+          rc = CURLM_CALL_MULTI_PERFORM;
+          if(protocol_connect)
+            multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
+                       CURLM_STATE_WAITDO:CURLM_STATE_DO);
+          else {
+#ifndef CURL_DISABLE_HTTP
+            if(Curl_connect_ongoing(data->easy_conn))
+              multistate(data, CURLM_STATE_WAITPROXYCONNECT);
+            else
+#endif
+              multistate(data, CURLM_STATE_WAITCONNECT);
+          }
+        }
+      }
+
+      if(result) {
+        /* failure detected */
+        stream_error = TRUE;
+        break;
+      }
+    }
+    break;
+
+#ifndef CURL_DISABLE_HTTP
+    case CURLM_STATE_WAITPROXYCONNECT:
+      /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */
+      result = Curl_http_connect(data->easy_conn, &protocol_connect);
+
+      if(data->easy_conn->bits.proxy_connect_closed) {
+        rc = CURLM_CALL_MULTI_PERFORM;
+        /* connect back to proxy again */
+        result = CURLE_OK;
+        multi_done(&data->easy_conn, CURLE_OK, FALSE);
+        multistate(data, CURLM_STATE_CONNECT);
+      }
+      else if(!result) {
+        if((data->easy_conn->http_proxy.proxytype != CURLPROXY_HTTPS ||
+           data->easy_conn->bits.proxy_ssl_connected[FIRSTSOCKET]) &&
+           Curl_connect_complete(data->easy_conn)) {
+          rc = CURLM_CALL_MULTI_PERFORM;
+          /* initiate protocol connect phase */
+          multistate(data, CURLM_STATE_SENDPROTOCONNECT);
+        }
+      }
+      break;
+#endif
+
+    case CURLM_STATE_WAITCONNECT:
+      /* awaiting a completion of an asynch TCP connect */
+      result = Curl_is_connected(data->easy_conn, FIRSTSOCKET, &connected);
+      if(connected && !result) {
+#ifndef CURL_DISABLE_HTTP
+        if((data->easy_conn->http_proxy.proxytype == CURLPROXY_HTTPS &&
+            !data->easy_conn->bits.proxy_ssl_connected[FIRSTSOCKET]) ||
+           Curl_connect_ongoing(data->easy_conn)) {
+          multistate(data, CURLM_STATE_WAITPROXYCONNECT);
+          break;
+        }
+#endif
+        rc = CURLM_CALL_MULTI_PERFORM;
+        multistate(data, data->easy_conn->bits.tunnel_proxy?
+                   CURLM_STATE_WAITPROXYCONNECT:
+                   CURLM_STATE_SENDPROTOCONNECT);
+      }
+      else if(result) {
+        /* failure detected */
+        /* Just break, the cleaning up is handled all in one place */
+        stream_error = TRUE;
+        break;
+      }
+      break;
+
+    case CURLM_STATE_SENDPROTOCONNECT:
+      result = Curl_protocol_connect(data->easy_conn, &protocol_connect);
+      if(!protocol_connect)
+        /* switch to waiting state */
+        multistate(data, CURLM_STATE_PROTOCONNECT);
+      else if(!result) {
+        /* protocol connect has completed, go WAITDO or DO */
+        multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
+                   CURLM_STATE_WAITDO:CURLM_STATE_DO);
+        rc = CURLM_CALL_MULTI_PERFORM;
+      }
+      else if(result) {
+        /* failure detected */
+        Curl_posttransfer(data);
+        multi_done(&data->easy_conn, result, TRUE);
+        stream_error = TRUE;
+      }
+      break;
+
+    case CURLM_STATE_PROTOCONNECT:
+      /* protocol-specific connect phase */
+      result = Curl_protocol_connecting(data->easy_conn, &protocol_connect);
+      if(!result && protocol_connect) {
+        /* after the connect has completed, go WAITDO or DO */
+        multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)?
+                   CURLM_STATE_WAITDO:CURLM_STATE_DO);
+        rc = CURLM_CALL_MULTI_PERFORM;
+      }
+      else if(result) {
+        /* failure detected */
+        Curl_posttransfer(data);
+        multi_done(&data->easy_conn, result, TRUE);
+        stream_error = TRUE;
+      }
+      break;
+
+    case CURLM_STATE_WAITDO:
+      /* Wait for our turn to DO when we're pipelining requests */
+      if(Curl_pipeline_checkget_write(data, data->easy_conn)) {
+        /* Grabbed the channel */
+        multistate(data, CURLM_STATE_DO);
+        rc = CURLM_CALL_MULTI_PERFORM;
+      }
+      break;
+
+    case CURLM_STATE_DO:
+      if(data->set.connect_only) {
+        /* keep connection open for application to use the socket */
+        connkeep(data->easy_conn, "CONNECT_ONLY");
+        multistate(data, CURLM_STATE_DONE);
+        result = CURLE_OK;
+        rc = CURLM_CALL_MULTI_PERFORM;
+      }
+      else {
+        /* Perform the protocol's DO action */
+        result = multi_do(&data->easy_conn, &dophase_done);
+
+        /* When multi_do() returns failure, data->easy_conn might be NULL! */
+
+        if(!result) {
+          if(!dophase_done) {
+            /* some steps needed for wildcard matching */
+            if(data->state.wildcardmatch) {
+              struct WildcardData *wc = &data->wildcard;
+              if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) {
+                /* skip some states if it is important */
+                multi_done(&data->easy_conn, CURLE_OK, FALSE);
+                multistate(data, CURLM_STATE_DONE);
+                rc = CURLM_CALL_MULTI_PERFORM;
+                break;
+              }
+            }
+            /* DO was not completed in one function call, we must continue
+               DOING... */
+            multistate(data, CURLM_STATE_DOING);
+            rc = CURLM_OK;
+          }
+
+          /* after DO, go DO_DONE... or DO_MORE */
+          else if(data->easy_conn->bits.do_more) {
+            /* we're supposed to do more, but we need to sit down, relax
+               and wait a little while first */
+            multistate(data, CURLM_STATE_DO_MORE);
+            rc = CURLM_OK;
+          }
+          else {
+            /* we're done with the DO, now DO_DONE */
+            multistate(data, CURLM_STATE_DO_DONE);
+            rc = CURLM_CALL_MULTI_PERFORM;
+          }
+        }
+        else if((CURLE_SEND_ERROR == result) &&
+                data->easy_conn->bits.reuse) {
+          /*
+           * In this situation, a connection that we were trying to use
+           * may have unexpectedly died.  If possible, send the connection
+           * back to the CONNECT phase so we can try again.
+           */
+          char *newurl = NULL;
+          followtype follow = FOLLOW_NONE;
+          CURLcode drc;
+          bool retry = FALSE;
+
+          drc = Curl_retry_request(data->easy_conn, &newurl);
+          if(drc) {
+            /* a failure here pretty much implies an out of memory */
+            result = drc;
+            stream_error = TRUE;
+          }
+          else
+            retry = (newurl)?TRUE:FALSE;
+
+          Curl_posttransfer(data);
+          drc = multi_done(&data->easy_conn, result, FALSE);
+
+          /* When set to retry the connection, we must to go back to
+           * the CONNECT state */
+          if(retry) {
+            if(!drc || (drc == CURLE_SEND_ERROR)) {
+              follow = FOLLOW_RETRY;
+              drc = Curl_follow(data, newurl, follow);
+              if(!drc) {
+                multistate(data, CURLM_STATE_CONNECT);
+                rc = CURLM_CALL_MULTI_PERFORM;
+                result = CURLE_OK;
+              }
+              else {
+                /* Follow failed */
+                result = drc;
+              }
+            }
+            else {
+              /* done didn't return OK or SEND_ERROR */
+              result = drc;
+            }
+          }
+          else {
+            /* Have error handler disconnect conn if we can't retry */
+            stream_error = TRUE;
+          }
+          free(newurl);
+        }
+        else {
+          /* failure detected */
+          Curl_posttransfer(data);
+          if(data->easy_conn)
+            multi_done(&data->easy_conn, result, FALSE);
+          stream_error = TRUE;
+        }
+      }
+      break;
+
+    case CURLM_STATE_DOING:
+      /* we continue DOING until the DO phase is complete */
+      result = Curl_protocol_doing(data->easy_conn,
+                                   &dophase_done);
+      if(!result) {
+        if(dophase_done) {
+          /* after DO, go DO_DONE or DO_MORE */
+          multistate(data, data->easy_conn->bits.do_more?
+                     CURLM_STATE_DO_MORE:
+                     CURLM_STATE_DO_DONE);
+          rc = CURLM_CALL_MULTI_PERFORM;
+        } /* dophase_done */
+      }
+      else {
+        /* failure detected */
+        Curl_posttransfer(data);
+        multi_done(&data->easy_conn, result, FALSE);
+        stream_error = TRUE;
+      }
+      break;
+
+    case CURLM_STATE_DO_MORE:
+      /*
+       * When we are connected, DO MORE and then go DO_DONE
+       */
+      result = multi_do_more(data->easy_conn, &control);
+
+      /* No need to remove this handle from the send pipeline here since that
+         is done in multi_done() */
+      if(!result) {
+        if(control) {
+          /* if positive, advance to DO_DONE
+             if negative, go back to DOING */
+          multistate(data, control == 1?
+                     CURLM_STATE_DO_DONE:
+                     CURLM_STATE_DOING);
+          rc = CURLM_CALL_MULTI_PERFORM;
+        }
+        else
+          /* stay in DO_MORE */
+          rc = CURLM_OK;
+      }
+      else {
+        /* failure detected */
+        Curl_posttransfer(data);
+        multi_done(&data->easy_conn, result, FALSE);
+        stream_error = TRUE;
+      }
+      break;
+
+    case CURLM_STATE_DO_DONE:
+      /* Move ourselves from the send to recv pipeline */
+      Curl_move_handle_from_send_to_recv_pipe(data, data->easy_conn);
+      /* Check if we can move pending requests to send pipe */
+      Curl_multi_process_pending_handles(multi);
+
+      /* Only perform the transfer if there's a good socket to work with.
+         Having both BAD is a signal to skip immediately to DONE */
+      if((data->easy_conn->sockfd != CURL_SOCKET_BAD) ||
+         (data->easy_conn->writesockfd != CURL_SOCKET_BAD))
+        multistate(data, CURLM_STATE_WAITPERFORM);
+      else
+      {
+        if(data->state.wildcardmatch &&
+           ((data->easy_conn->handler->flags & PROTOPT_WILDCARD) == 0)) {
+           data->wildcard.state = CURLWC_DONE;
+        }
+        multistate(data, CURLM_STATE_DONE);
+      }
+      rc = CURLM_CALL_MULTI_PERFORM;
+      break;
+
+    case CURLM_STATE_WAITPERFORM:
+      /* Wait for our turn to PERFORM */
+      if(Curl_pipeline_checkget_read(data, data->easy_conn)) {
+        /* Grabbed the channel */
+        multistate(data, CURLM_STATE_PERFORM);
+        rc = CURLM_CALL_MULTI_PERFORM;
+      }
+      break;
+
+    case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */
+      /* if both rates are within spec, resume transfer */
+      if(Curl_pgrsUpdate(data->easy_conn))
+        result = CURLE_ABORTED_BY_CALLBACK;
+      else
+        result = Curl_speedcheck(data, now);
+
+      if(!result) {
+        send_timeout_ms = 0;
+        if(data->set.max_send_speed > 0)
+          send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded,
+                                data->progress.ul_limit_size,
+                                data->set.max_send_speed,
+                                data->progress.ul_limit_start,
+                                now);
+
+        recv_timeout_ms = 0;
+        if(data->set.max_recv_speed > 0)
+          recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded,
+                                data->progress.dl_limit_size,
+                                data->set.max_recv_speed,
+                                data->progress.dl_limit_start,
+                                now);
+
+        if(send_timeout_ms <= 0 && recv_timeout_ms <= 0)
+          multistate(data, CURLM_STATE_PERFORM);
+        else if(send_timeout_ms >= recv_timeout_ms)
+          Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
+        else
+          Curl_expire(data, recv_timeout_ms, EXPIRE_TOOFAST);
+      }
+      break;
+
+    case CURLM_STATE_PERFORM:
+    {
+      char *newurl = NULL;
+      bool retry = FALSE;
+      bool comeback = FALSE;
+
+      /* check if over send speed */
+      send_timeout_ms = 0;
+      if(data->set.max_send_speed > 0)
+        send_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.uploaded,
+                                                 data->progress.ul_limit_size,
+                                                 data->set.max_send_speed,
+                                                 data->progress.ul_limit_start,
+                                                 now);
+
+      /* check if over recv speed */
+      recv_timeout_ms = 0;
+      if(data->set.max_recv_speed > 0)
+        recv_timeout_ms = Curl_pgrsLimitWaitTime(data->progress.downloaded,
+                                                 data->progress.dl_limit_size,
+                                                 data->set.max_recv_speed,
+                                                 data->progress.dl_limit_start,
+                                                 now);
+
+      if(send_timeout_ms > 0 || recv_timeout_ms > 0) {
+        multistate(data, CURLM_STATE_TOOFAST);
+        if(send_timeout_ms >= recv_timeout_ms)
+          Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
+        else
+          Curl_expire(data, recv_timeout_ms, EXPIRE_TOOFAST);
+        break;
+      }
+
+      /* read/write data if it is ready to do so */
+      result = Curl_readwrite(data->easy_conn, data, &done, &comeback);
+
+      k = &data->req;
+
+      if(!(k->keepon & KEEP_RECV))
+        /* We're done receiving */
+        Curl_pipeline_leave_read(data->easy_conn);
+
+      if(!(k->keepon & KEEP_SEND))
+        /* We're done sending */
+        Curl_pipeline_leave_write(data->easy_conn);
+
+      if(done || (result == CURLE_RECV_ERROR)) {
+        /* If CURLE_RECV_ERROR happens early enough, we assume it was a race
+         * condition and the server closed the re-used connection exactly when
+         * we wanted to use it, so figure out if that is indeed the case.
+         */
+        CURLcode ret = Curl_retry_request(data->easy_conn, &newurl);
+        if(!ret)
+          retry = (newurl)?TRUE:FALSE;
+
+        if(retry) {
+          /* if we are to retry, set the result to OK and consider the
+             request as done */
+          result = CURLE_OK;
+          done = TRUE;
+        }
+      }
+
+      if(result) {
+        /*
+         * The transfer phase returned error, we mark the connection to get
+         * closed to prevent being re-used. This is because we can't possibly
+         * know if the connection is in a good shape or not now.  Unless it is
+         * a protocol which uses two "channels" like FTP, as then the error
+         * happened in the data connection.
+         */
+
+        if(!(data->easy_conn->handler->flags & PROTOPT_DUAL) &&
+           result != CURLE_HTTP2_STREAM)
+          streamclose(data->easy_conn, "Transfer returned error");
+
+        Curl_posttransfer(data);
+        multi_done(&data->easy_conn, result, TRUE);
+      }
+      else if(done) {
+        followtype follow = FOLLOW_NONE;
+
+        /* call this even if the readwrite function returned error */
+        Curl_posttransfer(data);
+
+        /* we're no longer receiving */
+        Curl_removeHandleFromPipeline(data, &data->easy_conn->recv_pipe);
+
+        /* expire the new receiving pipeline head */
+        if(data->easy_conn->recv_pipe.head)
+          Curl_expire(data->easy_conn->recv_pipe.head->ptr, 0, EXPIRE_RUN_NOW);
+
+        /* Check if we can move pending requests to send pipe */
+        Curl_multi_process_pending_handles(multi);
+
+        /* When we follow redirects or is set to retry the connection, we must
+           to go back to the CONNECT state */
+        if(data->req.newurl || retry) {
+          if(!retry) {
+            /* if the URL is a follow-location and not just a retried request
+               then figure out the URL here */
+            free(newurl);
+            newurl = data->req.newurl;
+            data->req.newurl = NULL;
+            follow = FOLLOW_REDIR;
+          }
+          else
+            follow = FOLLOW_RETRY;
+          result = multi_done(&data->easy_conn, CURLE_OK, FALSE);
+          if(!result) {
+            result = Curl_follow(data, newurl, follow);
+            if(!result) {
+              multistate(data, CURLM_STATE_CONNECT);
+              rc = CURLM_CALL_MULTI_PERFORM;
+            }
+          }
+        }
+        else {
+          /* after the transfer is done, go DONE */
+
+          /* but first check to see if we got a location info even though we're
+             not following redirects */
+          if(data->req.location) {
+            free(newurl);
+            newurl = data->req.location;
+            data->req.location = NULL;
+            result = Curl_follow(data, newurl, FOLLOW_FAKE);
+            if(result)
+              stream_error = TRUE;
+          }
+
+          multistate(data, CURLM_STATE_DONE);
+          rc = CURLM_CALL_MULTI_PERFORM;
+        }
+      }
+      else if(comeback)
+        rc = CURLM_CALL_MULTI_PERFORM;
+
+      free(newurl);
+      break;
+    }
+
+    case CURLM_STATE_DONE:
+      /* this state is highly transient, so run another loop after this */
+      rc = CURLM_CALL_MULTI_PERFORM;
+
+      if(data->easy_conn) {
+        CURLcode res;
+
+        /* Remove ourselves from the receive pipeline, if we are there. */
+        Curl_removeHandleFromPipeline(data, &data->easy_conn->recv_pipe);
+        /* Check if we can move pending requests to send pipe */
+        Curl_multi_process_pending_handles(multi);
+
+        /* post-transfer command */
+        res = multi_done(&data->easy_conn, result, FALSE);
+
+        /* allow a previously set error code take precedence */
+        if(!result)
+          result = res;
+
+        /*
+         * If there are other handles on the pipeline, multi_done won't set
+         * easy_conn to NULL.  In such a case, curl_multi_remove_handle() can
+         * access free'd data, if the connection is free'd and the handle
+         * removed before we perform the processing in CURLM_STATE_COMPLETED
+         */
+        if(data->easy_conn)
+          data->easy_conn = NULL;
+      }
+
+      if(data->state.wildcardmatch) {
+        if(data->wildcard.state != CURLWC_DONE) {
+          /* if a wildcard is set and we are not ending -> lets start again
+             with CURLM_STATE_INIT */
+          multistate(data, CURLM_STATE_INIT);
+          break;
+        }
+      }
+
+      /* after we have DONE what we're supposed to do, go COMPLETED, and
+         it doesn't matter what the multi_done() returned! */
+      multistate(data, CURLM_STATE_COMPLETED);
+      break;
+
+    case CURLM_STATE_COMPLETED:
+      /* this is a completed transfer, it is likely to still be connected */
+
+      /* This node should be delinked from the list now and we should post
+         an information message that we are complete. */
+
+      /* Important: reset the conn pointer so that we don't point to memory
+         that could be freed anytime */
+      data->easy_conn = NULL;
+
+      Curl_expire_clear(data); /* stop all timers */
+      break;
+
+    case CURLM_STATE_MSGSENT:
+      data->result = result;
+      return CURLM_OK; /* do nothing */
+
+    default:
+      return CURLM_INTERNAL_ERROR;
+    }
+    statemachine_end:
+
+    if(data->mstate < CURLM_STATE_COMPLETED) {
+      if(result) {
+        /*
+         * If an error was returned, and we aren't in completed state now,
+         * then we go to completed and consider this transfer aborted.
+         */
+
+        /* NOTE: no attempt to disconnect connections must be made
+           in the case blocks above - cleanup happens only here */
+
+        data->state.pipe_broke = FALSE;
+
+        /* Check if we can move pending requests to send pipe */
+        Curl_multi_process_pending_handles(multi);
+
+        if(data->easy_conn) {
+          /* if this has a connection, unsubscribe from the pipelines */
+          Curl_pipeline_leave_write(data->easy_conn);
+          Curl_pipeline_leave_read(data->easy_conn);
+          Curl_removeHandleFromPipeline(data, &data->easy_conn->send_pipe);
+          Curl_removeHandleFromPipeline(data, &data->easy_conn->recv_pipe);
+
+          if(stream_error) {
+            /* Don't attempt to send data over a connection that timed out */
+            bool dead_connection = result == CURLE_OPERATION_TIMEDOUT;
+            /* disconnect properly */
+            Curl_disconnect(data->easy_conn, dead_connection);
+
+            /* This is where we make sure that the easy_conn pointer is reset.
+               We don't have to do this in every case block above where a
+               failure is detected */
+            data->easy_conn = NULL;
+          }
+        }
+        else if(data->mstate == CURLM_STATE_CONNECT) {
+          /* Curl_connect() failed */
+          (void)Curl_posttransfer(data);
+        }
+
+        multistate(data, CURLM_STATE_COMPLETED);
+      }
+      /* if there's still a connection to use, call the progress function */
+      else if(data->easy_conn && Curl_pgrsUpdate(data->easy_conn)) {
+        /* aborted due to progress callback return code must close the
+           connection */
+        result = CURLE_ABORTED_BY_CALLBACK;
+        streamclose(data->easy_conn, "Aborted by callback");
+
+        /* if not yet in DONE state, go there, otherwise COMPLETED */
+        multistate(data, (data->mstate < CURLM_STATE_DONE)?
+                   CURLM_STATE_DONE: CURLM_STATE_COMPLETED);
+        rc = CURLM_CALL_MULTI_PERFORM;
+      }
+    }
+
+    if(CURLM_STATE_COMPLETED == data->mstate) {
+      /* now fill in the Curl_message with this info */
+      msg = &data->msg;
+
+      msg->extmsg.msg = CURLMSG_DONE;
+      msg->extmsg.easy_handle = data;
+      msg->extmsg.data.result = result;
+
+      rc = multi_addmsg(multi, msg);
+
+      multistate(data, CURLM_STATE_MSGSENT);
+    }
+  } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE));
+
+  data->result = result;
+
+
+  return rc;
+}
+
+
+CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
+{
+  struct Curl_easy *data;
+  CURLMcode returncode = CURLM_OK;
+  struct Curl_tree *t;
+  struct curltime now = Curl_now();
+
+  if(!GOOD_MULTI_HANDLE(multi))
+    return CURLM_BAD_HANDLE;
+
+  data = multi->easyp;
+  while(data) {
+    CURLMcode result;
+    SIGPIPE_VARIABLE(pipe_st);
+
+    sigpipe_ignore(data, &pipe_st);
+    result = multi_runsingle(multi, now, data);
+    sigpipe_restore(&pipe_st);
+
+    if(result)
+      returncode = result;
+
+    data = data->next; /* operate on next handle */
+  }
+
+  /*
+   * Simply remove all expired timers from the splay since handles are dealt
+   * with unconditionally by this function and curl_multi_timeout() requires
+   * that already passed/handled expire times are removed from the splay.
+   *
+   * It is important that the 'now' value is set at the entry of this function
+   * and not for the current time as it may have ticked a little while since
+   * then and then we risk this loop to remove timers that actually have not
+   * been handled!
+   */
+  do {
+    multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
+    if(t)
+      /* the removed may have another timeout in queue */
+      (void)add_next_timeout(now, multi, t->payload);
+
+  } while(t);
+
+  *running_handles = multi->num_alive;
+
+  if(CURLM_OK >= returncode)
+    update_timer(multi);
+
+  return returncode;
+}
+
+CURLMcode curl_multi_cleanup(struct Curl_multi *multi)
+{
+  struct Curl_easy *data;
+  struct Curl_easy *nextdata;
+
+  if(GOOD_MULTI_HANDLE(multi)) {
+    multi->type = 0; /* not good anymore */
+
+    /* Firsrt remove all remaining easy handles */
+    data = multi->easyp;
+    while(data) {
+      nextdata = data->next;
+      if(!data->state.done && data->easy_conn)
+        /* if DONE was never called for this handle */
+        (void)multi_done(&data->easy_conn, CURLE_OK, TRUE);
+      if(data->dns.hostcachetype == HCACHE_MULTI) {
+        /* clear out the usage of the shared DNS cache */
+        Curl_hostcache_clean(data, data->dns.hostcache);
+        data->dns.hostcache = NULL;
+        data->dns.hostcachetype = HCACHE_NONE;
+      }
+
+      /* Clear the pointer to the connection cache */
+      data->state.conn_cache = NULL;
+      data->multi = NULL; /* clear the association */
+
+      data = nextdata;
+    }
+
+    /* Close all the connections in the connection cache */
+    Curl_conncache_close_all_connections(&multi->conn_cache);
+
+    Curl_hash_destroy(&multi->sockhash);
+    Curl_conncache_destroy(&multi->conn_cache);
+    Curl_llist_destroy(&multi->msglist, NULL);
+    Curl_llist_destroy(&multi->pending, NULL);
+
+    Curl_hash_destroy(&multi->hostcache);
+
+    /* Free the blacklists by setting them to NULL */
+    Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl);
+    Curl_pipeline_set_server_blacklist(NULL, &multi->pipelining_server_bl);
+
+    free(multi);
+
+    return CURLM_OK;
+  }
+  return CURLM_BAD_HANDLE;
+}
+
+/*
+ * curl_multi_info_read()
+ *
+ * This function is the primary way for a multi/multi_socket application to
+ * figure out if a transfer has ended. We MUST make this function as fast as
+ * possible as it will be polled frequently and we MUST NOT scan any lists in
+ * here to figure out things. We must scale fine to thousands of handles and
+ * beyond. The current design is fully O(1).
+ */
+
+CURLMsg *curl_multi_info_read(struct Curl_multi *multi, int *msgs_in_queue)
+{
+  struct Curl_message *msg;
+
+  *msgs_in_queue = 0; /* default to none */
+
+  if(GOOD_MULTI_HANDLE(multi) && Curl_llist_count(&multi->msglist)) {
+    /* there is one or more messages in the list */
+    struct curl_llist_element *e;
+
+    /* extract the head of the list to return */
+    e = multi->msglist.head;
+
+    msg = e->ptr;
+
+    /* remove the extracted entry */
+    Curl_llist_remove(&multi->msglist, e, NULL);
+
+    *msgs_in_queue = curlx_uztosi(Curl_llist_count(&multi->msglist));
+
+    return &msg->extmsg;
+  }
+  return NULL;
+}
+
+/*
+ * singlesocket() checks what sockets we deal with and their "action state"
+ * and if we have a different state in any of those sockets from last time we
+ * call the callback accordingly.
+ */
+static void singlesocket(struct Curl_multi *multi,
+                         struct Curl_easy *data)
+{
+  curl_socket_t socks[MAX_SOCKSPEREASYHANDLE];
+  int i;
+  struct Curl_sh_entry *entry;
+  curl_socket_t s;
+  int num;
+  unsigned int curraction;
+
+  for(i = 0; i< MAX_SOCKSPEREASYHANDLE; i++)
+    socks[i] = CURL_SOCKET_BAD;
+
+  /* Fill in the 'current' struct with the state as it is now: what sockets to
+     supervise and for what actions */
+  curraction = multi_getsock(data, socks, MAX_SOCKSPEREASYHANDLE);
+
+  /* We have 0 .. N sockets already and we get to know about the 0 .. M
+     sockets we should have from now on. Detect the differences, remove no
+     longer supervised ones and add new ones */
+
+  /* walk over the sockets we got right now */
+  for(i = 0; (i< MAX_SOCKSPEREASYHANDLE) &&
+        (curraction & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i)));
+      i++) {
+    int action = CURL_POLL_NONE;
+
+    s = socks[i];
+
+    /* get it from the hash */
+    entry = sh_getentry(&multi->sockhash, s);
+
+    if(curraction & GETSOCK_READSOCK(i))
+      action |= CURL_POLL_IN;
+    if(curraction & GETSOCK_WRITESOCK(i))
+      action |= CURL_POLL_OUT;
+
+    if(entry) {
+      /* yeps, already present so check if it has the same action set */
+      if(entry->action == action)
+        /* same, continue */
+        continue;
+    }
+    else {
+      /* this is a socket we didn't have before, add it! */
+      entry = sh_addentry(&multi->sockhash, s, data);
+      if(!entry)
+        /* fatal */
+        return;
+    }
+
+    /* we know (entry != NULL) at this point, see the logic above */
+    if(multi->socket_cb)
+      multi->socket_cb(data,
+                       s,
+                       action,
+                       multi->socket_userp,
+                       entry->socketp);
+
+    entry->action = action; /* store the current action state */
+  }
+
+  num = i; /* number of sockets */
+
+  /* when we've walked over all the sockets we should have right now, we must
+     make sure to detect sockets that are removed */
+  for(i = 0; i< data->numsocks; i++) {
+    int j;
+    s = data->sockets[i];
+    for(j = 0; j<num; j++) {
+      if(s == socks[j]) {
+        /* this is still supervised */
+        s = CURL_SOCKET_BAD;
+        break;
+      }
+    }
+
+    entry = sh_getentry(&multi->sockhash, s);
+    if(entry) {
+      /* this socket has been removed. Tell the app to remove it */
+      bool remove_sock_from_hash = TRUE;
+
+      /* check if the socket to be removed serves a connection which has
+         other easy-s in a pipeline. In this case the socket should not be
+         removed. */
+      struct connectdata *easy_conn = data->easy_conn;
+      if(easy_conn) {
+        if(easy_conn->recv_pipe.size > 1) {
+          /* the handle should not be removed from the pipe yet */
+          remove_sock_from_hash = FALSE;
+
+          /* Update the sockhash entry to instead point to the next in line
+             for the recv_pipe, or the first (in case this particular easy
+             isn't already) */
+          if(entry->easy == data) {
+            if(Curl_recvpipe_head(data, easy_conn))
+              entry->easy = easy_conn->recv_pipe.head->next->ptr;
+            else
+              entry->easy = easy_conn->recv_pipe.head->ptr;
+          }
+        }
+        if(easy_conn->send_pipe.size > 1) {
+          /* the handle should not be removed from the pipe yet */
+          remove_sock_from_hash = FALSE;
+
+          /* Update the sockhash entry to instead point to the next in line
+             for the send_pipe, or the first (in case this particular easy
+             isn't already) */
+          if(entry->easy == data) {
+            if(Curl_sendpipe_head(data, easy_conn))
+              entry->easy = easy_conn->send_pipe.head->next->ptr;
+            else
+              entry->easy = easy_conn->send_pipe.head->ptr;
+          }
+        }
+        /* Don't worry about overwriting recv_pipe head with send_pipe_head,
+           when action will be asked on the socket (see multi_socket()), the
+           head of the correct pipe will be taken according to the
+           action. */
+      }
+
+      if(remove_sock_from_hash) {
+        /* in this case 'entry' is always non-NULL */
+        if(multi->socket_cb)
+          multi->socket_cb(data,
+                           s,
+                           CURL_POLL_REMOVE,
+                           multi->socket_userp,
+                           entry->socketp);
+        sh_delentry(&multi->sockhash, s);
+      }
+    } /* if sockhash entry existed */
+  } /* for loop over numsocks */
+
+  memcpy(data->sockets, socks, num*sizeof(curl_socket_t));
+  data->numsocks = num;
+}
+
+/*
+ * Curl_multi_closed()
+ *
+ * Used by the connect code to tell the multi_socket code that one of the
+ * sockets we were using is about to be closed.  This function will then
+ * remove it from the sockethash for this handle to make the multi_socket API
+ * behave properly, especially for the case when libcurl will create another
+ * socket again and it gets the same file descriptor number.
+ */
+
+void Curl_multi_closed(struct connectdata *conn, curl_socket_t s)
+{
+  struct Curl_multi *multi = conn->data->multi;
+  if(multi) {
+    /* this is set if this connection is part of a handle that is added to
+       a multi handle, and only then this is necessary */
+    struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
+
+    if(entry) {
+      if(multi->socket_cb)
+        multi->socket_cb(conn->data, s, CURL_POLL_REMOVE,
+                         multi->socket_userp,
+                         entry->socketp);
+
+      /* now remove it from the socket hash */
+      sh_delentry(&multi->sockhash, s);
+    }
+  }
+}
+
+/*
+ * add_next_timeout()
+ *
+ * Each Curl_easy has a list of timeouts. The add_next_timeout() is called
+ * when it has just been removed from the splay tree because the timeout has
+ * expired. This function is then to advance in the list to pick the next
+ * timeout to use (skip the already expired ones) and add this node back to
+ * the splay tree again.
+ *
+ * The splay tree only has each sessionhandle as a single node and the nearest
+ * timeout is used to sort it on.
+ */
+static CURLMcode add_next_timeout(struct curltime now,
+                                  struct Curl_multi *multi,
+                                  struct Curl_easy *d)
+{
+  struct curltime *tv = &d->state.expiretime;
+  struct curl_llist *list = &d->state.timeoutlist;
+  struct curl_llist_element *e;
+  struct time_node *node = NULL;
+
+  /* move over the timeout list for this specific handle and remove all
+     timeouts that are now passed tense and store the next pending
+     timeout in *tv */
+  for(e = list->head; e;) {
+    struct curl_llist_element *n = e->next;
+    timediff_t diff;
+    node = (struct time_node *)e->ptr;
+    diff = Curl_timediff(node->time, now);
+    if(diff <= 0)
+      /* remove outdated entry */
+      Curl_llist_remove(list, e, NULL);
+    else
+      /* the list is sorted so get out on the first mismatch */
+      break;
+    e = n;
+  }
+  e = list->head;
+  if(!e) {
+    /* clear the expire times within the handles that we remove from the
+       splay tree */
+    tv->tv_sec = 0;
+    tv->tv_usec = 0;
+  }
+  else {
+    /* copy the first entry to 'tv' */
+    memcpy(tv, &node->time, sizeof(*tv));
+
+    /* Insert this node again into the splay.  Keep the timer in the list in
+       case we need to recompute future timers. */
+    multi->timetree = Curl_splayinsert(*tv, multi->timetree,
+                                       &d->state.timenode);
+  }
+  return CURLM_OK;
+}
+
+static CURLMcode multi_socket(struct Curl_multi *multi,
+                              bool checkall,
+                              curl_socket_t s,
+                              int ev_bitmask,
+                              int *running_handles)
+{
+  CURLMcode result = CURLM_OK;
+  struct Curl_easy *data = NULL;
+  struct Curl_tree *t;
+  struct curltime now = Curl_now();
+
+  if(checkall) {
+    /* *perform() deals with running_handles on its own */
+    result = curl_multi_perform(multi, running_handles);
+
+    /* walk through each easy handle and do the socket state change magic
+       and callbacks */
+    if(result != CURLM_BAD_HANDLE) {
+      data = multi->easyp;
+      while(data) {
+        singlesocket(multi, data);
+        data = data->next;
+      }
+    }
+
+    /* or should we fall-through and do the timer-based stuff? */
+    return result;
+  }
+  if(s != CURL_SOCKET_TIMEOUT) {
+
+    struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
+
+    if(!entry)
+      /* Unmatched socket, we can't act on it but we ignore this fact.  In
+         real-world tests it has been proved that libevent can in fact give
+         the application actions even though the socket was just previously
+         asked to get removed, so thus we better survive stray socket actions
+         and just move on. */
+      ;
+    else {
+      SIGPIPE_VARIABLE(pipe_st);
+
+      data = entry->easy;
+
+      if(data->magic != CURLEASY_MAGIC_NUMBER)
+        /* bad bad bad bad bad bad bad */
+        return CURLM_INTERNAL_ERROR;
+
+      /* If the pipeline is enabled, take the handle which is in the head of
+         the pipeline. If we should write into the socket, take the send_pipe
+         head.  If we should read from the socket, take the recv_pipe head. */
+      if(data->easy_conn) {
+        if((ev_bitmask & CURL_POLL_OUT) &&
+           data->easy_conn->send_pipe.head)
+          data = data->easy_conn->send_pipe.head->ptr;
+        else if((ev_bitmask & CURL_POLL_IN) &&
+                data->easy_conn->recv_pipe.head)
+          data = data->easy_conn->recv_pipe.head->ptr;
+      }
+
+      if(data->easy_conn &&
+         !(data->easy_conn->handler->flags & PROTOPT_DIRLOCK))
+        /* set socket event bitmask if they're not locked */
+        data->easy_conn->cselect_bits = ev_bitmask;
+
+      sigpipe_ignore(data, &pipe_st);
+      result = multi_runsingle(multi, now, data);
+      sigpipe_restore(&pipe_st);
+
+      if(data->easy_conn &&
+         !(data->easy_conn->handler->flags & PROTOPT_DIRLOCK))
+        /* clear the bitmask only if not locked */
+        data->easy_conn->cselect_bits = 0;
+
+      if(CURLM_OK >= result)
+        /* get the socket(s) and check if the state has been changed since
+           last */
+        singlesocket(multi, data);
+
+      /* Now we fall-through and do the timer-based stuff, since we don't want
+         to force the user to have to deal with timeouts as long as at least
+         one connection in fact has traffic. */
+
+      data = NULL; /* set data to NULL again to avoid calling
+                      multi_runsingle() in case there's no need to */
+      now = Curl_now(); /* get a newer time since the multi_runsingle() loop
+                           may have taken some time */
+    }
+  }
+  else {
+    /* Asked to run due to time-out. Clear the 'lastcall' variable to force
+       update_timer() to trigger a callback to the app again even if the same
+       timeout is still the one to run after this call. That handles the case
+       when the application asks libcurl to run the timeout prematurely. */
+    memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall));
+  }
+
+  /*
+   * The loop following here will go on as long as there are expire-times left
+   * to process in the splay and 'data' will be re-assigned for every expired
+   * handle we deal with.
+   */
+  do {
+    /* the first loop lap 'data' can be NULL */
+    if(data) {
+      SIGPIPE_VARIABLE(pipe_st);
+
+      sigpipe_ignore(data, &pipe_st);
+      result = multi_runsingle(multi, now, data);
+      sigpipe_restore(&pipe_st);
+
+      if(CURLM_OK >= result)
+        /* get the socket(s) and check if the state has been changed since
+           last */
+        singlesocket(multi, data);
+    }
+
+    /* Check if there's one (more) expired timer to deal with! This function
+       extracts a matching node if there is one */
+
+    multi->timetree = Curl_splaygetbest(now, multi->timetree, &t);
+    if(t) {
+      data = t->payload; /* assign this for next loop */
+      (void)add_next_timeout(now, multi, t->payload);
+    }
+
+  } while(t);
+
+  *running_handles = multi->num_alive;
+  return result;
+}
+
+#undef curl_multi_setopt
+CURLMcode curl_multi_setopt(struct Curl_multi *multi,
+                            CURLMoption option, ...)
+{
+  CURLMcode res = CURLM_OK;
+  va_list param;
+
+  if(!GOOD_MULTI_HANDLE(multi))
+    return CURLM_BAD_HANDLE;
+
+  va_start(param, option);
+
+  switch(option) {
+  case CURLMOPT_SOCKETFUNCTION:
+    multi->socket_cb = va_arg(param, curl_socket_callback);
+    break;
+  case CURLMOPT_SOCKETDATA:
+    multi->socket_userp = va_arg(param, void *);
+    break;
+  case CURLMOPT_PUSHFUNCTION:
+    multi->push_cb = va_arg(param, curl_push_callback);
+    break;
+  case CURLMOPT_PUSHDATA:
+    multi->push_userp = va_arg(param, void *);
+    break;
+  case CURLMOPT_PIPELINING:
+    multi->pipelining = va_arg(param, long);
+    break;
+  case CURLMOPT_TIMERFUNCTION:
+    multi->timer_cb = va_arg(param, curl_multi_timer_callback);
+    break;
+  case CURLMOPT_TIMERDATA:
+    multi->timer_userp = va_arg(param, void *);
+    break;
+  case CURLMOPT_MAXCONNECTS:
+    multi->maxconnects = va_arg(param, long);
+    break;
+  case CURLMOPT_MAX_HOST_CONNECTIONS:
+    multi->max_host_connections = va_arg(param, long);
+    break;
+  case CURLMOPT_MAX_PIPELINE_LENGTH:
+    multi->max_pipeline_length = va_arg(param, long);
+    break;
+  case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE:
+    multi->content_length_penalty_size = va_arg(param, long);
+    break;
+  case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE:
+    multi->chunk_length_penalty_size = va_arg(param, long);
+    break;
+  case CURLMOPT_PIPELINING_SITE_BL:
+    res = Curl_pipeline_set_site_blacklist(va_arg(param, char **),
+                                           &multi->pipelining_site_bl);
+    break;
+  case CURLMOPT_PIPELINING_SERVER_BL:
+    res = Curl_pipeline_set_server_blacklist(va_arg(param, char **),
+                                             &multi->pipelining_server_bl);
+    break;
+  case CURLMOPT_MAX_TOTAL_CONNECTIONS:
+    multi->max_total_connections = va_arg(param, long);
+    break;
+  default:
+    res = CURLM_UNKNOWN_OPTION;
+    break;
+  }
+  va_end(param);
+  return res;
+}
+
+/* we define curl_multi_socket() in the public multi.h header */
+#undef curl_multi_socket
+
+CURLMcode curl_multi_socket(struct Curl_multi *multi, curl_socket_t s,
+                            int *running_handles)
+{
+  CURLMcode result = multi_socket(multi, FALSE, s, 0, running_handles);
+  if(CURLM_OK >= result)
+    update_timer(multi);
+  return result;
+}
+
+CURLMcode curl_multi_socket_action(struct Curl_multi *multi, curl_socket_t s,
+                                   int ev_bitmask, int *running_handles)
+{
+  CURLMcode result = multi_socket(multi, FALSE, s,
+                                  ev_bitmask, running_handles);
+  if(CURLM_OK >= result)
+    update_timer(multi);
+  return result;
+}
+
+CURLMcode curl_multi_socket_all(struct Curl_multi *multi, int *running_handles)
+
+{
+  CURLMcode result = multi_socket(multi, TRUE, CURL_SOCKET_BAD, 0,
+                                  running_handles);
+  if(CURLM_OK >= result)
+    update_timer(multi);
+  return result;
+}
+
+static CURLMcode multi_timeout(struct Curl_multi *multi,
+                               long *timeout_ms)
+{
+  static struct curltime tv_zero = {0, 0};
+
+  if(multi->timetree) {
+    /* we have a tree of expire times */
+    struct curltime now = Curl_now();
+
+    /* splay the lowest to the bottom */
+    multi->timetree = Curl_splay(tv_zero, multi->timetree);
+
+    if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) {
+      /* some time left before expiration */
+      timediff_t diff = Curl_timediff(multi->timetree->key, now);
+      if(diff <= 0)
+        /*
+         * Since we only provide millisecond resolution on the returned value
+         * and the diff might be less than one millisecond here, we don't
+         * return zero as that may cause short bursts of busyloops on fast
+         * processors while the diff is still present but less than one
+         * millisecond! instead we return 1 until the time is ripe.
+         */
+        *timeout_ms = 1;
+      else
+        /* this should be safe even on 64 bit archs, as we don't use that
+           overly long timeouts */
+        *timeout_ms = (long)diff;
+    }
+    else
+      /* 0 means immediately */
+      *timeout_ms = 0;
+  }
+  else
+    *timeout_ms = -1;
+
+  return CURLM_OK;
+}
+
+CURLMcode curl_multi_timeout(struct Curl_multi *multi,
+                             long *timeout_ms)
+{
+  /* First, make some basic checks that the CURLM handle is a good handle */
+  if(!GOOD_MULTI_HANDLE(multi))
+    return CURLM_BAD_HANDLE;
+
+  return multi_timeout(multi, timeout_ms);
+}
+
+/*
+ * Tell the application it should update its timers, if it subscribes to the
+ * update timer callback.
+ */
+static int update_timer(struct Curl_multi *multi)
+{
+  long timeout_ms;
+
+  if(!multi->timer_cb)
+    return 0;
+  if(multi_timeout(multi, &timeout_ms)) {
+    return -1;
+  }
+  if(timeout_ms < 0) {
+    static const struct curltime none = {0, 0};
+    if(Curl_splaycomparekeys(none, multi->timer_lastcall)) {
+      multi->timer_lastcall = none;
+      /* there's no timeout now but there was one previously, tell the app to
+         disable it */
+      return multi->timer_cb(multi, -1, multi->timer_userp);
+    }
+    return 0;
+  }
+
+  /* When multi_timeout() is done, multi->timetree points to the node with the
+   * timeout we got the (relative) time-out time for. We can thus easily check
+   * if this is the same (fixed) time as we got in a previous call and then
+   * avoid calling the callback again. */
+  if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0)
+    return 0;
+
+  multi->timer_lastcall = multi->timetree->key;
+
+  return multi->timer_cb(multi, timeout_ms, multi->timer_userp);
+}
+
+/*
+ * multi_deltimeout()
+ *
+ * Remove a given timestamp from the list of timeouts.
+ */
+static void
+multi_deltimeout(struct Curl_easy *data, expire_id eid)
+{
+  struct curl_llist_element *e;
+  struct curl_llist *timeoutlist = &data->state.timeoutlist;
+  /* find and remove the specific node from the list */
+  for(e = timeoutlist->head; e; e = e->next) {
+    struct time_node *n = (struct time_node *)e->ptr;
+    if(n->eid == eid) {
+      Curl_llist_remove(timeoutlist, e, NULL);
+      return;
+    }
+  }
+}
+
+/*
+ * multi_addtimeout()
+ *
+ * Add a timestamp to the list of timeouts. Keep the list sorted so that head
+ * of list is always the timeout nearest in time.
+ *
+ */
+static CURLMcode
+multi_addtimeout(struct Curl_easy *data,
+                 struct curltime *stamp,
+                 expire_id eid)
+{
+  struct curl_llist_element *e;
+  struct time_node *node;
+  struct curl_llist_element *prev = NULL;
+  size_t n;
+  struct curl_llist *timeoutlist = &data->state.timeoutlist;
+
+  node = &data->state.expires[eid];
+
+  /* copy the timestamp and id */
+  memcpy(&node->time, stamp, sizeof(*stamp));
+  node->eid = eid; /* also marks it as in use */
+
+  n = Curl_llist_count(timeoutlist);
+  if(n) {
+    /* find the correct spot in the list */
+    for(e = timeoutlist->head; e; e = e->next) {
+      struct time_node *check = (struct time_node *)e->ptr;
+      timediff_t diff = Curl_timediff(check->time, node->time);
+      if(diff > 0)
+        break;
+      prev = e;
+    }
+
+  }
+  /* else
+     this is the first timeout on the list */
+
+  Curl_llist_insert_next(timeoutlist, prev, node, &node->list);
+  return CURLM_OK;
+}
+
+/*
+ * Curl_expire()
+ *
+ * given a number of milliseconds from now to use to set the 'act before
+ * this'-time for the transfer, to be extracted by curl_multi_timeout()
+ *
+ * The timeout will be added to a queue of timeouts if it defines a moment in
+ * time that is later than the current head of queue.
+ *
+ * Expire replaces a former timeout using the same id if already set.
+ */
+void Curl_expire(struct Curl_easy *data, time_t milli, expire_id id)
+{
+  struct Curl_multi *multi = data->multi;
+  struct curltime *nowp = &data->state.expiretime;
+  int rc;
+  struct curltime set;
+
+  /* this is only interesting while there is still an associated multi struct
+     remaining! */
+  if(!multi)
+    return;
+
+  DEBUGASSERT(id < EXPIRE_LAST);
+
+  set = Curl_now();
+  set.tv_sec += milli/1000;
+  set.tv_usec += (unsigned int)(milli%1000)*1000;
+
+  if(set.tv_usec >= 1000000) {
+    set.tv_sec++;
+    set.tv_usec -= 1000000;
+  }
+
+  /* Remove any timer with the same id just in case. */
+  multi_deltimeout(data, id);
+
+  /* Add it to the timer list.  It must stay in the list until it has expired
+     in case we need to recompute the minimum timer later. */
+  multi_addtimeout(data, &set, id);
+
+  if(nowp->tv_sec || nowp->tv_usec) {
+    /* This means that the struct is added as a node in the splay tree.
+       Compare if the new time is earlier, and only remove-old/add-new if it
+       is. */
+    timediff_t diff = Curl_timediff(set, *nowp);
+
+    if(diff > 0) {
+      /* The current splay tree entry is sooner than this new expiry time.
+         We don't need to update our splay tree entry. */
+      return;
+    }
+
+    /* Since this is an updated time, we must remove the previous entry from
+       the splay tree first and then re-add the new value */
+    rc = Curl_splayremovebyaddr(multi->timetree,
+                                &data->state.timenode,
+                                &multi->timetree);
+    if(rc)
+      infof(data, "Internal error removing splay node = %d\n", rc);
+  }
+
+  /* Indicate that we are in the splay tree and insert the new timer expiry
+     value since it is our local minimum. */
+  *nowp = set;
+  data->state.timenode.payload = data;
+  multi->timetree = Curl_splayinsert(*nowp, multi->timetree,
+                                     &data->state.timenode);
+}
+
+/*
+ * Curl_expire_done()
+ *
+ * Removes the expire timer. Marks it as done.
+ *
+ */
+void Curl_expire_done(struct Curl_easy *data, expire_id id)
+{
+  /* remove the timer, if there */
+  multi_deltimeout(data, id);
+}
+
+/*
+ * Curl_expire_clear()
+ *
+ * Clear ALL timeout values for this handle.
+ */
+void Curl_expire_clear(struct Curl_easy *data)
+{
+  struct Curl_multi *multi = data->multi;
+  struct curltime *nowp = &data->state.expiretime;
+  int rc;
+
+  /* this is only interesting while there is still an associated multi struct
+     remaining! */
+  if(!multi)
+    return;
+
+  if(nowp->tv_sec || nowp->tv_usec) {
+    /* Since this is an cleared time, we must remove the previous entry from
+       the splay tree */
+    struct curl_llist *list = &data->state.timeoutlist;
+
+    rc = Curl_splayremovebyaddr(multi->timetree,
+                                &data->state.timenode,
+                                &multi->timetree);
+    if(rc)
+      infof(data, "Internal error clearing splay node = %d\n", rc);
+
+    /* flush the timeout list too */
+    while(list->size > 0) {
+      Curl_llist_remove(list, list->tail, NULL);
+    }
+
+#ifdef DEBUGBUILD
+    infof(data, "Expire cleared\n");
+#endif
+    nowp->tv_sec = 0;
+    nowp->tv_usec = 0;
+  }
+}
+
+
+
+
+CURLMcode curl_multi_assign(struct Curl_multi *multi, curl_socket_t s,
+                            void *hashp)
+{
+  struct Curl_sh_entry *there = NULL;
+
+  there = sh_getentry(&multi->sockhash, s);
+
+  if(!there)
+    return CURLM_BAD_SOCKET;
+
+  there->socketp = hashp;
+
+  return CURLM_OK;
+}
+
+size_t Curl_multi_max_host_connections(struct Curl_multi *multi)
+{
+  return multi ? multi->max_host_connections : 0;
+}
+
+size_t Curl_multi_max_total_connections(struct Curl_multi *multi)
+{
+  return multi ? multi->max_total_connections : 0;
+}
+
+curl_off_t Curl_multi_content_length_penalty_size(struct Curl_multi *multi)
+{
+  return multi ? multi->content_length_penalty_size : 0;
+}
+
+curl_off_t Curl_multi_chunk_length_penalty_size(struct Curl_multi *multi)
+{
+  return multi ? multi->chunk_length_penalty_size : 0;
+}
+
+struct curl_llist *Curl_multi_pipelining_site_bl(struct Curl_multi *multi)
+{
+  return &multi->pipelining_site_bl;
+}
+
+struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi)
+{
+  return &multi->pipelining_server_bl;
+}
+
+void Curl_multi_process_pending_handles(struct Curl_multi *multi)
+{
+  struct curl_llist_element *e = multi->pending.head;
+
+  while(e) {
+    struct Curl_easy *data = e->ptr;
+    struct curl_llist_element *next = e->next;
+
+    if(data->mstate == CURLM_STATE_CONNECT_PEND) {
+      multistate(data, CURLM_STATE_CONNECT);
+
+      /* Remove this node from the list */
+      Curl_llist_remove(&multi->pending, e, NULL);
+
+      /* Make sure that the handle will be processed soonish. */
+      Curl_expire(data, 0, EXPIRE_RUN_NOW);
+    }
+
+    e = next; /* operate on next handle */
+  }
+}
+
+#ifdef DEBUGBUILD
+void Curl_multi_dump(struct Curl_multi *multi)
+{
+  struct Curl_easy *data;
+  int i;
+  fprintf(stderr, "* Multi status: %d handles, %d alive\n",
+          multi->num_easy, multi->num_alive);
+  for(data = multi->easyp; data; data = data->next) {
+    if(data->mstate < CURLM_STATE_COMPLETED) {
+      /* only display handles that are not completed */
+      fprintf(stderr, "handle %p, state %s, %d sockets\n",
+              (void *)data,
+              statename[data->mstate], data->numsocks);
+      for(i = 0; i < data->numsocks; i++) {
+        curl_socket_t s = data->sockets[i];
+        struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s);
+
+        fprintf(stderr, "%d ", (int)s);
+        if(!entry) {
+          fprintf(stderr, "INTERNAL CONFUSION\n");
+          continue;
+        }
+        fprintf(stderr, "[%s %s] ",
+                entry->action&CURL_POLL_IN?"RECVING":"",
+                entry->action&CURL_POLL_OUT?"SENDING":"");
+      }
+      if(data->numsocks)
+        fprintf(stderr, "\n");
+    }
+  }
+}
+#endif
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/multihandle.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/multihandle.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/multihandle.h	(revision 331)
@@ -0,0 +1,151 @@
+#ifndef HEADER_CURL_MULTIHANDLE_H
+#define HEADER_CURL_MULTIHANDLE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "conncache.h"
+
+struct Curl_message {
+  struct curl_llist_element list;
+  /* the 'CURLMsg' is the part that is visible to the external user */
+  struct CURLMsg extmsg;
+};
+
+/* NOTE: if you add a state here, add the name to the statename[] array as
+   well!
+*/
+typedef enum {
+  CURLM_STATE_INIT,         /* 0 - start in this state */
+  CURLM_STATE_CONNECT_PEND, /* 1 - no connections, waiting for one */
+  CURLM_STATE_CONNECT,      /* 2 - resolve/connect has been sent off */
+  CURLM_STATE_WAITRESOLVE,  /* 3 - awaiting the resolve to finalize */
+  CURLM_STATE_WAITCONNECT,  /* 4 - awaiting the TCP connect to finalize */
+  CURLM_STATE_WAITPROXYCONNECT, /* 5 - awaiting HTTPS proxy SSL initialization
+                                   to complete and/or proxy CONNECT to
+                                   finalize */
+  CURLM_STATE_SENDPROTOCONNECT, /* 6 - initiate protocol connect procedure */
+  CURLM_STATE_PROTOCONNECT, /* 7 - completing the protocol-specific connect
+                                   phase */
+  CURLM_STATE_WAITDO,       /* 8 - wait for our turn to send the request */
+  CURLM_STATE_DO,           /* 9 - start send off the request (part 1) */
+  CURLM_STATE_DOING,        /* 10 - sending off the request (part 1) */
+  CURLM_STATE_DO_MORE,      /* 11 - send off the request (part 2) */
+  CURLM_STATE_DO_DONE,      /* 12 - done sending off request */
+  CURLM_STATE_WAITPERFORM,  /* 13 - wait for our turn to read the response */
+  CURLM_STATE_PERFORM,      /* 14 - transfer data */
+  CURLM_STATE_TOOFAST,      /* 15 - wait because limit-rate exceeded */
+  CURLM_STATE_DONE,         /* 16 - post data transfer operation */
+  CURLM_STATE_COMPLETED,    /* 17 - operation complete */
+  CURLM_STATE_MSGSENT,      /* 18 - the operation complete message is sent */
+  CURLM_STATE_LAST          /* 19 - not a true state, never use this */
+} CURLMstate;
+
+/* we support N sockets per easy handle. Set the corresponding bit to what
+   action we should wait for */
+#define MAX_SOCKSPEREASYHANDLE 5
+#define GETSOCK_READABLE (0x00ff)
+#define GETSOCK_WRITABLE (0xff00)
+
+#define CURLPIPE_ANY (CURLPIPE_HTTP1 | CURLPIPE_MULTIPLEX)
+
+/* This is the struct known as CURLM on the outside */
+struct Curl_multi {
+  /* First a simple identifier to easier detect if a user mix up
+     this multi handle with an easy handle. Set this to CURL_MULTI_HANDLE. */
+  long type;
+
+  /* We have a doubly-linked circular list with easy handles */
+  struct Curl_easy *easyp;
+  struct Curl_easy *easylp; /* last node */
+
+  int num_easy; /* amount of entries in the linked list above. */
+  int num_alive; /* amount of easy handles that are added but have not yet
+                    reached COMPLETE state */
+
+  struct curl_llist msglist; /* a list of messages from completed transfers */
+
+  struct curl_llist pending; /* Curl_easys that are in the
+                                CURLM_STATE_CONNECT_PEND state */
+
+  /* callback function and user data pointer for the *socket() API */
+  curl_socket_callback socket_cb;
+  void *socket_userp;
+
+  /* callback function and user data pointer for server push */
+  curl_push_callback push_cb;
+  void *push_userp;
+
+  /* Hostname cache */
+  struct curl_hash hostcache;
+
+  /* timetree points to the splay-tree of time nodes to figure out expire
+     times of all currently set timers */
+  struct Curl_tree *timetree;
+
+  /* 'sockhash' is the lookup hash for socket descriptor => easy handles (note
+     the pluralis form, there can be more than one easy handle waiting on the
+     same actual socket) */
+  struct curl_hash sockhash;
+
+  /* pipelining wanted bits (CURLPIPE*) */
+  long pipelining;
+
+  bool recheckstate; /* see Curl_multi_connchanged */
+
+  /* Shared connection cache (bundles)*/
+  struct conncache conn_cache;
+
+  long maxconnects; /* if >0, a fixed limit of the maximum number of entries
+                       we're allowed to grow the connection cache to */
+
+  long max_host_connections; /* if >0, a fixed limit of the maximum number
+                                of connections per host */
+
+  long max_total_connections; /* if >0, a fixed limit of the maximum number
+                                 of connections in total */
+
+  long max_pipeline_length; /* if >0, maximum number of requests in a
+                               pipeline */
+
+  long content_length_penalty_size; /* a connection with a
+                                       content-length bigger than
+                                       this is not considered
+                                       for pipelining */
+
+  long chunk_length_penalty_size; /* a connection with a chunk length
+                                     bigger than this is not
+                                     considered for pipelining */
+
+  struct curl_llist pipelining_site_bl; /* List of sites that are blacklisted
+                                           from pipelining */
+
+  struct curl_llist pipelining_server_bl; /* List of server types that are
+                                             blacklisted from pipelining */
+
+  /* timer callback and user data pointer for the *socket() API */
+  curl_multi_timer_callback timer_cb;
+  void *timer_userp;
+  struct curltime timer_lastcall; /* the fixed time for the timeout for the
+                                    previous callback */
+};
+
+#endif /* HEADER_CURL_MULTIHANDLE_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/multiif.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/multiif.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/multiif.h	(revision 331)
@@ -0,0 +1,99 @@
+#ifndef HEADER_CURL_MULTIIF_H
+#define HEADER_CURL_MULTIIF_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Prototypes for library-wide functions provided by multi.c
+ */
+
+void Curl_expire(struct Curl_easy *data, time_t milli, expire_id);
+void Curl_expire_clear(struct Curl_easy *data);
+void Curl_expire_done(struct Curl_easy *data, expire_id id);
+bool Curl_pipeline_wanted(const struct Curl_multi* multi, int bits);
+void Curl_multi_handlePipeBreak(struct Curl_easy *data);
+
+/* Internal version of curl_multi_init() accepts size parameters for the
+   socket and connection hashes */
+struct Curl_multi *Curl_multi_handle(int hashsize, int chashsize);
+
+/* the write bits start at bit 16 for the *getsock() bitmap */
+#define GETSOCK_WRITEBITSTART 16
+
+#define GETSOCK_BLANK 0 /* no bits set */
+
+/* set the bit for the given sock number to make the bitmap for writable */
+#define GETSOCK_WRITESOCK(x) (1 << (GETSOCK_WRITEBITSTART + (x)))
+
+/* set the bit for the given sock number to make the bitmap for readable */
+#define GETSOCK_READSOCK(x) (1 << (x))
+
+#ifdef DEBUGBUILD
+ /*
+  * Curl_multi_dump is not a stable public function, this is only meant to
+  * allow easier tracking of the internal handle's state and what sockets
+  * they use. Only for research and development DEBUGBUILD enabled builds.
+  */
+void Curl_multi_dump(struct Curl_multi *multi);
+#endif
+
+void Curl_multi_process_pending_handles(struct Curl_multi *multi);
+
+/* Return the value of the CURLMOPT_MAX_HOST_CONNECTIONS option */
+size_t Curl_multi_max_host_connections(struct Curl_multi *multi);
+
+/* Return the value of the CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE option */
+curl_off_t Curl_multi_content_length_penalty_size(struct Curl_multi *multi);
+
+/* Return the value of the CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE option */
+curl_off_t Curl_multi_chunk_length_penalty_size(struct Curl_multi *multi);
+
+/* Return the value of the CURLMOPT_PIPELINING_SITE_BL option */
+struct curl_llist *Curl_multi_pipelining_site_bl(struct Curl_multi *multi);
+
+/* Return the value of the CURLMOPT_PIPELINING_SERVER_BL option */
+struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi);
+
+/* Return the value of the CURLMOPT_MAX_TOTAL_CONNECTIONS option */
+size_t Curl_multi_max_total_connections(struct Curl_multi *multi);
+
+void Curl_multi_connchanged(struct Curl_multi *multi);
+
+/*
+ * Curl_multi_closed()
+ *
+ * Used by the connect code to tell the multi_socket code that one of the
+ * sockets we were using is about to be closed.  This function will then
+ * remove it from the sockethash for this handle to make the multi_socket API
+ * behave properly, especially for the case when libcurl will create another
+ * socket again and it gets the same file descriptor number.
+ */
+
+void Curl_multi_closed(struct connectdata *conn, curl_socket_t s);
+
+/*
+ * Add a handle and move it into PERFORM state at once. For pushed streams.
+ */
+CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
+                                 struct Curl_easy *data,
+                                 struct connectdata *conn);
+#endif /* HEADER_CURL_MULTIIF_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/netrc.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/netrc.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/netrc.c	(revision 331)
@@ -0,0 +1,205 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#include <curl/curl.h>
+#include "netrc.h"
+#include "strtok.h"
+#include "strcase.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Get user and password from .netrc when given a machine name */
+
+enum host_lookup_state {
+  NOTHING,
+  HOSTFOUND,    /* the 'machine' keyword was found */
+  HOSTVALID     /* this is "our" machine! */
+};
+
+/*
+ * @unittest: 1304
+ *
+ * *loginp and *passwordp MUST be allocated if they aren't NULL when passed
+ * in.
+ */
+int Curl_parsenetrc(const char *host,
+                    char **loginp,
+                    char **passwordp,
+                    char *netrcfile)
+{
+  FILE *file;
+  int retcode = 1;
+  int specific_login = (*loginp && **loginp != 0);
+  bool netrc_alloc = FALSE;
+  enum host_lookup_state state = NOTHING;
+
+  char state_login = 0;      /* Found a login keyword */
+  char state_password = 0;   /* Found a password keyword */
+  int state_our_login = FALSE;  /* With specific_login, found *our* login
+                                   name */
+
+#define NETRC DOT_CHAR "netrc"
+
+  if(!netrcfile) {
+    bool home_alloc = FALSE;
+    char *home = curl_getenv("HOME"); /* portable environment reader */
+    if(home) {
+      home_alloc = TRUE;
+#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
+    }
+    else {
+      struct passwd pw, *pw_res;
+      char pwbuf[1024];
+      if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res)
+         && pw_res) {
+        home = strdup(pw.pw_dir);
+        if(!home)
+          return CURLE_OUT_OF_MEMORY;
+        home_alloc = TRUE;
+      }
+#elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
+    }
+    else {
+      struct passwd *pw;
+      pw = getpwuid(geteuid());
+      if(pw) {
+        home = pw->pw_dir;
+      }
+#endif
+    }
+
+    if(!home)
+      return retcode; /* no home directory found (or possibly out of memory) */
+
+    netrcfile = curl_maprintf("%s%s%s", home, DIR_CHAR, NETRC);
+    if(home_alloc)
+      free(home);
+    if(!netrcfile) {
+      return -1;
+    }
+    netrc_alloc = TRUE;
+  }
+
+  file = fopen(netrcfile, FOPEN_READTEXT);
+  if(netrc_alloc)
+    free(netrcfile);
+  if(file) {
+    char *tok;
+    char *tok_buf;
+    bool done = FALSE;
+    char netrcbuffer[256];
+    int  netrcbuffsize = (int)sizeof(netrcbuffer);
+
+    while(!done && fgets(netrcbuffer, netrcbuffsize, file)) {
+      tok = strtok_r(netrcbuffer, " \t\n", &tok_buf);
+      if(tok && *tok == '#')
+        /* treat an initial hash as a comment line */
+        continue;
+      while(!done && tok) {
+
+        if((*loginp && **loginp) && (*passwordp && **passwordp)) {
+          done = TRUE;
+          break;
+        }
+
+        switch(state) {
+        case NOTHING:
+          if(strcasecompare("machine", tok)) {
+            /* the next tok is the machine name, this is in itself the
+               delimiter that starts the stuff entered for this machine,
+               after this we need to search for 'login' and
+               'password'. */
+            state = HOSTFOUND;
+          }
+          else if(strcasecompare("default", tok)) {
+            state = HOSTVALID;
+            retcode = 0; /* we did find our host */
+          }
+          break;
+        case HOSTFOUND:
+          if(strcasecompare(host, tok)) {
+            /* and yes, this is our host! */
+            state = HOSTVALID;
+            retcode = 0; /* we did find our host */
+          }
+          else
+            /* not our host */
+            state = NOTHING;
+          break;
+        case HOSTVALID:
+          /* we are now parsing sub-keywords concerning "our" host */
+          if(state_login) {
+            if(specific_login) {
+              state_our_login = strcasecompare(*loginp, tok);
+            }
+            else {
+              free(*loginp);
+              *loginp = strdup(tok);
+              if(!*loginp) {
+                retcode = -1; /* allocation failed */
+                goto out;
+              }
+            }
+            state_login = 0;
+          }
+          else if(state_password) {
+            if(state_our_login || !specific_login) {
+              free(*passwordp);
+              *passwordp = strdup(tok);
+              if(!*passwordp) {
+                retcode = -1; /* allocation failed */
+                goto out;
+              }
+            }
+            state_password = 0;
+          }
+          else if(strcasecompare("login", tok))
+            state_login = 1;
+          else if(strcasecompare("password", tok))
+            state_password = 1;
+          else if(strcasecompare("machine", tok)) {
+            /* ok, there's machine here go => */
+            state = HOSTFOUND;
+            state_our_login = FALSE;
+          }
+          break;
+        } /* switch (state) */
+
+        tok = strtok_r(NULL, " \t\n", &tok_buf);
+      } /* while(tok) */
+    } /* while fgets() */
+
+    out:
+    fclose(file);
+  }
+
+  return retcode;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/netrc.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/netrc.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/netrc.h	(revision 331)
@@ -0,0 +1,36 @@
+#ifndef HEADER_CURL_NETRC_H
+#define HEADER_CURL_NETRC_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */
+int Curl_parsenetrc(const char *host,
+                    char **loginp,
+                    char **passwordp,
+                    char *filename);
+  /* Assume: (*passwordp)[0]=0, host[0] != 0.
+   * If (*loginp)[0] = 0, search for login and password within a machine
+   * section in the netrc.
+   * If (*loginp)[0] != 0, search for password within machine and login.
+   */
+
+#endif /* HEADER_CURL_NETRC_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/non-ascii.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/non-ascii.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/non-ascii.c	(revision 331)
@@ -0,0 +1,322 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef CURL_DOES_CONVERSIONS
+
+#include <curl/curl.h>
+
+#include "non-ascii.h"
+#include "formdata.h"
+#include "sendf.h"
+#include "urldata.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifdef HAVE_ICONV
+#include <iconv.h>
+/* set default codesets for iconv */
+#ifndef CURL_ICONV_CODESET_OF_NETWORK
+#define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
+#endif
+#ifndef CURL_ICONV_CODESET_FOR_UTF8
+#define CURL_ICONV_CODESET_FOR_UTF8   "UTF-8"
+#endif
+#define ICONV_ERROR  (size_t)-1
+#endif /* HAVE_ICONV */
+
+/*
+ * Curl_convert_clone() returns a malloced copy of the source string (if
+ * returning CURLE_OK), with the data converted to network format.
+ */
+CURLcode Curl_convert_clone(struct Curl_easy *data,
+                           const char *indata,
+                           size_t insize,
+                           char **outbuf)
+{
+  char *convbuf;
+  CURLcode result;
+
+  convbuf = malloc(insize);
+  if(!convbuf)
+    return CURLE_OUT_OF_MEMORY;
+
+  memcpy(convbuf, indata, insize);
+  result = Curl_convert_to_network(data, convbuf, insize);
+  if(result) {
+    free(convbuf);
+    return result;
+  }
+
+  *outbuf = convbuf; /* return the converted buffer */
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_convert_to_network() is an internal function for performing ASCII
+ * conversions on non-ASCII platforms. It convers the buffer _in place_.
+ */
+CURLcode Curl_convert_to_network(struct Curl_easy *data,
+                                 char *buffer, size_t length)
+{
+  if(data && data->set.convtonetwork) {
+    /* use translation callback */
+    CURLcode result = data->set.convtonetwork(buffer, length);
+    if(result) {
+      failf(data,
+            "CURLOPT_CONV_TO_NETWORK_FUNCTION callback returned %d: %s",
+            (int)result, curl_easy_strerror(result));
+    }
+
+    return result;
+  }
+  else {
+#ifdef HAVE_ICONV
+    /* do the translation ourselves */
+    iconv_t tmpcd = (iconv_t) -1;
+    iconv_t *cd = &tmpcd;
+    char *input_ptr, *output_ptr;
+    size_t in_bytes, out_bytes, rc;
+
+    /* open an iconv conversion descriptor if necessary */
+    if(data)
+      cd = &data->outbound_cd;
+    if(*cd == (iconv_t)-1) {
+      *cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
+                       CURL_ICONV_CODESET_OF_HOST);
+      if(*cd == (iconv_t)-1) {
+        failf(data,
+              "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
+              CURL_ICONV_CODESET_OF_NETWORK,
+              CURL_ICONV_CODESET_OF_HOST,
+              errno, strerror(errno));
+        return CURLE_CONV_FAILED;
+      }
+    }
+    /* call iconv */
+    input_ptr = output_ptr = buffer;
+    in_bytes = out_bytes = length;
+    rc = iconv(*cd, &input_ptr, &in_bytes,
+               &output_ptr, &out_bytes);
+    if(!data)
+      iconv_close(tmpcd);
+    if((rc == ICONV_ERROR) || (in_bytes != 0)) {
+      failf(data,
+            "The Curl_convert_to_network iconv call failed with errno %i: %s",
+            errno, strerror(errno));
+      return CURLE_CONV_FAILED;
+    }
+#else
+    failf(data, "CURLOPT_CONV_TO_NETWORK_FUNCTION callback required");
+    return CURLE_CONV_REQD;
+#endif /* HAVE_ICONV */
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_convert_from_network() is an internal function for performing ASCII
+ * conversions on non-ASCII platforms. It convers the buffer _in place_.
+ */
+CURLcode Curl_convert_from_network(struct Curl_easy *data,
+                                   char *buffer, size_t length)
+{
+  if(data && data->set.convfromnetwork) {
+    /* use translation callback */
+    CURLcode result = data->set.convfromnetwork(buffer, length);
+    if(result) {
+      failf(data,
+            "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback returned %d: %s",
+            (int)result, curl_easy_strerror(result));
+    }
+
+    return result;
+  }
+  else {
+#ifdef HAVE_ICONV
+    /* do the translation ourselves */
+    iconv_t tmpcd = (iconv_t) -1;
+    iconv_t *cd = &tmpcd;
+    char *input_ptr, *output_ptr;
+    size_t in_bytes, out_bytes, rc;
+
+    /* open an iconv conversion descriptor if necessary */
+    if(data)
+      cd = &data->inbound_cd;
+    if(*cd == (iconv_t)-1) {
+      *cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
+                       CURL_ICONV_CODESET_OF_NETWORK);
+      if(*cd == (iconv_t)-1) {
+        failf(data,
+              "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
+              CURL_ICONV_CODESET_OF_HOST,
+              CURL_ICONV_CODESET_OF_NETWORK,
+              errno, strerror(errno));
+        return CURLE_CONV_FAILED;
+      }
+    }
+    /* call iconv */
+    input_ptr = output_ptr = buffer;
+    in_bytes = out_bytes = length;
+    rc = iconv(*cd, &input_ptr, &in_bytes,
+               &output_ptr, &out_bytes);
+    if(!data)
+      iconv_close(tmpcd);
+    if((rc == ICONV_ERROR) || (in_bytes != 0)) {
+      failf(data,
+            "Curl_convert_from_network iconv call failed with errno %i: %s",
+            errno, strerror(errno));
+      return CURLE_CONV_FAILED;
+    }
+#else
+    failf(data, "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback required");
+    return CURLE_CONV_REQD;
+#endif /* HAVE_ICONV */
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_convert_from_utf8() is an internal function for performing UTF-8
+ * conversions on non-ASCII platforms.
+ */
+CURLcode Curl_convert_from_utf8(struct Curl_easy *data,
+                                char *buffer, size_t length)
+{
+  if(data && data->set.convfromutf8) {
+    /* use translation callback */
+    CURLcode result = data->set.convfromutf8(buffer, length);
+    if(result) {
+      failf(data,
+            "CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %d: %s",
+            (int)result, curl_easy_strerror(result));
+    }
+
+    return result;
+  }
+  else {
+#ifdef HAVE_ICONV
+    /* do the translation ourselves */
+    iconv_t tmpcd = (iconv_t) -1;
+    iconv_t *cd = &tmpcd;
+    char *input_ptr;
+    char *output_ptr;
+    size_t in_bytes, out_bytes, rc;
+
+    /* open an iconv conversion descriptor if necessary */
+    if(data)
+      cd = &data->utf8_cd;
+    if(*cd == (iconv_t)-1) {
+      *cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
+                       CURL_ICONV_CODESET_FOR_UTF8);
+      if(*cd == (iconv_t)-1) {
+        failf(data,
+              "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
+              CURL_ICONV_CODESET_OF_HOST,
+              CURL_ICONV_CODESET_FOR_UTF8,
+              errno, strerror(errno));
+        return CURLE_CONV_FAILED;
+      }
+    }
+    /* call iconv */
+    input_ptr = output_ptr = buffer;
+    in_bytes = out_bytes = length;
+    rc = iconv(*cd, &input_ptr, &in_bytes,
+               &output_ptr, &out_bytes);
+    if(!data)
+      iconv_close(tmpcd);
+    if((rc == ICONV_ERROR) || (in_bytes != 0)) {
+      failf(data,
+            "The Curl_convert_from_utf8 iconv call failed with errno %i: %s",
+            errno, strerror(errno));
+      return CURLE_CONV_FAILED;
+    }
+    if(output_ptr < input_ptr) {
+      /* null terminate the now shorter output string */
+      *output_ptr = 0x00;
+    }
+#else
+    failf(data, "CURLOPT_CONV_FROM_UTF8_FUNCTION callback required");
+    return CURLE_CONV_REQD;
+#endif /* HAVE_ICONV */
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Init conversion stuff for a Curl_easy
+ */
+void Curl_convert_init(struct Curl_easy *data)
+{
+#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
+  /* conversion descriptors for iconv calls */
+  data->outbound_cd = (iconv_t)-1;
+  data->inbound_cd  = (iconv_t)-1;
+  data->utf8_cd     = (iconv_t)-1;
+#else
+  (void)data;
+#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
+}
+
+/*
+ * Setup conversion stuff for a Curl_easy
+ */
+void Curl_convert_setup(struct Curl_easy *data)
+{
+  data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
+                                CURL_ICONV_CODESET_OF_NETWORK);
+  data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
+                                 CURL_ICONV_CODESET_OF_HOST);
+  data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
+                             CURL_ICONV_CODESET_FOR_UTF8);
+}
+
+/*
+ * Close conversion stuff for a Curl_easy
+ */
+
+void Curl_convert_close(struct Curl_easy *data)
+{
+#ifdef HAVE_ICONV
+  /* close iconv conversion descriptors */
+  if(data->inbound_cd != (iconv_t)-1) {
+    iconv_close(data->inbound_cd);
+  }
+  if(data->outbound_cd != (iconv_t)-1) {
+    iconv_close(data->outbound_cd);
+  }
+  if(data->utf8_cd != (iconv_t)-1) {
+    iconv_close(data->utf8_cd);
+  }
+#else
+  (void)data;
+#endif /* HAVE_ICONV */
+}
+
+#endif /* CURL_DOES_CONVERSIONS */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/non-ascii.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/non-ascii.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/non-ascii.h	(revision 331)
@@ -0,0 +1,61 @@
+#ifndef HEADER_CURL_NON_ASCII_H
+#define HEADER_CURL_NON_ASCII_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef CURL_DOES_CONVERSIONS
+
+#include "urldata.h"
+
+/*
+ * Curl_convert_clone() returns a malloced copy of the source string (if
+ * returning CURLE_OK), with the data converted to network format.
+ *
+ * If no conversion was needed *outbuf may be NULL.
+ */
+CURLcode Curl_convert_clone(struct Curl_easy *data,
+                            const char *indata,
+                            size_t insize,
+                            char **outbuf);
+
+void Curl_convert_init(struct Curl_easy *data);
+void Curl_convert_setup(struct Curl_easy *data);
+void Curl_convert_close(struct Curl_easy *data);
+
+CURLcode Curl_convert_to_network(struct Curl_easy *data,
+                                 char *buffer, size_t length);
+CURLcode Curl_convert_from_network(struct Curl_easy *data,
+                                 char *buffer, size_t length);
+CURLcode Curl_convert_from_utf8(struct Curl_easy *data,
+                                 char *buffer, size_t length);
+#else
+#define Curl_convert_clone(a,b,c,d) ((void)a, CURLE_OK)
+#define Curl_convert_init(x) Curl_nop_stmt
+#define Curl_convert_setup(x) Curl_nop_stmt
+#define Curl_convert_close(x) Curl_nop_stmt
+#define Curl_convert_to_network(a,b,c) ((void)a, CURLE_OK)
+#define Curl_convert_from_network(a,b,c) ((void)a, CURLE_OK)
+#define Curl_convert_from_utf8(a,b,c) ((void)a, CURLE_OK)
+#endif
+
+#endif /* HEADER_CURL_NON_ASCII_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/nonblock.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/nonblock.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/nonblock.c	(revision 331)
@@ -0,0 +1,90 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#if (defined(HAVE_IOCTL_FIONBIO) && defined(NETWARE))
+#include <sys/filio.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#include "nonblock.h"
+
+/*
+ * curlx_nonblock() set the given socket to either blocking or non-blocking
+ * mode based on the 'nonblock' boolean argument. This function is highly
+ * portable.
+ */
+int curlx_nonblock(curl_socket_t sockfd,    /* operate on this */
+                   int nonblock   /* TRUE or FALSE */)
+{
+#if defined(USE_BLOCKING_SOCKETS)
+
+  return 0; /* returns success */
+
+#elif defined(HAVE_FCNTL_O_NONBLOCK)
+
+  /* most recent unix versions */
+  int flags;
+  flags = sfcntl(sockfd, F_GETFL, 0);
+  if(nonblock)
+    return sfcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
+  return sfcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
+
+#elif defined(HAVE_IOCTL_FIONBIO)
+
+  /* older unix versions */
+  int flags = nonblock ? 1 : 0;
+  return ioctl(sockfd, FIONBIO, &flags);
+
+#elif defined(HAVE_IOCTLSOCKET_FIONBIO)
+
+  /* Windows */
+  unsigned long flags = nonblock ? 1UL : 0UL;
+  return ioctlsocket(sockfd, FIONBIO, &flags);
+
+#elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO)
+
+  /* Amiga */
+  long flags = nonblock ? 1L : 0L;
+  return IoctlSocket(sockfd, FIONBIO, (char *)&flags);
+
+#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK)
+
+  /* BeOS */
+  long b = nonblock ? 1L : 0L;
+  return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
+
+#else
+#  error "no non-blocking method was found/used/set"
+#endif
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/nonblock.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/nonblock.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/nonblock.h	(revision 331)
@@ -0,0 +1,31 @@
+#ifndef HEADER_CURL_NONBLOCK_H
+#define HEADER_CURL_NONBLOCK_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h> /* for curl_socket_t */
+
+int curlx_nonblock(curl_socket_t sockfd,    /* operate on this */
+                   int nonblock   /* TRUE or FALSE */);
+
+#endif /* HEADER_CURL_NONBLOCK_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/nwlib.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/nwlib.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/nwlib.c	(revision 331)
@@ -0,0 +1,327 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef NETWARE /* Novell NetWare */
+
+#ifdef __NOVELL_LIBC__
+/* For native LibC-based NLM we need to register as a real lib. */
+#include <library.h>
+#include <netware.h>
+#include <screen.h>
+#include <nks/thread.h>
+#include <nks/synch.h>
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+typedef struct
+{
+  int     _errno;
+  void    *twentybytes;
+} libthreaddata_t;
+
+typedef struct
+{
+  int         x;
+  int         y;
+  int         z;
+  void        *tenbytes;
+  NXKey_t     perthreadkey;   /* if -1, no key obtained... */
+  NXMutex_t   *lock;
+} libdata_t;
+
+int         gLibId      = -1;
+void        *gLibHandle = (void *) NULL;
+rtag_t      gAllocTag   = (rtag_t) NULL;
+NXMutex_t   *gLibLock   = (NXMutex_t *) NULL;
+
+/* internal library function prototypes... */
+int  DisposeLibraryData(void *);
+void DisposeThreadData(void *);
+int  GetOrSetUpData(int id, libdata_t **data, libthreaddata_t **threaddata);
+
+
+int _NonAppStart(void        *NLMHandle,
+                 void        *errorScreen,
+                 const char  *cmdLine,
+                 const char  *loadDirPath,
+                 size_t      uninitializedDataLength,
+                 void        *NLMFileHandle,
+                 int         (*readRoutineP)(int conn,
+                                             void *fileHandle, size_t offset,
+                                             size_t nbytes,
+                                             size_t *bytesRead,
+                                             void *buffer),
+                  size_t      customDataOffset,
+                  size_t      customDataSize,
+                  int         messageCount,
+                  const char  **messages)
+{
+  NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0);
+
+#ifndef __GNUC__
+#pragma unused(cmdLine)
+#pragma unused(loadDirPath)
+#pragma unused(uninitializedDataLength)
+#pragma unused(NLMFileHandle)
+#pragma unused(readRoutineP)
+#pragma unused(customDataOffset)
+#pragma unused(customDataSize)
+#pragma unused(messageCount)
+#pragma unused(messages)
+#endif
+
+  /*
+   * Here we process our command line, post errors (to the error screen),
+   * perform initializations and anything else we need to do before being able
+   * to accept calls into us. If we succeed, we return non-zero and the NetWare
+   * Loader will leave us up, otherwise we fail to load and get dumped.
+   */
+  gAllocTag = AllocateResourceTag(NLMHandle,
+                                  "<library-name> memory allocations",
+                                  AllocSignature);
+
+  if(!gAllocTag) {
+    OutputToScreen(errorScreen, "Unable to allocate resource tag for "
+                   "library memory allocations.\n");
+    return -1;
+  }
+
+  gLibId = register_library(DisposeLibraryData);
+
+  if(gLibId < -1) {
+    OutputToScreen(errorScreen, "Unable to register library with kernel.\n");
+    return -1;
+  }
+
+  gLibHandle = NLMHandle;
+
+  gLibLock = NXMutexAlloc(0, 0, &liblock);
+
+  if(!gLibLock) {
+    OutputToScreen(errorScreen, "Unable to allocate library data lock.\n");
+    return -1;
+  }
+
+  return 0;
+}
+
+/*
+ * Here we clean up any resources we allocated. Resource tags is a big part
+ * of what we created, but NetWare doesn't ask us to free those.
+ */
+void _NonAppStop(void)
+{
+  (void) unregister_library(gLibId);
+  NXMutexFree(gLibLock);
+}
+
+/*
+ * This function cannot be the first in the file for if the file is linked
+ * first, then the check-unload function's offset will be nlmname.nlm+0
+ * which is how to tell that there isn't one. When the check function is
+ * first in the linked objects, it is ambiguous. For this reason, we will
+ * put it inside this file after the stop function.
+ *
+ * Here we check to see if it's alright to ourselves to be unloaded. If not,
+ * we return a non-zero value. Right now, there isn't any reason not to allow
+ * it.
+ */
+int _NonAppCheckUnload(void)
+{
+    return 0;
+}
+
+int GetOrSetUpData(int id, libdata_t **appData,
+                   libthreaddata_t **threadData)
+{
+  int                 err;
+  libdata_t           *app_data;
+  libthreaddata_t *thread_data;
+  NXKey_t             key;
+  NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0);
+
+  err         = 0;
+  thread_data = (libthreaddata_t *) NULL;
+
+  /*
+   * Attempt to get our data for the application calling us. This is where we
+   * store whatever application-specific information we need to carry in
+   * support of calling applications.
+   */
+  app_data = (libdata_t *) get_app_data(id);
+
+  if(!app_data) {
+    /*
+     * This application hasn't called us before; set up application AND
+     * per-thread data. Of course, just in case a thread from this same
+     * application is calling us simultaneously, we better lock our application
+     * data-creation mutex. We also need to recheck for data after we acquire
+     * the lock because WE might be that other thread that was too late to
+     * create the data and the first thread in will have created it.
+     */
+    NXLock(gLibLock);
+
+    app_data = (libdata_t *) get_app_data(id);
+    if(!app_data) {
+      app_data = malloc(sizeof(libdata_t));
+
+      if(app_data) {
+        memset(app_data, 0, sizeof(libdata_t));
+
+        app_data->tenbytes = malloc(10);
+        app_data->lock     = NXMutexAlloc(0, 0, &liblock);
+
+        if(!app_data->tenbytes || !app_data->lock) {
+          if(app_data->lock)
+            NXMutexFree(app_data->lock);
+
+          free(app_data);
+          app_data = (libdata_t *) NULL;
+          err      = ENOMEM;
+        }
+
+        if(app_data) {
+          /*
+           * Here we burn in the application data that we were trying to get
+           * by calling get_app_data(). Next time we call the first function,
+           * we'll get this data we're just now setting. We also go on here to
+           * establish the per-thread data for the calling thread, something
+           * we'll have to do on each application thread the first time
+           * it calls us.
+           */
+          err = set_app_data(gLibId, app_data);
+
+          if(err) {
+            free(app_data);
+            app_data = (libdata_t *) NULL;
+            err      = ENOMEM;
+          }
+          else {
+            /* create key for thread-specific data... */
+            err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key);
+
+            if(err)                /* (no more keys left?) */
+              key = -1;
+
+            app_data->perthreadkey = key;
+          }
+        }
+      }
+    }
+
+    NXUnlock(gLibLock);
+  }
+
+  if(app_data) {
+    key = app_data->perthreadkey;
+
+    if(key != -1 /* couldn't create a key? no thread data */
+        && !(err = NXKeyGetValue(key, (void **) &thread_data))
+        && !thread_data) {
+      /*
+       * Allocate the per-thread data for the calling thread. Regardless of
+       * whether there was already application data or not, this may be the
+       * first call by a new thread. The fact that we allocation 20 bytes on
+       * a pointer is not very important, this just helps to demonstrate that
+       * we can have arbitrarily complex per-thread data.
+       */
+      thread_data = malloc(sizeof(libthreaddata_t));
+
+      if(thread_data) {
+        thread_data->_errno      = 0;
+        thread_data->twentybytes = malloc(20);
+
+        if(!thread_data->twentybytes) {
+          free(thread_data);
+          thread_data = (libthreaddata_t *) NULL;
+          err         = ENOMEM;
+        }
+
+        err = NXKeySetValue(key, thread_data);
+        if(err) {
+          free(thread_data->twentybytes);
+          free(thread_data);
+          thread_data = (libthreaddata_t *) NULL;
+        }
+      }
+    }
+  }
+
+  if(appData)
+    *appData = app_data;
+
+  if(threadData)
+    *threadData = thread_data;
+
+  return err;
+}
+
+int DisposeLibraryData(void *data)
+{
+  if(data) {
+    void *tenbytes = ((libdata_t *) data)->tenbytes;
+
+    free(tenbytes);
+    free(data);
+  }
+
+  return 0;
+}
+
+void DisposeThreadData(void *data)
+{
+  if(data) {
+    void *twentybytes = ((libthreaddata_t *) data)->twentybytes;
+
+    free(twentybytes);
+    free(data);
+  }
+}
+
+#else /* __NOVELL_LIBC__ */
+/* For native CLib-based NLM seems we can do a bit more simple. */
+#include <nwthread.h>
+
+int main(void)
+{
+  /* initialize any globals here... */
+
+  /* do this if any global initializing was done
+  SynchronizeStart();
+  */
+  ExitThread(TSR_THREAD, 0);
+  return 0;
+}
+
+#endif /* __NOVELL_LIBC__ */
+
+#else /* NETWARE */
+
+#ifdef __POCC__
+#  pragma warn(disable:2024)  /* Disable warning #2024: Empty input file */
+#endif
+
+#endif /* NETWARE */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/nwos.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/nwos.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/nwos.c	(revision 331)
@@ -0,0 +1,88 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef NETWARE /* Novell NetWare */
+
+#ifdef __NOVELL_LIBC__
+/* For native LibC-based NLM we need to do nothing. */
+int netware_init(void)
+{
+  return 0;
+}
+
+#else /* __NOVELL_LIBC__ */
+
+/* For native CLib-based NLM we need to initialize the LONG namespace. */
+#include <nwnspace.h>
+#include <nwthread.h>
+#include <nwadv.h>
+/* Make the CLIB Ctx stuff link */
+#include <netdb.h>
+NETDB_DEFINE_CONTEXT
+/* Make the CLIB Inet stuff link */
+#include <netinet/in.h>
+#include <arpa/inet.h>
+NETINET_DEFINE_CONTEXT
+
+int netware_init(void)
+{
+  int rc = 0;
+  unsigned int myHandle = GetNLMHandle();
+  /* import UnAugmentAsterisk dynamically for NW4.x compatibility */
+  void (*pUnAugmentAsterisk)(int) = (void(*)(int))
+          ImportSymbol(myHandle, "UnAugmentAsterisk");
+  /* import UseAccurateCaseForPaths dynamically for NW3.x compatibility */
+  void (*pUseAccurateCaseForPaths)(int) = (void(*)(int))
+          ImportSymbol(myHandle, "UseAccurateCaseForPaths");
+  if(pUnAugmentAsterisk)
+    pUnAugmentAsterisk(1);
+  if(pUseAccurateCaseForPaths)
+    pUseAccurateCaseForPaths(1);
+  UnimportSymbol(myHandle, "UnAugmentAsterisk");
+  UnimportSymbol(myHandle, "UseAccurateCaseForPaths");
+  /* set long name space */
+  if((SetCurrentNameSpace(4) == 255)) {
+    rc = 1;
+  }
+  if((SetTargetNameSpace(4) == 255)) {
+    rc = rc + 2;
+  }
+  return rc;
+}
+
+/* dummy function to satisfy newer prelude */
+int __init_environment(void)
+{
+  return 0;
+}
+
+/* dummy function to satisfy newer prelude */
+int __deinit_environment(void)
+{
+  return 0;
+}
+
+#endif /* __NOVELL_LIBC__ */
+
+#endif /* NETWARE */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/openldap.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/openldap.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/openldap.c	(revision 331)
@@ -0,0 +1,713 @@
+/***************************************************************************
+ *                      _   _ ____  _
+ *  Project         ___| | | |  _ \| |
+ *                 / __| | | | |_) | |
+ *                | (__| |_| |  _ <| |___
+ *                 \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010, 2017, Howard Chu, <hyc@openldap.org>
+ * Copyright (C) 2011 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_LDAP) && defined(USE_OPENLDAP)
+
+/*
+ * Notice that USE_OPENLDAP is only a source code selection switch. When
+ * libcurl is built with USE_OPENLDAP defined the libcurl source code that
+ * gets compiled is the code from openldap.c, otherwise the code that gets
+ * compiled is the code from ldap.c.
+ *
+ * When USE_OPENLDAP is defined a recent version of the OpenLDAP library
+ * might be required for compilation and runtime. In order to use ancient
+ * OpenLDAP library versions, USE_OPENLDAP shall not be defined.
+ */
+
+#include <ldap.h>
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "sendf.h"
+#include "vtls/vtls.h"
+#include "transfer.h"
+#include "curl_ldap.h"
+#include "curl_base64.h"
+#include "connect.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifndef _LDAP_PVT_H
+extern int ldap_pvt_url_scheme2proto(const char *);
+extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url,
+                        LDAP **ld);
+#endif
+
+static CURLcode ldap_setup_connection(struct connectdata *conn);
+static CURLcode ldap_do(struct connectdata *conn, bool *done);
+static CURLcode ldap_done(struct connectdata *conn, CURLcode, bool);
+static CURLcode ldap_connect(struct connectdata *conn, bool *done);
+static CURLcode ldap_connecting(struct connectdata *conn, bool *done);
+static CURLcode ldap_disconnect(struct connectdata *conn, bool dead);
+
+static Curl_recv ldap_recv;
+
+/*
+ * LDAP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_ldap = {
+  "LDAP",                               /* scheme */
+  ldap_setup_connection,                /* setup_connection */
+  ldap_do,                              /* do_it */
+  ldap_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  ldap_connect,                         /* connect_it */
+  ldap_connecting,                      /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ldap_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_LDAP,                            /* defport */
+  CURLPROTO_LDAP,                       /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * LDAPS protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_ldaps = {
+  "LDAPS",                              /* scheme */
+  ldap_setup_connection,                /* setup_connection */
+  ldap_do,                              /* do_it */
+  ldap_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  ldap_connect,                         /* connect_it */
+  ldap_connecting,                      /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ldap_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_LDAPS,                           /* defport */
+  CURLPROTO_LDAP,                       /* protocol */
+  PROTOPT_SSL                           /* flags */
+};
+#endif
+
+static const char *url_errs[] = {
+  "success",
+  "out of memory",
+  "bad parameter",
+  "unrecognized scheme",
+  "unbalanced delimiter",
+  "bad URL",
+  "bad host or port",
+  "bad or missing attributes",
+  "bad or missing scope",
+  "bad or missing filter",
+  "bad or missing extensions"
+};
+
+typedef struct ldapconninfo {
+  LDAP *ld;
+  Curl_recv *recv;  /* for stacking SSL handler */
+  Curl_send *send;
+  int proto;
+  int msgid;
+  bool ssldone;
+  bool sslinst;
+  bool didbind;
+} ldapconninfo;
+
+typedef struct ldapreqinfo {
+  int msgid;
+  int nument;
+} ldapreqinfo;
+
+static CURLcode ldap_setup_connection(struct connectdata *conn)
+{
+  ldapconninfo *li;
+  LDAPURLDesc *lud;
+  struct Curl_easy *data = conn->data;
+  int rc, proto;
+  CURLcode status;
+
+  rc = ldap_url_parse(data->change.url, &lud);
+  if(rc != LDAP_URL_SUCCESS) {
+    const char *msg = "url parsing problem";
+    status = CURLE_URL_MALFORMAT;
+    if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) {
+      if(rc == LDAP_URL_ERR_MEM)
+        status = CURLE_OUT_OF_MEMORY;
+      msg = url_errs[rc];
+    }
+    failf(conn->data, "LDAP local: %s", msg);
+    return status;
+  }
+  proto = ldap_pvt_url_scheme2proto(lud->lud_scheme);
+  ldap_free_urldesc(lud);
+
+  li = calloc(1, sizeof(ldapconninfo));
+  if(!li)
+    return CURLE_OUT_OF_MEMORY;
+  li->proto = proto;
+  conn->proto.generic = li;
+  connkeep(conn, "OpenLDAP default");
+  /* TODO:
+   * - provide option to choose SASL Binds instead of Simple
+   */
+  return CURLE_OK;
+}
+
+#ifdef USE_SSL
+static Sockbuf_IO ldapsb_tls;
+#endif
+
+static CURLcode ldap_connect(struct connectdata *conn, bool *done)
+{
+  ldapconninfo *li = conn->proto.generic;
+  struct Curl_easy *data = conn->data;
+  int rc, proto = LDAP_VERSION3;
+  char hosturl[1024];
+  char *ptr;
+
+  (void)done;
+
+  strcpy(hosturl, "ldap");
+  ptr = hosturl + 4;
+  if(conn->handler->flags & PROTOPT_SSL)
+    *ptr++ = 's';
+  snprintf(ptr, sizeof(hosturl)-(ptr-hosturl), "://%s:%d",
+    conn->host.name, conn->remote_port);
+
+  rc = ldap_init_fd(conn->sock[FIRSTSOCKET], li->proto, hosturl, &li->ld);
+  if(rc) {
+    failf(data, "LDAP local: Cannot connect to %s, %s",
+          hosturl, ldap_err2string(rc));
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
+
+#ifdef USE_SSL
+  if(conn->handler->flags & PROTOPT_SSL) {
+    CURLcode result;
+    result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &li->ssldone);
+    if(result)
+      return result;
+  }
+#endif
+
+  return CURLE_OK;
+}
+
+static CURLcode ldap_connecting(struct connectdata *conn, bool *done)
+{
+  ldapconninfo *li = conn->proto.generic;
+  struct Curl_easy *data = conn->data;
+  LDAPMessage *msg = NULL;
+  struct timeval tv = {0, 1}, *tvp;
+  int rc, err;
+  char *info = NULL;
+
+#ifdef USE_SSL
+  if(conn->handler->flags & PROTOPT_SSL) {
+    /* Is the SSL handshake complete yet? */
+    if(!li->ssldone) {
+      CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET,
+                                                     &li->ssldone);
+      if(result || !li->ssldone)
+        return result;
+    }
+
+    /* Have we installed the libcurl SSL handlers into the sockbuf yet? */
+    if(!li->sslinst) {
+      Sockbuf *sb;
+      ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb);
+      ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, conn);
+      li->sslinst = TRUE;
+      li->recv = conn->recv[FIRSTSOCKET];
+      li->send = conn->send[FIRSTSOCKET];
+    }
+  }
+#endif
+
+  tvp = &tv;
+
+retry:
+  if(!li->didbind) {
+    char *binddn;
+    struct berval passwd;
+
+    if(conn->bits.user_passwd) {
+      binddn = conn->user;
+      passwd.bv_val = conn->passwd;
+      passwd.bv_len = strlen(passwd.bv_val);
+    }
+    else {
+      binddn = NULL;
+      passwd.bv_val = NULL;
+      passwd.bv_len = 0;
+    }
+    rc = ldap_sasl_bind(li->ld, binddn, LDAP_SASL_SIMPLE, &passwd,
+                        NULL, NULL, &li->msgid);
+    if(rc)
+      return CURLE_LDAP_CANNOT_BIND;
+    li->didbind = TRUE;
+    if(tvp)
+      return CURLE_OK;
+  }
+
+  rc = ldap_result(li->ld, li->msgid, LDAP_MSG_ONE, tvp, &msg);
+  if(rc < 0) {
+    failf(data, "LDAP local: bind ldap_result %s", ldap_err2string(rc));
+    return CURLE_LDAP_CANNOT_BIND;
+  }
+  if(rc == 0) {
+    /* timed out */
+    return CURLE_OK;
+  }
+
+  rc = ldap_parse_result(li->ld, msg, &err, NULL, &info, NULL, NULL, 1);
+  if(rc) {
+    failf(data, "LDAP local: bind ldap_parse_result %s", ldap_err2string(rc));
+    return CURLE_LDAP_CANNOT_BIND;
+  }
+
+  /* Try to fallback to LDAPv2? */
+  if(err == LDAP_PROTOCOL_ERROR) {
+    int proto;
+    ldap_get_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
+    if(proto == LDAP_VERSION3) {
+      if(info) {
+        ldap_memfree(info);
+        info = NULL;
+      }
+      proto = LDAP_VERSION2;
+      ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto);
+      li->didbind = FALSE;
+      goto retry;
+    }
+  }
+
+  if(err) {
+    failf(data, "LDAP remote: bind failed %s %s", ldap_err2string(rc),
+          info ? info : "");
+    if(info)
+      ldap_memfree(info);
+    return CURLE_LOGIN_DENIED;
+  }
+
+  if(info)
+    ldap_memfree(info);
+  conn->recv[FIRSTSOCKET] = ldap_recv;
+  *done = TRUE;
+
+  return CURLE_OK;
+}
+
+static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  ldapconninfo *li = conn->proto.generic;
+  (void) dead_connection;
+
+  if(li) {
+    if(li->ld) {
+      ldap_unbind_ext(li->ld, NULL, NULL);
+      li->ld = NULL;
+    }
+    conn->proto.generic = NULL;
+    free(li);
+  }
+  return CURLE_OK;
+}
+
+static CURLcode ldap_do(struct connectdata *conn, bool *done)
+{
+  ldapconninfo *li = conn->proto.generic;
+  ldapreqinfo *lr;
+  CURLcode status = CURLE_OK;
+  int rc = 0;
+  LDAPURLDesc *ludp = NULL;
+  int msgid;
+  struct Curl_easy *data = conn->data;
+
+  connkeep(conn, "OpenLDAP do");
+
+  infof(data, "LDAP local: %s\n", data->change.url);
+
+  rc = ldap_url_parse(data->change.url, &ludp);
+  if(rc != LDAP_URL_SUCCESS) {
+    const char *msg = "url parsing problem";
+    status = CURLE_URL_MALFORMAT;
+    if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) {
+      if(rc == LDAP_URL_ERR_MEM)
+        status = CURLE_OUT_OF_MEMORY;
+      msg = url_errs[rc];
+    }
+    failf(conn->data, "LDAP local: %s", msg);
+    return status;
+  }
+
+  rc = ldap_search_ext(li->ld, ludp->lud_dn, ludp->lud_scope,
+                       ludp->lud_filter, ludp->lud_attrs, 0,
+                       NULL, NULL, NULL, 0, &msgid);
+  ldap_free_urldesc(ludp);
+  if(rc != LDAP_SUCCESS) {
+    failf(data, "LDAP local: ldap_search_ext %s", ldap_err2string(rc));
+    return CURLE_LDAP_SEARCH_FAILED;
+  }
+  lr = calloc(1, sizeof(ldapreqinfo));
+  if(!lr)
+    return CURLE_OUT_OF_MEMORY;
+  lr->msgid = msgid;
+  data->req.protop = lr;
+  Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL);
+  *done = TRUE;
+  return CURLE_OK;
+}
+
+static CURLcode ldap_done(struct connectdata *conn, CURLcode res,
+                          bool premature)
+{
+  ldapreqinfo *lr = conn->data->req.protop;
+
+  (void)res;
+  (void)premature;
+
+  if(lr) {
+    /* if there was a search in progress, abandon it */
+    if(lr->msgid) {
+      ldapconninfo *li = conn->proto.generic;
+      ldap_abandon_ext(li->ld, lr->msgid, NULL, NULL);
+      lr->msgid = 0;
+    }
+    conn->data->req.protop = NULL;
+    free(lr);
+  }
+
+  return CURLE_OK;
+}
+
+static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
+                         size_t len, CURLcode *err)
+{
+  ldapconninfo *li = conn->proto.generic;
+  struct Curl_easy *data = conn->data;
+  ldapreqinfo *lr = data->req.protop;
+  int rc, ret;
+  LDAPMessage *msg = NULL;
+  LDAPMessage *ent;
+  BerElement *ber = NULL;
+  struct timeval tv = {0, 1};
+
+  (void)len;
+  (void)buf;
+  (void)sockindex;
+
+  rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_RECEIVED, &tv, &msg);
+  if(rc < 0) {
+    failf(data, "LDAP local: search ldap_result %s", ldap_err2string(rc));
+    *err = CURLE_RECV_ERROR;
+    return -1;
+  }
+
+  *err = CURLE_AGAIN;
+  ret = -1;
+
+  /* timed out */
+  if(!msg)
+    return ret;
+
+  for(ent = ldap_first_message(li->ld, msg); ent;
+    ent = ldap_next_message(li->ld, ent)) {
+    struct berval bv, *bvals, **bvp = &bvals;
+    int binary = 0, msgtype;
+    CURLcode writeerr;
+
+    msgtype = ldap_msgtype(ent);
+    if(msgtype == LDAP_RES_SEARCH_RESULT) {
+      int code;
+      char *info = NULL;
+      rc = ldap_parse_result(li->ld, ent, &code, NULL, &info, NULL, NULL, 0);
+      if(rc) {
+        failf(data, "LDAP local: search ldap_parse_result %s",
+              ldap_err2string(rc));
+        *err = CURLE_LDAP_SEARCH_FAILED;
+      }
+      else if(code && code != LDAP_SIZELIMIT_EXCEEDED) {
+        failf(data, "LDAP remote: search failed %s %s", ldap_err2string(rc),
+              info ? info : "");
+        *err = CURLE_LDAP_SEARCH_FAILED;
+      }
+      else {
+        /* successful */
+        if(code == LDAP_SIZELIMIT_EXCEEDED)
+          infof(data, "There are more than %d entries\n", lr->nument);
+        data->req.size = data->req.bytecount;
+        *err = CURLE_OK;
+        ret = 0;
+      }
+      lr->msgid = 0;
+      ldap_memfree(info);
+      break;
+    }
+    else if(msgtype != LDAP_RES_SEARCH_ENTRY)
+      continue;
+
+    lr->nument++;
+    rc = ldap_get_dn_ber(li->ld, ent, &ber, &bv);
+    if(rc < 0) {
+      /* TODO: verify that this is really how this return code should be
+         handled */
+      *err = CURLE_RECV_ERROR;
+      return -1;
+    }
+    writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
+    if(writeerr) {
+      *err = writeerr;
+      return -1;
+    }
+
+    writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
+                                 bv.bv_len);
+    if(writeerr) {
+      *err = writeerr;
+      return -1;
+    }
+
+    writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+    if(writeerr) {
+      *err = writeerr;
+      return -1;
+    }
+    data->req.bytecount += bv.bv_len + 5;
+
+    for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp);
+      rc == LDAP_SUCCESS;
+      rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp)) {
+      int i;
+
+      if(bv.bv_val == NULL) break;
+
+      if(bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7))
+        binary = 1;
+      else
+        binary = 0;
+
+      for(i = 0; bvals[i].bv_val != NULL; i++) {
+        int binval = 0;
+        writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
+        if(writeerr) {
+          *err = writeerr;
+          return -1;
+        }
+
+       writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
+                                    bv.bv_len);
+       if(writeerr) {
+         *err = writeerr;
+         return -1;
+       }
+
+        writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1);
+       if(writeerr) {
+         *err = writeerr;
+         return -1;
+       }
+        data->req.bytecount += bv.bv_len + 2;
+
+        if(!binary) {
+          /* check for leading or trailing whitespace */
+          if(ISSPACE(bvals[i].bv_val[0]) ||
+              ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1]))
+            binval = 1;
+          else {
+            /* check for unprintable characters */
+            unsigned int j;
+            for(j = 0; j<bvals[i].bv_len; j++)
+              if(!ISPRINT(bvals[i].bv_val[j])) {
+                binval = 1;
+                break;
+              }
+          }
+        }
+        if(binary || binval) {
+          char *val_b64 = NULL;
+          size_t val_b64_sz = 0;
+          /* Binary value, encode to base64. */
+          CURLcode error = Curl_base64_encode(data,
+                                              bvals[i].bv_val,
+                                              bvals[i].bv_len,
+                                              &val_b64,
+                                              &val_b64_sz);
+          if(error) {
+            ber_memfree(bvals);
+            ber_free(ber, 0);
+            ldap_msgfree(msg);
+            *err = error;
+            return -1;
+          }
+          writeerr = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                       (char *)": ", 2);
+          if(writeerr) {
+            *err = writeerr;
+            return -1;
+          }
+
+          data->req.bytecount += 2;
+          if(val_b64_sz > 0) {
+            writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
+                                     val_b64_sz);
+            if(writeerr) {
+              *err = writeerr;
+              return -1;
+            }
+            free(val_b64);
+            data->req.bytecount += val_b64_sz;
+          }
+        }
+        else {
+          writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1);
+          if(writeerr) {
+            *err = writeerr;
+            return -1;
+          }
+
+          writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val,
+                                       bvals[i].bv_len);
+          if(writeerr) {
+            *err = writeerr;
+            return -1;
+          }
+
+          data->req.bytecount += bvals[i].bv_len + 1;
+        }
+        writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+        if(writeerr) {
+          *err = writeerr;
+          return -1;
+        }
+
+        data->req.bytecount++;
+      }
+      ber_memfree(bvals);
+      writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+      if(writeerr) {
+        *err = writeerr;
+        return -1;
+      }
+      data->req.bytecount++;
+    }
+    writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+    if(writeerr) {
+      *err = writeerr;
+      return -1;
+    }
+    data->req.bytecount++;
+    ber_free(ber, 0);
+  }
+  ldap_msgfree(msg);
+  return ret;
+}
+
+#ifdef USE_SSL
+static int
+ldapsb_tls_setup(Sockbuf_IO_Desc *sbiod, void *arg)
+{
+  sbiod->sbiod_pvt = arg;
+  return 0;
+}
+
+static int
+ldapsb_tls_remove(Sockbuf_IO_Desc *sbiod)
+{
+  sbiod->sbiod_pvt = NULL;
+  return 0;
+}
+
+/* We don't need to do anything because libcurl does it already */
+static int
+ldapsb_tls_close(Sockbuf_IO_Desc *sbiod)
+{
+  (void)sbiod;
+  return 0;
+}
+
+static int
+ldapsb_tls_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg)
+{
+  (void)arg;
+  if(opt == LBER_SB_OPT_DATA_READY) {
+    struct connectdata *conn = sbiod->sbiod_pvt;
+    return Curl_ssl_data_pending(conn, FIRSTSOCKET);
+  }
+  return 0;
+}
+
+static ber_slen_t
+ldapsb_tls_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
+{
+  struct connectdata *conn = sbiod->sbiod_pvt;
+  ldapconninfo *li = conn->proto.generic;
+  ber_slen_t ret;
+  CURLcode err = CURLE_RECV_ERROR;
+
+  ret = (li->recv)(conn, FIRSTSOCKET, buf, len, &err);
+  if(ret < 0 && err == CURLE_AGAIN) {
+    SET_SOCKERRNO(EWOULDBLOCK);
+  }
+  return ret;
+}
+
+static ber_slen_t
+ldapsb_tls_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
+{
+  struct connectdata *conn = sbiod->sbiod_pvt;
+  ldapconninfo *li = conn->proto.generic;
+  ber_slen_t ret;
+  CURLcode err = CURLE_SEND_ERROR;
+
+  ret = (li->send)(conn, FIRSTSOCKET, buf, len, &err);
+  if(ret < 0 && err == CURLE_AGAIN) {
+    SET_SOCKERRNO(EWOULDBLOCK);
+  }
+  return ret;
+}
+
+static Sockbuf_IO ldapsb_tls =
+{
+  ldapsb_tls_setup,
+  ldapsb_tls_remove,
+  ldapsb_tls_ctrl,
+  ldapsb_tls_read,
+  ldapsb_tls_write,
+  ldapsb_tls_close
+};
+#endif /* USE_SSL */
+
+#endif /* !CURL_DISABLE_LDAP && USE_OPENLDAP */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/parsedate.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/parsedate.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/parsedate.c	(revision 331)
@@ -0,0 +1,585 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+/*
+  A brief summary of the date string formats this parser groks:
+
+  RFC 2616 3.3.1
+
+  Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
+  Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
+  Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format
+
+  we support dates without week day name:
+
+  06 Nov 1994 08:49:37 GMT
+  06-Nov-94 08:49:37 GMT
+  Nov  6 08:49:37 1994
+
+  without the time zone:
+
+  06 Nov 1994 08:49:37
+  06-Nov-94 08:49:37
+
+  weird order:
+
+  1994 Nov 6 08:49:37  (GNU date fails)
+  GMT 08:49:37 06-Nov-94 Sunday
+  94 6 Nov 08:49:37    (GNU date fails)
+
+  time left out:
+
+  1994 Nov 6
+  06-Nov-94
+  Sun Nov 6 94
+
+  unusual separators:
+
+  1994.Nov.6
+  Sun/Nov/6/94/GMT
+
+  commonly used time zone names:
+
+  Sun, 06 Nov 1994 08:49:37 CET
+  06 Nov 1994 08:49:37 EST
+
+  time zones specified using RFC822 style:
+
+  Sun, 12 Sep 2004 15:05:58 -0700
+  Sat, 11 Sep 2004 21:32:11 +0200
+
+  compact numerical date strings:
+
+  20040912 15:05:58 -0700
+  20040911 +0200
+
+*/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include <curl/curl.h>
+#include "strcase.h"
+#include "warnless.h"
+#include "parsedate.h"
+
+const char * const Curl_wkday[] =
+{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
+static const char * const weekday[] =
+{ "Monday", "Tuesday", "Wednesday", "Thursday",
+  "Friday", "Saturday", "Sunday" };
+const char * const Curl_month[]=
+{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+struct tzinfo {
+  char name[5];
+  int offset; /* +/- in minutes */
+};
+
+/*
+ * parsedate()
+ *
+ * Returns:
+ *
+ * PARSEDATE_OK     - a fine conversion
+ * PARSEDATE_FAIL   - failed to convert
+ * PARSEDATE_LATER  - time overflow at the far end of time_t
+ * PARSEDATE_SOONER - time underflow at the low end of time_t
+ */
+
+static int parsedate(const char *date, time_t *output);
+
+#define PARSEDATE_OK     0
+#define PARSEDATE_FAIL   -1
+#define PARSEDATE_LATER  1
+#define PARSEDATE_SOONER 2
+
+/* Here's a bunch of frequently used time zone names. These were supported
+   by the old getdate parser. */
+#define tDAYZONE -60       /* offset for daylight savings time */
+static const struct tzinfo tz[]= {
+  {"GMT", 0},              /* Greenwich Mean */
+  {"UTC", 0},              /* Universal (Coordinated) */
+  {"WET", 0},              /* Western European */
+  {"BST", 0 tDAYZONE},     /* British Summer */
+  {"WAT", 60},             /* West Africa */
+  {"AST", 240},            /* Atlantic Standard */
+  {"ADT", 240 tDAYZONE},   /* Atlantic Daylight */
+  {"EST", 300},            /* Eastern Standard */
+  {"EDT", 300 tDAYZONE},   /* Eastern Daylight */
+  {"CST", 360},            /* Central Standard */
+  {"CDT", 360 tDAYZONE},   /* Central Daylight */
+  {"MST", 420},            /* Mountain Standard */
+  {"MDT", 420 tDAYZONE},   /* Mountain Daylight */
+  {"PST", 480},            /* Pacific Standard */
+  {"PDT", 480 tDAYZONE},   /* Pacific Daylight */
+  {"YST", 540},            /* Yukon Standard */
+  {"YDT", 540 tDAYZONE},   /* Yukon Daylight */
+  {"HST", 600},            /* Hawaii Standard */
+  {"HDT", 600 tDAYZONE},   /* Hawaii Daylight */
+  {"CAT", 600},            /* Central Alaska */
+  {"AHST", 600},           /* Alaska-Hawaii Standard */
+  {"NT",  660},            /* Nome */
+  {"IDLW", 720},           /* International Date Line West */
+  {"CET", -60},            /* Central European */
+  {"MET", -60},            /* Middle European */
+  {"MEWT", -60},           /* Middle European Winter */
+  {"MEST", -60 tDAYZONE},  /* Middle European Summer */
+  {"CEST", -60 tDAYZONE},  /* Central European Summer */
+  {"MESZ", -60 tDAYZONE},  /* Middle European Summer */
+  {"FWT", -60},            /* French Winter */
+  {"FST", -60 tDAYZONE},   /* French Summer */
+  {"EET", -120},           /* Eastern Europe, USSR Zone 1 */
+  {"WAST", -420},          /* West Australian Standard */
+  {"WADT", -420 tDAYZONE}, /* West Australian Daylight */
+  {"CCT", -480},           /* China Coast, USSR Zone 7 */
+  {"JST", -540},           /* Japan Standard, USSR Zone 8 */
+  {"EAST", -600},          /* Eastern Australian Standard */
+  {"EADT", -600 tDAYZONE}, /* Eastern Australian Daylight */
+  {"GST", -600},           /* Guam Standard, USSR Zone 9 */
+  {"NZT", -720},           /* New Zealand */
+  {"NZST", -720},          /* New Zealand Standard */
+  {"NZDT", -720 tDAYZONE}, /* New Zealand Daylight */
+  {"IDLE", -720},          /* International Date Line East */
+  /* Next up: Military timezone names. RFC822 allowed these, but (as noted in
+     RFC 1123) had their signs wrong. Here we use the correct signs to match
+     actual military usage.
+   */
+  {"A",  1 * 60},         /* Alpha */
+  {"B",  2 * 60},         /* Bravo */
+  {"C",  3 * 60},         /* Charlie */
+  {"D",  4 * 60},         /* Delta */
+  {"E",  5 * 60},         /* Echo */
+  {"F",  6 * 60},         /* Foxtrot */
+  {"G",  7 * 60},         /* Golf */
+  {"H",  8 * 60},         /* Hotel */
+  {"I",  9 * 60},         /* India */
+  /* "J", Juliet is not used as a timezone, to indicate the observer's local
+     time */
+  {"K", 10 * 60},         /* Kilo */
+  {"L", 11 * 60},         /* Lima */
+  {"M", 12 * 60},         /* Mike */
+  {"N",  -1 * 60},         /* November */
+  {"O",  -2 * 60},         /* Oscar */
+  {"P",  -3 * 60},         /* Papa */
+  {"Q",  -4 * 60},         /* Quebec */
+  {"R",  -5 * 60},         /* Romeo */
+  {"S",  -6 * 60},         /* Sierra */
+  {"T",  -7 * 60},         /* Tango */
+  {"U",  -8 * 60},         /* Uniform */
+  {"V",  -9 * 60},         /* Victor */
+  {"W", -10 * 60},         /* Whiskey */
+  {"X", -11 * 60},         /* X-ray */
+  {"Y", -12 * 60},         /* Yankee */
+  {"Z", 0},                /* Zulu, zero meridian, a.k.a. UTC */
+};
+
+/* returns:
+   -1 no day
+   0 monday - 6 sunday
+*/
+
+static int checkday(const char *check, size_t len)
+{
+  int i;
+  const char * const *what;
+  bool found = FALSE;
+  if(len > 3)
+    what = &weekday[0];
+  else
+    what = &Curl_wkday[0];
+  for(i = 0; i<7; i++) {
+    if(strcasecompare(check, what[0])) {
+      found = TRUE;
+      break;
+    }
+    what++;
+  }
+  return found?i:-1;
+}
+
+static int checkmonth(const char *check)
+{
+  int i;
+  const char * const *what;
+  bool found = FALSE;
+
+  what = &Curl_month[0];
+  for(i = 0; i<12; i++) {
+    if(strcasecompare(check, what[0])) {
+      found = TRUE;
+      break;
+    }
+    what++;
+  }
+  return found?i:-1; /* return the offset or -1, no real offset is -1 */
+}
+
+/* return the time zone offset between GMT and the input one, in number
+   of seconds or -1 if the timezone wasn't found/legal */
+
+static int checktz(const char *check)
+{
+  unsigned int i;
+  const struct tzinfo *what;
+  bool found = FALSE;
+
+  what = tz;
+  for(i = 0; i< sizeof(tz)/sizeof(tz[0]); i++) {
+    if(strcasecompare(check, what->name)) {
+      found = TRUE;
+      break;
+    }
+    what++;
+  }
+  return found?what->offset*60:-1;
+}
+
+static void skip(const char **date)
+{
+  /* skip everything that aren't letters or digits */
+  while(**date && !ISALNUM(**date))
+    (*date)++;
+}
+
+enum assume {
+  DATE_MDAY,
+  DATE_YEAR,
+  DATE_TIME
+};
+
+/* this is a clone of 'struct tm' but with all fields we don't need or use
+   cut out */
+struct my_tm {
+  int tm_sec;
+  int tm_min;
+  int tm_hour;
+  int tm_mday;
+  int tm_mon;
+  int tm_year;
+};
+
+/* struct tm to time since epoch in GMT time zone.
+ * This is similar to the standard mktime function but for GMT only, and
+ * doesn't suffer from the various bugs and portability problems that
+ * some systems' implementations have.
+ */
+static time_t my_timegm(struct my_tm *tm)
+{
+  static const int month_days_cumulative [12] =
+    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+  int month, year, leap_days;
+
+  if(tm->tm_year < 70)
+    /* we don't support years before 1970 as they will cause this function
+       to return a negative value */
+    return -1;
+
+  year = tm->tm_year + 1900;
+  month = tm->tm_mon;
+  if(month < 0) {
+    year += (11 - month) / 12;
+    month = 11 - (11 - month) % 12;
+  }
+  else if(month >= 12) {
+    year -= month / 12;
+    month = month % 12;
+  }
+
+  leap_days = year - (tm->tm_mon <= 1);
+  leap_days = ((leap_days / 4) - (leap_days / 100) + (leap_days / 400)
+               - (1969 / 4) + (1969 / 100) - (1969 / 400));
+
+  return ((((time_t) (year - 1970) * 365
+            + leap_days + month_days_cumulative [month] + tm->tm_mday - 1) * 24
+           + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec;
+}
+
+/*
+ * parsedate()
+ *
+ * Returns:
+ *
+ * PARSEDATE_OK     - a fine conversion
+ * PARSEDATE_FAIL   - failed to convert
+ * PARSEDATE_LATER  - time overflow at the far end of time_t
+ * PARSEDATE_SOONER - time underflow at the low end of time_t
+ */
+
+static int parsedate(const char *date, time_t *output)
+{
+  time_t t = 0;
+  int wdaynum = -1;  /* day of the week number, 0-6 (mon-sun) */
+  int monnum = -1;   /* month of the year number, 0-11 */
+  int mdaynum = -1; /* day of month, 1 - 31 */
+  int hournum = -1;
+  int minnum = -1;
+  int secnum = -1;
+  int yearnum = -1;
+  int tzoff = -1;
+  struct my_tm tm;
+  enum assume dignext = DATE_MDAY;
+  const char *indate = date; /* save the original pointer */
+  int part = 0; /* max 6 parts */
+
+  while(*date && (part < 6)) {
+    bool found = FALSE;
+
+    skip(&date);
+
+    if(ISALPHA(*date)) {
+      /* a name coming up */
+      char buf[32]="";
+      size_t len;
+      if(sscanf(date, "%31[ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                          "abcdefghijklmnopqrstuvwxyz]", buf))
+        len = strlen(buf);
+      else
+        len = 0;
+
+      if(wdaynum == -1) {
+        wdaynum = checkday(buf, len);
+        if(wdaynum != -1)
+          found = TRUE;
+      }
+      if(!found && (monnum == -1)) {
+        monnum = checkmonth(buf);
+        if(monnum != -1)
+          found = TRUE;
+      }
+
+      if(!found && (tzoff == -1)) {
+        /* this just must be a time zone string */
+        tzoff = checktz(buf);
+        if(tzoff != -1)
+          found = TRUE;
+      }
+
+      if(!found)
+        return PARSEDATE_FAIL; /* bad string */
+
+      date += len;
+    }
+    else if(ISDIGIT(*date)) {
+      /* a digit */
+      int val;
+      char *end;
+      int len = 0;
+      if((secnum == -1) &&
+         (3 == sscanf(date, "%02d:%02d:%02d%n",
+                      &hournum, &minnum, &secnum, &len))) {
+        /* time stamp! */
+        date += len;
+      }
+      else if((secnum == -1) &&
+              (2 == sscanf(date, "%02d:%02d%n", &hournum, &minnum, &len))) {
+        /* time stamp without seconds */
+        date += len;
+        secnum = 0;
+      }
+      else {
+        long lval;
+        int error;
+        int old_errno;
+
+        old_errno = errno;
+        errno = 0;
+        lval = strtol(date, &end, 10);
+        error = errno;
+        if(errno != old_errno)
+          errno = old_errno;
+
+        if(error)
+          return PARSEDATE_FAIL;
+
+#if LONG_MAX != INT_MAX
+        if((lval > (long)INT_MAX) || (lval < (long)INT_MIN))
+          return PARSEDATE_FAIL;
+#endif
+
+        val = curlx_sltosi(lval);
+
+        if((tzoff == -1) &&
+           ((end - date) == 4) &&
+           (val <= 1400) &&
+           (indate< date) &&
+           ((date[-1] == '+' || date[-1] == '-'))) {
+          /* four digits and a value less than or equal to 1400 (to take into
+             account all sorts of funny time zone diffs) and it is preceded
+             with a plus or minus. This is a time zone indication.  1400 is
+             picked since +1300 is frequently used and +1400 is mentioned as
+             an edge number in the document "ISO C 200X Proposal: Timezone
+             Functions" at http://david.tribble.com/text/c0xtimezone.html If
+             anyone has a more authoritative source for the exact maximum time
+             zone offsets, please speak up! */
+          found = TRUE;
+          tzoff = (val/100 * 60 + val%100)*60;
+
+          /* the + and - prefix indicates the local time compared to GMT,
+             this we need ther reversed math to get what we want */
+          tzoff = date[-1]=='+'?-tzoff:tzoff;
+        }
+
+        if(((end - date) == 8) &&
+           (yearnum == -1) &&
+           (monnum == -1) &&
+           (mdaynum == -1)) {
+          /* 8 digits, no year, month or day yet. This is YYYYMMDD */
+          found = TRUE;
+          yearnum = val/10000;
+          monnum = (val%10000)/100-1; /* month is 0 - 11 */
+          mdaynum = val%100;
+        }
+
+        if(!found && (dignext == DATE_MDAY) && (mdaynum == -1)) {
+          if((val > 0) && (val<32)) {
+            mdaynum = val;
+            found = TRUE;
+          }
+          dignext = DATE_YEAR;
+        }
+
+        if(!found && (dignext == DATE_YEAR) && (yearnum == -1)) {
+          yearnum = val;
+          found = TRUE;
+          if(yearnum < 1900) {
+            if(yearnum > 70)
+              yearnum += 1900;
+            else
+              yearnum += 2000;
+          }
+          if(mdaynum == -1)
+            dignext = DATE_MDAY;
+        }
+
+        if(!found)
+          return PARSEDATE_FAIL;
+
+        date = end;
+      }
+    }
+
+    part++;
+  }
+
+  if(-1 == secnum)
+    secnum = minnum = hournum = 0; /* no time, make it zero */
+
+  if((-1 == mdaynum) ||
+     (-1 == monnum) ||
+     (-1 == yearnum))
+    /* lacks vital info, fail */
+    return PARSEDATE_FAIL;
+
+#if SIZEOF_TIME_T < 5
+  /* 32 bit time_t can only hold dates to the beginning of 2038 */
+  if(yearnum > 2037) {
+    *output = 0x7fffffff;
+    return PARSEDATE_LATER;
+  }
+#endif
+
+  if(yearnum < 1970) {
+    *output = 0;
+    return PARSEDATE_SOONER;
+  }
+
+  if((mdaynum > 31) || (monnum > 11) ||
+     (hournum > 23) || (minnum > 59) || (secnum > 60))
+    return PARSEDATE_FAIL; /* clearly an illegal date */
+
+  tm.tm_sec = secnum;
+  tm.tm_min = minnum;
+  tm.tm_hour = hournum;
+  tm.tm_mday = mdaynum;
+  tm.tm_mon = monnum;
+  tm.tm_year = yearnum - 1900;
+
+  /* my_timegm() returns a time_t. time_t is often 32 bits, even on many
+     architectures that feature 64 bit 'long'.
+
+     Some systems have 64 bit time_t and deal with years beyond 2038. However,
+     even on some of the systems with 64 bit time_t mktime() returns -1 for
+     dates beyond 03:14:07 UTC, January 19, 2038. (Such as AIX 5100-06)
+  */
+  t = my_timegm(&tm);
+
+  /* time zone adjust (cast t to int to compare to negative one) */
+  if(-1 != (int)t) {
+
+    /* Add the time zone diff between local time zone and GMT. */
+    long delta = (long)(tzoff!=-1?tzoff:0);
+
+    if((delta>0) && (t > LONG_MAX - delta)) {
+      *output = 0x7fffffff;
+      return PARSEDATE_LATER; /* time_t overflow */
+    }
+
+    t += delta;
+  }
+
+  *output = t;
+
+  return PARSEDATE_OK;
+}
+
+time_t curl_getdate(const char *p, const time_t *now)
+{
+  time_t parsed = -1;
+  int rc = parsedate(p, &parsed);
+  (void)now; /* legacy argument from the past that we ignore */
+
+  switch(rc) {
+  case PARSEDATE_OK:
+  case PARSEDATE_LATER:
+  case PARSEDATE_SOONER:
+    return parsed;
+  }
+  /* everything else is fail */
+  return -1;
+}
+
+/*
+ * Curl_gmtime() is a gmtime() replacement for portability. Do not use the
+ * gmtime_r() or gmtime() functions anywhere else but here.
+ *
+ */
+
+CURLcode Curl_gmtime(time_t intime, struct tm *store)
+{
+  const struct tm *tm;
+#ifdef HAVE_GMTIME_R
+  /* thread-safe version */
+  tm = (struct tm *)gmtime_r(&intime, store);
+#else
+  tm = gmtime(&intime);
+  if(tm)
+    *store = *tm; /* copy the pointed struct to the local copy */
+#endif
+
+  if(!tm)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+  return CURLE_OK;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/parsedate.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/parsedate.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/parsedate.h	(revision 331)
@@ -0,0 +1,31 @@
+#ifndef HEADER_CURL_PARSEDATE_H
+#define HEADER_CURL_PARSEDATE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+extern const char * const Curl_wkday[7];
+extern const char * const Curl_month[12];
+
+CURLcode Curl_gmtime(time_t intime, struct tm *store);
+
+#endif /* HEADER_CURL_PARSEDATE_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/pingpong.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/pingpong.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/pingpong.c	(revision 331)
@@ -0,0 +1,520 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ *   'pingpong' is for generic back-and-forth support functions used by FTP,
+ *   IMAP, POP3, SMTP and whatever more that likes them.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "urldata.h"
+#include "sendf.h"
+#include "select.h"
+#include "progress.h"
+#include "speedcheck.h"
+#include "pingpong.h"
+#include "multiif.h"
+#include "non-ascii.h"
+#include "vtls/vtls.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifdef USE_PINGPONG
+
+/* Returns timeout in ms. 0 or negative number means the timeout has already
+   triggered */
+time_t Curl_pp_state_timeout(struct pingpong *pp)
+{
+  struct connectdata *conn = pp->conn;
+  struct Curl_easy *data = conn->data;
+  time_t timeout_ms; /* in milliseconds */
+  time_t timeout2_ms; /* in milliseconds */
+  long response_time = (data->set.server_response_timeout)?
+    data->set.server_response_timeout: pp->response_time;
+
+  /* if CURLOPT_SERVER_RESPONSE_TIMEOUT is set, use that to determine
+     remaining time, or use pp->response because SERVER_RESPONSE_TIMEOUT is
+     supposed to govern the response for any given server response, not for
+     the time from connect to the given server response. */
+
+  /* Without a requested timeout, we only wait 'response_time' seconds for the
+     full response to arrive before we bail out */
+  timeout_ms = response_time -
+    Curl_timediff(Curl_now(), pp->response); /* spent time */
+
+  if(data->set.timeout) {
+    /* if timeout is requested, find out how much remaining time we have */
+    timeout2_ms = data->set.timeout - /* timeout time */
+      Curl_timediff(Curl_now(), conn->now); /* spent time */
+
+    /* pick the lowest number */
+    timeout_ms = CURLMIN(timeout_ms, timeout2_ms);
+  }
+
+  return timeout_ms;
+}
+
+/*
+ * Curl_pp_statemach()
+ */
+CURLcode Curl_pp_statemach(struct pingpong *pp, bool block)
+{
+  struct connectdata *conn = pp->conn;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  int rc;
+  time_t interval_ms;
+  time_t timeout_ms = Curl_pp_state_timeout(pp);
+  struct Curl_easy *data = conn->data;
+  CURLcode result = CURLE_OK;
+
+  if(timeout_ms <= 0) {
+    failf(data, "server response timeout");
+    return CURLE_OPERATION_TIMEDOUT; /* already too little time */
+  }
+
+  if(block) {
+    interval_ms = 1000;  /* use 1 second timeout intervals */
+    if(timeout_ms < interval_ms)
+      interval_ms = timeout_ms;
+  }
+  else
+    interval_ms = 0; /* immediate */
+
+  if(Curl_ssl_data_pending(conn, FIRSTSOCKET))
+    rc = 1;
+  else if(Curl_pp_moredata(pp))
+    /* We are receiving and there is data in the cache so just read it */
+    rc = 1;
+  else if(!pp->sendleft && Curl_ssl_data_pending(conn, FIRSTSOCKET))
+    /* We are receiving and there is data ready in the SSL library */
+    rc = 1;
+  else
+    rc = Curl_socket_check(pp->sendleft?CURL_SOCKET_BAD:sock, /* reading */
+                           CURL_SOCKET_BAD,
+                           pp->sendleft?sock:CURL_SOCKET_BAD, /* writing */
+                           interval_ms);
+
+  if(block) {
+    /* if we didn't wait, we don't have to spend time on this now */
+    if(Curl_pgrsUpdate(conn))
+      result = CURLE_ABORTED_BY_CALLBACK;
+    else
+      result = Curl_speedcheck(data, Curl_now());
+
+    if(result)
+      return result;
+  }
+
+  if(rc == -1) {
+    failf(data, "select/poll error");
+    result = CURLE_OUT_OF_MEMORY;
+  }
+  else if(rc)
+    result = pp->statemach_act(conn);
+
+  return result;
+}
+
+/* initialize stuff to prepare for reading a fresh new response */
+void Curl_pp_init(struct pingpong *pp)
+{
+  struct connectdata *conn = pp->conn;
+  pp->nread_resp = 0;
+  pp->linestart_resp = conn->data->state.buffer;
+  pp->pending_resp = TRUE;
+  pp->response = Curl_now(); /* start response time-out now! */
+}
+
+
+
+/***********************************************************************
+ *
+ * Curl_pp_vsendf()
+ *
+ * Send the formatted string as a command to a pingpong server. Note that
+ * the string should not have any CRLF appended, as this function will
+ * append the necessary things itself.
+ *
+ * made to never block
+ */
+CURLcode Curl_pp_vsendf(struct pingpong *pp,
+                        const char *fmt,
+                        va_list args)
+{
+  ssize_t bytes_written;
+  size_t write_len;
+  char *fmt_crlf;
+  char *s;
+  CURLcode result;
+  struct connectdata *conn = pp->conn;
+  struct Curl_easy *data;
+
+#ifdef HAVE_GSSAPI
+  enum protection_level data_sec;
+#endif
+
+  DEBUGASSERT(pp->sendleft == 0);
+  DEBUGASSERT(pp->sendsize == 0);
+  DEBUGASSERT(pp->sendthis == NULL);
+
+  if(!conn)
+    /* can't send without a connection! */
+    return CURLE_SEND_ERROR;
+
+  data = conn->data;
+
+  fmt_crlf = aprintf("%s\r\n", fmt); /* append a trailing CRLF */
+  if(!fmt_crlf)
+    return CURLE_OUT_OF_MEMORY;
+
+  s = vaprintf(fmt_crlf, args); /* trailing CRLF appended */
+  free(fmt_crlf);
+  if(!s)
+    return CURLE_OUT_OF_MEMORY;
+
+  bytes_written = 0;
+  write_len = strlen(s);
+
+  Curl_pp_init(pp);
+
+  result = Curl_convert_to_network(data, s, write_len);
+  /* Curl_convert_to_network calls failf if unsuccessful */
+  if(result) {
+    free(s);
+    return result;
+  }
+
+#ifdef HAVE_GSSAPI
+  conn->data_prot = PROT_CMD;
+#endif
+  result = Curl_write(conn, conn->sock[FIRSTSOCKET], s, write_len,
+                     &bytes_written);
+#ifdef HAVE_GSSAPI
+  data_sec = conn->data_prot;
+  DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST);
+  conn->data_prot = data_sec;
+#endif
+
+  if(result) {
+    free(s);
+    return result;
+  }
+
+  if(conn->data->set.verbose)
+    Curl_debug(conn->data, CURLINFO_HEADER_OUT,
+               s, (size_t)bytes_written, conn);
+
+  if(bytes_written != (ssize_t)write_len) {
+    /* the whole chunk was not sent, keep it around and adjust sizes */
+    pp->sendthis = s;
+    pp->sendsize = write_len;
+    pp->sendleft = write_len - bytes_written;
+  }
+  else {
+    free(s);
+    pp->sendthis = NULL;
+    pp->sendleft = pp->sendsize = 0;
+    pp->response = Curl_now();
+  }
+
+  return CURLE_OK;
+}
+
+
+/***********************************************************************
+ *
+ * Curl_pp_sendf()
+ *
+ * Send the formatted string as a command to a pingpong server. Note that
+ * the string should not have any CRLF appended, as this function will
+ * append the necessary things itself.
+ *
+ * made to never block
+ */
+CURLcode Curl_pp_sendf(struct pingpong *pp,
+                       const char *fmt, ...)
+{
+  CURLcode result;
+  va_list ap;
+  va_start(ap, fmt);
+
+  result = Curl_pp_vsendf(pp, fmt, ap);
+
+  va_end(ap);
+
+  return result;
+}
+
+/*
+ * Curl_pp_readresp()
+ *
+ * Reads a piece of a server response.
+ */
+CURLcode Curl_pp_readresp(curl_socket_t sockfd,
+                          struct pingpong *pp,
+                          int *code, /* return the server code if done */
+                          size_t *size) /* size of the response */
+{
+  ssize_t perline; /* count bytes per line */
+  bool keepon = TRUE;
+  ssize_t gotbytes;
+  char *ptr;
+  struct connectdata *conn = pp->conn;
+  struct Curl_easy *data = conn->data;
+  char * const buf = data->state.buffer;
+  CURLcode result = CURLE_OK;
+
+  *code = 0; /* 0 for errors or not done */
+  *size = 0;
+
+  ptr = buf + pp->nread_resp;
+
+  /* number of bytes in the current line, so far */
+  perline = (ssize_t)(ptr-pp->linestart_resp);
+
+  while((pp->nread_resp < (size_t)data->set.buffer_size) &&
+        (keepon && !result)) {
+
+    if(pp->cache) {
+      /* we had data in the "cache", copy that instead of doing an actual
+       * read
+       *
+       * pp->cache_size is cast to ssize_t here.  This should be safe, because
+       * it would have been populated with something of size int to begin
+       * with, even though its datatype may be larger than an int.
+       */
+      DEBUGASSERT((ptr + pp->cache_size) <= (buf + data->set.buffer_size + 1));
+      memcpy(ptr, pp->cache, pp->cache_size);
+      gotbytes = (ssize_t)pp->cache_size;
+      free(pp->cache);    /* free the cache */
+      pp->cache = NULL;   /* clear the pointer */
+      pp->cache_size = 0; /* zero the size just in case */
+    }
+    else {
+#ifdef HAVE_GSSAPI
+      enum protection_level prot = conn->data_prot;
+      conn->data_prot = PROT_CLEAR;
+#endif
+      DEBUGASSERT((ptr + data->set.buffer_size - pp->nread_resp) <=
+                  (buf + data->set.buffer_size + 1));
+      result = Curl_read(conn, sockfd, ptr,
+                         data->set.buffer_size - pp->nread_resp,
+                         &gotbytes);
+#ifdef HAVE_GSSAPI
+      DEBUGASSERT(prot  > PROT_NONE && prot < PROT_LAST);
+      conn->data_prot = prot;
+#endif
+      if(result == CURLE_AGAIN)
+        return CURLE_OK; /* return */
+
+      if(!result && (gotbytes > 0))
+        /* convert from the network encoding */
+        result = Curl_convert_from_network(data, ptr, gotbytes);
+      /* Curl_convert_from_network calls failf if unsuccessful */
+
+      if(result)
+        /* Set outer result variable to this error. */
+        keepon = FALSE;
+    }
+
+    if(!keepon)
+      ;
+    else if(gotbytes <= 0) {
+      keepon = FALSE;
+      result = CURLE_RECV_ERROR;
+      failf(data, "response reading failed");
+    }
+    else {
+      /* we got a whole chunk of data, which can be anything from one
+       * byte to a set of lines and possible just a piece of the last
+       * line */
+      ssize_t i;
+      ssize_t clipamount = 0;
+      bool restart = FALSE;
+
+      data->req.headerbytecount += (long)gotbytes;
+
+      pp->nread_resp += gotbytes;
+      for(i = 0; i < gotbytes; ptr++, i++) {
+        perline++;
+        if(*ptr == '\n') {
+          /* a newline is CRLF in pp-talk, so the CR is ignored as
+             the line isn't really terminated until the LF comes */
+
+          /* output debug output if that is requested */
+#ifdef HAVE_GSSAPI
+          if(!conn->sec_complete)
+#endif
+            if(data->set.verbose)
+              Curl_debug(data, CURLINFO_HEADER_IN,
+                         pp->linestart_resp, (size_t)perline, conn);
+
+          /*
+           * We pass all response-lines to the callback function registered
+           * for "headers". The response lines can be seen as a kind of
+           * headers.
+           */
+          result = Curl_client_write(conn, CLIENTWRITE_HEADER,
+                                     pp->linestart_resp, perline);
+          if(result)
+            return result;
+
+          if(pp->endofresp(conn, pp->linestart_resp, perline, code)) {
+            /* This is the end of the last line, copy the last line to the
+               start of the buffer and zero terminate, for old times sake */
+            size_t n = ptr - pp->linestart_resp;
+            memmove(buf, pp->linestart_resp, n);
+            buf[n] = 0; /* zero terminate */
+            keepon = FALSE;
+            pp->linestart_resp = ptr + 1; /* advance pointer */
+            i++; /* skip this before getting out */
+
+            *size = pp->nread_resp; /* size of the response */
+            pp->nread_resp = 0; /* restart */
+            break;
+          }
+          perline = 0; /* line starts over here */
+          pp->linestart_resp = ptr + 1;
+        }
+      }
+
+      if(!keepon && (i != gotbytes)) {
+        /* We found the end of the response lines, but we didn't parse the
+           full chunk of data we have read from the server. We therefore need
+           to store the rest of the data to be checked on the next invoke as
+           it may actually contain another end of response already! */
+        clipamount = gotbytes - i;
+        restart = TRUE;
+        DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing "
+                     "server response left\n",
+                     (int)clipamount));
+      }
+      else if(keepon) {
+
+        if((perline == gotbytes) && (gotbytes > data->set.buffer_size/2)) {
+          /* We got an excessive line without newlines and we need to deal
+             with it. We keep the first bytes of the line then we throw
+             away the rest. */
+          infof(data, "Excessive server response line length received, "
+                "%zd bytes. Stripping\n", gotbytes);
+          restart = TRUE;
+
+          /* we keep 40 bytes since all our pingpong protocols are only
+             interested in the first piece */
+          clipamount = 40;
+        }
+        else if(pp->nread_resp > (size_t)data->set.buffer_size/2) {
+          /* We got a large chunk of data and there's potentially still
+             trailing data to take care of, so we put any such part in the
+             "cache", clear the buffer to make space and restart. */
+          clipamount = perline;
+          restart = TRUE;
+        }
+      }
+      else if(i == gotbytes)
+        restart = TRUE;
+
+      if(clipamount) {
+        pp->cache_size = clipamount;
+        pp->cache = malloc(pp->cache_size);
+        if(pp->cache)
+          memcpy(pp->cache, pp->linestart_resp, pp->cache_size);
+        else
+          return CURLE_OUT_OF_MEMORY;
+      }
+      if(restart) {
+        /* now reset a few variables to start over nicely from the start of
+           the big buffer */
+        pp->nread_resp = 0; /* start over from scratch in the buffer */
+        ptr = pp->linestart_resp = buf;
+        perline = 0;
+      }
+
+    } /* there was data */
+
+  } /* while there's buffer left and loop is requested */
+
+  pp->pending_resp = FALSE;
+
+  return result;
+}
+
+int Curl_pp_getsock(struct pingpong *pp,
+                    curl_socket_t *socks,
+                    int numsocks)
+{
+  struct connectdata *conn = pp->conn;
+
+  if(!numsocks)
+    return GETSOCK_BLANK;
+
+  socks[0] = conn->sock[FIRSTSOCKET];
+
+  if(pp->sendleft) {
+    /* write mode */
+    return GETSOCK_WRITESOCK(0);
+  }
+
+  /* read mode */
+  return GETSOCK_READSOCK(0);
+}
+
+CURLcode Curl_pp_flushsend(struct pingpong *pp)
+{
+  /* we have a piece of a command still left to send */
+  struct connectdata *conn = pp->conn;
+  ssize_t written;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  CURLcode result = Curl_write(conn, sock, pp->sendthis + pp->sendsize -
+                               pp->sendleft, pp->sendleft, &written);
+  if(result)
+    return result;
+
+  if(written != (ssize_t)pp->sendleft) {
+    /* only a fraction was sent */
+    pp->sendleft -= written;
+  }
+  else {
+    free(pp->sendthis);
+    pp->sendthis = NULL;
+    pp->sendleft = pp->sendsize = 0;
+    pp->response = Curl_now();
+  }
+  return CURLE_OK;
+}
+
+CURLcode Curl_pp_disconnect(struct pingpong *pp)
+{
+  free(pp->cache);
+  pp->cache = NULL;
+  return CURLE_OK;
+}
+
+bool Curl_pp_moredata(struct pingpong *pp)
+{
+  return (!pp->sendleft && pp->cache && pp->nread_resp < pp->cache_size) ?
+         TRUE : FALSE;
+}
+
+#endif
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/pingpong.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/pingpong.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/pingpong.h	(revision 331)
@@ -0,0 +1,150 @@
+#ifndef HEADER_CURL_PINGPONG_H
+#define HEADER_CURL_PINGPONG_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_FTP) || \
+  !defined(CURL_DISABLE_POP3) || !defined(CURL_DISABLE_SMTP)
+#define USE_PINGPONG
+#endif
+
+/* forward-declaration, this is defined in urldata.h */
+struct connectdata;
+
+typedef enum {
+  FTPTRANSFER_BODY, /* yes do transfer a body */
+  FTPTRANSFER_INFO, /* do still go through to get info/headers */
+  FTPTRANSFER_NONE, /* don't get anything and don't get info */
+  FTPTRANSFER_LAST  /* end of list marker, never used */
+} curl_pp_transfer;
+
+/*
+ * 'pingpong' is the generic struct used for protocols doing server<->client
+ * conversations in a back-and-forth style such as FTP, IMAP, POP3, SMTP etc.
+ *
+ * It holds response cache and non-blocking sending data.
+ */
+struct pingpong {
+  char *cache;     /* data cache between getresponse()-calls */
+  size_t cache_size;  /* size of cache in bytes */
+  size_t nread_resp;  /* number of bytes currently read of a server response */
+  char *linestart_resp; /* line start pointer for the server response
+                           reader function */
+  bool pending_resp;  /* set TRUE when a server response is pending or in
+                         progress, and is cleared once the last response is
+                         read */
+  char *sendthis; /* allocated pointer to a buffer that is to be sent to the
+                     server */
+  size_t sendleft; /* number of bytes left to send from the sendthis buffer */
+  size_t sendsize; /* total size of the sendthis buffer */
+  struct curltime response; /* set to Curl_now() when a command has been sent
+                               off, used to time-out response reading */
+  long response_time; /* When no timeout is given, this is the amount of
+                         milliseconds we await for a server response. */
+
+  struct connectdata *conn; /* points to the connectdata struct that this
+                               belongs to */
+
+  /* Function pointers the protocols MUST implement and provide for the
+     pingpong layer to function */
+
+  CURLcode (*statemach_act)(struct connectdata *conn);
+
+  bool (*endofresp)(struct connectdata *conn, char *ptr, size_t len,
+                    int *code);
+};
+
+/*
+ * Curl_pp_statemach()
+ *
+ * called repeatedly until done. Set 'wait' to make it wait a while on the
+ * socket if there's no traffic.
+ */
+CURLcode Curl_pp_statemach(struct pingpong *pp, bool block);
+
+/* initialize stuff to prepare for reading a fresh new response */
+void Curl_pp_init(struct pingpong *pp);
+
+/* Returns timeout in ms. 0 or negative number means the timeout has already
+   triggered */
+time_t Curl_pp_state_timeout(struct pingpong *pp);
+
+
+/***********************************************************************
+ *
+ * Curl_pp_sendf()
+ *
+ * Send the formatted string as a command to a pingpong server. Note that
+ * the string should not have any CRLF appended, as this function will
+ * append the necessary things itself.
+ *
+ * made to never block
+ */
+CURLcode Curl_pp_sendf(struct pingpong *pp,
+                       const char *fmt, ...);
+
+/***********************************************************************
+ *
+ * Curl_pp_vsendf()
+ *
+ * Send the formatted string as a command to a pingpong server. Note that
+ * the string should not have any CRLF appended, as this function will
+ * append the necessary things itself.
+ *
+ * made to never block
+ */
+CURLcode Curl_pp_vsendf(struct pingpong *pp,
+                        const char *fmt,
+                        va_list args);
+
+/*
+ * Curl_pp_readresp()
+ *
+ * Reads a piece of a server response.
+ */
+CURLcode Curl_pp_readresp(curl_socket_t sockfd,
+                          struct pingpong *pp,
+                          int *code, /* return the server code if done */
+                          size_t *size); /* size of the response */
+
+
+CURLcode Curl_pp_flushsend(struct pingpong *pp);
+
+/* call this when a pingpong connection is disconnected */
+CURLcode Curl_pp_disconnect(struct pingpong *pp);
+
+int Curl_pp_getsock(struct pingpong *pp, curl_socket_t *socks,
+                    int numsocks);
+
+
+/***********************************************************************
+ *
+ * Curl_pp_moredata()
+ *
+ * Returns whether there are still more data in the cache and so a call
+ * to Curl_pp_readresp() will not block.
+ */
+bool Curl_pp_moredata(struct pingpong *pp);
+
+#endif /* HEADER_CURL_PINGPONG_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/pipeline.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/pipeline.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/pipeline.c	(revision 331)
@@ -0,0 +1,403 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2013, Linus Nielsen Feltzing, <linus@haxx.se>
+ * Copyright (C) 2013 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "url.h"
+#include "progress.h"
+#include "multiif.h"
+#include "pipeline.h"
+#include "sendf.h"
+#include "strcase.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+struct site_blacklist_entry {
+  struct curl_llist_element list;
+  unsigned short port;
+  char hostname[1];
+};
+
+static void site_blacklist_llist_dtor(void *user, void *element)
+{
+  struct site_blacklist_entry *entry = element;
+  (void)user;
+  free(entry);
+}
+
+static void server_blacklist_llist_dtor(void *user, void *element)
+{
+  (void)user;
+  free(element);
+}
+
+bool Curl_pipeline_penalized(struct Curl_easy *data,
+                             struct connectdata *conn)
+{
+  if(data) {
+    bool penalized = FALSE;
+    curl_off_t penalty_size =
+      Curl_multi_content_length_penalty_size(data->multi);
+    curl_off_t chunk_penalty_size =
+      Curl_multi_chunk_length_penalty_size(data->multi);
+    curl_off_t recv_size = -2; /* Make it easy to spot in the log */
+
+    /* Find the head of the recv pipe, if any */
+    if(conn->recv_pipe.head) {
+      struct Curl_easy *recv_handle = conn->recv_pipe.head->ptr;
+
+      recv_size = recv_handle->req.size;
+
+      if(penalty_size > 0 && recv_size > penalty_size)
+        penalized = TRUE;
+    }
+
+    if(chunk_penalty_size > 0 &&
+       (curl_off_t)conn->chunk.datasize > chunk_penalty_size)
+      penalized = TRUE;
+
+    infof(data, "Conn: %ld (%p) Receive pipe weight: (%"
+          CURL_FORMAT_CURL_OFF_T "/%zu), penalized: %s\n",
+          conn->connection_id, (void *)conn, recv_size,
+          conn->chunk.datasize, penalized?"TRUE":"FALSE");
+    return penalized;
+  }
+  return FALSE;
+}
+
+static CURLcode addHandleToPipeline(struct Curl_easy *data,
+                                    struct curl_llist *pipeline)
+{
+  Curl_llist_insert_next(pipeline, pipeline->tail, data,
+                         &data->pipeline_queue);
+  return CURLE_OK;
+}
+
+
+CURLcode Curl_add_handle_to_pipeline(struct Curl_easy *handle,
+                                     struct connectdata *conn)
+{
+  struct curl_llist_element *sendhead = conn->send_pipe.head;
+  struct curl_llist *pipeline;
+  CURLcode result;
+
+  pipeline = &conn->send_pipe;
+
+  result = addHandleToPipeline(handle, pipeline);
+
+  if(pipeline == &conn->send_pipe && sendhead != conn->send_pipe.head) {
+    /* this is a new one as head, expire it */
+    Curl_pipeline_leave_write(conn); /* not in use yet */
+    Curl_expire(conn->send_pipe.head->ptr, 0, EXPIRE_RUN_NOW);
+  }
+
+#if 0 /* enable for pipeline debugging */
+  print_pipeline(conn);
+#endif
+
+  return result;
+}
+
+/* Move this transfer from the sending list to the receiving list.
+
+   Pay special attention to the new sending list "leader" as it needs to get
+   checked to update what sockets it acts on.
+
+*/
+void Curl_move_handle_from_send_to_recv_pipe(struct Curl_easy *handle,
+                                             struct connectdata *conn)
+{
+  struct curl_llist_element *curr;
+
+  curr = conn->send_pipe.head;
+  while(curr) {
+    if(curr->ptr == handle) {
+      Curl_llist_move(&conn->send_pipe, curr,
+                      &conn->recv_pipe, conn->recv_pipe.tail);
+
+      if(conn->send_pipe.head) {
+        /* Since there's a new easy handle at the start of the send pipeline,
+           set its timeout value to 1ms to make it trigger instantly */
+        Curl_pipeline_leave_write(conn); /* not used now */
+#ifdef DEBUGBUILD
+        infof(conn->data, "%p is at send pipe head B!\n",
+              (void *)conn->send_pipe.head->ptr);
+#endif
+        Curl_expire(conn->send_pipe.head->ptr, 0, EXPIRE_RUN_NOW);
+      }
+
+      /* The receiver's list is not really interesting here since either this
+         handle is now first in the list and we'll deal with it soon, or
+         another handle is already first and thus is already taken care of */
+
+      break; /* we're done! */
+    }
+    curr = curr->next;
+  }
+}
+
+bool Curl_pipeline_site_blacklisted(struct Curl_easy *handle,
+                                    struct connectdata *conn)
+{
+  if(handle->multi) {
+    struct curl_llist *blacklist =
+      Curl_multi_pipelining_site_bl(handle->multi);
+
+    if(blacklist) {
+      struct curl_llist_element *curr;
+
+      curr = blacklist->head;
+      while(curr) {
+        struct site_blacklist_entry *site;
+
+        site = curr->ptr;
+        if(strcasecompare(site->hostname, conn->host.name) &&
+           site->port == conn->remote_port) {
+          infof(handle, "Site %s:%d is pipeline blacklisted\n",
+                conn->host.name, conn->remote_port);
+          return TRUE;
+        }
+        curr = curr->next;
+      }
+    }
+  }
+  return FALSE;
+}
+
+CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
+                                           struct curl_llist *list)
+{
+  /* Free the old list */
+  if(list->size)
+    Curl_llist_destroy(list, NULL);
+
+  if(sites) {
+    Curl_llist_init(list, (curl_llist_dtor) site_blacklist_llist_dtor);
+
+    /* Parse the URLs and populate the list */
+    while(*sites) {
+      char *port;
+      struct site_blacklist_entry *entry;
+
+      entry = malloc(sizeof(struct site_blacklist_entry) + strlen(*sites));
+      if(!entry) {
+        Curl_llist_destroy(list, NULL);
+        return CURLM_OUT_OF_MEMORY;
+      }
+      strcpy(entry->hostname, *sites);
+
+      port = strchr(entry->hostname, ':');
+      if(port) {
+        *port = '\0';
+        port++;
+        entry->port = (unsigned short)strtol(port, NULL, 10);
+      }
+      else {
+        /* Default port number for HTTP */
+        entry->port = 80;
+      }
+
+      Curl_llist_insert_next(list, list->tail, entry, &entry->list);
+      sites++;
+    }
+  }
+
+  return CURLM_OK;
+}
+
+struct blacklist_node {
+  struct curl_llist_element list;
+  char server_name[1];
+};
+
+bool Curl_pipeline_server_blacklisted(struct Curl_easy *handle,
+                                      char *server_name)
+{
+  if(handle->multi && server_name) {
+    struct curl_llist *list =
+      Curl_multi_pipelining_server_bl(handle->multi);
+
+    struct curl_llist_element *e = list->head;
+    while(e) {
+      struct blacklist_node *bl = (struct blacklist_node *)e;
+      if(strncasecompare(bl->server_name, server_name,
+                         strlen(bl->server_name))) {
+        infof(handle, "Server %s is blacklisted\n", server_name);
+        return TRUE;
+      }
+      e = e->next;
+    }
+
+    DEBUGF(infof(handle, "Server %s is not blacklisted\n", server_name));
+  }
+  return FALSE;
+}
+
+CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
+                                             struct curl_llist *list)
+{
+  /* Free the old list */
+  if(list->size)
+    Curl_llist_destroy(list, NULL);
+
+  if(servers) {
+    Curl_llist_init(list, (curl_llist_dtor) server_blacklist_llist_dtor);
+
+    /* Parse the URLs and populate the list */
+    while(*servers) {
+      struct blacklist_node *n;
+      size_t len = strlen(*servers);
+
+      n = malloc(sizeof(struct blacklist_node) + len);
+      if(!n) {
+        Curl_llist_destroy(list, NULL);
+        return CURLM_OUT_OF_MEMORY;
+      }
+      strcpy(n->server_name, *servers);
+
+      Curl_llist_insert_next(list, list->tail, n, &n->list);
+      servers++;
+    }
+  }
+
+
+  return CURLM_OK;
+}
+
+static bool pipe_head(struct Curl_easy *data,
+                      struct curl_llist *pipeline)
+{
+  if(pipeline) {
+    struct curl_llist_element *curr = pipeline->head;
+    if(curr)
+      return (curr->ptr == data) ? TRUE : FALSE;
+  }
+  return FALSE;
+}
+
+/* returns TRUE if the given handle is head of the recv pipe */
+bool Curl_recvpipe_head(struct Curl_easy *data,
+                        struct connectdata *conn)
+{
+  return pipe_head(data, &conn->recv_pipe);
+}
+
+/* returns TRUE if the given handle is head of the send pipe */
+bool Curl_sendpipe_head(struct Curl_easy *data,
+                        struct connectdata *conn)
+{
+  return pipe_head(data, &conn->send_pipe);
+}
+
+
+/*
+ * Check if the write channel is available and this handle as at the head,
+ * then grab the channel and return TRUE.
+ *
+ * If not available, return FALSE.
+ */
+
+bool Curl_pipeline_checkget_write(struct Curl_easy *data,
+                                  struct connectdata *conn)
+{
+  if(conn->bits.multiplex)
+    /* when multiplexing, we can use it at once */
+    return TRUE;
+
+  if(!conn->writechannel_inuse && Curl_sendpipe_head(data, conn)) {
+    /* Grab the channel */
+    conn->writechannel_inuse = TRUE;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+
+/*
+ * Check if the read channel is available and this handle as at the head, then
+ * grab the channel and return TRUE.
+ *
+ * If not available, return FALSE.
+ */
+
+bool Curl_pipeline_checkget_read(struct Curl_easy *data,
+                                 struct connectdata *conn)
+{
+  if(conn->bits.multiplex)
+    /* when multiplexing, we can use it at once */
+    return TRUE;
+
+  if(!conn->readchannel_inuse && Curl_recvpipe_head(data, conn)) {
+    /* Grab the channel */
+    conn->readchannel_inuse = TRUE;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+/*
+ * The current user of the pipeline write channel gives it up.
+ */
+void Curl_pipeline_leave_write(struct connectdata *conn)
+{
+  conn->writechannel_inuse = FALSE;
+}
+
+/*
+ * The current user of the pipeline read channel gives it up.
+ */
+void Curl_pipeline_leave_read(struct connectdata *conn)
+{
+  conn->readchannel_inuse = FALSE;
+}
+
+
+#if 0
+void print_pipeline(struct connectdata *conn)
+{
+  struct curl_llist_element *curr;
+  struct connectbundle *cb_ptr;
+  struct Curl_easy *data = conn->data;
+
+  cb_ptr = conn->bundle;
+
+  if(cb_ptr) {
+    curr = cb_ptr->conn_list->head;
+    while(curr) {
+      conn = curr->ptr;
+      infof(data, "- Conn %ld (%p) send_pipe: %zu, recv_pipe: %zu\n",
+            conn->connection_id,
+            (void *)conn,
+            conn->send_pipe->size,
+            conn->recv_pipe->size);
+      curr = curr->next;
+    }
+  }
+}
+
+#endif
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/pipeline.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/pipeline.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/pipeline.h	(revision 331)
@@ -0,0 +1,56 @@
+#ifndef HEADER_CURL_PIPELINE_H
+#define HEADER_CURL_PIPELINE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2015 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2013 - 2014, Linus Nielsen Feltzing, <linus@haxx.se>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+CURLcode Curl_add_handle_to_pipeline(struct Curl_easy *handle,
+                                     struct connectdata *conn);
+void Curl_move_handle_from_send_to_recv_pipe(struct Curl_easy *handle,
+                                             struct connectdata *conn);
+bool Curl_pipeline_penalized(struct Curl_easy *data,
+                             struct connectdata *conn);
+
+bool Curl_pipeline_site_blacklisted(struct Curl_easy *handle,
+                                    struct connectdata *conn);
+
+CURLMcode Curl_pipeline_set_site_blacklist(char **sites,
+                                           struct curl_llist *list_ptr);
+
+bool Curl_pipeline_server_blacklisted(struct Curl_easy *handle,
+                                      char *server_name);
+
+CURLMcode Curl_pipeline_set_server_blacklist(char **servers,
+                                             struct curl_llist *list_ptr);
+
+bool Curl_pipeline_checkget_write(struct Curl_easy *data,
+                                  struct connectdata *conn);
+bool Curl_pipeline_checkget_read(struct Curl_easy *data,
+                                 struct connectdata *conn);
+void Curl_pipeline_leave_write(struct connectdata *conn);
+void Curl_pipeline_leave_read(struct connectdata *conn);
+bool Curl_recvpipe_head(struct Curl_easy *data,
+                        struct connectdata *conn);
+bool Curl_sendpipe_head(struct Curl_easy *data,
+                        struct connectdata *conn);
+
+#endif /* HEADER_CURL_PIPELINE_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/pop3.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/pop3.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/pop3.c	(revision 331)
@@ -0,0 +1,1537 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC1734 POP3 Authentication
+ * RFC1939 POP3 protocol
+ * RFC2195 CRAM-MD5 authentication
+ * RFC2384 POP URL Scheme
+ * RFC2449 POP3 Extension Mechanism
+ * RFC2595 Using TLS with IMAP, POP3 and ACAP
+ * RFC2831 DIGEST-MD5 authentication
+ * RFC4422 Simple Authentication and Security Layer (SASL)
+ * RFC4616 PLAIN authentication
+ * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
+ * RFC5034 POP3 SASL Authentication Mechanism
+ * RFC6749 OAuth 2.0 Authorization Framework
+ * Draft   LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_POP3
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "progress.h"
+#include "transfer.h"
+#include "escape.h"
+#include "http.h" /* for HTTP proxy tunnel stuff */
+#include "socks.h"
+#include "pop3.h"
+#include "strtoofft.h"
+#include "strcase.h"
+#include "vtls/vtls.h"
+#include "connect.h"
+#include "strerror.h"
+#include "select.h"
+#include "multiif.h"
+#include "url.h"
+#include "curl_sasl.h"
+#include "curl_md5.h"
+#include "warnless.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Local API functions */
+static CURLcode pop3_regular_transfer(struct connectdata *conn, bool *done);
+static CURLcode pop3_do(struct connectdata *conn, bool *done);
+static CURLcode pop3_done(struct connectdata *conn, CURLcode status,
+                          bool premature);
+static CURLcode pop3_connect(struct connectdata *conn, bool *done);
+static CURLcode pop3_disconnect(struct connectdata *conn, bool dead);
+static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done);
+static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks,
+                        int numsocks);
+static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done);
+static CURLcode pop3_setup_connection(struct connectdata *conn);
+static CURLcode pop3_parse_url_options(struct connectdata *conn);
+static CURLcode pop3_parse_url_path(struct connectdata *conn);
+static CURLcode pop3_parse_custom_request(struct connectdata *conn);
+static CURLcode pop3_perform_auth(struct connectdata *conn, const char *mech,
+                                  const char *initresp);
+static CURLcode pop3_continue_auth(struct connectdata *conn, const char *resp);
+static void pop3_get_message(char *buffer, char **outptr);
+
+/*
+ * POP3 protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_pop3 = {
+  "POP3",                           /* scheme */
+  pop3_setup_connection,            /* setup_connection */
+  pop3_do,                          /* do_it */
+  pop3_done,                        /* done */
+  ZERO_NULL,                        /* do_more */
+  pop3_connect,                     /* connect_it */
+  pop3_multi_statemach,             /* connecting */
+  pop3_doing,                       /* doing */
+  pop3_getsock,                     /* proto_getsock */
+  pop3_getsock,                     /* doing_getsock */
+  ZERO_NULL,                        /* domore_getsock */
+  ZERO_NULL,                        /* perform_getsock */
+  pop3_disconnect,                  /* disconnect */
+  ZERO_NULL,                        /* readwrite */
+  ZERO_NULL,                        /* connection_check */
+  PORT_POP3,                        /* defport */
+  CURLPROTO_POP3,                   /* protocol */
+  PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
+  PROTOPT_URLOPTIONS
+};
+
+#ifdef USE_SSL
+/*
+ * POP3S protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_pop3s = {
+  "POP3S",                          /* scheme */
+  pop3_setup_connection,            /* setup_connection */
+  pop3_do,                          /* do_it */
+  pop3_done,                        /* done */
+  ZERO_NULL,                        /* do_more */
+  pop3_connect,                     /* connect_it */
+  pop3_multi_statemach,             /* connecting */
+  pop3_doing,                       /* doing */
+  pop3_getsock,                     /* proto_getsock */
+  pop3_getsock,                     /* doing_getsock */
+  ZERO_NULL,                        /* domore_getsock */
+  ZERO_NULL,                        /* perform_getsock */
+  pop3_disconnect,                  /* disconnect */
+  ZERO_NULL,                        /* readwrite */
+  ZERO_NULL,                        /* connection_check */
+  PORT_POP3S,                       /* defport */
+  CURLPROTO_POP3S,                  /* protocol */
+  PROTOPT_CLOSEACTION | PROTOPT_SSL
+  | PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS /* flags */
+};
+#endif
+
+/* SASL parameters for the pop3 protocol */
+static const struct SASLproto saslpop3 = {
+  "pop",                      /* The service name */
+  '*',                        /* Code received when continuation is expected */
+  '+',                        /* Code to receive upon authentication success */
+  255 - 8,                    /* Maximum initial response length (no max) */
+  pop3_perform_auth,          /* Send authentication command */
+  pop3_continue_auth,         /* Send authentication continuation */
+  pop3_get_message            /* Get SASL response message */
+};
+
+#ifdef USE_SSL
+static void pop3_to_pop3s(struct connectdata *conn)
+{
+  /* Change the connection handler */
+  conn->handler = &Curl_handler_pop3s;
+
+  /* Set the connection's upgraded to TLS flag */
+  conn->tls_upgraded = TRUE;
+}
+#else
+#define pop3_to_pop3s(x) Curl_nop_stmt
+#endif
+
+/***********************************************************************
+ *
+ * pop3_endofresp()
+ *
+ * Checks for an ending POP3 status code at the start of the given string, but
+ * also detects the APOP timestamp from the server greeting and various
+ * capabilities from the CAPA response including the supported authentication
+ * types and allowed SASL mechanisms.
+ */
+static bool pop3_endofresp(struct connectdata *conn, char *line, size_t len,
+                           int *resp)
+{
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+  /* Do we have an error response? */
+  if(len >= 4 && !memcmp("-ERR", line, 4)) {
+    *resp = '-';
+
+    return TRUE;
+  }
+
+  /* Are we processing CAPA command responses? */
+  if(pop3c->state == POP3_CAPA) {
+    /* Do we have the terminating line? */
+    if(len >= 1 && !memcmp(line, ".", 1))
+      /* Treat the response as a success */
+      *resp = '+';
+    else
+      /* Treat the response as an untagged continuation */
+      *resp = '*';
+
+    return TRUE;
+  }
+
+  /* Do we have a success response? */
+  if(len >= 3 && !memcmp("+OK", line, 3)) {
+    *resp = '+';
+
+    return TRUE;
+  }
+
+  /* Do we have a continuation response? */
+  if(len >= 1 && !memcmp("+", line, 1)) {
+    *resp = '*';
+
+    return TRUE;
+  }
+
+  return FALSE; /* Nothing for us */
+}
+
+/***********************************************************************
+ *
+ * pop3_get_message()
+ *
+ * Gets the authentication message from the response buffer.
+ */
+static void pop3_get_message(char *buffer, char **outptr)
+{
+  size_t len = 0;
+  char *message = NULL;
+
+  /* Find the start of the message */
+  for(message = buffer + 2; *message == ' ' || *message == '\t'; message++)
+    ;
+
+  /* Find the end of the message */
+  for(len = strlen(message); len--;)
+    if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' &&
+        message[len] != '\t')
+      break;
+
+  /* Terminate the message */
+  if(++len) {
+    message[len] = '\0';
+  }
+
+  *outptr = message;
+}
+
+/***********************************************************************
+ *
+ * state()
+ *
+ * This is the ONLY way to change POP3 state!
+ */
+static void state(struct connectdata *conn, pop3state newstate)
+{
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* for debug purposes */
+  static const char * const names[] = {
+    "STOP",
+    "SERVERGREET",
+    "CAPA",
+    "STARTTLS",
+    "UPGRADETLS",
+    "AUTH",
+    "APOP",
+    "USER",
+    "PASS",
+    "COMMAND",
+    "QUIT",
+    /* LAST */
+  };
+
+  if(pop3c->state != newstate)
+    infof(conn->data, "POP3 %p state change from %s to %s\n",
+          (void *)pop3c, names[pop3c->state], names[newstate]);
+#endif
+
+  pop3c->state = newstate;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_capa()
+ *
+ * Sends the CAPA command in order to obtain a list of server side supported
+ * capabilities.
+ */
+static CURLcode pop3_perform_capa(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+  pop3c->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanisms yet */
+  pop3c->sasl.authused = SASL_AUTH_NONE;  /* Clear the auth. mechanism used */
+  pop3c->tls_supported = FALSE;           /* Clear the TLS capability */
+
+  /* Send the CAPA command */
+  result = Curl_pp_sendf(&pop3c->pp, "%s", "CAPA");
+
+  if(!result)
+    state(conn, POP3_CAPA);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_starttls()
+ *
+ * Sends the STLS command to start the upgrade to TLS.
+ */
+static CURLcode pop3_perform_starttls(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  /* Send the STLS command */
+  result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "STLS");
+
+  if(!result)
+    state(conn, POP3_STARTTLS);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_upgrade_tls()
+ *
+ * Performs the upgrade to TLS.
+ */
+static CURLcode pop3_perform_upgrade_tls(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+  /* Start the SSL connection */
+  result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &pop3c->ssldone);
+
+  if(!result) {
+    if(pop3c->state != POP3_UPGRADETLS)
+      state(conn, POP3_UPGRADETLS);
+
+    if(pop3c->ssldone) {
+      pop3_to_pop3s(conn);
+      result = pop3_perform_capa(conn);
+    }
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_user()
+ *
+ * Sends a clear text USER command to authenticate with.
+ */
+static CURLcode pop3_perform_user(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  /* Check we have a username and password to authenticate with and end the
+     connect phase if we don't */
+  if(!conn->bits.user_passwd) {
+    state(conn, POP3_STOP);
+
+    return result;
+  }
+
+  /* Send the USER command */
+  result = Curl_pp_sendf(&conn->proto.pop3c.pp, "USER %s",
+                         conn->user ? conn->user : "");
+  if(!result)
+    state(conn, POP3_USER);
+
+  return result;
+}
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+/***********************************************************************
+ *
+ * pop3_perform_apop()
+ *
+ * Sends an APOP command to authenticate with.
+ */
+static CURLcode pop3_perform_apop(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  size_t i;
+  MD5_context *ctxt;
+  unsigned char digest[MD5_DIGEST_LEN];
+  char secret[2 * MD5_DIGEST_LEN + 1];
+
+  /* Check we have a username and password to authenticate with and end the
+     connect phase if we don't */
+  if(!conn->bits.user_passwd) {
+    state(conn, POP3_STOP);
+
+    return result;
+  }
+
+  /* Create the digest */
+  ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
+  if(!ctxt)
+    return CURLE_OUT_OF_MEMORY;
+
+  Curl_MD5_update(ctxt, (const unsigned char *) pop3c->apoptimestamp,
+                  curlx_uztoui(strlen(pop3c->apoptimestamp)));
+
+  Curl_MD5_update(ctxt, (const unsigned char *) conn->passwd,
+                  curlx_uztoui(strlen(conn->passwd)));
+
+  /* Finalise the digest */
+  Curl_MD5_final(ctxt, digest);
+
+  /* Convert the calculated 16 octet digest into a 32 byte hex string */
+  for(i = 0; i < MD5_DIGEST_LEN; i++)
+    snprintf(&secret[2 * i], 3, "%02x", digest[i]);
+
+  result = Curl_pp_sendf(&pop3c->pp, "APOP %s %s", conn->user, secret);
+
+  if(!result)
+    state(conn, POP3_APOP);
+
+  return result;
+}
+#endif
+
+/***********************************************************************
+ *
+ * pop3_perform_auth()
+ *
+ * Sends an AUTH command allowing the client to login with the given SASL
+ * authentication mechanism.
+ */
+static CURLcode pop3_perform_auth(struct connectdata *conn,
+                                  const char *mech,
+                                  const char *initresp)
+{
+  CURLcode result = CURLE_OK;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+  if(initresp) {                                  /* AUTH <mech> ...<crlf> */
+    /* Send the AUTH command with the initial response */
+    result = Curl_pp_sendf(&pop3c->pp, "AUTH %s %s", mech, initresp);
+  }
+  else {
+    /* Send the AUTH command */
+    result = Curl_pp_sendf(&pop3c->pp, "AUTH %s", mech);
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_continue_auth()
+ *
+ * Sends SASL continuation data or cancellation.
+ */
+static CURLcode pop3_continue_auth(struct connectdata *conn,
+                                   const char *resp)
+{
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+  return Curl_pp_sendf(&pop3c->pp, "%s", resp);
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_authentication()
+ *
+ * Initiates the authentication sequence, with the appropriate SASL
+ * authentication mechanism, falling back to APOP and clear text should a
+ * common mechanism not be available between the client and server.
+ */
+static CURLcode pop3_perform_authentication(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  saslprogress progress = SASL_IDLE;
+
+  /* Check we have enough data to authenticate with and end the
+     connect phase if we don't */
+  if(!Curl_sasl_can_authenticate(&pop3c->sasl, conn)) {
+    state(conn, POP3_STOP);
+    return result;
+  }
+
+  if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_SASL) {
+    /* Calculate the SASL login details */
+    result = Curl_sasl_start(&pop3c->sasl, conn, FALSE, &progress);
+
+    if(!result)
+      if(progress == SASL_INPROGRESS)
+        state(conn, POP3_AUTH);
+  }
+
+  if(!result && progress == SASL_IDLE) {
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+    if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_APOP)
+      /* Perform APOP authentication */
+      result = pop3_perform_apop(conn);
+    else
+#endif
+    if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_CLEARTEXT)
+      /* Perform clear text authentication */
+      result = pop3_perform_user(conn);
+    else {
+      /* Other mechanisms not supported */
+      infof(conn->data, "No known authentication mechanisms supported!\n");
+      result = CURLE_LOGIN_DENIED;
+    }
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_command()
+ *
+ * Sends a POP3 based command.
+ */
+static CURLcode pop3_perform_command(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct POP3 *pop3 = data->req.protop;
+  const char *command = NULL;
+
+  /* Calculate the default command */
+  if(pop3->id[0] == '\0' || conn->data->set.ftp_list_only) {
+    command = "LIST";
+
+    if(pop3->id[0] != '\0')
+      /* Message specific LIST so skip the BODY transfer */
+      pop3->transfer = FTPTRANSFER_INFO;
+  }
+  else
+    command = "RETR";
+
+  /* Send the command */
+  if(pop3->id[0] != '\0')
+    result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s %s",
+                           (pop3->custom && pop3->custom[0] != '\0' ?
+                            pop3->custom : command), pop3->id);
+  else
+    result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s",
+                           (pop3->custom && pop3->custom[0] != '\0' ?
+                            pop3->custom : command));
+
+  if(!result)
+    state(conn, POP3_COMMAND);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform_quit()
+ *
+ * Performs the quit action prior to sclose() be called.
+ */
+static CURLcode pop3_perform_quit(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  /* Send the QUIT command */
+  result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "QUIT");
+
+  if(!result)
+    state(conn, POP3_QUIT);
+
+  return result;
+}
+
+/* For the initial server greeting */
+static CURLcode pop3_state_servergreet_resp(struct connectdata *conn,
+                                            int pop3code,
+                                            pop3state instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  const char *line = data->state.buffer;
+  size_t len = strlen(line);
+  size_t i;
+
+  (void)instate; /* no use for this yet */
+
+  if(pop3code != '+') {
+    failf(data, "Got unexpected pop3-server response");
+    result = CURLE_WEIRD_SERVER_REPLY;
+  }
+  else {
+    /* Does the server support APOP authentication? */
+    if(len >= 4 && line[len - 2] == '>') {
+      /* Look for the APOP timestamp */
+      for(i = 3; i < len - 2; ++i) {
+        if(line[i] == '<') {
+          /* Calculate the length of the timestamp */
+          size_t timestamplen = len - 1 - i;
+          if(!timestamplen)
+            break;
+
+          /* Allocate some memory for the timestamp */
+          pop3c->apoptimestamp = (char *)calloc(1, timestamplen + 1);
+
+          if(!pop3c->apoptimestamp)
+            break;
+
+          /* Copy the timestamp */
+          memcpy(pop3c->apoptimestamp, line + i, timestamplen);
+          pop3c->apoptimestamp[timestamplen] = '\0';
+
+          /* Store the APOP capability */
+          pop3c->authtypes |= POP3_TYPE_APOP;
+          break;
+        }
+      }
+    }
+
+    result = pop3_perform_capa(conn);
+  }
+
+  return result;
+}
+
+/* For CAPA responses */
+static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
+                                     pop3state instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  const char *line = data->state.buffer;
+  size_t len = strlen(line);
+  size_t wordlen;
+
+  (void)instate; /* no use for this yet */
+
+  /* Do we have a untagged continuation response? */
+  if(pop3code == '*') {
+    /* Does the server support the STLS capability? */
+    if(len >= 4 && !memcmp(line, "STLS", 4))
+      pop3c->tls_supported = TRUE;
+
+    /* Does the server support clear text authentication? */
+    else if(len >= 4 && !memcmp(line, "USER", 4))
+      pop3c->authtypes |= POP3_TYPE_CLEARTEXT;
+
+    /* Does the server support SASL based authentication? */
+    else if(len >= 5 && !memcmp(line, "SASL ", 5)) {
+      pop3c->authtypes |= POP3_TYPE_SASL;
+
+      /* Advance past the SASL keyword */
+      line += 5;
+      len -= 5;
+
+      /* Loop through the data line */
+      for(;;) {
+        size_t llen;
+        unsigned int mechbit;
+
+        while(len &&
+              (*line == ' ' || *line == '\t' ||
+               *line == '\r' || *line == '\n')) {
+
+          line++;
+          len--;
+        }
+
+        if(!len)
+          break;
+
+        /* Extract the word */
+        for(wordlen = 0; wordlen < len && line[wordlen] != ' ' &&
+              line[wordlen] != '\t' && line[wordlen] != '\r' &&
+              line[wordlen] != '\n';)
+          wordlen++;
+
+        /* Test the word for a matching authentication mechanism */
+        mechbit = Curl_sasl_decode_mech(line, wordlen, &llen);
+        if(mechbit && llen == wordlen)
+          pop3c->sasl.authmechs |= mechbit;
+
+        line += wordlen;
+        len -= wordlen;
+      }
+    }
+  }
+  else if(pop3code == '+') {
+    if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
+      /* We don't have a SSL/TLS connection yet, but SSL is requested */
+      if(pop3c->tls_supported)
+        /* Switch to TLS connection now */
+        result = pop3_perform_starttls(conn);
+      else if(data->set.use_ssl == CURLUSESSL_TRY)
+        /* Fallback and carry on with authentication */
+        result = pop3_perform_authentication(conn);
+      else {
+        failf(data, "STLS not supported.");
+        result = CURLE_USE_SSL_FAILED;
+      }
+    }
+    else
+      result = pop3_perform_authentication(conn);
+  }
+  else {
+    /* Clear text is supported when CAPA isn't recognised */
+    pop3c->authtypes |= POP3_TYPE_CLEARTEXT;
+
+    result = pop3_perform_authentication(conn);
+  }
+
+  return result;
+}
+
+/* For STARTTLS responses */
+static CURLcode pop3_state_starttls_resp(struct connectdata *conn,
+                                         int pop3code,
+                                         pop3state instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(pop3code != '+') {
+    if(data->set.use_ssl != CURLUSESSL_TRY) {
+      failf(data, "STARTTLS denied");
+      result = CURLE_USE_SSL_FAILED;
+    }
+    else
+      result = pop3_perform_authentication(conn);
+  }
+  else
+    result = pop3_perform_upgrade_tls(conn);
+
+  return result;
+}
+
+/* For SASL authentication responses */
+static CURLcode pop3_state_auth_resp(struct connectdata *conn,
+                                     int pop3code,
+                                     pop3state instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  saslprogress progress;
+
+  (void)instate; /* no use for this yet */
+
+  result = Curl_sasl_continue(&pop3c->sasl, conn, pop3code, &progress);
+  if(!result)
+    switch(progress) {
+    case SASL_DONE:
+      state(conn, POP3_STOP);  /* Authenticated */
+      break;
+    case SASL_IDLE:            /* No mechanism left after cancellation */
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+      if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_APOP)
+        /* Perform APOP authentication */
+        result = pop3_perform_apop(conn);
+      else
+#endif
+      if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_CLEARTEXT)
+        /* Perform clear text authentication */
+        result = pop3_perform_user(conn);
+      else {
+        failf(data, "Authentication cancelled");
+        result = CURLE_LOGIN_DENIED;
+      }
+      break;
+    default:
+      break;
+    }
+
+  return result;
+}
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+/* For APOP responses */
+static CURLcode pop3_state_apop_resp(struct connectdata *conn, int pop3code,
+                                     pop3state instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(pop3code != '+') {
+    failf(data, "Authentication failed: %d", pop3code);
+    result = CURLE_LOGIN_DENIED;
+  }
+  else
+    /* End of connect phase */
+    state(conn, POP3_STOP);
+
+  return result;
+}
+#endif
+
+/* For USER responses */
+static CURLcode pop3_state_user_resp(struct connectdata *conn, int pop3code,
+                                     pop3state instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(pop3code != '+') {
+    failf(data, "Access denied. %c", pop3code);
+    result = CURLE_LOGIN_DENIED;
+  }
+  else
+    /* Send the PASS command */
+    result = Curl_pp_sendf(&conn->proto.pop3c.pp, "PASS %s",
+                           conn->passwd ? conn->passwd : "");
+  if(!result)
+    state(conn, POP3_PASS);
+
+  return result;
+}
+
+/* For PASS responses */
+static CURLcode pop3_state_pass_resp(struct connectdata *conn, int pop3code,
+                                     pop3state instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(pop3code != '+') {
+    failf(data, "Access denied. %c", pop3code);
+    result = CURLE_LOGIN_DENIED;
+  }
+  else
+    /* End of connect phase */
+    state(conn, POP3_STOP);
+
+  return result;
+}
+
+/* For command responses */
+static CURLcode pop3_state_command_resp(struct connectdata *conn,
+                                        int pop3code,
+                                        pop3state instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct POP3 *pop3 = data->req.protop;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  struct pingpong *pp = &pop3c->pp;
+
+  (void)instate; /* no use for this yet */
+
+  if(pop3code != '+') {
+    state(conn, POP3_STOP);
+    return CURLE_RECV_ERROR;
+  }
+
+  /* This 'OK' line ends with a CR LF pair which is the two first bytes of the
+     EOB string so count this is two matching bytes. This is necessary to make
+     the code detect the EOB if the only data than comes now is %2e CR LF like
+     when there is no body to return. */
+  pop3c->eob = 2;
+
+  /* But since this initial CR LF pair is not part of the actual body, we set
+     the strip counter here so that these bytes won't be delivered. */
+  pop3c->strip = 2;
+
+  if(pop3->transfer == FTPTRANSFER_BODY) {
+    /* POP3 download */
+    Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL);
+
+    if(pp->cache) {
+      /* The header "cache" contains a bunch of data that is actually body
+         content so send it as such. Note that there may even be additional
+         "headers" after the body */
+
+      if(!data->set.opt_no_body) {
+        result = Curl_pop3_write(conn, pp->cache, pp->cache_size);
+        if(result)
+          return result;
+      }
+
+      /* Free the cache */
+      Curl_safefree(pp->cache);
+
+      /* Reset the cache size */
+      pp->cache_size = 0;
+    }
+  }
+
+  /* End of DO phase */
+  state(conn, POP3_STOP);
+
+  return result;
+}
+
+static CURLcode pop3_statemach_act(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  int pop3code;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  struct pingpong *pp = &pop3c->pp;
+  size_t nread = 0;
+
+  /* Busy upgrading the connection; right now all I/O is SSL/TLS, not POP3 */
+  if(pop3c->state == POP3_UPGRADETLS)
+    return pop3_perform_upgrade_tls(conn);
+
+  /* Flush any data that needs to be sent */
+  if(pp->sendleft)
+    return Curl_pp_flushsend(pp);
+
+ do {
+    /* Read the response from the server */
+    result = Curl_pp_readresp(sock, pp, &pop3code, &nread);
+    if(result)
+      return result;
+
+    if(!pop3code)
+      break;
+
+    /* We have now received a full POP3 server response */
+    switch(pop3c->state) {
+    case POP3_SERVERGREET:
+      result = pop3_state_servergreet_resp(conn, pop3code, pop3c->state);
+      break;
+
+    case POP3_CAPA:
+      result = pop3_state_capa_resp(conn, pop3code, pop3c->state);
+      break;
+
+    case POP3_STARTTLS:
+      result = pop3_state_starttls_resp(conn, pop3code, pop3c->state);
+      break;
+
+    case POP3_AUTH:
+      result = pop3_state_auth_resp(conn, pop3code, pop3c->state);
+      break;
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+    case POP3_APOP:
+      result = pop3_state_apop_resp(conn, pop3code, pop3c->state);
+      break;
+#endif
+
+    case POP3_USER:
+      result = pop3_state_user_resp(conn, pop3code, pop3c->state);
+      break;
+
+    case POP3_PASS:
+      result = pop3_state_pass_resp(conn, pop3code, pop3c->state);
+      break;
+
+    case POP3_COMMAND:
+      result = pop3_state_command_resp(conn, pop3code, pop3c->state);
+      break;
+
+    case POP3_QUIT:
+      /* fallthrough, just stop! */
+    default:
+      /* internal error */
+      state(conn, POP3_STOP);
+      break;
+    }
+  } while(!result && pop3c->state != POP3_STOP && Curl_pp_moredata(pp));
+
+  return result;
+}
+
+/* Called repeatedly until done from multi.c */
+static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+  if((conn->handler->flags & PROTOPT_SSL) && !pop3c->ssldone) {
+    result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &pop3c->ssldone);
+    if(result || !pop3c->ssldone)
+      return result;
+  }
+
+  result = Curl_pp_statemach(&pop3c->pp, FALSE);
+  *done = (pop3c->state == POP3_STOP) ? TRUE : FALSE;
+
+  return result;
+}
+
+static CURLcode pop3_block_statemach(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+  while(pop3c->state != POP3_STOP && !result)
+    result = Curl_pp_statemach(&pop3c->pp, TRUE);
+
+  return result;
+}
+
+/* Allocate and initialize the POP3 struct for the current Curl_easy if
+   required */
+static CURLcode pop3_init(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct POP3 *pop3;
+
+  pop3 = data->req.protop = calloc(sizeof(struct POP3), 1);
+  if(!pop3)
+    result = CURLE_OUT_OF_MEMORY;
+
+  return result;
+}
+
+/* For the POP3 "protocol connect" and "doing" phases only */
+static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks,
+                        int numsocks)
+{
+  return Curl_pp_getsock(&conn->proto.pop3c.pp, socks, numsocks);
+}
+
+/***********************************************************************
+ *
+ * pop3_connect()
+ *
+ * This function should do everything that is to be considered a part of the
+ * connection phase.
+ *
+ * The variable 'done' points to will be TRUE if the protocol-layer connect
+ * phase is done when this function returns, or FALSE if not.
+ */
+static CURLcode pop3_connect(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  struct pingpong *pp = &pop3c->pp;
+
+  *done = FALSE; /* default to not done yet */
+
+  /* We always support persistent connections in POP3 */
+  connkeep(conn, "POP3 default");
+
+  /* Set the default response time-out */
+  pp->response_time = RESP_TIMEOUT;
+  pp->statemach_act = pop3_statemach_act;
+  pp->endofresp = pop3_endofresp;
+  pp->conn = conn;
+
+  /* Set the default preferred authentication type and mechanism */
+  pop3c->preftype = POP3_TYPE_ANY;
+  Curl_sasl_init(&pop3c->sasl, &saslpop3);
+
+  /* Initialise the pingpong layer */
+  Curl_pp_init(pp);
+
+  /* Parse the URL options */
+  result = pop3_parse_url_options(conn);
+  if(result)
+    return result;
+
+  /* Start off waiting for the server greeting response */
+  state(conn, POP3_SERVERGREET);
+
+  result = pop3_multi_statemach(conn, done);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_done()
+ *
+ * The DONE function. This does what needs to be done after a single DO has
+ * performed.
+ *
+ * Input argument is already checked for validity.
+ */
+static CURLcode pop3_done(struct connectdata *conn, CURLcode status,
+                          bool premature)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct POP3 *pop3 = data->req.protop;
+
+  (void)premature;
+
+  if(!pop3)
+    return CURLE_OK;
+
+  if(status) {
+    connclose(conn, "POP3 done with bad status");
+    result = status;         /* use the already set error code */
+  }
+
+  /* Cleanup our per-request based variables */
+  Curl_safefree(pop3->id);
+  Curl_safefree(pop3->custom);
+
+  /* Clear the transfer mode for the next request */
+  pop3->transfer = FTPTRANSFER_BODY;
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_perform()
+ *
+ * This is the actual DO function for POP3. Get a message/listing according to
+ * the options previously setup.
+ */
+static CURLcode pop3_perform(struct connectdata *conn, bool *connected,
+                             bool *dophase_done)
+{
+  /* This is POP3 and no proxy */
+  CURLcode result = CURLE_OK;
+  struct POP3 *pop3 = conn->data->req.protop;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  if(conn->data->set.opt_no_body) {
+    /* Requested no body means no transfer */
+    pop3->transfer = FTPTRANSFER_INFO;
+  }
+
+  *dophase_done = FALSE; /* not done yet */
+
+  /* Start the first command in the DO phase */
+  result = pop3_perform_command(conn);
+  if(result)
+    return result;
+
+  /* Run the state-machine */
+  result = pop3_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+  if(*dophase_done)
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_do()
+ *
+ * This function is registered as 'curl_do' function. It decodes the path
+ * parts etc as a wrapper to the actual DO function (pop3_perform).
+ *
+ * The input argument is already checked for validity.
+ */
+static CURLcode pop3_do(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+
+  *done = FALSE; /* default to false */
+
+  /* Parse the URL path */
+  result = pop3_parse_url_path(conn);
+  if(result)
+    return result;
+
+  /* Parse the custom request */
+  result = pop3_parse_custom_request(conn);
+  if(result)
+    return result;
+
+  result = pop3_regular_transfer(conn, done);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_disconnect()
+ *
+ * Disconnect from an POP3 server. Cleanup protocol-specific per-connection
+ * resources. BLOCKING.
+ */
+static CURLcode pop3_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+
+  /* We cannot send quit unconditionally. If this connection is stale or
+     bad in any way, sending quit and waiting around here will make the
+     disconnect wait in vain and cause more problems than we need to. */
+
+  /* The POP3 session may or may not have been allocated/setup at this
+     point! */
+  if(!dead_connection && pop3c->pp.conn && pop3c->pp.conn->bits.protoconnstart)
+    if(!pop3_perform_quit(conn))
+      (void)pop3_block_statemach(conn); /* ignore errors on QUIT */
+
+  /* Disconnect from the server */
+  Curl_pp_disconnect(&pop3c->pp);
+
+  /* Cleanup the SASL module */
+  Curl_sasl_cleanup(conn, pop3c->sasl.authused);
+
+  /* Cleanup our connection based variables */
+  Curl_safefree(pop3c->apoptimestamp);
+
+  return CURLE_OK;
+}
+
+/* Call this when the DO phase has completed */
+static CURLcode pop3_dophase_done(struct connectdata *conn, bool connected)
+{
+  (void)conn;
+  (void)connected;
+
+  return CURLE_OK;
+}
+
+/* Called from multi.c while DOing */
+static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done)
+{
+  CURLcode result = pop3_multi_statemach(conn, dophase_done);
+
+  if(result)
+    DEBUGF(infof(conn->data, "DO phase failed\n"));
+  else if(*dophase_done) {
+    result = pop3_dophase_done(conn, FALSE /* not connected */);
+
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_regular_transfer()
+ *
+ * The input argument is already checked for validity.
+ *
+ * Performs all commands done before a regular transfer between a local and a
+ * remote host.
+ */
+static CURLcode pop3_regular_transfer(struct connectdata *conn,
+                                      bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+  bool connected = FALSE;
+  struct Curl_easy *data = conn->data;
+
+  /* Make sure size is unknown at this point */
+  data->req.size = -1;
+
+  /* Set the progress data */
+  Curl_pgrsSetUploadCounter(data, 0);
+  Curl_pgrsSetDownloadCounter(data, 0);
+  Curl_pgrsSetUploadSize(data, -1);
+  Curl_pgrsSetDownloadSize(data, -1);
+
+  /* Carry out the perform */
+  result = pop3_perform(conn, &connected, dophase_done);
+
+  /* Perform post DO phase operations if necessary */
+  if(!result && *dophase_done)
+    result = pop3_dophase_done(conn, connected);
+
+  return result;
+}
+
+static CURLcode pop3_setup_connection(struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+
+  /* Initialise the POP3 layer */
+  CURLcode result = pop3_init(conn);
+  if(result)
+    return result;
+
+  /* Clear the TLS upgraded flag */
+  conn->tls_upgraded = FALSE;
+  data->state.path++;   /* don't include the initial slash */
+
+  return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * pop3_parse_url_options()
+ *
+ * Parse the URL login options.
+ */
+static CURLcode pop3_parse_url_options(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  const char *ptr = conn->options;
+
+  pop3c->sasl.resetprefs = TRUE;
+
+  while(!result && ptr && *ptr) {
+    const char *key = ptr;
+    const char *value;
+
+    while(*ptr && *ptr != '=')
+        ptr++;
+
+    value = ptr + 1;
+
+    while(*ptr && *ptr != ';')
+      ptr++;
+
+    if(strncasecompare(key, "AUTH=", 5)) {
+      result = Curl_sasl_parse_url_auth_option(&pop3c->sasl,
+                                               value, ptr - value);
+
+      if(result && strncasecompare(value, "+APOP", ptr - value)) {
+        pop3c->preftype = POP3_TYPE_APOP;
+        pop3c->sasl.prefmech = SASL_AUTH_NONE;
+        result = CURLE_OK;
+      }
+    }
+    else
+      result = CURLE_URL_MALFORMAT;
+
+    if(*ptr == ';')
+      ptr++;
+  }
+
+  if(pop3c->preftype != POP3_TYPE_APOP)
+    switch(pop3c->sasl.prefmech) {
+    case SASL_AUTH_NONE:
+      pop3c->preftype = POP3_TYPE_NONE;
+      break;
+    case SASL_AUTH_DEFAULT:
+      pop3c->preftype = POP3_TYPE_ANY;
+      break;
+    default:
+      pop3c->preftype = POP3_TYPE_SASL;
+      break;
+    }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * pop3_parse_url_path()
+ *
+ * Parse the URL path into separate path components.
+ */
+static CURLcode pop3_parse_url_path(struct connectdata *conn)
+{
+  /* The POP3 struct is already initialised in pop3_connect() */
+  struct Curl_easy *data = conn->data;
+  struct POP3 *pop3 = data->req.protop;
+  const char *path = data->state.path;
+
+  /* URL decode the path for the message ID */
+  return Curl_urldecode(data, path, 0, &pop3->id, NULL, TRUE);
+}
+
+/***********************************************************************
+ *
+ * pop3_parse_custom_request()
+ *
+ * Parse the custom request.
+ */
+static CURLcode pop3_parse_custom_request(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct POP3 *pop3 = data->req.protop;
+  const char *custom = data->set.str[STRING_CUSTOMREQUEST];
+
+  /* URL decode the custom request */
+  if(custom)
+    result = Curl_urldecode(data, custom, 0, &pop3->custom, NULL, TRUE);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * Curl_pop3_write()
+ *
+ * This function scans the body after the end-of-body and writes everything
+ * until the end is found.
+ */
+CURLcode Curl_pop3_write(struct connectdata *conn, char *str, size_t nread)
+{
+  /* This code could be made into a special function in the handler struct */
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct SingleRequest *k = &data->req;
+
+  struct pop3_conn *pop3c = &conn->proto.pop3c;
+  bool strip_dot = FALSE;
+  size_t last = 0;
+  size_t i;
+
+  /* Search through the buffer looking for the end-of-body marker which is
+     5 bytes (0d 0a 2e 0d 0a). Note that a line starting with a dot matches
+     the eob so the server will have prefixed it with an extra dot which we
+     need to strip out. Additionally the marker could of course be spread out
+     over 5 different data chunks. */
+  for(i = 0; i < nread; i++) {
+    size_t prev = pop3c->eob;
+
+    switch(str[i]) {
+    case 0x0d:
+      if(pop3c->eob == 0) {
+        pop3c->eob++;
+
+        if(i) {
+          /* Write out the body part that didn't match */
+          result = Curl_client_write(conn, CLIENTWRITE_BODY, &str[last],
+                                     i - last);
+
+          if(result)
+            return result;
+
+          last = i;
+        }
+      }
+      else if(pop3c->eob == 3)
+        pop3c->eob++;
+      else
+        /* If the character match wasn't at position 0 or 3 then restart the
+           pattern matching */
+        pop3c->eob = 1;
+      break;
+
+    case 0x0a:
+      if(pop3c->eob == 1 || pop3c->eob == 4)
+        pop3c->eob++;
+      else
+        /* If the character match wasn't at position 1 or 4 then start the
+           search again */
+        pop3c->eob = 0;
+      break;
+
+    case 0x2e:
+      if(pop3c->eob == 2)
+        pop3c->eob++;
+      else if(pop3c->eob == 3) {
+        /* We have an extra dot after the CRLF which we need to strip off */
+        strip_dot = TRUE;
+        pop3c->eob = 0;
+      }
+      else
+        /* If the character match wasn't at position 2 then start the search
+           again */
+        pop3c->eob = 0;
+      break;
+
+    default:
+      pop3c->eob = 0;
+      break;
+    }
+
+    /* Did we have a partial match which has subsequently failed? */
+    if(prev && prev >= pop3c->eob) {
+      /* Strip can only be non-zero for the very first mismatch after CRLF
+         and then both prev and strip are equal and nothing will be output
+         below */
+      while(prev && pop3c->strip) {
+        prev--;
+        pop3c->strip--;
+      }
+
+      if(prev) {
+        /* If the partial match was the CRLF and dot then only write the CRLF
+           as the server would have inserted the dot */
+        result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)POP3_EOB,
+                                   strip_dot ? prev - 1 : prev);
+
+        if(result)
+          return result;
+
+        last = i;
+        strip_dot = FALSE;
+      }
+    }
+  }
+
+  if(pop3c->eob == POP3_EOB_LEN) {
+    /* We have a full match so the transfer is done, however we must transfer
+    the CRLF at the start of the EOB as this is considered to be part of the
+    message as per RFC-1939, sect. 3 */
+    result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)POP3_EOB, 2);
+
+    k->keepon &= ~KEEP_RECV;
+    pop3c->eob = 0;
+
+    return result;
+  }
+
+  if(pop3c->eob)
+    /* While EOB is matching nothing should be output */
+    return CURLE_OK;
+
+  if(nread - last) {
+    result = Curl_client_write(conn, CLIENTWRITE_BODY, &str[last],
+                               nread - last);
+  }
+
+  return result;
+}
+
+#endif /* CURL_DISABLE_POP3 */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/pop3.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/pop3.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/pop3.h	(revision 331)
@@ -0,0 +1,95 @@
+#ifndef HEADER_CURL_POP3_H
+#define HEADER_CURL_POP3_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2009 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "pingpong.h"
+#include "curl_sasl.h"
+
+/****************************************************************************
+ * POP3 unique setup
+ ***************************************************************************/
+typedef enum {
+  POP3_STOP,         /* do nothing state, stops the state machine */
+  POP3_SERVERGREET,  /* waiting for the initial greeting immediately after
+                        a connect */
+  POP3_CAPA,
+  POP3_STARTTLS,
+  POP3_UPGRADETLS,   /* asynchronously upgrade the connection to SSL/TLS
+                       (multi mode only) */
+  POP3_AUTH,
+  POP3_APOP,
+  POP3_USER,
+  POP3_PASS,
+  POP3_COMMAND,
+  POP3_QUIT,
+  POP3_LAST          /* never used */
+} pop3state;
+
+/* This POP3 struct is used in the Curl_easy. All POP3 data that is
+   connection-oriented must be in pop3_conn to properly deal with the fact that
+   perhaps the Curl_easy is changed between the times the connection is
+   used. */
+struct POP3 {
+  curl_pp_transfer transfer;
+  char *id;               /* Message ID */
+  char *custom;           /* Custom Request */
+};
+
+/* pop3_conn is used for struct connection-oriented data in the connectdata
+   struct */
+struct pop3_conn {
+  struct pingpong pp;
+  pop3state state;        /* Always use pop3.c:state() to change state! */
+  bool ssldone;           /* Is connect() over SSL done? */
+  size_t eob;             /* Number of bytes of the EOB (End Of Body) that
+                             have been received so far */
+  size_t strip;           /* Number of bytes from the start to ignore as
+                             non-body */
+  struct SASL sasl;       /* SASL-related storage */
+  unsigned int authtypes; /* Accepted authentication types */
+  unsigned int preftype;  /* Preferred authentication type */
+  char *apoptimestamp;    /* APOP timestamp from the server greeting */
+  bool tls_supported;     /* StartTLS capability supported by server */
+};
+
+extern const struct Curl_handler Curl_handler_pop3;
+extern const struct Curl_handler Curl_handler_pop3s;
+
+/* Authentication type flags */
+#define POP3_TYPE_CLEARTEXT (1 << 0)
+#define POP3_TYPE_APOP      (1 << 1)
+#define POP3_TYPE_SASL      (1 << 2)
+
+/* Authentication type values */
+#define POP3_TYPE_NONE      0
+#define POP3_TYPE_ANY       ~0U
+
+/* This is the 5-bytes End-Of-Body marker for POP3 */
+#define POP3_EOB "\x0d\x0a\x2e\x0d\x0a"
+#define POP3_EOB_LEN 5
+
+/* This function scans the body after the end-of-body and writes everything
+ * until the end is found */
+CURLcode Curl_pop3_write(struct connectdata *conn, char *str, size_t nread);
+
+#endif /* HEADER_CURL_POP3_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/progress.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/progress.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/progress.c	(revision 331)
@@ -0,0 +1,577 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "urldata.h"
+#include "sendf.h"
+#include "progress.h"
+#include "curl_printf.h"
+
+/* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero
+   byte) */
+static void time2str(char *r, curl_off_t seconds)
+{
+  curl_off_t d, h, m, s;
+  if(seconds <= 0) {
+    strcpy(r, "--:--:--");
+    return;
+  }
+  h = seconds / CURL_OFF_T_C(3600);
+  if(h <= CURL_OFF_T_C(99)) {
+    m = (seconds - (h*CURL_OFF_T_C(3600))) / CURL_OFF_T_C(60);
+    s = (seconds - (h*CURL_OFF_T_C(3600))) - (m*CURL_OFF_T_C(60));
+    snprintf(r, 9, "%2" CURL_FORMAT_CURL_OFF_T ":%02" CURL_FORMAT_CURL_OFF_T
+             ":%02" CURL_FORMAT_CURL_OFF_T, h, m, s);
+  }
+  else {
+    /* this equals to more than 99 hours, switch to a more suitable output
+       format to fit within the limits. */
+    d = seconds / CURL_OFF_T_C(86400);
+    h = (seconds - (d*CURL_OFF_T_C(86400))) / CURL_OFF_T_C(3600);
+    if(d <= CURL_OFF_T_C(999))
+      snprintf(r, 9, "%3" CURL_FORMAT_CURL_OFF_T
+               "d %02" CURL_FORMAT_CURL_OFF_T "h", d, h);
+    else
+      snprintf(r, 9, "%7" CURL_FORMAT_CURL_OFF_T "d", d);
+  }
+}
+
+/* The point of this function would be to return a string of the input data,
+   but never longer than 5 columns (+ one zero byte).
+   Add suffix k, M, G when suitable... */
+static char *max5data(curl_off_t bytes, char *max5)
+{
+#define ONE_KILOBYTE  CURL_OFF_T_C(1024)
+#define ONE_MEGABYTE (CURL_OFF_T_C(1024) * ONE_KILOBYTE)
+#define ONE_GIGABYTE (CURL_OFF_T_C(1024) * ONE_MEGABYTE)
+#define ONE_TERABYTE (CURL_OFF_T_C(1024) * ONE_GIGABYTE)
+#define ONE_PETABYTE (CURL_OFF_T_C(1024) * ONE_TERABYTE)
+
+  if(bytes < CURL_OFF_T_C(100000))
+    snprintf(max5, 6, "%5" CURL_FORMAT_CURL_OFF_T, bytes);
+
+  else if(bytes < CURL_OFF_T_C(10000) * ONE_KILOBYTE)
+    snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "k", bytes/ONE_KILOBYTE);
+
+  else if(bytes < CURL_OFF_T_C(100) * ONE_MEGABYTE)
+    /* 'XX.XM' is good as long as we're less than 100 megs */
+    snprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0"
+             CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE,
+             (bytes%ONE_MEGABYTE) / (ONE_MEGABYTE/CURL_OFF_T_C(10)) );
+
+#if (CURL_SIZEOF_CURL_OFF_T > 4)
+
+  else if(bytes < CURL_OFF_T_C(10000) * ONE_MEGABYTE)
+    /* 'XXXXM' is good until we're at 10000MB or above */
+    snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE);
+
+  else if(bytes < CURL_OFF_T_C(100) * ONE_GIGABYTE)
+    /* 10000 MB - 100 GB, we show it as XX.XG */
+    snprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0"
+             CURL_FORMAT_CURL_OFF_T "G", bytes/ONE_GIGABYTE,
+             (bytes%ONE_GIGABYTE) / (ONE_GIGABYTE/CURL_OFF_T_C(10)) );
+
+  else if(bytes < CURL_OFF_T_C(10000) * ONE_GIGABYTE)
+    /* up to 10000GB, display without decimal: XXXXG */
+    snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "G", bytes/ONE_GIGABYTE);
+
+  else if(bytes < CURL_OFF_T_C(10000) * ONE_TERABYTE)
+    /* up to 10000TB, display without decimal: XXXXT */
+    snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "T", bytes/ONE_TERABYTE);
+
+  else
+    /* up to 10000PB, display without decimal: XXXXP */
+    snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "P", bytes/ONE_PETABYTE);
+
+    /* 16384 petabytes (16 exabytes) is the maximum a 64 bit unsigned number
+       can hold, but our data type is signed so 8192PB will be the maximum. */
+
+#else
+
+  else
+    snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE);
+
+#endif
+
+  return max5;
+}
+
+/*
+
+   New proposed interface, 9th of February 2000:
+
+   pgrsStartNow() - sets start time
+   pgrsSetDownloadSize(x) - known expected download size
+   pgrsSetUploadSize(x) - known expected upload size
+   pgrsSetDownloadCounter() - amount of data currently downloaded
+   pgrsSetUploadCounter() - amount of data currently uploaded
+   pgrsUpdate() - show progress
+   pgrsDone() - transfer complete
+
+*/
+
+int Curl_pgrsDone(struct connectdata *conn)
+{
+  int rc;
+  struct Curl_easy *data = conn->data;
+  data->progress.lastshow = 0;
+  rc = Curl_pgrsUpdate(conn); /* the final (forced) update */
+  if(rc)
+    return rc;
+
+  if(!(data->progress.flags & PGRS_HIDE) &&
+     !data->progress.callback)
+    /* only output if we don't use a progress callback and we're not
+     * hidden */
+    fprintf(data->set.err, "\n");
+
+  data->progress.speeder_c = 0; /* reset the progress meter display */
+  return 0;
+}
+
+/* reset the known transfer sizes */
+void Curl_pgrsResetTransferSizes(struct Curl_easy *data)
+{
+  Curl_pgrsSetDownloadSize(data, -1);
+  Curl_pgrsSetUploadSize(data, -1);
+}
+
+/*
+ * @unittest: 1399
+ */
+void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
+{
+  struct curltime now = Curl_now();
+  time_t *delta = NULL;
+
+  switch(timer) {
+  default:
+  case TIMER_NONE:
+    /* mistake filter */
+    break;
+  case TIMER_STARTOP:
+    /* This is set at the start of a transfer */
+    data->progress.t_startop = now;
+    break;
+  case TIMER_STARTSINGLE:
+    /* This is set at the start of each single fetch */
+    data->progress.t_startsingle = now;
+    data->progress.is_t_startransfer_set = false;
+    break;
+  case TIMER_STARTACCEPT:
+    data->progress.t_acceptdata = now;
+    break;
+  case TIMER_NAMELOOKUP:
+    delta = &data->progress.t_nslookup;
+    break;
+  case TIMER_CONNECT:
+    delta = &data->progress.t_connect;
+    break;
+  case TIMER_APPCONNECT:
+    delta = &data->progress.t_appconnect;
+    break;
+  case TIMER_PRETRANSFER:
+    delta = &data->progress.t_pretransfer;
+    break;
+  case TIMER_STARTTRANSFER:
+    delta = &data->progress.t_starttransfer;
+    /* prevent updating t_starttransfer unless:
+     *   1) this is the first time we're setting t_starttransfer
+     *   2) a redirect has occurred since the last time t_starttransfer was set
+     * This prevents repeated invocations of the function from incorrectly
+     * changing the t_starttransfer time.
+     */
+    if(data->progress.is_t_startransfer_set) {
+      return;
+    }
+    else {
+      data->progress.is_t_startransfer_set = true;
+      break;
+    }
+  case TIMER_POSTRANSFER:
+    /* this is the normal end-of-transfer thing */
+    break;
+  case TIMER_REDIRECT:
+    data->progress.t_redirect = Curl_timediff_us(now, data->progress.start);
+    break;
+  }
+  if(delta) {
+    timediff_t us = Curl_timediff_us(now, data->progress.t_startsingle);
+    if(us < 1)
+      us = 1; /* make sure at least one microsecond passed */
+    *delta += us;
+  }
+}
+
+void Curl_pgrsStartNow(struct Curl_easy *data)
+{
+  data->progress.speeder_c = 0; /* reset the progress meter display */
+  data->progress.start = Curl_now();
+  data->progress.is_t_startransfer_set = false;
+  data->progress.ul_limit_start.tv_sec = 0;
+  data->progress.ul_limit_start.tv_usec = 0;
+  data->progress.dl_limit_start.tv_sec = 0;
+  data->progress.dl_limit_start.tv_usec = 0;
+  /* clear all bits except HIDE and HEADERS_OUT */
+  data->progress.flags &= PGRS_HIDE|PGRS_HEADERS_OUT;
+}
+
+/*
+ * This is used to handle speed limits, calculating how much milliseconds we
+ * need to wait until we're back under the speed limit, if needed.
+ *
+ * The way it works is by having a "starting point" (time & amount of data
+ * transferred by then) used in the speed computation, to be used instead of
+ * the start of the transfer.  This starting point is regularly moved as
+ * transfer goes on, to keep getting accurate values (instead of average over
+ * the entire transfer).
+ *
+ * This function takes the current amount of data transferred, the amount at
+ * the starting point, the limit (in bytes/s), the time of the starting point
+ * and the current time.
+ *
+ * Returns -1 if no waiting is needed (not enough data transferred since
+ * starting point yet), 0 when no waiting is needed but the starting point
+ * should be reset (to current), or the number of milliseconds to wait to get
+ * back under the speed limit.
+ */
+long Curl_pgrsLimitWaitTime(curl_off_t cursize,
+                            curl_off_t startsize,
+                            curl_off_t limit,
+                            struct curltime start,
+                            struct curltime now)
+{
+  curl_off_t size = cursize - startsize;
+  time_t minimum;
+  time_t actual;
+
+  /* we don't have a starting point yet -- return 0 so it gets (re)set */
+  if(start.tv_sec == 0 && start.tv_usec == 0)
+    return 0;
+
+  /* not enough data yet */
+  if(size < limit)
+    return -1;
+
+  minimum = (time_t) (CURL_OFF_T_C(1000) * size / limit);
+  actual = Curl_timediff(now, start);
+
+  if(actual < minimum)
+    /* this is a conversion on some systems (64bit time_t => 32bit long) */
+    return (long)(minimum - actual);
+
+  return 0;
+}
+
+void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size)
+{
+  struct curltime now = Curl_now();
+
+  data->progress.downloaded = size;
+
+  /* download speed limit */
+  if((data->set.max_recv_speed > 0) &&
+     (Curl_pgrsLimitWaitTime(data->progress.downloaded,
+                             data->progress.dl_limit_size,
+                             data->set.max_recv_speed,
+                             data->progress.dl_limit_start,
+                             now) == 0)) {
+    data->progress.dl_limit_start = now;
+    data->progress.dl_limit_size = size;
+  }
+}
+
+void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size)
+{
+  struct curltime now = Curl_now();
+
+  data->progress.uploaded = size;
+
+  /* upload speed limit */
+  if((data->set.max_send_speed > 0) &&
+     (Curl_pgrsLimitWaitTime(data->progress.uploaded,
+                             data->progress.ul_limit_size,
+                             data->set.max_send_speed,
+                             data->progress.ul_limit_start,
+                             now) == 0)) {
+    data->progress.ul_limit_start = now;
+    data->progress.ul_limit_size = size;
+  }
+}
+
+void Curl_pgrsSetDownloadSize(struct Curl_easy *data, curl_off_t size)
+{
+  if(size >= 0) {
+    data->progress.size_dl = size;
+    data->progress.flags |= PGRS_DL_SIZE_KNOWN;
+  }
+  else {
+    data->progress.size_dl = 0;
+    data->progress.flags &= ~PGRS_DL_SIZE_KNOWN;
+  }
+}
+
+void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size)
+{
+  if(size >= 0) {
+    data->progress.size_ul = size;
+    data->progress.flags |= PGRS_UL_SIZE_KNOWN;
+  }
+  else {
+    data->progress.size_ul = 0;
+    data->progress.flags &= ~PGRS_UL_SIZE_KNOWN;
+  }
+}
+
+/*
+ * Curl_pgrsUpdate() returns 0 for success or the value returned by the
+ * progress callback!
+ */
+int Curl_pgrsUpdate(struct connectdata *conn)
+{
+  struct curltime now;
+  int result;
+  char max5[6][10];
+  curl_off_t dlpercen = 0;
+  curl_off_t ulpercen = 0;
+  curl_off_t total_percen = 0;
+  curl_off_t total_transfer;
+  curl_off_t total_expected_transfer;
+  curl_off_t timespent;
+  struct Curl_easy *data = conn->data;
+  int nowindex = data->progress.speeder_c% CURR_TIME;
+  int checkindex;
+  int countindex; /* amount of seconds stored in the speeder array */
+  char time_left[10];
+  char time_total[10];
+  char time_spent[10];
+  curl_off_t ulestimate = 0;
+  curl_off_t dlestimate = 0;
+  curl_off_t total_estimate;
+  bool shownow = FALSE;
+
+  now = Curl_now(); /* what time is it */
+
+  /* The time spent so far (from the start) */
+  data->progress.timespent = Curl_timediff_us(now, data->progress.start);
+  timespent = (curl_off_t)data->progress.timespent/1000000; /* seconds */
+
+  /* The average download speed this far */
+  data->progress.dlspeed = (curl_off_t)
+    (data->progress.downloaded/
+     (timespent>0?timespent:1));
+
+  /* The average upload speed this far */
+  data->progress.ulspeed = (curl_off_t)
+    (data->progress.uploaded/
+     (timespent>0?timespent:1));
+
+  /* Calculations done at most once a second, unless end is reached */
+  if(data->progress.lastshow != now.tv_sec) {
+    shownow = TRUE;
+
+    data->progress.lastshow = now.tv_sec;
+
+    /* Let's do the "current speed" thing, with the dl + ul speeds
+       combined. Store the speed at entry 'nowindex'. */
+    data->progress.speeder[ nowindex ] =
+      data->progress.downloaded + data->progress.uploaded;
+
+    /* remember the exact time for this moment */
+    data->progress.speeder_time [ nowindex ] = now;
+
+    /* advance our speeder_c counter, which is increased every time we get
+       here and we expect it to never wrap as 2^32 is a lot of seconds! */
+    data->progress.speeder_c++;
+
+    /* figure out how many index entries of data we have stored in our speeder
+       array. With N_ENTRIES filled in, we have about N_ENTRIES-1 seconds of
+       transfer. Imagine, after one second we have filled in two entries,
+       after two seconds we've filled in three entries etc. */
+    countindex = ((data->progress.speeder_c >= CURR_TIME)?
+                  CURR_TIME:data->progress.speeder_c) - 1;
+
+    /* first of all, we don't do this if there's no counted seconds yet */
+    if(countindex) {
+      timediff_t span_ms;
+
+      /* Get the index position to compare with the 'nowindex' position.
+         Get the oldest entry possible. While we have less than CURR_TIME
+         entries, the first entry will remain the oldest. */
+      checkindex = (data->progress.speeder_c >= CURR_TIME)?
+        data->progress.speeder_c%CURR_TIME:0;
+
+      /* Figure out the exact time for the time span */
+      span_ms = Curl_timediff(now,
+                              data->progress.speeder_time[checkindex]);
+      if(0 == span_ms)
+        span_ms = 1; /* at least one millisecond MUST have passed */
+
+      /* Calculate the average speed the last 'span_ms' milliseconds */
+      {
+        curl_off_t amount = data->progress.speeder[nowindex]-
+          data->progress.speeder[checkindex];
+
+        if(amount > CURL_OFF_T_C(4294967) /* 0xffffffff/1000 */)
+          /* the 'amount' value is bigger than would fit in 32 bits if
+             multiplied with 1000, so we use the double math for this */
+          data->progress.current_speed = (curl_off_t)
+            ((double)amount/((double)span_ms/1000.0));
+        else
+          /* the 'amount' value is small enough to fit within 32 bits even
+             when multiplied with 1000 */
+          data->progress.current_speed = amount*CURL_OFF_T_C(1000)/span_ms;
+      }
+    }
+    else
+      /* the first second we use the average */
+      data->progress.current_speed =
+        data->progress.ulspeed + data->progress.dlspeed;
+
+  } /* Calculations end */
+
+  if(!(data->progress.flags & PGRS_HIDE)) {
+    /* progress meter has not been shut off */
+
+    if(data->set.fxferinfo) {
+      /* There's a callback set, call that */
+      result = data->set.fxferinfo(data->set.progress_client,
+                                   data->progress.size_dl,
+                                   data->progress.downloaded,
+                                   data->progress.size_ul,
+                                   data->progress.uploaded);
+      if(result)
+        failf(data, "Callback aborted");
+      return result;
+    }
+    if(data->set.fprogress) {
+      /* The older deprecated callback is set, call that */
+      result = data->set.fprogress(data->set.progress_client,
+                                   (double)data->progress.size_dl,
+                                   (double)data->progress.downloaded,
+                                   (double)data->progress.size_ul,
+                                   (double)data->progress.uploaded);
+      if(result)
+        failf(data, "Callback aborted");
+      return result;
+    }
+
+    if(!shownow)
+      /* only show the internal progress meter once per second */
+      return 0;
+
+    /* If there's no external callback set, use internal code to show
+       progress */
+
+    if(!(data->progress.flags & PGRS_HEADERS_OUT)) {
+      if(data->state.resume_from) {
+        fprintf(data->set.err,
+                "** Resuming transfer from byte position %"
+                CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from);
+      }
+      fprintf(data->set.err,
+              "  %% Total    %% Received %% Xferd  Average Speed   "
+              "Time    Time     Time  Current\n"
+              "                                 Dload  Upload   "
+              "Total   Spent    Left  Speed\n");
+      data->progress.flags |= PGRS_HEADERS_OUT; /* headers are shown */
+    }
+
+    /* Figure out the estimated time of arrival for the upload */
+    if((data->progress.flags & PGRS_UL_SIZE_KNOWN) &&
+       (data->progress.ulspeed > CURL_OFF_T_C(0))) {
+      ulestimate = data->progress.size_ul / data->progress.ulspeed;
+
+      if(data->progress.size_ul > CURL_OFF_T_C(10000))
+        ulpercen = data->progress.uploaded /
+          (data->progress.size_ul/CURL_OFF_T_C(100));
+      else if(data->progress.size_ul > CURL_OFF_T_C(0))
+        ulpercen = (data->progress.uploaded*100) /
+          data->progress.size_ul;
+    }
+
+    /* ... and the download */
+    if((data->progress.flags & PGRS_DL_SIZE_KNOWN) &&
+       (data->progress.dlspeed > CURL_OFF_T_C(0))) {
+      dlestimate = data->progress.size_dl / data->progress.dlspeed;
+
+      if(data->progress.size_dl > CURL_OFF_T_C(10000))
+        dlpercen = data->progress.downloaded /
+          (data->progress.size_dl/CURL_OFF_T_C(100));
+      else if(data->progress.size_dl > CURL_OFF_T_C(0))
+        dlpercen = (data->progress.downloaded*100) /
+          data->progress.size_dl;
+    }
+
+    /* Now figure out which of them is slower and use that one for the
+       total estimate! */
+    total_estimate = ulestimate>dlestimate?ulestimate:dlestimate;
+
+    /* create the three time strings */
+    time2str(time_left, total_estimate > 0?(total_estimate - timespent):0);
+    time2str(time_total, total_estimate);
+    time2str(time_spent, timespent);
+
+    /* Get the total amount of data expected to get transferred */
+    total_expected_transfer =
+      (data->progress.flags & PGRS_UL_SIZE_KNOWN?
+       data->progress.size_ul:data->progress.uploaded)+
+      (data->progress.flags & PGRS_DL_SIZE_KNOWN?
+       data->progress.size_dl:data->progress.downloaded);
+
+    /* We have transferred this much so far */
+    total_transfer = data->progress.downloaded + data->progress.uploaded;
+
+    /* Get the percentage of data transferred so far */
+    if(total_expected_transfer > CURL_OFF_T_C(10000))
+      total_percen = total_transfer /
+        (total_expected_transfer/CURL_OFF_T_C(100));
+    else if(total_expected_transfer > CURL_OFF_T_C(0))
+      total_percen = (total_transfer*100) / total_expected_transfer;
+
+    fprintf(data->set.err,
+            "\r"
+            "%3" CURL_FORMAT_CURL_OFF_T " %s  "
+            "%3" CURL_FORMAT_CURL_OFF_T " %s  "
+            "%3" CURL_FORMAT_CURL_OFF_T " %s  %s  %s %s %s %s %s",
+            total_percen,  /* 3 letters */                /* total % */
+            max5data(total_expected_transfer, max5[2]),   /* total size */
+            dlpercen,      /* 3 letters */                /* rcvd % */
+            max5data(data->progress.downloaded, max5[0]), /* rcvd size */
+            ulpercen,      /* 3 letters */                /* xfer % */
+            max5data(data->progress.uploaded, max5[1]),   /* xfer size */
+            max5data(data->progress.dlspeed, max5[3]),    /* avrg dl speed */
+            max5data(data->progress.ulspeed, max5[4]),    /* avrg ul speed */
+            time_total,    /* 8 letters */                /* total time */
+            time_spent,    /* 8 letters */                /* time spent */
+            time_left,     /* 8 letters */                /* time left */
+            max5data(data->progress.current_speed, max5[5]) /* current speed */
+            );
+
+    /* we flush the output stream to make it appear as soon as possible */
+    fflush(data->set.err);
+
+  } /* !(data->progress.flags & PGRS_HIDE) */
+
+  return 0;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/progress.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/progress.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/progress.h	(revision 331)
@@ -0,0 +1,77 @@
+#ifndef HEADER_CURL_PROGRESS_H
+#define HEADER_CURL_PROGRESS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "timeval.h"
+
+
+typedef enum {
+  TIMER_NONE,
+  TIMER_STARTOP,
+  TIMER_STARTSINGLE,
+  TIMER_NAMELOOKUP,
+  TIMER_CONNECT,
+  TIMER_APPCONNECT,
+  TIMER_PRETRANSFER,
+  TIMER_STARTTRANSFER,
+  TIMER_POSTRANSFER,
+  TIMER_STARTACCEPT,
+  TIMER_REDIRECT,
+  TIMER_LAST /* must be last */
+} timerid;
+
+int Curl_pgrsDone(struct connectdata *);
+void Curl_pgrsStartNow(struct Curl_easy *data);
+void Curl_pgrsSetDownloadSize(struct Curl_easy *data, curl_off_t size);
+void Curl_pgrsSetUploadSize(struct Curl_easy *data, curl_off_t size);
+void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size);
+void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size);
+int Curl_pgrsUpdate(struct connectdata *);
+void Curl_pgrsResetTransferSizes(struct Curl_easy *data);
+void Curl_pgrsTime(struct Curl_easy *data, timerid timer);
+long Curl_pgrsLimitWaitTime(curl_off_t cursize,
+                            curl_off_t startsize,
+                            curl_off_t limit,
+                            struct curltime start,
+                            struct curltime now);
+
+/* Don't show progress for sizes smaller than: */
+#define LEAST_SIZE_PROGRESS BUFSIZE
+
+#define PROGRESS_DOWNLOAD (1<<0)
+#define PROGRESS_UPLOAD   (1<<1)
+#define PROGRESS_DOWN_AND_UP (PROGRESS_UPLOAD | PROGRESS_DOWNLOAD)
+
+#define PGRS_SHOW_DL (1<<0)
+#define PGRS_SHOW_UL (1<<1)
+#define PGRS_DONE_DL (1<<2)
+#define PGRS_DONE_UL (1<<3)
+#define PGRS_HIDE    (1<<4)
+#define PGRS_UL_SIZE_KNOWN (1<<5)
+#define PGRS_DL_SIZE_KNOWN (1<<6)
+
+#define PGRS_HEADERS_OUT (1<<7) /* set when the headers have been written */
+
+
+#endif /* HEADER_CURL_PROGRESS_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/rand.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/rand.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/rand.c	(revision 331)
@@ -0,0 +1,179 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include <curl/curl.h>
+#include "vtls/vtls.h"
+#include "sendf.h"
+#include "rand.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+static CURLcode randit(struct Curl_easy *data, unsigned int *rnd)
+{
+  unsigned int r;
+  CURLcode result = CURLE_OK;
+  static unsigned int randseed;
+  static bool seeded = FALSE;
+
+#ifdef CURLDEBUG
+  char *force_entropy = getenv("CURL_ENTROPY");
+  if(force_entropy) {
+    if(!seeded) {
+      unsigned int seed = 0;
+      size_t elen = strlen(force_entropy);
+      size_t clen = sizeof(seed);
+      size_t min = elen < clen ? elen : clen;
+      memcpy((char *)&seed, force_entropy, min);
+      randseed = ntohl(seed);
+      seeded = TRUE;
+    }
+    else
+      randseed++;
+    *rnd = randseed;
+    return CURLE_OK;
+  }
+#endif
+
+  /* data may be NULL! */
+  result = Curl_ssl_random(data, (unsigned char *)rnd, sizeof(*rnd));
+  if(result != CURLE_NOT_BUILT_IN)
+    /* only if there is no random function in the TLS backend do the non crypto
+       version, otherwise return result */
+    return result;
+
+  /* ---- non-cryptographic version following ---- */
+
+#ifdef RANDOM_FILE
+  if(!seeded) {
+    /* if there's a random file to read a seed from, use it */
+    int fd = open(RANDOM_FILE, O_RDONLY);
+    if(fd > -1) {
+      /* read random data into the randseed variable */
+      ssize_t nread = read(fd, &randseed, sizeof(randseed));
+      if(nread == sizeof(randseed))
+        seeded = TRUE;
+      close(fd);
+    }
+  }
+#endif
+
+  if(!seeded) {
+    struct curltime now = Curl_now();
+    infof(data, "WARNING: Using weak random seed\n");
+    randseed += (unsigned int)now.tv_usec + (unsigned int)now.tv_sec;
+    randseed = randseed * 1103515245 + 12345;
+    randseed = randseed * 1103515245 + 12345;
+    randseed = randseed * 1103515245 + 12345;
+    seeded = TRUE;
+  }
+
+  /* Return an unsigned 32-bit pseudo-random number. */
+  r = randseed = randseed * 1103515245 + 12345;
+  *rnd = (r << 16) | ((r >> 16) & 0xFFFF);
+  return CURLE_OK;
+}
+
+/*
+ * Curl_rand() stores 'num' number of random unsigned integers in the buffer
+ * 'rndptr' points to.
+ *
+ * If libcurl is built without TLS support or with a TLS backend that lacks a
+ * proper random API (Gskit, PolarSSL or mbedTLS), this function will use
+ * "weak" random.
+ *
+ * When built *with* TLS support and a backend that offers strong random, it
+ * will return error if it cannot provide strong random values.
+ *
+ * NOTE: 'data' may be passed in as NULL when coming from external API without
+ * easy handle!
+ *
+ */
+
+CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num)
+{
+  CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT;
+
+  DEBUGASSERT(num > 0);
+
+  while(num) {
+    unsigned int r;
+    size_t left = num < sizeof(unsigned int) ? num : sizeof(unsigned int);
+
+    result = randit(data, &r);
+    if(result)
+      return result;
+
+    while(left) {
+      *rnd++ = (unsigned char)(r & 0xFF);
+      r >>= 8;
+      --num;
+      --left;
+    }
+  }
+
+  return result;
+}
+
+/*
+ * Curl_rand_hex() fills the 'rnd' buffer with a given 'num' size with random
+ * hexadecimal digits PLUS a zero terminating byte. It must be an odd number
+ * size.
+ */
+
+CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd,
+                       size_t num)
+{
+  CURLcode result = CURLE_BAD_FUNCTION_ARGUMENT;
+  const char *hex = "0123456789abcdef";
+  unsigned char buffer[128];
+  unsigned char *bufp = buffer;
+  DEBUGASSERT(num > 1);
+
+  if((num/2 >= sizeof(buffer)) || !(num&1))
+    /* make sure it fits in the local buffer and that it is an odd number! */
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  num--; /* save one for zero termination */
+
+  result = Curl_rand(data, buffer, num/2);
+  if(result)
+    return result;
+
+  while(num) {
+    *rnd++ = hex[(*bufp & 0xF0)>>4];
+    *rnd++ = hex[*bufp & 0x0F];
+    bufp++;
+    num -= 2;
+  }
+  *rnd = 0;
+
+  return result;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/rand.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/rand.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/rand.h	(revision 331)
@@ -0,0 +1,47 @@
+#ifndef HEADER_CURL_RAND_H
+#define HEADER_CURL_RAND_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Curl_rand() stores 'num' number of random unsigned characters in the buffer
+ * 'rnd' points to.
+ *
+ * If libcurl is built without TLS support or with a TLS backend that lacks a
+ * proper random API (Gskit, PolarSSL or mbedTLS), this function will use
+ * "weak" random.
+ *
+ * When built *with* TLS support and a backend that offers strong random, it
+ * will return error if it cannot provide strong random values.
+ *
+ * NOTE: 'data' may be passed in as NULL when coming from external API without
+ * easy handle!
+ *
+ */
+CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num);
+
+/* Same as above but outputs only random lowercase hex characters.
+   Does NOT terminate.*/
+CURLcode Curl_rand_hex(struct Curl_easy *data, unsigned char *rnd,
+                       size_t num);
+
+#endif /* HEADER_CURL_RAND_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/rtsp.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/rtsp.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/rtsp.c	(revision 331)
@@ -0,0 +1,850 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_RTSP
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "sendf.h"
+#include "multiif.h"
+#include "http.h"
+#include "url.h"
+#include "progress.h"
+#include "rtsp.h"
+#include "strcase.h"
+#include "select.h"
+#include "connect.h"
+#include "strdup.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * TODO (general)
+ *  -incoming server requests
+ *      -server CSeq counter
+ *  -digest authentication
+ *  -connect thru proxy
+ *  -pipelining?
+ */
+
+
+#define RTP_PKT_CHANNEL(p)   ((int)((unsigned char)((p)[1])))
+
+#define RTP_PKT_LENGTH(p)  ((((int)((unsigned char)((p)[2]))) << 8) | \
+                             ((int)((unsigned char)((p)[3]))))
+
+/* protocol-specific functions set up to be called by the main engine */
+static CURLcode rtsp_do(struct connectdata *conn, bool *done);
+static CURLcode rtsp_done(struct connectdata *conn, CURLcode, bool premature);
+static CURLcode rtsp_connect(struct connectdata *conn, bool *done);
+static CURLcode rtsp_disconnect(struct connectdata *conn, bool dead);
+
+static int rtsp_getsock_do(struct connectdata *conn,
+                           curl_socket_t *socks,
+                           int numsocks);
+
+/*
+ * Parse and write out any available RTP data.
+ *
+ * nread: amount of data left after k->str. will be modified if RTP
+ *        data is parsed and k->str is moved up
+ * readmore: whether or not the RTP parser needs more data right away
+ */
+static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
+                                   struct connectdata *conn,
+                                   ssize_t *nread,
+                                   bool *readmore);
+
+static CURLcode rtsp_setup_connection(struct connectdata *conn);
+
+bool rtsp_connisdead(struct connectdata *check);
+static unsigned int rtsp_conncheck(struct connectdata *check,
+                                   unsigned int checks_to_perform);
+
+/* this returns the socket to wait for in the DO and DOING state for the multi
+   interface and then we're always _sending_ a request and thus we wait for
+   the single socket to become writable only */
+static int rtsp_getsock_do(struct connectdata *conn,
+                           curl_socket_t *socks,
+                           int numsocks)
+{
+  /* write mode */
+  (void)numsocks; /* unused, we trust it to be at least 1 */
+  socks[0] = conn->sock[FIRSTSOCKET];
+  return GETSOCK_WRITESOCK(0);
+}
+
+static
+CURLcode rtp_client_write(struct connectdata *conn, char *ptr, size_t len);
+
+
+/*
+ * RTSP handler interface.
+ */
+const struct Curl_handler Curl_handler_rtsp = {
+  "RTSP",                               /* scheme */
+  rtsp_setup_connection,                /* setup_connection */
+  rtsp_do,                              /* do_it */
+  rtsp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  rtsp_connect,                         /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  rtsp_getsock_do,                      /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  rtsp_disconnect,                      /* disconnect */
+  rtsp_rtp_readwrite,                   /* readwrite */
+  rtsp_conncheck,                       /* connection_check */
+  PORT_RTSP,                            /* defport */
+  CURLPROTO_RTSP,                       /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+
+
+static CURLcode rtsp_setup_connection(struct connectdata *conn)
+{
+  struct RTSP *rtsp;
+
+  conn->data->req.protop = rtsp = calloc(1, sizeof(struct RTSP));
+  if(!rtsp)
+    return CURLE_OUT_OF_MEMORY;
+
+  return CURLE_OK;
+}
+
+
+/*
+ * The server may send us RTP data at any point, and RTSPREQ_RECEIVE does not
+ * want to block the application forever while receiving a stream. Therefore,
+ * we cannot assume that an RTSP socket is dead just because it is readable.
+ *
+ * Instead, if it is readable, run Curl_connalive() to peek at the socket
+ * and distinguish between closed and data.
+ */
+bool rtsp_connisdead(struct connectdata *check)
+{
+  int sval;
+  bool ret_val = TRUE;
+
+  sval = SOCKET_READABLE(check->sock[FIRSTSOCKET], 0);
+  if(sval == 0) {
+    /* timeout */
+    ret_val = FALSE;
+  }
+  else if(sval & CURL_CSELECT_ERR) {
+    /* socket is in an error state */
+    ret_val = TRUE;
+  }
+  else if(sval & CURL_CSELECT_IN) {
+    /* readable with no error. could still be closed */
+    ret_val = !Curl_connalive(check);
+  }
+
+  return ret_val;
+}
+
+/*
+ * Function to check on various aspects of a connection.
+ */
+static unsigned int rtsp_conncheck(struct connectdata *check,
+                                   unsigned int checks_to_perform)
+{
+  unsigned int ret_val = CONNRESULT_NONE;
+
+  if(checks_to_perform & CONNCHECK_ISDEAD) {
+    if(rtsp_connisdead(check))
+      ret_val |= CONNRESULT_DEAD;
+  }
+
+  return ret_val;
+}
+
+
+static CURLcode rtsp_connect(struct connectdata *conn, bool *done)
+{
+  CURLcode httpStatus;
+  struct Curl_easy *data = conn->data;
+
+  httpStatus = Curl_http_connect(conn, done);
+
+  /* Initialize the CSeq if not already done */
+  if(data->state.rtsp_next_client_CSeq == 0)
+    data->state.rtsp_next_client_CSeq = 1;
+  if(data->state.rtsp_next_server_CSeq == 0)
+    data->state.rtsp_next_server_CSeq = 1;
+
+  conn->proto.rtspc.rtp_channel = -1;
+
+  return httpStatus;
+}
+
+static CURLcode rtsp_disconnect(struct connectdata *conn, bool dead)
+{
+  (void) dead;
+  Curl_safefree(conn->proto.rtspc.rtp_buf);
+  return CURLE_OK;
+}
+
+
+static CURLcode rtsp_done(struct connectdata *conn,
+                          CURLcode status, bool premature)
+{
+  struct Curl_easy *data = conn->data;
+  struct RTSP *rtsp = data->req.protop;
+  CURLcode httpStatus;
+  long CSeq_sent;
+  long CSeq_recv;
+
+  /* Bypass HTTP empty-reply checks on receive */
+  if(data->set.rtspreq == RTSPREQ_RECEIVE)
+    premature = TRUE;
+
+  httpStatus = Curl_http_done(conn, status, premature);
+
+  if(rtsp) {
+    /* Check the sequence numbers */
+    CSeq_sent = rtsp->CSeq_sent;
+    CSeq_recv = rtsp->CSeq_recv;
+    if((data->set.rtspreq != RTSPREQ_RECEIVE) && (CSeq_sent != CSeq_recv)) {
+      failf(data,
+            "The CSeq of this request %ld did not match the response %ld",
+            CSeq_sent, CSeq_recv);
+      return CURLE_RTSP_CSEQ_ERROR;
+    }
+    if(data->set.rtspreq == RTSPREQ_RECEIVE &&
+            (conn->proto.rtspc.rtp_channel == -1)) {
+      infof(data, "Got an RTP Receive with a CSeq of %ld\n", CSeq_recv);
+      /* TODO CPC: Server -> Client logic here */
+    }
+  }
+
+  return httpStatus;
+}
+
+static CURLcode rtsp_do(struct connectdata *conn, bool *done)
+{
+  struct Curl_easy *data = conn->data;
+  CURLcode result = CURLE_OK;
+  Curl_RtspReq rtspreq = data->set.rtspreq;
+  struct RTSP *rtsp = data->req.protop;
+  struct HTTP *http;
+  Curl_send_buffer *req_buffer;
+  curl_off_t postsize = 0; /* for ANNOUNCE and SET_PARAMETER */
+  curl_off_t putsize = 0; /* for ANNOUNCE and SET_PARAMETER */
+
+  const char *p_request = NULL;
+  const char *p_session_id = NULL;
+  const char *p_accept = NULL;
+  const char *p_accept_encoding = NULL;
+  const char *p_range = NULL;
+  const char *p_referrer = NULL;
+  const char *p_stream_uri = NULL;
+  const char *p_transport = NULL;
+  const char *p_uagent = NULL;
+  const char *p_proxyuserpwd = NULL;
+  const char *p_userpwd = NULL;
+
+  *done = TRUE;
+
+  http = &(rtsp->http_wrapper);
+  /* Assert that no one has changed the RTSP struct in an evil way */
+  DEBUGASSERT((void *)http == (void *)rtsp);
+
+  rtsp->CSeq_sent = data->state.rtsp_next_client_CSeq;
+  rtsp->CSeq_recv = 0;
+
+  /* Setup the 'p_request' pointer to the proper p_request string
+   * Since all RTSP requests are included here, there is no need to
+   * support custom requests like HTTP.
+   **/
+  data->set.opt_no_body = TRUE; /* most requests don't contain a body */
+  switch(rtspreq) {
+  default:
+    failf(data, "Got invalid RTSP request");
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+  case RTSPREQ_OPTIONS:
+    p_request = "OPTIONS";
+    break;
+  case RTSPREQ_DESCRIBE:
+    p_request = "DESCRIBE";
+    data->set.opt_no_body = FALSE;
+    break;
+  case RTSPREQ_ANNOUNCE:
+    p_request = "ANNOUNCE";
+    break;
+  case RTSPREQ_SETUP:
+    p_request = "SETUP";
+    break;
+  case RTSPREQ_PLAY:
+    p_request = "PLAY";
+    break;
+  case RTSPREQ_PAUSE:
+    p_request = "PAUSE";
+    break;
+  case RTSPREQ_TEARDOWN:
+    p_request = "TEARDOWN";
+    break;
+  case RTSPREQ_GET_PARAMETER:
+    /* GET_PARAMETER's no_body status is determined later */
+    p_request = "GET_PARAMETER";
+    data->set.opt_no_body = FALSE;
+    break;
+  case RTSPREQ_SET_PARAMETER:
+    p_request = "SET_PARAMETER";
+    break;
+  case RTSPREQ_RECORD:
+    p_request = "RECORD";
+    break;
+  case RTSPREQ_RECEIVE:
+    p_request = "";
+    /* Treat interleaved RTP as body*/
+    data->set.opt_no_body = FALSE;
+    break;
+  case RTSPREQ_LAST:
+    failf(data, "Got invalid RTSP request: RTSPREQ_LAST");
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+  }
+
+  if(rtspreq == RTSPREQ_RECEIVE) {
+    Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
+                        &http->readbytecount, -1, NULL);
+
+    return result;
+  }
+
+  p_session_id = data->set.str[STRING_RTSP_SESSION_ID];
+  if(!p_session_id &&
+     (rtspreq & ~(RTSPREQ_OPTIONS | RTSPREQ_DESCRIBE | RTSPREQ_SETUP))) {
+    failf(data, "Refusing to issue an RTSP request [%s] without a session ID.",
+          p_request);
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+  }
+
+  /* TODO: proxy? */
+
+  /* Stream URI. Default to server '*' if not specified */
+  if(data->set.str[STRING_RTSP_STREAM_URI]) {
+    p_stream_uri = data->set.str[STRING_RTSP_STREAM_URI];
+  }
+  else {
+    p_stream_uri = "*";
+  }
+
+  /* Transport Header for SETUP requests */
+  p_transport = Curl_checkheaders(conn, "Transport:");
+  if(rtspreq == RTSPREQ_SETUP && !p_transport) {
+    /* New Transport: setting? */
+    if(data->set.str[STRING_RTSP_TRANSPORT]) {
+      Curl_safefree(conn->allocptr.rtsp_transport);
+
+      conn->allocptr.rtsp_transport =
+        aprintf("Transport: %s\r\n",
+                data->set.str[STRING_RTSP_TRANSPORT]);
+      if(!conn->allocptr.rtsp_transport)
+        return CURLE_OUT_OF_MEMORY;
+    }
+    else {
+      failf(data,
+            "Refusing to issue an RTSP SETUP without a Transport: header.");
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    }
+
+    p_transport = conn->allocptr.rtsp_transport;
+  }
+
+  /* Accept Headers for DESCRIBE requests */
+  if(rtspreq == RTSPREQ_DESCRIBE) {
+    /* Accept Header */
+    p_accept = Curl_checkheaders(conn, "Accept:")?
+      NULL:"Accept: application/sdp\r\n";
+
+    /* Accept-Encoding header */
+    if(!Curl_checkheaders(conn, "Accept-Encoding:") &&
+       data->set.str[STRING_ENCODING]) {
+      Curl_safefree(conn->allocptr.accept_encoding);
+      conn->allocptr.accept_encoding =
+        aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
+
+      if(!conn->allocptr.accept_encoding)
+        return CURLE_OUT_OF_MEMORY;
+
+      p_accept_encoding = conn->allocptr.accept_encoding;
+    }
+  }
+
+  /* The User-Agent string might have been allocated in url.c already, because
+     it might have been used in the proxy connect, but if we have got a header
+     with the user-agent string specified, we erase the previously made string
+     here. */
+  if(Curl_checkheaders(conn, "User-Agent:") && conn->allocptr.uagent) {
+    Curl_safefree(conn->allocptr.uagent);
+    conn->allocptr.uagent = NULL;
+  }
+  else if(!Curl_checkheaders(conn, "User-Agent:") &&
+          data->set.str[STRING_USERAGENT]) {
+    p_uagent = conn->allocptr.uagent;
+  }
+
+  /* setup the authentication headers */
+  result = Curl_http_output_auth(conn, p_request, p_stream_uri, FALSE);
+  if(result)
+    return result;
+
+  p_proxyuserpwd = conn->allocptr.proxyuserpwd;
+  p_userpwd = conn->allocptr.userpwd;
+
+  /* Referrer */
+  Curl_safefree(conn->allocptr.ref);
+  if(data->change.referer && !Curl_checkheaders(conn, "Referer:"))
+    conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
+  else
+    conn->allocptr.ref = NULL;
+
+  p_referrer = conn->allocptr.ref;
+
+  /*
+   * Range Header
+   * Only applies to PLAY, PAUSE, RECORD
+   *
+   * Go ahead and use the Range stuff supplied for HTTP
+   */
+  if(data->state.use_range &&
+     (rtspreq  & (RTSPREQ_PLAY | RTSPREQ_PAUSE | RTSPREQ_RECORD))) {
+
+    /* Check to see if there is a range set in the custom headers */
+    if(!Curl_checkheaders(conn, "Range:") && data->state.range) {
+      Curl_safefree(conn->allocptr.rangeline);
+      conn->allocptr.rangeline = aprintf("Range: %s\r\n", data->state.range);
+      p_range = conn->allocptr.rangeline;
+    }
+  }
+
+  /*
+   * Sanity check the custom headers
+   */
+  if(Curl_checkheaders(conn, "CSeq:")) {
+    failf(data, "CSeq cannot be set as a custom header.");
+    return CURLE_RTSP_CSEQ_ERROR;
+  }
+  if(Curl_checkheaders(conn, "Session:")) {
+    failf(data, "Session ID cannot be set as a custom header.");
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+  }
+
+  /* Initialize a dynamic send buffer */
+  req_buffer = Curl_add_buffer_init();
+
+  if(!req_buffer)
+    return CURLE_OUT_OF_MEMORY;
+
+  result =
+    Curl_add_bufferf(req_buffer,
+                     "%s %s RTSP/1.0\r\n" /* Request Stream-URI RTSP/1.0 */
+                     "CSeq: %ld\r\n", /* CSeq */
+                     p_request, p_stream_uri, rtsp->CSeq_sent);
+  if(result)
+    return result;
+
+  /*
+   * Rather than do a normal alloc line, keep the session_id unformatted
+   * to make comparison easier
+   */
+  if(p_session_id) {
+    result = Curl_add_bufferf(req_buffer, "Session: %s\r\n", p_session_id);
+    if(result)
+      return result;
+  }
+
+  /*
+   * Shared HTTP-like options
+   */
+  result = Curl_add_bufferf(req_buffer,
+                            "%s" /* transport */
+                            "%s" /* accept */
+                            "%s" /* accept-encoding */
+                            "%s" /* range */
+                            "%s" /* referrer */
+                            "%s" /* user-agent */
+                            "%s" /* proxyuserpwd */
+                            "%s" /* userpwd */
+                            ,
+                            p_transport ? p_transport : "",
+                            p_accept ? p_accept : "",
+                            p_accept_encoding ? p_accept_encoding : "",
+                            p_range ? p_range : "",
+                            p_referrer ? p_referrer : "",
+                            p_uagent ? p_uagent : "",
+                            p_proxyuserpwd ? p_proxyuserpwd : "",
+                            p_userpwd ? p_userpwd : "");
+
+  /*
+   * Free userpwd now --- cannot reuse this for Negotiate and possibly NTLM
+   * with basic and digest, it will be freed anyway by the next request
+   */
+  Curl_safefree(conn->allocptr.userpwd);
+  conn->allocptr.userpwd = NULL;
+
+  if(result)
+    return result;
+
+  if((rtspreq == RTSPREQ_SETUP) || (rtspreq == RTSPREQ_DESCRIBE)) {
+    result = Curl_add_timecondition(data, req_buffer);
+    if(result)
+      return result;
+  }
+
+  result = Curl_add_custom_headers(conn, FALSE, req_buffer);
+  if(result)
+    return result;
+
+  if(rtspreq == RTSPREQ_ANNOUNCE ||
+     rtspreq == RTSPREQ_SET_PARAMETER ||
+     rtspreq == RTSPREQ_GET_PARAMETER) {
+
+    if(data->set.upload) {
+      putsize = data->state.infilesize;
+      data->set.httpreq = HTTPREQ_PUT;
+
+    }
+    else {
+      postsize = (data->state.infilesize != -1)?
+        data->state.infilesize:
+        (data->set.postfields? (curl_off_t)strlen(data->set.postfields):0);
+      data->set.httpreq = HTTPREQ_POST;
+    }
+
+    if(putsize > 0 || postsize > 0) {
+      /* As stated in the http comments, it is probably not wise to
+       * actually set a custom Content-Length in the headers */
+      if(!Curl_checkheaders(conn, "Content-Length:")) {
+        result = Curl_add_bufferf(req_buffer,
+            "Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n",
+            (data->set.upload ? putsize : postsize));
+        if(result)
+          return result;
+      }
+
+      if(rtspreq == RTSPREQ_SET_PARAMETER ||
+         rtspreq == RTSPREQ_GET_PARAMETER) {
+        if(!Curl_checkheaders(conn, "Content-Type:")) {
+          result = Curl_add_bufferf(req_buffer,
+              "Content-Type: text/parameters\r\n");
+          if(result)
+            return result;
+        }
+      }
+
+      if(rtspreq == RTSPREQ_ANNOUNCE) {
+        if(!Curl_checkheaders(conn, "Content-Type:")) {
+          result = Curl_add_bufferf(req_buffer,
+              "Content-Type: application/sdp\r\n");
+          if(result)
+            return result;
+        }
+      }
+
+      data->state.expect100header = FALSE; /* RTSP posts are simple/small */
+    }
+    else if(rtspreq == RTSPREQ_GET_PARAMETER) {
+      /* Check for an empty GET_PARAMETER (heartbeat) request */
+      data->set.httpreq = HTTPREQ_HEAD;
+      data->set.opt_no_body = TRUE;
+    }
+  }
+
+  /* RTSP never allows chunked transfer */
+  data->req.forbidchunk = TRUE;
+  /* Finish the request buffer */
+  result = Curl_add_buffer(req_buffer, "\r\n", 2);
+  if(result)
+    return result;
+
+  if(postsize > 0) {
+    result = Curl_add_buffer(req_buffer, data->set.postfields,
+                             (size_t)postsize);
+    if(result)
+      return result;
+  }
+
+  /* issue the request */
+  result = Curl_add_buffer_send(req_buffer, conn,
+                                &data->info.request_size, 0, FIRSTSOCKET);
+  if(result) {
+    failf(data, "Failed sending RTSP request");
+    return result;
+  }
+
+  Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
+                      putsize?FIRSTSOCKET:-1,
+                      putsize?&http->writebytecount:NULL);
+
+  /* Increment the CSeq on success */
+  data->state.rtsp_next_client_CSeq++;
+
+  if(http->writebytecount) {
+    /* if a request-body has been sent off, we make sure this progress is
+       noted properly */
+    Curl_pgrsSetUploadCounter(data, http->writebytecount);
+    if(Curl_pgrsUpdate(conn))
+      result = CURLE_ABORTED_BY_CALLBACK;
+  }
+
+  return result;
+}
+
+
+static CURLcode rtsp_rtp_readwrite(struct Curl_easy *data,
+                                   struct connectdata *conn,
+                                   ssize_t *nread,
+                                   bool *readmore) {
+  struct SingleRequest *k = &data->req;
+  struct rtsp_conn *rtspc = &(conn->proto.rtspc);
+
+  char *rtp; /* moving pointer to rtp data */
+  ssize_t rtp_dataleft; /* how much data left to parse in this round */
+  char *scratch;
+  CURLcode result;
+
+  if(rtspc->rtp_buf) {
+    /* There was some leftover data the last time. Merge buffers */
+    char *newptr = Curl_saferealloc(rtspc->rtp_buf,
+                                    rtspc->rtp_bufsize + *nread);
+    if(!newptr) {
+      rtspc->rtp_buf = NULL;
+      rtspc->rtp_bufsize = 0;
+      return CURLE_OUT_OF_MEMORY;
+    }
+    rtspc->rtp_buf = newptr;
+    memcpy(rtspc->rtp_buf + rtspc->rtp_bufsize, k->str, *nread);
+    rtspc->rtp_bufsize += *nread;
+    rtp = rtspc->rtp_buf;
+    rtp_dataleft = rtspc->rtp_bufsize;
+  }
+  else {
+    /* Just parse the request buffer directly */
+    rtp = k->str;
+    rtp_dataleft = *nread;
+  }
+
+  while((rtp_dataleft > 0) &&
+        (rtp[0] == '$')) {
+    if(rtp_dataleft > 4) {
+      int rtp_length;
+
+      /* Parse the header */
+      /* The channel identifier immediately follows and is 1 byte */
+      rtspc->rtp_channel = RTP_PKT_CHANNEL(rtp);
+
+      /* The length is two bytes */
+      rtp_length = RTP_PKT_LENGTH(rtp);
+
+      if(rtp_dataleft < rtp_length + 4) {
+        /* Need more - incomplete payload*/
+        *readmore = TRUE;
+        break;
+      }
+      /* We have the full RTP interleaved packet
+       * Write out the header including the leading '$' */
+      DEBUGF(infof(data, "RTP write channel %d rtp_length %d\n",
+             rtspc->rtp_channel, rtp_length));
+      result = rtp_client_write(conn, &rtp[0], rtp_length + 4);
+      if(result) {
+        failf(data, "Got an error writing an RTP packet");
+        *readmore = FALSE;
+        Curl_safefree(rtspc->rtp_buf);
+        rtspc->rtp_buf = NULL;
+        rtspc->rtp_bufsize = 0;
+        return result;
+      }
+
+      /* Move forward in the buffer */
+      rtp_dataleft -= rtp_length + 4;
+      rtp += rtp_length + 4;
+
+      if(data->set.rtspreq == RTSPREQ_RECEIVE) {
+        /* If we are in a passive receive, give control back
+         * to the app as often as we can.
+         */
+        k->keepon &= ~KEEP_RECV;
+      }
+    }
+    else {
+      /* Need more - incomplete header */
+      *readmore = TRUE;
+      break;
+    }
+  }
+
+  if(rtp_dataleft != 0 && rtp[0] == '$') {
+    DEBUGF(infof(data, "RTP Rewinding %zd %s\n", rtp_dataleft,
+          *readmore ? "(READMORE)" : ""));
+
+    /* Store the incomplete RTP packet for a "rewind" */
+    scratch = malloc(rtp_dataleft);
+    if(!scratch) {
+      Curl_safefree(rtspc->rtp_buf);
+      rtspc->rtp_buf = NULL;
+      rtspc->rtp_bufsize = 0;
+      return CURLE_OUT_OF_MEMORY;
+    }
+    memcpy(scratch, rtp, rtp_dataleft);
+    Curl_safefree(rtspc->rtp_buf);
+    rtspc->rtp_buf = scratch;
+    rtspc->rtp_bufsize = rtp_dataleft;
+
+    /* As far as the transfer is concerned, this data is consumed */
+    *nread = 0;
+    return CURLE_OK;
+  }
+  /* Fix up k->str to point just after the last RTP packet */
+  k->str += *nread - rtp_dataleft;
+
+  /* either all of the data has been read or...
+   * rtp now points at the next byte to parse
+   */
+  if(rtp_dataleft > 0)
+    DEBUGASSERT(k->str[0] == rtp[0]);
+
+  DEBUGASSERT(rtp_dataleft <= *nread); /* sanity check */
+
+  *nread = rtp_dataleft;
+
+  /* If we get here, we have finished with the leftover/merge buffer */
+  Curl_safefree(rtspc->rtp_buf);
+  rtspc->rtp_buf = NULL;
+  rtspc->rtp_bufsize = 0;
+
+  return CURLE_OK;
+}
+
+static
+CURLcode rtp_client_write(struct connectdata *conn, char *ptr, size_t len)
+{
+  struct Curl_easy *data = conn->data;
+  size_t wrote;
+  curl_write_callback writeit;
+  void *user_ptr;
+
+  if(len == 0) {
+    failf(data, "Cannot write a 0 size RTP packet.");
+    return CURLE_WRITE_ERROR;
+  }
+
+  /* If the user has configured CURLOPT_INTERLEAVEFUNCTION then use that
+     function and any configured CURLOPT_INTERLEAVEDATA to write out the RTP
+     data. Otherwise, use the CURLOPT_WRITEFUNCTION with the CURLOPT_WRITEDATA
+     pointer to write out the RTP data. */
+  if(data->set.fwrite_rtp) {
+    writeit = data->set.fwrite_rtp;
+    user_ptr = data->set.rtp_out;
+  }
+  else
+  {
+    writeit = data->set.fwrite_func;
+    user_ptr = data->set.out;
+  }
+
+  wrote = writeit(ptr, 1, len, user_ptr);
+
+  if(CURL_WRITEFUNC_PAUSE == wrote) {
+    failf(data, "Cannot pause RTP");
+    return CURLE_WRITE_ERROR;
+  }
+
+  if(wrote != len) {
+    failf(data, "Failed writing RTP data");
+    return CURLE_WRITE_ERROR;
+  }
+
+  return CURLE_OK;
+}
+
+CURLcode Curl_rtsp_parseheader(struct connectdata *conn,
+                               char *header)
+{
+  struct Curl_easy *data = conn->data;
+  long CSeq = 0;
+
+  if(checkprefix("CSeq:", header)) {
+    /* Store the received CSeq. Match is verified in rtsp_done */
+    int nc = sscanf(&header[4], ": %ld", &CSeq);
+    if(nc == 1) {
+      struct RTSP *rtsp = data->req.protop;
+      rtsp->CSeq_recv = CSeq; /* mark the request */
+      data->state.rtsp_CSeq_recv = CSeq; /* update the handle */
+    }
+    else {
+      failf(data, "Unable to read the CSeq header: [%s]", header);
+      return CURLE_RTSP_CSEQ_ERROR;
+    }
+  }
+  else if(checkprefix("Session:", header)) {
+    char *start;
+
+    /* Find the first non-space letter */
+    start = header + 8;
+    while(*start && ISSPACE(*start))
+      start++;
+
+    if(!*start) {
+      failf(data, "Got a blank Session ID");
+    }
+    else if(data->set.str[STRING_RTSP_SESSION_ID]) {
+      /* If the Session ID is set, then compare */
+      if(strncmp(start, data->set.str[STRING_RTSP_SESSION_ID],
+                 strlen(data->set.str[STRING_RTSP_SESSION_ID]))  != 0) {
+        failf(data, "Got RTSP Session ID Line [%s], but wanted ID [%s]",
+              start, data->set.str[STRING_RTSP_SESSION_ID]);
+        return CURLE_RTSP_SESSION_ERROR;
+      }
+    }
+    else {
+      /* If the Session ID is not set, and we find it in a response, then set
+       * it.
+       *
+       * Allow any non whitespace content, up to the field separator or end of
+       * line. RFC 2326 isn't 100% clear on the session ID and for example
+       * gstreamer does url-encoded session ID's not covered by the standard.
+       */
+      char *end = start;
+      while(*end && *end != ';' && !ISSPACE(*end))
+        end++;
+
+      /* Copy the id substring into a new buffer */
+      data->set.str[STRING_RTSP_SESSION_ID] = malloc(end - start + 1);
+      if(data->set.str[STRING_RTSP_SESSION_ID] == NULL)
+        return CURLE_OUT_OF_MEMORY;
+      memcpy(data->set.str[STRING_RTSP_SESSION_ID], start, end - start);
+      (data->set.str[STRING_RTSP_SESSION_ID])[end - start] = '\0';
+    }
+  }
+  return CURLE_OK;
+}
+
+#endif /* CURL_DISABLE_RTSP */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/rtsp.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/rtsp.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/rtsp.h	(revision 331)
@@ -0,0 +1,67 @@
+#ifndef HEADER_CURL_RTSP_H
+#define HEADER_CURL_RTSP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifndef CURL_DISABLE_RTSP
+
+extern const struct Curl_handler Curl_handler_rtsp;
+
+CURLcode Curl_rtsp_parseheader(struct connectdata *conn, char *header);
+
+#else
+/* disabled */
+#define Curl_rtsp_parseheader(x,y) CURLE_NOT_BUILT_IN
+
+#endif /* CURL_DISABLE_RTSP */
+
+/*
+ * RTSP Connection data
+ *
+ * Currently, only used for tracking incomplete RTP data reads
+ */
+struct rtsp_conn {
+  char *rtp_buf;
+  ssize_t rtp_bufsize;
+  int rtp_channel;
+};
+
+/****************************************************************************
+ * RTSP unique setup
+ ***************************************************************************/
+struct RTSP {
+  /*
+   * http_wrapper MUST be the first element of this structure for the wrap
+   * logic to work. In this way, we get a cheap polymorphism because
+   * &(data->state.proto.rtsp) == &(data->state.proto.http) per the C spec
+   *
+   * HTTP functions can safely treat this as an HTTP struct, but RTSP aware
+   * functions can also index into the later elements.
+   */
+  struct HTTP http_wrapper; /*wrap HTTP to do the heavy lifting */
+
+  long CSeq_sent; /* CSeq of this request */
+  long CSeq_recv; /* CSeq received */
+};
+
+
+#endif /* HEADER_CURL_RTSP_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/security.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/security.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/security.c	(revision 331)
@@ -0,0 +1,588 @@
+/* This source code was modified by Martin Hedenfalk <mhe@stacken.kth.se> for
+ * use in Curl. His latest changes were done 2000-09-18.
+ *
+ * It has since been patched and modified a lot by Daniel Stenberg
+ * <daniel@haxx.se> to make it better applied to curl conditions, and to make
+ * it not use globals, pollute name space and more. This source code awaits a
+ * rewrite to work around the paragraph 2 in the BSD licenses as explained
+ * below.
+ *
+ * Copyright (c) 1998, 1999, 2017 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ *
+ * Copyright (C) 2001 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.  */
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_FTP
+#ifdef HAVE_GSSAPI
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include "urldata.h"
+#include "curl_base64.h"
+#include "curl_memory.h"
+#include "curl_sec.h"
+#include "ftp.h"
+#include "sendf.h"
+#include "strcase.h"
+#include "warnless.h"
+#include "strdup.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+static const struct {
+  enum protection_level level;
+  const char *name;
+} level_names[] = {
+  { PROT_CLEAR, "clear" },
+  { PROT_SAFE, "safe" },
+  { PROT_CONFIDENTIAL, "confidential" },
+  { PROT_PRIVATE, "private" }
+};
+
+static enum protection_level
+name_to_level(const char *name)
+{
+  int i;
+  for(i = 0; i < (int)sizeof(level_names)/(int)sizeof(level_names[0]); i++)
+    if(checkprefix(name, level_names[i].name))
+      return level_names[i].level;
+  return PROT_NONE;
+}
+
+/* Convert a protocol |level| to its char representation.
+   We take an int to catch programming mistakes. */
+static char level_to_char(int level)
+{
+  switch(level) {
+  case PROT_CLEAR:
+    return 'C';
+  case PROT_SAFE:
+    return 'S';
+  case PROT_CONFIDENTIAL:
+    return 'E';
+  case PROT_PRIVATE:
+    return 'P';
+  case PROT_CMD:
+    /* Fall through */
+  default:
+    /* Those 2 cases should not be reached! */
+    break;
+  }
+  DEBUGASSERT(0);
+  /* Default to the most secure alternative. */
+  return 'P';
+}
+
+/* Send an FTP command defined by |message| and the optional arguments. The
+   function returns the ftp_code. If an error occurs, -1 is returned. */
+static int ftp_send_command(struct connectdata *conn, const char *message, ...)
+{
+  int ftp_code;
+  ssize_t nread = 0;
+  va_list args;
+  char print_buffer[50];
+
+  va_start(args, message);
+  vsnprintf(print_buffer, sizeof(print_buffer), message, args);
+  va_end(args);
+
+  if(Curl_ftpsend(conn, print_buffer)) {
+    ftp_code = -1;
+  }
+  else {
+    if(Curl_GetFTPResponse(&nread, conn, &ftp_code))
+      ftp_code = -1;
+  }
+
+  (void)nread; /* Unused */
+  return ftp_code;
+}
+
+/* Read |len| from the socket |fd| and store it in |to|. Return a CURLcode
+   saying whether an error occurred or CURLE_OK if |len| was read. */
+static CURLcode
+socket_read(curl_socket_t fd, void *to, size_t len)
+{
+  char *to_p = to;
+  CURLcode result;
+  ssize_t nread;
+
+  while(len > 0) {
+    result = Curl_read_plain(fd, to_p, len, &nread);
+    if(!result) {
+      len -= nread;
+      to_p += nread;
+    }
+    else {
+      /* FIXME: We are doing a busy wait */
+      if(result == CURLE_AGAIN)
+        continue;
+      return result;
+    }
+  }
+  return CURLE_OK;
+}
+
+
+/* Write |len| bytes from the buffer |to| to the socket |fd|. Return a
+   CURLcode saying whether an error occurred or CURLE_OK if |len| was
+   written. */
+static CURLcode
+socket_write(struct connectdata *conn, curl_socket_t fd, const void *to,
+             size_t len)
+{
+  const char *to_p = to;
+  CURLcode result;
+  ssize_t written;
+
+  while(len > 0) {
+    result = Curl_write_plain(conn, fd, to_p, len, &written);
+    if(!result) {
+      len -= written;
+      to_p += written;
+    }
+    else {
+      /* FIXME: We are doing a busy wait */
+      if(result == CURLE_AGAIN)
+        continue;
+      return result;
+    }
+  }
+  return CURLE_OK;
+}
+
+static CURLcode read_data(struct connectdata *conn,
+                          curl_socket_t fd,
+                          struct krb5buffer *buf)
+{
+  int len;
+  void *tmp = NULL;
+  CURLcode result;
+
+  result = socket_read(fd, &len, sizeof(len));
+  if(result)
+    return result;
+
+  if(len) {
+    /* only realloc if there was a length */
+    len = ntohl(len);
+    tmp = Curl_saferealloc(buf->data, len);
+  }
+  if(tmp == NULL)
+    return CURLE_OUT_OF_MEMORY;
+
+  buf->data = tmp;
+  result = socket_read(fd, buf->data, len);
+  if(result)
+    return result;
+  buf->size = conn->mech->decode(conn->app_data, buf->data, len,
+                                 conn->data_prot, conn);
+  buf->index = 0;
+  return CURLE_OK;
+}
+
+static size_t
+buffer_read(struct krb5buffer *buf, void *data, size_t len)
+{
+  if(buf->size - buf->index < len)
+    len = buf->size - buf->index;
+  memcpy(data, (char *)buf->data + buf->index, len);
+  buf->index += len;
+  return len;
+}
+
+/* Matches Curl_recv signature */
+static ssize_t sec_recv(struct connectdata *conn, int sockindex,
+                        char *buffer, size_t len, CURLcode *err)
+{
+  size_t bytes_read;
+  size_t total_read = 0;
+  curl_socket_t fd = conn->sock[sockindex];
+
+  *err = CURLE_OK;
+
+  /* Handle clear text response. */
+  if(conn->sec_complete == 0 || conn->data_prot == PROT_CLEAR)
+      return read(fd, buffer, len);
+
+  if(conn->in_buffer.eof_flag) {
+    conn->in_buffer.eof_flag = 0;
+    return 0;
+  }
+
+  bytes_read = buffer_read(&conn->in_buffer, buffer, len);
+  len -= bytes_read;
+  total_read += bytes_read;
+  buffer += bytes_read;
+
+  while(len > 0) {
+    if(read_data(conn, fd, &conn->in_buffer))
+      return -1;
+    if(conn->in_buffer.size == 0) {
+      if(bytes_read > 0)
+        conn->in_buffer.eof_flag = 1;
+      return bytes_read;
+    }
+    bytes_read = buffer_read(&conn->in_buffer, buffer, len);
+    len -= bytes_read;
+    total_read += bytes_read;
+    buffer += bytes_read;
+  }
+  /* FIXME: Check for overflow */
+  return total_read;
+}
+
+/* Send |length| bytes from |from| to the |fd| socket taking care of encoding
+   and negociating with the server. |from| can be NULL. */
+/* FIXME: We don't check for errors nor report any! */
+static void do_sec_send(struct connectdata *conn, curl_socket_t fd,
+                        const char *from, int length)
+{
+  int bytes, htonl_bytes; /* 32-bit integers for htonl */
+  char *buffer = NULL;
+  char *cmd_buffer;
+  size_t cmd_size = 0;
+  CURLcode error;
+  enum protection_level prot_level = conn->data_prot;
+  bool iscmd = (prot_level == PROT_CMD)?TRUE:FALSE;
+
+  DEBUGASSERT(prot_level > PROT_NONE && prot_level < PROT_LAST);
+
+  if(iscmd) {
+    if(!strncmp(from, "PASS ", 5) || !strncmp(from, "ACCT ", 5))
+      prot_level = PROT_PRIVATE;
+    else
+      prot_level = conn->command_prot;
+  }
+  bytes = conn->mech->encode(conn->app_data, from, length, prot_level,
+                             (void **)&buffer);
+  if(!buffer || bytes <= 0)
+    return; /* error */
+
+  if(iscmd) {
+    error = Curl_base64_encode(conn->data, buffer, curlx_sitouz(bytes),
+                               &cmd_buffer, &cmd_size);
+    if(error) {
+      free(buffer);
+      return; /* error */
+    }
+    if(cmd_size > 0) {
+      static const char *enc = "ENC ";
+      static const char *mic = "MIC ";
+      if(prot_level == PROT_PRIVATE)
+        socket_write(conn, fd, enc, 4);
+      else
+        socket_write(conn, fd, mic, 4);
+
+      socket_write(conn, fd, cmd_buffer, cmd_size);
+      socket_write(conn, fd, "\r\n", 2);
+      infof(conn->data, "Send: %s%s\n", prot_level == PROT_PRIVATE?enc:mic,
+            cmd_buffer);
+      free(cmd_buffer);
+    }
+  }
+  else {
+    htonl_bytes = htonl(bytes);
+    socket_write(conn, fd, &htonl_bytes, sizeof(htonl_bytes));
+    socket_write(conn, fd, buffer, curlx_sitouz(bytes));
+  }
+  free(buffer);
+}
+
+static ssize_t sec_write(struct connectdata *conn, curl_socket_t fd,
+                         const char *buffer, size_t length)
+{
+  ssize_t tx = 0, len = conn->buffer_size;
+
+  len -= conn->mech->overhead(conn->app_data, conn->data_prot,
+                              curlx_sztosi(len));
+  if(len <= 0)
+    len = length;
+  while(length) {
+    if(length < (size_t)len)
+      len = length;
+
+    do_sec_send(conn, fd, buffer, curlx_sztosi(len));
+    length -= len;
+    buffer += len;
+    tx += len;
+  }
+  return tx;
+}
+
+/* Matches Curl_send signature */
+static ssize_t sec_send(struct connectdata *conn, int sockindex,
+                        const void *buffer, size_t len, CURLcode *err)
+{
+  curl_socket_t fd = conn->sock[sockindex];
+  *err = CURLE_OK;
+  return sec_write(conn, fd, buffer, len);
+}
+
+int Curl_sec_read_msg(struct connectdata *conn, char *buffer,
+                      enum protection_level level)
+{
+  /* decoded_len should be size_t or ssize_t but conn->mech->decode returns an
+     int */
+  int decoded_len;
+  char *buf;
+  int ret_code = 0;
+  size_t decoded_sz = 0;
+  CURLcode error;
+
+  if(!conn->mech)
+    /* not inititalized, return error */
+    return -1;
+
+  DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
+
+  error = Curl_base64_decode(buffer + 4, (unsigned char **)&buf, &decoded_sz);
+  if(error || decoded_sz == 0)
+    return -1;
+
+  if(decoded_sz > (size_t)INT_MAX) {
+    free(buf);
+    return -1;
+  }
+  decoded_len = curlx_uztosi(decoded_sz);
+
+  decoded_len = conn->mech->decode(conn->app_data, buf, decoded_len,
+                                   level, conn);
+  if(decoded_len <= 0) {
+    free(buf);
+    return -1;
+  }
+
+  if(conn->data->set.verbose) {
+    buf[decoded_len] = '\n';
+    Curl_debug(conn->data, CURLINFO_HEADER_IN, buf, decoded_len + 1, conn);
+  }
+
+  buf[decoded_len] = '\0';
+  if(decoded_len <= 3)
+    /* suspiciously short */
+    return 0;
+
+  if(buf[3] != '-')
+    /* safe to ignore return code */
+    (void)sscanf(buf, "%d", &ret_code);
+
+  if(buf[decoded_len - 1] == '\n')
+    buf[decoded_len - 1] = '\0';
+  /* FIXME: Is |buffer| length always greater than |decoded_len|? */
+  strcpy(buffer, buf);
+  free(buf);
+  return ret_code;
+}
+
+/* FIXME: The error code returned here is never checked. */
+static int sec_set_protection_level(struct connectdata *conn)
+{
+  int code;
+  char *pbsz;
+  static unsigned int buffer_size = 1 << 20; /* 1048576 */
+  enum protection_level level = conn->request_data_prot;
+
+  DEBUGASSERT(level > PROT_NONE && level < PROT_LAST);
+
+  if(!conn->sec_complete) {
+    infof(conn->data, "Trying to change the protection level after the"
+                      "completion of the data exchange.\n");
+    return -1;
+  }
+
+  /* Bail out if we try to set up the same level */
+  if(conn->data_prot == level)
+    return 0;
+
+  if(level) {
+    code = ftp_send_command(conn, "PBSZ %u", buffer_size);
+    if(code < 0)
+      return -1;
+
+    if(code/100 != 2) {
+      failf(conn->data, "Failed to set the protection's buffer size.");
+      return -1;
+    }
+    conn->buffer_size = buffer_size;
+
+    pbsz = strstr(conn->data->state.buffer, "PBSZ=");
+    if(pbsz) {
+      /* ignore return code, use default value if it fails */
+      (void)sscanf(pbsz, "PBSZ=%u", &buffer_size);
+      if(buffer_size < conn->buffer_size)
+        conn->buffer_size = buffer_size;
+    }
+  }
+
+  /* Now try to negiociate the protection level. */
+  code = ftp_send_command(conn, "PROT %c", level_to_char(level));
+
+  if(code < 0)
+    return -1;
+
+  if(code/100 != 2) {
+    failf(conn->data, "Failed to set the protection level.");
+    return -1;
+  }
+
+  conn->data_prot = level;
+  if(level == PROT_PRIVATE)
+    conn->command_prot = level;
+
+  return 0;
+}
+
+int
+Curl_sec_request_prot(struct connectdata *conn, const char *level)
+{
+  enum protection_level l = name_to_level(level);
+  if(l == PROT_NONE)
+    return -1;
+  DEBUGASSERT(l > PROT_NONE && l < PROT_LAST);
+  conn->request_data_prot = l;
+  return 0;
+}
+
+static CURLcode choose_mech(struct connectdata *conn)
+{
+  int ret;
+  struct Curl_easy *data = conn->data;
+  void *tmp_allocation;
+  const struct Curl_sec_client_mech *mech = &Curl_krb5_client_mech;
+
+  tmp_allocation = realloc(conn->app_data, mech->size);
+  if(tmp_allocation == NULL) {
+    failf(data, "Failed realloc of size %u", mech->size);
+    mech = NULL;
+    return CURLE_OUT_OF_MEMORY;
+  }
+  conn->app_data = tmp_allocation;
+
+  if(mech->init) {
+    ret = mech->init(conn->app_data);
+    if(ret) {
+      infof(data, "Failed initialization for %s. Skipping it.\n",
+            mech->name);
+      return CURLE_FAILED_INIT;
+    }
+  }
+
+  infof(data, "Trying mechanism %s...\n", mech->name);
+  ret = ftp_send_command(conn, "AUTH %s", mech->name);
+  if(ret < 0)
+    /* FIXME: This error is too generic but it is OK for now. */
+    return CURLE_COULDNT_CONNECT;
+
+  if(ret/100 != 3) {
+    switch(ret) {
+    case 504:
+      infof(data, "Mechanism %s is not supported by the server (server "
+            "returned ftp code: 504).\n", mech->name);
+      break;
+    case 534:
+      infof(data, "Mechanism %s was rejected by the server (server returned "
+            "ftp code: 534).\n", mech->name);
+      break;
+    default:
+      if(ret/100 == 5) {
+        infof(data, "server does not support the security extensions\n");
+        return CURLE_USE_SSL_FAILED;
+      }
+      break;
+    }
+    return CURLE_LOGIN_DENIED;
+  }
+
+  /* Authenticate */
+  ret = mech->auth(conn->app_data, conn);
+
+  if(ret != AUTH_CONTINUE) {
+    if(ret != AUTH_OK) {
+      /* Mechanism has dumped the error to stderr, don't error here. */
+      return -1;
+    }
+    DEBUGASSERT(ret == AUTH_OK);
+
+    conn->mech = mech;
+    conn->sec_complete = 1;
+    conn->recv[FIRSTSOCKET] = sec_recv;
+    conn->send[FIRSTSOCKET] = sec_send;
+    conn->recv[SECONDARYSOCKET] = sec_recv;
+    conn->send[SECONDARYSOCKET] = sec_send;
+    conn->command_prot = PROT_SAFE;
+    /* Set the requested protection level */
+    /* BLOCKING */
+    (void)sec_set_protection_level(conn);
+  }
+
+  return CURLE_OK;
+}
+
+CURLcode
+Curl_sec_login(struct connectdata *conn)
+{
+  return choose_mech(conn);
+}
+
+
+void
+Curl_sec_end(struct connectdata *conn)
+{
+  if(conn->mech != NULL && conn->mech->end)
+    conn->mech->end(conn->app_data);
+  free(conn->app_data);
+  conn->app_data = NULL;
+  if(conn->in_buffer.data) {
+    free(conn->in_buffer.data);
+    conn->in_buffer.data = NULL;
+    conn->in_buffer.size = 0;
+    conn->in_buffer.index = 0;
+    /* FIXME: Is this really needed? */
+    conn->in_buffer.eof_flag = 0;
+  }
+  conn->sec_complete = 0;
+  conn->data_prot = PROT_CLEAR;
+  conn->mech = NULL;
+}
+
+#endif /* HAVE_GSSAPI */
+
+#endif /* CURL_DISABLE_FTP */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/select.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/select.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/select.c	(revision 331)
@@ -0,0 +1,583 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#if !defined(HAVE_SELECT) && !defined(HAVE_POLL_FINE)
+#error "We can't compile without select() or poll() support."
+#endif
+
+#if defined(__BEOS__) && !defined(__HAIKU__)
+/* BeOS has FD_SET defined in socket.h */
+#include <socket.h>
+#endif
+
+#ifdef MSDOS
+#include <dos.h>  /* delay() */
+#endif
+
+#ifdef __VXWORKS__
+#include <strings.h>  /* bzero() in FD_SET */
+#endif
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "connect.h"
+#include "select.h"
+#include "warnless.h"
+
+/* Convenience local macros */
+#define ELAPSED_MS() (int)Curl_timediff(Curl_now(), initial_tv)
+
+int Curl_ack_eintr = 0;
+#define ERROR_NOT_EINTR(error) (Curl_ack_eintr || error != EINTR)
+
+/*
+ * Internal function used for waiting a specific amount of ms
+ * in Curl_socket_check() and Curl_poll() when no file descriptor
+ * is provided to wait on, just being used to delay execution.
+ * WinSock select() and poll() timeout mechanisms need a valid
+ * socket descriptor in a not null file descriptor set to work.
+ * Waiting indefinitely with this function is not allowed, a
+ * zero or negative timeout value will return immediately.
+ * Timeout resolution, accuracy, as well as maximum supported
+ * value is system dependent, neither factor is a citical issue
+ * for the intended use of this function in the library.
+ *
+ * Return values:
+ *   -1 = system call error, invalid timeout value, or interrupted
+ *    0 = specified timeout has elapsed
+ */
+int Curl_wait_ms(int timeout_ms)
+{
+#if !defined(MSDOS) && !defined(USE_WINSOCK)
+#ifndef HAVE_POLL_FINE
+  struct timeval pending_tv;
+#endif
+  struct curltime initial_tv;
+  int pending_ms;
+  int error;
+#endif
+  int r = 0;
+
+  if(!timeout_ms)
+    return 0;
+  if(timeout_ms < 0) {
+    SET_SOCKERRNO(EINVAL);
+    return -1;
+  }
+#if defined(MSDOS)
+  delay(timeout_ms);
+#elif defined(USE_WINSOCK)
+  Sleep(timeout_ms);
+#else
+  pending_ms = timeout_ms;
+  initial_tv = Curl_now();
+  do {
+#if defined(HAVE_POLL_FINE)
+    r = poll(NULL, 0, pending_ms);
+#else
+    pending_tv.tv_sec = pending_ms / 1000;
+    pending_tv.tv_usec = (pending_ms % 1000) * 1000;
+    r = select(0, NULL, NULL, NULL, &pending_tv);
+#endif /* HAVE_POLL_FINE */
+    if(r != -1)
+      break;
+    error = SOCKERRNO;
+    if(error && ERROR_NOT_EINTR(error))
+      break;
+    pending_ms = timeout_ms - ELAPSED_MS();
+    if(pending_ms <= 0) {
+      r = 0;  /* Simulate a "call timed out" case */
+      break;
+    }
+  } while(r == -1);
+#endif /* USE_WINSOCK */
+  if(r)
+    r = -1;
+  return r;
+}
+
+/*
+ * Wait for read or write events on a set of file descriptors. It uses poll()
+ * when a fine poll() is available, in order to avoid limits with FD_SETSIZE,
+ * otherwise select() is used.  An error is returned if select() is being used
+ * and a file descriptor is too large for FD_SETSIZE.
+ *
+ * A negative timeout value makes this function wait indefinitely,
+ * unless no valid file descriptor is given, when this happens the
+ * negative timeout is ignored and the function times out immediately.
+ *
+ * Return values:
+ *   -1 = system call error or fd >= FD_SETSIZE
+ *    0 = timeout
+ *    [bitmask] = action as described below
+ *
+ * CURL_CSELECT_IN - first socket is readable
+ * CURL_CSELECT_IN2 - second socket is readable
+ * CURL_CSELECT_OUT - write socket is writable
+ * CURL_CSELECT_ERR - an error condition occurred
+ */
+int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */
+                      curl_socket_t readfd1,
+                      curl_socket_t writefd, /* socket to write to */
+                      time_t timeout_ms)     /* milliseconds to wait */
+{
+#ifdef HAVE_POLL_FINE
+  struct pollfd pfd[3];
+  int num;
+#else
+  struct timeval pending_tv;
+  struct timeval *ptimeout;
+  fd_set fds_read;
+  fd_set fds_write;
+  fd_set fds_err;
+  curl_socket_t maxfd;
+#endif
+  struct curltime initial_tv = {0, 0};
+  int pending_ms = 0;
+  int error;
+  int r;
+  int ret;
+
+#if SIZEOF_TIME_T != SIZEOF_INT
+  /* wrap-around precaution */
+  if(timeout_ms >= INT_MAX)
+    timeout_ms = INT_MAX;
+#endif
+
+  if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) &&
+     (writefd == CURL_SOCKET_BAD)) {
+    /* no sockets, just wait */
+    r = Curl_wait_ms((int)timeout_ms);
+    return r;
+  }
+
+  /* Avoid initial timestamp, avoid Curl_now() call, when elapsed
+     time in this function does not need to be measured. This happens
+     when function is called with a zero timeout or a negative timeout
+     value indicating a blocking call should be performed. */
+
+  if(timeout_ms > 0) {
+    pending_ms = (int)timeout_ms;
+    initial_tv = Curl_now();
+  }
+
+#ifdef HAVE_POLL_FINE
+
+  num = 0;
+  if(readfd0 != CURL_SOCKET_BAD) {
+    pfd[num].fd = readfd0;
+    pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
+    pfd[num].revents = 0;
+    num++;
+  }
+  if(readfd1 != CURL_SOCKET_BAD) {
+    pfd[num].fd = readfd1;
+    pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI;
+    pfd[num].revents = 0;
+    num++;
+  }
+  if(writefd != CURL_SOCKET_BAD) {
+    pfd[num].fd = writefd;
+    pfd[num].events = POLLWRNORM|POLLOUT;
+    pfd[num].revents = 0;
+    num++;
+  }
+
+  do {
+    if(timeout_ms < 0)
+      pending_ms = -1;
+    else if(!timeout_ms)
+      pending_ms = 0;
+    r = poll(pfd, num, pending_ms);
+    if(r != -1)
+      break;
+    error = SOCKERRNO;
+    if(error && ERROR_NOT_EINTR(error))
+      break;
+    if(timeout_ms > 0) {
+      pending_ms = (int)(timeout_ms - ELAPSED_MS());
+      if(pending_ms <= 0) {
+        r = 0;  /* Simulate a "call timed out" case */
+        break;
+      }
+    }
+  } while(r == -1);
+
+  if(r < 0)
+    return -1;
+  if(r == 0)
+    return 0;
+
+  ret = 0;
+  num = 0;
+  if(readfd0 != CURL_SOCKET_BAD) {
+    if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
+      ret |= CURL_CSELECT_IN;
+    if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
+      ret |= CURL_CSELECT_ERR;
+    num++;
+  }
+  if(readfd1 != CURL_SOCKET_BAD) {
+    if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP))
+      ret |= CURL_CSELECT_IN2;
+    if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL))
+      ret |= CURL_CSELECT_ERR;
+    num++;
+  }
+  if(writefd != CURL_SOCKET_BAD) {
+    if(pfd[num].revents & (POLLWRNORM|POLLOUT))
+      ret |= CURL_CSELECT_OUT;
+    if(pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL))
+      ret |= CURL_CSELECT_ERR;
+  }
+
+  return ret;
+
+#else  /* HAVE_POLL_FINE */
+
+  FD_ZERO(&fds_err);
+  maxfd = (curl_socket_t)-1;
+
+  FD_ZERO(&fds_read);
+  if(readfd0 != CURL_SOCKET_BAD) {
+    VERIFY_SOCK(readfd0);
+    FD_SET(readfd0, &fds_read);
+    FD_SET(readfd0, &fds_err);
+    maxfd = readfd0;
+  }
+  if(readfd1 != CURL_SOCKET_BAD) {
+    VERIFY_SOCK(readfd1);
+    FD_SET(readfd1, &fds_read);
+    FD_SET(readfd1, &fds_err);
+    if(readfd1 > maxfd)
+      maxfd = readfd1;
+  }
+
+  FD_ZERO(&fds_write);
+  if(writefd != CURL_SOCKET_BAD) {
+    VERIFY_SOCK(writefd);
+    FD_SET(writefd, &fds_write);
+    FD_SET(writefd, &fds_err);
+    if(writefd > maxfd)
+      maxfd = writefd;
+  }
+
+  ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
+
+  do {
+    if(timeout_ms > 0) {
+      pending_tv.tv_sec = pending_ms / 1000;
+      pending_tv.tv_usec = (pending_ms % 1000) * 1000;
+    }
+    else if(!timeout_ms) {
+      pending_tv.tv_sec = 0;
+      pending_tv.tv_usec = 0;
+    }
+
+    /* WinSock select() must not be called with an fd_set that contains zero
+       fd flags, or it will return WSAEINVAL.  But, it also can't be called
+       with no fd_sets at all!  From the documentation:
+
+         Any two of the parameters, readfds, writefds, or exceptfds, can be
+         given as null. At least one must be non-null, and any non-null
+         descriptor set must contain at least one handle to a socket.
+
+       We know that we have at least one bit set in at least two fd_sets in
+       this case, but we may have no bits set in either fds_read or fd_write,
+       so check for that and handle it.  Luckily, with WinSock, we can _also_
+       ask how many bits are set on an fd_set.
+
+       It is unclear why WinSock doesn't just handle this for us instead of
+       calling this an error.
+
+       Note also that WinSock ignores the first argument, so we don't worry
+       about the fact that maxfd is computed incorrectly with WinSock (since
+       curl_socket_t is unsigned in such cases and thus -1 is the largest
+       value).
+    */
+#ifdef USE_WINSOCK
+    r = select((int)maxfd + 1,
+               fds_read.fd_count ? &fds_read : NULL,
+               fds_write.fd_count ? &fds_write : NULL,
+               &fds_err, ptimeout);
+#else
+    r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
+#endif
+
+    if(r != -1)
+      break;
+    error = SOCKERRNO;
+    if(error && ERROR_NOT_EINTR(error))
+      break;
+    if(timeout_ms > 0) {
+      pending_ms = (int)(timeout_ms - ELAPSED_MS());
+      if(pending_ms <= 0) {
+        r = 0;  /* Simulate a "call timed out" case */
+        break;
+      }
+    }
+  } while(r == -1);
+
+  if(r < 0)
+    return -1;
+  if(r == 0)
+    return 0;
+
+  ret = 0;
+  if(readfd0 != CURL_SOCKET_BAD) {
+    if(FD_ISSET(readfd0, &fds_read))
+      ret |= CURL_CSELECT_IN;
+    if(FD_ISSET(readfd0, &fds_err))
+      ret |= CURL_CSELECT_ERR;
+  }
+  if(readfd1 != CURL_SOCKET_BAD) {
+    if(FD_ISSET(readfd1, &fds_read))
+      ret |= CURL_CSELECT_IN2;
+    if(FD_ISSET(readfd1, &fds_err))
+      ret |= CURL_CSELECT_ERR;
+  }
+  if(writefd != CURL_SOCKET_BAD) {
+    if(FD_ISSET(writefd, &fds_write))
+      ret |= CURL_CSELECT_OUT;
+    if(FD_ISSET(writefd, &fds_err))
+      ret |= CURL_CSELECT_ERR;
+  }
+
+  return ret;
+
+#endif  /* HAVE_POLL_FINE */
+
+}
+
+/*
+ * This is a wrapper around poll().  If poll() does not exist, then
+ * select() is used instead.  An error is returned if select() is
+ * being used and a file descriptor is too large for FD_SETSIZE.
+ * A negative timeout value makes this function wait indefinitely,
+ * unless no valid file descriptor is given, when this happens the
+ * negative timeout is ignored and the function times out immediately.
+ *
+ * Return values:
+ *   -1 = system call error or fd >= FD_SETSIZE
+ *    0 = timeout
+ *    N = number of structures with non zero revent fields
+ */
+int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
+{
+#ifndef HAVE_POLL_FINE
+  struct timeval pending_tv;
+  struct timeval *ptimeout;
+  fd_set fds_read;
+  fd_set fds_write;
+  fd_set fds_err;
+  curl_socket_t maxfd;
+#endif
+  struct curltime initial_tv = {0, 0};
+  bool fds_none = TRUE;
+  unsigned int i;
+  int pending_ms = 0;
+  int error;
+  int r;
+
+  if(ufds) {
+    for(i = 0; i < nfds; i++) {
+      if(ufds[i].fd != CURL_SOCKET_BAD) {
+        fds_none = FALSE;
+        break;
+      }
+    }
+  }
+  if(fds_none) {
+    r = Curl_wait_ms(timeout_ms);
+    return r;
+  }
+
+  /* Avoid initial timestamp, avoid Curl_now() call, when elapsed
+     time in this function does not need to be measured. This happens
+     when function is called with a zero timeout or a negative timeout
+     value indicating a blocking call should be performed. */
+
+  if(timeout_ms > 0) {
+    pending_ms = timeout_ms;
+    initial_tv = Curl_now();
+  }
+
+#ifdef HAVE_POLL_FINE
+
+  do {
+    if(timeout_ms < 0)
+      pending_ms = -1;
+    else if(!timeout_ms)
+      pending_ms = 0;
+    r = poll(ufds, nfds, pending_ms);
+    if(r != -1)
+      break;
+    error = SOCKERRNO;
+    if(error && ERROR_NOT_EINTR(error))
+      break;
+    if(timeout_ms > 0) {
+      pending_ms = (int)(timeout_ms - ELAPSED_MS());
+      if(pending_ms <= 0) {
+        r = 0;  /* Simulate a "call timed out" case */
+        break;
+      }
+    }
+  } while(r == -1);
+
+  if(r < 0)
+    return -1;
+  if(r == 0)
+    return 0;
+
+  for(i = 0; i < nfds; i++) {
+    if(ufds[i].fd == CURL_SOCKET_BAD)
+      continue;
+    if(ufds[i].revents & POLLHUP)
+      ufds[i].revents |= POLLIN;
+    if(ufds[i].revents & POLLERR)
+      ufds[i].revents |= (POLLIN|POLLOUT);
+  }
+
+#else  /* HAVE_POLL_FINE */
+
+  FD_ZERO(&fds_read);
+  FD_ZERO(&fds_write);
+  FD_ZERO(&fds_err);
+  maxfd = (curl_socket_t)-1;
+
+  for(i = 0; i < nfds; i++) {
+    ufds[i].revents = 0;
+    if(ufds[i].fd == CURL_SOCKET_BAD)
+      continue;
+    VERIFY_SOCK(ufds[i].fd);
+    if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI|
+                          POLLRDNORM|POLLWRNORM|POLLRDBAND)) {
+      if(ufds[i].fd > maxfd)
+        maxfd = ufds[i].fd;
+      if(ufds[i].events & (POLLRDNORM|POLLIN))
+        FD_SET(ufds[i].fd, &fds_read);
+      if(ufds[i].events & (POLLWRNORM|POLLOUT))
+        FD_SET(ufds[i].fd, &fds_write);
+      if(ufds[i].events & (POLLRDBAND|POLLPRI))
+        FD_SET(ufds[i].fd, &fds_err);
+    }
+  }
+
+#ifdef USE_WINSOCK
+  /* WinSock select() can't handle zero events.  See the comment about this in
+     Curl_check_socket(). */
+  if(fds_read.fd_count == 0 && fds_write.fd_count == 0
+     && fds_err.fd_count == 0) {
+    r = Curl_wait_ms(timeout_ms);
+    return r;
+  }
+#endif
+
+  ptimeout = (timeout_ms < 0) ? NULL : &pending_tv;
+
+  do {
+    if(timeout_ms > 0) {
+      pending_tv.tv_sec = pending_ms / 1000;
+      pending_tv.tv_usec = (pending_ms % 1000) * 1000;
+    }
+    else if(!timeout_ms) {
+      pending_tv.tv_sec = 0;
+      pending_tv.tv_usec = 0;
+    }
+
+#ifdef USE_WINSOCK
+    r = select((int)maxfd + 1,
+               /* WinSock select() can't handle fd_sets with zero bits set, so
+                  don't give it such arguments.  See the comment about this in
+                  Curl_check_socket().
+               */
+               fds_read.fd_count ? &fds_read : NULL,
+               fds_write.fd_count ? &fds_write : NULL,
+               fds_err.fd_count ? &fds_err : NULL, ptimeout);
+#else
+    r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout);
+#endif
+    if(r != -1)
+      break;
+    error = SOCKERRNO;
+    if(error && ERROR_NOT_EINTR(error))
+      break;
+    if(timeout_ms > 0) {
+      pending_ms = timeout_ms - ELAPSED_MS();
+      if(pending_ms <= 0) {
+        r = 0;  /* Simulate a "call timed out" case */
+        break;
+      }
+    }
+  } while(r == -1);
+
+  if(r < 0)
+    return -1;
+  if(r == 0)
+    return 0;
+
+  r = 0;
+  for(i = 0; i < nfds; i++) {
+    ufds[i].revents = 0;
+    if(ufds[i].fd == CURL_SOCKET_BAD)
+      continue;
+    if(FD_ISSET(ufds[i].fd, &fds_read))
+      ufds[i].revents |= POLLIN;
+    if(FD_ISSET(ufds[i].fd, &fds_write))
+      ufds[i].revents |= POLLOUT;
+    if(FD_ISSET(ufds[i].fd, &fds_err))
+      ufds[i].revents |= POLLPRI;
+    if(ufds[i].revents != 0)
+      r++;
+  }
+
+#endif  /* HAVE_POLL_FINE */
+
+  return r;
+}
+
+#ifdef TPF
+/*
+ * This is a replacement for select() on the TPF platform.
+ * It is used whenever libcurl calls select().
+ * The call below to tpf_process_signals() is required because
+ * TPF's select calls are not signal interruptible.
+ *
+ * Return values are the same as select's.
+ */
+int tpf_select_libcurl(int maxfds, fd_set *reads, fd_set *writes,
+                       fd_set *excepts, struct timeval *tv)
+{
+   int rc;
+
+   rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv);
+   tpf_process_signals();
+   return rc;
+}
+#endif /* TPF */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/select.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/select.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/select.h	(revision 331)
@@ -0,0 +1,116 @@
+#ifndef HEADER_CURL_SELECT_H
+#define HEADER_CURL_SELECT_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#elif defined(HAVE_SYS_POLL_H)
+#include <sys/poll.h>
+#endif
+
+/*
+ * Definition of pollfd struct and constants for platforms lacking them.
+ */
+
+#if !defined(HAVE_STRUCT_POLLFD) && \
+    !defined(HAVE_SYS_POLL_H) && \
+    !defined(HAVE_POLL_H) && \
+    !defined(POLLIN)
+
+#define POLLIN      0x01
+#define POLLPRI     0x02
+#define POLLOUT     0x04
+#define POLLERR     0x08
+#define POLLHUP     0x10
+#define POLLNVAL    0x20
+
+struct pollfd
+{
+    curl_socket_t fd;
+    short   events;
+    short   revents;
+};
+
+#endif
+
+#ifndef POLLRDNORM
+#define POLLRDNORM POLLIN
+#endif
+
+#ifndef POLLWRNORM
+#define POLLWRNORM POLLOUT
+#endif
+
+#ifndef POLLRDBAND
+#define POLLRDBAND POLLPRI
+#endif
+
+/* there are three CSELECT defines that are defined in the public header that
+   are exposed to users, but this *IN2 bit is only ever used internally and
+   therefore defined here */
+#define CURL_CSELECT_IN2 (CURL_CSELECT_ERR << 1)
+
+int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2,
+                      curl_socket_t writefd,
+                      time_t timeout_ms);
+
+#define SOCKET_READABLE(x,z) \
+  Curl_socket_check(x, CURL_SOCKET_BAD, CURL_SOCKET_BAD, z)
+#define SOCKET_WRITABLE(x,z) \
+  Curl_socket_check(CURL_SOCKET_BAD, CURL_SOCKET_BAD, x, z)
+
+int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms);
+
+/* On non-DOS and non-Winsock platforms, when Curl_ack_eintr is set,
+ * EINTR condition is honored and function might exit early without
+ * awaiting full timeout.  Otherwise EINTR will be ignored and full
+ * timeout will elapse. */
+extern int Curl_ack_eintr;
+
+int Curl_wait_ms(int timeout_ms);
+
+#ifdef TPF
+int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes,
+                       fd_set* excepts, struct timeval* tv);
+#endif
+
+/* Winsock and TPF sockets are not in range [0..FD_SETSIZE-1], which
+   unfortunately makes it impossible for us to easily check if they're valid
+*/
+#if defined(USE_WINSOCK) || defined(TPF)
+#define VALID_SOCK(x) 1
+#define VERIFY_SOCK(x) Curl_nop_stmt
+#else
+#define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE))
+#define VERIFY_SOCK(x) do { \
+  if(!VALID_SOCK(x)) { \
+    SET_SOCKERRNO(EINVAL); \
+    return -1; \
+  } \
+} WHILE_FALSE
+#endif
+
+#endif /* HEADER_CURL_SELECT_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/sendf.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/sendf.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/sendf.c	(revision 331)
@@ -0,0 +1,859 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_LINUX_TCP_H
+#include <linux/tcp.h>
+#endif
+
+#include <curl/curl.h>
+
+#include "urldata.h"
+#include "sendf.h"
+#include "connect.h"
+#include "vtls/vtls.h"
+#include "ssh.h"
+#include "multiif.h"
+#include "non-ascii.h"
+#include "strerror.h"
+#include "select.h"
+#include "strdup.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifdef CURL_DO_LINEEND_CONV
+/*
+ * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF
+ * (\n), with special processing for CRLF sequences that are split between two
+ * blocks of data.  Remaining, bare CRs are changed to LFs.  The possibly new
+ * size of the data is returned.
+ */
+static size_t convert_lineends(struct Curl_easy *data,
+                               char *startPtr, size_t size)
+{
+  char *inPtr, *outPtr;
+
+  /* sanity check */
+  if((startPtr == NULL) || (size < 1)) {
+    return size;
+  }
+
+  if(data->state.prev_block_had_trailing_cr) {
+    /* The previous block of incoming data
+       had a trailing CR, which was turned into a LF. */
+    if(*startPtr == '\n') {
+      /* This block of incoming data starts with the
+         previous block's LF so get rid of it */
+      memmove(startPtr, startPtr + 1, size-1);
+      size--;
+      /* and it wasn't a bare CR but a CRLF conversion instead */
+      data->state.crlf_conversions++;
+    }
+    data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */
+  }
+
+  /* find 1st CR, if any */
+  inPtr = outPtr = memchr(startPtr, '\r', size);
+  if(inPtr) {
+    /* at least one CR, now look for CRLF */
+    while(inPtr < (startPtr + size-1)) {
+      /* note that it's size-1, so we'll never look past the last byte */
+      if(memcmp(inPtr, "\r\n", 2) == 0) {
+        /* CRLF found, bump past the CR and copy the NL */
+        inPtr++;
+        *outPtr = *inPtr;
+        /* keep track of how many CRLFs we converted */
+        data->state.crlf_conversions++;
+      }
+      else {
+        if(*inPtr == '\r') {
+          /* lone CR, move LF instead */
+          *outPtr = '\n';
+        }
+        else {
+          /* not a CRLF nor a CR, just copy whatever it is */
+          *outPtr = *inPtr;
+        }
+      }
+      outPtr++;
+      inPtr++;
+    } /* end of while loop */
+
+    if(inPtr < startPtr + size) {
+      /* handle last byte */
+      if(*inPtr == '\r') {
+        /* deal with a CR at the end of the buffer */
+        *outPtr = '\n'; /* copy a NL instead */
+        /* note that a CRLF might be split across two blocks */
+        data->state.prev_block_had_trailing_cr = TRUE;
+      }
+      else {
+        /* copy last byte */
+        *outPtr = *inPtr;
+      }
+      outPtr++;
+    }
+    if(outPtr < startPtr + size)
+      /* tidy up by null terminating the now shorter data */
+      *outPtr = '\0';
+
+    return (outPtr - startPtr);
+  }
+  return size;
+}
+#endif /* CURL_DO_LINEEND_CONV */
+
+#ifdef USE_RECV_BEFORE_SEND_WORKAROUND
+bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex)
+{
+  struct postponed_data * const psnd = &(conn->postponed[sockindex]);
+  return psnd->buffer && psnd->allocated_size &&
+         psnd->recv_size > psnd->recv_processed;
+}
+
+static void pre_receive_plain(struct connectdata *conn, int num)
+{
+  const curl_socket_t sockfd = conn->sock[num];
+  struct postponed_data * const psnd = &(conn->postponed[num]);
+  size_t bytestorecv = psnd->allocated_size - psnd->recv_size;
+  /* WinSock will destroy unread received data if send() is
+     failed.
+     To avoid lossage of received data, recv() must be
+     performed before every send() if any incoming data is
+     available. However, skip this, if buffer is already full. */
+  if((conn->handler->protocol&PROTO_FAMILY_HTTP) != 0 &&
+     conn->recv[num] == Curl_recv_plain &&
+     (!psnd->buffer || bytestorecv)) {
+    const int readymask = Curl_socket_check(sockfd, CURL_SOCKET_BAD,
+                                            CURL_SOCKET_BAD, 0);
+    if(readymask != -1 && (readymask & CURL_CSELECT_IN) != 0) {
+      /* Have some incoming data */
+      if(!psnd->buffer) {
+        /* Use buffer double default size for intermediate buffer */
+        psnd->allocated_size = 2 * conn->data->set.buffer_size;
+        psnd->buffer = malloc(psnd->allocated_size);
+        psnd->recv_size = 0;
+        psnd->recv_processed = 0;
+#ifdef DEBUGBUILD
+        psnd->bindsock = sockfd; /* Used only for DEBUGASSERT */
+#endif /* DEBUGBUILD */
+        bytestorecv = psnd->allocated_size;
+      }
+      if(psnd->buffer) {
+        ssize_t recvedbytes;
+        DEBUGASSERT(psnd->bindsock == sockfd);
+        recvedbytes = sread(sockfd, psnd->buffer + psnd->recv_size,
+                            bytestorecv);
+        if(recvedbytes > 0)
+          psnd->recv_size += recvedbytes;
+      }
+      else
+        psnd->allocated_size = 0;
+    }
+  }
+}
+
+static ssize_t get_pre_recved(struct connectdata *conn, int num, char *buf,
+                              size_t len)
+{
+  struct postponed_data * const psnd = &(conn->postponed[num]);
+  size_t copysize;
+  if(!psnd->buffer)
+    return 0;
+
+  DEBUGASSERT(psnd->allocated_size > 0);
+  DEBUGASSERT(psnd->recv_size <= psnd->allocated_size);
+  DEBUGASSERT(psnd->recv_processed <= psnd->recv_size);
+  /* Check and process data that already received and storied in internal
+     intermediate buffer */
+  if(psnd->recv_size > psnd->recv_processed) {
+    DEBUGASSERT(psnd->bindsock == conn->sock[num]);
+    copysize = CURLMIN(len, psnd->recv_size - psnd->recv_processed);
+    memcpy(buf, psnd->buffer + psnd->recv_processed, copysize);
+    psnd->recv_processed += copysize;
+  }
+  else
+    copysize = 0; /* buffer was allocated, but nothing was received */
+
+  /* Free intermediate buffer if it has no unprocessed data */
+  if(psnd->recv_processed == psnd->recv_size) {
+    free(psnd->buffer);
+    psnd->buffer = NULL;
+    psnd->allocated_size = 0;
+    psnd->recv_size = 0;
+    psnd->recv_processed = 0;
+#ifdef DEBUGBUILD
+    psnd->bindsock = CURL_SOCKET_BAD;
+#endif /* DEBUGBUILD */
+  }
+  return (ssize_t)copysize;
+}
+#else  /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
+/* Use "do-nothing" macros instead of functions when workaround not used */
+bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex)
+{
+  (void)conn;
+  (void)sockindex;
+  return false;
+}
+#define pre_receive_plain(c,n) do {} WHILE_FALSE
+#define get_pre_recved(c,n,b,l) 0
+#endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
+
+/* Curl_infof() is for info message along the way */
+
+void Curl_infof(struct Curl_easy *data, const char *fmt, ...)
+{
+  if(data && data->set.verbose) {
+    va_list ap;
+    size_t len;
+    char print_buffer[2048 + 1];
+    va_start(ap, fmt);
+    vsnprintf(print_buffer, sizeof(print_buffer), fmt, ap);
+    va_end(ap);
+    len = strlen(print_buffer);
+    Curl_debug(data, CURLINFO_TEXT, print_buffer, len, NULL);
+  }
+}
+
+/* Curl_failf() is for messages stating why we failed.
+ * The message SHALL NOT include any LF or CR.
+ */
+
+void Curl_failf(struct Curl_easy *data, const char *fmt, ...)
+{
+  if(data->set.verbose || data->set.errorbuffer) {
+    va_list ap;
+    size_t len;
+    char error[CURL_ERROR_SIZE + 2];
+    va_start(ap, fmt);
+    vsnprintf(error, CURL_ERROR_SIZE, fmt, ap);
+    len = strlen(error);
+
+    if(data->set.errorbuffer && !data->state.errorbuf) {
+      strcpy(data->set.errorbuffer, error);
+      data->state.errorbuf = TRUE; /* wrote error string */
+    }
+    if(data->set.verbose) {
+      error[len] = '\n';
+      error[++len] = '\0';
+      Curl_debug(data, CURLINFO_TEXT, error, len, NULL);
+    }
+    va_end(ap);
+  }
+}
+
+/* Curl_sendf() sends formatted data to the server */
+CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
+                    const char *fmt, ...)
+{
+  struct Curl_easy *data = conn->data;
+  ssize_t bytes_written;
+  size_t write_len;
+  CURLcode result = CURLE_OK;
+  char *s;
+  char *sptr;
+  va_list ap;
+  va_start(ap, fmt);
+  s = vaprintf(fmt, ap); /* returns an allocated string */
+  va_end(ap);
+  if(!s)
+    return CURLE_OUT_OF_MEMORY; /* failure */
+
+  bytes_written = 0;
+  write_len = strlen(s);
+  sptr = s;
+
+  for(;;) {
+    /* Write the buffer to the socket */
+    result = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
+
+    if(result)
+      break;
+
+    if(data->set.verbose)
+      Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written, conn);
+
+    if((size_t)bytes_written != write_len) {
+      /* if not all was written at once, we must advance the pointer, decrease
+         the size left and try again! */
+      write_len -= bytes_written;
+      sptr += bytes_written;
+    }
+    else
+      break;
+  }
+
+  free(s); /* free the output string */
+
+  return result;
+}
+
+/*
+ * Curl_write() is an internal write function that sends data to the
+ * server. Works with plain sockets, SCP, SSL or kerberos.
+ *
+ * If the write would block (CURLE_AGAIN), we return CURLE_OK and
+ * (*written == 0). Otherwise we return regular CURLcode value.
+ */
+CURLcode Curl_write(struct connectdata *conn,
+                    curl_socket_t sockfd,
+                    const void *mem,
+                    size_t len,
+                    ssize_t *written)
+{
+  ssize_t bytes_written;
+  CURLcode result = CURLE_OK;
+  int num = (sockfd == conn->sock[SECONDARYSOCKET]);
+
+  bytes_written = conn->send[num](conn, num, mem, len, &result);
+
+  *written = bytes_written;
+  if(bytes_written >= 0)
+    /* we completely ignore the curlcode value when subzero is not returned */
+    return CURLE_OK;
+
+  /* handle CURLE_AGAIN or a send failure */
+  switch(result) {
+  case CURLE_AGAIN:
+    *written = 0;
+    return CURLE_OK;
+
+  case CURLE_OK:
+    /* general send failure */
+    return CURLE_SEND_ERROR;
+
+  default:
+    /* we got a specific curlcode, forward it */
+    return result;
+  }
+}
+
+ssize_t Curl_send_plain(struct connectdata *conn, int num,
+                        const void *mem, size_t len, CURLcode *code)
+{
+  curl_socket_t sockfd = conn->sock[num];
+  ssize_t bytes_written;
+  /* WinSock will destroy unread received data if send() is
+     failed.
+     To avoid lossage of received data, recv() must be
+     performed before every send() if any incoming data is
+     available. */
+  pre_receive_plain(conn, num);
+
+#if defined(MSG_FASTOPEN) && !defined(TCP_FASTOPEN_CONNECT) /* Linux */
+  if(conn->bits.tcp_fastopen) {
+    bytes_written = sendto(sockfd, mem, len, MSG_FASTOPEN,
+                           conn->ip_addr->ai_addr, conn->ip_addr->ai_addrlen);
+    conn->bits.tcp_fastopen = FALSE;
+  }
+  else
+#endif
+    bytes_written = swrite(sockfd, mem, len);
+
+  *code = CURLE_OK;
+  if(-1 == bytes_written) {
+    int err = SOCKERRNO;
+
+    if(
+#ifdef WSAEWOULDBLOCK
+      /* This is how Windows does it */
+      (WSAEWOULDBLOCK == err)
+#else
+      /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
+         due to its inability to send off data without blocking. We therefor
+         treat both error codes the same here */
+      (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) ||
+      (EINPROGRESS == err)
+#endif
+      ) {
+      /* this is just a case of EWOULDBLOCK */
+      bytes_written = 0;
+      *code = CURLE_AGAIN;
+    }
+    else {
+      failf(conn->data, "Send failure: %s",
+            Curl_strerror(conn, err));
+      conn->data->state.os_errno = err;
+      *code = CURLE_SEND_ERROR;
+    }
+  }
+  return bytes_written;
+}
+
+/*
+ * Curl_write_plain() is an internal write function that sends data to the
+ * server using plain sockets only. Otherwise meant to have the exact same
+ * proto as Curl_write()
+ */
+CURLcode Curl_write_plain(struct connectdata *conn,
+                          curl_socket_t sockfd,
+                          const void *mem,
+                          size_t len,
+                          ssize_t *written)
+{
+  ssize_t bytes_written;
+  CURLcode result;
+  int num = (sockfd == conn->sock[SECONDARYSOCKET]);
+
+  bytes_written = Curl_send_plain(conn, num, mem, len, &result);
+
+  *written = bytes_written;
+
+  return result;
+}
+
+ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
+                        size_t len, CURLcode *code)
+{
+  curl_socket_t sockfd = conn->sock[num];
+  ssize_t nread;
+  /* Check and return data that already received and storied in internal
+     intermediate buffer */
+  nread = get_pre_recved(conn, num, buf, len);
+  if(nread > 0) {
+    *code = CURLE_OK;
+    return nread;
+  }
+
+  nread = sread(sockfd, buf, len);
+
+  *code = CURLE_OK;
+  if(-1 == nread) {
+    int err = SOCKERRNO;
+
+    if(
+#ifdef WSAEWOULDBLOCK
+      /* This is how Windows does it */
+      (WSAEWOULDBLOCK == err)
+#else
+      /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
+         due to its inability to send off data without blocking. We therefor
+         treat both error codes the same here */
+      (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
+#endif
+      ) {
+      /* this is just a case of EWOULDBLOCK */
+      *code = CURLE_AGAIN;
+    }
+    else {
+      failf(conn->data, "Recv failure: %s",
+            Curl_strerror(conn, err));
+      conn->data->state.os_errno = err;
+      *code = CURLE_RECV_ERROR;
+    }
+  }
+  return nread;
+}
+
+static CURLcode pausewrite(struct Curl_easy *data,
+                           int type, /* what type of data */
+                           const char *ptr,
+                           size_t len)
+{
+  /* signalled to pause sending on this connection, but since we have data
+     we want to send we need to dup it to save a copy for when the sending
+     is again enabled */
+  struct SingleRequest *k = &data->req;
+  struct UrlState *s = &data->state;
+  char *dupl;
+  unsigned int i;
+  bool newtype = TRUE;
+
+  if(s->tempcount) {
+    for(i = 0; i< s->tempcount; i++) {
+      if(s->tempwrite[i].type == type) {
+        /* data for this type exists */
+        newtype = FALSE;
+        break;
+      }
+    }
+    DEBUGASSERT(i < 3);
+  }
+  else
+    i = 0;
+
+  if(!newtype) {
+    /* append new data to old data */
+
+    /* figure out the new size of the data to save */
+    size_t newlen = len + s->tempwrite[i].len;
+    /* allocate the new memory area */
+    char *newptr = realloc(s->tempwrite[i].buf, newlen);
+    if(!newptr)
+      return CURLE_OUT_OF_MEMORY;
+    /* copy the new data to the end of the new area */
+    memcpy(newptr + s->tempwrite[i].len, ptr, len);
+
+    /* update the pointer and the size */
+    s->tempwrite[i].buf = newptr;
+    s->tempwrite[i].len = newlen;
+  }
+  else {
+    dupl = Curl_memdup(ptr, len);
+    if(!dupl)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* store this information in the state struct for later use */
+    s->tempwrite[i].buf = dupl;
+    s->tempwrite[i].len = len;
+    s->tempwrite[i].type = type;
+
+    if(newtype)
+      s->tempcount++;
+  }
+
+  /* mark the connection as RECV paused */
+  k->keepon |= KEEP_RECV_PAUSE;
+
+  DEBUGF(infof(data, "Paused %zu bytes in buffer for type %02x\n",
+               len, type));
+
+  return CURLE_OK;
+}
+
+
+/* Curl_client_chop_write() writes chunks of data not larger than
+ * CURL_MAX_WRITE_SIZE via client write callback(s) and
+ * takes care of pause requests from the callbacks.
+ */
+CURLcode Curl_client_chop_write(struct connectdata *conn,
+                                int type,
+                                char *ptr,
+                                size_t len)
+{
+  struct Curl_easy *data = conn->data;
+  curl_write_callback writeheader = NULL;
+  curl_write_callback writebody = NULL;
+
+  if(!len)
+    return CURLE_OK;
+
+  /* If reading is paused, append this data to the already held data for this
+     type. */
+  if(data->req.keepon & KEEP_RECV_PAUSE)
+    return pausewrite(data, type, ptr, len);
+
+  /* Determine the callback(s) to use. */
+  if(type & CLIENTWRITE_BODY)
+    writebody = data->set.fwrite_func;
+  if((type & CLIENTWRITE_HEADER) &&
+     (data->set.fwrite_header || data->set.writeheader)) {
+    /*
+     * Write headers to the same callback or to the especially setup
+     * header callback function (added after version 7.7.1).
+     */
+    writeheader =
+      data->set.fwrite_header? data->set.fwrite_header: data->set.fwrite_func;
+  }
+
+  /* Chop data, write chunks. */
+  while(len) {
+    size_t chunklen = len <= CURL_MAX_WRITE_SIZE? len: CURL_MAX_WRITE_SIZE;
+
+    if(writebody) {
+      size_t wrote = writebody(ptr, 1, chunklen, data->set.out);
+
+      if(CURL_WRITEFUNC_PAUSE == wrote) {
+        if(conn->handler->flags & PROTOPT_NONETWORK) {
+          /* Protocols that work without network cannot be paused. This is
+             actually only FILE:// just now, and it can't pause since the
+             transfer isn't done using the "normal" procedure. */
+          failf(data, "Write callback asked for PAUSE when not supported!");
+          return CURLE_WRITE_ERROR;
+        }
+        return pausewrite(data, type, ptr, len);
+      }
+      if(wrote != chunklen) {
+        failf(data, "Failed writing body (%zu != %zu)", wrote, chunklen);
+        return CURLE_WRITE_ERROR;
+      }
+    }
+
+    if(writeheader) {
+      size_t wrote = writeheader(ptr, 1, chunklen, data->set.writeheader);
+
+      if(CURL_WRITEFUNC_PAUSE == wrote)
+        /* here we pass in the HEADER bit only since if this was body as well
+           then it was passed already and clearly that didn't trigger the
+           pause, so this is saved for later with the HEADER bit only */
+        return pausewrite(data, CLIENTWRITE_HEADER, ptr, len);
+
+      if(wrote != chunklen) {
+        failf(data, "Failed writing header");
+        return CURLE_WRITE_ERROR;
+      }
+    }
+
+    ptr += chunklen;
+    len -= chunklen;
+  }
+
+  return CURLE_OK;
+}
+
+
+/* Curl_client_write() sends data to the write callback(s)
+
+   The bit pattern defines to what "streams" to write to. Body and/or header.
+   The defines are in sendf.h of course.
+
+   If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the
+   local character encoding.  This is a problem and should be changed in
+   the future to leave the original data alone.
+ */
+CURLcode Curl_client_write(struct connectdata *conn,
+                           int type,
+                           char *ptr,
+                           size_t len)
+{
+  struct Curl_easy *data = conn->data;
+
+  if(0 == len)
+    len = strlen(ptr);
+
+  DEBUGASSERT(type <= 3);
+
+  /* FTP data may need conversion. */
+  if((type & CLIENTWRITE_BODY) &&
+    (conn->handler->protocol & PROTO_FAMILY_FTP) &&
+    conn->proto.ftpc.transfertype == 'A') {
+    /* convert from the network encoding */
+    CURLcode result = Curl_convert_from_network(data, ptr, len);
+    /* Curl_convert_from_network calls failf if unsuccessful */
+    if(result)
+      return result;
+
+#ifdef CURL_DO_LINEEND_CONV
+    /* convert end-of-line markers */
+    len = convert_lineends(data, ptr, len);
+#endif /* CURL_DO_LINEEND_CONV */
+    }
+
+  return Curl_client_chop_write(conn, type, ptr, len);
+}
+
+CURLcode Curl_read_plain(curl_socket_t sockfd,
+                         char *buf,
+                         size_t bytesfromsocket,
+                         ssize_t *n)
+{
+  ssize_t nread = sread(sockfd, buf, bytesfromsocket);
+
+  if(-1 == nread) {
+    int err = SOCKERRNO;
+    int return_error;
+#ifdef USE_WINSOCK
+    return_error = WSAEWOULDBLOCK == err;
+#else
+    return_error = EWOULDBLOCK == err || EAGAIN == err || EINTR == err;
+#endif
+    if(return_error)
+      return CURLE_AGAIN;
+    return CURLE_RECV_ERROR;
+  }
+
+  /* we only return number of bytes read when we return OK */
+  *n = nread;
+  return CURLE_OK;
+}
+
+/*
+ * Internal read-from-socket function. This is meant to deal with plain
+ * sockets, SSL sockets and kerberos sockets.
+ *
+ * Returns a regular CURLcode value.
+ */
+CURLcode Curl_read(struct connectdata *conn, /* connection data */
+                   curl_socket_t sockfd,     /* read from this socket */
+                   char *buf,                /* store read data here */
+                   size_t sizerequested,     /* max amount to read */
+                   ssize_t *n)               /* amount bytes read */
+{
+  CURLcode result = CURLE_RECV_ERROR;
+  ssize_t nread = 0;
+  size_t bytesfromsocket = 0;
+  char *buffertofill = NULL;
+  struct Curl_easy *data = conn->data;
+
+  /* if HTTP/1 pipelining is both wanted and possible */
+  bool pipelining = Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1) &&
+    (conn->bundle->multiuse == BUNDLE_PIPELINING);
+
+  /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
+     If it is the second socket, we set num to 1. Otherwise to 0. This lets
+     us use the correct ssl handle. */
+  int num = (sockfd == conn->sock[SECONDARYSOCKET]);
+
+  *n = 0; /* reset amount to zero */
+
+  /* If session can pipeline, check connection buffer  */
+  if(pipelining) {
+    size_t bytestocopy = CURLMIN(conn->buf_len - conn->read_pos,
+                                 sizerequested);
+
+    /* Copy from our master buffer first if we have some unread data there*/
+    if(bytestocopy > 0) {
+      memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
+      conn->read_pos += bytestocopy;
+      conn->bits.stream_was_rewound = FALSE;
+
+      *n = (ssize_t)bytestocopy;
+      return CURLE_OK;
+    }
+    /* If we come here, it means that there is no data to read from the buffer,
+     * so we read from the socket */
+    bytesfromsocket = CURLMIN(sizerequested, MASTERBUF_SIZE);
+    buffertofill = conn->master_buffer;
+  }
+  else {
+    bytesfromsocket = CURLMIN(sizerequested, (size_t)data->set.buffer_size);
+    buffertofill = buf;
+  }
+
+  nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &result);
+  if(nread < 0)
+    return result;
+
+  if(pipelining) {
+    memcpy(buf, conn->master_buffer, nread);
+    conn->buf_len = nread;
+    conn->read_pos = nread;
+  }
+
+  *n += nread;
+
+  return CURLE_OK;
+}
+
+/* return 0 on success */
+static int showit(struct Curl_easy *data, curl_infotype type,
+                  char *ptr, size_t size)
+{
+  static const char s_infotype[CURLINFO_END][3] = {
+    "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
+  int rc = 0;
+
+#ifdef CURL_DOES_CONVERSIONS
+  char *buf = NULL;
+  size_t conv_size = 0;
+
+  switch(type) {
+  case CURLINFO_HEADER_OUT:
+    buf = Curl_memdup(ptr, size);
+    if(!buf)
+      return 1;
+    conv_size = size;
+
+    /* Special processing is needed for this block if it
+     * contains both headers and data (separated by CRLFCRLF).
+     * We want to convert just the headers, leaving the data as-is.
+     */
+    if(size > 4) {
+      size_t i;
+      for(i = 0; i < size-4; i++) {
+        if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
+          /* convert everything through this CRLFCRLF but no further */
+          conv_size = i + 4;
+          break;
+        }
+      }
+    }
+
+    Curl_convert_from_network(data, buf, conv_size);
+    /* Curl_convert_from_network calls failf if unsuccessful */
+    /* we might as well continue even if it fails...   */
+    ptr = buf; /* switch pointer to use my buffer instead */
+    break;
+  default:
+    /* leave everything else as-is */
+    break;
+  }
+#endif /* CURL_DOES_CONVERSIONS */
+
+  if(data->set.fdebug)
+    rc = (*data->set.fdebug)(data, type, ptr, size, data->set.debugdata);
+  else {
+    switch(type) {
+    case CURLINFO_TEXT:
+    case CURLINFO_HEADER_OUT:
+    case CURLINFO_HEADER_IN:
+      fwrite(s_infotype[type], 2, 1, data->set.err);
+      fwrite(ptr, size, 1, data->set.err);
+#ifdef CURL_DOES_CONVERSIONS
+      if(size != conv_size) {
+        /* we had untranslated data so we need an explicit newline */
+        fwrite("\n", 1, 1, data->set.err);
+      }
+#endif
+      break;
+    default: /* nada */
+      break;
+    }
+  }
+#ifdef CURL_DOES_CONVERSIONS
+  free(buf);
+#endif
+  return rc;
+}
+
+int Curl_debug(struct Curl_easy *data, curl_infotype type,
+               char *ptr, size_t size,
+               struct connectdata *conn)
+{
+  int rc;
+  if(data->set.printhost && conn && conn->host.dispname) {
+    char buffer[160];
+    const char *t = NULL;
+    const char *w = "Data";
+    switch(type) {
+    case CURLINFO_HEADER_IN:
+      w = "Header";
+      /* FALLTHROUGH */
+    case CURLINFO_DATA_IN:
+      t = "from";
+      break;
+    case CURLINFO_HEADER_OUT:
+      w = "Header";
+      /* FALLTHROUGH */
+    case CURLINFO_DATA_OUT:
+      t = "to";
+      break;
+    default:
+      break;
+    }
+
+    if(t) {
+      snprintf(buffer, sizeof(buffer), "[%s %s %s]", w, t,
+               conn->host.dispname);
+      rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer));
+      if(rc)
+        return rc;
+    }
+  }
+  rc = showit(data, type, ptr, size);
+  return rc;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/sendf.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/sendf.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/sendf.h	(revision 331)
@@ -0,0 +1,94 @@
+#ifndef HEADER_CURL_SENDF_H
+#define HEADER_CURL_SENDF_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *,
+                    const char *fmt, ...);
+void Curl_infof(struct Curl_easy *, const char *fmt, ...);
+void Curl_failf(struct Curl_easy *, const char *fmt, ...);
+
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+
+#if defined(HAVE_VARIADIC_MACROS_C99)
+#define infof(...)  Curl_nop_stmt
+#elif defined(HAVE_VARIADIC_MACROS_GCC)
+#define infof(x...)  Curl_nop_stmt
+#else
+#define infof (void)
+#endif
+
+#else /* CURL_DISABLE_VERBOSE_STRINGS */
+
+#define infof Curl_infof
+
+#endif /* CURL_DISABLE_VERBOSE_STRINGS */
+
+#define failf Curl_failf
+
+#define CLIENTWRITE_BODY   (1<<0)
+#define CLIENTWRITE_HEADER (1<<1)
+#define CLIENTWRITE_BOTH   (CLIENTWRITE_BODY|CLIENTWRITE_HEADER)
+
+CURLcode Curl_client_chop_write(struct connectdata *conn, int type, char *ptr,
+                                size_t len) WARN_UNUSED_RESULT;
+CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr,
+                           size_t len) WARN_UNUSED_RESULT;
+
+bool Curl_recv_has_postponed_data(struct connectdata *conn, int sockindex);
+
+/* internal read-function, does plain socket only */
+CURLcode Curl_read_plain(curl_socket_t sockfd,
+                         char *buf,
+                         size_t bytesfromsocket,
+                         ssize_t *n);
+
+ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
+                        size_t len, CURLcode *code);
+ssize_t Curl_send_plain(struct connectdata *conn, int num,
+                        const void *mem, size_t len, CURLcode *code);
+
+/* internal read-function, does plain socket, SSL and krb4 */
+CURLcode Curl_read(struct connectdata *conn, curl_socket_t sockfd,
+                   char *buf, size_t buffersize,
+                   ssize_t *n);
+/* internal write-function, does plain socket, SSL, SCP, SFTP and krb4 */
+CURLcode Curl_write(struct connectdata *conn,
+                    curl_socket_t sockfd,
+                    const void *mem, size_t len,
+                    ssize_t *written);
+
+/* internal write-function, does plain sockets ONLY */
+CURLcode Curl_write_plain(struct connectdata *conn,
+                          curl_socket_t sockfd,
+                          const void *mem, size_t len,
+                          ssize_t *written);
+
+/* the function used to output verbose information */
+int Curl_debug(struct Curl_easy *handle, curl_infotype type,
+               char *data, size_t size,
+               struct connectdata *conn);
+
+
+#endif /* HEADER_CURL_SENDF_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/setopt.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/setopt.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/setopt.c	(revision 331)
@@ -0,0 +1,2554 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#ifdef HAVE_LINUX_TCP_H
+#include <linux/tcp.h>
+#endif
+
+#include "urldata.h"
+#include "url.h"
+#include "progress.h"
+#include "content_encoding.h"
+#include "strcase.h"
+#include "share.h"
+#include "vtls/vtls.h"
+#include "warnless.h"
+#include "sendf.h"
+#include "http2.h"
+#include "setopt.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+CURLcode Curl_setstropt(char **charp, const char *s)
+{
+  /* Release the previous storage at `charp' and replace by a dynamic storage
+     copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */
+
+  Curl_safefree(*charp);
+
+  if(s) {
+    char *str = strdup(s);
+
+    if(!str)
+      return CURLE_OUT_OF_MEMORY;
+
+    *charp = str;
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp)
+{
+  CURLcode result = CURLE_OK;
+  char *user = NULL;
+  char *passwd = NULL;
+
+  /* Parse the login details if specified. It not then we treat NULL as a hint
+     to clear the existing data */
+  if(option) {
+    result = Curl_parse_login_details(option, strlen(option),
+                                      (userp ? &user : NULL),
+                                      (passwdp ? &passwd : NULL),
+                                      NULL);
+  }
+
+  if(!result) {
+    /* Store the username part of option if required */
+    if(userp) {
+      if(!user && option && option[0] == ':') {
+        /* Allocate an empty string instead of returning NULL as user name */
+        user = strdup("");
+        if(!user)
+          result = CURLE_OUT_OF_MEMORY;
+      }
+
+      Curl_safefree(*userp);
+      *userp = user;
+    }
+
+    /* Store the password part of option if required */
+    if(passwdp) {
+      Curl_safefree(*passwdp);
+      *passwdp = passwd;
+    }
+  }
+
+  return result;
+}
+
+#define C_SSLVERSION_VALUE(x) (x & 0xffff)
+#define C_SSLVERSION_MAX_VALUE(x) (x & 0xffff0000)
+
+static CURLcode setopt(struct Curl_easy *data, CURLoption option,
+                       va_list param)
+{
+  char *argptr;
+  CURLcode result = CURLE_OK;
+  long arg;
+  curl_off_t bigsize;
+
+  switch(option) {
+  case CURLOPT_DNS_CACHE_TIMEOUT:
+    arg = va_arg(param, long);
+    if(arg < -1)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.dns_cache_timeout = arg;
+    break;
+  case CURLOPT_DNS_USE_GLOBAL_CACHE:
+    /* remember we want this enabled */
+    arg = va_arg(param, long);
+    data->set.global_dns_cache = (0 != arg) ? TRUE : FALSE;
+    break;
+  case CURLOPT_SSL_CIPHER_LIST:
+    /* set a list of cipher we want to use in the SSL connection */
+    result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_ORIG],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_PROXY_SSL_CIPHER_LIST:
+    /* set a list of cipher we want to use in the SSL connection for proxy */
+    result = Curl_setstropt(&data->set.str[STRING_SSL_CIPHER_LIST_PROXY],
+                            va_arg(param, char *));
+    break;
+
+  case CURLOPT_RANDOM_FILE:
+    /*
+     * This is the path name to a file that contains random data to seed
+     * the random SSL stuff with. The file is only used for reading.
+     */
+    result = Curl_setstropt(&data->set.str[STRING_SSL_RANDOM_FILE],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_EGDSOCKET:
+    /*
+     * The Entropy Gathering Daemon socket pathname
+     */
+    result = Curl_setstropt(&data->set.str[STRING_SSL_EGDSOCKET],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_MAXCONNECTS:
+    /*
+     * Set the absolute number of maximum simultaneous alive connection that
+     * libcurl is allowed to have.
+     */
+    arg = va_arg(param, long);
+    if(arg < 0)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.maxconnects = arg;
+    break;
+  case CURLOPT_FORBID_REUSE:
+    /*
+     * When this transfer is done, it must not be left to be reused by a
+     * subsequent transfer but shall be closed immediately.
+     */
+    data->set.reuse_forbid = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+  case CURLOPT_FRESH_CONNECT:
+    /*
+     * This transfer shall not use a previously cached connection but
+     * should be made with a fresh new connect!
+     */
+    data->set.reuse_fresh = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+  case CURLOPT_VERBOSE:
+    /*
+     * Verbose means infof() calls that give a lot of information about
+     * the connection and transfer procedures as well as internal choices.
+     */
+    data->set.verbose = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+  case CURLOPT_HEADER:
+    /*
+     * Set to include the header in the general data output stream.
+     */
+    data->set.include_header = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+  case CURLOPT_NOPROGRESS:
+    /*
+     * Shut off the internal supported progress meter
+     */
+    data->set.hide_progress = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    if(data->set.hide_progress)
+      data->progress.flags |= PGRS_HIDE;
+    else
+      data->progress.flags &= ~PGRS_HIDE;
+    break;
+  case CURLOPT_NOBODY:
+    /*
+     * Do not include the body part in the output data stream.
+     */
+    data->set.opt_no_body = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+  case CURLOPT_FAILONERROR:
+    /*
+     * Don't output the >=400 error code HTML-page, but instead only
+     * return error.
+     */
+    data->set.http_fail_on_error = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+  case CURLOPT_KEEP_SENDING_ON_ERROR:
+    data->set.http_keep_sending_on_error = (0 != va_arg(param, long)) ?
+      TRUE : FALSE;
+    break;
+  case CURLOPT_UPLOAD:
+  case CURLOPT_PUT:
+    /*
+     * We want to sent data to the remote host. If this is HTTP, that equals
+     * using the PUT request.
+     */
+    data->set.upload = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    if(data->set.upload) {
+      /* If this is HTTP, PUT is what's needed to "upload" */
+      data->set.httpreq = HTTPREQ_PUT;
+      data->set.opt_no_body = FALSE; /* this is implied */
+    }
+    else
+      /* In HTTP, the opposite of upload is GET (unless NOBODY is true as
+         then this can be changed to HEAD later on) */
+      data->set.httpreq = HTTPREQ_GET;
+    break;
+  case CURLOPT_REQUEST_TARGET:
+    result = Curl_setstropt(&data->set.str[STRING_TARGET],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_FILETIME:
+    /*
+     * Try to get the file time of the remote document. The time will
+     * later (possibly) become available using curl_easy_getinfo().
+     */
+    data->set.get_filetime = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+  case CURLOPT_FTP_CREATE_MISSING_DIRS:
+    /*
+     * An FTP option that modifies an upload to create missing directories on
+     * the server.
+     */
+    switch(va_arg(param, long)) {
+    case 0:
+      data->set.ftp_create_missing_dirs = 0;
+      break;
+    case 1:
+      data->set.ftp_create_missing_dirs = 1;
+      break;
+    case 2:
+      data->set.ftp_create_missing_dirs = 2;
+      break;
+    default:
+      /* reserve other values for future use */
+      result = CURLE_UNKNOWN_OPTION;
+      break;
+    }
+    break;
+  case CURLOPT_SERVER_RESPONSE_TIMEOUT:
+    /*
+     * Option that specifies how quickly an server response must be obtained
+     * before it is considered failure. For pingpong protocols.
+     */
+    arg = va_arg(param, long);
+    if((arg >= 0) && (arg < (INT_MAX/1000)))
+      data->set.server_response_timeout = arg * 1000;
+    else
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    break;
+  case CURLOPT_TFTP_NO_OPTIONS:
+    /*
+     * Option that prevents libcurl from sending TFTP option requests to the
+     * server.
+     */
+    data->set.tftp_no_options = va_arg(param, long) != 0;
+    break;
+  case CURLOPT_TFTP_BLKSIZE:
+    /*
+     * TFTP option that specifies the block size to use for data transmission.
+     */
+    arg = va_arg(param, long);
+    if(arg < 0)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.tftp_blksize = arg;
+    break;
+  case CURLOPT_DIRLISTONLY:
+    /*
+     * An option that changes the command to one that asks for a list
+     * only, no file info details.
+     */
+    data->set.ftp_list_only = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+  case CURLOPT_APPEND:
+    /*
+     * We want to upload and append to an existing file.
+     */
+    data->set.ftp_append = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+  case CURLOPT_FTP_FILEMETHOD:
+    /*
+     * How do access files over FTP.
+     */
+    arg = va_arg(param, long);
+    if((arg < CURLFTPMETHOD_DEFAULT) || (arg > CURLFTPMETHOD_SINGLECWD))
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.ftp_filemethod = (curl_ftpfile)arg;
+    break;
+  case CURLOPT_NETRC:
+    /*
+     * Parse the $HOME/.netrc file
+     */
+    arg = va_arg(param, long);
+    if((arg < CURL_NETRC_IGNORED) || (arg > CURL_NETRC_REQUIRED))
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.use_netrc = (enum CURL_NETRC_OPTION)arg;
+    break;
+  case CURLOPT_NETRC_FILE:
+    /*
+     * Use this file instead of the $HOME/.netrc file
+     */
+    result = Curl_setstropt(&data->set.str[STRING_NETRC_FILE],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_TRANSFERTEXT:
+    /*
+     * This option was previously named 'FTPASCII'. Renamed to work with
+     * more protocols than merely FTP.
+     *
+     * Transfer using ASCII (instead of BINARY).
+     */
+    data->set.prefer_ascii = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+  case CURLOPT_TIMECONDITION:
+    /*
+     * Set HTTP time condition. This must be one of the defines in the
+     * curl/curl.h header file.
+     */
+    arg = va_arg(param, long);
+    if((arg < CURL_TIMECOND_NONE) || (arg > CURL_TIMECOND_LASTMOD))
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.timecondition = (curl_TimeCond)arg;
+    break;
+  case CURLOPT_TIMEVALUE:
+    /*
+     * This is the value to compare with the remote document with the
+     * method set with CURLOPT_TIMECONDITION
+     */
+    data->set.timevalue = (time_t)va_arg(param, long);
+    break;
+  case CURLOPT_SSLVERSION:
+    /*
+     * Set explicit SSL version to try to connect with, as some SSL
+     * implementations are lame.
+     */
+#ifdef USE_SSL
+    arg = va_arg(param, long);
+    if((arg < CURL_SSLVERSION_DEFAULT) || (arg > CURL_SSLVERSION_TLSv1_3))
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.ssl.primary.version = C_SSLVERSION_VALUE(arg);
+    data->set.ssl.primary.version_max = C_SSLVERSION_MAX_VALUE(arg);
+#else
+    result = CURLE_UNKNOWN_OPTION;
+#endif
+    break;
+  case CURLOPT_PROXY_SSLVERSION:
+    /*
+     * Set explicit SSL version to try to connect with for proxy, as some SSL
+     * implementations are lame.
+     */
+#ifdef USE_SSL
+    arg = va_arg(param, long);
+    if((arg < CURL_SSLVERSION_DEFAULT) || (arg > CURL_SSLVERSION_TLSv1_3))
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.proxy_ssl.primary.version = C_SSLVERSION_VALUE(arg);
+    data->set.proxy_ssl.primary.version_max = C_SSLVERSION_MAX_VALUE(arg);
+#else
+    result = CURLE_UNKNOWN_OPTION;
+#endif
+    break;
+
+#ifndef CURL_DISABLE_HTTP
+  case CURLOPT_AUTOREFERER:
+    /*
+     * Switch on automatic referer that gets set if curl follows locations.
+     */
+    data->set.http_auto_referer = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_ACCEPT_ENCODING:
+    /*
+     * String to use at the value of Accept-Encoding header.
+     *
+     * If the encoding is set to "" we use an Accept-Encoding header that
+     * encompasses all the encodings we support.
+     * If the encoding is set to NULL we don't send an Accept-Encoding header
+     * and ignore an received Content-Encoding header.
+     *
+     */
+    argptr = va_arg(param, char *);
+    if(argptr && !*argptr) {
+      argptr = Curl_all_content_encodings();
+      if(!argptr)
+        result = CURLE_OUT_OF_MEMORY;
+      else {
+        result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr);
+        free(argptr);
+      }
+    }
+    else
+      result = Curl_setstropt(&data->set.str[STRING_ENCODING], argptr);
+    break;
+
+  case CURLOPT_TRANSFER_ENCODING:
+    data->set.http_transfer_encoding = (0 != va_arg(param, long)) ?
+      TRUE : FALSE;
+    break;
+
+  case CURLOPT_FOLLOWLOCATION:
+    /*
+     * Follow Location: header hints on a HTTP-server.
+     */
+    data->set.http_follow_location = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_UNRESTRICTED_AUTH:
+    /*
+     * Send authentication (user+password) when following locations, even when
+     * hostname changed.
+     */
+    data->set.http_disable_hostname_check_before_authentication =
+      (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_MAXREDIRS:
+    /*
+     * The maximum amount of hops you allow curl to follow Location:
+     * headers. This should mostly be used to detect never-ending loops.
+     */
+    arg = va_arg(param, long);
+    if(arg < -1)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.maxredirs = arg;
+    break;
+
+  case CURLOPT_POSTREDIR:
+    /*
+     * Set the behaviour of POST when redirecting
+     * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
+     * CURL_REDIR_POST_301 - POST is kept as POST after 301
+     * CURL_REDIR_POST_302 - POST is kept as POST after 302
+     * CURL_REDIR_POST_303 - POST is kept as POST after 303
+     * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303
+     * other - POST is kept as POST after 301 and 302
+     */
+    arg = va_arg(param, long);
+    if(arg < CURL_REDIR_GET_ALL)
+      /* no return error on too high numbers since the bitmask could be
+         extended in a future */
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.keep_post = arg & CURL_REDIR_POST_ALL;
+    break;
+
+  case CURLOPT_POST:
+    /* Does this option serve a purpose anymore? Yes it does, when
+       CURLOPT_POSTFIELDS isn't used and the POST data is read off the
+       callback! */
+    if(va_arg(param, long)) {
+      data->set.httpreq = HTTPREQ_POST;
+      data->set.opt_no_body = FALSE; /* this is implied */
+    }
+    else
+      data->set.httpreq = HTTPREQ_GET;
+    break;
+
+  case CURLOPT_COPYPOSTFIELDS:
+    /*
+     * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
+     * If needed, CURLOPT_POSTFIELDSIZE must have been set prior to
+     *  CURLOPT_COPYPOSTFIELDS and not altered later.
+     */
+    argptr = va_arg(param, char *);
+
+    if(!argptr || data->set.postfieldsize == -1)
+      result = Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr);
+    else {
+      /*
+       *  Check that requested length does not overflow the size_t type.
+       */
+
+      if((data->set.postfieldsize < 0) ||
+         ((sizeof(curl_off_t) != sizeof(size_t)) &&
+          (data->set.postfieldsize > (curl_off_t)((size_t)-1))))
+        result = CURLE_OUT_OF_MEMORY;
+      else {
+        char *p;
+
+        (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
+
+        /* Allocate even when size == 0. This satisfies the need of possible
+           later address compare to detect the COPYPOSTFIELDS mode, and
+           to mark that postfields is used rather than read function or
+           form data.
+        */
+        p = malloc((size_t)(data->set.postfieldsize?
+                            data->set.postfieldsize:1));
+
+        if(!p)
+          result = CURLE_OUT_OF_MEMORY;
+        else {
+          if(data->set.postfieldsize)
+            memcpy(p, argptr, (size_t)data->set.postfieldsize);
+
+          data->set.str[STRING_COPYPOSTFIELDS] = p;
+        }
+      }
+    }
+
+    data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS];
+    data->set.httpreq = HTTPREQ_POST;
+    break;
+
+  case CURLOPT_POSTFIELDS:
+    /*
+     * Like above, but use static data instead of copying it.
+     */
+    data->set.postfields = va_arg(param, void *);
+    /* Release old copied data. */
+    (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
+    data->set.httpreq = HTTPREQ_POST;
+    break;
+
+  case CURLOPT_POSTFIELDSIZE:
+    /*
+     * The size of the POSTFIELD data to prevent libcurl to do strlen() to
+     * figure it out. Enables binary posts.
+     */
+    bigsize = va_arg(param, long);
+    if(bigsize < -1)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+
+    if(data->set.postfieldsize < bigsize &&
+       data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
+      /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
+      (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
+      data->set.postfields = NULL;
+    }
+
+    data->set.postfieldsize = bigsize;
+    break;
+
+  case CURLOPT_POSTFIELDSIZE_LARGE:
+    /*
+     * The size of the POSTFIELD data to prevent libcurl to do strlen() to
+     * figure it out. Enables binary posts.
+     */
+    bigsize = va_arg(param, curl_off_t);
+    if(bigsize < -1)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+
+    if(data->set.postfieldsize < bigsize &&
+       data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
+      /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
+      (void) Curl_setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
+      data->set.postfields = NULL;
+    }
+
+    data->set.postfieldsize = bigsize;
+    break;
+
+  case CURLOPT_HTTPPOST:
+    /*
+     * Set to make us do HTTP POST
+     */
+    data->set.httppost = va_arg(param, struct curl_httppost *);
+    data->set.httpreq = HTTPREQ_POST_FORM;
+    data->set.opt_no_body = FALSE; /* this is implied */
+    break;
+#endif   /* CURL_DISABLE_HTTP */
+
+  case CURLOPT_MIMEPOST:
+    /*
+     * Set to make us do MIME/form POST
+     */
+    result = Curl_mime_set_subparts(&data->set.mimepost,
+                                    va_arg(param, curl_mime *), FALSE);
+    if(!result) {
+      data->set.httpreq = HTTPREQ_POST_MIME;
+      data->set.opt_no_body = FALSE; /* this is implied */
+    }
+    break;
+
+  case CURLOPT_REFERER:
+    /*
+     * String to set in the HTTP Referer: field.
+     */
+    if(data->change.referer_alloc) {
+      Curl_safefree(data->change.referer);
+      data->change.referer_alloc = FALSE;
+    }
+    result = Curl_setstropt(&data->set.str[STRING_SET_REFERER],
+                            va_arg(param, char *));
+    data->change.referer = data->set.str[STRING_SET_REFERER];
+    break;
+
+  case CURLOPT_USERAGENT:
+    /*
+     * String to use in the HTTP User-Agent field
+     */
+    result = Curl_setstropt(&data->set.str[STRING_USERAGENT],
+                            va_arg(param, char *));
+    break;
+
+  case CURLOPT_HTTPHEADER:
+    /*
+     * Set a list with HTTP headers to use (or replace internals with)
+     */
+    data->set.headers = va_arg(param, struct curl_slist *);
+    break;
+
+#ifndef CURL_DISABLE_HTTP
+  case CURLOPT_PROXYHEADER:
+    /*
+     * Set a list with proxy headers to use (or replace internals with)
+     *
+     * Since CURLOPT_HTTPHEADER was the only way to set HTTP headers for a
+     * long time we remain doing it this way until CURLOPT_PROXYHEADER is
+     * used. As soon as this option has been used, if set to anything but
+     * NULL, custom headers for proxies are only picked from this list.
+     *
+     * Set this option to NULL to restore the previous behavior.
+     */
+    data->set.proxyheaders = va_arg(param, struct curl_slist *);
+    break;
+
+  case CURLOPT_HEADEROPT:
+    /*
+     * Set header option.
+     */
+    arg = va_arg(param, long);
+    data->set.sep_headers = (arg & CURLHEADER_SEPARATE)? TRUE: FALSE;
+    break;
+
+  case CURLOPT_HTTP200ALIASES:
+    /*
+     * Set a list of aliases for HTTP 200 in response header
+     */
+    data->set.http200aliases = va_arg(param, struct curl_slist *);
+    break;
+
+#if !defined(CURL_DISABLE_COOKIES)
+  case CURLOPT_COOKIE:
+    /*
+     * Cookie string to send to the remote server in the request.
+     */
+    result = Curl_setstropt(&data->set.str[STRING_COOKIE],
+                            va_arg(param, char *));
+    break;
+
+  case CURLOPT_COOKIEFILE:
+    /*
+     * Set cookie file to read and parse. Can be used multiple times.
+     */
+    argptr = (char *)va_arg(param, void *);
+    if(argptr) {
+      struct curl_slist *cl;
+      /* append the cookie file name to the list of file names, and deal with
+         them later */
+      cl = curl_slist_append(data->change.cookielist, argptr);
+      if(!cl) {
+        curl_slist_free_all(data->change.cookielist);
+        data->change.cookielist = NULL;
+        return CURLE_OUT_OF_MEMORY;
+      }
+      data->change.cookielist = cl; /* store the list for later use */
+    }
+    break;
+
+  case CURLOPT_COOKIEJAR:
+    /*
+     * Set cookie file name to dump all cookies to when we're done.
+     */
+  {
+    struct CookieInfo *newcookies;
+    result = Curl_setstropt(&data->set.str[STRING_COOKIEJAR],
+                            va_arg(param, char *));
+
+    /*
+     * Activate the cookie parser. This may or may not already
+     * have been made.
+     */
+    newcookies = Curl_cookie_init(data, NULL, data->cookies,
+                                  data->set.cookiesession);
+    if(!newcookies)
+      result = CURLE_OUT_OF_MEMORY;
+    data->cookies = newcookies;
+  }
+  break;
+
+  case CURLOPT_COOKIESESSION:
+    /*
+     * Set this option to TRUE to start a new "cookie session". It will
+     * prevent the forthcoming read-cookies-from-file actions to accept
+     * cookies that are marked as being session cookies, as they belong to a
+     * previous session.
+     *
+     * In the original Netscape cookie spec, "session cookies" are cookies
+     * with no expire date set. RFC2109 describes the same action if no
+     * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
+     * a 'Discard' action that can enforce the discard even for cookies that
+     * have a Max-Age.
+     *
+     * We run mostly with the original cookie spec, as hardly anyone implements
+     * anything else.
+     */
+    data->set.cookiesession = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_COOKIELIST:
+    argptr = va_arg(param, char *);
+
+    if(argptr == NULL)
+      break;
+
+    if(strcasecompare(argptr, "ALL")) {
+      /* clear all cookies */
+      Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+      Curl_cookie_clearall(data->cookies);
+      Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+    }
+    else if(strcasecompare(argptr, "SESS")) {
+      /* clear session cookies */
+      Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+      Curl_cookie_clearsess(data->cookies);
+      Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+    }
+    else if(strcasecompare(argptr, "FLUSH")) {
+      /* flush cookies to file, takes care of the locking */
+      Curl_flush_cookies(data, 0);
+    }
+    else if(strcasecompare(argptr, "RELOAD")) {
+      /* reload cookies from file */
+      Curl_cookie_loadfiles(data);
+      break;
+    }
+    else {
+      if(!data->cookies)
+        /* if cookie engine was not running, activate it */
+        data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE);
+
+      argptr = strdup(argptr);
+      if(!argptr || !data->cookies) {
+        result = CURLE_OUT_OF_MEMORY;
+        free(argptr);
+      }
+      else {
+        Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
+
+        if(checkprefix("Set-Cookie:", argptr))
+          /* HTTP Header format line */
+          Curl_cookie_add(data, data->cookies, TRUE, argptr + 11, NULL, NULL);
+
+        else
+          /* Netscape format line */
+          Curl_cookie_add(data, data->cookies, FALSE, argptr, NULL, NULL);
+
+        Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
+        free(argptr);
+      }
+    }
+
+    break;
+#endif /* !CURL_DISABLE_COOKIES */
+
+  case CURLOPT_HTTPGET:
+    /*
+     * Set to force us do HTTP GET
+     */
+    if(va_arg(param, long)) {
+      data->set.httpreq = HTTPREQ_GET;
+      data->set.upload = FALSE; /* switch off upload */
+      data->set.opt_no_body = FALSE; /* this is implied */
+    }
+    break;
+
+  case CURLOPT_HTTP_VERSION:
+    /*
+     * This sets a requested HTTP version to be used. The value is one of
+     * the listed enums in curl/curl.h.
+     */
+    arg = va_arg(param, long);
+    if(arg < CURL_HTTP_VERSION_NONE)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+#ifndef USE_NGHTTP2
+    if(arg >= CURL_HTTP_VERSION_2)
+      return CURLE_UNSUPPORTED_PROTOCOL;
+#else
+    if(arg > CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE)
+      return CURLE_UNSUPPORTED_PROTOCOL;
+#endif
+    data->set.httpversion = arg;
+    break;
+
+  case CURLOPT_EXPECT_100_TIMEOUT_MS:
+    /*
+     * Time to wait for a response to a HTTP request containing an
+     * Expect: 100-continue header before sending the data anyway.
+     */
+    arg = va_arg(param, long);
+    if(arg < 0)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.expect_100_timeout = arg;
+    break;
+
+#endif   /* CURL_DISABLE_HTTP */
+
+  case CURLOPT_HTTPAUTH:
+    /*
+     * Set HTTP Authentication type BITMASK.
+     */
+  {
+    int bitcheck;
+    bool authbits;
+    unsigned long auth = va_arg(param, unsigned long);
+
+    if(auth == CURLAUTH_NONE) {
+      data->set.httpauth = auth;
+      break;
+    }
+
+    /* the DIGEST_IE bit is only used to set a special marker, for all the
+       rest we need to handle it as normal DIGEST */
+    data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE;
+
+    if(auth & CURLAUTH_DIGEST_IE) {
+      auth |= CURLAUTH_DIGEST; /* set standard digest bit */
+      auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
+    }
+
+    /* switch off bits we can't support */
+#ifndef USE_NTLM
+    auth &= ~CURLAUTH_NTLM;    /* no NTLM support */
+    auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
+#elif !defined(NTLM_WB_ENABLED)
+    auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
+#endif
+#ifndef USE_SPNEGO
+    auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
+                                    GSS-API or SSPI */
+#endif
+
+    /* check if any auth bit lower than CURLAUTH_ONLY is still set */
+    bitcheck = 0;
+    authbits = FALSE;
+    while(bitcheck < 31) {
+      if(auth & (1UL << bitcheck++)) {
+        authbits = TRUE;
+        break;
+      }
+    }
+    if(!authbits)
+      return CURLE_NOT_BUILT_IN; /* no supported types left! */
+
+    data->set.httpauth = auth;
+  }
+  break;
+
+  case CURLOPT_CUSTOMREQUEST:
+    /*
+     * Set a custom string to use as request
+     */
+    result = Curl_setstropt(&data->set.str[STRING_CUSTOMREQUEST],
+                            va_arg(param, char *));
+
+    /* we don't set
+       data->set.httpreq = HTTPREQ_CUSTOM;
+       here, we continue as if we were using the already set type
+       and this just changes the actual request keyword */
+    break;
+
+#ifndef CURL_DISABLE_PROXY
+  case CURLOPT_HTTPPROXYTUNNEL:
+    /*
+     * Tunnel operations through the proxy instead of normal proxy use
+     */
+    data->set.tunnel_thru_httpproxy = (0 != va_arg(param, long)) ?
+      TRUE : FALSE;
+    break;
+
+  case CURLOPT_PROXYPORT:
+    /*
+     * Explicitly set HTTP proxy port number.
+     */
+    arg = va_arg(param, long);
+    if((arg < 0) || (arg > 65535))
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.proxyport = arg;
+    break;
+
+  case CURLOPT_PROXYAUTH:
+    /*
+     * Set HTTP Authentication type BITMASK.
+     */
+  {
+    int bitcheck;
+    bool authbits;
+    unsigned long auth = va_arg(param, unsigned long);
+
+    if(auth == CURLAUTH_NONE) {
+      data->set.proxyauth = auth;
+      break;
+    }
+
+    /* the DIGEST_IE bit is only used to set a special marker, for all the
+       rest we need to handle it as normal DIGEST */
+    data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE;
+
+    if(auth & CURLAUTH_DIGEST_IE) {
+      auth |= CURLAUTH_DIGEST; /* set standard digest bit */
+      auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
+    }
+    /* switch off bits we can't support */
+#ifndef USE_NTLM
+    auth &= ~CURLAUTH_NTLM;    /* no NTLM support */
+    auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
+#elif !defined(NTLM_WB_ENABLED)
+    auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
+#endif
+#ifndef USE_SPNEGO
+    auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without
+                                    GSS-API or SSPI */
+#endif
+
+    /* check if any auth bit lower than CURLAUTH_ONLY is still set */
+    bitcheck = 0;
+    authbits = FALSE;
+    while(bitcheck < 31) {
+      if(auth & (1UL << bitcheck++)) {
+        authbits = TRUE;
+        break;
+      }
+    }
+    if(!authbits)
+      return CURLE_NOT_BUILT_IN; /* no supported types left! */
+
+    data->set.proxyauth = auth;
+  }
+  break;
+
+  case CURLOPT_PROXY:
+    /*
+     * Set proxy server:port to use as proxy.
+     *
+     * If the proxy is set to "" (and CURLOPT_SOCKS_PROXY is set to "" or NULL)
+     * we explicitly say that we don't want to use a proxy
+     * (even though there might be environment variables saying so).
+     *
+     * Setting it to NULL, means no proxy but allows the environment variables
+     * to decide for us (if CURLOPT_SOCKS_PROXY setting it to NULL).
+     */
+    result = Curl_setstropt(&data->set.str[STRING_PROXY],
+                            va_arg(param, char *));
+    break;
+
+  case CURLOPT_PRE_PROXY:
+    /*
+     * Set proxy server:port to use as SOCKS proxy.
+     *
+     * If the proxy is set to "" or NULL we explicitly say that we don't want
+     * to use the socks proxy.
+     */
+    result = Curl_setstropt(&data->set.str[STRING_PRE_PROXY],
+                            va_arg(param, char *));
+    break;
+
+  case CURLOPT_PROXYTYPE:
+    /*
+     * Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME
+     */
+    arg = va_arg(param, long);
+    if((arg < CURLPROXY_HTTP) || (arg > CURLPROXY_SOCKS5_HOSTNAME))
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.proxytype = (curl_proxytype)arg;
+    break;
+
+  case CURLOPT_PROXY_TRANSFER_MODE:
+    /*
+     * set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy
+     */
+    switch(va_arg(param, long)) {
+    case 0:
+      data->set.proxy_transfer_mode = FALSE;
+      break;
+    case 1:
+      data->set.proxy_transfer_mode = TRUE;
+      break;
+    default:
+      /* reserve other values for future use */
+      result = CURLE_UNKNOWN_OPTION;
+      break;
+    }
+    break;
+#endif   /* CURL_DISABLE_PROXY */
+
+  case CURLOPT_SOCKS5_AUTH:
+    data->set.socks5auth = va_arg(param, unsigned long);
+    if(data->set.socks5auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI))
+      result = CURLE_NOT_BUILT_IN;
+    break;
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  case CURLOPT_SOCKS5_GSSAPI_NEC:
+    /*
+     * Set flag for NEC SOCK5 support
+     */
+    data->set.socks5_gssapi_nec = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_SOCKS5_GSSAPI_SERVICE:
+  case CURLOPT_PROXY_SERVICE_NAME:
+    /*
+     * Set proxy authentication service name for Kerberos 5 and SPNEGO
+     */
+    result = Curl_setstropt(&data->set.str[STRING_PROXY_SERVICE_NAME],
+                            va_arg(param, char *));
+    break;
+#endif
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) ||     \
+  defined(USE_SPNEGO)
+  case CURLOPT_SERVICE_NAME:
+    /*
+     * Set authentication service name for DIGEST-MD5, Kerberos 5 and SPNEGO
+     */
+    result = Curl_setstropt(&data->set.str[STRING_SERVICE_NAME],
+                            va_arg(param, char *));
+    break;
+
+#endif
+
+  case CURLOPT_HEADERDATA:
+    /*
+     * Custom pointer to pass the header write callback function
+     */
+    data->set.writeheader = (void *)va_arg(param, void *);
+    break;
+  case CURLOPT_ERRORBUFFER:
+    /*
+     * Error buffer provided by the caller to get the human readable
+     * error string in.
+     */
+    data->set.errorbuffer = va_arg(param, char *);
+    break;
+  case CURLOPT_WRITEDATA:
+    /*
+     * FILE pointer to write to. Or possibly
+     * used as argument to the write callback.
+     */
+    data->set.out = va_arg(param, void *);
+    break;
+  case CURLOPT_FTPPORT:
+    /*
+     * Use FTP PORT, this also specifies which IP address to use
+     */
+    result = Curl_setstropt(&data->set.str[STRING_FTPPORT],
+                            va_arg(param, char *));
+    data->set.ftp_use_port = (data->set.str[STRING_FTPPORT]) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_FTP_USE_EPRT:
+    data->set.ftp_use_eprt = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_FTP_USE_EPSV:
+    data->set.ftp_use_epsv = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_FTP_USE_PRET:
+    data->set.ftp_use_pret = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_FTP_SSL_CCC:
+    arg = va_arg(param, long);
+    if((arg < CURLFTPSSL_CCC_NONE) || (arg > CURLFTPSSL_CCC_ACTIVE))
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.ftp_ccc = (curl_ftpccc)arg;
+    break;
+
+  case CURLOPT_FTP_SKIP_PASV_IP:
+    /*
+     * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
+     * bypass of the IP address in PASV responses.
+     */
+    data->set.ftp_skip_ip = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_READDATA:
+    /*
+     * FILE pointer to read the file to be uploaded from. Or possibly
+     * used as argument to the read callback.
+     */
+    data->set.in_set = va_arg(param, void *);
+    break;
+  case CURLOPT_INFILESIZE:
+    /*
+     * If known, this should inform curl about the file size of the
+     * to-be-uploaded file.
+     */
+    arg = va_arg(param, long);
+    if(arg < -1)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.filesize = arg;
+    break;
+  case CURLOPT_INFILESIZE_LARGE:
+    /*
+     * If known, this should inform curl about the file size of the
+     * to-be-uploaded file.
+     */
+    bigsize = va_arg(param, curl_off_t);
+    if(bigsize < -1)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.filesize = bigsize;
+    break;
+  case CURLOPT_LOW_SPEED_LIMIT:
+    /*
+     * The low speed limit that if transfers are below this for
+     * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
+     */
+    arg = va_arg(param, long);
+    if(arg < 0)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.low_speed_limit = arg;
+    break;
+  case CURLOPT_MAX_SEND_SPEED_LARGE:
+    /*
+     * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE
+     * bytes per second the transfer is throttled..
+     */
+    bigsize = va_arg(param, curl_off_t);
+    if(bigsize < 0)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.max_send_speed = bigsize;
+    break;
+  case CURLOPT_MAX_RECV_SPEED_LARGE:
+    /*
+     * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per
+     * second the transfer is throttled..
+     */
+    bigsize = va_arg(param, curl_off_t);
+    if(bigsize < 0)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.max_recv_speed = bigsize;
+    break;
+  case CURLOPT_LOW_SPEED_TIME:
+    /*
+     * The low speed time that if transfers are below the set
+     * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
+     */
+    arg = va_arg(param, long);
+    if(arg < 0)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.low_speed_time = arg;
+    break;
+  case CURLOPT_URL:
+    /*
+     * The URL to fetch.
+     */
+    if(data->change.url_alloc) {
+      /* the already set URL is allocated, free it first! */
+      Curl_safefree(data->change.url);
+      data->change.url_alloc = FALSE;
+    }
+    result = Curl_setstropt(&data->set.str[STRING_SET_URL],
+                            va_arg(param, char *));
+    data->change.url = data->set.str[STRING_SET_URL];
+    break;
+  case CURLOPT_PORT:
+    /*
+     * The port number to use when getting the URL
+     */
+    arg = va_arg(param, long);
+    if((arg < 0) || (arg > 65535))
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.use_port = arg;
+    break;
+  case CURLOPT_TIMEOUT:
+    /*
+     * The maximum time you allow curl to use for a single transfer
+     * operation.
+     */
+    arg = va_arg(param, long);
+    if((arg >= 0) && (arg < (INT_MAX/1000)))
+      data->set.timeout = arg * 1000;
+    else
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    break;
+
+  case CURLOPT_TIMEOUT_MS:
+    arg = va_arg(param, long);
+    if(arg < 0)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.timeout = arg;
+    break;
+
+  case CURLOPT_CONNECTTIMEOUT:
+    /*
+     * The maximum time you allow curl to use to connect.
+     */
+    arg = va_arg(param, long);
+    if((arg >= 0) && (arg < (INT_MAX/1000)))
+      data->set.connecttimeout = arg * 1000;
+    else
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    break;
+
+  case CURLOPT_CONNECTTIMEOUT_MS:
+    arg = va_arg(param, long);
+    if(arg < 0)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.connecttimeout = arg;
+    break;
+
+  case CURLOPT_ACCEPTTIMEOUT_MS:
+    /*
+     * The maximum time you allow curl to wait for server connect
+     */
+    arg = va_arg(param, long);
+    if(arg < 0)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.accepttimeout = arg;
+    break;
+
+  case CURLOPT_USERPWD:
+    /*
+     * user:password to use in the operation
+     */
+    result = setstropt_userpwd(va_arg(param, char *),
+                               &data->set.str[STRING_USERNAME],
+                               &data->set.str[STRING_PASSWORD]);
+    break;
+
+  case CURLOPT_USERNAME:
+    /*
+     * authentication user name to use in the operation
+     */
+    result = Curl_setstropt(&data->set.str[STRING_USERNAME],
+                            va_arg(param, char *));
+    break;
+
+  case CURLOPT_PASSWORD:
+    /*
+     * authentication password to use in the operation
+     */
+    result = Curl_setstropt(&data->set.str[STRING_PASSWORD],
+                            va_arg(param, char *));
+    break;
+
+  case CURLOPT_LOGIN_OPTIONS:
+    /*
+     * authentication options to use in the operation
+     */
+    result = Curl_setstropt(&data->set.str[STRING_OPTIONS],
+                            va_arg(param, char *));
+    break;
+
+  case CURLOPT_XOAUTH2_BEARER:
+    /*
+     * OAuth 2.0 bearer token to use in the operation
+     */
+    result = Curl_setstropt(&data->set.str[STRING_BEARER],
+                            va_arg(param, char *));
+    break;
+
+  case CURLOPT_POSTQUOTE:
+    /*
+     * List of RAW FTP commands to use after a transfer
+     */
+    data->set.postquote = va_arg(param, struct curl_slist *);
+    break;
+  case CURLOPT_PREQUOTE:
+    /*
+     * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
+     */
+    data->set.prequote = va_arg(param, struct curl_slist *);
+    break;
+  case CURLOPT_QUOTE:
+    /*
+     * List of RAW FTP commands to use before a transfer
+     */
+    data->set.quote = va_arg(param, struct curl_slist *);
+    break;
+  case CURLOPT_RESOLVE:
+    /*
+     * List of NAME:[address] names to populate the DNS cache with
+     * Prefix the NAME with dash (-) to _remove_ the name from the cache.
+     *
+     * Names added with this API will remain in the cache until explicitly
+     * removed or the handle is cleaned up.
+     *
+     * This API can remove any name from the DNS cache, but only entries
+     * that aren't actually in use right now will be pruned immediately.
+     */
+    data->set.resolve = va_arg(param, struct curl_slist *);
+    data->change.resolve = data->set.resolve;
+    break;
+  case CURLOPT_PROGRESSFUNCTION:
+    /*
+     * Progress callback function
+     */
+    data->set.fprogress = va_arg(param, curl_progress_callback);
+    if(data->set.fprogress)
+      data->progress.callback = TRUE; /* no longer internal */
+    else
+      data->progress.callback = FALSE; /* NULL enforces internal */
+    break;
+
+  case CURLOPT_XFERINFOFUNCTION:
+    /*
+     * Transfer info callback function
+     */
+    data->set.fxferinfo = va_arg(param, curl_xferinfo_callback);
+    if(data->set.fxferinfo)
+      data->progress.callback = TRUE; /* no longer internal */
+    else
+      data->progress.callback = FALSE; /* NULL enforces internal */
+
+    break;
+
+  case CURLOPT_PROGRESSDATA:
+    /*
+     * Custom client data to pass to the progress callback
+     */
+    data->set.progress_client = va_arg(param, void *);
+    break;
+
+#ifndef CURL_DISABLE_PROXY
+  case CURLOPT_PROXYUSERPWD:
+    /*
+     * user:password needed to use the proxy
+     */
+    result = setstropt_userpwd(va_arg(param, char *),
+                               &data->set.str[STRING_PROXYUSERNAME],
+                               &data->set.str[STRING_PROXYPASSWORD]);
+    break;
+  case CURLOPT_PROXYUSERNAME:
+    /*
+     * authentication user name to use in the operation
+     */
+    result = Curl_setstropt(&data->set.str[STRING_PROXYUSERNAME],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_PROXYPASSWORD:
+    /*
+     * authentication password to use in the operation
+     */
+    result = Curl_setstropt(&data->set.str[STRING_PROXYPASSWORD],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_NOPROXY:
+    /*
+     * proxy exception list
+     */
+    result = Curl_setstropt(&data->set.str[STRING_NOPROXY],
+                            va_arg(param, char *));
+    break;
+#endif
+
+  case CURLOPT_RANGE:
+    /*
+     * What range of the file you want to transfer
+     */
+    result = Curl_setstropt(&data->set.str[STRING_SET_RANGE],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_RESUME_FROM:
+    /*
+     * Resume transfer at the given file position
+     */
+    arg = va_arg(param, long);
+    if(arg < -1)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.set_resume_from = arg;
+    break;
+  case CURLOPT_RESUME_FROM_LARGE:
+    /*
+     * Resume transfer at the given file position
+     */
+    bigsize = va_arg(param, curl_off_t);
+    if(bigsize < -1)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.set_resume_from = bigsize;
+    break;
+  case CURLOPT_DEBUGFUNCTION:
+    /*
+     * stderr write callback.
+     */
+    data->set.fdebug = va_arg(param, curl_debug_callback);
+    /*
+     * if the callback provided is NULL, it'll use the default callback
+     */
+    break;
+  case CURLOPT_DEBUGDATA:
+    /*
+     * Set to a void * that should receive all error writes. This
+     * defaults to CURLOPT_STDERR for normal operations.
+     */
+    data->set.debugdata = va_arg(param, void *);
+    break;
+  case CURLOPT_STDERR:
+    /*
+     * Set to a FILE * that should receive all error writes. This
+     * defaults to stderr for normal operations.
+     */
+    data->set.err = va_arg(param, FILE *);
+    if(!data->set.err)
+      data->set.err = stderr;
+    break;
+  case CURLOPT_HEADERFUNCTION:
+    /*
+     * Set header write callback
+     */
+    data->set.fwrite_header = va_arg(param, curl_write_callback);
+    break;
+  case CURLOPT_WRITEFUNCTION:
+    /*
+     * Set data write callback
+     */
+    data->set.fwrite_func = va_arg(param, curl_write_callback);
+    if(!data->set.fwrite_func) {
+      data->set.is_fwrite_set = 0;
+      /* When set to NULL, reset to our internal default function */
+      data->set.fwrite_func = (curl_write_callback)fwrite;
+    }
+    else
+      data->set.is_fwrite_set = 1;
+    break;
+  case CURLOPT_READFUNCTION:
+    /*
+     * Read data callback
+     */
+    data->set.fread_func_set = va_arg(param, curl_read_callback);
+    if(!data->set.fread_func_set) {
+      data->set.is_fread_set = 0;
+      /* When set to NULL, reset to our internal default function */
+      data->set.fread_func_set = (curl_read_callback)fread;
+    }
+    else
+      data->set.is_fread_set = 1;
+    break;
+  case CURLOPT_SEEKFUNCTION:
+    /*
+     * Seek callback. Might be NULL.
+     */
+    data->set.seek_func = va_arg(param, curl_seek_callback);
+    break;
+  case CURLOPT_SEEKDATA:
+    /*
+     * Seek control callback. Might be NULL.
+     */
+    data->set.seek_client = va_arg(param, void *);
+    break;
+  case CURLOPT_CONV_FROM_NETWORK_FUNCTION:
+    /*
+     * "Convert from network encoding" callback
+     */
+    data->set.convfromnetwork = va_arg(param, curl_conv_callback);
+    break;
+  case CURLOPT_CONV_TO_NETWORK_FUNCTION:
+    /*
+     * "Convert to network encoding" callback
+     */
+    data->set.convtonetwork = va_arg(param, curl_conv_callback);
+    break;
+  case CURLOPT_CONV_FROM_UTF8_FUNCTION:
+    /*
+     * "Convert from UTF-8 encoding" callback
+     */
+    data->set.convfromutf8 = va_arg(param, curl_conv_callback);
+    break;
+  case CURLOPT_IOCTLFUNCTION:
+    /*
+     * I/O control callback. Might be NULL.
+     */
+    data->set.ioctl_func = va_arg(param, curl_ioctl_callback);
+    break;
+  case CURLOPT_IOCTLDATA:
+    /*
+     * I/O control data pointer. Might be NULL.
+     */
+    data->set.ioctl_client = va_arg(param, void *);
+    break;
+  case CURLOPT_SSLCERT:
+    /*
+     * String that holds file name of the SSL certificate to use
+     */
+    result = Curl_setstropt(&data->set.str[STRING_CERT_ORIG],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_PROXY_SSLCERT:
+    /*
+     * String that holds file name of the SSL certificate to use for proxy
+     */
+    result = Curl_setstropt(&data->set.str[STRING_CERT_PROXY],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_SSLCERTTYPE:
+    /*
+     * String that holds file type of the SSL certificate to use
+     */
+    result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE_ORIG],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_PROXY_SSLCERTTYPE:
+    /*
+     * String that holds file type of the SSL certificate to use for proxy
+     */
+    result = Curl_setstropt(&data->set.str[STRING_CERT_TYPE_PROXY],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_SSLKEY:
+    /*
+     * String that holds file name of the SSL key to use
+     */
+    result = Curl_setstropt(&data->set.str[STRING_KEY_ORIG],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_PROXY_SSLKEY:
+    /*
+     * String that holds file name of the SSL key to use for proxy
+     */
+    result = Curl_setstropt(&data->set.str[STRING_KEY_PROXY],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_SSLKEYTYPE:
+    /*
+     * String that holds file type of the SSL key to use
+     */
+    result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE_ORIG],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_PROXY_SSLKEYTYPE:
+    /*
+     * String that holds file type of the SSL key to use for proxy
+     */
+    result = Curl_setstropt(&data->set.str[STRING_KEY_TYPE_PROXY],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_KEYPASSWD:
+    /*
+     * String that holds the SSL or SSH private key password.
+     */
+    result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD_ORIG],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_PROXY_KEYPASSWD:
+    /*
+     * String that holds the SSL private key password for proxy.
+     */
+    result = Curl_setstropt(&data->set.str[STRING_KEY_PASSWD_PROXY],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_SSLENGINE:
+    /*
+     * String that holds the SSL crypto engine.
+     */
+    argptr = va_arg(param, char *);
+    if(argptr && argptr[0])
+      result = Curl_ssl_set_engine(data, argptr);
+    break;
+
+  case CURLOPT_SSLENGINE_DEFAULT:
+    /*
+     * flag to set engine as default.
+     */
+    result = Curl_ssl_set_engine_default(data);
+    break;
+  case CURLOPT_CRLF:
+    /*
+     * Kludgy option to enable CRLF conversions. Subject for removal.
+     */
+    data->set.crlf = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_INTERFACE:
+    /*
+     * Set what interface or address/hostname to bind the socket to when
+     * performing an operation and thus what from-IP your connection will use.
+     */
+    result = Curl_setstropt(&data->set.str[STRING_DEVICE],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_LOCALPORT:
+    /*
+     * Set what local port to bind the socket to when performing an operation.
+     */
+    arg = va_arg(param, long);
+    if((arg < 0) || (arg > 65535))
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.localport = curlx_sltous(arg);
+    break;
+  case CURLOPT_LOCALPORTRANGE:
+    /*
+     * Set number of local ports to try, starting with CURLOPT_LOCALPORT.
+     */
+    arg = va_arg(param, long);
+    if((arg < 0) || (arg > 65535))
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.localportrange = curlx_sltosi(arg);
+    break;
+  case CURLOPT_KRBLEVEL:
+    /*
+     * A string that defines the kerberos security level.
+     */
+    result = Curl_setstropt(&data->set.str[STRING_KRB_LEVEL],
+                            va_arg(param, char *));
+    data->set.krb = (data->set.str[STRING_KRB_LEVEL]) ? TRUE : FALSE;
+    break;
+  case CURLOPT_GSSAPI_DELEGATION:
+    /*
+     * GSS-API credential delegation bitmask
+     */
+    arg = va_arg(param, long);
+    if(arg < CURLGSSAPI_DELEGATION_NONE)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.gssapi_delegation = arg;
+    break;
+  case CURLOPT_SSL_VERIFYPEER:
+    /*
+     * Enable peer SSL verifying.
+     */
+    data->set.ssl.primary.verifypeer = (0 != va_arg(param, long)) ?
+      TRUE : FALSE;
+
+    /* Update the current connection ssl_config. */
+    if(data->easy_conn) {
+      data->easy_conn->ssl_config.verifypeer =
+        data->set.ssl.primary.verifypeer;
+    }
+    break;
+  case CURLOPT_PROXY_SSL_VERIFYPEER:
+    /*
+     * Enable peer SSL verifying for proxy.
+     */
+    data->set.proxy_ssl.primary.verifypeer =
+      (0 != va_arg(param, long))?TRUE:FALSE;
+
+    /* Update the current connection proxy_ssl_config. */
+    if(data->easy_conn) {
+      data->easy_conn->proxy_ssl_config.verifypeer =
+        data->set.proxy_ssl.primary.verifypeer;
+    }
+    break;
+  case CURLOPT_SSL_VERIFYHOST:
+    /*
+     * Enable verification of the host name in the peer certificate
+     */
+    arg = va_arg(param, long);
+
+    /* Obviously people are not reading documentation and too many thought
+       this argument took a boolean when it wasn't and misused it. We thus ban
+       1 as a sensible input and we warn about its use. Then we only have the
+       2 action internally stored as TRUE. */
+
+    if(1 == arg) {
+      failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    }
+
+    data->set.ssl.primary.verifyhost = (0 != arg) ? TRUE : FALSE;
+
+    /* Update the current connection ssl_config. */
+    if(data->easy_conn) {
+      data->easy_conn->ssl_config.verifyhost =
+        data->set.ssl.primary.verifyhost;
+    }
+    break;
+  case CURLOPT_PROXY_SSL_VERIFYHOST:
+    /*
+     * Enable verification of the host name in the peer certificate for proxy
+     */
+    arg = va_arg(param, long);
+
+    /* Obviously people are not reading documentation and too many thought
+       this argument took a boolean when it wasn't and misused it. We thus ban
+       1 as a sensible input and we warn about its use. Then we only have the
+       2 action internally stored as TRUE. */
+
+    if(1 == arg) {
+      failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!");
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    }
+
+    data->set.proxy_ssl.primary.verifyhost = (0 != arg)?TRUE:FALSE;
+
+    /* Update the current connection proxy_ssl_config. */
+    if(data->easy_conn) {
+      data->easy_conn->proxy_ssl_config.verifyhost =
+        data->set.proxy_ssl.primary.verifyhost;
+    }
+    break;
+  case CURLOPT_SSL_VERIFYSTATUS:
+    /*
+     * Enable certificate status verifying.
+     */
+    if(!Curl_ssl_cert_status_request()) {
+      result = CURLE_NOT_BUILT_IN;
+      break;
+    }
+
+    data->set.ssl.primary.verifystatus = (0 != va_arg(param, long)) ?
+      TRUE : FALSE;
+
+    /* Update the current connection ssl_config. */
+    if(data->easy_conn) {
+      data->easy_conn->ssl_config.verifystatus =
+        data->set.ssl.primary.verifystatus;
+    }
+    break;
+  case CURLOPT_SSL_CTX_FUNCTION:
+    /*
+     * Set a SSL_CTX callback
+     */
+#ifdef USE_SSL
+    if(Curl_ssl->have_ssl_ctx)
+      data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
+    else
+#endif
+      result = CURLE_NOT_BUILT_IN;
+    break;
+  case CURLOPT_SSL_CTX_DATA:
+    /*
+     * Set a SSL_CTX callback parameter pointer
+     */
+#ifdef USE_SSL
+    if(Curl_ssl->have_ssl_ctx)
+      data->set.ssl.fsslctxp = va_arg(param, void *);
+    else
+#endif
+      result = CURLE_NOT_BUILT_IN;
+    break;
+  case CURLOPT_SSL_FALSESTART:
+    /*
+     * Enable TLS false start.
+     */
+    if(!Curl_ssl_false_start()) {
+      result = CURLE_NOT_BUILT_IN;
+      break;
+    }
+
+    data->set.ssl.falsestart = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+  case CURLOPT_CERTINFO:
+#ifdef USE_SSL
+    if(Curl_ssl->have_certinfo)
+      data->set.ssl.certinfo = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    else
+#endif
+      result = CURLE_NOT_BUILT_IN;
+        break;
+  case CURLOPT_PINNEDPUBLICKEY:
+    /*
+     * Set pinned public key for SSL connection.
+     * Specify file name of the public key in DER format.
+     */
+#ifdef USE_SSL
+    if(Curl_ssl->have_pinnedpubkey)
+      result = Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG],
+                              va_arg(param, char *));
+    else
+#endif
+      result = CURLE_NOT_BUILT_IN;
+    break;
+  case CURLOPT_PROXY_PINNEDPUBLICKEY:
+    /*
+     * Set pinned public key for SSL connection.
+     * Specify file name of the public key in DER format.
+     */
+#ifdef USE_SSL
+    if(Curl_ssl->have_pinnedpubkey)
+      result = Curl_setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY],
+                              va_arg(param, char *));
+    else
+#endif
+      result = CURLE_NOT_BUILT_IN;
+    break;
+  case CURLOPT_CAINFO:
+    /*
+     * Set CA info for SSL connection. Specify file name of the CA certificate
+     */
+    result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE_ORIG],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_PROXY_CAINFO:
+    /*
+     * Set CA info SSL connection for proxy. Specify file name of the
+     * CA certificate
+     */
+    result = Curl_setstropt(&data->set.str[STRING_SSL_CAFILE_PROXY],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_CAPATH:
+    /*
+     * Set CA path info for SSL connection. Specify directory name of the CA
+     * certificates which have been prepared using openssl c_rehash utility.
+     */
+#ifdef USE_SSL
+    if(Curl_ssl->have_ca_path)
+      /* This does not work on windows. */
+      result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH_ORIG],
+                              va_arg(param, char *));
+    else
+#endif
+      result = CURLE_NOT_BUILT_IN;
+    break;
+  case CURLOPT_PROXY_CAPATH:
+    /*
+     * Set CA path info for SSL connection proxy. Specify directory name of the
+     * CA certificates which have been prepared using openssl c_rehash utility.
+     */
+#ifdef USE_SSL
+    if(Curl_ssl->have_ca_path)
+      /* This does not work on windows. */
+      result = Curl_setstropt(&data->set.str[STRING_SSL_CAPATH_PROXY],
+                              va_arg(param, char *));
+    else
+#endif
+      result = CURLE_NOT_BUILT_IN;
+    break;
+  case CURLOPT_CRLFILE:
+    /*
+     * Set CRL file info for SSL connection. Specify file name of the CRL
+     * to check certificates revocation
+     */
+    result = Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE_ORIG],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_PROXY_CRLFILE:
+    /*
+     * Set CRL file info for SSL connection for proxy. Specify file name of the
+     * CRL to check certificates revocation
+     */
+    result = Curl_setstropt(&data->set.str[STRING_SSL_CRLFILE_PROXY],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_ISSUERCERT:
+    /*
+     * Set Issuer certificate file
+     * to check certificates issuer
+     */
+    result = Curl_setstropt(&data->set.str[STRING_SSL_ISSUERCERT_ORIG],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_TELNETOPTIONS:
+    /*
+     * Set a linked list of telnet options
+     */
+    data->set.telnet_options = va_arg(param, struct curl_slist *);
+    break;
+
+  case CURLOPT_BUFFERSIZE:
+    /*
+     * The application kindly asks for a differently sized receive buffer.
+     * If it seems reasonable, we'll use it.
+     */
+    arg = va_arg(param, long);
+
+    if(arg > READBUFFER_MAX)
+      arg = READBUFFER_MAX;
+    else if(arg < 1)
+      arg = READBUFFER_SIZE;
+    else if(arg < READBUFFER_MIN)
+      arg = READBUFFER_MIN;
+
+    /* Resize if new size */
+    if(arg != data->set.buffer_size) {
+      char *newbuff = realloc(data->state.buffer, arg + 1);
+      if(!newbuff) {
+        DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n"));
+        result = CURLE_OUT_OF_MEMORY;
+      }
+      else
+        data->state.buffer = newbuff;
+    }
+    data->set.buffer_size = arg;
+
+    break;
+
+  case CURLOPT_NOSIGNAL:
+    /*
+     * The application asks not to set any signal() or alarm() handlers,
+     * even when using a timeout.
+     */
+    data->set.no_signal = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_SHARE:
+  {
+    struct Curl_share *set;
+    set = va_arg(param, struct Curl_share *);
+
+    /* disconnect from old share, if any */
+    if(data->share) {
+      Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
+
+      if(data->dns.hostcachetype == HCACHE_SHARED) {
+        data->dns.hostcache = NULL;
+        data->dns.hostcachetype = HCACHE_NONE;
+      }
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+      if(data->share->cookies == data->cookies)
+        data->cookies = NULL;
+#endif
+
+      if(data->share->sslsession == data->state.session)
+        data->state.session = NULL;
+
+      data->share->dirty--;
+
+      Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
+      data->share = NULL;
+    }
+
+    /* use new share if it set */
+    data->share = set;
+    if(data->share) {
+
+      Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
+
+      data->share->dirty++;
+
+      if(data->share->specifier & (1<< CURL_LOCK_DATA_DNS)) {
+        /* use shared host cache */
+        data->dns.hostcache = &data->share->hostcache;
+        data->dns.hostcachetype = HCACHE_SHARED;
+      }
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+      if(data->share->cookies) {
+        /* use shared cookie list, first free own one if any */
+        Curl_cookie_cleanup(data->cookies);
+        /* enable cookies since we now use a share that uses cookies! */
+        data->cookies = data->share->cookies;
+      }
+#endif   /* CURL_DISABLE_HTTP */
+      if(data->share->sslsession) {
+        data->set.general_ssl.max_ssl_sessions = data->share->max_ssl_sessions;
+        data->state.session = data->share->sslsession;
+      }
+      Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
+
+    }
+    /* check for host cache not needed,
+     * it will be done by curl_easy_perform */
+  }
+  break;
+
+  case CURLOPT_PRIVATE:
+    /*
+     * Set private data pointer.
+     */
+    data->set.private_data = va_arg(param, void *);
+    break;
+
+  case CURLOPT_MAXFILESIZE:
+    /*
+     * Set the maximum size of a file to download.
+     */
+    arg = va_arg(param, long);
+    if(arg < 0)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.max_filesize = arg;
+    break;
+
+#ifdef USE_SSL
+  case CURLOPT_USE_SSL:
+    /*
+     * Make transfers attempt to use SSL/TLS.
+     */
+    arg = va_arg(param, long);
+    if((arg < CURLUSESSL_NONE) || (arg > CURLUSESSL_ALL))
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.use_ssl = (curl_usessl)arg;
+    break;
+
+  case CURLOPT_SSL_OPTIONS:
+    arg = va_arg(param, long);
+    data->set.ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
+    data->set.ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
+    break;
+
+  case CURLOPT_PROXY_SSL_OPTIONS:
+    arg = va_arg(param, long);
+    data->set.proxy_ssl.enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
+    data->set.proxy_ssl.no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE);
+    break;
+
+#endif
+  case CURLOPT_FTPSSLAUTH:
+    /*
+     * Set a specific auth for FTP-SSL transfers.
+     */
+    arg = va_arg(param, long);
+    if((arg < CURLFTPAUTH_DEFAULT) || (arg > CURLFTPAUTH_TLS))
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.ftpsslauth = (curl_ftpauth)arg;
+    break;
+
+  case CURLOPT_IPRESOLVE:
+    arg = va_arg(param, long);
+    if((arg < CURL_IPRESOLVE_WHATEVER) || (arg > CURL_IPRESOLVE_V6))
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.ipver = arg;
+    break;
+
+  case CURLOPT_MAXFILESIZE_LARGE:
+    /*
+     * Set the maximum size of a file to download.
+     */
+    bigsize = va_arg(param, curl_off_t);
+    if(bigsize < 0)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.max_filesize = bigsize;
+    break;
+
+  case CURLOPT_TCP_NODELAY:
+    /*
+     * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
+     * algorithm
+     */
+    data->set.tcp_nodelay = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_FTP_ACCOUNT:
+    result = Curl_setstropt(&data->set.str[STRING_FTP_ACCOUNT],
+                            va_arg(param, char *));
+    break;
+
+  case CURLOPT_IGNORE_CONTENT_LENGTH:
+    data->set.ignorecl = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_CONNECT_ONLY:
+    /*
+     * No data transfer, set up connection and let application use the socket
+     */
+    data->set.connect_only = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_FTP_ALTERNATIVE_TO_USER:
+    result = Curl_setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER],
+                            va_arg(param, char *));
+    break;
+
+  case CURLOPT_SOCKOPTFUNCTION:
+    /*
+     * socket callback function: called after socket() but before connect()
+     */
+    data->set.fsockopt = va_arg(param, curl_sockopt_callback);
+    break;
+
+  case CURLOPT_SOCKOPTDATA:
+    /*
+     * socket callback data pointer. Might be NULL.
+     */
+    data->set.sockopt_client = va_arg(param, void *);
+    break;
+
+  case CURLOPT_OPENSOCKETFUNCTION:
+    /*
+     * open/create socket callback function: called instead of socket(),
+     * before connect()
+     */
+    data->set.fopensocket = va_arg(param, curl_opensocket_callback);
+    break;
+
+  case CURLOPT_OPENSOCKETDATA:
+    /*
+     * socket callback data pointer. Might be NULL.
+     */
+    data->set.opensocket_client = va_arg(param, void *);
+    break;
+
+  case CURLOPT_CLOSESOCKETFUNCTION:
+    /*
+     * close socket callback function: called instead of close()
+     * when shutting down a connection
+     */
+    data->set.fclosesocket = va_arg(param, curl_closesocket_callback);
+    break;
+
+  case CURLOPT_CLOSESOCKETDATA:
+    /*
+     * socket callback data pointer. Might be NULL.
+     */
+    data->set.closesocket_client = va_arg(param, void *);
+    break;
+
+  case CURLOPT_SSL_SESSIONID_CACHE:
+    data->set.ssl.primary.sessionid = (0 != va_arg(param, long)) ?
+      TRUE : FALSE;
+    data->set.proxy_ssl.primary.sessionid = data->set.ssl.primary.sessionid;
+    break;
+
+#ifdef USE_LIBSSH2
+    /* we only include SSH options if explicitly built to support SSH */
+  case CURLOPT_SSH_AUTH_TYPES:
+    data->set.ssh_auth_types = va_arg(param, long);
+    break;
+
+  case CURLOPT_SSH_PUBLIC_KEYFILE:
+    /*
+     * Use this file instead of the $HOME/.ssh/id_dsa.pub file
+     */
+    result = Curl_setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY],
+                            va_arg(param, char *));
+    break;
+
+  case CURLOPT_SSH_PRIVATE_KEYFILE:
+    /*
+     * Use this file instead of the $HOME/.ssh/id_dsa file
+     */
+    result = Curl_setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
+    /*
+     * Option to allow for the MD5 of the host public key to be checked
+     * for validation purposes.
+     */
+    result = Curl_setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5],
+                            va_arg(param, char *));
+    break;
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+  case CURLOPT_SSH_KNOWNHOSTS:
+    /*
+     * Store the file name to read known hosts from.
+     */
+    result = Curl_setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS],
+                            va_arg(param, char *));
+    break;
+
+  case CURLOPT_SSH_KEYFUNCTION:
+    /* setting to NULL is fine since the ssh.c functions themselves will
+       then rever to use the internal default */
+    data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback);
+    break;
+
+  case CURLOPT_SSH_KEYDATA:
+    /*
+     * Custom client data to pass to the SSH keyfunc callback
+     */
+    data->set.ssh_keyfunc_userp = va_arg(param, void *);
+    break;
+#endif /* HAVE_LIBSSH2_KNOWNHOST_API */
+
+#endif /* USE_LIBSSH2 */
+
+  case CURLOPT_HTTP_TRANSFER_DECODING:
+    /*
+     * disable libcurl transfer encoding is used
+     */
+    data->set.http_te_skip = (0 == va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_HTTP_CONTENT_DECODING:
+    /*
+     * raw data passed to the application when content encoding is used
+     */
+    data->set.http_ce_skip = (0 == va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_NEW_FILE_PERMS:
+    /*
+     * Uses these permissions instead of 0644
+     */
+    arg = va_arg(param, long);
+    if((arg < 0) || (arg > 0777))
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.new_file_perms = arg;
+    break;
+
+  case CURLOPT_NEW_DIRECTORY_PERMS:
+    /*
+     * Uses these permissions instead of 0755
+     */
+    arg = va_arg(param, long);
+    if((arg < 0) || (arg > 0777))
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.new_directory_perms = arg;
+    break;
+
+  case CURLOPT_ADDRESS_SCOPE:
+    /*
+     * We always get longs when passed plain numericals, but for this value we
+     * know that an unsigned int will always hold the value so we blindly
+     * typecast to this type
+     */
+    arg = va_arg(param, long);
+    if((arg < 0) || (arg > 0xf))
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.scope_id = curlx_sltoui(arg);
+    break;
+
+  case CURLOPT_PROTOCOLS:
+    /* set the bitmask for the protocols that are allowed to be used for the
+       transfer, which thus helps the app which takes URLs from users or other
+       external inputs and want to restrict what protocol(s) to deal
+       with. Defaults to CURLPROTO_ALL. */
+    data->set.allowed_protocols = va_arg(param, long);
+    break;
+
+  case CURLOPT_REDIR_PROTOCOLS:
+    /* set the bitmask for the protocols that libcurl is allowed to follow to,
+       as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
+       to be set in both bitmasks to be allowed to get redirected to. Defaults
+       to all protocols except FILE and SCP. */
+    data->set.redir_protocols = va_arg(param, long);
+    break;
+
+  case CURLOPT_DEFAULT_PROTOCOL:
+    /* Set the protocol to use when the URL doesn't include any protocol */
+    result = Curl_setstropt(&data->set.str[STRING_DEFAULT_PROTOCOL],
+                            va_arg(param, char *));
+    break;
+
+  case CURLOPT_MAIL_FROM:
+    /* Set the SMTP mail originator */
+    result = Curl_setstropt(&data->set.str[STRING_MAIL_FROM],
+                            va_arg(param, char *));
+    break;
+
+  case CURLOPT_MAIL_AUTH:
+    /* Set the SMTP auth originator */
+    result = Curl_setstropt(&data->set.str[STRING_MAIL_AUTH],
+                            va_arg(param, char *));
+    break;
+
+  case CURLOPT_MAIL_RCPT:
+    /* Set the list of mail recipients */
+    data->set.mail_rcpt = va_arg(param, struct curl_slist *);
+    break;
+
+  case CURLOPT_SASL_IR:
+    /* Enable/disable SASL initial response */
+    data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+  case CURLOPT_RTSP_REQUEST:
+  {
+    /*
+     * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...)
+     * Would this be better if the RTSPREQ_* were just moved into here?
+     */
+    long curl_rtspreq = va_arg(param, long);
+    Curl_RtspReq rtspreq = RTSPREQ_NONE;
+    switch(curl_rtspreq) {
+    case CURL_RTSPREQ_OPTIONS:
+      rtspreq = RTSPREQ_OPTIONS;
+      break;
+
+    case CURL_RTSPREQ_DESCRIBE:
+      rtspreq = RTSPREQ_DESCRIBE;
+      break;
+
+    case CURL_RTSPREQ_ANNOUNCE:
+      rtspreq = RTSPREQ_ANNOUNCE;
+      break;
+
+    case CURL_RTSPREQ_SETUP:
+      rtspreq = RTSPREQ_SETUP;
+      break;
+
+    case CURL_RTSPREQ_PLAY:
+      rtspreq = RTSPREQ_PLAY;
+      break;
+
+    case CURL_RTSPREQ_PAUSE:
+      rtspreq = RTSPREQ_PAUSE;
+      break;
+
+    case CURL_RTSPREQ_TEARDOWN:
+      rtspreq = RTSPREQ_TEARDOWN;
+      break;
+
+    case CURL_RTSPREQ_GET_PARAMETER:
+      rtspreq = RTSPREQ_GET_PARAMETER;
+      break;
+
+    case CURL_RTSPREQ_SET_PARAMETER:
+      rtspreq = RTSPREQ_SET_PARAMETER;
+      break;
+
+    case CURL_RTSPREQ_RECORD:
+      rtspreq = RTSPREQ_RECORD;
+      break;
+
+    case CURL_RTSPREQ_RECEIVE:
+      rtspreq = RTSPREQ_RECEIVE;
+      break;
+    default:
+      rtspreq = RTSPREQ_NONE;
+    }
+
+    data->set.rtspreq = rtspreq;
+    break;
+  }
+
+
+  case CURLOPT_RTSP_SESSION_ID:
+    /*
+     * Set the RTSP Session ID manually. Useful if the application is
+     * resuming a previously established RTSP session
+     */
+    result = Curl_setstropt(&data->set.str[STRING_RTSP_SESSION_ID],
+                            va_arg(param, char *));
+    break;
+
+  case CURLOPT_RTSP_STREAM_URI:
+    /*
+     * Set the Stream URI for the RTSP request. Unless the request is
+     * for generic server options, the application will need to set this.
+     */
+    result = Curl_setstropt(&data->set.str[STRING_RTSP_STREAM_URI],
+                            va_arg(param, char *));
+    break;
+
+  case CURLOPT_RTSP_TRANSPORT:
+    /*
+     * The content of the Transport: header for the RTSP request
+     */
+    result = Curl_setstropt(&data->set.str[STRING_RTSP_TRANSPORT],
+                            va_arg(param, char *));
+    break;
+
+  case CURLOPT_RTSP_CLIENT_CSEQ:
+    /*
+     * Set the CSEQ number to issue for the next RTSP request. Useful if the
+     * application is resuming a previously broken connection. The CSEQ
+     * will increment from this new number henceforth.
+     */
+    data->state.rtsp_next_client_CSeq = va_arg(param, long);
+    break;
+
+  case CURLOPT_RTSP_SERVER_CSEQ:
+    /* Same as the above, but for server-initiated requests */
+    data->state.rtsp_next_client_CSeq = va_arg(param, long);
+    break;
+
+  case CURLOPT_INTERLEAVEDATA:
+    data->set.rtp_out = va_arg(param, void *);
+    break;
+  case CURLOPT_INTERLEAVEFUNCTION:
+    /* Set the user defined RTP write function */
+    data->set.fwrite_rtp = va_arg(param, curl_write_callback);
+    break;
+
+  case CURLOPT_WILDCARDMATCH:
+    data->set.wildcard_enabled = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+  case CURLOPT_CHUNK_BGN_FUNCTION:
+    data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback);
+    break;
+  case CURLOPT_CHUNK_END_FUNCTION:
+    data->set.chunk_end = va_arg(param, curl_chunk_end_callback);
+    break;
+  case CURLOPT_FNMATCH_FUNCTION:
+    data->set.fnmatch = va_arg(param, curl_fnmatch_callback);
+    break;
+  case CURLOPT_CHUNK_DATA:
+    data->wildcard.customptr = va_arg(param, void *);
+    break;
+  case CURLOPT_FNMATCH_DATA:
+    data->set.fnmatch_data = va_arg(param, void *);
+    break;
+#ifdef USE_TLS_SRP
+  case CURLOPT_TLSAUTH_USERNAME:
+    result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_ORIG],
+                            va_arg(param, char *));
+    if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype)
+      data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+    break;
+  case CURLOPT_PROXY_TLSAUTH_USERNAME:
+    result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_USERNAME_PROXY],
+                            va_arg(param, char *));
+    if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
+       !data->set.proxy_ssl.authtype)
+      data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+    break;
+  case CURLOPT_TLSAUTH_PASSWORD:
+    result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_ORIG],
+                            va_arg(param, char *));
+    if(data->set.str[STRING_TLSAUTH_USERNAME_ORIG] && !data->set.ssl.authtype)
+      data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+    break;
+  case CURLOPT_PROXY_TLSAUTH_PASSWORD:
+    result = Curl_setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD_PROXY],
+                            va_arg(param, char *));
+    if(data->set.str[STRING_TLSAUTH_USERNAME_PROXY] &&
+       !data->set.proxy_ssl.authtype)
+      data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */
+    break;
+  case CURLOPT_TLSAUTH_TYPE:
+    argptr = va_arg(param, char *);
+    if(!argptr ||
+       strncasecompare(argptr, "SRP", strlen("SRP")))
+      data->set.ssl.authtype = CURL_TLSAUTH_SRP;
+    else
+      data->set.ssl.authtype = CURL_TLSAUTH_NONE;
+    break;
+  case CURLOPT_PROXY_TLSAUTH_TYPE:
+    argptr = va_arg(param, char *);
+    if(!argptr ||
+       strncasecompare(argptr, "SRP", strlen("SRP")))
+      data->set.proxy_ssl.authtype = CURL_TLSAUTH_SRP;
+    else
+      data->set.proxy_ssl.authtype = CURL_TLSAUTH_NONE;
+    break;
+#endif
+  case CURLOPT_DNS_SERVERS:
+    result = Curl_set_dns_servers(data, va_arg(param, char *));
+    break;
+  case CURLOPT_DNS_INTERFACE:
+    result = Curl_set_dns_interface(data, va_arg(param, char *));
+    break;
+  case CURLOPT_DNS_LOCAL_IP4:
+    result = Curl_set_dns_local_ip4(data, va_arg(param, char *));
+    break;
+  case CURLOPT_DNS_LOCAL_IP6:
+    result = Curl_set_dns_local_ip6(data, va_arg(param, char *));
+    break;
+
+  case CURLOPT_TCP_KEEPALIVE:
+    data->set.tcp_keepalive = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+  case CURLOPT_TCP_KEEPIDLE:
+    arg = va_arg(param, long);
+    if(arg < 0)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.tcp_keepidle = arg;
+    break;
+  case CURLOPT_TCP_KEEPINTVL:
+    arg = va_arg(param, long);
+    if(arg < 0)
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    data->set.tcp_keepintvl = arg;
+    break;
+  case CURLOPT_TCP_FASTOPEN:
+#if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN) || \
+   defined(TCP_FASTOPEN_CONNECT)
+    data->set.tcp_fastopen = (0 != va_arg(param, long))?TRUE:FALSE;
+#else
+    result = CURLE_NOT_BUILT_IN;
+#endif
+    break;
+  case CURLOPT_SSL_ENABLE_NPN:
+    data->set.ssl_enable_npn = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+  case CURLOPT_SSL_ENABLE_ALPN:
+    data->set.ssl_enable_alpn = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+
+#ifdef USE_UNIX_SOCKETS
+  case CURLOPT_UNIX_SOCKET_PATH:
+    data->set.abstract_unix_socket = FALSE;
+    result = Curl_setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
+                            va_arg(param, char *));
+    break;
+  case CURLOPT_ABSTRACT_UNIX_SOCKET:
+    data->set.abstract_unix_socket = TRUE;
+    result = Curl_setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH],
+                            va_arg(param, char *));
+    break;
+#endif
+
+  case CURLOPT_PATH_AS_IS:
+    data->set.path_as_is = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+  case CURLOPT_PIPEWAIT:
+    data->set.pipewait = (0 != va_arg(param, long)) ? TRUE : FALSE;
+    break;
+  case CURLOPT_STREAM_WEIGHT:
+#ifndef USE_NGHTTP2
+    return CURLE_NOT_BUILT_IN;
+#else
+    arg = va_arg(param, long);
+    if((arg >= 1) && (arg <= 256))
+      data->set.stream_weight = (int)arg;
+    break;
+#endif
+  case CURLOPT_STREAM_DEPENDS:
+  case CURLOPT_STREAM_DEPENDS_E:
+  {
+#ifndef USE_NGHTTP2
+    return CURLE_NOT_BUILT_IN;
+#else
+    struct Curl_easy *dep = va_arg(param, struct Curl_easy *);
+    if(!dep || GOOD_EASY_HANDLE(dep)) {
+      if(data->set.stream_depends_on) {
+        Curl_http2_remove_child(data->set.stream_depends_on, data);
+      }
+      Curl_http2_add_child(dep, data, (option == CURLOPT_STREAM_DEPENDS_E));
+    }
+    break;
+#endif
+  }
+  case CURLOPT_CONNECT_TO:
+    data->set.connect_to = va_arg(param, struct curl_slist *);
+    break;
+  case CURLOPT_SUPPRESS_CONNECT_HEADERS:
+    data->set.suppress_connect_headers = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  case CURLOPT_SSH_COMPRESSION:
+    data->set.ssh_compression = (0 != va_arg(param, long))?TRUE:FALSE;
+    break;
+  default:
+    /* unknown tag and its companion, just ignore: */
+    result = CURLE_UNKNOWN_OPTION;
+    break;
+  }
+
+  return result;
+}
+
+/*
+ * curl_easy_setopt() is the external interface for setting options on an
+ * easy handle.
+ */
+
+#undef curl_easy_setopt
+CURLcode curl_easy_setopt(struct Curl_easy *data, CURLoption tag, ...)
+{
+  va_list arg;
+  CURLcode result;
+
+  if(!data)
+    return CURLE_BAD_FUNCTION_ARGUMENT;
+
+  va_start(arg, tag);
+
+  result = setopt(data, tag, arg);
+
+  va_end(arg);
+  return result;
+}
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/setopt.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/setopt.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/setopt.h	(revision 331)
@@ -0,0 +1,27 @@
+#ifndef HEADER_CURL_SETOPT_H
+#define HEADER_CURL_SETOPT_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+CURLcode Curl_setstropt(char **charp, const char *s);
+
+#endif /* HEADER_CURL_SETOPT_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/setup-os400.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/setup-os400.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/setup-os400.h	(revision 331)
@@ -0,0 +1,223 @@
+#ifndef HEADER_CURL_SETUP_OS400_H
+#define HEADER_CURL_SETUP_OS400_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+
+/* OS/400 netdb.h does not define NI_MAXHOST. */
+#define NI_MAXHOST      1025
+
+/* OS/400 netdb.h does not define NI_MAXSERV. */
+#define NI_MAXSERV      32
+
+/* No OS/400 header file defines u_int32_t. */
+typedef unsigned long   u_int32_t;
+
+
+/* System API wrapper prototypes & definitions to support ASCII parameters. */
+
+#include <sys/socket.h>
+#include <netdb.h>
+#include <gskssl.h>
+#include <qsoasync.h>
+#include <gssapi.h>
+
+extern int Curl_getaddrinfo_a(const char *nodename,
+                              const char *servname,
+                              const struct addrinfo *hints,
+                              struct addrinfo **res);
+#define getaddrinfo             Curl_getaddrinfo_a
+
+
+extern int Curl_getnameinfo_a(const struct sockaddr *sa,
+                              curl_socklen_t salen,
+                              char *nodename, curl_socklen_t nodenamelen,
+                              char *servname, curl_socklen_t servnamelen,
+                              int flags);
+#define getnameinfo             Curl_getnameinfo_a
+
+
+/* GSKit wrappers. */
+
+extern int      Curl_gsk_environment_open(gsk_handle * my_env_handle);
+#define gsk_environment_open    Curl_gsk_environment_open
+
+extern int      Curl_gsk_secure_soc_open(gsk_handle my_env_handle,
+                                         gsk_handle * my_session_handle);
+#define gsk_secure_soc_open     Curl_gsk_secure_soc_open
+
+extern int      Curl_gsk_environment_close(gsk_handle * my_env_handle);
+#define gsk_environment_close   Curl_gsk_environment_close
+
+extern int      Curl_gsk_secure_soc_close(gsk_handle * my_session_handle);
+#define gsk_secure_soc_close    Curl_gsk_secure_soc_close
+
+extern int      Curl_gsk_environment_init(gsk_handle my_env_handle);
+#define gsk_environment_init    Curl_gsk_environment_init
+
+extern int      Curl_gsk_secure_soc_init(gsk_handle my_session_handle);
+#define gsk_secure_soc_init     Curl_gsk_secure_soc_init
+
+extern int      Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle,
+                                                GSK_BUF_ID bufID,
+                                                const char *buffer,
+                                                int bufSize);
+#define gsk_attribute_set_buffer        Curl_gsk_attribute_set_buffer_a
+
+extern int      Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle,
+                                            GSK_ENUM_ID enumID,
+                                            GSK_ENUM_VALUE enumValue);
+#define gsk_attribute_set_enum  Curl_gsk_attribute_set_enum
+
+extern int      Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle,
+                                                     GSK_NUM_ID numID,
+                                                     int numValue);
+#define gsk_attribute_set_numeric_value Curl_gsk_attribute_set_numeric_value
+
+extern int      Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle,
+                                                GSK_CALLBACK_ID callBackID,
+                                                void *callBackAreaPtr);
+#define gsk_attribute_set_callback      Curl_gsk_attribute_set_callback
+
+extern int      Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle,
+                                                GSK_BUF_ID bufID,
+                                                const char **buffer,
+                                                int *bufSize);
+#define gsk_attribute_get_buffer        Curl_gsk_attribute_get_buffer_a
+
+extern int      Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle,
+                                            GSK_ENUM_ID enumID,
+                                            GSK_ENUM_VALUE *enumValue);
+#define gsk_attribute_get_enum  Curl_gsk_attribute_get_enum
+
+extern int      Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle,
+                                                     GSK_NUM_ID numID,
+                                                     int *numValue);
+#define gsk_attribute_get_numeric_value Curl_gsk_attribute_get_numeric_value
+
+extern int      Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle,
+                                 GSK_CERT_ID certID,
+                                 const gsk_cert_data_elem **certDataElem,
+                                 int *certDataElementCount);
+#define gsk_attribute_get_cert_info     Curl_gsk_attribute_get_cert_info
+
+extern int      Curl_gsk_secure_soc_misc(gsk_handle my_session_handle,
+                                         GSK_MISC_ID miscID);
+#define gsk_secure_soc_misc     Curl_gsk_secure_soc_misc
+
+extern int      Curl_gsk_secure_soc_read(gsk_handle my_session_handle,
+                                         char *readBuffer,
+                                         int readBufSize, int *amtRead);
+#define gsk_secure_soc_read     Curl_gsk_secure_soc_read
+
+extern int      Curl_gsk_secure_soc_write(gsk_handle my_session_handle,
+                                          char *writeBuffer,
+                                          int writeBufSize, int *amtWritten);
+#define gsk_secure_soc_write    Curl_gsk_secure_soc_write
+
+extern const char *     Curl_gsk_strerror_a(int gsk_return_value);
+#define gsk_strerror    Curl_gsk_strerror_a
+
+extern int      Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle,
+                                      int IOCompletionPort,
+                                      Qso_OverlappedIO_t * communicationsArea);
+#define gsk_secure_soc_startInit        Curl_gsk_secure_soc_startInit
+
+
+/* GSSAPI wrappers. */
+
+extern OM_uint32 Curl_gss_import_name_a(OM_uint32 * minor_status,
+                                        gss_buffer_t in_name,
+                                        gss_OID in_name_type,
+                                        gss_name_t * out_name);
+#define gss_import_name         Curl_gss_import_name_a
+
+
+extern OM_uint32 Curl_gss_display_status_a(OM_uint32 * minor_status,
+                                           OM_uint32 status_value,
+                                           int status_type, gss_OID mech_type,
+                                           gss_msg_ctx_t * message_context,
+                                           gss_buffer_t status_string);
+#define gss_display_status      Curl_gss_display_status_a
+
+
+extern OM_uint32 Curl_gss_init_sec_context_a(OM_uint32 * minor_status,
+                                             gss_cred_id_t cred_handle,
+                                             gss_ctx_id_t * context_handle,
+                                             gss_name_t target_name,
+                                             gss_OID mech_type,
+                                             gss_flags_t req_flags,
+                                             OM_uint32 time_req,
+                                             gss_channel_bindings_t
+                                             input_chan_bindings,
+                                             gss_buffer_t input_token,
+                                             gss_OID * actual_mech_type,
+                                             gss_buffer_t output_token,
+                                             gss_flags_t * ret_flags,
+                                             OM_uint32 * time_rec);
+#define gss_init_sec_context    Curl_gss_init_sec_context_a
+
+
+extern OM_uint32 Curl_gss_delete_sec_context_a(OM_uint32 * minor_status,
+                                               gss_ctx_id_t * context_handle,
+                                               gss_buffer_t output_token);
+#define gss_delete_sec_context  Curl_gss_delete_sec_context_a
+
+
+/* LDAP wrappers. */
+
+#define BerValue                struct berval
+
+#define ldap_url_parse          ldap_url_parse_utf8
+#define ldap_init               Curl_ldap_init_a
+#define ldap_simple_bind_s      Curl_ldap_simple_bind_s_a
+#define ldap_search_s           Curl_ldap_search_s_a
+#define ldap_get_values_len     Curl_ldap_get_values_len_a
+#define ldap_err2string         Curl_ldap_err2string_a
+#define ldap_get_dn             Curl_ldap_get_dn_a
+#define ldap_first_attribute    Curl_ldap_first_attribute_a
+#define ldap_next_attribute     Curl_ldap_next_attribute_a
+
+/* Some socket functions must be wrapped to process textual addresses
+   like AF_UNIX. */
+
+extern int Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen);
+extern int Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen);
+extern int Curl_os400_sendto(int sd, char *buffer, int buflen, int flags,
+                             struct sockaddr * dstaddr, int addrlen);
+extern int Curl_os400_recvfrom(int sd, char *buffer, int buflen, int flags,
+                               struct sockaddr *fromaddr, int *addrlen);
+
+#define connect                 Curl_os400_connect
+#define bind                    Curl_os400_bind
+#define sendto                  Curl_os400_sendto
+#define recvfrom                Curl_os400_recvfrom
+
+#ifdef HAVE_LIBZ
+#define zlibVersion             Curl_os400_zlibVersion
+#define inflateInit_            Curl_os400_inflateInit_
+#define inflateInit2_           Curl_os400_inflateInit2_
+#define inflate                 Curl_os400_inflate
+#define inflateEnd              Curl_os400_inflateEnd
+#endif
+
+#endif /* HEADER_CURL_SETUP_OS400_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/setup-vms.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/setup-vms.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/setup-vms.h	(revision 331)
@@ -0,0 +1,443 @@
+#ifndef HEADER_CURL_SETUP_VMS_H
+#define HEADER_CURL_SETUP_VMS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*                                                                         */
+/* JEM, 12/30/12, VMS now generates config.h, so only define wrappers for  */
+/*                getenv(), getpwuid() and provide is_vms_shell()          */
+/*                Also need upper case symbols for system services, and    */
+/*                OpenSSL, and some Kerberos image                         */
+
+#ifdef __DECC
+#pragma message save
+#pragma message disable dollarid
+#endif
+
+/* Hide the stuff we are overriding */
+#define getenv decc_getenv
+#ifdef __DECC
+#   if __INITIAL_POINTER_SIZE != 64
+#       define getpwuid decc_getpwuid
+#   endif
+#endif
+#include <stdlib.h>
+char *decc$getenv(const char *__name);
+#include <pwd.h>
+
+#include <string.h>
+#include <unixlib.h>
+
+#undef getenv
+#undef getpwuid
+#define getenv vms_getenv
+#define getpwuid vms_getpwuid
+
+/* VAX needs these in upper case when compiling exact case */
+#define sys$assign SYS$ASSIGN
+#define sys$dassgn SYS$DASSGN
+#define sys$qiow SYS$QIOW
+
+#ifdef __DECC
+#   if __INITIAL_POINTER_SIZE
+#       pragma __pointer_size __save
+#   endif
+#endif
+
+#if __USE_LONG_GID_T
+#   define decc_getpwuid DECC$__LONG_GID_GETPWUID
+#else
+#   if __INITIAL_POINTER_SIZE
+#       define decc_getpwuid decc$__32_getpwuid
+#   else
+#       define decc_getpwuid decc$getpwuid
+#   endif
+#endif
+
+    struct passwd * decc_getpwuid(uid_t uid);
+
+#ifdef __DECC
+#   if __INITIAL_POINTER_SIZE == 32
+/* Translate the path, but only if the path is a VMS file specification */
+/* The translation is usually only needed for older versions of VMS */
+static char *vms_translate_path(const char *path)
+{
+  char *unix_path;
+  char *test_str;
+
+  /* See if the result is in VMS format, if not, we are done */
+  /* Assume that this is a PATH, not just some data */
+  test_str = strpbrk(path, ":[<^");
+  if(test_str == NULL) {
+    return (char *)path;
+  }
+
+  unix_path = decc$translate_vms(path);
+
+  if((int)unix_path <= 0) {
+    /* We can not translate it, so return the original string */
+    return (char *)path;
+  }
+}
+#   else
+    /* VMS translate path is actually not needed on the current 64 bit */
+    /* VMS platforms, so instead of figuring out the pointer settings */
+    /* Change it to a noop */
+#   define vms_translate_path(__path) __path
+#   endif
+#endif
+
+#ifdef __DECC
+#   if __INITIAL_POINTER_SIZE
+#       pragma __pointer_size __restore
+#   endif
+#endif
+
+static char *vms_getenv(const char *envvar)
+{
+  char *result;
+  char *vms_path;
+
+  /* first use the DECC getenv() function */
+  result = decc$getenv(envvar);
+  if(result == NULL) {
+    return result;
+  }
+
+  vms_path = result;
+  result = vms_translate_path(vms_path);
+
+  /* note that if you backport this to use VAX C RTL, that the VAX C RTL */
+  /* may do a malloc(2048) for each call to getenv(), so you will need   */
+  /* to add a free(vms_path) */
+  /* Do not do a free() for DEC C RTL builds, which should be used for */
+  /* VMS 5.5-2 and later, even if using GCC */
+
+  return result;
+}
+
+
+static struct passwd vms_passwd_cache;
+
+static struct passwd * vms_getpwuid(uid_t uid)
+{
+  struct passwd * my_passwd;
+
+/* Hack needed to support 64 bit builds, decc_getpwnam is 32 bit only */
+#ifdef __DECC
+#   if __INITIAL_POINTER_SIZE
+  __char_ptr32 unix_path;
+#   else
+  char *unix_path;
+#   endif
+#else
+  char *unix_path;
+#endif
+
+  my_passwd = decc_getpwuid(uid);
+  if(my_passwd == NULL) {
+    return my_passwd;
+  }
+
+  unix_path = vms_translate_path(my_passwd->pw_dir);
+
+  if((long)unix_path <= 0) {
+    /* We can not translate it, so return the original string */
+    return my_passwd;
+  }
+
+  /* If no changes needed just return it */
+  if(unix_path == my_passwd->pw_dir) {
+    return my_passwd;
+  }
+
+  /* Need to copy the structure returned */
+  /* Since curl is only using pw_dir, no need to fix up */
+  /* the pw_shell when running under Bash */
+  vms_passwd_cache.pw_name = my_passwd->pw_name;
+  vms_passwd_cache.pw_uid = my_passwd->pw_uid;
+  vms_passwd_cache.pw_gid = my_passwd->pw_uid;
+  vms_passwd_cache.pw_dir = unix_path;
+  vms_passwd_cache.pw_shell = my_passwd->pw_shell;
+
+  return &vms_passwd_cache;
+}
+
+#ifdef __DECC
+#pragma message restore
+#endif
+
+/* Bug - VMS OpenSSL and Kerberos universal symbols are in uppercase only */
+/* VMS libraries should have universal symbols in exact and uppercase */
+
+#define ASN1_INTEGER_get ASN1_INTEGER_GET
+#define ASN1_STRING_data ASN1_STRING_DATA
+#define ASN1_STRING_length ASN1_STRING_LENGTH
+#define ASN1_STRING_print ASN1_STRING_PRINT
+#define ASN1_STRING_to_UTF8 ASN1_STRING_TO_UTF8
+#define ASN1_STRING_type ASN1_STRING_TYPE
+#define BIO_ctrl BIO_CTRL
+#define BIO_free BIO_FREE
+#define BIO_new BIO_NEW
+#define BIO_s_mem BIO_S_MEM
+#define BN_bn2bin BN_BN2BIN
+#define BN_num_bits BN_NUM_BITS
+#define CRYPTO_cleanup_all_ex_data CRYPTO_CLEANUP_ALL_EX_DATA
+#define CRYPTO_free CRYPTO_FREE
+#define CRYPTO_malloc CRYPTO_MALLOC
+#define CONF_modules_load_file CONF_MODULES_LOAD_FILE
+#ifdef __VAX
+#  ifdef VMS_OLD_SSL
+  /* Ancient OpenSSL on VAX/VMS missing this constant */
+#    define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10
+#    undef CONF_modules_load_file
+     static int CONF_modules_load_file(const char *filename,
+                                       const char *appname,
+                                       unsigned long flags) {
+             return 1;
+     }
+#  endif
+#endif
+#define DES_ecb_encrypt DES_ECB_ENCRYPT
+#define DES_set_key DES_SET_KEY
+#define DES_set_odd_parity DES_SET_ODD_PARITY
+#define ENGINE_ctrl ENGINE_CTRL
+#define ENGINE_ctrl_cmd ENGINE_CTRL_CMD
+#define ENGINE_finish ENGINE_FINISH
+#define ENGINE_free ENGINE_FREE
+#define ENGINE_get_first ENGINE_GET_FIRST
+#define ENGINE_get_id ENGINE_GET_ID
+#define ENGINE_get_next ENGINE_GET_NEXT
+#define ENGINE_init ENGINE_INIT
+#define ENGINE_load_builtin_engines ENGINE_LOAD_BUILTIN_ENGINES
+#define ENGINE_load_private_key ENGINE_LOAD_PRIVATE_KEY
+#define ENGINE_set_default ENGINE_SET_DEFAULT
+#define ERR_clear_error ERR_CLEAR_ERROR
+#define ERR_error_string ERR_ERROR_STRING
+#define ERR_error_string_n ERR_ERROR_STRING_N
+#define ERR_free_strings ERR_FREE_STRINGS
+#define ERR_get_error ERR_GET_ERROR
+#define ERR_peek_error ERR_PEEK_ERROR
+#define ERR_remove_state ERR_REMOVE_STATE
+#define EVP_PKEY_copy_parameters EVP_PKEY_COPY_PARAMETERS
+#define EVP_PKEY_free EVP_PKEY_FREE
+#define EVP_cleanup EVP_CLEANUP
+#define GENERAL_NAMES_free GENERAL_NAMES_FREE
+#define i2d_X509_PUBKEY I2D_X509_PUBKEY
+#define MD4_Final MD4_FINAL
+#define MD4_Init MD4_INIT
+#define MD4_Update MD4_UPDATE
+#define MD5_Final MD5_FINAL
+#define MD5_Init MD5_INIT
+#define MD5_Update MD5_UPDATE
+#define OPENSSL_add_all_algo_noconf OPENSSL_ADD_ALL_ALGO_NOCONF
+#ifndef __VAX
+#define OPENSSL_load_builtin_modules OPENSSL_LOAD_BUILTIN_MODULES
+#endif
+#define PEM_read_X509 PEM_READ_X509
+#define PEM_write_bio_X509 PEM_WRITE_BIO_X509
+#define PKCS12_PBE_add PKCS12_PBE_ADD
+#define PKCS12_free PKCS12_FREE
+#define PKCS12_parse PKCS12_PARSE
+#define RAND_add RAND_ADD
+#define RAND_bytes RAND_BYTES
+#define RAND_egd RAND_EGD
+#define RAND_file_name RAND_FILE_NAME
+#define RAND_load_file RAND_LOAD_FILE
+#define RAND_status RAND_STATUS
+#define SSL_CIPHER_get_name SSL_CIPHER_GET_NAME
+#define SSL_CTX_add_client_CA SSL_CTX_ADD_CLIENT_CA
+#define SSL_CTX_callback_ctrl SSL_CTX_CALLBACK_CTRL
+#define SSL_CTX_check_private_key SSL_CTX_CHECK_PRIVATE_KEY
+#define SSL_CTX_ctrl SSL_CTX_CTRL
+#define SSL_CTX_free SSL_CTX_FREE
+#define SSL_CTX_get_cert_store SSL_CTX_GET_CERT_STORE
+#define SSL_CTX_load_verify_locations SSL_CTX_LOAD_VERIFY_LOCATIONS
+#define SSL_CTX_new SSL_CTX_NEW
+#define SSL_CTX_set_cipher_list SSL_CTX_SET_CIPHER_LIST
+#define SSL_CTX_set_def_passwd_cb_ud SSL_CTX_SET_DEF_PASSWD_CB_UD
+#define SSL_CTX_set_default_passwd_cb SSL_CTX_SET_DEFAULT_PASSWD_CB
+#define SSL_CTX_set_msg_callback SSL_CTX_SET_MSG_CALLBACK
+#define SSL_CTX_set_verify SSL_CTX_SET_VERIFY
+#define SSL_CTX_use_PrivateKey SSL_CTX_USE_PRIVATEKEY
+#define SSL_CTX_use_PrivateKey_file SSL_CTX_USE_PRIVATEKEY_FILE
+#define SSL_CTX_use_cert_chain_file SSL_CTX_USE_CERT_CHAIN_FILE
+#define SSL_CTX_use_certificate SSL_CTX_USE_CERTIFICATE
+#define SSL_CTX_use_certificate_file SSL_CTX_USE_CERTIFICATE_FILE
+#define SSL_SESSION_free SSL_SESSION_FREE
+#define SSL_connect SSL_CONNECT
+#define SSL_free SSL_FREE
+#define SSL_get1_session SSL_GET1_SESSION
+#define SSL_get_certificate SSL_GET_CERTIFICATE
+#define SSL_get_current_cipher SSL_GET_CURRENT_CIPHER
+#define SSL_get_error SSL_GET_ERROR
+#define SSL_get_peer_cert_chain SSL_GET_PEER_CERT_CHAIN
+#define SSL_get_peer_certificate SSL_GET_PEER_CERTIFICATE
+#define SSL_get_privatekey SSL_GET_PRIVATEKEY
+#define SSL_get_session SSL_GET_SESSION
+#define SSL_get_shutdown SSL_GET_SHUTDOWN
+#define SSL_get_verify_result SSL_GET_VERIFY_RESULT
+#define SSL_library_init SSL_LIBRARY_INIT
+#define SSL_load_error_strings SSL_LOAD_ERROR_STRINGS
+#define SSL_new SSL_NEW
+#define SSL_peek SSL_PEEK
+#define SSL_pending SSL_PENDING
+#define SSL_read SSL_READ
+#define SSL_set_connect_state SSL_SET_CONNECT_STATE
+#define SSL_set_fd SSL_SET_FD
+#define SSL_set_session SSL_SET_SESSION
+#define SSL_shutdown SSL_SHUTDOWN
+#define SSL_version SSL_VERSION
+#define SSL_write SSL_WRITE
+#define SSLeay SSLEAY
+#define SSLv23_client_method SSLV23_CLIENT_METHOD
+#define SSLv3_client_method SSLV3_CLIENT_METHOD
+#define TLSv1_client_method TLSV1_CLIENT_METHOD
+#define UI_create_method UI_CREATE_METHOD
+#define UI_destroy_method UI_DESTROY_METHOD
+#define UI_get0_user_data UI_GET0_USER_DATA
+#define UI_get_input_flags UI_GET_INPUT_FLAGS
+#define UI_get_string_type UI_GET_STRING_TYPE
+#define UI_create_method UI_CREATE_METHOD
+#define UI_destroy_method UI_DESTROY_METHOD
+#define UI_method_get_closer UI_METHOD_GET_CLOSER
+#define UI_method_get_opener UI_METHOD_GET_OPENER
+#define UI_method_get_reader UI_METHOD_GET_READER
+#define UI_method_get_writer UI_METHOD_GET_WRITER
+#define UI_method_set_closer UI_METHOD_SET_CLOSER
+#define UI_method_set_opener UI_METHOD_SET_OPENER
+#define UI_method_set_reader UI_METHOD_SET_READER
+#define UI_method_set_writer UI_METHOD_SET_WRITER
+#define UI_OpenSSL UI_OPENSSL
+#define UI_set_result UI_SET_RESULT
+#define X509V3_EXT_print X509V3_EXT_PRINT
+#define X509_EXTENSION_get_critical X509_EXTENSION_GET_CRITICAL
+#define X509_EXTENSION_get_data X509_EXTENSION_GET_DATA
+#define X509_EXTENSION_get_object X509_EXTENSION_GET_OBJECT
+#define X509_LOOKUP_file X509_LOOKUP_FILE
+#define X509_NAME_ENTRY_get_data X509_NAME_ENTRY_GET_DATA
+#define X509_NAME_get_entry X509_NAME_GET_ENTRY
+#define X509_NAME_get_index_by_NID X509_NAME_GET_INDEX_BY_NID
+#define X509_NAME_print_ex X509_NAME_PRINT_EX
+#define X509_STORE_CTX_get_current_cert X509_STORE_CTX_GET_CURRENT_CERT
+#define X509_STORE_add_lookup X509_STORE_ADD_LOOKUP
+#define X509_STORE_set_flags X509_STORE_SET_FLAGS
+#define X509_check_issued X509_CHECK_ISSUED
+#define X509_free X509_FREE
+#define X509_get_ext_d2i X509_GET_EXT_D2I
+#define X509_get_issuer_name X509_GET_ISSUER_NAME
+#define X509_get_pubkey X509_GET_PUBKEY
+#define X509_get_serialNumber X509_GET_SERIALNUMBER
+#define X509_get_subject_name X509_GET_SUBJECT_NAME
+#define X509_load_crl_file X509_LOAD_CRL_FILE
+#define X509_verify_cert_error_string X509_VERIFY_CERT_ERROR_STRING
+#define d2i_PKCS12_fp D2I_PKCS12_FP
+#define i2t_ASN1_OBJECT I2T_ASN1_OBJECT
+#define sk_num SK_NUM
+#define sk_pop SK_POP
+#define sk_pop_free SK_POP_FREE
+#define sk_value SK_VALUE
+#ifdef __VAX
+#define OPENSSL_NO_SHA256
+#endif
+#define SHA256_Final SHA256_FINAL
+#define SHA256_Init SHA256_INIT
+#define SHA256_Update SHA256_UPDATE
+
+#define USE_UPPERCASE_GSSAPI 1
+#define gss_seal GSS_SEAL
+#define gss_unseal GSS_UNSEAL
+
+#define USE_UPPERCASE_KRBAPI 1
+
+/* AI_NUMERICHOST needed for IP V6 support in Curl */
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#ifndef AI_NUMERICHOST
+#ifdef ENABLE_IPV6
+#undef ENABLE_IPV6
+#endif
+#endif
+#endif
+
+/* VAX symbols are always in uppercase */
+#ifdef __VAX
+#define inflate INFLATE
+#define inflateEnd INFLATEEND
+#define inflateInit2_ INFLATEINIT2_
+#define inflateInit_ INFLATEINIT_
+#define zlibVersion ZLIBVERSION
+#endif
+
+/* Older VAX OpenSSL port defines these as Macros */
+/* Need to include the headers first and then redefine */
+/* that way a newer port will also work if some one has one */
+#ifdef __VAX
+
+#   if (OPENSSL_VERSION_NUMBER < 0x00907001L)
+#       define des_set_odd_parity DES_SET_ODD_PARITY
+#       define des_set_key DES_SET_KEY
+#       define des_ecb_encrypt DES_ECB_ENCRYPT
+
+#   endif
+#   include <openssl/evp.h>
+#   ifndef OpenSSL_add_all_algorithms
+#       define OpenSSL_add_all_algorithms OPENSSL_ADD_ALL_ALGORITHMS
+        void OPENSSL_ADD_ALL_ALGORITHMS(void);
+#   endif
+
+    /* Curl defines these to lower case and VAX needs them in upper case */
+    /* So we need static routines */
+#   if (OPENSSL_VERSION_NUMBER < 0x00907001L)
+
+#       undef des_set_odd_parity
+#       undef DES_set_odd_parity
+#       undef des_set_key
+#       undef DES_set_key
+#       undef des_ecb_encrypt
+#       undef DES_ecb_encrypt
+
+        static void des_set_odd_parity(des_cblock *key) {
+            DES_SET_ODD_PARITY(key);
+        }
+
+        static int des_set_key(const_des_cblock *key,
+                               des_key_schedule schedule) {
+            return DES_SET_KEY(key, schedule);
+        }
+
+        static void des_ecb_encrypt(const_des_cblock *input,
+                                    des_cblock *output,
+                                    des_key_schedule ks, int enc) {
+            DES_ECB_ENCRYPT(input, output, ks, enc);
+        }
+#endif
+/* Need this to stop a macro redefinition error */
+#if OPENSSL_VERSION_NUMBER < 0x00907000L
+#   ifdef X509_STORE_set_flags
+#       undef X509_STORE_set_flags
+#       define X509_STORE_set_flags(x,y) Curl_nop_stmt
+#   endif
+#endif
+#endif
+
+#endif /* HEADER_CURL_SETUP_VMS_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/sha256.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/sha256.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/sha256.c	(revision 331)
@@ -0,0 +1,262 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Florin Petriuc, <petriuc.florin@gmail.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+
+#include "warnless.h"
+#include "curl_sha256.h"
+
+#if defined(USE_OPENSSL)
+
+/* When OpenSSL is available we use the SHA256-function from OpenSSL */
+#include <openssl/sha.h>
+
+#else
+
+/* When no other crypto library is available we use this code segment */
+
+/* ===== start - public domain SHA256 implementation ===== */
+/* This is based on SHA256 implementation in LibTomCrypt that was released into
+ * public domain by Tom St Denis. */
+
+#define WPA_GET_BE32(a) ((((unsigned long)(a)[0]) << 24) | \
+                         (((unsigned long)(a)[1]) << 16) | \
+                         (((unsigned long)(a)[2]) <<  8) | \
+                          ((unsigned long)(a)[3]))
+#define WPA_PUT_BE32(a, val)                                        \
+do {                                                                \
+  (a)[0] = (unsigned char)((((unsigned long) (val)) >> 24) & 0xff); \
+  (a)[1] = (unsigned char)((((unsigned long) (val)) >> 16) & 0xff); \
+  (a)[2] = (unsigned char)((((unsigned long) (val)) >> 8) & 0xff);  \
+  (a)[3] = (unsigned char)(((unsigned long) (val)) & 0xff);         \
+} while(0)
+
+#ifdef HAVE_LONGLONG
+#define WPA_PUT_BE64(a, val)                                    \
+do {                                                            \
+  (a)[0] = (unsigned char)(((unsigned long long)(val)) >> 56);  \
+  (a)[1] = (unsigned char)(((unsigned long long)(val)) >> 48);  \
+  (a)[2] = (unsigned char)(((unsigned long long)(val)) >> 40);  \
+  (a)[3] = (unsigned char)(((unsigned long long)(val)) >> 32);  \
+  (a)[4] = (unsigned char)(((unsigned long long)(val)) >> 24);  \
+  (a)[5] = (unsigned char)(((unsigned long long)(val)) >> 16);  \
+  (a)[6] = (unsigned char)(((unsigned long long)(val)) >> 8);   \
+  (a)[7] = (unsigned char)(((unsigned long long)(val)) & 0xff); \
+} while(0)
+#else
+#define WPA_PUT_BE64(a, val)                                  \
+do {                                                          \
+  (a)[0] = (unsigned char)(((unsigned __int64)(val)) >> 56);  \
+  (a)[1] = (unsigned char)(((unsigned __int64)(val)) >> 48);  \
+  (a)[2] = (unsigned char)(((unsigned __int64)(val)) >> 40);  \
+  (a)[3] = (unsigned char)(((unsigned __int64)(val)) >> 32);  \
+  (a)[4] = (unsigned char)(((unsigned __int64)(val)) >> 24);  \
+  (a)[5] = (unsigned char)(((unsigned __int64)(val)) >> 16);  \
+  (a)[6] = (unsigned char)(((unsigned __int64)(val)) >> 8);   \
+  (a)[7] = (unsigned char)(((unsigned __int64)(val)) & 0xff); \
+} while(0)
+#endif
+
+typedef struct sha256_state {
+#ifdef HAVE_LONGLONG
+  unsigned long long length;
+#else
+  unsigned __int64 length;
+#endif
+  unsigned long state[8], curlen;
+  unsigned char buf[64];
+} SHA256_CTX;
+/* the K array */
+static const unsigned long K[64] = {
+  0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
+  0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
+  0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
+  0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+  0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
+  0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
+  0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
+  0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+  0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
+  0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
+  0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
+  0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+  0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+};
+/* Various logical functions */
+#define RORc(x, y) \
+(((((unsigned long)(x) & 0xFFFFFFFFUL) >> (unsigned long)((y) & 31)) | \
+   ((unsigned long)(x) << (unsigned long)(32 - ((y) & 31)))) & 0xFFFFFFFFUL)
+#define Ch(x,y,z)   (z ^ (x & (y ^ z)))
+#define Maj(x,y,z)  (((x | y) & z) | (x & y))
+#define S(x, n)     RORc((x), (n))
+#define R(x, n)     (((x)&0xFFFFFFFFUL)>>(n))
+#define Sigma0(x)   (S(x, 2) ^ S(x, 13) ^ S(x, 22))
+#define Sigma1(x)   (S(x, 6) ^ S(x, 11) ^ S(x, 25))
+#define Gamma0(x)   (S(x, 7) ^ S(x, 18) ^ R(x, 3))
+#define Gamma1(x)   (S(x, 17) ^ S(x, 19) ^ R(x, 10))
+#ifndef MIN
+#define MIN(x, y)   (((x) < (y)) ? (x) : (y))
+#endif
+/* compress 512-bits */
+static int sha256_compress(struct sha256_state *md,
+                           unsigned char *buf)
+{
+  unsigned long S[8], W[64], t0, t1;
+  unsigned long t;
+  int i;
+  /* copy state into S */
+  for(i = 0; i < 8; i++) {
+    S[i] = md->state[i];
+  }
+  /* copy the state into 512-bits into W[0..15] */
+  for(i = 0; i < 16; i++)
+    W[i] = WPA_GET_BE32(buf + (4 * i));
+  /* fill W[16..63] */
+  for(i = 16; i < 64; i++) {
+    W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) +
+      W[i - 16];
+  }
+  /* Compress */
+#define RND(a,b,c,d,e,f,g,h,i)                    \
+  t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
+  t1 = Sigma0(a) + Maj(a, b, c);                  \
+  d += t0;                                        \
+  h = t0 + t1;
+  for(i = 0; i < 64; ++i) {
+    RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
+    t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
+    S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
+  }
+  /* feedback */
+  for(i = 0; i < 8; i++) {
+    md->state[i] = md->state[i] + S[i];
+  }
+  return 0;
+}
+/* Initialize the hash state */
+static void SHA256_Init(struct sha256_state *md)
+{
+  md->curlen = 0;
+  md->length = 0;
+  md->state[0] = 0x6A09E667UL;
+  md->state[1] = 0xBB67AE85UL;
+  md->state[2] = 0x3C6EF372UL;
+  md->state[3] = 0xA54FF53AUL;
+  md->state[4] = 0x510E527FUL;
+  md->state[5] = 0x9B05688CUL;
+  md->state[6] = 0x1F83D9ABUL;
+  md->state[7] = 0x5BE0CD19UL;
+}
+/**
+   Process a block of memory though the hash
+   @param md     The hash state
+   @param in     The data to hash
+   @param inlen  The length of the data (octets)
+   @return CRYPT_OK if successful
+*/
+static int SHA256_Update(struct sha256_state *md,
+                         const unsigned char *in,
+                         unsigned long inlen)
+{
+  unsigned long n;
+#define block_size 64
+  if(md->curlen > sizeof(md->buf))
+    return -1;
+  while(inlen > 0) {
+    if(md->curlen == 0 && inlen >= block_size) {
+      if(sha256_compress(md, (unsigned char *)in) < 0)
+        return -1;
+      md->length += block_size * 8;
+      in += block_size;
+      inlen -= block_size;
+    }
+    else {
+      n = MIN(inlen, (block_size - md->curlen));
+      memcpy(md->buf + md->curlen, in, n);
+      md->curlen += n;
+      in += n;
+      inlen -= n;
+      if(md->curlen == block_size) {
+        if(sha256_compress(md, md->buf) < 0)
+          return -1;
+        md->length += 8 * block_size;
+        md->curlen = 0;
+      }
+    }
+  }
+  return 0;
+}
+/**
+   Terminate the hash to get the digest
+   @param md  The hash state
+   @param out [out] The destination of the hash (32 bytes)
+   @return CRYPT_OK if successful
+*/
+static int SHA256_Final(unsigned char *out,
+                        struct sha256_state *md)
+{
+  int i;
+  if(md->curlen >= sizeof(md->buf))
+    return -1;
+  /* increase the length of the message */
+  md->length += md->curlen * 8;
+  /* append the '1' bit */
+  md->buf[md->curlen++] = (unsigned char)0x80;
+  /* if the length is currently above 56 bytes we append zeros
+   * then compress.  Then we can fall back to padding zeros and length
+   * encoding like normal.
+   */
+  if(md->curlen > 56) {
+    while(md->curlen < 64) {
+      md->buf[md->curlen++] = (unsigned char)0;
+    }
+    sha256_compress(md, md->buf);
+    md->curlen = 0;
+  }
+  /* pad upto 56 bytes of zeroes */
+  while(md->curlen < 56) {
+    md->buf[md->curlen++] = (unsigned char)0;
+  }
+  /* store length */
+  WPA_PUT_BE64(md->buf + 56, md->length);
+  sha256_compress(md, md->buf);
+  /* copy output */
+  for(i = 0; i < 8; i++)
+    WPA_PUT_BE32(out + (4 * i), md->state[i]);
+  return 0;
+}
+/* ===== end - public domain SHA256 implementation ===== */
+
+#endif
+
+void Curl_sha256it(unsigned char *outbuffer, /* 32 unsigned chars */
+                   const unsigned char *input)
+{
+  SHA256_CTX ctx;
+  SHA256_Init(&ctx);
+  SHA256_Update(&ctx, input, curlx_uztoui(strlen((char *)input)));
+  SHA256_Final(outbuffer, &ctx);
+}
+
+#endif /* CURL_DISABLE_CRYPTO_AUTH */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/share.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/share.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/share.c	(revision 331)
@@ -0,0 +1,248 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "share.h"
+#include "vtls/vtls.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+struct Curl_share *
+curl_share_init(void)
+{
+  struct Curl_share *share = calloc(1, sizeof(struct Curl_share));
+  if(share) {
+    share->specifier |= (1<<CURL_LOCK_DATA_SHARE);
+
+    if(Curl_mk_dnscache(&share->hostcache)) {
+      free(share);
+      return NULL;
+    }
+  }
+
+  return share;
+}
+
+#undef curl_share_setopt
+CURLSHcode
+curl_share_setopt(struct Curl_share *share, CURLSHoption option, ...)
+{
+  va_list param;
+  int type;
+  curl_lock_function lockfunc;
+  curl_unlock_function unlockfunc;
+  void *ptr;
+  CURLSHcode res = CURLSHE_OK;
+
+  if(share->dirty)
+    /* don't allow setting options while one or more handles are already
+       using this share */
+    return CURLSHE_IN_USE;
+
+  va_start(param, option);
+
+  switch(option) {
+  case CURLSHOPT_SHARE:
+    /* this is a type this share will share */
+    type = va_arg(param, int);
+    share->specifier |= (1<<type);
+    switch(type) {
+    case CURL_LOCK_DATA_DNS:
+      break;
+
+    case CURL_LOCK_DATA_COOKIE:
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+      if(!share->cookies) {
+        share->cookies = Curl_cookie_init(NULL, NULL, NULL, TRUE);
+        if(!share->cookies)
+          res = CURLSHE_NOMEM;
+      }
+#else   /* CURL_DISABLE_HTTP */
+      res = CURLSHE_NOT_BUILT_IN;
+#endif
+      break;
+
+    case CURL_LOCK_DATA_SSL_SESSION:
+#ifdef USE_SSL
+      if(!share->sslsession) {
+        share->max_ssl_sessions = 8;
+        share->sslsession = calloc(share->max_ssl_sessions,
+                                   sizeof(struct curl_ssl_session));
+        share->sessionage = 0;
+        if(!share->sslsession)
+          res = CURLSHE_NOMEM;
+      }
+#else
+      res = CURLSHE_NOT_BUILT_IN;
+#endif
+      break;
+
+    case CURL_LOCK_DATA_CONNECT:     /* not supported (yet) */
+      if(Curl_conncache_init(&share->conn_cache, 103))
+        res = CURLSHE_NOMEM;
+      break;
+
+    default:
+      res = CURLSHE_BAD_OPTION;
+    }
+    break;
+
+  case CURLSHOPT_UNSHARE:
+    /* this is a type this share will no longer share */
+    type = va_arg(param, int);
+    share->specifier &= ~(1<<type);
+    switch(type) {
+    case CURL_LOCK_DATA_DNS:
+      break;
+
+    case CURL_LOCK_DATA_COOKIE:
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+      if(share->cookies) {
+        Curl_cookie_cleanup(share->cookies);
+        share->cookies = NULL;
+      }
+#else   /* CURL_DISABLE_HTTP */
+      res = CURLSHE_NOT_BUILT_IN;
+#endif
+      break;
+
+    case CURL_LOCK_DATA_SSL_SESSION:
+#ifdef USE_SSL
+      Curl_safefree(share->sslsession);
+#else
+      res = CURLSHE_NOT_BUILT_IN;
+#endif
+      break;
+
+    case CURL_LOCK_DATA_CONNECT:
+      break;
+
+    default:
+      res = CURLSHE_BAD_OPTION;
+      break;
+    }
+    break;
+
+  case CURLSHOPT_LOCKFUNC:
+    lockfunc = va_arg(param, curl_lock_function);
+    share->lockfunc = lockfunc;
+    break;
+
+  case CURLSHOPT_UNLOCKFUNC:
+    unlockfunc = va_arg(param, curl_unlock_function);
+    share->unlockfunc = unlockfunc;
+    break;
+
+  case CURLSHOPT_USERDATA:
+    ptr = va_arg(param, void *);
+    share->clientdata = ptr;
+    break;
+
+  default:
+    res = CURLSHE_BAD_OPTION;
+    break;
+  }
+
+  va_end(param);
+
+  return res;
+}
+
+CURLSHcode
+curl_share_cleanup(struct Curl_share *share)
+{
+  if(share == NULL)
+    return CURLSHE_INVALID;
+
+  if(share->lockfunc)
+    share->lockfunc(NULL, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE,
+                    share->clientdata);
+
+  if(share->dirty) {
+    if(share->unlockfunc)
+      share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
+    return CURLSHE_IN_USE;
+  }
+
+  Curl_conncache_close_all_connections(&share->conn_cache);
+  Curl_conncache_destroy(&share->conn_cache);
+  Curl_hash_destroy(&share->hostcache);
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+  Curl_cookie_cleanup(share->cookies);
+#endif
+
+#ifdef USE_SSL
+  if(share->sslsession) {
+    size_t i;
+    for(i = 0; i < share->max_ssl_sessions; i++)
+      Curl_ssl_kill_session(&(share->sslsession[i]));
+    free(share->sslsession);
+  }
+#endif
+
+  if(share->unlockfunc)
+    share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata);
+  free(share);
+
+  return CURLSHE_OK;
+}
+
+
+CURLSHcode
+Curl_share_lock(struct Curl_easy *data, curl_lock_data type,
+                curl_lock_access accesstype)
+{
+  struct Curl_share *share = data->share;
+
+  if(share == NULL)
+    return CURLSHE_INVALID;
+
+  if(share->specifier & (1<<type)) {
+    if(share->lockfunc) /* only call this if set! */
+      share->lockfunc(data, type, accesstype, share->clientdata);
+  }
+  /* else if we don't share this, pretend successful lock */
+
+  return CURLSHE_OK;
+}
+
+CURLSHcode
+Curl_share_unlock(struct Curl_easy *data, curl_lock_data type)
+{
+  struct Curl_share *share = data->share;
+
+  if(share == NULL)
+    return CURLSHE_INVALID;
+
+  if(share->specifier & (1<<type)) {
+    if(share->unlockfunc) /* only call this if set! */
+      share->unlockfunc (data, type, share->clientdata);
+  }
+
+  return CURLSHE_OK;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/share.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/share.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/share.h	(revision 331)
@@ -0,0 +1,62 @@
+#ifndef HEADER_CURL_SHARE_H
+#define HEADER_CURL_SHARE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include <curl/curl.h>
+#include "cookie.h"
+#include "urldata.h"
+#include "conncache.h"
+
+/* SalfordC says "A structure member may not be volatile". Hence:
+ */
+#ifdef __SALFORDC__
+#define CURL_VOLATILE
+#else
+#define CURL_VOLATILE volatile
+#endif
+
+/* this struct is libcurl-private, don't export details */
+struct Curl_share {
+  unsigned int specifier;
+  CURL_VOLATILE unsigned int dirty;
+
+  curl_lock_function lockfunc;
+  curl_unlock_function unlockfunc;
+  void *clientdata;
+  struct conncache conn_cache;
+  struct curl_hash hostcache;
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+  struct CookieInfo *cookies;
+#endif
+
+  struct curl_ssl_session *sslsession;
+  size_t max_ssl_sessions;
+  long sessionage;
+};
+
+CURLSHcode Curl_share_lock(struct Curl_easy *, curl_lock_data,
+                           curl_lock_access);
+CURLSHcode Curl_share_unlock(struct Curl_easy *, curl_lock_data);
+
+#endif /* HEADER_CURL_SHARE_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/sigpipe.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/sigpipe.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/sigpipe.h	(revision 331)
@@ -0,0 +1,78 @@
+#ifndef HEADER_CURL_SIGPIPE_H
+#define HEADER_CURL_SIGPIPE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if defined(HAVE_SIGNAL_H) && defined(HAVE_SIGACTION) && defined(USE_OPENSSL)
+#include <signal.h>
+
+struct sigpipe_ignore {
+  struct sigaction old_pipe_act;
+  bool no_signal;
+};
+
+#define SIGPIPE_VARIABLE(x) struct sigpipe_ignore x
+
+/*
+ * sigpipe_ignore() makes sure we ignore SIGPIPE while running libcurl
+ * internals, and then sigpipe_restore() will restore the situation when we
+ * return from libcurl again.
+ */
+static void sigpipe_ignore(struct Curl_easy *data,
+                           struct sigpipe_ignore *ig)
+{
+  /* get a local copy of no_signal because the Curl_easy might not be
+     around when we restore */
+  ig->no_signal = data->set.no_signal;
+  if(!data->set.no_signal) {
+    struct sigaction action;
+    /* first, extract the existing situation */
+    memset(&ig->old_pipe_act, 0, sizeof(struct sigaction));
+    sigaction(SIGPIPE, NULL, &ig->old_pipe_act);
+    action = ig->old_pipe_act;
+    /* ignore this signal */
+    action.sa_handler = SIG_IGN;
+    sigaction(SIGPIPE, &action, NULL);
+  }
+}
+
+/*
+ * sigpipe_restore() puts back the outside world's opinion of signal handler
+ * and SIGPIPE handling. It MUST only be called after a corresponding
+ * sigpipe_ignore() was used.
+ */
+static void sigpipe_restore(struct sigpipe_ignore *ig)
+{
+  if(!ig->no_signal)
+    /* restore the outside state */
+    sigaction(SIGPIPE, &ig->old_pipe_act, NULL);
+}
+
+#else
+/* for systems without sigaction */
+#define sigpipe_ignore(x,y) Curl_nop_stmt
+#define sigpipe_restore(x)  Curl_nop_stmt
+#define SIGPIPE_VARIABLE(x)
+#endif
+
+#endif /* HEADER_CURL_SIGPIPE_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/slist.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/slist.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/slist.c	(revision 331)
@@ -0,0 +1,145 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "slist.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* returns last node in linked list */
+static struct curl_slist *slist_get_last(struct curl_slist *list)
+{
+  struct curl_slist     *item;
+
+  /* if caller passed us a NULL, return now */
+  if(!list)
+    return NULL;
+
+  /* loop through to find the last item */
+  item = list;
+  while(item->next) {
+    item = item->next;
+  }
+  return item;
+}
+
+/*
+ * Curl_slist_append_nodup() appends a string to the linked list. Rather than
+ * copying the string in dynamic storage, it takes its ownership. The string
+ * should have been malloc()ated. Curl_slist_append_nodup always returns
+ * the address of the first record, so that you can use this function as an
+ * initialization function as well as an append function.
+ * If an error occurs, NULL is returned and the string argument is NOT
+ * released.
+ */
+struct curl_slist *Curl_slist_append_nodup(struct curl_slist *list, char *data)
+{
+  struct curl_slist     *last;
+  struct curl_slist     *new_item;
+
+  DEBUGASSERT(data);
+
+  new_item = malloc(sizeof(struct curl_slist));
+  if(!new_item)
+    return NULL;
+
+  new_item->next = NULL;
+  new_item->data = data;
+
+  /* if this is the first item, then new_item *is* the list */
+  if(!list)
+    return new_item;
+
+  last = slist_get_last(list);
+  last->next = new_item;
+  return list;
+}
+
+/*
+ * curl_slist_append() appends a string to the linked list. It always returns
+ * the address of the first record, so that you can use this function as an
+ * initialization function as well as an append function. If you find this
+ * bothersome, then simply create a separate _init function and call it
+ * appropriately from within the program.
+ */
+struct curl_slist *curl_slist_append(struct curl_slist *list,
+                                     const char *data)
+{
+  char *dupdata = strdup(data);
+
+  if(!dupdata)
+    return NULL;
+
+  list = Curl_slist_append_nodup(list, dupdata);
+  if(!list)
+    free(dupdata);
+
+  return list;
+}
+
+/*
+ * Curl_slist_duplicate() duplicates a linked list. It always returns the
+ * address of the first record of the cloned list or NULL in case of an
+ * error (or if the input list was NULL).
+ */
+struct curl_slist *Curl_slist_duplicate(struct curl_slist *inlist)
+{
+  struct curl_slist *outlist = NULL;
+  struct curl_slist *tmp;
+
+  while(inlist) {
+    tmp = curl_slist_append(outlist, inlist->data);
+
+    if(!tmp) {
+      curl_slist_free_all(outlist);
+      return NULL;
+    }
+
+    outlist = tmp;
+    inlist = inlist->next;
+  }
+  return outlist;
+}
+
+/* be nice and clean up resources */
+void curl_slist_free_all(struct curl_slist *list)
+{
+  struct curl_slist     *next;
+  struct curl_slist     *item;
+
+  if(!list)
+    return;
+
+  item = list;
+  do {
+    next = item->next;
+    Curl_safefree(item->data);
+    free(item);
+    item = next;
+  } while(next);
+}
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/slist.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/slist.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/slist.h	(revision 331)
@@ -0,0 +1,40 @@
+#ifndef HEADER_CURL_SLIST_H
+#define HEADER_CURL_SLIST_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Curl_slist_duplicate() duplicates a linked list. It always returns the
+ * address of the first record of the cloned list or NULL in case of an
+ * error (or if the input list was NULL).
+ */
+struct curl_slist *Curl_slist_duplicate(struct curl_slist *inlist);
+
+/*
+ * Curl_slist_append_nodup() takes ownership of the given string and appends
+ * it to the list.
+ */
+struct curl_slist *Curl_slist_append_nodup(struct curl_slist *list,
+                                           char *data);
+
+#endif /* HEADER_CURL_SLIST_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/smb.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/smb.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/smb.c	(revision 331)
@@ -0,0 +1,1005 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies
+ * Copyright (C) 2016-2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) &&  \
+  (CURL_SIZEOF_CURL_OFF_T > 4)
+
+#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
+
+#define BUILDING_CURL_SMB_C
+
+#ifdef HAVE_PROCESS_H
+#include <process.h>
+#ifdef CURL_WINDOWS_APP
+#define getpid GetCurrentProcessId
+#elif !defined(MSDOS)
+#define getpid _getpid
+#endif
+#endif
+
+#include "smb.h"
+#include "urldata.h"
+#include "sendf.h"
+#include "multiif.h"
+#include "connect.h"
+#include "progress.h"
+#include "transfer.h"
+#include "vtls/vtls.h"
+#include "curl_ntlm_core.h"
+#include "escape.h"
+#include "curl_endian.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Local API functions */
+static CURLcode smb_setup_connection(struct connectdata *conn);
+static CURLcode smb_connect(struct connectdata *conn, bool *done);
+static CURLcode smb_connection_state(struct connectdata *conn, bool *done);
+static CURLcode smb_request_state(struct connectdata *conn, bool *done);
+static CURLcode smb_done(struct connectdata *conn, CURLcode status,
+                         bool premature);
+static CURLcode smb_disconnect(struct connectdata *conn, bool dead);
+static int smb_getsock(struct connectdata *conn, curl_socket_t *socks,
+                       int numsocks);
+static CURLcode smb_parse_url_path(struct connectdata *conn);
+
+/*
+ * SMB handler interface
+ */
+const struct Curl_handler Curl_handler_smb = {
+  "SMB",                                /* scheme */
+  smb_setup_connection,                 /* setup_connection */
+  ZERO_NULL,                            /* do_it */
+  smb_done,                             /* done */
+  ZERO_NULL,                            /* do_more */
+  smb_connect,                          /* connect_it */
+  smb_connection_state,                 /* connecting */
+  smb_request_state,                    /* doing */
+  smb_getsock,                          /* proto_getsock */
+  smb_getsock,                          /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  smb_disconnect,                       /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_SMB,                             /* defport */
+  CURLPROTO_SMB,                        /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+
+#ifdef USE_SSL
+/*
+ * SMBS handler interface
+ */
+const struct Curl_handler Curl_handler_smbs = {
+  "SMBS",                               /* scheme */
+  smb_setup_connection,                 /* setup_connection */
+  ZERO_NULL,                            /* do_it */
+  smb_done,                             /* done */
+  ZERO_NULL,                            /* do_more */
+  smb_connect,                          /* connect_it */
+  smb_connection_state,                 /* connecting */
+  smb_request_state,                    /* doing */
+  smb_getsock,                          /* proto_getsock */
+  smb_getsock,                          /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  smb_disconnect,                       /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_SMBS,                            /* defport */
+  CURLPROTO_SMBS,                       /* protocol */
+  PROTOPT_SSL                           /* flags */
+};
+#endif
+
+#define MAX_PAYLOAD_SIZE  0x8000
+#define MAX_MESSAGE_SIZE  (MAX_PAYLOAD_SIZE + 0x1000)
+#define CLIENTNAME        "curl"
+#define SERVICENAME       "?????"
+
+/* Append a string to an SMB message */
+#define MSGCAT(str)                             \
+  strcpy(p, (str));                             \
+  p += strlen(str);
+
+/* Append a null-terminated string to an SMB message */
+#define MSGCATNULL(str)                         \
+  strcpy(p, (str));                             \
+  p += strlen(str) + 1;
+
+/* SMB is mostly little endian */
+#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \
+  defined(__OS400__)
+static unsigned short smb_swap16(unsigned short x)
+{
+  return (unsigned short) ((x << 8) | ((x >> 8) & 0xff));
+}
+
+static unsigned int smb_swap32(unsigned int x)
+{
+  return (x << 24) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) |
+    ((x >> 24) & 0xff);
+}
+
+#ifdef HAVE_LONGLONG
+static unsigned long long smb_swap64(unsigned long long x)
+{
+  return ((unsigned long long) smb_swap32((unsigned int) x) << 32) |
+    smb_swap32((unsigned int) (x >> 32));
+}
+#else
+static unsigned __int64 smb_swap64(unsigned __int64 x)
+{
+  return ((unsigned __int64) smb_swap32((unsigned int) x) << 32) |
+    smb_swap32((unsigned int) (x >> 32));
+}
+#endif
+#else
+#  define smb_swap16(x) (x)
+#  define smb_swap32(x) (x)
+#  define smb_swap64(x) (x)
+#endif
+
+/* SMB request state */
+enum smb_req_state {
+  SMB_REQUESTING,
+  SMB_TREE_CONNECT,
+  SMB_OPEN,
+  SMB_DOWNLOAD,
+  SMB_UPLOAD,
+  SMB_CLOSE,
+  SMB_TREE_DISCONNECT,
+  SMB_DONE
+};
+
+/* SMB request data */
+struct smb_request {
+  enum smb_req_state state;
+  char *share;
+  char *path;
+  unsigned short tid; /* Even if we connect to the same tree as another */
+  unsigned short fid; /* request, the tid will be different */
+  CURLcode result;
+};
+
+static void conn_state(struct connectdata *conn, enum smb_conn_state newstate)
+{
+  struct smb_conn *smb = &conn->proto.smbc;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* For debug purposes */
+  static const char * const names[] = {
+    "SMB_NOT_CONNECTED",
+    "SMB_CONNECTING",
+    "SMB_NEGOTIATE",
+    "SMB_SETUP",
+    "SMB_CONNECTED",
+    /* LAST */
+  };
+
+  if(smb->state != newstate)
+    infof(conn->data, "SMB conn %p state change from %s to %s\n",
+          (void *)smb, names[smb->state], names[newstate]);
+#endif
+
+  smb->state = newstate;
+}
+
+static void request_state(struct connectdata *conn,
+                          enum smb_req_state newstate)
+{
+  struct smb_request *req = conn->data->req.protop;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* For debug purposes */
+  static const char * const names[] = {
+    "SMB_REQUESTING",
+    "SMB_TREE_CONNECT",
+    "SMB_OPEN",
+    "SMB_DOWNLOAD",
+    "SMB_UPLOAD",
+    "SMB_CLOSE",
+    "SMB_TREE_DISCONNECT",
+    "SMB_DONE",
+    /* LAST */
+  };
+
+  if(req->state != newstate)
+    infof(conn->data, "SMB request %p state change from %s to %s\n",
+          (void *)req, names[req->state], names[newstate]);
+#endif
+
+  req->state = newstate;
+}
+
+static CURLcode smb_setup_connection(struct connectdata *conn)
+{
+  struct smb_request *req;
+
+  /* Initialize the request state */
+  conn->data->req.protop = req = calloc(1, sizeof(struct smb_request));
+  if(!req)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Parse the URL path */
+  return smb_parse_url_path(conn);
+}
+
+static CURLcode smb_connect(struct connectdata *conn, bool *done)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  char *slash;
+
+  (void) done;
+
+  /* Check we have a username and password to authenticate with */
+  if(!conn->bits.user_passwd)
+    return CURLE_LOGIN_DENIED;
+
+  /* Initialize the connection state */
+  memset(smbc, 0, sizeof(*smbc));
+  smbc->state = SMB_CONNECTING;
+  smbc->recv_buf = malloc(MAX_MESSAGE_SIZE);
+  if(!smbc->recv_buf)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Multiple requests are allowed with this connection */
+  connkeep(conn, "SMB default");
+
+  /* Parse the username, domain, and password */
+  slash = strchr(conn->user, '/');
+  if(!slash)
+    slash = strchr(conn->user, '\\');
+
+  if(slash) {
+    smbc->user = slash + 1;
+    smbc->domain = strdup(conn->user);
+    if(!smbc->domain)
+      return CURLE_OUT_OF_MEMORY;
+    smbc->domain[slash - conn->user] = 0;
+  }
+  else {
+    smbc->user = conn->user;
+    smbc->domain = strdup(conn->host.name);
+    if(!smbc->domain)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode smb_recv_message(struct connectdata *conn, void **msg)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  char *buf = smbc->recv_buf;
+  ssize_t bytes_read;
+  size_t nbt_size;
+  size_t msg_size;
+  size_t len = MAX_MESSAGE_SIZE - smbc->got;
+  CURLcode result;
+
+  result = Curl_read(conn, FIRSTSOCKET, buf + smbc->got, len, &bytes_read);
+  if(result)
+    return result;
+
+  if(!bytes_read)
+    return CURLE_OK;
+
+  smbc->got += bytes_read;
+
+  /* Check for a 32-bit nbt header */
+  if(smbc->got < sizeof(unsigned int))
+    return CURLE_OK;
+
+  nbt_size = Curl_read16_be((const unsigned char *)
+                            (buf + sizeof(unsigned short))) +
+    sizeof(unsigned int);
+  if(smbc->got < nbt_size)
+    return CURLE_OK;
+
+  msg_size = sizeof(struct smb_header);
+  if(nbt_size >= msg_size + 1) {
+    /* Add the word count */
+    msg_size += 1 + ((unsigned char) buf[msg_size]) * sizeof(unsigned short);
+    if(nbt_size >= msg_size + sizeof(unsigned short)) {
+      /* Add the byte count */
+      msg_size += sizeof(unsigned short) +
+        Curl_read16_le((const unsigned char *)&buf[msg_size]);
+      if(nbt_size < msg_size)
+        return CURLE_READ_ERROR;
+    }
+  }
+
+  *msg = buf;
+
+  return CURLE_OK;
+}
+
+static void smb_pop_message(struct connectdata *conn)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+
+  smbc->got = 0;
+}
+
+static void smb_format_message(struct connectdata *conn, struct smb_header *h,
+                               unsigned char cmd, size_t len)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  struct smb_request *req = conn->data->req.protop;
+  unsigned int pid;
+
+  memset(h, 0, sizeof(*h));
+  h->nbt_length = htons((unsigned short) (sizeof(*h) - sizeof(unsigned int) +
+                                          len));
+  memcpy((char *)h->magic, "\xffSMB", 4);
+  h->command = cmd;
+  h->flags = SMB_FLAGS_CANONICAL_PATHNAMES | SMB_FLAGS_CASELESS_PATHNAMES;
+  h->flags2 = smb_swap16(SMB_FLAGS2_IS_LONG_NAME | SMB_FLAGS2_KNOWS_LONG_NAME);
+  h->uid = smb_swap16(smbc->uid);
+  h->tid = smb_swap16(req->tid);
+  pid = getpid();
+  h->pid_high = smb_swap16((unsigned short)(pid >> 16));
+  h->pid = smb_swap16((unsigned short) pid);
+}
+
+static CURLcode smb_send(struct connectdata *conn, ssize_t len,
+                         size_t upload_size)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  ssize_t bytes_written;
+  CURLcode result;
+
+  result = Curl_write(conn, FIRSTSOCKET, conn->data->state.uploadbuffer,
+                      len, &bytes_written);
+  if(result)
+    return result;
+
+  if(bytes_written != len) {
+    smbc->send_size = len;
+    smbc->sent = bytes_written;
+  }
+
+  smbc->upload_size = upload_size;
+
+  return CURLE_OK;
+}
+
+static CURLcode smb_flush(struct connectdata *conn)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  ssize_t bytes_written;
+  ssize_t len = smbc->send_size - smbc->sent;
+  CURLcode result;
+
+  if(!smbc->send_size)
+    return CURLE_OK;
+
+  result = Curl_write(conn, FIRSTSOCKET,
+                      conn->data->state.uploadbuffer + smbc->sent,
+                      len, &bytes_written);
+  if(result)
+    return result;
+
+  if(bytes_written != len)
+    smbc->sent += bytes_written;
+  else
+    smbc->send_size = 0;
+
+  return CURLE_OK;
+}
+
+static CURLcode smb_send_message(struct connectdata *conn, unsigned char cmd,
+                                 const void *msg, size_t msg_len)
+{
+  smb_format_message(conn, (struct smb_header *)conn->data->state.uploadbuffer,
+                     cmd, msg_len);
+  memcpy(conn->data->state.uploadbuffer + sizeof(struct smb_header),
+         msg, msg_len);
+
+  return smb_send(conn, sizeof(struct smb_header) + msg_len, 0);
+}
+
+static CURLcode smb_send_negotiate(struct connectdata *conn)
+{
+  const char *msg = "\x00\x0c\x00\x02NT LM 0.12";
+
+  return smb_send_message(conn, SMB_COM_NEGOTIATE, msg, 15);
+}
+
+static CURLcode smb_send_setup(struct connectdata *conn)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  struct smb_setup msg;
+  char *p = msg.bytes;
+  unsigned char lm_hash[21];
+  unsigned char lm[24];
+  unsigned char nt_hash[21];
+  unsigned char nt[24];
+
+  size_t byte_count = sizeof(lm) + sizeof(nt);
+  byte_count += strlen(smbc->user) + strlen(smbc->domain);
+  byte_count += strlen(OS) + strlen(CLIENTNAME) + 4; /* 4 null chars */
+  if(byte_count > sizeof(msg.bytes))
+    return CURLE_FILESIZE_EXCEEDED;
+
+  Curl_ntlm_core_mk_lm_hash(conn->data, conn->passwd, lm_hash);
+  Curl_ntlm_core_lm_resp(lm_hash, smbc->challenge, lm);
+#ifdef USE_NTRESPONSES
+  Curl_ntlm_core_mk_nt_hash(conn->data, conn->passwd, nt_hash);
+  Curl_ntlm_core_lm_resp(nt_hash, smbc->challenge, nt);
+#else
+  memset(nt, 0, sizeof(nt));
+#endif
+
+  memset(&msg, 0, sizeof(msg));
+  msg.word_count = SMB_WC_SETUP_ANDX;
+  msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
+  msg.max_buffer_size = smb_swap16(MAX_MESSAGE_SIZE);
+  msg.max_mpx_count = smb_swap16(1);
+  msg.vc_number = smb_swap16(1);
+  msg.session_key = smb_swap32(smbc->session_key);
+  msg.capabilities = smb_swap32(SMB_CAP_LARGE_FILES);
+  msg.lengths[0] = smb_swap16(sizeof(lm));
+  msg.lengths[1] = smb_swap16(sizeof(nt));
+  memcpy(p, lm, sizeof(lm));
+  p += sizeof(lm);
+  memcpy(p, nt, sizeof(nt));
+  p += sizeof(nt);
+  MSGCATNULL(smbc->user);
+  MSGCATNULL(smbc->domain);
+  MSGCATNULL(OS);
+  MSGCATNULL(CLIENTNAME);
+  byte_count = p - msg.bytes;
+  msg.byte_count = smb_swap16((unsigned short)byte_count);
+
+  return smb_send_message(conn, SMB_COM_SETUP_ANDX, &msg,
+                          sizeof(msg) - sizeof(msg.bytes) + byte_count);
+}
+
+static CURLcode smb_send_tree_connect(struct connectdata *conn)
+{
+  struct smb_request *req = conn->data->req.protop;
+  struct smb_tree_connect msg;
+  char *p = msg.bytes;
+
+  size_t byte_count = strlen(conn->host.name) + strlen(req->share);
+  byte_count += strlen(SERVICENAME) + 5; /* 2 nulls and 3 backslashes */
+  if(byte_count > sizeof(msg.bytes))
+    return CURLE_FILESIZE_EXCEEDED;
+
+  memset(&msg, 0, sizeof(msg));
+  msg.word_count = SMB_WC_TREE_CONNECT_ANDX;
+  msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
+  msg.pw_len = 0;
+  MSGCAT("\\\\");
+  MSGCAT(conn->host.name);
+  MSGCAT("\\");
+  MSGCATNULL(req->share);
+  MSGCATNULL(SERVICENAME); /* Match any type of service */
+  byte_count = p - msg.bytes;
+  msg.byte_count = smb_swap16((unsigned short)byte_count);
+
+  return smb_send_message(conn, SMB_COM_TREE_CONNECT_ANDX, &msg,
+                          sizeof(msg) - sizeof(msg.bytes) + byte_count);
+}
+
+static CURLcode smb_send_open(struct connectdata *conn)
+{
+  struct smb_request *req = conn->data->req.protop;
+  struct smb_nt_create msg;
+  size_t byte_count;
+
+  if((strlen(req->path) + 1) > sizeof(msg.bytes))
+    return CURLE_FILESIZE_EXCEEDED;
+
+  memset(&msg, 0, sizeof(msg));
+  msg.word_count = SMB_WC_NT_CREATE_ANDX;
+  msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
+  byte_count = strlen(req->path);
+  msg.name_length = smb_swap16((unsigned short)byte_count);
+  msg.share_access = smb_swap32(SMB_FILE_SHARE_ALL);
+  if(conn->data->set.upload) {
+    msg.access = smb_swap32(SMB_GENERIC_READ | SMB_GENERIC_WRITE);
+    msg.create_disposition = smb_swap32(SMB_FILE_OVERWRITE_IF);
+  }
+  else {
+    msg.access = smb_swap32(SMB_GENERIC_READ);
+    msg.create_disposition = smb_swap32(SMB_FILE_OPEN);
+  }
+  msg.byte_count = smb_swap16((unsigned short) ++byte_count);
+  strcpy(msg.bytes, req->path);
+
+  return smb_send_message(conn, SMB_COM_NT_CREATE_ANDX, &msg,
+                          sizeof(msg) - sizeof(msg.bytes) + byte_count);
+}
+
+static CURLcode smb_send_close(struct connectdata *conn)
+{
+  struct smb_request *req = conn->data->req.protop;
+  struct smb_close msg;
+
+  memset(&msg, 0, sizeof(msg));
+  msg.word_count = SMB_WC_CLOSE;
+  msg.fid = smb_swap16(req->fid);
+
+  return smb_send_message(conn, SMB_COM_CLOSE, &msg, sizeof(msg));
+}
+
+static CURLcode smb_send_tree_disconnect(struct connectdata *conn)
+{
+  struct smb_tree_disconnect msg;
+
+  memset(&msg, 0, sizeof(msg));
+
+  return smb_send_message(conn, SMB_COM_TREE_DISCONNECT, &msg, sizeof(msg));
+}
+
+static CURLcode smb_send_read(struct connectdata *conn)
+{
+  struct smb_request *req = conn->data->req.protop;
+  curl_off_t offset = conn->data->req.offset;
+  struct smb_read msg;
+
+  memset(&msg, 0, sizeof(msg));
+  msg.word_count = SMB_WC_READ_ANDX;
+  msg.andx.command = SMB_COM_NO_ANDX_COMMAND;
+  msg.fid = smb_swap16(req->fid);
+  msg.offset = smb_swap32((unsigned int) offset);
+  msg.offset_high = smb_swap32((unsigned int) (offset >> 32));
+  msg.min_bytes = smb_swap16(MAX_PAYLOAD_SIZE);
+  msg.max_bytes = smb_swap16(MAX_PAYLOAD_SIZE);
+
+  return smb_send_message(conn, SMB_COM_READ_ANDX, &msg, sizeof(msg));
+}
+
+static CURLcode smb_send_write(struct connectdata *conn)
+{
+  struct smb_write *msg = (struct smb_write *)conn->data->state.uploadbuffer;
+  struct smb_request *req = conn->data->req.protop;
+  curl_off_t offset = conn->data->req.offset;
+
+  curl_off_t upload_size = conn->data->req.size - conn->data->req.bytecount;
+  if(upload_size >= MAX_PAYLOAD_SIZE - 1) /* There is one byte of padding */
+    upload_size = MAX_PAYLOAD_SIZE - 1;
+
+  memset(msg, 0, sizeof(*msg));
+  msg->word_count = SMB_WC_WRITE_ANDX;
+  msg->andx.command = SMB_COM_NO_ANDX_COMMAND;
+  msg->fid = smb_swap16(req->fid);
+  msg->offset = smb_swap32((unsigned int) offset);
+  msg->offset_high = smb_swap32((unsigned int) (offset >> 32));
+  msg->data_length = smb_swap16((unsigned short) upload_size);
+  msg->data_offset = smb_swap16(sizeof(*msg) - sizeof(unsigned int));
+  msg->byte_count = smb_swap16((unsigned short) (upload_size + 1));
+
+  smb_format_message(conn, &msg->h, SMB_COM_WRITE_ANDX,
+                     sizeof(*msg) - sizeof(msg->h) + (size_t) upload_size);
+
+  return smb_send(conn, sizeof(*msg), (size_t) upload_size);
+}
+
+static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  CURLcode result;
+
+  /* Check if there is data in the transfer buffer */
+  if(!smbc->send_size && smbc->upload_size) {
+    int nread = smbc->upload_size > UPLOAD_BUFSIZE ? UPLOAD_BUFSIZE :
+      (int) smbc->upload_size;
+    conn->data->req.upload_fromhere = conn->data->state.uploadbuffer;
+    result = Curl_fillreadbuffer(conn, nread, &nread);
+    if(result && result != CURLE_AGAIN)
+      return result;
+    if(!nread)
+      return CURLE_OK;
+
+    smbc->upload_size -= nread;
+    smbc->send_size = nread;
+    smbc->sent = 0;
+  }
+
+  /* Check if there is data to send */
+  if(smbc->send_size) {
+    result = smb_flush(conn);
+    if(result)
+      return result;
+  }
+
+  /* Check if there is still data to be sent */
+  if(smbc->send_size || smbc->upload_size)
+    return CURLE_AGAIN;
+
+  return smb_recv_message(conn, msg);
+}
+
+static CURLcode smb_connection_state(struct connectdata *conn, bool *done)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  struct smb_negotiate_response *nrsp;
+  struct smb_header *h;
+  CURLcode result;
+  void *msg = NULL;
+
+  if(smbc->state == SMB_CONNECTING) {
+#ifdef USE_SSL
+    if((conn->handler->flags & PROTOPT_SSL)) {
+      bool ssl_done = FALSE;
+      result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &ssl_done);
+      if(result && result != CURLE_AGAIN)
+        return result;
+      if(!ssl_done)
+        return CURLE_OK;
+    }
+#endif
+
+    result = smb_send_negotiate(conn);
+    if(result) {
+      connclose(conn, "SMB: failed to send negotiate message");
+      return result;
+    }
+
+    conn_state(conn, SMB_NEGOTIATE);
+  }
+
+  /* Send the previous message and check for a response */
+  result = smb_send_and_recv(conn, &msg);
+  if(result && result != CURLE_AGAIN) {
+    connclose(conn, "SMB: failed to communicate");
+    return result;
+  }
+
+  if(!msg)
+    return CURLE_OK;
+
+  h = msg;
+
+  switch(smbc->state) {
+  case SMB_NEGOTIATE:
+    if(h->status || smbc->got < sizeof(*nrsp) + sizeof(smbc->challenge) - 1) {
+      connclose(conn, "SMB: negotiation failed");
+      return CURLE_COULDNT_CONNECT;
+    }
+    nrsp = msg;
+    memcpy(smbc->challenge, nrsp->bytes, sizeof(smbc->challenge));
+    smbc->session_key = smb_swap32(nrsp->session_key);
+    result = smb_send_setup(conn);
+    if(result) {
+      connclose(conn, "SMB: failed to send setup message");
+      return result;
+    }
+    conn_state(conn, SMB_SETUP);
+    break;
+
+  case SMB_SETUP:
+    if(h->status) {
+      connclose(conn, "SMB: authentication failed");
+      return CURLE_LOGIN_DENIED;
+    }
+    smbc->uid = smb_swap16(h->uid);
+    conn_state(conn, SMB_CONNECTED);
+    *done = true;
+    break;
+
+  default:
+    smb_pop_message(conn);
+    return CURLE_OK; /* ignore */
+  }
+
+  smb_pop_message(conn);
+
+  return CURLE_OK;
+}
+
+/*
+ * Convert a timestamp from the Windows world (100 nsec units from
+ * 1 Jan 1601) to Posix time.
+ */
+static void get_posix_time(long *_out, const void *_in)
+{
+#ifdef HAVE_LONGLONG
+  long long timestamp = *(long long *) _in;
+#else
+  unsigned __int64 timestamp = *(unsigned __int64 *) _in;
+#endif
+
+  timestamp -= 116444736000000000ULL;
+  timestamp /= 10000000;
+  *_out = (long) timestamp;
+}
+
+static CURLcode smb_request_state(struct connectdata *conn, bool *done)
+{
+  struct smb_request *req = conn->data->req.protop;
+  struct smb_header *h;
+  struct smb_conn *smbc = &conn->proto.smbc;
+  enum smb_req_state next_state = SMB_DONE;
+  unsigned short len;
+  unsigned short off;
+  CURLcode result;
+  void *msg = NULL;
+  const struct smb_nt_create_response *smb_m;
+
+  /* Start the request */
+  if(req->state == SMB_REQUESTING) {
+    result = smb_send_tree_connect(conn);
+    if(result) {
+      connclose(conn, "SMB: failed to send tree connect message");
+      return result;
+    }
+
+    request_state(conn, SMB_TREE_CONNECT);
+  }
+
+  /* Send the previous message and check for a response */
+  result = smb_send_and_recv(conn, &msg);
+  if(result && result != CURLE_AGAIN) {
+    connclose(conn, "SMB: failed to communicate");
+    return result;
+  }
+
+  if(!msg)
+    return CURLE_OK;
+
+  h = msg;
+
+  switch(req->state) {
+  case SMB_TREE_CONNECT:
+    if(h->status) {
+      req->result = CURLE_REMOTE_FILE_NOT_FOUND;
+      if(h->status == smb_swap32(SMB_ERR_NOACCESS))
+        req->result = CURLE_REMOTE_ACCESS_DENIED;
+      break;
+    }
+    req->tid = smb_swap16(h->tid);
+    next_state = SMB_OPEN;
+    break;
+
+  case SMB_OPEN:
+    if(h->status || smbc->got < sizeof(struct smb_nt_create_response)) {
+      req->result = CURLE_REMOTE_FILE_NOT_FOUND;
+      next_state = SMB_TREE_DISCONNECT;
+      break;
+    }
+    smb_m = (const struct smb_nt_create_response*) msg;
+    req->fid = smb_swap16(smb_m->fid);
+    conn->data->req.offset = 0;
+    if(conn->data->set.upload) {
+      conn->data->req.size = conn->data->state.infilesize;
+      Curl_pgrsSetUploadSize(conn->data, conn->data->req.size);
+      next_state = SMB_UPLOAD;
+    }
+    else {
+      smb_m = (const struct smb_nt_create_response*) msg;
+      conn->data->req.size = smb_swap64(smb_m->end_of_file);
+      Curl_pgrsSetDownloadSize(conn->data, conn->data->req.size);
+      if(conn->data->set.get_filetime)
+        get_posix_time(&conn->data->info.filetime, &smb_m->last_change_time);
+      next_state = SMB_DOWNLOAD;
+    }
+    break;
+
+  case SMB_DOWNLOAD:
+    if(h->status || smbc->got < sizeof(struct smb_header) + 14) {
+      req->result = CURLE_RECV_ERROR;
+      next_state = SMB_CLOSE;
+      break;
+    }
+    len = Curl_read16_le(((const unsigned char *) msg) +
+                         sizeof(struct smb_header) + 11);
+    off = Curl_read16_le(((const unsigned char *) msg) +
+                         sizeof(struct smb_header) + 13);
+    if(len > 0) {
+      if(off + sizeof(unsigned int) + len > smbc->got) {
+        failf(conn->data, "Invalid input packet");
+        result = CURLE_RECV_ERROR;
+      }
+      else
+        result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                   (char *)msg + off + sizeof(unsigned int),
+                                   len);
+      if(result) {
+        req->result = result;
+        next_state = SMB_CLOSE;
+        break;
+      }
+    }
+    conn->data->req.bytecount += len;
+    conn->data->req.offset += len;
+    Curl_pgrsSetDownloadCounter(conn->data, conn->data->req.bytecount);
+    next_state = (len < MAX_PAYLOAD_SIZE) ? SMB_CLOSE : SMB_DOWNLOAD;
+    break;
+
+  case SMB_UPLOAD:
+    if(h->status || smbc->got < sizeof(struct smb_header) + 6) {
+      req->result = CURLE_UPLOAD_FAILED;
+      next_state = SMB_CLOSE;
+      break;
+    }
+    len = Curl_read16_le(((const unsigned char *) msg) +
+                         sizeof(struct smb_header) + 5);
+    conn->data->req.bytecount += len;
+    conn->data->req.offset += len;
+    Curl_pgrsSetUploadCounter(conn->data, conn->data->req.bytecount);
+    if(conn->data->req.bytecount >= conn->data->req.size)
+      next_state = SMB_CLOSE;
+    else
+      next_state = SMB_UPLOAD;
+    break;
+
+  case SMB_CLOSE:
+    /* We don't care if the close failed, proceed to tree disconnect anyway */
+    next_state = SMB_TREE_DISCONNECT;
+    break;
+
+  case SMB_TREE_DISCONNECT:
+    next_state = SMB_DONE;
+    break;
+
+  default:
+    smb_pop_message(conn);
+    return CURLE_OK; /* ignore */
+  }
+
+  smb_pop_message(conn);
+
+  switch(next_state) {
+  case SMB_OPEN:
+    result = smb_send_open(conn);
+    break;
+
+  case SMB_DOWNLOAD:
+    result = smb_send_read(conn);
+    break;
+
+  case SMB_UPLOAD:
+    result = smb_send_write(conn);
+    break;
+
+  case SMB_CLOSE:
+    result = smb_send_close(conn);
+    break;
+
+  case SMB_TREE_DISCONNECT:
+    result = smb_send_tree_disconnect(conn);
+    break;
+
+  case SMB_DONE:
+    result = req->result;
+    *done = true;
+    break;
+
+  default:
+    break;
+  }
+
+  if(result) {
+    connclose(conn, "SMB: failed to send message");
+    return result;
+  }
+
+  request_state(conn, next_state);
+
+  return CURLE_OK;
+}
+
+static CURLcode smb_done(struct connectdata *conn, CURLcode status,
+                         bool premature)
+{
+  struct smb_request *req = conn->data->req.protop;
+
+  (void) premature;
+
+  Curl_safefree(req->share);
+  Curl_safefree(conn->data->req.protop);
+
+  return status;
+}
+
+static CURLcode smb_disconnect(struct connectdata *conn, bool dead)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+  struct smb_request *req = conn->data->req.protop;
+
+  (void) dead;
+
+  Curl_safefree(smbc->domain);
+  Curl_safefree(smbc->recv_buf);
+
+  /* smb_done is not always called, so cleanup the request */
+  if(req) {
+    Curl_safefree(req->share);
+  }
+
+  return CURLE_OK;
+}
+
+static int smb_getsock(struct connectdata *conn, curl_socket_t *socks,
+                       int numsocks)
+{
+  struct smb_conn *smbc = &conn->proto.smbc;
+
+  if(!numsocks)
+    return GETSOCK_BLANK;
+
+  socks[0] = conn->sock[FIRSTSOCKET];
+
+  if(smbc->send_size || smbc->upload_size)
+    return GETSOCK_WRITESOCK(0);
+
+  return GETSOCK_READSOCK(0);
+}
+
+static CURLcode smb_parse_url_path(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct smb_request *req = data->req.protop;
+  char *path;
+  char *slash;
+
+  /* URL decode the path */
+  result = Curl_urldecode(data, data->state.path, 0, &path, NULL, TRUE);
+  if(result)
+    return result;
+
+  /* Parse the path for the share */
+  req->share = strdup((*path == '/' || *path == '\\') ? path + 1 : path);
+  if(!req->share) {
+    free(path);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  slash = strchr(req->share, '/');
+  if(!slash)
+    slash = strchr(req->share, '\\');
+
+  /* The share must be present */
+  if(!slash) {
+    free(path);
+
+    return CURLE_URL_MALFORMAT;
+  }
+
+  /* Parse the path for the file path converting any forward slashes into
+     backslashes */
+  *slash++ = 0;
+  req->path = slash;
+  for(; *slash; slash++) {
+    if(*slash == '/')
+      *slash = '\\';
+  }
+
+  free(path);
+
+  return CURLE_OK;
+}
+
+#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
+
+#endif /* CURL_DISABLE_SMB && USE_NTLM && CURL_SIZEOF_CURL_OFF_T > 4 */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/smb.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/smb.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/smb.h	(revision 331)
@@ -0,0 +1,271 @@
+#ifndef HEADER_CURL_SMB_H
+#define HEADER_CURL_SMB_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2014, Bill Nagel <wnagel@tycoint.com>, Exacq Technologies
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+enum smb_conn_state {
+  SMB_NOT_CONNECTED = 0,
+  SMB_CONNECTING,
+  SMB_NEGOTIATE,
+  SMB_SETUP,
+  SMB_CONNECTED
+};
+
+struct smb_conn {
+  enum smb_conn_state state;
+  char *user;
+  char *domain;
+  unsigned char challenge[8];
+  unsigned int session_key;
+  unsigned short uid;
+  char *recv_buf;
+  size_t upload_size;
+  size_t send_size;
+  size_t sent;
+  size_t got;
+};
+
+/*
+ * Definitions for SMB protocol data structures
+ */
+#ifdef BUILDING_CURL_SMB_C
+
+#if defined(_MSC_VER) || defined(__ILEC400__)
+#  define PACK
+#  pragma pack(push)
+#  pragma pack(1)
+#elif defined(__GNUC__)
+#  define PACK __attribute__((packed))
+#else
+#  define PACK
+#endif
+
+#define SMB_COM_CLOSE                 0x04
+#define SMB_COM_READ_ANDX             0x2e
+#define SMB_COM_WRITE_ANDX            0x2f
+#define SMB_COM_TREE_DISCONNECT       0x71
+#define SMB_COM_NEGOTIATE             0x72
+#define SMB_COM_SETUP_ANDX            0x73
+#define SMB_COM_TREE_CONNECT_ANDX     0x75
+#define SMB_COM_NT_CREATE_ANDX        0xa2
+#define SMB_COM_NO_ANDX_COMMAND       0xff
+
+#define SMB_WC_CLOSE                  0x03
+#define SMB_WC_READ_ANDX              0x0c
+#define SMB_WC_WRITE_ANDX             0x0e
+#define SMB_WC_SETUP_ANDX             0x0d
+#define SMB_WC_TREE_CONNECT_ANDX      0x04
+#define SMB_WC_NT_CREATE_ANDX         0x18
+
+#define SMB_FLAGS_CANONICAL_PATHNAMES 0x10
+#define SMB_FLAGS_CASELESS_PATHNAMES  0x08
+#define SMB_FLAGS2_UNICODE_STRINGS    0x8000
+#define SMB_FLAGS2_IS_LONG_NAME       0x0040
+#define SMB_FLAGS2_KNOWS_LONG_NAME    0x0001
+
+#define SMB_CAP_LARGE_FILES           0x08
+#define SMB_GENERIC_WRITE             0x40000000
+#define SMB_GENERIC_READ              0x80000000
+#define SMB_FILE_SHARE_ALL            0x07
+#define SMB_FILE_OPEN                 0x01
+#define SMB_FILE_OVERWRITE_IF         0x05
+
+#define SMB_ERR_NOACCESS              0x00050001
+
+struct smb_header {
+  unsigned char nbt_type;
+  unsigned char nbt_flags;
+  unsigned short nbt_length;
+  unsigned char magic[4];
+  unsigned char command;
+  unsigned int status;
+  unsigned char flags;
+  unsigned short flags2;
+  unsigned short pid_high;
+  unsigned char signature[8];
+  unsigned short pad;
+  unsigned short tid;
+  unsigned short pid;
+  unsigned short uid;
+  unsigned short mid;
+} PACK;
+
+struct smb_negotiate_response {
+  struct smb_header h;
+  unsigned char word_count;
+  unsigned short dialect_index;
+  unsigned char security_mode;
+  unsigned short max_mpx_count;
+  unsigned short max_number_vcs;
+  unsigned int max_buffer_size;
+  unsigned int max_raw_size;
+  unsigned int session_key;
+  unsigned int capabilities;
+  unsigned int system_time_low;
+  unsigned int system_time_high;
+  unsigned short server_time_zone;
+  unsigned char encryption_key_length;
+  unsigned short byte_count;
+  char bytes[1];
+} PACK;
+
+struct andx {
+  unsigned char command;
+  unsigned char pad;
+  unsigned short offset;
+} PACK;
+
+struct smb_setup {
+  unsigned char word_count;
+  struct andx andx;
+  unsigned short max_buffer_size;
+  unsigned short max_mpx_count;
+  unsigned short vc_number;
+  unsigned int session_key;
+  unsigned short lengths[2];
+  unsigned int pad;
+  unsigned int capabilities;
+  unsigned short byte_count;
+  char bytes[1024];
+} PACK;
+
+struct smb_tree_connect {
+  unsigned char word_count;
+  struct andx andx;
+  unsigned short flags;
+  unsigned short pw_len;
+  unsigned short byte_count;
+  char bytes[1024];
+} PACK;
+
+struct smb_nt_create {
+  unsigned char word_count;
+  struct andx andx;
+  unsigned char pad;
+  unsigned short name_length;
+  unsigned int flags;
+  unsigned int root_fid;
+  unsigned int access;
+#ifdef HAVE_LONGLONG
+  unsigned long long allocation_size;
+#else
+  unsigned __int64 allocation_size;
+#endif
+  unsigned int ext_file_attributes;
+  unsigned int share_access;
+  unsigned int create_disposition;
+  unsigned int create_options;
+  unsigned int impersonation_level;
+  unsigned char security_flags;
+  unsigned short byte_count;
+  char bytes[1024];
+} PACK;
+
+struct smb_nt_create_response {
+  struct smb_header h;
+  unsigned char word_count;
+  struct andx andx;
+  unsigned char op_lock_level;
+  unsigned short fid;
+  unsigned int create_disposition;
+#ifdef HAVE_LONGLONG
+  unsigned long long create_time;
+  unsigned long long last_access_time;
+  unsigned long long last_write_time;
+  unsigned long long last_change_time;
+#else
+  unsigned __int64 create_time;
+  unsigned __int64 last_access_time;
+  unsigned __int64 last_write_time;
+  unsigned __int64 last_change_time;
+#endif
+  unsigned int ext_file_attributes;
+#ifdef HAVE_LONGLONG
+  unsigned long long allocation_size;
+  unsigned long long end_of_file;
+#else
+  unsigned __int64 allocation_size;
+  unsigned __int64 end_of_file;
+#endif
+} PACK;
+
+struct smb_read {
+  unsigned char word_count;
+  struct andx andx;
+  unsigned short fid;
+  unsigned int offset;
+  unsigned short max_bytes;
+  unsigned short min_bytes;
+  unsigned int timeout;
+  unsigned short remaining;
+  unsigned int offset_high;
+  unsigned short byte_count;
+} PACK;
+
+struct smb_write {
+  struct smb_header h;
+  unsigned char word_count;
+  struct andx andx;
+  unsigned short fid;
+  unsigned int offset;
+  unsigned int timeout;
+  unsigned short write_mode;
+  unsigned short remaining;
+  unsigned short pad;
+  unsigned short data_length;
+  unsigned short data_offset;
+  unsigned int offset_high;
+  unsigned short byte_count;
+  unsigned char pad2;
+} PACK;
+
+struct smb_close {
+  unsigned char word_count;
+  unsigned short fid;
+  unsigned int last_mtime;
+  unsigned short byte_count;
+} PACK;
+
+struct smb_tree_disconnect {
+  unsigned char word_count;
+  unsigned short byte_count;
+} PACK;
+
+#if defined(_MSC_VER) || defined(__ILEC400__)
+#  pragma pack(pop)
+#endif
+
+#endif /* BUILDING_CURL_SMB_C */
+
+#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
+    (CURL_SIZEOF_CURL_OFF_T > 4)
+
+#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)
+
+extern const struct Curl_handler Curl_handler_smb;
+extern const struct Curl_handler Curl_handler_smbs;
+
+#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */
+
+#endif /* CURL_DISABLE_SMB && USE_NTLM && CURL_SIZEOF_CURL_OFF_T > 4 */
+
+#endif /* HEADER_CURL_SMB_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/smtp.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/smtp.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/smtp.c	(revision 331)
@@ -0,0 +1,1633 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC1870 SMTP Service Extension for Message Size
+ * RFC2195 CRAM-MD5 authentication
+ * RFC2831 DIGEST-MD5 authentication
+ * RFC3207 SMTP over TLS
+ * RFC4422 Simple Authentication and Security Layer (SASL)
+ * RFC4616 PLAIN authentication
+ * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism
+ * RFC4954 SMTP Authentication
+ * RFC5321 SMTP protocol
+ * RFC6749 OAuth 2.0 Authorization Framework
+ * Draft   SMTP URL Interface   <draft-earhart-url-smtp-00.txt>
+ * Draft   LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_SMTP
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "progress.h"
+#include "transfer.h"
+#include "escape.h"
+#include "http.h" /* for HTTP proxy tunnel stuff */
+#include "mime.h"
+#include "socks.h"
+#include "smtp.h"
+#include "strtoofft.h"
+#include "strcase.h"
+#include "vtls/vtls.h"
+#include "connect.h"
+#include "strerror.h"
+#include "select.h"
+#include "multiif.h"
+#include "url.h"
+#include "curl_gethostname.h"
+#include "curl_sasl.h"
+#include "warnless.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Local API functions */
+static CURLcode smtp_regular_transfer(struct connectdata *conn, bool *done);
+static CURLcode smtp_do(struct connectdata *conn, bool *done);
+static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
+                          bool premature);
+static CURLcode smtp_connect(struct connectdata *conn, bool *done);
+static CURLcode smtp_disconnect(struct connectdata *conn, bool dead);
+static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done);
+static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks,
+                        int numsocks);
+static CURLcode smtp_doing(struct connectdata *conn, bool *dophase_done);
+static CURLcode smtp_setup_connection(struct connectdata *conn);
+static CURLcode smtp_parse_url_options(struct connectdata *conn);
+static CURLcode smtp_parse_url_path(struct connectdata *conn);
+static CURLcode smtp_parse_custom_request(struct connectdata *conn);
+static CURLcode smtp_perform_auth(struct connectdata *conn, const char *mech,
+                                  const char *initresp);
+static CURLcode smtp_continue_auth(struct connectdata *conn, const char *resp);
+static void smtp_get_message(char *buffer, char **outptr);
+
+/*
+ * SMTP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_smtp = {
+  "SMTP",                           /* scheme */
+  smtp_setup_connection,            /* setup_connection */
+  smtp_do,                          /* do_it */
+  smtp_done,                        /* done */
+  ZERO_NULL,                        /* do_more */
+  smtp_connect,                     /* connect_it */
+  smtp_multi_statemach,             /* connecting */
+  smtp_doing,                       /* doing */
+  smtp_getsock,                     /* proto_getsock */
+  smtp_getsock,                     /* doing_getsock */
+  ZERO_NULL,                        /* domore_getsock */
+  ZERO_NULL,                        /* perform_getsock */
+  smtp_disconnect,                  /* disconnect */
+  ZERO_NULL,                        /* readwrite */
+  ZERO_NULL,                        /* connection_check */
+  PORT_SMTP,                        /* defport */
+  CURLPROTO_SMTP,                   /* protocol */
+  PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
+  PROTOPT_URLOPTIONS
+};
+
+#ifdef USE_SSL
+/*
+ * SMTPS protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_smtps = {
+  "SMTPS",                          /* scheme */
+  smtp_setup_connection,            /* setup_connection */
+  smtp_do,                          /* do_it */
+  smtp_done,                        /* done */
+  ZERO_NULL,                        /* do_more */
+  smtp_connect,                     /* connect_it */
+  smtp_multi_statemach,             /* connecting */
+  smtp_doing,                       /* doing */
+  smtp_getsock,                     /* proto_getsock */
+  smtp_getsock,                     /* doing_getsock */
+  ZERO_NULL,                        /* domore_getsock */
+  ZERO_NULL,                        /* perform_getsock */
+  smtp_disconnect,                  /* disconnect */
+  ZERO_NULL,                        /* readwrite */
+  ZERO_NULL,                        /* connection_check */
+  PORT_SMTPS,                       /* defport */
+  CURLPROTO_SMTPS,                  /* protocol */
+  PROTOPT_CLOSEACTION | PROTOPT_SSL
+  | PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS /* flags */
+};
+#endif
+
+/* SASL parameters for the smtp protocol */
+static const struct SASLproto saslsmtp = {
+  "smtp",                     /* The service name */
+  334,                        /* Code received when continuation is expected */
+  235,                        /* Code to receive upon authentication success */
+  512 - 8,                    /* Maximum initial response length (no max) */
+  smtp_perform_auth,          /* Send authentication command */
+  smtp_continue_auth,         /* Send authentication continuation */
+  smtp_get_message            /* Get SASL response message */
+};
+
+#ifdef USE_SSL
+static void smtp_to_smtps(struct connectdata *conn)
+{
+  /* Change the connection handler */
+  conn->handler = &Curl_handler_smtps;
+
+  /* Set the connection's upgraded to TLS flag */
+  conn->tls_upgraded = TRUE;
+}
+#else
+#define smtp_to_smtps(x) Curl_nop_stmt
+#endif
+
+/***********************************************************************
+ *
+ * smtp_endofresp()
+ *
+ * Checks for an ending SMTP status code at the start of the given string, but
+ * also detects various capabilities from the EHLO response including the
+ * supported authentication mechanisms.
+ */
+static bool smtp_endofresp(struct connectdata *conn, char *line, size_t len,
+                           int *resp)
+{
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+  bool result = FALSE;
+
+  /* Nothing for us */
+  if(len < 4 || !ISDIGIT(line[0]) || !ISDIGIT(line[1]) || !ISDIGIT(line[2]))
+    return FALSE;
+
+  /* Do we have a command response? This should be the response code followed
+     by a space and optionally some text as per RFC-5321 and as outlined in
+     Section 4. Examples of RFC-4954 but some e-mail servers ignore this and
+     only send the response code instead as per Section 4.2. */
+  if(line[3] == ' ' || len == 5) {
+    result = TRUE;
+    *resp = curlx_sltosi(strtol(line, NULL, 10));
+
+    /* Make sure real server never sends internal value */
+    if(*resp == 1)
+      *resp = 0;
+  }
+  /* Do we have a multiline (continuation) response? */
+  else if(line[3] == '-' &&
+          (smtpc->state == SMTP_EHLO || smtpc->state == SMTP_COMMAND)) {
+    result = TRUE;
+    *resp = 1;  /* Internal response code */
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_get_message()
+ *
+ * Gets the authentication message from the response buffer.
+ */
+static void smtp_get_message(char *buffer, char **outptr)
+{
+  size_t len = 0;
+  char *message = NULL;
+
+  /* Find the start of the message */
+  for(message = buffer + 4; *message == ' ' || *message == '\t'; message++)
+    ;
+
+  /* Find the end of the message */
+  for(len = strlen(message); len--;)
+    if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' &&
+       message[len] != '\t')
+      break;
+
+  /* Terminate the message */
+  if(++len) {
+    message[len] = '\0';
+  }
+
+  *outptr = message;
+}
+
+/***********************************************************************
+ *
+ * state()
+ *
+ * This is the ONLY way to change SMTP state!
+ */
+static void state(struct connectdata *conn, smtpstate newstate)
+{
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* for debug purposes */
+  static const char * const names[] = {
+    "STOP",
+    "SERVERGREET",
+    "EHLO",
+    "HELO",
+    "STARTTLS",
+    "UPGRADETLS",
+    "AUTH",
+    "COMMAND",
+    "MAIL",
+    "RCPT",
+    "DATA",
+    "POSTDATA",
+    "QUIT",
+    /* LAST */
+  };
+
+  if(smtpc->state != newstate)
+    infof(conn->data, "SMTP %p state change from %s to %s\n",
+          (void *)smtpc, names[smtpc->state], names[newstate]);
+#endif
+
+  smtpc->state = newstate;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_ehlo()
+ *
+ * Sends the EHLO command to not only initialise communication with the ESMTP
+ * server but to also obtain a list of server side supported capabilities.
+ */
+static CURLcode smtp_perform_ehlo(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+  smtpc->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanism yet */
+  smtpc->sasl.authused = SASL_AUTH_NONE;  /* Clear the authentication mechanism
+                                             used for esmtp connections */
+  smtpc->tls_supported = FALSE;           /* Clear the TLS capability */
+  smtpc->auth_supported = FALSE;          /* Clear the AUTH capability */
+
+  /* Send the EHLO command */
+  result = Curl_pp_sendf(&smtpc->pp, "EHLO %s", smtpc->domain);
+
+  if(!result)
+    state(conn, SMTP_EHLO);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_helo()
+ *
+ * Sends the HELO command to initialise communication with the SMTP server.
+ */
+static CURLcode smtp_perform_helo(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+  smtpc->sasl.authused = SASL_AUTH_NONE; /* No authentication mechanism used
+                                            in smtp connections */
+
+  /* Send the HELO command */
+  result = Curl_pp_sendf(&smtpc->pp, "HELO %s", smtpc->domain);
+
+  if(!result)
+    state(conn, SMTP_HELO);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_starttls()
+ *
+ * Sends the STLS command to start the upgrade to TLS.
+ */
+static CURLcode smtp_perform_starttls(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  /* Send the STARTTLS command */
+  result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "STARTTLS");
+
+  if(!result)
+    state(conn, SMTP_STARTTLS);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_upgrade_tls()
+ *
+ * Performs the upgrade to TLS.
+ */
+static CURLcode smtp_perform_upgrade_tls(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+  /* Start the SSL connection */
+  result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &smtpc->ssldone);
+
+  if(!result) {
+    if(smtpc->state != SMTP_UPGRADETLS)
+      state(conn, SMTP_UPGRADETLS);
+
+    if(smtpc->ssldone) {
+      smtp_to_smtps(conn);
+      result = smtp_perform_ehlo(conn);
+    }
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_auth()
+ *
+ * Sends an AUTH command allowing the client to login with the given SASL
+ * authentication mechanism.
+ */
+static CURLcode smtp_perform_auth(struct connectdata *conn,
+                                  const char *mech,
+                                  const char *initresp)
+{
+  CURLcode result = CURLE_OK;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+  if(initresp) {                                  /* AUTH <mech> ...<crlf> */
+    /* Send the AUTH command with the initial response */
+    result = Curl_pp_sendf(&smtpc->pp, "AUTH %s %s", mech, initresp);
+  }
+  else {
+    /* Send the AUTH command */
+    result = Curl_pp_sendf(&smtpc->pp, "AUTH %s", mech);
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_continue_auth()
+ *
+ * Sends SASL continuation data or cancellation.
+ */
+static CURLcode smtp_continue_auth(struct connectdata *conn, const char *resp)
+{
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+  return Curl_pp_sendf(&smtpc->pp, "%s", resp);
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_authentication()
+ *
+ * Initiates the authentication sequence, with the appropriate SASL
+ * authentication mechanism.
+ */
+static CURLcode smtp_perform_authentication(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+  saslprogress progress;
+
+  /* Check we have enough data to authenticate with, and the
+     server supports authentiation, and end the connect phase if not */
+  if(!smtpc->auth_supported ||
+     !Curl_sasl_can_authenticate(&smtpc->sasl, conn)) {
+    state(conn, SMTP_STOP);
+    return result;
+  }
+
+  /* Calculate the SASL login details */
+  result = Curl_sasl_start(&smtpc->sasl, conn, FALSE, &progress);
+
+  if(!result) {
+    if(progress == SASL_INPROGRESS)
+      state(conn, SMTP_AUTH);
+    else {
+      /* Other mechanisms not supported */
+      infof(conn->data, "No known authentication mechanisms supported!\n");
+      result = CURLE_LOGIN_DENIED;
+    }
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_command()
+ *
+ * Sends a SMTP based command.
+ */
+static CURLcode smtp_perform_command(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct SMTP *smtp = data->req.protop;
+
+  /* Send the command */
+  if(smtp->rcpt)
+    result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s %s",
+                           smtp->custom && smtp->custom[0] != '\0' ?
+                           smtp->custom : "VRFY",
+                           smtp->rcpt->data);
+  else
+    result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s",
+                           smtp->custom && smtp->custom[0] != '\0' ?
+                           smtp->custom : "HELP");
+
+  if(!result)
+    state(conn, SMTP_COMMAND);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_mail()
+ *
+ * Sends an MAIL command to initiate the upload of a message.
+ */
+static CURLcode smtp_perform_mail(struct connectdata *conn)
+{
+  char *from = NULL;
+  char *auth = NULL;
+  char *size = NULL;
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  /* Calculate the FROM parameter */
+  if(!data->set.str[STRING_MAIL_FROM])
+    /* Null reverse-path, RFC-5321, sect. 3.6.3 */
+    from = strdup("<>");
+  else if(data->set.str[STRING_MAIL_FROM][0] == '<')
+    from = aprintf("%s", data->set.str[STRING_MAIL_FROM]);
+  else
+    from = aprintf("<%s>", data->set.str[STRING_MAIL_FROM]);
+
+  if(!from)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Calculate the optional AUTH parameter */
+  if(data->set.str[STRING_MAIL_AUTH] && conn->proto.smtpc.sasl.authused) {
+    if(data->set.str[STRING_MAIL_AUTH][0] != '\0')
+      auth = aprintf("%s", data->set.str[STRING_MAIL_AUTH]);
+    else
+      /* Empty AUTH, RFC-2554, sect. 5 */
+      auth = strdup("<>");
+
+    if(!auth) {
+      free(from);
+
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  /* Prepare the mime data if some. */
+  if(data->set.mimepost.kind != MIMEKIND_NONE) {
+    /* Use the whole structure as data. */
+    data->set.mimepost.flags &= ~MIME_BODY_ONLY;
+
+    /* Add external headers and mime version. */
+    curl_mime_headers(&data->set.mimepost, data->set.headers, 0);
+    result = Curl_mime_prepare_headers(&data->set.mimepost, NULL,
+                                       NULL, MIMESTRATEGY_MAIL);
+
+    if(!result)
+      if(!Curl_checkheaders(conn, "Mime-Version"))
+        result = Curl_mime_add_header(&data->set.mimepost.curlheaders,
+                                      "Mime-Version: 1.0");
+
+    /* Make sure we will read the entire mime structure. */
+    if(!result)
+      result = Curl_mime_rewind(&data->set.mimepost);
+
+    if(result) {
+      free(from);
+      free(auth);
+      return result;
+    }
+
+    data->state.infilesize = Curl_mime_size(&data->set.mimepost);
+
+    /* Read from mime structure. */
+    data->state.fread_func = (curl_read_callback) Curl_mime_read;
+    data->state.in = (void *) &data->set.mimepost;
+  }
+
+  /* Calculate the optional SIZE parameter */
+  if(conn->proto.smtpc.size_supported && data->state.infilesize > 0) {
+    size = aprintf("%" CURL_FORMAT_CURL_OFF_T, data->state.infilesize);
+
+    if(!size) {
+      free(from);
+      free(auth);
+
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  /* Send the MAIL command */
+  if(!auth && !size)
+    result = Curl_pp_sendf(&conn->proto.smtpc.pp,
+                           "MAIL FROM:%s", from);
+  else if(auth && !size)
+    result = Curl_pp_sendf(&conn->proto.smtpc.pp,
+                           "MAIL FROM:%s AUTH=%s", from, auth);
+  else if(auth && size)
+    result = Curl_pp_sendf(&conn->proto.smtpc.pp,
+                           "MAIL FROM:%s AUTH=%s SIZE=%s", from, auth, size);
+  else
+    result = Curl_pp_sendf(&conn->proto.smtpc.pp,
+                           "MAIL FROM:%s SIZE=%s", from, size);
+
+  free(from);
+  free(auth);
+  free(size);
+
+  if(!result)
+    state(conn, SMTP_MAIL);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_rcpt_to()
+ *
+ * Sends a RCPT TO command for a given recipient as part of the message upload
+ * process.
+ */
+static CURLcode smtp_perform_rcpt_to(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct SMTP *smtp = data->req.protop;
+
+  /* Send the RCPT TO command */
+  if(smtp->rcpt->data[0] == '<')
+    result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:%s",
+                           smtp->rcpt->data);
+  else
+    result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:<%s>",
+                           smtp->rcpt->data);
+  if(!result)
+    state(conn, SMTP_RCPT);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform_quit()
+ *
+ * Performs the quit action prior to sclose() being called.
+ */
+static CURLcode smtp_perform_quit(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+  /* Send the QUIT command */
+  result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "QUIT");
+
+  if(!result)
+    state(conn, SMTP_QUIT);
+
+  return result;
+}
+
+/* For the initial server greeting */
+static CURLcode smtp_state_servergreet_resp(struct connectdata *conn,
+                                            int smtpcode,
+                                            smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(smtpcode/100 != 2) {
+    failf(data, "Got unexpected smtp-server response: %d", smtpcode);
+    result = CURLE_WEIRD_SERVER_REPLY;
+  }
+  else
+    result = smtp_perform_ehlo(conn);
+
+  return result;
+}
+
+/* For STARTTLS responses */
+static CURLcode smtp_state_starttls_resp(struct connectdata *conn,
+                                         int smtpcode,
+                                         smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(smtpcode != 220) {
+    if(data->set.use_ssl != CURLUSESSL_TRY) {
+      failf(data, "STARTTLS denied, code %d", smtpcode);
+      result = CURLE_USE_SSL_FAILED;
+    }
+    else
+      result = smtp_perform_authentication(conn);
+  }
+  else
+    result = smtp_perform_upgrade_tls(conn);
+
+  return result;
+}
+
+/* For EHLO responses */
+static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
+                                     smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+  const char *line = data->state.buffer;
+  size_t len = strlen(line);
+  size_t wordlen;
+
+  (void)instate; /* no use for this yet */
+
+  if(smtpcode/100 != 2 && smtpcode != 1) {
+    if(data->set.use_ssl <= CURLUSESSL_TRY || conn->ssl[FIRSTSOCKET].use)
+      result = smtp_perform_helo(conn);
+    else {
+      failf(data, "Remote access denied: %d", smtpcode);
+      result = CURLE_REMOTE_ACCESS_DENIED;
+    }
+  }
+  else {
+    line += 4;
+    len -= 4;
+
+    /* Does the server support the STARTTLS capability? */
+    if(len >= 8 && !memcmp(line, "STARTTLS", 8))
+      smtpc->tls_supported = TRUE;
+
+    /* Does the server support the SIZE capability? */
+    else if(len >= 4 && !memcmp(line, "SIZE", 4))
+      smtpc->size_supported = TRUE;
+
+    /* Does the server support authentication? */
+    else if(len >= 5 && !memcmp(line, "AUTH ", 5)) {
+      smtpc->auth_supported = TRUE;
+
+      /* Advance past the AUTH keyword */
+      line += 5;
+      len -= 5;
+
+      /* Loop through the data line */
+      for(;;) {
+        size_t llen;
+        unsigned int mechbit;
+
+        while(len &&
+              (*line == ' ' || *line == '\t' ||
+               *line == '\r' || *line == '\n')) {
+
+          line++;
+          len--;
+        }
+
+        if(!len)
+          break;
+
+        /* Extract the word */
+        for(wordlen = 0; wordlen < len && line[wordlen] != ' ' &&
+              line[wordlen] != '\t' && line[wordlen] != '\r' &&
+              line[wordlen] != '\n';)
+          wordlen++;
+
+        /* Test the word for a matching authentication mechanism */
+        mechbit = Curl_sasl_decode_mech(line, wordlen, &llen);
+        if(mechbit && llen == wordlen)
+          smtpc->sasl.authmechs |= mechbit;
+
+        line += wordlen;
+        len -= wordlen;
+      }
+    }
+
+    if(smtpcode != 1) {
+      if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
+        /* We don't have a SSL/TLS connection yet, but SSL is requested */
+        if(smtpc->tls_supported)
+          /* Switch to TLS connection now */
+          result = smtp_perform_starttls(conn);
+        else if(data->set.use_ssl == CURLUSESSL_TRY)
+          /* Fallback and carry on with authentication */
+          result = smtp_perform_authentication(conn);
+        else {
+          failf(data, "STARTTLS not supported.");
+          result = CURLE_USE_SSL_FAILED;
+        }
+      }
+      else
+        result = smtp_perform_authentication(conn);
+    }
+  }
+
+  return result;
+}
+
+/* For HELO responses */
+static CURLcode smtp_state_helo_resp(struct connectdata *conn, int smtpcode,
+                                     smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(smtpcode/100 != 2) {
+    failf(data, "Remote access denied: %d", smtpcode);
+    result = CURLE_REMOTE_ACCESS_DENIED;
+  }
+  else
+    /* End of connect phase */
+    state(conn, SMTP_STOP);
+
+  return result;
+}
+
+/* For SASL authentication responses */
+static CURLcode smtp_state_auth_resp(struct connectdata *conn,
+                                     int smtpcode,
+                                     smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+  saslprogress progress;
+
+  (void)instate; /* no use for this yet */
+
+  result = Curl_sasl_continue(&smtpc->sasl, conn, smtpcode, &progress);
+  if(!result)
+    switch(progress) {
+    case SASL_DONE:
+      state(conn, SMTP_STOP);  /* Authenticated */
+      break;
+    case SASL_IDLE:            /* No mechanism left after cancellation */
+      failf(data, "Authentication cancelled");
+      result = CURLE_LOGIN_DENIED;
+      break;
+    default:
+      break;
+    }
+
+  return result;
+}
+
+/* For command responses */
+static CURLcode smtp_state_command_resp(struct connectdata *conn, int smtpcode,
+                                        smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct SMTP *smtp = data->req.protop;
+  char *line = data->state.buffer;
+  size_t len = strlen(line);
+
+  (void)instate; /* no use for this yet */
+
+  if((smtp->rcpt && smtpcode/100 != 2 && smtpcode != 553 && smtpcode != 1) ||
+     (!smtp->rcpt && smtpcode/100 != 2 && smtpcode != 1)) {
+    failf(data, "Command failed: %d", smtpcode);
+    result = CURLE_RECV_ERROR;
+  }
+  else {
+    /* Temporarily add the LF character back and send as body to the client */
+    if(!data->set.opt_no_body) {
+      line[len] = '\n';
+      result = Curl_client_write(conn, CLIENTWRITE_BODY, line, len + 1);
+      line[len] = '\0';
+    }
+
+    if(smtpcode != 1) {
+      if(smtp->rcpt) {
+        smtp->rcpt = smtp->rcpt->next;
+
+        if(smtp->rcpt) {
+          /* Send the next command */
+          result = smtp_perform_command(conn);
+        }
+        else
+          /* End of DO phase */
+          state(conn, SMTP_STOP);
+      }
+      else
+        /* End of DO phase */
+        state(conn, SMTP_STOP);
+    }
+  }
+
+  return result;
+}
+
+/* For MAIL responses */
+static CURLcode smtp_state_mail_resp(struct connectdata *conn, int smtpcode,
+                                     smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(smtpcode/100 != 2) {
+    failf(data, "MAIL failed: %d", smtpcode);
+    result = CURLE_SEND_ERROR;
+  }
+  else
+    /* Start the RCPT TO command */
+    result = smtp_perform_rcpt_to(conn);
+
+  return result;
+}
+
+/* For RCPT responses */
+static CURLcode smtp_state_rcpt_resp(struct connectdata *conn, int smtpcode,
+                                     smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct SMTP *smtp = data->req.protop;
+
+  (void)instate; /* no use for this yet */
+
+  if(smtpcode/100 != 2) {
+    failf(data, "RCPT failed: %d", smtpcode);
+    result = CURLE_SEND_ERROR;
+  }
+  else {
+    smtp->rcpt = smtp->rcpt->next;
+
+    if(smtp->rcpt)
+      /* Send the next RCPT TO command */
+      result = smtp_perform_rcpt_to(conn);
+    else {
+      /* Send the DATA command */
+      result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "DATA");
+
+      if(!result)
+        state(conn, SMTP_DATA);
+    }
+  }
+
+  return result;
+}
+
+/* For DATA response */
+static CURLcode smtp_state_data_resp(struct connectdata *conn, int smtpcode,
+                                     smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  (void)instate; /* no use for this yet */
+
+  if(smtpcode != 354) {
+    failf(data, "DATA failed: %d", smtpcode);
+    result = CURLE_SEND_ERROR;
+  }
+  else {
+    /* Set the progress upload size */
+    Curl_pgrsSetUploadSize(data, data->state.infilesize);
+
+    /* SMTP upload */
+    Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
+
+    /* End of DO phase */
+    state(conn, SMTP_STOP);
+  }
+
+  return result;
+}
+
+/* For POSTDATA responses, which are received after the entire DATA
+   part has been sent to the server */
+static CURLcode smtp_state_postdata_resp(struct connectdata *conn,
+                                         int smtpcode,
+                                         smtpstate instate)
+{
+  CURLcode result = CURLE_OK;
+
+  (void)instate; /* no use for this yet */
+
+  if(smtpcode != 250)
+    result = CURLE_RECV_ERROR;
+
+  /* End of DONE phase */
+  state(conn, SMTP_STOP);
+
+  return result;
+}
+
+static CURLcode smtp_statemach_act(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  struct Curl_easy *data = conn->data;
+  int smtpcode;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+  struct pingpong *pp = &smtpc->pp;
+  size_t nread = 0;
+
+  /* Busy upgrading the connection; right now all I/O is SSL/TLS, not SMTP */
+  if(smtpc->state == SMTP_UPGRADETLS)
+    return smtp_perform_upgrade_tls(conn);
+
+  /* Flush any data that needs to be sent */
+  if(pp->sendleft)
+    return Curl_pp_flushsend(pp);
+
+  do {
+    /* Read the response from the server */
+    result = Curl_pp_readresp(sock, pp, &smtpcode, &nread);
+    if(result)
+      return result;
+
+    /* Store the latest response for later retrieval if necessary */
+    if(smtpc->state != SMTP_QUIT && smtpcode != 1)
+      data->info.httpcode = smtpcode;
+
+    if(!smtpcode)
+      break;
+
+    /* We have now received a full SMTP server response */
+    switch(smtpc->state) {
+    case SMTP_SERVERGREET:
+      result = smtp_state_servergreet_resp(conn, smtpcode, smtpc->state);
+      break;
+
+    case SMTP_EHLO:
+      result = smtp_state_ehlo_resp(conn, smtpcode, smtpc->state);
+      break;
+
+    case SMTP_HELO:
+      result = smtp_state_helo_resp(conn, smtpcode, smtpc->state);
+      break;
+
+    case SMTP_STARTTLS:
+      result = smtp_state_starttls_resp(conn, smtpcode, smtpc->state);
+      break;
+
+    case SMTP_AUTH:
+      result = smtp_state_auth_resp(conn, smtpcode, smtpc->state);
+      break;
+
+    case SMTP_COMMAND:
+      result = smtp_state_command_resp(conn, smtpcode, smtpc->state);
+      break;
+
+    case SMTP_MAIL:
+      result = smtp_state_mail_resp(conn, smtpcode, smtpc->state);
+      break;
+
+    case SMTP_RCPT:
+      result = smtp_state_rcpt_resp(conn, smtpcode, smtpc->state);
+      break;
+
+    case SMTP_DATA:
+      result = smtp_state_data_resp(conn, smtpcode, smtpc->state);
+      break;
+
+    case SMTP_POSTDATA:
+      result = smtp_state_postdata_resp(conn, smtpcode, smtpc->state);
+      break;
+
+    case SMTP_QUIT:
+      /* fallthrough, just stop! */
+    default:
+      /* internal error */
+      state(conn, SMTP_STOP);
+      break;
+    }
+  } while(!result && smtpc->state != SMTP_STOP && Curl_pp_moredata(pp));
+
+  return result;
+}
+
+/* Called repeatedly until done from multi.c */
+static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+  if((conn->handler->flags & PROTOPT_SSL) && !smtpc->ssldone) {
+    result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &smtpc->ssldone);
+    if(result || !smtpc->ssldone)
+      return result;
+  }
+
+  result = Curl_pp_statemach(&smtpc->pp, FALSE);
+  *done = (smtpc->state == SMTP_STOP) ? TRUE : FALSE;
+
+  return result;
+}
+
+static CURLcode smtp_block_statemach(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+  while(smtpc->state != SMTP_STOP && !result)
+    result = Curl_pp_statemach(&smtpc->pp, TRUE);
+
+  return result;
+}
+
+/* Allocate and initialize the SMTP struct for the current Curl_easy if
+   required */
+static CURLcode smtp_init(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct SMTP *smtp;
+
+  smtp = data->req.protop = calloc(sizeof(struct SMTP), 1);
+  if(!smtp)
+    result = CURLE_OUT_OF_MEMORY;
+
+  return result;
+}
+
+/* For the SMTP "protocol connect" and "doing" phases only */
+static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks,
+                        int numsocks)
+{
+  return Curl_pp_getsock(&conn->proto.smtpc.pp, socks, numsocks);
+}
+
+/***********************************************************************
+ *
+ * smtp_connect()
+ *
+ * This function should do everything that is to be considered a part of
+ * the connection phase.
+ *
+ * The variable pointed to by 'done' will be TRUE if the protocol-layer
+ * connect phase is done when this function returns, or FALSE if not.
+ */
+static CURLcode smtp_connect(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+  struct pingpong *pp = &smtpc->pp;
+
+  *done = FALSE; /* default to not done yet */
+
+  /* We always support persistent connections in SMTP */
+  connkeep(conn, "SMTP default");
+
+  /* Set the default response time-out */
+  pp->response_time = RESP_TIMEOUT;
+  pp->statemach_act = smtp_statemach_act;
+  pp->endofresp = smtp_endofresp;
+  pp->conn = conn;
+
+  /* Initialize the SASL storage */
+  Curl_sasl_init(&smtpc->sasl, &saslsmtp);
+
+  /* Initialise the pingpong layer */
+  Curl_pp_init(pp);
+
+  /* Parse the URL options */
+  result = smtp_parse_url_options(conn);
+  if(result)
+    return result;
+
+  /* Parse the URL path */
+  result = smtp_parse_url_path(conn);
+  if(result)
+    return result;
+
+  /* Start off waiting for the server greeting response */
+  state(conn, SMTP_SERVERGREET);
+
+  result = smtp_multi_statemach(conn, done);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_done()
+ *
+ * The DONE function. This does what needs to be done after a single DO has
+ * performed.
+ *
+ * Input argument is already checked for validity.
+ */
+static CURLcode smtp_done(struct connectdata *conn, CURLcode status,
+                          bool premature)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct SMTP *smtp = data->req.protop;
+  struct pingpong *pp = &conn->proto.smtpc.pp;
+  char *eob;
+  ssize_t len;
+  ssize_t bytes_written;
+
+  (void)premature;
+
+  if(!smtp || !pp->conn)
+    return CURLE_OK;
+
+  /* Cleanup our per-request based variables */
+  Curl_safefree(smtp->custom);
+
+  if(status) {
+    connclose(conn, "SMTP done with bad status"); /* marked for closure */
+    result = status;         /* use the already set error code */
+  }
+  else if(!data->set.connect_only && data->set.mail_rcpt &&
+          (data->set.upload || data->set.mimepost.kind)) {
+    /* Calculate the EOB taking into account any terminating CRLF from the
+       previous line of the email or the CRLF of the DATA command when there
+       is "no mail data". RFC-5321, sect. 4.1.1.4.
+
+       Note: As some SSL backends, such as OpenSSL, will cause Curl_write() to
+       fail when using a different pointer following a previous write, that
+       returned CURLE_AGAIN, we duplicate the EOB now rather than when the
+       bytes written doesn't equal len. */
+    if(smtp->trailing_crlf || !conn->data->state.infilesize) {
+      eob = strdup(SMTP_EOB + 2);
+      len = SMTP_EOB_LEN - 2;
+    }
+    else {
+      eob = strdup(SMTP_EOB);
+      len = SMTP_EOB_LEN;
+    }
+
+    if(!eob)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* Send the end of block data */
+    result = Curl_write(conn, conn->writesockfd, eob, len, &bytes_written);
+    if(result) {
+      free(eob);
+      return result;
+    }
+
+    if(bytes_written != len) {
+      /* The whole chunk was not sent so keep it around and adjust the
+         pingpong structure accordingly */
+      pp->sendthis = eob;
+      pp->sendsize = len;
+      pp->sendleft = len - bytes_written;
+    }
+    else {
+      /* Successfully sent so adjust the response timeout relative to now */
+      pp->response = Curl_now();
+
+      free(eob);
+    }
+
+    state(conn, SMTP_POSTDATA);
+
+    /* Run the state-machine
+
+       TODO: when the multi interface is used, this _really_ should be using
+       the smtp_multi_statemach function but we have no general support for
+       non-blocking DONE operations!
+    */
+    result = smtp_block_statemach(conn);
+  }
+
+  /* Clear the transfer mode for the next request */
+  smtp->transfer = FTPTRANSFER_BODY;
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_perform()
+ *
+ * This is the actual DO function for SMTP. Transfer a mail, send a command
+ * or get some data according to the options previously setup.
+ */
+static CURLcode smtp_perform(struct connectdata *conn, bool *connected,
+                             bool *dophase_done)
+{
+  /* This is SMTP and no proxy */
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct SMTP *smtp = data->req.protop;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  if(data->set.opt_no_body) {
+    /* Requested no body means no transfer */
+    smtp->transfer = FTPTRANSFER_INFO;
+  }
+
+  *dophase_done = FALSE; /* not done yet */
+
+  /* Store the first recipient (or NULL if not specified) */
+  smtp->rcpt = data->set.mail_rcpt;
+
+  /* Start the first command in the DO phase */
+  if((data->set.upload || data->set.mimepost.kind) && data->set.mail_rcpt)
+    /* MAIL transfer */
+    result = smtp_perform_mail(conn);
+  else
+    /* SMTP based command (VRFY, EXPN, NOOP, RSET or HELP) */
+    result = smtp_perform_command(conn);
+
+  if(result)
+    return result;
+
+  /* Run the state-machine */
+  result = smtp_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+  if(*dophase_done)
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_do()
+ *
+ * This function is registered as 'curl_do' function. It decodes the path
+ * parts etc as a wrapper to the actual DO function (smtp_perform).
+ *
+ * The input argument is already checked for validity.
+ */
+static CURLcode smtp_do(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+
+  *done = FALSE; /* default to false */
+
+  /* Parse the custom request */
+  result = smtp_parse_custom_request(conn);
+  if(result)
+    return result;
+
+  result = smtp_regular_transfer(conn, done);
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_disconnect()
+ *
+ * Disconnect from an SMTP server. Cleanup protocol-specific per-connection
+ * resources. BLOCKING.
+ */
+static CURLcode smtp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+
+  /* We cannot send quit unconditionally. If this connection is stale or
+     bad in any way, sending quit and waiting around here will make the
+     disconnect wait in vain and cause more problems than we need to. */
+
+  /* The SMTP session may or may not have been allocated/setup at this
+     point! */
+  if(!dead_connection && smtpc->pp.conn && smtpc->pp.conn->bits.protoconnstart)
+    if(!smtp_perform_quit(conn))
+      (void)smtp_block_statemach(conn); /* ignore errors on QUIT */
+
+  /* Disconnect from the server */
+  Curl_pp_disconnect(&smtpc->pp);
+
+  /* Cleanup the SASL module */
+  Curl_sasl_cleanup(conn, smtpc->sasl.authused);
+
+  /* Cleanup our connection based variables */
+  Curl_safefree(smtpc->domain);
+
+  return CURLE_OK;
+}
+
+/* Call this when the DO phase has completed */
+static CURLcode smtp_dophase_done(struct connectdata *conn, bool connected)
+{
+  struct SMTP *smtp = conn->data->req.protop;
+
+  (void)connected;
+
+  if(smtp->transfer != FTPTRANSFER_BODY)
+    /* no data to transfer */
+    Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+
+  return CURLE_OK;
+}
+
+/* Called from multi.c while DOing */
+static CURLcode smtp_doing(struct connectdata *conn, bool *dophase_done)
+{
+  CURLcode result = smtp_multi_statemach(conn, dophase_done);
+
+  if(result)
+    DEBUGF(infof(conn->data, "DO phase failed\n"));
+  else if(*dophase_done) {
+    result = smtp_dophase_done(conn, FALSE /* not connected */);
+
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_regular_transfer()
+ *
+ * The input argument is already checked for validity.
+ *
+ * Performs all commands done before a regular transfer between a local and a
+ * remote host.
+ */
+static CURLcode smtp_regular_transfer(struct connectdata *conn,
+                                      bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+  bool connected = FALSE;
+  struct Curl_easy *data = conn->data;
+
+  /* Make sure size is unknown at this point */
+  data->req.size = -1;
+
+  /* Set the progress data */
+  Curl_pgrsSetUploadCounter(data, 0);
+  Curl_pgrsSetDownloadCounter(data, 0);
+  Curl_pgrsSetUploadSize(data, -1);
+  Curl_pgrsSetDownloadSize(data, -1);
+
+  /* Carry out the perform */
+  result = smtp_perform(conn, &connected, dophase_done);
+
+  /* Perform post DO phase operations if necessary */
+  if(!result && *dophase_done)
+    result = smtp_dophase_done(conn, connected);
+
+  return result;
+}
+
+static CURLcode smtp_setup_connection(struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  CURLcode result;
+
+  /* Clear the TLS upgraded flag */
+  conn->tls_upgraded = FALSE;
+
+  /* Initialise the SMTP layer */
+  result = smtp_init(conn);
+  if(result)
+    return result;
+
+  data->state.path++;   /* don't include the initial slash */
+
+  return CURLE_OK;
+}
+
+/***********************************************************************
+ *
+ * smtp_parse_url_options()
+ *
+ * Parse the URL login options.
+ */
+static CURLcode smtp_parse_url_options(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+  const char *ptr = conn->options;
+
+  smtpc->sasl.resetprefs = TRUE;
+
+  while(!result && ptr && *ptr) {
+    const char *key = ptr;
+    const char *value;
+
+    while(*ptr && *ptr != '=')
+      ptr++;
+
+    value = ptr + 1;
+
+    while(*ptr && *ptr != ';')
+      ptr++;
+
+    if(strncasecompare(key, "AUTH=", 5))
+      result = Curl_sasl_parse_url_auth_option(&smtpc->sasl,
+                                               value, ptr - value);
+    else
+      result = CURLE_URL_MALFORMAT;
+
+    if(*ptr == ';')
+      ptr++;
+  }
+
+  return result;
+}
+
+/***********************************************************************
+ *
+ * smtp_parse_url_path()
+ *
+ * Parse the URL path into separate path components.
+ */
+static CURLcode smtp_parse_url_path(struct connectdata *conn)
+{
+  /* The SMTP struct is already initialised in smtp_connect() */
+  struct Curl_easy *data = conn->data;
+  struct smtp_conn *smtpc = &conn->proto.smtpc;
+  const char *path = data->state.path;
+  char localhost[HOSTNAME_MAX + 1];
+
+  /* Calculate the path if necessary */
+  if(!*path) {
+    if(!Curl_gethostname(localhost, sizeof(localhost)))
+      path = localhost;
+    else
+      path = "localhost";
+  }
+
+  /* URL decode the path and use it as the domain in our EHLO */
+  return Curl_urldecode(conn->data, path, 0, &smtpc->domain, NULL, TRUE);
+}
+
+/***********************************************************************
+ *
+ * smtp_parse_custom_request()
+ *
+ * Parse the custom request.
+ */
+static CURLcode smtp_parse_custom_request(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct SMTP *smtp = data->req.protop;
+  const char *custom = data->set.str[STRING_CUSTOMREQUEST];
+
+  /* URL decode the custom request */
+  if(custom)
+    result = Curl_urldecode(data, custom, 0, &smtp->custom, NULL, TRUE);
+
+  return result;
+}
+
+CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread)
+{
+  /* When sending a SMTP payload we must detect CRLF. sequences making sure
+     they are sent as CRLF.. instead, as a . on the beginning of a line will
+     be deleted by the server when not part of an EOB terminator and a
+     genuine CRLF.CRLF which isn't escaped will wrongly be detected as end of
+     data by the server
+  */
+  ssize_t i;
+  ssize_t si;
+  struct Curl_easy *data = conn->data;
+  struct SMTP *smtp = data->req.protop;
+  char *scratch = data->state.scratch;
+  char *newscratch = NULL;
+  char *oldscratch = NULL;
+  size_t eob_sent;
+
+  /* Do we need to allocate a scratch buffer? */
+  if(!scratch || data->set.crlf) {
+    oldscratch = scratch;
+
+    scratch = newscratch = malloc(2 * data->set.buffer_size);
+    if(!newscratch) {
+      failf(data, "Failed to alloc scratch buffer!");
+
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  /* Have we already sent part of the EOB? */
+  eob_sent = smtp->eob;
+
+  /* This loop can be improved by some kind of Boyer-Moore style of
+     approach but that is saved for later... */
+  for(i = 0, si = 0; i < nread; i++) {
+    if(SMTP_EOB[smtp->eob] == data->req.upload_fromhere[i]) {
+      smtp->eob++;
+
+      /* Is the EOB potentially the terminating CRLF? */
+      if(2 == smtp->eob || SMTP_EOB_LEN == smtp->eob)
+        smtp->trailing_crlf = TRUE;
+      else
+        smtp->trailing_crlf = FALSE;
+    }
+    else if(smtp->eob) {
+      /* A previous substring matched so output that first */
+      memcpy(&scratch[si], &SMTP_EOB[eob_sent], smtp->eob - eob_sent);
+      si += smtp->eob - eob_sent;
+
+      /* Then compare the first byte */
+      if(SMTP_EOB[0] == data->req.upload_fromhere[i])
+        smtp->eob = 1;
+      else
+        smtp->eob = 0;
+
+      eob_sent = 0;
+
+      /* Reset the trailing CRLF flag as there was more data */
+      smtp->trailing_crlf = FALSE;
+    }
+
+    /* Do we have a match for CRLF. as per RFC-5321, sect. 4.5.2 */
+    if(SMTP_EOB_FIND_LEN == smtp->eob) {
+      /* Copy the replacement data to the target buffer */
+      memcpy(&scratch[si], &SMTP_EOB_REPL[eob_sent],
+             SMTP_EOB_REPL_LEN - eob_sent);
+      si += SMTP_EOB_REPL_LEN - eob_sent;
+      smtp->eob = 0;
+      eob_sent = 0;
+    }
+    else if(!smtp->eob)
+      scratch[si++] = data->req.upload_fromhere[i];
+  }
+
+  if(smtp->eob - eob_sent) {
+    /* A substring matched before processing ended so output that now */
+    memcpy(&scratch[si], &SMTP_EOB[eob_sent], smtp->eob - eob_sent);
+    si += smtp->eob - eob_sent;
+  }
+
+  /* Only use the new buffer if we replaced something */
+  if(si != nread) {
+    /* Upload from the new (replaced) buffer instead */
+    data->req.upload_fromhere = scratch;
+
+    /* Save the buffer so it can be freed later */
+    data->state.scratch = scratch;
+
+    /* Free the old scratch buffer */
+    free(oldscratch);
+
+    /* Set the new amount too */
+    data->req.upload_present = si;
+  }
+  else
+    free(newscratch);
+
+  return CURLE_OK;
+}
+
+#endif /* CURL_DISABLE_SMTP */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/smtp.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/smtp.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/smtp.h	(revision 331)
@@ -0,0 +1,91 @@
+#ifndef HEADER_CURL_SMTP_H
+#define HEADER_CURL_SMTP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2009 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "pingpong.h"
+#include "curl_sasl.h"
+
+/****************************************************************************
+ * SMTP unique setup
+ ***************************************************************************/
+typedef enum {
+  SMTP_STOP,        /* do nothing state, stops the state machine */
+  SMTP_SERVERGREET, /* waiting for the initial greeting immediately after
+                       a connect */
+  SMTP_EHLO,
+  SMTP_HELO,
+  SMTP_STARTTLS,
+  SMTP_UPGRADETLS,  /* asynchronously upgrade the connection to SSL/TLS
+                       (multi mode only) */
+  SMTP_AUTH,
+  SMTP_COMMAND,     /* VRFY, EXPN, NOOP, RSET and HELP */
+  SMTP_MAIL,        /* MAIL FROM */
+  SMTP_RCPT,        /* RCPT TO */
+  SMTP_DATA,
+  SMTP_POSTDATA,
+  SMTP_QUIT,
+  SMTP_LAST         /* never used */
+} smtpstate;
+
+/* This SMTP struct is used in the Curl_easy. All SMTP data that is
+   connection-oriented must be in smtp_conn to properly deal with the fact that
+   perhaps the Curl_easy is changed between the times the connection is
+   used. */
+struct SMTP {
+  curl_pp_transfer transfer;
+  char *custom;            /* Custom Request */
+  struct curl_slist *rcpt; /* Recipient list */
+  size_t eob;              /* Number of bytes of the EOB (End Of Body) that
+                              have been received so far */
+  bool trailing_crlf;      /* Specifies if the tailing CRLF is present */
+};
+
+/* smtp_conn is used for struct connection-oriented data in the connectdata
+   struct */
+struct smtp_conn {
+  struct pingpong pp;
+  smtpstate state;         /* Always use smtp.c:state() to change state! */
+  bool ssldone;            /* Is connect() over SSL done? */
+  char *domain;            /* Client address/name to send in the EHLO */
+  struct SASL sasl;        /* SASL-related storage */
+  bool tls_supported;      /* StartTLS capability supported by server */
+  bool size_supported;     /* If server supports SIZE extension according to
+                              RFC 1870 */
+  bool auth_supported;     /* AUTH capability supported by server */
+};
+
+extern const struct Curl_handler Curl_handler_smtp;
+extern const struct Curl_handler Curl_handler_smtps;
+
+/* this is the 5-bytes End-Of-Body marker for SMTP */
+#define SMTP_EOB "\x0d\x0a\x2e\x0d\x0a"
+#define SMTP_EOB_LEN 5
+#define SMTP_EOB_FIND_LEN 3
+
+/* if found in data, replace it with this string instead */
+#define SMTP_EOB_REPL "\x0d\x0a\x2e\x2e"
+#define SMTP_EOB_REPL_LEN 4
+
+CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread);
+
+#endif /* HEADER_CURL_SMTP_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/sockaddr.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/sockaddr.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/sockaddr.h	(revision 331)
@@ -0,0 +1,43 @@
+#ifndef HEADER_CURL_SOCKADDR_H
+#define HEADER_CURL_SOCKADDR_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+struct Curl_sockaddr_storage {
+  union {
+    struct sockaddr sa;
+    struct sockaddr_in sa_in;
+#ifdef ENABLE_IPV6
+    struct sockaddr_in6 sa_in6;
+#endif
+#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
+    struct sockaddr_storage sa_stor;
+#else
+    char cbuf[256];   /* this should be big enough to fit a lot */
+#endif
+  } buffer;
+};
+
+#endif /* HEADER_CURL_SOCKADDR_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/socks.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/socks.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/socks.c	(revision 331)
@@ -0,0 +1,792 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_PROXY)
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "select.h"
+#include "connect.h"
+#include "timeval.h"
+#include "socks.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/*
+ * Helper read-from-socket functions. Does the same as Curl_read() but it
+ * blocks until all bytes amount of buffersize will be read. No more, no less.
+ *
+ * This is STUPID BLOCKING behaviour which we frown upon, but right now this
+ * is what we have...
+ */
+int Curl_blockread_all(struct connectdata *conn, /* connection data */
+                       curl_socket_t sockfd,     /* read from this socket */
+                       char *buf,                /* store read data here */
+                       ssize_t buffersize,       /* max amount to read */
+                       ssize_t *n)               /* amount bytes read */
+{
+  ssize_t nread;
+  ssize_t allread = 0;
+  int result;
+  timediff_t timeleft;
+  *n = 0;
+  for(;;) {
+    timeleft = Curl_timeleft(conn->data, NULL, TRUE);
+    if(timeleft < 0) {
+      /* we already got the timeout */
+      result = CURLE_OPERATION_TIMEDOUT;
+      break;
+    }
+    if(SOCKET_READABLE(sockfd, timeleft) <= 0) {
+      result = ~CURLE_OK;
+      break;
+    }
+    result = Curl_read_plain(sockfd, buf, buffersize, &nread);
+    if(CURLE_AGAIN == result)
+      continue;
+    if(result)
+      break;
+
+    if(buffersize == nread) {
+      allread += nread;
+      *n = allread;
+      result = CURLE_OK;
+      break;
+    }
+    if(!nread) {
+      result = ~CURLE_OK;
+      break;
+    }
+
+    buffersize -= nread;
+    buf += nread;
+    allread += nread;
+  }
+  return result;
+}
+
+/*
+* This function logs in to a SOCKS4 proxy and sends the specifics to the final
+* destination server.
+*
+* Reference :
+*   http://socks.permeo.com/protocol/socks4.protocol
+*
+* Note :
+*   Set protocol4a=true for  "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)"
+*   Nonsupport "Identification Protocol (RFC1413)"
+*/
+CURLcode Curl_SOCKS4(const char *proxy_user,
+                     const char *hostname,
+                     int remote_port,
+                     int sockindex,
+                     struct connectdata *conn)
+{
+  const bool protocol4a =
+    (conn->socks_proxy.proxytype == CURLPROXY_SOCKS4A) ? TRUE : FALSE;
+#define SOCKS4REQLEN 262
+  unsigned char socksreq[SOCKS4REQLEN]; /* room for SOCKS4 request incl. user
+                                           id */
+  int result;
+  CURLcode code;
+  curl_socket_t sock = conn->sock[sockindex];
+  struct Curl_easy *data = conn->data;
+
+  if(Curl_timeleft(data, NULL, TRUE) < 0) {
+    /* time-out, bail out, go home */
+    failf(data, "Connection time-out");
+    return CURLE_OPERATION_TIMEDOUT;
+  }
+
+  if(conn->bits.httpproxy)
+    infof(conn->data, "SOCKS4%s: connecting to HTTP proxy %s port %d\n",
+          protocol4a ? "a" : "", hostname, remote_port);
+
+  (void)curlx_nonblock(sock, FALSE);
+
+  infof(data, "SOCKS4 communication to %s:%d\n", hostname, remote_port);
+
+  /*
+   * Compose socks4 request
+   *
+   * Request format
+   *
+   *     +----+----+----+----+----+----+----+----+----+----+....+----+
+   *     | VN | CD | DSTPORT |      DSTIP        | USERID       |NULL|
+   *     +----+----+----+----+----+----+----+----+----+----+....+----+
+   * # of bytes:  1    1      2              4           variable       1
+   */
+
+  socksreq[0] = 4; /* version (SOCKS4) */
+  socksreq[1] = 1; /* connect */
+  socksreq[2] = (unsigned char)((remote_port >> 8) & 0xff); /* PORT MSB */
+  socksreq[3] = (unsigned char)(remote_port & 0xff);        /* PORT LSB */
+
+  /* DNS resolve only for SOCKS4, not SOCKS4a */
+  if(!protocol4a) {
+    struct Curl_dns_entry *dns;
+    Curl_addrinfo *hp = NULL;
+    int rc;
+
+    rc = Curl_resolv(conn, hostname, remote_port, &dns);
+
+    if(rc == CURLRESOLV_ERROR)
+      return CURLE_COULDNT_RESOLVE_PROXY;
+
+    if(rc == CURLRESOLV_PENDING)
+      /* ignores the return code, but 'dns' remains NULL on failure */
+      (void)Curl_resolver_wait_resolv(conn, &dns);
+
+    /*
+     * We cannot use 'hostent' as a struct that Curl_resolv() returns.  It
+     * returns a Curl_addrinfo pointer that may not always look the same.
+     */
+    if(dns)
+      hp = dns->addr;
+    if(hp) {
+      char buf[64];
+      Curl_printable_address(hp, buf, sizeof(buf));
+
+      if(hp->ai_family == AF_INET) {
+        struct sockaddr_in *saddr_in;
+
+        saddr_in = (struct sockaddr_in *)(void *)hp->ai_addr;
+        socksreq[4] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[0];
+        socksreq[5] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[1];
+        socksreq[6] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[2];
+        socksreq[7] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[3];
+
+        infof(data, "SOCKS4 connect to IPv4 %s (locally resolved)\n", buf);
+      }
+      else {
+        hp = NULL; /* fail! */
+
+        failf(data, "SOCKS4 connection to %s not supported\n", buf);
+      }
+
+      Curl_resolv_unlock(data, dns); /* not used anymore from now on */
+    }
+    if(!hp) {
+      failf(data, "Failed to resolve \"%s\" for SOCKS4 connect.",
+            hostname);
+      return CURLE_COULDNT_RESOLVE_HOST;
+    }
+  }
+
+  /*
+   * This is currently not supporting "Identification Protocol (RFC1413)".
+   */
+  socksreq[8] = 0; /* ensure empty userid is NUL-terminated */
+  if(proxy_user) {
+    size_t plen = strlen(proxy_user);
+    if(plen >= sizeof(socksreq) - 8) {
+      failf(data, "Too long SOCKS proxy name, can't use!\n");
+      return CURLE_COULDNT_CONNECT;
+    }
+    /* copy the proxy name WITH trailing zero */
+    memcpy(socksreq + 8, proxy_user, plen + 1);
+  }
+
+  /*
+   * Make connection
+   */
+  {
+    ssize_t actualread;
+    ssize_t written;
+    ssize_t hostnamelen = 0;
+    int packetsize = 9 +
+      (int)strlen((char *)socksreq + 8); /* size including NUL */
+
+    /* If SOCKS4a, set special invalid IP address 0.0.0.x */
+    if(protocol4a) {
+      socksreq[4] = 0;
+      socksreq[5] = 0;
+      socksreq[6] = 0;
+      socksreq[7] = 1;
+      /* If still enough room in buffer, also append hostname */
+      hostnamelen = (ssize_t)strlen(hostname) + 1; /* length including NUL */
+      if(packetsize + hostnamelen <= SOCKS4REQLEN)
+        strcpy((char *)socksreq + packetsize, hostname);
+      else
+        hostnamelen = 0; /* Flag: hostname did not fit in buffer */
+    }
+
+    /* Send request */
+    code = Curl_write_plain(conn, sock, (char *)socksreq,
+                            packetsize + hostnamelen,
+                            &written);
+    if(code || (written != packetsize + hostnamelen)) {
+      failf(data, "Failed to send SOCKS4 connect request.");
+      return CURLE_COULDNT_CONNECT;
+    }
+    if(protocol4a && hostnamelen == 0) {
+      /* SOCKS4a with very long hostname - send that name separately */
+      hostnamelen = (ssize_t)strlen(hostname) + 1;
+      code = Curl_write_plain(conn, sock, (char *)hostname, hostnamelen,
+                              &written);
+      if(code || (written != hostnamelen)) {
+        failf(data, "Failed to send SOCKS4 connect request.");
+        return CURLE_COULDNT_CONNECT;
+      }
+    }
+
+    packetsize = 8; /* receive data size */
+
+    /* Receive response */
+    result = Curl_blockread_all(conn, sock, (char *)socksreq, packetsize,
+                                &actualread);
+    if(result || (actualread != packetsize)) {
+      failf(data, "Failed to receive SOCKS4 connect request ack.");
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    /*
+     * Response format
+     *
+     *     +----+----+----+----+----+----+----+----+
+     *     | VN | CD | DSTPORT |      DSTIP        |
+     *     +----+----+----+----+----+----+----+----+
+     * # of bytes:  1    1      2              4
+     *
+     * VN is the version of the reply code and should be 0. CD is the result
+     * code with one of the following values:
+     *
+     * 90: request granted
+     * 91: request rejected or failed
+     * 92: request rejected because SOCKS server cannot connect to
+     *     identd on the client
+     * 93: request rejected because the client program and identd
+     *     report different user-ids
+     */
+
+    /* wrong version ? */
+    if(socksreq[0] != 0) {
+      failf(data,
+            "SOCKS4 reply has wrong version, version should be 4.");
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    /* Result */
+    switch(socksreq[1]) {
+    case 90:
+      infof(data, "SOCKS4%s request granted.\n", protocol4a?"a":"");
+      break;
+    case 91:
+      failf(data,
+            "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
+            ", request rejected or failed.",
+            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+            (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
+            (unsigned char)socksreq[1]);
+      return CURLE_COULDNT_CONNECT;
+    case 92:
+      failf(data,
+            "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
+            ", request rejected because SOCKS server cannot connect to "
+            "identd on the client.",
+            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+            (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
+            (unsigned char)socksreq[1]);
+      return CURLE_COULDNT_CONNECT;
+    case 93:
+      failf(data,
+            "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
+            ", request rejected because the client program and identd "
+            "report different user-ids.",
+            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+            (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
+            (unsigned char)socksreq[1]);
+      return CURLE_COULDNT_CONNECT;
+    default:
+      failf(data,
+            "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
+            ", Unknown.",
+            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+            (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
+            (unsigned char)socksreq[1]);
+      return CURLE_COULDNT_CONNECT;
+    }
+  }
+
+  (void)curlx_nonblock(sock, TRUE);
+
+  return CURLE_OK; /* Proxy was successful! */
+}
+
+/*
+ * This function logs in to a SOCKS5 proxy and sends the specifics to the final
+ * destination server.
+ */
+CURLcode Curl_SOCKS5(const char *proxy_user,
+                     const char *proxy_password,
+                     const char *hostname,
+                     int remote_port,
+                     int sockindex,
+                     struct connectdata *conn)
+{
+  /*
+    According to the RFC1928, section "6.  Replies". This is what a SOCK5
+    replies:
+
+        +----+-----+-------+------+----------+----------+
+        |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
+        +----+-----+-------+------+----------+----------+
+        | 1  |  1  | X'00' |  1   | Variable |    2     |
+        +----+-----+-------+------+----------+----------+
+
+    Where:
+
+    o  VER    protocol version: X'05'
+    o  REP    Reply field:
+    o  X'00' succeeded
+  */
+
+  unsigned char socksreq[600]; /* room for large user/pw (255 max each) */
+  int idx;
+  ssize_t actualread;
+  ssize_t written;
+  int result;
+  CURLcode code;
+  curl_socket_t sock = conn->sock[sockindex];
+  struct Curl_easy *data = conn->data;
+  timediff_t timeout;
+  bool socks5_resolve_local =
+    (conn->socks_proxy.proxytype == CURLPROXY_SOCKS5) ? TRUE : FALSE;
+  const size_t hostname_len = strlen(hostname);
+  ssize_t len = 0;
+  const unsigned long auth = data->set.socks5auth;
+  bool allow_gssapi = FALSE;
+
+  if(conn->bits.httpproxy)
+    infof(conn->data, "SOCKS5: connecting to HTTP proxy %s port %d\n",
+          hostname, remote_port);
+
+  /* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */
+  if(!socks5_resolve_local && hostname_len > 255) {
+    infof(conn->data, "SOCKS5: server resolving disabled for hostnames of "
+          "length > 255 [actual len=%zu]\n", hostname_len);
+    socks5_resolve_local = TRUE;
+  }
+
+  /* get timeout */
+  timeout = Curl_timeleft(data, NULL, TRUE);
+
+  if(timeout < 0) {
+    /* time-out, bail out, go home */
+    failf(data, "Connection time-out");
+    return CURLE_OPERATION_TIMEDOUT;
+  }
+
+  (void)curlx_nonblock(sock, TRUE);
+
+  /* wait until socket gets connected */
+  result = SOCKET_WRITABLE(sock, timeout);
+
+  if(-1 == result) {
+    failf(conn->data, "SOCKS5: no connection here");
+    return CURLE_COULDNT_CONNECT;
+  }
+  if(0 == result) {
+    failf(conn->data, "SOCKS5: connection timeout");
+    return CURLE_OPERATION_TIMEDOUT;
+  }
+
+  if(result & CURL_CSELECT_ERR) {
+    failf(conn->data, "SOCKS5: error occurred during connection");
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  if(auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI))
+    infof(conn->data,
+        "warning: unsupported value passed to CURLOPT_SOCKS5_AUTH: %lu\n",
+        auth);
+  if(!(auth & CURLAUTH_BASIC))
+    /* disable username/password auth */
+    proxy_user = NULL;
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  if(auth & CURLAUTH_GSSAPI)
+    allow_gssapi = TRUE;
+#endif
+
+  idx = 0;
+  socksreq[idx++] = 5;   /* version */
+  idx++;                 /* reserve for the number of authentication methods */
+  socksreq[idx++] = 0;   /* no authentication */
+  if(allow_gssapi)
+    socksreq[idx++] = 1; /* GSS-API */
+  if(proxy_user)
+    socksreq[idx++] = 2; /* username/password */
+  /* write the number of authentication methods */
+  socksreq[1] = (unsigned char) (idx - 2);
+
+  (void)curlx_nonblock(sock, FALSE);
+
+  infof(data, "SOCKS5 communication to %s:%d\n", hostname, remote_port);
+
+  code = Curl_write_plain(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
+                          &written);
+  if(code || (written != (2 + (int)socksreq[1]))) {
+    failf(data, "Unable to send initial SOCKS5 request.");
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  (void)curlx_nonblock(sock, TRUE);
+
+  result = SOCKET_READABLE(sock, timeout);
+
+  if(-1 == result) {
+    failf(conn->data, "SOCKS5 nothing to read");
+    return CURLE_COULDNT_CONNECT;
+  }
+  if(0 == result) {
+    failf(conn->data, "SOCKS5 read timeout");
+    return CURLE_OPERATION_TIMEDOUT;
+  }
+
+  if(result & CURL_CSELECT_ERR) {
+    failf(conn->data, "SOCKS5 read error occurred");
+    return CURLE_RECV_ERROR;
+  }
+
+  (void)curlx_nonblock(sock, FALSE);
+
+  result = Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread);
+  if(result || (actualread != 2)) {
+    failf(data, "Unable to receive initial SOCKS5 response.");
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  if(socksreq[0] != 5) {
+    failf(data, "Received invalid version in initial SOCKS5 response.");
+    return CURLE_COULDNT_CONNECT;
+  }
+  if(socksreq[1] == 0) {
+    /* Nothing to do, no authentication needed */
+    ;
+  }
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  else if(allow_gssapi && (socksreq[1] == 1)) {
+    code = Curl_SOCKS5_gssapi_negotiate(sockindex, conn);
+    if(code) {
+      failf(data, "Unable to negotiate SOCKS5 GSS-API context.");
+      return CURLE_COULDNT_CONNECT;
+    }
+  }
+#endif
+  else if(socksreq[1] == 2) {
+    /* Needs user name and password */
+    size_t proxy_user_len, proxy_password_len;
+    if(proxy_user && proxy_password) {
+      proxy_user_len = strlen(proxy_user);
+      proxy_password_len = strlen(proxy_password);
+    }
+    else {
+      proxy_user_len = 0;
+      proxy_password_len = 0;
+    }
+
+    /*   username/password request looks like
+     * +----+------+----------+------+----------+
+     * |VER | ULEN |  UNAME   | PLEN |  PASSWD  |
+     * +----+------+----------+------+----------+
+     * | 1  |  1   | 1 to 255 |  1   | 1 to 255 |
+     * +----+------+----------+------+----------+
+     */
+    len = 0;
+    socksreq[len++] = 1;    /* username/pw subnegotiation version */
+    socksreq[len++] = (unsigned char) proxy_user_len;
+    if(proxy_user && proxy_user_len)
+      memcpy(socksreq + len, proxy_user, proxy_user_len);
+    len += proxy_user_len;
+    socksreq[len++] = (unsigned char) proxy_password_len;
+    if(proxy_password && proxy_password_len)
+      memcpy(socksreq + len, proxy_password, proxy_password_len);
+    len += proxy_password_len;
+
+    code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
+    if(code || (len != written)) {
+      failf(data, "Failed to send SOCKS5 sub-negotiation request.");
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    result = Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread);
+    if(result || (actualread != 2)) {
+      failf(data, "Unable to receive SOCKS5 sub-negotiation response.");
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    /* ignore the first (VER) byte */
+    if(socksreq[1] != 0) { /* status */
+      failf(data, "User was rejected by the SOCKS5 server (%d %d).",
+            socksreq[0], socksreq[1]);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    /* Everything is good so far, user was authenticated! */
+  }
+  else {
+    /* error */
+    if(!allow_gssapi && (socksreq[1] == 1)) {
+      failf(data,
+            "SOCKS5 GSSAPI per-message authentication is not supported.");
+      return CURLE_COULDNT_CONNECT;
+    }
+    if(socksreq[1] == 255) {
+      if(!proxy_user || !*proxy_user) {
+        failf(data,
+              "No authentication method was acceptable. (It is quite likely"
+              " that the SOCKS5 server wanted a username/password, since none"
+              " was supplied to the server on this connection.)");
+      }
+      else {
+        failf(data, "No authentication method was acceptable.");
+      }
+      return CURLE_COULDNT_CONNECT;
+    }
+    else {
+      failf(data,
+            "Undocumented SOCKS5 mode attempted to be used by server.");
+      return CURLE_COULDNT_CONNECT;
+    }
+  }
+
+  /* Authentication is complete, now specify destination to the proxy */
+  len = 0;
+  socksreq[len++] = 5; /* version (SOCKS5) */
+  socksreq[len++] = 1; /* connect */
+  socksreq[len++] = 0; /* must be zero */
+
+  if(!socks5_resolve_local) {
+    socksreq[len++] = 3; /* ATYP: domain name = 3 */
+    socksreq[len++] = (char) hostname_len; /* address length */
+    memcpy(&socksreq[len], hostname, hostname_len); /* address str w/o NULL */
+    len += hostname_len;
+  }
+  else {
+    struct Curl_dns_entry *dns;
+    Curl_addrinfo *hp = NULL;
+    int rc = Curl_resolv(conn, hostname, remote_port, &dns);
+
+    if(rc == CURLRESOLV_ERROR)
+      return CURLE_COULDNT_RESOLVE_HOST;
+
+    if(rc == CURLRESOLV_PENDING) {
+      /* this requires that we're in "wait for resolve" state */
+      code = Curl_resolver_wait_resolv(conn, &dns);
+      if(code)
+        return code;
+    }
+
+    /*
+     * We cannot use 'hostent' as a struct that Curl_resolv() returns.  It
+     * returns a Curl_addrinfo pointer that may not always look the same.
+     */
+    if(dns)
+      hp = dns->addr;
+    if(hp) {
+      int i;
+      char buf[64];
+      Curl_printable_address(hp, buf, sizeof(buf));
+
+      if(hp->ai_family == AF_INET) {
+        struct sockaddr_in *saddr_in;
+        socksreq[len++] = 1; /* ATYP: IPv4 = 1 */
+
+        saddr_in = (struct sockaddr_in *)(void *)hp->ai_addr;
+        for(i = 0; i < 4; i++) {
+          socksreq[len++] = ((unsigned char *)&saddr_in->sin_addr.s_addr)[i];
+        }
+
+        infof(data, "SOCKS5 connect to IPv4 %s (locally resolved)\n", buf);
+      }
+#ifdef ENABLE_IPV6
+      else if(hp->ai_family == AF_INET6) {
+        struct sockaddr_in6 *saddr_in6;
+        socksreq[len++] = 4; /* ATYP: IPv6 = 4 */
+
+        saddr_in6 = (struct sockaddr_in6 *)(void *)hp->ai_addr;
+        for(i = 0; i < 16; i++) {
+          socksreq[len++] =
+            ((unsigned char *)&saddr_in6->sin6_addr.s6_addr)[i];
+        }
+
+        infof(data, "SOCKS5 connect to IPv6 %s (locally resolved)\n", buf);
+      }
+#endif
+      else {
+        hp = NULL; /* fail! */
+
+        failf(data, "SOCKS5 connection to %s not supported\n", buf);
+      }
+
+      Curl_resolv_unlock(data, dns); /* not used anymore from now on */
+    }
+    if(!hp) {
+      failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.",
+            hostname);
+      return CURLE_COULDNT_RESOLVE_HOST;
+    }
+  }
+
+  socksreq[len++] = (unsigned char)((remote_port >> 8) & 0xff); /* PORT MSB */
+  socksreq[len++] = (unsigned char)(remote_port & 0xff);        /* PORT LSB */
+
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  if(conn->socks5_gssapi_enctype) {
+    failf(data, "SOCKS5 GSS-API protection not yet implemented.");
+  }
+  else
+#endif
+    code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
+
+  if(code || (len != written)) {
+    failf(data, "Failed to send SOCKS5 connect request.");
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  len = 10; /* minimum packet size is 10 */
+
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  if(conn->socks5_gssapi_enctype) {
+    failf(data, "SOCKS5 GSS-API protection not yet implemented.");
+  }
+  else
+#endif
+    result = Curl_blockread_all(conn, sock, (char *)socksreq,
+                                len, &actualread);
+
+  if(result || (len != actualread)) {
+    failf(data, "Failed to receive SOCKS5 connect request ack.");
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  if(socksreq[0] != 5) { /* version */
+    failf(data,
+          "SOCKS5 reply has wrong version, version should be 5.");
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  /* Fix: in general, returned BND.ADDR is variable length parameter by RFC
+     1928, so the reply packet should be read until the end to avoid errors at
+     subsequent protocol level.
+
+    +----+-----+-------+------+----------+----------+
+    |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
+    +----+-----+-------+------+----------+----------+
+    | 1  |  1  | X'00' |  1   | Variable |    2     |
+    +----+-----+-------+------+----------+----------+
+
+     ATYP:
+     o  IP v4 address: X'01', BND.ADDR = 4 byte
+     o  domain name:  X'03', BND.ADDR = [ 1 byte length, string ]
+     o  IP v6 address: X'04', BND.ADDR = 16 byte
+     */
+
+  /* Calculate real packet size */
+  if(socksreq[3] == 3) {
+    /* domain name */
+    int addrlen = (int) socksreq[4];
+    len = 5 + addrlen + 2;
+  }
+  else if(socksreq[3] == 4) {
+    /* IPv6 */
+    len = 4 + 16 + 2;
+  }
+
+  /* At this point we already read first 10 bytes */
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  if(!conn->socks5_gssapi_enctype) {
+    /* decrypt_gssapi_blockread already read the whole packet */
+#endif
+    if(len > 10) {
+      result = Curl_blockread_all(conn, sock, (char *)&socksreq[10],
+                                  len - 10, &actualread);
+      if(result || ((len - 10) != actualread)) {
+        failf(data, "Failed to receive SOCKS5 connect request ack.");
+        return CURLE_COULDNT_CONNECT;
+      }
+    }
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  }
+#endif
+
+  if(socksreq[1] != 0) { /* Anything besides 0 is an error */
+    if(socksreq[3] == 1) {
+      failf(data,
+            "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)",
+            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+            (((unsigned char)socksreq[8] << 8) |
+             (unsigned char)socksreq[9]),
+            (unsigned char)socksreq[1]);
+    }
+    else if(socksreq[3] == 3) {
+      unsigned char port_upper = (unsigned char)socksreq[len - 2];
+      socksreq[len - 2] = 0;
+      failf(data,
+            "Can't complete SOCKS5 connection to %s:%d. (%d)",
+            (char *)&socksreq[5],
+            ((port_upper << 8) |
+             (unsigned char)socksreq[len - 1]),
+            (unsigned char)socksreq[1]);
+      socksreq[len - 2] = port_upper;
+    }
+    else if(socksreq[3] == 4) {
+      failf(data,
+            "Can't complete SOCKS5 connection to %02x%02x:%02x%02x:"
+            "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%d. (%d)",
+            (unsigned char)socksreq[4], (unsigned char)socksreq[5],
+            (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+            (unsigned char)socksreq[8], (unsigned char)socksreq[9],
+            (unsigned char)socksreq[10], (unsigned char)socksreq[11],
+            (unsigned char)socksreq[12], (unsigned char)socksreq[13],
+            (unsigned char)socksreq[14], (unsigned char)socksreq[15],
+            (unsigned char)socksreq[16], (unsigned char)socksreq[17],
+            (unsigned char)socksreq[18], (unsigned char)socksreq[19],
+            (((unsigned char)socksreq[20] << 8) |
+             (unsigned char)socksreq[21]),
+            (unsigned char)socksreq[1]);
+    }
+    return CURLE_COULDNT_CONNECT;
+  }
+  infof(data, "SOCKS5 request granted.\n");
+
+  (void)curlx_nonblock(sock, TRUE);
+  return CURLE_OK; /* Proxy was successful! */
+}
+
+#endif /* CURL_DISABLE_PROXY */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/socks.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/socks.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/socks.h	(revision 331)
@@ -0,0 +1,76 @@
+#ifndef HEADER_CURL_SOCKS_H
+#define HEADER_CURL_SOCKS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef CURL_DISABLE_PROXY
+#define Curl_SOCKS4(a,b,c,d,e) CURLE_NOT_BUILT_IN
+#define Curl_SOCKS5(a,b,c,d,e,f) CURLE_NOT_BUILT_IN
+#else
+/*
+ * Helper read-from-socket functions. Does the same as Curl_read() but it
+ * blocks until all bytes amount of buffersize will be read. No more, no less.
+ *
+ * This is STUPID BLOCKING behaviour which we frown upon, but right now this
+ * is what we have...
+ */
+int Curl_blockread_all(struct connectdata *conn,
+                       curl_socket_t sockfd,
+                       char *buf,
+                       ssize_t buffersize,
+                       ssize_t *n);
+
+/*
+ * This function logs in to a SOCKS4(a) proxy and sends the specifics to the
+ * final destination server.
+ */
+CURLcode Curl_SOCKS4(const char *proxy_name,
+                     const char *hostname,
+                     int remote_port,
+                     int sockindex,
+                     struct connectdata *conn);
+
+/*
+ * This function logs in to a SOCKS5 proxy and sends the specifics to the
+ * final destination server.
+ */
+CURLcode Curl_SOCKS5(const char *proxy_name,
+                     const char *proxy_password,
+                     const char *hostname,
+                     int remote_port,
+                     int sockindex,
+                     struct connectdata *conn);
+
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+/*
+ * This function handles the SOCKS5 GSS-API negotiation and initialisation
+ */
+CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
+                                      struct connectdata *conn);
+#endif
+
+#endif /* CURL_DISABLE_PROXY */
+
+#endif  /* HEADER_CURL_SOCKS_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/socks_gssapi.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/socks_gssapi.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/socks_gssapi.c	(revision 331)
@@ -0,0 +1,527 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2009, Markus Moeller, <markus_moeller@compuserve.com>
+ * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_PROXY)
+
+#include "curl_gssapi.h"
+#include "urldata.h"
+#include "sendf.h"
+#include "connect.h"
+#include "timeval.h"
+#include "socks.h"
+#include "warnless.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+static gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
+
+/*
+ * Helper GSS-API error functions.
+ */
+static int check_gss_err(struct Curl_easy *data,
+                         OM_uint32 major_status,
+                         OM_uint32 minor_status,
+                         const char *function)
+{
+  if(GSS_ERROR(major_status)) {
+    OM_uint32 maj_stat, min_stat;
+    OM_uint32 msg_ctx = 0;
+    gss_buffer_desc status_string;
+    char buf[1024];
+    size_t len;
+
+    len = 0;
+    msg_ctx = 0;
+    while(!msg_ctx) {
+      /* convert major status code (GSS-API error) to text */
+      maj_stat = gss_display_status(&min_stat, major_status,
+                                    GSS_C_GSS_CODE,
+                                    GSS_C_NULL_OID,
+                                    &msg_ctx, &status_string);
+      if(maj_stat == GSS_S_COMPLETE) {
+        if(sizeof(buf) > len + status_string.length + 1) {
+          strcpy(buf + len, (char *) status_string.value);
+          len += status_string.length;
+        }
+        gss_release_buffer(&min_stat, &status_string);
+        break;
+      }
+      gss_release_buffer(&min_stat, &status_string);
+    }
+    if(sizeof(buf) > len + 3) {
+      strcpy(buf + len, ".\n");
+      len += 2;
+    }
+    msg_ctx = 0;
+    while(!msg_ctx) {
+      /* convert minor status code (underlying routine error) to text */
+      maj_stat = gss_display_status(&min_stat, minor_status,
+                                    GSS_C_MECH_CODE,
+                                    GSS_C_NULL_OID,
+                                    &msg_ctx, &status_string);
+      if(maj_stat == GSS_S_COMPLETE) {
+        if(sizeof(buf) > len + status_string.length)
+          strcpy(buf + len, (char *) status_string.value);
+        gss_release_buffer(&min_stat, &status_string);
+        break;
+      }
+      gss_release_buffer(&min_stat, &status_string);
+    }
+    failf(data, "GSS-API error: %s failed:\n%s", function, buf);
+    return 1;
+  }
+
+  return 0;
+}
+
+CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
+                                      struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  curl_socket_t sock = conn->sock[sockindex];
+  CURLcode code;
+  ssize_t actualread;
+  ssize_t written;
+  int result;
+  OM_uint32 gss_major_status, gss_minor_status, gss_status;
+  OM_uint32 gss_ret_flags;
+  int gss_conf_state, gss_enc;
+  gss_buffer_desc  service = GSS_C_EMPTY_BUFFER;
+  gss_buffer_desc  gss_send_token = GSS_C_EMPTY_BUFFER;
+  gss_buffer_desc  gss_recv_token = GSS_C_EMPTY_BUFFER;
+  gss_buffer_desc  gss_w_token = GSS_C_EMPTY_BUFFER;
+  gss_buffer_desc* gss_token = GSS_C_NO_BUFFER;
+  gss_name_t       server = GSS_C_NO_NAME;
+  gss_name_t       gss_client_name = GSS_C_NO_NAME;
+  unsigned short   us_length;
+  char             *user = NULL;
+  unsigned char socksreq[4]; /* room for GSS-API exchange header only */
+  const char *serviceptr = data->set.str[STRING_PROXY_SERVICE_NAME] ?
+                           data->set.str[STRING_PROXY_SERVICE_NAME] : "rcmd";
+  const size_t serviceptr_length = strlen(serviceptr);
+
+  /*   GSS-API request looks like
+   * +----+------+-----+----------------+
+   * |VER | MTYP | LEN |     TOKEN      |
+   * +----+------+----------------------+
+   * | 1  |  1   |  2  | up to 2^16 - 1 |
+   * +----+------+-----+----------------+
+   */
+
+  /* prepare service name */
+  if(strchr(serviceptr, '/')) {
+    service.length = serviceptr_length;
+    service.value = malloc(service.length);
+    if(!service.value)
+      return CURLE_OUT_OF_MEMORY;
+    memcpy(service.value, serviceptr, service.length);
+
+    gss_major_status = gss_import_name(&gss_minor_status, &service,
+                                       (gss_OID) GSS_C_NULL_OID, &server);
+  }
+  else {
+    service.value = malloc(serviceptr_length +
+                           strlen(conn->socks_proxy.host.name) + 2);
+    if(!service.value)
+      return CURLE_OUT_OF_MEMORY;
+    service.length = serviceptr_length +
+      strlen(conn->socks_proxy.host.name) + 1;
+    snprintf(service.value, service.length + 1, "%s@%s",
+             serviceptr, conn->socks_proxy.host.name);
+
+    gss_major_status = gss_import_name(&gss_minor_status, &service,
+                                       GSS_C_NT_HOSTBASED_SERVICE, &server);
+  }
+
+  gss_release_buffer(&gss_status, &service); /* clear allocated memory */
+
+  if(check_gss_err(data, gss_major_status,
+                   gss_minor_status, "gss_import_name()")) {
+    failf(data, "Failed to create service name.");
+    gss_release_name(&gss_status, &server);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  /* As long as we need to keep sending some context info, and there's no  */
+  /* errors, keep sending it...                                            */
+  for(;;) {
+    gss_major_status = Curl_gss_init_sec_context(data,
+                                                 &gss_minor_status,
+                                                 &gss_context,
+                                                 server,
+                                                 &Curl_krb5_mech_oid,
+                                                 NULL,
+                                                 gss_token,
+                                                 &gss_send_token,
+                                                 TRUE,
+                                                 &gss_ret_flags);
+
+    if(gss_token != GSS_C_NO_BUFFER)
+      gss_release_buffer(&gss_status, &gss_recv_token);
+    if(check_gss_err(data, gss_major_status,
+                     gss_minor_status, "gss_init_sec_context")) {
+      gss_release_name(&gss_status, &server);
+      gss_release_buffer(&gss_status, &gss_recv_token);
+      gss_release_buffer(&gss_status, &gss_send_token);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      failf(data, "Failed to initial GSS-API token.");
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    if(gss_send_token.length != 0) {
+      socksreq[0] = 1;    /* GSS-API subnegotiation version */
+      socksreq[1] = 1;    /* authentication message type */
+      us_length = htons((short)gss_send_token.length);
+      memcpy(socksreq + 2, &us_length, sizeof(short));
+
+      code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
+      if(code || (4 != written)) {
+        failf(data, "Failed to send GSS-API authentication request.");
+        gss_release_name(&gss_status, &server);
+        gss_release_buffer(&gss_status, &gss_recv_token);
+        gss_release_buffer(&gss_status, &gss_send_token);
+        gss_delete_sec_context(&gss_status, &gss_context, NULL);
+        return CURLE_COULDNT_CONNECT;
+      }
+
+      code = Curl_write_plain(conn, sock, (char *)gss_send_token.value,
+                              gss_send_token.length, &written);
+
+      if(code || ((ssize_t)gss_send_token.length != written)) {
+        failf(data, "Failed to send GSS-API authentication token.");
+        gss_release_name(&gss_status, &server);
+        gss_release_buffer(&gss_status, &gss_recv_token);
+        gss_release_buffer(&gss_status, &gss_send_token);
+        gss_delete_sec_context(&gss_status, &gss_context, NULL);
+        return CURLE_COULDNT_CONNECT;
+      }
+
+    }
+
+    gss_release_buffer(&gss_status, &gss_send_token);
+    gss_release_buffer(&gss_status, &gss_recv_token);
+    if(gss_major_status != GSS_S_CONTINUE_NEEDED) break;
+
+    /* analyse response */
+
+    /*   GSS-API response looks like
+     * +----+------+-----+----------------+
+     * |VER | MTYP | LEN |     TOKEN      |
+     * +----+------+----------------------+
+     * | 1  |  1   |  2  | up to 2^16 - 1 |
+     * +----+------+-----+----------------+
+     */
+
+    result = Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
+    if(result || (actualread != 4)) {
+      failf(data, "Failed to receive GSS-API authentication response.");
+      gss_release_name(&gss_status, &server);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    /* ignore the first (VER) byte */
+    if(socksreq[1] == 255) { /* status / message type */
+      failf(data, "User was rejected by the SOCKS5 server (%d %d).",
+            socksreq[0], socksreq[1]);
+      gss_release_name(&gss_status, &server);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    if(socksreq[1] != 1) { /* status / messgae type */
+      failf(data, "Invalid GSS-API authentication response type (%d %d).",
+            socksreq[0], socksreq[1]);
+      gss_release_name(&gss_status, &server);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    memcpy(&us_length, socksreq + 2, sizeof(short));
+    us_length = ntohs(us_length);
+
+    gss_recv_token.length = us_length;
+    gss_recv_token.value = malloc(us_length);
+    if(!gss_recv_token.value) {
+      failf(data,
+            "Could not allocate memory for GSS-API authentication "
+            "response token.");
+      gss_release_name(&gss_status, &server);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    result = Curl_blockread_all(conn, sock, (char *)gss_recv_token.value,
+                                gss_recv_token.length, &actualread);
+
+    if(result || (actualread != us_length)) {
+      failf(data, "Failed to receive GSS-API authentication token.");
+      gss_release_name(&gss_status, &server);
+      gss_release_buffer(&gss_status, &gss_recv_token);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    gss_token = &gss_recv_token;
+  }
+
+  gss_release_name(&gss_status, &server);
+
+  /* Everything is good so far, user was authenticated! */
+  gss_major_status = gss_inquire_context(&gss_minor_status, gss_context,
+                                         &gss_client_name, NULL, NULL, NULL,
+                                         NULL, NULL, NULL);
+  if(check_gss_err(data, gss_major_status,
+                   gss_minor_status, "gss_inquire_context")) {
+    gss_delete_sec_context(&gss_status, &gss_context, NULL);
+    gss_release_name(&gss_status, &gss_client_name);
+    failf(data, "Failed to determine user name.");
+    return CURLE_COULDNT_CONNECT;
+  }
+  gss_major_status = gss_display_name(&gss_minor_status, gss_client_name,
+                                      &gss_send_token, NULL);
+  if(check_gss_err(data, gss_major_status,
+                   gss_minor_status, "gss_display_name")) {
+    gss_delete_sec_context(&gss_status, &gss_context, NULL);
+    gss_release_name(&gss_status, &gss_client_name);
+    gss_release_buffer(&gss_status, &gss_send_token);
+    failf(data, "Failed to determine user name.");
+    return CURLE_COULDNT_CONNECT;
+  }
+  user = malloc(gss_send_token.length + 1);
+  if(!user) {
+    gss_delete_sec_context(&gss_status, &gss_context, NULL);
+    gss_release_name(&gss_status, &gss_client_name);
+    gss_release_buffer(&gss_status, &gss_send_token);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  memcpy(user, gss_send_token.value, gss_send_token.length);
+  user[gss_send_token.length] = '\0';
+  gss_release_name(&gss_status, &gss_client_name);
+  gss_release_buffer(&gss_status, &gss_send_token);
+  infof(data, "SOCKS5 server authencticated user %s with GSS-API.\n",user);
+  free(user);
+  user = NULL;
+
+  /* Do encryption */
+  socksreq[0] = 1;    /* GSS-API subnegotiation version */
+  socksreq[1] = 2;    /* encryption message type */
+
+  gss_enc = 0; /* no data protection */
+  /* do confidentiality protection if supported */
+  if(gss_ret_flags & GSS_C_CONF_FLAG)
+    gss_enc = 2;
+  /* else do integrity protection */
+  else if(gss_ret_flags & GSS_C_INTEG_FLAG)
+    gss_enc = 1;
+
+  infof(data, "SOCKS5 server supports GSS-API %s data protection.\n",
+        (gss_enc == 0)?"no":((gss_enc==1)?"integrity":"confidentiality"));
+  /* force for the moment to no data protection */
+  gss_enc = 0;
+  /*
+   * Sending the encryption type in clear seems wrong. It should be
+   * protected with gss_seal()/gss_wrap(). See RFC1961 extract below
+   * The NEC reference implementations on which this is based is
+   * therefore at fault
+   *
+   *  +------+------+------+.......................+
+   *  + ver  | mtyp | len  |   token               |
+   *  +------+------+------+.......................+
+   *  + 0x01 | 0x02 | 0x02 | up to 2^16 - 1 octets |
+   *  +------+------+------+.......................+
+   *
+   *   Where:
+   *
+   *  - "ver" is the protocol version number, here 1 to represent the
+   *    first version of the SOCKS/GSS-API protocol
+   *
+   *  - "mtyp" is the message type, here 2 to represent a protection
+   *    -level negotiation message
+   *
+   *  - "len" is the length of the "token" field in octets
+   *
+   *  - "token" is the GSS-API encapsulated protection level
+   *
+   * The token is produced by encapsulating an octet containing the
+   * required protection level using gss_seal()/gss_wrap() with conf_req
+   * set to FALSE.  The token is verified using gss_unseal()/
+   * gss_unwrap().
+   *
+   */
+  if(data->set.socks5_gssapi_nec) {
+    us_length = htons((short)1);
+    memcpy(socksreq + 2, &us_length, sizeof(short));
+  }
+  else {
+    gss_send_token.length = 1;
+    gss_send_token.value = malloc(1);
+    if(!gss_send_token.value) {
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      return CURLE_OUT_OF_MEMORY;
+    }
+    memcpy(gss_send_token.value, &gss_enc, 1);
+
+    gss_major_status = gss_wrap(&gss_minor_status, gss_context, 0,
+                                GSS_C_QOP_DEFAULT, &gss_send_token,
+                                &gss_conf_state, &gss_w_token);
+
+    if(check_gss_err(data, gss_major_status, gss_minor_status, "gss_wrap")) {
+      gss_release_buffer(&gss_status, &gss_send_token);
+      gss_release_buffer(&gss_status, &gss_w_token);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      failf(data, "Failed to wrap GSS-API encryption value into token.");
+      return CURLE_COULDNT_CONNECT;
+    }
+    gss_release_buffer(&gss_status, &gss_send_token);
+
+    us_length = htons((short)gss_w_token.length);
+    memcpy(socksreq + 2, &us_length, sizeof(short));
+  }
+
+  code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
+  if(code  || (4 != written)) {
+    failf(data, "Failed to send GSS-API encryption request.");
+    gss_release_buffer(&gss_status, &gss_w_token);
+    gss_delete_sec_context(&gss_status, &gss_context, NULL);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  if(data->set.socks5_gssapi_nec) {
+    memcpy(socksreq, &gss_enc, 1);
+    code = Curl_write_plain(conn, sock, socksreq, 1, &written);
+    if(code || ( 1 != written)) {
+      failf(data, "Failed to send GSS-API encryption type.");
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      return CURLE_COULDNT_CONNECT;
+    }
+  }
+  else {
+    code = Curl_write_plain(conn, sock, (char *)gss_w_token.value,
+                            gss_w_token.length, &written);
+    if(code || ((ssize_t)gss_w_token.length != written)) {
+      failf(data, "Failed to send GSS-API encryption type.");
+      gss_release_buffer(&gss_status, &gss_w_token);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      return CURLE_COULDNT_CONNECT;
+    }
+    gss_release_buffer(&gss_status, &gss_w_token);
+  }
+
+  result = Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
+  if(result || (actualread != 4)) {
+    failf(data, "Failed to receive GSS-API encryption response.");
+    gss_delete_sec_context(&gss_status, &gss_context, NULL);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  /* ignore the first (VER) byte */
+  if(socksreq[1] == 255) { /* status / message type */
+    failf(data, "User was rejected by the SOCKS5 server (%d %d).",
+          socksreq[0], socksreq[1]);
+    gss_delete_sec_context(&gss_status, &gss_context, NULL);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  if(socksreq[1] != 2) { /* status / messgae type */
+    failf(data, "Invalid GSS-API encryption response type (%d %d).",
+          socksreq[0], socksreq[1]);
+    gss_delete_sec_context(&gss_status, &gss_context, NULL);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  memcpy(&us_length, socksreq + 2, sizeof(short));
+  us_length = ntohs(us_length);
+
+  gss_recv_token.length = us_length;
+  gss_recv_token.value = malloc(gss_recv_token.length);
+  if(!gss_recv_token.value) {
+    gss_delete_sec_context(&gss_status, &gss_context, NULL);
+    return CURLE_OUT_OF_MEMORY;
+  }
+  result = Curl_blockread_all(conn, sock, (char *)gss_recv_token.value,
+                              gss_recv_token.length, &actualread);
+
+  if(result || (actualread != us_length)) {
+    failf(data, "Failed to receive GSS-API encryptrion type.");
+    gss_release_buffer(&gss_status, &gss_recv_token);
+    gss_delete_sec_context(&gss_status, &gss_context, NULL);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  if(!data->set.socks5_gssapi_nec) {
+    gss_major_status = gss_unwrap(&gss_minor_status, gss_context,
+                                  &gss_recv_token, &gss_w_token,
+                                  0, GSS_C_QOP_DEFAULT);
+
+    if(check_gss_err(data, gss_major_status, gss_minor_status, "gss_unwrap")) {
+      gss_release_buffer(&gss_status, &gss_recv_token);
+      gss_release_buffer(&gss_status, &gss_w_token);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      failf(data, "Failed to unwrap GSS-API encryption value into token.");
+      return CURLE_COULDNT_CONNECT;
+    }
+    gss_release_buffer(&gss_status, &gss_recv_token);
+
+    if(gss_w_token.length != 1) {
+      failf(data, "Invalid GSS-API encryption response length (%d).",
+            gss_w_token.length);
+      gss_release_buffer(&gss_status, &gss_w_token);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    memcpy(socksreq, gss_w_token.value, gss_w_token.length);
+    gss_release_buffer(&gss_status, &gss_w_token);
+  }
+  else {
+    if(gss_recv_token.length != 1) {
+      failf(data, "Invalid GSS-API encryption response length (%d).",
+            gss_recv_token.length);
+      gss_release_buffer(&gss_status, &gss_recv_token);
+      gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    memcpy(socksreq, gss_recv_token.value, gss_recv_token.length);
+    gss_release_buffer(&gss_status, &gss_recv_token);
+  }
+
+  infof(data, "SOCKS5 access with%s protection granted.\n",
+        (socksreq[0] == 0)?"out GSS-API data":
+        ((socksreq[0] == 1)?" GSS-API integrity":" GSS-API confidentiality"));
+
+  conn->socks5_gssapi_enctype = socksreq[0];
+  if(socksreq[0] == 0)
+    gss_delete_sec_context(&gss_status, &gss_context, NULL);
+
+  return CURLE_OK;
+}
+
+#endif /* HAVE_GSSAPI && !CURL_DISABLE_PROXY */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/socks_sspi.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/socks_sspi.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/socks_sspi.c	(revision 331)
@@ -0,0 +1,605 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2009, 2011, Markus Moeller, <markus_moeller@compuserve.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_WINDOWS_SSPI) && !defined(CURL_DISABLE_PROXY)
+
+#include "urldata.h"
+#include "sendf.h"
+#include "connect.h"
+#include "strerror.h"
+#include "timeval.h"
+#include "socks.h"
+#include "curl_sspi.h"
+#include "curl_multibyte.h"
+#include "warnless.h"
+#include "strdup.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * Helper sspi error functions.
+ */
+static int check_sspi_err(struct connectdata *conn,
+                          SECURITY_STATUS status,
+                          const char *function)
+{
+  if(status != SEC_E_OK &&
+     status != SEC_I_COMPLETE_AND_CONTINUE &&
+     status != SEC_I_COMPLETE_NEEDED &&
+     status != SEC_I_CONTINUE_NEEDED) {
+    failf(conn->data, "SSPI error: %s failed: %s", function,
+          Curl_sspi_strerror(conn, status));
+    return 1;
+  }
+  return 0;
+}
+
+/* This is the SSPI-using version of this function */
+CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
+                                      struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  curl_socket_t sock = conn->sock[sockindex];
+  CURLcode code;
+  ssize_t actualread;
+  ssize_t written;
+  int result;
+  /* Needs GSS-API authentication */
+  SECURITY_STATUS status;
+  unsigned long sspi_ret_flags = 0;
+  unsigned char gss_enc;
+  SecBuffer sspi_send_token, sspi_recv_token, sspi_w_token[3];
+  SecBufferDesc input_desc, output_desc, wrap_desc;
+  SecPkgContext_Sizes sspi_sizes;
+  CredHandle cred_handle;
+  CtxtHandle sspi_context;
+  PCtxtHandle context_handle = NULL;
+  SecPkgCredentials_Names names;
+  TimeStamp expiry;
+  char *service_name = NULL;
+  unsigned short us_length;
+  unsigned long qop;
+  unsigned char socksreq[4]; /* room for GSS-API exchange header only */
+  const char *service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
+                        data->set.str[STRING_PROXY_SERVICE_NAME]  : "rcmd";
+  const size_t service_length = strlen(service);
+
+  /*   GSS-API request looks like
+   * +----+------+-----+----------------+
+   * |VER | MTYP | LEN |     TOKEN      |
+   * +----+------+----------------------+
+   * | 1  |  1   |  2  | up to 2^16 - 1 |
+   * +----+------+-----+----------------+
+   */
+
+  /* prepare service name */
+  if(strchr(service, '/')) {
+    service_name = strdup(service);
+    if(!service_name)
+      return CURLE_OUT_OF_MEMORY;
+  }
+  else {
+    service_name = malloc(service_length +
+                          strlen(conn->socks_proxy.host.name) + 2);
+    if(!service_name)
+      return CURLE_OUT_OF_MEMORY;
+    snprintf(service_name, service_length +
+             strlen(conn->socks_proxy.host.name) + 2, "%s/%s",
+             service, conn->socks_proxy.host.name);
+  }
+
+  input_desc.cBuffers = 1;
+  input_desc.pBuffers = &sspi_recv_token;
+  input_desc.ulVersion = SECBUFFER_VERSION;
+
+  sspi_recv_token.BufferType = SECBUFFER_TOKEN;
+  sspi_recv_token.cbBuffer = 0;
+  sspi_recv_token.pvBuffer = NULL;
+
+  output_desc.cBuffers = 1;
+  output_desc.pBuffers = &sspi_send_token;
+  output_desc.ulVersion = SECBUFFER_VERSION;
+
+  sspi_send_token.BufferType = SECBUFFER_TOKEN;
+  sspi_send_token.cbBuffer = 0;
+  sspi_send_token.pvBuffer = NULL;
+
+  wrap_desc.cBuffers = 3;
+  wrap_desc.pBuffers = sspi_w_token;
+  wrap_desc.ulVersion = SECBUFFER_VERSION;
+
+  cred_handle.dwLower = 0;
+  cred_handle.dwUpper = 0;
+
+  status = s_pSecFn->AcquireCredentialsHandle(NULL,
+                                              (TCHAR *) TEXT("Kerberos"),
+                                              SECPKG_CRED_OUTBOUND,
+                                              NULL,
+                                              NULL,
+                                              NULL,
+                                              NULL,
+                                              &cred_handle,
+                                              &expiry);
+
+  if(check_sspi_err(conn, status, "AcquireCredentialsHandle")) {
+    failf(data, "Failed to acquire credentials.");
+    free(service_name);
+    s_pSecFn->FreeCredentialsHandle(&cred_handle);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  /* As long as we need to keep sending some context info, and there's no  */
+  /* errors, keep sending it...                                            */
+  for(;;) {
+    TCHAR *sname;
+
+    sname = Curl_convert_UTF8_to_tchar(service_name);
+    if(!sname)
+      return CURLE_OUT_OF_MEMORY;
+
+    status = s_pSecFn->InitializeSecurityContext(&cred_handle,
+                                                 context_handle,
+                                                 sname,
+                                                 ISC_REQ_MUTUAL_AUTH |
+                                                 ISC_REQ_ALLOCATE_MEMORY |
+                                                 ISC_REQ_CONFIDENTIALITY |
+                                                 ISC_REQ_REPLAY_DETECT,
+                                                 0,
+                                                 SECURITY_NATIVE_DREP,
+                                                 &input_desc,
+                                                 0,
+                                                 &sspi_context,
+                                                 &output_desc,
+                                                 &sspi_ret_flags,
+                                                 &expiry);
+
+    Curl_unicodefree(sname);
+
+    if(sspi_recv_token.pvBuffer) {
+      s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
+      sspi_recv_token.pvBuffer = NULL;
+      sspi_recv_token.cbBuffer = 0;
+    }
+
+    if(check_sspi_err(conn, status, "InitializeSecurityContext")) {
+      free(service_name);
+      s_pSecFn->FreeCredentialsHandle(&cred_handle);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      if(sspi_recv_token.pvBuffer)
+        s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
+      failf(data, "Failed to initialise security context.");
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    if(sspi_send_token.cbBuffer != 0) {
+      socksreq[0] = 1;    /* GSS-API subnegotiation version */
+      socksreq[1] = 1;    /* authentication message type */
+      us_length = htons((short)sspi_send_token.cbBuffer);
+      memcpy(socksreq + 2, &us_length, sizeof(short));
+
+      code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
+      if(code || (4 != written)) {
+        failf(data, "Failed to send SSPI authentication request.");
+        free(service_name);
+        if(sspi_send_token.pvBuffer)
+          s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
+        if(sspi_recv_token.pvBuffer)
+          s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
+        s_pSecFn->FreeCredentialsHandle(&cred_handle);
+        s_pSecFn->DeleteSecurityContext(&sspi_context);
+        return CURLE_COULDNT_CONNECT;
+      }
+
+      code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer,
+                              sspi_send_token.cbBuffer, &written);
+      if(code || (sspi_send_token.cbBuffer != (size_t)written)) {
+        failf(data, "Failed to send SSPI authentication token.");
+        free(service_name);
+        if(sspi_send_token.pvBuffer)
+          s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
+        if(sspi_recv_token.pvBuffer)
+          s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
+        s_pSecFn->FreeCredentialsHandle(&cred_handle);
+        s_pSecFn->DeleteSecurityContext(&sspi_context);
+        return CURLE_COULDNT_CONNECT;
+      }
+
+    }
+
+    if(sspi_send_token.pvBuffer) {
+      s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
+      sspi_send_token.pvBuffer = NULL;
+    }
+    sspi_send_token.cbBuffer = 0;
+
+    if(sspi_recv_token.pvBuffer) {
+      s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
+      sspi_recv_token.pvBuffer = NULL;
+    }
+    sspi_recv_token.cbBuffer = 0;
+
+    if(status != SEC_I_CONTINUE_NEEDED)
+      break;
+
+    /* analyse response */
+
+    /*   GSS-API response looks like
+     * +----+------+-----+----------------+
+     * |VER | MTYP | LEN |     TOKEN      |
+     * +----+------+----------------------+
+     * | 1  |  1   |  2  | up to 2^16 - 1 |
+     * +----+------+-----+----------------+
+     */
+
+    result = Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
+    if(result || (actualread != 4)) {
+      failf(data, "Failed to receive SSPI authentication response.");
+      free(service_name);
+      s_pSecFn->FreeCredentialsHandle(&cred_handle);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    /* ignore the first (VER) byte */
+    if(socksreq[1] == 255) { /* status / message type */
+      failf(data, "User was rejected by the SOCKS5 server (%u %u).",
+            (unsigned int)socksreq[0], (unsigned int)socksreq[1]);
+      free(service_name);
+      s_pSecFn->FreeCredentialsHandle(&cred_handle);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    if(socksreq[1] != 1) { /* status / messgae type */
+      failf(data, "Invalid SSPI authentication response type (%u %u).",
+            (unsigned int)socksreq[0], (unsigned int)socksreq[1]);
+      free(service_name);
+      s_pSecFn->FreeCredentialsHandle(&cred_handle);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    memcpy(&us_length, socksreq + 2, sizeof(short));
+    us_length = ntohs(us_length);
+
+    sspi_recv_token.cbBuffer = us_length;
+    sspi_recv_token.pvBuffer = malloc(us_length);
+
+    if(!sspi_recv_token.pvBuffer) {
+      free(service_name);
+      s_pSecFn->FreeCredentialsHandle(&cred_handle);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_OUT_OF_MEMORY;
+    }
+    result = Curl_blockread_all(conn, sock, (char *)sspi_recv_token.pvBuffer,
+                                sspi_recv_token.cbBuffer, &actualread);
+
+    if(result || (actualread != us_length)) {
+      failf(data, "Failed to receive SSPI authentication token.");
+      free(service_name);
+      if(sspi_recv_token.pvBuffer)
+        s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
+      s_pSecFn->FreeCredentialsHandle(&cred_handle);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    context_handle = &sspi_context;
+  }
+
+  free(service_name);
+
+  /* Everything is good so far, user was authenticated! */
+  status = s_pSecFn->QueryCredentialsAttributes(&cred_handle,
+                                                SECPKG_CRED_ATTR_NAMES,
+                                                &names);
+  s_pSecFn->FreeCredentialsHandle(&cred_handle);
+  if(check_sspi_err(conn, status, "QueryCredentialAttributes")) {
+    s_pSecFn->DeleteSecurityContext(&sspi_context);
+    s_pSecFn->FreeContextBuffer(names.sUserName);
+    failf(data, "Failed to determine user name.");
+    return CURLE_COULDNT_CONNECT;
+  }
+  infof(data, "SOCKS5 server authencticated user %s with GSS-API.\n",
+        names.sUserName);
+  s_pSecFn->FreeContextBuffer(names.sUserName);
+
+  /* Do encryption */
+  socksreq[0] = 1;    /* GSS-API subnegotiation version */
+  socksreq[1] = 2;    /* encryption message type */
+
+  gss_enc = 0; /* no data protection */
+  /* do confidentiality protection if supported */
+  if(sspi_ret_flags & ISC_REQ_CONFIDENTIALITY)
+    gss_enc = 2;
+  /* else do integrity protection */
+  else if(sspi_ret_flags & ISC_REQ_INTEGRITY)
+    gss_enc = 1;
+
+  infof(data, "SOCKS5 server supports GSS-API %s data protection.\n",
+        (gss_enc == 0)?"no":((gss_enc == 1)?"integrity":"confidentiality") );
+  /* force to no data protection, avoid encryption/decryption for now */
+  gss_enc = 0;
+  /*
+   * Sending the encryption type in clear seems wrong. It should be
+   * protected with gss_seal()/gss_wrap(). See RFC1961 extract below
+   * The NEC reference implementations on which this is based is
+   * therefore at fault
+   *
+   *  +------+------+------+.......................+
+   *  + ver  | mtyp | len  |   token               |
+   *  +------+------+------+.......................+
+   *  + 0x01 | 0x02 | 0x02 | up to 2^16 - 1 octets |
+   *  +------+------+------+.......................+
+   *
+   *   Where:
+   *
+   *  - "ver" is the protocol version number, here 1 to represent the
+   *    first version of the SOCKS/GSS-API protocol
+   *
+   *  - "mtyp" is the message type, here 2 to represent a protection
+   *    -level negotiation message
+   *
+   *  - "len" is the length of the "token" field in octets
+   *
+   *  - "token" is the GSS-API encapsulated protection level
+   *
+   * The token is produced by encapsulating an octet containing the
+   * required protection level using gss_seal()/gss_wrap() with conf_req
+   * set to FALSE.  The token is verified using gss_unseal()/
+   * gss_unwrap().
+   *
+   */
+
+  if(data->set.socks5_gssapi_nec) {
+    us_length = htons((short)1);
+    memcpy(socksreq + 2, &us_length, sizeof(short));
+  }
+  else {
+    status = s_pSecFn->QueryContextAttributes(&sspi_context,
+                                              SECPKG_ATTR_SIZES,
+                                              &sspi_sizes);
+    if(check_sspi_err(conn, status, "QueryContextAttributes")) {
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      failf(data, "Failed to query security context attributes.");
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    sspi_w_token[0].cbBuffer = sspi_sizes.cbSecurityTrailer;
+    sspi_w_token[0].BufferType = SECBUFFER_TOKEN;
+    sspi_w_token[0].pvBuffer = malloc(sspi_sizes.cbSecurityTrailer);
+
+    if(!sspi_w_token[0].pvBuffer) {
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    sspi_w_token[1].cbBuffer = 1;
+    sspi_w_token[1].pvBuffer = malloc(1);
+    if(!sspi_w_token[1].pvBuffer) {
+      s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    memcpy(sspi_w_token[1].pvBuffer, &gss_enc, 1);
+    sspi_w_token[2].BufferType = SECBUFFER_PADDING;
+    sspi_w_token[2].cbBuffer = sspi_sizes.cbBlockSize;
+    sspi_w_token[2].pvBuffer = malloc(sspi_sizes.cbBlockSize);
+    if(!sspi_w_token[2].pvBuffer) {
+      s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+      s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_OUT_OF_MEMORY;
+    }
+    status = s_pSecFn->EncryptMessage(&sspi_context,
+                                      KERB_WRAP_NO_ENCRYPT,
+                                      &wrap_desc,
+                                      0);
+    if(check_sspi_err(conn, status, "EncryptMessage")) {
+      s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+      s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+      s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      failf(data, "Failed to query security context attributes.");
+      return CURLE_COULDNT_CONNECT;
+    }
+    sspi_send_token.cbBuffer = sspi_w_token[0].cbBuffer
+      + sspi_w_token[1].cbBuffer
+      + sspi_w_token[2].cbBuffer;
+    sspi_send_token.pvBuffer = malloc(sspi_send_token.cbBuffer);
+    if(!sspi_send_token.pvBuffer) {
+      s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+      s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+      s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    memcpy(sspi_send_token.pvBuffer, sspi_w_token[0].pvBuffer,
+           sspi_w_token[0].cbBuffer);
+    memcpy((PUCHAR) sspi_send_token.pvBuffer +(int)sspi_w_token[0].cbBuffer,
+           sspi_w_token[1].pvBuffer, sspi_w_token[1].cbBuffer);
+    memcpy((PUCHAR) sspi_send_token.pvBuffer
+           + sspi_w_token[0].cbBuffer
+           + sspi_w_token[1].cbBuffer,
+           sspi_w_token[2].pvBuffer, sspi_w_token[2].cbBuffer);
+
+    s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+    sspi_w_token[0].pvBuffer = NULL;
+    sspi_w_token[0].cbBuffer = 0;
+    s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+    sspi_w_token[1].pvBuffer = NULL;
+    sspi_w_token[1].cbBuffer = 0;
+    s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
+    sspi_w_token[2].pvBuffer = NULL;
+    sspi_w_token[2].cbBuffer = 0;
+
+    us_length = htons((short)sspi_send_token.cbBuffer);
+    memcpy(socksreq + 2, &us_length, sizeof(short));
+  }
+
+  code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
+  if(code || (4 != written)) {
+    failf(data, "Failed to send SSPI encryption request.");
+    if(sspi_send_token.pvBuffer)
+      s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
+    s_pSecFn->DeleteSecurityContext(&sspi_context);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  if(data->set.socks5_gssapi_nec) {
+    memcpy(socksreq, &gss_enc, 1);
+    code = Curl_write_plain(conn, sock, (char *)socksreq, 1, &written);
+    if(code || (1 != written)) {
+      failf(data, "Failed to send SSPI encryption type.");
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_COULDNT_CONNECT;
+    }
+  }
+  else {
+    code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer,
+                            sspi_send_token.cbBuffer, &written);
+    if(code || (sspi_send_token.cbBuffer != (size_t)written)) {
+      failf(data, "Failed to send SSPI encryption type.");
+      if(sspi_send_token.pvBuffer)
+        s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_COULDNT_CONNECT;
+    }
+    if(sspi_send_token.pvBuffer)
+      s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
+  }
+
+  result = Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
+  if(result || (actualread != 4)) {
+    failf(data, "Failed to receive SSPI encryption response.");
+    s_pSecFn->DeleteSecurityContext(&sspi_context);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  /* ignore the first (VER) byte */
+  if(socksreq[1] == 255) { /* status / message type */
+    failf(data, "User was rejected by the SOCKS5 server (%u %u).",
+          (unsigned int)socksreq[0], (unsigned int)socksreq[1]);
+    s_pSecFn->DeleteSecurityContext(&sspi_context);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  if(socksreq[1] != 2) { /* status / message type */
+    failf(data, "Invalid SSPI encryption response type (%u %u).",
+          (unsigned int)socksreq[0], (unsigned int)socksreq[1]);
+    s_pSecFn->DeleteSecurityContext(&sspi_context);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+  memcpy(&us_length, socksreq + 2, sizeof(short));
+  us_length = ntohs(us_length);
+
+  sspi_w_token[0].cbBuffer = us_length;
+  sspi_w_token[0].pvBuffer = malloc(us_length);
+  if(!sspi_w_token[0].pvBuffer) {
+    s_pSecFn->DeleteSecurityContext(&sspi_context);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  result = Curl_blockread_all(conn, sock, (char *)sspi_w_token[0].pvBuffer,
+                              sspi_w_token[0].cbBuffer, &actualread);
+
+  if(result || (actualread != us_length)) {
+    failf(data, "Failed to receive SSPI encryption type.");
+    s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+    s_pSecFn->DeleteSecurityContext(&sspi_context);
+    return CURLE_COULDNT_CONNECT;
+  }
+
+
+  if(!data->set.socks5_gssapi_nec) {
+    wrap_desc.cBuffers = 2;
+    sspi_w_token[0].BufferType = SECBUFFER_STREAM;
+    sspi_w_token[1].BufferType = SECBUFFER_DATA;
+    sspi_w_token[1].cbBuffer = 0;
+    sspi_w_token[1].pvBuffer = NULL;
+
+    status = s_pSecFn->DecryptMessage(&sspi_context,
+                                      &wrap_desc,
+                                      0,
+                                      &qop);
+
+    if(check_sspi_err(conn, status, "DecryptMessage")) {
+      if(sspi_w_token[0].pvBuffer)
+        s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+      if(sspi_w_token[1].pvBuffer)
+        s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      failf(data, "Failed to query security context attributes.");
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    if(sspi_w_token[1].cbBuffer != 1) {
+      failf(data, "Invalid SSPI encryption response length (%lu).",
+            (unsigned long)sspi_w_token[1].cbBuffer);
+      if(sspi_w_token[0].pvBuffer)
+        s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+      if(sspi_w_token[1].pvBuffer)
+        s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_COULDNT_CONNECT;
+    }
+
+    memcpy(socksreq, sspi_w_token[1].pvBuffer, sspi_w_token[1].cbBuffer);
+    s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+    s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
+  }
+  else {
+    if(sspi_w_token[0].cbBuffer != 1) {
+      failf(data, "Invalid SSPI encryption response length (%lu).",
+            (unsigned long)sspi_w_token[0].cbBuffer);
+      s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+      s_pSecFn->DeleteSecurityContext(&sspi_context);
+      return CURLE_COULDNT_CONNECT;
+    }
+    memcpy(socksreq, sspi_w_token[0].pvBuffer, sspi_w_token[0].cbBuffer);
+    s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
+  }
+
+  infof(data, "SOCKS5 access with%s protection granted.\n",
+        (socksreq[0] == 0)?"out GSS-API data":
+        ((socksreq[0] == 1)?" GSS-API integrity":" GSS-API confidentiality"));
+
+  /* For later use if encryption is required
+     conn->socks5_gssapi_enctype = socksreq[0];
+     if(socksreq[0] != 0)
+       conn->socks5_sspi_context = sspi_context;
+     else {
+       s_pSecFn->DeleteSecurityContext(&sspi_context);
+       conn->socks5_sspi_context = sspi_context;
+     }
+  */
+  return CURLE_OK;
+}
+#endif
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/speedcheck.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/speedcheck.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/speedcheck.c	(revision 331)
@@ -0,0 +1,73 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "multiif.h"
+#include "speedcheck.h"
+
+void Curl_speedinit(struct Curl_easy *data)
+{
+  memset(&data->state.keeps_speed, 0, sizeof(struct curltime));
+}
+
+/*
+ * @unittest: 1606
+ */
+CURLcode Curl_speedcheck(struct Curl_easy *data,
+                         struct curltime now)
+{
+  if((data->progress.current_speed >= 0) && data->set.low_speed_time) {
+    if(data->progress.current_speed < data->set.low_speed_limit) {
+      if(!data->state.keeps_speed.tv_sec)
+        /* under the limit at this very moment */
+        data->state.keeps_speed = now;
+      else {
+        /* how long has it been under the limit */
+        timediff_t howlong = Curl_timediff(now, data->state.keeps_speed);
+
+        if(howlong >= data->set.low_speed_time * 1000) {
+          /* too long */
+          failf(data,
+                "Operation too slow. "
+                "Less than %ld bytes/sec transferred the last %ld seconds",
+                data->set.low_speed_limit,
+                data->set.low_speed_time);
+          return CURLE_OPERATION_TIMEDOUT;
+        }
+      }
+    }
+    else
+      /* faster right now */
+      data->state.keeps_speed.tv_sec = 0;
+  }
+
+  if(data->set.low_speed_limit)
+    /* if low speed limit is enabled, set the expire timer to make this
+       connection's speed get checked again in a second */
+    Curl_expire(data, 1000, EXPIRE_SPEEDCHECK);
+
+  return CURLE_OK;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/speedcheck.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/speedcheck.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/speedcheck.h	(revision 331)
@@ -0,0 +1,33 @@
+#ifndef HEADER_CURL_SPEEDCHECK_H
+#define HEADER_CURL_SPEEDCHECK_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "timeval.h"
+
+void Curl_speedinit(struct Curl_easy *data);
+CURLcode Curl_speedcheck(struct Curl_easy *data,
+                         struct curltime now);
+
+#endif /* HEADER_CURL_SPEEDCHECK_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/splay.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/splay.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/splay.c	(revision 331)
@@ -0,0 +1,278 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1997 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "splay.h"
+
+/*
+ * This macro compares two node keys i and j and returns:
+ *
+ *  negative value: when i is smaller than j
+ *  zero          : when i is equal   to   j
+ *  positive when : when i is larger  than j
+ */
+#define compare(i,j) Curl_splaycomparekeys((i),(j))
+
+/*
+ * Splay using the key i (which may or may not be in the tree.) The starting
+ * root is t.
+ */
+struct Curl_tree *Curl_splay(struct curltime i,
+                             struct Curl_tree *t)
+{
+  struct Curl_tree N, *l, *r, *y;
+  long comp;
+
+  if(t == NULL)
+    return t;
+  N.smaller = N.larger = NULL;
+  l = r = &N;
+
+  for(;;) {
+    comp = compare(i, t->key);
+    if(comp < 0) {
+      if(t->smaller == NULL)
+        break;
+      if(compare(i, t->smaller->key) < 0) {
+        y = t->smaller;                           /* rotate smaller */
+        t->smaller = y->larger;
+        y->larger = t;
+        t = y;
+        if(t->smaller == NULL)
+          break;
+      }
+      r->smaller = t;                               /* link smaller */
+      r = t;
+      t = t->smaller;
+    }
+    else if(comp > 0) {
+      if(t->larger == NULL)
+        break;
+      if(compare(i, t->larger->key) > 0) {
+        y = t->larger;                          /* rotate larger */
+        t->larger = y->smaller;
+        y->smaller = t;
+        t = y;
+        if(t->larger == NULL)
+          break;
+      }
+      l->larger = t;                              /* link larger */
+      l = t;
+      t = t->larger;
+    }
+    else
+      break;
+  }
+
+  l->larger = t->smaller;                                /* assemble */
+  r->smaller = t->larger;
+  t->smaller = N.larger;
+  t->larger = N.smaller;
+
+  return t;
+}
+
+/* Insert key i into the tree t.  Return a pointer to the resulting tree or
+ * NULL if something went wrong.
+ *
+ * @unittest: 1309
+ */
+struct Curl_tree *Curl_splayinsert(struct curltime i,
+                                   struct Curl_tree *t,
+                                   struct Curl_tree *node)
+{
+  static const struct curltime KEY_NOTUSED = {
+    (time_t)-1, (unsigned int)-1
+  }; /* will *NEVER* appear */
+
+  if(node == NULL)
+    return t;
+
+  if(t != NULL) {
+    t = Curl_splay(i, t);
+    if(compare(i, t->key)==0) {
+      /* There already exists a node in the tree with the very same key. Build
+         a doubly-linked circular list of nodes. We add the new 'node' struct
+         to the end of this list. */
+
+      node->key = KEY_NOTUSED; /* we set the key in the sub node to NOTUSED
+                                  to quickly identify this node as a subnode */
+      node->samen = t;
+      node->samep = t->samep;
+      t->samep->samen = node;
+      t->samep = node;
+
+      return t; /* the root node always stays the same */
+    }
+  }
+
+  if(t == NULL) {
+    node->smaller = node->larger = NULL;
+  }
+  else if(compare(i, t->key) < 0) {
+    node->smaller = t->smaller;
+    node->larger = t;
+    t->smaller = NULL;
+
+  }
+  else {
+    node->larger = t->larger;
+    node->smaller = t;
+    t->larger = NULL;
+  }
+  node->key = i;
+
+  /* no identical nodes (yet), we are the only one in the list of nodes */
+  node->samen = node;
+  node->samep = node;
+  return node;
+}
+
+/* Finds and deletes the best-fit node from the tree. Return a pointer to the
+   resulting tree.  best-fit means the smallest node if it is not larger than
+   the key */
+struct Curl_tree *Curl_splaygetbest(struct curltime i,
+                                    struct Curl_tree *t,
+                                    struct Curl_tree **removed)
+{
+  static struct curltime tv_zero = {0, 0};
+  struct Curl_tree *x;
+
+  if(!t) {
+    *removed = NULL; /* none removed since there was no root */
+    return NULL;
+  }
+
+  /* find smallest */
+  t = Curl_splay(tv_zero, t);
+  if(compare(i, t->key) < 0) {
+    /* even the smallest is too big */
+    *removed = NULL;
+    return t;
+  }
+
+  /* FIRST! Check if there is a list with identical keys */
+  x = t->samen;
+  if(x != t) {
+    /* there is, pick one from the list */
+
+    /* 'x' is the new root node */
+
+    x->key = t->key;
+    x->larger = t->larger;
+    x->smaller = t->smaller;
+    x->samep = t->samep;
+    t->samep->samen = x;
+
+    *removed = t;
+    return x; /* new root */
+  }
+
+  /* we splayed the tree to the smallest element, there is no smaller */
+  x = t->larger;
+  *removed = t;
+
+  return x;
+}
+
+
+/* Deletes the very node we point out from the tree if it's there. Stores a
+ * pointer to the new resulting tree in 'newroot'.
+ *
+ * Returns zero on success and non-zero on errors! TODO: document error codes.
+ * When returning error, it does not touch the 'newroot' pointer.
+ *
+ * NOTE: when the last node of the tree is removed, there's no tree left so
+ * 'newroot' will be made to point to NULL.
+ *
+ * @unittest: 1309
+ */
+int Curl_splayremovebyaddr(struct Curl_tree *t,
+                           struct Curl_tree *removenode,
+                           struct Curl_tree **newroot)
+{
+  static const struct curltime KEY_NOTUSED = {
+    (time_t)-1, (unsigned int)-1
+  }; /* will *NEVER* appear */
+  struct Curl_tree *x;
+
+  if(!t || !removenode)
+    return 1;
+
+  if(compare(KEY_NOTUSED, removenode->key) == 0) {
+    /* Key set to NOTUSED means it is a subnode within a 'same' linked list
+       and thus we can unlink it easily. */
+    if(removenode->samen == removenode)
+      /* A non-subnode should never be set to KEY_NOTUSED */
+      return 3;
+
+    removenode->samep->samen = removenode->samen;
+    removenode->samen->samep = removenode->samep;
+
+    /* Ensures that double-remove gets caught. */
+    removenode->samen = removenode;
+
+    *newroot = t; /* return the same root */
+    return 0;
+  }
+
+  t = Curl_splay(removenode->key, t);
+
+  /* First make sure that we got the same root node as the one we want
+     to remove, as otherwise we might be trying to remove a node that
+     isn't actually in the tree.
+
+     We cannot just compare the keys here as a double remove in quick
+     succession of a node with key != KEY_NOTUSED && same != NULL
+     could return the same key but a different node. */
+  if(t != removenode)
+    return 2;
+
+  /* Check if there is a list with identical sizes, as then we're trying to
+     remove the root node of a list of nodes with identical keys. */
+  x = t->samen;
+  if(x != t) {
+    /* 'x' is the new root node, we just make it use the root node's
+       smaller/larger links */
+
+    x->key = t->key;
+    x->larger = t->larger;
+    x->smaller = t->smaller;
+    x->samep = t->samep;
+    t->samep->samen = x;
+  }
+  else {
+    /* Remove the root node */
+    if(t->smaller == NULL)
+      x = t->larger;
+    else {
+      x = Curl_splay(removenode->key, t->smaller);
+      x->larger = t->larger;
+    }
+  }
+
+  *newroot = x; /* store new root pointer */
+
+  return 0;
+}
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/splay.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/splay.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/splay.h	(revision 331)
@@ -0,0 +1,68 @@
+#ifndef HEADER_CURL_SPLAY_H
+#define HEADER_CURL_SPLAY_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1997 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+#include "timeval.h"
+
+struct Curl_tree {
+  struct Curl_tree *smaller; /* smaller node */
+  struct Curl_tree *larger;  /* larger node */
+  struct Curl_tree *samen;   /* points to the next node with identical key */
+  struct Curl_tree *samep;   /* points to the prev node with identical key */
+  struct curltime key;        /* this node's "sort" key */
+  void *payload;             /* data the splay code doesn't care about */
+};
+
+struct Curl_tree *Curl_splay(struct curltime i,
+                             struct Curl_tree *t);
+
+struct Curl_tree *Curl_splayinsert(struct curltime key,
+                                   struct Curl_tree *t,
+                                   struct Curl_tree *newnode);
+
+#if 0
+struct Curl_tree *Curl_splayremove(struct curltime key,
+                                   struct Curl_tree *t,
+                                   struct Curl_tree **removed);
+#endif
+
+struct Curl_tree *Curl_splaygetbest(struct curltime key,
+                                    struct Curl_tree *t,
+                                    struct Curl_tree **removed);
+
+int Curl_splayremovebyaddr(struct Curl_tree *t,
+                           struct Curl_tree *removenode,
+                           struct Curl_tree **newroot);
+
+#define Curl_splaycomparekeys(i,j) ( ((i.tv_sec)  < (j.tv_sec))  ? -1 : \
+                                   ( ((i.tv_sec)  > (j.tv_sec))  ?  1 : \
+                                   ( ((i.tv_usec) < (j.tv_usec)) ? -1 : \
+                                   ( ((i.tv_usec) > (j.tv_usec)) ?  1 : 0))))
+
+#ifdef DEBUGBUILD
+void Curl_splayprint(struct Curl_tree * t, int d, char output);
+#else
+#define Curl_splayprint(x,y,z) Curl_nop_stmt
+#endif
+
+#endif /* HEADER_CURL_SPLAY_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/ssh.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/ssh.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/ssh.c	(revision 331)
@@ -0,0 +1,3463 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* #define CURL_LIBSSH2_DEBUG */
+
+#include "curl_setup.h"
+
+#ifdef USE_LIBSSH2
+
+#ifdef HAVE_LIMITS_H
+#  include <limits.h>
+#endif
+
+#include <libssh2.h>
+#include <libssh2_sftp.h>
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
+#undef in_addr_t
+#define in_addr_t unsigned long
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "hostip.h"
+#include "progress.h"
+#include "transfer.h"
+#include "escape.h"
+#include "http.h" /* for HTTP proxy tunnel stuff */
+#include "ssh.h"
+#include "url.h"
+#include "speedcheck.h"
+#include "getinfo.h"
+#include "strdup.h"
+#include "strcase.h"
+#include "vtls/vtls.h"
+#include "connect.h"
+#include "strerror.h"
+#include "inet_ntop.h"
+#include "parsedate.h" /* for the week day and month names */
+#include "sockaddr.h" /* required for Curl_sockaddr_storage */
+#include "strtoofft.h"
+#include "multiif.h"
+#include "select.h"
+#include "warnless.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifdef WIN32
+#  undef  PATH_MAX
+#  define PATH_MAX MAX_PATH
+#  ifndef R_OK
+#    define R_OK 4
+#  endif
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024 /* just an extra precaution since there are systems that
+                         have their definition hidden well */
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010206
+/* libssh2_sftp_statvfs and friends were added in 1.2.6 */
+#define HAS_STATVFS_SUPPORT 1
+#endif
+
+#define sftp_libssh2_last_error(s) curlx_ultosi(libssh2_sftp_last_error(s))
+
+#define sftp_libssh2_realpath(s,p,t,m) \
+        libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
+                                (t), (m), LIBSSH2_SFTP_REALPATH)
+
+
+/* Local functions: */
+static const char *sftp_libssh2_strerror(int err);
+static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
+static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
+static LIBSSH2_FREE_FUNC(my_libssh2_free);
+
+static CURLcode get_pathname(const char **cpp, char **path);
+
+static CURLcode ssh_connect(struct connectdata *conn, bool *done);
+static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
+static CURLcode ssh_do(struct connectdata *conn, bool *done);
+
+static CURLcode ssh_getworkingpath(struct connectdata *conn,
+                                   char *homedir, /* when SFTP is used */
+                                   char **path);
+
+static CURLcode scp_done(struct connectdata *conn,
+                         CURLcode, bool premature);
+static CURLcode scp_doing(struct connectdata *conn,
+                          bool *dophase_done);
+static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection);
+
+static CURLcode sftp_done(struct connectdata *conn,
+                          CURLcode, bool premature);
+static CURLcode sftp_doing(struct connectdata *conn,
+                           bool *dophase_done);
+static CURLcode sftp_disconnect(struct connectdata *conn, bool dead);
+static
+CURLcode sftp_perform(struct connectdata *conn,
+                      bool *connected,
+                      bool *dophase_done);
+
+static int ssh_getsock(struct connectdata *conn,
+                       curl_socket_t *sock, /* points to numsocks number
+                                               of sockets */
+                       int numsocks);
+
+static int ssh_perform_getsock(const struct connectdata *conn,
+                               curl_socket_t *sock, /* points to numsocks
+                                                       number of sockets */
+                               int numsocks);
+
+static CURLcode ssh_setup_connection(struct connectdata *conn);
+
+/*
+ * SCP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_scp = {
+  "SCP",                                /* scheme */
+  ssh_setup_connection,                 /* setup_connection */
+  ssh_do,                               /* do_it */
+  scp_done,                             /* done */
+  ZERO_NULL,                            /* do_more */
+  ssh_connect,                          /* connect_it */
+  ssh_multi_statemach,                  /* connecting */
+  scp_doing,                            /* doing */
+  ssh_getsock,                          /* proto_getsock */
+  ssh_getsock,                          /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ssh_perform_getsock,                  /* perform_getsock */
+  scp_disconnect,                       /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_SSH,                             /* defport */
+  CURLPROTO_SCP,                        /* protocol */
+  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
+  | PROTOPT_NOURLQUERY                  /* flags */
+};
+
+
+/*
+ * SFTP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_sftp = {
+  "SFTP",                               /* scheme */
+  ssh_setup_connection,                 /* setup_connection */
+  ssh_do,                               /* do_it */
+  sftp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  ssh_connect,                          /* connect_it */
+  ssh_multi_statemach,                  /* connecting */
+  sftp_doing,                           /* doing */
+  ssh_getsock,                          /* proto_getsock */
+  ssh_getsock,                          /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ssh_perform_getsock,                  /* perform_getsock */
+  sftp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_SSH,                             /* defport */
+  CURLPROTO_SFTP,                       /* protocol */
+  PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
+  | PROTOPT_NOURLQUERY                  /* flags */
+};
+
+static void
+kbd_callback(const char *name, int name_len, const char *instruction,
+             int instruction_len, int num_prompts,
+             const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
+             LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
+             void **abstract)
+{
+  struct connectdata *conn = (struct connectdata *)*abstract;
+
+#ifdef CURL_LIBSSH2_DEBUG
+  fprintf(stderr, "name=%s\n", name);
+  fprintf(stderr, "name_len=%d\n", name_len);
+  fprintf(stderr, "instruction=%s\n", instruction);
+  fprintf(stderr, "instruction_len=%d\n", instruction_len);
+  fprintf(stderr, "num_prompts=%d\n", num_prompts);
+#else
+  (void)name;
+  (void)name_len;
+  (void)instruction;
+  (void)instruction_len;
+#endif  /* CURL_LIBSSH2_DEBUG */
+  if(num_prompts == 1) {
+    responses[0].text = strdup(conn->passwd);
+    responses[0].length = curlx_uztoui(strlen(conn->passwd));
+  }
+  (void)prompts;
+  (void)abstract;
+} /* kbd_callback */
+
+static CURLcode sftp_libssh2_error_to_CURLE(int err)
+{
+  switch(err) {
+    case LIBSSH2_FX_OK:
+      return CURLE_OK;
+
+    case LIBSSH2_FX_NO_SUCH_FILE:
+    case LIBSSH2_FX_NO_SUCH_PATH:
+      return CURLE_REMOTE_FILE_NOT_FOUND;
+
+    case LIBSSH2_FX_PERMISSION_DENIED:
+    case LIBSSH2_FX_WRITE_PROTECT:
+    case LIBSSH2_FX_LOCK_CONFlICT:
+      return CURLE_REMOTE_ACCESS_DENIED;
+
+    case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
+    case LIBSSH2_FX_QUOTA_EXCEEDED:
+      return CURLE_REMOTE_DISK_FULL;
+
+    case LIBSSH2_FX_FILE_ALREADY_EXISTS:
+      return CURLE_REMOTE_FILE_EXISTS;
+
+    case LIBSSH2_FX_DIR_NOT_EMPTY:
+      return CURLE_QUOTE_ERROR;
+
+    default:
+      break;
+  }
+
+  return CURLE_SSH;
+}
+
+static CURLcode libssh2_session_error_to_CURLE(int err)
+{
+  switch(err) {
+    /* Ordered by order of appearance in libssh2.h */
+    case LIBSSH2_ERROR_NONE:
+      return CURLE_OK;
+
+    case LIBSSH2_ERROR_SOCKET_NONE:
+      return CURLE_COULDNT_CONNECT;
+
+    case LIBSSH2_ERROR_ALLOC:
+      return CURLE_OUT_OF_MEMORY;
+
+    case LIBSSH2_ERROR_SOCKET_SEND:
+      return CURLE_SEND_ERROR;
+
+    case LIBSSH2_ERROR_HOSTKEY_INIT:
+    case LIBSSH2_ERROR_HOSTKEY_SIGN:
+    case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
+    case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
+      return CURLE_PEER_FAILED_VERIFICATION;
+
+    case LIBSSH2_ERROR_PASSWORD_EXPIRED:
+      return CURLE_LOGIN_DENIED;
+
+    case LIBSSH2_ERROR_SOCKET_TIMEOUT:
+    case LIBSSH2_ERROR_TIMEOUT:
+      return CURLE_OPERATION_TIMEDOUT;
+
+    case LIBSSH2_ERROR_EAGAIN:
+      return CURLE_AGAIN;
+  }
+
+  /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
+     error code, and possibly add a few new SSH-related one. We must however
+     not return or even depend on libssh2 errors in the public libcurl API */
+
+  return CURLE_SSH;
+}
+
+static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
+{
+  (void)abstract; /* arg not used */
+  return malloc(count);
+}
+
+static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
+{
+  (void)abstract; /* arg not used */
+  return realloc(ptr, count);
+}
+
+static LIBSSH2_FREE_FUNC(my_libssh2_free)
+{
+  (void)abstract; /* arg not used */
+  if(ptr) /* ssh2 agent sometimes call free with null ptr */
+    free(ptr);
+}
+
+/*
+ * SSH State machine related code
+ */
+/* This is the ONLY way to change SSH state! */
+static void state(struct connectdata *conn, sshstate nowstate)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
+  /* for debug purposes */
+  static const char * const names[] = {
+    "SSH_STOP",
+    "SSH_INIT",
+    "SSH_S_STARTUP",
+    "SSH_HOSTKEY",
+    "SSH_AUTHLIST",
+    "SSH_AUTH_PKEY_INIT",
+    "SSH_AUTH_PKEY",
+    "SSH_AUTH_PASS_INIT",
+    "SSH_AUTH_PASS",
+    "SSH_AUTH_AGENT_INIT",
+    "SSH_AUTH_AGENT_LIST",
+    "SSH_AUTH_AGENT",
+    "SSH_AUTH_HOST_INIT",
+    "SSH_AUTH_HOST",
+    "SSH_AUTH_KEY_INIT",
+    "SSH_AUTH_KEY",
+    "SSH_AUTH_DONE",
+    "SSH_SFTP_INIT",
+    "SSH_SFTP_REALPATH",
+    "SSH_SFTP_QUOTE_INIT",
+    "SSH_SFTP_POSTQUOTE_INIT",
+    "SSH_SFTP_QUOTE",
+    "SSH_SFTP_NEXT_QUOTE",
+    "SSH_SFTP_QUOTE_STAT",
+    "SSH_SFTP_QUOTE_SETSTAT",
+    "SSH_SFTP_QUOTE_SYMLINK",
+    "SSH_SFTP_QUOTE_MKDIR",
+    "SSH_SFTP_QUOTE_RENAME",
+    "SSH_SFTP_QUOTE_RMDIR",
+    "SSH_SFTP_QUOTE_UNLINK",
+    "SSH_SFTP_QUOTE_STATVFS",
+    "SSH_SFTP_GETINFO",
+    "SSH_SFTP_FILETIME",
+    "SSH_SFTP_TRANS_INIT",
+    "SSH_SFTP_UPLOAD_INIT",
+    "SSH_SFTP_CREATE_DIRS_INIT",
+    "SSH_SFTP_CREATE_DIRS",
+    "SSH_SFTP_CREATE_DIRS_MKDIR",
+    "SSH_SFTP_READDIR_INIT",
+    "SSH_SFTP_READDIR",
+    "SSH_SFTP_READDIR_LINK",
+    "SSH_SFTP_READDIR_BOTTOM",
+    "SSH_SFTP_READDIR_DONE",
+    "SSH_SFTP_DOWNLOAD_INIT",
+    "SSH_SFTP_DOWNLOAD_STAT",
+    "SSH_SFTP_CLOSE",
+    "SSH_SFTP_SHUTDOWN",
+    "SSH_SCP_TRANS_INIT",
+    "SSH_SCP_UPLOAD_INIT",
+    "SSH_SCP_DOWNLOAD_INIT",
+    "SSH_SCP_DONE",
+    "SSH_SCP_SEND_EOF",
+    "SSH_SCP_WAIT_EOF",
+    "SSH_SCP_WAIT_CLOSE",
+    "SSH_SCP_CHANNEL_FREE",
+    "SSH_SESSION_DISCONNECT",
+    "SSH_SESSION_FREE",
+    "QUIT"
+  };
+
+  if(sshc->state != nowstate) {
+    infof(conn->data, "SFTP %p state change from %s to %s\n",
+          (void *)sshc, names[sshc->state], names[nowstate]);
+  }
+#endif
+
+  sshc->state = nowstate;
+}
+
+/* figure out the path to work with in this particular request */
+static CURLcode ssh_getworkingpath(struct connectdata *conn,
+                                   char *homedir,  /* when SFTP is used */
+                                   char **path) /* returns the  allocated
+                                                   real path to work with */
+{
+  struct Curl_easy *data = conn->data;
+  char *real_path = NULL;
+  char *working_path;
+  size_t working_path_len;
+  CURLcode result =
+    Curl_urldecode(data, data->state.path, 0, &working_path,
+                   &working_path_len, FALSE);
+  if(result)
+    return result;
+
+  /* Check for /~/, indicating relative to the user's home directory */
+  if(conn->handler->protocol & CURLPROTO_SCP) {
+    real_path = malloc(working_path_len + 1);
+    if(real_path == NULL) {
+      free(working_path);
+      return CURLE_OUT_OF_MEMORY;
+    }
+    if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3)))
+      /* It is referenced to the home directory, so strip the leading '/~/' */
+      memcpy(real_path, working_path + 3, 4 + working_path_len-3);
+    else
+      memcpy(real_path, working_path, 1 + working_path_len);
+  }
+  else if(conn->handler->protocol & CURLPROTO_SFTP) {
+    if((working_path_len > 1) && (working_path[1] == '~')) {
+      size_t homelen = strlen(homedir);
+      real_path = malloc(homelen + working_path_len + 1);
+      if(real_path == NULL) {
+        free(working_path);
+        return CURLE_OUT_OF_MEMORY;
+      }
+      /* It is referenced to the home directory, so strip the
+         leading '/' */
+      memcpy(real_path, homedir, homelen);
+      real_path[homelen] = '/';
+      real_path[homelen + 1] = '\0';
+      if(working_path_len > 3) {
+        memcpy(real_path + homelen + 1, working_path + 3,
+               1 + working_path_len -3);
+      }
+    }
+    else {
+      real_path = malloc(working_path_len + 1);
+      if(real_path == NULL) {
+        free(working_path);
+        return CURLE_OUT_OF_MEMORY;
+      }
+      memcpy(real_path, working_path, 1 + working_path_len);
+    }
+  }
+
+  free(working_path);
+
+  /* store the pointer for the caller to receive */
+  *path = real_path;
+
+  return CURLE_OK;
+}
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+static int sshkeycallback(struct Curl_easy *easy,
+                          const struct curl_khkey *knownkey, /* known */
+                          const struct curl_khkey *foundkey, /* found */
+                          enum curl_khmatch match,
+                          void *clientp)
+{
+  (void)easy;
+  (void)knownkey;
+  (void)foundkey;
+  (void)clientp;
+
+  /* we only allow perfect matches, and we reject everything else */
+  return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE;
+}
+#endif
+
+/*
+ * Earlier libssh2 versions didn't have the ability to seek to 64bit positions
+ * with 32bit size_t.
+ */
+#ifdef HAVE_LIBSSH2_SFTP_SEEK64
+#define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
+#else
+#define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
+#endif
+
+/*
+ * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit
+ * architectures so we check of the necessary function is present.
+ */
+#ifndef HAVE_LIBSSH2_SCP_SEND64
+#define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
+#else
+#define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c),            \
+                                             (libssh2_uint64_t)d, 0, 0)
+#endif
+
+/*
+ * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64.
+ */
+#ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
+#define libssh2_session_startup(x,y) libssh2_session_handshake(x,y)
+#endif
+
+static CURLcode ssh_knownhost(struct connectdata *conn)
+{
+  CURLcode result = CURLE_OK;
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+  struct Curl_easy *data = conn->data;
+
+  if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
+    /* we're asked to verify the host against a file */
+    struct ssh_conn *sshc = &conn->proto.sshc;
+    int rc;
+    int keytype;
+    size_t keylen;
+    const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
+                                                    &keylen, &keytype);
+    int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
+    int keybit = 0;
+
+    if(remotekey) {
+      /*
+       * A subject to figure out is what host name we need to pass in here.
+       * What host name does OpenSSH store in its file if an IDN name is
+       * used?
+       */
+      struct libssh2_knownhost *host;
+      enum curl_khmatch keymatch;
+      curl_sshkeycallback func =
+        data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback;
+      struct curl_khkey knownkey;
+      struct curl_khkey *knownkeyp = NULL;
+      struct curl_khkey foundkey;
+
+      keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
+        LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS;
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP
+      keycheck = libssh2_knownhost_checkp(sshc->kh,
+                                          conn->host.name,
+                                          (conn->remote_port != PORT_SSH)?
+                                          conn->remote_port:-1,
+                                          remotekey, keylen,
+                                          LIBSSH2_KNOWNHOST_TYPE_PLAIN|
+                                          LIBSSH2_KNOWNHOST_KEYENC_RAW|
+                                          keybit,
+                                          &host);
+#else
+      keycheck = libssh2_knownhost_check(sshc->kh,
+                                         conn->host.name,
+                                         remotekey, keylen,
+                                         LIBSSH2_KNOWNHOST_TYPE_PLAIN|
+                                         LIBSSH2_KNOWNHOST_KEYENC_RAW|
+                                         keybit,
+                                         &host);
+#endif
+
+      infof(data, "SSH host check: %d, key: %s\n", keycheck,
+            (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)?
+            host->key:"<none>");
+
+      /* setup 'knownkey' */
+      if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
+        knownkey.key = host->key;
+        knownkey.len = 0;
+        knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
+          CURLKHTYPE_RSA : CURLKHTYPE_DSS;
+        knownkeyp = &knownkey;
+      }
+
+      /* setup 'foundkey' */
+      foundkey.key = remotekey;
+      foundkey.len = keylen;
+      foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)?
+        CURLKHTYPE_RSA : CURLKHTYPE_DSS;
+
+      /*
+       * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
+       * curl_khmatch enum are ever modified, we need to introduce a
+       * translation table here!
+       */
+      keymatch = (enum curl_khmatch)keycheck;
+
+      /* Ask the callback how to behave */
+      rc = func(data, knownkeyp, /* from the knownhosts file */
+                &foundkey, /* from the remote host */
+                keymatch, data->set.ssh_keyfunc_userp);
+    }
+    else
+      /* no remotekey means failure! */
+      rc = CURLKHSTAT_REJECT;
+
+    switch(rc) {
+    default: /* unknown return codes will equal reject */
+      /* FALLTHROUGH */
+    case CURLKHSTAT_REJECT:
+      state(conn, SSH_SESSION_FREE);
+      /* FALLTHROUGH */
+    case CURLKHSTAT_DEFER:
+      /* DEFER means bail out but keep the SSH_HOSTKEY state */
+      result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
+      break;
+    case CURLKHSTAT_FINE:
+    case CURLKHSTAT_FINE_ADD_TO_FILE:
+      /* proceed */
+      if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
+        /* the found host+key didn't match but has been told to be fine
+           anyway so we add it in memory */
+        int addrc = libssh2_knownhost_add(sshc->kh,
+                                          conn->host.name, NULL,
+                                          remotekey, keylen,
+                                          LIBSSH2_KNOWNHOST_TYPE_PLAIN|
+                                          LIBSSH2_KNOWNHOST_KEYENC_RAW|
+                                          keybit, NULL);
+        if(addrc)
+          infof(data, "Warning adding the known host %s failed!\n",
+                conn->host.name);
+        else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) {
+          /* now we write the entire in-memory list of known hosts to the
+             known_hosts file */
+          int wrc =
+            libssh2_knownhost_writefile(sshc->kh,
+                                        data->set.str[STRING_SSH_KNOWNHOSTS],
+                                        LIBSSH2_KNOWNHOST_FILE_OPENSSH);
+          if(wrc) {
+            infof(data, "Warning, writing %s failed!\n",
+                  data->set.str[STRING_SSH_KNOWNHOSTS]);
+          }
+        }
+      }
+      break;
+    }
+  }
+#else /* HAVE_LIBSSH2_KNOWNHOST_API */
+  (void)conn;
+#endif
+  return result;
+}
+
+static CURLcode ssh_check_fingerprint(struct connectdata *conn)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  struct Curl_easy *data = conn->data;
+  const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
+  char md5buffer[33];
+  int i;
+
+  const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
+      LIBSSH2_HOSTKEY_HASH_MD5);
+
+  if(fingerprint) {
+    /* The fingerprint points to static storage (!), don't free() it. */
+    for(i = 0; i < 16; i++)
+      snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
+    infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
+  }
+
+  /* Before we authenticate we check the hostkey's MD5 fingerprint
+   * against a known fingerprint, if available.
+   */
+  if(pubkey_md5 && strlen(pubkey_md5) == 32) {
+    if(!fingerprint || !strcasecompare(md5buffer, pubkey_md5)) {
+      if(fingerprint)
+        failf(data,
+            "Denied establishing ssh session: mismatch md5 fingerprint. "
+            "Remote %s is not equal to %s", md5buffer, pubkey_md5);
+      else
+        failf(data,
+            "Denied establishing ssh session: md5 fingerprint not available");
+      state(conn, SSH_SESSION_FREE);
+      sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
+      return sshc->actualcode;
+    }
+    infof(data, "MD5 checksum match!\n");
+    /* as we already matched, we skip the check for known hosts */
+    return CURLE_OK;
+  }
+  return ssh_knownhost(conn);
+}
+
+/*
+ * ssh_statemach_act() runs the SSH state machine as far as it can without
+ * blocking and without reaching the end.  The data the pointer 'block' points
+ * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
+ * meaning it wants to be called again when the socket is ready
+ */
+
+static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct SSHPROTO *sftp_scp = data->req.protop;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  curl_socket_t sock = conn->sock[FIRSTSOCKET];
+  char *new_readdir_line;
+  int rc = LIBSSH2_ERROR_NONE;
+  int err;
+  int seekerr = CURL_SEEKFUNC_OK;
+  *block = 0; /* we're not blocking by default */
+
+  do {
+
+    switch(sshc->state) {
+    case SSH_INIT:
+      sshc->secondCreateDirs = 0;
+      sshc->nextstate = SSH_NO_STATE;
+      sshc->actualcode = CURLE_OK;
+
+      /* Set libssh2 to non-blocking, since everything internally is
+         non-blocking */
+      libssh2_session_set_blocking(sshc->ssh_session, 0);
+
+      state(conn, SSH_S_STARTUP);
+      /* fall-through */
+
+    case SSH_S_STARTUP:
+      rc = libssh2_session_startup(sshc->ssh_session, (int)sock);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc) {
+        failf(data, "Failure establishing ssh session");
+        state(conn, SSH_SESSION_FREE);
+        sshc->actualcode = CURLE_FAILED_INIT;
+        break;
+      }
+
+      state(conn, SSH_HOSTKEY);
+
+      /* fall-through */
+    case SSH_HOSTKEY:
+      /*
+       * Before we authenticate we should check the hostkey's fingerprint
+       * against our known hosts. How that is handled (reading from file,
+       * whatever) is up to us.
+       */
+      result = ssh_check_fingerprint(conn);
+      if(!result)
+        state(conn, SSH_AUTHLIST);
+      /* ssh_check_fingerprint sets state appropriately on error */
+      break;
+
+    case SSH_AUTHLIST:
+      /*
+       * Figure out authentication methods
+       * NB: As soon as we have provided a username to an openssh server we
+       * must never change it later. Thus, always specify the correct username
+       * here, even though the libssh2 docs kind of indicate that it should be
+       * possible to get a 'generic' list (not user-specific) of authentication
+       * methods, presumably with a blank username. That won't work in my
+       * experience.
+       * So always specify it here.
+       */
+      sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
+                                             conn->user,
+                                             curlx_uztoui(strlen(conn->user)));
+
+      if(!sshc->authlist) {
+        if(libssh2_userauth_authenticated(sshc->ssh_session)) {
+          sshc->authed = TRUE;
+          infof(data, "SSH user accepted with no authentication\n");
+          state(conn, SSH_AUTH_DONE);
+          break;
+        }
+        err = libssh2_session_last_errno(sshc->ssh_session);
+        if(err == LIBSSH2_ERROR_EAGAIN)
+          rc = LIBSSH2_ERROR_EAGAIN;
+        else {
+          state(conn, SSH_SESSION_FREE);
+          sshc->actualcode = libssh2_session_error_to_CURLE(err);
+        }
+        break;
+      }
+      infof(data, "SSH authentication methods available: %s\n",
+            sshc->authlist);
+
+      state(conn, SSH_AUTH_PKEY_INIT);
+      break;
+
+    case SSH_AUTH_PKEY_INIT:
+      /*
+       * Check the supported auth types in the order I feel is most secure
+       * with the requested type of authentication
+       */
+      sshc->authed = FALSE;
+
+      if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
+         (strstr(sshc->authlist, "publickey") != NULL)) {
+        char *home = NULL;
+        bool out_of_memory = FALSE;
+
+        sshc->rsa_pub = sshc->rsa = NULL;
+
+        /* To ponder about: should really the lib be messing about with the
+           HOME environment variable etc? */
+        home = curl_getenv("HOME");
+
+        if(data->set.str[STRING_SSH_PRIVATE_KEY])
+          sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]);
+        else {
+          /* If no private key file is specified, try some common paths. */
+          if(home) {
+            /* Try ~/.ssh first. */
+            sshc->rsa = aprintf("%s/.ssh/id_rsa", home);
+            if(!sshc->rsa)
+              out_of_memory = TRUE;
+            else if(access(sshc->rsa, R_OK) != 0) {
+              Curl_safefree(sshc->rsa);
+              sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
+              if(!sshc->rsa)
+                out_of_memory = TRUE;
+              else if(access(sshc->rsa, R_OK) != 0) {
+                Curl_safefree(sshc->rsa);
+              }
+            }
+          }
+          if(!out_of_memory && !sshc->rsa) {
+            /* Nothing found; try the current dir. */
+            sshc->rsa = strdup("id_rsa");
+            if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
+              Curl_safefree(sshc->rsa);
+              sshc->rsa = strdup("id_dsa");
+              if(sshc->rsa && access(sshc->rsa, R_OK) != 0) {
+                Curl_safefree(sshc->rsa);
+                /* Out of guesses. Set to the empty string to avoid
+                 * surprising info messages. */
+                sshc->rsa = strdup("");
+              }
+            }
+          }
+        }
+
+        /*
+         * Unless the user explicitly specifies a public key file, let
+         * libssh2 extract the public key from the private key file.
+         * This is done by simply passing sshc->rsa_pub = NULL.
+         */
+        if(data->set.str[STRING_SSH_PUBLIC_KEY]
+            /* treat empty string the same way as NULL */
+            && data->set.str[STRING_SSH_PUBLIC_KEY][0]) {
+          sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
+          if(!sshc->rsa_pub)
+            out_of_memory = TRUE;
+        }
+
+        if(out_of_memory || sshc->rsa == NULL) {
+          free(home);
+          Curl_safefree(sshc->rsa);
+          Curl_safefree(sshc->rsa_pub);
+          state(conn, SSH_SESSION_FREE);
+          sshc->actualcode = CURLE_OUT_OF_MEMORY;
+          break;
+        }
+
+        sshc->passphrase = data->set.ssl.key_passwd;
+        if(!sshc->passphrase)
+          sshc->passphrase = "";
+
+        free(home);
+
+        if(sshc->rsa_pub)
+          infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub);
+        infof(data, "Using SSH private key file '%s'\n", sshc->rsa);
+
+        state(conn, SSH_AUTH_PKEY);
+      }
+      else {
+        state(conn, SSH_AUTH_PASS_INIT);
+      }
+      break;
+
+    case SSH_AUTH_PKEY:
+      /* The function below checks if the files exists, no need to stat() here.
+       */
+      rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
+                                                  conn->user,
+                                                  curlx_uztoui(
+                                                    strlen(conn->user)),
+                                                  sshc->rsa_pub,
+                                                  sshc->rsa, sshc->passphrase);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+
+      Curl_safefree(sshc->rsa_pub);
+      Curl_safefree(sshc->rsa);
+
+      if(rc == 0) {
+        sshc->authed = TRUE;
+        infof(data, "Initialized SSH public key authentication\n");
+        state(conn, SSH_AUTH_DONE);
+      }
+      else {
+        char *err_msg;
+        (void)libssh2_session_last_error(sshc->ssh_session,
+                                         &err_msg, NULL, 0);
+        infof(data, "SSH public key authentication failed: %s\n", err_msg);
+        state(conn, SSH_AUTH_PASS_INIT);
+        rc = 0; /* clear rc and continue */
+      }
+      break;
+
+    case SSH_AUTH_PASS_INIT:
+      if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
+         (strstr(sshc->authlist, "password") != NULL)) {
+        state(conn, SSH_AUTH_PASS);
+      }
+      else {
+        state(conn, SSH_AUTH_HOST_INIT);
+        rc = 0; /* clear rc and continue */
+      }
+      break;
+
+    case SSH_AUTH_PASS:
+      rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
+                                        curlx_uztoui(strlen(conn->user)),
+                                        conn->passwd,
+                                        curlx_uztoui(strlen(conn->passwd)),
+                                        NULL);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc == 0) {
+        sshc->authed = TRUE;
+        infof(data, "Initialized password authentication\n");
+        state(conn, SSH_AUTH_DONE);
+      }
+      else {
+        state(conn, SSH_AUTH_HOST_INIT);
+        rc = 0; /* clear rc and continue */
+      }
+      break;
+
+    case SSH_AUTH_HOST_INIT:
+      if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
+         (strstr(sshc->authlist, "hostbased") != NULL)) {
+        state(conn, SSH_AUTH_HOST);
+      }
+      else {
+        state(conn, SSH_AUTH_AGENT_INIT);
+      }
+      break;
+
+    case SSH_AUTH_HOST:
+      state(conn, SSH_AUTH_AGENT_INIT);
+      break;
+
+    case SSH_AUTH_AGENT_INIT:
+#ifdef HAVE_LIBSSH2_AGENT_API
+      if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
+         && (strstr(sshc->authlist, "publickey") != NULL)) {
+
+        /* Connect to the ssh-agent */
+        /* The agent could be shared by a curl thread i believe
+           but nothing obvious as keys can be added/removed at any time */
+        if(!sshc->ssh_agent) {
+          sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
+          if(!sshc->ssh_agent) {
+            infof(data, "Could not create agent object\n");
+
+            state(conn, SSH_AUTH_KEY_INIT);
+            break;
+          }
+        }
+
+        rc = libssh2_agent_connect(sshc->ssh_agent);
+        if(rc == LIBSSH2_ERROR_EAGAIN)
+          break;
+        if(rc < 0) {
+          infof(data, "Failure connecting to agent\n");
+          state(conn, SSH_AUTH_KEY_INIT);
+          rc = 0; /* clear rc and continue */
+        }
+        else {
+          state(conn, SSH_AUTH_AGENT_LIST);
+        }
+      }
+      else
+#endif /* HAVE_LIBSSH2_AGENT_API */
+        state(conn, SSH_AUTH_KEY_INIT);
+      break;
+
+    case SSH_AUTH_AGENT_LIST:
+#ifdef HAVE_LIBSSH2_AGENT_API
+      rc = libssh2_agent_list_identities(sshc->ssh_agent);
+
+      if(rc == LIBSSH2_ERROR_EAGAIN)
+        break;
+      if(rc < 0) {
+        infof(data, "Failure requesting identities to agent\n");
+        state(conn, SSH_AUTH_KEY_INIT);
+        rc = 0; /* clear rc and continue */
+      }
+      else {
+        state(conn, SSH_AUTH_AGENT);
+        sshc->sshagent_prev_identity = NULL;
+      }
+#endif
+      break;
+
+    case SSH_AUTH_AGENT:
+#ifdef HAVE_LIBSSH2_AGENT_API
+      /* as prev_identity evolves only after an identity user auth finished we
+         can safely request it again as long as EAGAIN is returned here or by
+         libssh2_agent_userauth */
+      rc = libssh2_agent_get_identity(sshc->ssh_agent,
+                                      &sshc->sshagent_identity,
+                                      sshc->sshagent_prev_identity);
+      if(rc == LIBSSH2_ERROR_EAGAIN)
+        break;
+
+      if(rc == 0) {
+        rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
+                                    sshc->sshagent_identity);
+
+        if(rc < 0) {
+          if(rc != LIBSSH2_ERROR_EAGAIN)
+            /* tried and failed? go to next identity */
+            sshc->sshagent_prev_identity = sshc->sshagent_identity;
+          else
+            break;
+        }
+      }
+
+      if(rc < 0)
+        infof(data, "Failure requesting identities to agent\n");
+      else if(rc == 1)
+        infof(data, "No identity would match\n");
+
+      if(rc == LIBSSH2_ERROR_NONE) {
+        sshc->authed = TRUE;
+        infof(data, "Agent based authentication successful\n");
+        state(conn, SSH_AUTH_DONE);
+      }
+      else {
+        state(conn, SSH_AUTH_KEY_INIT);
+        rc = 0; /* clear rc and continue */
+      }
+#endif
+      break;
+
+    case SSH_AUTH_KEY_INIT:
+      if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
+         && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
+        state(conn, SSH_AUTH_KEY);
+      }
+      else {
+        state(conn, SSH_AUTH_DONE);
+      }
+      break;
+
+    case SSH_AUTH_KEY:
+      /* Authentication failed. Continue with keyboard-interactive now. */
+      rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
+                                                    conn->user,
+                                                    curlx_uztoui(
+                                                      strlen(conn->user)),
+                                                    &kbd_callback);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc == 0) {
+        sshc->authed = TRUE;
+        infof(data, "Initialized keyboard interactive authentication\n");
+      }
+      state(conn, SSH_AUTH_DONE);
+      break;
+
+    case SSH_AUTH_DONE:
+      if(!sshc->authed) {
+        failf(data, "Authentication failure");
+        state(conn, SSH_SESSION_FREE);
+        sshc->actualcode = CURLE_LOGIN_DENIED;
+        break;
+      }
+
+      /*
+       * At this point we have an authenticated ssh session.
+       */
+      infof(data, "Authentication complete\n");
+
+      Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
+
+      conn->sockfd = sock;
+      conn->writesockfd = CURL_SOCKET_BAD;
+
+      if(conn->handler->protocol == CURLPROTO_SFTP) {
+        state(conn, SSH_SFTP_INIT);
+        break;
+      }
+      infof(data, "SSH CONNECT phase done\n");
+      state(conn, SSH_STOP);
+      break;
+
+    case SSH_SFTP_INIT:
+      /*
+       * Start the libssh2 sftp session
+       */
+      sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
+      if(!sshc->sftp_session) {
+        char *err_msg;
+        if(libssh2_session_last_errno(sshc->ssh_session) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+
+        (void)libssh2_session_last_error(sshc->ssh_session,
+                                         &err_msg, NULL, 0);
+        failf(data, "Failure initializing sftp session: %s", err_msg);
+        state(conn, SSH_SESSION_FREE);
+        sshc->actualcode = CURLE_FAILED_INIT;
+        break;
+      }
+      state(conn, SSH_SFTP_REALPATH);
+      break;
+
+    case SSH_SFTP_REALPATH:
+    {
+      char tempHome[PATH_MAX];
+
+      /*
+       * Get the "home" directory
+       */
+      rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
+                                 tempHome, PATH_MAX-1);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc > 0) {
+        /* It seems that this string is not always NULL terminated */
+        tempHome[rc] = '\0';
+        sshc->homedir = strdup(tempHome);
+        if(!sshc->homedir) {
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->actualcode = CURLE_OUT_OF_MEMORY;
+          break;
+        }
+        conn->data->state.most_recent_ftp_entrypath = sshc->homedir;
+      }
+      else {
+        /* Return the error type */
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        if(err)
+          result = sftp_libssh2_error_to_CURLE(err);
+        else
+          /* in this case, the error wasn't in the SFTP level but for example
+             a time-out or similar */
+          result = CURLE_SSH;
+        sshc->actualcode = result;
+        DEBUGF(infof(data, "error = %d makes libcurl = %d\n",
+                     err, (int)result));
+        state(conn, SSH_STOP);
+        break;
+      }
+    }
+    /* This is the last step in the SFTP connect phase. Do note that while
+       we get the homedir here, we get the "workingpath" in the DO action
+       since the homedir will remain the same between request but the
+       working path will not. */
+    DEBUGF(infof(data, "SSH CONNECT phase done\n"));
+    state(conn, SSH_STOP);
+    break;
+
+    case SSH_SFTP_QUOTE_INIT:
+
+      result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
+      if(result) {
+        sshc->actualcode = result;
+        state(conn, SSH_STOP);
+        break;
+      }
+
+      if(data->set.quote) {
+        infof(data, "Sending quote commands\n");
+        sshc->quote_item = data->set.quote;
+        state(conn, SSH_SFTP_QUOTE);
+      }
+      else {
+        state(conn, SSH_SFTP_GETINFO);
+      }
+      break;
+
+    case SSH_SFTP_POSTQUOTE_INIT:
+      if(data->set.postquote) {
+        infof(data, "Sending quote commands\n");
+        sshc->quote_item = data->set.postquote;
+        state(conn, SSH_SFTP_QUOTE);
+      }
+      else {
+        state(conn, SSH_STOP);
+      }
+      break;
+
+    case SSH_SFTP_QUOTE:
+      /* Send any quote commands */
+    {
+      const char *cp;
+
+      /*
+       * Support some of the "FTP" commands
+       */
+      char *cmd = sshc->quote_item->data;
+      sshc->acceptfail = FALSE;
+
+      /* if a command starts with an asterisk, which a legal SFTP command never
+         can, the command will be allowed to fail without it causing any
+         aborts or cancels etc. It will cause libcurl to act as if the command
+         is successful, whatever the server reponds. */
+
+      if(cmd[0] == '*') {
+        cmd++;
+        sshc->acceptfail = TRUE;
+      }
+
+      if(strcasecompare("pwd", cmd)) {
+        /* output debug output if that is requested */
+        char *tmp = aprintf("257 \"%s\" is current directory.\n",
+                            sftp_scp->path);
+        if(!tmp) {
+          result = CURLE_OUT_OF_MEMORY;
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          break;
+        }
+        if(data->set.verbose) {
+          Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
+          Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
+        }
+        /* this sends an FTP-like "header" to the header callback so that the
+           current directory can be read very similar to how it is read when
+           using ordinary FTP. */
+        result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
+        free(tmp);
+        if(result) {
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = result;
+        }
+        else
+          state(conn, SSH_SFTP_NEXT_QUOTE);
+        break;
+      }
+      if(cmd) {
+        /*
+         * the arguments following the command must be separated from the
+         * command with a space so we can check for it unconditionally
+         */
+        cp = strchr(cmd, ' ');
+        if(cp == NULL) {
+          failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+
+        /*
+         * also, every command takes at least one argument so we get that
+         * first argument right now
+         */
+        result = get_pathname(&cp, &sshc->quote_path1);
+        if(result) {
+          if(result == CURLE_OUT_OF_MEMORY)
+            failf(data, "Out of memory");
+          else
+            failf(data, "Syntax error: Bad first parameter");
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = result;
+          break;
+        }
+
+        /*
+         * SFTP is a binary protocol, so we don't send text commands
+         * to the server. Instead, we scan for commands used by
+         * OpenSSH's sftp program and call the appropriate libssh2
+         * functions.
+         */
+        if(strncasecompare(cmd, "chgrp ", 6) ||
+           strncasecompare(cmd, "chmod ", 6) ||
+           strncasecompare(cmd, "chown ", 6) ) {
+          /* attribute change */
+
+          /* sshc->quote_path1 contains the mode to set */
+          /* get the destination */
+          result = get_pathname(&cp, &sshc->quote_path2);
+          if(result) {
+            if(result == CURLE_OUT_OF_MEMORY)
+              failf(data, "Out of memory");
+            else
+              failf(data, "Syntax error in chgrp/chmod/chown: "
+                    "Bad second parameter");
+            Curl_safefree(sshc->quote_path1);
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->nextstate = SSH_NO_STATE;
+            sshc->actualcode = result;
+            break;
+          }
+          memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
+          state(conn, SSH_SFTP_QUOTE_STAT);
+          break;
+        }
+        if(strncasecompare(cmd, "ln ", 3) ||
+                strncasecompare(cmd, "symlink ", 8)) {
+          /* symbolic linking */
+          /* sshc->quote_path1 is the source */
+          /* get the destination */
+          result = get_pathname(&cp, &sshc->quote_path2);
+          if(result) {
+            if(result == CURLE_OUT_OF_MEMORY)
+              failf(data, "Out of memory");
+            else
+              failf(data,
+                    "Syntax error in ln/symlink: Bad second parameter");
+            Curl_safefree(sshc->quote_path1);
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->nextstate = SSH_NO_STATE;
+            sshc->actualcode = result;
+            break;
+          }
+          state(conn, SSH_SFTP_QUOTE_SYMLINK);
+          break;
+        }
+        else if(strncasecompare(cmd, "mkdir ", 6)) {
+          /* create dir */
+          state(conn, SSH_SFTP_QUOTE_MKDIR);
+          break;
+        }
+        else if(strncasecompare(cmd, "rename ", 7)) {
+          /* rename file */
+          /* first param is the source path */
+          /* second param is the dest. path */
+          result = get_pathname(&cp, &sshc->quote_path2);
+          if(result) {
+            if(result == CURLE_OUT_OF_MEMORY)
+              failf(data, "Out of memory");
+            else
+              failf(data, "Syntax error in rename: Bad second parameter");
+            Curl_safefree(sshc->quote_path1);
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->nextstate = SSH_NO_STATE;
+            sshc->actualcode = result;
+            break;
+          }
+          state(conn, SSH_SFTP_QUOTE_RENAME);
+          break;
+        }
+        else if(strncasecompare(cmd, "rmdir ", 6)) {
+          /* delete dir */
+          state(conn, SSH_SFTP_QUOTE_RMDIR);
+          break;
+        }
+        else if(strncasecompare(cmd, "rm ", 3)) {
+          state(conn, SSH_SFTP_QUOTE_UNLINK);
+          break;
+        }
+#ifdef HAS_STATVFS_SUPPORT
+        else if(strncasecompare(cmd, "statvfs ", 8)) {
+          state(conn, SSH_SFTP_QUOTE_STATVFS);
+          break;
+        }
+#endif
+
+        failf(data, "Unknown SFTP command");
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+    }
+    if(!sshc->quote_item) {
+      state(conn, SSH_SFTP_GETINFO);
+    }
+    break;
+
+    case SSH_SFTP_NEXT_QUOTE:
+      Curl_safefree(sshc->quote_path1);
+      Curl_safefree(sshc->quote_path2);
+
+      sshc->quote_item = sshc->quote_item->next;
+
+      if(sshc->quote_item) {
+        state(conn, SSH_SFTP_QUOTE);
+      }
+      else {
+        if(sshc->nextstate != SSH_NO_STATE) {
+          state(conn, sshc->nextstate);
+          sshc->nextstate = SSH_NO_STATE;
+        }
+        else {
+          state(conn, SSH_SFTP_GETINFO);
+        }
+      }
+      break;
+
+    case SSH_SFTP_QUOTE_STAT:
+    {
+      char *cmd = sshc->quote_item->data;
+      sshc->acceptfail = FALSE;
+
+      /* if a command starts with an asterisk, which a legal SFTP command never
+         can, the command will be allowed to fail without it causing any
+         aborts or cancels etc. It will cause libcurl to act as if the command
+         is successful, whatever the server reponds. */
+
+      if(cmd[0] == '*') {
+        cmd++;
+        sshc->acceptfail = TRUE;
+      }
+
+      if(!strncasecompare(cmd, "chmod", 5)) {
+        /* Since chown and chgrp only set owner OR group but libssh2 wants to
+         * set them both at once, we need to obtain the current ownership
+         * first.  This takes an extra protocol round trip.
+         */
+        rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
+                                  curlx_uztoui(strlen(sshc->quote_path2)),
+                                  LIBSSH2_SFTP_STAT,
+                                  &sshc->quote_attrs);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc != 0 && !sshc->acceptfail) { /* get those attributes */
+          err = sftp_libssh2_last_error(sshc->sftp_session);
+          Curl_safefree(sshc->quote_path1);
+          Curl_safefree(sshc->quote_path2);
+          failf(data, "Attempt to get SFTP stats failed: %s",
+                sftp_libssh2_strerror(err));
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+      }
+
+      /* Now set the new attributes... */
+      if(strncasecompare(cmd, "chgrp", 5)) {
+        sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
+        sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
+        if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
+           !sshc->acceptfail) {
+          Curl_safefree(sshc->quote_path1);
+          Curl_safefree(sshc->quote_path2);
+          failf(data, "Syntax error: chgrp gid not a number");
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+      }
+      else if(strncasecompare(cmd, "chmod", 5)) {
+        sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
+        sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
+        /* permissions are octal */
+        if(sshc->quote_attrs.permissions == 0 &&
+           !ISDIGIT(sshc->quote_path1[0])) {
+          Curl_safefree(sshc->quote_path1);
+          Curl_safefree(sshc->quote_path2);
+          failf(data, "Syntax error: chmod permissions not a number");
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+      }
+      else if(strncasecompare(cmd, "chown", 5)) {
+        sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
+        sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
+        if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
+           !sshc->acceptfail) {
+          Curl_safefree(sshc->quote_path1);
+          Curl_safefree(sshc->quote_path2);
+          failf(data, "Syntax error: chown uid not a number");
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = CURLE_QUOTE_ERROR;
+          break;
+        }
+      }
+
+      /* Now send the completed structure... */
+      state(conn, SSH_SFTP_QUOTE_SETSTAT);
+      break;
+    }
+
+    case SSH_SFTP_QUOTE_SETSTAT:
+      rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
+                                curlx_uztoui(strlen(sshc->quote_path2)),
+                                LIBSSH2_SFTP_SETSTAT,
+                                &sshc->quote_attrs);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        failf(data, "Attempt to set SFTP stats failed: %s",
+              sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_SYMLINK:
+      rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
+                                   curlx_uztoui(strlen(sshc->quote_path1)),
+                                   sshc->quote_path2,
+                                   curlx_uztoui(strlen(sshc->quote_path2)),
+                                   LIBSSH2_SFTP_SYMLINK);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        failf(data, "symlink command failed: %s",
+              sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_MKDIR:
+      rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
+                                 curlx_uztoui(strlen(sshc->quote_path1)),
+                                 data->set.new_directory_perms);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_RENAME:
+      rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
+                                  curlx_uztoui(strlen(sshc->quote_path1)),
+                                  sshc->quote_path2,
+                                  curlx_uztoui(strlen(sshc->quote_path2)),
+                                  LIBSSH2_SFTP_RENAME_OVERWRITE |
+                                  LIBSSH2_SFTP_RENAME_ATOMIC |
+                                  LIBSSH2_SFTP_RENAME_NATIVE);
+
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        Curl_safefree(sshc->quote_path2);
+        failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_RMDIR:
+      rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
+                                 curlx_uztoui(strlen(sshc->quote_path1)));
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+    case SSH_SFTP_QUOTE_UNLINK:
+      rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
+                                  curlx_uztoui(strlen(sshc->quote_path1)));
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+
+#ifdef HAS_STATVFS_SUPPORT
+    case SSH_SFTP_QUOTE_STATVFS:
+    {
+      LIBSSH2_SFTP_STATVFS statvfs;
+      rc = libssh2_sftp_statvfs(sshc->sftp_session, sshc->quote_path1,
+                                curlx_uztoui(strlen(sshc->quote_path1)),
+                                &statvfs);
+
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc != 0 && !sshc->acceptfail) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        Curl_safefree(sshc->quote_path1);
+        failf(data, "statvfs command failed: %s", sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->nextstate = SSH_NO_STATE;
+        sshc->actualcode = CURLE_QUOTE_ERROR;
+        break;
+      }
+      else if(rc == 0) {
+        char *tmp = aprintf("statvfs:\n"
+                            "f_bsize: %llu\n" "f_frsize: %llu\n"
+                            "f_blocks: %llu\n" "f_bfree: %llu\n"
+                            "f_bavail: %llu\n" "f_files: %llu\n"
+                            "f_ffree: %llu\n" "f_favail: %llu\n"
+                            "f_fsid: %llu\n" "f_flag: %llu\n"
+                            "f_namemax: %llu\n",
+                            statvfs.f_bsize, statvfs.f_frsize,
+                            statvfs.f_blocks, statvfs.f_bfree,
+                            statvfs.f_bavail, statvfs.f_files,
+                            statvfs.f_ffree, statvfs.f_favail,
+                            statvfs.f_fsid, statvfs.f_flag,
+                            statvfs.f_namemax);
+        if(!tmp) {
+          result = CURLE_OUT_OF_MEMORY;
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          break;
+        }
+
+        result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp));
+        free(tmp);
+        if(result) {
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->nextstate = SSH_NO_STATE;
+          sshc->actualcode = result;
+        }
+      }
+      state(conn, SSH_SFTP_NEXT_QUOTE);
+      break;
+    }
+#endif
+    case SSH_SFTP_GETINFO:
+    {
+      if(data->set.get_filetime) {
+        state(conn, SSH_SFTP_FILETIME);
+      }
+      else {
+        state(conn, SSH_SFTP_TRANS_INIT);
+      }
+      break;
+    }
+
+    case SSH_SFTP_FILETIME:
+    {
+      LIBSSH2_SFTP_ATTRIBUTES attrs;
+
+      rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
+                                curlx_uztoui(strlen(sftp_scp->path)),
+                                LIBSSH2_SFTP_STAT, &attrs);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc == 0) {
+        data->info.filetime = (long)attrs.mtime;
+      }
+
+      state(conn, SSH_SFTP_TRANS_INIT);
+      break;
+    }
+
+    case SSH_SFTP_TRANS_INIT:
+      if(data->set.upload)
+        state(conn, SSH_SFTP_UPLOAD_INIT);
+      else {
+        if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
+          state(conn, SSH_SFTP_READDIR_INIT);
+        else
+          state(conn, SSH_SFTP_DOWNLOAD_INIT);
+      }
+      break;
+
+    case SSH_SFTP_UPLOAD_INIT:
+    {
+      unsigned long flags;
+      /*
+       * NOTE!!!  libssh2 requires that the destination path is a full path
+       *          that includes the destination file and name OR ends in a "/"
+       *          If this is not done the destination file will be named the
+       *          same name as the last directory in the path.
+       */
+
+      if(data->state.resume_from != 0) {
+        LIBSSH2_SFTP_ATTRIBUTES attrs;
+        if(data->state.resume_from < 0) {
+          rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
+                                    curlx_uztoui(strlen(sftp_scp->path)),
+                                    LIBSSH2_SFTP_STAT, &attrs);
+          if(rc == LIBSSH2_ERROR_EAGAIN) {
+            break;
+          }
+          if(rc) {
+            data->state.resume_from = 0;
+          }
+          else {
+            curl_off_t size = attrs.filesize;
+            if(size < 0) {
+              failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
+              return CURLE_BAD_DOWNLOAD_RESUME;
+            }
+            data->state.resume_from = attrs.filesize;
+          }
+        }
+      }
+
+      if(data->set.ftp_append)
+        /* Try to open for append, but create if nonexisting */
+        flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
+      else if(data->state.resume_from > 0)
+        /* If we have restart position then open for append */
+        flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
+      else
+        /* Clear file before writing (normal behaviour) */
+        flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
+
+      sshc->sftp_handle =
+        libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
+                             curlx_uztoui(strlen(sftp_scp->path)),
+                             flags, data->set.new_file_perms,
+                             LIBSSH2_SFTP_OPENFILE);
+
+      if(!sshc->sftp_handle) {
+        rc = libssh2_session_last_errno(sshc->ssh_session);
+
+        if(LIBSSH2_ERROR_EAGAIN == rc)
+          break;
+
+        if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
+          /* only when there was an SFTP protocol error can we extract
+             the sftp error! */
+          err = sftp_libssh2_last_error(sshc->sftp_session);
+        else
+          err = -1; /* not an sftp error at all */
+
+        if(sshc->secondCreateDirs) {
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->actualcode = err>= LIBSSH2_FX_OK?
+            sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
+          failf(data, "Creating the dir/file failed: %s",
+                sftp_libssh2_strerror(err));
+          break;
+        }
+        if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
+            (err == LIBSSH2_FX_FAILURE) ||
+            (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
+           (data->set.ftp_create_missing_dirs &&
+            (strlen(sftp_scp->path) > 1))) {
+          /* try to create the path remotely */
+          rc = 0; /* clear rc and continue */
+          sshc->secondCreateDirs = 1;
+          state(conn, SSH_SFTP_CREATE_DIRS_INIT);
+          break;
+        }
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = err>= LIBSSH2_FX_OK?
+          sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
+        if(!sshc->actualcode) {
+          /* Sometimes, for some reason libssh2_sftp_last_error() returns
+             zero even though libssh2_sftp_open() failed previously! We need
+             to work around that! */
+          sshc->actualcode = CURLE_SSH;
+          err = -1;
+        }
+        failf(data, "Upload failed: %s (%d/%d)",
+              err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
+              err, rc);
+        break;
+      }
+
+      /* If we have a restart point then we need to seek to the correct
+         position. */
+      if(data->state.resume_from > 0) {
+        /* Let's read off the proper amount of bytes from the input. */
+        if(conn->seek_func) {
+          seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
+                                    SEEK_SET);
+        }
+
+        if(seekerr != CURL_SEEKFUNC_OK) {
+          curl_off_t passed = 0;
+
+          if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
+            failf(data, "Could not seek stream");
+            return CURLE_FTP_COULDNT_USE_REST;
+          }
+          /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
+          do {
+            size_t readthisamountnow =
+              (data->state.resume_from - passed > data->set.buffer_size) ?
+              (size_t)data->set.buffer_size :
+              curlx_sotouz(data->state.resume_from - passed);
+
+            size_t actuallyread =
+              data->state.fread_func(data->state.buffer, 1,
+                                     readthisamountnow, data->state.in);
+
+            passed += actuallyread;
+            if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
+              /* this checks for greater-than only to make sure that the
+                 CURL_READFUNC_ABORT return code still aborts */
+              failf(data, "Failed to read data");
+              return CURLE_FTP_COULDNT_USE_REST;
+            }
+          } while(passed < data->state.resume_from);
+        }
+
+        /* now, decrease the size of the read */
+        if(data->state.infilesize > 0) {
+          data->state.infilesize -= data->state.resume_from;
+          data->req.size = data->state.infilesize;
+          Curl_pgrsSetUploadSize(data, data->state.infilesize);
+        }
+
+        SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
+      }
+      if(data->state.infilesize > 0) {
+        data->req.size = data->state.infilesize;
+        Curl_pgrsSetUploadSize(data, data->state.infilesize);
+      }
+      /* upload data */
+      Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
+
+      /* not set by Curl_setup_transfer to preserve keepon bits */
+      conn->sockfd = conn->writesockfd;
+
+      if(result) {
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = result;
+      }
+      else {
+        /* store this original bitmask setup to use later on if we can't
+           figure out a "real" bitmask */
+        sshc->orig_waitfor = data->req.keepon;
+
+        /* we want to use the _sending_ function even when the socket turns
+           out readable as the underlying libssh2 sftp send function will deal
+           with both accordingly */
+        conn->cselect_bits = CURL_CSELECT_OUT;
+
+        /* since we don't really wait for anything at this point, we want the
+           state machine to move on as soon as possible so we set a very short
+           timeout here */
+        Curl_expire(data, 0, EXPIRE_RUN_NOW);
+
+        state(conn, SSH_STOP);
+      }
+      break;
+    }
+
+    case SSH_SFTP_CREATE_DIRS_INIT:
+      if(strlen(sftp_scp->path) > 1) {
+        sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
+        state(conn, SSH_SFTP_CREATE_DIRS);
+      }
+      else {
+        state(conn, SSH_SFTP_UPLOAD_INIT);
+      }
+      break;
+
+    case SSH_SFTP_CREATE_DIRS:
+      sshc->slash_pos = strchr(sshc->slash_pos, '/');
+      if(sshc->slash_pos) {
+        *sshc->slash_pos = 0;
+
+        infof(data, "Creating directory '%s'\n", sftp_scp->path);
+        state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
+        break;
+      }
+      state(conn, SSH_SFTP_UPLOAD_INIT);
+      break;
+
+    case SSH_SFTP_CREATE_DIRS_MKDIR:
+      /* 'mode' - parameter is preliminary - default to 0644 */
+      rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path,
+                                 curlx_uztoui(strlen(sftp_scp->path)),
+                                 data->set.new_directory_perms);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      *sshc->slash_pos = '/';
+      ++sshc->slash_pos;
+      if(rc < 0) {
+        /*
+         * Abort if failure wasn't that the dir already exists or the
+         * permission was denied (creation might succeed further down the
+         * path) - retry on unspecific FAILURE also
+         */
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
+           (err != LIBSSH2_FX_FAILURE) &&
+           (err != LIBSSH2_FX_PERMISSION_DENIED)) {
+          result = sftp_libssh2_error_to_CURLE(err);
+          state(conn, SSH_SFTP_CLOSE);
+          sshc->actualcode = result?result:CURLE_SSH;
+          break;
+        }
+        rc = 0; /* clear rc and continue */
+      }
+      state(conn, SSH_SFTP_CREATE_DIRS);
+      break;
+
+    case SSH_SFTP_READDIR_INIT:
+      Curl_pgrsSetDownloadSize(data, -1);
+      if(data->set.opt_no_body) {
+        state(conn, SSH_STOP);
+        break;
+      }
+
+      /*
+       * This is a directory that we are trying to get, so produce a directory
+       * listing
+       */
+      sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session,
+                                               sftp_scp->path,
+                                               curlx_uztoui(
+                                                 strlen(sftp_scp->path)),
+                                               0, 0, LIBSSH2_SFTP_OPENDIR);
+      if(!sshc->sftp_handle) {
+        if(libssh2_session_last_errno(sshc->ssh_session) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        failf(data, "Could not open directory for reading: %s",
+              sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        result = sftp_libssh2_error_to_CURLE(err);
+        sshc->actualcode = result?result:CURLE_SSH;
+        break;
+      }
+      sshc->readdir_filename = malloc(PATH_MAX + 1);
+      if(!sshc->readdir_filename) {
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = CURLE_OUT_OF_MEMORY;
+        break;
+      }
+      sshc->readdir_longentry = malloc(PATH_MAX + 1);
+      if(!sshc->readdir_longentry) {
+        Curl_safefree(sshc->readdir_filename);
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = CURLE_OUT_OF_MEMORY;
+        break;
+      }
+      state(conn, SSH_SFTP_READDIR);
+      break;
+
+    case SSH_SFTP_READDIR:
+      sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
+                                                  sshc->readdir_filename,
+                                                  PATH_MAX,
+                                                  sshc->readdir_longentry,
+                                                  PATH_MAX,
+                                                  &sshc->readdir_attrs);
+      if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
+        rc = LIBSSH2_ERROR_EAGAIN;
+        break;
+      }
+      if(sshc->readdir_len > 0) {
+        sshc->readdir_filename[sshc->readdir_len] = '\0';
+
+        if(data->set.ftp_list_only) {
+          char *tmpLine;
+
+          tmpLine = aprintf("%s\n", sshc->readdir_filename);
+          if(tmpLine == NULL) {
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->actualcode = CURLE_OUT_OF_MEMORY;
+            break;
+          }
+          result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                     tmpLine, sshc->readdir_len + 1);
+          free(tmpLine);
+
+          if(result) {
+            state(conn, SSH_STOP);
+            break;
+          }
+          /* since this counts what we send to the client, we include the
+             newline in this counter */
+          data->req.bytecount += sshc->readdir_len + 1;
+
+          /* output debug output if that is requested */
+          if(data->set.verbose) {
+            Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
+                       sshc->readdir_len, conn);
+          }
+        }
+        else {
+          sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry);
+          sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
+          sshc->readdir_line = calloc(sshc->readdir_totalLen, 1);
+          if(!sshc->readdir_line) {
+            Curl_safefree(sshc->readdir_filename);
+            Curl_safefree(sshc->readdir_longentry);
+            state(conn, SSH_SFTP_CLOSE);
+            sshc->actualcode = CURLE_OUT_OF_MEMORY;
+            break;
+          }
+
+          memcpy(sshc->readdir_line, sshc->readdir_longentry,
+                 sshc->readdir_currLen);
+          if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
+             ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
+              LIBSSH2_SFTP_S_IFLNK)) {
+            sshc->readdir_linkPath = malloc(PATH_MAX + 1);
+            if(sshc->readdir_linkPath == NULL) {
+              Curl_safefree(sshc->readdir_filename);
+              Curl_safefree(sshc->readdir_longentry);
+              state(conn, SSH_SFTP_CLOSE);
+              sshc->actualcode = CURLE_OUT_OF_MEMORY;
+              break;
+            }
+
+            snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
+                     sshc->readdir_filename);
+            state(conn, SSH_SFTP_READDIR_LINK);
+            break;
+          }
+          state(conn, SSH_SFTP_READDIR_BOTTOM);
+          break;
+        }
+      }
+      else if(sshc->readdir_len == 0) {
+        Curl_safefree(sshc->readdir_filename);
+        Curl_safefree(sshc->readdir_longentry);
+        state(conn, SSH_SFTP_READDIR_DONE);
+        break;
+      }
+      else if(sshc->readdir_len <= 0) {
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        result = sftp_libssh2_error_to_CURLE(err);
+        sshc->actualcode = result?result:CURLE_SSH;
+        failf(data, "Could not open remote file for reading: %s :: %d",
+              sftp_libssh2_strerror(err),
+              libssh2_session_last_errno(sshc->ssh_session));
+        Curl_safefree(sshc->readdir_filename);
+        Curl_safefree(sshc->readdir_longentry);
+        state(conn, SSH_SFTP_CLOSE);
+        break;
+      }
+      break;
+
+    case SSH_SFTP_READDIR_LINK:
+      sshc->readdir_len =
+        libssh2_sftp_symlink_ex(sshc->sftp_session,
+                                sshc->readdir_linkPath,
+                                curlx_uztoui(strlen(sshc->readdir_linkPath)),
+                                sshc->readdir_filename,
+                                PATH_MAX, LIBSSH2_SFTP_READLINK);
+      if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
+        rc = LIBSSH2_ERROR_EAGAIN;
+        break;
+      }
+      Curl_safefree(sshc->readdir_linkPath);
+
+      /* get room for the filename and extra output */
+      sshc->readdir_totalLen += 4 + sshc->readdir_len;
+      new_readdir_line = Curl_saferealloc(sshc->readdir_line,
+                                          sshc->readdir_totalLen);
+      if(!new_readdir_line) {
+        sshc->readdir_line = NULL;
+        Curl_safefree(sshc->readdir_filename);
+        Curl_safefree(sshc->readdir_longentry);
+        state(conn, SSH_SFTP_CLOSE);
+        sshc->actualcode = CURLE_OUT_OF_MEMORY;
+        break;
+      }
+      sshc->readdir_line = new_readdir_line;
+
+      sshc->readdir_currLen += snprintf(sshc->readdir_line +
+                                        sshc->readdir_currLen,
+                                        sshc->readdir_totalLen -
+                                        sshc->readdir_currLen,
+                                        " -> %s",
+                                        sshc->readdir_filename);
+
+      state(conn, SSH_SFTP_READDIR_BOTTOM);
+      break;
+
+    case SSH_SFTP_READDIR_BOTTOM:
+      sshc->readdir_currLen += snprintf(sshc->readdir_line +
+                                        sshc->readdir_currLen,
+                                        sshc->readdir_totalLen -
+                                        sshc->readdir_currLen, "\n");
+      result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                 sshc->readdir_line,
+                                 sshc->readdir_currLen);
+
+      if(!result) {
+
+        /* output debug output if that is requested */
+        if(data->set.verbose) {
+          Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
+                     sshc->readdir_currLen, conn);
+        }
+        data->req.bytecount += sshc->readdir_currLen;
+      }
+      Curl_safefree(sshc->readdir_line);
+      if(result) {
+        state(conn, SSH_STOP);
+      }
+      else
+        state(conn, SSH_SFTP_READDIR);
+      break;
+
+    case SSH_SFTP_READDIR_DONE:
+      if(libssh2_sftp_closedir(sshc->sftp_handle) ==
+         LIBSSH2_ERROR_EAGAIN) {
+        rc = LIBSSH2_ERROR_EAGAIN;
+        break;
+      }
+      sshc->sftp_handle = NULL;
+      Curl_safefree(sshc->readdir_filename);
+      Curl_safefree(sshc->readdir_longentry);
+
+      /* no data to transfer */
+      Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+      state(conn, SSH_STOP);
+      break;
+
+    case SSH_SFTP_DOWNLOAD_INIT:
+      /*
+       * Work on getting the specified file
+       */
+      sshc->sftp_handle =
+        libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path,
+                             curlx_uztoui(strlen(sftp_scp->path)),
+                             LIBSSH2_FXF_READ, data->set.new_file_perms,
+                             LIBSSH2_SFTP_OPENFILE);
+      if(!sshc->sftp_handle) {
+        if(libssh2_session_last_errno(sshc->ssh_session) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+        err = sftp_libssh2_last_error(sshc->sftp_session);
+        failf(data, "Could not open remote file for reading: %s",
+              sftp_libssh2_strerror(err));
+        state(conn, SSH_SFTP_CLOSE);
+        result = sftp_libssh2_error_to_CURLE(err);
+        sshc->actualcode = result?result:CURLE_SSH;
+        break;
+      }
+      state(conn, SSH_SFTP_DOWNLOAD_STAT);
+      break;
+
+    case SSH_SFTP_DOWNLOAD_STAT:
+    {
+      LIBSSH2_SFTP_ATTRIBUTES attrs;
+
+      rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path,
+                                curlx_uztoui(strlen(sftp_scp->path)),
+                                LIBSSH2_SFTP_STAT, &attrs);
+      if(rc == LIBSSH2_ERROR_EAGAIN) {
+        break;
+      }
+      if(rc ||
+              !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) ||
+              (attrs.filesize == 0)) {
+        /*
+         * libssh2_sftp_open() didn't return an error, so maybe the server
+         * just doesn't support stat()
+         * OR the server doesn't return a file size with a stat()
+         * OR file size is 0
+         */
+        data->req.size = -1;
+        data->req.maxdownload = -1;
+        Curl_pgrsSetDownloadSize(data, -1);
+      }
+      else {
+        curl_off_t size = attrs.filesize;
+
+        if(size < 0) {
+          failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size);
+          return CURLE_BAD_DOWNLOAD_RESUME;
+        }
+        if(conn->data->state.use_range) {
+          curl_off_t from, to;
+          char *ptr;
+          char *ptr2;
+          CURLofft to_t;
+          CURLofft from_t;
+
+          from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from);
+          if(from_t == CURL_OFFT_FLOW)
+            return CURLE_RANGE_ERROR;
+          while(*ptr && (ISSPACE(*ptr) || (*ptr == '-')))
+            ptr++;
+          to_t = curlx_strtoofft(ptr, &ptr2, 0, &to);
+          if(to_t == CURL_OFFT_FLOW)
+            return CURLE_RANGE_ERROR;
+          if((to_t == CURL_OFFT_INVAL) /* no "to" value given */
+             || (to >= size)) {
+            to = size - 1;
+          }
+          if(from_t) {
+            /* from is relative to end of file */
+            from = size - to;
+            to = size - 1;
+          }
+          if(from > size) {
+            failf(data, "Offset (%"
+                  CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
+                  CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize);
+            return CURLE_BAD_DOWNLOAD_RESUME;
+          }
+          if(from > to) {
+            from = to;
+            size = 0;
+          }
+          else {
+            size = to - from + 1;
+          }
+
+          SFTP_SEEK(conn->proto.sshc.sftp_handle, from);
+        }
+        data->req.size = size;
+        data->req.maxdownload = size;
+        Curl_pgrsSetDownloadSize(data, size);
+      }
+
+      /* We can resume if we can seek to the resume position */
+      if(data->state.resume_from) {
+        if(data->state.resume_from < 0) {
+          /* We're supposed to download the last abs(from) bytes */
+          if((curl_off_t)attrs.filesize < -data->state.resume_from) {
+            failf(data, "Offset (%"
+                  CURL_FORMAT_CURL_OFF_T ") was beyond file size (%"
+                  CURL_FORMAT_CURL_OFF_T ")",
+                  data->state.resume_from, attrs.filesize);
+            return CURLE_BAD_DOWNLOAD_RESUME;
+          }
+          /* download from where? */
+          data->state.resume_from += attrs.filesize;
+        }
+        else {
+          if((curl_off_t)attrs.filesize < data->state.resume_from) {
+            failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T
+                  ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")",
+                  data->state.resume_from, attrs.filesize);
+            return CURLE_BAD_DOWNLOAD_RESUME;
+          }
+        }
+        /* Does a completed file need to be seeked and started or closed ? */
+        /* Now store the number of bytes we are expected to download */
+        data->req.size = attrs.filesize - data->state.resume_from;
+        data->req.maxdownload = attrs.filesize - data->state.resume_from;
+        Curl_pgrsSetDownloadSize(data,
+                                 attrs.filesize - data->state.resume_from);
+        SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
+      }
+    }
+
+    /* Setup the actual download */
+    if(data->req.size == 0) {
+      /* no data to transfer */
+      Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+      infof(data, "File already completely downloaded\n");
+      state(conn, SSH_STOP);
+      break;
+    }
+    Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
+                        FALSE, NULL, -1, NULL);
+
+    /* not set by Curl_setup_transfer to preserve keepon bits */
+    conn->writesockfd = conn->sockfd;
+
+    /* we want to use the _receiving_ function even when the socket turns
+       out writableable as the underlying libssh2 recv function will deal
+       with both accordingly */
+    conn->cselect_bits = CURL_CSELECT_IN;
+
+    if(result) {
+      /* this should never occur; the close state should be entered
+         at the time the error occurs */
+      state(conn, SSH_SFTP_CLOSE);
+      sshc->actualcode = result;
+    }
+    else {
+      state(conn, SSH_STOP);
+    }
+    break;
+
+    case SSH_SFTP_CLOSE:
+      if(sshc->sftp_handle) {
+        rc = libssh2_sftp_close(sshc->sftp_handle);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          infof(data, "Failed to close libssh2 file\n");
+        }
+        sshc->sftp_handle = NULL;
+      }
+
+      Curl_safefree(sftp_scp->path);
+
+      DEBUGF(infof(data, "SFTP DONE done\n"));
+
+      /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
+         After nextstate is executed, the control should come back to
+         SSH_SFTP_CLOSE to pass the correct result back  */
+      if(sshc->nextstate != SSH_NO_STATE &&
+         sshc->nextstate != SSH_SFTP_CLOSE) {
+        state(conn, sshc->nextstate);
+        sshc->nextstate = SSH_SFTP_CLOSE;
+      }
+      else {
+        state(conn, SSH_STOP);
+        result = sshc->actualcode;
+      }
+      break;
+
+    case SSH_SFTP_SHUTDOWN:
+      /* during times we get here due to a broken transfer and then the
+         sftp_handle might not have been taken down so make sure that is done
+         before we proceed */
+
+      if(sshc->sftp_handle) {
+        rc = libssh2_sftp_close(sshc->sftp_handle);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          infof(data, "Failed to close libssh2 file\n");
+        }
+        sshc->sftp_handle = NULL;
+      }
+      if(sshc->sftp_session) {
+        rc = libssh2_sftp_shutdown(sshc->sftp_session);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          infof(data, "Failed to stop libssh2 sftp subsystem\n");
+        }
+        sshc->sftp_session = NULL;
+      }
+
+      Curl_safefree(sshc->homedir);
+      conn->data->state.most_recent_ftp_entrypath = NULL;
+
+      state(conn, SSH_SESSION_DISCONNECT);
+      break;
+
+    case SSH_SCP_TRANS_INIT:
+      result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
+      if(result) {
+        sshc->actualcode = result;
+        state(conn, SSH_STOP);
+        break;
+      }
+
+      if(data->set.upload) {
+        if(data->state.infilesize < 0) {
+          failf(data, "SCP requires a known file size for upload");
+          sshc->actualcode = CURLE_UPLOAD_FAILED;
+          state(conn, SSH_SCP_CHANNEL_FREE);
+          break;
+        }
+        state(conn, SSH_SCP_UPLOAD_INIT);
+      }
+      else {
+        state(conn, SSH_SCP_DOWNLOAD_INIT);
+      }
+      break;
+
+    case SSH_SCP_UPLOAD_INIT:
+      /*
+       * libssh2 requires that the destination path is a full path that
+       * includes the destination file and name OR ends in a "/" .  If this is
+       * not done the destination file will be named the same name as the last
+       * directory in the path.
+       */
+      sshc->ssh_channel =
+        SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms,
+                 data->state.infilesize);
+      if(!sshc->ssh_channel) {
+        int ssh_err;
+        char *err_msg;
+
+        if(libssh2_session_last_errno(sshc->ssh_session) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+
+        ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
+                                                   &err_msg, NULL, 0));
+        failf(conn->data, "%s", err_msg);
+        state(conn, SSH_SCP_CHANNEL_FREE);
+        sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
+        break;
+      }
+
+      /* upload data */
+      Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
+                          FIRSTSOCKET, NULL);
+
+      /* not set by Curl_setup_transfer to preserve keepon bits */
+      conn->sockfd = conn->writesockfd;
+
+      if(result) {
+        state(conn, SSH_SCP_CHANNEL_FREE);
+        sshc->actualcode = result;
+      }
+      else {
+        /* store this original bitmask setup to use later on if we can't
+           figure out a "real" bitmask */
+        sshc->orig_waitfor = data->req.keepon;
+
+        /* we want to use the _sending_ function even when the socket turns
+           out readable as the underlying libssh2 scp send function will deal
+           with both accordingly */
+        conn->cselect_bits = CURL_CSELECT_OUT;
+
+        state(conn, SSH_STOP);
+      }
+      break;
+
+    case SSH_SCP_DOWNLOAD_INIT:
+    {
+      curl_off_t bytecount;
+
+      /*
+       * We must check the remote file; if it is a directory no values will
+       * be set in sb
+       */
+
+       /*
+        * If support for >2GB files exists, use it.
+        */
+
+      /* get a fresh new channel from the ssh layer */
+#if LIBSSH2_VERSION_NUM < 0x010700
+      struct stat sb;
+      memset(&sb, 0, sizeof(struct stat));
+      sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
+                                           sftp_scp->path, &sb);
+#else
+      libssh2_struct_stat sb;
+      memset(&sb, 0, sizeof(libssh2_struct_stat));
+      sshc->ssh_channel = libssh2_scp_recv2(sshc->ssh_session,
+                                            sftp_scp->path, &sb);
+#endif
+
+      if(!sshc->ssh_channel) {
+        int ssh_err;
+        char *err_msg;
+
+        if(libssh2_session_last_errno(sshc->ssh_session) ==
+           LIBSSH2_ERROR_EAGAIN) {
+          rc = LIBSSH2_ERROR_EAGAIN;
+          break;
+        }
+
+
+        ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
+                                                   &err_msg, NULL, 0));
+        failf(conn->data, "%s", err_msg);
+        state(conn, SSH_SCP_CHANNEL_FREE);
+        sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
+        break;
+      }
+
+      /* download data */
+      bytecount = (curl_off_t)sb.st_size;
+      data->req.maxdownload =  (curl_off_t)sb.st_size;
+      Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL);
+
+      /* not set by Curl_setup_transfer to preserve keepon bits */
+      conn->writesockfd = conn->sockfd;
+
+      /* we want to use the _receiving_ function even when the socket turns
+         out writableable as the underlying libssh2 recv function will deal
+         with both accordingly */
+      conn->cselect_bits = CURL_CSELECT_IN;
+
+      if(result) {
+        state(conn, SSH_SCP_CHANNEL_FREE);
+        sshc->actualcode = result;
+      }
+      else
+        state(conn, SSH_STOP);
+    }
+    break;
+
+    case SSH_SCP_DONE:
+      if(data->set.upload)
+        state(conn, SSH_SCP_SEND_EOF);
+      else
+        state(conn, SSH_SCP_CHANNEL_FREE);
+      break;
+
+    case SSH_SCP_SEND_EOF:
+      if(sshc->ssh_channel) {
+        rc = libssh2_channel_send_eof(sshc->ssh_channel);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc) {
+          infof(data, "Failed to send libssh2 channel EOF\n");
+        }
+      }
+      state(conn, SSH_SCP_WAIT_EOF);
+      break;
+
+    case SSH_SCP_WAIT_EOF:
+      if(sshc->ssh_channel) {
+        rc = libssh2_channel_wait_eof(sshc->ssh_channel);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc) {
+          infof(data, "Failed to get channel EOF: %d\n", rc);
+        }
+      }
+      state(conn, SSH_SCP_WAIT_CLOSE);
+      break;
+
+    case SSH_SCP_WAIT_CLOSE:
+      if(sshc->ssh_channel) {
+        rc = libssh2_channel_wait_closed(sshc->ssh_channel);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc) {
+          infof(data, "Channel failed to close: %d\n", rc);
+        }
+      }
+      state(conn, SSH_SCP_CHANNEL_FREE);
+      break;
+
+    case SSH_SCP_CHANNEL_FREE:
+      if(sshc->ssh_channel) {
+        rc = libssh2_channel_free(sshc->ssh_channel);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          infof(data, "Failed to free libssh2 scp subsystem\n");
+        }
+        sshc->ssh_channel = NULL;
+      }
+      DEBUGF(infof(data, "SCP DONE phase complete\n"));
+#if 0 /* PREV */
+      state(conn, SSH_SESSION_DISCONNECT);
+#endif
+      state(conn, SSH_STOP);
+      result = sshc->actualcode;
+      break;
+
+    case SSH_SESSION_DISCONNECT:
+      /* during weird times when we've been prematurely aborted, the channel
+         is still alive when we reach this state and we MUST kill the channel
+         properly first */
+      if(sshc->ssh_channel) {
+        rc = libssh2_channel_free(sshc->ssh_channel);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          infof(data, "Failed to free libssh2 scp subsystem\n");
+        }
+        sshc->ssh_channel = NULL;
+      }
+
+      if(sshc->ssh_session) {
+        rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          infof(data, "Failed to disconnect libssh2 session\n");
+        }
+      }
+
+      Curl_safefree(sshc->homedir);
+      conn->data->state.most_recent_ftp_entrypath = NULL;
+
+      state(conn, SSH_SESSION_FREE);
+      break;
+
+    case SSH_SESSION_FREE:
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+      if(sshc->kh) {
+        libssh2_knownhost_free(sshc->kh);
+        sshc->kh = NULL;
+      }
+#endif
+
+#ifdef HAVE_LIBSSH2_AGENT_API
+      if(sshc->ssh_agent) {
+        rc = libssh2_agent_disconnect(sshc->ssh_agent);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          infof(data, "Failed to disconnect from libssh2 agent\n");
+        }
+        libssh2_agent_free(sshc->ssh_agent);
+        sshc->ssh_agent = NULL;
+
+        /* NB: there is no need to free identities, they are part of internal
+           agent stuff */
+        sshc->sshagent_identity = NULL;
+        sshc->sshagent_prev_identity = NULL;
+      }
+#endif
+
+      if(sshc->ssh_session) {
+        rc = libssh2_session_free(sshc->ssh_session);
+        if(rc == LIBSSH2_ERROR_EAGAIN) {
+          break;
+        }
+        if(rc < 0) {
+          infof(data, "Failed to free libssh2 session\n");
+        }
+        sshc->ssh_session = NULL;
+      }
+
+      /* worst-case scenario cleanup */
+
+      DEBUGASSERT(sshc->ssh_session == NULL);
+      DEBUGASSERT(sshc->ssh_channel == NULL);
+      DEBUGASSERT(sshc->sftp_session == NULL);
+      DEBUGASSERT(sshc->sftp_handle == NULL);
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+      DEBUGASSERT(sshc->kh == NULL);
+#endif
+#ifdef HAVE_LIBSSH2_AGENT_API
+      DEBUGASSERT(sshc->ssh_agent == NULL);
+#endif
+
+      Curl_safefree(sshc->rsa_pub);
+      Curl_safefree(sshc->rsa);
+
+      Curl_safefree(sshc->quote_path1);
+      Curl_safefree(sshc->quote_path2);
+
+      Curl_safefree(sshc->homedir);
+
+      Curl_safefree(sshc->readdir_filename);
+      Curl_safefree(sshc->readdir_longentry);
+      Curl_safefree(sshc->readdir_line);
+      Curl_safefree(sshc->readdir_linkPath);
+
+      /* the code we are about to return */
+      result = sshc->actualcode;
+
+      memset(sshc, 0, sizeof(struct ssh_conn));
+
+      connclose(conn, "SSH session free");
+      sshc->state = SSH_SESSION_FREE; /* current */
+      sshc->nextstate = SSH_NO_STATE;
+      state(conn, SSH_STOP);
+      break;
+
+    case SSH_QUIT:
+      /* fallthrough, just stop! */
+    default:
+      /* internal error */
+      sshc->nextstate = SSH_NO_STATE;
+      state(conn, SSH_STOP);
+      break;
+    }
+
+  } while(!rc && (sshc->state != SSH_STOP));
+
+  if(rc == LIBSSH2_ERROR_EAGAIN) {
+    /* we would block, we need to wait for the socket to be ready (in the
+       right direction too)! */
+    *block = TRUE;
+  }
+
+  return result;
+}
+
+/* called by the multi interface to figure out what socket(s) to wait for and
+   for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
+static int ssh_perform_getsock(const struct connectdata *conn,
+                               curl_socket_t *sock, /* points to numsocks
+                                                       number of sockets */
+                               int numsocks)
+{
+#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
+  int bitmap = GETSOCK_BLANK;
+  (void)numsocks;
+
+  sock[0] = conn->sock[FIRSTSOCKET];
+
+  if(conn->waitfor & KEEP_RECV)
+    bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
+
+  if(conn->waitfor & KEEP_SEND)
+    bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
+
+  return bitmap;
+#else
+  /* if we don't know the direction we can use the generic *_getsock()
+     function even for the protocol_connect and doing states */
+  return Curl_single_getsock(conn, sock, numsocks);
+#endif
+}
+
+/* Generic function called by the multi interface to figure out what socket(s)
+   to wait for and for what actions during the DOING and PROTOCONNECT states*/
+static int ssh_getsock(struct connectdata *conn,
+                       curl_socket_t *sock, /* points to numsocks number
+                                               of sockets */
+                       int numsocks)
+{
+#ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
+  (void)conn;
+  (void)sock;
+  (void)numsocks;
+  /* if we don't know any direction we can just play along as we used to and
+     not provide any sensible info */
+  return GETSOCK_BLANK;
+#else
+  /* if we know the direction we can use the generic *_getsock() function even
+     for the protocol_connect and doing states */
+  return ssh_perform_getsock(conn, sock, numsocks);
+#endif
+}
+
+#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
+/*
+ * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
+ * function is used to figure out in what direction and stores this info so
+ * that the multi interface can take advantage of it. Make sure to call this
+ * function in all cases so that when it _doesn't_ return EAGAIN we can
+ * restore the default wait bits.
+ */
+static void ssh_block2waitfor(struct connectdata *conn, bool block)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  int dir = 0;
+  if(block) {
+    dir = libssh2_session_block_directions(sshc->ssh_session);
+    if(dir) {
+      /* translate the libssh2 define bits into our own bit defines */
+      conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) |
+        ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0);
+    }
+  }
+  if(!dir)
+    /* It didn't block or libssh2 didn't reveal in which direction, put back
+       the original set */
+    conn->waitfor = sshc->orig_waitfor;
+}
+#else
+  /* no libssh2 directional support so we simply don't know */
+#define ssh_block2waitfor(x,y) Curl_nop_stmt
+#endif
+
+/* called repeatedly until done from multi.c */
+static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  CURLcode result = CURLE_OK;
+  bool block; /* we store the status and use that to provide a ssh_getsock()
+                 implementation */
+
+  result = ssh_statemach_act(conn, &block);
+  *done = (sshc->state == SSH_STOP) ? TRUE : FALSE;
+  ssh_block2waitfor(conn, block);
+
+  return result;
+}
+
+static CURLcode ssh_block_statemach(struct connectdata *conn,
+                                    bool disconnect)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  while((sshc->state != SSH_STOP) && !result) {
+    bool block;
+    timediff_t left = 1000;
+    struct curltime now = Curl_now();
+
+    result = ssh_statemach_act(conn, &block);
+    if(result)
+      break;
+
+    if(!disconnect) {
+      if(Curl_pgrsUpdate(conn))
+        return CURLE_ABORTED_BY_CALLBACK;
+
+      result = Curl_speedcheck(data, now);
+      if(result)
+        break;
+
+      left = Curl_timeleft(data, NULL, FALSE);
+      if(left < 0) {
+        failf(data, "Operation timed out");
+        return CURLE_OPERATION_TIMEDOUT;
+      }
+    }
+
+#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION
+    if(!result && block) {
+      int dir = libssh2_session_block_directions(sshc->ssh_session);
+      curl_socket_t sock = conn->sock[FIRSTSOCKET];
+      curl_socket_t fd_read = CURL_SOCKET_BAD;
+      curl_socket_t fd_write = CURL_SOCKET_BAD;
+      if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
+        fd_read = sock;
+      if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
+        fd_write = sock;
+      /* wait for the socket to become ready */
+      (void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write,
+                              left>1000?1000:left); /* ignore result */
+    }
+#endif
+
+  }
+
+  return result;
+}
+
+/*
+ * SSH setup and connection
+ */
+static CURLcode ssh_setup_connection(struct connectdata *conn)
+{
+  struct SSHPROTO *ssh;
+
+  conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO));
+  if(!ssh)
+    return CURLE_OUT_OF_MEMORY;
+
+  return CURLE_OK;
+}
+
+static Curl_recv scp_recv, sftp_recv;
+static Curl_send scp_send, sftp_send;
+
+/*
+ * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
+ * do protocol-specific actions at connect-time.
+ */
+static CURLcode ssh_connect(struct connectdata *conn, bool *done)
+{
+#ifdef CURL_LIBSSH2_DEBUG
+  curl_socket_t sock;
+#endif
+  struct ssh_conn *ssh;
+  CURLcode result;
+  struct Curl_easy *data = conn->data;
+
+  /* initialize per-handle data if not already */
+  if(!data->req.protop)
+    ssh_setup_connection(conn);
+
+  /* We default to persistent connections. We set this already in this connect
+     function to make the re-use checks properly be able to check this bit. */
+  connkeep(conn, "SSH default");
+
+  if(conn->handler->protocol & CURLPROTO_SCP) {
+    conn->recv[FIRSTSOCKET] = scp_recv;
+    conn->send[FIRSTSOCKET] = scp_send;
+  }
+  else {
+    conn->recv[FIRSTSOCKET] = sftp_recv;
+    conn->send[FIRSTSOCKET] = sftp_send;
+  }
+  ssh = &conn->proto.sshc;
+
+#ifdef CURL_LIBSSH2_DEBUG
+  if(conn->user) {
+    infof(data, "User: %s\n", conn->user);
+  }
+  if(conn->passwd) {
+    infof(data, "Password: %s\n", conn->passwd);
+  }
+  sock = conn->sock[FIRSTSOCKET];
+#endif /* CURL_LIBSSH2_DEBUG */
+
+  ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
+                                             my_libssh2_free,
+                                             my_libssh2_realloc, conn);
+  if(ssh->ssh_session == NULL) {
+    failf(data, "Failure initialising ssh session");
+    return CURLE_FAILED_INIT;
+  }
+
+  if(data->set.ssh_compression) {
+#if LIBSSH2_VERSION_NUM >= 0x010208
+    if(libssh2_session_flag(ssh->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0)
+#endif
+      infof(data, "Failed to enable compression for ssh session\n");
+  }
+
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+  if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
+    int rc;
+    ssh->kh = libssh2_knownhost_init(ssh->ssh_session);
+    if(!ssh->kh) {
+      /* eeek. TODO: free the ssh_session! */
+      return CURLE_FAILED_INIT;
+    }
+
+    /* read all known hosts from there */
+    rc = libssh2_knownhost_readfile(ssh->kh,
+                                    data->set.str[STRING_SSH_KNOWNHOSTS],
+                                    LIBSSH2_KNOWNHOST_FILE_OPENSSH);
+    if(rc < 0)
+      infof(data, "Failed to read known hosts from %s\n",
+            data->set.str[STRING_SSH_KNOWNHOSTS]);
+  }
+#endif /* HAVE_LIBSSH2_KNOWNHOST_API */
+
+#ifdef CURL_LIBSSH2_DEBUG
+  libssh2_trace(ssh->ssh_session, ~0);
+  infof(data, "SSH socket: %d\n", (int)sock);
+#endif /* CURL_LIBSSH2_DEBUG */
+
+  state(conn, SSH_INIT);
+
+  result = ssh_multi_statemach(conn, done);
+
+  return result;
+}
+
+/*
+ ***********************************************************************
+ *
+ * scp_perform()
+ *
+ * This is the actual DO function for SCP. Get a file according to
+ * the options previously setup.
+ */
+
+static
+CURLcode scp_perform(struct connectdata *conn,
+                      bool *connected,
+                      bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  *dophase_done = FALSE; /* not done yet */
+
+  /* start the first command in the DO phase */
+  state(conn, SSH_SCP_TRANS_INIT);
+
+  /* run the state-machine */
+  result = ssh_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+
+  return result;
+}
+
+/* called from multi.c while DOing */
+static CURLcode scp_doing(struct connectdata *conn,
+                               bool *dophase_done)
+{
+  CURLcode result;
+  result = ssh_multi_statemach(conn, dophase_done);
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+  return result;
+}
+
+/*
+ * The DO function is generic for both protocols. There was previously two
+ * separate ones but this way means less duplicated code.
+ */
+
+static CURLcode ssh_do(struct connectdata *conn, bool *done)
+{
+  CURLcode result;
+  bool connected = 0;
+  struct Curl_easy *data = conn->data;
+  struct ssh_conn *sshc = &conn->proto.sshc;
+
+  *done = FALSE; /* default to false */
+
+  data->req.size = -1; /* make sure this is unknown at this point */
+
+  sshc->actualcode = CURLE_OK; /* reset error code */
+  sshc->secondCreateDirs = 0;   /* reset the create dir attempt state
+                                   variable */
+
+  Curl_pgrsSetUploadCounter(data, 0);
+  Curl_pgrsSetDownloadCounter(data, 0);
+  Curl_pgrsSetUploadSize(data, -1);
+  Curl_pgrsSetDownloadSize(data, -1);
+
+  if(conn->handler->protocol & CURLPROTO_SCP)
+    result = scp_perform(conn, &connected,  done);
+  else
+    result = sftp_perform(conn, &connected,  done);
+
+  return result;
+}
+
+/* BLOCKING, but the function is using the state machine so the only reason
+   this is still blocking is that the multi interface code has no support for
+   disconnecting operations that takes a while */
+static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  CURLcode result = CURLE_OK;
+  struct ssh_conn *ssh = &conn->proto.sshc;
+  (void) dead_connection;
+
+  if(ssh->ssh_session) {
+    /* only if there's a session still around to use! */
+
+    state(conn, SSH_SESSION_DISCONNECT);
+
+    result = ssh_block_statemach(conn, TRUE);
+  }
+
+  return result;
+}
+
+/* generic done function for both SCP and SFTP called from their specific
+   done functions */
+static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
+{
+  CURLcode result = CURLE_OK;
+  struct SSHPROTO *sftp_scp = conn->data->req.protop;
+
+  if(!status) {
+    /* run the state-machine
+
+       TODO: when the multi interface is used, this _really_ should be using
+       the ssh_multi_statemach function but we have no general support for
+       non-blocking DONE operations!
+    */
+    result = ssh_block_statemach(conn, FALSE);
+  }
+  else
+    result = status;
+
+  if(sftp_scp)
+    Curl_safefree(sftp_scp->path);
+  if(Curl_pgrsDone(conn))
+    return CURLE_ABORTED_BY_CALLBACK;
+
+  conn->data->req.keepon = 0; /* clear all bits */
+  return result;
+}
+
+
+static CURLcode scp_done(struct connectdata *conn, CURLcode status,
+                         bool premature)
+{
+  (void)premature; /* not used */
+
+  if(!status)
+    state(conn, SSH_SCP_DONE);
+
+  return ssh_done(conn, status);
+
+}
+
+static ssize_t scp_send(struct connectdata *conn, int sockindex,
+                        const void *mem, size_t len, CURLcode *err)
+{
+  ssize_t nwrite;
+  (void)sockindex; /* we only support SCP on the fixed known primary socket */
+
+  /* libssh2_channel_write() returns int! */
+  nwrite = (ssize_t)
+    libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
+
+  ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
+
+  if(nwrite == LIBSSH2_ERROR_EAGAIN) {
+    *err = CURLE_AGAIN;
+    nwrite = 0;
+  }
+  else if(nwrite < LIBSSH2_ERROR_NONE) {
+    *err = libssh2_session_error_to_CURLE((int)nwrite);
+    nwrite = -1;
+  }
+
+  return nwrite;
+}
+
+static ssize_t scp_recv(struct connectdata *conn, int sockindex,
+                        char *mem, size_t len, CURLcode *err)
+{
+  ssize_t nread;
+  (void)sockindex; /* we only support SCP on the fixed known primary socket */
+
+  /* libssh2_channel_read() returns int */
+  nread = (ssize_t)
+    libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
+
+  ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
+  if(nread == LIBSSH2_ERROR_EAGAIN) {
+    *err = CURLE_AGAIN;
+    nread = -1;
+  }
+
+  return nread;
+}
+
+/*
+ * =============== SFTP ===============
+ */
+
+/*
+ ***********************************************************************
+ *
+ * sftp_perform()
+ *
+ * This is the actual DO function for SFTP. Get a file/directory according to
+ * the options previously setup.
+ */
+
+static
+CURLcode sftp_perform(struct connectdata *conn,
+                      bool *connected,
+                      bool *dophase_done)
+{
+  CURLcode result = CURLE_OK;
+
+  DEBUGF(infof(conn->data, "DO phase starts\n"));
+
+  *dophase_done = FALSE; /* not done yet */
+
+  /* start the first command in the DO phase */
+  state(conn, SSH_SFTP_QUOTE_INIT);
+
+  /* run the state-machine */
+  result = ssh_multi_statemach(conn, dophase_done);
+
+  *connected = conn->bits.tcpconnect[FIRSTSOCKET];
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+
+  return result;
+}
+
+/* called from multi.c while DOing */
+static CURLcode sftp_doing(struct connectdata *conn,
+                           bool *dophase_done)
+{
+  CURLcode result = ssh_multi_statemach(conn, dophase_done);
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+  return result;
+}
+
+/* BLOCKING, but the function is using the state machine so the only reason
+   this is still blocking is that the multi interface code has no support for
+   disconnecting operations that takes a while */
+static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  CURLcode result = CURLE_OK;
+  (void) dead_connection;
+
+  DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
+
+  if(conn->proto.sshc.ssh_session) {
+    /* only if there's a session still around to use! */
+    state(conn, SSH_SFTP_SHUTDOWN);
+    result = ssh_block_statemach(conn, TRUE);
+  }
+
+  DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
+
+  return result;
+
+}
+
+static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
+                               bool premature)
+{
+  struct ssh_conn *sshc = &conn->proto.sshc;
+
+  if(!status) {
+    /* Post quote commands are executed after the SFTP_CLOSE state to avoid
+       errors that could happen due to open file handles during POSTQUOTE
+       operation */
+    if(!status && !premature && conn->data->set.postquote) {
+      sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
+      state(conn, SSH_SFTP_CLOSE);
+    }
+    else
+      state(conn, SSH_SFTP_CLOSE);
+  }
+  return ssh_done(conn, status);
+}
+
+/* return number of sent bytes */
+static ssize_t sftp_send(struct connectdata *conn, int sockindex,
+                         const void *mem, size_t len, CURLcode *err)
+{
+  ssize_t nwrite;   /* libssh2_sftp_write() used to return size_t in 0.14
+                       but is changed to ssize_t in 0.15. These days we don't
+                       support libssh2 0.15*/
+  (void)sockindex;
+
+  nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
+
+  ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
+
+  if(nwrite == LIBSSH2_ERROR_EAGAIN) {
+    *err = CURLE_AGAIN;
+    nwrite = 0;
+  }
+  else if(nwrite < LIBSSH2_ERROR_NONE) {
+    *err = libssh2_session_error_to_CURLE((int)nwrite);
+    nwrite = -1;
+  }
+
+  return nwrite;
+}
+
+/*
+ * Return number of received (decrypted) bytes
+ * or <0 on error
+ */
+static ssize_t sftp_recv(struct connectdata *conn, int sockindex,
+                         char *mem, size_t len, CURLcode *err)
+{
+  ssize_t nread;
+  (void)sockindex;
+
+  nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
+
+  ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE);
+
+  if(nread == LIBSSH2_ERROR_EAGAIN) {
+    *err = CURLE_AGAIN;
+    nread = -1;
+
+  }
+  else if(nread < 0) {
+    *err = libssh2_session_error_to_CURLE((int)nread);
+  }
+  return nread;
+}
+
+/* The get_pathname() function is being borrowed from OpenSSH sftp.c
+   version 4.6p1. */
+/*
+ * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+static CURLcode
+get_pathname(const char **cpp, char **path)
+{
+  const char *cp = *cpp, *end;
+  char quot;
+  unsigned int i, j;
+  static const char WHITESPACE[] = " \t\r\n";
+
+  cp += strspn(cp, WHITESPACE);
+  if(!*cp) {
+    *cpp = cp;
+    *path = NULL;
+    return CURLE_QUOTE_ERROR;
+  }
+
+  *path = malloc(strlen(cp) + 1);
+  if(*path == NULL)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Check for quoted filenames */
+  if(*cp == '\"' || *cp == '\'') {
+    quot = *cp++;
+
+    /* Search for terminating quote, unescape some chars */
+    for(i = j = 0; i <= strlen(cp); i++) {
+      if(cp[i] == quot) {  /* Found quote */
+        i++;
+        (*path)[j] = '\0';
+        break;
+      }
+      if(cp[i] == '\0') {  /* End of string */
+        /*error("Unterminated quote");*/
+        goto fail;
+      }
+      if(cp[i] == '\\') {  /* Escaped characters */
+        i++;
+        if(cp[i] != '\'' && cp[i] != '\"' &&
+            cp[i] != '\\') {
+          /*error("Bad escaped character '\\%c'",
+              cp[i]);*/
+          goto fail;
+        }
+      }
+      (*path)[j++] = cp[i];
+    }
+
+    if(j == 0) {
+      /*error("Empty quotes");*/
+      goto fail;
+    }
+    *cpp = cp + i + strspn(cp + i, WHITESPACE);
+  }
+  else {
+    /* Read to end of filename */
+    end = strpbrk(cp, WHITESPACE);
+    if(end == NULL)
+      end = strchr(cp, '\0');
+    *cpp = end + strspn(end, WHITESPACE);
+
+    memcpy(*path, cp, end - cp);
+    (*path)[end - cp] = '\0';
+  }
+  return CURLE_OK;
+
+  fail:
+  Curl_safefree(*path);
+  return CURLE_QUOTE_ERROR;
+}
+
+
+static const char *sftp_libssh2_strerror(int err)
+{
+  switch(err) {
+    case LIBSSH2_FX_NO_SUCH_FILE:
+      return "No such file or directory";
+
+    case LIBSSH2_FX_PERMISSION_DENIED:
+      return "Permission denied";
+
+    case LIBSSH2_FX_FAILURE:
+      return "Operation failed";
+
+    case LIBSSH2_FX_BAD_MESSAGE:
+      return "Bad message from SFTP server";
+
+    case LIBSSH2_FX_NO_CONNECTION:
+      return "Not connected to SFTP server";
+
+    case LIBSSH2_FX_CONNECTION_LOST:
+      return "Connection to SFTP server lost";
+
+    case LIBSSH2_FX_OP_UNSUPPORTED:
+      return "Operation not supported by SFTP server";
+
+    case LIBSSH2_FX_INVALID_HANDLE:
+      return "Invalid handle";
+
+    case LIBSSH2_FX_NO_SUCH_PATH:
+      return "No such file or directory";
+
+    case LIBSSH2_FX_FILE_ALREADY_EXISTS:
+      return "File already exists";
+
+    case LIBSSH2_FX_WRITE_PROTECT:
+      return "File is write protected";
+
+    case LIBSSH2_FX_NO_MEDIA:
+      return "No media";
+
+    case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
+      return "Disk full";
+
+    case LIBSSH2_FX_QUOTA_EXCEEDED:
+      return "User quota exceeded";
+
+    case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
+      return "Unknown principle";
+
+    case LIBSSH2_FX_LOCK_CONFlICT:
+      return "File lock conflict";
+
+    case LIBSSH2_FX_DIR_NOT_EMPTY:
+      return "Directory not empty";
+
+    case LIBSSH2_FX_NOT_A_DIRECTORY:
+      return "Not a directory";
+
+    case LIBSSH2_FX_INVALID_FILENAME:
+      return "Invalid filename";
+
+    case LIBSSH2_FX_LINK_LOOP:
+      return "Link points to itself";
+  }
+  return "Unknown error in libssh2";
+}
+
+#endif /* USE_LIBSSH2 */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/ssh.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/ssh.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/ssh.h	(revision 331)
@@ -0,0 +1,198 @@
+#ifndef HEADER_CURL_SSH_H
+#define HEADER_CURL_SSH_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_LIBSSH2_H
+#include <libssh2.h>
+#include <libssh2_sftp.h>
+#endif /* HAVE_LIBSSH2_H */
+
+/****************************************************************************
+ * SSH unique setup
+ ***************************************************************************/
+typedef enum {
+  SSH_NO_STATE = -1,  /* Used for "nextState" so say there is none */
+  SSH_STOP = 0,       /* do nothing state, stops the state machine */
+
+  SSH_INIT,           /* First state in SSH-CONNECT */
+  SSH_S_STARTUP,      /* Session startup */
+  SSH_HOSTKEY,        /* verify hostkey */
+  SSH_AUTHLIST,
+  SSH_AUTH_PKEY_INIT,
+  SSH_AUTH_PKEY,
+  SSH_AUTH_PASS_INIT,
+  SSH_AUTH_PASS,
+  SSH_AUTH_AGENT_INIT, /* initialize then wait for connection to agent */
+  SSH_AUTH_AGENT_LIST, /* ask for list then wait for entire list to come */
+  SSH_AUTH_AGENT,      /* attempt one key at a time */
+  SSH_AUTH_HOST_INIT,
+  SSH_AUTH_HOST,
+  SSH_AUTH_KEY_INIT,
+  SSH_AUTH_KEY,
+  SSH_AUTH_DONE,
+  SSH_SFTP_INIT,
+  SSH_SFTP_REALPATH,   /* Last state in SSH-CONNECT */
+
+  SSH_SFTP_QUOTE_INIT, /* First state in SFTP-DO */
+  SSH_SFTP_POSTQUOTE_INIT, /* (Possibly) First state in SFTP-DONE */
+  SSH_SFTP_QUOTE,
+  SSH_SFTP_NEXT_QUOTE,
+  SSH_SFTP_QUOTE_STAT,
+  SSH_SFTP_QUOTE_SETSTAT,
+  SSH_SFTP_QUOTE_SYMLINK,
+  SSH_SFTP_QUOTE_MKDIR,
+  SSH_SFTP_QUOTE_RENAME,
+  SSH_SFTP_QUOTE_RMDIR,
+  SSH_SFTP_QUOTE_UNLINK,
+  SSH_SFTP_QUOTE_STATVFS,
+  SSH_SFTP_GETINFO,
+  SSH_SFTP_FILETIME,
+  SSH_SFTP_TRANS_INIT,
+  SSH_SFTP_UPLOAD_INIT,
+  SSH_SFTP_CREATE_DIRS_INIT,
+  SSH_SFTP_CREATE_DIRS,
+  SSH_SFTP_CREATE_DIRS_MKDIR,
+  SSH_SFTP_READDIR_INIT,
+  SSH_SFTP_READDIR,
+  SSH_SFTP_READDIR_LINK,
+  SSH_SFTP_READDIR_BOTTOM,
+  SSH_SFTP_READDIR_DONE,
+  SSH_SFTP_DOWNLOAD_INIT,
+  SSH_SFTP_DOWNLOAD_STAT, /* Last state in SFTP-DO */
+  SSH_SFTP_CLOSE,    /* Last state in SFTP-DONE */
+  SSH_SFTP_SHUTDOWN, /* First state in SFTP-DISCONNECT */
+  SSH_SCP_TRANS_INIT, /* First state in SCP-DO */
+  SSH_SCP_UPLOAD_INIT,
+  SSH_SCP_DOWNLOAD_INIT,
+  SSH_SCP_DONE,
+  SSH_SCP_SEND_EOF,
+  SSH_SCP_WAIT_EOF,
+  SSH_SCP_WAIT_CLOSE,
+  SSH_SCP_CHANNEL_FREE,   /* Last state in SCP-DONE */
+  SSH_SESSION_DISCONNECT, /* First state in SCP-DISCONNECT */
+  SSH_SESSION_FREE,       /* Last state in SCP/SFTP-DISCONNECT */
+  SSH_QUIT,
+  SSH_LAST  /* never used */
+} sshstate;
+
+/* this struct is used in the HandleData struct which is part of the
+   Curl_easy, which means this is used on a per-easy handle basis.
+   Everything that is strictly related to a connection is banned from this
+   struct. */
+struct SSHPROTO {
+  char *path;                  /* the path we operate on */
+};
+
+/* ssh_conn is used for struct connection-oriented data in the connectdata
+   struct */
+struct ssh_conn {
+  const char *authlist;       /* List of auth. methods, managed by libssh2 */
+#ifdef USE_LIBSSH2
+  const char *passphrase;     /* pass-phrase to use */
+  char *rsa_pub;              /* path name */
+  char *rsa;                  /* path name */
+  bool authed;                /* the connection has been authenticated fine */
+  sshstate state;             /* always use ssh.c:state() to change state! */
+  sshstate nextstate;         /* the state to goto after stopping */
+  CURLcode actualcode;        /* the actual error code */
+  struct curl_slist *quote_item; /* for the quote option */
+  char *quote_path1;          /* two generic pointers for the QUOTE stuff */
+  char *quote_path2;
+  LIBSSH2_SFTP_ATTRIBUTES quote_attrs; /* used by the SFTP_QUOTE state */
+  bool acceptfail;            /* used by the SFTP_QUOTE (continue if
+                                 quote command fails) */
+  char *homedir;              /* when doing SFTP we figure out home dir in the
+                                 connect phase */
+
+  /* Here's a set of struct members used by the SFTP_READDIR state */
+  LIBSSH2_SFTP_ATTRIBUTES readdir_attrs;
+  char *readdir_filename;
+  char *readdir_longentry;
+  int readdir_len, readdir_totalLen, readdir_currLen;
+  char *readdir_line;
+  char *readdir_linkPath;
+  /* end of READDIR stuff */
+
+  int secondCreateDirs;         /* counter use by the code to see if the
+                                   second attempt has been made to change
+                                   to/create a directory */
+  char *slash_pos;              /* used by the SFTP_CREATE_DIRS state */
+  LIBSSH2_SESSION *ssh_session; /* Secure Shell session */
+  LIBSSH2_CHANNEL *ssh_channel; /* Secure Shell channel handle */
+  LIBSSH2_SFTP *sftp_session;   /* SFTP handle */
+  LIBSSH2_SFTP_HANDLE *sftp_handle;
+  int orig_waitfor;             /* default READ/WRITE bits wait for */
+
+#ifdef HAVE_LIBSSH2_AGENT_API
+  LIBSSH2_AGENT *ssh_agent;     /* proxy to ssh-agent/pageant */
+  struct libssh2_agent_publickey *sshagent_identity,
+                                 *sshagent_prev_identity;
+#endif
+
+  /* note that HAVE_LIBSSH2_KNOWNHOST_API is a define set in the libssh2.h
+     header */
+#ifdef HAVE_LIBSSH2_KNOWNHOST_API
+  LIBSSH2_KNOWNHOSTS *kh;
+#endif
+#endif /* USE_LIBSSH2 */
+};
+
+#ifdef USE_LIBSSH2
+
+/* Feature detection based on version numbers to better work with
+   non-configure platforms */
+
+#if !defined(LIBSSH2_VERSION_NUM) || (LIBSSH2_VERSION_NUM < 0x001000)
+#  error "SCP/SFTP protocols require libssh2 0.16 or later"
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010000
+#define HAVE_LIBSSH2_SFTP_SEEK64 1
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010100
+#define HAVE_LIBSSH2_VERSION 1
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010205
+#define HAVE_LIBSSH2_INIT 1
+#define HAVE_LIBSSH2_EXIT 1
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010206
+#define HAVE_LIBSSH2_KNOWNHOST_CHECKP 1
+#define HAVE_LIBSSH2_SCP_SEND64 1
+#endif
+
+#if LIBSSH2_VERSION_NUM >= 0x010208
+#define HAVE_LIBSSH2_SESSION_HANDSHAKE 1
+#endif
+
+extern const struct Curl_handler Curl_handler_scp;
+extern const struct Curl_handler Curl_handler_sftp;
+
+#endif /* USE_LIBSSH2 */
+
+#endif /* HEADER_CURL_SSH_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/strcase.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/strcase.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/strcase.c	(revision 331)
@@ -0,0 +1,177 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "strcase.h"
+
+/* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
+   its behavior is altered by the current locale. */
+char Curl_raw_toupper(char in)
+{
+#if !defined(CURL_DOES_CONVERSIONS)
+  if(in >= 'a' && in <= 'z')
+    return (char)('A' + in - 'a');
+#else
+  switch(in) {
+  case 'a':
+    return 'A';
+  case 'b':
+    return 'B';
+  case 'c':
+    return 'C';
+  case 'd':
+    return 'D';
+  case 'e':
+    return 'E';
+  case 'f':
+    return 'F';
+  case 'g':
+    return 'G';
+  case 'h':
+    return 'H';
+  case 'i':
+    return 'I';
+  case 'j':
+    return 'J';
+  case 'k':
+    return 'K';
+  case 'l':
+    return 'L';
+  case 'm':
+    return 'M';
+  case 'n':
+    return 'N';
+  case 'o':
+    return 'O';
+  case 'p':
+    return 'P';
+  case 'q':
+    return 'Q';
+  case 'r':
+    return 'R';
+  case 's':
+    return 'S';
+  case 't':
+    return 'T';
+  case 'u':
+    return 'U';
+  case 'v':
+    return 'V';
+  case 'w':
+    return 'W';
+  case 'x':
+    return 'X';
+  case 'y':
+    return 'Y';
+  case 'z':
+    return 'Z';
+  }
+#endif
+
+  return in;
+}
+
+/*
+ * Curl_strcasecompare() is for doing "raw" case insensitive strings. This is
+ * meant to be locale independent and only compare strings we know are safe
+ * for this.  See
+ * https://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for some
+ * further explanation to why this function is necessary.
+ *
+ * The function is capable of comparing a-z case insensitively even for
+ * non-ascii.
+ *
+ * @unittest: 1301
+ */
+
+int Curl_strcasecompare(const char *first, const char *second)
+{
+  while(*first && *second) {
+    if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second))
+      /* get out of the loop as soon as they don't match */
+      break;
+    first++;
+    second++;
+  }
+  /* we do the comparison here (possibly again), just to make sure that if the
+     loop above is skipped because one of the strings reached zero, we must not
+     return this as a successful match */
+  return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second));
+}
+
+int Curl_safe_strcasecompare(const char *first, const char *second)
+{
+  if(first && second)
+    /* both pointers point to something then compare them */
+    return Curl_strcasecompare(first, second);
+
+  /* if both pointers are NULL then treat them as equal */
+  return (NULL == first && NULL == second);
+}
+
+/*
+ * @unittest: 1301
+ */
+int Curl_strncasecompare(const char *first, const char *second, size_t max)
+{
+  while(*first && *second && max) {
+    if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) {
+      break;
+    }
+    max--;
+    first++;
+    second++;
+  }
+  if(0 == max)
+    return 1; /* they are equal this far */
+
+  return Curl_raw_toupper(*first) == Curl_raw_toupper(*second);
+}
+
+/* Copy an upper case version of the string from src to dest.  The
+ * strings may overlap.  No more than n characters of the string are copied
+ * (including any NUL) and the destination string will NOT be
+ * NUL-terminated if that limit is reached.
+ */
+void Curl_strntoupper(char *dest, const char *src, size_t n)
+{
+  if(n < 1)
+    return;
+
+  do {
+    *dest++ = Curl_raw_toupper(*src);
+  } while(*src++ && --n);
+}
+
+/* --- public functions --- */
+
+int curl_strequal(const char *first, const char *second)
+{
+  return Curl_strcasecompare(first, second);
+}
+int curl_strnequal(const char *first, const char *second, size_t max)
+{
+  return Curl_strncasecompare(first, second, max);
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/strcase.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/strcase.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/strcase.h	(revision 331)
@@ -0,0 +1,51 @@
+#ifndef HEADER_CURL_STRCASE_H
+#define HEADER_CURL_STRCASE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h>
+
+/*
+ * Only "raw" case insensitive strings. This is meant to be locale independent
+ * and only compare strings we know are safe for this.
+ *
+ * The function is capable of comparing a-z case insensitively even for
+ * non-ascii.
+ */
+
+#define strcasecompare(a,b) Curl_strcasecompare(a,b)
+#define strncasecompare(a,b,c) Curl_strncasecompare(a,b,c)
+
+int Curl_strcasecompare(const char *first, const char *second);
+int Curl_safe_strcasecompare(const char *first, const char *second);
+int Curl_strncasecompare(const char *first, const char *second, size_t max);
+
+char Curl_raw_toupper(char in);
+
+/* checkprefix() is a shorter version of the above, used when the first
+   argument is zero-byte terminated */
+#define checkprefix(a,b)    curl_strnequal(a,b,strlen(a))
+
+void Curl_strntoupper(char *dest, const char *src, size_t n);
+char Curl_raw_toupper(char in);
+
+#endif /* HEADER_CURL_STRCASE_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/strdup.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/strdup.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/strdup.c	(revision 331)
@@ -0,0 +1,100 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "strdup.h"
+#include "curl_memory.h"
+
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifndef HAVE_STRDUP
+char *curlx_strdup(const char *str)
+{
+  size_t len;
+  char *newstr;
+
+  if(!str)
+    return (char *)NULL;
+
+  len = strlen(str);
+
+  if(len >= ((size_t)-1) / sizeof(char))
+    return (char *)NULL;
+
+  newstr = malloc((len + 1)*sizeof(char));
+  if(!newstr)
+    return (char *)NULL;
+
+  memcpy(newstr, str, (len + 1)*sizeof(char));
+
+  return newstr;
+
+}
+#endif
+
+/***************************************************************************
+ *
+ * Curl_memdup(source, length)
+ *
+ * Copies the 'source' data to a newly allocated buffer (that is
+ * returned). Copies 'length' bytes.
+ *
+ * Returns the new pointer or NULL on failure.
+ *
+ ***************************************************************************/
+void *Curl_memdup(const void *src, size_t length)
+{
+  void *buffer = malloc(length);
+  if(!buffer)
+    return NULL; /* fail */
+
+  memcpy(buffer, src, length);
+
+  return buffer;
+}
+
+/***************************************************************************
+ *
+ * Curl_saferealloc(ptr, size)
+ *
+ * Does a normal realloc(), but will free the data pointer if the realloc
+ * fails. If 'size' is zero, it will free the data and return a failure.
+ *
+ * This convenience function is provided and used to help us avoid a common
+ * mistake pattern when we could pass in a zero, catch the NULL return and end
+ * up free'ing the memory twice.
+ *
+ * Returns the new pointer or NULL on failure.
+ *
+ ***************************************************************************/
+void *Curl_saferealloc(void *ptr, size_t size)
+{
+  void *datap = realloc(ptr, size);
+  if(size && !datap)
+    /* only free 'ptr' if size was non-zero */
+    free(ptr);
+  return datap;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/strdup.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/strdup.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/strdup.h	(revision 331)
@@ -0,0 +1,32 @@
+#ifndef HEADER_CURL_STRDUP_H
+#define HEADER_CURL_STRDUP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifndef HAVE_STRDUP
+extern char *curlx_strdup(const char *str);
+#endif
+void *Curl_memdup(const void *src, size_t buffer_length);
+void *Curl_saferealloc(void *ptr, size_t size);
+
+#endif /* HEADER_CURL_STRDUP_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/strerror.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/strerror.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/strerror.c	(revision 331)
@@ -0,0 +1,1103 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2004 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_STRERROR_R
+#  if (!defined(HAVE_POSIX_STRERROR_R) && \
+       !defined(HAVE_GLIBC_STRERROR_R) && \
+       !defined(HAVE_VXWORKS_STRERROR_R)) || \
+      (defined(HAVE_POSIX_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)) || \
+      (defined(HAVE_GLIBC_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)) || \
+      (defined(HAVE_POSIX_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R))
+#    error "strerror_r MUST be either POSIX, glibc or vxworks-style"
+#  endif
+#endif
+
+#include <curl/curl.h>
+
+#ifdef USE_LIBIDN2
+#include <idn2.h>
+#endif
+
+#ifdef USE_WINDOWS_SSPI
+#include "curl_sspi.h"
+#endif
+
+#include "strerror.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#if defined(WIN32) || defined(_WIN32_WCE)
+#define PRESERVE_WINDOWS_ERROR_CODE
+#endif
+
+const char *
+curl_easy_strerror(CURLcode error)
+{
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  switch(error) {
+  case CURLE_OK:
+    return "No error";
+
+  case CURLE_UNSUPPORTED_PROTOCOL:
+    return "Unsupported protocol";
+
+  case CURLE_FAILED_INIT:
+    return "Failed initialization";
+
+  case CURLE_URL_MALFORMAT:
+    return "URL using bad/illegal format or missing URL";
+
+  case CURLE_NOT_BUILT_IN:
+    return "A requested feature, protocol or option was not found built-in in"
+      " this libcurl due to a build-time decision.";
+
+  case CURLE_COULDNT_RESOLVE_PROXY:
+    return "Couldn't resolve proxy name";
+
+  case CURLE_COULDNT_RESOLVE_HOST:
+    return "Couldn't resolve host name";
+
+  case CURLE_COULDNT_CONNECT:
+    return "Couldn't connect to server";
+
+  case CURLE_WEIRD_SERVER_REPLY:
+    return "Weird server reply";
+
+  case CURLE_REMOTE_ACCESS_DENIED:
+    return "Access denied to remote resource";
+
+  case CURLE_FTP_ACCEPT_FAILED:
+    return "FTP: The server failed to connect to data port";
+
+  case CURLE_FTP_ACCEPT_TIMEOUT:
+    return "FTP: Accepting server connect has timed out";
+
+  case CURLE_FTP_PRET_FAILED:
+    return "FTP: The server did not accept the PRET command.";
+
+  case CURLE_FTP_WEIRD_PASS_REPLY:
+    return "FTP: unknown PASS reply";
+
+  case CURLE_FTP_WEIRD_PASV_REPLY:
+    return "FTP: unknown PASV reply";
+
+  case CURLE_FTP_WEIRD_227_FORMAT:
+    return "FTP: unknown 227 response format";
+
+  case CURLE_FTP_CANT_GET_HOST:
+    return "FTP: can't figure out the host in the PASV response";
+
+  case CURLE_HTTP2:
+    return "Error in the HTTP2 framing layer";
+
+  case CURLE_FTP_COULDNT_SET_TYPE:
+    return "FTP: couldn't set file type";
+
+  case CURLE_PARTIAL_FILE:
+    return "Transferred a partial file";
+
+  case CURLE_FTP_COULDNT_RETR_FILE:
+    return "FTP: couldn't retrieve (RETR failed) the specified file";
+
+  case CURLE_QUOTE_ERROR:
+    return "Quote command returned error";
+
+  case CURLE_HTTP_RETURNED_ERROR:
+    return "HTTP response code said error";
+
+  case CURLE_WRITE_ERROR:
+    return "Failed writing received data to disk/application";
+
+  case CURLE_UPLOAD_FAILED:
+    return "Upload failed (at start/before it took off)";
+
+  case CURLE_READ_ERROR:
+    return "Failed to open/read local data from file/application";
+
+  case CURLE_OUT_OF_MEMORY:
+    return "Out of memory";
+
+  case CURLE_OPERATION_TIMEDOUT:
+    return "Timeout was reached";
+
+  case CURLE_FTP_PORT_FAILED:
+    return "FTP: command PORT failed";
+
+  case CURLE_FTP_COULDNT_USE_REST:
+    return "FTP: command REST failed";
+
+  case CURLE_RANGE_ERROR:
+    return "Requested range was not delivered by the server";
+
+  case CURLE_HTTP_POST_ERROR:
+    return "Internal problem setting up the POST";
+
+  case CURLE_SSL_CONNECT_ERROR:
+    return "SSL connect error";
+
+  case CURLE_BAD_DOWNLOAD_RESUME:
+    return "Couldn't resume download";
+
+  case CURLE_FILE_COULDNT_READ_FILE:
+    return "Couldn't read a file:// file";
+
+  case CURLE_LDAP_CANNOT_BIND:
+    return "LDAP: cannot bind";
+
+  case CURLE_LDAP_SEARCH_FAILED:
+    return "LDAP: search failed";
+
+  case CURLE_FUNCTION_NOT_FOUND:
+    return "A required function in the library was not found";
+
+  case CURLE_ABORTED_BY_CALLBACK:
+    return "Operation was aborted by an application callback";
+
+  case CURLE_BAD_FUNCTION_ARGUMENT:
+    return "A libcurl function was given a bad argument";
+
+  case CURLE_INTERFACE_FAILED:
+    return "Failed binding local connection end";
+
+  case CURLE_TOO_MANY_REDIRECTS :
+    return "Number of redirects hit maximum amount";
+
+  case CURLE_UNKNOWN_OPTION:
+    return "An unknown option was passed in to libcurl";
+
+  case CURLE_TELNET_OPTION_SYNTAX :
+    return "Malformed telnet option";
+
+  case CURLE_PEER_FAILED_VERIFICATION:
+    return "SSL peer certificate or SSH remote key was not OK";
+
+  case CURLE_GOT_NOTHING:
+    return "Server returned nothing (no headers, no data)";
+
+  case CURLE_SSL_ENGINE_NOTFOUND:
+    return "SSL crypto engine not found";
+
+  case CURLE_SSL_ENGINE_SETFAILED:
+    return "Can not set SSL crypto engine as default";
+
+  case CURLE_SSL_ENGINE_INITFAILED:
+    return "Failed to initialise SSL crypto engine";
+
+  case CURLE_SEND_ERROR:
+    return "Failed sending data to the peer";
+
+  case CURLE_RECV_ERROR:
+    return "Failure when receiving data from the peer";
+
+  case CURLE_SSL_CERTPROBLEM:
+    return "Problem with the local SSL certificate";
+
+  case CURLE_SSL_CIPHER:
+    return "Couldn't use specified SSL cipher";
+
+  case CURLE_SSL_CACERT:
+    return "Peer certificate cannot be authenticated with given CA "
+      "certificates";
+
+  case CURLE_SSL_CACERT_BADFILE:
+    return "Problem with the SSL CA cert (path? access rights?)";
+
+  case CURLE_BAD_CONTENT_ENCODING:
+    return "Unrecognized or bad HTTP Content or Transfer-Encoding";
+
+  case CURLE_LDAP_INVALID_URL:
+    return "Invalid LDAP URL";
+
+  case CURLE_FILESIZE_EXCEEDED:
+    return "Maximum file size exceeded";
+
+  case CURLE_USE_SSL_FAILED:
+    return "Requested SSL level failed";
+
+  case CURLE_SSL_SHUTDOWN_FAILED:
+    return "Failed to shut down the SSL connection";
+
+  case CURLE_SSL_CRL_BADFILE:
+    return "Failed to load CRL file (path? access rights?, format?)";
+
+  case CURLE_SSL_ISSUER_ERROR:
+    return "Issuer check against peer certificate failed";
+
+  case CURLE_SEND_FAIL_REWIND:
+    return "Send failed since rewinding of the data stream failed";
+
+  case CURLE_LOGIN_DENIED:
+    return "Login denied";
+
+  case CURLE_TFTP_NOTFOUND:
+    return "TFTP: File Not Found";
+
+  case CURLE_TFTP_PERM:
+    return "TFTP: Access Violation";
+
+  case CURLE_REMOTE_DISK_FULL:
+    return "Disk full or allocation exceeded";
+
+  case CURLE_TFTP_ILLEGAL:
+    return "TFTP: Illegal operation";
+
+  case CURLE_TFTP_UNKNOWNID:
+    return "TFTP: Unknown transfer ID";
+
+  case CURLE_REMOTE_FILE_EXISTS:
+    return "Remote file already exists";
+
+  case CURLE_TFTP_NOSUCHUSER:
+    return "TFTP: No such user";
+
+  case CURLE_CONV_FAILED:
+    return "Conversion failed";
+
+  case CURLE_CONV_REQD:
+    return "Caller must register CURLOPT_CONV_ callback options";
+
+  case CURLE_REMOTE_FILE_NOT_FOUND:
+    return "Remote file not found";
+
+  case CURLE_SSH:
+    return "Error in the SSH layer";
+
+  case CURLE_AGAIN:
+    return "Socket not ready for send/recv";
+
+  case CURLE_RTSP_CSEQ_ERROR:
+    return "RTSP CSeq mismatch or invalid CSeq";
+
+  case CURLE_RTSP_SESSION_ERROR:
+    return "RTSP session error";
+
+  case CURLE_FTP_BAD_FILE_LIST:
+    return "Unable to parse FTP file list";
+
+  case CURLE_CHUNK_FAILED:
+    return "Chunk callback failed";
+
+  case CURLE_NO_CONNECTION_AVAILABLE:
+    return "The max connection limit is reached";
+
+  case CURLE_SSL_PINNEDPUBKEYNOTMATCH:
+    return "SSL public key does not match pinned public key";
+
+  case CURLE_SSL_INVALIDCERTSTATUS:
+    return "SSL server certificate status verification FAILED";
+
+  case CURLE_HTTP2_STREAM:
+    return "Stream error in the HTTP/2 framing layer";
+
+    /* error codes not used by current libcurl */
+  case CURLE_OBSOLETE20:
+  case CURLE_OBSOLETE24:
+  case CURLE_OBSOLETE29:
+  case CURLE_OBSOLETE32:
+  case CURLE_OBSOLETE40:
+  case CURLE_OBSOLETE44:
+  case CURLE_OBSOLETE46:
+  case CURLE_OBSOLETE50:
+  case CURLE_OBSOLETE57:
+  case CURL_LAST:
+    break;
+  }
+  /*
+   * By using a switch, gcc -Wall will complain about enum values
+   * which do not appear, helping keep this function up-to-date.
+   * By using gcc -Wall -Werror, you can't forget.
+   *
+   * A table would not have the same benefit.  Most compilers will
+   * generate code very similar to a table in any case, so there
+   * is little performance gain from a table.  And something is broken
+   * for the user's application, anyways, so does it matter how fast
+   * it _doesn't_ work?
+   *
+   * The line number for the error will be near this comment, which
+   * is why it is here, and not at the start of the switch.
+   */
+  return "Unknown error";
+#else
+  if(!error)
+    return "No error";
+  else
+    return "Error";
+#endif
+}
+
+const char *
+curl_multi_strerror(CURLMcode error)
+{
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  switch(error) {
+  case CURLM_CALL_MULTI_PERFORM:
+    return "Please call curl_multi_perform() soon";
+
+  case CURLM_OK:
+    return "No error";
+
+  case CURLM_BAD_HANDLE:
+    return "Invalid multi handle";
+
+  case CURLM_BAD_EASY_HANDLE:
+    return "Invalid easy handle";
+
+  case CURLM_OUT_OF_MEMORY:
+    return "Out of memory";
+
+  case CURLM_INTERNAL_ERROR:
+    return "Internal error";
+
+  case CURLM_BAD_SOCKET:
+    return "Invalid socket argument";
+
+  case CURLM_UNKNOWN_OPTION:
+    return "Unknown option";
+
+  case CURLM_ADDED_ALREADY:
+    return "The easy handle is already added to a multi handle";
+
+  case CURLM_LAST:
+    break;
+  }
+
+  return "Unknown error";
+#else
+  if(error == CURLM_OK)
+    return "No error";
+  else
+    return "Error";
+#endif
+}
+
+const char *
+curl_share_strerror(CURLSHcode error)
+{
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  switch(error) {
+  case CURLSHE_OK:
+    return "No error";
+
+  case CURLSHE_BAD_OPTION:
+    return "Unknown share option";
+
+  case CURLSHE_IN_USE:
+    return "Share currently in use";
+
+  case CURLSHE_INVALID:
+    return "Invalid share handle";
+
+  case CURLSHE_NOMEM:
+    return "Out of memory";
+
+  case CURLSHE_NOT_BUILT_IN:
+    return "Feature not enabled in this library";
+
+  case CURLSHE_LAST:
+    break;
+  }
+
+  return "CURLSHcode unknown";
+#else
+  if(error == CURLSHE_OK)
+    return "No error";
+  else
+    return "Error";
+#endif
+}
+
+#ifdef USE_WINSOCK
+
+/* This function handles most / all (?) Winsock errors curl is able to produce.
+ */
+static const char *
+get_winsock_error (int err, char *buf, size_t len)
+{
+#ifdef PRESERVE_WINDOWS_ERROR_CODE
+  DWORD old_win_err = GetLastError();
+#endif
+  int old_errno = errno;
+  const char *p;
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  switch(err) {
+  case WSAEINTR:
+    p = "Call interrupted";
+    break;
+  case WSAEBADF:
+    p = "Bad file";
+    break;
+  case WSAEACCES:
+    p = "Bad access";
+    break;
+  case WSAEFAULT:
+    p = "Bad argument";
+    break;
+  case WSAEINVAL:
+    p = "Invalid arguments";
+    break;
+  case WSAEMFILE:
+    p = "Out of file descriptors";
+    break;
+  case WSAEWOULDBLOCK:
+    p = "Call would block";
+    break;
+  case WSAEINPROGRESS:
+  case WSAEALREADY:
+    p = "Blocking call in progress";
+    break;
+  case WSAENOTSOCK:
+    p = "Descriptor is not a socket";
+    break;
+  case WSAEDESTADDRREQ:
+    p = "Need destination address";
+    break;
+  case WSAEMSGSIZE:
+    p = "Bad message size";
+    break;
+  case WSAEPROTOTYPE:
+    p = "Bad protocol";
+    break;
+  case WSAENOPROTOOPT:
+    p = "Protocol option is unsupported";
+    break;
+  case WSAEPROTONOSUPPORT:
+    p = "Protocol is unsupported";
+    break;
+  case WSAESOCKTNOSUPPORT:
+    p = "Socket is unsupported";
+    break;
+  case WSAEOPNOTSUPP:
+    p = "Operation not supported";
+    break;
+  case WSAEAFNOSUPPORT:
+    p = "Address family not supported";
+    break;
+  case WSAEPFNOSUPPORT:
+    p = "Protocol family not supported";
+    break;
+  case WSAEADDRINUSE:
+    p = "Address already in use";
+    break;
+  case WSAEADDRNOTAVAIL:
+    p = "Address not available";
+    break;
+  case WSAENETDOWN:
+    p = "Network down";
+    break;
+  case WSAENETUNREACH:
+    p = "Network unreachable";
+    break;
+  case WSAENETRESET:
+    p = "Network has been reset";
+    break;
+  case WSAECONNABORTED:
+    p = "Connection was aborted";
+    break;
+  case WSAECONNRESET:
+    p = "Connection was reset";
+    break;
+  case WSAENOBUFS:
+    p = "No buffer space";
+    break;
+  case WSAEISCONN:
+    p = "Socket is already connected";
+    break;
+  case WSAENOTCONN:
+    p = "Socket is not connected";
+    break;
+  case WSAESHUTDOWN:
+    p = "Socket has been shut down";
+    break;
+  case WSAETOOMANYREFS:
+    p = "Too many references";
+    break;
+  case WSAETIMEDOUT:
+    p = "Timed out";
+    break;
+  case WSAECONNREFUSED:
+    p = "Connection refused";
+    break;
+  case WSAELOOP:
+    p = "Loop??";
+    break;
+  case WSAENAMETOOLONG:
+    p = "Name too long";
+    break;
+  case WSAEHOSTDOWN:
+    p = "Host down";
+    break;
+  case WSAEHOSTUNREACH:
+    p = "Host unreachable";
+    break;
+  case WSAENOTEMPTY:
+    p = "Not empty";
+    break;
+  case WSAEPROCLIM:
+    p = "Process limit reached";
+    break;
+  case WSAEUSERS:
+    p = "Too many users";
+    break;
+  case WSAEDQUOT:
+    p = "Bad quota";
+    break;
+  case WSAESTALE:
+    p = "Something is stale";
+    break;
+  case WSAEREMOTE:
+    p = "Remote error";
+    break;
+#ifdef WSAEDISCON  /* missing in SalfordC! */
+  case WSAEDISCON:
+    p = "Disconnected";
+    break;
+#endif
+    /* Extended Winsock errors */
+  case WSASYSNOTREADY:
+    p = "Winsock library is not ready";
+    break;
+  case WSANOTINITIALISED:
+    p = "Winsock library not initialised";
+    break;
+  case WSAVERNOTSUPPORTED:
+    p = "Winsock version not supported";
+    break;
+
+    /* getXbyY() errors (already handled in herrmsg):
+     * Authoritative Answer: Host not found */
+  case WSAHOST_NOT_FOUND:
+    p = "Host not found";
+    break;
+
+    /* Non-Authoritative: Host not found, or SERVERFAIL */
+  case WSATRY_AGAIN:
+    p = "Host not found, try again";
+    break;
+
+    /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
+  case WSANO_RECOVERY:
+    p = "Unrecoverable error in call to nameserver";
+    break;
+
+    /* Valid name, no data record of requested type */
+  case WSANO_DATA:
+    p = "No data record of requested type";
+    break;
+
+  default:
+    return NULL;
+  }
+#else
+  if(!err)
+    return NULL;
+  else
+    p = "error";
+#endif
+  strncpy(buf, p, len);
+  buf [len-1] = '\0';
+
+  if(errno != old_errno)
+    errno = old_errno;
+
+#ifdef PRESERVE_WINDOWS_ERROR_CODE
+  if(old_win_err != GetLastError())
+    SetLastError(old_win_err);
+#endif
+
+  return buf;
+}
+#endif   /* USE_WINSOCK */
+
+/*
+ * Our thread-safe and smart strerror() replacement.
+ *
+ * The 'err' argument passed in to this function MUST be a true errno number
+ * as reported on this system. We do no range checking on the number before
+ * we pass it to the "number-to-message" conversion function and there might
+ * be systems that don't do proper range checking in there themselves.
+ *
+ * We don't do range checking (on systems other than Windows) since there is
+ * no good reliable and portable way to do it.
+ */
+const char *Curl_strerror(struct connectdata *conn, int err)
+{
+#ifdef PRESERVE_WINDOWS_ERROR_CODE
+  DWORD old_win_err = GetLastError();
+#endif
+  int old_errno = errno;
+  char *buf, *p;
+  size_t max;
+
+  DEBUGASSERT(conn);
+  DEBUGASSERT(err >= 0);
+
+  buf = conn->syserr_buf;
+  max = sizeof(conn->syserr_buf)-1;
+  *buf = '\0';
+
+#ifdef USE_WINSOCK
+
+#ifdef _WIN32_WCE
+  {
+    wchar_t wbuf[256];
+    wbuf[0] = L'\0';
+
+    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
+                  LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL);
+    wcstombs(buf, wbuf, max);
+  }
+#else
+  /* 'sys_nerr' is the maximum errno number, it is not widely portable */
+  if(err >= 0 && err < sys_nerr)
+    strncpy(buf, strerror(err), max);
+  else {
+    if(!get_winsock_error(err, buf, max) &&
+       !FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
+                       LANG_NEUTRAL, buf, (DWORD)max, NULL))
+      snprintf(buf, max, "Unknown error %d (%#x)", err, err);
+  }
+#endif
+
+#else /* not USE_WINSOCK coming up */
+
+#if defined(HAVE_STRERROR_R) && defined(HAVE_POSIX_STRERROR_R)
+ /*
+  * The POSIX-style strerror_r() may set errno to ERANGE if insufficient
+  * storage is supplied via 'strerrbuf' and 'buflen' to hold the generated
+  * message string, or EINVAL if 'errnum' is not a valid error number.
+  */
+  if(0 != strerror_r(err, buf, max)) {
+    if('\0' == buf[0])
+      snprintf(buf, max, "Unknown error %d", err);
+  }
+#elif defined(HAVE_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R)
+ /*
+  * The glibc-style strerror_r() only *might* use the buffer we pass to
+  * the function, but it always returns the error message as a pointer,
+  * so we must copy that string unconditionally (if non-NULL).
+  */
+  {
+    char buffer[256];
+    char *msg = strerror_r(err, buffer, sizeof(buffer));
+    if(msg)
+      strncpy(buf, msg, max);
+    else
+      snprintf(buf, max, "Unknown error %d", err);
+  }
+#elif defined(HAVE_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)
+ /*
+  * The vxworks-style strerror_r() does use the buffer we pass to the function.
+  * The buffer size should be at least NAME_MAX (256)
+  */
+  {
+    char buffer[256];
+    if(OK == strerror_r(err, buffer))
+      strncpy(buf, buffer, max);
+    else
+      snprintf(buf, max, "Unknown error %d", err);
+  }
+#else
+  {
+    char *msg = strerror(err);
+    if(msg)
+      strncpy(buf, msg, max);
+    else
+      snprintf(buf, max, "Unknown error %d", err);
+  }
+#endif
+
+#endif /* end of ! USE_WINSOCK */
+
+  buf[max] = '\0'; /* make sure the string is zero terminated */
+
+  /* strip trailing '\r\n' or '\n'. */
+  p = strrchr(buf, '\n');
+  if(p && (p - buf) >= 2)
+    *p = '\0';
+  p = strrchr(buf, '\r');
+  if(p && (p - buf) >= 1)
+    *p = '\0';
+
+  if(errno != old_errno)
+    errno = old_errno;
+
+#ifdef PRESERVE_WINDOWS_ERROR_CODE
+  if(old_win_err != GetLastError())
+    SetLastError(old_win_err);
+#endif
+
+  return buf;
+}
+
+#ifdef USE_WINDOWS_SSPI
+const char *Curl_sspi_strerror (struct connectdata *conn, int err)
+{
+#ifdef PRESERVE_WINDOWS_ERROR_CODE
+  DWORD old_win_err = GetLastError();
+#endif
+  int old_errno = errno;
+  const char *txt;
+  char *outbuf;
+  size_t outmax;
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  char txtbuf[80];
+  char msgbuf[sizeof(conn->syserr_buf)];
+  char *p, *str, *msg = NULL;
+  bool msg_formatted = FALSE;
+#endif
+
+  DEBUGASSERT(conn);
+
+  outbuf = conn->syserr_buf;
+  outmax = sizeof(conn->syserr_buf)-1;
+  *outbuf = '\0';
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+
+  switch(err) {
+    case SEC_E_OK:
+      txt = "No error";
+      break;
+    case CRYPT_E_REVOKED:
+      txt = "CRYPT_E_REVOKED";
+      break;
+    case SEC_E_ALGORITHM_MISMATCH:
+      txt = "SEC_E_ALGORITHM_MISMATCH";
+      break;
+    case SEC_E_BAD_BINDINGS:
+      txt = "SEC_E_BAD_BINDINGS";
+      break;
+    case SEC_E_BAD_PKGID:
+      txt = "SEC_E_BAD_PKGID";
+      break;
+    case SEC_E_BUFFER_TOO_SMALL:
+      txt = "SEC_E_BUFFER_TOO_SMALL";
+      break;
+    case SEC_E_CANNOT_INSTALL:
+      txt = "SEC_E_CANNOT_INSTALL";
+      break;
+    case SEC_E_CANNOT_PACK:
+      txt = "SEC_E_CANNOT_PACK";
+      break;
+    case SEC_E_CERT_EXPIRED:
+      txt = "SEC_E_CERT_EXPIRED";
+      break;
+    case SEC_E_CERT_UNKNOWN:
+      txt = "SEC_E_CERT_UNKNOWN";
+      break;
+    case SEC_E_CERT_WRONG_USAGE:
+      txt = "SEC_E_CERT_WRONG_USAGE";
+      break;
+    case SEC_E_CONTEXT_EXPIRED:
+      txt = "SEC_E_CONTEXT_EXPIRED";
+      break;
+    case SEC_E_CROSSREALM_DELEGATION_FAILURE:
+      txt = "SEC_E_CROSSREALM_DELEGATION_FAILURE";
+      break;
+    case SEC_E_CRYPTO_SYSTEM_INVALID:
+      txt = "SEC_E_CRYPTO_SYSTEM_INVALID";
+      break;
+    case SEC_E_DECRYPT_FAILURE:
+      txt = "SEC_E_DECRYPT_FAILURE";
+      break;
+    case SEC_E_DELEGATION_POLICY:
+      txt = "SEC_E_DELEGATION_POLICY";
+      break;
+    case SEC_E_DELEGATION_REQUIRED:
+      txt = "SEC_E_DELEGATION_REQUIRED";
+      break;
+    case SEC_E_DOWNGRADE_DETECTED:
+      txt = "SEC_E_DOWNGRADE_DETECTED";
+      break;
+    case SEC_E_ENCRYPT_FAILURE:
+      txt = "SEC_E_ENCRYPT_FAILURE";
+      break;
+    case SEC_E_ILLEGAL_MESSAGE:
+      txt = "SEC_E_ILLEGAL_MESSAGE";
+      break;
+    case SEC_E_INCOMPLETE_CREDENTIALS:
+      txt = "SEC_E_INCOMPLETE_CREDENTIALS";
+      break;
+    case SEC_E_INCOMPLETE_MESSAGE:
+      txt = "SEC_E_INCOMPLETE_MESSAGE";
+      break;
+    case SEC_E_INSUFFICIENT_MEMORY:
+      txt = "SEC_E_INSUFFICIENT_MEMORY";
+      break;
+    case SEC_E_INTERNAL_ERROR:
+      txt = "SEC_E_INTERNAL_ERROR";
+      break;
+    case SEC_E_INVALID_HANDLE:
+      txt = "SEC_E_INVALID_HANDLE";
+      break;
+    case SEC_E_INVALID_PARAMETER:
+      txt = "SEC_E_INVALID_PARAMETER";
+      break;
+    case SEC_E_INVALID_TOKEN:
+      txt = "SEC_E_INVALID_TOKEN";
+      break;
+    case SEC_E_ISSUING_CA_UNTRUSTED:
+      txt = "SEC_E_ISSUING_CA_UNTRUSTED";
+      break;
+    case SEC_E_ISSUING_CA_UNTRUSTED_KDC:
+      txt = "SEC_E_ISSUING_CA_UNTRUSTED_KDC";
+      break;
+    case SEC_E_KDC_CERT_EXPIRED:
+      txt = "SEC_E_KDC_CERT_EXPIRED";
+      break;
+    case SEC_E_KDC_CERT_REVOKED:
+      txt = "SEC_E_KDC_CERT_REVOKED";
+      break;
+    case SEC_E_KDC_INVALID_REQUEST:
+      txt = "SEC_E_KDC_INVALID_REQUEST";
+      break;
+    case SEC_E_KDC_UNABLE_TO_REFER:
+      txt = "SEC_E_KDC_UNABLE_TO_REFER";
+      break;
+    case SEC_E_KDC_UNKNOWN_ETYPE:
+      txt = "SEC_E_KDC_UNKNOWN_ETYPE";
+      break;
+    case SEC_E_LOGON_DENIED:
+      txt = "SEC_E_LOGON_DENIED";
+      break;
+    case SEC_E_MAX_REFERRALS_EXCEEDED:
+      txt = "SEC_E_MAX_REFERRALS_EXCEEDED";
+      break;
+    case SEC_E_MESSAGE_ALTERED:
+      txt = "SEC_E_MESSAGE_ALTERED";
+      break;
+    case SEC_E_MULTIPLE_ACCOUNTS:
+      txt = "SEC_E_MULTIPLE_ACCOUNTS";
+      break;
+    case SEC_E_MUST_BE_KDC:
+      txt = "SEC_E_MUST_BE_KDC";
+      break;
+    case SEC_E_NOT_OWNER:
+      txt = "SEC_E_NOT_OWNER";
+      break;
+    case SEC_E_NO_AUTHENTICATING_AUTHORITY:
+      txt = "SEC_E_NO_AUTHENTICATING_AUTHORITY";
+      break;
+    case SEC_E_NO_CREDENTIALS:
+      txt = "SEC_E_NO_CREDENTIALS";
+      break;
+    case SEC_E_NO_IMPERSONATION:
+      txt = "SEC_E_NO_IMPERSONATION";
+      break;
+    case SEC_E_NO_IP_ADDRESSES:
+      txt = "SEC_E_NO_IP_ADDRESSES";
+      break;
+    case SEC_E_NO_KERB_KEY:
+      txt = "SEC_E_NO_KERB_KEY";
+      break;
+    case SEC_E_NO_PA_DATA:
+      txt = "SEC_E_NO_PA_DATA";
+      break;
+    case SEC_E_NO_S4U_PROT_SUPPORT:
+      txt = "SEC_E_NO_S4U_PROT_SUPPORT";
+      break;
+    case SEC_E_NO_TGT_REPLY:
+      txt = "SEC_E_NO_TGT_REPLY";
+      break;
+    case SEC_E_OUT_OF_SEQUENCE:
+      txt = "SEC_E_OUT_OF_SEQUENCE";
+      break;
+    case SEC_E_PKINIT_CLIENT_FAILURE:
+      txt = "SEC_E_PKINIT_CLIENT_FAILURE";
+      break;
+    case SEC_E_PKINIT_NAME_MISMATCH:
+      txt = "SEC_E_PKINIT_NAME_MISMATCH";
+      break;
+    case SEC_E_POLICY_NLTM_ONLY:
+      txt = "SEC_E_POLICY_NLTM_ONLY";
+      break;
+    case SEC_E_QOP_NOT_SUPPORTED:
+      txt = "SEC_E_QOP_NOT_SUPPORTED";
+      break;
+    case SEC_E_REVOCATION_OFFLINE_C:
+      txt = "SEC_E_REVOCATION_OFFLINE_C";
+      break;
+    case SEC_E_REVOCATION_OFFLINE_KDC:
+      txt = "SEC_E_REVOCATION_OFFLINE_KDC";
+      break;
+    case SEC_E_SECPKG_NOT_FOUND:
+      txt = "SEC_E_SECPKG_NOT_FOUND";
+      break;
+    case SEC_E_SECURITY_QOS_FAILED:
+      txt = "SEC_E_SECURITY_QOS_FAILED";
+      break;
+    case SEC_E_SHUTDOWN_IN_PROGRESS:
+      txt = "SEC_E_SHUTDOWN_IN_PROGRESS";
+      break;
+    case SEC_E_SMARTCARD_CERT_EXPIRED:
+      txt = "SEC_E_SMARTCARD_CERT_EXPIRED";
+      break;
+    case SEC_E_SMARTCARD_CERT_REVOKED:
+      txt = "SEC_E_SMARTCARD_CERT_REVOKED";
+      break;
+    case SEC_E_SMARTCARD_LOGON_REQUIRED:
+      txt = "SEC_E_SMARTCARD_LOGON_REQUIRED";
+      break;
+    case SEC_E_STRONG_CRYPTO_NOT_SUPPORTED:
+      txt = "SEC_E_STRONG_CRYPTO_NOT_SUPPORTED";
+      break;
+    case SEC_E_TARGET_UNKNOWN:
+      txt = "SEC_E_TARGET_UNKNOWN";
+      break;
+    case SEC_E_TIME_SKEW:
+      txt = "SEC_E_TIME_SKEW";
+      break;
+    case SEC_E_TOO_MANY_PRINCIPALS:
+      txt = "SEC_E_TOO_MANY_PRINCIPALS";
+      break;
+    case SEC_E_UNFINISHED_CONTEXT_DELETED:
+      txt = "SEC_E_UNFINISHED_CONTEXT_DELETED";
+      break;
+    case SEC_E_UNKNOWN_CREDENTIALS:
+      txt = "SEC_E_UNKNOWN_CREDENTIALS";
+      break;
+    case SEC_E_UNSUPPORTED_FUNCTION:
+      txt = "SEC_E_UNSUPPORTED_FUNCTION";
+      break;
+    case SEC_E_UNSUPPORTED_PREAUTH:
+      txt = "SEC_E_UNSUPPORTED_PREAUTH";
+      break;
+    case SEC_E_UNTRUSTED_ROOT:
+      txt = "SEC_E_UNTRUSTED_ROOT";
+      break;
+    case SEC_E_WRONG_CREDENTIAL_HANDLE:
+      txt = "SEC_E_WRONG_CREDENTIAL_HANDLE";
+      break;
+    case SEC_E_WRONG_PRINCIPAL:
+      txt = "SEC_E_WRONG_PRINCIPAL";
+      break;
+    case SEC_I_COMPLETE_AND_CONTINUE:
+      txt = "SEC_I_COMPLETE_AND_CONTINUE";
+      break;
+    case SEC_I_COMPLETE_NEEDED:
+      txt = "SEC_I_COMPLETE_NEEDED";
+      break;
+    case SEC_I_CONTEXT_EXPIRED:
+      txt = "SEC_I_CONTEXT_EXPIRED";
+      break;
+    case SEC_I_CONTINUE_NEEDED:
+      txt = "SEC_I_CONTINUE_NEEDED";
+      break;
+    case SEC_I_INCOMPLETE_CREDENTIALS:
+      txt = "SEC_I_INCOMPLETE_CREDENTIALS";
+      break;
+    case SEC_I_LOCAL_LOGON:
+      txt = "SEC_I_LOCAL_LOGON";
+      break;
+    case SEC_I_NO_LSA_CONTEXT:
+      txt = "SEC_I_NO_LSA_CONTEXT";
+      break;
+    case SEC_I_RENEGOTIATE:
+      txt = "SEC_I_RENEGOTIATE";
+      break;
+    case SEC_I_SIGNATURE_NEEDED:
+      txt = "SEC_I_SIGNATURE_NEEDED";
+      break;
+    default:
+      txt = "Unknown error";
+  }
+
+  if(err == SEC_E_OK)
+    strncpy(outbuf, txt, outmax);
+  else if(err == SEC_E_ILLEGAL_MESSAGE)
+    snprintf(outbuf, outmax,
+             "SEC_E_ILLEGAL_MESSAGE (0x%08X) - This error usually occurs "
+             "when a fatal SSL/TLS alert is received (e.g. handshake failed). "
+             "More detail may be available in the Windows System event log.",
+             err);
+  else {
+    str = txtbuf;
+    snprintf(txtbuf, sizeof(txtbuf), "%s (0x%08X)", txt, err);
+    txtbuf[sizeof(txtbuf)-1] = '\0';
+
+#ifdef _WIN32_WCE
+    {
+      wchar_t wbuf[256];
+      wbuf[0] = L'\0';
+
+      if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+                       FORMAT_MESSAGE_IGNORE_INSERTS,
+                       NULL, err, LANG_NEUTRAL,
+                       wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) {
+        wcstombs(msgbuf, wbuf, sizeof(msgbuf)-1);
+        msg_formatted = TRUE;
+      }
+    }
+#else
+    if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
+                      FORMAT_MESSAGE_IGNORE_INSERTS,
+                      NULL, err, LANG_NEUTRAL,
+                      msgbuf, sizeof(msgbuf)-1, NULL)) {
+      msg_formatted = TRUE;
+    }
+#endif
+    if(msg_formatted) {
+      msgbuf[sizeof(msgbuf)-1] = '\0';
+      /* strip trailing '\r\n' or '\n' */
+      p = strrchr(msgbuf, '\n');
+      if(p && (p - msgbuf) >= 2)
+        *p = '\0';
+      p = strrchr(msgbuf, '\r');
+      if(p && (p - msgbuf) >= 1)
+        *p = '\0';
+      msg = msgbuf;
+    }
+    if(msg)
+      snprintf(outbuf, outmax, "%s - %s", str, msg);
+    else
+      strncpy(outbuf, str, outmax);
+  }
+
+#else
+
+  if(err == SEC_E_OK)
+    txt = "No error";
+  else
+    txt = "Error";
+
+  strncpy(outbuf, txt, outmax);
+
+#endif
+
+  outbuf[outmax] = '\0';
+
+  if(errno != old_errno)
+    errno = old_errno;
+
+#ifdef PRESERVE_WINDOWS_ERROR_CODE
+  if(old_win_err != GetLastError())
+    SetLastError(old_win_err);
+#endif
+
+  return outbuf;
+}
+#endif /* USE_WINDOWS_SSPI */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/strerror.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/strerror.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/strerror.h	(revision 331)
@@ -0,0 +1,37 @@
+#ifndef HEADER_CURL_STRERROR_H
+#define HEADER_CURL_STRERROR_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "urldata.h"
+
+const char *Curl_strerror (struct connectdata *conn, int err);
+
+#ifdef USE_LIBIDN2
+const char *Curl_idn_strerror (struct connectdata *conn, int err);
+#endif
+
+#ifdef USE_WINDOWS_SSPI
+const char *Curl_sspi_strerror (struct connectdata *conn, int err);
+#endif
+
+#endif /* HEADER_CURL_STRERROR_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/strtok.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/strtok.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/strtok.c	(revision 331)
@@ -0,0 +1,66 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef HAVE_STRTOK_R
+#include <stddef.h>
+
+#include "strtok.h"
+
+char *
+Curl_strtok_r(char *ptr, const char *sep, char **end)
+{
+  if(!ptr)
+    /* we got NULL input so then we get our last position instead */
+    ptr = *end;
+
+  /* pass all letters that are including in the separator string */
+  while(*ptr && strchr(sep, *ptr))
+    ++ptr;
+
+  if(*ptr) {
+    /* so this is where the next piece of string starts */
+    char *start = ptr;
+
+    /* set the end pointer to the first byte after the start */
+    *end = start + 1;
+
+    /* scan through the string to find where it ends, it ends on a
+       null byte or a character that exists in the separator string */
+    while(**end && !strchr(sep, **end))
+      ++*end;
+
+    if(**end) {
+      /* the end is not a null byte */
+      **end = '\0';  /* zero terminate it! */
+      ++*end;        /* advance the last pointer to beyond the null byte */
+    }
+
+    return start; /* return the position where the string starts */
+  }
+
+  /* we ended up on a null byte, there are no more strings to find! */
+  return NULL;
+}
+
+#endif /* this was only compiled if strtok_r wasn't present */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/strtok.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/strtok.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/strtok.h	(revision 331)
@@ -0,0 +1,34 @@
+#ifndef HEADER_CURL_STRTOK_H
+#define HEADER_CURL_STRTOK_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+#include <stddef.h>
+
+#ifndef HAVE_STRTOK_R
+char *Curl_strtok_r(char *s, const char *delim, char **last);
+#define strtok_r Curl_strtok_r
+#else
+#include <string.h>
+#endif
+
+#endif /* HEADER_CURL_STRTOK_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/strtoofft.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/strtoofft.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/strtoofft.c	(revision 331)
@@ -0,0 +1,244 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <errno.h>
+#include "curl_setup.h"
+
+#include "strtoofft.h"
+
+/*
+ * NOTE:
+ *
+ * In the ISO C standard (IEEE Std 1003.1), there is a strtoimax() function we
+ * could use in case strtoll() doesn't exist...  See
+ * https://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html
+ */
+
+#if (SIZEOF_CURL_OFF_T > SIZEOF_LONG)
+#  ifdef HAVE_STRTOLL
+#    define strtooff strtoll
+#  else
+#    if defined(_MSC_VER) && (_MSC_VER >= 1300) && (_INTEGRAL_MAX_BITS >= 64)
+#      if defined(_SAL_VERSION)
+         _Check_return_ _CRTIMP __int64 __cdecl _strtoi64(
+             _In_z_ const char *_String,
+             _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix);
+#      else
+         _CRTIMP __int64 __cdecl _strtoi64(const char *_String,
+                                           char **_EndPtr, int _Radix);
+#      endif
+#      define strtooff _strtoi64
+#    else
+#      define PRIVATE_STRTOOFF 1
+#    endif
+#  endif
+#else
+#  define strtooff strtol
+#endif
+
+#ifdef PRIVATE_STRTOOFF
+
+/* Range tests can be used for alphanum decoding if characters are consecutive,
+   like in ASCII. Else an array is scanned. Determine this condition now. */
+
+#if('9' - '0') != 9 || ('Z' - 'A') != 25 || ('z' - 'a') != 25
+
+#define NO_RANGE_TEST
+
+static const char valchars[] =
+            "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+#endif
+
+static int get_char(char c, int base);
+
+/**
+ * Custom version of the strtooff function.  This extracts a curl_off_t
+ * value from the given input string and returns it.
+ */
+static curl_off_t strtooff(const char *nptr, char **endptr, int base)
+{
+  char *end;
+  int is_negative = 0;
+  int overflow;
+  int i;
+  curl_off_t value = 0;
+  curl_off_t newval;
+
+  /* Skip leading whitespace. */
+  end = (char *)nptr;
+  while(ISSPACE(end[0])) {
+    end++;
+  }
+
+  /* Handle the sign, if any. */
+  if(end[0] == '-') {
+    is_negative = 1;
+    end++;
+  }
+  else if(end[0] == '+') {
+    end++;
+  }
+  else if(end[0] == '\0') {
+    /* We had nothing but perhaps some whitespace -- there was no number. */
+    if(endptr) {
+      *endptr = end;
+    }
+    return 0;
+  }
+
+  /* Handle special beginnings, if present and allowed. */
+  if(end[0] == '0' && end[1] == 'x') {
+    if(base == 16 || base == 0) {
+      end += 2;
+      base = 16;
+    }
+  }
+  else if(end[0] == '0') {
+    if(base == 8 || base == 0) {
+      end++;
+      base = 8;
+    }
+  }
+
+  /* Matching strtol, if the base is 0 and it doesn't look like
+   * the number is octal or hex, we assume it's base 10.
+   */
+  if(base == 0) {
+    base = 10;
+  }
+
+  /* Loop handling digits. */
+  value = 0;
+  overflow = 0;
+  for(i = get_char(end[0], base);
+      i != -1;
+      end++, i = get_char(end[0], base)) {
+    newval = base * value + i;
+    if(newval < value) {
+      /* We've overflowed. */
+      overflow = 1;
+      break;
+    }
+    else
+      value = newval;
+  }
+
+  if(!overflow) {
+    if(is_negative) {
+      /* Fix the sign. */
+      value *= -1;
+    }
+  }
+  else {
+    if(is_negative)
+      value = CURL_OFF_T_MIN;
+    else
+      value = CURL_OFF_T_MAX;
+
+    errno = ERANGE;
+  }
+
+  if(endptr)
+    *endptr = end;
+
+  return value;
+}
+
+/**
+ * Returns the value of c in the given base, or -1 if c cannot
+ * be interpreted properly in that base (i.e., is out of range,
+ * is a null, etc.).
+ *
+ * @param c     the character to interpret according to base
+ * @param base  the base in which to interpret c
+ *
+ * @return  the value of c in base, or -1 if c isn't in range
+ */
+static int get_char(char c, int base)
+{
+#ifndef NO_RANGE_TEST
+  int value = -1;
+  if(c <= '9' && c >= '0') {
+    value = c - '0';
+  }
+  else if(c <= 'Z' && c >= 'A') {
+    value = c - 'A' + 10;
+  }
+  else if(c <= 'z' && c >= 'a') {
+    value = c - 'a' + 10;
+  }
+#else
+  const char *cp;
+  int value;
+
+  cp = memchr(valchars, c, 10 + 26 + 26);
+
+  if(!cp)
+    return -1;
+
+  value = cp - valchars;
+
+  if(value >= 10 + 26)
+    value -= 26;                /* Lowercase. */
+#endif
+
+  if(value >= base) {
+    value = -1;
+  }
+
+  return value;
+}
+#endif  /* Only present if we need strtoll, but don't have it. */
+
+/*
+ * Parse a *positive* up to 64 bit number written in ascii.
+ */
+CURLofft curlx_strtoofft(const char *str, char **endp, int base,
+                         curl_off_t *num)
+{
+  char *end;
+  curl_off_t number;
+  errno = 0;
+  *num = 0; /* clear by default */
+
+  DEBUGASSERT(str);
+
+  while(*str && ISSPACE(*str))
+    str++;
+  if('-' == *str) {
+    if(endp)
+      *endp = (char *)str; /* didn't actually move */
+    return CURL_OFFT_INVAL; /* nothing parsed */
+  }
+  number = strtooff(str, &end, base);
+  if(endp)
+    *endp = end;
+  if(errno == ERANGE)
+    /* overflow/underflow */
+    return CURL_OFFT_FLOW;
+  else if(str == end)
+    /* nothing parsed */
+    return CURL_OFFT_INVAL;
+
+  *num = number;
+  return CURL_OFFT_OK;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/strtoofft.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/strtoofft.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/strtoofft.h	(revision 331)
@@ -0,0 +1,60 @@
+#ifndef HEADER_CURL_STRTOOFFT_H
+#define HEADER_CURL_STRTOOFFT_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+/*
+ * Determine which string to integral data type conversion function we use
+ * to implement string conversion to our curl_off_t integral data type.
+ *
+ * Notice that curl_off_t might be 64 or 32 bit wide, and that it might use
+ * an underlying data type which might be 'long', 'int64_t', 'long long' or
+ * '__int64' and more remotely other data types.
+ *
+ * On systems where the size of curl_off_t is greater than the size of 'long'
+ * the conversion function to use is strtoll() if it is available, otherwise,
+ * we emulate its functionality with our own clone.
+ *
+ * On systems where the size of curl_off_t is smaller or equal than the size
+ * of 'long' the conversion function to use is strtol().
+ */
+
+#if (SIZEOF_CURL_OFF_T == 4)
+#  define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFF)
+#else
+   /* assume CURL_SIZEOF_CURL_OFF_T == 8 */
+#  define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF)
+#endif
+#define CURL_OFF_T_MIN (-CURL_OFF_T_MAX - CURL_OFF_T_C(1))
+
+typedef enum {
+  CURL_OFFT_OK,    /* parsed fine */
+  CURL_OFFT_FLOW,  /* over or underflow */
+  CURL_OFFT_INVAL  /* nothing was parsed */
+} CURLofft;
+
+CURLofft curlx_strtoofft(const char *str, char **endp, int base,
+                         curl_off_t *num);
+
+#endif /* HEADER_CURL_STRTOOFFT_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/system_win32.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/system_win32.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/system_win32.h	(revision 331)
@@ -0,0 +1,61 @@
+#ifndef HEADER_CURL_SYSTEM_WIN32_H
+#define HEADER_CURL_SYSTEM_WIN32_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2016, Steve Holme, <steve_holme@hotmail.com>.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(WIN32)
+
+/* Version condition */
+typedef enum {
+  VERSION_LESS_THAN,
+  VERSION_LESS_THAN_EQUAL,
+  VERSION_EQUAL,
+  VERSION_GREATER_THAN_EQUAL,
+  VERSION_GREATER_THAN
+} VersionCondition;
+
+/* Platform identifier */
+typedef enum {
+  PLATFORM_DONT_CARE,
+  PLATFORM_WINDOWS,
+  PLATFORM_WINNT
+} PlatformIdentifier;
+
+/* This is used to verify if we are running on a specific windows version */
+bool Curl_verify_windows_version(const unsigned int majorVersion,
+                                 const unsigned int minorVersion,
+                                 const PlatformIdentifier platform,
+                                 const VersionCondition condition);
+
+#if defined(USE_WINDOWS_SSPI) || (!defined(CURL_DISABLE_TELNET) && \
+                                  defined(USE_WINSOCK))
+
+/* This is used to dynamically load DLLs */
+HMODULE Curl_load_library(LPCTSTR filename);
+
+#endif /* USE_WINDOWS_SSPI || (!CURL_DISABLE_TELNET && USE_WINSOCK) */
+
+#endif /* WIN32 */
+
+#endif /* HEADER_CURL_SYSTEM_WIN32_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/telnet.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/telnet.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/telnet.c	(revision 331)
@@ -0,0 +1,1700 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_TELNET
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "sendf.h"
+#include "telnet.h"
+#include "connect.h"
+#include "progress.h"
+#include "system_win32.h"
+
+#define  TELOPTS
+#define  TELCMDS
+
+#include "arpa_telnet.h"
+#include "select.h"
+#include "strcase.h"
+#include "warnless.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define SUBBUFSIZE 512
+
+#define CURL_SB_CLEAR(x)  x->subpointer = x->subbuffer
+#define CURL_SB_TERM(x)                                 \
+  do {                                                  \
+    x->subend = x->subpointer;                          \
+    CURL_SB_CLEAR(x);                                   \
+  } WHILE_FALSE
+#define CURL_SB_ACCUM(x,c)                                   \
+  do {                                                       \
+    if(x->subpointer < (x->subbuffer + sizeof x->subbuffer)) \
+      *x->subpointer++ = (c);                                \
+  } WHILE_FALSE
+
+#define  CURL_SB_GET(x) ((*x->subpointer++)&0xff)
+#define  CURL_SB_LEN(x) (x->subend - x->subpointer)
+
+/* For posterity:
+#define  CURL_SB_PEEK(x) ((*x->subpointer)&0xff)
+#define  CURL_SB_EOF(x) (x->subpointer >= x->subend) */
+
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+#define printoption(a,b,c,d)  Curl_nop_stmt
+#endif
+
+#ifdef USE_WINSOCK
+typedef FARPROC WSOCK2_FUNC;
+static CURLcode check_wsock2(struct Curl_easy *data);
+#endif
+
+static
+CURLcode telrcv(struct connectdata *,
+                const unsigned char *inbuf, /* Data received from socket */
+                ssize_t count);             /* Number of bytes received */
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+static void printoption(struct Curl_easy *data,
+                        const char *direction,
+                        int cmd, int option);
+#endif
+
+static void negotiate(struct connectdata *);
+static void send_negotiation(struct connectdata *, int cmd, int option);
+static void set_local_option(struct connectdata *, int cmd, int option);
+static void set_remote_option(struct connectdata *, int cmd, int option);
+
+static void printsub(struct Curl_easy *data,
+                     int direction, unsigned char *pointer,
+                     size_t length);
+static void suboption(struct connectdata *);
+static void sendsuboption(struct connectdata *conn, int option);
+
+static CURLcode telnet_do(struct connectdata *conn, bool *done);
+static CURLcode telnet_done(struct connectdata *conn,
+                                 CURLcode, bool premature);
+static CURLcode send_telnet_data(struct connectdata *conn,
+                                 char *buffer, ssize_t nread);
+
+/* For negotiation compliant to RFC 1143 */
+#define CURL_NO          0
+#define CURL_YES         1
+#define CURL_WANTYES     2
+#define CURL_WANTNO      3
+
+#define CURL_EMPTY       0
+#define CURL_OPPOSITE    1
+
+/*
+ * Telnet receiver states for fsm
+ */
+typedef enum
+{
+   CURL_TS_DATA = 0,
+   CURL_TS_IAC,
+   CURL_TS_WILL,
+   CURL_TS_WONT,
+   CURL_TS_DO,
+   CURL_TS_DONT,
+   CURL_TS_CR,
+   CURL_TS_SB,   /* sub-option collection */
+   CURL_TS_SE   /* looking for sub-option end */
+} TelnetReceive;
+
+struct TELNET {
+  int please_negotiate;
+  int already_negotiated;
+  int us[256];
+  int usq[256];
+  int us_preferred[256];
+  int him[256];
+  int himq[256];
+  int him_preferred[256];
+  int subnegotiation[256];
+  char subopt_ttype[32];             /* Set with suboption TTYPE */
+  char subopt_xdisploc[128];         /* Set with suboption XDISPLOC */
+  unsigned short subopt_wsx;         /* Set with suboption NAWS */
+  unsigned short subopt_wsy;         /* Set with suboption NAWS */
+  struct curl_slist *telnet_vars;    /* Environment variables */
+
+  /* suboptions */
+  unsigned char subbuffer[SUBBUFSIZE];
+  unsigned char *subpointer, *subend;      /* buffer for sub-options */
+
+  TelnetReceive telrcv_state;
+};
+
+
+/*
+ * TELNET protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_telnet = {
+  "TELNET",                             /* scheme */
+  ZERO_NULL,                            /* setup_connection */
+  telnet_do,                            /* do_it */
+  telnet_done,                          /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_TELNET,                          /* defport */
+  CURLPROTO_TELNET,                     /* protocol */
+  PROTOPT_NONE | PROTOPT_NOURLQUERY     /* flags */
+};
+
+
+#ifdef USE_WINSOCK
+static CURLcode
+check_wsock2(struct Curl_easy *data)
+{
+  int err;
+  WORD wVersionRequested;
+  WSADATA wsaData;
+
+  DEBUGASSERT(data);
+
+  /* telnet requires at least WinSock 2.0 so ask for it. */
+  wVersionRequested = MAKEWORD(2, 0);
+
+  err = WSAStartup(wVersionRequested, &wsaData);
+
+  /* We must've called this once already, so this call */
+  /* should always succeed.  But, just in case... */
+  if(err != 0) {
+    failf(data,"WSAStartup failed (%d)",err);
+    return CURLE_FAILED_INIT;
+  }
+
+  /* We have to have a WSACleanup call for every successful */
+  /* WSAStartup call. */
+  WSACleanup();
+
+  /* Check that our version is supported */
+  if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
+      HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested)) {
+      /* Our version isn't supported */
+    failf(data, "insufficient winsock version to support "
+          "telnet");
+    return CURLE_FAILED_INIT;
+  }
+
+  /* Our version is supported */
+  return CURLE_OK;
+}
+#endif
+
+static
+CURLcode init_telnet(struct connectdata *conn)
+{
+  struct TELNET *tn;
+
+  tn = calloc(1, sizeof(struct TELNET));
+  if(!tn)
+    return CURLE_OUT_OF_MEMORY;
+
+  conn->data->req.protop = tn; /* make us known */
+
+  tn->telrcv_state = CURL_TS_DATA;
+
+  /* Init suboptions */
+  CURL_SB_CLEAR(tn);
+
+  /* Set the options we want by default */
+  tn->us_preferred[CURL_TELOPT_SGA] = CURL_YES;
+  tn->him_preferred[CURL_TELOPT_SGA] = CURL_YES;
+
+  /* To be compliant with previous releases of libcurl
+     we enable this option by default. This behaviour
+         can be changed thanks to the "BINARY" option in
+         CURLOPT_TELNETOPTIONS
+  */
+  tn->us_preferred[CURL_TELOPT_BINARY] = CURL_YES;
+  tn->him_preferred[CURL_TELOPT_BINARY] = CURL_YES;
+
+  /* We must allow the server to echo what we sent
+         but it is not necessary to request the server
+         to do so (it might forces the server to close
+         the connection). Hence, we ignore ECHO in the
+         negotiate function
+  */
+  tn->him_preferred[CURL_TELOPT_ECHO] = CURL_YES;
+
+  /* Set the subnegotiation fields to send information
+    just after negotiation passed (do/will)
+
+     Default values are (0,0) initialized by calloc.
+     According to the RFC1013 it is valid:
+     A value equal to zero is acceptable for the width (or height),
+         and means that no character width (or height) is being sent.
+         In this case, the width (or height) that will be assumed by the
+         Telnet server is operating system specific (it will probably be
+         based upon the terminal type information that may have been sent
+         using the TERMINAL TYPE Telnet option). */
+  tn->subnegotiation[CURL_TELOPT_NAWS] = CURL_YES;
+  return CURLE_OK;
+}
+
+static void negotiate(struct connectdata *conn)
+{
+  int i;
+  struct TELNET *tn = (struct TELNET *) conn->data->req.protop;
+
+  for(i = 0; i < CURL_NTELOPTS; i++) {
+    if(i == CURL_TELOPT_ECHO)
+      continue;
+
+    if(tn->us_preferred[i] == CURL_YES)
+      set_local_option(conn, i, CURL_YES);
+
+    if(tn->him_preferred[i] == CURL_YES)
+      set_remote_option(conn, i, CURL_YES);
+  }
+}
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+static void printoption(struct Curl_easy *data,
+                        const char *direction, int cmd, int option)
+{
+  const char *fmt;
+  const char *opt;
+
+  if(data->set.verbose) {
+    if(cmd == CURL_IAC) {
+      if(CURL_TELCMD_OK(option))
+        infof(data, "%s IAC %s\n", direction, CURL_TELCMD(option));
+      else
+        infof(data, "%s IAC %d\n", direction, option);
+    }
+    else {
+      fmt = (cmd == CURL_WILL) ? "WILL" : (cmd == CURL_WONT) ? "WONT" :
+        (cmd == CURL_DO) ? "DO" : (cmd == CURL_DONT) ? "DONT" : 0;
+      if(fmt) {
+        if(CURL_TELOPT_OK(option))
+          opt = CURL_TELOPT(option);
+        else if(option == CURL_TELOPT_EXOPL)
+          opt = "EXOPL";
+        else
+          opt = NULL;
+
+        if(opt)
+          infof(data, "%s %s %s\n", direction, fmt, opt);
+        else
+          infof(data, "%s %s %d\n", direction, fmt, option);
+      }
+      else
+        infof(data, "%s %d %d\n", direction, cmd, option);
+    }
+  }
+}
+#endif
+
+static void send_negotiation(struct connectdata *conn, int cmd, int option)
+{
+   unsigned char buf[3];
+   ssize_t bytes_written;
+   int err;
+   struct Curl_easy *data = conn->data;
+
+   buf[0] = CURL_IAC;
+   buf[1] = (unsigned char)cmd;
+   buf[2] = (unsigned char)option;
+
+   bytes_written = swrite(conn->sock[FIRSTSOCKET], buf, 3);
+   if(bytes_written < 0) {
+     err = SOCKERRNO;
+     failf(data,"Sending data failed (%d)",err);
+   }
+
+   printoption(conn->data, "SENT", cmd, option);
+}
+
+static
+void set_remote_option(struct connectdata *conn, int option, int newstate)
+{
+  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  if(newstate == CURL_YES) {
+    switch(tn->him[option]) {
+    case CURL_NO:
+      tn->him[option] = CURL_WANTYES;
+      send_negotiation(conn, CURL_DO, option);
+      break;
+
+    case CURL_YES:
+      /* Already enabled */
+      break;
+
+    case CURL_WANTNO:
+      switch(tn->himq[option]) {
+      case CURL_EMPTY:
+        /* Already negotiating for CURL_YES, queue the request */
+        tn->himq[option] = CURL_OPPOSITE;
+        break;
+      case CURL_OPPOSITE:
+        /* Error: already queued an enable request */
+        break;
+      }
+      break;
+
+    case CURL_WANTYES:
+      switch(tn->himq[option]) {
+      case CURL_EMPTY:
+        /* Error: already negotiating for enable */
+        break;
+      case CURL_OPPOSITE:
+        tn->himq[option] = CURL_EMPTY;
+        break;
+      }
+      break;
+    }
+  }
+  else { /* NO */
+    switch(tn->him[option]) {
+    case CURL_NO:
+      /* Already disabled */
+      break;
+
+    case CURL_YES:
+      tn->him[option] = CURL_WANTNO;
+      send_negotiation(conn, CURL_DONT, option);
+      break;
+
+    case CURL_WANTNO:
+      switch(tn->himq[option]) {
+      case CURL_EMPTY:
+        /* Already negotiating for NO */
+        break;
+      case CURL_OPPOSITE:
+        tn->himq[option] = CURL_EMPTY;
+        break;
+      }
+      break;
+
+    case CURL_WANTYES:
+      switch(tn->himq[option]) {
+      case CURL_EMPTY:
+        tn->himq[option] = CURL_OPPOSITE;
+        break;
+      case CURL_OPPOSITE:
+        break;
+      }
+      break;
+    }
+  }
+}
+
+static
+void rec_will(struct connectdata *conn, int option)
+{
+  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  switch(tn->him[option]) {
+  case CURL_NO:
+    if(tn->him_preferred[option] == CURL_YES) {
+      tn->him[option] = CURL_YES;
+      send_negotiation(conn, CURL_DO, option);
+    }
+    else
+      send_negotiation(conn, CURL_DONT, option);
+
+    break;
+
+  case CURL_YES:
+    /* Already enabled */
+    break;
+
+  case CURL_WANTNO:
+    switch(tn->himq[option]) {
+    case CURL_EMPTY:
+      /* Error: DONT answered by WILL */
+      tn->him[option] = CURL_NO;
+      break;
+    case CURL_OPPOSITE:
+      /* Error: DONT answered by WILL */
+      tn->him[option] = CURL_YES;
+      tn->himq[option] = CURL_EMPTY;
+      break;
+    }
+    break;
+
+  case CURL_WANTYES:
+    switch(tn->himq[option]) {
+    case CURL_EMPTY:
+      tn->him[option] = CURL_YES;
+      break;
+    case CURL_OPPOSITE:
+      tn->him[option] = CURL_WANTNO;
+      tn->himq[option] = CURL_EMPTY;
+      send_negotiation(conn, CURL_DONT, option);
+      break;
+    }
+    break;
+  }
+}
+
+static
+void rec_wont(struct connectdata *conn, int option)
+{
+  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  switch(tn->him[option]) {
+  case CURL_NO:
+    /* Already disabled */
+    break;
+
+  case CURL_YES:
+    tn->him[option] = CURL_NO;
+    send_negotiation(conn, CURL_DONT, option);
+    break;
+
+  case CURL_WANTNO:
+    switch(tn->himq[option]) {
+    case CURL_EMPTY:
+      tn->him[option] = CURL_NO;
+      break;
+
+    case CURL_OPPOSITE:
+      tn->him[option] = CURL_WANTYES;
+      tn->himq[option] = CURL_EMPTY;
+      send_negotiation(conn, CURL_DO, option);
+      break;
+    }
+    break;
+
+  case CURL_WANTYES:
+    switch(tn->himq[option]) {
+    case CURL_EMPTY:
+      tn->him[option] = CURL_NO;
+      break;
+    case CURL_OPPOSITE:
+      tn->him[option] = CURL_NO;
+      tn->himq[option] = CURL_EMPTY;
+      break;
+    }
+    break;
+  }
+}
+
+static void
+set_local_option(struct connectdata *conn, int option, int newstate)
+{
+  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  if(newstate == CURL_YES) {
+    switch(tn->us[option]) {
+    case CURL_NO:
+      tn->us[option] = CURL_WANTYES;
+      send_negotiation(conn, CURL_WILL, option);
+      break;
+
+    case CURL_YES:
+      /* Already enabled */
+      break;
+
+    case CURL_WANTNO:
+      switch(tn->usq[option]) {
+      case CURL_EMPTY:
+        /* Already negotiating for CURL_YES, queue the request */
+        tn->usq[option] = CURL_OPPOSITE;
+        break;
+      case CURL_OPPOSITE:
+        /* Error: already queued an enable request */
+        break;
+      }
+      break;
+
+    case CURL_WANTYES:
+      switch(tn->usq[option]) {
+      case CURL_EMPTY:
+        /* Error: already negotiating for enable */
+        break;
+      case CURL_OPPOSITE:
+        tn->usq[option] = CURL_EMPTY;
+        break;
+      }
+      break;
+    }
+  }
+  else { /* NO */
+    switch(tn->us[option]) {
+    case CURL_NO:
+      /* Already disabled */
+      break;
+
+    case CURL_YES:
+      tn->us[option] = CURL_WANTNO;
+      send_negotiation(conn, CURL_WONT, option);
+      break;
+
+    case CURL_WANTNO:
+      switch(tn->usq[option]) {
+      case CURL_EMPTY:
+        /* Already negotiating for NO */
+        break;
+      case CURL_OPPOSITE:
+        tn->usq[option] = CURL_EMPTY;
+        break;
+      }
+      break;
+
+    case CURL_WANTYES:
+      switch(tn->usq[option]) {
+      case CURL_EMPTY:
+        tn->usq[option] = CURL_OPPOSITE;
+        break;
+      case CURL_OPPOSITE:
+        break;
+      }
+      break;
+    }
+  }
+}
+
+static
+void rec_do(struct connectdata *conn, int option)
+{
+  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  switch(tn->us[option]) {
+  case CURL_NO:
+    if(tn->us_preferred[option] == CURL_YES) {
+      tn->us[option] = CURL_YES;
+      send_negotiation(conn, CURL_WILL, option);
+      if(tn->subnegotiation[option] == CURL_YES)
+        /* transmission of data option */
+        sendsuboption(conn, option);
+    }
+    else if(tn->subnegotiation[option] == CURL_YES) {
+      /* send information to achieve this option*/
+      tn->us[option] = CURL_YES;
+      send_negotiation(conn, CURL_WILL, option);
+      sendsuboption(conn, option);
+    }
+    else
+      send_negotiation(conn, CURL_WONT, option);
+    break;
+
+  case CURL_YES:
+    /* Already enabled */
+    break;
+
+  case CURL_WANTNO:
+    switch(tn->usq[option]) {
+    case CURL_EMPTY:
+      /* Error: DONT answered by WILL */
+      tn->us[option] = CURL_NO;
+      break;
+    case CURL_OPPOSITE:
+      /* Error: DONT answered by WILL */
+      tn->us[option] = CURL_YES;
+      tn->usq[option] = CURL_EMPTY;
+      break;
+    }
+    break;
+
+  case CURL_WANTYES:
+    switch(tn->usq[option]) {
+    case CURL_EMPTY:
+      tn->us[option] = CURL_YES;
+      if(tn->subnegotiation[option] == CURL_YES) {
+        /* transmission of data option */
+        sendsuboption(conn, option);
+      }
+      break;
+    case CURL_OPPOSITE:
+      tn->us[option] = CURL_WANTNO;
+      tn->himq[option] = CURL_EMPTY;
+      send_negotiation(conn, CURL_WONT, option);
+      break;
+    }
+    break;
+  }
+}
+
+static
+void rec_dont(struct connectdata *conn, int option)
+{
+  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  switch(tn->us[option]) {
+  case CURL_NO:
+    /* Already disabled */
+    break;
+
+  case CURL_YES:
+    tn->us[option] = CURL_NO;
+    send_negotiation(conn, CURL_WONT, option);
+    break;
+
+  case CURL_WANTNO:
+    switch(tn->usq[option]) {
+    case CURL_EMPTY:
+      tn->us[option] = CURL_NO;
+      break;
+
+    case CURL_OPPOSITE:
+      tn->us[option] = CURL_WANTYES;
+      tn->usq[option] = CURL_EMPTY;
+      send_negotiation(conn, CURL_WILL, option);
+      break;
+    }
+    break;
+
+  case CURL_WANTYES:
+    switch(tn->usq[option]) {
+    case CURL_EMPTY:
+      tn->us[option] = CURL_NO;
+      break;
+    case CURL_OPPOSITE:
+      tn->us[option] = CURL_NO;
+      tn->usq[option] = CURL_EMPTY;
+      break;
+    }
+    break;
+  }
+}
+
+
+static void printsub(struct Curl_easy *data,
+                     int direction,             /* '<' or '>' */
+                     unsigned char *pointer,    /* where suboption data is */
+                     size_t length)             /* length of suboption data */
+{
+  unsigned int i = 0;
+
+  if(data->set.verbose) {
+    if(direction) {
+      infof(data, "%s IAC SB ", (direction == '<')? "RCVD":"SENT");
+      if(length >= 3) {
+        int j;
+
+        i = pointer[length-2];
+        j = pointer[length-1];
+
+        if(i != CURL_IAC || j != CURL_SE) {
+          infof(data, "(terminated by ");
+          if(CURL_TELOPT_OK(i))
+            infof(data, "%s ", CURL_TELOPT(i));
+          else if(CURL_TELCMD_OK(i))
+            infof(data, "%s ", CURL_TELCMD(i));
+          else
+            infof(data, "%u ", i);
+          if(CURL_TELOPT_OK(j))
+            infof(data, "%s", CURL_TELOPT(j));
+          else if(CURL_TELCMD_OK(j))
+            infof(data, "%s", CURL_TELCMD(j));
+          else
+            infof(data, "%d", j);
+          infof(data, ", not IAC SE!) ");
+        }
+      }
+      length -= 2;
+    }
+    if(length < 1) {
+      infof(data, "(Empty suboption?)");
+      return;
+    }
+
+    if(CURL_TELOPT_OK(pointer[0])) {
+      switch(pointer[0]) {
+      case CURL_TELOPT_TTYPE:
+      case CURL_TELOPT_XDISPLOC:
+      case CURL_TELOPT_NEW_ENVIRON:
+      case CURL_TELOPT_NAWS:
+        infof(data, "%s", CURL_TELOPT(pointer[0]));
+        break;
+      default:
+        infof(data, "%s (unsupported)", CURL_TELOPT(pointer[0]));
+        break;
+      }
+    }
+    else
+      infof(data, "%d (unknown)", pointer[i]);
+
+    switch(pointer[0]) {
+    case CURL_TELOPT_NAWS:
+      if(length > 4)
+        infof(data, "Width: %hu ; Height: %hu", (pointer[1]<<8) | pointer[2],
+              (pointer[3]<<8) | pointer[4]);
+      break;
+    default:
+      switch(pointer[1]) {
+      case CURL_TELQUAL_IS:
+        infof(data, " IS");
+        break;
+      case CURL_TELQUAL_SEND:
+        infof(data, " SEND");
+        break;
+      case CURL_TELQUAL_INFO:
+        infof(data, " INFO/REPLY");
+        break;
+      case CURL_TELQUAL_NAME:
+        infof(data, " NAME");
+        break;
+      }
+
+      switch(pointer[0]) {
+      case CURL_TELOPT_TTYPE:
+      case CURL_TELOPT_XDISPLOC:
+        pointer[length] = 0;
+        infof(data, " \"%s\"", &pointer[2]);
+        break;
+      case CURL_TELOPT_NEW_ENVIRON:
+        if(pointer[1] == CURL_TELQUAL_IS) {
+          infof(data, " ");
+          for(i = 3; i < length; i++) {
+            switch(pointer[i]) {
+            case CURL_NEW_ENV_VAR:
+              infof(data, ", ");
+              break;
+            case CURL_NEW_ENV_VALUE:
+              infof(data, " = ");
+              break;
+            default:
+              infof(data, "%c", pointer[i]);
+              break;
+            }
+          }
+        }
+        break;
+      default:
+        for(i = 2; i < length; i++)
+          infof(data, " %.2x", pointer[i]);
+        break;
+      }
+    }
+    if(direction)
+      infof(data, "\n");
+  }
+}
+
+static CURLcode check_telnet_options(struct connectdata *conn)
+{
+  struct curl_slist *head;
+  struct curl_slist *beg;
+  char option_keyword[128] = "";
+  char option_arg[256] = "";
+  struct Curl_easy *data = conn->data;
+  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  CURLcode result = CURLE_OK;
+  int binary_option;
+
+  /* Add the user name as an environment variable if it
+     was given on the command line */
+  if(conn->bits.user_passwd) {
+    snprintf(option_arg, sizeof(option_arg), "USER,%s", conn->user);
+    beg = curl_slist_append(tn->telnet_vars, option_arg);
+    if(!beg) {
+      curl_slist_free_all(tn->telnet_vars);
+      tn->telnet_vars = NULL;
+      return CURLE_OUT_OF_MEMORY;
+    }
+    tn->telnet_vars = beg;
+    tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;
+  }
+
+  for(head = data->set.telnet_options; head; head = head->next) {
+    if(sscanf(head->data, "%127[^= ]%*[ =]%255s",
+              option_keyword, option_arg) == 2) {
+
+      /* Terminal type */
+      if(strcasecompare(option_keyword, "TTYPE")) {
+        strncpy(tn->subopt_ttype, option_arg, 31);
+        tn->subopt_ttype[31] = 0; /* String termination */
+        tn->us_preferred[CURL_TELOPT_TTYPE] = CURL_YES;
+        continue;
+      }
+
+      /* Display variable */
+      if(strcasecompare(option_keyword, "XDISPLOC")) {
+        strncpy(tn->subopt_xdisploc, option_arg, 127);
+        tn->subopt_xdisploc[127] = 0; /* String termination */
+        tn->us_preferred[CURL_TELOPT_XDISPLOC] = CURL_YES;
+        continue;
+      }
+
+      /* Environment variable */
+      if(strcasecompare(option_keyword, "NEW_ENV")) {
+        beg = curl_slist_append(tn->telnet_vars, option_arg);
+        if(!beg) {
+          result = CURLE_OUT_OF_MEMORY;
+          break;
+        }
+        tn->telnet_vars = beg;
+        tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;
+        continue;
+      }
+
+      /* Window Size */
+      if(strcasecompare(option_keyword, "WS")) {
+        if(sscanf(option_arg, "%hu%*[xX]%hu",
+                  &tn->subopt_wsx, &tn->subopt_wsy) == 2)
+          tn->us_preferred[CURL_TELOPT_NAWS] = CURL_YES;
+        else {
+          failf(data, "Syntax error in telnet option: %s", head->data);
+          result = CURLE_TELNET_OPTION_SYNTAX;
+          break;
+        }
+        continue;
+      }
+
+      /* To take care or not of the 8th bit in data exchange */
+      if(strcasecompare(option_keyword, "BINARY")) {
+        binary_option = atoi(option_arg);
+        if(binary_option != 1) {
+          tn->us_preferred[CURL_TELOPT_BINARY] = CURL_NO;
+          tn->him_preferred[CURL_TELOPT_BINARY] = CURL_NO;
+        }
+        continue;
+      }
+
+      failf(data, "Unknown telnet option %s", head->data);
+      result = CURLE_UNKNOWN_OPTION;
+      break;
+    }
+    failf(data, "Syntax error in telnet option: %s", head->data);
+    result = CURLE_TELNET_OPTION_SYNTAX;
+    break;
+  }
+
+  if(result) {
+    curl_slist_free_all(tn->telnet_vars);
+    tn->telnet_vars = NULL;
+  }
+
+  return result;
+}
+
+/*
+ * suboption()
+ *
+ * Look at the sub-option buffer, and try to be helpful to the other
+ * side.
+ */
+
+static void suboption(struct connectdata *conn)
+{
+  struct curl_slist *v;
+  unsigned char temp[2048];
+  ssize_t bytes_written;
+  size_t len;
+  size_t tmplen;
+  int err;
+  char varname[128] = "";
+  char varval[128] = "";
+  struct Curl_easy *data = conn->data;
+  struct TELNET *tn = (struct TELNET *)data->req.protop;
+
+  printsub(data, '<', (unsigned char *)tn->subbuffer, CURL_SB_LEN(tn) + 2);
+  switch(CURL_SB_GET(tn)) {
+    case CURL_TELOPT_TTYPE:
+      len = strlen(tn->subopt_ttype) + 4 + 2;
+      snprintf((char *)temp, sizeof(temp),
+               "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_TTYPE,
+               CURL_TELQUAL_IS, tn->subopt_ttype, CURL_IAC, CURL_SE);
+      bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len);
+      if(bytes_written < 0) {
+        err = SOCKERRNO;
+        failf(data,"Sending data failed (%d)",err);
+      }
+      printsub(data, '>', &temp[2], len-2);
+      break;
+    case CURL_TELOPT_XDISPLOC:
+      len = strlen(tn->subopt_xdisploc) + 4 + 2;
+      snprintf((char *)temp, sizeof(temp),
+               "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_XDISPLOC,
+               CURL_TELQUAL_IS, tn->subopt_xdisploc, CURL_IAC, CURL_SE);
+      bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len);
+      if(bytes_written < 0) {
+        err = SOCKERRNO;
+        failf(data,"Sending data failed (%d)",err);
+      }
+      printsub(data, '>', &temp[2], len-2);
+      break;
+    case CURL_TELOPT_NEW_ENVIRON:
+      snprintf((char *)temp, sizeof(temp),
+               "%c%c%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_NEW_ENVIRON,
+               CURL_TELQUAL_IS);
+      len = 4;
+
+      for(v = tn->telnet_vars; v; v = v->next) {
+        tmplen = (strlen(v->data) + 1);
+        /* Add the variable only if it fits */
+        if(len + tmplen < (int)sizeof(temp)-6) {
+          if(sscanf(v->data, "%127[^,],%127s", varname, varval)) {
+            snprintf((char *)&temp[len], sizeof(temp) - len,
+                     "%c%s%c%s", CURL_NEW_ENV_VAR, varname,
+                     CURL_NEW_ENV_VALUE, varval);
+            len += tmplen;
+          }
+        }
+      }
+      snprintf((char *)&temp[len], sizeof(temp) - len,
+               "%c%c", CURL_IAC, CURL_SE);
+      len += 2;
+      bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len);
+      if(bytes_written < 0) {
+        err = SOCKERRNO;
+        failf(data,"Sending data failed (%d)",err);
+      }
+      printsub(data, '>', &temp[2], len-2);
+      break;
+  }
+  return;
+}
+
+
+/*
+ * sendsuboption()
+ *
+ * Send suboption information to the server side.
+ */
+
+static void sendsuboption(struct connectdata *conn, int option)
+{
+  ssize_t bytes_written;
+  int err;
+  unsigned short x, y;
+  unsigned char *uc1, *uc2;
+
+  struct Curl_easy *data = conn->data;
+  struct TELNET *tn = (struct TELNET *)data->req.protop;
+
+  switch(option) {
+  case CURL_TELOPT_NAWS:
+    /* We prepare data to be sent */
+    CURL_SB_CLEAR(tn);
+    CURL_SB_ACCUM(tn, CURL_IAC);
+    CURL_SB_ACCUM(tn, CURL_SB);
+    CURL_SB_ACCUM(tn, CURL_TELOPT_NAWS);
+    /* We must deal either with litte or big endian processors */
+    /* Window size must be sent according to the 'network order' */
+    x = htons(tn->subopt_wsx);
+    y = htons(tn->subopt_wsy);
+    uc1 = (unsigned char *)&x;
+    uc2 = (unsigned char *)&y;
+    CURL_SB_ACCUM(tn, uc1[0]);
+    CURL_SB_ACCUM(tn, uc1[1]);
+    CURL_SB_ACCUM(tn, uc2[0]);
+    CURL_SB_ACCUM(tn, uc2[1]);
+
+    CURL_SB_ACCUM(tn, CURL_IAC);
+    CURL_SB_ACCUM(tn, CURL_SE);
+    CURL_SB_TERM(tn);
+    /* data suboption is now ready */
+
+    printsub(data, '>', (unsigned char *)tn->subbuffer + 2,
+             CURL_SB_LEN(tn)-2);
+
+    /* we send the header of the suboption... */
+    bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer, 3);
+    if(bytes_written < 0) {
+      err = SOCKERRNO;
+      failf(data, "Sending data failed (%d)", err);
+    }
+    /* ... then the window size with the send_telnet_data() function
+       to deal with 0xFF cases ... */
+    send_telnet_data(conn, (char *)tn->subbuffer + 3, 4);
+    /* ... and the footer */
+    bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer + 7, 2);
+    if(bytes_written < 0) {
+      err = SOCKERRNO;
+      failf(data, "Sending data failed (%d)", err);
+    }
+    break;
+  }
+}
+
+
+static
+CURLcode telrcv(struct connectdata *conn,
+                const unsigned char *inbuf, /* Data received from socket */
+                ssize_t count)              /* Number of bytes received */
+{
+  unsigned char c;
+  CURLcode result;
+  int in = 0;
+  int startwrite = -1;
+  struct Curl_easy *data = conn->data;
+  struct TELNET *tn = (struct TELNET *)data->req.protop;
+
+#define startskipping()                                       \
+  if(startwrite >= 0) {                                       \
+    result = Curl_client_write(conn,                          \
+                               CLIENTWRITE_BODY,              \
+                               (char *)&inbuf[startwrite],    \
+                               in-startwrite);                \
+    if(result)                                                \
+      return result;                                          \
+  }                                                           \
+  startwrite = -1
+
+#define writebyte() \
+    if(startwrite < 0) \
+      startwrite = in
+
+#define bufferflush() startskipping()
+
+  while(count--) {
+    c = inbuf[in];
+
+    switch(tn->telrcv_state) {
+    case CURL_TS_CR:
+      tn->telrcv_state = CURL_TS_DATA;
+      if(c == '\0') {
+        startskipping();
+        break;   /* Ignore \0 after CR */
+      }
+      writebyte();
+      break;
+
+    case CURL_TS_DATA:
+      if(c == CURL_IAC) {
+        tn->telrcv_state = CURL_TS_IAC;
+        startskipping();
+        break;
+      }
+      else if(c == '\r')
+        tn->telrcv_state = CURL_TS_CR;
+      writebyte();
+      break;
+
+    case CURL_TS_IAC:
+    process_iac:
+      DEBUGASSERT(startwrite < 0);
+      switch(c) {
+      case CURL_WILL:
+        tn->telrcv_state = CURL_TS_WILL;
+        break;
+      case CURL_WONT:
+        tn->telrcv_state = CURL_TS_WONT;
+        break;
+      case CURL_DO:
+        tn->telrcv_state = CURL_TS_DO;
+        break;
+      case CURL_DONT:
+        tn->telrcv_state = CURL_TS_DONT;
+        break;
+      case CURL_SB:
+        CURL_SB_CLEAR(tn);
+        tn->telrcv_state = CURL_TS_SB;
+        break;
+      case CURL_IAC:
+        tn->telrcv_state = CURL_TS_DATA;
+        writebyte();
+        break;
+      case CURL_DM:
+      case CURL_NOP:
+      case CURL_GA:
+      default:
+        tn->telrcv_state = CURL_TS_DATA;
+        printoption(data, "RCVD", CURL_IAC, c);
+        break;
+      }
+      break;
+
+      case CURL_TS_WILL:
+        printoption(data, "RCVD", CURL_WILL, c);
+        tn->please_negotiate = 1;
+        rec_will(conn, c);
+        tn->telrcv_state = CURL_TS_DATA;
+        break;
+
+      case CURL_TS_WONT:
+        printoption(data, "RCVD", CURL_WONT, c);
+        tn->please_negotiate = 1;
+        rec_wont(conn, c);
+        tn->telrcv_state = CURL_TS_DATA;
+        break;
+
+      case CURL_TS_DO:
+        printoption(data, "RCVD", CURL_DO, c);
+        tn->please_negotiate = 1;
+        rec_do(conn, c);
+        tn->telrcv_state = CURL_TS_DATA;
+        break;
+
+      case CURL_TS_DONT:
+        printoption(data, "RCVD", CURL_DONT, c);
+        tn->please_negotiate = 1;
+        rec_dont(conn, c);
+        tn->telrcv_state = CURL_TS_DATA;
+        break;
+
+      case CURL_TS_SB:
+        if(c == CURL_IAC)
+          tn->telrcv_state = CURL_TS_SE;
+        else
+          CURL_SB_ACCUM(tn, c);
+        break;
+
+      case CURL_TS_SE:
+        if(c != CURL_SE) {
+          if(c != CURL_IAC) {
+            /*
+             * This is an error.  We only expect to get "IAC IAC" or "IAC SE".
+             * Several things may have happened.  An IAC was not doubled, the
+             * IAC SE was left off, or another option got inserted into the
+             * suboption are all possibilities.  If we assume that the IAC was
+             * not doubled, and really the IAC SE was left off, we could get
+             * into an infinite loop here.  So, instead, we terminate the
+             * suboption, and process the partial suboption if we can.
+             */
+            CURL_SB_ACCUM(tn, CURL_IAC);
+            CURL_SB_ACCUM(tn, c);
+            tn->subpointer -= 2;
+            CURL_SB_TERM(tn);
+
+            printoption(data, "In SUBOPTION processing, RCVD", CURL_IAC, c);
+            suboption(conn);   /* handle sub-option */
+            tn->telrcv_state = CURL_TS_IAC;
+            goto process_iac;
+          }
+          CURL_SB_ACCUM(tn, c);
+          tn->telrcv_state = CURL_TS_SB;
+        }
+        else
+        {
+          CURL_SB_ACCUM(tn, CURL_IAC);
+          CURL_SB_ACCUM(tn, CURL_SE);
+          tn->subpointer -= 2;
+          CURL_SB_TERM(tn);
+          suboption(conn);   /* handle sub-option */
+          tn->telrcv_state = CURL_TS_DATA;
+        }
+        break;
+    }
+    ++in;
+  }
+  bufferflush();
+  return CURLE_OK;
+}
+
+/* Escape and send a telnet data block */
+static CURLcode send_telnet_data(struct connectdata *conn,
+                                 char *buffer, ssize_t nread)
+{
+  ssize_t escapes, i, j, outlen;
+  unsigned char *outbuf = NULL;
+  CURLcode result = CURLE_OK;
+  ssize_t bytes_written, total_written;
+
+  /* Determine size of new buffer after escaping */
+  escapes = 0;
+  for(i = 0; i < nread; i++)
+    if((unsigned char)buffer[i] == CURL_IAC)
+      escapes++;
+  outlen = nread + escapes;
+
+  if(outlen == nread)
+    outbuf = (unsigned char *)buffer;
+  else {
+    outbuf = malloc(nread + escapes + 1);
+    if(!outbuf)
+      return CURLE_OUT_OF_MEMORY;
+
+    j = 0;
+    for(i = 0; i < nread; i++) {
+      outbuf[j++] = buffer[i];
+      if((unsigned char)buffer[i] == CURL_IAC)
+        outbuf[j++] = CURL_IAC;
+    }
+    outbuf[j] = '\0';
+  }
+
+  total_written = 0;
+  while(!result && total_written < outlen) {
+    /* Make sure socket is writable to avoid EWOULDBLOCK condition */
+    struct pollfd pfd[1];
+    pfd[0].fd = conn->sock[FIRSTSOCKET];
+    pfd[0].events = POLLOUT;
+    switch(Curl_poll(pfd, 1, -1)) {
+      case -1:                    /* error, abort writing */
+      case 0:                     /* timeout (will never happen) */
+        result = CURLE_SEND_ERROR;
+        break;
+      default:                    /* write! */
+        bytes_written = 0;
+        result = Curl_write(conn, conn->sock[FIRSTSOCKET],
+                            outbuf + total_written,
+                            outlen - total_written,
+                            &bytes_written);
+        total_written += bytes_written;
+        break;
+    }
+  }
+
+  /* Free malloc copy if escaped */
+  if(outbuf != (unsigned char *)buffer)
+    free(outbuf);
+
+  return result;
+}
+
+static CURLcode telnet_done(struct connectdata *conn,
+                                 CURLcode status, bool premature)
+{
+  struct TELNET *tn = (struct TELNET *)conn->data->req.protop;
+  (void)status; /* unused */
+  (void)premature; /* not used */
+
+  if(!tn)
+    return CURLE_OK;
+
+  curl_slist_free_all(tn->telnet_vars);
+  tn->telnet_vars = NULL;
+
+  Curl_safefree(conn->data->req.protop);
+
+  return CURLE_OK;
+}
+
+static CURLcode telnet_do(struct connectdata *conn, bool *done)
+{
+  CURLcode result;
+  struct Curl_easy *data = conn->data;
+  curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
+#ifdef USE_WINSOCK
+  HMODULE wsock2;
+  WSOCK2_FUNC close_event_func;
+  WSOCK2_FUNC create_event_func;
+  WSOCK2_FUNC event_select_func;
+  WSOCK2_FUNC enum_netevents_func;
+  WSAEVENT event_handle;
+  WSANETWORKEVENTS events;
+  HANDLE stdin_handle;
+  HANDLE objs[2];
+  DWORD  obj_count;
+  DWORD  wait_timeout;
+  DWORD waitret;
+  DWORD readfile_read;
+  int err;
+#else
+  int interval_ms;
+  struct pollfd pfd[2];
+  int poll_cnt;
+  curl_off_t total_dl = 0;
+  curl_off_t total_ul = 0;
+#endif
+  ssize_t nread;
+  struct curltime now;
+  bool keepon = TRUE;
+  char *buf = data->state.buffer;
+  struct TELNET *tn;
+
+  *done = TRUE; /* unconditionally */
+
+  result = init_telnet(conn);
+  if(result)
+    return result;
+
+  tn = (struct TELNET *)data->req.protop;
+
+  result = check_telnet_options(conn);
+  if(result)
+    return result;
+
+#ifdef USE_WINSOCK
+  /*
+  ** This functionality only works with WinSock >= 2.0.  So,
+  ** make sure we have it.
+  */
+  result = check_wsock2(data);
+  if(result)
+    return result;
+
+  /* OK, so we have WinSock 2.0.  We need to dynamically */
+  /* load ws2_32.dll and get the function pointers we need. */
+  wsock2 = Curl_load_library(TEXT("WS2_32.DLL"));
+  if(wsock2 == NULL) {
+    failf(data, "failed to load WS2_32.DLL (%u)", GetLastError());
+    return CURLE_FAILED_INIT;
+  }
+
+  /* Grab a pointer to WSACreateEvent */
+  create_event_func = GetProcAddress(wsock2, "WSACreateEvent");
+  if(create_event_func == NULL) {
+    failf(data, "failed to find WSACreateEvent function (%u)", GetLastError());
+    FreeLibrary(wsock2);
+    return CURLE_FAILED_INIT;
+  }
+
+  /* And WSACloseEvent */
+  close_event_func = GetProcAddress(wsock2, "WSACloseEvent");
+  if(close_event_func == NULL) {
+    failf(data, "failed to find WSACloseEvent function (%u)", GetLastError());
+    FreeLibrary(wsock2);
+    return CURLE_FAILED_INIT;
+  }
+
+  /* And WSAEventSelect */
+  event_select_func = GetProcAddress(wsock2, "WSAEventSelect");
+  if(event_select_func == NULL) {
+    failf(data, "failed to find WSAEventSelect function (%u)", GetLastError());
+    FreeLibrary(wsock2);
+    return CURLE_FAILED_INIT;
+  }
+
+  /* And WSAEnumNetworkEvents */
+  enum_netevents_func = GetProcAddress(wsock2, "WSAEnumNetworkEvents");
+  if(enum_netevents_func == NULL) {
+    failf(data, "failed to find WSAEnumNetworkEvents function (%u)",
+          GetLastError());
+    FreeLibrary(wsock2);
+    return CURLE_FAILED_INIT;
+  }
+
+  /* We want to wait for both stdin and the socket. Since
+  ** the select() function in winsock only works on sockets
+  ** we have to use the WaitForMultipleObjects() call.
+  */
+
+  /* First, create a sockets event object */
+  event_handle = (WSAEVENT)create_event_func();
+  if(event_handle == WSA_INVALID_EVENT) {
+    failf(data, "WSACreateEvent failed (%d)", SOCKERRNO);
+    FreeLibrary(wsock2);
+    return CURLE_FAILED_INIT;
+  }
+
+  /* Tell winsock what events we want to listen to */
+  if(event_select_func(sockfd, event_handle, FD_READ|FD_CLOSE) ==
+     SOCKET_ERROR) {
+    close_event_func(event_handle);
+    FreeLibrary(wsock2);
+    return CURLE_OK;
+  }
+
+  /* The get the Windows file handle for stdin */
+  stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
+
+  /* Create the list of objects to wait for */
+  objs[0] = event_handle;
+  objs[1] = stdin_handle;
+
+  /* If stdin_handle is a pipe, use PeekNamedPipe() method to check it,
+     else use the old WaitForMultipleObjects() way */
+  if(GetFileType(stdin_handle) == FILE_TYPE_PIPE ||
+     data->set.is_fread_set) {
+    /* Don't wait for stdin_handle, just wait for event_handle */
+    obj_count = 1;
+    /* Check stdin_handle per 100 milliseconds */
+    wait_timeout = 100;
+  }
+  else {
+    obj_count = 2;
+    wait_timeout = 1000;
+  }
+
+  /* Keep on listening and act on events */
+  while(keepon) {
+    const DWORD buf_size = (DWORD)data->set.buffer_size;
+    waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout);
+    switch(waitret) {
+    case WAIT_TIMEOUT:
+    {
+      for(;;) {
+        if(data->set.is_fread_set) {
+          size_t n;
+          /* read from user-supplied method */
+          n = data->state.fread_func(buf, 1, buf_size, data->state.in);
+          if(n == CURL_READFUNC_ABORT) {
+            keepon = FALSE;
+            result = CURLE_READ_ERROR;
+            break;
+          }
+
+          if(n == CURL_READFUNC_PAUSE)
+            break;
+
+          if(n == 0)                        /* no bytes */
+            break;
+
+          readfile_read = (DWORD)n; /* fall thru with number of bytes read */
+        }
+        else {
+          /* read from stdin */
+          if(!PeekNamedPipe(stdin_handle, NULL, 0, NULL,
+                            &readfile_read, NULL)) {
+            keepon = FALSE;
+            result = CURLE_READ_ERROR;
+            break;
+          }
+
+          if(!readfile_read)
+            break;
+
+          if(!ReadFile(stdin_handle, buf, buf_size,
+                       &readfile_read, NULL)) {
+            keepon = FALSE;
+            result = CURLE_READ_ERROR;
+            break;
+          }
+        }
+
+        result = send_telnet_data(conn, buf, readfile_read);
+        if(result) {
+          keepon = FALSE;
+          break;
+        }
+      }
+    }
+    break;
+
+    case WAIT_OBJECT_0 + 1:
+    {
+      if(!ReadFile(stdin_handle, buf, buf_size,
+                   &readfile_read, NULL)) {
+        keepon = FALSE;
+        result = CURLE_READ_ERROR;
+        break;
+      }
+
+      result = send_telnet_data(conn, buf, readfile_read);
+      if(result) {
+        keepon = FALSE;
+        break;
+      }
+    }
+    break;
+
+    case WAIT_OBJECT_0:
+
+      events.lNetworkEvents = 0;
+      if(SOCKET_ERROR == enum_netevents_func(sockfd, event_handle, &events)) {
+        err = SOCKERRNO;
+        if(err != EINPROGRESS) {
+          infof(data, "WSAEnumNetworkEvents failed (%d)", err);
+          keepon = FALSE;
+          result = CURLE_READ_ERROR;
+        }
+        break;
+      }
+      if(events.lNetworkEvents & FD_READ) {
+        /* read data from network */
+        result = Curl_read(conn, sockfd, buf, data->set.buffer_size, &nread);
+        /* read would've blocked. Loop again */
+        if(result == CURLE_AGAIN)
+          break;
+        /* returned not-zero, this an error */
+        else if(result) {
+          keepon = FALSE;
+          break;
+        }
+        /* returned zero but actually received 0 or less here,
+           the server closed the connection and we bail out */
+        else if(nread <= 0) {
+          keepon = FALSE;
+          break;
+        }
+
+        result = telrcv(conn, (unsigned char *) buf, nread);
+        if(result) {
+          keepon = FALSE;
+          break;
+        }
+
+        /* Negotiate if the peer has started negotiating,
+           otherwise don't. We don't want to speak telnet with
+           non-telnet servers, like POP or SMTP. */
+        if(tn->please_negotiate && !tn->already_negotiated) {
+          negotiate(conn);
+          tn->already_negotiated = 1;
+        }
+      }
+      if(events.lNetworkEvents & FD_CLOSE) {
+        keepon = FALSE;
+      }
+      break;
+
+    }
+
+    if(data->set.timeout) {
+      now = Curl_now();
+      if(Curl_timediff(now, conn->created) >= data->set.timeout) {
+        failf(data, "Time-out");
+        result = CURLE_OPERATION_TIMEDOUT;
+        keepon = FALSE;
+      }
+    }
+  }
+
+  /* We called WSACreateEvent, so call WSACloseEvent */
+  if(!close_event_func(event_handle)) {
+    infof(data, "WSACloseEvent failed (%d)", SOCKERRNO);
+  }
+
+  /* "Forget" pointers into the library we're about to free */
+  create_event_func = NULL;
+  close_event_func = NULL;
+  event_select_func = NULL;
+  enum_netevents_func = NULL;
+
+  /* We called LoadLibrary, so call FreeLibrary */
+  if(!FreeLibrary(wsock2))
+    infof(data, "FreeLibrary(wsock2) failed (%u)", GetLastError());
+#else
+  pfd[0].fd = sockfd;
+  pfd[0].events = POLLIN;
+
+  if(data->set.is_fread_set) {
+    poll_cnt = 1;
+    interval_ms = 100; /* poll user-supplied read function */
+  }
+  else {
+    /* really using fread, so infile is a FILE* */
+    pfd[1].fd = fileno((FILE *)data->state.in);
+    pfd[1].events = POLLIN;
+    poll_cnt = 2;
+    interval_ms = 1 * 1000;
+  }
+
+  while(keepon) {
+    switch(Curl_poll(pfd, poll_cnt, interval_ms)) {
+    case -1:                    /* error, stop reading */
+      keepon = FALSE;
+      continue;
+    case 0:                     /* timeout */
+      pfd[0].revents = 0;
+      pfd[1].revents = 0;
+      /* fall through */
+    default:                    /* read! */
+      if(pfd[0].revents & POLLIN) {
+        /* read data from network */
+        result = Curl_read(conn, sockfd, buf, data->set.buffer_size, &nread);
+        /* read would've blocked. Loop again */
+        if(result == CURLE_AGAIN)
+          break;
+        /* returned not-zero, this an error */
+        if(result) {
+          keepon = FALSE;
+          break;
+        }
+        /* returned zero but actually received 0 or less here,
+           the server closed the connection and we bail out */
+        else if(nread <= 0) {
+          keepon = FALSE;
+          break;
+        }
+
+        total_dl += nread;
+        Curl_pgrsSetDownloadCounter(data, total_dl);
+        result = telrcv(conn, (unsigned char *)buf, nread);
+        if(result) {
+          keepon = FALSE;
+          break;
+        }
+
+        /* Negotiate if the peer has started negotiating,
+           otherwise don't. We don't want to speak telnet with
+           non-telnet servers, like POP or SMTP. */
+        if(tn->please_negotiate && !tn->already_negotiated) {
+          negotiate(conn);
+          tn->already_negotiated = 1;
+        }
+      }
+
+      nread = 0;
+      if(poll_cnt == 2) {
+        if(pfd[1].revents & POLLIN) { /* read from in file */
+          nread = read(pfd[1].fd, buf, data->set.buffer_size);
+        }
+      }
+      else {
+        /* read from user-supplied method */
+        nread = (int)data->state.fread_func(buf, 1, data->set.buffer_size,
+                                            data->state.in);
+        if(nread == CURL_READFUNC_ABORT) {
+          keepon = FALSE;
+          break;
+        }
+        if(nread == CURL_READFUNC_PAUSE)
+          break;
+      }
+
+      if(nread > 0) {
+        result = send_telnet_data(conn, buf, nread);
+        if(result) {
+          keepon = FALSE;
+          break;
+        }
+        total_ul += nread;
+        Curl_pgrsSetUploadCounter(data, total_ul);
+      }
+      else if(nread < 0)
+        keepon = FALSE;
+
+      break;
+    } /* poll switch statement */
+
+    if(data->set.timeout) {
+      now = Curl_now();
+      if(Curl_timediff(now, conn->created) >= data->set.timeout) {
+        failf(data, "Time-out");
+        result = CURLE_OPERATION_TIMEDOUT;
+        keepon = FALSE;
+      }
+    }
+
+    if(Curl_pgrsUpdate(conn)) {
+      result = CURLE_ABORTED_BY_CALLBACK;
+      break;
+    }
+  }
+#endif
+  /* mark this as "no further transfer wanted" */
+  Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+
+  return result;
+}
+#endif
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/telnet.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/telnet.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/telnet.h	(revision 331)
@@ -0,0 +1,29 @@
+#ifndef HEADER_CURL_TELNET_H
+#define HEADER_CURL_TELNET_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifndef CURL_DISABLE_TELNET
+extern const struct Curl_handler Curl_handler_telnet;
+#endif
+
+#endif /* HEADER_CURL_TELNET_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/tftp.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/tftp.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/tftp.c	(revision 331)
@@ -0,0 +1,1403 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifndef CURL_DISABLE_TFTP
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "transfer.h"
+#include "sendf.h"
+#include "tftp.h"
+#include "progress.h"
+#include "connect.h"
+#include "strerror.h"
+#include "sockaddr.h" /* required for Curl_sockaddr_storage */
+#include "multiif.h"
+#include "url.h"
+#include "strcase.h"
+#include "speedcheck.h"
+#include "select.h"
+#include "escape.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* RFC2348 allows the block size to be negotiated */
+#define TFTP_BLKSIZE_DEFAULT 512
+#define TFTP_BLKSIZE_MIN 8
+#define TFTP_BLKSIZE_MAX 65464
+#define TFTP_OPTION_BLKSIZE "blksize"
+
+/* from RFC2349: */
+#define TFTP_OPTION_TSIZE    "tsize"
+#define TFTP_OPTION_INTERVAL "timeout"
+
+typedef enum {
+  TFTP_MODE_NETASCII = 0,
+  TFTP_MODE_OCTET
+} tftp_mode_t;
+
+typedef enum {
+  TFTP_STATE_START = 0,
+  TFTP_STATE_RX,
+  TFTP_STATE_TX,
+  TFTP_STATE_FIN
+} tftp_state_t;
+
+typedef enum {
+  TFTP_EVENT_NONE = -1,
+  TFTP_EVENT_INIT = 0,
+  TFTP_EVENT_RRQ = 1,
+  TFTP_EVENT_WRQ = 2,
+  TFTP_EVENT_DATA = 3,
+  TFTP_EVENT_ACK = 4,
+  TFTP_EVENT_ERROR = 5,
+  TFTP_EVENT_OACK = 6,
+  TFTP_EVENT_TIMEOUT
+} tftp_event_t;
+
+typedef enum {
+  TFTP_ERR_UNDEF = 0,
+  TFTP_ERR_NOTFOUND,
+  TFTP_ERR_PERM,
+  TFTP_ERR_DISKFULL,
+  TFTP_ERR_ILLEGAL,
+  TFTP_ERR_UNKNOWNID,
+  TFTP_ERR_EXISTS,
+  TFTP_ERR_NOSUCHUSER,  /* This will never be triggered by this code */
+
+  /* The remaining error codes are internal to curl */
+  TFTP_ERR_NONE = -100,
+  TFTP_ERR_TIMEOUT,
+  TFTP_ERR_NORESPONSE
+} tftp_error_t;
+
+typedef struct tftp_packet {
+  unsigned char *data;
+} tftp_packet_t;
+
+typedef struct tftp_state_data {
+  tftp_state_t    state;
+  tftp_mode_t     mode;
+  tftp_error_t    error;
+  tftp_event_t    event;
+  struct connectdata      *conn;
+  curl_socket_t   sockfd;
+  int             retries;
+  int             retry_time;
+  int             retry_max;
+  time_t          start_time;
+  time_t          max_time;
+  time_t          rx_time;
+  unsigned short  block;
+  struct Curl_sockaddr_storage   local_addr;
+  struct Curl_sockaddr_storage   remote_addr;
+  curl_socklen_t  remote_addrlen;
+  int             rbytes;
+  int             sbytes;
+  int             blksize;
+  int             requested_blksize;
+  tftp_packet_t   rpacket;
+  tftp_packet_t   spacket;
+} tftp_state_data_t;
+
+
+/* Forward declarations */
+static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event);
+static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event);
+static CURLcode tftp_connect(struct connectdata *conn, bool *done);
+static CURLcode tftp_disconnect(struct connectdata *conn,
+                                bool dead_connection);
+static CURLcode tftp_do(struct connectdata *conn, bool *done);
+static CURLcode tftp_done(struct connectdata *conn,
+                          CURLcode, bool premature);
+static CURLcode tftp_setup_connection(struct connectdata * conn);
+static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done);
+static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done);
+static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks,
+                        int numsocks);
+static CURLcode tftp_translate_code(tftp_error_t error);
+
+
+/*
+ * TFTP protocol handler.
+ */
+
+const struct Curl_handler Curl_handler_tftp = {
+  "TFTP",                               /* scheme */
+  tftp_setup_connection,                /* setup_connection */
+  tftp_do,                              /* do_it */
+  tftp_done,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  tftp_connect,                         /* connect_it */
+  tftp_multi_statemach,                 /* connecting */
+  tftp_doing,                           /* doing */
+  tftp_getsock,                         /* proto_getsock */
+  tftp_getsock,                         /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  tftp_disconnect,                      /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  PORT_TFTP,                            /* defport */
+  CURLPROTO_TFTP,                       /* protocol */
+  PROTOPT_NONE | PROTOPT_NOURLQUERY     /* flags */
+};
+
+/**********************************************************
+ *
+ * tftp_set_timeouts -
+ *
+ * Set timeouts based on state machine state.
+ * Use user provided connect timeouts until DATA or ACK
+ * packet is received, then use user-provided transfer timeouts
+ *
+ *
+ **********************************************************/
+static CURLcode tftp_set_timeouts(tftp_state_data_t *state)
+{
+  time_t maxtime, timeout;
+  timediff_t timeout_ms;
+  bool start = (state->state == TFTP_STATE_START) ? TRUE : FALSE;
+
+  time(&state->start_time);
+
+  /* Compute drop-dead time */
+  timeout_ms = Curl_timeleft(state->conn->data, NULL, start);
+
+  if(timeout_ms < 0) {
+    /* time-out, bail out, go home */
+    failf(state->conn->data, "Connection time-out");
+    return CURLE_OPERATION_TIMEDOUT;
+  }
+
+  if(start) {
+
+    maxtime = (time_t)(timeout_ms + 500) / 1000;
+    state->max_time = state->start_time + maxtime;
+
+    /* Set per-block timeout to total */
+    timeout = maxtime;
+
+    /* Average restart after 5 seconds */
+    state->retry_max = (int)timeout/5;
+
+    if(state->retry_max < 1)
+      /* avoid division by zero below */
+      state->retry_max = 1;
+
+    /* Compute the re-start interval to suit the timeout */
+    state->retry_time = (int)timeout/state->retry_max;
+    if(state->retry_time<1)
+      state->retry_time = 1;
+
+  }
+  else {
+    if(timeout_ms > 0)
+      maxtime = (time_t)(timeout_ms + 500) / 1000;
+    else
+      maxtime = 3600;
+
+    state->max_time = state->start_time + maxtime;
+
+    /* Set per-block timeout to total */
+    timeout = maxtime;
+
+    /* Average reposting an ACK after 5 seconds */
+    state->retry_max = (int)timeout/5;
+  }
+  /* But bound the total number */
+  if(state->retry_max<3)
+    state->retry_max = 3;
+
+  if(state->retry_max>50)
+    state->retry_max = 50;
+
+  /* Compute the re-ACK interval to suit the timeout */
+  state->retry_time = (int)(timeout/state->retry_max);
+  if(state->retry_time<1)
+    state->retry_time = 1;
+
+  infof(state->conn->data,
+        "set timeouts for state %d; Total %ld, retry %d maxtry %d\n",
+        (int)state->state, (long)(state->max_time-state->start_time),
+        state->retry_time, state->retry_max);
+
+  /* init RX time */
+  time(&state->rx_time);
+
+  return CURLE_OK;
+}
+
+/**********************************************************
+ *
+ * tftp_set_send_first
+ *
+ * Event handler for the START state
+ *
+ **********************************************************/
+
+static void setpacketevent(tftp_packet_t *packet, unsigned short num)
+{
+  packet->data[0] = (unsigned char)(num >> 8);
+  packet->data[1] = (unsigned char)(num & 0xff);
+}
+
+
+static void setpacketblock(tftp_packet_t *packet, unsigned short num)
+{
+  packet->data[2] = (unsigned char)(num >> 8);
+  packet->data[3] = (unsigned char)(num & 0xff);
+}
+
+static unsigned short getrpacketevent(const tftp_packet_t *packet)
+{
+  return (unsigned short)((packet->data[0] << 8) | packet->data[1]);
+}
+
+static unsigned short getrpacketblock(const tftp_packet_t *packet)
+{
+  return (unsigned short)((packet->data[2] << 8) | packet->data[3]);
+}
+
+static size_t Curl_strnlen(const char *string, size_t maxlen)
+{
+  const char *end = memchr(string, '\0', maxlen);
+  return end ? (size_t) (end - string) : maxlen;
+}
+
+static const char *tftp_option_get(const char *buf, size_t len,
+                                   const char **option, const char **value)
+{
+  size_t loc;
+
+  loc = Curl_strnlen(buf, len);
+  loc++; /* NULL term */
+
+  if(loc >= len)
+    return NULL;
+  *option = buf;
+
+  loc += Curl_strnlen(buf + loc, len-loc);
+  loc++; /* NULL term */
+
+  if(loc > len)
+    return NULL;
+  *value = &buf[strlen(*option) + 1];
+
+  return &buf[loc];
+}
+
+static CURLcode tftp_parse_option_ack(tftp_state_data_t *state,
+                                      const char *ptr, int len)
+{
+  const char *tmp = ptr;
+  struct Curl_easy *data = state->conn->data;
+
+  /* if OACK doesn't contain blksize option, the default (512) must be used */
+  state->blksize = TFTP_BLKSIZE_DEFAULT;
+
+  while(tmp < ptr + len) {
+    const char *option, *value;
+
+    tmp = tftp_option_get(tmp, ptr + len - tmp, &option, &value);
+    if(tmp == NULL) {
+      failf(data, "Malformed ACK packet, rejecting");
+      return CURLE_TFTP_ILLEGAL;
+    }
+
+    infof(data, "got option=(%s) value=(%s)\n", option, value);
+
+    if(checkprefix(option, TFTP_OPTION_BLKSIZE)) {
+      long blksize;
+
+      blksize = strtol(value, NULL, 10);
+
+      if(!blksize) {
+        failf(data, "invalid blocksize value in OACK packet");
+        return CURLE_TFTP_ILLEGAL;
+      }
+      if(blksize > TFTP_BLKSIZE_MAX) {
+        failf(data, "%s (%d)", "blksize is larger than max supported",
+              TFTP_BLKSIZE_MAX);
+        return CURLE_TFTP_ILLEGAL;
+      }
+      else if(blksize < TFTP_BLKSIZE_MIN) {
+        failf(data, "%s (%d)", "blksize is smaller than min supported",
+              TFTP_BLKSIZE_MIN);
+        return CURLE_TFTP_ILLEGAL;
+      }
+      else if(blksize > state->requested_blksize) {
+        /* could realloc pkt buffers here, but the spec doesn't call out
+         * support for the server requesting a bigger blksize than the client
+         * requests */
+        failf(data, "%s (%ld)",
+              "server requested blksize larger than allocated", blksize);
+        return CURLE_TFTP_ILLEGAL;
+      }
+
+      state->blksize = (int)blksize;
+      infof(data, "%s (%d) %s (%d)\n", "blksize parsed from OACK",
+            state->blksize, "requested", state->requested_blksize);
+    }
+    else if(checkprefix(option, TFTP_OPTION_TSIZE)) {
+      long tsize = 0;
+
+      tsize = strtol(value, NULL, 10);
+      infof(data, "%s (%ld)\n", "tsize parsed from OACK", tsize);
+
+      /* tsize should be ignored on upload: Who cares about the size of the
+         remote file? */
+      if(!data->set.upload) {
+        if(!tsize) {
+          failf(data, "invalid tsize -:%s:- value in OACK packet", value);
+          return CURLE_TFTP_ILLEGAL;
+        }
+        Curl_pgrsSetDownloadSize(data, tsize);
+      }
+    }
+  }
+
+  return CURLE_OK;
+}
+
+static size_t tftp_option_add(tftp_state_data_t *state, size_t csize,
+                              char *buf, const char *option)
+{
+  if(( strlen(option) + csize + 1) > (size_t)state->blksize)
+    return 0;
+  strcpy(buf, option);
+  return strlen(option) + 1;
+}
+
+static CURLcode tftp_connect_for_tx(tftp_state_data_t *state,
+                                    tftp_event_t event)
+{
+  CURLcode result;
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  struct Curl_easy *data = state->conn->data;
+
+  infof(data, "%s\n", "Connected for transmit");
+#endif
+  state->state = TFTP_STATE_TX;
+  result = tftp_set_timeouts(state);
+  if(result)
+    return result;
+  return tftp_tx(state, event);
+}
+
+static CURLcode tftp_connect_for_rx(tftp_state_data_t *state,
+                                    tftp_event_t event)
+{
+  CURLcode result;
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  struct Curl_easy *data = state->conn->data;
+
+  infof(data, "%s\n", "Connected for receive");
+#endif
+  state->state = TFTP_STATE_RX;
+  result = tftp_set_timeouts(state);
+  if(result)
+    return result;
+  return tftp_rx(state, event);
+}
+
+static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
+{
+  size_t sbytes;
+  ssize_t senddata;
+  const char *mode = "octet";
+  char *filename;
+  char buf[64];
+  struct Curl_easy *data = state->conn->data;
+  CURLcode result = CURLE_OK;
+
+  /* Set ascii mode if -B flag was used */
+  if(data->set.prefer_ascii)
+    mode = "netascii";
+
+  switch(event) {
+
+  case TFTP_EVENT_INIT:    /* Send the first packet out */
+  case TFTP_EVENT_TIMEOUT: /* Resend the first packet out */
+    /* Increment the retry counter, quit if over the limit */
+    state->retries++;
+    if(state->retries>state->retry_max) {
+      state->error = TFTP_ERR_NORESPONSE;
+      state->state = TFTP_STATE_FIN;
+      return result;
+    }
+
+    if(data->set.upload) {
+      /* If we are uploading, send an WRQ */
+      setpacketevent(&state->spacket, TFTP_EVENT_WRQ);
+      state->conn->data->req.upload_fromhere =
+        (char *)state->spacket.data + 4;
+      if(data->state.infilesize != -1)
+        Curl_pgrsSetUploadSize(data, data->state.infilesize);
+    }
+    else {
+      /* If we are downloading, send an RRQ */
+      setpacketevent(&state->spacket, TFTP_EVENT_RRQ);
+    }
+    /* As RFC3617 describes the separator slash is not actually part of the
+       file name so we skip the always-present first letter of the path
+       string. */
+    result = Curl_urldecode(data, &state->conn->data->state.path[1], 0,
+                            &filename, NULL, FALSE);
+    if(result)
+      return result;
+
+    if(strlen(filename) > (state->blksize - strlen(mode) - 4)) {
+      failf(data, "TFTP file name too long\n");
+      free(filename);
+      return CURLE_TFTP_ILLEGAL; /* too long file name field */
+    }
+
+    snprintf((char *)state->spacket.data + 2,
+             state->blksize,
+             "%s%c%s%c", filename, '\0',  mode, '\0');
+    sbytes = 4 + strlen(filename) + strlen(mode);
+
+    /* optional addition of TFTP options */
+    if(!data->set.tftp_no_options) {
+      /* add tsize option */
+      if(data->set.upload && (data->state.infilesize != -1))
+        snprintf(buf, sizeof(buf), "%" CURL_FORMAT_CURL_OFF_T,
+                 data->state.infilesize);
+      else
+        strcpy(buf, "0"); /* the destination is large enough */
+
+      sbytes += tftp_option_add(state, sbytes,
+                                (char *)state->spacket.data + sbytes,
+                                TFTP_OPTION_TSIZE);
+      sbytes += tftp_option_add(state, sbytes,
+                                (char *)state->spacket.data + sbytes, buf);
+      /* add blksize option */
+      snprintf(buf, sizeof(buf), "%d", state->requested_blksize);
+      sbytes += tftp_option_add(state, sbytes,
+                                (char *)state->spacket.data + sbytes,
+                                TFTP_OPTION_BLKSIZE);
+      sbytes += tftp_option_add(state, sbytes,
+                                (char *)state->spacket.data + sbytes, buf);
+
+      /* add timeout option */
+      snprintf(buf, sizeof(buf), "%d", state->retry_time);
+      sbytes += tftp_option_add(state, sbytes,
+                                (char *)state->spacket.data + sbytes,
+                                TFTP_OPTION_INTERVAL);
+      sbytes += tftp_option_add(state, sbytes,
+                                (char *)state->spacket.data + sbytes, buf);
+    }
+
+    /* the typecase for the 3rd argument is mostly for systems that do
+       not have a size_t argument, like older unixes that want an 'int' */
+    senddata = sendto(state->sockfd, (void *)state->spacket.data,
+                      (SEND_TYPE_ARG3)sbytes, 0,
+                      state->conn->ip_addr->ai_addr,
+                      state->conn->ip_addr->ai_addrlen);
+    if(senddata != (ssize_t)sbytes) {
+      failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+    }
+    free(filename);
+    break;
+
+  case TFTP_EVENT_OACK:
+    if(data->set.upload) {
+      result = tftp_connect_for_tx(state, event);
+    }
+    else {
+      result = tftp_connect_for_rx(state, event);
+    }
+    break;
+
+  case TFTP_EVENT_ACK: /* Connected for transmit */
+    result = tftp_connect_for_tx(state, event);
+    break;
+
+  case TFTP_EVENT_DATA: /* Connected for receive */
+    result = tftp_connect_for_rx(state, event);
+    break;
+
+  case TFTP_EVENT_ERROR:
+    state->state = TFTP_STATE_FIN;
+    break;
+
+  default:
+    failf(state->conn->data, "tftp_send_first: internal error");
+    break;
+  }
+
+  return result;
+}
+
+/* the next blocknum is x + 1 but it needs to wrap at an unsigned 16bit
+   boundary */
+#define NEXT_BLOCKNUM(x) (((x) + 1)&0xffff)
+
+/**********************************************************
+ *
+ * tftp_rx
+ *
+ * Event handler for the RX state
+ *
+ **********************************************************/
+static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event)
+{
+  ssize_t sbytes;
+  int rblock;
+  struct Curl_easy *data = state->conn->data;
+
+  switch(event) {
+
+  case TFTP_EVENT_DATA:
+    /* Is this the block we expect? */
+    rblock = getrpacketblock(&state->rpacket);
+    if(NEXT_BLOCKNUM(state->block) == rblock) {
+      /* This is the expected block.  Reset counters and ACK it. */
+      state->retries = 0;
+    }
+    else if(state->block == rblock) {
+      /* This is the last recently received block again. Log it and ACK it
+         again. */
+      infof(data, "Received last DATA packet block %d again.\n", rblock);
+    }
+    else {
+      /* totally unexpected, just log it */
+      infof(data,
+            "Received unexpected DATA packet block %d, expecting block %d\n",
+            rblock, NEXT_BLOCKNUM(state->block));
+      break;
+    }
+
+    /* ACK this block. */
+    state->block = (unsigned short)rblock;
+    setpacketevent(&state->spacket, TFTP_EVENT_ACK);
+    setpacketblock(&state->spacket, state->block);
+    sbytes = sendto(state->sockfd, (void *)state->spacket.data,
+                    4, SEND_4TH_ARG,
+                    (struct sockaddr *)&state->remote_addr,
+                    state->remote_addrlen);
+    if(sbytes < 0) {
+      failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+      return CURLE_SEND_ERROR;
+    }
+
+    /* Check if completed (That is, a less than full packet is received) */
+    if(state->rbytes < (ssize_t)state->blksize + 4) {
+      state->state = TFTP_STATE_FIN;
+    }
+    else {
+      state->state = TFTP_STATE_RX;
+    }
+    time(&state->rx_time);
+    break;
+
+  case TFTP_EVENT_OACK:
+    /* ACK option acknowledgement so we can move on to data */
+    state->block = 0;
+    state->retries = 0;
+    setpacketevent(&state->spacket, TFTP_EVENT_ACK);
+    setpacketblock(&state->spacket, state->block);
+    sbytes = sendto(state->sockfd, (void *)state->spacket.data,
+                    4, SEND_4TH_ARG,
+                    (struct sockaddr *)&state->remote_addr,
+                    state->remote_addrlen);
+    if(sbytes < 0) {
+      failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+      return CURLE_SEND_ERROR;
+    }
+
+    /* we're ready to RX data */
+    state->state = TFTP_STATE_RX;
+    time(&state->rx_time);
+    break;
+
+  case TFTP_EVENT_TIMEOUT:
+    /* Increment the retry count and fail if over the limit */
+    state->retries++;
+    infof(data,
+          "Timeout waiting for block %d ACK.  Retries = %d\n",
+          NEXT_BLOCKNUM(state->block), state->retries);
+    if(state->retries > state->retry_max) {
+      state->error = TFTP_ERR_TIMEOUT;
+      state->state = TFTP_STATE_FIN;
+    }
+    else {
+      /* Resend the previous ACK */
+      sbytes = sendto(state->sockfd, (void *)state->spacket.data,
+                      4, SEND_4TH_ARG,
+                      (struct sockaddr *)&state->remote_addr,
+                      state->remote_addrlen);
+      if(sbytes<0) {
+        failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+        return CURLE_SEND_ERROR;
+      }
+    }
+    break;
+
+  case TFTP_EVENT_ERROR:
+    setpacketevent(&state->spacket, TFTP_EVENT_ERROR);
+    setpacketblock(&state->spacket, state->block);
+    (void)sendto(state->sockfd, (void *)state->spacket.data,
+                 4, SEND_4TH_ARG,
+                 (struct sockaddr *)&state->remote_addr,
+                 state->remote_addrlen);
+    /* don't bother with the return code, but if the socket is still up we
+     * should be a good TFTP client and let the server know we're done */
+    state->state = TFTP_STATE_FIN;
+    break;
+
+  default:
+    failf(data, "%s", "tftp_rx: internal error");
+    return CURLE_TFTP_ILLEGAL; /* not really the perfect return code for
+                                  this */
+  }
+  return CURLE_OK;
+}
+
+/**********************************************************
+ *
+ * tftp_tx
+ *
+ * Event handler for the TX state
+ *
+ **********************************************************/
+static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event)
+{
+  struct Curl_easy *data = state->conn->data;
+  ssize_t sbytes;
+  int rblock;
+  CURLcode result = CURLE_OK;
+  struct SingleRequest *k = &data->req;
+  int cb; /* Bytes currently read */
+
+  switch(event) {
+
+  case TFTP_EVENT_ACK:
+  case TFTP_EVENT_OACK:
+    if(event == TFTP_EVENT_ACK) {
+      /* Ack the packet */
+      rblock = getrpacketblock(&state->rpacket);
+
+      if(rblock != state->block &&
+         /* There's a bug in tftpd-hpa that causes it to send us an ack for
+          * 65535 when the block number wraps to 0. So when we're expecting
+          * 0, also accept 65535. See
+          * http://syslinux.zytor.com/archives/2010-September/015253.html
+          * */
+         !(state->block == 0 && rblock == 65535)) {
+        /* This isn't the expected block.  Log it and up the retry counter */
+        infof(data, "Received ACK for block %d, expecting %d\n",
+              rblock, state->block);
+        state->retries++;
+        /* Bail out if over the maximum */
+        if(state->retries>state->retry_max) {
+          failf(data, "tftp_tx: giving up waiting for block %d ack",
+                state->block);
+          result = CURLE_SEND_ERROR;
+        }
+        else {
+          /* Re-send the data packet */
+          sbytes = sendto(state->sockfd, (void *)state->spacket.data,
+                          4 + state->sbytes, SEND_4TH_ARG,
+                          (struct sockaddr *)&state->remote_addr,
+                          state->remote_addrlen);
+          /* Check all sbytes were sent */
+          if(sbytes<0) {
+            failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+            result = CURLE_SEND_ERROR;
+          }
+        }
+
+        return result;
+      }
+      /* This is the expected packet.  Reset the counters and send the next
+         block */
+      time(&state->rx_time);
+      state->block++;
+    }
+    else
+      state->block = 1; /* first data block is 1 when using OACK */
+
+    state->retries = 0;
+    setpacketevent(&state->spacket, TFTP_EVENT_DATA);
+    setpacketblock(&state->spacket, state->block);
+    if(state->block > 1 && state->sbytes < (int)state->blksize) {
+      state->state = TFTP_STATE_FIN;
+      return CURLE_OK;
+    }
+
+    /* TFTP considers data block size < 512 bytes as an end of session. So
+     * in some cases we must wait for additional data to build full (512 bytes)
+     * data block.
+     * */
+    state->sbytes = 0;
+    state->conn->data->req.upload_fromhere = (char *)state->spacket.data + 4;
+    do {
+      result = Curl_fillreadbuffer(state->conn, state->blksize - state->sbytes,
+                                   &cb);
+      if(result)
+        return result;
+      state->sbytes += cb;
+      state->conn->data->req.upload_fromhere += cb;
+    } while(state->sbytes < state->blksize && cb != 0);
+
+    sbytes = sendto(state->sockfd, (void *) state->spacket.data,
+                    4 + state->sbytes, SEND_4TH_ARG,
+                    (struct sockaddr *)&state->remote_addr,
+                    state->remote_addrlen);
+    /* Check all sbytes were sent */
+    if(sbytes<0) {
+      failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+      return CURLE_SEND_ERROR;
+    }
+    /* Update the progress meter */
+    k->writebytecount += state->sbytes;
+    Curl_pgrsSetUploadCounter(data, k->writebytecount);
+    break;
+
+  case TFTP_EVENT_TIMEOUT:
+    /* Increment the retry counter and log the timeout */
+    state->retries++;
+    infof(data, "Timeout waiting for block %d ACK. "
+          " Retries = %d\n", NEXT_BLOCKNUM(state->block), state->retries);
+    /* Decide if we've had enough */
+    if(state->retries > state->retry_max) {
+      state->error = TFTP_ERR_TIMEOUT;
+      state->state = TFTP_STATE_FIN;
+    }
+    else {
+      /* Re-send the data packet */
+      sbytes = sendto(state->sockfd, (void *)state->spacket.data,
+                      4 + state->sbytes, SEND_4TH_ARG,
+                      (struct sockaddr *)&state->remote_addr,
+                      state->remote_addrlen);
+      /* Check all sbytes were sent */
+      if(sbytes<0) {
+        failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO));
+        return CURLE_SEND_ERROR;
+      }
+      /* since this was a re-send, we remain at the still byte position */
+      Curl_pgrsSetUploadCounter(data, k->writebytecount);
+    }
+    break;
+
+  case TFTP_EVENT_ERROR:
+    state->state = TFTP_STATE_FIN;
+    setpacketevent(&state->spacket, TFTP_EVENT_ERROR);
+    setpacketblock(&state->spacket, state->block);
+    (void)sendto(state->sockfd, (void *)state->spacket.data, 4, SEND_4TH_ARG,
+                 (struct sockaddr *)&state->remote_addr,
+                 state->remote_addrlen);
+    /* don't bother with the return code, but if the socket is still up we
+     * should be a good TFTP client and let the server know we're done */
+    state->state = TFTP_STATE_FIN;
+    break;
+
+  default:
+    failf(data, "tftp_tx: internal error, event: %i", (int)(event));
+    break;
+  }
+
+  return result;
+}
+
+/**********************************************************
+ *
+ * tftp_translate_code
+ *
+ * Translate internal error codes to CURL error codes
+ *
+ **********************************************************/
+static CURLcode tftp_translate_code(tftp_error_t error)
+{
+  CURLcode result = CURLE_OK;
+
+  if(error != TFTP_ERR_NONE) {
+    switch(error) {
+    case TFTP_ERR_NOTFOUND:
+      result = CURLE_TFTP_NOTFOUND;
+      break;
+    case TFTP_ERR_PERM:
+      result = CURLE_TFTP_PERM;
+      break;
+    case TFTP_ERR_DISKFULL:
+      result = CURLE_REMOTE_DISK_FULL;
+      break;
+    case TFTP_ERR_UNDEF:
+    case TFTP_ERR_ILLEGAL:
+      result = CURLE_TFTP_ILLEGAL;
+      break;
+    case TFTP_ERR_UNKNOWNID:
+      result = CURLE_TFTP_UNKNOWNID;
+      break;
+    case TFTP_ERR_EXISTS:
+      result = CURLE_REMOTE_FILE_EXISTS;
+      break;
+    case TFTP_ERR_NOSUCHUSER:
+      result = CURLE_TFTP_NOSUCHUSER;
+      break;
+    case TFTP_ERR_TIMEOUT:
+      result = CURLE_OPERATION_TIMEDOUT;
+      break;
+    case TFTP_ERR_NORESPONSE:
+      result = CURLE_COULDNT_CONNECT;
+      break;
+    default:
+      result = CURLE_ABORTED_BY_CALLBACK;
+      break;
+    }
+  }
+  else
+    result = CURLE_OK;
+
+  return result;
+}
+
+/**********************************************************
+ *
+ * tftp_state_machine
+ *
+ * The tftp state machine event dispatcher
+ *
+ **********************************************************/
+static CURLcode tftp_state_machine(tftp_state_data_t *state,
+                                   tftp_event_t event)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = state->conn->data;
+
+  switch(state->state) {
+  case TFTP_STATE_START:
+    DEBUGF(infof(data, "TFTP_STATE_START\n"));
+    result = tftp_send_first(state, event);
+    break;
+  case TFTP_STATE_RX:
+    DEBUGF(infof(data, "TFTP_STATE_RX\n"));
+    result = tftp_rx(state, event);
+    break;
+  case TFTP_STATE_TX:
+    DEBUGF(infof(data, "TFTP_STATE_TX\n"));
+    result = tftp_tx(state, event);
+    break;
+  case TFTP_STATE_FIN:
+    infof(data, "%s\n", "TFTP finished");
+    break;
+  default:
+    DEBUGF(infof(data, "STATE: %d\n", state->state));
+    failf(data, "%s", "Internal state machine error");
+    result = CURLE_TFTP_ILLEGAL;
+    break;
+  }
+
+  return result;
+}
+
+/**********************************************************
+ *
+ * tftp_disconnect
+ *
+ * The disconnect callback
+ *
+ **********************************************************/
+static CURLcode tftp_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  tftp_state_data_t *state = conn->proto.tftpc;
+  (void) dead_connection;
+
+  /* done, free dynamically allocated pkt buffers */
+  if(state) {
+    Curl_safefree(state->rpacket.data);
+    Curl_safefree(state->spacket.data);
+    free(state);
+  }
+
+  return CURLE_OK;
+}
+
+/**********************************************************
+ *
+ * tftp_connect
+ *
+ * The connect callback
+ *
+ **********************************************************/
+static CURLcode tftp_connect(struct connectdata *conn, bool *done)
+{
+  tftp_state_data_t *state;
+  int blksize, rc;
+
+  blksize = TFTP_BLKSIZE_DEFAULT;
+
+  state = conn->proto.tftpc = calloc(1, sizeof(tftp_state_data_t));
+  if(!state)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* alloc pkt buffers based on specified blksize */
+  if(conn->data->set.tftp_blksize) {
+    blksize = (int)conn->data->set.tftp_blksize;
+    if(blksize > TFTP_BLKSIZE_MAX || blksize < TFTP_BLKSIZE_MIN)
+      return CURLE_TFTP_ILLEGAL;
+  }
+
+  if(!state->rpacket.data) {
+    state->rpacket.data = calloc(1, blksize + 2 + 2);
+
+    if(!state->rpacket.data)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  if(!state->spacket.data) {
+    state->spacket.data = calloc(1, blksize + 2 + 2);
+
+    if(!state->spacket.data)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* we don't keep TFTP connections up basically because there's none or very
+   * little gain for UDP */
+  connclose(conn, "TFTP");
+
+  state->conn = conn;
+  state->sockfd = state->conn->sock[FIRSTSOCKET];
+  state->state = TFTP_STATE_START;
+  state->error = TFTP_ERR_NONE;
+  state->blksize = TFTP_BLKSIZE_DEFAULT;
+  state->requested_blksize = blksize;
+
+  ((struct sockaddr *)&state->local_addr)->sa_family =
+    (unsigned short)(conn->ip_addr->ai_family);
+
+  tftp_set_timeouts(state);
+
+  if(!conn->bits.bound) {
+    /* If not already bound, bind to any interface, random UDP port. If it is
+     * reused or a custom local port was desired, this has already been done!
+     *
+     * We once used the size of the local_addr struct as the third argument
+     * for bind() to better work with IPv6 or whatever size the struct could
+     * have, but we learned that at least Tru64, AIX and IRIX *requires* the
+     * size of that argument to match the exact size of a 'sockaddr_in' struct
+     * when running IPv4-only.
+     *
+     * Therefore we use the size from the address we connected to, which we
+     * assume uses the same IP version and thus hopefully this works for both
+     * IPv4 and IPv6...
+     */
+    rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr,
+              conn->ip_addr->ai_addrlen);
+    if(rc) {
+      failf(conn->data, "bind() failed; %s",
+            Curl_strerror(conn, SOCKERRNO));
+      return CURLE_COULDNT_CONNECT;
+    }
+    conn->bits.bound = TRUE;
+  }
+
+  Curl_pgrsStartNow(conn->data);
+
+  *done = TRUE;
+
+  return CURLE_OK;
+}
+
+/**********************************************************
+ *
+ * tftp_done
+ *
+ * The done callback
+ *
+ **********************************************************/
+static CURLcode tftp_done(struct connectdata *conn, CURLcode status,
+                          bool premature)
+{
+  CURLcode result = CURLE_OK;
+  tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc;
+
+  (void)status; /* unused */
+  (void)premature; /* not used */
+
+  if(Curl_pgrsDone(conn))
+    return CURLE_ABORTED_BY_CALLBACK;
+
+  /* If we have encountered an error */
+  if(state)
+    result = tftp_translate_code(state->error);
+
+  return result;
+}
+
+/**********************************************************
+ *
+ * tftp_getsock
+ *
+ * The getsock callback
+ *
+ **********************************************************/
+static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks,
+                        int numsocks)
+{
+  if(!numsocks)
+    return GETSOCK_BLANK;
+
+  socks[0] = conn->sock[FIRSTSOCKET];
+
+  return GETSOCK_READSOCK(0);
+}
+
+/**********************************************************
+ *
+ * tftp_receive_packet
+ *
+ * Called once select fires and data is ready on the socket
+ *
+ **********************************************************/
+static CURLcode tftp_receive_packet(struct connectdata *conn)
+{
+  struct Curl_sockaddr_storage fromaddr;
+  curl_socklen_t        fromlen;
+  CURLcode              result = CURLE_OK;
+  struct Curl_easy  *data = conn->data;
+  tftp_state_data_t     *state = (tftp_state_data_t *)conn->proto.tftpc;
+  struct SingleRequest  *k = &data->req;
+
+  /* Receive the packet */
+  fromlen = sizeof(fromaddr);
+  state->rbytes = (int)recvfrom(state->sockfd,
+                                (void *)state->rpacket.data,
+                                state->blksize + 4,
+                                0,
+                                (struct sockaddr *)&fromaddr,
+                                &fromlen);
+  if(state->remote_addrlen == 0) {
+    memcpy(&state->remote_addr, &fromaddr, fromlen);
+    state->remote_addrlen = fromlen;
+  }
+
+  /* Sanity check packet length */
+  if(state->rbytes < 4) {
+    failf(data, "Received too short packet");
+    /* Not a timeout, but how best to handle it? */
+    state->event = TFTP_EVENT_TIMEOUT;
+  }
+  else {
+    /* The event is given by the TFTP packet time */
+    unsigned short event = getrpacketevent(&state->rpacket);
+    state->event = (tftp_event_t)event;
+
+    switch(state->event) {
+    case TFTP_EVENT_DATA:
+      /* Don't pass to the client empty or retransmitted packets */
+      if(state->rbytes > 4 &&
+         (NEXT_BLOCKNUM(state->block) == getrpacketblock(&state->rpacket))) {
+        result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                   (char *)state->rpacket.data + 4,
+                                   state->rbytes-4);
+        if(result) {
+          tftp_state_machine(state, TFTP_EVENT_ERROR);
+          return result;
+        }
+        k->bytecount += state->rbytes-4;
+        Curl_pgrsSetDownloadCounter(data, (curl_off_t) k->bytecount);
+      }
+      break;
+    case TFTP_EVENT_ERROR:
+    {
+      unsigned short error = getrpacketblock(&state->rpacket);
+      state->error = (tftp_error_t)error;
+      infof(data, "%s\n", (const char *)state->rpacket.data + 4);
+      break;
+    }
+    case TFTP_EVENT_ACK:
+      break;
+    case TFTP_EVENT_OACK:
+      result = tftp_parse_option_ack(state,
+                                     (const char *)state->rpacket.data + 2,
+                                     state->rbytes-2);
+      if(result)
+        return result;
+      break;
+    case TFTP_EVENT_RRQ:
+    case TFTP_EVENT_WRQ:
+    default:
+      failf(data, "%s", "Internal error: Unexpected packet");
+      break;
+    }
+
+    /* Update the progress meter */
+    if(Curl_pgrsUpdate(conn)) {
+      tftp_state_machine(state, TFTP_EVENT_ERROR);
+      return CURLE_ABORTED_BY_CALLBACK;
+    }
+  }
+  return result;
+}
+
+/**********************************************************
+ *
+ * tftp_state_timeout
+ *
+ * Check if timeouts have been reached
+ *
+ **********************************************************/
+static long tftp_state_timeout(struct connectdata *conn, tftp_event_t *event)
+{
+  time_t                current;
+  tftp_state_data_t     *state = (tftp_state_data_t *)conn->proto.tftpc;
+
+  if(event)
+    *event = TFTP_EVENT_NONE;
+
+  time(&current);
+  if(current > state->max_time) {
+    DEBUGF(infof(conn->data, "timeout: %ld > %ld\n",
+                 (long)current, (long)state->max_time));
+    state->error = TFTP_ERR_TIMEOUT;
+    state->state = TFTP_STATE_FIN;
+    return 0;
+  }
+  if(current > state->rx_time + state->retry_time) {
+    if(event)
+      *event = TFTP_EVENT_TIMEOUT;
+    time(&state->rx_time); /* update even though we received nothing */
+  }
+
+  /* there's a typecast below here since 'time_t' may in fact be larger than
+     'long', but we estimate that a 'long' will still be able to hold number
+     of seconds even if "only" 32 bit */
+  return (long)(state->max_time - current);
+}
+
+/**********************************************************
+ *
+ * tftp_multi_statemach
+ *
+ * Handle single RX socket event and return
+ *
+ **********************************************************/
+static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done)
+{
+  int                   rc;
+  tftp_event_t          event;
+  CURLcode              result = CURLE_OK;
+  struct Curl_easy  *data = conn->data;
+  tftp_state_data_t     *state = (tftp_state_data_t *)conn->proto.tftpc;
+  long                  timeout_ms = tftp_state_timeout(conn, &event);
+
+  *done = FALSE;
+
+  if(timeout_ms <= 0) {
+    failf(data, "TFTP response timeout");
+    return CURLE_OPERATION_TIMEDOUT;
+  }
+  if(event != TFTP_EVENT_NONE) {
+    result = tftp_state_machine(state, event);
+    if(result)
+      return result;
+    *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE;
+    if(*done)
+      /* Tell curl we're done */
+      Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+  }
+  else {
+    /* no timeouts to handle, check our socket */
+    rc = SOCKET_READABLE(state->sockfd, 0);
+
+    if(rc == -1) {
+      /* bail out */
+      int error = SOCKERRNO;
+      failf(data, "%s", Curl_strerror(conn, error));
+      state->event = TFTP_EVENT_ERROR;
+    }
+    else if(rc != 0) {
+      result = tftp_receive_packet(conn);
+      if(result)
+        return result;
+      result = tftp_state_machine(state, state->event);
+      if(result)
+        return result;
+      *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE;
+      if(*done)
+        /* Tell curl we're done */
+        Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
+    }
+    /* if rc == 0, then select() timed out */
+  }
+
+  return result;
+}
+
+/**********************************************************
+ *
+ * tftp_doing
+ *
+ * Called from multi.c while DOing
+ *
+ **********************************************************/
+static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done)
+{
+  CURLcode result;
+  result = tftp_multi_statemach(conn, dophase_done);
+
+  if(*dophase_done) {
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+  }
+  else if(!result) {
+    /* The multi code doesn't have this logic for the DOING state so we
+       provide it for TFTP since it may do the entire transfer in this
+       state. */
+    if(Curl_pgrsUpdate(conn))
+      result = CURLE_ABORTED_BY_CALLBACK;
+    else
+      result = Curl_speedcheck(conn->data, Curl_now());
+  }
+  return result;
+}
+
+/**********************************************************
+ *
+ * tftp_peform
+ *
+ * Entry point for transfer from tftp_do, sarts state mach
+ *
+ **********************************************************/
+static CURLcode tftp_perform(struct connectdata *conn, bool *dophase_done)
+{
+  CURLcode              result = CURLE_OK;
+  tftp_state_data_t     *state = (tftp_state_data_t *)conn->proto.tftpc;
+
+  *dophase_done = FALSE;
+
+  result = tftp_state_machine(state, TFTP_EVENT_INIT);
+
+  if((state->state == TFTP_STATE_FIN) || result)
+    return result;
+
+  tftp_multi_statemach(conn, dophase_done);
+
+  if(*dophase_done)
+    DEBUGF(infof(conn->data, "DO phase is complete\n"));
+
+  return result;
+}
+
+
+/**********************************************************
+ *
+ * tftp_do
+ *
+ * The do callback
+ *
+ * This callback initiates the TFTP transfer
+ *
+ **********************************************************/
+
+static CURLcode tftp_do(struct connectdata *conn, bool *done)
+{
+  tftp_state_data_t *state;
+  CURLcode result;
+
+  *done = FALSE;
+
+  if(!conn->proto.tftpc) {
+    result = tftp_connect(conn, done);
+    if(result)
+      return result;
+  }
+
+  state = (tftp_state_data_t *)conn->proto.tftpc;
+  if(!state)
+    return CURLE_TFTP_ILLEGAL;
+
+  result = tftp_perform(conn, done);
+
+  /* If tftp_perform() returned an error, use that for return code. If it
+     was OK, see if tftp_translate_code() has an error. */
+  if(!result)
+    /* If we have encountered an internal tftp error, translate it. */
+    result = tftp_translate_code(state->error);
+
+  return result;
+}
+
+static CURLcode tftp_setup_connection(struct connectdata * conn)
+{
+  struct Curl_easy *data = conn->data;
+  char *type;
+  char command;
+
+  conn->socktype = SOCK_DGRAM;   /* UDP datagram based */
+
+  /* TFTP URLs support an extension like ";mode=<typecode>" that
+   * we'll try to get now! */
+  type = strstr(data->state.path, ";mode=");
+
+  if(!type)
+    type = strstr(conn->host.rawalloc, ";mode=");
+
+  if(type) {
+    *type = 0;                   /* it was in the middle of the hostname */
+    command = Curl_raw_toupper(type[6]);
+
+    switch(command) {
+    case 'A': /* ASCII mode */
+    case 'N': /* NETASCII mode */
+      data->set.prefer_ascii = TRUE;
+      break;
+
+    case 'O': /* octet mode */
+    case 'I': /* binary mode */
+    default:
+      /* switch off ASCII */
+      data->set.prefer_ascii = FALSE;
+      break;
+    }
+  }
+
+  return CURLE_OK;
+}
+#endif
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/tftp.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/tftp.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/tftp.h	(revision 331)
@@ -0,0 +1,29 @@
+#ifndef HEADER_CURL_TFTP_H
+#define HEADER_CURL_TFTP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#ifndef CURL_DISABLE_TFTP
+extern const struct Curl_handler Curl_handler_tftp;
+#endif
+
+#endif /* HEADER_CURL_TFTP_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/timeval.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/timeval.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/timeval.c	(revision 331)
@@ -0,0 +1,186 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "timeval.h"
+
+#if defined(WIN32) && !defined(MSDOS)
+
+struct curltime Curl_now(void)
+{
+  /*
+  ** GetTickCount() is available on _all_ Windows versions from W95 up
+  ** to nowadays. Returns milliseconds elapsed since last system boot,
+  ** increases monotonically and wraps once 49.7 days have elapsed.
+  */
+  struct curltime now;
+#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \
+    (_WIN32_WINNT < _WIN32_WINNT_VISTA)
+  DWORD milliseconds = GetTickCount();
+  now.tv_sec = milliseconds / 1000;
+  now.tv_usec = (milliseconds % 1000) * 1000;
+#else
+  ULONGLONG milliseconds = GetTickCount64();
+  now.tv_sec = (time_t) (milliseconds / 1000);
+  now.tv_usec = (unsigned int) (milliseconds % 1000) * 1000;
+#endif
+
+  return now;
+}
+
+#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
+
+struct curltime Curl_now(void)
+{
+  /*
+  ** clock_gettime() is granted to be increased monotonically when the
+  ** monotonic clock is queried. Time starting point is unspecified, it
+  ** could be the system start-up time, the Epoch, or something else,
+  ** in any case the time starting point does not change once that the
+  ** system has started up.
+  */
+  struct timeval now;
+  struct curltime cnow;
+  struct timespec tsnow;
+  if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) {
+    cnow.tv_sec = tsnow.tv_sec;
+    cnow.tv_usec = (unsigned int)(tsnow.tv_nsec / 1000);
+  }
+  /*
+  ** Even when the configure process has truly detected monotonic clock
+  ** availability, it might happen that it is not actually available at
+  ** run-time. When this occurs simply fallback to other time source.
+  */
+#ifdef HAVE_GETTIMEOFDAY
+  else {
+    (void)gettimeofday(&now, NULL);
+    cnow.tv_sec = now.tv_sec;
+    cnow.tv_usec = (unsigned int)now.tv_usec;
+  }
+#else
+  else {
+    cnow.tv_sec = time(NULL);
+    cnow.tv_usec = 0;
+  }
+#endif
+  return cnow;
+}
+
+#elif defined(HAVE_MACH_ABSOLUTE_TIME)
+
+#include <stdint.h>
+#include <mach/mach_time.h>
+
+struct curltime Curl_now(void)
+{
+  /*
+  ** Monotonic timer on Mac OS is provided by mach_absolute_time(), which
+  ** returns time in Mach "absolute time units," which are platform-dependent.
+  ** To convert to nanoseconds, one must use conversion factors specified by
+  ** mach_timebase_info().
+  */
+  static mach_timebase_info_data_t timebase;
+  struct curltime cnow;
+  uint64_t usecs;
+
+  if(0 == timebase.denom)
+    (void) mach_timebase_info(&timebase);
+
+  usecs = mach_absolute_time();
+  usecs *= timebase.numer;
+  usecs /= timebase.denom;
+  usecs /= 1000;
+
+  cnow.tv_sec = usecs / 1000000;
+  cnow.tv_usec = usecs % 1000000;
+
+  return cnow;
+}
+
+#elif defined(HAVE_GETTIMEOFDAY)
+
+struct curltime Curl_now(void)
+{
+  /*
+  ** gettimeofday() is not granted to be increased monotonically, due to
+  ** clock drifting and external source time synchronization it can jump
+  ** forward or backward in time.
+  */
+  struct timeval now;
+  struct curltime ret;
+  (void)gettimeofday(&now, NULL);
+  ret.tv_sec = now.tv_sec;
+  ret.tv_usec = now.tv_usec;
+  return ret;
+}
+
+#else
+
+struct curltime Curl_now(void)
+{
+  /*
+  ** time() returns the value of time in seconds since the Epoch.
+  */
+  struct curltime now;
+  now.tv_sec = time(NULL);
+  now.tv_usec = 0;
+  return now;
+}
+
+#endif
+
+#if SIZEOF_TIME_T < 8
+#define TIME_MAX INT_MAX
+#define TIME_MIN INT_MIN
+#else
+#define TIME_MAX 9223372036854775807LL
+#define TIME_MIN -9223372036854775807LL
+#endif
+
+/*
+ * Returns: time difference in number of milliseconds. For too large diffs it
+ * returns max value.
+ *
+ * @unittest: 1323
+ */
+timediff_t Curl_timediff(struct curltime newer, struct curltime older)
+{
+  timediff_t diff = newer.tv_sec-older.tv_sec;
+  if(diff >= (TIME_MAX/1000))
+    return TIME_MAX;
+  else if(diff <= (TIME_MIN/1000))
+    return TIME_MIN;
+  return diff * 1000 + (newer.tv_usec-older.tv_usec)/1000;
+}
+
+/*
+ * Returns: time difference in number of microseconds. For too large diffs it
+ * returns max value.
+ */
+timediff_t Curl_timediff_us(struct curltime newer, struct curltime older)
+{
+  timediff_t diff = newer.tv_sec-older.tv_sec;
+  if(diff >= (TIME_MAX/1000000))
+    return TIME_MAX;
+  else if(diff <= (TIME_MIN/1000000))
+    return TIME_MIN;
+  return diff * 1000000 + newer.tv_usec-older.tv_usec;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/timeval.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/timeval.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/timeval.h	(revision 331)
@@ -0,0 +1,56 @@
+#ifndef HEADER_CURL_TIMEVAL_H
+#define HEADER_CURL_TIMEVAL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if SIZEOF_TIME_T < 8
+typedef int timediff_t;
+#else
+typedef curl_off_t timediff_t;
+#endif
+
+struct curltime {
+  time_t tv_sec; /* seconds */
+  int tv_usec;   /* microseconds */
+};
+
+struct curltime Curl_now(void);
+
+/*
+ * Make sure that the first argument (t1) is the more recent time and t2 is
+ * the older time, as otherwise you get a weird negative time-diff back...
+ *
+ * Returns: the time difference in number of milliseconds.
+ */
+timediff_t Curl_timediff(struct curltime t1, struct curltime t2);
+
+/*
+ * Make sure that the first argument (t1) is the more recent time and t2 is
+ * the older time, as otherwise you get a weird negative time-diff back...
+ *
+ * Returns: the time difference in number of microseconds.
+ */
+timediff_t Curl_timediff_us(struct curltime newer, struct curltime older);
+
+#endif /* HEADER_CURL_TIMEVAL_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/transfer.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/transfer.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/transfer.c	(revision 331)
@@ -0,0 +1,2046 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+#include "strtoofft.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#ifndef HAVE_SOCKET
+#error "We can't compile without socket() support!"
+#endif
+
+#include "urldata.h"
+#include <curl/curl.h>
+#include "netrc.h"
+
+#include "content_encoding.h"
+#include "hostip.h"
+#include "transfer.h"
+#include "sendf.h"
+#include "speedcheck.h"
+#include "progress.h"
+#include "http.h"
+#include "url.h"
+#include "getinfo.h"
+#include "vtls/vtls.h"
+#include "select.h"
+#include "multiif.h"
+#include "connect.h"
+#include "non-ascii.h"
+#include "http2.h"
+#include "mime.h"
+#include "strcase.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_SMTP) || \
+    !defined(CURL_DISABLE_IMAP)
+/*
+ * checkheaders() checks the linked list of custom headers for a
+ * particular header (prefix).
+ *
+ * Returns a pointer to the first matching header or NULL if none matched.
+ */
+char *Curl_checkheaders(const struct connectdata *conn,
+                        const char *thisheader)
+{
+  struct curl_slist *head;
+  size_t thislen = strlen(thisheader);
+  struct Curl_easy *data = conn->data;
+
+  for(head = data->set.headers; head; head = head->next) {
+    if(strncasecompare(head->data, thisheader, thislen))
+      return head->data;
+  }
+
+  return NULL;
+}
+#endif
+
+/*
+ * This function will call the read callback to fill our buffer with data
+ * to upload.
+ */
+CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp)
+{
+  struct Curl_easy *data = conn->data;
+  size_t buffersize = (size_t)bytes;
+  int nread;
+#ifdef CURL_DOES_CONVERSIONS
+  bool sending_http_headers = FALSE;
+
+  if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
+    const struct HTTP *http = data->req.protop;
+
+    if(http->sending == HTTPSEND_REQUEST)
+      /* We're sending the HTTP request headers, not the data.
+         Remember that so we don't re-translate them into garbage. */
+      sending_http_headers = TRUE;
+  }
+#endif
+
+  if(data->req.upload_chunky) {
+    /* if chunked Transfer-Encoding */
+    buffersize -= (8 + 2 + 2);   /* 32bit hex + CRLF + CRLF */
+    data->req.upload_fromhere += (8 + 2); /* 32bit hex + CRLF */
+  }
+
+  /* this function returns a size_t, so we typecast to int to prevent warnings
+     with picky compilers */
+  nread = (int)data->state.fread_func(data->req.upload_fromhere, 1,
+                                      buffersize, data->state.in);
+
+  if(nread == CURL_READFUNC_ABORT) {
+    failf(data, "operation aborted by callback");
+    *nreadp = 0;
+    return CURLE_ABORTED_BY_CALLBACK;
+  }
+  if(nread == CURL_READFUNC_PAUSE) {
+    struct SingleRequest *k = &data->req;
+
+    if(conn->handler->flags & PROTOPT_NONETWORK) {
+      /* protocols that work without network cannot be paused. This is
+         actually only FILE:// just now, and it can't pause since the transfer
+         isn't done using the "normal" procedure. */
+      failf(data, "Read callback asked for PAUSE when not supported!");
+      return CURLE_READ_ERROR;
+    }
+
+    /* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */
+    k->keepon |= KEEP_SEND_PAUSE; /* mark socket send as paused */
+    if(data->req.upload_chunky) {
+        /* Back out the preallocation done above */
+      data->req.upload_fromhere -= (8 + 2);
+    }
+    *nreadp = 0;
+
+    return CURLE_OK; /* nothing was read */
+  }
+  else if((size_t)nread > buffersize) {
+    /* the read function returned a too large value */
+    *nreadp = 0;
+    failf(data, "read function returned funny value");
+    return CURLE_READ_ERROR;
+  }
+
+  if(!data->req.forbidchunk && data->req.upload_chunky) {
+    /* if chunked Transfer-Encoding
+     *    build chunk:
+     *
+     *        <HEX SIZE> CRLF
+     *        <DATA> CRLF
+     */
+    /* On non-ASCII platforms the <DATA> may or may not be
+       translated based on set.prefer_ascii while the protocol
+       portion must always be translated to the network encoding.
+       To further complicate matters, line end conversion might be
+       done later on, so we need to prevent CRLFs from becoming
+       CRCRLFs if that's the case.  To do this we use bare LFs
+       here, knowing they'll become CRLFs later on.
+     */
+
+    char hexbuffer[11];
+    const char *endofline_native;
+    const char *endofline_network;
+    int hexlen;
+
+    if(
+#ifdef CURL_DO_LINEEND_CONV
+       (data->set.prefer_ascii) ||
+#endif
+       (data->set.crlf)) {
+      /* \n will become \r\n later on */
+      endofline_native  = "\n";
+      endofline_network = "\x0a";
+    }
+    else {
+      endofline_native  = "\r\n";
+      endofline_network = "\x0d\x0a";
+    }
+    hexlen = snprintf(hexbuffer, sizeof(hexbuffer),
+                      "%x%s", nread, endofline_native);
+
+    /* move buffer pointer */
+    data->req.upload_fromhere -= hexlen;
+    nread += hexlen;
+
+    /* copy the prefix to the buffer, leaving out the NUL */
+    memcpy(data->req.upload_fromhere, hexbuffer, hexlen);
+
+    /* always append ASCII CRLF to the data */
+    memcpy(data->req.upload_fromhere + nread,
+           endofline_network,
+           strlen(endofline_network));
+
+#ifdef CURL_DOES_CONVERSIONS
+    {
+      CURLcode result;
+      int length;
+      if(data->set.prefer_ascii)
+        /* translate the protocol and data */
+        length = nread;
+      else
+        /* just translate the protocol portion */
+        length = (int)strlen(hexbuffer);
+      result = Curl_convert_to_network(data, data->req.upload_fromhere,
+                                       length);
+      /* Curl_convert_to_network calls failf if unsuccessful */
+      if(result)
+        return result;
+    }
+#endif /* CURL_DOES_CONVERSIONS */
+
+    if((nread - hexlen) == 0) {
+      /* mark this as done once this chunk is transferred */
+      data->req.upload_done = TRUE;
+      infof(data, "Signaling end of chunked upload via terminating chunk.\n");
+    }
+
+    nread += (int)strlen(endofline_native); /* for the added end of line */
+  }
+#ifdef CURL_DOES_CONVERSIONS
+  else if((data->set.prefer_ascii) && (!sending_http_headers)) {
+    CURLcode result;
+    result = Curl_convert_to_network(data, data->req.upload_fromhere, nread);
+    /* Curl_convert_to_network calls failf if unsuccessful */
+    if(result)
+      return result;
+  }
+#endif /* CURL_DOES_CONVERSIONS */
+
+  *nreadp = nread;
+
+  return CURLE_OK;
+}
+
+
+/*
+ * Curl_readrewind() rewinds the read stream. This is typically used for HTTP
+ * POST/PUT with multi-pass authentication when a sending was denied and a
+ * resend is necessary.
+ */
+CURLcode Curl_readrewind(struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  curl_mimepart *mimepart = &data->set.mimepost;
+
+  conn->bits.rewindaftersend = FALSE; /* we rewind now */
+
+  /* explicitly switch off sending data on this connection now since we are
+     about to restart a new transfer and thus we want to avoid inadvertently
+     sending more data on the existing connection until the next transfer
+     starts */
+  data->req.keepon &= ~KEEP_SEND;
+
+  /* We have sent away data. If not using CURLOPT_POSTFIELDS or
+     CURLOPT_HTTPPOST, call app to rewind
+  */
+  if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
+    struct HTTP *http = data->req.protop;
+
+    if(http->sendit)
+      mimepart = http->sendit;
+  }
+  if(data->set.postfields)
+    ; /* do nothing */
+  else if(data->set.httpreq == HTTPREQ_POST_MIME ||
+          data->set.httpreq == HTTPREQ_POST_FORM) {
+    if(Curl_mime_rewind(mimepart)) {
+      failf(data, "Cannot rewind mime/post data");
+      return CURLE_SEND_FAIL_REWIND;
+    }
+  }
+  else {
+    if(data->set.seek_func) {
+      int err;
+
+      err = (data->set.seek_func)(data->set.seek_client, 0, SEEK_SET);
+      if(err) {
+        failf(data, "seek callback returned error %d", (int)err);
+        return CURLE_SEND_FAIL_REWIND;
+      }
+    }
+    else if(data->set.ioctl_func) {
+      curlioerr err;
+
+      err = (data->set.ioctl_func)(data, CURLIOCMD_RESTARTREAD,
+                                   data->set.ioctl_client);
+      infof(data, "the ioctl callback returned %d\n", (int)err);
+
+      if(err) {
+        /* FIXME: convert to a human readable error message */
+        failf(data, "ioctl callback returned error %d", (int)err);
+        return CURLE_SEND_FAIL_REWIND;
+      }
+    }
+    else {
+      /* If no CURLOPT_READFUNCTION is used, we know that we operate on a
+         given FILE * stream and we can actually attempt to rewind that
+         ourselves with fseek() */
+      if(data->state.fread_func == (curl_read_callback)fread) {
+        if(-1 != fseek(data->state.in, 0, SEEK_SET))
+          /* successful rewind */
+          return CURLE_OK;
+      }
+
+      /* no callback set or failure above, makes us fail at once */
+      failf(data, "necessary data rewind wasn't possible");
+      return CURLE_SEND_FAIL_REWIND;
+    }
+  }
+  return CURLE_OK;
+}
+
+static int data_pending(const struct connectdata *conn)
+{
+  /* in the case of libssh2, we can never be really sure that we have emptied
+     its internal buffers so we MUST always try until we get EAGAIN back */
+  return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) ||
+#if defined(USE_NGHTTP2)
+    Curl_ssl_data_pending(conn, FIRSTSOCKET) ||
+    /* For HTTP/2, we may read up everything including responde body
+       with header fields in Curl_http_readwrite_headers. If no
+       content-length is provided, curl waits for the connection
+       close, which we emulate it using conn->proto.httpc.closed =
+       TRUE. The thing is if we read everything, then http2_recv won't
+       be called and we cannot signal the HTTP/2 stream has closed. As
+       a workaround, we return nonzero here to call http2_recv. */
+    ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion == 20);
+#else
+    Curl_ssl_data_pending(conn, FIRSTSOCKET);
+#endif
+}
+
+static void read_rewind(struct connectdata *conn,
+                        size_t thismuch)
+{
+  DEBUGASSERT(conn->read_pos >= thismuch);
+
+  conn->read_pos -= thismuch;
+  conn->bits.stream_was_rewound = TRUE;
+
+#ifdef DEBUGBUILD
+  {
+    char buf[512 + 1];
+    size_t show;
+
+    show = CURLMIN(conn->buf_len - conn->read_pos, sizeof(buf)-1);
+    if(conn->master_buffer) {
+      memcpy(buf, conn->master_buffer + conn->read_pos, show);
+      buf[show] = '\0';
+    }
+    else {
+      buf[0] = '\0';
+    }
+
+    DEBUGF(infof(conn->data,
+                 "Buffer after stream rewind (read_pos = %zu): [%s]\n",
+                 conn->read_pos, buf));
+  }
+#endif
+}
+
+/*
+ * Check to see if CURLOPT_TIMECONDITION was met by comparing the time of the
+ * remote document with the time provided by CURLOPT_TIMEVAL
+ */
+bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc)
+{
+  if((timeofdoc == 0) || (data->set.timevalue == 0))
+    return TRUE;
+
+  switch(data->set.timecondition) {
+  case CURL_TIMECOND_IFMODSINCE:
+  default:
+    if(timeofdoc <= data->set.timevalue) {
+      infof(data,
+            "The requested document is not new enough\n");
+      data->info.timecond = TRUE;
+      return FALSE;
+    }
+    break;
+  case CURL_TIMECOND_IFUNMODSINCE:
+    if(timeofdoc >= data->set.timevalue) {
+      infof(data,
+            "The requested document is not old enough\n");
+      data->info.timecond = TRUE;
+      return FALSE;
+    }
+    break;
+  }
+
+  return TRUE;
+}
+
+/*
+ * Go ahead and do a read if we have a readable socket or if
+ * the stream was rewound (in which case we have data in a
+ * buffer)
+ *
+ * return '*comeback' TRUE if we didn't properly drain the socket so this
+ * function should get called again without select() or similar in between!
+ */
+static CURLcode readwrite_data(struct Curl_easy *data,
+                               struct connectdata *conn,
+                               struct SingleRequest *k,
+                               int *didwhat, bool *done,
+                               bool *comeback)
+{
+  CURLcode result = CURLE_OK;
+  ssize_t nread; /* number of bytes read */
+  size_t excess = 0; /* excess bytes read */
+  bool is_empty_data = FALSE;
+  bool readmore = FALSE; /* used by RTP to signal for more data */
+  int maxloops = 100;
+
+  *done = FALSE;
+  *comeback = FALSE;
+
+  /* This is where we loop until we have read everything there is to
+     read or we get a CURLE_AGAIN */
+  do {
+    size_t buffersize = data->set.buffer_size;
+    size_t bytestoread = buffersize;
+
+    if(
+#if defined(USE_NGHTTP2)
+       /* For HTTP/2, read data without caring about the content
+          length. This is safe because body in HTTP/2 is always
+          segmented thanks to its framing layer. Meanwhile, we have to
+          call Curl_read to ensure that http2_handle_stream_close is
+          called when we read all incoming bytes for a particular
+          stream. */
+       !((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
+         conn->httpversion == 20) &&
+#endif
+       k->size != -1 && !k->header) {
+      /* make sure we don't read "too much" if we can help it since we
+         might be pipelining and then someone else might want to read what
+         follows! */
+      curl_off_t totalleft = k->size - k->bytecount;
+      if(totalleft < (curl_off_t)bytestoread)
+        bytestoread = (size_t)totalleft;
+    }
+
+    if(bytestoread) {
+      /* receive data from the network! */
+      result = Curl_read(conn, conn->sockfd, k->buf, bytestoread, &nread);
+
+      /* read would've blocked */
+      if(CURLE_AGAIN == result)
+        break; /* get out of loop */
+
+      if(result>0)
+        return result;
+    }
+    else {
+      /* read nothing but since we wanted nothing we consider this an OK
+         situation to proceed from */
+      DEBUGF(infof(data, "readwrite_data: we're done!\n"));
+      nread = 0;
+    }
+
+    if((k->bytecount == 0) && (k->writebytecount == 0)) {
+      Curl_pgrsTime(data, TIMER_STARTTRANSFER);
+      if(k->exp100 > EXP100_SEND_DATA)
+        /* set time stamp to compare with when waiting for the 100 */
+        k->start100 = Curl_now();
+    }
+
+    *didwhat |= KEEP_RECV;
+    /* indicates data of zero size, i.e. empty file */
+    is_empty_data = ((nread == 0) && (k->bodywrites == 0)) ? TRUE : FALSE;
+
+    /* NUL terminate, allowing string ops to be used */
+    if(0 < nread || is_empty_data) {
+      k->buf[nread] = 0;
+    }
+    else if(0 >= nread) {
+      /* if we receive 0 or less here, the server closed the connection
+         and we bail out from this! */
+      DEBUGF(infof(data, "nread <= 0, server closed connection, bailing\n"));
+      k->keepon &= ~KEEP_RECV;
+      break;
+    }
+
+    /* Default buffer to use when we write the buffer, it may be changed
+       in the flow below before the actual storing is done. */
+    k->str = k->buf;
+
+    if(conn->handler->readwrite) {
+      result = conn->handler->readwrite(data, conn, &nread, &readmore);
+      if(result)
+        return result;
+      if(readmore)
+        break;
+    }
+
+#ifndef CURL_DISABLE_HTTP
+    /* Since this is a two-state thing, we check if we are parsing
+       headers at the moment or not. */
+    if(k->header) {
+      /* we are in parse-the-header-mode */
+      bool stop_reading = FALSE;
+      result = Curl_http_readwrite_headers(data, conn, &nread, &stop_reading);
+      if(result)
+        return result;
+
+      if(conn->handler->readwrite &&
+         (k->maxdownload <= 0 && nread > 0)) {
+        result = conn->handler->readwrite(data, conn, &nread, &readmore);
+        if(result)
+          return result;
+        if(readmore)
+          break;
+      }
+
+      if(stop_reading) {
+        /* We've stopped dealing with input, get out of the do-while loop */
+
+        if(nread > 0) {
+          if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
+            infof(data,
+                  "Rewinding stream by : %zd"
+                  " bytes on url %s (zero-length body)\n",
+                  nread, data->state.path);
+            read_rewind(conn, (size_t)nread);
+          }
+          else {
+            infof(data,
+                  "Excess found in a non pipelined read:"
+                  " excess = %zd"
+                  " url = %s (zero-length body)\n",
+                  nread, data->state.path);
+          }
+        }
+
+        break;
+      }
+    }
+#endif /* CURL_DISABLE_HTTP */
+
+
+    /* This is not an 'else if' since it may be a rest from the header
+       parsing, where the beginning of the buffer is headers and the end
+       is non-headers. */
+    if(k->str && !k->header && (nread > 0 || is_empty_data)) {
+
+      if(data->set.opt_no_body) {
+        /* data arrives although we want none, bail out */
+        streamclose(conn, "ignoring body");
+        *done = TRUE;
+        return CURLE_WEIRD_SERVER_REPLY;
+      }
+
+#ifndef CURL_DISABLE_HTTP
+      if(0 == k->bodywrites && !is_empty_data) {
+        /* These checks are only made the first time we are about to
+           write a piece of the body */
+        if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
+          /* HTTP-only checks */
+
+          if(data->req.newurl) {
+            if(conn->bits.close) {
+              /* Abort after the headers if "follow Location" is set
+                 and we're set to close anyway. */
+              k->keepon &= ~KEEP_RECV;
+              *done = TRUE;
+              return CURLE_OK;
+            }
+            /* We have a new url to load, but since we want to be able
+               to re-use this connection properly, we read the full
+               response in "ignore more" */
+            k->ignorebody = TRUE;
+            infof(data, "Ignoring the response-body\n");
+          }
+          if(data->state.resume_from && !k->content_range &&
+             (data->set.httpreq == HTTPREQ_GET) &&
+             !k->ignorebody) {
+
+            if(k->size == data->state.resume_from) {
+              /* The resume point is at the end of file, consider this fine
+                 even if it doesn't allow resume from here. */
+              infof(data, "The entire document is already downloaded");
+              connclose(conn, "already downloaded");
+              /* Abort download */
+              k->keepon &= ~KEEP_RECV;
+              *done = TRUE;
+              return CURLE_OK;
+            }
+
+            /* we wanted to resume a download, although the server doesn't
+             * seem to support this and we did this with a GET (if it
+             * wasn't a GET we did a POST or PUT resume) */
+            failf(data, "HTTP server doesn't seem to support "
+                  "byte ranges. Cannot resume.");
+            return CURLE_RANGE_ERROR;
+          }
+
+          if(data->set.timecondition && !data->state.range) {
+            /* A time condition has been set AND no ranges have been
+               requested. This seems to be what chapter 13.3.4 of
+               RFC 2616 defines to be the correct action for a
+               HTTP/1.1 client */
+
+            if(!Curl_meets_timecondition(data, k->timeofdoc)) {
+              *done = TRUE;
+              /* We're simulating a http 304 from server so we return
+                 what should have been returned from the server */
+              data->info.httpcode = 304;
+              infof(data, "Simulate a HTTP 304 response!\n");
+              /* we abort the transfer before it is completed == we ruin the
+                 re-use ability. Close the connection */
+              connclose(conn, "Simulated 304 handling");
+              return CURLE_OK;
+            }
+          } /* we have a time condition */
+
+        } /* this is HTTP or RTSP */
+      } /* this is the first time we write a body part */
+#endif /* CURL_DISABLE_HTTP */
+
+      k->bodywrites++;
+
+      /* pass data to the debug function before it gets "dechunked" */
+      if(data->set.verbose) {
+        if(k->badheader) {
+          Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff,
+                     (size_t)k->hbuflen, conn);
+          if(k->badheader == HEADER_PARTHEADER)
+            Curl_debug(data, CURLINFO_DATA_IN,
+                       k->str, (size_t)nread, conn);
+        }
+        else
+          Curl_debug(data, CURLINFO_DATA_IN,
+                     k->str, (size_t)nread, conn);
+      }
+
+#ifndef CURL_DISABLE_HTTP
+      if(k->chunk) {
+        /*
+         * Here comes a chunked transfer flying and we need to decode this
+         * properly.  While the name says read, this function both reads
+         * and writes away the data. The returned 'nread' holds the number
+         * of actual data it wrote to the client.
+         */
+
+        CHUNKcode res =
+          Curl_httpchunk_read(conn, k->str, nread, &nread);
+
+        if(CHUNKE_OK < res) {
+          if(CHUNKE_WRITE_ERROR == res) {
+            failf(data, "Failed writing data");
+            return CURLE_WRITE_ERROR;
+          }
+          failf(data, "%s in chunked-encoding", Curl_chunked_strerror(res));
+          return CURLE_RECV_ERROR;
+        }
+        if(CHUNKE_STOP == res) {
+          size_t dataleft;
+          /* we're done reading chunks! */
+          k->keepon &= ~KEEP_RECV; /* read no more */
+
+          /* There are now possibly N number of bytes at the end of the
+             str buffer that weren't written to the client.
+
+             We DO care about this data if we are pipelining.
+             Push it back to be read on the next pass. */
+
+          dataleft = conn->chunk.dataleft;
+          if(dataleft != 0) {
+            infof(conn->data, "Leftovers after chunking: %zu bytes\n",
+                  dataleft);
+            if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
+              /* only attempt the rewind if we truly are pipelining */
+              infof(conn->data, "Rewinding %zu bytes\n",dataleft);
+              read_rewind(conn, dataleft);
+            }
+          }
+        }
+        /* If it returned OK, we just keep going */
+      }
+#endif   /* CURL_DISABLE_HTTP */
+
+      /* Account for body content stored in the header buffer */
+      if(k->badheader && !k->ignorebody) {
+        DEBUGF(infof(data, "Increasing bytecount by %zu from hbuflen\n",
+                     k->hbuflen));
+        k->bytecount += k->hbuflen;
+      }
+
+      if((-1 != k->maxdownload) &&
+         (k->bytecount + nread >= k->maxdownload)) {
+
+        excess = (size_t)(k->bytecount + nread - k->maxdownload);
+        if(excess > 0 && !k->ignorebody) {
+          if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) {
+            infof(data,
+                  "Rewinding stream by : %zu"
+                  " bytes on url %s (size = %" CURL_FORMAT_CURL_OFF_T
+                  ", maxdownload = %" CURL_FORMAT_CURL_OFF_T
+                  ", bytecount = %" CURL_FORMAT_CURL_OFF_T ", nread = %zd)\n",
+                  excess, data->state.path,
+                  k->size, k->maxdownload, k->bytecount, nread);
+            read_rewind(conn, excess);
+          }
+          else {
+            infof(data,
+                  "Excess found in a non pipelined read:"
+                  " excess = %zu"
+                  ", size = %" CURL_FORMAT_CURL_OFF_T
+                  ", maxdownload = %" CURL_FORMAT_CURL_OFF_T
+                  ", bytecount = %" CURL_FORMAT_CURL_OFF_T "\n",
+                  excess, k->size, k->maxdownload, k->bytecount);
+          }
+        }
+
+        nread = (ssize_t) (k->maxdownload - k->bytecount);
+        if(nread < 0) /* this should be unusual */
+          nread = 0;
+
+        k->keepon &= ~KEEP_RECV; /* we're done reading */
+      }
+
+      k->bytecount += nread;
+
+      Curl_pgrsSetDownloadCounter(data, k->bytecount);
+
+      if(!k->chunk && (nread || k->badheader || is_empty_data)) {
+        /* If this is chunky transfer, it was already written */
+
+        if(k->badheader && !k->ignorebody) {
+          /* we parsed a piece of data wrongly assuming it was a header
+             and now we output it as body instead */
+
+          /* Don't let excess data pollute body writes */
+          if(k->maxdownload == -1 || (curl_off_t)k->hbuflen <= k->maxdownload)
+            result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                       data->state.headerbuff,
+                                       k->hbuflen);
+          else
+            result = Curl_client_write(conn, CLIENTWRITE_BODY,
+                                       data->state.headerbuff,
+                                       (size_t)k->maxdownload);
+
+          if(result)
+            return result;
+        }
+        if(k->badheader < HEADER_ALLBAD) {
+          /* This switch handles various content encodings. If there's an
+             error here, be sure to check over the almost identical code
+             in http_chunks.c.
+             Make sure that ALL_CONTENT_ENCODINGS contains all the
+             encodings handled here. */
+          if(conn->data->set.http_ce_skip || !k->writer_stack) {
+            if(!k->ignorebody) {
+#ifndef CURL_DISABLE_POP3
+              if(conn->handler->protocol & PROTO_FAMILY_POP3)
+                result = Curl_pop3_write(conn, k->str, nread);
+              else
+#endif /* CURL_DISABLE_POP3 */
+                result = Curl_client_write(conn, CLIENTWRITE_BODY, k->str,
+                                           nread);
+            }
+          }
+          else
+            result = Curl_unencode_write(conn, k->writer_stack, k->str, nread);
+        }
+        k->badheader = HEADER_NORMAL; /* taken care of now */
+
+        if(result)
+          return result;
+      }
+
+    } /* if(!header and data to read) */
+
+    if(conn->handler->readwrite &&
+       (excess > 0 && !conn->bits.stream_was_rewound)) {
+      /* Parse the excess data */
+      k->str += nread;
+      nread = (ssize_t)excess;
+
+      result = conn->handler->readwrite(data, conn, &nread, &readmore);
+      if(result)
+        return result;
+
+      if(readmore)
+        k->keepon |= KEEP_RECV; /* we're not done reading */
+      break;
+    }
+
+    if(is_empty_data) {
+      /* if we received nothing, the server closed the connection and we
+         are done */
+      k->keepon &= ~KEEP_RECV;
+    }
+
+  } while(data_pending(conn) && maxloops--);
+
+  if(maxloops <= 0) {
+    /* we mark it as read-again-please */
+    conn->cselect_bits = CURL_CSELECT_IN;
+    *comeback = TRUE;
+  }
+
+  if(((k->keepon & (KEEP_RECV|KEEP_SEND)) == KEEP_SEND) &&
+     conn->bits.close) {
+    /* When we've read the entire thing and the close bit is set, the server
+       may now close the connection. If there's now any kind of sending going
+       on from our side, we need to stop that immediately. */
+    infof(data, "we are done reading and this is set to close, stop send\n");
+    k->keepon &= ~KEEP_SEND; /* no writing anymore either */
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode done_sending(struct connectdata *conn,
+                             struct SingleRequest *k)
+{
+  k->keepon &= ~KEEP_SEND; /* we're done writing */
+
+  Curl_http2_done_sending(conn);
+
+  if(conn->bits.rewindaftersend) {
+    CURLcode result = Curl_readrewind(conn);
+    if(result)
+      return result;
+  }
+  return CURLE_OK;
+}
+
+
+/*
+ * Send data to upload to the server, when the socket is writable.
+ */
+static CURLcode readwrite_upload(struct Curl_easy *data,
+                                 struct connectdata *conn,
+                                 int *didwhat)
+{
+  ssize_t i, si;
+  ssize_t bytes_written;
+  CURLcode result;
+  ssize_t nread; /* number of bytes read */
+  bool sending_http_headers = FALSE;
+  struct SingleRequest *k = &data->req;
+
+  if((k->bytecount == 0) && (k->writebytecount == 0))
+    Curl_pgrsTime(data, TIMER_STARTTRANSFER);
+
+  *didwhat |= KEEP_SEND;
+
+  do {
+
+    /* only read more data if there's no upload data already
+       present in the upload buffer */
+    if(0 == k->upload_present) {
+      /* init the "upload from here" pointer */
+      k->upload_fromhere = data->state.uploadbuffer;
+
+      if(!k->upload_done) {
+        /* HTTP pollution, this should be written nicer to become more
+           protocol agnostic. */
+        int fillcount;
+        struct HTTP *http = k->protop;
+
+        if((k->exp100 == EXP100_SENDING_REQUEST) &&
+           (http->sending == HTTPSEND_BODY)) {
+          /* If this call is to send body data, we must take some action:
+             We have sent off the full HTTP 1.1 request, and we shall now
+             go into the Expect: 100 state and await such a header */
+          k->exp100 = EXP100_AWAITING_CONTINUE; /* wait for the header */
+          k->keepon &= ~KEEP_SEND;         /* disable writing */
+          k->start100 = Curl_now();       /* timeout count starts now */
+          *didwhat &= ~KEEP_SEND;  /* we didn't write anything actually */
+
+          /* set a timeout for the multi interface */
+          Curl_expire(data, data->set.expect_100_timeout, EXPIRE_100_TIMEOUT);
+          break;
+        }
+
+        if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) {
+          if(http->sending == HTTPSEND_REQUEST)
+            /* We're sending the HTTP request headers, not the data.
+               Remember that so we don't change the line endings. */
+            sending_http_headers = TRUE;
+          else
+            sending_http_headers = FALSE;
+        }
+
+        result = Curl_fillreadbuffer(conn, UPLOAD_BUFSIZE, &fillcount);
+        if(result)
+          return result;
+
+        nread = (ssize_t)fillcount;
+      }
+      else
+        nread = 0; /* we're done uploading/reading */
+
+      if(!nread && (k->keepon & KEEP_SEND_PAUSE)) {
+        /* this is a paused transfer */
+        break;
+      }
+      if(nread <= 0) {
+        result = done_sending(conn, k);
+        if(result)
+          return result;
+        break;
+      }
+
+      /* store number of bytes available for upload */
+      k->upload_present = nread;
+
+      /* convert LF to CRLF if so asked */
+      if((!sending_http_headers) && (
+#ifdef CURL_DO_LINEEND_CONV
+         /* always convert if we're FTPing in ASCII mode */
+         (data->set.prefer_ascii) ||
+#endif
+         (data->set.crlf))) {
+        /* Do we need to allocate a scratch buffer? */
+        if(!data->state.scratch) {
+          data->state.scratch = malloc(2 * data->set.buffer_size);
+          if(!data->state.scratch) {
+            failf(data, "Failed to alloc scratch buffer!");
+
+            return CURLE_OUT_OF_MEMORY;
+          }
+        }
+
+        /*
+         * ASCII/EBCDIC Note: This is presumably a text (not binary)
+         * transfer so the data should already be in ASCII.
+         * That means the hex values for ASCII CR (0x0d) & LF (0x0a)
+         * must be used instead of the escape sequences \r & \n.
+         */
+        for(i = 0, si = 0; i < nread; i++, si++) {
+          if(k->upload_fromhere[i] == 0x0a) {
+            data->state.scratch[si++] = 0x0d;
+            data->state.scratch[si] = 0x0a;
+            if(!data->set.crlf) {
+              /* we're here only because FTP is in ASCII mode...
+                 bump infilesize for the LF we just added */
+              if(data->state.infilesize != -1)
+                data->state.infilesize++;
+            }
+          }
+          else
+            data->state.scratch[si] = k->upload_fromhere[i];
+        }
+
+        if(si != nread) {
+          /* only perform the special operation if we really did replace
+             anything */
+          nread = si;
+
+          /* upload from the new (replaced) buffer instead */
+          k->upload_fromhere = data->state.scratch;
+
+          /* set the new amount too */
+          k->upload_present = nread;
+        }
+      }
+
+#ifndef CURL_DISABLE_SMTP
+      if(conn->handler->protocol & PROTO_FAMILY_SMTP) {
+        result = Curl_smtp_escape_eob(conn, nread);
+        if(result)
+          return result;
+      }
+#endif /* CURL_DISABLE_SMTP */
+    } /* if 0 == k->upload_present */
+    else {
+      /* We have a partial buffer left from a previous "round". Use
+         that instead of reading more data */
+    }
+
+    /* write to socket (send away data) */
+    result = Curl_write(conn,
+                        conn->writesockfd,  /* socket to send to */
+                        k->upload_fromhere, /* buffer pointer */
+                        k->upload_present,  /* buffer size */
+                        &bytes_written);    /* actually sent */
+
+    if(result)
+      return result;
+
+    if(data->set.verbose)
+      /* show the data before we change the pointer upload_fromhere */
+      Curl_debug(data, CURLINFO_DATA_OUT, k->upload_fromhere,
+                 (size_t)bytes_written, conn);
+
+    k->writebytecount += bytes_written;
+
+    if((!k->upload_chunky || k->forbidchunk) &&
+       (k->writebytecount == data->state.infilesize)) {
+      /* we have sent all data we were supposed to */
+      k->upload_done = TRUE;
+      infof(data, "We are completely uploaded and fine\n");
+    }
+
+    if(k->upload_present != bytes_written) {
+      /* we only wrote a part of the buffer (if anything), deal with it! */
+
+      /* store the amount of bytes left in the buffer to write */
+      k->upload_present -= bytes_written;
+
+      /* advance the pointer where to find the buffer when the next send
+         is to happen */
+      k->upload_fromhere += bytes_written;
+    }
+    else {
+      /* we've uploaded that buffer now */
+      k->upload_fromhere = data->state.uploadbuffer;
+      k->upload_present = 0; /* no more bytes left */
+
+      if(k->upload_done) {
+        result = done_sending(conn, k);
+        if(result)
+          return result;
+      }
+    }
+
+    Curl_pgrsSetUploadCounter(data, k->writebytecount);
+
+  } WHILE_FALSE; /* just to break out from! */
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_readwrite() is the low-level function to be called when data is to
+ * be read and written to/from the connection.
+ *
+ * return '*comeback' TRUE if we didn't properly drain the socket so this
+ * function should get called again without select() or similar in between!
+ */
+CURLcode Curl_readwrite(struct connectdata *conn,
+                        struct Curl_easy *data,
+                        bool *done,
+                        bool *comeback)
+{
+  struct SingleRequest *k = &data->req;
+  CURLcode result;
+  int didwhat = 0;
+
+  curl_socket_t fd_read;
+  curl_socket_t fd_write;
+  int select_res = conn->cselect_bits;
+
+  conn->cselect_bits = 0;
+
+  /* only use the proper socket if the *_HOLD bit is not set simultaneously as
+     then we are in rate limiting state in that transfer direction */
+
+  if((k->keepon & KEEP_RECVBITS) == KEEP_RECV)
+    fd_read = conn->sockfd;
+  else
+    fd_read = CURL_SOCKET_BAD;
+
+  if((k->keepon & KEEP_SENDBITS) == KEEP_SEND)
+    fd_write = conn->writesockfd;
+  else
+    fd_write = CURL_SOCKET_BAD;
+
+  if(conn->data->state.drain) {
+    select_res |= CURL_CSELECT_IN;
+    DEBUGF(infof(data, "Curl_readwrite: forcibly told to drain data\n"));
+  }
+
+  if(!select_res) /* Call for select()/poll() only, if read/write/error
+                     status is not known. */
+    select_res = Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write, 0);
+
+  if(select_res == CURL_CSELECT_ERR) {
+    failf(data, "select/poll returned error");
+    return CURLE_SEND_ERROR;
+  }
+
+  /* We go ahead and do a read if we have a readable socket or if
+     the stream was rewound (in which case we have data in a
+     buffer) */
+  if((k->keepon & KEEP_RECV) &&
+     ((select_res & CURL_CSELECT_IN) || conn->bits.stream_was_rewound)) {
+
+    result = readwrite_data(data, conn, k, &didwhat, done, comeback);
+    if(result || *done)
+      return result;
+  }
+
+  /* If we still have writing to do, we check if we have a writable socket. */
+  if((k->keepon & KEEP_SEND) && (select_res & CURL_CSELECT_OUT)) {
+    /* write */
+
+    result = readwrite_upload(data, conn, &didwhat);
+    if(result)
+      return result;
+  }
+
+  k->now = Curl_now();
+  if(didwhat) {
+    /* Update read/write counters */
+    if(k->bytecountp)
+      *k->bytecountp = k->bytecount; /* read count */
+    if(k->writebytecountp)
+      *k->writebytecountp = k->writebytecount; /* write count */
+  }
+  else {
+    /* no read no write, this is a timeout? */
+    if(k->exp100 == EXP100_AWAITING_CONTINUE) {
+      /* This should allow some time for the header to arrive, but only a
+         very short time as otherwise it'll be too much wasted time too
+         often. */
+
+      /* Quoting RFC2616, section "8.2.3 Use of the 100 (Continue) Status":
+
+         Therefore, when a client sends this header field to an origin server
+         (possibly via a proxy) from which it has never seen a 100 (Continue)
+         status, the client SHOULD NOT wait for an indefinite period before
+         sending the request body.
+
+      */
+
+      timediff_t ms = Curl_timediff(k->now, k->start100);
+      if(ms >= data->set.expect_100_timeout) {
+        /* we've waited long enough, continue anyway */
+        k->exp100 = EXP100_SEND_DATA;
+        k->keepon |= KEEP_SEND;
+        Curl_expire_done(data, EXPIRE_100_TIMEOUT);
+        infof(data, "Done waiting for 100-continue\n");
+      }
+    }
+  }
+
+  if(Curl_pgrsUpdate(conn))
+    result = CURLE_ABORTED_BY_CALLBACK;
+  else
+    result = Curl_speedcheck(data, k->now);
+  if(result)
+    return result;
+
+  if(k->keepon) {
+    if(0 > Curl_timeleft(data, &k->now, FALSE)) {
+      if(k->size != -1) {
+        failf(data, "Operation timed out after %ld milliseconds with %"
+              CURL_FORMAT_CURL_OFF_T " out of %"
+              CURL_FORMAT_CURL_OFF_T " bytes received",
+              Curl_timediff(k->now, data->progress.t_startsingle),
+              k->bytecount, k->size);
+      }
+      else {
+        failf(data, "Operation timed out after %ld milliseconds with %"
+              CURL_FORMAT_CURL_OFF_T " bytes received",
+              Curl_timediff(k->now, data->progress.t_startsingle),
+              k->bytecount);
+      }
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+  }
+  else {
+    /*
+     * The transfer has been performed. Just make some general checks before
+     * returning.
+     */
+
+    if(!(data->set.opt_no_body) && (k->size != -1) &&
+       (k->bytecount != k->size) &&
+#ifdef CURL_DO_LINEEND_CONV
+       /* Most FTP servers don't adjust their file SIZE response for CRLFs,
+          so we'll check to see if the discrepancy can be explained
+          by the number of CRLFs we've changed to LFs.
+       */
+       (k->bytecount != (k->size + data->state.crlf_conversions)) &&
+#endif /* CURL_DO_LINEEND_CONV */
+       !k->newurl) {
+      failf(data, "transfer closed with %" CURL_FORMAT_CURL_OFF_T
+            " bytes remaining to read", k->size - k->bytecount);
+      return CURLE_PARTIAL_FILE;
+    }
+    if(!(data->set.opt_no_body) && k->chunk &&
+       (conn->chunk.state != CHUNK_STOP)) {
+      /*
+       * In chunked mode, return an error if the connection is closed prior to
+       * the empty (terminating) chunk is read.
+       *
+       * The condition above used to check for
+       * conn->proto.http->chunk.datasize != 0 which is true after reading
+       * *any* chunk, not just the empty chunk.
+       *
+       */
+      failf(data, "transfer closed with outstanding read data remaining");
+      return CURLE_PARTIAL_FILE;
+    }
+    if(Curl_pgrsUpdate(conn))
+      return CURLE_ABORTED_BY_CALLBACK;
+  }
+
+  /* Now update the "done" boolean we return */
+  *done = (0 == (k->keepon&(KEEP_RECV|KEEP_SEND|
+                            KEEP_RECV_PAUSE|KEEP_SEND_PAUSE))) ? TRUE : FALSE;
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_single_getsock() gets called by the multi interface code when the app
+ * has requested to get the sockets for the current connection. This function
+ * will then be called once for every connection that the multi interface
+ * keeps track of. This function will only be called for connections that are
+ * in the proper state to have this information available.
+ */
+int Curl_single_getsock(const struct connectdata *conn,
+                        curl_socket_t *sock, /* points to numsocks number
+                                                of sockets */
+                        int numsocks)
+{
+  const struct Curl_easy *data = conn->data;
+  int bitmap = GETSOCK_BLANK;
+  unsigned sockindex = 0;
+
+  if(conn->handler->perform_getsock)
+    return conn->handler->perform_getsock(conn, sock, numsocks);
+
+  if(numsocks < 2)
+    /* simple check but we might need two slots */
+    return GETSOCK_BLANK;
+
+  /* don't include HOLD and PAUSE connections */
+  if((data->req.keepon & KEEP_RECVBITS) == KEEP_RECV) {
+
+    DEBUGASSERT(conn->sockfd != CURL_SOCKET_BAD);
+
+    bitmap |= GETSOCK_READSOCK(sockindex);
+    sock[sockindex] = conn->sockfd;
+  }
+
+  /* don't include HOLD and PAUSE connections */
+  if((data->req.keepon & KEEP_SENDBITS) == KEEP_SEND) {
+
+    if((conn->sockfd != conn->writesockfd) ||
+       bitmap == GETSOCK_BLANK) {
+      /* only if they are not the same socket and we have a readable
+         one, we increase index */
+      if(bitmap != GETSOCK_BLANK)
+        sockindex++; /* increase index if we need two entries */
+
+      DEBUGASSERT(conn->writesockfd != CURL_SOCKET_BAD);
+
+      sock[sockindex] = conn->writesockfd;
+    }
+
+    bitmap |= GETSOCK_WRITESOCK(sockindex);
+  }
+
+  return bitmap;
+}
+
+/* Curl_init_CONNECT() gets called each time the handle switches to CONNECT
+   which means this gets called once for each subsequent redirect etc */
+void Curl_init_CONNECT(struct Curl_easy *data)
+{
+  data->state.fread_func = data->set.fread_func_set;
+  data->state.in = data->set.in_set;
+}
+
+/*
+ * Curl_pretransfer() is called immediately before a transfer starts, and only
+ * once for one transfer no matter if it has redirects or do multi-pass
+ * authentication etc.
+ */
+CURLcode Curl_pretransfer(struct Curl_easy *data)
+{
+  CURLcode result;
+  if(!data->change.url) {
+    /* we can't do anything without URL */
+    failf(data, "No URL set!");
+    return CURLE_URL_MALFORMAT;
+  }
+  /* since the URL may have been redirected in a previous use of this handle */
+  if(data->change.url_alloc) {
+    /* the already set URL is allocated, free it first! */
+    Curl_safefree(data->change.url);
+    data->change.url_alloc = FALSE;
+  }
+  data->change.url = data->set.str[STRING_SET_URL];
+
+  /* Init the SSL session ID cache here. We do it here since we want to do it
+     after the *_setopt() calls (that could specify the size of the cache) but
+     before any transfer takes place. */
+  result = Curl_ssl_initsessions(data, data->set.general_ssl.max_ssl_sessions);
+  if(result)
+    return result;
+
+  data->state.wildcardmatch = data->set.wildcard_enabled;
+  data->set.followlocation = 0; /* reset the location-follow counter */
+  data->state.this_is_a_follow = FALSE; /* reset this */
+  data->state.errorbuf = FALSE; /* no error has occurred */
+  data->state.httpversion = 0; /* don't assume any particular server version */
+
+  data->state.authproblem = FALSE;
+  data->state.authhost.want = data->set.httpauth;
+  data->state.authproxy.want = data->set.proxyauth;
+  Curl_safefree(data->info.wouldredirect);
+  data->info.wouldredirect = NULL;
+
+  if(data->set.httpreq == HTTPREQ_PUT)
+    data->state.infilesize = data->set.filesize;
+  else {
+    data->state.infilesize = data->set.postfieldsize;
+    if(data->set.postfields && (data->state.infilesize == -1))
+      data->state.infilesize = (curl_off_t)strlen(data->set.postfields);
+  }
+
+  /* If there is a list of cookie files to read, do it now! */
+  if(data->change.cookielist)
+    Curl_cookie_loadfiles(data);
+
+  /* If there is a list of host pairs to deal with */
+  if(data->change.resolve)
+    result = Curl_loadhostpairs(data);
+
+  if(!result) {
+    /* Allow data->set.use_port to set which port to use. This needs to be
+     * disabled for example when we follow Location: headers to URLs using
+     * different ports! */
+    data->state.allow_port = TRUE;
+
+#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL)
+    /*************************************************************
+     * Tell signal handler to ignore SIGPIPE
+     *************************************************************/
+    if(!data->set.no_signal)
+      data->state.prev_signal = signal(SIGPIPE, SIG_IGN);
+#endif
+
+    Curl_initinfo(data); /* reset session-specific information "variables" */
+    Curl_pgrsResetTransferSizes(data);
+    Curl_pgrsStartNow(data);
+
+    if(data->set.timeout)
+      Curl_expire(data, data->set.timeout, EXPIRE_TIMEOUT);
+
+    if(data->set.connecttimeout)
+      Curl_expire(data, data->set.connecttimeout, EXPIRE_CONNECTTIMEOUT);
+
+    /* In case the handle is re-used and an authentication method was picked
+       in the session we need to make sure we only use the one(s) we now
+       consider to be fine */
+    data->state.authhost.picked &= data->state.authhost.want;
+    data->state.authproxy.picked &= data->state.authproxy.want;
+
+    if(data->state.wildcardmatch) {
+      struct WildcardData *wc = &data->wildcard;
+      if(wc->state < CURLWC_INIT) {
+        result = Curl_wildcard_init(wc); /* init wildcard structures */
+        if(result)
+          return CURLE_OUT_OF_MEMORY;
+      }
+    }
+  }
+
+  return result;
+}
+
+/*
+ * Curl_posttransfer() is called immediately after a transfer ends
+ */
+CURLcode Curl_posttransfer(struct Curl_easy *data)
+{
+#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL)
+  /* restore the signal handler for SIGPIPE before we get back */
+  if(!data->set.no_signal)
+    signal(SIGPIPE, data->state.prev_signal);
+#else
+  (void)data; /* unused parameter */
+#endif
+
+  return CURLE_OK;
+}
+
+#ifndef CURL_DISABLE_HTTP
+/*
+ * Find the separator at the end of the host name, or the '?' in cases like
+ * http://www.url.com?id=2380
+ */
+static const char *find_host_sep(const char *url)
+{
+  const char *sep;
+  const char *query;
+
+  /* Find the start of the hostname */
+  sep = strstr(url, "//");
+  if(!sep)
+    sep = url;
+  else
+    sep += 2;
+
+  query = strchr(sep, '?');
+  sep = strchr(sep, '/');
+
+  if(!sep)
+    sep = url + strlen(url);
+
+  if(!query)
+    query = url + strlen(url);
+
+  return sep < query ? sep : query;
+}
+
+/*
+ * strlen_url() returns the length of the given URL if the spaces within the
+ * URL were properly URL encoded.
+ * URL encoding should be skipped for host names, otherwise IDN resolution
+ * will fail.
+ */
+static size_t strlen_url(const char *url, bool relative)
+{
+  const unsigned char *ptr;
+  size_t newlen = 0;
+  bool left = TRUE; /* left side of the ? */
+  const unsigned char *host_sep = (const unsigned char *) url;
+
+  if(!relative)
+    host_sep = (const unsigned char *) find_host_sep(url);
+
+  for(ptr = (unsigned char *)url; *ptr; ptr++) {
+
+    if(ptr < host_sep) {
+      ++newlen;
+      continue;
+    }
+
+    switch(*ptr) {
+    case '?':
+      left = FALSE;
+      /* fall through */
+    default:
+      if(*ptr >= 0x80)
+        newlen += 2;
+      newlen++;
+      break;
+    case ' ':
+      if(left)
+        newlen += 3;
+      else
+        newlen++;
+      break;
+    }
+  }
+  return newlen;
+}
+
+/* strcpy_url() copies a url to a output buffer and URL-encodes the spaces in
+ * the source URL accordingly.
+ * URL encoding should be skipped for host names, otherwise IDN resolution
+ * will fail.
+ */
+static void strcpy_url(char *output, const char *url, bool relative)
+{
+  /* we must add this with whitespace-replacing */
+  bool left = TRUE;
+  const unsigned char *iptr;
+  char *optr = output;
+  const unsigned char *host_sep = (const unsigned char *) url;
+
+  if(!relative)
+    host_sep = (const unsigned char *) find_host_sep(url);
+
+  for(iptr = (unsigned char *)url;    /* read from here */
+      *iptr;         /* until zero byte */
+      iptr++) {
+
+    if(iptr < host_sep) {
+      *optr++ = *iptr;
+      continue;
+    }
+
+    switch(*iptr) {
+    case '?':
+      left = FALSE;
+      /* fall through */
+    default:
+      if(*iptr >= 0x80) {
+        snprintf(optr, 4, "%%%02x", *iptr);
+        optr += 3;
+      }
+      else
+        *optr++=*iptr;
+      break;
+    case ' ':
+      if(left) {
+        *optr++='%'; /* add a '%' */
+        *optr++='2'; /* add a '2' */
+        *optr++='0'; /* add a '0' */
+      }
+      else
+        *optr++='+'; /* add a '+' here */
+      break;
+    }
+  }
+  *optr = 0; /* zero terminate output buffer */
+
+}
+
+/*
+ * Returns true if the given URL is absolute (as opposed to relative)
+ */
+static bool is_absolute_url(const char *url)
+{
+  char prot[16]; /* URL protocol string storage */
+  char letter;   /* used for a silly sscanf */
+
+  return (2 == sscanf(url, "%15[^?&/:]://%c", prot, &letter)) ? TRUE : FALSE;
+}
+
+/*
+ * Concatenate a relative URL to a base URL making it absolute.
+ * URL-encodes any spaces.
+ * The returned pointer must be freed by the caller unless NULL
+ * (returns NULL on out of memory).
+ */
+static char *concat_url(const char *base, const char *relurl)
+{
+  /***
+   TRY to append this new path to the old URL
+   to the right of the host part. Oh crap, this is doomed to cause
+   problems in the future...
+  */
+  char *newest;
+  char *protsep;
+  char *pathsep;
+  size_t newlen;
+  bool host_changed = FALSE;
+
+  const char *useurl = relurl;
+  size_t urllen;
+
+  /* we must make our own copy of the URL to play with, as it may
+     point to read-only data */
+  char *url_clone = strdup(base);
+
+  if(!url_clone)
+    return NULL; /* skip out of this NOW */
+
+  /* protsep points to the start of the host name */
+  protsep = strstr(url_clone, "//");
+  if(!protsep)
+    protsep = url_clone;
+  else
+    protsep += 2; /* pass the slashes */
+
+  if('/' != relurl[0]) {
+    int level = 0;
+
+    /* First we need to find out if there's a ?-letter in the URL,
+       and cut it and the right-side of that off */
+    pathsep = strchr(protsep, '?');
+    if(pathsep)
+      *pathsep = 0;
+
+    /* we have a relative path to append to the last slash if there's one
+       available, or if the new URL is just a query string (starts with a
+       '?')  we append the new one at the end of the entire currently worked
+       out URL */
+    if(useurl[0] != '?') {
+      pathsep = strrchr(protsep, '/');
+      if(pathsep)
+        *pathsep = 0;
+    }
+
+    /* Check if there's any slash after the host name, and if so, remember
+       that position instead */
+    pathsep = strchr(protsep, '/');
+    if(pathsep)
+      protsep = pathsep + 1;
+    else
+      protsep = NULL;
+
+    /* now deal with one "./" or any amount of "../" in the newurl
+       and act accordingly */
+
+    if((useurl[0] == '.') && (useurl[1] == '/'))
+      useurl += 2; /* just skip the "./" */
+
+    while((useurl[0] == '.') &&
+          (useurl[1] == '.') &&
+          (useurl[2] == '/')) {
+      level++;
+      useurl += 3; /* pass the "../" */
+    }
+
+    if(protsep) {
+      while(level--) {
+        /* cut off one more level from the right of the original URL */
+        pathsep = strrchr(protsep, '/');
+        if(pathsep)
+          *pathsep = 0;
+        else {
+          *protsep = 0;
+          break;
+        }
+      }
+    }
+  }
+  else {
+    /* We got a new absolute path for this server */
+
+    if((relurl[0] == '/') && (relurl[1] == '/')) {
+      /* the new URL starts with //, just keep the protocol part from the
+         original one */
+      *protsep = 0;
+      useurl = &relurl[2]; /* we keep the slashes from the original, so we
+                              skip the new ones */
+      host_changed = TRUE;
+    }
+    else {
+      /* cut off the original URL from the first slash, or deal with URLs
+         without slash */
+      pathsep = strchr(protsep, '/');
+      if(pathsep) {
+        /* When people use badly formatted URLs, such as
+           "http://www.url.com?dir=/home/daniel" we must not use the first
+           slash, if there's a ?-letter before it! */
+        char *sep = strchr(protsep, '?');
+        if(sep && (sep < pathsep))
+          pathsep = sep;
+        *pathsep = 0;
+      }
+      else {
+        /* There was no slash. Now, since we might be operating on a badly
+           formatted URL, such as "http://www.url.com?id=2380" which doesn't
+           use a slash separator as it is supposed to, we need to check for a
+           ?-letter as well! */
+        pathsep = strchr(protsep, '?');
+        if(pathsep)
+          *pathsep = 0;
+      }
+    }
+  }
+
+  /* If the new part contains a space, this is a mighty stupid redirect
+     but we still make an effort to do "right". To the left of a '?'
+     letter we replace each space with %20 while it is replaced with '+'
+     on the right side of the '?' letter.
+  */
+  newlen = strlen_url(useurl, !host_changed);
+
+  urllen = strlen(url_clone);
+
+  newest = malloc(urllen + 1 + /* possible slash */
+                  newlen + 1 /* zero byte */);
+
+  if(!newest) {
+    free(url_clone); /* don't leak this */
+    return NULL;
+  }
+
+  /* copy over the root url part */
+  memcpy(newest, url_clone, urllen);
+
+  /* check if we need to append a slash */
+  if(('/' == useurl[0]) || (protsep && !*protsep) || ('?' == useurl[0]))
+    ;
+  else
+    newest[urllen++]='/';
+
+  /* then append the new piece on the right side */
+  strcpy_url(&newest[urllen], useurl, !host_changed);
+
+  free(url_clone);
+
+  return newest;
+}
+#endif /* CURL_DISABLE_HTTP */
+
+/*
+ * Curl_follow() handles the URL redirect magic. Pass in the 'newurl' string
+ * as given by the remote server and set up the new URL to request.
+ */
+CURLcode Curl_follow(struct Curl_easy *data,
+                     char *newurl,    /* the Location: string */
+                     followtype type) /* see transfer.h */
+{
+#ifdef CURL_DISABLE_HTTP
+  (void)data;
+  (void)newurl;
+  (void)type;
+  /* Location: following will not happen when HTTP is disabled */
+  return CURLE_TOO_MANY_REDIRECTS;
+#else
+
+  /* Location: redirect */
+  bool disallowport = FALSE;
+  bool reachedmax = FALSE;
+
+  if(type == FOLLOW_REDIR) {
+    if((data->set.maxredirs != -1) &&
+       (data->set.followlocation >= data->set.maxredirs)) {
+      reachedmax = TRUE;
+      type = FOLLOW_FAKE; /* switch to fake to store the would-be-redirected
+                             to URL */
+    }
+    else {
+      /* mark the next request as a followed location: */
+      data->state.this_is_a_follow = TRUE;
+
+      data->set.followlocation++; /* count location-followers */
+
+      if(data->set.http_auto_referer) {
+        /* We are asked to automatically set the previous URL as the referer
+           when we get the next URL. We pick the ->url field, which may or may
+           not be 100% correct */
+
+        if(data->change.referer_alloc) {
+          Curl_safefree(data->change.referer);
+          data->change.referer_alloc = FALSE;
+        }
+
+        data->change.referer = strdup(data->change.url);
+        if(!data->change.referer)
+          return CURLE_OUT_OF_MEMORY;
+        data->change.referer_alloc = TRUE; /* yes, free this later */
+      }
+    }
+  }
+
+  if(!is_absolute_url(newurl)) {
+    /***
+     *DANG* this is an RFC 2068 violation. The URL is supposed
+     to be absolute and this doesn't seem to be that!
+     */
+    char *absolute = concat_url(data->change.url, newurl);
+    if(!absolute)
+      return CURLE_OUT_OF_MEMORY;
+    newurl = absolute;
+  }
+  else {
+    /* The new URL MAY contain space or high byte values, that means a mighty
+       stupid redirect URL but we still make an effort to do "right". */
+    char *newest;
+    size_t newlen = strlen_url(newurl, FALSE);
+
+    /* This is an absolute URL, don't allow the custom port number */
+    disallowport = TRUE;
+
+    newest = malloc(newlen + 1); /* get memory for this */
+    if(!newest)
+      return CURLE_OUT_OF_MEMORY;
+
+    strcpy_url(newest, newurl, FALSE); /* create a space-free URL */
+    newurl = newest; /* use this instead now */
+
+  }
+
+  if(type == FOLLOW_FAKE) {
+    /* we're only figuring out the new url if we would've followed locations
+       but now we're done so we can get out! */
+    data->info.wouldredirect = newurl;
+
+    if(reachedmax) {
+      failf(data, "Maximum (%ld) redirects followed", data->set.maxredirs);
+      return CURLE_TOO_MANY_REDIRECTS;
+    }
+    return CURLE_OK;
+  }
+
+  if(disallowport)
+    data->state.allow_port = FALSE;
+
+  if(data->change.url_alloc) {
+    Curl_safefree(data->change.url);
+    data->change.url_alloc = FALSE;
+  }
+
+  data->change.url = newurl;
+  data->change.url_alloc = TRUE;
+
+  infof(data, "Issue another request to this URL: '%s'\n", data->change.url);
+
+  /*
+   * We get here when the HTTP code is 300-399 (and 401). We need to perform
+   * differently based on exactly what return code there was.
+   *
+   * News from 7.10.6: we can also get here on a 401 or 407, in case we act on
+   * a HTTP (proxy-) authentication scheme other than Basic.
+   */
+  switch(data->info.httpcode) {
+    /* 401 - Act on a WWW-Authenticate, we keep on moving and do the
+       Authorization: XXXX header in the HTTP request code snippet */
+    /* 407 - Act on a Proxy-Authenticate, we keep on moving and do the
+       Proxy-Authorization: XXXX header in the HTTP request code snippet */
+    /* 300 - Multiple Choices */
+    /* 306 - Not used */
+    /* 307 - Temporary Redirect */
+  default:  /* for all above (and the unknown ones) */
+    /* Some codes are explicitly mentioned since I've checked RFC2616 and they
+     * seem to be OK to POST to.
+     */
+    break;
+  case 301: /* Moved Permanently */
+    /* (quote from RFC7231, section 6.4.2)
+     *
+     * Note: For historical reasons, a user agent MAY change the request
+     * method from POST to GET for the subsequent request.  If this
+     * behavior is undesired, the 307 (Temporary Redirect) status code
+     * can be used instead.
+     *
+     * ----
+     *
+     * Many webservers expect this, so these servers often answers to a POST
+     * request with an error page. To be sure that libcurl gets the page that
+     * most user agents would get, libcurl has to force GET.
+     *
+     * This behaviour is forbidden by RFC1945 and the obsolete RFC2616, and
+     * can be overridden with CURLOPT_POSTREDIR.
+     */
+    if((data->set.httpreq == HTTPREQ_POST
+        || data->set.httpreq == HTTPREQ_POST_FORM
+        || data->set.httpreq == HTTPREQ_POST_MIME)
+       && !(data->set.keep_post & CURL_REDIR_POST_301)) {
+      infof(data, "Switch from POST to GET\n");
+      data->set.httpreq = HTTPREQ_GET;
+    }
+    break;
+  case 302: /* Found */
+    /* (quote from RFC7231, section 6.4.3)
+     *
+     * Note: For historical reasons, a user agent MAY change the request
+     * method from POST to GET for the subsequent request.  If this
+     * behavior is undesired, the 307 (Temporary Redirect) status code
+     * can be used instead.
+     *
+     * ----
+     *
+     * Many webservers expect this, so these servers often answers to a POST
+     * request with an error page. To be sure that libcurl gets the page that
+     * most user agents would get, libcurl has to force GET.
+     *
+     * This behaviour is forbidden by RFC1945 and the obsolete RFC2616, and
+     * can be overridden with CURLOPT_POSTREDIR.
+     */
+    if((data->set.httpreq == HTTPREQ_POST
+        || data->set.httpreq == HTTPREQ_POST_FORM
+        || data->set.httpreq == HTTPREQ_POST_MIME)
+       && !(data->set.keep_post & CURL_REDIR_POST_302)) {
+      infof(data, "Switch from POST to GET\n");
+      data->set.httpreq = HTTPREQ_GET;
+    }
+    break;
+
+  case 303: /* See Other */
+    /* Disable both types of POSTs, unless the user explicitly
+       asks for POST after POST */
+    if(data->set.httpreq != HTTPREQ_GET
+      && !(data->set.keep_post & CURL_REDIR_POST_303)) {
+      data->set.httpreq = HTTPREQ_GET; /* enforce GET request */
+      infof(data, "Disables POST, goes with %s\n",
+            data->set.opt_no_body?"HEAD":"GET");
+    }
+    break;
+  case 304: /* Not Modified */
+    /* 304 means we did a conditional request and it was "Not modified".
+     * We shouldn't get any Location: header in this response!
+     */
+    break;
+  case 305: /* Use Proxy */
+    /* (quote from RFC2616, section 10.3.6):
+     * "The requested resource MUST be accessed through the proxy given
+     * by the Location field. The Location field gives the URI of the
+     * proxy.  The recipient is expected to repeat this single request
+     * via the proxy. 305 responses MUST only be generated by origin
+     * servers."
+     */
+    break;
+  }
+  Curl_pgrsTime(data, TIMER_REDIRECT);
+  Curl_pgrsResetTransferSizes(data);
+
+  return CURLE_OK;
+#endif /* CURL_DISABLE_HTTP */
+}
+
+/* Returns CURLE_OK *and* sets '*url' if a request retry is wanted.
+
+   NOTE: that the *url is malloc()ed. */
+CURLcode Curl_retry_request(struct connectdata *conn,
+                            char **url)
+{
+  struct Curl_easy *data = conn->data;
+
+  *url = NULL;
+
+  /* if we're talking upload, we can't do the checks below, unless the protocol
+     is HTTP as when uploading over HTTP we will still get a response */
+  if(data->set.upload &&
+     !(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)))
+    return CURLE_OK;
+
+  if((data->req.bytecount + data->req.headerbytecount == 0) &&
+      conn->bits.reuse &&
+      (!data->set.opt_no_body
+        || (conn->handler->protocol & PROTO_FAMILY_HTTP)) &&
+      (data->set.rtspreq != RTSPREQ_RECEIVE)) {
+    /* We got no data, we attempted to re-use a connection. For HTTP this
+       can be a retry so we try again regardless if we expected a body.
+       For other protocols we only try again only if we expected a body.
+
+       This might happen if the connection was left alive when we were
+       done using it before, but that was closed when we wanted to read from
+       it again. Bad luck. Retry the same request on a fresh connect! */
+    infof(conn->data, "Connection died, retrying a fresh connect\n");
+    *url = strdup(conn->data->change.url);
+    if(!*url)
+      return CURLE_OUT_OF_MEMORY;
+
+    connclose(conn, "retry"); /* close this connection */
+    conn->bits.retry = TRUE; /* mark this as a connection we're about
+                                to retry. Marking it this way should
+                                prevent i.e HTTP transfers to return
+                                error just because nothing has been
+                                transferred! */
+
+
+    if(conn->handler->protocol&PROTO_FAMILY_HTTP) {
+      struct HTTP *http = data->req.protop;
+      if(http->writebytecount)
+        return Curl_readrewind(conn);
+    }
+  }
+  return CURLE_OK;
+}
+
+/*
+ * Curl_setup_transfer() is called to setup some basic properties for the
+ * upcoming transfer.
+ */
+void
+Curl_setup_transfer(
+  struct connectdata *conn, /* connection data */
+  int sockindex,            /* socket index to read from or -1 */
+  curl_off_t size,          /* -1 if unknown at this point */
+  bool getheader,           /* TRUE if header parsing is wanted */
+  curl_off_t *bytecountp,   /* return number of bytes read or NULL */
+  int writesockindex,       /* socket index to write to, it may very well be
+                               the same we read from. -1 disables */
+  curl_off_t *writecountp   /* return number of bytes written or NULL */
+  )
+{
+  struct Curl_easy *data;
+  struct SingleRequest *k;
+
+  DEBUGASSERT(conn != NULL);
+
+  data = conn->data;
+  k = &data->req;
+
+  DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
+
+  /* now copy all input parameters */
+  conn->sockfd = sockindex == -1 ?
+      CURL_SOCKET_BAD : conn->sock[sockindex];
+  conn->writesockfd = writesockindex == -1 ?
+      CURL_SOCKET_BAD:conn->sock[writesockindex];
+  k->getheader = getheader;
+
+  k->size = size;
+  k->bytecountp = bytecountp;
+  k->writebytecountp = writecountp;
+
+  /* The code sequence below is placed in this function just because all
+     necessary input is not always known in do_complete() as this function may
+     be called after that */
+
+  if(!k->getheader) {
+    k->header = FALSE;
+    if(size > 0)
+      Curl_pgrsSetDownloadSize(data, size);
+  }
+  /* we want header and/or body, if neither then don't do this! */
+  if(k->getheader || !data->set.opt_no_body) {
+
+    if(conn->sockfd != CURL_SOCKET_BAD)
+      k->keepon |= KEEP_RECV;
+
+    if(conn->writesockfd != CURL_SOCKET_BAD) {
+      struct HTTP *http = data->req.protop;
+      /* HTTP 1.1 magic:
+
+         Even if we require a 100-return code before uploading data, we might
+         need to write data before that since the REQUEST may not have been
+         finished sent off just yet.
+
+         Thus, we must check if the request has been sent before we set the
+         state info where we wait for the 100-return code
+      */
+      if((data->state.expect100header) &&
+         (conn->handler->protocol&PROTO_FAMILY_HTTP) &&
+         (http->sending == HTTPSEND_BODY)) {
+        /* wait with write until we either got 100-continue or a timeout */
+        k->exp100 = EXP100_AWAITING_CONTINUE;
+        k->start100 = Curl_now();
+
+        /* Set a timeout for the multi interface. Add the inaccuracy margin so
+           that we don't fire slightly too early and get denied to run. */
+        Curl_expire(data, data->set.expect_100_timeout, EXPIRE_100_TIMEOUT);
+      }
+      else {
+        if(data->state.expect100header)
+          /* when we've sent off the rest of the headers, we must await a
+             100-continue but first finish sending the request */
+          k->exp100 = EXP100_SENDING_REQUEST;
+
+        /* enable the write bit when we're not waiting for continue */
+        k->keepon |= KEEP_SEND;
+      }
+    } /* if(conn->writesockfd != CURL_SOCKET_BAD) */
+  } /* if(k->getheader || !data->set.opt_no_body) */
+
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/transfer.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/transfer.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/transfer.h	(revision 331)
@@ -0,0 +1,71 @@
+#ifndef HEADER_CURL_TRANSFER_H
+#define HEADER_CURL_TRANSFER_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+char *Curl_checkheaders(const struct connectdata *conn,
+                        const char *thisheader);
+
+void Curl_init_CONNECT(struct Curl_easy *data);
+
+CURLcode Curl_pretransfer(struct Curl_easy *data);
+CURLcode Curl_second_connect(struct connectdata *conn);
+CURLcode Curl_posttransfer(struct Curl_easy *data);
+
+typedef enum {
+  FOLLOW_NONE,  /* not used within the function, just a placeholder to
+                   allow initing to this */
+  FOLLOW_FAKE,  /* only records stuff, not actually following */
+  FOLLOW_RETRY, /* set if this is a request retry as opposed to a real
+                          redirect following */
+  FOLLOW_REDIR, /* a full true redirect */
+  FOLLOW_LAST   /* never used */
+} followtype;
+
+CURLcode Curl_follow(struct Curl_easy *data, char *newurl,
+                     followtype type);
+CURLcode Curl_readwrite(struct connectdata *conn,
+                        struct Curl_easy *data, bool *done,
+                        bool *comeback);
+int Curl_single_getsock(const struct connectdata *conn,
+                        curl_socket_t *socks,
+                        int numsocks);
+CURLcode Curl_readrewind(struct connectdata *conn);
+CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp);
+CURLcode Curl_retry_request(struct connectdata *conn, char **url);
+bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc);
+
+/* This sets up a forthcoming transfer */
+void
+Curl_setup_transfer (struct connectdata *data,
+               int sockindex,           /* socket index to read from or -1 */
+               curl_off_t size,         /* -1 if unknown at this point */
+               bool getheader,          /* TRUE if header parsing is wanted */
+               curl_off_t *bytecountp,  /* return number of bytes read */
+               int writesockindex,      /* socket index to write to, it may
+                                           very well be the same we read from.
+                                           -1 disables */
+               curl_off_t *writecountp /* return number of bytes written */
+);
+
+#endif /* HEADER_CURL_TRANSFER_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/url.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/url.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/url.c	(revision 331)
@@ -0,0 +1,4872 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#ifdef __VMS
+#include <in.h>
+#include <inet.h>
+#endif
+
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+
+#ifndef HAVE_SOCKET
+#error "We can't compile without socket() support!"
+#endif
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#ifdef USE_LIBIDN2
+#include <idn2.h>
+
+#elif defined(USE_WIN32_IDN)
+/* prototype for curl_win32_idn_to_ascii() */
+bool curl_win32_idn_to_ascii(const char *in, char **out);
+#endif  /* USE_LIBIDN2 */
+
+#include "urldata.h"
+#include "netrc.h"
+
+#include "formdata.h"
+#include "mime.h"
+#include "vtls/vtls.h"
+#include "hostip.h"
+#include "transfer.h"
+#include "sendf.h"
+#include "progress.h"
+#include "cookie.h"
+#include "strcase.h"
+#include "strerror.h"
+#include "escape.h"
+#include "strtok.h"
+#include "share.h"
+#include "content_encoding.h"
+#include "http_digest.h"
+#include "http_negotiate.h"
+#include "select.h"
+#include "multiif.h"
+#include "easyif.h"
+#include "speedcheck.h"
+#include "warnless.h"
+#include "non-ascii.h"
+#include "inet_pton.h"
+#include "getinfo.h"
+
+/* And now for the protocols */
+#include "ftp.h"
+#include "dict.h"
+#include "telnet.h"
+#include "tftp.h"
+#include "http.h"
+#include "http2.h"
+#include "file.h"
+#include "curl_ldap.h"
+#include "ssh.h"
+#include "imap.h"
+#include "url.h"
+#include "connect.h"
+#include "inet_ntop.h"
+#include "http_ntlm.h"
+#include "curl_ntlm_wb.h"
+#include "socks.h"
+#include "curl_rtmp.h"
+#include "gopher.h"
+#include "http_proxy.h"
+#include "conncache.h"
+#include "multihandle.h"
+#include "pipeline.h"
+#include "dotdot.h"
+#include "strdup.h"
+#include "setopt.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* Local static prototypes */
+static struct connectdata *
+find_oldest_idle_connection_in_bundle(struct Curl_easy *data,
+                                      struct connectbundle *bundle);
+static void conn_free(struct connectdata *conn);
+static void free_fixed_hostname(struct hostname *host);
+static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
+static CURLcode parse_url_login(struct Curl_easy *data,
+                                struct connectdata *conn,
+                                char **userptr, char **passwdptr,
+                                char **optionsptr);
+static unsigned int get_protocol_family(unsigned int protocol);
+
+/* Some parts of the code (e.g. chunked encoding) assume this buffer has at
+ * more than just a few bytes to play with. Don't let it become too small or
+ * bad things will happen.
+ */
+#if READBUFFER_SIZE < READBUFFER_MIN
+# error READBUFFER_SIZE is too small
+#endif
+
+
+/*
+ * Protocol table.
+ */
+
+static const struct Curl_handler * const protocols[] = {
+
+#ifndef CURL_DISABLE_HTTP
+  &Curl_handler_http,
+#endif
+
+#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
+  &Curl_handler_https,
+#endif
+
+#ifndef CURL_DISABLE_FTP
+  &Curl_handler_ftp,
+#endif
+
+#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
+  &Curl_handler_ftps,
+#endif
+
+#ifndef CURL_DISABLE_TELNET
+  &Curl_handler_telnet,
+#endif
+
+#ifndef CURL_DISABLE_DICT
+  &Curl_handler_dict,
+#endif
+
+#ifndef CURL_DISABLE_LDAP
+  &Curl_handler_ldap,
+#if !defined(CURL_DISABLE_LDAPS) && \
+    ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
+     (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
+  &Curl_handler_ldaps,
+#endif
+#endif
+
+#ifndef CURL_DISABLE_FILE
+  &Curl_handler_file,
+#endif
+
+#ifndef CURL_DISABLE_TFTP
+  &Curl_handler_tftp,
+#endif
+
+#ifdef USE_LIBSSH2
+  &Curl_handler_scp,
+  &Curl_handler_sftp,
+#endif
+
+#ifndef CURL_DISABLE_IMAP
+  &Curl_handler_imap,
+#ifdef USE_SSL
+  &Curl_handler_imaps,
+#endif
+#endif
+
+#ifndef CURL_DISABLE_POP3
+  &Curl_handler_pop3,
+#ifdef USE_SSL
+  &Curl_handler_pop3s,
+#endif
+#endif
+
+#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
+   (CURL_SIZEOF_CURL_OFF_T > 4) && \
+   (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO))
+  &Curl_handler_smb,
+#ifdef USE_SSL
+  &Curl_handler_smbs,
+#endif
+#endif
+
+#ifndef CURL_DISABLE_SMTP
+  &Curl_handler_smtp,
+#ifdef USE_SSL
+  &Curl_handler_smtps,
+#endif
+#endif
+
+#ifndef CURL_DISABLE_RTSP
+  &Curl_handler_rtsp,
+#endif
+
+#ifndef CURL_DISABLE_GOPHER
+  &Curl_handler_gopher,
+#endif
+
+#ifdef USE_LIBRTMP
+  &Curl_handler_rtmp,
+  &Curl_handler_rtmpt,
+  &Curl_handler_rtmpe,
+  &Curl_handler_rtmpte,
+  &Curl_handler_rtmps,
+  &Curl_handler_rtmpts,
+#endif
+
+  (struct Curl_handler *) NULL
+};
+
+/*
+ * Dummy handler for undefined protocol schemes.
+ */
+
+static const struct Curl_handler Curl_handler_dummy = {
+  "<no protocol>",                      /* scheme */
+  ZERO_NULL,                            /* setup_connection */
+  ZERO_NULL,                            /* do_it */
+  ZERO_NULL,                            /* done */
+  ZERO_NULL,                            /* do_more */
+  ZERO_NULL,                            /* connect_it */
+  ZERO_NULL,                            /* connecting */
+  ZERO_NULL,                            /* doing */
+  ZERO_NULL,                            /* proto_getsock */
+  ZERO_NULL,                            /* doing_getsock */
+  ZERO_NULL,                            /* domore_getsock */
+  ZERO_NULL,                            /* perform_getsock */
+  ZERO_NULL,                            /* disconnect */
+  ZERO_NULL,                            /* readwrite */
+  ZERO_NULL,                            /* connection_check */
+  0,                                    /* defport */
+  0,                                    /* protocol */
+  PROTOPT_NONE                          /* flags */
+};
+
+void Curl_freeset(struct Curl_easy *data)
+{
+  /* Free all dynamic strings stored in the data->set substructure. */
+  enum dupstring i;
+  for(i = (enum dupstring)0; i < STRING_LAST; i++) {
+    Curl_safefree(data->set.str[i]);
+  }
+
+  if(data->change.referer_alloc) {
+    Curl_safefree(data->change.referer);
+    data->change.referer_alloc = FALSE;
+  }
+  data->change.referer = NULL;
+  if(data->change.url_alloc) {
+    Curl_safefree(data->change.url);
+    data->change.url_alloc = FALSE;
+  }
+  data->change.url = NULL;
+}
+
+/*
+ * This is the internal function curl_easy_cleanup() calls. This should
+ * cleanup and free all resources associated with this sessionhandle.
+ *
+ * NOTE: if we ever add something that attempts to write to a socket or
+ * similar here, we must ignore SIGPIPE first. It is currently only done
+ * when curl_easy_perform() is invoked.
+ */
+
+CURLcode Curl_close(struct Curl_easy *data)
+{
+  struct Curl_multi *m;
+
+  if(!data)
+    return CURLE_OK;
+
+  Curl_expire_clear(data); /* shut off timers */
+
+  m = data->multi;
+
+  if(m)
+    /* This handle is still part of a multi handle, take care of this first
+       and detach this handle from there. */
+    curl_multi_remove_handle(data->multi, data);
+
+  if(data->multi_easy)
+    /* when curl_easy_perform() is used, it creates its own multi handle to
+       use and this is the one */
+    curl_multi_cleanup(data->multi_easy);
+
+  /* Destroy the timeout list that is held in the easy handle. It is
+     /normally/ done by curl_multi_remove_handle() but this is "just in
+     case" */
+  Curl_llist_destroy(&data->state.timeoutlist, NULL);
+
+  data->magic = 0; /* force a clear AFTER the possibly enforced removal from
+                      the multi handle, since that function uses the magic
+                      field! */
+
+  if(data->state.rangestringalloc)
+    free(data->state.range);
+
+  /* Free the pathbuffer */
+  Curl_safefree(data->state.pathbuffer);
+  data->state.path = NULL;
+
+  /* freed here just in case DONE wasn't called */
+  Curl_free_request_state(data);
+
+  /* Close down all open SSL info and sessions */
+  Curl_ssl_close_all(data);
+  Curl_safefree(data->state.first_host);
+  Curl_safefree(data->state.scratch);
+  Curl_ssl_free_certinfo(data);
+
+  /* Cleanup possible redirect junk */
+  free(data->req.newurl);
+  data->req.newurl = NULL;
+
+  if(data->change.referer_alloc) {
+    Curl_safefree(data->change.referer);
+    data->change.referer_alloc = FALSE;
+  }
+  data->change.referer = NULL;
+
+  if(data->change.url_alloc) {
+    Curl_safefree(data->change.url);
+    data->change.url_alloc = FALSE;
+  }
+  data->change.url = NULL;
+
+  Curl_safefree(data->state.buffer);
+  Curl_safefree(data->state.headerbuff);
+
+  Curl_flush_cookies(data, 1);
+
+  Curl_digest_cleanup(data);
+
+  Curl_safefree(data->info.contenttype);
+  Curl_safefree(data->info.wouldredirect);
+
+  /* this destroys the channel and we cannot use it anymore after this */
+  Curl_resolver_cleanup(data->state.resolver);
+
+  Curl_http2_cleanup_dependencies(data);
+  Curl_convert_close(data);
+
+  Curl_mime_cleanpart(&data->set.mimepost);
+
+  /* No longer a dirty share, if it exists */
+  if(data->share) {
+    Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
+    data->share->dirty--;
+    Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
+  }
+
+  /* destruct wildcard structures if it is needed */
+  Curl_wildcard_dtor(&data->wildcard);
+  Curl_freeset(data);
+  free(data);
+  return CURLE_OK;
+}
+
+/*
+ * Initialize the UserDefined fields within a Curl_easy.
+ * This may be safely called on a new or existing Curl_easy.
+ */
+CURLcode Curl_init_userdefined(struct UserDefined *set)
+{
+  CURLcode result = CURLE_OK;
+
+  set->out = stdout; /* default output to stdout */
+  set->in_set = stdin;  /* default input from stdin */
+  set->err  = stderr;  /* default stderr to stderr */
+
+  /* use fwrite as default function to store output */
+  set->fwrite_func = (curl_write_callback)fwrite;
+
+  /* use fread as default function to read input */
+  set->fread_func_set = (curl_read_callback)fread;
+  set->is_fread_set = 0;
+  set->is_fwrite_set = 0;
+
+  set->seek_func = ZERO_NULL;
+  set->seek_client = ZERO_NULL;
+
+  /* conversion callbacks for non-ASCII hosts */
+  set->convfromnetwork = ZERO_NULL;
+  set->convtonetwork   = ZERO_NULL;
+  set->convfromutf8    = ZERO_NULL;
+
+  set->filesize = -1;        /* we don't know the size */
+  set->postfieldsize = -1;   /* unknown size */
+  set->maxredirs = -1;       /* allow any amount by default */
+
+  set->httpreq = HTTPREQ_GET; /* Default HTTP request */
+  set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */
+  set->ftp_use_epsv = TRUE;   /* FTP defaults to EPSV operations */
+  set->ftp_use_eprt = TRUE;   /* FTP defaults to EPRT operations */
+  set->ftp_use_pret = FALSE;  /* mainly useful for drftpd servers */
+  set->ftp_filemethod = FTPFILE_MULTICWD;
+
+  set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
+
+  /* Set the default size of the SSL session ID cache */
+  set->general_ssl.max_ssl_sessions = 5;
+
+  set->proxyport = 0;
+  set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
+  set->httpauth = CURLAUTH_BASIC;  /* defaults to basic */
+  set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */
+
+  /* SOCKS5 proxy auth defaults to username/password + GSS-API */
+  set->socks5auth = CURLAUTH_BASIC | CURLAUTH_GSSAPI;
+
+  /* make libcurl quiet by default: */
+  set->hide_progress = TRUE;  /* CURLOPT_NOPROGRESS changes these */
+
+  /*
+   * libcurl 7.10 introduced SSL verification *by default*! This needs to be
+   * switched off unless wanted.
+   */
+  set->ssl.primary.verifypeer = TRUE;
+  set->ssl.primary.verifyhost = TRUE;
+#ifdef USE_TLS_SRP
+  set->ssl.authtype = CURL_TLSAUTH_NONE;
+#endif
+  set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
+                                                      type */
+  set->ssl.primary.sessionid = TRUE; /* session ID caching enabled by
+                                        default */
+  set->proxy_ssl = set->ssl;
+
+  set->new_file_perms = 0644;    /* Default permissions */
+  set->new_directory_perms = 0755; /* Default permissions */
+
+  /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
+     define since we internally only use the lower 16 bits for the passed
+     in bitmask to not conflict with the private bits */
+  set->allowed_protocols = CURLPROTO_ALL;
+  set->redir_protocols = CURLPROTO_ALL &  /* All except FILE, SCP and SMB */
+                          ~(CURLPROTO_FILE | CURLPROTO_SCP | CURLPROTO_SMB |
+                            CURLPROTO_SMBS);
+
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  /*
+   * disallow unprotected protection negotiation NEC reference implementation
+   * seem not to follow rfc1961 section 4.3/4.4
+   */
+  set->socks5_gssapi_nec = FALSE;
+#endif
+
+  /* This is our preferred CA cert bundle/path since install time */
+#if defined(CURL_CA_BUNDLE)
+  result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_ORIG], CURL_CA_BUNDLE);
+  if(result)
+    return result;
+
+  result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_PROXY], CURL_CA_BUNDLE);
+  if(result)
+    return result;
+#endif
+#if defined(CURL_CA_PATH)
+  result = Curl_setstropt(&set->str[STRING_SSL_CAPATH_ORIG], CURL_CA_PATH);
+  if(result)
+    return result;
+
+  result = Curl_setstropt(&set->str[STRING_SSL_CAPATH_PROXY], CURL_CA_PATH);
+  if(result)
+    return result;
+#endif
+
+  set->wildcard_enabled = FALSE;
+  set->chunk_bgn      = ZERO_NULL;
+  set->chunk_end      = ZERO_NULL;
+
+  /* tcp keepalives are disabled by default, but provide reasonable values for
+   * the interval and idle times.
+   */
+  set->tcp_keepalive = FALSE;
+  set->tcp_keepintvl = 60;
+  set->tcp_keepidle = 60;
+  set->tcp_fastopen = FALSE;
+  set->tcp_nodelay = TRUE;
+
+  set->ssl_enable_npn = TRUE;
+  set->ssl_enable_alpn = TRUE;
+
+  set->expect_100_timeout = 1000L; /* Wait for a second by default. */
+  set->sep_headers = TRUE; /* separated header lists by default */
+  set->buffer_size = READBUFFER_SIZE;
+
+  Curl_http2_init_userset(set);
+  return result;
+}
+
+/**
+ * Curl_open()
+ *
+ * @param curl is a pointer to a sessionhandle pointer that gets set by this
+ * function.
+ * @return CURLcode
+ */
+
+CURLcode Curl_open(struct Curl_easy **curl)
+{
+  CURLcode result;
+  struct Curl_easy *data;
+
+  /* Very simple start-up: alloc the struct, init it with zeroes and return */
+  data = calloc(1, sizeof(struct Curl_easy));
+  if(!data) {
+    /* this is a very serious error */
+    DEBUGF(fprintf(stderr, "Error: calloc of Curl_easy failed\n"));
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  data->magic = CURLEASY_MAGIC_NUMBER;
+
+  result = Curl_resolver_init(&data->state.resolver);
+  if(result) {
+    DEBUGF(fprintf(stderr, "Error: resolver_init failed\n"));
+    free(data);
+    return result;
+  }
+
+  /* We do some initial setup here, all those fields that can't be just 0 */
+
+  data->state.buffer = malloc(READBUFFER_SIZE + 1);
+  if(!data->state.buffer) {
+    DEBUGF(fprintf(stderr, "Error: malloc of buffer failed\n"));
+    result = CURLE_OUT_OF_MEMORY;
+  }
+  else {
+    Curl_mime_initpart(&data->set.mimepost, data);
+
+    data->state.headerbuff = malloc(HEADERSIZE);
+    if(!data->state.headerbuff) {
+      DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
+      result = CURLE_OUT_OF_MEMORY;
+    }
+    else {
+      result = Curl_init_userdefined(&data->set);
+
+      data->state.headersize = HEADERSIZE;
+      Curl_convert_init(data);
+      Curl_initinfo(data);
+
+      /* most recent connection is not yet defined */
+      data->state.lastconnect = NULL;
+
+      data->progress.flags |= PGRS_HIDE;
+      data->state.current_speed = -1; /* init to negative == impossible */
+      data->set.fnmatch = ZERO_NULL;
+      data->set.maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
+
+      Curl_http2_init_state(&data->state);
+    }
+  }
+
+  if(result) {
+    Curl_resolver_cleanup(data->state.resolver);
+    free(data->state.buffer);
+    free(data->state.headerbuff);
+    Curl_freeset(data);
+    free(data);
+    data = NULL;
+  }
+  else
+    *curl = data;
+
+  return result;
+}
+
+#ifdef USE_RECV_BEFORE_SEND_WORKAROUND
+static void conn_reset_postponed_data(struct connectdata *conn, int num)
+{
+  struct postponed_data * const psnd = &(conn->postponed[num]);
+  if(psnd->buffer) {
+    DEBUGASSERT(psnd->allocated_size > 0);
+    DEBUGASSERT(psnd->recv_size <= psnd->allocated_size);
+    DEBUGASSERT(psnd->recv_size ?
+                (psnd->recv_processed < psnd->recv_size) :
+                (psnd->recv_processed == 0));
+    DEBUGASSERT(psnd->bindsock != CURL_SOCKET_BAD);
+    free(psnd->buffer);
+    psnd->buffer = NULL;
+    psnd->allocated_size = 0;
+    psnd->recv_size = 0;
+    psnd->recv_processed = 0;
+#ifdef DEBUGBUILD
+    psnd->bindsock = CURL_SOCKET_BAD; /* used only for DEBUGASSERT */
+#endif /* DEBUGBUILD */
+  }
+  else {
+    DEBUGASSERT(psnd->allocated_size == 0);
+    DEBUGASSERT(psnd->recv_size == 0);
+    DEBUGASSERT(psnd->recv_processed == 0);
+    DEBUGASSERT(psnd->bindsock == CURL_SOCKET_BAD);
+  }
+}
+
+static void conn_reset_all_postponed_data(struct connectdata *conn)
+{
+  conn_reset_postponed_data(conn, 0);
+  conn_reset_postponed_data(conn, 1);
+}
+#else  /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
+/* Use "do-nothing" macro instead of function when workaround not used */
+#define conn_reset_all_postponed_data(c) do {} WHILE_FALSE
+#endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */
+
+static void conn_free(struct connectdata *conn)
+{
+  if(!conn)
+    return;
+
+  /* possible left-overs from the async name resolvers */
+  Curl_resolver_cancel(conn);
+
+  /* close the SSL stuff before we close any sockets since they will/may
+     write to the sockets */
+  Curl_ssl_close(conn, FIRSTSOCKET);
+  Curl_ssl_close(conn, SECONDARYSOCKET);
+
+  /* close possibly still open sockets */
+  if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
+    Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
+  if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
+    Curl_closesocket(conn, conn->sock[FIRSTSOCKET]);
+  if(CURL_SOCKET_BAD != conn->tempsock[0])
+    Curl_closesocket(conn, conn->tempsock[0]);
+  if(CURL_SOCKET_BAD != conn->tempsock[1])
+    Curl_closesocket(conn, conn->tempsock[1]);
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
+    defined(NTLM_WB_ENABLED)
+  Curl_ntlm_wb_cleanup(conn);
+#endif
+
+  Curl_safefree(conn->user);
+  Curl_safefree(conn->passwd);
+  Curl_safefree(conn->oauth_bearer);
+  Curl_safefree(conn->options);
+  Curl_safefree(conn->http_proxy.user);
+  Curl_safefree(conn->socks_proxy.user);
+  Curl_safefree(conn->http_proxy.passwd);
+  Curl_safefree(conn->socks_proxy.passwd);
+  Curl_safefree(conn->allocptr.proxyuserpwd);
+  Curl_safefree(conn->allocptr.uagent);
+  Curl_safefree(conn->allocptr.userpwd);
+  Curl_safefree(conn->allocptr.accept_encoding);
+  Curl_safefree(conn->allocptr.te);
+  Curl_safefree(conn->allocptr.rangeline);
+  Curl_safefree(conn->allocptr.ref);
+  Curl_safefree(conn->allocptr.host);
+  Curl_safefree(conn->allocptr.cookiehost);
+  Curl_safefree(conn->allocptr.rtsp_transport);
+  Curl_safefree(conn->trailer);
+  Curl_safefree(conn->host.rawalloc); /* host name buffer */
+  Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */
+  Curl_safefree(conn->secondaryhostname);
+  Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */
+  Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */
+  Curl_safefree(conn->master_buffer);
+  Curl_safefree(conn->connect_state);
+
+  conn_reset_all_postponed_data(conn);
+
+  Curl_llist_destroy(&conn->send_pipe, NULL);
+  Curl_llist_destroy(&conn->recv_pipe, NULL);
+
+  Curl_safefree(conn->localdev);
+  Curl_free_primary_ssl_config(&conn->ssl_config);
+  Curl_free_primary_ssl_config(&conn->proxy_ssl_config);
+
+#ifdef USE_UNIX_SOCKETS
+  Curl_safefree(conn->unix_domain_socket);
+#endif
+
+  free(conn); /* free all the connection oriented data */
+}
+
+/*
+ * Disconnects the given connection. Note the connection may not be the
+ * primary connection, like when freeing room in the connection cache or
+ * killing of a dead old connection.
+ *
+ * This function MUST NOT reset state in the Curl_easy struct if that
+ * isn't strictly bound to the life-time of *this* particular connection.
+ *
+ */
+
+CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
+{
+  struct Curl_easy *data;
+  if(!conn)
+    return CURLE_OK; /* this is closed and fine already */
+  data = conn->data;
+
+  if(!data) {
+    DEBUGF(fprintf(stderr, "DISCONNECT without easy handle, ignoring\n"));
+    return CURLE_OK;
+  }
+
+  /*
+   * If this connection isn't marked to force-close, leave it open if there
+   * are other users of it
+   */
+  if(!conn->bits.close &&
+     (conn->send_pipe.size + conn->recv_pipe.size)) {
+    DEBUGF(infof(data, "Curl_disconnect, usecounter: %d\n",
+                 conn->send_pipe.size + conn->recv_pipe.size));
+    return CURLE_OK;
+  }
+
+  if(conn->dns_entry != NULL) {
+    Curl_resolv_unlock(data, conn->dns_entry);
+    conn->dns_entry = NULL;
+  }
+
+  Curl_hostcache_prune(data); /* kill old DNS cache entries */
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
+  /* Cleanup NTLM connection-related data */
+  Curl_http_ntlm_cleanup(conn);
+#endif
+
+  if(conn->handler->disconnect)
+    /* This is set if protocol-specific cleanups should be made */
+    conn->handler->disconnect(conn, dead_connection);
+
+    /* unlink ourselves! */
+  infof(data, "Closing connection %ld\n", conn->connection_id);
+  Curl_conncache_remove_conn(data->state.conn_cache, conn);
+
+  free_fixed_hostname(&conn->host);
+  free_fixed_hostname(&conn->conn_to_host);
+  free_fixed_hostname(&conn->http_proxy.host);
+  free_fixed_hostname(&conn->socks_proxy.host);
+
+  Curl_ssl_close(conn, FIRSTSOCKET);
+
+  /* Indicate to all handles on the pipe that we're dead */
+  if(Curl_pipeline_wanted(data->multi, CURLPIPE_ANY)) {
+    signalPipeClose(&conn->send_pipe, TRUE);
+    signalPipeClose(&conn->recv_pipe, TRUE);
+  }
+
+  conn_free(conn);
+
+  return CURLE_OK;
+}
+
+/*
+ * This function should return TRUE if the socket is to be assumed to
+ * be dead. Most commonly this happens when the server has closed the
+ * connection due to inactivity.
+ */
+static bool SocketIsDead(curl_socket_t sock)
+{
+  int sval;
+  bool ret_val = TRUE;
+
+  sval = SOCKET_READABLE(sock, 0);
+  if(sval == 0)
+    /* timeout */
+    ret_val = FALSE;
+
+  return ret_val;
+}
+
+/*
+ * IsPipeliningPossible()
+ *
+ * Return a bitmask with the available pipelining and multiplexing options for
+ * the given requested connection.
+ */
+static int IsPipeliningPossible(const struct Curl_easy *handle,
+                                const struct connectdata *conn)
+{
+  int avail = 0;
+
+  /* If a HTTP protocol and pipelining is enabled */
+  if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
+     (!conn->bits.protoconnstart || !conn->bits.close)) {
+
+    if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
+       (handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
+       (handle->set.httpreq == HTTPREQ_GET ||
+        handle->set.httpreq == HTTPREQ_HEAD))
+      /* didn't ask for HTTP/1.0 and a GET or HEAD */
+      avail |= CURLPIPE_HTTP1;
+
+    if(Curl_pipeline_wanted(handle->multi, CURLPIPE_MULTIPLEX) &&
+       (handle->set.httpversion >= CURL_HTTP_VERSION_2))
+      /* allows HTTP/2 */
+      avail |= CURLPIPE_MULTIPLEX;
+  }
+  return avail;
+}
+
+int Curl_removeHandleFromPipeline(struct Curl_easy *handle,
+                                  struct curl_llist *pipeline)
+{
+  if(pipeline) {
+    struct curl_llist_element *curr;
+
+    curr = pipeline->head;
+    while(curr) {
+      if(curr->ptr == handle) {
+        Curl_llist_remove(pipeline, curr, NULL);
+        return 1; /* we removed a handle */
+      }
+      curr = curr->next;
+    }
+  }
+
+  return 0;
+}
+
+#if 0 /* this code is saved here as it is useful for debugging purposes */
+static void Curl_printPipeline(struct curl_llist *pipeline)
+{
+  struct curl_llist_element *curr;
+
+  curr = pipeline->head;
+  while(curr) {
+    struct Curl_easy *data = (struct Curl_easy *) curr->ptr;
+    infof(data, "Handle in pipeline: %s\n", data->state.path);
+    curr = curr->next;
+  }
+}
+#endif
+
+static struct Curl_easy* gethandleathead(struct curl_llist *pipeline)
+{
+  struct curl_llist_element *curr = pipeline->head;
+  if(curr) {
+    return (struct Curl_easy *) curr->ptr;
+  }
+
+  return NULL;
+}
+
+/* remove the specified connection from all (possible) pipelines and related
+   queues */
+void Curl_getoff_all_pipelines(struct Curl_easy *data,
+                               struct connectdata *conn)
+{
+  bool recv_head = (conn->readchannel_inuse &&
+                    Curl_recvpipe_head(data, conn));
+  bool send_head = (conn->writechannel_inuse &&
+                    Curl_sendpipe_head(data, conn));
+
+  if(Curl_removeHandleFromPipeline(data, &conn->recv_pipe) && recv_head)
+    Curl_pipeline_leave_read(conn);
+  if(Curl_removeHandleFromPipeline(data, &conn->send_pipe) && send_head)
+    Curl_pipeline_leave_write(conn);
+}
+
+static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke)
+{
+  struct curl_llist_element *curr;
+
+  if(!pipeline)
+    return;
+
+  curr = pipeline->head;
+  while(curr) {
+    struct curl_llist_element *next = curr->next;
+    struct Curl_easy *data = (struct Curl_easy *) curr->ptr;
+
+#ifdef DEBUGBUILD /* debug-only code */
+    if(data->magic != CURLEASY_MAGIC_NUMBER) {
+      /* MAJOR BADNESS */
+      infof(data, "signalPipeClose() found BAAD easy handle\n");
+    }
+#endif
+
+    if(pipe_broke)
+      data->state.pipe_broke = TRUE;
+    Curl_multi_handlePipeBreak(data);
+    Curl_llist_remove(pipeline, curr, NULL);
+    curr = next;
+  }
+}
+
+static bool
+proxy_info_matches(const struct proxy_info* data,
+                   const struct proxy_info* needle)
+{
+  if((data->proxytype == needle->proxytype) &&
+     (data->port == needle->port) &&
+     Curl_safe_strcasecompare(data->host.name, needle->host.name))
+    return TRUE;
+
+  return FALSE;
+}
+
+
+/*
+ * This function finds the connection in the connection
+ * bundle that has been unused for the longest time.
+ *
+ * Returns the pointer to the oldest idle connection, or NULL if none was
+ * found.
+ */
+static struct connectdata *
+find_oldest_idle_connection_in_bundle(struct Curl_easy *data,
+                                      struct connectbundle *bundle)
+{
+  struct curl_llist_element *curr;
+  timediff_t highscore = -1;
+  timediff_t score;
+  struct curltime now;
+  struct connectdata *conn_candidate = NULL;
+  struct connectdata *conn;
+
+  (void)data;
+
+  now = Curl_now();
+
+  curr = bundle->conn_list.head;
+  while(curr) {
+    conn = curr->ptr;
+
+    if(!conn->inuse) {
+      /* Set higher score for the age passed since the connection was used */
+      score = Curl_timediff(now, conn->now);
+
+      if(score > highscore) {
+        highscore = score;
+        conn_candidate = conn;
+      }
+    }
+    curr = curr->next;
+  }
+
+  return conn_candidate;
+}
+
+/*
+ * This function checks if given connection is dead and disconnects if so.
+ * (That also removes it from the connection cache.)
+ *
+ * Returns TRUE if the connection actually was dead and disconnected.
+ */
+static bool disconnect_if_dead(struct connectdata *conn,
+                               struct Curl_easy *data)
+{
+  size_t pipeLen = conn->send_pipe.size + conn->recv_pipe.size;
+  if(!pipeLen && !conn->inuse) {
+    /* The check for a dead socket makes sense only if there are no
+       handles in pipeline and the connection isn't already marked in
+       use */
+    bool dead;
+
+    if(conn->handler->connection_check) {
+      /* The protocol has a special method for checking the state of the
+         connection. Use it to check if the connection is dead. */
+      unsigned int state;
+
+      state = conn->handler->connection_check(conn, CONNCHECK_ISDEAD);
+      dead = (state & CONNRESULT_DEAD);
+    }
+    else {
+      /* Use the general method for determining the death of a connection */
+      dead = SocketIsDead(conn->sock[FIRSTSOCKET]);
+    }
+
+    if(dead) {
+      conn->data = data;
+      infof(data, "Connection %ld seems to be dead!\n", conn->connection_id);
+
+      /* disconnect resources */
+      Curl_disconnect(conn, /* dead_connection */TRUE);
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+/*
+ * Wrapper to use disconnect_if_dead() function in Curl_conncache_foreach()
+ *
+ * Returns always 0.
+ */
+static int call_disconnect_if_dead(struct connectdata *conn,
+                                      void *param)
+{
+  struct Curl_easy* data = (struct Curl_easy*)param;
+  disconnect_if_dead(conn, data);
+  return 0; /* continue iteration */
+}
+
+/*
+ * This function scans the connection cache for half-open/dead connections,
+ * closes and removes them.
+ * The cleanup is done at most once per second.
+ */
+static void prune_dead_connections(struct Curl_easy *data)
+{
+  struct curltime now = Curl_now();
+  time_t elapsed = Curl_timediff(now, data->state.conn_cache->last_cleanup);
+
+  if(elapsed >= 1000L) {
+    Curl_conncache_foreach(data, data->state.conn_cache, data,
+                           call_disconnect_if_dead);
+    data->state.conn_cache->last_cleanup = now;
+  }
+}
+
+
+static size_t max_pipeline_length(struct Curl_multi *multi)
+{
+  return multi ? multi->max_pipeline_length : 0;
+}
+
+
+/*
+ * Given one filled in connection struct (named needle), this function should
+ * detect if there already is one that has all the significant details
+ * exactly the same and thus should be used instead.
+ *
+ * If there is a match, this function returns TRUE - and has marked the
+ * connection as 'in-use'. It must later be called with ConnectionDone() to
+ * return back to 'idle' (unused) state.
+ *
+ * The force_reuse flag is set if the connection must be used, even if
+ * the pipelining strategy wants to open a new connection instead of reusing.
+ */
+static bool
+ConnectionExists(struct Curl_easy *data,
+                 struct connectdata *needle,
+                 struct connectdata **usethis,
+                 bool *force_reuse,
+                 bool *waitpipe)
+{
+  struct connectdata *check;
+  struct connectdata *chosen = 0;
+  bool foundPendingCandidate = FALSE;
+  int canpipe = IsPipeliningPossible(data, needle);
+  struct connectbundle *bundle;
+
+#ifdef USE_NTLM
+  bool wantNTLMhttp = ((data->state.authhost.want &
+                      (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
+                      (needle->handler->protocol & PROTO_FAMILY_HTTP));
+  bool wantProxyNTLMhttp = (needle->bits.proxy_user_passwd &&
+                           ((data->state.authproxy.want &
+                           (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
+                           (needle->handler->protocol & PROTO_FAMILY_HTTP)));
+#endif
+
+  *force_reuse = FALSE;
+  *waitpipe = FALSE;
+
+  /* We can't pipeline if the site is blacklisted */
+  if((canpipe & CURLPIPE_HTTP1) &&
+     Curl_pipeline_site_blacklisted(data, needle))
+    canpipe &= ~ CURLPIPE_HTTP1;
+
+  /* Look up the bundle with all the connections to this
+     particular host */
+  bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache);
+  if(bundle) {
+    /* Max pipe length is zero (unlimited) for multiplexed connections */
+    size_t max_pipe_len = (bundle->multiuse != BUNDLE_MULTIPLEX)?
+      max_pipeline_length(data->multi):0;
+    size_t best_pipe_len = max_pipe_len;
+    struct curl_llist_element *curr;
+
+    infof(data, "Found bundle for host %s: %p [%s]\n",
+          (needle->bits.conn_to_host ? needle->conn_to_host.name :
+           needle->host.name), (void *)bundle,
+          (bundle->multiuse == BUNDLE_PIPELINING ?
+           "can pipeline" :
+           (bundle->multiuse == BUNDLE_MULTIPLEX ?
+            "can multiplex" : "serially")));
+
+    /* We can't pipeline if we don't know anything about the server */
+    if(canpipe) {
+      if(bundle->multiuse <= BUNDLE_UNKNOWN) {
+        if((bundle->multiuse == BUNDLE_UNKNOWN) && data->set.pipewait) {
+          infof(data, "Server doesn't support multi-use yet, wait\n");
+          *waitpipe = TRUE;
+          return FALSE; /* no re-use */
+        }
+
+        infof(data, "Server doesn't support multi-use (yet)\n");
+        canpipe = 0;
+      }
+      if((bundle->multiuse == BUNDLE_PIPELINING) &&
+         !Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1)) {
+        /* not asked for, switch off */
+        infof(data, "Could pipeline, but not asked to!\n");
+        canpipe = 0;
+      }
+      else if((bundle->multiuse == BUNDLE_MULTIPLEX) &&
+              !Curl_pipeline_wanted(data->multi, CURLPIPE_MULTIPLEX)) {
+        infof(data, "Could multiplex, but not asked to!\n");
+        canpipe = 0;
+      }
+    }
+
+    curr = bundle->conn_list.head;
+    while(curr) {
+      bool match = FALSE;
+      size_t pipeLen;
+
+      /*
+       * Note that if we use a HTTP proxy in normal mode (no tunneling), we
+       * check connections to that proxy and not to the actual remote server.
+       */
+      check = curr->ptr;
+      curr = curr->next;
+
+      if(disconnect_if_dead(check, data))
+        continue;
+
+      pipeLen = check->send_pipe.size + check->recv_pipe.size;
+
+      if(canpipe) {
+        if(check->bits.protoconnstart && check->bits.close)
+          continue;
+
+        if(!check->bits.multiplex) {
+          /* If not multiplexing, make sure the connection is fine for HTTP/1
+             pipelining */
+          struct Curl_easy* sh = gethandleathead(&check->send_pipe);
+          struct Curl_easy* rh = gethandleathead(&check->recv_pipe);
+          if(sh) {
+            if(!(IsPipeliningPossible(sh, check) & CURLPIPE_HTTP1))
+              continue;
+          }
+          else if(rh) {
+            if(!(IsPipeliningPossible(rh, check) & CURLPIPE_HTTP1))
+              continue;
+          }
+        }
+      }
+      else {
+        if(pipeLen > 0) {
+          /* can only happen within multi handles, and means that another easy
+             handle is using this connection */
+          continue;
+        }
+
+        if(Curl_resolver_asynch()) {
+          /* ip_addr_str[0] is NUL only if the resolving of the name hasn't
+             completed yet and until then we don't re-use this connection */
+          if(!check->ip_addr_str[0]) {
+            infof(data,
+                  "Connection #%ld is still name resolving, can't reuse\n",
+                  check->connection_id);
+            continue;
+          }
+        }
+
+        if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) ||
+           check->bits.close) {
+          if(!check->bits.close)
+            foundPendingCandidate = TRUE;
+          /* Don't pick a connection that hasn't connected yet or that is going
+             to get closed. */
+          infof(data, "Connection #%ld isn't open enough, can't reuse\n",
+                check->connection_id);
+#ifdef DEBUGBUILD
+          if(check->recv_pipe.size > 0) {
+            infof(data,
+                  "BAD! Unconnected #%ld has a non-empty recv pipeline!\n",
+                  check->connection_id);
+          }
+#endif
+          continue;
+        }
+      }
+
+#ifdef USE_UNIX_SOCKETS
+      if(needle->unix_domain_socket) {
+        if(!check->unix_domain_socket)
+          continue;
+        if(strcmp(needle->unix_domain_socket, check->unix_domain_socket))
+          continue;
+        if(needle->abstract_unix_socket != check->abstract_unix_socket)
+          continue;
+      }
+      else if(check->unix_domain_socket)
+        continue;
+#endif
+
+      if((needle->handler->flags&PROTOPT_SSL) !=
+         (check->handler->flags&PROTOPT_SSL))
+        /* don't do mixed SSL and non-SSL connections */
+        if(get_protocol_family(check->handler->protocol) !=
+           needle->handler->protocol || !check->tls_upgraded)
+          /* except protocols that have been upgraded via TLS */
+          continue;
+
+      if(needle->bits.httpproxy != check->bits.httpproxy ||
+         needle->bits.socksproxy != check->bits.socksproxy)
+        continue;
+
+      if(needle->bits.socksproxy && !proxy_info_matches(&needle->socks_proxy,
+                                                        &check->socks_proxy))
+        continue;
+
+      if(needle->bits.conn_to_host != check->bits.conn_to_host)
+        /* don't mix connections that use the "connect to host" feature and
+         * connections that don't use this feature */
+        continue;
+
+      if(needle->bits.conn_to_port != check->bits.conn_to_port)
+        /* don't mix connections that use the "connect to port" feature and
+         * connections that don't use this feature */
+        continue;
+
+      if(needle->bits.httpproxy) {
+        if(!proxy_info_matches(&needle->http_proxy, &check->http_proxy))
+          continue;
+
+        if(needle->bits.tunnel_proxy != check->bits.tunnel_proxy)
+          continue;
+
+        if(needle->http_proxy.proxytype == CURLPROXY_HTTPS) {
+          /* use https proxy */
+          if(needle->handler->flags&PROTOPT_SSL) {
+            /* use double layer ssl */
+            if(!Curl_ssl_config_matches(&needle->proxy_ssl_config,
+                                        &check->proxy_ssl_config))
+              continue;
+            if(check->proxy_ssl[FIRSTSOCKET].state != ssl_connection_complete)
+              continue;
+          }
+          else {
+            if(!Curl_ssl_config_matches(&needle->ssl_config,
+                                        &check->ssl_config))
+              continue;
+            if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete)
+              continue;
+          }
+        }
+      }
+
+      if(!canpipe && check->inuse)
+        /* this request can't be pipelined but the checked connection is
+           already in use so we skip it */
+        continue;
+
+      if(needle->localdev || needle->localport) {
+        /* If we are bound to a specific local end (IP+port), we must not
+           re-use a random other one, although if we didn't ask for a
+           particular one we can reuse one that was bound.
+
+           This comparison is a bit rough and too strict. Since the input
+           parameters can be specified in numerous ways and still end up the
+           same it would take a lot of processing to make it really accurate.
+           Instead, this matching will assume that re-uses of bound connections
+           will most likely also re-use the exact same binding parameters and
+           missing out a few edge cases shouldn't hurt anyone very much.
+        */
+        if((check->localport != needle->localport) ||
+           (check->localportrange != needle->localportrange) ||
+           (needle->localdev &&
+            (!check->localdev || strcmp(check->localdev, needle->localdev))))
+          continue;
+      }
+
+      if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) {
+        /* This protocol requires credentials per connection,
+           so verify that we're using the same name and password as well */
+        if(strcmp(needle->user, check->user) ||
+           strcmp(needle->passwd, check->passwd)) {
+          /* one of them was different */
+          continue;
+        }
+      }
+
+      if(!needle->bits.httpproxy || (needle->handler->flags&PROTOPT_SSL) ||
+         needle->bits.tunnel_proxy) {
+        /* The requested connection does not use a HTTP proxy or it uses SSL or
+           it is a non-SSL protocol tunneled or it is a non-SSL protocol which
+           is allowed to be upgraded via TLS */
+
+        if((strcasecompare(needle->handler->scheme, check->handler->scheme) ||
+            (get_protocol_family(check->handler->protocol) ==
+             needle->handler->protocol && check->tls_upgraded)) &&
+           (!needle->bits.conn_to_host || strcasecompare(
+            needle->conn_to_host.name, check->conn_to_host.name)) &&
+           (!needle->bits.conn_to_port ||
+             needle->conn_to_port == check->conn_to_port) &&
+           strcasecompare(needle->host.name, check->host.name) &&
+           needle->remote_port == check->remote_port) {
+          /* The schemes match or the the protocol family is the same and the
+             previous connection was TLS upgraded, and the hostname and host
+             port match */
+          if(needle->handler->flags & PROTOPT_SSL) {
+            /* This is a SSL connection so verify that we're using the same
+               SSL options as well */
+            if(!Curl_ssl_config_matches(&needle->ssl_config,
+                                        &check->ssl_config)) {
+              DEBUGF(infof(data,
+                           "Connection #%ld has different SSL parameters, "
+                           "can't reuse\n",
+                           check->connection_id));
+              continue;
+            }
+            if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) {
+              foundPendingCandidate = TRUE;
+              DEBUGF(infof(data,
+                           "Connection #%ld has not started SSL connect, "
+                           "can't reuse\n",
+                           check->connection_id));
+              continue;
+            }
+          }
+          match = TRUE;
+        }
+      }
+      else {
+        /* The requested connection is using the same HTTP proxy in normal
+           mode (no tunneling) */
+        match = TRUE;
+      }
+
+      if(match) {
+#if defined(USE_NTLM)
+        /* If we are looking for an HTTP+NTLM connection, check if this is
+           already authenticating with the right credentials. If not, keep
+           looking so that we can reuse NTLM connections if
+           possible. (Especially we must not reuse the same connection if
+           partway through a handshake!) */
+        if(wantNTLMhttp) {
+          if(strcmp(needle->user, check->user) ||
+             strcmp(needle->passwd, check->passwd))
+            continue;
+        }
+        else if(check->ntlm.state != NTLMSTATE_NONE) {
+          /* Connection is using NTLM auth but we don't want NTLM */
+          continue;
+        }
+
+        /* Same for Proxy NTLM authentication */
+        if(wantProxyNTLMhttp) {
+          /* Both check->http_proxy.user and check->http_proxy.passwd can be
+           * NULL */
+          if(!check->http_proxy.user || !check->http_proxy.passwd)
+            continue;
+
+          if(strcmp(needle->http_proxy.user, check->http_proxy.user) ||
+             strcmp(needle->http_proxy.passwd, check->http_proxy.passwd))
+            continue;
+        }
+        else if(check->proxyntlm.state != NTLMSTATE_NONE) {
+          /* Proxy connection is using NTLM auth but we don't want NTLM */
+          continue;
+        }
+
+        if(wantNTLMhttp || wantProxyNTLMhttp) {
+          /* Credentials are already checked, we can use this connection */
+          chosen = check;
+
+          if((wantNTLMhttp &&
+             (check->ntlm.state != NTLMSTATE_NONE)) ||
+              (wantProxyNTLMhttp &&
+               (check->proxyntlm.state != NTLMSTATE_NONE))) {
+            /* We must use this connection, no other */
+            *force_reuse = TRUE;
+            break;
+          }
+
+          /* Continue look up for a better connection */
+          continue;
+        }
+#endif
+        if(canpipe) {
+          /* We can pipeline if we want to. Let's continue looking for
+             the optimal connection to use, i.e the shortest pipe that is not
+             blacklisted. */
+
+          if(pipeLen == 0) {
+            /* We have the optimal connection. Let's stop looking. */
+            chosen = check;
+            break;
+          }
+
+          /* We can't use the connection if the pipe is full */
+          if(max_pipe_len && (pipeLen >= max_pipe_len)) {
+            infof(data, "Pipe is full, skip (%zu)\n", pipeLen);
+            continue;
+          }
+#ifdef USE_NGHTTP2
+          /* If multiplexed, make sure we don't go over concurrency limit */
+          if(check->bits.multiplex) {
+            /* Multiplexed connections can only be HTTP/2 for now */
+            struct http_conn *httpc = &check->proto.httpc;
+            if(pipeLen >= httpc->settings.max_concurrent_streams) {
+              infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)\n",
+                    pipeLen);
+              continue;
+            }
+          }
+#endif
+          /* We can't use the connection if the pipe is penalized */
+          if(Curl_pipeline_penalized(data, check)) {
+            infof(data, "Penalized, skip\n");
+            continue;
+          }
+
+          if(max_pipe_len) {
+            if(pipeLen < best_pipe_len) {
+              /* This connection has a shorter pipe so far. We'll pick this
+                 and continue searching */
+              chosen = check;
+              best_pipe_len = pipeLen;
+              continue;
+            }
+          }
+          else {
+            /* When not pipelining (== multiplexed), we have a match here! */
+            chosen = check;
+            infof(data, "Multiplexed connection found!\n");
+            break;
+          }
+        }
+        else {
+          /* We have found a connection. Let's stop searching. */
+          chosen = check;
+          break;
+        }
+      }
+    }
+  }
+
+  if(chosen) {
+    *usethis = chosen;
+    return TRUE; /* yes, we found one to use! */
+  }
+
+  if(foundPendingCandidate && data->set.pipewait) {
+    infof(data,
+          "Found pending candidate for reuse and CURLOPT_PIPEWAIT is set\n");
+    *waitpipe = TRUE;
+  }
+
+  return FALSE; /* no matching connecting exists */
+}
+
+/* after a TCP connection to the proxy has been verified, this function does
+   the next magic step.
+
+   Note: this function's sub-functions call failf()
+
+*/
+CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex)
+{
+  CURLcode result = CURLE_OK;
+
+  if(conn->bits.socksproxy) {
+#ifndef CURL_DISABLE_PROXY
+    /* for the secondary socket (FTP), use the "connect to host"
+     * but ignore the "connect to port" (use the secondary port)
+     */
+    const char * const host = conn->bits.httpproxy ?
+                              conn->http_proxy.host.name :
+                              conn->bits.conn_to_host ?
+                              conn->conn_to_host.name :
+                              sockindex == SECONDARYSOCKET ?
+                              conn->secondaryhostname : conn->host.name;
+    const int port = conn->bits.httpproxy ? (int)conn->http_proxy.port :
+                     sockindex == SECONDARYSOCKET ? conn->secondary_port :
+                     conn->bits.conn_to_port ? conn->conn_to_port :
+                     conn->remote_port;
+    conn->bits.socksproxy_connecting = TRUE;
+    switch(conn->socks_proxy.proxytype) {
+    case CURLPROXY_SOCKS5:
+    case CURLPROXY_SOCKS5_HOSTNAME:
+      result = Curl_SOCKS5(conn->socks_proxy.user, conn->socks_proxy.passwd,
+                         host, port, sockindex, conn);
+      break;
+
+    case CURLPROXY_SOCKS4:
+    case CURLPROXY_SOCKS4A:
+      result = Curl_SOCKS4(conn->socks_proxy.user, host, port, sockindex,
+                           conn);
+      break;
+
+    default:
+      failf(conn->data, "unknown proxytype option given");
+      result = CURLE_COULDNT_CONNECT;
+    } /* switch proxytype */
+    conn->bits.socksproxy_connecting = FALSE;
+#else
+  (void)sockindex;
+#endif /* CURL_DISABLE_PROXY */
+  }
+
+  return result;
+}
+
+/*
+ * verboseconnect() displays verbose information after a connect
+ */
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+void Curl_verboseconnect(struct connectdata *conn)
+{
+  if(conn->data->set.verbose)
+    infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n",
+          conn->bits.socksproxy ? conn->socks_proxy.host.dispname :
+          conn->bits.httpproxy ? conn->http_proxy.host.dispname :
+          conn->bits.conn_to_host ? conn->conn_to_host.dispname :
+          conn->host.dispname,
+          conn->ip_addr_str, conn->port, conn->connection_id);
+}
+#endif
+
+int Curl_protocol_getsock(struct connectdata *conn,
+                          curl_socket_t *socks,
+                          int numsocks)
+{
+  if(conn->handler->proto_getsock)
+    return conn->handler->proto_getsock(conn, socks, numsocks);
+  return GETSOCK_BLANK;
+}
+
+int Curl_doing_getsock(struct connectdata *conn,
+                       curl_socket_t *socks,
+                       int numsocks)
+{
+  if(conn && conn->handler->doing_getsock)
+    return conn->handler->doing_getsock(conn, socks, numsocks);
+  return GETSOCK_BLANK;
+}
+
+/*
+ * We are doing protocol-specific connecting and this is being called over and
+ * over from the multi interface until the connection phase is done on
+ * protocol layer.
+ */
+
+CURLcode Curl_protocol_connecting(struct connectdata *conn,
+                                  bool *done)
+{
+  CURLcode result = CURLE_OK;
+
+  if(conn && conn->handler->connecting) {
+    *done = FALSE;
+    result = conn->handler->connecting(conn, done);
+  }
+  else
+    *done = TRUE;
+
+  return result;
+}
+
+/*
+ * We are DOING this is being called over and over from the multi interface
+ * until the DOING phase is done on protocol layer.
+ */
+
+CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
+{
+  CURLcode result = CURLE_OK;
+
+  if(conn && conn->handler->doing) {
+    *done = FALSE;
+    result = conn->handler->doing(conn, done);
+  }
+  else
+    *done = TRUE;
+
+  return result;
+}
+
+/*
+ * We have discovered that the TCP connection has been successful, we can now
+ * proceed with some action.
+ *
+ */
+CURLcode Curl_protocol_connect(struct connectdata *conn,
+                               bool *protocol_done)
+{
+  CURLcode result = CURLE_OK;
+
+  *protocol_done = FALSE;
+
+  if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) {
+    /* We already are connected, get back. This may happen when the connect
+       worked fine in the first call, like when we connect to a local server
+       or proxy. Note that we don't know if the protocol is actually done.
+
+       Unless this protocol doesn't have any protocol-connect callback, as
+       then we know we're done. */
+    if(!conn->handler->connecting)
+      *protocol_done = TRUE;
+
+    return CURLE_OK;
+  }
+
+  if(!conn->bits.protoconnstart) {
+
+    result = Curl_proxy_connect(conn, FIRSTSOCKET);
+    if(result)
+      return result;
+
+    if(CONNECT_FIRSTSOCKET_PROXY_SSL())
+      /* wait for HTTPS proxy SSL initialization to complete */
+      return CURLE_OK;
+
+    if(conn->bits.tunnel_proxy && conn->bits.httpproxy &&
+       Curl_connect_ongoing(conn))
+      /* when using an HTTP tunnel proxy, await complete tunnel establishment
+         before proceeding further. Return CURLE_OK so we'll be called again */
+      return CURLE_OK;
+
+    if(conn->handler->connect_it) {
+      /* is there a protocol-specific connect() procedure? */
+
+      /* Call the protocol-specific connect function */
+      result = conn->handler->connect_it(conn, protocol_done);
+    }
+    else
+      *protocol_done = TRUE;
+
+    /* it has started, possibly even completed but that knowledge isn't stored
+       in this bit! */
+    if(!result)
+      conn->bits.protoconnstart = TRUE;
+  }
+
+  return result; /* pass back status */
+}
+
+/*
+ * Helpers for IDNA conversions.
+ */
+static bool is_ASCII_name(const char *hostname)
+{
+  const unsigned char *ch = (const unsigned char *)hostname;
+
+  while(*ch) {
+    if(*ch++ & 0x80)
+      return FALSE;
+  }
+  return TRUE;
+}
+
+/*
+ * Perform any necessary IDN conversion of hostname
+ */
+static CURLcode fix_hostname(struct connectdata *conn, struct hostname *host)
+{
+  size_t len;
+  struct Curl_easy *data = conn->data;
+
+#ifndef USE_LIBIDN2
+  (void)data;
+  (void)conn;
+#elif defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void)conn;
+#endif
+
+  /* set the name we use to display the host name */
+  host->dispname = host->name;
+
+  len = strlen(host->name);
+  if(len && (host->name[len-1] == '.'))
+    /* strip off a single trailing dot if present, primarily for SNI but
+       there's no use for it */
+    host->name[len-1] = 0;
+
+  /* Check name for non-ASCII and convert hostname to ACE form if we can */
+  if(!is_ASCII_name(host->name)) {
+#ifdef USE_LIBIDN2
+    if(idn2_check_version(IDN2_VERSION)) {
+      char *ace_hostname = NULL;
+#if IDN2_VERSION_NUMBER >= 0x00140000
+      /* IDN2_NFC_INPUT: Normalize input string using normalization form C.
+         IDN2_NONTRANSITIONAL: Perform Unicode TR46 non-transitional
+         processing. */
+      int flags = IDN2_NFC_INPUT | IDN2_NONTRANSITIONAL;
+#else
+      int flags = IDN2_NFC_INPUT;
+#endif
+      int rc = idn2_lookup_ul((const char *)host->name, &ace_hostname, flags);
+      if(rc == IDN2_OK) {
+        host->encalloc = (char *)ace_hostname;
+        /* change the name pointer to point to the encoded hostname */
+        host->name = host->encalloc;
+      }
+      else {
+        failf(data, "Failed to convert %s to ACE; %s\n", host->name,
+              idn2_strerror(rc));
+        return CURLE_URL_MALFORMAT;
+      }
+    }
+#elif defined(USE_WIN32_IDN)
+    char *ace_hostname = NULL;
+
+    if(curl_win32_idn_to_ascii(host->name, &ace_hostname)) {
+      host->encalloc = ace_hostname;
+      /* change the name pointer to point to the encoded hostname */
+      host->name = host->encalloc;
+    }
+    else {
+      failf(data, "Failed to convert %s to ACE;\n", host->name);
+      return CURLE_URL_MALFORMAT;
+    }
+#else
+    infof(data, "IDN support not present, can't parse Unicode domains\n");
+#endif
+  }
+  {
+    char *hostp;
+    for(hostp = host->name; *hostp; hostp++) {
+      if(*hostp <= 32) {
+        failf(data, "Host name '%s' contains bad letter", host->name);
+        return CURLE_URL_MALFORMAT;
+      }
+    }
+  }
+  return CURLE_OK;
+}
+
+/*
+ * Frees data allocated by fix_hostname()
+ */
+static void free_fixed_hostname(struct hostname *host)
+{
+#if defined(USE_LIBIDN2)
+  if(host->encalloc) {
+    idn2_free(host->encalloc); /* must be freed with idn2_free() since this was
+                                 allocated by libidn */
+    host->encalloc = NULL;
+  }
+#elif defined(USE_WIN32_IDN)
+  free(host->encalloc); /* must be freed with free() since this was
+                           allocated by curl_win32_idn_to_ascii */
+  host->encalloc = NULL;
+#else
+  (void)host;
+#endif
+}
+
+static void llist_dtor(void *user, void *element)
+{
+  (void)user;
+  (void)element;
+  /* Do nothing */
+}
+
+/*
+ * Allocate and initialize a new connectdata object.
+ */
+static struct connectdata *allocate_conn(struct Curl_easy *data)
+{
+  struct connectdata *conn;
+  size_t connsize = sizeof(struct connectdata);
+
+#ifdef USE_SSL
+/* SSLBK_MAX_ALIGN: The max byte alignment a CPU would use */
+#define SSLBK_MAX_ALIGN 32
+  /* The SSL backend-specific data (ssl_backend_data) objects are allocated as
+     part of connectdata at the end. To ensure suitable alignment we will
+     assume a maximum of SSLBK_MAX_ALIGN for alignment. Since calloc returns a
+     pointer suitably aligned for any variable this will ensure the
+     ssl_backend_data array has proper alignment, even if that alignment turns
+     out to be less than SSLBK_MAX_ALIGN. */
+  size_t paddingsize = sizeof(struct connectdata) % SSLBK_MAX_ALIGN;
+  size_t alignsize = paddingsize ? (SSLBK_MAX_ALIGN - paddingsize) : 0;
+  size_t sslbksize = Curl_ssl->sizeof_ssl_backend_data;
+  connsize += alignsize + (4 * sslbksize);
+#endif
+
+  conn = calloc(1, connsize);
+  if(!conn)
+    return NULL;
+
+#ifdef USE_SSL
+  /* Point to the ssl_backend_data objects at the end of connectdata.
+     Note that these backend pointers can be swapped by vtls (eg ssl backend
+     data becomes proxy backend data). */
+  {
+    char *end = (char *)conn + connsize;
+    conn->ssl[0].backend = ((void *)(end - (4 * sslbksize)));
+    conn->ssl[1].backend = ((void *)(end - (3 * sslbksize)));
+    conn->proxy_ssl[0].backend = ((void *)(end - (2 * sslbksize)));
+    conn->proxy_ssl[1].backend = ((void *)(end - (1 * sslbksize)));
+  }
+#endif
+
+  conn->handler = &Curl_handler_dummy;  /* Be sure we have a handler defined
+                                           already from start to avoid NULL
+                                           situations and checks */
+
+  /* and we setup a few fields in case we end up actually using this struct */
+
+  conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD;     /* no file descriptor */
+  conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
+  conn->tempsock[0] = CURL_SOCKET_BAD; /* no file descriptor */
+  conn->tempsock[1] = CURL_SOCKET_BAD; /* no file descriptor */
+  conn->connection_id = -1;    /* no ID */
+  conn->port = -1; /* unknown at this point */
+  conn->remote_port = -1; /* unknown at this point */
+#if defined(USE_RECV_BEFORE_SEND_WORKAROUND) && defined(DEBUGBUILD)
+  conn->postponed[0].bindsock = CURL_SOCKET_BAD; /* no file descriptor */
+  conn->postponed[1].bindsock = CURL_SOCKET_BAD; /* no file descriptor */
+#endif /* USE_RECV_BEFORE_SEND_WORKAROUND && DEBUGBUILD */
+
+  /* Default protocol-independent behavior doesn't support persistent
+     connections, so we set this to force-close. Protocols that support
+     this need to set this to FALSE in their "curl_do" functions. */
+  connclose(conn, "Default to force-close");
+
+  /* Store creation time to help future close decision making */
+  conn->created = Curl_now();
+
+  conn->data = data; /* Setup the association between this connection
+                        and the Curl_easy */
+
+  conn->http_proxy.proxytype = data->set.proxytype;
+  conn->socks_proxy.proxytype = CURLPROXY_SOCKS4;
+
+#ifdef CURL_DISABLE_PROXY
+
+  conn->bits.proxy = FALSE;
+  conn->bits.httpproxy = FALSE;
+  conn->bits.socksproxy = FALSE;
+  conn->bits.proxy_user_passwd = FALSE;
+  conn->bits.tunnel_proxy = FALSE;
+
+#else /* CURL_DISABLE_PROXY */
+
+  /* note that these two proxy bits are now just on what looks to be
+     requested, they may be altered down the road */
+  conn->bits.proxy = (data->set.str[STRING_PROXY] &&
+                      *data->set.str[STRING_PROXY]) ? TRUE : FALSE;
+  conn->bits.httpproxy = (conn->bits.proxy &&
+                          (conn->http_proxy.proxytype == CURLPROXY_HTTP ||
+                           conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0 ||
+                           conn->http_proxy.proxytype == CURLPROXY_HTTPS)) ?
+                           TRUE : FALSE;
+  conn->bits.socksproxy = (conn->bits.proxy &&
+                           !conn->bits.httpproxy) ? TRUE : FALSE;
+
+  if(data->set.str[STRING_PRE_PROXY] && *data->set.str[STRING_PRE_PROXY]) {
+    conn->bits.proxy = TRUE;
+    conn->bits.socksproxy = TRUE;
+  }
+
+  conn->bits.proxy_user_passwd =
+    (data->set.str[STRING_PROXYUSERNAME]) ? TRUE : FALSE;
+  conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
+
+#endif /* CURL_DISABLE_PROXY */
+
+  conn->bits.user_passwd = (data->set.str[STRING_USERNAME]) ? TRUE : FALSE;
+  conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
+  conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
+
+  conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus;
+  conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer;
+  conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost;
+  conn->proxy_ssl_config.verifystatus =
+    data->set.proxy_ssl.primary.verifystatus;
+  conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer;
+  conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost;
+
+  conn->ip_version = data->set.ipver;
+
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
+    defined(NTLM_WB_ENABLED)
+  conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
+  conn->ntlm_auth_hlpr_pid = 0;
+  conn->challenge_header = NULL;
+  conn->response_header = NULL;
+#endif
+
+  if(Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1) &&
+     !conn->master_buffer) {
+    /* Allocate master_buffer to be used for HTTP/1 pipelining */
+    conn->master_buffer = calloc(MASTERBUF_SIZE, sizeof(char));
+    if(!conn->master_buffer)
+      goto error;
+  }
+
+  /* Initialize the pipeline lists */
+  Curl_llist_init(&conn->send_pipe, (curl_llist_dtor) llist_dtor);
+  Curl_llist_init(&conn->recv_pipe, (curl_llist_dtor) llist_dtor);
+
+#ifdef HAVE_GSSAPI
+  conn->data_prot = PROT_CLEAR;
+#endif
+
+  /* Store the local bind parameters that will be used for this connection */
+  if(data->set.str[STRING_DEVICE]) {
+    conn->localdev = strdup(data->set.str[STRING_DEVICE]);
+    if(!conn->localdev)
+      goto error;
+  }
+  conn->localportrange = data->set.localportrange;
+  conn->localport = data->set.localport;
+
+  /* the close socket stuff needs to be copied to the connection struct as
+     it may live on without (this specific) Curl_easy */
+  conn->fclosesocket = data->set.fclosesocket;
+  conn->closesocket_client = data->set.closesocket_client;
+
+  return conn;
+  error:
+
+  Curl_llist_destroy(&conn->send_pipe, NULL);
+  Curl_llist_destroy(&conn->recv_pipe, NULL);
+
+  free(conn->master_buffer);
+  free(conn->localdev);
+  free(conn);
+  return NULL;
+}
+
+static CURLcode findprotocol(struct Curl_easy *data,
+                             struct connectdata *conn,
+                             const char *protostr)
+{
+  const struct Curl_handler * const *pp;
+  const struct Curl_handler *p;
+
+  /* Scan protocol handler table and match against 'protostr' to set a few
+     variables based on the URL. Now that the handler may be changed later
+     when the protocol specific setup function is called. */
+  for(pp = protocols; (p = *pp) != NULL; pp++) {
+    if(strcasecompare(p->scheme, protostr)) {
+      /* Protocol found in table. Check if allowed */
+      if(!(data->set.allowed_protocols & p->protocol))
+        /* nope, get out */
+        break;
+
+      /* it is allowed for "normal" request, now do an extra check if this is
+         the result of a redirect */
+      if(data->state.this_is_a_follow &&
+         !(data->set.redir_protocols & p->protocol))
+        /* nope, get out */
+        break;
+
+      /* Perform setup complement if some. */
+      conn->handler = conn->given = p;
+
+      /* 'port' and 'remote_port' are set in setup_connection_internals() */
+      return CURLE_OK;
+    }
+  }
+
+
+  /* The protocol was not found in the table, but we don't have to assign it
+     to anything since it is already assigned to a dummy-struct in the
+     create_conn() function when the connectdata struct is allocated. */
+  failf(data, "Protocol \"%s\" not supported or disabled in " LIBCURL_NAME,
+        protostr);
+
+  return CURLE_UNSUPPORTED_PROTOCOL;
+}
+
+/*
+ * Parse URL and fill in the relevant members of the connection struct.
+ */
+static CURLcode parseurlandfillconn(struct Curl_easy *data,
+                                    struct connectdata *conn,
+                                    bool *prot_missing,
+                                    char **userp, char **passwdp,
+                                    char **optionsp)
+{
+  char *at;
+  char *fragment;
+  char *path = data->state.path;
+  char *query;
+  int i;
+  int rc;
+  const char *protop = "";
+  CURLcode result;
+  bool rebuild_url = FALSE;
+  bool url_has_scheme = FALSE;
+  char protobuf[16];
+
+  *prot_missing = FALSE;
+
+  /* We might pass the entire URL into the request so we need to make sure
+   * there are no bad characters in there.*/
+  if(strpbrk(data->change.url, "\r\n")) {
+    failf(data, "Illegal characters found in URL");
+    return CURLE_URL_MALFORMAT;
+  }
+
+  /*************************************************************
+   * Parse the URL.
+   *
+   * We need to parse the url even when using the proxy, because we will need
+   * the hostname and port in case we are trying to SSL connect through the
+   * proxy -- and we don't know if we will need to use SSL until we parse the
+   * url ...
+   ************************************************************/
+  if(data->change.url[0] == ':') {
+    failf(data, "Bad URL, colon is first character");
+    return CURLE_URL_MALFORMAT;
+  }
+
+  /* MSDOS/Windows style drive prefix, eg c: in c:foo */
+#define STARTS_WITH_DRIVE_PREFIX(str) \
+  ((('a' <= str[0] && str[0] <= 'z') || \
+    ('A' <= str[0] && str[0] <= 'Z')) && \
+   (str[1] == ':'))
+
+  /* MSDOS/Windows style drive prefix, optionally with
+   * a '|' instead of ':', followed by a slash or NUL */
+#define STARTS_WITH_URL_DRIVE_PREFIX(str) \
+  ((('a' <= (str)[0] && (str)[0] <= 'z') || \
+    ('A' <= (str)[0] && (str)[0] <= 'Z')) && \
+   ((str)[1] == ':' || (str)[1] == '|') && \
+   ((str)[2] == '/' || (str)[2] == 0))
+
+  /* Don't mistake a drive letter for a scheme if the default protocol is file.
+     curld --proto-default file c:/foo/bar.txt */
+  if(STARTS_WITH_DRIVE_PREFIX(data->change.url) &&
+     data->set.str[STRING_DEFAULT_PROTOCOL] &&
+     strcasecompare(data->set.str[STRING_DEFAULT_PROTOCOL], "file")) {
+    ; /* do nothing */
+  }
+  else { /* check for a scheme */
+    for(i = 0; i < 16 && data->change.url[i]; ++i) {
+      if(data->change.url[i] == '/')
+        break;
+      if(data->change.url[i] == ':') {
+        url_has_scheme = TRUE;
+        break;
+      }
+    }
+  }
+
+  /* handle the file: scheme */
+  if((url_has_scheme && strncasecompare(data->change.url, "file:", 5)) ||
+     (!url_has_scheme && data->set.str[STRING_DEFAULT_PROTOCOL] &&
+      strcasecompare(data->set.str[STRING_DEFAULT_PROTOCOL], "file"))) {
+    if(url_has_scheme)
+      rc = sscanf(data->change.url, "%*15[^\n/:]:%[^\n]", path);
+    else
+      rc = sscanf(data->change.url, "%[^\n]", path);
+
+    if(rc != 1) {
+      failf(data, "Bad URL");
+      return CURLE_URL_MALFORMAT;
+    }
+
+    if(url_has_scheme && path[0] == '/' && path[1] == '/' &&
+       path[2] == '/' && path[3] == '/') {
+      /* This appears to be a UNC string (usually indicating a SMB share).
+       * We don't do SMB in file: URLs. (TODO?)
+       */
+      failf(data, "SMB shares are not supported in file: URLs.");
+      return CURLE_URL_MALFORMAT;
+    }
+
+    /* Extra handling URLs with an authority component (i.e. that start with
+     * "file://")
+     *
+     * We allow omitted hostname (e.g. file:/<path>) -- valid according to
+     * RFC 8089, but not the (current) WHAT-WG URL spec.
+     */
+    if(url_has_scheme && path[0] == '/' && path[1] == '/') {
+      /* swallow the two slashes */
+      char *ptr = &path[2];
+
+      /*
+       * According to RFC 8089, a file: URL can be reliably dereferenced if:
+       *
+       *  o it has no/blank hostname, or
+       *
+       *  o the hostname matches "localhost" (case-insensitively), or
+       *
+       *  o the hostname is a FQDN that resolves to this machine.
+       *
+       * For brevity, we only consider URLs with empty, "localhost", or
+       * "127.0.0.1" hostnames as local.
+       *
+       * Additionally, there is an exception for URLs with a Windows drive
+       * letter in the authority (which was accidentally omitted from RFC 8089
+       * Appendix E, but believe me, it was meant to be there. --MK)
+       */
+      if(ptr[0] != '/' && !STARTS_WITH_URL_DRIVE_PREFIX(ptr)) {
+        /* the URL includes a host name, it must match "localhost" or
+           "127.0.0.1" to be valid */
+        if(!checkprefix("localhost/", ptr) &&
+           !checkprefix("127.0.0.1/", ptr)) {
+          failf(data, "Invalid file://hostname/, "
+                      "expected localhost or 127.0.0.1 or none");
+          return CURLE_URL_MALFORMAT;
+        }
+        ptr += 9; /* now points to the slash after the host */
+      }
+
+      /*
+       * RFC 8089, Appendix D, Section D.1, says:
+       *
+       * > In a POSIX file system, the root of the file system is represented
+       * > as a directory with a zero-length name, usually written as "/"; the
+       * > presence of this root in a file URI can be taken as given by the
+       * > initial slash in the "path-absolute" rule.
+       *
+       * i.e. the first slash is part of the path.
+       *
+       * However in RFC 1738 the "/" between the host (or port) and the
+       * URL-path was NOT part of the URL-path.  Any agent that followed the
+       * older spec strictly, and wanted to refer to a file with an absolute
+       * path, would have included a second slash.  So if there are two
+       * slashes, swallow one.
+       */
+      if('/' == ptr[1]) /* note: the only way ptr[0]!='/' is if ptr[1]==':' */
+        ptr++;
+
+      /* This cannot be done with strcpy, as the memory chunks overlap! */
+      memmove(path, ptr, strlen(ptr) + 1);
+    }
+
+#if !defined(MSDOS) && !defined(WIN32) && !defined(__CYGWIN__)
+    /* Don't allow Windows drive letters when not in Windows.
+     * This catches both "file:/c:" and "file:c:" */
+    if(('/' == path[0] && STARTS_WITH_URL_DRIVE_PREFIX(&path[1])) ||
+       STARTS_WITH_URL_DRIVE_PREFIX(path)) {
+      failf(data, "File drive letters are only accepted in MSDOS/Windows.");
+      return CURLE_URL_MALFORMAT;
+    }
+#else
+    /* If the path starts with a slash and a drive letter, ditch the slash */
+    if('/' == path[0] && STARTS_WITH_URL_DRIVE_PREFIX(&path[1])) {
+      /* This cannot be done with strcpy, as the memory chunks overlap! */
+      memmove(path, &path[1], strlen(&path[1]) + 1);
+    }
+#endif
+
+    protop = "file"; /* protocol string */
+    *prot_missing = !url_has_scheme;
+  }
+  else {
+    /* clear path */
+    char slashbuf[4];
+    path[0] = 0;
+
+    rc = sscanf(data->change.url,
+                "%15[^\n/:]:%3[/]%[^\n/?#]%[^\n]",
+                protobuf, slashbuf, conn->host.name, path);
+    if(2 == rc) {
+      failf(data, "Bad URL");
+      return CURLE_URL_MALFORMAT;
+    }
+    if(3 > rc) {
+
+      /*
+       * The URL was badly formatted, let's try the browser-style _without_
+       * protocol specified like 'http://'.
+       */
+      rc = sscanf(data->change.url, "%[^\n/?#]%[^\n]", conn->host.name, path);
+      if(1 > rc) {
+        /*
+         * We couldn't even get this format.
+         * djgpp 2.04 has a sscanf() bug where 'conn->host.name' is
+         * assigned, but the return value is EOF!
+         */
+#if defined(__DJGPP__) && (DJGPP_MINOR == 4)
+        if(!(rc == -1 && *conn->host.name))
+#endif
+        {
+          failf(data, "<url> malformed");
+          return CURLE_URL_MALFORMAT;
+        }
+      }
+
+      /*
+       * Since there was no protocol part specified in the URL use the
+       * user-specified default protocol. If we weren't given a default make a
+       * guess by matching some protocols against the host's outermost
+       * sub-domain name. Finally if there was no match use HTTP.
+       */
+
+      protop = data->set.str[STRING_DEFAULT_PROTOCOL];
+      if(!protop) {
+        /* Note: if you add a new protocol, please update the list in
+         * lib/version.c too! */
+        if(checkprefix("FTP.", conn->host.name))
+          protop = "ftp";
+        else if(checkprefix("DICT.", conn->host.name))
+          protop = "DICT";
+        else if(checkprefix("LDAP.", conn->host.name))
+          protop = "LDAP";
+        else if(checkprefix("IMAP.", conn->host.name))
+          protop = "IMAP";
+        else if(checkprefix("SMTP.", conn->host.name))
+          protop = "smtp";
+        else if(checkprefix("POP3.", conn->host.name))
+          protop = "pop3";
+        else
+          protop = "http";
+      }
+
+      *prot_missing = TRUE; /* not given in URL */
+    }
+    else {
+      size_t s = strlen(slashbuf);
+      protop = protobuf;
+      if(s != 2) {
+        infof(data, "Unwillingly accepted illegal URL using %d slash%s!\n",
+              s, s>1?"es":"");
+
+        if(data->change.url_alloc)
+          free(data->change.url);
+        /* repair the URL to use two slashes */
+        data->change.url = aprintf("%s://%s%s",
+                                   protobuf, conn->host.name, path);
+        if(!data->change.url)
+          return CURLE_OUT_OF_MEMORY;
+        data->change.url_alloc = TRUE;
+      }
+    }
+  }
+
+  /* We search for '?' in the host name (but only on the right side of a
+   * @-letter to allow ?-letters in username and password) to handle things
+   * like http://example.com?param= (notice the missing '/').
+   */
+  at = strchr(conn->host.name, '@');
+  if(at)
+    query = strchr(at + 1, '?');
+  else
+    query = strchr(conn->host.name, '?');
+
+  if(query) {
+    /* We must insert a slash before the '?'-letter in the URL. If the URL had
+       a slash after the '?', that is where the path currently begins and the
+       '?string' is still part of the host name.
+
+       We must move the trailing part from the host name and put it first in
+       the path. And have it all prefixed with a slash.
+    */
+
+    size_t hostlen = strlen(query);
+    size_t pathlen = strlen(path);
+
+    /* move the existing path plus the zero byte forward, to make room for
+       the host-name part */
+    memmove(path + hostlen + 1, path, pathlen + 1);
+
+     /* now copy the trailing host part in front of the existing path */
+    memcpy(path + 1, query, hostlen);
+
+    path[0]='/'; /* prepend the missing slash */
+    rebuild_url = TRUE;
+
+    *query = 0; /* now cut off the hostname at the ? */
+  }
+  else if(!path[0]) {
+    /* if there's no path set, use a single slash */
+    strcpy(path, "/");
+    rebuild_url = TRUE;
+  }
+
+  /* If the URL is malformatted (missing a '/' after hostname before path) we
+   * insert a slash here. The only letters except '/' that can start a path is
+   * '?' and '#' - as controlled by the two sscanf() patterns above.
+   */
+  if(path[0] != '/') {
+    /* We need this function to deal with overlapping memory areas. We know
+       that the memory area 'path' points to is 'urllen' bytes big and that
+       is bigger than the path. Use +1 to move the zero byte too. */
+    memmove(&path[1], path, strlen(path) + 1);
+    path[0] = '/';
+    rebuild_url = TRUE;
+  }
+  else if(!data->set.path_as_is) {
+    /* sanitise paths and remove ../ and ./ sequences according to RFC3986 */
+    char *newp = Curl_dedotdotify(path);
+    if(!newp)
+      return CURLE_OUT_OF_MEMORY;
+
+    if(strcmp(newp, path)) {
+      rebuild_url = TRUE;
+      free(data->state.pathbuffer);
+      data->state.pathbuffer = newp;
+      data->state.path = newp;
+      path = newp;
+    }
+    else
+      free(newp);
+  }
+
+  /*
+   * "rebuild_url" means that one or more URL components have been modified so
+   * we need to generate an updated full version.  We need the corrected URL
+   * when communicating over HTTP proxy and we don't know at this point if
+   * we're using a proxy or not.
+   */
+  if(rebuild_url) {
+    char *reurl;
+
+    size_t plen = strlen(path); /* new path, should be 1 byte longer than
+                                   the original */
+    size_t prefixlen = strlen(conn->host.name);
+
+    if(!*prot_missing) {
+      size_t protolen = strlen(protop);
+
+      if(curl_strnequal(protop, data->change.url, protolen))
+        prefixlen += protolen;
+      else {
+        failf(data, "<url> malformed");
+        return CURLE_URL_MALFORMAT;
+      }
+
+      if(curl_strnequal("://", &data->change.url[protolen], 3))
+        prefixlen += 3;
+      /* only file: is allowed to omit one or both slashes */
+      else if(curl_strnequal("file:", data->change.url, 5))
+        prefixlen += 1 + (data->change.url[5] == '/');
+      else {
+        failf(data, "<url> malformed");
+        return CURLE_URL_MALFORMAT;
+      }
+    }
+
+    reurl = malloc(prefixlen + plen + 1);
+    if(!reurl)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* copy the prefix */
+    memcpy(reurl, data->change.url, prefixlen);
+
+    /* append the trailing piece + zerobyte */
+    memcpy(&reurl[prefixlen], path, plen + 1);
+
+    /* possible free the old one */
+    if(data->change.url_alloc) {
+      Curl_safefree(data->change.url);
+      data->change.url_alloc = FALSE;
+    }
+
+    infof(data, "Rebuilt URL to: %s\n", reurl);
+
+    data->change.url = reurl;
+    data->change.url_alloc = TRUE; /* free this later */
+  }
+
+  result = findprotocol(data, conn, protop);
+  if(result)
+    return result;
+
+  /*
+   * Parse the login details from the URL and strip them out of
+   * the host name
+   */
+  result = parse_url_login(data, conn, userp, passwdp, optionsp);
+  if(result)
+    return result;
+
+  if(conn->host.name[0] == '[') {
+    /* This looks like an IPv6 address literal.  See if there is an address
+       scope if there is no location header */
+    char *percent = strchr(conn->host.name, '%');
+    if(percent) {
+      unsigned int identifier_offset = 3;
+      char *endp;
+      unsigned long scope;
+      if(strncmp("%25", percent, 3) != 0) {
+        infof(data,
+              "Please URL encode %% as %%25, see RFC 6874.\n");
+        identifier_offset = 1;
+      }
+      scope = strtoul(percent + identifier_offset, &endp, 10);
+      if(*endp == ']') {
+        /* The address scope was well formed.  Knock it out of the
+           hostname. */
+        memmove(percent, endp, strlen(endp) + 1);
+        conn->scope_id = (unsigned int)scope;
+      }
+      else {
+        /* Zone identifier is not numeric */
+#if defined(HAVE_NET_IF_H) && defined(IFNAMSIZ) && defined(HAVE_IF_NAMETOINDEX)
+        char ifname[IFNAMSIZ + 2];
+        char *square_bracket;
+        unsigned int scopeidx = 0;
+        strncpy(ifname, percent + identifier_offset, IFNAMSIZ + 2);
+        /* Ensure nullbyte termination */
+        ifname[IFNAMSIZ + 1] = '\0';
+        square_bracket = strchr(ifname, ']');
+        if(square_bracket) {
+          /* Remove ']' */
+          *square_bracket = '\0';
+          scopeidx = if_nametoindex(ifname);
+          if(scopeidx == 0) {
+            infof(data, "Invalid network interface: %s; %s\n", ifname,
+                  strerror(errno));
+          }
+        }
+        if(scopeidx > 0) {
+          char *p = percent + identifier_offset + strlen(ifname);
+
+          /* Remove zone identifier from hostname */
+          memmove(percent, p, strlen(p) + 1);
+          conn->scope_id = scopeidx;
+        }
+        else
+#endif /* HAVE_NET_IF_H && IFNAMSIZ */
+          infof(data, "Invalid IPv6 address format\n");
+      }
+    }
+  }
+
+  if(data->set.scope_id)
+    /* Override any scope that was set above.  */
+    conn->scope_id = data->set.scope_id;
+
+  /* Remove the fragment part of the path. Per RFC 2396, this is always the
+     last part of the URI. We are looking for the first '#' so that we deal
+     gracefully with non conformant URI such as http://example.com#foo#bar. */
+  fragment = strchr(path, '#');
+  if(fragment) {
+    *fragment = 0;
+
+    /* we know the path part ended with a fragment, so we know the full URL
+       string does too and we need to cut it off from there so it isn't used
+       over proxy */
+    fragment = strchr(data->change.url, '#');
+    if(fragment)
+      *fragment = 0;
+  }
+
+  /*
+   * So if the URL was A://B/C#D,
+   *   protop is A
+   *   conn->host.name is B
+   *   data->state.path is /C
+   */
+  return CURLE_OK;
+}
+
+/*
+ * If we're doing a resumed transfer, we need to setup our stuff
+ * properly.
+ */
+static CURLcode setup_range(struct Curl_easy *data)
+{
+  struct UrlState *s = &data->state;
+  s->resume_from = data->set.set_resume_from;
+  if(s->resume_from || data->set.str[STRING_SET_RANGE]) {
+    if(s->rangestringalloc)
+      free(s->range);
+
+    if(s->resume_from)
+      s->range = aprintf("%" CURL_FORMAT_CURL_OFF_TU "-", s->resume_from);
+    else
+      s->range = strdup(data->set.str[STRING_SET_RANGE]);
+
+    s->rangestringalloc = (s->range) ? TRUE : FALSE;
+
+    if(!s->range)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* tell ourselves to fetch this range */
+    s->use_range = TRUE;        /* enable range download */
+  }
+  else
+    s->use_range = FALSE; /* disable range download */
+
+  return CURLE_OK;
+}
+
+
+/*
+ * setup_connection_internals() -
+ *
+ * Setup connection internals specific to the requested protocol in the
+ * Curl_easy. This is inited and setup before the connection is made but
+ * is about the particular protocol that is to be used.
+ *
+ * This MUST get called after proxy magic has been figured out.
+ */
+static CURLcode setup_connection_internals(struct connectdata *conn)
+{
+  const struct Curl_handler * p;
+  CURLcode result;
+  struct Curl_easy *data = conn->data;
+
+  /* in some case in the multi state-machine, we go back to the CONNECT state
+     and then a second (or third or...) call to this function will be made
+     without doing a DISCONNECT or DONE in between (since the connection is
+     yet in place) and therefore this function needs to first make sure
+     there's no lingering previous data allocated. */
+  Curl_free_request_state(data);
+
+  memset(&data->req, 0, sizeof(struct SingleRequest));
+  data->req.maxdownload = -1;
+
+  conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
+
+  /* Perform setup complement if some. */
+  p = conn->handler;
+
+  if(p->setup_connection) {
+    result = (*p->setup_connection)(conn);
+
+    if(result)
+      return result;
+
+    p = conn->handler;              /* May have changed. */
+  }
+
+  if(conn->port < 0)
+    /* we check for -1 here since if proxy was detected already, this
+       was very likely already set to the proxy port */
+    conn->port = p->defport;
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_free_request_state() should free temp data that was allocated in the
+ * Curl_easy for this single request.
+ */
+
+void Curl_free_request_state(struct Curl_easy *data)
+{
+  Curl_safefree(data->req.protop);
+  Curl_safefree(data->req.newurl);
+}
+
+
+#ifndef CURL_DISABLE_PROXY
+/****************************************************************
+* Checks if the host is in the noproxy list. returns true if it matches
+* and therefore the proxy should NOT be used.
+****************************************************************/
+static bool check_noproxy(const char *name, const char *no_proxy)
+{
+  /* no_proxy=domain1.dom,host.domain2.dom
+   *   (a comma-separated list of hosts which should
+   *   not be proxied, or an asterisk to override
+   *   all proxy variables)
+   */
+  size_t tok_start;
+  size_t tok_end;
+  const char *separator = ", ";
+  size_t no_proxy_len;
+  size_t namelen;
+  char *endptr;
+
+  if(no_proxy && no_proxy[0]) {
+    if(strcasecompare("*", no_proxy)) {
+      return TRUE;
+    }
+
+    /* NO_PROXY was specified and it wasn't just an asterisk */
+
+    no_proxy_len = strlen(no_proxy);
+    endptr = strchr(name, ':');
+    if(endptr)
+      namelen = endptr - name;
+    else
+      namelen = strlen(name);
+
+    for(tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) {
+      while(tok_start < no_proxy_len &&
+            strchr(separator, no_proxy[tok_start]) != NULL) {
+        /* Look for the beginning of the token. */
+        ++tok_start;
+      }
+
+      if(tok_start == no_proxy_len)
+        break; /* It was all trailing separator chars, no more tokens. */
+
+      for(tok_end = tok_start; tok_end < no_proxy_len &&
+            strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end)
+        /* Look for the end of the token. */
+        ;
+
+      /* To match previous behaviour, where it was necessary to specify
+       * ".local.com" to prevent matching "notlocal.com", we will leave
+       * the '.' off.
+       */
+      if(no_proxy[tok_start] == '.')
+        ++tok_start;
+
+      if((tok_end - tok_start) <= namelen) {
+        /* Match the last part of the name to the domain we are checking. */
+        const char *checkn = name + namelen - (tok_end - tok_start);
+        if(strncasecompare(no_proxy + tok_start, checkn,
+                           tok_end - tok_start)) {
+          if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') {
+            /* We either have an exact match, or the previous character is a .
+             * so it is within the same domain, so no proxy for this host.
+             */
+            return TRUE;
+          }
+        }
+      } /* if((tok_end - tok_start) <= namelen) */
+    } /* for(tok_start = 0; tok_start < no_proxy_len;
+         tok_start = tok_end + 1) */
+  } /* NO_PROXY was specified and it wasn't just an asterisk */
+
+  return FALSE;
+}
+
+#ifndef CURL_DISABLE_HTTP
+/****************************************************************
+* Detect what (if any) proxy to use. Remember that this selects a host
+* name and is not limited to HTTP proxies only.
+* The returned pointer must be freed by the caller (unless NULL)
+****************************************************************/
+static char *detect_proxy(struct connectdata *conn)
+{
+  char *proxy = NULL;
+
+  /* If proxy was not specified, we check for default proxy environment
+   * variables, to enable i.e Lynx compliance:
+   *
+   * http_proxy=http://some.server.dom:port/
+   * https_proxy=http://some.server.dom:port/
+   * ftp_proxy=http://some.server.dom:port/
+   * no_proxy=domain1.dom,host.domain2.dom
+   *   (a comma-separated list of hosts which should
+   *   not be proxied, or an asterisk to override
+   *   all proxy variables)
+   * all_proxy=http://some.server.dom:port/
+   *   (seems to exist for the CERN www lib. Probably
+   *   the first to check for.)
+   *
+   * For compatibility, the all-uppercase versions of these variables are
+   * checked if the lowercase versions don't exist.
+   */
+  char proxy_env[128];
+  const char *protop = conn->handler->scheme;
+  char *envp = proxy_env;
+  char *prox;
+
+  /* Now, build <protocol>_proxy and check for such a one to use */
+  while(*protop)
+    *envp++ = (char)tolower((int)*protop++);
+
+  /* append _proxy */
+  strcpy(envp, "_proxy");
+
+  /* read the protocol proxy: */
+  prox = curl_getenv(proxy_env);
+
+  /*
+   * We don't try the uppercase version of HTTP_PROXY because of
+   * security reasons:
+   *
+   * When curl is used in a webserver application
+   * environment (cgi or php), this environment variable can
+   * be controlled by the web server user by setting the
+   * http header 'Proxy:' to some value.
+   *
+   * This can cause 'internal' http/ftp requests to be
+   * arbitrarily redirected by any external attacker.
+   */
+  if(!prox && !strcasecompare("http_proxy", proxy_env)) {
+    /* There was no lowercase variable, try the uppercase version: */
+    Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
+    prox = curl_getenv(proxy_env);
+  }
+
+  if(prox)
+    proxy = prox; /* use this */
+  else {
+    proxy = curl_getenv("all_proxy"); /* default proxy to use */
+    if(!proxy)
+      proxy = curl_getenv("ALL_PROXY");
+  }
+
+  return proxy;
+}
+#endif /* CURL_DISABLE_HTTP */
+
+/*
+ * If this is supposed to use a proxy, we need to figure out the proxy
+ * host name, so that we can re-use an existing connection
+ * that may exist registered to the same proxy host.
+ */
+static CURLcode parse_proxy(struct Curl_easy *data,
+                            struct connectdata *conn, char *proxy,
+                            curl_proxytype proxytype)
+{
+  char *prox_portno;
+  char *endofprot;
+
+  /* We use 'proxyptr' to point to the proxy name from now on... */
+  char *proxyptr;
+  char *portptr;
+  char *atsign;
+  long port = -1;
+  char *proxyuser = NULL;
+  char *proxypasswd = NULL;
+  bool sockstype;
+
+  /* We do the proxy host string parsing here. We want the host name and the
+   * port name. Accept a protocol:// prefix
+   */
+
+  /* Parse the protocol part if present */
+  endofprot = strstr(proxy, "://");
+  if(endofprot) {
+    proxyptr = endofprot + 3;
+    if(checkprefix("https", proxy))
+      proxytype = CURLPROXY_HTTPS;
+    else if(checkprefix("socks5h", proxy))
+      proxytype = CURLPROXY_SOCKS5_HOSTNAME;
+    else if(checkprefix("socks5", proxy))
+      proxytype = CURLPROXY_SOCKS5;
+    else if(checkprefix("socks4a", proxy))
+      proxytype = CURLPROXY_SOCKS4A;
+    else if(checkprefix("socks4", proxy) || checkprefix("socks", proxy))
+      proxytype = CURLPROXY_SOCKS4;
+    else if(checkprefix("http:", proxy))
+      ; /* leave it as HTTP or HTTP/1.0 */
+    else {
+      /* Any other xxx:// reject! */
+      failf(data, "Unsupported proxy scheme for \'%s\'", proxy);
+      return CURLE_COULDNT_CONNECT;
+    }
+  }
+  else
+    proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */
+
+#ifdef USE_SSL
+  if(!Curl_ssl->support_https_proxy)
+#endif
+    if(proxytype == CURLPROXY_HTTPS) {
+      failf(data, "Unsupported proxy \'%s\', libcurl is built without the "
+                  "HTTPS-proxy support.", proxy);
+      return CURLE_NOT_BUILT_IN;
+    }
+
+  sockstype = proxytype == CURLPROXY_SOCKS5_HOSTNAME ||
+              proxytype == CURLPROXY_SOCKS5 ||
+              proxytype == CURLPROXY_SOCKS4A ||
+              proxytype == CURLPROXY_SOCKS4;
+
+  /* Is there a username and password given in this proxy url? */
+  atsign = strchr(proxyptr, '@');
+  if(atsign) {
+    CURLcode result =
+      Curl_parse_login_details(proxyptr, atsign - proxyptr,
+                               &proxyuser, &proxypasswd, NULL);
+    if(result)
+      return result;
+    proxyptr = atsign + 1;
+  }
+
+  /* start scanning for port number at this point */
+  portptr = proxyptr;
+
+  /* detect and extract RFC6874-style IPv6-addresses */
+  if(*proxyptr == '[') {
+    char *ptr = ++proxyptr; /* advance beyond the initial bracket */
+    while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.')))
+      ptr++;
+    if(*ptr == '%') {
+      /* There might be a zone identifier */
+      if(strncmp("%25", ptr, 3))
+        infof(data, "Please URL encode %% as %%25, see RFC 6874.\n");
+      ptr++;
+      /* Allow unreserved characters as defined in RFC 3986 */
+      while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') ||
+                     (*ptr == '.') || (*ptr == '_') || (*ptr == '~')))
+        ptr++;
+    }
+    if(*ptr == ']')
+      /* yeps, it ended nicely with a bracket as well */
+      *ptr++ = 0;
+    else
+      infof(data, "Invalid IPv6 address format\n");
+    portptr = ptr;
+    /* Note that if this didn't end with a bracket, we still advanced the
+     * proxyptr first, but I can't see anything wrong with that as no host
+     * name nor a numeric can legally start with a bracket.
+     */
+  }
+
+  /* Get port number off proxy.server.com:1080 */
+  prox_portno = strchr(portptr, ':');
+  if(prox_portno) {
+    char *endp = NULL;
+
+    *prox_portno = 0x0; /* cut off number from host name */
+    prox_portno ++;
+    /* now set the local port number */
+    port = strtol(prox_portno, &endp, 10);
+    if((endp && *endp && (*endp != '/') && (*endp != ' ')) ||
+       (port < 0) || (port > 65535)) {
+      /* meant to detect for example invalid IPv6 numerical addresses without
+         brackets: "2a00:fac0:a000::7:13". Accept a trailing slash only
+         because we then allow "URL style" with the number followed by a
+         slash, used in curl test cases already. Space is also an acceptable
+         terminating symbol. */
+      infof(data, "No valid port number in proxy string (%s)\n",
+            prox_portno);
+    }
+    else
+      conn->port = port;
+  }
+  else {
+    if(proxyptr[0]=='/') {
+      /* If the first character in the proxy string is a slash, fail
+         immediately. The following code will otherwise clear the string which
+         will lead to code running as if no proxy was set! */
+      Curl_safefree(proxyuser);
+      Curl_safefree(proxypasswd);
+      return CURLE_COULDNT_RESOLVE_PROXY;
+    }
+
+    /* without a port number after the host name, some people seem to use
+       a slash so we strip everything from the first slash */
+    atsign = strchr(proxyptr, '/');
+    if(atsign)
+      *atsign = '\0'; /* cut off path part from host name */
+
+    if(data->set.proxyport)
+      /* None given in the proxy string, then get the default one if it is
+         given */
+      port = data->set.proxyport;
+    else {
+      if(proxytype == CURLPROXY_HTTPS)
+        port = CURL_DEFAULT_HTTPS_PROXY_PORT;
+      else
+        port = CURL_DEFAULT_PROXY_PORT;
+    }
+  }
+
+  if(*proxyptr) {
+    struct proxy_info *proxyinfo =
+      sockstype ? &conn->socks_proxy : &conn->http_proxy;
+    proxyinfo->proxytype = proxytype;
+
+    if(proxyuser) {
+      /* found user and password, rip them out.  note that we are unescaping
+         them, as there is otherwise no way to have a username or password
+         with reserved characters like ':' in them. */
+      Curl_safefree(proxyinfo->user);
+      proxyinfo->user = curl_easy_unescape(data, proxyuser, 0, NULL);
+      Curl_safefree(proxyuser);
+
+      if(!proxyinfo->user) {
+        Curl_safefree(proxypasswd);
+        return CURLE_OUT_OF_MEMORY;
+      }
+
+      Curl_safefree(proxyinfo->passwd);
+      if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH)
+        proxyinfo->passwd = curl_easy_unescape(data, proxypasswd, 0, NULL);
+      else
+        proxyinfo->passwd = strdup("");
+      Curl_safefree(proxypasswd);
+
+      if(!proxyinfo->passwd)
+        return CURLE_OUT_OF_MEMORY;
+
+      conn->bits.proxy_user_passwd = TRUE; /* enable it */
+    }
+
+    if(port >= 0) {
+      proxyinfo->port = port;
+      if(conn->port < 0 || sockstype || !conn->socks_proxy.host.rawalloc)
+        conn->port = port;
+    }
+
+    /* now, clone the cleaned proxy host name */
+    Curl_safefree(proxyinfo->host.rawalloc);
+    proxyinfo->host.rawalloc = strdup(proxyptr);
+    proxyinfo->host.name = proxyinfo->host.rawalloc;
+
+    if(!proxyinfo->host.rawalloc)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  Curl_safefree(proxyuser);
+  Curl_safefree(proxypasswd);
+
+  return CURLE_OK;
+}
+
+/*
+ * Extract the user and password from the authentication string
+ */
+static CURLcode parse_proxy_auth(struct Curl_easy *data,
+                                 struct connectdata *conn)
+{
+  char proxyuser[MAX_CURL_USER_LENGTH]="";
+  char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
+  CURLcode result;
+
+  if(data->set.str[STRING_PROXYUSERNAME] != NULL) {
+    strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME],
+            MAX_CURL_USER_LENGTH);
+    proxyuser[MAX_CURL_USER_LENGTH-1] = '\0';   /*To be on safe side*/
+  }
+  if(data->set.str[STRING_PROXYPASSWORD] != NULL) {
+    strncpy(proxypasswd, data->set.str[STRING_PROXYPASSWORD],
+            MAX_CURL_PASSWORD_LENGTH);
+    proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
+  }
+
+  result = Curl_urldecode(data, proxyuser, 0, &conn->http_proxy.user, NULL,
+                          FALSE);
+  if(!result)
+    result = Curl_urldecode(data, proxypasswd, 0, &conn->http_proxy.passwd,
+                            NULL, FALSE);
+  return result;
+}
+
+/* create_conn helper to parse and init proxy values. to be called after unix
+   socket init but before any proxy vars are evaluated. */
+static CURLcode create_conn_helper_init_proxy(struct connectdata *conn)
+{
+  char *proxy = NULL;
+  char *socksproxy = NULL;
+  char *no_proxy = NULL;
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  /*************************************************************
+   * Extract the user and password from the authentication string
+   *************************************************************/
+  if(conn->bits.proxy_user_passwd) {
+    result = parse_proxy_auth(data, conn);
+    if(result)
+      goto out;
+  }
+
+  /*************************************************************
+   * Detect what (if any) proxy to use
+   *************************************************************/
+  if(data->set.str[STRING_PROXY]) {
+    proxy = strdup(data->set.str[STRING_PROXY]);
+    /* if global proxy is set, this is it */
+    if(NULL == proxy) {
+      failf(data, "memory shortage");
+      result = CURLE_OUT_OF_MEMORY;
+      goto out;
+    }
+  }
+
+  if(data->set.str[STRING_PRE_PROXY]) {
+    socksproxy = strdup(data->set.str[STRING_PRE_PROXY]);
+    /* if global socks proxy is set, this is it */
+    if(NULL == socksproxy) {
+      failf(data, "memory shortage");
+      result = CURLE_OUT_OF_MEMORY;
+      goto out;
+    }
+  }
+
+  if(!data->set.str[STRING_NOPROXY]) {
+    no_proxy = curl_getenv("no_proxy");
+    if(!no_proxy)
+      no_proxy = curl_getenv("NO_PROXY");
+  }
+
+  if(check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY] ?
+      data->set.str[STRING_NOPROXY] : no_proxy)) {
+    Curl_safefree(proxy);
+    Curl_safefree(socksproxy);
+  }
+#ifndef CURL_DISABLE_HTTP
+  else if(!proxy && !socksproxy)
+    /* if the host is not in the noproxy list, detect proxy. */
+    proxy = detect_proxy(conn);
+#endif /* CURL_DISABLE_HTTP */
+
+  Curl_safefree(no_proxy);
+
+#ifdef USE_UNIX_SOCKETS
+  /* For the time being do not mix proxy and unix domain sockets. See #1274 */
+  if(proxy && conn->unix_domain_socket) {
+    free(proxy);
+    proxy = NULL;
+  }
+#endif
+
+  if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) {
+    free(proxy);  /* Don't bother with an empty proxy string or if the
+                     protocol doesn't work with network */
+    proxy = NULL;
+  }
+  if(socksproxy && (!*socksproxy ||
+                    (conn->handler->flags & PROTOPT_NONETWORK))) {
+    free(socksproxy);  /* Don't bother with an empty socks proxy string or if
+                          the protocol doesn't work with network */
+    socksproxy = NULL;
+  }
+
+  /***********************************************************************
+   * If this is supposed to use a proxy, we need to figure out the proxy host
+   * name, proxy type and port number, so that we can re-use an existing
+   * connection that may exist registered to the same proxy host.
+   ***********************************************************************/
+  if(proxy || socksproxy) {
+    if(proxy) {
+      result = parse_proxy(data, conn, proxy, conn->http_proxy.proxytype);
+      Curl_safefree(proxy); /* parse_proxy copies the proxy string */
+      if(result)
+        goto out;
+    }
+
+    if(socksproxy) {
+      result = parse_proxy(data, conn, socksproxy,
+                           conn->socks_proxy.proxytype);
+      /* parse_proxy copies the socks proxy string */
+      Curl_safefree(socksproxy);
+      if(result)
+        goto out;
+    }
+
+    if(conn->http_proxy.host.rawalloc) {
+#ifdef CURL_DISABLE_HTTP
+      /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */
+      result = CURLE_UNSUPPORTED_PROTOCOL;
+      goto out;
+#else
+      /* force this connection's protocol to become HTTP if compatible */
+      if(!(conn->handler->protocol & PROTO_FAMILY_HTTP)) {
+        if((conn->handler->flags & PROTOPT_PROXY_AS_HTTP) &&
+           !conn->bits.tunnel_proxy)
+          conn->handler = &Curl_handler_http;
+        else
+          /* if not converting to HTTP over the proxy, enforce tunneling */
+          conn->bits.tunnel_proxy = TRUE;
+      }
+      conn->bits.httpproxy = TRUE;
+#endif
+    }
+    else {
+      conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
+      conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */
+    }
+
+    if(conn->socks_proxy.host.rawalloc) {
+      if(!conn->http_proxy.host.rawalloc) {
+        /* once a socks proxy */
+        if(!conn->socks_proxy.user) {
+          conn->socks_proxy.user = conn->http_proxy.user;
+          conn->http_proxy.user = NULL;
+          Curl_safefree(conn->socks_proxy.passwd);
+          conn->socks_proxy.passwd = conn->http_proxy.passwd;
+          conn->http_proxy.passwd = NULL;
+        }
+      }
+      conn->bits.socksproxy = TRUE;
+    }
+    else
+      conn->bits.socksproxy = FALSE; /* not a socks proxy */
+  }
+  else {
+    conn->bits.socksproxy = FALSE;
+    conn->bits.httpproxy = FALSE;
+  }
+  conn->bits.proxy = conn->bits.httpproxy || conn->bits.socksproxy;
+
+  if(!conn->bits.proxy) {
+    /* we aren't using the proxy after all... */
+    conn->bits.proxy = FALSE;
+    conn->bits.httpproxy = FALSE;
+    conn->bits.socksproxy = FALSE;
+    conn->bits.proxy_user_passwd = FALSE;
+    conn->bits.tunnel_proxy = FALSE;
+  }
+
+out:
+
+  free(socksproxy);
+  free(proxy);
+  return result;
+}
+#endif /* CURL_DISABLE_PROXY */
+
+/*
+ * parse_url_login()
+ *
+ * Parse the login details (user name, password and options) from the URL and
+ * strip them out of the host name
+ *
+ * Inputs: data->set.use_netrc (CURLOPT_NETRC)
+ *         conn->host.name
+ *
+ * Outputs: (almost :- all currently undefined)
+ *          conn->bits.user_passwd  - non-zero if non-default passwords exist
+ *          user                    - non-zero length if defined
+ *          passwd                  - non-zero length if defined
+ *          options                 - non-zero length if defined
+ *          conn->host.name         - remove user name and password
+ */
+static CURLcode parse_url_login(struct Curl_easy *data,
+                                struct connectdata *conn,
+                                char **user, char **passwd, char **options)
+{
+  CURLcode result = CURLE_OK;
+  char *userp = NULL;
+  char *passwdp = NULL;
+  char *optionsp = NULL;
+
+  /* At this point, we're hoping all the other special cases have
+   * been taken care of, so conn->host.name is at most
+   *    [user[:password][;options]]@]hostname
+   *
+   * We need somewhere to put the embedded details, so do that first.
+   */
+
+  char *ptr = strchr(conn->host.name, '@');
+  char *login = conn->host.name;
+
+  DEBUGASSERT(!**user);
+  DEBUGASSERT(!**passwd);
+  DEBUGASSERT(!**options);
+  DEBUGASSERT(conn->handler);
+
+  if(!ptr)
+    goto out;
+
+  /* We will now try to extract the
+   * possible login information in a string like:
+   * ftp://user:password@ftp.my.site:8021/README */
+  conn->host.name = ++ptr;
+
+  /* So the hostname is sane.  Only bother interpreting the
+   * results if we could care.  It could still be wasted
+   * work because it might be overtaken by the programmatically
+   * set user/passwd, but doing that first adds more cases here :-(
+   */
+
+  if(data->set.use_netrc == CURL_NETRC_REQUIRED)
+    goto out;
+
+  /* We could use the login information in the URL so extract it. Only parse
+     options if the handler says we should. */
+  result =
+    Curl_parse_login_details(login, ptr - login - 1,
+                             &userp, &passwdp,
+                             (conn->handler->flags & PROTOPT_URLOPTIONS)?
+                             &optionsp:NULL);
+  if(result)
+    goto out;
+
+  if(userp) {
+    char *newname;
+
+    /* We have a user in the URL */
+    conn->bits.userpwd_in_url = TRUE;
+    conn->bits.user_passwd = TRUE; /* enable user+password */
+
+    /* Decode the user */
+    result = Curl_urldecode(data, userp, 0, &newname, NULL, FALSE);
+    if(result) {
+      goto out;
+    }
+
+    free(*user);
+    *user = newname;
+  }
+
+  if(passwdp) {
+    /* We have a password in the URL so decode it */
+    char *newpasswd;
+    result = Curl_urldecode(data, passwdp, 0, &newpasswd, NULL, FALSE);
+    if(result) {
+      goto out;
+    }
+
+    free(*passwd);
+    *passwd = newpasswd;
+  }
+
+  if(optionsp) {
+    /* We have an options list in the URL so decode it */
+    char *newoptions;
+    result = Curl_urldecode(data, optionsp, 0, &newoptions, NULL, FALSE);
+    if(result) {
+      goto out;
+    }
+
+    free(*options);
+    *options = newoptions;
+  }
+
+
+  out:
+
+  free(userp);
+  free(passwdp);
+  free(optionsp);
+
+  return result;
+}
+
+/*
+ * Curl_parse_login_details()
+ *
+ * This is used to parse a login string for user name, password and options in
+ * the following formats:
+ *
+ *   user
+ *   user:password
+ *   user:password;options
+ *   user;options
+ *   user;options:password
+ *   :password
+ *   :password;options
+ *   ;options
+ *   ;options:password
+ *
+ * Parameters:
+ *
+ * login    [in]     - The login string.
+ * len      [in]     - The length of the login string.
+ * userp    [in/out] - The address where a pointer to newly allocated memory
+ *                     holding the user will be stored upon completion.
+ * passdwp  [in/out] - The address where a pointer to newly allocated memory
+ *                     holding the password will be stored upon completion.
+ * optionsp [in/out] - The address where a pointer to newly allocated memory
+ *                     holding the options will be stored upon completion.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_parse_login_details(const char *login, const size_t len,
+                                  char **userp, char **passwdp,
+                                  char **optionsp)
+{
+  CURLcode result = CURLE_OK;
+  char *ubuf = NULL;
+  char *pbuf = NULL;
+  char *obuf = NULL;
+  const char *psep = NULL;
+  const char *osep = NULL;
+  size_t ulen;
+  size_t plen;
+  size_t olen;
+
+  /* Attempt to find the password separator */
+  if(passwdp) {
+    psep = strchr(login, ':');
+
+    /* Within the constraint of the login string */
+    if(psep >= login + len)
+      psep = NULL;
+  }
+
+  /* Attempt to find the options separator */
+  if(optionsp) {
+    osep = strchr(login, ';');
+
+    /* Within the constraint of the login string */
+    if(osep >= login + len)
+      osep = NULL;
+  }
+
+  /* Calculate the portion lengths */
+  ulen = (psep ?
+          (size_t)(osep && psep > osep ? osep - login : psep - login) :
+          (osep ? (size_t)(osep - login) : len));
+  plen = (psep ?
+          (osep && osep > psep ? (size_t)(osep - psep) :
+                                 (size_t)(login + len - psep)) - 1 : 0);
+  olen = (osep ?
+          (psep && psep > osep ? (size_t)(psep - osep) :
+                                 (size_t)(login + len - osep)) - 1 : 0);
+
+  /* Allocate the user portion buffer */
+  if(userp && ulen) {
+    ubuf = malloc(ulen + 1);
+    if(!ubuf)
+      result = CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Allocate the password portion buffer */
+  if(!result && passwdp && plen) {
+    pbuf = malloc(plen + 1);
+    if(!pbuf) {
+      free(ubuf);
+      result = CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  /* Allocate the options portion buffer */
+  if(!result && optionsp && olen) {
+    obuf = malloc(olen + 1);
+    if(!obuf) {
+      free(pbuf);
+      free(ubuf);
+      result = CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  if(!result) {
+    /* Store the user portion if necessary */
+    if(ubuf) {
+      memcpy(ubuf, login, ulen);
+      ubuf[ulen] = '\0';
+      Curl_safefree(*userp);
+      *userp = ubuf;
+    }
+
+    /* Store the password portion if necessary */
+    if(pbuf) {
+      memcpy(pbuf, psep + 1, plen);
+      pbuf[plen] = '\0';
+      Curl_safefree(*passwdp);
+      *passwdp = pbuf;
+    }
+
+    /* Store the options portion if necessary */
+    if(obuf) {
+      memcpy(obuf, osep + 1, olen);
+      obuf[olen] = '\0';
+      Curl_safefree(*optionsp);
+      *optionsp = obuf;
+    }
+  }
+
+  return result;
+}
+
+/*************************************************************
+ * Figure out the remote port number and fix it in the URL
+ *
+ * No matter if we use a proxy or not, we have to figure out the remote
+ * port number of various reasons.
+ *
+ * To be able to detect port number flawlessly, we must not confuse them
+ * IPv6-specified addresses in the [0::1] style. (RFC2732)
+ *
+ * The conn->host.name is currently [user:passwd@]host[:port] where host
+ * could be a hostname, IPv4 address or IPv6 address.
+ *
+ * The port number embedded in the URL is replaced, if necessary.
+ *************************************************************/
+static CURLcode parse_remote_port(struct Curl_easy *data,
+                                  struct connectdata *conn)
+{
+  char *portptr;
+  char endbracket;
+
+  /* Note that at this point, the IPv6 address cannot contain any scope
+     suffix as that has already been removed in the parseurlandfillconn()
+     function */
+  if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.]%c",
+                  &endbracket)) &&
+     (']' == endbracket)) {
+    /* this is a RFC2732-style specified IP-address */
+    conn->bits.ipv6_ip = TRUE;
+
+    conn->host.name++; /* skip over the starting bracket */
+    portptr = strchr(conn->host.name, ']');
+    if(portptr) {
+      *portptr++ = '\0'; /* zero terminate, killing the bracket */
+      if(*portptr) {
+        if (*portptr != ':') {
+          failf(data, "IPv6 closing bracket followed by '%c'", *portptr);
+          return CURLE_URL_MALFORMAT;
+        }
+      }
+      else
+        portptr = NULL; /* no port number available */
+    }
+  }
+  else {
+#ifdef ENABLE_IPV6
+    struct in6_addr in6;
+    if(Curl_inet_pton(AF_INET6, conn->host.name, &in6) > 0) {
+      /* This is a numerical IPv6 address, meaning this is a wrongly formatted
+         URL */
+      failf(data, "IPv6 numerical address used in URL without brackets");
+      return CURLE_URL_MALFORMAT;
+    }
+#endif
+
+    portptr = strchr(conn->host.name, ':');
+  }
+
+  if(data->set.use_port && data->state.allow_port) {
+    /* if set, we use this and ignore the port possibly given in the URL */
+    conn->remote_port = (unsigned short)data->set.use_port;
+    if(portptr)
+      *portptr = '\0'; /* cut off the name there anyway - if there was a port
+                      number - since the port number is to be ignored! */
+    if(conn->bits.httpproxy) {
+      /* we need to create new URL with the new port number */
+      char *url;
+      char type[12]="";
+
+      if(conn->bits.type_set)
+        snprintf(type, sizeof(type), ";type=%c",
+                 data->set.prefer_ascii?'A':
+                 (data->set.ftp_list_only?'D':'I'));
+
+      /*
+       * This synthesized URL isn't always right--suffixes like ;type=A are
+       * stripped off. It would be better to work directly from the original
+       * URL and simply replace the port part of it.
+       */
+      url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->given->scheme,
+                    conn->bits.ipv6_ip?"[":"", conn->host.name,
+                    conn->bits.ipv6_ip?"]":"", conn->remote_port,
+                    data->state.slash_removed?"/":"", data->state.path,
+                    type);
+      if(!url)
+        return CURLE_OUT_OF_MEMORY;
+
+      if(data->change.url_alloc) {
+        Curl_safefree(data->change.url);
+        data->change.url_alloc = FALSE;
+      }
+
+      data->change.url = url;
+      data->change.url_alloc = TRUE;
+    }
+  }
+  else if(portptr) {
+    /* no CURLOPT_PORT given, extract the one from the URL */
+
+    char *rest;
+    long port;
+
+    port = strtol(portptr + 1, &rest, 10);  /* Port number must be decimal */
+
+    if((port < 0) || (port > 0xffff)) {
+      /* Single unix standard says port numbers are 16 bits long */
+      failf(data, "Port number out of range");
+      return CURLE_URL_MALFORMAT;
+    }
+
+    if(rest[0]) {
+      failf(data, "Port number ended with '%c'", rest[0]);
+      return CURLE_URL_MALFORMAT;
+    }
+
+    if(rest != &portptr[1]) {
+      *portptr = '\0'; /* cut off the name there */
+      conn->remote_port = curlx_ultous(port);
+    }
+    else {
+      /* Browser behavior adaptation. If there's a colon with no digits after,
+         just cut off the name there which makes us ignore the colon and just
+         use the default port. Firefox and Chrome both do that. */
+      *portptr = '\0';
+    }
+  }
+
+  /* only if remote_port was not already parsed off the URL we use the
+     default port number */
+  if(conn->remote_port < 0)
+    conn->remote_port = (unsigned short)conn->given->defport;
+
+  return CURLE_OK;
+}
+
+/*
+ * Override the login details from the URL with that in the CURLOPT_USERPWD
+ * option or a .netrc file, if applicable.
+ */
+static CURLcode override_login(struct Curl_easy *data,
+                               struct connectdata *conn,
+                               char **userp, char **passwdp, char **optionsp)
+{
+  if(data->set.str[STRING_USERNAME]) {
+    free(*userp);
+    *userp = strdup(data->set.str[STRING_USERNAME]);
+    if(!*userp)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  if(data->set.str[STRING_PASSWORD]) {
+    free(*passwdp);
+    *passwdp = strdup(data->set.str[STRING_PASSWORD]);
+    if(!*passwdp)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  if(data->set.str[STRING_OPTIONS]) {
+    free(*optionsp);
+    *optionsp = strdup(data->set.str[STRING_OPTIONS]);
+    if(!*optionsp)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  conn->bits.netrc = FALSE;
+  if(data->set.use_netrc != CURL_NETRC_IGNORED) {
+    int ret = Curl_parsenetrc(conn->host.name,
+                              userp, passwdp,
+                              data->set.str[STRING_NETRC_FILE]);
+    if(ret > 0) {
+      infof(data, "Couldn't find host %s in the "
+            DOT_CHAR "netrc file; using defaults\n",
+            conn->host.name);
+    }
+    else if(ret < 0) {
+      return CURLE_OUT_OF_MEMORY;
+    }
+    else {
+      /* set bits.netrc TRUE to remember that we got the name from a .netrc
+         file, so that it is safe to use even if we followed a Location: to a
+         different host or similar. */
+      conn->bits.netrc = TRUE;
+
+      conn->bits.user_passwd = TRUE; /* enable user+password */
+    }
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Set the login details so they're available in the connection
+ */
+static CURLcode set_login(struct connectdata *conn,
+                          const char *user, const char *passwd,
+                          const char *options)
+{
+  CURLcode result = CURLE_OK;
+
+  /* If our protocol needs a password and we have none, use the defaults */
+  if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) {
+    /* Store the default user */
+    conn->user = strdup(CURL_DEFAULT_USER);
+
+    /* Store the default password */
+    if(conn->user)
+      conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
+    else
+      conn->passwd = NULL;
+
+    /* This is the default password, so DON'T set conn->bits.user_passwd */
+  }
+  else {
+    /* Store the user, zero-length if not set */
+    conn->user = strdup(user);
+
+    /* Store the password (only if user is present), zero-length if not set */
+    if(conn->user)
+      conn->passwd = strdup(passwd);
+    else
+      conn->passwd = NULL;
+  }
+
+  if(!conn->user || !conn->passwd)
+    result = CURLE_OUT_OF_MEMORY;
+
+  /* Store the options, null if not set */
+  if(!result && options[0]) {
+    conn->options = strdup(options);
+
+    if(!conn->options)
+      result = CURLE_OUT_OF_MEMORY;
+  }
+
+  return result;
+}
+
+/*
+ * Parses a "host:port" string to connect to.
+ * The hostname and the port may be empty; in this case, NULL is returned for
+ * the hostname and -1 for the port.
+ */
+static CURLcode parse_connect_to_host_port(struct Curl_easy *data,
+                                           const char *host,
+                                           char **hostname_result,
+                                           int *port_result)
+{
+  char *host_dup;
+  char *hostptr;
+  char *host_portno;
+  char *portptr;
+  int port = -1;
+
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void) data;
+#endif
+
+  *hostname_result = NULL;
+  *port_result = -1;
+
+  if(!host || !*host)
+    return CURLE_OK;
+
+  host_dup = strdup(host);
+  if(!host_dup)
+    return CURLE_OUT_OF_MEMORY;
+
+  hostptr = host_dup;
+
+  /* start scanning for port number at this point */
+  portptr = hostptr;
+
+  /* detect and extract RFC6874-style IPv6-addresses */
+  if(*hostptr == '[') {
+    char *ptr = ++hostptr; /* advance beyond the initial bracket */
+    while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.')))
+      ptr++;
+    if(*ptr == '%') {
+      /* There might be a zone identifier */
+      if(strncmp("%25", ptr, 3))
+        infof(data, "Please URL encode %% as %%25, see RFC 6874.\n");
+      ptr++;
+      /* Allow unreserved characters as defined in RFC 3986 */
+      while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') ||
+                     (*ptr == '.') || (*ptr == '_') || (*ptr == '~')))
+        ptr++;
+    }
+    if(*ptr == ']')
+      /* yeps, it ended nicely with a bracket as well */
+      *ptr++ = '\0';
+    else
+      infof(data, "Invalid IPv6 address format\n");
+    portptr = ptr;
+    /* Note that if this didn't end with a bracket, we still advanced the
+     * hostptr first, but I can't see anything wrong with that as no host
+     * name nor a numeric can legally start with a bracket.
+     */
+  }
+
+  /* Get port number off server.com:1080 */
+  host_portno = strchr(portptr, ':');
+  if(host_portno) {
+    char *endp = NULL;
+    *host_portno = '\0'; /* cut off number from host name */
+    host_portno++;
+    if(*host_portno) {
+      long portparse = strtol(host_portno, &endp, 10);
+      if((endp && *endp) || (portparse < 0) || (portparse > 65535)) {
+        infof(data, "No valid port number in connect to host string (%s)\n",
+              host_portno);
+        hostptr = NULL;
+        port = -1;
+      }
+      else
+        port = (int)portparse; /* we know it will fit */
+    }
+  }
+
+  /* now, clone the cleaned host name */
+  if(hostptr) {
+    *hostname_result = strdup(hostptr);
+    if(!*hostname_result) {
+      free(host_dup);
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  *port_result = port;
+
+  free(host_dup);
+  return CURLE_OK;
+}
+
+/*
+ * Parses one "connect to" string in the form:
+ * "HOST:PORT:CONNECT-TO-HOST:CONNECT-TO-PORT".
+ */
+static CURLcode parse_connect_to_string(struct Curl_easy *data,
+                                        struct connectdata *conn,
+                                        const char *conn_to_host,
+                                        char **host_result,
+                                        int *port_result)
+{
+  CURLcode result = CURLE_OK;
+  const char *ptr = conn_to_host;
+  int host_match = FALSE;
+  int port_match = FALSE;
+
+  *host_result = NULL;
+  *port_result = -1;
+
+  if(*ptr == ':') {
+    /* an empty hostname always matches */
+    host_match = TRUE;
+    ptr++;
+  }
+  else {
+    /* check whether the URL's hostname matches */
+    size_t hostname_to_match_len;
+    char *hostname_to_match = aprintf("%s%s%s",
+                                      conn->bits.ipv6_ip ? "[" : "",
+                                      conn->host.name,
+                                      conn->bits.ipv6_ip ? "]" : "");
+    if(!hostname_to_match)
+      return CURLE_OUT_OF_MEMORY;
+    hostname_to_match_len = strlen(hostname_to_match);
+    host_match = strncasecompare(ptr, hostname_to_match,
+                                 hostname_to_match_len);
+    free(hostname_to_match);
+    ptr += hostname_to_match_len;
+
+    host_match = host_match && *ptr == ':';
+    ptr++;
+  }
+
+  if(host_match) {
+    if(*ptr == ':') {
+      /* an empty port always matches */
+      port_match = TRUE;
+      ptr++;
+    }
+    else {
+      /* check whether the URL's port matches */
+      char *ptr_next = strchr(ptr, ':');
+      if(ptr_next) {
+        char *endp = NULL;
+        long port_to_match = strtol(ptr, &endp, 10);
+        if((endp == ptr_next) && (port_to_match == conn->remote_port)) {
+          port_match = TRUE;
+          ptr = ptr_next + 1;
+        }
+      }
+    }
+  }
+
+  if(host_match && port_match) {
+    /* parse the hostname and port to connect to */
+    result = parse_connect_to_host_port(data, ptr, host_result, port_result);
+  }
+
+  return result;
+}
+
+/*
+ * Processes all strings in the "connect to" slist, and uses the "connect
+ * to host" and "connect to port" of the first string that matches.
+ */
+static CURLcode parse_connect_to_slist(struct Curl_easy *data,
+                                       struct connectdata *conn,
+                                       struct curl_slist *conn_to_host)
+{
+  CURLcode result = CURLE_OK;
+  char *host = NULL;
+  int port = -1;
+
+  while(conn_to_host && !host && port == -1) {
+    result = parse_connect_to_string(data, conn, conn_to_host->data,
+                                     &host, &port);
+    if(result)
+      return result;
+
+    if(host && *host) {
+      conn->conn_to_host.rawalloc = host;
+      conn->conn_to_host.name = host;
+      conn->bits.conn_to_host = TRUE;
+
+      infof(data, "Connecting to hostname: %s\n", host);
+    }
+    else {
+      /* no "connect to host" */
+      conn->bits.conn_to_host = FALSE;
+      Curl_safefree(host);
+    }
+
+    if(port >= 0) {
+      conn->conn_to_port = port;
+      conn->bits.conn_to_port = TRUE;
+      infof(data, "Connecting to port: %d\n", port);
+    }
+    else {
+      /* no "connect to port" */
+      conn->bits.conn_to_port = FALSE;
+      port = -1;
+    }
+
+    conn_to_host = conn_to_host->next;
+  }
+
+  return result;
+}
+
+/*************************************************************
+ * Resolve the address of the server or proxy
+ *************************************************************/
+static CURLcode resolve_server(struct Curl_easy *data,
+                               struct connectdata *conn,
+                               bool *async)
+{
+  CURLcode result = CURLE_OK;
+  timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+  /*************************************************************
+   * Resolve the name of the server or proxy
+   *************************************************************/
+  if(conn->bits.reuse)
+    /* We're reusing the connection - no need to resolve anything, and
+       fix_hostname() was called already in create_conn() for the re-use
+       case. */
+    *async = FALSE;
+
+  else {
+    /* this is a fresh connect */
+    int rc;
+    struct Curl_dns_entry *hostaddr;
+
+#ifdef USE_UNIX_SOCKETS
+    if(conn->unix_domain_socket) {
+      /* Unix domain sockets are local. The host gets ignored, just use the
+       * specified domain socket address. Do not cache "DNS entries". There is
+       * no DNS involved and we already have the filesystem path available */
+      const char *path = conn->unix_domain_socket;
+
+      hostaddr = calloc(1, sizeof(struct Curl_dns_entry));
+      if(!hostaddr)
+        result = CURLE_OUT_OF_MEMORY;
+      else {
+        bool longpath = FALSE;
+        hostaddr->addr = Curl_unix2addr(path, &longpath,
+                                        conn->abstract_unix_socket);
+        if(hostaddr->addr)
+          hostaddr->inuse++;
+        else {
+          /* Long paths are not supported for now */
+          if(longpath) {
+            failf(data, "Unix socket path too long: '%s'", path);
+            result = CURLE_COULDNT_RESOLVE_HOST;
+          }
+          else
+            result = CURLE_OUT_OF_MEMORY;
+          free(hostaddr);
+          hostaddr = NULL;
+        }
+      }
+    }
+    else
+#endif
+    if(!conn->bits.proxy) {
+      struct hostname *connhost;
+      if(conn->bits.conn_to_host)
+        connhost = &conn->conn_to_host;
+      else
+        connhost = &conn->host;
+
+      /* If not connecting via a proxy, extract the port from the URL, if it is
+       * there, thus overriding any defaults that might have been set above. */
+      if(conn->bits.conn_to_port)
+        conn->port = conn->conn_to_port;
+      else
+        conn->port = conn->remote_port;
+
+      /* Resolve target host right on */
+      rc = Curl_resolv_timeout(conn, connhost->name, (int)conn->port,
+                               &hostaddr, timeout_ms);
+      if(rc == CURLRESOLV_PENDING)
+        *async = TRUE;
+
+      else if(rc == CURLRESOLV_TIMEDOUT)
+        result = CURLE_OPERATION_TIMEDOUT;
+
+      else if(!hostaddr) {
+        failf(data, "Couldn't resolve host '%s'", connhost->dispname);
+        result =  CURLE_COULDNT_RESOLVE_HOST;
+        /* don't return yet, we need to clean up the timeout first */
+      }
+    }
+    else {
+      /* This is a proxy that hasn't been resolved yet. */
+
+      struct hostname * const host = conn->bits.socksproxy ?
+        &conn->socks_proxy.host : &conn->http_proxy.host;
+
+      /* resolve proxy */
+      rc = Curl_resolv_timeout(conn, host->name, (int)conn->port,
+                               &hostaddr, timeout_ms);
+
+      if(rc == CURLRESOLV_PENDING)
+        *async = TRUE;
+
+      else if(rc == CURLRESOLV_TIMEDOUT)
+        result = CURLE_OPERATION_TIMEDOUT;
+
+      else if(!hostaddr) {
+        failf(data, "Couldn't resolve proxy '%s'", host->dispname);
+        result = CURLE_COULDNT_RESOLVE_PROXY;
+        /* don't return yet, we need to clean up the timeout first */
+      }
+    }
+    DEBUGASSERT(conn->dns_entry == NULL);
+    conn->dns_entry = hostaddr;
+  }
+
+  return result;
+}
+
+/*
+ * Cleanup the connection just allocated before we can move along and use the
+ * previously existing one.  All relevant data is copied over and old_conn is
+ * ready for freeing once this function returns.
+ */
+static void reuse_conn(struct connectdata *old_conn,
+                       struct connectdata *conn)
+{
+  free_fixed_hostname(&old_conn->http_proxy.host);
+  free_fixed_hostname(&old_conn->socks_proxy.host);
+
+  free(old_conn->http_proxy.host.rawalloc);
+  free(old_conn->socks_proxy.host.rawalloc);
+
+  /* free the SSL config struct from this connection struct as this was
+     allocated in vain and is targeted for destruction */
+  Curl_free_primary_ssl_config(&old_conn->ssl_config);
+  Curl_free_primary_ssl_config(&old_conn->proxy_ssl_config);
+
+  conn->data = old_conn->data;
+
+  /* get the user+password information from the old_conn struct since it may
+   * be new for this request even when we re-use an existing connection */
+  conn->bits.user_passwd = old_conn->bits.user_passwd;
+  if(conn->bits.user_passwd) {
+    /* use the new user name and password though */
+    Curl_safefree(conn->user);
+    Curl_safefree(conn->passwd);
+    conn->user = old_conn->user;
+    conn->passwd = old_conn->passwd;
+    old_conn->user = NULL;
+    old_conn->passwd = NULL;
+  }
+
+  conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
+  if(conn->bits.proxy_user_passwd) {
+    /* use the new proxy user name and proxy password though */
+    Curl_safefree(conn->http_proxy.user);
+    Curl_safefree(conn->socks_proxy.user);
+    Curl_safefree(conn->http_proxy.passwd);
+    Curl_safefree(conn->socks_proxy.passwd);
+    conn->http_proxy.user = old_conn->http_proxy.user;
+    conn->socks_proxy.user = old_conn->socks_proxy.user;
+    conn->http_proxy.passwd = old_conn->http_proxy.passwd;
+    conn->socks_proxy.passwd = old_conn->socks_proxy.passwd;
+    old_conn->http_proxy.user = NULL;
+    old_conn->socks_proxy.user = NULL;
+    old_conn->http_proxy.passwd = NULL;
+    old_conn->socks_proxy.passwd = NULL;
+  }
+
+  /* host can change, when doing keepalive with a proxy or if the case is
+     different this time etc */
+  free_fixed_hostname(&conn->host);
+  free_fixed_hostname(&conn->conn_to_host);
+  Curl_safefree(conn->host.rawalloc);
+  Curl_safefree(conn->conn_to_host.rawalloc);
+  conn->host = old_conn->host;
+  conn->conn_to_host = old_conn->conn_to_host;
+  conn->conn_to_port = old_conn->conn_to_port;
+  conn->remote_port = old_conn->remote_port;
+
+  /* persist connection info in session handle */
+  Curl_persistconninfo(conn);
+
+  conn_reset_all_postponed_data(old_conn); /* free buffers */
+
+  /* re-use init */
+  conn->bits.reuse = TRUE; /* yes, we're re-using here */
+
+  Curl_safefree(old_conn->user);
+  Curl_safefree(old_conn->passwd);
+  Curl_safefree(old_conn->http_proxy.user);
+  Curl_safefree(old_conn->socks_proxy.user);
+  Curl_safefree(old_conn->http_proxy.passwd);
+  Curl_safefree(old_conn->socks_proxy.passwd);
+  Curl_safefree(old_conn->localdev);
+
+  Curl_llist_destroy(&old_conn->send_pipe, NULL);
+  Curl_llist_destroy(&old_conn->recv_pipe, NULL);
+
+  Curl_safefree(old_conn->master_buffer);
+
+#ifdef USE_UNIX_SOCKETS
+  Curl_safefree(old_conn->unix_domain_socket);
+#endif
+}
+
+/**
+ * create_conn() sets up a new connectdata struct, or re-uses an already
+ * existing one, and resolves host name.
+ *
+ * if this function returns CURLE_OK and *async is set to TRUE, the resolve
+ * response will be coming asynchronously. If *async is FALSE, the name is
+ * already resolved.
+ *
+ * @param data The sessionhandle pointer
+ * @param in_connect is set to the next connection data pointer
+ * @param async is set TRUE when an async DNS resolution is pending
+ * @see Curl_setup_conn()
+ *
+ * *NOTE* this function assigns the conn->data pointer!
+ */
+
+static CURLcode create_conn(struct Curl_easy *data,
+                            struct connectdata **in_connect,
+                            bool *async)
+{
+  CURLcode result = CURLE_OK;
+  struct connectdata *conn;
+  struct connectdata *conn_temp = NULL;
+  size_t urllen;
+  char *user = NULL;
+  char *passwd = NULL;
+  char *options = NULL;
+  bool reuse;
+  bool prot_missing = FALSE;
+  bool connections_available = TRUE;
+  bool force_reuse = FALSE;
+  bool waitpipe = FALSE;
+  size_t max_host_connections = Curl_multi_max_host_connections(data->multi);
+  size_t max_total_connections = Curl_multi_max_total_connections(data->multi);
+
+  *async = FALSE;
+
+  /*************************************************************
+   * Check input data
+   *************************************************************/
+
+  if(!data->change.url) {
+    result = CURLE_URL_MALFORMAT;
+    goto out;
+  }
+
+  /* First, split up the current URL in parts so that we can use the
+     parts for checking against the already present connections. In order
+     to not have to modify everything at once, we allocate a temporary
+     connection data struct and fill in for comparison purposes. */
+  conn = allocate_conn(data);
+
+  if(!conn) {
+    result = CURLE_OUT_OF_MEMORY;
+    goto out;
+  }
+
+  /* We must set the return variable as soon as possible, so that our
+     parent can cleanup any possible allocs we may have done before
+     any failure */
+  *in_connect = conn;
+
+  /* This initing continues below, see the comment "Continue connectdata
+   * initialization here" */
+
+  /***********************************************************
+   * We need to allocate memory to store the path in. We get the size of the
+   * full URL to be sure, and we need to make it at least 256 bytes since
+   * other parts of the code will rely on this fact
+   ***********************************************************/
+#define LEAST_PATH_ALLOC 256
+  urllen = strlen(data->change.url);
+  if(urllen < LEAST_PATH_ALLOC)
+    urllen = LEAST_PATH_ALLOC;
+
+  /*
+   * We malloc() the buffers below urllen+2 to make room for 2 possibilities:
+   * 1 - an extra terminating zero
+   * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used)
+   */
+
+  Curl_safefree(data->state.pathbuffer);
+  data->state.path = NULL;
+
+  data->state.pathbuffer = malloc(urllen + 2);
+  if(NULL == data->state.pathbuffer) {
+    result = CURLE_OUT_OF_MEMORY; /* really bad error */
+    goto out;
+  }
+  data->state.path = data->state.pathbuffer;
+
+  conn->host.rawalloc = malloc(urllen + 2);
+  if(NULL == conn->host.rawalloc) {
+    Curl_safefree(data->state.pathbuffer);
+    data->state.path = NULL;
+    result = CURLE_OUT_OF_MEMORY;
+    goto out;
+  }
+
+  conn->host.name = conn->host.rawalloc;
+  conn->host.name[0] = 0;
+
+  user = strdup("");
+  passwd = strdup("");
+  options = strdup("");
+  if(!user || !passwd || !options) {
+    result = CURLE_OUT_OF_MEMORY;
+    goto out;
+  }
+
+  result = parseurlandfillconn(data, conn, &prot_missing, &user, &passwd,
+                               &options);
+  if(result)
+    goto out;
+
+  /*************************************************************
+   * No protocol part in URL was used, add it!
+   *************************************************************/
+  if(prot_missing) {
+    /* We're guessing prefixes here and if we're told to use a proxy or if
+       we're gonna follow a Location: later or... then we need the protocol
+       part added so that we have a valid URL. */
+    char *reurl;
+    char *ch_lower;
+
+    reurl = aprintf("%s://%s", conn->handler->scheme, data->change.url);
+
+    if(!reurl) {
+      result = CURLE_OUT_OF_MEMORY;
+      goto out;
+    }
+
+    /* Change protocol prefix to lower-case */
+    for(ch_lower = reurl; *ch_lower != ':'; ch_lower++)
+      *ch_lower = (char)TOLOWER(*ch_lower);
+
+    if(data->change.url_alloc) {
+      Curl_safefree(data->change.url);
+      data->change.url_alloc = FALSE;
+    }
+
+    data->change.url = reurl;
+    data->change.url_alloc = TRUE; /* free this later */
+  }
+
+  /*************************************************************
+   * If the protocol can't handle url query strings, then cut
+   * off the unhandable part
+   *************************************************************/
+  if((conn->given->flags&PROTOPT_NOURLQUERY)) {
+    char *path_q_sep = strchr(conn->data->state.path, '?');
+    if(path_q_sep) {
+      /* according to rfc3986, allow the query (?foo=bar)
+         also on protocols that can't handle it.
+
+         cut the string-part after '?'
+      */
+
+      /* terminate the string */
+      path_q_sep[0] = 0;
+    }
+  }
+
+  if(data->set.str[STRING_BEARER]) {
+    conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]);
+    if(!conn->oauth_bearer) {
+      result = CURLE_OUT_OF_MEMORY;
+      goto out;
+    }
+  }
+
+#ifdef USE_UNIX_SOCKETS
+  if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
+    conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]);
+    if(conn->unix_domain_socket == NULL) {
+      result = CURLE_OUT_OF_MEMORY;
+      goto out;
+    }
+    conn->abstract_unix_socket = data->set.abstract_unix_socket;
+  }
+#endif
+
+  /* After the unix socket init but before the proxy vars are used, parse and
+     initialize the proxy vars */
+#ifndef CURL_DISABLE_PROXY
+  result = create_conn_helper_init_proxy(conn);
+  if(result)
+    goto out;
+#endif
+
+  /*************************************************************
+   * If the protocol is using SSL and HTTP proxy is used, we set
+   * the tunnel_proxy bit.
+   *************************************************************/
+  if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy)
+    conn->bits.tunnel_proxy = TRUE;
+
+  /*************************************************************
+   * Figure out the remote port number and fix it in the URL
+   *************************************************************/
+  result = parse_remote_port(data, conn);
+  if(result)
+    goto out;
+
+  /* Check for overridden login details and set them accordingly so they
+     they are known when protocol->setup_connection is called! */
+  result = override_login(data, conn, &user, &passwd, &options);
+  if(result)
+    goto out;
+  result = set_login(conn, user, passwd, options);
+  if(result)
+    goto out;
+
+  /*************************************************************
+   * Process the "connect to" linked list of hostname/port mappings.
+   * Do this after the remote port number has been fixed in the URL.
+   *************************************************************/
+  result = parse_connect_to_slist(data, conn, data->set.connect_to);
+  if(result)
+    goto out;
+
+  /*************************************************************
+   * IDN-fix the hostnames
+   *************************************************************/
+  result = fix_hostname(conn, &conn->host);
+  if(result)
+    goto out;
+  if(conn->bits.conn_to_host) {
+    result = fix_hostname(conn, &conn->conn_to_host);
+    if(result)
+      goto out;
+  }
+  if(conn->bits.httpproxy) {
+    result = fix_hostname(conn, &conn->http_proxy.host);
+    if(result)
+      goto out;
+  }
+  if(conn->bits.socksproxy) {
+    result = fix_hostname(conn, &conn->socks_proxy.host);
+    if(result)
+      goto out;
+  }
+
+  /*************************************************************
+   * Check whether the host and the "connect to host" are equal.
+   * Do this after the hostnames have been IDN-fixed.
+   *************************************************************/
+  if(conn->bits.conn_to_host &&
+     strcasecompare(conn->conn_to_host.name, conn->host.name)) {
+    conn->bits.conn_to_host = FALSE;
+  }
+
+  /*************************************************************
+   * Check whether the port and the "connect to port" are equal.
+   * Do this after the remote port number has been fixed in the URL.
+   *************************************************************/
+  if(conn->bits.conn_to_port && conn->conn_to_port == conn->remote_port) {
+    conn->bits.conn_to_port = FALSE;
+  }
+
+  /*************************************************************
+   * If the "connect to" feature is used with an HTTP proxy,
+   * we set the tunnel_proxy bit.
+   *************************************************************/
+  if((conn->bits.conn_to_host || conn->bits.conn_to_port) &&
+      conn->bits.httpproxy)
+    conn->bits.tunnel_proxy = TRUE;
+
+  /*************************************************************
+   * Setup internals depending on protocol. Needs to be done after
+   * we figured out what/if proxy to use.
+   *************************************************************/
+  result = setup_connection_internals(conn);
+  if(result)
+    goto out;
+
+  conn->recv[FIRSTSOCKET] = Curl_recv_plain;
+  conn->send[FIRSTSOCKET] = Curl_send_plain;
+  conn->recv[SECONDARYSOCKET] = Curl_recv_plain;
+  conn->send[SECONDARYSOCKET] = Curl_send_plain;
+
+  conn->bits.tcp_fastopen = data->set.tcp_fastopen;
+
+  /***********************************************************************
+   * file: is a special case in that it doesn't need a network connection
+   ***********************************************************************/
+#ifndef CURL_DISABLE_FILE
+  if(conn->handler->flags & PROTOPT_NONETWORK) {
+    bool done;
+    /* this is supposed to be the connect function so we better at least check
+       that the file is present here! */
+    DEBUGASSERT(conn->handler->connect_it);
+    result = conn->handler->connect_it(conn, &done);
+
+    /* Setup a "faked" transfer that'll do nothing */
+    if(!result) {
+      conn->data = data;
+      conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
+
+      Curl_conncache_add_conn(data->state.conn_cache, conn);
+
+      /*
+       * Setup whatever necessary for a resumed transfer
+       */
+      result = setup_range(data);
+      if(result) {
+        DEBUGASSERT(conn->handler->done);
+        /* we ignore the return code for the protocol-specific DONE */
+        (void)conn->handler->done(conn, result, FALSE);
+        goto out;
+      }
+
+      Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */
+                          -1, NULL); /* no upload */
+    }
+
+    /* since we skip do_init() */
+    Curl_init_do(data, conn);
+
+    goto out;
+  }
+#endif
+
+  /* Get a cloned copy of the SSL config situation stored in the
+     connection struct. But to get this going nicely, we must first make
+     sure that the strings in the master copy are pointing to the correct
+     strings in the session handle strings array!
+
+     Keep in mind that the pointers in the master copy are pointing to strings
+     that will be freed as part of the Curl_easy struct, but all cloned
+     copies will be separately allocated.
+  */
+  data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_ORIG];
+  data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY];
+  data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_ORIG];
+  data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY];
+  data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
+  data->set.proxy_ssl.primary.random_file =
+    data->set.str[STRING_SSL_RANDOM_FILE];
+  data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
+  data->set.proxy_ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
+  data->set.ssl.primary.cipher_list =
+    data->set.str[STRING_SSL_CIPHER_LIST_ORIG];
+  data->set.proxy_ssl.primary.cipher_list =
+    data->set.str[STRING_SSL_CIPHER_LIST_PROXY];
+
+  data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG];
+  data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY];
+  data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG];
+  data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY];
+  data->set.ssl.cert = data->set.str[STRING_CERT_ORIG];
+  data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY];
+  data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG];
+  data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY];
+  data->set.ssl.key = data->set.str[STRING_KEY_ORIG];
+  data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY];
+  data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG];
+  data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY];
+  data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_ORIG];
+  data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY];
+  data->set.ssl.primary.clientcert = data->set.str[STRING_CERT_ORIG];
+  data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY];
+#ifdef USE_TLS_SRP
+  data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_ORIG];
+  data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY];
+  data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_ORIG];
+  data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY];
+#endif
+
+  if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary,
+     &conn->ssl_config)) {
+    result = CURLE_OUT_OF_MEMORY;
+    goto out;
+  }
+
+  if(!Curl_clone_primary_ssl_config(&data->set.proxy_ssl.primary,
+                                    &conn->proxy_ssl_config)) {
+    result = CURLE_OUT_OF_MEMORY;
+    goto out;
+  }
+
+  prune_dead_connections(data);
+
+  /*************************************************************
+   * Check the current list of connections to see if we can
+   * re-use an already existing one or if we have to create a
+   * new one.
+   *************************************************************/
+
+  /* reuse_fresh is TRUE if we are told to use a new connection by force, but
+     we only acknowledge this option if this is not a re-used connection
+     already (which happens due to follow-location or during a HTTP
+     authentication phase). */
+  if(data->set.reuse_fresh && !data->state.this_is_a_follow)
+    reuse = FALSE;
+  else
+    reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe);
+
+  /* If we found a reusable connection, we may still want to
+     open a new connection if we are pipelining. */
+  if(reuse && !force_reuse && IsPipeliningPossible(data, conn_temp)) {
+    size_t pipelen = conn_temp->send_pipe.size + conn_temp->recv_pipe.size;
+    if(pipelen > 0) {
+      infof(data, "Found connection %ld, with requests in the pipe (%zu)\n",
+            conn_temp->connection_id, pipelen);
+
+      if(conn_temp->bundle->num_connections < max_host_connections &&
+         data->state.conn_cache->num_connections < max_total_connections) {
+        /* We want a new connection anyway */
+        reuse = FALSE;
+
+        infof(data, "We can reuse, but we want a new connection anyway\n");
+      }
+    }
+  }
+
+  if(reuse) {
+    /*
+     * We already have a connection for this, we got the former connection
+     * in the conn_temp variable and thus we need to cleanup the one we
+     * just allocated before we can move along and use the previously
+     * existing one.
+     */
+    conn_temp->inuse = TRUE; /* mark this as being in use so that no other
+                                handle in a multi stack may nick it */
+    reuse_conn(conn, conn_temp);
+    free(conn);          /* we don't need this anymore */
+    conn = conn_temp;
+    *in_connect = conn;
+
+    infof(data, "Re-using existing connection! (#%ld) with %s %s\n",
+          conn->connection_id,
+          conn->bits.proxy?"proxy":"host",
+          conn->socks_proxy.host.name ? conn->socks_proxy.host.dispname :
+          conn->http_proxy.host.name ? conn->http_proxy.host.dispname :
+                                       conn->host.dispname);
+  }
+  else {
+    /* We have decided that we want a new connection. However, we may not
+       be able to do that if we have reached the limit of how many
+       connections we are allowed to open. */
+    struct connectbundle *bundle = NULL;
+
+    if(conn->handler->flags & PROTOPT_ALPN_NPN) {
+      /* The protocol wants it, so set the bits if enabled in the easy handle
+         (default) */
+      if(data->set.ssl_enable_alpn)
+        conn->bits.tls_enable_alpn = TRUE;
+      if(data->set.ssl_enable_npn)
+        conn->bits.tls_enable_npn = TRUE;
+    }
+
+    if(waitpipe)
+      /* There is a connection that *might* become usable for pipelining
+         "soon", and we wait for that */
+      connections_available = FALSE;
+    else
+      bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
+
+    if(max_host_connections > 0 && bundle &&
+       (bundle->num_connections >= max_host_connections)) {
+      struct connectdata *conn_candidate;
+
+      /* The bundle is full. Let's see if we can kill a connection. */
+      conn_candidate = find_oldest_idle_connection_in_bundle(data, bundle);
+
+      if(conn_candidate) {
+        /* Set the connection's owner correctly, then kill it */
+        conn_candidate->data = data;
+        (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
+      }
+      else {
+        infof(data, "No more connections allowed to host: %d\n",
+              max_host_connections);
+        connections_available = FALSE;
+      }
+    }
+
+    if(connections_available &&
+       (max_total_connections > 0) &&
+       (data->state.conn_cache->num_connections >= max_total_connections)) {
+      struct connectdata *conn_candidate;
+
+      /* The cache is full. Let's see if we can kill a connection. */
+      conn_candidate = Curl_conncache_oldest_idle(data);
+
+      if(conn_candidate) {
+        /* Set the connection's owner correctly, then kill it */
+        conn_candidate->data = data;
+        (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE);
+      }
+      else {
+        infof(data, "No connections available in cache\n");
+        connections_available = FALSE;
+      }
+    }
+
+    if(!connections_available) {
+      infof(data, "No connections available.\n");
+
+      conn_free(conn);
+      *in_connect = NULL;
+
+      result = CURLE_NO_CONNECTION_AVAILABLE;
+      goto out;
+    }
+    else {
+      /*
+       * This is a brand new connection, so let's store it in the connection
+       * cache of ours!
+       */
+      Curl_conncache_add_conn(data->state.conn_cache, conn);
+    }
+
+#if defined(USE_NTLM)
+    /* If NTLM is requested in a part of this connection, make sure we don't
+       assume the state is fine as this is a fresh connection and NTLM is
+       connection based. */
+    if((data->state.authhost.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
+       data->state.authhost.done) {
+      infof(data, "NTLM picked AND auth done set, clear picked!\n");
+      data->state.authhost.picked = CURLAUTH_NONE;
+      data->state.authhost.done = FALSE;
+    }
+
+    if((data->state.authproxy.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
+       data->state.authproxy.done) {
+      infof(data, "NTLM-proxy picked AND auth done set, clear picked!\n");
+      data->state.authproxy.picked = CURLAUTH_NONE;
+      data->state.authproxy.done = FALSE;
+    }
+#endif
+  }
+
+  /* Mark the connection as used */
+  conn->inuse = TRUE;
+
+  /* Setup and init stuff before DO starts, in preparing for the transfer. */
+  Curl_init_do(data, conn);
+
+  /*
+   * Setup whatever necessary for a resumed transfer
+   */
+  result = setup_range(data);
+  if(result)
+    goto out;
+
+  /* Continue connectdata initialization here. */
+
+  /*
+   * Inherit the proper values from the urldata struct AFTER we have arranged
+   * the persistent connection stuff
+   */
+  conn->seek_func = data->set.seek_func;
+  conn->seek_client = data->set.seek_client;
+
+  /*************************************************************
+   * Resolve the address of the server or proxy
+   *************************************************************/
+  result = resolve_server(data, conn, async);
+
+out:
+
+  free(options);
+  free(passwd);
+  free(user);
+  return result;
+}
+
+/* Curl_setup_conn() is called after the name resolve initiated in
+ * create_conn() is all done.
+ *
+ * Curl_setup_conn() also handles reused connections
+ *
+ * conn->data MUST already have been setup fine (in create_conn)
+ */
+
+CURLcode Curl_setup_conn(struct connectdata *conn,
+                         bool *protocol_done)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  Curl_pgrsTime(data, TIMER_NAMELOOKUP);
+
+  if(conn->handler->flags & PROTOPT_NONETWORK) {
+    /* nothing to setup when not using a network */
+    *protocol_done = TRUE;
+    return result;
+  }
+  *protocol_done = FALSE; /* default to not done */
+
+  /* set proxy_connect_closed to false unconditionally already here since it
+     is used strictly to provide extra information to a parent function in the
+     case of proxy CONNECT failures and we must make sure we don't have it
+     lingering set from a previous invoke */
+  conn->bits.proxy_connect_closed = FALSE;
+
+  /*
+   * Set user-agent. Used for HTTP, but since we can attempt to tunnel
+   * basically anything through a http proxy we can't limit this based on
+   * protocol.
+   */
+  if(data->set.str[STRING_USERAGENT]) {
+    Curl_safefree(conn->allocptr.uagent);
+    conn->allocptr.uagent =
+      aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]);
+    if(!conn->allocptr.uagent)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  data->req.headerbytecount = 0;
+
+#ifdef CURL_DO_LINEEND_CONV
+  data->state.crlf_conversions = 0; /* reset CRLF conversion counter */
+#endif /* CURL_DO_LINEEND_CONV */
+
+  /* set start time here for timeout purposes in the connect procedure, it
+     is later set again for the progress meter purpose */
+  conn->now = Curl_now();
+
+  if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
+    conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
+    result = Curl_connecthost(conn, conn->dns_entry);
+    if(result)
+      return result;
+  }
+  else {
+    Curl_pgrsTime(data, TIMER_CONNECT);    /* we're connected already */
+    Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
+    conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
+    *protocol_done = TRUE;
+    Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]);
+    Curl_verboseconnect(conn);
+  }
+
+  conn->now = Curl_now(); /* time this *after* the connect is done, we
+                               set this here perhaps a second time */
+
+#ifdef __EMX__
+  /*
+   * This check is quite a hack. We're calling _fsetmode to fix the problem
+   * with fwrite converting newline characters (you get mangled text files,
+   * and corrupted binary files when you download to stdout and redirect it to
+   * a file).
+   */
+
+  if((data->set.out)->_handle == NULL) {
+    _fsetmode(stdout, "b");
+  }
+#endif
+
+  return result;
+}
+
+CURLcode Curl_connect(struct Curl_easy *data,
+                      struct connectdata **in_connect,
+                      bool *asyncp,
+                      bool *protocol_done)
+{
+  CURLcode result;
+
+  *asyncp = FALSE; /* assume synchronous resolves by default */
+
+  /* call the stuff that needs to be called */
+  result = create_conn(data, in_connect, asyncp);
+
+  if(!result) {
+    /* no error */
+    if((*in_connect)->send_pipe.size || (*in_connect)->recv_pipe.size)
+      /* pipelining */
+      *protocol_done = TRUE;
+    else if(!*asyncp) {
+      /* DNS resolution is done: that's either because this is a reused
+         connection, in which case DNS was unnecessary, or because DNS
+         really did finish already (synch resolver/fast async resolve) */
+      result = Curl_setup_conn(*in_connect, protocol_done);
+    }
+  }
+
+  if(result == CURLE_NO_CONNECTION_AVAILABLE) {
+    *in_connect = NULL;
+    return result;
+  }
+
+  if(result && *in_connect) {
+    /* We're not allowed to return failure with memory left allocated
+       in the connectdata struct, free those here */
+    Curl_disconnect(*in_connect, FALSE); /* close the connection */
+    *in_connect = NULL;           /* return a NULL */
+  }
+
+  return result;
+}
+
+/*
+ * Curl_init_do() inits the readwrite session. This is inited each time (in
+ * the DO function before the protocol-specific DO functions are invoked) for
+ * a transfer, sometimes multiple times on the same Curl_easy. Make sure
+ * nothing in here depends on stuff that are setup dynamically for the
+ * transfer.
+ *
+ * Allow this function to get called with 'conn' set to NULL.
+ */
+
+CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
+{
+  struct SingleRequest *k = &data->req;
+
+  conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to
+                                 use */
+
+  data->state.done = FALSE; /* *_done() is not called yet */
+  data->state.expect100header = FALSE;
+
+  /* if the protocol used doesn't support wildcards, switch it off */
+  if(data->state.wildcardmatch &&
+     !(conn->handler->flags & PROTOPT_WILDCARD))
+    data->state.wildcardmatch = FALSE;
+
+  if(data->set.opt_no_body)
+    /* in HTTP lingo, no body means using the HEAD request... */
+    data->set.httpreq = HTTPREQ_HEAD;
+  else if(HTTPREQ_HEAD == data->set.httpreq)
+    /* ... but if unset there really is no perfect method that is the
+       "opposite" of HEAD but in reality most people probably think GET
+       then. The important thing is that we can't let it remain HEAD if the
+       opt_no_body is set FALSE since then we'll behave wrong when getting
+       HTTP. */
+    data->set.httpreq = HTTPREQ_GET;
+
+  k->start = Curl_now(); /* start time */
+  k->now = k->start;   /* current time is now */
+  k->header = TRUE; /* assume header */
+
+  k->bytecount = 0;
+
+  k->buf = data->state.buffer;
+  k->hbufp = data->state.headerbuff;
+  k->ignorebody = FALSE;
+
+  Curl_speedinit(data);
+
+  Curl_pgrsSetUploadCounter(data, 0);
+  Curl_pgrsSetDownloadCounter(data, 0);
+
+  return CURLE_OK;
+}
+
+/*
+* get_protocol_family()
+*
+* This is used to return the protocol family for a given protocol.
+*
+* Parameters:
+*
+* protocol  [in]  - A single bit protocol identifier such as HTTP or HTTPS.
+*
+* Returns the family as a single bit protocol identifier.
+*/
+
+static unsigned int get_protocol_family(unsigned int protocol)
+{
+  unsigned int family;
+
+  switch(protocol) {
+  case CURLPROTO_HTTP:
+  case CURLPROTO_HTTPS:
+    family = CURLPROTO_HTTP;
+    break;
+
+  case CURLPROTO_FTP:
+  case CURLPROTO_FTPS:
+    family = CURLPROTO_FTP;
+    break;
+
+  case CURLPROTO_SCP:
+    family = CURLPROTO_SCP;
+    break;
+
+  case CURLPROTO_SFTP:
+    family = CURLPROTO_SFTP;
+    break;
+
+  case CURLPROTO_TELNET:
+    family = CURLPROTO_TELNET;
+    break;
+
+  case CURLPROTO_LDAP:
+  case CURLPROTO_LDAPS:
+    family = CURLPROTO_LDAP;
+    break;
+
+  case CURLPROTO_DICT:
+    family = CURLPROTO_DICT;
+    break;
+
+  case CURLPROTO_FILE:
+    family = CURLPROTO_FILE;
+    break;
+
+  case CURLPROTO_TFTP:
+    family = CURLPROTO_TFTP;
+    break;
+
+  case CURLPROTO_IMAP:
+  case CURLPROTO_IMAPS:
+    family = CURLPROTO_IMAP;
+    break;
+
+  case CURLPROTO_POP3:
+  case CURLPROTO_POP3S:
+    family = CURLPROTO_POP3;
+    break;
+
+  case CURLPROTO_SMTP:
+  case CURLPROTO_SMTPS:
+      family = CURLPROTO_SMTP;
+      break;
+
+  case CURLPROTO_RTSP:
+    family = CURLPROTO_RTSP;
+    break;
+
+  case CURLPROTO_RTMP:
+  case CURLPROTO_RTMPS:
+    family = CURLPROTO_RTMP;
+    break;
+
+  case CURLPROTO_RTMPT:
+  case CURLPROTO_RTMPTS:
+    family = CURLPROTO_RTMPT;
+    break;
+
+  case CURLPROTO_RTMPE:
+    family = CURLPROTO_RTMPE;
+    break;
+
+  case CURLPROTO_RTMPTE:
+    family = CURLPROTO_RTMPTE;
+    break;
+
+  case CURLPROTO_GOPHER:
+    family = CURLPROTO_GOPHER;
+    break;
+
+  case CURLPROTO_SMB:
+  case CURLPROTO_SMBS:
+    family = CURLPROTO_SMB;
+    break;
+
+  default:
+      family = 0;
+      break;
+  }
+
+  return family;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/url.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/url.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/url.h	(revision 331)
@@ -0,0 +1,97 @@
+#ifndef HEADER_CURL_URL_H
+#define HEADER_CURL_URL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#define READBUFFER_SIZE CURL_MAX_WRITE_SIZE
+#define READBUFFER_MAX  CURL_MAX_READ_SIZE
+#define READBUFFER_MIN  1024
+
+/*
+ * Prototypes for library-wide functions provided by url.c
+ */
+
+CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn);
+CURLcode Curl_open(struct Curl_easy **curl);
+CURLcode Curl_init_userdefined(struct UserDefined *set);
+CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
+                     va_list arg);
+CURLcode Curl_dupset(struct Curl_easy * dst, struct Curl_easy * src);
+void Curl_freeset(struct Curl_easy * data);
+CURLcode Curl_close(struct Curl_easy *data); /* opposite of curl_open() */
+CURLcode Curl_connect(struct Curl_easy *, struct connectdata **,
+                      bool *async, bool *protocol_connect);
+CURLcode Curl_disconnect(struct connectdata *, bool dead_connection);
+CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done);
+CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done);
+CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done);
+CURLcode Curl_setup_conn(struct connectdata *conn,
+                         bool *protocol_done);
+void Curl_free_request_state(struct Curl_easy *data);
+
+int Curl_protocol_getsock(struct connectdata *conn,
+                          curl_socket_t *socks,
+                          int numsocks);
+int Curl_doing_getsock(struct connectdata *conn,
+                       curl_socket_t *socks,
+                       int numsocks);
+CURLcode Curl_parse_login_details(const char *login, const size_t len,
+                                  char **userptr, char **passwdptr,
+                                  char **optionsptr);
+bool Curl_isPipeliningEnabled(const struct Curl_easy *handle);
+CURLcode Curl_addHandleToPipeline(struct Curl_easy *handle,
+                                  struct curl_llist *pipeline);
+int Curl_removeHandleFromPipeline(struct Curl_easy *handle,
+                                  struct curl_llist *pipeline);
+/* remove the specified connection from all (possible) pipelines and related
+   queues */
+void Curl_getoff_all_pipelines(struct Curl_easy *data,
+                               struct connectdata *conn);
+
+void Curl_close_connections(struct Curl_easy *data);
+
+#define CURL_DEFAULT_PROXY_PORT 1080 /* default proxy port unless specified */
+#define CURL_DEFAULT_HTTPS_PROXY_PORT 443 /* default https proxy port unless
+                                             specified */
+
+CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex);
+
+#ifdef CURL_DISABLE_VERBOSE_STRINGS
+#define Curl_verboseconnect(x)  Curl_nop_stmt
+#else
+void Curl_verboseconnect(struct connectdata *conn);
+#endif
+
+#define CONNECT_PROXY_SSL()\
+  (conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\
+  !conn->bits.proxy_ssl_connected[sockindex])
+
+#define CONNECT_FIRSTSOCKET_PROXY_SSL()\
+  (conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\
+  !conn->bits.proxy_ssl_connected[FIRSTSOCKET])
+
+#define CONNECT_SECONDARYSOCKET_PROXY_SSL()\
+  (conn->http_proxy.proxytype == CURLPROXY_HTTPS &&\
+  !conn->bits.proxy_ssl_connected[SECONDARYSOCKET])
+
+#endif /* HEADER_CURL_URL_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/urldata.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/urldata.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/urldata.h	(revision 331)
@@ -0,0 +1,1749 @@
+#ifndef HEADER_CURL_URLDATA_H
+#define HEADER_CURL_URLDATA_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* This file is for lib internal stuff */
+
+#include "curl_setup.h"
+
+#define PORT_FTP 21
+#define PORT_FTPS 990
+#define PORT_TELNET 23
+#define PORT_HTTP 80
+#define PORT_HTTPS 443
+#define PORT_DICT 2628
+#define PORT_LDAP 389
+#define PORT_LDAPS 636
+#define PORT_TFTP 69
+#define PORT_SSH 22
+#define PORT_IMAP 143
+#define PORT_IMAPS 993
+#define PORT_POP3 110
+#define PORT_POP3S 995
+#define PORT_SMB 445
+#define PORT_SMBS 445
+#define PORT_SMTP 25
+#define PORT_SMTPS 465 /* sometimes called SSMTP */
+#define PORT_RTSP 554
+#define PORT_RTMP 1935
+#define PORT_RTMPT PORT_HTTP
+#define PORT_RTMPS PORT_HTTPS
+#define PORT_GOPHER 70
+
+#define DICT_MATCH "/MATCH:"
+#define DICT_MATCH2 "/M:"
+#define DICT_MATCH3 "/FIND:"
+#define DICT_DEFINE "/DEFINE:"
+#define DICT_DEFINE2 "/D:"
+#define DICT_DEFINE3 "/LOOKUP:"
+
+#define CURL_DEFAULT_USER "anonymous"
+#define CURL_DEFAULT_PASSWORD "ftp@example.com"
+
+/* Convenience defines for checking protocols or their SSL based version. Each
+   protocol handler should only ever have a single CURLPROTO_ in its protocol
+   field. */
+#define PROTO_FAMILY_HTTP (CURLPROTO_HTTP|CURLPROTO_HTTPS)
+#define PROTO_FAMILY_FTP  (CURLPROTO_FTP|CURLPROTO_FTPS)
+#define PROTO_FAMILY_POP3 (CURLPROTO_POP3|CURLPROTO_POP3S)
+#define PROTO_FAMILY_SMB  (CURLPROTO_SMB|CURLPROTO_SMBS)
+#define PROTO_FAMILY_SMTP (CURLPROTO_SMTP|CURLPROTO_SMTPS)
+
+#define DEFAULT_CONNCACHE_SIZE 5
+
+/* length of longest IPv6 address string including the trailing null */
+#define MAX_IPADR_LEN sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")
+
+/* Default FTP/IMAP etc response timeout in milliseconds.
+   Symbian OS panics when given a timeout much greater than 1/2 hour.
+*/
+#define RESP_TIMEOUT (1800*1000)
+
+#include "cookie.h"
+#include "formdata.h"
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include "timeval.h"
+
+#include <curl/curl.h>
+
+#include "http_chunks.h" /* for the structs and enum stuff */
+#include "hostip.h"
+#include "hash.h"
+#include "splay.h"
+
+#include "mime.h"
+#include "imap.h"
+#include "pop3.h"
+#include "smtp.h"
+#include "ftp.h"
+#include "file.h"
+#include "ssh.h"
+#include "http.h"
+#include "rtsp.h"
+#include "smb.h"
+#include "wildcard.h"
+#include "multihandle.h"
+
+#ifdef HAVE_GSSAPI
+# ifdef HAVE_GSSGNU
+#  include <gss.h>
+# elif defined HAVE_GSSMIT
+#  include <gssapi/gssapi.h>
+#  include <gssapi/gssapi_generic.h>
+# else
+#  include <gssapi.h>
+# endif
+#endif
+
+#ifdef HAVE_LIBSSH2_H
+#include <libssh2.h>
+#include <libssh2_sftp.h>
+#endif /* HAVE_LIBSSH2_H */
+
+/* The upload buffer size, should not be smaller than CURL_MAX_WRITE_SIZE, as
+   it needs to hold a full buffer as could be sent in a write callback */
+#define UPLOAD_BUFSIZE CURL_MAX_WRITE_SIZE
+
+/* The "master buffer" is for HTTP pipelining */
+#define MASTERBUF_SIZE 16384
+
+/* Initial size of the buffer to store headers in, it'll be enlarged in case
+   of need. */
+#define HEADERSIZE 256
+
+#define CURLEASY_MAGIC_NUMBER 0xc0dedbadU
+#define GOOD_EASY_HANDLE(x) \
+  ((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER))
+
+/* Some convenience macros to get the larger/smaller value out of two given.
+   We prefix with CURL to prevent name collisions. */
+#define CURLMAX(x,y) ((x)>(y)?(x):(y))
+#define CURLMIN(x,y) ((x)<(y)?(x):(y))
+
+#ifdef HAVE_GSSAPI
+/* Types needed for krb5-ftp connections */
+struct krb5buffer {
+  void *data;
+  size_t size;
+  size_t index;
+  int eof_flag;
+};
+
+enum protection_level {
+  PROT_NONE, /* first in list */
+  PROT_CLEAR,
+  PROT_SAFE,
+  PROT_CONFIDENTIAL,
+  PROT_PRIVATE,
+  PROT_CMD,
+  PROT_LAST /* last in list */
+};
+#endif
+
+/* enum for the nonblocking SSL connection state machine */
+typedef enum {
+  ssl_connect_1,
+  ssl_connect_2,
+  ssl_connect_2_reading,
+  ssl_connect_2_writing,
+  ssl_connect_3,
+  ssl_connect_done
+} ssl_connect_state;
+
+typedef enum {
+  ssl_connection_none,
+  ssl_connection_negotiating,
+  ssl_connection_complete
+} ssl_connection_state;
+
+/* SSL backend-specific data; declared differently by each SSL backend */
+struct ssl_backend_data;
+
+/* struct for data related to each SSL connection */
+struct ssl_connect_data {
+  /* Use ssl encrypted communications TRUE/FALSE, not necessarily using it atm
+     but at least asked to or meaning to use it. See 'state' for the exact
+     current state of the connection. */
+  bool use;
+  ssl_connection_state state;
+  ssl_connect_state connecting_state;
+#if defined(USE_SSL)
+  struct ssl_backend_data *backend;
+#endif
+};
+
+struct ssl_primary_config {
+  long version;          /* what version the client wants to use */
+  long version_max;      /* max supported version the client wants to use*/
+  bool verifypeer;       /* set TRUE if this is desired */
+  bool verifyhost;       /* set TRUE if CN/SAN must match hostname */
+  bool verifystatus;     /* set TRUE if certificate status must be checked */
+  bool sessionid;        /* cache session IDs or not */
+  char *CApath;          /* certificate dir (doesn't work on windows) */
+  char *CAfile;          /* certificate to verify peer against */
+  char *clientcert;
+  char *random_file;     /* path to file containing "random" data */
+  char *egdsocket;       /* path to file containing the EGD daemon socket */
+  char *cipher_list;     /* list of ciphers to use */
+};
+
+struct ssl_config_data {
+  struct ssl_primary_config primary;
+  bool enable_beast; /* especially allow this flaw for interoperability's
+                        sake*/
+  bool no_revoke;    /* disable SSL certificate revocation checks */
+  long certverifyresult; /* result from the certificate verification */
+  char *CRLfile;   /* CRL to check certificate revocation */
+  char *issuercert;/* optional issuer certificate filename */
+  curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */
+  void *fsslctxp;        /* parameter for call back */
+  bool certinfo;         /* gather lots of certificate info */
+  bool falsestart;
+
+  char *cert; /* client certificate file name */
+  char *cert_type; /* format for certificate (default: PEM)*/
+  char *key; /* private key file name */
+  char *key_type; /* format for private key (default: PEM) */
+  char *key_passwd; /* plain text private key password */
+
+#ifdef USE_TLS_SRP
+  char *username; /* TLS username (for, e.g., SRP) */
+  char *password; /* TLS password (for, e.g., SRP) */
+  enum CURL_TLSAUTH authtype; /* TLS authentication type (default SRP) */
+#endif
+};
+
+struct ssl_general_config {
+  size_t max_ssl_sessions; /* SSL session id cache size */
+};
+
+/* information stored about one single SSL session */
+struct curl_ssl_session {
+  char *name;       /* host name for which this ID was used */
+  char *conn_to_host; /* host name for the connection (may be NULL) */
+  const char *scheme; /* protocol scheme used */
+  void *sessionid;  /* as returned from the SSL layer */
+  size_t idsize;    /* if known, otherwise 0 */
+  long age;         /* just a number, the higher the more recent */
+  int remote_port;  /* remote port */
+  int conn_to_port; /* remote port for the connection (may be -1) */
+  struct ssl_primary_config ssl_config; /* setup for this session */
+};
+
+#ifdef USE_WINDOWS_SSPI
+#include "curl_sspi.h"
+#endif
+
+/* Struct used for Digest challenge-response authentication */
+struct digestdata {
+#if defined(USE_WINDOWS_SSPI)
+  BYTE *input_token;
+  size_t input_token_len;
+  CtxtHandle *http_context;
+  /* copy of user/passwd used to make the identity for http_context.
+     either may be NULL. */
+  char *user;
+  char *passwd;
+#else
+  char *nonce;
+  char *cnonce;
+  char *realm;
+  int algo;
+  bool stale; /* set true for re-negotiation */
+  char *opaque;
+  char *qop;
+  char *algorithm;
+  int nc; /* nounce count */
+  bool userhash;
+#endif
+};
+
+typedef enum {
+  NTLMSTATE_NONE,
+  NTLMSTATE_TYPE1,
+  NTLMSTATE_TYPE2,
+  NTLMSTATE_TYPE3,
+  NTLMSTATE_LAST
+} curlntlm;
+
+#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
+#include <iconv.h>
+#endif
+
+/* Struct used for GSSAPI (Kerberos V5) authentication */
+#if defined(USE_KERBEROS5)
+struct kerberos5data {
+#if defined(USE_WINDOWS_SSPI)
+  CredHandle *credentials;
+  CtxtHandle *context;
+  TCHAR *spn;
+  SEC_WINNT_AUTH_IDENTITY identity;
+  SEC_WINNT_AUTH_IDENTITY *p_identity;
+  size_t token_max;
+  BYTE *output_token;
+#else
+  gss_ctx_id_t context;
+  gss_name_t spn;
+#endif
+};
+#endif
+
+/* Struct used for NTLM challenge-response authentication */
+#if defined(USE_NTLM)
+struct ntlmdata {
+  curlntlm state;
+#ifdef USE_WINDOWS_SSPI
+  CredHandle *credentials;
+  CtxtHandle *context;
+  SEC_WINNT_AUTH_IDENTITY identity;
+  SEC_WINNT_AUTH_IDENTITY *p_identity;
+  size_t token_max;
+  BYTE *output_token;
+  BYTE *input_token;
+  size_t input_token_len;
+#else
+  unsigned int flags;
+  unsigned char nonce[8];
+  void *target_info; /* TargetInfo received in the ntlm type-2 message */
+  unsigned int target_info_len;
+#endif
+};
+#endif
+
+#ifdef USE_SPNEGO
+struct negotiatedata {
+  /* When doing Negotiate (SPNEGO) auth, we first need to send a token
+     and then validate the received one. */
+  enum { GSS_AUTHNONE, GSS_AUTHRECV, GSS_AUTHSENT } state;
+#ifdef HAVE_GSSAPI
+  OM_uint32 status;
+  gss_ctx_id_t context;
+  gss_name_t spn;
+  gss_buffer_desc output_token;
+#else
+#ifdef USE_WINDOWS_SSPI
+  DWORD status;
+  CredHandle *credentials;
+  CtxtHandle *context;
+  SEC_WINNT_AUTH_IDENTITY identity;
+  SEC_WINNT_AUTH_IDENTITY *p_identity;
+  TCHAR *spn;
+  size_t token_max;
+  BYTE *output_token;
+  size_t output_token_length;
+#endif
+#endif
+};
+#endif
+
+
+/*
+ * Boolean values that concerns this connection.
+ */
+struct ConnectBits {
+  /* always modify bits.close with the connclose() and connkeep() macros! */
+  bool close; /* if set, we close the connection after this request */
+  bool reuse; /* if set, this is a re-used connection */
+  bool conn_to_host; /* if set, this connection has a "connect to host"
+                        that overrides the host in the URL */
+  bool conn_to_port; /* if set, this connection has a "connect to port"
+                        that overrides the port in the URL (remote port) */
+  bool proxy; /* if set, this transfer is done through a proxy - any type */
+  bool httpproxy;    /* if set, this transfer is done through a http proxy */
+  bool socksproxy;   /* if set, this transfer is done through a socks proxy */
+  bool user_passwd;    /* do we use user+password for this connection? */
+  bool proxy_user_passwd; /* user+password for the proxy? */
+  bool ipv6_ip; /* we communicate with a remote site specified with pure IPv6
+                   IP address */
+  bool ipv6;    /* we communicate with a site using an IPv6 address */
+
+  bool do_more; /* this is set TRUE if the ->curl_do_more() function is
+                   supposed to be called, after ->curl_do() */
+  bool tcpconnect[2]; /* the TCP layer (or similar) is connected, this is set
+                         the first time on the first connect function call */
+  bool protoconnstart;/* the protocol layer has STARTED its operation after
+                         the TCP layer connect */
+
+  bool retry;         /* this connection is about to get closed and then
+                         re-attempted at another connection. */
+  bool tunnel_proxy;  /* if CONNECT is used to "tunnel" through the proxy.
+                         This is implicit when SSL-protocols are used through
+                         proxies, but can also be enabled explicitly by
+                         apps */
+  bool authneg;       /* TRUE when the auth phase has started, which means
+                         that we are creating a request with an auth header,
+                         but it is not the final request in the auth
+                         negotiation. */
+  bool rewindaftersend;/* TRUE when the sending couldn't be stopped even
+                          though it will be discarded. When the whole send
+                          operation is done, we must call the data rewind
+                          callback. */
+  bool ftp_use_epsv;  /* As set with CURLOPT_FTP_USE_EPSV, but if we find out
+                         EPSV doesn't work we disable it for the forthcoming
+                         requests */
+
+  bool ftp_use_eprt;  /* As set with CURLOPT_FTP_USE_EPRT, but if we find out
+                         EPRT doesn't work we disable it for the forthcoming
+                         requests */
+  bool ftp_use_data_ssl; /* Enabled SSL for the data connection */
+  bool netrc;         /* name+password provided by netrc */
+  bool userpwd_in_url; /* name+password found in url */
+  bool stream_was_rewound; /* Indicates that the stream was rewound after a
+                              request read past the end of its response byte
+                              boundary */
+  bool proxy_connect_closed; /* set true if a proxy disconnected the
+                                connection in a CONNECT request with auth, so
+                                that libcurl should reconnect and continue. */
+  bool bound; /* set true if bind() has already been done on this socket/
+                 connection */
+  bool type_set;  /* type= was used in the URL */
+  bool multiplex; /* connection is multiplexed */
+
+  bool tcp_fastopen; /* use TCP Fast Open */
+  bool tls_enable_npn;  /* TLS NPN extension? */
+  bool tls_enable_alpn; /* TLS ALPN extension? */
+  bool proxy_ssl_connected[2]; /* TRUE when SSL initialization for HTTPS proxy
+                                  is complete */
+  bool socksproxy_connecting; /* connecting through a socks proxy */
+};
+
+struct hostname {
+  char *rawalloc; /* allocated "raw" version of the name */
+  char *encalloc; /* allocated IDN-encoded version of the name */
+  char *name;     /* name to use internally, might be encoded, might be raw */
+  const char *dispname; /* name to display, as 'name' might be encoded */
+};
+
+/*
+ * Flags on the keepon member of the Curl_transfer_keeper
+ */
+
+#define KEEP_NONE  0
+#define KEEP_RECV  (1<<0)     /* there is or may be data to read */
+#define KEEP_SEND (1<<1)     /* there is or may be data to write */
+#define KEEP_RECV_HOLD (1<<2) /* when set, no reading should be done but there
+                                 might still be data to read */
+#define KEEP_SEND_HOLD (1<<3) /* when set, no writing should be done but there
+                                  might still be data to write */
+#define KEEP_RECV_PAUSE (1<<4) /* reading is paused */
+#define KEEP_SEND_PAUSE (1<<5) /* writing is paused */
+
+#define KEEP_RECVBITS (KEEP_RECV | KEEP_RECV_HOLD | KEEP_RECV_PAUSE)
+#define KEEP_SENDBITS (KEEP_SEND | KEEP_SEND_HOLD | KEEP_SEND_PAUSE)
+
+
+#ifdef CURLRES_ASYNCH
+struct Curl_async {
+  char *hostname;
+  int port;
+  struct Curl_dns_entry *dns;
+  bool done;  /* set TRUE when the lookup is complete */
+  int status; /* if done is TRUE, this is the status from the callback */
+  void *os_specific;  /* 'struct thread_data' for Windows */
+};
+#endif
+
+#define FIRSTSOCKET     0
+#define SECONDARYSOCKET 1
+
+/* These function pointer types are here only to allow easier typecasting
+   within the source when we need to cast between data pointers (such as NULL)
+   and function pointers. */
+typedef CURLcode (*Curl_do_more_func)(struct connectdata *, int *);
+typedef CURLcode (*Curl_done_func)(struct connectdata *, CURLcode, bool);
+
+enum expect100 {
+  EXP100_SEND_DATA,           /* enough waiting, just send the body now */
+  EXP100_AWAITING_CONTINUE,   /* waiting for the 100 Continue header */
+  EXP100_SENDING_REQUEST,     /* still sending the request but will wait for
+                                 the 100 header once done with the request */
+  EXP100_FAILED               /* used on 417 Expectation Failed */
+};
+
+enum upgrade101 {
+  UPGR101_INIT,               /* default state */
+  UPGR101_REQUESTED,          /* upgrade requested */
+  UPGR101_RECEIVED,           /* response received */
+  UPGR101_WORKING             /* talking upgraded protocol */
+};
+
+/*
+ * Request specific data in the easy handle (Curl_easy).  Previously,
+ * these members were on the connectdata struct but since a conn struct may
+ * now be shared between different Curl_easys, we store connection-specific
+ * data here. This struct only keeps stuff that's interesting for *this*
+ * request, as it will be cleared between multiple ones
+ */
+struct SingleRequest {
+  curl_off_t size;        /* -1 if unknown at this point */
+  curl_off_t *bytecountp; /* return number of bytes read or NULL */
+
+  curl_off_t maxdownload; /* in bytes, the maximum amount of data to fetch,
+                             -1 means unlimited */
+  curl_off_t *writebytecountp; /* return number of bytes written or NULL */
+
+  curl_off_t bytecount;         /* total number of bytes read */
+  curl_off_t writebytecount;    /* number of bytes written */
+
+  long headerbytecount;         /* only count received headers */
+  long deductheadercount; /* this amount of bytes doesn't count when we check
+                             if anything has been transferred at the end of a
+                             connection. We use this counter to make only a
+                             100 reply (without a following second response
+                             code) result in a CURLE_GOT_NOTHING error code */
+
+  struct curltime start;         /* transfer started at this time */
+  struct curltime now;           /* current time */
+  bool header;                  /* incoming data has HTTP header */
+  enum {
+    HEADER_NORMAL,              /* no bad header at all */
+    HEADER_PARTHEADER,          /* part of the chunk is a bad header, the rest
+                                   is normal data */
+    HEADER_ALLBAD               /* all was believed to be header */
+  } badheader;                  /* the header was deemed bad and will be
+                                   written as body */
+  int headerline;               /* counts header lines to better track the
+                                   first one */
+  char *hbufp;                  /* points at *end* of header line */
+  size_t hbuflen;
+  char *str;                    /* within buf */
+  char *str_start;              /* within buf */
+  char *end_ptr;                /* within buf */
+  char *p;                      /* within headerbuff */
+  bool content_range;           /* set TRUE if Content-Range: was found */
+  curl_off_t offset;            /* possible resume offset read from the
+                                   Content-Range: header */
+  int httpcode;                 /* error code from the 'HTTP/1.? XXX' or
+                                   'RTSP/1.? XXX' line */
+  struct curltime start100;      /* time stamp to wait for the 100 code from */
+  enum expect100 exp100;        /* expect 100 continue state */
+  enum upgrade101 upgr101;      /* 101 upgrade state */
+
+  struct contenc_writer_s *writer_stack;  /* Content unencoding stack. */
+                                          /* See sec 3.5, RFC2616. */
+  time_t timeofdoc;
+  long bodywrites;
+
+  char *buf;
+  curl_socket_t maxfd;
+
+  int keepon;
+
+  bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload
+                       and we're uploading the last chunk */
+
+  bool ignorebody;  /* we read a response-body but we ignore it! */
+  bool ignorecl;    /* This HTTP response has no body so we ignore the Content-
+                       Length: header */
+
+  char *location;   /* This points to an allocated version of the Location:
+                       header data */
+  char *newurl;     /* Set to the new URL to use when a redirect or a retry is
+                       wanted */
+
+  /* 'upload_present' is used to keep a byte counter of how much data there is
+     still left in the buffer, aimed for upload. */
+  ssize_t upload_present;
+
+   /* 'upload_fromhere' is used as a read-pointer when we uploaded parts of a
+      buffer, so the next read should read from where this pointer points to,
+      and the 'upload_present' contains the number of bytes available at this
+      position */
+  char *upload_fromhere;
+
+  bool chunk; /* if set, this is a chunked transfer-encoding */
+  bool upload_chunky; /* set TRUE if we are doing chunked transfer-encoding
+                         on upload */
+  bool getheader;     /* TRUE if header parsing is wanted */
+
+  bool forbidchunk;   /* used only to explicitly forbid chunk-upload for
+                         specific upload buffers. See readmoredata() in
+                         http.c for details. */
+
+  void *protop;       /* Allocated protocol-specific data. Each protocol
+                         handler makes sure this points to data it needs. */
+};
+
+/*
+ * Specific protocol handler.
+ */
+
+struct Curl_handler {
+  const char *scheme;        /* URL scheme name. */
+
+  /* Complement to setup_connection_internals(). */
+  CURLcode (*setup_connection)(struct connectdata *);
+
+  /* These two functions MUST be set to be protocol dependent */
+  CURLcode (*do_it)(struct connectdata *, bool *done);
+  Curl_done_func done;
+
+  /* If the curl_do() function is better made in two halves, this
+   * curl_do_more() function will be called afterwards, if set. For example
+   * for doing the FTP stuff after the PASV/PORT command.
+   */
+  Curl_do_more_func do_more;
+
+  /* This function *MAY* be set to a protocol-dependent function that is run
+   * after the connect() and everything is done, as a step in the connection.
+   * The 'done' pointer points to a bool that should be set to TRUE if the
+   * function completes before return. If it doesn't complete, the caller
+   * should call the curl_connecting() function until it is.
+   */
+  CURLcode (*connect_it)(struct connectdata *, bool *done);
+
+  /* See above. Currently only used for FTP. */
+  CURLcode (*connecting)(struct connectdata *, bool *done);
+  CURLcode (*doing)(struct connectdata *, bool *done);
+
+  /* Called from the multi interface during the PROTOCONNECT phase, and it
+     should then return a proper fd set */
+  int (*proto_getsock)(struct connectdata *conn,
+                       curl_socket_t *socks,
+                       int numsocks);
+
+  /* Called from the multi interface during the DOING phase, and it should
+     then return a proper fd set */
+  int (*doing_getsock)(struct connectdata *conn,
+                       curl_socket_t *socks,
+                       int numsocks);
+
+  /* Called from the multi interface during the DO_MORE phase, and it should
+     then return a proper fd set */
+  int (*domore_getsock)(struct connectdata *conn,
+                        curl_socket_t *socks,
+                        int numsocks);
+
+  /* Called from the multi interface during the DO_DONE, PERFORM and
+     WAITPERFORM phases, and it should then return a proper fd set. Not setting
+     this will make libcurl use the generic default one. */
+  int (*perform_getsock)(const struct connectdata *conn,
+                         curl_socket_t *socks,
+                         int numsocks);
+
+  /* This function *MAY* be set to a protocol-dependent function that is run
+   * by the curl_disconnect(), as a step in the disconnection.  If the handler
+   * is called because the connection has been considered dead, dead_connection
+   * is set to TRUE.
+   */
+  CURLcode (*disconnect)(struct connectdata *, bool dead_connection);
+
+  /* If used, this function gets called from transfer.c:readwrite_data() to
+     allow the protocol to do extra reads/writes */
+  CURLcode (*readwrite)(struct Curl_easy *data, struct connectdata *conn,
+                        ssize_t *nread, bool *readmore);
+
+  /* This function can perform various checks on the connection. See
+     CONNCHECK_* for more information about the checks that can be performed,
+     and CONNRESULT_* for the results that can be returned. */
+  unsigned int (*connection_check)(struct connectdata *conn,
+                                   unsigned int checks_to_perform);
+
+  long defport;           /* Default port. */
+  unsigned int protocol;  /* See CURLPROTO_* - this needs to be the single
+                             specific protocol bit */
+  unsigned int flags;     /* Extra particular characteristics, see PROTOPT_* */
+};
+
+#define PROTOPT_NONE 0             /* nothing extra */
+#define PROTOPT_SSL (1<<0)         /* uses SSL */
+#define PROTOPT_DUAL (1<<1)        /* this protocol uses two connections */
+#define PROTOPT_CLOSEACTION (1<<2) /* need action before socket close */
+/* some protocols will have to call the underlying functions without regard to
+   what exact state the socket signals. IE even if the socket says "readable",
+   the send function might need to be called while uploading, or vice versa.
+*/
+#define PROTOPT_DIRLOCK (1<<3)
+#define PROTOPT_NONETWORK (1<<4)   /* protocol doesn't use the network! */
+#define PROTOPT_NEEDSPWD (1<<5)    /* needs a password, and if none is set it
+                                      gets a default */
+#define PROTOPT_NOURLQUERY (1<<6)   /* protocol can't handle
+                                        url query strings (?foo=bar) ! */
+#define PROTOPT_CREDSPERREQUEST (1<<7) /* requires login credentials per
+                                          request instead of per connection */
+#define PROTOPT_ALPN_NPN (1<<8) /* set ALPN and/or NPN for this */
+#define PROTOPT_STREAM (1<<9) /* a protocol with individual logical streams */
+#define PROTOPT_URLOPTIONS (1<<10) /* allow options part in the userinfo field
+                                      of the URL */
+#define PROTOPT_PROXY_AS_HTTP (1<<11) /* allow this non-HTTP scheme over a
+                                         HTTP proxy as HTTP proxies may know
+                                         this protocol and act as a gateway */
+#define PROTOPT_WILDCARD (1<<12) /* protocol supports wildcard matching */
+
+#define CONNCHECK_NONE 0                 /* No checks */
+#define CONNCHECK_ISDEAD (1<<0)          /* Check if the connection is dead. */
+
+#define CONNRESULT_NONE 0                /* No extra information. */
+#define CONNRESULT_DEAD (1<<0)           /* The connection is dead. */
+
+/* return the count of bytes sent, or -1 on error */
+typedef ssize_t (Curl_send)(struct connectdata *conn, /* connection data */
+                            int sockindex,            /* socketindex */
+                            const void *buf,          /* data to write */
+                            size_t len,               /* max amount to write */
+                            CURLcode *err);           /* error to return */
+
+/* return the count of bytes read, or -1 on error */
+typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */
+                            int sockindex,            /* socketindex */
+                            char *buf,                /* store data here */
+                            size_t len,               /* max amount to read */
+                            CURLcode *err);           /* error to return */
+
+#ifdef USE_RECV_BEFORE_SEND_WORKAROUND
+struct postponed_data {
+  char *buffer;          /* Temporal store for received data during
+                            sending, must be freed */
+  size_t allocated_size; /* Size of temporal store */
+  size_t recv_size;      /* Size of received data during sending */
+  size_t recv_processed; /* Size of processed part of postponed data */
+#ifdef DEBUGBUILD
+  curl_socket_t bindsock;/* Structure must be bound to specific socket,
+                            used only for DEBUGASSERT */
+#endif /* DEBUGBUILD */
+};
+#endif /* USE_RECV_BEFORE_SEND_WORKAROUND */
+
+struct proxy_info {
+  struct hostname host;
+  long port;
+  curl_proxytype proxytype; /* what kind of proxy that is in use */
+  char *user;    /* proxy user name string, allocated */
+  char *passwd;  /* proxy password string, allocated */
+};
+
+#define CONNECT_BUFFER_SIZE 16384
+
+/* struct for HTTP CONNECT state data */
+struct http_connect_state {
+  char connect_buffer[CONNECT_BUFFER_SIZE];
+  int perline; /* count bytes per line */
+  int keepon;
+  char *line_start;
+  char *ptr; /* where to store more data */
+  curl_off_t cl; /* size of content to read and ignore */
+  bool chunked_encoding;
+  enum {
+    TUNNEL_INIT,    /* init/default/no tunnel state */
+    TUNNEL_CONNECT, /* CONNECT has been sent off */
+    TUNNEL_COMPLETE /* CONNECT response received completely */
+  } tunnel_state;
+};
+
+/*
+ * The connectdata struct contains all fields and variables that should be
+ * unique for an entire connection.
+ */
+struct connectdata {
+  /* 'data' is the CURRENT Curl_easy using this connection -- take great
+     caution that this might very well vary between different times this
+     connection is used! */
+  struct Curl_easy *data;
+
+  struct curl_llist_element bundle_node; /* conncache */
+
+  /* chunk is for HTTP chunked encoding, but is in the general connectdata
+     struct only because we can do just about any protocol through a HTTP proxy
+     and a HTTP proxy may in fact respond using chunked encoding */
+  struct Curl_chunker chunk;
+
+  curl_closesocket_callback fclosesocket; /* function closing the socket(s) */
+  void *closesocket_client;
+
+  bool inuse; /* This is a marker for the connection cache logic. If this is
+                 TRUE this handle is being used by an easy handle and cannot
+                 be used by any other easy handle without careful
+                 consideration (== only for pipelining). */
+
+  /**** Fields set when inited and not modified again */
+  long connection_id; /* Contains a unique number to make it easier to
+                         track the connections in the log output */
+
+  /* 'dns_entry' is the particular host we use. This points to an entry in the
+     DNS cache and it will not get pruned while locked. It gets unlocked in
+     Curl_done(). This entry will be NULL if the connection is re-used as then
+     there is no name resolve done. */
+  struct Curl_dns_entry *dns_entry;
+
+  /* 'ip_addr' is the particular IP we connected to. It points to a struct
+     within the DNS cache, so this pointer is only valid as long as the DNS
+     cache entry remains locked. It gets unlocked in Curl_done() */
+  Curl_addrinfo *ip_addr;
+  Curl_addrinfo *tempaddr[2]; /* for happy eyeballs */
+
+  /* 'ip_addr_str' is the ip_addr data as a human readable string.
+     It remains available as long as the connection does, which is longer than
+     the ip_addr itself. */
+  char ip_addr_str[MAX_IPADR_LEN];
+
+  unsigned int scope_id;  /* Scope id for IPv6 */
+
+  int socktype;  /* SOCK_STREAM or SOCK_DGRAM */
+
+  struct hostname host;
+  char *secondaryhostname; /* secondary socket host name (ftp) */
+  struct hostname conn_to_host; /* the host to connect to. valid only if
+                                   bits.conn_to_host is set */
+
+  struct proxy_info socks_proxy;
+  struct proxy_info http_proxy;
+
+  long port;       /* which port to use locally */
+  int remote_port; /* the remote port, not the proxy port! */
+  int conn_to_port; /* the remote port to connect to. valid only if
+                       bits.conn_to_port is set */
+  unsigned short secondary_port; /* secondary socket remote port to connect to
+                                    (ftp) */
+
+  /* 'primary_ip' and 'primary_port' get filled with peer's numerical
+     ip address and port number whenever an outgoing connection is
+     *attempted* from the primary socket to a remote address. When more
+     than one address is tried for a connection these will hold data
+     for the last attempt. When the connection is actually established
+     these are updated with data which comes directly from the socket. */
+
+  char primary_ip[MAX_IPADR_LEN];
+  long primary_port;
+
+  /* 'local_ip' and 'local_port' get filled with local's numerical
+     ip address and port number whenever an outgoing connection is
+     **established** from the primary socket to a remote address. */
+
+  char local_ip[MAX_IPADR_LEN];
+  long local_port;
+
+  char *user;    /* user name string, allocated */
+  char *passwd;  /* password string, allocated */
+  char *options; /* options string, allocated */
+
+  char *oauth_bearer; /* bearer token for OAuth 2.0, allocated */
+
+  int httpversion;        /* the HTTP version*10 reported by the server */
+  int rtspversion;        /* the RTSP version*10 reported by the server */
+
+  struct curltime now;     /* "current" time */
+  struct curltime created; /* creation time */
+  curl_socket_t sock[2]; /* two sockets, the second is used for the data
+                            transfer when doing FTP */
+  curl_socket_t tempsock[2]; /* temporary sockets for happy eyeballs */
+  bool sock_accepted[2]; /* TRUE if the socket on this index was created with
+                            accept() */
+  Curl_recv *recv[2];
+  Curl_send *send[2];
+
+#ifdef USE_RECV_BEFORE_SEND_WORKAROUND
+  struct postponed_data postponed[2]; /* two buffers for two sockets */
+#endif /* USE_RECV_BEFORE_SEND_WORKAROUND */
+  struct ssl_connect_data ssl[2]; /* this is for ssl-stuff */
+  struct ssl_connect_data proxy_ssl[2]; /* this is for proxy ssl-stuff */
+  struct ssl_primary_config ssl_config;
+  struct ssl_primary_config proxy_ssl_config;
+  bool tls_upgraded;
+
+  struct ConnectBits bits;    /* various state-flags for this connection */
+
+ /* connecttime: when connect() is called on the current IP address. Used to
+    be able to track when to move on to try next IP - but only when the multi
+    interface is used. */
+  struct curltime connecttime;
+  /* The two fields below get set in Curl_connecthost */
+  int num_addr; /* number of addresses to try to connect to */
+  time_t timeoutms_per_addr; /* how long time in milliseconds to spend on
+                                trying to connect to each IP address */
+
+  const struct Curl_handler *handler; /* Connection's protocol handler */
+  const struct Curl_handler *given;   /* The protocol first given */
+
+  long ip_version; /* copied from the Curl_easy at creation time */
+
+  /**** curl_get() phase fields */
+
+  curl_socket_t sockfd;   /* socket to read from or CURL_SOCKET_BAD */
+  curl_socket_t writesockfd; /* socket to write to, it may very
+                                well be the same we read from.
+                                CURL_SOCKET_BAD disables */
+
+  /** Dynamicly allocated strings, MUST be freed before this **/
+  /** struct is killed.                                      **/
+  struct dynamically_allocated_data {
+    char *proxyuserpwd;
+    char *uagent;
+    char *accept_encoding;
+    char *userpwd;
+    char *rangeline;
+    char *ref;
+    char *host;
+    char *cookiehost;
+    char *rtsp_transport;
+    char *te; /* TE: request header */
+  } allocptr;
+
+#ifdef HAVE_GSSAPI
+  int sec_complete; /* if Kerberos is enabled for this connection */
+  enum protection_level command_prot;
+  enum protection_level data_prot;
+  enum protection_level request_data_prot;
+  size_t buffer_size;
+  struct krb5buffer in_buffer;
+  void *app_data;
+  const struct Curl_sec_client_mech *mech;
+  struct sockaddr_in local_addr;
+#endif
+
+#if defined(USE_KERBEROS5)    /* Consider moving some of the above GSS-API */
+  struct kerberos5data krb5;  /* variables into the structure definition, */
+#endif                        /* however, some of them are ftp specific. */
+
+  /* the two following *_inuse fields are only flags, not counters in any way.
+     If TRUE it means the channel is in use, and if FALSE it means the channel
+     is up for grabs by one. */
+
+  bool readchannel_inuse;  /* whether the read channel is in use by an easy
+                              handle */
+  bool writechannel_inuse; /* whether the write channel is in use by an easy
+                              handle */
+  struct curl_llist send_pipe; /* List of handles waiting to send on this
+                                  pipeline */
+  struct curl_llist recv_pipe; /* List of handles waiting to read their
+                                  responses on this pipeline */
+  char *master_buffer; /* The master buffer allocated on-demand;
+                          used for pipelining. */
+  size_t read_pos; /* Current read position in the master buffer */
+  size_t buf_len; /* Length of the buffer?? */
+
+
+  curl_seek_callback seek_func; /* function that seeks the input */
+  void *seek_client;            /* pointer to pass to the seek() above */
+
+  /*************** Request - specific items ************/
+
+#if defined(USE_NTLM)
+  struct ntlmdata ntlm;     /* NTLM differs from other authentication schemes
+                               because it authenticates connections, not
+                               single requests! */
+  struct ntlmdata proxyntlm; /* NTLM data for proxy */
+
+#if defined(NTLM_WB_ENABLED)
+  /* used for communication with Samba's winbind daemon helper ntlm_auth */
+  curl_socket_t ntlm_auth_hlpr_socket;
+  pid_t ntlm_auth_hlpr_pid;
+  char *challenge_header;
+  char *response_header;
+#endif
+#endif
+
+  char syserr_buf [256]; /* buffer for Curl_strerror() */
+
+#ifdef CURLRES_ASYNCH
+  /* data used for the asynch name resolve callback */
+  struct Curl_async async;
+#endif
+
+  /* These three are used for chunked-encoding trailer support */
+  char *trailer; /* allocated buffer to store trailer in */
+  int trlMax;    /* allocated buffer size */
+  int trlPos;    /* index of where to store data */
+
+  union {
+    struct ftp_conn ftpc;
+    struct http_conn httpc;
+    struct ssh_conn sshc;
+    struct tftp_state_data *tftpc;
+    struct imap_conn imapc;
+    struct pop3_conn pop3c;
+    struct smtp_conn smtpc;
+    struct rtsp_conn rtspc;
+    struct smb_conn smbc;
+    void *generic; /* RTMP and LDAP use this */
+  } proto;
+
+  int cselect_bits; /* bitmask of socket events */
+  int waitfor;      /* current READ/WRITE bits to wait for */
+
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  int socks5_gssapi_enctype;
+#endif
+
+  /* When this connection is created, store the conditions for the local end
+     bind. This is stored before the actual bind and before any connection is
+     made and will serve the purpose of being used for comparison reasons so
+     that subsequent bound-requested connections aren't accidentally re-using
+     wrong connections. */
+  char *localdev;
+  unsigned short localport;
+  int localportrange;
+  struct http_connect_state *connect_state; /* for HTTP CONNECT */
+  struct connectbundle *bundle; /* The bundle we are member of */
+  int negnpn; /* APLN or NPN TLS negotiated protocol, CURL_HTTP_VERSION* */
+
+#ifdef USE_UNIX_SOCKETS
+  char *unix_domain_socket;
+  bool abstract_unix_socket;
+#endif
+};
+
+/* The end of connectdata. */
+
+/*
+ * Struct to keep statistical and informational data.
+ * All variables in this struct must be initialized/reset in Curl_initinfo().
+ */
+struct PureInfo {
+  int httpcode;  /* Recent HTTP, FTP, RTSP or SMTP response code */
+  int httpproxycode; /* response code from proxy when received separate */
+  int httpversion; /* the http version number X.Y = X*10+Y */
+  long filetime; /* If requested, this is might get set. Set to -1 if the time
+                    was unretrievable. We cannot have this of type time_t,
+                    since time_t is unsigned on several platforms such as
+                    OpenVMS. */
+  bool timecond;  /* set to TRUE if the time condition didn't match, which
+                     thus made the document NOT get fetched */
+  long header_size;  /* size of read header(s) in bytes */
+  long request_size; /* the amount of bytes sent in the request(s) */
+  unsigned long proxyauthavail; /* what proxy auth types were announced */
+  unsigned long httpauthavail;  /* what host auth types were announced */
+  long numconnects; /* how many new connection did libcurl created */
+  char *contenttype; /* the content type of the object */
+  char *wouldredirect; /* URL this would've been redirected to if asked to */
+
+  /* PureInfo members 'conn_primary_ip', 'conn_primary_port', 'conn_local_ip'
+     and, 'conn_local_port' are copied over from the connectdata struct in
+     order to allow curl_easy_getinfo() to return this information even when
+     the session handle is no longer associated with a connection, and also
+     allow curl_easy_reset() to clear this information from the session handle
+     without disturbing information which is still alive, and that might be
+     reused, in the connection cache. */
+
+  char conn_primary_ip[MAX_IPADR_LEN];
+  long conn_primary_port;
+
+  char conn_local_ip[MAX_IPADR_LEN];
+  long conn_local_port;
+
+  const char *conn_scheme;
+  unsigned int conn_protocol;
+
+  struct curl_certinfo certs; /* info about the certs, only populated in
+                                 OpenSSL builds. Asked for with
+                                 CURLOPT_CERTINFO / CURLINFO_CERTINFO */
+};
+
+
+struct Progress {
+  time_t lastshow; /* time() of the last displayed progress meter or NULL to
+                      force redraw at next call */
+  curl_off_t size_dl; /* total expected size */
+  curl_off_t size_ul; /* total expected size */
+  curl_off_t downloaded; /* transferred so far */
+  curl_off_t uploaded; /* transferred so far */
+
+  curl_off_t current_speed; /* uses the currently fastest transfer */
+
+  bool callback;  /* set when progress callback is used */
+  int width; /* screen width at download start */
+  int flags; /* see progress.h */
+
+  time_t timespent;
+
+  curl_off_t dlspeed;
+  curl_off_t ulspeed;
+
+  time_t t_nslookup;
+  time_t t_connect;
+  time_t t_appconnect;
+  time_t t_pretransfer;
+  time_t t_starttransfer;
+  time_t t_redirect;
+
+  struct curltime start;
+  struct curltime t_startsingle;
+  struct curltime t_startop;
+  struct curltime t_acceptdata;
+
+  bool is_t_startransfer_set;
+
+  /* upload speed limit */
+  struct curltime ul_limit_start;
+  curl_off_t ul_limit_size;
+  /* download speed limit */
+  struct curltime dl_limit_start;
+  curl_off_t dl_limit_size;
+
+#define CURR_TIME (5 + 1) /* 6 entries for 5 seconds */
+
+  curl_off_t speeder[ CURR_TIME ];
+  struct curltime speeder_time[ CURR_TIME ];
+  int speeder_c;
+};
+
+typedef enum {
+  HTTPREQ_NONE, /* first in list */
+  HTTPREQ_GET,
+  HTTPREQ_POST,
+  HTTPREQ_POST_FORM, /* we make a difference internally */
+  HTTPREQ_POST_MIME, /* we make a difference internally */
+  HTTPREQ_PUT,
+  HTTPREQ_HEAD,
+  HTTPREQ_OPTIONS,
+  HTTPREQ_CUSTOM,
+  HTTPREQ_LAST /* last in list */
+} Curl_HttpReq;
+
+typedef enum {
+    RTSPREQ_NONE, /* first in list */
+    RTSPREQ_OPTIONS,
+    RTSPREQ_DESCRIBE,
+    RTSPREQ_ANNOUNCE,
+    RTSPREQ_SETUP,
+    RTSPREQ_PLAY,
+    RTSPREQ_PAUSE,
+    RTSPREQ_TEARDOWN,
+    RTSPREQ_GET_PARAMETER,
+    RTSPREQ_SET_PARAMETER,
+    RTSPREQ_RECORD,
+    RTSPREQ_RECEIVE,
+    RTSPREQ_LAST /* last in list */
+} Curl_RtspReq;
+
+/*
+ * Values that are generated, temporary or calculated internally for a
+ * "session handle" must be defined within the 'struct UrlState'.  This struct
+ * will be used within the Curl_easy struct. When the 'Curl_easy'
+ * struct is cloned, this data MUST NOT be copied.
+ *
+ * Remember that any "state" information goes globally for the curl handle.
+ * Session-data MUST be put in the connectdata struct and here.  */
+#define MAX_CURL_USER_LENGTH 256
+#define MAX_CURL_PASSWORD_LENGTH 256
+
+struct auth {
+  unsigned long want;  /* Bitmask set to the authentication methods wanted by
+                          app (with CURLOPT_HTTPAUTH or CURLOPT_PROXYAUTH). */
+  unsigned long picked;
+  unsigned long avail; /* Bitmask for what the server reports to support for
+                          this resource */
+  bool done;  /* TRUE when the auth phase is done and ready to do the *actual*
+                 request */
+  bool multipass; /* TRUE if this is not yet authenticated but within the
+                     auth multipass negotiation */
+  bool iestyle; /* TRUE if digest should be done IE-style or FALSE if it should
+                   be RFC compliant */
+};
+
+struct Curl_http2_dep {
+  struct Curl_http2_dep *next;
+  struct Curl_easy *data;
+};
+
+/*
+ * This struct is for holding data that was attemped to get sent to the user's
+ * callback but is held due to pausing. One instance per type (BOTH, HEADER,
+ * BODY).
+ */
+struct tempbuf {
+  char *buf;  /* allocated buffer to keep data in when a write callback
+                 returns to make the connection paused */
+  size_t len; /* size of the 'tempwrite' allocated buffer */
+  int type;   /* type of the 'tempwrite' buffer as a bitmask that is used with
+                 Curl_client_write() */
+};
+
+/* Timers */
+typedef enum {
+  EXPIRE_100_TIMEOUT,
+  EXPIRE_ASYNC_NAME,
+  EXPIRE_CONNECTTIMEOUT,
+  EXPIRE_DNS_PER_NAME,
+  EXPIRE_HAPPY_EYEBALLS,
+  EXPIRE_MULTI_PENDING,
+  EXPIRE_RUN_NOW,
+  EXPIRE_SPEEDCHECK,
+  EXPIRE_TIMEOUT,
+  EXPIRE_TOOFAST,
+  EXPIRE_LAST /* not an actual timer, used as a marker only */
+} expire_id;
+
+/*
+ * One instance for each timeout an easy handle can set.
+ */
+struct time_node {
+  struct curl_llist_element list;
+  struct curltime time;
+  expire_id eid;
+};
+
+struct UrlState {
+
+  /* Points to the connection cache */
+  struct conncache *conn_cache;
+
+  /* when curl_easy_perform() is called, the multi handle is "owned" by
+     the easy handle so curl_easy_cleanup() on such an easy handle will
+     also close the multi handle! */
+  bool multi_owned_by_easy;
+
+  /* buffers to store authentication data in, as parsed from input options */
+  struct curltime keeps_speed; /* for the progress meter really */
+
+  struct connectdata *lastconnect; /* The last connection, NULL if undefined */
+
+  char *headerbuff; /* allocated buffer to store headers in */
+  size_t headersize;   /* size of the allocation */
+
+  char *buffer; /* download buffer */
+  char uploadbuffer[UPLOAD_BUFSIZE + 1]; /* upload buffer */
+  curl_off_t current_speed;  /* the ProgressShow() function sets this,
+                                bytes / second */
+  bool this_is_a_follow; /* this is a followed Location: request */
+
+  char *first_host; /* host name of the first (not followed) request.
+                       if set, this should be the host name that we will
+                       sent authorization to, no else. Used to make Location:
+                       following not keep sending user+password... This is
+                       strdup() data.
+                    */
+  int first_remote_port; /* remote port of the first (not followed) request */
+  struct curl_ssl_session *session; /* array of 'max_ssl_sessions' size */
+  long sessionage;                  /* number of the most recent session */
+  unsigned int tempcount; /* number of entries in use in tempwrite, 0 - 3 */
+  struct tempbuf tempwrite[3]; /* BOTH, HEADER, BODY */
+  char *scratch; /* huge buffer[set.buffer_size*2] for upload CRLF replacing */
+  bool errorbuf; /* Set to TRUE if the error buffer is already filled in.
+                    This must be set to FALSE every time _easy_perform() is
+                    called. */
+  int os_errno;  /* filled in with errno whenever an error occurs */
+#ifdef HAVE_SIGNAL
+  /* storage for the previous bag^H^H^HSIGPIPE signal handler :-) */
+  void (*prev_signal)(int sig);
+#endif
+  bool allow_port; /* Is set.use_port allowed to take effect or not. This
+                      is always set TRUE when curl_easy_perform() is called. */
+  struct digestdata digest;      /* state data for host Digest auth */
+  struct digestdata proxydigest; /* state data for proxy Digest auth */
+
+#ifdef USE_SPNEGO
+  struct negotiatedata negotiate; /* state data for host Negotiate auth */
+  struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */
+#endif
+
+  struct auth authhost;  /* auth details for host */
+  struct auth authproxy; /* auth details for proxy */
+
+  bool authproblem; /* TRUE if there's some problem authenticating */
+
+  void *resolver; /* resolver state, if it is used in the URL state -
+                     ares_channel f.e. */
+
+#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
+  /* void instead of ENGINE to avoid bleeding OpenSSL into this header */
+  void *engine;
+#endif /* USE_OPENSSL */
+  struct curltime expiretime; /* set this with Curl_expire() only */
+  struct Curl_tree timenode; /* for the splay stuff */
+  struct curl_llist timeoutlist; /* list of pending timeouts */
+  struct time_node expires[EXPIRE_LAST]; /* nodes for each expire type */
+
+  /* a place to store the most recently set FTP entrypath */
+  char *most_recent_ftp_entrypath;
+
+  /* set after initial USER failure, to prevent an authentication loop */
+  bool ftp_trying_alternative;
+  bool wildcardmatch; /* enable wildcard matching */
+  int httpversion;       /* the lowest HTTP version*10 reported by any server
+                            involved in this request */
+  bool expect100header;  /* TRUE if we added Expect: 100-continue */
+
+  bool pipe_broke; /* TRUE if the connection we were pipelined on broke
+                      and we need to restart from the beginning */
+
+#if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__) && \
+    !defined(__SYMBIAN32__)
+/* do FTP line-end conversions on most platforms */
+#define CURL_DO_LINEEND_CONV
+  /* for FTP downloads: track CRLF sequences that span blocks */
+  bool prev_block_had_trailing_cr;
+  /* for FTP downloads: how many CRLFs did we converted to LFs? */
+  curl_off_t crlf_conversions;
+#endif
+  char *pathbuffer;/* allocated buffer to store the URL's path part in */
+  char *path;      /* path to use, points to somewhere within the pathbuffer
+                      area */
+  bool slash_removed; /* set TRUE if the 'path' points to a path where the
+                         initial URL slash separator has been taken off */
+  bool use_range;
+  bool rangestringalloc; /* the range string is malloc()'ed */
+
+  char *range; /* range, if used. See README for detailed specification on
+                  this syntax. */
+  curl_off_t resume_from; /* continue [ftp] transfer from here */
+
+  /* This RTSP state information survives requests and connections */
+  long rtsp_next_client_CSeq; /* the session's next client CSeq */
+  long rtsp_next_server_CSeq; /* the session's next server CSeq */
+  long rtsp_CSeq_recv; /* most recent CSeq received */
+
+  curl_off_t infilesize; /* size of file to upload, -1 means unknown.
+                            Copied from set.filesize at start of operation */
+
+  size_t drain; /* Increased when this stream has data to read, even if its
+                   socket is not necessarily is readable. Decreased when
+                   checked. */
+  bool done; /* set to FALSE when Curl_init_do() is called and set to TRUE
+                when multi_done() is called, to prevent multi_done() to get
+                invoked twice when the multi interface is used. */
+
+  curl_read_callback fread_func; /* read callback/function */
+  void *in;                      /* CURLOPT_READDATA */
+
+  struct Curl_easy *stream_depends_on;
+  bool stream_depends_e; /* set or don't set the Exclusive bit */
+  int stream_weight;
+};
+
+
+/*
+ * This 'DynamicStatic' struct defines dynamic states that actually change
+ * values in the 'UserDefined' area, which MUST be taken into consideration
+ * if the UserDefined struct is cloned or similar. You can probably just
+ * copy these, but each one indicate a special action on other data.
+ */
+
+struct DynamicStatic {
+  char *url;        /* work URL, copied from UserDefined */
+  bool url_alloc;   /* URL string is malloc()'ed */
+  char *referer;    /* referer string */
+  bool referer_alloc; /* referer sting is malloc()ed */
+  struct curl_slist *cookielist; /* list of cookie files set by
+                                    curl_easy_setopt(COOKIEFILE) calls */
+  struct curl_slist *resolve; /* set to point to the set.resolve list when
+                                 this should be dealt with in pretransfer */
+};
+
+/*
+ * This 'UserDefined' struct must only contain data that is set once to go
+ * for many (perhaps) independent connections. Values that are generated or
+ * calculated internally for the "session handle" MUST be defined within the
+ * 'struct UrlState' instead. The only exceptions MUST note the changes in
+ * the 'DynamicStatic' struct.
+ * Character pointer fields point to dynamic storage, unless otherwise stated.
+ */
+
+struct Curl_multi;    /* declared and used only in multi.c */
+
+enum dupstring {
+  STRING_CERT_ORIG,       /* client certificate file name */
+  STRING_CERT_PROXY,      /* client certificate file name */
+  STRING_CERT_TYPE_ORIG,  /* format for certificate (default: PEM)*/
+  STRING_CERT_TYPE_PROXY, /* format for certificate (default: PEM)*/
+  STRING_COOKIE,          /* HTTP cookie string to send */
+  STRING_COOKIEJAR,       /* dump all cookies to this file */
+  STRING_CUSTOMREQUEST,   /* HTTP/FTP/RTSP request/method to use */
+  STRING_DEFAULT_PROTOCOL, /* Protocol to use when the URL doesn't specify */
+  STRING_DEVICE,          /* local network interface/address to use */
+  STRING_ENCODING,        /* Accept-Encoding string */
+  STRING_FTP_ACCOUNT,     /* ftp account data */
+  STRING_FTP_ALTERNATIVE_TO_USER, /* command to send if USER/PASS fails */
+  STRING_FTPPORT,         /* port to send with the FTP PORT command */
+  STRING_KEY_ORIG,        /* private key file name */
+  STRING_KEY_PROXY,       /* private key file name */
+  STRING_KEY_PASSWD_ORIG, /* plain text private key password */
+  STRING_KEY_PASSWD_PROXY, /* plain text private key password */
+  STRING_KEY_TYPE_ORIG,   /* format for private key (default: PEM) */
+  STRING_KEY_TYPE_PROXY,  /* format for private key (default: PEM) */
+  STRING_KRB_LEVEL,       /* krb security level */
+  STRING_NETRC_FILE,      /* if not NULL, use this instead of trying to find
+                             $HOME/.netrc */
+  STRING_PROXY,           /* proxy to use */
+  STRING_PRE_PROXY,       /* pre socks proxy to use */
+  STRING_SET_RANGE,       /* range, if used */
+  STRING_SET_REFERER,     /* custom string for the HTTP referer field */
+  STRING_SET_URL,         /* what original URL to work on */
+  STRING_SSL_CAPATH_ORIG, /* CA directory name (doesn't work on windows) */
+  STRING_SSL_CAPATH_PROXY, /* CA directory name (doesn't work on windows) */
+  STRING_SSL_CAFILE_ORIG, /* certificate file to verify peer against */
+  STRING_SSL_CAFILE_PROXY, /* certificate file to verify peer against */
+  STRING_SSL_PINNEDPUBLICKEY_ORIG, /* public key file to verify peer against */
+  STRING_SSL_PINNEDPUBLICKEY_PROXY, /* public key file to verify proxy */
+  STRING_SSL_CIPHER_LIST_ORIG, /* list of ciphers to use */
+  STRING_SSL_CIPHER_LIST_PROXY, /* list of ciphers to use */
+  STRING_SSL_EGDSOCKET,   /* path to file containing the EGD daemon socket */
+  STRING_SSL_RANDOM_FILE, /* path to file containing "random" data */
+  STRING_USERAGENT,       /* User-Agent string */
+  STRING_SSL_CRLFILE_ORIG, /* crl file to check certificate */
+  STRING_SSL_CRLFILE_PROXY, /* crl file to check certificate */
+  STRING_SSL_ISSUERCERT_ORIG, /* issuer cert file to check certificate */
+  STRING_SSL_ISSUERCERT_PROXY, /* issuer cert file to check certificate */
+  STRING_USERNAME,        /* <username>, if used */
+  STRING_PASSWORD,        /* <password>, if used */
+  STRING_OPTIONS,         /* <options>, if used */
+  STRING_PROXYUSERNAME,   /* Proxy <username>, if used */
+  STRING_PROXYPASSWORD,   /* Proxy <password>, if used */
+  STRING_NOPROXY,         /* List of hosts which should not use the proxy, if
+                             used */
+  STRING_RTSP_SESSION_ID, /* Session ID to use */
+  STRING_RTSP_STREAM_URI, /* Stream URI for this request */
+  STRING_RTSP_TRANSPORT,  /* Transport for this session */
+#ifdef USE_LIBSSH2
+  STRING_SSH_PRIVATE_KEY, /* path to the private key file for auth */
+  STRING_SSH_PUBLIC_KEY,  /* path to the public key file for auth */
+  STRING_SSH_HOST_PUBLIC_KEY_MD5, /* md5 of host public key in ascii hex */
+  STRING_SSH_KNOWNHOSTS,  /* file name of knownhosts file */
+#endif
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  STRING_PROXY_SERVICE_NAME, /* Proxy service name */
+#endif
+#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \
+  defined(USE_SPNEGO) || defined(HAVE_GSSAPI)
+  STRING_SERVICE_NAME,    /* Service name */
+#endif
+  STRING_MAIL_FROM,
+  STRING_MAIL_AUTH,
+
+#ifdef USE_TLS_SRP
+  STRING_TLSAUTH_USERNAME_ORIG,  /* TLS auth <username> */
+  STRING_TLSAUTH_USERNAME_PROXY, /* TLS auth <username> */
+  STRING_TLSAUTH_PASSWORD_ORIG,  /* TLS auth <password> */
+  STRING_TLSAUTH_PASSWORD_PROXY, /* TLS auth <password> */
+#endif
+  STRING_BEARER,                /* <bearer>, if used */
+#ifdef USE_UNIX_SOCKETS
+  STRING_UNIX_SOCKET_PATH,      /* path to Unix socket, if used */
+#endif
+  STRING_TARGET,                /* CURLOPT_REQUEST_TARGET */
+  /* -- end of zero-terminated strings -- */
+
+  STRING_LASTZEROTERMINATED,
+
+  /* -- below this are pointers to binary data that cannot be strdup'ed.
+     Each such pointer must be added manually to Curl_dupset() --- */
+
+  STRING_COPYPOSTFIELDS,  /* if POST, set the fields' values here */
+
+  STRING_LAST /* not used, just an end-of-list marker */
+};
+
+struct UserDefined {
+  FILE *err;         /* the stderr user data goes here */
+  void *debugdata;   /* the data that will be passed to fdebug */
+  char *errorbuffer; /* (Static) store failure messages in here */
+  long proxyport; /* If non-zero, use this port number by default. If the
+                     proxy string features a ":[port]" that one will override
+                     this. */
+  void *out;         /* CURLOPT_WRITEDATA */
+  void *in_set;      /* CURLOPT_READDATA */
+  void *writeheader; /* write the header to this if non-NULL */
+  void *rtp_out;     /* write RTP to this if non-NULL */
+  long use_port;     /* which port to use (when not using default) */
+  unsigned long httpauth;  /* kind of HTTP authentication to use (bitmask) */
+  unsigned long proxyauth; /* kind of proxy authentication to use (bitmask) */
+  unsigned long socks5auth;/* kind of SOCKS5 authentication to use (bitmask) */
+  long followlocation; /* as in HTTP Location: */
+  long maxredirs;    /* maximum no. of http(s) redirects to follow, set to -1
+                        for infinity */
+
+  int keep_post;     /* keep POSTs as POSTs after a 30x request; each
+                        bit represents a request, from 301 to 303 */
+  bool free_referer; /* set TRUE if 'referer' points to a string we
+                        allocated */
+  void *postfields;  /* if POST, set the fields' values here */
+  curl_seek_callback seek_func;      /* function that seeks the input */
+  curl_off_t postfieldsize; /* if POST, this might have a size to use instead
+                               of strlen(), and then the data *may* be binary
+                               (contain zero bytes) */
+  unsigned short localport; /* local port number to bind to */
+  int localportrange; /* number of additional port numbers to test in case the
+                         'localport' one can't be bind()ed */
+  curl_write_callback fwrite_func;   /* function that stores the output */
+  curl_write_callback fwrite_header; /* function that stores headers */
+  curl_write_callback fwrite_rtp;    /* function that stores interleaved RTP */
+  curl_read_callback fread_func_set; /* function that reads the input */
+  int is_fread_set; /* boolean, has read callback been set to non-NULL? */
+  int is_fwrite_set; /* boolean, has write callback been set to non-NULL? */
+  curl_progress_callback fprogress; /* OLD and deprecated progress callback  */
+  curl_xferinfo_callback fxferinfo; /* progress callback */
+  curl_debug_callback fdebug;      /* function that write informational data */
+  curl_ioctl_callback ioctl_func;  /* function for I/O control */
+  curl_sockopt_callback fsockopt;  /* function for setting socket options */
+  void *sockopt_client; /* pointer to pass to the socket options callback */
+  curl_opensocket_callback fopensocket; /* function for checking/translating
+                                           the address and opening the
+                                           socket */
+  void *opensocket_client;
+  curl_closesocket_callback fclosesocket; /* function for closing the
+                                             socket */
+  void *closesocket_client;
+
+  void *seek_client;    /* pointer to pass to the seek callback */
+  /* the 3 curl_conv_callback functions below are used on non-ASCII hosts */
+  /* function to convert from the network encoding: */
+  curl_conv_callback convfromnetwork;
+  /* function to convert to the network encoding: */
+  curl_conv_callback convtonetwork;
+  /* function to convert from UTF-8 encoding: */
+  curl_conv_callback convfromutf8;
+
+  void *progress_client; /* pointer to pass to the progress callback */
+  void *ioctl_client;   /* pointer to pass to the ioctl callback */
+  long timeout;         /* in milliseconds, 0 means no timeout */
+  long connecttimeout;  /* in milliseconds, 0 means no timeout */
+  long accepttimeout;   /* in milliseconds, 0 means no timeout */
+  long server_response_timeout; /* in milliseconds, 0 means no timeout */
+  long tftp_blksize;    /* in bytes, 0 means use default */
+  bool tftp_no_options; /* do not send TFTP options requests */
+  curl_off_t filesize;  /* size of file to upload, -1 means unknown */
+  long low_speed_limit; /* bytes/second */
+  long low_speed_time;  /* number of seconds */
+  curl_off_t max_send_speed; /* high speed limit in bytes/second for upload */
+  curl_off_t max_recv_speed; /* high speed limit in bytes/second for
+                                download */
+  curl_off_t set_resume_from;  /* continue [ftp] transfer from here */
+  struct curl_slist *headers; /* linked list of extra headers */
+  struct curl_slist *proxyheaders; /* linked list of extra CONNECT headers */
+  struct curl_httppost *httppost;  /* linked list of old POST data */
+  curl_mimepart mimepost;  /* MIME/POST data. */
+  bool sep_headers;     /* handle host and proxy headers separately */
+  bool cookiesession;   /* new cookie session? */
+  bool crlf;            /* convert crlf on ftp upload(?) */
+  struct curl_slist *quote;     /* after connection is established */
+  struct curl_slist *postquote; /* after the transfer */
+  struct curl_slist *prequote; /* before the transfer, after type */
+  struct curl_slist *source_quote;  /* 3rd party quote */
+  struct curl_slist *source_prequote;  /* in 3rd party transfer mode - before
+                                          the transfer on source host */
+  struct curl_slist *source_postquote; /* in 3rd party transfer mode - after
+                                          the transfer on source host */
+  struct curl_slist *telnet_options; /* linked list of telnet options */
+  struct curl_slist *resolve;     /* list of names to add/remove from
+                                     DNS cache */
+  struct curl_slist *connect_to; /* list of host:port mappings to override
+                                    the hostname and port to connect to */
+  curl_TimeCond timecondition; /* kind of time/date comparison */
+  time_t timevalue;       /* what time to compare with */
+  Curl_HttpReq httpreq;   /* what kind of HTTP request (if any) is this */
+  long httpversion; /* when non-zero, a specific HTTP version requested to
+                       be used in the library's request(s) */
+  bool strip_path_slash; /* strip off initial slash from path */
+  struct ssl_config_data ssl;  /* user defined SSL stuff */
+  struct ssl_config_data proxy_ssl;  /* user defined SSL stuff for proxy */
+  struct ssl_general_config general_ssl; /* general user defined SSL stuff */
+  curl_proxytype proxytype; /* what kind of proxy that is in use */
+  long dns_cache_timeout; /* DNS cache timeout */
+  long buffer_size;      /* size of receive buffer to use */
+  void *private_data; /* application-private data */
+
+  struct curl_slist *http200aliases; /* linked list of aliases for http200 */
+
+  long ipver; /* the CURL_IPRESOLVE_* defines in the public header file
+                 0 - whatever, 1 - v2, 2 - v6 */
+
+  curl_off_t max_filesize; /* Maximum file size to download */
+
+  curl_ftpfile ftp_filemethod; /* how to get to a file when FTP is used  */
+
+  int ftp_create_missing_dirs; /* 1 - create directories that don't exist
+                                  2 - the same but also allow MKD to fail once
+                               */
+
+  curl_sshkeycallback ssh_keyfunc; /* key matching callback */
+  void *ssh_keyfunc_userp;         /* custom pointer to callback */
+  bool ssh_compression;            /* enable SSH compression */
+
+/* Here follows boolean settings that define how to behave during
+   this session. They are STATIC, set by libcurl users or at least initially
+   and they don't change during operations. */
+
+  bool printhost;        /* printing host name in debug info */
+  bool get_filetime;     /* get the time and get of the remote file */
+  bool tunnel_thru_httpproxy; /* use CONNECT through a HTTP proxy */
+  bool prefer_ascii;     /* ASCII rather than binary */
+  bool ftp_append;       /* append, not overwrite, on upload */
+  bool ftp_list_only;    /* switch FTP command for listing directories */
+  bool ftp_use_port;     /* use the FTP PORT command */
+  bool hide_progress;    /* don't use the progress meter */
+  bool http_fail_on_error;  /* fail on HTTP error codes >= 400 */
+  bool http_keep_sending_on_error; /* for HTTP status codes >= 300 */
+  bool http_follow_location; /* follow HTTP redirects */
+  bool http_transfer_encoding; /* request compressed HTTP transfer-encoding */
+  bool http_disable_hostname_check_before_authentication;
+  bool include_header;   /* include received protocol headers in data output */
+  bool http_set_referer; /* is a custom referer used */
+  bool http_auto_referer; /* set "correct" referer when following location: */
+  bool opt_no_body;      /* as set with CURLOPT_NOBODY */
+  bool upload;           /* upload request */
+  enum CURL_NETRC_OPTION
+       use_netrc;        /* defined in include/curl.h */
+  bool verbose;          /* output verbosity */
+  bool krb;              /* Kerberos connection requested */
+  bool reuse_forbid;     /* forbidden to be reused, close after use */
+  bool reuse_fresh;      /* do not re-use an existing connection  */
+  bool ftp_use_epsv;     /* if EPSV is to be attempted or not */
+  bool ftp_use_eprt;     /* if EPRT is to be attempted or not */
+  bool ftp_use_pret;     /* if PRET is to be used before PASV or not */
+
+  curl_usessl use_ssl;   /* if AUTH TLS is to be attempted etc, for FTP or
+                            IMAP or POP3 or others! */
+  curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */
+  curl_ftpccc ftp_ccc;   /* FTP CCC options */
+  bool no_signal;        /* do not use any signal/alarm handler */
+  bool global_dns_cache; /* subject for future removal */
+  bool tcp_nodelay;      /* whether to enable TCP_NODELAY or not */
+  bool ignorecl;         /* ignore content length */
+  bool ftp_skip_ip;      /* skip the IP address the FTP server passes on to
+                            us */
+  bool connect_only;     /* make connection, let application use the socket */
+  long ssh_auth_types;   /* allowed SSH auth types */
+  bool http_te_skip;     /* pass the raw body data to the user, even when
+                            transfer-encoded (chunked, compressed) */
+  bool http_ce_skip;     /* pass the raw body data to the user, even when
+                            content-encoded (chunked, compressed) */
+  long new_file_perms;    /* Permissions to use when creating remote files */
+  long new_directory_perms; /* Permissions to use when creating remote dirs */
+  bool proxy_transfer_mode; /* set transfer mode (;type=<a|i>) when doing FTP
+                               via an HTTP proxy */
+  char *str[STRING_LAST]; /* array of strings, pointing to allocated memory */
+  unsigned int scope_id;  /* Scope id for IPv6 */
+  long allowed_protocols;
+  long redir_protocols;
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  bool socks5_gssapi_nec; /* Flag to support NEC SOCKS5 server */
+#endif
+  struct curl_slist *mail_rcpt; /* linked list of mail recipients */
+  bool sasl_ir;         /* Enable/disable SASL initial response */
+  /* Common RTSP header options */
+  Curl_RtspReq rtspreq; /* RTSP request type */
+  long rtspversion; /* like httpversion, for RTSP */
+  bool wildcard_enabled; /* enable wildcard matching */
+  curl_chunk_bgn_callback chunk_bgn; /* called before part of transfer
+                                        starts */
+  curl_chunk_end_callback chunk_end; /* called after part transferring
+                                        stopped */
+  curl_fnmatch_callback fnmatch; /* callback to decide which file corresponds
+                                    to pattern (e.g. if WILDCARDMATCH is on) */
+  void *fnmatch_data;
+
+  long gssapi_delegation; /* GSS-API credential delegation, see the
+                             documentation of CURLOPT_GSSAPI_DELEGATION */
+
+  bool tcp_keepalive;    /* use TCP keepalives */
+  long tcp_keepidle;     /* seconds in idle before sending keepalive probe */
+  long tcp_keepintvl;    /* seconds between TCP keepalive probes */
+  bool tcp_fastopen;     /* use TCP Fast Open */
+
+  size_t maxconnects;  /* Max idle connections in the connection cache */
+
+  bool ssl_enable_npn;      /* TLS NPN extension? */
+  bool ssl_enable_alpn;     /* TLS ALPN extension? */
+  bool path_as_is;      /* allow dotdots? */
+  bool pipewait;        /* wait for pipe/multiplex status before starting a
+                           new connection */
+  long expect_100_timeout; /* in milliseconds */
+  bool suppress_connect_headers;  /* suppress proxy CONNECT response headers
+                                     from user callbacks */
+
+  struct Curl_easy *stream_depends_on;
+  bool stream_depends_e; /* set or don't set the Exclusive bit */
+  int stream_weight;
+
+  struct Curl_http2_dep *stream_dependents;
+
+  bool abstract_unix_socket;
+};
+
+struct Names {
+  struct curl_hash *hostcache;
+  enum {
+    HCACHE_NONE,    /* not pointing to anything */
+    HCACHE_GLOBAL,  /* points to the (shrug) global one */
+    HCACHE_MULTI,   /* points to a shared one in the multi handle */
+    HCACHE_SHARED   /* points to a shared one in a shared object */
+  } hostcachetype;
+};
+
+/*
+ * The 'connectdata' struct MUST have all the connection oriented stuff as we
+ * may have several simultaneous connections and connection structs in memory.
+ *
+ * The 'struct UserDefined' must only contain data that is set once to go for
+ * many (perhaps) independent connections. Values that are generated or
+ * calculated internally for the "session handle" must be defined within the
+ * 'struct UrlState' instead.
+ */
+
+struct Curl_easy {
+  /* first, two fields for the linked list of these */
+  struct Curl_easy *next;
+  struct Curl_easy *prev;
+
+  struct connectdata *easy_conn;     /* the "unit's" connection */
+  struct curl_llist_element connect_queue;
+  struct curl_llist_element pipeline_queue;
+
+  CURLMstate mstate;  /* the handle's state */
+  CURLcode result;   /* previous result */
+
+  struct Curl_message msg; /* A single posted message. */
+
+  /* Array with the plain socket numbers this handle takes care of, in no
+     particular order. Note that all sockets are added to the sockhash, where
+     the state etc are also kept. This array is mostly used to detect when a
+     socket is to be removed from the hash. See singlesocket(). */
+  curl_socket_t sockets[MAX_SOCKSPEREASYHANDLE];
+  int numsocks;
+
+  struct Names dns;
+  struct Curl_multi *multi;    /* if non-NULL, points to the multi handle
+                                  struct to which this "belongs" when used by
+                                  the multi interface */
+  struct Curl_multi *multi_easy; /* if non-NULL, points to the multi handle
+                                    struct to which this "belongs" when used
+                                    by the easy interface */
+  struct Curl_share *share;    /* Share, handles global variable mutexing */
+  struct SingleRequest req;    /* Request-specific data */
+  struct UserDefined set;      /* values set by the libcurl user */
+  struct DynamicStatic change; /* possibly modified userdefined data */
+  struct CookieInfo *cookies;  /* the cookies, read from files and servers.
+                                  NOTE that the 'cookie' field in the
+                                  UserDefined struct defines if the "engine"
+                                  is to be used or not. */
+  struct Progress progress;    /* for all the progress meter data */
+  struct UrlState state;       /* struct for fields used for state info and
+                                  other dynamic purposes */
+  struct WildcardData wildcard; /* wildcard download state info */
+  struct PureInfo info;        /* stats, reports and info data */
+  struct curl_tlssessioninfo tsi; /* Information about the TLS session, only
+                                     valid after a client has asked for it */
+#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
+  iconv_t outbound_cd;         /* for translating to the network encoding */
+  iconv_t inbound_cd;          /* for translating from the network encoding */
+  iconv_t utf8_cd;             /* for translating to UTF8 */
+#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
+  unsigned int magic;          /* set to a CURLEASY_MAGIC_NUMBER */
+};
+
+#define LIBCURL_NAME "libcurl"
+
+#endif /* HEADER_CURL_URLDATA_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/cleartext.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/cleartext.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/cleartext.c	(revision 331)
@@ -0,0 +1,165 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC4616 PLAIN authentication
+ * Draft   LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+#include "urldata.h"
+
+#include "vauth/vauth.h"
+#include "curl_base64.h"
+#include "curl_md5.h"
+#include "warnless.h"
+#include "strtok.h"
+#include "sendf.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * Curl_auth_create_plain_message()
+ *
+ * This is used to generate an already encoded PLAIN message ready
+ * for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * userp   [in]     - The user name.
+ * passdwp [in]     - The user's password.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_auth_create_plain_message(struct Curl_easy *data,
+                                        const char *userp,
+                                        const char *passwdp,
+                                        char **outptr, size_t *outlen)
+{
+  CURLcode result;
+  char *plainauth;
+  size_t ulen;
+  size_t plen;
+  size_t plainlen;
+
+  *outlen = 0;
+  *outptr = NULL;
+  ulen = strlen(userp);
+  plen = strlen(passwdp);
+
+  /* Compute binary message length, checking for overflows. */
+  plainlen = 2 * ulen;
+  if(plainlen < ulen)
+    return CURLE_OUT_OF_MEMORY;
+  plainlen += plen;
+  if(plainlen < plen)
+    return CURLE_OUT_OF_MEMORY;
+  plainlen += 2;
+  if(plainlen < 2)
+    return CURLE_OUT_OF_MEMORY;
+
+  plainauth = malloc(plainlen);
+  if(!plainauth)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Calculate the reply */
+  memcpy(plainauth, userp, ulen);
+  plainauth[ulen] = '\0';
+  memcpy(plainauth + ulen + 1, userp, ulen);
+  plainauth[2 * ulen + 1] = '\0';
+  memcpy(plainauth + 2 * ulen + 2, passwdp, plen);
+
+  /* Base64 encode the reply */
+  result = Curl_base64_encode(data, plainauth, plainlen, outptr, outlen);
+  free(plainauth);
+
+  return result;
+}
+
+/*
+ * Curl_auth_create_login_message()
+ *
+ * This is used to generate an already encoded LOGIN message containing the
+ * user name or password ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * valuep  [in]     - The user name or user's password.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_auth_create_login_message(struct Curl_easy *data,
+                                        const char *valuep, char **outptr,
+                                        size_t *outlen)
+{
+  size_t vlen = strlen(valuep);
+
+  if(!vlen) {
+    /* Calculate an empty reply */
+    *outptr = strdup("=");
+    if(*outptr) {
+      *outlen = (size_t) 1;
+      return CURLE_OK;
+    }
+
+    *outlen = 0;
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* Base64 encode the value */
+  return Curl_base64_encode(data, valuep, vlen, outptr, outlen);
+}
+
+/*
+ * Curl_auth_create_external_message()
+ *
+ * This is used to generate an already encoded EXTERNAL message containing
+ * the user name ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * user    [in]     - The user name.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_auth_create_external_message(struct Curl_easy *data,
+                                           const char *user, char **outptr,
+                                           size_t *outlen)
+{
+  /* This is the same formatting as the login message */
+  return Curl_auth_create_login_message(data, user, outptr, outlen);
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/cram.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/cram.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/cram.c	(revision 331)
@@ -0,0 +1,138 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC2195 CRAM-MD5 authentication
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+
+#include <curl/curl.h>
+#include "urldata.h"
+
+#include "vauth/vauth.h"
+#include "curl_base64.h"
+#include "curl_hmac.h"
+#include "curl_md5.h"
+#include "warnless.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * Curl_auth_decode_cram_md5_message()
+ *
+ * This is used to decode an already encoded CRAM-MD5 challenge message.
+ *
+ * Parameters:
+ *
+ * chlg64  [in]     - The base64 encoded challenge message.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_auth_decode_cram_md5_message(const char *chlg64, char **outptr,
+                                           size_t *outlen)
+{
+  CURLcode result = CURLE_OK;
+  size_t chlg64len = strlen(chlg64);
+
+  *outptr = NULL;
+  *outlen = 0;
+
+  /* Decode the challenge if necessary */
+  if(chlg64len && *chlg64 != '=')
+    result = Curl_base64_decode(chlg64, (unsigned char **) outptr, outlen);
+
+  return result;
+}
+
+/*
+ * Curl_auth_create_cram_md5_message()
+ *
+ * This is used to generate an already encoded CRAM-MD5 response message ready
+ * for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * chlg    [in]     - The challenge.
+ * userp   [in]     - The user name.
+ * passdwp [in]     - The user's password.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_auth_create_cram_md5_message(struct Curl_easy *data,
+                                           const char *chlg,
+                                           const char *userp,
+                                           const char *passwdp,
+                                           char **outptr, size_t *outlen)
+{
+  CURLcode result = CURLE_OK;
+  size_t chlglen = 0;
+  HMAC_context *ctxt;
+  unsigned char digest[MD5_DIGEST_LEN];
+  char *response;
+
+  if(chlg)
+    chlglen = strlen(chlg);
+
+  /* Compute the digest using the password as the key */
+  ctxt = Curl_HMAC_init(Curl_HMAC_MD5,
+                        (const unsigned char *) passwdp,
+                        curlx_uztoui(strlen(passwdp)));
+  if(!ctxt)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Update the digest with the given challenge */
+  if(chlglen > 0)
+    Curl_HMAC_update(ctxt, (const unsigned char *) chlg,
+                     curlx_uztoui(chlglen));
+
+  /* Finalise the digest */
+  Curl_HMAC_final(ctxt, digest);
+
+  /* Generate the response */
+  response = aprintf(
+    "%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+    userp, digest[0], digest[1], digest[2], digest[3], digest[4],
+    digest[5], digest[6], digest[7], digest[8], digest[9], digest[10],
+    digest[11], digest[12], digest[13], digest[14], digest[15]);
+  if(!response)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Base64 encode the response */
+  result = Curl_base64_encode(data, response, 0, outptr, outlen);
+
+  free(response);
+
+  return result;
+}
+
+#endif /* !CURL_DISABLE_CRYPTO_AUTH */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/digest.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/digest.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/digest.c	(revision 331)
@@ -0,0 +1,1003 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC2831 DIGEST-MD5 authentication
+ * RFC7616 DIGEST-SHA256, DIGEST-SHA512-256 authentication
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+
+#include <curl/curl.h>
+
+#include "vauth/vauth.h"
+#include "vauth/digest.h"
+#include "urldata.h"
+#include "curl_base64.h"
+#include "curl_hmac.h"
+#include "curl_md5.h"
+#include "curl_sha256.h"
+#include "vtls/vtls.h"
+#include "warnless.h"
+#include "strtok.h"
+#include "strcase.h"
+#include "non-ascii.h" /* included for Curl_convert_... prototypes */
+#include "curl_printf.h"
+#include "rand.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#if !defined(USE_WINDOWS_SSPI)
+#define DIGEST_QOP_VALUE_AUTH             (1 << 0)
+#define DIGEST_QOP_VALUE_AUTH_INT         (1 << 1)
+#define DIGEST_QOP_VALUE_AUTH_CONF        (1 << 2)
+
+#define DIGEST_QOP_VALUE_STRING_AUTH      "auth"
+#define DIGEST_QOP_VALUE_STRING_AUTH_INT  "auth-int"
+#define DIGEST_QOP_VALUE_STRING_AUTH_CONF "auth-conf"
+
+/* The CURL_OUTPUT_DIGEST_CONV macro below is for non-ASCII machines.
+   It converts digest text to ASCII so the MD5 will be correct for
+   what ultimately goes over the network.
+*/
+#define CURL_OUTPUT_DIGEST_CONV(a, b) \
+  result = Curl_convert_to_network(a, (char *)b, strlen((const char *)b)); \
+  if(result) { \
+    free(b); \
+    return result; \
+  }
+#endif /* !USE_WINDOWS_SSPI */
+
+bool Curl_auth_digest_get_pair(const char *str, char *value, char *content,
+                               const char **endptr)
+{
+  int c;
+  bool starts_with_quote = FALSE;
+  bool escape = FALSE;
+
+  for(c = DIGEST_MAX_VALUE_LENGTH - 1; (*str && (*str != '=') && c--);)
+    *value++ = *str++;
+  *value = 0;
+
+  if('=' != *str++)
+    /* eek, no match */
+    return FALSE;
+
+  if('\"' == *str) {
+    /* This starts with a quote so it must end with one as well! */
+    str++;
+    starts_with_quote = TRUE;
+  }
+
+  for(c = DIGEST_MAX_CONTENT_LENGTH - 1; *str && c--; str++) {
+    switch(*str) {
+    case '\\':
+      if(!escape) {
+        /* possibly the start of an escaped quote */
+        escape = TRUE;
+        *content++ = '\\'; /* Even though this is an escape character, we still
+                              store it as-is in the target buffer */
+        continue;
+      }
+      break;
+
+    case ',':
+      if(!starts_with_quote) {
+        /* This signals the end of the content if we didn't get a starting
+           quote and then we do "sloppy" parsing */
+        c = 0; /* the end */
+        continue;
+      }
+      break;
+
+    case '\r':
+    case '\n':
+      /* end of string */
+      c = 0;
+      continue;
+
+    case '\"':
+      if(!escape && starts_with_quote) {
+        /* end of string */
+        c = 0;
+        continue;
+      }
+      break;
+    }
+
+    escape = FALSE;
+    *content++ = *str;
+  }
+
+  *content = 0;
+  *endptr = str;
+
+  return TRUE;
+}
+
+#if !defined(USE_WINDOWS_SSPI)
+/* Convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string*/
+static void auth_digest_md5_to_ascii(unsigned char *source, /* 16 bytes */
+                                     unsigned char *dest) /* 33 bytes */
+{
+  int i;
+  for(i = 0; i < 16; i++)
+    snprintf((char *) &dest[i * 2], 3, "%02x", source[i]);
+}
+
+/* Convert sha256 chunk to RFC7616 -suitable ascii string*/
+static void auth_digest_sha256_to_ascii(unsigned char *source, /* 32 bytes */
+                                     unsigned char *dest) /* 65 bytes */
+{
+  int i;
+  for(i = 0; i < 32; i++)
+    snprintf((char *) &dest[i * 2], 3, "%02x", source[i]);
+}
+
+/* Perform quoted-string escaping as described in RFC2616 and its errata */
+static char *auth_digest_string_quoted(const char *source)
+{
+  char *dest, *d;
+  const char *s = source;
+  size_t n = 1; /* null terminator */
+
+  /* Calculate size needed */
+  while(*s) {
+    ++n;
+    if(*s == '"' || *s == '\\') {
+      ++n;
+    }
+    ++s;
+  }
+
+  dest = malloc(n);
+  if(dest) {
+    s = source;
+    d = dest;
+    while(*s) {
+      if(*s == '"' || *s == '\\') {
+        *d++ = '\\';
+      }
+      *d++ = *s++;
+    }
+    *d = 0;
+  }
+
+  return dest;
+}
+
+/* Retrieves the value for a corresponding key from the challenge string
+ * returns TRUE if the key could be found, FALSE if it does not exists
+ */
+static bool auth_digest_get_key_value(const char *chlg,
+                                      const char *key,
+                                      char *value,
+                                      size_t max_val_len,
+                                      char end_char)
+{
+  char *find_pos;
+  size_t i;
+
+  find_pos = strstr(chlg, key);
+  if(!find_pos)
+    return FALSE;
+
+  find_pos += strlen(key);
+
+  for(i = 0; *find_pos && *find_pos != end_char && i < max_val_len - 1; ++i)
+    value[i] = *find_pos++;
+  value[i] = '\0';
+
+  return TRUE;
+}
+
+static CURLcode auth_digest_get_qop_values(const char *options, int *value)
+{
+  char *tmp;
+  char *token;
+  char *tok_buf = NULL;
+
+  /* Initialise the output */
+  *value = 0;
+
+  /* Tokenise the list of qop values. Use a temporary clone of the buffer since
+     strtok_r() ruins it. */
+  tmp = strdup(options);
+  if(!tmp)
+    return CURLE_OUT_OF_MEMORY;
+
+  token = strtok_r(tmp, ",", &tok_buf);
+  while(token != NULL) {
+    if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH))
+      *value |= DIGEST_QOP_VALUE_AUTH;
+    else if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH_INT))
+      *value |= DIGEST_QOP_VALUE_AUTH_INT;
+    else if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH_CONF))
+      *value |= DIGEST_QOP_VALUE_AUTH_CONF;
+
+    token = strtok_r(NULL, ",", &tok_buf);
+  }
+
+  free(tmp);
+
+  return CURLE_OK;
+}
+
+/*
+ * auth_decode_digest_md5_message()
+ *
+ * This is used internally to decode an already encoded DIGEST-MD5 challenge
+ * message into the separate attributes.
+ *
+ * Parameters:
+ *
+ * chlg64  [in]     - The base64 encoded challenge message.
+ * nonce   [in/out] - The buffer where the nonce will be stored.
+ * nlen    [in]     - The length of the nonce buffer.
+ * realm   [in/out] - The buffer where the realm will be stored.
+ * rlen    [in]     - The length of the realm buffer.
+ * alg     [in/out] - The buffer where the algorithm will be stored.
+ * alen    [in]     - The length of the algorithm buffer.
+ * qop     [in/out] - The buffer where the qop-options will be stored.
+ * qlen    [in]     - The length of the qop buffer.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode auth_decode_digest_md5_message(const char *chlg64,
+                                               char *nonce, size_t nlen,
+                                               char *realm, size_t rlen,
+                                               char *alg, size_t alen,
+                                               char *qop, size_t qlen)
+{
+  CURLcode result = CURLE_OK;
+  unsigned char *chlg = NULL;
+  size_t chlglen = 0;
+  size_t chlg64len = strlen(chlg64);
+
+  /* Decode the base-64 encoded challenge message */
+  if(chlg64len && *chlg64 != '=') {
+    result = Curl_base64_decode(chlg64, &chlg, &chlglen);
+    if(result)
+      return result;
+  }
+
+  /* Ensure we have a valid challenge message */
+  if(!chlg)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  /* Retrieve nonce string from the challenge */
+  if(!auth_digest_get_key_value((char *) chlg, "nonce=\"", nonce, nlen,
+                                '\"')) {
+    free(chlg);
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  /* Retrieve realm string from the challenge */
+  if(!auth_digest_get_key_value((char *) chlg, "realm=\"", realm, rlen,
+                                '\"')) {
+    /* Challenge does not have a realm, set empty string [RFC2831] page 6 */
+    strcpy(realm, "");
+  }
+
+  /* Retrieve algorithm string from the challenge */
+  if(!auth_digest_get_key_value((char *) chlg, "algorithm=", alg, alen, ',')) {
+    free(chlg);
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  /* Retrieve qop-options string from the challenge */
+  if(!auth_digest_get_key_value((char *) chlg, "qop=\"", qop, qlen, '\"')) {
+    free(chlg);
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  free(chlg);
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_auth_is_digest_supported()
+ *
+ * This is used to evaluate if DIGEST is supported.
+ *
+ * Parameters: None
+ *
+ * Returns TRUE as DIGEST as handled by libcurl.
+ */
+bool Curl_auth_is_digest_supported(void)
+{
+  return TRUE;
+}
+
+/*
+ * Curl_auth_create_digest_md5_message()
+ *
+ * This is used to generate an already encoded DIGEST-MD5 response message
+ * ready for sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * chlg64  [in]     - The base64 encoded challenge message.
+ * userp   [in]     - The user name.
+ * passdwp [in]     - The user's password.
+ * service [in]     - The service type such as http, smtp, pop or imap.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
+                                             const char *chlg64,
+                                             const char *userp,
+                                             const char *passwdp,
+                                             const char *service,
+                                             char **outptr, size_t *outlen)
+{
+  CURLcode result = CURLE_OK;
+  size_t i;
+  MD5_context *ctxt;
+  char *response = NULL;
+  unsigned char digest[MD5_DIGEST_LEN];
+  char HA1_hex[2 * MD5_DIGEST_LEN + 1];
+  char HA2_hex[2 * MD5_DIGEST_LEN + 1];
+  char resp_hash_hex[2 * MD5_DIGEST_LEN + 1];
+  char nonce[64];
+  char realm[128];
+  char algorithm[64];
+  char qop_options[64];
+  int qop_values;
+  char cnonce[33];
+  char nonceCount[] = "00000001";
+  char method[]     = "AUTHENTICATE";
+  char qop[]        = DIGEST_QOP_VALUE_STRING_AUTH;
+  char *spn         = NULL;
+
+  /* Decode the challenge message */
+  result = auth_decode_digest_md5_message(chlg64, nonce, sizeof(nonce),
+                                          realm, sizeof(realm),
+                                          algorithm, sizeof(algorithm),
+                                          qop_options, sizeof(qop_options));
+  if(result)
+    return result;
+
+  /* We only support md5 sessions */
+  if(strcmp(algorithm, "md5-sess") != 0)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  /* Get the qop-values from the qop-options */
+  result = auth_digest_get_qop_values(qop_options, &qop_values);
+  if(result)
+    return result;
+
+  /* We only support auth quality-of-protection */
+  if(!(qop_values & DIGEST_QOP_VALUE_AUTH))
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  /* Generate 32 random hex chars, 32 bytes + 1 zero termination */
+  result = Curl_rand_hex(data, (unsigned char *)cnonce, sizeof(cnonce));
+  if(result)
+    return result;
+
+  /* So far so good, now calculate A1 and H(A1) according to RFC 2831 */
+  ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
+  if(!ctxt)
+    return CURLE_OUT_OF_MEMORY;
+
+  Curl_MD5_update(ctxt, (const unsigned char *) userp,
+                  curlx_uztoui(strlen(userp)));
+  Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+  Curl_MD5_update(ctxt, (const unsigned char *) realm,
+                  curlx_uztoui(strlen(realm)));
+  Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+  Curl_MD5_update(ctxt, (const unsigned char *) passwdp,
+                  curlx_uztoui(strlen(passwdp)));
+  Curl_MD5_final(ctxt, digest);
+
+  ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
+  if(!ctxt)
+    return CURLE_OUT_OF_MEMORY;
+
+  Curl_MD5_update(ctxt, (const unsigned char *) digest, MD5_DIGEST_LEN);
+  Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+  Curl_MD5_update(ctxt, (const unsigned char *) nonce,
+                  curlx_uztoui(strlen(nonce)));
+  Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+  Curl_MD5_update(ctxt, (const unsigned char *) cnonce,
+                  curlx_uztoui(strlen(cnonce)));
+  Curl_MD5_final(ctxt, digest);
+
+  /* Convert calculated 16 octet hex into 32 bytes string */
+  for(i = 0; i < MD5_DIGEST_LEN; i++)
+    snprintf(&HA1_hex[2 * i], 3, "%02x", digest[i]);
+
+  /* Generate our SPN */
+  spn = Curl_auth_build_spn(service, realm, NULL);
+  if(!spn)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Calculate H(A2) */
+  ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
+  if(!ctxt) {
+    free(spn);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  Curl_MD5_update(ctxt, (const unsigned char *) method,
+                  curlx_uztoui(strlen(method)));
+  Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+  Curl_MD5_update(ctxt, (const unsigned char *) spn,
+                  curlx_uztoui(strlen(spn)));
+  Curl_MD5_final(ctxt, digest);
+
+  for(i = 0; i < MD5_DIGEST_LEN; i++)
+    snprintf(&HA2_hex[2 * i], 3, "%02x", digest[i]);
+
+  /* Now calculate the response hash */
+  ctxt = Curl_MD5_init(Curl_DIGEST_MD5);
+  if(!ctxt) {
+    free(spn);
+
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  Curl_MD5_update(ctxt, (const unsigned char *) HA1_hex, 2 * MD5_DIGEST_LEN);
+  Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+  Curl_MD5_update(ctxt, (const unsigned char *) nonce,
+                  curlx_uztoui(strlen(nonce)));
+  Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+
+  Curl_MD5_update(ctxt, (const unsigned char *) nonceCount,
+                  curlx_uztoui(strlen(nonceCount)));
+  Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+  Curl_MD5_update(ctxt, (const unsigned char *) cnonce,
+                  curlx_uztoui(strlen(cnonce)));
+  Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+  Curl_MD5_update(ctxt, (const unsigned char *) qop,
+                  curlx_uztoui(strlen(qop)));
+  Curl_MD5_update(ctxt, (const unsigned char *) ":", 1);
+
+  Curl_MD5_update(ctxt, (const unsigned char *) HA2_hex, 2 * MD5_DIGEST_LEN);
+  Curl_MD5_final(ctxt, digest);
+
+  for(i = 0; i < MD5_DIGEST_LEN; i++)
+    snprintf(&resp_hash_hex[2 * i], 3, "%02x", digest[i]);
+
+  /* Generate the response */
+  response = aprintf("username=\"%s\",realm=\"%s\",nonce=\"%s\","
+                     "cnonce=\"%s\",nc=\"%s\",digest-uri=\"%s\",response=%s,"
+                     "qop=%s",
+                     userp, realm, nonce,
+                     cnonce, nonceCount, spn, resp_hash_hex, qop);
+  free(spn);
+  if(!response)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Base64 encode the response */
+  result = Curl_base64_encode(data, response, 0, outptr, outlen);
+
+  free(response);
+
+  return result;
+}
+
+/*
+ * Curl_auth_decode_digest_http_message()
+ *
+ * This is used to decode a HTTP DIGEST challenge message into the separate
+ * attributes.
+ *
+ * Parameters:
+ *
+ * chlg    [in]     - The challenge message.
+ * digest  [in/out] - The digest data struct being used and modified.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
+                                              struct digestdata *digest)
+{
+  bool before = FALSE; /* got a nonce before */
+  bool foundAuth = FALSE;
+  bool foundAuthInt = FALSE;
+  char *token = NULL;
+  char *tmp = NULL;
+
+  /* If we already have received a nonce, keep that in mind */
+  if(digest->nonce)
+    before = TRUE;
+
+  /* Clean up any former leftovers and initialise to defaults */
+  Curl_auth_digest_cleanup(digest);
+
+  for(;;) {
+    char value[DIGEST_MAX_VALUE_LENGTH];
+    char content[DIGEST_MAX_CONTENT_LENGTH];
+
+    /* Pass all additional spaces here */
+    while(*chlg && ISSPACE(*chlg))
+      chlg++;
+
+    /* Extract a value=content pair */
+    if(Curl_auth_digest_get_pair(chlg, value, content, &chlg)) {
+      if(strcasecompare(value, "nonce")) {
+        free(digest->nonce);
+        digest->nonce = strdup(content);
+        if(!digest->nonce)
+          return CURLE_OUT_OF_MEMORY;
+      }
+      else if(strcasecompare(value, "stale")) {
+        if(strcasecompare(content, "true")) {
+          digest->stale = TRUE;
+          digest->nc = 1; /* we make a new nonce now */
+        }
+      }
+      else if(strcasecompare(value, "realm")) {
+        free(digest->realm);
+        digest->realm = strdup(content);
+        if(!digest->realm)
+          return CURLE_OUT_OF_MEMORY;
+      }
+      else if(strcasecompare(value, "opaque")) {
+        free(digest->opaque);
+        digest->opaque = strdup(content);
+        if(!digest->opaque)
+          return CURLE_OUT_OF_MEMORY;
+      }
+      else if(strcasecompare(value, "qop")) {
+        char *tok_buf = NULL;
+        /* Tokenize the list and choose auth if possible, use a temporary
+           clone of the buffer since strtok_r() ruins it */
+        tmp = strdup(content);
+        if(!tmp)
+          return CURLE_OUT_OF_MEMORY;
+
+        token = strtok_r(tmp, ",", &tok_buf);
+        while(token != NULL) {
+          if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH)) {
+            foundAuth = TRUE;
+          }
+          else if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH_INT)) {
+            foundAuthInt = TRUE;
+          }
+          token = strtok_r(NULL, ",", &tok_buf);
+        }
+
+        free(tmp);
+
+        /* Select only auth or auth-int. Otherwise, ignore */
+        if(foundAuth) {
+          free(digest->qop);
+          digest->qop = strdup(DIGEST_QOP_VALUE_STRING_AUTH);
+          if(!digest->qop)
+            return CURLE_OUT_OF_MEMORY;
+        }
+        else if(foundAuthInt) {
+          free(digest->qop);
+          digest->qop = strdup(DIGEST_QOP_VALUE_STRING_AUTH_INT);
+          if(!digest->qop)
+            return CURLE_OUT_OF_MEMORY;
+        }
+      }
+      else if(strcasecompare(value, "algorithm")) {
+        free(digest->algorithm);
+        digest->algorithm = strdup(content);
+        if(!digest->algorithm)
+          return CURLE_OUT_OF_MEMORY;
+
+        if(strcasecompare(content, "MD5-sess"))
+          digest->algo = CURLDIGESTALGO_MD5SESS;
+        else if(strcasecompare(content, "MD5"))
+          digest->algo = CURLDIGESTALGO_MD5;
+        else if(strcasecompare(content, "SHA-256"))
+          digest->algo = CURLDIGESTALGO_SHA256;
+        else if(strcasecompare(content, "SHA-256-SESS"))
+          digest->algo = CURLDIGESTALGO_SHA256SESS;
+        else if(strcasecompare(content, "SHA-512-256"))
+          digest->algo = CURLDIGESTALGO_SHA512_256;
+        else if(strcasecompare(content, "SHA-512-256-SESS"))
+          digest->algo = CURLDIGESTALGO_SHA512_256SESS;
+        else
+          return CURLE_BAD_CONTENT_ENCODING;
+      }
+      else if(strcasecompare(value, "userhash")) {
+        if(strcasecompare(content, "true")) {
+          digest->userhash = TRUE;
+        }
+      }
+      else {
+        /* Unknown specifier, ignore it! */
+      }
+    }
+    else
+      break; /* We're done here */
+
+    /* Pass all additional spaces here */
+    while(*chlg && ISSPACE(*chlg))
+      chlg++;
+
+    /* Allow the list to be comma-separated */
+    if(',' == *chlg)
+      chlg++;
+  }
+
+  /* We had a nonce since before, and we got another one now without
+     'stale=true'. This means we provided bad credentials in the previous
+     request */
+  if(before && !digest->stale)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  /* We got this header without a nonce, that's a bad Digest line! */
+  if(!digest->nonce)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  return CURLE_OK;
+}
+
+/*
+ * _Curl_auth_create_digest_http_message()
+ *
+ * This is used to generate a HTTP DIGEST response message ready for sending
+ * to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * userp   [in]     - The user name.
+ * passdwp [in]     - The user's password.
+ * request [in]     - The HTTP request.
+ * uripath [in]     - The path of the HTTP uri.
+ * digest  [in/out] - The digest data struct being used and modified.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode _Curl_auth_create_digest_http_message(
+                  struct Curl_easy *data,
+                  const char *userp,
+                  const char *passwdp,
+                  const unsigned char *request,
+                  const unsigned char *uripath,
+                  struct digestdata *digest,
+                  char **outptr, size_t *outlen,
+                  void (*convert_to_ascii)(unsigned char *, unsigned char *),
+                  void (*hash)(unsigned char *, const unsigned char *))
+{
+  CURLcode result;
+  unsigned char hashbuf[32]; /* 32 bytes/256 bits */
+  unsigned char request_digest[65];
+  unsigned char *hashthis;
+  unsigned char ha1[65];    /* 64 digits and 1 zero byte */
+  unsigned char ha2[65];    /* 64 digits and 1 zero byte */
+  char userh[65];
+  char cnoncebuf[33];
+  char *cnonce = NULL;
+  size_t cnonce_sz = 0;
+  char *userp_quoted;
+  char *response = NULL;
+  char *tmp = NULL;
+
+  if(!digest->nc)
+    digest->nc = 1;
+
+  if(!digest->cnonce) {
+    result = Curl_rand_hex(data, (unsigned char *)cnoncebuf,
+                           sizeof(cnoncebuf));
+    if(result)
+      return result;
+
+    result = Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf),
+                                &cnonce, &cnonce_sz);
+    if(result)
+      return result;
+
+    digest->cnonce = cnonce;
+  }
+
+  if(digest->userhash) {
+    hashthis = (unsigned char *) aprintf("%s:%s", userp, digest->realm);
+    if(!hashthis)
+      return CURLE_OUT_OF_MEMORY;
+
+    CURL_OUTPUT_DIGEST_CONV(data, hashthis);
+    hash(hashbuf, hashthis);
+    free(hashthis);
+    convert_to_ascii(hashbuf, (unsigned char *)userh);
+  }
+
+  /*
+    If the algorithm is "MD5" or unspecified (which then defaults to MD5):
+
+      A1 = unq(username-value) ":" unq(realm-value) ":" passwd
+
+    If the algorithm is "MD5-sess" then:
+
+      A1 = H(unq(username-value) ":" unq(realm-value) ":" passwd) ":"
+           unq(nonce-value) ":" unq(cnonce-value)
+  */
+
+  hashthis = (unsigned char *)
+    aprintf("%s:%s:%s", digest->userhash ? userh : userp,
+                                    digest->realm, passwdp);
+  if(!hashthis)
+    return CURLE_OUT_OF_MEMORY;
+
+  CURL_OUTPUT_DIGEST_CONV(data, hashthis); /* convert on non-ASCII machines */
+  hash(hashbuf, hashthis);
+  free(hashthis);
+  convert_to_ascii(hashbuf, ha1);
+
+  if(digest->algo == CURLDIGESTALGO_MD5SESS ||
+     digest->algo == CURLDIGESTALGO_SHA256SESS ||
+     digest->algo == CURLDIGESTALGO_SHA512_256SESS) {
+    /* nonce and cnonce are OUTSIDE the hash */
+    tmp = aprintf("%s:%s:%s", ha1, digest->nonce, digest->cnonce);
+    if(!tmp)
+      return CURLE_OUT_OF_MEMORY;
+
+    CURL_OUTPUT_DIGEST_CONV(data, tmp); /* Convert on non-ASCII machines */
+    hash(hashbuf, (unsigned char *) tmp);
+    free(tmp);
+    convert_to_ascii(hashbuf, ha1);
+  }
+
+  /*
+    If the "qop" directive's value is "auth" or is unspecified, then A2 is:
+
+      A2 = Method ":" digest-uri-value
+
+    If the "qop" value is "auth-int", then A2 is:
+
+      A2 = Method ":" digest-uri-value ":" H(entity-body)
+
+    (The "Method" value is the HTTP request method as specified in section
+    5.1.1 of RFC 2616)
+  */
+
+  hashthis = (unsigned char *) aprintf("%s:%s", request, uripath);
+
+  if(digest->qop && strcasecompare(digest->qop, "auth-int")) {
+    /* We don't support auth-int for PUT or POST at the moment.
+       TODO: replace hash of empty string with entity-body for PUT/POST */
+    char hashed[65];
+    unsigned char *hashthis2;
+
+    hash(hashbuf, (const unsigned char *)"");
+    convert_to_ascii(hashbuf, (unsigned char *)hashed);
+
+    hashthis2 = (unsigned char *)aprintf("%s:%s", hashthis, hashed);
+    free(hashthis);
+    hashthis = hashthis2;
+  }
+
+  if(!hashthis)
+    return CURLE_OUT_OF_MEMORY;
+
+  CURL_OUTPUT_DIGEST_CONV(data, hashthis); /* convert on non-ASCII machines */
+  hash(hashbuf, hashthis);
+  free(hashthis);
+  convert_to_ascii(hashbuf, ha2);
+
+  if(digest->qop) {
+    hashthis = (unsigned char *) aprintf("%s:%s:%08x:%s:%s:%s",
+                                        ha1,
+                                        digest->nonce,
+                                        digest->nc,
+                                        digest->cnonce,
+                                        digest->qop,
+                                        ha2);
+  }
+  else {
+    hashthis = (unsigned char *) aprintf("%s:%s:%s",
+                                        ha1,
+                                        digest->nonce,
+                                        ha2);
+  }
+
+  if(!hashthis)
+    return CURLE_OUT_OF_MEMORY;
+
+  CURL_OUTPUT_DIGEST_CONV(data, hashthis); /* convert on non-ASCII machines */
+  hash(hashbuf, hashthis);
+  free(hashthis);
+  convert_to_ascii(hashbuf, request_digest);
+
+  /* For test case 64 (snooped from a Mozilla 1.3a request)
+
+     Authorization: Digest username="testuser", realm="testrealm", \
+     nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
+
+     Digest parameters are all quoted strings.  Username which is provided by
+     the user will need double quotes and backslashes within it escaped.  For
+     the other fields, this shouldn't be an issue.  realm, nonce, and opaque
+     are copied as is from the server, escapes and all.  cnonce is generated
+     with web-safe characters.  uri is already percent encoded.  nc is 8 hex
+     characters.  algorithm and qop with standard values only contain web-safe
+     characters.
+  */
+  userp_quoted = auth_digest_string_quoted(digest->userhash ? userh : userp);
+  if(!userp_quoted)
+    return CURLE_OUT_OF_MEMORY;
+
+  if(digest->qop) {
+    response = aprintf("username=\"%s\", "
+                       "realm=\"%s\", "
+                       "nonce=\"%s\", "
+                       "uri=\"%s\", "
+                       "cnonce=\"%s\", "
+                       "nc=%08x, "
+                       "qop=%s, "
+                       "response=\"%s\"",
+                       userp_quoted,
+                       digest->realm,
+                       digest->nonce,
+                       uripath,
+                       digest->cnonce,
+                       digest->nc,
+                       digest->qop,
+                       request_digest);
+
+    if(strcasecompare(digest->qop, "auth"))
+      digest->nc++; /* The nc (from RFC) has to be a 8 hex digit number 0
+                       padded which tells to the server how many times you are
+                       using the same nonce in the qop=auth mode */
+  }
+  else {
+    response = aprintf("username=\"%s\", "
+                       "realm=\"%s\", "
+                       "nonce=\"%s\", "
+                       "uri=\"%s\", "
+                       "response=\"%s\"",
+                       userp_quoted,
+                       digest->realm,
+                       digest->nonce,
+                       uripath,
+                       request_digest);
+  }
+  free(userp_quoted);
+  if(!response)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Add the optional fields */
+  if(digest->opaque) {
+    /* Append the opaque */
+    tmp = aprintf("%s, opaque=\"%s\"", response, digest->opaque);
+    free(response);
+    if(!tmp)
+      return CURLE_OUT_OF_MEMORY;
+
+    response = tmp;
+  }
+
+  if(digest->algorithm) {
+    /* Append the algorithm */
+    tmp = aprintf("%s, algorithm=\"%s\"", response, digest->algorithm);
+    free(response);
+    if(!tmp)
+      return CURLE_OUT_OF_MEMORY;
+
+    response = tmp;
+  }
+
+  if(digest->userhash) {
+    /* Append the userhash */
+    tmp = aprintf("%s, userhash=true", response);
+    free(response);
+    if(!tmp)
+      return CURLE_OUT_OF_MEMORY;
+
+    response = tmp;
+  }
+
+  /* Return the output */
+  *outptr = response;
+  *outlen = strlen(response);
+
+  return CURLE_OK;
+}
+
+/*
+ * Curl_auth_create_digest_http_message()
+ *
+ * This is used to generate a HTTP DIGEST response message ready for sending
+ * to the recipient.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * userp   [in]     - The user name.
+ * passdwp [in]     - The user's password.
+ * request [in]     - The HTTP request.
+ * uripath [in]     - The path of the HTTP uri.
+ * digest  [in/out] - The digest data struct being used and modified.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
+                                              const char *userp,
+                                              const char *passwdp,
+                                              const unsigned char *request,
+                                              const unsigned char *uripath,
+                                              struct digestdata *digest,
+                                              char **outptr, size_t *outlen)
+{
+  switch(digest->algo) {
+  case CURLDIGESTALGO_MD5:
+  case CURLDIGESTALGO_MD5SESS:
+    return _Curl_auth_create_digest_http_message(data, userp, passwdp,
+                                                 request, uripath, digest,
+                                                 outptr, outlen,
+                                                 auth_digest_md5_to_ascii,
+                                                 Curl_md5it);
+
+  case CURLDIGESTALGO_SHA256:
+  case CURLDIGESTALGO_SHA256SESS:
+  case CURLDIGESTALGO_SHA512_256:
+  case CURLDIGESTALGO_SHA512_256SESS:
+    return _Curl_auth_create_digest_http_message(data, userp, passwdp,
+                                                 request, uripath, digest,
+                                                 outptr, outlen,
+                                                 auth_digest_sha256_to_ascii,
+                                                 Curl_sha256it);
+
+  default:
+    return CURLE_UNSUPPORTED_PROTOCOL;
+  }
+}
+
+/*
+ * Curl_auth_digest_cleanup()
+ *
+ * This is used to clean up the digest specific data.
+ *
+ * Parameters:
+ *
+ * digest    [in/out] - The digest data struct being cleaned up.
+ *
+ */
+void Curl_auth_digest_cleanup(struct digestdata *digest)
+{
+  Curl_safefree(digest->nonce);
+  Curl_safefree(digest->cnonce);
+  Curl_safefree(digest->realm);
+  Curl_safefree(digest->opaque);
+  Curl_safefree(digest->qop);
+  Curl_safefree(digest->algorithm);
+
+  digest->nc = 0;
+  digest->algo = CURLDIGESTALGO_MD5; /* default algorithm */
+  digest->stale = FALSE; /* default means normal, not stale */
+  digest->userhash = FALSE;
+}
+#endif  /* !USE_WINDOWS_SSPI */
+
+#endif  /* CURL_DISABLE_CRYPTO_AUTH */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/digest.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/digest.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/digest.h	(revision 331)
@@ -0,0 +1,47 @@
+#ifndef HEADER_CURL_DIGEST_H
+#define HEADER_CURL_DIGEST_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h>
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+
+#define DIGEST_MAX_VALUE_LENGTH           256
+#define DIGEST_MAX_CONTENT_LENGTH         1024
+
+enum {
+  CURLDIGESTALGO_MD5,
+  CURLDIGESTALGO_MD5SESS,
+  CURLDIGESTALGO_SHA256,
+  CURLDIGESTALGO_SHA256SESS,
+  CURLDIGESTALGO_SHA512_256,
+  CURLDIGESTALGO_SHA512_256SESS
+};
+
+/* This is used to extract the realm from a challenge message */
+bool Curl_auth_digest_get_pair(const char *str, char *value, char *content,
+                               const char **endptr);
+
+#endif
+
+#endif /* HEADER_CURL_DIGEST_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/ntlm.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/ntlm.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/ntlm.c	(revision 331)
@@ -0,0 +1,859 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI)
+
+/*
+ * NTLM details:
+ *
+ * https://davenport.sourceforge.io/ntlm.html
+ * https://www.innovation.ch/java/ntlm.html
+ */
+
+#define DEBUG_ME 0
+
+#include "urldata.h"
+#include "non-ascii.h"
+#include "sendf.h"
+#include "curl_base64.h"
+#include "curl_ntlm_core.h"
+#include "curl_gethostname.h"
+#include "curl_multibyte.h"
+#include "warnless.h"
+#include "rand.h"
+#include "vtls/vtls.h"
+
+/* SSL backend-specific #if branches in this file must be kept in the order
+   documented in curl_ntlm_core. */
+#if defined(NTLM_NEEDS_NSS_INIT)
+#include "vtls/nssg.h" /* for Curl_nss_force_init() */
+#endif
+
+#define BUILDING_CURL_NTLM_MSGS_C
+#include "vauth/vauth.h"
+#include "vauth/ntlm.h"
+#include "curl_endian.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* "NTLMSSP" signature is always in ASCII regardless of the platform */
+#define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50"
+
+#define SHORTPAIR(x) ((x) & 0xff), (((x) >> 8) & 0xff)
+#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8) & 0xff), \
+  (((x) >> 16) & 0xff), (((x) >> 24) & 0xff)
+
+#if DEBUG_ME
+# define DEBUG_OUT(x) x
+static void ntlm_print_flags(FILE *handle, unsigned long flags)
+{
+  if(flags & NTLMFLAG_NEGOTIATE_UNICODE)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_UNICODE ");
+  if(flags & NTLMFLAG_NEGOTIATE_OEM)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_OEM ");
+  if(flags & NTLMFLAG_REQUEST_TARGET)
+    fprintf(handle, "NTLMFLAG_REQUEST_TARGET ");
+  if(flags & (1<<3))
+    fprintf(handle, "NTLMFLAG_UNKNOWN_3 ");
+  if(flags & NTLMFLAG_NEGOTIATE_SIGN)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_SIGN ");
+  if(flags & NTLMFLAG_NEGOTIATE_SEAL)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_SEAL ");
+  if(flags & NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE ");
+  if(flags & NTLMFLAG_NEGOTIATE_LM_KEY)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_LM_KEY ");
+  if(flags & NTLMFLAG_NEGOTIATE_NETWARE)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_NETWARE ");
+  if(flags & NTLMFLAG_NEGOTIATE_NTLM_KEY)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM_KEY ");
+  if(flags & (1<<10))
+    fprintf(handle, "NTLMFLAG_UNKNOWN_10 ");
+  if(flags & NTLMFLAG_NEGOTIATE_ANONYMOUS)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_ANONYMOUS ");
+  if(flags & NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED ");
+  if(flags & NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED ");
+  if(flags & NTLMFLAG_NEGOTIATE_LOCAL_CALL)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_LOCAL_CALL ");
+  if(flags & NTLMFLAG_NEGOTIATE_ALWAYS_SIGN)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_ALWAYS_SIGN ");
+  if(flags & NTLMFLAG_TARGET_TYPE_DOMAIN)
+    fprintf(handle, "NTLMFLAG_TARGET_TYPE_DOMAIN ");
+  if(flags & NTLMFLAG_TARGET_TYPE_SERVER)
+    fprintf(handle, "NTLMFLAG_TARGET_TYPE_SERVER ");
+  if(flags & NTLMFLAG_TARGET_TYPE_SHARE)
+    fprintf(handle, "NTLMFLAG_TARGET_TYPE_SHARE ");
+  if(flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM2_KEY ");
+  if(flags & NTLMFLAG_REQUEST_INIT_RESPONSE)
+    fprintf(handle, "NTLMFLAG_REQUEST_INIT_RESPONSE ");
+  if(flags & NTLMFLAG_REQUEST_ACCEPT_RESPONSE)
+    fprintf(handle, "NTLMFLAG_REQUEST_ACCEPT_RESPONSE ");
+  if(flags & NTLMFLAG_REQUEST_NONNT_SESSION_KEY)
+    fprintf(handle, "NTLMFLAG_REQUEST_NONNT_SESSION_KEY ");
+  if(flags & NTLMFLAG_NEGOTIATE_TARGET_INFO)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_TARGET_INFO ");
+  if(flags & (1<<24))
+    fprintf(handle, "NTLMFLAG_UNKNOWN_24 ");
+  if(flags & (1<<25))
+    fprintf(handle, "NTLMFLAG_UNKNOWN_25 ");
+  if(flags & (1<<26))
+    fprintf(handle, "NTLMFLAG_UNKNOWN_26 ");
+  if(flags & (1<<27))
+    fprintf(handle, "NTLMFLAG_UNKNOWN_27 ");
+  if(flags & (1<<28))
+    fprintf(handle, "NTLMFLAG_UNKNOWN_28 ");
+  if(flags & NTLMFLAG_NEGOTIATE_128)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_128 ");
+  if(flags & NTLMFLAG_NEGOTIATE_KEY_EXCHANGE)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_KEY_EXCHANGE ");
+  if(flags & NTLMFLAG_NEGOTIATE_56)
+    fprintf(handle, "NTLMFLAG_NEGOTIATE_56 ");
+}
+
+static void ntlm_print_hex(FILE *handle, const char *buf, size_t len)
+{
+  const char *p = buf;
+
+  (void) handle;
+
+  fprintf(stderr, "0x");
+  while(len-- > 0)
+    fprintf(stderr, "%02.2x", (unsigned int)*p++);
+}
+#else
+# define DEBUG_OUT(x) Curl_nop_stmt
+#endif
+
+/*
+ * ntlm_decode_type2_target()
+ *
+ * This is used to decode the "target info" in the NTLM type-2 message
+ * received.
+ *
+ * Parameters:
+ *
+ * data      [in]     - The session handle.
+ * buffer    [in]     - The decoded type-2 message.
+ * size      [in]     - The input buffer size, at least 32 bytes.
+ * ntlm      [in/out] - The NTLM data struct being used and modified.
+ *
+ * Returns CURLE_OK on success.
+ */
+static CURLcode ntlm_decode_type2_target(struct Curl_easy *data,
+                                         unsigned char *buffer,
+                                         size_t size,
+                                         struct ntlmdata *ntlm)
+{
+  unsigned short target_info_len = 0;
+  unsigned int target_info_offset = 0;
+
+#if defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void) data;
+#endif
+
+  if(size >= 48) {
+    target_info_len = Curl_read16_le(&buffer[40]);
+    target_info_offset = Curl_read32_le(&buffer[44]);
+    if(target_info_len > 0) {
+      if(((target_info_offset + target_info_len) > size) ||
+         (target_info_offset < 48)) {
+        infof(data, "NTLM handshake failure (bad type-2 message). "
+                    "Target Info Offset Len is set incorrect by the peer\n");
+        return CURLE_BAD_CONTENT_ENCODING;
+      }
+
+      ntlm->target_info = malloc(target_info_len);
+      if(!ntlm->target_info)
+        return CURLE_OUT_OF_MEMORY;
+
+      memcpy(ntlm->target_info, &buffer[target_info_offset], target_info_len);
+    }
+  }
+
+  ntlm->target_info_len = target_info_len;
+
+  return CURLE_OK;
+}
+
+/*
+  NTLM message structure notes:
+
+  A 'short' is a 'network short', a little-endian 16-bit unsigned value.
+
+  A 'long' is a 'network long', a little-endian, 32-bit unsigned value.
+
+  A 'security buffer' represents a triplet used to point to a buffer,
+  consisting of two shorts and one long:
+
+    1. A 'short' containing the length of the buffer content in bytes.
+    2. A 'short' containing the allocated space for the buffer in bytes.
+    3. A 'long' containing the offset to the start of the buffer in bytes,
+       from the beginning of the NTLM message.
+*/
+
+/*
+ * Curl_auth_is_ntlm_supported()
+ *
+ * This is used to evaluate if NTLM is supported.
+ *
+ * Parameters: None
+ *
+ * Returns TRUE as NTLM as handled by libcurl.
+ */
+bool Curl_auth_is_ntlm_supported(void)
+{
+  return TRUE;
+}
+
+/*
+ * Curl_auth_decode_ntlm_type2_message()
+ *
+ * This is used to decode an already encoded NTLM type-2 message. The message
+ * is first decoded from a base64 string into a raw NTLM message and checked
+ * for validity before the appropriate data for creating a type-3 message is
+ * written to the given NTLM data structure.
+ *
+ * Parameters:
+ *
+ * data     [in]     - The session handle.
+ * type2msg [in]     - The base64 encoded type-2 message.
+ * ntlm     [in/out] - The NTLM data struct being used and modified.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data,
+                                             const char *type2msg,
+                                             struct ntlmdata *ntlm)
+{
+  static const char type2_marker[] = { 0x02, 0x00, 0x00, 0x00 };
+
+  /* NTLM type-2 message structure:
+
+          Index  Description            Content
+            0    NTLMSSP Signature      Null-terminated ASCII "NTLMSSP"
+                                        (0x4e544c4d53535000)
+            8    NTLM Message Type      long (0x02000000)
+           12    Target Name            security buffer
+           20    Flags                  long
+           24    Challenge              8 bytes
+          (32)   Context                8 bytes (two consecutive longs) (*)
+          (40)   Target Information     security buffer (*)
+          (48)   OS Version Structure   8 bytes (*)
+  32 (48) (56)   Start of data block    (*)
+                                        (*) -> Optional
+  */
+
+  CURLcode result = CURLE_OK;
+  unsigned char *type2 = NULL;
+  size_t type2_len = 0;
+
+#if defined(NTLM_NEEDS_NSS_INIT)
+  /* Make sure the crypto backend is initialized */
+  result = Curl_nss_force_init(data);
+  if(result)
+    return result;
+#elif defined(CURL_DISABLE_VERBOSE_STRINGS)
+  (void)data;
+#endif
+
+  /* Decode the base-64 encoded type-2 message */
+  if(strlen(type2msg) && *type2msg != '=') {
+    result = Curl_base64_decode(type2msg, &type2, &type2_len);
+    if(result)
+      return result;
+  }
+
+  /* Ensure we have a valid type-2 message */
+  if(!type2) {
+    infof(data, "NTLM handshake failure (empty type-2 message)\n");
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  ntlm->flags = 0;
+
+  if((type2_len < 32) ||
+     (memcmp(type2, NTLMSSP_SIGNATURE, 8) != 0) ||
+     (memcmp(type2 + 8, type2_marker, sizeof(type2_marker)) != 0)) {
+    /* This was not a good enough type-2 message */
+    free(type2);
+    infof(data, "NTLM handshake failure (bad type-2 message)\n");
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
+  ntlm->flags = Curl_read32_le(&type2[20]);
+  memcpy(ntlm->nonce, &type2[24], 8);
+
+  if(ntlm->flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) {
+    result = ntlm_decode_type2_target(data, type2, type2_len, ntlm);
+    if(result) {
+      free(type2);
+      infof(data, "NTLM handshake failure (bad type-2 message)\n");
+      return result;
+    }
+  }
+
+  DEBUG_OUT({
+    fprintf(stderr, "**** TYPE2 header flags=0x%08.8lx ", ntlm->flags);
+    ntlm_print_flags(stderr, ntlm->flags);
+    fprintf(stderr, "\n                  nonce=");
+    ntlm_print_hex(stderr, (char *)ntlm->nonce, 8);
+    fprintf(stderr, "\n****\n");
+    fprintf(stderr, "**** Header %s\n ", header);
+  });
+
+  free(type2);
+
+  return result;
+}
+
+/* copy the source to the destination and fill in zeroes in every
+   other destination byte! */
+static void unicodecpy(unsigned char *dest, const char *src, size_t length)
+{
+  size_t i;
+  for(i = 0; i < length; i++) {
+    dest[2 * i] = (unsigned char)src[i];
+    dest[2 * i + 1] = '\0';
+  }
+}
+
+/*
+ * Curl_auth_create_ntlm_type1_message()
+ *
+ * This is used to generate an already encoded NTLM type-1 message ready for
+ * sending to the recipient using the appropriate compile time crypto API.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * userp   [in]     - The user name in the format User or Domain\User.
+ * passdwp [in]     - The user's password.
+ * ntlm    [in/out] - The NTLM data struct being used and modified.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
+                                             const char *userp,
+                                             const char *passwdp,
+                                             struct ntlmdata *ntlm,
+                                             char **outptr, size_t *outlen)
+{
+  /* NTLM type-1 message structure:
+
+       Index  Description            Content
+         0    NTLMSSP Signature      Null-terminated ASCII "NTLMSSP"
+                                     (0x4e544c4d53535000)
+         8    NTLM Message Type      long (0x01000000)
+        12    Flags                  long
+       (16)   Supplied Domain        security buffer (*)
+       (24)   Supplied Workstation   security buffer (*)
+       (32)   OS Version Structure   8 bytes (*)
+  (32) (40)   Start of data block    (*)
+                                     (*) -> Optional
+  */
+
+  size_t size;
+
+  unsigned char ntlmbuf[NTLM_BUFSIZE];
+  const char *host = "";              /* empty */
+  const char *domain = "";            /* empty */
+  size_t hostlen = 0;
+  size_t domlen = 0;
+  size_t hostoff = 0;
+  size_t domoff = hostoff + hostlen;  /* This is 0: remember that host and
+                                         domain are empty */
+  (void)userp;
+  (void)passwdp;
+
+  /* Clean up any former leftovers and initialise to defaults */
+  Curl_auth_ntlm_cleanup(ntlm);
+
+#if defined(USE_NTRESPONSES) && defined(USE_NTLM2SESSION)
+#define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY
+#else
+#define NTLM2FLAG 0
+#endif
+  snprintf((char *)ntlmbuf, NTLM_BUFSIZE,
+           NTLMSSP_SIGNATURE "%c"
+           "\x01%c%c%c" /* 32-bit type = 1 */
+           "%c%c%c%c"   /* 32-bit NTLM flag field */
+           "%c%c"       /* domain length */
+           "%c%c"       /* domain allocated space */
+           "%c%c"       /* domain name offset */
+           "%c%c"       /* 2 zeroes */
+           "%c%c"       /* host length */
+           "%c%c"       /* host allocated space */
+           "%c%c"       /* host name offset */
+           "%c%c"       /* 2 zeroes */
+           "%s"         /* host name */
+           "%s",        /* domain string */
+           0,           /* trailing zero */
+           0, 0, 0,     /* part of type-1 long */
+
+           LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM |
+                       NTLMFLAG_REQUEST_TARGET |
+                       NTLMFLAG_NEGOTIATE_NTLM_KEY |
+                       NTLM2FLAG |
+                       NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
+           SHORTPAIR(domlen),
+           SHORTPAIR(domlen),
+           SHORTPAIR(domoff),
+           0, 0,
+           SHORTPAIR(hostlen),
+           SHORTPAIR(hostlen),
+           SHORTPAIR(hostoff),
+           0, 0,
+           host,  /* this is empty */
+           domain /* this is empty */);
+
+  /* Initial packet length */
+  size = 32 + hostlen + domlen;
+
+  DEBUG_OUT({
+    fprintf(stderr, "* TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x "
+            "0x%08.8x ",
+            LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM |
+                        NTLMFLAG_REQUEST_TARGET |
+                        NTLMFLAG_NEGOTIATE_NTLM_KEY |
+                        NTLM2FLAG |
+                        NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
+            NTLMFLAG_NEGOTIATE_OEM |
+            NTLMFLAG_REQUEST_TARGET |
+            NTLMFLAG_NEGOTIATE_NTLM_KEY |
+            NTLM2FLAG |
+            NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
+    ntlm_print_flags(stderr,
+                     NTLMFLAG_NEGOTIATE_OEM |
+                     NTLMFLAG_REQUEST_TARGET |
+                     NTLMFLAG_NEGOTIATE_NTLM_KEY |
+                     NTLM2FLAG |
+                     NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
+    fprintf(stderr, "\n****\n");
+  });
+
+  /* Return with binary blob encoded into base64 */
+  return Curl_base64_encode(data, (char *)ntlmbuf, size, outptr, outlen);
+}
+
+/*
+ * Curl_auth_create_ntlm_type3_message()
+ *
+ * This is used to generate an already encoded NTLM type-3 message ready for
+ * sending to the recipient using the appropriate compile time crypto API.
+ *
+ * Parameters:
+ *
+ * data    [in]     - The session handle.
+ * userp   [in]     - The user name in the format User or Domain\User.
+ * passdwp [in]     - The user's password.
+ * ntlm    [in/out] - The NTLM data struct being used and modified.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
+                                             const char *userp,
+                                             const char *passwdp,
+                                             struct ntlmdata *ntlm,
+                                             char **outptr, size_t *outlen)
+
+{
+  /* NTLM type-3 message structure:
+
+          Index  Description            Content
+            0    NTLMSSP Signature      Null-terminated ASCII "NTLMSSP"
+                                        (0x4e544c4d53535000)
+            8    NTLM Message Type      long (0x03000000)
+           12    LM/LMv2 Response       security buffer
+           20    NTLM/NTLMv2 Response   security buffer
+           28    Target Name            security buffer
+           36    User Name              security buffer
+           44    Workstation Name       security buffer
+          (52)   Session Key            security buffer (*)
+          (60)   Flags                  long (*)
+          (64)   OS Version Structure   8 bytes (*)
+  52 (64) (72)   Start of data block
+                                          (*) -> Optional
+  */
+
+  CURLcode result = CURLE_OK;
+  size_t size;
+  unsigned char ntlmbuf[NTLM_BUFSIZE];
+  int lmrespoff;
+  unsigned char lmresp[24]; /* fixed-size */
+#ifdef USE_NTRESPONSES
+  int ntrespoff;
+  unsigned int ntresplen = 24;
+  unsigned char ntresp[24]; /* fixed-size */
+  unsigned char *ptr_ntresp = &ntresp[0];
+  unsigned char *ntlmv2resp = NULL;
+#endif
+  bool unicode = (ntlm->flags & NTLMFLAG_NEGOTIATE_UNICODE) ? TRUE : FALSE;
+  char host[HOSTNAME_MAX + 1] = "";
+  const char *user;
+  const char *domain = "";
+  size_t hostoff = 0;
+  size_t useroff = 0;
+  size_t domoff = 0;
+  size_t hostlen = 0;
+  size_t userlen = 0;
+  size_t domlen = 0;
+
+  user = strchr(userp, '\\');
+  if(!user)
+    user = strchr(userp, '/');
+
+  if(user) {
+    domain = userp;
+    domlen = (user - domain);
+    user++;
+  }
+  else
+    user = userp;
+
+  userlen = strlen(user);
+
+  /* Get the machine's un-qualified host name as NTLM doesn't like the fully
+     qualified domain name */
+  if(Curl_gethostname(host, sizeof(host))) {
+    infof(data, "gethostname() failed, continuing without!\n");
+    hostlen = 0;
+  }
+  else {
+    hostlen = strlen(host);
+  }
+
+#if defined(USE_NTRESPONSES) && defined(USE_NTLM_V2)
+  if(ntlm->target_info_len) {
+    unsigned char ntbuffer[0x18];
+    unsigned char entropy[8];
+    unsigned char ntlmv2hash[0x18];
+
+    result = Curl_rand(data, entropy, 8);
+    if(result)
+      return result;
+
+    result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
+    if(result)
+      return result;
+
+    result = Curl_ntlm_core_mk_ntlmv2_hash(user, userlen, domain, domlen,
+                                           ntbuffer, ntlmv2hash);
+    if(result)
+      return result;
+
+    /* LMv2 response */
+    result = Curl_ntlm_core_mk_lmv2_resp(ntlmv2hash, entropy,
+                                         &ntlm->nonce[0], lmresp);
+    if(result)
+      return result;
+
+    /* NTLMv2 response */
+    result = Curl_ntlm_core_mk_ntlmv2_resp(ntlmv2hash, entropy,
+                                           ntlm, &ntlmv2resp, &ntresplen);
+    if(result)
+      return result;
+
+    ptr_ntresp = ntlmv2resp;
+  }
+  else
+#endif
+
+#if defined(USE_NTRESPONSES) && defined(USE_NTLM2SESSION)
+  /* We don't support NTLM2 if we don't have USE_NTRESPONSES */
+  if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
+    unsigned char ntbuffer[0x18];
+    unsigned char tmp[0x18];
+    unsigned char md5sum[MD5_DIGEST_LENGTH];
+    unsigned char entropy[8];
+
+    /* Need to create 8 bytes random data */
+    result = Curl_rand(data, entropy, 8);
+    if(result)
+      return result;
+
+    /* 8 bytes random data as challenge in lmresp */
+    memcpy(lmresp, entropy, 8);
+
+    /* Pad with zeros */
+    memset(lmresp + 8, 0, 0x10);
+
+    /* Fill tmp with challenge(nonce?) + entropy */
+    memcpy(tmp, &ntlm->nonce[0], 8);
+    memcpy(tmp + 8, entropy, 8);
+
+    result = Curl_ssl_md5sum(tmp, 16, md5sum, MD5_DIGEST_LENGTH);
+    if(!result)
+      /* We shall only use the first 8 bytes of md5sum, but the des code in
+         Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */
+      result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
+    if(result)
+      return result;
+
+    Curl_ntlm_core_lm_resp(ntbuffer, md5sum, ntresp);
+
+    /* End of NTLM2 Session code */
+
+  }
+  else
+#endif
+  {
+
+#ifdef USE_NTRESPONSES
+    unsigned char ntbuffer[0x18];
+#endif
+    unsigned char lmbuffer[0x18];
+
+#ifdef USE_NTRESPONSES
+    result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
+    if(result)
+      return result;
+
+    Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], ntresp);
+#endif
+
+    result = Curl_ntlm_core_mk_lm_hash(data, passwdp, lmbuffer);
+    if(result)
+      return result;
+
+    Curl_ntlm_core_lm_resp(lmbuffer, &ntlm->nonce[0], lmresp);
+
+    /* A safer but less compatible alternative is:
+     *   Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], lmresp);
+     * See https://davenport.sourceforge.io/ntlm.html#ntlmVersion2 */
+  }
+
+  if(unicode) {
+    domlen = domlen * 2;
+    userlen = userlen * 2;
+    hostlen = hostlen * 2;
+  }
+
+  lmrespoff = 64; /* size of the message header */
+#ifdef USE_NTRESPONSES
+  ntrespoff = lmrespoff + 0x18;
+  domoff = ntrespoff + ntresplen;
+#else
+  domoff = lmrespoff + 0x18;
+#endif
+  useroff = domoff + domlen;
+  hostoff = useroff + userlen;
+
+  /* Create the big type-3 message binary blob */
+  size = snprintf((char *)ntlmbuf, NTLM_BUFSIZE,
+                  NTLMSSP_SIGNATURE "%c"
+                  "\x03%c%c%c"  /* 32-bit type = 3 */
+
+                  "%c%c"  /* LanManager length */
+                  "%c%c"  /* LanManager allocated space */
+                  "%c%c"  /* LanManager offset */
+                  "%c%c"  /* 2 zeroes */
+
+                  "%c%c"  /* NT-response length */
+                  "%c%c"  /* NT-response allocated space */
+                  "%c%c"  /* NT-response offset */
+                  "%c%c"  /* 2 zeroes */
+
+                  "%c%c"  /* domain length */
+                  "%c%c"  /* domain allocated space */
+                  "%c%c"  /* domain name offset */
+                  "%c%c"  /* 2 zeroes */
+
+                  "%c%c"  /* user length */
+                  "%c%c"  /* user allocated space */
+                  "%c%c"  /* user offset */
+                  "%c%c"  /* 2 zeroes */
+
+                  "%c%c"  /* host length */
+                  "%c%c"  /* host allocated space */
+                  "%c%c"  /* host offset */
+                  "%c%c"  /* 2 zeroes */
+
+                  "%c%c"  /* session key length (unknown purpose) */
+                  "%c%c"  /* session key allocated space (unknown purpose) */
+                  "%c%c"  /* session key offset (unknown purpose) */
+                  "%c%c"  /* 2 zeroes */
+
+                  "%c%c%c%c",  /* flags */
+
+                  /* domain string */
+                  /* user string */
+                  /* host string */
+                  /* LanManager response */
+                  /* NT response */
+
+                  0,                /* zero termination */
+                  0, 0, 0,          /* type-3 long, the 24 upper bits */
+
+                  SHORTPAIR(0x18),  /* LanManager response length, twice */
+                  SHORTPAIR(0x18),
+                  SHORTPAIR(lmrespoff),
+                  0x0, 0x0,
+
+#ifdef USE_NTRESPONSES
+                  SHORTPAIR(ntresplen),  /* NT-response length, twice */
+                  SHORTPAIR(ntresplen),
+                  SHORTPAIR(ntrespoff),
+                  0x0, 0x0,
+#else
+                  0x0, 0x0,
+                  0x0, 0x0,
+                  0x0, 0x0,
+                  0x0, 0x0,
+#endif
+                  SHORTPAIR(domlen),
+                  SHORTPAIR(domlen),
+                  SHORTPAIR(domoff),
+                  0x0, 0x0,
+
+                  SHORTPAIR(userlen),
+                  SHORTPAIR(userlen),
+                  SHORTPAIR(useroff),
+                  0x0, 0x0,
+
+                  SHORTPAIR(hostlen),
+                  SHORTPAIR(hostlen),
+                  SHORTPAIR(hostoff),
+                  0x0, 0x0,
+
+                  0x0, 0x0,
+                  0x0, 0x0,
+                  0x0, 0x0,
+                  0x0, 0x0,
+
+                  LONGQUARTET(ntlm->flags));
+
+  DEBUGASSERT(size == 64);
+  DEBUGASSERT(size == (size_t)lmrespoff);
+
+  /* We append the binary hashes */
+  if(size < (NTLM_BUFSIZE - 0x18)) {
+    memcpy(&ntlmbuf[size], lmresp, 0x18);
+    size += 0x18;
+  }
+
+  DEBUG_OUT({
+    fprintf(stderr, "**** TYPE3 header lmresp=");
+    ntlm_print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18);
+  });
+
+#ifdef USE_NTRESPONSES
+  if(size < (NTLM_BUFSIZE - ntresplen)) {
+    DEBUGASSERT(size == (size_t)ntrespoff);
+    memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen);
+    size += ntresplen;
+  }
+
+  DEBUG_OUT({
+    fprintf(stderr, "\n   ntresp=");
+    ntlm_print_hex(stderr, (char *)&ntlmbuf[ntrespoff], ntresplen);
+  });
+
+  free(ntlmv2resp);/* Free the dynamic buffer allocated for NTLMv2 */
+
+#endif
+
+  DEBUG_OUT({
+    fprintf(stderr, "\n   flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
+            LONGQUARTET(ntlm->flags), ntlm->flags);
+    ntlm_print_flags(stderr, ntlm->flags);
+    fprintf(stderr, "\n****\n");
+  });
+
+  /* Make sure that the domain, user and host strings fit in the
+     buffer before we copy them there. */
+  if(size + userlen + domlen + hostlen >= NTLM_BUFSIZE) {
+    failf(data, "user + domain + host name too big");
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  DEBUGASSERT(size == domoff);
+  if(unicode)
+    unicodecpy(&ntlmbuf[size], domain, domlen / 2);
+  else
+    memcpy(&ntlmbuf[size], domain, domlen);
+
+  size += domlen;
+
+  DEBUGASSERT(size == useroff);
+  if(unicode)
+    unicodecpy(&ntlmbuf[size], user, userlen / 2);
+  else
+    memcpy(&ntlmbuf[size], user, userlen);
+
+  size += userlen;
+
+  DEBUGASSERT(size == hostoff);
+  if(unicode)
+    unicodecpy(&ntlmbuf[size], host, hostlen / 2);
+  else
+    memcpy(&ntlmbuf[size], host, hostlen);
+
+  size += hostlen;
+
+  /* Convert domain, user, and host to ASCII but leave the rest as-is */
+  result = Curl_convert_to_network(data, (char *)&ntlmbuf[domoff],
+                                   size - domoff);
+  if(result)
+    return CURLE_CONV_FAILED;
+
+  /* Return with binary blob encoded into base64 */
+  result = Curl_base64_encode(data, (char *)ntlmbuf, size, outptr, outlen);
+
+  Curl_auth_ntlm_cleanup(ntlm);
+
+  return result;
+}
+
+/*
+* Curl_auth_ntlm_cleanup()
+*
+* This is used to clean up the NTLM specific data.
+*
+* Parameters:
+*
+* ntlm    [in/out] - The NTLM data struct being cleaned up.
+*
+*/
+void Curl_auth_ntlm_cleanup(struct ntlmdata *ntlm)
+{
+  /* Free the target info */
+  Curl_safefree(ntlm->target_info);
+
+  /* Reset any variables */
+  ntlm->target_info_len = 0;
+}
+
+#endif /* USE_NTLM && !USE_WINDOWS_SSPI */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/ntlm.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/ntlm.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/ntlm.h	(revision 331)
@@ -0,0 +1,143 @@
+#ifndef HEADER_CURL_NTLM_H
+#define HEADER_CURL_NTLM_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_NTLM
+
+/* NTLM buffer fixed size, large enough for long user + host + domain */
+#define NTLM_BUFSIZE 1024
+
+/* Stuff only required for curl_ntlm_msgs.c */
+#ifdef BUILDING_CURL_NTLM_MSGS_C
+
+/* Flag bits definitions based on https://davenport.sourceforge.io/ntlm.html */
+
+#define NTLMFLAG_NEGOTIATE_UNICODE               (1<<0)
+/* Indicates that Unicode strings are supported for use in security buffer
+   data. */
+
+#define NTLMFLAG_NEGOTIATE_OEM                   (1<<1)
+/* Indicates that OEM strings are supported for use in security buffer data. */
+
+#define NTLMFLAG_REQUEST_TARGET                  (1<<2)
+/* Requests that the server's authentication realm be included in the Type 2
+   message. */
+
+/* unknown (1<<3) */
+#define NTLMFLAG_NEGOTIATE_SIGN                  (1<<4)
+/* Specifies that authenticated communication between the client and server
+   should carry a digital signature (message integrity). */
+
+#define NTLMFLAG_NEGOTIATE_SEAL                  (1<<5)
+/* Specifies that authenticated communication between the client and server
+   should be encrypted (message confidentiality). */
+
+#define NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE        (1<<6)
+/* Indicates that datagram authentication is being used. */
+
+#define NTLMFLAG_NEGOTIATE_LM_KEY                (1<<7)
+/* Indicates that the LAN Manager session key should be used for signing and
+   sealing authenticated communications. */
+
+#define NTLMFLAG_NEGOTIATE_NETWARE               (1<<8)
+/* unknown purpose */
+
+#define NTLMFLAG_NEGOTIATE_NTLM_KEY              (1<<9)
+/* Indicates that NTLM authentication is being used. */
+
+/* unknown (1<<10) */
+
+#define NTLMFLAG_NEGOTIATE_ANONYMOUS             (1<<11)
+/* Sent by the client in the Type 3 message to indicate that an anonymous
+   context has been established. This also affects the response fields. */
+
+#define NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED       (1<<12)
+/* Sent by the client in the Type 1 message to indicate that a desired
+   authentication realm is included in the message. */
+
+#define NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED  (1<<13)
+/* Sent by the client in the Type 1 message to indicate that the client
+   workstation's name is included in the message. */
+
+#define NTLMFLAG_NEGOTIATE_LOCAL_CALL            (1<<14)
+/* Sent by the server to indicate that the server and client are on the same
+   machine. Implies that the client may use a pre-established local security
+   context rather than responding to the challenge. */
+
+#define NTLMFLAG_NEGOTIATE_ALWAYS_SIGN           (1<<15)
+/* Indicates that authenticated communication between the client and server
+   should be signed with a "dummy" signature. */
+
+#define NTLMFLAG_TARGET_TYPE_DOMAIN              (1<<16)
+/* Sent by the server in the Type 2 message to indicate that the target
+   authentication realm is a domain. */
+
+#define NTLMFLAG_TARGET_TYPE_SERVER              (1<<17)
+/* Sent by the server in the Type 2 message to indicate that the target
+   authentication realm is a server. */
+
+#define NTLMFLAG_TARGET_TYPE_SHARE               (1<<18)
+/* Sent by the server in the Type 2 message to indicate that the target
+   authentication realm is a share. Presumably, this is for share-level
+   authentication. Usage is unclear. */
+
+#define NTLMFLAG_NEGOTIATE_NTLM2_KEY             (1<<19)
+/* Indicates that the NTLM2 signing and sealing scheme should be used for
+   protecting authenticated communications. */
+
+#define NTLMFLAG_REQUEST_INIT_RESPONSE           (1<<20)
+/* unknown purpose */
+
+#define NTLMFLAG_REQUEST_ACCEPT_RESPONSE         (1<<21)
+/* unknown purpose */
+
+#define NTLMFLAG_REQUEST_NONNT_SESSION_KEY       (1<<22)
+/* unknown purpose */
+
+#define NTLMFLAG_NEGOTIATE_TARGET_INFO           (1<<23)
+/* Sent by the server in the Type 2 message to indicate that it is including a
+   Target Information block in the message. */
+
+/* unknown (1<24) */
+/* unknown (1<25) */
+/* unknown (1<26) */
+/* unknown (1<27) */
+/* unknown (1<28) */
+
+#define NTLMFLAG_NEGOTIATE_128                   (1<<29)
+/* Indicates that 128-bit encryption is supported. */
+
+#define NTLMFLAG_NEGOTIATE_KEY_EXCHANGE          (1<<30)
+/* Indicates that the client will provide an encrypted master key in
+   the "Session Key" field of the Type 3 message. */
+
+#define NTLMFLAG_NEGOTIATE_56                    (1<<31)
+/* Indicates that 56-bit encryption is supported. */
+
+#endif /* BUILDING_CURL_NTLM_MSGS_C */
+
+#endif /* USE_NTLM */
+
+#endif /* HEADER_CURL_NTLM_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/oauth2.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/oauth2.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/oauth2.c	(revision 331)
@@ -0,0 +1,86 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * RFC6749 OAuth 2.0 Authorization Framework
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+#include "urldata.h"
+
+#include "vauth/vauth.h"
+#include "curl_base64.h"
+#include "warnless.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * Curl_auth_create_oauth_bearer_message()
+ *
+ * This is used to generate an already encoded OAuth 2.0 message ready for
+ * sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data[in]         - The session handle.
+ * user[in]         - The user name.
+ * host[in]         - The host name(for OAUTHBEARER).
+ * port[in]         - The port(for OAUTHBEARER when not Port 80).
+ * bearer[in]       - The bearer token.
+ * outptr[in / out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen[out]      - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_easy *data,
+                                               const char *user,
+                                               const char *host,
+                                               const long port,
+                                               const char *bearer,
+                                               char **outptr, size_t *outlen)
+{
+  CURLcode result = CURLE_OK;
+  char *oauth = NULL;
+
+  /* Generate the message */
+  if(host == NULL && (port == 0 || port == 80))
+    oauth = aprintf("user=%s\1auth=Bearer %s\1\1", user, bearer);
+  else if(port == 0 || port == 80)
+    oauth = aprintf("user=%s\1host=%s\1auth=Bearer %s\1\1", user, host,
+                    bearer);
+  else
+    oauth = aprintf("user=%s\1host=%s\1port=%ld\1auth=Bearer %s\1\1", user,
+                    host, port, bearer);
+  if(!oauth)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Base64 encode the reply */
+  result = Curl_base64_encode(data, oauth, strlen(oauth), outptr, outlen);
+
+  free(oauth);
+
+  return result;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/vauth.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/vauth.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/vauth.c	(revision 331)
@@ -0,0 +1,147 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2014 - 2016, Steve Holme, <steve_holme@hotmail.com>.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+
+#include "vauth.h"
+#include "curl_multibyte.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/*
+ * Curl_auth_build_spn()
+ *
+ * This is used to build a SPN string in the following formats:
+ *
+ * service/host@realm (Not currently used)
+ * service/host       (Not used by GSS-API)
+ * service@realm      (Not used by Windows SSPI)
+ *
+ * Parameters:
+ *
+ * service  [in] - The service type such as http, smtp, pop or imap.
+ * host     [in] - The host name.
+ * realm    [in] - The realm.
+ *
+ * Returns a pointer to the newly allocated SPN.
+ */
+#if !defined(USE_WINDOWS_SSPI)
+char *Curl_auth_build_spn(const char *service, const char *host,
+                          const char *realm)
+{
+  char *spn = NULL;
+
+  /* Generate our SPN */
+  if(host && realm)
+    spn = aprintf("%s/%s@%s", service, host, realm);
+  else if(host)
+    spn = aprintf("%s/%s", service, host);
+  else if(realm)
+    spn = aprintf("%s@%s", service, realm);
+
+  /* Return our newly allocated SPN */
+  return spn;
+}
+#else
+TCHAR *Curl_auth_build_spn(const char *service, const char *host,
+                           const char *realm)
+{
+  char *utf8_spn = NULL;
+  TCHAR *tchar_spn = NULL;
+
+  (void) realm;
+
+  /* Note: We could use DsMakeSPN() or DsClientMakeSpnForTargetServer() rather
+     than doing this ourselves but the first is only available in Windows XP
+     and Windows Server 2003 and the latter is only available in Windows 2000
+     but not Windows95/98/ME or Windows NT4.0 unless the Active Directory
+     Client Extensions are installed. As such it is far simpler for us to
+     formulate the SPN instead. */
+
+  /* Generate our UTF8 based SPN */
+  utf8_spn = aprintf("%s/%s", service, host);
+  if(!utf8_spn) {
+    return NULL;
+  }
+
+  /* Allocate our TCHAR based SPN */
+  tchar_spn = Curl_convert_UTF8_to_tchar(utf8_spn);
+  if(!tchar_spn) {
+    free(utf8_spn);
+
+    return NULL;
+  }
+
+  /* Release the UTF8 variant when operating with Unicode */
+  Curl_unicodefree(utf8_spn);
+
+  /* Return our newly allocated SPN */
+  return tchar_spn;
+}
+#endif /* USE_WINDOWS_SSPI */
+
+/*
+* Curl_auth_user_contains_domain()
+*
+* This is used to test if the specified user contains a Windows domain name as
+* follows:
+*
+* User\Domain (Down-level Logon Name)
+* User/Domain (curl Down-level format - for compatibility with existing code)
+* User@Domain (User Principal Name)
+*
+* Note: The user name may be empty when using a GSS-API library or Windows SSPI
+* as the user and domain are either obtained from the credientals cache when
+* using GSS-API or via the currently logged in user's credientals when using
+* Windows SSPI.
+*
+* Parameters:
+*
+* user  [in] - The user name.
+*
+* Returns TRUE on success; otherwise FALSE.
+*/
+bool Curl_auth_user_contains_domain(const char *user)
+{
+  bool valid = FALSE;
+
+  if(user && *user) {
+    /* Check we have a domain name or UPN present */
+    char *p = strpbrk(user, "\\/@");
+
+    valid = (p != NULL && p > user && p < user + strlen(user) - 1 ? TRUE :
+                                                                    FALSE);
+  }
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  else
+    /* User and domain are obtained from the GSS-API credientials cache or the
+       currently logged in user from Windows */
+    valid = TRUE;
+#endif
+
+  return valid;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/vauth.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/vauth.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vauth/vauth.h	(revision 331)
@@ -0,0 +1,205 @@
+#ifndef HEADER_CURL_VAUTH_H
+#define HEADER_CURL_VAUTH_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2014 - 2017, Steve Holme, <steve_holme@hotmail.com>.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h>
+
+struct Curl_easy;
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+struct digestdata;
+#endif
+
+#if defined(USE_NTLM)
+struct ntlmdata;
+#endif
+
+#if defined(USE_KERBEROS5)
+struct kerberos5data;
+#endif
+
+#if (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)) && defined(USE_SPNEGO)
+struct negotiatedata;
+#endif
+
+#if defined(USE_WINDOWS_SSPI)
+#define GSS_ERROR(status) (status & 0x80000000)
+#endif
+
+/* This is used to build a SPN string */
+#if !defined(USE_WINDOWS_SSPI)
+char *Curl_auth_build_spn(const char *service, const char *host,
+                          const char *realm);
+#else
+TCHAR *Curl_auth_build_spn(const char *service, const char *host,
+                           const char *realm);
+#endif
+
+/* This is used to test if the user contains a Windows domain name */
+bool Curl_auth_user_contains_domain(const char *user);
+
+/* This is used to generate a base64 encoded PLAIN cleartext message */
+CURLcode Curl_auth_create_plain_message(struct Curl_easy *data,
+                                        const char *userp,
+                                        const char *passwdp,
+                                        char **outptr, size_t *outlen);
+
+/* This is used to generate a base64 encoded LOGIN cleartext message */
+CURLcode Curl_auth_create_login_message(struct Curl_easy *data,
+                                        const char *valuep, char **outptr,
+                                        size_t *outlen);
+
+/* This is used to generate a base64 encoded EXTERNAL cleartext message */
+CURLcode Curl_auth_create_external_message(struct Curl_easy *data,
+                                           const char *user, char **outptr,
+                                           size_t *outlen);
+
+#if !defined(CURL_DISABLE_CRYPTO_AUTH)
+/* This is used to decode a CRAM-MD5 challenge message */
+CURLcode Curl_auth_decode_cram_md5_message(const char *chlg64, char **outptr,
+                                           size_t *outlen);
+
+/* This is used to generate a CRAM-MD5 response message */
+CURLcode Curl_auth_create_cram_md5_message(struct Curl_easy *data,
+                                           const char *chlg,
+                                           const char *userp,
+                                           const char *passwdp,
+                                           char **outptr, size_t *outlen);
+
+/* This is used to evaluate if DIGEST is supported */
+bool Curl_auth_is_digest_supported(void);
+
+/* This is used to generate a base64 encoded DIGEST-MD5 response message */
+CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data,
+                                             const char *chlg64,
+                                             const char *userp,
+                                             const char *passwdp,
+                                             const char *service,
+                                             char **outptr, size_t *outlen);
+
+/* This is used to decode a HTTP DIGEST challenge message */
+CURLcode Curl_auth_decode_digest_http_message(const char *chlg,
+                                              struct digestdata *digest);
+
+/* This is used to generate a HTTP DIGEST response message */
+CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data,
+                                              const char *userp,
+                                              const char *passwdp,
+                                              const unsigned char *request,
+                                              const unsigned char *uri,
+                                              struct digestdata *digest,
+                                              char **outptr, size_t *outlen);
+
+/* This is used to clean up the digest specific data */
+void Curl_auth_digest_cleanup(struct digestdata *digest);
+#endif /* !CURL_DISABLE_CRYPTO_AUTH */
+
+#if defined(USE_NTLM)
+/* This is used to evaluate if NTLM is supported */
+bool Curl_auth_is_ntlm_supported(void);
+
+/* This is used to generate a base64 encoded NTLM type-1 message */
+CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
+                                             const char *userp,
+                                             const char *passwdp,
+                                             struct ntlmdata *ntlm,
+                                             char **outptr,
+                                             size_t *outlen);
+
+/* This is used to decode a base64 encoded NTLM type-2 message */
+CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data,
+                                             const char *type2msg,
+                                             struct ntlmdata *ntlm);
+
+/* This is used to generate a base64 encoded NTLM type-3 message */
+CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
+                                             const char *userp,
+                                             const char *passwdp,
+                                             struct ntlmdata *ntlm,
+                                             char **outptr, size_t *outlen);
+
+/* This is used to clean up the NTLM specific data */
+void Curl_auth_ntlm_cleanup(struct ntlmdata *ntlm);
+#endif /* USE_NTLM */
+
+/* This is used to generate a base64 encoded OAuth 2.0 message */
+CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_easy *data,
+                                               const char *user,
+                                               const char *host,
+                                               const long port,
+                                               const char *bearer,
+                                               char **outptr, size_t *outlen);
+#if defined(USE_KERBEROS5)
+/* This is used to evaluate if GSSAPI (Kerberos V5) is supported */
+bool Curl_auth_is_gssapi_supported(void);
+
+/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) user token
+   message */
+CURLcode Curl_auth_create_gssapi_user_message(struct Curl_easy *data,
+                                              const char *userp,
+                                              const char *passwdp,
+                                              const char *service,
+                                              const char *host,
+                                              const bool mutual,
+                                              const char *chlg64,
+                                              struct kerberos5data *krb5,
+                                              char **outptr, size_t *outlen);
+
+/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) security
+   token message */
+CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data,
+                                                  const char *input,
+                                                  struct kerberos5data *krb5,
+                                                  char **outptr,
+                                                  size_t *outlen);
+
+/* This is used to clean up the GSSAPI specific data */
+void Curl_auth_gssapi_cleanup(struct kerberos5data *krb5);
+#endif /* USE_KERBEROS5 */
+
+#if defined(USE_SPNEGO)
+/* This is used to evaluate if SPNEGO (Negotiate) is supported */
+bool Curl_auth_is_spnego_supported(void);
+
+/* This is used to decode a base64 encoded SPNEGO (Negotiate) challenge
+   message */
+CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
+                                         const char *user,
+                                         const char *passwood,
+                                         const char *service,
+                                         const char *host,
+                                         const char *chlg64,
+                                         struct negotiatedata *nego);
+
+/* This is used to generate a base64 encoded SPNEGO (Negotiate) response
+   message */
+CURLcode Curl_auth_create_spnego_message(struct Curl_easy *data,
+                                         struct negotiatedata *nego,
+                                         char **outptr, size_t *outlen);
+
+/* This is used to clean up the SPNEGO specifiec data */
+void Curl_auth_spnego_cleanup(struct negotiatedata *nego);
+
+#endif /* USE_SPNEGO */
+
+#endif /* HEADER_CURL_VAUTH_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/version.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/version.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/version.c	(revision 331)
@@ -0,0 +1,449 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "vtls/vtls.h"
+#include "http2.h"
+#include "curl_printf.h"
+
+#ifdef USE_ARES
+#  if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \
+     (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__))
+#    define CARES_STATICLIB
+#  endif
+#  include <ares.h>
+#endif
+
+#ifdef USE_LIBIDN2
+#include <idn2.h>
+#endif
+
+#ifdef USE_LIBPSL
+#include <libpsl.h>
+#endif
+
+#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
+#include <iconv.h>
+#endif
+
+#ifdef USE_LIBRTMP
+#include <librtmp/rtmp.h>
+#endif
+
+#ifdef USE_LIBSSH2
+#include <libssh2.h>
+#endif
+
+#ifdef HAVE_LIBSSH2_VERSION
+/* get it run-time if possible */
+#define CURL_LIBSSH2_VERSION libssh2_version(0)
+#else
+/* use build-time if run-time not possible */
+#define CURL_LIBSSH2_VERSION LIBSSH2_VERSION
+#endif
+
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#ifdef __SYMBIAN32__
+/* zlib pollutes the namespace with this definition */
+#undef WIN32
+#endif
+#endif
+
+#ifdef HAVE_BROTLI
+#include <brotli/decode.h>
+#endif
+
+void Curl_version_init(void);
+
+/* For thread safety purposes this function is called by global_init so that
+   the static data in both version functions is initialized. */
+void Curl_version_init(void)
+{
+  curl_version();
+  curl_version_info(CURLVERSION_NOW);
+}
+
+#ifdef HAVE_BROTLI
+static size_t brotli_version(char *buf, size_t bufsz)
+{
+  uint32_t brotli_version = BrotliDecoderVersion();
+  unsigned int major = brotli_version >> 24;
+  unsigned int minor = (brotli_version & 0x00FFFFFF) >> 12;
+  unsigned int patch = brotli_version & 0x00000FFF;
+
+  return snprintf(buf, bufsz, "%u.%u.%u", major, minor, patch);
+}
+#endif
+
+char *curl_version(void)
+{
+  static bool initialized;
+  static char version[200];
+  char *ptr = version;
+  size_t len;
+  size_t left = sizeof(version);
+
+  if(initialized)
+    return version;
+
+  strcpy(ptr, LIBCURL_NAME "/" LIBCURL_VERSION);
+  len = strlen(ptr);
+  left -= len;
+  ptr += len;
+
+  if(left > 1) {
+    len = Curl_ssl_version(ptr + 1, left - 1);
+
+    if(len > 0) {
+      *ptr = ' ';
+      left -= ++len;
+      ptr += len;
+    }
+  }
+
+#ifdef HAVE_LIBZ
+  len = snprintf(ptr, left, " zlib/%s", zlibVersion());
+  left -= len;
+  ptr += len;
+#endif
+#ifdef HAVE_BROTLI
+  len = snprintf(ptr, left, "%s", " brotli/");
+  left -= len;
+  ptr += len;
+  len = brotli_version(ptr, left);
+  left -= len;
+  ptr += len;
+#endif
+#ifdef USE_ARES
+  /* this function is only present in c-ares, not in the original ares */
+  len = snprintf(ptr, left, " c-ares/%s", ares_version(NULL));
+  left -= len;
+  ptr += len;
+#endif
+#ifdef USE_LIBIDN2
+  if(idn2_check_version(IDN2_VERSION)) {
+    len = snprintf(ptr, left, " libidn2/%s", idn2_check_version(NULL));
+    left -= len;
+    ptr += len;
+  }
+#endif
+#ifdef USE_LIBPSL
+  len = snprintf(ptr, left, " libpsl/%s", psl_get_version());
+  left -= len;
+  ptr += len;
+#endif
+#ifdef USE_WIN32_IDN
+  len = snprintf(ptr, left, " WinIDN");
+  left -= len;
+  ptr += len;
+#endif
+#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
+#ifdef _LIBICONV_VERSION
+  len = snprintf(ptr, left, " iconv/%d.%d",
+                 _LIBICONV_VERSION >> 8, _LIBICONV_VERSION & 255);
+#else
+  /* version unknown */
+  len = snprintf(ptr, left, " iconv");
+#endif /* _LIBICONV_VERSION */
+  left -= len;
+  ptr += len;
+#endif
+#ifdef USE_LIBSSH2
+  len = snprintf(ptr, left, " libssh2/%s", CURL_LIBSSH2_VERSION);
+  left -= len;
+  ptr += len;
+#endif
+#ifdef USE_NGHTTP2
+  len = Curl_http2_ver(ptr, left);
+  left -= len;
+  ptr += len;
+#endif
+#ifdef USE_LIBRTMP
+  {
+    char suff[2];
+    if(RTMP_LIB_VERSION & 0xff) {
+      suff[0] = (RTMP_LIB_VERSION & 0xff) + 'a' - 1;
+      suff[1] = '\0';
+    }
+    else
+      suff[0] = '\0';
+
+    snprintf(ptr, left, " librtmp/%d.%d%s",
+             RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff,
+             suff);
+/*
+  If another lib version is added below this one, this code would
+  also have to do:
+
+    len = what snprintf() returned
+
+    left -= len;
+    ptr += len;
+*/
+  }
+#endif
+
+  initialized = true;
+  return version;
+}
+
+/* data for curl_version_info
+
+   Keep the list sorted alphabetically. It is also written so that each
+   protocol line has its own #if line to make things easier on the eye.
+ */
+
+static const char * const protocols[] = {
+#ifndef CURL_DISABLE_DICT
+  "dict",
+#endif
+#ifndef CURL_DISABLE_FILE
+  "file",
+#endif
+#ifndef CURL_DISABLE_FTP
+  "ftp",
+#endif
+#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
+  "ftps",
+#endif
+#ifndef CURL_DISABLE_GOPHER
+  "gopher",
+#endif
+#ifndef CURL_DISABLE_HTTP
+  "http",
+#endif
+#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
+  "https",
+#endif
+#ifndef CURL_DISABLE_IMAP
+  "imap",
+#endif
+#if defined(USE_SSL) && !defined(CURL_DISABLE_IMAP)
+  "imaps",
+#endif
+#ifndef CURL_DISABLE_LDAP
+  "ldap",
+#if !defined(CURL_DISABLE_LDAPS) && \
+    ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \
+     (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL)))
+  "ldaps",
+#endif
+#endif
+#ifndef CURL_DISABLE_POP3
+  "pop3",
+#endif
+#if defined(USE_SSL) && !defined(CURL_DISABLE_POP3)
+  "pop3s",
+#endif
+#ifdef USE_LIBRTMP
+  "rtmp",
+#endif
+#ifndef CURL_DISABLE_RTSP
+  "rtsp",
+#endif
+#ifdef USE_LIBSSH2
+  "scp",
+#endif
+#ifdef USE_LIBSSH2
+  "sftp",
+#endif
+#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \
+   (CURL_SIZEOF_CURL_OFF_T > 4) && \
+   (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO))
+  "smb",
+#  ifdef USE_SSL
+  "smbs",
+#  endif
+#endif
+#ifndef CURL_DISABLE_SMTP
+  "smtp",
+#endif
+#if defined(USE_SSL) && !defined(CURL_DISABLE_SMTP)
+  "smtps",
+#endif
+#ifndef CURL_DISABLE_TELNET
+  "telnet",
+#endif
+#ifndef CURL_DISABLE_TFTP
+  "tftp",
+#endif
+
+  NULL
+};
+
+static curl_version_info_data version_info = {
+  CURLVERSION_NOW,
+  LIBCURL_VERSION,
+  LIBCURL_VERSION_NUM,
+  OS, /* as found by configure or set by hand at build-time */
+  0 /* features is 0 by default */
+#ifdef ENABLE_IPV6
+  | CURL_VERSION_IPV6
+#endif
+#ifdef USE_SSL
+  | CURL_VERSION_SSL
+#endif
+#ifdef USE_NTLM
+  | CURL_VERSION_NTLM
+#endif
+#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \
+  defined(NTLM_WB_ENABLED)
+  | CURL_VERSION_NTLM_WB
+#endif
+#ifdef USE_SPNEGO
+  | CURL_VERSION_SPNEGO
+#endif
+#ifdef USE_KERBEROS5
+  | CURL_VERSION_KERBEROS5
+#endif
+#ifdef HAVE_GSSAPI
+  | CURL_VERSION_GSSAPI
+#endif
+#ifdef USE_WINDOWS_SSPI
+  | CURL_VERSION_SSPI
+#endif
+#ifdef HAVE_LIBZ
+  | CURL_VERSION_LIBZ
+#endif
+#ifdef DEBUGBUILD
+  | CURL_VERSION_DEBUG
+#endif
+#ifdef CURLDEBUG
+  | CURL_VERSION_CURLDEBUG
+#endif
+#ifdef CURLRES_ASYNCH
+  | CURL_VERSION_ASYNCHDNS
+#endif
+#if (CURL_SIZEOF_CURL_OFF_T > 4) && \
+    ( (SIZEOF_OFF_T > 4) || defined(USE_WIN32_LARGE_FILES) )
+  | CURL_VERSION_LARGEFILE
+#endif
+#if defined(CURL_DOES_CONVERSIONS)
+  | CURL_VERSION_CONV
+#endif
+#if defined(USE_TLS_SRP)
+  | CURL_VERSION_TLSAUTH_SRP
+#endif
+#if defined(USE_NGHTTP2)
+  | CURL_VERSION_HTTP2
+#endif
+#if defined(USE_UNIX_SOCKETS)
+  | CURL_VERSION_UNIX_SOCKETS
+#endif
+#if defined(USE_LIBPSL)
+  | CURL_VERSION_PSL
+#endif
+#if defined(CURL_WITH_MULTI_SSL)
+  | CURL_VERSION_MULTI_SSL
+#endif
+#if defined(HAVE_BROTLI)
+  | CURL_VERSION_BROTLI
+#endif
+  ,
+  NULL, /* ssl_version */
+  0,    /* ssl_version_num, this is kept at zero */
+  NULL, /* zlib_version */
+  protocols,
+  NULL, /* c-ares version */
+  0,    /* c-ares version numerical */
+  NULL, /* libidn version */
+  0,    /* iconv version */
+  NULL, /* ssh lib version */
+  0,    /* brotli_ver_num */
+  NULL, /* brotli version */
+};
+
+curl_version_info_data *curl_version_info(CURLversion stamp)
+{
+  static bool initialized;
+#ifdef USE_LIBSSH2
+  static char ssh_buffer[80];
+#endif
+#ifdef USE_SSL
+  static char ssl_buffer[80];
+#endif
+#ifdef HAVE_BROTLI
+  static char brotli_buffer[80];
+#endif
+
+  if(initialized)
+    return &version_info;
+
+#ifdef USE_SSL
+  Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer));
+  version_info.ssl_version = ssl_buffer;
+  if(Curl_ssl->support_https_proxy)
+    version_info.features |= CURL_VERSION_HTTPS_PROXY;
+  else
+    version_info.features &= ~CURL_VERSION_HTTPS_PROXY;
+#endif
+
+#ifdef HAVE_LIBZ
+  version_info.libz_version = zlibVersion();
+  /* libz left NULL if non-existing */
+#endif
+#ifdef USE_ARES
+  {
+    int aresnum;
+    version_info.ares = ares_version(&aresnum);
+    version_info.ares_num = aresnum;
+  }
+#endif
+#ifdef USE_LIBIDN2
+  /* This returns a version string if we use the given version or later,
+     otherwise it returns NULL */
+  version_info.libidn = idn2_check_version(IDN2_VERSION);
+  if(version_info.libidn)
+    version_info.features |= CURL_VERSION_IDN;
+#elif defined(USE_WIN32_IDN)
+  version_info.features |= CURL_VERSION_IDN;
+#endif
+
+#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS)
+#ifdef _LIBICONV_VERSION
+  version_info.iconv_ver_num = _LIBICONV_VERSION;
+#else
+  /* version unknown */
+  version_info.iconv_ver_num = -1;
+#endif /* _LIBICONV_VERSION */
+#endif
+
+#ifdef USE_LIBSSH2
+  snprintf(ssh_buffer, sizeof(ssh_buffer), "libssh2/%s", LIBSSH2_VERSION);
+  version_info.libssh_version = ssh_buffer;
+#endif
+
+#ifdef HAVE_BROTLI
+  version_info.brotli_ver_num = BrotliDecoderVersion();
+  brotli_version(brotli_buffer, sizeof brotli_buffer);
+  version_info.brotli_version = brotli_buffer;
+#endif
+
+  (void)stamp; /* avoid compiler warnings, we don't use this */
+
+  initialized = true;
+  return &version_info;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/axtls.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/axtls.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/axtls.c	(revision 331)
@@ -0,0 +1,742 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010, DirecTV, Contact: Eric Hu, <ehu@directv.com>.
+ * Copyright (C) 2010 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all axTLS-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_AXTLS
+#include <axTLS/config.h>
+#include <axTLS/ssl.h>
+#include "axtls.h"
+
+#include "sendf.h"
+#include "inet_pton.h"
+#include "vtls.h"
+#include "parsedate.h"
+#include "connect.h" /* for the connect timeout */
+#include "select.h"
+#include "curl_printf.h"
+#include "hostcheck.h"
+#include <unistd.h>
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+struct ssl_backend_data {
+  SSL_CTX* ssl_ctx;
+  SSL*     ssl;
+};
+
+#define BACKEND connssl->backend
+
+static CURLcode map_error_to_curl(int axtls_err)
+{
+  switch(axtls_err) {
+  case SSL_ERROR_NOT_SUPPORTED:
+  case SSL_ERROR_INVALID_VERSION:
+  case -70:                       /* protocol version alert from server */
+    return CURLE_UNSUPPORTED_PROTOCOL;
+    break;
+  case SSL_ERROR_NO_CIPHER:
+    return CURLE_SSL_CIPHER;
+    break;
+  case SSL_ERROR_BAD_CERTIFICATE: /* this may be bad server cert too */
+  case SSL_ERROR_NO_CERT_DEFINED:
+  case -42:                       /* bad certificate alert from server */
+  case -43:                       /* unsupported cert alert from server */
+  case -44:                       /* cert revoked alert from server */
+  case -45:                       /* cert expired alert from server */
+  case -46:                       /* cert unknown alert from server */
+    return CURLE_SSL_CERTPROBLEM;
+    break;
+  case SSL_X509_ERROR(X509_NOT_OK):
+  case SSL_X509_ERROR(X509_VFY_ERROR_NO_TRUSTED_CERT):
+  case SSL_X509_ERROR(X509_VFY_ERROR_BAD_SIGNATURE):
+  case SSL_X509_ERROR(X509_VFY_ERROR_NOT_YET_VALID):
+  case SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED):
+  case SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED):
+  case SSL_X509_ERROR(X509_VFY_ERROR_INVALID_CHAIN):
+  case SSL_X509_ERROR(X509_VFY_ERROR_UNSUPPORTED_DIGEST):
+  case SSL_X509_ERROR(X509_INVALID_PRIV_KEY):
+    return CURLE_PEER_FAILED_VERIFICATION;
+    break;
+  case -48:                       /* unknown ca alert from server */
+    return CURLE_SSL_CACERT;
+    break;
+  case -49:                       /* access denied alert from server */
+    return CURLE_REMOTE_ACCESS_DENIED;
+    break;
+  case SSL_ERROR_CONN_LOST:
+  case SSL_ERROR_SOCK_SETUP_FAILURE:
+  case SSL_ERROR_INVALID_HANDSHAKE:
+  case SSL_ERROR_INVALID_PROT_MSG:
+  case SSL_ERROR_INVALID_HMAC:
+  case SSL_ERROR_INVALID_SESSION:
+  case SSL_ERROR_INVALID_KEY:     /* it's too bad this doesn't map better */
+  case SSL_ERROR_FINISHED_INVALID:
+  case SSL_ERROR_NO_CLIENT_RENOG:
+  default:
+    return CURLE_SSL_CONNECT_ERROR;
+    break;
+  }
+}
+
+static Curl_recv axtls_recv;
+static Curl_send axtls_send;
+
+static void free_ssl_structs(struct ssl_connect_data *connssl)
+{
+  if(BACKEND->ssl) {
+    ssl_free(BACKEND->ssl);
+    BACKEND->ssl = NULL;
+  }
+  if(BACKEND->ssl_ctx) {
+    ssl_ctx_free(BACKEND->ssl_ctx);
+    BACKEND->ssl_ctx = NULL;
+  }
+}
+
+/*
+ * For both blocking and non-blocking connects, this function sets up the
+ * ssl context and state.  This function is called after the TCP connect
+ * has completed.
+ */
+static CURLcode connect_prep(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct Curl_easy *data = conn->data;
+  SSL_CTX *ssl_ctx;
+  SSL *ssl = NULL;
+  int cert_types[] = {SSL_OBJ_X509_CERT, SSL_OBJ_PKCS12, 0};
+  int key_types[] = {SSL_OBJ_RSA_KEY, SSL_OBJ_PKCS8, SSL_OBJ_PKCS12, 0};
+  int i, ssl_fcn_return;
+
+  /* Assuming users will not compile in custom key/cert to axTLS.
+  *  Also, even for blocking connects, use axTLS non-blocking feature.
+  */
+  uint32_t client_option = SSL_NO_DEFAULT_KEY |
+    SSL_SERVER_VERIFY_LATER |
+    SSL_CONNECT_IN_PARTS;
+
+  if(connssl->state == ssl_connection_complete)
+    /* to make us tolerant against being called more than once for the
+       same connection */
+    return CURLE_OK;
+
+  if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) {
+    failf(data, "axtls does not support CURL_SSLVERSION_MAX");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+
+  /* axTLS only supports TLSv1 */
+  /* check to see if we've been told to use an explicit SSL/TLS version */
+  switch(SSL_CONN_CONFIG(version)) {
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+    break;
+  default:
+    failf(data, "axTLS only supports TLS 1.0 and 1.1, "
+          "and it cannot be specified which one to use");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+#ifdef  AXTLSDEBUG
+  client_option |= SSL_DISPLAY_STATES | SSL_DISPLAY_RSA | SSL_DISPLAY_CERTS;
+#endif /* AXTLSDEBUG */
+
+  /* Allocate an SSL_CTX struct */
+  ssl_ctx = ssl_ctx_new(client_option, SSL_DEFAULT_CLNT_SESS);
+  if(ssl_ctx == NULL) {
+    failf(data, "unable to create client SSL context");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  BACKEND->ssl_ctx = ssl_ctx;
+  BACKEND->ssl = NULL;
+
+  /* Load the trusted CA cert bundle file */
+  if(SSL_CONN_CONFIG(CAfile)) {
+    if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT,
+                    SSL_CONN_CONFIG(CAfile), NULL) != SSL_OK) {
+      infof(data, "error reading ca cert file %s \n",
+            SSL_CONN_CONFIG(CAfile));
+      if(SSL_CONN_CONFIG(verifypeer)) {
+        return CURLE_SSL_CACERT_BADFILE;
+      }
+    }
+    else
+      infof(data, "found certificates in %s\n", SSL_CONN_CONFIG(CAfile));
+  }
+
+  /* gtls.c tasks we're skipping for now:
+   * 1) certificate revocation list checking
+   * 2) dns name assignment to host
+   * 3) set protocol priority.  axTLS is TLSv1 only, so can probably ignore
+   * 4) set certificate priority.  axTLS ignores type and sends certs in
+   *  order added.  can probably ignore this.
+   */
+
+  /* Load client certificate */
+  if(SSL_SET_OPTION(cert)) {
+    i = 0;
+    /* Instead of trying to analyze cert type here, let axTLS try them all. */
+    while(cert_types[i] != 0) {
+      ssl_fcn_return = ssl_obj_load(ssl_ctx, cert_types[i],
+                                    SSL_SET_OPTION(cert), NULL);
+      if(ssl_fcn_return == SSL_OK) {
+        infof(data, "successfully read cert file %s \n",
+              SSL_SET_OPTION(cert));
+        break;
+      }
+      i++;
+    }
+    /* Tried all cert types, none worked. */
+    if(cert_types[i] == 0) {
+      failf(data, "%s is not x509 or pkcs12 format",
+            SSL_SET_OPTION(cert));
+      return CURLE_SSL_CERTPROBLEM;
+    }
+  }
+
+  /* Load client key.
+     If a pkcs12 file successfully loaded a cert, then there's nothing to do
+     because the key has already been loaded. */
+  if(SSL_SET_OPTION(key) && cert_types[i] != SSL_OBJ_PKCS12) {
+    i = 0;
+    /* Instead of trying to analyze key type here, let axTLS try them all. */
+    while(key_types[i] != 0) {
+      ssl_fcn_return = ssl_obj_load(ssl_ctx, key_types[i],
+                                    SSL_SET_OPTION(key), NULL);
+      if(ssl_fcn_return == SSL_OK) {
+        infof(data, "successfully read key file %s \n",
+              SSL_SET_OPTION(key));
+        break;
+      }
+      i++;
+    }
+    /* Tried all key types, none worked. */
+    if(key_types[i] == 0) {
+      failf(data, "Failure: %s is not a supported key file",
+            SSL_SET_OPTION(key));
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+
+  /* gtls.c does more here that is being left out for now
+   * 1) set session credentials.  can probably ignore since axtls puts this
+   *    info in the ssl_ctx struct
+   * 2) setting up callbacks.  these seem gnutls specific
+   */
+
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    const uint8_t *ssl_sessionid;
+    size_t ssl_idsize;
+
+    /* In axTLS, handshaking happens inside ssl_client_new. */
+    Curl_ssl_sessionid_lock(conn);
+    if(!Curl_ssl_getsessionid(conn, (void **) &ssl_sessionid, &ssl_idsize,
+                              sockindex)) {
+      /* we got a session id, use it! */
+      infof(data, "SSL re-using session ID\n");
+      ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex],
+                           ssl_sessionid, (uint8_t)ssl_idsize, NULL);
+    }
+    Curl_ssl_sessionid_unlock(conn);
+  }
+
+  if(!ssl)
+    ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0, NULL);
+
+  BACKEND->ssl = ssl;
+  return CURLE_OK;
+}
+
+static void Curl_axtls_close(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  infof(conn->data, "  Curl_axtls_close\n");
+
+    /* line from openssl.c: (void)SSL_shutdown(BACKEND->ssl);
+       axTLS compat layer does nothing for SSL_shutdown */
+
+    /* The following line is from openssl.c.  There seems to be no axTLS
+       equivalent.  ssl_free and ssl_ctx_free close things.
+       SSL_set_connect_state(connssl->handle); */
+
+  free_ssl_structs(connssl);
+}
+
+/*
+ * For both blocking and non-blocking connects, this function finalizes the
+ * SSL connection.
+ */
+static CURLcode connect_finish(struct connectdata *conn, int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  SSL *ssl = BACKEND->ssl;
+  const char *peer_CN;
+  uint32_t dns_altname_index;
+  const char *dns_altname;
+  int8_t found_subject_alt_names = 0;
+  int8_t found_subject_alt_name_matching_conn = 0;
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+  const char * const dispname = SSL_IS_PROXY() ?
+    conn->http_proxy.host.dispname : conn->host.dispname;
+
+  /* Here, gtls.c gets the peer certificates and fails out depending on
+   * settings in "data."  axTLS api doesn't have get cert chain fcn, so omit?
+   */
+
+  /* Verify server's certificate */
+  if(SSL_CONN_CONFIG(verifypeer)) {
+    if(ssl_verify_cert(ssl) != SSL_OK) {
+      Curl_axtls_close(conn, sockindex);
+      failf(data, "server cert verify failed");
+      return CURLE_PEER_FAILED_VERIFICATION;
+    }
+  }
+  else
+    infof(data, "\t server certificate verification SKIPPED\n");
+
+  /* Here, gtls.c does issuer verification. axTLS has no straightforward
+   * equivalent, so omitting for now.*/
+
+  /* Here, gtls.c does the following
+   * 1) x509 hostname checking per RFC2818.  axTLS doesn't support this, but
+   *    it seems useful. This is now implemented, by Oscar Koeroo
+   * 2) checks cert validity based on time.  axTLS does this in ssl_verify_cert
+   * 3) displays a bunch of cert information.  axTLS doesn't support most of
+   *    this, but a couple fields are available.
+   */
+
+  /* There is no (DNS) Altnames count in the version 1.4.8 API. There is a
+     risk of an inifite loop */
+  for(dns_altname_index = 0; ; dns_altname_index++) {
+    dns_altname = ssl_get_cert_subject_alt_dnsname(ssl, dns_altname_index);
+    if(dns_altname == NULL) {
+      break;
+    }
+    found_subject_alt_names = 1;
+
+    infof(data, "\tComparing subject alt name DNS with hostname: %s <-> %s\n",
+          dns_altname, hostname);
+    if(Curl_cert_hostcheck(dns_altname, hostname)) {
+      found_subject_alt_name_matching_conn = 1;
+      break;
+    }
+  }
+
+  /* RFC2818 checks */
+  if(found_subject_alt_names && !found_subject_alt_name_matching_conn) {
+    if(SSL_CONN_CONFIG(verifyhost)) {
+      /* Break connection ! */
+      Curl_axtls_close(conn, sockindex);
+      failf(data, "\tsubjectAltName(s) do not match %s\n", dispname);
+      return CURLE_PEER_FAILED_VERIFICATION;
+    }
+    else
+      infof(data, "\tsubjectAltName(s) do not match %s\n", dispname);
+  }
+  else if(found_subject_alt_names == 0) {
+    /* Per RFC2818, when no Subject Alt Names were available, examine the peer
+       CN as a legacy fallback */
+    peer_CN = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME);
+    if(peer_CN == NULL) {
+      if(SSL_CONN_CONFIG(verifyhost)) {
+        Curl_axtls_close(conn, sockindex);
+        failf(data, "unable to obtain common name from peer certificate");
+        return CURLE_PEER_FAILED_VERIFICATION;
+      }
+      else
+        infof(data, "unable to obtain common name from peer certificate");
+    }
+    else {
+      if(!Curl_cert_hostcheck((const char *)peer_CN, hostname)) {
+        if(SSL_CONN_CONFIG(verifyhost)) {
+          /* Break connection ! */
+          Curl_axtls_close(conn, sockindex);
+          failf(data, "\tcommon name \"%s\" does not match \"%s\"\n",
+                peer_CN, dispname);
+          return CURLE_PEER_FAILED_VERIFICATION;
+        }
+        else
+          infof(data, "\tcommon name \"%s\" does not match \"%s\"\n",
+                peer_CN, dispname);
+      }
+    }
+  }
+
+  /* General housekeeping */
+  connssl->state = ssl_connection_complete;
+  conn->recv[sockindex] = axtls_recv;
+  conn->send[sockindex] = axtls_send;
+
+  /* Put our freshly minted SSL session in cache */
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    const uint8_t *ssl_sessionid = ssl_get_session_id(ssl);
+    size_t ssl_idsize = ssl_get_session_id_size(ssl);
+    Curl_ssl_sessionid_lock(conn);
+    if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize,
+                             sockindex) != CURLE_OK)
+      infof(data, "failed to add session to cache\n");
+    Curl_ssl_sessionid_unlock(conn);
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * Use axTLS's non-blocking connection feature to open an SSL connection.
+ * This is called after a TCP connection is already established.
+ */
+static CURLcode Curl_axtls_connect_nonblocking(struct connectdata *conn,
+                                               int sockindex, bool *done)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  CURLcode conn_step;
+  int ssl_fcn_return;
+  int i;
+
+ *done = FALSE;
+  /* connectdata is calloc'd and connecting_state is only changed in this
+     function, so this is safe, as the state is effectively initialized. */
+  if(connssl->connecting_state == ssl_connect_1) {
+    conn_step = connect_prep(conn, sockindex);
+    if(conn_step != CURLE_OK) {
+      Curl_axtls_close(conn, sockindex);
+      return conn_step;
+    }
+    connssl->connecting_state = ssl_connect_2;
+  }
+
+  if(connssl->connecting_state == ssl_connect_2) {
+    /* Check to make sure handshake was ok. */
+    if(ssl_handshake_status(BACKEND->ssl) != SSL_OK) {
+      /* Loop to perform more work in between sleeps. This is work around the
+         fact that axtls does not expose any knowledge about when work needs
+         to be performed. This can save ~25% of time on SSL handshakes. */
+      for(i = 0; i<5; i++) {
+        ssl_fcn_return = ssl_read(BACKEND->ssl, NULL);
+        if(ssl_fcn_return < 0) {
+          Curl_axtls_close(conn, sockindex);
+          ssl_display_error(ssl_fcn_return); /* goes to stdout. */
+          return map_error_to_curl(ssl_fcn_return);
+        }
+        return CURLE_OK;
+      }
+    }
+    infof(conn->data, "handshake completed successfully\n");
+    connssl->connecting_state = ssl_connect_3;
+  }
+
+  if(connssl->connecting_state == ssl_connect_3) {
+    conn_step = connect_finish(conn, sockindex);
+    if(conn_step != CURLE_OK) {
+      Curl_axtls_close(conn, sockindex);
+      return conn_step;
+    }
+
+    /* Reset connect state */
+    connssl->connecting_state = ssl_connect_1;
+
+    *done = TRUE;
+    return CURLE_OK;
+  }
+
+  /* Unrecognized state.  Things are very bad. */
+  connssl->state  = ssl_connection_none;
+  connssl->connecting_state = ssl_connect_1;
+  /* Return value perhaps not strictly correct, but distinguishes the issue.*/
+  return CURLE_BAD_FUNCTION_ARGUMENT;
+}
+
+
+/*
+ * This function is called after the TCP connect has completed. Setup the TLS
+ * layer and do all necessary magic for a blocking connect.
+ */
+static CURLcode Curl_axtls_connect(struct connectdata *conn, int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  CURLcode conn_step = connect_prep(conn, sockindex);
+  int ssl_fcn_return;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  SSL *ssl = BACKEND->ssl;
+  long timeout_ms;
+
+  if(conn_step != CURLE_OK) {
+    Curl_axtls_close(conn, sockindex);
+    return conn_step;
+  }
+
+  /* Check to make sure handshake was ok. */
+  while(ssl_handshake_status(ssl) != SSL_OK) {
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    ssl_fcn_return = ssl_read(ssl, NULL);
+    if(ssl_fcn_return < 0) {
+      Curl_axtls_close(conn, sockindex);
+      ssl_display_error(ssl_fcn_return); /* goes to stdout. */
+      return map_error_to_curl(ssl_fcn_return);
+    }
+    /* TODO: avoid polling */
+    Curl_wait_ms(10);
+  }
+  infof(conn->data, "handshake completed successfully\n");
+
+  conn_step = connect_finish(conn, sockindex);
+  if(conn_step != CURLE_OK) {
+    Curl_axtls_close(conn, sockindex);
+    return conn_step;
+  }
+
+  return CURLE_OK;
+}
+
+/* return number of sent (non-SSL) bytes */
+static ssize_t axtls_send(struct connectdata *conn,
+                          int sockindex,
+                          const void *mem,
+                          size_t len,
+                          CURLcode *err)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  /* ssl_write() returns 'int' while write() and send() returns 'size_t' */
+  int rc = ssl_write(BACKEND->ssl, mem, (int)len);
+
+  infof(conn->data, "  axtls_send\n");
+
+  if(rc < 0) {
+    *err = map_error_to_curl(rc);
+    rc = -1; /* generic error code for send failure */
+  }
+
+  *err = CURLE_OK;
+  return rc;
+}
+
+/*
+ * This function is called to shut down the SSL layer but keep the
+ * socket open (CCC - Clear Command Channel)
+ */
+static int Curl_axtls_shutdown(struct connectdata *conn, int sockindex)
+{
+  /* Outline taken from openssl.c since functions are in axTLS compat layer.
+     axTLS's error set is much smaller, so a lot of error-handling was removed.
+   */
+  int retval = 0;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct Curl_easy *data = conn->data;
+  uint8_t *buf;
+  ssize_t nread;
+
+  infof(conn->data, "  Curl_axtls_shutdown\n");
+
+  /* This has only been tested on the proftpd server, and the mod_tls code
+     sends a close notify alert without waiting for a close notify alert in
+     response. Thus we wait for a close notify alert from the server, but
+     we do not send one. Let's hope other servers do the same... */
+
+  /* axTLS compat layer does nothing for SSL_shutdown, so we do nothing too
+  if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
+      (void)SSL_shutdown(BACKEND->ssl);
+  */
+
+  if(BACKEND->ssl) {
+    int what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
+    if(what > 0) {
+      /* Something to read, let's do it and hope that it is the close
+         notify alert from the server.  buf is managed internally by
+         axTLS and will be released upon calling ssl_free via
+         free_ssl_structs. */
+      nread = (ssize_t)ssl_read(BACKEND->ssl, &buf);
+
+      if(nread < SSL_OK) {
+        failf(data, "close notify alert not received during shutdown");
+        retval = -1;
+      }
+    }
+    else if(0 == what) {
+      /* timeout */
+      failf(data, "SSL shutdown timeout");
+    }
+    else {
+      /* anything that gets here is fatally bad */
+      failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+      retval = -1;
+    }
+
+    free_ssl_structs(connssl);
+  }
+  return retval;
+}
+
+static ssize_t axtls_recv(struct connectdata *conn, /* connection data */
+                          int num,                  /* socketindex */
+                          char *buf,                /* store read data here */
+                          size_t buffersize,        /* max amount to read */
+                          CURLcode *err)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[num];
+  ssize_t ret = 0;
+  uint8_t *read_buf;
+
+  infof(conn->data, "  axtls_recv\n");
+
+  *err = CURLE_OK;
+  if(connssl) {
+    ret = ssl_read(BACKEND->ssl, &read_buf);
+    if(ret > SSL_OK) {
+      /* ssl_read returns SSL_OK if there is more data to read, so if it is
+         larger, then all data has been read already.  */
+      memcpy(buf, read_buf,
+             (size_t)ret > buffersize ? buffersize : (size_t)ret);
+    }
+    else if(ret == SSL_OK) {
+      /* more data to be read, signal caller to call again */
+      *err = CURLE_AGAIN;
+      ret = -1;
+    }
+    else if(ret == -3) {
+      /* With patched axTLS, SSL_CLOSE_NOTIFY=-3.  Hard-coding until axTLS
+         team approves proposed fix. */
+      Curl_axtls_close(conn, num);
+    }
+    else {
+      failf(conn->data, "axTLS recv error (%d)", ret);
+      *err = map_error_to_curl((int) ret);
+      ret = -1;
+    }
+  }
+
+  return ret;
+}
+
+/*
+ * Return codes:
+ *     1 means the connection is still in place
+ *     0 means the connection has been closed
+ *    -1 means the connection status is unknown
+ */
+static int Curl_axtls_check_cxn(struct connectdata *conn)
+{
+  /* openssl.c line:
+     rc = SSL_peek(conn->ssl[FIRSTSOCKET].backend->ssl, (void*)&buf, 1);
+     axTLS compat layer always returns the last argument, so connection is
+     always alive? */
+
+  infof(conn->data, "  Curl_axtls_check_cxn\n");
+   return 1; /* connection still in place */
+}
+
+static void Curl_axtls_session_free(void *ptr)
+{
+  (void)ptr;
+  /* free the ID */
+  /* both openssl.c and gtls.c do something here, but axTLS's OpenSSL
+     compatibility layer does nothing, so we do nothing too. */
+}
+
+static size_t Curl_axtls_version(char *buffer, size_t size)
+{
+  return snprintf(buffer, size, "axTLS/%s", ssl_version());
+}
+
+static CURLcode Curl_axtls_random(struct Curl_easy *data,
+                                  unsigned char *entropy, size_t length)
+{
+  static bool ssl_seeded = FALSE;
+  (void)data;
+  if(!ssl_seeded) {
+    ssl_seeded = TRUE;
+    /* Initialize the seed if not already done. This call is not exactly thread
+     * safe (and neither is the ssl_seeded check), but the worst effect of a
+     * race condition is that some global resources will leak. */
+    RNG_initialize();
+  }
+  get_random((int)length, entropy);
+  return CURLE_OK;
+}
+
+static void *Curl_axtls_get_internals(struct ssl_connect_data *connssl,
+                                      CURLINFO info UNUSED_PARAM)
+{
+  (void)info;
+  return BACKEND->ssl;
+}
+
+const struct Curl_ssl Curl_ssl_axtls = {
+  { CURLSSLBACKEND_AXTLS, "axtls" }, /* info */
+
+  0, /* have_ca_path */
+  0, /* have_certinfo */
+  0, /* have_pinnedpubkey */
+  0, /* have_ssl_ctx */
+  0, /* support_https_proxy */
+
+  sizeof(struct ssl_backend_data),
+
+  /*
+   * axTLS has no global init.  Everything is done through SSL and SSL_CTX
+   * structs stored in connectdata structure.
+   */
+  Curl_none_init,                 /* init */
+  /* axTLS has no global cleanup. */
+  Curl_none_cleanup,              /* cleanup */
+  Curl_axtls_version,             /* version */
+  Curl_axtls_check_cxn,           /* check_cxn */
+  Curl_axtls_shutdown,            /* shutdown */
+  Curl_none_data_pending,         /* data_pending */
+  Curl_axtls_random,              /* random */
+  Curl_none_cert_status_request,  /* cert_status_request */
+  Curl_axtls_connect,             /* connect */
+  Curl_axtls_connect_nonblocking, /* connect_nonblocking */
+  Curl_axtls_get_internals,       /* get_internals */
+  Curl_axtls_close,               /* close_one */
+  Curl_none_close_all,            /* close_all */
+  Curl_axtls_session_free,        /* session_free */
+  Curl_none_set_engine,           /* set_engine */
+  Curl_none_set_engine_default,   /* set_engine_default */
+  Curl_none_engines_list,         /* engines_list */
+  Curl_none_false_start,          /* false_start */
+  Curl_none_md5sum,               /* md5sum */
+  NULL                            /* sha256sum */
+};
+
+#endif /* USE_AXTLS */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/axtls.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/axtls.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/axtls.h	(revision 331)
@@ -0,0 +1,34 @@
+#ifndef HEADER_CURL_AXTLS_H
+#define HEADER_CURL_AXTLS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010, DirecTV, Contact: Eric Hu <ehu@directv.com>
+ * Copyright (C) 2010 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifdef USE_AXTLS
+#include "curl/curl.h"
+#include "urldata.h"
+
+extern const struct Curl_ssl Curl_ssl_axtls;
+
+#endif /* USE_AXTLS */
+#endif /* HEADER_CURL_AXTLS_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/cyassl.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/cyassl.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/cyassl.c	(revision 331)
@@ -0,0 +1,1017 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all CyaSSL-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ *
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_CYASSL
+
+#define WOLFSSL_OPTIONS_IGNORE_SYS
+/* CyaSSL's version.h, which should contain only the version, should come
+before all other CyaSSL includes and be immediately followed by build config
+aka options.h. https://curl.haxx.se/mail/lib-2015-04/0069.html */
+#include <cyassl/version.h>
+#if defined(HAVE_CYASSL_OPTIONS_H) && (LIBCYASSL_VERSION_HEX > 0x03004008)
+#if defined(CYASSL_API) || defined(WOLFSSL_API)
+/* Safety measure. If either is defined some API include was already included
+and that's a problem since options.h hasn't been included yet. */
+#error "CyaSSL API was included before the CyaSSL build options."
+#endif
+#include <cyassl/options.h>
+#endif
+
+/* To determine what functions are available we rely on one or both of:
+   - the user's options.h generated by CyaSSL/wolfSSL
+   - the symbols detected by curl's configure
+   Since they are markedly different from one another, and one or the other may
+   not be available, we do some checking below to bring things in sync. */
+
+/* HAVE_ALPN is wolfSSL's build time symbol for enabling ALPN in options.h. */
+#ifndef HAVE_ALPN
+#ifdef HAVE_WOLFSSL_USEALPN
+#define HAVE_ALPN
+#endif
+#endif
+
+/* WOLFSSL_ALLOW_SSLV3 is wolfSSL's build time symbol for enabling SSLv3 in
+   options.h, but is only seen in >= 3.6.6 since that's when they started
+   disabling SSLv3 by default. */
+#ifndef WOLFSSL_ALLOW_SSLV3
+#if (LIBCYASSL_VERSION_HEX < 0x03006006) || \
+    defined(HAVE_WOLFSSLV3_CLIENT_METHOD)
+#define WOLFSSL_ALLOW_SSLV3
+#endif
+#endif
+
+/* HAVE_SUPPORTED_CURVES is wolfSSL's build time symbol for enabling the ECC
+   supported curve extension in options.h. Note ECC is enabled separately. */
+#ifndef HAVE_SUPPORTED_CURVES
+#if defined(HAVE_CYASSL_CTX_USESUPPORTEDCURVE) || \
+    defined(HAVE_WOLFSSL_CTX_USESUPPORTEDCURVE)
+#define HAVE_SUPPORTED_CURVES
+#endif
+#endif
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "vtls.h"
+#include "parsedate.h"
+#include "connect.h" /* for the connect timeout */
+#include "select.h"
+#include "strcase.h"
+#include "x509asn1.h"
+#include "curl_printf.h"
+
+#include <cyassl/openssl/ssl.h>
+#include <cyassl/ssl.h>
+#ifdef HAVE_CYASSL_ERROR_SSL_H
+#include <cyassl/error-ssl.h>
+#else
+#include <cyassl/error.h>
+#endif
+#include <cyassl/ctaocrypt/random.h>
+#include <cyassl/ctaocrypt/sha256.h>
+
+#include "cyassl.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#if LIBCYASSL_VERSION_HEX < 0x02007002 /* < 2.7.2 */
+#define CYASSL_MAX_ERROR_SZ 80
+#endif
+
+/* KEEP_PEER_CERT is a product of the presence of build time symbol
+   OPENSSL_EXTRA without NO_CERTS, depending on the version. KEEP_PEER_CERT is
+   in wolfSSL's settings.h, and the latter two are build time symbols in
+   options.h. */
+#ifndef KEEP_PEER_CERT
+#if defined(HAVE_CYASSL_GET_PEER_CERTIFICATE) || \
+    defined(HAVE_WOLFSSL_GET_PEER_CERTIFICATE) || \
+    (defined(OPENSSL_EXTRA) && !defined(NO_CERTS))
+#define KEEP_PEER_CERT
+#endif
+#endif
+
+struct ssl_backend_data {
+  SSL_CTX* ctx;
+  SSL*     handle;
+};
+
+#define BACKEND connssl->backend
+
+static Curl_recv cyassl_recv;
+static Curl_send cyassl_send;
+
+
+static int do_file_type(const char *type)
+{
+  if(!type || !type[0])
+    return SSL_FILETYPE_PEM;
+  if(strcasecompare(type, "PEM"))
+    return SSL_FILETYPE_PEM;
+  if(strcasecompare(type, "DER"))
+    return SSL_FILETYPE_ASN1;
+  return -1;
+}
+
+/*
+ * This function loads all the client/CA certificates and CRLs. Setup the TLS
+ * layer and do all necessary magic.
+ */
+static CURLcode
+cyassl_connect_step1(struct connectdata *conn,
+                     int sockindex)
+{
+  char error_buffer[CYASSL_MAX_ERROR_SZ];
+  char *ciphers;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+  SSL_METHOD* req_method = NULL;
+  curl_socket_t sockfd = conn->sock[sockindex];
+#ifdef HAVE_SNI
+  bool sni = FALSE;
+#define use_sni(x)  sni = (x)
+#else
+#define use_sni(x)  Curl_nop_stmt
+#endif
+
+  if(connssl->state == ssl_connection_complete)
+    return CURLE_OK;
+
+  if(SSL_CONN_CONFIG(version_max) != CURL_SSLVERSION_MAX_NONE) {
+    failf(data, "CyaSSL does not support to set maximum SSL/TLS version");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  /* check to see if we've been told to use an explicit SSL/TLS version */
+  switch(SSL_CONN_CONFIG(version)) {
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+#if LIBCYASSL_VERSION_HEX >= 0x03003000 /* >= 3.3.0 */
+    /* minimum protocol version is set later after the CTX object is created */
+    req_method = SSLv23_client_method();
+#else
+    infof(data, "CyaSSL <3.3.0 cannot be configured to use TLS 1.0-1.2, "
+          "TLS 1.0 is used exclusively\n");
+    req_method = TLSv1_client_method();
+#endif
+    use_sni(TRUE);
+    break;
+  case CURL_SSLVERSION_TLSv1_0:
+    req_method = TLSv1_client_method();
+    use_sni(TRUE);
+    break;
+  case CURL_SSLVERSION_TLSv1_1:
+    req_method = TLSv1_1_client_method();
+    use_sni(TRUE);
+    break;
+  case CURL_SSLVERSION_TLSv1_2:
+    req_method = TLSv1_2_client_method();
+    use_sni(TRUE);
+    break;
+  case CURL_SSLVERSION_TLSv1_3:
+    failf(data, "CyaSSL: TLS 1.3 is not yet supported");
+    return CURLE_SSL_CONNECT_ERROR;
+  case CURL_SSLVERSION_SSLv3:
+#ifdef WOLFSSL_ALLOW_SSLV3
+    req_method = SSLv3_client_method();
+    use_sni(FALSE);
+#else
+    failf(data, "CyaSSL does not support SSLv3");
+    return CURLE_NOT_BUILT_IN;
+#endif
+    break;
+  case CURL_SSLVERSION_SSLv2:
+    failf(data, "CyaSSL does not support SSLv2");
+    return CURLE_SSL_CONNECT_ERROR;
+  default:
+    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  if(!req_method) {
+    failf(data, "SSL: couldn't create a method!");
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  if(BACKEND->ctx)
+    SSL_CTX_free(BACKEND->ctx);
+  BACKEND->ctx = SSL_CTX_new(req_method);
+
+  if(!BACKEND->ctx) {
+    failf(data, "SSL: couldn't create a context!");
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  switch(SSL_CONN_CONFIG(version)) {
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+#if LIBCYASSL_VERSION_HEX > 0x03004006 /* > 3.4.6 */
+    /* Versions 3.3.0 to 3.4.6 we know the minimum protocol version is whatever
+    minimum version of TLS was built in and at least TLS 1.0. For later library
+    versions that could change (eg TLS 1.0 built in but defaults to TLS 1.1) so
+    we have this short circuit evaluation to find the minimum supported TLS
+    version. We use wolfSSL_CTX_SetMinVersion and not CyaSSL_SetMinVersion
+    because only the former will work before the user's CTX callback is called.
+    */
+    if((wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1) != 1) &&
+       (wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1_1) != 1) &&
+       (wolfSSL_CTX_SetMinVersion(BACKEND->ctx, WOLFSSL_TLSV1_2) != 1)) {
+      failf(data, "SSL: couldn't set the minimum protocol version");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+#endif
+    break;
+  }
+
+  ciphers = SSL_CONN_CONFIG(cipher_list);
+  if(ciphers) {
+    if(!SSL_CTX_set_cipher_list(BACKEND->ctx, ciphers)) {
+      failf(data, "failed setting cipher list: %s", ciphers);
+      return CURLE_SSL_CIPHER;
+    }
+    infof(data, "Cipher selection: %s\n", ciphers);
+  }
+
+#ifndef NO_FILESYSTEM
+  /* load trusted cacert */
+  if(SSL_CONN_CONFIG(CAfile)) {
+    if(1 != SSL_CTX_load_verify_locations(BACKEND->ctx,
+                                      SSL_CONN_CONFIG(CAfile),
+                                      SSL_CONN_CONFIG(CApath))) {
+      if(SSL_CONN_CONFIG(verifypeer)) {
+        /* Fail if we insist on successfully verifying the server. */
+        failf(data, "error setting certificate verify locations:\n"
+              "  CAfile: %s\n  CApath: %s",
+              SSL_CONN_CONFIG(CAfile)?
+              SSL_CONN_CONFIG(CAfile): "none",
+              SSL_CONN_CONFIG(CApath)?
+              SSL_CONN_CONFIG(CApath) : "none");
+        return CURLE_SSL_CACERT_BADFILE;
+      }
+      else {
+        /* Just continue with a warning if no strict certificate
+           verification is required. */
+        infof(data, "error setting certificate verify locations,"
+              " continuing anyway:\n");
+      }
+    }
+    else {
+      /* Everything is fine. */
+      infof(data, "successfully set certificate verify locations:\n");
+    }
+    infof(data,
+          "  CAfile: %s\n"
+          "  CApath: %s\n",
+          SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile):
+          "none",
+          SSL_CONN_CONFIG(CApath) ? SSL_CONN_CONFIG(CApath):
+          "none");
+  }
+
+  /* Load the client certificate, and private key */
+  if(SSL_SET_OPTION(cert) && SSL_SET_OPTION(key)) {
+    int file_type = do_file_type(SSL_SET_OPTION(cert_type));
+
+    if(SSL_CTX_use_certificate_file(BACKEND->ctx, SSL_SET_OPTION(cert),
+                                     file_type) != 1) {
+      failf(data, "unable to use client certificate (no key or wrong pass"
+            " phrase?)");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+
+    file_type = do_file_type(SSL_SET_OPTION(key_type));
+    if(SSL_CTX_use_PrivateKey_file(BACKEND->ctx, SSL_SET_OPTION(key),
+                                    file_type) != 1) {
+      failf(data, "unable to set private key");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+#endif /* !NO_FILESYSTEM */
+
+  /* SSL always tries to verify the peer, this only says whether it should
+   * fail to connect if the verification fails, or if it should continue
+   * anyway. In the latter case the result of the verification is checked with
+   * SSL_get_verify_result() below. */
+  SSL_CTX_set_verify(BACKEND->ctx,
+                     SSL_CONN_CONFIG(verifypeer)?SSL_VERIFY_PEER:
+                                                 SSL_VERIFY_NONE,
+                     NULL);
+
+#ifdef HAVE_SNI
+  if(sni) {
+    struct in_addr addr4;
+#ifdef ENABLE_IPV6
+    struct in6_addr addr6;
+#endif
+    const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+      conn->host.name;
+    size_t hostname_len = strlen(hostname);
+    if((hostname_len < USHRT_MAX) &&
+       (0 == Curl_inet_pton(AF_INET, hostname, &addr4)) &&
+#ifdef ENABLE_IPV6
+       (0 == Curl_inet_pton(AF_INET6, hostname, &addr6)) &&
+#endif
+       (CyaSSL_CTX_UseSNI(BACKEND->ctx, CYASSL_SNI_HOST_NAME, hostname,
+                          (unsigned short)hostname_len) != 1)) {
+      infof(data, "WARNING: failed to configure server name indication (SNI) "
+            "TLS extension\n");
+    }
+  }
+#endif
+
+#ifdef HAVE_SUPPORTED_CURVES
+  /* CyaSSL/wolfSSL does not send the supported ECC curves ext automatically:
+     https://github.com/wolfSSL/wolfssl/issues/366
+     The supported curves below are those also supported by OpenSSL 1.0.2 and
+     in the same order. */
+  CyaSSL_CTX_UseSupportedCurve(BACKEND->ctx, 0x17); /* secp256r1 */
+  CyaSSL_CTX_UseSupportedCurve(BACKEND->ctx, 0x19); /* secp521r1 */
+  CyaSSL_CTX_UseSupportedCurve(BACKEND->ctx, 0x18); /* secp384r1 */
+#endif
+
+  /* give application a chance to interfere with SSL set up. */
+  if(data->set.ssl.fsslctx) {
+    CURLcode result = CURLE_OK;
+    result = (*data->set.ssl.fsslctx)(data, BACKEND->ctx,
+                                      data->set.ssl.fsslctxp);
+    if(result) {
+      failf(data, "error signaled by ssl ctx callback");
+      return result;
+    }
+  }
+#ifdef NO_FILESYSTEM
+  else if(SSL_CONN_CONFIG(verifypeer)) {
+    failf(data, "SSL: Certificates couldn't be loaded because CyaSSL was built"
+          " with \"no filesystem\". Either disable peer verification"
+          " (insecure) or if you are building an application with libcurl you"
+          " can load certificates via CURLOPT_SSL_CTX_FUNCTION.");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+#endif
+
+  /* Let's make an SSL structure */
+  if(BACKEND->handle)
+    SSL_free(BACKEND->handle);
+  BACKEND->handle = SSL_new(BACKEND->ctx);
+  if(!BACKEND->handle) {
+    failf(data, "SSL: couldn't create a context (handle)!");
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+#ifdef HAVE_ALPN
+  if(conn->bits.tls_enable_alpn) {
+    char protocols[128];
+    *protocols = '\0';
+
+    /* wolfSSL's ALPN protocol name list format is a comma separated string of
+       protocols in descending order of preference, eg: "h2,http/1.1" */
+
+#ifdef USE_NGHTTP2
+    if(data->set.httpversion >= CURL_HTTP_VERSION_2) {
+      strcpy(protocols + strlen(protocols), NGHTTP2_PROTO_VERSION_ID ",");
+      infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+    }
+#endif
+
+    strcpy(protocols + strlen(protocols), ALPN_HTTP_1_1);
+    infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
+
+    if(wolfSSL_UseALPN(BACKEND->handle, protocols,
+                       (unsigned)strlen(protocols),
+                       WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) != SSL_SUCCESS) {
+      failf(data, "SSL: failed setting ALPN protocols");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+#endif /* HAVE_ALPN */
+
+  /* Check if there's a cached ID we can/should use here! */
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    void *ssl_sessionid = NULL;
+
+    Curl_ssl_sessionid_lock(conn);
+    if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
+      /* we got a session id, use it! */
+      if(!SSL_set_session(BACKEND->handle, ssl_sessionid)) {
+        Curl_ssl_sessionid_unlock(conn);
+        failf(data, "SSL: SSL_set_session failed: %s",
+              ERR_error_string(SSL_get_error(BACKEND->handle, 0),
+              error_buffer));
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      /* Informational message */
+      infof(data, "SSL re-using session ID\n");
+    }
+    Curl_ssl_sessionid_unlock(conn);
+  }
+
+  /* pass the raw socket into the SSL layer */
+  if(!SSL_set_fd(BACKEND->handle, (int)sockfd)) {
+    failf(data, "SSL: SSL_set_fd failed");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  connssl->connecting_state = ssl_connect_2;
+  return CURLE_OK;
+}
+
+
+static CURLcode
+cyassl_connect_step2(struct connectdata *conn,
+                     int sockindex)
+{
+  int ret = -1;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+  const char * const dispname = SSL_IS_PROXY() ?
+    conn->http_proxy.host.dispname : conn->host.dispname;
+  const char * const pinnedpubkey = SSL_IS_PROXY() ?
+                        data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
+                        data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+
+  conn->recv[sockindex] = cyassl_recv;
+  conn->send[sockindex] = cyassl_send;
+
+  /* Enable RFC2818 checks */
+  if(SSL_CONN_CONFIG(verifyhost)) {
+    ret = CyaSSL_check_domain_name(BACKEND->handle, hostname);
+    if(ret == SSL_FAILURE)
+      return CURLE_OUT_OF_MEMORY;
+  }
+
+  ret = SSL_connect(BACKEND->handle);
+  if(ret != 1) {
+    char error_buffer[CYASSL_MAX_ERROR_SZ];
+    int  detail = SSL_get_error(BACKEND->handle, ret);
+
+    if(SSL_ERROR_WANT_READ == detail) {
+      connssl->connecting_state = ssl_connect_2_reading;
+      return CURLE_OK;
+    }
+    else if(SSL_ERROR_WANT_WRITE == detail) {
+      connssl->connecting_state = ssl_connect_2_writing;
+      return CURLE_OK;
+    }
+    /* There is no easy way to override only the CN matching.
+     * This will enable the override of both mismatching SubjectAltNames
+     * as also mismatching CN fields */
+    else if(DOMAIN_NAME_MISMATCH == detail) {
+#if 1
+      failf(data, "\tsubject alt name(s) or common name do not match \"%s\"\n",
+            dispname);
+      return CURLE_PEER_FAILED_VERIFICATION;
+#else
+      /* When the CyaSSL_check_domain_name() is used and you desire to continue
+       * on a DOMAIN_NAME_MISMATCH, i.e. 'conn->ssl_config.verifyhost == 0',
+       * CyaSSL version 2.4.0 will fail with an INCOMPLETE_DATA error. The only
+       * way to do this is currently to switch the CyaSSL_check_domain_name()
+       * in and out based on the 'conn->ssl_config.verifyhost' value. */
+      if(SSL_CONN_CONFIG(verifyhost)) {
+        failf(data,
+              "\tsubject alt name(s) or common name do not match \"%s\"\n",
+              dispname);
+        return CURLE_PEER_FAILED_VERIFICATION;
+      }
+      else {
+        infof(data,
+              "\tsubject alt name(s) and/or common name do not match \"%s\"\n",
+              dispname);
+        return CURLE_OK;
+      }
+#endif
+    }
+#if LIBCYASSL_VERSION_HEX >= 0x02007000 /* 2.7.0 */
+    else if(ASN_NO_SIGNER_E == detail) {
+      if(SSL_CONN_CONFIG(verifypeer)) {
+        failf(data, "\tCA signer not available for verification\n");
+        return CURLE_SSL_CACERT_BADFILE;
+      }
+      else {
+        /* Just continue with a warning if no strict certificate
+           verification is required. */
+        infof(data, "CA signer not available for verification, "
+                    "continuing anyway\n");
+      }
+    }
+#endif
+    else {
+      failf(data, "SSL_connect failed with error %d: %s", detail,
+          ERR_error_string(detail, error_buffer));
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+
+  if(pinnedpubkey) {
+#ifdef KEEP_PEER_CERT
+    X509 *x509;
+    const char *x509_der;
+    int x509_der_len;
+    curl_X509certificate x509_parsed;
+    curl_asn1Element *pubkey;
+    CURLcode result;
+
+    x509 = SSL_get_peer_certificate(BACKEND->handle);
+    if(!x509) {
+      failf(data, "SSL: failed retrieving server certificate");
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    x509_der = (const char *)CyaSSL_X509_get_der(x509, &x509_der_len);
+    if(!x509_der) {
+      failf(data, "SSL: failed retrieving ASN.1 server certificate");
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    memset(&x509_parsed, 0, sizeof x509_parsed);
+    if(Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len))
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+
+    pubkey = &x509_parsed.subjectPublicKeyInfo;
+    if(!pubkey->header || pubkey->end <= pubkey->header) {
+      failf(data, "SSL: failed retrieving public key from server certificate");
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    result = Curl_pin_peer_pubkey(data,
+                                  pinnedpubkey,
+                                  (const unsigned char *)pubkey->header,
+                                  (size_t)(pubkey->end - pubkey->header));
+    if(result) {
+      failf(data, "SSL: public key does not match pinned public key!");
+      return result;
+    }
+#else
+    failf(data, "Library lacks pinning support built-in");
+    return CURLE_NOT_BUILT_IN;
+#endif
+  }
+
+#ifdef HAVE_ALPN
+  if(conn->bits.tls_enable_alpn) {
+    int rc;
+    char *protocol = NULL;
+    unsigned short protocol_len = 0;
+
+    rc = wolfSSL_ALPN_GetProtocol(BACKEND->handle, &protocol, &protocol_len);
+
+    if(rc == SSL_SUCCESS) {
+      infof(data, "ALPN, server accepted to use %.*s\n", protocol_len,
+            protocol);
+
+      if(protocol_len == ALPN_HTTP_1_1_LENGTH &&
+         !memcmp(protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH))
+        conn->negnpn = CURL_HTTP_VERSION_1_1;
+#ifdef USE_NGHTTP2
+      else if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
+              protocol_len == NGHTTP2_PROTO_VERSION_ID_LEN &&
+              !memcmp(protocol, NGHTTP2_PROTO_VERSION_ID,
+                      NGHTTP2_PROTO_VERSION_ID_LEN))
+        conn->negnpn = CURL_HTTP_VERSION_2;
+#endif
+      else
+        infof(data, "ALPN, unrecognized protocol %.*s\n", protocol_len,
+              protocol);
+    }
+    else if(rc == SSL_ALPN_NOT_FOUND)
+      infof(data, "ALPN, server did not agree to a protocol\n");
+    else {
+      failf(data, "ALPN, failure getting protocol, error %d", rc);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+#endif /* HAVE_ALPN */
+
+  connssl->connecting_state = ssl_connect_3;
+#if (LIBCYASSL_VERSION_HEX >= 0x03009010)
+  infof(data, "SSL connection using %s / %s\n",
+        wolfSSL_get_version(BACKEND->handle),
+        wolfSSL_get_cipher_name(BACKEND->handle));
+#else
+  infof(data, "SSL connected\n");
+#endif
+
+  return CURLE_OK;
+}
+
+
+static CURLcode
+cyassl_connect_step3(struct connectdata *conn,
+                     int sockindex)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    bool incache;
+    SSL_SESSION *our_ssl_sessionid;
+    void *old_ssl_sessionid = NULL;
+
+    our_ssl_sessionid = SSL_get_session(BACKEND->handle);
+
+    Curl_ssl_sessionid_lock(conn);
+    incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL,
+                                      sockindex));
+    if(incache) {
+      if(old_ssl_sessionid != our_ssl_sessionid) {
+        infof(data, "old SSL session ID is stale, removing\n");
+        Curl_ssl_delsessionid(conn, old_ssl_sessionid);
+        incache = FALSE;
+      }
+    }
+
+    if(!incache) {
+      result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
+                                     0 /* unknown size */, sockindex);
+      if(result) {
+        Curl_ssl_sessionid_unlock(conn);
+        failf(data, "failed to store ssl session");
+        return result;
+      }
+    }
+    Curl_ssl_sessionid_unlock(conn);
+  }
+
+  connssl->connecting_state = ssl_connect_done;
+
+  return result;
+}
+
+
+static ssize_t cyassl_send(struct connectdata *conn,
+                           int sockindex,
+                           const void *mem,
+                           size_t len,
+                           CURLcode *curlcode)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  char error_buffer[CYASSL_MAX_ERROR_SZ];
+  int  memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
+  int  rc     = SSL_write(BACKEND->handle, mem, memlen);
+
+  if(rc < 0) {
+    int err = SSL_get_error(BACKEND->handle, rc);
+
+    switch(err) {
+    case SSL_ERROR_WANT_READ:
+    case SSL_ERROR_WANT_WRITE:
+      /* there's data pending, re-invoke SSL_write() */
+      *curlcode = CURLE_AGAIN;
+      return -1;
+    default:
+      failf(conn->data, "SSL write: %s, errno %d",
+            ERR_error_string(err, error_buffer),
+            SOCKERRNO);
+      *curlcode = CURLE_SEND_ERROR;
+      return -1;
+    }
+  }
+  return rc;
+}
+
+static void Curl_cyassl_close(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  if(BACKEND->handle) {
+    (void)SSL_shutdown(BACKEND->handle);
+    SSL_free(BACKEND->handle);
+    BACKEND->handle = NULL;
+  }
+  if(BACKEND->ctx) {
+    SSL_CTX_free(BACKEND->ctx);
+    BACKEND->ctx = NULL;
+  }
+}
+
+static ssize_t cyassl_recv(struct connectdata *conn,
+                           int num,
+                           char *buf,
+                           size_t buffersize,
+                           CURLcode *curlcode)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[num];
+  char error_buffer[CYASSL_MAX_ERROR_SZ];
+  int  buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
+  int  nread    = SSL_read(BACKEND->handle, buf, buffsize);
+
+  if(nread < 0) {
+    int err = SSL_get_error(BACKEND->handle, nread);
+
+    switch(err) {
+    case SSL_ERROR_ZERO_RETURN: /* no more data */
+      break;
+    case SSL_ERROR_WANT_READ:
+    case SSL_ERROR_WANT_WRITE:
+      /* there's data pending, re-invoke SSL_read() */
+      *curlcode = CURLE_AGAIN;
+      return -1;
+    default:
+      failf(conn->data, "SSL read: %s, errno %d",
+            ERR_error_string(err, error_buffer),
+            SOCKERRNO);
+      *curlcode = CURLE_RECV_ERROR;
+      return -1;
+    }
+  }
+  return nread;
+}
+
+
+static void Curl_cyassl_session_free(void *ptr)
+{
+  (void)ptr;
+  /* CyaSSL reuses sessions on own, no free */
+}
+
+
+static size_t Curl_cyassl_version(char *buffer, size_t size)
+{
+#if LIBCYASSL_VERSION_HEX >= 0x03006000
+  return snprintf(buffer, size, "wolfSSL/%s", wolfSSL_lib_version());
+#elif defined(WOLFSSL_VERSION)
+  return snprintf(buffer, size, "wolfSSL/%s", WOLFSSL_VERSION);
+#elif defined(CYASSL_VERSION)
+  return snprintf(buffer, size, "CyaSSL/%s", CYASSL_VERSION);
+#else
+  return snprintf(buffer, size, "CyaSSL/%s", "<1.8.8");
+#endif
+}
+
+
+static int Curl_cyassl_init(void)
+{
+  return (CyaSSL_Init() == SSL_SUCCESS);
+}
+
+
+static bool Curl_cyassl_data_pending(const struct connectdata* conn,
+                                     int connindex)
+{
+  const struct ssl_connect_data *connssl = &conn->ssl[connindex];
+  if(BACKEND->handle)   /* SSL is in use */
+    return (0 != SSL_pending(BACKEND->handle)) ? TRUE : FALSE;
+  else
+    return FALSE;
+}
+
+
+/*
+ * This function is called to shut down the SSL layer but keep the
+ * socket open (CCC - Clear Command Channel)
+ */
+static int Curl_cyassl_shutdown(struct connectdata *conn, int sockindex)
+{
+  int retval = 0;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  if(BACKEND->handle) {
+    SSL_free(BACKEND->handle);
+    BACKEND->handle = NULL;
+  }
+  return retval;
+}
+
+
+static CURLcode
+cyassl_connect_common(struct connectdata *conn,
+                      int sockindex,
+                      bool nonblocking,
+                      bool *done)
+{
+  CURLcode result;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  curl_socket_t sockfd = conn->sock[sockindex];
+  time_t timeout_ms;
+  int what;
+
+  /* check if the connection has already been established */
+  if(ssl_connection_complete == connssl->state) {
+    *done = TRUE;
+    return CURLE_OK;
+  }
+
+  if(ssl_connect_1 == connssl->connecting_state) {
+    /* Find out how much more time we're allowed */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    result = cyassl_connect_step1(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  while(ssl_connect_2 == connssl->connecting_state ||
+        ssl_connect_2_reading == connssl->connecting_state ||
+        ssl_connect_2_writing == connssl->connecting_state) {
+
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    /* if ssl is expecting something, check if it's available. */
+    if(connssl->connecting_state == ssl_connect_2_reading
+       || connssl->connecting_state == ssl_connect_2_writing) {
+
+      curl_socket_t writefd = ssl_connect_2_writing ==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+      curl_socket_t readfd = ssl_connect_2_reading ==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+      what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
+                               nonblocking?0:timeout_ms);
+      if(what < 0) {
+        /* fatal error */
+        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      else if(0 == what) {
+        if(nonblocking) {
+          *done = FALSE;
+          return CURLE_OK;
+        }
+        else {
+          /* timeout */
+          failf(data, "SSL connection timeout");
+          return CURLE_OPERATION_TIMEDOUT;
+        }
+      }
+      /* socket is readable or writable */
+    }
+
+    /* Run transaction, and return to the caller if it failed or if
+     * this connection is part of a multi handle and this loop would
+     * execute again. This permits the owner of a multi handle to
+     * abort a connection attempt before step2 has completed while
+     * ensuring that a client using select() or epoll() will always
+     * have a valid fdset to wait on.
+     */
+    result = cyassl_connect_step2(conn, sockindex);
+    if(result || (nonblocking &&
+                  (ssl_connect_2 == connssl->connecting_state ||
+                   ssl_connect_2_reading == connssl->connecting_state ||
+                   ssl_connect_2_writing == connssl->connecting_state)))
+      return result;
+  } /* repeat step2 until all transactions are done. */
+
+  if(ssl_connect_3 == connssl->connecting_state) {
+    result = cyassl_connect_step3(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  if(ssl_connect_done == connssl->connecting_state) {
+    connssl->state = ssl_connection_complete;
+    conn->recv[sockindex] = cyassl_recv;
+    conn->send[sockindex] = cyassl_send;
+    *done = TRUE;
+  }
+  else
+    *done = FALSE;
+
+  /* Reset our connect state machine */
+  connssl->connecting_state = ssl_connect_1;
+
+  return CURLE_OK;
+}
+
+
+static CURLcode Curl_cyassl_connect_nonblocking(struct connectdata *conn,
+                                                int sockindex, bool *done)
+{
+  return cyassl_connect_common(conn, sockindex, TRUE, done);
+}
+
+
+static CURLcode Curl_cyassl_connect(struct connectdata *conn, int sockindex)
+{
+  CURLcode result;
+  bool done = FALSE;
+
+  result = cyassl_connect_common(conn, sockindex, FALSE, &done);
+  if(result)
+    return result;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+static CURLcode Curl_cyassl_random(struct Curl_easy *data,
+                                   unsigned char *entropy, size_t length)
+{
+  RNG rng;
+  (void)data;
+  if(InitRng(&rng))
+    return CURLE_FAILED_INIT;
+  if(length > UINT_MAX)
+    return CURLE_FAILED_INIT;
+  if(RNG_GenerateBlock(&rng, entropy, (unsigned)length))
+    return CURLE_FAILED_INIT;
+  return CURLE_OK;
+}
+
+static void Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */
+                                  size_t tmplen,
+                                  unsigned char *sha256sum /* output */,
+                                  size_t unused)
+{
+  Sha256 SHA256pw;
+  (void)unused;
+  InitSha256(&SHA256pw);
+  Sha256Update(&SHA256pw, tmp, (word32)tmplen);
+  Sha256Final(&SHA256pw, sha256sum);
+}
+
+static void *Curl_cyassl_get_internals(struct ssl_connect_data *connssl,
+                                       CURLINFO info UNUSED_PARAM)
+{
+  (void)info;
+  return BACKEND->handle;
+}
+
+const struct Curl_ssl Curl_ssl_cyassl = {
+  { CURLSSLBACKEND_WOLFSSL, "WolfSSL" }, /* info */
+
+  0, /* have_ca_path */
+  0, /* have_certinfo */
+#ifdef KEEP_PEER_CERT
+  1, /* have_pinnedpubkey */
+#else
+  0, /* have_pinnedpubkey */
+#endif
+  1, /* have_ssl_ctx */
+  0, /* support_https_proxy */
+
+  sizeof(struct ssl_backend_data),
+
+  Curl_cyassl_init,                /* init */
+  Curl_none_cleanup,               /* cleanup */
+  Curl_cyassl_version,             /* version */
+  Curl_none_check_cxn,             /* check_cxn */
+  Curl_cyassl_shutdown,            /* shutdown */
+  Curl_cyassl_data_pending,        /* data_pending */
+  Curl_cyassl_random,              /* random */
+  Curl_none_cert_status_request,   /* cert_status_request */
+  Curl_cyassl_connect,             /* connect */
+  Curl_cyassl_connect_nonblocking, /* connect_nonblocking */
+  Curl_cyassl_get_internals,       /* get_internals */
+  Curl_cyassl_close,               /* close_one */
+  Curl_none_close_all,             /* close_all */
+  Curl_cyassl_session_free,        /* session_free */
+  Curl_none_set_engine,            /* set_engine */
+  Curl_none_set_engine_default,    /* set_engine_default */
+  Curl_none_engines_list,          /* engines_list */
+  Curl_none_false_start,           /* false_start */
+  Curl_none_md5sum,                /* md5sum */
+  Curl_cyassl_sha256sum            /* sha256sum */
+};
+
+#endif
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/cyassl.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/cyassl.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/cyassl.h	(revision 331)
@@ -0,0 +1,31 @@
+#ifndef HEADER_CURL_CYASSL_H
+#define HEADER_CURL_CYASSL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_CYASSL
+
+extern const struct Curl_ssl Curl_ssl_cyassl;
+
+#endif /* USE_CYASSL */
+#endif /* HEADER_CURL_CYASSL_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/darwinssl.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/darwinssl.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/darwinssl.c	(revision 331)
@@ -0,0 +1,3020 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2017, Nick Zitzmann, <nickzman@gmail.com>.
+ * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all iOS and macOS SecureTransport-specific code for the
+ * TLS/SSL layer. No code but vtls.c should ever call or use these functions.
+ */
+
+#include "curl_setup.h"
+
+#include "urldata.h" /* for the Curl_easy definition */
+#include "curl_base64.h"
+#include "strtok.h"
+
+#ifdef USE_DARWINSSL
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wtautological-pointer-compare"
+#endif /* __clang__ */
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include <Security/Security.h>
+/* For some reason, when building for iOS, the omnibus header above does
+ * not include SecureTransport.h as of iOS SDK 5.1. */
+#include <Security/SecureTransport.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CommonCrypto/CommonDigest.h>
+
+/* The Security framework has changed greatly between iOS and different macOS
+   versions, and we will try to support as many of them as we can (back to
+   Leopard and iOS 5) by using macros and weak-linking.
+
+   In general, you want to build this using the most recent OS SDK, since some
+   features require curl to be built against the latest SDK. TLS 1.1 and 1.2
+   support, for instance, require the macOS 10.8 SDK or later. TLS 1.3
+   requires the macOS 10.13 or iOS 11 SDK or later. */
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
+#error "The darwinssl back-end requires Leopard or later."
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */
+
+#define CURL_BUILD_IOS 0
+#define CURL_BUILD_IOS_7 0
+#define CURL_BUILD_IOS_11 0
+#define CURL_BUILD_MAC 1
+/* This is the maximum API level we are allowed to use when building: */
+#define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
+#define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
+#define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+#define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
+#define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
+#define CURL_BUILD_MAC_10_13 MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
+/* These macros mean "the following code is present to allow runtime backward
+   compatibility with at least this cat or earlier":
+   (You set this at build-time using the compiler command line option
+   "-mmacos-version-min.") */
+#define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
+#define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
+#define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
+#define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
+#define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
+
+#elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
+#define CURL_BUILD_IOS 1
+#define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
+#define CURL_BUILD_IOS_11 __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
+#define CURL_BUILD_MAC 0
+#define CURL_BUILD_MAC_10_5 0
+#define CURL_BUILD_MAC_10_6 0
+#define CURL_BUILD_MAC_10_7 0
+#define CURL_BUILD_MAC_10_8 0
+#define CURL_BUILD_MAC_10_9 0
+#define CURL_BUILD_MAC_10_13 0
+#define CURL_SUPPORT_MAC_10_5 0
+#define CURL_SUPPORT_MAC_10_6 0
+#define CURL_SUPPORT_MAC_10_7 0
+#define CURL_SUPPORT_MAC_10_8 0
+#define CURL_SUPPORT_MAC_10_9 0
+
+#else
+#error "The darwinssl back-end requires iOS or OS X."
+#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
+
+#if CURL_BUILD_MAC
+#include <sys/sysctl.h>
+#endif /* CURL_BUILD_MAC */
+
+#include "urldata.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "connect.h"
+#include "select.h"
+#include "vtls.h"
+#include "darwinssl.h"
+#include "curl_printf.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* From MacTypes.h (which we can't include because it isn't present in iOS: */
+#define ioErr -36
+#define paramErr -50
+
+struct ssl_backend_data {
+  SSLContextRef ssl_ctx;
+  curl_socket_t ssl_sockfd;
+  bool ssl_direction; /* true if writing, false if reading */
+  size_t ssl_write_buffered_length;
+};
+
+#define BACKEND connssl->backend
+
+/* pinned public key support tests */
+
+/* version 1 supports macOS 10.12+ and iOS 10+ */
+#if ((TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000) || \
+    (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED  >= 101200))
+#define DARWIN_SSL_PINNEDPUBKEY_V1 1
+#endif
+
+/* version 2 supports MacOSX 10.7+ */
+#if (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
+#define DARWIN_SSL_PINNEDPUBKEY_V2 1
+#endif
+
+#if defined(DARWIN_SSL_PINNEDPUBKEY_V1) || defined(DARWIN_SSL_PINNEDPUBKEY_V2)
+/* this backend supports CURLOPT_PINNEDPUBLICKEY */
+#define DARWIN_SSL_PINNEDPUBKEY 1
+#endif /* DARWIN_SSL_PINNEDPUBKEY */
+
+#ifdef DARWIN_SSL_PINNEDPUBKEY
+/* both new and old APIs return rsa keys missing the spki header (not DER) */
+static const unsigned char rsa4096SpkiHeader[] = {
+                                       0x30, 0x82, 0x02, 0x22, 0x30, 0x0d,
+                                       0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+                                       0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+                                       0x00, 0x03, 0x82, 0x02, 0x0f, 0x00};
+
+static const unsigned char rsa2048SpkiHeader[] = {
+                                       0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+                                       0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+                                       0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+                                       0x00, 0x03, 0x82, 0x01, 0x0f, 0x00};
+#ifdef DARWIN_SSL_PINNEDPUBKEY_V1
+/* the *new* version doesn't return DER encoded ecdsa certs like the old... */
+static const unsigned char ecDsaSecp256r1SpkiHeader[] = {
+                                       0x30, 0x59, 0x30, 0x13, 0x06, 0x07,
+                                       0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
+                                       0x01, 0x06, 0x08, 0x2a, 0x86, 0x48,
+                                       0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
+                                       0x42, 0x00};
+
+static const unsigned char ecDsaSecp384r1SpkiHeader[] = {
+                                       0x30, 0x76, 0x30, 0x10, 0x06, 0x07,
+                                       0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
+                                       0x01, 0x06, 0x05, 0x2b, 0x81, 0x04,
+                                       0x00, 0x22, 0x03, 0x62, 0x00};
+#endif /* DARWIN_SSL_PINNEDPUBKEY_V1 */
+#endif /* DARWIN_SSL_PINNEDPUBKEY */
+
+/* The following two functions were ripped from Apple sample code,
+ * with some modifications: */
+static OSStatus SocketRead(SSLConnectionRef connection,
+                           void *data,          /* owned by
+                                                 * caller, data
+                                                 * RETURNED */
+                           size_t *dataLength)  /* IN/OUT */
+{
+  size_t bytesToGo = *dataLength;
+  size_t initLen = bytesToGo;
+  UInt8 *currData = (UInt8 *)data;
+  /*int sock = *(int *)connection;*/
+  struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
+  int sock = BACKEND->ssl_sockfd;
+  OSStatus rtn = noErr;
+  size_t bytesRead;
+  ssize_t rrtn;
+  int theErr;
+
+  *dataLength = 0;
+
+  for(;;) {
+    bytesRead = 0;
+    rrtn = read(sock, currData, bytesToGo);
+    if(rrtn <= 0) {
+      /* this is guesswork... */
+      theErr = errno;
+      if(rrtn == 0) { /* EOF = server hung up */
+        /* the framework will turn this into errSSLClosedNoNotify */
+        rtn = errSSLClosedGraceful;
+      }
+      else /* do the switch */
+        switch(theErr) {
+          case ENOENT:
+            /* connection closed */
+            rtn = errSSLClosedGraceful;
+            break;
+          case ECONNRESET:
+            rtn = errSSLClosedAbort;
+            break;
+          case EAGAIN:
+            rtn = errSSLWouldBlock;
+            BACKEND->ssl_direction = false;
+            break;
+          default:
+            rtn = ioErr;
+            break;
+        }
+      break;
+    }
+    else {
+      bytesRead = rrtn;
+    }
+    bytesToGo -= bytesRead;
+    currData  += bytesRead;
+
+    if(bytesToGo == 0) {
+      /* filled buffer with incoming data, done */
+      break;
+    }
+  }
+  *dataLength = initLen - bytesToGo;
+
+  return rtn;
+}
+
+static OSStatus SocketWrite(SSLConnectionRef connection,
+                            const void *data,
+                            size_t *dataLength)  /* IN/OUT */
+{
+  size_t bytesSent = 0;
+  /*int sock = *(int *)connection;*/
+  struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
+  int sock = BACKEND->ssl_sockfd;
+  ssize_t length;
+  size_t dataLen = *dataLength;
+  const UInt8 *dataPtr = (UInt8 *)data;
+  OSStatus ortn;
+  int theErr;
+
+  *dataLength = 0;
+
+  do {
+    length = write(sock,
+                   (char *)dataPtr + bytesSent,
+                   dataLen - bytesSent);
+  } while((length > 0) &&
+           ( (bytesSent += length) < dataLen) );
+
+  if(length <= 0) {
+    theErr = errno;
+    if(theErr == EAGAIN) {
+      ortn = errSSLWouldBlock;
+      BACKEND->ssl_direction = true;
+    }
+    else {
+      ortn = ioErr;
+    }
+  }
+  else {
+    ortn = noErr;
+  }
+  *dataLength = bytesSent;
+  return ortn;
+}
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher)
+{
+  switch(cipher) {
+    /* SSL version 3.0 */
+    case SSL_RSA_WITH_NULL_MD5:
+      return "SSL_RSA_WITH_NULL_MD5";
+      break;
+    case SSL_RSA_WITH_NULL_SHA:
+      return "SSL_RSA_WITH_NULL_SHA";
+      break;
+    case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
+      return "SSL_RSA_EXPORT_WITH_RC4_40_MD5";
+      break;
+    case SSL_RSA_WITH_RC4_128_MD5:
+      return "SSL_RSA_WITH_RC4_128_MD5";
+      break;
+    case SSL_RSA_WITH_RC4_128_SHA:
+      return "SSL_RSA_WITH_RC4_128_SHA";
+      break;
+    case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
+      return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5";
+      break;
+    case SSL_RSA_WITH_IDEA_CBC_SHA:
+      return "SSL_RSA_WITH_IDEA_CBC_SHA";
+      break;
+    case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
+      return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA";
+      break;
+    case SSL_RSA_WITH_DES_CBC_SHA:
+      return "SSL_RSA_WITH_DES_CBC_SHA";
+      break;
+    case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
+      return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA";
+      break;
+    case SSL_DH_DSS_WITH_DES_CBC_SHA:
+      return "SSL_DH_DSS_WITH_DES_CBC_SHA";
+      break;
+    case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:
+      return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
+      return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA";
+      break;
+    case SSL_DH_RSA_WITH_DES_CBC_SHA:
+      return "SSL_DH_RSA_WITH_DES_CBC_SHA";
+      break;
+    case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
+      return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA";
+      break;
+    case SSL_DHE_DSS_WITH_DES_CBC_SHA:
+      return "SSL_DHE_DSS_WITH_DES_CBC_SHA";
+      break;
+    case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
+      return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
+      return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA";
+      break;
+    case SSL_DHE_RSA_WITH_DES_CBC_SHA:
+      return "SSL_DHE_RSA_WITH_DES_CBC_SHA";
+      break;
+    case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
+      return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5";
+      break;
+    case SSL_DH_anon_WITH_RC4_128_MD5:
+      return "SSL_DH_anon_WITH_RC4_128_MD5";
+      break;
+    case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
+      return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA";
+      break;
+    case SSL_DH_anon_WITH_DES_CBC_SHA:
+      return "SSL_DH_anon_WITH_DES_CBC_SHA";
+      break;
+    case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
+      return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
+      return "SSL_FORTEZZA_DMS_WITH_NULL_SHA";
+      break;
+    case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
+      return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
+      break;
+    /* TLS 1.0 with AES (RFC 3268)
+       (Apparently these are used in SSLv3 implementations as well.) */
+    case TLS_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
+      return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
+      return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DH_anon_WITH_AES_128_CBC_SHA:
+      return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
+      return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
+      return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DH_anon_WITH_AES_256_CBC_SHA:
+      return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
+      break;
+    /* SSL version 2.0 */
+    case SSL_RSA_WITH_RC2_CBC_MD5:
+      return "SSL_RSA_WITH_RC2_CBC_MD5";
+      break;
+    case SSL_RSA_WITH_IDEA_CBC_MD5:
+      return "SSL_RSA_WITH_IDEA_CBC_MD5";
+      break;
+    case SSL_RSA_WITH_DES_CBC_MD5:
+      return "SSL_RSA_WITH_DES_CBC_MD5";
+      break;
+    case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
+      return "SSL_RSA_WITH_3DES_EDE_CBC_MD5";
+      break;
+  }
+  return "SSL_NULL_WITH_NULL_NULL";
+}
+
+CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher)
+{
+  switch(cipher) {
+    /* TLS 1.0 with AES (RFC 3268) */
+    case TLS_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
+      return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
+      return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DH_anon_WITH_AES_128_CBC_SHA:
+      return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
+      return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
+      return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DH_anon_WITH_AES_256_CBC_SHA:
+      return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
+      break;
+#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
+    /* TLS 1.0 with ECDSA (RFC 4492) */
+    case TLS_ECDH_ECDSA_WITH_NULL_SHA:
+      return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
+      break;
+    case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
+      return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
+      break;
+    case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
+      return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
+      return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
+      return "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
+      return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
+      return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
+      return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_ECDH_RSA_WITH_NULL_SHA:
+      return "TLS_ECDH_RSA_WITH_NULL_SHA";
+      break;
+    case TLS_ECDH_RSA_WITH_RC4_128_SHA:
+      return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
+      break;
+    case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_ECDHE_RSA_WITH_NULL_SHA:
+      return "TLS_ECDHE_RSA_WITH_NULL_SHA";
+      break;
+    case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
+      return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
+      break;
+    case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
+      return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
+      return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_ECDH_anon_WITH_NULL_SHA:
+      return "TLS_ECDH_anon_WITH_NULL_SHA";
+      break;
+    case TLS_ECDH_anon_WITH_RC4_128_SHA:
+      return "TLS_ECDH_anon_WITH_RC4_128_SHA";
+      break;
+    case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
+      return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
+      return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
+      break;
+#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+    /* TLS 1.2 (RFC 5246) */
+    case TLS_RSA_WITH_NULL_MD5:
+      return "TLS_RSA_WITH_NULL_MD5";
+      break;
+    case TLS_RSA_WITH_NULL_SHA:
+      return "TLS_RSA_WITH_NULL_SHA";
+      break;
+    case TLS_RSA_WITH_RC4_128_MD5:
+      return "TLS_RSA_WITH_RC4_128_MD5";
+      break;
+    case TLS_RSA_WITH_RC4_128_SHA:
+      return "TLS_RSA_WITH_RC4_128_SHA";
+      break;
+    case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_RSA_WITH_NULL_SHA256:
+      return "TLS_RSA_WITH_NULL_SHA256";
+      break;
+    case TLS_RSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_RSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_RSA_WITH_AES_256_CBC_SHA256:
+      return "TLS_RSA_WITH_AES_256_CBC_SHA256";
+      break;
+    case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
+      return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
+      return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
+      return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
+      break;
+    case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
+      return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
+      break;
+    case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
+      return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
+      break;
+    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
+      return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
+      break;
+    case TLS_DH_anon_WITH_RC4_128_MD5:
+      return "TLS_DH_anon_WITH_RC4_128_MD5";
+      break;
+    case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
+      return "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
+      return "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
+      break;
+    /* TLS 1.2 with AES GCM (RFC 5288) */
+    case TLS_RSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_RSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_RSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_RSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
+      return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
+      return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
+      return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
+      return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
+      return "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
+      return "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
+      break;
+    /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */
+    case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
+      return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
+      return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
+      return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
+      return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
+      return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
+      return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
+      return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
+      return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
+      break;
+#else
+    case SSL_RSA_WITH_NULL_MD5:
+      return "TLS_RSA_WITH_NULL_MD5";
+      break;
+    case SSL_RSA_WITH_NULL_SHA:
+      return "TLS_RSA_WITH_NULL_SHA";
+      break;
+    case SSL_RSA_WITH_RC4_128_MD5:
+      return "TLS_RSA_WITH_RC4_128_MD5";
+      break;
+    case SSL_RSA_WITH_RC4_128_SHA:
+      return "TLS_RSA_WITH_RC4_128_SHA";
+      break;
+    case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case SSL_DH_anon_WITH_RC4_128_MD5:
+      return "TLS_DH_anon_WITH_RC4_128_MD5";
+      break;
+    case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
+      break;
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
+    /* TLS PSK (RFC 4279): */
+    case TLS_PSK_WITH_RC4_128_SHA:
+      return "TLS_PSK_WITH_RC4_128_SHA";
+      break;
+    case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_PSK_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_PSK_WITH_AES_128_CBC_SHA:
+      return "TLS_PSK_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_PSK_WITH_AES_256_CBC_SHA:
+      return "TLS_PSK_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_DHE_PSK_WITH_RC4_128_SHA:
+      return "TLS_DHE_PSK_WITH_RC4_128_SHA";
+      break;
+    case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
+      return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
+      return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA";
+      break;
+    case TLS_RSA_PSK_WITH_RC4_128_SHA:
+      return "TLS_RSA_PSK_WITH_RC4_128_SHA";
+      break;
+    case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
+      return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA";
+      break;
+    case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
+      return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA";
+      break;
+    case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
+      return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA";
+      break;
+    /* More TLS PSK (RFC 4785): */
+    case TLS_PSK_WITH_NULL_SHA:
+      return "TLS_PSK_WITH_NULL_SHA";
+      break;
+    case TLS_DHE_PSK_WITH_NULL_SHA:
+      return "TLS_DHE_PSK_WITH_NULL_SHA";
+      break;
+    case TLS_RSA_PSK_WITH_NULL_SHA:
+      return "TLS_RSA_PSK_WITH_NULL_SHA";
+      break;
+    /* Even more TLS PSK (RFC 5487): */
+    case TLS_PSK_WITH_AES_128_GCM_SHA256:
+      return "TLS_PSK_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_PSK_WITH_AES_256_GCM_SHA384:
+      return "TLS_PSK_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
+      return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
+      return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
+      return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256";
+      break;
+    case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
+      return "TLS_PSK_WITH_AES_256_GCM_SHA384";
+      break;
+    case TLS_PSK_WITH_AES_128_CBC_SHA256:
+      return "TLS_PSK_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_PSK_WITH_AES_256_CBC_SHA384:
+      return "TLS_PSK_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_PSK_WITH_NULL_SHA256:
+      return "TLS_PSK_WITH_NULL_SHA256";
+      break;
+    case TLS_PSK_WITH_NULL_SHA384:
+      return "TLS_PSK_WITH_NULL_SHA384";
+      break;
+    case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
+      return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
+      return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_DHE_PSK_WITH_NULL_SHA256:
+      return "TLS_DHE_PSK_WITH_NULL_SHA256";
+      break;
+    case TLS_DHE_PSK_WITH_NULL_SHA384:
+      return "TLS_RSA_PSK_WITH_NULL_SHA384";
+      break;
+    case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
+      return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256";
+      break;
+    case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
+      return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384";
+      break;
+    case TLS_RSA_PSK_WITH_NULL_SHA256:
+      return "TLS_RSA_PSK_WITH_NULL_SHA256";
+      break;
+    case TLS_RSA_PSK_WITH_NULL_SHA384:
+      return "TLS_RSA_PSK_WITH_NULL_SHA384";
+      break;
+#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
+#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
+    /* New ChaCha20+Poly1305 cipher-suites used by TLS 1.3: */
+    case TLS_AES_128_GCM_SHA256:
+      return "TLS_AES_128_GCM_SHA256";
+      break;
+    case TLS_AES_256_GCM_SHA384:
+      return "TLS_AES_256_GCM_SHA384";
+      break;
+    case TLS_CHACHA20_POLY1305_SHA256:
+      return "TLS_CHACHA20_POLY1305_SHA256";
+      break;
+    case TLS_AES_128_CCM_SHA256:
+      return "TLS_AES_128_CCM_SHA256";
+      break;
+    case TLS_AES_128_CCM_8_SHA256:
+      return "TLS_AES_128_CCM_8_SHA256";
+      break;
+    case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
+      return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
+      break;
+    case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
+      return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256";
+      break;
+#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
+  }
+  return "TLS_NULL_WITH_NULL_NULL";
+}
+#endif /* !CURL_DISABLE_VERBOSE_STRINGS */
+
+#if CURL_BUILD_MAC
+CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
+{
+  int mib[2];
+  char *os_version;
+  size_t os_version_len;
+  char *os_version_major, *os_version_minor;
+  char *tok_buf;
+
+  /* Get the Darwin kernel version from the kernel using sysctl(): */
+  mib[0] = CTL_KERN;
+  mib[1] = KERN_OSRELEASE;
+  if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
+    return;
+  os_version = malloc(os_version_len*sizeof(char));
+  if(!os_version)
+    return;
+  if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
+    free(os_version);
+    return;
+  }
+
+  /* Parse the version: */
+  os_version_major = strtok_r(os_version, ".", &tok_buf);
+  os_version_minor = strtok_r(NULL, ".", &tok_buf);
+  *major = atoi(os_version_major);
+  *minor = atoi(os_version_minor);
+  free(os_version);
+}
+#endif /* CURL_BUILD_MAC */
+
+/* Apple provides a myriad of ways of getting information about a certificate
+   into a string. Some aren't available under iOS or newer cats. So here's
+   a unified function for getting a string describing the certificate that
+   ought to work in all cats starting with Leopard. */
+CF_INLINE CFStringRef getsubject(SecCertificateRef cert)
+{
+  CFStringRef server_cert_summary = CFSTR("(null)");
+
+#if CURL_BUILD_IOS
+  /* iOS: There's only one way to do this. */
+  server_cert_summary = SecCertificateCopySubjectSummary(cert);
+#else
+#if CURL_BUILD_MAC_10_7
+  /* Lion & later: Get the long description if we can. */
+  if(SecCertificateCopyLongDescription != NULL)
+    server_cert_summary =
+      SecCertificateCopyLongDescription(NULL, cert, NULL);
+  else
+#endif /* CURL_BUILD_MAC_10_7 */
+#if CURL_BUILD_MAC_10_6
+  /* Snow Leopard: Get the certificate summary. */
+  if(SecCertificateCopySubjectSummary != NULL)
+    server_cert_summary = SecCertificateCopySubjectSummary(cert);
+  else
+#endif /* CURL_BUILD_MAC_10_6 */
+  /* Leopard is as far back as we go... */
+  (void)SecCertificateCopyCommonName(cert, &server_cert_summary);
+#endif /* CURL_BUILD_IOS */
+  return server_cert_summary;
+}
+
+static CURLcode CopyCertSubject(struct Curl_easy *data,
+                                SecCertificateRef cert, char **certp)
+{
+  CFStringRef c = getsubject(cert);
+  CURLcode result = CURLE_OK;
+  const char *direct;
+  char *cbuf = NULL;
+  *certp = NULL;
+
+  if(!c) {
+    failf(data, "SSL: invalid CA certificate subject");
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  /* If the subject is already available as UTF-8 encoded (ie 'direct') then
+     use that, else convert it. */
+  direct = CFStringGetCStringPtr(c, kCFStringEncodingUTF8);
+  if(direct) {
+    *certp = strdup(direct);
+    if(!*certp) {
+      failf(data, "SSL: out of memory");
+      result = CURLE_OUT_OF_MEMORY;
+    }
+  }
+  else {
+    size_t cbuf_size = ((size_t)CFStringGetLength(c) * 4) + 1;
+    cbuf = calloc(cbuf_size, 1);
+    if(cbuf) {
+      if(!CFStringGetCString(c, cbuf, cbuf_size,
+                             kCFStringEncodingUTF8)) {
+        failf(data, "SSL: invalid CA certificate subject");
+        result = CURLE_SSL_CACERT;
+      }
+      else
+        /* pass back the buffer */
+        *certp = cbuf;
+    }
+    else {
+      failf(data, "SSL: couldn't allocate %zu bytes of memory", cbuf_size);
+      result = CURLE_OUT_OF_MEMORY;
+    }
+  }
+  if(result)
+    free(cbuf);
+  CFRelease(c);
+  return result;
+}
+
+#if CURL_SUPPORT_MAC_10_6
+/* The SecKeychainSearch API was deprecated in Lion, and using it will raise
+   deprecation warnings, so let's not compile this unless it's necessary: */
+static OSStatus CopyIdentityWithLabelOldSchool(char *label,
+                                               SecIdentityRef *out_c_a_k)
+{
+  OSStatus status = errSecItemNotFound;
+  SecKeychainAttributeList attr_list;
+  SecKeychainAttribute attr;
+  SecKeychainSearchRef search = NULL;
+  SecCertificateRef cert = NULL;
+
+  /* Set up the attribute list: */
+  attr_list.count = 1L;
+  attr_list.attr = &attr;
+
+  /* Set up our lone search criterion: */
+  attr.tag = kSecLabelItemAttr;
+  attr.data = label;
+  attr.length = (UInt32)strlen(label);
+
+  /* Start searching: */
+  status = SecKeychainSearchCreateFromAttributes(NULL,
+                                                 kSecCertificateItemClass,
+                                                 &attr_list,
+                                                 &search);
+  if(status == noErr) {
+    status = SecKeychainSearchCopyNext(search,
+                                       (SecKeychainItemRef *)&cert);
+    if(status == noErr && cert) {
+      /* If we found a certificate, does it have a private key? */
+      status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k);
+      CFRelease(cert);
+    }
+  }
+
+  if(search)
+    CFRelease(search);
+  return status;
+}
+#endif /* CURL_SUPPORT_MAC_10_6 */
+
+static OSStatus CopyIdentityWithLabel(char *label,
+                                      SecIdentityRef *out_cert_and_key)
+{
+  OSStatus status = errSecItemNotFound;
+
+#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
+  CFArrayRef keys_list;
+  CFIndex keys_list_count;
+  CFIndex i;
+  CFStringRef common_name;
+
+  /* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
+     kSecClassIdentity was introduced in Lion. If both exist, let's use them
+     to find the certificate. */
+  if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
+    CFTypeRef keys[5];
+    CFTypeRef values[5];
+    CFDictionaryRef query_dict;
+    CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
+      kCFStringEncodingUTF8);
+
+    /* Set up our search criteria and expected results: */
+    values[0] = kSecClassIdentity; /* we want a certificate and a key */
+    keys[0] = kSecClass;
+    values[1] = kCFBooleanTrue;    /* we want a reference */
+    keys[1] = kSecReturnRef;
+    values[2] = kSecMatchLimitAll; /* kSecMatchLimitOne would be better if the
+                                    * label matching below worked correctly */
+    keys[2] = kSecMatchLimit;
+    /* identity searches need a SecPolicyRef in order to work */
+    values[3] = SecPolicyCreateSSL(false, NULL);
+    keys[3] = kSecMatchPolicy;
+    /* match the name of the certificate (doesn't work in macOS 10.12.1) */
+    values[4] = label_cf;
+    keys[4] = kSecAttrLabel;
+    query_dict = CFDictionaryCreate(NULL, (const void **)keys,
+                                    (const void **)values, 5L,
+                                    &kCFCopyStringDictionaryKeyCallBacks,
+                                    &kCFTypeDictionaryValueCallBacks);
+    CFRelease(values[3]);
+
+    /* Do we have a match? */
+    status = SecItemCopyMatching(query_dict, (CFTypeRef *) &keys_list);
+
+    /* Because kSecAttrLabel matching doesn't work with kSecClassIdentity,
+     * we need to find the correct identity ourselves */
+    if(status == noErr) {
+      keys_list_count = CFArrayGetCount(keys_list);
+      *out_cert_and_key = NULL;
+      status = 1;
+      for(i = 0; i<keys_list_count; i++) {
+        OSStatus err = noErr;
+        SecCertificateRef cert = NULL;
+        SecIdentityRef identity =
+          (SecIdentityRef) CFArrayGetValueAtIndex(keys_list, i);
+        err = SecIdentityCopyCertificate(identity, &cert);
+        if(err == noErr) {
+#if CURL_BUILD_IOS
+          common_name = SecCertificateCopySubjectSummary(cert);
+#elif CURL_BUILD_MAC_10_7
+          SecCertificateCopyCommonName(cert, &common_name);
+#endif
+          if(CFStringCompare(common_name, label_cf, 0) == kCFCompareEqualTo) {
+            CFRelease(cert);
+            CFRelease(common_name);
+            CFRetain(identity);
+            *out_cert_and_key = identity;
+            status = noErr;
+            break;
+          }
+          CFRelease(common_name);
+        }
+        CFRelease(cert);
+      }
+    }
+
+    if(keys_list)
+      CFRelease(keys_list);
+    CFRelease(query_dict);
+    CFRelease(label_cf);
+  }
+  else {
+#if CURL_SUPPORT_MAC_10_6
+    /* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
+    status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
+#endif /* CURL_SUPPORT_MAC_10_6 */
+  }
+#elif CURL_SUPPORT_MAC_10_6
+  /* For developers building on older cats, we have no choice but to fall back
+     to SecKeychainSearch. */
+  status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
+#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
+  return status;
+}
+
+static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
+                                           const char *cPassword,
+                                           SecIdentityRef *out_cert_and_key)
+{
+  OSStatus status = errSecItemNotFound;
+  CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL,
+    (const UInt8 *)cPath, strlen(cPath), false);
+  CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
+    cPassword, kCFStringEncodingUTF8) : NULL;
+  CFDataRef pkcs_data = NULL;
+
+  /* We can import P12 files on iOS or OS X 10.7 or later: */
+  /* These constants are documented as having first appeared in 10.6 but they
+     raise linker errors when used on that cat for some reason. */
+#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
+  if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data,
+    NULL, NULL, &status)) {
+    const void *cKeys[] = {kSecImportExportPassphrase};
+    const void *cValues[] = {password};
+    CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
+      password ? 1L : 0L, NULL, NULL);
+    CFArrayRef items = NULL;
+
+    /* Here we go: */
+    status = SecPKCS12Import(pkcs_data, options, &items);
+    if(status == errSecSuccess && items && CFArrayGetCount(items)) {
+      CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L);
+      const void *temp_identity = CFDictionaryGetValue(identity_and_trust,
+        kSecImportItemIdentity);
+
+      /* Retain the identity; we don't care about any other data... */
+      CFRetain(temp_identity);
+      *out_cert_and_key = (SecIdentityRef)temp_identity;
+    }
+
+    if(items)
+      CFRelease(items);
+    CFRelease(options);
+    CFRelease(pkcs_data);
+  }
+#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
+  if(password)
+    CFRelease(password);
+  CFRelease(pkcs_url);
+  return status;
+}
+
+/* This code was borrowed from nss.c, with some modifications:
+ * Determine whether the nickname passed in is a filename that needs to
+ * be loaded as a PEM or a regular NSS nickname.
+ *
+ * returns 1 for a file
+ * returns 0 for not a file
+ */
+CF_INLINE bool is_file(const char *filename)
+{
+  struct_stat st;
+
+  if(filename == NULL)
+    return false;
+
+  if(stat(filename, &st) == 0)
+    return S_ISREG(st.st_mode);
+  return false;
+}
+
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+static CURLcode darwinssl_version_from_curl(SSLProtocol *darwinver,
+                                            long ssl_version)
+{
+  switch(ssl_version) {
+    case CURL_SSLVERSION_TLSv1_0:
+      *darwinver = kTLSProtocol1;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_1:
+      *darwinver = kTLSProtocol11;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_2:
+      *darwinver = kTLSProtocol12;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_3:
+      /* TLS 1.3 support first appeared in iOS 11 and macOS 10.13 */
+#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
+      /* We can assume __builtin_available() will always work in the
+         10.13/11.0 SDK: */
+      if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
+        *darwinver = kTLSProtocol13;
+        return CURLE_OK;
+      }
+#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
+      break;
+  }
+  return CURLE_SSL_CONNECT_ERROR;
+}
+#endif
+
+static CURLcode
+set_ssl_version_min_max(struct connectdata *conn, int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  long ssl_version = SSL_CONN_CONFIG(version);
+  long ssl_version_max = SSL_CONN_CONFIG(version_max);
+  long max_supported_version_by_os;
+
+  /* macOS 10.5-10.7 supported TLS 1.0 only.
+     macOS 10.8 and later, and iOS 5 and later, added TLS 1.1 and 1.2.
+     macOS 10.13 and later, and iOS 11 and later, added TLS 1.3. */
+#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
+  if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
+    max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_3;
+  }
+  else {
+    max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2;
+  }
+#else
+  max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2;
+#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
+
+  switch(ssl_version) {
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1:
+      ssl_version = CURL_SSLVERSION_TLSv1_0;
+      ssl_version_max = max_supported_version_by_os;
+      break;
+  }
+
+  switch(ssl_version_max) {
+    case CURL_SSLVERSION_MAX_NONE:
+      ssl_version_max = ssl_version << 16;
+      break;
+    case CURL_SSLVERSION_MAX_DEFAULT:
+      ssl_version_max = max_supported_version_by_os;
+      break;
+  }
+
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+  if(SSLSetProtocolVersionMax != NULL) {
+    SSLProtocol darwin_ver_min = kTLSProtocol1;
+    SSLProtocol darwin_ver_max = kTLSProtocol1;
+    CURLcode result = darwinssl_version_from_curl(&darwin_ver_min,
+                                                  ssl_version);
+    if(result) {
+      failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
+      return result;
+    }
+    result = darwinssl_version_from_curl(&darwin_ver_max,
+                                         ssl_version_max >> 16);
+    if(result) {
+      failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
+      return result;
+    }
+
+    (void)SSLSetProtocolVersionMin(BACKEND->ssl_ctx, darwin_ver_min);
+    (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, darwin_ver_max);
+    return result;
+  }
+  else {
+#if CURL_SUPPORT_MAC_10_8
+    long i = ssl_version;
+    (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+                                       kSSLProtocolAll,
+                                       false);
+    for(; i <= (ssl_version_max >> 16); i++) {
+      switch(i) {
+        case CURL_SSLVERSION_TLSv1_0:
+          (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+                                            kTLSProtocol1,
+                                            true);
+          break;
+        case CURL_SSLVERSION_TLSv1_1:
+          (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+                                            kTLSProtocol11,
+                                            true);
+          break;
+        case CURL_SSLVERSION_TLSv1_2:
+          (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+                                            kTLSProtocol12,
+                                            true);
+          break;
+        case CURL_SSLVERSION_TLSv1_3:
+          failf(data, "Your version of the OS does not support TLSv1.3");
+          return CURLE_SSL_CONNECT_ERROR;
+      }
+    }
+    return CURLE_OK;
+#endif  /* CURL_SUPPORT_MAC_10_8 */
+  }
+#endif  /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+  failf(data, "DarwinSSL: cannot set SSL protocol");
+  return CURLE_SSL_CONNECT_ERROR;
+}
+
+
+static CURLcode darwinssl_connect_step1(struct connectdata *conn,
+                                        int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  curl_socket_t sockfd = conn->sock[sockindex];
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
+  const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
+  char * const ssl_cert = SSL_SET_OPTION(cert);
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+  const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
+#ifdef ENABLE_IPV6
+  struct in6_addr addr;
+#else
+  struct in_addr addr;
+#endif /* ENABLE_IPV6 */
+  size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
+  SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
+  OSStatus err = noErr;
+#if CURL_BUILD_MAC
+  int darwinver_maj = 0, darwinver_min = 0;
+
+  GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
+#endif /* CURL_BUILD_MAC */
+
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+  if(SSLCreateContext != NULL) {  /* use the newer API if avaialble */
+    if(BACKEND->ssl_ctx)
+      CFRelease(BACKEND->ssl_ctx);
+    BACKEND->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
+    if(!BACKEND->ssl_ctx) {
+      failf(data, "SSL: couldn't create a context!");
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+  else {
+  /* The old ST API does not exist under iOS, so don't compile it: */
+#if CURL_SUPPORT_MAC_10_8
+    if(BACKEND->ssl_ctx)
+      (void)SSLDisposeContext(BACKEND->ssl_ctx);
+    err = SSLNewContext(false, &(BACKEND->ssl_ctx));
+    if(err != noErr) {
+      failf(data, "SSL: couldn't create a context: OSStatus %d", err);
+      return CURLE_OUT_OF_MEMORY;
+    }
+#endif /* CURL_SUPPORT_MAC_10_8 */
+  }
+#else
+  if(BACKEND->ssl_ctx)
+    (void)SSLDisposeContext(BACKEND->ssl_ctx);
+  err = SSLNewContext(false, &(BACKEND->ssl_ctx));
+  if(err != noErr) {
+    failf(data, "SSL: couldn't create a context: OSStatus %d", err);
+    return CURLE_OUT_OF_MEMORY;
+  }
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+  BACKEND->ssl_write_buffered_length = 0UL; /* reset buffered write length */
+
+  /* check to see if we've been told to use an explicit SSL/TLS version */
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+  if(SSLSetProtocolVersionMax != NULL) {
+    switch(conn->ssl_config.version) {
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1:
+      (void)SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kTLSProtocol1);
+#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
+      if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
+        (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol13);
+      }
+      else {
+        (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol12);
+      }
+#else
+      (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol12);
+#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
+      break;
+    case CURL_SSLVERSION_TLSv1_0:
+    case CURL_SSLVERSION_TLSv1_1:
+    case CURL_SSLVERSION_TLSv1_2:
+    case CURL_SSLVERSION_TLSv1_3:
+      {
+        CURLcode result = set_ssl_version_min_max(conn, sockindex);
+        if(result != CURLE_OK)
+          return result;
+        break;
+      }
+    case CURL_SSLVERSION_SSLv3:
+      err = SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kSSLProtocol3);
+      if(err != noErr) {
+        failf(data, "Your version of the OS does not support SSLv3");
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kSSLProtocol3);
+      break;
+    case CURL_SSLVERSION_SSLv2:
+      err = SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kSSLProtocol2);
+      if(err != noErr) {
+        failf(data, "Your version of the OS does not support SSLv2");
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kSSLProtocol2);
+      break;
+    default:
+      failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+  else {
+#if CURL_SUPPORT_MAC_10_8
+    (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+                                       kSSLProtocolAll,
+                                       false);
+    switch(conn->ssl_config.version) {
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1:
+      (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+                                         kTLSProtocol1,
+                                         true);
+      (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+                                         kTLSProtocol11,
+                                         true);
+      (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+                                         kTLSProtocol12,
+                                         true);
+      break;
+    case CURL_SSLVERSION_TLSv1_0:
+    case CURL_SSLVERSION_TLSv1_1:
+    case CURL_SSLVERSION_TLSv1_2:
+    case CURL_SSLVERSION_TLSv1_3:
+      {
+        CURLcode result = set_ssl_version_min_max(conn, sockindex);
+        if(result != CURLE_OK)
+          return result;
+        break;
+      }
+    case CURL_SSLVERSION_SSLv3:
+      err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+                                         kSSLProtocol3,
+                                         true);
+      if(err != noErr) {
+        failf(data, "Your version of the OS does not support SSLv3");
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      break;
+    case CURL_SSLVERSION_SSLv2:
+      err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+                                         kSSLProtocol2,
+                                         true);
+      if(err != noErr) {
+        failf(data, "Your version of the OS does not support SSLv2");
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      break;
+    default:
+      failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+#endif  /* CURL_SUPPORT_MAC_10_8 */
+  }
+#else
+  if(conn->ssl_config.version_max != CURL_SSLVERSION_MAX_NONE) {
+    failf(data, "Your version of the OS does not support to set maximum"
+                " SSL/TLS version");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+  (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, kSSLProtocolAll, false);
+  switch(conn->ssl_config.version) {
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+  case CURL_SSLVERSION_TLSv1_0:
+    (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+                                       kTLSProtocol1,
+                                       true);
+    break;
+  case CURL_SSLVERSION_TLSv1_1:
+    failf(data, "Your version of the OS does not support TLSv1.1");
+    return CURLE_SSL_CONNECT_ERROR;
+  case CURL_SSLVERSION_TLSv1_2:
+    failf(data, "Your version of the OS does not support TLSv1.2");
+    return CURLE_SSL_CONNECT_ERROR;
+  case CURL_SSLVERSION_TLSv1_3:
+    failf(data, "Your version of the OS does not support TLSv1.3");
+    return CURLE_SSL_CONNECT_ERROR;
+  case CURL_SSLVERSION_SSLv2:
+    err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+                                       kSSLProtocol2,
+                                       true);
+    if(err != noErr) {
+      failf(data, "Your version of the OS does not support SSLv2");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+    break;
+  case CURL_SSLVERSION_SSLv3:
+    err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
+                                       kSSLProtocol3,
+                                       true);
+    if(err != noErr) {
+      failf(data, "Your version of the OS does not support SSLv3");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+    break;
+  default:
+    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+
+  if(SSL_SET_OPTION(key)) {
+    infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
+          "Transport. The private key must be in the Keychain.\n");
+  }
+
+  if(ssl_cert) {
+    SecIdentityRef cert_and_key = NULL;
+    bool is_cert_file = is_file(ssl_cert);
+
+    /* User wants to authenticate with a client cert. Look for it:
+       If we detect that this is a file on disk, then let's load it.
+       Otherwise, assume that the user wants to use an identity loaded
+       from the Keychain. */
+    if(is_cert_file) {
+      if(!SSL_SET_OPTION(cert_type))
+        infof(data, "WARNING: SSL: Certificate type not set, assuming "
+                    "PKCS#12 format.\n");
+      else if(strncmp(SSL_SET_OPTION(cert_type), "P12",
+        strlen(SSL_SET_OPTION(cert_type))) != 0)
+        infof(data, "WARNING: SSL: The Security framework only supports "
+                    "loading identities that are in PKCS#12 format.\n");
+
+      err = CopyIdentityFromPKCS12File(ssl_cert,
+        SSL_SET_OPTION(key_passwd), &cert_and_key);
+    }
+    else
+      err = CopyIdentityWithLabel(ssl_cert, &cert_and_key);
+
+    if(err == noErr && cert_and_key) {
+      SecCertificateRef cert = NULL;
+      CFTypeRef certs_c[1];
+      CFArrayRef certs;
+
+      /* If we found one, print it out: */
+      err = SecIdentityCopyCertificate(cert_and_key, &cert);
+      if(err == noErr) {
+        char *certp;
+        CURLcode result = CopyCertSubject(data, cert, &certp);
+        if(!result) {
+          infof(data, "Client certificate: %s\n", certp);
+          free(certp);
+        }
+
+        CFRelease(cert);
+        if(result)
+          return result;
+      }
+      certs_c[0] = cert_and_key;
+      certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
+                            &kCFTypeArrayCallBacks);
+      err = SSLSetCertificate(BACKEND->ssl_ctx, certs);
+      if(certs)
+        CFRelease(certs);
+      if(err != noErr) {
+        failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
+        return CURLE_SSL_CERTPROBLEM;
+      }
+      CFRelease(cert_and_key);
+    }
+    else {
+      switch(err) {
+      case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
+        failf(data, "SSL: Incorrect password for the certificate \"%s\" "
+                    "and its private key.", ssl_cert);
+        break;
+      case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
+        failf(data, "SSL: Couldn't make sense of the data in the "
+                    "certificate \"%s\" and its private key.",
+                    ssl_cert);
+        break;
+      case -25260: /* errSecPassphraseRequired */
+        failf(data, "SSL The certificate \"%s\" requires a password.",
+                    ssl_cert);
+        break;
+      case errSecItemNotFound:
+        failf(data, "SSL: Can't find the certificate \"%s\" and its private "
+                    "key in the Keychain.", ssl_cert);
+        break;
+      default:
+        failf(data, "SSL: Can't load the certificate \"%s\" and its private "
+                    "key: OSStatus %d", ssl_cert, err);
+        break;
+      }
+      return CURLE_SSL_CERTPROBLEM;
+    }
+  }
+
+  /* SSL always tries to verify the peer, this only says whether it should
+   * fail to connect if the verification fails, or if it should continue
+   * anyway. In the latter case the result of the verification is checked with
+   * SSL_get_verify_result() below. */
+#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
+  /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
+     a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
+     works, it doesn't work as expected under Snow Leopard, Lion or
+     Mountain Lion.
+     So we need to call SSLSetEnableCertVerify() on those older cats in order
+     to disable certificate validation if the user turned that off.
+     (SecureTransport will always validate the certificate chain by
+     default.)
+  Note:
+  Darwin 11.x.x is Lion (10.7)
+  Darwin 12.x.x is Mountain Lion (10.8)
+  Darwin 13.x.x is Mavericks (10.9)
+  Darwin 14.x.x is Yosemite (10.10)
+  Darwin 15.x.x is El Capitan (10.11)
+  */
+#if CURL_BUILD_MAC
+  if(SSLSetSessionOption != NULL && darwinver_maj >= 13) {
+#else
+  if(SSLSetSessionOption != NULL) {
+#endif /* CURL_BUILD_MAC */
+    bool break_on_auth = !conn->ssl_config.verifypeer || ssl_cafile;
+    err = SSLSetSessionOption(BACKEND->ssl_ctx,
+                              kSSLSessionOptionBreakOnServerAuth,
+                              break_on_auth);
+    if(err != noErr) {
+      failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+  else {
+#if CURL_SUPPORT_MAC_10_8
+    err = SSLSetEnableCertVerify(BACKEND->ssl_ctx,
+                                 conn->ssl_config.verifypeer?true:false);
+    if(err != noErr) {
+      failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+#endif /* CURL_SUPPORT_MAC_10_8 */
+  }
+#else
+  err = SSLSetEnableCertVerify(BACKEND->ssl_ctx,
+                               conn->ssl_config.verifypeer?true:false);
+  if(err != noErr) {
+    failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
+
+  if(ssl_cafile && verifypeer) {
+    bool is_cert_file = is_file(ssl_cafile);
+
+    if(!is_cert_file) {
+      failf(data, "SSL: can't load CA certificate file %s", ssl_cafile);
+      return CURLE_SSL_CACERT_BADFILE;
+    }
+  }
+
+  /* Configure hostname check. SNI is used if available.
+   * Both hostname check and SNI require SSLSetPeerDomainName().
+   * Also: the verifyhost setting influences SNI usage */
+  if(conn->ssl_config.verifyhost) {
+    err = SSLSetPeerDomainName(BACKEND->ssl_ctx, hostname,
+    strlen(hostname));
+
+    if(err != noErr) {
+      infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
+            err);
+    }
+
+    if((Curl_inet_pton(AF_INET, hostname, &addr))
+  #ifdef ENABLE_IPV6
+    || (Curl_inet_pton(AF_INET6, hostname, &addr))
+  #endif
+       ) {
+      infof(data, "WARNING: using IP address, SNI is being disabled by "
+            "the OS.\n");
+    }
+  }
+  else {
+    infof(data, "WARNING: disabling hostname validation also disables SNI.\n");
+  }
+
+  /* Disable cipher suites that ST supports but are not safe. These ciphers
+     are unlikely to be used in any case since ST gives other ciphers a much
+     higher priority, but it's probably better that we not connect at all than
+     to give the user a false sense of security if the server only supports
+     insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
+  (void)SSLGetNumberSupportedCiphers(BACKEND->ssl_ctx, &all_ciphers_count);
+  all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
+  allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
+  if(all_ciphers && allowed_ciphers &&
+     SSLGetSupportedCiphers(BACKEND->ssl_ctx, all_ciphers,
+       &all_ciphers_count) == noErr) {
+    for(i = 0UL ; i < all_ciphers_count ; i++) {
+#if CURL_BUILD_MAC
+     /* There's a known bug in early versions of Mountain Lion where ST's ECC
+        ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
+        Work around the problem here by disabling those ciphers if we are
+        running in an affected version of OS X. */
+      if(darwinver_maj == 12 && darwinver_min <= 3 &&
+         all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
+        continue;
+      }
+#endif /* CURL_BUILD_MAC */
+      switch(all_ciphers[i]) {
+        /* Disable NULL ciphersuites: */
+        case SSL_NULL_WITH_NULL_NULL:
+        case SSL_RSA_WITH_NULL_MD5:
+        case SSL_RSA_WITH_NULL_SHA:
+        case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
+        case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
+        case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
+        case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
+        case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
+        case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
+        case 0x002C: /* TLS_PSK_WITH_NULL_SHA */
+        case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */
+        case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */
+        case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */
+        case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */
+        case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */
+        case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */
+        case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */
+        case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */
+        /* Disable anonymous ciphersuites: */
+        case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
+        case SSL_DH_anon_WITH_RC4_128_MD5:
+        case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_DH_anon_WITH_DES_CBC_SHA:
+        case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
+        case TLS_DH_anon_WITH_AES_128_CBC_SHA:
+        case TLS_DH_anon_WITH_AES_256_CBC_SHA:
+        case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
+        case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
+        case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
+        case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
+        case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
+        case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
+        case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
+        case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
+        case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
+        /* Disable weak key ciphersuites: */
+        case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
+        case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
+        case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
+        case SSL_RSA_WITH_DES_CBC_SHA:
+        case SSL_DH_DSS_WITH_DES_CBC_SHA:
+        case SSL_DH_RSA_WITH_DES_CBC_SHA:
+        case SSL_DHE_DSS_WITH_DES_CBC_SHA:
+        case SSL_DHE_RSA_WITH_DES_CBC_SHA:
+        /* Disable IDEA: */
+        case SSL_RSA_WITH_IDEA_CBC_SHA:
+        case SSL_RSA_WITH_IDEA_CBC_MD5:
+        /* Disable RC4: */
+        case SSL_RSA_WITH_RC4_128_MD5:
+        case SSL_RSA_WITH_RC4_128_SHA:
+        case 0xC002: /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */
+        case 0xC007: /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA*/
+        case 0xC00C: /* TLS_ECDH_RSA_WITH_RC4_128_SHA */
+        case 0xC011: /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
+        case 0x008A: /* TLS_PSK_WITH_RC4_128_SHA */
+        case 0x008E: /* TLS_DHE_PSK_WITH_RC4_128_SHA */
+        case 0x0092: /* TLS_RSA_PSK_WITH_RC4_128_SHA */
+          break;
+        default: /* enable everything else */
+          allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
+          break;
+      }
+    }
+    err = SSLSetEnabledCiphers(BACKEND->ssl_ctx, allowed_ciphers,
+                               allowed_ciphers_count);
+    if(err != noErr) {
+      failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+  else {
+    Curl_safefree(all_ciphers);
+    Curl_safefree(allowed_ciphers);
+    failf(data, "SSL: Failed to allocate memory for allowed ciphers");
+    return CURLE_OUT_OF_MEMORY;
+  }
+  Curl_safefree(all_ciphers);
+  Curl_safefree(allowed_ciphers);
+
+#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
+  /* We want to enable 1/n-1 when using a CBC cipher unless the user
+     specifically doesn't want us doing that: */
+  if(SSLSetSessionOption != NULL) {
+    /* TODO s/data->set.ssl.enable_beast/SSL_SET_OPTION(enable_beast)/g */
+    SSLSetSessionOption(BACKEND->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
+                      !data->set.ssl.enable_beast);
+    SSLSetSessionOption(BACKEND->ssl_ctx, kSSLSessionOptionFalseStart,
+                      data->set.ssl.falsestart); /* false start support */
+  }
+#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
+
+  /* Check if there's a cached ID we can/should use here! */
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    char *ssl_sessionid;
+    size_t ssl_sessionid_len;
+
+    Curl_ssl_sessionid_lock(conn);
+    if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
+                              &ssl_sessionid_len, sockindex)) {
+      /* we got a session id, use it! */
+      err = SSLSetPeerID(BACKEND->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
+      Curl_ssl_sessionid_unlock(conn);
+      if(err != noErr) {
+        failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      /* Informational message */
+      infof(data, "SSL re-using session ID\n");
+    }
+    /* If there isn't one, then let's make one up! This has to be done prior
+       to starting the handshake. */
+    else {
+      CURLcode result;
+      ssl_sessionid =
+        aprintf("%s:%d:%d:%s:%hu", ssl_cafile,
+                verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port);
+      ssl_sessionid_len = strlen(ssl_sessionid);
+
+      err = SSLSetPeerID(BACKEND->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
+      if(err != noErr) {
+        Curl_ssl_sessionid_unlock(conn);
+        failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+
+      result = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len,
+                                     sockindex);
+      Curl_ssl_sessionid_unlock(conn);
+      if(result) {
+        failf(data, "failed to store ssl session");
+        return result;
+      }
+    }
+  }
+
+  err = SSLSetIOFuncs(BACKEND->ssl_ctx, SocketRead, SocketWrite);
+  if(err != noErr) {
+    failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  /* pass the raw socket into the SSL layers */
+  /* We need to store the FD in a constant memory address, because
+   * SSLSetConnection() will not copy that address. I've found that
+   * conn->sock[sockindex] may change on its own. */
+  BACKEND->ssl_sockfd = sockfd;
+  err = SSLSetConnection(BACKEND->ssl_ctx, connssl);
+  if(err != noErr) {
+    failf(data, "SSL: SSLSetConnection() failed: %d", err);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  connssl->connecting_state = ssl_connect_2;
+  return CURLE_OK;
+}
+
+static long pem_to_der(const char *in, unsigned char **out, size_t *outlen)
+{
+  char *sep_start, *sep_end, *cert_start, *cert_end;
+  size_t i, j, err;
+  size_t len;
+  unsigned char *b64;
+
+  /* Jump through the separators at the beginning of the certificate. */
+  sep_start = strstr(in, "-----");
+  if(sep_start == NULL)
+    return 0;
+  cert_start = strstr(sep_start + 1, "-----");
+  if(cert_start == NULL)
+    return -1;
+
+  cert_start += 5;
+
+  /* Find separator after the end of the certificate. */
+  cert_end = strstr(cert_start, "-----");
+  if(cert_end == NULL)
+    return -1;
+
+  sep_end = strstr(cert_end + 1, "-----");
+  if(sep_end == NULL)
+    return -1;
+  sep_end += 5;
+
+  len = cert_end - cert_start;
+  b64 = malloc(len + 1);
+  if(!b64)
+    return -1;
+
+  /* Create base64 string without linefeeds. */
+  for(i = 0, j = 0; i < len; i++) {
+    if(cert_start[i] != '\r' && cert_start[i] != '\n')
+      b64[j++] = cert_start[i];
+  }
+  b64[j] = '\0';
+
+  err = Curl_base64_decode((const char *)b64, out, outlen);
+  free(b64);
+  if(err) {
+    free(*out);
+    return -1;
+  }
+
+  return sep_end - in;
+}
+
+static int read_cert(const char *file, unsigned char **out, size_t *outlen)
+{
+  int fd;
+  ssize_t n, len = 0, cap = 512;
+  unsigned char buf[512], *data;
+
+  fd = open(file, 0);
+  if(fd < 0)
+    return -1;
+
+  data = malloc(cap);
+  if(!data) {
+    close(fd);
+    return -1;
+  }
+
+  for(;;) {
+    n = read(fd, buf, sizeof(buf));
+    if(n < 0) {
+      close(fd);
+      free(data);
+      return -1;
+    }
+    else if(n == 0) {
+      close(fd);
+      break;
+    }
+
+    if(len + n >= cap) {
+      cap *= 2;
+      data = realloc(data, cap);
+      if(!data) {
+        close(fd);
+        return -1;
+      }
+    }
+
+    memcpy(data + len, buf, n);
+    len += n;
+  }
+  data[len] = '\0';
+
+  *out = data;
+  *outlen = len;
+
+  return 0;
+}
+
+static int sslerr_to_curlerr(struct Curl_easy *data, int err)
+{
+  switch(err) {
+    case errSSLXCertChainInvalid:
+      failf(data, "SSL certificate problem: Invalid certificate chain");
+      return CURLE_SSL_CACERT;
+    case errSSLUnknownRootCert:
+      failf(data, "SSL certificate problem: Untrusted root certificate");
+      return CURLE_SSL_CACERT;
+    case errSSLNoRootCert:
+      failf(data, "SSL certificate problem: No root certificate");
+      return CURLE_SSL_CACERT;
+    case errSSLCertExpired:
+      failf(data, "SSL certificate problem: Certificate chain had an "
+            "expired certificate");
+      return CURLE_SSL_CACERT;
+    case errSSLBadCert:
+      failf(data, "SSL certificate problem: Couldn't understand the server "
+            "certificate format");
+      return CURLE_SSL_CONNECT_ERROR;
+    case errSSLHostNameMismatch:
+      failf(data, "SSL certificate peer hostname mismatch");
+      return CURLE_PEER_FAILED_VERIFICATION;
+    default:
+      failf(data, "SSL unexpected certificate error %d", err);
+      return CURLE_SSL_CACERT;
+  }
+}
+
+static int append_cert_to_array(struct Curl_easy *data,
+                                unsigned char *buf, size_t buflen,
+                                CFMutableArrayRef array)
+{
+    CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen);
+    char *certp;
+    CURLcode result;
+    if(!certdata) {
+      failf(data, "SSL: failed to allocate array for CA certificate");
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    SecCertificateRef cacert =
+      SecCertificateCreateWithData(kCFAllocatorDefault, certdata);
+    CFRelease(certdata);
+    if(!cacert) {
+      failf(data, "SSL: failed to create SecCertificate from CA certificate");
+      return CURLE_SSL_CACERT;
+    }
+
+    /* Check if cacert is valid. */
+    result = CopyCertSubject(data, cacert, &certp);
+    if(result)
+      return result;
+    free(certp);
+
+    CFArrayAppendValue(array, cacert);
+    CFRelease(cacert);
+
+    return CURLE_OK;
+}
+
+static int verify_cert(const char *cafile, struct Curl_easy *data,
+                       SSLContextRef ctx)
+{
+  int n = 0, rc;
+  long res;
+  unsigned char *certbuf, *der;
+  size_t buflen, derlen, offset = 0;
+
+  if(read_cert(cafile, &certbuf, &buflen) < 0) {
+    failf(data, "SSL: failed to read or invalid CA certificate");
+    return CURLE_SSL_CACERT;
+  }
+
+  /*
+   * Certbuf now contains the contents of the certificate file, which can be
+   * - a single DER certificate,
+   * - a single PEM certificate or
+   * - a bunch of PEM certificates (certificate bundle).
+   *
+   * Go through certbuf, and convert any PEM certificate in it into DER
+   * format.
+   */
+  CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
+                                                 &kCFTypeArrayCallBacks);
+  if(array == NULL) {
+    free(certbuf);
+    failf(data, "SSL: out of memory creating CA certificate array");
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  while(offset < buflen) {
+    n++;
+
+    /*
+     * Check if the certificate is in PEM format, and convert it to DER. If
+     * this fails, we assume the certificate is in DER format.
+     */
+    res = pem_to_der((const char *)certbuf + offset, &der, &derlen);
+    if(res < 0) {
+      free(certbuf);
+      CFRelease(array);
+      failf(data, "SSL: invalid CA certificate #%d (offset %d) in bundle",
+            n, offset);
+      return CURLE_SSL_CACERT;
+    }
+    offset += res;
+
+    if(res == 0 && offset == 0) {
+      /* This is not a PEM file, probably a certificate in DER format. */
+      rc = append_cert_to_array(data, certbuf, buflen, array);
+      free(certbuf);
+      if(rc != CURLE_OK) {
+        CFRelease(array);
+        return rc;
+      }
+      break;
+    }
+    else if(res == 0) {
+      /* No more certificates in the bundle. */
+      free(certbuf);
+      break;
+    }
+
+    rc = append_cert_to_array(data, der, derlen, array);
+    free(der);
+    if(rc != CURLE_OK) {
+      free(certbuf);
+      CFRelease(array);
+      return rc;
+    }
+  }
+
+  SecTrustRef trust;
+  OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
+  if(trust == NULL) {
+    failf(data, "SSL: error getting certificate chain");
+    CFRelease(array);
+    return CURLE_OUT_OF_MEMORY;
+  }
+  else if(ret != noErr) {
+    CFRelease(array);
+    return sslerr_to_curlerr(data, ret);
+  }
+
+  ret = SecTrustSetAnchorCertificates(trust, array);
+  if(ret != noErr) {
+    CFRelease(trust);
+    return sslerr_to_curlerr(data, ret);
+  }
+  ret = SecTrustSetAnchorCertificatesOnly(trust, true);
+  if(ret != noErr) {
+    CFRelease(trust);
+    return sslerr_to_curlerr(data, ret);
+  }
+
+  SecTrustResultType trust_eval = 0;
+  ret = SecTrustEvaluate(trust, &trust_eval);
+  CFRelease(array);
+  CFRelease(trust);
+  if(ret != noErr) {
+    return sslerr_to_curlerr(data, ret);
+  }
+
+  switch(trust_eval) {
+    case kSecTrustResultUnspecified:
+    case kSecTrustResultProceed:
+      return CURLE_OK;
+
+    case kSecTrustResultRecoverableTrustFailure:
+    case kSecTrustResultDeny:
+    default:
+      failf(data, "SSL: certificate verification failed (result: %d)",
+            trust_eval);
+      return CURLE_PEER_FAILED_VERIFICATION;
+  }
+}
+
+#ifdef DARWIN_SSL_PINNEDPUBKEY
+static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
+                                    SSLContextRef ctx,
+                                    const char *pinnedpubkey)
+{  /* Scratch */
+  size_t pubkeylen, realpubkeylen, spkiHeaderLength = 24;
+  unsigned char *pubkey = NULL, *realpubkey = NULL;
+  const unsigned char *spkiHeader = NULL;
+  CFDataRef publicKeyBits = NULL;
+
+  /* Result is returned to caller */
+  CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+
+  /* if a path wasn't specified, don't pin */
+  if(!pinnedpubkey)
+    return CURLE_OK;
+
+
+  if(!ctx)
+    return result;
+
+  do {
+    SecTrustRef trust;
+    OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
+    if(ret != noErr || trust == NULL)
+      break;
+
+    SecKeyRef keyRef = SecTrustCopyPublicKey(trust);
+    CFRelease(trust);
+    if(keyRef == NULL)
+      break;
+
+#ifdef DARWIN_SSL_PINNEDPUBKEY_V1
+
+    publicKeyBits = SecKeyCopyExternalRepresentation(keyRef, NULL);
+    CFRelease(keyRef);
+    if(publicKeyBits == NULL)
+      break;
+
+#elif DARWIN_SSL_PINNEDPUBKEY_V2
+
+    OSStatus success = SecItemExport(keyRef, kSecFormatOpenSSL, 0, NULL,
+                                     &publicKeyBits);
+    CFRelease(keyRef);
+    if(success != errSecSuccess || publicKeyBits == NULL)
+      break;
+
+#endif /* DARWIN_SSL_PINNEDPUBKEY_V2 */
+
+    pubkeylen = CFDataGetLength(publicKeyBits);
+    pubkey = (unsigned char *)CFDataGetBytePtr(publicKeyBits);
+
+    switch(pubkeylen) {
+      case 526:
+        /* 4096 bit RSA pubkeylen == 526 */
+        spkiHeader = rsa4096SpkiHeader;
+        break;
+      case 270:
+        /* 2048 bit RSA pubkeylen == 270 */
+        spkiHeader = rsa2048SpkiHeader;
+        break;
+#ifdef DARWIN_SSL_PINNEDPUBKEY_V1
+      case 65:
+        /* ecDSA secp256r1 pubkeylen == 65 */
+        spkiHeader = ecDsaSecp256r1SpkiHeader;
+        spkiHeaderLength = 26;
+        break;
+      case 97:
+        /* ecDSA secp384r1 pubkeylen == 97 */
+        spkiHeader = ecDsaSecp384r1SpkiHeader;
+        spkiHeaderLength = 23;
+        break;
+      default:
+        infof(data, "SSL: unhandled public key length: %d\n", pubkeylen);
+#elif DARWIN_SSL_PINNEDPUBKEY_V2
+      default:
+        /* ecDSA secp256r1 pubkeylen == 91 header already included?
+         * ecDSA secp384r1 header already included too
+         * we assume rest of algorithms do same, so do nothing
+         */
+        result = Curl_pin_peer_pubkey(data, pinnedpubkey, pubkey,
+                                    pubkeylen);
+#endif /* DARWIN_SSL_PINNEDPUBKEY_V2 */
+        continue; /* break from loop */
+    }
+
+    realpubkeylen = pubkeylen + spkiHeaderLength;
+    realpubkey = malloc(realpubkeylen);
+    if(!realpubkey)
+      break;
+
+    memcpy(realpubkey, spkiHeader, spkiHeaderLength);
+    memcpy(realpubkey + spkiHeaderLength, pubkey, pubkeylen);
+
+    result = Curl_pin_peer_pubkey(data, pinnedpubkey, realpubkey,
+                                  realpubkeylen);
+
+  } while(0);
+
+  Curl_safefree(realpubkey);
+  if(publicKeyBits != NULL)
+    CFRelease(publicKeyBits);
+
+  return result;
+}
+#endif /* DARWIN_SSL_PINNEDPUBKEY */
+
+static CURLcode
+darwinssl_connect_step2(struct connectdata *conn, int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  OSStatus err;
+  SSLCipherSuite cipher;
+  SSLProtocol protocol = 0;
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+
+  DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
+              || ssl_connect_2_reading == connssl->connecting_state
+              || ssl_connect_2_writing == connssl->connecting_state);
+
+  /* Here goes nothing: */
+  err = SSLHandshake(BACKEND->ssl_ctx);
+
+  if(err != noErr) {
+    switch(err) {
+      case errSSLWouldBlock:  /* they're not done with us yet */
+        connssl->connecting_state = BACKEND->ssl_direction ?
+            ssl_connect_2_writing : ssl_connect_2_reading;
+        return CURLE_OK;
+
+      /* The below is errSSLServerAuthCompleted; it's not defined in
+        Leopard's headers */
+      case -9841:
+        if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) {
+          int res = verify_cert(SSL_CONN_CONFIG(CAfile), data,
+                                BACKEND->ssl_ctx);
+          if(res != CURLE_OK)
+            return res;
+        }
+        /* the documentation says we need to call SSLHandshake() again */
+        return darwinssl_connect_step2(conn, sockindex);
+
+      /* These are all certificate problems with the server: */
+      case errSSLXCertChainInvalid:
+        failf(data, "SSL certificate problem: Invalid certificate chain");
+        return CURLE_SSL_CACERT;
+      case errSSLUnknownRootCert:
+        failf(data, "SSL certificate problem: Untrusted root certificate");
+        return CURLE_SSL_CACERT;
+      case errSSLNoRootCert:
+        failf(data, "SSL certificate problem: No root certificate");
+        return CURLE_SSL_CACERT;
+      case errSSLCertExpired:
+        failf(data, "SSL certificate problem: Certificate chain had an "
+              "expired certificate");
+        return CURLE_SSL_CACERT;
+      case errSSLBadCert:
+        failf(data, "SSL certificate problem: Couldn't understand the server "
+              "certificate format");
+        return CURLE_SSL_CONNECT_ERROR;
+
+      /* These are all certificate problems with the client: */
+      case errSecAuthFailed:
+        failf(data, "SSL authentication failed");
+        return CURLE_SSL_CONNECT_ERROR;
+      case errSSLPeerHandshakeFail:
+        failf(data, "SSL peer handshake failed, the server most likely "
+              "requires a client certificate to connect");
+        return CURLE_SSL_CONNECT_ERROR;
+      case errSSLPeerUnknownCA:
+        failf(data, "SSL server rejected the client certificate due to "
+              "the certificate being signed by an unknown certificate "
+              "authority");
+        return CURLE_SSL_CONNECT_ERROR;
+
+      /* This error is raised if the server's cert didn't match the server's
+         host name: */
+      case errSSLHostNameMismatch:
+        failf(data, "SSL certificate peer verification failed, the "
+              "certificate did not match \"%s\"\n", conn->host.dispname);
+        return CURLE_PEER_FAILED_VERIFICATION;
+
+      /* Generic handshake errors: */
+      case errSSLConnectionRefused:
+        failf(data, "Server dropped the connection during the SSL handshake");
+        return CURLE_SSL_CONNECT_ERROR;
+      case errSSLClosedAbort:
+        failf(data, "Server aborted the SSL handshake");
+        return CURLE_SSL_CONNECT_ERROR;
+      case errSSLNegotiation:
+        failf(data, "Could not negotiate an SSL cipher suite with the server");
+        return CURLE_SSL_CONNECT_ERROR;
+      /* Sometimes paramErr happens with buggy ciphers: */
+      case paramErr: case errSSLInternal:
+        failf(data, "Internal SSL engine error encountered during the "
+              "SSL handshake");
+        return CURLE_SSL_CONNECT_ERROR;
+      case errSSLFatalAlert:
+        failf(data, "Fatal SSL engine error encountered during the SSL "
+              "handshake");
+        return CURLE_SSL_CONNECT_ERROR;
+      default:
+        failf(data, "Unknown SSL protocol error in connection to %s:%d",
+              hostname, err);
+        return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+  else {
+    /* we have been connected fine, we're not waiting for anything else. */
+    connssl->connecting_state = ssl_connect_3;
+
+#ifdef DARWIN_SSL_PINNEDPUBKEY
+    if(data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]) {
+      CURLcode result = pkp_pin_peer_pubkey(data, BACKEND->ssl_ctx,
+                            data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]);
+      if(result) {
+        failf(data, "SSL: public key does not match pinned public key!");
+        return result;
+      }
+    }
+#endif /* DARWIN_SSL_PINNEDPUBKEY */
+
+    /* Informational message */
+    (void)SSLGetNegotiatedCipher(BACKEND->ssl_ctx, &cipher);
+    (void)SSLGetNegotiatedProtocolVersion(BACKEND->ssl_ctx, &protocol);
+    switch(protocol) {
+      case kSSLProtocol2:
+        infof(data, "SSL 2.0 connection using %s\n",
+              SSLCipherNameForNumber(cipher));
+        break;
+      case kSSLProtocol3:
+        infof(data, "SSL 3.0 connection using %s\n",
+              SSLCipherNameForNumber(cipher));
+        break;
+      case kTLSProtocol1:
+        infof(data, "TLS 1.0 connection using %s\n",
+              TLSCipherNameForNumber(cipher));
+        break;
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+      case kTLSProtocol11:
+        infof(data, "TLS 1.1 connection using %s\n",
+              TLSCipherNameForNumber(cipher));
+        break;
+      case kTLSProtocol12:
+        infof(data, "TLS 1.2 connection using %s\n",
+              TLSCipherNameForNumber(cipher));
+        break;
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
+      case kTLSProtocol13:
+        infof(data, "TLS 1.3 connection using %s\n",
+              TLSCipherNameForNumber(cipher));
+        break;
+#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
+      default:
+        infof(data, "Unknown protocol connection\n");
+        break;
+    }
+
+    return CURLE_OK;
+  }
+}
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+/* This should be called during step3 of the connection at the earliest */
+static void
+show_verbose_server_cert(struct connectdata *conn,
+                         int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  CFArrayRef server_certs = NULL;
+  SecCertificateRef server_cert;
+  OSStatus err;
+  CFIndex i, count;
+  SecTrustRef trust = NULL;
+
+  if(!BACKEND->ssl_ctx)
+    return;
+
+#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
+#if CURL_BUILD_IOS
+#pragma unused(server_certs)
+  err = SSLCopyPeerTrust(BACKEND->ssl_ctx, &trust);
+  /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
+     a null trust, so be on guard for that: */
+  if(err == noErr && trust) {
+    count = SecTrustGetCertificateCount(trust);
+    for(i = 0L ; i < count ; i++) {
+      CURLcode result;
+      char *certp;
+      server_cert = SecTrustGetCertificateAtIndex(trust, i);
+      result = CopyCertSubject(data, server_cert, &certp);
+      if(!result) {
+        infof(data, "Server certificate: %s\n", certp);
+        free(certp);
+      }
+    }
+    CFRelease(trust);
+  }
+#else
+  /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
+     The function SecTrustGetCertificateAtIndex() is officially present
+     in Lion, but it is unfortunately also present in Snow Leopard as
+     private API and doesn't work as expected. So we have to look for
+     a different symbol to make sure this code is only executed under
+     Lion or later. */
+  if(SecTrustEvaluateAsync != NULL) {
+#pragma unused(server_certs)
+    err = SSLCopyPeerTrust(BACKEND->ssl_ctx, &trust);
+    /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
+       a null trust, so be on guard for that: */
+    if(err == noErr && trust) {
+      count = SecTrustGetCertificateCount(trust);
+      for(i = 0L ; i < count ; i++) {
+        char *certp;
+        CURLcode result;
+        server_cert = SecTrustGetCertificateAtIndex(trust, i);
+        result = CopyCertSubject(data, server_cert, &certp);
+        if(!result) {
+          infof(data, "Server certificate: %s\n", certp);
+          free(certp);
+        }
+      }
+      CFRelease(trust);
+    }
+  }
+  else {
+#if CURL_SUPPORT_MAC_10_8
+    err = SSLCopyPeerCertificates(BACKEND->ssl_ctx, &server_certs);
+    /* Just in case SSLCopyPeerCertificates() returns null too... */
+    if(err == noErr && server_certs) {
+      count = CFArrayGetCount(server_certs);
+      for(i = 0L ; i < count ; i++) {
+        char *certp;
+        CURLcode result;
+        server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
+                                                                i);
+        result = CopyCertSubject(data, server_cert, &certp);
+        if(!result) {
+          infof(data, "Server certificate: %s\n", certp);
+          free(certp);
+        }
+      }
+      CFRelease(server_certs);
+    }
+#endif /* CURL_SUPPORT_MAC_10_8 */
+  }
+#endif /* CURL_BUILD_IOS */
+#else
+#pragma unused(trust)
+  err = SSLCopyPeerCertificates(BACKEND->ssl_ctx, &server_certs);
+  if(err == noErr) {
+    count = CFArrayGetCount(server_certs);
+    for(i = 0L ; i < count ; i++) {
+      CURLcode result;
+      char *certp;
+      server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
+      result = CopyCertSubject(data, server_cert, &certp);
+      if(!result) {
+        infof(data, "Server certificate: %s\n", certp);
+        free(certp);
+      }
+    }
+    CFRelease(server_certs);
+  }
+#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
+}
+#endif /* !CURL_DISABLE_VERBOSE_STRINGS */
+
+static CURLcode
+darwinssl_connect_step3(struct connectdata *conn,
+                        int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  /* There is no step 3!
+   * Well, okay, if verbose mode is on, let's print the details of the
+   * server certificates. */
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  if(data->set.verbose)
+    show_verbose_server_cert(conn, sockindex);
+#endif
+
+  connssl->connecting_state = ssl_connect_done;
+  return CURLE_OK;
+}
+
+static Curl_recv darwinssl_recv;
+static Curl_send darwinssl_send;
+
+static CURLcode
+darwinssl_connect_common(struct connectdata *conn,
+                         int sockindex,
+                         bool nonblocking,
+                         bool *done)
+{
+  CURLcode result;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  curl_socket_t sockfd = conn->sock[sockindex];
+  long timeout_ms;
+  int what;
+
+  /* check if the connection has already been established */
+  if(ssl_connection_complete == connssl->state) {
+    *done = TRUE;
+    return CURLE_OK;
+  }
+
+  if(ssl_connect_1 == connssl->connecting_state) {
+    /* Find out how much more time we're allowed */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    result = darwinssl_connect_step1(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  while(ssl_connect_2 == connssl->connecting_state ||
+        ssl_connect_2_reading == connssl->connecting_state ||
+        ssl_connect_2_writing == connssl->connecting_state) {
+
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    /* if ssl is expecting something, check if it's available. */
+    if(connssl->connecting_state == ssl_connect_2_reading ||
+       connssl->connecting_state == ssl_connect_2_writing) {
+
+      curl_socket_t writefd = ssl_connect_2_writing ==
+      connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+      curl_socket_t readfd = ssl_connect_2_reading ==
+      connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+      what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
+                               nonblocking?0:timeout_ms);
+      if(what < 0) {
+        /* fatal error */
+        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      else if(0 == what) {
+        if(nonblocking) {
+          *done = FALSE;
+          return CURLE_OK;
+        }
+        else {
+          /* timeout */
+          failf(data, "SSL connection timeout");
+          return CURLE_OPERATION_TIMEDOUT;
+        }
+      }
+      /* socket is readable or writable */
+    }
+
+    /* Run transaction, and return to the caller if it failed or if this
+     * connection is done nonblocking and this loop would execute again. This
+     * permits the owner of a multi handle to abort a connection attempt
+     * before step2 has completed while ensuring that a client using select()
+     * or epoll() will always have a valid fdset to wait on.
+     */
+    result = darwinssl_connect_step2(conn, sockindex);
+    if(result || (nonblocking &&
+                  (ssl_connect_2 == connssl->connecting_state ||
+                   ssl_connect_2_reading == connssl->connecting_state ||
+                   ssl_connect_2_writing == connssl->connecting_state)))
+      return result;
+
+  } /* repeat step2 until all transactions are done. */
+
+
+  if(ssl_connect_3 == connssl->connecting_state) {
+    result = darwinssl_connect_step3(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  if(ssl_connect_done == connssl->connecting_state) {
+    connssl->state = ssl_connection_complete;
+    conn->recv[sockindex] = darwinssl_recv;
+    conn->send[sockindex] = darwinssl_send;
+    *done = TRUE;
+  }
+  else
+    *done = FALSE;
+
+  /* Reset our connect state machine */
+  connssl->connecting_state = ssl_connect_1;
+
+  return CURLE_OK;
+}
+
+static CURLcode Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
+                                                   int sockindex, bool *done)
+{
+  return darwinssl_connect_common(conn, sockindex, TRUE, done);
+}
+
+static CURLcode Curl_darwinssl_connect(struct connectdata *conn, int sockindex)
+{
+  CURLcode result;
+  bool done = FALSE;
+
+  result = darwinssl_connect_common(conn, sockindex, FALSE, &done);
+
+  if(result)
+    return result;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+static void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  if(BACKEND->ssl_ctx) {
+    (void)SSLClose(BACKEND->ssl_ctx);
+#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
+    if(SSLCreateContext != NULL)
+      CFRelease(BACKEND->ssl_ctx);
+#if CURL_SUPPORT_MAC_10_8
+    else
+      (void)SSLDisposeContext(BACKEND->ssl_ctx);
+#endif  /* CURL_SUPPORT_MAC_10_8 */
+#else
+    (void)SSLDisposeContext(BACKEND->ssl_ctx);
+#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
+    BACKEND->ssl_ctx = NULL;
+  }
+  BACKEND->ssl_sockfd = 0;
+}
+
+static int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct Curl_easy *data = conn->data;
+  ssize_t nread;
+  int what;
+  int rc;
+  char buf[120];
+
+  if(!BACKEND->ssl_ctx)
+    return 0;
+
+  if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
+    return 0;
+
+  Curl_darwinssl_close(conn, sockindex);
+
+  rc = 0;
+
+  what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
+
+  for(;;) {
+    if(what < 0) {
+      /* anything that gets here is fatally bad */
+      failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+      rc = -1;
+      break;
+    }
+
+    if(!what) {                                /* timeout */
+      failf(data, "SSL shutdown timeout");
+      break;
+    }
+
+    /* Something to read, let's do it and hope that it is the close
+     notify alert from the server. No way to SSL_Read now, so use read(). */
+
+    nread = read(conn->sock[sockindex], buf, sizeof(buf));
+
+    if(nread < 0) {
+      failf(data, "read: %s", strerror(errno));
+      rc = -1;
+    }
+
+    if(nread <= 0)
+      break;
+
+    what = SOCKET_READABLE(conn->sock[sockindex], 0);
+  }
+
+  return rc;
+}
+
+static void Curl_darwinssl_session_free(void *ptr)
+{
+  /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
+     cached session ID inside the Security framework. There is a private
+     function that does this, but I don't want to have to explain to you why I
+     got your application rejected from the App Store due to the use of a
+     private API, so the best we can do is free up our own char array that we
+     created way back in darwinssl_connect_step1... */
+  Curl_safefree(ptr);
+}
+
+static size_t Curl_darwinssl_version(char *buffer, size_t size)
+{
+  return snprintf(buffer, size, "SecureTransport");
+}
+
+/*
+ * This function uses SSLGetSessionState to determine connection status.
+ *
+ * Return codes:
+ *     1 means the connection is still in place
+ *     0 means the connection has been closed
+ *    -1 means the connection status is unknown
+ */
+static int Curl_darwinssl_check_cxn(struct connectdata *conn)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
+  OSStatus err;
+  SSLSessionState state;
+
+  if(BACKEND->ssl_ctx) {
+    err = SSLGetSessionState(BACKEND->ssl_ctx, &state);
+    if(err == noErr)
+      return state == kSSLConnected || state == kSSLHandshake;
+    return -1;
+  }
+  return 0;
+}
+
+static bool Curl_darwinssl_data_pending(const struct connectdata *conn,
+                                        int connindex)
+{
+  const struct ssl_connect_data *connssl = &conn->ssl[connindex];
+  OSStatus err;
+  size_t buffer;
+
+  if(BACKEND->ssl_ctx) {  /* SSL is in use */
+    err = SSLGetBufferedReadSize(BACKEND->ssl_ctx, &buffer);
+    if(err == noErr)
+      return buffer > 0UL;
+    return false;
+  }
+  else
+    return false;
+}
+
+static CURLcode Curl_darwinssl_random(struct Curl_easy *data UNUSED_PARAM,
+                                      unsigned char *entropy, size_t length)
+{
+  /* arc4random_buf() isn't available on cats older than Lion, so let's
+     do this manually for the benefit of the older cats. */
+  size_t i;
+  u_int32_t random_number = 0;
+
+  (void)data;
+
+  for(i = 0 ; i < length ; i++) {
+    if(i % sizeof(u_int32_t) == 0)
+      random_number = arc4random();
+    entropy[i] = random_number & 0xFF;
+    random_number >>= 8;
+  }
+  i = random_number = 0;
+  return CURLE_OK;
+}
+
+static CURLcode Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
+                                      size_t tmplen,
+                                      unsigned char *md5sum, /* output */
+                                      size_t md5len)
+{
+  (void)md5len;
+  (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
+  return CURLE_OK;
+}
+
+static void Curl_darwinssl_sha256sum(const unsigned char *tmp, /* input */
+                                     size_t tmplen,
+                                     unsigned char *sha256sum, /* output */
+                                     size_t sha256len)
+{
+  assert(sha256len >= CURL_SHA256_DIGEST_LENGTH);
+  (void)CC_SHA256(tmp, (CC_LONG)tmplen, sha256sum);
+}
+
+static bool Curl_darwinssl_false_start(void)
+{
+#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
+  if(SSLSetSessionOption != NULL)
+    return TRUE;
+#endif
+  return FALSE;
+}
+
+static ssize_t darwinssl_send(struct connectdata *conn,
+                              int sockindex,
+                              const void *mem,
+                              size_t len,
+                              CURLcode *curlcode)
+{
+  /*struct Curl_easy *data = conn->data;*/
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  size_t processed = 0UL;
+  OSStatus err;
+
+  /* The SSLWrite() function works a little differently than expected. The
+     fourth argument (processed) is currently documented in Apple's
+     documentation as: "On return, the length, in bytes, of the data actually
+     written."
+
+     Now, one could interpret that as "written to the socket," but actually,
+     it returns the amount of data that was written to a buffer internal to
+     the SSLContextRef instead. So it's possible for SSLWrite() to return
+     errSSLWouldBlock and a number of bytes "written" because those bytes were
+     encrypted and written to a buffer, not to the socket.
+
+     So if this happens, then we need to keep calling SSLWrite() over and
+     over again with no new data until it quits returning errSSLWouldBlock. */
+
+  /* Do we have buffered data to write from the last time we were called? */
+  if(BACKEND->ssl_write_buffered_length) {
+    /* Write the buffered data: */
+    err = SSLWrite(BACKEND->ssl_ctx, NULL, 0UL, &processed);
+    switch(err) {
+      case noErr:
+        /* processed is always going to be 0 because we didn't write to
+           the buffer, so return how much was written to the socket */
+        processed = BACKEND->ssl_write_buffered_length;
+        BACKEND->ssl_write_buffered_length = 0UL;
+        break;
+      case errSSLWouldBlock: /* argh, try again */
+        *curlcode = CURLE_AGAIN;
+        return -1L;
+      default:
+        failf(conn->data, "SSLWrite() returned error %d", err);
+        *curlcode = CURLE_SEND_ERROR;
+        return -1L;
+    }
+  }
+  else {
+    /* We've got new data to write: */
+    err = SSLWrite(BACKEND->ssl_ctx, mem, len, &processed);
+    if(err != noErr) {
+      switch(err) {
+        case errSSLWouldBlock:
+          /* Data was buffered but not sent, we have to tell the caller
+             to try sending again, and remember how much was buffered */
+          BACKEND->ssl_write_buffered_length = len;
+          *curlcode = CURLE_AGAIN;
+          return -1L;
+        default:
+          failf(conn->data, "SSLWrite() returned error %d", err);
+          *curlcode = CURLE_SEND_ERROR;
+          return -1L;
+      }
+    }
+  }
+  return (ssize_t)processed;
+}
+
+static ssize_t darwinssl_recv(struct connectdata *conn,
+                              int num,
+                              char *buf,
+                              size_t buffersize,
+                              CURLcode *curlcode)
+{
+  /*struct Curl_easy *data = conn->data;*/
+  struct ssl_connect_data *connssl = &conn->ssl[num];
+  size_t processed = 0UL;
+  OSStatus err = SSLRead(BACKEND->ssl_ctx, buf, buffersize, &processed);
+
+  if(err != noErr) {
+    switch(err) {
+      case errSSLWouldBlock:  /* return how much we read (if anything) */
+        if(processed)
+          return (ssize_t)processed;
+        *curlcode = CURLE_AGAIN;
+        return -1L;
+        break;
+
+      /* errSSLClosedGraceful - server gracefully shut down the SSL session
+         errSSLClosedNoNotify - server hung up on us instead of sending a
+           closure alert notice, read() is returning 0
+         Either way, inform the caller that the server disconnected. */
+      case errSSLClosedGraceful:
+      case errSSLClosedNoNotify:
+        *curlcode = CURLE_OK;
+        return -1L;
+        break;
+
+      default:
+        failf(conn->data, "SSLRead() return error %d", err);
+        *curlcode = CURLE_RECV_ERROR;
+        return -1L;
+        break;
+    }
+  }
+  return (ssize_t)processed;
+}
+
+static void *Curl_darwinssl_get_internals(struct ssl_connect_data *connssl,
+                                          CURLINFO info UNUSED_PARAM)
+{
+  (void)info;
+  return BACKEND->ssl_ctx;
+}
+
+const struct Curl_ssl Curl_ssl_darwinssl = {
+  { CURLSSLBACKEND_DARWINSSL, "darwinssl" }, /* info */
+
+  0, /* have_ca_path */
+  0, /* have_certinfo */
+#ifdef DARWIN_SSL_PINNEDPUBKEY
+  1, /* have_pinnedpubkey */
+#else
+  0, /* have_pinnedpubkey */
+#endif /* DARWIN_SSL_PINNEDPUBKEY */
+  0, /* have_ssl_ctx */
+  0, /* support_https_proxy */
+
+  sizeof(struct ssl_backend_data),
+
+  Curl_none_init,                     /* init */
+  Curl_none_cleanup,                  /* cleanup */
+  Curl_darwinssl_version,             /* version */
+  Curl_darwinssl_check_cxn,           /* check_cxn */
+  Curl_darwinssl_shutdown,            /* shutdown */
+  Curl_darwinssl_data_pending,        /* data_pending */
+  Curl_darwinssl_random,              /* random */
+  Curl_none_cert_status_request,      /* cert_status_request */
+  Curl_darwinssl_connect,             /* connect */
+  Curl_darwinssl_connect_nonblocking, /* connect_nonblocking */
+  Curl_darwinssl_get_internals,       /* get_internals */
+  Curl_darwinssl_close,               /* close_one */
+  Curl_none_close_all,                /* close_all */
+  Curl_darwinssl_session_free,        /* session_free */
+  Curl_none_set_engine,               /* set_engine */
+  Curl_none_set_engine_default,       /* set_engine_default */
+  Curl_none_engines_list,             /* engines_list */
+  Curl_darwinssl_false_start,         /* false_start */
+  Curl_darwinssl_md5sum,              /* md5sum */
+  Curl_darwinssl_sha256sum            /* sha256sum */
+};
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+#endif /* USE_DARWINSSL */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/darwinssl.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/darwinssl.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/darwinssl.h	(revision 331)
@@ -0,0 +1,32 @@
+#ifndef HEADER_CURL_DARWINSSL_H
+#define HEADER_CURL_DARWINSSL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
+ * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_DARWINSSL
+
+extern const struct Curl_ssl Curl_ssl_darwinssl;
+
+#endif /* USE_DARWINSSL */
+#endif /* HEADER_CURL_DARWINSSL_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/gskit.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/gskit.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/gskit.c	(revision 331)
@@ -0,0 +1,1390 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_GSKIT
+
+#include <gskssl.h>
+#include <qsoasync.h>
+
+/* Some symbols are undefined/unsupported on OS400 versions < V7R1. */
+#ifndef GSK_SSL_EXTN_SERVERNAME_REQUEST
+#define GSK_SSL_EXTN_SERVERNAME_REQUEST         230
+#endif
+
+#ifndef GSK_TLSV10_CIPHER_SPECS
+#define GSK_TLSV10_CIPHER_SPECS                 236
+#endif
+
+#ifndef GSK_TLSV11_CIPHER_SPECS
+#define GSK_TLSV11_CIPHER_SPECS                 237
+#endif
+
+#ifndef GSK_TLSV12_CIPHER_SPECS
+#define GSK_TLSV12_CIPHER_SPECS                 238
+#endif
+
+#ifndef GSK_PROTOCOL_TLSV11
+#define GSK_PROTOCOL_TLSV11                     437
+#endif
+
+#ifndef GSK_PROTOCOL_TLSV12
+#define GSK_PROTOCOL_TLSV12                     438
+#endif
+
+#ifndef GSK_FALSE
+#define GSK_FALSE                               0
+#endif
+
+#ifndef GSK_TRUE
+#define GSK_TRUE                                1
+#endif
+
+
+#ifdef HAVE_LIMITS_H
+#  include <limits.h>
+#endif
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "sendf.h"
+#include "gskit.h"
+#include "vtls.h"
+#include "connect.h" /* for the connect timeout */
+#include "select.h"
+#include "strcase.h"
+#include "x509asn1.h"
+#include "curl_printf.h"
+
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+
+/* Directions. */
+#define SOS_READ        0x01
+#define SOS_WRITE       0x02
+
+/* SSL version flags. */
+#define CURL_GSKPROTO_SSLV2     0
+#define CURL_GSKPROTO_SSLV2_MASK        (1 << CURL_GSKPROTO_SSLV2)
+#define CURL_GSKPROTO_SSLV3     1
+#define CURL_GSKPROTO_SSLV3_MASK        (1 << CURL_GSKPROTO_SSLV3)
+#define CURL_GSKPROTO_TLSV10    2
+#define CURL_GSKPROTO_TLSV10_MASK        (1 << CURL_GSKPROTO_TLSV10)
+#define CURL_GSKPROTO_TLSV11    3
+#define CURL_GSKPROTO_TLSV11_MASK        (1 << CURL_GSKPROTO_TLSV11)
+#define CURL_GSKPROTO_TLSV12    4
+#define CURL_GSKPROTO_TLSV12_MASK        (1 << CURL_GSKPROTO_TLSV12)
+#define CURL_GSKPROTO_LAST      5
+
+struct ssl_backend_data {
+  gsk_handle handle;
+  int iocport;
+  int localfd;
+  int remotefd;
+};
+
+#define BACKEND connssl->backend
+
+/* Supported ciphers. */
+typedef struct {
+  const char *name;            /* Cipher name. */
+  const char *gsktoken;        /* Corresponding token for GSKit String. */
+  unsigned int versions;       /* SSL version flags. */
+}  gskit_cipher;
+
+static const gskit_cipher  ciphertable[] = {
+  { "null-md5",         "01",
+      CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+      CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
+  { "null-sha",         "02",
+      CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+      CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
+  { "exp-rc4-md5",      "03",
+      CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK },
+  { "rc4-md5",          "04",
+      CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+      CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
+  { "rc4-sha",          "05",
+      CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+      CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
+  { "exp-rc2-cbc-md5",  "06",
+      CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK },
+  { "exp-des-cbc-sha",  "09",
+      CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+      CURL_GSKPROTO_TLSV11_MASK },
+  { "des-cbc3-sha",     "0A",
+      CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK |
+      CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK },
+  { "aes128-sha",       "2F",
+      CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
+      CURL_GSKPROTO_TLSV12_MASK },
+  { "aes256-sha",       "35",
+      CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK |
+      CURL_GSKPROTO_TLSV12_MASK },
+  { "null-sha256",      "3B",   CURL_GSKPROTO_TLSV12_MASK },
+  { "aes128-sha256",    "3C",   CURL_GSKPROTO_TLSV12_MASK },
+  { "aes256-sha256",    "3D",   CURL_GSKPROTO_TLSV12_MASK },
+  { "aes128-gcm-sha256",
+                        "9C",   CURL_GSKPROTO_TLSV12_MASK },
+  { "aes256-gcm-sha384",
+                        "9D",   CURL_GSKPROTO_TLSV12_MASK },
+  { "rc4-md5",          "1",    CURL_GSKPROTO_SSLV2_MASK },
+  { "exp-rc4-md5",      "2",    CURL_GSKPROTO_SSLV2_MASK },
+  { "rc2-md5",          "3",    CURL_GSKPROTO_SSLV2_MASK },
+  { "exp-rc2-md5",      "4",    CURL_GSKPROTO_SSLV2_MASK },
+  { "des-cbc-md5",      "6",    CURL_GSKPROTO_SSLV2_MASK },
+  { "des-cbc3-md5",     "7",    CURL_GSKPROTO_SSLV2_MASK },
+  { (const char *) NULL, (const char *) NULL, 0       }
+};
+
+
+static bool is_separator(char c)
+{
+  /* Return whether character is a cipher list separator. */
+  switch(c) {
+  case ' ':
+  case '\t':
+  case ':':
+  case ',':
+  case ';':
+    return true;
+  }
+  return false;
+}
+
+
+static CURLcode gskit_status(struct Curl_easy *data, int rc,
+                             const char *procname, CURLcode defcode)
+{
+  /* Process GSKit status and map it to a CURLcode. */
+  switch(rc) {
+  case GSK_OK:
+  case GSK_OS400_ASYNCHRONOUS_SOC_INIT:
+    return CURLE_OK;
+  case GSK_KEYRING_OPEN_ERROR:
+  case GSK_OS400_ERROR_NO_ACCESS:
+    return CURLE_SSL_CACERT_BADFILE;
+  case GSK_INSUFFICIENT_STORAGE:
+    return CURLE_OUT_OF_MEMORY;
+  case GSK_ERROR_BAD_V2_CIPHER:
+  case GSK_ERROR_BAD_V3_CIPHER:
+  case GSK_ERROR_NO_CIPHERS:
+    return CURLE_SSL_CIPHER;
+  case GSK_OS400_ERROR_NOT_TRUSTED_ROOT:
+  case GSK_ERROR_CERT_VALIDATION:
+    return CURLE_PEER_FAILED_VERIFICATION;
+  case GSK_OS400_ERROR_TIMED_OUT:
+    return CURLE_OPERATION_TIMEDOUT;
+  case GSK_WOULD_BLOCK:
+    return CURLE_AGAIN;
+  case GSK_OS400_ERROR_NOT_REGISTERED:
+    break;
+  case GSK_ERROR_IO:
+    switch(errno) {
+    case ENOMEM:
+      return CURLE_OUT_OF_MEMORY;
+    default:
+      failf(data, "%s I/O error: %s", procname, strerror(errno));
+      break;
+    }
+    break;
+  default:
+    failf(data, "%s: %s", procname, gsk_strerror(rc));
+    break;
+  }
+  return defcode;
+}
+
+
+static CURLcode set_enum(struct Curl_easy *data, gsk_handle h,
+                GSK_ENUM_ID id, GSK_ENUM_VALUE value, bool unsupported_ok)
+{
+  int rc = gsk_attribute_set_enum(h, id, value);
+
+  switch(rc) {
+  case GSK_OK:
+    return CURLE_OK;
+  case GSK_ERROR_IO:
+    failf(data, "gsk_attribute_set_enum() I/O error: %s", strerror(errno));
+    break;
+  case GSK_ATTRIBUTE_INVALID_ID:
+    if(unsupported_ok)
+      return CURLE_UNSUPPORTED_PROTOCOL;
+  default:
+    failf(data, "gsk_attribute_set_enum(): %s", gsk_strerror(rc));
+    break;
+  }
+  return CURLE_SSL_CONNECT_ERROR;
+}
+
+
+static CURLcode set_buffer(struct Curl_easy *data, gsk_handle h,
+                        GSK_BUF_ID id, const char *buffer, bool unsupported_ok)
+{
+  int rc = gsk_attribute_set_buffer(h, id, buffer, 0);
+
+  switch(rc) {
+  case GSK_OK:
+    return CURLE_OK;
+  case GSK_ERROR_IO:
+    failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno));
+    break;
+  case GSK_ATTRIBUTE_INVALID_ID:
+    if(unsupported_ok)
+      return CURLE_UNSUPPORTED_PROTOCOL;
+  default:
+    failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc));
+    break;
+  }
+  return CURLE_SSL_CONNECT_ERROR;
+}
+
+
+static CURLcode set_numeric(struct Curl_easy *data,
+                            gsk_handle h, GSK_NUM_ID id, int value)
+{
+  int rc = gsk_attribute_set_numeric_value(h, id, value);
+
+  switch(rc) {
+  case GSK_OK:
+    return CURLE_OK;
+  case GSK_ERROR_IO:
+    failf(data, "gsk_attribute_set_numeric_value() I/O error: %s",
+          strerror(errno));
+    break;
+  default:
+    failf(data, "gsk_attribute_set_numeric_value(): %s", gsk_strerror(rc));
+    break;
+  }
+  return CURLE_SSL_CONNECT_ERROR;
+}
+
+
+static CURLcode set_callback(struct Curl_easy *data,
+                             gsk_handle h, GSK_CALLBACK_ID id, void *info)
+{
+  int rc = gsk_attribute_set_callback(h, id, info);
+
+  switch(rc) {
+  case GSK_OK:
+    return CURLE_OK;
+  case GSK_ERROR_IO:
+    failf(data, "gsk_attribute_set_callback() I/O error: %s", strerror(errno));
+    break;
+  default:
+    failf(data, "gsk_attribute_set_callback(): %s", gsk_strerror(rc));
+    break;
+  }
+  return CURLE_SSL_CONNECT_ERROR;
+}
+
+
+static CURLcode set_ciphers(struct connectdata *conn,
+                                        gsk_handle h, unsigned int *protoflags)
+{
+  struct Curl_easy *data = conn->data;
+  const char *cipherlist = SSL_CONN_CONFIG(cipher_list);
+  const char *clp;
+  const gskit_cipher *ctp;
+  int i;
+  int l;
+  bool unsupported;
+  CURLcode result;
+  struct {
+    char *buf;
+    char *ptr;
+  } ciphers[CURL_GSKPROTO_LAST];
+
+  /* Compile cipher list into GSKit-compatible cipher lists. */
+
+  if(!cipherlist)
+    return CURLE_OK;
+  while(is_separator(*cipherlist))     /* Skip initial separators. */
+    cipherlist++;
+  if(!*cipherlist)
+    return CURLE_OK;
+
+  /* We allocate GSKit buffers of the same size as the input string: since
+     GSKit tokens are always shorter than their cipher names, allocated buffers
+     will always be large enough to accommodate the result. */
+  l = strlen(cipherlist) + 1;
+  memset((char *) ciphers, 0, sizeof ciphers);
+  for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
+    ciphers[i].buf = malloc(l);
+    if(!ciphers[i].buf) {
+      while(i--)
+        free(ciphers[i].buf);
+      return CURLE_OUT_OF_MEMORY;
+    }
+    ciphers[i].ptr = ciphers[i].buf;
+    *ciphers[i].ptr = '\0';
+  }
+
+  /* Process each cipher in input string. */
+  unsupported = FALSE;
+  result = CURLE_OK;
+  for(;;) {
+    for(clp = cipherlist; *cipherlist && !is_separator(*cipherlist);)
+      cipherlist++;
+    l = cipherlist - clp;
+    if(!l)
+      break;
+    /* Search the cipher in our table. */
+    for(ctp = ciphertable; ctp->name; ctp++)
+      if(strncasecompare(ctp->name, clp, l) && !ctp->name[l])
+        break;
+    if(!ctp->name) {
+      failf(data, "Unknown cipher %.*s", l, clp);
+      result = CURLE_SSL_CIPHER;
+    }
+    else {
+      unsupported |= !(ctp->versions & (CURL_GSKPROTO_SSLV2_MASK |
+                        CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK));
+      for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
+        if(ctp->versions & (1 << i)) {
+          strcpy(ciphers[i].ptr, ctp->gsktoken);
+          ciphers[i].ptr += strlen(ctp->gsktoken);
+        }
+      }
+    }
+
+   /* Advance to next cipher name or end of string. */
+    while(is_separator(*cipherlist))
+      cipherlist++;
+  }
+
+  /* Disable protocols with empty cipher lists. */
+  for(i = 0; i < CURL_GSKPROTO_LAST; i++) {
+    if(!(*protoflags & (1 << i)) || !ciphers[i].buf[0]) {
+      *protoflags &= ~(1 << i);
+      ciphers[i].buf[0] = '\0';
+    }
+  }
+
+  /* Try to set-up TLSv1.1 and TLSv2.1 ciphers. */
+  if(*protoflags & CURL_GSKPROTO_TLSV11_MASK) {
+    result = set_buffer(data, h, GSK_TLSV11_CIPHER_SPECS,
+                        ciphers[CURL_GSKPROTO_TLSV11].buf, TRUE);
+    if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+      result = CURLE_OK;
+      if(unsupported) {
+        failf(data, "TLSv1.1-only ciphers are not yet supported");
+        result = CURLE_SSL_CIPHER;
+      }
+    }
+  }
+  if(!result && (*protoflags & CURL_GSKPROTO_TLSV12_MASK)) {
+    result = set_buffer(data, h, GSK_TLSV12_CIPHER_SPECS,
+                        ciphers[CURL_GSKPROTO_TLSV12].buf, TRUE);
+    if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+      result = CURLE_OK;
+      if(unsupported) {
+        failf(data, "TLSv1.2-only ciphers are not yet supported");
+        result = CURLE_SSL_CIPHER;
+      }
+    }
+  }
+
+  /* Try to set-up TLSv1.0 ciphers. If not successful, concatenate them to
+     the SSLv3 ciphers. OS/400 prior to version 7.1 will understand it. */
+  if(!result && (*protoflags & CURL_GSKPROTO_TLSV10_MASK)) {
+    result = set_buffer(data, h, GSK_TLSV10_CIPHER_SPECS,
+                        ciphers[CURL_GSKPROTO_TLSV10].buf, TRUE);
+    if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+      result = CURLE_OK;
+      strcpy(ciphers[CURL_GSKPROTO_SSLV3].ptr,
+             ciphers[CURL_GSKPROTO_TLSV10].ptr);
+    }
+  }
+
+  /* Set-up other ciphers. */
+  if(!result && (*protoflags & CURL_GSKPROTO_SSLV3_MASK))
+    result = set_buffer(data, h, GSK_V3_CIPHER_SPECS,
+                        ciphers[CURL_GSKPROTO_SSLV3].buf, FALSE);
+  if(!result && (*protoflags & CURL_GSKPROTO_SSLV2_MASK))
+    result = set_buffer(data, h, GSK_V2_CIPHER_SPECS,
+                        ciphers[CURL_GSKPROTO_SSLV2].buf, FALSE);
+
+  /* Clean-up. */
+  for(i = 0; i < CURL_GSKPROTO_LAST; i++)
+    free(ciphers[i].buf);
+
+  return result;
+}
+
+
+static int Curl_gskit_init(void)
+{
+  /* No initialisation needed. */
+
+  return 1;
+}
+
+
+static void Curl_gskit_cleanup(void)
+{
+  /* Nothing to do. */
+}
+
+
+static CURLcode init_environment(struct Curl_easy *data,
+                                 gsk_handle *envir, const char *appid,
+                                 const char *file, const char *label,
+                                 const char *password)
+{
+  int rc;
+  CURLcode result;
+  gsk_handle h;
+
+  /* Creates the GSKit environment. */
+
+  rc = gsk_environment_open(&h);
+  switch(rc) {
+  case GSK_OK:
+    break;
+  case GSK_INSUFFICIENT_STORAGE:
+    return CURLE_OUT_OF_MEMORY;
+  default:
+    failf(data, "gsk_environment_open(): %s", gsk_strerror(rc));
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  result = set_enum(data, h, GSK_SESSION_TYPE, GSK_CLIENT_SESSION, FALSE);
+  if(!result && appid)
+    result = set_buffer(data, h, GSK_OS400_APPLICATION_ID, appid, FALSE);
+  if(!result && file)
+    result = set_buffer(data, h, GSK_KEYRING_FILE, file, FALSE);
+  if(!result && label)
+    result = set_buffer(data, h, GSK_KEYRING_LABEL, label, FALSE);
+  if(!result && password)
+    result = set_buffer(data, h, GSK_KEYRING_PW, password, FALSE);
+
+  if(!result) {
+    /* Locate CAs, Client certificate and key according to our settings.
+       Note: this call may be blocking for some tenths of seconds. */
+    result = gskit_status(data, gsk_environment_init(h),
+                          "gsk_environment_init()", CURLE_SSL_CERTPROBLEM);
+    if(!result) {
+      *envir = h;
+      return result;
+    }
+  }
+  /* Error: rollback. */
+  gsk_environment_close(&h);
+  return result;
+}
+
+
+static void cancel_async_handshake(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  Qso_OverlappedIO_t cstat;
+
+  if(QsoCancelOperation(conn->sock[sockindex], 0) > 0)
+    QsoWaitForIOCompletion(BACKEND->iocport, &cstat, (struct timeval *) NULL);
+}
+
+
+static void close_async_handshake(struct ssl_connect_data *connssl)
+{
+  QsoDestroyIOCompletionPort(BACKEND->iocport);
+  BACKEND->iocport = -1;
+}
+
+/* SSL over SSL
+ * Problems:
+ * 1) GSKit can only perform SSL on an AF_INET or AF_INET6 stream socket. To
+ *    pipe an SSL stream into another, it is therefore needed to have a pair
+ *    of such communicating sockets and handle the pipelining explicitly.
+ * 2) OS/400 socketpair() is only implemented for domain AF_UNIX, thus cannot
+ *    be used to produce the pipeline.
+ * The solution is to simulate socketpair() for AF_INET with low-level API
+ *    listen(), bind() and connect().
+ */
+
+static int
+inetsocketpair(int sv[2])
+{
+  int lfd;      /* Listening socket. */
+  int sfd;      /* Server socket. */
+  int cfd;      /* Client socket. */
+  int len;
+  struct sockaddr_in addr1;
+  struct sockaddr_in addr2;
+
+  /* Create listening socket on a local dynamic port. */
+  lfd = socket(AF_INET, SOCK_STREAM, 0);
+  if(lfd < 0)
+    return -1;
+  memset((char *) &addr1, 0, sizeof addr1);
+  addr1.sin_family = AF_INET;
+  addr1.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+  addr1.sin_port = 0;
+  if(bind(lfd, (struct sockaddr *) &addr1, sizeof addr1) ||
+     listen(lfd, 2) < 0) {
+    close(lfd);
+    return -1;
+  }
+
+  /* Get the allocated port. */
+  len = sizeof addr1;
+  if(getsockname(lfd, (struct sockaddr *) &addr1, &len) < 0) {
+    close(lfd);
+    return -1;
+  }
+
+  /* Create the client socket. */
+  cfd = socket(AF_INET, SOCK_STREAM, 0);
+  if(cfd < 0) {
+    close(lfd);
+    return -1;
+  }
+
+  /* Request unblocking connection to the listening socket. */
+  curlx_nonblock(cfd, TRUE);
+  if(connect(cfd, (struct sockaddr *) &addr1, sizeof addr1) < 0 &&
+     errno != EINPROGRESS) {
+    close(lfd);
+    close(cfd);
+    return -1;
+  }
+
+  /* Get the client dynamic port for intrusion check below. */
+  len = sizeof addr2;
+  if(getsockname(cfd, (struct sockaddr *) &addr2, &len) < 0) {
+    close(lfd);
+    close(cfd);
+    return -1;
+  }
+
+  /* Accept the incoming connection and get the server socket. */
+  curlx_nonblock(lfd, TRUE);
+  for(;;) {
+    len = sizeof addr1;
+    sfd = accept(lfd, (struct sockaddr *) &addr1, &len);
+    if(sfd < 0) {
+      close(lfd);
+      close(cfd);
+      return -1;
+    }
+
+    /* Check for possible intrusion from an external process. */
+    if(addr1.sin_addr.s_addr == addr2.sin_addr.s_addr &&
+       addr1.sin_port == addr2.sin_port)
+      break;
+
+    /* Intrusion: reject incoming connection. */
+    close(sfd);
+  }
+
+  /* Done, return sockets and succeed. */
+  close(lfd);
+  curlx_nonblock(cfd, FALSE);
+  sv[0] = cfd;
+  sv[1] = sfd;
+  return 0;
+}
+
+static int pipe_ssloverssl(struct connectdata *conn, int sockindex,
+                           int directions)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_connect_data *connproxyssl = &conn->proxy_ssl[sockindex];
+  fd_set fds_read;
+  fd_set fds_write;
+  int n;
+  int m;
+  int i;
+  int ret = 0;
+  struct timeval tv = {0, 0};
+  char buf[CURL_MAX_WRITE_SIZE];
+
+  if(!connssl->use || !connproxyssl->use)
+    return 0;   /* No SSL over SSL: OK. */
+
+  FD_ZERO(&fds_read);
+  FD_ZERO(&fds_write);
+  n = -1;
+  if(directions & SOS_READ) {
+    FD_SET(BACKEND->remotefd, &fds_write);
+    n = BACKEND->remotefd;
+  }
+  if(directions & SOS_WRITE) {
+    FD_SET(BACKEND->remotefd, &fds_read);
+    n = BACKEND->remotefd;
+    FD_SET(conn->sock[sockindex], &fds_write);
+    if(n < conn->sock[sockindex])
+      n = conn->sock[sockindex];
+  }
+  i = select(n + 1, &fds_read, &fds_write, NULL, &tv);
+  if(i < 0)
+    return -1;  /* Select error. */
+
+  if(FD_ISSET(BACKEND->remotefd, &fds_write)) {
+    /* Try getting data from HTTPS proxy and pipe it upstream. */
+    n = 0;
+    i = gsk_secure_soc_read(connproxyssl->backend->handle,
+                            buf, sizeof buf, &n);
+    switch(i) {
+    case GSK_OK:
+      if(n) {
+        i = write(BACKEND->remotefd, buf, n);
+        if(i < 0)
+          return -1;
+        ret = 1;
+      }
+      break;
+    case GSK_OS400_ERROR_TIMED_OUT:
+    case GSK_WOULD_BLOCK:
+      break;
+    default:
+      return -1;
+    }
+  }
+
+  if(FD_ISSET(BACKEND->remotefd, &fds_read) &&
+     FD_ISSET(conn->sock[sockindex], &fds_write)) {
+    /* Pipe data to HTTPS proxy. */
+    n = read(BACKEND->remotefd, buf, sizeof buf);
+    if(n < 0)
+      return -1;
+    if(n) {
+      i = gsk_secure_soc_write(connproxyssl->backend->handle, buf, n, &m);
+      if(i != GSK_OK || n != m)
+        return -1;
+      ret = 1;
+    }
+  }
+
+  return ret;  /* OK */
+}
+
+
+static void close_one(struct ssl_connect_data *connssl,
+                      struct connectdata *conn, int sockindex)
+{
+  if(BACKEND->handle) {
+    gskit_status(conn->data, gsk_secure_soc_close(&BACKEND->handle),
+              "gsk_secure_soc_close()", 0);
+    /* Last chance to drain output. */
+    while(pipe_ssloverssl(conn, sockindex, SOS_WRITE) > 0)
+      ;
+    BACKEND->handle = (gsk_handle) NULL;
+    if(BACKEND->localfd >= 0) {
+      close(BACKEND->localfd);
+      BACKEND->localfd = -1;
+    }
+    if(BACKEND->remotefd >= 0) {
+      close(BACKEND->remotefd);
+      BACKEND->remotefd = -1;
+    }
+  }
+  if(BACKEND->iocport >= 0)
+    close_async_handshake(connssl);
+}
+
+
+static ssize_t gskit_send(struct connectdata *conn, int sockindex,
+                           const void *mem, size_t len, CURLcode *curlcode)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct Curl_easy *data = conn->data;
+  CURLcode cc = CURLE_SEND_ERROR;
+  int written;
+
+  if(pipe_ssloverssl(conn, sockindex, SOS_WRITE) >= 0) {
+    cc = gskit_status(data,
+                      gsk_secure_soc_write(BACKEND->handle,
+                                           (char *) mem, (int) len, &written),
+                      "gsk_secure_soc_write()", CURLE_SEND_ERROR);
+    if(cc == CURLE_OK)
+      if(pipe_ssloverssl(conn, sockindex, SOS_WRITE) < 0)
+        cc = CURLE_SEND_ERROR;
+  }
+  if(cc != CURLE_OK) {
+    *curlcode = cc;
+    written = -1;
+  }
+  return (ssize_t) written; /* number of bytes */
+}
+
+
+static ssize_t gskit_recv(struct connectdata *conn, int num, char *buf,
+                           size_t buffersize, CURLcode *curlcode)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[num];
+  struct Curl_easy *data = conn->data;
+  int buffsize;
+  int nread;
+  CURLcode cc = CURLE_RECV_ERROR;
+
+  if(pipe_ssloverssl(conn, num, SOS_READ) >= 0) {
+    buffsize = buffersize > (size_t) INT_MAX? INT_MAX: (int) buffersize;
+    cc = gskit_status(data, gsk_secure_soc_read(BACKEND->handle,
+                                                buf, buffsize, &nread),
+                      "gsk_secure_soc_read()", CURLE_RECV_ERROR);
+  }
+  switch(cc) {
+  case CURLE_OK:
+    break;
+  case CURLE_OPERATION_TIMEDOUT:
+    cc = CURLE_AGAIN;
+  default:
+    *curlcode = cc;
+    nread = -1;
+    break;
+  }
+  return (ssize_t) nread;
+}
+
+static CURLcode
+set_ssl_version_min_max(unsigned int *protoflags, struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  long ssl_version = SSL_CONN_CONFIG(version);
+  long ssl_version_max = SSL_CONN_CONFIG(version_max);
+  long i = ssl_version;
+  switch(ssl_version_max) {
+    case CURL_SSLVERSION_MAX_NONE:
+      ssl_version_max = ssl_version;
+      break;
+    case CURL_SSLVERSION_MAX_DEFAULT:
+      ssl_version_max = CURL_SSLVERSION_TLSv1_2;
+      break;
+  }
+  for(; i <= (ssl_version_max >> 16); ++i) {
+    switch(i) {
+      case CURL_SSLVERSION_TLSv1_0:
+        *protoflags |= CURL_GSKPROTO_TLSV10_MASK;
+        break;
+      case CURL_SSLVERSION_TLSv1_1:
+        *protoflags |= CURL_GSKPROTO_TLSV11_MASK;
+        break;
+      case CURL_SSLVERSION_TLSv1_2:
+        *protoflags |= CURL_GSKPROTO_TLSV11_MASK;
+        break;
+      case CURL_SSLVERSION_TLSv1_3:
+        failf(data, "GSKit: TLS 1.3 is not yet supported");
+        return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  gsk_handle envir;
+  CURLcode result;
+  int rc;
+  const char * const keyringfile = SSL_CONN_CONFIG(CAfile);
+  const char * const keyringpwd = SSL_SET_OPTION(key_passwd);
+  const char * const keyringlabel = SSL_SET_OPTION(cert);
+  const long int ssl_version = SSL_CONN_CONFIG(version);
+  const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
+  const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name:
+    conn->host.name;
+  const char *sni;
+  unsigned int protoflags = 0;
+  long timeout;
+  Qso_OverlappedIO_t commarea;
+  int sockpair[2];
+  static const int sobufsize = CURL_MAX_WRITE_SIZE;
+
+  /* Create SSL environment, start (preferably asynchronous) handshake. */
+
+  BACKEND->handle = (gsk_handle) NULL;
+  BACKEND->iocport = -1;
+  BACKEND->localfd = -1;
+  BACKEND->remotefd = -1;
+
+  /* GSKit supports two ways of specifying an SSL context: either by
+   *  application identifier (that should have been defined at the system
+   *  level) or by keyring file, password and certificate label.
+   * Local certificate name (CURLOPT_SSLCERT) is used to hold either the
+   *  application identifier of the certificate label.
+   * Key password (CURLOPT_KEYPASSWD) holds the keyring password.
+   * It is not possible to have different keyrings for the CAs and the
+   *  local certificate. We thus use the CA file (CURLOPT_CAINFO) to identify
+   *  the keyring file.
+   * If no key password is given and the keyring is the system keyring,
+   *  application identifier mode is tried first, as recommended in IBM doc.
+   */
+
+  envir = (gsk_handle) NULL;
+
+  if(keyringlabel && *keyringlabel && !keyringpwd &&
+      !strcmp(keyringfile, CURL_CA_BUNDLE)) {
+    /* Try application identifier mode. */
+    init_environment(data, &envir, keyringlabel, (const char *) NULL,
+                     (const char *) NULL, (const char *) NULL);
+  }
+
+  if(!envir) {
+    /* Use keyring mode. */
+    result = init_environment(data, &envir, (const char *) NULL,
+                              keyringfile, keyringlabel, keyringpwd);
+    if(result)
+      return result;
+  }
+
+  /* Create secure session. */
+  result = gskit_status(data, gsk_secure_soc_open(envir, &BACKEND->handle),
+                        "gsk_secure_soc_open()", CURLE_SSL_CONNECT_ERROR);
+  gsk_environment_close(&envir);
+  if(result)
+    return result;
+
+  /* Establish a pipelining socket pair for SSL over SSL. */
+  if(conn->proxy_ssl[sockindex].use) {
+    if(inetsocketpair(sockpair))
+      return CURLE_SSL_CONNECT_ERROR;
+    BACKEND->localfd = sockpair[0];
+    BACKEND->remotefd = sockpair[1];
+    setsockopt(BACKEND->localfd, SOL_SOCKET, SO_RCVBUF,
+               (void *) sobufsize, sizeof sobufsize);
+    setsockopt(BACKEND->remotefd, SOL_SOCKET, SO_RCVBUF,
+               (void *) sobufsize, sizeof sobufsize);
+    setsockopt(BACKEND->localfd, SOL_SOCKET, SO_SNDBUF,
+               (void *) sobufsize, sizeof sobufsize);
+    setsockopt(BACKEND->remotefd, SOL_SOCKET, SO_SNDBUF,
+               (void *) sobufsize, sizeof sobufsize);
+    curlx_nonblock(BACKEND->localfd, TRUE);
+    curlx_nonblock(BACKEND->remotefd, TRUE);
+  }
+
+  /* Determine which SSL/TLS version should be enabled. */
+  sni = hostname;
+  switch(ssl_version) {
+  case CURL_SSLVERSION_SSLv2:
+    protoflags = CURL_GSKPROTO_SSLV2_MASK;
+    sni = NULL;
+    break;
+  case CURL_SSLVERSION_SSLv3:
+    protoflags = CURL_GSKPROTO_SSLV3_MASK;
+    sni = NULL;
+    break;
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+    protoflags = CURL_GSKPROTO_TLSV10_MASK |
+                 CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK;
+    break;
+  case CURL_SSLVERSION_TLSv1_0:
+  case CURL_SSLVERSION_TLSv1_1:
+  case CURL_SSLVERSION_TLSv1_2:
+  case CURL_SSLVERSION_TLSv1_3:
+    result = set_ssl_version_min_max(&protoflags, conn);
+    if(result != CURLE_OK)
+      return result;
+    break;
+  default:
+    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  /* Process SNI. Ignore if not supported (on OS400 < V7R1). */
+  if(sni) {
+    result = set_buffer(data, BACKEND->handle,
+                        GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, TRUE);
+    if(result == CURLE_UNSUPPORTED_PROTOCOL)
+      result = CURLE_OK;
+  }
+
+  /* Set session parameters. */
+  if(!result) {
+    /* Compute the handshake timeout. Since GSKit granularity is 1 second,
+       we round up the required value. */
+    timeout = Curl_timeleft(data, NULL, TRUE);
+    if(timeout < 0)
+      result = CURLE_OPERATION_TIMEDOUT;
+    else
+      result = set_numeric(data, BACKEND->handle, GSK_HANDSHAKE_TIMEOUT,
+                           (timeout + 999) / 1000);
+  }
+  if(!result)
+    result = set_numeric(data, BACKEND->handle, GSK_OS400_READ_TIMEOUT, 1);
+  if(!result)
+    result = set_numeric(data, BACKEND->handle, GSK_FD, BACKEND->localfd >= 0?
+                         BACKEND->localfd: conn->sock[sockindex]);
+  if(!result)
+    result = set_ciphers(conn, BACKEND->handle, &protoflags);
+  if(!protoflags) {
+    failf(data, "No SSL protocol/cipher combination enabled");
+    result = CURLE_SSL_CIPHER;
+  }
+  if(!result)
+    result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_SSLV2,
+                      (protoflags & CURL_GSKPROTO_SSLV2_MASK)?
+                      GSK_PROTOCOL_SSLV2_ON: GSK_PROTOCOL_SSLV2_OFF, FALSE);
+  if(!result)
+    result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_SSLV3,
+                      (protoflags & CURL_GSKPROTO_SSLV3_MASK)?
+                      GSK_PROTOCOL_SSLV3_ON: GSK_PROTOCOL_SSLV3_OFF, FALSE);
+  if(!result)
+    result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_TLSV1,
+                      (protoflags & CURL_GSKPROTO_TLSV10_MASK)?
+                      GSK_PROTOCOL_TLSV1_ON: GSK_PROTOCOL_TLSV1_OFF, FALSE);
+  if(!result) {
+    result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_TLSV11,
+                      (protoflags & CURL_GSKPROTO_TLSV11_MASK)?
+                      GSK_TRUE: GSK_FALSE, TRUE);
+    if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+      result = CURLE_OK;
+      if(protoflags == CURL_GSKPROTO_TLSV11_MASK) {
+        failf(data, "TLS 1.1 not yet supported");
+        result = CURLE_SSL_CIPHER;
+      }
+    }
+  }
+  if(!result) {
+    result = set_enum(data, BACKEND->handle, GSK_PROTOCOL_TLSV12,
+                      (protoflags & CURL_GSKPROTO_TLSV12_MASK)?
+                      GSK_TRUE: GSK_FALSE, TRUE);
+    if(result == CURLE_UNSUPPORTED_PROTOCOL) {
+      result = CURLE_OK;
+      if(protoflags == CURL_GSKPROTO_TLSV12_MASK) {
+        failf(data, "TLS 1.2 not yet supported");
+        result = CURLE_SSL_CIPHER;
+      }
+    }
+  }
+  if(!result)
+    result = set_enum(data, BACKEND->handle, GSK_SERVER_AUTH_TYPE,
+                      verifypeer? GSK_SERVER_AUTH_FULL:
+                      GSK_SERVER_AUTH_PASSTHRU, FALSE);
+
+  if(!result) {
+    /* Start handshake. Try asynchronous first. */
+    memset(&commarea, 0, sizeof commarea);
+    BACKEND->iocport = QsoCreateIOCompletionPort();
+    if(BACKEND->iocport != -1) {
+      result = gskit_status(data,
+                            gsk_secure_soc_startInit(BACKEND->handle,
+                                                     BACKEND->iocport,
+                                                     &commarea),
+                            "gsk_secure_soc_startInit()",
+                            CURLE_SSL_CONNECT_ERROR);
+      if(!result) {
+        connssl->connecting_state = ssl_connect_2;
+        return CURLE_OK;
+      }
+      else
+        close_async_handshake(connssl);
+    }
+    else if(errno != ENOBUFS)
+      result = gskit_status(data, GSK_ERROR_IO,
+                            "QsoCreateIOCompletionPort()", 0);
+    else if(conn->proxy_ssl[sockindex].use) {
+      /* Cannot pipeline while handshaking synchronously. */
+      result = CURLE_SSL_CONNECT_ERROR;
+    }
+    else {
+      /* No more completion port available. Use synchronous IO. */
+      result = gskit_status(data, gsk_secure_soc_init(BACKEND->handle),
+                            "gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR);
+      if(!result) {
+        connssl->connecting_state = ssl_connect_3;
+        return CURLE_OK;
+      }
+    }
+  }
+
+  /* Error: rollback. */
+  close_one(connssl, conn, sockindex);
+  return result;
+}
+
+
+static CURLcode gskit_connect_step2(struct connectdata *conn, int sockindex,
+                                    bool nonblocking)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  Qso_OverlappedIO_t cstat;
+  long timeout_ms;
+  struct timeval stmv;
+  CURLcode result;
+
+  /* Poll or wait for end of SSL asynchronous handshake. */
+
+  for(;;) {
+    timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE);
+    if(timeout_ms < 0)
+      timeout_ms = 0;
+    stmv.tv_sec = timeout_ms / 1000;
+    stmv.tv_usec = (timeout_ms - stmv.tv_sec * 1000) * 1000;
+    switch(QsoWaitForIOCompletion(BACKEND->iocport, &cstat, &stmv)) {
+    case 1:             /* Operation complete. */
+      break;
+    case -1:            /* An error occurred: handshake still in progress. */
+      if(errno == EINTR) {
+        if(nonblocking)
+          return CURLE_OK;
+        continue;       /* Retry. */
+      }
+      if(errno != ETIME) {
+        failf(data, "QsoWaitForIOCompletion() I/O error: %s", strerror(errno));
+        cancel_async_handshake(conn, sockindex);
+        close_async_handshake(connssl);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      /* FALL INTO... */
+    case 0:             /* Handshake in progress, timeout occurred. */
+      if(nonblocking)
+        return CURLE_OK;
+      cancel_async_handshake(conn, sockindex);
+      close_async_handshake(connssl);
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+    break;
+  }
+  result = gskit_status(data, cstat.returnValue, "SSL handshake",
+                        CURLE_SSL_CONNECT_ERROR);
+  if(!result)
+    connssl->connecting_state = ssl_connect_3;
+  close_async_handshake(connssl);
+  return result;
+}
+
+
+static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  const gsk_cert_data_elem *cdev;
+  int cdec;
+  const gsk_cert_data_elem *p;
+  const char *cert = (const char *) NULL;
+  const char *certend;
+  const char *ptr;
+  int i;
+  CURLcode result;
+
+  /* SSL handshake done: gather certificate info and verify host. */
+
+  if(gskit_status(data, gsk_attribute_get_cert_info(BACKEND->handle,
+                                                    GSK_PARTNER_CERT_INFO,
+                                                    &cdev, &cdec),
+                  "gsk_attribute_get_cert_info()", CURLE_SSL_CONNECT_ERROR) ==
+     CURLE_OK) {
+    infof(data, "Server certificate:\n");
+    p = cdev;
+    for(i = 0; i++ < cdec; p++)
+      switch(p->cert_data_id) {
+      case CERT_BODY_DER:
+        cert = p->cert_data_p;
+        certend = cert + cdev->cert_data_l;
+        break;
+      case CERT_DN_PRINTABLE:
+        infof(data, "\t subject: %.*s\n", p->cert_data_l, p->cert_data_p);
+        break;
+      case CERT_ISSUER_DN_PRINTABLE:
+        infof(data, "\t issuer: %.*s\n", p->cert_data_l, p->cert_data_p);
+        break;
+      case CERT_VALID_FROM:
+        infof(data, "\t start date: %.*s\n", p->cert_data_l, p->cert_data_p);
+        break;
+      case CERT_VALID_TO:
+        infof(data, "\t expire date: %.*s\n", p->cert_data_l, p->cert_data_p);
+        break;
+    }
+  }
+
+  /* Verify host. */
+  result = Curl_verifyhost(conn, cert, certend);
+  if(result)
+    return result;
+
+  /* The only place GSKit can get the whole CA chain is a validation
+     callback where no user data pointer is available. Therefore it's not
+     possible to copy this chain into our structures for CAINFO.
+     However the server certificate may be available, thus we can return
+     info about it. */
+  if(data->set.ssl.certinfo) {
+    result = Curl_ssl_init_certinfo(data, 1);
+    if(result)
+      return result;
+
+    if(cert) {
+      result = Curl_extract_certinfo(conn, 0, cert, certend);
+      if(result)
+        return result;
+    }
+  }
+
+  /* Check pinned public key. */
+  ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
+                         data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+  if(!result && ptr) {
+    curl_X509certificate x509;
+    curl_asn1Element *p;
+
+    if(Curl_parseX509(&x509, cert, certend))
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    p = &x509.subjectPublicKeyInfo;
+    result = Curl_pin_peer_pubkey(data, ptr, p->header, p->end - p->header);
+    if(result) {
+      failf(data, "SSL: public key does not match pinned public key!");
+      return result;
+    }
+  }
+
+  connssl->connecting_state = ssl_connect_done;
+  return CURLE_OK;
+}
+
+
+static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex,
+                                     bool nonblocking, bool *done)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  long timeout_ms;
+  Qso_OverlappedIO_t cstat;
+  CURLcode result = CURLE_OK;
+
+  *done = connssl->state == ssl_connection_complete;
+  if(*done)
+    return CURLE_OK;
+
+  /* Step 1: create session, start handshake. */
+  if(connssl->connecting_state == ssl_connect_1) {
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      result = CURLE_OPERATION_TIMEDOUT;
+    }
+    else
+      result = gskit_connect_step1(conn, sockindex);
+  }
+
+  /* Handle handshake pipelining. */
+  if(!result)
+    if(pipe_ssloverssl(conn, sockindex, SOS_READ | SOS_WRITE) < 0)
+      result = CURLE_SSL_CONNECT_ERROR;
+
+  /* Step 2: check if handshake is over. */
+  if(!result && connssl->connecting_state == ssl_connect_2) {
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      result = CURLE_OPERATION_TIMEDOUT;
+    }
+    else
+      result = gskit_connect_step2(conn, sockindex, nonblocking);
+  }
+
+  /* Handle handshake pipelining. */
+  if(!result)
+    if(pipe_ssloverssl(conn, sockindex, SOS_READ | SOS_WRITE) < 0)
+      result = CURLE_SSL_CONNECT_ERROR;
+
+  /* Step 3: gather certificate info, verify host. */
+  if(!result && connssl->connecting_state == ssl_connect_3)
+    result = gskit_connect_step3(conn, sockindex);
+
+  if(result)
+    close_one(connssl, conn, sockindex);
+  else if(connssl->connecting_state == ssl_connect_done) {
+    connssl->state = ssl_connection_complete;
+    connssl->connecting_state = ssl_connect_1;
+    conn->recv[sockindex] = gskit_recv;
+    conn->send[sockindex] = gskit_send;
+    *done = TRUE;
+  }
+
+  return result;
+}
+
+
+static CURLcode Curl_gskit_connect_nonblocking(struct connectdata *conn,
+                                               int sockindex, bool *done)
+{
+  CURLcode result;
+
+  result = gskit_connect_common(conn, sockindex, TRUE, done);
+  if(*done || result)
+    conn->ssl[sockindex].connecting_state = ssl_connect_1;
+  return result;
+}
+
+
+static CURLcode Curl_gskit_connect(struct connectdata *conn, int sockindex)
+{
+  CURLcode result;
+  bool done;
+
+  conn->ssl[sockindex].connecting_state = ssl_connect_1;
+  result = gskit_connect_common(conn, sockindex, FALSE, &done);
+  if(result)
+    return result;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+
+static void Curl_gskit_close(struct connectdata *conn, int sockindex)
+{
+  close_one(&conn->ssl[sockindex], conn, sockindex);
+  close_one(&conn->proxy_ssl[sockindex], conn, sockindex);
+}
+
+
+static int Curl_gskit_shutdown(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct Curl_easy *data = conn->data;
+  ssize_t nread;
+  int what;
+  int rc;
+  char buf[120];
+
+  if(!BACKEND->handle)
+    return 0;
+
+  if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
+    return 0;
+
+  close_one(connssl, conn, sockindex);
+  rc = 0;
+  what = SOCKET_READABLE(conn->sock[sockindex],
+                         SSL_SHUTDOWN_TIMEOUT);
+
+  for(;;) {
+    if(what < 0) {
+      /* anything that gets here is fatally bad */
+      failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+      rc = -1;
+      break;
+    }
+
+    if(!what) {                                /* timeout */
+      failf(data, "SSL shutdown timeout");
+      break;
+    }
+
+    /* Something to read, let's do it and hope that it is the close
+       notify alert from the server. No way to gsk_secure_soc_read() now, so
+       use read(). */
+
+    nread = read(conn->sock[sockindex], buf, sizeof(buf));
+
+    if(nread < 0) {
+      failf(data, "read: %s", strerror(errno));
+      rc = -1;
+    }
+
+    if(nread <= 0)
+      break;
+
+    what = SOCKET_READABLE(conn->sock[sockindex], 0);
+  }
+
+  return rc;
+}
+
+
+static size_t Curl_gskit_version(char *buffer, size_t size)
+{
+  strncpy(buffer, "GSKit", size);
+  return strlen(buffer);
+}
+
+
+static int Curl_gskit_check_cxn(struct connectdata *cxn)
+{
+  struct ssl_connect_data *connssl = &cxn->ssl[FIRSTSOCKET];
+  int err;
+  int errlen;
+
+  /* The only thing that can be tested here is at the socket level. */
+
+  if(!BACKEND->handle)
+    return 0; /* connection has been closed */
+
+  err = 0;
+  errlen = sizeof err;
+
+  if(getsockopt(cxn->sock[FIRSTSOCKET], SOL_SOCKET, SO_ERROR,
+                 (unsigned char *) &err, &errlen) ||
+     errlen != sizeof err || err)
+    return 0; /* connection has been closed */
+
+  return -1;  /* connection status unknown */
+}
+
+static void *Curl_gskit_get_internals(struct ssl_connect_data *connssl,
+                                      CURLINFO info UNUSED_PARAM)
+{
+  (void)info;
+  return BACKEND->handle;
+}
+
+const struct Curl_ssl Curl_ssl_gskit = {
+  { CURLSSLBACKEND_GSKIT, "gskit" }, /* info */
+
+  0, /* have_ca_path */
+  1, /* have_certinfo */
+  0, /* have_pinnedpubkey */
+  0, /* have_ssl_ctx */
+  /* TODO: convert to 1 and fix test #1014 (if need) */
+  0, /* support_https_proxy */
+
+  sizeof(struct ssl_backend_data),
+
+  Curl_gskit_init,                /* init */
+  Curl_gskit_cleanup,             /* cleanup */
+  Curl_gskit_version,             /* version */
+  Curl_gskit_check_cxn,           /* check_cxn */
+  Curl_gskit_shutdown,            /* shutdown */
+  Curl_none_data_pending,         /* data_pending */
+  Curl_none_random,               /* random */
+  Curl_none_cert_status_request,  /* cert_status_request */
+  Curl_gskit_connect,             /* connect */
+  Curl_gskit_connect_nonblocking, /* connect_nonblocking */
+  Curl_gskit_get_internals,       /* get_internals */
+  Curl_gskit_close,               /* close_one */
+  Curl_none_close_all,            /* close_all */
+  /* No session handling for GSKit */
+  Curl_none_session_free,         /* session_free */
+  Curl_none_set_engine,           /* set_engine */
+  Curl_none_set_engine_default,   /* set_engine_default */
+  Curl_none_engines_list,         /* engines_list */
+  Curl_none_false_start,          /* false_start */
+  Curl_none_md5sum,               /* md5sum */
+  NULL                            /* sha256sum */
+};
+
+#endif /* USE_GSKIT */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/gskit.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/gskit.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/gskit.h	(revision 331)
@@ -0,0 +1,38 @@
+#ifndef HEADER_CURL_GSKIT_H
+#define HEADER_CURL_GSKIT_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+/*
+ * This header should only be needed to get included by vtls.c and gskit.c
+ */
+
+#include "urldata.h"
+
+#ifdef USE_GSKIT
+
+extern const struct Curl_ssl Curl_ssl_gskit;
+
+#endif /* USE_GSKIT */
+
+#endif /* HEADER_CURL_GSKIT_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/gtls.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/gtls.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/gtls.c	(revision 331)
@@ -0,0 +1,1841 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all GnuTLS-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ *
+ * Note: don't use the GnuTLS' *_t variable type names in this source code,
+ * since they were not present in 1.0.X.
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_GNUTLS
+
+#include <gnutls/abstract.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+
+#ifdef USE_GNUTLS_NETTLE
+#include <gnutls/crypto.h>
+#include <nettle/md5.h>
+#include <nettle/sha2.h>
+#else
+#include <gcrypt.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "gtls.h"
+#include "vtls.h"
+#include "parsedate.h"
+#include "connect.h" /* for the connect timeout */
+#include "select.h"
+#include "strcase.h"
+#include "warnless.h"
+#include "x509asn1.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+#ifndef GNUTLS_POINTER_TO_SOCKET_CAST
+#define GNUTLS_POINTER_TO_SOCKET_CAST(p) \
+  ((curl_socket_t) ((char *)(p) - (char *)NULL))
+#endif
+#ifndef GNUTLS_SOCKET_TO_POINTER_CAST
+#define GNUTLS_SOCKET_TO_POINTER_CAST(s) \
+  ((void *) ((char *)NULL + (s)))
+#endif
+
+/* Enable GnuTLS debugging by defining GTLSDEBUG */
+/*#define GTLSDEBUG */
+
+#ifdef GTLSDEBUG
+static void tls_log_func(int level, const char *str)
+{
+    fprintf(stderr, "|<%d>| %s", level, str);
+}
+#endif
+static bool gtls_inited = FALSE;
+
+#if defined(GNUTLS_VERSION_NUMBER)
+#  if (GNUTLS_VERSION_NUMBER >= 0x020c00)
+#    undef gnutls_transport_set_lowat
+#    define gnutls_transport_set_lowat(A,B) Curl_nop_stmt
+#    define USE_GNUTLS_PRIORITY_SET_DIRECT 1
+#  endif
+#  if (GNUTLS_VERSION_NUMBER >= 0x020c03)
+#    define GNUTLS_MAPS_WINSOCK_ERRORS 1
+#  endif
+
+#  if HAVE_GNUTLS_ALPN_SET_PROTOCOLS
+#    define HAS_ALPN
+#  endif
+
+#  if HAVE_GNUTLS_OCSP_REQ_INIT
+#    define HAS_OCSP
+#  endif
+
+#  if (GNUTLS_VERSION_NUMBER >= 0x030306)
+#    define HAS_CAPATH
+#  endif
+#endif
+
+#ifdef HAS_OCSP
+# include <gnutls/ocsp.h>
+#endif
+
+struct ssl_backend_data {
+  gnutls_session_t session;
+  gnutls_certificate_credentials_t cred;
+#ifdef USE_TLS_SRP
+  gnutls_srp_client_credentials_t srp_client_cred;
+#endif
+};
+
+#define BACKEND connssl->backend
+
+/*
+ * Custom push and pull callback functions used by GNU TLS to read and write
+ * to the socket.  These functions are simple wrappers to send() and recv()
+ * (although here using the sread/swrite macros as defined by
+ * curl_setup_once.h).
+ * We use custom functions rather than the GNU TLS defaults because it allows
+ * us to get specific about the fourth "flags" argument, and to use arbitrary
+ * private data with gnutls_transport_set_ptr if we wish.
+ *
+ * When these custom push and pull callbacks fail, GNU TLS checks its own
+ * session-specific error variable, and when not set also its own global
+ * errno variable, in order to take appropriate action. GNU TLS does not
+ * require that the transport is actually a socket. This implies that for
+ * Windows builds these callbacks should ideally set the session-specific
+ * error variable using function gnutls_transport_set_errno or as a last
+ * resort global errno variable using gnutls_transport_set_global_errno,
+ * with a transport agnostic error value. This implies that some winsock
+ * error translation must take place in these callbacks.
+ *
+ * Paragraph above applies to GNU TLS versions older than 2.12.3, since
+ * this version GNU TLS does its own internal winsock error translation
+ * using system_errno() function.
+ */
+
+#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
+#  define gtls_EINTR  4
+#  define gtls_EIO    5
+#  define gtls_EAGAIN 11
+static int gtls_mapped_sockerrno(void)
+{
+  switch(SOCKERRNO) {
+  case WSAEWOULDBLOCK:
+    return gtls_EAGAIN;
+  case WSAEINTR:
+    return gtls_EINTR;
+  default:
+    break;
+  }
+  return gtls_EIO;
+}
+#endif
+
+static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len)
+{
+  ssize_t ret = swrite(GNUTLS_POINTER_TO_SOCKET_CAST(s), buf, len);
+#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
+  if(ret < 0)
+    gnutls_transport_set_global_errno(gtls_mapped_sockerrno());
+#endif
+  return ret;
+}
+
+static ssize_t Curl_gtls_pull(void *s, void *buf, size_t len)
+{
+  ssize_t ret = sread(GNUTLS_POINTER_TO_SOCKET_CAST(s), buf, len);
+#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS)
+  if(ret < 0)
+    gnutls_transport_set_global_errno(gtls_mapped_sockerrno());
+#endif
+  return ret;
+}
+
+static ssize_t Curl_gtls_push_ssl(void *s, const void *buf, size_t len)
+{
+  return gnutls_record_send((gnutls_session_t) s, buf, len);
+}
+
+static ssize_t Curl_gtls_pull_ssl(void *s, void *buf, size_t len)
+{
+  return gnutls_record_recv((gnutls_session_t) s, buf, len);
+}
+
+/* Curl_gtls_init()
+ *
+ * Global GnuTLS init, called from Curl_ssl_init(). This calls functions that
+ * are not thread-safe and thus this function itself is not thread-safe and
+ * must only be called from within curl_global_init() to keep the thread
+ * situation under control!
+ */
+static int Curl_gtls_init(void)
+{
+  int ret = 1;
+  if(!gtls_inited) {
+    ret = gnutls_global_init()?0:1;
+#ifdef GTLSDEBUG
+    gnutls_global_set_log_function(tls_log_func);
+    gnutls_global_set_log_level(2);
+#endif
+    gtls_inited = TRUE;
+  }
+  return ret;
+}
+
+static void Curl_gtls_cleanup(void)
+{
+  if(gtls_inited) {
+    gnutls_global_deinit();
+    gtls_inited = FALSE;
+  }
+}
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+static void showtime(struct Curl_easy *data,
+                     const char *text,
+                     time_t stamp)
+{
+  struct tm buffer;
+  const struct tm *tm = &buffer;
+  char str[96];
+  CURLcode result = Curl_gmtime(stamp, &buffer);
+  if(result)
+    return;
+
+  snprintf(str,
+           sizeof(str),
+           "\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT",
+           text,
+           Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
+           tm->tm_mday,
+           Curl_month[tm->tm_mon],
+           tm->tm_year + 1900,
+           tm->tm_hour,
+           tm->tm_min,
+           tm->tm_sec);
+  infof(data, "%s\n", str);
+}
+#endif
+
+static gnutls_datum_t load_file(const char *file)
+{
+  FILE *f;
+  gnutls_datum_t loaded_file = { NULL, 0 };
+  long filelen;
+  void *ptr;
+
+  f = fopen(file, "rb");
+  if(!f)
+    return loaded_file;
+  if(fseek(f, 0, SEEK_END) != 0
+     || (filelen = ftell(f)) < 0
+     || fseek(f, 0, SEEK_SET) != 0
+     || !(ptr = malloc((size_t)filelen)))
+    goto out;
+  if(fread(ptr, 1, (size_t)filelen, f) < (size_t)filelen) {
+    free(ptr);
+    goto out;
+  }
+
+  loaded_file.data = ptr;
+  loaded_file.size = (unsigned int)filelen;
+out:
+  fclose(f);
+  return loaded_file;
+}
+
+static void unload_file(gnutls_datum_t data)
+{
+  free(data.data);
+}
+
+
+/* this function does a SSL/TLS (re-)handshake */
+static CURLcode handshake(struct connectdata *conn,
+                          int sockindex,
+                          bool duringconnect,
+                          bool nonblocking)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  gnutls_session_t session = BACKEND->session;
+  curl_socket_t sockfd = conn->sock[sockindex];
+  time_t timeout_ms;
+  int rc;
+  int what;
+
+  for(;;) {
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, duringconnect);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    /* if ssl is expecting something, check if it's available. */
+    if(connssl->connecting_state == ssl_connect_2_reading
+       || connssl->connecting_state == ssl_connect_2_writing) {
+
+      curl_socket_t writefd = ssl_connect_2_writing ==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+      curl_socket_t readfd = ssl_connect_2_reading ==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+      what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
+                               nonblocking?0:
+                               timeout_ms?timeout_ms:1000);
+      if(what < 0) {
+        /* fatal error */
+        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      else if(0 == what) {
+        if(nonblocking)
+          return CURLE_OK;
+        else if(timeout_ms) {
+          /* timeout */
+          failf(data, "SSL connection timeout at %ld", (long)timeout_ms);
+          return CURLE_OPERATION_TIMEDOUT;
+        }
+      }
+      /* socket is readable or writable */
+    }
+
+    rc = gnutls_handshake(session);
+
+    if((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)) {
+      connssl->connecting_state =
+        gnutls_record_get_direction(session)?
+        ssl_connect_2_writing:ssl_connect_2_reading;
+      continue;
+    }
+    else if((rc < 0) && !gnutls_error_is_fatal(rc)) {
+      const char *strerr = NULL;
+
+      if(rc == GNUTLS_E_WARNING_ALERT_RECEIVED) {
+        int alert = gnutls_alert_get(session);
+        strerr = gnutls_alert_get_name(alert);
+      }
+
+      if(strerr == NULL)
+        strerr = gnutls_strerror(rc);
+
+      infof(data, "gnutls_handshake() warning: %s\n", strerr);
+      continue;
+    }
+    else if(rc < 0) {
+      const char *strerr = NULL;
+
+      if(rc == GNUTLS_E_FATAL_ALERT_RECEIVED) {
+        int alert = gnutls_alert_get(session);
+        strerr = gnutls_alert_get_name(alert);
+      }
+
+      if(strerr == NULL)
+        strerr = gnutls_strerror(rc);
+
+      failf(data, "gnutls_handshake() failed: %s", strerr);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+
+    /* Reset our connect state machine */
+    connssl->connecting_state = ssl_connect_1;
+    return CURLE_OK;
+  }
+}
+
+static gnutls_x509_crt_fmt_t do_file_type(const char *type)
+{
+  if(!type || !type[0])
+    return GNUTLS_X509_FMT_PEM;
+  if(strcasecompare(type, "PEM"))
+    return GNUTLS_X509_FMT_PEM;
+  if(strcasecompare(type, "DER"))
+    return GNUTLS_X509_FMT_DER;
+  return -1;
+}
+
+#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
+static CURLcode
+set_ssl_version_min_max(int *list, size_t list_size, struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  long ssl_version = SSL_CONN_CONFIG(version);
+  long ssl_version_max = SSL_CONN_CONFIG(version_max);
+  long i = ssl_version;
+  long protocol_priority_idx = 0;
+
+  switch(ssl_version_max) {
+    case CURL_SSLVERSION_MAX_NONE:
+      ssl_version_max = ssl_version << 16;
+      break;
+    case CURL_SSLVERSION_MAX_DEFAULT:
+      ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+      break;
+  }
+
+  for(; i <= (ssl_version_max >> 16) &&
+        protocol_priority_idx < list_size; ++i) {
+    switch(i) {
+      case CURL_SSLVERSION_TLSv1_0:
+        protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_0;
+        break;
+      case CURL_SSLVERSION_TLSv1_1:
+        protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_1;
+        break;
+      case CURL_SSLVERSION_TLSv1_2:
+        protocol_priority[protocol_priority_idx++] = GNUTLS_TLS1_2;
+        break;
+      case CURL_SSLVERSION_TLSv1_3:
+        failf(data, "GnuTLS: TLS 1.3 is not yet supported");
+        return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+  return CURLE_OK;
+}
+#else
+#define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509"
+/* If GnuTLS was compiled without support for SRP it will error out if SRP is
+   requested in the priority string, so treat it specially
+ */
+#define GNUTLS_SRP "+SRP"
+
+static CURLcode
+set_ssl_version_min_max(const char **prioritylist, struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  long ssl_version = SSL_CONN_CONFIG(version);
+  long ssl_version_max = SSL_CONN_CONFIG(version_max);
+  if(ssl_version == CURL_SSLVERSION_TLSv1_3 ||
+     ssl_version_max == CURL_SSLVERSION_MAX_TLSv1_3) {
+    failf(data, "GnuTLS: TLS 1.3 is not yet supported");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+  if(ssl_version_max == CURL_SSLVERSION_MAX_NONE) {
+    ssl_version_max = ssl_version << 16;
+  }
+  switch(ssl_version | ssl_version_max) {
+    case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_0:
+      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+                      "+VERS-TLS1.0:" GNUTLS_SRP;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_1:
+      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+                      "+VERS-TLS1.0:+VERS-TLS1.1:" GNUTLS_SRP;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_TLSv1_2:
+    case CURL_SSLVERSION_TLSv1_0 | CURL_SSLVERSION_MAX_DEFAULT:
+      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+                      "+VERS-TLS1.0:+VERS-TLS1.1:+VERS-TLS1.2:" GNUTLS_SRP;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_1:
+      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+                      "+VERS-TLS1.1:" GNUTLS_SRP;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_TLSv1_2:
+    case CURL_SSLVERSION_TLSv1_1 | CURL_SSLVERSION_MAX_DEFAULT:
+      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+                      "+VERS-TLS1.1:+VERS-TLS1.2:" GNUTLS_SRP;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_2:
+    case CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_DEFAULT:
+      *prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:"
+                      "+VERS-TLS1.2:" GNUTLS_SRP;
+      return CURLE_OK;
+  }
+
+  failf(data, "GnuTLS: cannot set ssl protocol");
+  return CURLE_SSL_CONNECT_ERROR;
+}
+#endif
+
+static CURLcode
+gtls_connect_step1(struct connectdata *conn,
+                   int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  unsigned int init_flags;
+  gnutls_session_t session;
+  int rc;
+  bool sni = TRUE; /* default is SNI enabled */
+  void *transport_ptr = NULL;
+  gnutls_push_func gnutls_transport_push = NULL;
+  gnutls_pull_func gnutls_transport_pull = NULL;
+#ifdef ENABLE_IPV6
+  struct in6_addr addr;
+#else
+  struct in_addr addr;
+#endif
+#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
+  static const int cipher_priority[] = {
+  /* These two ciphers were added to GnuTLS as late as ver. 3.0.1,
+     but this code path is only ever used for ver. < 2.12.0.
+     GNUTLS_CIPHER_AES_128_GCM,
+     GNUTLS_CIPHER_AES_256_GCM,
+  */
+    GNUTLS_CIPHER_AES_128_CBC,
+    GNUTLS_CIPHER_AES_256_CBC,
+    GNUTLS_CIPHER_CAMELLIA_128_CBC,
+    GNUTLS_CIPHER_CAMELLIA_256_CBC,
+    GNUTLS_CIPHER_3DES_CBC,
+  };
+  static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 };
+  int protocol_priority[] = { 0, 0, 0, 0 };
+#else
+  const char *prioritylist;
+  const char *err = NULL;
+#endif
+
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+
+  if(connssl->state == ssl_connection_complete)
+    /* to make us tolerant against being called more than once for the
+       same connection */
+    return CURLE_OK;
+
+  if(!gtls_inited)
+    Curl_gtls_init();
+
+  if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
+    failf(data, "GnuTLS does not support SSLv2");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+  else if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv3)
+    sni = FALSE; /* SSLv3 has no SNI */
+
+  /* allocate a cred struct */
+  rc = gnutls_certificate_allocate_credentials(&BACKEND->cred);
+  if(rc != GNUTLS_E_SUCCESS) {
+    failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc));
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+#ifdef USE_TLS_SRP
+  if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
+    infof(data, "Using TLS-SRP username: %s\n", SSL_SET_OPTION(username));
+
+    rc = gnutls_srp_allocate_client_credentials(
+           &BACKEND->srp_client_cred);
+    if(rc != GNUTLS_E_SUCCESS) {
+      failf(data, "gnutls_srp_allocate_client_cred() failed: %s",
+            gnutls_strerror(rc));
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    rc = gnutls_srp_set_client_credentials(BACKEND->srp_client_cred,
+                                           SSL_SET_OPTION(username),
+                                           SSL_SET_OPTION(password));
+    if(rc != GNUTLS_E_SUCCESS) {
+      failf(data, "gnutls_srp_set_client_cred() failed: %s",
+            gnutls_strerror(rc));
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    }
+  }
+#endif
+
+  if(SSL_CONN_CONFIG(CAfile)) {
+    /* set the trusted CA cert bundle file */
+    gnutls_certificate_set_verify_flags(BACKEND->cred,
+                                        GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT);
+
+    rc = gnutls_certificate_set_x509_trust_file(BACKEND->cred,
+                                                SSL_CONN_CONFIG(CAfile),
+                                                GNUTLS_X509_FMT_PEM);
+    if(rc < 0) {
+      infof(data, "error reading ca cert file %s (%s)\n",
+            SSL_CONN_CONFIG(CAfile), gnutls_strerror(rc));
+      if(SSL_CONN_CONFIG(verifypeer))
+        return CURLE_SSL_CACERT_BADFILE;
+    }
+    else
+      infof(data, "found %d certificates in %s\n", rc,
+            SSL_CONN_CONFIG(CAfile));
+  }
+
+#ifdef HAS_CAPATH
+  if(SSL_CONN_CONFIG(CApath)) {
+    /* set the trusted CA cert directory */
+    rc = gnutls_certificate_set_x509_trust_dir(BACKEND->cred,
+                                               SSL_CONN_CONFIG(CApath),
+                                               GNUTLS_X509_FMT_PEM);
+    if(rc < 0) {
+      infof(data, "error reading ca cert file %s (%s)\n",
+            SSL_CONN_CONFIG(CApath), gnutls_strerror(rc));
+      if(SSL_CONN_CONFIG(verifypeer))
+        return CURLE_SSL_CACERT_BADFILE;
+    }
+    else
+      infof(data, "found %d certificates in %s\n",
+            rc, SSL_CONN_CONFIG(CApath));
+  }
+#endif
+
+#ifdef CURL_CA_FALLBACK
+  /* use system ca certificate store as fallback */
+  if(SSL_CONN_CONFIG(verifypeer) &&
+     !(SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(CApath))) {
+    gnutls_certificate_set_x509_system_trust(BACKEND->cred);
+  }
+#endif
+
+  if(SSL_SET_OPTION(CRLfile)) {
+    /* set the CRL list file */
+    rc = gnutls_certificate_set_x509_crl_file(BACKEND->cred,
+                                              SSL_SET_OPTION(CRLfile),
+                                              GNUTLS_X509_FMT_PEM);
+    if(rc < 0) {
+      failf(data, "error reading crl file %s (%s)",
+            SSL_SET_OPTION(CRLfile), gnutls_strerror(rc));
+      return CURLE_SSL_CRL_BADFILE;
+    }
+    else
+      infof(data, "found %d CRL in %s\n",
+            rc, SSL_SET_OPTION(CRLfile));
+  }
+
+  /* Initialize TLS session as a client */
+  init_flags = GNUTLS_CLIENT;
+
+#if defined(GNUTLS_NO_TICKETS)
+  /* Disable TLS session tickets */
+  init_flags |= GNUTLS_NO_TICKETS;
+#endif
+
+  rc = gnutls_init(&BACKEND->session, init_flags);
+  if(rc != GNUTLS_E_SUCCESS) {
+    failf(data, "gnutls_init() failed: %d", rc);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  /* convenient assign */
+  session = BACKEND->session;
+
+  if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) &&
+#ifdef ENABLE_IPV6
+     (0 == Curl_inet_pton(AF_INET6, hostname, &addr)) &&
+#endif
+     sni &&
+     (gnutls_server_name_set(session, GNUTLS_NAME_DNS, hostname,
+                             strlen(hostname)) < 0))
+    infof(data, "WARNING: failed to configure server name indication (SNI) "
+          "TLS extension\n");
+
+  /* Use default priorities */
+  rc = gnutls_set_default_priority(session);
+  if(rc != GNUTLS_E_SUCCESS)
+    return CURLE_SSL_CONNECT_ERROR;
+
+#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT
+  rc = gnutls_cipher_set_priority(session, cipher_priority);
+  if(rc != GNUTLS_E_SUCCESS)
+    return CURLE_SSL_CONNECT_ERROR;
+
+  /* Sets the priority on the certificate types supported by gnutls. Priority
+   is higher for types specified before others. After specifying the types
+   you want, you must append a 0. */
+  rc = gnutls_certificate_type_set_priority(session, cert_type_priority);
+  if(rc != GNUTLS_E_SUCCESS)
+    return CURLE_SSL_CONNECT_ERROR;
+
+  if(SSL_CONN_CONFIG(cipher_list) != NULL) {
+    failf(data, "can't pass a custom cipher list to older GnuTLS"
+          " versions");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  switch(SSL_CONN_CONFIG(version)) {
+    case CURL_SSLVERSION_SSLv3:
+      protocol_priority[0] = GNUTLS_SSL3;
+      break;
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1:
+      protocol_priority[0] = GNUTLS_TLS1_0;
+      protocol_priority[1] = GNUTLS_TLS1_1;
+      protocol_priority[2] = GNUTLS_TLS1_2;
+      break;
+    case CURL_SSLVERSION_TLSv1_0:
+    case CURL_SSLVERSION_TLSv1_1:
+    case CURL_SSLVERSION_TLSv1_2:
+    case CURL_SSLVERSION_TLSv1_3:
+      {
+        CURLcode result = set_ssl_version_min_max(protocol_priority,
+                sizeof(protocol_priority)/sizeof(protocol_priority[0]), conn);
+        if(result != CURLE_OK)
+          return result;
+        break;
+      }
+    case CURL_SSLVERSION_SSLv2:
+      failf(data, "GnuTLS does not support SSLv2");
+      return CURLE_SSL_CONNECT_ERROR;
+    default:
+      failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+      return CURLE_SSL_CONNECT_ERROR;
+  }
+  rc = gnutls_protocol_set_priority(session, protocol_priority);
+  if(rc != GNUTLS_E_SUCCESS) {
+    failf(data, "Did you pass a valid GnuTLS cipher list?");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+#else
+  /* Ensure +SRP comes at the *end* of all relevant strings so that it can be
+   * removed if a run-time error indicates that SRP is not supported by this
+   * GnuTLS version */
+  switch(SSL_CONN_CONFIG(version)) {
+    case CURL_SSLVERSION_SSLv3:
+      prioritylist = GNUTLS_CIPHERS ":-VERS-TLS-ALL:+VERS-SSL3.0";
+      sni = false;
+      break;
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1:
+      prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:" GNUTLS_SRP;
+      break;
+    case CURL_SSLVERSION_TLSv1_0:
+    case CURL_SSLVERSION_TLSv1_1:
+    case CURL_SSLVERSION_TLSv1_2:
+    case CURL_SSLVERSION_TLSv1_3:
+      {
+        CURLcode result = set_ssl_version_min_max(&prioritylist, conn);
+        if(result != CURLE_OK)
+          return result;
+        break;
+      }
+    case CURL_SSLVERSION_SSLv2:
+      failf(data, "GnuTLS does not support SSLv2");
+      return CURLE_SSL_CONNECT_ERROR;
+    default:
+      failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+      return CURLE_SSL_CONNECT_ERROR;
+  }
+  rc = gnutls_priority_set_direct(session, prioritylist, &err);
+  if((rc == GNUTLS_E_INVALID_REQUEST) && err) {
+    if(!strcmp(err, GNUTLS_SRP)) {
+      /* This GnuTLS was probably compiled without support for SRP.
+       * Note that fact and try again without it. */
+      int validprioritylen = curlx_uztosi(err - prioritylist);
+      char *prioritycopy = strdup(prioritylist);
+      if(!prioritycopy)
+        return CURLE_OUT_OF_MEMORY;
+
+      infof(data, "This GnuTLS does not support SRP\n");
+      if(validprioritylen)
+        /* Remove the :+SRP */
+        prioritycopy[validprioritylen - 1] = 0;
+      rc = gnutls_priority_set_direct(session, prioritycopy, &err);
+      free(prioritycopy);
+    }
+  }
+  if(rc != GNUTLS_E_SUCCESS) {
+    failf(data, "Error %d setting GnuTLS cipher list starting with %s",
+          rc, err);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+#endif
+
+#ifdef HAS_ALPN
+  if(conn->bits.tls_enable_alpn) {
+    int cur = 0;
+    gnutls_datum_t protocols[2];
+
+#ifdef USE_NGHTTP2
+    if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
+       (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) {
+      protocols[cur].data = (unsigned char *)NGHTTP2_PROTO_VERSION_ID;
+      protocols[cur].size = NGHTTP2_PROTO_VERSION_ID_LEN;
+      cur++;
+      infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+    }
+#endif
+
+    protocols[cur].data = (unsigned char *)ALPN_HTTP_1_1;
+    protocols[cur].size = ALPN_HTTP_1_1_LENGTH;
+    cur++;
+    infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
+
+    gnutls_alpn_set_protocols(session, protocols, cur, 0);
+  }
+#endif
+
+  if(SSL_SET_OPTION(cert)) {
+    if(SSL_SET_OPTION(key_passwd)) {
+#if HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2
+      const unsigned int supported_key_encryption_algorithms =
+        GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR |
+        GNUTLS_PKCS_USE_PKCS12_RC2_40 | GNUTLS_PKCS_USE_PBES2_3DES |
+        GNUTLS_PKCS_USE_PBES2_AES_128 | GNUTLS_PKCS_USE_PBES2_AES_192 |
+        GNUTLS_PKCS_USE_PBES2_AES_256;
+      rc = gnutls_certificate_set_x509_key_file2(
+           BACKEND->cred,
+           SSL_SET_OPTION(cert),
+           SSL_SET_OPTION(key) ?
+           SSL_SET_OPTION(key) : SSL_SET_OPTION(cert),
+           do_file_type(SSL_SET_OPTION(cert_type)),
+           SSL_SET_OPTION(key_passwd),
+           supported_key_encryption_algorithms);
+      if(rc != GNUTLS_E_SUCCESS) {
+        failf(data,
+              "error reading X.509 potentially-encrypted key file: %s",
+              gnutls_strerror(rc));
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+#else
+      failf(data, "gnutls lacks support for encrypted key files");
+      return CURLE_SSL_CONNECT_ERROR;
+#endif
+    }
+    else {
+      if(gnutls_certificate_set_x509_key_file(
+           BACKEND->cred,
+           SSL_SET_OPTION(cert),
+           SSL_SET_OPTION(key) ?
+           SSL_SET_OPTION(key) : SSL_SET_OPTION(cert),
+           do_file_type(SSL_SET_OPTION(cert_type)) ) !=
+         GNUTLS_E_SUCCESS) {
+        failf(data, "error reading X.509 key or certificate file");
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+    }
+  }
+
+#ifdef USE_TLS_SRP
+  /* put the credentials to the current session */
+  if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP) {
+    rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP,
+                                BACKEND->srp_client_cred);
+    if(rc != GNUTLS_E_SUCCESS) {
+      failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+  else
+#endif
+  {
+    rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
+                                BACKEND->cred);
+    if(rc != GNUTLS_E_SUCCESS) {
+      failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc));
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+
+  if(conn->proxy_ssl[sockindex].use) {
+    transport_ptr = conn->proxy_ssl[sockindex].backend->session;
+    gnutls_transport_push = Curl_gtls_push_ssl;
+    gnutls_transport_pull = Curl_gtls_pull_ssl;
+  }
+  else {
+    /* file descriptor for the socket */
+    transport_ptr = GNUTLS_SOCKET_TO_POINTER_CAST(conn->sock[sockindex]);
+    gnutls_transport_push = Curl_gtls_push;
+    gnutls_transport_pull = Curl_gtls_pull;
+  }
+
+  /* set the connection handle */
+  gnutls_transport_set_ptr(session, transport_ptr);
+
+  /* register callback functions to send and receive data. */
+  gnutls_transport_set_push_function(session, gnutls_transport_push);
+  gnutls_transport_set_pull_function(session, gnutls_transport_pull);
+
+  /* lowat must be set to zero when using custom push and pull functions. */
+  gnutls_transport_set_lowat(session, 0);
+
+#ifdef HAS_OCSP
+  if(SSL_CONN_CONFIG(verifystatus)) {
+    rc = gnutls_ocsp_status_request_enable_client(session, NULL, 0, NULL);
+    if(rc != GNUTLS_E_SUCCESS) {
+      failf(data, "gnutls_ocsp_status_request_enable_client() failed: %d", rc);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+#endif
+
+  /* This might be a reconnect, so we check for a session ID in the cache
+     to speed up things */
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    void *ssl_sessionid;
+    size_t ssl_idsize;
+
+    Curl_ssl_sessionid_lock(conn);
+    if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize, sockindex)) {
+      /* we got a session id, use it! */
+      gnutls_session_set_data(session, ssl_sessionid, ssl_idsize);
+
+      /* Informational message */
+      infof(data, "SSL re-using session ID\n");
+    }
+    Curl_ssl_sessionid_unlock(conn);
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
+                                    gnutls_x509_crt_t cert,
+                                    const char *pinnedpubkey)
+{
+  /* Scratch */
+  size_t len1 = 0, len2 = 0;
+  unsigned char *buff1 = NULL;
+
+  gnutls_pubkey_t key = NULL;
+
+  /* Result is returned to caller */
+  int ret = 0;
+  CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+
+  /* if a path wasn't specified, don't pin */
+  if(NULL == pinnedpubkey)
+    return CURLE_OK;
+
+  if(NULL == cert)
+    return result;
+
+  do {
+    /* Begin Gyrations to get the public key     */
+    gnutls_pubkey_init(&key);
+
+    ret = gnutls_pubkey_import_x509(key, cert, 0);
+    if(ret < 0)
+      break; /* failed */
+
+    ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, NULL, &len1);
+    if(ret != GNUTLS_E_SHORT_MEMORY_BUFFER || len1 == 0)
+      break; /* failed */
+
+    buff1 = malloc(len1);
+    if(NULL == buff1)
+      break; /* failed */
+
+    len2 = len1;
+
+    ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, buff1, &len2);
+    if(ret < 0 || len1 != len2)
+      break; /* failed */
+
+    /* End Gyrations */
+
+    /* The one good exit point */
+    result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1);
+  } while(0);
+
+  if(NULL != key)
+    gnutls_pubkey_deinit(key);
+
+  Curl_safefree(buff1);
+
+  return result;
+}
+
+static Curl_recv gtls_recv;
+static Curl_send gtls_send;
+
+static CURLcode
+gtls_connect_step3(struct connectdata *conn,
+                   int sockindex)
+{
+  unsigned int cert_list_size;
+  const gnutls_datum_t *chainp;
+  unsigned int verify_status = 0;
+  gnutls_x509_crt_t x509_cert, x509_issuer;
+  gnutls_datum_t issuerp;
+  char certbuf[256] = ""; /* big enough? */
+  size_t size;
+  time_t certclock;
+  const char *ptr;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  gnutls_session_t session = BACKEND->session;
+  int rc;
+#ifdef HAS_ALPN
+  gnutls_datum_t proto;
+#endif
+  CURLcode result = CURLE_OK;
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  unsigned int algo;
+  unsigned int bits;
+  gnutls_protocol_t version = gnutls_protocol_get_version(session);
+#endif
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+
+  /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */
+  ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session),
+                                     gnutls_cipher_get(session),
+                                     gnutls_mac_get(session));
+
+  infof(data, "SSL connection using %s / %s\n",
+        gnutls_protocol_get_name(version), ptr);
+
+  /* This function will return the peer's raw certificate (chain) as sent by
+     the peer. These certificates are in raw format (DER encoded for
+     X.509). In case of a X.509 then a certificate list may be present. The
+     first certificate in the list is the peer's certificate, following the
+     issuer's certificate, then the issuer's issuer etc. */
+
+  chainp = gnutls_certificate_get_peers(session, &cert_list_size);
+  if(!chainp) {
+    if(SSL_CONN_CONFIG(verifypeer) ||
+       SSL_CONN_CONFIG(verifyhost) ||
+       SSL_SET_OPTION(issuercert)) {
+#ifdef USE_TLS_SRP
+      if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP
+         && SSL_SET_OPTION(username) != NULL
+         && !SSL_CONN_CONFIG(verifypeer)
+         && gnutls_cipher_get(session)) {
+        /* no peer cert, but auth is ok if we have SRP user and cipher and no
+           peer verify */
+      }
+      else {
+#endif
+        failf(data, "failed to get server cert");
+        return CURLE_PEER_FAILED_VERIFICATION;
+#ifdef USE_TLS_SRP
+      }
+#endif
+    }
+    infof(data, "\t common name: WARNING couldn't obtain\n");
+  }
+
+  if(data->set.ssl.certinfo && chainp) {
+    unsigned int i;
+
+    result = Curl_ssl_init_certinfo(data, cert_list_size);
+    if(result)
+      return result;
+
+    for(i = 0; i < cert_list_size; i++) {
+      const char *beg = (const char *) chainp[i].data;
+      const char *end = beg + chainp[i].size;
+
+      result = Curl_extract_certinfo(conn, i, beg, end);
+      if(result)
+        return result;
+    }
+  }
+
+  if(SSL_CONN_CONFIG(verifypeer)) {
+    /* This function will try to verify the peer's certificate and return its
+       status (trusted, invalid etc.). The value of status should be one or
+       more of the gnutls_certificate_status_t enumerated elements bitwise
+       or'd. To avoid denial of service attacks some default upper limits
+       regarding the certificate key size and chain size are set. To override
+       them use gnutls_certificate_set_verify_limits(). */
+
+    rc = gnutls_certificate_verify_peers2(session, &verify_status);
+    if(rc < 0) {
+      failf(data, "server cert verify failed: %d", rc);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+
+    /* verify_status is a bitmask of gnutls_certificate_status bits */
+    if(verify_status & GNUTLS_CERT_INVALID) {
+      if(SSL_CONN_CONFIG(verifypeer)) {
+        failf(data, "server certificate verification failed. CAfile: %s "
+              "CRLfile: %s", SSL_CONN_CONFIG(CAfile) ? SSL_CONN_CONFIG(CAfile):
+              "none",
+              SSL_SET_OPTION(CRLfile)?SSL_SET_OPTION(CRLfile):"none");
+        return CURLE_SSL_CACERT;
+      }
+      else
+        infof(data, "\t server certificate verification FAILED\n");
+    }
+    else
+      infof(data, "\t server certificate verification OK\n");
+  }
+  else
+    infof(data, "\t server certificate verification SKIPPED\n");
+
+#ifdef HAS_OCSP
+  if(SSL_CONN_CONFIG(verifystatus)) {
+    if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) {
+      gnutls_datum_t status_request;
+      gnutls_ocsp_resp_t ocsp_resp;
+
+      gnutls_ocsp_cert_status_t status;
+      gnutls_x509_crl_reason_t reason;
+
+      rc = gnutls_ocsp_status_request_get(session, &status_request);
+
+      infof(data, "\t server certificate status verification FAILED\n");
+
+      if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+        failf(data, "No OCSP response received");
+        return CURLE_SSL_INVALIDCERTSTATUS;
+      }
+
+      if(rc < 0) {
+        failf(data, "Invalid OCSP response received");
+        return CURLE_SSL_INVALIDCERTSTATUS;
+      }
+
+      gnutls_ocsp_resp_init(&ocsp_resp);
+
+      rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request);
+      if(rc < 0) {
+        failf(data, "Invalid OCSP response received");
+        return CURLE_SSL_INVALIDCERTSTATUS;
+      }
+
+      rc = gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL,
+                                       &status, NULL, NULL, NULL, &reason);
+
+      switch(status) {
+      case GNUTLS_OCSP_CERT_GOOD:
+        break;
+
+      case GNUTLS_OCSP_CERT_REVOKED: {
+        const char *crl_reason;
+
+        switch(reason) {
+          default:
+          case GNUTLS_X509_CRLREASON_UNSPECIFIED:
+            crl_reason = "unspecified reason";
+            break;
+
+          case GNUTLS_X509_CRLREASON_KEYCOMPROMISE:
+            crl_reason = "private key compromised";
+            break;
+
+          case GNUTLS_X509_CRLREASON_CACOMPROMISE:
+            crl_reason = "CA compromised";
+            break;
+
+          case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED:
+            crl_reason = "affiliation has changed";
+            break;
+
+          case GNUTLS_X509_CRLREASON_SUPERSEDED:
+            crl_reason = "certificate superseded";
+            break;
+
+          case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION:
+            crl_reason = "operation has ceased";
+            break;
+
+          case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD:
+            crl_reason = "certificate is on hold";
+            break;
+
+          case GNUTLS_X509_CRLREASON_REMOVEFROMCRL:
+            crl_reason = "will be removed from delta CRL";
+            break;
+
+          case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN:
+            crl_reason = "privilege withdrawn";
+            break;
+
+          case GNUTLS_X509_CRLREASON_AACOMPROMISE:
+            crl_reason = "AA compromised";
+            break;
+        }
+
+        failf(data, "Server certificate was revoked: %s", crl_reason);
+        break;
+      }
+
+      default:
+      case GNUTLS_OCSP_CERT_UNKNOWN:
+        failf(data, "Server certificate status is unknown");
+        break;
+      }
+
+      gnutls_ocsp_resp_deinit(ocsp_resp);
+
+      return CURLE_SSL_INVALIDCERTSTATUS;
+    }
+    else
+      infof(data, "\t server certificate status verification OK\n");
+  }
+  else
+    infof(data, "\t server certificate status verification SKIPPED\n");
+#endif
+
+  /* initialize an X.509 certificate structure. */
+  gnutls_x509_crt_init(&x509_cert);
+
+  if(chainp)
+    /* convert the given DER or PEM encoded Certificate to the native
+       gnutls_x509_crt_t format */
+    gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER);
+
+  if(SSL_SET_OPTION(issuercert)) {
+    gnutls_x509_crt_init(&x509_issuer);
+    issuerp = load_file(SSL_SET_OPTION(issuercert));
+    gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM);
+    rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer);
+    gnutls_x509_crt_deinit(x509_issuer);
+    unload_file(issuerp);
+    if(rc <= 0) {
+      failf(data, "server certificate issuer check failed (IssuerCert: %s)",
+            SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none");
+      gnutls_x509_crt_deinit(x509_cert);
+      return CURLE_SSL_ISSUER_ERROR;
+    }
+    infof(data, "\t server certificate issuer check OK (Issuer Cert: %s)\n",
+          SSL_SET_OPTION(issuercert)?SSL_SET_OPTION(issuercert):"none");
+  }
+
+  size = sizeof(certbuf);
+  rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME,
+                                     0, /* the first and only one */
+                                     FALSE,
+                                     certbuf,
+                                     &size);
+  if(rc) {
+    infof(data, "error fetching CN from cert:%s\n",
+          gnutls_strerror(rc));
+  }
+
+  /* This function will check if the given certificate's subject matches the
+     given hostname. This is a basic implementation of the matching described
+     in RFC2818 (HTTPS), which takes into account wildcards, and the subject
+     alternative name PKIX extension. Returns non zero on success, and zero on
+     failure. */
+  rc = gnutls_x509_crt_check_hostname(x509_cert, hostname);
+#if GNUTLS_VERSION_NUMBER < 0x030306
+  /* Before 3.3.6, gnutls_x509_crt_check_hostname() didn't check IP
+     addresses. */
+  if(!rc) {
+#ifdef ENABLE_IPV6
+    #define use_addr in6_addr
+#else
+    #define use_addr in_addr
+#endif
+    unsigned char addrbuf[sizeof(struct use_addr)];
+    unsigned char certaddr[sizeof(struct use_addr)];
+    size_t addrlen = 0, certaddrlen;
+    int i;
+    int ret = 0;
+
+    if(Curl_inet_pton(AF_INET, hostname, addrbuf) > 0)
+      addrlen = 4;
+#ifdef ENABLE_IPV6
+    else if(Curl_inet_pton(AF_INET6, hostname, addrbuf) > 0)
+      addrlen = 16;
+#endif
+
+    if(addrlen) {
+      for(i = 0; ; i++) {
+        certaddrlen = sizeof(certaddr);
+        ret = gnutls_x509_crt_get_subject_alt_name(x509_cert, i, certaddr,
+                                                   &certaddrlen, NULL);
+        /* If this happens, it wasn't an IP address. */
+        if(ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
+          continue;
+        if(ret < 0)
+          break;
+        if(ret != GNUTLS_SAN_IPADDRESS)
+          continue;
+        if(certaddrlen == addrlen && !memcmp(addrbuf, certaddr, addrlen)) {
+          rc = 1;
+          break;
+        }
+      }
+    }
+  }
+#endif
+  if(!rc) {
+    const char * const dispname = SSL_IS_PROXY() ?
+      conn->http_proxy.host.dispname : conn->host.dispname;
+
+    if(SSL_CONN_CONFIG(verifyhost)) {
+      failf(data, "SSL: certificate subject name (%s) does not match "
+            "target host name '%s'", certbuf, dispname);
+      gnutls_x509_crt_deinit(x509_cert);
+      return CURLE_PEER_FAILED_VERIFICATION;
+    }
+    else
+      infof(data, "\t common name: %s (does not match '%s')\n",
+            certbuf, dispname);
+  }
+  else
+    infof(data, "\t common name: %s (matched)\n", certbuf);
+
+  /* Check for time-based validity */
+  certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
+
+  if(certclock == (time_t)-1) {
+    if(SSL_CONN_CONFIG(verifypeer)) {
+      failf(data, "server cert expiration date verify failed");
+      gnutls_x509_crt_deinit(x509_cert);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+    else
+      infof(data, "\t server certificate expiration date verify FAILED\n");
+  }
+  else {
+    if(certclock < time(NULL)) {
+      if(SSL_CONN_CONFIG(verifypeer)) {
+        failf(data, "server certificate expiration date has passed.");
+        gnutls_x509_crt_deinit(x509_cert);
+        return CURLE_PEER_FAILED_VERIFICATION;
+      }
+      else
+        infof(data, "\t server certificate expiration date FAILED\n");
+    }
+    else
+      infof(data, "\t server certificate expiration date OK\n");
+  }
+
+  certclock = gnutls_x509_crt_get_activation_time(x509_cert);
+
+  if(certclock == (time_t)-1) {
+    if(SSL_CONN_CONFIG(verifypeer)) {
+      failf(data, "server cert activation date verify failed");
+      gnutls_x509_crt_deinit(x509_cert);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+    else
+      infof(data, "\t server certificate activation date verify FAILED\n");
+  }
+  else {
+    if(certclock > time(NULL)) {
+      if(SSL_CONN_CONFIG(verifypeer)) {
+        failf(data, "server certificate not activated yet.");
+        gnutls_x509_crt_deinit(x509_cert);
+        return CURLE_PEER_FAILED_VERIFICATION;
+      }
+      else
+        infof(data, "\t server certificate activation date FAILED\n");
+    }
+    else
+      infof(data, "\t server certificate activation date OK\n");
+  }
+
+  ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
+        data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+  if(ptr) {
+    result = pkp_pin_peer_pubkey(data, x509_cert, ptr);
+    if(result != CURLE_OK) {
+      failf(data, "SSL: public key does not match pinned public key!");
+      gnutls_x509_crt_deinit(x509_cert);
+      return result;
+    }
+  }
+
+  /* Show:
+
+  - subject
+  - start date
+  - expire date
+  - common name
+  - issuer
+
+  */
+
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  /* public key algorithm's parameters */
+  algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits);
+  infof(data, "\t certificate public key: %s\n",
+        gnutls_pk_algorithm_get_name(algo));
+
+  /* version of the X.509 certificate. */
+  infof(data, "\t certificate version: #%d\n",
+        gnutls_x509_crt_get_version(x509_cert));
+
+
+  size = sizeof(certbuf);
+  gnutls_x509_crt_get_dn(x509_cert, certbuf, &size);
+  infof(data, "\t subject: %s\n", certbuf);
+
+  certclock = gnutls_x509_crt_get_activation_time(x509_cert);
+  showtime(data, "start date", certclock);
+
+  certclock = gnutls_x509_crt_get_expiration_time(x509_cert);
+  showtime(data, "expire date", certclock);
+
+  size = sizeof(certbuf);
+  gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size);
+  infof(data, "\t issuer: %s\n", certbuf);
+
+  /* compression algorithm (if any) */
+  ptr = gnutls_compression_get_name(gnutls_compression_get(session));
+  /* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */
+  infof(data, "\t compression: %s\n", ptr);
+#endif
+
+  gnutls_x509_crt_deinit(x509_cert);
+
+#ifdef HAS_ALPN
+  if(conn->bits.tls_enable_alpn) {
+    rc = gnutls_alpn_get_selected_protocol(session, &proto);
+    if(rc == 0) {
+      infof(data, "ALPN, server accepted to use %.*s\n", proto.size,
+          proto.data);
+
+#ifdef USE_NGHTTP2
+      if(proto.size == NGHTTP2_PROTO_VERSION_ID_LEN &&
+         !memcmp(NGHTTP2_PROTO_VERSION_ID, proto.data,
+                 NGHTTP2_PROTO_VERSION_ID_LEN)) {
+        conn->negnpn = CURL_HTTP_VERSION_2;
+      }
+      else
+#endif
+      if(proto.size == ALPN_HTTP_1_1_LENGTH &&
+         !memcmp(ALPN_HTTP_1_1, proto.data, ALPN_HTTP_1_1_LENGTH)) {
+        conn->negnpn = CURL_HTTP_VERSION_1_1;
+      }
+    }
+    else
+      infof(data, "ALPN, server did not agree to a protocol\n");
+  }
+#endif
+
+  conn->ssl[sockindex].state = ssl_connection_complete;
+  conn->recv[sockindex] = gtls_recv;
+  conn->send[sockindex] = gtls_send;
+
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    /* we always unconditionally get the session id here, as even if we
+       already got it from the cache and asked to use it in the connection, it
+       might've been rejected and then a new one is in use now and we need to
+       detect that. */
+    bool incache;
+    void *ssl_sessionid;
+    void *connect_sessionid;
+    size_t connect_idsize = 0;
+
+    /* get the session ID data size */
+    gnutls_session_get_data(session, NULL, &connect_idsize);
+    connect_sessionid = malloc(connect_idsize); /* get a buffer for it */
+
+    if(connect_sessionid) {
+      /* extract session ID to the allocated buffer */
+      gnutls_session_get_data(session, connect_sessionid, &connect_idsize);
+
+      Curl_ssl_sessionid_lock(conn);
+      incache = !(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL,
+                                        sockindex));
+      if(incache) {
+        /* there was one before in the cache, so instead of risking that the
+           previous one was rejected, we just kill that and store the new */
+        Curl_ssl_delsessionid(conn, ssl_sessionid);
+      }
+
+      /* store this session id */
+      result = Curl_ssl_addsessionid(conn, connect_sessionid, connect_idsize,
+                                     sockindex);
+      Curl_ssl_sessionid_unlock(conn);
+      if(result) {
+        free(connect_sessionid);
+        result = CURLE_OUT_OF_MEMORY;
+      }
+    }
+    else
+      result = CURLE_OUT_OF_MEMORY;
+  }
+
+  return result;
+}
+
+
+/*
+ * This function is called after the TCP connect has completed. Setup the TLS
+ * layer and do all necessary magic.
+ */
+/* We use connssl->connecting_state to keep track of the connection status;
+   there are three states: 'ssl_connect_1' (not started yet or complete),
+   'ssl_connect_2_reading' (waiting for data from server), and
+   'ssl_connect_2_writing' (waiting to be able to write).
+ */
+static CURLcode
+gtls_connect_common(struct connectdata *conn,
+                    int sockindex,
+                    bool nonblocking,
+                    bool *done)
+{
+  int rc;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  /* Initiate the connection, if not already done */
+  if(ssl_connect_1 == connssl->connecting_state) {
+    rc = gtls_connect_step1(conn, sockindex);
+    if(rc)
+      return rc;
+  }
+
+  rc = handshake(conn, sockindex, TRUE, nonblocking);
+  if(rc)
+    /* handshake() sets its own error message with failf() */
+    return rc;
+
+  /* Finish connecting once the handshake is done */
+  if(ssl_connect_1 == connssl->connecting_state) {
+    rc = gtls_connect_step3(conn, sockindex);
+    if(rc)
+      return rc;
+  }
+
+  *done = ssl_connect_1 == connssl->connecting_state;
+
+  return CURLE_OK;
+}
+
+static CURLcode Curl_gtls_connect_nonblocking(struct connectdata *conn,
+                                              int sockindex, bool *done)
+{
+  return gtls_connect_common(conn, sockindex, TRUE, done);
+}
+
+static CURLcode Curl_gtls_connect(struct connectdata *conn, int sockindex)
+{
+  CURLcode result;
+  bool done = FALSE;
+
+  result = gtls_connect_common(conn, sockindex, FALSE, &done);
+  if(result)
+    return result;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+static bool Curl_gtls_data_pending(const struct connectdata *conn,
+                                   int connindex)
+{
+  const struct ssl_connect_data *connssl = &conn->ssl[connindex];
+  bool res = FALSE;
+  if(BACKEND->session &&
+     0 != gnutls_record_check_pending(BACKEND->session))
+    res = TRUE;
+
+  connssl = &conn->proxy_ssl[connindex];
+  if(BACKEND->session &&
+     0 != gnutls_record_check_pending(BACKEND->session))
+    res = TRUE;
+
+  return res;
+}
+
+static ssize_t gtls_send(struct connectdata *conn,
+                         int sockindex,
+                         const void *mem,
+                         size_t len,
+                         CURLcode *curlcode)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  ssize_t rc = gnutls_record_send(BACKEND->session, mem, len);
+
+  if(rc < 0) {
+    *curlcode = (rc == GNUTLS_E_AGAIN)
+      ? CURLE_AGAIN
+      : CURLE_SEND_ERROR;
+
+    rc = -1;
+  }
+
+  return rc;
+}
+
+static void close_one(struct ssl_connect_data *connssl)
+{
+  if(BACKEND->session) {
+    gnutls_bye(BACKEND->session, GNUTLS_SHUT_RDWR);
+    gnutls_deinit(BACKEND->session);
+    BACKEND->session = NULL;
+  }
+  if(BACKEND->cred) {
+    gnutls_certificate_free_credentials(BACKEND->cred);
+    BACKEND->cred = NULL;
+  }
+#ifdef USE_TLS_SRP
+  if(BACKEND->srp_client_cred) {
+    gnutls_srp_free_client_credentials(BACKEND->srp_client_cred);
+    BACKEND->srp_client_cred = NULL;
+  }
+#endif
+}
+
+static void Curl_gtls_close(struct connectdata *conn, int sockindex)
+{
+  close_one(&conn->ssl[sockindex]);
+  close_one(&conn->proxy_ssl[sockindex]);
+}
+
+/*
+ * This function is called to shut down the SSL layer but keep the
+ * socket open (CCC - Clear Command Channel)
+ */
+static int Curl_gtls_shutdown(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  ssize_t result;
+  int retval = 0;
+  struct Curl_easy *data = conn->data;
+  int done = 0;
+  char buf[120];
+
+  /* This has only been tested on the proftpd server, and the mod_tls code
+     sends a close notify alert without waiting for a close notify alert in
+     response. Thus we wait for a close notify alert from the server, but
+     we do not send one. Let's hope other servers do the same... */
+
+  if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
+      gnutls_bye(BACKEND->session, GNUTLS_SHUT_WR);
+
+  if(BACKEND->session) {
+    while(!done) {
+      int what = SOCKET_READABLE(conn->sock[sockindex],
+                                 SSL_SHUTDOWN_TIMEOUT);
+      if(what > 0) {
+        /* Something to read, let's do it and hope that it is the close
+           notify alert from the server */
+        result = gnutls_record_recv(BACKEND->session,
+                                    buf, sizeof(buf));
+        switch(result) {
+        case 0:
+          /* This is the expected response. There was no data but only
+             the close notify alert */
+          done = 1;
+          break;
+        case GNUTLS_E_AGAIN:
+        case GNUTLS_E_INTERRUPTED:
+          infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\n");
+          break;
+        default:
+          retval = -1;
+          done = 1;
+          break;
+        }
+      }
+      else if(0 == what) {
+        /* timeout */
+        failf(data, "SSL shutdown timeout");
+        done = 1;
+        break;
+      }
+      else {
+        /* anything that gets here is fatally bad */
+        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        retval = -1;
+        done = 1;
+      }
+    }
+    gnutls_deinit(BACKEND->session);
+  }
+  gnutls_certificate_free_credentials(BACKEND->cred);
+
+#ifdef USE_TLS_SRP
+  if(SSL_SET_OPTION(authtype) == CURL_TLSAUTH_SRP
+     && SSL_SET_OPTION(username) != NULL)
+    gnutls_srp_free_client_credentials(BACKEND->srp_client_cred);
+#endif
+
+  BACKEND->cred = NULL;
+  BACKEND->session = NULL;
+
+  return retval;
+}
+
+static ssize_t gtls_recv(struct connectdata *conn, /* connection data */
+                         int num,                  /* socketindex */
+                         char *buf,                /* store read data here */
+                         size_t buffersize,        /* max amount to read */
+                         CURLcode *curlcode)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[num];
+  ssize_t ret;
+
+  ret = gnutls_record_recv(BACKEND->session, buf, buffersize);
+  if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) {
+    *curlcode = CURLE_AGAIN;
+    return -1;
+  }
+
+  if(ret == GNUTLS_E_REHANDSHAKE) {
+    /* BLOCKING call, this is bad but a work-around for now. Fixing this "the
+       proper way" takes a whole lot of work. */
+    CURLcode result = handshake(conn, num, FALSE, FALSE);
+    if(result)
+      /* handshake() writes error message on its own */
+      *curlcode = result;
+    else
+      *curlcode = CURLE_AGAIN; /* then return as if this was a wouldblock */
+    return -1;
+  }
+
+  if(ret < 0) {
+    failf(conn->data, "GnuTLS recv error (%d): %s",
+
+          (int)ret, gnutls_strerror((int)ret));
+    *curlcode = CURLE_RECV_ERROR;
+    return -1;
+  }
+
+  return ret;
+}
+
+static void Curl_gtls_session_free(void *ptr)
+{
+  free(ptr);
+}
+
+static size_t Curl_gtls_version(char *buffer, size_t size)
+{
+  return snprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL));
+}
+
+#ifndef USE_GNUTLS_NETTLE
+static int Curl_gtls_seed(struct Curl_easy *data)
+{
+  /* we have the "SSL is seeded" boolean static to prevent multiple
+     time-consuming seedings in vain */
+  static bool ssl_seeded = FALSE;
+
+  /* Quickly add a bit of entropy */
+  gcry_fast_random_poll();
+
+  if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] ||
+     data->set.str[STRING_SSL_EGDSOCKET]) {
+
+    /* TODO: to a good job seeding the RNG
+       This may involve the gcry_control function and these options:
+       GCRYCTL_SET_RANDOM_SEED_FILE
+       GCRYCTL_SET_RNDEGD_SOCKET
+    */
+    ssl_seeded = TRUE;
+  }
+  return 0;
+}
+#endif
+
+/* data might be NULL! */
+static CURLcode Curl_gtls_random(struct Curl_easy *data,
+                                 unsigned char *entropy, size_t length)
+{
+#if defined(USE_GNUTLS_NETTLE)
+  int rc;
+  (void)data;
+  rc = gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length);
+  return rc?CURLE_FAILED_INIT:CURLE_OK;
+#elif defined(USE_GNUTLS)
+  if(data)
+    Curl_gtls_seed(data); /* Initiate the seed if not already done */
+  gcry_randomize(entropy, length, GCRY_STRONG_RANDOM);
+#endif
+  return CURLE_OK;
+}
+
+static CURLcode Curl_gtls_md5sum(unsigned char *tmp, /* input */
+                                 size_t tmplen,
+                                 unsigned char *md5sum, /* output */
+                                 size_t md5len)
+{
+#if defined(USE_GNUTLS_NETTLE)
+  struct md5_ctx MD5pw;
+  md5_init(&MD5pw);
+  md5_update(&MD5pw, (unsigned int)tmplen, tmp);
+  md5_digest(&MD5pw, (unsigned int)md5len, md5sum);
+#elif defined(USE_GNUTLS)
+  gcry_md_hd_t MD5pw;
+  gcry_md_open(&MD5pw, GCRY_MD_MD5, 0);
+  gcry_md_write(MD5pw, tmp, tmplen);
+  memcpy(md5sum, gcry_md_read(MD5pw, 0), md5len);
+  gcry_md_close(MD5pw);
+#endif
+  return CURLE_OK;
+}
+
+static void Curl_gtls_sha256sum(const unsigned char *tmp, /* input */
+                                size_t tmplen,
+                                unsigned char *sha256sum, /* output */
+                                size_t sha256len)
+{
+#if defined(USE_GNUTLS_NETTLE)
+  struct sha256_ctx SHA256pw;
+  sha256_init(&SHA256pw);
+  sha256_update(&SHA256pw, (unsigned int)tmplen, tmp);
+  sha256_digest(&SHA256pw, (unsigned int)sha256len, sha256sum);
+#elif defined(USE_GNUTLS)
+  gcry_md_hd_t SHA256pw;
+  gcry_md_open(&SHA256pw, GCRY_MD_SHA256, 0);
+  gcry_md_write(SHA256pw, tmp, tmplen);
+  memcpy(sha256sum, gcry_md_read(SHA256pw, 0), sha256len);
+  gcry_md_close(SHA256pw);
+#endif
+}
+
+static bool Curl_gtls_cert_status_request(void)
+{
+#ifdef HAS_OCSP
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}
+
+static void *Curl_gtls_get_internals(struct ssl_connect_data *connssl,
+                                     CURLINFO info UNUSED_PARAM)
+{
+  (void)info;
+  return BACKEND->session;
+}
+
+const struct Curl_ssl Curl_ssl_gnutls = {
+  { CURLSSLBACKEND_GNUTLS, "gnutls" }, /* info */
+
+  1, /* have_ca_path */
+  1, /* have_certinfo */
+  1, /* have_pinnedpubkey */
+  0, /* have_ssl_ctx */
+  1, /* support_https_proxy */
+
+  sizeof(struct ssl_backend_data),
+
+  Curl_gtls_init,                /* init */
+  Curl_gtls_cleanup,             /* cleanup */
+  Curl_gtls_version,             /* version */
+  Curl_none_check_cxn,           /* check_cxn */
+  Curl_gtls_shutdown,            /* shutdown */
+  Curl_gtls_data_pending,        /* data_pending */
+  Curl_gtls_random,              /* random */
+  Curl_gtls_cert_status_request, /* cert_status_request */
+  Curl_gtls_connect,             /* connect */
+  Curl_gtls_connect_nonblocking, /* connect_nonblocking */
+  Curl_gtls_get_internals,       /* get_internals */
+  Curl_gtls_close,               /* close_one */
+  Curl_none_close_all,           /* close_all */
+  Curl_gtls_session_free,        /* session_free */
+  Curl_none_set_engine,          /* set_engine */
+  Curl_none_set_engine_default,  /* set_engine_default */
+  Curl_none_engines_list,        /* engines_list */
+  Curl_none_false_start,         /* false_start */
+  Curl_gtls_md5sum,              /* md5sum */
+  Curl_gtls_sha256sum            /* sha256sum */
+};
+
+#endif /* USE_GNUTLS */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/gtls.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/gtls.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/gtls.h	(revision 331)
@@ -0,0 +1,34 @@
+#ifndef HEADER_CURL_GTLS_H
+#define HEADER_CURL_GTLS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_GNUTLS
+
+#include "urldata.h"
+
+extern const struct Curl_ssl Curl_ssl_gnutls;
+
+#endif /* USE_GNUTLS */
+#endif /* HEADER_CURL_GTLS_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/mbedtls.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/mbedtls.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/mbedtls.c	(revision 331)
@@ -0,0 +1,1075 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all mbedTLS-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ *
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_MBEDTLS
+
+#include <mbedtls/version.h>
+#if MBEDTLS_VERSION_NUMBER >= 0x02040000
+#include <mbedtls/net_sockets.h>
+#else
+#include <mbedtls/net.h>
+#endif
+#include <mbedtls/ssl.h>
+#include <mbedtls/certs.h>
+#include <mbedtls/x509.h>
+
+#include <mbedtls/error.h>
+#include <mbedtls/entropy.h>
+#include <mbedtls/ctr_drbg.h>
+#include <mbedtls/sha256.h>
+
+#include "urldata.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "mbedtls.h"
+#include "vtls.h"
+#include "parsedate.h"
+#include "connect.h" /* for the connect timeout */
+#include "select.h"
+#include "polarssl_threadlock.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+struct ssl_backend_data {
+  mbedtls_ctr_drbg_context ctr_drbg;
+  mbedtls_entropy_context entropy;
+  mbedtls_ssl_context ssl;
+  int server_fd;
+  mbedtls_x509_crt cacert;
+  mbedtls_x509_crt clicert;
+  mbedtls_x509_crl crl;
+  mbedtls_pk_context pk;
+  mbedtls_ssl_config config;
+  const char *protocols[3];
+};
+
+#define BACKEND connssl->backend
+
+/* apply threading? */
+#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
+#define THREADING_SUPPORT
+#endif
+
+#if defined(THREADING_SUPPORT)
+static mbedtls_entropy_context ts_entropy;
+
+static int entropy_init_initialized = 0;
+
+/* start of entropy_init_mutex() */
+static void entropy_init_mutex(mbedtls_entropy_context *ctx)
+{
+  /* lock 0 = entropy_init_mutex() */
+  Curl_polarsslthreadlock_lock_function(0);
+  if(entropy_init_initialized == 0) {
+    mbedtls_entropy_init(ctx);
+    entropy_init_initialized = 1;
+  }
+  Curl_polarsslthreadlock_unlock_function(0);
+}
+/* end of entropy_init_mutex() */
+
+/* start of entropy_func_mutex() */
+static int entropy_func_mutex(void *data, unsigned char *output, size_t len)
+{
+  int ret;
+  /* lock 1 = entropy_func_mutex() */
+  Curl_polarsslthreadlock_lock_function(1);
+  ret = mbedtls_entropy_func(data, output, len);
+  Curl_polarsslthreadlock_unlock_function(1);
+
+  return ret;
+}
+/* end of entropy_func_mutex() */
+
+#endif /* THREADING_SUPPORT */
+
+/* Define this to enable lots of debugging for mbedTLS */
+#undef MBEDTLS_DEBUG
+
+#ifdef MBEDTLS_DEBUG
+static void mbed_debug(void *context, int level, const char *f_name,
+                       int line_nb, const char *line)
+{
+  struct Curl_easy *data = NULL;
+
+  if(!context)
+    return;
+
+  data = (struct Curl_easy *)context;
+
+  infof(data, "%s", line);
+  (void) level;
+}
+#else
+#endif
+
+/* ALPN for http2? */
+#ifdef USE_NGHTTP2
+#  undef HAS_ALPN
+#  ifdef MBEDTLS_SSL_ALPN
+#    define HAS_ALPN
+#  endif
+#endif
+
+
+/*
+ *  profile
+ */
+static const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_fr =
+{
+  /* Hashes from SHA-1 and above */
+  MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA1) |
+  MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_RIPEMD160) |
+  MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA224) |
+  MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) |
+  MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384) |
+  MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA512),
+  0xFFFFFFF, /* Any PK alg    */
+  0xFFFFFFF, /* Any curve     */
+  1024,      /* RSA min key len */
+};
+
+/* See https://tls.mbed.org/discussions/generic/
+   howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der
+*/
+#define RSA_PUB_DER_MAX_BYTES   (38 + 2 * MBEDTLS_MPI_MAX_SIZE)
+#define ECP_PUB_DER_MAX_BYTES   (30 + 2 * MBEDTLS_ECP_MAX_BYTES)
+
+#define PUB_DER_MAX_BYTES   (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
+                             RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES)
+
+static Curl_recv mbed_recv;
+static Curl_send mbed_send;
+
+static CURLcode mbedtls_version_from_curl(int *mbedver, long version)
+{
+  switch(version) {
+    case CURL_SSLVERSION_TLSv1_0:
+      *mbedver = MBEDTLS_SSL_MINOR_VERSION_1;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_1:
+      *mbedver = MBEDTLS_SSL_MINOR_VERSION_2;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_2:
+      *mbedver = MBEDTLS_SSL_MINOR_VERSION_3;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_3:
+      break;
+  }
+  return CURLE_SSL_CONNECT_ERROR;
+}
+
+static CURLcode
+set_ssl_version_min_max(struct connectdata *conn, int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  int mbedtls_ver_min = MBEDTLS_SSL_MINOR_VERSION_1;
+  int mbedtls_ver_max = MBEDTLS_SSL_MINOR_VERSION_1;
+  long ssl_version = SSL_CONN_CONFIG(version);
+  long ssl_version_max = SSL_CONN_CONFIG(version_max);
+  CURLcode result = CURLE_OK;
+
+  switch(ssl_version) {
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1:
+      ssl_version = CURL_SSLVERSION_TLSv1_0;
+      ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+      break;
+  }
+
+  switch(ssl_version_max) {
+    case CURL_SSLVERSION_MAX_NONE:
+      ssl_version_max = ssl_version << 16;
+      break;
+    case CURL_SSLVERSION_MAX_DEFAULT:
+      ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+      break;
+  }
+
+  result = mbedtls_version_from_curl(&mbedtls_ver_min, ssl_version);
+  if(result) {
+    failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
+    return result;
+  }
+  result = mbedtls_version_from_curl(&mbedtls_ver_max, ssl_version_max >> 16);
+  if(result) {
+    failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
+    return result;
+  }
+
+  mbedtls_ssl_conf_min_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+                               mbedtls_ver_min);
+  mbedtls_ssl_conf_max_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+                               mbedtls_ver_max);
+
+  return result;
+}
+
+static CURLcode
+mbed_connect_step1(struct connectdata *conn,
+                   int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+  const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
+  const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
+  const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
+  char * const ssl_cert = SSL_SET_OPTION(cert);
+  const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+  const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
+  int ret = -1;
+  char errorbuf[128];
+  errorbuf[0] = 0;
+
+  /* mbedTLS only supports SSLv3 and TLSv1 */
+  if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
+    failf(data, "mbedTLS does not support SSLv2");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+#ifdef THREADING_SUPPORT
+  entropy_init_mutex(&ts_entropy);
+  mbedtls_ctr_drbg_init(&BACKEND->ctr_drbg);
+
+  ret = mbedtls_ctr_drbg_seed(&BACKEND->ctr_drbg, entropy_func_mutex,
+                              &ts_entropy, NULL, 0);
+  if(ret) {
+#ifdef MBEDTLS_ERROR_C
+    mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* MBEDTLS_ERROR_C */
+    failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n",
+          -ret, errorbuf);
+  }
+#else
+  mbedtls_entropy_init(&BACKEND->entropy);
+  mbedtls_ctr_drbg_init(&BACKEND->ctr_drbg);
+
+  ret = mbedtls_ctr_drbg_seed(&BACKEND->ctr_drbg, mbedtls_entropy_func,
+                              &BACKEND->entropy, NULL, 0);
+  if(ret) {
+#ifdef MBEDTLS_ERROR_C
+    mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* MBEDTLS_ERROR_C */
+    failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n",
+          -ret, errorbuf);
+  }
+#endif /* THREADING_SUPPORT */
+
+  /* Load the trusted CA */
+  mbedtls_x509_crt_init(&BACKEND->cacert);
+
+  if(ssl_cafile) {
+    ret = mbedtls_x509_crt_parse_file(&BACKEND->cacert, ssl_cafile);
+
+    if(ret<0) {
+#ifdef MBEDTLS_ERROR_C
+      mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* MBEDTLS_ERROR_C */
+      failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s",
+            ssl_cafile, -ret, errorbuf);
+
+      if(verifypeer)
+        return CURLE_SSL_CACERT_BADFILE;
+    }
+  }
+
+  if(ssl_capath) {
+    ret = mbedtls_x509_crt_parse_path(&BACKEND->cacert, ssl_capath);
+
+    if(ret<0) {
+#ifdef MBEDTLS_ERROR_C
+      mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* MBEDTLS_ERROR_C */
+      failf(data, "Error reading ca cert path %s - mbedTLS: (-0x%04X) %s",
+            ssl_capath, -ret, errorbuf);
+
+      if(verifypeer)
+        return CURLE_SSL_CACERT_BADFILE;
+    }
+  }
+
+  /* Load the client certificate */
+  mbedtls_x509_crt_init(&BACKEND->clicert);
+
+  if(ssl_cert) {
+    ret = mbedtls_x509_crt_parse_file(&BACKEND->clicert, ssl_cert);
+
+    if(ret) {
+#ifdef MBEDTLS_ERROR_C
+      mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* MBEDTLS_ERROR_C */
+      failf(data, "Error reading client cert file %s - mbedTLS: (-0x%04X) %s",
+            ssl_cert, -ret, errorbuf);
+
+      return CURLE_SSL_CERTPROBLEM;
+    }
+  }
+
+  /* Load the client private key */
+  mbedtls_pk_init(&BACKEND->pk);
+
+  if(SSL_SET_OPTION(key)) {
+    ret = mbedtls_pk_parse_keyfile(&BACKEND->pk, SSL_SET_OPTION(key),
+                                   SSL_SET_OPTION(key_passwd));
+    if(ret == 0 && !mbedtls_pk_can_do(&BACKEND->pk, MBEDTLS_PK_RSA))
+      ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
+
+    if(ret) {
+#ifdef MBEDTLS_ERROR_C
+      mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* MBEDTLS_ERROR_C */
+      failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s",
+            SSL_SET_OPTION(key), -ret, errorbuf);
+
+      return CURLE_SSL_CERTPROBLEM;
+    }
+  }
+
+  /* Load the CRL */
+  mbedtls_x509_crl_init(&BACKEND->crl);
+
+  if(ssl_crlfile) {
+    ret = mbedtls_x509_crl_parse_file(&BACKEND->crl, ssl_crlfile);
+
+    if(ret) {
+#ifdef MBEDTLS_ERROR_C
+      mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* MBEDTLS_ERROR_C */
+      failf(data, "Error reading CRL file %s - mbedTLS: (-0x%04X) %s",
+            ssl_crlfile, -ret, errorbuf);
+
+      return CURLE_SSL_CRL_BADFILE;
+    }
+  }
+
+  infof(data, "mbedTLS: Connecting to %s:%d\n", hostname, port);
+
+  mbedtls_ssl_config_init(&BACKEND->config);
+
+  mbedtls_ssl_init(&BACKEND->ssl);
+  if(mbedtls_ssl_setup(&BACKEND->ssl, &BACKEND->config)) {
+    failf(data, "mbedTLS: ssl_init failed");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+  ret = mbedtls_ssl_config_defaults(&BACKEND->config,
+                                    MBEDTLS_SSL_IS_CLIENT,
+                                    MBEDTLS_SSL_TRANSPORT_STREAM,
+                                    MBEDTLS_SSL_PRESET_DEFAULT);
+  if(ret) {
+    failf(data, "mbedTLS: ssl_config failed");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  /* new profile with RSA min key len = 1024 ... */
+  mbedtls_ssl_conf_cert_profile(&BACKEND->config,
+                                &mbedtls_x509_crt_profile_fr);
+
+  switch(SSL_CONN_CONFIG(version)) {
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+    mbedtls_ssl_conf_min_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+                                 MBEDTLS_SSL_MINOR_VERSION_1);
+    infof(data, "mbedTLS: Set min SSL version to TLS 1.0\n");
+    break;
+  case CURL_SSLVERSION_SSLv3:
+    mbedtls_ssl_conf_min_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+                                 MBEDTLS_SSL_MINOR_VERSION_0);
+    mbedtls_ssl_conf_max_version(&BACKEND->config, MBEDTLS_SSL_MAJOR_VERSION_3,
+                                 MBEDTLS_SSL_MINOR_VERSION_0);
+    infof(data, "mbedTLS: Set SSL version to SSLv3\n");
+    break;
+  case CURL_SSLVERSION_TLSv1_0:
+  case CURL_SSLVERSION_TLSv1_1:
+  case CURL_SSLVERSION_TLSv1_2:
+  case CURL_SSLVERSION_TLSv1_3:
+    {
+      CURLcode result = set_ssl_version_min_max(conn, sockindex);
+      if(result != CURLE_OK)
+        return result;
+      break;
+    }
+  default:
+    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  mbedtls_ssl_conf_authmode(&BACKEND->config, MBEDTLS_SSL_VERIFY_OPTIONAL);
+
+  mbedtls_ssl_conf_rng(&BACKEND->config, mbedtls_ctr_drbg_random,
+                       &BACKEND->ctr_drbg);
+  mbedtls_ssl_set_bio(&BACKEND->ssl, &conn->sock[sockindex],
+                      mbedtls_net_send,
+                      mbedtls_net_recv,
+                      NULL /*  rev_timeout() */);
+
+  mbedtls_ssl_conf_ciphersuites(&BACKEND->config,
+                                mbedtls_ssl_list_ciphersuites());
+
+#if defined(MBEDTLS_SSL_RENEGOTIATION)
+  mbedtls_ssl_conf_renegotiation(&BACKEND->config,
+                                 MBEDTLS_SSL_RENEGOTIATION_ENABLED);
+#endif
+
+#if defined(MBEDTLS_SSL_SESSION_TICKETS)
+  mbedtls_ssl_conf_session_tickets(&BACKEND->config,
+                                   MBEDTLS_SSL_SESSION_TICKETS_DISABLED);
+#endif
+
+  /* Check if there's a cached ID we can/should use here! */
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    void *old_session = NULL;
+
+    Curl_ssl_sessionid_lock(conn);
+    if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) {
+      ret = mbedtls_ssl_set_session(&BACKEND->ssl, old_session);
+      if(ret) {
+        Curl_ssl_sessionid_unlock(conn);
+        failf(data, "mbedtls_ssl_set_session returned -0x%x", -ret);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      infof(data, "mbedTLS re-using session\n");
+    }
+    Curl_ssl_sessionid_unlock(conn);
+  }
+
+  mbedtls_ssl_conf_ca_chain(&BACKEND->config,
+                            &BACKEND->cacert,
+                            &BACKEND->crl);
+
+  if(SSL_SET_OPTION(key)) {
+    mbedtls_ssl_conf_own_cert(&BACKEND->config,
+                              &BACKEND->clicert, &BACKEND->pk);
+  }
+  if(mbedtls_ssl_set_hostname(&BACKEND->ssl, hostname)) {
+    /* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks *and*
+       the name to set in the SNI extension. So even if curl connects to a
+       host specified as an IP address, this function must be used. */
+    failf(data, "couldn't set hostname in mbedTLS");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+#ifdef HAS_ALPN
+  if(conn->bits.tls_enable_alpn) {
+    const char **p = &BACKEND->protocols[0];
+#ifdef USE_NGHTTP2
+    if(data->set.httpversion >= CURL_HTTP_VERSION_2)
+      *p++ = NGHTTP2_PROTO_VERSION_ID;
+#endif
+    *p++ = ALPN_HTTP_1_1;
+    *p = NULL;
+    /* this function doesn't clone the protocols array, which is why we need
+       to keep it around */
+    if(mbedtls_ssl_conf_alpn_protocols(&BACKEND->config,
+                                       &BACKEND->protocols[0])) {
+      failf(data, "Failed setting ALPN protocols");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+    for(p = &BACKEND->protocols[0]; *p; ++p)
+      infof(data, "ALPN, offering %s\n", *p);
+  }
+#endif
+
+#ifdef MBEDTLS_DEBUG
+  /* In order to make that work in mbedtls MBEDTLS_DEBUG_C must be defined. */
+  mbedtls_ssl_conf_dbg(&BACKEND->config, mbed_debug, data);
+  /* - 0 No debug
+   * - 1 Error
+   * - 2 State change
+   * - 3 Informational
+   * - 4 Verbose
+   */
+  mbedtls_debug_set_threshold(4);
+#endif
+
+  /* give application a chance to interfere with mbedTLS set up. */
+  if(data->set.ssl.fsslctx) {
+    ret = (*data->set.ssl.fsslctx)(data, &BACKEND->config,
+                                   data->set.ssl.fsslctxp);
+    if(ret) {
+      failf(data, "error signaled by ssl ctx callback");
+      return ret;
+    }
+  }
+
+  connssl->connecting_state = ssl_connect_2;
+
+  return CURLE_OK;
+}
+
+static CURLcode
+mbed_connect_step2(struct connectdata *conn,
+                   int sockindex)
+{
+  int ret;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+  const mbedtls_x509_crt *peercert;
+  const char * const pinnedpubkey = SSL_IS_PROXY() ?
+        data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
+        data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+
+#ifdef HAS_ALPN
+  const char *next_protocol;
+#endif
+
+  char errorbuf[128];
+  errorbuf[0] = 0;
+
+  conn->recv[sockindex] = mbed_recv;
+  conn->send[sockindex] = mbed_send;
+
+  ret = mbedtls_ssl_handshake(&BACKEND->ssl);
+
+  if(ret == MBEDTLS_ERR_SSL_WANT_READ) {
+    connssl->connecting_state = ssl_connect_2_reading;
+    return CURLE_OK;
+  }
+  else if(ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
+    connssl->connecting_state = ssl_connect_2_writing;
+    return CURLE_OK;
+  }
+  else if(ret) {
+#ifdef MBEDTLS_ERROR_C
+    mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* MBEDTLS_ERROR_C */
+    failf(data, "ssl_handshake returned - mbedTLS: (-0x%04X) %s",
+          -ret, errorbuf);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  infof(data, "mbedTLS: Handshake complete, cipher is %s\n",
+        mbedtls_ssl_get_ciphersuite(&BACKEND->ssl)
+    );
+
+  ret = mbedtls_ssl_get_verify_result(&BACKEND->ssl);
+
+  if(ret && SSL_CONN_CONFIG(verifypeer)) {
+    if(ret & MBEDTLS_X509_BADCERT_EXPIRED)
+      failf(data, "Cert verify failed: BADCERT_EXPIRED");
+
+    if(ret & MBEDTLS_X509_BADCERT_REVOKED) {
+      failf(data, "Cert verify failed: BADCERT_REVOKED");
+      return CURLE_SSL_CACERT;
+    }
+
+    if(ret & MBEDTLS_X509_BADCERT_CN_MISMATCH)
+      failf(data, "Cert verify failed: BADCERT_CN_MISMATCH");
+
+    if(ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED)
+      failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED");
+
+    return CURLE_PEER_FAILED_VERIFICATION;
+  }
+
+  peercert = mbedtls_ssl_get_peer_cert(&BACKEND->ssl);
+
+  if(peercert && data->set.verbose) {
+    const size_t bufsize = 16384;
+    char *buffer = malloc(bufsize);
+
+    if(!buffer)
+      return CURLE_OUT_OF_MEMORY;
+
+    if(mbedtls_x509_crt_info(buffer, bufsize, "* ", peercert) > 0)
+      infof(data, "Dumping cert info:\n%s\n", buffer);
+    else
+      infof(data, "Unable to dump certificate information.\n");
+
+    free(buffer);
+  }
+
+  if(pinnedpubkey) {
+    int size;
+    CURLcode result;
+    mbedtls_x509_crt *p;
+    unsigned char pubkey[PUB_DER_MAX_BYTES];
+
+    if(!peercert || !peercert->raw.p || !peercert->raw.len) {
+      failf(data, "Failed due to missing peer certificate");
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    p = calloc(1, sizeof(*p));
+
+    if(!p)
+      return CURLE_OUT_OF_MEMORY;
+
+    mbedtls_x509_crt_init(p);
+
+    /* Make a copy of our const peercert because mbedtls_pk_write_pubkey_der
+       needs a non-const key, for now.
+       https://github.com/ARMmbed/mbedtls/issues/396 */
+    if(mbedtls_x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) {
+      failf(data, "Failed copying peer certificate");
+      mbedtls_x509_crt_free(p);
+      free(p);
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    size = mbedtls_pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES);
+
+    if(size <= 0) {
+      failf(data, "Failed copying public key from peer certificate");
+      mbedtls_x509_crt_free(p);
+      free(p);
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    /* mbedtls_pk_write_pubkey_der writes data at the end of the buffer. */
+    result = Curl_pin_peer_pubkey(data,
+                                  pinnedpubkey,
+                                  &pubkey[PUB_DER_MAX_BYTES - size], size);
+    if(result) {
+      mbedtls_x509_crt_free(p);
+      free(p);
+      return result;
+    }
+
+    mbedtls_x509_crt_free(p);
+    free(p);
+  }
+
+#ifdef HAS_ALPN
+  if(conn->bits.tls_enable_alpn) {
+    next_protocol = mbedtls_ssl_get_alpn_protocol(&BACKEND->ssl);
+
+    if(next_protocol) {
+      infof(data, "ALPN, server accepted to use %s\n", next_protocol);
+#ifdef USE_NGHTTP2
+      if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID,
+                  NGHTTP2_PROTO_VERSION_ID_LEN) &&
+         !next_protocol[NGHTTP2_PROTO_VERSION_ID_LEN]) {
+        conn->negnpn = CURL_HTTP_VERSION_2;
+      }
+      else
+#endif
+        if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH) &&
+           !next_protocol[ALPN_HTTP_1_1_LENGTH]) {
+          conn->negnpn = CURL_HTTP_VERSION_1_1;
+        }
+    }
+    else {
+      infof(data, "ALPN, server did not agree to a protocol\n");
+    }
+  }
+#endif
+
+  connssl->connecting_state = ssl_connect_3;
+  infof(data, "SSL connected\n");
+
+  return CURLE_OK;
+}
+
+static CURLcode
+mbed_connect_step3(struct connectdata *conn,
+                   int sockindex)
+{
+  CURLcode retcode = CURLE_OK;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct Curl_easy *data = conn->data;
+
+  DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    int ret;
+    mbedtls_ssl_session *our_ssl_sessionid;
+    void *old_ssl_sessionid = NULL;
+
+    our_ssl_sessionid = malloc(sizeof(mbedtls_ssl_session));
+    if(!our_ssl_sessionid)
+      return CURLE_OUT_OF_MEMORY;
+
+    mbedtls_ssl_session_init(our_ssl_sessionid);
+
+    ret = mbedtls_ssl_get_session(&BACKEND->ssl, our_ssl_sessionid);
+    if(ret) {
+      free(our_ssl_sessionid);
+      failf(data, "mbedtls_ssl_get_session returned -0x%x", -ret);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+
+    /* If there's already a matching session in the cache, delete it */
+    Curl_ssl_sessionid_lock(conn);
+    if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex))
+      Curl_ssl_delsessionid(conn, old_ssl_sessionid);
+
+    retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex);
+    Curl_ssl_sessionid_unlock(conn);
+    if(retcode) {
+      free(our_ssl_sessionid);
+      failf(data, "failed to store ssl session");
+      return retcode;
+    }
+  }
+
+  connssl->connecting_state = ssl_connect_done;
+
+  return CURLE_OK;
+}
+
+static ssize_t mbed_send(struct connectdata *conn, int sockindex,
+                         const void *mem, size_t len,
+                         CURLcode *curlcode)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  int ret = -1;
+
+  ret = mbedtls_ssl_write(&BACKEND->ssl,
+                          (unsigned char *)mem, len);
+
+  if(ret < 0) {
+    *curlcode = (ret == MBEDTLS_ERR_SSL_WANT_WRITE) ?
+      CURLE_AGAIN : CURLE_SEND_ERROR;
+    ret = -1;
+  }
+
+  return ret;
+}
+
+static void Curl_mbedtls_close_all(struct Curl_easy *data)
+{
+  (void)data;
+}
+
+static void Curl_mbedtls_close(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  mbedtls_pk_free(&BACKEND->pk);
+  mbedtls_x509_crt_free(&BACKEND->clicert);
+  mbedtls_x509_crt_free(&BACKEND->cacert);
+  mbedtls_x509_crl_free(&BACKEND->crl);
+  mbedtls_ssl_config_free(&BACKEND->config);
+  mbedtls_ssl_free(&BACKEND->ssl);
+  mbedtls_ctr_drbg_free(&BACKEND->ctr_drbg);
+#ifndef THREADING_SUPPORT
+  mbedtls_entropy_free(&BACKEND->entropy);
+#endif /* THREADING_SUPPORT */
+}
+
+static ssize_t mbed_recv(struct connectdata *conn, int num,
+                         char *buf, size_t buffersize,
+                         CURLcode *curlcode)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[num];
+  int ret = -1;
+  ssize_t len = -1;
+
+  memset(buf, 0, buffersize);
+  ret = mbedtls_ssl_read(&BACKEND->ssl, (unsigned char *)buf,
+                         buffersize);
+
+  if(ret <= 0) {
+    if(ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)
+      return 0;
+
+    *curlcode = (ret == MBEDTLS_ERR_SSL_WANT_READ) ?
+      CURLE_AGAIN : CURLE_RECV_ERROR;
+    return -1;
+  }
+
+  len = ret;
+
+  return len;
+}
+
+static void Curl_mbedtls_session_free(void *ptr)
+{
+  mbedtls_ssl_session_free(ptr);
+  free(ptr);
+}
+
+static size_t Curl_mbedtls_version(char *buffer, size_t size)
+{
+  unsigned int version = mbedtls_version_get_number();
+  return snprintf(buffer, size, "mbedTLS/%d.%d.%d", version>>24,
+                  (version>>16)&0xff, (version>>8)&0xff);
+}
+
+static CURLcode Curl_mbedtls_random(struct Curl_easy *data,
+                                    unsigned char *entropy, size_t length)
+{
+#if defined(MBEDTLS_CTR_DRBG_C)
+  int ret = -1;
+  char errorbuf[128];
+  mbedtls_entropy_context ctr_entropy;
+  mbedtls_ctr_drbg_context ctr_drbg;
+  mbedtls_entropy_init(&ctr_entropy);
+  mbedtls_ctr_drbg_init(&ctr_drbg);
+  errorbuf[0] = 0;
+
+  ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
+                              &ctr_entropy, NULL, 0);
+
+  if(ret) {
+#ifdef MBEDTLS_ERROR_C
+    mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* MBEDTLS_ERROR_C */
+    failf(data, "Failed - mbedTLS: ctr_drbg_seed returned (-0x%04X) %s\n",
+          -ret, errorbuf);
+  }
+  else {
+    ret = mbedtls_ctr_drbg_random(&ctr_drbg, entropy, length);
+
+    if(ret) {
+#ifdef MBEDTLS_ERROR_C
+      mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
+#endif /* MBEDTLS_ERROR_C */
+      failf(data, "mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n",
+            -ret, errorbuf);
+    }
+  }
+
+  mbedtls_ctr_drbg_free(&ctr_drbg);
+  mbedtls_entropy_free(&ctr_entropy);
+
+  return ret == 0 ? CURLE_OK : CURLE_FAILED_INIT;
+#elif defined(MBEDTLS_HAVEGE_C)
+  mbedtls_havege_state hs;
+  mbedtls_havege_init(&hs);
+  mbedtls_havege_random(&hs, entropy, length);
+  mbedtls_havege_free(&hs);
+  return CURLE_OK;
+#else
+  return CURLE_NOT_BUILT_IN;
+#endif
+}
+
+static CURLcode
+mbed_connect_common(struct connectdata *conn,
+                    int sockindex,
+                    bool nonblocking,
+                    bool *done)
+{
+  CURLcode retcode;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  curl_socket_t sockfd = conn->sock[sockindex];
+  long timeout_ms;
+  int what;
+
+  /* check if the connection has already been established */
+  if(ssl_connection_complete == connssl->state) {
+    *done = TRUE;
+    return CURLE_OK;
+  }
+
+  if(ssl_connect_1 == connssl->connecting_state) {
+    /* Find out how much more time we're allowed */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+    retcode = mbed_connect_step1(conn, sockindex);
+    if(retcode)
+      return retcode;
+  }
+
+  while(ssl_connect_2 == connssl->connecting_state ||
+        ssl_connect_2_reading == connssl->connecting_state ||
+        ssl_connect_2_writing == connssl->connecting_state) {
+
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    /* if ssl is expecting something, check if it's available. */
+    if(connssl->connecting_state == ssl_connect_2_reading
+       || connssl->connecting_state == ssl_connect_2_writing) {
+
+      curl_socket_t writefd = ssl_connect_2_writing ==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+      curl_socket_t readfd = ssl_connect_2_reading ==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+      what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
+                               nonblocking ? 0 : timeout_ms);
+      if(what < 0) {
+        /* fatal error */
+        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      else if(0 == what) {
+        if(nonblocking) {
+          *done = FALSE;
+          return CURLE_OK;
+        }
+        else {
+          /* timeout */
+          failf(data, "SSL connection timeout");
+          return CURLE_OPERATION_TIMEDOUT;
+        }
+      }
+      /* socket is readable or writable */
+    }
+
+    /* Run transaction, and return to the caller if it failed or if
+     * this connection is part of a multi handle and this loop would
+     * execute again. This permits the owner of a multi handle to
+     * abort a connection attempt before step2 has completed while
+     * ensuring that a client using select() or epoll() will always
+     * have a valid fdset to wait on.
+     */
+    retcode = mbed_connect_step2(conn, sockindex);
+    if(retcode || (nonblocking &&
+                   (ssl_connect_2 == connssl->connecting_state ||
+                    ssl_connect_2_reading == connssl->connecting_state ||
+                    ssl_connect_2_writing == connssl->connecting_state)))
+      return retcode;
+
+  } /* repeat step2 until all transactions are done. */
+
+  if(ssl_connect_3 == connssl->connecting_state) {
+    retcode = mbed_connect_step3(conn, sockindex);
+    if(retcode)
+      return retcode;
+  }
+
+  if(ssl_connect_done == connssl->connecting_state) {
+    connssl->state = ssl_connection_complete;
+    conn->recv[sockindex] = mbed_recv;
+    conn->send[sockindex] = mbed_send;
+    *done = TRUE;
+  }
+  else
+    *done = FALSE;
+
+  /* Reset our connect state machine */
+  connssl->connecting_state = ssl_connect_1;
+
+  return CURLE_OK;
+}
+
+static CURLcode Curl_mbedtls_connect_nonblocking(struct connectdata *conn,
+                                                 int sockindex, bool *done)
+{
+  return mbed_connect_common(conn, sockindex, TRUE, done);
+}
+
+
+static CURLcode Curl_mbedtls_connect(struct connectdata *conn, int sockindex)
+{
+  CURLcode retcode;
+  bool done = FALSE;
+
+  retcode = mbed_connect_common(conn, sockindex, FALSE, &done);
+  if(retcode)
+    return retcode;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+/*
+ * return 0 error initializing SSL
+ * return 1 SSL initialized successfully
+ */
+static int Curl_mbedtls_init(void)
+{
+  return Curl_polarsslthreadlock_thread_setup();
+}
+
+static void Curl_mbedtls_cleanup(void)
+{
+  (void)Curl_polarsslthreadlock_thread_cleanup();
+}
+
+static bool Curl_mbedtls_data_pending(const struct connectdata *conn,
+                                      int sockindex)
+{
+  const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  return mbedtls_ssl_get_bytes_avail(&BACKEND->ssl) != 0;
+}
+
+static void Curl_mbedtls_sha256sum(const unsigned char *input,
+                                    size_t inputlen,
+                                    unsigned char *sha256sum,
+                                    size_t sha256len UNUSED_PARAM)
+{
+  (void)sha256len;
+  mbedtls_sha256(input, inputlen, sha256sum, 0);
+}
+
+static void *Curl_mbedtls_get_internals(struct ssl_connect_data *connssl,
+                                        CURLINFO info UNUSED_PARAM)
+{
+  (void)info;
+  return &BACKEND->ssl;
+}
+
+const struct Curl_ssl Curl_ssl_mbedtls = {
+  { CURLSSLBACKEND_MBEDTLS, "mbedtls" }, /* info */
+
+  1, /* have_ca_path */
+  0, /* have_certinfo */
+  1, /* have_pinnedpubkey */
+  1, /* have_ssl_ctx */
+  0, /* support_https_proxy */
+
+  sizeof(struct ssl_backend_data),
+
+  Curl_mbedtls_init,                /* init */
+  Curl_mbedtls_cleanup,             /* cleanup */
+  Curl_mbedtls_version,             /* version */
+  Curl_none_check_cxn,              /* check_cxn */
+  Curl_none_shutdown,               /* shutdown */
+  Curl_mbedtls_data_pending,        /* data_pending */
+  Curl_mbedtls_random,              /* random */
+  Curl_none_cert_status_request,    /* cert_status_request */
+  Curl_mbedtls_connect,             /* connect */
+  Curl_mbedtls_connect_nonblocking, /* connect_nonblocking */
+  Curl_mbedtls_get_internals,       /* get_internals */
+  Curl_mbedtls_close,               /* close_one */
+  Curl_mbedtls_close_all,           /* close_all */
+  Curl_mbedtls_session_free,        /* session_free */
+  Curl_none_set_engine,             /* set_engine */
+  Curl_none_set_engine_default,     /* set_engine_default */
+  Curl_none_engines_list,           /* engines_list */
+  Curl_none_false_start,            /* false_start */
+  Curl_none_md5sum,                 /* md5sum */
+  Curl_mbedtls_sha256sum            /* sha256sum */
+};
+
+#endif /* USE_MBEDTLS */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/mbedtls.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/mbedtls.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/mbedtls.h	(revision 331)
@@ -0,0 +1,32 @@
+#ifndef HEADER_CURL_MBEDTLS_H
+#define HEADER_CURL_MBEDTLS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_MBEDTLS
+
+extern const struct Curl_ssl Curl_ssl_mbedtls;
+
+#endif /* USE_MBEDTLS */
+#endif /* HEADER_CURL_MBEDTLS_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/nss.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/nss.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/nss.c	(revision 331)
@@ -0,0 +1,2380 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all NSS-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_NSS
+
+#include "urldata.h"
+#include "sendf.h"
+#include "formdata.h" /* for the boundary function */
+#include "url.h" /* for the ssl config check function */
+#include "connect.h"
+#include "strcase.h"
+#include "select.h"
+#include "vtls.h"
+#include "llist.h"
+#include "curl_printf.h"
+#include "nssg.h"
+#include <nspr.h>
+#include <nss.h>
+#include <ssl.h>
+#include <sslerr.h>
+#include <secerr.h>
+#include <secmod.h>
+#include <sslproto.h>
+#include <prtypes.h>
+#include <pk11pub.h>
+#include <prio.h>
+#include <secitem.h>
+#include <secport.h>
+#include <certdb.h>
+#include <base64.h>
+#include <cert.h>
+#include <prerror.h>
+#include <keyhi.h>         /* for SECKEY_DestroyPublicKey() */
+#include <private/pprio.h> /* for PR_ImportTCPSocket */
+
+#define NSSVERNUM ((NSS_VMAJOR<<16)|(NSS_VMINOR<<8)|NSS_VPATCH)
+
+#if NSSVERNUM >= 0x030f00 /* 3.15.0 */
+#include <ocsp.h>
+#endif
+
+#include "strcase.h"
+#include "warnless.h"
+#include "x509asn1.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#define SSL_DIR "/etc/pki/nssdb"
+
+/* enough to fit the string "PEM Token #[0|1]" */
+#define SLOTSIZE 13
+
+struct ssl_backend_data {
+  PRFileDesc *handle;
+  char *client_nickname;
+  struct Curl_easy *data;
+  struct curl_llist obj_list;
+  PK11GenericObject *obj_clicert;
+};
+
+#define BACKEND connssl->backend
+
+static PRLock *nss_initlock = NULL;
+static PRLock *nss_crllock = NULL;
+static PRLock *nss_findslot_lock = NULL;
+static PRLock *nss_trustload_lock = NULL;
+static struct curl_llist nss_crl_list;
+static NSSInitContext *nss_context = NULL;
+static volatile int initialized = 0;
+
+/* type used to wrap pointers as list nodes */
+struct ptr_list_wrap {
+  void *ptr;
+  struct curl_llist_element node;
+};
+
+typedef struct {
+  const char *name;
+  int num;
+} cipher_s;
+
+#define PK11_SETATTRS(_attr, _idx, _type, _val, _len) do {  \
+  CK_ATTRIBUTE *ptr = (_attr) + ((_idx)++);                 \
+  ptr->type = (_type);                                      \
+  ptr->pValue = (_val);                                     \
+  ptr->ulValueLen = (_len);                                 \
+} WHILE_FALSE
+
+#define CERT_NewTempCertificate __CERT_NewTempCertificate
+
+#define NUM_OF_CIPHERS sizeof(cipherlist)/sizeof(cipherlist[0])
+static const cipher_s cipherlist[] = {
+  /* SSL2 cipher suites */
+  {"rc4",                        SSL_EN_RC4_128_WITH_MD5},
+  {"rc4-md5",                    SSL_EN_RC4_128_WITH_MD5},
+  {"rc4export",                  SSL_EN_RC4_128_EXPORT40_WITH_MD5},
+  {"rc2",                        SSL_EN_RC2_128_CBC_WITH_MD5},
+  {"rc2export",                  SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5},
+  {"des",                        SSL_EN_DES_64_CBC_WITH_MD5},
+  {"desede3",                    SSL_EN_DES_192_EDE3_CBC_WITH_MD5},
+  /* SSL3/TLS cipher suites */
+  {"rsa_rc4_128_md5",            SSL_RSA_WITH_RC4_128_MD5},
+  {"rsa_rc4_128_sha",            SSL_RSA_WITH_RC4_128_SHA},
+  {"rsa_3des_sha",               SSL_RSA_WITH_3DES_EDE_CBC_SHA},
+  {"rsa_des_sha",                SSL_RSA_WITH_DES_CBC_SHA},
+  {"rsa_rc4_40_md5",             SSL_RSA_EXPORT_WITH_RC4_40_MD5},
+  {"rsa_rc2_40_md5",             SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5},
+  {"rsa_null_md5",               SSL_RSA_WITH_NULL_MD5},
+  {"rsa_null_sha",               SSL_RSA_WITH_NULL_SHA},
+  {"fips_3des_sha",              SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA},
+  {"fips_des_sha",               SSL_RSA_FIPS_WITH_DES_CBC_SHA},
+  {"fortezza",                   SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA},
+  {"fortezza_rc4_128_sha",       SSL_FORTEZZA_DMS_WITH_RC4_128_SHA},
+  {"fortezza_null",              SSL_FORTEZZA_DMS_WITH_NULL_SHA},
+  /* TLS 1.0: Exportable 56-bit Cipher Suites. */
+  {"rsa_des_56_sha",             TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA},
+  {"rsa_rc4_56_sha",             TLS_RSA_EXPORT1024_WITH_RC4_56_SHA},
+  /* AES ciphers. */
+  {"dhe_dss_aes_128_cbc_sha",    TLS_DHE_DSS_WITH_AES_128_CBC_SHA},
+  {"dhe_dss_aes_256_cbc_sha",    TLS_DHE_DSS_WITH_AES_256_CBC_SHA},
+  {"dhe_rsa_aes_128_cbc_sha",    TLS_DHE_RSA_WITH_AES_128_CBC_SHA},
+  {"dhe_rsa_aes_256_cbc_sha",    TLS_DHE_RSA_WITH_AES_256_CBC_SHA},
+  {"rsa_aes_128_sha",            TLS_RSA_WITH_AES_128_CBC_SHA},
+  {"rsa_aes_256_sha",            TLS_RSA_WITH_AES_256_CBC_SHA},
+  /* ECC ciphers. */
+  {"ecdh_ecdsa_null_sha",        TLS_ECDH_ECDSA_WITH_NULL_SHA},
+  {"ecdh_ecdsa_rc4_128_sha",     TLS_ECDH_ECDSA_WITH_RC4_128_SHA},
+  {"ecdh_ecdsa_3des_sha",        TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA},
+  {"ecdh_ecdsa_aes_128_sha",     TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA},
+  {"ecdh_ecdsa_aes_256_sha",     TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA},
+  {"ecdhe_ecdsa_null_sha",       TLS_ECDHE_ECDSA_WITH_NULL_SHA},
+  {"ecdhe_ecdsa_rc4_128_sha",    TLS_ECDHE_ECDSA_WITH_RC4_128_SHA},
+  {"ecdhe_ecdsa_3des_sha",       TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA},
+  {"ecdhe_ecdsa_aes_128_sha",    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA},
+  {"ecdhe_ecdsa_aes_256_sha",    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
+  {"ecdh_rsa_null_sha",          TLS_ECDH_RSA_WITH_NULL_SHA},
+  {"ecdh_rsa_128_sha",           TLS_ECDH_RSA_WITH_RC4_128_SHA},
+  {"ecdh_rsa_3des_sha",          TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA},
+  {"ecdh_rsa_aes_128_sha",       TLS_ECDH_RSA_WITH_AES_128_CBC_SHA},
+  {"ecdh_rsa_aes_256_sha",       TLS_ECDH_RSA_WITH_AES_256_CBC_SHA},
+  {"ecdhe_rsa_null",             TLS_ECDHE_RSA_WITH_NULL_SHA},
+  {"ecdhe_rsa_rc4_128_sha",      TLS_ECDHE_RSA_WITH_RC4_128_SHA},
+  {"ecdhe_rsa_3des_sha",         TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA},
+  {"ecdhe_rsa_aes_128_sha",      TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
+  {"ecdhe_rsa_aes_256_sha",      TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
+  {"ecdh_anon_null_sha",         TLS_ECDH_anon_WITH_NULL_SHA},
+  {"ecdh_anon_rc4_128sha",       TLS_ECDH_anon_WITH_RC4_128_SHA},
+  {"ecdh_anon_3des_sha",         TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA},
+  {"ecdh_anon_aes_128_sha",      TLS_ECDH_anon_WITH_AES_128_CBC_SHA},
+  {"ecdh_anon_aes_256_sha",      TLS_ECDH_anon_WITH_AES_256_CBC_SHA},
+#ifdef TLS_RSA_WITH_NULL_SHA256
+  /* new HMAC-SHA256 cipher suites specified in RFC */
+  {"rsa_null_sha_256",                TLS_RSA_WITH_NULL_SHA256},
+  {"rsa_aes_128_cbc_sha_256",         TLS_RSA_WITH_AES_128_CBC_SHA256},
+  {"rsa_aes_256_cbc_sha_256",         TLS_RSA_WITH_AES_256_CBC_SHA256},
+  {"dhe_rsa_aes_128_cbc_sha_256",     TLS_DHE_RSA_WITH_AES_128_CBC_SHA256},
+  {"dhe_rsa_aes_256_cbc_sha_256",     TLS_DHE_RSA_WITH_AES_256_CBC_SHA256},
+  {"ecdhe_ecdsa_aes_128_cbc_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
+  {"ecdhe_rsa_aes_128_cbc_sha_256",   TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256},
+#endif
+#ifdef TLS_RSA_WITH_AES_128_GCM_SHA256
+  /* AES GCM cipher suites in RFC 5288 and RFC 5289 */
+  {"rsa_aes_128_gcm_sha_256",         TLS_RSA_WITH_AES_128_GCM_SHA256},
+  {"dhe_rsa_aes_128_gcm_sha_256",     TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
+  {"dhe_dss_aes_128_gcm_sha_256",     TLS_DHE_DSS_WITH_AES_128_GCM_SHA256},
+  {"ecdhe_ecdsa_aes_128_gcm_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+  {"ecdh_ecdsa_aes_128_gcm_sha_256",  TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256},
+  {"ecdhe_rsa_aes_128_gcm_sha_256",   TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+  {"ecdh_rsa_aes_128_gcm_sha_256",    TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256},
+#endif
+#ifdef TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+  /* cipher suites using SHA384 */
+  {"rsa_aes_256_gcm_sha_384",         TLS_RSA_WITH_AES_256_GCM_SHA384},
+  {"dhe_rsa_aes_256_gcm_sha_384",     TLS_DHE_RSA_WITH_AES_256_GCM_SHA384},
+  {"dhe_dss_aes_256_gcm_sha_384",     TLS_DHE_DSS_WITH_AES_256_GCM_SHA384},
+  {"ecdhe_ecdsa_aes_256_sha_384",     TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384},
+  {"ecdhe_rsa_aes_256_sha_384",       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384},
+  {"ecdhe_ecdsa_aes_256_gcm_sha_384", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384},
+  {"ecdhe_rsa_aes_256_gcm_sha_384",   TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
+#endif
+#ifdef TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+  /* chacha20-poly1305 cipher suites */
+ {"ecdhe_rsa_chacha20_poly1305_sha_256",
+     TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
+ {"ecdhe_ecdsa_chacha20_poly1305_sha_256",
+     TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256},
+ {"dhe_rsa_chacha20_poly1305_sha_256",
+     TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
+#endif
+};
+
+static const char *pem_library = "libnsspem.so";
+static SECMODModule *pem_module = NULL;
+
+static const char *trust_library = "libnssckbi.so";
+static SECMODModule *trust_module = NULL;
+
+/* NSPR I/O layer we use to detect blocking direction during SSL handshake */
+static PRDescIdentity nspr_io_identity = PR_INVALID_IO_LAYER;
+static PRIOMethods nspr_io_methods;
+
+static const char *nss_error_to_name(PRErrorCode code)
+{
+  const char *name = PR_ErrorToName(code);
+  if(name)
+    return name;
+
+  return "unknown error";
+}
+
+static void nss_print_error_message(struct Curl_easy *data, PRUint32 err)
+{
+  failf(data, "%s", PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT));
+}
+
+static SECStatus set_ciphers(struct Curl_easy *data, PRFileDesc * model,
+                             char *cipher_list)
+{
+  unsigned int i;
+  PRBool cipher_state[NUM_OF_CIPHERS];
+  PRBool found;
+  char *cipher;
+
+  /* use accessors to avoid dynamic linking issues after an update of NSS */
+  const PRUint16 num_implemented_ciphers = SSL_GetNumImplementedCiphers();
+  const PRUint16 *implemented_ciphers = SSL_GetImplementedCiphers();
+  if(!implemented_ciphers)
+    return SECFailure;
+
+  /* First disable all ciphers. This uses a different max value in case
+   * NSS adds more ciphers later we don't want them available by
+   * accident
+   */
+  for(i = 0; i < num_implemented_ciphers; i++) {
+    SSL_CipherPrefSet(model, implemented_ciphers[i], PR_FALSE);
+  }
+
+  /* Set every entry in our list to false */
+  for(i = 0; i < NUM_OF_CIPHERS; i++) {
+    cipher_state[i] = PR_FALSE;
+  }
+
+  cipher = cipher_list;
+
+  while(cipher_list && (cipher_list[0])) {
+    while((*cipher) && (ISSPACE(*cipher)))
+      ++cipher;
+
+    cipher_list = strchr(cipher, ',');
+    if(cipher_list) {
+      *cipher_list++ = '\0';
+    }
+
+    found = PR_FALSE;
+
+    for(i = 0; i<NUM_OF_CIPHERS; i++) {
+      if(strcasecompare(cipher, cipherlist[i].name)) {
+        cipher_state[i] = PR_TRUE;
+        found = PR_TRUE;
+        break;
+      }
+    }
+
+    if(found == PR_FALSE) {
+      failf(data, "Unknown cipher in list: %s", cipher);
+      return SECFailure;
+    }
+
+    if(cipher_list) {
+      cipher = cipher_list;
+    }
+  }
+
+  /* Finally actually enable the selected ciphers */
+  for(i = 0; i<NUM_OF_CIPHERS; i++) {
+    if(!cipher_state[i])
+      continue;
+
+    if(SSL_CipherPrefSet(model, cipherlist[i].num, PR_TRUE) != SECSuccess) {
+      failf(data, "cipher-suite not supported by NSS: %s", cipherlist[i].name);
+      return SECFailure;
+    }
+  }
+
+  return SECSuccess;
+}
+
+/*
+ * Return true if at least one cipher-suite is enabled. Used to determine
+ * if we need to call NSS_SetDomesticPolicy() to enable the default ciphers.
+ */
+static bool any_cipher_enabled(void)
+{
+  unsigned int i;
+
+  for(i = 0; i<NUM_OF_CIPHERS; i++) {
+    PRInt32 policy = 0;
+    SSL_CipherPolicyGet(cipherlist[i].num, &policy);
+    if(policy)
+      return TRUE;
+  }
+
+  return FALSE;
+}
+
+/*
+ * Determine whether the nickname passed in is a filename that needs to
+ * be loaded as a PEM or a regular NSS nickname.
+ *
+ * returns 1 for a file
+ * returns 0 for not a file (NSS nickname)
+ */
+static int is_file(const char *filename)
+{
+  struct_stat st;
+
+  if(filename == NULL)
+    return 0;
+
+  if(stat(filename, &st) == 0)
+    if(S_ISREG(st.st_mode))
+      return 1;
+
+  return 0;
+}
+
+/* Check if the given string is filename or nickname of a certificate.  If the
+ * given string is recognized as filename, return NULL.  If the given string is
+ * recognized as nickname, return a duplicated string.  The returned string
+ * should be later deallocated using free().  If the OOM failure occurs, we
+ * return NULL, too.
+ */
+static char *dup_nickname(struct Curl_easy *data, const char *str)
+{
+  const char *n;
+
+  if(!is_file(str))
+    /* no such file exists, use the string as nickname */
+    return strdup(str);
+
+  /* search the first slash; we require at least one slash in a file name */
+  n = strchr(str, '/');
+  if(!n) {
+    infof(data, "warning: certificate file name \"%s\" handled as nickname; "
+          "please use \"./%s\" to force file name\n", str, str);
+    return strdup(str);
+  }
+
+  /* we'll use the PEM reader to read the certificate from file */
+  return NULL;
+}
+
+/* Lock/unlock wrapper for PK11_FindSlotByName() to work around race condition
+ * in nssSlot_IsTokenPresent() causing spurious SEC_ERROR_NO_TOKEN.  For more
+ * details, go to <https://bugzilla.mozilla.org/1297397>.
+ */
+static PK11SlotInfo* nss_find_slot_by_name(const char *slot_name)
+{
+  PK11SlotInfo *slot;
+  PR_Lock(nss_findslot_lock);
+  slot = PK11_FindSlotByName(slot_name);
+  PR_Unlock(nss_findslot_lock);
+  return slot;
+}
+
+/* wrap 'ptr' as list node and tail-insert into 'list' */
+static CURLcode insert_wrapped_ptr(struct curl_llist *list, void *ptr)
+{
+  struct ptr_list_wrap *wrap = malloc(sizeof *wrap);
+  if(!wrap)
+    return CURLE_OUT_OF_MEMORY;
+
+  wrap->ptr = ptr;
+  Curl_llist_insert_next(list, list->tail, wrap, &wrap->node);
+  return CURLE_OK;
+}
+
+/* Call PK11_CreateGenericObject() with the given obj_class and filename.  If
+ * the call succeeds, append the object handle to the list of objects so that
+ * the object can be destroyed in Curl_nss_close(). */
+static CURLcode nss_create_object(struct ssl_connect_data *connssl,
+                                  CK_OBJECT_CLASS obj_class,
+                                  const char *filename, bool cacert)
+{
+  PK11SlotInfo *slot;
+  PK11GenericObject *obj;
+  CK_BBOOL cktrue = CK_TRUE;
+  CK_BBOOL ckfalse = CK_FALSE;
+  CK_ATTRIBUTE attrs[/* max count of attributes */ 4];
+  int attr_cnt = 0;
+  CURLcode result = (cacert)
+    ? CURLE_SSL_CACERT_BADFILE
+    : CURLE_SSL_CERTPROBLEM;
+
+  const int slot_id = (cacert) ? 0 : 1;
+  char *slot_name = aprintf("PEM Token #%d", slot_id);
+  if(!slot_name)
+    return CURLE_OUT_OF_MEMORY;
+
+  slot = nss_find_slot_by_name(slot_name);
+  free(slot_name);
+  if(!slot)
+    return result;
+
+  PK11_SETATTRS(attrs, attr_cnt, CKA_CLASS, &obj_class, sizeof(obj_class));
+  PK11_SETATTRS(attrs, attr_cnt, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL));
+  PK11_SETATTRS(attrs, attr_cnt, CKA_LABEL, (unsigned char *)filename,
+                (CK_ULONG)strlen(filename) + 1);
+
+  if(CKO_CERTIFICATE == obj_class) {
+    CK_BBOOL *pval = (cacert) ? (&cktrue) : (&ckfalse);
+    PK11_SETATTRS(attrs, attr_cnt, CKA_TRUST, pval, sizeof(*pval));
+  }
+
+  obj = PK11_CreateGenericObject(slot, attrs, attr_cnt, PR_FALSE);
+  PK11_FreeSlot(slot);
+  if(!obj)
+    return result;
+
+  if(insert_wrapped_ptr(&BACKEND->obj_list, obj) != CURLE_OK) {
+    PK11_DestroyGenericObject(obj);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  if(!cacert && CKO_CERTIFICATE == obj_class)
+    /* store reference to a client certificate */
+    BACKEND->obj_clicert = obj;
+
+  return CURLE_OK;
+}
+
+/* Destroy the NSS object whose handle is given by ptr.  This function is
+ * a callback of Curl_llist_alloc() used by Curl_llist_destroy() to destroy
+ * NSS objects in Curl_nss_close() */
+static void nss_destroy_object(void *user, void *ptr)
+{
+  struct ptr_list_wrap *wrap = (struct ptr_list_wrap *) ptr;
+  PK11GenericObject *obj = (PK11GenericObject *) wrap->ptr;
+  (void) user;
+  PK11_DestroyGenericObject(obj);
+  free(wrap);
+}
+
+/* same as nss_destroy_object() but for CRL items */
+static void nss_destroy_crl_item(void *user, void *ptr)
+{
+  struct ptr_list_wrap *wrap = (struct ptr_list_wrap *) ptr;
+  SECItem *crl_der = (SECItem *) wrap->ptr;
+  (void) user;
+  SECITEM_FreeItem(crl_der, PR_TRUE);
+  free(wrap);
+}
+
+static CURLcode nss_load_cert(struct ssl_connect_data *ssl,
+                              const char *filename, PRBool cacert)
+{
+  CURLcode result = (cacert)
+    ? CURLE_SSL_CACERT_BADFILE
+    : CURLE_SSL_CERTPROBLEM;
+
+  /* libnsspem.so leaks memory if the requested file does not exist.  For more
+   * details, go to <https://bugzilla.redhat.com/734760>. */
+  if(is_file(filename))
+    result = nss_create_object(ssl, CKO_CERTIFICATE, filename, cacert);
+
+  if(!result && !cacert) {
+    /* we have successfully loaded a client certificate */
+    CERTCertificate *cert;
+    char *nickname = NULL;
+    char *n = strrchr(filename, '/');
+    if(n)
+      n++;
+
+    /* The following undocumented magic helps to avoid a SIGSEGV on call
+     * of PK11_ReadRawAttribute() from SelectClientCert() when using an
+     * immature version of libnsspem.so.  For more details, go to
+     * <https://bugzilla.redhat.com/733685>. */
+    nickname = aprintf("PEM Token #1:%s", n);
+    if(nickname) {
+      cert = PK11_FindCertFromNickname(nickname, NULL);
+      if(cert)
+        CERT_DestroyCertificate(cert);
+
+      free(nickname);
+    }
+  }
+
+  return result;
+}
+
+/* add given CRL to cache if it is not already there */
+static CURLcode nss_cache_crl(SECItem *crl_der)
+{
+  CERTCertDBHandle *db = CERT_GetDefaultCertDB();
+  CERTSignedCrl *crl = SEC_FindCrlByDERCert(db, crl_der, 0);
+  if(crl) {
+    /* CRL already cached */
+    SEC_DestroyCrl(crl);
+    SECITEM_FreeItem(crl_der, PR_TRUE);
+    return CURLE_OK;
+  }
+
+  /* acquire lock before call of CERT_CacheCRL() and accessing nss_crl_list */
+  PR_Lock(nss_crllock);
+
+  /* store the CRL item so that we can free it in Curl_nss_cleanup() */
+  if(insert_wrapped_ptr(&nss_crl_list, crl_der) != CURLE_OK) {
+    SECITEM_FreeItem(crl_der, PR_TRUE);
+    PR_Unlock(nss_crllock);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  if(SECSuccess != CERT_CacheCRL(db, crl_der)) {
+    /* unable to cache CRL */
+    PR_Unlock(nss_crllock);
+    return CURLE_SSL_CRL_BADFILE;
+  }
+
+  /* we need to clear session cache, so that the CRL could take effect */
+  SSL_ClearSessionCache();
+  PR_Unlock(nss_crllock);
+  return CURLE_OK;
+}
+
+static CURLcode nss_load_crl(const char *crlfilename)
+{
+  PRFileDesc *infile;
+  PRFileInfo  info;
+  SECItem filedata = { 0, NULL, 0 };
+  SECItem *crl_der = NULL;
+  char *body;
+
+  infile = PR_Open(crlfilename, PR_RDONLY, 0);
+  if(!infile)
+    return CURLE_SSL_CRL_BADFILE;
+
+  if(PR_SUCCESS != PR_GetOpenFileInfo(infile, &info))
+    goto fail;
+
+  if(!SECITEM_AllocItem(NULL, &filedata, info.size + /* zero ended */ 1))
+    goto fail;
+
+  if(info.size != PR_Read(infile, filedata.data, info.size))
+    goto fail;
+
+  crl_der = SECITEM_AllocItem(NULL, NULL, 0U);
+  if(!crl_der)
+    goto fail;
+
+  /* place a trailing zero right after the visible data */
+  body = (char *)filedata.data;
+  body[--filedata.len] = '\0';
+
+  body = strstr(body, "-----BEGIN");
+  if(body) {
+    /* assume ASCII */
+    char *trailer;
+    char *begin = PORT_Strchr(body, '\n');
+    if(!begin)
+      begin = PORT_Strchr(body, '\r');
+    if(!begin)
+      goto fail;
+
+    trailer = strstr(++begin, "-----END");
+    if(!trailer)
+      goto fail;
+
+    /* retrieve DER from ASCII */
+    *trailer = '\0';
+    if(ATOB_ConvertAsciiToItem(crl_der, begin))
+      goto fail;
+
+    SECITEM_FreeItem(&filedata, PR_FALSE);
+  }
+  else
+    /* assume DER */
+    *crl_der = filedata;
+
+  PR_Close(infile);
+  return nss_cache_crl(crl_der);
+
+fail:
+  PR_Close(infile);
+  SECITEM_FreeItem(crl_der, PR_TRUE);
+  SECITEM_FreeItem(&filedata, PR_FALSE);
+  return CURLE_SSL_CRL_BADFILE;
+}
+
+static CURLcode nss_load_key(struct connectdata *conn, int sockindex,
+                             char *key_file)
+{
+  PK11SlotInfo *slot, *tmp;
+  SECStatus status;
+  CURLcode result;
+  struct ssl_connect_data *ssl = conn->ssl;
+  struct Curl_easy *data = conn->data;
+
+  (void)sockindex; /* unused */
+
+  result = nss_create_object(ssl, CKO_PRIVATE_KEY, key_file, FALSE);
+  if(result) {
+    PR_SetError(SEC_ERROR_BAD_KEY, 0);
+    return result;
+  }
+
+  slot = nss_find_slot_by_name("PEM Token #1");
+  if(!slot)
+    return CURLE_SSL_CERTPROBLEM;
+
+  /* This will force the token to be seen as re-inserted */
+  tmp = SECMOD_WaitForAnyTokenEvent(pem_module, 0, 0);
+  if(tmp)
+    PK11_FreeSlot(tmp);
+  PK11_IsPresent(slot);
+
+  status = PK11_Authenticate(slot, PR_TRUE, SSL_SET_OPTION(key_passwd));
+  PK11_FreeSlot(slot);
+
+  return (SECSuccess == status) ? CURLE_OK : CURLE_SSL_CERTPROBLEM;
+}
+
+static int display_error(struct connectdata *conn, PRInt32 err,
+                         const char *filename)
+{
+  switch(err) {
+  case SEC_ERROR_BAD_PASSWORD:
+    failf(conn->data, "Unable to load client key: Incorrect password");
+    return 1;
+  case SEC_ERROR_UNKNOWN_CERT:
+    failf(conn->data, "Unable to load certificate %s", filename);
+    return 1;
+  default:
+    break;
+  }
+  return 0; /* The caller will print a generic error */
+}
+
+static CURLcode cert_stuff(struct connectdata *conn, int sockindex,
+                           char *cert_file, char *key_file)
+{
+  struct Curl_easy *data = conn->data;
+  CURLcode result;
+
+  if(cert_file) {
+    result = nss_load_cert(&conn->ssl[sockindex], cert_file, PR_FALSE);
+    if(result) {
+      const PRErrorCode err = PR_GetError();
+      if(!display_error(conn, err, cert_file)) {
+        const char *err_name = nss_error_to_name(err);
+        failf(data, "unable to load client cert: %d (%s)", err, err_name);
+      }
+
+      return result;
+    }
+  }
+
+  if(key_file || (is_file(cert_file))) {
+    if(key_file)
+      result = nss_load_key(conn, sockindex, key_file);
+    else
+      /* In case the cert file also has the key */
+      result = nss_load_key(conn, sockindex, cert_file);
+    if(result) {
+      const PRErrorCode err = PR_GetError();
+      if(!display_error(conn, err, key_file)) {
+        const char *err_name = nss_error_to_name(err);
+        failf(data, "unable to load client key: %d (%s)", err, err_name);
+      }
+
+      return result;
+    }
+  }
+
+  return CURLE_OK;
+}
+
+static char *nss_get_password(PK11SlotInfo *slot, PRBool retry, void *arg)
+{
+  (void)slot; /* unused */
+
+  if(retry || NULL == arg)
+    return NULL;
+  else
+    return (char *)PORT_Strdup((char *)arg);
+}
+
+/* bypass the default SSL_AuthCertificate() hook in case we do not want to
+ * verify peer */
+static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig,
+                                    PRBool isServer)
+{
+  struct connectdata *conn = (struct connectdata *)arg;
+
+#ifdef SSL_ENABLE_OCSP_STAPLING
+  if(SSL_CONN_CONFIG(verifystatus)) {
+    SECStatus cacheResult;
+
+    const SECItemArray *csa = SSL_PeerStapledOCSPResponses(fd);
+    if(!csa) {
+      failf(conn->data, "Invalid OCSP response");
+      return SECFailure;
+    }
+
+    if(csa->len == 0) {
+      failf(conn->data, "No OCSP response received");
+      return SECFailure;
+    }
+
+    cacheResult = CERT_CacheOCSPResponseFromSideChannel(
+      CERT_GetDefaultCertDB(), SSL_PeerCertificate(fd),
+      PR_Now(), &csa->items[0], arg
+    );
+
+    if(cacheResult != SECSuccess) {
+      failf(conn->data, "Invalid OCSP response");
+      return cacheResult;
+    }
+  }
+#endif
+
+  if(!SSL_CONN_CONFIG(verifypeer)) {
+    infof(conn->data, "skipping SSL peer certificate verification\n");
+    return SECSuccess;
+  }
+
+  return SSL_AuthCertificate(CERT_GetDefaultCertDB(), fd, checksig, isServer);
+}
+
+/**
+ * Inform the application that the handshake is complete.
+ */
+static void HandshakeCallback(PRFileDesc *sock, void *arg)
+{
+  struct connectdata *conn = (struct connectdata*) arg;
+  unsigned int buflenmax = 50;
+  unsigned char buf[50];
+  unsigned int buflen;
+  SSLNextProtoState state;
+
+  if(!conn->bits.tls_enable_npn && !conn->bits.tls_enable_alpn) {
+    return;
+  }
+
+  if(SSL_GetNextProto(sock, &state, buf, &buflen, buflenmax) == SECSuccess) {
+
+    switch(state) {
+#if NSSVERNUM >= 0x031a00 /* 3.26.0 */
+    /* used by NSS internally to implement 0-RTT */
+    case SSL_NEXT_PROTO_EARLY_VALUE:
+      /* fall through! */
+#endif
+    case SSL_NEXT_PROTO_NO_SUPPORT:
+    case SSL_NEXT_PROTO_NO_OVERLAP:
+      infof(conn->data, "ALPN/NPN, server did not agree to a protocol\n");
+      return;
+#ifdef SSL_ENABLE_ALPN
+    case SSL_NEXT_PROTO_SELECTED:
+      infof(conn->data, "ALPN, server accepted to use %.*s\n", buflen, buf);
+      break;
+#endif
+    case SSL_NEXT_PROTO_NEGOTIATED:
+      infof(conn->data, "NPN, server accepted to use %.*s\n", buflen, buf);
+      break;
+    }
+
+#ifdef USE_NGHTTP2
+    if(buflen == NGHTTP2_PROTO_VERSION_ID_LEN &&
+       !memcmp(NGHTTP2_PROTO_VERSION_ID, buf, NGHTTP2_PROTO_VERSION_ID_LEN)) {
+      conn->negnpn = CURL_HTTP_VERSION_2;
+    }
+    else
+#endif
+    if(buflen == ALPN_HTTP_1_1_LENGTH &&
+       !memcmp(ALPN_HTTP_1_1, buf, ALPN_HTTP_1_1_LENGTH)) {
+      conn->negnpn = CURL_HTTP_VERSION_1_1;
+    }
+  }
+}
+
+#if NSSVERNUM >= 0x030f04 /* 3.15.4 */
+static SECStatus CanFalseStartCallback(PRFileDesc *sock, void *client_data,
+                                       PRBool *canFalseStart)
+{
+  struct connectdata *conn = client_data;
+  struct Curl_easy *data = conn->data;
+
+  SSLChannelInfo channelInfo;
+  SSLCipherSuiteInfo cipherInfo;
+
+  SECStatus rv;
+  PRBool negotiatedExtension;
+
+  *canFalseStart = PR_FALSE;
+
+  if(SSL_GetChannelInfo(sock, &channelInfo, sizeof(channelInfo)) != SECSuccess)
+    return SECFailure;
+
+  if(SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
+                            sizeof(cipherInfo)) != SECSuccess)
+    return SECFailure;
+
+  /* Prevent version downgrade attacks from TLS 1.2, and avoid False Start for
+   * TLS 1.3 and later. See https://bugzilla.mozilla.org/show_bug.cgi?id=861310
+   */
+  if(channelInfo.protocolVersion != SSL_LIBRARY_VERSION_TLS_1_2)
+    goto end;
+
+  /* Only allow ECDHE key exchange algorithm.
+   * See https://bugzilla.mozilla.org/show_bug.cgi?id=952863 */
+  if(cipherInfo.keaType != ssl_kea_ecdh)
+    goto end;
+
+  /* Prevent downgrade attacks on the symmetric cipher. We do not allow CBC
+   * mode due to BEAST, POODLE, and other attacks on the MAC-then-Encrypt
+   * design. See https://bugzilla.mozilla.org/show_bug.cgi?id=1109766 */
+  if(cipherInfo.symCipher != ssl_calg_aes_gcm)
+    goto end;
+
+  /* Enforce ALPN or NPN to do False Start, as an indicator of server
+   * compatibility. */
+  rv = SSL_HandshakeNegotiatedExtension(sock, ssl_app_layer_protocol_xtn,
+                                        &negotiatedExtension);
+  if(rv != SECSuccess || !negotiatedExtension) {
+    rv = SSL_HandshakeNegotiatedExtension(sock, ssl_next_proto_nego_xtn,
+                                          &negotiatedExtension);
+  }
+
+  if(rv != SECSuccess || !negotiatedExtension)
+    goto end;
+
+  *canFalseStart = PR_TRUE;
+
+  infof(data, "Trying TLS False Start\n");
+
+end:
+  return SECSuccess;
+}
+#endif
+
+static void display_cert_info(struct Curl_easy *data,
+                              CERTCertificate *cert)
+{
+  char *subject, *issuer, *common_name;
+  PRExplodedTime printableTime;
+  char timeString[256];
+  PRTime notBefore, notAfter;
+
+  subject = CERT_NameToAscii(&cert->subject);
+  issuer = CERT_NameToAscii(&cert->issuer);
+  common_name = CERT_GetCommonName(&cert->subject);
+  infof(data, "\tsubject: %s\n", subject);
+
+  CERT_GetCertTimes(cert, &notBefore, &notAfter);
+  PR_ExplodeTime(notBefore, PR_GMTParameters, &printableTime);
+  PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime);
+  infof(data, "\tstart date: %s\n", timeString);
+  PR_ExplodeTime(notAfter, PR_GMTParameters, &printableTime);
+  PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime);
+  infof(data, "\texpire date: %s\n", timeString);
+  infof(data, "\tcommon name: %s\n", common_name);
+  infof(data, "\tissuer: %s\n", issuer);
+
+  PR_Free(subject);
+  PR_Free(issuer);
+  PR_Free(common_name);
+}
+
+static CURLcode display_conn_info(struct connectdata *conn, PRFileDesc *sock)
+{
+  CURLcode result = CURLE_OK;
+  SSLChannelInfo channel;
+  SSLCipherSuiteInfo suite;
+  CERTCertificate *cert;
+  CERTCertificate *cert2;
+  CERTCertificate *cert3;
+  PRTime now;
+  int i;
+
+  if(SSL_GetChannelInfo(sock, &channel, sizeof channel) ==
+     SECSuccess && channel.length == sizeof channel &&
+     channel.cipherSuite) {
+    if(SSL_GetCipherSuiteInfo(channel.cipherSuite,
+                              &suite, sizeof suite) == SECSuccess) {
+      infof(conn->data, "SSL connection using %s\n", suite.cipherSuiteName);
+    }
+  }
+
+  cert = SSL_PeerCertificate(sock);
+  if(cert) {
+    infof(conn->data, "Server certificate:\n");
+
+    if(!conn->data->set.ssl.certinfo) {
+      display_cert_info(conn->data, cert);
+      CERT_DestroyCertificate(cert);
+    }
+    else {
+      /* Count certificates in chain. */
+      now = PR_Now();
+      i = 1;
+      if(!cert->isRoot) {
+        cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
+        while(cert2) {
+          i++;
+          if(cert2->isRoot) {
+            CERT_DestroyCertificate(cert2);
+            break;
+          }
+          cert3 = CERT_FindCertIssuer(cert2, now, certUsageSSLCA);
+          CERT_DestroyCertificate(cert2);
+          cert2 = cert3;
+        }
+      }
+
+      result = Curl_ssl_init_certinfo(conn->data, i);
+      if(!result) {
+        for(i = 0; cert; cert = cert2) {
+          result = Curl_extract_certinfo(conn, i++, (char *)cert->derCert.data,
+                                         (char *)cert->derCert.data +
+                                                 cert->derCert.len);
+          if(result)
+            break;
+
+          if(cert->isRoot) {
+            CERT_DestroyCertificate(cert);
+            break;
+          }
+
+          cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
+          CERT_DestroyCertificate(cert);
+        }
+      }
+    }
+  }
+
+  return result;
+}
+
+static SECStatus BadCertHandler(void *arg, PRFileDesc *sock)
+{
+  struct connectdata *conn = (struct connectdata *)arg;
+  struct Curl_easy *data = conn->data;
+  PRErrorCode err = PR_GetError();
+  CERTCertificate *cert;
+
+  /* remember the cert verification result */
+  if(SSL_IS_PROXY())
+    data->set.proxy_ssl.certverifyresult = err;
+  else
+    data->set.ssl.certverifyresult = err;
+
+  if(err == SSL_ERROR_BAD_CERT_DOMAIN && !SSL_CONN_CONFIG(verifyhost))
+    /* we are asked not to verify the host name */
+    return SECSuccess;
+
+  /* print only info about the cert, the error is printed off the callback */
+  cert = SSL_PeerCertificate(sock);
+  if(cert) {
+    infof(data, "Server certificate:\n");
+    display_cert_info(data, cert);
+    CERT_DestroyCertificate(cert);
+  }
+
+  return SECFailure;
+}
+
+/**
+ *
+ * Check that the Peer certificate's issuer certificate matches the one found
+ * by issuer_nickname.  This is not exactly the way OpenSSL and GNU TLS do the
+ * issuer check, so we provide comments that mimic the OpenSSL
+ * X509_check_issued function (in x509v3/v3_purp.c)
+ */
+static SECStatus check_issuer_cert(PRFileDesc *sock,
+                                   char *issuer_nickname)
+{
+  CERTCertificate *cert, *cert_issuer, *issuer;
+  SECStatus res = SECSuccess;
+  void *proto_win = NULL;
+
+  cert = SSL_PeerCertificate(sock);
+  cert_issuer = CERT_FindCertIssuer(cert, PR_Now(), certUsageObjectSigner);
+
+  proto_win = SSL_RevealPinArg(sock);
+  issuer = PK11_FindCertFromNickname(issuer_nickname, proto_win);
+
+  if((!cert_issuer) || (!issuer))
+    res = SECFailure;
+  else if(SECITEM_CompareItem(&cert_issuer->derCert,
+                              &issuer->derCert) != SECEqual)
+    res = SECFailure;
+
+  CERT_DestroyCertificate(cert);
+  CERT_DestroyCertificate(issuer);
+  CERT_DestroyCertificate(cert_issuer);
+  return res;
+}
+
+static CURLcode cmp_peer_pubkey(struct ssl_connect_data *connssl,
+                                const char *pinnedpubkey)
+{
+  CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+  struct Curl_easy *data = BACKEND->data;
+  CERTCertificate *cert;
+
+  if(!pinnedpubkey)
+    /* no pinned public key specified */
+    return CURLE_OK;
+
+  /* get peer certificate */
+  cert = SSL_PeerCertificate(BACKEND->handle);
+  if(cert) {
+    /* extract public key from peer certificate */
+    SECKEYPublicKey *pubkey = CERT_ExtractPublicKey(cert);
+    if(pubkey) {
+      /* encode the public key as DER */
+      SECItem *cert_der = PK11_DEREncodePublicKey(pubkey);
+      if(cert_der) {
+        /* compare the public key with the pinned public key */
+        result = Curl_pin_peer_pubkey(data, pinnedpubkey, cert_der->data,
+                                      cert_der->len);
+        SECITEM_FreeItem(cert_der, PR_TRUE);
+      }
+      SECKEY_DestroyPublicKey(pubkey);
+    }
+    CERT_DestroyCertificate(cert);
+  }
+
+  /* report the resulting status */
+  switch(result) {
+  case CURLE_OK:
+    infof(data, "pinned public key verified successfully!\n");
+    break;
+  case CURLE_SSL_PINNEDPUBKEYNOTMATCH:
+    failf(data, "failed to verify pinned public key");
+    break;
+  default:
+    /* OOM, etc. */
+    break;
+  }
+
+  return result;
+}
+
+/**
+ *
+ * Callback to pick the SSL client certificate.
+ */
+static SECStatus SelectClientCert(void *arg, PRFileDesc *sock,
+                                  struct CERTDistNamesStr *caNames,
+                                  struct CERTCertificateStr **pRetCert,
+                                  struct SECKEYPrivateKeyStr **pRetKey)
+{
+  struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg;
+  struct Curl_easy *data = BACKEND->data;
+  const char *nickname = BACKEND->client_nickname;
+  static const char pem_slotname[] = "PEM Token #1";
+
+  if(BACKEND->obj_clicert) {
+    /* use the cert/key provided by PEM reader */
+    SECItem cert_der = { 0, NULL, 0 };
+    void *proto_win = SSL_RevealPinArg(sock);
+    struct CERTCertificateStr *cert;
+    struct SECKEYPrivateKeyStr *key;
+
+    PK11SlotInfo *slot = nss_find_slot_by_name(pem_slotname);
+    if(NULL == slot) {
+      failf(data, "NSS: PK11 slot not found: %s", pem_slotname);
+      return SECFailure;
+    }
+
+    if(PK11_ReadRawAttribute(PK11_TypeGeneric, BACKEND->obj_clicert, CKA_VALUE,
+                             &cert_der) != SECSuccess) {
+      failf(data, "NSS: CKA_VALUE not found in PK11 generic object");
+      PK11_FreeSlot(slot);
+      return SECFailure;
+    }
+
+    cert = PK11_FindCertFromDERCertItem(slot, &cert_der, proto_win);
+    SECITEM_FreeItem(&cert_der, PR_FALSE);
+    if(NULL == cert) {
+      failf(data, "NSS: client certificate from file not found");
+      PK11_FreeSlot(slot);
+      return SECFailure;
+    }
+
+    key = PK11_FindPrivateKeyFromCert(slot, cert, NULL);
+    PK11_FreeSlot(slot);
+    if(NULL == key) {
+      failf(data, "NSS: private key from file not found");
+      CERT_DestroyCertificate(cert);
+      return SECFailure;
+    }
+
+    infof(data, "NSS: client certificate from file\n");
+    display_cert_info(data, cert);
+
+    *pRetCert = cert;
+    *pRetKey = key;
+    return SECSuccess;
+  }
+
+  /* use the default NSS hook */
+  if(SECSuccess != NSS_GetClientAuthData((void *)nickname, sock, caNames,
+                                          pRetCert, pRetKey)
+      || NULL == *pRetCert) {
+
+    if(NULL == nickname)
+      failf(data, "NSS: client certificate not found (nickname not "
+            "specified)");
+    else
+      failf(data, "NSS: client certificate not found: %s", nickname);
+
+    return SECFailure;
+  }
+
+  /* get certificate nickname if any */
+  nickname = (*pRetCert)->nickname;
+  if(NULL == nickname)
+    nickname = "[unknown]";
+
+  if(!strncmp(nickname, pem_slotname, sizeof(pem_slotname) - 1U)) {
+    failf(data, "NSS: refusing previously loaded certificate from file: %s",
+          nickname);
+    return SECFailure;
+  }
+
+  if(NULL == *pRetKey) {
+    failf(data, "NSS: private key not found for certificate: %s", nickname);
+    return SECFailure;
+  }
+
+  infof(data, "NSS: using client certificate: %s\n", nickname);
+  display_cert_info(data, *pRetCert);
+  return SECSuccess;
+}
+
+/* update blocking direction in case of PR_WOULD_BLOCK_ERROR */
+static void nss_update_connecting_state(ssl_connect_state state, void *secret)
+{
+  struct ssl_connect_data *connssl = (struct ssl_connect_data *)secret;
+  if(PR_GetError() != PR_WOULD_BLOCK_ERROR)
+    /* an unrelated error is passing by */
+    return;
+
+  switch(connssl->connecting_state) {
+  case ssl_connect_2:
+  case ssl_connect_2_reading:
+  case ssl_connect_2_writing:
+    break;
+  default:
+    /* we are not called from an SSL handshake */
+    return;
+  }
+
+  /* update the state accordingly */
+  connssl->connecting_state = state;
+}
+
+/* recv() wrapper we use to detect blocking direction during SSL handshake */
+static PRInt32 nspr_io_recv(PRFileDesc *fd, void *buf, PRInt32 amount,
+                            PRIntn flags, PRIntervalTime timeout)
+{
+  const PRRecvFN recv_fn = fd->lower->methods->recv;
+  const PRInt32 rv = recv_fn(fd->lower, buf, amount, flags, timeout);
+  if(rv < 0)
+    /* check for PR_WOULD_BLOCK_ERROR and update blocking direction */
+    nss_update_connecting_state(ssl_connect_2_reading, fd->secret);
+  return rv;
+}
+
+/* send() wrapper we use to detect blocking direction during SSL handshake */
+static PRInt32 nspr_io_send(PRFileDesc *fd, const void *buf, PRInt32 amount,
+                            PRIntn flags, PRIntervalTime timeout)
+{
+  const PRSendFN send_fn = fd->lower->methods->send;
+  const PRInt32 rv = send_fn(fd->lower, buf, amount, flags, timeout);
+  if(rv < 0)
+    /* check for PR_WOULD_BLOCK_ERROR and update blocking direction */
+    nss_update_connecting_state(ssl_connect_2_writing, fd->secret);
+  return rv;
+}
+
+/* close() wrapper to avoid assertion failure due to fd->secret != NULL */
+static PRStatus nspr_io_close(PRFileDesc *fd)
+{
+  const PRCloseFN close_fn = PR_GetDefaultIOMethods()->close;
+  fd->secret = NULL;
+  return close_fn(fd);
+}
+
+/* load a PKCS #11 module */
+static CURLcode nss_load_module(SECMODModule **pmod, const char *library,
+                                const char *name)
+{
+  char *config_string;
+  SECMODModule *module = *pmod;
+  if(module)
+    /* already loaded */
+    return CURLE_OK;
+
+  config_string = aprintf("library=%s name=%s", library, name);
+  if(!config_string)
+    return CURLE_OUT_OF_MEMORY;
+
+  module = SECMOD_LoadUserModule(config_string, NULL, PR_FALSE);
+  free(config_string);
+
+  if(module && module->loaded) {
+    /* loaded successfully */
+    *pmod = module;
+    return CURLE_OK;
+  }
+
+  if(module)
+    SECMOD_DestroyModule(module);
+  return CURLE_FAILED_INIT;
+}
+
+/* unload a PKCS #11 module */
+static void nss_unload_module(SECMODModule **pmod)
+{
+  SECMODModule *module = *pmod;
+  if(!module)
+    /* not loaded */
+    return;
+
+  if(SECMOD_UnloadUserModule(module) != SECSuccess)
+    /* unload failed */
+    return;
+
+  SECMOD_DestroyModule(module);
+  *pmod = NULL;
+}
+
+/* data might be NULL */
+static CURLcode nss_init_core(struct Curl_easy *data, const char *cert_dir)
+{
+  NSSInitParameters initparams;
+
+  if(nss_context != NULL)
+    return CURLE_OK;
+
+  memset((void *) &initparams, '\0', sizeof(initparams));
+  initparams.length = sizeof(initparams);
+
+  if(cert_dir) {
+    char *certpath = aprintf("sql:%s", cert_dir);
+    if(!certpath)
+      return CURLE_OUT_OF_MEMORY;
+
+    infof(data, "Initializing NSS with certpath: %s\n", certpath);
+    nss_context = NSS_InitContext(certpath, "", "", "", &initparams,
+            NSS_INIT_READONLY | NSS_INIT_PK11RELOAD);
+    free(certpath);
+
+    if(nss_context != NULL)
+      return CURLE_OK;
+
+    infof(data, "Unable to initialize NSS database\n");
+  }
+
+  infof(data, "Initializing NSS with certpath: none\n");
+  nss_context = NSS_InitContext("", "", "", "", &initparams, NSS_INIT_READONLY
+         | NSS_INIT_NOCERTDB   | NSS_INIT_NOMODDB       | NSS_INIT_FORCEOPEN
+         | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
+  if(nss_context != NULL)
+    return CURLE_OK;
+
+  infof(data, "Unable to initialize NSS\n");
+  return CURLE_SSL_CACERT_BADFILE;
+}
+
+/* data might be NULL */
+static CURLcode nss_init(struct Curl_easy *data)
+{
+  char *cert_dir;
+  struct_stat st;
+  CURLcode result;
+
+  if(initialized)
+    return CURLE_OK;
+
+  /* list of all CRL items we need to destroy in Curl_nss_cleanup() */
+  Curl_llist_init(&nss_crl_list, nss_destroy_crl_item);
+
+  /* First we check if $SSL_DIR points to a valid dir */
+  cert_dir = getenv("SSL_DIR");
+  if(cert_dir) {
+    if((stat(cert_dir, &st) != 0) ||
+        (!S_ISDIR(st.st_mode))) {
+      cert_dir = NULL;
+    }
+  }
+
+  /* Now we check if the default location is a valid dir */
+  if(!cert_dir) {
+    if((stat(SSL_DIR, &st) == 0) &&
+        (S_ISDIR(st.st_mode))) {
+      cert_dir = (char *)SSL_DIR;
+    }
+  }
+
+  if(nspr_io_identity == PR_INVALID_IO_LAYER) {
+    /* allocate an identity for our own NSPR I/O layer */
+    nspr_io_identity = PR_GetUniqueIdentity("libcurl");
+    if(nspr_io_identity == PR_INVALID_IO_LAYER)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* the default methods just call down to the lower I/O layer */
+    memcpy(&nspr_io_methods, PR_GetDefaultIOMethods(), sizeof nspr_io_methods);
+
+    /* override certain methods in the table by our wrappers */
+    nspr_io_methods.recv  = nspr_io_recv;
+    nspr_io_methods.send  = nspr_io_send;
+    nspr_io_methods.close = nspr_io_close;
+  }
+
+  result = nss_init_core(data, cert_dir);
+  if(result)
+    return result;
+
+  if(!any_cipher_enabled())
+    NSS_SetDomesticPolicy();
+
+  initialized = 1;
+
+  return CURLE_OK;
+}
+
+/**
+ * Global SSL init
+ *
+ * @retval 0 error initializing SSL
+ * @retval 1 SSL initialized successfully
+ */
+static int Curl_nss_init(void)
+{
+  /* curl_global_init() is not thread-safe so this test is ok */
+  if(nss_initlock == NULL) {
+    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 256);
+    nss_initlock = PR_NewLock();
+    nss_crllock = PR_NewLock();
+    nss_findslot_lock = PR_NewLock();
+    nss_trustload_lock = PR_NewLock();
+  }
+
+  /* We will actually initialize NSS later */
+
+  return 1;
+}
+
+/* data might be NULL */
+CURLcode Curl_nss_force_init(struct Curl_easy *data)
+{
+  CURLcode result;
+  if(!nss_initlock) {
+    if(data)
+      failf(data, "unable to initialize NSS, curl_global_init() should have "
+                  "been called with CURL_GLOBAL_SSL or CURL_GLOBAL_ALL");
+    return CURLE_FAILED_INIT;
+  }
+
+  PR_Lock(nss_initlock);
+  result = nss_init(data);
+  PR_Unlock(nss_initlock);
+
+  return result;
+}
+
+/* Global cleanup */
+static void Curl_nss_cleanup(void)
+{
+  /* This function isn't required to be threadsafe and this is only done
+   * as a safety feature.
+   */
+  PR_Lock(nss_initlock);
+  if(initialized) {
+    /* Free references to client certificates held in the SSL session cache.
+     * Omitting this hampers destruction of the security module owning
+     * the certificates. */
+    SSL_ClearSessionCache();
+
+    nss_unload_module(&pem_module);
+    nss_unload_module(&trust_module);
+    NSS_ShutdownContext(nss_context);
+    nss_context = NULL;
+  }
+
+  /* destroy all CRL items */
+  Curl_llist_destroy(&nss_crl_list, NULL);
+
+  PR_Unlock(nss_initlock);
+
+  PR_DestroyLock(nss_initlock);
+  PR_DestroyLock(nss_crllock);
+  PR_DestroyLock(nss_findslot_lock);
+  PR_DestroyLock(nss_trustload_lock);
+  nss_initlock = NULL;
+
+  initialized = 0;
+}
+
+/*
+ * This function uses SSL_peek to determine connection status.
+ *
+ * Return codes:
+ *     1 means the connection is still in place
+ *     0 means the connection has been closed
+ *    -1 means the connection status is unknown
+ */
+static int Curl_nss_check_cxn(struct connectdata *conn)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
+  int rc;
+  char buf;
+
+  rc =
+    PR_Recv(BACKEND->handle, (void *)&buf, 1, PR_MSG_PEEK,
+            PR_SecondsToInterval(1));
+  if(rc > 0)
+    return 1; /* connection still in place */
+
+  if(rc == 0)
+    return 0; /* connection has been closed */
+
+  return -1;  /* connection status unknown */
+}
+
+static void nss_close(struct ssl_connect_data *connssl)
+{
+  /* before the cleanup, check whether we are using a client certificate */
+  const bool client_cert = (BACKEND->client_nickname != NULL)
+    || (BACKEND->obj_clicert != NULL);
+
+  free(BACKEND->client_nickname);
+  BACKEND->client_nickname = NULL;
+
+  /* destroy all NSS objects in order to avoid failure of NSS shutdown */
+  Curl_llist_destroy(&BACKEND->obj_list, NULL);
+  BACKEND->obj_clicert = NULL;
+
+  if(BACKEND->handle) {
+    if(client_cert)
+      /* A server might require different authentication based on the
+       * particular path being requested by the client.  To support this
+       * scenario, we must ensure that a connection will never reuse the
+       * authentication data from a previous connection. */
+      SSL_InvalidateSession(BACKEND->handle);
+
+    PR_Close(BACKEND->handle);
+    BACKEND->handle = NULL;
+  }
+}
+
+/*
+ * This function is called when an SSL connection is closed.
+ */
+static void Curl_nss_close(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct ssl_connect_data *connssl_proxy = &conn->proxy_ssl[sockindex];
+
+  if(BACKEND->handle || connssl_proxy->backend->handle) {
+    /* NSS closes the socket we previously handed to it, so we must mark it
+       as closed to avoid double close */
+    fake_sclose(conn->sock[sockindex]);
+    conn->sock[sockindex] = CURL_SOCKET_BAD;
+  }
+
+  if(BACKEND->handle)
+    /* nss_close(connssl) will transitively close also
+       connssl_proxy->backend->handle if both are used. Clear it to avoid
+       a double close leading to crash. */
+    connssl_proxy->backend->handle = NULL;
+
+  nss_close(connssl);
+  nss_close(connssl_proxy);
+}
+
+/* return true if NSS can provide error code (and possibly msg) for the
+   error */
+static bool is_nss_error(CURLcode err)
+{
+  switch(err) {
+  case CURLE_PEER_FAILED_VERIFICATION:
+  case CURLE_SSL_CACERT:
+  case CURLE_SSL_CERTPROBLEM:
+  case CURLE_SSL_CONNECT_ERROR:
+  case CURLE_SSL_ISSUER_ERROR:
+    return true;
+
+  default:
+    return false;
+  }
+}
+
+/* return true if the given error code is related to a client certificate */
+static bool is_cc_error(PRInt32 err)
+{
+  switch(err) {
+  case SSL_ERROR_BAD_CERT_ALERT:
+  case SSL_ERROR_EXPIRED_CERT_ALERT:
+  case SSL_ERROR_REVOKED_CERT_ALERT:
+    return true;
+
+  default:
+    return false;
+  }
+}
+
+static Curl_recv nss_recv;
+static Curl_send nss_send;
+
+static CURLcode nss_load_ca_certificates(struct connectdata *conn,
+                                         int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  const char *cafile = SSL_CONN_CONFIG(CAfile);
+  const char *capath = SSL_CONN_CONFIG(CApath);
+  bool use_trust_module;
+  CURLcode result = CURLE_OK;
+
+  /* treat empty string as unset */
+  if(cafile && !cafile[0])
+    cafile = NULL;
+  if(capath && !capath[0])
+    capath = NULL;
+
+  infof(data, "  CAfile: %s\n  CApath: %s\n",
+      cafile ? cafile : "none",
+      capath ? capath : "none");
+
+  /* load libnssckbi.so if no other trust roots were specified */
+  use_trust_module = !cafile && !capath;
+
+  PR_Lock(nss_trustload_lock);
+  if(use_trust_module && !trust_module) {
+    /* libnssckbi.so needed but not yet loaded --> load it! */
+    result = nss_load_module(&trust_module, trust_library, "trust");
+    infof(data, "%s %s\n", (result) ? "failed to load" : "loaded",
+          trust_library);
+    if(result == CURLE_FAILED_INIT)
+      /* make the error non-fatal if we are not going to verify peer */
+      result = CURLE_SSL_CACERT_BADFILE;
+  }
+  else if(!use_trust_module && trust_module) {
+    /* libnssckbi.so not needed but already loaded --> unload it! */
+    infof(data, "unloading %s\n", trust_library);
+    nss_unload_module(&trust_module);
+  }
+  PR_Unlock(nss_trustload_lock);
+
+  if(cafile)
+    result = nss_load_cert(&conn->ssl[sockindex], cafile, PR_TRUE);
+
+  if(result)
+    return result;
+
+  if(capath) {
+    struct_stat st;
+    if(stat(capath, &st) == -1)
+      return CURLE_SSL_CACERT_BADFILE;
+
+    if(S_ISDIR(st.st_mode)) {
+      PRDirEntry *entry;
+      PRDir *dir = PR_OpenDir(capath);
+      if(!dir)
+        return CURLE_SSL_CACERT_BADFILE;
+
+      while((entry = PR_ReadDir(dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN))) {
+        char *fullpath = aprintf("%s/%s", capath, entry->name);
+        if(!fullpath) {
+          PR_CloseDir(dir);
+          return CURLE_OUT_OF_MEMORY;
+        }
+
+        if(CURLE_OK != nss_load_cert(&conn->ssl[sockindex], fullpath, PR_TRUE))
+          /* This is purposefully tolerant of errors so non-PEM files can
+           * be in the same directory */
+          infof(data, "failed to load '%s' from CURLOPT_CAPATH\n", fullpath);
+
+        free(fullpath);
+      }
+
+      PR_CloseDir(dir);
+    }
+    else
+      infof(data, "warning: CURLOPT_CAPATH not a directory (%s)\n", capath);
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode nss_sslver_from_curl(PRUint16 *nssver, long version)
+{
+  switch(version) {
+  case CURL_SSLVERSION_TLSv1:
+    /* TODO: set sslver->max to SSL_LIBRARY_VERSION_TLS_1_3 once stable */
+#ifdef SSL_LIBRARY_VERSION_TLS_1_2
+    *nssver = SSL_LIBRARY_VERSION_TLS_1_2;
+#elif defined SSL_LIBRARY_VERSION_TLS_1_1
+    *nssver = SSL_LIBRARY_VERSION_TLS_1_1;
+#else
+    *nssver = SSL_LIBRARY_VERSION_TLS_1_0;
+#endif
+    return CURLE_OK;
+
+  case CURL_SSLVERSION_SSLv2:
+    *nssver = SSL_LIBRARY_VERSION_2;
+    return CURLE_OK;
+
+  case CURL_SSLVERSION_SSLv3:
+    *nssver = SSL_LIBRARY_VERSION_3_0;
+    return CURLE_OK;
+
+  case CURL_SSLVERSION_TLSv1_0:
+    *nssver = SSL_LIBRARY_VERSION_TLS_1_0;
+    return CURLE_OK;
+
+  case CURL_SSLVERSION_TLSv1_1:
+#ifdef SSL_LIBRARY_VERSION_TLS_1_1
+    *nssver = SSL_LIBRARY_VERSION_TLS_1_1;
+    return CURLE_OK;
+#else
+    return CURLE_SSL_CONNECT_ERROR;
+#endif
+
+  case CURL_SSLVERSION_TLSv1_2:
+#ifdef SSL_LIBRARY_VERSION_TLS_1_2
+    *nssver = SSL_LIBRARY_VERSION_TLS_1_2;
+    return CURLE_OK;
+#else
+    return CURLE_SSL_CONNECT_ERROR;
+#endif
+
+  case CURL_SSLVERSION_TLSv1_3:
+#ifdef SSL_LIBRARY_VERSION_TLS_1_3
+    *nssver = SSL_LIBRARY_VERSION_TLS_1_3;
+    return CURLE_OK;
+#else
+    return CURLE_SSL_CONNECT_ERROR;
+#endif
+
+  default:
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+}
+
+static CURLcode nss_init_sslver(SSLVersionRange *sslver,
+                                struct Curl_easy *data,
+                                struct connectdata *conn)
+{
+  CURLcode result;
+  const long min = SSL_CONN_CONFIG(version);
+  const long max = SSL_CONN_CONFIG(version_max);
+
+  /* map CURL_SSLVERSION_DEFAULT to NSS default */
+  if(min == CURL_SSLVERSION_DEFAULT || max == CURL_SSLVERSION_MAX_DEFAULT) {
+    /* map CURL_SSLVERSION_DEFAULT to NSS default */
+    if(SSL_VersionRangeGetDefault(ssl_variant_stream, sslver) != SECSuccess)
+      return CURLE_SSL_CONNECT_ERROR;
+    /* ... but make sure we use at least TLSv1.0 according to libcurl API */
+    if(sslver->min < SSL_LIBRARY_VERSION_TLS_1_0)
+      sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
+  }
+
+  switch(min) {
+  case CURL_SSLVERSION_DEFAULT:
+    break;
+  case CURL_SSLVERSION_TLSv1:
+    sslver->min = SSL_LIBRARY_VERSION_TLS_1_0;
+    break;
+  default:
+    result = nss_sslver_from_curl(&sslver->min, min);
+    if(result) {
+      failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
+      return result;
+    }
+    if(max == CURL_SSLVERSION_MAX_NONE)
+      sslver->max = sslver->min;
+  }
+
+  switch(max) {
+  case CURL_SSLVERSION_MAX_NONE:
+  case CURL_SSLVERSION_MAX_DEFAULT:
+    break;
+  default:
+    result = nss_sslver_from_curl(&sslver->max, max >> 16);
+    if(result) {
+      failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
+      return result;
+    }
+  }
+
+  return CURLE_OK;
+}
+
+static CURLcode nss_fail_connect(struct ssl_connect_data *connssl,
+                                 struct Curl_easy *data,
+                                 CURLcode curlerr)
+{
+  PRErrorCode err = 0;
+
+  if(is_nss_error(curlerr)) {
+    /* read NSPR error code */
+    err = PR_GetError();
+    if(is_cc_error(err))
+      curlerr = CURLE_SSL_CERTPROBLEM;
+
+    /* print the error number and error string */
+    infof(data, "NSS error %d (%s)\n", err, nss_error_to_name(err));
+
+    /* print a human-readable message describing the error if available */
+    nss_print_error_message(data, err);
+  }
+
+  /* cleanup on connection failure */
+  Curl_llist_destroy(&BACKEND->obj_list, NULL);
+
+  return curlerr;
+}
+
+/* Switch the SSL socket into blocking or non-blocking mode. */
+static CURLcode nss_set_blocking(struct ssl_connect_data *connssl,
+                                 struct Curl_easy *data,
+                                 bool blocking)
+{
+  static PRSocketOptionData sock_opt;
+  sock_opt.option = PR_SockOpt_Nonblocking;
+  sock_opt.value.non_blocking = !blocking;
+
+  if(PR_SetSocketOption(BACKEND->handle, &sock_opt) != PR_SUCCESS)
+    return nss_fail_connect(connssl, data, CURLE_SSL_CONNECT_ERROR);
+
+  return CURLE_OK;
+}
+
+static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex)
+{
+  PRFileDesc *model = NULL;
+  PRFileDesc *nspr_io = NULL;
+  PRFileDesc *nspr_io_stub = NULL;
+  PRBool ssl_no_cache;
+  PRBool ssl_cbc_random_iv;
+  struct Curl_easy *data = conn->data;
+  curl_socket_t sockfd = conn->sock[sockindex];
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  CURLcode result;
+  bool second_layer = FALSE;
+
+  SSLVersionRange sslver = {
+    SSL_LIBRARY_VERSION_TLS_1_0,  /* min */
+    SSL_LIBRARY_VERSION_TLS_1_0   /* max */
+  };
+
+  BACKEND->data = data;
+
+  /* list of all NSS objects we need to destroy in Curl_nss_close() */
+  Curl_llist_init(&BACKEND->obj_list, nss_destroy_object);
+
+  /* FIXME. NSS doesn't support multiple databases open at the same time. */
+  PR_Lock(nss_initlock);
+  result = nss_init(conn->data);
+  if(result) {
+    PR_Unlock(nss_initlock);
+    goto error;
+  }
+
+  PK11_SetPasswordFunc(nss_get_password);
+
+  result = nss_load_module(&pem_module, pem_library, "PEM");
+  PR_Unlock(nss_initlock);
+  if(result == CURLE_FAILED_INIT)
+    infof(data, "WARNING: failed to load NSS PEM library %s. Using "
+                "OpenSSL PEM certificates will not work.\n", pem_library);
+  else if(result)
+    goto error;
+
+  result = CURLE_SSL_CONNECT_ERROR;
+
+  model = PR_NewTCPSocket();
+  if(!model)
+    goto error;
+  model = SSL_ImportFD(NULL, model);
+
+  if(SSL_OptionSet(model, SSL_SECURITY, PR_TRUE) != SECSuccess)
+    goto error;
+  if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_SERVER, PR_FALSE) != SECSuccess)
+    goto error;
+  if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE) != SECSuccess)
+    goto error;
+
+  /* do not use SSL cache if disabled or we are not going to verify peer */
+  ssl_no_cache = (SSL_SET_OPTION(primary.sessionid)
+                  && SSL_CONN_CONFIG(verifypeer)) ? PR_FALSE : PR_TRUE;
+  if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess)
+    goto error;
+
+  /* enable/disable the requested SSL version(s) */
+  if(nss_init_sslver(&sslver, data, conn) != CURLE_OK)
+    goto error;
+  if(SSL_VersionRangeSet(model, &sslver) != SECSuccess)
+    goto error;
+
+  ssl_cbc_random_iv = !SSL_SET_OPTION(enable_beast);
+#ifdef SSL_CBC_RANDOM_IV
+  /* unless the user explicitly asks to allow the protocol vulnerability, we
+     use the work-around */
+  if(SSL_OptionSet(model, SSL_CBC_RANDOM_IV, ssl_cbc_random_iv) != SECSuccess)
+    infof(data, "warning: failed to set SSL_CBC_RANDOM_IV = %d\n",
+          ssl_cbc_random_iv);
+#else
+  if(ssl_cbc_random_iv)
+    infof(data, "warning: support for SSL_CBC_RANDOM_IV not compiled in\n");
+#endif
+
+  if(SSL_CONN_CONFIG(cipher_list)) {
+    if(set_ciphers(data, model, SSL_CONN_CONFIG(cipher_list)) != SECSuccess) {
+      result = CURLE_SSL_CIPHER;
+      goto error;
+    }
+  }
+
+  if(!SSL_CONN_CONFIG(verifypeer) && SSL_CONN_CONFIG(verifyhost))
+    infof(data, "warning: ignoring value of ssl.verifyhost\n");
+
+  /* bypass the default SSL_AuthCertificate() hook in case we do not want to
+   * verify peer */
+  if(SSL_AuthCertificateHook(model, nss_auth_cert_hook, conn) != SECSuccess)
+    goto error;
+
+  /* not checked yet */
+  if(SSL_IS_PROXY())
+    data->set.proxy_ssl.certverifyresult = 0;
+  else
+    data->set.ssl.certverifyresult = 0;
+
+  if(SSL_BadCertHook(model, BadCertHandler, conn) != SECSuccess)
+    goto error;
+
+  if(SSL_HandshakeCallback(model, HandshakeCallback, conn) != SECSuccess)
+    goto error;
+
+  {
+    const CURLcode rv = nss_load_ca_certificates(conn, sockindex);
+    if((rv == CURLE_SSL_CACERT_BADFILE) && !SSL_CONN_CONFIG(verifypeer))
+      /* not a fatal error because we are not going to verify the peer */
+      infof(data, "warning: CA certificates failed to load\n");
+    else if(rv) {
+      result = rv;
+      goto error;
+    }
+  }
+
+  if(SSL_SET_OPTION(CRLfile)) {
+    const CURLcode rv = nss_load_crl(SSL_SET_OPTION(CRLfile));
+    if(rv) {
+      result = rv;
+      goto error;
+    }
+    infof(data, "  CRLfile: %s\n", SSL_SET_OPTION(CRLfile));
+  }
+
+  if(SSL_SET_OPTION(cert)) {
+    char *nickname = dup_nickname(data, SSL_SET_OPTION(cert));
+    if(nickname) {
+      /* we are not going to use libnsspem.so to read the client cert */
+      BACKEND->obj_clicert = NULL;
+    }
+    else {
+      CURLcode rv = cert_stuff(conn, sockindex, SSL_SET_OPTION(cert),
+                               SSL_SET_OPTION(key));
+      if(rv) {
+        /* failf() is already done in cert_stuff() */
+        result = rv;
+        goto error;
+      }
+    }
+
+    /* store the nickname for SelectClientCert() called during handshake */
+    BACKEND->client_nickname = nickname;
+  }
+  else
+    BACKEND->client_nickname = NULL;
+
+  if(SSL_GetClientAuthDataHook(model, SelectClientCert,
+                               (void *)connssl) != SECSuccess) {
+    result = CURLE_SSL_CERTPROBLEM;
+    goto error;
+  }
+
+  if(conn->proxy_ssl[sockindex].use) {
+    DEBUGASSERT(ssl_connection_complete == conn->proxy_ssl[sockindex].state);
+    DEBUGASSERT(conn->proxy_ssl[sockindex].backend->handle != NULL);
+    nspr_io = conn->proxy_ssl[sockindex].backend->handle;
+    second_layer = TRUE;
+  }
+  else {
+    /* wrap OS file descriptor by NSPR's file descriptor abstraction */
+    nspr_io = PR_ImportTCPSocket(sockfd);
+    if(!nspr_io)
+      goto error;
+  }
+
+  /* create our own NSPR I/O layer */
+  nspr_io_stub = PR_CreateIOLayerStub(nspr_io_identity, &nspr_io_methods);
+  if(!nspr_io_stub) {
+    if(!second_layer)
+      PR_Close(nspr_io);
+    goto error;
+  }
+
+  /* make the per-connection data accessible from NSPR I/O callbacks */
+  nspr_io_stub->secret = (void *)connssl;
+
+  /* push our new layer to the NSPR I/O stack */
+  if(PR_PushIOLayer(nspr_io, PR_TOP_IO_LAYER, nspr_io_stub) != PR_SUCCESS) {
+    if(!second_layer)
+      PR_Close(nspr_io);
+    PR_Close(nspr_io_stub);
+    goto error;
+  }
+
+  /* import our model socket onto the current I/O stack */
+  BACKEND->handle = SSL_ImportFD(model, nspr_io);
+  if(!BACKEND->handle) {
+    if(!second_layer)
+      PR_Close(nspr_io);
+    goto error;
+  }
+
+  PR_Close(model); /* We don't need this any more */
+  model = NULL;
+
+  /* This is the password associated with the cert that we're using */
+  if(SSL_SET_OPTION(key_passwd)) {
+    SSL_SetPKCS11PinArg(BACKEND->handle, SSL_SET_OPTION(key_passwd));
+  }
+
+#ifdef SSL_ENABLE_OCSP_STAPLING
+  if(SSL_CONN_CONFIG(verifystatus)) {
+    if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE)
+        != SECSuccess)
+      goto error;
+  }
+#endif
+
+#ifdef SSL_ENABLE_NPN
+  if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_NPN, conn->bits.tls_enable_npn
+                   ? PR_TRUE : PR_FALSE) != SECSuccess)
+    goto error;
+#endif
+
+#ifdef SSL_ENABLE_ALPN
+  if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_ALPN, conn->bits.tls_enable_alpn
+                   ? PR_TRUE : PR_FALSE) != SECSuccess)
+    goto error;
+#endif
+
+#if NSSVERNUM >= 0x030f04 /* 3.15.4 */
+  if(data->set.ssl.falsestart) {
+    if(SSL_OptionSet(BACKEND->handle, SSL_ENABLE_FALSE_START, PR_TRUE)
+        != SECSuccess)
+      goto error;
+
+    if(SSL_SetCanFalseStartCallback(BACKEND->handle, CanFalseStartCallback,
+        conn) != SECSuccess)
+      goto error;
+  }
+#endif
+
+#if defined(SSL_ENABLE_NPN) || defined(SSL_ENABLE_ALPN)
+  if(conn->bits.tls_enable_npn || conn->bits.tls_enable_alpn) {
+    int cur = 0;
+    unsigned char protocols[128];
+
+#ifdef USE_NGHTTP2
+    if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
+       (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) {
+      protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN;
+      memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID,
+          NGHTTP2_PROTO_VERSION_ID_LEN);
+      cur += NGHTTP2_PROTO_VERSION_ID_LEN;
+    }
+#endif
+    protocols[cur++] = ALPN_HTTP_1_1_LENGTH;
+    memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
+    cur += ALPN_HTTP_1_1_LENGTH;
+
+    if(SSL_SetNextProtoNego(BACKEND->handle, protocols, cur) != SECSuccess)
+      goto error;
+  }
+#endif
+
+
+  /* Force handshake on next I/O */
+  if(SSL_ResetHandshake(BACKEND->handle, /* asServer */ PR_FALSE)
+      != SECSuccess)
+    goto error;
+
+  /* propagate hostname to the TLS layer */
+  if(SSL_SetURL(BACKEND->handle, SSL_IS_PROXY() ? conn->http_proxy.host.name :
+                conn->host.name) != SECSuccess)
+    goto error;
+
+  /* prevent NSS from re-using the session for a different hostname */
+  if(SSL_SetSockPeerID(BACKEND->handle, SSL_IS_PROXY() ?
+                       conn->http_proxy.host.name : conn->host.name)
+     != SECSuccess)
+    goto error;
+
+  return CURLE_OK;
+
+error:
+  if(model)
+    PR_Close(model);
+
+  return nss_fail_connect(connssl, data, result);
+}
+
+static CURLcode nss_do_connect(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct Curl_easy *data = conn->data;
+  CURLcode result = CURLE_SSL_CONNECT_ERROR;
+  PRUint32 timeout;
+  long * const certverifyresult = SSL_IS_PROXY() ?
+    &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
+  const char * const pinnedpubkey = SSL_IS_PROXY() ?
+              data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
+              data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+
+
+  /* check timeout situation */
+  const time_t time_left = Curl_timeleft(data, NULL, TRUE);
+  if(time_left < 0) {
+    failf(data, "timed out before SSL handshake");
+    result = CURLE_OPERATION_TIMEDOUT;
+    goto error;
+  }
+
+  /* Force the handshake now */
+  timeout = PR_MillisecondsToInterval((PRUint32) time_left);
+  if(SSL_ForceHandshakeWithTimeout(BACKEND->handle, timeout) != SECSuccess) {
+    if(PR_GetError() == PR_WOULD_BLOCK_ERROR)
+      /* blocking direction is updated by nss_update_connecting_state() */
+      return CURLE_AGAIN;
+    else if(*certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN)
+      result = CURLE_PEER_FAILED_VERIFICATION;
+    else if(*certverifyresult != 0)
+      result = CURLE_SSL_CACERT;
+    goto error;
+  }
+
+  result = display_conn_info(conn, BACKEND->handle);
+  if(result)
+    goto error;
+
+  if(SSL_SET_OPTION(issuercert)) {
+    SECStatus ret = SECFailure;
+    char *nickname = dup_nickname(data, SSL_SET_OPTION(issuercert));
+    if(nickname) {
+      /* we support only nicknames in case of issuercert for now */
+      ret = check_issuer_cert(BACKEND->handle, nickname);
+      free(nickname);
+    }
+
+    if(SECFailure == ret) {
+      infof(data, "SSL certificate issuer check failed\n");
+      result = CURLE_SSL_ISSUER_ERROR;
+      goto error;
+    }
+    else {
+      infof(data, "SSL certificate issuer check ok\n");
+    }
+  }
+
+  result = cmp_peer_pubkey(connssl, pinnedpubkey);
+  if(result)
+    /* status already printed */
+    goto error;
+
+  return CURLE_OK;
+
+error:
+  return nss_fail_connect(connssl, data, result);
+}
+
+static CURLcode nss_connect_common(struct connectdata *conn, int sockindex,
+                                   bool *done)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct Curl_easy *data = conn->data;
+  const bool blocking = (done == NULL);
+  CURLcode result;
+
+  if(connssl->state == ssl_connection_complete) {
+    if(!blocking)
+      *done = TRUE;
+    return CURLE_OK;
+  }
+
+  if(connssl->connecting_state == ssl_connect_1) {
+    result = nss_setup_connect(conn, sockindex);
+    if(result)
+      /* we do not expect CURLE_AGAIN from nss_setup_connect() */
+      return result;
+
+    connssl->connecting_state = ssl_connect_2;
+  }
+
+  /* enable/disable blocking mode before handshake */
+  result = nss_set_blocking(connssl, data, blocking);
+  if(result)
+    return result;
+
+  result = nss_do_connect(conn, sockindex);
+  switch(result) {
+  case CURLE_OK:
+    break;
+  case CURLE_AGAIN:
+    if(!blocking)
+      /* CURLE_AGAIN in non-blocking mode is not an error */
+      return CURLE_OK;
+    /* fall through */
+  default:
+    return result;
+  }
+
+  if(blocking) {
+    /* in blocking mode, set NSS non-blocking mode _after_ SSL handshake */
+    result = nss_set_blocking(connssl, data, /* blocking */ FALSE);
+    if(result)
+      return result;
+  }
+  else
+    /* signal completed SSL handshake */
+    *done = TRUE;
+
+  connssl->state = ssl_connection_complete;
+  conn->recv[sockindex] = nss_recv;
+  conn->send[sockindex] = nss_send;
+
+  /* ssl_connect_done is never used outside, go back to the initial state */
+  connssl->connecting_state = ssl_connect_1;
+
+  return CURLE_OK;
+}
+
+static CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex)
+{
+  return nss_connect_common(conn, sockindex, /* blocking */ NULL);
+}
+
+static CURLcode Curl_nss_connect_nonblocking(struct connectdata *conn,
+                                             int sockindex, bool *done)
+{
+  return nss_connect_common(conn, sockindex, done);
+}
+
+static ssize_t nss_send(struct connectdata *conn,  /* connection data */
+                        int sockindex,             /* socketindex */
+                        const void *mem,           /* send this data */
+                        size_t len,                /* amount to write */
+                        CURLcode *curlcode)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  ssize_t rc;
+
+  /* The SelectClientCert() hook uses this for infof() and failf() but the
+     handle stored in nss_setup_connect() could have already been freed. */
+  BACKEND->data = conn->data;
+
+  rc = PR_Send(BACKEND->handle, mem, (int)len, 0, PR_INTERVAL_NO_WAIT);
+  if(rc < 0) {
+    PRInt32 err = PR_GetError();
+    if(err == PR_WOULD_BLOCK_ERROR)
+      *curlcode = CURLE_AGAIN;
+    else {
+      /* print the error number and error string */
+      const char *err_name = nss_error_to_name(err);
+      infof(conn->data, "SSL write: error %d (%s)\n", err, err_name);
+
+      /* print a human-readable message describing the error if available */
+      nss_print_error_message(conn->data, err);
+
+      *curlcode = (is_cc_error(err))
+        ? CURLE_SSL_CERTPROBLEM
+        : CURLE_SEND_ERROR;
+    }
+
+    return -1;
+  }
+
+  return rc; /* number of bytes */
+}
+
+static ssize_t nss_recv(struct connectdata *conn,  /* connection data */
+                        int sockindex,             /* socketindex */
+                        char *buf,                 /* store read data here */
+                        size_t buffersize,         /* max amount to read */
+                        CURLcode *curlcode)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  ssize_t nread;
+
+  /* The SelectClientCert() hook uses this for infof() and failf() but the
+     handle stored in nss_setup_connect() could have already been freed. */
+  BACKEND->data = conn->data;
+
+  nread = PR_Recv(BACKEND->handle, buf, (int)buffersize, 0,
+                  PR_INTERVAL_NO_WAIT);
+  if(nread < 0) {
+    /* failed SSL read */
+    PRInt32 err = PR_GetError();
+
+    if(err == PR_WOULD_BLOCK_ERROR)
+      *curlcode = CURLE_AGAIN;
+    else {
+      /* print the error number and error string */
+      const char *err_name = nss_error_to_name(err);
+      infof(conn->data, "SSL read: errno %d (%s)\n", err, err_name);
+
+      /* print a human-readable message describing the error if available */
+      nss_print_error_message(conn->data, err);
+
+      *curlcode = (is_cc_error(err))
+        ? CURLE_SSL_CERTPROBLEM
+        : CURLE_RECV_ERROR;
+    }
+
+    return -1;
+  }
+
+  return nread;
+}
+
+static size_t Curl_nss_version(char *buffer, size_t size)
+{
+  return snprintf(buffer, size, "NSS/%s", NSS_VERSION);
+}
+
+/* data might be NULL */
+static int Curl_nss_seed(struct Curl_easy *data)
+{
+  /* make sure that NSS is initialized */
+  return !!Curl_nss_force_init(data);
+}
+
+/* data might be NULL */
+static CURLcode Curl_nss_random(struct Curl_easy *data,
+                                unsigned char *entropy,
+                                size_t length)
+{
+  Curl_nss_seed(data);  /* Initiate the seed if not already done */
+
+  if(SECSuccess != PK11_GenerateRandom(entropy, curlx_uztosi(length)))
+    /* signal a failure */
+    return CURLE_FAILED_INIT;
+
+  return CURLE_OK;
+}
+
+static CURLcode Curl_nss_md5sum(unsigned char *tmp, /* input */
+                                size_t tmplen,
+                                unsigned char *md5sum, /* output */
+                                size_t md5len)
+{
+  PK11Context *MD5pw = PK11_CreateDigestContext(SEC_OID_MD5);
+  unsigned int MD5out;
+
+  PK11_DigestOp(MD5pw, tmp, curlx_uztoui(tmplen));
+  PK11_DigestFinal(MD5pw, md5sum, &MD5out, curlx_uztoui(md5len));
+  PK11_DestroyContext(MD5pw, PR_TRUE);
+
+  return CURLE_OK;
+}
+
+static void Curl_nss_sha256sum(const unsigned char *tmp, /* input */
+                               size_t tmplen,
+                               unsigned char *sha256sum, /* output */
+                               size_t sha256len)
+{
+  PK11Context *SHA256pw = PK11_CreateDigestContext(SEC_OID_SHA256);
+  unsigned int SHA256out;
+
+  PK11_DigestOp(SHA256pw, tmp, curlx_uztoui(tmplen));
+  PK11_DigestFinal(SHA256pw, sha256sum, &SHA256out, curlx_uztoui(sha256len));
+  PK11_DestroyContext(SHA256pw, PR_TRUE);
+}
+
+static bool Curl_nss_cert_status_request(void)
+{
+#ifdef SSL_ENABLE_OCSP_STAPLING
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}
+
+static bool Curl_nss_false_start(void)
+{
+#if NSSVERNUM >= 0x030f04 /* 3.15.4 */
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}
+
+static void *Curl_nss_get_internals(struct ssl_connect_data *connssl,
+                                    CURLINFO info UNUSED_PARAM)
+{
+  (void)info;
+  return BACKEND->handle;
+}
+
+const struct Curl_ssl Curl_ssl_nss = {
+  { CURLSSLBACKEND_NSS, "nss" }, /* info */
+
+  1, /* have_ca_path */
+  1, /* have_certinfo */
+  1, /* have_pinnedpubkey */
+  0, /* have_ssl_ctx */
+  1, /* support_https_proxy */
+
+  sizeof(struct ssl_backend_data),
+
+  Curl_nss_init,                /* init */
+  Curl_nss_cleanup,             /* cleanup */
+  Curl_nss_version,             /* version */
+  Curl_nss_check_cxn,           /* check_cxn */
+  /* NSS has no shutdown function provided and thus always fail */
+  Curl_none_shutdown,           /* shutdown */
+  Curl_none_data_pending,       /* data_pending */
+  Curl_nss_random,              /* random */
+  Curl_nss_cert_status_request, /* cert_status_request */
+  Curl_nss_connect,             /* connect */
+  Curl_nss_connect_nonblocking, /* connect_nonblocking */
+  Curl_nss_get_internals,       /* get_internals */
+  Curl_nss_close,               /* close_one */
+  Curl_none_close_all,          /* close_all */
+  /* NSS has its own session ID cache */
+  Curl_none_session_free,       /* session_free */
+  Curl_none_set_engine,         /* set_engine */
+  Curl_none_set_engine_default, /* set_engine_default */
+  Curl_none_engines_list,       /* engines_list */
+  Curl_nss_false_start,         /* false_start */
+  Curl_nss_md5sum,              /* md5sum */
+  Curl_nss_sha256sum            /* sha256sum */
+};
+
+#endif /* USE_NSS */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/nssg.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/nssg.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/nssg.h	(revision 331)
@@ -0,0 +1,39 @@
+#ifndef HEADER_CURL_NSSG_H
+#define HEADER_CURL_NSSG_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_NSS
+/*
+ * This header should only be needed to get included by vtls.c and nss.c
+ */
+
+#include "urldata.h"
+
+/* initialize NSS library if not already */
+CURLcode Curl_nss_force_init(struct Curl_easy *data);
+
+extern const struct Curl_ssl Curl_ssl_nss;
+
+#endif /* USE_NSS */
+#endif /* HEADER_CURL_NSSG_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/openssl.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/openssl.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/openssl.c	(revision 331)
@@ -0,0 +1,3661 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all OpenSSL-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ */
+
+/*
+ * The original SSLeay-using code for curl was written by Linas Vepstas and
+ * Sampo Kellomaki 1998.
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_OPENSSL
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#include "urldata.h"
+#include "sendf.h"
+#include "formdata.h" /* for the boundary function */
+#include "url.h" /* for the ssl config check function */
+#include "inet_pton.h"
+#include "openssl.h"
+#include "connect.h"
+#include "slist.h"
+#include "select.h"
+#include "vtls.h"
+#include "strcase.h"
+#include "hostcheck.h"
+#include "curl_printf.h"
+#include <openssl/ssl.h>
+#ifdef HAVE_OPENSSL_ENGINE_H
+#include <openssl/engine.h>
+#endif
+#include <openssl/rand.h>
+#include <openssl/x509v3.h>
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#include <openssl/dh.h>
+#include <openssl/err.h>
+#include <openssl/md5.h>
+#include <openssl/conf.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/bio.h>
+#include <openssl/buffer.h>
+
+#ifndef OPENSSL_IS_BORINGSSL
+/* BoringSSL does not support PKCS12 */
+#define HAVE_PKCS12_SUPPORT 1
+#include <openssl/pkcs12.h>
+#endif
+
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_OCSP)
+#include <openssl/ocsp.h>
+#endif
+
+#include "warnless.h"
+#include "non-ascii.h" /* for Curl_convert_from_utf8 prototype */
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+#ifndef OPENSSL_VERSION_NUMBER
+#error "OPENSSL_VERSION_NUMBER not defined"
+#endif
+
+#if defined(HAVE_OPENSSL_ENGINE_H)
+#include <openssl/ui.h>
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= 0x00909000L
+#define SSL_METHOD_QUAL const
+#else
+#define SSL_METHOD_QUAL
+#endif
+
+#if (OPENSSL_VERSION_NUMBER >= 0x10000000L)
+#define HAVE_ERR_REMOVE_THREAD_STATE 1
+#endif
+
+#if !defined(HAVE_SSLV2_CLIENT_METHOD) || \
+  OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0+ has no SSLv2 */
+#undef OPENSSL_NO_SSL2 /* undef first to avoid compiler warnings */
+#define OPENSSL_NO_SSL2
+#endif
+
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && /* OpenSSL 1.1.0+ */ \
+  !defined(LIBRESSL_VERSION_NUMBER)
+#define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER
+#define HAVE_X509_GET0_EXTENSIONS 1 /* added in 1.1.0 -pre1 */
+#define HAVE_OPAQUE_EVP_PKEY 1 /* since 1.1.0 -pre3 */
+#define HAVE_OPAQUE_RSA_DSA_DH 1 /* since 1.1.0 -pre5 */
+#define CONST_EXTS const
+#define HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED 1
+#else
+/* For OpenSSL before 1.1.0 */
+#define ASN1_STRING_get0_data(x) ASN1_STRING_data(x)
+#define X509_get0_notBefore(x) X509_get_notBefore(x)
+#define X509_get0_notAfter(x) X509_get_notAfter(x)
+#define CONST_EXTS /* nope */
+#ifdef LIBRESSL_VERSION_NUMBER
+static unsigned long OpenSSL_version_num(void)
+{
+  return LIBRESSL_VERSION_NUMBER;
+}
+#else
+#define OpenSSL_version_num() SSLeay()
+#endif
+#endif
+
+#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* 1.0.2 or later */ \
+  !defined(LIBRESSL_VERSION_NUMBER)
+#define HAVE_X509_GET0_SIGNATURE 1
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= 0x10002003L && \
+  OPENSSL_VERSION_NUMBER <= 0x10002FFFL && \
+  !defined(OPENSSL_NO_COMP)
+#define HAVE_SSL_COMP_FREE_COMPRESSION_METHODS 1
+#endif
+
+#if (OPENSSL_VERSION_NUMBER < 0x0090808fL)
+/* not present in older OpenSSL */
+#define OPENSSL_load_builtin_modules(x)
+#endif
+
+/*
+ * Whether SSL_CTX_set_keylog_callback is available.
+ * OpenSSL: supported since 1.1.1 https://github.com/openssl/openssl/pull/2287
+ * BoringSSL: supported since d28f59c27bac (committed 2015-11-19)
+ * LibreSSL: unsupported in at least 2.5.1 (explicitly check for it since it
+ *           lies and pretends to be OpenSSL 2.0.0).
+ */
+#if (OPENSSL_VERSION_NUMBER >= 0x10101000L && \
+     !defined(LIBRESSL_VERSION_NUMBER)) || \
+    defined(OPENSSL_IS_BORINGSSL)
+#define HAVE_KEYLOG_CALLBACK
+#endif
+
+#if defined(LIBRESSL_VERSION_NUMBER)
+#define OSSL_PACKAGE "LibreSSL"
+#elif defined(OPENSSL_IS_BORINGSSL)
+#define OSSL_PACKAGE "BoringSSL"
+#else
+#define OSSL_PACKAGE "OpenSSL"
+#endif
+
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
+/* up2date versions of OpenSSL maintain the default reasonably secure without
+ * breaking compatibility, so it is better not to override the default by curl
+ */
+#define DEFAULT_CIPHER_SELECTION NULL
+#else
+/* ... but it is not the case with old versions of OpenSSL */
+#define DEFAULT_CIPHER_SELECTION \
+  "ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH"
+#endif
+
+#ifdef ENABLE_SSLKEYLOGFILE
+typedef struct ssl_tap_state {
+  int master_key_length;
+  unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
+  unsigned char client_random[SSL3_RANDOM_SIZE];
+} ssl_tap_state_t;
+#endif /* ENABLE_SSLKEYLOGFILE */
+
+struct ssl_backend_data {
+  /* these ones requires specific SSL-types */
+  SSL_CTX* ctx;
+  SSL*     handle;
+  X509*    server_cert;
+#ifdef ENABLE_SSLKEYLOGFILE
+  /* tap_state holds the last seen master key if we're logging them */
+  ssl_tap_state_t tap_state;
+#endif
+};
+
+#define BACKEND connssl->backend
+
+/*
+ * Number of bytes to read from the random number seed file. This must be
+ * a finite value (because some entropy "files" like /dev/urandom have
+ * an infinite length), but must be large enough to provide enough
+ * entropy to properly seed OpenSSL's PRNG.
+ */
+#define RAND_LOAD_LENGTH 1024
+
+#ifdef ENABLE_SSLKEYLOGFILE
+/* The fp for the open SSLKEYLOGFILE, or NULL if not open */
+static FILE *keylog_file_fp;
+
+#ifdef HAVE_KEYLOG_CALLBACK
+static void ossl_keylog_callback(const SSL *ssl, const char *line)
+{
+  (void)ssl;
+
+  /* Using fputs here instead of fprintf since libcurl's fprintf replacement
+     may not be thread-safe. */
+  if(keylog_file_fp && line && *line) {
+    char stackbuf[256];
+    char *buf;
+    size_t linelen = strlen(line);
+
+    if(linelen <= sizeof(stackbuf) - 2)
+      buf = stackbuf;
+    else {
+      buf = malloc(linelen + 2);
+      if(!buf)
+        return;
+    }
+    strncpy(buf, line, linelen);
+    buf[linelen] = '\n';
+    buf[linelen + 1] = '\0';
+
+    fputs(buf, keylog_file_fp);
+    if(buf != stackbuf)
+      free(buf);
+  }
+}
+#else
+#define KEYLOG_PREFIX      "CLIENT_RANDOM "
+#define KEYLOG_PREFIX_LEN  (sizeof(KEYLOG_PREFIX) - 1)
+/*
+ * tap_ssl_key is called by libcurl to make the CLIENT_RANDOMs if the OpenSSL
+ * being used doesn't have native support for doing that.
+ */
+static void tap_ssl_key(const SSL *ssl, ssl_tap_state_t *state)
+{
+  const char *hex = "0123456789ABCDEF";
+  int pos, i;
+  char line[KEYLOG_PREFIX_LEN + 2 * SSL3_RANDOM_SIZE + 1 +
+            2 * SSL_MAX_MASTER_KEY_LENGTH + 1 + 1];
+  const SSL_SESSION *session = SSL_get_session(ssl);
+  unsigned char client_random[SSL3_RANDOM_SIZE];
+  unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
+  int master_key_length = 0;
+
+  if(!session || !keylog_file_fp)
+    return;
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+  /* ssl->s3 is not checked in openssl 1.1.0-pre6, but let's assume that
+   * we have a valid SSL context if we have a non-NULL session. */
+  SSL_get_client_random(ssl, client_random, SSL3_RANDOM_SIZE);
+  master_key_length =
+    SSL_SESSION_get_master_key(session, master_key, SSL_MAX_MASTER_KEY_LENGTH);
+#else
+  if(ssl->s3 && session->master_key_length > 0) {
+    master_key_length = session->master_key_length;
+    memcpy(master_key, session->master_key, session->master_key_length);
+    memcpy(client_random, ssl->s3->client_random, SSL3_RANDOM_SIZE);
+  }
+#endif
+
+  if(master_key_length <= 0)
+    return;
+
+  /* Skip writing keys if there is no key or it did not change. */
+  if(state->master_key_length == master_key_length &&
+     !memcmp(state->master_key, master_key, master_key_length) &&
+     !memcmp(state->client_random, client_random, SSL3_RANDOM_SIZE)) {
+    return;
+  }
+
+  state->master_key_length = master_key_length;
+  memcpy(state->master_key, master_key, master_key_length);
+  memcpy(state->client_random, client_random, SSL3_RANDOM_SIZE);
+
+  memcpy(line, KEYLOG_PREFIX, KEYLOG_PREFIX_LEN);
+  pos = KEYLOG_PREFIX_LEN;
+
+  /* Client Random for SSLv3/TLS */
+  for(i = 0; i < SSL3_RANDOM_SIZE; i++) {
+    line[pos++] = hex[client_random[i] >> 4];
+    line[pos++] = hex[client_random[i] & 0xF];
+  }
+  line[pos++] = ' ';
+
+  /* Master Secret (size is at most SSL_MAX_MASTER_KEY_LENGTH) */
+  for(i = 0; i < master_key_length; i++) {
+    line[pos++] = hex[master_key[i] >> 4];
+    line[pos++] = hex[master_key[i] & 0xF];
+  }
+  line[pos++] = '\n';
+  line[pos] = '\0';
+
+  /* Using fputs here instead of fprintf since libcurl's fprintf replacement
+     may not be thread-safe. */
+  fputs(line, keylog_file_fp);
+}
+#endif /* !HAVE_KEYLOG_CALLBACK */
+#endif /* ENABLE_SSLKEYLOGFILE */
+
+static const char *SSL_ERROR_to_str(int err)
+{
+  switch(err) {
+  case SSL_ERROR_NONE:
+    return "SSL_ERROR_NONE";
+  case SSL_ERROR_SSL:
+    return "SSL_ERROR_SSL";
+  case SSL_ERROR_WANT_READ:
+    return "SSL_ERROR_WANT_READ";
+  case SSL_ERROR_WANT_WRITE:
+    return "SSL_ERROR_WANT_WRITE";
+  case SSL_ERROR_WANT_X509_LOOKUP:
+    return "SSL_ERROR_WANT_X509_LOOKUP";
+  case SSL_ERROR_SYSCALL:
+    return "SSL_ERROR_SYSCALL";
+  case SSL_ERROR_ZERO_RETURN:
+    return "SSL_ERROR_ZERO_RETURN";
+  case SSL_ERROR_WANT_CONNECT:
+    return "SSL_ERROR_WANT_CONNECT";
+  case SSL_ERROR_WANT_ACCEPT:
+    return "SSL_ERROR_WANT_ACCEPT";
+#if defined(SSL_ERROR_WANT_ASYNC)
+  case SSL_ERROR_WANT_ASYNC:
+    return "SSL_ERROR_WANT_ASYNC";
+#endif
+#if defined(SSL_ERROR_WANT_ASYNC_JOB)
+  case SSL_ERROR_WANT_ASYNC_JOB:
+    return "SSL_ERROR_WANT_ASYNC_JOB";
+#endif
+#if defined(SSL_ERROR_WANT_EARLY)
+  case SSL_ERROR_WANT_EARLY:
+    return "SSL_ERROR_WANT_EARLY";
+#endif
+  default:
+    return "SSL_ERROR unknown";
+  }
+}
+
+/* Return error string for last OpenSSL error
+ */
+static char *ossl_strerror(unsigned long error, char *buf, size_t size)
+{
+  ERR_error_string_n(error, buf, size);
+  return buf;
+}
+
+static int passwd_callback(char *buf, int num, int encrypting,
+                           void *global_passwd)
+{
+  DEBUGASSERT(0 == encrypting);
+
+  if(!encrypting) {
+    int klen = curlx_uztosi(strlen((char *)global_passwd));
+    if(num > klen) {
+      memcpy(buf, global_passwd, klen + 1);
+      return klen;
+    }
+  }
+  return 0;
+}
+
+/*
+ * rand_enough() returns TRUE if we have seeded the random engine properly.
+ */
+static bool rand_enough(void)
+{
+  return (0 != RAND_status()) ? TRUE : FALSE;
+}
+
+static CURLcode Curl_ossl_seed(struct Curl_easy *data)
+{
+  /* we have the "SSL is seeded" boolean static to prevent multiple
+     time-consuming seedings in vain */
+  static bool ssl_seeded = FALSE;
+  char fname[256];
+
+  if(ssl_seeded)
+    return CURLE_OK;
+
+  if(rand_enough()) {
+    /* OpenSSL 1.1.0+ will return here */
+    ssl_seeded = TRUE;
+    return CURLE_OK;
+  }
+
+#ifndef RANDOM_FILE
+  /* if RANDOM_FILE isn't defined, we only perform this if an option tells
+     us to! */
+  if(data->set.str[STRING_SSL_RANDOM_FILE])
+#define RANDOM_FILE "" /* doesn't matter won't be used */
+#endif
+  {
+    /* let the option override the define */
+    RAND_load_file((data->set.str[STRING_SSL_RANDOM_FILE]?
+                    data->set.str[STRING_SSL_RANDOM_FILE]:
+                    RANDOM_FILE),
+                   RAND_LOAD_LENGTH);
+    if(rand_enough())
+      return CURLE_OK;
+  }
+
+#if defined(HAVE_RAND_EGD)
+  /* only available in OpenSSL 0.9.5 and later */
+  /* EGD_SOCKET is set at configure time or not at all */
+#ifndef EGD_SOCKET
+  /* If we don't have the define set, we only do this if the egd-option
+     is set */
+  if(data->set.str[STRING_SSL_EGDSOCKET])
+#define EGD_SOCKET "" /* doesn't matter won't be used */
+#endif
+  {
+    /* If there's an option and a define, the option overrides the
+       define */
+    int ret = RAND_egd(data->set.str[STRING_SSL_EGDSOCKET]?
+                       data->set.str[STRING_SSL_EGDSOCKET]:EGD_SOCKET);
+    if(-1 != ret) {
+      if(rand_enough())
+        return CURLE_OK;
+    }
+  }
+#endif
+
+  /* fallback to a custom seeding of the PRNG using a hash based on a current
+     time */
+  do {
+    unsigned char randb[64];
+    size_t len = sizeof(randb);
+    size_t i, i_max;
+    for(i = 0, i_max = len / sizeof(struct curltime); i < i_max; ++i) {
+      struct curltime tv = Curl_now();
+      Curl_wait_ms(1);
+      tv.tv_sec *= i + 1;
+      tv.tv_usec *= (unsigned int)i + 2;
+      tv.tv_sec ^= ((Curl_now().tv_sec + Curl_now().tv_usec) *
+                    (i + 3)) << 8;
+      tv.tv_usec ^= (unsigned int) ((Curl_now().tv_sec +
+                                     Curl_now().tv_usec) *
+                                    (i + 4)) << 16;
+      memcpy(&randb[i * sizeof(struct curltime)], &tv,
+             sizeof(struct curltime));
+    }
+    RAND_add(randb, (int)len, (double)len/2);
+  } while(!rand_enough());
+
+  /* generates a default path for the random seed file */
+  fname[0] = 0; /* blank it first */
+  RAND_file_name(fname, sizeof(fname));
+  if(fname[0]) {
+    /* we got a file name to try */
+    RAND_load_file(fname, RAND_LOAD_LENGTH);
+    if(rand_enough())
+      return CURLE_OK;
+  }
+
+  infof(data, "libcurl is now using a weak random seed!\n");
+  return (rand_enough() ? CURLE_OK :
+    CURLE_SSL_CONNECT_ERROR /* confusing error code */);
+}
+
+#ifndef SSL_FILETYPE_ENGINE
+#define SSL_FILETYPE_ENGINE 42
+#endif
+#ifndef SSL_FILETYPE_PKCS12
+#define SSL_FILETYPE_PKCS12 43
+#endif
+static int do_file_type(const char *type)
+{
+  if(!type || !type[0])
+    return SSL_FILETYPE_PEM;
+  if(strcasecompare(type, "PEM"))
+    return SSL_FILETYPE_PEM;
+  if(strcasecompare(type, "DER"))
+    return SSL_FILETYPE_ASN1;
+  if(strcasecompare(type, "ENG"))
+    return SSL_FILETYPE_ENGINE;
+  if(strcasecompare(type, "P12"))
+    return SSL_FILETYPE_PKCS12;
+  return -1;
+}
+
+#if defined(HAVE_OPENSSL_ENGINE_H) && !defined(OPENSSL_NO_UI)
+/*
+ * Supply default password to the engine user interface conversation.
+ * The password is passed by OpenSSL engine from ENGINE_load_private_key()
+ * last argument to the ui and can be obtained by UI_get0_user_data(ui) here.
+ */
+static int ssl_ui_reader(UI *ui, UI_STRING *uis)
+{
+  const char *password;
+  switch(UI_get_string_type(uis)) {
+  case UIT_PROMPT:
+  case UIT_VERIFY:
+    password = (const char *)UI_get0_user_data(ui);
+    if(password && (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD)) {
+      UI_set_result(ui, uis, password);
+      return 1;
+    }
+  default:
+    break;
+  }
+  return (UI_method_get_reader(UI_OpenSSL()))(ui, uis);
+}
+
+/*
+ * Suppress interactive request for a default password if available.
+ */
+static int ssl_ui_writer(UI *ui, UI_STRING *uis)
+{
+  switch(UI_get_string_type(uis)) {
+  case UIT_PROMPT:
+  case UIT_VERIFY:
+    if(UI_get0_user_data(ui) &&
+       (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD)) {
+      return 1;
+    }
+  default:
+    break;
+  }
+  return (UI_method_get_writer(UI_OpenSSL()))(ui, uis);
+}
+#endif
+
+static
+int cert_stuff(struct connectdata *conn,
+               SSL_CTX* ctx,
+               char *cert_file,
+               const char *cert_type,
+               char *key_file,
+               const char *key_type,
+               char *key_passwd)
+{
+  struct Curl_easy *data = conn->data;
+  char error_buffer[256];
+  bool check_privkey = TRUE;
+
+  int file_type = do_file_type(cert_type);
+
+  if(cert_file || (file_type == SSL_FILETYPE_ENGINE)) {
+    SSL *ssl;
+    X509 *x509;
+    int cert_done = 0;
+
+    if(key_passwd) {
+      /* set the password in the callback userdata */
+      SSL_CTX_set_default_passwd_cb_userdata(ctx, key_passwd);
+      /* Set passwd callback: */
+      SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
+    }
+
+
+    switch(file_type) {
+    case SSL_FILETYPE_PEM:
+      /* SSL_CTX_use_certificate_chain_file() only works on PEM files */
+      if(SSL_CTX_use_certificate_chain_file(ctx,
+                                            cert_file) != 1) {
+        failf(data,
+              "could not load PEM client certificate, " OSSL_PACKAGE
+              " error %s, "
+              "(no key found, wrong pass phrase, or wrong file format?)",
+              ossl_strerror(ERR_get_error(), error_buffer,
+                            sizeof(error_buffer)) );
+        return 0;
+      }
+      break;
+
+    case SSL_FILETYPE_ASN1:
+      /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but
+         we use the case above for PEM so this can only be performed with
+         ASN1 files. */
+      if(SSL_CTX_use_certificate_file(ctx,
+                                      cert_file,
+                                      file_type) != 1) {
+        failf(data,
+              "could not load ASN1 client certificate, " OSSL_PACKAGE
+              " error %s, "
+              "(no key found, wrong pass phrase, or wrong file format?)",
+              ossl_strerror(ERR_get_error(), error_buffer,
+                            sizeof(error_buffer)) );
+        return 0;
+      }
+      break;
+    case SSL_FILETYPE_ENGINE:
+#if defined(HAVE_OPENSSL_ENGINE_H) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME)
+      {
+        if(data->state.engine) {
+          const char *cmd_name = "LOAD_CERT_CTRL";
+          struct {
+            const char *cert_id;
+            X509 *cert;
+          } params;
+
+          params.cert_id = cert_file;
+          params.cert = NULL;
+
+          /* Does the engine supports LOAD_CERT_CTRL ? */
+          if(!ENGINE_ctrl(data->state.engine, ENGINE_CTRL_GET_CMD_FROM_NAME,
+                          0, (void *)cmd_name, NULL)) {
+            failf(data, "ssl engine does not support loading certificates");
+            return 0;
+          }
+
+          /* Load the certificate from the engine */
+          if(!ENGINE_ctrl_cmd(data->state.engine, cmd_name,
+                              0, &params, NULL, 1)) {
+            failf(data, "ssl engine cannot load client cert with id"
+                  " '%s' [%s]", cert_file,
+                  ossl_strerror(ERR_get_error(), error_buffer,
+                                sizeof(error_buffer)));
+            return 0;
+          }
+
+          if(!params.cert) {
+            failf(data, "ssl engine didn't initialized the certificate "
+                  "properly.");
+            return 0;
+          }
+
+          if(SSL_CTX_use_certificate(ctx, params.cert) != 1) {
+            failf(data, "unable to set client certificate");
+            X509_free(params.cert);
+            return 0;
+          }
+          X509_free(params.cert); /* we don't need the handle any more... */
+        }
+        else {
+          failf(data, "crypto engine not set, can't load certificate");
+          return 0;
+        }
+      }
+      break;
+#else
+      failf(data, "file type ENG for certificate not implemented");
+      return 0;
+#endif
+
+    case SSL_FILETYPE_PKCS12:
+    {
+#ifdef HAVE_PKCS12_SUPPORT
+      FILE *f;
+      PKCS12 *p12;
+      EVP_PKEY *pri;
+      STACK_OF(X509) *ca = NULL;
+
+      f = fopen(cert_file, "rb");
+      if(!f) {
+        failf(data, "could not open PKCS12 file '%s'", cert_file);
+        return 0;
+      }
+      p12 = d2i_PKCS12_fp(f, NULL);
+      fclose(f);
+
+      if(!p12) {
+        failf(data, "error reading PKCS12 file '%s'", cert_file);
+        return 0;
+      }
+
+      PKCS12_PBE_add();
+
+      if(!PKCS12_parse(p12, key_passwd, &pri, &x509,
+                       &ca)) {
+        failf(data,
+              "could not parse PKCS12 file, check password, " OSSL_PACKAGE
+              " error %s",
+              ossl_strerror(ERR_get_error(), error_buffer,
+                            sizeof(error_buffer)) );
+        PKCS12_free(p12);
+        return 0;
+      }
+
+      PKCS12_free(p12);
+
+      if(SSL_CTX_use_certificate(ctx, x509) != 1) {
+        failf(data,
+              "could not load PKCS12 client certificate, " OSSL_PACKAGE
+              " error %s",
+              ossl_strerror(ERR_get_error(), error_buffer,
+                            sizeof(error_buffer)) );
+        goto fail;
+      }
+
+      if(SSL_CTX_use_PrivateKey(ctx, pri) != 1) {
+        failf(data, "unable to use private key from PKCS12 file '%s'",
+              cert_file);
+        goto fail;
+      }
+
+      if(!SSL_CTX_check_private_key (ctx)) {
+        failf(data, "private key from PKCS12 file '%s' "
+              "does not match certificate in same file", cert_file);
+        goto fail;
+      }
+      /* Set Certificate Verification chain */
+      if(ca) {
+        while(sk_X509_num(ca)) {
+          /*
+           * Note that sk_X509_pop() is used below to make sure the cert is
+           * removed from the stack properly before getting passed to
+           * SSL_CTX_add_extra_chain_cert(), which takes ownership. Previously
+           * we used sk_X509_value() instead, but then we'd clean it in the
+           * subsequent sk_X509_pop_free() call.
+           */
+          X509 *x = sk_X509_pop(ca);
+          if(!SSL_CTX_add_client_CA(ctx, x)) {
+            X509_free(x);
+            failf(data, "cannot add certificate to client CA list");
+            goto fail;
+          }
+          if(!SSL_CTX_add_extra_chain_cert(ctx, x)) {
+            X509_free(x);
+            failf(data, "cannot add certificate to certificate chain");
+            goto fail;
+          }
+        }
+      }
+
+      cert_done = 1;
+  fail:
+      EVP_PKEY_free(pri);
+      X509_free(x509);
+      sk_X509_pop_free(ca, X509_free);
+
+      if(!cert_done)
+        return 0; /* failure! */
+      break;
+#else
+      failf(data, "file type P12 for certificate not supported");
+      return 0;
+#endif
+    }
+    default:
+      failf(data, "not supported file type '%s' for certificate", cert_type);
+      return 0;
+    }
+
+    file_type = do_file_type(key_type);
+
+    switch(file_type) {
+    case SSL_FILETYPE_PEM:
+      if(cert_done)
+        break;
+      if(!key_file)
+        /* cert & key can only be in PEM case in the same file */
+        key_file = cert_file;
+      /* FALLTHROUGH */
+    case SSL_FILETYPE_ASN1:
+      if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) {
+        failf(data, "unable to set private key file: '%s' type %s",
+              key_file, key_type?key_type:"PEM");
+        return 0;
+      }
+      break;
+    case SSL_FILETYPE_ENGINE:
+#if defined(HAVE_OPENSSL_ENGINE_H) && !defined(OPENSSL_NO_UI)
+      {                         /* XXXX still needs some work */
+        EVP_PKEY *priv_key = NULL;
+        if(data->state.engine) {
+          UI_METHOD *ui_method =
+            UI_create_method((char *)"curl user interface");
+          if(!ui_method) {
+            failf(data, "unable do create " OSSL_PACKAGE
+                  " user-interface method");
+            return 0;
+          }
+          UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL()));
+          UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL()));
+          UI_method_set_reader(ui_method, ssl_ui_reader);
+          UI_method_set_writer(ui_method, ssl_ui_writer);
+          /* the typecast below was added to please mingw32 */
+          priv_key = (EVP_PKEY *)
+            ENGINE_load_private_key(data->state.engine, key_file,
+                                    ui_method,
+                                    key_passwd);
+          UI_destroy_method(ui_method);
+          if(!priv_key) {
+            failf(data, "failed to load private key from crypto engine");
+            return 0;
+          }
+          if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) {
+            failf(data, "unable to set private key");
+            EVP_PKEY_free(priv_key);
+            return 0;
+          }
+          EVP_PKEY_free(priv_key);  /* we don't need the handle any more... */
+        }
+        else {
+          failf(data, "crypto engine not set, can't load private key");
+          return 0;
+        }
+      }
+      break;
+#else
+      failf(data, "file type ENG for private key not supported");
+      return 0;
+#endif
+    case SSL_FILETYPE_PKCS12:
+      if(!cert_done) {
+        failf(data, "file type P12 for private key not supported");
+        return 0;
+      }
+      break;
+    default:
+      failf(data, "not supported file type for private key");
+      return 0;
+    }
+
+    ssl = SSL_new(ctx);
+    if(!ssl) {
+      failf(data, "unable to create an SSL structure");
+      return 0;
+    }
+
+    x509 = SSL_get_certificate(ssl);
+
+    /* This version was provided by Evan Jordan and is supposed to not
+       leak memory as the previous version: */
+    if(x509) {
+      EVP_PKEY *pktmp = X509_get_pubkey(x509);
+      EVP_PKEY_copy_parameters(pktmp, SSL_get_privatekey(ssl));
+      EVP_PKEY_free(pktmp);
+    }
+
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_IS_BORINGSSL)
+    {
+      /* If RSA is used, don't check the private key if its flags indicate
+       * it doesn't support it. */
+      EVP_PKEY *priv_key = SSL_get_privatekey(ssl);
+      int pktype;
+#ifdef HAVE_OPAQUE_EVP_PKEY
+      pktype = EVP_PKEY_id(priv_key);
+#else
+      pktype = priv_key->type;
+#endif
+      if(pktype == EVP_PKEY_RSA) {
+        RSA *rsa = EVP_PKEY_get1_RSA(priv_key);
+        if(RSA_flags(rsa) & RSA_METHOD_FLAG_NO_CHECK)
+          check_privkey = FALSE;
+        RSA_free(rsa); /* Decrement reference count */
+      }
+    }
+#endif
+
+    SSL_free(ssl);
+
+    /* If we are using DSA, we can copy the parameters from
+     * the private key */
+
+    if(check_privkey == TRUE) {
+      /* Now we know that a key and cert have been set against
+       * the SSL context */
+      if(!SSL_CTX_check_private_key(ctx)) {
+        failf(data, "Private key does not match the certificate public key");
+        return 0;
+      }
+    }
+  }
+  return 1;
+}
+
+/* returns non-zero on failure */
+static int x509_name_oneline(X509_NAME *a, char *buf, size_t size)
+{
+#if 0
+  return X509_NAME_oneline(a, buf, size);
+#else
+  BIO *bio_out = BIO_new(BIO_s_mem());
+  BUF_MEM *biomem;
+  int rc;
+
+  if(!bio_out)
+    return 1; /* alloc failed! */
+
+  rc = X509_NAME_print_ex(bio_out, a, 0, XN_FLAG_SEP_SPLUS_SPC);
+  BIO_get_mem_ptr(bio_out, &biomem);
+
+  if((size_t)biomem->length < size)
+    size = biomem->length;
+  else
+    size--; /* don't overwrite the buffer end */
+
+  memcpy(buf, biomem->data, size);
+  buf[size] = 0;
+
+  BIO_free(bio_out);
+
+  return !rc;
+#endif
+}
+
+/**
+ * Global SSL init
+ *
+ * @retval 0 error initializing SSL
+ * @retval 1 SSL initialized successfully
+ */
+static int Curl_ossl_init(void)
+{
+#ifdef ENABLE_SSLKEYLOGFILE
+  const char *keylog_file_name;
+#endif
+
+  OPENSSL_load_builtin_modules();
+
+#ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES
+  ENGINE_load_builtin_engines();
+#endif
+
+  /* OPENSSL_config(NULL); is "strongly recommended" to use but unfortunately
+     that function makes an exit() call on wrongly formatted config files
+     which makes it hard to use in some situations. OPENSSL_config() itself
+     calls CONF_modules_load_file() and we use that instead and we ignore
+     its return code! */
+
+  /* CONF_MFLAGS_DEFAULT_SECTION introduced some time between 0.9.8b and
+     0.9.8e */
+#ifndef CONF_MFLAGS_DEFAULT_SECTION
+#define CONF_MFLAGS_DEFAULT_SECTION 0x0
+#endif
+
+  CONF_modules_load_file(NULL, NULL,
+                         CONF_MFLAGS_DEFAULT_SECTION|
+                         CONF_MFLAGS_IGNORE_MISSING_FILE);
+
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
+    !defined(LIBRESSL_VERSION_NUMBER)
+  /* OpenSSL 1.1.0+ takes care of initialization itself */
+#else
+  /* Lets get nice error messages */
+  SSL_load_error_strings();
+
+  /* Init the global ciphers and digests */
+  if(!SSLeay_add_ssl_algorithms())
+    return 0;
+
+  OpenSSL_add_all_algorithms();
+#endif
+
+#ifdef ENABLE_SSLKEYLOGFILE
+  keylog_file_name = curl_getenv("SSLKEYLOGFILE");
+  if(keylog_file_name && !keylog_file_fp) {
+    keylog_file_fp = fopen(keylog_file_name, FOPEN_APPENDTEXT);
+    if(keylog_file_fp) {
+      if(setvbuf(keylog_file_fp, NULL, _IOLBF, 4096)) {
+        fclose(keylog_file_fp);
+        keylog_file_fp = NULL;
+      }
+    }
+  }
+#endif
+
+  return 1;
+}
+
+/* Global cleanup */
+static void Curl_ossl_cleanup(void)
+{
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
+    !defined(LIBRESSL_VERSION_NUMBER)
+  /* OpenSSL 1.1 deprecates all these cleanup functions and
+     turns them into no-ops in OpenSSL 1.0 compatibility mode */
+#else
+  /* Free ciphers and digests lists */
+  EVP_cleanup();
+
+#ifdef HAVE_ENGINE_CLEANUP
+  /* Free engine list */
+  ENGINE_cleanup();
+#endif
+
+  /* Free OpenSSL error strings */
+  ERR_free_strings();
+
+  /* Free thread local error state, destroying hash upon zero refcount */
+#ifdef HAVE_ERR_REMOVE_THREAD_STATE
+  ERR_remove_thread_state(NULL);
+#else
+  ERR_remove_state(0);
+#endif
+
+  /* Free all memory allocated by all configuration modules */
+  CONF_modules_free();
+
+#ifdef HAVE_SSL_COMP_FREE_COMPRESSION_METHODS
+  SSL_COMP_free_compression_methods();
+#endif
+#endif
+
+#ifdef ENABLE_SSLKEYLOGFILE
+  if(keylog_file_fp) {
+    fclose(keylog_file_fp);
+    keylog_file_fp = NULL;
+  }
+#endif
+}
+
+/*
+ * This function is used to determine connection status.
+ *
+ * Return codes:
+ *     1 means the connection is still in place
+ *     0 means the connection has been closed
+ *    -1 means the connection status is unknown
+ */
+static int Curl_ossl_check_cxn(struct connectdata *conn)
+{
+  /* SSL_peek takes data out of the raw recv buffer without peeking so we use
+     recv MSG_PEEK instead. Bug #795 */
+#ifdef MSG_PEEK
+  char buf;
+  ssize_t nread;
+  nread = recv((RECV_TYPE_ARG1)conn->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf,
+               (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK);
+  if(nread == 0)
+    return 0; /* connection has been closed */
+  if(nread == 1)
+    return 1; /* connection still in place */
+  else if(nread == -1) {
+      int err = SOCKERRNO;
+      if(err == EINPROGRESS ||
+#if defined(EAGAIN) && (EAGAIN != EWOULDBLOCK)
+         err == EAGAIN ||
+#endif
+         err == EWOULDBLOCK)
+        return 1; /* connection still in place */
+      if(err == ECONNRESET ||
+#ifdef ECONNABORTED
+         err == ECONNABORTED ||
+#endif
+#ifdef ENETDOWN
+         err == ENETDOWN ||
+#endif
+#ifdef ENETRESET
+         err == ENETRESET ||
+#endif
+#ifdef ESHUTDOWN
+         err == ESHUTDOWN ||
+#endif
+#ifdef ETIMEDOUT
+         err == ETIMEDOUT ||
+#endif
+         err == ENOTCONN)
+        return 0; /* connection has been closed */
+  }
+#endif
+  return -1; /* connection status unknown */
+}
+
+/* Selects an OpenSSL crypto engine
+ */
+static CURLcode Curl_ossl_set_engine(struct Curl_easy *data,
+                                     const char *engine)
+{
+#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
+  ENGINE *e;
+
+#if OPENSSL_VERSION_NUMBER >= 0x00909000L
+  e = ENGINE_by_id(engine);
+#else
+  /* avoid memory leak */
+  for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) {
+    const char *e_id = ENGINE_get_id(e);
+    if(!strcmp(engine, e_id))
+      break;
+  }
+#endif
+
+  if(!e) {
+    failf(data, "SSL Engine '%s' not found", engine);
+    return CURLE_SSL_ENGINE_NOTFOUND;
+  }
+
+  if(data->state.engine) {
+    ENGINE_finish(data->state.engine);
+    ENGINE_free(data->state.engine);
+    data->state.engine = NULL;
+  }
+  if(!ENGINE_init(e)) {
+    char buf[256];
+
+    ENGINE_free(e);
+    failf(data, "Failed to initialise SSL Engine '%s':\n%s",
+          engine, ossl_strerror(ERR_get_error(), buf, sizeof(buf)));
+    return CURLE_SSL_ENGINE_INITFAILED;
+  }
+  data->state.engine = e;
+  return CURLE_OK;
+#else
+  (void)engine;
+  failf(data, "SSL Engine not supported");
+  return CURLE_SSL_ENGINE_NOTFOUND;
+#endif
+}
+
+/* Sets engine as default for all SSL operations
+ */
+static CURLcode Curl_ossl_set_engine_default(struct Curl_easy *data)
+{
+#ifdef HAVE_OPENSSL_ENGINE_H
+  if(data->state.engine) {
+    if(ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) {
+      infof(data, "set default crypto engine '%s'\n",
+            ENGINE_get_id(data->state.engine));
+    }
+    else {
+      failf(data, "set default crypto engine '%s' failed",
+            ENGINE_get_id(data->state.engine));
+      return CURLE_SSL_ENGINE_SETFAILED;
+    }
+  }
+#else
+  (void) data;
+#endif
+  return CURLE_OK;
+}
+
+/* Return list of OpenSSL crypto engine names.
+ */
+static struct curl_slist *Curl_ossl_engines_list(struct Curl_easy *data)
+{
+  struct curl_slist *list = NULL;
+#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
+  struct curl_slist *beg;
+  ENGINE *e;
+
+  for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) {
+    beg = curl_slist_append(list, ENGINE_get_id(e));
+    if(!beg) {
+      curl_slist_free_all(list);
+      return NULL;
+    }
+    list = beg;
+  }
+#endif
+  (void) data;
+  return list;
+}
+
+
+static void ossl_close(struct ssl_connect_data *connssl)
+{
+  if(BACKEND->handle) {
+    (void)SSL_shutdown(BACKEND->handle);
+    SSL_set_connect_state(BACKEND->handle);
+
+    SSL_free(BACKEND->handle);
+    BACKEND->handle = NULL;
+  }
+  if(BACKEND->ctx) {
+    SSL_CTX_free(BACKEND->ctx);
+    BACKEND->ctx = NULL;
+  }
+}
+
+/*
+ * This function is called when an SSL connection is closed.
+ */
+static void Curl_ossl_close(struct connectdata *conn, int sockindex)
+{
+  ossl_close(&conn->ssl[sockindex]);
+  ossl_close(&conn->proxy_ssl[sockindex]);
+}
+
+/*
+ * This function is called to shut down the SSL layer but keep the
+ * socket open (CCC - Clear Command Channel)
+ */
+static int Curl_ossl_shutdown(struct connectdata *conn, int sockindex)
+{
+  int retval = 0;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct Curl_easy *data = conn->data;
+  char buf[256]; /* We will use this for the OpenSSL error buffer, so it has
+                    to be at least 256 bytes long. */
+  unsigned long sslerror;
+  ssize_t nread;
+  int buffsize;
+  int err;
+  int done = 0;
+
+  /* This has only been tested on the proftpd server, and the mod_tls code
+     sends a close notify alert without waiting for a close notify alert in
+     response. Thus we wait for a close notify alert from the server, but
+     we do not send one. Let's hope other servers do the same... */
+
+  if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
+      (void)SSL_shutdown(BACKEND->handle);
+
+  if(BACKEND->handle) {
+    buffsize = (int)sizeof(buf);
+    while(!done) {
+      int what = SOCKET_READABLE(conn->sock[sockindex],
+                                 SSL_SHUTDOWN_TIMEOUT);
+      if(what > 0) {
+        ERR_clear_error();
+
+        /* Something to read, let's do it and hope that it is the close
+           notify alert from the server */
+        nread = (ssize_t)SSL_read(BACKEND->handle, buf, buffsize);
+        err = SSL_get_error(BACKEND->handle, (int)nread);
+
+        switch(err) {
+        case SSL_ERROR_NONE: /* this is not an error */
+        case SSL_ERROR_ZERO_RETURN: /* no more data */
+          /* This is the expected response. There was no data but only
+             the close notify alert */
+          done = 1;
+          break;
+        case SSL_ERROR_WANT_READ:
+          /* there's data pending, re-invoke SSL_read() */
+          infof(data, "SSL_ERROR_WANT_READ\n");
+          break;
+        case SSL_ERROR_WANT_WRITE:
+          /* SSL wants a write. Really odd. Let's bail out. */
+          infof(data, "SSL_ERROR_WANT_WRITE\n");
+          done = 1;
+          break;
+        default:
+          /* openssl/ssl.h says "look at error stack/return value/errno" */
+          sslerror = ERR_get_error();
+          failf(conn->data, OSSL_PACKAGE " SSL_read on shutdown: %s, errno %d",
+                (sslerror ?
+                 ossl_strerror(sslerror, buf, sizeof(buf)) :
+                 SSL_ERROR_to_str(err)),
+                SOCKERRNO);
+          done = 1;
+          break;
+        }
+      }
+      else if(0 == what) {
+        /* timeout */
+        failf(data, "SSL shutdown timeout");
+        done = 1;
+      }
+      else {
+        /* anything that gets here is fatally bad */
+        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        retval = -1;
+        done = 1;
+      }
+    } /* while()-loop for the select() */
+
+    if(data->set.verbose) {
+#ifdef HAVE_SSL_GET_SHUTDOWN
+      switch(SSL_get_shutdown(BACKEND->handle)) {
+      case SSL_SENT_SHUTDOWN:
+        infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n");
+        break;
+      case SSL_RECEIVED_SHUTDOWN:
+        infof(data, "SSL_get_shutdown() returned SSL_RECEIVED_SHUTDOWN\n");
+        break;
+      case SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN:
+        infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN|"
+              "SSL_RECEIVED__SHUTDOWN\n");
+        break;
+      }
+#endif
+    }
+
+    SSL_free(BACKEND->handle);
+    BACKEND->handle = NULL;
+  }
+  return retval;
+}
+
+static void Curl_ossl_session_free(void *ptr)
+{
+  /* free the ID */
+  SSL_SESSION_free(ptr);
+}
+
+/*
+ * This function is called when the 'data' struct is going away. Close
+ * down everything and free all resources!
+ */
+static void Curl_ossl_close_all(struct Curl_easy *data)
+{
+#ifdef HAVE_OPENSSL_ENGINE_H
+  if(data->state.engine) {
+    ENGINE_finish(data->state.engine);
+    ENGINE_free(data->state.engine);
+    data->state.engine = NULL;
+  }
+#else
+  (void)data;
+#endif
+#if !defined(HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED) && \
+  defined(HAVE_ERR_REMOVE_THREAD_STATE)
+  /* OpenSSL 1.0.1 and 1.0.2 build an error queue that is stored per-thread
+     so we need to clean it here in case the thread will be killed. All OpenSSL
+     code should extract the error in association with the error so clearing
+     this queue here should be harmless at worst. */
+  ERR_remove_thread_state(NULL);
+#endif
+}
+
+/* ====================================================== */
+
+
+/* Quote from RFC2818 section 3.1 "Server Identity"
+
+   If a subjectAltName extension of type dNSName is present, that MUST
+   be used as the identity. Otherwise, the (most specific) Common Name
+   field in the Subject field of the certificate MUST be used. Although
+   the use of the Common Name is existing practice, it is deprecated and
+   Certification Authorities are encouraged to use the dNSName instead.
+
+   Matching is performed using the matching rules specified by
+   [RFC2459].  If more than one identity of a given type is present in
+   the certificate (e.g., more than one dNSName name, a match in any one
+   of the set is considered acceptable.) Names may contain the wildcard
+   character * which is considered to match any single domain name
+   component or component fragment. E.g., *.a.com matches foo.a.com but
+   not bar.foo.a.com. f*.com matches foo.com but not bar.com.
+
+   In some cases, the URI is specified as an IP address rather than a
+   hostname. In this case, the iPAddress subjectAltName must be present
+   in the certificate and must exactly match the IP in the URI.
+
+*/
+static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert)
+{
+  bool matched = FALSE;
+  int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */
+  size_t addrlen = 0;
+  struct Curl_easy *data = conn->data;
+  STACK_OF(GENERAL_NAME) *altnames;
+#ifdef ENABLE_IPV6
+  struct in6_addr addr;
+#else
+  struct in_addr addr;
+#endif
+  CURLcode result = CURLE_OK;
+  bool dNSName = FALSE; /* if a dNSName field exists in the cert */
+  bool iPAddress = FALSE; /* if a iPAddress field exists in the cert */
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+  const char * const dispname = SSL_IS_PROXY() ?
+    conn->http_proxy.host.dispname : conn->host.dispname;
+
+#ifdef ENABLE_IPV6
+  if(conn->bits.ipv6_ip &&
+     Curl_inet_pton(AF_INET6, hostname, &addr)) {
+    target = GEN_IPADD;
+    addrlen = sizeof(struct in6_addr);
+  }
+  else
+#endif
+    if(Curl_inet_pton(AF_INET, hostname, &addr)) {
+      target = GEN_IPADD;
+      addrlen = sizeof(struct in_addr);
+    }
+
+  /* get a "list" of alternative names */
+  altnames = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL);
+
+  if(altnames) {
+    int numalts;
+    int i;
+    bool dnsmatched = FALSE;
+    bool ipmatched = FALSE;
+
+    /* get amount of alternatives, RFC2459 claims there MUST be at least
+       one, but we don't depend on it... */
+    numalts = sk_GENERAL_NAME_num(altnames);
+
+    /* loop through all alternatives - until a dnsmatch */
+    for(i = 0; (i < numalts) && !dnsmatched; i++) {
+      /* get a handle to alternative name number i */
+      const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i);
+
+      if(check->type == GEN_DNS)
+        dNSName = TRUE;
+      else if(check->type == GEN_IPADD)
+        iPAddress = TRUE;
+
+      /* only check alternatives of the same type the target is */
+      if(check->type == target) {
+        /* get data and length */
+        const char *altptr = (char *)ASN1_STRING_get0_data(check->d.ia5);
+        size_t altlen = (size_t) ASN1_STRING_length(check->d.ia5);
+
+        switch(target) {
+        case GEN_DNS: /* name/pattern comparison */
+          /* The OpenSSL man page explicitly says: "In general it cannot be
+             assumed that the data returned by ASN1_STRING_data() is null
+             terminated or does not contain embedded nulls." But also that
+             "The actual format of the data will depend on the actual string
+             type itself: for example for and IA5String the data will be ASCII"
+
+             Gisle researched the OpenSSL sources:
+             "I checked the 0.9.6 and 0.9.8 sources before my patch and
+             it always 0-terminates an IA5String."
+          */
+          if((altlen == strlen(altptr)) &&
+             /* if this isn't true, there was an embedded zero in the name
+                string and we cannot match it. */
+             Curl_cert_hostcheck(altptr, hostname)) {
+            dnsmatched = TRUE;
+            infof(data,
+                  " subjectAltName: host \"%s\" matched cert's \"%s\"\n",
+                  dispname, altptr);
+          }
+          break;
+
+        case GEN_IPADD: /* IP address comparison */
+          /* compare alternative IP address if the data chunk is the same size
+             our server IP address is */
+          if((altlen == addrlen) && !memcmp(altptr, &addr, altlen)) {
+            ipmatched = TRUE;
+            infof(data,
+                  " subjectAltName: host \"%s\" matched cert's IP address!\n",
+                  dispname);
+          }
+          break;
+        }
+      }
+    }
+    GENERAL_NAMES_free(altnames);
+
+    if(dnsmatched || ipmatched)
+      matched = TRUE;
+  }
+
+  if(matched)
+    /* an alternative name matched */
+    ;
+  else if(dNSName || iPAddress) {
+    infof(data, " subjectAltName does not match %s\n", dispname);
+    failf(data, "SSL: no alternative certificate subject name matches "
+          "target host name '%s'", dispname);
+    result = CURLE_PEER_FAILED_VERIFICATION;
+  }
+  else {
+    /* we have to look to the last occurrence of a commonName in the
+       distinguished one to get the most significant one. */
+    int j, i = -1;
+
+    /* The following is done because of a bug in 0.9.6b */
+
+    unsigned char *nulstr = (unsigned char *)"";
+    unsigned char *peer_CN = nulstr;
+
+    X509_NAME *name = X509_get_subject_name(server_cert);
+    if(name)
+      while((j = X509_NAME_get_index_by_NID(name, NID_commonName, i)) >= 0)
+        i = j;
+
+    /* we have the name entry and we will now convert this to a string
+       that we can use for comparison. Doing this we support BMPstring,
+       UTF8 etc. */
+
+    if(i >= 0) {
+      ASN1_STRING *tmp =
+        X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
+
+      /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input
+         is already UTF-8 encoded. We check for this case and copy the raw
+         string manually to avoid the problem. This code can be made
+         conditional in the future when OpenSSL has been fixed. Work-around
+         brought by Alexis S. L. Carvalho. */
+      if(tmp) {
+        if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) {
+          j = ASN1_STRING_length(tmp);
+          if(j >= 0) {
+            peer_CN = OPENSSL_malloc(j + 1);
+            if(peer_CN) {
+              memcpy(peer_CN, ASN1_STRING_get0_data(tmp), j);
+              peer_CN[j] = '\0';
+            }
+          }
+        }
+        else /* not a UTF8 name */
+          j = ASN1_STRING_to_UTF8(&peer_CN, tmp);
+
+        if(peer_CN && (curlx_uztosi(strlen((char *)peer_CN)) != j)) {
+          /* there was a terminating zero before the end of string, this
+             cannot match and we return failure! */
+          failf(data, "SSL: illegal cert name field");
+          result = CURLE_PEER_FAILED_VERIFICATION;
+        }
+      }
+    }
+
+    if(peer_CN == nulstr)
+       peer_CN = NULL;
+    else {
+      /* convert peer_CN from UTF8 */
+      CURLcode rc = Curl_convert_from_utf8(data, (char *)peer_CN,
+                                           strlen((char *)peer_CN));
+      /* Curl_convert_from_utf8 calls failf if unsuccessful */
+      if(rc) {
+        OPENSSL_free(peer_CN);
+        return rc;
+      }
+    }
+
+    if(result)
+      /* error already detected, pass through */
+      ;
+    else if(!peer_CN) {
+      failf(data,
+            "SSL: unable to obtain common name from peer certificate");
+      result = CURLE_PEER_FAILED_VERIFICATION;
+    }
+    else if(!Curl_cert_hostcheck((const char *)peer_CN, hostname)) {
+      failf(data, "SSL: certificate subject name '%s' does not match "
+            "target host name '%s'", peer_CN, dispname);
+      result = CURLE_PEER_FAILED_VERIFICATION;
+    }
+    else {
+      infof(data, " common name: %s (matched)\n", peer_CN);
+    }
+    if(peer_CN)
+      OPENSSL_free(peer_CN);
+  }
+
+  return result;
+}
+
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
+    !defined(OPENSSL_NO_OCSP)
+static CURLcode verifystatus(struct connectdata *conn,
+                             struct ssl_connect_data *connssl)
+{
+  int i, ocsp_status;
+  const unsigned char *p;
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+
+  OCSP_RESPONSE *rsp = NULL;
+  OCSP_BASICRESP *br = NULL;
+  X509_STORE     *st = NULL;
+  STACK_OF(X509) *ch = NULL;
+
+  long len = SSL_get_tlsext_status_ocsp_resp(BACKEND->handle, &p);
+
+  if(!p) {
+    failf(data, "No OCSP response received");
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    goto end;
+  }
+
+  rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
+  if(!rsp) {
+    failf(data, "Invalid OCSP response");
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    goto end;
+  }
+
+  ocsp_status = OCSP_response_status(rsp);
+  if(ocsp_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
+    failf(data, "Invalid OCSP response status: %s (%d)",
+          OCSP_response_status_str(ocsp_status), ocsp_status);
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    goto end;
+  }
+
+  br = OCSP_response_get1_basic(rsp);
+  if(!br) {
+    failf(data, "Invalid OCSP response");
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    goto end;
+  }
+
+  ch = SSL_get_peer_cert_chain(BACKEND->handle);
+  st = SSL_CTX_get_cert_store(BACKEND->ctx);
+
+#if ((OPENSSL_VERSION_NUMBER <= 0x1000201fL) /* Fixed after 1.0.2a */ || \
+     (defined(LIBRESSL_VERSION_NUMBER) &&                               \
+      LIBRESSL_VERSION_NUMBER <= 0x2040200fL))
+  /* The authorized responder cert in the OCSP response MUST be signed by the
+     peer cert's issuer (see RFC6960 section 4.2.2.2). If that's a root cert,
+     no problem, but if it's an intermediate cert OpenSSL has a bug where it
+     expects this issuer to be present in the chain embedded in the OCSP
+     response. So we add it if necessary. */
+
+  /* First make sure the peer cert chain includes both a peer and an issuer,
+     and the OCSP response contains a responder cert. */
+  if(sk_X509_num(ch) >= 2 && sk_X509_num(br->certs) >= 1) {
+    X509 *responder = sk_X509_value(br->certs, sk_X509_num(br->certs) - 1);
+
+    /* Find issuer of responder cert and add it to the OCSP response chain */
+    for(i = 0; i < sk_X509_num(ch); i++) {
+      X509 *issuer = sk_X509_value(ch, i);
+      if(X509_check_issued(issuer, responder) == X509_V_OK) {
+        if(!OCSP_basic_add1_cert(br, issuer)) {
+          failf(data, "Could not add issuer cert to OCSP response");
+          result = CURLE_SSL_INVALIDCERTSTATUS;
+          goto end;
+        }
+      }
+    }
+  }
+#endif
+
+  if(OCSP_basic_verify(br, ch, st, 0) <= 0) {
+    failf(data, "OCSP response verification failed");
+    result = CURLE_SSL_INVALIDCERTSTATUS;
+    goto end;
+  }
+
+  for(i = 0; i < OCSP_resp_count(br); i++) {
+    int cert_status, crl_reason;
+    OCSP_SINGLERESP *single = NULL;
+
+    ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
+
+    single = OCSP_resp_get0(br, i);
+    if(!single)
+      continue;
+
+    cert_status = OCSP_single_get0_status(single, &crl_reason, &rev,
+                                          &thisupd, &nextupd);
+
+    if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) {
+      failf(data, "OCSP response has expired");
+      result = CURLE_SSL_INVALIDCERTSTATUS;
+      goto end;
+    }
+
+    infof(data, "SSL certificate status: %s (%d)\n",
+          OCSP_cert_status_str(cert_status), cert_status);
+
+    switch(cert_status) {
+      case V_OCSP_CERTSTATUS_GOOD:
+        break;
+
+      case V_OCSP_CERTSTATUS_REVOKED:
+        result = CURLE_SSL_INVALIDCERTSTATUS;
+
+        failf(data, "SSL certificate revocation reason: %s (%d)",
+              OCSP_crl_reason_str(crl_reason), crl_reason);
+        goto end;
+
+      case V_OCSP_CERTSTATUS_UNKNOWN:
+        result = CURLE_SSL_INVALIDCERTSTATUS;
+        goto end;
+    }
+  }
+
+end:
+  if(br) OCSP_BASICRESP_free(br);
+  OCSP_RESPONSE_free(rsp);
+
+  return result;
+}
+#endif
+
+#endif /* USE_OPENSSL */
+
+/* The SSL_CTRL_SET_MSG_CALLBACK doesn't exist in ancient OpenSSL versions
+   and thus this cannot be done there. */
+#ifdef SSL_CTRL_SET_MSG_CALLBACK
+
+static const char *ssl_msg_type(int ssl_ver, int msg)
+{
+#ifdef SSL2_VERSION_MAJOR
+  if(ssl_ver == SSL2_VERSION_MAJOR) {
+    switch(msg) {
+      case SSL2_MT_ERROR:
+        return "Error";
+      case SSL2_MT_CLIENT_HELLO:
+        return "Client hello";
+      case SSL2_MT_CLIENT_MASTER_KEY:
+        return "Client key";
+      case SSL2_MT_CLIENT_FINISHED:
+        return "Client finished";
+      case SSL2_MT_SERVER_HELLO:
+        return "Server hello";
+      case SSL2_MT_SERVER_VERIFY:
+        return "Server verify";
+      case SSL2_MT_SERVER_FINISHED:
+        return "Server finished";
+      case SSL2_MT_REQUEST_CERTIFICATE:
+        return "Request CERT";
+      case SSL2_MT_CLIENT_CERTIFICATE:
+        return "Client CERT";
+    }
+  }
+  else
+#endif
+  if(ssl_ver == SSL3_VERSION_MAJOR) {
+    switch(msg) {
+      case SSL3_MT_HELLO_REQUEST:
+        return "Hello request";
+      case SSL3_MT_CLIENT_HELLO:
+        return "Client hello";
+      case SSL3_MT_SERVER_HELLO:
+        return "Server hello";
+#ifdef SSL3_MT_NEWSESSION_TICKET
+      case SSL3_MT_NEWSESSION_TICKET:
+        return "Newsession Ticket";
+#endif
+      case SSL3_MT_CERTIFICATE:
+        return "Certificate";
+      case SSL3_MT_SERVER_KEY_EXCHANGE:
+        return "Server key exchange";
+      case SSL3_MT_CLIENT_KEY_EXCHANGE:
+        return "Client key exchange";
+      case SSL3_MT_CERTIFICATE_REQUEST:
+        return "Request CERT";
+      case SSL3_MT_SERVER_DONE:
+        return "Server finished";
+      case SSL3_MT_CERTIFICATE_VERIFY:
+        return "CERT verify";
+      case SSL3_MT_FINISHED:
+        return "Finished";
+#ifdef SSL3_MT_CERTIFICATE_STATUS
+      case SSL3_MT_CERTIFICATE_STATUS:
+        return "Certificate Status";
+#endif
+    }
+  }
+  return "Unknown";
+}
+
+static const char *tls_rt_type(int type)
+{
+  switch(type) {
+#ifdef SSL3_RT_HEADER
+  case SSL3_RT_HEADER:
+    return "TLS header";
+#endif
+  case SSL3_RT_CHANGE_CIPHER_SPEC:
+    return "TLS change cipher";
+  case SSL3_RT_ALERT:
+    return "TLS alert";
+  case SSL3_RT_HANDSHAKE:
+    return "TLS handshake";
+  case SSL3_RT_APPLICATION_DATA:
+    return "TLS app data";
+  default:
+    return "TLS Unknown";
+  }
+}
+
+
+/*
+ * Our callback from the SSL/TLS layers.
+ */
+static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
+                          const void *buf, size_t len, SSL *ssl,
+                          void *userp)
+{
+  struct Curl_easy *data;
+  const char *msg_name, *tls_rt_name;
+  char ssl_buf[1024];
+  char unknown[32];
+  int msg_type, txt_len;
+  const char *verstr = NULL;
+  struct connectdata *conn = userp;
+
+  if(!conn || !conn->data || !conn->data->set.fdebug ||
+     (direction != 0 && direction != 1))
+    return;
+
+  data = conn->data;
+
+  switch(ssl_ver) {
+#ifdef SSL2_VERSION /* removed in recent versions */
+  case SSL2_VERSION:
+    verstr = "SSLv2";
+    break;
+#endif
+#ifdef SSL3_VERSION
+  case SSL3_VERSION:
+    verstr = "SSLv3";
+    break;
+#endif
+  case TLS1_VERSION:
+    verstr = "TLSv1.0";
+    break;
+#ifdef TLS1_1_VERSION
+  case TLS1_1_VERSION:
+    verstr = "TLSv1.1";
+    break;
+#endif
+#ifdef TLS1_2_VERSION
+  case TLS1_2_VERSION:
+    verstr = "TLSv1.2";
+    break;
+#endif
+#ifdef TLS1_3_VERSION
+  case TLS1_3_VERSION:
+    verstr = "TLSv1.3";
+    break;
+#endif
+  case 0:
+    break;
+  default:
+    snprintf(unknown, sizeof(unknown), "(%x)", ssl_ver);
+    verstr = unknown;
+    break;
+  }
+
+  if(ssl_ver) {
+    /* the info given when the version is zero is not that useful for us */
+
+    ssl_ver >>= 8; /* check the upper 8 bits only below */
+
+    /* SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL
+     * always pass-up content-type as 0. But the interesting message-type
+     * is at 'buf[0]'.
+     */
+    if(ssl_ver == SSL3_VERSION_MAJOR && content_type)
+      tls_rt_name = tls_rt_type(content_type);
+    else
+      tls_rt_name = "";
+
+    msg_type = *(char *)buf;
+    msg_name = ssl_msg_type(ssl_ver, msg_type);
+
+    txt_len = snprintf(ssl_buf, sizeof(ssl_buf), "%s (%s), %s, %s (%d):\n",
+                       verstr, direction?"OUT":"IN",
+                       tls_rt_name, msg_name, msg_type);
+    Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len, NULL);
+  }
+
+  Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT :
+             CURLINFO_SSL_DATA_IN, (char *)buf, len, NULL);
+  (void) ssl;
+}
+#endif
+
+#ifdef USE_OPENSSL
+/* ====================================================== */
+
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+#  define use_sni(x)  sni = (x)
+#else
+#  define use_sni(x)  Curl_nop_stmt
+#endif
+
+/* Check for OpenSSL 1.0.2 which has ALPN support. */
+#undef HAS_ALPN
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L \
+    && !defined(OPENSSL_NO_TLSEXT)
+#  define HAS_ALPN 1
+#endif
+
+/* Check for OpenSSL 1.0.1 which has NPN support. */
+#undef HAS_NPN
+#if OPENSSL_VERSION_NUMBER >= 0x10001000L \
+    && !defined(OPENSSL_NO_TLSEXT) \
+    && !defined(OPENSSL_NO_NEXTPROTONEG)
+#  define HAS_NPN 1
+#endif
+
+#ifdef HAS_NPN
+
+/*
+ * in is a list of length prefixed strings. this function has to select
+ * the protocol we want to use from the list and write its string into out.
+ */
+
+static int
+select_next_protocol(unsigned char **out, unsigned char *outlen,
+                     const unsigned char *in, unsigned int inlen,
+                     const char *key, unsigned int keylen)
+{
+  unsigned int i;
+  for(i = 0; i + keylen <= inlen; i += in[i] + 1) {
+    if(memcmp(&in[i + 1], key, keylen) == 0) {
+      *out = (unsigned char *) &in[i + 1];
+      *outlen = in[i];
+      return 0;
+    }
+  }
+  return -1;
+}
+
+static int
+select_next_proto_cb(SSL *ssl,
+                     unsigned char **out, unsigned char *outlen,
+                     const unsigned char *in, unsigned int inlen,
+                     void *arg)
+{
+  struct connectdata *conn = (struct connectdata*) arg;
+
+  (void)ssl;
+
+#ifdef USE_NGHTTP2
+  if(conn->data->set.httpversion >= CURL_HTTP_VERSION_2 &&
+     !select_next_protocol(out, outlen, in, inlen, NGHTTP2_PROTO_VERSION_ID,
+                           NGHTTP2_PROTO_VERSION_ID_LEN)) {
+    infof(conn->data, "NPN, negotiated HTTP2 (%s)\n",
+          NGHTTP2_PROTO_VERSION_ID);
+    conn->negnpn = CURL_HTTP_VERSION_2;
+    return SSL_TLSEXT_ERR_OK;
+  }
+#endif
+
+  if(!select_next_protocol(out, outlen, in, inlen, ALPN_HTTP_1_1,
+                           ALPN_HTTP_1_1_LENGTH)) {
+    infof(conn->data, "NPN, negotiated HTTP1.1\n");
+    conn->negnpn = CURL_HTTP_VERSION_1_1;
+    return SSL_TLSEXT_ERR_OK;
+  }
+
+  infof(conn->data, "NPN, no overlap, use HTTP1.1\n");
+  *out = (unsigned char *)ALPN_HTTP_1_1;
+  *outlen = ALPN_HTTP_1_1_LENGTH;
+  conn->negnpn = CURL_HTTP_VERSION_1_1;
+
+  return SSL_TLSEXT_ERR_OK;
+}
+#endif /* HAS_NPN */
+
+static const char *
+get_ssl_version_txt(SSL *ssl)
+{
+  if(!ssl)
+    return "";
+
+  switch(SSL_version(ssl)) {
+#ifdef TLS1_3_VERSION
+  case TLS1_3_VERSION:
+    return "TLSv1.3";
+#endif
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+  case TLS1_2_VERSION:
+    return "TLSv1.2";
+  case TLS1_1_VERSION:
+    return "TLSv1.1";
+#endif
+  case TLS1_VERSION:
+    return "TLSv1.0";
+  case SSL3_VERSION:
+    return "SSLv3";
+  case SSL2_VERSION:
+    return "SSLv2";
+  }
+  return "unknown";
+}
+
+static CURLcode
+set_ssl_version_min_max(long *ctx_options, struct connectdata *conn,
+                        int sockindex)
+{
+#if (OPENSSL_VERSION_NUMBER < 0x1000100FL) || !defined(TLS1_3_VERSION)
+  /* convoluted #if condition just to avoid compiler warnings on unused
+     variable */
+  struct Curl_easy *data = conn->data;
+#endif
+  long ssl_version = SSL_CONN_CONFIG(version);
+  long ssl_version_max = SSL_CONN_CONFIG(version_max);
+
+  if(ssl_version_max == CURL_SSLVERSION_MAX_NONE) {
+    ssl_version_max = ssl_version << 16;
+  }
+
+  switch(ssl_version) {
+    case CURL_SSLVERSION_TLSv1_3:
+#ifdef TLS1_3_VERSION
+    {
+      struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+      SSL_CTX_set_max_proto_version(BACKEND->ctx, TLS1_3_VERSION);
+      *ctx_options |= SSL_OP_NO_TLSv1_2;
+    }
+#else
+      (void)sockindex;
+      failf(data, OSSL_PACKAGE " was built without TLS 1.3 support");
+      return CURLE_NOT_BUILT_IN;
+#endif
+      /* FALLTHROUGH */
+    case CURL_SSLVERSION_TLSv1_2:
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+      *ctx_options |= SSL_OP_NO_TLSv1_1;
+#else
+      failf(data, OSSL_PACKAGE " was built without TLS 1.2 support");
+      return CURLE_NOT_BUILT_IN;
+#endif
+      /* FALLTHROUGH */
+    case CURL_SSLVERSION_TLSv1_1:
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+      *ctx_options |= SSL_OP_NO_TLSv1;
+#else
+      failf(data, OSSL_PACKAGE " was built without TLS 1.1 support");
+      return CURLE_NOT_BUILT_IN;
+#endif
+      /* FALLTHROUGH */
+    case CURL_SSLVERSION_TLSv1_0:
+      *ctx_options |= SSL_OP_NO_SSLv2;
+      *ctx_options |= SSL_OP_NO_SSLv3;
+      break;
+  }
+
+  switch(ssl_version_max) {
+    case CURL_SSLVERSION_MAX_TLSv1_0:
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+      *ctx_options |= SSL_OP_NO_TLSv1_1;
+#endif
+      /* FALLTHROUGH */
+    case CURL_SSLVERSION_MAX_TLSv1_1:
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+      *ctx_options |= SSL_OP_NO_TLSv1_2;
+#endif
+      /* FALLTHROUGH */
+    case CURL_SSLVERSION_MAX_TLSv1_2:
+    case CURL_SSLVERSION_MAX_DEFAULT:
+#ifdef TLS1_3_VERSION
+      *ctx_options |= SSL_OP_NO_TLSv1_3;
+#endif
+      break;
+    case CURL_SSLVERSION_MAX_TLSv1_3:
+#ifdef TLS1_3_VERSION
+      break;
+#else
+      failf(data, OSSL_PACKAGE " was built without TLS 1.3 support");
+      return CURLE_NOT_BUILT_IN;
+#endif
+  }
+  return CURLE_OK;
+}
+
+static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
+{
+  CURLcode result = CURLE_OK;
+  char *ciphers;
+  struct Curl_easy *data = conn->data;
+  SSL_METHOD_QUAL SSL_METHOD *req_method = NULL;
+  X509_LOOKUP *lookup = NULL;
+  curl_socket_t sockfd = conn->sock[sockindex];
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  long ctx_options = 0;
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+  bool sni;
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+#ifdef ENABLE_IPV6
+  struct in6_addr addr;
+#else
+  struct in_addr addr;
+#endif
+#endif
+  long * const certverifyresult = SSL_IS_PROXY() ?
+    &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
+  const long int ssl_version = SSL_CONN_CONFIG(version);
+#ifdef USE_TLS_SRP
+  const enum CURL_TLSAUTH ssl_authtype = SSL_SET_OPTION(authtype);
+#endif
+  char * const ssl_cert = SSL_SET_OPTION(cert);
+  const char * const ssl_cert_type = SSL_SET_OPTION(cert_type);
+  const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
+  const char * const ssl_capath = SSL_CONN_CONFIG(CApath);
+  const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
+  const char * const ssl_crlfile = SSL_SET_OPTION(CRLfile);
+  char error_buffer[256];
+
+  DEBUGASSERT(ssl_connect_1 == connssl->connecting_state);
+
+  /* Make funny stuff to get random input */
+  result = Curl_ossl_seed(data);
+  if(result)
+    return result;
+
+  *certverifyresult = !X509_V_OK;
+
+  /* check to see if we've been told to use an explicit SSL/TLS version */
+
+  switch(ssl_version) {
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+  case CURL_SSLVERSION_TLSv1_0:
+  case CURL_SSLVERSION_TLSv1_1:
+  case CURL_SSLVERSION_TLSv1_2:
+  case CURL_SSLVERSION_TLSv1_3:
+    /* it will be handled later with the context options */
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \
+    !defined(LIBRESSL_VERSION_NUMBER)
+    req_method = TLS_client_method();
+#else
+    req_method = SSLv23_client_method();
+#endif
+    use_sni(TRUE);
+    break;
+  case CURL_SSLVERSION_SSLv2:
+#ifdef OPENSSL_NO_SSL2
+    failf(data, OSSL_PACKAGE " was built without SSLv2 support");
+    return CURLE_NOT_BUILT_IN;
+#else
+#ifdef USE_TLS_SRP
+    if(ssl_authtype == CURL_TLSAUTH_SRP)
+      return CURLE_SSL_CONNECT_ERROR;
+#endif
+    req_method = SSLv2_client_method();
+    use_sni(FALSE);
+    break;
+#endif
+  case CURL_SSLVERSION_SSLv3:
+#ifdef OPENSSL_NO_SSL3_METHOD
+    failf(data, OSSL_PACKAGE " was built without SSLv3 support");
+    return CURLE_NOT_BUILT_IN;
+#else
+#ifdef USE_TLS_SRP
+    if(ssl_authtype == CURL_TLSAUTH_SRP)
+      return CURLE_SSL_CONNECT_ERROR;
+#endif
+    req_method = SSLv3_client_method();
+    use_sni(FALSE);
+    break;
+#endif
+  default:
+    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  if(BACKEND->ctx)
+    SSL_CTX_free(BACKEND->ctx);
+  BACKEND->ctx = SSL_CTX_new(req_method);
+
+  if(!BACKEND->ctx) {
+    failf(data, "SSL: couldn't create a context: %s",
+          ossl_strerror(ERR_peek_error(), error_buffer, sizeof(error_buffer)));
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+#ifdef SSL_MODE_RELEASE_BUFFERS
+  SSL_CTX_set_mode(BACKEND->ctx, SSL_MODE_RELEASE_BUFFERS);
+#endif
+
+#ifdef SSL_CTRL_SET_MSG_CALLBACK
+  if(data->set.fdebug && data->set.verbose) {
+    /* the SSL trace callback is only used for verbose logging */
+    SSL_CTX_set_msg_callback(BACKEND->ctx, ssl_tls_trace);
+    SSL_CTX_set_msg_callback_arg(BACKEND->ctx, conn);
+  }
+#endif
+
+  /* OpenSSL contains code to work-around lots of bugs and flaws in various
+     SSL-implementations. SSL_CTX_set_options() is used to enabled those
+     work-arounds. The man page for this option states that SSL_OP_ALL enables
+     all the work-arounds and that "It is usually safe to use SSL_OP_ALL to
+     enable the bug workaround options if compatibility with somewhat broken
+     implementations is desired."
+
+     The "-no_ticket" option was introduced in Openssl0.9.8j. It's a flag to
+     disable "rfc4507bis session ticket support".  rfc4507bis was later turned
+     into the proper RFC5077 it seems: https://tools.ietf.org/html/rfc5077
+
+     The enabled extension concerns the session management. I wonder how often
+     libcurl stops a connection and then resumes a TLS session. also, sending
+     the session data is some overhead. .I suggest that you just use your
+     proposed patch (which explicitly disables TICKET).
+
+     If someone writes an application with libcurl and openssl who wants to
+     enable the feature, one can do this in the SSL callback.
+
+     SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG option enabling allowed proper
+     interoperability with web server Netscape Enterprise Server 2.0.1 which
+     was released back in 1996.
+
+     Due to CVE-2010-4180, option SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG has
+     become ineffective as of OpenSSL 0.9.8q and 1.0.0c. In order to mitigate
+     CVE-2010-4180 when using previous OpenSSL versions we no longer enable
+     this option regardless of OpenSSL version and SSL_OP_ALL definition.
+
+     OpenSSL added a work-around for a SSL 3.0/TLS 1.0 CBC vulnerability
+     (https://www.openssl.org/~bodo/tls-cbc.txt). In 0.9.6e they added a bit to
+     SSL_OP_ALL that _disables_ that work-around despite the fact that
+     SSL_OP_ALL is documented to do "rather harmless" workarounds. In order to
+     keep the secure work-around, the SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit
+     must not be set.
+  */
+
+  ctx_options = SSL_OP_ALL;
+
+#ifdef SSL_OP_NO_TICKET
+  ctx_options |= SSL_OP_NO_TICKET;
+#endif
+
+#ifdef SSL_OP_NO_COMPRESSION
+  ctx_options |= SSL_OP_NO_COMPRESSION;
+#endif
+
+#ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
+  /* mitigate CVE-2010-4180 */
+  ctx_options &= ~SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG;
+#endif
+
+#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
+  /* unless the user explicitly ask to allow the protocol vulnerability we
+     use the work-around */
+  if(!SSL_SET_OPTION(enable_beast))
+    ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
+#endif
+
+  switch(ssl_version) {
+  case CURL_SSLVERSION_SSLv3:
+#ifdef USE_TLS_SRP
+    if(ssl_authtype == CURL_TLSAUTH_SRP) {
+      infof(data, "Set version TLSv1.x for SRP authorisation\n");
+    }
+#endif
+    ctx_options |= SSL_OP_NO_SSLv2;
+    ctx_options |= SSL_OP_NO_TLSv1;
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+    ctx_options |= SSL_OP_NO_TLSv1_1;
+    ctx_options |= SSL_OP_NO_TLSv1_2;
+#ifdef TLS1_3_VERSION
+    ctx_options |= SSL_OP_NO_TLSv1_3;
+#endif
+#endif
+    break;
+
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+    ctx_options |= SSL_OP_NO_SSLv2;
+    ctx_options |= SSL_OP_NO_SSLv3;
+    break;
+
+  case CURL_SSLVERSION_TLSv1_0:
+  case CURL_SSLVERSION_TLSv1_1:
+  case CURL_SSLVERSION_TLSv1_2:
+  case CURL_SSLVERSION_TLSv1_3:
+    result = set_ssl_version_min_max(&ctx_options, conn, sockindex);
+    if(result != CURLE_OK)
+       return result;
+    break;
+
+  case CURL_SSLVERSION_SSLv2:
+#ifndef OPENSSL_NO_SSL2
+    ctx_options |= SSL_OP_NO_SSLv3;
+    ctx_options |= SSL_OP_NO_TLSv1;
+#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
+    ctx_options |= SSL_OP_NO_TLSv1_1;
+    ctx_options |= SSL_OP_NO_TLSv1_2;
+#ifdef TLS1_3_VERSION
+    ctx_options |= SSL_OP_NO_TLSv1_3;
+#endif
+#endif
+    break;
+#else
+    failf(data, OSSL_PACKAGE " was built without SSLv2 support");
+    return CURLE_NOT_BUILT_IN;
+#endif
+
+  default:
+    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  SSL_CTX_set_options(BACKEND->ctx, ctx_options);
+
+#ifdef HAS_NPN
+  if(conn->bits.tls_enable_npn)
+    SSL_CTX_set_next_proto_select_cb(BACKEND->ctx, select_next_proto_cb, conn);
+#endif
+
+#ifdef HAS_ALPN
+  if(conn->bits.tls_enable_alpn) {
+    int cur = 0;
+    unsigned char protocols[128];
+
+#ifdef USE_NGHTTP2
+    if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
+       (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)) {
+      protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN;
+
+      memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID,
+          NGHTTP2_PROTO_VERSION_ID_LEN);
+      cur += NGHTTP2_PROTO_VERSION_ID_LEN;
+      infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+    }
+#endif
+
+    protocols[cur++] = ALPN_HTTP_1_1_LENGTH;
+    memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
+    cur += ALPN_HTTP_1_1_LENGTH;
+    infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
+
+    /* expects length prefixed preference ordered list of protocols in wire
+     * format
+     */
+    SSL_CTX_set_alpn_protos(BACKEND->ctx, protocols, cur);
+  }
+#endif
+
+  if(ssl_cert || ssl_cert_type) {
+    if(!cert_stuff(conn, BACKEND->ctx, ssl_cert, ssl_cert_type,
+                   SSL_SET_OPTION(key), SSL_SET_OPTION(key_type),
+                   SSL_SET_OPTION(key_passwd))) {
+      /* failf() is already done in cert_stuff() */
+      return CURLE_SSL_CERTPROBLEM;
+    }
+  }
+
+  ciphers = SSL_CONN_CONFIG(cipher_list);
+  if(!ciphers)
+    ciphers = (char *)DEFAULT_CIPHER_SELECTION;
+  if(ciphers) {
+    if(!SSL_CTX_set_cipher_list(BACKEND->ctx, ciphers)) {
+      failf(data, "failed setting cipher list: %s", ciphers);
+      return CURLE_SSL_CIPHER;
+    }
+    infof(data, "Cipher selection: %s\n", ciphers);
+  }
+
+#ifdef USE_TLS_SRP
+  if(ssl_authtype == CURL_TLSAUTH_SRP) {
+    char * const ssl_username = SSL_SET_OPTION(username);
+
+    infof(data, "Using TLS-SRP username: %s\n", ssl_username);
+
+    if(!SSL_CTX_set_srp_username(BACKEND->ctx, ssl_username)) {
+      failf(data, "Unable to set SRP user name");
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    }
+    if(!SSL_CTX_set_srp_password(BACKEND->ctx, SSL_SET_OPTION(password))) {
+      failf(data, "failed setting SRP password");
+      return CURLE_BAD_FUNCTION_ARGUMENT;
+    }
+    if(!SSL_CONN_CONFIG(cipher_list)) {
+      infof(data, "Setting cipher list SRP\n");
+
+      if(!SSL_CTX_set_cipher_list(BACKEND->ctx, "SRP")) {
+        failf(data, "failed setting SRP cipher list");
+        return CURLE_SSL_CIPHER;
+      }
+    }
+  }
+#endif
+
+  if(ssl_cafile || ssl_capath) {
+    /* tell SSL where to find CA certificates that are used to verify
+       the servers certificate. */
+    if(!SSL_CTX_load_verify_locations(BACKEND->ctx, ssl_cafile, ssl_capath)) {
+      if(verifypeer) {
+        /* Fail if we insist on successfully verifying the server. */
+        failf(data, "error setting certificate verify locations:\n"
+              "  CAfile: %s\n  CApath: %s",
+              ssl_cafile ? ssl_cafile : "none",
+              ssl_capath ? ssl_capath : "none");
+        return CURLE_SSL_CACERT_BADFILE;
+      }
+      /* Just continue with a warning if no strict  certificate verification
+         is required. */
+      infof(data, "error setting certificate verify locations,"
+            " continuing anyway:\n");
+    }
+    else {
+      /* Everything is fine. */
+      infof(data, "successfully set certificate verify locations:\n");
+    }
+    infof(data,
+          "  CAfile: %s\n"
+          "  CApath: %s\n",
+          ssl_cafile ? ssl_cafile : "none",
+          ssl_capath ? ssl_capath : "none");
+  }
+#ifdef CURL_CA_FALLBACK
+  else if(verifypeer) {
+    /* verfying the peer without any CA certificates won't
+       work so use openssl's built in default as fallback */
+    SSL_CTX_set_default_verify_paths(BACKEND->ctx);
+  }
+#endif
+
+  if(ssl_crlfile) {
+    /* tell SSL where to find CRL file that is used to check certificate
+     * revocation */
+    lookup = X509_STORE_add_lookup(SSL_CTX_get_cert_store(BACKEND->ctx),
+                                 X509_LOOKUP_file());
+    if(!lookup ||
+       (!X509_load_crl_file(lookup, ssl_crlfile, X509_FILETYPE_PEM)) ) {
+      failf(data, "error loading CRL file: %s", ssl_crlfile);
+      return CURLE_SSL_CRL_BADFILE;
+    }
+    /* Everything is fine. */
+    infof(data, "successfully load CRL file:\n");
+    X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx),
+                         X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
+
+    infof(data, "  CRLfile: %s\n", ssl_crlfile);
+  }
+
+  /* Try building a chain using issuers in the trusted store first to avoid
+  problems with server-sent legacy intermediates.
+  Newer versions of OpenSSL do alternate chain checking by default which
+  gives us the same fix without as much of a performance hit (slight), so we
+  prefer that if available.
+  https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest
+  */
+#if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS)
+  if(verifypeer) {
+    X509_STORE_set_flags(SSL_CTX_get_cert_store(BACKEND->ctx),
+                         X509_V_FLAG_TRUSTED_FIRST);
+  }
+#endif
+
+  /* SSL always tries to verify the peer, this only says whether it should
+   * fail to connect if the verification fails, or if it should continue
+   * anyway. In the latter case the result of the verification is checked with
+   * SSL_get_verify_result() below. */
+  SSL_CTX_set_verify(BACKEND->ctx,
+                     verifypeer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
+
+  /* Enable logging of secrets to the file specified in env SSLKEYLOGFILE. */
+#if defined(ENABLE_SSLKEYLOGFILE) && defined(HAVE_KEYLOG_CALLBACK)
+  if(keylog_file) {
+    SSL_CTX_set_keylog_callback(connssl->ctx, ossl_keylog_callback);
+  }
+#endif
+
+  /* give application a chance to interfere with SSL set up. */
+  if(data->set.ssl.fsslctx) {
+    result = (*data->set.ssl.fsslctx)(data, BACKEND->ctx,
+                                      data->set.ssl.fsslctxp);
+    if(result) {
+      failf(data, "error signaled by ssl ctx callback");
+      return result;
+    }
+  }
+
+  /* Lets make an SSL structure */
+  if(BACKEND->handle)
+    SSL_free(BACKEND->handle);
+  BACKEND->handle = SSL_new(BACKEND->ctx);
+  if(!BACKEND->handle) {
+    failf(data, "SSL: couldn't create a context (handle)!");
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
+    !defined(OPENSSL_NO_OCSP)
+  if(SSL_CONN_CONFIG(verifystatus))
+    SSL_set_tlsext_status_type(BACKEND->handle, TLSEXT_STATUSTYPE_ocsp);
+#endif
+
+  SSL_set_connect_state(BACKEND->handle);
+
+  BACKEND->server_cert = 0x0;
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+  if((0 == Curl_inet_pton(AF_INET, hostname, &addr)) &&
+#ifdef ENABLE_IPV6
+     (0 == Curl_inet_pton(AF_INET6, hostname, &addr)) &&
+#endif
+     sni &&
+     !SSL_set_tlsext_host_name(BACKEND->handle, hostname))
+    infof(data, "WARNING: failed to configure server name indication (SNI) "
+          "TLS extension\n");
+#endif
+
+  /* Check if there's a cached ID we can/should use here! */
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    void *ssl_sessionid = NULL;
+
+    Curl_ssl_sessionid_lock(conn);
+    if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL, sockindex)) {
+      /* we got a session id, use it! */
+      if(!SSL_set_session(BACKEND->handle, ssl_sessionid)) {
+        Curl_ssl_sessionid_unlock(conn);
+        failf(data, "SSL: SSL_set_session failed: %s",
+              ossl_strerror(ERR_get_error(), error_buffer,
+                            sizeof(error_buffer)));
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      /* Informational message */
+      infof(data, "SSL re-using session ID\n");
+    }
+    Curl_ssl_sessionid_unlock(conn);
+  }
+
+  if(conn->proxy_ssl[sockindex].use) {
+    BIO *const bio = BIO_new(BIO_f_ssl());
+    SSL *handle = conn->proxy_ssl[sockindex].backend->handle;
+    DEBUGASSERT(ssl_connection_complete == conn->proxy_ssl[sockindex].state);
+    DEBUGASSERT(handle != NULL);
+    DEBUGASSERT(bio != NULL);
+    BIO_set_ssl(bio, handle, FALSE);
+    SSL_set_bio(BACKEND->handle, bio, bio);
+  }
+  else if(!SSL_set_fd(BACKEND->handle, (int)sockfd)) {
+    /* pass the raw socket into the SSL layers */
+    failf(data, "SSL: SSL_set_fd failed: %s",
+          ossl_strerror(ERR_get_error(), error_buffer, sizeof(error_buffer)));
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  connssl->connecting_state = ssl_connect_2;
+
+  return CURLE_OK;
+}
+
+static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  int err;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  long * const certverifyresult = SSL_IS_PROXY() ?
+    &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
+  DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
+              || ssl_connect_2_reading == connssl->connecting_state
+              || ssl_connect_2_writing == connssl->connecting_state);
+
+  ERR_clear_error();
+
+  err = SSL_connect(BACKEND->handle);
+  /* If keylogging is enabled but the keylog callback is not supported then log
+     secrets here, immediately after SSL_connect by using tap_ssl_key. */
+#if defined(ENABLE_SSLKEYLOGFILE) && !defined(HAVE_KEYLOG_CALLBACK)
+  tap_ssl_key(BACKEND->handle, &BACKEND->tap_state);
+#endif
+
+  /* 1  is fine
+     0  is "not successful but was shut down controlled"
+     <0 is "handshake was not successful, because a fatal error occurred" */
+  if(1 != err) {
+    int detail = SSL_get_error(BACKEND->handle, err);
+
+    if(SSL_ERROR_WANT_READ == detail) {
+      connssl->connecting_state = ssl_connect_2_reading;
+      return CURLE_OK;
+    }
+    if(SSL_ERROR_WANT_WRITE == detail) {
+      connssl->connecting_state = ssl_connect_2_writing;
+      return CURLE_OK;
+    }
+    else {
+      /* untreated error */
+      unsigned long errdetail;
+      char error_buffer[256]="";
+      CURLcode result;
+      long lerr;
+      int lib;
+      int reason;
+
+      /* the connection failed, we're not waiting for anything else. */
+      connssl->connecting_state = ssl_connect_2;
+
+      /* Get the earliest error code from the thread's error queue and removes
+         the entry. */
+      errdetail = ERR_get_error();
+
+      /* Extract which lib and reason */
+      lib = ERR_GET_LIB(errdetail);
+      reason = ERR_GET_REASON(errdetail);
+
+      if((lib == ERR_LIB_SSL) &&
+         (reason == SSL_R_CERTIFICATE_VERIFY_FAILED)) {
+        result = CURLE_SSL_CACERT;
+
+        lerr = SSL_get_verify_result(BACKEND->handle);
+        if(lerr != X509_V_OK) {
+          *certverifyresult = lerr;
+          snprintf(error_buffer, sizeof(error_buffer),
+                   "SSL certificate problem: %s",
+                   X509_verify_cert_error_string(lerr));
+        }
+        else
+          /* strcpy() is fine here as long as the string fits within
+             error_buffer */
+          strcpy(error_buffer, "SSL certificate verification failed");
+      }
+      else {
+        result = CURLE_SSL_CONNECT_ERROR;
+        ossl_strerror(errdetail, error_buffer, sizeof(error_buffer));
+      }
+
+      /* detail is already set to the SSL error above */
+
+      /* If we e.g. use SSLv2 request-method and the server doesn't like us
+       * (RST connection etc.), OpenSSL gives no explanation whatsoever and
+       * the SO_ERROR is also lost.
+       */
+      if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) {
+        const char * const hostname = SSL_IS_PROXY() ?
+          conn->http_proxy.host.name : conn->host.name;
+        const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
+        failf(data, OSSL_PACKAGE " SSL_connect: %s in connection to %s:%ld ",
+              SSL_ERROR_to_str(detail), hostname, port);
+        return result;
+      }
+
+      /* Could be a CERT problem */
+      failf(data, "%s", error_buffer);
+
+      return result;
+    }
+  }
+  else {
+    /* we have been connected fine, we're not waiting for anything else. */
+    connssl->connecting_state = ssl_connect_3;
+
+    /* Informational message */
+    infof(data, "SSL connection using %s / %s\n",
+          get_ssl_version_txt(BACKEND->handle),
+          SSL_get_cipher(BACKEND->handle));
+
+#ifdef HAS_ALPN
+    /* Sets data and len to negotiated protocol, len is 0 if no protocol was
+     * negotiated
+     */
+    if(conn->bits.tls_enable_alpn) {
+      const unsigned char *neg_protocol;
+      unsigned int len;
+      SSL_get0_alpn_selected(BACKEND->handle, &neg_protocol, &len);
+      if(len != 0) {
+        infof(data, "ALPN, server accepted to use %.*s\n", len, neg_protocol);
+
+#ifdef USE_NGHTTP2
+        if(len == NGHTTP2_PROTO_VERSION_ID_LEN &&
+           !memcmp(NGHTTP2_PROTO_VERSION_ID, neg_protocol, len)) {
+          conn->negnpn = CURL_HTTP_VERSION_2;
+        }
+        else
+#endif
+        if(len == ALPN_HTTP_1_1_LENGTH &&
+           !memcmp(ALPN_HTTP_1_1, neg_protocol, ALPN_HTTP_1_1_LENGTH)) {
+          conn->negnpn = CURL_HTTP_VERSION_1_1;
+        }
+      }
+      else
+        infof(data, "ALPN, server did not agree to a protocol\n");
+    }
+#endif
+
+    return CURLE_OK;
+  }
+}
+
+static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len)
+{
+  int i, ilen;
+
+  ilen = (int)len;
+  if(ilen < 0)
+    return 1; /* buffer too big */
+
+  i = i2t_ASN1_OBJECT(buf, ilen, a);
+
+  if(i >= ilen)
+    return 1; /* buffer too small */
+
+  return 0;
+}
+
+#define push_certinfo(_label, _num) \
+do {                              \
+  long info_len = BIO_get_mem_data(mem, &ptr); \
+  Curl_ssl_push_certinfo_len(data, _num, _label, ptr, info_len); \
+  if(1 != BIO_reset(mem))                                        \
+    break;                                                       \
+} WHILE_FALSE
+
+static void pubkey_show(struct Curl_easy *data,
+                        BIO *mem,
+                        int num,
+                        const char *type,
+                        const char *name,
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+                        const
+#endif
+                        BIGNUM *bn)
+{
+  char *ptr;
+  char namebuf[32];
+
+  snprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name);
+
+  if(bn)
+    BN_print(mem, bn);
+  push_certinfo(namebuf, num);
+}
+
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+#define print_pubkey_BN(_type, _name, _num)              \
+  pubkey_show(data, mem, _num, #_type, #_name, _name)
+
+#else
+#define print_pubkey_BN(_type, _name, _num)    \
+do {                              \
+  if(_type->_name) { \
+    pubkey_show(data, mem, _num, #_type, #_name, _type->_name); \
+  } \
+} WHILE_FALSE
+#endif
+
+static int X509V3_ext(struct Curl_easy *data,
+                      int certnum,
+                      CONST_EXTS STACK_OF(X509_EXTENSION) *exts)
+{
+  int i;
+  size_t j;
+
+  if((int)sk_X509_EXTENSION_num(exts) <= 0)
+    /* no extensions, bail out */
+    return 1;
+
+  for(i = 0; i < (int)sk_X509_EXTENSION_num(exts); i++) {
+    ASN1_OBJECT *obj;
+    X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
+    BUF_MEM *biomem;
+    char buf[512];
+    char *ptr = buf;
+    char namebuf[128];
+    BIO *bio_out = BIO_new(BIO_s_mem());
+
+    if(!bio_out)
+      return 1;
+
+    obj = X509_EXTENSION_get_object(ext);
+
+    asn1_object_dump(obj, namebuf, sizeof(namebuf));
+
+    if(!X509V3_EXT_print(bio_out, ext, 0, 0))
+      ASN1_STRING_print(bio_out, (ASN1_STRING *)X509_EXTENSION_get_data(ext));
+
+    BIO_get_mem_ptr(bio_out, &biomem);
+
+    for(j = 0; j < (size_t)biomem->length; j++) {
+      const char *sep = "";
+      if(biomem->data[j] == '\n') {
+        sep = ", ";
+        j++; /* skip the newline */
+      };
+      while((j<(size_t)biomem->length) && (biomem->data[j] == ' '))
+        j++;
+      if(j<(size_t)biomem->length)
+        ptr += snprintf(ptr, sizeof(buf)-(ptr-buf), "%s%c", sep,
+                        biomem->data[j]);
+    }
+
+    Curl_ssl_push_certinfo(data, certnum, namebuf, buf);
+
+    BIO_free(bio_out);
+
+  }
+  return 0; /* all is fine */
+}
+
+static CURLcode get_cert_chain(struct connectdata *conn,
+                               struct ssl_connect_data *connssl)
+
+{
+  CURLcode result;
+  STACK_OF(X509) *sk;
+  int i;
+  struct Curl_easy *data = conn->data;
+  int numcerts;
+  BIO *mem;
+
+  sk = SSL_get_peer_cert_chain(BACKEND->handle);
+  if(!sk) {
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  numcerts = sk_X509_num(sk);
+
+  result = Curl_ssl_init_certinfo(data, numcerts);
+  if(result) {
+    return result;
+  }
+
+  mem = BIO_new(BIO_s_mem());
+
+  for(i = 0; i < numcerts; i++) {
+    ASN1_INTEGER *num;
+    X509 *x = sk_X509_value(sk, i);
+    EVP_PKEY *pubkey = NULL;
+    int j;
+    char *ptr;
+    const ASN1_BIT_STRING *psig = NULL;
+
+    X509_NAME_print_ex(mem, X509_get_subject_name(x), 0, XN_FLAG_ONELINE);
+    push_certinfo("Subject", i);
+
+    X509_NAME_print_ex(mem, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE);
+    push_certinfo("Issuer", i);
+
+    BIO_printf(mem, "%lx", X509_get_version(x));
+    push_certinfo("Version", i);
+
+    num = X509_get_serialNumber(x);
+    if(num->type == V_ASN1_NEG_INTEGER)
+      BIO_puts(mem, "-");
+    for(j = 0; j < num->length; j++)
+      BIO_printf(mem, "%02x", num->data[j]);
+    push_certinfo("Serial Number", i);
+
+#if defined(HAVE_X509_GET0_SIGNATURE) && defined(HAVE_X509_GET0_EXTENSIONS)
+    {
+      const X509_ALGOR *palg = NULL;
+      ASN1_STRING *a = ASN1_STRING_new();
+      if(a) {
+        X509_get0_signature(&psig, &palg, x);
+        X509_signature_print(mem, palg, a);
+        ASN1_STRING_free(a);
+
+        if(palg) {
+          i2a_ASN1_OBJECT(mem, palg->algorithm);
+          push_certinfo("Public Key Algorithm", i);
+        }
+      }
+      X509V3_ext(data, i, X509_get0_extensions(x));
+    }
+#else
+    {
+      /* before OpenSSL 1.0.2 */
+      X509_CINF *cinf = x->cert_info;
+
+      i2a_ASN1_OBJECT(mem, cinf->signature->algorithm);
+      push_certinfo("Signature Algorithm", i);
+
+      i2a_ASN1_OBJECT(mem, cinf->key->algor->algorithm);
+      push_certinfo("Public Key Algorithm", i);
+
+      X509V3_ext(data, i, cinf->extensions);
+
+      psig = x->signature;
+    }
+#endif
+
+    ASN1_TIME_print(mem, X509_get0_notBefore(x));
+    push_certinfo("Start date", i);
+
+    ASN1_TIME_print(mem, X509_get0_notAfter(x));
+    push_certinfo("Expire date", i);
+
+    pubkey = X509_get_pubkey(x);
+    if(!pubkey)
+      infof(data, "   Unable to load public key\n");
+    else {
+      int pktype;
+#ifdef HAVE_OPAQUE_EVP_PKEY
+      pktype = EVP_PKEY_id(pubkey);
+#else
+      pktype = pubkey->type;
+#endif
+      switch(pktype) {
+      case EVP_PKEY_RSA:
+      {
+        RSA *rsa;
+#ifdef HAVE_OPAQUE_EVP_PKEY
+        rsa = EVP_PKEY_get0_RSA(pubkey);
+#else
+        rsa = pubkey->pkey.rsa;
+#endif
+
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+        {
+          const BIGNUM *n;
+          const BIGNUM *e;
+
+          RSA_get0_key(rsa, &n, &e, NULL);
+          BN_print(mem, n);
+          push_certinfo("RSA Public Key", i);
+          print_pubkey_BN(rsa, n, i);
+          print_pubkey_BN(rsa, e, i);
+        }
+#else
+        BIO_printf(mem, "%d", BN_num_bits(rsa->n));
+        push_certinfo("RSA Public Key", i);
+        print_pubkey_BN(rsa, n, i);
+        print_pubkey_BN(rsa, e, i);
+#endif
+
+        break;
+      }
+      case EVP_PKEY_DSA:
+      {
+#ifndef OPENSSL_NO_DSA
+        DSA *dsa;
+#ifdef HAVE_OPAQUE_EVP_PKEY
+        dsa = EVP_PKEY_get0_DSA(pubkey);
+#else
+        dsa = pubkey->pkey.dsa;
+#endif
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+        {
+          const BIGNUM *p;
+          const BIGNUM *q;
+          const BIGNUM *g;
+          const BIGNUM *pub_key;
+
+          DSA_get0_pqg(dsa, &p, &q, &g);
+          DSA_get0_key(dsa, &pub_key, NULL);
+
+          print_pubkey_BN(dsa, p, i);
+          print_pubkey_BN(dsa, q, i);
+          print_pubkey_BN(dsa, g, i);
+          print_pubkey_BN(dsa, pub_key, i);
+        }
+#else
+        print_pubkey_BN(dsa, p, i);
+        print_pubkey_BN(dsa, q, i);
+        print_pubkey_BN(dsa, g, i);
+        print_pubkey_BN(dsa, pub_key, i);
+#endif
+#endif /* !OPENSSL_NO_DSA */
+        break;
+      }
+      case EVP_PKEY_DH:
+      {
+        DH *dh;
+#ifdef HAVE_OPAQUE_EVP_PKEY
+        dh = EVP_PKEY_get0_DH(pubkey);
+#else
+        dh = pubkey->pkey.dh;
+#endif
+#ifdef HAVE_OPAQUE_RSA_DSA_DH
+        {
+          const BIGNUM *p;
+          const BIGNUM *q;
+          const BIGNUM *g;
+          const BIGNUM *pub_key;
+          DH_get0_pqg(dh, &p, &q, &g);
+          DH_get0_key(dh, &pub_key, NULL);
+          print_pubkey_BN(dh, p, i);
+          print_pubkey_BN(dh, q, i);
+          print_pubkey_BN(dh, g, i);
+          print_pubkey_BN(dh, pub_key, i);
+       }
+#else
+        print_pubkey_BN(dh, p, i);
+        print_pubkey_BN(dh, g, i);
+        print_pubkey_BN(dh, pub_key, i);
+#endif
+        break;
+      }
+#if 0
+      case EVP_PKEY_EC: /* symbol not present in OpenSSL 0.9.6 */
+        /* left TODO */
+        break;
+#endif
+      }
+      EVP_PKEY_free(pubkey);
+    }
+
+    if(psig) {
+      for(j = 0; j < psig->length; j++)
+        BIO_printf(mem, "%02x:", psig->data[j]);
+      push_certinfo("Signature", i);
+    }
+
+    PEM_write_bio_X509(mem, x);
+    push_certinfo("Cert", i);
+  }
+
+  BIO_free(mem);
+
+  return CURLE_OK;
+}
+
+/*
+ * Heavily modified from:
+ * https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL
+ */
+static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data, X509* cert,
+                                    const char *pinnedpubkey)
+{
+  /* Scratch */
+  int len1 = 0, len2 = 0;
+  unsigned char *buff1 = NULL, *temp = NULL;
+
+  /* Result is returned to caller */
+  CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+
+  /* if a path wasn't specified, don't pin */
+  if(!pinnedpubkey)
+    return CURLE_OK;
+
+  if(!cert)
+    return result;
+
+  do {
+    /* Begin Gyrations to get the subjectPublicKeyInfo     */
+    /* Thanks to Viktor Dukhovni on the OpenSSL mailing list */
+
+    /* https://groups.google.com/group/mailing.openssl.users/browse_thread
+     /thread/d61858dae102c6c7 */
+    len1 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), NULL);
+    if(len1 < 1)
+      break; /* failed */
+
+    /* https://www.openssl.org/docs/crypto/buffer.html */
+    buff1 = temp = malloc(len1);
+    if(!buff1)
+      break; /* failed */
+
+    /* https://www.openssl.org/docs/crypto/d2i_X509.html */
+    len2 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &temp);
+
+    /*
+     * These checks are verifying we got back the same values as when we
+     * sized the buffer. It's pretty weak since they should always be the
+     * same. But it gives us something to test.
+     */
+    if((len1 != len2) || !temp || ((temp - buff1) != len1))
+      break; /* failed */
+
+    /* End Gyrations */
+
+    /* The one good exit point */
+    result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1);
+  } while(0);
+
+  /* https://www.openssl.org/docs/crypto/buffer.html */
+  if(buff1)
+    free(buff1);
+
+  return result;
+}
+
+/*
+ * Get the server cert, verify it and show it etc, only call failf() if the
+ * 'strict' argument is TRUE as otherwise all this is for informational
+ * purposes only!
+ *
+ * We check certificates to authenticate the server; otherwise we risk
+ * man-in-the-middle attack.
+ */
+static CURLcode servercert(struct connectdata *conn,
+                           struct ssl_connect_data *connssl,
+                           bool strict)
+{
+  CURLcode result = CURLE_OK;
+  int rc;
+  long lerr, len;
+  struct Curl_easy *data = conn->data;
+  X509 *issuer;
+  FILE *fp;
+  char buffer[2048];
+  const char *ptr;
+  long * const certverifyresult = SSL_IS_PROXY() ?
+    &data->set.proxy_ssl.certverifyresult : &data->set.ssl.certverifyresult;
+  BIO *mem = BIO_new(BIO_s_mem());
+
+  if(data->set.ssl.certinfo)
+    /* we've been asked to gather certificate info! */
+    (void)get_cert_chain(conn, connssl);
+
+  BACKEND->server_cert = SSL_get_peer_certificate(BACKEND->handle);
+  if(!BACKEND->server_cert) {
+    BIO_free(mem);
+    if(!strict)
+      return CURLE_OK;
+
+    failf(data, "SSL: couldn't get peer certificate!");
+    return CURLE_PEER_FAILED_VERIFICATION;
+  }
+
+  infof(data, "%s certificate:\n", SSL_IS_PROXY() ? "Proxy" : "Server");
+
+  rc = x509_name_oneline(X509_get_subject_name(BACKEND->server_cert),
+                         buffer, sizeof(buffer));
+  infof(data, " subject: %s\n", rc?"[NONE]":buffer);
+
+  ASN1_TIME_print(mem, X509_get0_notBefore(BACKEND->server_cert));
+  len = BIO_get_mem_data(mem, (char **) &ptr);
+  infof(data, " start date: %.*s\n", len, ptr);
+  (void)BIO_reset(mem);
+
+  ASN1_TIME_print(mem, X509_get0_notAfter(BACKEND->server_cert));
+  len = BIO_get_mem_data(mem, (char **) &ptr);
+  infof(data, " expire date: %.*s\n", len, ptr);
+  (void)BIO_reset(mem);
+
+  BIO_free(mem);
+
+  if(SSL_CONN_CONFIG(verifyhost)) {
+    result = verifyhost(conn, BACKEND->server_cert);
+    if(result) {
+      X509_free(BACKEND->server_cert);
+      BACKEND->server_cert = NULL;
+      return result;
+    }
+  }
+
+  rc = x509_name_oneline(X509_get_issuer_name(BACKEND->server_cert),
+                         buffer, sizeof(buffer));
+  if(rc) {
+    if(strict)
+      failf(data, "SSL: couldn't get X509-issuer name!");
+    result = CURLE_SSL_CONNECT_ERROR;
+  }
+  else {
+    infof(data, " issuer: %s\n", buffer);
+
+    /* We could do all sorts of certificate verification stuff here before
+       deallocating the certificate. */
+
+    /* e.g. match issuer name with provided issuer certificate */
+    if(SSL_SET_OPTION(issuercert)) {
+      fp = fopen(SSL_SET_OPTION(issuercert), FOPEN_READTEXT);
+      if(!fp) {
+        if(strict)
+          failf(data, "SSL: Unable to open issuer cert (%s)",
+                SSL_SET_OPTION(issuercert));
+        X509_free(BACKEND->server_cert);
+        BACKEND->server_cert = NULL;
+        return CURLE_SSL_ISSUER_ERROR;
+      }
+
+      issuer = PEM_read_X509(fp, NULL, ZERO_NULL, NULL);
+      if(!issuer) {
+        if(strict)
+          failf(data, "SSL: Unable to read issuer cert (%s)",
+                SSL_SET_OPTION(issuercert));
+        X509_free(BACKEND->server_cert);
+        X509_free(issuer);
+        fclose(fp);
+        return CURLE_SSL_ISSUER_ERROR;
+      }
+
+      fclose(fp);
+
+      if(X509_check_issued(issuer, BACKEND->server_cert) != X509_V_OK) {
+        if(strict)
+          failf(data, "SSL: Certificate issuer check failed (%s)",
+                SSL_SET_OPTION(issuercert));
+        X509_free(BACKEND->server_cert);
+        X509_free(issuer);
+        BACKEND->server_cert = NULL;
+        return CURLE_SSL_ISSUER_ERROR;
+      }
+
+      infof(data, " SSL certificate issuer check ok (%s)\n",
+            SSL_SET_OPTION(issuercert));
+      X509_free(issuer);
+    }
+
+    lerr = *certverifyresult = SSL_get_verify_result(BACKEND->handle);
+
+    if(*certverifyresult != X509_V_OK) {
+      if(SSL_CONN_CONFIG(verifypeer)) {
+        /* We probably never reach this, because SSL_connect() will fail
+           and we return earlier if verifypeer is set? */
+        if(strict)
+          failf(data, "SSL certificate verify result: %s (%ld)",
+                X509_verify_cert_error_string(lerr), lerr);
+        result = CURLE_PEER_FAILED_VERIFICATION;
+      }
+      else
+        infof(data, " SSL certificate verify result: %s (%ld),"
+              " continuing anyway.\n",
+              X509_verify_cert_error_string(lerr), lerr);
+    }
+    else
+      infof(data, " SSL certificate verify ok.\n");
+  }
+
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
+    !defined(OPENSSL_NO_OCSP)
+  if(SSL_CONN_CONFIG(verifystatus)) {
+    result = verifystatus(conn, connssl);
+    if(result) {
+      X509_free(BACKEND->server_cert);
+      BACKEND->server_cert = NULL;
+      return result;
+    }
+  }
+#endif
+
+  if(!strict)
+    /* when not strict, we don't bother about the verify cert problems */
+    result = CURLE_OK;
+
+  ptr = SSL_IS_PROXY() ? data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
+                         data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+  if(!result && ptr) {
+    result = pkp_pin_peer_pubkey(data, BACKEND->server_cert, ptr);
+    if(result)
+      failf(data, "SSL: public key does not match pinned public key!");
+  }
+
+  X509_free(BACKEND->server_cert);
+  BACKEND->server_cert = NULL;
+  connssl->connecting_state = ssl_connect_done;
+
+  return result;
+}
+
+static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    bool incache;
+    SSL_SESSION *our_ssl_sessionid;
+    void *old_ssl_sessionid = NULL;
+
+    our_ssl_sessionid = SSL_get1_session(BACKEND->handle);
+
+    /* SSL_get1_session() will increment the reference count and the session
+        will stay in memory until explicitly freed with SSL_SESSION_free(3),
+        regardless of its state. */
+
+    Curl_ssl_sessionid_lock(conn);
+    incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL,
+                                      sockindex));
+    if(incache) {
+      if(old_ssl_sessionid != our_ssl_sessionid) {
+        infof(data, "old SSL session ID is stale, removing\n");
+        Curl_ssl_delsessionid(conn, old_ssl_sessionid);
+        incache = FALSE;
+      }
+    }
+
+    if(!incache) {
+      result = Curl_ssl_addsessionid(conn, our_ssl_sessionid,
+                                      0 /* unknown size */, sockindex);
+      if(result) {
+        Curl_ssl_sessionid_unlock(conn);
+        failf(data, "failed to store ssl session");
+        return result;
+      }
+    }
+    else {
+      /* Session was incache, so refcount already incremented earlier.
+        * Avoid further increments with each SSL_get1_session() call.
+        * This does not free the session as refcount remains > 0
+        */
+      SSL_SESSION_free(our_ssl_sessionid);
+    }
+    Curl_ssl_sessionid_unlock(conn);
+  }
+
+  /*
+   * We check certificates to authenticate the server; otherwise we risk
+   * man-in-the-middle attack; NEVERTHELESS, if we're told explicitly not to
+   * verify the peer ignore faults and failures from the server cert
+   * operations.
+   */
+
+  result = servercert(conn, connssl, (SSL_CONN_CONFIG(verifypeer) ||
+                                      SSL_CONN_CONFIG(verifyhost)));
+
+  if(!result)
+    connssl->connecting_state = ssl_connect_done;
+
+  return result;
+}
+
+static Curl_recv ossl_recv;
+static Curl_send ossl_send;
+
+static CURLcode ossl_connect_common(struct connectdata *conn,
+                                    int sockindex,
+                                    bool nonblocking,
+                                    bool *done)
+{
+  CURLcode result;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  curl_socket_t sockfd = conn->sock[sockindex];
+  time_t timeout_ms;
+  int what;
+
+  /* check if the connection has already been established */
+  if(ssl_connection_complete == connssl->state) {
+    *done = TRUE;
+    return CURLE_OK;
+  }
+
+  if(ssl_connect_1 == connssl->connecting_state) {
+    /* Find out how much more time we're allowed */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    result = ossl_connect_step1(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  while(ssl_connect_2 == connssl->connecting_state ||
+        ssl_connect_2_reading == connssl->connecting_state ||
+        ssl_connect_2_writing == connssl->connecting_state) {
+
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    /* if ssl is expecting something, check if it's available. */
+    if(connssl->connecting_state == ssl_connect_2_reading ||
+       connssl->connecting_state == ssl_connect_2_writing) {
+
+      curl_socket_t writefd = ssl_connect_2_writing ==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+      curl_socket_t readfd = ssl_connect_2_reading ==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+      what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
+                               nonblocking?0:timeout_ms);
+      if(what < 0) {
+        /* fatal error */
+        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      if(0 == what) {
+        if(nonblocking) {
+          *done = FALSE;
+          return CURLE_OK;
+        }
+        /* timeout */
+        failf(data, "SSL connection timeout");
+        return CURLE_OPERATION_TIMEDOUT;
+      }
+      /* socket is readable or writable */
+    }
+
+    /* Run transaction, and return to the caller if it failed or if this
+     * connection is done nonblocking and this loop would execute again. This
+     * permits the owner of a multi handle to abort a connection attempt
+     * before step2 has completed while ensuring that a client using select()
+     * or epoll() will always have a valid fdset to wait on.
+     */
+    result = ossl_connect_step2(conn, sockindex);
+    if(result || (nonblocking &&
+                  (ssl_connect_2 == connssl->connecting_state ||
+                   ssl_connect_2_reading == connssl->connecting_state ||
+                   ssl_connect_2_writing == connssl->connecting_state)))
+      return result;
+
+  } /* repeat step2 until all transactions are done. */
+
+  if(ssl_connect_3 == connssl->connecting_state) {
+    result = ossl_connect_step3(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  if(ssl_connect_done == connssl->connecting_state) {
+    connssl->state = ssl_connection_complete;
+    conn->recv[sockindex] = ossl_recv;
+    conn->send[sockindex] = ossl_send;
+    *done = TRUE;
+  }
+  else
+    *done = FALSE;
+
+  /* Reset our connect state machine */
+  connssl->connecting_state = ssl_connect_1;
+
+  return CURLE_OK;
+}
+
+static CURLcode Curl_ossl_connect_nonblocking(struct connectdata *conn,
+                                              int sockindex,
+                                              bool *done)
+{
+  return ossl_connect_common(conn, sockindex, TRUE, done);
+}
+
+static CURLcode Curl_ossl_connect(struct connectdata *conn, int sockindex)
+{
+  CURLcode result;
+  bool done = FALSE;
+
+  result = ossl_connect_common(conn, sockindex, FALSE, &done);
+  if(result)
+    return result;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+static bool Curl_ossl_data_pending(const struct connectdata *conn,
+                                   int connindex)
+{
+  const struct ssl_connect_data *connssl = &conn->ssl[connindex];
+  const struct ssl_connect_data *proxyssl = &conn->proxy_ssl[connindex];
+  if(BACKEND->handle)
+    /* SSL is in use */
+    return (0 != SSL_pending(BACKEND->handle) ||
+           (proxyssl->backend->handle &&
+            0 != SSL_pending(proxyssl->backend->handle))) ?
+           TRUE : FALSE;
+  return FALSE;
+}
+
+static size_t Curl_ossl_version(char *buffer, size_t size);
+
+static ssize_t ossl_send(struct connectdata *conn,
+                         int sockindex,
+                         const void *mem,
+                         size_t len,
+                         CURLcode *curlcode)
+{
+  /* SSL_write() is said to return 'int' while write() and send() returns
+     'size_t' */
+  int err;
+  char error_buffer[256];
+  unsigned long sslerror;
+  int memlen;
+  int rc;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  ERR_clear_error();
+
+  memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len;
+  rc = SSL_write(BACKEND->handle, mem, memlen);
+
+  if(rc <= 0) {
+    err = SSL_get_error(BACKEND->handle, rc);
+
+    switch(err) {
+    case SSL_ERROR_WANT_READ:
+    case SSL_ERROR_WANT_WRITE:
+      /* The operation did not complete; the same TLS/SSL I/O function
+         should be called again later. This is basically an EWOULDBLOCK
+         equivalent. */
+      *curlcode = CURLE_AGAIN;
+      return -1;
+    case SSL_ERROR_SYSCALL:
+      failf(conn->data, "SSL_write() returned SYSCALL, errno = %d",
+            SOCKERRNO);
+      *curlcode = CURLE_SEND_ERROR;
+      return -1;
+    case SSL_ERROR_SSL:
+      /*  A failure in the SSL library occurred, usually a protocol error.
+          The OpenSSL error queue contains more information on the error. */
+      sslerror = ERR_get_error();
+      if(ERR_GET_LIB(sslerror) == ERR_LIB_SSL &&
+         ERR_GET_REASON(sslerror) == SSL_R_BIO_NOT_SET &&
+         conn->ssl[sockindex].state == ssl_connection_complete &&
+         conn->proxy_ssl[sockindex].state == ssl_connection_complete) {
+        char ver[120];
+        Curl_ossl_version(ver, 120);
+        failf(conn->data, "Error: %s does not support double SSL tunneling.",
+              ver);
+      }
+      else
+        failf(conn->data, "SSL_write() error: %s",
+              ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)));
+      *curlcode = CURLE_SEND_ERROR;
+      return -1;
+    }
+    /* a true error */
+    failf(conn->data, OSSL_PACKAGE " SSL_write: %s, errno %d",
+          SSL_ERROR_to_str(err), SOCKERRNO);
+    *curlcode = CURLE_SEND_ERROR;
+    return -1;
+  }
+  *curlcode = CURLE_OK;
+  return (ssize_t)rc; /* number of bytes */
+}
+
+static ssize_t ossl_recv(struct connectdata *conn, /* connection data */
+                         int num,                  /* socketindex */
+                         char *buf,                /* store read data here */
+                         size_t buffersize,        /* max amount to read */
+                         CURLcode *curlcode)
+{
+  char error_buffer[256];
+  unsigned long sslerror;
+  ssize_t nread;
+  int buffsize;
+  struct ssl_connect_data *connssl = &conn->ssl[num];
+
+  ERR_clear_error();
+
+  buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize;
+  nread = (ssize_t)SSL_read(BACKEND->handle, buf, buffsize);
+  if(nread <= 0) {
+    /* failed SSL_read */
+    int err = SSL_get_error(BACKEND->handle, (int)nread);
+
+    switch(err) {
+    case SSL_ERROR_NONE: /* this is not an error */
+    case SSL_ERROR_ZERO_RETURN: /* no more data */
+      break;
+    case SSL_ERROR_WANT_READ:
+    case SSL_ERROR_WANT_WRITE:
+      /* there's data pending, re-invoke SSL_read() */
+      *curlcode = CURLE_AGAIN;
+      return -1;
+    default:
+      /* openssl/ssl.h for SSL_ERROR_SYSCALL says "look at error stack/return
+         value/errno" */
+      /* https://www.openssl.org/docs/crypto/ERR_get_error.html */
+      sslerror = ERR_get_error();
+      if((nread < 0) || sslerror) {
+        /* If the return code was negative or there actually is an error in the
+           queue */
+        failf(conn->data, OSSL_PACKAGE " SSL_read: %s, errno %d",
+              (sslerror ?
+               ossl_strerror(sslerror, error_buffer, sizeof(error_buffer)) :
+               SSL_ERROR_to_str(err)),
+              SOCKERRNO);
+        *curlcode = CURLE_RECV_ERROR;
+        return -1;
+      }
+    }
+  }
+  return nread;
+}
+
+static size_t Curl_ossl_version(char *buffer, size_t size)
+{
+#ifdef OPENSSL_IS_BORINGSSL
+  return snprintf(buffer, size, OSSL_PACKAGE);
+#else /* OPENSSL_IS_BORINGSSL */
+  char sub[3];
+  unsigned long ssleay_value;
+  sub[2]='\0';
+  sub[1]='\0';
+  ssleay_value = OpenSSL_version_num();
+  if(ssleay_value < 0x906000) {
+    ssleay_value = SSLEAY_VERSION_NUMBER;
+    sub[0]='\0';
+  }
+  else {
+    if(ssleay_value&0xff0) {
+      int minor_ver = (ssleay_value >> 4) & 0xff;
+      if(minor_ver > 26) {
+        /* handle extended version introduced for 0.9.8za */
+        sub[1] = (char) ((minor_ver - 1) % 26 + 'a' + 1);
+        sub[0] = 'z';
+      }
+      else {
+        sub[0] = (char) (minor_ver + 'a' - 1);
+      }
+    }
+    else
+      sub[0]='\0';
+  }
+
+  return snprintf(buffer, size, "%s/%lx.%lx.%lx%s",
+                  OSSL_PACKAGE,
+                  (ssleay_value>>28)&0xf,
+                  (ssleay_value>>20)&0xff,
+                  (ssleay_value>>12)&0xff,
+                  sub);
+#endif /* OPENSSL_IS_BORINGSSL */
+}
+
+/* can be called with data == NULL */
+static CURLcode Curl_ossl_random(struct Curl_easy *data,
+                                 unsigned char *entropy, size_t length)
+{
+  int rc;
+  if(data) {
+    if(Curl_ossl_seed(data)) /* Initiate the seed if not already done */
+      return CURLE_FAILED_INIT; /* couldn't seed for some reason */
+  }
+  else {
+    if(!rand_enough())
+      return CURLE_FAILED_INIT;
+  }
+  /* RAND_bytes() returns 1 on success, 0 otherwise.  */
+  rc = RAND_bytes(entropy, curlx_uztosi(length));
+  return (rc == 1 ? CURLE_OK : CURLE_FAILED_INIT);
+}
+
+static CURLcode Curl_ossl_md5sum(unsigned char *tmp, /* input */
+                                 size_t tmplen,
+                                 unsigned char *md5sum /* output */,
+                                 size_t unused)
+{
+  MD5_CTX MD5pw;
+  (void)unused;
+  MD5_Init(&MD5pw);
+  MD5_Update(&MD5pw, tmp, tmplen);
+  MD5_Final(md5sum, &MD5pw);
+  return CURLE_OK;
+}
+
+#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256)
+static void Curl_ossl_sha256sum(const unsigned char *tmp, /* input */
+                                size_t tmplen,
+                                unsigned char *sha256sum /* output */,
+                                size_t unused)
+{
+  SHA256_CTX SHA256pw;
+  (void)unused;
+  SHA256_Init(&SHA256pw);
+  SHA256_Update(&SHA256pw, tmp, tmplen);
+  SHA256_Final(sha256sum, &SHA256pw);
+}
+#endif
+
+static bool Curl_ossl_cert_status_request(void)
+{
+#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \
+    !defined(OPENSSL_NO_OCSP)
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}
+
+static void *Curl_ossl_get_internals(struct ssl_connect_data *connssl,
+                                     CURLINFO info)
+{
+  /* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */
+  return info == CURLINFO_TLS_SESSION ?
+         (void *)BACKEND->ctx : (void *)BACKEND->handle;
+}
+
+const struct Curl_ssl Curl_ssl_openssl = {
+  { CURLSSLBACKEND_OPENSSL, "openssl" }, /* info */
+
+  1, /* have_ca_path */
+  1, /* have_certinfo */
+  1, /* have_pinnedpubkey */
+  1, /* have_ssl_ctx */
+  1, /* support_https_proxy */
+
+  sizeof(struct ssl_backend_data),
+
+  Curl_ossl_init,                /* init */
+  Curl_ossl_cleanup,             /* cleanup */
+  Curl_ossl_version,             /* version */
+  Curl_ossl_check_cxn,           /* check_cxn */
+  Curl_ossl_shutdown,            /* shutdown */
+  Curl_ossl_data_pending,        /* data_pending */
+  Curl_ossl_random,              /* random */
+  Curl_ossl_cert_status_request, /* cert_status_request */
+  Curl_ossl_connect,             /* connect */
+  Curl_ossl_connect_nonblocking, /* connect_nonblocking */
+  Curl_ossl_get_internals,       /* get_internals */
+  Curl_ossl_close,               /* close_one */
+  Curl_ossl_close_all,           /* close_all */
+  Curl_ossl_session_free,        /* session_free */
+  Curl_ossl_set_engine,          /* set_engine */
+  Curl_ossl_set_engine_default,  /* set_engine_default */
+  Curl_ossl_engines_list,        /* engines_list */
+  Curl_none_false_start,         /* false_start */
+  Curl_ossl_md5sum,              /* md5sum */
+#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256)
+  Curl_ossl_sha256sum            /* sha256sum */
+#else
+  NULL                           /* sha256sum */
+#endif
+};
+
+#endif /* USE_OPENSSL */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/openssl.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/openssl.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/openssl.h	(revision 331)
@@ -0,0 +1,37 @@
+#ifndef HEADER_CURL_SSLUSE_H
+#define HEADER_CURL_SSLUSE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#ifdef USE_OPENSSL
+/*
+ * This header should only be needed to get included by vtls.c and openssl.c
+ */
+
+#include "urldata.h"
+
+extern const struct Curl_ssl Curl_ssl_openssl;
+
+#endif /* USE_OPENSSL */
+#endif /* HEADER_CURL_SSLUSE_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/polarssl.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/polarssl.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/polarssl.c	(revision 331)
@@ -0,0 +1,937 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010 - 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all PolarSSL-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ *
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_POLARSSL
+#include <polarssl/net.h>
+#include <polarssl/ssl.h>
+#include <polarssl/certs.h>
+#include <polarssl/x509.h>
+#include <polarssl/version.h>
+#include <polarssl/sha256.h>
+
+#if POLARSSL_VERSION_NUMBER < 0x01030000
+#error too old PolarSSL
+#endif
+
+#include <polarssl/error.h>
+#include <polarssl/entropy.h>
+#include <polarssl/ctr_drbg.h>
+
+#include "urldata.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "polarssl.h"
+#include "vtls.h"
+#include "parsedate.h"
+#include "connect.h" /* for the connect timeout */
+#include "select.h"
+#include "strcase.h"
+#include "polarssl_threadlock.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* See https://tls.mbed.org/discussions/generic/
+   howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der
+*/
+#define RSA_PUB_DER_MAX_BYTES   (38 + 2 * POLARSSL_MPI_MAX_SIZE)
+#define ECP_PUB_DER_MAX_BYTES   (30 + 2 * POLARSSL_ECP_MAX_BYTES)
+
+#define PUB_DER_MAX_BYTES   (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
+                             RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES)
+
+struct ssl_backend_data {
+  ctr_drbg_context ctr_drbg;
+  entropy_context entropy;
+  ssl_context ssl;
+  int server_fd;
+  x509_crt cacert;
+  x509_crt clicert;
+  x509_crl crl;
+  rsa_context rsa;
+};
+
+#define BACKEND connssl->backend
+
+/* apply threading? */
+#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
+#define THREADING_SUPPORT
+#endif
+
+#ifndef POLARSSL_ERROR_C
+#define error_strerror(x,y,z)
+#endif /* POLARSSL_ERROR_C */
+
+
+#if defined(THREADING_SUPPORT)
+static entropy_context entropy;
+
+static int  entropy_init_initialized  = 0;
+
+/* start of entropy_init_mutex() */
+static void entropy_init_mutex(entropy_context *ctx)
+{
+  /* lock 0 = entropy_init_mutex() */
+  Curl_polarsslthreadlock_lock_function(0);
+  if(entropy_init_initialized == 0) {
+    entropy_init(ctx);
+    entropy_init_initialized = 1;
+  }
+  Curl_polarsslthreadlock_unlock_function(0);
+}
+/* end of entropy_init_mutex() */
+
+/* start of entropy_func_mutex() */
+static int entropy_func_mutex(void *data, unsigned char *output, size_t len)
+{
+  int ret;
+  /* lock 1 = entropy_func_mutex() */
+  Curl_polarsslthreadlock_lock_function(1);
+  ret = entropy_func(data, output, len);
+  Curl_polarsslthreadlock_unlock_function(1);
+
+  return ret;
+}
+/* end of entropy_func_mutex() */
+
+#endif /* THREADING_SUPPORT */
+
+/* Define this to enable lots of debugging for PolarSSL */
+#undef POLARSSL_DEBUG
+
+#ifdef POLARSSL_DEBUG
+static void polarssl_debug(void *context, int level, const char *line)
+{
+  struct Curl_easy *data = NULL;
+
+  if(!context)
+    return;
+
+  data = (struct Curl_easy *)context;
+
+  infof(data, "%s", line);
+  (void) level;
+}
+#else
+#endif
+
+/* ALPN for http2? */
+#ifdef POLARSSL_SSL_ALPN
+#  define HAS_ALPN
+#endif
+
+static Curl_recv polarssl_recv;
+static Curl_send polarssl_send;
+
+static CURLcode polarssl_version_from_curl(int *polarver, long ssl_version)
+{
+  switch(ssl_version) {
+    case CURL_SSLVERSION_TLSv1_0:
+      *polarver = SSL_MINOR_VERSION_1;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_1:
+      *polarver = SSL_MINOR_VERSION_2;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_2:
+      *polarver = SSL_MINOR_VERSION_3;
+      return CURLE_OK;
+    case CURL_SSLVERSION_TLSv1_3:
+      break;
+  }
+  return CURLE_SSL_CONNECT_ERROR;
+}
+
+static CURLcode
+set_ssl_version_min_max(struct connectdata *conn, int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+  long ssl_version = SSL_CONN_CONFIG(version);
+  long ssl_version_max = SSL_CONN_CONFIG(version_max);
+  int ssl_min_ver = SSL_MINOR_VERSION_1;
+  int ssl_max_ver = SSL_MINOR_VERSION_1;
+  CURLcode result = CURLE_OK;
+
+  switch(ssl_version) {
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1:
+      ssl_version = CURL_SSLVERSION_TLSv1_0;
+      ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+      break;
+  }
+
+  switch(ssl_version_max) {
+    case CURL_SSLVERSION_MAX_NONE:
+      ssl_version_max = ssl_version << 16;
+      break;
+    case CURL_SSLVERSION_MAX_DEFAULT:
+      ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+      break;
+  }
+
+  result = polarssl_version_from_curl(&ssl_min_ver, ssl_version);
+  if(result) {
+    failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
+    return result;
+  }
+  result = polarssl_version_from_curl(&ssl_max_ver, ssl_version_max >> 16);
+  if(result) {
+    failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
+    return result;
+  }
+
+  ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, ssl_min_ver);
+  ssl_set_max_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3, ssl_max_ver);
+
+  return result;
+}
+
+static CURLcode
+polarssl_connect_step1(struct connectdata *conn,
+                       int sockindex)
+{
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+  const char *capath = SSL_CONN_CONFIG(CApath);
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+  const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
+  int ret = -1;
+  char errorbuf[128];
+  errorbuf[0] = 0;
+
+  /* PolarSSL only supports SSLv3 and TLSv1 */
+  if(SSL_CONN_CONFIG(version) == CURL_SSLVERSION_SSLv2) {
+    failf(data, "PolarSSL does not support SSLv2");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+#ifdef THREADING_SUPPORT
+  entropy_init_mutex(&entropy);
+
+  if((ret = ctr_drbg_init(&BACKEND->ctr_drbg, entropy_func_mutex, &entropy,
+                          NULL, 0)) != 0) {
+    error_strerror(ret, errorbuf, sizeof(errorbuf));
+    failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
+          -ret, errorbuf);
+  }
+#else
+  entropy_init(&BACKEND->entropy);
+
+  if((ret = ctr_drbg_init(&BACKEND->ctr_drbg, entropy_func, &BACKEND->entropy,
+                          NULL, 0)) != 0) {
+    error_strerror(ret, errorbuf, sizeof(errorbuf));
+    failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n",
+          -ret, errorbuf);
+  }
+#endif /* THREADING_SUPPORT */
+
+  /* Load the trusted CA */
+  memset(&BACKEND->cacert, 0, sizeof(x509_crt));
+
+  if(SSL_CONN_CONFIG(CAfile)) {
+    ret = x509_crt_parse_file(&BACKEND->cacert,
+                              SSL_CONN_CONFIG(CAfile));
+
+    if(ret<0) {
+      error_strerror(ret, errorbuf, sizeof(errorbuf));
+      failf(data, "Error reading ca cert file %s - PolarSSL: (-0x%04X) %s",
+            SSL_CONN_CONFIG(CAfile), -ret, errorbuf);
+
+      if(SSL_CONN_CONFIG(verifypeer))
+        return CURLE_SSL_CACERT_BADFILE;
+    }
+  }
+
+  if(capath) {
+    ret = x509_crt_parse_path(&BACKEND->cacert, capath);
+
+    if(ret<0) {
+      error_strerror(ret, errorbuf, sizeof(errorbuf));
+      failf(data, "Error reading ca cert path %s - PolarSSL: (-0x%04X) %s",
+            capath, -ret, errorbuf);
+
+      if(SSL_CONN_CONFIG(verifypeer))
+        return CURLE_SSL_CACERT_BADFILE;
+    }
+  }
+
+  /* Load the client certificate */
+  memset(&BACKEND->clicert, 0, sizeof(x509_crt));
+
+  if(SSL_SET_OPTION(cert)) {
+    ret = x509_crt_parse_file(&BACKEND->clicert,
+                              SSL_SET_OPTION(cert));
+
+    if(ret) {
+      error_strerror(ret, errorbuf, sizeof(errorbuf));
+      failf(data, "Error reading client cert file %s - PolarSSL: (-0x%04X) %s",
+            SSL_SET_OPTION(cert), -ret, errorbuf);
+
+      return CURLE_SSL_CERTPROBLEM;
+    }
+  }
+
+  /* Load the client private key */
+  if(SSL_SET_OPTION(key)) {
+    pk_context pk;
+    pk_init(&pk);
+    ret = pk_parse_keyfile(&pk, SSL_SET_OPTION(key),
+                           SSL_SET_OPTION(key_passwd));
+    if(ret == 0 && !pk_can_do(&pk, POLARSSL_PK_RSA))
+      ret = POLARSSL_ERR_PK_TYPE_MISMATCH;
+    if(ret == 0)
+      rsa_copy(&BACKEND->rsa, pk_rsa(pk));
+    else
+      rsa_free(&BACKEND->rsa);
+    pk_free(&pk);
+
+    if(ret) {
+      error_strerror(ret, errorbuf, sizeof(errorbuf));
+      failf(data, "Error reading private key %s - PolarSSL: (-0x%04X) %s",
+            SSL_SET_OPTION(key), -ret, errorbuf);
+
+      return CURLE_SSL_CERTPROBLEM;
+    }
+  }
+
+  /* Load the CRL */
+  memset(&BACKEND->crl, 0, sizeof(x509_crl));
+
+  if(SSL_SET_OPTION(CRLfile)) {
+    ret = x509_crl_parse_file(&BACKEND->crl,
+                              SSL_SET_OPTION(CRLfile));
+
+    if(ret) {
+      error_strerror(ret, errorbuf, sizeof(errorbuf));
+      failf(data, "Error reading CRL file %s - PolarSSL: (-0x%04X) %s",
+            SSL_SET_OPTION(CRLfile), -ret, errorbuf);
+
+      return CURLE_SSL_CRL_BADFILE;
+    }
+  }
+
+  infof(data, "PolarSSL: Connecting to %s:%d\n", hostname, port);
+
+  if(ssl_init(&BACKEND->ssl)) {
+    failf(data, "PolarSSL: ssl_init failed");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  switch(SSL_CONN_CONFIG(version)) {
+  case CURL_SSLVERSION_DEFAULT:
+  case CURL_SSLVERSION_TLSv1:
+    ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
+                        SSL_MINOR_VERSION_1);
+    break;
+  case CURL_SSLVERSION_SSLv3:
+    ssl_set_min_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
+                        SSL_MINOR_VERSION_0);
+    ssl_set_max_version(&BACKEND->ssl, SSL_MAJOR_VERSION_3,
+                        SSL_MINOR_VERSION_0);
+    infof(data, "PolarSSL: Forced min. SSL Version to be SSLv3\n");
+    break;
+  case CURL_SSLVERSION_TLSv1_0:
+  case CURL_SSLVERSION_TLSv1_1:
+  case CURL_SSLVERSION_TLSv1_2:
+  case CURL_SSLVERSION_TLSv1_3:
+    {
+      CURLcode result = set_ssl_version_min_max(conn, sockindex);
+      if(result != CURLE_OK)
+        return result;
+      break;
+    }
+  default:
+    failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  ssl_set_endpoint(&BACKEND->ssl, SSL_IS_CLIENT);
+  ssl_set_authmode(&BACKEND->ssl, SSL_VERIFY_OPTIONAL);
+
+  ssl_set_rng(&BACKEND->ssl, ctr_drbg_random,
+              &BACKEND->ctr_drbg);
+  ssl_set_bio(&BACKEND->ssl,
+              net_recv, &conn->sock[sockindex],
+              net_send, &conn->sock[sockindex]);
+
+  ssl_set_ciphersuites(&BACKEND->ssl, ssl_list_ciphersuites());
+
+  /* Check if there's a cached ID we can/should use here! */
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    void *old_session = NULL;
+
+    Curl_ssl_sessionid_lock(conn);
+    if(!Curl_ssl_getsessionid(conn, &old_session, NULL, sockindex)) {
+      ret = ssl_set_session(&BACKEND->ssl, old_session);
+      if(ret) {
+        Curl_ssl_sessionid_unlock(conn);
+        failf(data, "ssl_set_session returned -0x%x", -ret);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      infof(data, "PolarSSL re-using session\n");
+    }
+    Curl_ssl_sessionid_unlock(conn);
+  }
+
+  ssl_set_ca_chain(&BACKEND->ssl,
+                   &BACKEND->cacert,
+                   &BACKEND->crl,
+                   hostname);
+
+  ssl_set_own_cert_rsa(&BACKEND->ssl,
+                       &BACKEND->clicert, &BACKEND->rsa);
+
+  if(ssl_set_hostname(&BACKEND->ssl, hostname)) {
+    /* ssl_set_hostname() sets the name to use in CN/SAN checks *and* the name
+       to set in the SNI extension. So even if curl connects to a host
+       specified as an IP address, this function must be used. */
+    failf(data, "couldn't set hostname in PolarSSL");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+#ifdef HAS_ALPN
+  if(conn->bits.tls_enable_alpn) {
+    static const char *protocols[3];
+    int cur = 0;
+
+#ifdef USE_NGHTTP2
+    if(data->set.httpversion >= CURL_HTTP_VERSION_2) {
+      protocols[cur++] = NGHTTP2_PROTO_VERSION_ID;
+      infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+    }
+#endif
+
+    protocols[cur++] = ALPN_HTTP_1_1;
+    infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1);
+
+    protocols[cur] = NULL;
+
+    ssl_set_alpn_protocols(&BACKEND->ssl, protocols);
+  }
+#endif
+
+#ifdef POLARSSL_DEBUG
+  ssl_set_dbg(&BACKEND->ssl, polarssl_debug, data);
+#endif
+
+  connssl->connecting_state = ssl_connect_2;
+
+  return CURLE_OK;
+}
+
+static CURLcode
+polarssl_connect_step2(struct connectdata *conn,
+                       int sockindex)
+{
+  int ret;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data* connssl = &conn->ssl[sockindex];
+  char buffer[1024];
+  const char * const pinnedpubkey = SSL_IS_PROXY() ?
+            data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY] :
+            data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG];
+
+
+  char errorbuf[128];
+  errorbuf[0] = 0;
+
+  conn->recv[sockindex] = polarssl_recv;
+  conn->send[sockindex] = polarssl_send;
+
+  ret = ssl_handshake(&BACKEND->ssl);
+
+  switch(ret) {
+  case 0:
+    break;
+
+  case POLARSSL_ERR_NET_WANT_READ:
+    connssl->connecting_state = ssl_connect_2_reading;
+    return CURLE_OK;
+
+  case POLARSSL_ERR_NET_WANT_WRITE:
+    connssl->connecting_state = ssl_connect_2_writing;
+    return CURLE_OK;
+
+  default:
+    error_strerror(ret, errorbuf, sizeof(errorbuf));
+    failf(data, "ssl_handshake returned - PolarSSL: (-0x%04X) %s",
+          -ret, errorbuf);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  infof(data, "PolarSSL: Handshake complete, cipher is %s\n",
+        ssl_get_ciphersuite(&BACKEND->ssl) );
+
+  ret = ssl_get_verify_result(&BACKEND->ssl);
+
+  if(ret && SSL_CONN_CONFIG(verifypeer)) {
+    if(ret & BADCERT_EXPIRED)
+      failf(data, "Cert verify failed: BADCERT_EXPIRED");
+
+    if(ret & BADCERT_REVOKED) {
+      failf(data, "Cert verify failed: BADCERT_REVOKED");
+      return CURLE_SSL_CACERT;
+    }
+
+    if(ret & BADCERT_CN_MISMATCH)
+      failf(data, "Cert verify failed: BADCERT_CN_MISMATCH");
+
+    if(ret & BADCERT_NOT_TRUSTED)
+      failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED");
+
+    return CURLE_PEER_FAILED_VERIFICATION;
+  }
+
+  if(ssl_get_peer_cert(&(BACKEND->ssl))) {
+    /* If the session was resumed, there will be no peer certs */
+    memset(buffer, 0, sizeof(buffer));
+
+    if(x509_crt_info(buffer, sizeof(buffer), (char *)"* ",
+                     ssl_get_peer_cert(&(BACKEND->ssl))) != -1)
+      infof(data, "Dumping cert info:\n%s\n", buffer);
+  }
+
+  /* adapted from mbedtls.c */
+  if(pinnedpubkey) {
+    int size;
+    CURLcode result;
+    x509_crt *p;
+    unsigned char pubkey[PUB_DER_MAX_BYTES];
+    const x509_crt *peercert;
+
+    peercert = ssl_get_peer_cert(&BACKEND->ssl);
+
+    if(!peercert || !peercert->raw.p || !peercert->raw.len) {
+      failf(data, "Failed due to missing peer certificate");
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    p = calloc(1, sizeof(*p));
+
+    if(!p)
+      return CURLE_OUT_OF_MEMORY;
+
+    x509_crt_init(p);
+
+    /* Make a copy of our const peercert because pk_write_pubkey_der
+       needs a non-const key, for now.
+       https://github.com/ARMmbed/mbedtls/issues/396 */
+    if(x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) {
+      failf(data, "Failed copying peer certificate");
+      x509_crt_free(p);
+      free(p);
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    size = pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES);
+
+    if(size <= 0) {
+      failf(data, "Failed copying public key from peer certificate");
+      x509_crt_free(p);
+      free(p);
+      return CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+    }
+
+    /* pk_write_pubkey_der writes data at the end of the buffer. */
+    result = Curl_pin_peer_pubkey(data,
+                                  pinnedpubkey,
+                                  &pubkey[PUB_DER_MAX_BYTES - size], size);
+    if(result) {
+      x509_crt_free(p);
+      free(p);
+      return result;
+    }
+
+    x509_crt_free(p);
+    free(p);
+  }
+
+#ifdef HAS_ALPN
+  if(conn->bits.tls_enable_alpn) {
+    const char *next_protocol = ssl_get_alpn_protocol(&BACKEND->ssl);
+
+    if(next_protocol != NULL) {
+      infof(data, "ALPN, server accepted to use %s\n", next_protocol);
+
+#ifdef USE_NGHTTP2
+      if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID,
+                  NGHTTP2_PROTO_VERSION_ID_LEN)) {
+        conn->negnpn = CURL_HTTP_VERSION_2;
+      }
+      else
+#endif
+        if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) {
+          conn->negnpn = CURL_HTTP_VERSION_1_1;
+        }
+    }
+    else
+      infof(data, "ALPN, server did not agree to a protocol\n");
+  }
+#endif
+
+  connssl->connecting_state = ssl_connect_3;
+  infof(data, "SSL connected\n");
+
+  return CURLE_OK;
+}
+
+static CURLcode
+polarssl_connect_step3(struct connectdata *conn,
+                       int sockindex)
+{
+  CURLcode retcode = CURLE_OK;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  struct Curl_easy *data = conn->data;
+
+  DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    int ret;
+    ssl_session *our_ssl_sessionid;
+    void *old_ssl_sessionid = NULL;
+
+    our_ssl_sessionid = malloc(sizeof(ssl_session));
+    if(!our_ssl_sessionid)
+      return CURLE_OUT_OF_MEMORY;
+
+    memset(our_ssl_sessionid, 0, sizeof(ssl_session));
+
+    ret = ssl_get_session(&BACKEND->ssl, our_ssl_sessionid);
+    if(ret) {
+      failf(data, "ssl_get_session returned -0x%x", -ret);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+
+    /* If there's already a matching session in the cache, delete it */
+    Curl_ssl_sessionid_lock(conn);
+    if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL, sockindex))
+      Curl_ssl_delsessionid(conn, old_ssl_sessionid);
+
+    retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0, sockindex);
+    Curl_ssl_sessionid_unlock(conn);
+    if(retcode) {
+      free(our_ssl_sessionid);
+      failf(data, "failed to store ssl session");
+      return retcode;
+    }
+  }
+
+  connssl->connecting_state = ssl_connect_done;
+
+  return CURLE_OK;
+}
+
+static ssize_t polarssl_send(struct connectdata *conn,
+                             int sockindex,
+                             const void *mem,
+                             size_t len,
+                             CURLcode *curlcode)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  int ret = -1;
+
+  ret = ssl_write(&BACKEND->ssl,
+                  (unsigned char *)mem, len);
+
+  if(ret < 0) {
+    *curlcode = (ret == POLARSSL_ERR_NET_WANT_WRITE) ?
+      CURLE_AGAIN : CURLE_SEND_ERROR;
+    ret = -1;
+  }
+
+  return ret;
+}
+
+static void Curl_polarssl_close(struct connectdata *conn, int sockindex)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  rsa_free(&BACKEND->rsa);
+  x509_crt_free(&BACKEND->clicert);
+  x509_crt_free(&BACKEND->cacert);
+  x509_crl_free(&BACKEND->crl);
+  ssl_free(&BACKEND->ssl);
+}
+
+static ssize_t polarssl_recv(struct connectdata *conn,
+                             int num,
+                             char *buf,
+                             size_t buffersize,
+                             CURLcode *curlcode)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[num];
+  int ret = -1;
+  ssize_t len = -1;
+
+  memset(buf, 0, buffersize);
+  ret = ssl_read(&BACKEND->ssl, (unsigned char *)buf, buffersize);
+
+  if(ret <= 0) {
+    if(ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY)
+      return 0;
+
+    *curlcode = (ret == POLARSSL_ERR_NET_WANT_READ) ?
+      CURLE_AGAIN : CURLE_RECV_ERROR;
+    return -1;
+  }
+
+  len = ret;
+
+  return len;
+}
+
+static void Curl_polarssl_session_free(void *ptr)
+{
+  ssl_session_free(ptr);
+  free(ptr);
+}
+
+/* 1.3.10 was the first rebranded version. All new releases (in 1.3 branch and
+   higher) will be mbed TLS branded.. */
+
+static size_t Curl_polarssl_version(char *buffer, size_t size)
+{
+  unsigned int version = version_get_number();
+  return snprintf(buffer, size, "%s/%d.%d.%d",
+                  version >= 0x01030A00?"mbedTLS":"PolarSSL",
+                  version>>24, (version>>16)&0xff, (version>>8)&0xff);
+}
+
+static CURLcode
+polarssl_connect_common(struct connectdata *conn,
+                        int sockindex,
+                        bool nonblocking,
+                        bool *done)
+{
+  CURLcode result;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  curl_socket_t sockfd = conn->sock[sockindex];
+  long timeout_ms;
+  int what;
+
+  /* check if the connection has already been established */
+  if(ssl_connection_complete == connssl->state) {
+    *done = TRUE;
+    return CURLE_OK;
+  }
+
+  if(ssl_connect_1 == connssl->connecting_state) {
+    /* Find out how much more time we're allowed */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    result = polarssl_connect_step1(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  while(ssl_connect_2 == connssl->connecting_state ||
+        ssl_connect_2_reading == connssl->connecting_state ||
+        ssl_connect_2_writing == connssl->connecting_state) {
+
+    /* check allowed time left */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    /* if ssl is expecting something, check if it's available. */
+    if(connssl->connecting_state == ssl_connect_2_reading ||
+       connssl->connecting_state == ssl_connect_2_writing) {
+
+      curl_socket_t writefd = ssl_connect_2_writing ==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+      curl_socket_t readfd = ssl_connect_2_reading ==
+        connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
+
+      what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
+                               nonblocking?0:timeout_ms);
+      if(what < 0) {
+        /* fatal error */
+        failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      else if(0 == what) {
+        if(nonblocking) {
+          *done = FALSE;
+          return CURLE_OK;
+        }
+        else {
+          /* timeout */
+          failf(data, "SSL connection timeout");
+          return CURLE_OPERATION_TIMEDOUT;
+        }
+      }
+      /* socket is readable or writable */
+    }
+
+    /* Run transaction, and return to the caller if it failed or if
+     * this connection is part of a multi handle and this loop would
+     * execute again. This permits the owner of a multi handle to
+     * abort a connection attempt before step2 has completed while
+     * ensuring that a client using select() or epoll() will always
+     * have a valid fdset to wait on.
+     */
+    result = polarssl_connect_step2(conn, sockindex);
+    if(result || (nonblocking &&
+                  (ssl_connect_2 == connssl->connecting_state ||
+                   ssl_connect_2_reading == connssl->connecting_state ||
+                   ssl_connect_2_writing == connssl->connecting_state)))
+      return result;
+
+  } /* repeat step2 until all transactions are done. */
+
+  if(ssl_connect_3 == connssl->connecting_state) {
+    result = polarssl_connect_step3(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  if(ssl_connect_done == connssl->connecting_state) {
+    connssl->state = ssl_connection_complete;
+    conn->recv[sockindex] = polarssl_recv;
+    conn->send[sockindex] = polarssl_send;
+    *done = TRUE;
+  }
+  else
+    *done = FALSE;
+
+  /* Reset our connect state machine */
+  connssl->connecting_state = ssl_connect_1;
+
+  return CURLE_OK;
+}
+
+static CURLcode Curl_polarssl_connect_nonblocking(struct connectdata *conn,
+                                                  int sockindex, bool *done)
+{
+  return polarssl_connect_common(conn, sockindex, TRUE, done);
+}
+
+
+static CURLcode Curl_polarssl_connect(struct connectdata *conn, int sockindex)
+{
+  CURLcode result;
+  bool done = FALSE;
+
+  result = polarssl_connect_common(conn, sockindex, FALSE, &done);
+  if(result)
+    return result;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+/*
+ * return 0 error initializing SSL
+ * return 1 SSL initialized successfully
+ */
+static int Curl_polarssl_init(void)
+{
+  return Curl_polarsslthreadlock_thread_setup();
+}
+
+static void Curl_polarssl_cleanup(void)
+{
+  (void)Curl_polarsslthreadlock_thread_cleanup();
+}
+
+static bool Curl_polarssl_data_pending(const struct connectdata *conn,
+                                       int sockindex)
+{
+  const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  return ssl_get_bytes_avail(&BACKEND->ssl) != 0;
+}
+
+static void Curl_polarssl_sha256sum(const unsigned char *input,
+                                    size_t inputlen,
+                                    unsigned char *sha256sum,
+                                    size_t sha256len UNUSED_PARAM)
+{
+  (void)sha256len;
+  sha256(input, inputlen, sha256sum, 0);
+}
+
+static void *Curl_polarssl_get_internals(struct ssl_connect_data *connssl,
+                                         CURLINFO info UNUSED_PARAM)
+{
+  (void)info;
+  return &BACKEND->ssl;
+}
+
+const struct Curl_ssl Curl_ssl_polarssl = {
+  { CURLSSLBACKEND_POLARSSL, "polarssl" }, /* info */
+
+  1, /* have_ca_path */
+  0, /* have_certinfo */
+  1, /* have_pinnedpubkey */
+  0, /* have_ssl_ctx */
+  0, /* support_https_proxy */
+
+  sizeof(struct ssl_backend_data),
+
+  Curl_polarssl_init,                /* init */
+  Curl_polarssl_cleanup,             /* cleanup */
+  Curl_polarssl_version,             /* version */
+  Curl_none_check_cxn,               /* check_cxn */
+  Curl_none_shutdown,                /* shutdown */
+  Curl_polarssl_data_pending,        /* data_pending */
+  /* This might cause libcurl to use a weeker random!
+   * TODO: use Polarssl's CTR-DRBG or HMAC-DRBG
+  */
+  Curl_none_random,                  /* random */
+  Curl_none_cert_status_request,     /* cert_status_request */
+  Curl_polarssl_connect,             /* connect */
+  Curl_polarssl_connect_nonblocking, /* connect_nonblocking */
+  Curl_polarssl_get_internals,       /* get_internals */
+  Curl_polarssl_close,               /* close_one */
+  Curl_none_close_all,               /* close_all */
+  Curl_polarssl_session_free,        /* session_free */
+  Curl_none_set_engine,              /* set_engine */
+  Curl_none_set_engine_default,      /* set_engine_default */
+  Curl_none_engines_list,            /* engines_list */
+  Curl_none_false_start,             /* false_start */
+  Curl_none_md5sum,                  /* md5sum */
+  Curl_polarssl_sha256sum            /* sha256sum */
+};
+
+#endif /* USE_POLARSSL */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/polarssl.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/polarssl.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/polarssl.h	(revision 331)
@@ -0,0 +1,32 @@
+#ifndef HEADER_CURL_POLARSSL_H
+#define HEADER_CURL_POLARSSL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_POLARSSL
+
+extern const struct Curl_ssl Curl_ssl_polarssl;
+
+#endif /* USE_POLARSSL */
+#endif /* HEADER_CURL_POLARSSL_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/polarssl_threadlock.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/polarssl_threadlock.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/polarssl_threadlock.c	(revision 331)
@@ -0,0 +1,153 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2013-2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if (defined(USE_POLARSSL) || defined(USE_MBEDTLS)) && \
+    (defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32))
+
+#if defined(USE_THREADS_POSIX)
+#  ifdef HAVE_PTHREAD_H
+#    include <pthread.h>
+#  endif
+#elif defined(USE_THREADS_WIN32)
+#  ifdef HAVE_PROCESS_H
+#    include <process.h>
+#  endif
+#endif
+
+#include "polarssl_threadlock.h"
+#include "curl_printf.h"
+#include "curl_memory.h"
+/* The last #include file should be: */
+#include "memdebug.h"
+
+/* number of thread locks */
+#define NUMT                    2
+
+/* This array will store all of the mutexes available to PolarSSL. */
+static POLARSSL_MUTEX_T *mutex_buf = NULL;
+
+int Curl_polarsslthreadlock_thread_setup(void)
+{
+  int i;
+  int ret;
+
+  mutex_buf = calloc(NUMT * sizeof(POLARSSL_MUTEX_T), 1);
+  if(!mutex_buf)
+    return 0;     /* error, no number of threads defined */
+
+#ifdef HAVE_PTHREAD_H
+  for(i = 0;  i < NUMT;  i++) {
+    ret = pthread_mutex_init(&mutex_buf[i], NULL);
+    if(ret)
+      return 0; /* pthread_mutex_init failed */
+  }
+#elif defined(HAVE_PROCESS_H)
+  for(i = 0;  i < NUMT;  i++) {
+    mutex_buf[i] = CreateMutex(0, FALSE, 0);
+    if(mutex_buf[i] == 0)
+      return 0;  /* CreateMutex failed */
+  }
+#endif /* HAVE_PTHREAD_H */
+
+  return 1; /* OK */
+}
+
+int Curl_polarsslthreadlock_thread_cleanup(void)
+{
+  int i;
+  int ret;
+
+  if(!mutex_buf)
+    return 0; /* error, no threads locks defined */
+
+#ifdef HAVE_PTHREAD_H
+  for(i = 0; i < NUMT; i++) {
+    ret = pthread_mutex_destroy(&mutex_buf[i]);
+    if(ret)
+      return 0; /* pthread_mutex_destroy failed */
+  }
+#elif defined(HAVE_PROCESS_H)
+  for(i = 0; i < NUMT; i++) {
+    ret = CloseHandle(mutex_buf[i]);
+    if(!ret)
+      return 0; /* CloseHandle failed */
+  }
+#endif /* HAVE_PTHREAD_H */
+  free(mutex_buf);
+  mutex_buf = NULL;
+
+  return 1; /* OK */
+}
+
+int Curl_polarsslthreadlock_lock_function(int n)
+{
+  int ret;
+#ifdef HAVE_PTHREAD_H
+  if(n < NUMT) {
+    ret = pthread_mutex_lock(&mutex_buf[n]);
+    if(ret) {
+      DEBUGF(fprintf(stderr,
+                     "Error: polarsslthreadlock_lock_function failed\n"));
+      return 0; /* pthread_mutex_lock failed */
+    }
+  }
+#elif defined(HAVE_PROCESS_H)
+  if(n < NUMT) {
+    ret = (WaitForSingleObject(mutex_buf[n], INFINITE) == WAIT_FAILED?1:0);
+    if(ret) {
+      DEBUGF(fprintf(stderr,
+                     "Error: polarsslthreadlock_lock_function failed\n"));
+      return 0; /* pthread_mutex_lock failed */
+    }
+  }
+#endif /* HAVE_PTHREAD_H */
+  return 1; /* OK */
+}
+
+int Curl_polarsslthreadlock_unlock_function(int n)
+{
+  int ret;
+#ifdef HAVE_PTHREAD_H
+  if(n < NUMT) {
+    ret = pthread_mutex_unlock(&mutex_buf[n]);
+    if(ret) {
+      DEBUGF(fprintf(stderr,
+                     "Error: polarsslthreadlock_unlock_function failed\n"));
+      return 0; /* pthread_mutex_unlock failed */
+    }
+  }
+#elif defined(HAVE_PROCESS_H)
+  if(n < NUMT) {
+    ret = ReleaseMutex(mutex_buf[n]);
+    if(!ret) {
+      DEBUGF(fprintf(stderr,
+                     "Error: polarsslthreadlock_unlock_function failed\n"));
+      return 0; /* pthread_mutex_lock failed */
+    }
+  }
+#endif /* HAVE_PTHREAD_H */
+  return 1; /* OK */
+}
+
+#endif /* USE_POLARSSL || USE_MBEDTLS */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/polarssl_threadlock.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/polarssl_threadlock.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/polarssl_threadlock.h	(revision 331)
@@ -0,0 +1,53 @@
+#ifndef HEADER_CURL_POLARSSL_THREADLOCK_H
+#define HEADER_CURL_POLARSSL_THREADLOCK_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2013-2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2010, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#if (defined USE_POLARSSL) || (defined USE_MBEDTLS)
+
+#if defined(USE_THREADS_POSIX)
+#  define POLARSSL_MUTEX_T       pthread_mutex_t
+#elif defined(USE_THREADS_WIN32)
+#  define POLARSSL_MUTEX_T       HANDLE
+#endif
+
+#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
+
+int Curl_polarsslthreadlock_thread_setup(void);
+int Curl_polarsslthreadlock_thread_cleanup(void);
+int Curl_polarsslthreadlock_lock_function(int n);
+int Curl_polarsslthreadlock_unlock_function(int n);
+
+#else
+
+#define Curl_polarsslthreadlock_thread_setup() 1
+#define Curl_polarsslthreadlock_thread_cleanup() 1
+#define Curl_polarsslthreadlock_lock_function(x) 1
+#define Curl_polarsslthreadlock_unlock_function(x) 1
+
+#endif /* USE_THREADS_POSIX || USE_THREADS_WIN32 */
+
+#endif /* USE_POLARSSL */
+
+#endif /* HEADER_CURL_POLARSSL_THREADLOCK_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/schannel.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/schannel.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/schannel.c	(revision 331)
@@ -0,0 +1,1852 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012 - 2016, Marc Hoersken, <info@marc-hoersken.de>
+ * Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com>
+ * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/*
+ * Source file for all SChannel-specific code for the TLS/SSL layer. No code
+ * but vtls.c should ever call or use these functions.
+ *
+ */
+
+/*
+ * Based upon the PolarSSL implementation in polarssl.c and polarssl.h:
+ *   Copyright (C) 2010, 2011, Hoi-Ho Chan, <hoiho.chan@gmail.com>
+ *
+ * Based upon the CyaSSL implementation in cyassl.c and cyassl.h:
+ *   Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * Thanks for code and inspiration!
+ */
+
+#include "curl_setup.h"
+
+#ifdef USE_SCHANNEL
+
+#ifndef USE_WINDOWS_SSPI
+#  error "Can't compile SCHANNEL support without SSPI."
+#endif
+
+#include <schnlsp.h>
+#include <schannel.h>
+#include "curl_sspi.h"
+#include "schannel.h"
+#include "vtls.h"
+#include "sendf.h"
+#include "connect.h" /* for the connect timeout */
+#include "strerror.h"
+#include "select.h" /* for the socket readyness */
+#include "inet_pton.h" /* for IP addr SNI check */
+#include "curl_multibyte.h"
+#include "warnless.h"
+#include "x509asn1.h"
+#include "curl_printf.h"
+#include "system_win32.h"
+#include "hostcheck.h"
+
+ /* The last #include file should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* ALPN requires version 8.1 of the Windows SDK, which was
+   shipped with Visual Studio 2013, aka _MSC_VER 1800:
+
+   https://technet.microsoft.com/en-us/library/hh831771%28v=ws.11%29.aspx
+*/
+#if defined(_MSC_VER) && (_MSC_VER >= 1800) && !defined(_USING_V110_SDK71_)
+#  define HAS_ALPN 1
+#endif
+
+#ifndef UNISP_NAME_A
+#define UNISP_NAME_A "Microsoft Unified Security Protocol Provider"
+#endif
+
+#ifndef UNISP_NAME_W
+#define UNISP_NAME_W L"Microsoft Unified Security Protocol Provider"
+#endif
+
+#ifndef UNISP_NAME
+#ifdef UNICODE
+#define UNISP_NAME  UNISP_NAME_W
+#else
+#define UNISP_NAME  UNISP_NAME_A
+#endif
+#endif
+
+#ifndef SP_PROT_SSL2_CLIENT
+#define SP_PROT_SSL2_CLIENT             0x00000008
+#endif
+
+#ifndef SP_PROT_SSL3_CLIENT
+#define SP_PROT_SSL3_CLIENT             0x00000008
+#endif
+
+#ifndef SP_PROT_TLS1_CLIENT
+#define SP_PROT_TLS1_CLIENT             0x00000080
+#endif
+
+#ifndef SP_PROT_TLS1_0_CLIENT
+#define SP_PROT_TLS1_0_CLIENT           SP_PROT_TLS1_CLIENT
+#endif
+
+#ifndef SP_PROT_TLS1_1_CLIENT
+#define SP_PROT_TLS1_1_CLIENT           0x00000200
+#endif
+
+#ifndef SP_PROT_TLS1_2_CLIENT
+#define SP_PROT_TLS1_2_CLIENT           0x00000800
+#endif
+
+#ifndef SECBUFFER_ALERT
+#define SECBUFFER_ALERT                 17
+#endif
+
+/* Both schannel buffer sizes must be > 0 */
+#define CURL_SCHANNEL_BUFFER_INIT_SIZE   4096
+#define CURL_SCHANNEL_BUFFER_FREE_SIZE   1024
+
+/* Uncomment to force verbose output
+ * #define infof(x, y, ...) printf(y, __VA_ARGS__)
+ * #define failf(x, y, ...) printf(y, __VA_ARGS__)
+ */
+
+/* Structs to store Schannel handles */
+struct curl_schannel_cred {
+  CredHandle cred_handle;
+  TimeStamp time_stamp;
+  int refcount;
+};
+
+struct curl_schannel_ctxt {
+  CtxtHandle ctxt_handle;
+  TimeStamp time_stamp;
+};
+
+struct ssl_backend_data {
+  struct curl_schannel_cred *cred;
+  struct curl_schannel_ctxt *ctxt;
+  SecPkgContext_StreamSizes stream_sizes;
+  size_t encdata_length, decdata_length;
+  size_t encdata_offset, decdata_offset;
+  unsigned char *encdata_buffer, *decdata_buffer;
+  /* encdata_is_incomplete: if encdata contains only a partial record that
+     can't be decrypted without another Curl_read_plain (that is, status is
+     SEC_E_INCOMPLETE_MESSAGE) then set this true. after Curl_read_plain writes
+     more bytes into encdata then set this back to false. */
+  bool encdata_is_incomplete;
+  unsigned long req_flags, ret_flags;
+  CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */
+  bool recv_sspi_close_notify; /* true if connection closed by close_notify */
+  bool recv_connection_closed; /* true if connection closed, regardless how */
+  bool use_alpn; /* true if ALPN is used for this connection */
+};
+
+#define BACKEND connssl->backend
+
+static Curl_recv schannel_recv;
+static Curl_send schannel_send;
+
+#ifdef _WIN32_WCE
+static CURLcode verify_certificate(struct connectdata *conn, int sockindex);
+#endif
+
+static void InitSecBuffer(SecBuffer *buffer, unsigned long BufType,
+                          void *BufDataPtr, unsigned long BufByteSize)
+{
+  buffer->cbBuffer = BufByteSize;
+  buffer->BufferType = BufType;
+  buffer->pvBuffer = BufDataPtr;
+}
+
+static void InitSecBufferDesc(SecBufferDesc *desc, SecBuffer *BufArr,
+                              unsigned long NumArrElem)
+{
+  desc->ulVersion = SECBUFFER_VERSION;
+  desc->pBuffers = BufArr;
+  desc->cBuffers = NumArrElem;
+}
+
+static CURLcode
+set_ssl_version_min_max(SCHANNEL_CRED *schannel_cred, struct connectdata *conn)
+{
+  struct Curl_easy *data = conn->data;
+  long ssl_version = SSL_CONN_CONFIG(version);
+  long ssl_version_max = SSL_CONN_CONFIG(version_max);
+  long i = ssl_version;
+
+  switch(ssl_version_max) {
+    case CURL_SSLVERSION_MAX_NONE:
+      ssl_version_max = ssl_version << 16;
+      break;
+    case CURL_SSLVERSION_MAX_DEFAULT:
+      ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
+      break;
+  }
+  for(; i <= (ssl_version_max >> 16); ++i) {
+    switch(i) {
+      case CURL_SSLVERSION_TLSv1_0:
+        schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_0_CLIENT;
+        break;
+      case CURL_SSLVERSION_TLSv1_1:
+        schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_1_CLIENT;
+        break;
+      case CURL_SSLVERSION_TLSv1_2:
+        schannel_cred->grbitEnabledProtocols |= SP_PROT_TLS1_2_CLIENT;
+        break;
+      case CURL_SSLVERSION_TLSv1_3:
+        failf(data, "Schannel: TLS 1.3 is not yet supported");
+        return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+  return CURLE_OK;
+}
+
+static CURLcode
+schannel_connect_step1(struct connectdata *conn, int sockindex)
+{
+  ssize_t written = -1;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  SecBuffer outbuf;
+  SecBufferDesc outbuf_desc;
+  SecBuffer inbuf;
+  SecBufferDesc inbuf_desc;
+#ifdef HAS_ALPN
+  unsigned char alpn_buffer[128];
+#endif
+  SCHANNEL_CRED schannel_cred;
+  SECURITY_STATUS sspi_status = SEC_E_OK;
+  struct curl_schannel_cred *old_cred = NULL;
+  struct in_addr addr;
+#ifdef ENABLE_IPV6
+  struct in6_addr addr6;
+#endif
+  TCHAR *host_name;
+  CURLcode result;
+  char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+
+  infof(data, "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n",
+        hostname, conn->remote_port);
+
+  if(Curl_verify_windows_version(5, 1, PLATFORM_WINNT,
+                                 VERSION_LESS_THAN_EQUAL)) {
+     /* SChannel in Windows XP (OS version 5.1) uses legacy handshakes and
+        algorithms that may not be supported by all servers. */
+     infof(data, "schannel: WinSSL version is old and may not be able to "
+           "connect to some servers due to lack of SNI, algorithms, etc.\n");
+  }
+
+#ifdef HAS_ALPN
+  /* ALPN is only supported on Windows 8.1 / Server 2012 R2 and above.
+     Also it doesn't seem to be supported for Wine, see curl bug #983. */
+  BACKEND->use_alpn = conn->bits.tls_enable_alpn &&
+                      !GetProcAddress(GetModuleHandleA("ntdll"),
+                                      "wine_get_version") &&
+                      Curl_verify_windows_version(6, 3, PLATFORM_WINNT,
+                                                  VERSION_GREATER_THAN_EQUAL);
+#else
+  BACKEND->use_alpn = false;
+#endif
+
+  BACKEND->cred = NULL;
+
+  /* check for an existing re-usable credential handle */
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    Curl_ssl_sessionid_lock(conn);
+    if(!Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL, sockindex)) {
+      BACKEND->cred = old_cred;
+      infof(data, "schannel: re-using existing credential handle\n");
+
+      /* increment the reference counter of the credential/session handle */
+      BACKEND->cred->refcount++;
+      infof(data, "schannel: incremented credential handle refcount = %d\n",
+            BACKEND->cred->refcount);
+    }
+    Curl_ssl_sessionid_unlock(conn);
+  }
+
+  if(!BACKEND->cred) {
+    /* setup Schannel API options */
+    memset(&schannel_cred, 0, sizeof(schannel_cred));
+    schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
+
+    if(conn->ssl_config.verifypeer) {
+#ifdef _WIN32_WCE
+      /* certificate validation on CE doesn't seem to work right; we'll
+         do it following a more manual process. */
+      schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
+        SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+        SCH_CRED_IGNORE_REVOCATION_OFFLINE;
+#else
+      schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION;
+      /* TODO s/data->set.ssl.no_revoke/SSL_SET_OPTION(no_revoke)/g */
+      if(data->set.ssl.no_revoke)
+        schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+                                 SCH_CRED_IGNORE_REVOCATION_OFFLINE;
+      else
+        schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN;
+#endif
+      if(data->set.ssl.no_revoke)
+        infof(data, "schannel: disabled server certificate revocation "
+                    "checks\n");
+      else
+        infof(data, "schannel: checking server certificate revocation\n");
+    }
+    else {
+      schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
+        SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
+        SCH_CRED_IGNORE_REVOCATION_OFFLINE;
+      infof(data, "schannel: disabled server certificate revocation checks\n");
+    }
+
+    if(!conn->ssl_config.verifyhost) {
+      schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;
+      infof(data, "schannel: verifyhost setting prevents Schannel from "
+            "comparing the supplied target name with the subject "
+            "names in server certificates.\n");
+    }
+
+    switch(conn->ssl_config.version) {
+    case CURL_SSLVERSION_DEFAULT:
+    case CURL_SSLVERSION_TLSv1:
+      schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT |
+        SP_PROT_TLS1_1_CLIENT |
+        SP_PROT_TLS1_2_CLIENT;
+      break;
+    case CURL_SSLVERSION_TLSv1_0:
+    case CURL_SSLVERSION_TLSv1_1:
+    case CURL_SSLVERSION_TLSv1_2:
+    case CURL_SSLVERSION_TLSv1_3:
+      {
+        result = set_ssl_version_min_max(&schannel_cred, conn);
+        if(result != CURLE_OK)
+          return result;
+        break;
+      }
+    case CURL_SSLVERSION_SSLv3:
+      schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT;
+      break;
+    case CURL_SSLVERSION_SSLv2:
+      schannel_cred.grbitEnabledProtocols = SP_PROT_SSL2_CLIENT;
+      break;
+    default:
+      failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+
+    /* allocate memory for the re-usable credential handle */
+    BACKEND->cred = (struct curl_schannel_cred *)
+      malloc(sizeof(struct curl_schannel_cred));
+    if(!BACKEND->cred) {
+      failf(data, "schannel: unable to allocate memory");
+      return CURLE_OUT_OF_MEMORY;
+    }
+    memset(BACKEND->cred, 0, sizeof(struct curl_schannel_cred));
+    BACKEND->cred->refcount = 1;
+
+    /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx
+       */
+    sspi_status =
+      s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME,
+                                         SECPKG_CRED_OUTBOUND, NULL,
+                                         &schannel_cred, NULL, NULL,
+                                         &BACKEND->cred->cred_handle,
+                                         &BACKEND->cred->time_stamp);
+
+    if(sspi_status != SEC_E_OK) {
+      if(sspi_status == SEC_E_WRONG_PRINCIPAL)
+        failf(data, "schannel: SNI or certificate check failed: %s",
+              Curl_sspi_strerror(conn, sspi_status));
+      else
+        failf(data, "schannel: AcquireCredentialsHandle failed: %s",
+              Curl_sspi_strerror(conn, sspi_status));
+      Curl_safefree(BACKEND->cred);
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+  }
+
+  /* Warn if SNI is disabled due to use of an IP address */
+  if(Curl_inet_pton(AF_INET, hostname, &addr)
+#ifdef ENABLE_IPV6
+     || Curl_inet_pton(AF_INET6, hostname, &addr6)
+#endif
+    ) {
+    infof(data, "schannel: using IP address, SNI is not supported by OS.\n");
+  }
+
+#ifdef HAS_ALPN
+  if(BACKEND->use_alpn) {
+    int cur = 0;
+    int list_start_index = 0;
+    unsigned int *extension_len = NULL;
+    unsigned short* list_len = NULL;
+
+    /* The first four bytes will be an unsigned int indicating number
+       of bytes of data in the rest of the the buffer. */
+    extension_len = (unsigned int *)(&alpn_buffer[cur]);
+    cur += sizeof(unsigned int);
+
+    /* The next four bytes are an indicator that this buffer will contain
+       ALPN data, as opposed to NPN, for example. */
+    *(unsigned int *)&alpn_buffer[cur] =
+      SecApplicationProtocolNegotiationExt_ALPN;
+    cur += sizeof(unsigned int);
+
+    /* The next two bytes will be an unsigned short indicating the number
+       of bytes used to list the preferred protocols. */
+    list_len = (unsigned short*)(&alpn_buffer[cur]);
+    cur += sizeof(unsigned short);
+
+    list_start_index = cur;
+
+#ifdef USE_NGHTTP2
+    if(data->set.httpversion >= CURL_HTTP_VERSION_2) {
+      memcpy(&alpn_buffer[cur], NGHTTP2_PROTO_ALPN, NGHTTP2_PROTO_ALPN_LEN);
+      cur += NGHTTP2_PROTO_ALPN_LEN;
+      infof(data, "schannel: ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
+    }
+#endif
+
+    alpn_buffer[cur++] = ALPN_HTTP_1_1_LENGTH;
+    memcpy(&alpn_buffer[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH);
+    cur += ALPN_HTTP_1_1_LENGTH;
+    infof(data, "schannel: ALPN, offering %s\n", ALPN_HTTP_1_1);
+
+    *list_len = curlx_uitous(cur - list_start_index);
+    *extension_len = *list_len + sizeof(unsigned int) + sizeof(unsigned short);
+
+    InitSecBuffer(&inbuf, SECBUFFER_APPLICATION_PROTOCOLS, alpn_buffer, cur);
+    InitSecBufferDesc(&inbuf_desc, &inbuf, 1);
+  }
+  else
+  {
+    InitSecBuffer(&inbuf, SECBUFFER_EMPTY, NULL, 0);
+    InitSecBufferDesc(&inbuf_desc, &inbuf, 1);
+  }
+#else /* HAS_ALPN */
+  InitSecBuffer(&inbuf, SECBUFFER_EMPTY, NULL, 0);
+  InitSecBufferDesc(&inbuf_desc, &inbuf, 1);
+#endif
+
+  /* setup output buffer */
+  InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0);
+  InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
+
+  /* setup request flags */
+  BACKEND->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
+    ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY |
+    ISC_REQ_STREAM;
+
+  /* allocate memory for the security context handle */
+  BACKEND->ctxt = (struct curl_schannel_ctxt *)
+    malloc(sizeof(struct curl_schannel_ctxt));
+  if(!BACKEND->ctxt) {
+    failf(data, "schannel: unable to allocate memory");
+    return CURLE_OUT_OF_MEMORY;
+  }
+  memset(BACKEND->ctxt, 0, sizeof(struct curl_schannel_ctxt));
+
+  host_name = Curl_convert_UTF8_to_tchar(hostname);
+  if(!host_name)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Schannel InitializeSecurityContext:
+     https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx
+
+     At the moment we don't pass inbuf unless we're using ALPN since we only
+     use it for that, and Wine (for which we currently disable ALPN) is giving
+     us problems with inbuf regardless. https://github.com/curl/curl/issues/983
+  */
+  sspi_status = s_pSecFn->InitializeSecurityContext(
+    &BACKEND->cred->cred_handle, NULL, host_name, BACKEND->req_flags, 0, 0,
+    (BACKEND->use_alpn ? &inbuf_desc : NULL),
+    0, &BACKEND->ctxt->ctxt_handle,
+    &outbuf_desc, &BACKEND->ret_flags, &BACKEND->ctxt->time_stamp);
+
+  Curl_unicodefree(host_name);
+
+  if(sspi_status != SEC_I_CONTINUE_NEEDED) {
+    if(sspi_status == SEC_E_WRONG_PRINCIPAL)
+      failf(data, "schannel: SNI or certificate check failed: %s",
+            Curl_sspi_strerror(conn, sspi_status));
+    else
+      failf(data, "schannel: initial InitializeSecurityContext failed: %s",
+            Curl_sspi_strerror(conn, sspi_status));
+    Curl_safefree(BACKEND->ctxt);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  infof(data, "schannel: sending initial handshake data: "
+        "sending %lu bytes...\n", outbuf.cbBuffer);
+
+  /* send initial handshake data which is now stored in output buffer */
+  result = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer,
+                            outbuf.cbBuffer, &written);
+  s_pSecFn->FreeContextBuffer(outbuf.pvBuffer);
+  if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) {
+    failf(data, "schannel: failed to send initial handshake data: "
+          "sent %zd of %lu bytes", written, outbuf.cbBuffer);
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+  infof(data, "schannel: sent initial handshake data: "
+        "sent %zd bytes\n", written);
+
+  BACKEND->recv_unrecoverable_err = CURLE_OK;
+  BACKEND->recv_sspi_close_notify = false;
+  BACKEND->recv_connection_closed = false;
+  BACKEND->encdata_is_incomplete = false;
+
+  /* continue to second handshake step */
+  connssl->connecting_state = ssl_connect_2;
+
+  return CURLE_OK;
+}
+
+static CURLcode
+schannel_connect_step2(struct connectdata *conn, int sockindex)
+{
+  int i;
+  ssize_t nread = -1, written = -1;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  unsigned char *reallocated_buffer;
+  size_t reallocated_length;
+  SecBuffer outbuf[3];
+  SecBufferDesc outbuf_desc;
+  SecBuffer inbuf[2];
+  SecBufferDesc inbuf_desc;
+  SECURITY_STATUS sspi_status = SEC_E_OK;
+  TCHAR *host_name;
+  CURLcode result;
+  bool doread;
+  char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+
+  doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE;
+
+  infof(data, "schannel: SSL/TLS connection with %s port %hu (step 2/3)\n",
+        hostname, conn->remote_port);
+
+  if(!BACKEND->cred || !BACKEND->ctxt)
+    return CURLE_SSL_CONNECT_ERROR;
+
+  /* buffer to store previously received and decrypted data */
+  if(BACKEND->decdata_buffer == NULL) {
+    BACKEND->decdata_offset = 0;
+    BACKEND->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
+    BACKEND->decdata_buffer = malloc(BACKEND->decdata_length);
+    if(BACKEND->decdata_buffer == NULL) {
+      failf(data, "schannel: unable to allocate memory");
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  /* buffer to store previously received and encrypted data */
+  if(BACKEND->encdata_buffer == NULL) {
+    BACKEND->encdata_is_incomplete = false;
+    BACKEND->encdata_offset = 0;
+    BACKEND->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE;
+    BACKEND->encdata_buffer = malloc(BACKEND->encdata_length);
+    if(BACKEND->encdata_buffer == NULL) {
+      failf(data, "schannel: unable to allocate memory");
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  /* if we need a bigger buffer to read a full message, increase buffer now */
+  if(BACKEND->encdata_length - BACKEND->encdata_offset <
+     CURL_SCHANNEL_BUFFER_FREE_SIZE) {
+    /* increase internal encrypted data buffer */
+    reallocated_length = BACKEND->encdata_offset +
+      CURL_SCHANNEL_BUFFER_FREE_SIZE;
+    reallocated_buffer = realloc(BACKEND->encdata_buffer,
+                                 reallocated_length);
+
+    if(reallocated_buffer == NULL) {
+      failf(data, "schannel: unable to re-allocate memory");
+      return CURLE_OUT_OF_MEMORY;
+    }
+    else {
+      BACKEND->encdata_buffer = reallocated_buffer;
+      BACKEND->encdata_length = reallocated_length;
+    }
+  }
+
+  for(;;) {
+    if(doread) {
+      /* read encrypted handshake data from socket */
+      result = Curl_read_plain(conn->sock[sockindex],
+                               (char *) (BACKEND->encdata_buffer +
+                                         BACKEND->encdata_offset),
+                               BACKEND->encdata_length -
+                               BACKEND->encdata_offset,
+                               &nread);
+      if(result == CURLE_AGAIN) {
+        if(connssl->connecting_state != ssl_connect_2_writing)
+          connssl->connecting_state = ssl_connect_2_reading;
+        infof(data, "schannel: failed to receive handshake, "
+              "need more data\n");
+        return CURLE_OK;
+      }
+      else if((result != CURLE_OK) || (nread == 0)) {
+        failf(data, "schannel: failed to receive handshake, "
+              "SSL/TLS connection failed");
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+
+      /* increase encrypted data buffer offset */
+      BACKEND->encdata_offset += nread;
+      BACKEND->encdata_is_incomplete = false;
+      infof(data, "schannel: encrypted data got %zd\n", nread);
+    }
+
+    infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
+          BACKEND->encdata_offset, BACKEND->encdata_length);
+
+    /* setup input buffers */
+    InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(BACKEND->encdata_offset),
+                  curlx_uztoul(BACKEND->encdata_offset));
+    InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
+    InitSecBufferDesc(&inbuf_desc, inbuf, 2);
+
+    /* setup output buffers */
+    InitSecBuffer(&outbuf[0], SECBUFFER_TOKEN, NULL, 0);
+    InitSecBuffer(&outbuf[1], SECBUFFER_ALERT, NULL, 0);
+    InitSecBuffer(&outbuf[2], SECBUFFER_EMPTY, NULL, 0);
+    InitSecBufferDesc(&outbuf_desc, outbuf, 3);
+
+    if(inbuf[0].pvBuffer == NULL) {
+      failf(data, "schannel: unable to allocate memory");
+      return CURLE_OUT_OF_MEMORY;
+    }
+
+    /* copy received handshake data into input buffer */
+    memcpy(inbuf[0].pvBuffer, BACKEND->encdata_buffer,
+           BACKEND->encdata_offset);
+
+    host_name = Curl_convert_UTF8_to_tchar(hostname);
+    if(!host_name)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx
+       */
+    sspi_status = s_pSecFn->InitializeSecurityContext(
+      &BACKEND->cred->cred_handle, &BACKEND->ctxt->ctxt_handle,
+      host_name, BACKEND->req_flags, 0, 0, &inbuf_desc, 0, NULL,
+      &outbuf_desc, &BACKEND->ret_flags, &BACKEND->ctxt->time_stamp);
+
+    Curl_unicodefree(host_name);
+
+    /* free buffer for received handshake data */
+    Curl_safefree(inbuf[0].pvBuffer);
+
+    /* check if the handshake was incomplete */
+    if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
+      BACKEND->encdata_is_incomplete = true;
+      connssl->connecting_state = ssl_connect_2_reading;
+      infof(data, "schannel: received incomplete message, need more data\n");
+      return CURLE_OK;
+    }
+
+    /* If the server has requested a client certificate, attempt to continue
+       the handshake without one. This will allow connections to servers which
+       request a client certificate but do not require it. */
+    if(sspi_status == SEC_I_INCOMPLETE_CREDENTIALS &&
+       !(BACKEND->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) {
+      BACKEND->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS;
+      connssl->connecting_state = ssl_connect_2_writing;
+      infof(data, "schannel: a client certificate has been requested\n");
+      return CURLE_OK;
+    }
+
+    /* check if the handshake needs to be continued */
+    if(sspi_status == SEC_I_CONTINUE_NEEDED || sspi_status == SEC_E_OK) {
+      for(i = 0; i < 3; i++) {
+        /* search for handshake tokens that need to be send */
+        if(outbuf[i].BufferType == SECBUFFER_TOKEN && outbuf[i].cbBuffer > 0) {
+          infof(data, "schannel: sending next handshake data: "
+                "sending %lu bytes...\n", outbuf[i].cbBuffer);
+
+          /* send handshake token to server */
+          result = Curl_write_plain(conn, conn->sock[sockindex],
+                                    outbuf[i].pvBuffer, outbuf[i].cbBuffer,
+                                    &written);
+          if((result != CURLE_OK) ||
+             (outbuf[i].cbBuffer != (size_t) written)) {
+            failf(data, "schannel: failed to send next handshake data: "
+                  "sent %zd of %lu bytes", written, outbuf[i].cbBuffer);
+            return CURLE_SSL_CONNECT_ERROR;
+          }
+        }
+
+        /* free obsolete buffer */
+        if(outbuf[i].pvBuffer != NULL) {
+          s_pSecFn->FreeContextBuffer(outbuf[i].pvBuffer);
+        }
+      }
+    }
+    else {
+      if(sspi_status == SEC_E_WRONG_PRINCIPAL)
+        failf(data, "schannel: SNI or certificate check failed: %s",
+              Curl_sspi_strerror(conn, sspi_status));
+      else
+        failf(data, "schannel: next InitializeSecurityContext failed: %s",
+              Curl_sspi_strerror(conn, sspi_status));
+      return sspi_status == SEC_E_UNTRUSTED_ROOT ?
+          CURLE_SSL_CACERT : CURLE_SSL_CONNECT_ERROR;
+    }
+
+    /* check if there was additional remaining encrypted data */
+    if(inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) {
+      infof(data, "schannel: encrypted data length: %lu\n", inbuf[1].cbBuffer);
+      /*
+        There are two cases where we could be getting extra data here:
+        1) If we're renegotiating a connection and the handshake is already
+        complete (from the server perspective), it can encrypted app data
+        (not handshake data) in an extra buffer at this point.
+        2) (sspi_status == SEC_I_CONTINUE_NEEDED) We are negotiating a
+        connection and this extra data is part of the handshake.
+        We should process the data immediately; waiting for the socket to
+        be ready may fail since the server is done sending handshake data.
+      */
+      /* check if the remaining data is less than the total amount
+         and therefore begins after the already processed data */
+      if(BACKEND->encdata_offset > inbuf[1].cbBuffer) {
+        memmove(BACKEND->encdata_buffer,
+                (BACKEND->encdata_buffer + BACKEND->encdata_offset) -
+                inbuf[1].cbBuffer, inbuf[1].cbBuffer);
+        BACKEND->encdata_offset = inbuf[1].cbBuffer;
+        if(sspi_status == SEC_I_CONTINUE_NEEDED) {
+          doread = FALSE;
+          continue;
+        }
+      }
+    }
+    else {
+      BACKEND->encdata_offset = 0;
+    }
+    break;
+  }
+
+  /* check if the handshake needs to be continued */
+  if(sspi_status == SEC_I_CONTINUE_NEEDED) {
+    connssl->connecting_state = ssl_connect_2_reading;
+    return CURLE_OK;
+  }
+
+  /* check if the handshake is complete */
+  if(sspi_status == SEC_E_OK) {
+    connssl->connecting_state = ssl_connect_3;
+    infof(data, "schannel: SSL/TLS handshake complete\n");
+  }
+
+#ifdef _WIN32_WCE
+  /* Windows CE doesn't do any server certificate validation.
+     We have to do it manually. */
+  if(conn->ssl_config.verifypeer)
+    return verify_certificate(conn, sockindex);
+#endif
+
+  return CURLE_OK;
+}
+
+static CURLcode
+schannel_connect_step3(struct connectdata *conn, int sockindex)
+{
+  CURLcode result = CURLE_OK;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  SECURITY_STATUS sspi_status = SEC_E_OK;
+  CERT_CONTEXT *ccert_context = NULL;
+#ifndef CURL_DISABLE_VERBOSE_STRINGS
+  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+#endif
+#ifdef HAS_ALPN
+  SecPkgContext_ApplicationProtocol alpn_result;
+#endif
+
+  DEBUGASSERT(ssl_connect_3 == connssl->connecting_state);
+
+  infof(data, "schannel: SSL/TLS connection with %s port %hu (step 3/3)\n",
+        hostname, conn->remote_port);
+
+  if(!BACKEND->cred)
+    return CURLE_SSL_CONNECT_ERROR;
+
+  /* check if the required context attributes are met */
+  if(BACKEND->ret_flags != BACKEND->req_flags) {
+    if(!(BACKEND->ret_flags & ISC_RET_SEQUENCE_DETECT))
+      failf(data, "schannel: failed to setup sequence detection");
+    if(!(BACKEND->ret_flags & ISC_RET_REPLAY_DETECT))
+      failf(data, "schannel: failed to setup replay detection");
+    if(!(BACKEND->ret_flags & ISC_RET_CONFIDENTIALITY))
+      failf(data, "schannel: failed to setup confidentiality");
+    if(!(BACKEND->ret_flags & ISC_RET_ALLOCATED_MEMORY))
+      failf(data, "schannel: failed to setup memory allocation");
+    if(!(BACKEND->ret_flags & ISC_RET_STREAM))
+      failf(data, "schannel: failed to setup stream orientation");
+    return CURLE_SSL_CONNECT_ERROR;
+  }
+
+#ifdef HAS_ALPN
+  if(BACKEND->use_alpn) {
+    sspi_status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
+      SECPKG_ATTR_APPLICATION_PROTOCOL, &alpn_result);
+
+    if(sspi_status != SEC_E_OK) {
+      failf(data, "schannel: failed to retrieve ALPN result");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+
+    if(alpn_result.ProtoNegoStatus ==
+       SecApplicationProtocolNegotiationStatus_Success) {
+
+      infof(data, "schannel: ALPN, server accepted to use %.*s\n",
+        alpn_result.ProtocolIdSize, alpn_result.ProtocolId);
+
+#ifdef USE_NGHTTP2
+      if(alpn_result.ProtocolIdSize == NGHTTP2_PROTO_VERSION_ID_LEN &&
+         !memcmp(NGHTTP2_PROTO_VERSION_ID, alpn_result.ProtocolId,
+          NGHTTP2_PROTO_VERSION_ID_LEN)) {
+        conn->negnpn = CURL_HTTP_VERSION_2;
+      }
+      else
+#endif
+      if(alpn_result.ProtocolIdSize == ALPN_HTTP_1_1_LENGTH &&
+         !memcmp(ALPN_HTTP_1_1, alpn_result.ProtocolId,
+           ALPN_HTTP_1_1_LENGTH)) {
+        conn->negnpn = CURL_HTTP_VERSION_1_1;
+      }
+    }
+    else
+      infof(data, "ALPN, server did not agree to a protocol\n");
+  }
+#endif
+
+  /* save the current session data for possible re-use */
+  if(SSL_SET_OPTION(primary.sessionid)) {
+    bool incache;
+    struct curl_schannel_cred *old_cred = NULL;
+
+    Curl_ssl_sessionid_lock(conn);
+    incache = !(Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL,
+                                      sockindex));
+    if(incache) {
+      if(old_cred != BACKEND->cred) {
+        infof(data, "schannel: old credential handle is stale, removing\n");
+        /* we're not taking old_cred ownership here, no refcount++ is needed */
+        Curl_ssl_delsessionid(conn, (void *)old_cred);
+        incache = FALSE;
+      }
+    }
+    if(!incache) {
+      result = Curl_ssl_addsessionid(conn, (void *)BACKEND->cred,
+                                     sizeof(struct curl_schannel_cred),
+                                     sockindex);
+      if(result) {
+        Curl_ssl_sessionid_unlock(conn);
+        failf(data, "schannel: failed to store credential handle");
+        return result;
+      }
+      else {
+        /* this cred session is now also referenced by sessionid cache */
+        BACKEND->cred->refcount++;
+        infof(data, "schannel: stored credential handle in session cache\n");
+      }
+    }
+    Curl_ssl_sessionid_unlock(conn);
+  }
+
+  if(data->set.ssl.certinfo) {
+    sspi_status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
+      SECPKG_ATTR_REMOTE_CERT_CONTEXT, &ccert_context);
+
+    if((sspi_status != SEC_E_OK) || (ccert_context == NULL)) {
+      failf(data, "schannel: failed to retrieve remote cert context");
+      return CURLE_SSL_CONNECT_ERROR;
+    }
+
+    result = Curl_ssl_init_certinfo(data, 1);
+    if(!result) {
+      if(((ccert_context->dwCertEncodingType & X509_ASN_ENCODING) != 0) &&
+         (ccert_context->cbCertEncoded > 0)) {
+
+        const char *beg = (const char *) ccert_context->pbCertEncoded;
+        const char *end = beg + ccert_context->cbCertEncoded;
+        result = Curl_extract_certinfo(conn, 0, beg, end);
+      }
+    }
+    CertFreeCertificateContext(ccert_context);
+    if(result)
+      return result;
+  }
+
+  connssl->connecting_state = ssl_connect_done;
+
+  return CURLE_OK;
+}
+
+static CURLcode
+schannel_connect_common(struct connectdata *conn, int sockindex,
+                        bool nonblocking, bool *done)
+{
+  CURLcode result;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  curl_socket_t sockfd = conn->sock[sockindex];
+  time_t timeout_ms;
+  int what;
+
+  /* check if the connection has already been established */
+  if(ssl_connection_complete == connssl->state) {
+    *done = TRUE;
+    return CURLE_OK;
+  }
+
+  if(ssl_connect_1 == connssl->connecting_state) {
+    /* check out how much more time we're allowed */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL/TLS connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    result = schannel_connect_step1(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  while(ssl_connect_2 == connssl->connecting_state ||
+        ssl_connect_2_reading == connssl->connecting_state ||
+        ssl_connect_2_writing == connssl->connecting_state) {
+
+    /* check out how much more time we're allowed */
+    timeout_ms = Curl_timeleft(data, NULL, TRUE);
+
+    if(timeout_ms < 0) {
+      /* no need to continue if time already is up */
+      failf(data, "SSL/TLS connection timeout");
+      return CURLE_OPERATION_TIMEDOUT;
+    }
+
+    /* if ssl is expecting something, check if it's available. */
+    if(connssl->connecting_state == ssl_connect_2_reading
+       || connssl->connecting_state == ssl_connect_2_writing) {
+
+      curl_socket_t writefd = ssl_connect_2_writing ==
+        connssl->connecting_state ? sockfd : CURL_SOCKET_BAD;
+      curl_socket_t readfd = ssl_connect_2_reading ==
+        connssl->connecting_state ? sockfd : CURL_SOCKET_BAD;
+
+      what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
+                               nonblocking ? 0 : timeout_ms);
+      if(what < 0) {
+        /* fatal error */
+        failf(data, "select/poll on SSL/TLS socket, errno: %d", SOCKERRNO);
+        return CURLE_SSL_CONNECT_ERROR;
+      }
+      else if(0 == what) {
+        if(nonblocking) {
+          *done = FALSE;
+          return CURLE_OK;
+        }
+        else {
+          /* timeout */
+          failf(data, "SSL/TLS connection timeout");
+          return CURLE_OPERATION_TIMEDOUT;
+        }
+      }
+      /* socket is readable or writable */
+    }
+
+    /* Run transaction, and return to the caller if it failed or if
+     * this connection is part of a multi handle and this loop would
+     * execute again. This permits the owner of a multi handle to
+     * abort a connection attempt before step2 has completed while
+     * ensuring that a client using select() or epoll() will always
+     * have a valid fdset to wait on.
+     */
+    result = schannel_connect_step2(conn, sockindex);
+    if(result || (nonblocking &&
+                  (ssl_connect_2 == connssl->connecting_state ||
+                   ssl_connect_2_reading == connssl->connecting_state ||
+                   ssl_connect_2_writing == connssl->connecting_state)))
+      return result;
+
+  } /* repeat step2 until all transactions are done. */
+
+  if(ssl_connect_3 == connssl->connecting_state) {
+    result = schannel_connect_step3(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  if(ssl_connect_done == connssl->connecting_state) {
+    connssl->state = ssl_connection_complete;
+    conn->recv[sockindex] = schannel_recv;
+    conn->send[sockindex] = schannel_send;
+    *done = TRUE;
+  }
+  else
+    *done = FALSE;
+
+  /* reset our connection state machine */
+  connssl->connecting_state = ssl_connect_1;
+
+  return CURLE_OK;
+}
+
+static ssize_t
+schannel_send(struct connectdata *conn, int sockindex,
+              const void *buf, size_t len, CURLcode *err)
+{
+  ssize_t written = -1;
+  size_t data_len = 0;
+  unsigned char *data = NULL;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  SecBuffer outbuf[4];
+  SecBufferDesc outbuf_desc;
+  SECURITY_STATUS sspi_status = SEC_E_OK;
+  CURLcode result;
+
+  /* check if the maximum stream sizes were queried */
+  if(BACKEND->stream_sizes.cbMaximumMessage == 0) {
+    sspi_status = s_pSecFn->QueryContextAttributes(
+      &BACKEND->ctxt->ctxt_handle,
+      SECPKG_ATTR_STREAM_SIZES,
+      &BACKEND->stream_sizes);
+    if(sspi_status != SEC_E_OK) {
+      *err = CURLE_SEND_ERROR;
+      return -1;
+    }
+  }
+
+  /* check if the buffer is longer than the maximum message length */
+  if(len > BACKEND->stream_sizes.cbMaximumMessage) {
+    len = BACKEND->stream_sizes.cbMaximumMessage;
+  }
+
+  /* calculate the complete message length and allocate a buffer for it */
+  data_len = BACKEND->stream_sizes.cbHeader + len +
+    BACKEND->stream_sizes.cbTrailer;
+  data = (unsigned char *) malloc(data_len);
+  if(data == NULL) {
+    *err = CURLE_OUT_OF_MEMORY;
+    return -1;
+  }
+
+  /* setup output buffers (header, data, trailer, empty) */
+  InitSecBuffer(&outbuf[0], SECBUFFER_STREAM_HEADER,
+                data, BACKEND->stream_sizes.cbHeader);
+  InitSecBuffer(&outbuf[1], SECBUFFER_DATA,
+                data + BACKEND->stream_sizes.cbHeader, curlx_uztoul(len));
+  InitSecBuffer(&outbuf[2], SECBUFFER_STREAM_TRAILER,
+                data + BACKEND->stream_sizes.cbHeader + len,
+                BACKEND->stream_sizes.cbTrailer);
+  InitSecBuffer(&outbuf[3], SECBUFFER_EMPTY, NULL, 0);
+  InitSecBufferDesc(&outbuf_desc, outbuf, 4);
+
+  /* copy data into output buffer */
+  memcpy(outbuf[1].pvBuffer, buf, len);
+
+  /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375390.aspx */
+  sspi_status = s_pSecFn->EncryptMessage(&BACKEND->ctxt->ctxt_handle, 0,
+                                         &outbuf_desc, 0);
+
+  /* check if the message was encrypted */
+  if(sspi_status == SEC_E_OK) {
+    written = 0;
+
+    /* send the encrypted message including header, data and trailer */
+    len = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer;
+
+    /*
+      It's important to send the full message which includes the header,
+      encrypted payload, and trailer.  Until the client receives all the
+      data a coherent message has not been delivered and the client
+      can't read any of it.
+
+      If we wanted to buffer the unwritten encrypted bytes, we would
+      tell the client that all data it has requested to be sent has been
+      sent. The unwritten encrypted bytes would be the first bytes to
+      send on the next invocation.
+      Here's the catch with this - if we tell the client that all the
+      bytes have been sent, will the client call this method again to
+      send the buffered data?  Looking at who calls this function, it
+      seems the answer is NO.
+    */
+
+    /* send entire message or fail */
+    while(len > (size_t)written) {
+      ssize_t this_write;
+      time_t timeleft;
+      int what;
+
+      this_write = 0;
+
+      timeleft = Curl_timeleft(conn->data, NULL, FALSE);
+      if(timeleft < 0) {
+        /* we already got the timeout */
+        failf(conn->data, "schannel: timed out sending data "
+              "(bytes sent: %zd)", written);
+        *err = CURLE_OPERATION_TIMEDOUT;
+        written = -1;
+        break;
+      }
+
+      what = SOCKET_WRITABLE(conn->sock[sockindex], timeleft);
+      if(what < 0) {
+        /* fatal error */
+        failf(conn->data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
+        *err = CURLE_SEND_ERROR;
+        written = -1;
+        break;
+      }
+      else if(0 == what) {
+        failf(conn->data, "schannel: timed out sending data "
+              "(bytes sent: %zd)", written);
+        *err = CURLE_OPERATION_TIMEDOUT;
+        written = -1;
+        break;
+      }
+      /* socket is writable */
+
+      result = Curl_write_plain(conn, conn->sock[sockindex], data + written,
+                                len - written, &this_write);
+      if(result == CURLE_AGAIN)
+        continue;
+      else if(result != CURLE_OK) {
+        *err = result;
+        written = -1;
+        break;
+      }
+
+      written += this_write;
+    }
+  }
+  else if(sspi_status == SEC_E_INSUFFICIENT_MEMORY) {
+    *err = CURLE_OUT_OF_MEMORY;
+  }
+  else{
+    *err = CURLE_SEND_ERROR;
+  }
+
+  Curl_safefree(data);
+
+  if(len == (size_t)written)
+    /* Encrypted message including header, data and trailer entirely sent.
+       The return value is the number of unencrypted bytes that were sent. */
+    written = outbuf[1].cbBuffer;
+
+  return written;
+}
+
+static ssize_t
+schannel_recv(struct connectdata *conn, int sockindex,
+              char *buf, size_t len, CURLcode *err)
+{
+  size_t size = 0;
+  ssize_t nread = -1;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  unsigned char *reallocated_buffer;
+  size_t reallocated_length;
+  bool done = FALSE;
+  SecBuffer inbuf[4];
+  SecBufferDesc inbuf_desc;
+  SECURITY_STATUS sspi_status = SEC_E_OK;
+  /* we want the length of the encrypted buffer to be at least large enough
+     that it can hold all the bytes requested and some TLS record overhead. */
+  size_t min_encdata_length = len + CURL_SCHANNEL_BUFFER_FREE_SIZE;
+
+  /****************************************************************************
+   * Don't return or set BACKEND->recv_unrecoverable_err unless in the cleanup.
+   * The pattern for return error is set *err, optional infof, goto cleanup.
+   *
+   * Our priority is to always return as much decrypted data to the caller as
+   * possible, even if an error occurs. The state of the decrypted buffer must
+   * always be valid. Transfer of decrypted data to the caller's buffer is
+   * handled in the cleanup.
+   */
+
+  infof(data, "schannel: client wants to read %zu bytes\n", len);
+  *err = CURLE_OK;
+
+  if(len && len <= BACKEND->decdata_offset) {
+    infof(data, "schannel: enough decrypted data is already available\n");
+    goto cleanup;
+  }
+  else if(BACKEND->recv_unrecoverable_err) {
+    *err = BACKEND->recv_unrecoverable_err;
+    infof(data, "schannel: an unrecoverable error occurred in a prior call\n");
+    goto cleanup;
+  }
+  else if(BACKEND->recv_sspi_close_notify) {
+    /* once a server has indicated shutdown there is no more encrypted data */
+    infof(data, "schannel: server indicated shutdown in a prior call\n");
+    goto cleanup;
+  }
+  else if(!len) {
+    /* It's debatable what to return when !len. Regardless we can't return
+    immediately because there may be data to decrypt (in the case we want to
+    decrypt all encrypted cached data) so handle !len later in cleanup.
+    */
+    ; /* do nothing */
+  }
+  else if(!BACKEND->recv_connection_closed) {
+    /* increase enc buffer in order to fit the requested amount of data */
+    size = BACKEND->encdata_length - BACKEND->encdata_offset;
+    if(size < CURL_SCHANNEL_BUFFER_FREE_SIZE ||
+       BACKEND->encdata_length < min_encdata_length) {
+      reallocated_length = BACKEND->encdata_offset +
+                           CURL_SCHANNEL_BUFFER_FREE_SIZE;
+      if(reallocated_length < min_encdata_length) {
+        reallocated_length = min_encdata_length;
+      }
+      reallocated_buffer = realloc(BACKEND->encdata_buffer,
+                                   reallocated_length);
+      if(reallocated_buffer == NULL) {
+        *err = CURLE_OUT_OF_MEMORY;
+        failf(data, "schannel: unable to re-allocate memory");
+        goto cleanup;
+      }
+
+      BACKEND->encdata_buffer = reallocated_buffer;
+      BACKEND->encdata_length = reallocated_length;
+      size = BACKEND->encdata_length - BACKEND->encdata_offset;
+      infof(data, "schannel: encdata_buffer resized %zu\n",
+            BACKEND->encdata_length);
+    }
+
+    infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
+          BACKEND->encdata_offset, BACKEND->encdata_length);
+
+    /* read encrypted data from socket */
+    *err = Curl_read_plain(conn->sock[sockindex],
+                           (char *)(BACKEND->encdata_buffer +
+                                    BACKEND->encdata_offset),
+                           size, &nread);
+    if(*err) {
+      nread = -1;
+      if(*err == CURLE_AGAIN)
+        infof(data, "schannel: Curl_read_plain returned CURLE_AGAIN\n");
+      else if(*err == CURLE_RECV_ERROR)
+        infof(data, "schannel: Curl_read_plain returned CURLE_RECV_ERROR\n");
+      else
+        infof(data, "schannel: Curl_read_plain returned error %d\n", *err);
+    }
+    else if(nread == 0) {
+      BACKEND->recv_connection_closed = true;
+      infof(data, "schannel: server closed the connection\n");
+    }
+    else if(nread > 0) {
+      BACKEND->encdata_offset += (size_t)nread;
+      BACKEND->encdata_is_incomplete = false;
+      infof(data, "schannel: encrypted data got %zd\n", nread);
+    }
+  }
+
+  infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
+        BACKEND->encdata_offset, BACKEND->encdata_length);
+
+  /* decrypt loop */
+  while(BACKEND->encdata_offset > 0 && sspi_status == SEC_E_OK &&
+        (!len || BACKEND->decdata_offset < len ||
+         BACKEND->recv_connection_closed)) {
+    /* prepare data buffer for DecryptMessage call */
+    InitSecBuffer(&inbuf[0], SECBUFFER_DATA, BACKEND->encdata_buffer,
+                  curlx_uztoul(BACKEND->encdata_offset));
+
+    /* we need 3 more empty input buffers for possible output */
+    InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0);
+    InitSecBuffer(&inbuf[2], SECBUFFER_EMPTY, NULL, 0);
+    InitSecBuffer(&inbuf[3], SECBUFFER_EMPTY, NULL, 0);
+    InitSecBufferDesc(&inbuf_desc, inbuf, 4);
+
+    /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx
+       */
+    sspi_status = s_pSecFn->DecryptMessage(&BACKEND->ctxt->ctxt_handle,
+                                           &inbuf_desc, 0, NULL);
+
+    /* check if everything went fine (server may want to renegotiate
+       or shutdown the connection context) */
+    if(sspi_status == SEC_E_OK || sspi_status == SEC_I_RENEGOTIATE ||
+       sspi_status == SEC_I_CONTEXT_EXPIRED) {
+      /* check for successfully decrypted data, even before actual
+         renegotiation or shutdown of the connection context */
+      if(inbuf[1].BufferType == SECBUFFER_DATA) {
+        infof(data, "schannel: decrypted data length: %lu\n",
+              inbuf[1].cbBuffer);
+
+        /* increase buffer in order to fit the received amount of data */
+        size = inbuf[1].cbBuffer > CURL_SCHANNEL_BUFFER_FREE_SIZE ?
+               inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_FREE_SIZE;
+        if(BACKEND->decdata_length - BACKEND->decdata_offset < size ||
+           BACKEND->decdata_length < len) {
+          /* increase internal decrypted data buffer */
+          reallocated_length = BACKEND->decdata_offset + size;
+          /* make sure that the requested amount of data fits */
+          if(reallocated_length < len) {
+            reallocated_length = len;
+          }
+          reallocated_buffer = realloc(BACKEND->decdata_buffer,
+                                       reallocated_length);
+          if(reallocated_buffer == NULL) {
+            *err = CURLE_OUT_OF_MEMORY;
+            failf(data, "schannel: unable to re-allocate memory");
+            goto cleanup;
+          }
+          BACKEND->decdata_buffer = reallocated_buffer;
+          BACKEND->decdata_length = reallocated_length;
+        }
+
+        /* copy decrypted data to internal buffer */
+        size = inbuf[1].cbBuffer;
+        if(size) {
+          memcpy(BACKEND->decdata_buffer + BACKEND->decdata_offset,
+                 inbuf[1].pvBuffer, size);
+          BACKEND->decdata_offset += size;
+        }
+
+        infof(data, "schannel: decrypted data added: %zu\n", size);
+        infof(data, "schannel: decrypted data cached: offset %zu length %zu\n",
+              BACKEND->decdata_offset, BACKEND->decdata_length);
+      }
+
+      /* check for remaining encrypted data */
+      if(inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) {
+        infof(data, "schannel: encrypted data length: %lu\n",
+              inbuf[3].cbBuffer);
+
+        /* check if the remaining data is less than the total amount
+         * and therefore begins after the already processed data
+         */
+        if(BACKEND->encdata_offset > inbuf[3].cbBuffer) {
+          /* move remaining encrypted data forward to the beginning of
+             buffer */
+          memmove(BACKEND->encdata_buffer,
+                  (BACKEND->encdata_buffer + BACKEND->encdata_offset) -
+                  inbuf[3].cbBuffer, inbuf[3].cbBuffer);
+          BACKEND->encdata_offset = inbuf[3].cbBuffer;
+        }
+
+        infof(data, "schannel: encrypted data cached: offset %zu length %zu\n",
+              BACKEND->encdata_offset, BACKEND->encdata_length);
+      }
+      else {
+        /* reset encrypted buffer offset, because there is no data remaining */
+        BACKEND->encdata_offset = 0;
+      }
+
+      /* check if server wants to renegotiate the connection context */
+      if(sspi_status == SEC_I_RENEGOTIATE) {
+        infof(data, "schannel: remote party requests renegotiation\n");
+        if(*err && *err != CURLE_AGAIN) {
+          infof(data, "schannel: can't renogotiate, an error is pending\n");
+          goto cleanup;
+        }
+        if(BACKEND->encdata_offset) {
+          *err = CURLE_RECV_ERROR;
+          infof(data, "schannel: can't renogotiate, "
+                      "encrypted data available\n");
+          goto cleanup;
+        }
+        /* begin renegotiation */
+        infof(data, "schannel: renegotiating SSL/TLS connection\n");
+        connssl->state = ssl_connection_negotiating;
+        connssl->connecting_state = ssl_connect_2_writing;
+        *err = schannel_connect_common(conn, sockindex, FALSE, &done);
+        if(*err) {
+          infof(data, "schannel: renegotiation failed\n");
+          goto cleanup;
+        }
+        /* now retry receiving data */
+        sspi_status = SEC_E_OK;
+        infof(data, "schannel: SSL/TLS connection renegotiated\n");
+        continue;
+      }
+      /* check if the server closed the connection */
+      else if(sspi_status == SEC_I_CONTEXT_EXPIRED) {
+        /* In Windows 2000 SEC_I_CONTEXT_EXPIRED (close_notify) is not
+           returned so we have to work around that in cleanup. */
+        BACKEND->recv_sspi_close_notify = true;
+        if(!BACKEND->recv_connection_closed) {
+          BACKEND->recv_connection_closed = true;
+          infof(data, "schannel: server closed the connection\n");
+        }
+        goto cleanup;
+      }
+    }
+    else if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) {
+      BACKEND->encdata_is_incomplete = true;
+      if(!*err)
+        *err = CURLE_AGAIN;
+      infof(data, "schannel: failed to decrypt data, need more data\n");
+      goto cleanup;
+    }
+    else {
+      *err = CURLE_RECV_ERROR;
+      infof(data, "schannel: failed to read data from server: %s\n",
+            Curl_sspi_strerror(conn, sspi_status));
+      goto cleanup;
+    }
+  }
+
+  infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n",
+        BACKEND->encdata_offset, BACKEND->encdata_length);
+
+  infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n",
+        BACKEND->decdata_offset, BACKEND->decdata_length);
+
+cleanup:
+  /* Warning- there is no guarantee the encdata state is valid at this point */
+  infof(data, "schannel: schannel_recv cleanup\n");
+
+  /* Error if the connection has closed without a close_notify.
+  Behavior here is a matter of debate. We don't want to be vulnerable to a
+  truncation attack however there's some browser precedent for ignoring the
+  close_notify for compatibility reasons.
+  Additionally, Windows 2000 (v5.0) is a special case since it seems it doesn't
+  return close_notify. In that case if the connection was closed we assume it
+  was graceful (close_notify) since there doesn't seem to be a way to tell.
+  */
+  if(len && !BACKEND->decdata_offset && BACKEND->recv_connection_closed &&
+     !BACKEND->recv_sspi_close_notify) {
+    bool isWin2k = Curl_verify_windows_version(5, 0, PLATFORM_WINNT,
+                                               VERSION_EQUAL);
+
+    if(isWin2k && sspi_status == SEC_E_OK)
+      BACKEND->recv_sspi_close_notify = true;
+    else {
+      *err = CURLE_RECV_ERROR;
+      infof(data, "schannel: server closed abruptly (missing close_notify)\n");
+    }
+  }
+
+  /* Any error other than CURLE_AGAIN is an unrecoverable error. */
+  if(*err && *err != CURLE_AGAIN)
+      BACKEND->recv_unrecoverable_err = *err;
+
+  size = len < BACKEND->decdata_offset ? len : BACKEND->decdata_offset;
+  if(size) {
+    memcpy(buf, BACKEND->decdata_buffer, size);
+    memmove(BACKEND->decdata_buffer, BACKEND->decdata_buffer + size,
+            BACKEND->decdata_offset - size);
+    BACKEND->decdata_offset -= size;
+
+    infof(data, "schannel: decrypted data returned %zu\n", size);
+    infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n",
+          BACKEND->decdata_offset, BACKEND->decdata_length);
+    *err = CURLE_OK;
+    return (ssize_t)size;
+  }
+
+  if(!*err && !BACKEND->recv_connection_closed)
+      *err = CURLE_AGAIN;
+
+  /* It's debatable what to return when !len. We could return whatever error we
+  got from decryption but instead we override here so the return is consistent.
+  */
+  if(!len)
+    *err = CURLE_OK;
+
+  return *err ? -1 : 0;
+}
+
+static CURLcode Curl_schannel_connect_nonblocking(struct connectdata *conn,
+                                                  int sockindex, bool *done)
+{
+  return schannel_connect_common(conn, sockindex, TRUE, done);
+}
+
+static CURLcode Curl_schannel_connect(struct connectdata *conn, int sockindex)
+{
+  CURLcode result;
+  bool done = FALSE;
+
+  result = schannel_connect_common(conn, sockindex, FALSE, &done);
+  if(result)
+    return result;
+
+  DEBUGASSERT(done);
+
+  return CURLE_OK;
+}
+
+static bool Curl_schannel_data_pending(const struct connectdata *conn,
+                                       int sockindex)
+{
+  const struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+
+  if(connssl->use) /* SSL/TLS is in use */
+    return (BACKEND->decdata_offset > 0 ||
+            (BACKEND->encdata_offset > 0 && !BACKEND->encdata_is_incomplete));
+  else
+    return FALSE;
+}
+
+static void Curl_schannel_close(struct connectdata *conn, int sockindex)
+{
+  if(conn->ssl[sockindex].use)
+    /* if the SSL/TLS channel hasn't been shut down yet, do that now. */
+    Curl_ssl_shutdown(conn, sockindex);
+}
+
+static void Curl_schannel_session_free(void *ptr)
+{
+  /* this is expected to be called under sessionid lock */
+  struct curl_schannel_cred *cred = ptr;
+
+  cred->refcount--;
+  if(cred->refcount == 0) {
+    s_pSecFn->FreeCredentialsHandle(&cred->cred_handle);
+    Curl_safefree(cred);
+  }
+}
+
+static int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
+{
+  /* See https://msdn.microsoft.com/en-us/library/windows/desktop/aa380138.aspx
+   * Shutting Down an Schannel Connection
+   */
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
+    conn->host.name;
+
+  infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n",
+        hostname, conn->remote_port);
+
+  if(BACKEND->cred && BACKEND->ctxt) {
+    SecBufferDesc BuffDesc;
+    SecBuffer Buffer;
+    SECURITY_STATUS sspi_status;
+    SecBuffer outbuf;
+    SecBufferDesc outbuf_desc;
+    CURLcode result;
+    TCHAR *host_name;
+    DWORD dwshut = SCHANNEL_SHUTDOWN;
+
+    InitSecBuffer(&Buffer, SECBUFFER_TOKEN, &dwshut, sizeof(dwshut));
+    InitSecBufferDesc(&BuffDesc, &Buffer, 1);
+
+    sspi_status = s_pSecFn->ApplyControlToken(&BACKEND->ctxt->ctxt_handle,
+                                              &BuffDesc);
+
+    if(sspi_status != SEC_E_OK)
+      failf(data, "schannel: ApplyControlToken failure: %s",
+            Curl_sspi_strerror(conn, sspi_status));
+
+    host_name = Curl_convert_UTF8_to_tchar(hostname);
+    if(!host_name)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* setup output buffer */
+    InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0);
+    InitSecBufferDesc(&outbuf_desc, &outbuf, 1);
+
+    sspi_status = s_pSecFn->InitializeSecurityContext(
+      &BACKEND->cred->cred_handle,
+      &BACKEND->ctxt->ctxt_handle,
+      host_name,
+      BACKEND->req_flags,
+      0,
+      0,
+      NULL,
+      0,
+      &BACKEND->ctxt->ctxt_handle,
+      &outbuf_desc,
+      &BACKEND->ret_flags,
+      &BACKEND->ctxt->time_stamp);
+
+    Curl_unicodefree(host_name);
+
+    if((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) {
+      /* send close message which is in output buffer */
+      ssize_t written;
+      result = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer,
+                                outbuf.cbBuffer, &written);
+
+      s_pSecFn->FreeContextBuffer(outbuf.pvBuffer);
+      if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) {
+        infof(data, "schannel: failed to send close msg: %s"
+              " (bytes written: %zd)\n", curl_easy_strerror(result), written);
+      }
+    }
+  }
+
+  /* free SSPI Schannel API security context handle */
+  if(BACKEND->ctxt) {
+    infof(data, "schannel: clear security context handle\n");
+    s_pSecFn->DeleteSecurityContext(&BACKEND->ctxt->ctxt_handle);
+    Curl_safefree(BACKEND->ctxt);
+  }
+
+  /* free SSPI Schannel API credential handle */
+  if(BACKEND->cred) {
+    Curl_ssl_sessionid_lock(conn);
+    Curl_schannel_session_free(BACKEND->cred);
+    Curl_ssl_sessionid_unlock(conn);
+    BACKEND->cred = NULL;
+  }
+
+  /* free internal buffer for received encrypted data */
+  if(BACKEND->encdata_buffer != NULL) {
+    Curl_safefree(BACKEND->encdata_buffer);
+    BACKEND->encdata_length = 0;
+    BACKEND->encdata_offset = 0;
+    BACKEND->encdata_is_incomplete = false;
+  }
+
+  /* free internal buffer for received decrypted data */
+  if(BACKEND->decdata_buffer != NULL) {
+    Curl_safefree(BACKEND->decdata_buffer);
+    BACKEND->decdata_length = 0;
+    BACKEND->decdata_offset = 0;
+  }
+
+  return CURLE_OK;
+}
+
+static int Curl_schannel_init(void)
+{
+  return (Curl_sspi_global_init() == CURLE_OK ? 1 : 0);
+}
+
+static void Curl_schannel_cleanup(void)
+{
+  Curl_sspi_global_cleanup();
+}
+
+static size_t Curl_schannel_version(char *buffer, size_t size)
+{
+  size = snprintf(buffer, size, "WinSSL");
+
+  return size;
+}
+
+static CURLcode Curl_schannel_random(struct Curl_easy *data UNUSED_PARAM,
+                                     unsigned char *entropy, size_t length)
+{
+  HCRYPTPROV hCryptProv = 0;
+
+  (void)data;
+
+  if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL,
+                          CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
+    return CURLE_FAILED_INIT;
+
+  if(!CryptGenRandom(hCryptProv, (DWORD)length, entropy)) {
+    CryptReleaseContext(hCryptProv, 0UL);
+    return CURLE_FAILED_INIT;
+  }
+
+  CryptReleaseContext(hCryptProv, 0UL);
+  return CURLE_OK;
+}
+
+#ifdef _WIN32_WCE
+static CURLcode verify_certificate(struct connectdata *conn, int sockindex)
+{
+  SECURITY_STATUS status;
+  struct Curl_easy *data = conn->data;
+  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
+  CURLcode result = CURLE_OK;
+  CERT_CONTEXT *pCertContextServer = NULL;
+  const CERT_CHAIN_CONTEXT *pChainContext = NULL;
+  const char * const conn_hostname = SSL_IS_PROXY() ?
+    conn->http_proxy.host.name :
+    conn->host.name;
+
+  status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
+                                            SECPKG_ATTR_REMOTE_CERT_CONTEXT,
+                                            &pCertContextServer);
+
+  if((status != SEC_E_OK) || (pCertContextServer == NULL)) {
+    failf(data, "schannel: Failed to read remote certificate context: %s",
+          Curl_sspi_strerror(conn, status));
+    result = CURLE_PEER_FAILED_VERIFICATION;
+  }
+
+  if(result == CURLE_OK) {
+    CERT_CHAIN_PARA ChainPara;
+    memset(&ChainPara, 0, sizeof(ChainPara));
+    ChainPara.cbSize = sizeof(ChainPara);
+
+    if(!CertGetCertificateChain(NULL,
+                                pCertContextServer,
+                                NULL,
+                                pCertContextServer->hCertStore,
+                                &ChainPara,
+                                (data->set.ssl.no_revoke ? 0 :
+                                 CERT_CHAIN_REVOCATION_CHECK_CHAIN),
+                                NULL,
+                                &pChainContext)) {
+      failf(data, "schannel: CertGetCertificateChain failed: %s",
+            Curl_sspi_strerror(conn, GetLastError()));
+      pChainContext = NULL;
+      result = CURLE_PEER_FAILED_VERIFICATION;
+    }
+
+    if(result == CURLE_OK) {
+      CERT_SIMPLE_CHAIN *pSimpleChain = pChainContext->rgpChain[0];
+      DWORD dwTrustErrorMask = ~(DWORD)(CERT_TRUST_IS_NOT_TIME_NESTED);
+      dwTrustErrorMask &= pSimpleChain->TrustStatus.dwErrorStatus;
+      if(dwTrustErrorMask) {
+        if(dwTrustErrorMask & CERT_TRUST_IS_REVOKED)
+          failf(data, "schannel: CertGetCertificateChain trust error"
+                " CERT_TRUST_IS_REVOKED");
+        else if(dwTrustErrorMask & CERT_TRUST_IS_PARTIAL_CHAIN)
+          failf(data, "schannel: CertGetCertificateChain trust error"
+                " CERT_TRUST_IS_PARTIAL_CHAIN");
+        else if(dwTrustErrorMask & CERT_TRUST_IS_UNTRUSTED_ROOT)
+          failf(data, "schannel: CertGetCertificateChain trust error"
+                " CERT_TRUST_IS_UNTRUSTED_ROOT");
+        else if(dwTrustErrorMask & CERT_TRUST_IS_NOT_TIME_VALID)
+          failf(data, "schannel: CertGetCertificateChain trust error"
+                " CERT_TRUST_IS_NOT_TIME_VALID");
+        else
+          failf(data, "schannel: CertGetCertificateChain error mask: 0x%08x",
+                dwTrustErrorMask);
+        result = CURLE_PEER_FAILED_VERIFICATION;
+      }
+    }
+  }
+
+  if(result == CURLE_OK) {
+    if(conn->ssl_config.verifyhost) {
+      TCHAR cert_hostname_buff[256];
+      DWORD len;
+
+      /* TODO: Fix this for certificates with multiple alternative names.
+      Right now we're only asking for the first preferred alternative name.
+      Instead we'd need to do all via CERT_NAME_SEARCH_ALL_NAMES_FLAG
+      (if WinCE supports that?) and run this section in a loop for each.
+      https://msdn.microsoft.com/en-us/library/windows/desktop/aa376086.aspx
+      curl: (51) schannel: CertGetNameString() certificate hostname
+      (.google.com) did not match connection (google.com)
+      */
+      len = CertGetNameString(pCertContextServer,
+                              CERT_NAME_DNS_TYPE,
+                              CERT_NAME_DISABLE_IE4_UTF8_FLAG,
+                              NULL,
+                              cert_hostname_buff,
+                              256);
+      if(len > 0) {
+        const char *cert_hostname;
+
+        /* Comparing the cert name and the connection hostname encoded as UTF-8
+         * is acceptable since both values are assumed to use ASCII
+         * (or some equivalent) encoding
+         */
+        cert_hostname = Curl_convert_tchar_to_UTF8(cert_hostname_buff);
+        if(!cert_hostname) {
+          result = CURLE_OUT_OF_MEMORY;
+        }
+        else{
+          int match_result;
+
+          match_result = Curl_cert_hostcheck(cert_hostname, conn->host.name);
+          if(match_result == CURL_HOST_MATCH) {
+            infof(data,
+                  "schannel: connection hostname (%s) validated "
+                  "against certificate name (%s)\n",
+                  conn->host.name,
+                  cert_hostname);
+            result = CURLE_OK;
+          }
+          else{
+            failf(data,
+                  "schannel: connection hostname (%s) "
+                  "does not match certificate name (%s)",
+                  conn->host.name,
+                  cert_hostname);
+            result = CURLE_PEER_FAILED_VERIFICATION;
+          }
+          Curl_unicodefree(cert_hostname);
+        }
+      }
+      else {
+        failf(data,
+              "schannel: CertGetNameString did not provide any "
+              "certificate name information");
+        result = CURLE_PEER_FAILED_VERIFICATION;
+      }
+    }
+  }
+
+  if(pChainContext)
+    CertFreeCertificateChain(pChainContext);
+
+  if(pCertContextServer)
+    CertFreeCertificateContext(pCertContextServer);
+
+  return result;
+}
+#endif /* _WIN32_WCE */
+
+static void *Curl_schannel_get_internals(struct ssl_connect_data *connssl,
+                                         CURLINFO info UNUSED_PARAM)
+{
+  (void)info;
+  return &BACKEND->ctxt->ctxt_handle;
+}
+
+const struct Curl_ssl Curl_ssl_schannel = {
+  { CURLSSLBACKEND_SCHANNEL, "schannel" }, /* info */
+
+  0, /* have_ca_path */
+  1, /* have_certinfo */
+  0, /* have_pinnedpubkey */
+  0, /* have_ssl_ctx */
+  0, /* support_https_proxy */
+
+  sizeof(struct ssl_backend_data),
+
+  Curl_schannel_init,                /* init */
+  Curl_schannel_cleanup,             /* cleanup */
+  Curl_schannel_version,             /* version */
+  Curl_none_check_cxn,               /* check_cxn */
+  Curl_schannel_shutdown,            /* shutdown */
+  Curl_schannel_data_pending,        /* data_pending */
+  Curl_schannel_random,              /* random */
+  Curl_none_cert_status_request,     /* cert_status_request */
+  Curl_schannel_connect,             /* connect */
+  Curl_schannel_connect_nonblocking, /* connect_nonblocking */
+  Curl_schannel_get_internals,       /* get_internals */
+  Curl_schannel_close,               /* close_one */
+  Curl_none_close_all,               /* close_all */
+  Curl_schannel_session_free,        /* session_free */
+  Curl_none_set_engine,              /* set_engine */
+  Curl_none_set_engine_default,      /* set_engine_default */
+  Curl_none_engines_list,            /* engines_list */
+  Curl_none_false_start,             /* false_start */
+  Curl_none_md5sum,                  /* md5sum */
+  NULL                               /* sha256sum */
+};
+
+#endif /* USE_SCHANNEL */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/schannel.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/schannel.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/schannel.h	(revision 331)
@@ -0,0 +1,34 @@
+#ifndef HEADER_CURL_SCHANNEL_H
+#define HEADER_CURL_SCHANNEL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2012, Marc Hoersken, <info@marc-hoersken.de>, et al.
+ * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+#ifdef USE_SCHANNEL
+
+#include "urldata.h"
+
+extern const struct Curl_ssl Curl_ssl_schannel;
+
+#endif /* USE_SCHANNEL */
+#endif /* HEADER_CURL_SCHANNEL_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/vtls.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/vtls.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/vtls.c	(revision 331)
@@ -0,0 +1,1326 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+/* This file is for implementing all "generic" SSL functions that all libcurl
+   internals should use. It is then responsible for calling the proper
+   "backend" function.
+
+   SSL-functions in libcurl should call functions in this source file, and not
+   to any specific SSL-layer.
+
+   Curl_ssl_ - prefix for generic ones
+
+   Note that this source code uses the functions of the configured SSL
+   backend via the global Curl_ssl instance.
+
+   "SSL/TLS Strong Encryption: An Introduction"
+   https://httpd.apache.org/docs/2.0/ssl/ssl_intro.html
+*/
+
+#include "curl_setup.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include "urldata.h"
+
+#include "vtls.h" /* generic SSL protos etc */
+#include "slist.h"
+#include "sendf.h"
+#include "strcase.h"
+#include "url.h"
+#include "progress.h"
+#include "share.h"
+#include "multiif.h"
+#include "timeval.h"
+#include "curl_md5.h"
+#include "warnless.h"
+#include "curl_base64.h"
+#include "curl_printf.h"
+
+/* The last #include files should be: */
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* convenience macro to check if this handle is using a shared SSL session */
+#define SSLSESSION_SHARED(data) (data->share &&                        \
+                                 (data->share->specifier &             \
+                                  (1<<CURL_LOCK_DATA_SSL_SESSION)))
+
+#define CLONE_STRING(var)                    \
+  if(source->var) {                          \
+    dest->var = strdup(source->var);         \
+    if(!dest->var)                           \
+      return FALSE;                          \
+  }                                          \
+  else                                       \
+    dest->var = NULL;
+
+bool
+Curl_ssl_config_matches(struct ssl_primary_config* data,
+                        struct ssl_primary_config* needle)
+{
+  if((data->version == needle->version) &&
+     (data->version_max == needle->version_max) &&
+     (data->verifypeer == needle->verifypeer) &&
+     (data->verifyhost == needle->verifyhost) &&
+     (data->verifystatus == needle->verifystatus) &&
+     Curl_safe_strcasecompare(data->CApath, needle->CApath) &&
+     Curl_safe_strcasecompare(data->CAfile, needle->CAfile) &&
+     Curl_safe_strcasecompare(data->clientcert, needle->clientcert) &&
+     Curl_safe_strcasecompare(data->random_file, needle->random_file) &&
+     Curl_safe_strcasecompare(data->egdsocket, needle->egdsocket) &&
+     Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list))
+    return TRUE;
+
+  return FALSE;
+}
+
+bool
+Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
+                              struct ssl_primary_config *dest)
+{
+  dest->version = source->version;
+  dest->version_max = source->version_max;
+  dest->verifypeer = source->verifypeer;
+  dest->verifyhost = source->verifyhost;
+  dest->verifystatus = source->verifystatus;
+  dest->sessionid = source->sessionid;
+
+  CLONE_STRING(CApath);
+  CLONE_STRING(CAfile);
+  CLONE_STRING(clientcert);
+  CLONE_STRING(random_file);
+  CLONE_STRING(egdsocket);
+  CLONE_STRING(cipher_list);
+
+  return TRUE;
+}
+
+void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc)
+{
+  Curl_safefree(sslc->CApath);
+  Curl_safefree(sslc->CAfile);
+  Curl_safefree(sslc->clientcert);
+  Curl_safefree(sslc->random_file);
+  Curl_safefree(sslc->egdsocket);
+  Curl_safefree(sslc->cipher_list);
+}
+
+#ifdef USE_SSL
+static int multissl_init(const struct Curl_ssl *backend);
+#endif
+
+int Curl_ssl_backend(void)
+{
+#ifdef USE_SSL
+  multissl_init(NULL);
+  return Curl_ssl->info.id;
+#else
+  return (int)CURLSSLBACKEND_NONE;
+#endif
+}
+
+#ifdef USE_SSL
+
+/* "global" init done? */
+static bool init_ssl = FALSE;
+
+/**
+ * Global SSL init
+ *
+ * @retval 0 error initializing SSL
+ * @retval 1 SSL initialized successfully
+ */
+int Curl_ssl_init(void)
+{
+  /* make sure this is only done once */
+  if(init_ssl)
+    return 1;
+  init_ssl = TRUE; /* never again */
+
+  return Curl_ssl->init();
+}
+
+
+/* Global cleanup */
+void Curl_ssl_cleanup(void)
+{
+  if(init_ssl) {
+    /* only cleanup if we did a previous init */
+    Curl_ssl->cleanup();
+    init_ssl = FALSE;
+  }
+}
+
+static bool ssl_prefs_check(struct Curl_easy *data)
+{
+  /* check for CURLOPT_SSLVERSION invalid parameter value */
+  const long sslver = data->set.ssl.primary.version;
+  if((sslver < 0) || (sslver >= CURL_SSLVERSION_LAST)) {
+    failf(data, "Unrecognized parameter value passed via CURLOPT_SSLVERSION");
+    return FALSE;
+  }
+
+  switch(data->set.ssl.primary.version_max) {
+  case CURL_SSLVERSION_MAX_NONE:
+  case CURL_SSLVERSION_MAX_DEFAULT:
+    break;
+
+  default:
+    if((data->set.ssl.primary.version_max >> 16) < sslver) {
+      failf(data, "CURL_SSLVERSION_MAX incompatible with CURL_SSLVERSION");
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+static CURLcode
+ssl_connect_init_proxy(struct connectdata *conn, int sockindex)
+{
+  DEBUGASSERT(conn->bits.proxy_ssl_connected[sockindex]);
+  if(ssl_connection_complete == conn->ssl[sockindex].state &&
+     !conn->proxy_ssl[sockindex].use) {
+    struct ssl_backend_data *pbdata;
+
+    if(!Curl_ssl->support_https_proxy)
+      return CURLE_NOT_BUILT_IN;
+
+    /* The pointers to the ssl backend data, which is opaque here, are swapped
+       rather than move the contents. */
+    pbdata = conn->proxy_ssl[sockindex].backend;
+    conn->proxy_ssl[sockindex] = conn->ssl[sockindex];
+
+    memset(&conn->ssl[sockindex], 0, sizeof(conn->ssl[sockindex]));
+    memset(pbdata, 0, Curl_ssl->sizeof_ssl_backend_data);
+
+    conn->ssl[sockindex].backend = pbdata;
+  }
+  return CURLE_OK;
+}
+
+CURLcode
+Curl_ssl_connect(struct connectdata *conn, int sockindex)
+{
+  CURLcode result;
+
+  if(conn->bits.proxy_ssl_connected[sockindex]) {
+    result = ssl_connect_init_proxy(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  if(!ssl_prefs_check(conn->data))
+    return CURLE_SSL_CONNECT_ERROR;
+
+  /* mark this is being ssl-enabled from here on. */
+  conn->ssl[sockindex].use = TRUE;
+  conn->ssl[sockindex].state = ssl_connection_negotiating;
+
+  result = Curl_ssl->connect(conn, sockindex);
+
+  if(!result)
+    Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSL is connected */
+
+  return result;
+}
+
+CURLcode
+Curl_ssl_connect_nonblocking(struct connectdata *conn, int sockindex,
+                             bool *done)
+{
+  CURLcode result;
+  if(conn->bits.proxy_ssl_connected[sockindex]) {
+    result = ssl_connect_init_proxy(conn, sockindex);
+    if(result)
+      return result;
+  }
+
+  if(!ssl_prefs_check(conn->data))
+    return CURLE_SSL_CONNECT_ERROR;
+
+  /* mark this is being ssl requested from here on. */
+  conn->ssl[sockindex].use = TRUE;
+  result = Curl_ssl->connect_nonblocking(conn, sockindex, done);
+  if(!result && *done)
+    Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSL is connected */
+  return result;
+}
+
+/*
+ * Lock shared SSL session data
+ */
+void Curl_ssl_sessionid_lock(struct connectdata *conn)
+{
+  if(SSLSESSION_SHARED(conn->data))
+    Curl_share_lock(conn->data,
+                    CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE);
+}
+
+/*
+ * Unlock shared SSL session data
+ */
+void Curl_ssl_sessionid_unlock(struct connectdata *conn)
+{
+  if(SSLSESSION_SHARED(conn->data))
+    Curl_share_unlock(conn->data, CURL_LOCK_DATA_SSL_SESSION);
+}
+
+/*
+ * Check if there's a session ID for the given connection in the cache, and if
+ * there's one suitable, it is provided. Returns TRUE when no entry matched.
+ */
+bool Curl_ssl_getsessionid(struct connectdata *conn,
+                           void **ssl_sessionid,
+                           size_t *idsize, /* set 0 if unknown */
+                           int sockindex)
+{
+  struct curl_ssl_session *check;
+  struct Curl_easy *data = conn->data;
+  size_t i;
+  long *general_age;
+  bool no_match = TRUE;
+
+  const bool isProxy = CONNECT_PROXY_SSL();
+  struct ssl_primary_config * const ssl_config = isProxy ?
+    &conn->proxy_ssl_config :
+    &conn->ssl_config;
+  const char * const name = isProxy ? conn->http_proxy.host.name :
+    conn->host.name;
+  int port = isProxy ? (int)conn->port : conn->remote_port;
+  *ssl_sessionid = NULL;
+
+  DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
+
+  if(!SSL_SET_OPTION(primary.sessionid))
+    /* session ID re-use is disabled */
+    return TRUE;
+
+  /* Lock if shared */
+  if(SSLSESSION_SHARED(data))
+    general_age = &data->share->sessionage;
+  else
+    general_age = &data->state.sessionage;
+
+  for(i = 0; i < data->set.general_ssl.max_ssl_sessions; i++) {
+    check = &data->state.session[i];
+    if(!check->sessionid)
+      /* not session ID means blank entry */
+      continue;
+    if(strcasecompare(name, check->name) &&
+       ((!conn->bits.conn_to_host && !check->conn_to_host) ||
+        (conn->bits.conn_to_host && check->conn_to_host &&
+         strcasecompare(conn->conn_to_host.name, check->conn_to_host))) &&
+       ((!conn->bits.conn_to_port && check->conn_to_port == -1) ||
+        (conn->bits.conn_to_port && check->conn_to_port != -1 &&
+         conn->conn_to_port == check->conn_to_port)) &&
+       (port == check->remote_port) &&
+       strcasecompare(conn->handler->scheme, check->scheme) &&
+       Curl_ssl_config_matches(ssl_config, &check->ssl_config)) {
+      /* yes, we have a session ID! */
+      (*general_age)++;          /* increase general age */
+      check->age = *general_age; /* set this as used in this age */
+      *ssl_sessionid = check->sessionid;
+      if(idsize)
+        *idsize = check->idsize;
+      no_match = FALSE;
+      break;
+    }
+  }
+
+  return no_match;
+}
+
+/*
+ * Kill a single session ID entry in the cache.
+ */
+void Curl_ssl_kill_session(struct curl_ssl_session *session)
+{
+  if(session->sessionid) {
+    /* defensive check */
+
+    /* free the ID the SSL-layer specific way */
+    Curl_ssl->session_free(session->sessionid);
+
+    session->sessionid = NULL;
+    session->age = 0; /* fresh */
+
+    Curl_free_primary_ssl_config(&session->ssl_config);
+
+    Curl_safefree(session->name);
+    Curl_safefree(session->conn_to_host);
+  }
+}
+
+/*
+ * Delete the given session ID from the cache.
+ */
+void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid)
+{
+  size_t i;
+  struct Curl_easy *data = conn->data;
+
+  for(i = 0; i < data->set.general_ssl.max_ssl_sessions; i++) {
+    struct curl_ssl_session *check = &data->state.session[i];
+
+    if(check->sessionid == ssl_sessionid) {
+      Curl_ssl_kill_session(check);
+      break;
+    }
+  }
+}
+
+/*
+ * Store session id in the session cache. The ID passed on to this function
+ * must already have been extracted and allocated the proper way for the SSL
+ * layer. Curl_XXXX_session_free() will be called to free/kill the session ID
+ * later on.
+ */
+CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
+                               void *ssl_sessionid,
+                               size_t idsize,
+                               int sockindex)
+{
+  size_t i;
+  struct Curl_easy *data = conn->data; /* the mother of all structs */
+  struct curl_ssl_session *store = &data->state.session[0];
+  long oldest_age = data->state.session[0].age; /* zero if unused */
+  char *clone_host;
+  char *clone_conn_to_host;
+  int conn_to_port;
+  long *general_age;
+  const bool isProxy = CONNECT_PROXY_SSL();
+  struct ssl_primary_config * const ssl_config = isProxy ?
+    &conn->proxy_ssl_config :
+    &conn->ssl_config;
+
+  DEBUGASSERT(SSL_SET_OPTION(primary.sessionid));
+
+  clone_host = strdup(isProxy ? conn->http_proxy.host.name : conn->host.name);
+  if(!clone_host)
+    return CURLE_OUT_OF_MEMORY; /* bail out */
+
+  if(conn->bits.conn_to_host) {
+    clone_conn_to_host = strdup(conn->conn_to_host.name);
+    if(!clone_conn_to_host) {
+      free(clone_host);
+      return CURLE_OUT_OF_MEMORY; /* bail out */
+    }
+  }
+  else
+    clone_conn_to_host = NULL;
+
+  if(conn->bits.conn_to_port)
+    conn_to_port = conn->conn_to_port;
+  else
+    conn_to_port = -1;
+
+  /* Now we should add the session ID and the host name to the cache, (remove
+     the oldest if necessary) */
+
+  /* If using shared SSL session, lock! */
+  if(SSLSESSION_SHARED(data)) {
+    general_age = &data->share->sessionage;
+  }
+  else {
+    general_age = &data->state.sessionage;
+  }
+
+  /* find an empty slot for us, or find the oldest */
+  for(i = 1; (i < data->set.general_ssl.max_ssl_sessions) &&
+        data->state.session[i].sessionid; i++) {
+    if(data->state.session[i].age < oldest_age) {
+      oldest_age = data->state.session[i].age;
+      store = &data->state.session[i];
+    }
+  }
+  if(i == data->set.general_ssl.max_ssl_sessions)
+    /* cache is full, we must "kill" the oldest entry! */
+    Curl_ssl_kill_session(store);
+  else
+    store = &data->state.session[i]; /* use this slot */
+
+  /* now init the session struct wisely */
+  store->sessionid = ssl_sessionid;
+  store->idsize = idsize;
+  store->age = *general_age;    /* set current age */
+  /* free it if there's one already present */
+  free(store->name);
+  free(store->conn_to_host);
+  store->name = clone_host;               /* clone host name */
+  store->conn_to_host = clone_conn_to_host; /* clone connect to host name */
+  store->conn_to_port = conn_to_port; /* connect to port number */
+  /* port number */
+  store->remote_port = isProxy ? (int)conn->port : conn->remote_port;
+  store->scheme = conn->handler->scheme;
+
+  if(!Curl_clone_primary_ssl_config(ssl_config, &store->ssl_config)) {
+    store->sessionid = NULL; /* let caller free sessionid */
+    free(clone_host);
+    free(clone_conn_to_host);
+    return CURLE_OUT_OF_MEMORY;
+  }
+
+  return CURLE_OK;
+}
+
+
+void Curl_ssl_close_all(struct Curl_easy *data)
+{
+  size_t i;
+  /* kill the session ID cache if not shared */
+  if(data->state.session && !SSLSESSION_SHARED(data)) {
+    for(i = 0; i < data->set.general_ssl.max_ssl_sessions; i++)
+      /* the single-killer function handles empty table slots */
+      Curl_ssl_kill_session(&data->state.session[i]);
+
+    /* free the cache data */
+    Curl_safefree(data->state.session);
+  }
+
+  Curl_ssl->close_all(data);
+}
+
+#if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
+  defined(USE_DARWINSSL) || defined(USE_POLARSSL) || defined(USE_NSS) || \
+  defined(USE_MBEDTLS)
+int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks,
+                     int numsocks)
+{
+  struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
+
+  if(!numsocks)
+    return GETSOCK_BLANK;
+
+  if(connssl->connecting_state == ssl_connect_2_writing) {
+    /* write mode */
+    socks[0] = conn->sock[FIRSTSOCKET];
+    return GETSOCK_WRITESOCK(0);
+  }
+  if(connssl->connecting_state == ssl_connect_2_reading) {
+    /* read mode */
+    socks[0] = conn->sock[FIRSTSOCKET];
+    return GETSOCK_READSOCK(0);
+  }
+
+  return GETSOCK_BLANK;
+}
+#else
+int Curl_ssl_getsock(struct connectdata *conn,
+                     curl_socket_t *socks,
+                     int numsocks)
+{
+  (void)conn;
+  (void)socks;
+  (void)numsocks;
+  return GETSOCK_BLANK;
+}
+/* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL || USE_DARWINSSL || USE_NSS */
+#endif
+
+void Curl_ssl_close(struct connectdata *conn, int sockindex)
+{
+  DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
+  Curl_ssl->close_one(conn, sockindex);
+}
+
+CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex)
+{
+  if(Curl_ssl->shutdown(conn, sockindex))
+    return CURLE_SSL_SHUTDOWN_FAILED;
+
+  conn->ssl[sockindex].use = FALSE; /* get back to ordinary socket usage */
+  conn->ssl[sockindex].state = ssl_connection_none;
+
+  conn->recv[sockindex] = Curl_recv_plain;
+  conn->send[sockindex] = Curl_send_plain;
+
+  return CURLE_OK;
+}
+
+/* Selects an SSL crypto engine
+ */
+CURLcode Curl_ssl_set_engine(struct Curl_easy *data, const char *engine)
+{
+  return Curl_ssl->set_engine(data, engine);
+}
+
+/* Selects the default SSL crypto engine
+ */
+CURLcode Curl_ssl_set_engine_default(struct Curl_easy *data)
+{
+  return Curl_ssl->set_engine_default(data);
+}
+
+/* Return list of OpenSSL crypto engine names. */
+struct curl_slist *Curl_ssl_engines_list(struct Curl_easy *data)
+{
+  return Curl_ssl->engines_list(data);
+}
+
+/*
+ * This sets up a session ID cache to the specified size. Make sure this code
+ * is agnostic to what underlying SSL technology we use.
+ */
+CURLcode Curl_ssl_initsessions(struct Curl_easy *data, size_t amount)
+{
+  struct curl_ssl_session *session;
+
+  if(data->state.session)
+    /* this is just a precaution to prevent multiple inits */
+    return CURLE_OK;
+
+  session = calloc(amount, sizeof(struct curl_ssl_session));
+  if(!session)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* store the info in the SSL section */
+  data->set.general_ssl.max_ssl_sessions = amount;
+  data->state.session = session;
+  data->state.sessionage = 1; /* this is brand new */
+  return CURLE_OK;
+}
+
+static size_t Curl_multissl_version(char *buffer, size_t size);
+
+size_t Curl_ssl_version(char *buffer, size_t size)
+{
+#ifdef CURL_WITH_MULTI_SSL
+  return Curl_multissl_version(buffer, size);
+#else
+  return Curl_ssl->version(buffer, size);
+#endif
+}
+
+/*
+ * This function tries to determine connection status.
+ *
+ * Return codes:
+ *     1 means the connection is still in place
+ *     0 means the connection has been closed
+ *    -1 means the connection status is unknown
+ */
+int Curl_ssl_check_cxn(struct connectdata *conn)
+{
+  return Curl_ssl->check_cxn(conn);
+}
+
+bool Curl_ssl_data_pending(const struct connectdata *conn,
+                           int connindex)
+{
+  return Curl_ssl->data_pending(conn, connindex);
+}
+
+void Curl_ssl_free_certinfo(struct Curl_easy *data)
+{
+  int i;
+  struct curl_certinfo *ci = &data->info.certs;
+
+  if(ci->num_of_certs) {
+    /* free all individual lists used */
+    for(i = 0; i<ci->num_of_certs; i++) {
+      curl_slist_free_all(ci->certinfo[i]);
+      ci->certinfo[i] = NULL;
+    }
+
+    free(ci->certinfo); /* free the actual array too */
+    ci->certinfo = NULL;
+    ci->num_of_certs = 0;
+  }
+}
+
+CURLcode Curl_ssl_init_certinfo(struct Curl_easy *data, int num)
+{
+  struct curl_certinfo *ci = &data->info.certs;
+  struct curl_slist **table;
+
+  /* Free any previous certificate information structures */
+  Curl_ssl_free_certinfo(data);
+
+  /* Allocate the required certificate information structures */
+  table = calloc((size_t) num, sizeof(struct curl_slist *));
+  if(!table)
+    return CURLE_OUT_OF_MEMORY;
+
+  ci->num_of_certs = num;
+  ci->certinfo = table;
+
+  return CURLE_OK;
+}
+
+/*
+ * 'value' is NOT a zero terminated string
+ */
+CURLcode Curl_ssl_push_certinfo_len(struct Curl_easy *data,
+                                    int certnum,
+                                    const char *label,
+                                    const char *value,
+                                    size_t valuelen)
+{
+  struct curl_certinfo *ci = &data->info.certs;
+  char *output;
+  struct curl_slist *nl;
+  CURLcode result = CURLE_OK;
+  size_t labellen = strlen(label);
+  size_t outlen = labellen + 1 + valuelen + 1; /* label:value\0 */
+
+  output = malloc(outlen);
+  if(!output)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* sprintf the label and colon */
+  snprintf(output, outlen, "%s:", label);
+
+  /* memcpy the value (it might not be zero terminated) */
+  memcpy(&output[labellen + 1], value, valuelen);
+
+  /* zero terminate the output */
+  output[labellen + 1 + valuelen] = 0;
+
+  nl = Curl_slist_append_nodup(ci->certinfo[certnum], output);
+  if(!nl) {
+    free(output);
+    curl_slist_free_all(ci->certinfo[certnum]);
+    result = CURLE_OUT_OF_MEMORY;
+  }
+
+  ci->certinfo[certnum] = nl;
+  return result;
+}
+
+/*
+ * This is a convenience function for push_certinfo_len that takes a zero
+ * terminated value.
+ */
+CURLcode Curl_ssl_push_certinfo(struct Curl_easy *data,
+                                int certnum,
+                                const char *label,
+                                const char *value)
+{
+  size_t valuelen = strlen(value);
+
+  return Curl_ssl_push_certinfo_len(data, certnum, label, value, valuelen);
+}
+
+CURLcode Curl_ssl_random(struct Curl_easy *data,
+                         unsigned char *entropy,
+                         size_t length)
+{
+  return Curl_ssl->random(data, entropy, length);
+}
+
+/*
+ * Public key pem to der conversion
+ */
+
+static CURLcode pubkey_pem_to_der(const char *pem,
+                                  unsigned char **der, size_t *der_len)
+{
+  char *stripped_pem, *begin_pos, *end_pos;
+  size_t pem_count, stripped_pem_count = 0, pem_len;
+  CURLcode result;
+
+  /* if no pem, exit. */
+  if(!pem)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  begin_pos = strstr(pem, "-----BEGIN PUBLIC KEY-----");
+  if(!begin_pos)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  pem_count = begin_pos - pem;
+  /* Invalid if not at beginning AND not directly following \n */
+  if(0 != pem_count && '\n' != pem[pem_count - 1])
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  /* 26 is length of "-----BEGIN PUBLIC KEY-----" */
+  pem_count += 26;
+
+  /* Invalid if not directly following \n */
+  end_pos = strstr(pem + pem_count, "\n-----END PUBLIC KEY-----");
+  if(!end_pos)
+    return CURLE_BAD_CONTENT_ENCODING;
+
+  pem_len = end_pos - pem;
+
+  stripped_pem = malloc(pem_len - pem_count + 1);
+  if(!stripped_pem)
+    return CURLE_OUT_OF_MEMORY;
+
+  /*
+   * Here we loop through the pem array one character at a time between the
+   * correct indices, and place each character that is not '\n' or '\r'
+   * into the stripped_pem array, which should represent the raw base64 string
+   */
+  while(pem_count < pem_len) {
+    if('\n' != pem[pem_count] && '\r' != pem[pem_count])
+      stripped_pem[stripped_pem_count++] = pem[pem_count];
+    ++pem_count;
+  }
+  /* Place the null terminator in the correct place */
+  stripped_pem[stripped_pem_count] = '\0';
+
+  result = Curl_base64_decode(stripped_pem, der, der_len);
+
+  Curl_safefree(stripped_pem);
+
+  return result;
+}
+
+/*
+ * Generic pinned public key check.
+ */
+
+CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data,
+                              const char *pinnedpubkey,
+                              const unsigned char *pubkey, size_t pubkeylen)
+{
+  FILE *fp;
+  unsigned char *buf = NULL, *pem_ptr = NULL;
+  long filesize;
+  size_t size, pem_len;
+  CURLcode pem_read;
+  CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
+  CURLcode encode;
+  size_t encodedlen, pinkeylen;
+  char *encoded, *pinkeycopy, *begin_pos, *end_pos;
+  unsigned char *sha256sumdigest = NULL;
+
+  /* if a path wasn't specified, don't pin */
+  if(!pinnedpubkey)
+    return CURLE_OK;
+  if(!pubkey || !pubkeylen)
+    return result;
+
+  /* only do this if pinnedpubkey starts with "sha256//", length 8 */
+  if(strncmp(pinnedpubkey, "sha256//", 8) == 0) {
+    if(!Curl_ssl->sha256sum) {
+      /* without sha256 support, this cannot match */
+      return result;
+    }
+
+    /* compute sha256sum of public key */
+    sha256sumdigest = malloc(CURL_SHA256_DIGEST_LENGTH);
+    if(!sha256sumdigest)
+      return CURLE_OUT_OF_MEMORY;
+    Curl_ssl->sha256sum(pubkey, pubkeylen,
+                        sha256sumdigest, CURL_SHA256_DIGEST_LENGTH);
+    encode = Curl_base64_encode(data, (char *)sha256sumdigest,
+                                CURL_SHA256_DIGEST_LENGTH, &encoded,
+                                &encodedlen);
+    Curl_safefree(sha256sumdigest);
+
+    if(encode)
+      return encode;
+
+    infof(data, "\t public key hash: sha256//%s\n", encoded);
+
+    /* it starts with sha256//, copy so we can modify it */
+    pinkeylen = strlen(pinnedpubkey) + 1;
+    pinkeycopy = malloc(pinkeylen);
+    if(!pinkeycopy) {
+      Curl_safefree(encoded);
+      return CURLE_OUT_OF_MEMORY;
+    }
+    memcpy(pinkeycopy, pinnedpubkey, pinkeylen);
+    /* point begin_pos to the copy, and start extracting keys */
+    begin_pos = pinkeycopy;
+    do {
+      end_pos = strstr(begin_pos, ";sha256//");
+      /*
+       * if there is an end_pos, null terminate,
+       * otherwise it'll go to the end of the original string
+       */
+      if(end_pos)
+        end_pos[0] = '\0';
+
+      /* compare base64 sha256 digests, 8 is the length of "sha256//" */
+      if(encodedlen == strlen(begin_pos + 8) &&
+         !memcmp(encoded, begin_pos + 8, encodedlen)) {
+        result = CURLE_OK;
+        break;
+      }
+
+      /*
+       * change back the null-terminator we changed earlier,
+       * and look for next begin
+       */
+      if(end_pos) {
+        end_pos[0] = ';';
+        begin_pos = strstr(end_pos, "sha256//");
+      }
+    } while(end_pos && begin_pos);
+    Curl_safefree(encoded);
+    Curl_safefree(pinkeycopy);
+    return result;
+  }
+
+  fp = fopen(pinnedpubkey, "rb");
+  if(!fp)
+    return result;
+
+  do {
+    /* Determine the file's size */
+    if(fseek(fp, 0, SEEK_END))
+      break;
+    filesize = ftell(fp);
+    if(fseek(fp, 0, SEEK_SET))
+      break;
+    if(filesize < 0 || filesize > MAX_PINNED_PUBKEY_SIZE)
+      break;
+
+    /*
+     * if the size of our certificate is bigger than the file
+     * size then it can't match
+     */
+    size = curlx_sotouz((curl_off_t) filesize);
+    if(pubkeylen > size)
+      break;
+
+    /*
+     * Allocate buffer for the pinned key
+     * With 1 additional byte for null terminator in case of PEM key
+     */
+    buf = malloc(size + 1);
+    if(!buf)
+      break;
+
+    /* Returns number of elements read, which should be 1 */
+    if((int) fread(buf, size, 1, fp) != 1)
+      break;
+
+    /* If the sizes are the same, it can't be base64 encoded, must be der */
+    if(pubkeylen == size) {
+      if(!memcmp(pubkey, buf, pubkeylen))
+        result = CURLE_OK;
+      break;
+    }
+
+    /*
+     * Otherwise we will assume it's PEM and try to decode it
+     * after placing null terminator
+     */
+    buf[size] = '\0';
+    pem_read = pubkey_pem_to_der((const char *)buf, &pem_ptr, &pem_len);
+    /* if it wasn't read successfully, exit */
+    if(pem_read)
+      break;
+
+    /*
+     * if the size of our certificate doesn't match the size of
+     * the decoded file, they can't be the same, otherwise compare
+     */
+    if(pubkeylen == pem_len && !memcmp(pubkey, pem_ptr, pubkeylen))
+      result = CURLE_OK;
+  } while(0);
+
+  Curl_safefree(buf);
+  Curl_safefree(pem_ptr);
+  fclose(fp);
+
+  return result;
+}
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+CURLcode Curl_ssl_md5sum(unsigned char *tmp, /* input */
+                         size_t tmplen,
+                         unsigned char *md5sum, /* output */
+                         size_t md5len)
+{
+  return Curl_ssl->md5sum(tmp, tmplen, md5sum, md5len);
+}
+#endif
+
+/*
+ * Check whether the SSL backend supports the status_request extension.
+ */
+bool Curl_ssl_cert_status_request(void)
+{
+  return Curl_ssl->cert_status_request();
+}
+
+/*
+ * Check whether the SSL backend supports false start.
+ */
+bool Curl_ssl_false_start(void)
+{
+  return Curl_ssl->false_start();
+}
+
+/*
+ * Default implementations for unsupported functions.
+ */
+
+int Curl_none_init(void)
+{
+  return 1;
+}
+
+void Curl_none_cleanup(void)
+{ }
+
+int Curl_none_shutdown(struct connectdata *conn UNUSED_PARAM,
+                       int sockindex UNUSED_PARAM)
+{
+  (void)conn;
+  (void)sockindex;
+  return 0;
+}
+
+int Curl_none_check_cxn(struct connectdata *conn UNUSED_PARAM)
+{
+  (void)conn;
+  return -1;
+}
+
+CURLcode Curl_none_random(struct Curl_easy *data UNUSED_PARAM,
+                          unsigned char *entropy UNUSED_PARAM,
+                          size_t length UNUSED_PARAM)
+{
+  (void)data;
+  (void)entropy;
+  (void)length;
+  return CURLE_NOT_BUILT_IN;
+}
+
+void Curl_none_close_all(struct Curl_easy *data UNUSED_PARAM)
+{
+  (void)data;
+}
+
+void Curl_none_session_free(void *ptr UNUSED_PARAM)
+{
+  (void)ptr;
+}
+
+bool Curl_none_data_pending(const struct connectdata *conn UNUSED_PARAM,
+                            int connindex UNUSED_PARAM)
+{
+  (void)conn;
+  (void)connindex;
+  return 0;
+}
+
+bool Curl_none_cert_status_request(void)
+{
+  return FALSE;
+}
+
+CURLcode Curl_none_set_engine(struct Curl_easy *data UNUSED_PARAM,
+                              const char *engine UNUSED_PARAM)
+{
+  (void)data;
+  (void)engine;
+  return CURLE_NOT_BUILT_IN;
+}
+
+CURLcode Curl_none_set_engine_default(struct Curl_easy *data UNUSED_PARAM)
+{
+  (void)data;
+  return CURLE_NOT_BUILT_IN;
+}
+
+struct curl_slist *Curl_none_engines_list(struct Curl_easy *data UNUSED_PARAM)
+{
+  (void)data;
+  return (struct curl_slist *)NULL;
+}
+
+bool Curl_none_false_start(void)
+{
+  return FALSE;
+}
+
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen,
+                          unsigned char *md5sum, size_t md5len UNUSED_PARAM)
+{
+  MD5_context *MD5pw;
+
+  (void)md5len;
+
+  MD5pw = Curl_MD5_init(Curl_DIGEST_MD5);
+  if(!MD5pw)
+    return CURLE_OUT_OF_MEMORY;
+  Curl_MD5_update(MD5pw, input, curlx_uztoui(inputlen));
+  Curl_MD5_final(MD5pw, md5sum);
+  return CURLE_OK;
+}
+#else
+CURLcode Curl_none_md5sum(unsigned char *input UNUSED_PARAM,
+                          size_t inputlen UNUSED_PARAM,
+                          unsigned char *md5sum UNUSED_PARAM,
+                          size_t md5len UNUSED_PARAM)
+{
+  (void)input;
+  (void)inputlen;
+  (void)md5sum;
+  (void)md5len;
+  return CURLE_NOT_BUILT_IN;
+}
+#endif
+
+static int Curl_multissl_init(void)
+{
+  if(multissl_init(NULL))
+    return 1;
+  return Curl_ssl->init();
+}
+
+static CURLcode Curl_multissl_connect(struct connectdata *conn, int sockindex)
+{
+  if(multissl_init(NULL))
+    return CURLE_FAILED_INIT;
+  return Curl_ssl->connect(conn, sockindex);
+}
+
+static CURLcode Curl_multissl_connect_nonblocking(struct connectdata *conn,
+                                                  int sockindex, bool *done)
+{
+  if(multissl_init(NULL))
+    return CURLE_FAILED_INIT;
+  return Curl_ssl->connect_nonblocking(conn, sockindex, done);
+}
+
+static void *Curl_multissl_get_internals(struct ssl_connect_data *connssl,
+                                         CURLINFO info)
+{
+  if(multissl_init(NULL))
+    return NULL;
+  return Curl_ssl->get_internals(connssl, info);
+}
+
+static void Curl_multissl_close(struct connectdata *conn, int sockindex)
+{
+  if(multissl_init(NULL))
+    return;
+  Curl_ssl->close_one(conn, sockindex);
+}
+
+static const struct Curl_ssl Curl_ssl_multi = {
+  { CURLSSLBACKEND_NONE, "multi" },  /* info */
+
+  0, /* have_ca_path */
+  0, /* have_certinfo */
+  0, /* have_pinnedpubkey */
+  0, /* have_ssl_ctx */
+  0, /* support_https_proxy */
+
+  (size_t)-1, /* something insanely large to be on the safe side */
+
+  Curl_multissl_init,                /* init */
+  Curl_none_cleanup,                 /* cleanup */
+  Curl_multissl_version,             /* version */
+  Curl_none_check_cxn,               /* check_cxn */
+  Curl_none_shutdown,                /* shutdown */
+  Curl_none_data_pending,            /* data_pending */
+  Curl_none_random,                  /* random */
+  Curl_none_cert_status_request,     /* cert_status_request */
+  Curl_multissl_connect,             /* connect */
+  Curl_multissl_connect_nonblocking, /* connect_nonblocking */
+  Curl_multissl_get_internals,       /* get_internals */
+  Curl_multissl_close,               /* close_one */
+  Curl_none_close_all,               /* close_all */
+  Curl_none_session_free,            /* session_free */
+  Curl_none_set_engine,              /* set_engine */
+  Curl_none_set_engine_default,      /* set_engine_default */
+  Curl_none_engines_list,            /* engines_list */
+  Curl_none_false_start,             /* false_start */
+  Curl_none_md5sum,                  /* md5sum */
+  NULL                               /* sha256sum */
+};
+
+const struct Curl_ssl *Curl_ssl =
+#if defined(CURL_WITH_MULTI_SSL)
+  &Curl_ssl_multi;
+#elif defined(USE_AXTLS)
+  &Curl_ssl_axtls;
+#elif defined(USE_CYASSL)
+  &Curl_ssl_cyassl;
+#elif defined(USE_DARWINSSL)
+  &Curl_ssl_darwinssl;
+#elif defined(USE_GNUTLS)
+  &Curl_ssl_gnutls;
+#elif defined(USE_GSKIT)
+  &Curl_ssl_gskit;
+#elif defined(USE_MBEDTLS)
+  &Curl_ssl_mbedtls;
+#elif defined(USE_NSS)
+  &Curl_ssl_nss;
+#elif defined(USE_OPENSSL)
+  &Curl_ssl_openssl;
+#elif defined(USE_POLARSSL)
+  &Curl_ssl_polarssl;
+#elif defined(USE_SCHANNEL)
+  &Curl_ssl_schannel;
+#else
+#error "Missing struct Curl_ssl for selected SSL backend"
+#endif
+
+static const struct Curl_ssl *available_backends[] = {
+#if defined(USE_AXTLS)
+  &Curl_ssl_axtls,
+#endif
+#if defined(USE_CYASSL)
+  &Curl_ssl_cyassl,
+#endif
+#if defined(USE_DARWINSSL)
+  &Curl_ssl_darwinssl,
+#endif
+#if defined(USE_GNUTLS)
+  &Curl_ssl_gnutls,
+#endif
+#if defined(USE_GSKIT)
+  &Curl_ssl_gskit,
+#endif
+#if defined(USE_MBEDTLS)
+  &Curl_ssl_mbedtls,
+#endif
+#if defined(USE_NSS)
+  &Curl_ssl_nss,
+#endif
+#if defined(USE_OPENSSL)
+  &Curl_ssl_openssl,
+#endif
+#if defined(USE_POLARSSL)
+  &Curl_ssl_polarssl,
+#endif
+#if defined(USE_SCHANNEL)
+  &Curl_ssl_schannel,
+#endif
+  NULL
+};
+
+static size_t Curl_multissl_version(char *buffer, size_t size)
+{
+  static const struct Curl_ssl *selected;
+  static char backends[200];
+  static size_t total;
+  const struct Curl_ssl *current;
+
+  current = Curl_ssl == &Curl_ssl_multi ? available_backends[0] : Curl_ssl;
+
+  if(current != selected) {
+    char *p = backends;
+    int i;
+
+    selected = current;
+
+    for(i = 0; available_backends[i]; i++) {
+      if(i)
+        *(p++) = ' ';
+      if(selected != available_backends[i])
+        *(p++) = '(';
+      p += available_backends[i]->version(p, backends + sizeof(backends) - p);
+      if(selected != available_backends[i])
+        *(p++) = ')';
+    }
+    *p = '\0';
+    total = p - backends;
+  }
+
+  if(size < total)
+    memcpy(buffer, backends, total + 1);
+  else {
+    memcpy(buffer, backends, size - 1);
+    buffer[size - 1] = '\0';
+  }
+
+  return total;
+}
+
+static int multissl_init(const struct Curl_ssl *backend)
+{
+  const char *env;
+  int i;
+
+  if(Curl_ssl != &Curl_ssl_multi)
+    return 1;
+
+  if(backend) {
+    Curl_ssl = backend;
+    return 0;
+  }
+
+  if(!available_backends[0])
+    return 1;
+
+  env = getenv("CURL_SSL_BACKEND");
+#ifdef CURL_DEFAULT_SSL_BACKEND
+  if(!env)
+    env = CURL_DEFAULT_SSL_BACKEND;
+#endif
+  if(env) {
+    for(i = 0; available_backends[i]; i++) {
+      if(strcasecompare(env, available_backends[i]->info.name)) {
+        Curl_ssl = available_backends[i];
+        return 0;
+      }
+    }
+  }
+
+  /* Fall back to first available backend */
+  Curl_ssl = available_backends[0];
+  return 0;
+}
+
+CURLsslset curl_global_sslset(curl_sslbackend id, const char *name,
+                              const curl_ssl_backend ***avail)
+{
+  int i;
+
+  if(Curl_ssl != &Curl_ssl_multi)
+    return id == Curl_ssl->info.id ? CURLSSLSET_OK : CURLSSLSET_TOO_LATE;
+
+  for(i = 0; available_backends[i]; i++) {
+    if(available_backends[i]->info.id == id ||
+       (name && strcasecompare(available_backends[i]->info.name, name))) {
+      multissl_init(available_backends[i]);
+      return CURLSSLSET_OK;
+    }
+  }
+
+  if(avail)
+    *avail = (const curl_ssl_backend **)&available_backends;
+  return CURLSSLSET_UNKNOWN_BACKEND;
+}
+
+#else /* USE_SSL */
+CURLsslset curl_global_sslset(curl_sslbackend id, const char *name,
+                              const curl_ssl_backend ***avail)
+{
+  (void)id;
+  (void)name;
+  (void)avail;
+  return CURLSSLSET_NO_BACKENDS;
+}
+
+#endif /* !USE_SSL */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/vtls.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/vtls.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/vtls/vtls.h	(revision 331)
@@ -0,0 +1,274 @@
+#ifndef HEADER_CURL_VTLS_H
+#define HEADER_CURL_VTLS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "curl_setup.h"
+
+struct connectdata;
+struct ssl_connect_data;
+
+struct Curl_ssl {
+  /*
+   * This *must* be the first entry to allow returning the list of available
+   * backends in curl_global_sslset().
+   */
+  curl_ssl_backend info;
+
+  unsigned have_ca_path:1;      /* supports CAPATH */
+  unsigned have_certinfo:1;     /* supports CURLOPT_CERTINFO */
+  unsigned have_pinnedpubkey:1; /* supports CURLOPT_PINNEDPUBLICKEY */
+  unsigned have_ssl_ctx:1;      /* supports CURLOPT_SSL_CTX_* */
+
+  unsigned support_https_proxy:1; /* supports access via HTTPS proxies */
+
+  size_t sizeof_ssl_backend_data;
+
+  int (*init)(void);
+  void (*cleanup)(void);
+
+  size_t (*version)(char *buffer, size_t size);
+  int (*check_cxn)(struct connectdata *cxn);
+  int (*shutdown)(struct connectdata *conn, int sockindex);
+  bool (*data_pending)(const struct connectdata *conn,
+                       int connindex);
+
+  /* return 0 if a find random is filled in */
+  CURLcode (*random)(struct Curl_easy *data, unsigned char *entropy,
+                     size_t length);
+  bool (*cert_status_request)(void);
+
+  CURLcode (*connect)(struct connectdata *conn, int sockindex);
+  CURLcode (*connect_nonblocking)(struct connectdata *conn, int sockindex,
+                                  bool *done);
+  void *(*get_internals)(struct ssl_connect_data *connssl, CURLINFO info);
+  void (*close_one)(struct connectdata *conn, int sockindex);
+  void (*close_all)(struct Curl_easy *data);
+  void (*session_free)(void *ptr);
+
+  CURLcode (*set_engine)(struct Curl_easy *data, const char *engine);
+  CURLcode (*set_engine_default)(struct Curl_easy *data);
+  struct curl_slist *(*engines_list)(struct Curl_easy *data);
+
+  bool (*false_start)(void);
+
+  CURLcode (*md5sum)(unsigned char *input, size_t inputlen,
+                     unsigned char *md5sum, size_t md5sumlen);
+  void (*sha256sum)(const unsigned char *input, size_t inputlen,
+                    unsigned char *sha256sum, size_t sha256sumlen);
+};
+
+#ifdef USE_SSL
+extern const struct Curl_ssl *Curl_ssl;
+#endif
+
+int Curl_none_init(void);
+void Curl_none_cleanup(void);
+int Curl_none_shutdown(struct connectdata *conn, int sockindex);
+int Curl_none_check_cxn(struct connectdata *conn);
+CURLcode Curl_none_random(struct Curl_easy *data, unsigned char *entropy,
+                          size_t length);
+void Curl_none_close_all(struct Curl_easy *data);
+void Curl_none_session_free(void *ptr);
+bool Curl_none_data_pending(const struct connectdata *conn, int connindex);
+bool Curl_none_cert_status_request(void);
+CURLcode Curl_none_set_engine(struct Curl_easy *data, const char *engine);
+CURLcode Curl_none_set_engine_default(struct Curl_easy *data);
+struct curl_slist *Curl_none_engines_list(struct Curl_easy *data);
+bool Curl_none_false_start(void);
+CURLcode Curl_none_md5sum(unsigned char *input, size_t inputlen,
+                          unsigned char *md5sum, size_t md5len);
+
+#include "openssl.h"        /* OpenSSL versions */
+#include "gtls.h"           /* GnuTLS versions */
+#include "nssg.h"           /* NSS versions */
+#include "gskit.h"          /* Global Secure ToolKit versions */
+#include "polarssl.h"       /* PolarSSL versions */
+#include "axtls.h"          /* axTLS versions */
+#include "cyassl.h"         /* CyaSSL versions */
+#include "schannel.h"       /* Schannel SSPI version */
+#include "darwinssl.h"      /* SecureTransport (Darwin) version */
+#include "mbedtls.h"        /* mbedTLS versions */
+
+#ifndef MAX_PINNED_PUBKEY_SIZE
+#define MAX_PINNED_PUBKEY_SIZE 1048576 /* 1MB */
+#endif
+
+#ifndef MD5_DIGEST_LENGTH
+#define MD5_DIGEST_LENGTH 16 /* fixed size */
+#endif
+
+#ifndef CURL_SHA256_DIGEST_LENGTH
+#define CURL_SHA256_DIGEST_LENGTH 32 /* fixed size */
+#endif
+
+/* see https://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-04 */
+#define ALPN_HTTP_1_1_LENGTH 8
+#define ALPN_HTTP_1_1 "http/1.1"
+
+/* set of helper macros for the backends to access the correct fields. For the
+   proxy or for the remote host - to properly support HTTPS proxy */
+
+#define SSL_IS_PROXY() (CURLPROXY_HTTPS == conn->http_proxy.proxytype && \
+  ssl_connection_complete != conn->proxy_ssl[conn->sock[SECONDARYSOCKET] == \
+  CURL_SOCKET_BAD ? FIRSTSOCKET : SECONDARYSOCKET].state)
+#define SSL_SET_OPTION(var) (SSL_IS_PROXY() ? data->set.proxy_ssl.var : \
+                             data->set.ssl.var)
+#define SSL_CONN_CONFIG(var) (SSL_IS_PROXY() ?          \
+  conn->proxy_ssl_config.var : conn->ssl_config.var)
+
+bool Curl_ssl_config_matches(struct ssl_primary_config* data,
+                             struct ssl_primary_config* needle);
+bool Curl_clone_primary_ssl_config(struct ssl_primary_config *source,
+                                   struct ssl_primary_config *dest);
+void Curl_free_primary_ssl_config(struct ssl_primary_config* sslc);
+int Curl_ssl_getsock(struct connectdata *conn, curl_socket_t *socks,
+                     int numsocks);
+
+int Curl_ssl_backend(void);
+
+#ifdef USE_SSL
+int Curl_ssl_init(void);
+void Curl_ssl_cleanup(void);
+CURLcode Curl_ssl_connect(struct connectdata *conn, int sockindex);
+CURLcode Curl_ssl_connect_nonblocking(struct connectdata *conn,
+                                      int sockindex,
+                                      bool *done);
+/* tell the SSL stuff to close down all open information regarding
+   connections (and thus session ID caching etc) */
+void Curl_ssl_close_all(struct Curl_easy *data);
+void Curl_ssl_close(struct connectdata *conn, int sockindex);
+CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex);
+CURLcode Curl_ssl_set_engine(struct Curl_easy *data, const char *engine);
+/* Sets engine as default for all SSL operations */
+CURLcode Curl_ssl_set_engine_default(struct Curl_easy *data);
+struct curl_slist *Curl_ssl_engines_list(struct Curl_easy *data);
+
+/* init the SSL session ID cache */
+CURLcode Curl_ssl_initsessions(struct Curl_easy *, size_t);
+size_t Curl_ssl_version(char *buffer, size_t size);
+bool Curl_ssl_data_pending(const struct connectdata *conn,
+                           int connindex);
+int Curl_ssl_check_cxn(struct connectdata *conn);
+
+/* Certificate information list handling. */
+
+void Curl_ssl_free_certinfo(struct Curl_easy *data);
+CURLcode Curl_ssl_init_certinfo(struct Curl_easy *data, int num);
+CURLcode Curl_ssl_push_certinfo_len(struct Curl_easy *data, int certnum,
+                                    const char *label, const char *value,
+                                    size_t valuelen);
+CURLcode Curl_ssl_push_certinfo(struct Curl_easy *data, int certnum,
+                                const char *label, const char *value);
+
+/* Functions to be used by SSL library adaptation functions */
+
+/* Lock session cache mutex.
+ * Call this before calling other Curl_ssl_*session* functions
+ * Caller should unlock this mutex as soon as possible, as it may block
+ * other SSL connection from making progress.
+ * The purpose of explicitly locking SSL session cache data is to allow
+ * individual SSL engines to manage session lifetime in their specific way.
+ */
+void Curl_ssl_sessionid_lock(struct connectdata *conn);
+
+/* Unlock session cache mutex */
+void Curl_ssl_sessionid_unlock(struct connectdata *conn);
+
+/* extract a session ID
+ * Sessionid mutex must be locked (see Curl_ssl_sessionid_lock).
+ * Caller must make sure that the ownership of returned sessionid object
+ * is properly taken (e.g. its refcount is incremented
+ * under sessionid mutex).
+ */
+bool Curl_ssl_getsessionid(struct connectdata *conn,
+                           void **ssl_sessionid,
+                           size_t *idsize, /* set 0 if unknown */
+                           int sockindex);
+/* add a new session ID
+ * Sessionid mutex must be locked (see Curl_ssl_sessionid_lock).
+ * Caller must ensure that it has properly shared ownership of this sessionid
+ * object with cache (e.g. incrementing refcount on success)
+ */
+CURLcode Curl_ssl_addsessionid(struct connectdata *conn,
+                               void *ssl_sessionid,
+                               size_t idsize,
+                               int sockindex);
+/* Kill a single session ID entry in the cache
+ * Sessionid mutex must be locked (see Curl_ssl_sessionid_lock).
+ * This will call engine-specific curlssl_session_free function, which must
+ * take sessionid object ownership from sessionid cache
+ * (e.g. decrement refcount).
+ */
+void Curl_ssl_kill_session(struct curl_ssl_session *session);
+/* delete a session from the cache
+ * Sessionid mutex must be locked (see Curl_ssl_sessionid_lock).
+ * This will call engine-specific curlssl_session_free function, which must
+ * take sessionid object ownership from sessionid cache
+ * (e.g. decrement refcount).
+ */
+void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid);
+
+/* get N random bytes into the buffer */
+CURLcode Curl_ssl_random(struct Curl_easy *data, unsigned char *buffer,
+                         size_t length);
+CURLcode Curl_ssl_md5sum(unsigned char *tmp, /* input */
+                         size_t tmplen,
+                         unsigned char *md5sum, /* output */
+                         size_t md5len);
+/* Check pinned public key. */
+CURLcode Curl_pin_peer_pubkey(struct Curl_easy *data,
+                              const char *pinnedpubkey,
+                              const unsigned char *pubkey, size_t pubkeylen);
+
+bool Curl_ssl_cert_status_request(void);
+
+bool Curl_ssl_false_start(void);
+
+#define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */
+
+#else
+
+/* When SSL support is not present, just define away these function calls */
+#define Curl_ssl_init() 1
+#define Curl_ssl_cleanup() Curl_nop_stmt
+#define Curl_ssl_connect(x,y) CURLE_NOT_BUILT_IN
+#define Curl_ssl_close_all(x) Curl_nop_stmt
+#define Curl_ssl_close(x,y) Curl_nop_stmt
+#define Curl_ssl_shutdown(x,y) CURLE_NOT_BUILT_IN
+#define Curl_ssl_set_engine(x,y) CURLE_NOT_BUILT_IN
+#define Curl_ssl_set_engine_default(x) CURLE_NOT_BUILT_IN
+#define Curl_ssl_engines_list(x) NULL
+#define Curl_ssl_send(a,b,c,d,e) -1
+#define Curl_ssl_recv(a,b,c,d,e) -1
+#define Curl_ssl_initsessions(x,y) CURLE_OK
+#define Curl_ssl_version(x,y) 0
+#define Curl_ssl_data_pending(x,y) 0
+#define Curl_ssl_check_cxn(x) 0
+#define Curl_ssl_free_certinfo(x) Curl_nop_stmt
+#define Curl_ssl_connect_nonblocking(x,y,z) CURLE_NOT_BUILT_IN
+#define Curl_ssl_kill_session(x) Curl_nop_stmt
+#define Curl_ssl_random(x,y,z) ((void)x, CURLE_NOT_BUILT_IN)
+#define Curl_ssl_cert_status_request() FALSE
+#define Curl_ssl_false_start() FALSE
+#endif
+
+#endif /* HEADER_CURL_VTLS_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/warnless.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/warnless.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/warnless.c	(revision 331)
@@ -0,0 +1,546 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(__INTEL_COMPILER) && defined(__unix__)
+
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#  include <arpa/inet.h>
+#endif
+
+#endif /* __INTEL_COMPILER && __unix__ */
+
+#define BUILDING_WARNLESS_C 1
+
+#include "warnless.h"
+
+#define CURL_MASK_SCHAR  0x7F
+#define CURL_MASK_UCHAR  0xFF
+
+#if (SIZEOF_SHORT == 2)
+#  define CURL_MASK_SSHORT  0x7FFF
+#  define CURL_MASK_USHORT  0xFFFF
+#elif (SIZEOF_SHORT == 4)
+#  define CURL_MASK_SSHORT  0x7FFFFFFF
+#  define CURL_MASK_USHORT  0xFFFFFFFF
+#elif (SIZEOF_SHORT == 8)
+#  define CURL_MASK_SSHORT  0x7FFFFFFFFFFFFFFF
+#  define CURL_MASK_USHORT  0xFFFFFFFFFFFFFFFF
+#else
+#  error "SIZEOF_SHORT not defined"
+#endif
+
+#if (SIZEOF_INT == 2)
+#  define CURL_MASK_SINT  0x7FFF
+#  define CURL_MASK_UINT  0xFFFF
+#elif (SIZEOF_INT == 4)
+#  define CURL_MASK_SINT  0x7FFFFFFF
+#  define CURL_MASK_UINT  0xFFFFFFFF
+#elif (SIZEOF_INT == 8)
+#  define CURL_MASK_SINT  0x7FFFFFFFFFFFFFFF
+#  define CURL_MASK_UINT  0xFFFFFFFFFFFFFFFF
+#elif (SIZEOF_INT == 16)
+#  define CURL_MASK_SINT  0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+#  define CURL_MASK_UINT  0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+#else
+#  error "SIZEOF_INT not defined"
+#endif
+
+#if (SIZEOF_LONG == 2)
+#  define CURL_MASK_SLONG  0x7FFFL
+#  define CURL_MASK_ULONG  0xFFFFUL
+#elif (SIZEOF_LONG == 4)
+#  define CURL_MASK_SLONG  0x7FFFFFFFL
+#  define CURL_MASK_ULONG  0xFFFFFFFFUL
+#elif (SIZEOF_LONG == 8)
+#  define CURL_MASK_SLONG  0x7FFFFFFFFFFFFFFFL
+#  define CURL_MASK_ULONG  0xFFFFFFFFFFFFFFFFUL
+#elif (SIZEOF_LONG == 16)
+#  define CURL_MASK_SLONG  0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFL
+#  define CURL_MASK_ULONG  0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFUL
+#else
+#  error "SIZEOF_LONG not defined"
+#endif
+
+#if (SIZEOF_CURL_OFF_T == 2)
+#  define CURL_MASK_SCOFFT  CURL_OFF_T_C(0x7FFF)
+#  define CURL_MASK_UCOFFT  CURL_OFF_TU_C(0xFFFF)
+#elif (SIZEOF_CURL_OFF_T == 4)
+#  define CURL_MASK_SCOFFT  CURL_OFF_T_C(0x7FFFFFFF)
+#  define CURL_MASK_UCOFFT  CURL_OFF_TU_C(0xFFFFFFFF)
+#elif (SIZEOF_CURL_OFF_T == 8)
+#  define CURL_MASK_SCOFFT  CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF)
+#  define CURL_MASK_UCOFFT  CURL_OFF_TU_C(0xFFFFFFFFFFFFFFFF)
+#elif (SIZEOF_CURL_OFF_T == 16)
+#  define CURL_MASK_SCOFFT  CURL_OFF_T_C(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
+#  define CURL_MASK_UCOFFT  CURL_OFF_TU_C(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
+#else
+#  error "SIZEOF_CURL_OFF_T not defined"
+#endif
+
+#if (SIZEOF_SIZE_T == SIZEOF_SHORT)
+#  define CURL_MASK_SSIZE_T  CURL_MASK_SSHORT
+#  define CURL_MASK_USIZE_T  CURL_MASK_USHORT
+#elif (SIZEOF_SIZE_T == SIZEOF_INT)
+#  define CURL_MASK_SSIZE_T  CURL_MASK_SINT
+#  define CURL_MASK_USIZE_T  CURL_MASK_UINT
+#elif (SIZEOF_SIZE_T == SIZEOF_LONG)
+#  define CURL_MASK_SSIZE_T  CURL_MASK_SLONG
+#  define CURL_MASK_USIZE_T  CURL_MASK_ULONG
+#elif (SIZEOF_SIZE_T == SIZEOF_CURL_OFF_T)
+#  define CURL_MASK_SSIZE_T  CURL_MASK_SCOFFT
+#  define CURL_MASK_USIZE_T  CURL_MASK_UCOFFT
+#else
+#  error "SIZEOF_SIZE_T not defined"
+#endif
+
+/*
+** unsigned long to unsigned short
+*/
+
+unsigned short curlx_ultous(unsigned long ulnum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(ulnum <= (unsigned long) CURL_MASK_USHORT);
+  return (unsigned short)(ulnum & (unsigned long) CURL_MASK_USHORT);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned long to unsigned char
+*/
+
+unsigned char curlx_ultouc(unsigned long ulnum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(ulnum <= (unsigned long) CURL_MASK_UCHAR);
+  return (unsigned char)(ulnum & (unsigned long) CURL_MASK_UCHAR);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned long to signed int
+*/
+
+int curlx_ultosi(unsigned long ulnum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(ulnum <= (unsigned long) CURL_MASK_SINT);
+  return (int)(ulnum & (unsigned long) CURL_MASK_SINT);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned size_t to signed curl_off_t
+*/
+
+curl_off_t curlx_uztoso(size_t uznum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#elif defined(_MSC_VER)
+#  pragma warning(push)
+#  pragma warning(disable:4310) /* cast truncates constant value */
+#endif
+
+  DEBUGASSERT(uznum <= (size_t) CURL_MASK_SCOFFT);
+  return (curl_off_t)(uznum & (size_t) CURL_MASK_SCOFFT);
+
+#if defined(__INTEL_COMPILER) || defined(_MSC_VER)
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned size_t to signed int
+*/
+
+int curlx_uztosi(size_t uznum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(uznum <= (size_t) CURL_MASK_SINT);
+  return (int)(uznum & (size_t) CURL_MASK_SINT);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned size_t to unsigned long
+*/
+
+unsigned long curlx_uztoul(size_t uznum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+#if (SIZEOF_LONG < SIZEOF_SIZE_T)
+  DEBUGASSERT(uznum <= (size_t) CURL_MASK_ULONG);
+#endif
+  return (unsigned long)(uznum & (size_t) CURL_MASK_ULONG);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned size_t to unsigned int
+*/
+
+unsigned int curlx_uztoui(size_t uznum)
+{
+#ifdef __INTEL_COMPILER
+# pragma warning(push)
+# pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+#if (SIZEOF_INT < SIZEOF_SIZE_T)
+  DEBUGASSERT(uznum <= (size_t) CURL_MASK_UINT);
+#endif
+  return (unsigned int)(uznum & (size_t) CURL_MASK_UINT);
+
+#ifdef __INTEL_COMPILER
+# pragma warning(pop)
+#endif
+}
+
+/*
+** signed long to signed int
+*/
+
+int curlx_sltosi(long slnum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(slnum >= 0);
+#if (SIZEOF_INT < SIZEOF_LONG)
+  DEBUGASSERT((unsigned long) slnum <= (unsigned long) CURL_MASK_SINT);
+#endif
+  return (int)(slnum & (long) CURL_MASK_SINT);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** signed long to unsigned int
+*/
+
+unsigned int curlx_sltoui(long slnum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(slnum >= 0);
+#if (SIZEOF_INT < SIZEOF_LONG)
+  DEBUGASSERT((unsigned long) slnum <= (unsigned long) CURL_MASK_UINT);
+#endif
+  return (unsigned int)(slnum & (long) CURL_MASK_UINT);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** signed long to unsigned short
+*/
+
+unsigned short curlx_sltous(long slnum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(slnum >= 0);
+  DEBUGASSERT((unsigned long) slnum <= (unsigned long) CURL_MASK_USHORT);
+  return (unsigned short)(slnum & (long) CURL_MASK_USHORT);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned size_t to signed ssize_t
+*/
+
+ssize_t curlx_uztosz(size_t uznum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(uznum <= (size_t) CURL_MASK_SSIZE_T);
+  return (ssize_t)(uznum & (size_t) CURL_MASK_SSIZE_T);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** signed curl_off_t to unsigned size_t
+*/
+
+size_t curlx_sotouz(curl_off_t sonum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(sonum >= 0);
+  return (size_t)(sonum & (curl_off_t) CURL_MASK_USIZE_T);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** signed ssize_t to signed int
+*/
+
+int curlx_sztosi(ssize_t sznum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(sznum >= 0);
+#if (SIZEOF_INT < SIZEOF_SIZE_T)
+  DEBUGASSERT((size_t) sznum <= (size_t) CURL_MASK_SINT);
+#endif
+  return (int)(sznum & (ssize_t) CURL_MASK_SINT);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned int to unsigned short
+*/
+
+unsigned short curlx_uitous(unsigned int uinum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(uinum <= (unsigned int) CURL_MASK_USHORT);
+  return (unsigned short) (uinum & (unsigned int) CURL_MASK_USHORT);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned int to unsigned char
+*/
+
+unsigned char curlx_uitouc(unsigned int uinum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(uinum <= (unsigned int) CURL_MASK_UCHAR);
+  return (unsigned char) (uinum & (unsigned int) CURL_MASK_UCHAR);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** unsigned int to signed int
+*/
+
+int curlx_uitosi(unsigned int uinum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(uinum <= (unsigned int) CURL_MASK_SINT);
+  return (int) (uinum & (unsigned int) CURL_MASK_SINT);
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+/*
+** signed int to unsigned size_t
+*/
+
+size_t curlx_sitouz(int sinum)
+{
+#ifdef __INTEL_COMPILER
+#  pragma warning(push)
+#  pragma warning(disable:810) /* conversion may lose significant bits */
+#endif
+
+  DEBUGASSERT(sinum >= 0);
+  return (size_t) sinum;
+
+#ifdef __INTEL_COMPILER
+#  pragma warning(pop)
+#endif
+}
+
+#ifdef USE_WINSOCK
+
+/*
+** curl_socket_t to signed int
+*/
+
+int curlx_sktosi(curl_socket_t s)
+{
+  return (int)((ssize_t) s);
+}
+
+/*
+** signed int to curl_socket_t
+*/
+
+curl_socket_t curlx_sitosk(int i)
+{
+  return (curl_socket_t)((ssize_t) i);
+}
+
+#endif /* USE_WINSOCK */
+
+#if defined(WIN32) || defined(_WIN32)
+
+ssize_t curlx_read(int fd, void *buf, size_t count)
+{
+  return (ssize_t)read(fd, buf, curlx_uztoui(count));
+}
+
+ssize_t curlx_write(int fd, const void *buf, size_t count)
+{
+  return (ssize_t)write(fd, buf, curlx_uztoui(count));
+}
+
+#endif /* WIN32 || _WIN32 */
+
+#if defined(__INTEL_COMPILER) && defined(__unix__)
+
+int curlx_FD_ISSET(int fd, fd_set *fdset)
+{
+  #pragma warning(push)
+  #pragma warning(disable:1469) /* clobber ignored */
+  return FD_ISSET(fd, fdset);
+  #pragma warning(pop)
+}
+
+void curlx_FD_SET(int fd, fd_set *fdset)
+{
+  #pragma warning(push)
+  #pragma warning(disable:1469) /* clobber ignored */
+  FD_SET(fd, fdset);
+  #pragma warning(pop)
+}
+
+void curlx_FD_ZERO(fd_set *fdset)
+{
+  #pragma warning(push)
+  #pragma warning(disable:593) /* variable was set but never used */
+  FD_ZERO(fdset);
+  #pragma warning(pop)
+}
+
+unsigned short curlx_htons(unsigned short usnum)
+{
+#if (__INTEL_COMPILER == 910) && defined(__i386__)
+  return (unsigned short)(((usnum << 8) & 0xFF00) | ((usnum >> 8) & 0x00FF));
+#else
+  #pragma warning(push)
+  #pragma warning(disable:810) /* conversion may lose significant bits */
+  return htons(usnum);
+  #pragma warning(pop)
+#endif
+}
+
+unsigned short curlx_ntohs(unsigned short usnum)
+{
+#if (__INTEL_COMPILER == 910) && defined(__i386__)
+  return (unsigned short)(((usnum << 8) & 0xFF00) | ((usnum >> 8) & 0x00FF));
+#else
+  #pragma warning(push)
+  #pragma warning(disable:810) /* conversion may lose significant bits */
+  return ntohs(usnum);
+  #pragma warning(pop)
+#endif
+}
+
+#endif /* __INTEL_COMPILER && __unix__ */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/warnless.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/warnless.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/warnless.h	(revision 331)
@@ -0,0 +1,113 @@
+#ifndef HEADER_CURL_WARNLESS_H
+#define HEADER_CURL_WARNLESS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#ifdef USE_WINSOCK
+#include <curl/curl.h> /* for curl_socket_t */
+#endif
+
+unsigned short curlx_ultous(unsigned long ulnum);
+
+unsigned char curlx_ultouc(unsigned long ulnum);
+
+int curlx_ultosi(unsigned long ulnum);
+
+int curlx_uztosi(size_t uznum);
+
+curl_off_t curlx_uztoso(size_t uznum);
+
+unsigned long curlx_uztoul(size_t uznum);
+
+unsigned int curlx_uztoui(size_t uznum);
+
+int curlx_sltosi(long slnum);
+
+unsigned int curlx_sltoui(long slnum);
+
+unsigned short curlx_sltous(long slnum);
+
+ssize_t curlx_uztosz(size_t uznum);
+
+size_t curlx_sotouz(curl_off_t sonum);
+
+int curlx_sztosi(ssize_t sznum);
+
+unsigned short curlx_uitous(unsigned int uinum);
+
+unsigned char curlx_uitouc(unsigned int uinum);
+
+int curlx_uitosi(unsigned int uinum);
+
+size_t curlx_sitouz(int sinum);
+
+#ifdef USE_WINSOCK
+
+int curlx_sktosi(curl_socket_t s);
+
+curl_socket_t curlx_sitosk(int i);
+
+#endif /* USE_WINSOCK */
+
+#if defined(WIN32) || defined(_WIN32)
+
+ssize_t curlx_read(int fd, void *buf, size_t count);
+
+ssize_t curlx_write(int fd, const void *buf, size_t count);
+
+#ifndef BUILDING_WARNLESS_C
+#  undef  read
+#  define read(fd, buf, count)  curlx_read(fd, buf, count)
+#  undef  write
+#  define write(fd, buf, count) curlx_write(fd, buf, count)
+#endif
+
+#endif /* WIN32 || _WIN32 */
+
+#if defined(__INTEL_COMPILER) && defined(__unix__)
+
+int curlx_FD_ISSET(int fd, fd_set *fdset);
+
+void curlx_FD_SET(int fd, fd_set *fdset);
+
+void curlx_FD_ZERO(fd_set *fdset);
+
+unsigned short curlx_htons(unsigned short usnum);
+
+unsigned short curlx_ntohs(unsigned short usnum);
+
+#ifndef BUILDING_WARNLESS_C
+#  undef  FD_ISSET
+#  define FD_ISSET(a,b) curlx_FD_ISSET((a),(b))
+#  undef  FD_SET
+#  define FD_SET(a,b)   curlx_FD_SET((a),(b))
+#  undef  FD_ZERO
+#  define FD_ZERO(a)    curlx_FD_ZERO((a))
+#  undef  htons
+#  define htons(a)      curlx_htons((a))
+#  undef  ntohs
+#  define ntohs(a)      curlx_ntohs((a))
+#endif
+
+#endif /* __INTEL_COMPILER && __unix__ */
+
+#endif /* HEADER_CURL_WARNLESS_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/wildcard.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/wildcard.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/wildcard.c	(revision 331)
@@ -0,0 +1,63 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#include "wildcard.h"
+#include "llist.h"
+#include "fileinfo.h"
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+CURLcode Curl_wildcard_init(struct WildcardData *wc)
+{
+  Curl_llist_init(&wc->filelist, Curl_fileinfo_dtor);
+  wc->state = CURLWC_INIT;
+
+  return CURLE_OK;
+}
+
+void Curl_wildcard_dtor(struct WildcardData *wc)
+{
+  if(!wc)
+    return;
+
+  if(wc->tmp_dtor) {
+    wc->tmp_dtor(wc->tmp);
+    wc->tmp_dtor = ZERO_NULL;
+    wc->tmp = NULL;
+  }
+  DEBUGASSERT(wc->tmp == NULL);
+
+  Curl_llist_destroy(&wc->filelist, NULL);
+
+
+  free(wc->path);
+  wc->path = NULL;
+  free(wc->pattern);
+  wc->pattern = NULL;
+
+  wc->customptr = NULL;
+  wc->state = CURLWC_INIT;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/wildcard.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/wildcard.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/wildcard.h	(revision 331)
@@ -0,0 +1,61 @@
+#ifndef HEADER_CURL_WILDCARD_H
+#define HEADER_CURL_WILDCARD_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2010 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include <curl/curl.h>
+
+#include "llist.h"
+
+/* list of wildcard process states */
+typedef enum {
+  CURLWC_CLEAR = 0,
+  CURLWC_INIT = 1,
+  CURLWC_MATCHING, /* library is trying to get list of addresses for
+                      downloading */
+  CURLWC_DOWNLOADING,
+  CURLWC_CLEAN, /* deallocate resources and reset settings */
+  CURLWC_SKIP,  /* skip over concrete file */
+  CURLWC_ERROR, /* error cases */
+  CURLWC_DONE   /* if is wildcard->state == CURLWC_DONE wildcard loop
+                   will end */
+} curl_wildcard_states;
+
+typedef void (*curl_wildcard_tmp_dtor)(void *ptr);
+
+/* struct keeping information about wildcard download process */
+struct WildcardData {
+  curl_wildcard_states state;
+  char *path; /* path to the directory, where we trying wildcard-match */
+  char *pattern; /* wildcard pattern */
+  struct curl_llist filelist; /* llist with struct Curl_fileinfo */
+  void *tmp; /* pointer to protocol specific temporary data */
+  curl_wildcard_tmp_dtor tmp_dtor;
+  void *customptr;  /* for CURLOPT_CHUNK_DATA pointer */
+};
+
+CURLcode Curl_wildcard_init(struct WildcardData *wc);
+void Curl_wildcard_dtor(struct WildcardData *wc);
+
+struct Curl_easy;
+
+#endif /* HEADER_CURL_WILDCARD_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/x509asn1.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/x509asn1.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/x509asn1.c	(revision 331)
@@ -0,0 +1,1200 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \
+    defined(USE_CYASSL) || defined(USE_SCHANNEL)
+
+#include <curl/curl.h>
+#include "urldata.h"
+#include "strcase.h"
+#include "hostcheck.h"
+#include "vtls/vtls.h"
+#include "sendf.h"
+#include "inet_pton.h"
+#include "curl_base64.h"
+#include "x509asn1.h"
+
+/* The last 3 #include files should be in this order */
+#include "curl_printf.h"
+#include "curl_memory.h"
+#include "memdebug.h"
+
+/* For overflow checks. */
+#define CURL_SIZE_T_MAX         ((size_t)-1)
+
+
+/* ASN.1 OIDs. */
+static const char       cnOID[] = "2.5.4.3";    /* Common name. */
+static const char       sanOID[] = "2.5.29.17"; /* Subject alternative name. */
+
+static const curl_OID   OIDtable[] = {
+  { "1.2.840.10040.4.1",        "dsa" },
+  { "1.2.840.10040.4.3",        "dsa-with-sha1" },
+  { "1.2.840.10045.2.1",        "ecPublicKey" },
+  { "1.2.840.10045.3.0.1",      "c2pnb163v1" },
+  { "1.2.840.10045.4.1",        "ecdsa-with-SHA1" },
+  { "1.2.840.10046.2.1",        "dhpublicnumber" },
+  { "1.2.840.113549.1.1.1",     "rsaEncryption" },
+  { "1.2.840.113549.1.1.2",     "md2WithRSAEncryption" },
+  { "1.2.840.113549.1.1.4",     "md5WithRSAEncryption" },
+  { "1.2.840.113549.1.1.5",     "sha1WithRSAEncryption" },
+  { "1.2.840.113549.1.1.10",    "RSASSA-PSS" },
+  { "1.2.840.113549.1.1.14",    "sha224WithRSAEncryption" },
+  { "1.2.840.113549.1.1.11",    "sha256WithRSAEncryption" },
+  { "1.2.840.113549.1.1.12",    "sha384WithRSAEncryption" },
+  { "1.2.840.113549.1.1.13",    "sha512WithRSAEncryption" },
+  { "1.2.840.113549.2.2",       "md2" },
+  { "1.2.840.113549.2.5",       "md5" },
+  { "1.3.14.3.2.26",            "sha1" },
+  { cnOID,                      "CN" },
+  { "2.5.4.4",                  "SN" },
+  { "2.5.4.5",                  "serialNumber" },
+  { "2.5.4.6",                  "C" },
+  { "2.5.4.7",                  "L" },
+  { "2.5.4.8",                  "ST" },
+  { "2.5.4.9",                  "streetAddress" },
+  { "2.5.4.10",                 "O" },
+  { "2.5.4.11",                 "OU" },
+  { "2.5.4.12",                 "title" },
+  { "2.5.4.13",                 "description" },
+  { "2.5.4.17",                 "postalCode" },
+  { "2.5.4.41",                 "name" },
+  { "2.5.4.42",                 "givenName" },
+  { "2.5.4.43",                 "initials" },
+  { "2.5.4.44",                 "generationQualifier" },
+  { "2.5.4.45",                 "X500UniqueIdentifier" },
+  { "2.5.4.46",                 "dnQualifier" },
+  { "2.5.4.65",                 "pseudonym" },
+  { "1.2.840.113549.1.9.1",     "emailAddress" },
+  { "2.5.4.72",                 "role" },
+  { sanOID,                     "subjectAltName" },
+  { "2.5.29.18",                "issuerAltName" },
+  { "2.5.29.19",                "basicConstraints" },
+  { "2.16.840.1.101.3.4.2.4",   "sha224" },
+  { "2.16.840.1.101.3.4.2.1",   "sha256" },
+  { "2.16.840.1.101.3.4.2.2",   "sha384" },
+  { "2.16.840.1.101.3.4.2.3",   "sha512" },
+  { (const char *) NULL,        (const char *) NULL }
+};
+
+/*
+ * Lightweight ASN.1 parser.
+ * In particular, it does not check for syntactic/lexical errors.
+ * It is intended to support certificate information gathering for SSL backends
+ * that offer a mean to get certificates as a whole, but do not supply
+ * entry points to get particular certificate sub-fields.
+ * Please note there is no pretention here to rewrite a full SSL library.
+ */
+
+
+const char *Curl_getASN1Element(curl_asn1Element *elem,
+                                const char *beg, const char *end)
+{
+  unsigned char b;
+  unsigned long len;
+  curl_asn1Element lelem;
+
+  /* Get a single ASN.1 element into `elem', parse ASN.1 string at `beg'
+     ending at `end'.
+     Returns a pointer in source string after the parsed element, or NULL
+     if an error occurs. */
+  if(!beg || !end || beg >= end || !*beg ||
+     (size_t)(end - beg) > CURL_ASN1_MAX)
+    return (const char *) NULL;
+
+  /* Process header byte. */
+  elem->header = beg;
+  b = (unsigned char) *beg++;
+  elem->constructed = (b & 0x20) != 0;
+  elem->class = (b >> 6) & 3;
+  b &= 0x1F;
+  if(b == 0x1F)
+    return (const char *) NULL; /* Long tag values not supported here. */
+  elem->tag = b;
+
+  /* Process length. */
+  if(beg >= end)
+    return (const char *) NULL;
+  b = (unsigned char) *beg++;
+  if(!(b & 0x80))
+    len = b;
+  else if(!(b &= 0x7F)) {
+    /* Unspecified length. Since we have all the data, we can determine the
+       effective length by skipping element until an end element is found. */
+    if(!elem->constructed)
+      return (const char *) NULL;
+    elem->beg = beg;
+    while(beg < end && *beg) {
+      beg = Curl_getASN1Element(&lelem, beg, end);
+      if(!beg)
+        return (const char *) NULL;
+    }
+    if(beg >= end)
+      return (const char *) NULL;
+    elem->end = beg;
+    return beg + 1;
+  }
+  else if((unsigned)b > (size_t)(end - beg))
+    return (const char *) NULL; /* Does not fit in source. */
+  else {
+    /* Get long length. */
+    len = 0;
+    do {
+      if(len & 0xFF000000L)
+        return (const char *) NULL;  /* Lengths > 32 bits are not supported. */
+      len = (len << 8) | (unsigned char) *beg++;
+    } while(--b);
+  }
+  if(len > (size_t)(end - beg))
+    return (const char *) NULL;  /* Element data does not fit in source. */
+  elem->beg = beg;
+  elem->end = beg + len;
+  return elem->end;
+}
+
+static const curl_OID * searchOID(const char *oid)
+{
+  const curl_OID *op;
+
+  /* Search the null terminated OID or OID identifier in local table.
+     Return the table entry pointer or NULL if not found. */
+
+  for(op = OIDtable; op->numoid; op++)
+    if(!strcmp(op->numoid, oid) || strcasecompare(op->textoid, oid))
+      return op;
+
+  return (const curl_OID *) NULL;
+}
+
+static const char *bool2str(const char *beg, const char *end)
+{
+  /* Convert an ASN.1 Boolean value into its string representation.
+     Return the dynamically allocated string, or NULL if source is not an
+     ASN.1 Boolean value. */
+
+  if(end - beg != 1)
+    return (const char *) NULL;
+  return strdup(*beg? "TRUE": "FALSE");
+}
+
+static const char *octet2str(const char *beg, const char *end)
+{
+  size_t n = end - beg;
+  char *buf = NULL;
+
+  /* Convert an ASN.1 octet string to a printable string.
+     Return the dynamically allocated string, or NULL if an error occurs. */
+
+  if(n <= (CURL_SIZE_T_MAX - 1) / 3) {
+    buf = malloc(3 * n + 1);
+    if(buf)
+      for(n = 0; beg < end; n += 3)
+        snprintf(buf + n, 4, "%02x:", *(const unsigned char *) beg++);
+  }
+  return buf;
+}
+
+static const char *bit2str(const char *beg, const char *end)
+{
+  /* Convert an ASN.1 bit string to a printable string.
+     Return the dynamically allocated string, or NULL if an error occurs. */
+
+  if(++beg > end)
+    return (const char *) NULL;
+  return octet2str(beg, end);
+}
+
+static const char *int2str(const char *beg, const char *end)
+{
+  long val = 0;
+  size_t n = end - beg;
+
+  /* Convert an ASN.1 integer value into its string representation.
+     Return the dynamically allocated string, or NULL if source is not an
+     ASN.1 integer value. */
+
+  if(!n)
+    return (const char *) NULL;
+
+  if(n > 4)
+    return octet2str(beg, end);
+
+  /* Represent integers <= 32-bit as a single value. */
+  if(*beg & 0x80)
+    val = ~val;
+
+  do
+    val = (val << 8) | *(const unsigned char *) beg++;
+  while(beg < end);
+  return curl_maprintf("%s%lx", (val < 0 || val >= 10)? "0x": "", val);
+}
+
+static ssize_t
+utf8asn1str(char **to, int type, const char *from, const char *end)
+{
+  size_t inlength = end - from;
+  int size = 1;
+  size_t outlength;
+  int charsize;
+  unsigned int wc;
+  char *buf;
+
+  /* Perform a lazy conversion from an ASN.1 typed string to UTF8. Allocate the
+     destination buffer dynamically. The allocation size will normally be too
+     large: this is to avoid buffer overflows.
+     Terminate the string with a nul byte and return the converted
+     string length. */
+
+  *to = (char *) NULL;
+  switch(type) {
+  case CURL_ASN1_BMP_STRING:
+    size = 2;
+    break;
+  case CURL_ASN1_UNIVERSAL_STRING:
+    size = 4;
+    break;
+  case CURL_ASN1_NUMERIC_STRING:
+  case CURL_ASN1_PRINTABLE_STRING:
+  case CURL_ASN1_TELETEX_STRING:
+  case CURL_ASN1_IA5_STRING:
+  case CURL_ASN1_VISIBLE_STRING:
+  case CURL_ASN1_UTF8_STRING:
+    break;
+  default:
+    return -1;  /* Conversion not supported. */
+  }
+
+  if(inlength % size)
+    return -1;  /* Length inconsistent with character size. */
+  if(inlength / size > (CURL_SIZE_T_MAX - 1) / 4)
+    return -1;  /* Too big. */
+  buf = malloc(4 * (inlength / size) + 1);
+  if(!buf)
+    return -1;  /* Not enough memory. */
+
+  if(type == CURL_ASN1_UTF8_STRING) {
+    /* Just copy. */
+    outlength = inlength;
+    if(outlength)
+      memcpy(buf, from, outlength);
+  }
+  else {
+    for(outlength = 0; from < end;) {
+      wc = 0;
+      switch(size) {
+      case 4:
+        wc = (wc << 8) | *(const unsigned char *) from++;
+        wc = (wc << 8) | *(const unsigned char *) from++;
+        /* fallthrough */
+      case 2:
+        wc = (wc << 8) | *(const unsigned char *) from++;
+        /* fallthrough */
+      default: /* case 1: */
+        wc = (wc << 8) | *(const unsigned char *) from++;
+      }
+      charsize = 1;
+      if(wc >= 0x00000080) {
+        if(wc >= 0x00000800) {
+          if(wc >= 0x00010000) {
+            if(wc >= 0x00200000) {
+              free(buf);
+              return -1;        /* Invalid char. size for target encoding. */
+            }
+            buf[outlength + 3] = (char) (0x80 | (wc & 0x3F));
+            wc = (wc >> 6) | 0x00010000;
+            charsize++;
+          }
+          buf[outlength + 2] = (char) (0x80 | (wc & 0x3F));
+          wc = (wc >> 6) | 0x00000800;
+          charsize++;
+        }
+        buf[outlength + 1] = (char) (0x80 | (wc & 0x3F));
+        wc = (wc >> 6) | 0x000000C0;
+        charsize++;
+      }
+      buf[outlength] = (char) wc;
+      outlength += charsize;
+    }
+  }
+  buf[outlength] = '\0';
+  *to = buf;
+  return outlength;
+}
+
+static const char *string2str(int type, const char *beg, const char *end)
+{
+  char *buf;
+
+  /* Convert an ASN.1 String into its UTF-8 string representation.
+     Return the dynamically allocated string, or NULL if an error occurs. */
+
+  if(utf8asn1str(&buf, type, beg, end) < 0)
+    return (const char *) NULL;
+  return buf;
+}
+
+static int encodeUint(char *buf, int n, unsigned int x)
+{
+  int i = 0;
+  unsigned int y = x / 10;
+
+  /* Decimal ASCII encode unsigned integer `x' in the `n'-byte buffer at `buf'.
+     Return the total number of encoded digits, even if larger than `n'. */
+
+  if(y) {
+    i += encodeUint(buf, n, y);
+    x -= y * 10;
+  }
+  if(i < n)
+    buf[i] = (char) ('0' + x);
+  i++;
+  if(i < n)
+    buf[i] = '\0';      /* Store a terminator if possible. */
+  return i;
+}
+
+static int encodeOID(char *buf, int n, const char *beg, const char *end)
+{
+  int i = 0;
+  unsigned int x;
+  unsigned int y;
+
+  /* Convert an ASN.1 OID into its dotted string representation.
+     Store the result in th `n'-byte buffer at `buf'.
+     Return the converted string length, or -1 if an error occurs. */
+
+  /* Process the first two numbers. */
+  y = *(const unsigned char *) beg++;
+  x = y / 40;
+  y -= x * 40;
+  i += encodeUint(buf + i, n - i, x);
+  if(i < n)
+    buf[i] = '.';
+  i++;
+  i += encodeUint(buf + i, n - i, y);
+
+  /* Process the trailing numbers. */
+  while(beg < end) {
+    if(i < n)
+      buf[i] = '.';
+    i++;
+    x = 0;
+    do {
+      if(x & 0xFF000000)
+        return -1;
+      y = *(const unsigned char *) beg++;
+      x = (x << 7) | (y & 0x7F);
+    } while(y & 0x80);
+    i += encodeUint(buf + i, n - i, x);
+  }
+  if(i < n)
+    buf[i] = '\0';
+  return i;
+}
+
+static const char *OID2str(const char *beg, const char *end, bool symbolic)
+{
+  char *buf = (char *) NULL;
+  const curl_OID * op;
+  int n;
+
+  /* Convert an ASN.1 OID into its dotted or symbolic string representation.
+     Return the dynamically allocated string, or NULL if an error occurs. */
+
+  if(beg < end) {
+    n = encodeOID((char *) NULL, -1, beg, end);
+    if(n >= 0) {
+      buf = malloc(n + 1);
+      if(buf) {
+        encodeOID(buf, n, beg, end);
+        buf[n] = '\0';
+
+        if(symbolic) {
+          op = searchOID(buf);
+          if(op) {
+            free(buf);
+            buf = strdup(op->textoid);
+          }
+        }
+      }
+    }
+  }
+  return buf;
+}
+
+static const char *GTime2str(const char *beg, const char *end)
+{
+  const char *tzp;
+  const char *fracp;
+  char sec1, sec2;
+  size_t fracl;
+  size_t tzl;
+  const char *sep = "";
+
+  /* Convert an ASN.1 Generalized time to a printable string.
+     Return the dynamically allocated string, or NULL if an error occurs. */
+
+  for(fracp = beg; fracp < end && *fracp >= '0' && *fracp <= '9'; fracp++)
+    ;
+
+  /* Get seconds digits. */
+  sec1 = '0';
+  switch(fracp - beg - 12) {
+  case 0:
+    sec2 = '0';
+    break;
+  case 2:
+    sec1 = fracp[-2];
+    /* FALLTHROUGH */
+  case 1:
+    sec2 = fracp[-1];
+    break;
+  default:
+    return (const char *) NULL;
+  }
+
+  /* Scan for timezone, measure fractional seconds. */
+  tzp = fracp;
+  fracl = 0;
+  if(fracp < end && (*fracp == '.' || *fracp == ',')) {
+    fracp++;
+    do
+      tzp++;
+    while(tzp < end && *tzp >= '0' && *tzp <= '9');
+    /* Strip leading zeroes in fractional seconds. */
+    for(fracl = tzp - fracp - 1; fracl && fracp[fracl - 1] == '0'; fracl--)
+      ;
+  }
+
+  /* Process timezone. */
+  if(tzp >= end)
+    ;           /* Nothing to do. */
+  else if(*tzp == 'Z') {
+    tzp = " GMT";
+    end = tzp + 4;
+  }
+  else {
+    sep = " ";
+    tzp++;
+  }
+
+  tzl = end - tzp;
+  return curl_maprintf("%.4s-%.2s-%.2s %.2s:%.2s:%c%c%s%.*s%s%.*s",
+                       beg, beg + 4, beg + 6,
+                       beg + 8, beg + 10, sec1, sec2,
+                       fracl? ".": "", fracl, fracp,
+                       sep, tzl, tzp);
+}
+
+static const char *UTime2str(const char *beg, const char *end)
+{
+  const char *tzp;
+  size_t tzl;
+  const char *sec;
+
+  /* Convert an ASN.1 UTC time to a printable string.
+     Return the dynamically allocated string, or NULL if an error occurs. */
+
+  for(tzp = beg; tzp < end && *tzp >= '0' && *tzp <= '9'; tzp++)
+    ;
+  /* Get the seconds. */
+  sec = beg + 10;
+  switch(tzp - sec) {
+  case 0:
+    sec = "00";
+  case 2:
+    break;
+  default:
+    return (const char *) NULL;
+  }
+
+  /* Process timezone. */
+  if(tzp >= end)
+    return (const char *) NULL;
+  if(*tzp == 'Z') {
+    tzp = "GMT";
+    end = tzp + 3;
+  }
+  else
+    tzp++;
+
+  tzl = end - tzp;
+  return curl_maprintf("%u%.2s-%.2s-%.2s %.2s:%.2s:%.2s %.*s",
+                       20 - (*beg >= '5'), beg, beg + 2, beg + 4,
+                       beg + 6, beg + 8, sec,
+                       tzl, tzp);
+}
+
+const char *Curl_ASN1tostr(curl_asn1Element *elem, int type)
+{
+  /* Convert an ASN.1 element to a printable string.
+     Return the dynamically allocated string, or NULL if an error occurs. */
+
+  if(elem->constructed)
+    return (const char *) NULL; /* No conversion of structured elements. */
+
+  if(!type)
+    type = elem->tag;   /* Type not forced: use element tag as type. */
+
+  switch(type) {
+  case CURL_ASN1_BOOLEAN:
+    return bool2str(elem->beg, elem->end);
+  case CURL_ASN1_INTEGER:
+  case CURL_ASN1_ENUMERATED:
+    return int2str(elem->beg, elem->end);
+  case CURL_ASN1_BIT_STRING:
+    return bit2str(elem->beg, elem->end);
+  case CURL_ASN1_OCTET_STRING:
+    return octet2str(elem->beg, elem->end);
+  case CURL_ASN1_NULL:
+    return strdup("");
+  case CURL_ASN1_OBJECT_IDENTIFIER:
+    return OID2str(elem->beg, elem->end, TRUE);
+  case CURL_ASN1_UTC_TIME:
+    return UTime2str(elem->beg, elem->end);
+  case CURL_ASN1_GENERALIZED_TIME:
+    return GTime2str(elem->beg, elem->end);
+  case CURL_ASN1_UTF8_STRING:
+  case CURL_ASN1_NUMERIC_STRING:
+  case CURL_ASN1_PRINTABLE_STRING:
+  case CURL_ASN1_TELETEX_STRING:
+  case CURL_ASN1_IA5_STRING:
+  case CURL_ASN1_VISIBLE_STRING:
+  case CURL_ASN1_UNIVERSAL_STRING:
+  case CURL_ASN1_BMP_STRING:
+    return string2str(type, elem->beg, elem->end);
+  }
+
+  return (const char *) NULL;   /* Unsupported. */
+}
+
+static ssize_t encodeDN(char *buf, size_t n, curl_asn1Element *dn)
+{
+  curl_asn1Element rdn;
+  curl_asn1Element atv;
+  curl_asn1Element oid;
+  curl_asn1Element value;
+  size_t l = 0;
+  const char *p1;
+  const char *p2;
+  const char *p3;
+  const char *str;
+
+  /* ASCII encode distinguished name at `dn' into the `n'-byte buffer at `buf'.
+     Return the total string length, even if larger than `n'. */
+
+  for(p1 = dn->beg; p1 < dn->end;) {
+    p1 = Curl_getASN1Element(&rdn, p1, dn->end);
+    for(p2 = rdn.beg; p2 < rdn.end;) {
+      p2 = Curl_getASN1Element(&atv, p2, rdn.end);
+      p3 = Curl_getASN1Element(&oid, atv.beg, atv.end);
+      Curl_getASN1Element(&value, p3, atv.end);
+      str = Curl_ASN1tostr(&oid, 0);
+      if(!str)
+        return -1;
+
+      /* Encode delimiter.
+         If attribute has a short uppercase name, delimiter is ", ". */
+      if(l) {
+        for(p3 = str; isupper(*p3); p3++)
+          ;
+        for(p3 = (*p3 || p3 - str > 2)? "/": ", "; *p3; p3++) {
+          if(l < n)
+            buf[l] = *p3;
+          l++;
+        }
+      }
+
+      /* Encode attribute name. */
+      for(p3 = str; *p3; p3++) {
+        if(l < n)
+          buf[l] = *p3;
+        l++;
+      }
+      free((char *) str);
+
+      /* Generate equal sign. */
+      if(l < n)
+        buf[l] = '=';
+      l++;
+
+      /* Generate value. */
+      str = Curl_ASN1tostr(&value, 0);
+      if(!str)
+        return -1;
+      for(p3 = str; *p3; p3++) {
+        if(l < n)
+          buf[l] = *p3;
+        l++;
+      }
+      free((char *) str);
+    }
+  }
+
+  return l;
+}
+
+const char *Curl_DNtostr(curl_asn1Element *dn)
+{
+  char *buf = (char *) NULL;
+  ssize_t n = encodeDN(buf, 0, dn);
+
+  /* Convert an ASN.1 distinguished name into a printable string.
+     Return the dynamically allocated string, or NULL if an error occurs. */
+
+  if(n >= 0) {
+    buf = malloc(n + 1);
+    if(buf) {
+      encodeDN(buf, n + 1, dn);
+      buf[n] = '\0';
+    }
+  }
+  return (const char *) buf;
+}
+
+/*
+ * X509 parser.
+ */
+
+int Curl_parseX509(curl_X509certificate *cert,
+                   const char *beg, const char *end)
+{
+  curl_asn1Element elem;
+  curl_asn1Element tbsCertificate;
+  const char *ccp;
+  static const char defaultVersion = 0;  /* v1. */
+
+  /* ASN.1 parse an X509 certificate into structure subfields.
+     Syntax is assumed to have already been checked by the SSL backend.
+     See RFC 5280. */
+
+  cert->certificate.header = NULL;
+  cert->certificate.beg = beg;
+  cert->certificate.end = end;
+
+  /* Get the sequence content. */
+  if(!Curl_getASN1Element(&elem, beg, end))
+    return -1;  /* Invalid bounds/size. */
+  beg = elem.beg;
+  end = elem.end;
+
+  /* Get tbsCertificate. */
+  beg = Curl_getASN1Element(&tbsCertificate, beg, end);
+  /* Skip the signatureAlgorithm. */
+  beg = Curl_getASN1Element(&cert->signatureAlgorithm, beg, end);
+  /* Get the signatureValue. */
+  Curl_getASN1Element(&cert->signature, beg, end);
+
+  /* Parse TBSCertificate. */
+  beg = tbsCertificate.beg;
+  end = tbsCertificate.end;
+  /* Get optional version, get serialNumber. */
+  cert->version.header = NULL;
+  cert->version.beg = &defaultVersion;
+  cert->version.end = &defaultVersion + sizeof defaultVersion;;
+  beg = Curl_getASN1Element(&elem, beg, end);
+  if(elem.tag == 0) {
+    Curl_getASN1Element(&cert->version, elem.beg, elem.end);
+    beg = Curl_getASN1Element(&elem, beg, end);
+  }
+  cert->serialNumber = elem;
+  /* Get signature algorithm. */
+  beg = Curl_getASN1Element(&cert->signatureAlgorithm, beg, end);
+  /* Get issuer. */
+  beg = Curl_getASN1Element(&cert->issuer, beg, end);
+  /* Get notBefore and notAfter. */
+  beg = Curl_getASN1Element(&elem, beg, end);
+  ccp = Curl_getASN1Element(&cert->notBefore, elem.beg, elem.end);
+  Curl_getASN1Element(&cert->notAfter, ccp, elem.end);
+  /* Get subject. */
+  beg = Curl_getASN1Element(&cert->subject, beg, end);
+  /* Get subjectPublicKeyAlgorithm and subjectPublicKey. */
+  beg = Curl_getASN1Element(&cert->subjectPublicKeyInfo, beg, end);
+  ccp = Curl_getASN1Element(&cert->subjectPublicKeyAlgorithm,
+                            cert->subjectPublicKeyInfo.beg,
+                            cert->subjectPublicKeyInfo.end);
+  Curl_getASN1Element(&cert->subjectPublicKey, ccp,
+                      cert->subjectPublicKeyInfo.end);
+  /* Get optional issuerUiqueID, subjectUniqueID and extensions. */
+  cert->issuerUniqueID.tag = cert->subjectUniqueID.tag = 0;
+  cert->extensions.tag = elem.tag = 0;
+  cert->issuerUniqueID.header = cert->subjectUniqueID.header = NULL;
+  cert->issuerUniqueID.beg = cert->issuerUniqueID.end = "";
+  cert->subjectUniqueID.beg = cert->subjectUniqueID.end = "";
+  cert->extensions.header = NULL;
+  cert->extensions.beg = cert->extensions.end = "";
+  if(beg < end)
+    beg = Curl_getASN1Element(&elem, beg, end);
+  if(elem.tag == 1) {
+    cert->issuerUniqueID = elem;
+    if(beg < end)
+      beg = Curl_getASN1Element(&elem, beg, end);
+  }
+  if(elem.tag == 2) {
+    cert->subjectUniqueID = elem;
+    if(beg < end)
+      beg = Curl_getASN1Element(&elem, beg, end);
+  }
+  if(elem.tag == 3)
+    Curl_getASN1Element(&cert->extensions, elem.beg, elem.end);
+  return 0;
+}
+
+static size_t copySubstring(char *to, const char *from)
+{
+  size_t i;
+
+  /* Copy at most 64-characters, terminate with a newline and returns the
+     effective number of stored characters. */
+
+  for(i = 0; i < 64; i++) {
+    to[i] = *from;
+    if(!*from++)
+      break;
+  }
+
+  to[i++] = '\n';
+  return i;
+}
+
+static const char *dumpAlgo(curl_asn1Element *param,
+                            const char *beg, const char *end)
+{
+  curl_asn1Element oid;
+
+  /* Get algorithm parameters and return algorithm name. */
+
+  beg = Curl_getASN1Element(&oid, beg, end);
+  param->header = NULL;
+  param->tag = 0;
+  param->beg = param->end = end;
+  if(beg < end)
+    Curl_getASN1Element(param, beg, end);
+  return OID2str(oid.beg, oid.end, TRUE);
+}
+
+static void do_pubkey_field(struct Curl_easy *data, int certnum,
+                            const char *label, curl_asn1Element *elem)
+{
+  const char *output;
+
+  /* Generate a certificate information record for the public key. */
+
+  output = Curl_ASN1tostr(elem, 0);
+  if(output) {
+    if(data->set.ssl.certinfo)
+      Curl_ssl_push_certinfo(data, certnum, label, output);
+    if(!certnum)
+      infof(data, "   %s: %s\n", label, output);
+    free((char *) output);
+  }
+}
+
+static void do_pubkey(struct Curl_easy *data, int certnum,
+                      const char *algo, curl_asn1Element *param,
+                      curl_asn1Element *pubkey)
+{
+  curl_asn1Element elem;
+  curl_asn1Element pk;
+  const char *p;
+  const char *q;
+  unsigned long len;
+  unsigned int i;
+
+  /* Generate all information records for the public key. */
+
+  /* Get the public key (single element). */
+  Curl_getASN1Element(&pk, pubkey->beg + 1, pubkey->end);
+
+  if(strcasecompare(algo, "rsaEncryption")) {
+    p = Curl_getASN1Element(&elem, pk.beg, pk.end);
+    /* Compute key length. */
+    for(q = elem.beg; !*q && q < elem.end; q++)
+      ;
+    len = (unsigned long)((elem.end - q) * 8);
+    if(len)
+      for(i = *(unsigned char *) q; !(i & 0x80); i <<= 1)
+        len--;
+    if(len > 32)
+      elem.beg = q;     /* Strip leading zero bytes. */
+    if(!certnum)
+      infof(data, "   RSA Public Key (%lu bits)\n", len);
+    if(data->set.ssl.certinfo) {
+      q = curl_maprintf("%lu", len);
+      if(q) {
+        Curl_ssl_push_certinfo(data, certnum, "RSA Public Key", q);
+        free((char *) q);
+      }
+    }
+    /* Generate coefficients. */
+    do_pubkey_field(data, certnum, "rsa(n)", &elem);
+    Curl_getASN1Element(&elem, p, pk.end);
+    do_pubkey_field(data, certnum, "rsa(e)", &elem);
+  }
+  else if(strcasecompare(algo, "dsa")) {
+    p = Curl_getASN1Element(&elem, param->beg, param->end);
+    do_pubkey_field(data, certnum, "dsa(p)", &elem);
+    p = Curl_getASN1Element(&elem, p, param->end);
+    do_pubkey_field(data, certnum, "dsa(q)", &elem);
+    Curl_getASN1Element(&elem, p, param->end);
+    do_pubkey_field(data, certnum, "dsa(g)", &elem);
+    do_pubkey_field(data, certnum, "dsa(pub_key)", &pk);
+  }
+  else if(strcasecompare(algo, "dhpublicnumber")) {
+    p = Curl_getASN1Element(&elem, param->beg, param->end);
+    do_pubkey_field(data, certnum, "dh(p)", &elem);
+    Curl_getASN1Element(&elem, param->beg, param->end);
+    do_pubkey_field(data, certnum, "dh(g)", &elem);
+    do_pubkey_field(data, certnum, "dh(pub_key)", &pk);
+  }
+#if 0 /* Patent-encumbered. */
+  else if(strcasecompare(algo, "ecPublicKey")) {
+    /* Left TODO. */
+  }
+#endif
+}
+
+CURLcode Curl_extract_certinfo(struct connectdata *conn,
+                               int certnum,
+                               const char *beg,
+                               const char *end)
+{
+  curl_X509certificate cert;
+  struct Curl_easy *data = conn->data;
+  curl_asn1Element param;
+  const char *ccp;
+  char *cp1;
+  size_t cl1;
+  char *cp2;
+  CURLcode result;
+  unsigned long version;
+  size_t i;
+  size_t j;
+
+  if(!data->set.ssl.certinfo)
+    if(certnum)
+      return CURLE_OK;
+
+  /* Prepare the certificate information for curl_easy_getinfo(). */
+
+  /* Extract the certificate ASN.1 elements. */
+  if(Curl_parseX509(&cert, beg, end))
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Subject. */
+  ccp = Curl_DNtostr(&cert.subject);
+  if(!ccp)
+    return CURLE_OUT_OF_MEMORY;
+  if(data->set.ssl.certinfo)
+    Curl_ssl_push_certinfo(data, certnum, "Subject", ccp);
+  if(!certnum)
+    infof(data, "%2d Subject: %s\n", certnum, ccp);
+  free((char *) ccp);
+
+  /* Issuer. */
+  ccp = Curl_DNtostr(&cert.issuer);
+  if(!ccp)
+    return CURLE_OUT_OF_MEMORY;
+  if(data->set.ssl.certinfo)
+    Curl_ssl_push_certinfo(data, certnum, "Issuer", ccp);
+  if(!certnum)
+    infof(data, "   Issuer: %s\n", ccp);
+  free((char *) ccp);
+
+  /* Version (always fits in less than 32 bits). */
+  version = 0;
+  for(ccp = cert.version.beg; ccp < cert.version.end; ccp++)
+    version = (version << 8) | *(const unsigned char *) ccp;
+  if(data->set.ssl.certinfo) {
+    ccp = curl_maprintf("%lx", version);
+    if(!ccp)
+      return CURLE_OUT_OF_MEMORY;
+    Curl_ssl_push_certinfo(data, certnum, "Version", ccp);
+    free((char *) ccp);
+  }
+  if(!certnum)
+    infof(data, "   Version: %lu (0x%lx)\n", version + 1, version);
+
+  /* Serial number. */
+  ccp = Curl_ASN1tostr(&cert.serialNumber, 0);
+  if(!ccp)
+    return CURLE_OUT_OF_MEMORY;
+  if(data->set.ssl.certinfo)
+    Curl_ssl_push_certinfo(data, certnum, "Serial Number", ccp);
+  if(!certnum)
+    infof(data, "   Serial Number: %s\n", ccp);
+  free((char *) ccp);
+
+  /* Signature algorithm .*/
+  ccp = dumpAlgo(&param, cert.signatureAlgorithm.beg,
+                 cert.signatureAlgorithm.end);
+  if(!ccp)
+    return CURLE_OUT_OF_MEMORY;
+  if(data->set.ssl.certinfo)
+    Curl_ssl_push_certinfo(data, certnum, "Signature Algorithm", ccp);
+  if(!certnum)
+    infof(data, "   Signature Algorithm: %s\n", ccp);
+  free((char *) ccp);
+
+  /* Start Date. */
+  ccp = Curl_ASN1tostr(&cert.notBefore, 0);
+  if(!ccp)
+    return CURLE_OUT_OF_MEMORY;
+  if(data->set.ssl.certinfo)
+    Curl_ssl_push_certinfo(data, certnum, "Start Date", ccp);
+  if(!certnum)
+    infof(data, "   Start Date: %s\n", ccp);
+  free((char *) ccp);
+
+  /* Expire Date. */
+  ccp = Curl_ASN1tostr(&cert.notAfter, 0);
+  if(!ccp)
+    return CURLE_OUT_OF_MEMORY;
+  if(data->set.ssl.certinfo)
+    Curl_ssl_push_certinfo(data, certnum, "Expire Date", ccp);
+  if(!certnum)
+    infof(data, "   Expire Date: %s\n", ccp);
+  free((char *) ccp);
+
+  /* Public Key Algorithm. */
+  ccp = dumpAlgo(&param, cert.subjectPublicKeyAlgorithm.beg,
+                 cert.subjectPublicKeyAlgorithm.end);
+  if(!ccp)
+    return CURLE_OUT_OF_MEMORY;
+  if(data->set.ssl.certinfo)
+    Curl_ssl_push_certinfo(data, certnum, "Public Key Algorithm", ccp);
+  if(!certnum)
+    infof(data, "   Public Key Algorithm: %s\n", ccp);
+  do_pubkey(data, certnum, ccp, &param, &cert.subjectPublicKey);
+  free((char *) ccp);
+
+/* TODO: extensions. */
+
+  /* Signature. */
+  ccp = Curl_ASN1tostr(&cert.signature, 0);
+  if(!ccp)
+    return CURLE_OUT_OF_MEMORY;
+  if(data->set.ssl.certinfo)
+    Curl_ssl_push_certinfo(data, certnum, "Signature", ccp);
+  if(!certnum)
+    infof(data, "   Signature: %s\n", ccp);
+  free((char *) ccp);
+
+  /* Generate PEM certificate. */
+  result = Curl_base64_encode(data, cert.certificate.beg,
+                              cert.certificate.end - cert.certificate.beg,
+                              &cp1, &cl1);
+  if(result)
+    return result;
+  /* Compute the number of characters in final certificate string. Format is:
+     -----BEGIN CERTIFICATE-----\n
+     <max 64 base64 characters>\n
+     .
+     .
+     .
+     -----END CERTIFICATE-----\n
+   */
+  i = 28 + cl1 + (cl1 + 64 - 1) / 64 + 26;
+  cp2 = malloc(i + 1);
+  if(!cp2) {
+    free(cp1);
+    return CURLE_OUT_OF_MEMORY;
+  }
+  /* Build the certificate string. */
+  i = copySubstring(cp2, "-----BEGIN CERTIFICATE-----");
+  for(j = 0; j < cl1; j += 64)
+    i += copySubstring(cp2 + i, cp1 + j);
+  i += copySubstring(cp2 + i, "-----END CERTIFICATE-----");
+  cp2[i] = '\0';
+  free(cp1);
+  if(data->set.ssl.certinfo)
+    Curl_ssl_push_certinfo(data, certnum, "Cert", cp2);
+  if(!certnum)
+    infof(data, "%s\n", cp2);
+  free(cp2);
+  return CURLE_OK;
+}
+
+#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_CYASSL or USE_SCHANNEL */
+
+#if defined(USE_GSKIT)
+
+static const char *checkOID(const char *beg, const char *end,
+                            const char *oid)
+{
+  curl_asn1Element e;
+  const char *ccp;
+  const char *p;
+  bool matched;
+
+  /* Check if first ASN.1 element at `beg' is the given OID.
+     Return a pointer in the source after the OID if found, else NULL. */
+
+  ccp = Curl_getASN1Element(&e, beg, end);
+  if(!ccp || e.tag != CURL_ASN1_OBJECT_IDENTIFIER)
+    return (const char *) NULL;
+
+  p = OID2str(e.beg, e.end, FALSE);
+  if(!p)
+    return (const char *) NULL;
+
+  matched = !strcmp(p, oid);
+  free((char *) p);
+  return matched? ccp: (const char *) NULL;
+}
+
+CURLcode Curl_verifyhost(struct connectdata *conn,
+                         const char *beg, const char *end)
+{
+  struct Curl_easy *data = conn->data;
+  curl_X509certificate cert;
+  curl_asn1Element dn;
+  curl_asn1Element elem;
+  curl_asn1Element ext;
+  curl_asn1Element name;
+  const char *p;
+  const char *q;
+  char *dnsname;
+  int matched = -1;
+  size_t addrlen = (size_t) -1;
+  ssize_t len;
+  const char * const hostname = SSL_IS_PROXY()? conn->http_proxy.host.name:
+                                                conn->host.name;
+  const char * const dispname = SSL_IS_PROXY()?
+                                  conn->http_proxy.host.dispname:
+                                  conn->host.dispname;
+#ifdef ENABLE_IPV6
+  struct in6_addr addr;
+#else
+  struct in_addr addr;
+#endif
+
+  /* Verify that connection server matches info in X509 certificate at
+     `beg'..`end'. */
+
+  if(!SSL_CONN_CONFIG(verifyhost))
+    return CURLE_OK;
+
+  if(Curl_parseX509(&cert, beg, end))
+    return CURLE_PEER_FAILED_VERIFICATION;
+
+  /* Get the server IP address. */
+#ifdef ENABLE_IPV6
+  if(conn->bits.ipv6_ip && Curl_inet_pton(AF_INET6, hostname, &addr))
+    addrlen = sizeof(struct in6_addr);
+  else
+#endif
+  if(Curl_inet_pton(AF_INET, hostname, &addr))
+    addrlen = sizeof(struct in_addr);
+
+  /* Process extensions. */
+  for(p = cert.extensions.beg; p < cert.extensions.end && matched != 1;) {
+    p = Curl_getASN1Element(&ext, p, cert.extensions.end);
+    /* Check if extension is a subjectAlternativeName. */
+    ext.beg = checkOID(ext.beg, ext.end, sanOID);
+    if(ext.beg) {
+      ext.beg = Curl_getASN1Element(&elem, ext.beg, ext.end);
+      /* Skip critical if present. */
+      if(elem.tag == CURL_ASN1_BOOLEAN)
+        ext.beg = Curl_getASN1Element(&elem, ext.beg, ext.end);
+      /* Parse the octet string contents: is a single sequence. */
+      Curl_getASN1Element(&elem, elem.beg, elem.end);
+      /* Check all GeneralNames. */
+      for(q = elem.beg; matched != 1 && q < elem.end;) {
+        q = Curl_getASN1Element(&name, q, elem.end);
+        switch(name.tag) {
+        case 2: /* DNS name. */
+          len = utf8asn1str(&dnsname, CURL_ASN1_IA5_STRING,
+                            name.beg, name.end);
+          if(len > 0 && (size_t)len == strlen(dnsname))
+            matched = Curl_cert_hostcheck(dnsname, hostname);
+          else
+            matched = 0;
+          free(dnsname);
+          break;
+
+        case 7: /* IP address. */
+          matched = (size_t) (name.end - q) == addrlen &&
+                    !memcmp(&addr, q, addrlen);
+          break;
+        }
+      }
+    }
+  }
+
+  switch(matched) {
+  case 1:
+    /* an alternative name matched the server hostname */
+    infof(data, "\t subjectAltName: %s matched\n", dispname);
+    return CURLE_OK;
+  case 0:
+    /* an alternative name field existed, but didn't match and then
+       we MUST fail */
+    infof(data, "\t subjectAltName does not match %s\n", dispname);
+    return CURLE_PEER_FAILED_VERIFICATION;
+  }
+
+  /* Process subject. */
+  name.header = NULL;
+  name.beg = name.end = "";
+  q = cert.subject.beg;
+  /* we have to look to the last occurrence of a commonName in the
+     distinguished one to get the most significant one. */
+  while(q < cert.subject.end) {
+    q = Curl_getASN1Element(&dn, q, cert.subject.end);
+    for(p = dn.beg; p < dn.end;) {
+      p = Curl_getASN1Element(&elem, p, dn.end);
+      /* We have a DN's AttributeTypeAndValue: check it in case it's a CN. */
+      elem.beg = checkOID(elem.beg, elem.end, cnOID);
+      if(elem.beg)
+        name = elem;    /* Latch CN. */
+    }
+  }
+
+  /* Check the CN if found. */
+  if(!Curl_getASN1Element(&elem, name.beg, name.end))
+    failf(data, "SSL: unable to obtain common name from peer certificate");
+  else {
+    len = utf8asn1str(&dnsname, elem.tag, elem.beg, elem.end);
+    if(len < 0) {
+      free(dnsname);
+      return CURLE_OUT_OF_MEMORY;
+    }
+    if(strlen(dnsname) != (size_t) len)         /* Nul byte in string ? */
+      failf(data, "SSL: illegal cert name field");
+    else if(Curl_cert_hostcheck((const char *) dnsname, hostname)) {
+      infof(data, "\t common name: %s (matched)\n", dnsname);
+      free(dnsname);
+      return CURLE_OK;
+    }
+    else
+      failf(data, "SSL: certificate subject name '%s' does not match "
+            "target host name '%s'", dnsname, dispname);
+    free(dnsname);
+  }
+
+  return CURLE_PEER_FAILED_VERIFICATION;
+}
+
+#endif /* USE_GSKIT */
Index: EcnlProtoTool/trunk/curl-7.57.0/lib/x509asn1.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/lib/x509asn1.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/lib/x509asn1.h	(revision 331)
@@ -0,0 +1,134 @@
+#ifndef HEADER_CURL_X509ASN1_H
+#define HEADER_CURL_X509ASN1_H
+
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "curl_setup.h"
+
+#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \
+    defined(USE_CYASSL) || defined(USE_SCHANNEL)
+
+#include "urldata.h"
+
+/*
+ * Constants.
+ */
+
+/* Largest supported ASN.1 structure. */
+#define CURL_ASN1_MAX                   ((size_t) 0x40000)      /* 256K */
+
+/* ASN.1 classes. */
+#define CURL_ASN1_UNIVERSAL             0
+#define CURL_ASN1_APPLICATION           1
+#define CURL_ASN1_CONTEXT_SPECIFIC      2
+#define CURL_ASN1_PRIVATE               3
+
+/* ASN.1 types. */
+#define CURL_ASN1_BOOLEAN               1
+#define CURL_ASN1_INTEGER               2
+#define CURL_ASN1_BIT_STRING            3
+#define CURL_ASN1_OCTET_STRING          4
+#define CURL_ASN1_NULL                  5
+#define CURL_ASN1_OBJECT_IDENTIFIER     6
+#define CURL_ASN1_OBJECT_DESCRIPTOR     7
+#define CURL_ASN1_INSTANCE_OF           8
+#define CURL_ASN1_REAL                  9
+#define CURL_ASN1_ENUMERATED            10
+#define CURL_ASN1_EMBEDDED              11
+#define CURL_ASN1_UTF8_STRING           12
+#define CURL_ASN1_RELATIVE_OID          13
+#define CURL_ASN1_SEQUENCE              16
+#define CURL_ASN1_SET                   17
+#define CURL_ASN1_NUMERIC_STRING        18
+#define CURL_ASN1_PRINTABLE_STRING      19
+#define CURL_ASN1_TELETEX_STRING        20
+#define CURL_ASN1_VIDEOTEX_STRING       21
+#define CURL_ASN1_IA5_STRING            22
+#define CURL_ASN1_UTC_TIME              23
+#define CURL_ASN1_GENERALIZED_TIME      24
+#define CURL_ASN1_GRAPHIC_STRING        25
+#define CURL_ASN1_VISIBLE_STRING        26
+#define CURL_ASN1_GENERAL_STRING        27
+#define CURL_ASN1_UNIVERSAL_STRING      28
+#define CURL_ASN1_CHARACTER_STRING      29
+#define CURL_ASN1_BMP_STRING            30
+
+
+/*
+ * Types.
+ */
+
+/* ASN.1 parsed element. */
+typedef struct {
+  const char *  header;         /* Pointer to header byte. */
+  const char *  beg;            /* Pointer to element data. */
+  const char *  end;            /* Pointer to 1st byte after element. */
+  unsigned char class;          /* ASN.1 element class. */
+  unsigned char tag;            /* ASN.1 element tag. */
+  bool          constructed;    /* Element is constructed. */
+}  curl_asn1Element;
+
+
+/* ASN.1 OID table entry. */
+typedef struct {
+  const char *  numoid;         /* Dotted-numeric OID. */
+  const char *  textoid;        /* OID name. */
+}  curl_OID;
+
+
+/* X509 certificate: RFC 5280. */
+typedef struct {
+  curl_asn1Element      certificate;
+  curl_asn1Element      version;
+  curl_asn1Element      serialNumber;
+  curl_asn1Element      signatureAlgorithm;
+  curl_asn1Element      signature;
+  curl_asn1Element      issuer;
+  curl_asn1Element      notBefore;
+  curl_asn1Element      notAfter;
+  curl_asn1Element      subject;
+  curl_asn1Element      subjectPublicKeyInfo;
+  curl_asn1Element      subjectPublicKeyAlgorithm;
+  curl_asn1Element      subjectPublicKey;
+  curl_asn1Element      issuerUniqueID;
+  curl_asn1Element      subjectUniqueID;
+  curl_asn1Element      extensions;
+}  curl_X509certificate;
+
+
+/*
+ * Prototypes.
+ */
+
+const char *Curl_getASN1Element(curl_asn1Element *elem,
+                                 const char *beg, const char *end);
+const char *Curl_ASN1tostr(curl_asn1Element *elem, int type);
+const char *Curl_DNtostr(curl_asn1Element *dn);
+int Curl_parseX509(curl_X509certificate *cert,
+                   const char *beg, const char *end);
+CURLcode Curl_extract_certinfo(struct connectdata *conn, int certnum,
+                               const char *beg, const char *end);
+CURLcode Curl_verifyhost(struct connectdata *conn,
+                         const char *beg, const char *end);
+#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_CYASSL or USE_SCHANNEL */
+#endif /* HEADER_CURL_X509ASN1_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/src/slist_wc.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/slist_wc.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/slist_wc.c	(revision 331)
@@ -0,0 +1,72 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "tool_setup.h"
+
+#ifndef CURL_DISABLE_LIBCURL_OPTION
+
+#include "slist_wc.h"
+
+/* The last #include files should be: */
+#include "memdebug.h"
+
+/*
+ * slist_wc_append() appends a string to the linked list. This function can be
+ * used as an initialization function as well as an append function.
+ */
+struct slist_wc *slist_wc_append(struct slist_wc *list,
+                                 const char *data)
+{
+  struct curl_slist *new_item = curl_slist_append(NULL, data);
+
+  if(!new_item)
+    return NULL;
+
+  if(!list) {
+    list = malloc(sizeof(struct slist_wc));
+
+    if(!list) {
+      curl_slist_free_all(new_item);
+      return NULL;
+    }
+
+    list->first = new_item;
+    list->last = new_item;
+    return list;
+  }
+
+  list->last->next = new_item;
+  list->last = list->last->next;
+  return list;
+}
+
+/* be nice and clean up resources */
+void slist_wc_free_all(struct slist_wc *list)
+{
+  if(!list)
+    return;
+
+  curl_slist_free_all(list->first);
+  free(list);
+}
+
+#endif /* CURL_DISABLE_LIBCURL_OPTION */
Index: EcnlProtoTool/trunk/curl-7.57.0/src/slist_wc.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/slist_wc.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/slist_wc.h	(revision 331)
@@ -0,0 +1,56 @@
+#ifndef HEADER_CURL_SLIST_WC_H
+#define HEADER_CURL_SLIST_WC_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "tool_setup.h"
+#ifndef CURL_DISABLE_LIBCURL_OPTION
+
+/* linked-list structure with last node cache for easysrc */
+struct slist_wc {
+  struct curl_slist *first;
+  struct curl_slist *last;
+};
+
+/*
+ * NAME curl_slist_wc_append()
+ *
+ * DESCRIPTION
+ *
+ * Appends a string to a linked list. If no list exists, it will be created
+ * first. Returns the new list, after appending.
+ */
+struct slist_wc *slist_wc_append(struct slist_wc *, const char *);
+
+/*
+ * NAME curl_slist_free_all()
+ *
+ * DESCRIPTION
+ *
+ * free a previously built curl_slist_wc.
+ */
+void slist_wc_free_all(struct slist_wc *);
+
+#endif /* CURL_DISABLE_LIBCURL_OPTION */
+
+#endif /* HEADER_CURL_SLIST_WC_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_binmode.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_binmode.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_binmode.c	(revision 331)
@@ -0,0 +1,52 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#ifdef HAVE_SETMODE
+
+#ifdef HAVE_IO_H
+#  include <io.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#  include <fcntl.h>
+#endif
+
+#include "tool_binmode.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+void set_binmode(FILE *stream)
+{
+#ifdef O_BINARY
+#  ifdef __HIGHC__
+  _setmode(stream, O_BINARY);
+#  else
+  (void)setmode(fileno(stream), O_BINARY);
+#  endif
+#else
+  (void)stream;
+#endif
+}
+
+#endif /* HAVE_SETMODE */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_binmode.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_binmode.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_binmode.h	(revision 331)
@@ -0,0 +1,37 @@
+#ifndef HEADER_CURL_TOOL_BINMODE_H
+#define HEADER_CURL_TOOL_BINMODE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#ifdef HAVE_SETMODE
+
+void set_binmode(FILE *stream);
+
+#else
+
+#define set_binmode(x) Curl_nop_stmt
+
+#endif /* HAVE_SETMODE */
+
+#endif /* HEADER_CURL_TOOL_BINMODE_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_bname.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_bname.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_bname.c	(revision 331)
@@ -0,0 +1,50 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#include "tool_bname.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+#ifndef HAVE_BASENAME
+
+char *tool_basename(char *path)
+{
+  char *s1;
+  char *s2;
+
+  s1 = strrchr(path, '/');
+  s2 = strrchr(path, '\\');
+
+  if(s1 && s2) {
+    path = (s1 > s2) ? s1 + 1 : s2 + 1;
+  }
+  else if(s1)
+    path = s1 + 1;
+  else if(s2)
+    path = s2 + 1;
+
+  return path;
+}
+
+#endif /* HAVE_BASENAME */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_bname.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_bname.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_bname.h	(revision 331)
@@ -0,0 +1,35 @@
+#ifndef HEADER_CURL_TOOL_BNAME_H
+#define HEADER_CURL_TOOL_BNAME_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#ifndef HAVE_BASENAME
+
+char *tool_basename(char *path);
+
+#define basename(x) tool_basename((x))
+
+#endif /* HAVE_BASENAME */
+
+#endif /* HEADER_CURL_TOOL_BNAME_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_dbg.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_dbg.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_dbg.c	(revision 331)
@@ -0,0 +1,282 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_cfgable.h"
+#include "tool_convert.h"
+#include "tool_msgs.h"
+#include "tool_cb_dbg.h"
+#include "tool_util.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+static void dump(const char *timebuf, const char *text,
+                 FILE *stream, const unsigned char *ptr, size_t size,
+                 trace tracetype, curl_infotype infotype);
+
+/*
+** callback for CURLOPT_DEBUGFUNCTION
+*/
+
+int tool_debug_cb(CURL *handle, curl_infotype type,
+                  char *data, size_t size,
+                  void *userdata)
+{
+  struct OperationConfig *operation = userdata;
+  struct GlobalConfig *config = operation->global;
+  FILE *output = config->errors;
+  const char *text;
+  struct timeval tv;
+  struct tm *now;
+  char timebuf[20];
+  time_t secs;
+  static time_t epoch_offset;
+  static int    known_offset;
+
+  (void)handle; /* not used */
+
+  if(config->tracetime) {
+    tv = tvnow();
+    if(!known_offset) {
+      epoch_offset = time(NULL) - tv.tv_sec;
+      known_offset = 1;
+    }
+    secs = epoch_offset + tv.tv_sec;
+    now = localtime(&secs);  /* not thread safe but we don't care */
+    snprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d.%06ld ",
+             now->tm_hour, now->tm_min, now->tm_sec, (long)tv.tv_usec);
+  }
+  else
+    timebuf[0] = 0;
+
+  if(!config->trace_stream) {
+    /* open for append */
+    if(!strcmp("-", config->trace_dump))
+      config->trace_stream = stdout;
+    else if(!strcmp("%", config->trace_dump))
+      /* Ok, this is somewhat hackish but we do it undocumented for now */
+      config->trace_stream = config->errors;  /* aka stderr */
+    else {
+      config->trace_stream = fopen(config->trace_dump, FOPEN_WRITETEXT);
+      config->trace_fopened = TRUE;
+    }
+  }
+
+  if(config->trace_stream)
+    output = config->trace_stream;
+
+  if(!output) {
+    warnf(config, "Failed to create/open output");
+    return 0;
+  }
+
+  if(config->tracetype == TRACE_PLAIN) {
+    /*
+     * This is the trace look that is similar to what libcurl makes on its
+     * own.
+     */
+    static const char * const s_infotype[] = {
+      "*", "<", ">", "{", "}", "{", "}"
+    };
+    size_t i;
+    size_t st = 0;
+    static bool newl = FALSE;
+    static bool traced_data = FALSE;
+
+    switch(type) {
+    case CURLINFO_HEADER_OUT:
+      if(size > 0) {
+        for(i = 0; i < size - 1; i++) {
+          if(data[i] == '\n') { /* LF */
+            if(!newl) {
+              fprintf(output, "%s%s ", timebuf, s_infotype[type]);
+            }
+            (void)fwrite(data + st, i - st + 1, 1, output);
+            st = i + 1;
+            newl = FALSE;
+          }
+        }
+        if(!newl)
+          fprintf(output, "%s%s ", timebuf, s_infotype[type]);
+        (void)fwrite(data + st, i - st + 1, 1, output);
+      }
+      newl = (size && (data[size - 1] != '\n')) ? TRUE : FALSE;
+      traced_data = FALSE;
+      break;
+    case CURLINFO_TEXT:
+    case CURLINFO_HEADER_IN:
+      if(!newl)
+        fprintf(output, "%s%s ", timebuf, s_infotype[type]);
+      (void)fwrite(data, size, 1, output);
+      newl = (size && (data[size - 1] != '\n')) ? TRUE : FALSE;
+      traced_data = FALSE;
+      break;
+    case CURLINFO_DATA_OUT:
+    case CURLINFO_DATA_IN:
+    case CURLINFO_SSL_DATA_IN:
+    case CURLINFO_SSL_DATA_OUT:
+      if(!traced_data) {
+        /* if the data is output to a tty and we're sending this debug trace
+           to stderr or stdout, we don't display the alert about the data not
+           being shown as the data _is_ shown then just not via this
+           function */
+        if(!config->isatty || ((output != stderr) && (output != stdout))) {
+          if(!newl)
+            fprintf(output, "%s%s ", timebuf, s_infotype[type]);
+          fprintf(output, "[%zd bytes data]\n", size);
+          newl = FALSE;
+          traced_data = TRUE;
+        }
+      }
+      break;
+    default: /* nada */
+      newl = FALSE;
+      traced_data = FALSE;
+      break;
+    }
+
+    return 0;
+  }
+
+#ifdef CURL_DOES_CONVERSIONS
+  /* Special processing is needed for CURLINFO_HEADER_OUT blocks
+   * if they contain both headers and data (separated by CRLFCRLF).
+   * We dump the header text and then switch type to CURLINFO_DATA_OUT.
+   */
+  if((type == CURLINFO_HEADER_OUT) && (size > 4)) {
+    size_t i;
+    for(i = 0; i < size - 4; i++) {
+      if(memcmp(&data[i], "\r\n\r\n", 4) == 0) {
+        /* dump everything through the CRLFCRLF as a sent header */
+        text = "=> Send header";
+        dump(timebuf, text, output, (unsigned char *)data, i + 4,
+             config->tracetype, type);
+        data += i + 3;
+        size -= i + 4;
+        type = CURLINFO_DATA_OUT;
+        data += 1;
+        break;
+      }
+    }
+  }
+#endif /* CURL_DOES_CONVERSIONS */
+
+  switch(type) {
+  case CURLINFO_TEXT:
+    fprintf(output, "%s== Info: %s", timebuf, data);
+    /* FALLTHROUGH */
+  default: /* in case a new one is introduced to shock us */
+    return 0;
+
+  case CURLINFO_HEADER_OUT:
+    text = "=> Send header";
+    break;
+  case CURLINFO_DATA_OUT:
+    text = "=> Send data";
+    break;
+  case CURLINFO_HEADER_IN:
+    text = "<= Recv header";
+    break;
+  case CURLINFO_DATA_IN:
+    text = "<= Recv data";
+    break;
+  case CURLINFO_SSL_DATA_IN:
+    text = "<= Recv SSL data";
+    break;
+  case CURLINFO_SSL_DATA_OUT:
+    text = "=> Send SSL data";
+    break;
+  }
+
+  dump(timebuf, text, output, (unsigned char *) data, size, config->tracetype,
+       type);
+  return 0;
+}
+
+static void dump(const char *timebuf, const char *text,
+                 FILE *stream, const unsigned char *ptr, size_t size,
+                 trace tracetype, curl_infotype infotype)
+{
+  size_t i;
+  size_t c;
+
+  unsigned int width = 0x10;
+
+  if(tracetype == TRACE_ASCII)
+    /* without the hex output, we can fit more on screen */
+    width = 0x40;
+
+  fprintf(stream, "%s%s, %zd bytes (0x%zx)\n", timebuf, text, size, size);
+
+  for(i = 0; i < size; i += width) {
+
+    fprintf(stream, "%04zx: ", i);
+
+    if(tracetype == TRACE_BIN) {
+      /* hex not disabled, show it */
+      for(c = 0; c < width; c++)
+        if(i + c < size)
+          fprintf(stream, "%02x ", ptr[i + c]);
+        else
+          fputs("   ", stream);
+    }
+
+    for(c = 0; (c < width) && (i + c < size); c++) {
+      /* check for 0D0A; if found, skip past and start a new line of output */
+      if((tracetype == TRACE_ASCII) &&
+         (i + c + 1 < size) && (ptr[i + c] == 0x0D) &&
+         (ptr[i + c + 1] == 0x0A)) {
+        i += (c + 2 - width);
+        break;
+      }
+#ifdef CURL_DOES_CONVERSIONS
+      /* repeat the 0D0A check above but use the host encoding for CRLF */
+      if((tracetype == TRACE_ASCII) &&
+         (i + c + 1 < size) && (ptr[i + c] == '\r') &&
+         (ptr[i + c + 1] == '\n')) {
+        i += (c + 2 - width);
+        break;
+      }
+      /* convert to host encoding and print this character */
+      fprintf(stream, "%c", convert_char(infotype, ptr[i + c]));
+#else
+      (void)infotype;
+      fprintf(stream, "%c", ((ptr[i + c] >= 0x20) && (ptr[i + c] < 0x80)) ?
+              ptr[i + c] : UNPRINTABLE_CHAR);
+#endif /* CURL_DOES_CONVERSIONS */
+      /* check again for 0D0A, to avoid an extra \n if it's at width */
+      if((tracetype == TRACE_ASCII) &&
+         (i + c + 2 < size) && (ptr[i + c + 1] == 0x0D) &&
+         (ptr[i + c + 2] == 0x0A)) {
+        i += (c + 3 - width);
+        break;
+      }
+    }
+    fputc('\n', stream); /* newline */
+  }
+  fflush(stream);
+}
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_dbg.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_dbg.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_dbg.h	(revision 331)
@@ -0,0 +1,35 @@
+#ifndef HEADER_CURL_TOOL_CB_DBG_H
+#define HEADER_CURL_TOOL_CB_DBG_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+/*
+** callback for CURLOPT_DEBUGFUNCTION
+*/
+
+int tool_debug_cb(CURL *handle, curl_infotype type,
+                  char *data, size_t size,
+                  void *userdata);
+
+#endif /* HEADER_CURL_TOOL_CB_DBG_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_hdr.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_hdr.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_hdr.c	(revision 331)
@@ -0,0 +1,236 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#include "strcase.h"
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_cfgable.h"
+#include "tool_doswin.h"
+#include "tool_msgs.h"
+#include "tool_cb_hdr.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+static char *parse_filename(const char *ptr, size_t len);
+
+/*
+** callback for CURLOPT_HEADERFUNCTION
+*/
+
+size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
+{
+  struct HdrCbData *hdrcbdata = userdata;
+  struct OutStruct *outs = hdrcbdata->outs;
+  struct OutStruct *heads = hdrcbdata->heads;
+  const char *str = ptr;
+  const size_t cb = size * nmemb;
+  const char *end = (char *)ptr + cb;
+  char *url = NULL;
+
+  /*
+   * Once that libcurl has called back tool_header_cb() the returned value
+   * is checked against the amount that was intended to be written, if
+   * it does not match then it fails with CURLE_WRITE_ERROR. So at this
+   * point returning a value different from sz*nmemb indicates failure.
+   */
+  size_t failure = (size && nmemb) ? 0 : 1;
+
+  if(!heads->config)
+    return failure;
+
+#ifdef DEBUGBUILD
+  if(size * nmemb > (size_t)CURL_MAX_HTTP_HEADER) {
+    warnf(heads->config->global, "Header data exceeds single call write "
+          "limit!\n");
+    return failure;
+  }
+#endif
+
+  /*
+   * Write header data when curl option --dump-header (-D) is given.
+   */
+
+  if(heads->config->headerfile && heads->stream) {
+    size_t rc = fwrite(ptr, size, nmemb, heads->stream);
+    if(rc != cb)
+      return rc;
+    /* flush the stream to send off what we got earlier */
+    (void)fflush(heads->stream);
+  }
+
+  /*
+   * This callback sets the filename where output shall be written when
+   * curl options --remote-name (-O) and --remote-header-name (-J) have
+   * been simultaneously given and additionally server returns an HTTP
+   * Content-Disposition header specifying a filename property.
+   */
+
+  if(hdrcbdata->honor_cd_filename &&
+     (cb > 20) && checkprefix("Content-disposition:", str) &&
+     !curl_easy_getinfo(outs->config->easy, CURLINFO_EFFECTIVE_URL, &url) &&
+     url && (checkprefix("http://", url) || checkprefix("https://", url))) {
+    const char *p = str + 20;
+
+    /* look for the 'filename=' parameter
+       (encoded filenames (*=) are not supported) */
+    for(;;) {
+      char *filename;
+      size_t len;
+
+      while(*p && (p < end) && !ISALPHA(*p))
+        p++;
+      if(p > end - 9)
+        break;
+
+      if(memcmp(p, "filename=", 9)) {
+        /* no match, find next parameter */
+        while((p < end) && (*p != ';'))
+          p++;
+        continue;
+      }
+      p += 9;
+
+      /* this expression below typecasts 'cb' only to avoid
+         warning: signed and unsigned type in conditional expression
+      */
+      len = (ssize_t)cb - (p - str);
+      filename = parse_filename(p, len);
+      if(filename) {
+        outs->filename = filename;
+        outs->alloc_filename = TRUE;
+        outs->is_cd_filename = TRUE;
+        outs->s_isreg = TRUE;
+        outs->fopened = FALSE;
+        outs->stream = NULL;
+        hdrcbdata->honor_cd_filename = FALSE;
+        break;
+      }
+      return failure;
+    }
+  }
+
+  return cb;
+}
+
+/*
+ * Copies a file name part and returns an ALLOCATED data buffer.
+ */
+static char *parse_filename(const char *ptr, size_t len)
+{
+  char *copy;
+  char *p;
+  char *q;
+  char  stop = '\0';
+
+  /* simple implementation of strndup() */
+  copy = malloc(len + 1);
+  if(!copy)
+    return NULL;
+  memcpy(copy, ptr, len);
+  copy[len] = '\0';
+
+  p = copy;
+  if(*p == '\'' || *p == '"') {
+    /* store the starting quote */
+    stop = *p;
+    p++;
+  }
+  else
+    stop = ';';
+
+  /* scan for the end letter and stop there */
+  q = strchr(p, stop);
+  if(q)
+    *q = '\0';
+
+  /* if the filename contains a path, only use filename portion */
+  q = strrchr(p, '/');
+  if(q) {
+    p = q + 1;
+    if(!*p) {
+      Curl_safefree(copy);
+      return NULL;
+    }
+  }
+
+  /* If the filename contains a backslash, only use filename portion. The idea
+     is that even systems that don't handle backslashes as path separators
+     probably want the path removed for convenience. */
+  q = strrchr(p, '\\');
+  if(q) {
+    p = q + 1;
+    if(!*p) {
+      Curl_safefree(copy);
+      return NULL;
+    }
+  }
+
+  /* make sure the file name doesn't end in \r or \n */
+  q = strchr(p, '\r');
+  if(q)
+    *q = '\0';
+
+  q = strchr(p, '\n');
+  if(q)
+    *q = '\0';
+
+  if(copy != p)
+    memmove(copy, p, strlen(p) + 1);
+
+#if defined(MSDOS) || defined(WIN32)
+  {
+    char *sanitized;
+    SANITIZEcode sc = sanitize_file_name(&sanitized, copy, 0);
+    Curl_safefree(copy);
+    if(sc)
+      return NULL;
+    copy = sanitized;
+  }
+#endif /* MSDOS || WIN32 */
+
+  /* in case we built debug enabled, we allow an environment variable
+   * named CURL_TESTDIR to prefix the given file name to put it into a
+   * specific directory
+   */
+#ifdef DEBUGBUILD
+  {
+    char *tdir = curlx_getenv("CURL_TESTDIR");
+    if(tdir) {
+      char buffer[512]; /* suitably large */
+      snprintf(buffer, sizeof(buffer), "%s/%s", tdir, copy);
+      Curl_safefree(copy);
+      copy = strdup(buffer); /* clone the buffer, we don't use the libcurl
+                                aprintf() or similar since we want to use the
+                                same memory code as the "real" parse_filename
+                                function */
+      curl_free(tdir);
+    }
+  }
+#endif
+
+  return copy;
+}
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_hdr.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_hdr.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_hdr.h	(revision 331)
@@ -0,0 +1,54 @@
+#ifndef HEADER_CURL_TOOL_CB_HDR_H
+#define HEADER_CURL_TOOL_CB_HDR_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+/*
+ * curl operates using a single HdrCbData struct variable, a
+ * pointer to this is passed as userdata pointer to tool_header_cb.
+ *
+ * 'outs' member is a pointer to the OutStruct variable used to keep
+ * track of information relative to curl's output writing.
+ *
+ * 'heads' member is a pointer to the OutStruct variable used to keep
+ * track of information relative to header response writing.
+ *
+ * 'honor_cd_filename' member is TRUE when tool_header_cb is allowed
+ * to honor Content-Disposition filename property and accordingly
+ * set 'outs' filename, otherwise FALSE;
+ */
+
+struct HdrCbData {
+  struct OutStruct *outs;
+  struct OutStruct *heads;
+  bool honor_cd_filename;
+};
+
+/*
+** callback for CURLOPT_HEADERFUNCTION
+*/
+
+size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata);
+
+#endif /* HEADER_CURL_TOOL_CB_HDR_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_prg.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_prg.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_prg.c	(revision 331)
@@ -0,0 +1,150 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_cfgable.h"
+#include "tool_cb_prg.h"
+#include "tool_util.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+/*
+** callback for CURLOPT_XFERINFOFUNCTION
+*/
+
+#define MAX_BARLENGTH 256
+
+int tool_progress_cb(void *clientp,
+                     curl_off_t dltotal, curl_off_t dlnow,
+                     curl_off_t ultotal, curl_off_t ulnow)
+{
+  /* The original progress-bar source code was written for curl by Lars Aas,
+     and this new edition inherits some of his concepts. */
+
+  char line[MAX_BARLENGTH + 1];
+  char format[40];
+  double frac;
+  double percent;
+  int barwidth;
+  int num;
+  struct timeval now = tvnow();
+  struct ProgressData *bar = (struct ProgressData *)clientp;
+  curl_off_t total;
+  curl_off_t point;
+
+  /* expected transfer size */
+  total = dltotal + ultotal + bar->initial_size;
+
+  /* we've come this far */
+  point = dlnow + ulnow + bar->initial_size;
+
+  if(bar->calls && (tvdiff(now, bar->prevtime) < 100L) && point < total)
+    /* after first call, limit progress-bar updating to 10 Hz */
+    /* update when we're at 100% even if last update is less than 200ms ago */
+    return 0;
+
+  if(point > total)
+    /* we have got more than the expected total! */
+    total = point;
+
+  /* simply count invokes */
+  bar->calls++;
+
+  if(total < 1) {
+    curl_off_t prevblock = bar->prev / 1024;
+    curl_off_t thisblock = point / 1024;
+    while(thisblock > prevblock) {
+      fprintf(bar->out, "#");
+      prevblock++;
+    }
+  }
+  else if(point != bar->prev) {
+    frac = (double)point / (double)total;
+    percent = frac * 100.0;
+    barwidth = bar->width - 7;
+    num = (int) (((double)barwidth) * frac);
+    if(num > MAX_BARLENGTH)
+      num = MAX_BARLENGTH;
+    memset(line, '#', num);
+    line[num] = '\0';
+    snprintf(format, sizeof(format), "\r%%-%ds %%5.1f%%%%", barwidth);
+    fprintf(bar->out, format, line, percent);
+  }
+  fflush(bar->out);
+  bar->prev = point;
+  bar->prevtime = now;
+
+  return 0;
+}
+
+void progressbarinit(struct ProgressData *bar,
+                     struct OperationConfig *config)
+{
+#ifdef __EMX__
+  /* 20000318 mgs */
+  int scr_size[2];
+#endif
+  char *colp;
+
+  memset(bar, 0, sizeof(struct ProgressData));
+
+  /* pass this through to progress function so
+   * it can display progress towards total file
+   * not just the part that's left. (21-may-03, dbyron) */
+  if(config->use_resume)
+    bar->initial_size = config->resume_from;
+
+/* TODO: get terminal width through ansi escapes or something similar.
+   try to update width when xterm is resized... - 19990617 larsa */
+#ifndef __EMX__
+  /* 20000318 mgs
+   * OS/2 users most likely won't have this env var set, and besides that
+   * we're using our own way to determine screen width */
+  colp = curlx_getenv("COLUMNS");
+  if(colp) {
+    char *endptr;
+    long num = strtol(colp, &endptr, 10);
+    if((endptr != colp) && (endptr == colp + strlen(colp)) && (num > 0))
+      bar->width = (int)num;
+    else
+      bar->width = 79;
+    curl_free(colp);
+  }
+  else
+    bar->width = 79;
+#else
+  /* 20000318 mgs
+   * We use this emx library call to get the screen width, and subtract
+   * one from what we got in order to avoid a problem with the cursor
+   * advancing to the next line if we print a string that is as long as
+   * the screen is wide. */
+
+  _scrsize(scr_size);
+  bar->width = scr_size[0] - 1;
+#endif
+
+  bar->out = config->global->errors;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_prg.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_prg.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_prg.h	(revision 331)
@@ -0,0 +1,50 @@
+#ifndef HEADER_CURL_TOOL_CB_PRG_H
+#define HEADER_CURL_TOOL_CB_PRG_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#define CURL_PROGRESS_STATS 0 /* default progress display */
+#define CURL_PROGRESS_BAR   1
+
+struct ProgressData {
+  int         calls;
+  curl_off_t  prev;
+  struct timeval prevtime;
+  int         width;
+  FILE       *out;  /* where to write everything to */
+  curl_off_t  initial_size;
+};
+
+void progressbarinit(struct ProgressData *bar,
+                     struct OperationConfig *config);
+
+/*
+** callback for CURLOPT_PROGRESSFUNCTION
+*/
+
+int tool_progress_cb(void *clientp,
+                     curl_off_t dltotal, curl_off_t dlnow,
+                     curl_off_t ultotal, curl_off_t ulnow);
+
+#endif /* HEADER_CURL_TOOL_CB_PRG_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_rea.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_rea.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_rea.c	(revision 331)
@@ -0,0 +1,55 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_cfgable.h"
+#include "tool_cb_rea.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+/*
+** callback for CURLOPT_READFUNCTION
+*/
+
+size_t tool_read_cb(void *buffer, size_t sz, size_t nmemb, void *userdata)
+{
+  ssize_t rc;
+  struct InStruct *in = userdata;
+
+  rc = read(in->fd, buffer, sz*nmemb);
+  if(rc < 0) {
+    if(errno == EAGAIN) {
+      errno = 0;
+      in->config->readbusy = TRUE;
+      return CURL_READFUNC_PAUSE;
+    }
+    /* since size_t is unsigned we can't return negative values fine */
+    rc = 0;
+  }
+  in->config->readbusy = FALSE;
+  return (size_t)rc;
+}
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_rea.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_rea.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_rea.h	(revision 331)
@@ -0,0 +1,33 @@
+#ifndef HEADER_CURL_TOOL_CB_REA_H
+#define HEADER_CURL_TOOL_CB_REA_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+/*
+** callback for CURLOPT_READFUNCTION
+*/
+
+size_t tool_read_cb(void *buffer, size_t sz, size_t nmemb, void *userdata);
+
+#endif /* HEADER_CURL_TOOL_CB_REA_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_see.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_see.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_see.c	(revision 331)
@@ -0,0 +1,131 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_cfgable.h"
+#include "tool_cb_see.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+/* OUR_MAX_SEEK_L has 'long' data type, OUR_MAX_SEEK_O has 'curl_off_t,
+   both represent the same value. Maximum offset used here when we lseek
+   using a 'long' data type offset */
+
+#define OUR_MAX_SEEK_L  2147483647L - 1L
+#define OUR_MAX_SEEK_O  CURL_OFF_T_C(0x7FFFFFFF) - CURL_OFF_T_C(0x1)
+
+/*
+** callback for CURLOPT_SEEKFUNCTION
+**
+** Notice that this is not supposed to return the resulting offset. This
+** shall only return CURL_SEEKFUNC_* return codes.
+*/
+
+int tool_seek_cb(void *userdata, curl_off_t offset, int whence)
+{
+  struct InStruct *in = userdata;
+
+#if(CURL_SIZEOF_CURL_OFF_T > SIZEOF_OFF_T) && !defined(USE_WIN32_LARGE_FILES)
+
+  /* The offset check following here is only interesting if curl_off_t is
+     larger than off_t and we are not using the WIN32 large file support
+     macros that provide the support to do 64bit seeks correctly */
+
+  if(offset > OUR_MAX_SEEK_O) {
+    /* Some precaution code to work around problems with different data sizes
+       to allow seeking >32bit even if off_t is 32bit. Should be very rare and
+       is really valid on weirdo-systems. */
+    curl_off_t left = offset;
+
+    if(whence != SEEK_SET)
+      /* this code path doesn't support other types */
+      return CURL_SEEKFUNC_FAIL;
+
+    if(LSEEK_ERROR == lseek(in->fd, 0, SEEK_SET))
+      /* couldn't rewind to beginning */
+      return CURL_SEEKFUNC_FAIL;
+
+    while(left) {
+      long step = (left > OUR_MAX_SEEK_O) ? OUR_MAX_SEEK_L : (long)left;
+      if(LSEEK_ERROR == lseek(in->fd, step, SEEK_CUR))
+        /* couldn't seek forwards the desired amount */
+        return CURL_SEEKFUNC_FAIL;
+      left -= step;
+    }
+    return CURL_SEEKFUNC_OK;
+  }
+#endif
+
+  if(LSEEK_ERROR == lseek(in->fd, offset, whence))
+    /* couldn't rewind, the reason is in errno but errno is just not portable
+       enough and we don't actually care that much why we failed. We'll let
+       libcurl know that it may try other means if it wants to. */
+    return CURL_SEEKFUNC_CANTSEEK;
+
+  return CURL_SEEKFUNC_OK;
+}
+
+#if defined(WIN32) && !defined(__MINGW64__)
+
+#ifdef __BORLANDC__
+/* 64-bit lseek-like function unavailable */
+#  define _lseeki64(hnd,ofs,whence) lseek(hnd,ofs,whence)
+#endif
+
+#ifdef __POCC__
+#  if(__POCC__ < 450)
+/* 64-bit lseek-like function unavailable */
+#    define _lseeki64(hnd,ofs,whence) _lseek(hnd,ofs,whence)
+#  else
+#    define _lseeki64(hnd,ofs,whence) _lseek64(hnd,ofs,whence)
+#  endif
+#endif
+
+#ifdef _WIN32_WCE
+/* 64-bit lseek-like function unavailable */
+#  undef _lseeki64
+#  define _lseeki64(hnd,ofs,whence) lseek(hnd,ofs,whence)
+#  undef _get_osfhandle
+#  define _get_osfhandle(fd) (fd)
+#endif
+
+/*
+ * Truncate a file handle at a 64-bit position 'where'.
+ */
+
+int tool_ftruncate64(int fd, curl_off_t where)
+{
+  if(_lseeki64(fd, where, SEEK_SET) < 0)
+    return -1;
+
+  if(!SetEndOfFile((HANDLE)_get_osfhandle(fd)))
+    return -1;
+
+  return 0;
+}
+
+#endif /* WIN32  && ! __MINGW64__ */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_see.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_see.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_see.h	(revision 331)
@@ -0,0 +1,46 @@
+#ifndef HEADER_CURL_TOOL_CB_SEE_H
+#define HEADER_CURL_TOOL_CB_SEE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#if defined(WIN32) && !defined(__MINGW64__)
+
+int tool_ftruncate64(int fd, curl_off_t where);
+
+#undef  ftruncate
+#define ftruncate(fd,where) tool_ftruncate64(fd,where)
+
+#ifndef HAVE_FTRUNCATE
+#  define HAVE_FTRUNCATE 1
+#endif
+
+#endif /* WIN32  && ! __MINGW64__ */
+
+/*
+** callback for CURLOPT_SEEKFUNCTION
+*/
+
+int tool_seek_cb(void *userdata, curl_off_t offset, int whence);
+
+#endif /* HEADER_CURL_TOOL_CB_SEE_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_wrt.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_wrt.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_wrt.c	(revision 331)
@@ -0,0 +1,177 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_cfgable.h"
+#include "tool_msgs.h"
+#include "tool_cb_wrt.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+/* create a local file for writing, return TRUE on success */
+bool tool_create_output_file(struct OutStruct *outs)
+{
+  struct GlobalConfig *global = outs->config->global;
+  FILE *file;
+
+  if(!outs->filename || !*outs->filename) {
+    warnf(global, "Remote filename has no length!\n");
+    return FALSE;
+  }
+
+  if(outs->is_cd_filename) {
+    /* don't overwrite existing files */
+    file = fopen(outs->filename, "rb");
+    if(file) {
+      fclose(file);
+      warnf(global, "Refusing to overwrite %s: %s\n", outs->filename,
+            strerror(EEXIST));
+      return FALSE;
+    }
+  }
+
+  /* open file for writing */
+  file = fopen(outs->filename, "wb");
+  if(!file) {
+    warnf(global, "Failed to create the file %s: %s\n", outs->filename,
+          strerror(errno));
+    return FALSE;
+  }
+  outs->s_isreg = TRUE;
+  outs->fopened = TRUE;
+  outs->stream = file;
+  outs->bytes = 0;
+  outs->init = 0;
+  return TRUE;
+}
+
+/*
+** callback for CURLOPT_WRITEFUNCTION
+*/
+
+size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata)
+{
+  size_t rc;
+  struct OutStruct *outs = userdata;
+  struct OperationConfig *config = outs->config;
+  size_t bytes = sz * nmemb;
+  bool is_tty = config->global->isatty;
+
+  /*
+   * Once that libcurl has called back tool_write_cb() the returned value
+   * is checked against the amount that was intended to be written, if
+   * it does not match then it fails with CURLE_WRITE_ERROR. So at this
+   * point returning a value different from sz*nmemb indicates failure.
+   */
+  const size_t failure = bytes ? 0 : 1;
+
+#ifdef DEBUGBUILD
+  {
+    char *tty = curlx_getenv("CURL_ISATTY");
+    if(tty) {
+      is_tty = TRUE;
+      curl_free(tty);
+    }
+  }
+
+  if(config->include_headers) {
+    if(bytes > (size_t)CURL_MAX_HTTP_HEADER) {
+      warnf(config->global, "Header data size exceeds single call write "
+            "limit!\n");
+      return failure;
+    }
+  }
+  else {
+    if(bytes > (size_t)CURL_MAX_WRITE_SIZE) {
+      warnf(config->global, "Data size exceeds single call write limit!\n");
+      return failure;
+    }
+  }
+
+  {
+    /* Some internal congruency checks on received OutStruct */
+    bool check_fails = FALSE;
+    if(outs->filename) {
+      /* regular file */
+      if(!*outs->filename)
+        check_fails = TRUE;
+      if(!outs->s_isreg)
+        check_fails = TRUE;
+      if(outs->fopened && !outs->stream)
+        check_fails = TRUE;
+      if(!outs->fopened && outs->stream)
+        check_fails = TRUE;
+      if(!outs->fopened && outs->bytes)
+        check_fails = TRUE;
+    }
+    else {
+      /* standard stream */
+      if(!outs->stream || outs->s_isreg || outs->fopened)
+        check_fails = TRUE;
+      if(outs->alloc_filename || outs->is_cd_filename || outs->init)
+        check_fails = TRUE;
+    }
+    if(check_fails) {
+      warnf(config->global, "Invalid output struct data for write callback\n");
+      return failure;
+    }
+  }
+#endif
+
+  if(!outs->stream && !tool_create_output_file(outs))
+    return failure;
+
+  if(is_tty && (outs->bytes < 2000) && !config->terminal_binary_ok) {
+    /* binary output to terminal? */
+    if(memchr(buffer, 0, bytes)) {
+      warnf(config->global, "Binary output can mess up your terminal. "
+            "Use \"--output -\" to tell curl to output it to your terminal "
+            "anyway, or consider \"--output <FILE>\" to save to a file.\n");
+      config->synthetic_error = ERR_BINARY_TERMINAL;
+      return failure;
+    }
+  }
+
+  rc = fwrite(buffer, sz, nmemb, outs->stream);
+
+  if(bytes == rc)
+    /* we added this amount of data to the output */
+    outs->bytes += bytes;
+
+  if(config->readbusy) {
+    config->readbusy = FALSE;
+    curl_easy_pause(config->easy, CURLPAUSE_CONT);
+  }
+
+  if(config->nobuffer) {
+    /* output buffering disabled */
+    int res = fflush(outs->stream);
+    if(res)
+      return failure;
+  }
+
+  return rc;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_wrt.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_wrt.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_cb_wrt.h	(revision 331)
@@ -0,0 +1,36 @@
+#ifndef HEADER_CURL_TOOL_CB_WRT_H
+#define HEADER_CURL_TOOL_CB_WRT_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+/*
+** callback for CURLOPT_WRITEFUNCTION
+*/
+
+size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata);
+
+/* create a local file for writing, return TRUE on success */
+bool tool_create_output_file(struct OutStruct *outs);
+
+#endif /* HEADER_CURL_TOOL_CB_WRT_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_cfgable.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_cfgable.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_cfgable.c	(revision 331)
@@ -0,0 +1,174 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#include "tool_cfgable.h"
+#include "tool_main.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+void config_init(struct OperationConfig* config)
+{
+  memset(config, 0, sizeof(struct OperationConfig));
+
+  config->postfieldsize = -1;
+  config->use_httpget = FALSE;
+  config->create_dirs = FALSE;
+  config->maxredirs = DEFAULT_MAXREDIRS;
+  config->proto = CURLPROTO_ALL; /* FIXME: better to read from library */
+  config->proto_present = FALSE;
+  config->proto_redir = CURLPROTO_ALL & /* All except FILE, SCP and SMB */
+                        ~(CURLPROTO_FILE | CURLPROTO_SCP | CURLPROTO_SMB |
+                          CURLPROTO_SMBS);
+  config->proto_redir_present = FALSE;
+  config->proto_default = NULL;
+  config->tcp_nodelay = TRUE; /* enabled by default */
+}
+
+static void free_config_fields(struct OperationConfig *config)
+{
+  struct getout *urlnode;
+
+  Curl_safefree(config->random_file);
+  Curl_safefree(config->egd_file);
+  Curl_safefree(config->useragent);
+  Curl_safefree(config->cookie);
+  Curl_safefree(config->cookiejar);
+  Curl_safefree(config->cookiefile);
+
+  Curl_safefree(config->postfields);
+  Curl_safefree(config->referer);
+
+  Curl_safefree(config->headerfile);
+  Curl_safefree(config->ftpport);
+  Curl_safefree(config->iface);
+
+  Curl_safefree(config->range);
+
+  Curl_safefree(config->userpwd);
+  Curl_safefree(config->tls_username);
+  Curl_safefree(config->tls_password);
+  Curl_safefree(config->tls_authtype);
+  Curl_safefree(config->proxy_tls_username);
+  Curl_safefree(config->proxy_tls_password);
+  Curl_safefree(config->proxy_tls_authtype);
+  Curl_safefree(config->proxyuserpwd);
+  Curl_safefree(config->proxy);
+
+  Curl_safefree(config->dns_ipv6_addr);
+  Curl_safefree(config->dns_ipv4_addr);
+  Curl_safefree(config->dns_interface);
+  Curl_safefree(config->dns_servers);
+
+  Curl_safefree(config->noproxy);
+
+  Curl_safefree(config->mail_from);
+  curl_slist_free_all(config->mail_rcpt);
+  Curl_safefree(config->mail_auth);
+
+  Curl_safefree(config->netrc_file);
+
+  urlnode = config->url_list;
+  while(urlnode) {
+    struct getout *next = urlnode->next;
+    Curl_safefree(urlnode->url);
+    Curl_safefree(urlnode->outfile);
+    Curl_safefree(urlnode->infile);
+    Curl_safefree(urlnode);
+    urlnode = next;
+  }
+  config->url_list = NULL;
+  config->url_last = NULL;
+  config->url_get = NULL;
+  config->url_out = NULL;
+
+  Curl_safefree(config->cipher_list);
+  Curl_safefree(config->proxy_cipher_list);
+  Curl_safefree(config->cert);
+  Curl_safefree(config->proxy_cert);
+  Curl_safefree(config->cert_type);
+  Curl_safefree(config->proxy_cert_type);
+  Curl_safefree(config->cacert);
+  Curl_safefree(config->proxy_cacert);
+  Curl_safefree(config->capath);
+  Curl_safefree(config->proxy_capath);
+  Curl_safefree(config->crlfile);
+  Curl_safefree(config->pinnedpubkey);
+  Curl_safefree(config->proxy_crlfile);
+  Curl_safefree(config->key);
+  Curl_safefree(config->proxy_key);
+  Curl_safefree(config->key_type);
+  Curl_safefree(config->proxy_key_type);
+  Curl_safefree(config->key_passwd);
+  Curl_safefree(config->proxy_key_passwd);
+  Curl_safefree(config->pubkey);
+  Curl_safefree(config->hostpubmd5);
+  Curl_safefree(config->engine);
+  Curl_safefree(config->request_target);
+  Curl_safefree(config->customrequest);
+  Curl_safefree(config->krblevel);
+
+  Curl_safefree(config->oauth_bearer);
+
+  Curl_safefree(config->unix_socket_path);
+  Curl_safefree(config->writeout);
+  Curl_safefree(config->proto_default);
+
+  curl_slist_free_all(config->quote);
+  curl_slist_free_all(config->postquote);
+  curl_slist_free_all(config->prequote);
+
+  curl_slist_free_all(config->headers);
+  curl_slist_free_all(config->proxyheaders);
+
+  if(config->mimepost) {
+    curl_mime_free(config->mimepost);
+    config->mimepost = NULL;
+  }
+  config->mimecurrent = NULL;
+
+  curl_slist_free_all(config->telnet_options);
+  curl_slist_free_all(config->resolve);
+  curl_slist_free_all(config->connect_to);
+
+  Curl_safefree(config->preproxy);
+  Curl_safefree(config->proxy_service_name);
+  Curl_safefree(config->service_name);
+
+  Curl_safefree(config->ftp_account);
+  Curl_safefree(config->ftp_alternative_to_user);
+}
+
+void config_free(struct OperationConfig *config)
+{
+  struct OperationConfig *last = config;
+
+  /* Free each of the structures in reverse order */
+  while(last) {
+    struct OperationConfig *prev = last->prev;
+
+    free_config_fields(last);
+    free(last);
+
+    last = prev;
+  }
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_cfgable.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_cfgable.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_cfgable.h	(revision 331)
@@ -0,0 +1,283 @@
+#ifndef HEADER_CURL_TOOL_CFGABLE_H
+#define HEADER_CURL_TOOL_CFGABLE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#include "tool_sdecls.h"
+
+#include "tool_metalink.h"
+
+typedef enum {
+  ERR_NONE,
+  ERR_BINARY_TERMINAL = 1, /* binary to terminal detected */
+  ERR_LAST
+} curl_error;
+
+struct GlobalConfig;
+
+struct OperationConfig {
+  CURL *easy;               /* A copy of the handle from GlobalConfig */
+  bool remote_time;
+  char *random_file;
+  char *egd_file;
+  char *useragent;
+  char *cookie;             /* single line with specified cookies */
+  char *cookiejar;          /* write to this file */
+  char *cookiefile;         /* read from this file */
+  bool cookiesession;       /* new session? */
+  bool encoding;            /* Accept-Encoding please */
+  bool tr_encoding;         /* Transfer-Encoding please */
+  unsigned long authtype;   /* auth bitmask */
+  bool use_resume;
+  bool resume_from_current;
+  bool disable_epsv;
+  bool disable_eprt;
+  bool ftp_pret;
+  long proto;
+  bool proto_present;
+  long proto_redir;
+  bool proto_redir_present;
+  char *proto_default;
+  curl_off_t resume_from;
+  char *postfields;
+  curl_off_t postfieldsize;
+  char *referer;
+  double timeout;
+  double connecttimeout;
+  long maxredirs;
+  curl_off_t max_filesize;
+  char *headerfile;
+  char *ftpport;
+  char *iface;
+  int localport;
+  int localportrange;
+  unsigned short porttouse;
+  char *range;
+  long low_speed_limit;
+  long low_speed_time;
+  char *dns_servers;   /* dot notation: 1.1.1.1;2.2.2.2 */
+  char *dns_interface; /* interface name */
+  char *dns_ipv4_addr; /* dot notation */
+  char *dns_ipv6_addr; /* dot notation */
+  char *userpwd;
+  char *login_options;
+  char *tls_username;
+  char *tls_password;
+  char *tls_authtype;
+  char *proxy_tls_username;
+  char *proxy_tls_password;
+  char *proxy_tls_authtype;
+  char *proxyuserpwd;
+  char *proxy;
+  int proxyver;             /* set to CURLPROXY_HTTP* define */
+  char *noproxy;
+  char *mail_from;
+  struct curl_slist *mail_rcpt;
+  char *mail_auth;
+  bool sasl_ir;             /* Enable/disable SASL initial response */
+  bool proxytunnel;
+  bool ftp_append;          /* APPE on ftp */
+  bool use_ascii;           /* select ascii or text transfer */
+  bool autoreferer;         /* automatically set referer */
+  bool failonerror;         /* fail on (HTTP) errors */
+  bool include_headers;     /* send headers to data output */
+  bool no_body;             /* don't get the body */
+  bool dirlistonly;         /* only get the FTP dir list */
+  bool followlocation;      /* follow http redirects */
+  bool unrestricted_auth;   /* Continue to send authentication (user+password)
+                               when following ocations, even when hostname
+                               changed */
+  bool netrc_opt;
+  bool netrc;
+  char *netrc_file;
+  struct getout *url_list;  /* point to the first node */
+  struct getout *url_last;  /* point to the last/current node */
+  struct getout *url_get;   /* point to the node to fill in URL */
+  struct getout *url_out;   /* point to the node to fill in outfile */
+  struct getout *url_ul;    /* point to the node to fill in upload */
+  char *cipher_list;
+  char *proxy_cipher_list;
+  char *cert;
+  char *proxy_cert;
+  char *cert_type;
+  char *proxy_cert_type;
+  char *cacert;
+  char *proxy_cacert;
+  char *capath;
+  char *proxy_capath;
+  char *crlfile;
+  char *proxy_crlfile;
+  char *pinnedpubkey;
+  char *key;
+  char *proxy_key;
+  char *key_type;
+  char *proxy_key_type;
+  char *key_passwd;
+  char *proxy_key_passwd;
+  char *pubkey;
+  char *hostpubmd5;
+  char *engine;
+  bool crlf;
+  char *customrequest;
+  char *krblevel;
+  char *request_target;
+  long httpversion;
+  bool nobuffer;
+  bool readbusy;            /* set when reading input returns EAGAIN */
+  bool globoff;
+  bool use_httpget;
+  bool insecure_ok;         /* set TRUE to allow insecure SSL connects */
+  bool proxy_insecure_ok;   /* set TRUE to allow insecure SSL connects
+                               for proxy */
+  bool terminal_binary_ok;
+  bool verifystatus;
+  bool create_dirs;
+  bool ftp_create_dirs;
+  bool ftp_skip_ip;
+  bool proxynegotiate;
+  bool proxyntlm;
+  bool proxydigest;
+  bool proxybasic;
+  bool proxyanyauth;
+  char *writeout;           /* %-styled format string to output */
+  struct curl_slist *quote;
+  struct curl_slist *postquote;
+  struct curl_slist *prequote;
+  long ssl_version;
+  long ssl_version_max;
+  long proxy_ssl_version;
+  long ip_version;
+  curl_TimeCond timecond;
+  time_t condtime;
+  struct curl_slist *headers;
+  struct curl_slist *proxyheaders;
+  curl_mime *mimepost;
+  curl_mime *mimecurrent;
+  struct curl_slist *telnet_options;
+  struct curl_slist *resolve;
+  struct curl_slist *connect_to;
+  HttpReq httpreq;
+
+  /* for bandwidth limiting features: */
+  curl_off_t sendpersecond; /* send to peer */
+  curl_off_t recvpersecond; /* receive from peer */
+
+  bool ftp_ssl;
+  bool ftp_ssl_reqd;
+  bool ftp_ssl_control;
+  bool ftp_ssl_ccc;
+  int ftp_ssl_ccc_mode;
+  char *preproxy;
+  int socks5_gssapi_nec;    /* The NEC reference server does not protect the
+                               encryption type exchange */
+  unsigned long socks5_auth;/* auth bitmask for socks5 proxies */
+  char *proxy_service_name; /* set authentication service name for HTTP and
+                               SOCKS5 proxies */
+  char *service_name;       /* set authentication service name for DIGEST-MD5,
+                               Kerberos 5 and SPNEGO */
+
+  bool tcp_nodelay;
+  bool tcp_fastopen;
+  long req_retry;           /* number of retries */
+  bool retry_connrefused;   /* set connection refused as a transient error */
+  long retry_delay;         /* delay between retries (in seconds) */
+  long retry_maxtime;       /* maximum time to keep retrying */
+
+  char *ftp_account;        /* for ACCT */
+  char *ftp_alternative_to_user;  /* send command if USER/PASS fails */
+  int ftp_filemethod;
+  long tftp_blksize;        /* TFTP BLKSIZE option */
+  bool tftp_no_options;     /* do not send TFTP options requests */
+  bool ignorecl;            /* --ignore-content-length */
+  bool disable_sessionid;
+
+  bool raw;
+  bool post301;
+  bool post302;
+  bool post303;
+  bool nokeepalive;         /* for keepalive needs */
+  long alivetime;
+  bool content_disposition; /* use Content-disposition filename */
+
+  int default_node_flags;   /* default flags to search for each 'node', which
+                               is basically each given URL to transfer */
+
+  bool xattr;               /* store metadata in extended attributes */
+  long gssapi_delegation;
+  bool ssl_allow_beast;     /* allow this SSL vulnerability */
+  bool proxy_ssl_allow_beast; /* allow this SSL vulnerability for proxy*/
+
+  bool ssl_no_revoke;       /* disable SSL certificate revocation checks */
+  /*bool proxy_ssl_no_revoke; */
+
+  bool use_metalink;        /* process given URLs as metalink XML file */
+  metalinkfile *metalinkfile_list; /* point to the first node */
+  metalinkfile *metalinkfile_last; /* point to the last/current node */
+#ifdef CURLDEBUG
+  bool test_event_based;
+#endif
+  char *oauth_bearer;             /* OAuth 2.0 bearer token */
+  bool nonpn;                     /* enable/disable TLS NPN extension */
+  bool noalpn;                    /* enable/disable TLS ALPN extension */
+  char *unix_socket_path;         /* path to Unix domain socket */
+  bool abstract_unix_socket;      /* path to an abstract Unix domain socket */
+  bool falsestart;
+  bool path_as_is;
+  double expect100timeout;
+  bool suppress_connect_headers;  /* suppress proxy CONNECT response headers
+                                     from user callbacks */
+  curl_error synthetic_error;     /* if non-zero, it overrides any libcurl
+                                     error */
+  bool ssh_compression;           /* enable/disable SSH compression */
+  struct GlobalConfig *global;
+  struct OperationConfig *prev;
+  struct OperationConfig *next;   /* Always last in the struct */
+};
+
+struct GlobalConfig {
+  CURL *easy;                     /* Once we have one, we keep it here */
+  int showerror;                  /* -1 == unset, default => show errors
+                                      0 => -s is used to NOT show errors
+                                      1 => -S has been used to show errors */
+  bool mute;                      /* don't show messages, --silent given */
+  bool noprogress;                /* don't show progress bar --silent given */
+  bool isatty;                    /* Updated internally if output is a tty */
+  FILE *errors;                   /* Error stream, defaults to stderr */
+  bool errors_fopened;            /* Whether error stream isn't stderr */
+  char *trace_dump;               /* file to dump the network trace to */
+  FILE *trace_stream;
+  bool trace_fopened;
+  trace tracetype;
+  bool tracetime;                 /* include timestamp? */
+  int progressmode;               /* CURL_PROGRESS_BAR / CURL_PROGRESS_STATS */
+  char *libcurl;                  /* Output libcurl code to this file name */
+  bool fail_early;                /* exit on first transfer error */
+  struct OperationConfig *first;
+  struct OperationConfig *current;
+  struct OperationConfig *last;   /* Always last in the struct */
+};
+
+void config_init(struct OperationConfig *config);
+void config_free(struct OperationConfig *config);
+
+#endif /* HEADER_CURL_TOOL_CFGABLE_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_convert.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_convert.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_convert.c	(revision 331)
@@ -0,0 +1,150 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#ifdef CURL_DOES_CONVERSIONS
+
+#ifdef HAVE_ICONV
+#  include <iconv.h>
+#endif
+
+#include "tool_convert.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+#ifdef HAVE_ICONV
+
+/* curl tool iconv conversion descriptors */
+static iconv_t inbound_cd  = (iconv_t)-1;
+static iconv_t outbound_cd = (iconv_t)-1;
+
+/* set default codesets for iconv */
+#ifndef CURL_ICONV_CODESET_OF_NETWORK
+#  define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
+#endif
+
+/*
+ * convert_to_network() is a curl tool function to convert
+ * from the host encoding to ASCII on non-ASCII platforms.
+ */
+CURLcode convert_to_network(char *buffer, size_t length)
+{
+  /* translate from the host encoding to the network encoding */
+  char *input_ptr, *output_ptr;
+  size_t res, in_bytes, out_bytes;
+
+  /* open an iconv conversion descriptor if necessary */
+  if(outbound_cd == (iconv_t)-1) {
+    outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
+                             CURL_ICONV_CODESET_OF_HOST);
+    if(outbound_cd == (iconv_t)-1) {
+      return CURLE_CONV_FAILED;
+    }
+  }
+  /* call iconv */
+  input_ptr = output_ptr = buffer;
+  in_bytes = out_bytes = length;
+  res = iconv(outbound_cd, &input_ptr,  &in_bytes,
+              &output_ptr, &out_bytes);
+  if((res == (size_t)-1) || (in_bytes != 0)) {
+    return CURLE_CONV_FAILED;
+  }
+
+  return CURLE_OK;
+}
+
+/*
+ * convert_from_network() is a curl tool function
+ * for performing ASCII conversions on non-ASCII platforms.
+ */
+CURLcode convert_from_network(char *buffer, size_t length)
+{
+  /* translate from the network encoding to the host encoding */
+  char *input_ptr, *output_ptr;
+  size_t res, in_bytes, out_bytes;
+
+  /* open an iconv conversion descriptor if necessary */
+  if(inbound_cd == (iconv_t)-1) {
+    inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
+                            CURL_ICONV_CODESET_OF_NETWORK);
+    if(inbound_cd == (iconv_t)-1) {
+      return CURLE_CONV_FAILED;
+    }
+  }
+  /* call iconv */
+  input_ptr = output_ptr = buffer;
+  in_bytes = out_bytes = length;
+  res = iconv(inbound_cd, &input_ptr,  &in_bytes,
+              &output_ptr, &out_bytes);
+  if((res == (size_t)-1) || (in_bytes != 0)) {
+    return CURLE_CONV_FAILED;
+  }
+
+  return CURLE_OK;
+}
+
+void convert_cleanup(void)
+{
+  /* close iconv conversion descriptors */
+  if(inbound_cd != (iconv_t)-1)
+    (void)iconv_close(inbound_cd);
+  if(outbound_cd != (iconv_t)-1)
+    (void)iconv_close(outbound_cd);
+}
+
+#endif /* HAVE_ICONV */
+
+char convert_char(curl_infotype infotype, char this_char)
+{
+/* determine how this specific character should be displayed */
+  switch(infotype) {
+  case CURLINFO_DATA_IN:
+  case CURLINFO_DATA_OUT:
+  case CURLINFO_SSL_DATA_IN:
+  case CURLINFO_SSL_DATA_OUT:
+    /* data, treat as ASCII */
+    if((this_char >= 0x20) && (this_char < 0x7f)) {
+      /* printable ASCII hex value: convert to host encoding */
+      (void)convert_from_network(&this_char, 1);
+    }
+    else {
+      /* non-printable ASCII, use a replacement character */
+      return UNPRINTABLE_CHAR;
+    }
+    /* fall through to default */
+  default:
+    /* treat as host encoding */
+    if(ISPRINT(this_char)
+       &&  (this_char != '\t')
+       &&  (this_char != '\r')
+       &&  (this_char != '\n')) {
+      /* printable characters excluding tabs and line end characters */
+      return this_char;
+    }
+    break;
+  }
+  /* non-printable, use a replacement character  */
+  return UNPRINTABLE_CHAR;
+}
+
+#endif /* CURL_DOES_CONVERSIONS */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_convert.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_convert.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_convert.h	(revision 331)
@@ -0,0 +1,45 @@
+#ifndef HEADER_CURL_TOOL_CONVERT_H
+#define HEADER_CURL_TOOL_CONVERT_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#ifdef CURL_DOES_CONVERSIONS
+
+#ifdef HAVE_ICONV
+
+CURLcode convert_to_network(char *buffer, size_t length);
+CURLcode convert_from_network(char *buffer, size_t length);
+void convert_cleanup(void);
+
+#endif /* HAVE_ICONV */
+
+char convert_char(curl_infotype infotype, char this_char);
+
+#endif /* CURL_DOES_CONVERSIONS */
+
+#if !defined(CURL_DOES_CONVERSIONS) || !defined(HAVE_ICONV)
+#define convert_cleanup() Curl_nop_stmt
+#endif
+
+#endif /* HEADER_CURL_TOOL_CONVERT_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_dirhie.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_dirhie.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_dirhie.c	(revision 331)
@@ -0,0 +1,158 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#include <sys/stat.h>
+
+#ifdef WIN32
+#  include <direct.h>
+#endif
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_dirhie.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+#ifdef NETWARE
+#  ifndef __NOVELL_LIBC__
+#    define mkdir mkdir_510
+#  endif
+#endif
+
+#ifdef WIN32
+#  define mkdir(x,y) (mkdir)((x))
+#  ifndef __POCC__
+#    define F_OK 0
+#  endif
+#endif
+
+static void show_dir_errno(FILE *errors, const char *name)
+{
+  switch(errno) {
+#ifdef EACCES
+  case EACCES:
+    fprintf(errors, "You don't have permission to create %s.\n", name);
+    break;
+#endif
+#ifdef ENAMETOOLONG
+  case ENAMETOOLONG:
+    fprintf(errors, "The directory name %s is too long.\n", name);
+    break;
+#endif
+#ifdef EROFS
+  case EROFS:
+    fprintf(errors, "%s resides on a read-only file system.\n", name);
+    break;
+#endif
+#ifdef ENOSPC
+  case ENOSPC:
+    fprintf(errors, "No space left on the file system that will "
+            "contain the directory %s.\n", name);
+    break;
+#endif
+#ifdef EDQUOT
+  case EDQUOT:
+    fprintf(errors, "Cannot create directory %s because you "
+            "exceeded your quota.\n", name);
+    break;
+#endif
+  default :
+    fprintf(errors, "Error creating directory %s.\n", name);
+    break;
+  }
+}
+
+/*
+ * Create the needed directory hierarchy recursively in order to save
+ *  multi-GETs in file output, ie:
+ *  curl "http://my.site/dir[1-5]/file[1-5].txt" -o "dir#1/file#2.txt"
+ *  should create all the dir* automagically
+ */
+
+#ifdef WIN32
+/* systems that may use either or when specifying a path */
+#define PATH_DELIMITERS "\\/"
+#else
+#define PATH_DELIMITERS DIR_CHAR
+#endif
+
+
+CURLcode create_dir_hierarchy(const char *outfile, FILE *errors)
+{
+  char *tempdir;
+  char *tempdir2;
+  char *outdup;
+  char *dirbuildup;
+  CURLcode result = CURLE_OK;
+  size_t outlen;
+
+  outlen = strlen(outfile);
+  outdup = strdup(outfile);
+  if(!outdup)
+    return CURLE_OUT_OF_MEMORY;
+
+  dirbuildup = malloc(outlen + 1);
+  if(!dirbuildup) {
+    Curl_safefree(outdup);
+    return CURLE_OUT_OF_MEMORY;
+  }
+  dirbuildup[0] = '\0';
+
+  /* Allow strtok() here since this isn't used threaded */
+  /* !checksrc! disable BANNEDFUNC 2 */
+  tempdir = strtok(outdup, PATH_DELIMITERS);
+
+  while(tempdir != NULL) {
+    tempdir2 = strtok(NULL, PATH_DELIMITERS);
+    /* since strtok returns a token for the last word even
+       if not ending with DIR_CHAR, we need to prune it */
+    if(tempdir2 != NULL) {
+      size_t dlen = strlen(dirbuildup);
+      if(dlen)
+        snprintf(&dirbuildup[dlen], outlen - dlen, "%s%s", DIR_CHAR, tempdir);
+      else {
+        if(outdup == tempdir)
+          /* the output string doesn't start with a separator */
+          strcpy(dirbuildup, tempdir);
+        else
+          snprintf(dirbuildup, outlen, "%s%s", DIR_CHAR, tempdir);
+      }
+      if(access(dirbuildup, F_OK) == -1) {
+        if(-1 == mkdir(dirbuildup, (mode_t)0000750)) {
+          show_dir_errno(errors, dirbuildup);
+          result = CURLE_WRITE_ERROR;
+          break; /* get out of loop */
+        }
+      }
+    }
+    tempdir = tempdir2;
+  }
+
+  Curl_safefree(dirbuildup);
+  Curl_safefree(outdup);
+
+  return result;
+}
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_dirhie.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_dirhie.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_dirhie.h	(revision 331)
@@ -0,0 +1,29 @@
+#ifndef HEADER_CURL_TOOL_DIRHIE_H
+#define HEADER_CURL_TOOL_DIRHIE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+CURLcode create_dir_hierarchy(const char *outfile, FILE *errors);
+
+#endif /* HEADER_CURL_TOOL_DIRHIE_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_doswin.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_doswin.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_doswin.c	(revision 331)
@@ -0,0 +1,668 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#if defined(MSDOS) || defined(WIN32)
+
+#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME)
+#  include <libgen.h>
+#endif
+
+#ifdef WIN32
+#  include "tool_cfgable.h"
+#  include "tool_libinfo.h"
+#endif
+
+#include "tool_bname.h"
+#include "tool_doswin.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+/*
+ * Macros ALWAYS_TRUE and ALWAYS_FALSE are used to avoid compiler warnings.
+ */
+
+#define ALWAYS_TRUE   (1)
+#define ALWAYS_FALSE  (0)
+
+#if defined(_MSC_VER) && !defined(__POCC__)
+#  undef ALWAYS_TRUE
+#  undef ALWAYS_FALSE
+#  if (_MSC_VER < 1500)
+#    define ALWAYS_TRUE   (0, 1)
+#    define ALWAYS_FALSE  (1, 0)
+#  else
+#    define ALWAYS_TRUE \
+__pragma(warning(push)) \
+__pragma(warning(disable:4127)) \
+(1) \
+__pragma(warning(pop))
+#    define ALWAYS_FALSE \
+__pragma(warning(push)) \
+__pragma(warning(disable:4127)) \
+(0) \
+__pragma(warning(pop))
+#  endif
+#endif
+
+#ifdef WIN32
+#  undef  PATH_MAX
+#  define PATH_MAX MAX_PATH
+#endif
+
+#ifndef S_ISCHR
+#  ifdef S_IFCHR
+#    define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#  else
+#    define S_ISCHR(m) (0) /* cannot tell if file is a device */
+#  endif
+#endif
+
+#ifdef WIN32
+#  define _use_lfn(f) ALWAYS_TRUE   /* long file names always available */
+#elif !defined(__DJGPP__) || (__DJGPP__ < 2)  /* DJGPP 2.0 has _use_lfn() */
+#  define _use_lfn(f) ALWAYS_FALSE  /* long file names never available */
+#elif defined(__DJGPP__)
+#  include <fcntl.h>                /* _use_lfn(f) prototype */
+#endif
+
+#ifndef UNITTESTS
+static SANITIZEcode truncate_dryrun(const char *path,
+                                    const size_t truncate_pos);
+#ifdef MSDOS
+static SANITIZEcode msdosify(char **const sanitized, const char *file_name,
+                             int flags);
+#endif
+static SANITIZEcode rename_if_reserved_dos_device_name(char **const sanitized,
+                                                       const char *file_name,
+                                                       int flags);
+#endif /* !UNITTESTS (static declarations used if no unit tests) */
+
+
+/*
+Sanitize a file or path name.
+
+All banned characters are replaced by underscores, for example:
+f?*foo => f__foo
+f:foo::$DATA => f_foo__$DATA
+f:\foo:bar => f__foo_bar
+f:\foo:bar => f:\foo:bar   (flag SANITIZE_ALLOW_PATH)
+
+This function was implemented according to the guidelines in 'Naming Files,
+Paths, and Namespaces' section 'Naming Conventions'.
+https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx
+
+Flags
+-----
+SANITIZE_ALLOW_COLONS:     Allow colons.
+Without this flag colons are sanitized.
+
+SANITIZE_ALLOW_PATH:       Allow path separators and colons.
+Without this flag path separators and colons are sanitized.
+
+SANITIZE_ALLOW_RESERVED:   Allow reserved device names.
+Without this flag a reserved device name is renamed (COM1 => _COM1) unless it's
+in a UNC prefixed path.
+
+SANITIZE_ALLOW_TRUNCATE:   Allow truncating a long filename.
+Without this flag if the sanitized filename or path will be too long an error
+occurs. With this flag the filename --and not any other parts of the path-- may
+be truncated to at least a single character. A filename followed by an
+alternate data stream (ADS) cannot be truncated in any case.
+
+Success: (SANITIZE_ERR_OK) *sanitized points to a sanitized copy of file_name.
+Failure: (!= SANITIZE_ERR_OK) *sanitized is NULL.
+*/
+SANITIZEcode sanitize_file_name(char **const sanitized, const char *file_name,
+                                int flags)
+{
+  char *p, *target;
+  size_t len;
+  SANITIZEcode sc;
+  size_t max_sanitized_len;
+
+  if(!sanitized)
+    return SANITIZE_ERR_BAD_ARGUMENT;
+
+  *sanitized = NULL;
+
+  if(!file_name)
+    return SANITIZE_ERR_BAD_ARGUMENT;
+
+  if((flags & SANITIZE_ALLOW_PATH)) {
+#ifndef MSDOS
+    if(file_name[0] == '\\' && file_name[1] == '\\')
+      /* UNC prefixed path \\ (eg \\?\C:\foo) */
+      max_sanitized_len = 32767-1;
+    else
+#endif
+      max_sanitized_len = PATH_MAX-1;
+  }
+  else
+    /* The maximum length of a filename.
+       FILENAME_MAX is often the same as PATH_MAX, in other words it is 260 and
+       does not discount the path information therefore we shouldn't use it. */
+    max_sanitized_len = (PATH_MAX-1 > 255) ? 255 : PATH_MAX-1;
+
+  len = strlen(file_name);
+  if(len > max_sanitized_len) {
+    if(!(flags & SANITIZE_ALLOW_TRUNCATE) ||
+       truncate_dryrun(file_name, max_sanitized_len))
+      return SANITIZE_ERR_INVALID_PATH;
+
+    len = max_sanitized_len;
+  }
+
+  target = malloc(len + 1);
+  if(!target)
+    return SANITIZE_ERR_OUT_OF_MEMORY;
+
+  strncpy(target, file_name, len);
+  target[len] = '\0';
+
+#ifndef MSDOS
+  if((flags & SANITIZE_ALLOW_PATH) && !strncmp(target, "\\\\?\\", 4))
+    /* Skip the literal path prefix \\?\ */
+    p = target + 4;
+  else
+#endif
+    p = target;
+
+  /* replace control characters and other banned characters */
+  for(; *p; ++p) {
+    const char *banned;
+
+    if((1 <= *p && *p <= 31) ||
+       (!(flags & (SANITIZE_ALLOW_COLONS|SANITIZE_ALLOW_PATH)) && *p == ':') ||
+       (!(flags & SANITIZE_ALLOW_PATH) && (*p == '/' || *p == '\\'))) {
+      *p = '_';
+      continue;
+    }
+
+    for(banned = "|<>\"?*"; *banned; ++banned) {
+      if(*p == *banned) {
+        *p = '_';
+        break;
+      }
+    }
+  }
+
+  /* remove trailing spaces and periods if not allowing paths */
+  if(!(flags & SANITIZE_ALLOW_PATH) && len) {
+    char *clip = NULL;
+
+    p = &target[len];
+    do {
+      --p;
+      if(*p != ' ' && *p != '.')
+        break;
+      clip = p;
+    } while(p != target);
+
+    if(clip) {
+      *clip = '\0';
+      len = clip - target;
+    }
+  }
+
+#ifdef MSDOS
+  sc = msdosify(&p, target, flags);
+  free(target);
+  if(sc)
+    return sc;
+  target = p;
+  len = strlen(target);
+
+  if(len > max_sanitized_len) {
+    free(target);
+    return SANITIZE_ERR_INVALID_PATH;
+  }
+#endif
+
+  if(!(flags & SANITIZE_ALLOW_RESERVED)) {
+    sc = rename_if_reserved_dos_device_name(&p, target, flags);
+    free(target);
+    if(sc)
+      return sc;
+    target = p;
+    len = strlen(target);
+
+    if(len > max_sanitized_len) {
+      free(target);
+      return SANITIZE_ERR_INVALID_PATH;
+    }
+  }
+
+  *sanitized = target;
+  return SANITIZE_ERR_OK;
+}
+
+
+/*
+Test if truncating a path to a file will leave at least a single character in
+the filename. Filenames suffixed by an alternate data stream can't be
+truncated. This performs a dry run, nothing is modified.
+
+Good truncate_pos 9:    C:\foo\bar  =>  C:\foo\ba
+Good truncate_pos 6:    C:\foo      =>  C:\foo
+Good truncate_pos 5:    C:\foo      =>  C:\fo
+Bad* truncate_pos 5:    C:foo       =>  C:foo
+Bad truncate_pos 5:     C:\foo:ads  =>  C:\fo
+Bad truncate_pos 9:     C:\foo:ads  =>  C:\foo:ad
+Bad truncate_pos 5:     C:\foo\bar  =>  C:\fo
+Bad truncate_pos 5:     C:\foo\     =>  C:\fo
+Bad truncate_pos 7:     C:\foo\     =>  C:\foo\
+Error truncate_pos 7:   C:\foo      =>  (pos out of range)
+Bad truncate_pos 1:     C:\foo\     =>  C
+
+* C:foo is ambiguous, C could end up being a drive or file therefore something
+  like C:superlongfilename can't be truncated.
+
+Returns
+SANITIZE_ERR_OK: Good -- 'path' can be truncated
+SANITIZE_ERR_INVALID_PATH: Bad -- 'path' cannot be truncated
+!= SANITIZE_ERR_OK && != SANITIZE_ERR_INVALID_PATH: Error
+*/
+SANITIZEcode truncate_dryrun(const char *path, const size_t truncate_pos)
+{
+  size_t len;
+
+  if(!path)
+    return SANITIZE_ERR_BAD_ARGUMENT;
+
+  len = strlen(path);
+
+  if(truncate_pos > len)
+    return SANITIZE_ERR_BAD_ARGUMENT;
+
+  if(!len || !truncate_pos)
+    return SANITIZE_ERR_INVALID_PATH;
+
+  if(strpbrk(&path[truncate_pos - 1], "\\/:"))
+    return SANITIZE_ERR_INVALID_PATH;
+
+  /* C:\foo can be truncated but C:\foo:ads can't */
+  if(truncate_pos > 1) {
+    const char *p = &path[truncate_pos - 1];
+    do {
+      --p;
+      if(*p == ':')
+        return SANITIZE_ERR_INVALID_PATH;
+    } while(p != path && *p != '\\' && *p != '/');
+  }
+
+  return SANITIZE_ERR_OK;
+}
+
+/* The functions msdosify, rename_if_dos_device_name and __crt0_glob_function
+ * were taken with modification from the DJGPP port of tar 1.12. They use
+ * algorithms originally from DJTAR.
+ */
+
+/*
+Extra sanitization MSDOS for file_name.
+
+This is a supporting function for sanitize_file_name.
+
+Warning: This is an MSDOS legacy function and was purposely written in a way
+that some path information may pass through. For example drive letter names
+(C:, D:, etc) are allowed to pass through. For sanitizing a filename use
+sanitize_file_name.
+
+Success: (SANITIZE_ERR_OK) *sanitized points to a sanitized copy of file_name.
+Failure: (!= SANITIZE_ERR_OK) *sanitized is NULL.
+*/
+#if defined(MSDOS) || defined(UNITTESTS)
+SANITIZEcode msdosify(char **const sanitized, const char *file_name,
+                      int flags)
+{
+  char dos_name[PATH_MAX];
+  static const char illegal_chars_dos[] = ".+, ;=[]" /* illegal in DOS */
+    "|<>/\\\":?*"; /* illegal in DOS & W95 */
+  static const char *illegal_chars_w95 = &illegal_chars_dos[8];
+  int idx, dot_idx;
+  const char *s = file_name;
+  char *d = dos_name;
+  const char *const dlimit = dos_name + sizeof(dos_name) - 1;
+  const char *illegal_aliens = illegal_chars_dos;
+  size_t len = sizeof(illegal_chars_dos) - 1;
+
+  if(!sanitized)
+    return SANITIZE_ERR_BAD_ARGUMENT;
+
+  *sanitized = NULL;
+
+  if(!file_name)
+    return SANITIZE_ERR_BAD_ARGUMENT;
+
+  if(strlen(file_name) > PATH_MAX-1 &&
+     (!(flags & SANITIZE_ALLOW_TRUNCATE) ||
+      truncate_dryrun(file_name, PATH_MAX-1)))
+    return SANITIZE_ERR_INVALID_PATH;
+
+  /* Support for Windows 9X VFAT systems, when available. */
+  if(_use_lfn(file_name)) {
+    illegal_aliens = illegal_chars_w95;
+    len -= (illegal_chars_w95 - illegal_chars_dos);
+  }
+
+  /* Get past the drive letter, if any. */
+  if(s[0] >= 'A' && s[0] <= 'z' && s[1] == ':') {
+    *d++ = *s++;
+    *d = ((flags & (SANITIZE_ALLOW_COLONS|SANITIZE_ALLOW_PATH))) ? ':' : '_';
+    ++d, ++s;
+  }
+
+  for(idx = 0, dot_idx = -1; *s && d < dlimit; s++, d++) {
+    if(memchr(illegal_aliens, *s, len)) {
+
+      if((flags & (SANITIZE_ALLOW_COLONS|SANITIZE_ALLOW_PATH)) && *s == ':')
+        *d = ':';
+      else if((flags & SANITIZE_ALLOW_PATH) && (*s == '/' || *s == '\\'))
+        *d = *s;
+      /* Dots are special: DOS doesn't allow them as the leading character,
+         and a file name cannot have more than a single dot.  We leave the
+         first non-leading dot alone, unless it comes too close to the
+         beginning of the name: we want sh.lex.c to become sh_lex.c, not
+         sh.lex-c.  */
+      else if(*s == '.') {
+        if((flags & SANITIZE_ALLOW_PATH) && idx == 0 &&
+           (s[1] == '/' || s[1] == '\\' ||
+            (s[1] == '.' && (s[2] == '/' || s[2] == '\\')))) {
+          /* Copy "./" and "../" verbatim.  */
+          *d++ = *s++;
+          if(d == dlimit)
+            break;
+          if(*s == '.') {
+            *d++ = *s++;
+            if(d == dlimit)
+              break;
+          }
+          *d = *s;
+        }
+        else if(idx == 0)
+          *d = '_';
+        else if(dot_idx >= 0) {
+          if(dot_idx < 5) { /* 5 is a heuristic ad-hoc'ery */
+            d[dot_idx - idx] = '_'; /* replace previous dot */
+            *d = '.';
+          }
+          else
+            *d = '-';
+        }
+        else
+          *d = '.';
+
+        if(*s == '.')
+          dot_idx = idx;
+      }
+      else if(*s == '+' && s[1] == '+') {
+        if(idx - 2 == dot_idx) { /* .c++, .h++ etc. */
+          *d++ = 'x';
+          if(d == dlimit)
+            break;
+          *d   = 'x';
+        }
+        else {
+          /* libg++ etc.  */
+          if(dlimit - d < 4) {
+            *d++ = 'x';
+            if(d == dlimit)
+              break;
+            *d   = 'x';
+          }
+          else {
+            memcpy(d, "plus", 4);
+            d += 3;
+          }
+        }
+        s++;
+        idx++;
+      }
+      else
+        *d = '_';
+    }
+    else
+      *d = *s;
+    if(*s == '/' || *s == '\\') {
+      idx = 0;
+      dot_idx = -1;
+    }
+    else
+      idx++;
+  }
+  *d = '\0';
+
+  if(*s) {
+    /* dos_name is truncated, check that truncation requirements are met,
+       specifically truncating a filename suffixed by an alternate data stream
+       or truncating the entire filename is not allowed. */
+    if(!(flags & SANITIZE_ALLOW_TRUNCATE) || strpbrk(s, "\\/:") ||
+       truncate_dryrun(dos_name, d - dos_name))
+      return SANITIZE_ERR_INVALID_PATH;
+  }
+
+  *sanitized = strdup(dos_name);
+  return (*sanitized ? SANITIZE_ERR_OK : SANITIZE_ERR_OUT_OF_MEMORY);
+}
+#endif /* MSDOS || UNITTESTS */
+
+/*
+Rename file_name if it's a reserved dos device name.
+
+This is a supporting function for sanitize_file_name.
+
+Warning: This is an MSDOS legacy function and was purposely written in a way
+that some path information may pass through. For example drive letter names
+(C:, D:, etc) are allowed to pass through. For sanitizing a filename use
+sanitize_file_name.
+
+Success: (SANITIZE_ERR_OK) *sanitized points to a sanitized copy of file_name.
+Failure: (!= SANITIZE_ERR_OK) *sanitized is NULL.
+*/
+SANITIZEcode rename_if_reserved_dos_device_name(char **const sanitized,
+                                                const char *file_name,
+                                                int flags)
+{
+  /* We could have a file whose name is a device on MS-DOS.  Trying to
+   * retrieve such a file would fail at best and wedge us at worst.  We need
+   * to rename such files. */
+  char *p, *base;
+  char fname[PATH_MAX];
+#ifdef MSDOS
+  struct_stat st_buf;
+#endif
+
+  if(!sanitized)
+    return SANITIZE_ERR_BAD_ARGUMENT;
+
+  *sanitized = NULL;
+
+  if(!file_name)
+    return SANITIZE_ERR_BAD_ARGUMENT;
+
+  /* Ignore UNC prefixed paths, they are allowed to contain a reserved name. */
+#ifndef MSDOS
+  if((flags & SANITIZE_ALLOW_PATH) &&
+     file_name[0] == '\\' && file_name[1] == '\\') {
+    size_t len = strlen(file_name);
+    *sanitized = malloc(len + 1);
+    if(!*sanitized)
+      return SANITIZE_ERR_OUT_OF_MEMORY;
+    strncpy(*sanitized, file_name, len + 1);
+    return SANITIZE_ERR_OK;
+  }
+#endif
+
+  if(strlen(file_name) > PATH_MAX-1 &&
+     (!(flags & SANITIZE_ALLOW_TRUNCATE) ||
+      truncate_dryrun(file_name, PATH_MAX-1)))
+    return SANITIZE_ERR_INVALID_PATH;
+
+  strncpy(fname, file_name, PATH_MAX-1);
+  fname[PATH_MAX-1] = '\0';
+  base = basename(fname);
+
+  /* Rename reserved device names that are known to be accessible without \\.\
+     Examples: CON => _CON, CON.EXT => CON_EXT, CON:ADS => CON_ADS
+     https://support.microsoft.com/en-us/kb/74496
+     https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx
+     */
+  for(p = fname; p; p = (p == fname && fname != base ? base : NULL)) {
+    size_t p_len;
+    int x = (curl_strnequal(p, "CON", 3) ||
+             curl_strnequal(p, "PRN", 3) ||
+             curl_strnequal(p, "AUX", 3) ||
+             curl_strnequal(p, "NUL", 3)) ? 3 :
+            (curl_strnequal(p, "CLOCK$", 6)) ? 6 :
+            (curl_strnequal(p, "COM", 3) || curl_strnequal(p, "LPT", 3)) ?
+              (('1' <= p[3] && p[3] <= '9') ? 4 : 3) : 0;
+
+    if(!x)
+      continue;
+
+    /* the devices may be accessible with an extension or ADS, for
+       example CON.AIR and 'CON . AIR' and CON:AIR access console */
+
+    for(; p[x] == ' '; ++x)
+      ;
+
+    if(p[x] == '.') {
+      p[x] = '_';
+      continue;
+    }
+    else if(p[x] == ':') {
+      if(!(flags & (SANITIZE_ALLOW_COLONS|SANITIZE_ALLOW_PATH))) {
+        p[x] = '_';
+        continue;
+      }
+      ++x;
+    }
+    else if(p[x]) /* no match */
+      continue;
+
+    /* p points to 'CON' or 'CON ' or 'CON:', etc */
+    p_len = strlen(p);
+
+    /* Prepend a '_' */
+    if(strlen(fname) == PATH_MAX-1) {
+      --p_len;
+      if(!(flags & SANITIZE_ALLOW_TRUNCATE) || truncate_dryrun(p, p_len))
+        return SANITIZE_ERR_INVALID_PATH;
+      p[p_len] = '\0';
+    }
+    memmove(p + 1, p, p_len + 1);
+    p[0] = '_';
+    ++p_len;
+
+    /* if fname was just modified then the basename pointer must be updated */
+    if(p == fname)
+      base = basename(fname);
+  }
+
+  /* This is the legacy portion from rename_if_dos_device_name that checks for
+     reserved device names. It only works on MSDOS. On Windows XP the stat
+     check errors with EINVAL if the device name is reserved. On Windows
+     Vista/7/8 it sets mode S_IFREG (regular file or device). According to MSDN
+     stat doc the latter behavior is correct, but that doesn't help us identify
+     whether it's a reserved device name and not a regular file name. */
+#ifdef MSDOS
+  if(base && ((stat(base, &st_buf)) == 0) && (S_ISCHR(st_buf.st_mode))) {
+    /* Prepend a '_' */
+    size_t blen = strlen(base);
+    if(blen) {
+      if(strlen(fname) == PATH_MAX-1) {
+        --blen;
+        if(!(flags & SANITIZE_ALLOW_TRUNCATE) || truncate_dryrun(base, blen))
+          return SANITIZE_ERR_INVALID_PATH;
+        base[blen] = '\0';
+      }
+      memmove(base + 1, base, blen + 1);
+      base[0] = '_';
+      ++blen;
+    }
+  }
+#endif
+
+  *sanitized = strdup(fname);
+  return (*sanitized ? SANITIZE_ERR_OK : SANITIZE_ERR_OUT_OF_MEMORY);
+}
+
+#if defined(MSDOS) && (defined(__DJGPP__) || defined(__GO32__))
+
+/*
+ * Disable program default argument globbing. We do it on our own.
+ */
+char **__crt0_glob_function(char *arg)
+{
+  (void)arg;
+  return (char **)0;
+}
+
+#endif /* MSDOS && (__DJGPP__ || __GO32__) */
+
+#ifdef WIN32
+
+/*
+ * Function to find CACert bundle on a Win32 platform using SearchPath.
+ * (SearchPath is already declared via inclusions done in setup header file)
+ * (Use the ASCII version instead of the unicode one!)
+ * The order of the directories it searches is:
+ *  1. application's directory
+ *  2. current working directory
+ *  3. Windows System directory (e.g. C:\windows\system32)
+ *  4. Windows Directory (e.g. C:\windows)
+ *  5. all directories along %PATH%
+ *
+ * For WinXP and later search order actually depends on registry value:
+ * HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\SafeProcessSearchMode
+ */
+
+CURLcode FindWin32CACert(struct OperationConfig *config,
+                         const char *bundle_file)
+{
+  CURLcode result = CURLE_OK;
+
+  /* search and set cert file only if libcurl supports SSL */
+  if(curlinfo->features & CURL_VERSION_SSL) {
+
+    DWORD res_len;
+    char buf[PATH_MAX];
+    char *ptr = NULL;
+
+    buf[0] = '\0';
+
+    res_len = SearchPathA(NULL, bundle_file, NULL, PATH_MAX, buf, &ptr);
+    if(res_len > 0) {
+      Curl_safefree(config->cacert);
+      config->cacert = strdup(buf);
+      if(!config->cacert)
+        result = CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  return result;
+}
+
+#endif /* WIN32 */
+
+#endif /* MSDOS || WIN32 */
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_doswin.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_doswin.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_doswin.h	(revision 331)
@@ -0,0 +1,68 @@
+#ifndef HEADER_CURL_TOOL_DOSWIN_H
+#define HEADER_CURL_TOOL_DOSWIN_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#if defined(MSDOS) || defined(WIN32)
+
+#define SANITIZE_ALLOW_COLONS    (1<<0)  /* Allow colons */
+#define SANITIZE_ALLOW_PATH      (1<<1)  /* Allow path separators and colons */
+#define SANITIZE_ALLOW_RESERVED  (1<<2)  /* Allow reserved device names */
+#define SANITIZE_ALLOW_TRUNCATE  (1<<3)  /* Allow truncating a long filename */
+
+typedef enum {
+  SANITIZE_ERR_OK = 0,           /* 0 - OK */
+  SANITIZE_ERR_INVALID_PATH,     /* 1 - the path is invalid */
+  SANITIZE_ERR_BAD_ARGUMENT,     /* 2 - bad function parameter */
+  SANITIZE_ERR_OUT_OF_MEMORY,    /* 3 - out of memory */
+  SANITIZE_ERR_LAST /* never use! */
+} SANITIZEcode;
+
+SANITIZEcode sanitize_file_name(char **const sanitized, const char *file_name,
+                                int flags);
+#ifdef UNITTESTS
+SANITIZEcode truncate_dryrun(const char *path, const size_t truncate_pos);
+SANITIZEcode msdosify(char **const sanitized, const char *file_name,
+                      int flags);
+SANITIZEcode rename_if_reserved_dos_device_name(char **const sanitized,
+                                                const char *file_name,
+                                                int flags);
+#endif /* UNITTESTS */
+
+#if defined(MSDOS) && (defined(__DJGPP__) || defined(__GO32__))
+
+char **__crt0_glob_function(char *arg);
+
+#endif /* MSDOS && (__DJGPP__ || __GO32__) */
+
+#ifdef WIN32
+
+CURLcode FindWin32CACert(struct OperationConfig *config,
+                         const char *bundle_file);
+
+#endif /* WIN32 */
+
+#endif /* MSDOS || WIN32 */
+
+#endif /* HEADER_CURL_TOOL_DOSWIN_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_easysrc.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_easysrc.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_easysrc.c	(revision 331)
@@ -0,0 +1,236 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#include "slist_wc.h"
+
+#ifndef CURL_DISABLE_LIBCURL_OPTION
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_cfgable.h"
+#include "tool_easysrc.h"
+#include "tool_msgs.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+/* global variable definitions, for easy-interface source code generation */
+
+struct slist_wc *easysrc_decl = NULL; /* Variable declarations */
+struct slist_wc *easysrc_data = NULL; /* Build slists, forms etc. */
+struct slist_wc *easysrc_code = NULL; /* Setopt calls */
+struct slist_wc *easysrc_toohard = NULL; /* Unconvertible setopt */
+struct slist_wc *easysrc_clean = NULL;  /* Clean up allocated data */
+int easysrc_mime_count = 0;
+int easysrc_slist_count = 0;
+
+static const char *const srchead[]={
+  "/********* Sample code generated by the curl command line tool **********",
+  " * All curl_easy_setopt() options are documented at:",
+  " * https://curl.haxx.se/libcurl/c/curl_easy_setopt.html",
+  " ************************************************************************/",
+  "#include <curl/curl.h>",
+  "",
+  "int main(int argc, char *argv[])",
+  "{",
+  "  CURLcode ret;",
+  "  CURL *hnd;",
+  NULL
+};
+/* easysrc_decl declarations come here */
+/* easysrc_data initialisations come here */
+/* easysrc_code statements come here */
+static const char *const srchard[]={
+  "/* Here is a list of options the curl code used that cannot get generated",
+  "   as source easily. You may select to either not use them or implement",
+  "   them yourself.",
+  "",
+  NULL
+};
+static const char *const srcend[]={
+  "",
+  "  return (int)ret;",
+  "}",
+  "/**** End of sample code ****/",
+  NULL
+};
+
+/* Clean up all source code if we run out of memory */
+static void easysrc_free(void)
+{
+  slist_wc_free_all(easysrc_decl);
+  easysrc_decl = NULL;
+  slist_wc_free_all(easysrc_data);
+  easysrc_data = NULL;
+  slist_wc_free_all(easysrc_code);
+  easysrc_code = NULL;
+  slist_wc_free_all(easysrc_toohard);
+  easysrc_toohard = NULL;
+  slist_wc_free_all(easysrc_clean);
+  easysrc_clean = NULL;
+}
+
+/* Add a source line to the main code or remarks */
+CURLcode easysrc_add(struct slist_wc **plist, const char *line)
+{
+  CURLcode ret = CURLE_OK;
+  struct slist_wc *list = slist_wc_append(*plist, line);
+  if(!list) {
+    easysrc_free();
+    ret = CURLE_OUT_OF_MEMORY;
+  }
+  else
+    *plist = list;
+  return ret;
+}
+
+CURLcode easysrc_addf(struct slist_wc **plist, const char *fmt, ...)
+{
+  CURLcode ret;
+  char *bufp;
+  va_list ap;
+  va_start(ap, fmt);
+  bufp = curlx_mvaprintf(fmt, ap);
+  va_end(ap);
+  if(! bufp) {
+    ret = CURLE_OUT_OF_MEMORY;
+  }
+  else {
+    ret = easysrc_add(plist, bufp);
+    curl_free(bufp);
+  }
+  return ret;
+}
+
+#define CHKRET(v) do {CURLcode ret = (v); if(ret) return ret;} WHILE_FALSE
+
+CURLcode easysrc_init(void)
+{
+  CHKRET(easysrc_add(&easysrc_code,
+                     "hnd = curl_easy_init();"));
+  return CURLE_OK;
+}
+
+CURLcode easysrc_perform(void)
+{
+  /* Note any setopt calls which we could not convert */
+  if(easysrc_toohard) {
+    int i;
+    struct curl_slist *ptr;
+    const char *c;
+    CHKRET(easysrc_add(&easysrc_code, ""));
+    /* Preamble comment */
+    for(i = 0; ((c = srchard[i]) != NULL); i++)
+      CHKRET(easysrc_add(&easysrc_code, c));
+    /* Each unconverted option */
+    if(easysrc_toohard) {
+      for(ptr = easysrc_toohard->first; ptr; ptr = ptr->next)
+        CHKRET(easysrc_add(&easysrc_code, ptr->data));
+    }
+    CHKRET(easysrc_add(&easysrc_code, ""));
+    CHKRET(easysrc_add(&easysrc_code, "*/"));
+
+    slist_wc_free_all(easysrc_toohard);
+    easysrc_toohard = NULL;
+  }
+
+  CHKRET(easysrc_add(&easysrc_code, ""));
+  CHKRET(easysrc_add(&easysrc_code, "ret = curl_easy_perform(hnd);"));
+  CHKRET(easysrc_add(&easysrc_code, ""));
+
+  return CURLE_OK;
+}
+
+CURLcode easysrc_cleanup(void)
+{
+  CHKRET(easysrc_add(&easysrc_code, "curl_easy_cleanup(hnd);"));
+  CHKRET(easysrc_add(&easysrc_code, "hnd = NULL;"));
+
+  return CURLE_OK;
+}
+
+void dumpeasysrc(struct GlobalConfig *config)
+{
+  struct curl_slist *ptr;
+  char *o = config->libcurl;
+
+  FILE *out;
+  bool fopened = FALSE;
+  if(strcmp(o, "-")) {
+    out = fopen(o, FOPEN_WRITETEXT);
+    fopened = TRUE;
+  }
+  else
+    out = stdout;
+  if(!out)
+    warnf(config, "Failed to open %s to write libcurl code!\n", o);
+  else {
+    int i;
+    const char *c;
+
+    for(i = 0; ((c = srchead[i]) != NULL); i++)
+      fprintf(out, "%s\n", c);
+
+    /* Declare variables used for complex setopt values */
+    if(easysrc_decl) {
+      for(ptr = easysrc_decl->first; ptr; ptr = ptr->next)
+        fprintf(out, "  %s\n", ptr->data);
+    }
+
+    /* Set up complex values for setopt calls */
+    if(easysrc_data) {
+      fprintf(out, "\n");
+
+      for(ptr = easysrc_data->first; ptr; ptr = ptr->next)
+        fprintf(out, "  %s\n", ptr->data);
+    }
+
+    fprintf(out, "\n");
+    if(easysrc_code) {
+      for(ptr = easysrc_code->first; ptr; ptr = ptr->next) {
+        if(ptr->data[0]) {
+          fprintf(out, "  %s\n", ptr->data);
+        }
+        else {
+          fprintf(out, "\n");
+        }
+      }
+    }
+
+    if(easysrc_clean) {
+      for(ptr = easysrc_clean->first; ptr; ptr = ptr->next)
+        fprintf(out, "  %s\n", ptr->data);
+    }
+
+    for(i = 0; ((c = srcend[i]) != NULL); i++)
+      fprintf(out, "%s\n", c);
+
+    if(fopened)
+      fclose(out);
+  }
+
+  easysrc_free();
+}
+
+#endif /* CURL_DISABLE_LIBCURL_OPTION */
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_easysrc.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_easysrc.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_easysrc.h	(revision 331)
@@ -0,0 +1,49 @@
+#ifndef HEADER_CURL_TOOL_EASYSRC_H
+#define HEADER_CURL_TOOL_EASYSRC_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+#ifndef CURL_DISABLE_LIBCURL_OPTION
+
+/* global variable declarations, for easy-interface source code generation */
+
+extern struct slist_wc *easysrc_decl; /* Variable declarations */
+extern struct slist_wc *easysrc_data; /* Build slists, forms etc. */
+extern struct slist_wc *easysrc_code; /* Setopt calls etc. */
+extern struct slist_wc *easysrc_toohard; /* Unconvertible setopt */
+extern struct slist_wc *easysrc_clean;  /* Clean up (reverse order) */
+
+extern int easysrc_mime_count;  /* Number of curl_mime variables */
+extern int easysrc_slist_count; /* Number of curl_slist variables */
+
+extern CURLcode easysrc_init(void);
+extern CURLcode easysrc_add(struct slist_wc **plist, const char *bupf);
+extern CURLcode easysrc_addf(struct slist_wc **plist,
+                             const char *fmt, ...);
+extern CURLcode easysrc_perform(void);
+extern CURLcode easysrc_cleanup(void);
+
+void dumpeasysrc(struct GlobalConfig *config);
+
+#endif /* CURL_DISABLE_LIBCURL_OPTION */
+
+#endif /* HEADER_CURL_TOOL_EASYSRC_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_formparse.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_formparse.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_formparse.c	(revision 331)
@@ -0,0 +1,864 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#include "mime.h"
+#include "strcase.h"
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_cfgable.h"
+#include "tool_convert.h"
+#include "tool_msgs.h"
+#include "tool_binmode.h"
+#include "tool_getparam.h"
+#include "tool_paramhlp.h"
+#include "tool_formparse.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+/* Stdin parameters. */
+typedef struct {
+  char *data;  /* Memory data. */
+  curl_off_t origin;  /* File read origin offset. */
+  curl_off_t size; /* Data size. */
+  curl_off_t curpos; /* Current read position. */
+}  standard_input;
+
+
+/*
+ * helper function to get a word from form param
+ * after call get_parm_word, str either point to string end
+ * or point to any of end chars.
+ */
+static char *get_param_word(char **str, char **end_pos, char endchar)
+{
+  char *ptr = *str;
+  char *word_begin = NULL;
+  char *ptr2;
+  char *escape = NULL;
+
+  /* the first non-space char is here */
+  word_begin = ptr;
+  if(*ptr == '"') {
+    ++ptr;
+    while(*ptr) {
+      if(*ptr == '\\') {
+        if(ptr[1] == '\\' || ptr[1] == '"') {
+          /* remember the first escape position */
+          if(!escape)
+            escape = ptr;
+          /* skip escape of back-slash or double-quote */
+          ptr += 2;
+          continue;
+        }
+      }
+      if(*ptr == '"') {
+        *end_pos = ptr;
+        if(escape) {
+          /* has escape, we restore the unescaped string here */
+          ptr = ptr2 = escape;
+          do {
+            if(*ptr == '\\' && (ptr[1] == '\\' || ptr[1] == '"'))
+              ++ptr;
+            *ptr2++ = *ptr++;
+          }
+          while(ptr < *end_pos);
+          *end_pos = ptr2;
+        }
+        while(*ptr && *ptr != ';' && *ptr != endchar)
+          ++ptr;
+        *str = ptr;
+        return word_begin + 1;
+      }
+      ++ptr;
+    }
+    /* end quote is missing, treat it as non-quoted. */
+    ptr = word_begin;
+  }
+
+  while(*ptr && *ptr != ';' && *ptr != endchar)
+    ++ptr;
+  *str = *end_pos = ptr;
+  return word_begin;
+}
+
+/* Append slist item and return -1 if failed. */
+static int slist_append(struct curl_slist **plist, const char *data)
+{
+  struct curl_slist *s = curl_slist_append(*plist, data);
+
+  if(!s)
+    return -1;
+
+  *plist = s;
+  return 0;
+}
+
+/* Read headers from a file and append to list. */
+static int read_field_headers(struct OperationConfig *config,
+                              const char *filename, FILE *fp,
+                              struct curl_slist **pheaders)
+{
+  size_t hdrlen = 0;
+  size_t pos = 0;
+  int c;
+  bool incomment = FALSE;
+  int lineno = 1;
+  char hdrbuf[999]; /* Max. header length + 1. */
+
+  for(;;) {
+    c = getc(fp);
+    if(c == EOF || (!pos && !ISSPACE(c))) {
+      /* Strip and flush the current header. */
+      while(hdrlen && ISSPACE(hdrbuf[hdrlen - 1]))
+        hdrlen--;
+      if(hdrlen) {
+        hdrbuf[hdrlen] = '\0';
+        if(slist_append(pheaders, hdrbuf)) {
+          fprintf(config->global->errors,
+                  "Out of memory for field headers!\n");
+          return -1;
+        }
+        hdrlen = 0;
+      }
+    }
+
+    switch(c) {
+    case EOF:
+      if(ferror(fp)) {
+        fprintf(config->global->errors,
+                "Header file %s read error: %s\n", filename, strerror(errno));
+        return -1;
+      }
+      return 0;    /* Done. */
+    case '\r':
+      continue;    /* Ignore. */
+    case '\n':
+      pos = 0;
+      incomment = FALSE;
+      lineno++;
+      continue;
+    case '#':
+      if(!pos)
+        incomment = TRUE;
+      break;
+    }
+
+    pos++;
+    if(!incomment) {
+      if(hdrlen == sizeof hdrbuf - 1) {
+        warnf(config->global, "File %s line %d: header too long (truncated)\n",
+              filename, lineno);
+        c = ' ';
+      }
+      if(hdrlen <= sizeof hdrbuf - 1)
+        hdrbuf[hdrlen++] = (char) c;
+    }
+  }
+  /* NOTREACHED */
+}
+
+static int get_param_part(struct OperationConfig *config, char endchar,
+                          char **str, char **pdata, char **ptype,
+                          char **pfilename, char **pencoder,
+                          struct curl_slist **pheaders)
+{
+  char *p = *str;
+  char *type = NULL;
+  char *filename = NULL;
+  char *encoder = NULL;
+  char *endpos;
+  char *tp;
+  char sep;
+  char type_major[128] = "";
+  char type_minor[128] = "";
+  char *endct = NULL;
+  struct curl_slist *headers = NULL;
+
+  if(ptype)
+    *ptype = NULL;
+  if(pfilename)
+    *pfilename = NULL;
+  if(pheaders)
+    *pheaders = NULL;
+  if(pencoder)
+    *pencoder = NULL;
+  while(ISSPACE(*p))
+    p++;
+  tp = p;
+  *pdata = get_param_word(&p, &endpos, endchar);
+  /* If not quoted, strip trailing spaces. */
+  if(*pdata == tp)
+    while(endpos > *pdata && ISSPACE(endpos[-1]))
+      endpos--;
+  sep = *p;
+  *endpos = '\0';
+  while(sep == ';') {
+    while(ISSPACE(*++p))
+      ;
+
+    if(!endct && checkprefix("type=", p)) {
+      for(p += 5; ISSPACE(*p); p++)
+        ;
+      /* set type pointer */
+      type = p;
+
+      /* verify that this is a fine type specifier */
+      if(2 != sscanf(type, "%127[^/ ]/%127[^;, \n]", type_major, type_minor)) {
+        warnf(config->global, "Illegally formatted content-type field!\n");
+        curl_slist_free_all(headers);
+        return -1; /* illegal content-type syntax! */
+      }
+
+      /* now point beyond the content-type specifier */
+      p = type + strlen(type_major) + strlen(type_minor) + 1;
+      for(endct = p; *p && *p != ';' && *p != endchar; p++)
+        if(!ISSPACE(*p))
+          endct = p + 1;
+      sep = *p;
+    }
+    else if(checkprefix("filename=", p)) {
+      if(endct) {
+        *endct = '\0';
+        endct = NULL;
+      }
+      for(p += 9; ISSPACE(*p); p++)
+        ;
+      tp = p;
+      filename = get_param_word(&p, &endpos, endchar);
+      /* If not quoted, strip trailing spaces. */
+      if(filename == tp)
+        while(endpos > filename && ISSPACE(endpos[-1]))
+          endpos--;
+      sep = *p;
+      *endpos = '\0';
+    }
+    else if(checkprefix("headers=", p)) {
+      if(endct) {
+        *endct = '\0';
+        endct = NULL;
+      }
+      p += 8;
+      if(*p == '@' || *p == '<') {
+        char *hdrfile;
+        FILE *fp;
+        /* Read headers from a file. */
+
+        do {
+          p++;
+        } while(ISSPACE(*p));
+        tp = p;
+        hdrfile = get_param_word(&p, &endpos, endchar);
+        /* If not quoted, strip trailing spaces. */
+        if(hdrfile == tp)
+          while(endpos > hdrfile && ISSPACE(endpos[-1]))
+            endpos--;
+        sep = *p;
+        *endpos = '\0';
+        /* TODO: maybe special fopen for VMS? */
+        fp = fopen(hdrfile, FOPEN_READTEXT);
+        if(!fp)
+          warnf(config->global, "Cannot read from %s: %s\n", hdrfile,
+                strerror(errno));
+        else {
+          int i = read_field_headers(config, hdrfile, fp, &headers);
+
+          fclose(fp);
+          if(i) {
+            curl_slist_free_all(headers);
+            return -1;
+          }
+        }
+      }
+      else {
+        char *hdr;
+
+        while(ISSPACE(*p))
+          p++;
+        tp = p;
+        hdr = get_param_word(&p, &endpos, endchar);
+        /* If not quoted, strip trailing spaces. */
+        if(hdr == tp)
+          while(endpos > hdr && ISSPACE(endpos[-1]))
+            endpos--;
+        sep = *p;
+        *endpos = '\0';
+        if(slist_append(&headers, hdr)) {
+          fprintf(config->global->errors, "Out of memory for field header!\n");
+          curl_slist_free_all(headers);
+          return -1;
+        }
+      }
+    }
+    else if(checkprefix("encoder=", p)) {
+      if(endct) {
+        *endct = '\0';
+        endct = NULL;
+      }
+      for(p += 8; ISSPACE(*p); p++)
+        ;
+      tp = p;
+      encoder = get_param_word(&p, &endpos, endchar);
+      /* If not quoted, strip trailing spaces. */
+      if(encoder == tp)
+        while(endpos > encoder && ISSPACE(endpos[-1]))
+          endpos--;
+      sep = *p;
+      *endpos = '\0';
+    }
+    else if(endct) {
+      /* This is part of content type. */
+      for(endct = p; *p && *p != ';' && *p != endchar; p++)
+        if(!ISSPACE(*p))
+          endct = p + 1;
+      sep = *p;
+    }
+    else {
+      /* unknown prefix, skip to next block */
+      char *unknown = get_param_word(&p, &endpos, endchar);
+
+      sep = *p;
+      *endpos = '\0';
+      if(*unknown)
+        warnf(config->global, "skip unknown form field: %s\n", unknown);
+    }
+  }
+
+  /* Terminate content type. */
+  if(endct)
+    *endct = '\0';
+
+  if(ptype)
+    *ptype = type;
+  else if(type)
+    warnf(config->global, "Field content type not allowed here: %s\n", type);
+
+  if(pfilename)
+    *pfilename = filename;
+  else if(filename)
+    warnf(config->global,
+          "Field file name not allowed here: %s\n", filename);
+
+  if(pencoder)
+    *pencoder = encoder;
+  else if(encoder)
+    warnf(config->global,
+          "Field encoder not allowed here: %s\n", encoder);
+
+  if(pheaders)
+    *pheaders = headers;
+  else if(headers) {
+    warnf(config->global,
+          "Field headers not allowed here: %s\n", headers->data);
+    curl_slist_free_all(headers);
+  }
+
+  *str = p;
+  return sep & 0xFF;
+}
+
+
+/* Mime part callbacks for stdin. */
+static size_t stdin_read(char *buffer, size_t size, size_t nitems, void *arg)
+{
+  standard_input *sip = (standard_input *) arg;
+  curl_off_t bytesleft;
+  (void) size;  /* Always 1: ignored. */
+
+  if(sip->curpos >= sip->size)
+    return 0;  /* At eof. */
+  bytesleft = sip->size - sip->curpos;
+  if((curl_off_t) nitems > bytesleft)
+    nitems = (size_t) bytesleft;
+  if(sip->data) {
+    /* Return data from memory. */
+    memcpy(buffer, sip->data + (size_t) sip->curpos, nitems);
+  }
+  else {
+    /* Read from stdin. */
+    nitems = fread(buffer, 1, nitems, stdin);
+  }
+  sip->curpos += nitems;
+  return nitems;
+}
+
+static int stdin_seek(void *instream, curl_off_t offset, int whence)
+{
+  standard_input *sip = (standard_input *) instream;
+
+  switch(whence) {
+  case SEEK_CUR:
+    offset += sip->curpos;
+    break;
+  case SEEK_END:
+    offset += sip->size;
+    break;
+  }
+  if(offset < 0)
+    return CURL_SEEKFUNC_CANTSEEK;
+  if(!sip->data) {
+    if(fseek(stdin, (long) (offset + sip->origin), SEEK_SET))
+      return CURL_SEEKFUNC_CANTSEEK;
+  }
+  sip->curpos = offset;
+  return CURL_SEEKFUNC_OK;
+}
+
+static void stdin_free(void *ptr)
+{
+  standard_input *sip = (standard_input *) ptr;
+
+  Curl_safefree(sip->data);
+  free(sip);
+}
+
+/* Set a part's data from a file, taking care about the pseudo filename "-" as
+ * a shortcut to read stdin: if so, use a callback to read OUR stdin (to
+ * workaround Windows DLL file handle caveat).
+ * If stdin is a regular file opened in binary mode, save current offset as
+ * origin for rewind and do not buffer data. Else read to EOF and keep in
+ * memory. In all cases, compute the stdin data size.
+ */
+static CURLcode file_or_stdin(curl_mimepart *part, const char *file)
+{
+  standard_input *sip = NULL;
+  int fd = -1;
+  CURLcode result = CURLE_OK;
+  struct_stat sbuf;
+
+  if(strcmp(file, "-"))
+    return curl_mime_filedata(part, file);
+
+  sip = (standard_input *) malloc(sizeof *sip);
+  if(!sip)
+    return CURLE_OUT_OF_MEMORY;
+
+  memset((char *) sip, 0, sizeof *sip);
+  set_binmode(stdin);
+
+  /* If stdin is a regular file, do not buffer data but read it when needed. */
+  fd = fileno(stdin);
+  sip->origin = ftell(stdin);
+  if(fd >= 0 && sip->origin >= 0 && !fstat(fd, &sbuf) &&
+#ifdef __VMS
+     sbuf.st_fab_rfm != FAB$C_VAR && sbuf.st_fab_rfm != FAB$C_VFC &&
+#endif
+     S_ISREG(sbuf.st_mode)) {
+    sip->size = sbuf.st_size - sip->origin;
+    if(sip->size < 0)
+      sip->size = 0;
+  }
+  else {  /* Not suitable for direct use, buffer stdin data. */
+    size_t stdinsize = 0;
+
+    sip->origin = 0;
+    if(file2memory(&sip->data, &stdinsize, stdin) != PARAM_OK)
+      result = CURLE_OUT_OF_MEMORY;
+    else {
+      if(!stdinsize)
+        sip->data = NULL;  /* Has been freed if no data. */
+      sip->size = stdinsize;
+      if(ferror(stdin))
+        result = CURLE_READ_ERROR;
+    }
+  }
+
+  /* Set remote file name. */
+  if(!result)
+    result = curl_mime_filename(part, file);
+
+  /* Set part's data from callback. */
+  if(!result)
+    result = curl_mime_data_cb(part, sip->size,
+                               stdin_read, stdin_seek, stdin_free, sip);
+  if(result)
+    stdin_free(sip);
+  return result;
+}
+
+
+/***************************************************************************
+ *
+ * formparse()
+ *
+ * Reads a 'name=value' parameter and builds the appropriate linked list.
+ *
+ * Specify files to upload with 'name=@filename', or 'name=@"filename"'
+ * in case the filename contain ',' or ';'. Supports specified
+ * given Content-Type of the files. Such as ';type=<content-type>'.
+ *
+ * If literal_value is set, any initial '@' or '<' in the value string
+ * loses its special meaning, as does any embedded ';type='.
+ *
+ * You may specify more than one file for a single name (field). Specify
+ * multiple files by writing it like:
+ *
+ * 'name=@filename,filename2,filename3'
+ *
+ * or use double-quotes quote the filename:
+ *
+ * 'name=@"filename","filename2","filename3"'
+ *
+ * If you want content-types specified for each too, write them like:
+ *
+ * 'name=@filename;type=image/gif,filename2,filename3'
+ *
+ * If you want custom headers added for a single part, write them in a separate
+ * file and do like this:
+ *
+ * 'name=foo;headers=@headerfile' or why not
+ * 'name=@filemame;headers=@headerfile'
+ *
+ * To upload a file, but to fake the file name that will be included in the
+ * formpost, do like this:
+ *
+ * 'name=@filename;filename=/dev/null' or quote the faked filename like:
+ * 'name=@filename;filename="play, play, and play.txt"'
+ *
+ * If filename/path contains ',' or ';', it must be quoted by double-quotes,
+ * else curl will fail to figure out the correct filename. if the filename
+ * tobe quoted contains '"' or '\', '"' and '\' must be escaped by backslash.
+ *
+ * This function uses curl_formadd to fulfill it's job. Is heavily based on
+ * the old curl_formparse code.
+ *
+ ***************************************************************************/
+
+int formparse(struct OperationConfig *config,
+              const char *input,
+              curl_mime **mimepost,
+              curl_mime **mimecurrent,
+              bool literal_value)
+{
+  /* input MUST be a string in the format 'name=contents' and we'll
+     build a linked list with the info */
+  char *name = NULL;
+  char *contents = NULL;
+  char *contp;
+  char *data;
+  char *type = NULL;
+  char *filename = NULL;
+  char *encoder = NULL;
+  struct curl_slist *headers = NULL;
+  curl_mimepart *part = NULL;
+  CURLcode res;
+  int sep = '\0';
+
+  /* Allocate the main mime structure if needed. */
+  if(!*mimepost) {
+    *mimepost = curl_mime_init(config->easy);
+    if(!*mimepost) {
+      warnf(config->global, "curl_mime_init failed!\n");
+      return 1;
+    }
+    *mimecurrent = *mimepost;
+  }
+
+  /* Make a copy we can overwrite. */
+  contents = strdup(input);
+  if(!contents) {
+    fprintf(config->global->errors, "out of memory\n");
+    return 2;
+  }
+
+  /* Scan for the end of the name. */
+  contp = strchr(contents, '=');
+  if(contp) {
+    if(contp > contents)
+      name = contents;
+    *contp++ = '\0';
+
+    if(*contp == '(' && !literal_value) {
+      curl_mime *subparts;
+
+      /* Starting a multipart. */
+      sep = get_param_part(config, '\0',
+                           &contp, &data, &type, NULL, NULL, &headers);
+      if(sep < 0) {
+        Curl_safefree(contents);
+        return 3;
+      }
+      subparts = curl_mime_init(config->easy);
+      if(!subparts) {
+        warnf(config->global, "curl_mime_init failed!\n");
+        curl_slist_free_all(headers);
+        Curl_safefree(contents);
+        return 4;
+      }
+      part = curl_mime_addpart(*mimecurrent);
+      if(!part) {
+        warnf(config->global, "curl_mime_addpart failed!\n");
+        curl_mime_free(subparts);
+        curl_slist_free_all(headers);
+        Curl_safefree(contents);
+        return 5;
+      }
+      if(curl_mime_subparts(part, subparts)) {
+        warnf(config->global, "curl_mime_subparts failed!\n");
+        curl_mime_free(subparts);
+        curl_slist_free_all(headers);
+        Curl_safefree(contents);
+        return 6;
+      }
+      *mimecurrent = subparts;
+      if(curl_mime_headers(part, headers, 1)) {
+        warnf(config->global, "curl_mime_headers failed!\n");
+        curl_slist_free_all(headers);
+        Curl_safefree(contents);
+        return 7;
+      }
+      if(curl_mime_type(part, type)) {
+        warnf(config->global, "curl_mime_type failed!\n");
+        Curl_safefree(contents);
+        return 8;
+      }
+    }
+    else if(!name && !strcmp(contp, ")") && !literal_value) {
+      /* Ending a mutipart. */
+      if(*mimecurrent == *mimepost) {
+        warnf(config->global, "no multipart to terminate!\n");
+        Curl_safefree(contents);
+        return 9;
+        }
+      *mimecurrent = (*mimecurrent)->parent->parent;
+    }
+    else if('@' == contp[0] && !literal_value) {
+
+      /* we use the @-letter to indicate file name(s) */
+
+      curl_mime *subparts = NULL;
+
+      do {
+        /* since this was a file, it may have a content-type specifier
+           at the end too, or a filename. Or both. */
+        ++contp;
+        sep = get_param_part(config, ',', &contp,
+                             &data, &type, &filename, &encoder, &headers);
+        if(sep < 0) {
+          if(subparts != *mimecurrent)
+            curl_mime_free(subparts);
+          Curl_safefree(contents);
+          return 10;
+        }
+
+        /* now contp point to comma or string end.
+           If more files to come, make sure we have multiparts. */
+        if(!subparts) {
+          if(sep != ',')    /* If there is a single file. */
+            subparts = *mimecurrent;
+          else {
+            subparts = curl_mime_init(config->easy);
+            if(!subparts) {
+              warnf(config->global, "curl_mime_init failed!\n");
+              curl_slist_free_all(headers);
+              Curl_safefree(contents);
+              return 11;
+            }
+          }
+        }
+
+        /* Allocate a part for that file. */
+        part = curl_mime_addpart(subparts);
+        if(!part) {
+          warnf(config->global, "curl_mime_addpart failed!\n");
+          if(subparts != *mimecurrent)
+            curl_mime_free(subparts);
+          curl_slist_free_all(headers);
+          Curl_safefree(contents);
+          return 12;
+        }
+
+        /* Set part headers. */
+        if(curl_mime_headers(part, headers, 1)) {
+          warnf(config->global, "curl_mime_headers failed!\n");
+          if(subparts != *mimecurrent)
+            curl_mime_free(subparts);
+          curl_slist_free_all(headers);
+          Curl_safefree(contents);
+          return 13;
+        }
+
+        /* Setup file in part. */
+        res = file_or_stdin(part, data);
+        if(res) {
+          warnf(config->global, "setting file %s  failed!\n", data);
+          if(res != CURLE_READ_ERROR) {
+            if(subparts != *mimecurrent)
+              curl_mime_free(subparts);
+            Curl_safefree(contents);
+            return 14;
+          }
+        }
+        if(filename && curl_mime_filename(part, filename)) {
+          warnf(config->global, "curl_mime_filename failed!\n");
+          if(subparts != *mimecurrent)
+            curl_mime_free(subparts);
+          Curl_safefree(contents);
+          return 15;
+        }
+        if(curl_mime_type(part, type)) {
+          warnf(config->global, "curl_mime_type failed!\n");
+          if(subparts != *mimecurrent)
+            curl_mime_free(subparts);
+          Curl_safefree(contents);
+          return 16;
+        }
+        if(curl_mime_encoder(part, encoder)) {
+          warnf(config->global, "curl_mime_encoder failed!\n");
+          if(subparts != *mimecurrent)
+            curl_mime_free(subparts);
+          Curl_safefree(contents);
+          return 17;
+        }
+
+        /* *contp could be '\0', so we just check with the delimiter */
+      } while(sep); /* loop if there's another file name */
+
+      /* now we add the multiple files section */
+      if(subparts != *mimecurrent) {
+        part = curl_mime_addpart(*mimecurrent);
+        if(!part) {
+          warnf(config->global, "curl_mime_addpart failed!\n");
+          curl_mime_free(subparts);
+          Curl_safefree(contents);
+          return 18;
+        }
+        if(curl_mime_subparts(part, subparts)) {
+          warnf(config->global, "curl_mime_subparts failed!\n");
+          curl_mime_free(subparts);
+          Curl_safefree(contents);
+          return 19;
+        }
+      }
+    }
+    else {
+        /* Allocate a mime part. */
+        part = curl_mime_addpart(*mimecurrent);
+        if(!part) {
+          warnf(config->global, "curl_mime_addpart failed!\n");
+          Curl_safefree(contents);
+          return 20;
+        }
+
+      if(*contp == '<' && !literal_value) {
+        ++contp;
+        sep = get_param_part(config, '\0', &contp,
+                             &data, &type, NULL, &encoder, &headers);
+        if(sep < 0) {
+          Curl_safefree(contents);
+          return 21;
+        }
+
+        /* Set part headers. */
+        if(curl_mime_headers(part, headers, 1)) {
+          warnf(config->global, "curl_mime_headers failed!\n");
+          curl_slist_free_all(headers);
+          Curl_safefree(contents);
+          return 22;
+        }
+
+        /* Setup file in part. */
+        res = file_or_stdin(part, data);
+        if(res) {
+          warnf(config->global, "setting file %s failed!\n", data);
+          if(res != CURLE_READ_ERROR) {
+            Curl_safefree(contents);
+            return 23;
+          }
+        }
+      }
+      else {
+        if(literal_value)
+          data = contp;
+        else {
+          sep = get_param_part(config, '\0', &contp,
+                               &data, &type, &filename, &encoder, &headers);
+          if(sep < 0) {
+            Curl_safefree(contents);
+            return 24;
+          }
+        }
+
+        /* Set part headers. */
+        if(curl_mime_headers(part, headers, 1)) {
+          warnf(config->global, "curl_mime_headers failed!\n");
+          curl_slist_free_all(headers);
+          Curl_safefree(contents);
+          return 25;
+        }
+
+#ifdef CURL_DOES_CONVERSIONS
+        if(convert_to_network(data, strlen(data))) {
+          warnf(config->global, "curl_formadd failed!\n");
+          Curl_safefree(contents);
+          return 26;
+        }
+#endif
+
+        if(curl_mime_data(part, data, CURL_ZERO_TERMINATED)) {
+          warnf(config->global, "curl_mime_data failed!\n");
+          Curl_safefree(contents);
+          return 27;
+        }
+      }
+
+      if(curl_mime_filename(part, filename)) {
+        warnf(config->global, "curl_mime_filename failed!\n");
+        Curl_safefree(contents);
+        return 28;
+      }
+      if(curl_mime_type(part, type)) {
+        warnf(config->global, "curl_mime_type failed!\n");
+        Curl_safefree(contents);
+        return 29;
+      }
+      if(curl_mime_encoder(part, encoder)) {
+        warnf(config->global, "curl_mime_encoder failed!\n");
+        Curl_safefree(contents);
+        return 30;
+      }
+
+      if(sep) {
+        *contp = (char) sep;
+        warnf(config->global,
+              "garbage at end of field specification: %s\n", contp);
+      }
+    }
+
+    /* Set part name. */
+    if(name && curl_mime_name(part, name)) {
+      warnf(config->global, "curl_mime_name failed!\n");
+      Curl_safefree(contents);
+      return 31;
+    }
+  }
+  else {
+    warnf(config->global, "Illegally formatted input field!\n");
+    Curl_safefree(contents);
+    return 32;
+  }
+  Curl_safefree(contents);
+  return 0;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_formparse.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_formparse.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_formparse.h	(revision 331)
@@ -0,0 +1,33 @@
+#ifndef HEADER_CURL_TOOL_FORMPARSE_H
+#define HEADER_CURL_TOOL_FORMPARSE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+int formparse(struct OperationConfig *config,
+              const char *input,
+              curl_mime **mimepost,
+              curl_mime **mimecurrent,
+              bool literal_value);
+
+#endif /* HEADER_CURL_TOOL_FORMPARSE_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_getparam.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_getparam.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_getparam.c	(revision 331)
@@ -0,0 +1,2164 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#include "strcase.h"
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_binmode.h"
+#include "tool_cfgable.h"
+#include "tool_cb_prg.h"
+#include "tool_convert.h"
+#include "tool_formparse.h"
+#include "tool_getparam.h"
+#include "tool_helpers.h"
+#include "tool_libinfo.h"
+#include "tool_metalink.h"
+#include "tool_msgs.h"
+#include "tool_paramhlp.h"
+#include "tool_parsecfg.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+#ifdef MSDOS
+#  define USE_WATT32
+#endif
+
+#define GetStr(str,val) do { \
+  if(*(str)) { \
+    free(*(str)); \
+    *(str) = NULL; \
+  } \
+  if((val)) {              \
+    *(str) = strdup((val)); \
+    if(!(*(str)))          \
+      return PARAM_NO_MEM; \
+  } \
+} WHILE_FALSE
+
+struct LongShort {
+  const char *letter; /* short name option */
+  const char *lname;  /* long name option */
+  enum {
+    ARG_NONE,   /* stand-alone but not a boolean */
+    ARG_BOOL,   /* accepts a --no-[name] prefix */
+    ARG_STRING  /* requires an argument */
+  } desc;
+};
+
+static const struct LongShort aliases[]= {
+  /* 'letter' strings with more than one character have *no* short option to
+     mention. */
+  {"*@", "url",                      ARG_STRING},
+  {"*4", "dns-ipv4-addr",            ARG_STRING},
+  {"*6", "dns-ipv6-addr",            ARG_STRING},
+  {"*a", "random-file",              ARG_STRING},
+  {"*b", "egd-file",                 ARG_STRING},
+  {"*B", "oauth2-bearer",            ARG_STRING},
+  {"*c", "connect-timeout",          ARG_STRING},
+  {"*d", "ciphers",                  ARG_STRING},
+  {"*D", "dns-interface",            ARG_STRING},
+  {"*e", "disable-epsv",             ARG_BOOL},
+  {"*E", "epsv",                     ARG_BOOL},
+         /* 'epsv' made like this to make --no-epsv and --epsv to work
+             although --disable-epsv is the documented option */
+  {"*F", "dns-servers",              ARG_STRING},
+  {"*g", "trace",                    ARG_STRING},
+  {"*G", "npn",                      ARG_BOOL},
+  {"*h", "trace-ascii",              ARG_STRING},
+  {"*H", "alpn",                     ARG_BOOL},
+  {"*i", "limit-rate",               ARG_STRING},
+  {"*j", "compressed",               ARG_BOOL},
+  {"*J", "tr-encoding",              ARG_BOOL},
+  {"*k", "digest",                   ARG_BOOL},
+  {"*l", "negotiate",                ARG_BOOL},
+  {"*m", "ntlm",                     ARG_BOOL},
+  {"*M", "ntlm-wb",                  ARG_BOOL},
+  {"*n", "basic",                    ARG_BOOL},
+  {"*o", "anyauth",                  ARG_BOOL},
+#ifdef USE_WATT32
+  {"*p", "wdebug",                   ARG_BOOL},
+#endif
+  {"*q", "ftp-create-dirs",          ARG_BOOL},
+  {"*r", "create-dirs",              ARG_BOOL},
+  {"*s", "max-redirs",               ARG_STRING},
+  {"*t", "proxy-ntlm",               ARG_BOOL},
+  {"*u", "crlf",                     ARG_BOOL},
+  {"*v", "stderr",                   ARG_STRING},
+  {"*w", "interface",                ARG_STRING},
+  {"*x", "krb",                      ARG_STRING},
+  {"*x", "krb4",                     ARG_STRING},
+         /* 'krb4' is the previous name */
+  {"*y", "max-filesize",             ARG_STRING},
+  {"*z", "disable-eprt",             ARG_BOOL},
+  {"*Z", "eprt",                     ARG_BOOL},
+         /* 'eprt' made like this to make --no-eprt and --eprt to work
+             although --disable-eprt is the documented option */
+  {"*~", "xattr",                    ARG_BOOL},
+  {"$a", "ftp-ssl",                  ARG_BOOL},
+         /* 'ftp-ssl' deprecated name since 7.20.0 */
+  {"$a", "ssl",                      ARG_BOOL},
+         /* 'ssl' new option name in 7.20.0, previously this was ftp-ssl */
+  {"$b", "ftp-pasv",                 ARG_BOOL},
+  {"$c", "socks5",                   ARG_STRING},
+  {"$d", "tcp-nodelay",              ARG_BOOL},
+  {"$e", "proxy-digest",             ARG_BOOL},
+  {"$f", "proxy-basic",              ARG_BOOL},
+  {"$g", "retry",                    ARG_STRING},
+  {"$V", "retry-connrefused",        ARG_BOOL},
+  {"$h", "retry-delay",              ARG_STRING},
+  {"$i", "retry-max-time",           ARG_STRING},
+  {"$k", "proxy-negotiate",          ARG_BOOL},
+  {"$m", "ftp-account",              ARG_STRING},
+  {"$n", "proxy-anyauth",            ARG_BOOL},
+  {"$o", "trace-time",               ARG_BOOL},
+  {"$p", "ignore-content-length",    ARG_BOOL},
+  {"$q", "ftp-skip-pasv-ip",         ARG_BOOL},
+  {"$r", "ftp-method",               ARG_STRING},
+  {"$s", "local-port",               ARG_STRING},
+  {"$t", "socks4",                   ARG_STRING},
+  {"$T", "socks4a",                  ARG_STRING},
+  {"$u", "ftp-alternative-to-user",  ARG_STRING},
+  {"$v", "ftp-ssl-reqd",             ARG_BOOL},
+         /* 'ftp-ssl-reqd' deprecated name since 7.20.0 */
+  {"$v", "ssl-reqd",                 ARG_BOOL},
+         /* 'ssl-reqd' new in 7.20.0, previously this was ftp-ssl-reqd */
+  {"$w", "sessionid",                ARG_BOOL},
+         /* 'sessionid' listed as --no-sessionid in the help */
+  {"$x", "ftp-ssl-control",          ARG_BOOL},
+  {"$y", "ftp-ssl-ccc",              ARG_BOOL},
+  {"$j", "ftp-ssl-ccc-mode",         ARG_STRING},
+  {"$z", "libcurl",                  ARG_STRING},
+  {"$#", "raw",                      ARG_BOOL},
+  {"$0", "post301",                  ARG_BOOL},
+  {"$1", "keepalive",                ARG_BOOL},
+         /* 'keepalive' listed as --no-keepalive in the help */
+  {"$2", "socks5-hostname",          ARG_STRING},
+  {"$3", "keepalive-time",           ARG_STRING},
+  {"$4", "post302",                  ARG_BOOL},
+  {"$5", "noproxy",                  ARG_STRING},
+  {"$7", "socks5-gssapi-nec",        ARG_BOOL},
+  {"$8", "proxy1.0",                 ARG_STRING},
+  {"$9", "tftp-blksize",             ARG_STRING},
+  {"$A", "mail-from",                ARG_STRING},
+  {"$B", "mail-rcpt",                ARG_STRING},
+  {"$C", "ftp-pret",                 ARG_BOOL},
+  {"$D", "proto",                    ARG_STRING},
+  {"$E", "proto-redir",              ARG_STRING},
+  {"$F", "resolve",                  ARG_STRING},
+  {"$G", "delegation",               ARG_STRING},
+  {"$H", "mail-auth",                ARG_STRING},
+  {"$I", "post303",                  ARG_BOOL},
+  {"$J", "metalink",                 ARG_BOOL},
+  {"$K", "sasl-ir",                  ARG_BOOL},
+  {"$L", "test-event",               ARG_BOOL},
+  {"$M", "unix-socket",              ARG_STRING},
+  {"$N", "path-as-is",               ARG_BOOL},
+  {"$O", "socks5-gssapi-service",    ARG_STRING},
+         /* 'socks5-gssapi-service' merged with'proxy-service-name' and
+            deprecated since 7.49.0 */
+  {"$O", "proxy-service-name",       ARG_STRING},
+  {"$P", "service-name",             ARG_STRING},
+  {"$Q", "proto-default",            ARG_STRING},
+  {"$R", "expect100-timeout",        ARG_STRING},
+  {"$S", "tftp-no-options",          ARG_BOOL},
+  {"$U", "connect-to",               ARG_STRING},
+  {"$W", "abstract-unix-socket",     ARG_STRING},
+  {"$X", "tls-max",                  ARG_STRING},
+  {"$Y", "suppress-connect-headers", ARG_BOOL},
+  {"$Z", "compressed-ssh",           ARG_BOOL},
+  {"0",   "http1.0",                 ARG_NONE},
+  {"01",  "http1.1",                 ARG_NONE},
+  {"02",  "http2",                   ARG_NONE},
+  {"03",  "http2-prior-knowledge",   ARG_NONE},
+  {"1",  "tlsv1",                    ARG_NONE},
+  {"10",  "tlsv1.0",                 ARG_NONE},
+  {"11",  "tlsv1.1",                 ARG_NONE},
+  {"12",  "tlsv1.2",                 ARG_NONE},
+  {"13",  "tlsv1.3",                 ARG_NONE},
+  {"2",  "sslv2",                    ARG_NONE},
+  {"3",  "sslv3",                    ARG_NONE},
+  {"4",  "ipv4",                     ARG_NONE},
+  {"6",  "ipv6",                     ARG_NONE},
+  {"a",  "append",                   ARG_BOOL},
+  {"A",  "user-agent",               ARG_STRING},
+  {"b",  "cookie",                   ARG_STRING},
+  {"B",  "use-ascii",                ARG_BOOL},
+  {"c",  "cookie-jar",               ARG_STRING},
+  {"C",  "continue-at",              ARG_STRING},
+  {"d",  "data",                     ARG_STRING},
+  {"dr", "data-raw",                 ARG_STRING},
+  {"da", "data-ascii",               ARG_STRING},
+  {"db", "data-binary",              ARG_STRING},
+  {"de", "data-urlencode",           ARG_STRING},
+  {"D",  "dump-header",              ARG_STRING},
+  {"e",  "referer",                  ARG_STRING},
+  {"E",  "cert",                     ARG_STRING},
+  {"Ea", "cacert",                   ARG_STRING},
+  {"Eb", "cert-type",                ARG_STRING},
+  {"Ec", "key",                      ARG_STRING},
+  {"Ed", "key-type",                 ARG_STRING},
+  {"Ee", "pass",                     ARG_STRING},
+  {"Ef", "engine",                   ARG_STRING},
+  {"Eg", "capath",                   ARG_STRING},
+  {"Eh", "pubkey",                   ARG_STRING},
+  {"Ei", "hostpubmd5",               ARG_STRING},
+  {"Ej", "crlfile",                  ARG_STRING},
+  {"Ek", "tlsuser",                  ARG_STRING},
+  {"El", "tlspassword",              ARG_STRING},
+  {"Em", "tlsauthtype",              ARG_STRING},
+  {"En", "ssl-allow-beast",          ARG_BOOL},
+  {"Eo", "login-options",            ARG_STRING},
+  {"Ep", "pinnedpubkey",             ARG_STRING},
+  {"Eq", "cert-status",              ARG_BOOL},
+  {"Er", "false-start",              ARG_BOOL},
+  {"Es", "ssl-no-revoke",            ARG_BOOL},
+  {"Et", "tcp-fastopen",             ARG_BOOL},
+  {"Eu", "proxy-tlsuser",            ARG_STRING},
+  {"Ev", "proxy-tlspassword",        ARG_STRING},
+  {"Ew", "proxy-tlsauthtype",        ARG_STRING},
+  {"Ex", "proxy-cert",               ARG_STRING},
+  {"Ey", "proxy-cert-type",          ARG_STRING},
+  {"Ez", "proxy-key",                ARG_STRING},
+  {"E0", "proxy-key-type",           ARG_STRING},
+  {"E1", "proxy-pass",               ARG_STRING},
+  {"E2", "proxy-ciphers",            ARG_STRING},
+  {"E3", "proxy-crlfile",            ARG_STRING},
+  {"E4", "proxy-ssl-allow-beast",    ARG_BOOL},
+  {"E5", "login-options",            ARG_STRING},
+  {"E6", "proxy-cacert",             ARG_STRING},
+  {"E7", "proxy-capath",             ARG_STRING},
+  {"E8", "proxy-insecure",           ARG_BOOL},
+  {"E9", "proxy-tlsv1",              ARG_NONE},
+  {"EA", "socks5-basic",             ARG_BOOL},
+  {"EB", "socks5-gssapi",            ARG_BOOL},
+  {"f",  "fail",                     ARG_BOOL},
+  {"fa", "fail-early",               ARG_BOOL},
+  {"F",  "form",                     ARG_STRING},
+  {"Fs", "form-string",              ARG_STRING},
+  {"g",  "globoff",                  ARG_BOOL},
+  {"G",  "get",                      ARG_NONE},
+  {"Ga", "request-target",           ARG_STRING},
+  {"h",  "help",                     ARG_BOOL},
+  {"H",  "header",                   ARG_STRING},
+  {"Hp", "proxy-header",             ARG_STRING},
+  {"i",  "include",                  ARG_BOOL},
+  {"I",  "head",                     ARG_BOOL},
+  {"j",  "junk-session-cookies",     ARG_BOOL},
+  {"J",  "remote-header-name",       ARG_BOOL},
+  {"k",  "insecure",                 ARG_BOOL},
+  {"K",  "config",                   ARG_STRING},
+  {"l",  "list-only",                ARG_BOOL},
+  {"L",  "location",                 ARG_BOOL},
+  {"Lt", "location-trusted",         ARG_BOOL},
+  {"m",  "max-time",                 ARG_STRING},
+  {"M",  "manual",                   ARG_BOOL},
+  {"n",  "netrc",                    ARG_BOOL},
+  {"no", "netrc-optional",           ARG_BOOL},
+  {"ne", "netrc-file",               ARG_STRING},
+  {"N",  "buffer",                   ARG_BOOL},
+         /* 'buffer' listed as --no-buffer in the help */
+  {"o",  "output",                   ARG_STRING},
+  {"O",  "remote-name",              ARG_NONE},
+  {"Oa", "remote-name-all",          ARG_BOOL},
+  {"p",  "proxytunnel",              ARG_BOOL},
+  {"P",  "ftp-port",                 ARG_STRING},
+  {"q",  "disable",                  ARG_BOOL},
+  {"Q",  "quote",                    ARG_STRING},
+  {"r",  "range",                    ARG_STRING},
+  {"R",  "remote-time",              ARG_BOOL},
+  {"s",  "silent",                   ARG_BOOL},
+  {"S",  "show-error",               ARG_BOOL},
+  {"t",  "telnet-option",            ARG_STRING},
+  {"T",  "upload-file",              ARG_STRING},
+  {"u",  "user",                     ARG_STRING},
+  {"U",  "proxy-user",               ARG_STRING},
+  {"v",  "verbose",                  ARG_BOOL},
+  {"V",  "version",                  ARG_BOOL},
+  {"w",  "write-out",                ARG_STRING},
+  {"x",  "proxy",                    ARG_STRING},
+  {"xa", "preproxy",                 ARG_STRING},
+  {"X",  "request",                  ARG_STRING},
+  {"Y",  "speed-limit",              ARG_STRING},
+  {"y",  "speed-time",               ARG_STRING},
+  {"z",  "time-cond",                ARG_STRING},
+  {"#",  "progress-bar",             ARG_BOOL},
+  {":",  "next",                     ARG_NONE},
+};
+
+/* Split the argument of -E to 'certname' and 'passphrase' separated by colon.
+ * We allow ':' and '\' to be escaped by '\' so that we can use certificate
+ * nicknames containing ':'.  See <https://sourceforge.net/p/curl/bugs/1196/>
+ * for details. */
+#ifndef UNITTESTS
+static
+#endif
+void parse_cert_parameter(const char *cert_parameter,
+                          char **certname,
+                          char **passphrase)
+{
+  size_t param_length = strlen(cert_parameter);
+  size_t span;
+  const char *param_place = NULL;
+  char *certname_place = NULL;
+  *certname = NULL;
+  *passphrase = NULL;
+
+  /* most trivial assumption: cert_parameter is empty */
+  if(param_length == 0)
+    return;
+
+  /* next less trivial: cert_parameter starts 'pkcs11:' and thus
+   * looks like a RFC7512 PKCS#11 URI which can be used as-is.
+   * Also if cert_parameter contains no colon nor backslash, this
+   * means no passphrase was given and no characters escaped */
+  if(!strncmp(cert_parameter, "pkcs11:", 7) ||
+     !strpbrk(cert_parameter, ":\\")) {
+    *certname = strdup(cert_parameter);
+    return;
+  }
+  /* deal with escaped chars; find unescaped colon if it exists */
+  certname_place = malloc(param_length + 1);
+  if(!certname_place)
+    return;
+
+  *certname = certname_place;
+  param_place = cert_parameter;
+  while(*param_place) {
+    span = strcspn(param_place, ":\\");
+    strncpy(certname_place, param_place, span);
+    param_place += span;
+    certname_place += span;
+    /* we just ate all the non-special chars. now we're on either a special
+     * char or the end of the string. */
+    switch(*param_place) {
+    case '\0':
+      break;
+    case '\\':
+      param_place++;
+      switch(*param_place) {
+        case '\0':
+          *certname_place++ = '\\';
+          break;
+        case '\\':
+          *certname_place++ = '\\';
+          param_place++;
+          break;
+        case ':':
+          *certname_place++ = ':';
+          param_place++;
+          break;
+        default:
+          *certname_place++ = '\\';
+          *certname_place++ = *param_place;
+          param_place++;
+          break;
+      }
+      break;
+    case ':':
+      /* Since we live in a world of weirdness and confusion, the win32
+         dudes can use : when using drive letters and thus c:\file:password
+         needs to work. In order not to break compatibility, we still use : as
+         separator, but we try to detect when it is used for a file name! On
+         windows. */
+#ifdef WIN32
+      if(param_place &&
+          (param_place == &cert_parameter[1]) &&
+          (cert_parameter[2] == '\\' || cert_parameter[2] == '/') &&
+          (ISALPHA(cert_parameter[0])) ) {
+        /* colon in the second column, followed by a backslash, and the
+           first character is an alphabetic letter:
+
+           this is a drive letter colon */
+        *certname_place++ = ':';
+        param_place++;
+        break;
+      }
+#endif
+      /* escaped colons and Windows drive letter colons were handled
+       * above; if we're still here, this is a separating colon */
+      param_place++;
+      if(strlen(param_place) > 0) {
+        *passphrase = strdup(param_place);
+      }
+      goto done;
+    }
+  }
+done:
+  *certname_place = '\0';
+}
+
+static void
+GetFileAndPassword(char *nextarg, char **file, char **password)
+{
+  char *certname, *passphrase;
+  parse_cert_parameter(nextarg, &certname, &passphrase);
+  Curl_safefree(*file);
+  *file = certname;
+  if(passphrase) {
+    Curl_safefree(*password);
+    *password = passphrase;
+  }
+  cleanarg(nextarg);
+}
+
+ParameterError getparameter(const char *flag, /* f or -long-flag */
+                            char *nextarg,    /* NULL if unset */
+                            bool *usedarg,    /* set to TRUE if the arg
+                                                 has been used */
+                            struct GlobalConfig *global,
+                            struct OperationConfig *config)
+{
+  char letter;
+  char subletter = '\0'; /* subletters can only occur on long options */
+  int rc;
+  const char *parse = NULL;
+  unsigned int j;
+  time_t now;
+  int hit = -1;
+  bool longopt = FALSE;
+  bool singleopt = FALSE; /* when true means '-o foo' used '-ofoo' */
+  ParameterError err;
+  bool toggle = TRUE; /* how to switch boolean options, on or off. Controlled
+                         by using --OPTION or --no-OPTION */
+
+  *usedarg = FALSE; /* default is that we don't use the arg */
+
+  if(('-' != flag[0]) ||
+     (('-' == flag[0]) && ('-' == flag[1]))) {
+    /* this should be a long name */
+    const char *word = ('-' == flag[0]) ? flag + 2 : flag;
+    size_t fnam = strlen(word);
+    int numhits = 0;
+
+    if(!strncmp(word, "no-", 3)) {
+      /* disable this option but ignore the "no-" part when looking for it */
+      word += 3;
+      toggle = FALSE;
+    }
+
+    for(j = 0; j < sizeof(aliases)/sizeof(aliases[0]); j++) {
+      if(curl_strnequal(aliases[j].lname, word, fnam)) {
+        longopt = TRUE;
+        numhits++;
+        if(curl_strequal(aliases[j].lname, word)) {
+          parse = aliases[j].letter;
+          hit = j;
+          numhits = 1; /* a single unique hit */
+          break;
+        }
+        parse = aliases[j].letter;
+        hit = j;
+      }
+    }
+    if(numhits > 1) {
+      /* this is at least the second match! */
+      return PARAM_OPTION_AMBIGUOUS;
+    }
+    if(hit < 0) {
+      return PARAM_OPTION_UNKNOWN;
+    }
+  }
+  else {
+    flag++; /* prefixed with one dash, pass it */
+    hit = -1;
+    parse = flag;
+  }
+
+  do {
+    /* we can loop here if we have multiple single-letters */
+
+    if(!longopt) {
+      letter = (char)*parse;
+      subletter = '\0';
+    }
+    else {
+      letter = parse[0];
+      subletter = parse[1];
+    }
+
+    if(hit < 0) {
+      for(j = 0; j < sizeof(aliases)/sizeof(aliases[0]); j++) {
+        if(letter == aliases[j].letter[0]) {
+          hit = j;
+          break;
+        }
+      }
+      if(hit < 0) {
+        return PARAM_OPTION_UNKNOWN;
+      }
+    }
+
+    if(aliases[hit].desc == ARG_STRING) {
+      /* this option requires an extra parameter */
+      if(!longopt && parse[1]) {
+        nextarg = (char *)&parse[1]; /* this is the actual extra parameter */
+        singleopt = TRUE;   /* don't loop anymore after this */
+      }
+      else if(!nextarg)
+        return PARAM_REQUIRES_PARAMETER;
+      else
+        *usedarg = TRUE; /* mark it as used */
+    }
+    else if((aliases[hit].desc == ARG_NONE) && !toggle)
+      return PARAM_NO_PREFIX;
+
+    switch(letter) {
+    case '*': /* options without a short option */
+      switch(subletter) {
+      case '4': /* --dns-ipv4-addr */
+        /* addr in dot notation */
+        GetStr(&config->dns_ipv4_addr, nextarg);
+        break;
+      case '6': /* --dns-ipv6-addr */
+        /* addr in dot notation */
+        GetStr(&config->dns_ipv6_addr, nextarg);
+        break;
+      case 'a': /* random-file */
+        GetStr(&config->random_file, nextarg);
+        break;
+      case 'b': /* egd-file */
+        GetStr(&config->egd_file, nextarg);
+        break;
+      case 'B': /* OAuth 2.0 bearer token */
+        GetStr(&config->oauth_bearer, nextarg);
+        break;
+      case 'c': /* connect-timeout */
+        err = str2udouble(&config->connecttimeout, nextarg,
+                          LONG_MAX/1000);
+        if(err)
+          return err;
+        break;
+      case 'd': /* ciphers */
+        GetStr(&config->cipher_list, nextarg);
+        break;
+      case 'D': /* --dns-interface */
+        /* interface name */
+        GetStr(&config->dns_interface, nextarg);
+        break;
+      case 'e': /* --disable-epsv */
+        config->disable_epsv = toggle;
+        break;
+      case 'E': /* --epsv */
+        config->disable_epsv = (!toggle)?TRUE:FALSE;
+        break;
+      case 'F': /* --dns-servers */
+        /* IP addrs of DNS servers */
+        GetStr(&config->dns_servers, nextarg);
+        break;
+      case 'g': /* --trace */
+        GetStr(&global->trace_dump, nextarg);
+        if(global->tracetype && (global->tracetype != TRACE_BIN))
+          warnf(global, "--trace overrides an earlier trace/verbose option\n");
+        global->tracetype = TRACE_BIN;
+        break;
+      case 'G': /* --npn */
+        config->nonpn = (!toggle)?TRUE:FALSE;
+        break;
+      case 'h': /* --trace-ascii */
+        GetStr(&global->trace_dump, nextarg);
+        if(global->tracetype && (global->tracetype != TRACE_ASCII))
+          warnf(global,
+                "--trace-ascii overrides an earlier trace/verbose option\n");
+        global->tracetype = TRACE_ASCII;
+        break;
+      case 'H': /* --alpn */
+        config->noalpn = (!toggle)?TRUE:FALSE;
+        break;
+      case 'i': /* --limit-rate */
+      {
+        /* We support G, M, K too */
+        char *unit;
+        curl_off_t value;
+        if(curlx_strtoofft(nextarg, &unit, 0, &value)) {
+          warnf(global, "unsupported rate\n");
+          return PARAM_BAD_USE;
+        }
+
+        if(!*unit)
+          unit = (char *)"b";
+        else if(strlen(unit) > 1)
+          unit = (char *)"w"; /* unsupported */
+
+        switch(*unit) {
+        case 'G':
+        case 'g':
+          value *= 1024*1024*1024;
+          break;
+        case 'M':
+        case 'm':
+          value *= 1024*1024;
+          break;
+        case 'K':
+        case 'k':
+          value *= 1024;
+          break;
+        case 'b':
+        case 'B':
+          /* for plain bytes, leave as-is */
+          break;
+        default:
+          warnf(global, "unsupported rate unit. Use G, M, K or B!\n");
+          return PARAM_BAD_USE;
+        }
+        config->recvpersecond = value;
+        config->sendpersecond = value;
+      }
+      break;
+
+      case 'j': /* --compressed */
+        if(toggle && !(curlinfo->features & CURL_VERSION_LIBZ))
+          return PARAM_LIBCURL_DOESNT_SUPPORT;
+        config->encoding = toggle;
+        break;
+
+      case 'J': /* --tr-encoding */
+        config->tr_encoding = toggle;
+        break;
+
+      case 'k': /* --digest */
+        if(toggle)
+          config->authtype |= CURLAUTH_DIGEST;
+        else
+          config->authtype &= ~CURLAUTH_DIGEST;
+        break;
+
+      case 'l': /* --negotiate */
+        if(toggle) {
+          if(curlinfo->features & CURL_VERSION_SPNEGO)
+            config->authtype |= CURLAUTH_NEGOTIATE;
+          else
+            return PARAM_LIBCURL_DOESNT_SUPPORT;
+        }
+        else
+          config->authtype &= ~CURLAUTH_NEGOTIATE;
+        break;
+
+      case 'm': /* --ntlm */
+        if(toggle) {
+          if(curlinfo->features & CURL_VERSION_NTLM)
+            config->authtype |= CURLAUTH_NTLM;
+          else
+            return PARAM_LIBCURL_DOESNT_SUPPORT;
+        }
+        else
+          config->authtype &= ~CURLAUTH_NTLM;
+        break;
+
+      case 'M': /* --ntlm-wb */
+        if(toggle) {
+          if(curlinfo->features & CURL_VERSION_NTLM_WB)
+            config->authtype |= CURLAUTH_NTLM_WB;
+          else
+            return PARAM_LIBCURL_DOESNT_SUPPORT;
+        }
+        else
+          config->authtype &= ~CURLAUTH_NTLM_WB;
+        break;
+
+      case 'n': /* --basic for completeness */
+        if(toggle)
+          config->authtype |= CURLAUTH_BASIC;
+        else
+          config->authtype &= ~CURLAUTH_BASIC;
+        break;
+
+      case 'o': /* --anyauth, let libcurl pick it */
+        if(toggle)
+          config->authtype = CURLAUTH_ANY;
+        /* --no-anyauth simply doesn't touch it */
+        break;
+
+#ifdef USE_WATT32
+      case 'p': /* --wdebug */
+        dbug_init();
+        break;
+#endif
+      case 'q': /* --ftp-create-dirs */
+        config->ftp_create_dirs = toggle;
+        break;
+
+      case 'r': /* --create-dirs */
+        config->create_dirs = toggle;
+        break;
+
+      case 's': /* --max-redirs */
+        /* specified max no of redirects (http(s)), this accepts -1 as a
+           special condition */
+        err = str2num(&config->maxredirs, nextarg);
+        if(err)
+          return err;
+        if(config->maxredirs < -1)
+          return PARAM_BAD_NUMERIC;
+        break;
+
+      case 't': /* --proxy-ntlm */
+        if(curlinfo->features & CURL_VERSION_NTLM)
+          config->proxyntlm = toggle;
+        else
+          return PARAM_LIBCURL_DOESNT_SUPPORT;
+        break;
+
+      case 'u': /* --crlf */
+        /* LF -> CRLF conversion? */
+        config->crlf = toggle;
+        break;
+
+      case 'v': /* --stderr */
+        if(strcmp(nextarg, "-")) {
+          FILE *newfile = fopen(nextarg, FOPEN_WRITETEXT);
+          if(!newfile)
+            warnf(global, "Failed to open %s!\n", nextarg);
+          else {
+            if(global->errors_fopened)
+              fclose(global->errors);
+            global->errors = newfile;
+            global->errors_fopened = TRUE;
+          }
+        }
+        else
+          global->errors = stdout;
+        break;
+      case 'w': /* --interface */
+        /* interface */
+        GetStr(&config->iface, nextarg);
+        break;
+      case 'x': /* --krb */
+        /* kerberos level string */
+        if(curlinfo->features & CURL_VERSION_KERBEROS4)
+          GetStr(&config->krblevel, nextarg);
+        else
+          return PARAM_LIBCURL_DOESNT_SUPPORT;
+        break;
+      case 'y': /* --max-filesize */
+        err = str2offset(&config->max_filesize, nextarg);
+        if(err)
+          return err;
+        break;
+      case 'z': /* --disable-eprt */
+        config->disable_eprt = toggle;
+        break;
+      case 'Z': /* --eprt */
+        config->disable_eprt = (!toggle)?TRUE:FALSE;
+        break;
+      case '~': /* --xattr */
+        config->xattr = toggle;
+        break;
+      case '@': /* the URL! */
+      {
+        struct getout *url;
+
+        if(!config->url_get)
+          config->url_get = config->url_list;
+
+        if(config->url_get) {
+          /* there's a node here, if it already is filled-in continue to find
+             an "empty" node */
+          while(config->url_get && (config->url_get->flags & GETOUT_URL))
+            config->url_get = config->url_get->next;
+        }
+
+        /* now there might or might not be an available node to fill in! */
+
+        if(config->url_get)
+          /* existing node */
+          url = config->url_get;
+        else
+          /* there was no free node, create one! */
+          config->url_get = url = new_getout(config);
+
+        if(!url)
+          return PARAM_NO_MEM;
+
+        /* fill in the URL */
+        GetStr(&url->url, nextarg);
+        url->flags |= GETOUT_URL;
+      }
+      }
+      break;
+    case '$': /* more options without a short option */
+      switch(subletter) {
+      case 'a': /* --ssl */
+        if(toggle && !(curlinfo->features & CURL_VERSION_SSL))
+          return PARAM_LIBCURL_DOESNT_SUPPORT;
+        config->ftp_ssl = toggle;
+        break;
+      case 'b': /* --ftp-pasv */
+        Curl_safefree(config->ftpport);
+        break;
+      case 'c': /* --socks5 specifies a socks5 proxy to use, and resolves
+                   the name locally and passes on the resolved address */
+        GetStr(&config->proxy, nextarg);
+        config->proxyver = CURLPROXY_SOCKS5;
+        break;
+      case 't': /* --socks4 specifies a socks4 proxy to use */
+        GetStr(&config->proxy, nextarg);
+        config->proxyver = CURLPROXY_SOCKS4;
+        break;
+      case 'T': /* --socks4a specifies a socks4a proxy to use */
+        GetStr(&config->proxy, nextarg);
+        config->proxyver = CURLPROXY_SOCKS4A;
+        break;
+      case '2': /* --socks5-hostname specifies a socks5 proxy and enables name
+                   resolving with the proxy */
+        GetStr(&config->proxy, nextarg);
+        config->proxyver = CURLPROXY_SOCKS5_HOSTNAME;
+        break;
+      case 'd': /* --tcp-nodelay option */
+        config->tcp_nodelay = toggle;
+        break;
+      case 'e': /* --proxy-digest */
+        config->proxydigest = toggle;
+        break;
+      case 'f': /* --proxy-basic */
+        config->proxybasic = toggle;
+        break;
+      case 'g': /* --retry */
+        err = str2unum(&config->req_retry, nextarg);
+        if(err)
+          return err;
+        break;
+      case 'V': /* --retry-connrefused */
+        config->retry_connrefused = toggle;
+        break;
+      case 'h': /* --retry-delay */
+        err = str2unum(&config->retry_delay, nextarg);
+        if(err)
+          return err;
+        break;
+      case 'i': /* --retry-max-time */
+        err = str2unum(&config->retry_maxtime, nextarg);
+        if(err)
+          return err;
+        break;
+
+      case 'k': /* --proxy-negotiate */
+        if(curlinfo->features & CURL_VERSION_SPNEGO)
+          config->proxynegotiate = toggle;
+        else
+          return PARAM_LIBCURL_DOESNT_SUPPORT;
+        break;
+
+      case 'm': /* --ftp-account */
+        GetStr(&config->ftp_account, nextarg);
+        break;
+      case 'n': /* --proxy-anyauth */
+        config->proxyanyauth = toggle;
+        break;
+      case 'o': /* --trace-time */
+        global->tracetime = toggle;
+        break;
+      case 'p': /* --ignore-content-length */
+        config->ignorecl = toggle;
+        break;
+      case 'q': /* --ftp-skip-pasv-ip */
+        config->ftp_skip_ip = toggle;
+        break;
+      case 'r': /* --ftp-method (undocumented at this point) */
+        config->ftp_filemethod = ftpfilemethod(config, nextarg);
+        break;
+      case 's': /* --local-port */
+        rc = sscanf(nextarg, "%d - %d",
+                    &config->localport,
+                    &config->localportrange);
+        if(!rc)
+          return PARAM_BAD_USE;
+        if(rc == 1)
+          config->localportrange = 1; /* default number of ports to try */
+        else {
+          config->localportrange -= config->localport;
+          if(config->localportrange < 1) {
+            warnf(global, "bad range input\n");
+            return PARAM_BAD_USE;
+          }
+        }
+        break;
+      case 'u': /* --ftp-alternative-to-user */
+        GetStr(&config->ftp_alternative_to_user, nextarg);
+        break;
+      case 'v': /* --ssl-reqd */
+        if(toggle && !(curlinfo->features & CURL_VERSION_SSL))
+          return PARAM_LIBCURL_DOESNT_SUPPORT;
+        config->ftp_ssl_reqd = toggle;
+        break;
+      case 'w': /* --no-sessionid */
+        config->disable_sessionid = (!toggle)?TRUE:FALSE;
+        break;
+      case 'x': /* --ftp-ssl-control */
+        if(toggle && !(curlinfo->features & CURL_VERSION_SSL))
+          return PARAM_LIBCURL_DOESNT_SUPPORT;
+        config->ftp_ssl_control = toggle;
+        break;
+      case 'y': /* --ftp-ssl-ccc */
+        config->ftp_ssl_ccc = toggle;
+        if(!config->ftp_ssl_ccc_mode)
+          config->ftp_ssl_ccc_mode = CURLFTPSSL_CCC_PASSIVE;
+        break;
+      case 'j': /* --ftp-ssl-ccc-mode */
+        config->ftp_ssl_ccc = TRUE;
+        config->ftp_ssl_ccc_mode = ftpcccmethod(config, nextarg);
+        break;
+      case 'z': /* --libcurl */
+#ifdef CURL_DISABLE_LIBCURL_OPTION
+        warnf(global,
+              "--libcurl option was disabled at build-time!\n");
+        return PARAM_OPTION_UNKNOWN;
+#else
+        GetStr(&global->libcurl, nextarg);
+        break;
+#endif
+      case '#': /* --raw */
+        config->raw = toggle;
+        break;
+      case '0': /* --post301 */
+        config->post301 = toggle;
+        break;
+      case '1': /* --no-keepalive */
+        config->nokeepalive = (!toggle)?TRUE:FALSE;
+        break;
+      case '3': /* --keepalive-time */
+        err = str2unum(&config->alivetime, nextarg);
+        if(err)
+          return err;
+        break;
+      case '4': /* --post302 */
+        config->post302 = toggle;
+        break;
+      case 'I': /* --post303 */
+        config->post303 = toggle;
+        break;
+      case '5': /* --noproxy */
+        /* This specifies the noproxy list */
+        GetStr(&config->noproxy, nextarg);
+        break;
+       case '7': /* --socks5-gssapi-nec*/
+        config->socks5_gssapi_nec = toggle;
+        break;
+      case '8': /* --proxy1.0 */
+        /* http 1.0 proxy */
+        GetStr(&config->proxy, nextarg);
+        config->proxyver = CURLPROXY_HTTP_1_0;
+        break;
+      case '9': /* --tftp-blksize */
+        err = str2unum(&config->tftp_blksize, nextarg);
+        if(err)
+          return err;
+        break;
+      case 'A': /* --mail-from */
+        GetStr(&config->mail_from, nextarg);
+        break;
+      case 'B': /* --mail-rcpt */
+        /* append receiver to a list */
+        err = add2list(&config->mail_rcpt, nextarg);
+        if(err)
+          return err;
+        break;
+      case 'C': /* --ftp-pret */
+        config->ftp_pret = toggle;
+        break;
+      case 'D': /* --proto */
+        config->proto_present = TRUE;
+        if(proto2num(config, &config->proto, nextarg))
+          return PARAM_BAD_USE;
+        break;
+      case 'E': /* --proto-redir */
+        config->proto_redir_present = TRUE;
+        if(proto2num(config, &config->proto_redir, nextarg))
+          return PARAM_BAD_USE;
+        break;
+      case 'F': /* --resolve */
+        err = add2list(&config->resolve, nextarg);
+        if(err)
+          return err;
+        break;
+      case 'G': /* --delegation LEVEL */
+        config->gssapi_delegation = delegation(config, nextarg);
+        break;
+      case 'H': /* --mail-auth */
+        GetStr(&config->mail_auth, nextarg);
+        break;
+      case 'J': /* --metalink */
+        {
+#ifdef USE_METALINK
+          int mlmaj, mlmin, mlpatch;
+          metalink_get_version(&mlmaj, &mlmin, &mlpatch);
+          if((mlmaj*10000)+(mlmin*100) + mlpatch < CURL_REQ_LIBMETALINK_VERS) {
+            warnf(global,
+                  "--metalink option cannot be used because the version of "
+                  "the linked libmetalink library is too old. "
+                  "Required: %d.%d.%d, found %d.%d.%d\n",
+                  CURL_REQ_LIBMETALINK_MAJOR,
+                  CURL_REQ_LIBMETALINK_MINOR,
+                  CURL_REQ_LIBMETALINK_PATCH,
+                  mlmaj, mlmin, mlpatch);
+            return PARAM_BAD_USE;
+          }
+          else
+            config->use_metalink = toggle;
+#else
+          warnf(global, "--metalink option is ignored because the binary is "
+                "built without the Metalink support.\n");
+#endif
+          break;
+        }
+      case 'K': /* --sasl-ir */
+        config->sasl_ir = toggle;
+        break;
+      case 'L': /* --test-event */
+#ifdef CURLDEBUG
+        config->test_event_based = toggle;
+#else
+        warnf(global, "--test-event is ignored unless a debug build!\n");
+#endif
+        break;
+      case 'M': /* --unix-socket */
+        config->abstract_unix_socket = FALSE;
+        GetStr(&config->unix_socket_path, nextarg);
+        break;
+      case 'N': /* --path-as-is */
+        config->path_as_is = toggle;
+        break;
+      case 'O': /* --proxy-service-name */
+        GetStr(&config->proxy_service_name, nextarg);
+        break;
+      case 'P': /* --service-name */
+        GetStr(&config->service_name, nextarg);
+        break;
+      case 'Q': /* --proto-default */
+        GetStr(&config->proto_default, nextarg);
+        err = check_protocol(config->proto_default);
+        if(err)
+          return err;
+        break;
+      case 'R': /* --expect100-timeout */
+        err = str2udouble(&config->expect100timeout, nextarg, LONG_MAX/1000);
+        if(err)
+          return err;
+        break;
+      case 'S': /* --tftp-no-options */
+        config->tftp_no_options = toggle;
+        break;
+      case 'U': /* --connect-to */
+        err = add2list(&config->connect_to, nextarg);
+        if(err)
+          return err;
+        break;
+      case 'W': /* --abstract-unix-socket */
+        config->abstract_unix_socket = TRUE;
+        GetStr(&config->unix_socket_path, nextarg);
+        break;
+      case 'X': /* --tls-max */
+        err = str2tls_max(&config->ssl_version_max, nextarg);
+        if(err)
+          return err;
+        break;
+      case 'Y': /* --suppress-connect-headers */
+        config->suppress_connect_headers = toggle;
+        break;
+      case 'Z': /* --compressed-ssh */
+        config->ssh_compression = toggle;
+        break;
+      }
+      break;
+    case '#': /* --progress-bar */
+      if(toggle)
+        global->progressmode = CURL_PROGRESS_BAR;
+      else
+        global->progressmode = CURL_PROGRESS_STATS;
+      break;
+    case ':': /* --next */
+      return PARAM_NEXT_OPERATION;
+    case '0': /* --http* options */
+      switch(subletter) {
+      case '\0':
+        /* HTTP version 1.0 */
+        config->httpversion = CURL_HTTP_VERSION_1_0;
+        break;
+      case '1':
+        /* HTTP version 1.1 */
+        config->httpversion = CURL_HTTP_VERSION_1_1;
+        break;
+      case '2':
+        /* HTTP version 2.0 */
+        config->httpversion = CURL_HTTP_VERSION_2_0;
+        break;
+      case '3':
+        /* HTTP version 2.0 over clean TCP*/
+        config->httpversion = CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE;
+        break;
+      }
+      break;
+    case '1': /* --tlsv1* options */
+      switch(subletter) {
+      case '\0':
+        /* TLS version 1.x */
+        config->ssl_version = CURL_SSLVERSION_TLSv1;
+        break;
+      case '0':
+        /* TLS version 1.0 */
+        config->ssl_version = CURL_SSLVERSION_TLSv1_0;
+        break;
+      case '1':
+        /* TLS version 1.1 */
+        config->ssl_version = CURL_SSLVERSION_TLSv1_1;
+        break;
+      case '2':
+        /* TLS version 1.2 */
+        config->ssl_version = CURL_SSLVERSION_TLSv1_2;
+        break;
+      case '3':
+        /* TLS version 1.3 */
+        config->ssl_version = CURL_SSLVERSION_TLSv1_3;
+        break;
+      }
+      break;
+    case '2':
+      /* SSL version 2 */
+      config->ssl_version = CURL_SSLVERSION_SSLv2;
+      break;
+    case '3':
+      /* SSL version 3 */
+      config->ssl_version = CURL_SSLVERSION_SSLv3;
+      break;
+    case '4':
+      /* IPv4 */
+      config->ip_version = 4;
+      break;
+    case '6':
+      /* IPv6 */
+      config->ip_version = 6;
+      break;
+    case 'a':
+      /* This makes the FTP sessions use APPE instead of STOR */
+      config->ftp_append = toggle;
+      break;
+    case 'A':
+      /* This specifies the User-Agent name */
+      GetStr(&config->useragent, nextarg);
+      break;
+    case 'b': /* cookie string coming up: */
+      if(nextarg[0] == '@') {
+        nextarg++;
+      }
+      else if(strchr(nextarg, '=')) {
+        /* A cookie string must have a =-letter */
+        GetStr(&config->cookie, nextarg);
+        break;
+      }
+      /* We have a cookie file to read from! */
+      GetStr(&config->cookiefile, nextarg);
+      break;
+    case 'B':
+      /* use ASCII/text when transferring */
+      config->use_ascii = toggle;
+      break;
+    case 'c':
+      /* get the file name to dump all cookies in */
+      GetStr(&config->cookiejar, nextarg);
+      break;
+    case 'C':
+      /* This makes us continue an ftp transfer at given position */
+      if(strcmp(nextarg, "-")) {
+        err = str2offset(&config->resume_from, nextarg);
+        if(err)
+          return err;
+        config->resume_from_current = FALSE;
+      }
+      else {
+        config->resume_from_current = TRUE;
+        config->resume_from = 0;
+      }
+      config->use_resume = TRUE;
+      break;
+    case 'd':
+      /* postfield data */
+    {
+      char *postdata = NULL;
+      FILE *file;
+      size_t size = 0;
+      bool raw_mode = (subletter == 'r');
+
+      if(subletter == 'e') { /* --data-urlencode*/
+        /* [name]=[content], we encode the content part only
+         * [name]@[file name]
+         *
+         * Case 2: we first load the file using that name and then encode
+         * the content.
+         */
+        const char *p = strchr(nextarg, '=');
+        size_t nlen;
+        char is_file;
+        if(!p)
+          /* there was no '=' letter, check for a '@' instead */
+          p = strchr(nextarg, '@');
+        if(p) {
+          nlen = p - nextarg; /* length of the name part */
+          is_file = *p++; /* pass the separator */
+        }
+        else {
+          /* neither @ nor =, so no name and it isn't a file */
+          nlen = is_file = 0;
+          p = nextarg;
+        }
+        if('@' == is_file) {
+          /* a '@' letter, it means that a file name or - (stdin) follows */
+          if(!strcmp("-", p)) {
+            file = stdin;
+            set_binmode(stdin);
+          }
+          else {
+            file = fopen(p, "rb");
+            if(!file)
+              warnf(global,
+                    "Couldn't read data from file \"%s\", this makes "
+                    "an empty POST.\n", nextarg);
+          }
+
+          err = file2memory(&postdata, &size, file);
+
+          if(file && (file != stdin))
+            fclose(file);
+          if(err)
+            return err;
+        }
+        else {
+          GetStr(&postdata, p);
+          if(postdata)
+            size = strlen(postdata);
+        }
+
+        if(!postdata) {
+          /* no data from the file, point to a zero byte string to make this
+             get sent as a POST anyway */
+          postdata = strdup("");
+          if(!postdata)
+            return PARAM_NO_MEM;
+          size = 0;
+        }
+        else {
+          char *enc = curl_easy_escape(config->easy, postdata, (int)size);
+          Curl_safefree(postdata); /* no matter if it worked or not */
+          if(enc) {
+            /* now make a string with the name from above and append the
+               encoded string */
+            size_t outlen = nlen + strlen(enc) + 2;
+            char *n = malloc(outlen);
+            if(!n) {
+              curl_free(enc);
+              return PARAM_NO_MEM;
+            }
+            if(nlen > 0) { /* only append '=' if we have a name */
+              snprintf(n, outlen, "%.*s=%s", nlen, nextarg, enc);
+              size = outlen-1;
+            }
+            else {
+              strcpy(n, enc);
+              size = outlen-2; /* since no '=' was inserted */
+            }
+            curl_free(enc);
+            postdata = n;
+          }
+          else
+            return PARAM_NO_MEM;
+        }
+      }
+      else if('@' == *nextarg && !raw_mode) {
+        /* the data begins with a '@' letter, it means that a file name
+           or - (stdin) follows */
+        nextarg++; /* pass the @ */
+
+        if(!strcmp("-", nextarg)) {
+          file = stdin;
+          if(subletter == 'b') /* forced data-binary */
+            set_binmode(stdin);
+        }
+        else {
+          file = fopen(nextarg, "rb");
+          if(!file)
+            warnf(global, "Couldn't read data from file \"%s\", this makes "
+                  "an empty POST.\n", nextarg);
+        }
+
+        if(subletter == 'b')
+          /* forced binary */
+          err = file2memory(&postdata, &size, file);
+        else {
+          err = file2string(&postdata, file);
+          if(postdata)
+            size = strlen(postdata);
+        }
+
+        if(file && (file != stdin))
+          fclose(file);
+        if(err)
+          return err;
+
+        if(!postdata) {
+          /* no data from the file, point to a zero byte string to make this
+             get sent as a POST anyway */
+          postdata = strdup("");
+          if(!postdata)
+            return PARAM_NO_MEM;
+        }
+      }
+      else {
+        GetStr(&postdata, nextarg);
+        if(postdata)
+          size = strlen(postdata);
+      }
+
+#ifdef CURL_DOES_CONVERSIONS
+      if(subletter != 'b') {
+        /* NOT forced binary, convert to ASCII */
+        if(convert_to_network(postdata, strlen(postdata))) {
+          Curl_safefree(postdata);
+          return PARAM_NO_MEM;
+        }
+      }
+#endif
+
+      if(config->postfields) {
+        /* we already have a string, we append this one with a separating
+           &-letter */
+        char *oldpost = config->postfields;
+        curl_off_t oldlen = config->postfieldsize;
+        curl_off_t newlen = oldlen + curlx_uztoso(size) + 2;
+        config->postfields = malloc((size_t)newlen);
+        if(!config->postfields) {
+          Curl_safefree(oldpost);
+          Curl_safefree(postdata);
+          return PARAM_NO_MEM;
+        }
+        memcpy(config->postfields, oldpost, (size_t)oldlen);
+        /* use byte value 0x26 for '&' to accommodate non-ASCII platforms */
+        config->postfields[oldlen] = '\x26';
+        memcpy(&config->postfields[oldlen + 1], postdata, size);
+        config->postfields[oldlen + 1 + size] = '\0';
+        Curl_safefree(oldpost);
+        Curl_safefree(postdata);
+        config->postfieldsize += size + 1;
+      }
+      else {
+        config->postfields = postdata;
+        config->postfieldsize = curlx_uztoso(size);
+      }
+    }
+    /*
+      We can't set the request type here, as this data might be used in
+      a simple GET if -G is used. Already or soon.
+
+      if(SetHTTPrequest(HTTPREQ_SIMPLEPOST, &config->httpreq)) {
+        Curl_safefree(postdata);
+        return PARAM_BAD_USE;
+      }
+    */
+    break;
+    case 'D':
+      /* dump-header to given file name */
+      GetStr(&config->headerfile, nextarg);
+      break;
+    case 'e':
+    {
+      char *ptr = strstr(nextarg, ";auto");
+      if(ptr) {
+        /* Automatic referer requested, this may be combined with a
+           set initial one */
+        config->autoreferer = TRUE;
+        *ptr = 0; /* zero terminate here */
+      }
+      else
+        config->autoreferer = FALSE;
+      GetStr(&config->referer, nextarg);
+    }
+    break;
+    case 'E':
+      switch(subletter) {
+      case '\0': /* certificate file */
+        GetFileAndPassword(nextarg, &config->cert, &config->key_passwd);
+        break;
+      case 'a': /* CA info PEM file */
+        /* CA info PEM file */
+        GetStr(&config->cacert, nextarg);
+        break;
+      case 'b': /* cert file type */
+        GetStr(&config->cert_type, nextarg);
+        break;
+      case 'c': /* private key file */
+        GetStr(&config->key, nextarg);
+        break;
+      case 'd': /* private key file type */
+        GetStr(&config->key_type, nextarg);
+        break;
+      case 'e': /* private key passphrase */
+        GetStr(&config->key_passwd, nextarg);
+        cleanarg(nextarg);
+        break;
+      case 'f': /* crypto engine */
+        GetStr(&config->engine, nextarg);
+        if(config->engine && curl_strequal(config->engine, "list"))
+          return PARAM_ENGINES_REQUESTED;
+        break;
+      case 'g': /* CA info PEM file */
+        /* CA cert directory */
+        GetStr(&config->capath, nextarg);
+        break;
+      case 'h': /* --pubkey public key file */
+        GetStr(&config->pubkey, nextarg);
+        break;
+      case 'i': /* --hostpubmd5 md5 of the host public key */
+        GetStr(&config->hostpubmd5, nextarg);
+        if(!config->hostpubmd5 || strlen(config->hostpubmd5) != 32)
+          return PARAM_BAD_USE;
+        break;
+      case 'j': /* CRL info PEM file */
+        /* CRL file */
+        GetStr(&config->crlfile, nextarg);
+        break;
+      case 'k': /* TLS username */
+        if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP)
+          GetStr(&config->tls_username, nextarg);
+        else
+          return PARAM_LIBCURL_DOESNT_SUPPORT;
+        break;
+      case 'l': /* TLS password */
+        if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP)
+          GetStr(&config->tls_password, nextarg);
+        else
+          return PARAM_LIBCURL_DOESNT_SUPPORT;
+        break;
+      case 'm': /* TLS authentication type */
+        if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP) {
+          GetStr(&config->tls_authtype, nextarg);
+          if(!curl_strequal(config->tls_authtype, "SRP"))
+            return PARAM_LIBCURL_DOESNT_SUPPORT; /* only support TLS-SRP */
+        }
+        else
+          return PARAM_LIBCURL_DOESNT_SUPPORT;
+        break;
+      case 'n': /* no empty SSL fragments, --ssl-allow-beast */
+        if(curlinfo->features & CURL_VERSION_SSL)
+          config->ssl_allow_beast = toggle;
+        break;
+
+      case 'o': /* --login-options */
+        GetStr(&config->login_options, nextarg);
+        break;
+
+      case 'p': /* Pinned public key DER file */
+        /* Pinned public key DER file */
+        GetStr(&config->pinnedpubkey, nextarg);
+        break;
+
+      case 'q': /* --cert-status */
+        config->verifystatus = TRUE;
+        break;
+
+      case 'r': /* --false-start */
+        config->falsestart = TRUE;
+        break;
+
+      case 's': /* --ssl-no-revoke */
+        if(curlinfo->features & CURL_VERSION_SSL)
+          config->ssl_no_revoke = TRUE;
+        break;
+
+      case 't': /* --tcp-fastopen */
+        config->tcp_fastopen = TRUE;
+        break;
+
+      case 'u': /* TLS username for proxy */
+        if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP)
+          GetStr(&config->proxy_tls_username, nextarg);
+        else
+          return PARAM_LIBCURL_DOESNT_SUPPORT;
+        break;
+
+      case 'v': /* TLS password for proxy */
+        if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP)
+          GetStr(&config->proxy_tls_password, nextarg);
+        else
+          return PARAM_LIBCURL_DOESNT_SUPPORT;
+        break;
+
+      case 'w': /* TLS authentication type for proxy */
+        if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP) {
+          GetStr(&config->proxy_tls_authtype, nextarg);
+          if(!curl_strequal(config->proxy_tls_authtype, "SRP"))
+            return PARAM_LIBCURL_DOESNT_SUPPORT; /* only support TLS-SRP */
+        }
+        else
+          return PARAM_LIBCURL_DOESNT_SUPPORT;
+        break;
+
+      case 'x': /* certificate file for proxy */
+        GetFileAndPassword(nextarg, &config->proxy_cert,
+                           &config->proxy_key_passwd);
+        break;
+
+      case 'y': /* cert file type for proxy */
+        GetStr(&config->proxy_cert_type, nextarg);
+        break;
+
+      case 'z': /* private key file for proxy */
+        GetStr(&config->proxy_key, nextarg);
+        break;
+
+      case '0': /* private key file type for proxy */
+        GetStr(&config->proxy_key_type, nextarg);
+        break;
+
+      case '1': /* private key passphrase for proxy */
+        GetStr(&config->proxy_key_passwd, nextarg);
+        cleanarg(nextarg);
+        break;
+
+      case '2': /* ciphers for proxy */
+        GetStr(&config->proxy_cipher_list, nextarg);
+        break;
+
+      case '3': /* CRL info PEM file for proxy */
+        /* CRL file */
+        GetStr(&config->proxy_crlfile, nextarg);
+        break;
+
+      case '4': /* no empty SSL fragments for proxy */
+        if(curlinfo->features & CURL_VERSION_SSL)
+          config->proxy_ssl_allow_beast = toggle;
+        break;
+
+      case '5': /* --login-options */
+        GetStr(&config->login_options, nextarg);
+        break;
+
+      case '6': /* CA info PEM file for proxy */
+        /* CA info PEM file */
+        GetStr(&config->proxy_cacert, nextarg);
+        break;
+
+      case '7': /* CA info PEM file for proxy */
+        /* CA cert directory */
+        GetStr(&config->proxy_capath, nextarg);
+        break;
+
+      case '8': /* allow insecure SSL connects for proxy */
+        config->proxy_insecure_ok = toggle;
+        break;
+
+      case '9': /* --proxy-tlsv1 */
+        /* TLS version 1 for proxy */
+        config->proxy_ssl_version = CURL_SSLVERSION_TLSv1;
+        break;
+
+      case 'A':
+        /* --socks5-basic */
+        if(toggle)
+          config->socks5_auth |= CURLAUTH_BASIC;
+        else
+          config->socks5_auth &= ~CURLAUTH_BASIC;
+        break;
+
+      case 'B':
+        /* --socks5-gssapi */
+        if(toggle)
+          config->socks5_auth |= CURLAUTH_GSSAPI;
+        else
+          config->socks5_auth &= ~CURLAUTH_GSSAPI;
+        break;
+
+      default: /* unknown flag */
+        return PARAM_OPTION_UNKNOWN;
+      }
+      break;
+    case 'f':
+      switch(subletter) {
+      case 'a': /* --fail-early */
+        global->fail_early = toggle;
+        break;
+      default:
+        /* fail hard on errors  */
+        config->failonerror = toggle;
+      }
+      break;
+    case 'F':
+      /* "form data" simulation, this is a little advanced so lets do our best
+         to sort this out slowly and carefully */
+      if(formparse(config,
+                   nextarg,
+                   &config->mimepost,
+                   &config->mimecurrent,
+                   (subletter == 's')?TRUE:FALSE)) /* 's' is literal string */
+        return PARAM_BAD_USE;
+      if(SetHTTPrequest(config, HTTPREQ_MIMEPOST, &config->httpreq))
+        return PARAM_BAD_USE;
+      break;
+
+    case 'g': /* g disables URLglobbing */
+      config->globoff = toggle;
+      break;
+
+    case 'G': /* HTTP GET */
+      if(subletter == 'a') { /* --request-target */
+        GetStr(&config->request_target, nextarg);
+      }
+      else
+        config->use_httpget = TRUE;
+      break;
+
+    case 'h': /* h for help */
+      if(toggle) {
+        return PARAM_HELP_REQUESTED;
+      }
+      /* we now actually support --no-help too! */
+      break;
+    case 'H':
+      /* A custom header to append to a list */
+      if(nextarg[0] == '@') {
+        /* read many headers from a file or stdin */
+        char *string;
+        size_t len;
+        bool use_stdin = !strcmp(&nextarg[1], "-");
+        FILE *file = use_stdin?stdin:fopen(&nextarg[1], FOPEN_READTEXT);
+        if(!file)
+          warnf(global, "Failed to open %s!\n", &nextarg[1]);
+        else {
+          err = file2memory(&string, &len, file);
+          if(!err) {
+            /* Allow strtok() here since this isn't used threaded */
+            /* !checksrc! disable BANNEDFUNC 2 */
+            char *h = strtok(string, "\r\n");
+            while(h) {
+              if(subletter == 'p') /* --proxy-header */
+                err = add2list(&config->proxyheaders, h);
+              else
+                err = add2list(&config->headers, h);
+              if(err)
+                break;
+              h = strtok(NULL, "\r\n");
+            }
+            free(string);
+          }
+          if(!use_stdin)
+            fclose(file);
+          if(err)
+            return err;
+        }
+      }
+      else {
+        if(subletter == 'p') /* --proxy-header */
+          err = add2list(&config->proxyheaders, nextarg);
+        else
+          err = add2list(&config->headers, nextarg);
+        if(err)
+          return err;
+      }
+      break;
+    case 'i':
+      config->include_headers = toggle; /* include the headers as well in the
+                                           general output stream */
+      break;
+    case 'j':
+      config->cookiesession = toggle;
+      break;
+    case 'I':
+      /*
+       * no_body will imply include_headers later on
+       */
+      config->no_body = toggle;
+      if(SetHTTPrequest(config,
+                        (config->no_body)?HTTPREQ_HEAD:HTTPREQ_GET,
+                        &config->httpreq))
+        return PARAM_BAD_USE;
+      break;
+    case 'J': /* --remote-header-name */
+      if(config->include_headers) {
+        warnf(global,
+              "--include and --remote-header-name cannot be combined.\n");
+        return PARAM_BAD_USE;
+      }
+      config->content_disposition = toggle;
+      break;
+    case 'k': /* allow insecure SSL connects */
+      config->insecure_ok = toggle;
+      break;
+    case 'K': /* parse config file */
+      if(parseconfig(nextarg, global))
+        warnf(global, "error trying read config from the '%s' file\n",
+              nextarg);
+      break;
+    case 'l':
+      config->dirlistonly = toggle; /* only list the names of the FTP dir */
+      break;
+    case 'L':
+      config->followlocation = toggle; /* Follow Location: HTTP headers */
+      switch(subletter) {
+      case 't':
+        /* Continue to send authentication (user+password) when following
+         * locations, even when hostname changed */
+        config->unrestricted_auth = toggle;
+        break;
+      }
+      break;
+    case 'm':
+      /* specified max time */
+      err = str2udouble(&config->timeout, nextarg, LONG_MAX/1000);
+      if(err)
+        return err;
+      break;
+    case 'M': /* M for manual, huge help */
+      if(toggle) { /* --no-manual shows no manual... */
+#ifdef USE_MANUAL
+        return PARAM_MANUAL_REQUESTED;
+#else
+        warnf(global,
+              "built-in manual was disabled at build-time!\n");
+        return PARAM_OPTION_UNKNOWN;
+#endif
+      }
+      break;
+    case 'n':
+      switch(subletter) {
+      case 'o': /* CA info PEM file */
+        /* use .netrc or URL */
+        config->netrc_opt = toggle;
+        break;
+      case 'e': /* netrc-file */
+        GetStr(&config->netrc_file, nextarg);
+        break;
+      default:
+        /* pick info from .netrc, if this is used for http, curl will
+           automatically enfore user+password with the request */
+        config->netrc = toggle;
+        break;
+      }
+      break;
+    case 'N':
+      /* disable the output I/O buffering. note that the option is called
+         --buffer but is mostly used in the negative form: --no-buffer */
+      if(longopt)
+        config->nobuffer = (!toggle)?TRUE:FALSE;
+      else
+        config->nobuffer = toggle;
+      break;
+    case 'O': /* --remote-name */
+      if(subletter == 'a') { /* --remote-name-all */
+        config->default_node_flags = toggle?GETOUT_USEREMOTE:0;
+        break;
+      }
+      /* fall-through! */
+    case 'o': /* --output */
+      /* output file */
+    {
+      struct getout *url;
+      if(!config->url_out)
+        config->url_out = config->url_list;
+      if(config->url_out) {
+        /* there's a node here, if it already is filled-in continue to find
+           an "empty" node */
+        while(config->url_out && (config->url_out->flags & GETOUT_OUTFILE))
+          config->url_out = config->url_out->next;
+      }
+
+      /* now there might or might not be an available node to fill in! */
+
+      if(config->url_out)
+        /* existing node */
+        url = config->url_out;
+      else
+        /* there was no free node, create one! */
+        config->url_out = url = new_getout(config);
+
+      if(!url)
+        return PARAM_NO_MEM;
+
+      /* fill in the outfile */
+      if('o' == letter) {
+        GetStr(&url->outfile, nextarg);
+        url->flags &= ~GETOUT_USEREMOTE; /* switch off */
+      }
+      else {
+        url->outfile = NULL; /* leave it */
+        if(toggle)
+          url->flags |= GETOUT_USEREMOTE;  /* switch on */
+        else
+          url->flags &= ~GETOUT_USEREMOTE; /* switch off */
+      }
+      url->flags |= GETOUT_OUTFILE;
+    }
+    break;
+    case 'P':
+      /* This makes the FTP sessions use PORT instead of PASV */
+      /* use <eth0> or <192.168.10.10> style addresses. Anything except
+         this will make us try to get the "default" address.
+         NOTE: this is a changed behaviour since the released 4.1!
+      */
+      GetStr(&config->ftpport, nextarg);
+      break;
+    case 'p':
+      /* proxy tunnel for non-http protocols */
+      config->proxytunnel = toggle;
+      break;
+
+    case 'q': /* if used first, already taken care of, we do it like
+                 this so we don't cause an error! */
+      break;
+    case 'Q':
+      /* QUOTE command to send to FTP server */
+      switch(nextarg[0]) {
+      case '-':
+        /* prefixed with a dash makes it a POST TRANSFER one */
+        nextarg++;
+        err = add2list(&config->postquote, nextarg);
+        break;
+      case '+':
+        /* prefixed with a plus makes it a just-before-transfer one */
+        nextarg++;
+        err = add2list(&config->prequote, nextarg);
+        break;
+      default:
+        err = add2list(&config->quote, nextarg);
+        break;
+      }
+      if(err)
+        return err;
+      break;
+    case 'r':
+      /* Specifying a range WITHOUT A DASH will create an illegal HTTP range
+         (and won't actually be range by definition). The man page previously
+         claimed that to be a good way, why this code is added to work-around
+         it. */
+      if(ISDIGIT(*nextarg) && !strchr(nextarg, '-')) {
+        char buffer[32];
+        curl_off_t off;
+        if(curlx_strtoofft(nextarg, NULL, 10, &off)) {
+          warnf(global, "unsupported range point\n");
+          return PARAM_BAD_USE;
+        }
+        warnf(global,
+              "A specified range MUST include at least one dash (-). "
+              "Appending one for you!\n");
+        snprintf(buffer, sizeof(buffer), "%" CURL_FORMAT_CURL_OFF_T "-", off);
+        Curl_safefree(config->range);
+        config->range = strdup(buffer);
+        if(!config->range)
+          return PARAM_NO_MEM;
+      }
+      {
+        /* byte range requested */
+        char *tmp_range;
+        tmp_range = nextarg;
+        while(*tmp_range != '\0') {
+          if(!ISDIGIT(*tmp_range) && *tmp_range != '-' && *tmp_range != ',') {
+            warnf(global, "Invalid character is found in given range. "
+                  "A specified range MUST have only digits in "
+                  "\'start\'-\'stop\'. The server's response to this "
+                  "request is uncertain.\n");
+            break;
+          }
+          tmp_range++;
+        }
+        /* byte range requested */
+        GetStr(&config->range, nextarg);
+      }
+      break;
+    case 'R':
+      /* use remote file's time */
+      config->remote_time = toggle;
+      break;
+    case 's':
+      /* don't show progress meter, don't show errors : */
+      if(toggle)
+        global->mute = global->noprogress = TRUE;
+      else
+        global->mute = global->noprogress = FALSE;
+      if(global->showerror < 0)
+        /* if still on the default value, set showerror to the reverse of
+           toggle. This is to allow -S and -s to be used in an independent
+           order but still have the same effect. */
+        global->showerror = (!toggle)?TRUE:FALSE; /* toggle off */
+      break;
+    case 'S':
+      /* show errors */
+      global->showerror = toggle?1:0; /* toggle on if used with -s */
+      break;
+    case 't':
+      /* Telnet options */
+      err = add2list(&config->telnet_options, nextarg);
+      if(err)
+        return err;
+      break;
+    case 'T':
+      /* we are uploading */
+    {
+      struct getout *url;
+      if(!config->url_ul)
+        config->url_ul = config->url_list;
+      if(config->url_ul) {
+        /* there's a node here, if it already is filled-in continue to find
+           an "empty" node */
+        while(config->url_ul && (config->url_ul->flags & GETOUT_UPLOAD))
+          config->url_ul = config->url_ul->next;
+      }
+
+      /* now there might or might not be an available node to fill in! */
+
+      if(config->url_ul)
+        /* existing node */
+        url = config->url_ul;
+      else
+        /* there was no free node, create one! */
+        config->url_ul = url = new_getout(config);
+
+      if(!url)
+        return PARAM_NO_MEM;
+
+      url->flags |= GETOUT_UPLOAD; /* mark -T used */
+      if(!*nextarg)
+        url->flags |= GETOUT_NOUPLOAD;
+      else {
+        /* "-" equals stdin, but keep the string around for now */
+        GetStr(&url->infile, nextarg);
+      }
+    }
+    break;
+    case 'u':
+      /* user:password  */
+      GetStr(&config->userpwd, nextarg);
+      cleanarg(nextarg);
+      break;
+    case 'U':
+      /* Proxy user:password  */
+      GetStr(&config->proxyuserpwd, nextarg);
+      cleanarg(nextarg);
+      break;
+    case 'v':
+      if(toggle) {
+        /* the '%' thing here will cause the trace get sent to stderr */
+        Curl_safefree(global->trace_dump);
+        global->trace_dump = strdup("%");
+        if(!global->trace_dump)
+          return PARAM_NO_MEM;
+        if(global->tracetype && (global->tracetype != TRACE_PLAIN))
+          warnf(global,
+                "-v, --verbose overrides an earlier trace/verbose option\n");
+        global->tracetype = TRACE_PLAIN;
+      }
+      else
+        /* verbose is disabled here */
+        global->tracetype = TRACE_NONE;
+      break;
+    case 'V':
+      if(toggle)    /* --no-version yields no output! */
+        return PARAM_VERSION_INFO_REQUESTED;
+      break;
+
+    case 'w':
+      /* get the output string */
+      if('@' == *nextarg) {
+        /* the data begins with a '@' letter, it means that a file name
+           or - (stdin) follows */
+        FILE *file;
+        const char *fname;
+        nextarg++; /* pass the @ */
+        if(!strcmp("-", nextarg)) {
+          fname = "<stdin>";
+          file = stdin;
+        }
+        else {
+          fname = nextarg;
+          file = fopen(nextarg, FOPEN_READTEXT);
+        }
+        err = file2string(&config->writeout, file);
+        if(file && (file != stdin))
+          fclose(file);
+        if(err)
+          return err;
+        if(!config->writeout)
+          warnf(global, "Failed to read %s", fname);
+      }
+      else
+        GetStr(&config->writeout, nextarg);
+      break;
+    case 'x':
+      switch(subletter) {
+      case 'a': /* --preproxy */
+        GetStr(&config->preproxy, nextarg);
+        break;
+      default:
+        /* --proxy */
+        GetStr(&config->proxy, nextarg);
+        config->proxyver = CURLPROXY_HTTP;
+        break;
+      }
+      break;
+    case 'X':
+      /* set custom request */
+      GetStr(&config->customrequest, nextarg);
+      break;
+    case 'y':
+      /* low speed time */
+      err = str2unum(&config->low_speed_time, nextarg);
+      if(err)
+        return err;
+      if(!config->low_speed_limit)
+        config->low_speed_limit = 1;
+      break;
+    case 'Y':
+      /* low speed limit */
+      err = str2unum(&config->low_speed_limit, nextarg);
+      if(err)
+        return err;
+      if(!config->low_speed_time)
+        config->low_speed_time = 30;
+      break;
+    case 'z': /* time condition coming up */
+      switch(*nextarg) {
+      case '+':
+        nextarg++;
+        /* FALLTHROUGH */
+      default:
+        /* If-Modified-Since: (section 14.28 in RFC2068) */
+        config->timecond = CURL_TIMECOND_IFMODSINCE;
+        break;
+      case '-':
+        /* If-Unmodified-Since:  (section 14.24 in RFC2068) */
+        config->timecond = CURL_TIMECOND_IFUNMODSINCE;
+        nextarg++;
+        break;
+      case '=':
+        /* Last-Modified:  (section 14.29 in RFC2068) */
+        config->timecond = CURL_TIMECOND_LASTMOD;
+        nextarg++;
+        break;
+      }
+      now = time(NULL);
+      config->condtime = curl_getdate(nextarg, &now);
+      if(-1 == (int)config->condtime) {
+        /* now let's see if it is a file name to get the time from instead! */
+        struct_stat statbuf;
+        if(-1 == stat(nextarg, &statbuf)) {
+          /* failed, remove time condition */
+          config->timecond = CURL_TIMECOND_NONE;
+          warnf(global,
+                "Illegal date format for -z, --time-cond (and not "
+                "a file name). Disabling time condition. "
+                "See curl_getdate(3) for valid date syntax.\n");
+        }
+        else {
+          /* pull the time out from the file */
+          config->condtime = statbuf.st_mtime;
+        }
+      }
+      break;
+    default: /* unknown flag */
+      return PARAM_OPTION_UNKNOWN;
+    }
+    hit = -1;
+
+  } while(!longopt && !singleopt && *++parse && !*usedarg);
+
+  return PARAM_OK;
+}
+
+ParameterError parse_args(struct GlobalConfig *config, int argc,
+                          argv_item_t argv[])
+{
+  int i;
+  bool stillflags;
+  char *orig_opt = NULL;
+  ParameterError result = PARAM_OK;
+  struct OperationConfig *operation = config->first;
+
+  for(i = 1, stillflags = TRUE; i < argc && !result; i++) {
+    orig_opt = argv[i];
+
+    if(stillflags && ('-' == argv[i][0])) {
+      char *nextarg;
+      bool passarg;
+      char *flag = argv[i];
+
+      if(!strcmp("--", argv[i]))
+        /* This indicates the end of the flags and thus enables the
+           following (URL) argument to start with -. */
+        stillflags = FALSE;
+      else {
+        nextarg = (i < (argc - 1)) ? argv[i + 1] : NULL;
+
+        result = getparameter(flag, nextarg, &passarg, config, operation);
+        if(result == PARAM_NEXT_OPERATION) {
+          /* Reset result as PARAM_NEXT_OPERATION is only used here and not
+             returned from this function */
+          result = PARAM_OK;
+
+          if(operation->url_list && operation->url_list->url) {
+            /* Allocate the next config */
+            operation->next = malloc(sizeof(struct OperationConfig));
+            if(operation->next) {
+              /* Initialise the newly created config */
+              config_init(operation->next);
+
+              /* Copy the easy handle */
+              operation->next->easy = config->easy;
+
+              /* Set the global config pointer */
+              operation->next->global = config;
+
+              /* Update the last operation pointer */
+              config->last = operation->next;
+
+              /* Move onto the new config */
+              operation->next->prev = operation;
+              operation = operation->next;
+            }
+            else
+              result = PARAM_NO_MEM;
+          }
+        }
+        else if(!result && passarg)
+          i++; /* we're supposed to skip this */
+      }
+    }
+    else {
+      bool used;
+
+      /* Just add the URL please */
+      result = getparameter((char *)"--url", argv[i], &used, config,
+                            operation);
+    }
+  }
+
+  if(result && result != PARAM_HELP_REQUESTED &&
+     result != PARAM_MANUAL_REQUESTED &&
+     result != PARAM_VERSION_INFO_REQUESTED &&
+     result != PARAM_ENGINES_REQUESTED) {
+    const char *reason = param2text(result);
+
+    if(orig_opt && strcmp(":", orig_opt))
+      helpf(config->errors, "option %s: %s\n", orig_opt, reason);
+    else
+      helpf(config->errors, "%s\n", reason);
+  }
+
+  return result;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_getparam.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_getparam.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_getparam.h	(revision 331)
@@ -0,0 +1,65 @@
+#ifndef HEADER_CURL_TOOL_GETPARAM_H
+#define HEADER_CURL_TOOL_GETPARAM_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+typedef enum {
+  PARAM_OK = 0,
+  PARAM_OPTION_AMBIGUOUS,
+  PARAM_OPTION_UNKNOWN,
+  PARAM_REQUIRES_PARAMETER,
+  PARAM_BAD_USE,
+  PARAM_HELP_REQUESTED,
+  PARAM_MANUAL_REQUESTED,
+  PARAM_VERSION_INFO_REQUESTED,
+  PARAM_ENGINES_REQUESTED,
+  PARAM_GOT_EXTRA_PARAMETER,
+  PARAM_BAD_NUMERIC,
+  PARAM_NEGATIVE_NUMERIC,
+  PARAM_LIBCURL_DOESNT_SUPPORT,
+  PARAM_LIBCURL_UNSUPPORTED_PROTOCOL,
+  PARAM_NO_MEM,
+  PARAM_NEXT_OPERATION,
+  PARAM_NO_PREFIX,
+  PARAM_NUMBER_TOO_LARGE,
+  PARAM_LAST
+} ParameterError;
+
+struct GlobalConfig;
+struct OperationConfig;
+
+ParameterError getparameter(const char *flag, char *nextarg, bool *usedarg,
+                            struct GlobalConfig *global,
+                            struct OperationConfig *operation);
+
+#ifdef UNITTESTS
+void parse_cert_parameter(const char *cert_parameter,
+                          char **certname,
+                          char **passphrase);
+#endif
+
+ParameterError parse_args(struct GlobalConfig *config, int argc,
+                          argv_item_t argv[]);
+
+#endif /* HEADER_CURL_TOOL_GETPARAM_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_getpass.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_getpass.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_getpass.c	(revision 331)
@@ -0,0 +1,254 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#ifndef HAVE_GETPASS_R
+/* this file is only for systems without getpass_r() */
+
+#ifdef HAVE_FCNTL_H
+#  include <fcntl.h>
+#endif
+
+#ifdef HAVE_TERMIOS_H
+#  include <termios.h>
+#elif defined(HAVE_TERMIO_H)
+#  include <termio.h>
+#endif
+
+#ifdef __VMS
+#  include descrip
+#  include starlet
+#  include iodef
+#endif
+
+#ifdef WIN32
+#  include <conio.h>
+#endif
+
+#ifdef NETWARE
+#  ifdef __NOVELL_LIBC__
+#    include <screen.h>
+#  else
+#    include <nwconio.h>
+#  endif
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include "tool_getpass.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+#ifdef __VMS
+/* VMS implementation */
+char *getpass_r(const char *prompt, char *buffer, size_t buflen)
+{
+  long sts;
+  short chan;
+
+  /* MSK, 23-JAN-2004, iosbdef.h wasn't in VAX V7.2 or CC 6.4  */
+  /* distribution so I created this.  May revert back later to */
+  /* struct _iosb iosb;                                        */
+  struct _iosb
+     {
+     short int iosb$w_status; /* status     */
+     short int iosb$w_bcnt;   /* byte count */
+     int       unused;        /* unused     */
+     } iosb;
+
+  $DESCRIPTOR(ttdesc, "TT");
+
+  buffer[0] = '\0';
+  sts = sys$assign(&ttdesc, &chan, 0, 0);
+  if(sts & 1) {
+    sts = sys$qiow(0, chan,
+                   IO$_READPROMPT | IO$M_NOECHO,
+                   &iosb, 0, 0, buffer, buflen, 0, 0,
+                   prompt, strlen(prompt));
+
+    if((sts & 1) && (iosb.iosb$w_status & 1))
+      buffer[iosb.iosb$w_bcnt] = '\0';
+
+    sts = sys$dassgn(chan);
+  }
+  return buffer; /* we always return success */
+}
+#define DONE
+#endif /* __VMS */
+
+#ifdef __SYMBIAN32__
+#  define getch() getchar()
+#endif
+
+#if defined(WIN32) || defined(__SYMBIAN32__)
+
+char *getpass_r(const char *prompt, char *buffer, size_t buflen)
+{
+  size_t i;
+  fputs(prompt, stderr);
+
+  for(i = 0; i < buflen; i++) {
+    buffer[i] = (char)getch();
+    if(buffer[i] == '\r' || buffer[i] == '\n') {
+      buffer[i] = '\0';
+      break;
+    }
+    else
+      if(buffer[i] == '\b')
+        /* remove this letter and if this is not the first key, remove the
+           previous one as well */
+        i = i - (i >= 1 ? 2 : 1);
+  }
+#ifndef __SYMBIAN32__
+  /* since echo is disabled, print a newline */
+  fputs("\n", stderr);
+#endif
+  /* if user didn't hit ENTER, terminate buffer */
+  if(i == buflen)
+    buffer[buflen-1] = '\0';
+
+  return buffer; /* we always return success */
+}
+#define DONE
+#endif /* WIN32 || __SYMBIAN32__ */
+
+#ifdef NETWARE
+/* NetWare implementation */
+#ifdef __NOVELL_LIBC__
+char *getpass_r(const char *prompt, char *buffer, size_t buflen)
+{
+  return getpassword(prompt, buffer, buflen);
+}
+#else
+char *getpass_r(const char *prompt, char *buffer, size_t buflen)
+{
+  size_t i = 0;
+
+  printf("%s", prompt);
+  do {
+    buffer[i++] = getch();
+    if(buffer[i-1] == '\b') {
+      /* remove this letter and if this is not the first key,
+         remove the previous one as well */
+      if(i > 1) {
+        printf("\b \b");
+        i = i - 2;
+      }
+      else {
+        RingTheBell();
+        i = i - 1;
+      }
+    }
+    else if(buffer[i-1] != 13)
+      putchar('*');
+
+  } while((buffer[i-1] != 13) && (i < buflen));
+  buffer[i-1] = '\0';
+  printf("\r\n");
+  return buffer;
+}
+#endif /* __NOVELL_LIBC__ */
+#define DONE
+#endif /* NETWARE */
+
+#ifndef DONE /* not previously provided */
+
+#ifdef HAVE_TERMIOS_H
+#  define struct_term  struct termios
+#elif defined(HAVE_TERMIO_H)
+#  define struct_term  struct termio
+#else
+#  undef  struct_term
+#endif
+
+static bool ttyecho(bool enable, int fd)
+{
+#ifdef struct_term
+  static struct_term withecho;
+  static struct_term noecho;
+#endif
+  if(!enable) {
+    /* disable echo by extracting the current 'withecho' mode and remove the
+       ECHO bit and set back the struct */
+#ifdef HAVE_TERMIOS_H
+    tcgetattr(fd, &withecho);
+    noecho = withecho;
+    noecho.c_lflag &= ~ECHO;
+    tcsetattr(fd, TCSANOW, &noecho);
+#elif defined(HAVE_TERMIO_H)
+    ioctl(fd, TCGETA, &withecho);
+    noecho = withecho;
+    noecho.c_lflag &= ~ECHO;
+    ioctl(fd, TCSETA, &noecho);
+#else
+    /* neither HAVE_TERMIO_H nor HAVE_TERMIOS_H, we can't disable echo! */
+    (void)fd;
+    return FALSE; /* not disabled */
+#endif
+    return TRUE; /* disabled */
+  }
+  /* re-enable echo, assumes we disabled it before (and set the structs we
+     now use to reset the terminal status) */
+#ifdef HAVE_TERMIOS_H
+  tcsetattr(fd, TCSAFLUSH, &withecho);
+#elif defined(HAVE_TERMIO_H)
+  ioctl(fd, TCSETA, &withecho);
+#else
+  return FALSE; /* not enabled */
+#endif
+  return TRUE; /* enabled */
+}
+
+char *getpass_r(const char *prompt, /* prompt to display */
+                char *password,     /* buffer to store password in */
+                size_t buflen)      /* size of buffer to store password in */
+{
+  ssize_t nread;
+  bool disabled;
+  int fd = open("/dev/tty", O_RDONLY);
+  if(-1 == fd)
+    fd = STDIN_FILENO; /* use stdin if the tty couldn't be used */
+
+  disabled = ttyecho(FALSE, fd); /* disable terminal echo */
+
+  fputs(prompt, stderr);
+  nread = read(fd, password, buflen);
+  if(nread > 0)
+    password[--nread] = '\0'; /* zero terminate where enter is stored */
+  else
+    password[0] = '\0'; /* got nothing */
+
+  if(disabled) {
+    /* if echo actually was disabled, add a newline */
+    fputs("\n", stderr);
+    (void)ttyecho(TRUE, fd); /* enable echo */
+  }
+
+  if(STDIN_FILENO != fd)
+    close(fd);
+
+  return password; /* return pointer to buffer */
+}
+
+#endif /* DONE */
+#endif /* HAVE_GETPASS_R */
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_getpass.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_getpass.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_getpass.h	(revision 331)
@@ -0,0 +1,36 @@
+#ifndef HEADER_CURL_TOOL_GETPASS_H
+#define HEADER_CURL_TOOL_GETPASS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#ifndef HAVE_GETPASS_R
+/* If there's a system-provided function named like this, we trust it is
+   also found in one of the standard headers. */
+
+/*
+ * Returning NULL will abort the continued operation!
+ */
+char *getpass_r(const char *prompt, char *buffer, size_t buflen);
+#endif
+
+#endif /* HEADER_CURL_TOOL_GETPASS_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_help.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_help.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_help.c	(revision 331)
@@ -0,0 +1,577 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#include "tool_panykey.h"
+#include "tool_help.h"
+#include "tool_libinfo.h"
+#include "tool_version.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+#ifdef MSDOS
+#  define USE_WATT32
+#endif
+
+/*
+ * The help output is generated with the following command
+ ---------------------------------------------------------
+
+  cd $srcroot/docs/cmdline-opts
+  ./gen.pl listhelp
+ */
+
+struct helptxt {
+  const char *opt;
+  const char *desc;
+};
+
+static const struct helptxt helptext[] = {
+  {"    --abstract-unix-socket <path>",
+   "Connect via abstract Unix domain socket"},
+  {"    --anyauth",
+   "Pick any authentication method"},
+  {"-a, --append",
+   "Append to target file when uploading"},
+  {"    --basic",
+   "Use HTTP Basic Authentication"},
+  {"    --cacert <file>",
+   "CA certificate to verify peer against"},
+  {"    --capath <dir>",
+   "CA directory to verify peer against"},
+  {"-E, --cert <certificate[:password]>",
+   "Client certificate file and password"},
+  {"    --cert-status",
+   "Verify the status of the server certificate"},
+  {"    --cert-type <type>",
+   "Certificate file type (DER/PEM/ENG)"},
+  {"    --ciphers <list of ciphers>",
+   "SSL ciphers to use"},
+  {"    --compressed",
+   "Request compressed response"},
+  {"    --compressed-ssh",
+   "Enable SSH compression"},
+  {"-K, --config <file>",
+   "Read config from a file"},
+  {"    --connect-timeout <seconds>",
+   "Maximum time allowed for connection"},
+  {"    --connect-to <HOST1:PORT1:HOST2:PORT2>",
+   "Connect to host"},
+  {"-C, --continue-at <offset>",
+   "Resumed transfer offset"},
+  {"-b, --cookie <data>",
+   "Send cookies from string/file"},
+  {"-c, --cookie-jar <filename>",
+   "Write cookies to <filename> after operation"},
+  {"    --create-dirs",
+   "Create necessary local directory hierarchy"},
+  {"    --crlf",
+   "Convert LF to CRLF in upload"},
+  {"    --crlfile <file>",
+   "Get a CRL list in PEM format from the given file"},
+  {"-d, --data <data>",
+   "HTTP POST data"},
+  {"    --data-ascii <data>",
+   "HTTP POST ASCII data"},
+  {"    --data-binary <data>",
+   "HTTP POST binary data"},
+  {"    --data-raw <data>",
+   "HTTP POST data, '@' allowed"},
+  {"    --data-urlencode <data>",
+   "HTTP POST data url encoded"},
+  {"    --delegation <LEVEL>",
+   "GSS-API delegation permission"},
+  {"    --digest",
+   "Use HTTP Digest Authentication"},
+  {"-q, --disable",
+   "Disable .curlrc"},
+  {"    --disable-eprt",
+   "Inhibit using EPRT or LPRT"},
+  {"    --disable-epsv",
+   "Inhibit using EPSV"},
+  {"    --dns-interface <interface>",
+   "Interface to use for DNS requests"},
+  {"    --dns-ipv4-addr <address>",
+   "IPv4 address to use for DNS requests"},
+  {"    --dns-ipv6-addr <address>",
+   "IPv6 address to use for DNS requests"},
+  {"    --dns-servers <addresses>",
+   "DNS server addrs to use"},
+  {"-D, --dump-header <filename>",
+   "Write the received headers to <filename>"},
+  {"    --egd-file <file>",
+   "EGD socket path for random data"},
+  {"    --engine <name>",
+   "Crypto engine to use"},
+  {"    --expect100-timeout <seconds>",
+   "How long to wait for 100-continue"},
+  {"-f, --fail",
+   "Fail silently (no output at all) on HTTP errors"},
+  {"    --fail-early",
+   "Fail on first transfer error, do not continue"},
+  {"    --false-start",
+   "Enable TLS False Start"},
+  {"-F, --form <name=content>",
+   "Specify multipart MIME data"},
+  {"    --form-string <name=string>",
+   "Specify multipart MIME data"},
+  {"    --ftp-account <data>",
+   "Account data string"},
+  {"    --ftp-alternative-to-user <command>",
+   "String to replace USER [name]"},
+  {"    --ftp-create-dirs",
+   "Create the remote dirs if not present"},
+  {"    --ftp-method <method>",
+   "Control CWD usage"},
+  {"    --ftp-pasv",
+   "Use PASV/EPSV instead of PORT"},
+  {"-P, --ftp-port <address>",
+   "Use PORT instead of PASV"},
+  {"    --ftp-pret",
+   "Send PRET before PASV"},
+  {"    --ftp-skip-pasv-ip",
+   "Skip the IP address for PASV"},
+  {"    --ftp-ssl-ccc",
+   "Send CCC after authenticating"},
+  {"    --ftp-ssl-ccc-mode <active/passive>",
+   "Set CCC mode"},
+  {"    --ftp-ssl-control",
+   "Require SSL/TLS for FTP login, clear for transfer"},
+  {"-G, --get",
+   "Put the post data in the URL and use GET"},
+  {"-g, --globoff",
+   "Disable URL sequences and ranges using {} and []"},
+  {"-I, --head",
+   "Show document info only"},
+  {"-H, --header <header/@file>",
+   "Pass custom header(s) to server"},
+  {"-h, --help",
+   "This help text"},
+  {"    --hostpubmd5 <md5>",
+   "Acceptable MD5 hash of the host public key"},
+  {"-0, --http1.0",
+   "Use HTTP 1.0"},
+  {"    --http1.1",
+   "Use HTTP 1.1"},
+  {"    --http2",
+   "Use HTTP 2"},
+  {"    --http2-prior-knowledge",
+   "Use HTTP 2 without HTTP/1.1 Upgrade"},
+  {"    --ignore-content-length",
+   "Ignore the size of the remote resource"},
+  {"-i, --include",
+   "Include protocol response headers in the output"},
+  {"-k, --insecure",
+   "Allow insecure server connections when using SSL"},
+  {"    --interface <name>",
+   "Use network INTERFACE (or address)"},
+  {"-4, --ipv4",
+   "Resolve names to IPv4 addresses"},
+  {"-6, --ipv6",
+   "Resolve names to IPv6 addresses"},
+  {"-j, --junk-session-cookies",
+   "Ignore session cookies read from file"},
+  {"    --keepalive-time <seconds>",
+   "Interval time for keepalive probes"},
+  {"    --key <key>",
+   "Private key file name"},
+  {"    --key-type <type>",
+   "Private key file type (DER/PEM/ENG)"},
+  {"    --krb <level>",
+   "Enable Kerberos with security <level>"},
+  {"    --libcurl <file>",
+   "Dump libcurl equivalent code of this command line"},
+  {"    --limit-rate <speed>",
+   "Limit transfer speed to RATE"},
+  {"-l, --list-only",
+   "List only mode"},
+  {"    --local-port <num/range>",
+   "Force use of RANGE for local port numbers"},
+  {"-L, --location",
+   "Follow redirects"},
+  {"    --location-trusted",
+   "Like --location, and send auth to other hosts"},
+  {"    --login-options <options>",
+   "Server login options"},
+  {"    --mail-auth <address>",
+   "Originator address of the original email"},
+  {"    --mail-from <address>",
+   "Mail from this address"},
+  {"    --mail-rcpt <address>",
+   "Mail from this address"},
+  {"-M, --manual",
+   "Display the full manual"},
+  {"    --max-filesize <bytes>",
+   "Maximum file size to download"},
+  {"    --max-redirs <num>",
+   "Maximum number of redirects allowed"},
+  {"-m, --max-time <time>",
+   "Maximum time allowed for the transfer"},
+  {"    --metalink",
+   "Process given URLs as metalink XML file"},
+  {"    --negotiate",
+   "Use HTTP Negotiate (SPNEGO) authentication"},
+  {"-n, --netrc",
+   "Must read .netrc for user name and password"},
+  {"    --netrc-file <filename>",
+   "Specify FILE for netrc"},
+  {"    --netrc-optional",
+   "Use either .netrc or URL"},
+  {"-:, --next",
+   "Make next URL use its separate set of options"},
+  {"    --no-alpn",
+   "Disable the ALPN TLS extension"},
+  {"-N, --no-buffer",
+   "Disable buffering of the output stream"},
+  {"    --no-keepalive",
+   "Disable TCP keepalive on the connection"},
+  {"    --no-npn",
+   "Disable the NPN TLS extension"},
+  {"    --no-sessionid",
+   "Disable SSL session-ID reusing"},
+  {"    --noproxy <no-proxy-list>",
+   "List of hosts which do not use proxy"},
+  {"    --ntlm",
+   "Use HTTP NTLM authentication"},
+  {"    --ntlm-wb",
+   "Use HTTP NTLM authentication with winbind"},
+  {"    --oauth2-bearer <token>",
+   "OAuth 2 Bearer Token"},
+  {"-o, --output <file>",
+   "Write to file instead of stdout"},
+  {"    --pass <phrase>",
+   "Pass phrase for the private key"},
+  {"    --path-as-is",
+   "Do not squash .. sequences in URL path"},
+  {"    --pinnedpubkey <hashes>",
+   "FILE/HASHES Public key to verify peer against"},
+  {"    --post301",
+   "Do not switch to GET after following a 301"},
+  {"    --post302",
+   "Do not switch to GET after following a 302"},
+  {"    --post303",
+   "Do not switch to GET after following a 303"},
+  {"    --preproxy [protocol://]host[:port]",
+   "Use this proxy first"},
+  {"-#, --progress-bar",
+   "Display transfer progress as a bar"},
+  {"    --proto <protocols>",
+   "Enable/disable PROTOCOLS"},
+  {"    --proto-default <protocol>",
+   "Use PROTOCOL for any URL missing a scheme"},
+  {"    --proto-redir <protocols>",
+   "Enable/disable PROTOCOLS on redirect"},
+  {"-x, --proxy [protocol://]host[:port]",
+   "Use this proxy"},
+  {"    --proxy-anyauth",
+   "Pick any proxy authentication method"},
+  {"    --proxy-basic",
+   "Use Basic authentication on the proxy"},
+  {"    --proxy-cacert <file>",
+   "CA certificate to verify peer against for proxy"},
+  {"    --proxy-capath <dir>",
+   "CA directory to verify peer against for proxy"},
+  {"    --proxy-cert <cert[:passwd]>",
+   "Set client certificate for proxy"},
+  {"    --proxy-cert-type <type>",
+   "Client certificate type for HTTS proxy"},
+  {"    --proxy-ciphers <list>",
+   "SSL ciphers to use for proxy"},
+  {"    --proxy-crlfile <file>",
+   "Set a CRL list for proxy"},
+  {"    --proxy-digest",
+   "Use Digest authentication on the proxy"},
+  {"    --proxy-header <header/@file>",
+   "Pass custom header(s) to proxy"},
+  {"    --proxy-insecure",
+   "Do HTTPS proxy connections without verifying the proxy"},
+  {"    --proxy-key <key>",
+   "Private key for HTTPS proxy"},
+  {"    --proxy-key-type <type>",
+   "Private key file type for proxy"},
+  {"    --proxy-negotiate",
+   "Use HTTP Negotiate (SPNEGO) authentication on the proxy"},
+  {"    --proxy-ntlm",
+   "Use NTLM authentication on the proxy"},
+  {"    --proxy-pass <phrase>",
+   "Pass phrase for the private key for HTTPS proxy"},
+  {"    --proxy-service-name <name>",
+   "SPNEGO proxy service name"},
+  {"    --proxy-ssl-allow-beast",
+   "Allow security flaw for interop for HTTPS proxy"},
+  {"    --proxy-tlsauthtype <type>",
+   "TLS authentication type for HTTPS proxy"},
+  {"    --proxy-tlspassword <string>",
+   "TLS password for HTTPS proxy"},
+  {"    --proxy-tlsuser <name>",
+   "TLS username for HTTPS proxy"},
+  {"    --proxy-tlsv1",
+   "Use TLSv1 for HTTPS proxy"},
+  {"-U, --proxy-user <user:password>",
+   "Proxy user and password"},
+  {"    --proxy1.0 <host[:port]>",
+   "Use HTTP/1.0 proxy on given port"},
+  {"-p, --proxytunnel",
+   "Operate through a HTTP proxy tunnel (using CONNECT)"},
+  {"    --pubkey <key>",
+   "SSH Public key file name"},
+  {"-Q, --quote",
+   "Send command(s) to server before transfer"},
+  {"    --random-file <file>",
+   "File for reading random data from"},
+  {"-r, --range <range>",
+   "Retrieve only the bytes within RANGE"},
+  {"    --raw",
+   "Do HTTP \"raw\"; no transfer decoding"},
+  {"-e, --referer <URL>",
+   "Referrer URL"},
+  {"-J, --remote-header-name",
+   "Use the header-provided filename"},
+  {"-O, --remote-name",
+   "Write output to a file named as the remote file"},
+  {"    --remote-name-all",
+   "Use the remote file name for all URLs"},
+  {"-R, --remote-time",
+   "Set the remote file's time on the local output"},
+  {"-X, --request <command>",
+   "Specify request command to use"},
+  {"    --request-target",
+   "Specify the target for this request"},
+  {"    --resolve <host:port:address>",
+   "Resolve the host+port to this address"},
+  {"    --retry <num>",
+   "Retry request if transient problems occur"},
+  {"    --retry-connrefused",
+   "Retry on connection refused (use with --retry)"},
+  {"    --retry-delay <seconds>",
+   "Wait time between retries"},
+  {"    --retry-max-time <seconds>",
+   "Retry only within this period"},
+  {"    --sasl-ir",
+   "Enable initial response in SASL authentication"},
+  {"    --service-name <name>",
+   "SPNEGO service name"},
+  {"-S, --show-error",
+   "Show error even when -s is used"},
+  {"-s, --silent",
+   "Silent mode"},
+  {"    --socks4 <host[:port]>",
+   "SOCKS4 proxy on given host + port"},
+  {"    --socks4a <host[:port]>",
+   "SOCKS4a proxy on given host + port"},
+  {"    --socks5 <host[:port]>",
+   "SOCKS5 proxy on given host + port"},
+  {"    --socks5-basic",
+   "Enable username/password auth for SOCKS5 proxies"},
+  {"    --socks5-gssapi",
+   "Enable GSS-API auth for SOCKS5 proxies"},
+  {"    --socks5-gssapi-nec",
+   "Compatibility with NEC SOCKS5 server"},
+  {"    --socks5-gssapi-service <name>",
+   "SOCKS5 proxy service name for GSS-API"},
+  {"    --socks5-hostname <host[:port]>",
+   "SOCKS5 proxy, pass host name to proxy"},
+  {"-Y, --speed-limit <speed>",
+   "Stop transfers slower than this"},
+  {"-y, --speed-time <seconds>",
+   "Trigger 'speed-limit' abort after this time"},
+  {"    --ssl",
+   "Try SSL/TLS"},
+  {"    --ssl-allow-beast",
+   "Allow security flaw to improve interop"},
+  {"    --ssl-no-revoke",
+   "Disable cert revocation checks (WinSSL)"},
+  {"    --ssl-reqd",
+   "Require SSL/TLS"},
+  {"-2, --sslv2",
+   "Use SSLv2"},
+  {"-3, --sslv3",
+   "Use SSLv3"},
+  {"    --stderr",
+   "Where to redirect stderr"},
+  {"    --suppress-connect-headers",
+   "Suppress proxy CONNECT response headers"},
+  {"    --tcp-fastopen",
+   "Use TCP Fast Open"},
+  {"    --tcp-nodelay",
+   "Use the TCP_NODELAY option"},
+  {"-t, --telnet-option <opt=val>",
+   "Set telnet option"},
+  {"    --tftp-blksize <value>",
+   "Set TFTP BLKSIZE option"},
+  {"    --tftp-no-options",
+   "Do not send any TFTP options"},
+  {"-z, --time-cond <time>",
+   "Transfer based on a time condition"},
+  {"    --tls-max <VERSION>",
+   "Use TLSv1.0 or greater"},
+  {"    --tlsauthtype <type>",
+   "TLS authentication type"},
+  {"    --tlspassword",
+   "TLS password"},
+  {"    --tlsuser <name>",
+   "TLS user name"},
+  {"-1, --tlsv1",
+   "Use TLSv1.0 or greater"},
+  {"    --tlsv1.0",
+   "Use TLSv1.0"},
+  {"    --tlsv1.1",
+   "Use TLSv1.1"},
+  {"    --tlsv1.2",
+   "Use TLSv1.2"},
+  {"    --tlsv1.3",
+   "Use TLSv1.3"},
+  {"    --tr-encoding",
+   "Request compressed transfer encoding"},
+  {"    --trace <file>",
+   "Write a debug trace to FILE"},
+  {"    --trace-ascii <file>",
+   "Like --trace, but without hex output"},
+  {"    --trace-time",
+   "Add time stamps to trace/verbose output"},
+  {"    --unix-socket <path>",
+   "Connect through this Unix domain socket"},
+  {"-T, --upload-file <file>",
+   "Transfer local FILE to destination"},
+  {"    --url <url>",
+   "URL to work with"},
+  {"-B, --use-ascii",
+   "Use ASCII/text transfer"},
+  {"-u, --user <user:password>",
+   "Server user and password"},
+  {"-A, --user-agent <name>",
+   "Send User-Agent <name> to server"},
+  {"-v, --verbose",
+   "Make the operation more talkative"},
+  {"-V, --version",
+   "Show version number and quit"},
+  {"-w, --write-out <format>",
+   "Use output FORMAT after completion"},
+  {"    --xattr",
+   "Store metadata in extended file attributes"},
+  { NULL, NULL }
+};
+
+#ifdef NETWARE
+#  define PRINT_LINES_PAUSE 23
+#endif
+
+#ifdef __SYMBIAN32__
+#  define PRINT_LINES_PAUSE 16
+#endif
+
+struct feat {
+  const char *name;
+  int bitmask;
+};
+
+static const struct feat feats[] = {
+  {"AsynchDNS",      CURL_VERSION_ASYNCHDNS},
+  {"Debug",          CURL_VERSION_DEBUG},
+  {"TrackMemory",    CURL_VERSION_CURLDEBUG},
+  {"IDN",            CURL_VERSION_IDN},
+  {"IPv6",           CURL_VERSION_IPV6},
+  {"Largefile",      CURL_VERSION_LARGEFILE},
+  {"SSPI",           CURL_VERSION_SSPI},
+  {"GSS-API",        CURL_VERSION_GSSAPI},
+  {"Kerberos",       CURL_VERSION_KERBEROS5},
+  {"SPNEGO",         CURL_VERSION_SPNEGO},
+  {"NTLM",           CURL_VERSION_NTLM},
+  {"NTLM_WB",        CURL_VERSION_NTLM_WB},
+  {"SSL",            CURL_VERSION_SSL},
+  {"libz",           CURL_VERSION_LIBZ},
+  {"brotli",         CURL_VERSION_BROTLI},
+  {"CharConv",       CURL_VERSION_CONV},
+  {"TLS-SRP",        CURL_VERSION_TLSAUTH_SRP},
+  {"HTTP2",          CURL_VERSION_HTTP2},
+  {"UnixSockets",    CURL_VERSION_UNIX_SOCKETS},
+  {"HTTPS-proxy",    CURL_VERSION_HTTPS_PROXY},
+  {"MultiSSL",       CURL_VERSION_MULTI_SSL}
+};
+
+void tool_help(void)
+{
+  int i;
+  puts("Usage: curl [options...] <url>");
+  for(i = 0; helptext[i].opt; i++) {
+    printf(" %-19s %s\n", helptext[i].opt, helptext[i].desc);
+#ifdef PRINT_LINES_PAUSE
+    if(i && ((i % PRINT_LINES_PAUSE) == 0))
+      tool_pressanykey();
+#endif
+  }
+}
+
+void tool_version_info(void)
+{
+  const char *const *proto;
+
+  printf(CURL_ID "%s\n", curl_version());
+#ifdef CURL_PATCHSTAMP
+  printf("Release-Date: %s, security patched: %s\n",
+         LIBCURL_TIMESTAMP, CURL_PATCHSTAMP);
+#else
+  printf("Release-Date: %s\n", LIBCURL_TIMESTAMP);
+#endif
+  if(curlinfo->protocols) {
+    printf("Protocols: ");
+    for(proto = curlinfo->protocols; *proto; ++proto) {
+      printf("%s ", *proto);
+    }
+    puts(""); /* newline */
+  }
+  if(curlinfo->features) {
+    unsigned int i;
+    printf("Features: ");
+    for(i = 0; i < sizeof(feats)/sizeof(feats[0]); i++) {
+      if(curlinfo->features & feats[i].bitmask)
+        printf("%s ", feats[i].name);
+    }
+#ifdef USE_METALINK
+    printf("Metalink ");
+#endif
+#ifdef USE_LIBPSL
+    printf("PSL ");
+#endif
+    puts(""); /* newline */
+  }
+}
+
+void tool_list_engines(CURL *curl)
+{
+  struct curl_slist *engines = NULL;
+
+  /* Get the list of engines */
+  curl_easy_getinfo(curl, CURLINFO_SSL_ENGINES, &engines);
+
+  puts("Build-time engines:");
+  if(engines) {
+    for(; engines; engines = engines->next)
+      printf("  %s\n", engines->data);
+  }
+  else {
+    puts("  <none>");
+  }
+
+  /* Cleanup the list of engines */
+  curl_slist_free_all(engines);
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_help.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_help.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_help.h	(revision 331)
@@ -0,0 +1,31 @@
+#ifndef HEADER_CURL_TOOL_HELP_H
+#define HEADER_CURL_TOOL_HELP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+void tool_help(void);
+void tool_list_engines(CURL *curl);
+void tool_version_info(void);
+
+#endif /* HEADER_CURL_TOOL_HELP_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_helpers.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_helpers.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_helpers.c	(revision 331)
@@ -0,0 +1,120 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#include "strcase.h"
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_cfgable.h"
+#include "tool_msgs.h"
+#include "tool_getparam.h"
+#include "tool_helpers.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+/*
+** Helper functions that are used from more than one source file.
+*/
+
+const char *param2text(int res)
+{
+  ParameterError error = (ParameterError)res;
+  switch(error) {
+  case PARAM_GOT_EXTRA_PARAMETER:
+    return "had unsupported trailing garbage";
+  case PARAM_OPTION_UNKNOWN:
+    return "is unknown";
+  case PARAM_OPTION_AMBIGUOUS:
+    return "is ambiguous";
+  case PARAM_REQUIRES_PARAMETER:
+    return "requires parameter";
+  case PARAM_BAD_USE:
+    return "is badly used here";
+  case PARAM_BAD_NUMERIC:
+    return "expected a proper numerical parameter";
+  case PARAM_NEGATIVE_NUMERIC:
+    return "expected a positive numerical parameter";
+  case PARAM_LIBCURL_DOESNT_SUPPORT:
+    return "the installed libcurl version doesn't support this";
+  case PARAM_LIBCURL_UNSUPPORTED_PROTOCOL:
+    return "a specified protocol is unsupported by libcurl";
+  case PARAM_NO_MEM:
+    return "out of memory";
+  case PARAM_NO_PREFIX:
+    return "the given option can't be reversed with a --no- prefix";
+  case PARAM_NUMBER_TOO_LARGE:
+    return "too large number";
+  default:
+    return "unknown error";
+  }
+}
+
+int SetHTTPrequest(struct OperationConfig *config, HttpReq req, HttpReq *store)
+{
+  /* this mirrors the HttpReq enum in tool_sdecls.h */
+  const char *reqname[]= {
+    "", /* unspec */
+    "GET (-G, --get)",
+    "HEAD (-I, --head)",
+    "multipart formpost (-F, --form)",
+    "POST (-d, --data)"
+  };
+
+  if((*store == HTTPREQ_UNSPEC) ||
+     (*store == req)) {
+    *store = req;
+    return 0;
+  }
+  warnf(config->global, "You can only select one HTTP request method! "
+        "You asked for both %s and %s.\n",
+        reqname[req], reqname[*store]);
+
+  return 1;
+}
+
+void customrequest_helper(struct OperationConfig *config, HttpReq req,
+                          char *method)
+{
+  /* this mirrors the HttpReq enum in tool_sdecls.h */
+  const char *dflt[]= {
+    "GET",
+    "GET",
+    "HEAD",
+    "POST",
+    "POST"
+  };
+
+  if(!method)
+    ;
+  else if(curl_strequal(method, dflt[req])) {
+    notef(config->global, "Unnecessary use of -X or --request, %s is already "
+          "inferred.\n", dflt[req]);
+  }
+  else if(curl_strequal(method, "head")) {
+    warnf(config->global,
+          "Setting custom HTTP method to HEAD with -X/--request may not work "
+          "the way you want. Consider using -I/--head instead.\n");
+  }
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_helpers.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_helpers.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_helpers.h	(revision 331)
@@ -0,0 +1,35 @@
+#ifndef HEADER_CURL_TOOL_HELPERS_H
+#define HEADER_CURL_TOOL_HELPERS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+const char *param2text(int res);
+
+int SetHTTPrequest(struct OperationConfig *config, HttpReq req,
+                   HttpReq *store);
+
+void customrequest_helper(struct OperationConfig *config, HttpReq req,
+                          char *method);
+
+#endif /* HEADER_CURL_TOOL_HELPERS_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_homedir.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_homedir.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_homedir.c	(revision 331)
@@ -0,0 +1,95 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#ifdef HAVE_PWD_H
+#  include <pwd.h>
+#endif
+
+#include "tool_homedir.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+static char *GetEnv(const char *variable, char do_expand)
+{
+  char *env = NULL;
+#ifdef WIN32
+  char  buf1[1024], buf2[1024];
+  DWORD rc;
+
+  /* Don't use getenv(); it doesn't find variable added after program was
+   * started. Don't accept truncated results (i.e. rc >= sizeof(buf1)).  */
+
+  rc = GetEnvironmentVariableA(variable, buf1, sizeof(buf1));
+  if(rc > 0 && rc < sizeof(buf1)) {
+    env = buf1;
+    variable = buf1;
+  }
+  if(do_expand && strchr(variable, '%')) {
+    /* buf2 == variable if not expanded */
+    rc = ExpandEnvironmentStringsA(variable, buf2, sizeof(buf2));
+    if(rc > 0 && rc < sizeof(buf2) &&
+       !strchr(buf2, '%'))    /* no vars still unexpanded */
+      env = buf2;
+  }
+#else
+  (void)do_expand;
+  /* no length control */
+  env = getenv(variable);
+#endif
+  return (env && env[0]) ? strdup(env) : NULL;
+}
+
+/* return the home directory of the current user as an allocated string */
+char *homedir(void)
+{
+  char *home;
+
+  home = GetEnv("CURL_HOME", FALSE);
+  if(home)
+    return home;
+
+  home = GetEnv("HOME", FALSE);
+  if(home)
+    return home;
+
+#if defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
+ {
+   struct passwd *pw = getpwuid(geteuid());
+
+   if(pw) {
+     home = pw->pw_dir;
+     if(home && home[0])
+       home = strdup(home);
+     else
+       home = NULL;
+   }
+ }
+#endif /* PWD-stuff */
+#ifdef WIN32
+  home = GetEnv("APPDATA", TRUE);
+  if(!home)
+    home = GetEnv("%USERPROFILE%\\Application Data", TRUE); /* Normally only
+                                                               on Win-2K/XP */
+#endif /* WIN32 */
+  return home;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_homedir.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_homedir.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_homedir.h	(revision 331)
@@ -0,0 +1,28 @@
+#ifndef HEADER_CURL_TOOL_HOMEDIR_H
+#define HEADER_CURL_TOOL_HOMEDIR_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+char *homedir(void);
+
+#endif /* HEADER_CURL_TOOL_HOMEDIR_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_hugehelp.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_hugehelp.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_hugehelp.c	(revision 331)
@@ -0,0 +1,10098 @@
+#include "tool_setup.h"
+#ifndef HAVE_LIBZ
+/*
+ * NEVER EVER edit this manually, fix the mkhelp.pl script instead!
+ */
+#ifdef USE_MANUAL
+#include "tool_hugehelp.h"
+void hugehelp(void)
+{
+   fputs(
+"                                  _   _ ____  _\n"
+"  Project                     ___| | | |  _ \\| |\n"
+"                             / __| | | | |_) | |\n"
+"                            | (__| |_| |  _ <| |___\n"
+"                             \\___|\\___/|_| \\_\\_____|\n"
+"\n"
+"NAME\n"
+"       curl - transfer a URL\n"
+"\n"
+"SYNOPSIS\n"
+"       curl [options] [URL...]\n"
+"\n"
+"DESCRIPTION\n"
+"       curl  is  a tool to transfer data from or to a server, using one of the\n"
+"       supported protocols (DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS,  IMAP,\n"
+, stdout);
+ fputs(
+"       IMAPS,  LDAP,  LDAPS,  POP3,  POP3S,  RTMP, RTSP, SCP, SFTP, SMB, SMBS,\n"
+"       SMTP, SMTPS, TELNET and TFTP). The command is designed to work  without\n"
+"       user interaction.\n"
+"\n"
+"       curl offers a busload of useful tricks like proxy support, user authen-\n"
+"       tication, FTP upload, HTTP post, SSL connections, cookies, file  trans-\n"
+"       fer  resume,  Metalink,  and more. As you will see below, the number of\n"
+"       features will make your head spin!\n"
+"\n"
+, stdout);
+ fputs(
+"       curl is powered by  libcurl  for  all  transfer-related  features.  See\n"
+"       libcurl(3) for details.\n"
+"\n"
+"URL\n"
+"       The  URL  syntax is protocol-dependent. You'll find a detailed descrip-\n"
+"       tion in RFC 3986.\n"
+"\n"
+"       You can specify multiple URLs or parts of URLs  by  writing  part  sets\n"
+"       within braces as in:\n"
+"\n"
+"         http://site.{one,two,three}.com\n"
+"\n"
+"       or you can get sequences of alphanumeric series by using [] as in:\n"
+"\n"
+"         ftp://ftp.example.com/file[1-100].txt\n"
+"\n"
+, stdout);
+ fputs(
+"         ftp://ftp.example.com/file[001-100].txt    (with leading zeros)\n"
+"\n"
+"         ftp://ftp.example.com/file[a-z].txt\n"
+"\n"
+"       Nested  sequences  are not supported, but you can use several ones next\n"
+"       to each other:\n"
+"\n"
+"         http://example.com/archive[1996-1999]/vol[1-4]/part{a,b,c}.html\n"
+"\n"
+"       You can specify any amount of URLs on the command line.  They  will  be\n"
+"       fetched in a sequential manner in the specified order.\n"
+"\n"
+, stdout);
+ fputs(
+"       You  can  specify a step counter for the ranges to get every Nth number\n"
+"       or letter:\n"
+"\n"
+"         http://example.com/file[1-100:10].txt\n"
+"\n"
+"         http://example.com/file[a-z:2].txt\n"
+"\n"
+"       When using [] or {} sequences when invoked from a command line  prompt,\n"
+"       you probably have to put the full URL within double quotes to avoid the\n"
+"       shell from interfering with it. This also  goes  for  other  characters\n"
+"       treated special, like for example '&', '?' and '*'.\n"
+"\n"
+, stdout);
+ fputs(
+"       Provide  the IPv6 zone index in the URL with an escaped percentage sign\n"
+"       and the interface name. Like in\n"
+"\n"
+"         http://[fe80::3%25eth0]/\n"
+"\n"
+"       If you specify URL without protocol:// prefix,  curl  will  attempt  to\n"
+"       guess  what  protocol  you might want. It will then default to HTTP but\n"
+"       try other protocols based on often-used host name prefixes.  For  exam-\n"
+"       ple,  for  host names starting with \"ftp.\" curl will assume you want to\n"
+"       speak FTP.\n"
+"\n"
+, stdout);
+ fputs(
+"       curl will do its best to use what you pass to it as a URL.  It  is  not\n"
+"       trying  to  validate it as a syntactically correct URL by any means but\n"
+"       is instead very liberal with what it accepts.\n"
+"\n"
+"       curl will attempt to re-use connections for multiple file transfers, so\n"
+"       that  getting many files from the same server will not do multiple con-\n"
+"       nects / handshakes. This improves speed. Of course this is only done on\n"
+, stdout);
+ fputs(
+"       files  specified  on  a  single command line and cannot be used between\n"
+"       separate curl invokes.\n"
+"\n"
+"PROGRESS METER\n"
+"       curl normally displays a progress meter during  operations,  indicating\n"
+"       the  amount  of  transferred  data,  transfer speeds and estimated time\n"
+"       left, etc. The progress meter displays number of bytes and  the  speeds\n"
+"       are  in  bytes per second. The suffixes (k, M, G, T, P) are 1024 based.\n"
+"       For example 1k is 1024 bytes. 1M is 1048576 bytes.\n"
+"\n"
+, stdout);
+ fputs(
+"       curl displays this data to the terminal by default, so  if  you  invoke\n"
+"       curl  to do an operation and it is about to write data to the terminal,\n"
+"       it disables the progress meter as otherwise it would mess up the output\n"
+"       mixing progress meter and response data.\n"
+"\n"
+"       If you want a progress meter for HTTP POST or PUT requests, you need to\n"
+"       redirect the response output to a file, using shell redirect  (>),  -o,\n"
+"       --output or similar.\n"
+"\n"
+, stdout);
+ fputs(
+"       It  is not the same case for FTP upload as that operation does not spit\n"
+"       out any response data to the terminal.\n"
+"\n"
+"       If you prefer a progress  \"bar\"  instead  of  the  regular  meter,  -#,\n"
+"       --progress-bar  is your friend. You can also disable the progress meter\n"
+"       completely with the -s, --silent option.\n"
+"\n"
+"OPTIONS\n"
+"       Options start with one or two dashes. Many of the  options  require  an\n"
+"       additional value next to them.\n"
+"\n"
+, stdout);
+ fputs(
+"       The  short  \"single-dash\"  form  of the options, -d for example, may be\n"
+"       used with or without a space between it and its value, although a space\n"
+"       is a recommended separator. The long \"double-dash\" form, -d, --data for\n"
+"       example, requires a space between it and its value.\n"
+"\n"
+"       Short version options that don't need any additional values can be used\n"
+"       immediately  next  to  each other, like for example you can specify all\n"
+, stdout);
+ fputs(
+"       the options -O, -L and -v at once as -OLv.\n"
+"\n"
+"       In general, all boolean options are enabled with --option and yet again\n"
+"       disabled  with --no-option. That is, you use the exact same option name\n"
+"       but prefix it with \"no-\". However, in this list we mostly only list and\n"
+"       show  the --option version of them. (This concept with --no options was\n"
+"       added in  7.19.0.  Previously  most  options  were  toggled  on/off  on\n"
+"       repeated use of the same command line option.)\n"
+, stdout);
+ fputs(
+"\n"
+"       --abstract-unix-socket <path>\n"
+"              (HTTP)  Connect  through an abstract Unix domain socket, instead\n"
+"              of using the network.   Note:  netstat  shows  the  path  of  an\n"
+"              abstract  socket  prefixed with '@', however the <path> argument\n"
+"              should not have this leading character.\n"
+"\n"
+"              Added in 7.53.0.\n"
+"\n"
+"       --anyauth\n"
+"              (HTTP) Tells curl to figure out authentication method by itself,\n"
+, stdout);
+ fputs(
+"              and  use  the most secure one the remote site claims to support.\n"
+"              This is done by first doing a request and checking the response-\n"
+"              headers,  thus  possibly  inducing  an extra network round-trip.\n"
+"              This is  used  instead  of  setting  a  specific  authentication\n"
+"              method,  which  you  can  do with --basic, --digest, --ntlm, and\n"
+"              --negotiate.\n"
+"\n"
+, stdout);
+ fputs(
+"              Using --anyauth is not recommended if you do uploads from stdin,\n"
+"              since  it  may require data to be sent twice and then the client\n"
+"              must be able to rewind. If the need should arise when  uploading\n"
+"              from stdin, the upload operation will fail.\n"
+"\n"
+"              Used together with -u, --user.\n"
+"\n"
+"              See also --proxy-anyauth and --basic and --digest.\n"
+"\n"
+"       -a, --append\n"
+, stdout);
+ fputs(
+"              (FTP SFTP) When used in an upload, this makes curl append to the\n"
+"              target file instead  of  overwriting  it.  If  the  remote  file\n"
+"              doesn't  exist,  it  will  be  created.   Note that this flag is\n"
+"              ignored by some SFTP servers (including OpenSSH).\n"
+"\n"
+"       --basic\n"
+"              (HTTP) Tells curl to use  HTTP  Basic  authentication  with  the\n"
+"              remote  host.  This  is  the  default and this option is usually\n"
+, stdout);
+ fputs(
+"              pointless, unless you use it to override a previously set option\n"
+"              that  sets  a  different  authentication method (such as --ntlm,\n"
+"              --digest, or --negotiate).\n"
+"\n"
+"              Used together with -u, --user.\n"
+"\n"
+"              See also --proxy-basic.\n"
+"\n"
+"       --cacert <file>\n"
+"              (TLS) Tells curl to use the specified certificate file to verify\n"
+"              the  peer.  The  file  may contain multiple CA certificates. The\n"
+, stdout);
+ fputs(
+"              certificate(s) must be in PEM format. Normally curl is built  to\n"
+"              use a default file for this, so this option is typically used to\n"
+"              alter that default file.\n"
+"\n"
+"              curl recognizes the environment variable named  'CURL_CA_BUNDLE'\n"
+"              if  it  is  set,  and uses the given path as a path to a CA cert\n"
+"              bundle. This option overrides that variable.\n"
+"\n"
+"              The windows version of curl will automatically  look  for  a  CA\n"
+, stdout);
+ fputs(
+"              certs file named 'curl-ca-bundle.crt', either in the same direc-\n"
+"              tory as curl.exe, or in the Current Working Directory, or in any\n"
+"              folder along your PATH.\n"
+"\n"
+"              If  curl  is  built  against  the  NSS  SSL library, the NSS PEM\n"
+"              PKCS#11 module (libnsspem.so) needs to  be  available  for  this\n"
+"              option to work properly.\n"
+"\n"
+"              (iOS  and macOS only) If curl is built against Secure Transport,\n"
+, stdout);
+ fputs(
+"              then this option is supported for  backward  compatibility  with\n"
+"              other  SSL  engines,  but it should not be set. If the option is\n"
+"              not set, then curl will use the certificates in the  system  and\n"
+"              user  Keychain to verify the peer, which is the preferred method\n"
+"              of verifying the peer's certificate chain.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"       --capath <dir>\n"
+, stdout);
+ fputs(
+"              (TLS) Tells curl to use the specified certificate  directory  to\n"
+"              verify  the  peer.  Multiple paths can be provided by separating\n"
+"              them with \":\" (e.g.  \"path1:path2:path3\"). The certificates must\n"
+"              be  in  PEM  format,  and  if curl is built against OpenSSL, the\n"
+"              directory must have been processed using  the  c_rehash  utility\n"
+"              supplied  with OpenSSL. Using --capath can allow OpenSSL-powered\n"
+, stdout);
+ fputs(
+"              curl to make SSL-connections much more  efficiently  than  using\n"
+"              --cacert if the --cacert file contains many CA certificates.\n"
+"\n"
+"              If this option is set, the default capath value will be ignored,\n"
+"              and if it is used several times, the last one will be used.\n"
+"\n"
+"       --cert-status\n"
+"              (TLS) Tells curl to verify the status of the server  certificate\n"
+"              by using the Certificate Status Request (aka. OCSP stapling) TLS\n"
+, stdout);
+ fputs(
+"              extension.\n"
+"\n"
+"              If this option is enabled and the server sends an invalid  (e.g.\n"
+"              expired) response, if the response suggests that the server cer-\n"
+"              tificate has been revoked, or no response at  all  is  received,\n"
+"              the verification fails.\n"
+"\n"
+"              This  is  currently  only implemented in the OpenSSL, GnuTLS and\n"
+"              NSS backends.\n"
+"\n"
+"              Added in 7.41.0.\n"
+"\n"
+"       --cert-type <type>\n"
+, stdout);
+ fputs(
+"              (TLS) Tells curl what certificate type the provided  certificate\n"
+"              is in. PEM, DER and ENG are recognized types.  If not specified,\n"
+"              PEM is assumed.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"              See also -E, --cert and --key and --key-type.\n"
+"\n"
+"       -E, --cert <certificate[:password]>\n"
+"              (TLS) Tells curl to use the specified  client  certificate  file\n"
+, stdout);
+ fputs(
+"              when getting a file with HTTPS, FTPS or another SSL-based proto-\n"
+"              col. The certificate must be in PKCS#12 format if  using  Secure\n"
+"              Transport,  or  PEM  format  if  using any other engine.  If the\n"
+"              optional password isn't specified, it will be queried for on the\n"
+"              terminal.  Note  that  this  option assumes a \"certificate\" file\n"
+"              that is the private key and the client certificate concatenated!\n"
+, stdout);
+ fputs(
+"              See -E, --cert and --key to specify them independently.\n"
+"\n"
+"              If  curl  is  built against the NSS SSL library then this option\n"
+"              can tell curl the nickname of the certificate to use within  the\n"
+"              NSS  database defined by the environment variable SSL_DIR (or by\n"
+"              default /etc/pki/nssdb). If the NSS  PEM  PKCS#11  module  (lib-\n"
+"              nsspem.so)  is  available  then  PEM files may be loaded. If you\n"
+, stdout);
+ fputs(
+"              want to use a file from the current directory, please precede it\n"
+"              with  \"./\"  prefix, in order to avoid confusion with a nickname.\n"
+"              If the nickname contains \":\", it needs to be preceded by \"\\\"  so\n"
+"              that  it  is not recognized as password delimiter.  If the nick-\n"
+"              name contains \"\\\", it needs to be escaped as \"\\\\\" so that it  is\n"
+"              not recognized as an escape character.\n"
+"\n"
+, stdout);
+ fputs(
+"              (iOS  and macOS only) If curl is built against Secure Transport,\n"
+"              then the certificate string can either be the name of a certifi-\n"
+"              cate/private  key in the system or user keychain, or the path to\n"
+"              a PKCS#12-encoded certificate and private key. If  you  want  to\n"
+"              use  a  file  from the current directory, please precede it with\n"
+"              \"./\" prefix, in order to avoid confusion with a nickname.\n"
+"\n"
+, stdout);
+ fputs(
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"              See also --cert-type and --key and --key-type.\n"
+"\n"
+"       --ciphers <list of ciphers>\n"
+"              (TLS) Specifies which ciphers to use in the connection. The list\n"
+"              of  ciphers  must  specify  valid ciphers. Read up on SSL cipher\n"
+"              list details on this URL:\n"
+"\n"
+"               https://curl.haxx.se/docs/ssl-ciphers.html\n"
+"\n"
+, stdout);
+ fputs(
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"       --compressed-ssh\n"
+"              (SCP SFTP) Enables built-in SSH compression.  This is a request,\n"
+"              not an order; the server may or may not do it.\n"
+"\n"
+"              Added in 7.56.0.\n"
+"\n"
+"       --compressed\n"
+"              (HTTP) Request a compressed response using one of the algorithms\n"
+"              curl supports, and save  the  uncompressed  document.   If  this\n"
+, stdout);
+ fputs(
+"              option  is  used  and  the server sends an unsupported encoding,\n"
+"              curl will report an error.\n"
+"\n"
+"       -K, --config <file>\n"
+"\n"
+"              Specify a text file to read curl  arguments  from.  The  command\n"
+"              line  arguments  found  in the text file will be used as if they\n"
+"              were provided on the command line.\n"
+"\n"
+"              Options and their parameters must be specified on the same  line\n"
+, stdout);
+ fputs(
+"              in the file, separated by whitespace, colon, or the equals sign.\n"
+"              Long option names can optionally be given  in  the  config  file\n"
+"              without the initial double dashes and if so, the colon or equals\n"
+"              characters can be used as separators. If the option is specified\n"
+"              with  one or two dashes, there can be no colon or equals charac-\n"
+"              ter between the option and its parameter.\n"
+"\n"
+, stdout);
+ fputs(
+"              If the parameter is to contain whitespace, the parameter must be\n"
+"              enclosed  within  quotes.  Within  double  quotes, the following\n"
+"              escape sequences are available: \\\\, \\\", \\t, \\n,  \\r  and  \\v.  A\n"
+"              backslash  preceding  any  other letter is ignored. If the first\n"
+"              column of a config line is a '#' character, the rest of the line\n"
+"              will be treated as a comment. Only write one option per physical\n"
+, stdout);
+ fputs(
+"              line in the config file.\n"
+"\n"
+"              Specify the filename to -K, --config as '-' to  make  curl  read\n"
+"              the file from stdin.\n"
+"\n"
+"              Note  that  to  be able to specify a URL in the config file, you\n"
+"              need to specify it using the --url option,  and  not  by  simply\n"
+"              writing  the  URL  on its own line. So, it could look similar to\n"
+"              this:\n"
+"\n"
+"              url = \"https://curl.haxx.se/docs/\"\n"
+"\n"
+, stdout);
+ fputs(
+"              When curl is invoked, it (unless -q, --disable is  used)  checks\n"
+"              for a default config file and uses it if found. The default con-\n"
+"              fig file is checked for in the following places in this order:\n"
+"\n"
+"              1) curl tries to find the \"home dir\": It first  checks  for  the\n"
+"              CURL_HOME and then the HOME environment variables. Failing that,\n"
+"              it uses getpwuid() on Unix-like systems (which returns the  home\n"
+, stdout);
+ fputs(
+"              dir  given the current user in your system). On Windows, it then\n"
+"              checks for the APPDATA variable, or as a last resort the '%USER-\n"
+"              PROFILE%\\Application Data'.\n"
+"\n"
+"              2)  On  windows, if there is no _curlrc file in the home dir, it\n"
+"              checks for one in the same dir the curl executable is placed. On\n"
+"              Unix-like  systems,  it will simply try to load .curlrc from the\n"
+"              determined home dir.\n"
+"\n"
+, stdout);
+ fputs(
+"              # --- Example file ---\n"
+"              # this is a comment\n"
+"              url = \"example.com\"\n"
+"              output = \"curlhere.html\"\n"
+"              user-agent = \"superagent/1.0\"\n"
+"\n"
+"              # and fetch another URL too\n"
+"              url = \"example.com/docs/manpage.html\"\n"
+"              -O\n"
+"              referer = \"http://nowhereatall.example.com/\"\n"
+"              # --- End of example file ---\n"
+"\n"
+"              This option can be used multiple times to load  multiple  config\n"
+, stdout);
+ fputs(
+"              files.\n"
+"\n"
+"       --connect-timeout <seconds>\n"
+"              Maximum  time  in  seconds  that  you allow curl's connection to\n"
+"              take.  This only limits the connection phase, so  if  curl  con-\n"
+"              nects  within the given period it will continue - if not it will\n"
+"              exit.  Since version 7.32.0, this option accepts decimal values.\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"              See also -m, --max-time.\n"
+"\n"
+, stdout);
+ fputs(
+"       --connect-to <HOST1:PORT1:HOST2:PORT2>\n"
+"\n"
+"              For  a  request  to  the  given  HOST1:PORT1  pair,  connect  to\n"
+"              HOST2:PORT2 instead.  This option is suitable to direct requests\n"
+"              at a specific server, e.g. at a specific cluster node in a clus-\n"
+"              ter  of  servers. This option is only used to establish the net-\n"
+"              work connection. It does NOT affect the  hostname/port  that  is\n"
+, stdout);
+ fputs(
+"              used for TLS/SSL (e.g. SNI, certificate verification) or for the\n"
+"              application protocols. \"HOST1\" and  \"PORT1\"  may  be  the  empty\n"
+"              string, meaning \"any host/port\". \"HOST2\" and \"PORT2\" may also be\n"
+"              the  empty  string,  meaning   \"use   the   request's   original\n"
+"              host/port\".\n"
+"\n"
+"              A \"host\" specified to this option is compared as a string, so it\n"
+, stdout);
+ fputs(
+"              needs to match the name used in request URL. It  can  be  either\n"
+"              numerical  such  as  \"127.0.0.1\"  or  the full host name such as\n"
+"              \"example.org\".\n"
+"\n"
+"              This option can be used many times to add many connect rules.\n"
+"\n"
+"              See also --resolve and -H, --header. Added in 7.49.0.\n"
+"\n"
+"       -C, --continue-at <offset>\n"
+"              Continue/Resume a previous file transfer at  the  given  offset.\n"
+, stdout);
+ fputs(
+"              The  given  offset  is  the  exact  number of bytes that will be\n"
+"              skipped, counting from the beginning of the source  file  before\n"
+"              it is transferred to the destination.  If used with uploads, the\n"
+"              FTP server command SIZE will not be used by curl.\n"
+"\n"
+"              Use \"-C -\" to tell curl to automatically find out  where/how  to\n"
+"              resume  the  transfer. It then uses the given output/input files\n"
+"              to figure that out.\n"
+"\n"
+, stdout);
+ fputs(
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"              See also -r, --range.\n"
+"\n"
+"       -c, --cookie-jar <filename>\n"
+"              (HTTP) Specify to which file you want curl to write all  cookies\n"
+"              after  a  completed  operation. Curl writes all cookies from its\n"
+"              in-memory cookie storage to the given file at the end of  opera-\n"
+"              tions.  If  no  cookies  are known, no data will be written. The\n"
+, stdout);
+ fputs(
+"              file will be written using the Netscape cookie file  format.  If\n"
+"              you set the file name to a single dash, \"-\", the cookies will be\n"
+"              written to stdout.\n"
+"\n"
+"              This command line option will activate the  cookie  engine  that\n"
+"              makes curl record and use cookies. Another way to activate it is\n"
+"              to use the -b, --cookie option.\n"
+"\n"
+"              If the cookie jar can't be created or written to, the whole curl\n"
+, stdout);
+ fputs(
+"              operation  won't fail or even report an error clearly. Using -v,\n"
+"              --verbose will get a warning displayed, but  that  is  the  only\n"
+"              visible feedback you get about this possibly lethal situation.\n"
+"\n"
+"              If  this  option  is used several times, the last specified file\n"
+"              name will be used.\n"
+"\n"
+"       -b, --cookie <data>\n"
+"              (HTTP) Pass the data to the HTTP server in the Cookie header. It\n"
+, stdout);
+ fputs(
+"              is  supposedly the data previously received from the server in a\n"
+"              \"Set-Cookie:\"  line.   The  data  should  be   in   the   format\n"
+"              \"NAME1=VALUE1; NAME2=VALUE2\".\n"
+"\n"
+"              If  no '=' symbol is used in the argument, it is instead treated\n"
+"              as a filename to read previously stored cookie from. This option\n"
+"              also  activates  the  cookie  engine which will make curl record\n"
+, stdout);
+ fputs(
+"              incoming cookies, which may be handy if  you're  using  this  in\n"
+"              combination  with  the  -L, --location option or do multiple URL\n"
+"              transfers on the same invoke.\n"
+"\n"
+"              The file format of the file to read cookies from should be plain\n"
+"              HTTP  headers  (Set-Cookie style) or the Netscape/Mozilla cookie\n"
+"              file format.\n"
+"\n"
+"              The file specified with -b, --cookie is only used as  input.  No\n"
+, stdout);
+ fputs(
+"              cookies  will  be written to the file. To store cookies, use the\n"
+"              -c, --cookie-jar option.\n"
+"\n"
+"              Exercise caution if you  are  using  this  option  and  multiple\n"
+"              transfers may occur.  If you use the NAME1=VALUE1; format, or in\n"
+"              a file use the Set-Cookie format and  don't  specify  a  domain,\n"
+"              then the cookie is sent for any domain (even after redirects are\n"
+, stdout);
+ fputs(
+"              followed) and cannot be modified by a server-set cookie. If  the\n"
+"              cookie  engine is enabled and a server sets a cookie of the same\n"
+"              name then both will be sent on a future transfer to that server,\n"
+"              likely  not  what  you  intended.  To address these issues set a\n"
+"              domain in Set-Cookie (doing that will include  sub  domains)  or\n"
+"              use the Netscape format.\n"
+"\n"
+, stdout);
+ fputs(
+"              If this option is used several times, the last one will be used.\n"
+"              Users very often want to both read cookies from a file and write\n"
+"              updated cookies back to a file, so using both -b,  --cookie  and\n"
+"              -c, --cookie-jar in the same command line is common.\n"
+"\n"
+"       --create-dirs\n"
+"              When used in conjunction with the -o, --output option, curl will\n"
+"              create the necessary local directory hierarchy as  needed.  This\n"
+, stdout);
+ fputs(
+"              option  creates the dirs mentioned with the -o, --output option,\n"
+"              nothing else. If the --output file name uses no dir  or  if  the\n"
+"              dirs it mentions already exist, no dir will be created.\n"
+"\n"
+"              To  create remote directories when using FTP or SFTP, try --ftp-\n"
+"              create-dirs.\n"
+"\n"
+"       --crlf (FTP SMTP)  Convert  LF  to  CRLF  in  upload.  Useful  for  MVS\n"
+"              (OS/390).\n"
+"\n"
+"              (SMTP added in 7.40.0)\n"
+"\n"
+, stdout);
+ fputs(
+"       --crlfile <file>\n"
+"              (TLS) Provide a file using PEM format with a Certificate Revoca-\n"
+"              tion List that may specify peer certificates that are to be con-\n"
+"              sidered revoked.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"              Added in 7.19.7.\n"
+"\n"
+"       --data-ascii <data>\n"
+"              (HTTP) This is just an alias for -d, --data.\n"
+"\n"
+"       --data-binary <data>\n"
+, stdout);
+ fputs(
+"              (HTTP)  This  posts data exactly as specified with no extra pro-\n"
+"              cessing whatsoever.\n"
+"\n"
+"              If you start the data with the letter @, the rest  should  be  a\n"
+"              filename.   Data  is  posted  in  a similar manner as -d, --data\n"
+"              does, except that newlines and carriage  returns  are  preserved\n"
+"              and conversions are never done.\n"
+"\n"
+"              If  this  option  is  used several times, the ones following the\n"
+, stdout);
+ fputs(
+"              first will append data as described in -d, --data.\n"
+"\n"
+"       --data-raw <data>\n"
+"              (HTTP) This posts data similarly to -d, --data but  without  the\n"
+"              special interpretation of the @ character.\n"
+"\n"
+"              See also -d, --data. Added in 7.43.0.\n"
+"\n"
+"       --data-urlencode <data>\n"
+"              (HTTP)  This posts data, similar to the other -d, --data options\n"
+"              with the exception that this performs URL-encoding.\n"
+"\n"
+, stdout);
+ fputs(
+"              To be CGI-compliant, the <data> part should begin  with  a  name\n"
+"              followed  by a separator and a content specification. The <data>\n"
+"              part can be passed to curl using one of the following syntaxes:\n"
+"\n"
+"              content\n"
+"                     This will make curl URL-encode the content and pass  that\n"
+"                     on.  Just  be careful so that the content doesn't contain\n"
+"                     any = or @ symbols, as that will  then  make  the  syntax\n"
+, stdout);
+ fputs(
+"                     match one of the other cases below!\n"
+"\n"
+"              =content\n"
+"                     This  will make curl URL-encode the content and pass that\n"
+"                     on. The preceding = symbol is not included in the data.\n"
+"\n"
+"              name=content\n"
+"                     This will make curl URL-encode the content part and  pass\n"
+"                     that  on.  Note that the name part is expected to be URL-\n"
+"                     encoded already.\n"
+"\n"
+"              @filename\n"
+, stdout);
+ fputs(
+"                     This will  make  curl  load  data  from  the  given  file\n"
+"                     (including  any  newlines), URL-encode that data and pass\n"
+"                     it on in the POST.\n"
+"\n"
+"              name@filename\n"
+"                     This will  make  curl  load  data  from  the  given  file\n"
+"                     (including  any  newlines), URL-encode that data and pass\n"
+"                     it on in the POST. The  name  part  gets  an  equal  sign\n"
+, stdout);
+ fputs(
+"                     appended, resulting in name=urlencoded-file-content. Note\n"
+"                     that the name is expected to be URL-encoded already.\n"
+"       See also -d, --data and --data-raw. Added in 7.18.0.\n"
+"\n"
+"       -d, --data <data>\n"
+"              (HTTP) Sends the specified data in a POST request  to  the  HTTP\n"
+"              server,  in  the  same  way  that a browser does when a user has\n"
+"              filled in an HTML form and presses the submit button. This  will\n"
+, stdout);
+ fputs(
+"              cause curl to pass the data to the server using the content-type\n"
+"              application/x-www-form-urlencoded.  Compare to -F, --form.\n"
+"\n"
+"              --data-raw is almost the same but does not have a special inter-\n"
+"              pretation  of  the  @ character. To post data purely binary, you\n"
+"              should instead use the --data-binary option.  To URL-encode  the\n"
+"              value of a form field you may use --data-urlencode.\n"
+"\n"
+, stdout);
+ fputs(
+"              If  any of these options is used more than once on the same com-\n"
+"              mand line, the data pieces specified  will  be  merged  together\n"
+"              with  a  separating  &-symbol.  Thus,  using  '-d name=daniel -d\n"
+"              skill=lousy'  would  generate  a  post  chunk  that  looks  like\n"
+"              'name=daniel&skill=lousy'.\n"
+"\n"
+"              If  you  start  the data with the letter @, the rest should be a\n"
+, stdout);
+ fputs(
+"              file name to read the data from, or - if you want curl  to  read\n"
+"              the data from stdin. Multiple files can also be specified. Post-\n"
+"              ing data from a file named  from  a  file  like  that,  carriage\n"
+"              returns and newlines will be stripped out. If you don't want the\n"
+"              @ character to have  a  special  interpretation  use  --data-raw\n"
+"              instead.\n"
+"\n"
+"              See also --data-binary and --data-urlencode and --data-raw. This\n"
+, stdout);
+ fputs(
+"              option overrides -F, --form and -I, --head and --upload.\n"
+"\n"
+"       --delegation <LEVEL>\n"
+"              (GSS/kerberos) Set LEVEL to tell the server what it  is  allowed\n"
+"              to delegate when it comes to user credentials.\n"
+"\n"
+"              none   Don't allow any delegation.\n"
+"\n"
+"              policy Delegates  if  and only if the OK-AS-DELEGATE flag is set\n"
+"                     in the Kerberos service ticket,  which  is  a  matter  of\n"
+"                     realm policy.\n"
+"\n"
+, stdout);
+ fputs(
+"              always Unconditionally allow the server to delegate.\n"
+"\n"
+"       --digest\n"
+"              (HTTP)  Enables HTTP Digest authentication. This is an authenti-\n"
+"              cation scheme that prevents the password from  being  sent  over\n"
+"              the  wire in clear text. Use this in combination with the normal\n"
+"              -u, --user option to set user name and password.\n"
+"\n"
+"              If this option is used several times,  only  the  first  one  is\n"
+"              used.\n"
+"\n"
+, stdout);
+ fputs(
+"              See  also  -u,  --user  and  --proxy-digest  and --anyauth. This\n"
+"              option overrides --basic and --ntlm and --negotiate.\n"
+"\n"
+"       --disable-eprt\n"
+"              (FTP) Tell curl to disable the use of the EPRT and LPRT commands\n"
+"              when doing active FTP transfers. Curl will normally always first\n"
+"              attempt to use EPRT, then LPRT before using PORT, but with  this\n"
+"              option,  it  will  use PORT right away. EPRT and LPRT are exten-\n"
+, stdout);
+ fputs(
+"              sions to the original FTP protocol, and  may  not  work  on  all\n"
+"              servers, but they enable more functionality in a better way than\n"
+"              the traditional PORT command.\n"
+"\n"
+"              --eprt can be used to explicitly enable EPRT again and --no-eprt\n"
+"              is an alias for --disable-eprt.\n"
+"\n"
+"              If  the  server is accessed using IPv6, this option will have no\n"
+"              effect as EPRT is necessary then.\n"
+"\n"
+, stdout);
+ fputs(
+"              Disabling EPRT only changes the active behavior. If you want  to\n"
+"              switch  to  passive  mode  you need to not use -P, --ftp-port or\n"
+"              force it with --ftp-pasv.\n"
+"\n"
+"       --disable-epsv\n"
+"              (FTP) (FTP) Tell curl to disable the use  of  the  EPSV  command\n"
+"              when  doing  passive  FTP  transfers.  Curl will normally always\n"
+"              first attempt to use EPSV before PASV, but with this option,  it\n"
+"              will not try using EPSV.\n"
+"\n"
+, stdout);
+ fputs(
+"              --epsv can be used to explicitly enable EPSV again and --no-epsv\n"
+"              is an alias for --disable-epsv.\n"
+"\n"
+"              If the server is an IPv6 host, this option will have  no  effect\n"
+"              as EPSV is necessary then.\n"
+"\n"
+"              Disabling EPSV only changes the passive behavior. If you want to\n"
+"              switch to active mode you need to use -P, --ftp-port.\n"
+"\n"
+"       -q, --disable\n"
+"              If used as the first parameter on the command line,  the  curlrc\n"
+, stdout);
+ fputs(
+"              config  file will not be read and used. See the -K, --config for\n"
+"              details on the default config file search path.\n"
+"\n"
+"       --dns-interface <interface>\n"
+"              (DNS) Tell curl to send outgoing DNS  requests  through  <inter-\n"
+"              face>.  This  option is a counterpart to --interface (which does\n"
+"              not affect DNS). The supplied string must be an  interface  name\n"
+"              (not an address).\n"
+"\n"
+, stdout);
+ fputs(
+"              See  also  --dns-ipv4-addr  and --dns-ipv6-addr. --dns-interface\n"
+"              requires that the underlying libcurl was  built  to  support  c-\n"
+"              ares. Added in 7.33.0.\n"
+"\n"
+"       --dns-ipv4-addr <address>\n"
+"              (DNS)  Tell  curl  to  bind to <ip-address> when making IPv4 DNS\n"
+"              requests, so that the DNS requests originate from this  address.\n"
+"              The argument should be a single IPv4 address.\n"
+"\n"
+, stdout);
+ fputs(
+"              See  also  --dns-interface  and --dns-ipv6-addr. --dns-ipv4-addr\n"
+"              requires that the underlying libcurl was  built  to  support  c-\n"
+"              ares. Added in 7.33.0.\n"
+"\n"
+"       --dns-ipv6-addr <address>\n"
+"              (DNS)  Tell  curl  to  bind to <ip-address> when making IPv6 DNS\n"
+"              requests, so that the DNS requests originate from this  address.\n"
+"              The argument should be a single IPv6 address.\n"
+"\n"
+, stdout);
+ fputs(
+"              See  also  --dns-interface  and --dns-ipv4-addr. --dns-ipv6-addr\n"
+"              requires that the underlying libcurl was  built  to  support  c-\n"
+"              ares. Added in 7.33.0.\n"
+"\n"
+"       --dns-servers <addresses>\n"
+"              Set  the  list  of  DNS servers to be used instead of the system\n"
+"              default.  The list of IP addresses should be separated with com-\n"
+"              mas. Port numbers may also optionally be given as :<port-number>\n"
+, stdout);
+ fputs(
+"              after each IP address.\n"
+"\n"
+"              --dns-servers requires that the underlying libcurl was built  to\n"
+"              support c-ares. Added in 7.33.0.\n"
+"\n"
+"       -D, --dump-header <filename>\n"
+"              (HTTP  FTP) Write the received protocol headers to the specified\n"
+"              file.\n"
+"\n"
+"              This option is handy to use when you want to store  the  headers\n"
+"              that  an  HTTP site sends to you. Cookies from the headers could\n"
+, stdout);
+ fputs(
+"              then be read in a  second  curl  invocation  by  using  the  -b,\n"
+"              --cookie  option! The -c, --cookie-jar option is a better way to\n"
+"              store cookies.\n"
+"\n"
+"              When used in FTP, the FTP server response lines  are  considered\n"
+"              being \"headers\" and thus are saved there.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"              See also -o, --output.\n"
+"\n"
+"       --egd-file <file>\n"
+, stdout);
+ fputs(
+"              (TLS)  Specify  the  path  name  to the Entropy Gathering Daemon\n"
+"              socket. The socket is used to seed the  random  engine  for  SSL\n"
+"              connections.\n"
+"\n"
+"              See also --random-file.\n"
+"\n"
+"       --engine <name>\n"
+"              (TLS)  Select the OpenSSL crypto engine to use for cipher opera-\n"
+"              tions. Use --engine list to print a list of build-time supported\n"
+"              engines.  Note  that  not  all  (or  none) of the engines may be\n"
+, stdout);
+ fputs(
+"              available at run-time.\n"
+"\n"
+"       --expect100-timeout <seconds>\n"
+"              (HTTP) Maximum time in seconds that you allow curl to wait for a\n"
+"              100-continue  response  when curl emits an Expects: 100-continue\n"
+"              header in its request. By default curl  will  wait  one  second.\n"
+"              This  option accepts decimal values! When curl stops waiting, it\n"
+"              will continue as if the response has been received.\n"
+"\n"
+, stdout);
+ fputs(
+"              See also --connect-timeout. Added in 7.47.0.\n"
+"\n"
+"       --fail-early\n"
+"              Fail and exit on the first detected transfer error.\n"
+"\n"
+"              When curl is used to do multiple transfers on the command  line,\n"
+"              it  will  attempt  to  operate on each given URL, one by one. By\n"
+"              default, it will ignore errors if there are more URLs given  and\n"
+"              the  last  URL's  success  will  determine  the  error code curl\n"
+, stdout);
+ fputs(
+"              returns. So early failures will be \"hidden\" by  subsequent  suc-\n"
+"              cessful transfers.\n"
+"\n"
+"              Using  this  option,  curl  will  instead return an error on the\n"
+"              first transfer that fails, independent of  the  amount  of  URLs\n"
+"              that  are given on the command line. This way, no transfer fail-\n"
+"              ures go undetected by scripts and similar.\n"
+"\n"
+"              This option is global and does not need to be specified for each\n"
+, stdout);
+ fputs(
+"              use of -:, --next.\n"
+"\n"
+"              This option does not imply -f, --fail, which causes transfers to\n"
+"              fail due to the server's HTTP status code. You can  combine  the\n"
+"              two options, however note -f, --fail is not global and is there-\n"
+"              fore contained by -:, --next.\n"
+"\n"
+"              Added in 7.52.0.\n"
+"\n"
+"       -f, --fail\n"
+"              (HTTP) Fail silently (no output at all) on server  errors.  This\n"
+, stdout);
+ fputs(
+"              is  mostly done to better enable scripts etc to better deal with\n"
+"              failed attempts. In normal cases when an HTTP  server  fails  to\n"
+"              deliver  a  document,  it  returns  an  HTML document stating so\n"
+"              (which often also describes why and more). This flag  will  pre-\n"
+"              vent curl from outputting that and return error 22.\n"
+"\n"
+"              This  method is not fail-safe and there are occasions where non-\n"
+, stdout);
+ fputs(
+"              successful response codes will  slip  through,  especially  when\n"
+"              authentication is involved (response codes 401 and 407).\n"
+"\n"
+"       --false-start\n"
+"              (TLS)  Tells  curl  to use false start during the TLS handshake.\n"
+"              False start is a mode where a  TLS  client  will  start  sending\n"
+"              application data before verifying the server's Finished message,\n"
+"              thus saving a round trip when performing a full handshake.\n"
+"\n"
+, stdout);
+ fputs(
+"              This is currently only implemented in the NSS and Secure  Trans-\n"
+"              port (on iOS 7.0 or later, or OS X 10.9 or later) backends.\n"
+"\n"
+"              Added in 7.42.0.\n"
+"\n"
+"       --form-string <name=string>\n"
+"              (HTTP  SMTP  IMAP)  Similar  to -F, --form except that the value\n"
+"              string for the named parameter is used  literally.  Leading  '@'\n"
+"              and '<' characters, and the ';type=' string in the value have no\n"
+, stdout);
+ fputs(
+"              special meaning. Use this in preference to -F, --form if there's\n"
+"              any  possibility  that the string value may accidentally trigger\n"
+"              the '@' or '<' features of -F, --form.\n"
+"\n"
+"              See also -F, --form.\n"
+"\n"
+"       -F, --form <name=content>\n"
+"              (HTTP SMTP IMAP) For HTTP protocol family, this lets  curl  emu-\n"
+"              late  a  filled-in  form  in which a user has pressed the submit\n"
+, stdout);
+ fputs(
+"              button. This causes curl to POST  data  using  the  Content-Type\n"
+"              multipart/form-data according to RFC 2388.\n"
+"\n"
+"              For  SMTP and IMAP protocols, this is the mean to compose a mul-\n"
+"              tipart mail message to transmit.\n"
+"\n"
+"              This enables uploading of binary files etc. To force  the  'con-\n"
+"              tent' part to be a file, prefix the file name with an @ sign. To\n"
+, stdout);
+ fputs(
+"              just get the content part from a file, prefix the file name with\n"
+"              the  symbol  <.  The  difference  between @ and < is then that @\n"
+"              makes a file get attached in the post as a  file  upload,  while\n"
+"              the < makes a text field and just get the contents for that text\n"
+"              field from a file.\n"
+"\n"
+"              Example: to send an image to an HTTP server, where 'profile'  is\n"
+, stdout);
+ fputs(
+"              the  name  of  the  form-field to which portrait.jpg will be the\n"
+"              input:\n"
+"\n"
+"               curl -F profile=@portrait.jpg https://example.com/upload.cgi\n"
+"\n"
+"              To read content from stdin instead of a file, use - as the file-\n"
+"              name.  This  goes  for  both @ and < constructs. If stdin is not\n"
+"              attached to a regular file, it is buffered  first  to  determine\n"
+"              its  size  and  allow  a possible resend. Defining a part's data\n"
+, stdout);
+ fputs(
+"              from a named non-regular file (such as a named pipe or  similar)\n"
+"              is  unfortunately  not  subject  to buffering and will be effec-\n"
+"              tively read at transmission time; since the full size is unknown\n"
+"              before  the  transfer starts, data is sent as chunks by HTTP and\n"
+"              rejected by IMAP.\n"
+"\n"
+"              You can also  tell  curl  what  Content-Type  to  use  by  using\n"
+"              'type=', in a manner similar to:\n"
+"\n"
+, stdout);
+ fputs(
+"               curl -F \"web=@index.html;type=text/html\" example.com\n"
+"\n"
+"              or\n"
+"\n"
+"               curl -F \"name=daniel;type=text/foo\" example.com\n"
+"\n"
+"              You  can  also explicitly change the name field of a file upload\n"
+"              part by setting filename=, like this:\n"
+"\n"
+"               curl -F \"file=@localfile;filename=nameinpost\" example.com\n"
+"\n"
+"              If filename/path contains ',' or ';', it must be quoted by  dou-\n"
+"              ble-quotes like:\n"
+"\n"
+, stdout);
+ fputs(
+"               curl   -F  \"file=@\\\"localfile\\\";filename=\\\"nameinpost\\\"\"  exam-\n"
+"              ple.com\n"
+"\n"
+"              or\n"
+"\n"
+"               curl -F 'file=@\"localfile\";filename=\"nameinpost\"' example.com\n"
+"\n"
+"              Note that if a filename/path is  quoted  by  double-quotes,  any\n"
+"              double-quote or backslash within the filename must be escaped by\n"
+"              backslash.\n"
+"\n"
+"              Quoting must also be applied to non-file  data  if  it  contains\n"
+, stdout);
+ fputs(
+"              semicolons, leading/trailing spaces or leading double quotes:\n"
+"\n"
+"               curl  -F  'colors=\"red;  green;  blue\";type=text/x-myapp' exam-\n"
+"              ple.com\n"
+"\n"
+"              You can add custom headers to the  field  by  setting  headers=,\n"
+"              like\n"
+"\n"
+"                curl -F \"submit=OK;headers=\\\"X-submit-type: OK\\\"\" example.com\n"
+"\n"
+"              or\n"
+"\n"
+"                curl -F \"submit=OK;headers=@headerfile\" example.com\n"
+"\n"
+, stdout);
+ fputs(
+"              The  headers=  keyword may appear more that once and above notes\n"
+"              about quoting apply. When headers are read from  a  file,  Empty\n"
+"              lines and lines starting with '#' are comments and ignored; each\n"
+"              header can be folded by splitting between two words and starting\n"
+"              the  continuation  line  with a space; embedded carriage-returns\n"
+"              and trailing spaces are stripped.   Here  is  an  example  of  a\n"
+, stdout);
+ fputs(
+"              header file contents:\n"
+"\n"
+"                # This file contain two headers.\n"
+"                X-header-1: this is a header\n"
+"\n"
+"                # The following header is folded.\n"
+"                X-header-2: this is\n"
+"                 another header\n"
+"\n"
+"              To  support  sending  multipart  mail  messages,  the  syntax is\n"
+"              extended as follows:\n"
+"              - name can be omitted: the equal sign is the first character  of\n"
+"              the argument,\n"
+, stdout);
+ fputs(
+"              -  if  data  starts with '(', this signals to start a new multi-\n"
+"              part: it can be followed by a content type specification.\n"
+"              - a multipart can be terminated with a '=)' argument.\n"
+"\n"
+"              Example: the following command sends an SMTP  mime  e-mail  con-\n"
+"              sisting in an inline part in two alternative formats: plain text\n"
+"              and HTML. It attaches a text file:\n"
+"\n"
+"               curl -F '=(;type=multipart/alternative' \\\n"
+, stdout);
+ fputs(
+"                       -F '=plain text message' \\\n"
+"                       -F '= <body>HTML message</body>;type=text/html' \\\n"
+"                    -F '=)' -F '=@textfile.txt' ...  smtp://example.com\n"
+"\n"
+"              Data can be  encoded  for  transfer  using  encoder=.  Available\n"
+"              encodings  are  binary and 8bit that do nothing else than adding\n"
+"              the corresponding Content-Transfer-Encoding  header,  7bit  that\n"
+, stdout);
+ fputs(
+"              only  rejects  8-bit  characters  with a transfer error, quoted-\n"
+"              printable and base64 that encodes data according to  the  corre-\n"
+"              sponding schemes, limiting lines length to 76 characters.\n"
+"\n"
+"              Example:  send  multipart mail with a quoted-printable text mes-\n"
+"              sage and a base64 attached file:\n"
+"\n"
+"               curl -F '=text message;encoder=quoted-printable' \\\n"
+"                    -F '=@localfile;encoder=base64' ... smtp://example.com\n"
+"\n"
+, stdout);
+ fputs(
+"              See further examples and details in the MANUAL.\n"
+"\n"
+"              This option can be used multiple times.\n"
+"\n"
+"              This option overrides -d, --data and -I, --head and --upload.\n"
+"\n"
+"       --ftp-account <data>\n"
+"              (FTP) When an FTP server asks for \"account data\" after user name\n"
+"              and  password has been provided, this data is sent off using the\n"
+"              ACCT command.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+, stdout);
+ fputs(
+"              Added in 7.13.0.\n"
+"\n"
+"       --ftp-alternative-to-user <command>\n"
+"              (FTP) If authenticating with the USER and PASS  commands  fails,\n"
+"              send  this  command.   When  connecting  to  Tumbleweed's Secure\n"
+"              Transport server over FTPS using  a  client  certificate,  using\n"
+"              \"SITE  AUTH\"  will tell the server to retrieve the username from\n"
+"              the certificate.\n"
+"              Added in 7.15.5.\n"
+"\n"
+"       --ftp-create-dirs\n"
+, stdout);
+ fputs(
+"              (FTP SFTP) When an FTP or SFTP URL/operation uses  a  path  that\n"
+"              doesn't  currently exist on the server, the standard behavior of\n"
+"              curl is to fail. Using this option, curl will instead attempt to\n"
+"              create missing directories.\n"
+"\n"
+"              See also --create-dirs.\n"
+"\n"
+"       --ftp-method <method>\n"
+"              (FTP)  Control what method curl should use to reach a file on an\n"
+, stdout);
+ fputs(
+"              FTP(S) server. The method argument should be one of the  follow-\n"
+"              ing alternatives:\n"
+"\n"
+"              multicwd\n"
+"                     curl  does  a  single CWD operation for each path part in\n"
+"                     the given URL. For deep hierarchies this means very  many\n"
+"                     commands.  This  is  how RFC 1738 says it should be done.\n"
+"                     This is the default but the slowest behavior.\n"
+"\n"
+, stdout);
+ fputs(
+"              nocwd  curl does no CWD at all. curl will do  SIZE,  RETR,  STOR\n"
+"                     etc and give a full path to the server for all these com-\n"
+"                     mands. This is the fastest behavior.\n"
+"\n"
+"              singlecwd\n"
+"                     curl does one CWD with the full target directory and then\n"
+"                     operates  on  the  file  \"normally\" (like in the multicwd\n"
+"                     case). This is somewhat  more  standards  compliant  than\n"
+, stdout);
+ fputs(
+"                     'nocwd' but without the full penalty of 'multicwd'.\n"
+"\n"
+"       Added in 7.15.1.\n"
+"\n"
+"       --ftp-pasv\n"
+"              (FTP)  Use  passive mode for the data connection. Passive is the\n"
+"              internal default behavior, but using this option can be used  to\n"
+"              override a previous -P, --ftp-port option.\n"
+"\n"
+"              If  this  option  is  used  several times, only the first one is\n"
+"              used. Undoing an enforced passive really isn't  doable  but  you\n"
+, stdout);
+ fputs(
+"              must then instead enforce the correct -P, --ftp-port again.\n"
+"\n"
+"              Passive mode means that curl will try the EPSV command first and\n"
+"              then PASV, unless --disable-epsv is used.\n"
+"              See also --disable-epsv. Added in 7.11.0.\n"
+"\n"
+"       -P, --ftp-port <address>\n"
+"              (FTP) Reverses the default initiator/listener  roles  when  con-\n"
+"              necting  with  FTP. This option makes curl use active mode. curl\n"
+, stdout);
+ fputs(
+"              then tells the server to connect back to the client's  specified\n"
+"              address and port, while passive mode asks the server to setup an\n"
+"              IP address and port for it to connect to.  <address>  should  be\n"
+"              one of:\n"
+"\n"
+"              interface\n"
+"                     i.e  \"eth0\"  to  specify which interface's IP address you\n"
+"                     want to use (Unix only)\n"
+"\n"
+"              IP address\n"
+, stdout);
+ fputs(
+"                     i.e \"192.168.10.1\" to specify the exact IP address\n"
+"\n"
+"              host name\n"
+"                     i.e \"my.host.domain\" to specify the machine\n"
+"\n"
+"              -      make curl pick the same IP address that is  already  used\n"
+"                     for the control connection\n"
+"\n"
+"       If  this  option is used several times, the last one will be used. Dis-\n"
+"       able the use of PORT with --ftp-pasv. Disable the attempt  to  use  the\n"
+, stdout);
+ fputs(
+"       EPRT  command  instead  of PORT by using --disable-eprt. EPRT is really\n"
+"       PORT++.\n"
+"\n"
+"       Since 7.19.5, you can append  \":[start]-[end]\"  to  the  right  of  the\n"
+"       address,  to tell curl what TCP port range to use. That means you spec-\n"
+"       ify a port range, from a lower to a  higher  number.  A  single  number\n"
+"       works  as well, but do note that it increases the risk of failure since\n"
+"       the port may not be available.\n"
+"\n"
+"       See also --ftp-pasv and --disable-eprt.\n"
+"\n"
+, stdout);
+ fputs(
+"       --ftp-pret\n"
+"              (FTP) Tell curl to send a PRET command before PASV  (and  EPSV).\n"
+"              Certain  FTP  servers,  mainly drftpd, require this non-standard\n"
+"              command for directory listings as well as up  and  downloads  in\n"
+"              PASV mode.\n"
+"\n"
+"              Added in 7.20.0.\n"
+"\n"
+"       --ftp-skip-pasv-ip\n"
+"              (FTP) Tell curl to not use the IP address the server suggests in\n"
+"              its response to curl's PASV command when curl connects the  data\n"
+, stdout);
+ fputs(
+"              connection.  Instead  curl  will  re-use  the same IP address it\n"
+"              already uses for the control connection.\n"
+"\n"
+"              This option has no effect if PORT, EPRT or EPSV is used  instead\n"
+"              of PASV.\n"
+"\n"
+"              See also --ftp-pasv. Added in 7.14.2.\n"
+"\n"
+"       --ftp-ssl-ccc-mode <active/passive>\n"
+"              (FTP)  Sets the CCC mode. The passive mode will not initiate the\n"
+"              shutdown, but instead wait for the server to do it, and will not\n"
+, stdout);
+ fputs(
+"              reply to the shutdown from the server. The active mode initiates\n"
+"              the shutdown and waits for a reply from the server.\n"
+"\n"
+"              See also --ftp-ssl-ccc. Added in 7.16.2.\n"
+"\n"
+"       --ftp-ssl-ccc\n"
+"              (FTP) Use CCC (Clear Command Channel)  Shuts  down  the  SSL/TLS\n"
+"              layer after authenticating. The rest of the control channel com-\n"
+"              munication will be unencrypted. This allows NAT routers to  fol-\n"
+, stdout);
+ fputs(
+"              low the FTP transaction. The default mode is passive.\n"
+"\n"
+"              See also --ssl and --ftp-ssl-ccc-mode. Added in 7.16.1.\n"
+"\n"
+"       --ftp-ssl-control\n"
+"              (FTP)  Require  SSL/TLS  for  the FTP login, clear for transfer.\n"
+"              Allows secure authentication, but non-encrypted  data  transfers\n"
+"              for  efficiency.   Fails the transfer if the server doesn't sup-\n"
+"              port SSL/TLS.\n"
+"\n"
+"              Added in 7.16.0.\n"
+"\n"
+"       -G, --get\n"
+, stdout);
+ fputs(
+"              When used, this option will make all  data  specified  with  -d,\n"
+"              --data,  --data-binary or --data-urlencode to be used in an HTTP\n"
+"              GET request instead of the POST request that otherwise would  be\n"
+"              used. The data will be appended to the URL with a '?' separator.\n"
+"              If  used  in  combination  with  -I,  --head, the POST data will\n"
+"              instead be appended to the URL with a HEAD request.\n"
+"\n"
+, stdout);
+ fputs(
+"              If this option is used several times,  only  the  first  one  is\n"
+"              used.  This is because undoing a GET doesn't make sense, but you\n"
+"              should then instead enforce the alternative method you prefer.\n"
+"\n"
+"       -g, --globoff\n"
+"              This option switches off the \"URL globbing parser\". When you set\n"
+"              this  option, you can specify URLs that contain the letters {}[]\n"
+"              without having them being interpreted by curl itself. Note  that\n"
+, stdout);
+ fputs(
+"              these  letters are not normal legal URL contents but they should\n"
+"              be encoded according to the URI standard.\n"
+"\n"
+"       -I, --head\n"
+"              (HTTP FTP FILE) Fetch the headers only! HTTP-servers feature the\n"
+"              command  HEAD which this uses to get nothing but the header of a\n"
+"              document. When used on an FTP or FILE file,  curl  displays  the\n"
+"              file size and last modification time only.\n"
+"\n"
+"       -H, --header <header/@file>\n"
+, stdout);
+ fputs(
+"              (HTTP)  Extra header to include in the request when sending HTTP\n"
+"              to a server. You may specify any number of extra  headers.  Note\n"
+"              that if you should add a custom header that has the same name as\n"
+"              one of the internal ones curl would  use,  your  externally  set\n"
+"              header will be used instead of the internal one. This allows you\n"
+"              to make even trickier stuff than curl  would  normally  do.  You\n"
+, stdout);
+ fputs(
+"              should  not  replace internally set headers without knowing per-\n"
+"              fectly well what you're doing. Remove an internal header by giv-\n"
+"              ing  a  replacement  without  content  on  the right side of the\n"
+"              colon, as in: -H \"Host:\". If you send the custom header with no-\n"
+"              value  then its header must be terminated with a semicolon, such\n"
+"              as -H \"X-Custom-Header;\" to send \"X-Custom-Header:\".\n"
+"\n"
+, stdout);
+ fputs(
+"              curl will make sure that each header  you  add/replace  is  sent\n"
+"              with the proper end-of-line marker, you should thus not add that\n"
+"              as a part of the header content: do not add newlines or carriage\n"
+"              returns, they will only mess things up for you.\n"
+"\n"
+"              Starting  in  7.55.0, this option can take an argument in @file-\n"
+"              name style, which then adds a header for each line in the  input\n"
+, stdout);
+ fputs(
+"              file. Using @- will make curl read the header file from stdin.\n"
+"\n"
+"              See also the -A, --user-agent and -e, --referer options.\n"
+"\n"
+"              Starting in 7.37.0, you need --proxy-header to send custom head-\n"
+"              ers intended for a proxy.\n"
+"\n"
+"              Example:\n"
+"\n"
+"               curl -H \"X-First-Name: Joe\" http://example.com/\n"
+"\n"
+"              WARNING: headers set  with  this  option  will  be  set  in  all\n"
+, stdout);
+ fputs(
+"              requests  -  even  after  redirects are followed, like when told\n"
+"              with -L, --location. This can lead to the header being  sent  to\n"
+"              other  hosts than the original host, so sensitive headers should\n"
+"              be used with caution combined with following redirects.\n"
+"\n"
+"              This option can be used  multiple  times  to  add/replace/remove\n"
+"              multiple headers.\n"
+"\n"
+"       -h, --help\n"
+, stdout);
+ fputs(
+"              Usage  help.  This lists all current command line options with a\n"
+"              short description.\n"
+"       --hostpubmd5 <md5>\n"
+"              (SFTP SCP) Pass a string containing 32 hexadecimal  digits.  The\n"
+"              string  should  be the 128 bit MD5 checksum of the remote host's\n"
+"              public key, curl will refuse the connection with the host unless\n"
+"              the md5sums match.\n"
+"\n"
+"              Added in 7.17.1.\n"
+"\n"
+"       -0, --http1.0\n"
+, stdout);
+ fputs(
+"              (HTTP)  Tells  curl to use HTTP version 1.0 instead of using its\n"
+"              internally preferred HTTP version.\n"
+"\n"
+"              This option overrides --http1.1 and --http2.\n"
+"\n"
+"       --http1.1\n"
+"              (HTTP) Tells curl to use HTTP version 1.1.\n"
+"\n"
+"              This option  overrides  -0,  --http1.0  and  --http2.  Added  in\n"
+"              7.33.0.\n"
+"\n"
+"       --http2-prior-knowledge\n"
+"              (HTTP)  Tells  curl  to  issue  its  non-TLS HTTP requests using\n"
+, stdout);
+ fputs(
+"              HTTP/2 without HTTP/1.1 Upgrade.  It  requires  prior  knowledge\n"
+"              that  the  server  supports HTTP/2 straight away. HTTPS requests\n"
+"              will still do HTTP/2 the standard way with  negotiated  protocol\n"
+"              version in the TLS handshake.\n"
+"\n"
+"              --http2-prior-knowledge requires that the underlying libcurl was\n"
+"              built to support HTTP/2. This option overrides --http1.1 and -0,\n"
+"              --http1.0 and --http2. Added in 7.49.0.\n"
+"\n"
+, stdout);
+ fputs(
+"       --http2\n"
+"              (HTTP) Tells curl to use HTTP version 2.\n"
+"\n"
+"              See also --no-alpn. --http2 requires that the underlying libcurl\n"
+"              was built to support HTTP/2. This option overrides --http1.1 and\n"
+"              -0, --http1.0 and --http2-prior-knowledge. Added in 7.33.0.\n"
+"\n"
+"       --ignore-content-length\n"
+"              (FTP  HTTP)  For HTTP, Ignore the Content-Length header. This is\n"
+"              particularly useful for servers running Apache 1.x,  which  will\n"
+, stdout);
+ fputs(
+"              report  incorrect  Content-Length  for files larger than 2 giga-\n"
+"              bytes.\n"
+"\n"
+"              For FTP (since 7.46.0), skip the RETR command to figure out  the\n"
+"              size before downloading a file.\n"
+"\n"
+"       -i, --include\n"
+"              Include  the  HTTP  response  headers  in  the  output. The HTTP\n"
+"              response headers can include things like server  name,  cookies,\n"
+"              date of the document, HTTP version and more...\n"
+"\n"
+, stdout);
+ fputs(
+"              To view the request headers, consider the -v, --verbose option.\n"
+"\n"
+"              See also -v, --verbose.\n"
+"\n"
+"       -k, --insecure\n"
+"              (TLS) By default, every SSL connection curl makes is verified to\n"
+"              be secure. This option allows curl to proceed and  operate  even\n"
+"              for server connections otherwise considered insecure.\n"
+"\n"
+"              The  server  connection  is verified by making sure the server's\n"
+, stdout);
+ fputs(
+"              certificate contains the right name  and  verifies  successfully\n"
+"              using the cert store.\n"
+"\n"
+"              See this online resource for further details:\n"
+"               https://curl.haxx.se/docs/sslcerts.html\n"
+"              See also --proxy-insecure and --cacert.\n"
+"\n"
+"       --interface <name>\n"
+"\n"
+"              Perform  an operation using a specified interface. You can enter\n"
+"              interface name, IP address or host name. An example  could  look\n"
+"              like:\n"
+"\n"
+, stdout);
+ fputs(
+"               curl --interface eth0:1 https://www.example.com/\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"              On  Linux  it can be used to specify a VRF, but the binary needs\n"
+"              to either have CAP_NET_RAW or to be ran as root.  More  informa-\n"
+"              tion   about  Linux  VRF:  https://www.kernel.org/doc/Documenta-\n"
+"              tion/networking/vrf.txt\n"
+"\n"
+"              See also --dns-interface.\n"
+"\n"
+"       -4, --ipv4\n"
+, stdout);
+ fputs(
+"              This option tells curl to resolve names to IPv4 addresses  only,\n"
+"              and not for example try IPv6.\n"
+"\n"
+"              See  also  --http1.1  and  --http2.  This  option  overrides -6,\n"
+"              --ipv6.\n"
+"\n"
+"       -6, --ipv6\n"
+"              This option tells curl to resolve names to IPv6 addresses  only,\n"
+"              and not for example try IPv4.\n"
+"\n"
+"              See  also  --http1.1  and  --http2.  This  option  overrides -6,\n"
+"              --ipv6.\n"
+"\n"
+, stdout);
+ fputs(
+"       -j, --junk-session-cookies\n"
+"              (HTTP) When curl is told to read cookies from a given file, this\n"
+"              option  will  make  it  discard all \"session cookies\". This will\n"
+"              basically have the same effect as if a new session  is  started.\n"
+"              Typical  browsers  always  discard  session cookies when they're\n"
+"              closed down.\n"
+"\n"
+"              See also -b, --cookie and -c, --cookie-jar.\n"
+"\n"
+"       --keepalive-time <seconds>\n"
+, stdout);
+ fputs(
+"              This option sets the time a  connection  needs  to  remain  idle\n"
+"              before  sending keepalive probes and the time between individual\n"
+"              keepalive probes. It is currently effective on operating systems\n"
+"              offering  the  TCP_KEEPIDLE  and  TCP_KEEPINTVL  socket  options\n"
+"              (meaning Linux, recent AIX, HP-UX and more). This option has  no\n"
+"              effect if --no-keepalive is used.\n"
+"\n"
+, stdout);
+ fputs(
+"              If this option is used several times, the last one will be used.\n"
+"              If unspecified, the option defaults to 60 seconds.\n"
+"\n"
+"              Added in 7.18.0.\n"
+"\n"
+"       --key-type <type>\n"
+"              (TLS) Private key file type. Specify which type your --key  pro-\n"
+"              vided  private  key  is. DER, PEM, and ENG are supported. If not\n"
+"              specified, PEM is assumed.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+, stdout);
+ fputs(
+"       --key <key>\n"
+"              (TLS SSH) Private key file name. Allows you to provide your pri-\n"
+"              vate  key in this separate file. For SSH, if not specified, curl\n"
+"              tries the following candidates in order:\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"       --krb <level>\n"
+"              (FTP) Enable Kerberos authentication and use. The level must  be\n"
+"              entered and should be one of 'clear', 'safe', 'confidential', or\n"
+, stdout);
+ fputs(
+"              'private'. Should you use a level that  is  not  one  of  these,\n"
+"              'private' will instead be used.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"              --krb  requires that the underlying libcurl was built to support\n"
+"              Kerberos.\n"
+"\n"
+"       --libcurl <file>\n"
+"              Append this option to any ordinary curl command  line,  and  you\n"
+"              will  get a libcurl-using C source code written to the file that\n"
+, stdout);
+ fputs(
+"              does the equivalent of what your command-line operation does!\n"
+"\n"
+"              If this option is used several times, the last given  file  name\n"
+"              will be used.\n"
+"\n"
+"              Added in 7.16.1.\n"
+"\n"
+"       --limit-rate <speed>\n"
+"              Specify  the  maximum  transfer  rate you want curl to use - for\n"
+"              both downloads and uploads. This feature is useful if you have a\n"
+"              limited pipe and you'd like your transfer not to use your entire\n"
+, stdout);
+ fputs(
+"              bandwidth. To make it slower than it otherwise would be.\n"
+"\n"
+"              The given speed is measured in bytes/second, unless a suffix  is\n"
+"              appended.   Appending  'k' or 'K' will count the number as kilo-\n"
+"              bytes, 'm' or M' makes it megabytes, while 'g' or 'G'  makes  it\n"
+"              gigabytes. Examples: 200K, 3m and 1G.\n"
+"\n"
+"              If  you  also use the -Y, --speed-limit option, that option will\n"
+, stdout);
+ fputs(
+"              take precedence and might cripple the rate-limiting slightly, to\n"
+"              help keeping the speed-limit logic working.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"       -l, --list-only\n"
+"              (FTP  POP3)  (FTP)  When  listing  an FTP directory, this switch\n"
+"              forces a name-only view. This is especially useful if  the  user\n"
+"              wants  to  machine-parse  the contents of an FTP directory since\n"
+, stdout);
+ fputs(
+"              the normal directory view doesn't use a standard look or format.\n"
+"              When used like this, the option causes a NLST command to be sent\n"
+"              to the server instead of LIST.\n"
+"\n"
+"              Note: Some FTP servers list only  files  in  their  response  to\n"
+"              NLST; they do not include sub-directories and symbolic links.\n"
+"\n"
+"              (POP3)  When  retrieving a specific email from POP3, this switch\n"
+, stdout);
+ fputs(
+"              forces a LIST command to be performed instead of RETR.  This  is\n"
+"              particularly  useful if the user wants to see if a specific mes-\n"
+"              sage id exists on the server and what size it is.\n"
+"\n"
+"              Note: When combined with -X, --request, this option can be  used\n"
+"              to send an UIDL command instead, so the user may use the email's\n"
+"              unique identifier rather  than  it's  message  id  to  make  the\n"
+"              request.\n"
+"\n"
+, stdout);
+ fputs(
+"              Added in 7.21.5.\n"
+"\n"
+"       --local-port <num/range>\n"
+"              Set  a  preferred single number or range (FROM-TO) of local port\n"
+"              numbers to use for the connection(s).  Note that port numbers by\n"
+"              nature  are a scarce resource that will be busy at times so set-\n"
+"              ting this range to something too narrow might cause  unnecessary\n"
+"              connection setup failures.\n"
+"\n"
+"              Added in 7.15.2.\n"
+"\n"
+"       --location-trusted\n"
+, stdout);
+ fputs(
+"              (HTTP)  Like  -L,  --location, but will allow sending the name +\n"
+"              password to all hosts that the site may redirect to. This may or\n"
+"              may not introduce a security breach if the site redirects you to\n"
+"              a site to which you'll send your authentication info  (which  is\n"
+"              plaintext in the case of HTTP Basic authentication).\n"
+"\n"
+"              See also -u, --user.\n"
+"\n"
+"       -L, --location\n"
+, stdout);
+ fputs(
+"              (HTTP)  If  the server reports that the requested page has moved\n"
+"              to a different location (indicated with a Location: header and a\n"
+"              3XX  response code), this option will make curl redo the request\n"
+"              on the new place. If used together with  -i,  --include  or  -I,\n"
+"              --head,  headers  from  all  requested pages will be shown. When\n"
+"              authentication is used, curl only sends its credentials  to  the\n"
+, stdout);
+ fputs(
+"              initial  host.  If a redirect takes curl to a different host, it\n"
+"              won't be able to intercept the user+password. See  also  --loca-\n"
+"              tion-trusted  on how to change this. You can limit the amount of\n"
+"              redirects to follow by using the --max-redirs option.\n"
+"\n"
+"              When curl follows a redirect and the request is not a plain  GET\n"
+"              (for example POST or PUT), it will do the following request with\n"
+, stdout);
+ fputs(
+"              a GET if the HTTP response was 301, 302, or 303. If the response\n"
+"              code  was  any  other  3xx code, curl will re-send the following\n"
+"              request using the same unmodified method.\n"
+"\n"
+"              You can tell curl to not change the non-GET  request  method  to\n"
+"              GET  after  a  30x  response  by using the dedicated options for\n"
+"              that: --post301, --post302 and --post303.\n"
+"\n"
+"       --login-options <options>\n"
+, stdout);
+ fputs(
+"              (IMAP POP3 SMTP) Specify the login options to use during  server\n"
+"              authentication.\n"
+"\n"
+"              You  can  use  the  login  options  to specify protocol specific\n"
+"              options that may be used during authentication. At present  only\n"
+"              IMAP,  POP3 and SMTP support login options. For more information\n"
+"              about the login options please see RFC 2384, RFC 5092  and  IETF\n"
+"              draft draft-earhart-url-smtp-00.txt\n"
+"\n"
+, stdout);
+ fputs(
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"              Added in 7.34.0.\n"
+"\n"
+"       --mail-auth <address>\n"
+"              (SMTP)  Specify  a  single address. This will be used to specify\n"
+"              the authentication address (identity)  of  a  submitted  message\n"
+"              that is being relayed to another server.\n"
+"\n"
+"              See also --mail-rcpt and --mail-from. Added in 7.25.0.\n"
+"\n"
+"       --mail-from <address>\n"
+, stdout);
+ fputs(
+"              (SMTP)  Specify  a single address that the given mail should get\n"
+"              sent from.\n"
+"\n"
+"              See also --mail-rcpt and --mail-auth. Added in 7.20.0.\n"
+"\n"
+"       --mail-rcpt <address>\n"
+"              (SMTP) Specify a single address, user name or mailing list name.\n"
+"              Repeat this option several times to send to multiple recipients.\n"
+"              When  performing a mail transfer, the recipient should specify a\n"
+"              valid email address to send the mail to.\n"
+"\n"
+, stdout);
+ fputs(
+"              When performing an  address  verification  (VRFY  command),  the\n"
+"              recipient  should be specified as the user name or user name and\n"
+"              domain (as per Section 3.5 of RFC5321). (Added in 7.34.0)\n"
+"\n"
+"              When performing a mailing list expand (EXPN command), the recip-\n"
+"              ient  should  be  specified using the mailing list name, such as\n"
+"              \"Friends\" or \"London-Office\".  (Added in 7.34.0)\n"
+"\n"
+"              Added in 7.20.0.\n"
+"\n"
+, stdout);
+ fputs(
+"       -M, --manual\n"
+"              Manual. Display the huge help text.\n"
+"\n"
+"       --max-filesize <bytes>\n"
+"              Specify the maximum size (in bytes) of a file  to  download.  If\n"
+"              the  file requested is larger than this value, the transfer will\n"
+"              not start and curl will return with exit code 63.\n"
+"\n"
+"              NOTE: The file size is not always known prior to  download,  and\n"
+"              for such files this option has no effect even if the file trans-\n"
+, stdout);
+ fputs(
+"              fer ends up being larger than this given  limit.  This  concerns\n"
+"              both FTP and HTTP transfers.\n"
+"\n"
+"              See also --limit-rate.\n"
+"\n"
+"       --max-redirs <num>\n"
+"              (HTTP)  Set  maximum  number  of redirection-followings allowed.\n"
+"              When -L, --location is used, is used to prevent curl  from  fol-\n"
+"              lowing  redirections \"in absurdum\". By default, the limit is set\n"
+, stdout);
+ fputs(
+"              to 50 redirections. Set this option to -1 to make it unlimited.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"       -m, --max-time <time>\n"
+"              Maximum time in seconds that you allow the  whole  operation  to\n"
+"              take.   This is useful for preventing your batch jobs from hang-\n"
+"              ing for hours due to slow networks or links going  down.   Since\n"
+, stdout);
+ fputs(
+"              7.32.0, this option accepts decimal values, but the actual time-\n"
+"              out will decrease in accuracy as the specified timeout increases\n"
+"              in decimal precision.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"              See also --connect-timeout.\n"
+"\n"
+"       --metalink\n"
+"              This  option  can  tell curl to parse and process a given URI as\n"
+"              Metalink file (both version 3 and 4 (RFC  5854)  are  supported)\n"
+, stdout);
+ fputs(
+"              and  make use of the mirrors listed within for failover if there\n"
+"              are errors (such as the file or server not being available).  It\n"
+"              will  also  verify  the hash of the file after the download com-\n"
+"              pletes. The Metalink file itself is downloaded and processed  in\n"
+"              memory and not stored in the local file system.\n"
+"\n"
+"              Example to use a remote Metalink file:\n"
+"\n"
+, stdout);
+ fputs(
+"               curl --metalink http://www.example.com/example.metalink\n"
+"\n"
+"              To use a Metalink file in the local file system, use FILE proto-\n"
+"              col (file://):\n"
+"\n"
+"               curl --metalink file://example.metalink\n"
+"\n"
+"              Please note that if FILE protocol is disabled, there is  no  way\n"
+"              to  use  a local Metalink file at the time of this writing. Also\n"
+"              note that if --metalink and -i,  --include  are  used  together,\n"
+, stdout);
+ fputs(
+"              --include  will be ignored. This is because including headers in\n"
+"              the response will break Metalink parser and if the  headers  are\n"
+"              included in the file described in Metalink file, hash check will\n"
+"              fail.\n"
+"\n"
+"              --metalink requires that the underlying  libcurl  was  built  to\n"
+"              support metalink. Added in 7.27.0.\n"
+"\n"
+"       --negotiate\n"
+"              (HTTP) Enables Negotiate (SPNEGO) authentication.\n"
+"\n"
+, stdout);
+ fputs(
+"              This  option  requires a library built with GSS-API or SSPI sup-\n"
+"              port. Use -V, --version  to  see  if  your  curl  supports  GSS-\n"
+"              API/SSPI or SPNEGO.\n"
+"\n"
+"              When  using this option, you must also provide a fake -u, --user\n"
+"              option to activate the authentication code properly.  Sending  a\n"
+"              '-u  :'  is  enough  as  the user name and password from the -u,\n"
+"              --user option aren't actually used.\n"
+"\n"
+, stdout);
+ fputs(
+"              If this option is used several times,  only  the  first  one  is\n"
+"              used.\n"
+"\n"
+"              See also --basic and --ntlm and --anyauth and --proxy-negotiate.\n"
+"\n"
+"       --netrc-file <filename>\n"
+"              This  option  is similar to -n, --netrc, except that you provide\n"
+"              the path (absolute or relative) to  the  netrc  file  that  Curl\n"
+"              should use.  You can only specify one netrc file per invocation.\n"
+, stdout);
+ fputs(
+"              If several --netrc-file options are provided, the last one  will\n"
+"              be used.\n"
+"\n"
+"              It will abide by --netrc-optional if specified.\n"
+"\n"
+"              This option overrides -n, --netrc. Added in 7.21.5.\n"
+"\n"
+"       --netrc-optional\n"
+"              Very  similar  to  -n, --netrc, but this option makes the .netrc\n"
+"              usage optional and not mandatory as the -n, --netrc option does.\n"
+"\n"
+"              See also --netrc-file. This option overrides -n, --netrc.\n"
+"\n"
+, stdout);
+ fputs(
+"       -n, --netrc\n"
+"              Makes curl scan the .netrc  (_netrc  on  Windows)  file  in  the\n"
+"              user's home directory for login name and password. This is typi-\n"
+"              cally used for FTP on Unix. If used with HTTP, curl will  enable\n"
+"              user authentication. See netrc(5) ftp(1) for details on the file\n"
+"              format. Curl will not complain if that  file  doesn't  have  the\n"
+"              right permissions (it should not be either world- or group-read-\n"
+, stdout);
+ fputs(
+"              able). The environment variable \"HOME\" is used to find the  home\n"
+"              directory.\n"
+"\n"
+"              A  quick  and  very  simple  example of how to setup a .netrc to\n"
+"              allow curl to FTP to the machine host.domain.com with user  name\n"
+"              'myself' and password 'secret' should look similar to:\n"
+"\n"
+"              machine host.domain.com login myself password secret\n"
+"\n"
+"       -:, --next\n"
+"              Tells curl to use a separate operation for the following URL and\n"
+, stdout);
+ fputs(
+"              associated  options.  This  allows  you  to  send  several   URL\n"
+"              requests,  each  with  their  own specific options, for example,\n"
+"              such as different user names or custom requests for each.\n"
+"\n"
+"              -:, --next will reset all local options  and  only  global  ones\n"
+"              will  have  their values survive over to the operation following\n"
+"              the -:, --next instruction. Global options  include  -v,  --ver-\n"
+, stdout);
+ fputs(
+"              bose, --trace, --trace-ascii and --fail-early.\n"
+"\n"
+"              For  example,  you can do both a GET and a POST in a single com-\n"
+"              mand line:\n"
+"\n"
+"               curl www1.example.com --next -d postthis www2.example.com\n"
+"\n"
+"              Added in 7.36.0.\n"
+"\n"
+"       --no-alpn\n"
+"              (HTTPS) Disable the ALPN  TLS  extension.  ALPN  is  enabled  by\n"
+"              default  if  libcurl was built with an SSL library that supports\n"
+, stdout);
+ fputs(
+"              ALPN. ALPN is used by a libcurl that supports HTTP/2 to  negoti-\n"
+"              ate HTTP/2 support with the server during https sessions.\n"
+"\n"
+"              See  also  --no-npn  and  --http2.  --no-alpn  requires that the\n"
+"              underlying libcurl was built to support TLS. Added in 7.36.0.\n"
+"\n"
+"       -N, --no-buffer\n"
+"              Disables the buffering of the output stream. In normal work sit-\n"
+"              uations,  curl  will  use a standard buffered output stream that\n"
+, stdout);
+ fputs(
+"              will have the effect that it will output the data in chunks, not\n"
+"              necessarily  exactly  when  the data arrives.  Using this option\n"
+"              will disable that buffering.\n"
+"\n"
+"              Note that this is the negated option name  documented.  You  can\n"
+"              thus use --buffer to enforce the buffering.\n"
+"\n"
+"       --no-keepalive\n"
+"              Disables  the  use  of keepalive messages on the TCP connection.\n"
+"              curl otherwise enables them by default.\n"
+"\n"
+, stdout);
+ fputs(
+"              Note that this is the negated option name  documented.  You  can\n"
+"              thus use --keepalive to enforce keepalive.\n"
+"\n"
+"       --no-npn\n"
+"              (HTTPS) Disable the NPN TLS extension. NPN is enabled by default\n"
+"              if libcurl was built with an SSL library that supports NPN.  NPN\n"
+"              is  used  by  a libcurl that supports HTTP/2 to negotiate HTTP/2\n"
+"              support with the server during https sessions.\n"
+"\n"
+, stdout);
+ fputs(
+"              See also --no-alpn  and  --http2.  --no-npn  requires  that  the\n"
+"              underlying libcurl was built to support TLS. Added in 7.36.0.\n"
+"\n"
+"       --no-sessionid\n"
+"              (TLS)  Disable curl's use of SSL session-ID caching.  By default\n"
+"              all transfers are done using the cache. Note that while  nothing\n"
+"              should  ever  get  hurt  by attempting to reuse SSL session-IDs,\n"
+"              there seem to be broken SSL implementations in the wild that may\n"
+, stdout);
+ fputs(
+"              require you to disable this in order for you to succeed.\n"
+"\n"
+"              Note  that  this  is the negated option name documented. You can\n"
+"              thus use --sessionid to enforce session-ID caching.\n"
+"\n"
+"              Added in 7.16.0.\n"
+"\n"
+"       --noproxy <no-proxy-list>\n"
+"              Comma-separated list of hosts which do not use a proxy,  if  one\n"
+"              is  specified.  The only wildcard is a single * character, which\n"
+, stdout);
+ fputs(
+"              matches all hosts, and effectively disables the proxy. Each name\n"
+"              in  this  list  is matched as either a domain which contains the\n"
+"              hostname, or the hostname itself. For example,  local.com  would\n"
+"              match   local.com,  local.com:80,  and  www.local.com,  but  not\n"
+"              www.notlocal.com.\n"
+"\n"
+"              Since 7.53.0, This option overrides  the  environment  variables\n"
+, stdout);
+ fputs(
+"              that  disable the proxy. If there's an environment variable dis-\n"
+"              abling a proxy, you can set noproxy list to \"\" to override it.\n"
+"\n"
+"              Added in 7.19.4.\n"
+"\n"
+"       --ntlm-wb\n"
+"              (HTTP) Enables NTLM much in the style --ntlm does, but hand over\n"
+"              the  authentication  to the separate binary ntlmauth application\n"
+"              that is executed when needed.\n"
+"\n"
+"              See also --ntlm and --proxy-ntlm.\n"
+"\n"
+, stdout);
+ fputs(
+"       --ntlm (HTTP) Enables  NTLM  authentication.  The  NTLM  authentication\n"
+"              method was designed by Microsoft and is used by IIS web servers.\n"
+"              It is a proprietary protocol, reverse-engineered by clever  peo-\n"
+"              ple and implemented in curl based on their efforts. This kind of\n"
+"              behavior should not be endorsed, you should  encourage  everyone\n"
+"              who  uses  NTLM to switch to a public and documented authentica-\n"
+, stdout);
+ fputs(
+"              tion method instead, such as Digest.\n"
+"\n"
+"              If you want to enable NTLM for your proxy  authentication,  then\n"
+"              use --proxy-ntlm.\n"
+"\n"
+"              If  this  option  is  used  several times, only the first one is\n"
+"              used.\n"
+"\n"
+"              See also  --proxy-ntlm.  --ntlm  requires  that  the  underlying\n"
+"              libcurl  was built to support TLS. This option overrides --basic\n"
+"              and --negotiated and --digest and --anyauth.\n"
+"\n"
+, stdout);
+ fputs(
+"       --oauth2-bearer <token>\n"
+"              (IMAP POP3 SMTP) Specify the Bearer Token for OAUTH  2.0  server\n"
+"              authentication. The Bearer Token is used in conjunction with the\n"
+"              user name which can be specified as part of  the  --url  or  -u,\n"
+"              --user options.\n"
+"\n"
+"              The  Bearer  Token  and user name are formatted according to RFC\n"
+"              6750.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+, stdout);
+ fputs(
+"       -o, --output <file>\n"
+"              Write output to <file> instead of stdout. If you are using {} or\n"
+"              []  to  fetch  multiple documents, you can use '#' followed by a\n"
+"              number in the <file> specifier. That variable will  be  replaced\n"
+"              with the current string for the URL being fetched. Like in:\n"
+"\n"
+"               curl http://{one,two}.example.com -o \"file_#1.txt\"\n"
+"\n"
+"              or use several variables like:\n"
+"\n"
+, stdout);
+ fputs(
+"               curl http://{site,host}.host[1-5].com -o \"#1_#2\"\n"
+"\n"
+"              You  may use this option as many times as the number of URLs you\n"
+"              have. For example, if you specify two URLs on the  same  command\n"
+"              line, you can use it like this:\n"
+"\n"
+"                curl -o aa example.com -o bb example.net\n"
+"\n"
+"              and  the  order  of  the -o options and the URLs doesn't matter,\n"
+"              just that the first -o is for the first URL and so  on,  so  the\n"
+, stdout);
+ fputs(
+"              above command line can also be written as\n"
+"\n"
+"                curl example.com example.net -o aa -o bb\n"
+"\n"
+"              See  also  the --create-dirs option to create the local directo-\n"
+"              ries dynamically. Specifying the output as '-' (a  single  dash)\n"
+"              will force the output to be done to stdout.\n"
+"\n"
+"              See   also  -O,  --remote-name  and  --remote-name-all  and  -J,\n"
+"              --remote-header-name.\n"
+"\n"
+"       --pass <phrase>\n"
+, stdout);
+ fputs(
+"              (SSH TLS) Passphrase for the private key\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"       --path-as-is\n"
+"              Tell curl to not handle sequences of /../ or /./  in  the  given\n"
+"              URL  path.  Normally curl will squash or merge them according to\n"
+"              standards but with this option set you tell it not to do that.\n"
+"\n"
+"              Added in 7.42.0.\n"
+"\n"
+"       --pinnedpubkey <hashes>\n"
+, stdout);
+ fputs(
+"              (TLS) Tells curl to  use  the  specified  public  key  file  (or\n"
+"              hashes)  to  verify the peer. This can be a path to a file which\n"
+"              contains a single public key in PEM or DER format, or any number\n"
+"              of base64 encoded sha256 hashes preceded by 'sha256//' and sepa-\n"
+"              rated by ';'\n"
+"\n"
+"              When negotiating a TLS or SSL connection,  the  server  sends  a\n"
+, stdout);
+ fputs(
+"              certificate  indicating  its identity. A public key is extracted\n"
+"              from this certificate and if it does not exactly match the  pub-\n"
+"              lic  key provided to this option, curl will abort the connection\n"
+"              before sending or receiving any data.\n"
+"\n"
+"              PEM/DER support:\n"
+"                7.39.0: OpenSSL, GnuTLS and GSKit\n"
+"                7.43.0: NSS and wolfSSL/CyaSSL\n"
+"                7.47.0: mbedtls\n"
+"                7.49.0: PolarSSL sha256 support:\n"
+, stdout);
+ fputs(
+"                7.44.0: OpenSSL, GnuTLS, NSS and wolfSSL/CyaSSL.\n"
+"                7.47.0: mbedtls\n"
+"                7.49.0: PolarSSL Other SSL backends not supported.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"       --post301\n"
+"              (HTTP) Tells curl to respect RFC 7231/6.4.2 and not convert POST\n"
+"              requests into GET requests when following a 301 redirection. The\n"
+"              non-RFC behaviour is ubiquitous in web browsers,  so  curl  does\n"
+, stdout);
+ fputs(
+"              the  conversion  by  default to maintain consistency. However, a\n"
+"              server may require a POST to remain a POST after  such  a  redi-\n"
+"              rection.  This  option is meaningful only when using -L, --loca-\n"
+"              tion.\n"
+"\n"
+"              See also --post302 and --post303 and -L,  --location.  Added  in\n"
+"              7.17.1.\n"
+"\n"
+"       --post302\n"
+"              (HTTP) Tells curl to respect RFC 7231/6.4.3 and not convert POST\n"
+, stdout);
+ fputs(
+"              requests into GET requests when following a 302 redirection. The\n"
+"              non-RFC  behaviour  is  ubiquitous in web browsers, so curl does\n"
+"              the conversion by default to maintain  consistency.  However,  a\n"
+"              server  may  require  a POST to remain a POST after such a redi-\n"
+"              rection. This option is meaningful only when using  -L,  --loca-\n"
+"              tion.\n"
+"\n"
+"              See  also  --post301  and --post303 and -L, --location. Added in\n"
+, stdout);
+ fputs(
+"              7.19.1.\n"
+"\n"
+"       --post303\n"
+"              (HTTP) Tells curl to respect RFC 7231/6.4.4 and not convert POST\n"
+"              requests into GET requests when following a 303 redirection. The\n"
+"              non-RFC behaviour is ubiquitous in web browsers,  so  curl  does\n"
+"              the  conversion  by  default to maintain consistency. However, a\n"
+"              server may require a POST to remain a POST after  such  a  redi-\n"
+, stdout);
+ fputs(
+"              rection.  This  option is meaningful only when using -L, --loca-\n"
+"              tion.\n"
+"\n"
+"              See also --post302 and --post301 and -L,  --location.  Added  in\n"
+"              7.26.0.\n"
+"\n"
+"       --preproxy [protocol://]host[:port]\n"
+"              Use  the  specified  SOCKS proxy before connecting to an HTTP or\n"
+"              HTTPS -x, --proxy. In such a case curl  first  connects  to  the\n"
+"              SOCKS  proxy  and  then  connects (through SOCKS) to the HTTP or\n"
+, stdout);
+ fputs(
+"              HTTPS proxy. Hence pre proxy.\n"
+"\n"
+"              The pre proxy string should be specified with a protocol:// pre-\n"
+"              fix  to  specify  alternative  proxy  protocols.  Use socks4://,\n"
+"              socks4a://, socks5:// or  socks5h://  to  request  the  specific\n"
+"              SOCKS  version  to be used. No protocol specified will make curl\n"
+"              default to SOCKS4.\n"
+"\n"
+"              If the port number is not specified in the proxy string,  it  is\n"
+, stdout);
+ fputs(
+"              assumed to be 1080.\n"
+"\n"
+"              User and password that might be provided in the proxy string are\n"
+"              URL decoded by curl. This allows you to pass in special  charac-\n"
+"              ters such as @ by using %40 or pass in a colon with %3a.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"              Added in 7.52.0.\n"
+"\n"
+"       -#, --progress-bar\n"
+"              Make  curl  display  transfer  progress as a simple progress bar\n"
+, stdout);
+ fputs(
+"              instead of the standard, more informational, meter.\n"
+"\n"
+"              This progress bar draws a single line of '#'  characters  across\n"
+"              the screen and shows a percentage if the transfer size is known.\n"
+"              For transfers without a known size, it will instead  output  one\n"
+"              '#' character for every 1024 bytes transferred.\n"
+"\n"
+"       --proto-default <protocol>\n"
+"              Tells curl to use protocol for any URL missing a scheme name.\n"
+"\n"
+, stdout);
+ fputs(
+"              Example:\n"
+"\n"
+"               curl --proto-default https ftp.mozilla.org\n"
+"\n"
+"              An  unknown  or  unsupported  protocol causes error CURLE_UNSUP-\n"
+"              PORTED_PROTOCOL (1).\n"
+"\n"
+"              This option does not change the default proxy protocol (http).\n"
+"\n"
+"              Without this option curl would make a guess based on  the  host,\n"
+"              see --url for details.\n"
+"\n"
+"              Added in 7.45.0.\n"
+"\n"
+"       --proto-redir <protocols>\n"
+, stdout);
+ fputs(
+"              Tells  curl to limit what protocols it may use on redirect. Pro-\n"
+"              tocols denied by --proto are not overridden by this option.  See\n"
+"              --proto for how protocols are represented.\n"
+"\n"
+"              Example, allow only HTTP and HTTPS on redirect:\n"
+"\n"
+"               curl --proto-redir -all,http,https http://example.com\n"
+"\n"
+"              By default curl will allow all protocols on redirect except sev-\n"
+, stdout);
+ fputs(
+"              eral disabled for security reasons: Since 7.19.4  FILE  and  SCP\n"
+"              are  disabled,  and since 7.40.0 SMB and SMBS are also disabled.\n"
+"              Specifying all  or  +all  enables  all  protocols  on  redirect,\n"
+"              including those disabled for security.\n"
+"\n"
+"              Added in 7.20.2.\n"
+"\n"
+"       --proto <protocols>\n"
+"              Tells  curl  to limit what protocols it may use in the transfer.\n"
+, stdout);
+ fputs(
+"              Protocols are evaluated left to right, are comma separated,  and\n"
+"              are each a protocol name or\n"
+"\n"
+"              +  Permit this protocol in addition to protocols already permit-\n"
+"                 ted (this is the default if no modifier is used).\n"
+"\n"
+"              -  Deny this protocol, removing it from the  list  of  protocols\n"
+"                 already permitted.\n"
+"\n"
+"              =  Permit  only this protocol (ignoring the list already permit-\n"
+, stdout);
+ fputs(
+"                 ted), though subject  to  later  modification  by  subsequent\n"
+"                 entries in the comma separated list.\n"
+"\n"
+"              For example:\n"
+"\n"
+"              --proto -ftps  uses the default protocols, but disables ftps\n"
+"\n"
+"              --proto -all,https,+http\n"
+"                             only enables http and https\n"
+"\n"
+"              --proto =http,https\n"
+"                             also only enables http and https\n"
+"\n"
+, stdout);
+ fputs(
+"       Unknown protocols produce a warning. This allows scripts to safely rely\n"
+"       on being able to disable potentially dangerous protocols, without rely-\n"
+"       ing  upon  support  for that protocol being built into curl to avoid an\n"
+"       error.\n"
+"\n"
+"       This option can be used multiple times, in which case the effect is the\n"
+"       same as concatenating the protocols into one instance of the option.\n"
+"\n"
+"       See also --proto-redir and --proto-default. Added in 7.20.2.\n"
+"\n"
+"       --proxy-anyauth\n"
+, stdout);
+ fputs(
+"              Tells  curl to pick a suitable authentication method when commu-\n"
+"              nicating with the given HTTP proxy. This might  cause  an  extra\n"
+"              request/response round-trip.\n"
+"\n"
+"              See also -x, --proxy and --proxy-basic and --proxy-digest. Added\n"
+"              in 7.13.2.\n"
+"\n"
+"       --proxy-basic\n"
+"              Tells curl to use HTTP Basic authentication  when  communicating\n"
+"              with the given proxy. Use --basic for enabling HTTP Basic with a\n"
+, stdout);
+ fputs(
+"              remote host. Basic is the  default  authentication  method  curl\n"
+"              uses with proxies.\n"
+"\n"
+"              See also -x, --proxy and --proxy-anyauth and --proxy-digest.\n"
+"\n"
+"       --proxy-cacert <file>\n"
+"              Same as --cacert but used in HTTPS proxy context.\n"
+"\n"
+"              See  also  --proxy-capath  and  --cacert  and  --capath  and -x,\n"
+"              --proxy. Added in 7.52.0.\n"
+"\n"
+"       --proxy-capath <dir>\n"
+"              Same as --capath but used in HTTPS proxy context.\n"
+"\n"
+, stdout);
+ fputs(
+"              See also --proxy-cacert and -x, --proxy and --capath.  Added  in\n"
+"              7.52.0.\n"
+"\n"
+"       --proxy-cert-type <type>\n"
+"              Same as --cert-type but used in HTTPS proxy context.\n"
+"\n"
+"              Added in 7.52.0.\n"
+"\n"
+"       --proxy-cert <cert[:passwd]>\n"
+"              Same as -E, --cert but used in HTTPS proxy context.\n"
+"\n"
+"              Added in 7.52.0.\n"
+"\n"
+"       --proxy-ciphers <list>\n"
+"              Same as --ciphers but used in HTTPS proxy context.\n"
+"\n"
+"              Added in 7.52.0.\n"
+"\n"
+, stdout);
+ fputs(
+"       --proxy-crlfile <file>\n"
+"              Same as --crlfile but used in HTTPS proxy context.\n"
+"\n"
+"              Added in 7.52.0.\n"
+"\n"
+"       --proxy-digest\n"
+"              Tells  curl to use HTTP Digest authentication when communicating\n"
+"              with the given proxy. Use --digest for enabling HTTP Digest with\n"
+"              a remote host.\n"
+"\n"
+"              See also -x, --proxy and --proxy-anyauth and --proxy-basic.\n"
+"\n"
+"       --proxy-header <header/@file>\n"
+, stdout);
+ fputs(
+"              (HTTP)  Extra header to include in the request when sending HTTP\n"
+"              to a proxy. You may specify any number of extra headers. This is\n"
+"              the  equivalent option to -H, --header but is for proxy communi-\n"
+"              cation only like in CONNECT requests when you  want  a  separate\n"
+"              header  sent  to  the proxy to what is sent to the actual remote\n"
+"              host.\n"
+"\n"
+"              curl will make sure that each header  you  add/replace  is  sent\n"
+, stdout);
+ fputs(
+"              with the proper end-of-line marker, you should thus not add that\n"
+"              as a part of the header content: do not add newlines or carriage\n"
+"              returns, they will only mess things up for you.\n"
+"\n"
+"              Headers  specified  with  this  option  will  not be included in\n"
+"              requests that curl knows will not be sent to a proxy.\n"
+"\n"
+"              Starting in 7.55.0, this option can take an argument  in  @file-\n"
+, stdout);
+ fputs(
+"              name  style, which then adds a header for each line in the input\n"
+"              file. Using @- will make curl read the header file from stdin.\n"
+"\n"
+"              This option can be used  multiple  times  to  add/replace/remove\n"
+"              multiple headers.\n"
+"\n"
+"              Added in 7.37.0.\n"
+"       --proxy-insecure\n"
+"              Same as -k, --insecure but used in HTTPS proxy context.\n"
+"\n"
+"              Added in 7.52.0.\n"
+"\n"
+"       --proxy-key-type <type>\n"
+, stdout);
+ fputs(
+"              Same as --key-type but used in HTTPS proxy context.\n"
+"\n"
+"              Added in 7.52.0.\n"
+"\n"
+"       --proxy-key <key>\n"
+"              Same as --key but used in HTTPS proxy context.\n"
+"\n"
+"       --proxy-negotiate\n"
+"              Tells  curl  to  use HTTP Negotiate (SPNEGO) authentication when\n"
+"              communicating with the given proxy. Use --negotiate for enabling\n"
+"              HTTP Negotiate (SPNEGO) with a remote host.\n"
+"\n"
+, stdout);
+ fputs(
+"              See also --proxy-anyauth and --proxy-basic. Added in 7.17.1.\n"
+"\n"
+"       --proxy-ntlm\n"
+"              Tells  curl  to  use HTTP NTLM authentication when communicating\n"
+"              with the given proxy. Use --ntlm for enabling NTLM with a remote\n"
+"              host.\n"
+"\n"
+"              See also --proxy-negotiate and --proxy-anyauth.\n"
+"\n"
+"       --proxy-pass <phrase>\n"
+"              Same as --pass but used in HTTPS proxy context.\n"
+"\n"
+"              Added in 7.52.0.\n"
+"\n"
+"       --proxy-service-name <name>\n"
+, stdout);
+ fputs(
+"              This  option  allows  you  to  change the service name for proxy\n"
+"              negotiation.\n"
+"\n"
+"              Added in 7.43.0.\n"
+"\n"
+"       --proxy-ssl-allow-beast\n"
+"              Same as --ssl-allow-beast but used in HTTPS proxy context.\n"
+"\n"
+"              Added in 7.52.0.\n"
+"\n"
+"       --proxy-tlsauthtype <type>\n"
+"              Same as --tlsauthtype but used in HTTPS proxy context.\n"
+"\n"
+"              Added in 7.52.0.\n"
+"\n"
+"       --proxy-tlspassword <string>\n"
+, stdout);
+ fputs(
+"              Same as --tlspassword but used in HTTPS proxy context.\n"
+"\n"
+"              Added in 7.52.0.\n"
+"\n"
+"       --proxy-tlsuser <name>\n"
+"              Same as --tlsuser but used in HTTPS proxy context.\n"
+"\n"
+"              Added in 7.52.0.\n"
+"\n"
+"       --proxy-tlsv1\n"
+"              Same as -1, --tlsv1 but used in HTTPS proxy context.\n"
+"\n"
+"              Added in 7.52.0.\n"
+"\n"
+"       -U, --proxy-user <user:password>\n"
+"              Specify the user name and password to use for proxy  authentica-\n"
+"              tion.\n"
+"\n"
+, stdout);
+ fputs(
+"              If  you  use  a  Windows  SSPI-enabled curl binary and do either\n"
+"              Negotiate or NTLM authentication  then  you  can  tell  curl  to\n"
+"              select the user name and password from your environment by spec-\n"
+"              ifying a single colon with this option: \"-U :\".\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"       -x, --proxy [protocol://]host[:port]\n"
+"              Use the specified proxy.\n"
+"\n"
+, stdout);
+ fputs(
+"              The proxy string can be specified with a protocol:// prefix.  No\n"
+"              protocol specified or http:// will be treated as HTTP proxy. Use\n"
+"              socks4://, socks4a://, socks5:// or socks5h:// to request a spe-\n"
+"              cific SOCKS version to be used.  (The protocol support was added\n"
+"              in curl 7.21.7)\n"
+"\n"
+"              HTTPS proxy support via https:// protocol prefix  was  added  in\n"
+"              7.52.0 for OpenSSL, GnuTLS and NSS.\n"
+"\n"
+, stdout);
+ fputs(
+"              Unrecognized  and  unsupported  proxy  protocols  cause an error\n"
+"              since 7.52.0.  Prior versions may ignore the  protocol  and  use\n"
+"              http:// instead.\n"
+"\n"
+"              If  the  port number is not specified in the proxy string, it is\n"
+"              assumed to be 1080.\n"
+"\n"
+"              This option overrides existing environment  variables  that  set\n"
+"              the  proxy  to use. If there's an environment variable setting a\n"
+, stdout);
+ fputs(
+"              proxy, you can set proxy to \"\" to override it.\n"
+"\n"
+"              All operations that are performed over an HTTP proxy will trans-\n"
+"              parently  be  converted  to HTTP. It means that certain protocol\n"
+"              specific operations might not be available. This is not the case\n"
+"              if you can tunnel through the proxy, as one with the -p, --prox-\n"
+"              ytunnel option.\n"
+"\n"
+"              User and password that might be provided in the proxy string are\n"
+, stdout);
+ fputs(
+"              URL  decoded by curl. This allows you to pass in special charac-\n"
+"              ters such as @ by using %40 or pass in a colon with %3a.\n"
+"\n"
+"              The proxy host can be specified the exact same way as the  proxy\n"
+"              environment  variables,  including the protocol prefix (http://)\n"
+"              and the embedded user + password.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"       --proxy1.0 <host[:port]>\n"
+, stdout);
+ fputs(
+"              Use the specified HTTP 1.0 proxy. If  the  port  number  is  not\n"
+"              specified, it is assumed at port 1080.\n"
+"\n"
+"              The  only  difference between this and the HTTP proxy option -x,\n"
+"              --proxy, is that attempts to use CONNECT through the proxy  will\n"
+"              specify an HTTP 1.0 protocol instead of the default HTTP 1.1.\n"
+"\n"
+"       -p, --proxytunnel\n"
+"              When  an  HTTP proxy is used -x, --proxy, this option will cause\n"
+, stdout);
+ fputs(
+"              non-HTTP protocols  to  attempt  to  tunnel  through  the  proxy\n"
+"              instead  of merely using it to do HTTP-like operations. The tun-\n"
+"              nel approach is made with the HTTP  proxy  CONNECT  request  and\n"
+"              requires that the proxy allows direct connect to the remote port\n"
+"              number curl wants to tunnel through to.\n"
+"\n"
+"              To suppress proxy CONNECT response headers when curl is  set  to\n"
+, stdout);
+ fputs(
+"              output headers use --suppress-connect-headers.\n"
+"\n"
+"              See also -x, --proxy.\n"
+"\n"
+"       --pubkey <key>\n"
+"              (SFTP SCP) Public key file name. Allows you to provide your pub-\n"
+"              lic key in this separate file.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"              (As of 7.39.0, curl attempts to automatically extract the public\n"
+"              key  from the private key file, so passing this option is gener-\n"
+, stdout);
+ fputs(
+"              ally not required. Note that this public key extraction requires\n"
+"              libcurl  to  be linked against a copy of libssh2 1.2.8 or higher\n"
+"              that is itself linked against OpenSSL.)\n"
+"\n"
+"       -Q, --quote\n"
+"              (FTP SFTP) Send an arbitrary command to the remote FTP  or  SFTP\n"
+"              server.  Quote commands are sent BEFORE the transfer takes place\n"
+"              (just after the initial PWD command in an FTP  transfer,  to  be\n"
+, stdout);
+ fputs(
+"              exact). To make commands take place after a successful transfer,\n"
+"              prefix them with a dash '-'.  To make  commands  be  sent  after\n"
+"              curl has changed the working directory, just before the transfer\n"
+"              command(s), prefix the command with a '+'  (this  is  only  sup-\n"
+"              ported for FTP). You may specify any number of commands.\n"
+"\n"
+"              If  the  server  returns  failure  for  one of the commands, the\n"
+, stdout);
+ fputs(
+"              entire operation will be aborted. You  must  send  syntactically\n"
+"              correct  FTP  commands as RFC 959 defines to FTP servers, or one\n"
+"              of the commands listed below to SFTP servers.\n"
+"\n"
+"              This option can be used multiple times. When speaking to an  FTP\n"
+"              server,  prefix  the  command  with an asterisk (*) to make curl\n"
+"              continue even if the command fails as by default curl will  stop\n"
+"              at first failure.\n"
+"\n"
+, stdout);
+ fputs(
+"              SFTP  is a binary protocol. Unlike for FTP, curl interprets SFTP\n"
+"              quote commands itself before sending them to the  server.   File\n"
+"              names may be quoted shell-style to embed spaces or special char-\n"
+"              acters.  Following is the list of all supported SFTP quote  com-\n"
+"              mands:\n"
+"\n"
+"              chgrp group file\n"
+"                     The  chgrp command sets the group ID of the file named by\n"
+, stdout);
+ fputs(
+"                     the file operand to the group ID specified by  the  group\n"
+"                     operand. The group operand is a decimal integer group ID.\n"
+"\n"
+"              chmod mode file\n"
+"                     The  chmod  command  modifies  the  file mode bits of the\n"
+"                     specified file. The mode operand is an octal integer mode\n"
+"                     number.\n"
+"\n"
+"              chown user file\n"
+"                     The chown command sets the owner of the file named by the\n"
+, stdout);
+ fputs(
+"                     file operand to the user ID specified by the  user  oper-\n"
+"                     and. The user operand is a decimal integer user ID.\n"
+"\n"
+"              ln source_file target_file\n"
+"                     The ln and symlink commands create a symbolic link at the\n"
+"                     target_file location pointing to  the  source_file  loca-\n"
+"                     tion.\n"
+"\n"
+"              mkdir directory_name\n"
+"                     The  mkdir  command  creates  the  directory named by the\n"
+, stdout);
+ fputs(
+"                     directory_name operand.\n"
+"\n"
+"              pwd    The pwd command returns the absolute pathname of the cur-\n"
+"                     rent working directory.\n"
+"\n"
+"              rename source target\n"
+"                     The rename command renames the file or directory named by\n"
+"                     the source operand to the destination path named  by  the\n"
+"                     target operand.\n"
+"\n"
+"              rm file\n"
+, stdout);
+ fputs(
+"                     The rm command removes the file specified by the file op-\n"
+"                     erand.\n"
+"\n"
+"              rmdir directory\n"
+"                     The rmdir command removes the directory  entry  specified\n"
+"                     by the directory operand, provided it is empty.\n"
+"\n"
+"              symlink source_file target_file\n"
+"                     See ln.\n"
+"\n"
+"       --random-file <file>\n"
+"              Specify the path name to file containing what will be considered\n"
+, stdout);
+ fputs(
+"              as random data. The data may be used to seed the  random  engine\n"
+"              for SSL connections.  See also the --egd-file option.\n"
+"\n"
+"       -r, --range <range>\n"
+"              (HTTP  FTP SFTP FILE) Retrieve a byte range (i.e a partial docu-\n"
+"              ment) from a HTTP/1.1, FTP or  SFTP  server  or  a  local  FILE.\n"
+"              Ranges can be specified in a number of ways.\n"
+"\n"
+"              0-499     specifies the first 500 bytes\n"
+"\n"
+, stdout);
+ fputs(
+"              500-999   specifies the second 500 bytes\n"
+"\n"
+"              -500      specifies the last 500 bytes\n"
+"\n"
+"              9500-     specifies the bytes from offset 9500 and forward\n"
+"\n"
+"              0-0,-1    specifies the first and last byte only(*)(HTTP)\n"
+"\n"
+"              100-199,500-599\n"
+"                        specifies two separate 100-byte ranges(*) (HTTP)\n"
+"\n"
+"              (*)  = NOTE that this will cause the server to reply with a mul-\n"
+"              tipart response!\n"
+"\n"
+, stdout);
+ fputs(
+"              Only digit characters (0-9) are valid in the 'start' and  'stop'\n"
+"              fields  of the 'start-stop' range syntax. If a non-digit charac-\n"
+"              ter is given in the range, the server's response will be unspec-\n"
+"              ified, depending on the server's configuration.\n"
+"\n"
+"              You  should also be aware that many HTTP/1.1 servers do not have\n"
+"              this feature enabled, so that when you attempt to get  a  range,\n"
+, stdout);
+ fputs(
+"              you'll instead get the whole document.\n"
+"\n"
+"              FTP  and  SFTP  range  downloads only support the simple 'start-\n"
+"              stop' syntax (optionally with one of the numbers  omitted).  FTP\n"
+"              use depends on the extended FTP command SIZE.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"       --raw  (HTTP) When used, it disables all internal HTTP decoding of con-\n"
+, stdout);
+ fputs(
+"              tent or transfer encodings and  instead  makes  them  passed  on\n"
+"              unaltered, raw.\n"
+"\n"
+"              Added in 7.16.2.\n"
+"\n"
+"       -e, --referer <URL>\n"
+"              (HTTP) Sends the \"Referrer Page\" information to the HTTP server.\n"
+"              This can also be set with the -H, --header flag of course.  When\n"
+"              used  with  -L,  --location  you  can  append \";auto\" to the -e,\n"
+"              --referer URL to make curl automatically set  the  previous  URL\n"
+, stdout);
+ fputs(
+"              when  it  follows  a Location: header. The \";auto\" string can be\n"
+"              used alone, even if you don't set an initial -e, --referer.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"              See also -A, --user-agent and -H, --header.\n"
+"\n"
+"       -J, --remote-header-name\n"
+"              (HTTP) This option tells the -O, --remote-name option to use the\n"
+"              server-specified   Content-Disposition   filename   instead   of\n"
+, stdout);
+ fputs(
+"              extracting a filename from the URL.\n"
+"\n"
+"              If the server specifies a file name and a file  with  that  name\n"
+"              already  exists  in the current working directory it will not be\n"
+"              overwritten and an error will occur. If the server doesn't spec-\n"
+"              ify a file name then this option has no effect.\n"
+"\n"
+"              There's  no  attempt to decode %-sequences (yet) in the provided\n"
+, stdout);
+ fputs(
+"              file name, so this option may provide you with rather unexpected\n"
+"              file names.\n"
+"\n"
+"              WARNING:  Exercise  judicious  use of this option, especially on\n"
+"              Windows. A rogue server could send you the  name  of  a  DLL  or\n"
+"              other  file  that could possibly be loaded automatically by Win-\n"
+"              dows or some third party software.\n"
+"\n"
+"       --remote-name-all\n"
+"              This option changes the default action for all given URLs to  be\n"
+, stdout);
+ fputs(
+"              dealt with as if -O, --remote-name were used for each one. So if\n"
+"              you want to disable that for a specific URL after --remote-name-\n"
+"              all has been used, you must use \"-o -\" or --no-remote-name.\n"
+"\n"
+"              Added in 7.19.0.\n"
+"\n"
+"       -O, --remote-name\n"
+"              Write  output to a local file named like the remote file we get.\n"
+"              (Only the file part of the remote file is used, the path is  cut\n"
+"              off.)\n"
+"\n"
+, stdout);
+ fputs(
+"              The  file will be saved in the current working directory. If you\n"
+"              want the file saved in a  different  directory,  make  sure  you\n"
+"              change  the  current working directory before invoking curl with\n"
+"              this option.\n"
+"\n"
+"              The remote file name to use for saving  is  extracted  from  the\n"
+"              given  URL,  nothing  else,  and if it already exists it will be\n"
+, stdout);
+ fputs(
+"              overwritten. If you want the server to be  able  to  choose  the\n"
+"              file name refer to -J, --remote-header-name which can be used in\n"
+"              addition to this option. If the server chooses a file  name  and\n"
+"              that name already exists it will not be overwritten.\n"
+"\n"
+"              There is no URL decoding done on the file name. If it has %20 or\n"
+"              other URL encoded parts of the name, they will end up  as-is  as\n"
+"              file name.\n"
+"\n"
+, stdout);
+ fputs(
+"              You  may use this option as many times as the number of URLs you\n"
+"              have.\n"
+"\n"
+"       -R, --remote-time\n"
+"              When used, this will make curl attempt to figure out  the  time-\n"
+"              stamp  of  the  remote  file,  and if that is available make the\n"
+"              local file get that same timestamp.\n"
+"\n"
+"       --request-target\n"
+"              (HTTP) Tells curl to use an alternative \"target\" (path)  instead\n"
+, stdout);
+ fputs(
+"              of  using  the  path as provided in the URL. Particularly useful\n"
+"              when wanting to issue HTTP requests  without  leading  slash  or\n"
+"              other  data  that  doesn't  follow the regular URL pattern, like\n"
+"              \"OPTIONS *\".\n"
+"\n"
+"              Added in 7.55.0.\n"
+"\n"
+"       -X, --request <command>\n"
+"              (HTTP) Specifies a custom request method to use when communicat-\n"
+"              ing  with the HTTP server.  The specified request method will be\n"
+, stdout);
+ fputs(
+"              used instead of the method otherwise  used  (which  defaults  to\n"
+"              GET).  Read  the HTTP 1.1 specification for details and explana-\n"
+"              tions. Common additional HTTP requests include PUT  and  DELETE,\n"
+"              but related technologies like WebDAV offers PROPFIND, COPY, MOVE\n"
+"              and more.\n"
+"\n"
+"              Normally you don't need this option. All  sorts  of  GET,  HEAD,\n"
+"              POST and PUT requests are rather invoked by using dedicated com-\n"
+, stdout);
+ fputs(
+"              mand line options.\n"
+"\n"
+"              This option only changes  the  actual  word  used  in  the  HTTP\n"
+"              request,  it does not alter the way curl behaves. So for example\n"
+"              if you want to make a proper HEAD request, using  -X  HEAD  will\n"
+"              not suffice. You need to use the -I, --head option.\n"
+"\n"
+"              The  method  string  you set with -X, --request will be used for\n"
+"              all requests, which if you for example use  -L,  --location  may\n"
+, stdout);
+ fputs(
+"              cause  unintended  side-effects when curl doesn't change request\n"
+"              method according to the HTTP 30x response codes - and similar.\n"
+"\n"
+"              (FTP) Specifies a custom FTP command to use instead of LIST when\n"
+"              doing file lists with FTP.\n"
+"\n"
+"              (POP3) Specifies a custom POP3 command to use instead of LIST or\n"
+"              RETR. (Added in 7.26.0)\n"
+"\n"
+"              (IMAP) Specifies a custom IMAP command to use instead  of  LIST.\n"
+, stdout);
+ fputs(
+"              (Added in 7.30.0)\n"
+"\n"
+"              (SMTP) Specifies a custom SMTP command to use instead of HELP or\n"
+"              VRFY. (Added in 7.34.0)\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"       --resolve <host:port:address>\n"
+"              Provide a custom address for a  specific  host  and  port  pair.\n"
+"              Using  this,  you  can make the curl requests(s) use a specified\n"
+, stdout);
+ fputs(
+"              address and prevent the otherwise normally resolved  address  to\n"
+"              be  used.  Consider it a sort of /etc/hosts alternative provided\n"
+"              on the command line. The port number should be the  number  used\n"
+"              for  the  specific  protocol the host will be used for. It means\n"
+"              you need several entries if you want to provide address for  the\n"
+"              same host but different ports.\n"
+"\n"
+, stdout);
+ fputs(
+"              The provided address set by this option will be used even if -4,\n"
+"              --ipv4 or -6, --ipv6 is set to make curl use another IP version.\n"
+"              Support for providing the IP address within [brackets] was added\n"
+"              in 7.57.0.\n"
+"\n"
+"              This  option  can  be  used many times to add many host names to\n"
+"              resolve.\n"
+"\n"
+"              Added in 7.21.3.\n"
+"\n"
+"       --retry-connrefused\n"
+, stdout);
+ fputs(
+"              In addition to the other conditions, consider ECONNREFUSED as  a\n"
+"              transient  error  too  for --retry. This option is used together\n"
+"              with --retry.\n"
+"\n"
+"              Added in 7.52.0.\n"
+"\n"
+"       --retry-delay <seconds>\n"
+"              Make curl sleep this amount of time before  each  retry  when  a\n"
+"              transfer  has  failed  with  a  transient  error (it changes the\n"
+"              default backoff time algorithm between retries). This option  is\n"
+, stdout);
+ fputs(
+"              only  interesting if --retry is also used. Setting this delay to\n"
+"              zero will make curl use the default backoff time.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"              Added in 7.12.3.\n"
+"\n"
+"       --retry-max-time <seconds>\n"
+"              The retry timer is reset  before  the  first  transfer  attempt.\n"
+"              Retries will be done as usual (see --retry) as long as the timer\n"
+, stdout);
+ fputs(
+"              hasn't reached this given limit. Notice that if the timer hasn't\n"
+"              reached  the  limit, the request will be made and while perform-\n"
+"              ing, it may take longer than this given time period. To limit  a\n"
+"              single  request's  maximum  time,  use -m, --max-time.  Set this\n"
+"              option to zero to not timeout retries.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"              Added in 7.12.3.\n"
+"\n"
+, stdout);
+ fputs(
+"       --retry <num>\n"
+"              If a transient error is returned when curl tries  to  perform  a\n"
+"              transfer,  it  will retry this number of times before giving up.\n"
+"              Setting the number to 0 makes curl do no retries (which  is  the\n"
+"              default).  Transient  error  means either: a timeout, an FTP 4xx\n"
+"              response code or an HTTP 5xx response code.\n"
+"\n"
+"              When curl is about to retry a transfer, it will first  wait  one\n"
+, stdout);
+ fputs(
+"              second  and  then for all forthcoming retries it will double the\n"
+"              waiting time until it reaches 10 minutes which then will be  the\n"
+"              delay  between  the rest of the retries.  By using --retry-delay\n"
+"              you  disable  this  exponential  backoff  algorithm.  See   also\n"
+"              --retry-max-time to limit the total time allowed for retries.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+, stdout);
+ fputs(
+"              Added in 7.12.3.\n"
+"\n"
+"       --sasl-ir\n"
+"              Enable initial response in SASL authentication.\n"
+"\n"
+"              Added in 7.31.0.\n"
+"\n"
+"       --service-name <name>\n"
+"              This option allows you to change the service name for SPNEGO.\n"
+"\n"
+"              Examples:    --negotiate    --service-name   sockd   would   use\n"
+"              sockd/server-name.\n"
+"\n"
+"              Added in 7.43.0.\n"
+"       -S, --show-error\n"
+"              When used with -s, --silent, it makes curl show an error message\n"
+, stdout);
+ fputs(
+"              if it fails.\n"
+"       -s, --silent\n"
+"              Silent  or  quiet  mode. Don't show progress meter or error mes-\n"
+"              sages.  Makes Curl mute. It will still output the data  you  ask\n"
+"              for, potentially even to the terminal/stdout unless you redirect\n"
+"              it.\n"
+"\n"
+"              Use -S, --show-error in  addition  to  this  option  to  disable\n"
+"              progress meter but still show error messages.\n"
+"\n"
+"              See also -v, --verbose and --stderr.\n"
+"\n"
+, stdout);
+ fputs(
+"       --socks4 <host[:port]>\n"
+"              Use the specified SOCKS4 proxy. If the port number is not speci-\n"
+"              fied, it is assumed at port 1080.\n"
+"\n"
+"              This option overrides any previous use of -x, --proxy,  as  they\n"
+"              are mutually exclusive.\n"
+"\n"
+"              Since 7.21.7, this option is superfluous since you can specify a\n"
+"              socks4 proxy with -x, --proxy using a socks4:// protocol prefix.\n"
+, stdout);
+ fputs(
+"              Since 7.52.0, --preproxy can be used to specify a SOCKS proxy at\n"
+"              the  same  time -x, --proxy is used with an HTTP/HTTPS proxy. In\n"
+"              such a case curl first connects to the SOCKS proxy and then con-\n"
+"              nects (through SOCKS) to the HTTP or HTTPS proxy.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"              Added in 7.15.2.\n"
+"\n"
+"       --socks4a <host[:port]>\n"
+, stdout);
+ fputs(
+"              Use the specified SOCKS4a proxy. If the port number is not spec-\n"
+"              ified, it is assumed at port 1080.\n"
+"\n"
+"              This option overrides any previous use of -x, --proxy,  as  they\n"
+"              are mutually exclusive.\n"
+"\n"
+"              Since 7.21.7, this option is superfluous since you can specify a\n"
+"              socks4a proxy with -x, --proxy using a socks4a:// protocol  pre-\n"
+"              fix.\n"
+"\n"
+, stdout);
+ fputs(
+"              Since 7.52.0, --preproxy can be used to specify a SOCKS proxy at\n"
+"              the same time -x, --proxy is used with an HTTP/HTTPS  proxy.  In\n"
+"              such a case curl first connects to the SOCKS proxy and then con-\n"
+"              nects (through SOCKS) to the HTTP or HTTPS proxy.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"              Added in 7.18.0.\n"
+"\n"
+"       --socks5-basic\n"
+, stdout);
+ fputs(
+"              Tells curl to use username/password authentication when connect-\n"
+"              ing  to a SOCKS5 proxy.  The username/password authentication is\n"
+"              enabled  by  default.   Use  --socks5-gssapi  to  force  GSS-API\n"
+"              authentication to SOCKS5 proxies.\n"
+"\n"
+"              Added in 7.55.0.\n"
+"\n"
+"       --socks5-gssapi-nec\n"
+"              As  part of the GSS-API negotiation a protection mode is negoti-\n"
+, stdout);
+ fputs(
+"              ated. RFC 1961 says in section 4.3/4.4 it should  be  protected,\n"
+"              but  the  NEC  reference  implementation  does  not.  The option\n"
+"              --socks5-gssapi-nec allows the unprotected exchange of the  pro-\n"
+"              tection mode negotiation.\n"
+"\n"
+"              Added in 7.19.4.\n"
+"\n"
+"       --socks5-gssapi-service <name>\n"
+"              The default service name for a socks server is rcmd/server-fqdn.\n"
+"              This option allows you to change it.\n"
+"\n"
+, stdout);
+ fputs(
+"              Examples:  --socks5  proxy-name  --socks5-gssapi-service   sockd\n"
+"              would  use sockd/proxy-name --socks5 proxy-name --socks5-gssapi-\n"
+"              service sockd/real-name  would  use  sockd/real-name  for  cases\n"
+"              where the proxy-name does not match the principal name.\n"
+"\n"
+"              Added in 7.19.4.\n"
+"\n"
+"       --socks5-gssapi\n"
+"              Tells  curl  to  use GSS-API authentication when connecting to a\n"
+, stdout);
+ fputs(
+"              SOCKS5 proxy.  The GSS-API authentication is enabled by  default\n"
+"              (if  curl is compiled with GSS-API support).  Use --socks5-basic\n"
+"              to force username/password authentication to SOCKS5 proxies.\n"
+"\n"
+"              Added in 7.55.0.\n"
+"\n"
+"       --socks5-hostname <host[:port]>\n"
+"              Use the specified SOCKS5 proxy (and let the  proxy  resolve  the\n"
+"              host  name).  If the port number is not specified, it is assumed\n"
+"              at port 1080.\n"
+"\n"
+, stdout);
+ fputs(
+"              This option overrides any previous use of -x, --proxy,  as  they\n"
+"              are mutually exclusive.\n"
+"\n"
+"              Since 7.21.7, this option is superfluous since you can specify a\n"
+"              socks5 hostname proxy with -x, --proxy using a socks5h:// proto-\n"
+"              col prefix.\n"
+"\n"
+"              Since 7.52.0, --preproxy can be used to specify a SOCKS proxy at\n"
+"              the same time -x, --proxy is used with an HTTP/HTTPS  proxy.  In\n"
+, stdout);
+ fputs(
+"              such a case curl first connects to the SOCKS proxy and then con-\n"
+"              nects (through SOCKS) to the HTTP or HTTPS proxy.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"              Added in 7.18.0.\n"
+"\n"
+"       --socks5 <host[:port]>\n"
+"              Use the specified SOCKS5 proxy  -  but  resolve  the  host  name\n"
+"              locally.  If  the port number is not specified, it is assumed at\n"
+"              port 1080.\n"
+"\n"
+, stdout);
+ fputs(
+"              This option overrides any previous use of -x, --proxy,  as  they\n"
+"              are mutually exclusive.\n"
+"\n"
+"              Since 7.21.7, this option is superfluous since you can specify a\n"
+"              socks5 proxy with -x, --proxy using a socks5:// protocol prefix.\n"
+"              Since 7.52.0, --preproxy can be used to specify a SOCKS proxy at\n"
+"              the  same  time -x, --proxy is used with an HTTP/HTTPS proxy. In\n"
+, stdout);
+ fputs(
+"              such a case curl first connects to the SOCKS proxy and then con-\n"
+"              nects (through SOCKS) to the HTTP or HTTPS proxy.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"              This  option (as well as --socks4) does not work with IPV6, FTPS\n"
+"              or LDAP.\n"
+"\n"
+"              Added in 7.18.0.\n"
+"\n"
+"       -Y, --speed-limit <speed>\n"
+"              If a download is slower than this given speed (in bytes per sec-\n"
+, stdout);
+ fputs(
+"              ond)  for  speed-time seconds it gets aborted. speed-time is set\n"
+"              with -y, --speed-time and is 30 if not set.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"       -y, --speed-time <seconds>\n"
+"              If a download is slower than speed-limit bytes per second during\n"
+"              a speed-time period, the download gets aborted. If speed-time is\n"
+"              used, the default speed-limit will be  1  unless  set  with  -Y,\n"
+, stdout);
+ fputs(
+"              --speed-limit.\n"
+"\n"
+"              This  option  controls  transfers  and thus will not affect slow\n"
+"              connects etc. If this is a concern for you, try  the  --connect-\n"
+"              timeout option.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"       --ssl-allow-beast\n"
+"              This option tells curl to not work around a security flaw in the\n"
+"              SSL3 and TLS1.0 protocols known as BEAST.  If this option  isn't\n"
+, stdout);
+ fputs(
+"              used,  the SSL layer may use workarounds known to cause interop-\n"
+"              erability problems with some older SSL implementations. WARNING:\n"
+"              this option loosens the SSL security, and by using this flag you\n"
+"              ask for exactly that.\n"
+"\n"
+"              Added in 7.25.0.\n"
+"\n"
+"       --ssl-no-revoke\n"
+"              (WinSSL) This option tells curl to disable  certificate  revoca-\n"
+"              tion checks.  WARNING: this option loosens the SSL security, and\n"
+, stdout);
+ fputs(
+"              by using this flag you ask for exactly that.\n"
+"\n"
+"              Added in 7.44.0.\n"
+"\n"
+"       --ssl-reqd\n"
+"              (FTP IMAP POP3 SMTP) Require SSL/TLS for the connection.  Termi-\n"
+"              nates the connection if the server doesn't support SSL/TLS.\n"
+"\n"
+"              This option was formerly known as --ftp-ssl-reqd.\n"
+"\n"
+"              Added in 7.20.0.\n"
+"\n"
+"       --ssl  (FTP  IMAP  POP3  SMTP)  Try  to use SSL/TLS for the connection.\n"
+, stdout);
+ fputs(
+"              Reverts to a non-secure connection if the server doesn't support\n"
+"              SSL/TLS.   See also --ftp-ssl-control and --ssl-reqd for differ-\n"
+"              ent levels of encryption required.\n"
+"\n"
+"              This option was formerly known as --ftp-ssl (Added  in  7.11.0).\n"
+"              That  option  name  can  still  be used but will be removed in a\n"
+"              future version.\n"
+"\n"
+"              Added in 7.20.0.\n"
+"\n"
+"       -2, --sslv2\n"
+, stdout);
+ fputs(
+"              (SSL) Forces curl to use SSL version 2 when negotiating  with  a\n"
+"              remote  SSL  server.  Sometimes curl is built without SSLv2 sup-\n"
+"              port. SSLv2 is widely considered insecure (see RFC 6176).\n"
+"\n"
+"              See also --http1.1 and --http2. -2, --sslv2  requires  that  the\n"
+"              underlying  libcurl  was built to support TLS. This option over-\n"
+"              rides -3, --sslv3 and -1, --tlsv1 and --tlsv1.1 and --tlsv1.2.\n"
+"\n"
+"       -3, --sslv3\n"
+, stdout);
+ fputs(
+"              (SSL) Forces curl to use SSL version 3 when negotiating  with  a\n"
+"              remote  SSL  server.  Sometimes curl is built without SSLv3 sup-\n"
+"              port. SSLv3 is widely considered insecure (see RFC 7568).\n"
+"\n"
+"              See also --http1.1 and --http2. -3, --sslv3  requires  that  the\n"
+"              underlying  libcurl  was built to support TLS. This option over-\n"
+"              rides -2, --sslv2 and -1, --tlsv1 and --tlsv1.1 and --tlsv1.2.\n"
+"\n"
+"       --stderr\n"
+, stdout);
+ fputs(
+"              Redirect all writes to stderr to the specified file instead.  If\n"
+"              the file name is a plain '-', it is instead written to stdout.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"              See also -v, --verbose and -s, --silent.\n"
+"\n"
+"       --suppress-connect-headers\n"
+"              When  -p,  --proxytunnel  is  used and a CONNECT request is made\n"
+"              don't output proxy CONNECT  response  headers.  This  option  is\n"
+, stdout);
+ fputs(
+"              meant  to  be used with -D, --dump-header or -i, --include which\n"
+"              are used to show protocol headers  in  the  output.  It  has  no\n"
+"              effect on debug options such as -v, --verbose or --trace, or any\n"
+"              statistics.\n"
+"\n"
+"              See also -D, --dump-header and -i, --include and -p, --proxytun-\n"
+"              nel.\n"
+"\n"
+"       --tcp-fastopen\n"
+"              Enable use of TCP Fast Open (RFC7413).\n"
+"\n"
+"              Added in 7.49.0.\n"
+"\n"
+"       --tcp-nodelay\n"
+, stdout);
+ fputs(
+"              Turn  on the TCP_NODELAY option. See the curl_easy_setopt(3) man\n"
+"              page for details about this option.\n"
+"\n"
+"              Since 7.50.2, curl sets this option by default and you  need  to\n"
+"              explicitly switch it off if you don't want it on.\n"
+"\n"
+"              Added in 7.11.2.\n"
+"\n"
+"       -t, --telnet-option <opt=val>\n"
+"              Pass options to the telnet protocol. Supported options are:\n"
+"\n"
+"              TTYPE=<term> Sets the terminal type.\n"
+"\n"
+, stdout);
+ fputs(
+"              XDISPLOC=<X display> Sets the X display location.\n"
+"\n"
+"              NEW_ENV=<var,val> Sets an environment variable.\n"
+"\n"
+"       --tftp-blksize <value>\n"
+"              (TFTP) Set TFTP BLKSIZE option (must be >512). This is the block\n"
+"              size that curl will try to use when transferring data to or from\n"
+"              a TFTP server. By default 512 bytes will be used.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"              Added in 7.20.0.\n"
+"\n"
+, stdout);
+ fputs(
+"       --tftp-no-options\n"
+"              (TFTP) Tells curl not to send TFTP options requests.\n"
+"\n"
+"              This  option  improves  interop with some legacy servers that do\n"
+"              not acknowledge or properly implement TFTP  options.  When  this\n"
+"              option is used --tftp-blksize is ignored.\n"
+"\n"
+"              Added in 7.48.0.\n"
+"\n"
+"       -z, --time-cond <time>\n"
+"              (HTTP  FTP) Request a file that has been modified later than the\n"
+, stdout);
+ fputs(
+"              given time and date, or one that has been modified  before  that\n"
+"              time.  The <date expression> can be all sorts of date strings or\n"
+"              if it doesn't match any internal ones, it is taken as a filename\n"
+"              and  tries  to  get  the  modification  date (mtime) from <file>\n"
+"              instead. See the curl_getdate(3) man pages for  date  expression\n"
+"              details.\n"
+"\n"
+"              Start the date expression with a dash (-) to make it request for\n"
+, stdout);
+ fputs(
+"              a document that is older than the given date/time, default is  a\n"
+"              document that is newer than the specified date/time.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"       --tls-max <VERSION>\n"
+"              (SSL)  VERSION  defines maximum supported TLS version. A minimum\n"
+"              is defined by arguments tlsv1.0 or tlsv1.1 or tlsv1.2.\n"
+"\n"
+"              default\n"
+"                     Use up to recommended TLS version.\n"
+"\n"
+, stdout);
+ fputs(
+"              1.0    Use up to TLSv1.0.\n"
+"              1.1    Use up to TLSv1.1.\n"
+"              1.2    Use up to TLSv1.2.\n"
+"              1.3    Use up to TLSv1.3.\n"
+"\n"
+"       See also --tlsv1.0 and --tlsv1.1 and --tlsv1.2. --tls-max requires that\n"
+"       the underlying libcurl was built to support TLS. Added in 7.54.0.\n"
+"\n"
+"       --tlsauthtype <type>\n"
+"              Set  TLS  authentication  type.  Currently,  the  only supported\n"
+"              option is \"SRP\",  for  TLS-SRP  (RFC  5054).  If  --tlsuser  and\n"
+, stdout);
+ fputs(
+"              --tlspassword  are specified but --tlsauthtype is not, then this\n"
+"              option defaults to \"SRP\".\n"
+"\n"
+"              Added in 7.21.4.\n"
+"\n"
+"       --tlspassword\n"
+"              Set password for use with the TLS authentication  method  speci-\n"
+"              fied with --tlsauthtype. Requires that --tlsuser also be set.\n"
+"\n"
+"              Added in 7.21.4.\n"
+"       --tlsuser <name>\n"
+"              Set  username  for use with the TLS authentication method speci-\n"
+, stdout);
+ fputs(
+"              fied with --tlsauthtype. Requires  that  --tlspassword  also  is\n"
+"              set.\n"
+"\n"
+"              Added in 7.21.4.\n"
+"\n"
+"       --tlsv1.0\n"
+"              (TLS)  Forces  curl  to use TLS version 1.0 when connecting to a\n"
+"              remote TLS server.\n"
+"\n"
+"              Added in 7.34.0.\n"
+"\n"
+"       --tlsv1.1\n"
+"              (TLS) Forces curl to use TLS version 1.1 when  connecting  to  a\n"
+"              remote TLS server.\n"
+"\n"
+"              Added in 7.34.0.\n"
+"\n"
+"       --tlsv1.2\n"
+, stdout);
+ fputs(
+"              (TLS)  Forces  curl  to use TLS version 1.2 when connecting to a\n"
+"              remote TLS server.\n"
+"\n"
+"              Added in 7.34.0.\n"
+"\n"
+"       --tlsv1.3\n"
+"              (TLS) Forces curl to use TLS version 1.3 when  connecting  to  a\n"
+"              remote TLS server.\n"
+"\n"
+"              Note that TLS 1.3 is only supported by a subset of TLS backends.\n"
+"              At the time of this writing, they are BoringSSL, NSS, and Secure\n"
+, stdout);
+ fputs(
+"              Transport (on iOS 11 or later, and macOS 10.13 or later).\n"
+"\n"
+"              Added in 7.52.0.\n"
+"\n"
+"       -1, --tlsv1\n"
+"              (SSL)  Tells curl to use TLS version 1.x when negotiating with a\n"
+"              remote TLS server. That means TLS version 1.0, 1.1 or 1.2.\n"
+"\n"
+"              See also --http1.1 and --http2. -1, --tlsv1  requires  that  the\n"
+"              underlying  libcurl  was built to support TLS. This option over-\n"
+"              rides --tlsv1.1 and --tlsv1.2 and --tlsv1.3.\n"
+"\n"
+, stdout);
+ fputs(
+"       --tr-encoding\n"
+"              (HTTP) Request a compressed Transfer-Encoding response using one\n"
+"              of  the  algorithms curl supports, and uncompress the data while\n"
+"              receiving it.\n"
+"\n"
+"              Added in 7.21.6.\n"
+"\n"
+"       --trace-ascii <file>\n"
+"              Enables a full trace dump of all  incoming  and  outgoing  data,\n"
+"              including descriptive information, to the given output file. Use\n"
+"              \"-\" as filename to have the output sent to stdout.\n"
+"\n"
+, stdout);
+ fputs(
+"              This is very similar to --trace, but leaves out the hex part and\n"
+"              only  shows  the ASCII part of the dump. It makes smaller output\n"
+"              that might be easier to read for untrained humans.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"              This option overrides --trace and -v, --verbose.\n"
+"\n"
+"       --trace-time\n"
+"              Prepends a time stamp to each trace or verbose  line  that  curl\n"
+"              displays.\n"
+"\n"
+, stdout);
+ fputs(
+"              Added in 7.14.0.\n"
+"\n"
+"       --trace <file>\n"
+"              Enables  a  full  trace  dump of all incoming and outgoing data,\n"
+"              including descriptive information, to the given output file. Use\n"
+"              \"-\"  as  filename  to have the output sent to stdout. Use \"%\" as\n"
+"              filename to have the output sent to stderr.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"              This option overrides -v, --verbose and --trace-ascii.\n"
+"\n"
+, stdout);
+ fputs(
+"       --unix-socket <path>\n"
+"              (HTTP) Connect through this Unix domain socket, instead of using\n"
+"              the network.\n"
+"\n"
+"              Added in 7.40.0.\n"
+"\n"
+"       -T, --upload-file <file>\n"
+"              This  transfers  the  specified local file to the remote URL. If\n"
+"              there is no file part in the specified URL, curl will append the\n"
+"              local file name. NOTE that you must use a trailing / on the last\n"
+, stdout);
+ fputs(
+"              directory to really prove to Curl that there is no file name  or\n"
+"              curl will think that your last directory name is the remote file\n"
+"              name to use. That will most likely cause the upload operation to\n"
+"              fail. If this is used on an HTTP(S) server, the PUT command will\n"
+"              be used.\n"
+"\n"
+"              Use the file name \"-\" (a single dash) to use stdin instead of  a\n"
+"              given  file.   Alternately,  the file name \".\" (a single period)\n"
+, stdout);
+ fputs(
+"              may be specified instead of \"-\" to  use  stdin  in  non-blocking\n"
+"              mode  to  allow  reading  server  output  while  stdin  is being\n"
+"              uploaded.\n"
+"\n"
+"              You can specify one -T, --upload-file for each URL on  the  com-\n"
+"              mand  line.  Each -T, --upload-file + URL pair specifies what to\n"
+"              upload and to where. curl also supports \"globbing\"  of  the  -T,\n"
+, stdout);
+ fputs(
+"              --upload-file  argument,  meaning  that  you can upload multiple\n"
+"              files to a single URL by using the same URL globbing style  sup-\n"
+"              ported in the URL, like this:\n"
+"\n"
+"               curl --upload-file \"{file1,file2}\" http://www.example.com\n"
+"\n"
+"              or even\n"
+"\n"
+"               curl -T \"img[1-1000].png\" ftp://ftp.example.com/upload/\n"
+"\n"
+"              When  uploading  to an SMTP server: the uploaded data is assumed\n"
+, stdout);
+ fputs(
+"              to be RFC 5322 formatted. It has to feature the necessary set of\n"
+"              headers  and  mail  body formatted correctly by the user as curl\n"
+"              will not transcode nor encode it further in any way.\n"
+"\n"
+"       --url <url>\n"
+"              Specify a URL to fetch. This option is  mostly  handy  when  you\n"
+"              want to specify URL(s) in a config file.\n"
+"\n"
+"              If  the given URL is missing a scheme name (such as \"http://\" or\n"
+, stdout);
+ fputs(
+"              \"ftp://\" etc) then curl will make a guess based on the host.  If\n"
+"              the  outermost  sub-domain  name  matches DICT, FTP, IMAP, LDAP,\n"
+"              POP3 or SMTP then that protocol will  be  used,  otherwise  HTTP\n"
+"              will be used. Since 7.45.0 guessing can be disabled by setting a\n"
+"              default protocol, see --proto-default for details.\n"
+"\n"
+"              This option may be used any number of times.  To  control  where\n"
+, stdout);
+ fputs(
+"              this  URL  is written, use the -o, --output or the -O, --remote-\n"
+"              name options.\n"
+"\n"
+"       -B, --use-ascii\n"
+"              (FTP LDAP) Enable ASCII transfer. For  FTP,  this  can  also  be\n"
+"              enforced  by  using  a URL that ends with \";type=A\". This option\n"
+"              causes data sent to stdout to be in text mode for win32 systems.\n"
+"\n"
+"       -A, --user-agent <name>\n"
+"              (HTTP) Specify the User-Agent string to send to the HTTP server.\n"
+, stdout);
+ fputs(
+"              To  encode blanks in the string, surround the string with single\n"
+"              quote marks. This can also be set with the -H,  --header  option\n"
+"              of course.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"       -u, --user <user:password>\n"
+"              Specify the user name and password to use for server authentica-\n"
+"              tion. Overrides -n, --netrc and --netrc-optional.\n"
+"\n"
+, stdout);
+ fputs(
+"              If you simply specify the user name,  curl  will  prompt  for  a\n"
+"              password.\n"
+"\n"
+"              The  user  name  and  passwords are split up on the first colon,\n"
+"              which makes it impossible to use a colon in the user  name  with\n"
+"              this option. The password can, still.\n"
+"\n"
+"              When  using  Kerberos  V5 with a Windows based server you should\n"
+"              include the Windows domain name in the user name, in  order  for\n"
+, stdout);
+ fputs(
+"              the  server  to  successfully  obtain  a Kerberos Ticket. If you\n"
+"              don't then the initial authentication handshake may fail.\n"
+"\n"
+"              When using NTLM, the user name can be specified  simply  as  the\n"
+"              user  name,  without the domain, if there is a single domain and\n"
+"              forest in your setup for example.\n"
+"\n"
+"              To specify the domain name use either Down-Level Logon  Name  or\n"
+, stdout);
+ fputs(
+"              UPN (User Principal Name) formats. For example, EXAMPLE\\user and\n"
+"              user@example.com respectively.\n"
+"\n"
+"              If you use a Windows SSPI-enabled curl binary and  perform  Ker-\n"
+"              beros  V5, Negotiate, NTLM or Digest authentication then you can\n"
+"              tell curl to select the user name and password from  your  envi-\n"
+"              ronment by specifying a single colon with this option: \"-u :\".\n"
+"\n"
+, stdout);
+ fputs(
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"       -v, --verbose\n"
+"              Makes  curl  verbose  during the operation. Useful for debugging\n"
+"              and seeing what's going on \"under the  hood\".  A  line  starting\n"
+"              with  '>'  means  \"header  data\" sent by curl, '<' means \"header\n"
+"              data\" received by curl that is hidden in  normal  cases,  and  a\n"
+"              line starting with '*' means additional info provided by curl.\n"
+"\n"
+, stdout);
+ fputs(
+"              If you only want HTTP headers in the output, -i, --include might\n"
+"              be the option you're looking for.\n"
+"\n"
+"              If you think this option still doesn't give you enough  details,\n"
+"              consider using --trace or --trace-ascii instead.\n"
+"\n"
+"              Use -s, --silent to make curl really quiet.\n"
+"\n"
+"              See  also  -i,  --include.  This  option  overrides  --trace and\n"
+"              --trace-ascii.\n"
+"\n"
+"       -V, --version\n"
+, stdout);
+ fputs(
+"              Displays information about curl and the libcurl version it uses.\n"
+"              The first line includes the full version of  curl,  libcurl  and\n"
+"              other 3rd party libraries linked with the executable.\n"
+"\n"
+"              The  second  line (starts with \"Protocols:\") shows all protocols\n"
+"              that libcurl reports to support.\n"
+"\n"
+"              The third line (starts with \"Features:\") shows specific features\n"
+, stdout);
+ fputs(
+"              libcurl reports to offer. Available features include:\n"
+"\n"
+"              IPv6   You can use IPv6 with this.\n"
+"\n"
+"              krb4   Krb4 for FTP is supported.\n"
+"\n"
+"              SSL    SSL  versions of various protocols are supported, such as\n"
+"                     HTTPS, FTPS, POP3S and so on.\n"
+"\n"
+"              libz   Automatic decompression of compressed files over HTTP  is\n"
+"                     supported.\n"
+"\n"
+"              NTLM   NTLM authentication is supported.\n"
+"\n"
+, stdout);
+ fputs(
+"              Debug  This  curl  uses a libcurl built with Debug. This enables\n"
+"                     more error-tracking and memory debugging etc.  For  curl-\n"
+"                     developers only!\n"
+"\n"
+"              AsynchDNS\n"
+"                     This  curl  uses asynchronous name resolves. Asynchronous\n"
+"                     name resolves can be done using either the c-ares or  the\n"
+"                     threaded resolver backends.\n"
+"\n"
+"              SPNEGO SPNEGO authentication is supported.\n"
+"\n"
+, stdout);
+ fputs(
+"              Largefile\n"
+"                     This curl supports transfers of large files, files larger\n"
+"                     than 2GB.\n"
+"\n"
+"              IDN    This curl supports IDN - international domain names.\n"
+"\n"
+"              GSS-API\n"
+"                     GSS-API is supported.\n"
+"\n"
+"              SSPI   SSPI is supported.\n"
+"\n"
+"              TLS-SRP\n"
+"                     SRP (Secure Remote Password) authentication is  supported\n"
+"                     for TLS.\n"
+"\n"
+, stdout);
+ fputs(
+"              HTTP2  HTTP/2 support has been built-in.\n"
+"\n"
+"              UnixSockets\n"
+"                     Unix sockets support is provided.\n"
+"\n"
+"              HTTPS-proxy\n"
+"                     This curl is built to support HTTPS proxy.\n"
+"\n"
+"              Metalink\n"
+"                     This  curl  supports  Metalink (both version 3 and 4 (RFC\n"
+"                     5854)), which describes mirrors and  hashes.   curl  will\n"
+"                     use mirrors for failover if there are errors (such as the\n"
+, stdout);
+ fputs(
+"                     file or server not being available).\n"
+"\n"
+"              PSL    PSL is short for Public Suffix List and means  that  this\n"
+"                     curl  has  been  built  with knowledge about \"public suf-\n"
+"                     fixes\".\n"
+"\n"
+"       -w, --write-out <format>\n"
+"              Make curl display information on stdout after a completed trans-\n"
+"              fer.  The  format  is a string that may contain plain text mixed\n"
+, stdout);
+ fputs(
+"              with any number of variables. The format can be specified  as  a\n"
+"              literal  \"string\",  or  you can have curl read the format from a\n"
+"              file with \"@filename\" and to tell curl to read the  format  from\n"
+"              stdin you write \"@-\".\n"
+"\n"
+"              The  variables  present in the output format will be substituted\n"
+"              by the value or text that curl thinks fit, as  described  below.\n"
+, stdout);
+ fputs(
+"              All  variables are specified as %{variable_name} and to output a\n"
+"              normal % you just write them as %%. You can output a newline  by\n"
+"              using \\n, a carriage return with \\r and a tab space with \\t.\n"
+"\n"
+"              NOTE: The %-symbol is a special symbol in the win32-environment,\n"
+"              where all occurrences of %  must  be  doubled  when  using  this\n"
+"              option.\n"
+"\n"
+"              The variables available are:\n"
+"\n"
+, stdout);
+ fputs(
+"              content_type   The  Content-Type  of  the requested document, if\n"
+"                             there was any.\n"
+"\n"
+"              filename_effective\n"
+"                             The ultimate filename that curl  writes  out  to.\n"
+"                             This  is only meaningful if curl is told to write\n"
+"                             to a file  with  the  -O,  --remote-name  or  -o,\n"
+"                             --output  option. It's most useful in combination\n"
+, stdout);
+ fputs(
+"                             with the -J, --remote-header-name option.  (Added\n"
+"                             in 7.26.0)\n"
+"\n"
+"              ftp_entry_path The initial path curl ended up in when logging on\n"
+"                             to the remote FTP server. (Added in 7.15.4)\n"
+"\n"
+"              http_code      The numerical response code that was found in the\n"
+"                             last  retrieved  HTTP(S)  or  FTP(s) transfer. In\n"
+, stdout);
+ fputs(
+"                             7.18.2 the alias response_code was added to  show\n"
+"                             the same info.\n"
+"\n"
+"              http_connect   The  numerical  code  that  was found in the last\n"
+"                             response  (from  a  proxy)  to  a  curl   CONNECT\n"
+"                             request. (Added in 7.12.4)\n"
+"\n"
+"              http_version   The  http  version  that  was  effectively  used.\n"
+"                             (Added in 7.50.0)\n"
+"\n"
+, stdout);
+ fputs(
+"              local_ip       The IP address of  the  local  end  of  the  most\n"
+"                             recently  done connection - can be either IPv4 or\n"
+"                             IPv6 (Added in 7.29.0)\n"
+"\n"
+"              local_port     The local port number of the most  recently  done\n"
+"                             connection (Added in 7.29.0)\n"
+"\n"
+"              num_connects   Number  of new connects made in the recent trans-\n"
+"                             fer. (Added in 7.12.3)\n"
+"\n"
+, stdout);
+ fputs(
+"              num_redirects  Number of redirects that  were  followed  in  the\n"
+"                             request. (Added in 7.12.3)\n"
+"\n"
+"              proxy_ssl_verify_result\n"
+"                             The result of the HTTPS proxy's SSL peer certifi-\n"
+"                             cate verification that was requested. 0 means the\n"
+"                             verification was successful. (Added in 7.52.0)\n"
+"\n"
+"              redirect_url   When an HTTP request was made without -L, --loca-\n"
+, stdout);
+ fputs(
+"                             tion to follow redirects (or when --max-redir  is\n"
+"                             met),  this  variable  will show the actual URL a\n"
+"                             redirect would have gone to. (Added in 7.18.2)\n"
+"\n"
+"              remote_ip      The remote IP address of the most  recently  done\n"
+"                             connection - can be either IPv4 or IPv6 (Added in\n"
+"                             7.29.0)\n"
+"\n"
+, stdout);
+ fputs(
+"              remote_port    The remote port number of the most recently  done\n"
+"                             connection (Added in 7.29.0)\n"
+"\n"
+"              scheme         The  URL  scheme (sometimes called protocol) that\n"
+"                             was effectively used (Added in 7.52.0)\n"
+"\n"
+"              size_download  The total amount of bytes that were downloaded.\n"
+"\n"
+"              size_header    The total amount of bytes of the downloaded head-\n"
+"                             ers.\n"
+"\n"
+, stdout);
+ fputs(
+"              size_request   The  total  amount of bytes that were sent in the\n"
+"                             HTTP request.\n"
+"\n"
+"              size_upload    The total amount of bytes that were uploaded.\n"
+"\n"
+"              speed_download The average download speed that curl measured for\n"
+"                             the complete download. Bytes per second.\n"
+"\n"
+"              speed_upload   The  average  upload speed that curl measured for\n"
+"                             the complete upload. Bytes per second.\n"
+"\n"
+, stdout);
+ fputs(
+"              ssl_verify_result\n"
+"                             The result of the SSL peer certificate  verifica-\n"
+"                             tion that was requested. 0 means the verification\n"
+"                             was successful. (Added in 7.19.0)\n"
+"\n"
+"              time_appconnect\n"
+"                             The time, in seconds,  it  took  from  the  start\n"
+"                             until  the  SSL/SSH/etc  connect/handshake to the\n"
+, stdout);
+ fputs(
+"                             remote host was completed. (Added in 7.19.0)\n"
+"\n"
+"              time_connect   The time, in seconds,  it  took  from  the  start\n"
+"                             until  the  TCP  connect  to  the remote host (or\n"
+"                             proxy) was completed.\n"
+"\n"
+"              time_namelookup\n"
+"                             The time, in seconds,  it  took  from  the  start\n"
+"                             until the name resolving was completed.\n"
+"\n"
+"              time_pretransfer\n"
+, stdout);
+ fputs(
+"                             The  time,  in  seconds,  it  took from the start\n"
+"                             until the file transfer was just about to  begin.\n"
+"                             This includes all pre-transfer commands and nego-\n"
+"                             tiations that are specific to the particular pro-\n"
+"                             tocol(s) involved.\n"
+"\n"
+"              time_redirect  The time, in seconds, it took for all redirection\n"
+, stdout);
+ fputs(
+"                             steps including name lookup, connect, pretransfer\n"
+"                             and  transfer  before  the  final transaction was\n"
+"                             started. time_redirect shows the complete  execu-\n"
+"                             tion  time  for  multiple redirections. (Added in\n"
+"                             7.12.3)\n"
+"\n"
+"              time_starttransfer\n"
+"                             The time, in seconds,  it  took  from  the  start\n"
+, stdout);
+ fputs(
+"                             until  the first byte was just about to be trans-\n"
+"                             ferred. This includes time_pretransfer  and  also\n"
+"                             the  time  the  server  needed  to  calculate the\n"
+"                             result.\n"
+"\n"
+"              time_total     The total time, in seconds, that the full  opera-\n"
+"                             tion lasted.\n"
+"\n"
+"              url_effective  The URL that was fetched last. This is most mean-\n"
+, stdout);
+ fputs(
+"                             ingful if you've told curl  to  follow  location:\n"
+"                             headers.\n"
+"\n"
+"              If this option is used several times, the last one will be used.\n"
+"\n"
+"       --xattr\n"
+"              When  saving  output  to a file, this option tells curl to store\n"
+"              certain file metadata in extended  file  attributes.  Currently,\n"
+"              the URL is stored in the xdg.origin.url attribute and, for HTTP,\n"
+, stdout);
+ fputs(
+"              the content type is stored in the mime_type  attribute.  If  the\n"
+"              file  system  does not support extended attributes, a warning is\n"
+"              issued.\n"
+"\n"
+"FILES\n"
+"       ~/.curlrc\n"
+"              Default config file, see -K, --config for details.\n"
+"\n"
+"ENVIRONMENT\n"
+"       The environment variables can be specified in lower case or upper case.\n"
+"       The lower case version has precedence. http_proxy is an exception as it\n"
+"       is only available in lower case.\n"
+"\n"
+, stdout);
+ fputs(
+"       Using an environment variable to set the proxy has the same  effect  as\n"
+"       using the -x, --proxy option.\n"
+"\n"
+"       http_proxy [protocol://]<host>[:port]\n"
+"              Sets the proxy server to use for HTTP.\n"
+"       HTTPS_PROXY [protocol://]<host>[:port]\n"
+"              Sets the proxy server to use for HTTPS.\n"
+"\n"
+"       [url-protocol]_PROXY [protocol://]<host>[:port]\n"
+"              Sets  the proxy server to use for [url-protocol], where the pro-\n"
+, stdout);
+ fputs(
+"              tocol is a protocol that curl supports and  as  specified  in  a\n"
+"              URL. FTP, FTPS, POP3, IMAP, SMTP, LDAP etc.\n"
+"\n"
+"       ALL_PROXY [protocol://]<host>[:port]\n"
+"              Sets  the  proxy  server to use if no protocol-specific proxy is\n"
+"              set.\n"
+"\n"
+"       NO_PROXY <comma-separated list of hosts>\n"
+"              list of host names that shouldn't go through any proxy.  If  set\n"
+"              to a asterisk '*' only, it matches all hosts.\n"
+"\n"
+, stdout);
+ fputs(
+"              Since  7.53.0,  this environment variable disable the proxy even\n"
+"              if specify -x, --proxy  option.  That  is  NO_PROXY=direct.exam-\n"
+"              ple.com  curl  -x  http://proxy.example.com  http://direct.exam-\n"
+"              ple.com    accesses    the    target    URL    directly,     and\n"
+"              NO_PROXY=direct.example.com   curl  -x  http://proxy.example.com\n"
+"              http://somewhere.example.com accesses  the  target  URL  through\n"
+"              proxy.\n"
+"\n"
+, stdout);
+ fputs(
+"PROXY PROTOCOL PREFIXES\n"
+"       Since  curl  version  7.21.7,  the proxy string may be specified with a\n"
+"       protocol:// prefix to specify alternative proxy protocols.\n"
+"\n"
+"       If no protocol is specified in  the  proxy  string  or  if  the  string\n"
+"       doesn't  match  a  supported  one, the proxy will be treated as an HTTP\n"
+"       proxy.\n"
+"\n"
+"       The supported proxy protocol prefixes are as follows:\n"
+"\n"
+"       socks4://\n"
+"              Makes it the equivalent of --socks4\n"
+"\n"
+"       socks4a://\n"
+, stdout);
+ fputs(
+"              Makes it the equivalent of --socks4a\n"
+"\n"
+"       socks5://\n"
+"              Makes it the equivalent of --socks5\n"
+"\n"
+"       socks5h://\n"
+"              Makes it the equivalent of --socks5-hostname\n"
+"\n"
+"EXIT CODES\n"
+"       There are a bunch of different  error  codes  and  their  corresponding\n"
+"       error  messages  that  may appear during bad conditions. At the time of\n"
+"       this writing, the exit codes are:\n"
+"\n"
+"       1      Unsupported protocol. This build of curl has no support for this\n"
+, stdout);
+ fputs(
+"              protocol.\n"
+"\n"
+"       2      Failed to initialize.\n"
+"\n"
+"       3      URL malformed. The syntax was not correct.\n"
+"\n"
+"       4      A  feature  or  option  that  was  needed to perform the desired\n"
+"              request was not enabled or was  explicitly  disabled  at  build-\n"
+"              time.  To  make  curl able to do this, you probably need another\n"
+"              build of libcurl!\n"
+"\n"
+"       5      Couldn't resolve proxy.  The  given  proxy  host  could  not  be\n"
+"              resolved.\n"
+"\n"
+, stdout);
+ fputs(
+"       6      Couldn't resolve host. The given remote host was not resolved.\n"
+"\n"
+"       7      Failed to connect to host.\n"
+"\n"
+"       8      Weird server reply. The server sent data curl couldn't parse.\n"
+"\n"
+"       9      FTP  access  denied. The server denied login or denied access to\n"
+"              the particular resource or directory you wanted to  reach.  Most\n"
+"              often  you  tried to change to a directory that doesn't exist on\n"
+"              the server.\n"
+"\n"
+, stdout);
+ fputs(
+"       10     FTP accept failed. While waiting for the server to connect  back\n"
+"              when  an active FTP session is used, an error code was sent over\n"
+"              the control connection or similar.\n"
+"\n"
+"       11     FTP weird PASS reply. Curl couldn't parse the reply sent to  the\n"
+"              PASS request.\n"
+"\n"
+"       12     During  an  active  FTP  session while waiting for the server to\n"
+"              connect back to curl, the timeout expired.\n"
+"\n"
+, stdout);
+ fputs(
+"       13     FTP weird PASV reply, Curl couldn't parse the reply sent to  the\n"
+"              PASV request.\n"
+"\n"
+"       14     FTP  weird  227  format.  Curl  couldn't  parse the 227-line the\n"
+"              server sent.\n"
+"\n"
+"       15     FTP can't get host. Couldn't resolve the host IP we got  in  the\n"
+"              227-line.\n"
+"\n"
+"       16     HTTP/2 error. A problem was detected in the HTTP2 framing layer.\n"
+"              This is somewhat generic and can be one out of several problems,\n"
+, stdout);
+ fputs(
+"              see the error message for details.\n"
+"\n"
+"       17     FTP  couldn't  set  binary.  Couldn't  change transfer method to\n"
+"              binary.\n"
+"\n"
+"       18     Partial file. Only a part of the file was transferred.\n"
+"\n"
+"       19     FTP couldn't download/access the given file, the RETR (or  simi-\n"
+"              lar) command failed.\n"
+"\n"
+"       21     FTP quote error. A quote command returned error from the server.\n"
+"       22     HTTP  page  not  retrieved.  The  requested url was not found or\n"
+, stdout);
+ fputs(
+"              returned another error with the HTTP error  code  being  400  or\n"
+"              above. This return code only appears if -f, --fail is used.\n"
+"\n"
+"       23     Write  error.  Curl couldn't write data to a local filesystem or\n"
+"              similar.\n"
+"\n"
+"       25     FTP couldn't STOR file. The server denied  the  STOR  operation,\n"
+"              used for FTP uploading.\n"
+"\n"
+"       26     Read error. Various reading problems.\n"
+"\n"
+"       27     Out of memory. A memory allocation request failed.\n"
+"\n"
+, stdout);
+ fputs(
+"       28     Operation  timeout.  The  specified  time-out period was reached\n"
+"              according to the conditions.\n"
+"\n"
+"       30     FTP PORT failed. The PORT command failed. Not  all  FTP  servers\n"
+"              support  the  PORT  command,  try  doing  a  transfer using PASV\n"
+"              instead!\n"
+"\n"
+"       31     FTP couldn't use REST. The REST command failed. This command  is\n"
+"              used for resumed FTP transfers.\n"
+"\n"
+"       33     HTTP range error. The range \"command\" didn't work.\n"
+"\n"
+, stdout);
+ fputs(
+"       34     HTTP post error. Internal post-request generation error.\n"
+"\n"
+"       35     SSL connect error. The SSL handshaking failed.\n"
+"\n"
+"       36     Bad  download resume. Couldn't continue an earlier aborted down-\n"
+"              load.\n"
+"\n"
+"       37     FILE couldn't read file. Failed to open the file. Permissions?\n"
+"\n"
+"       38     LDAP cannot bind. LDAP bind operation failed.\n"
+"\n"
+"       39     LDAP search failed.\n"
+"\n"
+"       41     Function not found. A required LDAP function was not found.\n"
+"\n"
+, stdout);
+ fputs(
+"       42     Aborted by callback. An application told curl to abort the oper-\n"
+"              ation.\n"
+"\n"
+"       43     Internal error. A function was called with a bad parameter.\n"
+"\n"
+"       45     Interface  error.  A  specified  outgoing interface could not be\n"
+"              used.\n"
+"\n"
+"       47     Too many redirects. When following redirects, curl hit the maxi-\n"
+"              mum amount.\n"
+"\n"
+"       48     Unknown  option  specified  to  libcurl. This indicates that you\n"
+, stdout);
+ fputs(
+"              passed a weird option to curl that was passed on to libcurl  and\n"
+"              rejected. Read up in the manual!\n"
+"\n"
+"       49     Malformed telnet option.\n"
+"\n"
+"       51     The peer's SSL certificate or SSH MD5 fingerprint was not OK.\n"
+"\n"
+"       52     The  server  didn't  reply anything, which here is considered an\n"
+"              error.\n"
+"\n"
+"       53     SSL crypto engine not found.\n"
+"\n"
+"       54     Cannot set SSL crypto engine as default.\n"
+"\n"
+"       55     Failed sending network data.\n"
+"\n"
+, stdout);
+ fputs(
+"       56     Failure in receiving network data.\n"
+"\n"
+"       58     Problem with the local certificate.\n"
+"\n"
+"       59     Couldn't use specified SSL cipher.\n"
+"\n"
+"       60     Peer certificate cannot be authenticated with known CA  certifi-\n"
+"              cates.\n"
+"\n"
+"       61     Unrecognized transfer encoding.\n"
+"\n"
+"       62     Invalid LDAP URL.\n"
+"\n"
+"       63     Maximum file size exceeded.\n"
+"\n"
+"       64     Requested FTP SSL level failed.\n"
+"\n"
+"       65     Sending the data requires a rewind that failed.\n"
+"\n"
+, stdout);
+ fputs(
+"       66     Failed to initialise SSL Engine.\n"
+"\n"
+"       67     The  user  name,  password, or similar was not accepted and curl\n"
+"              failed to log in.\n"
+"\n"
+"       68     File not found on TFTP server.\n"
+"\n"
+"       69     Permission problem on TFTP server.\n"
+"\n"
+"       70     Out of disk space on TFTP server.\n"
+"\n"
+"       71     Illegal TFTP operation.\n"
+"\n"
+"       72     Unknown TFTP transfer ID.\n"
+"\n"
+"       73     File already exists (TFTP).\n"
+"\n"
+"       74     No such user (TFTP).\n"
+"\n"
+, stdout);
+ fputs(
+"       75     Character conversion failed.\n"
+"\n"
+"       76     Character conversion functions required.\n"
+"\n"
+"       77     Problem with reading the SSL CA cert (path? access rights?).\n"
+"\n"
+"       78     The resource referenced in the URL does not exist.\n"
+"\n"
+"       79     An unspecified error occurred during the SSH session.\n"
+"\n"
+"       80     Failed to shut down the SSL connection.\n"
+"\n"
+"       82     Could not load CRL file,  missing  or  wrong  format  (added  in\n"
+"              7.19.0).\n"
+"\n"
+, stdout);
+ fputs(
+"       83     Issuer check failed (added in 7.19.0).\n"
+"\n"
+"       84     The FTP PRET command failed\n"
+"\n"
+"       85     RTSP: mismatch of CSeq numbers\n"
+"\n"
+"       86     RTSP: mismatch of Session Identifiers\n"
+"\n"
+"       87     unable to parse FTP file list\n"
+"\n"
+"       88     FTP chunk callback reported error\n"
+"\n"
+"       89     No connection available, the session will be queued\n"
+"\n"
+"       90     SSL public key does not matched pinned public key\n"
+"\n"
+, stdout);
+ fputs(
+"       XX     More error codes will appear here in future releases. The exist-\n"
+"              ing ones are meant to never change.\n"
+"\n"
+"AUTHORS / CONTRIBUTORS\n"
+"       Daniel Stenberg is the main author, but the whole list of  contributors\n"
+"       is found in the separate THANKS file.\n"
+"\n"
+"WWW\n"
+"       https://curl.haxx.se\n"
+"\n"
+"SEE ALSO\n"
+"       ftp(1), wget(1)\n"
+"\n"
+"LATEST VERSION\n"
+"\n"
+"  You always find news about what's going on as well as the latest versions\n"
+"  from the curl web pages, located at:\n"
+"\n"
+, stdout);
+ fputs(
+"        https://curl.haxx.se\n"
+"\n"
+"SIMPLE USAGE\n"
+"\n"
+"  Get the main page from Netscape's web-server:\n"
+"\n"
+"        curl http://www.netscape.com/\n"
+"\n"
+"  Get the README file the user's home directory at funet's ftp-server:\n"
+"\n"
+"        curl ftp://ftp.funet.fi/README\n"
+"\n"
+"  Get a web page from a server using port 8000:\n"
+"\n"
+"        curl http://www.weirdserver.com:8000/\n"
+"\n"
+"  Get a directory listing of an FTP site:\n"
+"\n"
+"        curl ftp://cool.haxx.se/\n"
+"\n"
+"  Get the definition of curl from a dictionary:\n"
+"\n"
+, stdout);
+ fputs(
+"        curl dict://dict.org/m:curl\n"
+"\n"
+"  Fetch two documents at once:\n"
+"\n"
+"        curl ftp://cool.haxx.se/ http://www.weirdserver.com:8000/\n"
+"\n"
+"  Get a file off an FTPS server:\n"
+"\n"
+"        curl ftps://files.are.secure.com/secrets.txt\n"
+"\n"
+"  or use the more appropriate FTPS way to get the same file:\n"
+"\n"
+"        curl --ftp-ssl ftp://files.are.secure.com/secrets.txt\n"
+"\n"
+"  Get a file from an SSH server using SFTP:\n"
+"\n"
+"        curl -u username sftp://example.com/etc/issue\n"
+"\n"
+, stdout);
+ fputs(
+"  Get a file from an SSH server using SCP using a private key\n"
+"  (not password-protected) to authenticate:\n"
+"\n"
+"        curl -u username: --key ~/.ssh/id_rsa \\\n"
+"             scp://example.com/~/file.txt\n"
+"\n"
+"  Get a file from an SSH server using SCP using a private key\n"
+"  (password-protected) to authenticate:\n"
+"\n"
+"        curl -u username: --key ~/.ssh/id_rsa --pass private_key_password \\\n"
+"             scp://example.com/~/file.txt\n"
+"\n"
+"  Get the main page from an IPv6 web server:\n"
+"\n"
+, stdout);
+ fputs(
+"        curl \"http://[2001:1890:1112:1::20]/\"\n"
+"\n"
+"  Get a file from an SMB server:\n"
+"\n"
+"        curl -u \"domain\\username:passwd\" smb://server.example.com/share/file.txt\n"
+"\n"
+"DOWNLOAD TO A FILE\n"
+"\n"
+"  Get a web page and store in a local file with a specific name:\n"
+"\n"
+"        curl -o thatpage.html http://www.netscape.com/\n"
+"\n"
+"  Get a web page and store in a local file, make the local file get the name\n"
+"  of the remote document (if no file name part is specified in the URL, this\n"
+"  will fail):\n"
+"\n"
+, stdout);
+ fputs(
+"        curl -O http://www.netscape.com/index.html\n"
+"\n"
+"  Fetch two files and store them with their remote names:\n"
+"\n"
+"        curl -O www.haxx.se/index.html -O curl.haxx.se/download.html\n"
+"\n"
+"USING PASSWORDS\n"
+"\n"
+" FTP\n"
+"\n"
+"   To ftp files using name+passwd, include them in the URL like:\n"
+"\n"
+"        curl ftp://name:passwd@machine.domain:port/full/path/to/file\n"
+"\n"
+"   or specify them with the -u flag like\n"
+"\n"
+"        curl -u name:passwd ftp://machine.domain:port/full/path/to/file\n"
+"\n"
+" FTPS\n"
+"\n"
+, stdout);
+ fputs(
+"   It is just like for FTP, but you may also want to specify and use\n"
+"   SSL-specific options for certificates etc.\n"
+"\n"
+"   Note that using FTPS:// as prefix is the \"implicit\" way as described in the\n"
+"   standards while the recommended \"explicit\" way is done by using FTP:// and\n"
+"   the --ftp-ssl option.\n"
+"\n"
+" SFTP / SCP\n"
+"\n"
+"   This is similar to FTP, but you can use the --key option to specify a\n"
+"   private key to use instead of a password. Note that the private key may\n"
+, stdout);
+ fputs(
+"   itself be protected by a password that is unrelated to the login password\n"
+"   of the remote system; this password is specified using the --pass option.\n"
+"   Typically, curl will automatically extract the public key from the private\n"
+"   key file, but in cases where curl does not have the proper library support,\n"
+"   a matching public key file must be specified using the --pubkey option.\n"
+"\n"
+" HTTP\n"
+"\n"
+"   Curl also supports user and password in HTTP URLs, thus you can pick a file\n"
+"   like:\n"
+"\n"
+, stdout);
+ fputs(
+"        curl http://name:passwd@machine.domain/full/path/to/file\n"
+"\n"
+"   or specify user and password separately like in\n"
+"\n"
+"        curl -u name:passwd http://machine.domain/full/path/to/file\n"
+"\n"
+"   HTTP offers many different methods of authentication and curl supports\n"
+"   several: Basic, Digest, NTLM and Negotiate (SPNEGO). Without telling which\n"
+"   method to use, curl defaults to Basic. You can also ask curl to pick the\n"
+"   most secure ones out of the ones that the server accepts for the given URL,\n"
+, stdout);
+ fputs(
+"   by using --anyauth.\n"
+"\n"
+"   NOTE! According to the URL specification, HTTP URLs can not contain a user\n"
+"   and password, so that style will not work when using curl via a proxy, even\n"
+"   though curl allows it at other times. When using a proxy, you _must_ use\n"
+"   the -u style for user and password.\n"
+"\n"
+" HTTPS\n"
+"\n"
+"   Probably most commonly used with private certificates, as explained below.\n"
+"\n"
+"PROXY\n"
+"\n"
+" curl supports both HTTP and SOCKS proxy servers, with optional authentication.\n"
+, stdout);
+ fputs(
+" It does not have special support for FTP proxy servers since there are no\n"
+" standards for those, but it can still be made to work with many of them. You\n"
+" can also use both HTTP and SOCKS proxies to transfer files to and from FTP\n"
+" servers.\n"
+"\n"
+" Get an ftp file using an HTTP proxy named my-proxy that uses port 888:\n"
+"\n"
+"        curl -x my-proxy:888 ftp://ftp.leachsite.com/README\n"
+"\n"
+" Get a file from an HTTP server that requires user and password, using the\n"
+" same proxy as above:\n"
+"\n"
+, stdout);
+ fputs(
+"        curl -u user:passwd -x my-proxy:888 http://www.get.this/\n"
+"\n"
+" Some proxies require special authentication. Specify by using -U as above:\n"
+"\n"
+"        curl -U user:passwd -x my-proxy:888 http://www.get.this/\n"
+"\n"
+" A comma-separated list of hosts and domains which do not use the proxy can\n"
+" be specified as:\n"
+"\n"
+"        curl --noproxy localhost,get.this -x my-proxy:888 http://www.get.this/\n"
+"\n"
+" If the proxy is specified with --proxy1.0 instead of --proxy or -x, then\n"
+, stdout);
+ fputs(
+" curl will use HTTP/1.0 instead of HTTP/1.1 for any CONNECT attempts.\n"
+"\n"
+" curl also supports SOCKS4 and SOCKS5 proxies with --socks4 and --socks5.\n"
+"\n"
+" See also the environment variables Curl supports that offer further proxy\n"
+" control.\n"
+"\n"
+" Most FTP proxy servers are set up to appear as a normal FTP server from the\n"
+" client's perspective, with special commands to select the remote FTP server.\n"
+" curl supports the -u, -Q and --ftp-account options that can be used to\n"
+, stdout);
+ fputs(
+" set up transfers through many FTP proxies. For example, a file can be\n"
+" uploaded to a remote FTP server using a Blue Coat FTP proxy with the\n"
+" options:\n"
+"\n"
+"   curl -u \"Remote-FTP-Username@remote.ftp.server Proxy-Username:Remote-Pass\" \\\n"
+"    --ftp-account Proxy-Password --upload-file local-file \\\n"
+"    ftp://my-ftp.proxy.server:21/remote/upload/path/\n"
+"\n"
+" See the manual for your FTP proxy to determine the form it expects to set up\n"
+" transfers, and curl's -v option to see exactly what curl is sending.\n"
+"\n"
+, stdout);
+ fputs(
+"RANGES\n"
+"\n"
+"  HTTP 1.1 introduced byte-ranges. Using this, a client can request\n"
+"  to get only one or more subparts of a specified document. Curl supports\n"
+"  this with the -r flag.\n"
+"\n"
+"  Get the first 100 bytes of a document:\n"
+"\n"
+"        curl -r 0-99 http://www.get.this/\n"
+"\n"
+"  Get the last 500 bytes of a document:\n"
+"\n"
+"        curl -r -500 http://www.get.this/\n"
+"\n"
+"  Curl also supports simple ranges for FTP files as well. Then you can only\n"
+"  specify start and stop position.\n"
+"\n"
+, stdout);
+ fputs(
+"  Get the first 100 bytes of a document using FTP:\n"
+"\n"
+"        curl -r 0-99 ftp://www.get.this/README\n"
+"\n"
+"UPLOADING\n"
+"\n"
+" FTP / FTPS / SFTP / SCP\n"
+"\n"
+"  Upload all data on stdin to a specified server:\n"
+"\n"
+"        curl -T - ftp://ftp.upload.com/myfile\n"
+"\n"
+"  Upload data from a specified file, login with user and password:\n"
+"\n"
+"        curl -T uploadfile -u user:passwd ftp://ftp.upload.com/myfile\n"
+"\n"
+"  Upload a local file to the remote site, and use the local file name at the remote\n"
+"  site too:\n"
+"\n"
+, stdout);
+ fputs(
+"        curl -T uploadfile -u user:passwd ftp://ftp.upload.com/\n"
+"\n"
+"  Upload a local file to get appended to the remote file:\n"
+"\n"
+"        curl -T localfile -a ftp://ftp.upload.com/remotefile\n"
+"\n"
+"  Curl also supports ftp upload through a proxy, but only if the proxy is\n"
+"  configured to allow that kind of tunneling. If it does, you can run curl in\n"
+"  a fashion similar to:\n"
+"\n"
+"        curl --proxytunnel -x proxy:port -T localfile ftp.upload.com\n"
+"\n"
+"SMB / SMBS\n"
+"\n"
+"        curl -T file.txt -u \"domain\\username:passwd\" \n"
+, stdout);
+ fputs(
+"         smb://server.example.com/share/\n"
+"\n"
+" HTTP\n"
+"\n"
+"  Upload all data on stdin to a specified HTTP site:\n"
+"\n"
+"        curl -T - http://www.upload.com/myfile\n"
+"\n"
+"  Note that the HTTP server must have been configured to accept PUT before\n"
+"  this can be done successfully.\n"
+"\n"
+"  For other ways to do HTTP data upload, see the POST section below.\n"
+"\n"
+"VERBOSE / DEBUG\n"
+"\n"
+"  If curl fails where it isn't supposed to, if the servers don't let you in,\n"
+"  if you can't understand the responses: use the -v flag to get verbose\n"
+, stdout);
+ fputs(
+"  fetching. Curl will output lots of info and what it sends and receives in\n"
+"  order to let the user see all client-server interaction (but it won't show\n"
+"  you the actual data).\n"
+"\n"
+"        curl -v ftp://ftp.upload.com/\n"
+"\n"
+"  To get even more details and information on what curl does, try using the\n"
+"  --trace or --trace-ascii options with a given file name to log to, like\n"
+"  this:\n"
+"\n"
+"        curl --trace trace.txt www.haxx.se\n"
+"\n"
+"\n"
+"DETAILED INFORMATION\n"
+"\n"
+, stdout);
+ fputs(
+"  Different protocols provide different ways of getting detailed information\n"
+"  about specific files/documents. To get curl to show detailed information\n"
+"  about a single file, you should use -I/--head option. It displays all\n"
+"  available info on a single file for HTTP and FTP. The HTTP information is a\n"
+"  lot more extensive.\n"
+"\n"
+"  For HTTP, you can get the header information (the same as -I would show)\n"
+"  shown before the data by using -i/--include. Curl understands the\n"
+, stdout);
+ fputs(
+"  -D/--dump-header option when getting files from both FTP and HTTP, and it\n"
+"  will then store the headers in the specified file.\n"
+"\n"
+"  Store the HTTP headers in a separate file (headers.txt in the example):\n"
+"\n"
+"        curl --dump-header headers.txt curl.haxx.se\n"
+"\n"
+"  Note that headers stored in a separate file can be very useful at a later\n"
+"  time if you want curl to use cookies sent by the server. More about that in\n"
+"  the cookies section.\n"
+"\n"
+"POST (HTTP)\n"
+"\n"
+, stdout);
+ fputs(
+"  It's easy to post data using curl. This is done using the -d <data>\n"
+"  option.  The post data must be urlencoded.\n"
+"\n"
+"  Post a simple \"name\" and \"phone\" guestbook.\n"
+"\n"
+"        curl -d \"name=Rafael%20Sagula&phone=3320780\" \\\n"
+"                http://www.where.com/guest.cgi\n"
+"\n"
+"  How to post a form with curl, lesson #1:\n"
+"\n"
+"  Dig out all the <input> tags in the form that you want to fill in. (There's\n"
+"  a perl program called formfind.pl on the curl site that helps with this).\n"
+"\n"
+, stdout);
+ fputs(
+"  If there's a \"normal\" post, you use -d to post. -d takes a full \"post\n"
+"  string\", which is in the format\n"
+"\n"
+"        <variable1>=<data1>&<variable2>=<data2>&...\n"
+"\n"
+"  The 'variable' names are the names set with \"name=\" in the <input> tags, and\n"
+"  the data is the contents you want to fill in for the inputs. The data *must*\n"
+"  be properly URL encoded. That means you replace space with + and that you\n"
+"  replace weird letters with %XX where XX is the hexadecimal representation of\n"
+, stdout);
+ fputs(
+"  the letter's ASCII code.\n"
+"\n"
+"  Example:\n"
+"\n"
+"  (page located at http://www.formpost.com/getthis/\n"
+"\n"
+"        <form action=\"post.cgi\" method=\"post\">\n"
+"        <input name=user size=10>\n"
+"        <input name=pass type=password size=10>\n"
+"        <input name=id type=hidden value=\"blablabla\">\n"
+"        <input name=ding value=\"submit\">\n"
+"        </form>\n"
+"\n"
+"  We want to enter user 'foobar' with password '12345'.\n"
+"\n"
+"  To post to this, you enter a curl command line like:\n"
+"\n"
+, stdout);
+ fputs(
+"        curl -d \"user=foobar&pass=12345&id=blablabla&ding=submit\"  (continues)\n"
+"          http://www.formpost.com/getthis/post.cgi\n"
+"\n"
+"\n"
+"  While -d uses the application/x-www-form-urlencoded mime-type, generally\n"
+"  understood by CGI's and similar, curl also supports the more capable\n"
+"  multipart/form-data type. This latter type supports things like file upload.\n"
+"\n"
+"  -F accepts parameters like -F \"name=contents\". If you want the contents to\n"
+, stdout);
+ fputs(
+"  be read from a file, use <@filename> as contents. When specifying a file,\n"
+"  you can also specify the file content type by appending ';type=<mime type>'\n"
+"  to the file name. You can also post the contents of several files in one\n"
+"  field.  For example, the field name 'coolfiles' is used to send three files,\n"
+"  with different content types using the following syntax:\n"
+"\n"
+"        curl -F \"coolfiles=@fil1.gif;type=image/gif,fil2.txt,fil3.html\" \\\n"
+"        http://www.post.com/postit.cgi\n"
+"\n"
+, stdout);
+ fputs(
+"  If the content-type is not specified, curl will try to guess from the file\n"
+"  extension (it only knows a few), or use the previously specified type (from\n"
+"  an earlier file if several files are specified in a list) or else it will\n"
+"  use the default type 'application/octet-stream'.\n"
+"\n"
+"  Emulate a fill-in form with -F. Let's say you fill in three fields in a\n"
+"  form. One field is a file name which to post, one field is your name and one\n"
+, stdout);
+ fputs(
+"  field is a file description. We want to post the file we have written named\n"
+"  \"cooltext.txt\". To let curl do the posting of this data instead of your\n"
+"  favourite browser, you have to read the HTML source of the form page and\n"
+"  find the names of the input fields. In our example, the input field names\n"
+"  are 'file', 'yourname' and 'filedescription'.\n"
+"\n"
+"        curl -F \"file=@cooltext.txt\" -F \"yourname=Daniel\" \\\n"
+"             -F \"filedescription=Cool text file with cool text inside\" \\\n"
+, stdout);
+ fputs(
+"             http://www.post.com/postit.cgi\n"
+"\n"
+"  To send two files in one post you can do it in two ways:\n"
+"\n"
+"  1. Send multiple files in a single \"field\" with a single field name:\n"
+"\n"
+"        curl -F \"pictures=@dog.gif,cat.gif\"\n"
+"\n"
+"  2. Send two fields with two field names:\n"
+"\n"
+"        curl -F \"docpicture=@dog.gif\" -F \"catpicture=@cat.gif\"\n"
+"\n"
+"  To send a field value literally without interpreting a leading '@'\n"
+"  or '<', or an embedded ';type=', use --form-string instead of\n"
+, stdout);
+ fputs(
+"  -F. This is recommended when the value is obtained from a user or\n"
+"  some other unpredictable source. Under these circumstances, using\n"
+"  -F instead of --form-string would allow a user to trick curl into\n"
+"  uploading a file.\n"
+"\n"
+"REFERRER\n"
+"\n"
+"  An HTTP request has the option to include information about which address\n"
+"  referred it to the actual page.  Curl allows you to specify the\n"
+"  referrer to be used on the command line. It is especially useful to\n"
+, stdout);
+ fputs(
+"  fool or trick stupid servers or CGI scripts that rely on that information\n"
+"  being available or contain certain data.\n"
+"\n"
+"        curl -e www.coolsite.com http://www.showme.com/\n"
+"\n"
+"  NOTE: The Referer: [sic] field is defined in the HTTP spec to be a full URL.\n"
+"\n"
+"USER AGENT\n"
+"\n"
+"  An HTTP request has the option to include information about the browser\n"
+"  that generated the request. Curl allows it to be specified on the command\n"
+"  line. It is especially useful to fool or trick stupid servers or CGI\n"
+, stdout);
+ fputs(
+"  scripts that only accept certain browsers.\n"
+"\n"
+"  Example:\n"
+"\n"
+"  curl -A 'Mozilla/3.0 (Win95; I)' http://www.nationsbank.com/\n"
+"\n"
+"  Other common strings:\n"
+"    'Mozilla/3.0 (Win95; I)'     Netscape Version 3 for Windows 95\n"
+"    'Mozilla/3.04 (Win95; U)'    Netscape Version 3 for Windows 95\n"
+"    'Mozilla/2.02 (OS/2; U)'     Netscape Version 2 for OS/2\n"
+"    'Mozilla/4.04 [en] (X11; U; AIX 4.2; Nav)'           NS for AIX\n"
+"    'Mozilla/4.05 [en] (X11; U; Linux 2.0.32 i586)'      NS for Linux\n"
+"\n"
+, stdout);
+ fputs(
+"  Note that Internet Explorer tries hard to be compatible in every way:\n"
+"    'Mozilla/4.0 (compatible; MSIE 4.01; Windows 95)'    MSIE for W95\n"
+"\n"
+"  Mozilla is not the only possible User-Agent name:\n"
+"    'Konqueror/1.0'             KDE File Manager desktop client\n"
+"    'Lynx/2.7.1 libwww-FM/2.14' Lynx command line browser\n"
+"\n"
+"COOKIES\n"
+"\n"
+"  Cookies are generally used by web servers to keep state information at the\n"
+"  client's side. The server sets cookies by sending a response line in the\n"
+, stdout);
+ fputs(
+"  headers that looks like 'Set-Cookie: <data>' where the data part then\n"
+"  typically contains a set of NAME=VALUE pairs (separated by semicolons ';'\n"
+"  like \"NAME1=VALUE1; NAME2=VALUE2;\"). The server can also specify for what\n"
+"  path the \"cookie\" should be used for (by specifying \"path=value\"), when the\n"
+"  cookie should expire (\"expire=DATE\"), for what domain to use it\n"
+"  (\"domain=NAME\") and if it should be used on secure connections only\n"
+"  (\"secure\").\n"
+"\n"
+, stdout);
+ fputs(
+"  If you've received a page from a server that contains a header like:\n"
+"        Set-Cookie: sessionid=boo123; path=\"/foo\";\n"
+"\n"
+"  it means the server wants that first pair passed on when we get anything in\n"
+"  a path beginning with \"/foo\".\n"
+"\n"
+"  Example, get a page that wants my name passed in a cookie:\n"
+"\n"
+"        curl -b \"name=Daniel\" www.sillypage.com\n"
+"\n"
+"  Curl also has the ability to use previously received cookies in following\n"
+"  sessions. If you get cookies from a server and store them in a file in a\n"
+, stdout);
+ fputs(
+"  manner similar to:\n"
+"\n"
+"        curl --dump-header headers www.example.com\n"
+"\n"
+"  ... you can then in a second connect to that (or another) site, use the\n"
+"  cookies from the 'headers' file like:\n"
+"\n"
+"        curl -b headers www.example.com\n"
+"\n"
+"  While saving headers to a file is a working way to store cookies, it is\n"
+"  however error-prone and not the preferred way to do this. Instead, make curl\n"
+"  save the incoming cookies using the well-known netscape cookie format like\n"
+"  this:\n"
+"\n"
+, stdout);
+ fputs(
+"        curl -c cookies.txt www.example.com\n"
+"\n"
+"  Note that by specifying -b you enable the \"cookie awareness\" and with -L\n"
+"  you can make curl follow a location: (which often is used in combination\n"
+"  with cookies). So that if a site sends cookies and a location, you can\n"
+"  use a non-existing file to trigger the cookie awareness like:\n"
+"\n"
+"        curl -L -b empty.txt www.example.com\n"
+"\n"
+"  The file to read cookies from must be formatted using plain HTTP headers OR\n"
+, stdout);
+ fputs(
+"  as netscape's cookie file. Curl will determine what kind it is based on the\n"
+"  file contents.  In the above command, curl will parse the header and store\n"
+"  the cookies received from www.example.com.  curl will send to the server the\n"
+"  stored cookies which match the request as it follows the location.  The\n"
+"  file \"empty.txt\" may be a nonexistent file.\n"
+"\n"
+"  To read and write cookies from a netscape cookie file, you can set both -b\n"
+"  and -c to use the same file:\n"
+"\n"
+, stdout);
+ fputs(
+"        curl -b cookies.txt -c cookies.txt www.example.com\n"
+"\n"
+"PROGRESS METER\n"
+"\n"
+"  The progress meter exists to show a user that something actually is\n"
+"  happening. The different fields in the output have the following meaning:\n"
+"\n"
+"  % Total    % Received % Xferd  Average Speed          Time             Curr.\n"
+"                                 Dload  Upload Total    Current  Left    Speed\n"
+"  0  151M    0 38608    0     0   9406      0  4:41:43  0:00:04  4:41:39  9287\n"
+"\n"
+"  From left-to-right:\n"
+, stdout);
+ fputs(
+"   %             - percentage completed of the whole transfer\n"
+"   Total         - total size of the whole expected transfer\n"
+"   %             - percentage completed of the download\n"
+"   Received      - currently downloaded amount of bytes\n"
+"   %             - percentage completed of the upload\n"
+"   Xferd         - currently uploaded amount of bytes\n"
+"   Average Speed\n"
+"   Dload         - the average transfer speed of the download\n"
+"   Average Speed\n"
+"   Upload        - the average transfer speed of the upload\n"
+, stdout);
+ fputs(
+"   Time Total    - expected time to complete the operation\n"
+"   Time Current  - time passed since the invoke\n"
+"   Time Left     - expected time left to completion\n"
+"   Curr.Speed    - the average transfer speed the last 5 seconds (the first\n"
+"                   5 seconds of a transfer is based on less time of course.)\n"
+"\n"
+"  The -# option will display a totally different progress bar that doesn't\n"
+"  need much explanation!\n"
+"\n"
+"SPEED LIMIT\n"
+"\n"
+, stdout);
+ fputs(
+"  Curl allows the user to set the transfer speed conditions that must be met\n"
+"  to let the transfer keep going. By using the switch -y and -Y you\n"
+"  can make curl abort transfers if the transfer speed is below the specified\n"
+"  lowest limit for a specified time.\n"
+"\n"
+"  To have curl abort the download if the speed is slower than 3000 bytes per\n"
+"  second for 1 minute, run:\n"
+"\n"
+"        curl -Y 3000 -y 60 www.far-away-site.com\n"
+"\n"
+"  This can very well be used in combination with the overall time limit, so\n"
+, stdout);
+ fputs(
+"  that the above operation must be completed in whole within 30 minutes:\n"
+"\n"
+"        curl -m 1800 -Y 3000 -y 60 www.far-away-site.com\n"
+"\n"
+"  Forcing curl not to transfer data faster than a given rate is also possible,\n"
+"  which might be useful if you're using a limited bandwidth connection and you\n"
+"  don't want your transfer to use all of it (sometimes referred to as\n"
+"  \"bandwidth throttle\").\n"
+"\n"
+"  Make curl transfer data no faster than 10 kilobytes per second:\n"
+"\n"
+, stdout);
+ fputs(
+"        curl --limit-rate 10K www.far-away-site.com\n"
+"\n"
+"    or\n"
+"\n"
+"        curl --limit-rate 10240 www.far-away-site.com\n"
+"\n"
+"  Or prevent curl from uploading data faster than 1 megabyte per second:\n"
+"\n"
+"        curl -T upload --limit-rate 1M ftp://uploadshereplease.com\n"
+"\n"
+"  When using the --limit-rate option, the transfer rate is regulated on a\n"
+"  per-second basis, which will cause the total transfer speed to become lower\n"
+"  than the given number. Sometimes of course substantially lower, if your\n"
+, stdout);
+ fputs(
+"  transfer stalls during periods.\n"
+"\n"
+"CONFIG FILE\n"
+"\n"
+"  Curl automatically tries to read the .curlrc file (or _curlrc file on win32\n"
+"  systems) from the user's home dir on startup.\n"
+"\n"
+"  The config file could be made up with normal command line switches, but you\n"
+"  can also specify the long options without the dashes to make it more\n"
+"  readable. You can separate the options and the parameter with spaces, or\n"
+"  with = or :. Comments can be used within the file. If the first letter on a\n"
+, stdout);
+ fputs(
+"  line is a '#'-symbol the rest of the line is treated as a comment.\n"
+"\n"
+"  If you want the parameter to contain spaces, you must enclose the entire\n"
+"  parameter within double quotes (\"). Within those quotes, you specify a\n"
+"  quote as \\\".\n"
+"\n"
+"  NOTE: You must specify options and their arguments on the same line.\n"
+"\n"
+"  Example, set default time out and proxy in a config file:\n"
+"\n"
+"        # We want a 30 minute timeout:\n"
+"        -m 1800\n"
+"        # ... and we use a proxy for all accesses:\n"
+, stdout);
+ fputs(
+"        proxy = proxy.our.domain.com:8080\n"
+"\n"
+"  White spaces ARE significant at the end of lines, but all white spaces\n"
+"  leading up to the first characters of each line are ignored.\n"
+"\n"
+"  Prevent curl from reading the default file by using -q as the first command\n"
+"  line parameter, like:\n"
+"\n"
+"        curl -q www.thatsite.com\n"
+"\n"
+"  Force curl to get and display a local help page in case it is invoked\n"
+"  without URL by making a config file similar to:\n"
+"\n"
+"        # default url to get\n"
+, stdout);
+ fputs(
+"        url = \"http://help.with.curl.com/curlhelp.html\"\n"
+"\n"
+"  You can specify another config file to be read by using the -K/--config\n"
+"  flag. If you set config file name to \"-\" it'll read the config from stdin,\n"
+"  which can be handy if you want to hide options from being visible in process\n"
+"  tables etc:\n"
+"\n"
+"        echo \"user = user:passwd\" | curl -K - http://that.secret.site.com\n"
+"\n"
+"EXTRA HEADERS\n"
+"\n"
+"  When using curl in your own very special programs, you may end up needing\n"
+, stdout);
+ fputs(
+"  to pass on your own custom headers when getting a web page. You can do\n"
+"  this by using the -H flag.\n"
+"\n"
+"  Example, send the header \"X-you-and-me: yes\" to the server when getting a\n"
+"  page:\n"
+"\n"
+"        curl -H \"X-you-and-me: yes\" www.love.com\n"
+"\n"
+"  This can also be useful in case you want curl to send a different text in a\n"
+"  header than it normally does. The -H header you specify then replaces the\n"
+"  header curl would normally send. If you replace an internal header with an\n"
+, stdout);
+ fputs(
+"  empty one, you prevent that header from being sent. To prevent the Host:\n"
+"  header from being used:\n"
+"\n"
+"        curl -H \"Host:\" www.server.com\n"
+"\n"
+"FTP and PATH NAMES\n"
+"\n"
+"  Do note that when getting files with the ftp:// URL, the given path is\n"
+"  relative the directory you enter. To get the file 'README' from your home\n"
+"  directory at your ftp site, do:\n"
+"\n"
+"        curl ftp://user:passwd@my.site.com/README\n"
+"\n"
+"  But if you want the README file from the root directory of that very same\n"
+, stdout);
+ fputs(
+"  site, you need to specify the absolute file name:\n"
+"\n"
+"        curl ftp://user:passwd@my.site.com//README\n"
+"\n"
+"  (I.e with an extra slash in front of the file name.)\n"
+"\n"
+"SFTP and SCP and PATH NAMES\n"
+"\n"
+"  With sftp: and scp: URLs, the path name given is the absolute name on the\n"
+"  server. To access a file relative to the remote user's home directory,\n"
+"  prefix the file with /~/ , such as:\n"
+"\n"
+"        curl -u $USER sftp://home.example.com/~/.bashrc\n"
+"\n"
+"FTP and firewalls\n"
+"\n"
+, stdout);
+ fputs(
+"  The FTP protocol requires one of the involved parties to open a second\n"
+"  connection as soon as data is about to get transferred. There are two ways to\n"
+"  do this.\n"
+"\n"
+"  The default way for curl is to issue the PASV command which causes the\n"
+"  server to open another port and await another connection performed by the\n"
+"  client. This is good if the client is behind a firewall that doesn't allow\n"
+"  incoming connections.\n"
+"\n"
+"        curl ftp.download.com\n"
+"\n"
+, stdout);
+ fputs(
+"  If the server, for example, is behind a firewall that doesn't allow connections\n"
+"  on ports other than 21 (or if it just doesn't support the PASV command), the\n"
+"  other way to do it is to use the PORT command and instruct the server to\n"
+"  connect to the client on the given IP number and port (as parameters to the\n"
+"  PORT command).\n"
+"\n"
+"  The -P flag to curl supports a few different options. Your machine may have\n"
+"  several IP-addresses and/or network interfaces and curl allows you to select\n"
+, stdout);
+ fputs(
+"  which of them to use. Default address can also be used:\n"
+"\n"
+"        curl -P - ftp.download.com\n"
+"\n"
+"  Download with PORT but use the IP address of our 'le0' interface (this does\n"
+"  not work on windows):\n"
+"\n"
+"        curl -P le0 ftp.download.com\n"
+"\n"
+"  Download with PORT but use 192.168.0.10 as our IP address to use:\n"
+"\n"
+"        curl -P 192.168.0.10 ftp.download.com\n"
+"\n"
+"NETWORK INTERFACE\n"
+"\n"
+"  Get a web page from a server using a specified port for the interface:\n"
+"\n"
+, stdout);
+ fputs(
+"        curl --interface eth0:1 http://www.netscape.com/\n"
+"\n"
+"  or\n"
+"\n"
+"        curl --interface 192.168.1.10 http://www.netscape.com/\n"
+"\n"
+"HTTPS\n"
+"\n"
+"  Secure HTTP requires SSL libraries to be installed and used when curl is\n"
+"  built. If that is done, curl is capable of retrieving and posting documents\n"
+"  using the HTTPS protocol.\n"
+"\n"
+"  Example:\n"
+"\n"
+"        curl https://www.secure-site.com\n"
+"\n"
+"  Curl is also capable of using your personal certificates to get/post files\n"
+, stdout);
+ fputs(
+"  from sites that require valid certificates. The only drawback is that the\n"
+"  certificate needs to be in PEM-format. PEM is a standard and open format to\n"
+"  store certificates with, but it is not used by the most commonly used\n"
+"  browsers (Netscape and MSIE both use the so called PKCS#12 format). If you\n"
+"  want curl to use the certificates you use with your (favourite) browser, you\n"
+"  may need to download/compile a converter that can convert your browser's\n"
+, stdout);
+ fputs(
+"  formatted certificates to PEM formatted ones. This kind of converter is\n"
+"  included in recent versions of OpenSSL, and for older versions Dr Stephen\n"
+"  N. Henson has written a patch for SSLeay that adds this functionality. You\n"
+"  can get his patch (that requires an SSLeay installation) from his site at:\n"
+"  http://www.drh-consultancy.demon.co.uk/\n"
+"\n"
+"  Example on how to automatically retrieve a document using a certificate with\n"
+"  a personal password:\n"
+"\n"
+, stdout);
+ fputs(
+"        curl -E /path/to/cert.pem:password https://secure.site.com/\n"
+"\n"
+"  If you neglect to specify the password on the command line, you will be\n"
+"  prompted for the correct password before any data can be received.\n"
+"\n"
+"  Many older SSL-servers have problems with SSLv3 or TLS, which newer versions\n"
+"  of OpenSSL etc use, therefore it is sometimes useful to specify what\n"
+"  SSL-version curl should use. Use -3, -2 or -1 to specify that exact SSL\n"
+"  version to use (for SSLv3, SSLv2 or TLSv1 respectively):\n"
+"\n"
+, stdout);
+ fputs(
+"        curl -2 https://secure.site.com/\n"
+"\n"
+"  Otherwise, curl will first attempt to use v3 and then v2.\n"
+"\n"
+"  To use OpenSSL to convert your favourite browser's certificate into a PEM\n"
+"  formatted one that curl can use, do something like this:\n"
+"\n"
+"    In Netscape, you start with hitting the 'Security' menu button.\n"
+"\n"
+"    Select 'certificates->yours' and then pick a certificate in the list\n"
+"\n"
+"    Press the 'Export' button\n"
+"\n"
+"    enter your PIN code for the certs\n"
+"\n"
+"    select a proper place to save it\n"
+"\n"
+, stdout);
+ fputs(
+"    Run the 'openssl' application to convert the certificate. If you cd to the\n"
+"    openssl installation, you can do it like:\n"
+"\n"
+"     # ./apps/openssl pkcs12 -in [file you saved] -clcerts -out [PEMfile]\n"
+"\n"
+"    In Firefox, select Options, then Advanced, then the Encryption tab,\n"
+"    View Certificates. This opens the Certificate Manager, where you can\n"
+"    Export. Be sure to select PEM for the Save as type.\n"
+"\n"
+"    In Internet Explorer, select Internet Options, then the Content tab, then\n"
+, stdout);
+ fputs(
+"    Certificates. Then you can Export, and depending on the format you may\n"
+"    need to convert to PEM.\n"
+"\n"
+"    In Chrome, select Settings, then Show Advanced Settings. Under HTTPS/SSL\n"
+"    select Manage Certificates.\n"
+"\n"
+"RESUMING FILE TRANSFERS\n"
+"\n"
+" To continue a file transfer where it was previously aborted, curl supports\n"
+" resume on HTTP(S) downloads as well as FTP uploads and downloads.\n"
+"\n"
+" Continue downloading a document:\n"
+"\n"
+"        curl -C - -o file ftp://ftp.server.com/path/file\n"
+"\n"
+, stdout);
+ fputs(
+" Continue uploading a document(*1):\n"
+"\n"
+"        curl -C - -T file ftp://ftp.server.com/path/file\n"
+"\n"
+" Continue downloading a document from a web server(*2):\n"
+"\n"
+"        curl -C - -o file http://www.server.com/\n"
+"\n"
+" (*1) = This requires that the FTP server supports the non-standard command\n"
+"        SIZE. If it doesn't, curl will say so.\n"
+"\n"
+" (*2) = This requires that the web server supports at least HTTP/1.1. If it\n"
+"        doesn't, curl will say so.\n"
+"\n"
+"TIME CONDITIONS\n"
+"\n"
+, stdout);
+ fputs(
+" HTTP allows a client to specify a time condition for the document it\n"
+" requests. It is If-Modified-Since or If-Unmodified-Since. Curl allows you to\n"
+" specify them with the -z/--time-cond flag.\n"
+"\n"
+" For example, you can easily make a download that only gets performed if the\n"
+" remote file is newer than a local copy. It would be made like:\n"
+"\n"
+"        curl -z local.html http://remote.server.com/remote.html\n"
+"\n"
+" Or you can download a file only if the local file is newer than the remote\n"
+, stdout);
+ fputs(
+" one. Do this by prepending the date string with a '-', as in:\n"
+"\n"
+"        curl -z -local.html http://remote.server.com/remote.html\n"
+"\n"
+" You can specify a \"free text\" date as condition. Tell curl to only download\n"
+" the file if it was updated since January 12, 2012:\n"
+"\n"
+"        curl -z \"Jan 12 2012\" http://remote.server.com/remote.html\n"
+"\n"
+" Curl will then accept a wide range of date formats. You always make the date\n"
+" check the other way around by prepending it with a dash '-'.\n"
+"\n"
+"DICT\n"
+"\n"
+"  For fun try\n"
+"\n"
+, stdout);
+ fputs(
+"        curl dict://dict.org/m:curl\n"
+"        curl dict://dict.org/d:heisenbug:jargon\n"
+"        curl dict://dict.org/d:daniel:web1913\n"
+"\n"
+"  Aliases for 'm' are 'match' and 'find', and aliases for 'd' are 'define'\n"
+"  and 'lookup'. For example,\n"
+"\n"
+"        curl dict://dict.org/find:curl\n"
+"\n"
+"  Commands that break the URL description of the RFC (but not the DICT\n"
+"  protocol) are\n"
+"\n"
+"        curl dict://dict.org/show:db\n"
+"        curl dict://dict.org/show:strat\n"
+"\n"
+, stdout);
+ fputs(
+"  Authentication is still missing (but this is not required by the RFC)\n"
+"\n"
+"LDAP\n"
+"\n"
+"  If you have installed the OpenLDAP library, curl can take advantage of it\n"
+"  and offer ldap:// support.\n"
+"  On Windows, curl will use WinLDAP from Platform SDK by default.\n"
+"\n"
+"  Default protocol version used by curl is LDAPv3. LDAPv2 will be used as\n"
+"  fallback mechanism in case if LDAPv3 will fail to connect.\n"
+"\n"
+"  LDAP is a complex thing and writing an LDAP query is not an easy task. I do\n"
+, stdout);
+ fputs(
+"  advise you to dig up the syntax description for that elsewhere. One such\n"
+"  place might be:\n"
+"\n"
+"  RFC 2255, \"The LDAP URL Format\" https://curl.haxx.se/rfc/rfc2255.txt\n"
+"\n"
+"  To show you an example, this is how I can get all people from my local LDAP\n"
+"  server that has a certain sub-domain in their email address:\n"
+"\n"
+"        curl -B \"ldap://ldap.frontec.se/o=frontec??sub?mail=*sth.frontec.se\"\n"
+"\n"
+"  If I want the same info in HTML format, I can get it by not using the -B\n"
+"  (enforce ASCII) flag.\n"
+"\n"
+, stdout);
+ fputs(
+"  You also can use authentication when accessing LDAP catalog:\n"
+"\n"
+"      curl -u user:passwd \"ldap://ldap.frontec.se/o=frontec??sub?mail=*\"\n"
+"      curl \"ldap://user:passwd@ldap.frontec.se/o=frontec??sub?mail=*\"\n"
+"\n"
+"  By default, if user and password provided, OpenLDAP/WinLDAP will use basic\n"
+"  authentication. On Windows you can control this behavior by providing \n"
+"  one of --basic, --ntlm or --digest option in curl command line\n"
+"\n"
+, stdout);
+ fputs(
+"      curl --ntlm \"ldap://user:passwd@ldap.frontec.se/o=frontec??sub?mail=*\"\n"
+"\n"
+"  On Windows, if no user/password specified, auto-negotiation mechanism will\n"
+"  be used with current logon credentials (SSPI/SPNEGO).\n"
+"\n"
+"ENVIRONMENT VARIABLES\n"
+"\n"
+"  Curl reads and understands the following environment variables:\n"
+"\n"
+"        http_proxy, HTTPS_PROXY, FTP_PROXY\n"
+"\n"
+"  They should be set for protocol-specific proxies. General proxy should be\n"
+"  set with\n"
+"\n"
+"        ALL_PROXY\n"
+"\n"
+, stdout);
+ fputs(
+"  A comma-separated list of host names that shouldn't go through any proxy is\n"
+"  set in (only an asterisk, '*' matches all hosts)\n"
+"\n"
+"        NO_PROXY\n"
+"\n"
+"  If the host name matches one of these strings, or the host is within the\n"
+"  domain of one of these strings, transactions with that node will not be\n"
+"  proxied. When a domain is used, it needs to start with a period. A user can\n"
+"  specify that both www.example.com and foo.example.com should not uses a\n"
+, stdout);
+ fputs(
+"  proxy by setting NO_PROXY to \".example.com\". By including the full name you\n"
+"  can exclude specific host names, so to make www.example.com not use a proxy\n"
+"  but still have foo.example.com do it, set NO_PROXY to \"www.example.com\"\n"
+"\n"
+"  The usage of the -x/--proxy flag overrides the environment variables.\n"
+"\n"
+"NETRC\n"
+"\n"
+"  Unix introduced the .netrc concept a long time ago. It is a way for a user\n"
+"  to specify name and password for commonly visited FTP sites in a file so\n"
+, stdout);
+ fputs(
+"  that you don't have to type them in each time you visit those sites. You\n"
+"  realize this is a big security risk if someone else gets hold of your\n"
+"  passwords, so therefore most unix programs won't read this file unless it is\n"
+"  only readable by yourself (curl doesn't care though).\n"
+"\n"
+"  Curl supports .netrc files if told to (using the -n/--netrc and\n"
+"  --netrc-optional options). This is not restricted to just FTP,\n"
+"  so curl can use it for all protocols where authentication is used.\n"
+"\n"
+, stdout);
+ fputs(
+"  A very simple .netrc file could look something like:\n"
+"\n"
+"        machine curl.haxx.se login iamdaniel password mysecret\n"
+"\n"
+"CUSTOM OUTPUT\n"
+"\n"
+"  To better allow script programmers to get to know about the progress of\n"
+"  curl, the -w/--write-out option was introduced. Using this, you can specify\n"
+"  what information from the previous transfer you want to extract.\n"
+"\n"
+"  To display the amount of bytes downloaded together with some text and an\n"
+"  ending newline:\n"
+"\n"
+, stdout);
+ fputs(
+"        curl -w 'We downloaded %{size_download} bytes\\n' www.download.com\n"
+"\n"
+"KERBEROS FTP TRANSFER\n"
+"\n"
+"  Curl supports kerberos4 and kerberos5/GSSAPI for FTP transfers. You need\n"
+"  the kerberos package installed and used at curl build time for it to be\n"
+"  available.\n"
+"\n"
+"  First, get the krb-ticket the normal way, like with the kinit/kauth tool.\n"
+"  Then use curl in way similar to:\n"
+"\n"
+"        curl --krb private ftp://krb4site.com -u username:fakepwd\n"
+"\n"
+, stdout);
+ fputs(
+"  There's no use for a password on the -u switch, but a blank one will make\n"
+"  curl ask for one and you already entered the real password to kinit/kauth.\n"
+"\n"
+"TELNET\n"
+"\n"
+"  The curl telnet support is basic and very easy to use. Curl passes all data\n"
+"  passed to it on stdin to the remote server. Connect to a remote telnet\n"
+"  server using a command line similar to:\n"
+"\n"
+"        curl telnet://remote.server.com\n"
+"\n"
+"  And enter the data to pass to the server on stdin. The result will be sent\n"
+, stdout);
+ fputs(
+"  to stdout or to the file you specify with -o.\n"
+"\n"
+"  You might want the -N/--no-buffer option to switch off the buffered output\n"
+"  for slow connections or similar.\n"
+"\n"
+"  Pass options to the telnet protocol negotiation, by using the -t option. To\n"
+"  tell the server we use a vt100 terminal, try something like:\n"
+"\n"
+"        curl -tTTYPE=vt100 telnet://remote.server.com\n"
+"\n"
+"  Other interesting options for it -t include:\n"
+"\n"
+"   - XDISPLOC=<X display> Sets the X display location.\n"
+"\n"
+, stdout);
+ fputs(
+"   - NEW_ENV=<var,val> Sets an environment variable.\n"
+"\n"
+"  NOTE: The telnet protocol does not specify any way to login with a specified\n"
+"  user and password so curl can't do that automatically. To do that, you need\n"
+"  to track when the login prompt is received and send the username and\n"
+"  password accordingly.\n"
+"\n"
+"PERSISTENT CONNECTIONS\n"
+"\n"
+"  Specifying multiple files on a single command line will make curl transfer\n"
+"  all of them, one after the other in the specified order.\n"
+"\n"
+, stdout);
+ fputs(
+"  libcurl will attempt to use persistent connections for the transfers so that\n"
+"  the second transfer to the same host can use the same connection that was\n"
+"  already initiated and was left open in the previous transfer. This greatly\n"
+"  decreases connection time for all but the first transfer and it makes a far\n"
+"  better use of the network.\n"
+"\n"
+"  Note that curl cannot use persistent connections for transfers that are used\n"
+"  in subsequence curl invokes. Try to stuff as many URLs as possible on the\n"
+, stdout);
+ fputs(
+"  same command line if they are using the same host, as that'll make the\n"
+"  transfers faster. If you use an HTTP proxy for file transfers, practically\n"
+"  all transfers will be persistent.\n"
+"\n"
+"MULTIPLE TRANSFERS WITH A SINGLE COMMAND LINE\n"
+"\n"
+"  As is mentioned above, you can download multiple files with one command line\n"
+"  by simply adding more URLs. If you want those to get saved to a local file\n"
+"  instead of just printed to stdout, you need to add one save option for each\n"
+, stdout);
+ fputs(
+"  URL you specify. Note that this also goes for the -O option (but not\n"
+"  --remote-name-all).\n"
+"\n"
+"  For example: get two files and use -O for the first and a custom file\n"
+"  name for the second:\n"
+"\n"
+"    curl -O http://url.com/file.txt ftp://ftp.com/moo.exe -o moo.jpg\n"
+"\n"
+"  You can also upload multiple files in a similar fashion:\n"
+"\n"
+"    curl -T local1 ftp://ftp.com/moo.exe -T local2 ftp://ftp.com/moo2.txt\n"
+"\n"
+"IPv6\n"
+"\n"
+"  curl will connect to a server with IPv6 when a host lookup returns an IPv6\n"
+, stdout);
+ fputs(
+"  address and fall back to IPv4 if the connection fails. The --ipv4 and --ipv6\n"
+"  options can specify which address to use when both are available. IPv6\n"
+"  addresses can also be specified directly in URLs using the syntax:\n"
+"\n"
+"    http://[2001:1890:1112:1::20]/overview.html\n"
+"\n"
+"  When this style is used, the -g option must be given to stop curl from\n"
+"  interpreting the square brackets as special globbing characters.  Link local\n"
+, stdout);
+ fputs(
+"  and site local addresses including a scope identifier, such as fe80::1234%1,\n"
+"  may also be used, but the scope portion must be numeric or match an existing\n"
+"  network interface on Linux and the percent character must be URL escaped. The\n"
+"  previous example in an SFTP URL might look like:\n"
+"\n"
+"    sftp://[fe80::1234%251]/\n"
+"\n"
+"  IPv6 addresses provided other than in URLs (e.g. to the --proxy, --interface\n"
+"  or --ftp-port options) should not be URL encoded.\n"
+"\n"
+"METALINK\n"
+"\n"
+, stdout);
+ fputs(
+"  Curl supports Metalink (both version 3 and 4 (RFC 5854) are supported), a way\n"
+"  to list multiple URIs and hashes for a file. Curl will make use of the mirrors\n"
+"  listed within for failover if there are errors (such as the file or server not\n"
+"  being available). It will also verify the hash of the file after the download\n"
+"  completes. The Metalink file itself is downloaded and processed in memory and\n"
+"  not stored in the local file system.\n"
+"\n"
+"  Example to use a remote Metalink file:\n"
+"\n"
+, stdout);
+ fputs(
+"    curl --metalink http://www.example.com/example.metalink\n"
+"\n"
+"  To use a Metalink file in the local file system, use FILE protocol (file://):\n"
+"\n"
+"    curl --metalink file://example.metalink\n"
+"\n"
+"  Please note that if FILE protocol is disabled, there is no way to use a local\n"
+"  Metalink file at the time of this writing. Also note that if --metalink and\n"
+"  --include are used together, --include will be ignored. This is because including\n"
+, stdout);
+ fputs(
+"  headers in the response will break Metalink parser and if the headers are included\n"
+"  in the file described in Metalink file, hash check will fail.\n"
+"\n"
+"MAILING LISTS\n"
+"\n"
+"  For your convenience, we have several open mailing lists to discuss curl,\n"
+"  its development and things relevant to this. Get all info at\n"
+"  https://curl.haxx.se/mail/. Some of the lists available are:\n"
+"\n"
+"  curl-users\n"
+"\n"
+"    Users of the command line tool. How to use it, what doesn't work, new\n"
+, stdout);
+ fputs(
+"    features, related tools, questions, news, installations, compilations,\n"
+"    running, porting etc.\n"
+"\n"
+"  curl-library\n"
+"\n"
+"    Developers using or developing libcurl. Bugs, extensions, improvements.\n"
+"\n"
+"  curl-announce\n"
+"\n"
+"    Low-traffic. Only receives announcements of new public versions. At worst,\n"
+"    that makes something like one or two mails per month, but usually only one\n"
+"    mail every second month.\n"
+"\n"
+"  curl-and-php\n"
+"\n"
+"    Using the curl functions in PHP. Everything curl with a PHP angle. Or PHP\n"
+, stdout);
+ fputs(
+"    with a curl angle.\n"
+"\n"
+"  curl-and-python\n"
+"\n"
+"    Python hackers using curl with or without the python binding pycurl.\n"
+"\n"
+"  Please direct curl questions, feature requests and trouble reports to one of\n"
+"  these mailing lists instead of mailing any individual.\n"
+, stdout) ;
+}
+#else /* !USE_MANUAL */
+/* built-in manual is disabled, blank function */
+#include "tool_hugehelp.h"
+void hugehelp(void) {}
+#endif /* USE_MANUAL */
+#else
+/*
+ * NEVER EVER edit this manually, fix the mkhelp.pl script instead!
+ */
+#ifdef USE_MANUAL
+#include "tool_hugehelp.h"
+#include <zlib.h>
+#include "memdebug.h" /* keep this as LAST include */
+static const unsigned char hugehelpgz[] = {
+  /* This mumbo-jumbo is the huge help text compressed with gzip.
+     Thanks to this operation, the size of this data shrank from 194646
+     to 57342 bytes. You can disable the use of compressed help
+     texts by NOT passing -c to the mkhelp.pl tool. */
+  0x1f, 0x8b, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0xed, 0xfd,
+  0x6b, 0x7b, 0x1b, 0x47, 0x92, 0x26, 0x80, 0x7e, 0xe7, 0xaf, 0xa8, 0x46,
+  0x9f, 0x1e, 0x92, 0xdd, 0x00, 0x78, 0xd1, 0xc5, 0x36, 0x2d, 0x79, 0x4c,
+  0x53, 0x94, 0xcd, 0x31, 0x25, 0x72, 0x09, 0xca, 0x76, 0xaf, 0xed, 0x47,
+  0x4f, 0x01, 0x28, 0x92, 0xd5, 0x02, 0xaa, 0xd0, 0x55, 0x05, 0x52, 0xec,
+  0xd9, 0xd9, 0xdf, 0x7e, 0x32, 0xde, 0x88, 0xc8, 0xcc, 0xaa, 0x4c, 0x80,
+  0xb4, 0xdb, 0xee, 0x9d, 0x73, 0x76, 0xe7, 0x62, 0x49, 0x64, 0x55, 0x56,
+  0x5e, 0x23, 0xe3, 0xf2, 0xc6, 0x1b, 0x49, 0xf2, 0xd0, 0xff, 0xbc, 0xc7,
+  0xff, 0xbf, 0x37, 0xff, 0x63, 0xfe, 0xdc, 0x48, 0x92, 0xf3, 0xaa, 0xfc,
+  0x5b, 0x36, 0x69, 0xe2, 0xcf, 0xbe, 0x7f, 0xff, 0xbf, 0x12, 0xfe, 0x5f,
+  0xf3, 0xce, 0x4f, 0xe6, 0xcf, 0x8d, 0xb5, 0x6d, 0xef, 0x24, 0xee, 0x85,
+  0xff, 0xf5, 0x7e, 0x3b, 0x79, 0xe8, 0x85, 0xff, 0x95, 0x6c, 0xe1, 0x85,
+  0xf7, 0xf2, 0x85, 0x17, 0xf4, 0xf7, 0xf7, 0xef, 0xd7, 0x7f, 0xe4, 0x27,
+  0xea, 0x15, 0xfd, 0x67, 0x87, 0xde, 0xfb, 0xe9, 0x3d, 0xfd, 0xd5, 0xfc,
+  0x64, 0x63, 0xe3, 0xed, 0xe1, 0x9b, 0x63, 0x7d, 0x75, 0xb2, 0xac, 0x66,
+  0xc9, 0x20, 0x69, 0xaa, 0xb4, 0xa8, 0xaf, 0xb2, 0x2a, 0x49, 0x93, 0x77,
+  0x17, 0xa7, 0x1b, 0x1b, 0xa3, 0xbf, 0xbe, 0x3d, 0x3b, 0x1f, 0x9d, 0x8c,
+  0x5a, 0x8f, 0xfd, 0x58, 0x2e, 0x9a, 0xbc, 0x2c, 0xea, 0x9f, 0x93, 0x1f,
+  0xcd, 0x43, 0xc3, 0xe1, 0xf0, 0xe7, 0x8d, 0x8d, 0x57, 0xc7, 0xa3, 0xa3,
+  0x8b, 0x93, 0xf3, 0xcb, 0x93, 0xb3, 0xb7, 0xad, 0x67, 0x93, 0xbc, 0x4e,
+  0x4c, 0x63, 0x4d, 0x59, 0xce, 0xcc, 0x7f, 0x5c, 0xfb, 0xd3, 0xb4, 0x49,
+  0x93, 0xab, 0xaa, 0x9c, 0x27, 0x65, 0x45, 0xbf, 0x48, 0x93, 0x3a, 0xab,
+  0x6e, 0xb3, 0xaa, 0x9f, 0x2c, 0xeb, 0xbc, 0xb8, 0x4e, 0xca, 0x22, 0x4b,
+  0xca, 0xab, 0xa4, 0xb9, 0xc9, 0xb4, 0xb9, 0x7a, 0xb9, 0x58, 0x94, 0x55,
+  0x93, 0x4d, 0x93, 0x45, 0x55, 0x36, 0xe5, 0xa4, 0x9c, 0xd5, 0xc9, 0xd6,
+  0xab, 0x93, 0xa3, 0xcb, 0x7e, 0xf2, 0xfa, 0xe4, 0xf4, 0xd8, 0xfc, 0xf7,
+  0xf2, 0x1c, 0xff, 0x19, 0xf5, 0x93, 0xaf, 0xcf, 0xce, 0xbf, 0x39, 0xbe,
+  0xe8, 0x27, 0xdf, 0x5c, 0xd2, 0xcf, 0xe8, 0xbf, 0xe6, 0x87, 0xc9, 0xc9,
+  0x9b, 0xc3, 0xf3, 0xbe, 0x36, 0x47, 0xff, 0xa0, 0x1f, 0x9e, 0xbe, 0x32,
+  0x3f, 0xe4, 0x3f, 0xe8, 0x9f, 0xe7, 0x67, 0xe7, 0x4f, 0xe4, 0x0f, 0xfa,
+  0xe7, 0xc5, 0xe5, 0x1b, 0xf3, 0xdb, 0x8b, 0xcb, 0x91, 0xf9, 0xef, 0xe8,
+  0x88, 0xfe, 0x83, 0xaf, 0x8c, 0xde, 0x7c, 0x85, 0xff, 0x8c, 0x6c, 0x73,
+  0xa3, 0x37, 0xfc, 0x73, 0x7c, 0xe9, 0xf2, 0xf8, 0xf4, 0xed, 0xf1, 0x65,
+  0x92, 0x16, 0xd3, 0xe4, 0xd2, 0x3c, 0xbf, 0x3d, 0x4c, 0x2e, 0x6f, 0xb2,
+  0x64, 0x52, 0xce, 0xe7, 0xf4, 0x23, 0x33, 0x23, 0xd3, 0xac, 0xce, 0xaf,
+  0x0b, 0x33, 0x14, 0x33, 0xf2, 0xbb, 0xb2, 0xfa, 0x90, 0x24, 0x77, 0x79,
+  0x73, 0x53, 0x2e, 0x1b, 0x6d, 0x6e, 0x69, 0x66, 0x23, 0xc9, 0x8b, 0x26,
+  0xab, 0xd2, 0x09, 0xcd, 0xf5, 0x70, 0xa3, 0x35, 0xab, 0xe5, 0x95, 0x99,
+  0xc3, 0xda, 0x4c, 0xda, 0x78, 0x59, 0xcf, 0xca, 0x74, 0x4a, 0x53, 0x65,
+  0x5e, 0xb9, 0x5a, 0x9a, 0x49, 0xae, 0xf2, 0xc9, 0x87, 0x3a, 0x99, 0xe5,
+  0x1f, 0x32, 0x9a, 0xa8, 0x8f, 0xf7, 0x3a, 0x71, 0x7d, 0x6e, 0x34, 0x5d,
+  0x9a, 0x39, 0x2d, 0x06, 0xda, 0x5c, 0x93, 0x4f, 0x52, 0xfa, 0x00, 0x66,
+  0x2e, 0x59, 0x2e, 0xa8, 0x35, 0x9e, 0xb1, 0x64, 0x51, 0xd6, 0xe6, 0xa5,
+  0xd1, 0xe8, 0xd4, 0xf4, 0xbc, 0x28, 0x32, 0xf4, 0xa3, 0xee, 0x9b, 0x7f,
+  0x94, 0x1f, 0xf2, 0xcc, 0xfc, 0xe5, 0x2a, 0x9f, 0x65, 0x09, 0xaf, 0xa8,
+  0x6d, 0x8e, 0x96, 0x36, 0xa9, 0xb2, 0x7a, 0x39, 0xcf, 0xcc, 0xec, 0xbd,
+  0xc9, 0x9a, 0x74, 0x96, 0x17, 0x1f, 0xcc, 0x5f, 0x69, 0xe0, 0xf3, 0xb2,
+  0xca, 0x86, 0xc9, 0x61, 0x9d, 0xdc, 0x97, 0x4b, 0x33, 0xe0, 0xd9, 0xcc,
+  0xac, 0x79, 0x96, 0x8c, 0xb3, 0x59, 0x79, 0xd7, 0xa7, 0x95, 0x4e, 0x8a,
+  0xe5, 0x7c, 0x6c, 0x1a, 0x28, 0xaf, 0x5c, 0x73, 0x69, 0xb3, 0x34, 0xcd,
+  0xf1, 0xd3, 0xf3, 0xd4, 0x8c, 0xc9, 0xbc, 0x5b, 0x25, 0x37, 0x99, 0x19,
+  0x73, 0xbd, 0xc8, 0x8b, 0x3f, 0xb4, 0xe7, 0xc5, 0x4c, 0xed, 0xa2, 0xbc,
+  0xcb, 0x2a, 0x33, 0xb3, 0xe3, 0xfb, 0xc4, 0x4c, 0xc2, 0x98, 0x37, 0xe1,
+  0x95, 0xd9, 0x64, 0x49, 0x6a, 0x9a, 0xb0, 0x1b, 0x70, 0x50, 0x65, 0xb3,
+  0x94, 0x36, 0x93, 0xfd, 0xc6, 0xd0, 0x2c, 0x62, 0x66, 0x77, 0x9b, 0xbc,
+  0xba, 0xf5, 0x64, 0x1b, 0x2f, 0x4f, 0xcd, 0x48, 0xf2, 0x59, 0x6d, 0x96,
+  0x81, 0x8e, 0x85, 0x3c, 0x43, 0x8b, 0x4a, 0xc7, 0xc4, 0xec, 0xcd, 0xfb,
+  0xa2, 0x49, 0x3f, 0xe2, 0xf3, 0xb2, 0x37, 0x07, 0xd3, 0x6c, 0x91, 0x15,
+  0xd3, 0xac, 0x68, 0x86, 0xc9, 0x5f, 0xcb, 0xe5, 0xa6, 0xf9, 0xf6, 0x55,
+  0x6e, 0xe6, 0x20, 0x95, 0xa6, 0xcc, 0x97, 0xcd, 0x26, 0x98, 0x54, 0xf9,
+  0xc2, 0x5b, 0x8a, 0xb2, 0x30, 0x6b, 0x9e, 0x5c, 0xbc, 0x3e, 0x4a, 0x9e,
+  0x7c, 0xf6, 0xe9, 0x73, 0xb7, 0xe6, 0xa6, 0x81, 0x64, 0x92, 0x16, 0x66,
+  0xc4, 0xd9, 0x24, 0xbf, 0xba, 0x4f, 0xe6, 0xcb, 0x59, 0x93, 0x2f, 0xcc,
+  0xec, 0x9b, 0x8f, 0xd7, 0x74, 0x80, 0x16, 0x69, 0xd5, 0xd4, 0xb4, 0x09,
+  0xf0, 0x03, 0x8c, 0xfd, 0xae, 0xca, 0x1b, 0x3a, 0x48, 0xf8, 0x9d, 0xe9,
+  0x61, 0xd6, 0xd4, 0xda, 0x1c, 0xed, 0x35, 0xf3, 0x9d, 0xb1, 0xd9, 0x5b,
+  0x66, 0x6a, 0xd3, 0xda, 0x7c, 0xf4, 0x60, 0xc3, 0xc9, 0x90, 0x9b, 0xa6,
+  0x59, 0x1c, 0xec, 0xec, 0xd4, 0x79, 0x93, 0x0d, 0xff, 0xd3, 0x9c, 0xc3,
+  0x7e, 0x73, 0x57, 0xf6, 0x9b, 0x9b, 0x2a, 0xcb, 0xfe, 0x6b, 0x68, 0xf6,
+  0xb0, 0x7d, 0xd2, 0x7c, 0xf7, 0x5e, 0x3a, 0x76, 0x9d, 0x35, 0xe6, 0x0b,
+  0x7f, 0x5f, 0x66, 0x05, 0xb5, 0x68, 0xfa, 0x91, 0xce, 0x16, 0x37, 0xa9,
+  0x59, 0xce, 0xcc, 0xec, 0x46, 0x3a, 0xd9, 0x66, 0xc3, 0x50, 0xaf, 0xf8,
+  0x6c, 0xff, 0xf8, 0x73, 0xf8, 0xd1, 0x2b, 0x7c, 0xd3, 0xfc, 0x77, 0x98,
+  0x7d, 0x4c, 0xe7, 0x66, 0x6c, 0xf4, 0xa9, 0x1d, 0xda, 0x62, 0x3f, 0xee,
+  0x0d, 0xf6, 0x76, 0x77, 0x7f, 0x1e, 0x36, 0x1f, 0x9b, 0xc7, 0x3d, 0xbf,
+  0xbb, 0xeb, 0xde, 0xa0, 0x47, 0xb7, 0x68, 0xbc, 0xc9, 0xcc, 0x6c, 0x19,
+  0xfa, 0xf8, 0x3f, 0xb2, 0xaa, 0xac, 0xb7, 0x1f, 0xd7, 0x52, 0x3a, 0xf8,
+  0x47, 0xfb, 0xbb, 0x6f, 0xb3, 0x1a, 0x7b, 0xc6, 0x8d, 0x35, 0x49, 0x2b,
+  0xb3, 0x6f, 0xcb, 0xc6, 0x89, 0xa7, 0xbe, 0x39, 0x94, 0x8d, 0x9d, 0x19,
+  0x73, 0xe6, 0xcc, 0xd3, 0x46, 0xb0, 0xa5, 0x33, 0x92, 0x69, 0x75, 0x52,
+  0x64, 0x1f, 0xed, 0x29, 0x37, 0xa7, 0x3f, 0x4b, 0x27, 0x37, 0x49, 0x69,
+  0x36, 0x7f, 0x15, 0x59, 0x02, 0xbf, 0x43, 0x69, 0x35, 0xb9, 0xc9, 0x6f,
+  0xcd, 0x6c, 0x7c, 0xf6, 0xd9, 0xf3, 0x81, 0xf9, 0xcf, 0x67, 0x3f, 0xef,
+  0xdc, 0x96, 0x33, 0x33, 0x39, 0x4f, 0x7f, 0xde, 0xa1, 0x25, 0xfe, 0xcf,
+  0xb4, 0x3f, 0xee, 0x4f, 0xfe, 0x6b, 0x78, 0xd3, 0xcc, 0x67, 0x2b, 0x37,
+  0x4e, 0x5a, 0x98, 0xff, 0x9f, 0x97, 0xcb, 0xa2, 0xb1, 0x9b, 0xc5, 0xec,
+  0xb9, 0xc6, 0x13, 0x4e, 0xe6, 0xb8, 0x9a, 0x33, 0x4a, 0x5b, 0x9b, 0xf6,
+  0x10, 0x9d, 0x3a, 0x73, 0x40, 0xdd, 0x71, 0x6c, 0x26, 0x37, 0x66, 0xfc,
+  0x66, 0xf3, 0xa4, 0x32, 0x07, 0x4d, 0x9e, 0xd2, 0xc1, 0x34, 0xf2, 0x81,
+  0xe4, 0x15, 0x9a, 0xe2, 0x8f, 0xe5, 0xe6, 0xb9, 0xb2, 0x9a, 0x66, 0x55,
+  0x7b, 0x1b, 0xa3, 0x3b, 0xae, 0x3f, 0x89, 0x99, 0xcf, 0x85, 0xf9, 0xf8,
+  0x92, 0x44, 0x1d, 0x4e, 0x1a, 0xb5, 0x60, 0xce, 0xe8, 0xb5, 0x99, 0x2a,
+  0x33, 0x3d, 0xb4, 0xb1, 0x68, 0xf6, 0xee, 0x93, 0xb7, 0x66, 0x0d, 0x59,
+  0x3e, 0x78, 0xfb, 0x6f, 0x96, 0x35, 0xcd, 0x83, 0x33, 0xe7, 0x36, 0xd1,
+  0xc1, 0x5e, 0xb0, 0x8f, 0x56, 0x3d, 0x6f, 0x96, 0xfe, 0x60, 0xbf, 0xfd,
+  0xf0, 0xf7, 0x46, 0x6e, 0xba, 0x1d, 0x6c, 0xbe, 0xfe, 0x9f, 0xff, 0xe5,
+  0x6d, 0x84, 0x3b, 0xfa, 0x6d, 0x5e, 0xdc, 0x96, 0x1f, 0xcc, 0xc0, 0x71,
+  0xb1, 0xa5, 0xad, 0x49, 0x4d, 0x48, 0x34, 0xcc, 0x17, 0x8d, 0xbd, 0x31,
+  0x68, 0x87, 0x98, 0x1f, 0x8d, 0xd3, 0xf1, 0xec, 0x3e, 0xb9, 0x49, 0x6f,
+  0x33, 0x1a, 0xef, 0xc2, 0x6c, 0x1d, 0x9a, 0x01, 0x23, 0xc9, 0x67, 0x10,
+  0x2d, 0x72, 0x56, 0xa7, 0xe5, 0x72, 0x6c, 0xce, 0xfb, 0xdf, 0x97, 0x65,
+  0xc3, 0x13, 0x93, 0xde, 0x96, 0xf9, 0xb4, 0x75, 0x3d, 0xde, 0x64, 0x24,
+  0x63, 0xe8, 0xc3, 0xb8, 0x37, 0x8c, 0x8c, 0xa3, 0x9e, 0x62, 0xef, 0xe7,
+  0x0d, 0xdd, 0x40, 0x46, 0x3a, 0xa5, 0xb3, 0xba, 0x4c, 0x92, 0xeb, 0x92,
+  0x36, 0x2e, 0x64, 0x22, 0x76, 0x9e, 0x59, 0x94, 0x9b, 0x94, 0x2e, 0x1a,
+  0x73, 0xa7, 0xd8, 0xad, 0x59, 0x65, 0x10, 0x8f, 0x58, 0xa9, 0x74, 0xd6,
+  0xe7, 0x0b, 0x85, 0xde, 0x91, 0xa9, 0x4a, 0x36, 0xff, 0x6d, 0xb3, 0x9f,
+  0x6c, 0xfe, 0xfb, 0x26, 0x44, 0xfb, 0xe6, 0x9f, 0x37, 0xdd, 0x3a, 0x1b,
+  0x0d, 0xe9, 0x36, 0x9f, 0xd2, 0xdd, 0x60, 0x46, 0x72, 0x72, 0x7e, 0xfb,
+  0x3c, 0xf9, 0x07, 0x5d, 0xe7, 0x46, 0xfc, 0x65, 0x1f, 0x75, 0x93, 0xe8,
+  0xd8, 0xcc, 0xdb, 0x89, 0x91, 0x83, 0xe9, 0x82, 0xee, 0xf5, 0xac, 0x9a,
+  0x98, 0x1d, 0x95, 0x5e, 0x9b, 0x3d, 0x64, 0xae, 0x47, 0x6d, 0x8e, 0xda,
+  0xa7, 0x57, 0x78, 0x58, 0x46, 0x66, 0x25, 0x45, 0x3a, 0x37, 0x9b, 0xf4,
+  0x94, 0x7a, 0x94, 0x17, 0xe1, 0x62, 0xfe, 0x78, 0x95, 0x7d, 0xba, 0x7b,
+  0x70, 0xf0, 0xe4, 0x4f, 0xfb, 0xcf, 0xb2, 0xe6, 0x66, 0xf7, 0xe7, 0x1d,
+  0xfb, 0xc8, 0xc9, 0x15, 0xa6, 0x5d, 0xb7, 0x9f, 0x76, 0xc2, 0x5c, 0xbc,
+  0x56, 0x70, 0x9b, 0xf7, 0xcd, 0xdf, 0xb3, 0xab, 0xfc, 0x63, 0x5f, 0x55,
+  0x18, 0x3e, 0x06, 0xa9, 0xd9, 0x6a, 0x66, 0xfd, 0xe8, 0xd4, 0x6a, 0x73,
+  0xd7, 0xcb, 0xac, 0x36, 0x33, 0x79, 0x77, 0x93, 0x36, 0x89, 0x6d, 0x80,
+  0x57, 0x76, 0x9e, 0x5f, 0xdf, 0x34, 0xc9, 0x5d, 0x4a, 0xf2, 0xff, 0xa4,
+  0xe1, 0x26, 0xe8, 0xe2, 0x35, 0x52, 0xff, 0x2a, 0x35, 0xe2, 0x9b, 0xd6,
+  0x10, 0xb7, 0xec, 0xd8, 0x5d, 0xfa, 0x8d, 0xd9, 0xe6, 0xbc, 0x20, 0x4e,
+  0xc3, 0x19, 0xa7, 0x35, 0x1d, 0xa4, 0xc2, 0x9c, 0xd7, 0xc6, 0x5c, 0xdb,
+  0x4b, 0xfa, 0xd7, 0x8d, 0xb9, 0x98, 0x31, 0x07, 0xd2, 0x51, 0xdc, 0x5d,
+  0xaf, 0x69, 0x39, 0x69, 0x6d, 0xec, 0x7d, 0x62, 0x16, 0xa9, 0x2f, 0xcb,
+  0x6c, 0xdf, 0xa8, 0xcd, 0x81, 0x33, 0xc2, 0xc2, 0xee, 0x8c, 0x1e, 0xc9,
+  0xbd, 0x1e, 0x8f, 0x13, 0x7d, 0x4c, 0x6b, 0xba, 0xbb, 0xf9, 0x86, 0x36,
+  0x9d, 0xf7, 0x06, 0x6b, 0x26, 0x2d, 0xfd, 0x40, 0x5a, 0x42, 0x47, 0x17,
+  0xc1, 0x6b, 0xd3, 0xd2, 0x6c, 0x32, 0xd3, 0x5b, 0x23, 0x1f, 0x69, 0x64,
+  0x24, 0xf5, 0x30, 0x2b, 0xd8, 0xe4, 0xa6, 0x4d, 0xfa, 0x61, 0xde, 0x90,
+  0xd8, 0x87, 0x62, 0x69, 0xfa, 0x6b, 0x26, 0x05, 0xba, 0xa1, 0x91, 0x9d,
+  0xde, 0xf8, 0x71, 0x63, 0x99, 0x67, 0x93, 0x5b, 0xa3, 0x38, 0x18, 0x1d,
+  0x31, 0xb3, 0x6f, 0xe1, 0x8a, 0x9d, 0x90, 0xba, 0x32, 0x33, 0xe7, 0x65,
+  0x52, 0x56, 0x15, 0x29, 0xe1, 0xb4, 0x82, 0x63, 0x96, 0x6b, 0xf3, 0xcc,
+  0xdc, 0xec, 0xfe, 0x74, 0xe6, 0x74, 0xc7, 0x18, 0xf9, 0x62, 0x54, 0x05,
+  0x48, 0x10, 0x73, 0xa5, 0x43, 0x0c, 0x63, 0xe0, 0xe8, 0x1d, 0xb5, 0x3d,
+  0x99, 0x64, 0x8b, 0xa6, 0x8e, 0x8d, 0x49, 0x17, 0xdc, 0x74, 0xa7, 0xca,
+  0x68, 0xe6, 0x7d, 0x3d, 0x08, 0xf3, 0x6a, 0xef, 0x61, 0xa8, 0x42, 0xaa,
+  0x5a, 0x18, 0xd5, 0xa8, 0xb6, 0xb3, 0xd6, 0x60, 0x6f, 0x18, 0x31, 0x86,
+  0x39, 0x9f, 0x53, 0x47, 0xe9, 0xe1, 0x9a, 0x4f, 0x2a, 0xc4, 0x25, 0x2d,
+  0x24, 0x2b, 0xbf, 0xfc, 0x5d, 0xba, 0x4d, 0xcc, 0x7c, 0xda, 0xc6, 0xcd,
+  0x57, 0xed, 0x9a, 0xd2, 0xe7, 0x6b, 0x63, 0x36, 0x98, 0xcb, 0x75, 0x5a,
+  0xdf, 0x18, 0x7d, 0xa8, 0x96, 0x93, 0x9d, 0xcf, 0xcd, 0x9e, 0xb9, 0xa5,
+  0xf5, 0x5d, 0x64, 0xd9, 0x74, 0x98, 0x9c, 0x5d, 0x91, 0x54, 0xad, 0x4c,
+  0xa7, 0x1b, 0xfc, 0x9a, 0x04, 0xbd, 0x99, 0xb7, 0x29, 0xf4, 0x6a, 0x7b,
+  0xb4, 0xb8, 0x2b, 0x9e, 0xc4, 0xa6, 0x9d, 0x66, 0x26, 0x3b, 0x21, 0x29,
+  0x37, 0x6b, 0xdf, 0x0a, 0x38, 0x87, 0x46, 0x7a, 0x53, 0xf7, 0xc6, 0x59,
+  0x82, 0x9d, 0x38, 0xce, 0x9a, 0xbb, 0x2c, 0xb3, 0xcd, 0xd5, 0x99, 0xb9,
+  0x89, 0x68, 0xd1, 0x58, 0x19, 0x83, 0x30, 0xa4, 0xa9, 0x3d, 0xbf, 0x38,
+  0xfb, 0xfa, 0xe2, 0x78, 0x34, 0x4a, 0xde, 0x1c, 0x5f, 0x1e, 0x5f, 0xb4,
+  0x66, 0xba, 0x28, 0xab, 0x39, 0x56, 0x74, 0x9a, 0xd7, 0x8b, 0x59, 0x7a,
+  0x4f, 0x4b, 0x6d, 0x46, 0x72, 0x5d, 0xd1, 0xc9, 0x9a, 0x67, 0x74, 0x2b,
+  0x4c, 0x97, 0x90, 0x64, 0x49, 0x69, 0xe4, 0x43, 0x2a, 0x4a, 0x28, 0x09,
+  0x13, 0x68, 0xae, 0xc5, 0xb5, 0x9b, 0x69, 0x23, 0x71, 0xe4, 0x72, 0xa3,
+  0xdb, 0xcd, 0xae, 0x07, 0x69, 0x83, 0xb0, 0x37, 0xfa, 0xee, 0x67, 0x3c,
+  0x4d, 0x35, 0xc6, 0x64, 0xf6, 0x6c, 0x3e, 0x87, 0xb0, 0x33, 0x7f, 0x3a,
+  0x05, 0x30, 0xbb, 0x32, 0xda, 0xaf, 0xb9, 0xf0, 0x58, 0x79, 0xef, 0xf6,
+  0x49, 0x7b, 0x6b, 0x55, 0x56, 0xb3, 0x0d, 0x49, 0x34, 0x53, 0x83, 0xdc,
+  0x15, 0xfe, 0x82, 0x15, 0x62, 0x46, 0x4d, 0x20, 0xd9, 0x27, 0x8f, 0x2d,
+  0xa8, 0x0b, 0x99, 0x59, 0xd9, 0x29, 0x37, 0x5f, 0x2f, 0xaf, 0x70, 0x90,
+  0x93, 0x2d, 0xa3, 0x2c, 0xbf, 0x31, 0x06, 0x8c, 0x31, 0x22, 0xfa, 0xc9,
+  0xf9, 0x36, 0xde, 0xdb, 0xdb, 0xdd, 0x7f, 0xca, 0x82, 0x60, 0xa8, 0xcd,
+  0xbd, 0xf6, 0x04, 0xf1, 0xde, 0x07, 0x5a, 0x5e, 0x7e, 0x88, 0x1a, 0x1f,
+  0x26, 0x7b, 0x6f, 0xf8, 0x27, 0x4f, 0x3f, 0x7d, 0xf6, 0xc9, 0x73, 0xf9,
+  0x61, 0x7b, 0x83, 0xdb, 0xfe, 0x63, 0x77, 0xc0, 0x18, 0x23, 0xeb, 0xcc,
+  0xf4, 0xc4, 0x8c, 0x6e, 0x9e, 0x17, 0xe6, 0x98, 0x98, 0x63, 0x25, 0xb2,
+  0x8a, 0xf6, 0xb3, 0xe9, 0xfc, 0x15, 0x4b, 0x36, 0x59, 0xd7, 0xb6, 0x95,
+  0x67, 0x5e, 0x36, 0x5b, 0xd6, 0xc8, 0x72, 0xbb, 0x48, 0x98, 0x09, 0x73,
+  0xc0, 0xe8, 0xd6, 0x19, 0x93, 0x80, 0x25, 0x53, 0xc7, 0xe8, 0xa4, 0x59,
+  0xf4, 0x6b, 0xf6, 0x56, 0x34, 0x6f, 0x98, 0xbe, 0x99, 0x3b, 0x91, 0xae,
+  0xb9, 0x70, 0xde, 0x8d, 0x28, 0x80, 0x84, 0xbc, 0xcb, 0x6b, 0x88, 0x86,
+  0xbb, 0x72, 0x39, 0x33, 0x86, 0x05, 0x3d, 0xb0, 0x5c, 0xe0, 0x05, 0xf3,
+  0xa9, 0x85, 0x93, 0x01, 0xf3, 0xfc, 0x23, 0xed, 0x9d, 0x6e, 0x2b, 0xa6,
+  0x6b, 0xe6, 0x9f, 0x0b, 0xb3, 0x95, 0xb8, 0x3b, 0xc3, 0xee, 0x0d, 0x01,
+  0xd9, 0x17, 0xec, 0x44, 0x3a, 0xf3, 0x10, 0xda, 0xe7, 0x67, 0xa3, 0x4b,
+  0xd2, 0x00, 0xce, 0xdf, 0x5d, 0x9a, 0x86, 0x8c, 0x0a, 0x50, 0x37, 0x66,
+  0x53, 0xd2, 0x8b, 0x45, 0x06, 0xab, 0x4e, 0x9b, 0x33, 0x7b, 0x2f, 0x87,
+  0xa0, 0x82, 0x5a, 0xa3, 0x9f, 0xe4, 0x3e, 0xb2, 0xd9, 0x4b, 0x47, 0x50,
+  0x8d, 0x5e, 0xbe, 0xc3, 0xed, 0x3b, 0xc9, 0xd6, 0x17, 0xdb, 0x66, 0xcf,
+  0x0e, 0x4a, 0x3b, 0x3b, 0x83, 0x81, 0xbc, 0x6a, 0xbe, 0x5d, 0xe7, 0xf3,
+  0x7c, 0x96, 0x7a, 0xea, 0x95, 0x48, 0x54, 0x3a, 0x9f, 0x56, 0xae, 0x4c,
+  0xcc, 0xae, 0x41, 0xb7, 0x9d, 0x75, 0x47, 0x73, 0x08, 0xa9, 0xe4, 0x96,
+  0x6a, 0x4a, 0x0a, 0x01, 0x94, 0xd8, 0x45, 0x6e, 0xa7, 0x8e, 0xd6, 0x8c,
+  0xc4, 0x55, 0x6b, 0xa2, 0xba, 0xeb, 0x16, 0x4c, 0x1c, 0xdd, 0x48, 0x70,
+  0x1f, 0xd8, 0xa9, 0x4b, 0x7a, 0xe3, 0xb4, 0xea, 0x25, 0x56, 0x16, 0xf3,
+  0xd9, 0xa4, 0x13, 0x52, 0x65, 0xd7, 0x4b, 0x33, 0x82, 0x84, 0x67, 0x97,
+  0x46, 0xfa, 0x47, 0x6f, 0xa4, 0xda, 0xc0, 0x60, 0x4c, 0x8f, 0xe4, 0x35,
+  0x5b, 0x7e, 0x57, 0xc6, 0x94, 0xa0, 0x43, 0xa3, 0x9a, 0x2d, 0x34, 0x1a,
+  0xd9, 0x31, 0x91, 0x0d, 0x63, 0x77, 0x69, 0x49, 0x47, 0xa5, 0xc9, 0x8c,
+  0xa0, 0x81, 0xf8, 0xa7, 0x27, 0x07, 0x66, 0xc9, 0x06, 0x83, 0xda, 0xcc,
+  0x3f, 0xa9, 0xc3, 0x0b, 0x31, 0xb3, 0xcf, 0xe0, 0xc3, 0xb0, 0x0e, 0x8f,
+  0x33, 0x76, 0x75, 0xf0, 0xb5, 0xc9, 0xef, 0x42, 0x84, 0x1a, 0x45, 0xf5,
+  0xce, 0x7c, 0x38, 0x35, 0x4b, 0x66, 0x0e, 0xdc, 0x1b, 0x9a, 0x28, 0x76,
+  0x57, 0x24, 0xd2, 0x54, 0x9d, 0x60, 0x67, 0xe4, 0x74, 0xee, 0x53, 0xa7,
+  0xcb, 0x4c, 0xa7, 0x39, 0xfd, 0xd6, 0x9c, 0x2f, 0x73, 0xc3, 0x2d, 0x33,
+  0x98, 0x03, 0x32, 0xa9, 0x73, 0x37, 0x99, 0xb0, 0x2c, 0xeb, 0x9b, 0x92,
+  0x2c, 0xb7, 0x1e, 0xcb, 0xe2, 0x01, 0x7d, 0xab, 0x87, 0xfb, 0x7c, 0x9e,
+  0xe8, 0xb7, 0xe4, 0x53, 0x66, 0x1c, 0x53, 0x5f, 0x37, 0xeb, 0x9b, 0x8b,
+  0xe6, 0xde, 0xd3, 0xdb, 0x21, 0xab, 0xb9, 0xef, 0x95, 0x55, 0x78, 0xcc,
+  0x95, 0xba, 0x20, 0x65, 0x4a, 0x64, 0x38, 0x2e, 0x43, 0x1c, 0xd9, 0x9a,
+  0xbb, 0xd6, 0x37, 0x73, 0x4b, 0x4f, 0x5e, 0xdf, 0xe8, 0xa3, 0xde, 0xc5,
+  0x9a, 0x9a, 0xc1, 0xd1, 0xe5, 0x40, 0x26, 0xee, 0x54, 0xe5, 0x7e, 0x59,
+  0xb1, 0x30, 0x9b, 0x95, 0x66, 0x2f, 0xf7, 0x58, 0x65, 0x95, 0x6e, 0x53,
+  0xaf, 0xa9, 0x97, 0x34, 0xe3, 0xec, 0xfa, 0x29, 0xed, 0xda, 0xd8, 0x4e,
+  0xcb, 0x7c, 0xd5, 0x0f, 0x76, 0xcd, 0x4d, 0xd4, 0x08, 0x73, 0x64, 0xae,
+  0xce, 0x9a, 0xf6, 0xb1, 0xce, 0x3c, 0xb6, 0xb7, 0xb9, 0xea, 0x36, 0x1b,
+  0x3e, 0x8f, 0x30, 0x7b, 0x3a, 0x33, 0x5f, 0x63, 0xfb, 0xc8, 0x45, 0x66,
+  0x47, 0x66, 0x46, 0x34, 0xcd, 0x53, 0xec, 0x13, 0x5e, 0x1a, 0x28, 0x23,
+  0xce, 0x48, 0x8b, 0xe8, 0xc1, 0xf7, 0x5d, 0x1b, 0x6b, 0x36, 0xf3, 0xaf,
+  0x24, 0xed, 0xd3, 0xe0, 0xcc, 0x8c, 0xfd, 0x14, 0xe3, 0x18, 0xdc, 0x26,
+  0x74, 0xfc, 0x8c, 0xd9, 0x40, 0x67, 0x71, 0x70, 0x76, 0x7a, 0xeb, 0x1d,
+  0x23, 0x32, 0xa6, 0x0b, 0xd2, 0x53, 0xfa, 0x70, 0x58, 0x8c, 0xcb, 0xd2,
+  0x58, 0xae, 0x6e, 0x68, 0x74, 0x1f, 0x64, 0x05, 0xed, 0x76, 0x59, 0x51,
+  0x23, 0x12, 0x16, 0x56, 0xde, 0xde, 0x1b, 0x73, 0x29, 0xbd, 0x4e, 0x73,
+  0xbb, 0xdf, 0xe4, 0x64, 0x4c, 0x13, 0x7d, 0xb8, 0x28, 0xe5, 0x79, 0x5a,
+  0x2a, 0x52, 0x81, 0x44, 0x6e, 0x2d, 0x6b, 0x3e, 0x3e, 0x66, 0x54, 0x46,
+  0xf2, 0x40, 0x76, 0x48, 0xbb, 0xa4, 0x36, 0x6a, 0x73, 0x63, 0x28, 0xca,
+  0xa4, 0x73, 0x42, 0xf8, 0x42, 0x83, 0x34, 0x2d, 0xf6, 0x86, 0xc9, 0x37,
+  0xe5, 0x5d, 0x06, 0xf7, 0x1d, 0xf4, 0xfb, 0x9c, 0x1c, 0x50, 0x46, 0x15,
+  0xbc, 0xcb, 0x92, 0xb9, 0x51, 0x3d, 0xcd, 0x6c, 0x42, 0xfb, 0xc0, 0xcf,
+  0x4c, 0x3f, 0x9d, 0xcd, 0x52, 0xde, 0xf1, 0x2c, 0xd9, 0x51, 0xd8, 0xa5,
+  0xbc, 0xe2, 0x23, 0x91, 0x6c, 0x41, 0xbd, 0x99, 0xd0, 0x6c, 0x2d, 0x1a,
+  0x37, 0x0a, 0x3b, 0x21, 0x77, 0x69, 0xed, 0x1d, 0x2e, 0x36, 0x4e, 0x93,
+  0x4f, 0x86, 0x7b, 0x9f, 0x0d, 0x77, 0x87, 0x64, 0x8a, 0x64, 0xb7, 0x79,
+  0xb9, 0xac, 0x69, 0x3d, 0xa9, 0x27, 0xde, 0xe9, 0x24, 0x37, 0x11, 0x2d,
+  0xef, 0xf5, 0xf5, 0x8c, 0x15, 0x9f, 0x9d, 0xf2, 0xea, 0x2a, 0xf1, 0x94,
+  0xa3, 0x2a, 0x5b, 0xb0, 0x0d, 0x44, 0x73, 0x23, 0x07, 0x8e, 0x85, 0xaa,
+  0xaf, 0x15, 0xc9, 0x6c, 0x3a, 0x8f, 0xc2, 0x60, 0x90, 0x8e, 0xeb, 0x86,
+  0xcc, 0xa9, 0xc1, 0xb2, 0xc8, 0x3f, 0x0e, 0xea, 0x72, 0xf2, 0xc1, 0x2c,
+  0xcb, 0x8b, 0x45, 0xda, 0xdc, 0x7c, 0xd1, 0xf1, 0xd4, 0x6e, 0xd1, 0x6d,
+  0xb2, 0x9d, 0x24, 0x47, 0xac, 0x58, 0xd2, 0x5c, 0x54, 0x7c, 0xe2, 0xcc,
+  0x7a, 0x4a, 0x2b, 0xc9, 0x3b, 0xd3, 0x8a, 0xd9, 0xcd, 0x73, 0xb3, 0xac,
+  0x09, 0x37, 0xd6, 0x57, 0x61, 0xda, 0x69, 0x0e, 0x5e, 0x40, 0xba, 0x48,
+  0xe0, 0x4c, 0x33, 0x87, 0xa7, 0xac, 0x3e, 0x0c, 0xc9, 0x6d, 0x61, 0xac,
+  0xc6, 0x03, 0xda, 0xd0, 0x8d, 0x11, 0x63, 0x0d, 0xcf, 0x7b, 0x2d, 0x42,
+  0x98, 0xba, 0xc5, 0x32, 0xd9, 0x49, 0x29, 0x9d, 0x4f, 0xed, 0x81, 0x7c,
+  0x36, 0x51, 0x7b, 0x43, 0xb6, 0xde, 0xe6, 0x97, 0xc6, 0x02, 0xbc, 0xe1,
+  0x85, 0x47, 0x63, 0x3c, 0x46, 0xb3, 0x47, 0xaf, 0x8d, 0x0d, 0x51, 0x34,
+  0x9d, 0xe6, 0xcc, 0x57, 0xe9, 0xb2, 0xa6, 0x7b, 0x86, 0xcd, 0x5d, 0x6c,
+  0x13, 0x71, 0xcb, 0x58, 0x0b, 0x74, 0xb8, 0xd1, 0x79, 0xed, 0x50, 0x57,
+  0xf5, 0x93, 0xe1, 0xb3, 0x27, 0x66, 0x51, 0xfd, 0x89, 0x2e, 0xee, 0xc9,
+  0x9d, 0x19, 0x9f, 0xd4, 0x4b, 0x73, 0x97, 0xd6, 0xac, 0x9e, 0x98, 0x33,
+  0x7c, 0x95, 0x5f, 0x2f, 0xab, 0x8c, 0x2f, 0x35, 0x78, 0x40, 0xd5, 0xf1,
+  0x49, 0xf7, 0xc4, 0x4d, 0x09, 0x7f, 0xa1, 0x91, 0x2f, 0xd9, 0xec, 0xaa,
+  0xdf, 0x9d, 0x05, 0xd2, 0xe8, 0x68, 0x0b, 0x60, 0x88, 0xd8, 0x44, 0x46,
+  0x73, 0x43, 0x63, 0x45, 0x26, 0xf7, 0xfa, 0xdc, 0x4c, 0x70, 0x42, 0x0e,
+  0xb3, 0x64, 0x32, 0x4b, 0xf3, 0x39, 0xcc, 0x1d, 0x71, 0x08, 0x0d, 0x3b,
+  0xcd, 0x5d, 0x8a, 0x3a, 0x0e, 0x4d, 0x7c, 0x4c, 0xd6, 0x40, 0x55, 0x93,
+  0xb0, 0xa2, 0x49, 0x48, 0x55, 0x99, 0x60, 0x5d, 0xfb, 0x26, 0x9b, 0x7c,
+  0xd0, 0xd5, 0xd4, 0x5b, 0x78, 0xd0, 0x69, 0x8e, 0x3c, 0xa1, 0x30, 0x39,
+  0xcc, 0x53, 0x4b, 0xb3, 0xa6, 0x8b, 0xb2, 0xae, 0x73, 0xf2, 0x28, 0x90,
+  0x86, 0xbc, 0x9c, 0x40, 0x71, 0x26, 0x13, 0xfb, 0xa3, 0x59, 0x49, 0xdd,
+  0x12, 0x89, 0xd9, 0x63, 0xc5, 0x74, 0xd0, 0x54, 0xf9, 0x62, 0x55, 0xef,
+  0xf8, 0xca, 0x68, 0xdf, 0xd9, 0xb5, 0x18, 0x31, 0xb0, 0x0f, 0xd8, 0x62,
+  0x98, 0x24, 0x9d, 0xd9, 0xec, 0x34, 0xc7, 0x73, 0xdb, 0x27, 0x13, 0x39,
+  0x37, 0x22, 0x94, 0xf5, 0x47, 0x78, 0x80, 0x8c, 0xb6, 0x28, 0x67, 0xd9,
+  0x28, 0xb6, 0xf9, 0x04, 0xf7, 0x42, 0x7e, 0x9d, 0x91, 0xc7, 0xd9, 0x1c,
+  0xef, 0x66, 0x66, 0x6e, 0x0b, 0x4f, 0x50, 0xd8, 0x15, 0x2f, 0xb2, 0xeb,
+  0xb2, 0x21, 0x01, 0x1d, 0x6c, 0x93, 0x77, 0xd8, 0xf8, 0x76, 0x4f, 0xa8,
+  0x26, 0xe4, 0x5f, 0x53, 0x39, 0xab, 0x28, 0xe6, 0xd3, 0xac, 0x09, 0x89,
+  0x11, 0x56, 0x37, 0x66, 0x07, 0x76, 0x57, 0xdd, 0xb4, 0x36, 0xc9, 0xa0,
+  0x8e, 0xe2, 0x2e, 0xd5, 0xab, 0x5c, 0x75, 0xa0, 0x31, 0x99, 0x6c, 0x64,
+  0x1e, 0xdf, 0xe5, 0x93, 0x4c, 0x3d, 0x14, 0xe2, 0x49, 0x9b, 0xe5, 0xe1,
+  0xde, 0x9f, 0x2f, 0x6b, 0x58, 0x4d, 0xac, 0xa6, 0x90, 0x41, 0x79, 0x97,
+  0x93, 0x1a, 0x73, 0x72, 0x25, 0x67, 0x95, 0x6e, 0x51, 0x3e, 0x1f, 0x69,
+  0x95, 0xc3, 0x7a, 0x36, 0xcd, 0x49, 0x3f, 0x3d, 0x23, 0x47, 0xed, 0x36,
+  0xd7, 0x6f, 0xbc, 0x2f, 0x9a, 0x9d, 0xd3, 0xe8, 0x60, 0x48, 0x5e, 0xa5,
+  0xf9, 0x2c, 0x32, 0x4f, 0x50, 0x50, 0x8d, 0x45, 0x7a, 0x93, 0x55, 0xb2,
+  0x06, 0x4b, 0x9a, 0x74, 0x8a, 0x0e, 0x04, 0x4f, 0x8f, 0xb2, 0x8c, 0x55,
+  0x2c, 0xe8, 0x63, 0x1f, 0xef, 0xed, 0xf4, 0xe2, 0x1e, 0xe3, 0xb5, 0x93,
+  0xbf, 0xf3, 0xf2, 0x79, 0xc7, 0x33, 0xa5, 0x56, 0xd3, 0x05, 0xb9, 0xc1,
+  0xbb, 0x27, 0x94, 0xb4, 0x51, 0x8a, 0xa4, 0x6c, 0xab, 0x53, 0x4d, 0x9c,
+  0x8a, 0x85, 0x8d, 0x40, 0x40, 0x38, 0x90, 0xc3, 0x5f, 0x8e, 0x30, 0xb7,
+  0x23, 0x9a, 0x52, 0xa7, 0x39, 0xa3, 0x9a, 0x91, 0x9f, 0x10, 0x46, 0x78,
+  0x6b, 0xc7, 0x1a, 0x83, 0xb8, 0xb2, 0x7e, 0x70, 0x72, 0x82, 0xd1, 0x7c,
+  0xab, 0xee, 0x89, 0x33, 0x8b, 0x97, 0x3a, 0xcd, 0x91, 0x36, 0x4c, 0xaa,
+  0x83, 0x39, 0x34, 0x39, 0xed, 0x47, 0x6c, 0x02, 0x75, 0x85, 0x9a, 0xed,
+  0xcb, 0x9e, 0x31, 0x95, 0xab, 0xac, 0x6c, 0xa0, 0xbb, 0x57, 0xb3, 0xf4,
+  0xda, 0xec, 0xbb, 0x4e, 0x73, 0xf9, 0xb5, 0xb1, 0x71, 0x39, 0x20, 0x51,
+  0x97, 0xe6, 0xf6, 0xa0, 0x71, 0x8b, 0xbd, 0x6f, 0xcc, 0x3d, 0xb3, 0xcd,
+  0x66, 0x4b, 0x48, 0xc0, 0x33, 0x33, 0xc0, 0xd1, 0xe8, 0x9b, 0x6d, 0x5f,
+  0xc0, 0x61, 0x7e, 0x1f, 0x23, 0xde, 0x20, 0x9f, 0x60, 0x9a, 0x24, 0x5f,
+  0x61, 0x4d, 0xba, 0x52, 0x8e, 0x57, 0x3a, 0x32, 0x79, 0x3a, 0x11, 0xe4,
+  0x22, 0x1a, 0x8a, 0x00, 0x80, 0x04, 0xc0, 0x34, 0xa9, 0xb7, 0x8a, 0x77,
+  0x38, 0x79, 0x11, 0xf8, 0x9a, 0x36, 0x7f, 0x5b, 0xd6, 0x4b, 0x32, 0xdc,
+  0x3b, 0xcd, 0x2d, 0x8c, 0x20, 0x6b, 0x8c, 0xf1, 0x66, 0x24, 0xd2, 0xb2,
+  0xa0, 0x3f, 0xad, 0x76, 0x91, 0x43, 0xcf, 0xa5, 0x25, 0xa9, 0xc8, 0x39,
+  0x48, 0x16, 0x82, 0xbd, 0x9b, 0x8d, 0x68, 0x91, 0x96, 0xbb, 0x4b, 0x0b,
+  0xf7, 0x09, 0x05, 0x2f, 0x20, 0x76, 0xa6, 0x39, 0x05, 0xbe, 0xe8, 0xe0,
+  0xad, 0x90, 0xe2, 0x5b, 0xf5, 0xd2, 0xc8, 0x19, 0xd2, 0xaa, 0x58, 0x88,
+  0x04, 0x02, 0x44, 0x85, 0x8c, 0x51, 0xe0, 0x3c, 0x69, 0xb2, 0xfd, 0x5b,
+  0x1f, 0x13, 0x2c, 0x9c, 0xbf, 0x92, 0x13, 0xa3, 0xcf, 0x1a, 0x4d, 0xf5,
+  0x05, 0xed, 0xb7, 0x40, 0x0b, 0xb8, 0x3c, 0x1d, 0xc5, 0x16, 0xb4, 0xed,
+  0x4c, 0xa7, 0xf7, 0x49, 0xe4, 0x92, 0x7f, 0x85, 0xfd, 0x4d, 0x25, 0x69,
+  0x4b, 0x46, 0xe5, 0x0c, 0xe6, 0x8c, 0xae, 0xf5, 0xcc, 0x74, 0x53, 0x0c,
+  0x09, 0x0e, 0xd4, 0x91, 0x18, 0x33, 0x6a, 0x54, 0x43, 0x6a, 0x84, 0xf5,
+  0x2d, 0x1d, 0x1d, 0xfa, 0xed, 0xc2, 0x99, 0xd4, 0xdd, 0x20, 0xde, 0xef,
+  0xb7, 0xea, 0x6d, 0x2b, 0xc9, 0x4c, 0x2b, 0xe7, 0xc7, 0x6f, 0xa0, 0xd8,
+  0xa7, 0x66, 0xe3, 0xbc, 0x55, 0x3f, 0x8e, 0xc6, 0xe1, 0xc6, 0xcb, 0x7c,
+  0xd6, 0x72, 0x96, 0x3a, 0x5b, 0x04, 0x41, 0x30, 0xde, 0x57, 0xe8, 0x1a,
+  0xbb, 0xfd, 0x73, 0xf8, 0xcd, 0xba, 0xbb, 0xac, 0xb9, 0x5f, 0x88, 0xcb,
+  0x6f, 0x59, 0xb7, 0x2c, 0x6b, 0xbd, 0x9d, 0x67, 0x0d, 0x94, 0x0f, 0x52,
+  0xf8, 0xbd, 0x36, 0x83, 0x15, 0x42, 0xb7, 0xe8, 0x32, 0xb8, 0x2e, 0xf2,
+  0x7f, 0x88, 0x6f, 0x21, 0x2b, 0x6e, 0xf3, 0xaa, 0x2c, 0x48, 0x55, 0x31,
+  0x36, 0x41, 0x95, 0x43, 0x38, 0x93, 0xba, 0x6b, 0xc4, 0xc7, 0xe6, 0xd1,
+  0xbb, 0x8b, 0xd3, 0xf7, 0x47, 0x87, 0xef, 0xbf, 0x7a, 0xf7, 0xf6, 0xd5,
+  0xe9, 0xf1, 0x66, 0xf7, 0x50, 0x5f, 0xb1, 0x58, 0xa0, 0x83, 0x52, 0x93,
+  0x42, 0x86, 0x13, 0x62, 0xba, 0xc8, 0x2d, 0x5f, 0xe7, 0xb7, 0x46, 0xac,
+  0x41, 0xb5, 0x82, 0xf3, 0x12, 0x7f, 0x83, 0xb9, 0x2f, 0x13, 0xde, 0x69,
+  0x6e, 0x6c, 0xee, 0x63, 0xd3, 0x69, 0x3e, 0x7d, 0x32, 0x78, 0x3d, 0x29,
+  0x62, 0xce, 0x68, 0x07, 0x83, 0x91, 0xd1, 0x12, 0xd3, 0x65, 0x42, 0x2a,
+  0x9d, 0xa7, 0x3d, 0x7b, 0x7e, 0xcc, 0x65, 0x63, 0x94, 0x47, 0xf5, 0x9c,
+  0x1a, 0xeb, 0xac, 0xfc, 0xa0, 0x11, 0x51, 0xa3, 0x79, 0x1e, 0x46, 0x96,
+  0xbb, 0xe6, 0x75, 0xe1, 0xa9, 0xd8, 0xa4, 0x96, 0xcc, 0xfe, 0x1d, 0x48,
+  0x27, 0x27, 0x55, 0x63, 0xd4, 0xbe, 0x2c, 0xc7, 0xc1, 0xd0, 0x90, 0x0f,
+  0xa9, 0xc5, 0xf0, 0x5a, 0x74, 0xf5, 0x13, 0x63, 0x14, 0xde, 0xd3, 0x1c,
+  0x50, 0x23, 0xc3, 0xec, 0x63, 0x86, 0x93, 0x27, 0x6f, 0x1d, 0x2d, 0x2b,
+  0x9c, 0xe5, 0xef, 0x8d, 0x4e, 0x42, 0x12, 0xf0, 0x15, 0xdc, 0x1e, 0xe6,
+  0x05, 0x7d, 0xc8, 0x5c, 0x36, 0xdd, 0x8b, 0xaf, 0x9c, 0x4d, 0xc9, 0xbd,
+  0x00, 0x13, 0x13, 0x0e, 0x81, 0xf3, 0xc3, 0xcb, 0x6f, 0x82, 0x39, 0x21,
+  0x31, 0xef, 0xe0, 0x07, 0xb2, 0x15, 0x61, 0x18, 0xd5, 0x8d, 0x1c, 0x90,
+  0xb7, 0xa3, 0x51, 0x82, 0xe0, 0xf6, 0x2c, 0x1f, 0x57, 0x29, 0x7d, 0x93,
+  0x7e, 0x4c, 0x3f, 0x35, 0xdb, 0xba, 0xd3, 0xdc, 0xf9, 0xb7, 0x47, 0xa3,
+  0x3f, 0xee, 0xed, 0x19, 0xe5, 0x6f, 0xba, 0x34, 0xf3, 0xb2, 0x65, 0x5e,
+  0x29, 0x6a, 0x73, 0x32, 0xe7, 0xc3, 0xba, 0xdc, 0xc6, 0xe5, 0x0d, 0x8d,
+  0x0f, 0xd7, 0x43, 0x7a, 0x6b, 0x6e, 0x5d, 0xec, 0x24, 0x9e, 0x63, 0xda,
+  0xcf, 0x5d, 0x35, 0x9d, 0x17, 0x58, 0x63, 0xff, 0x46, 0x62, 0x98, 0x7b,
+  0x7b, 0x76, 0x1f, 0x8c, 0x62, 0x2b, 0x3f, 0x1b, 0x49, 0xe4, 0x3c, 0x9d,
+  0x98, 0xbf, 0x92, 0x0d, 0xb5, 0x4d, 0x63, 0x6b, 0x9f, 0x31, 0x1d, 0xd7,
+  0x88, 0xb5, 0xd2, 0x4b, 0x72, 0x71, 0x22, 0xe0, 0x1f, 0xca, 0x85, 0xa2,
+  0x7b, 0xbc, 0x1c, 0xa8, 0x02, 0x9d, 0x1d, 0xa7, 0x93, 0x0f, 0x77, 0x69,
+  0x35, 0x65, 0x87, 0x89, 0xd9, 0x33, 0xe3, 0x7c, 0x96, 0x37, 0xf7, 0x7c,
+  0x7b, 0x74, 0x47, 0xc1, 0xa1, 0x23, 0x9a, 0x42, 0x73, 0x92, 0xae, 0x8d,
+  0x2d, 0x44, 0x5a, 0x28, 0x59, 0x88, 0xe6, 0x60, 0x78, 0xba, 0x3e, 0x54,
+  0xa5, 0xc6, 0xaa, 0x3a, 0xf6, 0xdb, 0x9d, 0xe6, 0xe0, 0x7e, 0xa2, 0x93,
+  0x84, 0x6e, 0xba, 0xdd, 0xab, 0x82, 0xd0, 0x17, 0x53, 0xba, 0x81, 0x92,
+  0xfa, 0xde, 0xdc, 0xf6, 0xf3, 0x24, 0xa2, 0x2a, 0x02, 0xeb, 0x90, 0x7c,
+  0x9b, 0xdd, 0x1b, 0xc3, 0x22, 0x2f, 0x9c, 0xac, 0x64, 0x1f, 0x51, 0x46,
+  0x96, 0x2a, 0xeb, 0xa4, 0xb9, 0xfa, 0x19, 0x33, 0x71, 0x15, 0xf3, 0x4d,
+  0x12, 0x5a, 0x56, 0xfc, 0xbe, 0xea, 0xe3, 0xd4, 0xc4, 0x66, 0xdd, 0x12,
+  0xca, 0xf8, 0x52, 0x6c, 0x2b, 0x06, 0x17, 0x27, 0x5c, 0x26, 0x1c, 0x13,
+  0x26, 0x97, 0x73, 0xcd, 0x7b, 0x6f, 0x96, 0xd6, 0x0d, 0x6c, 0x0a, 0x8c,
+  0x5b, 0x3c, 0x13, 0xed, 0x3b, 0x04, 0x72, 0xe4, 0x85, 0x39, 0x68, 0xff,
+  0xfc, 0x15, 0xc2, 0xc7, 0x15, 0xc7, 0x33, 0x94, 0xaa, 0x32, 0x57, 0xad,
+  0xab, 0xe4, 0x8d, 0xde, 0x19, 0xd4, 0x09, 0xeb, 0x3d, 0x59, 0x70, 0xac,
+  0x8f, 0xd5, 0x1b, 0x76, 0x03, 0x85, 0xea, 0x2a, 0x59, 0xf2, 0xe2, 0x2d,
+  0x38, 0xe8, 0x25, 0x5b, 0xd9, 0xf0, 0xda, 0xb4, 0xd7, 0xa3, 0x76, 0xf6,
+  0x0e, 0xe8, 0xbf, 0xfb, 0xf8, 0xef, 0x93, 0x9e, 0x02, 0x65, 0xfc, 0xa5,
+  0xa6, 0xfb, 0xa6, 0x2b, 0x2d, 0xc5, 0x95, 0x4e, 0xf7, 0x8f, 0x5c, 0x40,
+  0x22, 0x80, 0x49, 0x2e, 0xc7, 0x0f, 0x07, 0x6b, 0x57, 0xa7, 0xfd, 0x88,
+  0x06, 0xe4, 0x26, 0x02, 0x77, 0x1b, 0x6c, 0xd3, 0x31, 0xb9, 0x9d, 0xcc,
+  0xd8, 0x26, 0x46, 0x83, 0x81, 0x07, 0x80, 0x03, 0x53, 0x34, 0x1d, 0x93,
+  0xf7, 0x55, 0x76, 0x93, 0xd6, 0x46, 0x99, 0x5a, 0x36, 0x38, 0x1d, 0x5d,
+  0xcb, 0xc1, 0x1c, 0xa9, 0x59, 0x6e, 0x5d, 0x2e, 0xf2, 0xe1, 0xa1, 0x35,
+  0x50, 0x64, 0x15, 0xd9, 0x79, 0x39, 0x2b, 0xef, 0xf4, 0x89, 0x81, 0x20,
+  0x57, 0x62, 0x17, 0x97, 0x59, 0x4d, 0x80, 0x5f, 0xe8, 0x31, 0x3f, 0x08,
+  0x35, 0x27, 0x6d, 0x87, 0x60, 0x35, 0xe6, 0x08, 0x5e, 0x99, 0x19, 0x23,
+  0xcb, 0x63, 0x86, 0x75, 0x23, 0x1b, 0x0b, 0xbd, 0x0e, 0x34, 0x20, 0xd1,
+  0x44, 0xf2, 0x2b, 0x71, 0xbc, 0xc8, 0xbf, 0x21, 0xf1, 0x45, 0x3f, 0xa8,
+  0x39, 0x50, 0xd5, 0x55, 0x0e, 0x1e, 0xde, 0xda, 0x7a, 0x80, 0xed, 0x5d,
+  0x2c, 0x83, 0x65, 0x5f, 0xa7, 0xee, 0x6b, 0xd1, 0x88, 0x63, 0x86, 0xb6,
+  0xe9, 0x15, 0xc7, 0x0c, 0x7e, 0xfd, 0x21, 0x31, 0x3d, 0x1e, 0x90, 0x9b,
+  0x63, 0x59, 0x3f, 0xe2, 0x8c, 0x78, 0x42, 0x81, 0xdf, 0xb1, 0x8e, 0x1e,
+  0x0e, 0xc8, 0xf9, 0x13, 0xd0, 0xdd, 0x85, 0xf7, 0x9e, 0xb3, 0xe5, 0xc8,
+  0x3b, 0x59, 0x23, 0x6e, 0xe8, 0x42, 0x4c, 0xf9, 0xad, 0xf4, 0x43, 0x3a,
+  0x4c, 0xce, 0x8e, 0x46, 0xe7, 0xf4, 0x09, 0xb3, 0x35, 0x8a, 0x6b, 0xd3,
+  0x8b, 0xd3, 0x51, 0xa7, 0x39, 0x63, 0xa1, 0x67, 0x45, 0xdd, 0x82, 0x7a,
+  0xad, 0x9c, 0x66, 0x75, 0x00, 0x6a, 0x64, 0x5c, 0x3a, 0x6b, 0x2c, 0x52,
+  0x84, 0xb4, 0x28, 0x42, 0x43, 0xe1, 0xd3, 0x84, 0x8f, 0x5a, 0xf0, 0xa1,
+  0x85, 0xd9, 0xf0, 0xd3, 0x6d, 0xeb, 0x52, 0xe8, 0xeb, 0x5e, 0xb0, 0x9e,
+  0xfe, 0x7a, 0x79, 0x4d, 0x5a, 0x72, 0xad, 0xb6, 0x8d, 0xfd, 0x82, 0x99,
+  0x8d, 0xe0, 0x82, 0xd7, 0x61, 0x9b, 0x33, 0xc1, 0xc7, 0xc6, 0xa8, 0xf5,
+  0x04, 0x82, 0xc0, 0x25, 0x5e, 0x94, 0xae, 0x55, 0xd2, 0xe4, 0x81, 0xc1,
+  0xca, 0xe1, 0x1b, 0x9f, 0x64, 0x46, 0x49, 0x9a, 0x46, 0x2e, 0x29, 0x5e,
+  0x14, 0x55, 0xec, 0xaf, 0x04, 0x77, 0x15, 0xf1, 0x53, 0xa0, 0xa1, 0x09,
+  0x2b, 0x11, 0xb4, 0xeb, 0xe1, 0x63, 0xcc, 0xc9, 0x29, 0x4b, 0x2a, 0x1d,
+  0x9b, 0x94, 0xd4, 0x9e, 0x3d, 0xfb, 0x5f, 0x17, 0x4b, 0x33, 0xf1, 0x91,
+  0xdb, 0x82, 0xae, 0x7d, 0xba, 0xfb, 0x68, 0x02, 0xd7, 0x39, 0xa0, 0x9e,
+  0xee, 0xb5, 0x1d, 0x50, 0xd8, 0x6c, 0x46, 0x45, 0xcd, 0x92, 0x17, 0xf4,
+  0xdf, 0x07, 0xa5, 0x32, 0xa2, 0xce, 0xbe, 0x14, 0xc6, 0xbb, 0x12, 0xb6,
+  0x60, 0x39, 0xba, 0x66, 0xc7, 0x21, 0xa0, 0x3d, 0x24, 0xb1, 0xd7, 0x4f,
+  0x5e, 0x1d, 0x5f, 0x60, 0xf9, 0x8f, 0xdf, 0x7e, 0x0d, 0x9f, 0xb0, 0x55,
+  0x6d, 0xa7, 0x68, 0xb3, 0x66, 0x5b, 0x97, 0x63, 0x3a, 0x22, 0xfe, 0xbb,
+  0x53, 0x4d, 0xe2, 0x93, 0x5c, 0xf9, 0x88, 0xf8, 0x4f, 0x7f, 0xbf, 0x8b,
+  0x2b, 0xb0, 0x91, 0x8e, 0xfb, 0x32, 0x75, 0xe2, 0x39, 0xf8, 0x90, 0xdd,
+  0xbb, 0xbf, 0x61, 0x3a, 0xbd, 0x39, 0x76, 0x0f, 0xbf, 0xf0, 0x66, 0xe6,
+  0xc7, 0x03, 0x42, 0x15, 0x18, 0xf5, 0x69, 0xfa, 0xf3, 0xaf, 0xbb, 0x0a,
+  0xc5, 0x4d, 0x93, 0xb4, 0xef, 0xc4, 0x88, 0x37, 0x00, 0x8e, 0x18, 0x8d,
+  0xdf, 0x73, 0xb8, 0x8e, 0x05, 0xbb, 0xa0, 0x4a, 0x09, 0x70, 0x4a, 0x3b,
+  0x3d, 0x2d, 0x58, 0x21, 0x22, 0x11, 0xcd, 0xa0, 0x0d, 0x80, 0x38, 0xba,
+  0xc7, 0x65, 0x52, 0xce, 0x82, 0x4b, 0xae, 0x65, 0x53, 0x41, 0xd5, 0xdc,
+  0x97, 0x6b, 0x0d, 0x76, 0x86, 0x5c, 0x3e, 0xac, 0xde, 0x75, 0xcf, 0x81,
+  0x55, 0xf6, 0x80, 0x87, 0xf2, 0xaf, 0xc4, 0xc4, 0x7b, 0x19, 0xe1, 0x29,
+  0x74, 0x8f, 0x35, 0xb5, 0xa1, 0x2c, 0x6f, 0x16, 0xd5, 0x4c, 0xcd, 0xea,
+  0xea, 0xec, 0x9a, 0x65, 0x27, 0x57, 0x88, 0xdb, 0x43, 0xec, 0xf7, 0xe7,
+  0x65, 0x36, 0xf2, 0xad, 0xca, 0x45, 0x75, 0x64, 0x18, 0x59, 0xf7, 0x30,
+  0x6b, 0x94, 0x50, 0x5c, 0x25, 0x62, 0xce, 0x63, 0x5b, 0xe9, 0xbe, 0xe2,
+  0xed, 0x47, 0x46, 0x52, 0xcf, 0x9b, 0x92, 0x5e, 0x6c, 0x29, 0x1a, 0x0e,
+  0x58, 0xc8, 0x79, 0xc9, 0x6f, 0x69, 0xea, 0x74, 0xef, 0x38, 0xcf, 0x5b,
+  0x5b, 0x27, 0x2b, 0x0b, 0xfa, 0xb3, 0x20, 0x8f, 0xcd, 0x1f, 0x22, 0x1b,
+  0x32, 0xba, 0x17, 0xc9, 0x79, 0x2b, 0xc1, 0x1c, 0x68, 0x2e, 0x04, 0x5c,
+  0x12, 0x30, 0x67, 0x44, 0x4b, 0x8f, 0xd9, 0x1a, 0xaa, 0x75, 0xa8, 0x49,
+  0xe1, 0xd9, 0x19, 0x81, 0x1a, 0xde, 0xdd, 0x20, 0x46, 0x7e, 0x37, 0x14,
+  0x06, 0xe6, 0xbd, 0x4b, 0xce, 0xc1, 0x7c, 0xf2, 0x01, 0x68, 0x1f, 0xb9,
+  0x9a, 0x5a, 0xf2, 0x43, 0xb0, 0x36, 0x8c, 0x12, 0x8b, 0x2c, 0x01, 0xcc,
+  0x1c, 0xf2, 0x5a, 0xd2, 0x9e, 0xa4, 0x6b, 0x39, 0x2f, 0x58, 0x59, 0x5b,
+  0x69, 0x00, 0x9b, 0xbe, 0xbe, 0x7f, 0x75, 0x72, 0x91, 0x6c, 0x99, 0x55,
+  0x1d, 0x77, 0x95, 0x1b, 0xbd, 0xd7, 0x77, 0xb2, 0x66, 0xb2, 0xb3, 0xf8,
+  0x90, 0xef, 0x18, 0x3b, 0x68, 0x3a, 0xde, 0xb6, 0xda, 0x3d, 0x3e, 0x87,
+  0x4d, 0xa8, 0x36, 0x93, 0x1a, 0x4d, 0xb0, 0x9a, 0xba, 0xa7, 0xc1, 0xb3,
+  0xa2, 0x18, 0x28, 0xee, 0x8c, 0x27, 0x4c, 0x13, 0xbb, 0x18, 0x00, 0x52,
+  0xe1, 0x88, 0x66, 0x42, 0xde, 0xc1, 0x8c, 0x1d, 0xa7, 0xc6, 0xfc, 0xeb,
+  0x9e, 0x55, 0x46, 0x2c, 0x89, 0x8f, 0x81, 0x7d, 0x0b, 0x0a, 0xb3, 0x91,
+  0x7b, 0xc2, 0x69, 0x7b, 0x7d, 0x02, 0x48, 0xd1, 0xa4, 0x2c, 0xe8, 0x2e,
+  0x9a, 0x92, 0x83, 0xaa, 0xdb, 0x1c, 0x5c, 0x66, 0xbd, 0xe1, 0x4e, 0x2f,
+  0xb1, 0x90, 0x30, 0x33, 0xcb, 0x40, 0x35, 0x3a, 0x0c, 0x9e, 0xd9, 0x62,
+  0x57, 0xcb, 0x9a, 0x9d, 0xae, 0x64, 0xef, 0xdb, 0xf5, 0x1a, 0xc6, 0x04,
+  0xaa, 0xb7, 0x9c, 0x56, 0xd9, 0x32, 0x4a, 0x31, 0xce, 0x95, 0x35, 0x24,
+  0xc7, 0xb6, 0x53, 0x58, 0xaa, 0xde, 0x4f, 0xbd, 0xc4, 0x83, 0x14, 0xb5,
+  0x5c, 0x63, 0xb9, 0x0b, 0xfa, 0x7b, 0x57, 0x80, 0xb9, 0x8a, 0xed, 0x09,
+  0x9e, 0x66, 0xb3, 0x7c, 0x9e, 0x37, 0xd0, 0xe1, 0xbd, 0x2e, 0x04, 0x4b,
+  0xd1, 0xee, 0xd2, 0x4f, 0x61, 0x97, 0x14, 0xa6, 0x97, 0xd2, 0xaf, 0x4d,
+  0x97, 0xe0, 0xac, 0x61, 0x14, 0x55, 0xdc, 0x9c, 0x6b, 0x77, 0xc8, 0x02,
+  0xfd, 0xd6, 0xc4, 0x7a, 0x7e, 0x1f, 0x8b, 0xb7, 0x7d, 0x64, 0xea, 0x06,
+  0x70, 0x22, 0x3a, 0x67, 0xe2, 0xc4, 0x18, 0xf3, 0xe5, 0xa0, 0x67, 0x2c,
+  0xd5, 0xc7, 0x03, 0xd9, 0x6d, 0x5e, 0xdf, 0x51, 0xc1, 0x03, 0xc9, 0xa3,
+  0xee, 0x0f, 0x36, 0x43, 0xcd, 0x81, 0x81, 0xd9, 0xf9, 0x41, 0xac, 0x4e,
+  0x68, 0x40, 0x10, 0x56, 0xec, 0xfe, 0xe9, 0xea, 0xbb, 0x2a, 0xec, 0x07,
+  0x59, 0x31, 0x29, 0xa7, 0x1d, 0xfb, 0x8c, 0x26, 0xc1, 0x13, 0x72, 0xd8,
+  0xf1, 0x1c, 0x3f, 0xc1, 0x2e, 0x8f, 0x3b, 0xd6, 0xc8, 0xa3, 0xc3, 0xde,
+  0xbe, 0x5f, 0xb4, 0xef, 0x63, 0xe6, 0x3d, 0xb6, 0xfd, 0xaf, 0xda, 0xf5,
+  0xff, 0x32, 0x3d, 0xc2, 0x53, 0xbf, 0x1e, 0xa1, 0x48, 0x0c, 0x26, 0xf9,
+  0xe2, 0x86, 0x7c, 0xee, 0x2f, 0x10, 0x86, 0x26, 0x17, 0x19, 0xff, 0x20,
+  0xae, 0x40, 0x8c, 0xe4, 0xca, 0xab, 0xc5, 0x4f, 0xa0, 0x6f, 0x8b, 0x78,
+  0xc9, 0x15, 0x36, 0xad, 0xc6, 0x98, 0x40, 0x1f, 0xf2, 0xc0, 0x5a, 0xa5,
+  0x40, 0x84, 0xbe, 0xcc, 0x37, 0xbd, 0xbd, 0x5d, 0x18, 0xe5, 0xa8, 0xbf,
+  0x1d, 0x1a, 0x93, 0x21, 0x9d, 0x12, 0x8e, 0xc9, 0x4c, 0x13, 0xd2, 0x2e,
+  0xf0, 0xf3, 0x4e, 0x73, 0xe8, 0xbc, 0xa4, 0x23, 0xf0, 0xad, 0x6b, 0x66,
+  0xf4, 0xdd, 0xc5, 0xe9, 0x41, 0x77, 0x9e, 0x80, 0x86, 0xad, 0x0f, 0x76,
+  0x76, 0xe0, 0x7a, 0xbb, 0x49, 0x3f, 0x7e, 0x1c, 0xd6, 0xd9, 0xce, 0xb4,
+  0x9c, 0xd4, 0x3b, 0x75, 0x3d, 0xd3, 0xd9, 0x68, 0xe3, 0xc5, 0x7f, 0x07,
+  0x9f, 0x45, 0x39, 0x5f, 0x54, 0x30, 0xa2, 0x07, 0x75, 0x1d, 0x44, 0x6a,
+  0x47, 0x47, 0x1a, 0x07, 0x3a, 0x2e, 0x18, 0xf3, 0x85, 0x03, 0x3e, 0xc8,
+  0x69, 0x02, 0xbe, 0x49, 0xf4, 0x65, 0x4c, 0xaf, 0x8d, 0x4d, 0xda, 0x28,
+  0x69, 0x3f, 0x22, 0x73, 0x52, 0xd9, 0xa9, 0x9f, 0xfb, 0x66, 0x0b, 0xdd,
+  0x1d, 0x25, 0xff, 0x21, 0xe0, 0xca, 0xbc, 0x59, 0x1b, 0x67, 0x7e, 0xde,
+  0x51, 0xf3, 0xed, 0x20, 0xe2, 0xb1, 0x18, 0x35, 0xf5, 0xd2, 0xc4, 0x3d,
+  0xe9, 0xec, 0x9e, 0x6e, 0x42, 0x93, 0xd9, 0xbd, 0xd7, 0x65, 0x65, 0x4e,
+  0xcd, 0xbc, 0x8e, 0xd9, 0xfa, 0xe2, 0x92, 0xab, 0x11, 0x00, 0x4d, 0x6a,
+  0xf2, 0x46, 0xb0, 0xe3, 0x61, 0x59, 0x78, 0xad, 0x9b, 0x41, 0x4c, 0x10,
+  0x64, 0x1f, 0x26, 0x1a, 0xd5, 0x5a, 0xe5, 0x67, 0xf4, 0xe2, 0xb9, 0x16,
+  0x9d, 0xd8, 0xb5, 0x18, 0x97, 0x85, 0xf3, 0x04, 0x42, 0x1a, 0x99, 0x2e,
+  0xf7, 0x63, 0xbd, 0xc3, 0x3a, 0x57, 0x19, 0x3d, 0x0a, 0x89, 0x5e, 0x55,
+  0xa5, 0x27, 0xc6, 0x07, 0xdf, 0x42, 0x9d, 0x32, 0xb2, 0x21, 0xbf, 0xd6,
+  0x58, 0x47, 0xf7, 0xf8, 0x5a, 0xe8, 0x7f, 0x43, 0xf8, 0x1a, 0x8d, 0x64,
+  0x54, 0xb4, 0xf5, 0x59, 0x8d, 0x52, 0xf8, 0x40, 0xcd, 0x52, 0x4c, 0xa3,
+  0x18, 0x82, 0xba, 0x08, 0x8e, 0x03, 0x41, 0xeb, 0xfd, 0x57, 0x28, 0xb6,
+  0x9d, 0xe8, 0xf9, 0x74, 0xdf, 0xf0, 0x37, 0x28, 0xd2, 0x4f, 0xb0, 0x16,
+  0x5d, 0xfd, 0x06, 0xa0, 0x10, 0x6b, 0x8b, 0xc5, 0x72, 0x23, 0xba, 0xe3,
+  0x51, 0x80, 0x98, 0x28, 0xa1, 0x39, 0x92, 0x71, 0x52, 0x80, 0xcf, 0x6a,
+  0xab, 0xd8, 0x7b, 0x29, 0x11, 0x9e, 0xc3, 0x1c, 0x0d, 0x76, 0x6d, 0x3c,
+  0xfe, 0x3d, 0xa3, 0x02, 0x15, 0x4f, 0x0b, 0x2d, 0xc0, 0x88, 0xa1, 0x26,
+  0x03, 0x2e, 0x8a, 0x72, 0xb0, 0x66, 0xa5, 0xbb, 0x5e, 0xcc, 0xee, 0x33,
+  0x02, 0x11, 0x98, 0xf9, 0xae, 0xce, 0x71, 0x4a, 0x7e, 0x72, 0x0f, 0xc8,
+  0xc3, 0x7e, 0x3b, 0x55, 0xf3, 0x67, 0x50, 0xa9, 0x38, 0x58, 0x91, 0x88,
+  0xfe, 0x98, 0x24, 0xb2, 0x7c, 0x51, 0x63, 0x48, 0xb0, 0x63, 0x0c, 0xc7,
+  0xcf, 0x91, 0xfc, 0x21, 0xa9, 0x09, 0x0c, 0x85, 0x53, 0x27, 0x4e, 0x5d,
+  0xf6, 0x65, 0xea, 0x66, 0x14, 0x8e, 0xa8, 0xa4, 0x8f, 0xdd, 0x1d, 0x65,
+  0xd3, 0x0e, 0x7c, 0x30, 0x16, 0xad, 0x8e, 0x45, 0x94, 0xd5, 0xa1, 0xe3,
+  0xd8, 0xcd, 0x66, 0x54, 0x5f, 0x0b, 0xe0, 0x79, 0xe8, 0x49, 0x95, 0xe9,
+  0x27, 0x8a, 0xb2, 0xdb, 0x2b, 0xe9, 0xc7, 0x20, 0xb4, 0x5e, 0x2c, 0x02,
+  0xcd, 0xeb, 0x80, 0x22, 0xd1, 0xec, 0x32, 0xc7, 0x6f, 0xbc, 0xcc, 0x3d,
+  0x00, 0x9b, 0xa5, 0xb4, 0xc1, 0x37, 0x7f, 0x21, 0xdb, 0xcf, 0xc9, 0x76,
+  0xe9, 0x3a, 0x6c, 0x8a, 0xc9, 0xac, 0xac, 0xd5, 0xa1, 0x48, 0xcb, 0xc4,
+  0x69, 0x20, 0xe6, 0x60, 0x7c, 0x2f, 0x3f, 0x90, 0x35, 0x90, 0x5f, 0x70,
+  0xb3, 0x57, 0x25, 0x79, 0x17, 0x43, 0x0f, 0xa0, 0x28, 0x61, 0x2e, 0x73,
+  0x85, 0xdc, 0x07, 0x56, 0xf1, 0x3e, 0x48, 0x7e, 0xfa, 0xa9, 0x9f, 0x90,
+  0xf6, 0xf7, 0x93, 0xb1, 0x29, 0x7f, 0x32, 0x9b, 0x2c, 0xf9, 0xa9, 0x12,
+  0xc1, 0xf1, 0xd3, 0xad, 0xf9, 0x64, 0x37, 0x5e, 0x44, 0x6e, 0x93, 0x7a,
+  0x06, 0x7f, 0x28, 0x2b, 0x14, 0x02, 0x39, 0xb9, 0xd7, 0x08, 0x01, 0xe7,
+  0xe8, 0xc0, 0x79, 0xc1, 0x7e, 0x3f, 0xbb, 0xa2, 0x80, 0xbe, 0x84, 0xf6,
+  0xf1, 0x72, 0x5e, 0x88, 0x1a, 0xc6, 0x1b, 0x11, 0x47, 0x1c, 0x72, 0x7f,
+  0xf3, 0x8f, 0x9b, 0x6e, 0xcf, 0xf4, 0xd5, 0x67, 0xd5, 0xa8, 0x5c, 0x8d,
+  0x1c, 0x27, 0x3d, 0xf5, 0x9a, 0xce, 0x82, 0x68, 0x1c, 0x23, 0x42, 0x8c,
+  0xe4, 0x3c, 0x23, 0x87, 0x11, 0x83, 0x92, 0x4b, 0x0b, 0xe5, 0x02, 0x36,
+  0x7b, 0x71, 0x73, 0x5f, 0x53, 0xc0, 0x2c, 0x26, 0x6d, 0xdc, 0xd5, 0x4f,
+  0xbd, 0x8b, 0x46, 0x1b, 0x47, 0xce, 0x7c, 0xc4, 0x03, 0x50, 0x2d, 0xcd,
+  0x16, 0x68, 0xc9, 0x47, 0xd3, 0x97, 0xcd, 0xc1, 0x26, 0x02, 0x47, 0x70,
+  0xee, 0x8a, 0xf8, 0xab, 0x42, 0x5c, 0x97, 0x36, 0xe3, 0xe1, 0x3e, 0x82,
+  0x4f, 0xb6, 0x0c, 0x6c, 0x8e, 0x45, 0x29, 0xd8, 0xc4, 0x65, 0x5b, 0x51,
+  0xba, 0x44, 0xd8, 0xfd, 0x7e, 0xc4, 0x94, 0x12, 0x1c, 0xb3, 0x7d, 0xd7,
+  0x28, 0x89, 0xce, 0xdb, 0x39, 0x18, 0x20, 0x09, 0x75, 0xc1, 0x89, 0xa3,
+  0xbc, 0x39, 0xe8, 0x62, 0x45, 0xe2, 0x61, 0x4d, 0x1e, 0xb8, 0x40, 0xae,
+  0x2a, 0x0a, 0xa3, 0xb1, 0x39, 0x93, 0x74, 0x96, 0x29, 0x69, 0xf1, 0xae,
+  0x90, 0xa4, 0xb3, 0x51, 0x09, 0x93, 0x63, 0x82, 0xc8, 0x11, 0xa2, 0x94,
+  0x02, 0x71, 0x0e, 0x75, 0x5d, 0xba, 0xec, 0x02, 0x85, 0x87, 0xfa, 0xf4,
+  0x32, 0xe9, 0xad, 0x56, 0x7b, 0x7a, 0xdd, 0x37, 0xbe, 0xb7, 0xa1, 0x26,
+  0xb8, 0xd6, 0xc4, 0x6d, 0x69, 0xfa, 0xb0, 0x25, 0xd8, 0x85, 0xc1, 0xdf,
+  0x19, 0x98, 0xc4, 0xf0, 0x62, 0xbd, 0x47, 0xb7, 0x13, 0xc6, 0x66, 0xd5,
+  0x41, 0x70, 0xb2, 0xf2, 0x42, 0xdb, 0xde, 0x04, 0xbb, 0xe0, 0x70, 0x0e,
+  0x97, 0x0e, 0xee, 0x28, 0x56, 0x18, 0xbd, 0xa7, 0xbb, 0xf2, 0xc7, 0xbe,
+  0x4d, 0xf8, 0x47, 0xfa, 0x9e, 0xb8, 0x5a, 0xf4, 0x8a, 0xd0, 0xf3, 0x6d,
+  0xf4, 0x79, 0x24, 0x72, 0x2a, 0xf2, 0x12, 0xfa, 0x4f, 0x30, 0x3b, 0x7b,
+  0xdb, 0xe2, 0x51, 0x40, 0x2e, 0x26, 0x10, 0x71, 0xe2, 0x36, 0xe9, 0xdd,
+  0x94, 0x1c, 0xbd, 0xed, 0x1d, 0x10, 0x86, 0x9c, 0x01, 0x69, 0x32, 0x42,
+  0x1b, 0xc4, 0xec, 0x1e, 0x2c, 0x84, 0xc7, 0xbf, 0x39, 0x7b, 0x73, 0xdc,
+  0x06, 0x3f, 0xe1, 0x27, 0x31, 0xb7, 0x82, 0x91, 0x56, 0xaf, 0x8d, 0x88,
+  0xe1, 0x1d, 0x94, 0x06, 0xaa, 0x1b, 0xb6, 0x97, 0xe9, 0xd7, 0x75, 0xd6,
+  0x2c, 0xee, 0x96, 0xf9, 0x74, 0x6b, 0x9b, 0xf6, 0x07, 0x21, 0x1f, 0x07,
+  0x00, 0xdc, 0xb2, 0x85, 0x55, 0x27, 0x5b, 0xac, 0x8c, 0x57, 0x59, 0xb3,
+  0xac, 0x0a, 0xf6, 0x04, 0x25, 0xd4, 0xfd, 0x30, 0xa4, 0x93, 0xc8, 0xbd,
+  0xe6, 0xdb, 0x40, 0x92, 0x55, 0xcd, 0x81, 0x63, 0x6e, 0x72, 0x9b, 0xa4,
+  0x80, 0x91, 0xa3, 0x88, 0x9f, 0x63, 0xed, 0x69, 0x2c, 0xc1, 0x3d, 0x85,
+  0xb9, 0xd0, 0xf4, 0xc4, 0xc3, 0xf3, 0xf3, 0x57, 0x87, 0x97, 0x87, 0x76,
+  0x6c, 0xb8, 0x88, 0x21, 0x59, 0xa0, 0x0e, 0x1b, 0x91, 0x44, 0xda, 0x11,
+  0x3d, 0xb9, 0xf9, 0xa7, 0x77, 0xa3, 0xe3, 0x8b, 0xee, 0xc2, 0x9e, 0x5f,
+  0x9c, 0x51, 0xc6, 0xfa, 0x9f, 0x7e, 0x3a, 0xa4, 0x48, 0x91, 0xf8, 0xb9,
+  0x5f, 0xa5, 0x4d, 0xba, 0x19, 0x9c, 0xea, 0x7d, 0xb3, 0xd7, 0xce, 0x80,
+  0xde, 0xd1, 0x0e, 0x5e, 0xc9, 0x6d, 0x06, 0xa3, 0x3f, 0x79, 0x4f, 0x6b,
+  0x5a, 0x4d, 0x14, 0xfb, 0x84, 0x8f, 0xea, 0x72, 0xf6, 0x43, 0x8f, 0x86,
+  0x37, 0x90, 0xd2, 0x49, 0x32, 0x8d, 0xde, 0xeb, 0x5c, 0xcd, 0x92, 0xec,
+  0xa3, 0xb1, 0xac, 0x1b, 0xdd, 0xf4, 0xd8, 0x5f, 0x94, 0x53, 0xd4, 0x9d,
+  0x17, 0xb7, 0x3e, 0xba, 0x40, 0x8c, 0x96, 0xe2, 0xdc, 0x6e, 0xc8, 0x01,
+  0x24, 0xb5, 0x99, 0xdd, 0x06, 0x7c, 0xda, 0x50, 0x7b, 0x2b, 0xc6, 0x69,
+  0xe0, 0x5c, 0x62, 0x87, 0x21, 0x52, 0xdc, 0xb8, 0x4b, 0xc1, 0x84, 0xfc,
+  0xd1, 0x9c, 0xc7, 0x41, 0x72, 0x2c, 0xd8, 0x6b, 0x0c, 0xdb, 0xfc, 0x20,
+  0x78, 0xa8, 0xb1, 0xb6, 0x82, 0x08, 0xfb, 0xb8, 0xac, 0xf0, 0xd2, 0x3e,
+  0x7b, 0x5d, 0xe5, 0x99, 0x13, 0x2d, 0xcc, 0x43, 0xd4, 0x69, 0x9a, 0x72,
+  0x98, 0x4a, 0xbd, 0x48, 0x9c, 0x79, 0x90, 0x5e, 0xd3, 0xee, 0x32, 0x8f,
+  0x1a, 0x25, 0xda, 0x58, 0x48, 0xf4, 0xaf, 0x9d, 0xbd, 0xe1, 0x6e, 0x2f,
+  0xec, 0x3c, 0x1d, 0x16, 0x64, 0xd1, 0x5a, 0x7f, 0x31, 0xc9, 0xc2, 0xa6,
+  0x2c, 0x1f, 0xec, 0x1f, 0x8b, 0x30, 0xa3, 0x87, 0x2e, 0x4c, 0xfb, 0xd1,
+  0xae, 0x0c, 0xce, 0x02, 0x68, 0x17, 0x81, 0xa5, 0x2a, 0x15, 0x8a, 0x46,
+  0x26, 0x16, 0xe5, 0x1d, 0x8d, 0xc4, 0x6c, 0xb5, 0xd9, 0xac, 0x95, 0xee,
+  0xdc, 0x8b, 0x4f, 0x73, 0x01, 0x66, 0x81, 0xac, 0x3b, 0xdb, 0xb1, 0x60,
+  0x8c, 0x5c, 0x9e, 0xbe, 0x1e, 0x67, 0x51, 0x46, 0x30, 0x18, 0xed, 0x2e,
+  0x70, 0x3f, 0x17, 0x19, 0x19, 0xc8, 0xbd, 0x99, 0x1f, 0x6c, 0x1c, 0x68,
+  0xc4, 0x73, 0x40, 0xcd, 0x90, 0xf6, 0xf9, 0x82, 0x33, 0xa7, 0x02, 0xc3,
+  0xfd, 0x4d, 0xfa, 0x31, 0x9f, 0x2f, 0xe7, 0x09, 0xbe, 0xc7, 0x0a, 0xad,
+  0x3c, 0xa9, 0x17, 0x23, 0xf9, 0x4f, 0x38, 0xe8, 0x4a, 0x8b, 0xba, 0x59,
+  0x7b, 0xf6, 0x7b, 0xe4, 0x92, 0x31, 0x97, 0xb2, 0x9a, 0x9d, 0x02, 0x5f,
+  0x9f, 0xe7, 0x4d, 0xdd, 0xb1, 0xfb, 0x8d, 0xaa, 0x90, 0x52, 0x0c, 0x4d,
+  0x53, 0xa4, 0xf8, 0x12, 0x8f, 0x88, 0x73, 0x4e, 0xdd, 0x53, 0x1d, 0xce,
+  0x43, 0x09, 0x65, 0x55, 0x5e, 0x4e, 0xed, 0xb1, 0x21, 0x2d, 0x31, 0x2f,
+  0x96, 0x66, 0xa2, 0xa9, 0x39, 0xba, 0x55, 0xe5, 0x37, 0x41, 0x18, 0x0f,
+  0x80, 0xc6, 0x11, 0x70, 0xaa, 0x8a, 0xfb, 0xf9, 0x64, 0xf8, 0x64, 0x7f,
+  0xb8, 0xdb, 0x6f, 0x59, 0xef, 0x92, 0xe1, 0x68, 0x4e, 0xd7, 0x24, 0x9f,
+  0xdb, 0xec, 0x87, 0xe1, 0xbf, 0xcc, 0x4b, 0x43, 0x79, 0x1f, 0x83, 0x79,
+  0xfa, 0x11, 0xcb, 0x17, 0x5d, 0xd6, 0x32, 0x79, 0xf1, 0xcd, 0xd9, 0xe8,
+  0x72, 0xef, 0xe0, 0xfc, 0xec, 0xc2, 0xfc, 0x97, 0xfe, 0xbe, 0x8f, 0xbf,
+  0xef, 0x07, 0xd6, 0xe3, 0x6b, 0x81, 0x2d, 0x29, 0x4e, 0x1a, 0xaa, 0x0e,
+  0x6e, 0x01, 0xb1, 0x62, 0xbc, 0x86, 0x08, 0xdb, 0x4e, 0x52, 0x50, 0x17,
+  0x2b, 0xe2, 0x33, 0xf3, 0x3e, 0xa5, 0xc8, 0xd1, 0x61, 0x7b, 0x3f, 0x03,
+  0x23, 0x93, 0x37, 0xaa, 0x4a, 0x49, 0x66, 0x96, 0xe6, 0x7c, 0x75, 0x3d,
+  0x7a, 0x9c, 0x55, 0x23, 0xd0, 0x68, 0x25, 0x34, 0x01, 0xdc, 0xa1, 0xfd,
+  0xab, 0xc9, 0xcc, 0x68, 0xfa, 0x19, 0x85, 0x47, 0xa7, 0x19, 0x67, 0xd3,
+  0xd3, 0x4f, 0x62, 0x06, 0x88, 0x20, 0xaf, 0x81, 0x16, 0x1d, 0x76, 0x7b,
+  0x86, 0x5d, 0x29, 0xb8, 0x38, 0x4a, 0x63, 0x34, 0xbd, 0xcc, 0xeb, 0x1b,
+  0x45, 0xff, 0x77, 0x9b, 0x03, 0xd8, 0xc8, 0x77, 0x58, 0x9d, 0x34, 0x9c,
+  0xf9, 0xf5, 0xf6, 0xec, 0x32, 0x49, 0xaf, 0xae, 0x34, 0x4d, 0x0d, 0x50,
+  0x50, 0xd2, 0x58, 0x77, 0x60, 0xe5, 0xab, 0xa3, 0xb9, 0x0e, 0x25, 0x1f,
+  0xeb, 0x23, 0x97, 0xa7, 0xa3, 0x1d, 0x72, 0x57, 0x31, 0xae, 0x63, 0xf4,
+  0xf6, 0xa4, 0xdf, 0x72, 0x64, 0xfa, 0xd1, 0xdc, 0x6d, 0xba, 0x29, 0xe5,
+  0x1a, 0xed, 0xce, 0x9d, 0x77, 0x17, 0xda, 0xf4, 0xe7, 0x61, 0xd2, 0xc3,
+  0x82, 0xf6, 0x58, 0xc7, 0xec, 0x61, 0x5d, 0x7b, 0x8c, 0x65, 0x04, 0x0c,
+  0x04, 0xfd, 0xa5, 0x2c, 0xdd, 0x00, 0x85, 0x01, 0x2f, 0x6f, 0x1f, 0x59,
+  0xc1, 0xa4, 0x74, 0xf4, 0xc8, 0x22, 0xa1, 0x81, 0x61, 0x50, 0x3d, 0x69,
+  0x78, 0x9f, 0x1b, 0x46, 0xbb, 0xe6, 0xef, 0xd4, 0x2c, 0x36, 0xed, 0x38,
+  0x8b, 0x61, 0x2a, 0xf1, 0x1d, 0xd7, 0xb4, 0x6d, 0xdb, 0x74, 0x0c, 0xce,
+  0x57, 0x7e, 0x4a, 0x37, 0x87, 0x91, 0x2e, 0x14, 0x93, 0xcb, 0xaf, 0x29,
+  0x02, 0xd6, 0x45, 0xed, 0xbb, 0x8e, 0x04, 0x6e, 0x28, 0xd2, 0xc7, 0xea,
+  0xa6, 0xe7, 0xf9, 0x0c, 0x9a, 0x00, 0x15, 0x09, 0x74, 0x56, 0xa5, 0xf6,
+  0x8c, 0x76, 0xa8, 0x2e, 0xc3, 0x1b, 0xdf, 0x3a, 0xf0, 0xe7, 0x29, 0xdd,
+  0x3a, 0xd6, 0xcf, 0xad, 0x90, 0x6b, 0x3d, 0x48, 0x48, 0xca, 0xa6, 0x0c,
+  0x42, 0xa0, 0xf3, 0x69, 0x6a, 0xd9, 0x39, 0xde, 0x6d, 0x8e, 0x29, 0x3d,
+  0x8c, 0x44, 0x48, 0x80, 0xb4, 0xa5, 0x0e, 0x24, 0xbd, 0xbd, 0xfd, 0x4f,
+  0x86, 0xbb, 0xe6, 0x7f, 0x69, 0x69, 0x44, 0x5d, 0x64, 0x06, 0x03, 0x97,
+  0xa9, 0x2e, 0xb8, 0xdc, 0xae, 0x93, 0x59, 0xef, 0xa0, 0xb2, 0xba, 0xee,
+  0x0d, 0x1f, 0x7d, 0xaf, 0xd0, 0x5a, 0xda, 0x3b, 0x25, 0x9d, 0xca, 0x4f,
+  0xf4, 0x98, 0x57, 0xcb, 0x59, 0x04, 0xac, 0xe2, 0xb9, 0x8d, 0x49, 0x41,
+  0x9b, 0xdd, 0x8a, 0xd3, 0xf8, 0x1b, 0x12, 0x4f, 0x9c, 0x45, 0x31, 0x6c,
+  0x85, 0xfa, 0x3f, 0x6b, 0xf9, 0x00, 0x8f, 0xc4, 0x70, 0x83, 0x6c, 0x1e,
+  0x98, 0x03, 0xf1, 0xa2, 0xbc, 0xba, 0xaa, 0xb3, 0xa6, 0x7b, 0x07, 0x1d,
+  0xc9, 0x23, 0x3b, 0x17, 0x20, 0xc1, 0xf1, 0x60, 0xce, 0xed, 0x24, 0xf1,
+  0x24, 0x6d, 0xda, 0x82, 0x8b, 0x9b, 0x1b, 0x46, 0xc0, 0x9d, 0xed, 0x27,
+  0x3c, 0x70, 0x36, 0xe7, 0x6a, 0x05, 0x29, 0xc8, 0x38, 0xaf, 0x22, 0x9c,
+  0xbb, 0xa7, 0xe2, 0x43, 0xbe, 0x58, 0x90, 0x8d, 0x03, 0xc6, 0x0d, 0xda,
+  0xbb, 0x36, 0x4e, 0x30, 0xce, 0xcc, 0x46, 0xc5, 0x76, 0x56, 0x04, 0x8c,
+  0x51, 0x92, 0x27, 0x16, 0x3d, 0x3c, 0xce, 0xcc, 0xb1, 0xcd, 0x42, 0xad,
+  0x9d, 0x5c, 0x1b, 0x5e, 0x9e, 0xb5, 0xa4, 0x87, 0x4e, 0x29, 0xa7, 0xba,
+  0x48, 0x59, 0xcc, 0xd0, 0xdd, 0xe2, 0x32, 0x10, 0x25, 0xf5, 0x22, 0x06,
+  0xc4, 0x72, 0xc0, 0x78, 0xeb, 0x72, 0x1b, 0x9d, 0xfc, 0xcf, 0x63, 0x97,
+  0x15, 0x6f, 0xd3, 0xce, 0x19, 0x66, 0x1c, 0x03, 0x6d, 0x27, 0xbd, 0xc1,
+  0x51, 0x32, 0xe8, 0xa1, 0x23, 0x2e, 0x8a, 0x5a, 0x76, 0x40, 0xb0, 0xb0,
+  0x7d, 0x48, 0x95, 0x48, 0xa0, 0x0f, 0xed, 0x70, 0x1e, 0x5a, 0x19, 0xe8,
+  0x4f, 0x58, 0x42, 0x9e, 0x6c, 0x1d, 0x25, 0x4e, 0x49, 0x23, 0x59, 0x0b,
+  0x3e, 0xda, 0x97, 0x15, 0xc6, 0x9d, 0xbc, 0x20, 0xb5, 0x11, 0x3a, 0x4c,
+  0x00, 0x85, 0xd5, 0x2c, 0x24, 0x4e, 0xbf, 0x5d, 0x36, 0xff, 0xc2, 0x58,
+  0x49, 0x45, 0xfb, 0x17, 0xbc, 0x2a, 0xde, 0xa6, 0x9e, 0xf0, 0xa6, 0x26,
+  0x3e, 0xa7, 0xc1, 0xdf, 0x8c, 0x9d, 0xfd, 0x42, 0x7d, 0x15, 0x2b, 0xf2,
+  0xd4, 0xac, 0x5b, 0xa3, 0x94, 0xa0, 0x08, 0xf6, 0x86, 0xcd, 0x97, 0xd6,
+  0xb9, 0x66, 0x8f, 0x0a, 0xa0, 0x3e, 0x42, 0x16, 0xd5, 0x95, 0xf5, 0x57,
+  0xb8, 0xda, 0x52, 0x97, 0x97, 0x3b, 0xf5, 0xd2, 0xfb, 0x87, 0x04, 0x0c,
+  0x9e, 0x71, 0x2b, 0x35, 0x9a, 0x91, 0x56, 0x84, 0xdd, 0x24, 0xb8, 0x76,
+  0xf3, 0x62, 0x30, 0xcf, 0xe6, 0x04, 0xe0, 0xe3, 0x07, 0x8d, 0x40, 0x2c,
+  0x49, 0x0b, 0xd7, 0xdd, 0xc8, 0xeb, 0xc3, 0x86, 0x78, 0x23, 0x81, 0xef,
+  0x29, 0x27, 0x88, 0xd0, 0x37, 0x43, 0x44, 0x53, 0x59, 0x08, 0x7e, 0x86,
+  0x4c, 0x2c, 0xfb, 0x75, 0x38, 0xca, 0x3e, 0x18, 0x15, 0xba, 0xe8, 0xd3,
+  0xcf, 0x91, 0x0a, 0xa4, 0xb3, 0x4f, 0x9d, 0x6d, 0xb2, 0x22, 0x86, 0x9f,
+  0x6f, 0x79, 0x9f, 0xe5, 0x39, 0xcf, 0x97, 0xf2, 0x36, 0x6b, 0x24, 0x2a,
+  0xca, 0x7d, 0x97, 0xf0, 0x9d, 0xc0, 0xea, 0x4d, 0x27, 0x3a, 0xcd, 0x81,
+  0xbf, 0x24, 0x6b, 0x9c, 0x4f, 0x48, 0x7d, 0x4b, 0xa9, 0x92, 0x36, 0x90,
+  0xd7, 0xb3, 0x6f, 0xce, 0x41, 0x4f, 0x5d, 0xb0, 0xdc, 0xfd, 0xb8, 0x44,
+  0xd0, 0x0e, 0x91, 0xab, 0xa7, 0x99, 0xc6, 0xf6, 0xa4, 0xe4, 0x5f, 0x06,
+  0x29, 0x8f, 0x02, 0x2e, 0x37, 0xba, 0x04, 0x62, 0x94, 0xe2, 0x3a, 0xc6,
+  0x18, 0x04, 0x65, 0xc2, 0xaa, 0x43, 0x37, 0x13, 0xca, 0xe5, 0xf4, 0x50,
+  0x7c, 0xb8, 0x9a, 0xaa, 0x73, 0x44, 0x3b, 0x6a, 0xa4, 0xb0, 0x98, 0x46,
+  0x77, 0x29, 0xb6, 0x9a, 0xfd, 0x04, 0xc4, 0x4d, 0x78, 0xa8, 0x14, 0xdc,
+  0x33, 0x18, 0xbb, 0xed, 0xec, 0xf2, 0xb9, 0xa3, 0xae, 0x59, 0x79, 0x88,
+  0xf6, 0xbc, 0xb9, 0x58, 0x36, 0x21, 0x59, 0x24, 0xaf, 0x07, 0x29, 0xd2,
+  0x76, 0x52, 0x78, 0x0a, 0xef, 0x6e, 0xca, 0x19, 0x5b, 0xc6, 0x41, 0x84,
+  0x45, 0x13, 0xae, 0x8c, 0x76, 0x45, 0xed, 0x10, 0x5a, 0x0d, 0x8e, 0xe5,
+  0x5b, 0x00, 0xe1, 0x5a, 0x61, 0x12, 0xa3, 0xe3, 0x65, 0x29, 0xe1, 0xbc,
+  0x15, 0x0a, 0x7a, 0x1b, 0xa6, 0xa7, 0x98, 0x73, 0x3e, 0x2e, 0x6b, 0xd9,
+  0x2f, 0x94, 0xd4, 0x64, 0xb6, 0x58, 0x5a, 0x41, 0x2c, 0x0b, 0x65, 0x83,
+  0x12, 0x4c, 0x59, 0xb5, 0x4c, 0xe4, 0x13, 0xe9, 0x82, 0x5d, 0x14, 0x6f,
+  0x4e, 0xa9, 0x80, 0x66, 0x9b, 0x18, 0x1d, 0x80, 0xdc, 0xb4, 0xd8, 0x3b,
+  0x68, 0x94, 0x09, 0x19, 0x6e, 0x40, 0x97, 0x26, 0xf9, 0x82, 0xe6, 0x14,
+  0xde, 0xa4, 0x64, 0xb5, 0x37, 0xcb, 0x74, 0xd5, 0xd4, 0xb5, 0x91, 0x3b,
+  0x0f, 0x8a, 0x27, 0xa7, 0xc1, 0x44, 0x42, 0x09, 0xd8, 0xb6, 0x2b, 0xa2,
+  0x86, 0xfe, 0x42, 0xbe, 0xa0, 0x73, 0xb6, 0x42, 0x1e, 0x9d, 0x83, 0x59,
+  0xe6, 0xa6, 0x4d, 0x4d, 0x80, 0x2c, 0x28, 0xb9, 0x46, 0x34, 0xd1, 0x80,
+  0x9b, 0xd2, 0x5b, 0xfe, 0xa4, 0x09, 0x81, 0x75, 0x1c, 0x76, 0x33, 0xdd,
+  0x98, 0xdd, 0xbb, 0x16, 0xbd, 0x0c, 0x25, 0xc5, 0x2b, 0x7a, 0xbc, 0x2d,
+  0xf6, 0x13, 0x69, 0x57, 0xab, 0x19, 0x19, 0xe5, 0x9b, 0xbf, 0x79, 0xd0,
+  0x4b, 0x94, 0x52, 0x8b, 0xef, 0x72, 0xb4, 0xab, 0xf0, 0x78, 0xe8, 0x59,
+  0xb0, 0x53, 0x45, 0x75, 0xe4, 0x63, 0xdf, 0x6d, 0x8e, 0x78, 0x1a, 0xf7,
+  0x5e, 0x7e, 0x77, 0x78, 0xfa, 0xee, 0x78, 0xef, 0xf3, 0x84, 0xfe, 0xb5,
+  0xcf, 0xff, 0xda, 0xef, 0x45, 0x57, 0xc9, 0x08, 0xa7, 0xcd, 0x97, 0x9b,
+  0x49, 0x7d, 0x3f, 0x1f, 0x97, 0x33, 0xbb, 0x4a, 0x32, 0x17, 0x1a, 0x2a,
+  0xeb, 0xcb, 0xed, 0xad, 0x09, 0x73, 0xe2, 0x21, 0xef, 0x4a, 0xea, 0x5a,
+  0x80, 0x34, 0x2a, 0x65, 0x10, 0xa7, 0xf3, 0x33, 0xb7, 0x1a, 0x24, 0xb7,
+  0xa9, 0xf0, 0x42, 0xbc, 0xee, 0x72, 0x25, 0xb8, 0x89, 0xf9, 0xa7, 0xf4,
+  0x40, 0xd7, 0x49, 0x54, 0x6a, 0xf0, 0xd5, 0xe2, 0x18, 0xff, 0x3c, 0x59,
+  0x11, 0x08, 0x7e, 0x23, 0x97, 0x00, 0xe6, 0x50, 0x4e, 0x42, 0x7e, 0x57,
+  0xb0, 0x42, 0x44, 0x92, 0x73, 0xaf, 0xbc, 0x25, 0x9b, 0x04, 0x92, 0xb6,
+  0x38, 0x6e, 0xa0, 0x47, 0x03, 0x37, 0x5f, 0x39, 0x1f, 0x8b, 0xd6, 0xe2,
+  0xe5, 0xcb, 0x99, 0xfd, 0x78, 0x4a, 0xfb, 0x71, 0x56, 0x8a, 0x75, 0xa2,
+  0xf9, 0x39, 0x55, 0x8b, 0xa5, 0xc7, 0xe3, 0x05, 0xb4, 0x74, 0x46, 0xc2,
+  0x07, 0xd4, 0x0a, 0xfa, 0xb1, 0x9b, 0x39, 0x9a, 0xc5, 0xa3, 0xc9, 0x50,
+  0x04, 0xde, 0x2b, 0xaf, 0x9c, 0x84, 0xb7, 0xe1, 0x51, 0xff, 0x1a, 0x94,
+  0x2d, 0x44, 0x50, 0xa1, 0x59, 0x1a, 0x0c, 0x85, 0x53, 0x01, 0x25, 0x39,
+  0x98, 0x02, 0xed, 0x76, 0x47, 0x9a, 0x15, 0xbb, 0x9f, 0x65, 0xdb, 0x1a,
+  0x3b, 0xd4, 0xeb, 0x67, 0xe7, 0x4d, 0xf9, 0x0f, 0x33, 0xe3, 0xa9, 0x7c,
+  0x24, 0x76, 0x87, 0xc9, 0x9d, 0xb4, 0xb2, 0xe7, 0xee, 0xb8, 0x73, 0xba,
+  0x9c, 0x7f, 0x8a, 0x5b, 0xc6, 0x6a, 0x8a, 0xc9, 0x37, 0x6a, 0x12, 0x70,
+  0x81, 0xc1, 0x22, 0xc8, 0x6d, 0x6b, 0x33, 0x2e, 0xbd, 0x2b, 0x4a, 0xa7,
+  0xc4, 0xec, 0xb1, 0x92, 0xb7, 0x9e, 0x5b, 0x7a, 0xb9, 0x06, 0xba, 0x22,
+  0xb5, 0xab, 0xe3, 0xac, 0xb8, 0x18, 0x8e, 0x3f, 0x66, 0xd5, 0x84, 0x12,
+  0x6f, 0x27, 0x46, 0x53, 0x84, 0xee, 0xc5, 0xc9, 0xc2, 0x4c, 0xdc, 0xd3,
+  0xda, 0x37, 0x2a, 0xfe, 0x60, 0x92, 0xea, 0xfa, 0xaf, 0x5c, 0x7b, 0x60,
+  0x0f, 0x26, 0x66, 0x0f, 0x0f, 0x2d, 0x47, 0x8a, 0x5e, 0x58, 0xed, 0x73,
+  0xad, 0x89, 0x0c, 0xf0, 0xf0, 0x07, 0x50, 0x21, 0xcc, 0xb0, 0xbe, 0xe8,
+  0xad, 0xa6, 0x6c, 0x17, 0xf4, 0x85, 0x19, 0x2f, 0x1c, 0xba, 0x84, 0x12,
+  0x26, 0x41, 0x1b, 0xb0, 0x1a, 0x17, 0x65, 0x57, 0x07, 0xd9, 0xcc, 0x08,
+  0x60, 0x14, 0xf7, 0x4a, 0x36, 0xb0, 0x85, 0x5b, 0x8c, 0x95, 0x35, 0x25,
+  0xa5, 0x41, 0xb8, 0x30, 0x4c, 0xca, 0x9a, 0x95, 0x77, 0x14, 0x17, 0x69,
+  0x53, 0x44, 0xcd, 0xcb, 0x29, 0xef, 0x87, 0xf1, 0xbd, 0xe5, 0x77, 0x1d,
+  0x90, 0xee, 0xc2, 0x9f, 0x1d, 0x6a, 0x36, 0x6e, 0x74, 0x07, 0x58, 0x71,
+  0xd0, 0xc1, 0xbb, 0xa7, 0x0e, 0xbb, 0xd0, 0xb0, 0x7f, 0x97, 0xef, 0x7b,
+  0xc7, 0xcf, 0x10, 0xbb, 0x68, 0x30, 0xe2, 0x71, 0xd9, 0xdc, 0xd8, 0x2b,
+  0x07, 0x03, 0x26, 0xf7, 0x98, 0xb1, 0x54, 0x1b, 0x28, 0xe5, 0x6a, 0x99,
+  0x35, 0x82, 0x6b, 0x13, 0xff, 0x4d, 0x10, 0x02, 0xfc, 0xc0, 0xec, 0x20,
+  0x65, 0xa3, 0xcc, 0x6f, 0xc2, 0x8a, 0xd4, 0x20, 0xcb, 0x9c, 0xfc, 0x47,
+  0x30, 0x4a, 0x41, 0x42, 0x63, 0xbe, 0x4b, 0x60, 0xa1, 0xba, 0x26, 0xc2,
+  0x11, 0x1a, 0x7a, 0x1a, 0x24, 0x1b, 0x63, 0xaa, 0x09, 0xf0, 0xe2, 0x16,
+  0x75, 0x8b, 0xe9, 0x00, 0x9c, 0x21, 0xc7, 0x59, 0xc2, 0xe4, 0x66, 0x5f,
+  0x8e, 0xf5, 0x9d, 0x7a, 0x9b, 0x8c, 0xed, 0x08, 0x08, 0xac, 0xa5, 0x55,
+  0xae, 0x38, 0xb4, 0xff, 0xb4, 0xa1, 0x11, 0x18, 0x5e, 0x55, 0xcd, 0x2c,
+  0x6b, 0xe0, 0xa9, 0xb3, 0x48, 0x4c, 0x4c, 0x79, 0x28, 0xbc, 0x52, 0x17,
+  0x16, 0x83, 0x9a, 0xdf, 0x1d, 0xc5, 0x62, 0x0a, 0x55, 0x4c, 0xdf, 0x81,
+  0xf2, 0xe2, 0xb1, 0x25, 0xd5, 0xa5, 0x9c, 0x48, 0x34, 0x4f, 0x82, 0xc6,
+  0x49, 0x9a, 0x18, 0x6d, 0x40, 0x57, 0x06, 0xf8, 0x71, 0x8f, 0x96, 0x66,
+  0x2b, 0x9a, 0xae, 0x2f, 0x1f, 0xcc, 0x8b, 0xb8, 0x19, 0x07, 0x66, 0xff,
+  0xd7, 0xb1, 0xf8, 0xa1, 0x5e, 0xae, 0x93, 0xb2, 0xf8, 0xdb, 0xb2, 0x98,
+  0x34, 0x16, 0x13, 0x07, 0x9d, 0xb4, 0xec, 0x7b, 0xa4, 0x4d, 0x12, 0x30,
+  0xb5, 0x40, 0x9a, 0xee, 0xc6, 0xc7, 0x87, 0xc4, 0x7d, 0x47, 0x99, 0x47,
+  0x04, 0x17, 0xa6, 0x6b, 0x67, 0xe6, 0xe5, 0x28, 0xdd, 0xe4, 0x66, 0x85,
+  0xaa, 0xc9, 0x0d, 0xb2, 0x2a, 0xe1, 0xde, 0xc9, 0xd4, 0x67, 0xb9, 0x02,
+  0xfe, 0xc3, 0xcd, 0x8a, 0xa2, 0x94, 0x93, 0x48, 0xa2, 0xbc, 0xe9, 0xb2,
+  0x50, 0x41, 0xbd, 0xaa, 0x9f, 0x21, 0xba, 0xea, 0x86, 0xe6, 0x3c, 0x9b,
+  0xd5, 0x99, 0x0d, 0xe1, 0xdb, 0x77, 0x9c, 0x29, 0x02, 0xb3, 0xb8, 0x28,
+  0x39, 0x06, 0x47, 0xde, 0xa0, 0x3c, 0x7a, 0xca, 0xd1, 0x13, 0xa3, 0x82,
+  0x48, 0x67, 0xc8, 0xd0, 0xa3, 0x7d, 0x72, 0xaf, 0x59, 0xf7, 0xd2, 0x82,
+  0xee, 0x3a, 0xcd, 0xba, 0x0f, 0x6e, 0x9f, 0xd2, 0xce, 0x9b, 0x64, 0xb2,
+  0xeb, 0x54, 0xe5, 0x4a, 0xca, 0xc9, 0x5b, 0x85, 0x9c, 0x0b, 0xa6, 0x37,
+  0xcc, 0xdf, 0x4c, 0x41, 0xa9, 0xc1, 0xe0, 0xaa, 0x59, 0x0c, 0xa2, 0x4b,
+  0x80, 0xb5, 0x6e, 0x6f, 0x81, 0xd9, 0x95, 0xb0, 0x16, 0xbc, 0x51, 0xc2,
+  0x96, 0x5b, 0x02, 0x8d, 0x27, 0xa7, 0xaf, 0xd9, 0x07, 0x7d, 0x74, 0x41,
+  0x7f, 0xcb, 0x2d, 0x67, 0xc3, 0x10, 0x87, 0x82, 0x08, 0x99, 0x39, 0x82,
+  0xfa, 0xe6, 0xbb, 0x6e, 0xc2, 0xcf, 0xd6, 0xd9, 0x68, 0xe7, 0xc9, 0x67,
+  0xbb, 0x61, 0xea, 0xf9, 0x16, 0x7d, 0xc3, 0x91, 0xd9, 0x7c, 0x32, 0x7c,
+  0xba, 0x3b, 0xdc, 0xdd, 0xee, 0xf4, 0x86, 0xa6, 0x7b, 0x4d, 0x32, 0xb9,
+  0x52, 0x70, 0xda, 0x8b, 0x83, 0xa6, 0xc0, 0xe5, 0x6b, 0x2b, 0x68, 0xd3,
+  0x4f, 0x5b, 0xba, 0xc8, 0x6e, 0xcd, 0x56, 0x8b, 0x19, 0xc3, 0xc9, 0x69,
+  0x0e, 0x2c, 0xbb, 0x79, 0x8f, 0x6e, 0x33, 0xbd, 0x5f, 0x28, 0x2f, 0xb0,
+  0x9d, 0xab, 0x87, 0x47, 0xe8, 0xc2, 0x64, 0xc0, 0x70, 0x24, 0x08, 0x52,
+  0x9b, 0x4e, 0x55, 0x00, 0xc7, 0x21, 0xd8, 0xfe, 0xbb, 0x3b, 0x40, 0x3c,
+  0x87, 0xde, 0xde, 0x67, 0xc3, 0x4f, 0xfc, 0x35, 0x25, 0x4d, 0x7c, 0x90,
+  0xd6, 0x93, 0x3c, 0x5f, 0x6b, 0x63, 0x28, 0xea, 0xf0, 0x6f, 0x4b, 0xd0,
+  0xb2, 0x98, 0x6d, 0x9a, 0xa7, 0x1c, 0x41, 0x75, 0x6c, 0x56, 0x41, 0xb3,
+  0xa4, 0x46, 0x9a, 0x2d, 0xb6, 0xae, 0x5d, 0x49, 0x61, 0x22, 0x92, 0x6d,
+  0x21, 0xe0, 0x83, 0x3b, 0x6f, 0x86, 0x73, 0xdd, 0x51, 0xa5, 0xcc, 0x59,
+  0x60, 0x02, 0x97, 0x45, 0x15, 0x26, 0x94, 0x10, 0x3e, 0x92, 0xe8, 0x3c,
+  0xcd, 0xdc, 0xd7, 0x25, 0xcd, 0x53, 0x6c, 0x52, 0xe1, 0x35, 0x00, 0x85,
+  0x99, 0x35, 0x6e, 0xec, 0xd9, 0x17, 0x80, 0xce, 0x97, 0x1e, 0xa0, 0xa6,
+  0x65, 0xa0, 0xa4, 0x11, 0x65, 0x90, 0x19, 0x58, 0x13, 0x44, 0xad, 0xd9,
+  0x7e, 0xa2, 0x81, 0x30, 0x65, 0x4c, 0x02, 0x57, 0x04, 0x23, 0x37, 0x84,
+  0x19, 0x98, 0x08, 0x19, 0xec, 0x6c, 0x45, 0xe8, 0x36, 0xfa, 0x66, 0x7c,
+  0xe0, 0x77, 0xc2, 0x0e, 0x2a, 0xb2, 0x3b, 0x92, 0xc6, 0xb5, 0xa8, 0x13,
+  0x55, 0x95, 0x93, 0x33, 0xc7, 0x06, 0xfd, 0x59, 0x25, 0x23, 0x20, 0x24,
+  0x5d, 0xd0, 0xd3, 0x48, 0x16, 0xe1, 0x04, 0xa7, 0xb3, 0xb6, 0x84, 0x59,
+  0x05, 0x18, 0x8a, 0x88, 0x71, 0xe7, 0x71, 0x56, 0xed, 0xca, 0x4d, 0x07,
+  0x06, 0x67, 0x07, 0xbc, 0x68, 0x22, 0xce, 0x1e, 0x02, 0x4f, 0xb0, 0x67,
+  0x84, 0x19, 0x4b, 0x30, 0xd7, 0x69, 0x2d, 0x6c, 0xdf, 0x63, 0xde, 0x8d,
+  0x6b, 0xb6, 0x4e, 0x95, 0xde, 0x3d, 0xbc, 0x1f, 0xbd, 0x5d, 0x23, 0x33,
+  0x3d, 0x83, 0xab, 0xc4, 0x23, 0x58, 0x83, 0x8f, 0x40, 0xf1, 0x7a, 0x91,
+  0x9e, 0x0a, 0xb1, 0x2f, 0xb3, 0xea, 0x9a, 0xc9, 0x6c, 0xc4, 0xb8, 0x61,
+  0xb9, 0xfe, 0xe5, 0x1a, 0x90, 0xbe, 0x73, 0x2a, 0xba, 0x51, 0xb4, 0x3c,
+  0xe7, 0x1d, 0x96, 0x26, 0x0c, 0xcb, 0x5c, 0x79, 0x8c, 0x72, 0x7f, 0xc4,
+  0xa1, 0x70, 0xa3, 0xeb, 0x7b, 0x10, 0x20, 0x5e, 0x00, 0x38, 0x86, 0xbc,
+  0x61, 0x0a, 0x9d, 0x57, 0x0c, 0x09, 0xc8, 0x74, 0x66, 0xb4, 0xad, 0x10,
+  0xde, 0xb5, 0x34, 0x2d, 0x8b, 0xac, 0x22, 0x29, 0x08, 0xd4, 0xf4, 0x40,
+  0xc1, 0xae, 0xb1, 0x8b, 0xc5, 0x6c, 0xfe, 0xa3, 0xaf, 0x4f, 0x80, 0xfe,
+  0x35, 0x87, 0xbe, 0x90, 0xd4, 0x56, 0xee, 0x3f, 0xd3, 0xaa, 0x5b, 0x23,
+  0xec, 0x3a, 0xb7, 0x26, 0x63, 0x9a, 0xb4, 0x28, 0xd3, 0x3a, 0x3a, 0x72,
+  0xa2, 0xca, 0xb0, 0xe0, 0x1b, 0x45, 0xa7, 0xa5, 0xc8, 0x02, 0x29, 0xa4,
+  0x1a, 0x21, 0x4c, 0x1d, 0xa4, 0x3c, 0x3a, 0x5f, 0xf8, 0xba, 0xa6, 0x60,
+  0xa7, 0xb5, 0x84, 0x00, 0xa1, 0x58, 0x04, 0x70, 0x63, 0xb7, 0x5f, 0x99,
+  0xa6, 0x3e, 0x0b, 0xa1, 0x53, 0xf2, 0xf9, 0x78, 0x1d, 0x09, 0xac, 0x49,
+  0xc7, 0x1c, 0xb7, 0x53, 0x97, 0x69, 0x38, 0x1c, 0xdd, 0x47, 0xd2, 0x02,
+  0x39, 0x65, 0x62, 0x9e, 0x3f, 0x55, 0x4b, 0x28, 0x24, 0xf0, 0x1f, 0xc0,
+  0xc1, 0xd3, 0x1d, 0x61, 0xce, 0x27, 0xdd, 0x92, 0x9a, 0x4c, 0xe2, 0xb7,
+  0xa6, 0x44, 0x3c, 0x02, 0x9c, 0x8c, 0x37, 0x47, 0xf6, 0xca, 0x4b, 0xba,
+  0xd9, 0xbf, 0x14, 0x87, 0x07, 0x01, 0xa7, 0xfd, 0x20, 0x88, 0x64, 0x12,
+  0x31, 0xc4, 0x4e, 0x58, 0x03, 0x68, 0x1a, 0xe2, 0xcd, 0x71, 0x98, 0xcc,
+  0x9b, 0x3d, 0xde, 0x71, 0xc4, 0xa3, 0x59, 0x73, 0xa9, 0x82, 0x3f, 0x74,
+  0x27, 0xef, 0xe5, 0xc3, 0xb3, 0xf7, 0x4b, 0xa7, 0x6f, 0xfd, 0xec, 0x31,
+  0x1f, 0xad, 0x62, 0x2d, 0x5f, 0x7a, 0x8e, 0x1e, 0xc0, 0x05, 0xd8, 0x56,
+  0xb0, 0x0e, 0x9f, 0xb6, 0x94, 0xf1, 0x8c, 0xa2, 0x97, 0xbf, 0xd5, 0xaa,
+  0x63, 0x33, 0xc2, 0x02, 0xa5, 0xce, 0xc7, 0x9b, 0x63, 0x6f, 0x25, 0xd6,
+  0xde, 0x67, 0x4d, 0x12, 0x9d, 0x11, 0x2d, 0x90, 0xa1, 0xf7, 0xd1, 0xec,
+  0xff, 0x86, 0x37, 0xf3, 0x18, 0x3e, 0x95, 0x41, 0xbc, 0x39, 0xcd, 0x98,
+  0x11, 0xa5, 0x31, 0x18, 0xdf, 0x97, 0x7a, 0x49, 0x3d, 0x34, 0xb8, 0x16,
+  0xf4, 0x92, 0xe1, 0x29, 0xec, 0xa2, 0x83, 0x9d, 0xd2, 0x8a, 0xd0, 0x45,
+  0x9c, 0x98, 0x36, 0x6d, 0xc9, 0xb2, 0x38, 0x31, 0xf2, 0x55, 0x6f, 0xb0,
+  0xed, 0x7e, 0x7b, 0xce, 0x88, 0xa5, 0x06, 0xf7, 0x81, 0x2c, 0x74, 0xbc,
+  0xb9, 0x1c, 0x86, 0xa9, 0x2c, 0x1f, 0x51, 0xcd, 0x46, 0x97, 0xef, 0xff,
+  0xcf, 0x86, 0xc8, 0xee, 0x51, 0xec, 0x06, 0x29, 0x59, 0x71, 0xcd, 0xac,
+  0x4f, 0xa6, 0x5b, 0x80, 0x69, 0x27, 0x2d, 0x52, 0xf8, 0x00, 0x3c, 0x00,
+  0xe3, 0xbb, 0x8f, 0x98, 0xdd, 0x0c, 0x91, 0xcd, 0x9c, 0x11, 0xef, 0x2f,
+  0xed, 0xcd, 0x33, 0x1d, 0xd0, 0xf0, 0x06, 0xb2, 0x6b, 0x87, 0xd8, 0x87,
+  0x6b, 0x36, 0xab, 0xdd, 0x9c, 0xf1, 0x7d, 0x19, 0xec, 0xc0, 0xd5, 0xb7,
+  0xa3, 0x12, 0xa4, 0xc9, 0xf5, 0xde, 0xba, 0x2c, 0xf7, 0x3e, 0x6d, 0x5d,
+  0x96, 0xee, 0x9d, 0x75, 0xd7, 0xe4, 0x08, 0x69, 0x1b, 0xed, 0x84, 0x66,
+  0xbc, 0x04, 0x28, 0x09, 0xc8, 0x89, 0x43, 0x80, 0x0c, 0xbd, 0xda, 0xd5,
+  0x01, 0x04, 0xa1, 0xe2, 0xb0, 0xff, 0x9c, 0x97, 0x40, 0x81, 0x17, 0x51,
+  0xe6, 0x93, 0x71, 0x55, 0xde, 0xd5, 0xd0, 0x9e, 0xd4, 0x9e, 0x4a, 0x19,
+  0x47, 0x79, 0x13, 0x44, 0xf3, 0xcd, 0xf4, 0xce, 0x2c, 0x91, 0xdb, 0x37,
+  0x97, 0x6f, 0x4e, 0x99, 0xac, 0x96, 0x33, 0xd9, 0x28, 0x6d, 0x45, 0xfa,
+  0xbc, 0x1c, 0xcf, 0xcd, 0xfa, 0x1b, 0x05, 0xa5, 0x61, 0x69, 0xa6, 0x02,
+  0x32, 0x48, 0xb7, 0x43, 0x54, 0x48, 0x82, 0x8a, 0x8b, 0x98, 0xaf, 0x5f,
+  0x5c, 0x41, 0x2e, 0x9a, 0x26, 0x8b, 0x8b, 0xdc, 0xaf, 0xd5, 0x00, 0x93,
+  0x9d, 0x8f, 0x83, 0xbb, 0xbb, 0xbb, 0x01, 0xf5, 0xce, 0x29, 0x26, 0x64,
+  0xb2, 0x1d, 0x31, 0xae, 0x02, 0xaa, 0xd4, 0x6b, 0x5a, 0x0a, 0x7a, 0x24,
+  0x38, 0x7d, 0x9e, 0xa6, 0x86, 0x9a, 0x0a, 0xe0, 0x84, 0xb4, 0x0e, 0x05,
+  0x52, 0xbc, 0x2c, 0xa1, 0x32, 0xc8, 0x44, 0xd2, 0xb6, 0xb2, 0xd5, 0x15,
+  0x69, 0x4e, 0xf9, 0x72, 0xd4, 0xc8, 0xbe, 0xfe, 0x45, 0xaa, 0x08, 0xa9,
+  0x44, 0x12, 0x93, 0x58, 0x56, 0xe4, 0x7f, 0x62, 0x0b, 0x23, 0x86, 0xdc,
+  0x16, 0x9d, 0x44, 0xfd, 0xfa, 0x36, 0x3a, 0xd6, 0xb2, 0x4c, 0x94, 0x03,
+  0x96, 0xda, 0xf6, 0x8e, 0x6f, 0x44, 0x4f, 0x64, 0xea, 0x0e, 0xe0, 0xf1,
+  0xb1, 0x9a, 0x66, 0xb3, 0x99, 0xd6, 0x51, 0xe2, 0x20, 0x85, 0x3f, 0x37,
+  0xd0, 0xf0, 0xa2, 0x3a, 0xb6, 0x23, 0x48, 0xae, 0x1d, 0x27, 0xae, 0x9a,
+  0x77, 0x60, 0x30, 0x01, 0x67, 0x09, 0x48, 0x71, 0xcb, 0xb6, 0x7b, 0x66,
+  0x10, 0x44, 0x10, 0xc5, 0x5d, 0xd3, 0xf7, 0x22, 0x35, 0x39, 0x39, 0x4c,
+  0xfc, 0xfc, 0x7e, 0x47, 0xd8, 0x37, 0xcf, 0xaa, 0x6b, 0xfa, 0x89, 0xb2,
+  0xb9, 0x45, 0xb3, 0x46, 0xd2, 0xc4, 0xa3, 0xaf, 0x49, 0x92, 0x7f, 0x1b,
+  0xf0, 0xa5, 0x0a, 0xcf, 0xca, 0x92, 0x60, 0xad, 0xe2, 0x02, 0xde, 0x1c,
+  0x4c, 0x59, 0xac, 0x4c, 0xd3, 0xc2, 0xcc, 0x84, 0x39, 0xb1, 0x21, 0xc4,
+  0x62, 0x36, 0x7b, 0x39, 0x2b, 0x97, 0xf5, 0xfd, 0x66, 0x22, 0xfc, 0xe4,
+  0x42, 0xe9, 0xdb, 0x70, 0x82, 0x26, 0xd6, 0xd2, 0xac, 0xef, 0xb2, 0xf8,
+  0xa0, 0xf7, 0x22, 0xa1, 0xdd, 0x6b, 0xf6, 0x2d, 0x76, 0x9a, 0xdb, 0xf4,
+  0x3e, 0xf6, 0x6f, 0x7e, 0xdb, 0xd1, 0x59, 0x86, 0x27, 0x92, 0xed, 0xbc,
+  0xc7, 0x19, 0x7a, 0x2e, 0x8a, 0x10, 0xb3, 0xf2, 0x92, 0x56, 0xd4, 0xc7,
+  0x36, 0x48, 0xf7, 0x06, 0x33, 0xe8, 0xa9, 0x97, 0xdc, 0x85, 0xff, 0x21,
+  0x6f, 0x56, 0xa4, 0x30, 0xb8, 0x9a, 0x5f, 0x9c, 0xc2, 0xe0, 0x28, 0x85,
+  0x38, 0xc5, 0xdb, 0xf2, 0x79, 0xfb, 0x19, 0x53, 0xc3, 0xe4, 0xdc, 0xcc,
+  0xd7, 0x20, 0x88, 0xfc, 0x5c, 0x7b, 0xcd, 0xa5, 0x3e, 0x5f, 0x99, 0x5c,
+  0x6b, 0x36, 0x13, 0x96, 0xf1, 0xc9, 0x00, 0x9d, 0x27, 0xd6, 0x9a, 0x0c,
+  0x90, 0x1e, 0x6c, 0x5a, 0xd2, 0xce, 0xb2, 0xd6, 0xa7, 0xf5, 0x14, 0x13,
+  0x51, 0x2a, 0x25, 0x3e, 0x53, 0x74, 0x5c, 0x8d, 0x69, 0xf6, 0xb5, 0xb3,
+  0x9b, 0x33, 0x38, 0x33, 0xde, 0xe9, 0xa5, 0xf9, 0x80, 0x10, 0xb0, 0xac,
+  0xa9, 0x74, 0x93, 0x75, 0x8c, 0x2e, 0xce, 0xdd, 0x75, 0x62, 0x25, 0x18,
+  0x2c, 0x23, 0x13, 0xd7, 0x40, 0x9a, 0xfc, 0xb3, 0xed, 0xdd, 0x36, 0xce,
+  0xea, 0xea, 0x5e, 0x41, 0xab, 0xfd, 0x85, 0x8e, 0x77, 0xce, 0x89, 0x40,
+  0x7e, 0xfd, 0x44, 0xa1, 0x52, 0xd2, 0x9a, 0x78, 0xba, 0x7c, 0x53, 0x2f,
+  0x9b, 0x65, 0xd7, 0x3c, 0xa6, 0x17, 0xa7, 0xc7, 0xdf, 0x1d, 0x9f, 0x06,
+  0x17, 0xd8, 0xd7, 0xa3, 0xd1, 0xce, 0x87, 0xac, 0x1a, 0xa3, 0x0a, 0x13,
+  0xf9, 0xbc, 0x13, 0x3c, 0x67, 0xf1, 0x3a, 0x9e, 0x54, 0xbf, 0x73, 0xc9,
+  0xe5, 0x09, 0xa3, 0x76, 0x03, 0x63, 0x9f, 0x10, 0x99, 0xfc, 0x49, 0x61,
+  0x4c, 0x45, 0xfe, 0x88, 0x00, 0xc3, 0x70, 0x4b, 0x4d, 0xaa, 0x6c, 0xca,
+  0x55, 0x8a, 0x42, 0x48, 0x58, 0x41, 0x6a, 0x7e, 0x92, 0xbc, 0xc2, 0x52,
+  0x32, 0x2c, 0x18, 0xd1, 0x0f, 0x3b, 0x88, 0xe0, 0x8d, 0x45, 0x69, 0xae,
+  0x90, 0xfb, 0xe4, 0x95, 0x7c, 0xb3, 0x66, 0xe7, 0x26, 0xcd, 0x06, 0x73,
+  0xcf, 0xb0, 0xc9, 0x70, 0xf6, 0xed, 0xe0, 0x70, 0x34, 0x78, 0x75, 0x7c,
+  0x7a, 0xfc, 0xf5, 0xe1, 0xe5, 0xb1, 0xd2, 0x82, 0x92, 0xfb, 0x7f, 0x85,
+  0x32, 0xc4, 0xf2, 0xee, 0x5b, 0x99, 0x16, 0x8c, 0x9f, 0x68, 0x65, 0x9b,
+  0x9c, 0xc9, 0x9e, 0x95, 0x3d, 0x97, 0x4b, 0xe9, 0x91, 0x89, 0x22, 0xc8,
+  0xd0, 0x78, 0x73, 0xe6, 0xf4, 0xcd, 0xe6, 0xd2, 0xd5, 0x60, 0x04, 0xe9,
+  0xec, 0x8e, 0xca, 0x3e, 0xbc, 0x2b, 0x08, 0x17, 0x9d, 0xdb, 0x34, 0x40,
+  0x1e, 0xbd, 0x37, 0xf9, 0xde, 0xcc, 0xb6, 0x16, 0x18, 0xf4, 0x99, 0x2b,
+  0x8c, 0x77, 0xcd, 0xe1, 0x45, 0xf0, 0xf1, 0x15, 0x9e, 0xec, 0xd0, 0x74,
+  0x0e, 0x5d, 0x12, 0x6f, 0x61, 0x7f, 0x15, 0x49, 0xb3, 0xa7, 0x0d, 0x54,
+  0x4f, 0x6e, 0xb2, 0xb9, 0x68, 0x94, 0x14, 0x70, 0x46, 0x7a, 0x27, 0xe7,
+  0xcb, 0x09, 0xb3, 0x01, 0x1f, 0xf4, 0x71, 0x06, 0xc1, 0x8c, 0x78, 0x0e,
+  0x36, 0x6f, 0x0c, 0xba, 0x79, 0x47, 0xe4, 0xbd, 0xe4, 0xa4, 0x27, 0x08,
+  0x06, 0xb2, 0x42, 0x87, 0x40, 0x8b, 0x71, 0x9e, 0x40, 0xd1, 0x0a, 0xfd,
+  0x5a, 0x79, 0xc9, 0xb5, 0x49, 0xba, 0x97, 0xbf, 0x65, 0x01, 0xf5, 0x78,
+  0xfc, 0x28, 0xb2, 0x83, 0x1f, 0x41, 0x60, 0xaa, 0xea, 0x4b, 0x9d, 0xfc,
+  0x95, 0x1e, 0x4e, 0xde, 0x4f, 0xdc, 0x77, 0x49, 0xc8, 0xc1, 0x66, 0x8d,
+  0xa2, 0x70, 0xa3, 0x82, 0x41, 0x62, 0xed, 0xd4, 0x5d, 0xed, 0x2f, 0xdb,
+  0x68, 0x4a, 0x51, 0xca, 0x4b, 0x99, 0xc8, 0x59, 0x16, 0x5e, 0xdf, 0x47,
+  0x0a, 0x86, 0x16, 0xf1, 0x2f, 0x11, 0xad, 0xea, 0x5f, 0x43, 0x7a, 0x66,
+  0x9b, 0x3e, 0x35, 0xc8, 0x16, 0x01, 0xef, 0xe5, 0xd6, 0x6b, 0xa5, 0xb2,
+  0xb5, 0x7a, 0x9e, 0x5f, 0xcb, 0xc1, 0x23, 0x5e, 0x3f, 0x3e, 0xbf, 0xe0,
+  0x82, 0x8a, 0xa7, 0xf4, 0x17, 0x09, 0xda, 0xd4, 0x31, 0xae, 0x1e, 0xa1,
+  0xd2, 0x26, 0x8c, 0x41, 0x06, 0xaf, 0xbf, 0x8d, 0xc5, 0x2a, 0xb0, 0x8c,
+  0xe1, 0x84, 0xc2, 0x57, 0x2a, 0x07, 0x22, 0x96, 0x8b, 0xe8, 0x15, 0x00,
+  0xa2, 0x9e, 0x50, 0x17, 0x84, 0x9e, 0x10, 0x9d, 0x60, 0x48, 0xa4, 0xfa,
+  0xd6, 0xcf, 0xe8, 0x97, 0xa4, 0xfb, 0x29, 0x70, 0x60, 0xc5, 0x34, 0xb6,
+  0xf8, 0x84, 0xa9, 0x59, 0x7a, 0x33, 0xa9, 0x50, 0x2e, 0x2a, 0x35, 0x5d,
+  0x19, 0x76, 0x86, 0x0a, 0xc2, 0x7f, 0xe2, 0x06, 0x0b, 0x5d, 0xe9, 0x28,
+  0x75, 0x20, 0x7e, 0x31, 0xc1, 0x19, 0x63, 0xc0, 0x0a, 0x9f, 0xee, 0x4b,
+  0x88, 0x3a, 0xb5, 0xe1, 0x4a, 0x94, 0x9a, 0x44, 0xec, 0x3a, 0xd0, 0xb6,
+  0x05, 0x63, 0xce, 0x63, 0xa0, 0xcc, 0x68, 0x89, 0xba, 0xb2, 0x72, 0x76,
+  0x25, 0x91, 0xad, 0x14, 0x74, 0x90, 0x30, 0x33, 0xc6, 0xac, 0x4d, 0x00,
+  0xa4, 0x75, 0x93, 0x16, 0x91, 0x53, 0x67, 0x26, 0xde, 0xd6, 0x5c, 0xc0,
+  0x28, 0x65, 0xd9, 0x22, 0x0a, 0x35, 0xed, 0x8d, 0x16, 0xc6, 0x97, 0x00,
+  0xed, 0x1f, 0x49, 0x61, 0xcf, 0xc9, 0x25, 0x2e, 0x5d, 0xe1, 0x99, 0x21,
+  0xf2, 0x0f, 0xdd, 0x6f, 0x65, 0x6c, 0x57, 0x89, 0x78, 0x71, 0x8e, 0xfa,
+  0xd6, 0x16, 0x5c, 0xe1, 0x02, 0xce, 0x12, 0x8b, 0xe8, 0xa9, 0x91, 0x33,
+  0xe1, 0x11, 0xff, 0x51, 0x0d, 0xb3, 0x76, 0x52, 0x05, 0x96, 0x0f, 0xf7,
+  0x7a, 0xd1, 0x05, 0x30, 0x64, 0x8c, 0xa4, 0x37, 0xdf, 0x46, 0x77, 0xc9,
+  0x2b, 0x63, 0x83, 0x79, 0xb4, 0x79, 0x82, 0xef, 0xbf, 0x42, 0xe7, 0xe8,
+  0x3b, 0x78, 0x01, 0x27, 0xdf, 0xe8, 0x0f, 0x5c, 0x02, 0x8f, 0x10, 0x3b,
+  0xbc, 0x95, 0xc7, 0x99, 0xf9, 0x5e, 0x4e, 0x35, 0x36, 0xfc, 0x1a, 0x35,
+  0x21, 0x6a, 0xb5, 0x36, 0x1b, 0x90, 0x6e, 0x0b, 0x52, 0xc4, 0x48, 0x0a,
+  0xd1, 0xbb, 0x14, 0x8a, 0xcf, 0x12, 0xbf, 0x40, 0x0d, 0x36, 0x04, 0xb4,
+  0xf7, 0xf3, 0xbe, 0x84, 0xc2, 0x00, 0x56, 0x0b, 0x22, 0xca, 0x66, 0x02,
+  0x27, 0x96, 0x23, 0x44, 0x9f, 0x4c, 0xeb, 0xdb, 0xf8, 0x09, 0xaf, 0x6f,
+  0xa3, 0x27, 0xfc, 0x11, 0xe7, 0xdc, 0xd9, 0x3e, 0xc7, 0xe7, 0xa3, 0xef,
+  0x56, 0xa5, 0xfb, 0x33, 0x2d, 0x3a, 0x1f, 0x71, 0x37, 0x3a, 0xda, 0xf4,
+  0xfe, 0x31, 0x5f, 0x7d, 0xce, 0xa3, 0xee, 0xfa, 0xe0, 0x9c, 0x9b, 0xef,
+  0xcb, 0xe1, 0x3e, 0x3f, 0x1c, 0x7d, 0xe7, 0x1d, 0x6b, 0x6f, 0x0b, 0xe0,
+  0x1c, 0xc7, 0xb2, 0x8d, 0x51, 0x7f, 0xa7, 0x52, 0x72, 0x40, 0x6a, 0x2c,
+  0xba, 0xdf, 0xeb, 0xdb, 0xc7, 0xec, 0x77, 0xd3, 0x93, 0x60, 0xbf, 0x07,
+  0x73, 0xbc, 0x6e, 0xbf, 0xfb, 0x0b, 0xd5, 0xc6, 0x40, 0x7a, 0xbb, 0xbd,
+  0xe0, 0x2a, 0x7d, 0x37, 0x28, 0xf8, 0x1a, 0xdf, 0xe6, 0x40, 0xc2, 0xf2,
+  0xd6, 0x0e, 0x21, 0x62, 0xe8, 0xe7, 0x2f, 0xdb, 0xe8, 0xe6, 0x85, 0x60,
+  0xa3, 0xeb, 0x7a, 0xc6, 0x77, 0xfa, 0xaa, 0x8d, 0xae, 0x08, 0xd1, 0x8c,
+  0x37, 0xb9, 0xbf, 0xc7, 0xc3, 0xfd, 0xed, 0xed, 0x5a, 0x3f, 0xb5, 0x37,
+  0x9c, 0x21, 0x05, 0x2a, 0xd9, 0x3c, 0x75, 0x2f, 0x4d, 0x3f, 0x42, 0x0b,
+  0xd1, 0x57, 0x28, 0x1b, 0x12, 0x1c, 0x43, 0xef, 0xba, 0x25, 0x54, 0x68,
+  0x81, 0xd9, 0x2b, 0xd5, 0xa5, 0x71, 0x8b, 0xe3, 0xda, 0x86, 0xa9, 0xee,
+  0x67, 0x89, 0x5f, 0x05, 0x27, 0xb2, 0x45, 0xfe, 0x92, 0x45, 0xf3, 0x8d,
+  0xeb, 0x8c, 0x20, 0x02, 0xe0, 0x1d, 0x6a, 0x9d, 0xd3, 0xa2, 0x1e, 0xb8,
+  0x2a, 0x8a, 0x2f, 0xec, 0x5f, 0x03, 0x2d, 0xfd, 0xd5, 0xdb, 0x51, 0xe7,
+  0xb8, 0xd6, 0x19, 0x23, 0xe6, 0xaf, 0x71, 0xf4, 0xcc, 0xef, 0x6d, 0x9e,
+  0x4b, 0xed, 0xaa, 0x96, 0x48, 0x93, 0x41, 0x22, 0x33, 0x7d, 0xc2, 0x72,
+  0xcb, 0x3b, 0xc5, 0x27, 0xd5, 0xc2, 0x9f, 0xf0, 0xf7, 0x91, 0xcf, 0xc5,
+  0xeb, 0x9d, 0x64, 0xfa, 0x92, 0x27, 0x25, 0x46, 0xf3, 0xc2, 0x42, 0x96,
+  0xfa, 0xa9, 0x05, 0xd4, 0x84, 0x75, 0x55, 0xe8, 0x9d, 0x6c, 0xc1, 0x85,
+  0x22, 0xf1, 0x0a, 0x47, 0xc6, 0x22, 0x33, 0x5b, 0x42, 0x1b, 0x23, 0x90,
+  0x9d, 0xed, 0xb5, 0xda, 0x14, 0x4f, 0xe1, 0xe2, 0xf6, 0xe9, 0x80, 0x1e,
+  0x57, 0xe5, 0x49, 0x7e, 0xf8, 0x1c, 0x3f, 0x1c, 0x76, 0x27, 0x3a, 0xb0,
+  0x35, 0xa5, 0xca, 0x91, 0xf5, 0x32, 0x2e, 0x8b, 0x29, 0xf1, 0x3f, 0x53,
+  0xb7, 0xb5, 0x62, 0xf1, 0x5d, 0xea, 0x78, 0xab, 0x49, 0x90, 0x0b, 0x3b,
+  0x8b, 0xd9, 0x4b, 0xdd, 0xc9, 0x4d, 0x51, 0xba, 0xd8, 0xf3, 0x28, 0x3e,
+  0xe9, 0x86, 0xdf, 0x5a, 0x3d, 0x7e, 0x21, 0xc3, 0x8c, 0x2f, 0x39, 0xaf,
+  0xb9, 0x67, 0xc9, 0x8f, 0x73, 0x2e, 0xba, 0xf0, 0x22, 0x5f, 0x0c, 0xf4,
+  0x4d, 0x16, 0xc2, 0xf3, 0xf4, 0x83, 0x5c, 0x8d, 0x4f, 0x69, 0x19, 0x22,
+  0x83, 0xe4, 0xa2, 0x68, 0x7e, 0x60, 0x87, 0xb6, 0x8d, 0xdd, 0x35, 0xa2,
+  0xb2, 0x34, 0x96, 0xa3, 0x0d, 0xe6, 0x0d, 0x7f, 0x23, 0x96, 0x06, 0xa3,
+  0xc0, 0x55, 0xdf, 0x67, 0xa1, 0x90, 0x77, 0xf4, 0xc2, 0xbe, 0xfb, 0xe0,
+  0xfa, 0xb9, 0xfd, 0xb0, 0x6e, 0xfd, 0x74, 0xce, 0xfe, 0x7b, 0xac, 0xdf,
+  0xf3, 0xdf, 0x6d, 0xfd, 0x9e, 0xff, 0xb7, 0x58, 0xbf, 0xe7, 0xff, 0xfc,
+  0xfa, 0x3d, 0xed, 0xae, 0xdf, 0xf3, 0xff, 0x2e, 0xeb, 0xa7, 0xe5, 0x3e,
+  0x74, 0xf5, 0xb2, 0x60, 0xfd, 0xc8, 0x13, 0xc2, 0x57, 0x08, 0x08, 0xbe,
+  0xa0, 0x0d, 0xd1, 0x74, 0xeb, 0x9b, 0x1c, 0x78, 0x10, 0xac, 0x19, 0x7b,
+  0x76, 0x15, 0xf2, 0x88, 0xcc, 0xfb, 0x38, 0x4f, 0xa3, 0x70, 0x27, 0x29,
+  0xe1, 0xd9, 0xc9, 0x79, 0x62, 0x3b, 0xe0, 0x2d, 0x83, 0xa3, 0x19, 0x82,
+  0x92, 0x13, 0x75, 0xb9, 0xd6, 0xe4, 0x87, 0x33, 0x13, 0xc0, 0xc9, 0x66,
+  0xb5, 0x4b, 0x95, 0x8c, 0x71, 0x09, 0x99, 0xc9, 0x3b, 0x78, 0x41, 0xf3,
+  0x35, 0xe0, 0xc7, 0xbf, 0x88, 0xe6, 0xff, 0xa0, 0xaa, 0x9a, 0xeb, 0x52,
+  0xcc, 0xcd, 0xee, 0x4d, 0xdd, 0xa3, 0x97, 0x6d, 0x55, 0xe1, 0x09, 0x5d,
+  0xc2, 0xc9, 0xe0, 0xa1, 0x25, 0x7b, 0x05, 0xcd, 0x60, 0x39, 0x5f, 0x48,
+  0x5e, 0xe0, 0x03, 0x79, 0x51, 0xd0, 0x3f, 0xb7, 0x93, 0xef, 0x91, 0xf5,
+  0xc4, 0x9e, 0x55, 0xc9, 0x15, 0xb0, 0x25, 0x81, 0x15, 0x88, 0xad, 0x61,
+  0x8b, 0x15, 0x04, 0x46, 0x51, 0x2e, 0x99, 0x4e, 0xce, 0x2f, 0x83, 0xda,
+  0x6d, 0x8d, 0xdd, 0xac, 0xf0, 0x35, 0x24, 0xc1, 0x44, 0x4b, 0x1a, 0x2f,
+  0x7f, 0x34, 0x4a, 0x1b, 0x49, 0xd7, 0x22, 0x27, 0x4a, 0x50, 0xa7, 0x99,
+  0x06, 0xcc, 0xbc, 0x6e, 0x9a, 0x1a, 0x4a, 0xb6, 0x84, 0x57, 0xa1, 0x56,
+  0x7b, 0x0f, 0x66, 0x96, 0x18, 0x94, 0x58, 0x55, 0x19, 0xd8, 0x85, 0x92,
+  0x73, 0x6f, 0x49, 0x51, 0x8b, 0x5b, 0x05, 0xce, 0x83, 0x1e, 0xc6, 0xa7,
+  0x52, 0x1f, 0x8c, 0xc3, 0x0c, 0x18, 0x85, 0x71, 0xf2, 0x88, 0xff, 0x80,
+  0xfd, 0xbb, 0x02, 0xc4, 0xcd, 0x3a, 0x84, 0x6f, 0x87, 0x06, 0x6b, 0xee,
+  0x43, 0xc4, 0x87, 0x1b, 0xeb, 0xe0, 0x9b, 0x8c, 0x0b, 0xbc, 0xc9, 0xfc,
+  0x2c, 0x44, 0x4b, 0xe1, 0xc6, 0x0e, 0x61, 0x06, 0x1e, 0x99, 0xc1, 0x09,
+  0x8a, 0x2d, 0xa0, 0xa5, 0x47, 0xa2, 0xb1, 0xcc, 0x56, 0x4f, 0x88, 0x51,
+  0x96, 0x0c, 0x41, 0x22, 0x1e, 0xb7, 0x29, 0x53, 0x77, 0xfc, 0x0b, 0xb3,
+  0xfe, 0x3c, 0x54, 0xa7, 0x2f, 0x92, 0xb2, 0x6b, 0x8e, 0x85, 0xae, 0x43,
+  0x10, 0xda, 0x64, 0x3f, 0xbf, 0x4c, 0x1c, 0x87, 0x67, 0x65, 0x17, 0x1f,
+  0x17, 0x4d, 0x55, 0x2e, 0xee, 0x93, 0xaf, 0x53, 0x1a, 0x16, 0xd4, 0xc2,
+  0x34, 0x9b, 0x07, 0x39, 0x1f, 0x5c, 0x3b, 0x4e, 0xb4, 0x34, 0xae, 0x23,
+  0xa7, 0x23, 0x84, 0x5e, 0xc9, 0xd3, 0x92, 0x50, 0xd1, 0xf7, 0x29, 0xf9,
+  0xf3, 0x34, 0x77, 0x0c, 0xb0, 0xc9, 0xd1, 0xe8, 0x34, 0x54, 0xa6, 0x95,
+  0xfe, 0x7e, 0x6d, 0x8e, 0x2f, 0x5a, 0x1b, 0xb4, 0x4f, 0x94, 0x19, 0x39,
+  0x37, 0xfe, 0x22, 0x7a, 0x98, 0x65, 0xdc, 0xd9, 0x4c, 0x33, 0xe1, 0x85,
+  0x38, 0x3c, 0x99, 0x54, 0xf7, 0x0b, 0x32, 0xd0, 0xf8, 0x65, 0x39, 0x7b,
+  0xd4, 0x3f, 0x26, 0x51, 0x5c, 0x9b, 0x46, 0xf8, 0x0e, 0x11, 0x32, 0x79,
+  0x15, 0x82, 0x98, 0x82, 0x99, 0x66, 0xba, 0x28, 0xb8, 0xaa, 0x82, 0x99,
+  0x64, 0xd6, 0x14, 0x04, 0x09, 0xae, 0x22, 0x47, 0xc0, 0x02, 0x86, 0x12,
+  0x1b, 0x1d, 0x2a, 0x65, 0xb8, 0x75, 0x90, 0x69, 0x49, 0x74, 0xbd, 0xf0,
+  0x68, 0x6f, 0xeb, 0xc5, 0x20, 0x6f, 0x74, 0x6a, 0x81, 0xaa, 0x08, 0xb6,
+  0x4c, 0xbb, 0x29, 0x65, 0x4c, 0x17, 0x01, 0x3b, 0x03, 0x87, 0xbc, 0xf7,
+  0x76, 0x77, 0x1f, 0xa4, 0xdd, 0x10, 0xf7, 0xaf, 0xb2, 0x6f, 0x60, 0x14,
+  0x54, 0xaa, 0x50, 0xa8, 0x37, 0x1a, 0xad, 0x03, 0xee, 0x88, 0x37, 0x90,
+  0x24, 0x9a, 0xe6, 0x92, 0x70, 0xd0, 0x25, 0x2a, 0x32, 0x9f, 0xb4, 0x24,
+  0x18, 0xee, 0x08, 0xb2, 0xac, 0x63, 0x76, 0x1a, 0xd0, 0x70, 0x18, 0x11,
+  0x76, 0x8c, 0x3e, 0xd6, 0x07, 0xad, 0x77, 0xa2, 0x05, 0xf2, 0xa8, 0x43,
+  0xf4, 0x92, 0x68, 0x2f, 0xc3, 0xe4, 0xab, 0x7b, 0x67, 0x38, 0x79, 0x45,
+  0xde, 0xd1, 0x2b, 0x76, 0xb5, 0x4a, 0x79, 0xe6, 0x28, 0xf1, 0xfc, 0x5a,
+  0x6a, 0x8d, 0x3f, 0x78, 0xbc, 0x52, 0x46, 0x00, 0x2d, 0x6a, 0xb4, 0x8a,
+  0x0c, 0xfd, 0xb8, 0xc7, 0xc0, 0x8e, 0xd6, 0xd2, 0x12, 0xba, 0x61, 0x7b,
+  0xac, 0xfa, 0x7c, 0xa9, 0xac, 0xe5, 0x43, 0x6d, 0x13, 0xa5, 0xb4, 0x51,
+  0x79, 0x9f, 0xb4, 0xd5, 0x12, 0xca, 0x54, 0x1c, 0x20, 0x1f, 0xb1, 0x9b,
+  0x85, 0x4d, 0x29, 0x8c, 0xa8, 0x8b, 0xfd, 0x91, 0x51, 0x1a, 0xce, 0x04,
+  0x26, 0x82, 0x1e, 0x86, 0x41, 0x68, 0xae, 0x44, 0x87, 0xff, 0x31, 0xc6,
+  0xab, 0xa5, 0x27, 0xdd, 0x4f, 0x96, 0x0a, 0x52, 0xa3, 0xd4, 0x96, 0x66,
+  0x63, 0x3a, 0x4c, 0x33, 0x97, 0xe5, 0x51, 0x4f, 0x0d, 0x74, 0x32, 0x4e,
+  0xbe, 0x44, 0xb8, 0x18, 0xaa, 0x04, 0xeb, 0x1e, 0xef, 0x2e, 0x4e, 0xfb,
+  0x89, 0xd4, 0x56, 0x24, 0xc0, 0xa7, 0x59, 0xe9, 0xb8, 0x6e, 0xe4, 0xa8,
+  0xcc, 0x99, 0x97, 0x8e, 0xc7, 0x52, 0x3b, 0x86, 0x25, 0x12, 0xdb, 0x70,
+  0x7e, 0x9a, 0x26, 0x6b, 0x45, 0xc8, 0x84, 0x2e, 0x29, 0x56, 0xda, 0x48,
+  0x30, 0xd3, 0x83, 0x9b, 0x48, 0x25, 0x84, 0xfb, 0x50, 0x3b, 0x6d, 0x69,
+  0x8d, 0x34, 0x6d, 0x9f, 0x93, 0x41, 0xc9, 0x59, 0x11, 0x49, 0x29, 0x95,
+  0x50, 0x24, 0xd1, 0xa1, 0x25, 0x58, 0x1e, 0xe4, 0x94, 0x2e, 0x2b, 0x2f,
+  0x20, 0xd9, 0xbb, 0xc9, 0xcd, 0xba, 0x16, 0x3d, 0xa6, 0x5b, 0x5b, 0x8e,
+  0x99, 0xca, 0xaf, 0xc1, 0x87, 0x63, 0xf0, 0x60, 0xc2, 0xd7, 0x39, 0xef,
+  0x58, 0xbc, 0x70, 0x62, 0x0b, 0x04, 0xdb, 0x4f, 0x5a, 0x87, 0x42, 0x15,
+  0x4e, 0xee, 0x9a, 0xcb, 0x67, 0x8d, 0x72, 0xbe, 0xf3, 0x4e, 0x71, 0xc9,
+  0x34, 0x74, 0xfa, 0x51, 0xc3, 0xa1, 0xef, 0xf3, 0xa8, 0x3b, 0x6f, 0x9f,
+  0x5f, 0xb1, 0x9d, 0x26, 0x3a, 0xae, 0xae, 0x54, 0x36, 0xcb, 0x3e, 0x42,
+  0xc9, 0x29, 0x58, 0xa7, 0xf4, 0x1e, 0x59, 0x03, 0xf6, 0xd3, 0xd8, 0xe1,
+  0x01, 0xaf, 0x12, 0x91, 0x8c, 0x95, 0xd0, 0x1d, 0x65, 0x2f, 0x53, 0xe1,
+  0x9a, 0x49, 0x95, 0x2f, 0x1a, 0x0e, 0xff, 0x06, 0x65, 0xb5, 0xe3, 0x6a,
+  0xd8, 0xf5, 0xac, 0x1c, 0xa7, 0x7c, 0x4e, 0x2c, 0xd8, 0x43, 0xdd, 0x4e,
+  0x2d, 0xc2, 0x4f, 0x94, 0x0a, 0x36, 0xdb, 0x33, 0x92, 0xa8, 0x63, 0x86,
+  0x3c, 0x38, 0x40, 0xbd, 0x4b, 0x8a, 0x47, 0xad, 0xfb, 0xa0, 0xfd, 0x04,
+  0x73, 0x6a, 0x0d, 0xae, 0xfa, 0x72, 0x82, 0x35, 0xe3, 0x11, 0x58, 0x99,
+  0xda, 0x3b, 0x57, 0x81, 0x2a, 0x84, 0xcc, 0xe4, 0xe9, 0x32, 0x6b, 0x43,
+  0x67, 0x36, 0x25, 0x5a, 0x27, 0xc5, 0x4f, 0x00, 0xdf, 0xb0, 0xb5, 0xb5,
+  0x25, 0x2a, 0x16, 0x85, 0x85, 0x10, 0xbd, 0xa6, 0xad, 0x3e, 0xad, 0x35,
+  0x60, 0x0b, 0xba, 0x99, 0x5c, 0xe7, 0x14, 0x91, 0xe8, 0xcd, 0x15, 0xb3,
+  0xf7, 0x57, 0x41, 0x19, 0xd3, 0x2b, 0xd6, 0xd3, 0x80, 0xf3, 0xe4, 0x35,
+  0x59, 0x33, 0x33, 0x3e, 0x53, 0xef, 0x7e, 0x4b, 0xaa, 0xd9, 0x4f, 0xc7,
+  0xaf, 0x28, 0x88, 0x36, 0x2e, 0xf8, 0x6d, 0x66, 0x71, 0x8b, 0xaa, 0x08,
+  0x73, 0xf6, 0x4a, 0x8a, 0xf8, 0x2f, 0x38, 0xe7, 0xb4, 0xf0, 0x0b, 0x4b,
+  0x83, 0x78, 0x66, 0x0d, 0x9d, 0x14, 0xa9, 0x6b, 0x8c, 0x32, 0xae, 0x58,
+  0x73, 0x68, 0xa1, 0xe2, 0xb8, 0xd5, 0x0d, 0x95, 0x35, 0x13, 0xef, 0x97,
+  0xd3, 0x2c, 0x9d, 0xc5, 0xa8, 0xb6, 0xa9, 0xc3, 0xe4, 0x6d, 0x64, 0xe1,
+  0x46, 0x8c, 0xa7, 0x85, 0xf8, 0xad, 0x05, 0x77, 0xca, 0xb0, 0xab, 0x42,
+  0xb2, 0x3a, 0xb5, 0x87, 0x38, 0x55, 0x11, 0x43, 0x87, 0x08, 0xdf, 0x6f,
+  0x85, 0x5f, 0x41, 0x59, 0x82, 0x25, 0xea, 0xe4, 0x20, 0xf4, 0xd0, 0xff,
+  0xdf, 0x9c, 0xda, 0x07, 0xb0, 0x03, 0x80, 0x11, 0xee, 0x36, 0x27, 0x8e,
+  0x38, 0xce, 0xeb, 0xe2, 0x72, 0xeb, 0x02, 0x65, 0xa7, 0x8e, 0x31, 0xdc,
+  0x80, 0xc4, 0xe4, 0xb6, 0x9c, 0x43, 0x84, 0xbb, 0x45, 0x72, 0x2c, 0xc2,
+  0x95, 0xbe, 0xcd, 0x14, 0x2a, 0x02, 0xfb, 0x82, 0x17, 0xa0, 0xb1, 0xe9,
+  0x6e, 0xd4, 0x9a, 0xc8, 0x19, 0x16, 0x32, 0xfb, 0xfb, 0x2b, 0x8a, 0xbf,
+  0x48, 0xc5, 0x47, 0xd9, 0x63, 0x38, 0xec, 0x75, 0x7a, 0x65, 0x8b, 0xb1,
+  0x8a, 0x00, 0x2f, 0x27, 0x66, 0x0a, 0xb9, 0x50, 0x34, 0x7e, 0x56, 0x44,
+  0x72, 0x52, 0x58, 0x5c, 0x93, 0x94, 0xb4, 0xd7, 0x2e, 0x1d, 0x04, 0x85,
+  0x4f, 0xd6, 0xb3, 0x7c, 0x61, 0x7d, 0x9c, 0x7d, 0x22, 0x50, 0x65, 0x18,
+  0x07, 0x05, 0x68, 0xef, 0x42, 0xb2, 0xc0, 0x4e, 0x61, 0x4a, 0x61, 0x96,
+  0x9c, 0x91, 0xfa, 0xbf, 0xd5, 0x69, 0xff, 0xe9, 0xee, 0x1e, 0xba, 0xfb,
+  0x74, 0xf7, 0x93, 0xed, 0xf6, 0xdd, 0x3c, 0xab, 0xb3, 0x01, 0x70, 0x3c,
+  0x71, 0x1d, 0x95, 0xab, 0x9b, 0x38, 0x3f, 0x0f, 0xf4, 0x51, 0x7a, 0x49,
+  0xc0, 0x3f, 0xd3, 0x65, 0xa5, 0x88, 0x38, 0x2a, 0x78, 0x43, 0x36, 0x63,
+  0x7d, 0x43, 0x74, 0x66, 0xc1, 0x5d, 0xef, 0xde, 0x81, 0x31, 0x05, 0x17,
+  0x3a, 0xcf, 0x94, 0xd9, 0x3d, 0xf4, 0xae, 0x2d, 0x94, 0x22, 0x93, 0xc1,
+  0xe0, 0x22, 0xb2, 0x18, 0x43, 0x6a, 0x59, 0x9f, 0xc3, 0x89, 0x93, 0x10,
+  0x38, 0x8a, 0xd2, 0x2e, 0x9d, 0x66, 0x25, 0xcf, 0xeb, 0xbc, 0xc8, 0xeb,
+  0x1b, 0x94, 0x5c, 0xab, 0xeb, 0xf4, 0x3a, 0x0b, 0xd3, 0x54, 0x8d, 0x48,
+  0x32, 0x86, 0x93, 0x94, 0x46, 0x06, 0xb1, 0x33, 0x61, 0x71, 0xf8, 0x3c,
+  0x08, 0x8c, 0x5f, 0xca, 0xb2, 0x80, 0x6d, 0xc8, 0x0d, 0x73, 0x45, 0x59,
+  0x63, 0x57, 0x2c, 0x68, 0x55, 0xad, 0x20, 0x2a, 0x60, 0x01, 0xe2, 0x19,
+  0x2e, 0x2d, 0xc0, 0xb5, 0x05, 0x02, 0xc4, 0x1e, 0xf9, 0x11, 0xb6, 0x68,
+  0x71, 0xcf, 0x46, 0x46, 0x08, 0xed, 0x12, 0x16, 0x6a, 0x96, 0x82, 0x93,
+  0xd6, 0xfc, 0xcd, 0xfc, 0xec, 0x07, 0xa3, 0x91, 0x0e, 0x3f, 0xb3, 0x3f,
+  0xde, 0x7e, 0x5c, 0x71, 0xa1, 0xfd, 0x8e, 0x86, 0x46, 0xf0, 0x44, 0x71,
+  0x67, 0xc3, 0x60, 0x79, 0xc9, 0xff, 0x58, 0xe1, 0x84, 0x40, 0xd6, 0x58,
+  0x72, 0xf2, 0xe6, 0x90, 0xa0, 0x18, 0x23, 0x49, 0x9b, 0x68, 0x23, 0x19,
+  0x5b, 0x59, 0x36, 0xa8, 0xb4, 0x44, 0x0a, 0x6b, 0x94, 0x39, 0xcb, 0x92,
+  0x5d, 0x32, 0xa8, 0xaa, 0xc5, 0x65, 0xcc, 0x5c, 0xe2, 0x33, 0xaa, 0x29,
+  0x41, 0xa7, 0xc0, 0xc8, 0xc8, 0x53, 0xa9, 0xe2, 0x4d, 0x25, 0xc1, 0x23,
+  0xf9, 0x38, 0x9b, 0x2f, 0x3c, 0xde, 0x5e, 0x21, 0x36, 0x07, 0x3d, 0xe6,
+  0xe7, 0x84, 0xd3, 0x24, 0xaa, 0x02, 0xfe, 0xa6, 0xac, 0x01, 0x43, 0x0e,
+  0xe3, 0xd1, 0x55, 0x85, 0x50, 0x09, 0xf7, 0x56, 0x1b, 0xc5, 0xc1, 0x45,
+  0xfc, 0x88, 0xd5, 0xb8, 0x33, 0x6e, 0xd5, 0xe9, 0x36, 0x03, 0x26, 0x1a,
+  0x82, 0x32, 0x33, 0x07, 0x86, 0x54, 0x3a, 0x74, 0x25, 0xaf, 0xb8, 0x4f,
+  0xdc, 0x19, 0xb8, 0xbb, 0x26, 0x93, 0x9c, 0x74, 0x17, 0x9c, 0x7c, 0xf3,
+  0xcb, 0xeb, 0xeb, 0x28, 0xd6, 0xc4, 0x4c, 0x01, 0x2d, 0x3c, 0x8d, 0xf9,
+  0x2a, 0x4b, 0x1b, 0x68, 0x1c, 0x74, 0xd3, 0xaf, 0xc6, 0x93, 0x3a, 0x0d,
+  0x3e, 0xf2, 0x8c, 0x37, 0x8a, 0x17, 0x3e, 0x6a, 0x3f, 0xbe, 0x0b, 0xb0,
+  0x09, 0x78, 0x0f, 0x10, 0x55, 0x1e, 0x7e, 0x66, 0xbd, 0x50, 0x57, 0xa9,
+  0xd9, 0x14, 0xf7, 0x7d, 0x2d, 0xbc, 0xde, 0x58, 0x09, 0x92, 0xcd, 0x97,
+  0xdd, 0x2d, 0x3e, 0x53, 0xb4, 0x22, 0x83, 0x7a, 0x89, 0x91, 0x9f, 0xf1,
+  0x9f, 0x09, 0x33, 0x58, 0x13, 0x9b, 0x97, 0xc5, 0x01, 0x27, 0xca, 0x4a,
+  0xef, 0xe0, 0xbd, 0x41, 0x81, 0x53, 0x0f, 0xec, 0x2b, 0xca, 0x8a, 0x5a,
+  0x82, 0xc0, 0x2b, 0x0b, 0x24, 0xdd, 0xf7, 0x0e, 0x1d, 0x09, 0x96, 0xf7,
+  0x32, 0xc4, 0xf2, 0xb2, 0x21, 0x61, 0x24, 0xd1, 0x0e, 0x0e, 0x09, 0x83,
+  0xac, 0x27, 0xc4, 0x10, 0x01, 0x21, 0x53, 0x26, 0x17, 0xaf, 0x8f, 0x92,
+  0xfd, 0x27, 0x9f, 0x7e, 0x3a, 0x8c, 0x12, 0x08, 0x72, 0x82, 0xa5, 0xd9,
+  0x84, 0x34, 0x53, 0x8e, 0x6d, 0xae, 0x6f, 0x69, 0x43, 0x51, 0xe9, 0x3d,
+  0x4b, 0x0b, 0xa6, 0xed, 0x9e, 0x13, 0x31, 0x08, 0x09, 0xc7, 0xe5, 0x2c,
+  0x34, 0xf2, 0x11, 0xbb, 0x9a, 0x93, 0x62, 0x21, 0x52, 0x0c, 0x0a, 0x16,
+  0x49, 0x8d, 0x79, 0xbe, 0x42, 0xa9, 0xcb, 0x04, 0x27, 0x65, 0xab, 0x7b,
+  0xc3, 0x05, 0xc0, 0xe0, 0x3d, 0x46, 0x42, 0x1a, 0xbd, 0x01, 0xb0, 0x5f,
+  0x0e, 0xbe, 0xf3, 0x74, 0x6c, 0x46, 0xd2, 0x29, 0x69, 0x7e, 0x36, 0x13,
+  0x0d, 0x9f, 0x8d, 0x33, 0x9b, 0x21, 0xcd, 0x85, 0x3b, 0x3a, 0x24, 0x41,
+  0x9c, 0xf4, 0x59, 0x50, 0xa6, 0x0c, 0x51, 0xc5, 0x9b, 0x0f, 0x74, 0x9a,
+  0x43, 0x8e, 0xe3, 0x75, 0xd6, 0x84, 0xd9, 0x1d, 0x1e, 0xcc, 0x72, 0x4d,
+  0xe3, 0x31, 0xcb, 0x48, 0x92, 0x53, 0x92, 0x17, 0xca, 0xe3, 0xaf, 0x35,
+  0x9c, 0x27, 0x60, 0x15, 0x63, 0x7a, 0xf5, 0x2f, 0xb1, 0x1a, 0x2f, 0x64,
+  0xea, 0x25, 0x59, 0xeb, 0xcb, 0x28, 0x73, 0x90, 0x60, 0x3d, 0x41, 0x63,
+  0xd3, 0x34, 0x46, 0xb1, 0x76, 0xb2, 0x1b, 0xc0, 0x5a, 0x30, 0x96, 0x08,
+  0xf4, 0x53, 0x8b, 0x89, 0xd3, 0x86, 0x9d, 0xc5, 0x28, 0xfd, 0x5e, 0xd8,
+  0x46, 0xa5, 0x50, 0x00, 0x61, 0x9b, 0xa9, 0x2b, 0xb1, 0x99, 0x50, 0x02,
+  0x60, 0x92, 0x0f, 0xe6, 0xe9, 0xc0, 0xee, 0xa1, 0x77, 0xbd, 0x79, 0x8a,
+  0x50, 0x4c, 0x80, 0xeb, 0xee, 0xc0, 0x86, 0x53, 0xa9, 0x52, 0xdf, 0x5c,
+  0x76, 0x8c, 0x6a, 0x77, 0x0a, 0xc9, 0xe7, 0x3b, 0x78, 0xd3, 0xec, 0x4d,
+  0x6a, 0x6b, 0x33, 0x82, 0xfc, 0x6a, 0x5c, 0xbe, 0x84, 0x35, 0xa6, 0x70,
+  0x1a, 0xb8, 0x27, 0x96, 0xa3, 0x8b, 0x2e, 0xab, 0x2a, 0x35, 0x7b, 0xf1,
+  0x6f, 0x8b, 0x6b, 0xc7, 0x87, 0x7e, 0x13, 0x16, 0x1e, 0x30, 0x7a, 0x58,
+  0x58, 0x44, 0x04, 0x87, 0x74, 0xf0, 0x3a, 0x91, 0x8e, 0xbc, 0xfc, 0xb2,
+  0xd5, 0x9c, 0x72, 0x6d, 0xfb, 0x54, 0xb2, 0x82, 0x0a, 0x9d, 0x5c, 0xe7,
+  0x91, 0x94, 0x3a, 0xa1, 0x02, 0xe0, 0x9d, 0xe5, 0xa0, 0xc0, 0x7e, 0x4c,
+  0x43, 0x77, 0x19, 0x82, 0xf7, 0x2e, 0x04, 0x3f, 0xcb, 0x62, 0x15, 0x8b,
+  0x6c, 0x54, 0xf9, 0x9a, 0x2c, 0x24, 0x29, 0x62, 0x4b, 0xa4, 0x00, 0xba,
+  0xa3, 0xc8, 0x5b, 0xdb, 0x54, 0xcb, 0x49, 0xc3, 0x85, 0x04, 0xe4, 0x6b,
+  0xd0, 0x19, 0x43, 0xb4, 0x17, 0xef, 0x26, 0x10, 0x0d, 0x54, 0xd9, 0xf5,
+  0x92, 0x2e, 0x50, 0xee, 0x0b, 0x53, 0xe5, 0x8c, 0x97, 0xd8, 0xb9, 0x53,
+  0x0b, 0xc9, 0x23, 0x2f, 0x84, 0xb5, 0xee, 0x03, 0xa7, 0x05, 0x79, 0x02,
+  0xf2, 0x7f, 0x48, 0x90, 0x4a, 0xbc, 0x5f, 0xc4, 0x07, 0xc8, 0x8c, 0x4b,
+  0xf0, 0xf1, 0x64, 0x44, 0x03, 0xfe, 0x8a, 0x8a, 0x72, 0xb1, 0x1a, 0x43,
+  0x67, 0x6d, 0x93, 0x53, 0x1f, 0xbb, 0xdb, 0x8b, 0x37, 0x16, 0xdf, 0xc6,
+  0xa4, 0xc4, 0xfa, 0x1d, 0x74, 0x65, 0xcf, 0xf5, 0x89, 0x45, 0xbe, 0x40,
+  0x15, 0x04, 0x35, 0x67, 0xb7, 0x23, 0x16, 0xcc, 0xb2, 0x30, 0xd3, 0xd5,
+  0x2c, 0x29, 0x84, 0x67, 0x09, 0x2d, 0x8c, 0xf0, 0xfe, 0x9b, 0x50, 0xa5,
+  0xca, 0x70, 0xb9, 0x7c, 0xdc, 0xd4, 0xee, 0x1c, 0x60, 0x40, 0x42, 0x31,
+  0x78, 0x9b, 0x81, 0x24, 0x89, 0xf0, 0x0c, 0x8d, 0x8a, 0x3f, 0x14, 0x6e,
+  0x81, 0x3f, 0xf0, 0x73, 0x0a, 0xf4, 0x4d, 0x32, 0x47, 0x0c, 0x89, 0x89,
+  0x21, 0x55, 0xa2, 0x00, 0xa1, 0x5a, 0xe0, 0x49, 0xbf, 0x72, 0x61, 0x0c,
+  0x6b, 0xcf, 0x43, 0xf5, 0x34, 0x42, 0x9a, 0x33, 0x5d, 0x84, 0xb2, 0x84,
+  0x4a, 0x4b, 0x13, 0x92, 0xbe, 0x26, 0x9b, 0x11, 0x27, 0x28, 0xf4, 0xd0,
+  0x54, 0xd9, 0xdf, 0xac, 0xa9, 0x4f, 0x12, 0x3f, 0x38, 0x99, 0x6a, 0xf0,
+  0x72, 0x90, 0xb1, 0xf1, 0x62, 0xa8, 0x4c, 0xf0, 0xe1, 0xdf, 0x44, 0xbc,
+  0xea, 0x40, 0x2c, 0xd9, 0x70, 0x46, 0x17, 0xb3, 0xcf, 0x5a, 0x4d, 0x9f,
+  0xe3, 0x21, 0x92, 0x02, 0xed, 0x12, 0x59, 0x57, 0x1f, 0xb2, 0xde, 0x5d,
+  0x36, 0x7e, 0xf9, 0x25, 0xb9, 0x49, 0x3e, 0x82, 0xe1, 0x99, 0xd5, 0x23,
+  0x12, 0x36, 0x3b, 0x20, 0x7c, 0x4e, 0xbc, 0x73, 0xd6, 0x6d, 0xa4, 0xac,
+  0x56, 0x37, 0xeb, 0xe5, 0x10, 0x78, 0x4d, 0x5e, 0x95, 0xe5, 0xda, 0x16,
+  0x69, 0x56, 0xd8, 0x0f, 0x80, 0x79, 0xf1, 0xe0, 0x49, 0x0c, 0xda, 0x71,
+  0x19, 0x52, 0x2c, 0x71, 0xec, 0xd9, 0x15, 0xb9, 0x1b, 0x4b, 0x59, 0x45,
+  0x95, 0x60, 0x36, 0xf7, 0x34, 0xa6, 0xf6, 0xb2, 0xcf, 0x10, 0xfd, 0x28,
+  0xa7, 0xbf, 0x1b, 0x03, 0x4b, 0x1f, 0xb0, 0x61, 0xd0, 0x5f, 0x3f, 0xb7,
+  0xaf, 0xd3, 0x7f, 0x8c, 0xf0, 0x02, 0x67, 0xea, 0x9a, 0xd1, 0x98, 0xc3,
+  0xaf, 0xaf, 0xec, 0x70, 0x01, 0x5e, 0xad, 0x75, 0xb6, 0xd9, 0x67, 0x85,
+  0xed, 0xf3, 0x4d, 0x1c, 0x74, 0x45, 0x8e, 0xa0, 0x96, 0x06, 0xf6, 0x0c,
+  0x95, 0xd7, 0xe8, 0xee, 0x78, 0x42, 0x57, 0x71, 0xb5, 0x0d, 0xf4, 0x7e,
+  0x45, 0xc7, 0x49, 0x7d, 0x4b, 0xb4, 0xef, 0x3f, 0xf5, 0x6c, 0xef, 0x7f,
+  0xea, 0xb9, 0xfe, 0xff, 0xd4, 0x73, 0x23, 0xf8, 0xa9, 0xd7, 0x03, 0xad,
+  0x67, 0x10, 0x80, 0xfd, 0xe5, 0x8b, 0xbe, 0xc9, 0x1f, 0x75, 0xdf, 0xf4,
+  0x3e, 0xe9, 0x7d, 0xb1, 0xb7, 0xb9, 0x6e, 0xd2, 0x5c, 0xaa, 0x66, 0x7e,
+  0xe5, 0x11, 0x81, 0xf1, 0x04, 0x92, 0x0c, 0x91, 0x49, 0xd2, 0x59, 0x72,
+  0xb3, 0x82, 0xb2, 0x10, 0x81, 0xe7, 0xd5, 0x7b, 0x82, 0xa6, 0xdc, 0xd5,
+  0x0e, 0xf1, 0x58, 0xb1, 0x2d, 0xdb, 0x98, 0x2e, 0x84, 0xd6, 0x9d, 0x0b,
+  0x8a, 0x11, 0xda, 0xd7, 0x83, 0x03, 0xfd, 0x3f, 0xcc, 0x17, 0x2c, 0x0a,
+  0x48, 0x53, 0x4a, 0x52, 0x41, 0x08, 0x01, 0xfc, 0x58, 0x70, 0x00, 0x4c,
+  0xd4, 0x4e, 0x42, 0xf1, 0x93, 0x7f, 0x44, 0xf7, 0x44, 0x80, 0x8d, 0x9d,
+  0xe7, 0xa8, 0x19, 0x63, 0x86, 0x35, 0x63, 0x53, 0x67, 0x87, 0x2e, 0x41,
+  0x60, 0xd9, 0x50, 0xc9, 0xa5, 0x86, 0xad, 0x27, 0x56, 0x90, 0x54, 0x63,
+  0xe1, 0x89, 0x58, 0xb5, 0x33, 0x68, 0x63, 0x6c, 0x52, 0xa3, 0x55, 0xfd,
+  0xb2, 0x67, 0x2e, 0x95, 0xcf, 0xcd, 0x1d, 0x56, 0x19, 0x5d, 0xe8, 0x73,
+  0xda, 0x5b, 0x4b, 0xb3, 0x5a, 0xee, 0xa0, 0x7e, 0x1c, 0xcc, 0xef, 0x4d,
+  0xe7, 0x37, 0x7f, 0xc9, 0xce, 0xb0, 0x22, 0x6d, 0x4a, 0x65, 0x95, 0xea,
+  0xc6, 0xdc, 0x1e, 0x9d, 0x20, 0xb4, 0x9c, 0x5a, 0x76, 0x22, 0xcb, 0x99,
+  0xd4, 0x67, 0x5e, 0xc6, 0x58, 0x8f, 0x82, 0x81, 0xb8, 0xc3, 0xc9, 0x3a,
+  0xff, 0xcb, 0xb3, 0x6f, 0x3f, 0xd7, 0x06, 0x7e, 0xea, 0xfd, 0x30, 0xe0,
+  0x9f, 0x22, 0x17, 0xef, 0x20, 0x39, 0xfb, 0x96, 0x36, 0xf7, 0x2f, 0x13,
+  0x60, 0xeb, 0x3e, 0xf0, 0x25, 0xff, 0x05, 0x3b, 0x7b, 0x5d, 0xb3, 0x97,
+  0x5e, 0x28, 0xfc, 0x25, 0xaa, 0xf6, 0x21, 0x77, 0x00, 0x06, 0xdd, 0x62,
+  0x41, 0xd9, 0x00, 0x9a, 0x7d, 0xd6, 0x70, 0xf6, 0x19, 0x12, 0xf2, 0xc7,
+  0x25, 0x8c, 0xcf, 0x26, 0xa4, 0x2e, 0x05, 0x75, 0xe2, 0xdf, 0x65, 0x7f,
+  0xd1, 0x96, 0x32, 0xf6, 0x2f, 0xe2, 0x1d, 0x3a, 0xbd, 0x5c, 0x8d, 0x37,
+  0x9d, 0xb6, 0xf3, 0x90, 0xcc, 0x79, 0x38, 0x8e, 0xd0, 0x54, 0x3b, 0x9e,
+  0x0b, 0xfe, 0x1b, 0xee, 0x38, 0xd0, 0x79, 0x90, 0xae, 0x4e, 0xf5, 0x6e,
+  0xd2, 0x2a, 0xd3, 0x1a, 0x06, 0x52, 0x5d, 0x89, 0xab, 0xe8, 0x7c, 0x1e,
+  0xf3, 0x2a, 0x4b, 0xb0, 0x4b, 0x80, 0xa5, 0x57, 0xe5, 0x4c, 0x2b, 0xb3,
+  0x9b, 0x9d, 0xcf, 0x2b, 0x6c, 0x0b, 0x1a, 0xdd, 0x95, 0x04, 0x07, 0x9f,
+  0x8a, 0xd3, 0x5b, 0x3e, 0x1b, 0x53, 0x31, 0x25, 0x3a, 0x25, 0x21, 0x7c,
+  0xae, 0xb7, 0x25, 0xf4, 0x31, 0xd8, 0xfa, 0xa6, 0x23, 0xf3, 0x71, 0x06,
+  0x37, 0x86, 0x66, 0x57, 0x0d, 0xc4, 0xcf, 0x18, 0x71, 0x05, 0x74, 0x8f,
+  0x0d, 0x62, 0xe3, 0x92, 0x60, 0x45, 0x84, 0x22, 0xdf, 0x90, 0xda, 0xcb,
+  0x99, 0x2e, 0x45, 0x62, 0x2b, 0x0f, 0x40, 0xc3, 0x4d, 0xe3, 0x83, 0xb5,
+  0x85, 0xcb, 0x69, 0x86, 0xc2, 0xd3, 0x96, 0xfc, 0x51, 0xdc, 0x92, 0x5e,
+  0x7d, 0x73, 0x8c, 0x5e, 0xd6, 0x6b, 0x18, 0xbc, 0xf0, 0x83, 0xc0, 0x3e,
+  0x06, 0x7b, 0x07, 0x5e, 0x1d, 0x09, 0xfe, 0x59, 0xbc, 0x79, 0x9f, 0x63,
+  0x41, 0xe3, 0x8d, 0xb5, 0x4c, 0xff, 0x9a, 0xf6, 0xf7, 0x6d, 0xfb, 0x1b,
+  0x11, 0x5a, 0x03, 0x26, 0x1e, 0x88, 0x7f, 0xf6, 0xd2, 0x87, 0x24, 0x89,
+  0x2f, 0xce, 0xb3, 0x8a, 0x13, 0x36, 0x48, 0xd5, 0x22, 0xad, 0xfb, 0x2d,
+  0xe2, 0x83, 0xf0, 0x7b, 0xc8, 0x2f, 0x98, 0x32, 0xe0, 0x95, 0x47, 0x62,
+  0x26, 0xb2, 0x03, 0xcc, 0x90, 0x02, 0xa1, 0xbc, 0xb3, 0xca, 0x39, 0x51,
+  0xf2, 0x4d, 0x0f, 0x5c, 0xf9, 0x31, 0x98, 0x94, 0x6a, 0x3a, 0xb3, 0x7a,
+  0xec, 0x72, 0xe0, 0xc2, 0x54, 0xa5, 0x16, 0x13, 0x65, 0xf0, 0x29, 0xc8,
+  0x63, 0x61, 0xca, 0x84, 0xd2, 0x27, 0xc7, 0x61, 0x6b, 0x53, 0x4c, 0x74,
+  0xfa, 0x18, 0x15, 0xee, 0x02, 0xe2, 0x05, 0xec, 0x03, 0x94, 0xb6, 0xc7,
+  0x13, 0x30, 0x88, 0xe8, 0x1d, 0x07, 0x48, 0x0c, 0xb3, 0xa7, 0x82, 0x99,
+  0x38, 0x40, 0xc4, 0xa1, 0xb6, 0x08, 0xaa, 0x48, 0xb6, 0xd9, 0x37, 0x82,
+  0x6e, 0xa5, 0xde, 0x0c, 0x4b, 0x63, 0x52, 0xe1, 0xd8, 0x62, 0xa7, 0xd2,
+  0x64, 0xf3, 0xe5, 0xf6, 0xa6, 0x1d, 0xda, 0x1a, 0x1b, 0xb0, 0xb5, 0x69,
+  0x34, 0x9c, 0x65, 0xeb, 0xf1, 0xb1, 0x33, 0x6f, 0x8e, 0x3a, 0x16, 0xd9,
+  0x80, 0x57, 0x33, 0x4a, 0xa7, 0x54, 0x6b, 0xae, 0x3b, 0xca, 0xbe, 0xe3,
+  0x74, 0x32, 0x99, 0x02, 0x6f, 0xf2, 0x74, 0x66, 0x7a, 0x48, 0x79, 0x4d,
+  0xb7, 0x4a, 0x05, 0x57, 0x1f, 0x30, 0x61, 0x64, 0xcc, 0x86, 0xa5, 0x2e,
+  0x50, 0x54, 0x00, 0x1c, 0xd7, 0x62, 0x0f, 0xd5, 0x7e, 0xa5, 0xbe, 0xd5,
+  0xfa, 0xd9, 0xe6, 0xcb, 0x2d, 0xbe, 0xb1, 0x9c, 0x6b, 0xc6, 0xfb, 0xf6,
+  0x66, 0xf2, 0x53, 0x3c, 0x57, 0x2d, 0xe1, 0x77, 0x5d, 0x8f, 0x74, 0xcf,
+  0x3e, 0xf4, 0x46, 0xf2, 0x62, 0x5c, 0x4e, 0xef, 0xbf, 0x40, 0x0c, 0x43,
+  0x5e, 0x79, 0xb1, 0x83, 0x1f, 0x75, 0x94, 0xe6, 0x55, 0x0d, 0xa1, 0x15,
+  0xb3, 0x54, 0xf8, 0xf3, 0x4b, 0x7a, 0x1c, 0x46, 0x7b, 0xf3, 0xb1, 0xd9,
+  0x4c, 0x86, 0x43, 0x23, 0x8a, 0xea, 0x39, 0x4a, 0xa6, 0xac, 0xb9, 0x5a,
+  0x40, 0x7e, 0x24, 0x1b, 0xc1, 0x32, 0x52, 0x48, 0xc1, 0x24, 0x35, 0x5a,
+  0xd4, 0xa3, 0xc5, 0xbf, 0xae, 0x5e, 0x52, 0x05, 0x35, 0x85, 0x5e, 0x6c,
+  0x44, 0x38, 0x2d, 0xcc, 0xc3, 0x0a, 0x34, 0xf2, 0xd2, 0x39, 0x3f, 0x1d,
+  0xe7, 0xe2, 0xb5, 0x9d, 0x96, 0x2d, 0x22, 0x36, 0xce, 0x9a, 0x36, 0x97,
+  0x7c, 0x5c, 0x78, 0x4f, 0xca, 0x8a, 0x43, 0x0e, 0x10, 0x10, 0xd6, 0x8c,
+  0x91, 0xce, 0x0d, 0x8e, 0xe5, 0x8b, 0x2a, 0x4b, 0x8d, 0x9c, 0xf8, 0x84,
+  0xbe, 0x14, 0xe3, 0x1f, 0xe1, 0x84, 0x34, 0x36, 0xa5, 0x4c, 0x0f, 0x3f,
+  0x1d, 0xe0, 0x41, 0xaf, 0x82, 0x9f, 0x1e, 0x80, 0x36, 0x36, 0xa0, 0x2f,
+  0x2a, 0x62, 0x98, 0xf4, 0x9e, 0x17, 0x5c, 0x55, 0x83, 0xc6, 0x47, 0xc5,
+  0xa9, 0x9f, 0x3f, 0xe5, 0x11, 0xf2, 0x4c, 0x09, 0xbb, 0x51, 0xcb, 0xa9,
+  0xa7, 0xf7, 0x51, 0x15, 0x46, 0x95, 0xec, 0x18, 0x39, 0x6b, 0x90, 0xf4,
+  0x34, 0x2a, 0xd6, 0xc2, 0xd8, 0x40, 0xba, 0x58, 0x8d, 0x4e, 0x79, 0x8d,
+  0x22, 0xbc, 0xc9, 0x27, 0xcf, 0xbd, 0x5e, 0xaf, 0x3e, 0xa0, 0xec, 0xa2,
+  0xf1, 0x4e, 0x3c, 0x0e, 0xa1, 0x8c, 0x51, 0xc6, 0xe4, 0x06, 0xa1, 0x5b,
+  0x37, 0xe8, 0x17, 0xb9, 0x77, 0x98, 0xe2, 0x47, 0xc6, 0x68, 0xdd, 0x0c,
+  0x0f, 0x9d, 0x27, 0xff, 0x34, 0x7c, 0xae, 0xdb, 0xa7, 0xfb, 0xe1, 0xb5,
+  0xbb, 0xdb, 0xb3, 0x96, 0xf4, 0x7d, 0xee, 0x04, 0xef, 0xf0, 0x87, 0x37,
+  0x38, 0x39, 0xa6, 0xaf, 0x96, 0x15, 0x17, 0x8e, 0xe7, 0xc7, 0x58, 0x5f,
+  0xd0, 0x14, 0x04, 0x51, 0xd9, 0xdf, 0x1c, 0xbe, 0x7d, 0x77, 0x78, 0x3a,
+  0xfc, 0x75, 0x75, 0x81, 0xd6, 0xbe, 0xe6, 0xe5, 0x1c, 0x76, 0xe8, 0x34,
+  0x1e, 0x4e, 0x46, 0xa6, 0x9c, 0x0f, 0xda, 0x3f, 0x04, 0x2f, 0x88, 0xb3,
+  0x69, 0x30, 0x6e, 0x53, 0x82, 0xab, 0x1e, 0xee, 0x2f, 0xad, 0xa5, 0x48,
+  0x56, 0x4f, 0xdf, 0xa7, 0xd7, 0x7b, 0x82, 0x5b, 0xb5, 0x89, 0x9e, 0x11,
+  0xe9, 0xe9, 0x92, 0x53, 0x2d, 0x70, 0x47, 0xab, 0x89, 0xca, 0xd5, 0xd5,
+  0xf2, 0x5e, 0x94, 0x57, 0x57, 0x8e, 0xbc, 0xa2, 0x1b, 0x19, 0x3a, 0x3a,
+  0x5a, 0x9d, 0x31, 0xf7, 0x7b, 0xf2, 0xe4, 0x75, 0xf0, 0xcb, 0x98, 0x46,
+  0x27, 0xca, 0x07, 0x4d, 0xc9, 0xd9, 0xa4, 0x2f, 0xa4, 0x6f, 0xf1, 0x59,
+  0x35, 0x1d, 0xf4, 0x03, 0xa1, 0xaa, 0xd1, 0x52, 0x8f, 0xa8, 0x24, 0x1a,
+  0x26, 0xeb, 0xfc, 0x90, 0xaa, 0xc5, 0x6b, 0x2e, 0xa7, 0x04, 0xb4, 0xfb,
+  0x81, 0xed, 0xc5, 0x35, 0x6b, 0x49, 0x25, 0xd4, 0xd9, 0x50, 0x88, 0x91,
+  0x05, 0x03, 0x22, 0x66, 0x60, 0x04, 0xc4, 0xe5, 0x72, 0x6e, 0x0e, 0x85,
+  0x51, 0x70, 0xa7, 0x9b, 0xb5, 0x84, 0xf0, 0xba, 0x9b, 0x4b, 0x6b, 0x85,
+  0xeb, 0x5a, 0xd3, 0x0e, 0xa3, 0xb5, 0x1f, 0xa9, 0xa4, 0x4e, 0x5d, 0xc8,
+  0xd3, 0x23, 0x37, 0xec, 0xc7, 0x5d, 0x3d, 0xbd, 0xd1, 0xc9, 0xe5, 0xb1,
+  0x99, 0xbe, 0x77, 0x97, 0xdf, 0xf4, 0x24, 0x44, 0xda, 0x4d, 0x63, 0x07,
+  0x7d, 0x02, 0x55, 0xdd, 0xbb, 0xb5, 0xc9, 0x6e, 0x15, 0x7b, 0x4d, 0x8c,
+  0x7d, 0x10, 0x93, 0xd9, 0xee, 0xa3, 0xc3, 0x35, 0xab, 0xf4, 0x6c, 0xf8,
+  0xac, 0xbb, 0x4a, 0xab, 0x89, 0x4a, 0x99, 0xba, 0x32, 0xd8, 0xee, 0xc2,
+  0x87, 0x49, 0xb8, 0x9b, 0x1d, 0x47, 0x65, 0x8f, 0xe0, 0x0c, 0x88, 0x2a,
+  0x52, 0xce, 0x64, 0x0d, 0xee, 0x02, 0x25, 0xe6, 0xf2, 0xe2, 0xa9, 0x60,
+  0xed, 0xb4, 0xcc, 0x1d, 0xe2, 0xc4, 0xe6, 0x30, 0x9a, 0x59, 0xb1, 0xb4,
+  0x9a, 0xda, 0xac, 0xae, 0x50, 0x19, 0x54, 0xa4, 0x18, 0x15, 0xc8, 0x30,
+  0x5b, 0x40, 0xf9, 0xf1, 0x5b, 0xc9, 0x76, 0xae, 0xf8, 0xb0, 0xba, 0x8a,
+  0x5d, 0xd6, 0x5e, 0x9c, 0x46, 0x15, 0xfe, 0x47, 0xf0, 0xe6, 0x5b, 0x3e,
+  0xd0, 0xb5, 0xd8, 0xb9, 0x38, 0xf3, 0x27, 0xcd, 0xab, 0x20, 0x0d, 0x5e,
+  0xf0, 0x9f, 0xf1, 0xfd, 0x8e, 0xcb, 0xb5, 0x2a, 0x67, 0xec, 0x31, 0x94,
+  0x37, 0x18, 0x02, 0xc8, 0x38, 0x7b, 0xf0, 0xb0, 0xc0, 0x01, 0x8e, 0xd0,
+  0x19, 0xcc, 0x11, 0x54, 0x93, 0x0d, 0x8b, 0xa0, 0x6c, 0x8d, 0xb6, 0x65,
+  0x0a, 0x19, 0x35, 0x2b, 0xad, 0x45, 0x12, 0x28, 0x3c, 0x9e, 0x32, 0xd1,
+  0x26, 0x63, 0x44, 0x19, 0xde, 0xe9, 0x0d, 0x0d, 0x24, 0x08, 0xe3, 0xc9,
+  0xdd, 0x34, 0xae, 0x6d, 0xb1, 0xaf, 0x02, 0xf0, 0x23, 0x40, 0xbb, 0x39,
+  0x5d, 0xe3, 0xe8, 0xfb, 0x57, 0x5e, 0xe9, 0x03, 0x45, 0x38, 0xf1, 0x7e,
+  0x11, 0xed, 0x73, 0x15, 0xb1, 0x52, 0xe6, 0x60, 0x7a, 0x43, 0x04, 0xe3,
+  0xa6, 0x59, 0xb6, 0xb0, 0xa4, 0xb6, 0x28, 0x4d, 0x49, 0xcb, 0x4e, 0xc1,
+  0x37, 0x21, 0x14, 0x46, 0x71, 0x9f, 0x15, 0xbd, 0x13, 0xd1, 0x61, 0xa3,
+  0x00, 0xf4, 0xff, 0x54, 0xcb, 0x85, 0xc2, 0x7f, 0x7b, 0x9f, 0x3c, 0xf9,
+  0xd4, 0xdc, 0xbf, 0xf7, 0x60, 0x99, 0x75, 0x53, 0xc6, 0x2c, 0x90, 0xab,
+  0x29, 0xb3, 0xc4, 0x84, 0x51, 0x70, 0xa8, 0x64, 0x43, 0x27, 0x35, 0xd9,
+  0x0c, 0xf0, 0x47, 0x49, 0x6e, 0x62, 0x48, 0x26, 0x61, 0x26, 0x51, 0x26,
+  0x4c, 0xe0, 0x5a, 0x98, 0x27, 0x86, 0x16, 0x0d, 0xbd, 0x0d, 0x6c, 0x54,
+  0x38, 0xd4, 0xb5, 0x31, 0x22, 0xe5, 0xe2, 0xf8, 0xf2, 0xc2, 0xfc, 0x31,
+  0xba, 0x3c, 0xbb, 0x58, 0xc1, 0x73, 0xd6, 0x70, 0x96, 0x3d, 0x4d, 0x9a,
+  0xc2, 0x1c, 0x30, 0xcd, 0x6d, 0x02, 0x24, 0xe0, 0x68, 0x59, 0xec, 0xd4,
+  0x51, 0xce, 0x1c, 0x8f, 0x3a, 0xa7, 0x1e, 0xb6, 0x06, 0x7a, 0x65, 0xee,
+  0x87, 0xb5, 0x03, 0xe3, 0x35, 0x5f, 0xbf, 0x43, 0x30, 0x60, 0xda, 0x8c,
+  0x34, 0x62, 0x2b, 0xe8, 0xd1, 0x5b, 0x63, 0x9e, 0x51, 0x1c, 0xcd, 0x11,
+  0x18, 0x6b, 0xbd, 0xd0, 0x15, 0xfc, 0x76, 0x0c, 0xea, 0xac, 0x39, 0x4d,
+  0x5d, 0xfc, 0x54, 0xe4, 0x01, 0xe8, 0x69, 0x26, 0x6f, 0x2f, 0xd9, 0x82,
+  0xbf, 0x58, 0x74, 0x8f, 0x07, 0xf6, 0xaf, 0xd1, 0x77, 0xb6, 0xdd, 0x80,
+  0xeb, 0x72, 0x9e, 0xb1, 0x4b, 0x1f, 0x4e, 0x1f, 0x2b, 0x9c, 0x6a, 0xa9,
+  0x44, 0x93, 0x73, 0x4a, 0x75, 0x98, 0xce, 0x6e, 0xd9, 0x78, 0x68, 0x95,
+  0x37, 0x6d, 0x42, 0xb0, 0xd6, 0xc2, 0xe6, 0x75, 0xc9, 0x8c, 0x4d, 0xda,
+  0x80, 0xe6, 0x68, 0x53, 0x7b, 0xe5, 0xd1, 0xf4, 0xb4, 0x85, 0xf7, 0x5e,
+  0x57, 0xc8, 0x50, 0x4e, 0x75, 0x5c, 0xb2, 0x10, 0xc2, 0xc1, 0xe6, 0xc6,
+  0x02, 0xa0, 0xa3, 0xd8, 0x0c, 0xe8, 0x12, 0x7e, 0x45, 0xb7, 0x73, 0x79,
+  0x8a, 0xd7, 0x36, 0x10, 0x05, 0x10, 0x03, 0x33, 0xb7, 0xb7, 0x65, 0xc9,
+  0x39, 0xc1, 0x79, 0xd9, 0x15, 0xba, 0x2d, 0x9d, 0x2d, 0x14, 0xb3, 0xaa,
+  0x9a, 0xf9, 0x25, 0xae, 0xba, 0xc9, 0xe4, 0x8b, 0xc7, 0x57, 0x12, 0x91,
+  0xcf, 0x74, 0x34, 0x18, 0x58, 0x1d, 0xce, 0xa5, 0x80, 0xa2, 0xa5, 0x51,
+  0x0a, 0x8c, 0xe4, 0x5d, 0x21, 0xc4, 0x0f, 0x85, 0xb1, 0x20, 0x10, 0x37,
+  0x9f, 0xda, 0x49, 0x23, 0x46, 0x14, 0x82, 0xfb, 0xf0, 0xa5, 0x35, 0x2d,
+  0xa1, 0xb2, 0x33, 0x43, 0x6a, 0xc8, 0x9f, 0x05, 0x9f, 0x31, 0xa2, 0xd0,
+  0x7a, 0xd3, 0x48, 0x7b, 0xce, 0xa2, 0x9a, 0x34, 0xdd, 0x91, 0x22, 0x49,
+  0x3b, 0x18, 0xe8, 0xb9, 0xbf, 0x68, 0x2c, 0xd2, 0x60, 0xe2, 0x38, 0x59,
+  0xd0, 0x70, 0xae, 0x34, 0x27, 0x44, 0xab, 0x17, 0x40, 0xb2, 0xd2, 0x8b,
+  0x68, 0xae, 0x0d, 0x67, 0xa4, 0x6b, 0x7d, 0xe2, 0x56, 0xa6, 0xb7, 0xaa,
+  0x81, 0xc3, 0x35, 0x3c, 0x41, 0x7e, 0x62, 0x78, 0x6b, 0x4b, 0xee, 0xb5,
+  0xb4, 0xbe, 0xf6, 0xe8, 0x56, 0x26, 0x1d, 0x62, 0x83, 0x5e, 0xd0, 0x92,
+  0x29, 0xb9, 0x9b, 0xee, 0x2d, 0xae, 0x0e, 0x6f, 0x0e, 0xfc, 0x0e, 0xe5,
+  0x38, 0x10, 0xfd, 0x95, 0x31, 0x1e, 0xcb, 0x19, 0x0a, 0x3b, 0xa8, 0xea,
+  0x16, 0xab, 0x90, 0x09, 0x15, 0x8c, 0x29, 0x34, 0x4c, 0xe3, 0xed, 0x8a,
+  0x87, 0x5e, 0xe9, 0x20, 0xba, 0x4d, 0xbd, 0xac, 0xef, 0x61, 0x0c, 0x49,
+  0xcd, 0x48, 0x02, 0x20, 0xe5, 0xda, 0xea, 0x98, 0x16, 0x8a, 0x53, 0x5a,
+  0x79, 0xac, 0x2b, 0x54, 0x3e, 0xa0, 0xb7, 0x57, 0x24, 0x67, 0x29, 0xa5,
+  0x3f, 0xd8, 0x5d, 0xcc, 0xac, 0xf4, 0x19, 0x55, 0xd0, 0x3e, 0x99, 0xb0,
+  0x1c, 0xda, 0x5f, 0xab, 0xb3, 0x66, 0xb9, 0x08, 0xef, 0x79, 0x97, 0xf8,
+  0x66, 0x5b, 0xe4, 0xea, 0xce, 0x8d, 0xdf, 0xc5, 0xa6, 0x34, 0x77, 0x9b,
+  0x9d, 0x7e, 0x9f, 0x97, 0x39, 0x30, 0xcf, 0x49, 0x13, 0x08, 0x6e, 0xf7,
+  0x55, 0x49, 0xc8, 0xfa, 0xeb, 0x21, 0x49, 0x56, 0xa3, 0x5e, 0xec, 0xf6,
+  0x24, 0xcf, 0x51, 0x92, 0x7e, 0x18, 0x3a, 0x60, 0xdf, 0x36, 0xf3, 0xe2,
+  0xf5, 0x37, 0x3c, 0x33, 0x9a, 0xcd, 0x20, 0x59, 0x68, 0xb4, 0x3a, 0x5b,
+  0x54, 0x1c, 0x18, 0xe7, 0x77, 0x7b, 0x63, 0xe5, 0xd0, 0x57, 0xf7, 0xaa,
+  0xb7, 0xf7, 0xd9, 0xfe, 0x70, 0xef, 0xf9, 0xa7, 0xc3, 0x3d, 0x94, 0x15,
+  0xf4, 0x2a, 0x91, 0x33, 0xad, 0x2f, 0x55, 0xbe, 0xf3, 0xda, 0x89, 0xd4,
+  0x57, 0x4c, 0x56, 0x73, 0x63, 0xe2, 0x03, 0xf3, 0xfb, 0x21, 0x3d, 0x36,
+  0xe4, 0x6a, 0x0a, 0xc1, 0x27, 0xe6, 0x46, 0xa3, 0xa1, 0xa8, 0x7e, 0xe8,
+  0x9c, 0x54, 0x2c, 0x0a, 0xef, 0xc4, 0x45, 0x4e, 0x9b, 0x48, 0xe9, 0xea,
+  0xbc, 0x59, 0xe2, 0xb0, 0x19, 0xa8, 0xab, 0x98, 0xd8, 0x1e, 0x67, 0x33,
+  0xde, 0x21, 0x15, 0xe8, 0x13, 0x51, 0x22, 0x9d, 0x4c, 0xb7, 0xdf, 0x0f,
+  0x84, 0xe6, 0x2f, 0xb6, 0xf9, 0x88, 0x7f, 0xc1, 0x1e, 0xb9, 0x2e, 0xc7,
+  0x0e, 0xf8, 0x59, 0xba, 0x14, 0x1f, 0xc2, 0xd8, 0xc0, 0x0f, 0xb6, 0x72,
+  0x2f, 0x10, 0xff, 0xf6, 0xae, 0x18, 0x30, 0x97, 0xb8, 0x2c, 0x0e, 0x95,
+  0x9c, 0xb6, 0xe5, 0xb1, 0xf2, 0x61, 0x74, 0xb8, 0x58, 0x2c, 0x47, 0x0a,
+  0x8b, 0x68, 0x6d, 0x8e, 0xde, 0xf9, 0xcb, 0x5f, 0x9c, 0x3c, 0xe2, 0x2a,
+  0xb7, 0xe0, 0x70, 0x7f, 0x06, 0xce, 0x43, 0x8e, 0x6d, 0x31, 0xc3, 0x76,
+  0xd2, 0x3b, 0xf8, 0x11, 0x5e, 0xe0, 0x9f, 0x07, 0x3f, 0x9a, 0x7f, 0xff,
+  0xdc, 0xf3, 0x48, 0x2f, 0x99, 0x57, 0x47, 0x01, 0x32, 0x1b, 0xed, 0xa3,
+  0xdc, 0x4f, 0xda, 0x65, 0x02, 0xa1, 0x19, 0x5c, 0x1e, 0x9d, 0xf3, 0x61,
+  0xac, 0x38, 0xc6, 0x8d, 0xdd, 0x4c, 0x72, 0x08, 0x6a, 0x3d, 0x89, 0x70,
+  0x70, 0xa9, 0x2f, 0x3c, 0x10, 0x04, 0x6d, 0x99, 0xd4, 0x7b, 0xa9, 0xaf,
+  0x68, 0x0d, 0xd2, 0x19, 0x2b, 0xc6, 0x93, 0x18, 0x15, 0xf7, 0x9a, 0xdc,
+  0x28, 0x92, 0x40, 0x4b, 0x6e, 0x40, 0xab, 0x4e, 0xcb, 0xcf, 0xb4, 0x39,
+  0x62, 0xe9, 0xa9, 0xc1, 0xab, 0x71, 0x67, 0xba, 0xd6, 0x17, 0x42, 0x49,
+  0x06, 0xd7, 0x37, 0xc2, 0x89, 0x66, 0xe6, 0xc3, 0xcc, 0x98, 0x0a, 0xdd,
+  0x2a, 0xaf, 0x3f, 0xd0, 0x18, 0x25, 0x53, 0x84, 0xc1, 0x16, 0x1b, 0x9e,
+  0xce, 0x8d, 0xbe, 0x51, 0xc8, 0x4b, 0x88, 0x27, 0x6c, 0xf6, 0x97, 0x37,
+  0xc5, 0xee, 0x92, 0xd0, 0xf5, 0xd7, 0xec, 0xea, 0x28, 0x79, 0x8e, 0x3c,
+  0x56, 0x65, 0x8f, 0xe0, 0x74, 0x62, 0xb4, 0x53, 0x72, 0x6e, 0xd4, 0x5d,
+  0xbb, 0x47, 0x3c, 0x82, 0x15, 0xf3, 0x0e, 0x76, 0x0d, 0x5d, 0x82, 0xdb,
+  0xdd, 0xcb, 0x8b, 0x4a, 0x14, 0x90, 0x73, 0x98, 0x49, 0x5e, 0x2c, 0x4b,
+  0x11, 0xb9, 0xe3, 0x48, 0x37, 0x98, 0x56, 0xa6, 0x1b, 0xe0, 0x7d, 0x45,
+  0x7a, 0x30, 0x1f, 0x11, 0x0a, 0xef, 0xaa, 0x6a, 0xb7, 0x11, 0x35, 0x19,
+  0x70, 0xe2, 0x9c, 0x4e, 0x3a, 0x63, 0x3f, 0x7a, 0xad, 0x93, 0x4e, 0x7f,
+  0x1a, 0xa1, 0xad, 0x65, 0x75, 0xee, 0x0a, 0xd4, 0xac, 0x8c, 0x94, 0x8c,
+  0x42, 0xf7, 0xe7, 0x31, 0xd2, 0x4b, 0xef, 0x6e, 0xdd, 0xdf, 0x0d, 0x3d,
+  0x2a, 0x54, 0x89, 0x13, 0x93, 0x3c, 0xc8, 0x17, 0x0f, 0x4f, 0xa0, 0x92,
+  0xf5, 0xd0, 0x5a, 0xb6, 0x44, 0x8c, 0xbd, 0x68, 0xea, 0xe5, 0xf5, 0x35,
+  0xd2, 0xf2, 0x83, 0x2e, 0x72, 0xda, 0x9b, 0xe0, 0xce, 0x85, 0x24, 0xdc,
+  0xc8, 0x73, 0xf4, 0x5c, 0x67, 0xc3, 0xe5, 0xd6, 0x89, 0xe4, 0xe1, 0xb6,
+  0x63, 0x40, 0x24, 0x5f, 0xdd, 0x4c, 0x4e, 0xf4, 0x9c, 0xfb, 0xe9, 0x42,
+  0x55, 0x36, 0x50, 0xf1, 0x10, 0x08, 0xc5, 0x00, 0x18, 0xaa, 0xc2, 0x11,
+  0x4e, 0x87, 0xd5, 0x62, 0x70, 0xad, 0x93, 0x90, 0x5c, 0x6d, 0x54, 0x22,
+  0x81, 0x39, 0x41, 0xf2, 0x2b, 0x21, 0xe3, 0x62, 0x36, 0xa5, 0xca, 0xb2,
+  0xd3, 0xb0, 0x82, 0x29, 0xa2, 0xa9, 0x7b, 0x7d, 0x5e, 0x61, 0x42, 0xd6,
+  0x39, 0x08, 0x9c, 0x54, 0xf4, 0xd5, 0xa6, 0xa7, 0xc3, 0xfd, 0x60, 0x69,
+  0xeb, 0xd9, 0x60, 0x32, 0x99, 0x0c, 0xa0, 0x10, 0xbc, 0x60, 0x2d, 0x65,
+  0x47, 0xb4, 0x84, 0x15, 0xce, 0x83, 0x51, 0x26, 0x33, 0x7e, 0x74, 0x74,
+  0x24, 0x0a, 0xcd, 0xe5, 0x4d, 0x47, 0xb5, 0xb0, 0xc4, 0x31, 0xa2, 0x5a,
+  0xc5, 0x40, 0x7c, 0xf5, 0xcd, 0xb2, 0x99, 0xa2, 0x40, 0x25, 0x09, 0x0d,
+  0x95, 0xc2, 0x36, 0xd5, 0xb2, 0xc3, 0xef, 0x47, 0xe5, 0x82, 0xfb, 0x0e,
+  0xdc, 0x15, 0x42, 0xe2, 0xaa, 0x6c, 0xc1, 0x75, 0x05, 0xf0, 0xa2, 0xb4,
+  0xdd, 0xad, 0x80, 0xc7, 0x5d, 0xf5, 0x29, 0x78, 0xb4, 0x83, 0x31, 0xc4,
+  0xa2, 0x6d, 0x05, 0x9f, 0x4d, 0x73, 0x41, 0x55, 0xa6, 0xf2, 0xad, 0x6e,
+  0xdb, 0x0f, 0xac, 0x87, 0x4c, 0x75, 0x7b, 0x49, 0x9e, 0xaf, 0x5c, 0x92,
+  0xe8, 0xe4, 0x93, 0x79, 0x45, 0xd3, 0xbe, 0x75, 0x04, 0x6e, 0xc0, 0x23,
+  0x39, 0x12, 0x47, 0x37, 0x84, 0xdb, 0x9a, 0xd1, 0xe2, 0x98, 0x2e, 0xd7,
+  0x2c, 0x06, 0xe4, 0x56, 0x19, 0x8d, 0x4e, 0x77, 0x2e, 0x4f, 0x47, 0x01,
+  0x64, 0xfa, 0x9e, 0x7c, 0xc7, 0xf0, 0x11, 0xb7, 0x7d, 0x9f, 0x3c, 0x45,
+  0x20, 0x5c, 0x2d, 0xaf, 0xda, 0x3b, 0x9c, 0xbf, 0x12, 0xe5, 0x5c, 0x58,
+  0x16, 0x9a, 0x4b, 0x61, 0xaf, 0xf1, 0x22, 0x2b, 0x90, 0x8b, 0x4c, 0xb7,
+  0x39, 0x4e, 0x00, 0x50, 0x85, 0x75, 0xf2, 0xf6, 0xf0, 0x92, 0xf2, 0x23,
+  0x1a, 0x81, 0x77, 0x90, 0x2f, 0x28, 0x00, 0x74, 0x0b, 0xbf, 0xa3, 0x65,
+  0xc4, 0x4b, 0x27, 0xae, 0xc6, 0x80, 0x6a, 0xed, 0xbc, 0x7c, 0xb5, 0x6e,
+  0xbc, 0x75, 0xd3, 0x6f, 0xa6, 0x54, 0xee, 0x87, 0xee, 0x9e, 0xef, 0xae,
+  0xc6, 0x5e, 0x74, 0x35, 0x78, 0x02, 0xe2, 0xc7, 0xe1, 0x42, 0x84, 0xb9,
+  0x4e, 0xb4, 0x06, 0xd5, 0xa4, 0xfb, 0xb3, 0xf2, 0x3a, 0x27, 0x97, 0x20,
+  0xd6, 0x0b, 0xfb, 0x5a, 0x6b, 0xf3, 0x76, 0x65, 0x30, 0xcf, 0x4e, 0xcd,
+  0xb9, 0x1c, 0xed, 0xc4, 0x1c, 0x3e, 0x22, 0x74, 0x53, 0xd8, 0x39, 0xd5,
+  0x98, 0xb3, 0xcd, 0xa2, 0x0b, 0x93, 0xd4, 0xc0, 0x81, 0x95, 0x4f, 0x8c,
+  0xad, 0x30, 0xa1, 0xbc, 0x07, 0x64, 0x94, 0xd5, 0x4a, 0x76, 0xc7, 0x61,
+  0xaf, 0xbc, 0x45, 0xaf, 0xa5, 0xae, 0xd2, 0x7a, 0xb9, 0x88, 0x66, 0x91,
+  0xc8, 0x08, 0xd7, 0x3a, 0xe4, 0x9f, 0xb7, 0xae, 0x8f, 0xaf, 0xc9, 0x34,
+  0xbb, 0x0e, 0xae, 0x5d, 0x4b, 0x66, 0x10, 0x61, 0xf0, 0x82, 0xb6, 0x8a,
+  0x2c, 0x71, 0x09, 0xaa, 0xfb, 0x34, 0xc9, 0x64, 0x6a, 0x0d, 0xa6, 0xfd,
+  0x28, 0xc7, 0x75, 0xbf, 0x5b, 0xd1, 0x86, 0xd9, 0xc5, 0xda, 0xd4, 0xb2,
+  0x2d, 0x6a, 0x12, 0x05, 0x32, 0x77, 0x9a, 0xfb, 0xfa, 0xd8, 0x51, 0x92,
+  0x77, 0xf8, 0x4b, 0x5a, 0x74, 0xe5, 0x0c, 0xc3, 0xa1, 0x80, 0xd3, 0x1d,
+  0x15, 0xe3, 0xbb, 0x5b, 0x61, 0xed, 0xb0, 0x3e, 0x7b, 0xe9, 0x18, 0x8e,
+  0xf9, 0x7c, 0x28, 0x0d, 0xbc, 0x8a, 0xac, 0x77, 0x17, 0xa7, 0x36, 0x2c,
+  0xff, 0xef, 0x9b, 0xae, 0xe8, 0xc6, 0x30, 0xe2, 0x90, 0xd0, 0xdb, 0x21,
+  0x5a, 0x06, 0x92, 0xa2, 0x4d, 0x12, 0x6e, 0xea, 0xbb, 0x4e, 0xdb, 0x6f,
+  0xc7, 0xf9, 0x7a, 0x1f, 0xe8, 0xd1, 0x37, 0xc7, 0x87, 0xaf, 0x6c, 0x3e,
+  0xfa, 0xbf, 0x82, 0x25, 0xd4, 0x39, 0x38, 0xc7, 0x19, 0x73, 0xab, 0x2f,
+  0xd5, 0x67, 0x82, 0xf5, 0xd1, 0xad, 0x8a, 0xdd, 0x62, 0x54, 0xb6, 0x3a,
+  0xe3, 0x33, 0xb2, 0x92, 0x62, 0x7c, 0xa5, 0x93, 0xc4, 0x47, 0x1d, 0x88,
+  0xf3, 0x9a, 0x94, 0x66, 0x4e, 0xcf, 0xf1, 0xb6, 0xf2, 0x35, 0xb6, 0xf2,
+  0xac, 0x1c, 0x97, 0x57, 0x57, 0x6b, 0xee, 0x77, 0x26, 0x7a, 0x43, 0x1a,
+  0x0d, 0x6f, 0x99, 0x1e, 0x4d, 0x23, 0xbd, 0x37, 0xa6, 0xde, 0x9b, 0x45,
+  0x35, 0x87, 0xad, 0x27, 0x30, 0x2c, 0xa9, 0x8f, 0x1c, 0x5c, 0x3d, 0x7e,
+  0x76, 0xb3, 0x1a, 0x10, 0x6a, 0xef, 0x21, 0xc1, 0x9b, 0x3d, 0x33, 0x0a,
+  0x10, 0xb2, 0x74, 0xd9, 0x75, 0xf2, 0x9f, 0xff, 0xf5, 0xe3, 0xcf, 0x11,
+  0xce, 0x70, 0xf2, 0xfd, 0xdd, 0x70, 0x72, 0x9a, 0x79, 0x7a, 0x2e, 0xf4,
+  0x1f, 0x96, 0xd9, 0xd9, 0x95, 0x29, 0x27, 0x0d, 0x2c, 0x9b, 0x5d, 0x0d,
+  0x3d, 0xe2, 0x86, 0xf0, 0x62, 0x24, 0x85, 0x49, 0x3f, 0x88, 0x92, 0x45,
+  0x94, 0x4f, 0xcc, 0x39, 0xa0, 0xc4, 0xc2, 0x8b, 0xda, 0x1b, 0x2e, 0x11,
+  0xc1, 0x72, 0x74, 0xf2, 0x4a, 0x04, 0xf0, 0x69, 0x57, 0x1f, 0xc3, 0x8f,
+  0x9f, 0xf3, 0x06, 0x3c, 0xb1, 0x5e, 0x4f, 0x6f, 0x25, 0x6c, 0x34, 0x35,
+  0x9a, 0x55, 0x44, 0x42, 0xf7, 0xf5, 0xc9, 0xe9, 0xf1, 0x76, 0xf2, 0x3a,
+  0x03, 0xe5, 0x9e, 0x47, 0x0a, 0x43, 0x5b, 0xf0, 0x0f, 0x38, 0xf2, 0x96,
+  0xaa, 0x47, 0xd2, 0x9e, 0xa2, 0xa5, 0x1d, 0xc5, 0x40, 0xc4, 0xe6, 0x67,
+  0x27, 0x03, 0x96, 0x86, 0xb3, 0x97, 0x4b, 0xa4, 0x5c, 0x28, 0xbe, 0x41,
+  0x5d, 0xef, 0x82, 0xa8, 0x22, 0x78, 0x71, 0x10, 0x87, 0xe2, 0xe4, 0xd5,
+  0xa1, 0x47, 0xe5, 0x52, 0xfa, 0xd1, 0x2d, 0xea, 0xb4, 0xc2, 0xef, 0x24,
+  0x94, 0xc1, 0x55, 0x94, 0xeb, 0x24, 0x9a, 0xba, 0x4e, 0xa9, 0xbb, 0x84,
+  0x4c, 0x07, 0x20, 0x8f, 0x8c, 0x68, 0x2e, 0x61, 0x29, 0xd7, 0x30, 0x98,
+  0x2d, 0x68, 0xbc, 0xde, 0xc4, 0x7d, 0xa3, 0x13, 0x47, 0x11, 0x51, 0xfe,
+  0x73, 0xe7, 0xcb, 0x28, 0xab, 0x8a, 0x92, 0x24, 0xa3, 0x90, 0x97, 0xbc,
+  0x61, 0x46, 0xac, 0xa5, 0x1d, 0x65, 0xd3, 0xa9, 0x20, 0x84, 0x46, 0xae,
+  0xc8, 0xae, 0x88, 0x40, 0xe5, 0x82, 0xdf, 0xa2, 0x80, 0xfd, 0x55, 0xd8,
+  0xf8, 0x75, 0x3f, 0x53, 0x56, 0x1b, 0xdb, 0x94, 0x34, 0x6b, 0x5c, 0x3a,
+  0xcc, 0xe2, 0xdd, 0x92, 0x58, 0xe1, 0x0b, 0xc5, 0xf8, 0xe2, 0xf4, 0xf0,
+  0xe9, 0x26, 0xe4, 0x68, 0xda, 0xc6, 0x8e, 0xf2, 0x63, 0x37, 0x92, 0x93,
+  0x01, 0xdd, 0x9e, 0x09, 0x8f, 0xeb, 0xa8, 0x37, 0x0a, 0x4f, 0x59, 0xaf,
+  0x33, 0x6a, 0x67, 0xb1, 0x9d, 0xcd, 0x52, 0x7d, 0x49, 0x02, 0x86, 0xbe,
+  0x58, 0x31, 0x02, 0xad, 0x62, 0x16, 0xa9, 0xc8, 0xe9, 0x95, 0xaf, 0xfb,
+  0xde, 0x8c, 0xee, 0x2d, 0xe2, 0x7f, 0xa6, 0xad, 0x1b, 0x85, 0xe2, 0xcb,
+  0xcc, 0x1d, 0x64, 0x1c, 0xca, 0x9b, 0x36, 0x55, 0x3e, 0xf9, 0x90, 0x23,
+  0xbd, 0x60, 0x09, 0xf1, 0x92, 0x16, 0x6a, 0xcd, 0x70, 0x37, 0x2d, 0x83,
+  0xa8, 0xd9, 0x6e, 0x43, 0x00, 0x6b, 0xe3, 0xd2, 0x90, 0x13, 0x28, 0x48,
+  0x8d, 0x25, 0x66, 0x32, 0xed, 0xcf, 0x0c, 0x80, 0x77, 0x7b, 0x5a, 0x54,
+  0x70, 0x50, 0xd6, 0x03, 0x64, 0x57, 0x84, 0x2d, 0x31, 0x43, 0x15, 0x38,
+  0x98, 0xa1, 0x77, 0xc2, 0x9d, 0x42, 0xc5, 0x8b, 0x21, 0xaa, 0x87, 0x46,
+  0x37, 0x9a, 0x13, 0x36, 0x15, 0x70, 0x2f, 0x19, 0xb2, 0x4c, 0x8f, 0x11,
+  0x37, 0xd7, 0xf9, 0x6d, 0x2c, 0x00, 0x48, 0xfe, 0x07, 0xe9, 0xd8, 0x5c,
+  0x72, 0x79, 0xa5, 0x2e, 0x98, 0xc2, 0xdf, 0x6c, 0xb4, 0x85, 0x1d, 0x26,
+  0x44, 0x70, 0x24, 0x33, 0x1b, 0x9c, 0xe0, 0x19, 0x49, 0x50, 0x62, 0x2a,
+  0x29, 0x0e, 0xcc, 0xf6, 0x4f, 0x7a, 0xdf, 0x94, 0x75, 0x73, 0xd0, 0xb3,
+  0x5c, 0x9d, 0xb0, 0xf5, 0xa1, 0xe2, 0xb6, 0x76, 0x8e, 0xd4, 0xb1, 0x1b,
+  0x44, 0xab, 0x4b, 0xc8, 0x4d, 0x62, 0x04, 0x9b, 0x3c, 0xad, 0xd0, 0xef,
+  0x10, 0x5e, 0x67, 0xa1, 0xd8, 0x7d, 0xca, 0xdb, 0xbe, 0x09, 0xb9, 0x48,
+  0xa9, 0x4b, 0x3f, 0x0c, 0x8e, 0xf0, 0xf1, 0xc1, 0x37, 0x68, 0xee, 0xf3,
+  0x9e, 0x75, 0x42, 0x74, 0x7f, 0x75, 0x10, 0x56, 0xd0, 0x76, 0xce, 0x79,
+  0xbe, 0x08, 0x97, 0x8a, 0x0e, 0x46, 0x8c, 0x53, 0x3a, 0x28, 0xb5, 0x81,
+  0xa7, 0xd3, 0x1d, 0x5d, 0x70, 0x2e, 0x22, 0x1e, 0x96, 0x53, 0xb2, 0xd1,
+  0xb0, 0x45, 0x45, 0xb1, 0x2d, 0x23, 0x99, 0xa7, 0x83, 0xf2, 0x6a, 0x00,
+  0xa4, 0xde, 0x3c, 0xad, 0x3e, 0x50, 0x9c, 0xdc, 0x3b, 0x75, 0xc8, 0x79,
+  0x06, 0x23, 0xe5, 0x74, 0x1a, 0xbb, 0x2a, 0x90, 0xe3, 0x83, 0x18, 0xab,
+  0x6c, 0x7c, 0x85, 0xfc, 0xf2, 0x42, 0x1e, 0x88, 0xa7, 0x08, 0xaf, 0xdb,
+  0x4a, 0x06, 0x44, 0x37, 0xb2, 0xb6, 0xf0, 0x41, 0x9f, 0x6f, 0x13, 0x8c,
+  0x1a, 0x3a, 0xc5, 0x9c, 0xdd, 0x0b, 0xf0, 0x89, 0x2c, 0x17, 0xd0, 0x7c,
+  0x89, 0x1b, 0x2c, 0xb0, 0x07, 0x14, 0xae, 0x0c, 0xc5, 0xe9, 0x93, 0xe1,
+  0xb3, 0x67, 0xc3, 0xdd, 0x7e, 0x10, 0x43, 0x6a, 0xa0, 0x7e, 0x16, 0x2e,
+  0x80, 0x6d, 0x1e, 0xfe, 0x72, 0x55, 0x46, 0x17, 0xd7, 0xa7, 0xee, 0xdb,
+  0xcb, 0x21, 0x03, 0xbc, 0xcd, 0x21, 0x70, 0x5d, 0xb8, 0x99, 0x2b, 0xb6,
+  0xb2, 0xd8, 0xe4, 0xf4, 0xb5, 0x18, 0x9d, 0x9a, 0x80, 0x09, 0xbe, 0x1c,
+  0x84, 0x15, 0xc5, 0xa5, 0xa6, 0x85, 0x8f, 0x23, 0xf6, 0xaa, 0x53, 0xac,
+  0xb4, 0x7d, 0x40, 0xd1, 0x7a, 0xa8, 0x2c, 0xf0, 0x03, 0x33, 0xa9, 0x52,
+  0xba, 0x6b, 0x90, 0xd1, 0x0f, 0x39, 0x07, 0x59, 0x39, 0xca, 0xea, 0xd5,
+  0x73, 0xc6, 0xd4, 0x73, 0x9f, 0xd0, 0x8c, 0x59, 0xd2, 0x5a, 0x25, 0x67,
+  0x77, 0xf7, 0x03, 0xb6, 0xad, 0x77, 0x96, 0xba, 0x73, 0x46, 0x52, 0x45,
+  0x6b, 0x0f, 0x8b, 0x29, 0x8d, 0x26, 0x56, 0x22, 0xdb, 0x56, 0x40, 0xce,
+  0x70, 0x6c, 0x5e, 0x93, 0x12, 0x39, 0x78, 0x6b, 0x96, 0xe1, 0x20, 0xf9,
+  0x8f, 0x32, 0xeb, 0x21, 0xc1, 0xaf, 0x93, 0xdf, 0x17, 0x90, 0xfd, 0x1c,
+  0x5e, 0xbc, 0x3d, 0x79, 0xfb, 0xf5, 0x81, 0x95, 0x71, 0x24, 0xef, 0x3c,
+  0x16, 0x74, 0x17, 0xe5, 0x73, 0x25, 0x59, 0xf0, 0x48, 0x1e, 0xe5, 0x21,
+  0x77, 0xac, 0xb2, 0x83, 0x84, 0x25, 0xb4, 0x98, 0xd4, 0xed, 0x12, 0xd4,
+  0x16, 0xc6, 0x2b, 0xd9, 0x43, 0xb8, 0x2f, 0x9b, 0x32, 0xd0, 0x85, 0xd8,
+  0xa5, 0xdd, 0x2a, 0xe0, 0x6e, 0xb3, 0x90, 0x0b, 0x64, 0x6c, 0xa8, 0x66,
+  0xa4, 0x52, 0xd4, 0x2f, 0x27, 0x10, 0x06, 0x3d, 0x81, 0x85, 0x43, 0x7c,
+  0xa1, 0xe6, 0xbb, 0xa2, 0xc5, 0xbe, 0xce, 0x0c, 0xca, 0x35, 0x56, 0xad,
+  0xce, 0xa1, 0xff, 0xda, 0x59, 0x59, 0xa1, 0xa9, 0xe1, 0x32, 0x63, 0xde,
+  0x45, 0xa9, 0x3c, 0x2e, 0xac, 0x2b, 0xf2, 0x53, 0x07, 0x12, 0xb6, 0xe3,
+  0x7f, 0x34, 0xd0, 0xce, 0x21, 0xed, 0xd8, 0x62, 0x60, 0xc7, 0xb8, 0x27,
+  0xb5, 0x76, 0x2a, 0xdc, 0x26, 0xd1, 0xec, 0xea, 0x59, 0xe6, 0x20, 0xf2,
+  0x56, 0xdd, 0xb9, 0x61, 0x75, 0x67, 0xb6, 0x08, 0x48, 0x84, 0x50, 0xa2,
+  0x93, 0x7e, 0xa3, 0x76, 0x06, 0xf9, 0x54, 0x71, 0x09, 0x2b, 0x4a, 0xa8,
+  0x5d, 0x6a, 0x59, 0x6b, 0x00, 0xb1, 0x5c, 0x0f, 0xaf, 0x54, 0x62, 0xb1,
+  0xc8, 0x98, 0x47, 0xc5, 0x07, 0x63, 0x9b, 0xaf, 0x9b, 0x39, 0x5e, 0x2c,
+  0xc7, 0xf3, 0xe9, 0xb3, 0xe4, 0x85, 0xf9, 0x4f, 0xa0, 0x67, 0x01, 0xd1,
+  0x34, 0x3a, 0x32, 0xba, 0x16, 0x85, 0x5f, 0xe9, 0xca, 0xe0, 0x44, 0x7e,
+  0x51, 0xed, 0xe9, 0xaf, 0x4f, 0xf6, 0x4d, 0x4f, 0x3f, 0xa6, 0x4a, 0xdb,
+  0x65, 0x94, 0xc2, 0xeb, 0xbc, 0x61, 0x14, 0xc9, 0x0a, 0x36, 0x04, 0xbf,
+  0x20, 0x2a, 0xad, 0xf8, 0xde, 0xfe, 0xa7, 0x09, 0x01, 0x60, 0xdf, 0xbc,
+  0x7a, 0x96, 0x18, 0xd3, 0x64, 0xf2, 0xa1, 0x5e, 0xce, 0x55, 0x22, 0x4b,
+  0x1d, 0x62, 0xea, 0x67, 0xc0, 0x37, 0x60, 0x3a, 0x3e, 0xcb, 0x27, 0x94,
+  0x85, 0xe2, 0x43, 0x9a, 0xa8, 0x04, 0x62, 0x6d, 0x6b, 0xea, 0x89, 0xcb,
+  0xd3, 0xdd, 0x1c, 0x88, 0x66, 0x71, 0xc4, 0x37, 0xe2, 0x51, 0x33, 0x73,
+  0x60, 0x3e, 0x5e, 0x73, 0xe5, 0xc2, 0xb5, 0x7e, 0x84, 0x4f, 0x5a, 0xae,
+  0x98, 0x5d, 0x2c, 0xa5, 0x39, 0xdf, 0x7b, 0xc3, 0xdd, 0x55, 0xd5, 0x38,
+  0x3d, 0x9a, 0x11, 0x09, 0xeb, 0xc1, 0x1e, 0x90, 0xe2, 0xaa, 0x89, 0x79,
+  0xd3, 0xd7, 0xc3, 0x38, 0xc2, 0x63, 0x66, 0x72, 0x05, 0xf0, 0xc0, 0xdc,
+  0x2b, 0x6c, 0x02, 0x52, 0x0e, 0xad, 0xdf, 0xd0, 0x63, 0x21, 0xa0, 0xd2,
+  0xdd, 0x3d, 0x71, 0x3c, 0xd1, 0xbf, 0x5a, 0xae, 0x3e, 0xf9, 0xf5, 0x8a,
+  0xc2, 0xa9, 0x18, 0xcc, 0x9a, 0xb1, 0xec, 0xad, 0xed, 0x86, 0xd7, 0x0f,
+  0xcc, 0x9d, 0x9b, 0x3c, 0x5b, 0x57, 0x83, 0xfb, 0xa3, 0x73, 0x1e, 0x7a,
+  0xe2, 0x43, 0x6e, 0x58, 0xbc, 0x41, 0x68, 0xde, 0xb2, 0x1a, 0x90, 0x4a,
+  0x38, 0xcb, 0xa6, 0xc1, 0x15, 0x1d, 0x5b, 0x0c, 0x9c, 0x63, 0x54, 0x95,
+  0x97, 0x44, 0x63, 0xf2, 0x63, 0x91, 0xa3, 0x0c, 0x43, 0xb2, 0x22, 0x34,
+  0x86, 0x58, 0xa4, 0x27, 0x76, 0xf6, 0xad, 0x06, 0x88, 0x7f, 0xd2, 0x94,
+  0xbe, 0x5b, 0x5c, 0x57, 0x29, 0x39, 0xef, 0x08, 0xfb, 0xef, 0xd8, 0x56,
+  0x13, 0x74, 0x2e, 0x49, 0x56, 0xf5, 0x8e, 0xf9, 0xb9, 0xfc, 0xf2, 0x09,
+  0x9a, 0x98, 0x52, 0xeb, 0xa7, 0x6a, 0xca, 0xf9, 0x71, 0xe5, 0x2d, 0xe8,
+  0xa7, 0x8e, 0x46, 0x38, 0xc6, 0x87, 0x57, 0x37, 0x02, 0x93, 0x92, 0x06,
+  0x5a, 0x30, 0x42, 0xe2, 0xf9, 0xe4, 0xcb, 0xc5, 0x16, 0x1b, 0x21, 0xd8,
+  0xad, 0x70, 0x38, 0x04, 0x64, 0x43, 0xbc, 0xb8, 0xa2, 0x25, 0x74, 0xb8,
+  0x70, 0x02, 0x97, 0x57, 0x74, 0x39, 0x1e, 0xcd, 0x3c, 0x1b, 0x50, 0x5e,
+  0x10, 0x0f, 0x2d, 0xdd, 0xe0, 0x92, 0xa8, 0xc3, 0xa3, 0x19, 0x3e, 0x6e,
+  0x73, 0xef, 0xf6, 0xa3, 0xbd, 0xa3, 0xed, 0xe6, 0x6f, 0xfe, 0x16, 0x7f,
+  0xcc, 0x67, 0x91, 0xcd, 0xf5, 0xab, 0xce, 0xc2, 0xfe, 0x3a, 0xc7, 0xaf,
+  0x51, 0xe2, 0xd3, 0xd9, 0xa2, 0x18, 0xea, 0x17, 0x1e, 0x35, 0x3f, 0xdd,
+  0x65, 0xb6, 0x3c, 0xbd, 0xbf, 0x6e, 0x7e, 0xba, 0x73, 0xe3, 0xcb, 0x32,
+  0x7f, 0x7e, 0xba, 0x6b, 0xb9, 0x96, 0xa8, 0x99, 0x13, 0xeb, 0xb4, 0x3e,
+  0xe4, 0x80, 0x33, 0x06, 0x62, 0x40, 0xda, 0x44, 0x4e, 0xa4, 0x32, 0xac,
+  0xf4, 0x93, 0x13, 0x66, 0x10, 0x44, 0x04, 0x47, 0x5e, 0x3f, 0xe5, 0x84,
+  0x03, 0xbe, 0x42, 0x2d, 0x02, 0x2d, 0x92, 0x9b, 0x94, 0x4f, 0x96, 0x5c,
+  0xbf, 0x79, 0xc9, 0xf5, 0xe2, 0x49, 0x87, 0xb3, 0xa4, 0xc7, 0xcb, 0x02,
+  0x17, 0xd6, 0xe1, 0x82, 0x72, 0x06, 0x8c, 0x8c, 0xfa, 0xe8, 0xaa, 0x41,
+  0x45, 0x1c, 0x8f, 0xe6, 0x56, 0x47, 0x46, 0x58, 0x5e, 0x28, 0x4c, 0xa9,
+  0xdb, 0x1d, 0xb4, 0xce, 0x1c, 0x23, 0x33, 0x02, 0xe6, 0x55, 0xac, 0xc4,
+  0xec, 0x1b, 0xcb, 0xf1, 0x3a, 0x60, 0x30, 0x1d, 0xdf, 0x37, 0x11, 0xcc,
+  0x2c, 0x8d, 0x9a, 0x66, 0x61, 0xab, 0x96, 0xa0, 0xfc, 0xd3, 0xe7, 0xc3,
+  0xdd, 0xed, 0x3e, 0x15, 0xbe, 0x5b, 0x60, 0x06, 0x08, 0xd4, 0x68, 0xef,
+  0x7a, 0xc2, 0xf4, 0xe6, 0xd7, 0x64, 0x43, 0xad, 0xaa, 0x43, 0x4d, 0xfe,
+  0x16, 0x09, 0x06, 0x6b, 0xa4, 0x55, 0x38, 0x9d, 0xda, 0xdc, 0xad, 0x79,
+  0x1f, 0xf5, 0x01, 0xe0, 0x2d, 0xe9, 0x7a, 0x4b, 0xc5, 0x87, 0xe2, 0x0a,
+  0x5d, 0xfa, 0xc4, 0xa1, 0xaa, 0x81, 0xb9, 0x2a, 0x97, 0xc2, 0x88, 0x0b,
+  0x07, 0x72, 0xc4, 0xb7, 0xe2, 0xc8, 0x37, 0x95, 0xf8, 0x18, 0xd6, 0x36,
+  0x7f, 0x43, 0x8c, 0x22, 0x28, 0x9d, 0x2a, 0xf1, 0xc8, 0x6e, 0x21, 0x0f,
+  0x13, 0xf3, 0x0c, 0x77, 0x4f, 0xee, 0x14, 0x24, 0x95, 0xac, 0x1b, 0x38,
+  0x3e, 0xb6, 0xd6, 0x81, 0x53, 0x0e, 0xb5, 0xe1, 0x30, 0x56, 0x87, 0xfa,
+  0x36, 0xcf, 0xee, 0x5a, 0xce, 0x21, 0xe9, 0x57, 0xdf, 0x72, 0x11, 0xb3,
+  0x4d, 0x72, 0x4b, 0x33, 0x64, 0x9a, 0x1c, 0x97, 0xb6, 0xc6, 0xe2, 0x9a,
+  0x83, 0xec, 0x3f, 0xed, 0x4d, 0xf3, 0x07, 0x9e, 0xe6, 0x3a, 0x06, 0x9e,
+  0x67, 0xf6, 0x31, 0x47, 0x9d, 0xda, 0x27, 0x05, 0xbd, 0xba, 0x4f, 0xc0,
+  0x91, 0xeb, 0x14, 0x17, 0xc8, 0x15, 0x06, 0x6b, 0xe5, 0x35, 0x93, 0x7f,
+  0x71, 0xde, 0x75, 0xa8, 0xfd, 0xf2, 0x67, 0xda, 0x67, 0x5e, 0xfc, 0x36,
+  0xb6, 0xf0, 0x67, 0x55, 0x4e, 0xc8, 0x34, 0xc2, 0x25, 0xab, 0x9c, 0x9f,
+  0xb0, 0x0c, 0x22, 0xe1, 0x19, 0x59, 0x11, 0x8f, 0x24, 0xd8, 0x8b, 0x26,
+  0x38, 0xe6, 0xe6, 0x44, 0x07, 0x38, 0x8c, 0xa6, 0x0b, 0xeb, 0xba, 0x7a,
+  0x63, 0x6a, 0x8d, 0x64, 0x7c, 0xaf, 0xf4, 0xf9, 0xe2, 0x1d, 0x70, 0xa4,
+  0x66, 0x01, 0xfd, 0xa6, 0x05, 0xf3, 0x3b, 0xc2, 0x01, 0xe7, 0x67, 0x61,
+  0xfa, 0x16, 0x8c, 0x4c, 0x1a, 0xaf, 0x7d, 0x3e, 0xba, 0x80, 0x9b, 0xd5,
+  0x2b, 0x74, 0x9a, 0x51, 0x0a, 0x03, 0xd1, 0x5b, 0x47, 0x97, 0x98, 0x4d,
+  0x70, 0xce, 0x07, 0x34, 0xdb, 0xb9, 0x5c, 0x92, 0x6b, 0x1e, 0x67, 0x5f,
+  0xd2, 0x79, 0x24, 0x83, 0xa7, 0x9b, 0xe6, 0x69, 0x19, 0x5d, 0x68, 0xf6,
+  0x87, 0x37, 0xe9, 0xc7, 0x8f, 0xc3, 0x3a, 0xdb, 0x31, 0xbb, 0xb6, 0xde,
+  0xa9, 0xeb, 0x19, 0x7d, 0xb4, 0x06, 0x33, 0xc5, 0xea, 0xeb, 0x81, 0xed,
+  0x57, 0x9d, 0x5f, 0x11, 0xc6, 0x93, 0x94, 0x5e, 0x6d, 0x09, 0x5b, 0x57,
+  0x86, 0x84, 0xb9, 0x98, 0xbb, 0xc0, 0x0a, 0x66, 0x77, 0x43, 0x1a, 0xb0,
+  0x9f, 0x9a, 0xc0, 0xa2, 0xc1, 0x05, 0xb0, 0x6c, 0x3b, 0x8e, 0xb6, 0x92,
+  0xf8, 0xdc, 0xaa, 0x55, 0x38, 0x38, 0x39, 0xab, 0x1e, 0x24, 0xc1, 0x4c,
+  0x8a, 0x85, 0x8b, 0x99, 0xfb, 0xa1, 0x70, 0x49, 0xc7, 0x13, 0x56, 0xf9,
+  0xa9, 0x38, 0x67, 0x24, 0x1d, 0x7e, 0x95, 0x21, 0xed, 0x0d, 0x8d, 0x80,
+  0x75, 0x07, 0x7b, 0x76, 0x4e, 0xef, 0xee, 0xee, 0x86, 0xeb, 0x2c, 0xe9,
+  0x7f, 0x3a, 0xa9, 0xa7, 0xdd, 0xdc, 0x99, 0xd9, 0xb5, 0xa7, 0x79, 0xb1,
+  0xfc, 0x98, 0x78, 0xd9, 0xaf, 0x96, 0x77, 0x5b, 0x5d, 0xc5, 0xc9, 0x77,
+  0x17, 0xaf, 0x6d, 0xd1, 0x2f, 0xcd, 0x39, 0x24, 0x5f, 0x44, 0x1d, 0x7a,
+  0x4d, 0xb3, 0x9c, 0x73, 0x92, 0x89, 0x99, 0xed, 0xe8, 0xf0, 0xfc, 0xfd,
+  0xdb, 0xe3, 0xcb, 0xf7, 0x17, 0x87, 0xdf, 0xd3, 0x14, 0x72, 0x10, 0xb0,
+  0x4a, 0x41, 0xfe, 0x5f, 0x95, 0x25, 0x95, 0x1e, 0x78, 0x03, 0x8c, 0x75,
+  0x5e, 0x20, 0xf1, 0x34, 0x46, 0x8f, 0x6d, 0xf3, 0xe9, 0xb5, 0x9f, 0xa6,
+  0x2f, 0x07, 0x49, 0x6b, 0xbe, 0x3e, 0x18, 0xcb, 0x21, 0x9b, 0x0d, 0xcb,
+  0xea, 0x9a, 0x76, 0xe1, 0xce, 0x2b, 0x91, 0x9f, 0xd1, 0xe6, 0x76, 0x8a,
+  0xac, 0x21, 0xf0, 0x14, 0xd1, 0x33, 0xdc, 0x56, 0x57, 0x94, 0xcb, 0xb9,
+  0xae, 0x64, 0xa6, 0x5f, 0x49, 0xc2, 0xdb, 0x9a, 0x4f, 0x21, 0x00, 0x17,
+  0xb7, 0x4f, 0xd7, 0x18, 0x03, 0x4d, 0x4b, 0x7f, 0xa2, 0x03, 0x36, 0xbb,
+  0xe5, 0xad, 0x85, 0x28, 0x86, 0x5f, 0x8e, 0x84, 0xa1, 0xec, 0xb3, 0xfb,
+  0x7e, 0x24, 0x5b, 0x0c, 0xc4, 0x95, 0xa5, 0xcd, 0xad, 0x03, 0x1a, 0x98,
+  0x4a, 0x61, 0xac, 0x2f, 0x81, 0xa1, 0x7a, 0x50, 0xd7, 0xec, 0x68, 0x51,
+  0x53, 0xfb, 0x9a, 0xd3, 0xf3, 0x50, 0x97, 0xa4, 0xe2, 0x18, 0xde, 0x98,
+  0x9f, 0xcb, 0x98, 0x9f, 0xff, 0x53, 0x63, 0x7e, 0xfe, 0x4f, 0x8c, 0xf9,
+  0xe9, 0xbf, 0x7c, 0xcc, 0x7f, 0xa3, 0x31, 0xff, 0x6d, 0x59, 0x7c, 0x18,
+  0x98, 0xfe, 0xd2, 0x2d, 0x2c, 0x05, 0x06, 0xea, 0xb8, 0xca, 0xdc, 0xe2,
+  0xb4, 0x26, 0x47, 0x93, 0xad, 0x8b, 0x3b, 0xf1, 0xeb, 0x25, 0xa4, 0x92,
+  0xdf, 0xc2, 0x41, 0xa7, 0x95, 0x55, 0x00, 0x93, 0x56, 0x69, 0x76, 0xca,
+  0xa4, 0x9d, 0xe6, 0xf5, 0x84, 0xec, 0x1b, 0x72, 0x98, 0xf4, 0xa4, 0x47,
+  0xda, 0x74, 0x6f, 0xe8, 0xca, 0xb9, 0x07, 0x1c, 0x28, 0xb5, 0xb9, 0x5d,
+  0xc8, 0xb4, 0xc6, 0xa9, 0xb4, 0x71, 0x19, 0x57, 0x85, 0x0e, 0xcc, 0x2d,
+  0x94, 0x1d, 0xaf, 0x8d, 0xb2, 0xa7, 0x9a, 0xbc, 0x90, 0xa1, 0xcc, 0xb8,
+  0xbc, 0x5f, 0x50, 0x73, 0x89, 0x96, 0xfd, 0xae, 0x6d, 0xc5, 0x50, 0xdb,
+  0xc1, 0xa4, 0xd3, 0x39, 0x71, 0xbd, 0xdd, 0x64, 0xf7, 0x9b, 0x81, 0xc2,
+  0x30, 0x99, 0x95, 0x24, 0x6f, 0x48, 0xaf, 0x5b, 0xa3, 0x89, 0x8c, 0x5d,
+  0x75, 0x07, 0xbe, 0x2f, 0x3a, 0xe5, 0x1e, 0xfc, 0x7b, 0xe3, 0x43, 0x96,
+  0x2d, 0xd2, 0x19, 0xf2, 0x10, 0x29, 0x1a, 0xb7, 0x8a, 0x93, 0xbe, 0x15,
+  0x3e, 0x56, 0x70, 0x15, 0xde, 0x48, 0xdb, 0xd7, 0x3a, 0x24, 0x9d, 0x56,
+  0x2d, 0x9e, 0x03, 0x68, 0x98, 0x4f, 0x83, 0xd4, 0x6c, 0x25, 0xa4, 0xd2,
+  0x80, 0x9c, 0xed, 0x05, 0x69, 0x27, 0x63, 0x49, 0x8a, 0xb5, 0x9f, 0x50,
+  0x8e, 0x8d, 0xdc, 0x3c, 0x7c, 0x9b, 0x4f, 0x97, 0x41, 0x0d, 0xd1, 0xee,
+  0xeb, 0xc8, 0xb7, 0x6f, 0xd1, 0x93, 0xf2, 0xf2, 0xd1, 0x13, 0xa5, 0xbd,
+  0xff, 0x48, 0xdd, 0x40, 0xad, 0x97, 0x60, 0x4b, 0x29, 0x4f, 0x17, 0x6b,
+  0xb7, 0x97, 0x47, 0xe7, 0xef, 0xbf, 0x3d, 0x3e, 0x3e, 0x3f, 0x79, 0x75,
+  0x7a, 0x2c, 0x07, 0xc6, 0xfe, 0xe8, 0xed, 0xe5, 0x77, 0xa7, 0x5a, 0x92,
+  0x41, 0xf7, 0x62, 0xb0, 0xe1, 0x85, 0x5b, 0x93, 0x85, 0x72, 0x1f, 0xcc,
+  0xf3, 0x45, 0x93, 0x1c, 0x9e, 0xfc, 0x60, 0xb4, 0xd6, 0xf3, 0xc1, 0xbb,
+  0x1f, 0x02, 0xca, 0x5f, 0x0f, 0x87, 0xb7, 0xb2, 0x1e, 0xa2, 0xd9, 0x86,
+  0xb0, 0x1d, 0xdd, 0xd8, 0x6d, 0xb6, 0xc2, 0xef, 0x7b, 0x0d, 0x52, 0x31,
+  0xb7, 0xc2, 0x2a, 0x0c, 0xfc, 0xa2, 0xd2, 0x6a, 0xb3, 0x1a, 0x0b, 0xf9,
+  0xf5, 0x7c, 0x57, 0x2b, 0x16, 0xac, 0xf5, 0xa1, 0x7d, 0xda, 0xb6, 0x19,
+  0x3f, 0x64, 0xf7, 0xe0, 0xb7, 0x49, 0x5e, 0xd0, 0x7f, 0xe3, 0x15, 0x25,
+  0xce, 0xab, 0xfc, 0x96, 0xf4, 0x3f, 0xf3, 0x2c, 0x07, 0x19, 0xe8, 0xd1,
+  0xa1, 0xad, 0xaf, 0x21, 0x81, 0x0e, 0x6a, 0x04, 0xb1, 0x50, 0x34, 0x0a,
+  0x8f, 0x46, 0x10, 0x2c, 0xcb, 0xa7, 0xec, 0xeb, 0xe0, 0xf6, 0xd0, 0xa0,
+  0x99, 0x9e, 0x61, 0xf2, 0xea, 0xf8, 0xa2, 0x9f, 0x9c, 0x1f, 0xbf, 0x61,
+  0x30, 0xdf, 0xf1, 0xdb, 0xaf, 0x99, 0x56, 0x45, 0x2b, 0x49, 0x20, 0x36,
+  0x17, 0xa2, 0xfb, 0xbc, 0x39, 0x31, 0xef, 0x82, 0xe5, 0xa4, 0xae, 0xcd,
+  0xed, 0xfa, 0x3b, 0x66, 0x1b, 0xf3, 0xd8, 0x5e, 0x98, 0xff, 0xc4, 0xa6,
+  0xca, 0xd8, 0x11, 0xdf, 0x44, 0xa6, 0x4b, 0x14, 0x33, 0x1b, 0xcd, 0x15,
+  0xa3, 0x80, 0x66, 0x83, 0x67, 0xcc, 0x4c, 0x48, 0x18, 0x57, 0xd4, 0x09,
+  0x82, 0xeb, 0x07, 0xf9, 0xd6, 0x5c, 0xe4, 0x48, 0xa2, 0x42, 0x64, 0xc5,
+  0x9a, 0xcf, 0xf5, 0x69, 0x5f, 0xd2, 0x95, 0xe4, 0x4d, 0x46, 0x2c, 0x95,
+  0xa4, 0xca, 0x05, 0x6a, 0xed, 0x71, 0x76, 0x98, 0xb9, 0xce, 0xa7, 0xc8,
+  0x55, 0x33, 0xdf, 0x28, 0x2b, 0x8a, 0x26, 0xfe, 0x9e, 0x13, 0x57, 0x8d,
+  0x93, 0x17, 0x33, 0xf3, 0xe2, 0x2c, 0x8e, 0x21, 0xe5, 0xe2, 0xcb, 0xae,
+  0x88, 0x74, 0x87, 0x86, 0x5a, 0xaa, 0x0c, 0xb2, 0xcd, 0x8b, 0x66, 0x38,
+  0xc8, 0x1a, 0x62, 0xab, 0xa0, 0x3e, 0x8b, 0xbd, 0x15, 0x64, 0x9a, 0x6e,
+  0x02, 0x74, 0xb7, 0xd9, 0x4f, 0x36, 0x89, 0x6b, 0x9b, 0xfe, 0x44, 0xd9,
+  0x41, 0x29, 0xb1, 0xbd, 0xd9, 0x0f, 0xeb, 0x87, 0x6e, 0xca, 0x76, 0xdd,
+  0x34, 0x3b, 0x9e, 0x5b, 0xa3, 0x25, 0x44, 0xfe, 0x8e, 0xf4, 0x83, 0x5d,
+  0x88, 0x79, 0x2d, 0x11, 0x74, 0x20, 0x98, 0x04, 0xb0, 0x5f, 0x07, 0x9c,
+  0xd0, 0xb6, 0xb9, 0x76, 0x32, 0xf0, 0xaa, 0xbc, 0xf6, 0xdf, 0x58, 0x96,
+  0xf0, 0x32, 0xfc, 0xd2, 0x5a, 0x54, 0xce, 0xc7, 0xd5, 0x69, 0x4e, 0x17,
+  0xcb, 0x5f, 0x67, 0x7d, 0x3d, 0x5a, 0x9a, 0xe7, 0x90, 0x33, 0x1e, 0xfc,
+  0x21, 0x81, 0x3b, 0x94, 0x80, 0x79, 0x53, 0x56, 0xdd, 0x05, 0xc5, 0xed,
+  0x97, 0xd3, 0x90, 0x4b, 0x20, 0x04, 0x42, 0xb0, 0x0e, 0x02, 0x2a, 0x55,
+  0xed, 0xf6, 0x80, 0x4d, 0xac, 0xa3, 0x44, 0x6c, 0x46, 0x20, 0xfc, 0xee,
+  0x2a, 0xa2, 0xfb, 0x29, 0x34, 0x52, 0xc6, 0x42, 0x2c, 0x9e, 0x16, 0xae,
+  0x8c, 0x40, 0x66, 0x91, 0x66, 0x52, 0xe7, 0x41, 0x41, 0x0c, 0x95, 0x76,
+  0x6b, 0x20, 0x01, 0x20, 0xb5, 0xea, 0xe8, 0xbd, 0x3f, 0xfc, 0x93, 0x2b,
+  0x27, 0xe5, 0x39, 0x38, 0x57, 0x34, 0x92, 0xf9, 0xf3, 0x68, 0xf6, 0x83,
+  0x0e, 0x5e, 0x15, 0x34, 0x22, 0x03, 0x08, 0x8e, 0x17, 0x46, 0x46, 0x64,
+  0x41, 0xfa, 0x77, 0xbb, 0x4c, 0xd2, 0x5c, 0x8a, 0xe0, 0x78, 0x04, 0x30,
+  0x78, 0xd7, 0xd6, 0xe8, 0xf2, 0x7d, 0xae, 0x83, 0x48, 0x71, 0x4f, 0x90,
+  0x97, 0xba, 0x8c, 0x03, 0x1c, 0x5b, 0x30, 0x5b, 0x68, 0xda, 0xae, 0x82,
+  0xab, 0x78, 0x42, 0xc8, 0x61, 0x28, 0xb0, 0x1d, 0xe8, 0x7f, 0x69, 0x60,
+  0xa8, 0x9a, 0xee, 0x2b, 0x1f, 0x28, 0x35, 0x46, 0x60, 0x92, 0x29, 0x7b,
+  0xaf, 0xb0, 0x24, 0xb6, 0x9f, 0x28, 0x5b, 0xcb, 0xfd, 0xc2, 0x2f, 0xe8,
+  0x44, 0x07, 0xfa, 0xdc, 0xd8, 0x34, 0x71, 0x97, 0x4f, 0x51, 0x27, 0x5c,
+  0x40, 0x34, 0x94, 0x5c, 0x2d, 0x79, 0x2e, 0xe4, 0x49, 0xcc, 0x43, 0xf8,
+  0xe6, 0x38, 0xee, 0x65, 0xe1, 0x15, 0xc3, 0x9c, 0x26, 0x9c, 0xf1, 0x4d,
+  0xce, 0x14, 0x2c, 0x03, 0x1c, 0x8f, 0x3b, 0x7c, 0x1d, 0xdb, 0x5c, 0x47,
+  0x63, 0xf5, 0x2f, 0xaf, 0x88, 0x77, 0x38, 0x74, 0xa3, 0x2a, 0xca, 0x72,
+  0x68, 0x8f, 0x08, 0x93, 0x91, 0x7f, 0x60, 0x62, 0xc7, 0x6f, 0x37, 0xb5,
+  0xce, 0x0e, 0x51, 0x79, 0x80, 0xb5, 0x92, 0xc1, 0x51, 0xe6, 0x84, 0x7e,
+  0xc8, 0x67, 0x65, 0xd4, 0xef, 0x69, 0x44, 0xdb, 0x1c, 0xaf, 0xbf, 0xd9,
+  0x54, 0x5f, 0x16, 0x25, 0x00, 0x5d, 0xa7, 0xf2, 0x5b, 0x4e, 0xfe, 0xdb,
+  0xbc, 0xe6, 0x4f, 0x7c, 0xbd, 0xa9, 0xfc, 0xc4, 0x61, 0x8a, 0x03, 0xb9,
+  0x56, 0xd9, 0x95, 0xaa, 0x31, 0xf8, 0xfa, 0x20, 0xd9, 0xdf, 0xdd, 0xfd,
+  0xb6, 0x9f, 0x3c, 0xe1, 0xc2, 0xe9, 0x7b, 0x5f, 0x47, 0x73, 0x64, 0x19,
+  0x63, 0x42, 0x2a, 0xb2, 0x46, 0x07, 0x07, 0x7f, 0x25, 0xcd, 0x18, 0x73,
+  0xc6, 0x3b, 0xd3, 0x42, 0x1a, 0x19, 0x38, 0xeb, 0x30, 0xbf, 0xdd, 0x0b,
+  0x8c, 0x96, 0x6a, 0x41, 0x9a, 0xdc, 0x34, 0x53, 0x92, 0xbb, 0x39, 0x5c,
+  0x50, 0x14, 0x61, 0x5d, 0x48, 0x8a, 0x17, 0x6d, 0xd5, 0x81, 0x25, 0xce,
+  0xa9, 0x67, 0xf4, 0x00, 0x08, 0xc3, 0xcb, 0x00, 0x90, 0x35, 0x5b, 0x40,
+  0x8b, 0xb5, 0x9c, 0xfe, 0x5e, 0x97, 0x08, 0x9e, 0x3d, 0x49, 0xc4, 0x10,
+  0xff, 0x1d, 0x75, 0x89, 0x19, 0x82, 0xfa, 0x79, 0xdd, 0x0c, 0xc8, 0xd6,
+  0x8c, 0x3a, 0xea, 0xcf, 0xcf, 0xce, 0x9f, 0x6c, 0x5b, 0x58, 0x39, 0x73,
+  0x86, 0x48, 0xae, 0x4f, 0xa2, 0x30, 0x41, 0x9b, 0x05, 0xa4, 0xdc, 0x62,
+  0x40, 0x9b, 0xc6, 0xaa, 0x60, 0x2b, 0xbd, 0x2e, 0xbe, 0x07, 0xaf, 0xac,
+  0xcb, 0x2c, 0xf7, 0x8a, 0x42, 0xb8, 0x63, 0xc9, 0x32, 0x81, 0x50, 0x22,
+  0x1b, 0x61, 0xa2, 0xa4, 0x58, 0x1d, 0x92, 0x67, 0x38, 0x00, 0x8a, 0x35,
+  0x69, 0xf3, 0x4d, 0x13, 0xe4, 0xb1, 0xd3, 0xc9, 0x76, 0x6e, 0x97, 0x17,
+  0x06, 0x16, 0xb0, 0xa8, 0x7b, 0x10, 0x5e, 0x63, 0xc5, 0xf4, 0xf2, 0x7d,
+  0x6b, 0x83, 0x68, 0xe4, 0xd2, 0xa2, 0x7d, 0xcb, 0x94, 0x60, 0xc3, 0x95,
+  0x75, 0xf1, 0x2c, 0x31, 0x6b, 0x4b, 0x6d, 0x16, 0xfe, 0xf6, 0x34, 0x79,
+  0x7b, 0x3a, 0xba, 0xf4, 0x3d, 0xfd, 0x70, 0xe8, 0x06, 0x08, 0xa8, 0x36,
+  0x55, 0x81, 0x17, 0x2f, 0x3e, 0x3d, 0x19, 0x5d, 0x0e, 0x63, 0x94, 0xa3,
+  0x07, 0xc9, 0xa8, 0x9c, 0xfb, 0x95, 0xf8, 0x6a, 0xa9, 0x94, 0x06, 0xb8,
+  0x33, 0x87, 0x2f, 0xd4, 0x9b, 0x9f, 0x57, 0xbe, 0xaf, 0x3f, 0xd8, 0xa9,
+  0xd4, 0xc5, 0xcf, 0x19, 0xdd, 0x24, 0xc8, 0x28, 0x75, 0xe4, 0xd7, 0xcb,
+  0xf1, 0xc0, 0xe3, 0x06, 0x61, 0x7d, 0x07, 0x64, 0xe5, 0x66, 0xf7, 0x9a,
+  0x1b, 0xea, 0x43, 0x68, 0x08, 0x6c, 0xc9, 0x7e, 0xe2, 0x8d, 0x24, 0xac,
+  0x2e, 0x2d, 0x8f, 0xe4, 0x24, 0xc9, 0xc0, 0x13, 0x05, 0x5f, 0x00, 0x3d,
+  0xfd, 0xa8, 0x4d, 0x45, 0x13, 0xd1, 0x99, 0x47, 0xa9, 0x6e, 0xd1, 0x06,
+  0x3a, 0x52, 0x64, 0xc5, 0xe3, 0xba, 0x58, 0x17, 0x4c, 0xf2, 0x76, 0xa1,
+  0x92, 0xce, 0xc8, 0xae, 0xe3, 0xa2, 0x7b, 0xec, 0x16, 0xb0, 0xbd, 0x5e,
+  0x45, 0x5d, 0x95, 0x4f, 0x99, 0xd9, 0xa5, 0x6e, 0x53, 0xbb, 0x70, 0xf6,
+  0x0e, 0x89, 0x1c, 0x26, 0x72, 0x26, 0xeb, 0x75, 0xc5, 0x4a, 0xb2, 0xdf,
+  0xa4, 0x05, 0x69, 0x19, 0xfc, 0xc0, 0x38, 0x29, 0x04, 0x33, 0xfa, 0x31,
+  0xca, 0x81, 0x58, 0xaa, 0xac, 0xc7, 0x9a, 0xfe, 0xce, 0x98, 0xb6, 0x76,
+  0xbe, 0x64, 0x7e, 0xa4, 0x52, 0xad, 0x0c, 0x95, 0xd0, 0xb0, 0x2a, 0x34,
+  0xb1, 0x22, 0x81, 0x67, 0x7e, 0x59, 0xe4, 0xe6, 0xfb, 0x09, 0xab, 0xae,
+  0x57, 0x04, 0x00, 0xad, 0x52, 0x06, 0xf7, 0xe0, 0x1e, 0x33, 0x63, 0xda,
+  0xac, 0x2d, 0x83, 0x22, 0x39, 0x05, 0xf4, 0xb8, 0x7e, 0x88, 0xd6, 0x43,
+  0x5a, 0x05, 0xe4, 0xf7, 0xd3, 0x00, 0xf7, 0xda, 0x94, 0x3d, 0x60, 0xe7,
+  0x92, 0x04, 0x7b, 0x73, 0x21, 0xed, 0x20, 0x77, 0x34, 0x5a, 0x17, 0x36,
+  0x4d, 0x3c, 0xe0, 0x84, 0x24, 0x8d, 0x2a, 0xbe, 0xb7, 0x92, 0x44, 0xd5,
+  0xad, 0xd7, 0x17, 0x67, 0x6f, 0x06, 0x97, 0x67, 0x28, 0xff, 0x87, 0xa6,
+  0x93, 0x88, 0xc6, 0xa9, 0xe5, 0x5b, 0xbd, 0x1a, 0x86, 0x6d, 0xd4, 0xc9,
+  0x56, 0xbd, 0x3d, 0xf4, 0x79, 0x7f, 0x17, 0x7e, 0xd1, 0xd7, 0x80, 0x81,
+  0xb7, 0x60, 0x5d, 0x04, 0xe6, 0xa6, 0xd9, 0x4d, 0x93, 0x94, 0x54, 0x46,
+  0x1b, 0x6f, 0x40, 0x03, 0x2a, 0xbc, 0xc7, 0xcb, 0xfa, 0x1e, 0xdc, 0xe0,
+  0x00, 0x22, 0x01, 0x22, 0xd5, 0x84, 0x4e, 0x5c, 0x65, 0xa0, 0xb0, 0xc9,
+  0xb7, 0xc4, 0xd8, 0xc1, 0x70, 0xf0, 0xa6, 0x34, 0xe7, 0x37, 0xad, 0xaa,
+  0xf2, 0x4e, 0x6f, 0x2e, 0xe4, 0x30, 0x98, 0x85, 0xb4, 0x65, 0xe7, 0x57,
+  0xa6, 0x2a, 0x4a, 0x12, 0xbe, 0x56, 0x52, 0x5b, 0xab, 0x00, 0x3e, 0x6b,
+  0xa7, 0x8f, 0x29, 0x6a, 0x6c, 0xd0, 0x54, 0xc6, 0x5e, 0xca, 0xa6, 0x2b,
+  0xd0, 0x19, 0xa7, 0x24, 0x29, 0x01, 0x34, 0xf3, 0xde, 0xe9, 0x0b, 0x51,
+  0x08, 0x25, 0x94, 0x82, 0xfe, 0x5d, 0xfd, 0x47, 0x96, 0x39, 0xfb, 0x2f,
+  0xc1, 0x19, 0x16, 0xfa, 0x30, 0x52, 0xeb, 0x67, 0x33, 0x07, 0x34, 0x13,
+  0x16, 0x1a, 0xaa, 0xd6, 0x4a, 0x7b, 0x5b, 0xb1, 0x60, 0x20, 0x08, 0x80,
+  0x3c, 0xa0, 0x9f, 0x06, 0xda, 0xa4, 0xa6, 0xfc, 0xe6, 0x94, 0x6c, 0x35,
+  0x5d, 0x4e, 0xb0, 0x4a, 0x14, 0x98, 0xa1, 0x52, 0x27, 0x63, 0xe6, 0x22,
+  0xd2, 0x7c, 0x25, 0x6a, 0xda, 0x41, 0xec, 0xd8, 0xce, 0xee, 0xea, 0x59,
+  0xfc, 0x94, 0x2d, 0x2d, 0x40, 0xca, 0x24, 0xe1, 0x35, 0x32, 0x56, 0x2c,
+  0xab, 0xa0, 0xf6, 0x51, 0x71, 0x55, 0xda, 0x02, 0x52, 0x11, 0x81, 0x45,
+  0xac, 0x8f, 0xa0, 0xb9, 0x13, 0x7c, 0x06, 0xb1, 0xb5, 0xd0, 0xf6, 0x45,
+  0x6c, 0xf4, 0x2b, 0xf2, 0x6c, 0x76, 0x5a, 0xdc, 0x5e, 0xe3, 0x45, 0x5c,
+  0x2a, 0x22, 0xd3, 0x5b, 0xbd, 0x16, 0xee, 0x6f, 0xc5, 0xca, 0x9d, 0xc8,
+  0x3d, 0x6d, 0x6b, 0xbe, 0x32, 0x78, 0xc5, 0xce, 0xb9, 0x9c, 0x6c, 0xd0,
+  0x89, 0x5c, 0x73, 0x41, 0x46, 0xc2, 0xcc, 0x4d, 0x63, 0x80, 0x7c, 0xad,
+  0x6d, 0xd1, 0x24, 0xfa, 0xd1, 0x64, 0x8b, 0xbc, 0x80, 0x13, 0x1f, 0xc2,
+  0x7c, 0x2a, 0xbf, 0x52, 0xc4, 0x24, 0xf3, 0x03, 0x76, 0x9a, 0x7b, 0xf2,
+  0xc3, 0x0f, 0x49, 0xbb, 0x1c, 0xd5, 0xf6, 0xaa, 0xc4, 0x2e, 0x41, 0xb3,
+  0x4e, 0x4b, 0xbf, 0xbb, 0x01, 0x20, 0x9f, 0xf7, 0x9c, 0x51, 0x09, 0x00,
+  0xfc, 0x83, 0x4b, 0x48, 0x62, 0x41, 0xc6, 0xfe, 0xbb, 0x51, 0x84, 0x36,
+  0xc2, 0xec, 0x2e, 0xce, 0x9e, 0xa0, 0x86, 0xc0, 0xe0, 0x24, 0x02, 0x46,
+  0x81, 0xc8, 0x75, 0xb1, 0x75, 0x21, 0x3b, 0xe6, 0xfc, 0x5f, 0x7f, 0xc2,
+  0x5c, 0xd9, 0xc2, 0xfa, 0x86, 0xdc, 0xc0, 0xb8, 0x10, 0x1e, 0x2c, 0x99,
+  0xc5, 0x89, 0x6c, 0x18, 0x19, 0x2e, 0x7d, 0x26, 0x46, 0x25, 0xa8, 0xd3,
+  0xa4, 0xca, 0xc4, 0xdb, 0x50, 0xdb, 0x3c, 0xff, 0x20, 0xd8, 0x47, 0xf9,
+  0xa7, 0x33, 0x86, 0x69, 0x0e, 0xb1, 0xc2, 0xa9, 0x77, 0x62, 0x1c, 0x8b,
+  0x48, 0x67, 0xcd, 0x18, 0xbd, 0x19, 0xd6, 0xe8, 0x2c, 0x49, 0x83, 0xa2,
+  0x64, 0x2e, 0x50, 0x21, 0x94, 0x1c, 0x4c, 0x94, 0x42, 0x4a, 0x7c, 0xdf,
+  0xfc, 0x45, 0xcf, 0xed, 0xb0, 0x1d, 0xb6, 0xa0, 0x5d, 0x10, 0x8b, 0x54,
+  0xa9, 0x30, 0xc1, 0xc2, 0x10, 0x61, 0x15, 0xe5, 0x65, 0x2b, 0xa9, 0x3e,
+  0x79, 0xf4, 0x34, 0x96, 0xc9, 0x1a, 0x35, 0x72, 0xaa, 0xb8, 0x4e, 0x62,
+  0x40, 0x9e, 0xe6, 0x8e, 0x2c, 0x41, 0x2d, 0xe0, 0x9d, 0x72, 0x6c, 0x0b,
+  0xb0, 0x19, 0x06, 0xc6, 0x28, 0x1d, 0xe0, 0xb1, 0x7a, 0x15, 0x2a, 0xc0,
+  0x05, 0x37, 0x84, 0xfe, 0xd7, 0x9f, 0x30, 0xf5, 0x6d, 0xdb, 0xfc, 0x3d,
+  0x01, 0xa8, 0x0b, 0x8f, 0x2c, 0xe5, 0x8e, 0x75, 0x8f, 0x96, 0x1f, 0xe0,
+  0x41, 0xaa, 0x9c, 0xf9, 0xf7, 0xf9, 0xbb, 0xcb, 0x6d, 0x57, 0x73, 0x53,
+  0x76, 0xab, 0x8f, 0x6e, 0x95, 0xc4, 0x97, 0xb0, 0x8e, 0x0c, 0xa7, 0xa7,
+  0x89, 0x9c, 0x12, 0x84, 0x9b, 0x1c, 0x0c, 0x72, 0xb2, 0x3c, 0xd9, 0xdd,
+  0x33, 0x96, 0xd4, 0xee, 0x3e, 0x8a, 0x6f, 0x3d, 0xd9, 0x7d, 0x32, 0x64,
+  0x1b, 0xc3, 0x15, 0x51, 0x0d, 0xae, 0x05, 0xda, 0xd8, 0xa8, 0xf0, 0x8e,
+  0xf2, 0x4f, 0x82, 0xe9, 0x7d, 0xf2, 0xf1, 0x23, 0x7e, 0xd5, 0x06, 0x66,
+  0x0e, 0x6c, 0x3e, 0x83, 0xed, 0x6a, 0xfc, 0xe6, 0xf7, 0x66, 0x1c, 0x01,
+  0x98, 0x65, 0xc1, 0xb9, 0x43, 0x28, 0x6f, 0x46, 0x29, 0x70, 0x2b, 0xab,
+  0x4e, 0x34, 0xdd, 0x4c, 0x7f, 0xbf, 0xbc, 0x82, 0xd9, 0x2b, 0x34, 0x78,
+  0xfb, 0x15, 0xcd, 0xa7, 0x0b, 0x85, 0x33, 0x1e, 0x13, 0xa8, 0xb4, 0x51,
+  0x18, 0x9e, 0xec, 0x7e, 0xf4, 0x15, 0xe3, 0xd6, 0x96, 0x30, 0x97, 0x9d,
+  0x88, 0x24, 0x45, 0xe1, 0x86, 0x8e, 0x08, 0x92, 0x7f, 0x07, 0x14, 0xcf,
+  0x37, 0x87, 0x02, 0x33, 0xac, 0x7f, 0xdd, 0x97, 0x98, 0x3e, 0xff, 0xeb,
+  0x49, 0xfb, 0xae, 0xbc, 0xce, 0x8b, 0x81, 0xb6, 0xf9, 0x42, 0xfe, 0x12,
+  0xf8, 0x2b, 0x51, 0x75, 0x89, 0x94, 0x63, 0xd0, 0x1c, 0x6f, 0x5b, 0x17,
+  0x0a, 0x8c, 0x3e, 0x6a, 0xc2, 0x76, 0x4b, 0xd4, 0x14, 0x29, 0x67, 0x27,
+  0x22, 0x7a, 0xad, 0xf0, 0x18, 0xae, 0xae, 0x62, 0x61, 0x49, 0x09, 0xe4,
+  0x23, 0xf6, 0x2b, 0x7e, 0x3c, 0xdc, 0x16, 0xcb, 0x52, 0xd5, 0x38, 0x1a,
+  0xbe, 0x93, 0xeb, 0x81, 0x2b, 0x2b, 0xb3, 0x1c, 0x95, 0x3e, 0x76, 0x7a,
+  0x93, 0x1c, 0x36, 0x28, 0x8e, 0x25, 0x39, 0x36, 0x81, 0x99, 0x4a, 0x53,
+  0xd1, 0x67, 0x3b, 0x95, 0xcb, 0xce, 0x11, 0xef, 0xb3, 0x02, 0xe2, 0x5a,
+  0x73, 0xc1, 0x2e, 0x6b, 0xd0, 0x96, 0x49, 0x44, 0x3d, 0x72, 0xa7, 0x71,
+  0x34, 0x3d, 0x9c, 0x47, 0x73, 0x0e, 0xe9, 0x6a, 0x25, 0xbd, 0x5f, 0x2a,
+  0x63, 0x3d, 0xed, 0xe3, 0x6f, 0xcf, 0x76, 0x3f, 0xdb, 0x17, 0xf7, 0xe0,
+  0xc9, 0xf1, 0xe5, 0xeb, 0xae, 0x43, 0xaf, 0x32, 0xfb, 0x89, 0xff, 0x4b,
+  0xa5, 0x82, 0x6f, 0x8c, 0x81, 0x41, 0x79, 0xbf, 0x03, 0x62, 0x8e, 0x1d,
+  0xec, 0xee, 0xc6, 0x02, 0xec, 0xbf, 0x23, 0x31, 0xe9, 0x93, 0xa7, 0xed,
+  0xd8, 0x0b, 0xa9, 0xf5, 0x03, 0x9a, 0xef, 0xd5, 0xfc, 0x54, 0xbc, 0xbf,
+  0x9c, 0x8f, 0xce, 0x51, 0x18, 0xca, 0x1b, 0x5e, 0x60, 0x35, 0x82, 0x8e,
+  0x88, 0x91, 0x96, 0x77, 0xdc, 0xea, 0x02, 0x22, 0xd9, 0x62, 0x3b, 0xa2,
+  0xb9, 0xdf, 0x16, 0xae, 0xfa, 0x44, 0xea, 0xa0, 0x41, 0xc8, 0x8b, 0x15,
+  0x11, 0xcd, 0xb9, 0xab, 0x25, 0xe3, 0xa0, 0xca, 0x88, 0x3f, 0x80, 0x15,
+  0x3f, 0xe1, 0x7e, 0x7f, 0x98, 0x03, 0x01, 0x53, 0x50, 0x4d, 0x16, 0x92,
+  0x7f, 0xc2, 0xff, 0xa6, 0xab, 0xb8, 0x05, 0x74, 0xdc, 0x7f, 0x16, 0x99,
+  0x38, 0x5c, 0xd8, 0xbf, 0x60, 0xe2, 0xda, 0xf3, 0xe6, 0xd4, 0x23, 0x76,
+  0xe3, 0xc1, 0xe8, 0x95, 0x68, 0x41, 0x98, 0x9b, 0x5e, 0x6b, 0xb5, 0xa7,
+  0x5f, 0x3c, 0x16, 0x9a, 0xee, 0xe1, 0x3a, 0x2e, 0x15, 0xf7, 0xd6, 0x03,
+  0x63, 0x19, 0x59, 0xc0, 0x4b, 0x7b, 0x24, 0x7d, 0xc7, 0xe7, 0x4b, 0xf7,
+  0xc7, 0x5c, 0xca, 0x13, 0xc0, 0xdf, 0x80, 0xc8, 0x53, 0xa7, 0xb9, 0x8b,
+  0x6c, 0x91, 0x61, 0xe8, 0x7e, 0x80, 0xd9, 0xdb, 0xdc, 0xd6, 0x4e, 0x6d,
+  0xbc, 0x7a, 0xd7, 0xe6, 0x1e, 0xcd, 0x17, 0x44, 0x30, 0x56, 0x47, 0x7d,
+  0x2d, 0xed, 0x5a, 0x96, 0x98, 0x4b, 0xf5, 0xcb, 0xf6, 0xe5, 0x26, 0x93,
+  0xf7, 0x75, 0x8e, 0x2d, 0x7c, 0x27, 0xcc, 0xa7, 0x23, 0x93, 0x1d, 0x4d,
+  0xd8, 0xa5, 0x2a, 0x5d, 0x52, 0x1e, 0xb7, 0x5d, 0xc6, 0x15, 0x00, 0xbf,
+  0x17, 0x85, 0x23, 0x3c, 0x13, 0x68, 0x9a, 0xec, 0xf8, 0x64, 0xeb, 0xbb,
+  0x8b, 0xd7, 0x7f, 0xb5, 0xa9, 0xbc, 0xdb, 0xfd, 0xb8, 0x35, 0xac, 0xfd,
+  0xf5, 0x42, 0x48, 0x0e, 0xb4, 0x25, 0x09, 0xa4, 0xad, 0x89, 0x77, 0xff,
+  0x08, 0xf1, 0xbd, 0x4c, 0xd1, 0x95, 0x6c, 0x51, 0xa5, 0x41, 0xf3, 0xd4,
+  0x48, 0x8c, 0xba, 0x27, 0xc3, 0x67, 0xf0, 0x8a, 0xbc, 0x3e, 0x7a, 0xf6,
+  0x64, 0x7f, 0xcf, 0xd8, 0xad, 0x5b, 0x1d, 0x69, 0xb1, 0xfd, 0xe0, 0x30,
+  0xdb, 0xeb, 0x9d, 0x7d, 0x5c, 0xd0, 0xde, 0xdb, 0x3a, 0xfe, 0xe1, 0xfc,
+  0xad, 0x37, 0x40, 0xbb, 0x02, 0x41, 0x6e, 0xa5, 0x3f, 0x42, 0x4e, 0x6c,
+  0xb2, 0x63, 0x74, 0xb7, 0x6d, 0xb0, 0xa5, 0x38, 0x75, 0x31, 0xcc, 0x9a,
+  0xed, 0xbd, 0xae, 0x72, 0xd2, 0x73, 0x7b, 0x34, 0x1f, 0xbd, 0xd3, 0xb2,
+  0x98, 0x9a, 0xdb, 0xff, 0x8c, 0xf8, 0x26, 0xb2, 0x9e, 0x51, 0x63, 0x1f,
+  0x1c, 0xdd, 0xea, 0x63, 0xf2, 0xa6, 0x8f, 0xa3, 0x52, 0x84, 0x50, 0x84,
+  0x37, 0xf8, 0x21, 0x98, 0xbe, 0x28, 0x2f, 0x9a, 0xf3, 0x4d, 0x96, 0x64,
+  0xe7, 0x90, 0x8b, 0xb7, 0x69, 0x95, 0x5f, 0x66, 0x4d, 0x12, 0xee, 0x37,
+  0xf2, 0xfa, 0xbc, 0x80, 0x53, 0x7b, 0x55, 0x3c, 0x84, 0x47, 0xce, 0xd1,
+  0x10, 0x3c, 0xbe, 0xa5, 0x8e, 0xfd, 0x6d, 0xaf, 0x52, 0x14, 0x97, 0x50,
+  0x93, 0x70, 0x07, 0x54, 0xf5, 0x58, 0x09, 0x12, 0x3c, 0xea, 0xcc, 0x8a,
+  0xbc, 0x0d, 0x5e, 0xc6, 0x51, 0x44, 0x22, 0x69, 0xbf, 0xcd, 0xc4, 0x11,
+  0xf1, 0x83, 0x23, 0xd4, 0xcb, 0x15, 0x23, 0x8a, 0x69, 0x4b, 0xd1, 0x43,
+  0xc9, 0x61, 0xd8, 0x40, 0xa8, 0x7b, 0x0f, 0x25, 0xf1, 0xf9, 0x93, 0xd0,
+  0xa9, 0x75, 0x76, 0x79, 0x7c, 0xc0, 0x25, 0x3f, 0x6c, 0xb6, 0xb8, 0x2a,
+  0xc4, 0x0c, 0x94, 0x41, 0x41, 0x33, 0x49, 0x9b, 0xf0, 0x47, 0xd7, 0x8f,
+  0x15, 0x8f, 0x07, 0x66, 0x95, 0x36, 0x03, 0x3b, 0x35, 0x9b, 0x95, 0xac,
+  0x46, 0xc8, 0x84, 0x13, 0x15, 0x98, 0xe3, 0x6f, 0xb1, 0xc2, 0xb4, 0x57,
+  0x9c, 0x60, 0x8a, 0x9c, 0x4d, 0xbe, 0x56, 0x82, 0x89, 0x92, 0x40, 0x19,
+  0x0c, 0x0b, 0xeb, 0x4b, 0x9c, 0x50, 0xe5, 0x9b, 0xb0, 0x60, 0x0b, 0x82,
+  0x51, 0xaf, 0xa5, 0x56, 0x26, 0x14, 0xef, 0xd5, 0x65, 0xe4, 0x3d, 0x49,
+  0xee, 0x62, 0x66, 0xdd, 0xbd, 0x23, 0x56, 0x08, 0xb9, 0xbb, 0x56, 0xe5,
+  0xc7, 0xc3, 0xe1, 0x65, 0xc3, 0x68, 0xe2, 0xe5, 0xa2, 0x1d, 0xa3, 0xf6,
+  0x08, 0x99, 0x4f, 0x56, 0x17, 0x97, 0x2c, 0xef, 0x30, 0x52, 0x8b, 0x93,
+  0xde, 0xb6, 0xff, 0x9d, 0x5d, 0xa9, 0x5a, 0x09, 0x80, 0x04, 0x99, 0xab,
+  0x48, 0x2d, 0x56, 0x6c, 0x9c, 0x3d, 0x07, 0x1a, 0xa8, 0xd7, 0x89, 0x3a,
+  0xe9, 0x11, 0xdd, 0xc9, 0xb8, 0x5e, 0x56, 0xd3, 0xe5, 0xdc, 0x1c, 0x50,
+  0x1f, 0x17, 0x0d, 0x05, 0x07, 0xb6, 0x1b, 0xa0, 0x07, 0x11, 0x97, 0xf8,
+  0xb3, 0xdd, 0x56, 0x63, 0x43, 0x0c, 0xbc, 0x13, 0xd8, 0x1d, 0xec, 0xd9,
+  0x5c, 0xf5, 0x1c, 0x19, 0x60, 0x1c, 0xcd, 0xfb, 0x1d, 0x63, 0x2a, 0xf3,
+  0xbe, 0xac, 0x14, 0xa3, 0xab, 0xe8, 0xbf, 0x5f, 0x04, 0x12, 0x83, 0xd7,
+  0x06, 0x4f, 0xe4, 0x85, 0xa2, 0x66, 0x58, 0x23, 0x20, 0xb7, 0x11, 0xbb,
+  0xba, 0x70, 0x70, 0xef, 0x6e, 0x4a, 0x54, 0xef, 0xb1, 0xa1, 0xde, 0xd0,
+  0x6c, 0x21, 0x73, 0x7c, 0xe8, 0x91, 0x2f, 0x7b, 0x59, 0x10, 0xb2, 0x36,
+  0x34, 0xf1, 0xf0, 0x2e, 0x8d, 0x29, 0xc3, 0x2d, 0xf9, 0x5b, 0x39, 0x16,
+  0xac, 0x1d, 0x99, 0x49, 0xb1, 0x74, 0xf7, 0x2b, 0x40, 0x7a, 0x97, 0x66,
+  0xa3, 0x49, 0xbd, 0x7b, 0x0a, 0x50, 0x26, 0x02, 0x0e, 0xe5, 0x4a, 0x5d,
+  0xe4, 0xde, 0x4f, 0xae, 0x41, 0x7e, 0xc2, 0xe8, 0x34, 0x25, 0x19, 0x0c,
+  0x53, 0xb6, 0xf6, 0xbb, 0x29, 0xcd, 0xe9, 0x84, 0x6c, 0x7f, 0xd3, 0xb8,
+  0xa4, 0x0f, 0x42, 0xf4, 0xd4, 0x0e, 0x43, 0x9b, 0x4e, 0x9a, 0xa5, 0xcc,
+  0x7a, 0xb7, 0x77, 0xa5, 0xba, 0x03, 0xcd, 0xbb, 0xe0, 0xef, 0x03, 0x63,
+  0xce, 0xc4, 0x6c, 0xbe, 0x74, 0x72, 0xaf, 0xd7, 0xa2, 0xbb, 0x43, 0xa8,
+  0x89, 0x72, 0xe9, 0xb1, 0xfd, 0x05, 0x83, 0xb5, 0x9d, 0xa0, 0xd8, 0x5e,
+  0x5e, 0xaf, 0x60, 0xdb, 0xfd, 0x4d, 0x35, 0x72, 0x9f, 0x33, 0x9d, 0x1d,
+  0xac, 0x03, 0xe9, 0x67, 0xeb, 0xb4, 0x67, 0x4d, 0x4a, 0xb3, 0x1c, 0x2d,
+  0xdd, 0xae, 0x18, 0x48, 0x98, 0x65, 0x2d, 0xf3, 0x97, 0xa3, 0x60, 0x20,
+  0x44, 0x25, 0xd8, 0x3f, 0xc2, 0xbe, 0x4a, 0x18, 0x7e, 0x12, 0xde, 0x98,
+  0x6f, 0xe4, 0x2b, 0x52, 0x05, 0x13, 0xf2, 0x4a, 0x73, 0x2a, 0xd8, 0xa0,
+  0x7a, 0x9a, 0x6c, 0x91, 0x9d, 0x93, 0x3c, 0xfb, 0xf4, 0xd9, 0xd3, 0x6d,
+  0x29, 0xac, 0x62, 0x81, 0x51, 0xdb, 0xb1, 0x0a, 0x0e, 0x38, 0x6e, 0xc2,
+  0x8a, 0x89, 0x4b, 0x2c, 0xa7, 0x3a, 0x26, 0x1c, 0x81, 0x12, 0x27, 0x5e,
+  0xce, 0xa4, 0xe7, 0xe4, 0x4e, 0x46, 0xf9, 0x00, 0x2d, 0x2f, 0xdd, 0x6d,
+  0xce, 0x7c, 0x2c, 0xe3, 0x97, 0x6d, 0x81, 0x4e, 0x2b, 0xbf, 0x5d, 0xb2,
+  0x02, 0x73, 0x32, 0x42, 0x1d, 0x51, 0x5a, 0xc6, 0x6d, 0xa4, 0xe1, 0x45,
+  0xd1, 0x1a, 0xec, 0x5a, 0xe2, 0x8a, 0xea, 0x7c, 0x3d, 0xde, 0x50, 0x01,
+  0xbd, 0xd2, 0xbb, 0x1a, 0xd8, 0x09, 0xc0, 0xe9, 0x26, 0x7c, 0xf7, 0xc4,
+  0xf8, 0xc5, 0x8c, 0x5e, 0x8a, 0x98, 0x34, 0xdd, 0x65, 0xed, 0x79, 0x64,
+  0xbe, 0x1a, 0xda, 0x29, 0xfa, 0xbe, 0xc0, 0x81, 0x64, 0x4d, 0xa2, 0xc9,
+  0x8d, 0xf3, 0x6c, 0xae, 0xec, 0xde, 0x7c, 0xc9, 0x96, 0x95, 0xab, 0xcc,
+  0xcb, 0xf1, 0x08, 0xbe, 0x31, 0x01, 0x61, 0x5c, 0x95, 0x9d, 0xae, 0x16,
+  0x7f, 0xaa, 0x59, 0xb4, 0xad, 0x9e, 0xad, 0x84, 0xdc, 0xeb, 0x6e, 0xd3,
+  0x7c, 0xf5, 0x2e, 0xd2, 0x5e, 0xff, 0x6e, 0x77, 0x65, 0x98, 0x64, 0xc3,
+  0x5f, 0xed, 0x4c, 0xc4, 0x8a, 0xde, 0x73, 0x71, 0x5a, 0x90, 0xcb, 0xc0,
+  0x5f, 0x30, 0x08, 0x49, 0x32, 0x92, 0x2d, 0x74, 0x78, 0x67, 0x67, 0xfb,
+  0xe1, 0x4e, 0xcb, 0x93, 0x0f, 0x75, 0xf2, 0x9c, 0x8d, 0xf8, 0xc2, 0xaf,
+  0xc9, 0xe8, 0xfa, 0x40, 0xdf, 0xa4, 0x15, 0x63, 0xb2, 0x4e, 0xc6, 0x39,
+  0x32, 0x4c, 0x84, 0xb4, 0x08, 0x4a, 0x9b, 0x0c, 0xef, 0x20, 0x76, 0x89,
+  0xa4, 0x32, 0xc0, 0xf6, 0xd8, 0xc5, 0xbc, 0x63, 0xce, 0x1b, 0x11, 0x21,
+  0x84, 0x03, 0x02, 0x09, 0xc9, 0xa1, 0xd9, 0x84, 0xa1, 0x66, 0xe5, 0xba,
+  0xe5, 0x0d, 0x0e, 0xc6, 0x5c, 0xc7, 0xa9, 0x8c, 0x53, 0xa8, 0xb4, 0xe2,
+  0xec, 0x7e, 0x8e, 0xc0, 0xb5, 0xf5, 0x69, 0x95, 0x46, 0x52, 0xf8, 0x6e,
+  0x18, 0xd0, 0x58, 0xf1, 0x93, 0xae, 0xf8, 0x5a, 0x84, 0x04, 0xd3, 0x77,
+  0x07, 0x4a, 0x83, 0x46, 0xa2, 0x7e, 0x70, 0x63, 0x66, 0x12, 0x29, 0x2e,
+  0xb0, 0x27, 0x05, 0x15, 0xac, 0x6f, 0x3b, 0xad, 0x42, 0x0f, 0x33, 0xfa,
+  0x66, 0xf7, 0x37, 0x66, 0x8c, 0xd3, 0xd5, 0xc7, 0xfc, 0xd3, 0xd6, 0x64,
+  0xf6, 0xf9, 0x8c, 0x22, 0x51, 0x3c, 0xa6, 0x95, 0xa2, 0xea, 0x45, 0x98,
+  0x8e, 0x6a, 0xe7, 0x70, 0x2d, 0xde, 0xcc, 0x02, 0xce, 0xd8, 0xa5, 0xc9,
+  0x90, 0xb3, 0xf0, 0x9e, 0x55, 0xa7, 0x92, 0x36, 0xda, 0xb6, 0xaa, 0x3f,
+  0x69, 0x5b, 0xd5, 0x36, 0xb5, 0x36, 0xae, 0xa4, 0x1d, 0x4b, 0x01, 0xf3,
+  0xb7, 0xfa, 0x98, 0x31, 0xb2, 0xcf, 0xdf, 0x1e, 0x7f, 0x7d, 0xb6, 0xfd,
+  0x90, 0x37, 0xae, 0x2d, 0xff, 0xed, 0xb8, 0x00, 0x3f, 0xab, 0x08, 0xbe,
+  0xc6, 0xdd, 0x87, 0x1e, 0xfe, 0xf5, 0x68, 0x34, 0x38, 0x3c, 0x3f, 0x41,
+  0x95, 0x92, 0x91, 0xf9, 0x73, 0x05, 0x85, 0xde, 0x10, 0x0c, 0x8e, 0x83,
+  0xef, 0x24, 0x9d, 0xad, 0x16, 0x35, 0x23, 0x81, 0xb7, 0x0b, 0x28, 0x0c,
+  0xa6, 0x18, 0xe2, 0x39, 0xb2, 0xc9, 0xc9, 0x68, 0xbe, 0x6b, 0x40, 0x9d,
+  0x9f, 0xec, 0xe0, 0x53, 0xf4, 0x49, 0x0c, 0x28, 0x6e, 0x28, 0x87, 0x5c,
+  0xf9, 0x4c, 0xe1, 0xe1, 0xca, 0x8d, 0x2a, 0x3e, 0xd5, 0x98, 0x39, 0x74,
+  0x9d, 0xb8, 0xe0, 0x54, 0x3c, 0x1b, 0x80, 0x9c, 0x3e, 0x04, 0xf7, 0x16,
+  0x56, 0xcf, 0xae, 0x97, 0x09, 0xc6, 0x08, 0xf3, 0xc7, 0x50, 0xb9, 0x49,
+  0x73, 0x05, 0x0b, 0xc2, 0xa9, 0x6b, 0xfe, 0x6f, 0x0e, 0x96, 0x49, 0x72,
+  0xb0, 0xc9, 0x68, 0xca, 0xac, 0x28, 0x97, 0xd7, 0x37, 0xa0, 0x8c, 0xe9,
+  0x98, 0xdb, 0x90, 0xe5, 0x1a, 0x69, 0xb4, 0x94, 0x9b, 0xa6, 0x93, 0xc1,
+  0x16, 0xc4, 0x3b, 0xaa, 0xf7, 0x54, 0x19, 0x05, 0x42, 0x58, 0xbd, 0x61,
+  0x9c, 0xcb, 0xf4, 0x5f, 0x42, 0x5c, 0xb7, 0x46, 0x03, 0x19, 0x73, 0x90,
+  0x10, 0x0e, 0xa3, 0xa2, 0x99, 0xcd, 0xe5, 0xaf, 0x69, 0x71, 0x0f, 0xc7,
+  0xa0, 0x78, 0xaa, 0x91, 0x92, 0x66, 0xf7, 0x74, 0x7b, 0xa3, 0x37, 0xd5,
+  0x84, 0x4b, 0xc1, 0xbe, 0xd0, 0xc2, 0xb3, 0x5f, 0xac, 0xdd, 0xb3, 0xa8,
+  0x3e, 0xa8, 0xa5, 0x9c, 0x93, 0x41, 0xd1, 0xd7, 0x56, 0xfa, 0xc6, 0x70,
+  0x94, 0xa0, 0x90, 0x28, 0xc2, 0xb2, 0x09, 0x22, 0xa2, 0x08, 0x25, 0x3c,
+  0xb6, 0x8c, 0xed, 0x50, 0xce, 0x96, 0x5c, 0x0a, 0x97, 0xdc, 0x7f, 0x84,
+  0xf7, 0xdf, 0x76, 0xdc, 0xd5, 0x68, 0x55, 0x21, 0x8d, 0x0c, 0x92, 0x3d,
+  0x0a, 0xa1, 0xc9, 0xae, 0xbc, 0xcc, 0xd0, 0x85, 0x14, 0x38, 0x66, 0x26,
+  0x96, 0x38, 0xcd, 0x2c, 0xb7, 0x85, 0xa6, 0x16, 0x00, 0xe1, 0xdc, 0x96,
+  0xf1, 0x2a, 0x87, 0x54, 0x23, 0x5d, 0xd6, 0xaa, 0x35, 0x3b, 0xea, 0x49,
+  0x26, 0xd1, 0xed, 0x57, 0xb4, 0xf2, 0xb4, 0xc6, 0x68, 0x7a, 0xca, 0x2a,
+  0x5c, 0xae, 0x86, 0xc5, 0xc7, 0x74, 0x4a, 0xc6, 0xf7, 0xf6, 0x63, 0xfc,
+  0x9d, 0x14, 0xc0, 0x15, 0xab, 0x08, 0x3f, 0x96, 0x1f, 0xc2, 0x2d, 0xc6,
+  0x70, 0x1d, 0xf0, 0xa2, 0xfd, 0xa5, 0x4e, 0xd3, 0xdf, 0xa1, 0xe6, 0x8c,
+  0x2e, 0x31, 0x56, 0xa3, 0xb5, 0xc8, 0xac, 0xe5, 0x77, 0x8b, 0x12, 0xd0,
+  0x44, 0x0c, 0xf1, 0x44, 0xb0, 0x81, 0x29, 0x68, 0x6c, 0x47, 0xa5, 0xea,
+  0x11, 0x79, 0x96, 0x52, 0x2e, 0x87, 0xc2, 0x2f, 0x7b, 0xdf, 0xb0, 0xd9,
+  0x09, 0xe5, 0xfa, 0x8a, 0x45, 0x6e, 0x75, 0x86, 0x8f, 0x98, 0x10, 0x37,
+  0x7e, 0xf7, 0xc3, 0xc0, 0xb2, 0xb3, 0x91, 0xd1, 0x7a, 0x22, 0xd4, 0x36,
+  0x43, 0xd9, 0x85, 0x5b, 0xef, 0xe5, 0x2f, 0x74, 0x06, 0xbe, 0xcf, 0x0b,
+  0xa3, 0x19, 0xd6, 0xdb, 0xba, 0x39, 0x05, 0x8a, 0x15, 0x9e, 0xdd, 0x6a,
+  0xb3, 0x36, 0x96, 0x98, 0x91, 0x38, 0x0e, 0x96, 0x46, 0x8a, 0x33, 0x07,
+  0x27, 0x02, 0x51, 0xe4, 0x15, 0xa6, 0xb9, 0x5f, 0x04, 0x90, 0xfe, 0x89,
+  0x15, 0x3a, 0x68, 0x03, 0x0c, 0x7f, 0xc6, 0x2c, 0x28, 0xf2, 0x8f, 0x2e,
+  0x98, 0x8d, 0x7b, 0x83, 0x53, 0xf2, 0x9d, 0x6f, 0xc7, 0x08, 0xc2, 0x48,
+  0xb5, 0x45, 0x48, 0xb6, 0x6e, 0xb4, 0x86, 0x66, 0x17, 0xe3, 0xdc, 0x7a,
+  0xb6, 0x9d, 0x5c, 0x35, 0x8b, 0xad, 0xbd, 0x6d, 0x66, 0x0a, 0x97, 0x7a,
+  0x77, 0xa5, 0xbb, 0xee, 0x43, 0x47, 0x0e, 0x21, 0xe9, 0x70, 0x42, 0x1d,
+  0x55, 0x33, 0x8a, 0xca, 0x90, 0xeb, 0x12, 0x3a, 0x05, 0x9d, 0x60, 0xa9,
+  0x3a, 0xad, 0x05, 0xb4, 0x00, 0xda, 0x8d, 0x39, 0x50, 0x81, 0x70, 0x59,
+  0x10, 0xfd, 0x19, 0x92, 0xad, 0x28, 0xc2, 0x60, 0x9d, 0xbf, 0x42, 0xe2,
+  0x2e, 0xd9, 0x98, 0x66, 0xe6, 0x66, 0xd3, 0x01, 0xc9, 0x90, 0xeb, 0xaa,
+  0x34, 0x57, 0x64, 0x15, 0x21, 0x89, 0x12, 0x9b, 0x82, 0x54, 0xfd, 0xac,
+  0xb8, 0xcd, 0xab, 0xb2, 0x00, 0x0f, 0xd7, 0x6d, 0x5a, 0xe5, 0x08, 0x6a,
+  0xf7, 0xbe, 0x39, 0x7b, 0x73, 0xdc, 0xf3, 0xfd, 0x22, 0x57, 0xb9, 0x78,
+  0x8c, 0xb1, 0x7e, 0x5d, 0x7f, 0xac, 0xae, 0x66, 0x18, 0xae, 0xa1, 0x92,
+  0xe0, 0x54, 0x11, 0xc1, 0x26, 0x35, 0xf3, 0x61, 0x42, 0x3e, 0xad, 0x46,
+  0x84, 0x8d, 0x3a, 0x29, 0x31, 0x6f, 0xa9, 0x8d, 0xa1, 0xbb, 0x2c, 0x04,
+  0x9c, 0xc0, 0x95, 0xa0, 0xc6, 0x21, 0xa8, 0x8b, 0x4b, 0xbf, 0x3a, 0x43,
+  0xe2, 0x55, 0x70, 0x20, 0x45, 0x9f, 0x37, 0x00, 0x96, 0x36, 0x06, 0x02,
+  0xdf, 0x9c, 0xdf, 0x93, 0x65, 0xb3, 0xd9, 0xbe, 0x00, 0x37, 0x6b, 0x32,
+  0xc6, 0x9b, 0x4d, 0x9d, 0x5e, 0x80, 0x23, 0x9d, 0x8c, 0x0f, 0x2b, 0x66,
+  0xad, 0xf8, 0x36, 0xef, 0x6a, 0xfe, 0x84, 0x6b, 0x9d, 0x1b, 0x77, 0xa7,
+  0xef, 0x80, 0x4f, 0x5f, 0x50, 0x7b, 0x35, 0xa4, 0xe4, 0x48, 0x5d, 0xce,
+  0x4a, 0xbb, 0xd8, 0x56, 0x3b, 0x70, 0x4e, 0xc4, 0xa0, 0xa1, 0x63, 0xd1,
+  0x7c, 0xbe, 0x9c, 0x08, 0x39, 0x8a, 0x8d, 0x20, 0xca, 0x55, 0x26, 0x09,
+  0xf6, 0x8c, 0x2f, 0x66, 0x4d, 0xa9, 0xf0, 0x4a, 0xef, 0x24, 0xd4, 0xe4,
+  0x0a, 0x56, 0x2e, 0x73, 0x75, 0x03, 0x34, 0x64, 0xf9, 0xbd, 0x80, 0xbf,
+  0x24, 0x87, 0xa7, 0x85, 0x12, 0xca, 0xd7, 0xfa, 0x7e, 0x96, 0x67, 0x50,
+  0xd4, 0x4f, 0xac, 0x61, 0x87, 0xbd, 0xb0, 0xca, 0x09, 0xb3, 0xd5, 0x31,
+  0xdf, 0x99, 0x25, 0xb2, 0x51, 0xce, 0xb7, 0x50, 0x49, 0xb6, 0xd3, 0xa9,
+  0x7e, 0x5c, 0xa2, 0x16, 0x23, 0x18, 0x0a, 0xdb, 0x34, 0x36, 0xc4, 0xcb,
+  0xec, 0x01, 0xd0, 0x3a, 0x88, 0x38, 0x96, 0x86, 0x49, 0x84, 0x94, 0x51,
+  0x13, 0xdb, 0x1e, 0x4a, 0x33, 0x36, 0x76, 0xee, 0x50, 0x9e, 0xff, 0x2d,
+  0xb2, 0xf1, 0x84, 0x3b, 0x9d, 0xd1, 0xb0, 0x6e, 0x51, 0xe2, 0xd0, 0x00,
+  0x08, 0x76, 0xd7, 0x43, 0x42, 0x2a, 0x56, 0x4b, 0xa1, 0xdd, 0xfe, 0x9a,
+  0x7b, 0x61, 0x3b, 0x68, 0xcd, 0x1d, 0x22, 0x66, 0x60, 0x55, 0x36, 0xc0,
+  0xa5, 0x97, 0x35, 0x18, 0xe6, 0x9a, 0x2a, 0x9d, 0xb8, 0xbf, 0x0c, 0xd2,
+  0x7a, 0x92, 0xe7, 0xca, 0xc5, 0x4d, 0xe1, 0xb0, 0x8c, 0x10, 0xa0, 0x51,
+  0xde, 0x0e, 0xbb, 0x1e, 0x89, 0xe5, 0xc0, 0x9d, 0x96, 0xec, 0xe6, 0x65,
+  0x90, 0x05, 0x97, 0x2a, 0x05, 0x64, 0x83, 0x3c, 0x53, 0x1a, 0x2b, 0x8b,
+  0xd1, 0x93, 0x2b, 0x93, 0xd7, 0x0a, 0xfb, 0xd6, 0x98, 0xe0, 0x7b, 0xbe,
+  0x0d, 0xae, 0x93, 0x30, 0xa0, 0x5a, 0x37, 0x75, 0xc3, 0xf6, 0xe4, 0xdd,
+  0xdd, 0xfe, 0x70, 0x4d, 0xfd, 0x51, 0x3f, 0xe0, 0xf1, 0xbc, 0x63, 0xa1,
+  0x30, 0x0b, 0x4d, 0xcc, 0x3e, 0x19, 0x6d, 0xb7, 0xea, 0x96, 0x1c, 0x9e,
+  0x9e, 0xbf, 0x4d, 0x40, 0xfd, 0xc3, 0x75, 0xae, 0x6b, 0x2e, 0x5d, 0xc0,
+  0x3f, 0x66, 0x3d, 0x19, 0x16, 0x73, 0x12, 0xc2, 0x1b, 0x95, 0x16, 0x1d,
+  0x56, 0x44, 0x98, 0xd7, 0xc3, 0x78, 0xae, 0x02, 0xf4, 0x17, 0x6a, 0xbf,
+  0x40, 0xca, 0xab, 0x91, 0xd1, 0x1d, 0x8e, 0xf9, 0xe4, 0x90, 0x3f, 0xac,
+  0x92, 0x16, 0x35, 0xa8, 0xb5, 0xe5, 0xd6, 0xbb, 0x96, 0xfc, 0xa8, 0x54,
+  0xa6, 0xa3, 0x40, 0xa8, 0x37, 0x99, 0xa5, 0x58, 0x12, 0xe3, 0xce, 0x52,
+  0x86, 0x29, 0xfb, 0x38, 0x83, 0x12, 0x90, 0x50, 0xaf, 0x79, 0xbb, 0xf5,
+  0xfa, 0x4c, 0x6b, 0x33, 0xb1, 0xc5, 0xa2, 0x08, 0x12, 0xad, 0xed, 0x8c,
+  0x47, 0xb2, 0x9f, 0x02, 0x64, 0xed, 0xa3, 0x72, 0xa1, 0x68, 0x49, 0x86,
+  0x6b, 0x96, 0xf8, 0x6d, 0x9f, 0x3f, 0x3a, 0x5e, 0x92, 0x8c, 0xe8, 0x96,
+  0x5e, 0xe6, 0x05, 0x66, 0xdd, 0x89, 0x9f, 0xa0, 0xef, 0x89, 0x17, 0x8c,
+  0xf9, 0x5d, 0x88, 0x78, 0x2a, 0x4b, 0xe7, 0x46, 0x3b, 0x28, 0x14, 0x1d,
+  0x4f, 0x0e, 0x60, 0xc2, 0x30, 0x76, 0xa7, 0x92, 0xab, 0xdb, 0xd7, 0xfd,
+  0x76, 0x21, 0x8b, 0x0e, 0x68, 0x9e, 0x3f, 0x43, 0xa0, 0x19, 0xbf, 0xf9,
+  0x58, 0x22, 0x14, 0x5e, 0xb7, 0xf9, 0xd8, 0x12, 0xc1, 0xd1, 0xd2, 0x2d,
+  0x4c, 0xb2, 0xc9, 0x4d, 0xd8, 0x22, 0x6e, 0x66, 0x02, 0x26, 0x37, 0xcb,
+  0xe2, 0x83, 0xe9, 0x42, 0x98, 0xa8, 0xa9, 0xf8, 0xd6, 0x9c, 0xa4, 0x17,
+  0x4a, 0x1f, 0xd1, 0x5f, 0xb8, 0x8c, 0x96, 0x6d, 0x81, 0xf8, 0x3d, 0x6f,
+  0xc9, 0x9f, 0x17, 0x56, 0xcf, 0x8c, 0xf5, 0x6e, 0x6a, 0x4f, 0x48, 0xda,
+  0xb8, 0x09, 0x8c, 0x62, 0xb8, 0x75, 0x9d, 0x5d, 0xcd, 0x40, 0xb3, 0x1f,
+  0x3d, 0xf4, 0x90, 0xb0, 0x98, 0x28, 0xb5, 0x0d, 0xd2, 0x70, 0x14, 0x75,
+  0x13, 0x08, 0xc4, 0x65, 0xcd, 0xa9, 0x4f, 0xb2, 0xac, 0x60, 0x95, 0xf0,
+  0x98, 0xc3, 0x23, 0x3d, 0x69, 0x67, 0x0d, 0xaf, 0xda, 0x07, 0x36, 0xd5,
+  0x02, 0xb1, 0x22, 0x97, 0x64, 0x2c, 0xd0, 0x0b, 0xab, 0xba, 0x51, 0x79,
+  0x1f, 0xbf, 0xac, 0x48, 0x44, 0x72, 0xb9, 0xfc, 0xa5, 0xac, 0xb0, 0x9b,
+  0x6c, 0x4e, 0x47, 0x55, 0xe4, 0xc1, 0xbf, 0x70, 0x96, 0xdc, 0x40, 0xbc,
+  0x89, 0xb2, 0x3f, 0xec, 0x4c, 0x52, 0xf1, 0x28, 0x79, 0xf8, 0xd6, 0x88,
+  0x1f, 0x92, 0x86, 0x9e, 0x30, 0x7c, 0xcb, 0x12, 0x49, 0x05, 0xa1, 0x1b,
+  0x69, 0xd7, 0xed, 0x75, 0xf5, 0x6b, 0xa4, 0x20, 0x35, 0x4f, 0x98, 0xf2,
+  0xf3, 0xb7, 0xdd, 0xe6, 0x6c, 0xd5, 0xbf, 0x31, 0x20, 0x26, 0x0f, 0xc9,
+  0x41, 0x6b, 0xc1, 0xcb, 0xcf, 0x56, 0x78, 0xb8, 0x7e, 0xbd, 0x10, 0x6c,
+  0x33, 0x9c, 0xc5, 0x65, 0x60, 0xd1, 0x12, 0x81, 0x8e, 0xff, 0xee, 0xf7,
+  0x11, 0x82, 0xf4, 0x45, 0xe9, 0x72, 0x3e, 0x8d, 0x66, 0x97, 0xdb, 0xb5,
+  0x95, 0xba, 0x3e, 0x12, 0xb9, 0xa0, 0xd5, 0x50, 0x5e, 0x8b, 0x93, 0x57,
+  0x66, 0x93, 0x91, 0xce, 0x7a, 0x6d, 0x06, 0xf1, 0xd5, 0xaa, 0xc5, 0x45,
+  0xfd, 0x50, 0x0d, 0xef, 0xc2, 0xce, 0xa7, 0x52, 0xa9, 0x3e, 0xe5, 0x10,
+  0x71, 0x90, 0x0d, 0xbd, 0xcd, 0xce, 0x29, 0x70, 0xca, 0xd7, 0xbe, 0x82,
+  0x15, 0x3b, 0x03, 0x93, 0x12, 0xe5, 0x98, 0x26, 0x37, 0x4b, 0x22, 0x27,
+  0xa3, 0x2b, 0x8f, 0x4b, 0x89, 0x09, 0x2d, 0x7d, 0x95, 0x51, 0x9f, 0xdb,
+  0x1d, 0x0e, 0x48, 0xb4, 0xd8, 0x9b, 0x5d, 0x67, 0xe6, 0x20, 0x72, 0x82,
+  0xcc, 0xb8, 0x2a, 0x3f, 0x64, 0xbc, 0xeb, 0x60, 0x5e, 0x80, 0x15, 0x86,
+  0x75, 0x29, 0x71, 0xca, 0x1a, 0x39, 0x37, 0xb5, 0x38, 0xbd, 0x88, 0x3e,
+  0x4b, 0x15, 0x46, 0x24, 0x9d, 0xdc, 0x49, 0xc3, 0xdc, 0x65, 0x73, 0x2b,
+  0xeb, 0x31, 0x2f, 0xd7, 0x84, 0x48, 0xa8, 0xe2, 0x27, 0xdf, 0x6e, 0x02,
+  0x29, 0x41, 0xbb, 0xea, 0xf0, 0xfb, 0x67, 0x5f, 0x3c, 0x35, 0xab, 0x4f,
+  0xbe, 0x5d, 0x75, 0xff, 0xe4, 0x47, 0x56, 0xf4, 0xf1, 0x85, 0x43, 0xcc,
+  0x5e, 0x82, 0x27, 0x2c, 0x79, 0x61, 0x36, 0x15, 0xfb, 0xc4, 0x28, 0xa6,
+  0xd5, 0x75, 0x77, 0xa1, 0x00, 0xce, 0x40, 0x4d, 0x8f, 0xa9, 0x64, 0x5e,
+  0x5d, 0x49, 0x2a, 0x02, 0x63, 0xf9, 0xa7, 0xae, 0x24, 0x95, 0xd0, 0x0d,
+  0xf7, 0x59, 0x49, 0x32, 0x3b, 0x26, 0x72, 0xc8, 0x9d, 0x23, 0x87, 0x53,
+  0x3f, 0xa1, 0x87, 0xd3, 0xf2, 0x80, 0x50, 0x24, 0xaf, 0x9d, 0xa2, 0xf9,
+  0x67, 0x02, 0xbf, 0x1a, 0xad, 0xb6, 0x21, 0xe4, 0x13, 0xbe, 0x15, 0xa8,
+  0x9d, 0x5c, 0x0a, 0xc2, 0x26, 0x47, 0x30, 0xe7, 0x81, 0xe5, 0xcb, 0xa0,
+  0x92, 0x60, 0xbe, 0x6e, 0xc0, 0x5c, 0xc8, 0xc9, 0x31, 0x19, 0x2d, 0x11,
+  0x8b, 0x90, 0x3d, 0x17, 0xd4, 0x47, 0x0c, 0x13, 0x89, 0xa8, 0xf8, 0x02,
+  0x40, 0x4a, 0x62, 0x61, 0xa7, 0x0a, 0x40, 0xe2, 0xc1, 0xfb, 0x3c, 0x5e,
+  0x91, 0xba, 0x83, 0x8c, 0xf0, 0x11, 0x33, 0x4d, 0x7f, 0x60, 0x6b, 0x40,
+  0xbc, 0xf6, 0x8c, 0xa2, 0x84, 0x8d, 0x14, 0x68, 0xc7, 0x9c, 0x2b, 0x1b,
+  0x1b, 0x6c, 0xe2, 0x3d, 0xe6, 0xbf, 0x72, 0xf0, 0xe9, 0xae, 0x66, 0x76,
+  0x53, 0xb8, 0xcb, 0x7f, 0x06, 0x95, 0x4d, 0x43, 0x3d, 0x82, 0x1e, 0x33,
+  0x3f, 0xb5, 0x4f, 0x86, 0x32, 0x50, 0x18, 0xfd, 0x9e, 0x3d, 0xa1, 0x98,
+  0x77, 0xdc, 0xa7, 0xc4, 0x17, 0xad, 0xef, 0x45, 0xb0, 0x6e, 0x84, 0x3a,
+  0xca, 0x0d, 0x3a, 0xf5, 0xee, 0x1e, 0x59, 0x8d, 0x13, 0x89, 0x97, 0x6e,
+  0xd6, 0x5c, 0xae, 0x35, 0xe2, 0x91, 0x98, 0xe6, 0x75, 0xc4, 0x89, 0xc1,
+  0x98, 0x2d, 0xd9, 0x70, 0xb6, 0x8a, 0x07, 0x6a, 0x46, 0xf0, 0xd6, 0xc6,
+  0x2a, 0x9a, 0x03, 0xd3, 0x03, 0xe5, 0xbb, 0x2d, 0x51, 0x9b, 0xaf, 0x4d,
+  0xcc, 0xda, 0xfb, 0x6c, 0xf8, 0xb4, 0x75, 0x4e, 0x9a, 0xd9, 0x7c, 0x70,
+  0x37, 0x7e, 0x20, 0xf6, 0x71, 0x79, 0xfa, 0x26, 0x99, 0x2f, 0x51, 0x25,
+  0x53, 0x18, 0x4a, 0xef, 0x67, 0x99, 0xba, 0xa1, 0xc9, 0xc1, 0xc3, 0xbe,
+  0x42, 0xe2, 0x1b, 0x45, 0x47, 0x62, 0xc0, 0xa6, 0x8e, 0x9f, 0xdf, 0xa5,
+  0x4a, 0x8a, 0xdd, 0xaf, 0x74, 0x5c, 0xa6, 0x49, 0xf6, 0x67, 0x2f, 0x16,
+  0xb3, 0x3c, 0x9a, 0xcd, 0xa2, 0x60, 0xd2, 0xec, 0x63, 0x36, 0x59, 0x22,
+  0x4e, 0x4d, 0xea, 0x21, 0xb1, 0xdb, 0xac, 0x77, 0xa0, 0x7b, 0x4e, 0x73,
+  0x71, 0x93, 0x9b, 0x1f, 0x74, 0x27, 0xa3, 0x3b, 0x76, 0x1e, 0x7c, 0xe0,
+  0x3d, 0x63, 0xf2, 0xbc, 0xd8, 0xef, 0x82, 0x58, 0x31, 0x30, 0xec, 0x74,
+  0x21, 0x9a, 0x2d, 0x95, 0x5f, 0x17, 0xac, 0x74, 0xbc, 0xc9, 0x27, 0x55,
+  0x59, 0x97, 0x57, 0x0c, 0xce, 0xf2, 0x4c, 0xa4, 0x93, 0x93, 0x51, 0x72,
+  0x97, 0x8d, 0x35, 0x19, 0x74, 0x18, 0x3a, 0x93, 0x21, 0x43, 0x28, 0x42,
+  0x52, 0xe5, 0x59, 0x43, 0x53, 0xa6, 0x31, 0x51, 0xa2, 0xaf, 0x41, 0x79,
+  0xda, 0x41, 0x56, 0x5c, 0x1b, 0x6b, 0x15, 0x0a, 0x3c, 0x15, 0x66, 0x99,
+  0xf1, 0xc5, 0xb4, 0xc8, 0xca, 0x48, 0x60, 0x9c, 0x3b, 0xa0, 0xd7, 0x0a,
+  0xef, 0x13, 0xdc, 0xe1, 0xe3, 0x54, 0x6a, 0x8c, 0xb0, 0x77, 0xc0, 0x88,
+  0x1d, 0xd2, 0x51, 0xc4, 0x71, 0xf9, 0x81, 0x7c, 0x66, 0x41, 0x82, 0x86,
+  0xad, 0x7b, 0xdf, 0xf1, 0xde, 0x15, 0xd3, 0xb2, 0x02, 0x1a, 0xc9, 0x63,
+  0xff, 0x47, 0xdd, 0x96, 0x65, 0x85, 0x8c, 0x43, 0x50, 0x2b, 0x86, 0xf2,
+  0xf4, 0xee, 0x86, 0xe3, 0xb6, 0xba, 0x0a, 0x74, 0x39, 0x21, 0xb9, 0x94,
+  0xb3, 0x59, 0x84, 0x60, 0x9a, 0xfa, 0xef, 0xae, 0x1b, 0x6f, 0x35, 0xa2,
+  0x34, 0x6c, 0xb2, 0x1e, 0x2e, 0x93, 0x52, 0xdc, 0x33, 0xaf, 0xf2, 0xeb,
+  0x15, 0xc5, 0x89, 0x2c, 0x9f, 0x01, 0x2e, 0x27, 0x9c, 0x58, 0xf4, 0x46,
+  0xae, 0xcc, 0x8a, 0xcf, 0x68, 0x12, 0xd4, 0xdc, 0x8a, 0x55, 0xfe, 0xe6,
+  0xfb, 0x2e, 0xb6, 0xfb, 0xbc, 0x5c, 0xf8, 0xdf, 0xba, 0x5e, 0xf4, 0xca,
+  0x23, 0xd1, 0xee, 0x8a, 0x3d, 0x01, 0x31, 0x95, 0xcf, 0xd7, 0xf2, 0x02,
+  0xde, 0x05, 0x2f, 0x26, 0x1b, 0x57, 0xfa, 0x56, 0xd1, 0xdc, 0x22, 0xa4,
+  0x15, 0x01, 0xa6, 0x78, 0x51, 0xd9, 0xa9, 0xad, 0xcc, 0x49, 0xeb, 0xd3,
+  0x8e, 0x79, 0xf9, 0x67, 0xb7, 0xa4, 0x1f, 0xec, 0x0f, 0xc6, 0x59, 0x4a,
+  0x05, 0x09, 0x5e, 0x34, 0xa4, 0x31, 0xfd, 0xa2, 0x6c, 0x8c, 0xaf, 0xf8,
+  0xcd, 0x4b, 0xa8, 0x5a, 0xb4, 0xb6, 0x67, 0x87, 0xef, 0x2e, 0xbf, 0x49,
+  0x92, 0x7d, 0x62, 0xbd, 0x7e, 0x4c, 0x36, 0x06, 0x44, 0x42, 0xab, 0x15,
+  0x3d, 0xd6, 0x74, 0xa2, 0xca, 0xe2, 0x6f, 0xcb, 0xa2, 0x4d, 0x76, 0x1e,
+  0xf3, 0xd2, 0xe3, 0x02, 0x95, 0xbb, 0x97, 0xf3, 0x83, 0x5b, 0x50, 0x62,
+  0xad, 0x86, 0xc1, 0x4b, 0x32, 0x18, 0x60, 0xde, 0x91, 0xb7, 0xb6, 0x3e,
+  0xa0, 0x59, 0xc7, 0xc9, 0x3f, 0xa5, 0xb7, 0xd2, 0x5d, 0x25, 0xce, 0xd1,
+  0xc8, 0x29, 0x2a, 0x0f, 0x90, 0xab, 0xbf, 0xe9, 0x56, 0x57, 0xba, 0x78,
+  0x7d, 0xd4, 0x69, 0xee, 0xf9, 0x27, 0xcf, 0x76, 0x7f, 0x47, 0xac, 0x5e,
+  0x49, 0x0e, 0x12, 0x71, 0x24, 0x44, 0xd9, 0x62, 0xbe, 0xaf, 0x28, 0x5b,
+  0x53, 0x5d, 0x0d, 0xa5, 0x3c, 0xe4, 0x27, 0x94, 0xd7, 0xcd, 0x94, 0x70,
+  0x5b, 0x7a, 0xa2, 0x69, 0x74, 0xac, 0xef, 0xff, 0xe7, 0x7f, 0x85, 0xc9,
+  0xa4, 0x3f, 0xfe, 0xcc, 0xde, 0xe2, 0x2b, 0xd4, 0x80, 0x72, 0xe0, 0x76,
+  0x95, 0x33, 0xb5, 0xbb, 0x92, 0xe9, 0x48, 0x6f, 0xfe, 0x71, 0xd3, 0x16,
+  0x69, 0x80, 0xd2, 0x1f, 0x4d, 0x45, 0xd6, 0xdb, 0x53, 0xfa, 0xa6, 0x0b,
+  0x5b, 0x49, 0xc5, 0x5d, 0xab, 0x0f, 0xb8, 0xda, 0x11, 0x52, 0xba, 0x60,
+  0xba, 0xaa, 0xce, 0x8a, 0x56, 0x1b, 0x10, 0xe6, 0x7e, 0x75, 0x98, 0x93,
+  0x9b, 0x9c, 0x51, 0x56, 0xe8, 0x3f, 0xe9, 0xa2, 0xc8, 0xd9, 0xcd, 0x8b,
+  0x15, 0x0e, 0x4c, 0x81, 0x12, 0xfd, 0xa7, 0x59, 0x81, 0x7e, 0x73, 0x57,
+  0xfe, 0x57, 0xdb, 0x99, 0x69, 0x54, 0x0c, 0xea, 0xf1, 0xfb, 0x3f, 0xee,
+  0x51, 0x16, 0x4c, 0xaf, 0xdb, 0x04, 0x03, 0xda, 0xed, 0xaa, 0x5a, 0x0d,
+  0x69, 0x1d, 0x73, 0xa8, 0x7e, 0x90, 0x72, 0x6c, 0xfb, 0xa4, 0x38, 0xfe,
+  0x17, 0x0a, 0x54, 0xff, 0xb8, 0x37, 0x78, 0xf6, 0xb3, 0xfd, 0xe8, 0x1f,
+  0xf7, 0xde, 0xff, 0x71, 0xbf, 0x17, 0x4d, 0x72, 0x72, 0x39, 0xef, 0x1e,
+  0x56, 0x91, 0xf4, 0xd9, 0xe2, 0x5e, 0x52, 0x13, 0x24, 0xd6, 0xe8, 0x4a,
+  0x43, 0xa1, 0xf0, 0x59, 0xc8, 0x0b, 0x44, 0xae, 0xab, 0x8e, 0xaa, 0xaa,
+  0xb5, 0xa1, 0x54, 0x38, 0xdc, 0x95, 0xfc, 0xb2, 0xb8, 0x55, 0x38, 0xe7,
+  0x4d, 0x31, 0xf3, 0x81, 0x30, 0x24, 0x12, 0x22, 0x7f, 0x6f, 0x10, 0x4b,
+  0x88, 0x52, 0x4b, 0x84, 0xb3, 0x21, 0x00, 0x29, 0x73, 0x9d, 0xa5, 0x49,
+  0x67, 0xd2, 0xc7, 0x63, 0xfb, 0x93, 0x22, 0x0b, 0x92, 0x8f, 0xa0, 0x0c,
+  0x33, 0xc3, 0x33, 0x0c, 0x38, 0x2b, 0x15, 0xcc, 0x9b, 0x36, 0x80, 0x2d,
+  0x71, 0x2d, 0xf4, 0xde, 0x95, 0xbc, 0xa3, 0xca, 0x6b, 0x5d, 0x69, 0xf1,
+  0xb7, 0xa5, 0x56, 0x24, 0x74, 0x37, 0x8a, 0x69, 0x29, 0x77, 0x85, 0x6a,
+  0xf9, 0x67, 0x12, 0x81, 0xa1, 0xa4, 0xf6, 0x04, 0x97, 0x5c, 0x1d, 0x4d,
+  0x4b, 0x4d, 0xc7, 0x54, 0xb8, 0xa9, 0x55, 0x04, 0x03, 0x55, 0xac, 0xe9,
+  0xd6, 0x19, 0x3b, 0x92, 0xa5, 0xb4, 0x5e, 0x31, 0x21, 0xfe, 0x54, 0x78,
+  0x93, 0x20, 0x13, 0x85, 0xc9, 0x59, 0xe3, 0xd9, 0xe5, 0x54, 0x50, 0xc2,
+  0x91, 0x36, 0xd9, 0xc0, 0xcb, 0x05, 0x45, 0xea, 0x29, 0x7e, 0xea, 0x61,
+  0xdd, 0x24, 0xc0, 0x37, 0x08, 0xa2, 0x92, 0x66, 0x13, 0x4d, 0xef, 0x8d,
+  0x24, 0x64, 0xce, 0x49, 0x4b, 0x62, 0xa7, 0x2e, 0x02, 0x91, 0x35, 0x66,
+  0x9f, 0x6d, 0x0e, 0x36, 0x93, 0x2d, 0x97, 0x6e, 0x95, 0x4c, 0xd3, 0xfa,
+  0x66, 0x3b, 0xe6, 0x88, 0x74, 0xbe, 0x3f, 0x27, 0xa8, 0xc6, 0xe2, 0x7b,
+  0xa0, 0x2b, 0x93, 0x25, 0x54, 0x74, 0x60, 0x7a, 0x61, 0x9f, 0x21, 0x60,
+  0xc2, 0x80, 0xc1, 0x81, 0x47, 0xa9, 0xdc, 0xfa, 0xd9, 0x00, 0xb9, 0xc9,
+  0xfc, 0xf3, 0xff, 0x08, 0xef, 0x05, 0x79, 0x92, 0x31, 0x5f, 0x03, 0x4e,
+  0xfc, 0x71, 0x17, 0x29, 0x45, 0xf3, 0x92, 0x17, 0x8b, 0x9b, 0xca, 0xa8,
+  0x7f, 0x61, 0x7e, 0xd1, 0xe8, 0x9b, 0x84, 0x89, 0xfe, 0xcc, 0x53, 0xfc,
+  0x8c, 0xdd, 0x20, 0x0b, 0x47, 0x66, 0xf7, 0x3b, 0x72, 0xc3, 0x11, 0x9c,
+  0x64, 0x90, 0xd6, 0x83, 0x40, 0xd5, 0x09, 0x8a, 0x48, 0x93, 0x35, 0x42,
+  0x30, 0x46, 0x0a, 0xac, 0x15, 0x13, 0x94, 0x54, 0x4c, 0x76, 0x86, 0xc3,
+  0x1d, 0x12, 0x58, 0x3b, 0xe6, 0x0f, 0xc7, 0x91, 0x0e, 0xd4, 0x6d, 0xb7,
+  0xca, 0x8b, 0xd9, 0xe8, 0xc0, 0xae, 0x80, 0x22, 0x42, 0xca, 0xa2, 0xb9,
+  0x40, 0x7b, 0xfd, 0xf7, 0x25, 0xa0, 0xa8, 0x95, 0x51, 0x28, 0x2b, 0x4e,
+  0x60, 0x9d, 0xb7, 0xee, 0xc8, 0xa0, 0xb6, 0x0a, 0x7b, 0xd6, 0x6b, 0xa1,
+  0x49, 0x68, 0x6e, 0x3a, 0x69, 0x55, 0x0c, 0xa3, 0x01, 0x40, 0x38, 0x6f,
+  0x94, 0xa1, 0x0a, 0x99, 0xc3, 0xe9, 0x5a, 0x83, 0xee, 0xe9, 0x7e, 0xdb,
+  0xf1, 0xb1, 0xc8, 0x0b, 0x63, 0x62, 0x18, 0xd5, 0x18, 0xec, 0x83, 0x84,
+  0xc5, 0x0b, 0xf3, 0x56, 0xd8, 0x9b, 0xd6, 0x8e, 0xc2, 0x7a, 0x29, 0xa3,
+  0x5e, 0xc9, 0x54, 0x51, 0xb1, 0x99, 0x7e, 0x91, 0xe3, 0xf9, 0x5b, 0xc1,
+  0x65, 0xc9, 0x1f, 0xd9, 0xe6, 0x1b, 0x53, 0xd0, 0xba, 0xd8, 0x10, 0x99,
+  0xad, 0x06, 0x20, 0xba, 0x4c, 0xca, 0x68, 0x20, 0x68, 0xef, 0x68, 0x2d,
+  0xe6, 0xf6, 0xb0, 0x3e, 0x07, 0xeb, 0x29, 0x71, 0x95, 0x64, 0x68, 0xcc,
+  0x44, 0xe0, 0x68, 0xe6, 0xfd, 0xd5, 0xf1, 0x85, 0xa8, 0x27, 0xf0, 0x40,
+  0xb8, 0x3a, 0x80, 0x61, 0xb9, 0x6b, 0xb2, 0x64, 0x9e, 0x3f, 0xb5, 0x85,
+  0x22, 0xeb, 0x9b, 0x74, 0xff, 0xd9, 0x73, 0xe9, 0xb6, 0x32, 0x45, 0xe1,
+  0xde, 0xde, 0xe4, 0x5f, 0xed, 0xec, 0x70, 0xd8, 0x9c, 0x6c, 0xd3, 0x40,
+  0x2e, 0xa4, 0x52, 0xee, 0x72, 0xf3, 0xf3, 0xcd, 0x28, 0x60, 0x4e, 0x35,
+  0x57, 0xb6, 0xdf, 0xc9, 0xfb, 0x0c, 0x50, 0x9f, 0xcf, 0x1a, 0xdf, 0xef,
+  0x56, 0x11, 0x41, 0x1e, 0x4b, 0xa0, 0x35, 0xf8, 0x84, 0xea, 0x89, 0x50,
+  0x2b, 0x70, 0x01, 0x32, 0xaa, 0x7d, 0x2e, 0x49, 0x98, 0xc3, 0xe4, 0xb0,
+  0x35, 0x3f, 0x35, 0xd7, 0x40, 0x9c, 0x84, 0xf4, 0x1d, 0x02, 0x7e, 0xa3,
+  0xd5, 0xf0, 0x1a, 0x16, 0x14, 0xa8, 0xd9, 0x73, 0xa0, 0xb4, 0xa3, 0x8d,
+  0xa7, 0x61, 0x17, 0x76, 0xc9, 0xa0, 0xa7, 0xe6, 0x0b, 0x41, 0x9a, 0x88,
+  0xee, 0x0b, 0x85, 0x48, 0xb1, 0x45, 0xef, 0xc1, 0x04, 0xdd, 0x69, 0x31,
+  0xd7, 0x41, 0xd5, 0x74, 0xd8, 0x57, 0xe2, 0xb4, 0xb3, 0xca, 0x1a, 0x02,
+  0x98, 0xd8, 0x24, 0xcb, 0x99, 0x72, 0xc8, 0xac, 0x2d, 0x05, 0x7e, 0x82,
+  0x73, 0x60, 0xb6, 0xc2, 0x0e, 0xed, 0x03, 0x31, 0x36, 0x02, 0x86, 0x77,
+  0x72, 0x32, 0x7f, 0x36, 0xdc, 0x3d, 0x48, 0xce, 0x16, 0x59, 0x61, 0xd6,
+  0xa0, 0x9f, 0x7c, 0x5d, 0x2c, 0x69, 0x49, 0x68, 0xd4, 0x5f, 0x8f, 0xbe,
+  0x0d, 0xf8, 0x0f, 0xe8, 0x8d, 0xa7, 0x4f, 0xe8, 0x8d, 0xb7, 0x23, 0x7e,
+  0xea, 0xae, 0x9c, 0x5d, 0x51, 0xe1, 0xe2, 0xa3, 0xfb, 0xd4, 0xfc, 0x11,
+  0x7b, 0xfc, 0x13, 0x7a, 0xdc, 0x6c, 0xbc, 0x69, 0x33, 0xab, 0x63, 0xbf,
+  0x47, 0x07, 0xce, 0xcb, 0x59, 0x5a, 0xc1, 0xef, 0xcb, 0x9b, 0x6f, 0x4d,
+  0x8f, 0x9f, 0x3e, 0x8d, 0xf4, 0xb8, 0xbf, 0xa2, 0x43, 0xc3, 0x7f, 0xbe,
+  0x47, 0x67, 0x70, 0xfc, 0xd1, 0xdf, 0xc6, 0xe9, 0xe4, 0x03, 0xb6, 0x22,
+  0x50, 0xed, 0x96, 0x52, 0xf5, 0xf7, 0x94, 0xe6, 0x9c, 0x71, 0xff, 0x98,
+  0xca, 0x2d, 0x15, 0x68, 0xc7, 0x1a, 0xa4, 0x72, 0x7f, 0xb2, 0xff, 0x64,
+  0x6f, 0xe7, 0xf9, 0xf0, 0xe9, 0x70, 0xdf, 0xa2, 0xcc, 0xcc, 0xc6, 0xba,
+  0xa5, 0x3a, 0x01, 0x14, 0xcf, 0x5f, 0x55, 0x66, 0x2d, 0x2f, 0x4c, 0x3b,
+  0x5e, 0x79, 0x66, 0xe1, 0x73, 0x76, 0xf8, 0x92, 0x94, 0x08, 0x16, 0xfc,
+  0x5c, 0xa5, 0x61, 0xa4, 0x4c, 0x16, 0xf1, 0x14, 0x50, 0x27, 0xc4, 0xd9,
+  0xb1, 0xac, 0x30, 0x03, 0xe3, 0xdc, 0xd8, 0xcc, 0x4d, 0xb9, 0x84, 0x4f,
+  0x9d, 0x1c, 0x38, 0xca, 0x2a, 0x2d, 0x3a, 0x92, 0x94, 0x64, 0x2d, 0xa3,
+  0x95, 0xe2, 0xa5, 0xf7, 0x8c, 0xe7, 0xa5, 0x00, 0x91, 0x46, 0xe3, 0x91,
+  0x12, 0x95, 0x73, 0x9d, 0x5e, 0x94, 0x74, 0x30, 0xe6, 0x0c, 0xca, 0x71,
+  0x7f, 0x63, 0x4c, 0x8d, 0x5b, 0x72, 0x1c, 0x07, 0xe5, 0xc4, 0x58, 0xa6,
+  0x30, 0x71, 0x0e, 0x3b, 0xfe, 0x05, 0xe4, 0x80, 0x39, 0x84, 0x6f, 0x57,
+  0x7e, 0x20, 0x04, 0x0a, 0xf0, 0x80, 0x70, 0xd9, 0xcc, 0x69, 0x10, 0x78,
+  0xb7, 0xf3, 0xd0, 0x86, 0x86, 0x32, 0x89, 0x21, 0x31, 0x27, 0x53, 0x02,
+  0x13, 0xfb, 0xb8, 0x99, 0x49, 0x8d, 0xa6, 0xd1, 0xe5, 0xa2, 0xc5, 0x5c,
+  0x30, 0xeb, 0x5c, 0x74, 0x51, 0xda, 0x05, 0xfe, 0x57, 0x9b, 0x6e, 0x68,
+  0x6d, 0xe9, 0xa9, 0x4e, 0xf5, 0x2f, 0x6d, 0xf5, 0x57, 0xef, 0xb2, 0x27,
+  0xbf, 0xfd, 0x2e, 0xdb, 0x7f, 0xec, 0x2e, 0xf3, 0xb6, 0x19, 0xbb, 0x82,
+  0xd6, 0x6c, 0x34, 0x33, 0x85, 0x18, 0xc7, 0x8a, 0x5d, 0xe6, 0x6d, 0x32,
+  0x17, 0xf6, 0x6c, 0x6d, 0xb1, 0xf6, 0x1e, 0x73, 0x9b, 0x6c, 0xd5, 0x2e,
+  0xc3, 0x36, 0xb3, 0xfb, 0xec, 0x81, 0x8d, 0xc6, 0x9e, 0xb6, 0xf5, 0xbb,
+  0xec, 0xb2, 0x2d, 0x57, 0xd6, 0xec, 0x31, 0x7f, 0x43, 0x3c, 0x7a, 0x97,
+  0x39, 0xb7, 0x17, 0xcb, 0x9d, 0x64, 0xc5, 0x46, 0xf3, 0xf7, 0x99, 0xea,
+  0x5a, 0xe1, 0x2e, 0xfb, 0x2c, 0xb6, 0xcb, 0x9e, 0xfc, 0xea, 0x5d, 0xf6,
+  0xf4, 0xb7, 0xdf, 0x65, 0x4f, 0xfe, 0x9f, 0x2c, 0xfb, 0xef, 0x25, 0xcb,
+  0xf6, 0x7e, 0xb1, 0x2c, 0xdb, 0xef, 0x04, 0x36, 0x8d, 0xba, 0xca, 0xfe,
+  0xe6, 0x1f, 0xd5, 0xed, 0x7f, 0xb0, 0xb3, 0xf3, 0x33, 0x9c, 0x27, 0x07,
+  0x74, 0x5f, 0xff, 0x1c, 0x54, 0xab, 0x8c, 0xa8, 0xf5, 0xa3, 0xb3, 0xa3,
+  0x6f, 0x47, 0xe2, 0xb7, 0x16, 0xc5, 0x4b, 0x15, 0x33, 0x76, 0xf0, 0x19,
+  0x75, 0x1d, 0x39, 0xd0, 0x81, 0xae, 0xcf, 0x15, 0xed, 0x06, 0x1f, 0xfb,
+  0xea, 0x3b, 0x06, 0xe4, 0x48, 0x8e, 0x36, 0x38, 0xcd, 0x24, 0xbb, 0x98,
+  0x33, 0x1d, 0xa4, 0xd5, 0x95, 0xf4, 0x55, 0xdc, 0x11, 0xeb, 0x41, 0x17,
+  0x9f, 0x46, 0xe1, 0xbd, 0xb8, 0xd5, 0xdc, 0x54, 0xc8, 0xed, 0xc0, 0xa3,
+  0xdb, 0x1a, 0x36, 0x5a, 0xd7, 0x3b, 0xe9, 0xd7, 0x37, 0x60, 0x7f, 0x5d,
+  0x54, 0xd9, 0x8a, 0x22, 0xb1, 0x97, 0x37, 0xde, 0x6f, 0xd5, 0x85, 0x16,
+  0xa3, 0x70, 0x10, 0x2e, 0x33, 0x6f, 0xbe, 0xe9, 0xbd, 0x20, 0x1f, 0x9d,
+  0xe8, 0x7a, 0x81, 0x30, 0xb5, 0x44, 0x22, 0x33, 0xd4, 0x82, 0x44, 0x69,
+  0x03, 0x1d, 0xa2, 0x36, 0xc2, 0xe0, 0xa5, 0x0c, 0xe5, 0x09, 0xea, 0xa7,
+  0xa6, 0xc9, 0x00, 0x36, 0x8a, 0x5f, 0xa4, 0xf4, 0x1b, 0xfe, 0xfb, 0x33,
+  0xfa, 0x2e, 0xb9, 0x7a, 0xf9, 0x5f, 0x37, 0xf4, 0x4f, 0xa9, 0xe5, 0x20,
+  0x74, 0x49, 0xfe, 0x2a, 0x4f, 0xe2, 0x13, 0xed, 0x27, 0x0d, 0xa9, 0x3a,
+  0x66, 0xcc, 0xdb, 0x80, 0x0a, 0x08, 0xa3, 0xf6, 0x49, 0xd7, 0x56, 0xa0,
+  0x05, 0x4d, 0x33, 0x68, 0xf9, 0x69, 0x5c, 0x49, 0xcc, 0x7c, 0x4e, 0x45,
+  0xe5, 0x0e, 0xf0, 0x0b, 0x1a, 0xb9, 0x48, 0xa9, 0x2c, 0x40, 0x9f, 0x2b,
+  0x84, 0x84, 0xb4, 0xc7, 0x4c, 0xd7, 0x2f, 0xfd, 0xde, 0xdb, 0xfd, 0x34,
+  0xf4, 0x36, 0xbf, 0xd3, 0xa4, 0x36, 0x47, 0x2c, 0x08, 0x40, 0x04, 0xe0,
+  0xe5, 0x63, 0x97, 0xca, 0x11, 0xfb, 0x6c, 0x24, 0xef, 0x8d, 0x1c, 0x00,
+  0xd3, 0x8c, 0x2d, 0xc6, 0x31, 0x9b, 0xfe, 0x41, 0xb1, 0x75, 0x4e, 0xe3,
+  0xad, 0x21, 0x27, 0x85, 0x14, 0x37, 0x91, 0xa8, 0x7e, 0x20, 0x2d, 0x50,
+  0x18, 0x57, 0x82, 0x4d, 0x5f, 0x3a, 0x8e, 0xaa, 0x3f, 0x3d, 0xdd, 0xa5,
+  0x55, 0xd5, 0x56, 0x52, 0xae, 0x3a, 0xce, 0x7b, 0xee, 0x4f, 0x4f, 0xd2,
+  0xe1, 0xbf, 0x90, 0x74, 0xe8, 0x59, 0xdb, 0x95, 0xf0, 0x47, 0x39, 0xe3,
+  0xd7, 0xc4, 0x8c, 0x32, 0x18, 0xa7, 0x55, 0x24, 0x85, 0xc2, 0xde, 0x05,
+  0x42, 0xa9, 0xe1, 0x71, 0x81, 0xeb, 0x9b, 0x5c, 0xc6, 0x5b, 0x70, 0xf1,
+  0xf6, 0x87, 0x61, 0x73, 0x9d, 0x22, 0xf7, 0xea, 0x30, 0xe9, 0x07, 0x3c,
+  0x50, 0xe9, 0xac, 0x4f, 0x51, 0xbc, 0x08, 0x5b, 0x10, 0x56, 0xc7, 0xff,
+  0x04, 0xf1, 0x39, 0xdd, 0x79, 0x8e, 0x04, 0x26, 0x63, 0xbf, 0x82, 0xbf,
+  0xde, 0xa1, 0x2f, 0xc8, 0xf4, 0xa6, 0x68, 0x6c, 0xec, 0x36, 0xab, 0x27,
+  0x15, 0x95, 0x37, 0x91, 0x02, 0x01, 0x68, 0x6b, 0x41, 0x84, 0x78, 0xe6,
+  0x1a, 0xbb, 0xce, 0x34, 0x7d, 0xd2, 0x0e, 0x5a, 0x29, 0x32, 0xc0, 0x8b,
+  0x31, 0x8c, 0x80, 0x92, 0x1d, 0xe8, 0x48, 0x8b, 0x92, 0xa6, 0x42, 0xa2,
+  0x41, 0xaf, 0x3a, 0xca, 0x38, 0x9d, 0x0c, 0x75, 0x14, 0x46, 0xc0, 0x26,
+  0x34, 0x06, 0x3b, 0x04, 0x46, 0x8d, 0x23, 0x05, 0x61, 0x6f, 0x77, 0xff,
+  0x29, 0x93, 0x8f, 0xd8, 0xaf, 0x55, 0x1d, 0xa3, 0x0b, 0x79, 0xbc, 0x7a,
+  0x84, 0x5f, 0xe8, 0xd9, 0xff, 0xe2, 0x41, 0x94, 0xbe, 0x95, 0x12, 0x57,
+  0xe2, 0x70, 0xa1, 0x33, 0x82, 0xac, 0x0d, 0xe6, 0x05, 0x9e, 0xdc, 0x64,
+  0x73, 0xa9, 0x61, 0xf1, 0x0b, 0x2b, 0x72, 0x77, 0xfa, 0xc4, 0xf8, 0xb5,
+  0xab, 0x66, 0x31, 0x9c, 0x97, 0xff, 0x30, 0xf3, 0x91, 0x52, 0x51, 0xac,
+  0x60, 0xe7, 0x52, 0x72, 0x62, 0xc1, 0xb3, 0x07, 0xc1, 0xb8, 0x2c, 0xac,
+  0xcd, 0xea, 0x04, 0xad, 0x32, 0x38, 0x23, 0x39, 0x3d, 0x39, 0x32, 0x3d,
+  0x3e, 0x7e, 0xff, 0xee, 0xed, 0xe8, 0xdd, 0x79, 0xf7, 0x80, 0x9e, 0x9f,
+  0x5d, 0x5c, 0x1e, 0xbf, 0x7a, 0x7f, 0x7e, 0x71, 0x76, 0x79, 0x76, 0x74,
+  0x76, 0x9a, 0x6c, 0xed, 0x6d, 0xaf, 0xcd, 0xc5, 0xb2, 0xee, 0x12, 0x8f,
+  0xc2, 0x4e, 0xfb, 0xcf, 0xa2, 0xc5, 0x76, 0x61, 0x8b, 0xc6, 0x13, 0xb6,
+  0xf6, 0xbd, 0x6c, 0x81, 0x16, 0x29, 0x30, 0x7c, 0x26, 0xb8, 0x83, 0x20,
+  0x7b, 0xd3, 0xe4, 0x7a, 0xc9, 0x9b, 0x59, 0x82, 0xf1, 0x9a, 0xa8, 0x52,
+  0x37, 0xc1, 0x8d, 0x91, 0x65, 0x12, 0x11, 0xf4, 0xd2, 0x78, 0xd6, 0xba,
+  0x0e, 0x9f, 0x75, 0x55, 0x0b, 0x5a, 0x03, 0x68, 0x8c, 0x6e, 0x57, 0xd4,
+  0xf1, 0x6d, 0x61, 0xf7, 0x05, 0x33, 0x7f, 0x80, 0x1f, 0xd9, 0xbe, 0x02,
+  0xfa, 0x78, 0x89, 0xd0, 0x98, 0x2e, 0xab, 0x0e, 0x3a, 0x4c, 0xce, 0xc3,
+  0x42, 0x2f, 0xf2, 0xc6, 0x34, 0x2b, 0xa4, 0xda, 0xa0, 0xf4, 0x03, 0x01,
+  0x3a, 0x9a, 0x5e, 0x89, 0x17, 0x9b, 0x07, 0xe8, 0xb7, 0xde, 0x5c, 0x21,
+  0x39, 0x34, 0x0b, 0xbc, 0xdb, 0xfc, 0x36, 0xf3, 0x62, 0xdc, 0x79, 0x7d,
+  0xa2, 0xf6, 0x48, 0x77, 0x02, 0x41, 0x5d, 0x44, 0x10, 0x1e, 0x6b, 0xf8,
+  0x87, 0x13, 0x71, 0xa0, 0x07, 0x42, 0xcb, 0x50, 0x42, 0x98, 0x91, 0x3f,
+  0x96, 0x07, 0x36, 0x32, 0x4f, 0x22, 0xf9, 0xe1, 0xfb, 0xb4, 0xf6, 0x7d,
+  0xde, 0xd0, 0x61, 0x85, 0xf9, 0x6e, 0x2b, 0x0e, 0xb1, 0xe8, 0x7b, 0xcf,
+  0xd0, 0x21, 0xf2, 0xe9, 0xbb, 0xd1, 0x78, 0x5d, 0xd1, 0x5c, 0x4c, 0x73,
+  0x05, 0x74, 0x27, 0x17, 0x57, 0x82, 0xa6, 0xc9, 0x4b, 0xd1, 0x48, 0x61,
+  0xc4, 0x25, 0x92, 0x0d, 0xa3, 0x84, 0x1f, 0x58, 0x20, 0x14, 0x21, 0x83,
+  0x12, 0x4e, 0xb2, 0x67, 0x45, 0x6c, 0x74, 0x74, 0x1e, 0x21, 0x79, 0xf0,
+  0xb2, 0xee, 0x59, 0x2a, 0x6a, 0x65, 0xd4, 0xdd, 0xe1, 0x6e, 0x32, 0x7a,
+  0xf3, 0x95, 0x50, 0xfb, 0x7d, 0x35, 0x62, 0xa2, 0x64, 0x52, 0x85, 0xf5,
+  0x8d, 0x61, 0x9c, 0x3e, 0x09, 0xc2, 0x63, 0x26, 0x71, 0xec, 0xbf, 0xa4,
+  0x2e, 0x8b, 0xad, 0x16, 0x92, 0x55, 0x37, 0xea, 0x84, 0x33, 0xa9, 0x79,
+  0xdc, 0xfd, 0x68, 0xa2, 0x3a, 0x87, 0x67, 0xa8, 0x2a, 0x68, 0x74, 0xdc,
+  0xc3, 0xf5, 0x44, 0x52, 0xfb, 0xc1, 0x79, 0x78, 0xe4, 0x49, 0x78, 0xcc,
+  0x51, 0x10, 0xbd, 0x43, 0xa5, 0x72, 0x77, 0x3a, 0xce, 0x5b, 0x5b, 0x35,
+  0xa3, 0x6c, 0x1c, 0x06, 0x25, 0x66, 0x57, 0x50, 0xb4, 0x90, 0x27, 0xd7,
+  0xc7, 0x2f, 0x11, 0x58, 0xb3, 0xd0, 0xa9, 0x38, 0xdd, 0x12, 0x1a, 0x49,
+  0x27, 0xbe, 0xe6, 0xaa, 0x04, 0x64, 0xdd, 0x39, 0xf8, 0x0b, 0x6a, 0x50,
+  0x32, 0xfb, 0x2a, 0xdf, 0xa0, 0xc2, 0xb1, 0x00, 0xd2, 0xbf, 0x5c, 0x43,
+  0x67, 0xde, 0x59, 0x9a, 0x51, 0xe6, 0xdd, 0x3d, 0x27, 0xed, 0x05, 0x19,
+  0x06, 0xd0, 0x76, 0xa6, 0xa4, 0xb9, 0x3b, 0x80, 0xb8, 0xee, 0x6a, 0x94,
+  0x20, 0x4a, 0x84, 0x2e, 0xb4, 0x52, 0xf5, 0x25, 0x94, 0x8d, 0x83, 0x24,
+  0x79, 0x95, 0x15, 0xf7, 0xed, 0x0e, 0xf5, 0xc1, 0x94, 0x71, 0xcb, 0x95,
+  0xd7, 0x5d, 0x32, 0xb7, 0xe0, 0x19, 0x29, 0x00, 0x6a, 0xbb, 0x18, 0x76,
+  0xa9, 0xdd, 0xe7, 0x98, 0x04, 0x78, 0x69, 0xa7, 0x41, 0xb1, 0x35, 0xfe,
+  0x64, 0x6c, 0x81, 0x93, 0x41, 0xa3, 0x7f, 0xf8, 0xe4, 0x63, 0xa6, 0x01,
+  0x9c, 0x6a, 0x30, 0x60, 0xea, 0xe5, 0xf8, 0x6f, 0xa8, 0x53, 0x4c, 0x4a,
+  0xfb, 0x2c, 0x85, 0xbd, 0xca, 0x13, 0xa1, 0x90, 0x38, 0xb2, 0x96, 0xcd,
+  0x53, 0x1c, 0xb1, 0x0a, 0x5d, 0xd3, 0x54, 0xa7, 0x04, 0x61, 0x49, 0xa5,
+  0x90, 0x6e, 0xef, 0x02, 0xf4, 0x29, 0x9a, 0x0a, 0x95, 0xad, 0xb8, 0x7c,
+  0x75, 0x8b, 0x0f, 0xae, 0x48, 0x3a, 0x31, 0xd2, 0xaa, 0x73, 0x8d, 0xf1,
+  0x6c, 0x32, 0xbc, 0xcf, 0x82, 0x4d, 0xe9, 0xf1, 0x95, 0x6d, 0xa9, 0xcc,
+  0xab, 0xfb, 0x7f, 0xa1, 0x3f, 0xc2, 0x51, 0xb4, 0x82, 0x33, 0x34, 0xcf,
+  0x7a, 0xda, 0xe9, 0x71, 0x88, 0x0f, 0xbc, 0xbe, 0xea, 0x03, 0x2f, 0x9d,
+  0x40, 0x5d, 0xdf, 0x36, 0x64, 0xcf, 0x63, 0x3e, 0xf0, 0xae, 0x50, 0x1e,
+  0x33, 0xdd, 0xdf, 0x0b, 0xcb, 0x20, 0x7e, 0x97, 0x56, 0x05, 0xc0, 0xe4,
+  0xbe, 0xe6, 0x4f, 0xdc, 0x17, 0x0b, 0x29, 0x2f, 0x90, 0x5e, 0x11, 0x0e,
+  0xb7, 0xca, 0x1c, 0xdd, 0x29, 0xb9, 0xd7, 0x98, 0xe2, 0x46, 0x38, 0x94,
+  0x15, 0x15, 0xba, 0x28, 0x1b, 0x66, 0x73, 0x26, 0xe0, 0x2e, 0xe9, 0x0c,
+  0x15, 0xb9, 0x58, 0xbc, 0x49, 0x56, 0x9d, 0x90, 0x5a, 0xb3, 0xbb, 0x09,
+  0xce, 0xae, 0xe5, 0x82, 0xf6, 0x87, 0x62, 0xaa, 0x24, 0xe4, 0xea, 0xc9,
+  0x19, 0xf9, 0x22, 0xa3, 0xaf, 0xe0, 0x1a, 0xb2, 0xa4, 0xcf, 0xb7, 0x65,
+  0x4e, 0x18, 0xaa, 0x0d, 0x7b, 0x25, 0x18, 0x3d, 0xc8, 0xed, 0x92, 0xcb,
+  0xb0, 0x20, 0x01, 0xec, 0x09, 0x8b, 0x78, 0x11, 0x83, 0xc2, 0x21, 0x82,
+  0xd3, 0xba, 0x95, 0xea, 0x93, 0xb7, 0xb0, 0xc1, 0x80, 0x46, 0x18, 0x85,
+  0x9f, 0x48, 0xd6, 0xcc, 0x9e, 0x2c, 0xd2, 0x46, 0x0f, 0x8c, 0x27, 0x11,
+  0xa9, 0x7b, 0x40, 0xab, 0x15, 0xa4, 0xe4, 0x4f, 0x2c, 0xfb, 0x50, 0x97,
+  0xb0, 0xb9, 0x5d, 0x69, 0xd7, 0xde, 0xaa, 0x16, 0xc1, 0xe9, 0x14, 0xc6,
+  0xe1, 0x03, 0x62, 0xfc, 0xe3, 0xbd, 0x42, 0xc6, 0xd6, 0x2b, 0x33, 0x0b,
+  0x4a, 0xe7, 0xa5, 0xe2, 0x3b, 0x79, 0x83, 0x15, 0xeb, 0x60, 0x56, 0x15,
+  0xcb, 0x29, 0x65, 0x1e, 0xe6, 0xcb, 0xee, 0x91, 0x2f, 0x34, 0x44, 0x67,
+  0x11, 0x3a, 0x4c, 0xe8, 0x04, 0x3d, 0x42, 0xdc, 0x12, 0xcc, 0x60, 0x0f,
+  0xa3, 0x54, 0x69, 0xfd, 0x89, 0x1a, 0x0a, 0x51, 0xbb, 0xb8, 0xb3, 0x6f,
+  0xc7, 0xb2, 0xb9, 0x98, 0x0d, 0x53, 0x4c, 0x07, 0x46, 0x08, 0x2c, 0xd6,
+  0x38, 0x9e, 0x9c, 0x6f, 0xa6, 0x05, 0x76, 0xf5, 0xe9, 0x23, 0xf8, 0x27,
+  0x0c, 0xa9, 0x93, 0xb9, 0x0b, 0xc1, 0xe2, 0x46, 0x25, 0x78, 0x12, 0x9b,
+  0xc9, 0x18, 0x68, 0x2f, 0xb4, 0x15, 0x56, 0xf2, 0xda, 0x6b, 0x36, 0x17,
+  0x26, 0x50, 0x27, 0x6c, 0x15, 0xc0, 0x89, 0xa7, 0x4f, 0x66, 0xee, 0x1d,
+  0x27, 0x53, 0xa1, 0x4d, 0xd8, 0x3b, 0x85, 0xc0, 0xa4, 0xbd, 0x6f, 0xb1,
+  0xaf, 0x26, 0x98, 0x47, 0xf0, 0x2b, 0x31, 0x45, 0x3a, 0x3f, 0x27, 0xd7,
+  0x92, 0x4b, 0x7b, 0xec, 0x76, 0x52, 0xb9, 0xa7, 0x23, 0xce, 0x0f, 0xc8,
+  0x49, 0x7c, 0x88, 0x3a, 0x96, 0xaf, 0x65, 0x2e, 0x58, 0xb1, 0x18, 0x31,
+  0xd2, 0x8e, 0x69, 0x07, 0x81, 0xaa, 0x3f, 0xe7, 0x82, 0xd2, 0x71, 0xd8,
+  0xdb, 0x48, 0xce, 0x9b, 0x96, 0x9d, 0x86, 0x9c, 0x56, 0xcc, 0xa1, 0xe7,
+  0x0d, 0xe3, 0x3a, 0x3b, 0x1f, 0x9b, 0x07, 0xbc, 0xe2, 0xf2, 0x3d, 0x04,
+  0xe9, 0x15, 0x57, 0x22, 0x0d, 0xbb, 0x7f, 0xba, 0xdf, 0x9a, 0xd1, 0xc5,
+  0x84, 0x34, 0xad, 0xd5, 0x6a, 0xb7, 0x42, 0xfb, 0x2b, 0x2f, 0xcc, 0x89,
+  0x5e, 0x37, 0x28, 0x3c, 0xf4, 0x6b, 0x06, 0xd5, 0x2a, 0xd1, 0x2d, 0x63,
+  0x90, 0x3e, 0x77, 0x56, 0x84, 0x3f, 0xb2, 0xd6, 0x09, 0xbb, 0x62, 0x08,
+  0xa6, 0xcd, 0x35, 0x15, 0x31, 0xbd, 0x61, 0xd8, 0x07, 0x7f, 0xe9, 0x48,
+  0x1e, 0x9e, 0x46, 0x6c, 0x0d, 0xfa, 0xef, 0x8f, 0x07, 0xf0, 0x7b, 0x4d,
+  0x7f, 0x5e, 0xd9, 0x8f, 0xe3, 0xbe, 0xf4, 0xe5, 0x77, 0xe8, 0x46, 0xbe,
+  0xb8, 0x21, 0xaf, 0xc6, 0x8b, 0x58, 0x96, 0x8d, 0x37, 0x11, 0xf2, 0xd8,
+  0x6f, 0xff, 0xfd, 0x6a, 0xe6, 0x88, 0x6d, 0xd6, 0x7c, 0x5f, 0x1e, 0xfb,
+  0xcd, 0xbf, 0xcf, 0x67, 0x77, 0xfd, 0xe5, 0x62, 0xa5, 0xe2, 0x2b, 0x81,
+  0x32, 0xb7, 0x25, 0x8e, 0xbb, 0x55, 0x7e, 0x85, 0x50, 0x14, 0x74, 0x74,
+  0x28, 0x15, 0xe5, 0x5b, 0xd1, 0x4a, 0x03, 0xbe, 0x58, 0xfc, 0x4d, 0x24,
+  0x18, 0x44, 0x73, 0x38, 0x39, 0x52, 0xfa, 0xe3, 0x05, 0xff, 0xb9, 0xf3,
+  0x65, 0x6c, 0x8d, 0x94, 0x12, 0xf5, 0x98, 0xae, 0x41, 0x2d, 0x16, 0x82,
+  0xfa, 0x13, 0x4c, 0x15, 0x20, 0x2a, 0xaf, 0xad, 0x9c, 0x40, 0x93, 0xa5,
+  0x58, 0x11, 0x7a, 0x35, 0x56, 0xa1, 0x44, 0x66, 0x88, 0x00, 0xa3, 0x64,
+  0x82, 0x59, 0x1e, 0x69, 0x8b, 0x14, 0x22, 0xc5, 0x23, 0xf3, 0x3e, 0x58,
+  0x5b, 0x56, 0x96, 0x58, 0x5c, 0xcb, 0xaf, 0xf4, 0xe8, 0x68, 0x4b, 0xbf,
+  0xe9, 0x4b, 0x85, 0x10, 0xd3, 0x1c, 0x6d, 0x2b, 0x41, 0x4c, 0xea, 0x7e,
+  0xc2, 0x72, 0x86, 0xf4, 0x2e, 0x8c, 0x84, 0x27, 0xdd, 0x74, 0xc6, 0xc0,
+  0xdc, 0xe4, 0xe8, 0xec, 0xed, 0xdb, 0xe3, 0xa3, 0x6e, 0x38, 0x0f, 0xb4,
+  0x15, 0x48, 0x3e, 0x00, 0xcd, 0xba, 0xa8, 0xfa, 0x41, 0x85, 0x3a, 0x7c,
+  0x9d, 0xa9, 0xc7, 0x2d, 0xa7, 0x12, 0xf7, 0x00, 0xf5, 0x6b, 0x52, 0xa1,
+  0x66, 0xe5, 0x1c, 0x06, 0x8f, 0xb7, 0x93, 0x77, 0x40, 0x24, 0xb1, 0x2b,
+  0xd8, 0x0f, 0xce, 0x1b, 0x01, 0xb7, 0x14, 0x95, 0x2f, 0x64, 0x0d, 0x14,
+  0x26, 0xa6, 0xf6, 0x80, 0xab, 0xf8, 0x4d, 0xa7, 0x3b, 0x02, 0x5c, 0x96,
+  0x94, 0xb8, 0xd0, 0x98, 0xb1, 0x7b, 0x99, 0x99, 0xbe, 0x28, 0x43, 0x64,
+  0x50, 0x5e, 0x71, 0xb1, 0xcc, 0x79, 0x5a, 0x7d, 0xa0, 0x68, 0xa0, 0x97,
+  0x2b, 0x82, 0x5c, 0x41, 0xf0, 0x0e, 0x4f, 0xa7, 0xb1, 0x24, 0x74, 0xb8,
+  0x98, 0x15, 0x1b, 0x8f, 0x5c, 0x34, 0xee, 0x90, 0x54, 0x97, 0x3b, 0xd0,
+  0x24, 0x3e, 0x7a, 0xbd, 0xc8, 0xee, 0xe8, 0x33, 0xcc, 0xbd, 0x41, 0x99,
+  0xe4, 0x21, 0x5b, 0x3d, 0x33, 0x24, 0xb3, 0x1b, 0xfd, 0x5e, 0x92, 0xd8,
+  0x69, 0xad, 0xe6, 0xcc, 0x06, 0x0f, 0x2e, 0x5e, 0x2a, 0xb1, 0xc4, 0x09,
+  0x20, 0xc1, 0x5c, 0x7d, 0xa3, 0x64, 0x7a, 0x5e, 0xc4, 0x4d, 0x39, 0x44,
+  0xfc, 0xcc, 0x0e, 0xc6, 0x79, 0x4b, 0x8e, 0x8c, 0x47, 0xb3, 0xb7, 0x2a,
+  0xe4, 0x8b, 0xf9, 0xc6, 0x42, 0x90, 0xbd, 0x52, 0x3b, 0xea, 0x1d, 0xa9,
+  0x45, 0xe7, 0xef, 0xfa, 0xe0, 0x3c, 0x13, 0x11, 0x34, 0x0c, 0x67, 0x08,
+  0xb1, 0x67, 0x5d, 0xa2, 0x57, 0x70, 0x20, 0xc1, 0xe1, 0x48, 0xe4, 0x67,
+  0xd7, 0x4b, 0xce, 0x76, 0x23, 0x48, 0x00, 0x8e, 0x6b, 0xa0, 0xe8, 0x02,
+  0x79, 0x8a, 0x34, 0xb0, 0xbe, 0x56, 0x75, 0xa6, 0xfd, 0x6a, 0x26, 0x98,
+  0x96, 0x42, 0xa6, 0x5f, 0xa9, 0x4c, 0xd8, 0xef, 0x2e, 0x47, 0x38, 0x2f,
+  0x16, 0xcb, 0x26, 0x88, 0x9d, 0x11, 0xb1, 0x13, 0x27, 0xf3, 0x7f, 0x39,
+  0x08, 0xeb, 0xfd, 0xa4, 0x53, 0x7f, 0x55, 0x21, 0xc2, 0x61, 0xfd, 0xd7,
+  0x8d, 0x11, 0x00, 0x6b, 0xbd, 0xb4, 0xbe, 0x4d, 0xe3, 0x8c, 0x1a, 0xc1,
+  0x88, 0xe3, 0xac, 0x78, 0xdb, 0x75, 0x07, 0xee, 0x85, 0xee, 0x6e, 0xb0,
+  0x6f, 0xa9, 0x90, 0x58, 0x47, 0xdd, 0x01, 0x72, 0xc1, 0x8e, 0xfc, 0x33,
+  0x76, 0x0e, 0x79, 0x9f, 0xb2, 0x55, 0xd7, 0xd2, 0x87, 0x3e, 0x28, 0x20,
+  0xf9, 0xa1, 0xdf, 0xfe, 0x6e, 0x5a, 0x5f, 0xb7, 0xdb, 0x5d, 0x8e, 0xf6,
+  0xb9, 0xdf, 0xa3, 0x07, 0xd1, 0x42, 0xd8, 0xad, 0x6f, 0x3f, 0xfe, 0xb3,
+  0x01, 0xcb, 0xdd, 0x03, 0x7e, 0x39, 0x77, 0xf3, 0x3e, 0x48, 0xe2, 0x08,
+  0xa9, 0x1b, 0xe0, 0x51, 0xbd, 0x3b, 0x79, 0xed, 0x2d, 0xec, 0x92, 0xf6,
+  0xfd, 0x8b, 0x38, 0x12, 0xa3, 0x8e, 0x75, 0x44, 0xa2, 0xcc, 0x8f, 0xbb,
+  0x94, 0x1f, 0xbc, 0x84, 0x5b, 0x39, 0x9f, 0x5d, 0x38, 0x94, 0xcd, 0xf9,
+  0x7a, 0xfc, 0xc4, 0x51, 0xc2, 0xdb, 0x6f, 0xa9, 0xb0, 0x20, 0xd1, 0xac,
+  0xa5, 0xae, 0xe0, 0x13, 0xad, 0x49, 0x78, 0xcc, 0xbd, 0x14, 0x4c, 0x89,
+  0x5b, 0x83, 0x88, 0xb6, 0x12, 0xce, 0xc2, 0x3a, 0xb4, 0xbb, 0xdb, 0x9e,
+  0x78, 0xea, 0x37, 0x3f, 0x16, 0x04, 0x6f, 0xc9, 0x27, 0x02, 0xe3, 0x7f,
+  0xf1, 0x30, 0x1d, 0x63, 0xc0, 0x65, 0xe5, 0x45, 0x9e, 0xa4, 0x2d, 0x16,
+  0xcc, 0x56, 0x01, 0x09, 0xc8, 0x55, 0x04, 0x9a, 0x1c, 0x01, 0xae, 0xf8,
+  0x71, 0xa1, 0x27, 0xd1, 0xde, 0xd6, 0xb3, 0x01, 0x7a, 0x40, 0x39, 0x76,
+  0x81, 0xae, 0xeb, 0xe6, 0xaa, 0xf3, 0xdc, 0x6f, 0x3f, 0x6d, 0xcd, 0xac,
+  0xa6, 0xb5, 0x7c, 0x8c, 0x48, 0xf3, 0x1f, 0xfd, 0x3d, 0xfa, 0x61, 0x91,
+  0x06, 0x2f, 0x18, 0x46, 0xb0, 0xb6, 0x27, 0xf6, 0xe1, 0xdf, 0xa3, 0x27,
+  0x48, 0xdb, 0x8b, 0xee, 0xa1, 0x56, 0x1f, 0xf0, 0xd8, 0xef, 0xf1, 0xfd,
+  0xdb, 0xbd, 0x55, 0x9f, 0x45, 0x39, 0x2d, 0x3c, 0xf1, 0x1b, 0x7e, 0xf8,
+  0x9d, 0x35, 0x4a, 0x38, 0xcb, 0xf1, 0x05, 0xfd, 0xf7, 0x40, 0x67, 0x78,
+  0x5d, 0x9d, 0x8e, 0x15, 0xcc, 0xb0, 0x5e, 0x91, 0xd0, 0x20, 0x9d, 0xf7,
+  0x51, 0xc0, 0x2f, 0x5b, 0xc4, 0x5a, 0x78, 0xa6, 0x95, 0x38, 0x32, 0x01,
+  0xa1, 0xef, 0x40, 0xf9, 0x66, 0x38, 0xb3, 0x9a, 0x53, 0xdd, 0x39, 0x71,
+  0x59, 0x98, 0x17, 0xba, 0x64, 0x1b, 0x56, 0x8c, 0x99, 0x1e, 0xc5, 0xa4,
+  0xaf, 0xe0, 0xa4, 0xee, 0x6d, 0xc9, 0x2f, 0xa4, 0x8e, 0x58, 0xd9, 0x1d,
+  0xc4, 0x86, 0x67, 0xcc, 0xcb, 0xb4, 0x9e, 0x1a, 0x57, 0xaa, 0xa1, 0x3b,
+  0x8e, 0x82, 0x31, 0x9b, 0x4d, 0x41, 0xe5, 0x01, 0x89, 0xda, 0x39, 0xce,
+  0xb4, 0x99, 0xcb, 0x6b, 0xb5, 0xca, 0xd7, 0x41, 0xd2, 0x1b, 0xbc, 0x4b,
+  0x0e, 0x7a, 0xbf, 0x23, 0x80, 0xdc, 0x33, 0x4e, 0x7f, 0x01, 0x1e, 0xae,
+  0x5d, 0x79, 0x60, 0x1d, 0x3a, 0xcc, 0x43, 0x08, 0x05, 0xe9, 0xb8, 0x71,
+  0x58, 0xd8, 0x15, 0x71, 0x74, 0x26, 0x6f, 0xbb, 0x0b, 0x10, 0x01, 0x58,
+  0x51, 0x84, 0x9a, 0x03, 0xc2, 0x76, 0x74, 0x0d, 0x92, 0xd3, 0x90, 0xe9,
+  0xeb, 0xbb, 0x8c, 0xdf, 0x05, 0x75, 0xfd, 0x1c, 0x6c, 0x6c, 0x35, 0x50,
+  0xcc, 0xc3, 0x89, 0x01, 0x2e, 0xc9, 0x96, 0x33, 0x0a, 0x21, 0x07, 0x06,
+  0x29, 0xd8, 0x0c, 0x19, 0x23, 0xa6, 0x10, 0x31, 0x1f, 0x21, 0x96, 0x6c,
+  0x5d, 0x7a, 0x2e, 0x7c, 0xc7, 0x3e, 0x44, 0x76, 0x57, 0xdc, 0x79, 0x8c,
+  0x7d, 0x08, 0x3a, 0xda, 0x4f, 0x82, 0xda, 0x3d, 0xfe, 0xd1, 0xd7, 0xa6,
+  0x6e, 0xf3, 0x94, 0xa3, 0x32, 0x3c, 0x8d, 0xf2, 0x21, 0x9e, 0x4f, 0x2d,
+  0x60, 0xb8, 0xd6, 0x3d, 0xc7, 0x29, 0xdb, 0x91, 0x34, 0x8f, 0xb7, 0xa3,
+  0x51, 0x08, 0x15, 0x2b, 0xaa, 0x6c, 0x52, 0x5e, 0x17, 0xf9, 0x3f, 0xa8,
+  0x45, 0x78, 0x36, 0xbb, 0xe0, 0x91, 0x16, 0x58, 0x4f, 0x3d, 0xf5, 0xc4,
+  0xe0, 0x41, 0xf1, 0x93, 0xee, 0x6a, 0x28, 0x97, 0x08, 0x09, 0x29, 0x0a,
+  0xe4, 0x12, 0x05, 0x82, 0xcc, 0x23, 0x57, 0xab, 0x65, 0x3e, 0x77, 0xc9,
+  0xa5, 0xd1, 0xd1, 0xc9, 0x87, 0x83, 0xc5, 0xd5, 0x5d, 0x21, 0x20, 0xa0,
+  0x15, 0x1c, 0x01, 0x59, 0xf2, 0x2b, 0xc0, 0x75, 0x28, 0xd2, 0xf2, 0xcb,
+  0xa1, 0x75, 0xf1, 0xfc, 0x7d, 0x54, 0xcb, 0xa6, 0xa3, 0x11, 0x67, 0x48,
+  0x51, 0xf6, 0x80, 0x48, 0x49, 0x98, 0x1b, 0x07, 0x88, 0x64, 0xc1, 0xfb,
+  0x28, 0x9e, 0x14, 0xd3, 0x10, 0x67, 0x55, 0x85, 0x67, 0xab, 0xcb, 0x91,
+  0x62, 0x9d, 0x1f, 0x8f, 0x20, 0x47, 0x21, 0xeb, 0x5e, 0xe9, 0x2d, 0xc5,
+  0xc8, 0x06, 0xf3, 0xb3, 0xad, 0x4a, 0x5e, 0x72, 0x15, 0x70, 0xef, 0x48,
+  0xf2, 0x81, 0x8d, 0x96, 0x25, 0x5a, 0x10, 0x75, 0x38, 0x48, 0xeb, 0xc6,
+  0x16, 0x0b, 0xdd, 0x30, 0xfb, 0x3f, 0x1a, 0x18, 0x12, 0x85, 0x07, 0xe1,
+  0x8d, 0xd5, 0x9e, 0x37, 0xbf, 0x26, 0x1c, 0xb3, 0xee, 0x8a, 0xee, 0xd6,
+  0x72, 0x54, 0xa3, 0xb6, 0x8b, 0x1c, 0x3c, 0x12, 0xc3, 0xdf, 0xd6, 0xd1,
+  0x70, 0x8c, 0xc2, 0x48, 0x1e, 0x94, 0x12, 0xc3, 0x21, 0xab, 0x99, 0x4e,
+  0x53, 0x43, 0xc5, 0xa4, 0x89, 0x80, 0x8c, 0xe1, 0xb5, 0x76, 0xaf, 0xf4,
+  0x49, 0xfa, 0xb0, 0xc8, 0x15, 0xf5, 0x7d, 0xb0, 0x50, 0x29, 0xdb, 0x1d,
+  0xec, 0xbd, 0x34, 0xb2, 0xa2, 0xd4, 0xea, 0xef, 0x80, 0xc8, 0xfc, 0x55,
+  0x90, 0xcc, 0xdf, 0x17, 0x91, 0xe9, 0x6e, 0x0a, 0xba, 0x75, 0xc2, 0x7b,
+  0x02, 0xc1, 0x52, 0x4a, 0xa9, 0xe3, 0xe8, 0xe8, 0x5d, 0x6a, 0x89, 0xb0,
+  0xa3, 0x4a, 0x7a, 0xfc, 0x30, 0xf5, 0xdb, 0xf8, 0x96, 0x2c, 0x90, 0x91,
+  0x5b, 0x22, 0x35, 0x62, 0x75, 0x5e, 0xb8, 0x32, 0xfc, 0x38, 0x83, 0x00,
+  0xc5, 0xfd, 0xff, 0x17, 0x47, 0x44, 0xfd, 0x7b, 0x66, 0x77, 0xd1, 0xf0,
+  0xf6, 0x8c, 0x6c, 0x7e, 0xe1, 0xdd, 0xc7, 0x5f, 0x3c, 0x78, 0x21, 0xe3,
+  0x9c, 0xd1, 0x6b, 0x8e, 0x42, 0xc9, 0x93, 0x77, 0xb6, 0x4e, 0x16, 0x97,
+  0xfb, 0x68, 0xe2, 0x07, 0x06, 0xa5, 0xaf, 0x98, 0x2b, 0x47, 0xc4, 0x9b,
+  0x16, 0x78, 0x5f, 0x21, 0xe0, 0x32, 0xa5, 0xcc, 0x55, 0x9e, 0x5e, 0x23,
+  0xd1, 0xc7, 0x59, 0x73, 0x47, 0xe8, 0x4f, 0xcc, 0x87, 0x4e, 0xa4, 0x27,
+  0x05, 0x64, 0x8a, 0x56, 0x86, 0xc1, 0xfa, 0x1c, 0x66, 0x24, 0x81, 0xc2,
+  0x2c, 0x70, 0xb6, 0xca, 0xab, 0x7a, 0x7b, 0x83, 0xd3, 0x17, 0x65, 0x96,
+  0x77, 0x9e, 0xeb, 0xd6, 0xdc, 0x28, 0x48, 0xa7, 0x85, 0x9b, 0xd5, 0x80,
+  0xa6, 0x3c, 0xe8, 0x1b, 0xfe, 0xf6, 0x18, 0xcb, 0xb1, 0x8d, 0x96, 0x7b,
+  0x20, 0x55, 0xd2, 0x1b, 0xa2, 0x2e, 0xbf, 0xa7, 0x69, 0x45, 0x6a, 0x73,
+  0xe3, 0x76, 0x8c, 0xa4, 0x96, 0x68, 0x43, 0x7a, 0x8b, 0xc2, 0xdf, 0xc6,
+  0x53, 0x21, 0x8e, 0x6a, 0x96, 0x1f, 0x76, 0x1e, 0x56, 0x1f, 0x0b, 0x87,
+  0x88, 0xbd, 0xa2, 0x94, 0xeb, 0x6c, 0xa6, 0xc7, 0x35, 0xd7, 0x4c, 0x69,
+  0xfa, 0xd8, 0x00, 0xee, 0x74, 0x27, 0x2b, 0x99, 0x94, 0xc5, 0x7c, 0x25,
+  0x70, 0x60, 0x9a, 0xaf, 0xa6, 0x0b, 0xf3, 0x21, 0x94, 0x85, 0xa7, 0x4b,
+  0x7a, 0xea, 0x49, 0x3c, 0xf4, 0x5b, 0x17, 0x44, 0xd7, 0xca, 0x01, 0xed,
+  0x43, 0xb0, 0x55, 0x58, 0xb5, 0x44, 0x22, 0x26, 0x2c, 0x97, 0x04, 0xa8,
+  0x27, 0x49, 0x0d, 0xea, 0x84, 0x17, 0x57, 0x0f, 0xed, 0xca, 0x38, 0x5f,
+  0x88, 0x50, 0x29, 0x16, 0xbc, 0x6f, 0xba, 0x02, 0x3b, 0xac, 0x6c, 0x79,
+  0xc9, 0xb4, 0x3b, 0x40, 0x3f, 0xf3, 0xf7, 0x5d, 0x54, 0x41, 0x10, 0x04,
+  0x5a, 0xe8, 0xe5, 0xce, 0x56, 0xc1, 0x66, 0x0f, 0x7d, 0xac, 0x8c, 0x8a,
+  0x60, 0x8f, 0xf5, 0x15, 0xe1, 0xea, 0x93, 0x0f, 0xd8, 0x82, 0x58, 0xab,
+  0xbc, 0xa2, 0xb1, 0x08, 0x52, 0x4b, 0x38, 0x48, 0x8a, 0x7a, 0xc4, 0x2f,
+  0xb8, 0x35, 0x22, 0xfa, 0xf3, 0xd1, 0xd1, 0xf9, 0x76, 0x72, 0xee, 0x52,
+  0x9b, 0xe1, 0xf6, 0x05, 0xb8, 0x98, 0xee, 0x6c, 0x5f, 0xdc, 0x4b, 0x01,
+  0x12, 0x26, 0x63, 0x8a, 0x67, 0x2a, 0x4b, 0xee, 0x38, 0x76, 0xae, 0xa5,
+  0x1c, 0x83, 0xdb, 0xf9, 0x37, 0x97, 0x7f, 0x9d, 0xb1, 0x1c, 0x82, 0x78,
+  0x80, 0x13, 0x91, 0x25, 0x27, 0xda, 0x97, 0x06, 0xc6, 0xac, 0x2b, 0x09,
+  0xd7, 0xce, 0x94, 0xff, 0x92, 0xbb, 0xcd, 0x3b, 0x08, 0x43, 0xef, 0x34,
+  0xc7, 0x89, 0xf8, 0x8a, 0x7c, 0xf3, 0x28, 0x17, 0xa4, 0xf8, 0x4e, 0xcd,
+  0xb7, 0x5f, 0x87, 0x15, 0x97, 0x46, 0x71, 0x9d, 0x15, 0x21, 0xcd, 0x36,
+  0x3e, 0x4a, 0xfa, 0x82, 0x6c, 0xe0, 0xe9, 0xb0, 0x4b, 0xf0, 0xea, 0xe5,
+  0x96, 0x4b, 0xe7, 0x72, 0x60, 0x4f, 0x79, 0xbf, 0xaf, 0xa2, 0x82, 0xa2,
+  0xb3, 0x3d, 0x06, 0xde, 0xfe, 0x03, 0x89, 0xde, 0x6b, 0xca, 0xe7, 0x6f,
+  0x70, 0x95, 0x2e, 0xee, 0x69, 0x3a, 0xcc, 0x83, 0x75, 0x7d, 0xb3, 0x6f,
+  0x04, 0xd4, 0xfe, 0xf0, 0x53, 0x58, 0x42, 0x46, 0x27, 0xc8, 0xaa, 0x15,
+  0x44, 0x6f, 0x52, 0xa4, 0xab, 0xd3, 0x9a, 0x28, 0xfb, 0x43, 0x67, 0x5f,
+  0x0c, 0xfe, 0x07, 0xed, 0xb4, 0xbf, 0x2f, 0x43, 0xdf, 0xe1, 0x16, 0x36,
+  0xd4, 0x6b, 0x70, 0x3e, 0x11, 0x01, 0x3c, 0xa2, 0x1c, 0xe3, 0xbc, 0x01,
+  0x83, 0xab, 0xd2, 0x94, 0xb4, 0x8f, 0x25, 0xbd, 0x01, 0x48, 0x2a, 0xbd,
+  0x16, 0x4d, 0x4c, 0x33, 0xaa, 0xfe, 0xff, 0xa0, 0x6f, 0x69, 0x03, 0x0c,
+  0xdc, 0x44, 0x24, 0xe6, 0xab, 0xe3, 0xd7, 0x67, 0x17, 0xc7, 0xed, 0xe4,
+  0x80, 0x06, 0x25, 0x27, 0x10, 0x68, 0xe8, 0xf6, 0x0e, 0xec, 0x2b, 0xae,
+  0x94, 0x59, 0x5e, 0xe4, 0x04, 0x13, 0x4b, 0xce, 0xbf, 0x7f, 0x65, 0x3b,
+  0x47, 0x9a, 0x48, 0xc1, 0x9d, 0x72, 0xf5, 0x72, 0x65, 0x9e, 0xbb, 0x1a,
+  0x04, 0x29, 0x1b, 0x54, 0x02, 0x41, 0xea, 0x29, 0xda, 0xee, 0x21, 0xc0,
+  0xc3, 0x81, 0x39, 0xfe, 0x58, 0xca, 0x64, 0x9f, 0x75, 0x4d, 0x99, 0x6f,
+  0xb6, 0xd9, 0x40, 0xbd, 0x86, 0x82, 0x01, 0x86, 0x0b, 0xb1, 0x79, 0x89,
+  0xe1, 0x84, 0x68, 0x4f, 0x86, 0x89, 0xfd, 0x88, 0xfb, 0x0a, 0x17, 0x87,
+  0x85, 0xfa, 0x82, 0xaf, 0xc4, 0x22, 0x89, 0x54, 0xf0, 0x93, 0xbd, 0x97,
+  0x7c, 0xa9, 0x12, 0x59, 0x35, 0xed, 0x59, 0x5b, 0x6d, 0xa1, 0xcf, 0x8c,
+  0x34, 0x92, 0x9c, 0xe6, 0xcf, 0x63, 0xc4, 0x3b, 0x6f, 0x3e, 0xbb, 0x55,
+  0x6f, 0xf7, 0xbd, 0x9e, 0xda, 0x69, 0x93, 0x0e, 0x6f, 0xfe, 0x65, 0x33,
+  0x11, 0x40, 0x2a, 0x04, 0x1e, 0x5f, 0xf5, 0x2b, 0xaa, 0x2c, 0xb9, 0xaa,
+  0x1b, 0xdb, 0x0f, 0x45, 0x8f, 0x75, 0xd0, 0xab, 0x6d, 0x34, 0xcd, 0x94,
+  0x95, 0x98, 0x22, 0x17, 0xc0, 0xa2, 0x38, 0x0f, 0xbe, 0x01, 0xf1, 0x21,
+  0x37, 0xb7, 0xb6, 0xd5, 0x8f, 0xe4, 0xc9, 0x91, 0xe3, 0xa7, 0xf2, 0x69,
+  0xf8, 0x55, 0xe4, 0x80, 0x59, 0x41, 0x49, 0x56, 0xb9, 0x28, 0x93, 0x96,
+  0x38, 0xb8, 0x2f, 0x1a, 0x3a, 0xad, 0x10, 0x2c, 0xc1, 0xa4, 0x55, 0xb8,
+  0x90, 0x78, 0x3f, 0xb9, 0xed, 0x5b, 0x23, 0x23, 0xf5, 0xb3, 0x67, 0x9f,
+  0x91, 0x1a, 0x81, 0x20, 0xa9, 0x94, 0xa2, 0x10, 0x36, 0x42, 0x30, 0x6d,
+  0x84, 0xa9, 0x28, 0x9d, 0x01, 0x68, 0xf9, 0xc0, 0x71, 0x36, 0xe3, 0xd2,
+  0x17, 0x23, 0xaf, 0x89, 0x47, 0x47, 0xeb, 0xda, 0x08, 0xc4, 0x21, 0xab,
+  0x27, 0x66, 0x15, 0xd2, 0x0f, 0x2e, 0x47, 0x31, 0x59, 0x75, 0x34, 0xfb,
+  0x76, 0xdb, 0x6a, 0x4e, 0x2a, 0x6f, 0x07, 0xcb, 0xe0, 0x6c, 0x44, 0x77,
+  0x56, 0xe5, 0xf5, 0x87, 0x64, 0xeb, 0xcf, 0xdb, 0xb6, 0xf0, 0x68, 0x04,
+  0xeb, 0x45, 0xae, 0xc9, 0xbc, 0x58, 0x66, 0xad, 0xa2, 0xb4, 0xda, 0xda,
+  0x15, 0x0a, 0xa5, 0x10, 0xeb, 0x5d, 0x0c, 0xb6, 0x4f, 0x75, 0x01, 0x17,
+  0x01, 0x8f, 0xbd, 0x64, 0x46, 0xca, 0x2e, 0x08, 0x6f, 0x4d, 0xac, 0x08,
+  0x28, 0x1e, 0xc5, 0x4b, 0xa8, 0xea, 0xd3, 0x30, 0x79, 0x57, 0x40, 0xbb,
+  0x91, 0xbd, 0x29, 0x77, 0x49, 0x5e, 0x98, 0x81, 0x98, 0xb1, 0x9a, 0xdb,
+  0x24, 0x22, 0xa8, 0xfe, 0xde, 0x96, 0x4f, 0x22, 0x48, 0x3b, 0x5c, 0x1b,
+  0x38, 0xd9, 0x22, 0xfc, 0x9c, 0x68, 0x4b, 0x5e, 0x87, 0x95, 0x5f, 0xb8,
+  0x68, 0x05, 0x1d, 0x07, 0xb3, 0x4a, 0x68, 0x9b, 0xd2, 0xa2, 0xb2, 0xd9,
+  0x6c, 0xc0, 0x8c, 0xa0, 0xc4, 0x90, 0x48, 0x76, 0x86, 0x59, 0xa7, 0x74,
+  0xc2, 0x21, 0x76, 0xdf, 0x06, 0x0b, 0x6e, 0x1f, 0x64, 0x5f, 0x0d, 0x09,
+  0xa4, 0xac, 0x59, 0xcb, 0x82, 0xcb, 0x53, 0x22, 0x5e, 0xc2, 0xff, 0x3b,
+  0xbf, 0x0c, 0x26, 0x87, 0x87, 0xb4, 0xaa, 0x4c, 0x43, 0x48, 0xb1, 0x35,
+  0xb9, 0xb9, 0xae, 0x16, 0x5c, 0x2f, 0x26, 0x56, 0xcc, 0xc6, 0x37, 0x00,
+  0xf8, 0x51, 0x5d, 0xdd, 0x3a, 0x6b, 0xb8, 0x33, 0xfc, 0xee, 0xc9, 0xab,
+  0x56, 0xe1, 0x49, 0x9a, 0x8a, 0x69, 0x58, 0x46, 0xc1, 0xf3, 0x70, 0x48,
+  0x2d, 0x29, 0x73, 0x62, 0xdd, 0xdd, 0x62, 0x9b, 0x72, 0xd6, 0xce, 0x58,
+  0x8b, 0x83, 0xe1, 0x77, 0xf1, 0xe6, 0xa4, 0x15, 0xd6, 0x66, 0xb9, 0x0d,
+  0x6d, 0x18, 0x5b, 0x45, 0x2b, 0xa3, 0xd2, 0x66, 0xa0, 0x12, 0xc8, 0xfa,
+  0x99, 0x10, 0xc6, 0x71, 0x33, 0x2f, 0xa7, 0x84, 0x3a, 0xcf, 0x1e, 0x9e,
+  0x8b, 0x39, 0xe0, 0x8f, 0x7a, 0x70, 0x04, 0xb2, 0x5f, 0xfb, 0x65, 0xaa,
+  0xd1, 0xce, 0x98, 0xd8, 0x68, 0x78, 0x66, 0xe2, 0xcd, 0xb9, 0xa1, 0x6a,
+  0xfd, 0x26, 0x79, 0xd3, 0x1f, 0x42, 0x91, 0x94, 0x93, 0xc6, 0x1b, 0x01,
+  0x3d, 0x10, 0x6f, 0x8e, 0x85, 0x6f, 0x64, 0x64, 0x04, 0xe1, 0x86, 0x71,
+  0xbb, 0x7e, 0x64, 0xfc, 0x60, 0xb0, 0xc8, 0xe6, 0x87, 0x2c, 0xd2, 0x83,
+  0x15, 0x5e, 0x3d, 0xb2, 0xd8, 0x0a, 0xa3, 0x07, 0xdd, 0x05, 0x56, 0xc2,
+  0xfe, 0x8a, 0x97, 0x72, 0x10, 0x6f, 0xce, 0xae, 0xb0, 0x10, 0x37, 0xae,
+  0x59, 0x60, 0xf9, 0x4a, 0x30, 0x0b, 0x33, 0x23, 0x22, 0x8d, 0x16, 0x3c,
+  0xc9, 0xde, 0x73, 0xe1, 0x6c, 0xaa, 0x88, 0xdd, 0xbc, 0x5f, 0x3f, 0x21,
+  0x33, 0x49, 0x6f, 0xbc, 0x9f, 0xa3, 0x00, 0xa3, 0x15, 0x16, 0xc2, 0x94,
+  0x96, 0xd2, 0x6f, 0xc6, 0x25, 0x29, 0x81, 0x5c, 0xe4, 0xb2, 0x59, 0x3d,
+  0x21, 0xde, 0xf7, 0x12, 0x5b, 0x8a, 0x7a, 0x51, 0xe6, 0x85, 0xe6, 0x95,
+  0x8b, 0x8c, 0xf1, 0xba, 0x98, 0xc4, 0x52, 0xeb, 0xd7, 0x05, 0x5a, 0xe6,
+  0x1f, 0x08, 0x04, 0x6e, 0x15, 0x85, 0xf7, 0x11, 0xa6, 0x6b, 0x7f, 0x1f,
+  0xf3, 0xe3, 0x6e, 0x1f, 0xf3, 0xa8, 0x74, 0x1b, 0xbb, 0x5a, 0x5d, 0x0f,
+  0xaf, 0x76, 0xfb, 0x93, 0xf6, 0x4c, 0x76, 0xfb, 0xb7, 0xb8, 0x9b, 0x5a,
+  0xaf, 0xd0, 0xdd, 0xd4, 0x7e, 0x58, 0xef, 0x7f, 0xa0, 0xaf, 0xb4, 0x18,
+  0x1e, 0x01, 0x4f, 0xb9, 0xb1, 0x2b, 0xe5, 0x73, 0x5c, 0x31, 0x15, 0xa0,
+  0x79, 0x0c, 0xb4, 0xa4, 0xe0, 0xe3, 0x15, 0xaa, 0xfa, 0xc9, 0x04, 0xcb,
+  0x72, 0xac, 0x9e, 0x1c, 0x79, 0xda, 0x75, 0x91, 0xe5, 0xbb, 0x5f, 0xb7,
+  0x37, 0x9c, 0xa0, 0xd5, 0x02, 0x4f, 0xbe, 0xda, 0x39, 0x10, 0xd3, 0x8c,
+  0x9c, 0xc4, 0xb2, 0x15, 0x08, 0xcd, 0xcb, 0x0d, 0xa9, 0xdc, 0x5b, 0xb7,
+  0x91, 0x56, 0xce, 0x71, 0x35, 0x7f, 0xe0, 0x90, 0x9b, 0x07, 0xdc, 0xa8,
+  0x08, 0xd3, 0xe3, 0x8d, 0x2a, 0x38, 0x99, 0x72, 0x8c, 0x57, 0xcc, 0xfc,
+  0xaa, 0x1e, 0xb4, 0x76, 0xe1, 0xba, 0x9e, 0xd0, 0x83, 0xb1, 0xce, 0xb8,
+  0xa9, 0x45, 0x62, 0xcf, 0xbd, 0x27, 0x29, 0xe3, 0xcd, 0x49, 0x77, 0xdd,
+  0x7b, 0x32, 0x3d, 0x7d, 0xcf, 0x91, 0xca, 0xc4, 0xd8, 0xc6, 0xb8, 0x0c,
+  0xf7, 0x86, 0x1e, 0xf0, 0x5f, 0x24, 0x20, 0xc8, 0x8a, 0x9f, 0x15, 0xbe,
+  0xdd, 0x4e, 0x5f, 0x34, 0x77, 0xef, 0x1a, 0xb8, 0xad, 0x17, 0x6d, 0xb5,
+  0x0b, 0xce, 0x75, 0xd6, 0x10, 0x2a, 0x04, 0x03, 0x08, 0xa0, 0x34, 0x28,
+  0xac, 0x20, 0x8a, 0x2c, 0x18, 0x41, 0xa6, 0x44, 0x59, 0x1d, 0x62, 0xfb,
+  0xf8, 0x93, 0x4c, 0x01, 0x86, 0x49, 0x45, 0x15, 0x18, 0x51, 0x43, 0xb4,
+  0x8a, 0x5b, 0x9d, 0x89, 0x2d, 0xa1, 0x8f, 0x27, 0xcc, 0x82, 0x1d, 0x16,
+  0xaf, 0xeb, 0xb0, 0xb1, 0xd5, 0x43, 0xcf, 0x59, 0xc1, 0xd4, 0x91, 0xd9,
+  0xf5, 0xd4, 0x2f, 0x05, 0xe9, 0x0d, 0xbf, 0xea, 0xf3, 0x14, 0x5c, 0x9b,
+  0xc1, 0xe3, 0x8f, 0x28, 0x90, 0x95, 0x15, 0x6b, 0xa8, 0x2b, 0x94, 0x50,
+  0xb9, 0x9d, 0x5c, 0x64, 0x94, 0xb9, 0x75, 0x4b, 0xd2, 0x94, 0x52, 0xb3,
+  0x13, 0x6e, 0x61, 0x2b, 0x1f, 0x66, 0x02, 0x5c, 0x24, 0x15, 0x89, 0xc8,
+  0x65, 0x03, 0x9d, 0xc6, 0x6c, 0x8d, 0x6d, 0x36, 0xf8, 0x53, 0x2e, 0x05,
+  0xb2, 0x37, 0xdc, 0xeb, 0x73, 0x45, 0xc0, 0x4a, 0xd5, 0x45, 0xb5, 0x31,
+  0xe8, 0x27, 0xa9, 0xd0, 0xe6, 0x73, 0x2a, 0x67, 0xd7, 0x1b, 0x71, 0x41,
+  0xdf, 0xad, 0x43, 0x1f, 0x35, 0xfc, 0xdc, 0xce, 0xac, 0xb9, 0x4b, 0xef,
+  0x43, 0x45, 0x7d, 0x77, 0xf0, 0xf4, 0xb3, 0xcf, 0x5a, 0x37, 0x7a, 0xed,
+  0x11, 0x83, 0x3e, 0xdb, 0xdd, 0xe5, 0xac, 0xf3, 0xee, 0x6b, 0xe6, 0x17,
+  0x83, 0xcf, 0xf0, 0x62, 0xfb, 0xb5, 0x3a, 0x33, 0x4b, 0x30, 0x5d, 0xfd,
+  0xde, 0x80, 0x7e, 0x13, 0xf9, 0x1c, 0xbc, 0x2e, 0x2b, 0xdf, 0xfa, 0x8c,
+  0x3e, 0x17, 0x79, 0x8b, 0x13, 0xe2, 0x31, 0x8f, 0xe5, 0xd5, 0x15, 0xf9,
+  0xbb, 0xe8, 0x49, 0x5c, 0x7c, 0x66, 0x47, 0xdc, 0xa5, 0xd5, 0x34, 0x1c,
+  0xee, 0x6e, 0x7f, 0xb0, 0xb7, 0x6a, 0xb8, 0xa0, 0x35, 0x05, 0xbc, 0x85,
+  0x96, 0x93, 0xcc, 0x49, 0x63, 0x48, 0x30, 0x88, 0xb9, 0xdb, 0xd0, 0x9e,
+  0xe9, 0xd1, 0xde, 0x67, 0x9f, 0xf5, 0xa9, 0x67, 0xcf, 0x3e, 0xfb, 0x6c,
+  0x65, 0xd2, 0x9a, 0xf7, 0x99, 0xbb, 0xd2, 0x39, 0xa9, 0xe8, 0x75, 0xb7,
+  0x67, 0x6a, 0xb2, 0x57, 0xe2, 0xdf, 0xa1, 0xdf, 0x24, 0x2f, 0x93, 0xb7,
+  0x67, 0x97, 0xc7, 0x9e, 0xff, 0xc6, 0xf9, 0x67, 0xfd, 0x3a, 0x31, 0x08,
+  0x08, 0x2f, 0x50, 0x99, 0x02, 0xf6, 0xb1, 0x31, 0xb6, 0x42, 0x94, 0x03,
+  0x00, 0xb5, 0xea, 0x39, 0xfc, 0x43, 0xf7, 0x73, 0x67, 0x05, 0xea, 0x4f,
+  0x5c, 0xe7, 0x8d, 0xcf, 0xa4, 0xb0, 0x65, 0x16, 0x7b, 0x1b, 0x7e, 0x90,
+  0xdb, 0x74, 0x96, 0xdb, 0xc8, 0xce, 0x66, 0x4d, 0xf8, 0x53, 0x66, 0x55,
+  0xa4, 0x7f, 0x94, 0x8b, 0xcd, 0x00, 0x02, 0x9a, 0xcd, 0xc8, 0x79, 0x20,
+  0x37, 0x21, 0xbf, 0x30, 0xc0, 0x93, 0x72, 0x5a, 0x60, 0xd0, 0x72, 0x01,
+  0xcc, 0x14, 0xde, 0x65, 0xff, 0xe3, 0x91, 0xe0, 0x0e, 0x9c, 0x5e, 0x40,
+  0x9e, 0x29, 0x78, 0x9c, 0x9a, 0xe9, 0x7b, 0xd3, 0xb0, 0x59, 0x77, 0x0b,
+  0x65, 0x53, 0xb5, 0xe9, 0x38, 0xe0, 0x01, 0x11, 0x85, 0x69, 0xb6, 0x50,
+  0x7e, 0xc2, 0xa2, 0xdd, 0x8e, 0xd9, 0xcb, 0x57, 0xf9, 0xf5, 0xb2, 0x8a,
+  0x83, 0xab, 0x60, 0x9c, 0x0b, 0x96, 0x59, 0x39, 0x70, 0xd3, 0xbb, 0x54,
+  0x31, 0xd4, 0xa0, 0x2d, 0xd6, 0xc3, 0xad, 0x86, 0xb2, 0x62, 0x96, 0x89,
+  0xa0, 0x38, 0xf0, 0x8b, 0x11, 0xca, 0xdc, 0xe8, 0x31, 0xe4, 0x47, 0x10,
+  0x64, 0x09, 0x5c, 0x7f, 0x52, 0xaa, 0x46, 0x80, 0xe3, 0xea, 0x69, 0x37,
+  0x8b, 0x8d, 0x9a, 0x34, 0x69, 0x22, 0x53, 0xd0, 0x8d, 0xe2, 0x95, 0xcb,
+  0x4d, 0x8f, 0x73, 0x82, 0x9e, 0x85, 0x4f, 0xe6, 0xa6, 0xf4, 0x18, 0xaf,
+  0xc3, 0xc4, 0x52, 0x92, 0x3c, 0x9c, 0x28, 0x8e, 0xbf, 0xf2, 0x22, 0x99,
+  0xe7, 0xef, 0x8a, 0x59, 0x99, 0x4e, 0x6b, 0x29, 0xcc, 0x2b, 0xf1, 0x7d,
+  0x4c, 0x16, 0x73, 0x80, 0xc8, 0xd2, 0x06, 0x04, 0xa9, 0xb4, 0xd2, 0xbc,
+  0xc6, 0xc9, 0x96, 0x16, 0x91, 0xd5, 0x1d, 0xea, 0xb9, 0x49, 0x58, 0x4a,
+  0xd1, 0x4e, 0xe1, 0x34, 0xde, 0xed, 0x61, 0xcc, 0x0d, 0x40, 0xfb, 0x9d,
+  0x57, 0xcb, 0xf2, 0x36, 0xa3, 0x08, 0x14, 0x5d, 0x92, 0xd4, 0x5d, 0xbd,
+  0x90, 0x47, 0x27, 0xff, 0xf3, 0xf8, 0xf7, 0x0c, 0x81, 0x55, 0xe9, 0x9d,
+  0x4d, 0x6e, 0xf8, 0x9e, 0x59, 0xa5, 0x24, 0x34, 0x65, 0xb3, 0x69, 0xd3,
+  0x99, 0x58, 0xf1, 0x54, 0x34, 0x17, 0xb7, 0x07, 0x62, 0x9c, 0x52, 0xe3,
+  0xcd, 0x6c, 0xac, 0x70, 0x6f, 0x53, 0x0a, 0x82, 0x23, 0x13, 0x61, 0x62,
+  0x53, 0xa0, 0xd2, 0xb1, 0x1e, 0x36, 0x54, 0xc2, 0xf5, 0x7a, 0xd9, 0xbe,
+  0x87, 0x5b, 0x18, 0x15, 0x32, 0x83, 0x9a, 0x04, 0x05, 0x88, 0x8a, 0xa8,
+  0x5b, 0xa6, 0xb7, 0x0f, 0x14, 0xd9, 0xf1, 0xf3, 0x01, 0x51, 0x97, 0xb1,
+  0xca, 0x28, 0x5a, 0x56, 0x25, 0x2f, 0xde, 0x5d, 0x9c, 0xae, 0x48, 0xea,
+  0x18, 0x61, 0x15, 0x68, 0xba, 0x7a, 0x17, 0x19, 0xe8, 0x48, 0xaa, 0xe4,
+  0x3c, 0xbd, 0xce, 0x7a, 0x3e, 0xab, 0x4b, 0x8b, 0xd8, 0x49, 0x9c, 0x10,
+  0x31, 0x4f, 0x91, 0x4f, 0x23, 0x4d, 0x62, 0xdc, 0x45, 0xa9, 0xfd, 0x4c,
+  0x8c, 0xab, 0x59, 0x2a, 0xb3, 0xb7, 0xac, 0x50, 0x2d, 0xfa, 0xfb, 0x68,
+  0x2d, 0x06, 0x0b, 0xcc, 0xef, 0x30, 0x72, 0xf9, 0xb8, 0xaa, 0x74, 0x41,
+  0xbb, 0x28, 0xe9, 0x7d, 0x4e, 0x9e, 0xfa, 0x9e, 0x76, 0x73, 0x90, 0xc5,
+  0x78, 0x95, 0x79, 0x2a, 0x28, 0x4e, 0xed, 0xbb, 0x94, 0x3a, 0x3e, 0x7e,
+  0x0e, 0xb6, 0x70, 0x9c, 0x2b, 0x23, 0xd2, 0xb5, 0x3a, 0x56, 0x85, 0x94,
+  0x93, 0x24, 0x73, 0x24, 0xfb, 0x0a, 0xee, 0x33, 0x4d, 0x4e, 0xa5, 0x7f,
+  0x07, 0x12, 0x94, 0x61, 0x6d, 0x48, 0xbb, 0xd6, 0x02, 0x2a, 0xc5, 0x06,
+  0x9b, 0xce, 0x88, 0xe0, 0xdd, 0xba, 0xb2, 0x68, 0x8c, 0xd3, 0x92, 0x38,
+  0xc1, 0x51, 0x48, 0xb4, 0xb0, 0x7e, 0xe7, 0xd6, 0xca, 0xfe, 0xee, 0x0c,
+  0x44, 0x2e, 0x50, 0x74, 0xa8, 0x95, 0xe3, 0x07, 0x66, 0x77, 0x14, 0x92,
+  0xaf, 0xe7, 0x2d, 0xab, 0xb7, 0xf7, 0xfe, 0xa3, 0x1f, 0x25, 0xb2, 0x5e,
+  0x41, 0xbe, 0xe7, 0x75, 0xb7, 0x01, 0xc6, 0x19, 0x4b, 0x78, 0xd6, 0xef,
+  0x50, 0x69, 0xbb, 0xb4, 0x1e, 0xb9, 0x2e, 0xa3, 0xbe, 0xc5, 0x81, 0x97,
+  0xd6, 0x91, 0x1c, 0x71, 0x86, 0xc9, 0xe0, 0x55, 0x6e, 0xee, 0x91, 0x9a,
+  0xa9, 0x12, 0xd8, 0x31, 0xc0, 0x29, 0x12, 0xee, 0x30, 0x86, 0xd5, 0x52,
+  0x34, 0x9e, 0x02, 0x24, 0x9d, 0x7d, 0xc5, 0x06, 0x77, 0xcc, 0x9e, 0x58,
+  0xc5, 0xaa, 0x25, 0xb7, 0xb8, 0xd3, 0x18, 0x52, 0xe7, 0xb2, 0x90, 0xba,
+  0xa6, 0x6c, 0x5c, 0x6b, 0xda, 0x09, 0xe1, 0x70, 0x22, 0xf3, 0xa3, 0x04,
+  0x06, 0x0c, 0xe5, 0x41, 0x65, 0xd6, 0x56, 0x5d, 0x81, 0xc0, 0xe0, 0xb4,
+  0x04, 0x45, 0x8c, 0x3e, 0xe9, 0xfa, 0x81, 0x4d, 0xa7, 0x2c, 0xb5, 0x3b,
+  0x47, 0x59, 0x98, 0x76, 0x87, 0x53, 0x68, 0x26, 0xa6, 0xd9, 0x61, 0x67,
+  0x08, 0xca, 0x4a, 0xbf, 0x02, 0x65, 0xd8, 0x1a, 0x18, 0x10, 0x8f, 0xfe,
+  0xd6, 0xa3, 0x28, 0x42, 0x51, 0x4a, 0x26, 0x7a, 0x2c, 0xa6, 0x0f, 0x38,
+  0x11, 0x3d, 0xe2, 0xdf, 0x85, 0x8c, 0x20, 0x49, 0xfe, 0x34, 0x70, 0xcc,
+  0xe0, 0x5b, 0xf7, 0x99, 0xd1, 0xb2, 0x1d, 0x0a, 0x05, 0xc6, 0x54, 0x24,
+  0x47, 0x25, 0xe1, 0x82, 0x57, 0x75, 0xd9, 0x29, 0x8b, 0x7e, 0xef, 0xc7,
+  0x20, 0x79, 0xd2, 0x8d, 0x26, 0x40, 0xb4, 0xba, 0xcb, 0x22, 0xfb, 0x48,
+  0x54, 0x8f, 0xab, 0x9b, 0x0b, 0x15, 0xed, 0xef, 0x0f, 0x2f, 0xde, 0x9e,
+  0xbc, 0xfd, 0xfa, 0x80, 0xb2, 0xe1, 0xb2, 0x6a, 0x42, 0xd5, 0x19, 0x93,
+  0xbf, 0x2d, 0xa7, 0xf9, 0x84, 0x65, 0x85, 0x54, 0xbd, 0x6b, 0x51, 0x2d,
+  0x67, 0xe2, 0x66, 0x35, 0xe2, 0x25, 0x90, 0xef, 0x02, 0x44, 0x25, 0xa2,
+  0xe8, 0xaa, 0xbc, 0x5e, 0xda, 0xa9, 0x9f, 0x40, 0x1d, 0x41, 0xb0, 0x00,
+  0x81, 0x54, 0x92, 0x48, 0xbc, 0x69, 0x89, 0x49, 0xc3, 0x28, 0x0b, 0xaf,
+  0x4e, 0x4f, 0x93, 0x90, 0x63, 0x0f, 0x25, 0x23, 0x95, 0x0c, 0x9c, 0x21,
+  0x4c, 0x68, 0xc8, 0x6c, 0xff, 0x3a, 0x1f, 0xcf, 0x60, 0x93, 0x91, 0x02,
+  0xc0, 0xa5, 0x78, 0x3c, 0xb9, 0x67, 0xcc, 0x57, 0xd3, 0x95, 0xee, 0x22,
+  0x03, 0x23, 0x0b, 0xb4, 0x22, 0x56, 0x38, 0xaf, 0xa6, 0xb0, 0x87, 0x8c,
+  0x98, 0x2c, 0xaf, 0x1a, 0x52, 0x91, 0x5a, 0xb7, 0x69, 0x9b, 0xe3, 0x7e,
+  0x5d, 0x24, 0xe1, 0x86, 0x2d, 0x1d, 0x1f, 0x12, 0x21, 0xb1, 0x4b, 0x90,
+  0x57, 0x99, 0xfd, 0xc8, 0xba, 0x21, 0x6a, 0x23, 0x44, 0xc3, 0x68, 0xd3,
+  0x2c, 0xb5, 0x25, 0x1f, 0x6b, 0x92, 0x97, 0xa1, 0xc0, 0xb8, 0xcb, 0xaa,
+  0xcc, 0x95, 0x69, 0x47, 0xaa, 0x93, 0x11, 0x77, 0xc3, 0x64, 0x54, 0x9a,
+  0xe7, 0x43, 0x2d, 0xcb, 0x96, 0x11, 0x6a, 0x55, 0x24, 0x45, 0x7f, 0x1c,
+  0xd0, 0x0b, 0x15, 0x16, 0x10, 0x9d, 0x6b, 0x8f, 0x37, 0x52, 0xc2, 0x90,
+  0xf6, 0xff, 0x38, 0xb3, 0x4a, 0x05, 0x7d, 0x01, 0x11, 0x20, 0xda, 0x21,
+  0xbd, 0x81, 0x11, 0xa8, 0x3d, 0x9a, 0x59, 0x14, 0x56, 0xf4, 0x5a, 0x7a,
+  0xa0, 0x3c, 0x98, 0x0f, 0xb3, 0xee, 0x0e, 0x38, 0x5a, 0x74, 0xc5, 0x2b,
+  0x66, 0x90, 0x8a, 0xed, 0xe9, 0xf9, 0x4f, 0xa5, 0xf6, 0x85, 0x0d, 0xab,
+  0x32, 0xed, 0x7b, 0x46, 0x5a, 0x66, 0x10, 0x2a, 0x3f, 0x73, 0x15, 0x8d,
+  0x88, 0x2e, 0xc3, 0xcb, 0xe7, 0xf3, 0x5f, 0x96, 0x0b, 0xa7, 0xef, 0x1c,
+  0x0c, 0x39, 0x92, 0x56, 0x9a, 0x20, 0x2a, 0x75, 0x35, 0xdc, 0x8e, 0x02,
+  0x7d, 0xb8, 0x0f, 0x72, 0x27, 0xd5, 0x46, 0xbf, 0x9e, 0x3e, 0x28, 0xf8,
+  0xb4, 0x6e, 0x4c, 0xf7, 0x96, 0xc6, 0x82, 0x5a, 0xcf, 0x92, 0x36, 0x95,
+  0x26, 0x5e, 0xb9, 0x6f, 0x3f, 0xa8, 0x29, 0xb1, 0x52, 0xa4, 0x4f, 0x46,
+  0x9a, 0x93, 0x84, 0x0e, 0x89, 0x59, 0xad, 0x14, 0xc2, 0x12, 0xbf, 0xc9,
+  0x8b, 0xdb, 0x12, 0xbf, 0x91, 0x98, 0x53, 0x90, 0xe2, 0xeb, 0x93, 0x65,
+  0xc5, 0x26, 0xc2, 0x9f, 0x55, 0x75, 0xd2, 0x28, 0x0a, 0xde, 0x8c, 0x85,
+  0xb9, 0xe6, 0xeb, 0xc4, 0x31, 0xca, 0x0b, 0xf4, 0x20, 0x72, 0x35, 0xf2,
+  0x61, 0xa2, 0xcd, 0xdb, 0xb7, 0x55, 0x32, 0xcd, 0x8b, 0x33, 0xaa, 0xe2,
+  0xed, 0x71, 0xcc, 0xeb, 0x85, 0x23, 0xf7, 0x4d, 0x6e, 0xfd, 0x3f, 0xab,
+  0x6f, 0x92, 0x61, 0xbb, 0x06, 0x57, 0xcb, 0x86, 0xa5, 0x48, 0x33, 0x0e,
+  0x92, 0xa4, 0xc3, 0x94, 0xa5, 0xb0, 0x9d, 0xae, 0x12, 0xb6, 0x09, 0x94,
+  0x1a, 0x24, 0xee, 0xae, 0xd0, 0x20, 0xda, 0xc5, 0x97, 0x24, 0x5b, 0xa1,
+  0x7b, 0xf6, 0x3c, 0x52, 0xa4, 0x16, 0x21, 0x59, 0xfb, 0x6e, 0xe3, 0xfe,
+  0xd8, 0xcb, 0x39, 0xb1, 0xe5, 0x3a, 0x62, 0x30, 0x07, 0xbe, 0xba, 0xe3,
+  0xd3, 0x23, 0x50, 0x4f, 0x7f, 0x52, 0xa2, 0x97, 0x1d, 0x83, 0x3f, 0x1d,
+  0x73, 0x25, 0x76, 0x0d, 0x4c, 0xa7, 0xa2, 0x1d, 0xd6, 0x40, 0x4f, 0xf3,
+  0x06, 0x02, 0xe4, 0x4f, 0xfb, 0xbb, 0xab, 0x84, 0x3c, 0x35, 0xa4, 0x45,
+  0x13, 0xe8, 0x34, 0xd6, 0xd6, 0x06, 0xc3, 0x35, 0xe8, 0xb2, 0x63, 0xe9,
+  0x0e, 0x59, 0x2e, 0xc8, 0x57, 0x37, 0xa0, 0xfd, 0x92, 0xd6, 0xab, 0xe6,
+  0x7f, 0xf8, 0xaf, 0xa8, 0xe6, 0xe3, 0xe4, 0xd7, 0x85, 0xb7, 0xc6, 0xd4,
+  0x50, 0x0c, 0xf1, 0xa6, 0xb2, 0x44, 0x7d, 0x25, 0x9e, 0xda, 0xee, 0x74,
+  0x06, 0xd8, 0xf6, 0x28, 0xdb, 0x22, 0x87, 0x93, 0x5a, 0x0b, 0x4d, 0xd8,
+  0x74, 0xbe, 0x70, 0x85, 0x78, 0xf4, 0x78, 0x09, 0x32, 0x47, 0x4f, 0x81,
+  0x82, 0x5a, 0x2c, 0x70, 0x97, 0xbf, 0x18, 0x6e, 0x5a, 0x4f, 0x94, 0xb2,
+  0x49, 0x9e, 0x0a, 0x82, 0x14, 0x53, 0x42, 0xdf, 0x6a, 0x5f, 0x8d, 0x00,
+  0xa7, 0x0d, 0xa2, 0x3e, 0xff, 0x28, 0x09, 0xb5, 0x00, 0xda, 0x7d, 0x96,
+  0xda, 0x1e, 0xbf, 0xdd, 0x4b, 0xb6, 0x48, 0xae, 0x6e, 0x5b, 0xed, 0x35,
+  0x8c, 0xf7, 0x2b, 0x0b, 0x37, 0xdb, 0x31, 0x29, 0xdf, 0x91, 0x5d, 0x3c,
+  0x2f, 0x69, 0xb0, 0xc6, 0xd2, 0xab, 0x8c, 0x06, 0xb0, 0x9c, 0xa5, 0x15,
+  0x20, 0x7b, 0xd9, 0xd5, 0x72, 0x16, 0x33, 0x75, 0xe8, 0x74, 0x4b, 0x90,
+  0x28, 0xaf, 0xeb, 0xa5, 0x18, 0x82, 0x36, 0xf7, 0xd9, 0x72, 0x23, 0x25,
+  0x33, 0xd3, 0x1f, 0x7c, 0xba, 0x9e, 0x11, 0x0a, 0x65, 0xa5, 0x82, 0x02,
+  0x1f, 0xb1, 0xd6, 0xe5, 0x14, 0x2d, 0x53, 0x6c, 0x29, 0xb9, 0x52, 0xae,
+  0xa9, 0x53, 0xd8, 0xe4, 0x0b, 0xd4, 0x44, 0x32, 0x7a, 0x14, 0xdd, 0x56,
+  0x9d, 0xe6, 0x7a, 0x67, 0xe7, 0x97, 0x27, 0x67, 0x6f, 0x47, 0xc9, 0x9f,
+  0x7b, 0x6b, 0x13, 0x94, 0xda, 0x64, 0x8a, 0x3f, 0xf4, 0xdd, 0x9a, 0x24,
+  0x2f, 0xc4, 0xdb, 0xb0, 0xca, 0x3e, 0xf6, 0xd4, 0xf8, 0x89, 0xb9, 0xbf,
+  0x8d, 0x84, 0xd5, 0x37, 0x85, 0x85, 0x46, 0x56, 0xab, 0x93, 0x71, 0x19,
+  0xe8, 0xcb, 0x34, 0x2b, 0x6d, 0x0c, 0xa3, 0x8d, 0xe6, 0x5f, 0xb6, 0x10,
+  0xb6, 0x9d, 0xe6, 0xe3, 0x32, 0x58, 0x64, 0x5f, 0x0b, 0x5d, 0x2a, 0x2f,
+  0xb8, 0xb2, 0xe1, 0x62, 0x45, 0x6f, 0xb1, 0xd4, 0x54, 0x55, 0xab, 0x8e,
+  0xa0, 0x09, 0xbf, 0x3e, 0xbe, 0x24, 0x57, 0xcd, 0x05, 0x8c, 0x21, 0xdb,
+  0x41, 0x38, 0xbc, 0x44, 0xf5, 0x49, 0xad, 0x7a, 0x26, 0xe4, 0x95, 0x5c,
+  0xee, 0xf6, 0xe3, 0x62, 0x96, 0x16, 0xd1, 0x24, 0x2c, 0xa3, 0xd3, 0x52,
+  0x05, 0xdf, 0xd2, 0xd1, 0xd4, 0xa9, 0x07, 0xc5, 0xa3, 0x49, 0x67, 0xfe,
+  0x88, 0xf3, 0x77, 0x97, 0xe2, 0xad, 0x7a, 0x75, 0x7c, 0x7a, 0x7c, 0x79,
+  0xdc, 0xb5, 0xde, 0xc7, 0x4c, 0xbb, 0x85, 0xec, 0x9b, 0x26, 0x9b, 0xdc,
+  0x14, 0xe5, 0xac, 0xbc, 0xce, 0xa5, 0x88, 0x59, 0xf2, 0x7d, 0x36, 0x7e,
+  0x75, 0xf8, 0x1d, 0x69, 0x14, 0xe4, 0x79, 0x3a, 0xbf, 0x38, 0x3b, 0x7f,
+  0x7d, 0xf2, 0xf6, 0x55, 0x3f, 0x39, 0x3a, 0x3b, 0xff, 0x6b, 0x3f, 0x79,
+  0x73, 0xf6, 0xdd, 0x71, 0x04, 0x75, 0x4d, 0xbc, 0xb5, 0x91, 0x22, 0xca,
+  0x52, 0x4a, 0xc8, 0x19, 0xdf, 0x05, 0x07, 0x2e, 0xbc, 0x6b, 0xe4, 0x10,
+  0xe8, 0x11, 0x54, 0x04, 0xc7, 0x59, 0x33, 0x53, 0x67, 0xe4, 0xc7, 0x37,
+  0xc7, 0x87, 0xaf, 0xfa, 0x01, 0x69, 0x29, 0x71, 0x9f, 0x9b, 0x8f, 0xd1,
+  0xf8, 0xec, 0xa0, 0x41, 0x75, 0xc9, 0xf6, 0x07, 0x74, 0x04, 0x0e, 0x75,
+  0xf1, 0x89, 0x35, 0x1b, 0x16, 0x85, 0x5f, 0xa6, 0xab, 0x10, 0x14, 0x42,
+  0x92, 0xbb, 0xb2, 0x6c, 0xa0, 0x97, 0x09, 0x42, 0xea, 0x9a, 0x2a, 0xda,
+  0x52, 0xe4, 0x95, 0x79, 0x25, 0x12, 0x80, 0xfd, 0x65, 0x6f, 0xd8, 0x32,
+  0x4b, 0x11, 0x9e, 0x0e, 0xe9, 0x32, 0xb3, 0x3e, 0x5b, 0x46, 0x55, 0x88,
+  0x24, 0xf6, 0x41, 0xa6, 0x52, 0x74, 0x09, 0x04, 0xf5, 0x04, 0x03, 0x1a,
+  0x31, 0xb7, 0xa7, 0x50, 0xda, 0xc5, 0xd3, 0x1b, 0x54, 0xcd, 0x16, 0x06,
+  0x55, 0xe1, 0x98, 0xa0, 0xf9, 0x73, 0x1f, 0xd4, 0x2a, 0x02, 0x3f, 0xf0,
+  0xc4, 0x46, 0x71, 0xd7, 0x5c, 0x06, 0xe5, 0xca, 0x6c, 0xcd, 0x8c, 0x01,
+  0x56, 0xbc, 0x54, 0xd6, 0x3d, 0x90, 0x0c, 0x4e, 0xd4, 0x39, 0xb1, 0x4e,
+  0xcd, 0xb2, 0x5c, 0x52, 0xe2, 0xa0, 0x61, 0x66, 0x0b, 0xf5, 0x5d, 0xb5,
+  0x45, 0x85, 0xef, 0x29, 0xa1, 0x81, 0x46, 0xb4, 0x7e, 0x5d, 0x66, 0x25,
+  0x5e, 0x90, 0x41, 0x7b, 0xb3, 0xc2, 0x39, 0x88, 0x81, 0x4f, 0x2b, 0x2c,
+  0x0d, 0x2e, 0xfc, 0x63, 0x46, 0x9c, 0x14, 0xe2, 0x1b, 0x4d, 0x28, 0x08,
+  0x37, 0x60, 0x8b, 0xda, 0x47, 0x09, 0xab, 0x04, 0x15, 0x0d, 0x55, 0xfa,
+  0x10, 0xaf, 0x75, 0xdb, 0x2a, 0x15, 0x69, 0x4f, 0xfa, 0x93, 0xdd, 0x8f,
+  0xce, 0xdb, 0x4e, 0x3a, 0x45, 0x9d, 0x0c, 0x84, 0x41, 0x74, 0x6e, 0x2e,
+  0xc2, 0xd0, 0xcf, 0xb4, 0xf5, 0x7a, 0x85, 0x70, 0xf4, 0xfd, 0xb7, 0xb2,
+  0x18, 0x9e, 0x98, 0x3a, 0x3d, 0x31, 0x47, 0x22, 0x92, 0xc6, 0x3f, 0x2d,
+  0x51, 0x10, 0x11, 0xd0, 0x04, 0x68, 0x57, 0x98, 0x7d, 0xd3, 0x56, 0xf8,
+  0x61, 0xaa, 0x10, 0x1a, 0xfd, 0x32, 0x4a, 0x87, 0x3e, 0xf0, 0xe9, 0x60,
+  0xcd, 0x2e, 0x8e, 0x2f, 0x2f, 0x86, 0xc9, 0x96, 0xcf, 0x50, 0xf7, 0x7c,
+  0xb8, 0x1b, 0x86, 0x6f, 0xa8, 0x38, 0x69, 0xf4, 0xab, 0xa8, 0x5a, 0xba,
+  0xe2, 0xab, 0x90, 0x0f, 0xf4, 0xdd, 0x10, 0x77, 0xec, 0xb1, 0x52, 0xec,
+  0xc6, 0xbe, 0xe7, 0x97, 0x40, 0x6d, 0x7d, 0x8f, 0x7e, 0xb1, 0x66, 0x94,
+  0xdf, 0x1c, 0x9f, 0x46, 0xa8, 0xf7, 0xbf, 0xbb, 0x78, 0xfd, 0xd7, 0xf6,
+  0x28, 0x9f, 0x3c, 0x8d, 0x7c, 0xf5, 0xb7, 0x74, 0xad, 0x67, 0x75, 0x39,
+  0x33, 0x4a, 0x0b, 0x92, 0x4b, 0x90, 0x5b, 0x72, 0x60, 0xae, 0x01, 0xc2,
+  0xa6, 0x7f, 0x11, 0x32, 0xab, 0xc2, 0x39, 0x63, 0x47, 0x28, 0xcf, 0x89,
+  0xe9, 0xed, 0x6c, 0x6f, 0xce, 0xe0, 0xe1, 0x7b, 0x82, 0x93, 0x4d, 0x16,
+  0x69, 0x1e, 0xf8, 0xa1, 0xdf, 0xa9, 0xea, 0x93, 0x53, 0x5a, 0x8e, 0xf5,
+  0x14, 0xab, 0x1a, 0xa7, 0xa4, 0x25, 0x7c, 0x4a, 0xb7, 0xea, 0x6d, 0xa9,
+  0x1d, 0xbf, 0x2a, 0xba, 0xaf, 0x9d, 0x41, 0xa2, 0x14, 0x55, 0x70, 0x16,
+  0x33, 0xc7, 0x5d, 0xb2, 0x85, 0x5e, 0x1a, 0x32, 0xe4, 0xa9, 0x7b, 0x29,
+  0xbc, 0x67, 0xc7, 0x72, 0x29, 0x0f, 0xe1, 0x9c, 0x44, 0x4c, 0x1d, 0x96,
+  0x17, 0x2e, 0x14, 0xd4, 0xc0, 0xcb, 0x9a, 0xc9, 0x0e, 0x57, 0xb8, 0xf7,
+  0x75, 0xbf, 0x15, 0x6e, 0xaf, 0xb2, 0x68, 0x41, 0x1e, 0xe9, 0x72, 0x60,
+  0xaf, 0xb3, 0x9f, 0x7c, 0xe8, 0xaa, 0x26, 0xb0, 0x17, 0x49, 0x32, 0x74,
+  0xa8, 0x1b, 0x91, 0xf0, 0x7b, 0xbb, 0x50, 0x81, 0x97, 0x10, 0xa9, 0x55,
+  0xe4, 0x03, 0x29, 0xe8, 0x92, 0xe6, 0x22, 0x4e, 0x15, 0x08, 0x65, 0xdd,
+  0x40, 0x96, 0x22, 0xb5, 0x7d, 0x13, 0xa8, 0x7b, 0xce, 0x5f, 0xf8, 0x98,
+  0x83, 0x97, 0xd4, 0x6b, 0xf4, 0x80, 0xf9, 0x4e, 0xd5, 0x84, 0x5f, 0xa0,
+  0xf2, 0xf5, 0x8a, 0xc4, 0x2f, 0x56, 0x79, 0xb5, 0x65, 0x92, 0xeb, 0x6d,
+  0x9e, 0xea, 0xf6, 0x68, 0xd4, 0xf9, 0x3e, 0x78, 0x1a, 0x06, 0x10, 0xf2,
+  0xc5, 0xed, 0x53, 0x78, 0x6c, 0x9e, 0xf7, 0xf9, 0x5f, 0xcf, 0x99, 0xb7,
+  0xa9, 0x69, 0x87, 0x13, 0x58, 0x71, 0x67, 0x35, 0xf7, 0xe4, 0x5c, 0x13,
+  0x4d, 0x03, 0x76, 0x65, 0x89, 0xbc, 0x49, 0x4a, 0xbb, 0xe9, 0xa5, 0xa6,
+  0x8e, 0x99, 0x77, 0xb4, 0xb7, 0x24, 0x03, 0xcd, 0x61, 0xfd, 0x71, 0x5c,
+  0x51, 0xe9, 0xaf, 0xa6, 0xfe, 0x79, 0x5d, 0x4e, 0xaf, 0x51, 0x72, 0x3f,
+  0x19, 0xae, 0x48, 0x0e, 0xb5, 0x24, 0x15, 0x88, 0x99, 0xe8, 0x1e, 0xf4,
+  0x4d, 0x38, 0x72, 0x0f, 0x4d, 0xe5, 0x27, 0x98, 0x62, 0x01, 0x1b, 0x95,
+  0x81, 0x4a, 0x80, 0x3d, 0xbe, 0x96, 0xa8, 0x79, 0x6f, 0xf8, 0xa4, 0x2d,
+  0x09, 0x9a, 0xea, 0x1e, 0x09, 0x29, 0xc6, 0xbc, 0x8f, 0x6c, 0xba, 0x93,
+  0xa2, 0x63, 0xb2, 0xcb, 0xe1, 0xa2, 0xe0, 0x1a, 0xff, 0xd8, 0x1c, 0x64,
+  0x05, 0xa0, 0x24, 0xc7, 0x94, 0x34, 0x73, 0x71, 0xfc, 0xfa, 0xdd, 0xe8,
+  0xf8, 0x55, 0x92, 0x46, 0xea, 0xf2, 0x21, 0xee, 0x96, 0xc3, 0xb5, 0xc3,
+  0xee, 0x6d, 0xd3, 0x68, 0xc9, 0x5b, 0x5b, 0xfa, 0x12, 0x14, 0x32, 0x12,
+  0x90, 0x8a, 0xb1, 0xad, 0xc2, 0x2c, 0x07, 0xd6, 0x02, 0xe4, 0xc5, 0x5f,
+  0xc0, 0xbd, 0xc0, 0xa3, 0x9e, 0x66, 0x54, 0x77, 0xe1, 0x05, 0xa3, 0x29,
+  0x02, 0xc9, 0xf7, 0xc6, 0x6e, 0x9a, 0x7a, 0x96, 0x65, 0x0b, 0xc9, 0x64,
+  0x9b, 0x97, 0xcb, 0x82, 0x5d, 0x6b, 0x66, 0x65, 0xd4, 0x9b, 0xc4, 0xee,
+  0xcb, 0x04, 0xad, 0x6a, 0xf8, 0x29, 0x3a, 0x72, 0x54, 0x77, 0x20, 0xcf,
+  0x01, 0x40, 0xcc, 0x2e, 0x86, 0x96, 0x46, 0x66, 0x66, 0x2b, 0x6f, 0x7c,
+  0x57, 0xec, 0x8a, 0x2a, 0x22, 0x54, 0x77, 0xce, 0xe8, 0xd6, 0xdc, 0x9d,
+  0x74, 0x76, 0x5d, 0x56, 0xa6, 0xc1, 0xb9, 0x4d, 0xbf, 0xab, 0x00, 0x9e,
+  0xa9, 0xb7, 0xdb, 0xb3, 0x1a, 0x26, 0x32, 0x33, 0xa8, 0x1f, 0xa1, 0xd4,
+  0x8c, 0x13, 0x93, 0xe9, 0x9c, 0xf1, 0x3c, 0xc1, 0xe2, 0xa6, 0x20, 0x13,
+  0x8b, 0xc6, 0x91, 0xa4, 0x12, 0x63, 0x3e, 0x78, 0x0a, 0x83, 0x8d, 0xf8,
+  0x8f, 0xac, 0x2a, 0xbb, 0x2e, 0x01, 0x55, 0xfc, 0x62, 0x3d, 0xff, 0x57,
+  0x96, 0xea, 0xd8, 0xdb, 0x8f, 0x9d, 0x80, 0x79, 0xfa, 0x11, 0x6e, 0x8e,
+  0x95, 0xdb, 0x81, 0x9d, 0x7e, 0x34, 0x1d, 0xf4, 0x18, 0x10, 0x12, 0xc4,
+  0x87, 0xdf, 0xd8, 0xf2, 0x8b, 0x0a, 0xee, 0x45, 0xf1, 0x1e, 0xb7, 0xda,
+  0xe2, 0x09, 0x09, 0xd0, 0x44, 0xbc, 0x30, 0xb6, 0xd7, 0xf0, 0x35, 0xa5,
+  0x34, 0x4c, 0x32, 0x02, 0xb6, 0xb8, 0x20, 0x01, 0xbe, 0xb7, 0x4d, 0x3f,
+  0x9e, 0x95, 0x14, 0xe9, 0x62, 0x4f, 0x0e, 0xbe, 0x1f, 0xd6, 0x11, 0x25,
+  0x15, 0xb3, 0xa2, 0x8d, 0xa8, 0x26, 0x11, 0xfb, 0x15, 0xc1, 0xac, 0x8e,
+  0xd4, 0xa4, 0x7c, 0x22, 0x5e, 0x73, 0x2d, 0xbd, 0x81, 0x71, 0xf0, 0x9b,
+  0x81, 0x20, 0xe1, 0x76, 0x94, 0x23, 0xdc, 0x34, 0xd1, 0x6f, 0x93, 0x08,
+  0x4a, 0xb7, 0x91, 0xfb, 0x87, 0x64, 0x91, 0x1b, 0xf8, 0x9d, 0x39, 0xf1,
+  0x3b, 0x62, 0x5d, 0xf7, 0x95, 0xcd, 0x1d, 0x89, 0x34, 0x34, 0x1c, 0x98,
+  0x29, 0x69, 0xe1, 0xf7, 0x15, 0x0b, 0x60, 0xda, 0xc8, 0xcb, 0x29, 0x52,
+  0x70, 0x98, 0x15, 0x3e, 0xac, 0x6d, 0x25, 0xc5, 0x82, 0xa5, 0x33, 0x14,
+  0xa7, 0x32, 0xcb, 0x97, 0xcf, 0x97, 0x73, 0x76, 0x2e, 0xf5, 0x39, 0xd0,
+  0x33, 0x98, 0xd3, 0x55, 0xa0, 0x0b, 0x0b, 0xa4, 0x1a, 0x03, 0x7b, 0xba,
+  0x7b, 0xdf, 0x86, 0x2e, 0xb1, 0x6d, 0xa5, 0x04, 0x2e, 0xbd, 0xc3, 0x84,
+  0xd2, 0x58, 0xa8, 0xff, 0xe3, 0x3b, 0x34, 0x79, 0x61, 0x54, 0x83, 0x2f,
+  0xc2, 0x4e, 0xa4, 0x9e, 0xe4, 0x60, 0xc1, 0x81, 0x9d, 0x49, 0x88, 0xd9,
+  0x6c, 0xea, 0x59, 0x21, 0xbc, 0xdd, 0xe0, 0xec, 0x95, 0x55, 0x5a, 0x2d,
+  0xa3, 0xa4, 0x92, 0x10, 0xfa, 0x2b, 0x7b, 0x9e, 0x86, 0xea, 0x5c, 0x88,
+  0x7c, 0x2d, 0xc9, 0xc6, 0xbf, 0xe6, 0x4a, 0xa3, 0xcb, 0x45, 0x70, 0x8d,
+  0x5a, 0x49, 0x61, 0xdd, 0x8f, 0xe6, 0xf3, 0xbb, 0x82, 0xad, 0x10, 0xdb,
+  0x88, 0xbc, 0xae, 0x32, 0xc7, 0xd6, 0x15, 0x92, 0xd7, 0xc9, 0x6a, 0x91,
+  0x47, 0x9e, 0x90, 0xcb, 0xe0, 0x1a, 0x61, 0x5a, 0x00, 0xe6, 0x83, 0x39,
+  0xa0, 0x49, 0xe1, 0xe5, 0xeb, 0x6b, 0xe6, 0xd7, 0xd3, 0x8f, 0x1f, 0xc3,
+  0xcb, 0xd2, 0x19, 0x54, 0x5c, 0x06, 0x97, 0xad, 0xad, 0x67, 0x1f, 0x3b,
+  0xd6, 0xd6, 0x30, 0x5a, 0xac, 0x56, 0x33, 0x40, 0xd3, 0x71, 0xc9, 0x11,
+  0x1c, 0x9e, 0xa9, 0xd4, 0x9b, 0x45, 0x75, 0x42, 0x8b, 0x50, 0xb8, 0x4b,
+  0xf3, 0x68, 0x39, 0x1a, 0x81, 0xf3, 0x79, 0x35, 0xbc, 0x34, 0xce, 0x66,
+  0xfe, 0x6c, 0x6e, 0x8c, 0xfe, 0x48, 0xb3, 0xa8, 0x93, 0xa4, 0x8d, 0x4e,
+  0xcb, 0x25, 0xc7, 0xc1, 0xb2, 0x20, 0xb0, 0x92, 0xf3, 0xb4, 0xd3, 0x69,
+  0x32, 0xb7, 0x55, 0x8e, 0xb2, 0xc8, 0x7c, 0xa4, 0xeb, 0x64, 0xcf, 0xcc,
+  0x7f, 0x5e, 0x2c, 0x09, 0xd2, 0xe7, 0x91, 0x0f, 0xea, 0xd6, 0x8c, 0x4e,
+  0x3b, 0xaa, 0x13, 0xe9, 0x8d, 0x22, 0x62, 0xa0, 0xf6, 0xe2, 0x4b, 0x7c,
+  0x40, 0x50, 0x81, 0x43, 0x0a, 0xbf, 0xf9, 0x17, 0x6c, 0x44, 0xed, 0xb4,
+  0x41, 0x3c, 0x61, 0x75, 0xcc, 0x3e, 0x9a, 0xc9, 0x66, 0x7e, 0xf7, 0xc4,
+  0xde, 0x0b, 0xee, 0x36, 0x1b, 0xfa, 0x85, 0xbc, 0x23, 0xd0, 0x91, 0x96,
+  0xfc, 0xb6, 0xc5, 0x24, 0x20, 0xe2, 0xca, 0x46, 0xce, 0x22, 0xa7, 0x13,
+  0x4b, 0xb4, 0xf1, 0xbf, 0xc1, 0x99, 0xae, 0xd3, 0x7a, 0x36, 0xc8, 0xbb,
+  0x62, 0xfc, 0x18, 0x80, 0x34, 0x0b, 0x26, 0xb1, 0xbb, 0xd0, 0x34, 0x31,
+  0x3a, 0x1c, 0x9d, 0x76, 0x88, 0x8c, 0xd6, 0xb2, 0x29, 0xee, 0xb5, 0x35,
+  0x9e, 0x47, 0x12, 0xa6, 0x69, 0x04, 0xa1, 0x95, 0x24, 0xbc, 0x8e, 0x2b,
+  0x8d, 0x29, 0xf8, 0x56, 0x55, 0x84, 0xa9, 0x0f, 0xf8, 0xeb, 0x8e, 0x59,
+  0x2e, 0xec, 0x0c, 0x33, 0xf2, 0x10, 0xca, 0x83, 0x6b, 0xf7, 0xc4, 0x68,
+  0x5d, 0xf0, 0xc4, 0x8e, 0x60, 0x48, 0x1e, 0x0a, 0xc4, 0x32, 0x07, 0x9b,
+  0x8e, 0x7c, 0x44, 0x97, 0x00, 0xd5, 0x9f, 0x1a, 0xc4, 0xe8, 0x67, 0x6c,
+  0x18, 0x43, 0x54, 0xc9, 0x1a, 0x4f, 0x13, 0x9e, 0xa4, 0x91, 0x1b, 0xcb,
+  0x8a, 0x2a, 0x6a, 0xc3, 0xc1, 0x32, 0x88, 0xcf, 0x34, 0x64, 0x3f, 0xe5,
+  0x48, 0xdd, 0x15, 0x57, 0x0f, 0xd2, 0x1e, 0x78, 0x6d, 0x76, 0x05, 0x24,
+  0x7e, 0xc8, 0xe0, 0xe3, 0xbf, 0x2f, 0x73, 0x52, 0x26, 0x28, 0x79, 0x67,
+  0x98, 0xbc, 0x62, 0x68, 0x91, 0x54, 0xe1, 0xe1, 0x9a, 0x5c, 0xa8, 0xdb,
+  0x45, 0x8f, 0xda, 0x0e, 0x04, 0x41, 0x14, 0xd3, 0x21, 0x3a, 0x87, 0x6f,
+  0xd0, 0xe9, 0x23, 0xea, 0xf4, 0xdc, 0x1c, 0x74, 0x58, 0x80, 0x5c, 0x79,
+  0xbd, 0x01, 0x98, 0x44, 0x62, 0xce, 0x0a, 0x06, 0x17, 0xea, 0xd9, 0xfa,
+  0x43, 0x68, 0x6f, 0xf6, 0x5b, 0x85, 0x17, 0x60, 0x7f, 0x89, 0x11, 0xd0,
+  0x50, 0xdd, 0x8e, 0x22, 0x9d, 0xed, 0xd4, 0xcd, 0x94, 0xe4, 0xdf, 0xb2,
+  0x98, 0x51, 0x27, 0xa9, 0x29, 0x2d, 0x32, 0xd3, 0x9d, 0x9b, 0x26, 0x46,
+  0x72, 0x12, 0x2c, 0x10, 0x7c, 0x9e, 0xd6, 0xe4, 0x90, 0xc4, 0x17, 0xdf,
+  0x4a, 0xa2, 0x9f, 0x88, 0xfc, 0x08, 0xc9, 0x6c, 0xfc, 0xa9, 0x22, 0x3b,
+  0x94, 0x47, 0x8c, 0x89, 0x6c, 0xad, 0xdb, 0xba, 0x9c, 0xfb, 0x5b, 0xea,
+  0x90, 0xd9, 0x68, 0xe3, 0xb2, 0x56, 0x26, 0x44, 0x33, 0x48, 0xf3, 0x7a,
+  0xeb, 0x3c, 0x81, 0x3a, 0xea, 0x17, 0xb2, 0x73, 0x70, 0xbd, 0x3f, 0x8f,
+  0x9b, 0x63, 0x5d, 0x99, 0xbf, 0xb0, 0x48, 0xe2, 0x2f, 0x26, 0xe6, 0x88,
+  0x31, 0x0f, 0x91, 0x0d, 0x69, 0xc1, 0x73, 0x82, 0x87, 0x69, 0x31, 0x54,
+  0xc0, 0x6e, 0xa3, 0xf8, 0x64, 0xa4, 0x28, 0x8e, 0xd9, 0x4e, 0x4b, 0x49,
+  0xb6, 0x9f, 0xcc, 0x8c, 0xac, 0x8f, 0xd8, 0x9a, 0x5a, 0x13, 0x89, 0xe8,
+  0xab, 0xfa, 0x5d, 0x71, 0x5a, 0x2f, 0x49, 0xf7, 0x98, 0x2d, 0xe9, 0xdb,
+  0xcc, 0xfc, 0x64, 0x99, 0x87, 0x34, 0x47, 0x38, 0xca, 0xd6, 0x65, 0xa9,
+  0x83, 0xe8, 0x8c, 0x7a, 0xc4, 0x65, 0x4b, 0x2d, 0x9f, 0xa6, 0x9c, 0x5e,
+  0x5d, 0x6e, 0x97, 0xe1, 0x8a, 0xde, 0x91, 0x41, 0xd8, 0xf7, 0x4b, 0x82,
+  0xfa, 0x41, 0x6b, 0xca, 0x88, 0xd0, 0xee, 0xb4, 0xea, 0x7d, 0xa6, 0x51,
+  0x36, 0x26, 0x78, 0x3e, 0xf8, 0x92, 0xf1, 0xfb, 0xa6, 0xb7, 0x87, 0xa6,
+  0xcd, 0x02, 0xa4, 0xdc, 0xaa, 0xb2, 0x79, 0xd2, 0xf5, 0xb3, 0x06, 0xb5,
+  0x40, 0x59, 0x71, 0xb0, 0x05, 0x3d, 0xe5, 0xec, 0xb5, 0xba, 0xc4, 0xd4,
+  0x2a, 0x45, 0x0c, 0xec, 0xfa, 0x98, 0x2a, 0xa0, 0xad, 0xba, 0x9f, 0xff,
+  0xca, 0xfb, 0xf0, 0x59, 0xbb, 0x3e, 0x86, 0x50, 0xb1, 0xfd, 0xaa, 0x03,
+  0x95, 0x3e, 0xee, 0x44, 0xad, 0x00, 0xa6, 0xff, 0xdf, 0x79, 0xa2, 0xd2,
+  0xc7, 0x1d, 0xa9, 0xb4, 0x75, 0xa6, 0x56, 0xd4, 0x6e, 0x5d, 0xd9, 0xe3,
+  0xdf, 0xf0, 0x94, 0xd9, 0xe8, 0xfd, 0x63, 0xcf, 0x98, 0xee, 0x89, 0xff,
+  0xbb, 0x4f, 0xd9, 0xa7, 0x1d, 0x2d, 0x10, 0xbc, 0x86, 0x8f, 0x2c, 0x43,
+  0x43, 0x68, 0x62, 0xd2, 0xb5, 0x76, 0x2c, 0x05, 0x59, 0x9c, 0xc5, 0x98,
+  0xb9, 0x6c, 0x62, 0x01, 0x75, 0xc0, 0xda, 0x30, 0x21, 0xcf, 0xec, 0x72,
+  0x68, 0x92, 0xee, 0xda, 0x96, 0x03, 0x1b, 0x5d, 0x39, 0x40, 0xfd, 0xaa,
+  0xd8, 0x43, 0x11, 0x09, 0x6e, 0x5c, 0xd7, 0xe6, 0x6e, 0x5f, 0xe4, 0xac,
+  0x22, 0x18, 0xed, 0x85, 0x48, 0xf4, 0xbf, 0x1e, 0x8d, 0x06, 0x87, 0xe7,
+  0x27, 0xdd, 0x93, 0xd7, 0xfe, 0x9c, 0x96, 0xe2, 0x7d, 0xb6, 0xb2, 0x2a,
+  0xcd, 0x6a, 0xb4, 0x42, 0xfb, 0xdb, 0x46, 0xd3, 0xed, 0x4e, 0xec, 0x61,
+  0x9d, 0xb4, 0xf0, 0x78, 0xd2, 0x23, 0x9f, 0x51, 0x58, 0xa8, 0x30, 0x39,
+  0xa7, 0x8e, 0x13, 0xbc, 0x49, 0x6e, 0xe1, 0x81, 0x00, 0xbc, 0x08, 0xca,
+  0x0a, 0xe2, 0x9a, 0xd8, 0xfb, 0xec, 0xf9, 0x9e, 0x39, 0x17, 0xf7, 0xcc,
+  0xd7, 0x26, 0x2f, 0x3f, 0x1d, 0x3e, 0xd9, 0xa1, 0x7a, 0xe8, 0x79, 0xa3,
+  0x91, 0x05, 0x98, 0x75, 0xd2, 0xbc, 0x91, 0x77, 0x91, 0xe0, 0x3d, 0x5f,
+  0x63, 0x6f, 0x8f, 0x8f, 0x12, 0xc6, 0x78, 0x81, 0xc0, 0x2b, 0x41, 0xc6,
+  0x09, 0xa5, 0xaf, 0x48, 0x08, 0x14, 0x21, 0x66, 0x12, 0xa6, 0xb2, 0x88,
+  0xbc, 0x5d, 0x03, 0x73, 0x2c, 0x98, 0x0e, 0x35, 0x26, 0x90, 0xe1, 0x5d,
+  0xd8, 0x8e, 0x90, 0xc0, 0x63, 0xbb, 0x42, 0xe6, 0x85, 0xfa, 0x18, 0xa6,
+  0x6b, 0x78, 0x53, 0xf2, 0x48, 0x0a, 0x66, 0x2a, 0xc6, 0xb8, 0x7a, 0x7d,
+  0xd4, 0x80, 0x59, 0x61, 0x02, 0x39, 0xf7, 0x64, 0x60, 0xe9, 0x88, 0x48,
+  0x54, 0x84, 0x1a, 0x79, 0x59, 0x26, 0x73, 0x6b, 0x94, 0x5c, 0xfd, 0x7d,
+  0x5a, 0x0c, 0x7f, 0xa9, 0x45, 0x15, 0x51, 0x89, 0x3d, 0xc3, 0x49, 0xbb,
+  0x2e, 0xa2, 0x4c, 0xac, 0xa5, 0x55, 0x03, 0x12, 0x23, 0xa9, 0xeb, 0x0b,
+  0xe0, 0x2d, 0xb0, 0x94, 0x72, 0xd9, 0xd3, 0x1d, 0xaf, 0x29, 0xdb, 0x7e,
+  0xe4, 0x67, 0xda, 0x7a, 0x04, 0xc5, 0x4f, 0x1f, 0xe3, 0xb6, 0xaa, 0x2c,
+  0x9d, 0x49, 0xaf, 0xbc, 0xef, 0x84, 0xbf, 0x44, 0xc4, 0x88, 0xc4, 0x6d,
+  0x1d, 0xa2, 0x97, 0x84, 0xa1, 0xc6, 0xeb, 0x82, 0x85, 0x32, 0xcc, 0xd3,
+  0x66, 0xa2, 0xf4, 0x6e, 0xe6, 0x42, 0xc9, 0x17, 0xe9, 0x2c, 0x79, 0x04,
+  0x08, 0x77, 0xf5, 0xe2, 0x3f, 0x86, 0xb2, 0x5d, 0x4f, 0xe7, 0x1a, 0x51,
+  0xa7, 0x1c, 0x2a, 0xb1, 0x32, 0xe1, 0x6d, 0x39, 0xb7, 0xa2, 0x31, 0x4a,
+  0x33, 0x16, 0x79, 0xe6, 0x89, 0xb3, 0x6e, 0x8c, 0xd9, 0xd8, 0x92, 0xd6,
+  0xc7, 0x34, 0x29, 0xe7, 0x0b, 0xc4, 0x0b, 0x70, 0xd1, 0x69, 0xb3, 0x92,
+  0x20, 0xb6, 0x2d, 0xf5, 0xd0, 0xd7, 0x8a, 0x77, 0xae, 0xeb, 0x3a, 0x79,
+  0x84, 0xec, 0xfd, 0x2d, 0x84, 0x21, 0x29, 0x71, 0xec, 0x69, 0xf8, 0xe5,
+  0xea, 0x9c, 0x4c, 0x61, 0xb2, 0x85, 0x98, 0xa9, 0x24, 0xd4, 0x29, 0xa1,
+  0x9c, 0x06, 0xae, 0x23, 0x7e, 0x2a, 0x8e, 0x3f, 0xd3, 0x57, 0x69, 0x42,
+  0x1e, 0x51, 0x43, 0xbd, 0xa3, 0xfa, 0x85, 0x74, 0x33, 0xff, 0x37, 0x28,
+  0x82, 0xcf, 0x12, 0xbb, 0x56, 0x8f, 0x51, 0x08, 0x99, 0x13, 0x99, 0x0b,
+  0x08, 0x06, 0x74, 0x3f, 0xce, 0xe8, 0xfa, 0x7f, 0xfa, 0xe0, 0xff, 0x2f,
+  0xe9, 0x83, 0xff, 0xcc, 0x29, 0xa5, 0x6a, 0xb3, 0xd0, 0x21, 0xfc, 0x93,
+  0xe9, 0x1f, 0xc6, 0x18, 0x32, 0x77, 0x76, 0x3f, 0x74, 0x34, 0x5f, 0xbf,
+  0xe0, 0x88, 0x86, 0x5b, 0xe1, 0xff, 0x8e, 0x23, 0xfa, 0xa8, 0x93, 0xf9,
+  0xff, 0xbc, 0x1f, 0xff, 0xdd, 0xce, 0xe1, 0x1a, 0xac, 0xc7, 0x96, 0xd9,
+  0x66, 0x77, 0x54, 0x75, 0x80, 0xeb, 0x7e, 0xc0, 0xd6, 0xde, 0x76, 0xaa,
+  0x0f, 0xe5, 0xad, 0xf0, 0xd4, 0x9d, 0x9c, 0x7f, 0xf7, 0x1c, 0x9c, 0x15,
+  0xa3, 0x6e, 0xd4, 0xb2, 0x4a, 0x4e, 0x5f, 0x1d, 0x9e, 0xff, 0x82, 0xd3,
+  0xfe, 0x57, 0x38, 0x5a, 0x17, 0x59, 0x36, 0x1d, 0x70, 0x84, 0xe4, 0x05,
+  0xfe, 0x11, 0x8d, 0x29, 0x6a, 0x2a, 0x3a, 0xb6, 0x2d, 0x05, 0x4e, 0xc2,
+  0x60, 0x2d, 0x5e, 0x36, 0x6a, 0x4a, 0x21, 0x04, 0x11, 0x84, 0x13, 0xad,
+  0x43, 0x2f, 0x4b, 0x59, 0x4c, 0xb7, 0x45, 0x05, 0xe4, 0x6f, 0x63, 0xab,
+  0x48, 0x90, 0x9d, 0x8e, 0xf7, 0x35, 0xd1, 0x48, 0x59, 0x2e, 0x3e, 0xef,
+  0x19, 0xc6, 0xef, 0x44, 0x11, 0x1f, 0xf7, 0x6e, 0x28, 0x1c, 0xdc, 0x61,
+  0xb2, 0xa7, 0x27, 0xbb, 0x5c, 0x24, 0x1b, 0x59, 0xb9, 0xbf, 0x63, 0x6a,
+  0x7a, 0xf7, 0xf3, 0xab, 0x30, 0x03, 0x6b, 0xa7, 0xd2, 0x5f, 0x89, 0xd6,
+  0x0c, 0x52, 0x2c, 0x70, 0xba, 0xac, 0xc2, 0xa2, 0x40, 0xa9, 0x3f, 0x3b,
+  0x1c, 0x26, 0xe7, 0xfe, 0xda, 0x4f, 0xb4, 0xe7, 0xd2, 0x7c, 0xbe, 0x35,
+  0x9d, 0x11, 0x90, 0x7a, 0xbf, 0x05, 0xc9, 0xf0, 0xbb, 0x64, 0x23, 0x82,
+  0x7b, 0x89, 0x3a, 0xf7, 0x39, 0xfd, 0x5a, 0xb2, 0xbe, 0xff, 0x1a, 0x62,
+  0xb0, 0xbc, 0xd7, 0x1f, 0x42, 0x3a, 0x95, 0x45, 0x53, 0x31, 0xad, 0xb1,
+  0x04, 0x4b, 0x6b, 0xa5, 0xdb, 0x5e, 0x7a, 0xc5, 0xd9, 0x52, 0xae, 0x93,
+  0x4c, 0xb3, 0x16, 0x72, 0x0b, 0xf2, 0xf9, 0xce, 0x9a, 0xc9, 0xd0, 0xae,
+  0x2c, 0xf8, 0xbe, 0xa8, 0x7e, 0xb2, 0x51, 0x71, 0xb5, 0xc4, 0x9c, 0x19,
+  0x61, 0xa5, 0x34, 0x71, 0x83, 0xc1, 0x0a, 0x6f, 0x85, 0x06, 0xfb, 0x57,
+  0x20, 0x91, 0x7f, 0x43, 0xe4, 0xe5, 0xfa, 0x52, 0x40, 0x61, 0xb6, 0xb5,
+  0x3a, 0x64, 0xac, 0x54, 0x48, 0x51, 0xc8, 0x98, 0xf6, 0x02, 0xd5, 0x3c,
+  0xcb, 0x9b, 0x7b, 0x4a, 0xd8, 0xbf, 0x93, 0xb4, 0x91, 0xae, 0xbc, 0x1f,
+  0x9d, 0x3e, 0xc1, 0xb4, 0x5e, 0x9e, 0x8e, 0x7c, 0xe2, 0xeb, 0x3a, 0xe1,
+  0xaa, 0xdd, 0x46, 0xf8, 0x7c, 0x75, 0x7c, 0x38, 0xba, 0x1c, 0x06, 0x43,
+  0x34, 0x63, 0x0c, 0x51, 0x21, 0xbc, 0x61, 0x58, 0x08, 0x8f, 0x4e, 0xcd,
+  0x58, 0xef, 0x89, 0x6d, 0x4e, 0x12, 0x90, 0xa8, 0x73, 0xdc, 0x37, 0x6d,
+  0x9d, 0xec, 0xdc, 0x94, 0x01, 0xb0, 0x4d, 0x56, 0x85, 0x24, 0x51, 0x66,
+  0xee, 0xc6, 0xf9, 0x8c, 0x46, 0x60, 0xfa, 0x65, 0xac, 0xa1, 0xb9, 0xe0,
+  0x8a, 0x91, 0xce, 0x5a, 0xce, 0x08, 0x4f, 0x46, 0x9f, 0x69, 0xfb, 0x21,
+  0x88, 0xcd, 0x52, 0x72, 0x7c, 0x57, 0x67, 0xec, 0x19, 0x2d, 0xa3, 0xac,
+  0x33, 0x61, 0x0c, 0xa3, 0x36, 0x74, 0xae, 0xfa, 0x98, 0x0d, 0x0b, 0xe8,
+  0x67, 0x32, 0x10, 0xe2, 0x3b, 0x08, 0xd3, 0xa1, 0xd2, 0xfa, 0x83, 0xe2,
+  0xc2, 0x27, 0x0d, 0x72, 0x2b, 0xd3, 0xb5, 0x55, 0x76, 0xf6, 0xbb, 0x96,
+  0x90, 0x59, 0x68, 0x24, 0x8f, 0x52, 0x12, 0x41, 0xd7, 0xb6, 0xfb, 0x3e,
+  0x27, 0xfa, 0xdd, 0xed, 0x35, 0xeb, 0x6d, 0x23, 0xe4, 0x54, 0xe4, 0x80,
+  0x33, 0x3c, 0x80, 0x78, 0xb9, 0x2d, 0xe3, 0x45, 0x75, 0x92, 0xc9, 0x4d,
+  0x66, 0x2e, 0x91, 0xa1, 0x97, 0x02, 0xfd, 0xe8, 0x09, 0xd9, 0x08, 0xb8,
+  0xb2, 0x22, 0xd3, 0xf3, 0x8b, 0x27, 0xe4, 0xe9, 0xd3, 0x70, 0x42, 0xaa,
+  0xec, 0xef, 0xd3, 0x18, 0xbd, 0x30, 0x60, 0xda, 0x40, 0x88, 0x33, 0xb2,
+  0xfa, 0x82, 0x39, 0x92, 0xa9, 0xab, 0x3b, 0x54, 0x8c, 0x84, 0x8b, 0xb6,
+  0x67, 0x1e, 0xf3, 0x14, 0x59, 0xd8, 0x14, 0x82, 0x0c, 0xab, 0x2b, 0x36,
+  0x92, 0xba, 0xec, 0x9e, 0x55, 0xc0, 0x53, 0x37, 0x6f, 0x5e, 0x50, 0x9e,
+  0xf2, 0x91, 0xb5, 0x1a, 0x24, 0x41, 0x3b, 0x51, 0xd2, 0x82, 0x32, 0xb1,
+  0xec, 0xe1, 0x19, 0x0c, 0xae, 0x9a, 0x85, 0x1d, 0xd8, 0xda, 0xdd, 0xb1,
+  0x1b, 0x4c, 0x86, 0x0c, 0x9d, 0xc7, 0xce, 0x83, 0x97, 0xd1, 0x27, 0x97,
+  0x95, 0xad, 0xee, 0xb1, 0x6e, 0x0a, 0x02, 0x48, 0x19, 0xd5, 0xcb, 0x60,
+  0xb4, 0x28, 0x48, 0x7e, 0xa4, 0x2a, 0xe2, 0x63, 0x27, 0x22, 0x14, 0x1e,
+  0x98, 0x96, 0x56, 0x6c, 0xd4, 0x0e, 0x58, 0x24, 0xb8, 0xc6, 0x47, 0x65,
+  0x0a, 0x38, 0x03, 0x09, 0xd8, 0xdf, 0x41, 0x48, 0xc3, 0x6b, 0xac, 0xf9,
+  0xdb, 0x6c, 0x86, 0x4c, 0xc8, 0xac, 0x98, 0x54, 0xf7, 0x0b, 0x9f, 0x0f,
+  0x7b, 0xfa, 0xcf, 0xcc, 0xbf, 0x82, 0xe7, 0x11, 0x3c, 0x36, 0x8a, 0x8f,
+  0x11, 0x76, 0xdb, 0xa1, 0xfe, 0x45, 0xe9, 0x6c, 0x2a, 0xdf, 0xd8, 0x33,
+  0x05, 0xc4, 0x2d, 0xc7, 0x88, 0xad, 0xfe, 0x4b, 0xd6, 0x8c, 0x4a, 0x6f,
+  0xe6, 0x9c, 0xe3, 0xbc, 0xe4, 0x6e, 0xdc, 0x63, 0x09, 0x0a, 0x21, 0x8b,
+  0x20, 0x7e, 0xf4, 0xda, 0xef, 0xf7, 0x79, 0xc2, 0x6e, 0xf7, 0x83, 0xac,
+  0x02, 0x12, 0x09, 0xaf, 0xc9, 0x4b, 0xd3, 0x76, 0xc4, 0xd3, 0x81, 0xd5,
+  0xd2, 0x42, 0xfb, 0xec, 0x8a, 0xb2, 0xbe, 0x50, 0x9b, 0xb7, 0xb6, 0xaa,
+  0x72, 0x3b, 0xde, 0x76, 0xc9, 0x6c, 0x23, 0x23, 0x5c, 0x19, 0xbd, 0xa5,
+  0xbe, 0xa5, 0xf1, 0x32, 0x97, 0x5c, 0x7d, 0xba, 0x01, 0xcd, 0xd3, 0xb7,
+  0xfb, 0xab, 0xd8, 0x9d, 0x87, 0xf2, 0x6b, 0xe4, 0x7b, 0x4e, 0xa9, 0x8e,
+  0x80, 0xa3, 0x9e, 0x4b, 0x6c, 0x15, 0x4e, 0x80, 0x17, 0xc9, 0x41, 0xfd,
+  0x7c, 0xef, 0x93, 0xe7, 0xdb, 0xeb, 0xca, 0x0e, 0x52, 0xdd, 0x0d, 0xca,
+  0x62, 0xe3, 0x4d, 0x44, 0xff, 0xda, 0x1f, 0xfa, 0x13, 0xe4, 0x15, 0x07,
+  0x90, 0x6c, 0xc4, 0xf0, 0x8e, 0x33, 0x17, 0x0e, 0x6d, 0x0a, 0x4c, 0x84,
+  0xe5, 0x50, 0xa7, 0xed, 0xc2, 0xe3, 0x6a, 0x4a, 0x7b, 0xce, 0xb1, 0x99,
+  0xbb, 0x66, 0x61, 0x77, 0x98, 0x6c, 0x26, 0x0e, 0x9e, 0x68, 0x1f, 0xf8,
+  0xfe, 0xf4, 0x2b, 0xb1, 0x71, 0x67, 0xf1, 0xf7, 0x61, 0xfb, 0x5f, 0x7e,
+  0x40, 0xd3, 0x35, 0xf0, 0x6b, 0x56, 0xf9, 0xc9, 0xbf, 0x60, 0x95, 0x9f,
+  0xac, 0x5f, 0xe5, 0x27, 0x8f, 0x5d, 0xe5, 0x4f, 0x9e, 0x3d, 0xff, 0xf4,
+  0x57, 0xac, 0xb2, 0x37, 0xc3, 0xff, 0xc7, 0x56, 0xd9, 0xdb, 0x69, 0xbf,
+  0x6e, 0x95, 0x05, 0x18, 0x12, 0x08, 0x62, 0x29, 0x5a, 0x41, 0x10, 0x3e,
+  0xca, 0x3a, 0x67, 0x08, 0x3f, 0x3f, 0xab, 0x16, 0x68, 0x9b, 0xda, 0xd7,
+  0x16, 0xac, 0x22, 0x4d, 0x2c, 0x62, 0x66, 0xbb, 0x2c, 0x7c, 0xe8, 0xb8,
+  0x8b, 0x19, 0xd5, 0x3d, 0xda, 0x1c, 0x6c, 0xaa, 0x83, 0x44, 0x73, 0x8c,
+  0x94, 0x42, 0x86, 0x3f, 0x67, 0x96, 0xfa, 0x5f, 0x48, 0x41, 0x14, 0xe2,
+  0x66, 0x3c, 0xe4, 0x53, 0x6b, 0xd2, 0x56, 0xd4, 0xc1, 0x88, 0x16, 0x55,
+  0xa1, 0xd2, 0x2b, 0xed, 0xda, 0x2b, 0x8c, 0x0f, 0x65, 0x56, 0x26, 0x68,
+  0xc2, 0x9d, 0xfa, 0xdf, 0x5a, 0x93, 0x24, 0x48, 0x62, 0xa3, 0xbb, 0x4e,
+  0xc0, 0x4f, 0xed, 0x12, 0x1f, 0x0e, 0x68, 0xe7, 0xaa, 0x99, 0x77, 0x2c,
+  0x96, 0xc0, 0x7a, 0x22, 0xc0, 0x69, 0x63, 0xab, 0x35, 0x78, 0x10, 0xb2,
+  0x57, 0x34, 0xe8, 0xe9, 0x72, 0xbe, 0x50, 0x42, 0x2d, 0xca, 0x6d, 0xc8,
+  0xb9, 0x4e, 0x31, 0x27, 0xd4, 0x02, 0x77, 0x19, 0xf1, 0x2f, 0x59, 0xf7,
+  0x8b, 0xe0, 0xbe, 0xd8, 0x95, 0xa3, 0x35, 0x44, 0x5c, 0x32, 0x28, 0x8f,
+  0x81, 0xb6, 0x4a, 0x23, 0xd9, 0x04, 0x45, 0x17, 0x16, 0xc9, 0x59, 0x88,
+  0x94, 0x81, 0x34, 0xcd, 0xc6, 0xcb, 0x6b, 0xcd, 0x49, 0xb5, 0x35, 0x9b,
+  0xda, 0x8b, 0x85, 0xec, 0x0b, 0xe2, 0xa9, 0xc8, 0xfa, 0x0c, 0x84, 0xbd,
+  0x0f, 0xd3, 0xf3, 0x1b, 0x2a, 0x58, 0x36, 0x59, 0x87, 0x9b, 0x0a, 0x06,
+  0x8e, 0x3d, 0xd0, 0x1a, 0x39, 0x7e, 0xd2, 0xaa, 0xa5, 0x13, 0x29, 0x2e,
+  0xe3, 0x6f, 0x95, 0x66, 0xb2, 0x18, 0x5c, 0xa5, 0x44, 0x70, 0x17, 0x24,
+  0x25, 0x0a, 0x56, 0x52, 0x9c, 0x78, 0x97, 0x47, 0xe7, 0xc9, 0xeb, 0x54,
+  0x4a, 0x5b, 0x24, 0x5b, 0x46, 0x30, 0x7d, 0xf2, 0x74, 0xef, 0xc9, 0xf6,
+  0x5a, 0x05, 0xb5, 0x4d, 0xd8, 0x82, 0x6f, 0x15, 0x65, 0x0c, 0xb3, 0x7a,
+  0xb9, 0x34, 0xf6, 0xa4, 0xa6, 0x73, 0x99, 0x2f, 0xbd, 0x7f, 0x7b, 0xf6,
+  0xea, 0xf8, 0xf4, 0xf0, 0xaf, 0x36, 0xeb, 0x98, 0x26, 0x41, 0xd3, 0xd7,
+  0xde, 0x1b, 0xbb, 0xee, 0xfe, 0xbd, 0x31, 0x95, 0xcd, 0x2f, 0xb7, 0x9e,
+  0x6c, 0x53, 0xd6, 0x4e, 0x50, 0xe7, 0xec, 0x3a, 0x6b, 0xe7, 0x6a, 0x33,
+  0x84, 0x78, 0x0d, 0xe5, 0x88, 0xf5, 0xdc, 0xed, 0x0e, 0xf7, 0x85, 0xbd,
+  0x5e, 0xe8, 0xb7, 0xdd, 0x51, 0xf6, 0x98, 0xf4, 0x53, 0x21, 0x26, 0xe2,
+  0x04, 0xaf, 0x30, 0x3f, 0x83, 0x12, 0xc3, 0xf3, 0x49, 0x4e, 0x6a, 0x7c,
+  0x6d, 0x76, 0x2d, 0x65, 0xc2, 0x52, 0x7c, 0xfa, 0xaa, 0x4d, 0x6d, 0x86,
+  0x0c, 0x30, 0xfa, 0xc5, 0xfa, 0x78, 0x6b, 0x5b, 0x24, 0x36, 0x90, 0xa1,
+  0xd9, 0xac, 0xc8, 0x9a, 0x81, 0x74, 0xec, 0x85, 0xf9, 0xf3, 0xe5, 0x6d,
+  0x3a, 0x0b, 0x72, 0x0b, 0xa9, 0x4c, 0x98, 0xee, 0x4c, 0x8b, 0x2b, 0xa4,
+  0x37, 0x3d, 0xe6, 0xfe, 0x91, 0xa5, 0xb0, 0xd7, 0x27, 0xcd, 0x51, 0x09,
+  0x98, 0xea, 0x2f, 0x2f, 0xff, 0x7a, 0x7e, 0xfc, 0xf2, 0x05, 0xa1, 0x12,
+  0xbf, 0x20, 0xdc, 0x79, 0xdd, 0x02, 0x29, 0x26, 0x54, 0xc5, 0x36, 0x18,
+  0xc3, 0x0f, 0xaf, 0x4e, 0x46, 0xe7, 0xa7, 0x67, 0x47, 0x2f, 0x5f, 0xfc,
+  0x40, 0xe6, 0x96, 0x91, 0xa9, 0xf7, 0xde, 0xbb, 0xf6, 0x67, 0x96, 0x8d,
+  0x3b, 0x4c, 0x48, 0x3f, 0xfe, 0xfe, 0xfd, 0xf1, 0xdb, 0xef, 0x5e, 0xbe,
+  0xb8, 0x4d, 0xab, 0x3e, 0x8d, 0x8f, 0xdf, 0x5e, 0x51, 0x83, 0xaf, 0xb5,
+  0xd5, 0x48, 0x6f, 0x1d, 0xcf, 0x3e, 0xd4, 0xf9, 0x3f, 0xb2, 0xc4, 0xbc,
+  0x3e, 0x5b, 0x86, 0x64, 0xb8, 0x97, 0x52, 0x72, 0xc5, 0x5c, 0x69, 0x64,
+  0x27, 0x7c, 0x75, 0xfa, 0x2d, 0x11, 0x2e, 0x5a, 0x07, 0xe2, 0x9c, 0x6b,
+  0x7c, 0x24, 0x5f, 0x3c, 0xdb, 0xdb, 0xdf, 0x76, 0x05, 0xec, 0x40, 0xd8,
+  0x6a, 0x7a, 0xfc, 0x21, 0xc8, 0x99, 0xf8, 0x87, 0x64, 0x7f, 0xb8, 0x2a,
+  0x0b, 0x00, 0xf6, 0x7b, 0xf4, 0x08, 0xea, 0x8b, 0x41, 0xa6, 0x35, 0xa0,
+  0xa1, 0x54, 0xff, 0xaf, 0x02, 0x71, 0x4d, 0xe0, 0x8a, 0xba, 0x7c, 0xed,
+  0x71, 0x24, 0x7c, 0xe5, 0xb6, 0x9e, 0xe9, 0x8e, 0xb8, 0xb3, 0xd6, 0x5e,
+  0x1b, 0xbf, 0x63, 0x90, 0xa3, 0x6b, 0x6b, 0x61, 0xb2, 0x8d, 0x29, 0x2e,
+  0xfb, 0x27, 0x3e, 0xcf, 0x1e, 0xfc, 0x05, 0xd9, 0x1f, 0x25, 0xb3, 0x7b,
+  0x61, 0x94, 0xba, 0xf1, 0x34, 0x2f, 0xf5, 0x01, 0xe7, 0x56, 0x3e, 0xa7,
+  0x9c, 0xc1, 0xac, 0x4e, 0xd4, 0xf1, 0xe1, 0xb9, 0x35, 0x66, 0xd9, 0x75,
+  0x3a, 0xb9, 0xb7, 0x3c, 0xa5, 0x58, 0x90, 0x69, 0x19, 0xc9, 0x9d, 0x4f,
+  0x27, 0x64, 0xe5, 0xcc, 0xb2, 0xe9, 0x35, 0xc4, 0x33, 0xe7, 0xe1, 0x9b,
+  0xe3, 0x6a, 0xbd, 0x21, 0xdc, 0x35, 0x4b, 0x36, 0xa0, 0xd7, 0xe5, 0xea,
+  0xfc, 0x16, 0x5b, 0x8e, 0xac, 0xbd, 0xfb, 0x68, 0xdb, 0xa0, 0xc2, 0xe6,
+  0xda, 0x39, 0x7d, 0xda, 0x76, 0x25, 0xff, 0x03, 0x87, 0x9c, 0x78, 0x5c,
+  0xe0, 0xad, 0x7c, 0x41, 0x7f, 0x5d, 0xcd, 0xe6, 0xcc, 0xf6, 0x3c, 0x57,
+  0x50, 0x65, 0xea, 0x6c, 0x1a, 0xb6, 0x65, 0xe0, 0x92, 0xf2, 0x08, 0x44,
+  0x0a, 0xdc, 0x38, 0x3f, 0x73, 0x9c, 0x25, 0xc9, 0x7a, 0x7b, 0xcd, 0xf6,
+  0xcc, 0xb4, 0xa4, 0xca, 0xaa, 0xf6, 0xbc, 0xcc, 0xac, 0x30, 0x76, 0xc1,
+  0x29, 0x41, 0x14, 0xa5, 0x7f, 0x41, 0x6d, 0x91, 0x48, 0x24, 0x9d, 0xc4,
+  0xcc, 0xd4, 0x17, 0x1a, 0x0e, 0x41, 0x05, 0x8d, 0x52, 0xb8, 0x7b, 0xf0,
+  0x10, 0xb3, 0x10, 0xd4, 0x61, 0x0a, 0x37, 0x03, 0xbf, 0xd5, 0xa0, 0x66,
+  0xe4, 0x02, 0xc5, 0x9a, 0x2c, 0x39, 0xa9, 0xe9, 0x66, 0xad, 0xca, 0x1a,
+  0xa5, 0x40, 0xc1, 0x7e, 0x75, 0xd4, 0x85, 0x11, 0x0e, 0x0c, 0x3f, 0x63,
+  0xe7, 0xda, 0xf2, 0x5e, 0xf2, 0xe0, 0x94, 0x96, 0x00, 0x9d, 0xda, 0x9a,
+  0xd3, 0x60, 0x84, 0xe9, 0x3a, 0x4a, 0x2b, 0x6e, 0x95, 0xcb, 0xd6, 0x3d,
+  0x65, 0x1a, 0xa5, 0xf7, 0xe5, 0x8e, 0xc2, 0xad, 0x24, 0xd9, 0xbd, 0x68,
+  0xd6, 0x9b, 0x91, 0x20, 0x23, 0xa4, 0x61, 0x84, 0x7b, 0xf7, 0x92, 0x22,
+  0x72, 0x5a, 0xc5, 0x95, 0xfb, 0x33, 0xda, 0xaa, 0x7d, 0xb4, 0x35, 0x70,
+  0x55, 0x63, 0xf2, 0xc6, 0x2a, 0x6d, 0x11, 0xc2, 0x06, 0x4b, 0xa0, 0x6b,
+  0x89, 0x7f, 0xd8, 0x2b, 0xa8, 0x3b, 0x44, 0xf6, 0x04, 0x7d, 0x6c, 0x87,
+  0xf3, 0xbe, 0x54, 0x08, 0xe5, 0x91, 0xd4, 0xd3, 0xa0, 0xb1, 0x22, 0xbb,
+  0xf3, 0x1b, 0x73, 0x0a, 0xb9, 0x6d, 0xf0, 0xf7, 0x74, 0x04, 0x1b, 0x63,
+  0x82, 0x92, 0x56, 0x92, 0x17, 0xdf, 0x1d, 0x5f, 0x8c, 0x4e, 0xce, 0xde,
+  0x7e, 0x11, 0xb5, 0x13, 0x13, 0xf9, 0x6d, 0x62, 0xab, 0x0a, 0x69, 0xa6,
+  0x9b, 0x2b, 0xed, 0x42, 0xde, 0x21, 0x75, 0x43, 0x24, 0x87, 0x94, 0xdd,
+  0x43, 0x0f, 0x74, 0xb7, 0x40, 0x2d, 0x2d, 0xc0, 0xfd, 0x99, 0x56, 0xd7,
+  0x98, 0x0b, 0xb3, 0x17, 0x61, 0xd3, 0xa0, 0x6a, 0xa7, 0x1a, 0x3b, 0xf6,
+  0xaf, 0xfb, 0xc1, 0xf8, 0xe3, 0x50, 0x15, 0x2f, 0x52, 0xbc, 0x5c, 0x70,
+  0x26, 0x14, 0xe5, 0xbc, 0x33, 0x2b, 0x86, 0xdf, 0xbb, 0x80, 0xde, 0xdb,
+  0x7c, 0xb8, 0xf5, 0xa2, 0x79, 0xf8, 0x76, 0xcf, 0xcb, 0xde, 0xb0, 0xcf,
+  0xed, 0xc5, 0x9e, 0xdb, 0x0b, 0x9f, 0xdb, 0x8f, 0x3d, 0xb7, 0x1f, 0x3e,
+  0xf7, 0x24, 0xf6, 0x9c, 0x97, 0xa0, 0xe3, 0x99, 0xaf, 0x3a, 0x43, 0xeb,
+  0x2c, 0x42, 0x6f, 0x3d, 0x5b, 0xe5, 0x0c, 0x37, 0x3c, 0x13, 0xce, 0x33,
+  0x61, 0xd5, 0x82, 0x5d, 0x6d, 0xc0, 0xfa, 0x10, 0x9b, 0x8e, 0x1f, 0xd5,
+  0x7c, 0x88, 0x10, 0x3b, 0xa4, 0xd2, 0x18, 0xc1, 0x6b, 0xfe, 0xfb, 0x45,
+  0x98, 0x76, 0x97, 0x60, 0xda, 0xc3, 0xba, 0xe7, 0xa4, 0x06, 0x25, 0x94,
+  0x19, 0xc2, 0x85, 0x76, 0xfb, 0x6a, 0x50, 0x78, 0x74, 0xd3, 0x21, 0x8b,
+  0x81, 0xdd, 0xeb, 0xbd, 0xd1, 0xc5, 0x79, 0xaf, 0x2f, 0xc1, 0x3c, 0xf3,
+  0x81, 0x81, 0xf9, 0x77, 0x02, 0x5d, 0x9b, 0xa8, 0xea, 0x9f, 0x3d, 0x15,
+  0xdc, 0x0d, 0xf7, 0x91, 0x4b, 0xb6, 0x84, 0xde, 0x65, 0xfc, 0xd2, 0x62,
+  0x8f, 0xb8, 0xec, 0x9b, 0xab, 0x2a, 0x61, 0xd4, 0xe0, 0xf6, 0x08, 0x19,
+  0x11, 0xd0, 0x77, 0x04, 0xa6, 0xf1, 0xde, 0x59, 0xf2, 0x24, 0xaa, 0x5b,
+  0x4c, 0xdd, 0x7c, 0x20, 0x07, 0xfe, 0x69, 0x67, 0x46, 0xb5, 0x43, 0x91,
+  0xa9, 0x74, 0x65, 0xde, 0xcb, 0x8a, 0x75, 0x25, 0xa5, 0x89, 0x42, 0x99,
+  0xec, 0xce, 0x14, 0x5b, 0xbe, 0x9a, 0x55, 0x29, 0x1c, 0x9a, 0xb3, 0xee,
+  0x0d, 0x72, 0xa8, 0xfe, 0x6e, 0x51, 0x08, 0xdc, 0xfc, 0x79, 0x6c, 0xcd,
+  0x0f, 0x0f, 0xc8, 0x1f, 0x0f, 0xde, 0x8e, 0x62, 0x1c, 0xb1, 0x3b, 0x14,
+  0x04, 0x96, 0x3c, 0x6a, 0x50, 0x32, 0xa6, 0x5f, 0x39, 0x24, 0xf1, 0xe9,
+  0x74, 0xd7, 0x9d, 0x46, 0x16, 0x5a, 0xd5, 0x8f, 0x1a, 0x68, 0x6b, 0xa4,
+  0x74, 0x36, 0x03, 0x95, 0xee, 0x74, 0xb4, 0x9d, 0xa8, 0x8f, 0xcd, 0x01,
+  0xfc, 0x68, 0x9c, 0x9e, 0x38, 0x82, 0xf8, 0x79, 0x04, 0xb0, 0x4f, 0x5c,
+  0x6c, 0xf4, 0xa6, 0x92, 0x6b, 0xaf, 0xc9, 0xbb, 0x0b, 0x4f, 0x2b, 0xc9,
+  0x8b, 0x68, 0x0f, 0x23, 0x4e, 0xc0, 0x76, 0xf7, 0xf6, 0x84, 0x4b, 0xc0,
+  0xeb, 0x1f, 0xd7, 0x81, 0xfd, 0xed, 0x7b, 0xb8, 0xff, 0xab, 0xe7, 0x70,
+  0xff, 0x5f, 0x34, 0x87, 0x4f, 0x7e, 0xdd, 0x1c, 0x3e, 0xf9, 0xcd, 0xe6,
+  0xd0, 0x55, 0xf7, 0xa4, 0x87, 0xa8, 0xe5, 0xbc, 0xee, 0x88, 0x4e, 0xdc,
+  0xad, 0xe6, 0x9f, 0x63, 0x8a, 0x94, 0x93, 0x57, 0xc2, 0x3c, 0x48, 0xf9,
+  0xac, 0x19, 0xea, 0x1c, 0x76, 0x06, 0xdc, 0xd8, 0x2c, 0x7c, 0xcb, 0x49,
+  0x4c, 0xee, 0x3b, 0x24, 0xcb, 0x83, 0x1f, 0x92, 0x64, 0xe3, 0x57, 0x25,
+  0x69, 0x9c, 0x46, 0x17, 0xe8, 0x27, 0x6f, 0x47, 0x23, 0x8e, 0x5f, 0x8e,
+  0xe0, 0x81, 0xed, 0xda, 0x20, 0x64, 0xbc, 0xe1, 0x02, 0xd9, 0x22, 0x69,
+  0x7d, 0x66, 0x7a, 0x88, 0xab, 0x1c, 0x4a, 0x35, 0xbf, 0x37, 0x4f, 0x27,
+  0xf4, 0xe3, 0xdd, 0xe1, 0xde, 0x13, 0xfb, 0x9b, 0xed, 0x5f, 0x40, 0x9b,
+  0xe1, 0xdc, 0xa3, 0x71, 0x5d, 0x25, 0x4c, 0x21, 0x68, 0x2f, 0xc5, 0xc7,
+  0xd0, 0xab, 0xcd, 0x8a, 0xe1, 0x83, 0x4b, 0xc1, 0xc1, 0x1b, 0xce, 0xf1,
+  0xee, 0x9c, 0xe0, 0x7e, 0x22, 0x3a, 0x4b, 0x4c, 0x5f, 0x79, 0xd0, 0x0b,
+  0xed, 0x79, 0x7c, 0xff, 0x8f, 0x79, 0xa1, 0xe3, 0x3a, 0x45, 0xeb, 0x5f,
+  0xad, 0xd4, 0xe1, 0xa6, 0x1a, 0x68, 0xd5, 0x82, 0x38, 0x29, 0xa2, 0xb3,
+  0xb6, 0x08, 0x37, 0x4c, 0x3a, 0x38, 0xe9, 0x61, 0x62, 0xdc, 0x0f, 0x8e,
+  0xe5, 0x5d, 0xe7, 0xf4, 0xe4, 0x68, 0x6f, 0xb4, 0x36, 0xa5, 0x50, 0xd3,
+  0x69, 0x26, 0xb6, 0xa6, 0xc2, 0xf2, 0x28, 0x6b, 0xde, 0x56, 0xcb, 0x42,
+  0x3f, 0xe3, 0x72, 0x4a, 0x41, 0x07, 0x11, 0x2c, 0xeb, 0x24, 0x63, 0xaa,
+  0x80, 0xfc, 0x21, 0x21, 0xff, 0xbc, 0x3d, 0xde, 0x74, 0x92, 0x0d, 0xd2,
+  0x7a, 0x92, 0xe7, 0x71, 0xf3, 0x86, 0x3d, 0x81, 0x30, 0xa7, 0x96, 0x70,
+  0x6b, 0x50, 0x95, 0x56, 0x72, 0x44, 0x6a, 0x19, 0x44, 0xa2, 0x32, 0xe4,
+  0x24, 0x7a, 0xb6, 0xac, 0xca, 0x65, 0x73, 0x0d, 0x4a, 0x33, 0x74, 0xb6,
+  0x1f, 0x58, 0x4b, 0x5a, 0x2c, 0xde, 0x2c, 0xcf, 0xa4, 0xca, 0x17, 0xe0,
+  0x78, 0xf2, 0xea, 0x2d, 0xf4, 0x6d, 0x49, 0x42, 0xd8, 0x1f, 0xe2, 0x52,
+  0xe6, 0x0a, 0x7d, 0xef, 0x82, 0xdc, 0xe5, 0xde, 0xa0, 0x47, 0xb6, 0x9e,
+  0x25, 0xa9, 0x37, 0xef, 0x12, 0x1f, 0x1f, 0x53, 0xe9, 0xf0, 0xab, 0xa8,
+  0xf8, 0xba, 0xda, 0x65, 0xaf, 0xbe, 0x1d, 0xb3, 0x85, 0xee, 0x95, 0xf2,
+  0x0d, 0x3c, 0xbc, 0xea, 0xb3, 0x25, 0xb5, 0x69, 0x96, 0x11, 0xc9, 0x5f,
+  0x52, 0x4a, 0x66, 0xef, 0x4d, 0xf6, 0x91, 0xb3, 0x4e, 0x42, 0x0d, 0x4c,
+  0x0a, 0xb8, 0xde, 0xa0, 0x30, 0x02, 0x3d, 0x7b, 0x38, 0x3a, 0x3a, 0x39,
+  0x69, 0xe5, 0xa8, 0xd0, 0xe4, 0x31, 0x71, 0x14, 0x52, 0x89, 0x6b, 0xa2,
+  0xd0, 0x22, 0x4f, 0x36, 0xba, 0x1b, 0xa3, 0xe0, 0x9d, 0xe7, 0xd7, 0x37,
+  0x70, 0x47, 0x65, 0x69, 0x9d, 0x6b, 0x91, 0x9c, 0x54, 0x74, 0xa6, 0xc2,
+  0x74, 0x13, 0x96, 0xc7, 0xcd, 0xd2, 0x18, 0x9a, 0xbf, 0x7f, 0xda, 0x7d,
+  0x1c, 0xfa, 0x29, 0xb3, 0xc5, 0xe7, 0xca, 0x77, 0x7f, 0x87, 0x7b, 0x2d,
+  0xc2, 0x77, 0x7b, 0x5e, 0x49, 0x45, 0x14, 0xa6, 0x96, 0x10, 0xc2, 0x5a,
+  0x2a, 0xda, 0x49, 0xd4, 0x3f, 0xdc, 0xb2, 0x19, 0xab, 0x7a, 0xd4, 0x99,
+  0x09, 0x52, 0x04, 0x49, 0xa4, 0x36, 0xaa, 0xf8, 0x16, 0xd7, 0x62, 0xeb,
+  0xf7, 0xba, 0xd7, 0x20, 0x3e, 0xb2, 0xf6, 0x04, 0x10, 0x91, 0x10, 0xce,
+  0x80, 0xf4, 0xa8, 0x75, 0x0a, 0xec, 0x21, 0xa0, 0x19, 0xb0, 0x47, 0xe0,
+  0x5f, 0x74, 0x02, 0x80, 0xab, 0x75, 0xb5, 0x1d, 0x1e, 0x3e, 0x04, 0xb0,
+  0xce, 0x7a, 0x7f, 0xea, 0xc5, 0x19, 0x91, 0x1f, 0x71, 0x92, 0x5a, 0x09,
+  0xdb, 0xff, 0xda, 0x9d, 0x16, 0xc9, 0x20, 0xf7, 0x84, 0x98, 0xbf, 0xa6,
+  0xcb, 0x22, 0xff, 0x08, 0xf8, 0xa7, 0xd1, 0x17, 0x5e, 0x10, 0x17, 0xf0,
+  0x0a, 0x9e, 0xdb, 0x23, 0xd6, 0x5e, 0x5c, 0x05, 0x7b, 0xfa, 0xf0, 0x3b,
+  0xf3, 0x72, 0x32, 0x2d, 0xe7, 0x14, 0x0b, 0xe4, 0x36, 0xfa, 0x3e, 0xd9,
+  0x20, 0xc4, 0x7a, 0x24, 0x96, 0x58, 0x64, 0x0d, 0x81, 0xb5, 0xd6, 0xba,
+  0xfb, 0xda, 0x2e, 0xd4, 0x4b, 0x14, 0x17, 0x59, 0x10, 0xc4, 0x70, 0x4d,
+  0xf1, 0x3a, 0xf6, 0x82, 0x7a, 0x80, 0x3e, 0x9f, 0xab, 0x8e, 0xdc, 0x7b,
+  0x8e, 0x94, 0xb9, 0x5d, 0x2e, 0x1c, 0x5c, 0xc7, 0xb1, 0xb0, 0xa7, 0xa5,
+  0xe5, 0x76, 0xa4, 0xf6, 0x79, 0xd7, 0x59, 0x03, 0xda, 0x74, 0xe7, 0xd3,
+  0x96, 0x92, 0x33, 0x6b, 0x29, 0xa1, 0x99, 0xc6, 0xdb, 0x15, 0xfb, 0x6a,
+  0x91, 0xff, 0x83, 0xbf, 0x25, 0x9f, 0xd1, 0xe6, 0xdf, 0xd1, 0x90, 0xcf,
+  0x2c, 0x44, 0xea, 0x39, 0x46, 0x79, 0x16, 0x75, 0x04, 0x0b, 0x87, 0xdb,
+  0x97, 0xfe, 0x0d, 0xea, 0x05, 0xa9, 0x23, 0xd6, 0x19, 0x84, 0x54, 0x89,
+  0x88, 0x56, 0xf6, 0x66, 0xa7, 0xfc, 0x0d, 0x15, 0x1a, 0xd4, 0x7e, 0x55,
+  0xbc, 0x11, 0xdb, 0xa5, 0x24, 0xd5, 0xcf, 0xef, 0x71, 0xd0, 0x47, 0x8a,
+  0x0d, 0x8b, 0x0e, 0x26, 0xba, 0x13, 0x93, 0x71, 0x11, 0x2a, 0x9f, 0x58,
+  0x79, 0x29, 0xa6, 0x6f, 0xeb, 0x9a, 0xf1, 0xc2, 0x7a, 0x05, 0xb2, 0x83,
+  0x70, 0x11, 0x11, 0x5a, 0xb4, 0x50, 0x96, 0x38, 0x35, 0x65, 0xa1, 0xc0,
+  0xee, 0x2d, 0xa3, 0x88, 0x6b, 0xf1, 0x68, 0x6a, 0x91, 0x18, 0x75, 0x5d,
+  0x15, 0xf1, 0x80, 0x1b, 0x76, 0xd5, 0x69, 0xd2, 0x54, 0x03, 0x37, 0x51,
+  0x24, 0x39, 0xb6, 0x52, 0x25, 0x7c, 0x22, 0xf7, 0xe1, 0xb6, 0xaa, 0x96,
+  0xe6, 0x84, 0xe7, 0x85, 0xbf, 0xdd, 0x03, 0x35, 0x52, 0x78, 0xf5, 0x59,
+  0x2a, 0x99, 0xed, 0x2d, 0x84, 0x8d, 0x99, 0xf5, 0x7b, 0x78, 0xdf, 0x19,
+  0xfa, 0xdf, 0x61, 0x68, 0xed, 0x76, 0x40, 0xf0, 0x7b, 0xdf, 0x2d, 0xfc,
+  0x67, 0xbf, 0x4d, 0xfd, 0xd4, 0x0c, 0x32, 0xe9, 0x19, 0xc2, 0xb5, 0x84,
+  0xc2, 0x42, 0x34, 0x26, 0x3c, 0x89, 0x48, 0x69, 0x64, 0x4b, 0x04, 0xbc,
+  0xda, 0xb8, 0x2f, 0x99, 0x9c, 0x5b, 0x4b, 0x12, 0xb2, 0x48, 0x13, 0x6a,
+  0x2d, 0xdb, 0x2c, 0x79, 0xb9, 0xc3, 0xe6, 0x78, 0x11, 0x23, 0x93, 0xfa,
+  0xd7, 0x4e, 0x8a, 0x01, 0xc9, 0xb4, 0xf0, 0x40, 0xdb, 0x1a, 0x1c, 0x44,
+  0xe9, 0x5d, 0x16, 0xae, 0xf4, 0x77, 0x94, 0xe6, 0x58, 0xa8, 0x2c, 0x93,
+  0x63, 0x7a, 0x23, 0x6c, 0xec, 0x2f, 0x42, 0x0c, 0x9e, 0xfb, 0x65, 0x76,
+  0x50, 0xb1, 0x32, 0xd8, 0x59, 0xb2, 0xf7, 0x84, 0x2d, 0x15, 0xf9, 0x80,
+  0x43, 0x61, 0x90, 0x27, 0xb5, 0x5d, 0x15, 0xcd, 0xa4, 0x77, 0x3d, 0x2b,
+  0xc7, 0x63, 0x33, 0xec, 0x9e, 0xa7, 0x96, 0x9a, 0x2f, 0x07, 0xce, 0x25,
+  0xbf, 0x1f, 0xd6, 0xcd, 0xd9, 0xe7, 0x70, 0xbd, 0x50, 0x8f, 0xd2, 0x95,
+  0xac, 0x89, 0x17, 0xf2, 0x7d, 0x2d, 0x98, 0x1e, 0xb9, 0x69, 0x04, 0x4f,
+  0x27, 0x5b, 0x83, 0x06, 0xe6, 0xe1, 0x23, 0x25, 0x0f, 0x89, 0x7e, 0xaa,
+  0x1d, 0x4c, 0xb8, 0x9c, 0xf7, 0x2a, 0x70, 0x4d, 0x8b, 0xe1, 0xbd, 0xaf,
+  0x25, 0x3e, 0xf2, 0xb0, 0xf6, 0x36, 0xcf, 0x42, 0x7b, 0x40, 0xbd, 0xff,
+  0xa4, 0x3f, 0xf6, 0xfa, 0xf4, 0xdf, 0xfd, 0xff, 0xea, 0x25, 0x64, 0xc5,
+  0x1c, 0xec, 0xec, 0xdc, 0xdd, 0xdd, 0x0d, 0x85, 0xbe, 0x78, 0x68, 0x96,
+  0x6c, 0x23, 0xcc, 0x14, 0x20, 0xe6, 0x96, 0x15, 0x1f, 0xb8, 0x4c, 0x7a,
+  0xf9, 0xfc, 0xfa, 0xc7, 0xbd, 0xc1, 0xde, 0xee, 0xee, 0xee, 0xcf, 0xc3,
+  0x05, 0x4d, 0xf1, 0x15, 0x9a, 0x35, 0xff, 0xf5, 0x9b, 0xdd, 0xe1, 0x9e,
+  0xec, 0x44, 0xc9, 0xb0, 0x64, 0x22, 0x6d, 0xd6, 0x77, 0xc1, 0x4c, 0xb8,
+  0xbc, 0x95, 0x0f, 0x3c, 0x31, 0xc3, 0xee, 0xf5, 0x74, 0x75, 0xde, 0x1d,
+  0x97, 0xa6, 0x20, 0x9f, 0xe2, 0xb3, 0x27, 0xfb, 0xfb, 0x09, 0xab, 0x1c,
+  0x0c, 0x67, 0xe7, 0x18, 0x0f, 0x65, 0x32, 0x4a, 0xfd, 0x3e, 0xbe, 0xcd,
+  0x26, 0x44, 0xe9, 0x52, 0x71, 0x71, 0xb0, 0xa0, 0x50, 0x94, 0x45, 0x4f,
+  0x70, 0x25, 0x6e, 0x23, 0xc8, 0x8c, 0xfc, 0x29, 0xa7, 0xf7, 0xae, 0x61,
+  0xb3, 0xcb, 0x2b, 0x92, 0xae, 0x5c, 0x66, 0xc7, 0xd6, 0xa1, 0x4e, 0xeb,
+  0x98, 0xde, 0x66, 0xa1, 0xe9, 0xb8, 0xe6, 0xc0, 0x1c, 0x56, 0x94, 0x52,
+  0x45, 0x0e, 0xe1, 0x8c, 0xab, 0x65, 0x25, 0xe4, 0xe1, 0x88, 0xff, 0xdc,
+  0xa5, 0xf7, 0xad, 0xeb, 0xde, 0xcc, 0xf8, 0x0b, 0xf3, 0x9f, 0x55, 0x75,
+  0x5f, 0x53, 0x2d, 0x80, 0x76, 0x95, 0x35, 0x93, 0x9b, 0x80, 0x0a, 0x13,
+  0x02, 0x9c, 0x94, 0xf7, 0x1b, 0x33, 0x1a, 0xcb, 0x34, 0xb9, 0xaa, 0xb4,
+  0x8a, 0xcb, 0xe3, 0x31, 0x8d, 0x12, 0x97, 0x2e, 0xaa, 0xab, 0x70, 0xb5,
+  0x45, 0x96, 0x8a, 0x11, 0xf5, 0xc8, 0xd3, 0xea, 0xa8, 0x2b, 0x04, 0xa5,
+  0xc9, 0x6b, 0xcd, 0x33, 0x9a, 0xdc, 0x64, 0x73, 0x91, 0x98, 0x5b, 0x8a,
+  0x24, 0xe9, 0xc9, 0x26, 0xec, 0x85, 0x97, 0x5a, 0xef, 0x4a, 0x7e, 0x63,
+  0x06, 0xb3, 0x2d, 0x79, 0x3a, 0xf6, 0x9e, 0x13, 0x82, 0xf1, 0xeb, 0x25,
+  0xd9, 0x8d, 0xe3, 0x54, 0x2e, 0x14, 0xa5, 0xb1, 0x5d, 0x85, 0x83, 0x22,
+  0xa1, 0x98, 0x55, 0xb8, 0xc7, 0xc8, 0xcd, 0x32, 0x10, 0xed, 0x47, 0xae,
+  0x55, 0xc4, 0xdd, 0xcc, 0x89, 0x7d, 0x75, 0x72, 0x74, 0x89, 0xa4, 0x99,
+  0x3e, 0xd0, 0xb5, 0x7d, 0x64, 0xca, 0x84, 0xfc, 0xef, 0xe7, 0x70, 0x83,
+  0x60, 0xa3, 0x8a, 0x7b, 0x39, 0x75, 0xc8, 0x03, 0xee, 0xa5, 0xa5, 0x63,
+  0xed, 0x27, 0x3e, 0x73, 0x7f, 0x84, 0x8e, 0xbd, 0xa5, 0x27, 0x5a, 0xbc,
+  0xc6, 0xd3, 0x67, 0xc3, 0x5d, 0x1e, 0xa3, 0x2b, 0x2f, 0xa7, 0xd8, 0x6e,
+  0x78, 0x8b, 0x6a, 0xe1, 0xc8, 0x4b, 0x57, 0xf0, 0x7b, 0x6a, 0x77, 0xfa,
+  0x09, 0x53, 0x42, 0x72, 0xea, 0xa5, 0xfe, 0xd6, 0x03, 0x91, 0xac, 0xd5,
+  0x4d, 0xfd, 0x7a, 0xbf, 0xb4, 0x2d, 0x3b, 0x4c, 0x7e, 0x14, 0x08, 0x2d,
+  0x6d, 0x56, 0x86, 0xe4, 0x65, 0xc7, 0xe0, 0xf5, 0xd8, 0x13, 0x89, 0x38,
+  0xaa, 0x9a, 0xac, 0xe8, 0x3b, 0x3a, 0xf7, 0x92, 0x6e, 0x01, 0xb9, 0xb2,
+  0x04, 0xaa, 0xdc, 0xaa, 0x81, 0x14, 0xd3, 0x50, 0x02, 0xa6, 0xfc, 0xc1,
+  0x57, 0x52, 0xc6, 0x8e, 0x35, 0xe5, 0x18, 0x54, 0x9c, 0x96, 0x72, 0x5b,
+  0xc1, 0x3f, 0x6c, 0xb9, 0xaa, 0xca, 0x39, 0x24, 0x6f, 0x60, 0xc2, 0xeb,
+  0x2e, 0xfd, 0xe5, 0x32, 0x84, 0xf0, 0x35, 0x07, 0x45, 0x1a, 0xb2, 0x02,
+  0x19, 0xd1, 0x42, 0x2a, 0x21, 0xa4, 0xf6, 0x72, 0x02, 0x69, 0x27, 0xc0,
+  0xdc, 0x83, 0x83, 0xaa, 0xf7, 0x39, 0xf9, 0xb4, 0x5f, 0x1e, 0xf6, 0x5a,
+  0x27, 0x32, 0x46, 0x08, 0x5f, 0xb3, 0x74, 0x6b, 0xdb, 0x32, 0x22, 0xd3,
+  0x48, 0xee, 0x67, 0x1f, 0x1b, 0xbe, 0xf9, 0xaf, 0x50, 0xda, 0xad, 0x78,
+  0xb2, 0x9f, 0xd4, 0xf7, 0x46, 0x8d, 0x98, 0xfb, 0x93, 0xd0, 0xad, 0xe5,
+  0x17, 0xf5, 0xe3, 0xb7, 0x0a, 0x60, 0xb0, 0xdc, 0x7a, 0x47, 0xaf, 0x1c,
+  0xe2, 0x15, 0xa1, 0xcb, 0x57, 0x18, 0xc3, 0x23, 0x0a, 0x44, 0x96, 0x89,
+  0x4a, 0xb1, 0xf1, 0x2c, 0x2d, 0x3e, 0xd4, 0x56, 0xd3, 0x46, 0x4b, 0x7d,
+  0xaa, 0xbb, 0xc4, 0x99, 0x27, 0xee, 0x87, 0x82, 0x6b, 0xc0, 0xcd, 0xd8,
+  0x69, 0xee, 0xef, 0x4b, 0xd2, 0x4c, 0xe7, 0x69, 0x45, 0x29, 0x09, 0x0f,
+  0x17, 0x9f, 0x74, 0xd5, 0x27, 0xe3, 0x73, 0xeb, 0xca, 0x51, 0xfe, 0x7e,
+  0x11, 0xd9, 0xa5, 0xce, 0xba, 0x91, 0xd0, 0xe6, 0xbf, 0x07, 0x1a, 0xab,
+  0x58, 0x57, 0xa3, 0x1b, 0x8f, 0xdb, 0xca, 0x81, 0x36, 0xba, 0xe1, 0xd7,
+  0x82, 0x62, 0x65, 0xce, 0x45, 0x54, 0x62, 0xc9, 0x1b, 0xc3, 0xe4, 0xcc,
+  0x19, 0x8f, 0x45, 0x1f, 0x84, 0x79, 0x4d, 0x35, 0x11, 0xd3, 0x11, 0x7f,
+  0x1f, 0x68, 0x59, 0xd7, 0xd8, 0x0c, 0xa0, 0x28, 0x02, 0x21, 0x43, 0xee,
+  0xad, 0xc8, 0x6f, 0xf5, 0xae, 0xaf, 0x0e, 0x7c, 0x96, 0x69, 0x46, 0x86,
+  0x50, 0x6d, 0x1e, 0x8e, 0xe3, 0xa5, 0x01, 0x38, 0x8d, 0x07, 0x11, 0x2f,
+  0xc7, 0xc0, 0x51, 0x3d, 0x5b, 0x8d, 0xc9, 0x3d, 0x5e, 0x4b, 0x24, 0x6f,
+  0x66, 0xee, 0xc0, 0xe5, 0xc2, 0x55, 0x4d, 0xe2, 0x0c, 0xce, 0x59, 0x59,
+  0xf4, 0x03, 0xee, 0x07, 0x22, 0x9f, 0x64, 0xff, 0x12, 0xc1, 0x22, 0xe6,
+  0x52, 0x04, 0xcf, 0x56, 0xd2, 0x4a, 0xf9, 0x3d, 0xdd, 0x87, 0xfe, 0x97,
+  0x1f, 0xa8, 0xd7, 0xc5, 0xec, 0xe2, 0xba, 0x18, 0x66, 0xe3, 0xf5, 0x19,
+  0xe3, 0x3f, 0x5c, 0xa1, 0xba, 0xf0, 0xc9, 0xff, 0xd6, 0xd8, 0xeb, 0x59,
+  0x55, 0x1a, 0xa1, 0xf1, 0xdd, 0x33, 0x05, 0x2c, 0x48, 0xfd, 0x3f, 0xb9,
+  0x9f, 0x64, 0x2d, 0x31, 0xdb, 0xe0, 0x56, 0x89, 0xba, 0x4d, 0x58, 0x1e,
+  0xea, 0x9b, 0x72, 0x41, 0xb1, 0xd9, 0x56, 0x74, 0x97, 0x85, 0xae, 0x2e,
+  0xd3, 0x47, 0x14, 0x05, 0x0c, 0xae, 0x4f, 0x36, 0x9f, 0xc5, 0x18, 0x20,
+  0x43, 0xc1, 0x5c, 0xb9, 0xa4, 0xeb, 0x90, 0x83, 0xc7, 0x08, 0xac, 0x72,
+  0xdc, 0xe0, 0xea, 0x4b, 0x5d, 0xcf, 0x2f, 0x73, 0x72, 0x02, 0xac, 0xa8,
+  0xb7, 0xc6, 0x98, 0x3e, 0xb9, 0xe8, 0x1c, 0xc7, 0x64, 0x27, 0xd6, 0x47,
+  0x9a, 0x45, 0x7d, 0x43, 0x77, 0x33, 0xdd, 0x19, 0x30, 0xfc, 0x36, 0xe2,
+  0x9c, 0x89, 0x34, 0x69, 0x6f, 0x2f, 0x4f, 0xdf, 0xf4, 0x3b, 0x27, 0x21,
+  0x28, 0x90, 0xae, 0x5b, 0x53, 0x53, 0xab, 0xc3, 0xac, 0x32, 0x59, 0xd8,
+  0xbe, 0x2b, 0x55, 0xc4, 0x59, 0x8d, 0x34, 0x75, 0x7d, 0x49, 0x5a, 0xa9,
+  0x04, 0xfa, 0xac, 0xb6, 0x20, 0xcf, 0x6b, 0xe8, 0xdd, 0x24, 0xc4, 0x4f,
+  0x0d, 0x3f, 0x01, 0xcc, 0x67, 0x23, 0x6a, 0xcc, 0x76, 0xf4, 0x0a, 0x7c,
+  0x84, 0xfb, 0xba, 0x6c, 0x1d, 0x1a, 0x7f, 0xc1, 0x68, 0x1b, 0x32, 0xa5,
+  0x6c, 0xf2, 0xaa, 0xbc, 0x2b, 0x06, 0xa7, 0x94, 0xbf, 0x92, 0x9c, 0x96,
+  0xd7, 0x64, 0x21, 0xbd, 0x8d, 0x5b, 0xf2, 0xef, 0xce, 0xdf, 0x26, 0x5b,
+  0x24, 0x89, 0x93, 0x73, 0xcb, 0x5a, 0x42, 0x8f, 0x6e, 0x8b, 0xc6, 0x59,
+  0xf3, 0x2d, 0x25, 0xbd, 0xe9, 0x27, 0xc7, 0x3f, 0x1c, 0xbe, 0x39, 0x3f,
+  0x3d, 0xfe, 0x89, 0x95, 0xce, 0x60, 0x38, 0xf4, 0xe3, 0x2f, 0x3d, 0x2d,
+  0x1c, 0x5e, 0x7b, 0x8a, 0x63, 0x99, 0x9e, 0xdc, 0xaf, 0x92, 0x05, 0x7c,
+  0x7c, 0x74, 0x0b, 0x8e, 0x46, 0xe7, 0x27, 0x03, 0x25, 0x1c, 0xe1, 0x8a,
+  0x30, 0x79, 0x41, 0x0a, 0x33, 0x1f, 0x60, 0x25, 0x03, 0xfe, 0x36, 0x0c,
+  0x50, 0xd8, 0xf3, 0xd0, 0x4f, 0xde, 0x2a, 0x83, 0x67, 0x1f, 0x8b, 0x4e,
+  0x57, 0xfc, 0xab, 0xfc, 0x1a, 0x51, 0x86, 0x0e, 0x7d, 0x88, 0x96, 0xd0,
+  0x9e, 0x04, 0xb8, 0x57, 0xca, 0x70, 0xb3, 0xe1, 0xa1, 0x3a, 0x9b, 0xb1,
+  0x43, 0x6b, 0xa5, 0x14, 0xe5, 0x7a, 0x79, 0x58, 0x45, 0x00, 0x2a, 0x83,
+  0xf0, 0x89, 0x00, 0x2c, 0xc7, 0x56, 0xea, 0x89, 0x9a, 0xca, 0x3b, 0x84,
+  0xa5, 0x87, 0x5c, 0x33, 0x56, 0x38, 0x1c, 0x18, 0x5b, 0x7d, 0x99, 0x1c,
+  0xf4, 0x7e, 0xc7, 0x8b, 0xc4, 0xf7, 0xfe, 0x45, 0x38, 0xe5, 0x6d, 0x34,
+  0xd5, 0xfa, 0x8a, 0x39, 0xd9, 0x97, 0xdd, 0x98, 0xea, 0x84, 0x81, 0xff,
+  0xd3, 0x9c, 0x74, 0x51, 0xf1, 0xc6, 0xcb, 0xeb, 0xeb, 0x48, 0x42, 0x30,
+  0x95, 0x80, 0xc9, 0x32, 0x5c, 0xc5, 0x46, 0x63, 0xd9, 0xac, 0x13, 0xf6,
+  0xe9, 0x9a, 0xfe, 0xf7, 0x10, 0xab, 0x52, 0x32, 0x86, 0x72, 0x6a, 0x54,
+  0x97, 0xe4, 0x50, 0xdd, 0xd2, 0xa8, 0x22, 0x1e, 0x36, 0xc7, 0x19, 0x26,
+  0x9b, 0x5f, 0x6c, 0x2a, 0x9d, 0xb2, 0x51, 0xee, 0xe5, 0x56, 0x26, 0xad,
+  0xa6, 0xc7, 0x6a, 0xcd, 0x98, 0xcb, 0x0a, 0xf5, 0x93, 0xcd, 0x17, 0x9b,
+  0xf2, 0x9c, 0x3c, 0xd6, 0x15, 0x38, 0x78, 0x87, 0xa3, 0x3e, 0xac, 0xec,
+  0x4e, 0xac, 0x5f, 0xcc, 0x4c, 0xef, 0x4d, 0x3e, 0x9d, 0x72, 0x81, 0x79,
+  0x29, 0xd2, 0x21, 0x1c, 0x41, 0x52, 0xee, 0x2d, 0xb8, 0x98, 0xd0, 0x75,
+  0xed, 0x39, 0xf7, 0x75, 0xf3, 0xcf, 0xda, 0x03, 0xaf, 0x88, 0x15, 0xb9,
+  0xa9, 0x5d, 0x6d, 0x09, 0xf9, 0xea, 0xaa, 0x93, 0x82, 0x58, 0x08, 0xcc,
+  0x25, 0xe8, 0x46, 0x6a, 0x2d, 0x8a, 0xa4, 0x66, 0x75, 0xb6, 0xdf, 0x01,
+  0xb1, 0x23, 0xd6, 0x11, 0xba, 0xb4, 0x1a, 0xcb, 0x89, 0x85, 0xaa, 0xf0,
+  0x15, 0xb1, 0x9c, 0x73, 0x8d, 0x49, 0xaa, 0xc2, 0xb1, 0xe2, 0xfb, 0xea,
+  0xed, 0x73, 0x1b, 0x8f, 0xb3, 0xd1, 0x14, 0x49, 0x48, 0x96, 0x18, 0x1e,
+  0xcc, 0x0a, 0xf8, 0x7d, 0x55, 0xdb, 0xef, 0x87, 0xf9, 0xd0, 0x5c, 0x81,
+  0x41, 0x09, 0x98, 0x6d, 0x44, 0xa2, 0x1d, 0x3f, 0x53, 0x24, 0x60, 0x94,
+  0x89, 0xd5, 0x4b, 0xd7, 0x68, 0x57, 0xcd, 0x10, 0xff, 0x26, 0x28, 0x6a,
+  0xa3, 0x31, 0x56, 0x51, 0xb1, 0x69, 0x9e, 0xdc, 0x44, 0x05, 0x39, 0x14,
+  0xce, 0x43, 0xee, 0x07, 0x63, 0x42, 0x7c, 0x50, 0xd4, 0x55, 0xfe, 0x9d,
+  0x9c, 0xaa, 0x08, 0x1e, 0xf1, 0x95, 0x04, 0x53, 0x5a, 0x35, 0xd1, 0x19,
+  0x53, 0xcf, 0xae, 0x24, 0xd1, 0x5a, 0x35, 0x64, 0xab, 0xd1, 0xe3, 0x1c,
+  0x1e, 0xdf, 0x7a, 0x18, 0x51, 0x74, 0x58, 0x71, 0xc1, 0x96, 0x93, 0xd1,
+  0xb0, 0xcb, 0x15, 0xc1, 0x15, 0x7d, 0xbf, 0x14, 0x86, 0xa6, 0xbe, 0x17,
+  0x0d, 0x8e, 0x84, 0xdb, 0x70, 0x7f, 0x3c, 0xb1, 0xc5, 0x79, 0xcd, 0xa3,
+  0x55, 0x5a, 0x71, 0x7d, 0xb4, 0xe2, 0x83, 0xa2, 0x67, 0xa8, 0xf1, 0xec,
+  0x63, 0x36, 0x59, 0x36, 0x6d, 0xac, 0xb8, 0xaf, 0x7c, 0x29, 0x4f, 0x38,
+  0xba, 0xb5, 0x85, 0xa3, 0xa0, 0x06, 0xca, 0xb9, 0x66, 0x76, 0x1f, 0xf4,
+  0xb6, 0x25, 0xb4, 0x47, 0x21, 0x1f, 0x9b, 0xf0, 0x1d, 0x8b, 0xd9, 0x69,
+  0x9f, 0xab, 0x8c, 0x7d, 0x6c, 0x2e, 0x7c, 0x1d, 0xfd, 0x3c, 0x17, 0x18,
+  0x8e, 0x7c, 0xfb, 0x35, 0x7b, 0x63, 0xbc, 0x4f, 0xdb, 0xfa, 0x34, 0xe2,
+  0xa8, 0xa9, 0x83, 0xa3, 0x1c, 0x7c, 0x19, 0xf5, 0xe1, 0x86, 0xc9, 0xa1,
+  0xad, 0xec, 0xa8, 0xaf, 0xea, 0xfc, 0x07, 0x0e, 0xb2, 0x93, 0xf3, 0xdb,
+  0xe7, 0x9e, 0x7f, 0x93, 0xee, 0x3c, 0xfc, 0xc8, 0x4a, 0xfc, 0x60, 0x14,
+  0x1f, 0xaa, 0xf1, 0x53, 0xf3, 0xc7, 0xb7, 0xf4, 0x07, 0x89, 0x55, 0x32,
+  0x27, 0x99, 0x96, 0x85, 0x3d, 0x73, 0xe1, 0xd6, 0xa6, 0xa4, 0x3a, 0xf9,
+  0x43, 0x16, 0x1d, 0x58, 0x60, 0x82, 0xf4, 0x13, 0x89, 0x8b, 0xcb, 0xa7,
+  0x87, 0xf2, 0xab, 0xed, 0xf4, 0x35, 0xcd, 0x26, 0x8e, 0x93, 0x04, 0xe7,
+  0x08, 0x73, 0x7a, 0xf4, 0xe1, 0x85, 0x18, 0xb1, 0x20, 0x2f, 0x63, 0x89,
+  0x16, 0x66, 0xaa, 0xfe, 0x41, 0xce, 0x6b, 0x2d, 0x07, 0x8d, 0xea, 0xa4,
+  0x73, 0x0b, 0xac, 0x85, 0x61, 0x64, 0x63, 0xfc, 0xec, 0xaf, 0xa4, 0x63,
+  0xc6, 0xe2, 0x2c, 0xc4, 0x57, 0x59, 0xaa, 0x95, 0x55, 0x43, 0xc6, 0xe5,
+  0x2e, 0x7f, 0x84, 0xb4, 0x65, 0xab, 0xdf, 0x7b, 0x85, 0x34, 0x23, 0x39,
+  0xf0, 0x7c, 0x14, 0x96, 0x5c, 0xc0, 0x55, 0x17, 0xdb, 0x65, 0x20, 0xf2,
+  0xc3, 0x62, 0x17, 0xb2, 0x62, 0xb2, 0xa2, 0x9f, 0x54, 0x07, 0x90, 0x89,
+  0x9b, 0x21, 0x15, 0x3e, 0x68, 0xf4, 0x72, 0x9e, 0xcd, 0x29, 0x18, 0x62,
+  0xef, 0x45, 0xa6, 0x81, 0x60, 0xf3, 0x9f, 0x3e, 0x36, 0x88, 0x37, 0x37,
+  0x25, 0xfd, 0x8d, 0xae, 0x58, 0xc6, 0xed, 0xfc, 0x21, 0x88, 0x80, 0xd5,
+  0xf7, 0xc5, 0xe4, 0xe6, 0xd5, 0xdb, 0x51, 0xfc, 0xf5, 0x70, 0x70, 0x78,
+  0xde, 0xe8, 0x21, 0xb4, 0x19, 0xa4, 0x46, 0x2e, 0x58, 0x90, 0xa8, 0x62,
+  0xb8, 0xf7, 0xbb, 0x78, 0x73, 0xad, 0x17, 0xac, 0x6f, 0x88, 0x14, 0x0b,
+  0x16, 0xe2, 0xa2, 0x79, 0x02, 0xaf, 0x3d, 0x48, 0xe9, 0x28, 0xc4, 0x2b,
+  0x2f, 0xd9, 0x33, 0x4d, 0x11, 0x04, 0x54, 0xa8, 0x44, 0x93, 0x95, 0x87,
+  0x3c, 0xea, 0xee, 0x6b, 0x90, 0xb6, 0xeb, 0x1f, 0xbf, 0x64, 0x99, 0x4f,
+  0xa9, 0xc8, 0x69, 0x24, 0xe0, 0xe4, 0xcf, 0x50, 0x0b, 0x22, 0xe2, 0xc5,
+  0x03, 0xcd, 0x5e, 0x9d, 0xd1, 0xeb, 0xbc, 0x4d, 0xfb, 0xb2, 0x5b, 0xf1,
+  0xa3, 0x6a, 0xd5, 0x90, 0xcc, 0xa4, 0xec, 0x7f, 0xfd, 0x55, 0x78, 0x7b,
+  0xbe, 0x7a, 0xbb, 0xe2, 0x73, 0xf4, 0x9b, 0x81, 0xc2, 0xee, 0x45, 0x23,
+  0xf0, 0x54, 0xfa, 0x70, 0x2e, 0xe2, 0x04, 0xa1, 0xed, 0x5f, 0x3e, 0x24,
+  0x25, 0xcc, 0x13, 0xf2, 0xc7, 0xda, 0x07, 0x05, 0x32, 0x1b, 0xff, 0x14,
+  0x61, 0x69, 0xb7, 0x18, 0xd9, 0x95, 0x5c, 0x70, 0x60, 0xef, 0x5c, 0x34,
+  0xe1, 0xed, 0xc8, 0x12, 0xad, 0x84, 0xeb, 0x3a, 0x33, 0x28, 0x89, 0x91,
+  0x1a, 0x90, 0x5c, 0xd8, 0xe7, 0x3f, 0x76, 0xf6, 0x2d, 0x5c, 0xc9, 0xe6,
+  0x4e, 0xe0, 0x90, 0x9a, 0x0b, 0x3c, 0x54, 0x10, 0x8a, 0xfc, 0xe3, 0x08,
+  0x31, 0xe6, 0x15, 0xbb, 0x19, 0xc1, 0x68, 0x8e, 0x42, 0xdb, 0x39, 0xa0,
+  0x8e, 0xaa, 0x26, 0x16, 0xed, 0xc9, 0x88, 0xf3, 0x00, 0x1f, 0xda, 0x4c,
+  0x79, 0x04, 0x61, 0xb5, 0x8e, 0xb9, 0xe9, 0x8d, 0x51, 0x92, 0xe8, 0x72,
+  0x7d, 0xf8, 0x18, 0xdb, 0x7d, 0x63, 0xdf, 0x49, 0xb6, 0xc6, 0xe6, 0xc6,
+  0xf6, 0x32, 0xb1, 0x49, 0xde, 0x3c, 0x05, 0xca, 0x39, 0xde, 0xdc, 0xb3,
+  0x4f, 0x9f, 0x3d, 0xdd, 0xde, 0xd6, 0x8a, 0x92, 0x0c, 0x98, 0x18, 0x13,
+  0x50, 0x3f, 0x27, 0xb9, 0xc5, 0xb5, 0xe9, 0x68, 0x82, 0x6f, 0xe0, 0x67,
+  0xf5, 0x1c, 0x31, 0xf1, 0xe6, 0xe8, 0x1e, 0xd3, 0x57, 0x69, 0x11, 0xc9,
+  0x04, 0x87, 0x44, 0xb7, 0x66, 0x70, 0xaa, 0x32, 0xb1, 0x76, 0x5e, 0xf8,
+  0x95, 0x52, 0x01, 0x71, 0x23, 0xe7, 0x87, 0xe2, 0x72, 0xd8, 0x10, 0xa3,
+  0x7a, 0xd3, 0x86, 0x08, 0xc0, 0x73, 0xbe, 0xf6, 0xe8, 0x0f, 0xda, 0xcf,
+  0x37, 0x5a, 0x0a, 0xed, 0x7c, 0x39, 0x9e, 0x99, 0x1b, 0x68, 0x44, 0x65,
+  0x3d, 0x3f, 0x26, 0xa7, 0x79, 0xdd, 0x88, 0x30, 0x86, 0xad, 0xa0, 0xa0,
+  0xb9, 0x55, 0x77, 0x0e, 0x0f, 0x1c, 0xe9, 0xaa, 0xd8, 0x6a, 0xb2, 0xa4,
+  0x7c, 0x23, 0xb8, 0x64, 0x27, 0xd6, 0xdb, 0x7a, 0x0b, 0xfe, 0x56, 0xbd,
+  0xbc, 0x1a, 0xac, 0x1a, 0xd8, 0xc7, 0xac, 0xf6, 0xcc, 0xb8, 0xc1, 0x1d,
+  0x29, 0x88, 0xc8, 0xb6, 0x26, 0x37, 0x74, 0xf2, 0x82, 0x55, 0xc1, 0xd5,
+  0x55, 0xbd, 0x34, 0xbd, 0xcf, 0x57, 0x1a, 0xa1, 0x7f, 0xc3, 0x65, 0x9b,
+  0x5e, 0x51, 0x2e, 0x12, 0x23, 0xe8, 0x66, 0x19, 0x4a, 0xdb, 0x92, 0x20,
+  0x0b, 0xe0, 0xcf, 0xb6, 0x42, 0xb0, 0x98, 0xf7, 0x89, 0x78, 0x29, 0xc4,
+  0xff, 0x0a, 0x6c, 0x54, 0x8a, 0x0c, 0x7a, 0x78, 0x6b, 0x38, 0x71, 0x9b,
+  0xdd, 0xc0, 0x66, 0x00, 0xd3, 0x98, 0x05, 0xd6, 0x76, 0xd0, 0x6b, 0xfa,
+  0x60, 0xcd, 0x6e, 0x2d, 0xf9, 0x4a, 0xe8, 0x64, 0x89, 0x55, 0x5b, 0x9b,
+  0x99, 0xc9, 0x20, 0xe3, 0x35, 0xe9, 0x71, 0x7f, 0x08, 0xbc, 0x4f, 0x77,
+  0x88, 0x46, 0x3f, 0x81, 0x9e, 0x51, 0x0d, 0x9f, 0x75, 0x64, 0x69, 0x1f,
+  0xb6, 0x77, 0x1a, 0x2b, 0x45, 0xce, 0x3a, 0xdf, 0x97, 0x0a, 0xc2, 0xe9,
+  0x69, 0xec, 0xb6, 0x65, 0xdc, 0xdb, 0xe6, 0xec, 0xac, 0x44, 0x72, 0x08,
+  0x39, 0xa0, 0x8d, 0x52, 0x83, 0xb4, 0x6a, 0xa6, 0xd1, 0x41, 0x2f, 0xae,
+  0xf8, 0xda, 0x39, 0x00, 0x03, 0x39, 0xac, 0xd0, 0x96, 0x85, 0xa6, 0x5f,
+  0x51, 0x83, 0x9c, 0x00, 0xb8, 0x4d, 0xde, 0x2c, 0x43, 0xe9, 0x28, 0x11,
+  0x3e, 0x64, 0x5c, 0x22, 0x4c, 0x41, 0x2b, 0xe1, 0xd2, 0x22, 0x61, 0x8e,
+  0x11, 0x56, 0x8f, 0x0a, 0x07, 0xd5, 0x89, 0x3d, 0xcd, 0xc8, 0x25, 0x9b,
+  0x95, 0x77, 0x01, 0x86, 0x97, 0xdc, 0xa9, 0xae, 0x77, 0xed, 0x64, 0x06,
+  0x2a, 0x10, 0xff, 0x9f, 0xfa, 0xcb, 0xf7, 0x34, 0x59, 0xff, 0xa5, 0x93,
+  0x25, 0xdd, 0x4e, 0x83, 0xc4, 0x3f, 0xd8, 0xc1, 0x7f, 0xc2, 0xa4, 0xfc,
+  0x8d, 0x10, 0x29, 0x3c, 0x33, 0xa6, 0xcb, 0x73, 0x34, 0xf7, 0xa7, 0xa1,
+  0xd5, 0x77, 0xb5, 0x09, 0x4a, 0x63, 0x62, 0xab, 0x7e, 0x7c, 0x1f, 0xf8,
+  0x8e, 0x68, 0x0f, 0xfe, 0x54, 0xf4, 0xc1, 0xaa, 0x67, 0x4c, 0xaf, 0x14,
+  0xe5, 0x67, 0xa9, 0x34, 0x14, 0x2f, 0xe3, 0x4f, 0x95, 0x64, 0xd0, 0x1b,
+  0xa3, 0xc3, 0x74, 0x9c, 0x0c, 0x32, 0xfe, 0x79, 0x68, 0x01, 0x10, 0x5a,
+  0xe6, 0x00, 0xab, 0xf1, 0xa7, 0x41, 0x7d, 0x3f, 0x1f, 0x97, 0x33, 0xd9,
+  0xe8, 0x34, 0x5c, 0xd3, 0x67, 0xfd, 0x19, 0x2f, 0x0b, 0x22, 0x1b, 0x03,
+  0x2f, 0x0b, 0xb6, 0x1f, 0x65, 0xfe, 0x25, 0x13, 0xa5, 0x9c, 0x4c, 0x90,
+  0x8e, 0x42, 0x28, 0x6e, 0xb3, 0xdd, 0xff, 0x94, 0x30, 0x14, 0x07, 0x81,
+  0x37, 0x2e, 0x71, 0x34, 0xd5, 0x40, 0xe7, 0xd2, 0x15, 0x0f, 0x8d, 0x66,
+  0x81, 0x44, 0x37, 0x8f, 0xb7, 0x3a, 0xd6, 0xb6, 0x88, 0x65, 0x10, 0xd3,
+  0x09, 0x35, 0x1d, 0x7d, 0x8f, 0xac, 0x13, 0xd9, 0x77, 0x47, 0xfc, 0xb3,
+  0xc1, 0x25, 0x7e, 0xa6, 0xb8, 0x03, 0xc9, 0x58, 0xa3, 0x48, 0xb6, 0xa4,
+  0x94, 0x91, 0x8f, 0x32, 0x2e, 0xa5, 0xda, 0x60, 0x26, 0x14, 0x88, 0x2c,
+  0xc2, 0xfb, 0x4a, 0x0f, 0xd3, 0x7b, 0x4e, 0xdb, 0x37, 0x36, 0xff, 0xfa,
+  0xd6, 0xc0, 0xa1, 0x3e, 0x6b, 0xf2, 0x79, 0x2a, 0xf0, 0x1f, 0xc6, 0xfb,
+  0xd8, 0x6d, 0xac, 0xa4, 0x13, 0x40, 0x83, 0x9a, 0xfd, 0x36, 0x7c, 0xa8,
+  0x39, 0xba, 0x10, 0x15, 0xcc, 0x2e, 0x48, 0x09, 0xf2, 0x3d, 0x99, 0x2b,
+  0x47, 0xef, 0xdf, 0xa6, 0x9c, 0x31, 0x44, 0x83, 0x5a, 0x7e, 0x60, 0xac,
+  0xa5, 0xe6, 0x79, 0x8a, 0x47, 0x89, 0xc1, 0x1a, 0x67, 0xfd, 0xc4, 0x45,
+  0x03, 0x15, 0x06, 0x95, 0x50, 0xe0, 0x70, 0x7d, 0x73, 0x36, 0xaa, 0x68,
+  0xdd, 0xfb, 0x27, 0xe4, 0xe9, 0x42, 0x0c, 0x78, 0xc9, 0x3e, 0xb2, 0x1c,
+  0xa5, 0xdd, 0xc9, 0xab, 0x19, 0x89, 0x1d, 0x25, 0x11, 0x11, 0x8b, 0xb8,
+  0xd3, 0x7f, 0x78, 0xd1, 0x49, 0x76, 0xfc, 0x0c, 0xbc, 0xa8, 0xe4, 0x50,
+  0xeb, 0x00, 0xaf, 0x6f, 0x6e, 0x75, 0x51, 0xe2, 0xab, 0x66, 0xf1, 0x9e,
+  0x4a, 0xaa, 0xde, 0xbf, 0x27, 0x5c, 0x1f, 0xd6, 0x4c, 0x7d, 0xee, 0xf8,
+  0x01, 0x66, 0x96, 0x73, 0xe4, 0x96, 0x0b, 0x6a, 0x07, 0x9b, 0x7c, 0x56,
+  0xb2, 0x41, 0xf3, 0xd0, 0x30, 0xda, 0x08, 0x3a, 0x3f, 0x17, 0x7b, 0xab,
+  0x5d, 0x65, 0xe3, 0x69, 0xd0, 0x31, 0x0a, 0xd8, 0xbf, 0x47, 0xa4, 0xcf,
+  0x6e, 0x26, 0x73, 0xdd, 0x64, 0x55, 0x3e, 0xf1, 0x4b, 0x4e, 0xe1, 0x01,
+  0x6c, 0x29, 0xe6, 0x5e, 0xa2, 0xd0, 0x5f, 0x94, 0x64, 0xae, 0xf3, 0x3f,
+  0xf0, 0x8e, 0x4a, 0x85, 0x2d, 0x94, 0xdb, 0x55, 0x80, 0x58, 0x22, 0xb1,
+  0x59, 0x42, 0x22, 0xb8, 0x88, 0xed, 0xc9, 0x03, 0xe3, 0x04, 0x8b, 0xe5,
+  0x3e, 0xc6, 0x6a, 0xd4, 0xb3, 0xb4, 0xb6, 0x1d, 0xe4, 0x11, 0xd8, 0x92,
+  0xab, 0x1c, 0x20, 0xb9, 0x09, 0x88, 0x02, 0xc3, 0x73, 0xc8, 0x90, 0x1d,
+  0xba, 0xf5, 0x87, 0x2b, 0x66, 0x86, 0xa1, 0x96, 0x22, 0x03, 0xdc, 0xd4,
+  0xf0, 0x94, 0x88, 0x9e, 0xd3, 0x9d, 0x94, 0x18, 0x46, 0x30, 0xe9, 0xe2,
+  0xdf, 0x95, 0x64, 0x64, 0x8b, 0x5d, 0xdb, 0xa9, 0x90, 0x12, 0x6f, 0x0b,
+  0x0e, 0x4c, 0x75, 0x24, 0xe5, 0x25, 0x79, 0xa8, 0x39, 0x88, 0xa1, 0xce,
+  0x82, 0xef, 0xaf, 0x5a, 0x70, 0x55, 0x68, 0x65, 0x58, 0xf4, 0x33, 0xeb,
+  0xd4, 0xf0, 0x07, 0x95, 0x58, 0x19, 0x34, 0xbb, 0x4f, 0xa2, 0x44, 0xa6,
+  0x9d, 0xff, 0xf1, 0x3f, 0xff, 0x2c, 0x56, 0x2d, 0x1b, 0xc8, 0xcb, 0xf7,
+  0xf9, 0xc2, 0x13, 0x5e, 0x5e, 0x19, 0x5d, 0x8b, 0xe6, 0x62, 0x80, 0x26,
+  0x9d, 0x08, 0x0f, 0xe2, 0x45, 0xa7, 0xfc, 0xa1, 0x69, 0x98, 0x20, 0x97,
+  0x31, 0x61, 0xd3, 0xd9, 0x23, 0x3b, 0x1b, 0xa8, 0x96, 0x24, 0x86, 0xf4,
+  0xc9, 0x39, 0x4a, 0x04, 0xaf, 0x6f, 0x0e, 0x2e, 0xa4, 0x56, 0xc1, 0xf1,
+  0xcf, 0x56, 0x0e, 0x89, 0xcb, 0x5c, 0xcb, 0x90, 0xb8, 0xfb, 0x3e, 0x99,
+  0xb1, 0x60, 0xe9, 0x19, 0xac, 0xd2, 0xee, 0xe6, 0xfa, 0x3e, 0x78, 0x63,
+  0x78, 0xb0, 0x27, 0xe6, 0x5b, 0xef, 0x2d, 0x19, 0xa6, 0xb9, 0xa6, 0xa5,
+  0x7c, 0xb4, 0xf9, 0xb6, 0xd1, 0x0b, 0x1c, 0x4d, 0x26, 0xea, 0x74, 0xca,
+  0x4e, 0xe5, 0xae, 0xc4, 0xf5, 0xd9, 0x24, 0xa2, 0xde, 0x76, 0xf6, 0xd7,
+  0x93, 0x68, 0x1f, 0xb4, 0xe8, 0x57, 0x6d, 0xfb, 0x60, 0xba, 0xe0, 0x7e,
+  0x28, 0xfb, 0x8b, 0x2e, 0x41, 0x73, 0x6c, 0xa4, 0x14, 0x9f, 0x32, 0xda,
+  0xfc, 0xba, 0x7d, 0x1e, 0xf6, 0x03, 0x87, 0xe9, 0x7d, 0x5d, 0xcf, 0x68,
+  0xb3, 0xe7, 0x57, 0xf7, 0xa6, 0x53, 0xf5, 0xca, 0x6c, 0x65, 0xff, 0x2e,
+  0xe5, 0xe7, 0x74, 0xc1, 0x3c, 0xcb, 0x72, 0xb3, 0x86, 0xf3, 0x6f, 0x91,
+  0x51, 0xc1, 0x63, 0x26, 0x62, 0x7c, 0x60, 0xc6, 0xc0, 0xd3, 0x88, 0xcf,
+  0xbb, 0x80, 0x98, 0xc8, 0x50, 0xab, 0x37, 0x0c, 0xa9, 0x06, 0x26, 0x8c,
+  0xa6, 0x07, 0x07, 0xdf, 0x6a, 0x89, 0x1a, 0x71, 0x31, 0xe0, 0xf6, 0x84,
+  0x50, 0xaa, 0x56, 0x30, 0x21, 0x3a, 0xff, 0xef, 0x59, 0xac, 0x20, 0x70,
+  0xab, 0x55, 0x2e, 0x6d, 0x25, 0xd7, 0x54, 0x76, 0x87, 0x86, 0x5e, 0x07,
+  0xa7, 0x74, 0x2f, 0xce, 0x22, 0x3c, 0x93, 0x49, 0x88, 0x5c, 0xe0, 0xba,
+  0x02, 0x00, 0xb0, 0xba, 0xc5, 0xde, 0x22, 0x6c, 0x0b, 0x7d, 0x8b, 0xab,
+  0xaf, 0xe2, 0x17, 0xab, 0x7d, 0x91, 0x8e, 0x50, 0xa9, 0xd9, 0xb6, 0xb8,
+  0x1d, 0xd5, 0xda, 0x04, 0xb2, 0x00, 0x46, 0x24, 0xdc, 0x01, 0x13, 0xa2,
+  0xe0, 0x06, 0x46, 0x27, 0x7d, 0x68, 0xdb, 0x08, 0x09, 0x17, 0x97, 0xa6,
+  0x80, 0xa9, 0x73, 0x0d, 0xb2, 0x88, 0xb2, 0xb3, 0x95, 0xcc, 0xfd, 0x12,
+  0x99, 0x39, 0xba, 0x57, 0xad, 0xd0, 0xba, 0x74, 0x57, 0x6d, 0x5b, 0x74,
+  0xfd, 0xd3, 0x07, 0x7c, 0x85, 0x90, 0xea, 0xc8, 0xa1, 0x87, 0xee, 0xc8,
+  0xa8, 0x68, 0x90, 0x31, 0xa8, 0x94, 0xf2, 0xc6, 0xb0, 0x4a, 0x4a, 0xfd,
+  0x5e, 0x42, 0x4a, 0x80, 0x83, 0x2d, 0x9b, 0x0e, 0x48, 0x32, 0xf9, 0xc5,
+  0x56, 0xed, 0xf8, 0xea, 0x28, 0xd3, 0x68, 0x6a, 0x3d, 0xeb, 0xdb, 0x31,
+  0xee, 0x8e, 0xae, 0x46, 0x67, 0x76, 0xb0, 0x7f, 0x69, 0x21, 0x6e, 0xfb,
+  0xe0, 0xd9, 0x20, 0xf2, 0x93, 0xf7, 0x96, 0x38, 0x99, 0x23, 0x1c, 0xa8,
+  0x16, 0xea, 0x4a, 0x7c, 0x33, 0x8d, 0x0d, 0x9f, 0x5f, 0x92, 0x5c, 0xfa,
+  0x74, 0xc4, 0x99, 0x85, 0xd6, 0x34, 0x58, 0xba, 0xae, 0x35, 0x4d, 0xb0,
+  0xb2, 0x4d, 0x21, 0xe6, 0xf8, 0xc0, 0x49, 0x23, 0x42, 0xb2, 0xe8, 0x17,
+  0xf5, 0x10, 0xcb, 0x9c, 0xf2, 0x27, 0xd7, 0x8c, 0xc0, 0x33, 0x9d, 0xd7,
+  0x7f, 0xd1, 0x17, 0x11, 0xf1, 0x4f, 0x0b, 0x72, 0x3a, 0x79, 0xdc, 0xd4,
+  0xad, 0x84, 0xa7, 0x83, 0x33, 0xda, 0xad, 0x03, 0xb5, 0x95, 0x52, 0xc4,
+  0xfd, 0xda, 0x63, 0xb5, 0x66, 0xa6, 0x71, 0x67, 0xde, 0x18, 0xd9, 0x59,
+  0x2f, 0x2b, 0xae, 0xe5, 0xfa, 0xb0, 0xba, 0xa7, 0x1e, 0x1c, 0xdb, 0x1e,
+  0xd1, 0x15, 0xb5, 0xe9, 0xb6, 0x57, 0xf4, 0xca, 0x0e, 0x11, 0x93, 0xab,
+  0xdd, 0x52, 0xcc, 0xf8, 0x6f, 0xd4, 0x2b, 0x6e, 0xed, 0x31, 0x7d, 0xfa,
+  0x67, 0xef, 0xb5, 0xee, 0x4d, 0xc6, 0x94, 0xc2, 0x7a, 0xc3, 0x3c, 0x4a,
+  0xd8, 0xaf, 0xbf, 0xca, 0x5a, 0xb7, 0xd5, 0xc3, 0x67, 0x76, 0xd5, 0x55,
+  0xb6, 0x17, 0x13, 0x21, 0x24, 0x1d, 0xde, 0xa7, 0x8b, 0x85, 0x88, 0x9d,
+  0x87, 0xc7, 0xce, 0x84, 0x30, 0x5c, 0x19, 0x8b, 0xb8, 0xd9, 0xa5, 0xa6,
+  0x75, 0x53, 0x96, 0x1f, 0x12, 0x81, 0x96, 0x30, 0xc0, 0x8a, 0x42, 0x99,
+  0xeb, 0x9b, 0xe3, 0x1a, 0xca, 0xfc, 0x38, 0xb1, 0xe2, 0x8e, 0x46, 0xdf,
+  0xec, 0x64, 0xcd, 0xc4, 0xca, 0xc0, 0x1d, 0x07, 0x9a, 0x62, 0xb3, 0xec,
+  0xa1, 0x9b, 0x09, 0x42, 0x18, 0x25, 0x32, 0x68, 0x1e, 0xac, 0x8b, 0xf1,
+  0xb1, 0xd3, 0xd0, 0xb6, 0x50, 0x7e, 0xa7, 0x81, 0x12, 0xa1, 0x5e, 0x62,
+  0xbf, 0xc4, 0x65, 0x58, 0xb3, 0x56, 0xdf, 0xb7, 0x1e, 0xda, 0xe7, 0x62,
+  0xdc, 0xb4, 0xc7, 0x18, 0x1d, 0x11, 0xd9, 0xdd, 0x84, 0x96, 0x58, 0x2e,
+  0xfe, 0x0f, 0x2c, 0x2c, 0xb2, 0x08, 0x5c, 0x2c, 0x0e, 0xe8, 0x92, 0x87,
+  0xbb, 0xbc, 0x20, 0x13, 0x97, 0xad, 0xd8, 0x87, 0xfb, 0xac, 0x65, 0xe9,
+  0x49, 0xe1, 0x8d, 0x74, 0x1b, 0xbd, 0x66, 0x5c, 0xed, 0x2f, 0xe8, 0x33,
+  0x67, 0xd2, 0x49, 0x1f, 0xd0, 0x65, 0xb8, 0x0c, 0x6d, 0x3d, 0x72, 0xa3,
+  0x55, 0x5c, 0xe7, 0xc5, 0x63, 0x7c, 0x3f, 0x16, 0xe2, 0xc0, 0x98, 0x81,
+  0x6c, 0x60, 0x5b, 0x95, 0x2c, 0x2e, 0x8e, 0x62, 0x50, 0xe2, 0xfe, 0x83,
+  0x62, 0x22, 0x15, 0x3a, 0x3f, 0x12, 0x15, 0x9e, 0x3f, 0x74, 0xa2, 0x1e,
+  0x0b, 0x02, 0x41, 0xe4, 0x93, 0x25, 0xa5, 0x30, 0x47, 0x0a, 0xbe, 0x05,
+  0x5e, 0x0e, 0xa3, 0x03, 0x70, 0xea, 0xc2, 0x2d, 0xc5, 0x34, 0x57, 0xac,
+  0x85, 0xd5, 0xf5, 0x56, 0x6c, 0x10, 0xaa, 0x06, 0x8e, 0x79, 0x96, 0xb2,
+  0xea, 0xfa, 0xfc, 0x83, 0x62, 0xca, 0x88, 0xb8, 0x45, 0xed, 0xa5, 0xc3,
+  0x62, 0x9b, 0xf0, 0x46, 0xed, 0xeb, 0xe1, 0xe8, 0x27, 0x8f, 0xde, 0x0a,
+  0x42, 0xeb, 0x25, 0x73, 0xeb, 0xd1, 0x93, 0x91, 0x55, 0xc4, 0x44, 0x85,
+  0xf4, 0xcb, 0x74, 0xa2, 0xea, 0xfe, 0x43, 0xbd, 0x4b, 0xb9, 0xd0, 0x43,
+  0x7b, 0x12, 0x18, 0x83, 0xd1, 0xba, 0x64, 0x18, 0x5a, 0xf2, 0x18, 0x11,
+  0xcf, 0xd9, 0xcd, 0x0c, 0x0d, 0xd6, 0xac, 0x28, 0x7f, 0xbe, 0xea, 0xe1,
+  0xe3, 0xb5, 0xd2, 0xa8, 0x91, 0x86, 0xbe, 0xa2, 0xe7, 0x8f, 0x3f, 0x3e,
+  0xbf, 0x8f, 0x88, 0x63, 0x8c, 0x0f, 0x69, 0x2a, 0x91, 0xc3, 0x33, 0xce,
+  0x1e, 0x6b, 0x20, 0x13, 0x73, 0x5e, 0xe7, 0x18, 0x75, 0x05, 0x84, 0x22,
+  0xda, 0xc2, 0xf2, 0xf5, 0x11, 0xcd, 0x40, 0x56, 0xa0, 0x85, 0xfe, 0x25,
+  0x1a, 0x4f, 0x26, 0xf2, 0x24, 0x0b, 0x73, 0x46, 0xc7, 0x87, 0xc3, 0x02,
+  0x0f, 0x7a, 0x9c, 0xa8, 0x4e, 0x66, 0x74, 0x09, 0x44, 0x57, 0x6c, 0xe9,
+  0x6f, 0xe1, 0x3c, 0x6b, 0x12, 0xab, 0x64, 0x95, 0x03, 0x9e, 0xf8, 0x98,
+  0x6d, 0x44, 0xde, 0xb0, 0xc8, 0x69, 0x05, 0x3d, 0xaa, 0xaa, 0xea, 0xfc,
+  0x65, 0x9b, 0x6e, 0x01, 0x8f, 0x1a, 0xa5, 0x3d, 0x81, 0x09, 0x90, 0x0c,
+  0x7e, 0xe5, 0x3d, 0x80, 0x6d, 0x42, 0x5a, 0xc6, 0xe0, 0x21, 0x5f, 0xac,
+  0x7a, 0xad, 0x09, 0x80, 0x87, 0x54, 0xdc, 0xd9, 0xd4, 0xab, 0xef, 0x27,
+  0x86, 0xaa, 0x25, 0xf4, 0x3c, 0x58, 0xdf, 0x9c, 0x52, 0x01, 0xff, 0x8e,
+  0x24, 0x70, 0x1f, 0x53, 0x73, 0x0a, 0xa2, 0xa0, 0xf4, 0x3a, 0xc5, 0x45,
+  0x64, 0x93, 0x40, 0xad, 0x53, 0xbd, 0x5d, 0x55, 0xaa, 0x5d, 0x34, 0xa2,
+  0x6e, 0xca, 0x20, 0x6f, 0x87, 0x94, 0x3d, 0x8a, 0x39, 0xe2, 0xb6, 0x30,
+  0x56, 0x56, 0xca, 0xe9, 0x77, 0x85, 0x11, 0x09, 0x0d, 0x7b, 0x9f, 0xc5,
+  0x57, 0x4f, 0x5d, 0xc9, 0xc7, 0xcb, 0x06, 0x61, 0x6a, 0x47, 0x11, 0x16,
+  0x01, 0xa5, 0x4b, 0x62, 0x18, 0xbe, 0x66, 0xfd, 0x9f, 0x1f, 0xa7, 0xd7,
+  0xc3, 0xb2, 0xca, 0xe9, 0xc6, 0x01, 0xe6, 0x4e, 0x5b, 0xa3, 0xad, 0xdf,
+  0x87, 0x3c, 0x21, 0x9b, 0x22, 0xd6, 0x9c, 0x44, 0x5e, 0x12, 0xe5, 0xfb,
+  0x6a, 0xb7, 0x3b, 0xc7, 0x66, 0x45, 0x00, 0xc6, 0xb6, 0xe9, 0xaa, 0x87,
+  0xc5, 0x22, 0x94, 0x92, 0x51, 0x93, 0xb8, 0x72, 0x4a, 0x8a, 0x19, 0xb0,
+  0x43, 0x76, 0x63, 0xa5, 0xd8, 0xd8, 0x5d, 0x5a, 0x21, 0x37, 0x34, 0xf0,
+  0x50, 0xe4, 0x75, 0xbd, 0xc4, 0x82, 0xbd, 0x3e, 0x39, 0x3d, 0xb6, 0xa0,
+  0xa0, 0xff, 0xbd, 0x33, 0xa4, 0x09, 0xaf, 0x26, 0x01, 0x04, 0x8a, 0x93,
+  0xb2, 0xbc, 0x0c, 0x3b, 0xc9, 0xda, 0xfa, 0xb6, 0xcf, 0xa5, 0x67, 0xf0,
+  0xe3, 0x56, 0xca, 0xd6, 0xf1, 0xdb, 0xef, 0x4e, 0x2e, 0xce, 0xde, 0xbe,
+  0x39, 0x7e, 0x6b, 0xbd, 0xbd, 0x74, 0x28, 0x62, 0xfc, 0xb1, 0x75, 0x18,
+  0xf4, 0xcd, 0x29, 0x5e, 0x40, 0x24, 0x86, 0xa8, 0x99, 0x45, 0x54, 0x1b,
+  0x8b, 0x85, 0xfc, 0x6b, 0xe8, 0x37, 0xe7, 0x3d, 0xa4, 0x1e, 0x5f, 0x8a,
+  0xc3, 0x2f, 0xc8, 0xde, 0x9f, 0x52, 0xe8, 0x6d, 0xc8, 0x3e, 0x62, 0x5b,
+  0xba, 0x8b, 0x28, 0x6c, 0x3f, 0x4e, 0x32, 0x29, 0x5d, 0x4a, 0x09, 0x1a,
+  0x1b, 0x76, 0x4a, 0x38, 0x4a, 0xe4, 0x82, 0x69, 0xad, 0x4e, 0xb8, 0xcd,
+  0xfd, 0x8e, 0x93, 0x06, 0xe3, 0x5c, 0xb8, 0x0c, 0x00, 0x6f, 0x5c, 0xe9,
+  0x4f, 0xce, 0xec, 0x54, 0xe7, 0xbc, 0xd2, 0x57, 0x7b, 0x10, 0x3a, 0x97,
+  0x71, 0xeb, 0x57, 0x19, 0xeb, 0xc6, 0xfd, 0xbc, 0x51, 0xfc, 0xa8, 0x2e,
+  0x84, 0x83, 0x9d, 0x9d, 0x9f, 0x51, 0xe0, 0xee, 0x0b, 0xa9, 0x70, 0x17,
+  0x12, 0xa2, 0xd5, 0x5e, 0x47, 0x44, 0xe4, 0x7a, 0x29, 0x3c, 0xb4, 0x6f,
+  0xed, 0x74, 0xc2, 0x39, 0xf8, 0xfe, 0xfc, 0xe2, 0xec, 0x87, 0xbf, 0xfe,
+  0xc6, 0x9f, 0xf0, 0xb0, 0x3a, 0x3f, 0x12, 0x84, 0x4d, 0x1b, 0xff, 0xf9,
+  0x57, 0x7d, 0x6d, 0xed, 0xe7, 0xda, 0xed, 0xf7, 0xdb, 0x75, 0x58, 0x83,
+  0x04, 0x25, 0x64, 0x43, 0x32, 0xed, 0xbc, 0xe6, 0x46, 0x3a, 0xab, 0xd7,
+  0x02, 0x68, 0xf8, 0x86, 0xab, 0x7d, 0xc2, 0x07, 0xa8, 0xbb, 0x5d, 0x37,
+  0x1d, 0xc8, 0x1e, 0x90, 0xa2, 0xe7, 0x00, 0x90, 0x9a, 0xa6, 0x49, 0xa9,
+  0x98, 0x9c, 0xac, 0x09, 0x40, 0x9f, 0x9d, 0x8f, 0xc3, 0xd3, 0xd3, 0x5f,
+  0x3f, 0x09, 0x5a, 0xa8, 0xb0, 0x3d, 0x0d, 0xa8, 0x13, 0x66, 0x07, 0x34,
+  0xb0, 0x5a, 0xaa, 0x1e, 0x81, 0x75, 0xbc, 0x74, 0x6f, 0xcf, 0xa4, 0x37,
+  0x2f, 0xa0, 0x1e, 0x0f, 0xea, 0xcc, 0x28, 0xb5, 0x54, 0x97, 0x39, 0x99,
+  0x11, 0x26, 0xc6, 0x98, 0xdb, 0xd4, 0xb1, 0xa0, 0x1a, 0x98, 0xff, 0x4b,
+  0x06, 0xa3, 0xf1, 0x3c, 0x72, 0x2e, 0x11, 0xd0, 0xde, 0xa5, 0x25, 0xf8,
+  0xe0, 0x42, 0x85, 0x52, 0xb1, 0xf2, 0x2a, 0x89, 0x54, 0x42, 0xc3, 0x8d,
+  0x40, 0xd7, 0x6c, 0x95, 0xd7, 0x1f, 0x00, 0x85, 0xa7, 0x83, 0x09, 0x65,
+  0x57, 0xf3, 0x60, 0x49, 0xd7, 0x45, 0x57, 0x56, 0xf0, 0x89, 0x93, 0x6f,
+  0xec, 0x09, 0x51, 0x68, 0xf1, 0x9d, 0x12, 0x3d, 0xa9, 0x5a, 0x88, 0xc8,
+  0xed, 0x27, 0x24, 0x93, 0x77, 0x04, 0xe5, 0x95, 0xcd, 0xa1, 0xf1, 0x8f,
+  0xa7, 0x0b, 0xa5, 0x72, 0xf1, 0x15, 0xf2, 0xec, 0xea, 0xe4, 0xbd, 0x64,
+  0x95, 0x12, 0x19, 0xe6, 0x41, 0xa2, 0xbc, 0xe4, 0xba, 0xc8, 0xdd, 0x3d,
+  0xf8, 0x98, 0x68, 0xaa, 0x3b, 0x4f, 0x89, 0x9f, 0x0f, 0xa3, 0xbf, 0x79,
+  0x4c, 0x73, 0x66, 0x37, 0xc2, 0xe5, 0x40, 0xa1, 0x71, 0xd9, 0x1c, 0xe6,
+  0x0f, 0x02, 0x20, 0x36, 0xb2, 0x35, 0x81, 0x12, 0xcd, 0x39, 0x1d, 0xbc,
+  0xaf, 0x3a, 0x7b, 0x00, 0x85, 0x08, 0x47, 0xe0, 0x3e, 0xf1, 0x70, 0x97,
+  0x23, 0xd1, 0x39, 0xf3, 0x18, 0xb9, 0x40, 0x99, 0xff, 0xc0, 0x6f, 0xcf,
+  0xf5, 0x97, 0x55, 0x43, 0xe9, 0x2b, 0x7a, 0x2a, 0x5b, 0x25, 0x16, 0x04,
+  0x31, 0xeb, 0xcd, 0x3b, 0xd4, 0xfc, 0xf7, 0xf2, 0xec, 0xe8, 0xec, 0xd4,
+  0xfc, 0xe5, 0xf8, 0xf5, 0xc9, 0x0f, 0xee, 0x12, 0x93, 0x0d, 0x60, 0x33,
+  0x51, 0x38, 0x0c, 0xa8, 0x85, 0x2b, 0x7d, 0xe9, 0xc1, 0x48, 0xa6, 0x80,
+  0xfd, 0xa2, 0xcd, 0xdc, 0xe6, 0x1d, 0x4b, 0xa9, 0x3d, 0xd9, 0xaa, 0x23,
+  0x29, 0xd4, 0x1b, 0xa4, 0xf4, 0x71, 0xab, 0x16, 0x39, 0xed, 0x76, 0xe6,
+  0x49, 0xeb, 0x44, 0x42, 0x11, 0xf0, 0x2f, 0xba, 0xf6, 0x59, 0xe6, 0x4e,
+  0x21, 0xa4, 0x9c, 0x5f, 0x59, 0xed, 0xdf, 0xaf, 0x99, 0xa7, 0x19, 0x14,
+  0x42, 0xc6, 0x4c, 0xd1, 0x55, 0x47, 0xd3, 0x47, 0x4a, 0x59, 0xdf, 0x1b,
+  0xa4, 0xea, 0x67, 0x4d, 0x95, 0xe1, 0x1c, 0x03, 0xa7, 0xd1, 0xca, 0xf2,
+  0xee, 0x00, 0x0d, 0xe9, 0x56, 0x75, 0xcd, 0xb5, 0xc7, 0x24, 0x13, 0x20,
+  0x78, 0x20, 0xc4, 0x89, 0x51, 0xfc, 0xdb, 0x41, 0x4e, 0xb8, 0xde, 0xa3,
+  0x99, 0xab, 0x68, 0x7a, 0x50, 0xce, 0xf7, 0x22, 0xb1, 0xd1, 0xdd, 0xa6,
+  0x48, 0xc6, 0xa0, 0x22, 0xa5, 0x52, 0x24, 0xb2, 0xd3, 0x46, 0xfa, 0xab,
+  0x1a, 0x49, 0xdb, 0xad, 0x3c, 0xfb, 0x35, 0x8d, 0x3c, 0xeb, 0xb4, 0x71,
+  0xf3, 0xab, 0x1a, 0xb1, 0x95, 0xa2, 0x8d, 0x2a, 0xf4, 0xc3, 0xc9, 0x65,
+  0x72, 0x74, 0xf6, 0xca, 0xed, 0xd1, 0x4b, 0x0b, 0x77, 0x4c, 0x93, 0xf1,
+  0xb2, 0x30, 0xab, 0x48, 0x3c, 0xdc, 0xa8, 0x2e, 0x45, 0xcd, 0x30, 0x08,
+  0x92, 0xc3, 0xf2, 0x4a, 0xf0, 0x60, 0xbe, 0x94, 0xe3, 0x47, 0x15, 0x47,
+  0xdb, 0x7d, 0x92, 0x3c, 0x79, 0x7c, 0x4e, 0x74, 0x11, 0xd7, 0x8e, 0xe6,
+  0x8f, 0x76, 0x36, 0xb1, 0x06, 0xa5, 0x95, 0x26, 0x62, 0x8d, 0x53, 0x22,
+  0x85, 0x28, 0x38, 0xa3, 0x88, 0xa0, 0xdc, 0x2d, 0xa6, 0xc6, 0x0d, 0x3f,
+  0xe3, 0xd4, 0x27, 0x6c, 0x34, 0x2a, 0x53, 0xde, 0x48, 0x6f, 0x5a, 0x08,
+  0xa3, 0x3d, 0x45, 0xc8, 0xb6, 0x76, 0x8c, 0xd4, 0x37, 0x80, 0x91, 0x43,
+  0x50, 0x48, 0x10, 0xc9, 0xe0, 0x3c, 0x92, 0x2e, 0x54, 0x38, 0xa4, 0x2b,
+  0x57, 0xfe, 0x0a, 0xae, 0x24, 0xdb, 0x84, 0xfd, 0xce, 0x3e, 0xff, 0xf1,
+  0x3a, 0x45, 0xa9, 0x70, 0x73, 0xfe, 0x04, 0x6f, 0x92, 0xff, 0xc3, 0xd3,
+  0xcb, 0x9e, 0xd8, 0x6b, 0xd8, 0x8c, 0x7c, 0x86, 0x9a, 0x5a, 0x53, 0x86,
+  0x16, 0xd6, 0xf7, 0x45, 0x93, 0x7e, 0x84, 0x1d, 0x46, 0x4a, 0xb3, 0xd0,
+  0x62, 0xb8, 0x37, 0x9f, 0xca, 0x65, 0x9c, 0x58, 0xfe, 0x0d, 0x9c, 0x3f,
+  0xcd, 0xee, 0xf1, 0x20, 0x04, 0x62, 0xae, 0x9a, 0x1e, 0x68, 0x76, 0x21,
+  0x57, 0x99, 0xac, 0xa9, 0xce, 0xd7, 0x46, 0x34, 0xbc, 0x6b, 0x3f, 0xab,
+  0x89, 0x8a, 0x65, 0x25, 0x70, 0x04, 0x57, 0xaa, 0xc2, 0x11, 0x27, 0x50,
+  0x75, 0x6e, 0x9e, 0xb4, 0xc1, 0x0a, 0x5e, 0xf7, 0x32, 0xe1, 0xfc, 0x25,
+  0xc9, 0x00, 0x12, 0x9d, 0x73, 0x5a, 0x62, 0x26, 0xfb, 0x00, 0xd8, 0x51,
+  0xd5, 0x41, 0xf3, 0x8b, 0x7b, 0x2e, 0x92, 0x91, 0x16, 0x48, 0xd4, 0xe9,
+  0xe2, 0x05, 0x75, 0x61, 0x24, 0x8b, 0xc1, 0xa5, 0x0c, 0x3c, 0xe3, 0x3f,
+  0x8e, 0xf4, 0xee, 0xd6, 0xfa, 0xc7, 0x7e, 0xfd, 0x77, 0xa5, 0x20, 0x12,
+  0xa9, 0xc5, 0x45, 0x91, 0x27, 0x88, 0x47, 0x62, 0xac, 0x21, 0x27, 0x81,
+  0xb4, 0xe2, 0x19, 0x89, 0xcf, 0x57, 0x7c, 0x87, 0x59, 0x32, 0x2e, 0x2d,
+  0x5b, 0x47, 0xd7, 0xab, 0x4c, 0xed, 0x87, 0xad, 0x7d, 0xd2, 0xdd, 0x22,
+  0xea, 0xe1, 0x25, 0x2e, 0xb5, 0xd2, 0x8f, 0xf5, 0x7c, 0x2a, 0xd6, 0x68,
+  0x46, 0x59, 0x3f, 0xa2, 0x3b, 0x55, 0xd9, 0x82, 0x4a, 0x37, 0x5f, 0xba,
+  0x12, 0x72, 0x08, 0x28, 0xc1, 0xa2, 0xc4, 0x3c, 0x4f, 0xb4, 0x97, 0x46,
+  0x21, 0xf2, 0x8d, 0x81, 0xcf, 0xe4, 0xb3, 0x94, 0x93, 0xc2, 0x57, 0x1a,
+  0x61, 0x2b, 0x8b, 0xdc, 0x6e, 0x3d, 0x29, 0x48, 0x87, 0x1f, 0x11, 0x06,
+  0xca, 0x08, 0xfc, 0xd2, 0xfe, 0x5b, 0xde, 0x08, 0xc8, 0x83, 0x3a, 0xee,
+  0x44, 0x1a, 0xed, 0xb2, 0xe2, 0xac, 0x37, 0x47, 0x98, 0x05, 0x7c, 0x69,
+  0x5a, 0x34, 0x02, 0x11, 0xaa, 0x88, 0xe5, 0xc8, 0x2c, 0xcf, 0x9b, 0x10,
+  0x58, 0x52, 0x5e, 0x35, 0x42, 0xa7, 0xc2, 0xdc, 0xfb, 0x3c, 0x3f, 0x37,
+  0x69, 0x71, 0x9d, 0xb1, 0xb2, 0xe5, 0x71, 0x7e, 0x71, 0xdd, 0x06, 0xbe,
+  0x61, 0xcc, 0xb1, 0x87, 0x99, 0x1f, 0xab, 0x52, 0xde, 0x61, 0x92, 0xdd,
+  0xdb, 0xb5, 0xf3, 0x40, 0x83, 0x5a, 0x34, 0x80, 0x77, 0xd3, 0x2c, 0x7c,
+  0x0f, 0x92, 0xa7, 0xbb, 0x14, 0xe2, 0xc4, 0x16, 0xfb, 0x73, 0x3a, 0xab,
+  0xf5, 0xc4, 0x53, 0x52, 0x47, 0x08, 0xa6, 0x24, 0x45, 0xbb, 0xa0, 0xe8,
+  0x38, 0x5d, 0xb1, 0x8c, 0x06, 0xe3, 0x04, 0x21, 0xf1, 0x4e, 0xf4, 0x61,
+  0x89, 0x41, 0x00, 0x5a, 0xdc, 0x14, 0xd6, 0x8e, 0xa0, 0xe5, 0x2b, 0x6c,
+  0x72, 0xa2, 0x02, 0xf1, 0xa2, 0xbc, 0x04, 0x22, 0x67, 0xee, 0x49, 0x6f,
+  0x3c, 0x7b, 0x76, 0x3c, 0x77, 0xd8, 0x28, 0xe7, 0x87, 0xa3, 0x91, 0x6e,
+  0x93, 0xa3, 0x70, 0x47, 0x48, 0x0c, 0x01, 0x44, 0x05, 0x92, 0x65, 0x18,
+  0xb1, 0xe2, 0xa5, 0x91, 0x4e, 0xf0, 0x71, 0x8f, 0xc5, 0xdb, 0x2b, 0x96,
+  0xd1, 0x09, 0x88, 0x3d, 0xc4, 0x8f, 0x84, 0x7d, 0xa5, 0x23, 0xbe, 0x5b,
+  0x3f, 0x93, 0xf1, 0x42, 0xb2, 0x98, 0x56, 0xcc, 0x33, 0xf2, 0xf9, 0x54,
+  0xdc, 0x93, 0x33, 0xd0, 0x08, 0xa0, 0x76, 0x79, 0xc2, 0xbd, 0x27, 0xe1,
+  0xa0, 0xbf, 0xe3, 0x51, 0xf5, 0xff, 0xa9, 0x41, 0x7f, 0x17, 0x19, 0xf4,
+  0x53, 0x77, 0x70, 0xf8, 0x63, 0xc9, 0xfe, 0xfe, 0x27, 0x0a, 0xab, 0x66,
+  0x47, 0xcd, 0x2c, 0x71, 0x1f, 0xf4, 0xbe, 0x68, 0x9e, 0x1b, 0x00, 0x18,
+  0x1c, 0x7e, 0xcb, 0x3b, 0xbc, 0xde, 0xa7, 0x9e, 0xd9, 0x4f, 0x4d, 0x52,
+  0x58, 0x23, 0x46, 0xd3, 0x64, 0x29, 0x13, 0x08, 0x1f, 0xa5, 0xe9, 0x21,
+  0x34, 0xc4, 0x1d, 0xe1, 0x2a, 0x9a, 0x55, 0x60, 0x1e, 0xed, 0x85, 0xf7,
+  0x9d, 0xe7, 0xd6, 0x90, 0xde, 0xd9, 0xe7, 0x3d, 0x49, 0x65, 0x0b, 0xa4,
+  0x06, 0x2c, 0x76, 0xe6, 0x34, 0x6b, 0xcc, 0x9a, 0x38, 0x1f, 0x10, 0x27,
+  0xad, 0x5c, 0x55, 0x29, 0xe8, 0x2b, 0x51, 0x77, 0x76, 0xb8, 0x82, 0x23,
+  0x95, 0xd5, 0xe8, 0x94, 0x7a, 0x5f, 0x10, 0x6e, 0x0f, 0x6a, 0x81, 0x38,
+  0x4e, 0xc8, 0x13, 0x87, 0x2a, 0xbf, 0x57, 0xd6, 0x59, 0xa7, 0x95, 0x67,
+  0xfb, 0xc1, 0x0c, 0xf1, 0x20, 0xf9, 0xc8, 0x88, 0xca, 0x10, 0xa7, 0xdb,
+  0xd9, 0xfb, 0xc4, 0x2d, 0x91, 0x5b, 0x07, 0x94, 0x4a, 0xe6, 0x3c, 0xfb,
+  0xa1, 0x27, 0xbd, 0xad, 0x3c, 0x51, 0xcf, 0xb0, 0x70, 0xab, 0x07, 0xfb,
+  0x52, 0x5e, 0x75, 0x5f, 0x61, 0x79, 0x7c, 0x4e, 0xe2, 0x4e, 0x78, 0x0c,
+  0x87, 0xc9, 0x19, 0x3c, 0x31, 0x2d, 0xe6, 0x56, 0xc6, 0xe8, 0xa7, 0x2e,
+  0xef, 0xaa, 0xbd, 0x75, 0x3f, 0x73, 0x6b, 0xac, 0x5d, 0xd2, 0xb0, 0xf8,
+  0x8e, 0x8a, 0x59, 0x7b, 0xa5, 0xa8, 0xbb, 0x31, 0x4b, 0x2e, 0x8e, 0x2f,
+  0x2f, 0x00, 0xeb, 0x81, 0x08, 0xe8, 0xde, 0xb9, 0x46, 0x24, 0x6c, 0x5b,
+  0xbe, 0x3f, 0x11, 0x68, 0x4e, 0x29, 0x71, 0x22, 0x82, 0x49, 0x61, 0xec,
+  0x8a, 0xf3, 0x3f, 0xf5, 0x3d, 0xc6, 0xa5, 0x9b, 0x35, 0xe7, 0x29, 0x77,
+  0x21, 0xb1, 0x36, 0x5d, 0xcd, 0xfe, 0xbe, 0xc3, 0x27, 0x70, 0x21, 0x2d,
+  0xbe, 0x49, 0x2d, 0xe0, 0x54, 0xaf, 0x5e, 0x87, 0xd2, 0xd6, 0x4a, 0x0b,
+  0xf4, 0x1c, 0x43, 0x36, 0x83, 0xc0, 0xa5, 0xfd, 0xb8, 0x68, 0x01, 0xd2,
+  0x09, 0x8b, 0x15, 0xc6, 0xe7, 0x3c, 0x75, 0x33, 0x91, 0x24, 0x9a, 0xe4,
+  0xe9, 0xee, 0x6e, 0x84, 0x03, 0x22, 0x1d, 0x1b, 0xb1, 0x2a, 0xaa, 0x9d,
+  0xe0, 0xed, 0xf1, 0x16, 0x7b, 0xce, 0xa0, 0x6b, 0xd6, 0x64, 0xb7, 0x0c,
+  0xae, 0xc8, 0x56, 0xa6, 0x19, 0x53, 0x39, 0xed, 0xcd, 0x1b, 0x4b, 0x99,
+  0xef, 0x91, 0x00, 0xa0, 0x93, 0xd6, 0x11, 0x2f, 0x9c, 0x1d, 0xa0, 0x95,
+  0x9a, 0x52, 0x8f, 0xe3, 0x52, 0x5c, 0xa0, 0x41, 0xcf, 0x02, 0x09, 0xbe,
+  0xff, 0x2c, 0xdc, 0x11, 0xa3, 0xcb, 0xb3, 0x0b, 0xd9, 0x61, 0xe1, 0xe5,
+  0x2c, 0x61, 0x70, 0x7a, 0xc4, 0xb1, 0x15, 0xf4, 0x23, 0x95, 0xa2, 0x6d,
+  0x8a, 0xad, 0xa5, 0x86, 0xf3, 0xbe, 0xca, 0x32, 0xe0, 0x82, 0xd2, 0x44,
+  0x64, 0x68, 0xdf, 0x49, 0x4e, 0xad, 0xd2, 0x20, 0xea, 0xc9, 0xf4, 0x5e,
+  0xe2, 0x83, 0x76, 0xc6, 0x27, 0x98, 0x53, 0x40, 0x51, 0xf0, 0x84, 0x93,
+  0x41, 0x89, 0x46, 0x51, 0x80, 0x72, 0xb6, 0xa6, 0x4c, 0x77, 0x2f, 0xf2,
+  0x21, 0x3a, 0xb3, 0x4c, 0x97, 0x2a, 0xe4, 0x75, 0xd3, 0x78, 0xbe, 0x2b,
+  0x54, 0x37, 0x22, 0x69, 0xc1, 0x6c, 0x90, 0x02, 0x7b, 0x48, 0x29, 0x3c,
+  0xd1, 0x5d, 0xed, 0x89, 0x51, 0x95, 0xa7, 0x42, 0xb7, 0x24, 0x97, 0xa7,
+  0xda, 0x0e, 0x4e, 0xed, 0x76, 0x37, 0xff, 0xf9, 0xd9, 0xc5, 0xa5, 0xbd,
+  0xf7, 0xe9, 0xb3, 0xf8, 0x41, 0xe7, 0xfc, 0x10, 0xdb, 0x7c, 0xc2, 0xe4,
+  0xd5, 0x72, 0xbb, 0xa1, 0x62, 0xd4, 0x46, 0x34, 0x8f, 0x57, 0x16, 0x05,
+  0xed, 0x68, 0x43, 0x64, 0xc4, 0x57, 0x40, 0x72, 0x09, 0xaf, 0x95, 0x93,
+  0x39, 0xec, 0x4b, 0xa5, 0x0b, 0x27, 0x5e, 0x27, 0xc8, 0x29, 0xb9, 0x4f,
+  0xf6, 0xc2, 0xdd, 0x41, 0xde, 0xb3, 0x8b, 0x63, 0x2a, 0x1a, 0x7e, 0x79,
+  0xc3, 0x7f, 0x0b, 0xfa, 0xce, 0x99, 0x7b, 0xf2, 0xc3, 0x78, 0xe1, 0x79,
+  0xec, 0x0e, 0x8a, 0x4f, 0x19, 0xf3, 0x03, 0xed, 0xdb, 0x3c, 0x51, 0x6f,
+  0xce, 0x9e, 0x78, 0x58, 0x24, 0x88, 0x4d, 0xd9, 0x2b, 0xc0, 0xb6, 0xe0,
+  0x07, 0x3d, 0xf9, 0x4a, 0xcf, 0x28, 0x67, 0x7c, 0x24, 0x5a, 0xcc, 0xb6,
+  0x4f, 0x9e, 0xba, 0x16, 0x16, 0x74, 0x5f, 0x49, 0x03, 0x27, 0x5a, 0x96,
+  0x89, 0x7e, 0x38, 0xd0, 0xed, 0x82, 0x2b, 0x83, 0x37, 0x06, 0x3f, 0xe7,
+  0xda, 0x79, 0x66, 0xf3, 0xc1, 0x55, 0x61, 0xf0, 0xba, 0x42, 0x3f, 0x56,
+  0x08, 0x08, 0x74, 0x8e, 0xce, 0xb6, 0x7b, 0xc2, 0xbb, 0xfd, 0x2b, 0xc2,
+  0x12, 0x59, 0x50, 0x13, 0x8f, 0xdd, 0xbb, 0x5b, 0x49, 0xe5, 0xca, 0x8b,
+  0x65, 0x06, 0x4d, 0x2d, 0xad, 0x66, 0x44, 0xa3, 0x6d, 0x04, 0x49, 0xc5,
+  0x89, 0x26, 0x77, 0x41, 0xf0, 0x0b, 0xb0, 0x21, 0xf7, 0x0d, 0xb9, 0x85,
+  0x4e, 0x4e, 0x8f, 0xdd, 0x52, 0x31, 0x05, 0x37, 0x0e, 0xb2, 0xd3, 0xf8,
+  0xa9, 0x94, 0xa2, 0xbd, 0x2a, 0x86, 0xc9, 0x39, 0xd5, 0xc8, 0x83, 0xe6,
+  0x54, 0xff, 0xbb, 0x6b, 0x8d, 0x0f, 0x0a, 0x3c, 0xb1, 0xe6, 0xf2, 0x44,
+  0xd6, 0x60, 0x5e, 0x98, 0x95, 0xc5, 0x4f, 0xe8, 0xaf, 0x1e, 0x5d, 0x6c,
+  0x30, 0xdc, 0xcf, 0xdc, 0xcb, 0xb5, 0x19, 0x89, 0xb1, 0xdb, 0xbb, 0x8f,
+  0x3c, 0x95, 0x7d, 0x65, 0x8c, 0x7a, 0x34, 0x61, 0x45, 0x33, 0x9d, 0x67,
+  0x2d, 0x08, 0xcd, 0x2d, 0x5c, 0xe9, 0x33, 0x2d, 0x11, 0xee, 0x35, 0xc5,
+  0x17, 0xc2, 0xe1, 0xd8, 0x16, 0x60, 0x20, 0x08, 0x21, 0xa9, 0x73, 0xa6,
+  0xad, 0x82, 0xa4, 0xed, 0xcc, 0x22, 0x71, 0x6d, 0x38, 0x90, 0xa4, 0x25,
+  0xbd, 0x60, 0x39, 0x57, 0xba, 0x93, 0xdb, 0x29, 0xf8, 0xf7, 0x94, 0x77,
+  0xa2, 0xdd, 0x36, 0xf6, 0x0e, 0x6b, 0xf5, 0x4e, 0xb0, 0x8b, 0xc2, 0x1d,
+  0x45, 0x5e, 0x04, 0xf2, 0x0b, 0x9b, 0x1b, 0xde, 0x37, 0x01, 0x9e, 0x3e,
+  0x73, 0x4d, 0x5d, 0x81, 0xa3, 0x5b, 0x65, 0xfb, 0x61, 0x4b, 0xfe, 0x58,
+  0x82, 0xee, 0xdc, 0x3e, 0xc9, 0x96, 0x23, 0xa7, 0x70, 0x46, 0x8e, 0x94,
+  0xf7, 0x0d, 0xde, 0x0c, 0x97, 0x25, 0x91, 0x78, 0x14, 0xf7, 0x0e, 0x9a,
+  0x3b, 0xe4, 0xe8, 0x22, 0x3b, 0xa4, 0xb8, 0x06, 0x80, 0xfc, 0x46, 0x38,
+  0x94, 0x6f, 0xc4, 0x5b, 0x43, 0x55, 0xa6, 0x02, 0xea, 0xd7, 0xe5, 0x5c,
+  0x10, 0x7e, 0xde, 0x97, 0x3e, 0x15, 0xd7, 0x06, 0xd7, 0xe4, 0xb6, 0xce,
+  0x00, 0x5f, 0x90, 0x96, 0x96, 0xf0, 0xc1, 0xc6, 0xc9, 0xa7, 0x00, 0x9f,
+  0xd5, 0x96, 0xe6, 0x38, 0xc2, 0x41, 0x46, 0x97, 0xb1, 0xa8, 0xbc, 0x1a,
+  0xeb, 0x2c, 0x3d, 0x02, 0x19, 0x9a, 0x6f, 0x79, 0x8c, 0x7f, 0xb5, 0x86,
+  0x81, 0xa3, 0xca, 0xfe, 0x06, 0x75, 0x72, 0xc8, 0x17, 0x0e, 0x67, 0xdb,
+  0xf0, 0x28, 0x8b, 0x65, 0xea, 0xd9, 0xf4, 0x4f, 0x3f, 0x13, 0xbf, 0x95,
+  0xf8, 0x45, 0xb4, 0x1a, 0x65, 0x37, 0xcc, 0xf4, 0x6c, 0xcf, 0x3a, 0x01,
+  0x09, 0x50, 0x27, 0x28, 0x71, 0x1f, 0x56, 0x47, 0xbc, 0x92, 0xa3, 0x6f,
+  0x92, 0x37, 0xaf, 0x9e, 0x11, 0xb0, 0xe3, 0x3a, 0xab, 0x16, 0xc6, 0x6a,
+  0x71, 0x86, 0xf9, 0xd9, 0xb7, 0x5e, 0x63, 0xfb, 0x0e, 0x26, 0xa4, 0xf1,
+  0x7e, 0x11, 0x66, 0x62, 0x35, 0x98, 0x25, 0xa4, 0xc4, 0xc4, 0x6b, 0xcd,
+  0x31, 0x56, 0x32, 0x2c, 0xaf, 0x2c, 0x73, 0xc0, 0xb5, 0xd4, 0x11, 0x60,
+  0xcf, 0x9e, 0x38, 0x01, 0x46, 0x85, 0xd7, 0xcb, 0x24, 0x2b, 0xae, 0xc9,
+  0x38, 0x88, 0x9c, 0xa8, 0x67, 0x2c, 0x34, 0x8f, 0xf8, 0xdc, 0x93, 0x22,
+  0x1b, 0xbe, 0x06, 0x25, 0x1d, 0xe1, 0x4e, 0xef, 0xbd, 0x67, 0xbe, 0x6f,
+  0x81, 0x78, 0x07, 0x01, 0x99, 0x61, 0xb6, 0x71, 0x68, 0x29, 0xde, 0xb3,
+  0xcf, 0xed, 0xb3, 0xe4, 0x48, 0xca, 0x0b, 0xaf, 0x3a, 0xc4, 0x8a, 0x37,
+  0x44, 0x01, 0x56, 0x33, 0x41, 0x55, 0x33, 0xd6, 0x79, 0xbc, 0xb9, 0xf7,
+  0x5e, 0xf9, 0xac, 0xed, 0x3a, 0x01, 0x6d, 0xb4, 0xdd, 0x98, 0x18, 0x54,
+  0xbe, 0xb8, 0xf1, 0x0f, 0xe7, 0x73, 0xbe, 0xa5, 0xcf, 0xbb, 0x28, 0x49,
+  0x95, 0x81, 0x99, 0x9f, 0x89, 0xaf, 0x47, 0x9d, 0xb7, 0xfe, 0xd1, 0x61,
+  0xb2, 0x2a, 0x45, 0x00, 0x7b, 0xdd, 0xfb, 0xc8, 0x9e, 0x9c, 0x19, 0x2a,
+  0x93, 0x76, 0x5d, 0xe4, 0xff, 0xd0, 0xe4, 0x62, 0xba, 0x9b, 0xb5, 0xb2,
+  0x87, 0xf7, 0xf8, 0xbe, 0x08, 0x8c, 0xdb, 0x74, 0x96, 0x8b, 0x50, 0xa4,
+  0x20, 0x9a, 0x7b, 0xe0, 0x89, 0xec, 0x5a, 0x2e, 0x0c, 0x07, 0x0b, 0x00,
+  0xa5, 0x1d, 0x29, 0x84, 0x9b, 0xb5, 0x40, 0xb7, 0xcf, 0x9f, 0x8a, 0xde,
+  0xa5, 0xba, 0x31, 0xdd, 0xbc, 0x34, 0x11, 0x33, 0x30, 0x9b, 0x75, 0xc5,
+  0xf4, 0x73, 0xb9, 0xf6, 0x64, 0x29, 0x6d, 0x75, 0x0f, 0x5b, 0x29, 0x85,
+  0xfe, 0x7a, 0x97, 0x17, 0x02, 0x83, 0x0d, 0x5e, 0x7f, 0xbe, 0xc2, 0x1f,
+  0x29, 0xd5, 0xce, 0x8f, 0xb1, 0x97, 0xbc, 0xe7, 0x3f, 0x71, 0x27, 0xa1,
+  0xc5, 0x0a, 0xa7, 0x94, 0x60, 0x7d, 0xcf, 0x09, 0x61, 0xcf, 0x12, 0x3b,
+  0x52, 0xa4, 0x18, 0x74, 0x84, 0xb2, 0xf7, 0xca, 0x7e, 0x7e, 0x56, 0x92,
+  0x34, 0xf5, 0xbe, 0xc7, 0x5b, 0xea, 0x35, 0x68, 0xc0, 0x9d, 0x71, 0x50,
+  0xb4, 0x6a, 0x9b, 0xba, 0xa7, 0x3f, 0x93, 0xbd, 0xa1, 0xf7, 0xa5, 0x35,
+  0x59, 0x57, 0xbd, 0xf1, 0xc9, 0xae, 0xaf, 0xb0, 0x4e, 0x29, 0x4c, 0xc7,
+  0x49, 0xb6, 0x2b, 0x5f, 0xe0, 0x9d, 0x71, 0x32, 0xa3, 0x32, 0xa1, 0x33,
+  0x2d, 0x3e, 0xaa, 0x8c, 0x60, 0xee, 0xb1, 0xfd, 0x96, 0xd0, 0xbd, 0xf4,
+  0xd5, 0xa7, 0xe4, 0xe4, 0x95, 0xf7, 0xe0, 0x13, 0x37, 0xc0, 0x74, 0x46,
+  0xda, 0xc0, 0x3d, 0x7b, 0xab, 0x6a, 0x29, 0x7b, 0xea, 0x3d, 0xca, 0x3b,
+  0xe3, 0x6d, 0xc9, 0xdc, 0x35, 0x98, 0xfe, 0xe0, 0x19, 0xde, 0x0e, 0x47,
+  0x37, 0xe6, 0x56, 0x9b, 0x34, 0x40, 0x07, 0x16, 0x1a, 0x3a, 0xea, 0xae,
+  0xfd, 0x27, 0xcf, 0xd7, 0x3c, 0x2b, 0x97, 0x66, 0x6d, 0xaf, 0x7a, 0xef,
+  0xbd, 0x4f, 0xc2, 0x63, 0xae, 0x26, 0x81, 0x82, 0x98, 0xcd, 0x51, 0xa3,
+  0x93, 0x96, 0x6c, 0x51, 0x1e, 0xe5, 0xbf, 0xab, 0x7b, 0xb0, 0x22, 0x5a,
+  0xae, 0xfa, 0xdf, 0xfd, 0xfe, 0x7e, 0xea, 0x23, 0xa1, 0xd9, 0x37, 0x58,
+  0x65, 0x88, 0x1e, 0x4c, 0x5a, 0x3c, 0xdc, 0x0e, 0x29, 0x82, 0xd9, 0xf1,
+  0x5a, 0xe0, 0x35, 0x37, 0x7a, 0xc4, 0xb2, 0x70, 0x92, 0x83, 0x0d, 0x41,
+  0x49, 0x5c, 0x9e, 0xfa, 0xf4, 0x6d, 0x24, 0xf3, 0xc5, 0x0f, 0xe5, 0x79,
+  0x52, 0x77, 0x3b, 0xc7, 0xa0, 0xbe, 0x59, 0xb2, 0xd9, 0x6d, 0x47, 0xe4,
+  0xdc, 0x6c, 0xde, 0x6b, 0xfb, 0x4e, 0x7a, 0xa1, 0x6f, 0x50, 0x1b, 0x8f,
+  0x4c, 0x6f, 0xd9, 0x2e, 0xb7, 0xc4, 0xcc, 0xf0, 0xc2, 0xdf, 0x55, 0x25,
+  0xfd, 0x55, 0xd3, 0xed, 0xb7, 0x38, 0x29, 0x32, 0x04, 0xe9, 0x09, 0xae,
+  0xd8, 0xfb, 0x8c, 0xa8, 0x36, 0x04, 0x75, 0x31, 0xab, 0x74, 0x93, 0x4d,
+  0x3e, 0xe8, 0x91, 0x91, 0x46, 0x1c, 0x1a, 0xd9, 0x7b, 0xeb, 0xa9, 0x9d,
+  0x5a, 0x98, 0x34, 0x17, 0xc7, 0x5d, 0x2b, 0xc0, 0x3d, 0xca, 0xbb, 0xe6,
+  0xe2, 0x72, 0x74, 0x7e, 0x40, 0x7d, 0xe6, 0x78, 0x9c, 0x39, 0x10, 0x47,
+  0xa3, 0xec, 0xef, 0x92, 0x85, 0x52, 0xbb, 0xa7, 0x9f, 0xaf, 0x78, 0x7a,
+  0x24, 0xee, 0xbd, 0x93, 0x29, 0x89, 0x5f, 0xb3, 0x0e, 0xfe, 0x4b, 0x9f,
+  0x08, 0xb6, 0x4f, 0xfd, 0xfc, 0xec, 0x05, 0xa3, 0x9e, 0x41, 0x1a, 0x52,
+  0xe4, 0xdd, 0x3d, 0xfc, 0xa9, 0xb3, 0x69, 0x6e, 0x96, 0xc5, 0x07, 0xab,
+  0x2f, 0x0a, 0x1d, 0x95, 0x2e, 0xb0, 0x7b, 0xe1, 0x33, 0x3d, 0x1a, 0x9e,
+  0x37, 0xd4, 0xe2, 0x5f, 0xfa, 0xe2, 0xa5, 0xd0, 0x42, 0xa7, 0x1c, 0x48,
+  0x34, 0xf2, 0x75, 0xe9, 0xcd, 0xc1, 0x67, 0xbb, 0xf6, 0xfa, 0x15, 0x62,
+  0x8b, 0x0f, 0xd9, 0xbd, 0xdb, 0x75, 0x1c, 0xaf, 0x37, 0xea, 0x62, 0x5e,
+  0x90, 0x13, 0xc2, 0x3d, 0x62, 0x1b, 0xf8, 0xe1, 0x07, 0x96, 0xf1, 0x96,
+  0x0f, 0x49, 0xe2, 0x4c, 0xb6, 0xe6, 0x85, 0x11, 0x88, 0xac, 0x16, 0xd0,
+  0xf1, 0x42, 0x70, 0xa6, 0xca, 0x66, 0x19, 0xf1, 0xe9, 0xb1, 0x8d, 0x82,
+  0x8d, 0x3d, 0x08, 0xec, 0x3d, 0x94, 0x7d, 0xe2, 0x40, 0x25, 0x17, 0xb4,
+  0x37, 0x93, 0x57, 0x90, 0x6f, 0x4c, 0x1c, 0x55, 0x66, 0xc5, 0x0f, 0xdf,
+  0x5d, 0x7e, 0x73, 0x76, 0x31, 0x4a, 0x76, 0x28, 0x2d, 0xf5, 0xf2, 0xe2,
+  0xe4, 0xab, 0x77, 0xc6, 0xf6, 0xb7, 0x31, 0xba, 0x57, 0x69, 0x91, 0x9b,
+  0x9b, 0x63, 0xd4, 0x64, 0x85, 0x59, 0xc7, 0x6b, 0x2d, 0x4d, 0xc1, 0xe4,
+  0x9c, 0xe6, 0xae, 0x2c, 0x2b, 0x2e, 0x4f, 0x04, 0x56, 0x80, 0x9b, 0x52,
+  0x16, 0x83, 0xa9, 0xd3, 0xc8, 0xc7, 0x4c, 0x28, 0xac, 0xd2, 0xd9, 0xb5,
+  0x79, 0x27, 0xab, 0x56, 0xa1, 0x15, 0xc9, 0xe5, 0x37, 0x87, 0x6f, 0xbf,
+  0x1d, 0x29, 0x6d, 0xf9, 0xf7, 0xdf, 0x7f, 0xef, 0x43, 0x7e, 0xea, 0x83,
+  0x9d, 0x1d, 0xe8, 0x97, 0x37, 0xe9, 0xc7, 0x8f, 0xc3, 0x3a, 0xdb, 0xd8,
+  0x18, 0x1d, 0x1f, 0x27, 0x87, 0xa7, 0xa3, 0xb3, 0x0d, 0x97, 0x8c, 0xbd,
+  0xb5, 0x47, 0x24, 0x2d, 0xd7, 0x59, 0x63, 0xfe, 0xb2, 0xb1, 0x71, 0x7a,
+  0x78, 0x49, 0x96, 0xab, 0x94, 0x57, 0xa5, 0x79, 0x26, 0x62, 0x85, 0x74,
+  0x76, 0x47, 0x3c, 0x72, 0x57, 0x39, 0xd0, 0xce, 0x77, 0x5a, 0x99, 0xbd,
+  0x4b, 0xae, 0x68, 0x6e, 0x9e, 0x3b, 0xa2, 0xbb, 0x10, 0xcc, 0x12, 0x81,
+  0x31, 0xcd, 0x98, 0x94, 0x21, 0x6c, 0x23, 0x71, 0xde, 0x2b, 0xe6, 0x3b,
+  0xcf, 0xc6, 0x5c, 0x5d, 0xb7, 0xcf, 0xd0, 0x43, 0x00, 0xd0, 0x3c, 0x02,
+  0x82, 0x15, 0x43, 0x38, 0x21, 0x5e, 0xd0, 0xe4, 0xdd, 0xe8, 0xf0, 0xeb,
+  0x63, 0x7a, 0xf6, 0xeb, 0xac, 0x71, 0x53, 0xcb, 0x25, 0xe4, 0xe9, 0x2b,
+  0x6f, 0xb3, 0xa6, 0x9e, 0xa4, 0x8b, 0x6c, 0x93, 0xfa, 0x34, 0x1e, 0x08,
+  0xe3, 0xbe, 0x6b, 0x9c, 0xd5, 0x7a, 0x57, 0x28, 0xa0, 0x90, 0xe7, 0x41,
+  0xe9, 0xef, 0xb7, 0x7b, 0x71, 0x7c, 0xf8, 0xea, 0xcd, 0xb1, 0x16, 0x68,
+  0x66, 0x56, 0x4e, 0xd3, 0xe8, 0x0d, 0x95, 0xad, 0x76, 0x91, 0x0f, 0xba,
+  0xe6, 0x97, 0xa6, 0x0d, 0xf3, 0x1b, 0xaa, 0x22, 0x1d, 0xff, 0x9c, 0xab,
+  0x1f, 0x80, 0x67, 0x87, 0x57, 0xf9, 0x0e, 0xb7, 0xae, 0xdf, 0x4b, 0xed,
+  0x9c, 0x08, 0xd3, 0x88, 0x6a, 0xbe, 0xec, 0x9a, 0x80, 0x4f, 0xe3, 0xd3,
+  0xdd, 0xdd, 0xdd, 0x35, 0xe3, 0x80, 0x69, 0x20, 0x17, 0xa8, 0x19, 0xca,
+  0x01, 0x3d, 0xbe, 0xe3, 0xda, 0x77, 0x3d, 0xa6, 0xfd, 0x86, 0x75, 0xbb,
+  0x22, 0xcb, 0x1a, 0xd7, 0x6e, 0xde, 0x64, 0xf1, 0x2e, 0x4f, 0xca, 0xd2,
+  0xae, 0x40, 0x6b, 0x72, 0x50, 0x3b, 0x37, 0x6f, 0x94, 0x72, 0x0d, 0x6f,
+  0x70, 0xc7, 0x8d, 0x29, 0x03, 0x9a, 0xa9, 0xea, 0xbe, 0xdb, 0x24, 0xfd,
+  0x06, 0xc0, 0x94, 0x49, 0x33, 0x2c, 0xab, 0xeb, 0x9d, 0xf9, 0x01, 0xb4,
+  0x13, 0xf3, 0xd0, 0x6b, 0x82, 0xb9, 0x26, 0x46, 0xcb, 0xb5, 0x0c, 0x12,
+  0x35, 0x4d, 0x6c, 0x69, 0xae, 0xa5, 0x47, 0xf4, 0xeb, 0x17, 0xcc, 0x02,
+  0xb3, 0xff, 0x5c, 0xe9, 0xc8, 0xb5, 0x9e, 0x5e, 0xe4, 0x23, 0xb4, 0xff,
+  0xe0, 0x38, 0x1c, 0x1a, 0x59, 0x60, 0xbe, 0x42, 0x3c, 0x54, 0xd8, 0x22,
+  0xe6, 0xaf, 0x95, 0xd9, 0x32, 0xc3, 0xe6, 0x23, 0x44, 0xa8, 0x94, 0x0b,
+  0xe5, 0x94, 0x41, 0x8a, 0xcc, 0x2f, 0xa8, 0x34, 0x79, 0x45, 0xcc, 0xb0,
+  0xfc, 0x05, 0x73, 0x80, 0x48, 0x88, 0x5c, 0xcb, 0xc4, 0x01, 0xcf, 0x47,
+  0x0d, 0x77, 0xbf, 0x39, 0x18, 0x60, 0xff, 0xd4, 0x76, 0xb7, 0x3c, 0xe2,
+  0xe3, 0xde, 0xa0, 0x78, 0xf6, 0x0b, 0xb9, 0x71, 0xbd, 0xbd, 0x33, 0x32,
+  0xbd, 0x08, 0xbe, 0xb5, 0x74, 0x15, 0x4f, 0x6b, 0xfe, 0x9c, 0x5f, 0xd8,
+  0xc2, 0xac, 0xc6, 0x0e, 0xa0, 0x9e, 0x8f, 0xfe, 0xc6, 0xd1, 0xb9, 0xfc,
+  0x8d, 0x30, 0x71, 0xf9, 0x2d, 0x0d, 0x9e, 0xa4, 0xb5, 0xb9, 0x77, 0x49,
+  0x9c, 0xab, 0xba, 0x0a, 0x88, 0x1d, 0x2c, 0x4f, 0x54, 0xad, 0xf1, 0x4d,
+  0x87, 0x35, 0x3d, 0x3c, 0x30, 0x53, 0x43, 0xb7, 0xc3, 0xff, 0xde, 0x19,
+  0xd6, 0xf5, 0xcd, 0x4e, 0x3e, 0x7d, 0x5f, 0xd5, 0x69, 0xf2, 0xd3, 0x46,
+  0x27, 0xa3, 0xb2, 0x3b, 0x88, 0xff, 0x8d, 0x19, 0xfc, 0x45, 0x33, 0xb5,
+  0x7a, 0x14, 0xbf, 0xc7, 0x08, 0x06, 0x03, 0x6a, 0x55, 0xbf, 0xf4, 0xde,
+  0x3c, 0xf0, 0xde, 0x52, 0xfd, 0xfe, 0x8a, 0xd1, 0x45, 0x44, 0xa1, 0x19,
+  0x24, 0x33, 0x40, 0x1a, 0xd9, 0x12, 0xdf, 0xe8, 0x5a, 0xac, 0xe2, 0xc7,
+  0xfd, 0xdd, 0xdd, 0xbd, 0x83, 0xbd, 0x4f, 0x3f, 0xdb, 0x3d, 0xd8, 0xdb,
+  0xdb, 0xdb, 0x3f, 0xd8, 0x3b, 0x38, 0xd8, 0xdf, 0xfd, 0x79, 0xa7, 0xb7,
+  0x6a, 0xea, 0xde, 0x7c, 0xb5, 0xa2, 0x41, 0x33, 0xea, 0x1e, 0xd3, 0xcb,
+  0xfd, 0x64, 0x47, 0x8f, 0x51, 0x4d, 0x7b, 0x49, 0x3d, 0x1f, 0x13, 0xae,
+  0x8b, 0x0f, 0xa7, 0x3f, 0x98, 0xda, 0x28, 0xc5, 0x99, 0x37, 0xa0, 0x57,
+  0x67, 0xdf, 0xbf, 0x3d, 0x3d, 0x3b, 0x7c, 0x95, 0x5c, 0x9e, 0x25, 0x87,
+  0x70, 0xe1, 0x45, 0xe4, 0x24, 0x28, 0x22, 0x09, 0x19, 0xcd, 0x65, 0x3c,
+  0xbc, 0x72, 0x56, 0xe2, 0x6f, 0xb2, 0x10, 0x46, 0x74, 0xa2, 0xdb, 0xcf,
+  0x12, 0x26, 0x1a, 0xb5, 0x34, 0xbc, 0x69, 0xe6, 0x0f, 0xdf, 0x08, 0x8f,
+  0xf9, 0x72, 0x9f, 0x21, 0x16, 0xce, 0x0a, 0x47, 0x77, 0xf4, 0xe4, 0x4b,
+  0x59, 0x7b, 0x89, 0x4b, 0x09, 0x3c, 0xc1, 0x16, 0x61, 0xdf, 0x62, 0x00,
+  0xa6, 0x2b, 0xc1, 0xc4, 0xd5, 0xbd, 0x3a, 0xa0, 0x2f, 0x5b, 0x27, 0x47,
+  0xf0, 0x2f, 0x50, 0x77, 0x48, 0xbf, 0xdc, 0x0e, 0x06, 0x78, 0xb6, 0x72,
+  0x48, 0xe6, 0x32, 0xcf, 0x3e, 0x62, 0xd4, 0x6d, 0xd9, 0xcb, 0xfc, 0x83,
+  0x6e, 0x74, 0x60, 0x59, 0x52, 0xbf, 0x42, 0x5e, 0x69, 0x97, 0x81, 0xd4,
+  0x8c, 0x7c, 0x8e, 0xbe, 0xa3, 0x22, 0xd9, 0x7d, 0x82, 0x7e, 0xe3, 0xdf,
+  0xe3, 0x3b, 0x36, 0xeb, 0x94, 0x3b, 0xf0, 0x6e, 0x74, 0xf2, 0xf6, 0x6b,
+  0x44, 0xb8, 0xbf, 0x3f, 0xbb, 0x78, 0x35, 0x32, 0xcd, 0x1a, 0x79, 0x85,
+  0xc6, 0x2f, 0x4b, 0x92, 0x84, 0xd2, 0x2b, 0x3e, 0x97, 0xf4, 0xe9, 0xbf,
+  0xf0, 0x76, 0xea, 0xfb, 0xec, 0xf2, 0x73, 0xdf, 0x76, 0xa1, 0x12, 0x42,
+  0xf1, 0x5b, 0xc3, 0xdb, 0x8d, 0x5f, 0xce, 0xd3, 0xc9, 0x0d, 0x19, 0xdb,
+  0xbc, 0x59, 0x01, 0x99, 0xdd, 0xa1, 0x9c, 0x8e, 0x1d, 0xb2, 0xa1, 0x76,
+  0x9a, 0x12, 0xdb, 0x11, 0xad, 0x94, 0x95, 0xcf, 0x87, 0xee, 0x79, 0x5a,
+  0xcc, 0x5e, 0xbf, 0x9a, 0xa5, 0xd7, 0xf8, 0x60, 0x78, 0x0c, 0xbc, 0x8f,
+  0xc9, 0xe7, 0x1f, 0xfb, 0x49, 0xba, 0x36, 0xd0, 0xde, 0x09, 0x36, 0x00,
+  0xf2, 0x70, 0x50, 0x17, 0x49, 0x02, 0x48, 0xac, 0x40, 0xa2, 0x48, 0x1b,
+  0x41, 0xb5, 0x88, 0x69, 0xb8, 0x5b, 0xe0, 0x06, 0x65, 0x48, 0x99, 0x6d,
+  0xdb, 0xe8, 0xd8, 0x0e, 0xcd, 0x2b, 0x05, 0x46, 0xd0, 0x92, 0xe7, 0xcf,
+  0xa9, 0x1d, 0xbc, 0xd8, 0x15, 0xf5, 0xe5, 0x29, 0xa7, 0xce, 0x10, 0x88,
+  0x91, 0xe1, 0xf1, 0x84, 0x63, 0x14, 0x8d, 0xb6, 0x47, 0x24, 0xf6, 0x04,
+  0x44, 0xea, 0xe1, 0x8a, 0x83, 0x03, 0x4c, 0xc9, 0xc1, 0x5c, 0x46, 0x75,
+  0xdd, 0x98, 0xae, 0xa4, 0x54, 0x0e, 0x81, 0x61, 0x08, 0xc2, 0xb7, 0x61,
+  0x2c, 0x23, 0x4e, 0x3c, 0xe8, 0x29, 0x9c, 0x89, 0x5b, 0xc9, 0x6b, 0x66,
+  0x2d, 0xb1, 0x25, 0xa5, 0xe8, 0xf2, 0xa2, 0xaf, 0xb3, 0x0f, 0x13, 0xb3,
+  0x6e, 0xef, 0x49, 0xe7, 0x85, 0xa4, 0x3b, 0xce, 0xe8, 0xe3, 0x46, 0x80,
+  0xf3, 0xce, 0xd1, 0xd8, 0xb7, 0x2b, 0x0d, 0xda, 0x9a, 0x36, 0xa5, 0xc7,
+  0xe5, 0xe6, 0x48, 0x32, 0x3b, 0x8f, 0xaa, 0x9d, 0xc1, 0x0d, 0x40, 0xca,
+  0xec, 0x2d, 0x60, 0x71, 0xd2, 0xae, 0xc8, 0x59, 0xea, 0x6a, 0x43, 0x78,
+  0xd3, 0xc6, 0x20, 0x4a, 0xf7, 0x9e, 0x59, 0x23, 0x6a, 0x2a, 0x6f, 0xea,
+  0x6c, 0x76, 0x45, 0xa6, 0x90, 0xbd, 0x42, 0xb8, 0x38, 0xb2, 0x2b, 0x92,
+  0x21, 0x3c, 0xe0, 0xcb, 0xc2, 0x58, 0x2a, 0xa9, 0xe0, 0x73, 0x58, 0x96,
+  0x5c, 0x43, 0xac, 0xbb, 0x8a, 0xec, 0x6d, 0x19, 0xc2, 0xb1, 0xcd, 0xcf,
+  0x19, 0x80, 0x67, 0x9b, 0x6b, 0x89, 0x0e, 0x2f, 0x5b, 0x80, 0x6f, 0x1d,
+  0x9d, 0x3b, 0x9a, 0xad, 0xfb, 0x05, 0xd1, 0xf9, 0x10, 0x58, 0xc3, 0x2b,
+  0x1b, 0xa8, 0xfc, 0xba, 0x20, 0xba, 0xce, 0x3e, 0x12, 0xdb, 0xac, 0x8c,
+  0xcd, 0xd9, 0x6b, 0x56, 0xab, 0x97, 0xf1, 0x52, 0x6b, 0xf8, 0x39, 0x64,
+  0x21, 0xcd, 0x36, 0x11, 0x51, 0x91, 0xcd, 0x25, 0x88, 0x7a, 0x56, 0x03,
+  0xd5, 0xca, 0xb3, 0xb5, 0x2a, 0x49, 0x63, 0x32, 0xb7, 0x30, 0x13, 0x41,
+  0xdb, 0xea, 0xd1, 0x88, 0xa1, 0xa6, 0x6c, 0x0b, 0x42, 0x09, 0xf6, 0x3e,
+  0x8c, 0xdc, 0x1d, 0x3a, 0x17, 0x2d, 0x08, 0x6e, 0x6b, 0x94, 0xcb, 0xb1,
+  0x5b, 0x58, 0xda, 0x23, 0x00, 0xaf, 0x52, 0x93, 0x47, 0x61, 0x35, 0x35,
+  0xad, 0x35, 0xe0, 0xcd, 0x9e, 0xb0, 0x82, 0x18, 0x81, 0x82, 0xdc, 0xa5,
+  0x65, 0x6d, 0x77, 0x8e, 0x99, 0xad, 0x0f, 0x72, 0x21, 0x6e, 0x00, 0xc5,
+  0x1e, 0x8a, 0x1b, 0x91, 0xbc, 0xab, 0xe5, 0xcd, 0xc3, 0xa2, 0x26, 0xec,
+  0x92, 0x9a, 0x7e, 0xb3, 0x7b, 0x96, 0x06, 0x79, 0xb1, 0x5e, 0xe8, 0x48,
+  0x27, 0x1e, 0xf5, 0x61, 0x8c, 0x15, 0x94, 0xd3, 0x35, 0x47, 0x48, 0x1c,
+  0xaa, 0x94, 0x01, 0x19, 0x20, 0x6a, 0xe8, 0xb0, 0xae, 0xaa, 0x7f, 0xd1,
+  0xce, 0x23, 0x0e, 0x3c, 0x03, 0x49, 0x0e, 0x92, 0xaf, 0xd2, 0x3a, 0x9f,
+  0xf4, 0xa5, 0x28, 0x82, 0x14, 0x49, 0xa0, 0x37, 0x6c, 0xe1, 0x84, 0x64,
+  0x8b, 0xf9, 0x76, 0xb7, 0x87, 0xc9, 0xf7, 0x5a, 0xe5, 0xc2, 0x18, 0x91,
+  0x4c, 0xde, 0x9f, 0x4f, 0x80, 0xe3, 0xb6, 0x68, 0x10, 0x9a, 0x0f, 0xd9,
+  0x9f, 0xe2, 0x67, 0x07, 0x4b, 0x36, 0x3e, 0xe2, 0x38, 0x00, 0xb1, 0xaa,
+  0x69, 0xfd, 0xc1, 0x06, 0xb5, 0xb0, 0x56, 0x22, 0x8a, 0x90, 0x35, 0xc7,
+  0xba, 0x34, 0x1b, 0xf9, 0x02, 0x7d, 0x41, 0xc8, 0xab, 0xd0, 0xe0, 0x8b,
+  0x87, 0x8d, 0x62, 0x47, 0x6a, 0x6d, 0x21, 0x53, 0xb6, 0x0a, 0x18, 0x76,
+  0xa6, 0x15, 0x51, 0x83, 0x81, 0x99, 0x30, 0x9a, 0x1a, 0x11, 0xa0, 0x67,
+  0x97, 0xc7, 0x7f, 0x48, 0x0e, 0xbb, 0x31, 0x70, 0xba, 0x99, 0x54, 0x0c,
+  0x4b, 0xc9, 0x58, 0xbb, 0xc1, 0xd0, 0x77, 0x86, 0x98, 0x32, 0x2b, 0x66,
+  0x8a, 0xe5, 0xdf, 0x90, 0x0c, 0x59, 0xe7, 0xed, 0xad, 0x4b, 0xc9, 0x90,
+  0x40, 0x49, 0x3d, 0x5b, 0x7b, 0x0d, 0xd1, 0x81, 0x3b, 0x57, 0x85, 0x84,
+  0x49, 0xdd, 0xf3, 0x94, 0x33, 0x54, 0x3e, 0x9a, 0x83, 0xad, 0x29, 0x0a,
+  0x34, 0xcd, 0xd7, 0x37, 0x5a, 0x50, 0x90, 0x40, 0xd8, 0x04, 0x47, 0x26,
+  0x53, 0x8b, 0xa9, 0x95, 0xb9, 0xf8, 0x95, 0x57, 0xd0, 0xc4, 0xb6, 0x40,
+  0xbb, 0xff, 0x3d, 0x1d, 0xb9, 0xf7, 0x7a, 0xb1, 0xc8, 0x15, 0xc8, 0x7d,
+  0xb9, 0x62, 0x3b, 0xa8, 0xbd, 0x65, 0xf5, 0xd8, 0xf1, 0x6d, 0x76, 0xae,
+  0xf0, 0x52, 0x2c, 0x04, 0x5d, 0x01, 0x80, 0x7f, 0x20, 0xf8, 0x8d, 0x3b,
+  0x55, 0xa5, 0xa6, 0x7f, 0x31, 0x81, 0x76, 0x92, 0xee, 0x08, 0x2e, 0x98,
+  0x2c, 0xa4, 0x93, 0x0c, 0xe6, 0x37, 0xad, 0xb6, 0x53, 0x6e, 0x40, 0x54,
+  0x8b, 0x59, 0x45, 0x55, 0xf8, 0xb3, 0xa3, 0x6f, 0x47, 0xad, 0x94, 0x1f,
+  0xd3, 0x1a, 0x3e, 0xa4, 0xa5, 0x83, 0x3a, 0x1b, 0xda, 0x48, 0xc3, 0x93,
+  0xa6, 0x23, 0x9e, 0x2c, 0x9d, 0xa3, 0x87, 0x3d, 0xa6, 0xcb, 0xa6, 0xd5,
+  0x2c, 0x55, 0xd8, 0x98, 0x64, 0x1e, 0x1b, 0x6d, 0x51, 0x6e, 0x78, 0x37,
+  0x1f, 0xef, 0x9f, 0xb2, 0x56, 0x99, 0xc8, 0x6c, 0xa5, 0x5c, 0xd7, 0x60,
+  0x9c, 0x31, 0xd9, 0x10, 0x31, 0x09, 0x62, 0x15, 0xa9, 0x7f, 0x38, 0x81,
+  0xbc, 0x33, 0xe7, 0xd8, 0xdc, 0x1b, 0x6e, 0x77, 0xd3, 0x1d, 0xb4, 0x6a,
+  0x9c, 0x39, 0x17, 0x67, 0xb4, 0xae, 0x6f, 0x57, 0xae, 0xb1, 0x90, 0xea,
+  0x21, 0xa4, 0x5b, 0x69, 0xaf, 0x69, 0x75, 0xa0, 0xd9, 0x16, 0x56, 0xcf,
+  0xd2, 0x45, 0x17, 0xe1, 0xc7, 0x83, 0x24, 0x99, 0x32, 0x4d, 0xe6, 0xf7,
+  0x92, 0xc3, 0x22, 0xba, 0x01, 0x71, 0x73, 0xc0, 0x2b, 0xf1, 0xe9, 0xa7,
+  0x81, 0x2e, 0xf8, 0xd1, 0x3e, 0x7d, 0x60, 0x7e, 0xed, 0x79, 0x3f, 0x66,
+  0x84, 0x17, 0x21, 0x6f, 0x03, 0xf4, 0x50, 0xeb, 0x02, 0x89, 0x58, 0x18,
+  0x5e, 0x65, 0x2e, 0xfe, 0xa2, 0x0d, 0xb1, 0x04, 0xbb, 0xac, 0xef, 0xe4,
+  0xfe, 0x06, 0x9b, 0xd7, 0xdc, 0xd1, 0xb4, 0x66, 0xdc, 0xd1, 0x0a, 0xc3,
+  0x4c, 0xc5, 0x64, 0xb7, 0xb7, 0x9e, 0xd6, 0x6c, 0x34, 0xf7, 0x21, 0x5d,
+  0xaa, 0x64, 0x04, 0x8c, 0x4a, 0x69, 0x98, 0x26, 0x59, 0x3a, 0x63, 0x77,
+  0x47, 0x67, 0x1f, 0xd9, 0x92, 0x58, 0x4e, 0x46, 0xbc, 0x5b, 0xdd, 0x9d,
+  0x77, 0xbf, 0xa6, 0x3b, 0x87, 0xc9, 0xda, 0x54, 0x2b, 0x4c, 0x10, 0x4b,
+  0xfc, 0x5a, 0x89, 0x98, 0x4b, 0xec, 0x6a, 0xd5, 0x7b, 0x78, 0x8e, 0x50,
+  0x93, 0x66, 0xdc, 0x26, 0x69, 0x0d, 0x1d, 0x13, 0x45, 0xc9, 0x4f, 0xc3,
+  0xa8, 0xa1, 0xf6, 0xfb, 0xda, 0x95, 0xc7, 0x76, 0xf7, 0xe4, 0xca, 0xfb,
+  0x68, 0x4b, 0x33, 0xc1, 0x86, 0x97, 0xfc, 0xa8, 0xbd, 0xe1, 0xae, 0xaf,
+  0x5f, 0xd9, 0xa4, 0xc6, 0x0a, 0x49, 0x54, 0x34, 0xc5, 0x1b, 0x9e, 0x8a,
+  0x42, 0x23, 0x01, 0x68, 0xb2, 0xf3, 0x9a, 0xfc, 0x6c, 0x8f, 0xd9, 0x0d,
+  0xcc, 0x49, 0x12, 0xf6, 0x40, 0x4a, 0x72, 0xcd, 0xe6, 0x0b, 0x4e, 0xfe,
+  0x8a, 0x94, 0x54, 0xc5, 0x39, 0x7a, 0xea, 0x8e, 0xd4, 0x33, 0xbb, 0xdc,
+  0xd2, 0x47, 0xce, 0x15, 0x91, 0x22, 0x64, 0x9c, 0xae, 0x01, 0xe5, 0x33,
+  0xcb, 0xb8, 0xa5, 0x66, 0x65, 0xa2, 0xea, 0x51, 0x9b, 0x01, 0x9e, 0xf6,
+  0x33, 0x2e, 0x5b, 0x5b, 0x1d, 0x53, 0x58, 0xbf, 0x05, 0x65, 0x4c, 0xad,
+  0x12, 0x1e, 0x3b, 0x22, 0x69, 0xc0, 0x20, 0x91, 0xa1, 0xa4, 0x18, 0x9d,
+  0x6b, 0x76, 0x74, 0xd3, 0xd6, 0x52, 0xae, 0x5c, 0x17, 0x46, 0xb3, 0xea,
+  0x99, 0x69, 0x77, 0x96, 0x9b, 0x0e, 0x6d, 0x82, 0x4e, 0x47, 0xab, 0x25,
+  0x89, 0x2c, 0xd4, 0x2d, 0x6c, 0x89, 0x2d, 0xda, 0xa5, 0x88, 0x42, 0x3e,
+  0xcd, 0xae, 0xd0, 0xe5, 0x6b, 0xa0, 0x9f, 0x0c, 0xfe, 0x87, 0xcc, 0x0c,
+  0xa9, 0xe7, 0x04, 0x01, 0x03, 0xf3, 0xd1, 0xc2, 0x63, 0xbf, 0x10, 0xd4,
+  0x29, 0x04, 0x3e, 0xe1, 0x3b, 0x75, 0x1c, 0x96, 0x10, 0x5f, 0x73, 0xfd,
+  0x20, 0xff, 0x74, 0xec, 0x79, 0xd6, 0xad, 0x10, 0x25, 0xa2, 0x82, 0x9b,
+  0xdb, 0x70, 0x75, 0x54, 0x01, 0xf9, 0x0b, 0x3a, 0x6c, 0x2f, 0xb2, 0xaf,
+  0x88, 0xe2, 0xf8, 0xa8, 0x4c, 0xfd, 0x69, 0x55, 0x5b, 0x6e, 0x43, 0x7b,
+  0xca, 0x9b, 0xdf, 0xba, 0x32, 0x98, 0x78, 0x7e, 0x60, 0x5e, 0x18, 0xbc,
+  0x13, 0x77, 0xc6, 0x97, 0xfc, 0x85, 0x21, 0xc9, 0x33, 0xf9, 0xc2, 0x39,
+  0xb5, 0x65, 0x1f, 0x38, 0x90, 0x97, 0x88, 0xad, 0xbe, 0x27, 0x9e, 0x9c,
+  0xf6, 0xac, 0xf0, 0xf3, 0xca, 0x66, 0xdf, 0xa9, 0x69, 0x8b, 0x43, 0xc6,
+  0x7f, 0xe5, 0x77, 0xc5, 0x78, 0xbc, 0xa7, 0x26, 0x86, 0x9c, 0x4d, 0x21,
+  0xbe, 0x97, 0xfd, 0xbd, 0x1d, 0xee, 0x8c, 0x96, 0xa2, 0x85, 0x5e, 0x27,
+  0x5b, 0xd2, 0xe1, 0x39, 0x70, 0x10, 0x50, 0x36, 0xca, 0x0d, 0x9c, 0x72,
+  0x3f, 0x08, 0x87, 0x33, 0x17, 0x40, 0x34, 0x02, 0x65, 0x74, 0x35, 0x99,
+  0xbb, 0x96, 0x09, 0x0a, 0x4b, 0x59, 0x9f, 0x0d, 0xb7, 0x40, 0x7d, 0xab,
+  0xf2, 0x6d, 0x52, 0x51, 0x77, 0xdf, 0x6a, 0xca, 0x28, 0xa2, 0x92, 0xa2,
+  0x68, 0xec, 0x9d, 0xcd, 0x85, 0xcd, 0x6b, 0x45, 0x3d, 0x98, 0x1d, 0x7d,
+  0x71, 0xf8, 0xf6, 0xeb, 0x63, 0x68, 0x02, 0x90, 0xed, 0x74, 0x40, 0x73,
+  0xda, 0xed, 0xd3, 0xe5, 0x04, 0xa6, 0x90, 0x99, 0x31, 0x40, 0xd8, 0xea,
+  0xa1, 0xa4, 0x4a, 0x73, 0x62, 0x4a, 0x2a, 0x9b, 0x17, 0xcb, 0x2d, 0xc0,
+  0xb4, 0x8d, 0x44, 0x3d, 0xaa, 0xd0, 0x20, 0x00, 0x63, 0xae, 0xd8, 0xfd,
+  0x5a, 0x2f, 0xc7, 0x0b, 0x94, 0x62, 0x81, 0x7d, 0xe6, 0xc4, 0x8c, 0xfa,
+  0x59, 0x86, 0xed, 0xb3, 0xb8, 0xa1, 0x69, 0x4b, 0xd6, 0xa6, 0xaf, 0x60,
+  0xd3, 0x0f, 0x7d, 0xaf, 0x1a, 0xf3, 0x62, 0xec, 0xed, 0xee, 0x3a, 0xca,
+  0xb2, 0xd4, 0x36, 0x18, 0x48, 0xcb, 0x2a, 0xd9, 0x1d, 0x7c, 0xf6, 0xd9,
+  0x2a, 0x41, 0x68, 0x1b, 0x05, 0x15, 0xc2, 0xb3, 0x47, 0xb7, 0x39, 0xa0,
+  0x47, 0x57, 0xb5, 0x19, 0xb1, 0x68, 0x50, 0x62, 0x4e, 0x40, 0x81, 0xb5,
+  0xd5, 0x5a, 0xc4, 0xc3, 0xc3, 0xd1, 0x1a, 0xc4, 0xc1, 0x6c, 0x69, 0x32,
+  0x4c, 0xe5, 0x46, 0x62, 0xed, 0x0f, 0x50, 0x87, 0xa8, 0x33, 0x68, 0x41,
+  0xb8, 0xc0, 0xdc, 0x86, 0x63, 0x1f, 0x35, 0x31, 0x9e, 0x01, 0xbf, 0x62,
+  0x8a, 0xae, 0xc2, 0xd1, 0xa8, 0x4a, 0xf0, 0xee, 0x9c, 0xfc, 0x7f, 0x27,
+  0x6f, 0xbf, 0x66, 0x77, 0x88, 0xb1, 0xed, 0xe1, 0x4b, 0xdf, 0xe9, 0x58,
+  0xfa, 0xef, 0xa4, 0x5a, 0x36, 0x15, 0x88, 0x22, 0x1c, 0x06, 0xd3, 0xd5,
+  0xe7, 0x85, 0x94, 0xa8, 0xb6, 0xab, 0xbf, 0xc2, 0x57, 0x79, 0x99, 0x0c,
+  0x3c, 0xe5, 0x44, 0x88, 0xc7, 0x48, 0x33, 0x99, 0xdf, 0xab, 0x65, 0x24,
+  0x5f, 0x40, 0xeb, 0x1a, 0x99, 0xb1, 0xcd, 0xb2, 0x9d, 0xcb, 0xe6, 0x39,
+  0x76, 0x50, 0xa0, 0x9b, 0x44, 0x3e, 0xc9, 0x9f, 0xc1, 0xf9, 0xee, 0x68,
+  0x22, 0x8f, 0xeb, 0x4a, 0xcb, 0xd5, 0xd9, 0x66, 0x3d, 0x26, 0xcd, 0xaa,
+  0xaf, 0xbe, 0x9f, 0xae, 0x1b, 0x92, 0xeb, 0xc9, 0xf9, 0x52, 0x9d, 0x56,
+  0x1b, 0x6c, 0xea, 0x65, 0xf9, 0xcf, 0xf7, 0x73, 0x4d, 0x0f, 0xe9, 0xa0,
+  0xd2, 0x4d, 0x55, 0x4c, 0x9d, 0x4f, 0x43, 0x7a, 0x1c, 0x0d, 0x84, 0x5c,
+  0xf2, 0xfb, 0xfc, 0xe9, 0x34, 0xfe, 0x39, 0x7e, 0x5f, 0xa7, 0x26, 0x72,
+  0x00, 0x48, 0xa5, 0x15, 0x62, 0x3a, 0x9b, 0x42, 0xae, 0xb6, 0x0c, 0x69,
+  0xe1, 0x90, 0x1c, 0x79, 0x5b, 0x2d, 0xd9, 0x48, 0x84, 0xab, 0x02, 0xb4,
+  0x75, 0xb4, 0x87, 0xc0, 0x8f, 0x82, 0xcb, 0xeb, 0x03, 0x30, 0x9e, 0xe6,
+  0xf9, 0x65, 0x51, 0x64, 0x64, 0xa4, 0xa2, 0xaa, 0x64, 0xce, 0xf6, 0x42,
+  0xdf, 0x9e, 0xa2, 0x6a, 0x29, 0x35, 0x9d, 0x01, 0x34, 0x30, 0x9d, 0x4f,
+  0xeb, 0x1b, 0x54, 0x31, 0xb3, 0xae, 0xa8, 0x50, 0xbd, 0xc2, 0xe7, 0xb9,
+  0x5d, 0xd2, 0xa7, 0x58, 0x99, 0x82, 0x72, 0xdd, 0x9a, 0x8a, 0xf6, 0x0c,
+  0x6c, 0x6c, 0x90, 0x13, 0x7e, 0x87, 0x5c, 0xf1, 0xa3, 0x70, 0x02, 0xd5,
+  0x97, 0xbe, 0xd6, 0x1f, 0xef, 0x62, 0x0c, 0x0f, 0x78, 0xe6, 0x3d, 0xef,
+  0xc9, 0x63, 0x4f, 0x1c, 0xeb, 0xef, 0x91, 0xb8, 0x22, 0x0e, 0x9d, 0x27,
+  0xc8, 0xa2, 0x5b, 0xbd, 0xed, 0x4d, 0xf3, 0x6d, 0x01, 0x38, 0x7d, 0x60,
+  0x99, 0xa1, 0x66, 0x46, 0x67, 0xb9, 0x38, 0x85, 0xec, 0xfc, 0xdd, 0xa5,
+  0x50, 0x49, 0xa9, 0x78, 0xf7, 0x6b, 0x09, 0xf9, 0x45, 0x43, 0x21, 0xcd,
+  0x48, 0xb7, 0x60, 0xf3, 0x17, 0xb1, 0x6e, 0xce, 0x8a, 0xc4, 0x37, 0x31,
+  0x42, 0xee, 0x60, 0xdf, 0x66, 0xc0, 0x9c, 0x9f, 0x8d, 0x2e, 0xc9, 0x8d,
+  0x80, 0xab, 0x4f, 0xed, 0xd1, 0xef, 0x8e, 0x2f, 0xbe, 0x3a, 0x1b, 0x1d,
+  0x9b, 0xf5, 0x78, 0x75, 0xfc, 0xd5, 0x3b, 0x92, 0x5a, 0xb4, 0x3b, 0xd8,
+  0xf5, 0x4c, 0xd9, 0x31, 0xe2, 0xff, 0xa2, 0xba, 0xae, 0x48, 0x91, 0xc3,
+  0x36, 0x65, 0x3d, 0x48, 0xeb, 0x79, 0x5a, 0x15, 0x8f, 0xeb, 0x92, 0xce,
+  0x32, 0xf6, 0x55, 0xe6, 0xc8, 0x25, 0x60, 0x0a, 0x1f, 0xc9, 0x43, 0x42,
+  0x25, 0x43, 0x98, 0x97, 0x72, 0x94, 0x98, 0x46, 0xbb, 0x3e, 0x70, 0x4e,
+  0xcd, 0x5b, 0xf6, 0x4c, 0xcb, 0xe1, 0x73, 0xb5, 0x17, 0xc1, 0x27, 0x84,
+  0xcd, 0x7b, 0x64, 0xf5, 0x68, 0x61, 0xd4, 0x99, 0x95, 0x7c, 0x6b, 0xa2,
+  0x5c, 0x20, 0xb5, 0x8d, 0x7b, 0x3c, 0x6f, 0x70, 0x85, 0xb3, 0x41, 0x21,
+  0xa5, 0x0b, 0x6b, 0xde, 0xdc, 0x5c, 0xa7, 0x95, 0x60, 0x64, 0x99, 0x57,
+  0xb6, 0xb2, 0xce, 0xb8, 0x8c, 0x01, 0xdf, 0xda, 0x12, 0x0f, 0x67, 0xcc,
+  0xae, 0xd0, 0x78, 0x6d, 0x89, 0x11, 0x7c, 0x87, 0x71, 0x0a, 0x45, 0x39,
+  0xd7, 0xfe, 0xb3, 0x7c, 0xb6, 0x34, 0xf3, 0x7e, 0x1d, 0x16, 0xde, 0x3a,
+  0xb7, 0xab, 0x45, 0xcf, 0x25, 0x8f, 0x94, 0xfc, 0x1c, 0xac, 0x08, 0x48,
+  0x5a, 0x12, 0xfa, 0xdd, 0xa9, 0x68, 0xe2, 0x14, 0x14, 0x3e, 0xbb, 0x94,
+  0x16, 0xe0, 0x99, 0x90, 0xab, 0x8b, 0x05, 0xaa, 0x36, 0x2b, 0x01, 0x26,
+  0x97, 0x14, 0xc4, 0xc2, 0x55, 0x10, 0x75, 0xb4, 0xa4, 0x08, 0x09, 0xf0,
+  0xe6, 0x0b, 0xcf, 0x3b, 0xb7, 0x8e, 0xff, 0xe2, 0x8c, 0x7a, 0x81, 0x93,
+  0x8d, 0x8d, 0x8d, 0x57, 0xc7, 0x97, 0x87, 0x27, 0xa7, 0xc7, 0xaf, 0x92,
+  0x93, 0xb7, 0xaf, 0xcf, 0x2e, 0xde, 0x1c, 0x5e, 0x0a, 0x1c, 0xe3, 0x95,
+  0xf5, 0xc8, 0xb9, 0x2a, 0x6b, 0x52, 0x4b, 0xc8, 0xf3, 0xd6, 0x61, 0x0b,
+  0x9b, 0x55, 0xbc, 0x96, 0x32, 0xea, 0x3c, 0x0d, 0x59, 0x6b, 0x0e, 0x36,
+  0x12, 0x81, 0x71, 0xb8, 0xb2, 0x74, 0xa4, 0x17, 0xec, 0xd8, 0xd8, 0xfb,
+  0x50, 0xa7, 0xd3, 0xf2, 0x28, 0x11, 0xdd, 0xf0, 0xda, 0xa6, 0x6c, 0x95,
+  0x51, 0xbe, 0x13, 0x5d, 0x49, 0x60, 0xec, 0xc9, 0xc1, 0xc9, 0x0e, 0x17,
+  0xb4, 0xf6, 0x4a, 0x16, 0x68, 0xbd, 0x19, 0xb0, 0x72, 0x50, 0x3b, 0x1e,
+  0x81, 0xce, 0x55, 0x09, 0x54, 0x89, 0xdf, 0xa6, 0xa5, 0x85, 0xc1, 0x8a,
+  0x1a, 0x2d, 0x80, 0x61, 0x3c, 0xf8, 0x89, 0xbf, 0xbe, 0xc4, 0xcb, 0xb2,
+  0x41, 0xc9, 0x00, 0x8d, 0x14, 0x4b, 0x23, 0x8a, 0xa3, 0xda, 0xac, 0x94,
+  0x3d, 0xeb, 0xa0, 0x5d, 0xb2, 0x02, 0x5b, 0xa3, 0x73, 0xc2, 0x55, 0xeb,
+  0x37, 0xb5, 0x65, 0xe3, 0xf5, 0x46, 0x63, 0x1a, 0x9c, 0x08, 0x71, 0x32,
+  0xcd, 0xc5, 0xf6, 0x06, 0x73, 0xeb, 0x17, 0x4a, 0x59, 0x67, 0x91, 0xa0,
+  0xce, 0xe2, 0xcf, 0x77, 0xbc, 0xc2, 0x8f, 0x38, 0x6d, 0xee, 0xdc, 0x2a,
+  0xd1, 0xf5, 0xe0, 0x95, 0x79, 0x68, 0xba, 0x9c, 0x2f, 0xb4, 0xda, 0xb7,
+  0x68, 0xd4, 0xf0, 0xe5, 0xe9, 0x12, 0xb2, 0xd2, 0x06, 0xe5, 0x03, 0x8e,
+  0x9f, 0xd7, 0x32, 0x07, 0x3c, 0x0e, 0xec, 0xef, 0x46, 0x43, 0x81, 0x28,
+  0x36, 0x6b, 0xa3, 0x77, 0xdd, 0xf2, 0x9d, 0x6d, 0xcd, 0x05, 0x13, 0x32,
+  0xb2, 0xcf, 0x76, 0xeb, 0x7d, 0xa6, 0x0e, 0x6b, 0x84, 0xf9, 0xdf, 0x52,
+  0xfa, 0x2f, 0xda, 0xb2, 0xd2, 0xa0, 0x5c, 0x15, 0x61, 0xf0, 0xb1, 0x35,
+  0x28, 0xff, 0xc5, 0x36, 0xa4, 0xc7, 0x97, 0xf4, 0xfa, 0x69, 0xc7, 0x76,
+  0xd5, 0xed, 0x81, 0x48, 0x71, 0x23, 0x4f, 0xee, 0xb5, 0xd0, 0x05, 0x71,
+  0x2a, 0x02, 0x6e, 0x44, 0xce, 0x52, 0xf0, 0x11, 0x88, 0xa4, 0x44, 0x40,
+  0x4c, 0xb7, 0xef, 0x12, 0xe5, 0x1b, 0xca, 0x0f, 0x64, 0xcb, 0x6b, 0xc9,
+  0x56, 0x2f, 0x95, 0x8e, 0x51, 0x64, 0xc2, 0x74, 0x07, 0xa1, 0x57, 0x6c,
+  0x68, 0xd6, 0xaf, 0xbe, 0xa4, 0x58, 0x44, 0x48, 0x7f, 0x2e, 0x35, 0x0f,
+  0x21, 0x4f, 0x46, 0x75, 0x96, 0xd6, 0x30, 0xa8, 0x90, 0x50, 0xc3, 0x77,
+  0x86, 0x75, 0xc3, 0x3a, 0xd2, 0x36, 0xaf, 0x90, 0x1d, 0x44, 0xf4, 0x34,
+  0x79, 0x41, 0xcf, 0x12, 0x29, 0x8e, 0xc7, 0x0a, 0x93, 0x79, 0xad, 0x68,
+  0x80, 0xc3, 0x34, 0xc3, 0x95, 0xe8, 0x19, 0x16, 0x7a, 0x4e, 0x0f, 0xa4,
+  0xaa, 0xe1, 0xf7, 0x5c, 0xd1, 0xa1, 0xde, 0xe2, 0xc6, 0x7c, 0xa3, 0x97,
+  0x5c, 0x93, 0x8d, 0x34, 0x36, 0x5d, 0x0f, 0x04, 0xe8, 0x94, 0x1f, 0x7f,
+  0x79, 0x91, 0x5e, 0xa5, 0xd9, 0xec, 0x4f, 0xfb, 0xbb, 0xa3, 0xf4, 0x7a,
+  0x39, 0x4b, 0xff, 0x0d, 0x2f, 0xbe, 0x7c, 0xf2, 0x64, 0x7f, 0xf7, 0x93,
+  0x4f, 0x77, 0x7b, 0x5d, 0xf4, 0x81, 0xe3, 0x64, 0x01, 0xc2, 0x06, 0x9c,
+  0x2c, 0x24, 0x77, 0xf1, 0x9d, 0xe1, 0xe4, 0x3a, 0x87, 0x51, 0x47, 0x8a,
+  0x92, 0xcc, 0x41, 0xca, 0xd6, 0x24, 0xc4, 0x24, 0xe7, 0x0f, 0x9b, 0x1d,
+  0x5c, 0x9b, 0x7d, 0xfd, 0xc7, 0xbd, 0x03, 0x16, 0x65, 0xd7, 0x70, 0xbe,
+  0xa7, 0xbc, 0x63, 0x93, 0x17, 0x79, 0x61, 0x6e, 0xa0, 0x2f, 0x92, 0x26,
+  0xbd, 0xb6, 0x7b, 0x55, 0x58, 0x12, 0x38, 0x1d, 0xc2, 0xc6, 0x37, 0xaf,
+  0x68, 0x93, 0xe7, 0x66, 0xaa, 0xb6, 0xc0, 0x85, 0xb1, 0x59, 0x43, 0xc9,
+  0x5a, 0x64, 0x15, 0x32, 0x57, 0xaf, 0xab, 0x74, 0xae, 0x49, 0x27, 0xf4,
+  0x3e, 0xc1, 0xd6, 0x86, 0x8b, 0x99, 0x16, 0x5f, 0x67, 0xbf, 0x45, 0xee,
+  0x36, 0xdc, 0x6c, 0x51, 0xbb, 0xea, 0x98, 0x7c, 0xdd, 0x9c, 0x48, 0x51,
+  0xb1, 0x4d, 0x72, 0xa9, 0xf4, 0xd8, 0xa7, 0xd2, 0xc3, 0xa8, 0xfa, 0xb6,
+  0x92, 0xf4, 0x60, 0xaa, 0x23, 0x1d, 0xe2, 0xef, 0x60, 0xf5, 0x48, 0x99,
+  0x11, 0xb0, 0xb7, 0xe0, 0x3c, 0x7a, 0x5b, 0x5f, 0x8a, 0x9d, 0x6f, 0x79,
+  0x6b, 0x5c, 0xa9, 0x03, 0x5f, 0x26, 0x2f, 0xd4, 0x4b, 0xb4, 0xf7, 0xc5,
+  0x4b, 0x6c, 0x88, 0xbd, 0x2f, 0xfe, 0xcd, 0xfe, 0x6c, 0x5f, 0x7e, 0xb6,
+  0xff, 0xc5, 0xbf, 0x0d, 0x87, 0xe8, 0x1f, 0xed, 0x90, 0x4d, 0xfd, 0xf5,
+  0xa6, 0xb0, 0x26, 0xa5, 0x72, 0x84, 0xf9, 0x5f, 0x64, 0xb6, 0x73, 0x51,
+  0x2a, 0xac, 0x75, 0x4f, 0xbf, 0xec, 0xcf, 0x72, 0x5f, 0x22, 0xaa, 0x56,
+  0x6e, 0xe5, 0xb5, 0x4f, 0x3d, 0x57, 0xc7, 0x26, 0xdd, 0xc6, 0x41, 0xd0,
+  0x8e, 0xc0, 0x28, 0xf1, 0xf2, 0x9f, 0x69, 0xa7, 0xfe, 0x79, 0x23, 0x91,
+  0xe8, 0x26, 0x2d, 0xc7, 0x3d, 0x02, 0x1e, 0xba, 0x6d, 0x99, 0xee, 0x88,
+  0x79, 0x91, 0xa9, 0x65, 0x4a, 0xe3, 0xa0, 0x3b, 0xd0, 0x2b, 0xb1, 0xf4,
+  0x17, 0xa9, 0x4a, 0x6b, 0xf3, 0x5f, 0xf4, 0x19, 0x4e, 0x79, 0x31, 0x3a,
+  0x46, 0x43, 0xd2, 0x01, 0xcf, 0xfe, 0xe9, 0x87, 0x1f, 0x44, 0xa1, 0x32,
+  0x7f, 0x91, 0x9e, 0xdf, 0x18, 0x59, 0x34, 0x35, 0xe2, 0x6d, 0x8e, 0x9a,
+  0x2d, 0x52, 0x15, 0x4b, 0xae, 0xfc, 0x2b, 0x19, 0x29, 0x37, 0x62, 0x96,
+  0xf6, 0x70, 0x74, 0x74, 0x72, 0x02, 0xc4, 0x28, 0x26, 0xf5, 0x98, 0xc5,
+  0x18, 0xf6, 0xe6, 0x16, 0x20, 0x1e, 0x0e, 0x96, 0xe8, 0x6f, 0x7d, 0x5a,
+  0x3b, 0x2c, 0x3b, 0x76, 0xbf, 0x69, 0x4c, 0x0d, 0x70, 0x59, 0x4a, 0xec,
+  0x59, 0xd6, 0x72, 0x5e, 0xf6, 0xf8, 0xc1, 0xeb, 0xbc, 0x27, 0x41, 0x2c,
+  0xfe, 0x49, 0xcf, 0x91, 0x60, 0xf1, 0x7a, 0x60, 0xd1, 0x5e, 0xb2, 0xea,
+  0x94, 0xff, 0x23, 0x7b, 0xb9, 0xb7, 0x1b, 0x7f, 0x02, 0x51, 0x5b, 0xa2,
+  0xfd, 0x7b, 0xe9, 0x02, 0x82, 0xeb, 0x9e, 0xcf, 0xa7, 0xfc, 0xb4, 0x54,
+  0x95, 0x46, 0x81, 0xaf, 0x97, 0xbd, 0x31, 0xdd, 0xb0, 0xf4, 0x7f, 0x2b,
+  0xfa, 0x81, 0x88, 0x95, 0x3c, 0x5b, 0x2f, 0xc7, 0xf3, 0xbc, 0xd5, 0xe1,
+  0x1d, 0x1a, 0xe0, 0x17, 0x34, 0xe0, 0xef, 0x33, 0xbb, 0x3b, 0x32, 0x52,
+  0xed, 0x58, 0xf7, 0xdb, 0xbc, 0x2a, 0xcb, 0x71, 0x5a, 0x6d, 0x4a, 0x38,
+  0x47, 0xfb, 0xb9, 0xb9, 0xb7, 0xff, 0xe4, 0xe9, 0xb3, 0xcd, 0xa1, 0xe8,
+  0x69, 0x10, 0x11, 0x8d, 0x4f, 0x3c, 0xc2, 0x4d, 0x58, 0xca, 0x0c, 0x46,
+  0x4d, 0x23, 0x55, 0x3f, 0x16, 0x5c, 0x25, 0x29, 0x46, 0x9f, 0x7b, 0xc9,
+  0x5f, 0xfb, 0x37, 0xfa, 0xce, 0x4b, 0x7c, 0xe2, 0xdf, 0xf2, 0xe9, 0x4b,
+  0x3b, 0xc2, 0x7f, 0xa3, 0xb1, 0xbc, 0x94, 0x41, 0x98, 0x75, 0xd5, 0x74,
+  0xc2, 0x7a, 0x7b, 0x23, 0x2a, 0xd7, 0xa2, 0x8b, 0xab, 0x8b, 0xb8, 0x81,
+  0x41, 0x03, 0xc1, 0x30, 0x98, 0x72, 0xf4, 0x03, 0xda, 0xaa, 0x4b, 0xa6,
+  0xdb, 0xf9, 0x38, 0x30, 0xad, 0x0c, 0xa8, 0x95, 0x81, 0x13, 0xd8, 0x60,
+  0x6b, 0x1c, 0xd0, 0x42, 0xf4, 0x25, 0x9b, 0x72, 0x06, 0x2f, 0x8b, 0xa8,
+  0x02, 0x65, 0x09, 0x10, 0xc0, 0xd1, 0xd7, 0x27, 0x9b, 0x02, 0xbc, 0x61,
+  0x33, 0xb1, 0x1f, 0xf3, 0x4f, 0x5b, 0x88, 0xe1, 0x24, 0x5d, 0xd0, 0xe9,
+  0xdf, 0x50, 0x42, 0xda, 0x94, 0x70, 0x24, 0xf4, 0x5d, 0x4e, 0x7c, 0x36,
+  0x1f, 0x93, 0x5b, 0x67, 0x46, 0x1e, 0xef, 0x8a, 0x79, 0x24, 0xbd, 0x66,
+  0xcc, 0xbc, 0xd4, 0x02, 0x28, 0x41, 0xcc, 0x67, 0x61, 0x33, 0x27, 0x07,
+  0xaf, 0x6d, 0xd0, 0xd3, 0x66, 0xea, 0xc9, 0xa3, 0xe6, 0x57, 0x2c, 0x4f,
+  0x54, 0x44, 0xf4, 0x86, 0x5a, 0xb3, 0x9b, 0x77, 0x82, 0x2f, 0x3d, 0x90,
+  0xbd, 0x3f, 0xce, 0x24, 0xdf, 0x92, 0xdd, 0x26, 0xac, 0x18, 0x92, 0xfc,
+  0x7c, 0x61, 0x8b, 0xe5, 0x7d, 0x91, 0x80, 0x57, 0x9a, 0xdf, 0x92, 0xb8,
+  0x63, 0xab, 0x74, 0x3d, 0x5e, 0xda, 0x70, 0x05, 0xfa, 0x78, 0x46, 0x1c,
+  0x1a, 0x47, 0x14, 0x03, 0x9f, 0x30, 0x73, 0x7c, 0x2f, 0xce, 0x06, 0x6a,
+  0x61, 0xf3, 0x73, 0x1c, 0x82, 0x17, 0xb4, 0x0c, 0xf8, 0xf5, 0x17, 0x9b,
+  0x1b, 0xb6, 0x56, 0x94, 0xd5, 0xdc, 0x3b, 0x01, 0x64, 0xde, 0xa0, 0xfe,
+  0x78, 0x3c, 0x82, 0x04, 0xd6, 0xc6, 0x88, 0x8e, 0x05, 0x05, 0x21, 0x8c,
+  0x36, 0x35, 0x9b, 0x4a, 0xa5, 0x5d, 0xeb, 0xa0, 0xe6, 0xc6, 0x33, 0x4a,
+  0x53, 0x20, 0xed, 0x71, 0x93, 0xd0, 0xaa, 0x78, 0x6f, 0xd3, 0x92, 0xa3,
+  0xc2, 0x67, 0x0a, 0x81, 0x57, 0x65, 0x5a, 0x00, 0x76, 0x43, 0x8a, 0x71,
+  0x39, 0x6d, 0xde, 0x1f, 0x58, 0xed, 0x29, 0x0f, 0x2e, 0x5f, 0x91, 0x39,
+  0x8a, 0x82, 0x23, 0xf2, 0x9a, 0x12, 0x81, 0xe5, 0xa3, 0x2f, 0x69, 0xba,
+  0xf7, 0x86, 0xd7, 0xf9, 0x15, 0x4f, 0x86, 0x11, 0x91, 0xd7, 0xd9, 0x8e,
+  0xf9, 0x67, 0xdf, 0xfc, 0x7c, 0x9f, 0xb4, 0x32, 0xfa, 0xcb, 0x13, 0xe0,
+  0xb1, 0xfc, 0xbb, 0xdf, 0x3b, 0x1b, 0xf6, 0x5c, 0xd0, 0x5f, 0x72, 0x7b,
+  0xe7, 0x4b, 0x54, 0x47, 0x7a, 0x39, 0x50, 0xbe, 0x52, 0x64, 0xc9, 0xa9,
+  0xaa, 0xe9, 0x83, 0x4a, 0xc8, 0xd0, 0x22, 0x93, 0x74, 0x49, 0xe9, 0x29,
+  0x16, 0x3c, 0x22, 0x40, 0x0a, 0x51, 0xd4, 0x49, 0xef, 0xce, 0xc5, 0x3d,
+  0x43, 0xe9, 0x3c, 0xb8, 0x59, 0xb3, 0xbb, 0xed, 0xbe, 0x8f, 0xb4, 0x35,
+  0xe2, 0xfd, 0x96, 0x92, 0xe3, 0x89, 0x41, 0xc4, 0xea, 0xb4, 0xf8, 0xfc,
+  0x96, 0xd4, 0x55, 0xf4, 0x72, 0x86, 0xb1, 0xcc, 0x79, 0x77, 0x05, 0xdb,
+  0xa5, 0x09, 0x19, 0xc8, 0x97, 0xd7, 0xcd, 0x36, 0x7d, 0x26, 0x9b, 0xd5,
+  0xb0, 0xd5, 0xa5, 0x28, 0xa9, 0x7e, 0x55, 0x80, 0x07, 0xfc, 0xa1, 0x4d,
+  0xff, 0xec, 0x97, 0x93, 0x26, 0x33, 0xb6, 0x2e, 0xb1, 0xa5, 0xcd, 0x59,
+  0xce, 0x1d, 0xcf, 0x99, 0x92, 0x18, 0x5b, 0x78, 0x36, 0xe0, 0xdb, 0x53,
+  0x54, 0xa2, 0xc1, 0xeb, 0x61, 0x72, 0x0a, 0xc4, 0x78, 0x9d, 0x32, 0x1f,
+  0x8f, 0xde, 0xb0, 0xba, 0x1b, 0xcc, 0xd6, 0x61, 0x1d, 0x7c, 0x83, 0x33,
+  0x58, 0x88, 0xd9, 0x42, 0xb7, 0x14, 0x88, 0x27, 0x9d, 0xd1, 0xc9, 0xfa,
+  0x85, 0xe8, 0x23, 0x7d, 0xf8, 0xc2, 0xed, 0x73, 0xf0, 0xf9, 0xb3, 0xdf,
+  0x0f, 0x79, 0x5c, 0x76, 0xc3, 0x7a, 0x8d, 0x30, 0x68, 0x4b, 0x14, 0x50,
+  0x4f, 0xac, 0xdb, 0x43, 0xc0, 0x90, 0xca, 0x8c, 0x9d, 0x2e, 0x44, 0xb0,
+  0x40, 0xa4, 0x40, 0x88, 0x09, 0x9b, 0xd6, 0xb0, 0xcb, 0xa8, 0x66, 0x24,
+  0x6d, 0xa3, 0x1e, 0xec, 0xc6, 0x59, 0x66, 0x8d, 0x6b, 0x5e, 0xab, 0xd2,
+  0xc2, 0xcd, 0xe1, 0x8b, 0x11, 0xba, 0x5d, 0x1b, 0xae, 0xa3, 0x4e, 0x52,
+  0xbf, 0xd2, 0x5b, 0xf3, 0x17, 0x52, 0xce, 0xc6, 0x95, 0x59, 0xf5, 0xac,
+  0xe2, 0xab, 0x81, 0x31, 0x42, 0x5e, 0x01, 0xcd, 0x6f, 0x2e, 0xdf, 0x9c,
+  0x26, 0xca, 0x6b, 0x74, 0xe5, 0x54, 0x45, 0x45, 0x66, 0x62, 0x88, 0xe2,
+  0x19, 0x61, 0x7d, 0x48, 0x9e, 0xe2, 0x5b, 0x8e, 0xe7, 0x96, 0x12, 0xde,
+  0x13, 0x9a, 0x9c, 0xd6, 0x91, 0xf5, 0x9e, 0xe0, 0x57, 0x69, 0x1f, 0x99,
+  0x6d, 0xb2, 0x49, 0x53, 0xb0, 0xd9, 0x4f, 0x36, 0xa9, 0xab, 0xf4, 0x8b,
+  0x4d, 0xcc, 0x27, 0x7e, 0xec, 0x4d, 0xdf, 0xe6, 0x30, 0x72, 0x0a, 0xe9,
+  0x99, 0x97, 0x5f, 0xb6, 0x66, 0x09, 0x3f, 0xd7, 0xa6, 0x5e, 0x72, 0xbe,
+  0x48, 0xa0, 0x73, 0xeb, 0xbb, 0x5e, 0xfb, 0x2f, 0x8f, 0x4a, 0x62, 0x1a,
+  0xa5, 0x02, 0x9d, 0x0e, 0xe6, 0x3a, 0xb1, 0x3f, 0xcb, 0x91, 0xfb, 0x1a,
+  0x34, 0xf4, 0xf0, 0x29, 0xbe, 0x54, 0x51, 0x64, 0x21, 0xa0, 0x2c, 0xdd,
+  0x78, 0x0b, 0xa8, 0xe4, 0x35, 0xab, 0x99, 0xb3, 0xdd, 0x77, 0x57, 0xc2,
+  0xcb, 0x00, 0x99, 0xb3, 0x37, 0x44, 0x32, 0xa4, 0x63, 0x46, 0xb7, 0x0d,
+  0x58, 0xe3, 0xbd, 0x87, 0x09, 0xed, 0x59, 0x54, 0xae, 0x9a, 0xf4, 0x3a,
+  0xcb, 0x31, 0xd9, 0xb5, 0xc8, 0x27, 0xa8, 0x75, 0xff, 0xf2, 0xcb, 0x69,
+  0x79, 0x4d, 0x92, 0xab, 0x6f, 0x0e, 0x1a, 0xfd, 0x09, 0x40, 0xf2, 0xbe,
+  0x7c, 0x94, 0x3b, 0x8c, 0xb3, 0xc2, 0x5a, 0xbc, 0xfe, 0x7b, 0x05, 0x44,
+  0xf5, 0x35, 0xb9, 0x42, 0x27, 0xd2, 0xb6, 0x6d, 0x9a, 0xd7, 0xc3, 0xb4,
+  0x6f, 0x7f, 0xe1, 0x7f, 0x4b, 0x27, 0x27, 0x95, 0x96, 0xb9, 0x50, 0xaa,
+  0xd4, 0x91, 0x9d, 0xdd, 0xdb, 0x22, 0x51, 0x70, 0x70, 0x11, 0xc3, 0x39,
+  0xdf, 0x5b, 0x33, 0xc9, 0xd0, 0xdb, 0xfc, 0x72, 0x93, 0x73, 0x04, 0x36,
+  0x5f, 0x6c, 0x42, 0x82, 0x91, 0x5c, 0x9a, 0x8f, 0x33, 0xe4, 0x91, 0xc9,
+  0xe5, 0xb4, 0xc9, 0xb7, 0xe2, 0x80, 0x75, 0x07, 0x61, 0x72, 0x74, 0x07,
+  0x04, 0xd7, 0xb2, 0x33, 0x23, 0x7d, 0xf0, 0x24, 0xdc, 0x04, 0xae, 0x7c,
+  0x2b, 0x51, 0x11, 0x8f, 0x1b, 0x06, 0xca, 0xc8, 0xa5, 0x0b, 0xb5, 0x0c,
+  0xa4, 0x27, 0xc4, 0x03, 0x24, 0x6e, 0xce, 0x65, 0xb1, 0xa0, 0x34, 0xf7,
+  0x49, 0x03, 0x6f, 0x0b, 0x9f, 0xa5, 0x61, 0xf2, 0xae, 0x98, 0x72, 0x71,
+  0x75, 0x32, 0x96, 0xf3, 0x6a, 0xb2, 0x9c, 0x93, 0xab, 0x62, 0x42, 0x0e,
+  0x32, 0x5c, 0x3c, 0xac, 0x1e, 0xb4, 0xc2, 0xf3, 0x7e, 0x87, 0xd9, 0x39,
+  0xc2, 0x0e, 0x73, 0xf9, 0x2e, 0xa0, 0x28, 0x04, 0xc0, 0x12, 0x87, 0x38,
+  0xb4, 0x02, 0x4b, 0x7e, 0x22, 0x02, 0x88, 0x22, 0x83, 0xc7, 0xaf, 0x8f,
+  0x2f, 0x2e, 0x8e, 0x2f, 0x68, 0xbe, 0x0f, 0x3b, 0xd5, 0xb8, 0x94, 0x06,
+  0xd9, 0x85, 0x1a, 0x15, 0xf6, 0xeb, 0x7b, 0x6a, 0x34, 0x2b, 0x89, 0x44,
+  0xa1, 0x14, 0xa3, 0x82, 0x05, 0xc1, 0x74, 0x3f, 0x5c, 0xee, 0xc0, 0x77,
+  0x2f, 0x02, 0xf6, 0x6d, 0xc3, 0x06, 0x80, 0x41, 0xc1, 0x01, 0xd9, 0xd2,
+  0x2d, 0x5c, 0x0b, 0x95, 0x10, 0xe0, 0x2f, 0x35, 0xbb, 0xfe, 0x26, 0x6b,
+  0xa9, 0xa9, 0x43, 0x41, 0xea, 0x66, 0x12, 0x4c, 0x9f, 0x59, 0xff, 0x04,
+  0x86, 0x7c, 0x45, 0x67, 0x94, 0x6c, 0x27, 0x4c, 0x46, 0xdd, 0x2c, 0x17,
+  0xf9, 0xd4, 0x7a, 0x7b, 0xcd, 0xcf, 0x8d, 0xfa, 0x97, 0xf0, 0x29, 0xaf,
+  0x15, 0xeb, 0x82, 0xa8, 0xa6, 0x3a, 0x23, 0x7c, 0x6f, 0x5b, 0xa7, 0x56,
+  0x75, 0x82, 0xc4, 0x37, 0x06, 0x8d, 0x29, 0xb1, 0x79, 0x3b, 0x4d, 0x5c,
+  0xf6, 0x7e, 0x06, 0x2f, 0x23, 0x49, 0x0b, 0x85, 0xdf, 0xf8, 0x92, 0x81,
+  0x7c, 0x59, 0x73, 0x87, 0x77, 0x77, 0xb5, 0x6d, 0x2f, 0x90, 0x1d, 0x5a,
+  0x1d, 0x24, 0x3f, 0xd6, 0xf9, 0xe4, 0x67, 0x77, 0x79, 0x20, 0xfd, 0xa7,
+  0xcd, 0x47, 0x85, 0xa9, 0x93, 0x89, 0x12, 0x63, 0x98, 0xb3, 0xb2, 0xdf,
+  0x8d, 0x8e, 0x2f, 0x92, 0xc3, 0xaf, 0x89, 0xd1, 0xfb, 0x9f, 0x5c, 0x60,
+  0x7a, 0x4e, 0x6e, 0x87, 0x0d, 0xe1, 0x57, 0x14, 0x8a, 0x92, 0x6c, 0xea,
+  0x57, 0xa2, 0x1d, 0xb6, 0x56, 0x36, 0xd7, 0xfa, 0x05, 0xee, 0xba, 0x6f,
+  0xaf, 0x21, 0xb9, 0x0b, 0x1f, 0x58, 0xc5, 0xc7, 0xac, 0x21, 0x1d, 0x32,
+  0x7f, 0x15, 0x99, 0xdc, 0x88, 0x43, 0x12, 0xba, 0x36, 0xd2, 0xfb, 0x3a,
+  0x30, 0x3b, 0x79, 0x95, 0x0e, 0x93, 0xcd, 0x37, 0xe5, 0x3f, 0x8c, 0x32,
+  0x90, 0xee, 0x3c, 0x19, 0xee, 0x26, 0x5b, 0xdf, 0xe7, 0xc5, 0x67, 0xcf,
+  0x3e, 0x4f, 0x4e, 0xb6, 0x37, 0x5b, 0x60, 0x7e, 0x2e, 0x29, 0x32, 0x4e,
+  0x8b, 0x0f, 0x76, 0xc9, 0xce, 0x70, 0xb2, 0x19, 0x54, 0x27, 0xce, 0x87,
+  0x9a, 0xe9, 0xfc, 0x57, 0xb6, 0x88, 0x1c, 0x4e, 0xc9, 0x0b, 0x48, 0xbe,
+  0xb3, 0xe5, 0xdd, 0xc9, 0xca, 0x37, 0x4f, 0x4d, 0x69, 0xea, 0x3e, 0x7b,
+  0x16, 0x34, 0xf1, 0xd4, 0xb6, 0xf1, 0x8e, 0xdb, 0xf8, 0x85, 0x4d, 0xec,
+  0x0f, 0x77, 0xf7, 0x93, 0xad, 0xb3, 0xd1, 0xce, 0xbe, 0x6d, 0x21, 0x6c,
+  0x62, 0x1f, 0x4d, 0xd0, 0x43, 0xed, 0x97, 0x9f, 0xd2, 0xf7, 0x7f, 0xcc,
+  0x8a, 0x9f, 0x93, 0xad, 0x1f, 0xf6, 0xf6, 0x4c, 0x03, 0x9f, 0x27, 0x87,
+  0x27, 0x3f, 0x24, 0x4f, 0x87, 0xa6, 0xb1, 0xb7, 0xe9, 0xad, 0x34, 0x27,
+  0xac, 0xc4, 0x23, 0x34, 0x62, 0x7e, 0x1f, 0xb4, 0xf1, 0xac, 0xd3, 0xc6,
+  0xa9, 0xb1, 0x0b, 0x3f, 0x9a, 0x6b, 0x65, 0x77, 0xf8, 0x64, 0x3f, 0xc9,
+  0x9f, 0x7d, 0xfa, 0x5c, 0x1b, 0x92, 0x36, 0xf0, 0xfb, 0xb6, 0xb7, 0x92,
+  0x99, 0x4f, 0x8c, 0xaa, 0x73, 0xfc, 0xd1, 0x08, 0x34, 0x88, 0x88, 0x8a,
+  0x3c, 0x85, 0x37, 0x69, 0x35, 0x95, 0xed, 0x46, 0xc5, 0x46, 0xcc, 0x4a,
+  0x09, 0x25, 0x7c, 0x06, 0xb7, 0xa5, 0xb9, 0x38, 0x0f, 0x82, 0xee, 0x90,
+  0x6d, 0xaa, 0x8f, 0x7e, 0x9e, 0xbc, 0x19, 0x9d, 0x1c, 0x9b, 0x11, 0xed,
+  0x9a, 0xae, 0xb9, 0x39, 0xe4, 0x0e, 0xe1, 0x57, 0x98, 0xdc, 0xcf, 0xc0,
+  0x36, 0x2b, 0x6d, 0xa8, 0xce, 0xcd, 0x40, 0x56, 0xb3, 0xe9, 0xcc, 0xc5,
+  0x5d, 0xe3, 0xbb, 0x04, 0x49, 0x19, 0x1c, 0x5e, 0x93, 0x09, 0xc1, 0x57,
+  0x2d, 0x3e, 0xfd, 0x6d, 0x59, 0x98, 0x63, 0x52, 0x95, 0x15, 0x21, 0xa7,
+  0x36, 0x5b, 0xda, 0xc2, 0xb7, 0xaf, 0x8e, 0x39, 0x3b, 0xfe, 0x4d, 0x5a,
+  0x18, 0x19, 0x49, 0x24, 0x57, 0xf5, 0x07, 0x8a, 0xff, 0x73, 0x38, 0x87,
+  0xdf, 0x3f, 0xbd, 0x2f, 0x3e, 0x9a, 0x75, 0xfc, 0x64, 0xb8, 0x47, 0x90,
+  0x6d, 0xb2, 0x7a, 0x5f, 0xbf, 0x31, 0xff, 0xde, 0x7b, 0xba, 0x99, 0xd0,
+  0xaf, 0xda, 0x16, 0xbc, 0x9e, 0xd7, 0x8d, 0xa3, 0xb3, 0xb3, 0x6f, 0x4f,
+  0x18, 0x00, 0x72, 0x24, 0x6e, 0x55, 0x52, 0xae, 0xac, 0x55, 0xcc, 0xd2,
+  0xd5, 0x58, 0x6f, 0x2e, 0x5b, 0x09, 0xc1, 0xb8, 0x0f, 0x59, 0xb6, 0x20,
+  0x34, 0x42, 0xd3, 0x91, 0x08, 0x8d, 0xc8, 0x68, 0x8b, 0x6d, 0x22, 0xf5,
+  0xa7, 0xc3, 0xc5, 0xd9, 0xd4, 0xd6, 0x85, 0x3b, 0xbe, 0xb7, 0x0c, 0x1c,
+  0xa9, 0xab, 0x3c, 0x8b, 0x2e, 0xda, 0x6c, 0x05, 0x75, 0x41, 0x63, 0x85,
+  0xa9, 0xaa, 0x8d, 0xd8, 0xbe, 0x9b, 0x23, 0xa3, 0xdd, 0x73, 0xa7, 0x0f,
+  0xc4, 0x6b, 0xbb, 0xe9, 0x71, 0xc4, 0x43, 0xa3, 0x45, 0xba, 0x0e, 0x43,
+  0xd4, 0xc8, 0x40, 0x10, 0xe0, 0xbc, 0xc8, 0x66, 0x14, 0x06, 0xcf, 0x00,
+  0xcf, 0x7b, 0x7b, 0xf8, 0xe6, 0xf8, 0xe5, 0x77, 0x87, 0xa7, 0xef, 0x8e,
+  0xcd, 0x2b, 0xb9, 0xf9, 0xd8, 0x96, 0x83, 0xf0, 0xa1, 0x8f, 0xf3, 0x7c,
+  0x52, 0xce, 0x28, 0xca, 0xb4, 0xf9, 0xf9, 0xe6, 0x06, 0xc3, 0xcb, 0x93,
+  0x1e, 0xbd, 0xb5, 0xc7, 0xaf, 0x99, 0x7d, 0x41, 0xff, 0xda, 0xe7, 0x7f,
+  0xed, 0x7f, 0xde, 0xdb, 0x6e, 0x0d, 0x3a, 0xb0, 0x92, 0xaf, 0x50, 0x7c,
+  0x12, 0x35, 0x03, 0x51, 0x66, 0x19, 0xb9, 0x1b, 0x3c, 0x2b, 0x3d, 0x8d,
+  0xd1, 0xe8, 0xdd, 0x46, 0xcf, 0x6e, 0x8d, 0xef, 0x7d, 0x1b, 0xbc, 0x47,
+  0x2f, 0xbd, 0x84, 0x82, 0xd1, 0xdb, 0xee, 0x5b, 0x95, 0x03, 0xa1, 0x72,
+  0x6a, 0x43, 0x9b, 0x60, 0x56, 0xc8, 0x64, 0xab, 0xc7, 0x7f, 0x79, 0xf9,
+  0xea, 0xf0, 0xf2, 0x98, 0x5e, 0xd0, 0xcf, 0x0b, 0x1a, 0xd1, 0xa6, 0x51,
+  0x50, 0x7f, 0xb6, 0x24, 0x34, 0xfd, 0x92, 0x06, 0xd4, 0xdb, 0xe6, 0x58,
+  0x06, 0x82, 0xea, 0x9d, 0x7e, 0x95, 0x85, 0x02, 0xb7, 0x5d, 0xc6, 0x79,
+  0xad, 0x88, 0x95, 0xad, 0x1e, 0xff, 0xae, 0x67, 0x3d, 0xb8, 0x52, 0xed,
+  0x44, 0xc2, 0x95, 0x53, 0x24, 0x59, 0x04, 0x99, 0xb5, 0x0c, 0x49, 0x73,
+  0xeb, 0x23, 0xc1, 0x0a, 0xf6, 0x38, 0x79, 0xac, 0xf9, 0x76, 0xe1, 0x25,
+  0xa5, 0x9d, 0x7c, 0x4c, 0x65, 0xb9, 0xb7, 0xff, 0xe4, 0x73, 0xcc, 0xe7,
+  0xcb, 0xde, 0x8e, 0xb9, 0x1b, 0x7a, 0x9f, 0xd3, 0xa7, 0xf3, 0xc6, 0xab,
+  0xfd, 0x26, 0x9f, 0x21, 0x7b, 0x4a, 0x76, 0x14, 0xc3, 0x65, 0x68, 0xd5,
+  0x3d, 0xa6, 0x1e, 0x4c, 0xe8, 0x1d, 0x67, 0x89, 0x29, 0xaf, 0x8d, 0x82,
+  0x07, 0xb0, 0x5e, 0x28, 0x5a, 0x85, 0x72, 0x1c, 0xec, 0xd4, 0xc5, 0xe7,
+  0xfc, 0xfb, 0xa3, 0xcf, 0xef, 0xf2, 0x18, 0x85, 0x0b, 0x88, 0xbe, 0x39,
+  0xbf, 0xd7, 0x44, 0x32, 0x7c, 0x0b, 0x3a, 0x39, 0xaf, 0x59, 0xa0, 0x19,
+  0x8f, 0xc5, 0xb7, 0xa3, 0xc6, 0x08, 0x74, 0x02, 0x23, 0x5a, 0xee, 0xa1,
+  0x28, 0x01, 0x6d, 0xe0, 0x83, 0x2c, 0xf4, 0xce, 0x4e, 0xc7, 0xb9, 0xd1,
+  0x84, 0x6d, 0x6a, 0x8c, 0x67, 0x95, 0xdb, 0xa9, 0xd7, 0xe3, 0x97, 0x7b,
+  0x24, 0x4b, 0x1b, 0x96, 0x9b, 0xb4, 0xb6, 0x3e, 0x24, 0x44, 0x1b, 0xe5,
+  0xd9, 0xf6, 0x3a, 0x75, 0xf2, 0xd1, 0x30, 0x0c, 0x36, 0xe9, 0xd9, 0x3e,
+  0x36, 0xa2, 0xa6, 0xc8, 0xaa, 0xb5, 0x00, 0x8b, 0x48, 0x30, 0x0a, 0x43,
+  0xf4, 0x39, 0xe8, 0xcd, 0x3b, 0xc3, 0xe1, 0xd0, 0x9a, 0x3b, 0x08, 0xa4,
+  0x49, 0x0c, 0x8a, 0xe8, 0xeb, 0x7c, 0x5e, 0x60, 0xcc, 0xf1, 0x16, 0x94,
+  0x79, 0x28, 0xd4, 0xdb, 0x02, 0xbc, 0x11, 0x3f, 0x81, 0x3d, 0x1a, 0x9e,
+  0x8f, 0x63, 0x53, 0x3e, 0xbb, 0xa9, 0xfc, 0x0b, 0x1f, 0x62, 0x8b, 0xb0,
+  0xa6, 0x6f, 0xec, 0x7b, 0x94, 0x22, 0x38, 0x56, 0x4e, 0xd9, 0xc2, 0xf2,
+  0xb0, 0xe7, 0x09, 0x40, 0xce, 0xc5, 0xda, 0xee, 0x6d, 0xf1, 0x1b, 0xed,
+  0x4a, 0x9f, 0xb1, 0x07, 0x24, 0xe4, 0xca, 0x3b, 0xf0, 0x19, 0x80, 0x35,
+  0x81, 0xb0, 0x27, 0x05, 0xbb, 0x07, 0xf4, 0x06, 0x59, 0x58, 0xb5, 0x59,
+  0xda, 0x11, 0x8e, 0x68, 0xb2, 0x99, 0xa1, 0xfb, 0x4b, 0x96, 0xa3, 0x30,
+  0xcb, 0xd4, 0x9a, 0xc4, 0x63, 0xd4, 0xb6, 0x12, 0x74, 0xa4, 0x3a, 0x78,
+  0xe7, 0xae, 0x22, 0xb4, 0xd9, 0x80, 0xb9, 0x59, 0x34, 0x11, 0x51, 0xa5,
+  0x87, 0xf0, 0x73, 0xac, 0x8b, 0x97, 0x4f, 0xb4, 0x45, 0x1b, 0x2c, 0xef,
+  0xcc, 0x8d, 0xbb, 0x95, 0xdb, 0xa2, 0xcb, 0xcc, 0x28, 0x7b, 0x97, 0x6d,
+  0xbd, 0x06, 0x91, 0x7b, 0x49, 0x7a, 0x67, 0xae, 0x9e, 0x22, 0x23, 0x7c,
+  0x26, 0x90, 0x0e, 0xf0, 0xca, 0x9c, 0x7a, 0x7e, 0x46, 0x3b, 0x42, 0xad,
+  0x91, 0x94, 0xba, 0x22, 0x49, 0xc9, 0x16, 0x1b, 0x1a, 0x4c, 0x8f, 0xac,
+  0x0e, 0x3d, 0x52, 0xc0, 0xcb, 0x39, 0xb1, 0x94, 0x8a, 0xa6, 0xae, 0xe6,
+  0x39, 0xf5, 0xdc, 0x88, 0xe8, 0x91, 0xec, 0x9b, 0x1c, 0xb8, 0x44, 0xf2,
+  0x73, 0x30, 0xae, 0x42, 0x67, 0x2b, 0x2d, 0xa6, 0xde, 0x47, 0x6c, 0x7c,
+  0x5a, 0xdc, 0x4f, 0x04, 0xef, 0x2d, 0x06, 0xe0, 0xac, 0xd0, 0x90, 0xb0,
+  0x98, 0x57, 0xd7, 0xd7, 0x6c, 0xb5, 0x25, 0xdd, 0xa1, 0xc5, 0x37, 0xd9,
+  0x29, 0xcd, 0x0a, 0xa1, 0xa0, 0xef, 0x57, 0xcd, 0xe6, 0xa5, 0xad, 0xa4,
+  0x27, 0x5e, 0x97, 0xd6, 0x66, 0xd6, 0x98, 0x24, 0xaf, 0x5b, 0x63, 0x93,
+  0xae, 0x90, 0xa0, 0xd1, 0x8e, 0x21, 0x9f, 0x5d, 0x6c, 0xa0, 0x00, 0x4a,
+  0xe1, 0x08, 0x19, 0x74, 0xd1, 0x41, 0xb4, 0xe7, 0x10, 0x28, 0x0e, 0x89,
+  0x7a, 0x67, 0xa1, 0x56, 0xd8, 0xae, 0xc9, 0x38, 0x75, 0x26, 0xd7, 0x46,
+  0xd2, 0xf2, 0xf6, 0x52, 0x55, 0xa6, 0x93, 0x42, 0xe4, 0x50, 0x79, 0x9b,
+  0x39, 0x9e, 0x47, 0xe7, 0x70, 0x74, 0xe4, 0xbf, 0x72, 0xfa, 0xad, 0x30,
+  0xe9, 0x04, 0x78, 0xad, 0xbc, 0xc2, 0x20, 0x3b, 0xb3, 0x32, 0x4c, 0xbc,
+  0x26, 0xd9, 0x55, 0x52, 0xb6, 0x38, 0x94, 0xd1, 0x37, 0x89, 0x5b, 0x6b,
+  0x8b, 0xbc, 0x47, 0x98, 0xad, 0xc5, 0x33, 0x4d, 0xb8, 0x78, 0x90, 0x56,
+  0x40, 0xb0, 0x18, 0x3d, 0x17, 0xff, 0xd5, 0x51, 0xf6, 0xec, 0x22, 0xf5,
+  0xb4, 0xd6, 0x04, 0x36, 0x01, 0xf6, 0x00, 0x29, 0x74, 0x36, 0x84, 0x7f,
+  0x29, 0xeb, 0x84, 0x9d, 0x0c, 0x0f, 0x5a, 0x47, 0x90, 0x06, 0x67, 0xce,
+  0x42, 0x34, 0x90, 0x87, 0x62, 0x24, 0x2f, 0x70, 0x05, 0x83, 0xf1, 0x06,
+  0xe7, 0x1b, 0x0d, 0x26, 0x2a, 0xd1, 0xd7, 0x13, 0x16, 0x8c, 0x5b, 0x07,
+  0xf3, 0xa1, 0x73, 0x7a, 0x7e, 0x71, 0xf6, 0xf5, 0xc5, 0xf1, 0x68, 0x94,
+  0xbc, 0x39, 0xbe, 0x64, 0x5b, 0xff, 0x92, 0xa1, 0x77, 0xd7, 0xa8, 0x1d,
+  0x8d, 0x58, 0x83, 0x92, 0x31, 0x29, 0xe4, 0x44, 0x1d, 0x09, 0xc8, 0x79,
+  0xa2, 0x92, 0xc8, 0xb8, 0x1d, 0xd9, 0x88, 0x9f, 0x09, 0x62, 0xef, 0x06,
+  0xde, 0x7e, 0x60, 0x9a, 0x10, 0x90, 0xb4, 0xce, 0x73, 0xe7, 0x46, 0x85,
+  0x62, 0xcc, 0x28, 0x27, 0x9b, 0x73, 0xe8, 0x5c, 0xe8, 0x74, 0x65, 0x9b,
+  0x3f, 0x31, 0xbc, 0x3f, 0x99, 0xd9, 0x94, 0x32, 0x70, 0x7f, 0x32, 0xc6,
+  0xaf, 0x6c, 0x8a, 0x3f, 0x25, 0x3f, 0x98, 0x36, 0xa7, 0xc6, 0x78, 0x95,
+  0x92, 0xb7, 0x23, 0x94, 0xba, 0x75, 0x5c, 0xcb, 0xb9, 0x57, 0xcc, 0x39,
+  0xe1, 0x14, 0xc3, 0xea, 0x81, 0x3a, 0x93, 0xe0, 0x8a, 0xe1, 0x72, 0xba,
+  0x82, 0xa9, 0xb3, 0x5f, 0x96, 0x5a, 0x63, 0x49, 0x72, 0x9a, 0x5d, 0xa1,
+  0x0e, 0x0b, 0x3e, 0x67, 0x9a, 0xdb, 0x25, 0x52, 0xea, 0xbd, 0x37, 0xf4,
+  0xa3, 0xdd, 0xe4, 0xc9, 0xa7, 0xcf, 0x77, 0x3f, 0xe5, 0xbf, 0xea, 0x7f,
+  0x3f, 0x7b, 0xba, 0x2b, 0xec, 0xf8, 0xe6, 0x5f, 0x4f, 0x0f, 0x9e, 0xee,
+  0x1d, 0x10, 0x4f, 0xe3, 0xee, 0xc1, 0xae, 0xf9, 0xbf, 0xa7, 0xf2, 0x13,
+  0x22, 0xa3, 0xfc, 0x6c, 0xff, 0xd3, 0x4f, 0x80, 0x86, 0xa1, 0xfd, 0x31,
+  0x33, 0x1f, 0x19, 0x34, 0xe5, 0x00, 0x74, 0x51, 0xd0, 0x7c, 0xfe, 0xd4,
+  0xf6, 0x44, 0x52, 0x78, 0x9d, 0xca, 0x60, 0xd3, 0xc0, 0x6d, 0x0d, 0x50,
+  0xf5, 0xaa, 0x32, 0x85, 0x8d, 0x5f, 0xb9, 0xd0, 0x0e, 0x43, 0xde, 0xe6,
+  0x4a, 0x7a, 0xe0, 0x5f, 0x6b, 0xbd, 0xc3, 0x40, 0x73, 0x8f, 0xea, 0xed,
+  0x97, 0x7e, 0x5a, 0x13, 0xc9, 0x37, 0x40, 0xe0, 0x26, 0x4b, 0x25, 0xef,
+  0x4d, 0xb4, 0x5c, 0x9b, 0x5f, 0x58, 0xba, 0x53, 0x8d, 0xf9, 0x97, 0x7e,
+  0x8f, 0x3d, 0x57, 0xf4, 0x96, 0xec, 0x86, 0x24, 0xfc, 0x9a, 0xcd, 0x45,
+  0x88, 0x7c, 0xab, 0xb5, 0x79, 0x36, 0xdc, 0xf2, 0xbb, 0x99, 0xf2, 0x6a,
+  0x3d, 0xdb, 0x1c, 0x2e, 0xae, 0xaa, 0x1c, 0x19, 0x72, 0xd0, 0xdc, 0xbb,
+  0x85, 0xdf, 0xde, 0x63, 0x9a, 0x73, 0x23, 0xc2, 0x0e, 0xb6, 0x2b, 0x37,
+  0xf0, 0x16, 0x27, 0x67, 0x60, 0x9b, 0xad, 0x9c, 0xa9, 0x04, 0xa1, 0xb6,
+  0xa6, 0x31, 0x5e, 0xb5, 0x5b, 0x76, 0xc0, 0x6f, 0x88, 0xce, 0x69, 0xf3,
+  0xe2, 0x50, 0xaf, 0x14, 0x57, 0x3c, 0x3f, 0xaf, 0x3b, 0x3b, 0xf8, 0x14,
+  0xed, 0x46, 0xef, 0x7b, 0xf2, 0x0d, 0x9c, 0x27, 0x7b, 0xe8, 0xd6, 0x0e,
+  0xcd, 0x61, 0xeb, 0xb5, 0x68, 0x23, 0xe3, 0xb8, 0xa0, 0x7c, 0xc7, 0x8e,
+  0xa4, 0x7b, 0x0e, 0xf0, 0x75, 0xdb, 0x9c, 0x7f, 0xfb, 0xcc, 0xc0, 0x03,
+  0xce, 0xe5, 0x4e, 0x88, 0x75, 0x94, 0x6a, 0x39, 0x6c, 0xab, 0x08, 0x1b,
+  0xfc, 0xd1, 0xc2, 0xb6, 0x70, 0x99, 0x31, 0xac, 0x8d, 0x9a, 0xa2, 0xf9,
+  0x9c, 0xf9, 0xb9, 0xb4, 0x56, 0xda, 0x8d, 0xd3, 0xaa, 0x55, 0x33, 0x61,
+  0x83, 0x6b, 0x84, 0x98, 0xeb, 0xd5, 0x5c, 0x17, 0x48, 0x77, 0x64, 0x3d,
+  0xe2, 0x0f, 0x1b, 0x1b, 0xa3, 0xf3, 0xe3, 0xe3, 0x57, 0xc9, 0xe9, 0xc9,
+  0x9b, 0x93, 0x4b, 0x4f, 0x0b, 0xb7, 0xb7, 0x87, 0x7a, 0x5a, 0xb5, 0x7a,
+  0x5c, 0x67, 0x3a, 0x1c, 0xf5, 0x32, 0x7f, 0x4f, 0xef, 0xef, 0x79, 0x26,
+  0x59, 0x14, 0xb3, 0xee, 0x7b, 0xb0, 0xb7, 0xc1, 0xec, 0x44, 0x35, 0xb8,
+  0x3d, 0x2d, 0xae, 0x36, 0x1a, 0x8d, 0xe9, 0xdd, 0x80, 0xd9, 0x05, 0x06,
+  0x7f, 0x15, 0x9c, 0x46, 0x5b, 0x5d, 0x12, 0x16, 0x59, 0x9b, 0xd2, 0x23,
+  0xd8, 0xd6, 0x4e, 0xaf, 0x68, 0x6e, 0x33, 0x86, 0x56, 0x7b, 0x6e, 0x39,
+  0xc0, 0xf6, 0xee, 0x32, 0xb0, 0x1d, 0xcc, 0x73, 0xce, 0xb5, 0xf4, 0x31,
+  0xc5, 0x28, 0x65, 0x22, 0x37, 0x1e, 0xe4, 0xb8, 0xff, 0x45, 0xef, 0x74,
+  0x58, 0x40, 0xad, 0x7e, 0xab, 0xe6, 0x7a, 0x7c, 0x66, 0x02, 0x8a, 0xe4,
+  0xc9, 0xae, 0x4d, 0x57, 0x58, 0x40, 0xe6, 0x88, 0x7e, 0x4f, 0x1f, 0xdb,
+  0x4b, 0x8c, 0x12, 0xb2, 0x24, 0x55, 0xbe, 0x5a, 0x16, 0xc1, 0x75, 0xf7,
+  0x57, 0x7e, 0xd7, 0x8c, 0xff, 0xf9, 0x2e, 0xae, 0xb7, 0xab, 0xb4, 0x1a,
+  0x18, 0x75, 0xeb, 0x7e, 0xa0, 0x2e, 0x55, 0xde, 0x11, 0x82, 0x37, 0x66,
+  0x7f, 0x4f, 0xe6, 0xea, 0x5c, 0x76, 0x54, 0x44, 0x97, 0x73, 0x52, 0x22,
+  0x2e, 0x39, 0x93, 0x03, 0x40, 0x43, 0xa7, 0x4c, 0x5f, 0xf5, 0x70, 0x3a,
+  0x05, 0xc7, 0x31, 0x0c, 0xeb, 0x2a, 0x3a, 0x19, 0x45, 0x19, 0x08, 0x10,
+  0xab, 0xd4, 0x6a, 0x4e, 0xc3, 0x94, 0xb1, 0x84, 0xfa, 0xf4, 0x3c, 0xd9,
+  0xfb, 0x94, 0xc6, 0xf1, 0xb8, 0xf1, 0xbc, 0x2e, 0xab, 0x89, 0xcd, 0x29,
+  0x86, 0x8d, 0xe0, 0x25, 0x98, 0x72, 0x5a, 0x04, 0x6a, 0xae, 0xf1, 0xec,
+  0x2a, 0x28, 0x16, 0xa0, 0x3d, 0x32, 0x4a, 0x24, 0x9e, 0x0e, 0x77, 0x14,
+  0x02, 0xdc, 0xac, 0x16, 0xd1, 0x5d, 0x23, 0xf3, 0xe2, 0x55, 0x28, 0xad,
+  0x6c, 0x02, 0x2a, 0x4f, 0x03, 0xb9, 0x44, 0xcc, 0x5e, 0xbb, 0xcb, 0xa7,
+  0x50, 0xa5, 0x1d, 0xd7, 0x9c, 0x59, 0x2f, 0xde, 0x7c, 0x8c, 0x95, 0x46,
+  0xcc, 0x12, 0xc1, 0x4e, 0xdb, 0x33, 0x51, 0x60, 0x68, 0x5a, 0x4b, 0x78,
+  0x14, 0xb6, 0xa0, 0x3f, 0x50, 0x7e, 0xb3, 0x8b, 0x0b, 0x90, 0xfd, 0x44,
+  0xa2, 0xb9, 0xe7, 0xbe, 0x42, 0xb9, 0x02, 0x4d, 0x33, 0x53, 0x67, 0xc2,
+  0x1b, 0xbb, 0xb1, 0xdb, 0x63, 0x26, 0xa6, 0x16, 0x6f, 0xd8, 0x7b, 0xbb,
+  0x46, 0x69, 0x9d, 0x95, 0xe3, 0x4e, 0xc9, 0xfa, 0xd0, 0x12, 0xc5, 0xb0,
+  0x06, 0x98, 0x9d, 0xbd, 0xdd, 0x6f, 0x57, 0xcf, 0x3a, 0x38, 0xf4, 0xd7,
+  0xbe, 0xbc, 0xff, 0x74, 0xcd, 0xa2, 0x9d, 0x55, 0x30, 0xc6, 0x33, 0xc5,
+  0x40, 0x42, 0x11, 0x74, 0x91, 0x97, 0x60, 0xd9, 0xcc, 0xc6, 0xcf, 0xae,
+  0x53, 0x54, 0xfe, 0x5d, 0xd3, 0x7b, 0xcd, 0x09, 0xe9, 0x74, 0xe5, 0x8d,
+  0xa0, 0xb2, 0xf9, 0x97, 0x35, 0xb9, 0xc5, 0x16, 0x60, 0xda, 0x73, 0xb6,
+  0xab, 0x4d, 0x27, 0x67, 0x6e, 0x06, 0xef, 0x6d, 0x96, 0x9c, 0xfd, 0xb6,
+  0x90, 0xd0, 0xdd, 0x53, 0x65, 0xd7, 0x4b, 0x66, 0xc2, 0x28, 0xd9, 0xd6,
+  0x27, 0x62, 0x6a, 0x39, 0xaf, 0x46, 0x36, 0x13, 0x7c, 0x88, 0xf7, 0x13,
+  0x04, 0xef, 0x24, 0x55, 0x95, 0x55, 0x8a, 0xf7, 0x76, 0x2e, 0x06, 0x72,
+  0xca, 0x4e, 0xca, 0xb9, 0x54, 0xff, 0xe4, 0xe3, 0x55, 0x78, 0x89, 0xfd,
+  0xcc, 0xbc, 0x38, 0x44, 0xa6, 0x2f, 0x6f, 0x14, 0x2b, 0xec, 0x29, 0xad,
+  0x8c, 0xa2, 0x61, 0x0d, 0x87, 0x05, 0xd0, 0x40, 0x5f, 0x76, 0x2d, 0x5a,
+  0xb2, 0x9f, 0x22, 0x89, 0x5f, 0x2b, 0x03, 0x26, 0x33, 0xe5, 0x93, 0xb3,
+  0xff, 0xe8, 0xec, 0xed, 0xeb, 0x93, 0xaf, 0x2d, 0x95, 0x11, 0x0b, 0xf1,
+  0x16, 0xc5, 0x06, 0xbb, 0x8f, 0xfd, 0x48, 0xb7, 0x14, 0x55, 0x15, 0xf4,
+  0xad, 0x11, 0x4f, 0xef, 0xfd, 0x1f, 0x40, 0x80, 0x14, 0x4f, 0xc8, 0x41,
+  0xce, 0xfc, 0x1f, 0xf5, 0xb6, 0x73, 0x37, 0x74, 0xa8, 0xea, 0x38, 0x4b,
+  0x23, 0xad, 0x9a, 0xe5, 0xc2, 0x82, 0x08, 0xbd, 0xa2, 0xac, 0xc2, 0xa3,
+  0xad, 0xa9, 0xe8, 0xcb, 0x05, 0x8b, 0x26, 0x49, 0x28, 0x6d, 0x79, 0x73,
+  0xf9, 0x0e, 0x20, 0x77, 0x82, 0x70, 0xa9, 0xc8, 0x05, 0x10, 0xe0, 0x72,
+  0x66, 0xc4, 0xbe, 0xe9, 0xe3, 0xe5, 0x35, 0x7e, 0x33, 0x4d, 0xeb, 0x1b,
+  0x1e, 0x28, 0x2e, 0x8d, 0x9c, 0x61, 0xda, 0x88, 0xb5, 0xa5, 0x53, 0x32,
+  0xd4, 0x1d, 0x18, 0xc7, 0xa2, 0x7f, 0x5d, 0x7c, 0xa8, 0x4e, 0x34, 0xeb,
+  0xc1, 0xe2, 0x93, 0x34, 0x8d, 0x35, 0x45, 0xa8, 0x12, 0xb1, 0x4e, 0xfc,
+  0xe4, 0x25, 0x85, 0x65, 0x0e, 0x88, 0x4f, 0x7e, 0xce, 0x84, 0x72, 0x7e,
+  0xfa, 0xa9, 0x48, 0x49, 0xc7, 0xfa, 0x7e, 0x72, 0xe5, 0x65, 0xb4, 0x31,
+  0x4e, 0x50, 0x37, 0x1d, 0xfb, 0x88, 0xc9, 0xc1, 0xb2, 0xf9, 0xc7, 0xcd,
+  0x41, 0x7d, 0x3f, 0x1f, 0x97, 0x33, 0x4d, 0xbc, 0xb0, 0x04, 0x12, 0xfa,
+  0x90, 0x5f, 0x30, 0x2f, 0xe1, 0x48, 0x6d, 0xe3, 0xb9, 0x25, 0x1d, 0x56,
+  0xca, 0xf5, 0x9f, 0x8b, 0x19, 0x21, 0x3c, 0xa4, 0xa3, 0x00, 0xb7, 0x0f,
+  0xc9, 0xf8, 0xac, 0x98, 0xcc, 0x4a, 0xd9, 0xd5, 0x94, 0x60, 0x8e, 0x99,
+  0x6a, 0x0f, 0x9d, 0x22, 0x7e, 0xe5, 0x92, 0x3c, 0x1c, 0xa8, 0x1f, 0x62,
+  0xd4, 0x9d, 0x9e, 0x30, 0x6a, 0x60, 0x80, 0xf4, 0x36, 0xff, 0x42, 0x50,
+  0xf9, 0x1e, 0xbf, 0x0d, 0x17, 0x1c, 0x31, 0x5d, 0xfd, 0x89, 0x1d, 0x8a,
+  0x1c, 0xf7, 0xfb, 0xab, 0x7e, 0x5c, 0x1f, 0xed, 0x4c, 0xbd, 0xd9, 0x4f,
+  0x69, 0x75, 0x2d, 0x2c, 0x7d, 0x12, 0x49, 0x83, 0x91, 0x68, 0xcb, 0xda,
+  0x58, 0xc7, 0x24, 0x29, 0x25, 0x16, 0x35, 0x03, 0xf5, 0x69, 0xc9, 0x39,
+  0x85, 0x92, 0x71, 0xc5, 0x2e, 0x49, 0xbb, 0x11, 0x3d, 0x89, 0xf3, 0x47,
+  0x8b, 0x45, 0x49, 0xdd, 0x5d, 0xa6, 0xd5, 0x29, 0x9c, 0x7f, 0x56, 0x2e,
+  0x33, 0xef, 0x35, 0x72, 0xe2, 0xc1, 0x12, 0xce, 0xc4, 0x71, 0xc2, 0x9f,
+  0xd2, 0x4a, 0xf7, 0x5a, 0x3f, 0xd2, 0x35, 0xc1, 0xbf, 0x7f, 0x29, 0x75,
+  0xca, 0xcc, 0x79, 0x16, 0xa6, 0x14, 0xa1, 0x0f, 0xfc, 0x74, 0x57, 0xdc,
+  0x6f, 0x8d, 0xc0, 0x55, 0xeb, 0xe4, 0xf0, 0xe2, 0xd8, 0x68, 0xb6, 0xd7,
+  0x05, 0x38, 0x2a, 0x8a, 0x46, 0x93, 0xea, 0xb2, 0x42, 0x0a, 0xa3, 0x15,
+  0x7a, 0x3e, 0xe8, 0x83, 0x77, 0xde, 0x9b, 0xb4, 0x99, 0x04, 0x18, 0xc0,
+  0xf9, 0xdb, 0x6e, 0xcb, 0x4d, 0x94, 0x17, 0x18, 0x52, 0x87, 0x68, 0x12,
+  0x78, 0x4b, 0x51, 0x88, 0xc4, 0x7c, 0xaa, 0x54, 0x4e, 0xe0, 0xf3, 0x40,
+  0xac, 0xfb, 0x64, 0xc0, 0x3a, 0xd7, 0x38, 0xd5, 0x2e, 0x15, 0xe1, 0xef,
+  0x4a, 0xcc, 0x29, 0xdf, 0x6a, 0x85, 0x3d, 0xdd, 0x76, 0xea, 0xc7, 0x5d,
+  0x46, 0x7f, 0xc7, 0x3d, 0x43, 0xba, 0x48, 0x57, 0x2f, 0xc8, 0x2c, 0xc2,
+  0x9e, 0xbd, 0xd7, 0x53, 0x4f, 0xf9, 0xe5, 0x14, 0x40, 0xc2, 0x58, 0xb3,
+  0x63, 0x5a, 0x98, 0x80, 0xc4, 0xaf, 0xc3, 0xe6, 0xc0, 0x54, 0xce, 0x2a,
+  0xed, 0x0a, 0x82, 0x0b, 0x8f, 0x89, 0x2d, 0xe9, 0x03, 0x2b, 0x00, 0xbe,
+  0x7c, 0x8a, 0xfa, 0x76, 0xff, 0x68, 0x47, 0xeb, 0xfa, 0xb0, 0xe1, 0xd5,
+  0x55, 0x37, 0x4b, 0xaa, 0xec, 0x76, 0xd4, 0x8b, 0x21, 0x7d, 0x08, 0x22,
+  0x15, 0x31, 0x53, 0xfa, 0x0b, 0x7e, 0x0c, 0xd4, 0x9b, 0xd2, 0x9d, 0x42,
+  0xea, 0x58, 0x0a, 0xad, 0x52, 0x62, 0xaa, 0xae, 0x23, 0x1c, 0xd8, 0x83,
+  0x84, 0x1e, 0xfb, 0xaa, 0xf1, 0xe0, 0xdb, 0x1d, 0xad, 0x67, 0x4d, 0xfe,
+  0x1b, 0x4a, 0x20, 0xd6, 0x03, 0x5f, 0x67, 0xad, 0x02, 0xd8, 0x36, 0x53,
+  0xa8, 0x37, 0xe8, 0x99, 0xb9, 0xd8, 0x9c, 0xcd, 0x9c, 0xc0, 0xd7, 0xc7,
+  0x68, 0x55, 0x91, 0x54, 0xe7, 0x14, 0x26, 0x91, 0x5d, 0x54, 0x54, 0xe3,
+  0xbe, 0x95, 0xe2, 0x40, 0x65, 0xea, 0x28, 0x03, 0xc8, 0x12, 0x7b, 0x21,
+  0x4d, 0x04, 0x20, 0x81, 0xdb, 0xbc, 0xd6, 0xe0, 0xa3, 0xd9, 0xdb, 0x13,
+  0xc6, 0x44, 0x34, 0x4c, 0x48, 0x90, 0x35, 0x13, 0x6f, 0x2a, 0xb3, 0xc9,
+  0x4d, 0xc9, 0x98, 0x5a, 0x33, 0x69, 0x5e, 0xa6, 0x67, 0x2f, 0xf9, 0x5f,
+  0xb2, 0x07, 0xbe, 0x75, 0x49, 0x7b, 0xb4, 0x11, 0x86, 0xcc, 0x43, 0x39,
+  0x74, 0x1b, 0xe2, 0xf8, 0x87, 0xcb, 0x8b, 0xc3, 0xe4, 0x9b, 0xe3, 0xc3,
+  0x57, 0xc7, 0x17, 0xa3, 0xce, 0xa5, 0x2f, 0xf0, 0x0f, 0xd6, 0xd0, 0xc8,
+  0x09, 0x0c, 0xd5, 0x58, 0x89, 0x07, 0x04, 0xb7, 0xaf, 0x52, 0xcf, 0x6c,
+  0x1e, 0x3a, 0x48, 0xe6, 0x7c, 0x90, 0x41, 0xc4, 0xd1, 0x02, 0x10, 0x18,
+  0xd7, 0x10, 0x36, 0xb6, 0x8d, 0x89, 0x91, 0x50, 0x04, 0x62, 0x50, 0x97,
+  0xb9, 0x9f, 0x31, 0xe3, 0xb8, 0xfa, 0xdc, 0x65, 0x32, 0x2d, 0x35, 0x19,
+  0xb0, 0xbd, 0x72, 0xdf, 0xb8, 0x7c, 0x6f, 0x4f, 0x6c, 0xc9, 0x25, 0x23,
+  0x5e, 0xc3, 0xde, 0x0f, 0x03, 0xf3, 0xdd, 0x81, 0x99, 0xfc, 0x01, 0x91,
+  0x39, 0xde, 0x67, 0x75, 0xaf, 0xe3, 0x02, 0x6c, 0x7f, 0x7e, 0x83, 0x2b,
+  0x31, 0x05, 0x27, 0xe9, 0x9b, 0x68, 0x4b, 0x74, 0xba, 0x66, 0x54, 0x1f,
+  0xa9, 0x6b, 0x41, 0xe0, 0x52, 0xf5, 0x94, 0x64, 0x39, 0x41, 0x41, 0x7a,
+  0x8b, 0x00, 0x94, 0x9c, 0x99, 0x29, 0x78, 0x30, 0x74, 0x44, 0x86, 0x00,
+  0x5d, 0xc7, 0x9c, 0x3d, 0xbe, 0xd4, 0x67, 0xcc, 0xb5, 0xcc, 0x1e, 0x33,
+  0xd3, 0x2d, 0x79, 0xc8, 0xbf, 0x1f, 0x10, 0x00, 0x11, 0x0c, 0x7e, 0xdd,
+  0x8a, 0x8f, 0x8a, 0x33, 0x54, 0x68, 0xb8, 0xa5, 0x39, 0xea, 0x83, 0xdd,
+  0xf3, 0x0a, 0xdd, 0xa7, 0x4f, 0x6a, 0x85, 0x10, 0x79, 0x97, 0x51, 0x60,
+  0x64, 0xd4, 0xc3, 0xbf, 0xc9, 0x75, 0x67, 0xb9, 0xf8, 0x24, 0x0b, 0x36,
+  0x2f, 0x17, 0xc8, 0xdf, 0xcc, 0x28, 0xcd, 0x06, 0xf4, 0xb8, 0x7d, 0x2e,
+  0x4b, 0xbe, 0x29, 0x6b, 0xdc, 0x05, 0xe1, 0xe3, 0x74, 0xc9, 0xc7, 0xa6,
+  0x1f, 0x6f, 0x48, 0x7c, 0xcb, 0x92, 0xc4, 0x6e, 0x6c, 0x68, 0x4a, 0xd5,
+  0xf9, 0xe1, 0xe5, 0x37, 0x88, 0xae, 0x62, 0x0b, 0xbf, 0x02, 0x63, 0x8a,
+  0xc6, 0xd4, 0xc2, 0x94, 0x2c, 0x6b, 0xc0, 0xb1, 0xfe, 0xab, 0xc4, 0x8c,
+  0xaa, 0x4f, 0x22, 0x7a, 0x97, 0x33, 0x10, 0x69, 0xc6, 0xb5, 0x7e, 0x21,
+  0xa3, 0x5b, 0x95, 0x18, 0x01, 0x7d, 0xb7, 0xf9, 0x76, 0x16, 0x6f, 0xb9,
+  0xc9, 0x89, 0xf0, 0x9b, 0x3c, 0x26, 0x6c, 0x7a, 0x52, 0xe6, 0x36, 0x92,
+  0x36, 0xf3, 0x30, 0x7e, 0x41, 0x99, 0xce, 0x1c, 0x80, 0x9a, 0x96, 0x71,
+  0xde, 0x43, 0xef, 0x48, 0x7f, 0x39, 0xbf, 0x1f, 0x86, 0x04, 0x3c, 0xc9,
+  0x57, 0xcb, 0xa6, 0x2d, 0x56, 0x3a, 0xfc, 0xc7, 0x56, 0xb3, 0xac, 0xca,
+  0xb2, 0xf1, 0xfa, 0x00, 0xed, 0x27, 0x6d, 0xe4, 0x44, 0x33, 0xc1, 0x25,
+  0xf7, 0x85, 0x9a, 0x2a, 0x44, 0xef, 0xf6, 0x15, 0xc3, 0x74, 0x5c, 0x97,
+  0xb3, 0x65, 0xe3, 0xa1, 0xaf, 0x7f, 0x59, 0x9f, 0xbd, 0x4e, 0x6f, 0x9d,
+  0x0c, 0x95, 0xec, 0xb3, 0x60, 0x8a, 0x3a, 0x63, 0xe9, 0x1b, 0xf5, 0x12,
+  0xc1, 0xc6, 0xaa, 0x2c, 0xda, 0x35, 0xe0, 0x00, 0xf4, 0xde, 0xde, 0xd8,
+  0x18, 0xe9, 0x62, 0x13, 0xdd, 0x6b, 0xb8, 0xe8, 0xdf, 0x43, 0x9b, 0xa4,
+  0x3e, 0x70, 0xb0, 0x60, 0x62, 0xfe, 0xa2, 0x24, 0x70, 0x19, 0xaf, 0x29,
+  0x44, 0x38, 0xaf, 0x71, 0x5e, 0xb7, 0x07, 0x85, 0x5f, 0xd9, 0x70, 0x85,
+  0xe6, 0x97, 0x5d, 0x96, 0xca, 0xc9, 0x2f, 0xe1, 0x3a, 0xb7, 0x21, 0x5a,
+  0xd9, 0xf0, 0x51, 0x86, 0x69, 0xba, 0x04, 0xb4, 0x82, 0xb4, 0x85, 0xe3,
+  0x52, 0x27, 0x77, 0xfe, 0xf7, 0x4e, 0xd2, 0xe7, 0xea, 0x04, 0x11, 0xd2,
+  0x9e, 0x65, 0xf2, 0xff, 0x01, 0xf0, 0x4a, 0xe8, 0x7d, 0xa9, 0xcd, 0x61,
+  0x9b, 0x40, 0x76, 0x68, 0x4c, 0xa8, 0x9b, 0x6a, 0xe2, 0x76, 0xbf, 0xd1,
+  0x0e, 0xb2, 0x3b, 0xb2, 0x5f, 0xd4, 0x46, 0x10, 0xba, 0x10, 0x2e, 0xe2,
+  0x6c, 0x09, 0x98, 0x40, 0xb7, 0x71, 0x65, 0xbd, 0x7a, 0x54, 0x4f, 0x95,
+  0xab, 0x8e, 0xb2, 0x5a, 0x8f, 0x72, 0x4a, 0x1a, 0x36, 0xdd, 0x48, 0x5a,
+  0x76, 0x3b, 0x95, 0x23, 0xe4, 0x3f, 0x35, 0xe9, 0x48, 0x80, 0x5d, 0xb2,
+  0xfd, 0xbd, 0x12, 0x7d, 0x5e, 0xb1, 0x63, 0x45, 0x9c, 0x32, 0x9a, 0x4e,
+  0xc3, 0x91, 0xda, 0x49, 0xd5, 0x02, 0x28, 0x5a, 0x09, 0x5a, 0x4b, 0x61,
+  0x1e, 0x21, 0x24, 0x19, 0x71, 0x18, 0x73, 0xd2, 0x36, 0x15, 0x93, 0x54,
+  0x4b, 0x46, 0xaf, 0x54, 0x4d, 0xe3, 0xb0, 0x2b, 0xe5, 0xba, 0x2f, 0x77,
+  0x3f, 0x92, 0xf0, 0x11, 0x99, 0xa3, 0xf2, 0x99, 0xbe, 0x4a, 0xa0, 0x43,
+  0x92, 0x7a, 0xbe, 0x0c, 0xde, 0xf0, 0x01, 0x29, 0x0e, 0xb1, 0x79, 0x4d,
+  0x59, 0x1e, 0xe2, 0x92, 0x12, 0x2e, 0x13, 0xf8, 0xbf, 0x6e, 0x72, 0xc1,
+  0x95, 0xf2, 0xac, 0xb7, 0x6b, 0xa8, 0xc2, 0xc3, 0x47, 0x90, 0x02, 0x17,
+  0x55, 0xb5, 0xc0, 0x87, 0x61, 0x78, 0x60, 0x86, 0x96, 0x55, 0x55, 0x2e,
+  0x91, 0x13, 0x3f, 0xa7, 0x9c, 0x51, 0x18, 0x16, 0xeb, 0xfc, 0xc8, 0xaf,
+  0xfb, 0x9f, 0x24, 0x10, 0x6b, 0x91, 0x70, 0x02, 0x89, 0x50, 0xc5, 0xd1,
+  0x85, 0xb2, 0xbf, 0x07, 0xc3, 0x94, 0x31, 0x1b, 0xe0, 0x29, 0xd5, 0x16,
+  0x94, 0x2f, 0xad, 0x3b, 0xf9, 0xdb, 0x7d, 0x99, 0x25, 0x9b, 0x71, 0x2f,
+  0x21, 0x66, 0xd6, 0x0b, 0xbd, 0xb8, 0x53, 0xab, 0x08, 0x1c, 0x67, 0x71,
+  0xd7, 0x4d, 0xb5, 0x9c, 0x34, 0x41, 0xf9, 0xd2, 0x56, 0x68, 0xde, 0xce,
+  0x71, 0xe9, 0xdb, 0xf6, 0x27, 0xe7, 0x62, 0xde, 0xb3, 0xf5, 0x41, 0x3d,
+  0xdb, 0x4a, 0x5b, 0x49, 0x2e, 0xfc, 0xf2, 0x46, 0xd2, 0xfa, 0xee, 0xb6,
+  0xdd, 0x65, 0x83, 0x73, 0x9b, 0x51, 0xdf, 0xa6, 0x3f, 0x42, 0x76, 0x82,
+  0x77, 0xf7, 0x8a, 0x22, 0x06, 0xc5, 0xa3, 0x4a, 0x84, 0x7c, 0x11, 0x6a,
+  0x0d, 0xb9, 0x2c, 0x37, 0x2c, 0x41, 0xa2, 0xe9, 0xd2, 0x40, 0xa0, 0xaa,
+  0x1c, 0xfd, 0xdd, 0x31, 0x13, 0xa9, 0x95, 0x7e, 0x6c, 0x89, 0xab, 0xda,
+  0x91, 0x2c, 0x76, 0x70, 0xaa, 0xa0, 0x68, 0xb2, 0xfa, 0xa1, 0x90, 0xc5,
+  0xc9, 0xfc, 0x0d, 0x93, 0x57, 0x72, 0x28, 0xe4, 0x0b, 0x5d, 0x75, 0x22,
+  0xbc, 0x1b, 0xcf, 0x99, 0x0a, 0x25, 0xd8, 0x47, 0xaf, 0xd4, 0xa7, 0x0a,
+  0x91, 0x83, 0xb9, 0x21, 0xcb, 0x46, 0x17, 0xc9, 0xcc, 0xab, 0x7e, 0xc2,
+  0x74, 0x81, 0x46, 0xbc, 0x39, 0xcb, 0x76, 0x37, 0xbd, 0x1a, 0x5d, 0x5b,
+  0x0c, 0xfa, 0x2f, 0x61, 0xfd, 0x58, 0xb2, 0x42, 0xf6, 0x5e, 0x10, 0xb8,
+  0x6d, 0x3b, 0xd2, 0x15, 0xd3, 0xc4, 0x2f, 0xed, 0xcc, 0xde, 0x67, 0xfb,
+  0xc3, 0xbd, 0xe7, 0x9f, 0x0e, 0x77, 0x87, 0x7b, 0xbb, 0x24, 0x5f, 0xa8,
+  0x2b, 0x5e, 0xe7, 0x78, 0x5e, 0x22, 0x9f, 0x6a, 0xbd, 0x17, 0x7e, 0xf3,
+  0xed, 0xf1, 0xe5, 0xf7, 0x67, 0x17, 0xdf, 0x26, 0x27, 0x6f, 0x2f, 0x8f,
+  0x2f, 0x5e, 0x1f, 0x1e, 0x3d, 0x96, 0xb0, 0xdf, 0x77, 0x5b, 0x7b, 0x35,
+  0xcb, 0x33, 0x37, 0x31, 0xa1, 0x6f, 0xd0, 0xcd, 0x59, 0xd6, 0xdc, 0xec,
+  0x1e, 0xec, 0xad, 0xa5, 0xa4, 0x8e, 0xb8, 0x07, 0xdd, 0xfb, 0x3a, 0xa8,
+  0x3d, 0x1a, 0xd4, 0xea, 0x56, 0x2c, 0x35, 0xe3, 0x88, 0xb1, 0x55, 0x16,
+  0x97, 0x0b, 0x31, 0x8f, 0x2a, 0x48, 0x60, 0x64, 0x15, 0xc1, 0x3e, 0x66,
+  0xf2, 0x5b, 0x4e, 0xaf, 0x15, 0x92, 0x19, 0xc1, 0xa0, 0x8b, 0xcc, 0xdd,
+  0xe0, 0xfa, 0xe0, 0x8d, 0xb8, 0x53, 0x98, 0xce, 0x76, 0x0a, 0x15, 0x4f,
+  0xa5, 0xb2, 0xe4, 0xae, 0xd1, 0x6e, 0x91, 0x0a, 0xa5, 0x4c, 0x38, 0x38,
+  0xb5, 0x79, 0x22, 0x96, 0x85, 0x00, 0xd0, 0x07, 0xd5, 0xd3, 0xd1, 0xd7,
+  0x76, 0x89, 0x77, 0x1f, 0x3e, 0xdb, 0xe1, 0x5e, 0xad, 0x15, 0xd7, 0x8c,
+  0x81, 0xb5, 0x5c, 0xa3, 0x47, 0xd2, 0x11, 0x9c, 0x06, 0xaf, 0x37, 0xfc,
+  0x29, 0x28, 0x54, 0x44, 0x92, 0x06, 0x7a, 0xc8, 0x16, 0x43, 0x32, 0xdf,
+  0x51, 0xc8, 0x9d, 0x60, 0xfd, 0x4f, 0xcb, 0x5a, 0x50, 0xeb, 0x75, 0x8b,
+  0xa4, 0x30, 0xe1, 0xca, 0x54, 0xfe, 0xeb, 0xac, 0x6a, 0x03, 0x9d, 0x39,
+  0xad, 0xd2, 0x3b, 0x94, 0x57, 0xc9, 0x1d, 0xe5, 0xe8, 0x46, 0xd2, 0x2a,
+  0xaf, 0x45, 0x8a, 0x93, 0x9b, 0xf3, 0xe4, 0xfc, 0xf8, 0xcd, 0x40, 0x0b,
+  0x1c, 0x9b, 0xbf, 0xb3, 0x33, 0x4a, 0xf9, 0x25, 0x39, 0xb7, 0x67, 0x91,
+  0x15, 0x8a, 0xa5, 0x81, 0x4c, 0x14, 0xf0, 0x8f, 0x3f, 0x00, 0x3a, 0x34,
+  0x96, 0x81, 0x52, 0x20, 0xa3, 0x8a, 0xb9, 0xe4, 0xdc, 0xc2, 0x2e, 0x2d,
+  0x27, 0xad, 0xa7, 0x00, 0x96, 0x93, 0x2d, 0x0b, 0xd2, 0xa5, 0xef, 0x01,
+  0x89, 0x0a, 0xd4, 0x80, 0x85, 0x09, 0x94, 0x9a, 0x79, 0x7d, 0xfe, 0xed,
+  0xd1, 0xe8, 0x8f, 0x7b, 0xfb, 0xd2, 0x9d, 0x6d, 0xb5, 0x0a, 0x48, 0x56,
+  0x75, 0x93, 0xf2, 0x21, 0xae, 0xfd, 0x3e, 0x6a, 0x8a, 0x35, 0x0e, 0x38,
+  0x16, 0x63, 0xcb, 0x26, 0x06, 0x6d, 0xb7, 0x32, 0x83, 0x80, 0xfc, 0xba,
+  0xb7, 0x2a, 0xa6, 0x2d, 0xda, 0x4b, 0x21, 0x11, 0x94, 0x77, 0x92, 0x02,
+  0x4b, 0x8d, 0x85, 0xfa, 0xa5, 0x85, 0xfe, 0x88, 0x5b, 0x96, 0xd6, 0x90,
+  0x43, 0xee, 0xe0, 0x2c, 0xdd, 0x35, 0xa7, 0xf9, 0x76, 0xbf, 0x25, 0x9e,
+  0x58, 0xb9, 0xd9, 0x95, 0x10, 0xc8, 0x7d, 0x06, 0x07, 0x40, 0xd0, 0xeb,
+  0x53, 0x2d, 0xe1, 0x56, 0xb8, 0x3a, 0x28, 0xf4, 0xf4, 0x99, 0x59, 0x28,
+  0x73, 0xb2, 0x98, 0xb7, 0x81, 0x84, 0x42, 0x39, 0x23, 0xd3, 0xc5, 0x3e,
+  0xf2, 0xaa, 0xa2, 0xd2, 0x31, 0x0b, 0xc6, 0x91, 0xbe, 0x1d, 0x26, 0xdf,
+  0x64, 0x05, 0x25, 0xce, 0x13, 0xe2, 0x4e, 0x73, 0xaf, 0x80, 0x0b, 0xa4,
+  0x1a, 0x92, 0xa8, 0xa9, 0x77, 0x9a, 0xa5, 0xc2, 0xc9, 0x69, 0x64, 0x5d,
+  0xcd, 0x16, 0xae, 0xd6, 0x93, 0x4a, 0x09, 0x9d, 0x27, 0x04, 0xa2, 0x96,
+  0xec, 0x82, 0x49, 0xa2, 0xa9, 0x81, 0xad, 0x36, 0xb1, 0x26, 0x4a, 0x22,
+  0xa0, 0x39, 0x39, 0xe6, 0x88, 0x35, 0x89, 0x57, 0xf9, 0x06, 0x74, 0xda,
+  0xe4, 0x2d, 0x64, 0x8b, 0xcb, 0x09, 0x95, 0x69, 0x75, 0x43, 0xae, 0x8f,
+  0xda, 0x5c, 0x37, 0x69, 0x31, 0xb9, 0x1f, 0x4e, 0x8d, 0x2e, 0x4b, 0xce,
+  0xb3, 0xe1, 0xf2, 0xc3, 0x8e, 0x77, 0x4c, 0x49, 0xe4, 0xdf, 0x30, 0x47,
+  0x40, 0xdb, 0xf1, 0xad, 0x85, 0x8a, 0x43, 0xea, 0xb0, 0xb4, 0x75, 0x26,
+  0x68, 0x4b, 0x68, 0xb6, 0x3f, 0x1f, 0xcf, 0x95, 0x24, 0x5b, 0xc7, 0x89,
+  0x65, 0x38, 0xa6, 0x16, 0x86, 0x8b, 0x6c, 0x7e, 0x60, 0xb3, 0x91, 0x55,
+  0x3e, 0x48, 0x55, 0x0d, 0x6b, 0x58, 0x78, 0x4e, 0xda, 0x22, 0xbb, 0x9e,
+  0x89, 0x42, 0xe1, 0x9b, 0x2e, 0xb6, 0x89, 0x48, 0x0a, 0x08, 0x1b, 0x3c,
+  0x52, 0xed, 0x08, 0x1a, 0xbb, 0xd9, 0x87, 0x8d, 0x40, 0x6a, 0xf9, 0xe1,
+  0x8a, 0x14, 0x7a, 0xd7, 0x88, 0x30, 0x87, 0x80, 0x6c, 0x99, 0x94, 0x61,
+  0x71, 0xf1, 0x28, 0x12, 0x49, 0xc2, 0x4f, 0x44, 0x04, 0x8b, 0x1d, 0x02,
+  0x1a, 0x77, 0x41, 0x45, 0x23, 0xf8, 0xa9, 0xf5, 0x80, 0xf9, 0xac, 0x98,
+  0x5f, 0xdf, 0x3e, 0x21, 0x8f, 0xf7, 0xe5, 0xe9, 0x48, 0xa3, 0x22, 0x45,
+  0x76, 0xe7, 0x6d, 0x2d, 0x2e, 0x3d, 0x20, 0xfb, 0x8f, 0x1c, 0x40, 0x4c,
+  0xa9, 0x0c, 0xb6, 0x03, 0xf4, 0x84, 0xa5, 0x82, 0x0b, 0x93, 0xb9, 0xe4,
+  0x07, 0x9d, 0x04, 0x81, 0x11, 0x53, 0x57, 0xb4, 0x74, 0x19, 0x2b, 0x43,
+  0x96, 0xe9, 0x85, 0xb8, 0xfb, 0x8c, 0xb2, 0xf4, 0xa4, 0x9f, 0x0c, 0xf6,
+  0xc1, 0x9f, 0xb3, 0xd7, 0x9e, 0xc4, 0xb4, 0x61, 0x9a, 0x40, 0x6a, 0xc3,
+  0xb4, 0xa4, 0xad, 0x88, 0x38, 0xd8, 0x92, 0x2d, 0x7d, 0x6b, 0xde, 0xa7,
+  0x3f, 0xf6, 0x65, 0x40, 0xb7, 0x7b, 0x40, 0x6c, 0x33, 0x6f, 0xe5, 0xec,
+  0x3e, 0x54, 0x19, 0xf6, 0xd7, 0xae, 0x2a, 0x72, 0x23, 0xee, 0x72, 0x4b,
+  0x20, 0xcd, 0x45, 0x13, 0xe0, 0x0a, 0x15, 0x4a, 0x50, 0xed, 0x80, 0x99,
+  0x42, 0x71, 0x72, 0x17, 0xc9, 0xed, 0xbe, 0xc6, 0x9a, 0xe9, 0x37, 0x3a,
+  0x6f, 0xec, 0xac, 0x77, 0x42, 0x24, 0x48, 0x5b, 0x24, 0x94, 0x9b, 0xb7,
+  0x6b, 0x29, 0xeb, 0xc9, 0xec, 0x59, 0x23, 0x45, 0x5a, 0x52, 0xa6, 0x2c,
+  0xc4, 0xad, 0xc0, 0x29, 0xef, 0xcc, 0x47, 0x4f, 0x06, 0xbc, 0x07, 0x73,
+  0x02, 0xf2, 0xdb, 0x43, 0x44, 0x9e, 0x14, 0x36, 0x51, 0x42, 0x5c, 0xf9,
+  0xa0, 0xe8, 0xc3, 0xf2, 0xdf, 0xe4, 0xec, 0x98, 0x00, 0xd6, 0x14, 0xd7,
+  0xb9, 0x39, 0xf9, 0x9b, 0x89, 0x39, 0x4c, 0x4b, 0x92, 0xf8, 0x8d, 0xad,
+  0xa3, 0x36, 0x62, 0x6a, 0xcf, 0x4d, 0x5f, 0xcc, 0x0d, 0xbe, 0xa0, 0xa1,
+  0xd4, 0x9b, 0x6e, 0xec, 0x42, 0x71, 0xde, 0x1e, 0x88, 0xc4, 0x39, 0xb4,
+  0x72, 0xd8, 0x79, 0xa5, 0xc5, 0xd1, 0x37, 0x8f, 0x3f, 0x92, 0x8e, 0xb3,
+  0x29, 0x5f, 0xe2, 0x5f, 0x73, 0x4e, 0x3f, 0xe6, 0xe8, 0xfc, 0xe4, 0x2d,
+  0x97, 0xfb, 0xb6, 0x67, 0x21, 0x23, 0xea, 0xc5, 0x0d, 0xae, 0x2b, 0x8f,
+  0xfe, 0xa4, 0xca, 0x01, 0xcf, 0x8e, 0x23, 0xda, 0x33, 0xb4, 0xc7, 0x73,
+  0xf9, 0xd6, 0xc5, 0x92, 0xbf, 0xbe, 0x49, 0xf7, 0x5c, 0x5d, 0xcf, 0x36,
+  0x3b, 0x65, 0x6c, 0xed, 0x9a, 0x74, 0x2e, 0x14, 0xeb, 0x91, 0x9a, 0x4c,
+  0x9d, 0x82, 0x8f, 0x32, 0xdd, 0xd4, 0x4a, 0x4b, 0xce, 0xf5, 0x3b, 0x99,
+  0x8e, 0xbe, 0x2b, 0xfc, 0x8f, 0xc9, 0x70, 0xc7, 0x7c, 0xb0, 0xde, 0xd1,
+  0x17, 0x17, 0x1f, 0x26, 0xb5, 0xb9, 0xe1, 0x28, 0xad, 0xf7, 0x47, 0x18,
+  0xe4, 0x58, 0x0e, 0xd3, 0xe3, 0xe9, 0xcf, 0xc9, 0x60, 0x32, 0xc3, 0xf8,
+  0x12, 0x14, 0xcb, 0xfe, 0xd1, 0xac, 0x3c, 0x3d, 0xf1, 0xb3, 0x5d, 0xc3,
+  0xd7, 0x39, 0x9d, 0xb7, 0x8f, 0x7d, 0x1d, 0xfa, 0x19, 0x1b, 0x0c, 0xcc,
+  0x6f, 0x9b, 0x1c, 0x4e, 0x6f, 0x29, 0xe9, 0x6e, 0x2a, 0xff, 0xa4, 0xf1,
+  0x1c, 0x17, 0x28, 0x35, 0x8a, 0x91, 0xa6, 0x63, 0xae, 0x2c, 0xfe, 0x5d,
+  0x6e, 0x8c, 0x8e, 0xa3, 0x8e, 0x7e, 0x41, 0xf9, 0x7f, 0xd4, 0x41, 0xbc,
+  0xe5, 0xfd, 0x52, 0x93, 0x39, 0xfa, 0x92, 0xb3, 0xe0, 0xa0, 0xa5, 0x24,
+  0x9d, 0x69, 0xe9, 0x86, 0xc9, 0x57, 0x14, 0xe3, 0xac, 0x32, 0x8f, 0xfd,
+  0x55, 0x2e, 0x3e, 0x2e, 0xc9, 0x47, 0x8b, 0x91, 0x32, 0xff, 0xc4, 0xd0,
+  0x8e, 0x24, 0xc8, 0x81, 0xb1, 0x63, 0xb2, 0xbf, 0x69, 0x0f, 0x0e, 0xfd,
+  0xd2, 0x94, 0x76, 0x33, 0x14, 0xcd, 0x97, 0x48, 0x82, 0xa1, 0x78, 0xbc,
+  0x94, 0xdc, 0x43, 0xbe, 0x30, 0xa7, 0x99, 0x26, 0xf6, 0x97, 0x3e, 0x9b,
+  0x8a, 0x7a, 0x8e, 0xd1, 0x94, 0x6a, 0x04, 0x76, 0x4b, 0xe0, 0x0e, 0x77,
+  0xbd, 0x3e, 0xba, 0x31, 0xa2, 0x39, 0xb3, 0x5d, 0x1d, 0xb1, 0x4b, 0x4f,
+  0xbb, 0x38, 0xa2, 0x3b, 0x4a, 0x17, 0xc1, 0xfe, 0x52, 0xb3, 0x23, 0xa1,
+  0x85, 0xee, 0xb0, 0xec, 0xb2, 0x7b, 0x97, 0x67, 0xb7, 0x3d, 0x04, 0x4a,
+  0x6a, 0x1c, 0xbd, 0x7b, 0x43, 0xa5, 0x4d, 0x50, 0x81, 0xfa, 0xf2, 0xe2,
+  0xf0, 0xed, 0xe8, 0x35, 0xbb, 0xc6, 0x2f, 0x4b, 0xaf, 0xb4, 0xb5, 0xc4,
+  0x15, 0x34, 0x7e, 0x6c, 0x69, 0xe2, 0xee, 0xb8, 0xde, 0x86, 0xe2, 0xe9,
+  0xa5, 0xee, 0x75, 0xbf, 0xcb, 0xb7, 0xcf, 0x45, 0xb3, 0x69, 0x36, 0xa8,
+  0x6b, 0x5b, 0xa3, 0x6d, 0xab, 0x08, 0xd5, 0x7e, 0x51, 0x36, 0x57, 0x75,
+  0x5e, 0x99, 0xa1, 0xe5, 0x21, 0x9a, 0x96, 0x23, 0xed, 0x8c, 0xfe, 0x94,
+  0xef, 0xde, 0x95, 0x64, 0xa4, 0x47, 0xc6, 0x54, 0x1c, 0x48, 0xa5, 0x1a,
+  0xc7, 0xc7, 0xe6, 0xdc, 0xa9, 0x7c, 0xf7, 0x0a, 0x95, 0x9f, 0x6d, 0xdc,
+  0xcf, 0xfb, 0xd4, 0xa6, 0xb7, 0xfe, 0xbc, 0xb7, 0x1d, 0x6f, 0xfe, 0xf2,
+  0x97, 0x36, 0x1f, 0xef, 0xbb, 0xda, 0x66, 0x2e, 0xa5, 0x68, 0xeb, 0xcf,
+  0xfb, 0xdb, 0x6b, 0x47, 0xe4, 0x67, 0x45, 0xba, 0x6f, 0x9a, 0x37, 0xa8,
+  0xb3, 0xc9, 0x4b, 0x3e, 0x66, 0x56, 0x67, 0xb2, 0x08, 0x1d, 0x8f, 0x6f,
+  0xb8, 0x45, 0xd8, 0x41, 0xb0, 0x6d, 0xab, 0xa9, 0xbb, 0xc0, 0x9b, 0x64,
+  0x97, 0x9c, 0xfc, 0xcf, 0x63, 0x9f, 0x46, 0xb2, 0xd8, 0x6c, 0xfc, 0x2b,
+  0x8a, 0xd8, 0x01, 0xea, 0x72, 0x88, 0x6f, 0xef, 0xaf, 0xf9, 0xb6, 0x1b,
+  0x9d, 0xe7, 0x96, 0xa0, 0x28, 0x36, 0xc1, 0xe0, 0x94, 0x0d, 0x5b, 0xbe,
+  0x63, 0xbf, 0xbd, 0xee, 0x7b, 0x97, 0x27, 0x6f, 0x8e, 0x89, 0x35, 0xfb,
+  0xd5, 0x09, 0x91, 0xcf, 0x8d, 0x84, 0xfe, 0x51, 0x3d, 0x10, 0x96, 0x91,
+  0xd7, 0xaf, 0x96, 0xc2, 0xe1, 0x5d, 0x8b, 0x36, 0xb3, 0x92, 0xc3, 0xae,
+  0x04, 0x7d, 0x5a, 0x30, 0xd0, 0xb5, 0x66, 0x5a, 0x9e, 0x5c, 0x0d, 0xde,
+  0x94, 0x53, 0x58, 0xc9, 0x83, 0x11, 0xa0, 0x82, 0xe6, 0x2d, 0xf3, 0xc3,
+  0x77, 0xc5, 0xbc, 0xf5, 0xe3, 0x61, 0x24, 0x53, 0x77, 0x63, 0x55, 0x51,
+  0x9e, 0x7f, 0xec, 0x0c, 0x06, 0xd4, 0x99, 0x01, 0xc3, 0xba, 0x24, 0xb8,
+  0xd3, 0xe2, 0xe7, 0x50, 0xd1, 0x62, 0x26, 0x28, 0x9f, 0xdd, 0x33, 0x10,
+  0x21, 0x75, 0xf0, 0x31, 0x97, 0xbd, 0x79, 0x4d, 0x19, 0x64, 0xce, 0xc5,
+  0xc7, 0x4e, 0xbc, 0x0d, 0x9f, 0xbc, 0x14, 0x86, 0x54, 0x76, 0xe7, 0xf0,
+  0x4f, 0x52, 0x7e, 0xb9, 0x5c, 0xdc, 0x63, 0x94, 0x77, 0x2d, 0x68, 0x45,
+  0x34, 0xbe, 0xfa, 0x0f, 0x7e, 0xa7, 0x55, 0x86, 0x4a, 0x38, 0xa6, 0xbd,
+  0x1d, 0x28, 0x3f, 0x91, 0xaa, 0x4d, 0x67, 0x95, 0x77, 0x5d, 0x49, 0xb7,
+  0xb5, 0xba, 0x9d, 0x47, 0x6c, 0xea, 0xf1, 0xb0, 0xb6, 0xfb, 0xe9, 0x93,
+  0xc0, 0x96, 0x94, 0xfa, 0xfa, 0xaa, 0xb4, 0xc1, 0x31, 0x23, 0x76, 0x16,
+  0xed, 0x02, 0xc7, 0x59, 0xa2, 0x49, 0xde, 0x9c, 0xc3, 0xbf, 0x39, 0xd8,
+  0x44, 0x5d, 0x86, 0xbc, 0x88, 0x0c, 0x66, 0xf0, 0xcb, 0x47, 0x13, 0x84,
+  0x5e, 0x93, 0xde, 0x15, 0x11, 0x61, 0x50, 0x1c, 0xab, 0xc7, 0x1d, 0x60,
+  0x9e, 0x18, 0xde, 0x5c, 0xe6, 0x82, 0x20, 0xb9, 0xa6, 0x86, 0x24, 0x1b,
+  0xd5, 0x16, 0x19, 0x6b, 0x9d, 0xe4, 0xec, 0x95, 0x24, 0x41, 0xba, 0x5c,
+  0x4c, 0x01, 0xca, 0x60, 0x38, 0xea, 0x7f, 0x10, 0x29, 0x76, 0x75, 0x9f,
+  0xec, 0xed, 0xf7, 0x93, 0xfd, 0xdd, 0xbd, 0xfd, 0xc8, 0x18, 0x7a, 0xff,
+  0x41, 0xa0, 0xa8, 0x7d, 0xfc, 0xba, 0xf7, 0xd8, 0x51, 0xb8, 0x7c, 0x06,
+  0xdc, 0x24, 0x92, 0xf9, 0x6b, 0x84, 0x0f, 0xc5, 0x67, 0x41, 0xc4, 0x8c,
+  0xaa, 0xc7, 0xa0, 0xb3, 0xc3, 0xb5, 0xc5, 0x4e, 0x42, 0xad, 0xb1, 0x69,
+  0x4b, 0x87, 0x4d, 0x51, 0x49, 0x87, 0x0b, 0xcf, 0x02, 0xf9, 0x62, 0x3d,
+  0xa5, 0x69, 0x85, 0x52, 0xa0, 0xed, 0x35, 0xca, 0x1b, 0x5d, 0x16, 0x82,
+  0xd6, 0xd0, 0xda, 0x98, 0xfd, 0xfe, 0xea, 0xe4, 0xe8, 0x52, 0xf9, 0x0e,
+  0xaf, 0x48, 0x79, 0xaa, 0xee, 0x1f, 0x57, 0x8c, 0x71, 0xed, 0x33, 0xd3,
+  0x83, 0x9b, 0xcc, 0xa8, 0xd1, 0xc5, 0x78, 0x79, 0x7d, 0xf0, 0xb7, 0xb4,
+  0xba, 0x2e, 0x8b, 0x87, 0x9e, 0x9f, 0x22, 0xa1, 0xec, 0xc0, 0x48, 0xa8,
+  0xbd, 0xcf, 0xf6, 0x9e, 0x20, 0xff, 0x7b, 0x96, 0xa3, 0x20, 0x10, 0x09,
+  0x88, 0xcd, 0xf9, 0x26, 0x13, 0x6c, 0x20, 0x4d, 0xc2, 0xb2, 0x6a, 0x14,
+  0xd3, 0x4d, 0xbe, 0xee, 0x53, 0xff, 0xd9, 0xa9, 0x3c, 0xcb, 0xa9, 0xe7,
+  0x9b, 0x92, 0xab, 0xb0, 0x49, 0x69, 0x9a, 0xcb, 0xc5, 0x66, 0x9b, 0x22,
+  0xfe, 0x81, 0xb1, 0xd2, 0x27, 0x6c, 0xed, 0xc9, 0x23, 0x4b, 0x7c, 0x8f,
+  0x0c, 0xa2, 0x2a, 0x4b, 0x3f, 0xb8, 0x32, 0xc8, 0x8e, 0x7d, 0x43, 0x43,
+  0x1e, 0x17, 0xaf, 0x8f, 0x98, 0xc1, 0x54, 0xf3, 0xa5, 0x30, 0xd5, 0x89,
+  0x75, 0x4d, 0x6d, 0x53, 0x2f, 0x1f, 0xf8, 0x3e, 0xe5, 0x36, 0x1c, 0x4c,
+  0xc7, 0x8f, 0x78, 0xc8, 0x9c, 0x3b, 0x26, 0x8b, 0x3b, 0x6c, 0x97, 0xde,
+  0x21, 0x43, 0x0d, 0xf5, 0x43, 0xb4, 0xe6, 0xf1, 0x16, 0xd7, 0x94, 0xe5,
+  0x88, 0x03, 0x75, 0x4d, 0x2b, 0x49, 0xab, 0x77, 0xc7, 0xf4, 0x9b, 0xaa,
+  0xbc, 0xbe, 0x3a, 0x3c, 0xf7, 0x0c, 0x5d, 0x18, 0x92, 0xce, 0xa9, 0x47,
+  0xcf, 0x91, 0xa1, 0x83, 0x92, 0xea, 0x52, 0x8d, 0xa9, 0xef, 0x4c, 0x94,
+  0x06, 0x72, 0x92, 0x74, 0x23, 0x00, 0xe4, 0x4b, 0xb9, 0x4f, 0xe0, 0x7f,
+  0x42, 0x35, 0x83, 0xd9, 0x34, 0x45, 0x20, 0x54, 0x6e, 0x21, 0xca, 0x80,
+  0x38, 0x2b, 0x34, 0x8b, 0xb9, 0xdf, 0x29, 0xdd, 0x60, 0x7e, 0x8c, 0xef,
+  0xe0, 0x8a, 0x3e, 0x37, 0x4a, 0x38, 0x68, 0x5c, 0x46, 0xaf, 0xbe, 0xa5,
+  0x1e, 0x4b, 0x50, 0x07, 0x5a, 0x9b, 0xfa, 0xb2, 0x6d, 0x24, 0x4a, 0xad,
+  0x46, 0x75, 0x5e, 0xa9, 0x6f, 0x91, 0x9a, 0xbb, 0x7d, 0x32, 0xe4, 0x3f,
+  0xf7, 0x6d, 0xe9, 0x61, 0x3c, 0x06, 0x9c, 0xe7, 0x95, 0x16, 0x36, 0x9e,
+  0x67, 0x54, 0xcd, 0x37, 0xaf, 0xe7, 0x0e, 0x96, 0x72, 0x25, 0xaf, 0xbb,
+  0x92, 0x7a, 0xa2, 0x44, 0x52, 0x68, 0x01, 0xfd, 0x40, 0x6f, 0x73, 0xc1,
+  0x75, 0x99, 0x5d, 0xf6, 0x31, 0x91, 0x74, 0x14, 0xc9, 0xbb, 0x91, 0xca,
+  0x29, 0x78, 0x8c, 0xf2, 0xab, 0xef, 0x75, 0x29, 0xf8, 0xa6, 0x31, 0xcb,
+  0x90, 0xd6, 0x1f, 0xcc, 0xa5, 0xc0, 0x50, 0x04, 0x33, 0x8f, 0xb9, 0x04,
+  0xf3, 0xc9, 0x7d, 0x95, 0x33, 0x24, 0x88, 0x1c, 0x69, 0x60, 0x74, 0x6a,
+  0x6d, 0x3d, 0xbe, 0x4c, 0xc9, 0x76, 0x9e, 0xd5, 0x19, 0xf3, 0x2f, 0x82,
+  0x10, 0x88, 0x62, 0x7f, 0xb4, 0xf5, 0x60, 0x33, 0x29, 0xa6, 0x16, 0xe2,
+  0x8c, 0x76, 0xe9, 0xfe, 0xfe, 0xb3, 0x67, 0xfd, 0xa4, 0x47, 0x7e, 0x47,
+  0xf4, 0x89, 0x36, 0xf4, 0x6b, 0x08, 0x9e, 0x5e, 0xb4, 0xc2, 0xee, 0x4e,
+  0x75, 0x35, 0xa1, 0xff, 0xa7, 0xf7, 0xb4, 0xb0, 0xe4, 0xa5, 0x24, 0xe2,
+  0x50, 0x37, 0x11, 0x64, 0xb5, 0x74, 0x39, 0xbc, 0xd3, 0xe8, 0x77, 0x27,
+  0xd6, 0xb5, 0x44, 0x71, 0xa4, 0x45, 0x56, 0x2e, 0x34, 0x60, 0x3c, 0x97,
+  0x92, 0x21, 0xf8, 0xbe, 0x17, 0x65, 0x43, 0x88, 0x9f, 0x11, 0x72, 0xc2,
+  0x8b, 0x50, 0x2f, 0xc7, 0x03, 0x49, 0x10, 0x66, 0x43, 0x33, 0x37, 0x87,
+  0x79, 0x4e, 0x8b, 0x20, 0x1e, 0xfc, 0x40, 0x48, 0x7f, 0x95, 0xf4, 0x64,
+  0xbb, 0xd1, 0x1f, 0x43, 0xc4, 0x7b, 0xb3, 0x09, 0x0d, 0xa3, 0x7c, 0x29,
+  0xff, 0xf8, 0xf7, 0x7f, 0x37, 0xcd, 0xfe, 0x3b, 0xb5, 0xf2, 0xf2, 0xcf,
+  0x75, 0x73, 0xe3, 0x3d, 0xd3, 0x93, 0x33, 0x70, 0xe2, 0xa2, 0xdd, 0x40,
+  0xb0, 0x81, 0x79, 0x16, 0x79, 0x6c, 0x6f, 0x4e, 0x45, 0x48, 0xf7, 0xbd,
+  0xf1, 0xe5, 0xc8, 0x30, 0x64, 0xbf, 0xa9, 0x05, 0x90, 0x7c, 0x45, 0x91,
+  0xe8, 0x8c, 0x32, 0xd3, 0xcd, 0x22, 0x80, 0x58, 0x70, 0xdb, 0x41, 0x4a,
+  0x58, 0xbe, 0xc3, 0x37, 0xca, 0x25, 0xe7, 0x3a, 0x25, 0xb4, 0xee, 0xf4,
+  0xa6, 0xe0, 0x53, 0x8c, 0x75, 0x32, 0xbf, 0x4a, 0x67, 0xe5, 0xb5, 0x1d,
+  0x71, 0xac, 0x68, 0xcd, 0x2f, 0x1a, 0x7b, 0xcf, 0x6f, 0x48, 0xdf, 0xf4,
+  0xe3, 0xeb, 0x8f, 0x6c, 0x85, 0x70, 0x02, 0xf6, 0x68, 0x02, 0xfe, 0x1a,
+  0x16, 0x29, 0x13, 0x46, 0x62, 0x63, 0xa9, 0xa8, 0x20, 0xd9, 0xd1, 0x83,
+  0x6e, 0x4f, 0x3e, 0x41, 0x77, 0x27, 0x74, 0x04, 0x3a, 0x55, 0x73, 0x9c,
+  0xac, 0xb0, 0xca, 0x8d, 0x14, 0x44, 0x11, 0xdd, 0x24, 0x33, 0xf2, 0x2a,
+  0x37, 0x67, 0x01, 0x17, 0x20, 0x7d, 0x87, 0xe6, 0x0c, 0xa1, 0xc9, 0x8c,
+  0x09, 0x69, 0xc6, 0x5c, 0x73, 0x6c, 0x30, 0x28, 0x9a, 0xd9, 0x9c, 0xf9,
+  0x9b, 0xa7, 0xa8, 0x3f, 0xa6, 0x19, 0x1a, 0x79, 0x11, 0x92, 0x0c, 0xb6,
+  0xe7, 0x99, 0x5f, 0xfd, 0xe7, 0x66, 0xc9, 0x17, 0x7a, 0x5c, 0xd6, 0x93,
+  0xda, 0xd9, 0x71, 0xc4, 0x8d, 0x8e, 0x1c, 0x8d, 0x7c, 0xa1, 0x83, 0x42,
+  0x4a, 0xa2, 0x01, 0xda, 0x6f, 0x45, 0x93, 0xb0, 0x8f, 0xf9, 0x90, 0x55,
+  0xcd, 0x34, 0x22, 0x9e, 0x69, 0x72, 0xbe, 0x19, 0xf9, 0x9e, 0x01, 0x94,
+  0x5c, 0x27, 0x5b, 0xa3, 0xd1, 0xf9, 0xc9, 0x8e, 0x56, 0x54, 0xdb, 0xd8,
+  0x38, 0x7e, 0xfb, 0xdd, 0xc9, 0xc5, 0xd9, 0xdb, 0x37, 0xc7, 0x6f, 0x2f,
+  0x93, 0xef, 0x0e, 0x2f, 0x4e, 0x0e, 0xbf, 0x3a, 0x15, 0xf2, 0x05, 0x1a,
+  0x26, 0x61, 0xce, 0xd8, 0x14, 0xec, 0x90, 0x12, 0x7b, 0x79, 0x71, 0xd1,
+  0x52, 0x36, 0x9d, 0x2a, 0xdd, 0xef, 0x85, 0x51, 0x1f, 0x86, 0xf1, 0x7b,
+  0x54, 0xe5, 0xea, 0x93, 0x2d, 0xf4, 0x5e, 0x0b, 0x74, 0x91, 0x2d, 0x7f,
+  0xef, 0xa5, 0xf3, 0x13, 0x1c, 0x8e, 0xc4, 0x99, 0x0a, 0x73, 0x57, 0x9a,
+  0xd2, 0xd6, 0x7a, 0xf9, 0x9a, 0x19, 0x21, 0xb4, 0xf0, 0x8d, 0xbe, 0x0a,
+  0xf9, 0xc1, 0xba, 0x8e, 0xeb, 0xc3, 0xe1, 0xe9, 0xa9, 0xfb, 0xd4, 0xfa,
+  0x9a, 0x48, 0xc2, 0x06, 0xc6, 0xb9, 0x84, 0x68, 0x94, 0xe2, 0xd4, 0xd7,
+  0xa5, 0x2b, 0x0f, 0x50, 0xdc, 0xfb, 0x95, 0x00, 0xe8, 0x63, 0x66, 0xbb,
+  0x6c, 0x31, 0x8d, 0x0b, 0x81, 0x16, 0x9a, 0xac, 0xca, 0xeb, 0x0f, 0xfd,
+  0x64, 0xf3, 0xcf, 0x9b, 0x52, 0xa1, 0x1e, 0xdc, 0xd5, 0x5c, 0x71, 0x69,
+  0xdb, 0x75, 0xea, 0xed, 0x99, 0xeb, 0x93, 0xc4, 0xe1, 0x6d, 0x07, 0xec,
+  0x8b, 0x0e, 0x45, 0x51, 0xab, 0x7a, 0x0d, 0xf8, 0xb2, 0x7b, 0x5c, 0xca,
+  0x92, 0x58, 0x76, 0x0a, 0x91, 0x8f, 0x14, 0x67, 0x8d, 0xbe, 0x0b, 0x27,
+  0x42, 0x3a, 0xf1, 0x28, 0xca, 0x31, 0xd6, 0x82, 0x3c, 0x6f, 0xb6, 0x54,
+  0x9c, 0x3a, 0xa7, 0xcd, 0x54, 0x4f, 0x85, 0x70, 0x31, 0xd5, 0x96, 0x25,
+  0x95, 0x19, 0xa9, 0xe2, 0x36, 0x02, 0xe5, 0x39, 0x19, 0x53, 0x01, 0xb4,
+  0x0f, 0xcd, 0x4c, 0xe3, 0xe4, 0xb3, 0x13, 0xa9, 0xe5, 0xdd, 0x45, 0x4c,
+  0xa8, 0x93, 0xfb, 0x29, 0xb1, 0x8e, 0xb2, 0xf5, 0x33, 0x59, 0x57, 0x09,
+  0x42, 0x31, 0x69, 0x37, 0xcf, 0x3e, 0x58, 0x30, 0xd8, 0x9d, 0xa9, 0x33,
+  0x09, 0xc0, 0xa4, 0xff, 0x7a, 0x0f, 0xb9, 0x49, 0x1c, 0x6b, 0xb1, 0xa4,
+  0x88, 0x44, 0x39, 0x84, 0x39, 0x76, 0xb8, 0xf4, 0xec, 0x23, 0x73, 0x09,
+  0xd9, 0x5d, 0xe6, 0x76, 0x02, 0x57, 0xd3, 0x13, 0x18, 0x7a, 0xb7, 0xc7,
+  0x5a, 0x29, 0x2b, 0xd5, 0xca, 0x4c, 0x88, 0x9b, 0xb1, 0xca, 0x05, 0xa5,
+  0xa9, 0x3b, 0x1c, 0x38, 0x0d, 0x19, 0xf0, 0xdc, 0xea, 0x74, 0xa7, 0xe1,
+  0x9e, 0xe2, 0x09, 0x96, 0xb5, 0xa8, 0x50, 0xb8, 0x43, 0x3e, 0xee, 0x68,
+  0xad, 0x2b, 0x80, 0x0c, 0x28, 0x21, 0xa8, 0x32, 0x52, 0xb4, 0x5e, 0x5d,
+  0x52, 0x6a, 0x88, 0xd8, 0xf4, 0xc5, 0x11, 0x6a, 0x32, 0x14, 0x54, 0x95,
+  0xd5, 0xd5, 0xd2, 0x41, 0xf2, 0x40, 0x91, 0x35, 0x15, 0x65, 0xe4, 0x16,
+  0x62, 0x85, 0x00, 0x90, 0x0f, 0x23, 0x3d, 0xbd, 0x2e, 0xd5, 0x00, 0x4f,
+  0x2d, 0x6a, 0xc6, 0x56, 0x1c, 0xf4, 0x8c, 0x7a, 0xcb, 0x1c, 0x68, 0x05,
+  0x17, 0xf0, 0x35, 0x1a, 0x21, 0x24, 0x7c, 0x29, 0x1d, 0x32, 0xad, 0x20,
+  0x5f, 0x7b, 0xdc, 0x0c, 0x2e, 0x7d, 0x89, 0x24, 0x39, 0x67, 0xe9, 0x28,
+  0x95, 0x1f, 0xe8, 0x13, 0x95, 0xcb, 0x01, 0x48, 0x67, 0x74, 0x8b, 0x1e,
+  0x44, 0x93, 0x02, 0x5a, 0x47, 0x93, 0x1a, 0xbc, 0x32, 0xf2, 0x6a, 0x46,
+  0x19, 0xa4, 0xaa, 0x77, 0xa4, 0xc9, 0x38, 0xbf, 0x66, 0x4e, 0x10, 0x22,
+  0xa0, 0xa0, 0x73, 0x09, 0x8a, 0xc7, 0x72, 0x9e, 0xd1, 0xe1, 0x00, 0x81,
+  0x23, 0x8c, 0xf7, 0x9b, 0x72, 0xe6, 0xb3, 0x0c, 0xea, 0x48, 0x64, 0xf5,
+  0x6d, 0xec, 0x03, 0xb1, 0xcf, 0x25, 0xcd, 0xa3, 0xc2, 0x51, 0xa5, 0x3c,
+  0x81, 0x80, 0x73, 0x29, 0xa8, 0x06, 0xae, 0xd4, 0x02, 0xa9, 0x80, 0xca,
+  0xa5, 0x80, 0x79, 0xd0, 0xc4, 0x05, 0xda, 0xb8, 0x70, 0xa4, 0x53, 0x9d,
+  0xd7, 0x2d, 0x5b, 0x5f, 0x80, 0x5a, 0x99, 0x30, 0x43, 0x33, 0x89, 0x19,
+  0x86, 0x94, 0xb4, 0x0b, 0x82, 0xc9, 0x62, 0x09, 0x77, 0x9e, 0xd9, 0x13,
+  0xd4, 0x69, 0x33, 0x53, 0x5b, 0x9e, 0x9a, 0x51, 0x98, 0x2d, 0xc2, 0x8f,
+  0xb1, 0x07, 0x49, 0xfe, 0x35, 0xb0, 0xb5, 0x0c, 0x05, 0x78, 0xb2, 0xed,
+  0x80, 0x47, 0x6c, 0x06, 0x90, 0x7c, 0x98, 0x48, 0x35, 0x59, 0x40, 0x74,
+  0xa8, 0x14, 0x2e, 0x08, 0xe1, 0x5a, 0xc1, 0x87, 0x44, 0x13, 0xee, 0x66,
+  0x33, 0xaf, 0xc0, 0x00, 0xfb, 0x23, 0xd3, 0xc0, 0xf8, 0x20, 0x39, 0x31,
+  0x64, 0x99, 0xcb, 0xd0, 0x3f, 0x26, 0x23, 0xf7, 0x06, 0x22, 0x49, 0x25,
+  0x64, 0x9e, 0x75, 0x62, 0x1a, 0xde, 0x15, 0xa2, 0xf0, 0x18, 0x5f, 0x0d,
+  0x95, 0x7a, 0x3a, 0x79, 0x3a, 0x67, 0xe3, 0xd1, 0xed, 0xbe, 0xf9, 0x3d,
+  0xc3, 0x8e, 0x37, 0x36, 0x8e, 0xde, 0x8d, 0x2e, 0xcf, 0xde, 0x24, 0x67,
+  0xef, 0x2e, 0xcf, 0xdf, 0x5d, 0x8a, 0x9e, 0x3a, 0xe6, 0xa4, 0x0d, 0x86,
+  0x2e, 0xb1, 0xee, 0xac, 0x8b, 0x39, 0x17, 0x80, 0x0f, 0x30, 0x66, 0x25,
+  0x68, 0x45, 0x3d, 0x46, 0x31, 0x9b, 0x94, 0x09, 0xae, 0x3d, 0xe6, 0x2b,
+  0xc7, 0x94, 0xdf, 0x99, 0x29, 0x47, 0x42, 0x3d, 0x3c, 0xf9, 0x9a, 0xe3,
+  0x09, 0xbf, 0x87, 0x9e, 0xb5, 0x76, 0xad, 0xaa, 0xfb, 0xb6, 0x1f, 0x03,
+  0xe8, 0x9c, 0x36, 0x83, 0x9b, 0x5f, 0x32, 0x97, 0x9d, 0xbb, 0xce, 0xf7,
+  0xeb, 0x63, 0xba, 0xa5, 0xe0, 0xae, 0x46, 0xa0, 0x14, 0x56, 0x0f, 0xac,
+  0x61, 0x3b, 0xb3, 0xd8, 0x4f, 0x70, 0x6e, 0x4a, 0x33, 0xc2, 0x1b, 0x9b,
+  0x12, 0x43, 0x30, 0x42, 0x40, 0x81, 0x19, 0x41, 0x45, 0x98, 0x5b, 0x76,
+  0x19, 0x14, 0xd9, 0x1d, 0x29, 0x3e, 0x81, 0x4e, 0x7d, 0x97, 0x6c, 0x7e,
+  0x9f, 0xf9, 0x0d, 0xfe, 0xe9, 0x3f, 0x29, 0x6f, 0xfb, 0xbd, 0xfe, 0xe4,
+  0xbf, 0xf8, 0x93, 0x3f, 0x15, 0x9b, 0x10, 0x98, 0x6d, 0xa8, 0xcc, 0xb7,
+  0xc7, 0x17, 0x5f, 0x1d, 0x5f, 0x9c, 0x8d, 0x20, 0x0f, 0xd4, 0xdf, 0x1d,
+  0xee, 0xf5, 0x0f, 0x59, 0x35, 0xce, 0xaa, 0x52, 0xea, 0xe8, 0xe9, 0xbf,
+  0x9e, 0xed, 0x7c, 0x3d, 0x1a, 0x1d, 0x9e, 0x9f, 0xd8, 0x4a, 0x55, 0x36,
+  0x83, 0x94, 0x7d, 0x24, 0x05, 0xe7, 0x38, 0xd3, 0xf8, 0xf5, 0x15, 0xb3,
+  0x2f, 0x26, 0x1f, 0x38, 0xb3, 0x20, 0x00, 0xa5, 0x68, 0x60, 0x8d, 0xd0,
+  0x28, 0x92, 0x58, 0x4c, 0x0d, 0x2b, 0x13, 0x9c, 0x5f, 0x6d, 0x82, 0xcb,
+  0x42, 0x50, 0x30, 0xb0, 0x6f, 0x21, 0xb8, 0x1f, 0xaa, 0xf1, 0xc0, 0xec,
+  0xf6, 0x0f, 0x5a, 0xb8, 0x9d, 0x13, 0xa1, 0x8c, 0xa8, 0xe4, 0x0c, 0x09,
+  0xe7, 0x6c, 0xfc, 0x90, 0x17, 0x79, 0xb3, 0xf3, 0x81, 0xce, 0x07, 0x55,
+  0x51, 0x9a, 0x0d, 0x59, 0xba, 0xf3, 0x81, 0x52, 0xd8, 0x3b, 0x89, 0xd8,
+  0x75, 0xec, 0x34, 0xe6, 0x6b, 0xb6, 0xf4, 0x29, 0x3b, 0xbc, 0xcd, 0x4f,
+  0x9e, 0x5a, 0x9a, 0x3e, 0xd1, 0xfc, 0x81, 0x94, 0xbd, 0x32, 0x77, 0xd5,
+  0xe2, 0x6e, 0x2a, 0x97, 0x08, 0x58, 0xea, 0x59, 0xb9, 0x14, 0x19, 0xde,
+  0x8d, 0x50, 0x53, 0x79, 0x56, 0x64, 0x6c, 0x49, 0x3e, 0x4a, 0x32, 0x9e,
+  0xa5, 0xc5, 0x07, 0xe8, 0x0f, 0xd0, 0x08, 0xe8, 0xee, 0x53, 0xf2, 0x39,
+  0x2a, 0x9b, 0x0b, 0x40, 0x82, 0xf0, 0xc1, 0xc0, 0xe4, 0x9b, 0x91, 0x70,
+  0xbb, 0xe7, 0x60, 0x9e, 0xe5, 0xd8, 0xf3, 0x42, 0xef, 0x38, 0x4e, 0x6e,
+  0x12, 0xc8, 0x77, 0x7c, 0x7c, 0x6a, 0x2e, 0x26, 0x9b, 0x65, 0x06, 0x1f,
+  0x5d, 0x36, 0xa3, 0x58, 0x90, 0x42, 0x02, 0x39, 0xb1, 0x3a, 0x87, 0x20,
+  0x63, 0xe9, 0xa1, 0x05, 0x14, 0x10, 0x40, 0xc6, 0x76, 0x41, 0xfe, 0x78,
+  0x6d, 0xcb, 0x0c, 0x89, 0xe4, 0x66, 0x21, 0x06, 0x76, 0x60, 0x57, 0x75,
+  0xc8, 0xaf, 0x7f, 0x25, 0x78, 0xdb, 0x23, 0x07, 0x08, 0xb4, 0x05, 0x01,
+  0xb9, 0x13, 0xce, 0x08, 0xb5, 0x10, 0x83, 0x56, 0x7a, 0xdb, 0xca, 0x65,
+  0xe2, 0xd7, 0x63, 0x5e, 0x40, 0x26, 0x35, 0x9c, 0x4a, 0xc0, 0xd3, 0xf2,
+  0x81, 0x69, 0xce, 0x42, 0x3b, 0x4f, 0x40, 0x3b, 0xce, 0x70, 0x20, 0x8a,
+  0xde, 0xcc, 0x1a, 0xeb, 0xa8, 0xa8, 0x99, 0x61, 0x0d, 0x4a, 0xd7, 0x14,
+  0x22, 0xa7, 0x6a, 0x51, 0x55, 0xfb, 0xf0, 0x7c, 0xa6, 0xac, 0x29, 0xad,
+  0x91, 0xc9, 0xd6, 0xbf, 0xb5, 0x66, 0x07, 0x6f, 0xe9, 0xba, 0x28, 0x07,
+  0xe3, 0x25, 0x1c, 0x33, 0x5e, 0xa1, 0x3e, 0x4e, 0xe2, 0x2e, 0xaf, 0x58,
+  0xf3, 0xe0, 0xdf, 0x53, 0x40, 0x1a, 0xf4, 0x18, 0x1c, 0xa3, 0x46, 0xbe,
+  0x74, 0x9b, 0x69, 0xcb, 0xf2, 0x2b, 0x71, 0x12, 0x92, 0xab, 0x20, 0x6e,
+  0x07, 0x28, 0x8b, 0x6c, 0x9d, 0x34, 0x9e, 0x4d, 0xd3, 0xef, 0xa4, 0x5c,
+  0x34, 0xb6, 0xe0, 0xc5, 0x25, 0xd4, 0x84, 0x4c, 0xca, 0x40, 0x68, 0x2e,
+  0x85, 0x66, 0x6e, 0xdd, 0x36, 0x54, 0x5a, 0x8e, 0xa9, 0x61, 0xd2, 0x19,
+  0xd7, 0xe9, 0x59, 0x79, 0x95, 0xf0, 0x61, 0x6a, 0x2e, 0x2f, 0xff, 0x7a,
+  0x7e, 0xfc, 0x52, 0xdf, 0x5c, 0xb7, 0x66, 0xcc, 0x98, 0x08, 0xd0, 0x5c,
+  0x26, 0x0c, 0xc5, 0x9a, 0x43, 0xc3, 0xa2, 0x62, 0xd0, 0x28, 0x98, 0x87,
+  0x3f, 0x33, 0x48, 0x7e, 0x78, 0x75, 0x32, 0x3a, 0x3f, 0x3d, 0x3b, 0x7a,
+  0xf9, 0xe2, 0x07, 0x15, 0xc9, 0x5f, 0x50, 0x8c, 0x90, 0xf5, 0x34, 0xfb,
+  0x33, 0xc7, 0xe8, 0x22, 0xef, 0xbd, 0x3d, 0xfe, 0xfe, 0xbd, 0xb1, 0xc7,
+  0x5e, 0x52, 0x5d, 0x87, 0xfe, 0x6d, 0x3a, 0x93, 0x97, 0x48, 0x3f, 0x8d,
+  0xe8, 0x76, 0xc3, 0x36, 0x05, 0x67, 0x77, 0x62, 0x6d, 0x7d, 0x62, 0x97,
+  0xa8, 0x74, 0xaf, 0x38, 0x5a, 0xaf, 0x14, 0x5d, 0xda, 0xca, 0xab, 0x8f,
+  0x54, 0x13, 0x77, 0xd7, 0xff, 0x66, 0xc3, 0xa0, 0x6a, 0xc2, 0x10, 0xf9,
+  0xd0, 0x1c, 0x00, 0xd7, 0xe5, 0x37, 0x0e, 0xd0, 0x2f, 0xfc, 0xe9, 0x15,
+  0xf9, 0xd1, 0x2c, 0x01, 0xad, 0x94, 0xa8, 0x07, 0xe8, 0x45, 0x58, 0x6a,
+  0x85, 0x7a, 0x8d, 0x30, 0xf4, 0x9a, 0x4e, 0xa3, 0x72, 0x4c, 0x54, 0x18,
+  0xdb, 0x97, 0x54, 0x8b, 0x65, 0xa3, 0x22, 0xd7, 0xf9, 0xf1, 0xc5, 0xe8,
+  0x64, 0x74, 0x49, 0x86, 0xab, 0x54, 0x6e, 0x95, 0x20, 0x94, 0x96, 0xd5,
+  0x05, 0x69, 0x4b, 0x9b, 0x70, 0xd8, 0xaf, 0x16, 0xd4, 0x3a, 0xd1, 0x56,
+  0xcc, 0xb5, 0xb3, 0xb8, 0xe9, 0x06, 0xe0, 0xd4, 0x70, 0x52, 0x44, 0x99,
+  0x36, 0x3b, 0xbd, 0xd2, 0x03, 0x5c, 0xca, 0xd6, 0xe8, 0x14, 0xcd, 0x41,
+  0xc1, 0x2b, 0xac, 0xce, 0x2c, 0x1f, 0x3b, 0x67, 0x66, 0x07, 0x43, 0x42,
+  0xf0, 0x24, 0xa1, 0xe8, 0xf1, 0x8f, 0x90, 0x06, 0xc4, 0x1c, 0x35, 0x82,
+  0x14, 0xf3, 0x96, 0x6b, 0x4d, 0xd2, 0x9a, 0xfd, 0x04, 0x76, 0xeb, 0x96,
+  0x82, 0xd1, 0xa2, 0x7a, 0x9a, 0xfd, 0xa9, 0x87, 0x42, 0x17, 0xd6, 0x37,
+  0x10, 0x56, 0x8b, 0xc8, 0x26, 0xa1, 0x9c, 0x73, 0x2a, 0x2a, 0xf9, 0x27,
+  0x8d, 0xd6, 0x02, 0x6a, 0x0d, 0x00, 0x05, 0x65, 0x64, 0x81, 0x0a, 0x22,
+  0xaa, 0xe3, 0x35, 0xe5, 0xb0, 0x82, 0x5a, 0x6f, 0x4a, 0xfa, 0x16, 0x5c,
+  0xf0, 0xfe, 0xc7, 0xf4, 0x3a, 0xa5, 0x19, 0x1c, 0x2f, 0xfd, 0x52, 0x90,
+  0xb6, 0xf7, 0x5c, 0x95, 0x08, 0x13, 0x0f, 0x88, 0x74, 0x5a, 0xc1, 0x93,
+  0xd1, 0x48, 0xa9, 0x08, 0x35, 0x7c, 0x04, 0xef, 0x3c, 0x6c, 0xb3, 0x78,
+  0xe9, 0xbe, 0x54, 0x23, 0x6c, 0xdd, 0x8c, 0x7a, 0xb5, 0x63, 0x69, 0xfb,
+  0x56, 0x99, 0x02, 0x17, 0xd9, 0xa9, 0x58, 0x53, 0xc4, 0xb1, 0x98, 0xd8,
+  0xcb, 0x98, 0xb2, 0x0e, 0x09, 0x60, 0x50, 0x09, 0x43, 0x9a, 0x11, 0x7f,
+  0x14, 0x5a, 0x42, 0xc1, 0x59, 0x54, 0x62, 0xa7, 0xb0, 0xbb, 0xb2, 0x67,
+  0xba, 0x3c, 0x0e, 0x9e, 0x6e, 0x6f, 0x5b, 0x71, 0x7c, 0xed, 0x5e, 0x3e,
+  0x68, 0x19, 0x32, 0x74, 0xb1, 0xfa, 0x9c, 0x70, 0x99, 0x22, 0xbf, 0x4f,
+  0x03, 0x3b, 0x5e, 0x9e, 0x78, 0x2d, 0xd9, 0xf7, 0x16, 0x9f, 0x02, 0x81,
+  0xd7, 0xaa, 0xba, 0x4d, 0xa3, 0x6b, 0x61, 0x03, 0x8c, 0x7e, 0xb9, 0x40,
+  0x09, 0xb5, 0x89, 0xd4, 0x90, 0x00, 0x6a, 0xdf, 0x36, 0xa8, 0x97, 0x88,
+  0x9b, 0x2c, 0x33, 0xab, 0x6f, 0xde, 0x9d, 0x5e, 0x9e, 0x9c, 0xfb, 0xf8,
+  0x83, 0xe4, 0xfb, 0x93, 0xcb, 0x6f, 0x8c, 0xd6, 0x3e, 0x3a, 0x79, 0xfb,
+  0xf5, 0x29, 0x05, 0x79, 0xdf, 0xbc, 0x39, 0x7c, 0x4b, 0xf4, 0x22, 0x6f,
+  0x01, 0x6d, 0x3e, 0x84, 0xe1, 0x40, 0xe2, 0xc8, 0x4c, 0x31, 0xed, 0x1d,
+  0x22, 0x9e, 0xe8, 0x87, 0xb1, 0xc6, 0xce, 0xf1, 0xe3, 0xaa, 0xea, 0x45,
+  0x7b, 0x92, 0x68, 0xc5, 0xc5, 0x32, 0xb8, 0x27, 0x37, 0x2e, 0x8e, 0x2d,
+  0x19, 0x5b, 0x34, 0xd1, 0xdd, 0xe2, 0x11, 0x48, 0x72, 0x66, 0x0d, 0x1d,
+  0x38, 0x1a, 0xbe, 0xbb, 0x5d, 0xfc, 0x12, 0x2b, 0x6a, 0xa9, 0xa7, 0x61,
+  0xc7, 0x18, 0x9d, 0xa9, 0x10, 0xbb, 0x86, 0xef, 0xcb, 0x76, 0xd2, 0x91,
+  0xf9, 0x22, 0xba, 0x04, 0x20, 0x51, 0xe9, 0x1c, 0xe9, 0x64, 0x71, 0x92,
+  0xd1, 0x7c, 0x71, 0xea, 0x5f, 0xa8, 0xc3, 0x56, 0xcd, 0x41, 0xc5, 0x07,
+  0x5f, 0x97, 0x99, 0x3b, 0xb9, 0x83, 0x33, 0x6d, 0x46, 0xe3, 0x3f, 0x30,
+  0xc3, 0xf8, 0x72, 0x19, 0x90, 0x5c, 0x1b, 0x98, 0x25, 0xd9, 0xb6, 0x75,
+  0xc6, 0xc4, 0xec, 0x3f, 0x60, 0xb5, 0xd2, 0x92, 0xab, 0x6b, 0x79, 0x4e,
+  0xd3, 0x9c, 0xb6, 0x2c, 0x58, 0x34, 0x24, 0x64, 0x48, 0x5e, 0xa3, 0x8c,
+  0x19, 0xd2, 0x52, 0x1f, 0x6b, 0xd1, 0x32, 0xf0, 0x7d, 0x77, 0xa6, 0xc1,
+  0x49, 0xcd, 0x6b, 0xb5, 0x85, 0x1f, 0x1d, 0x74, 0x02, 0xa5, 0x15, 0xe1,
+  0xae, 0xc8, 0x08, 0xe5, 0x40, 0x7f, 0xfd, 0xdb, 0xe2, 0xda, 0x4f, 0x79,
+  0xe5, 0xc2, 0xf2, 0x8b, 0xd8, 0xca, 0x0a, 0x93, 0x3b, 0xab, 0x45, 0x52,
+  0xcc, 0xb2, 0xd5, 0x03, 0xa9, 0x50, 0xb9, 0xb7, 0xea, 0x83, 0xf2, 0xfb,
+  0xfd, 0xf0, 0xf7, 0xfb, 0x1c, 0x64, 0x38, 0x39, 0xbf, 0x7d, 0x6e, 0x19,
+  0x90, 0x99, 0xc8, 0xc1, 0x57, 0xdf, 0x54, 0x29, 0xa0, 0x1d, 0x46, 0x8f,
+  0x8a, 0xcb, 0x9c, 0x65, 0x22, 0x07, 0xff, 0x08, 0x42, 0xba, 0xac, 0x90,
+  0xa0, 0x8e, 0x47, 0x10, 0x5d, 0x61, 0xdc, 0x3f, 0x3c, 0x4f, 0x90, 0x53,
+  0x74, 0x5d, 0x99, 0x06, 0xcd, 0xef, 0x9f, 0xda, 0x64, 0x1c, 0x27, 0xd3,
+  0x50, 0xa4, 0x51, 0xd2, 0x21, 0x07, 0xf9, 0xe2, 0x56, 0xab, 0x7c, 0x9b,
+  0xbf, 0x3e, 0xb7, 0x05, 0xba, 0xea, 0x56, 0x90, 0xba, 0xc5, 0x36, 0xae,
+  0xc2, 0x1f, 0x9d, 0x83, 0x0f, 0x8c, 0x24, 0x83, 0x33, 0x32, 0x3a, 0xfd,
+  0xca, 0xda, 0x19, 0x19, 0x5e, 0x99, 0x62, 0x64, 0x7d, 0xcd, 0x90, 0x1a,
+  0x0f, 0x79, 0xe4, 0x09, 0x17, 0xbf, 0xd2, 0x87, 0xac, 0xfa, 0x8f, 0xfb,
+  0xbb, 0xbb, 0x7b, 0x07, 0x7b, 0x9f, 0x7e, 0xb6, 0x7b, 0xb0, 0xb7, 0xb7,
+  0xb7, 0x7f, 0xb0, 0x77, 0x70, 0xb0, 0xbf, 0xfb, 0xf3, 0x0e, 0xf9, 0x8f,
+  0x6e, 0xf3, 0xec, 0x4e, 0x23, 0xd3, 0xec, 0xe7, 0xc3, 0xb6, 0xae, 0x9b,
+  0x7b, 0x06, 0x03, 0xb0, 0xa7, 0x0f, 0xfb, 0x5a, 0x35, 0x1f, 0x4b, 0x2b,
+  0xc3, 0x39, 0x33, 0x4c, 0x21, 0xb9, 0x70, 0xa9, 0xe6, 0x38, 0x83, 0x1e,
+  0xcd, 0x3d, 0x7a, 0xf5, 0xf7, 0x25, 0x8d, 0x74, 0x4c, 0xea, 0x00, 0x74,
+  0x9a, 0xda, 0x26, 0xf6, 0x5e, 0xcf, 0xca, 0xf1, 0x18, 0xa9, 0x4b, 0x36,
+  0xb7, 0x7d, 0x98, 0x10, 0x97, 0xf2, 0x07, 0xde, 0x12, 0x12, 0x3a, 0x04,
+  0xaa, 0x98, 0x0f, 0xba, 0x9b, 0x1d, 0xe7, 0xd9, 0x33, 0x3b, 0x60, 0x52,
+  0x52, 0x5d, 0x11, 0x78, 0xba, 0xcd, 0x24, 0x55, 0x36, 0xe7, 0x2d, 0xb9,
+  0xca, 0x3e, 0xdd, 0x3d, 0x38, 0xa0, 0xd2, 0x3f, 0x7f, 0xda, 0xeb, 0x0b,
+  0x20, 0xdc, 0xcf, 0x72, 0xe9, 0xdb, 0xeb, 0x89, 0xdb, 0x20, 0xf3, 0xc3,
+  0x1f, 0x67, 0xb1, 0x9c, 0x67, 0x95, 0x31, 0x44, 0xa8, 0x78, 0x34, 0x10,
+  0xd1, 0xf0, 0x18, 0x32, 0xc7, 0x22, 0x18, 0x99, 0x3a, 0xd9, 0x38, 0x74,
+  0x23, 0x30, 0x57, 0xb4, 0x65, 0xa1, 0x60, 0xbe, 0x30, 0x37, 0x44, 0xdb,
+  0x36, 0xca, 0x5f, 0x01, 0xac, 0xc9, 0xb9, 0x6c, 0x9c, 0xc5, 0xc7, 0xf7,
+  0xad, 0x48, 0x06, 0x1c, 0xae, 0x82, 0x4b, 0x1a, 0xd3, 0xe3, 0xac, 0xc3,
+  0xc3, 0x63, 0xe2, 0x29, 0xb7, 0x92, 0xc0, 0xf7, 0xa3, 0x37, 0xd8, 0xfd,
+  0x67, 0x7b, 0x3f, 0x33, 0x5e, 0x99, 0x0e, 0x84, 0x9b, 0x35, 0x0d, 0xbe,
+  0xf8, 0x29, 0x5a, 0xba, 0x91, 0xb6, 0xb2, 0xe1, 0xf5, 0x50, 0xb5, 0x0a,
+  0xf1, 0x36, 0xf6, 0xfd, 0xac, 0x11, 0xae, 0x53, 0xc0, 0x85, 0xca, 0x61,
+  0xa7, 0xa9, 0x43, 0xc9, 0x77, 0xd5, 0xea, 0xc0, 0x6c, 0x39, 0xba, 0x37,
+  0xc7, 0x97, 0x87, 0xe6, 0xf2, 0xf8, 0x36, 0x34, 0xf4, 0xdf, 0x64, 0xc6,
+  0x2a, 0xa7, 0xc5, 0xde, 0xc2, 0x79, 0xb8, 0xb5, 0xec, 0xe0, 0x34, 0x77,
+  0x4f, 0x93, 0x2d, 0x0a, 0x51, 0x3e, 0xfb, 0xf4, 0xd9, 0xd3, 0x6d, 0x2e,
+  0xc5, 0xc2, 0xaf, 0x65, 0x94, 0x20, 0x06, 0xaf, 0xa4, 0xb0, 0x53, 0x91,
+  0x03, 0xdf, 0x8a, 0xa4, 0x77, 0x17, 0x27, 0x7c, 0xa4, 0x6f, 0x98, 0x44,
+  0x84, 0x8d, 0xde, 0x2e, 0x9b, 0x24, 0xee, 0x5b, 0x4f, 0xc9, 0x98, 0xe7,
+  0xc4, 0x74, 0x0a, 0xf2, 0x05, 0xba, 0x18, 0x2d, 0xf9, 0x07, 0x6e, 0x58,
+  0x73, 0x40, 0x4b, 0x14, 0x28, 0x95, 0xba, 0x6f, 0xe8, 0x0c, 0xa8, 0x51,
+  0x89, 0x99, 0x59, 0xf6, 0x99, 0xb5, 0xc0, 0xc8, 0x0e, 0x62, 0x79, 0xc4,
+  0xd2, 0xbf, 0xc3, 0xc6, 0xbf, 0xcd, 0x90, 0x1f, 0x28, 0x85, 0xb4, 0x0d,
+  0xcd, 0x83, 0x8a, 0x1d, 0xa7, 0x1e, 0xb7, 0xd2, 0x51, 0x9d, 0xb6, 0xe9,
+  0x91, 0xba, 0x29, 0x9f, 0x93, 0x88, 0x22, 0x3b, 0x85, 0x8c, 0x67, 0x69,
+  0xe0, 0x59, 0xcc, 0x5b, 0x2e, 0x1f, 0x21, 0xd3, 0x00, 0xa9, 0x05, 0x72,
+  0x0e, 0xe6, 0xe6, 0x3a, 0xaa, 0xee, 0x45, 0xc3, 0x86, 0x99, 0x60, 0xeb,
+  0x29, 0x76, 0x10, 0x41, 0x4c, 0x1b, 0xe3, 0xa7, 0xd2, 0x58, 0xd6, 0x24,
+  0x35, 0x9a, 0x5b, 0x1d, 0x68, 0x89, 0xfd, 0xc1, 0x5c, 0x7f, 0xe5, 0x01,
+  0xe6, 0xfc, 0xfc, 0x52, 0xfd, 0xbb, 0x3e, 0xe7, 0x61, 0xa9, 0xd3, 0xee,
+  0xc0, 0x56, 0x74, 0x8d, 0x19, 0x75, 0x81, 0x9f, 0xb4, 0xd6, 0xcf, 0x16,
+  0x7a, 0xb2, 0xb3, 0xb3, 0xbd, 0xa2, 0x37, 0xf2, 0xeb, 0xd8, 0xd7, 0xcf,
+  0x41, 0x4a, 0xe4, 0xa5, 0x74, 0x9b, 0x35, 0x6f, 0x37, 0x4e, 0x53, 0x9b,
+  0xd7, 0xb4, 0x92, 0x53, 0x01, 0xc6, 0xb3, 0x1b, 0x55, 0xcd, 0x2b, 0xee,
+  0xbc, 0x0a, 0xaf, 0xf6, 0x20, 0x04, 0x8b, 0xa7, 0x24, 0x71, 0x5c, 0x55,
+  0x9e, 0x51, 0x01, 0xc3, 0xe4, 0x90, 0x76, 0x43, 0xeb, 0xc3, 0x5e, 0x97,
+  0xd5, 0x9f, 0xab, 0x75, 0x0f, 0x54, 0x89, 0xb5, 0xee, 0xbc, 0xbe, 0xf7,
+  0x4b, 0x55, 0xf3, 0x94, 0x13, 0xc4, 0x3a, 0x7b, 0xc7, 0x19, 0xf3, 0x1f,
+  0x59, 0xc9, 0xe9, 0xf1, 0x99, 0xe7, 0x45, 0xab, 0x50, 0xb0, 0x34, 0x02,
+  0xa4, 0x8b, 0x1d, 0x04, 0xa8, 0x52, 0x2b, 0xa5, 0xe0, 0xf6, 0x8b, 0x87,
+  0x82, 0x82, 0x44, 0xb2, 0x5a, 0x58, 0xb1, 0xb6, 0x9b, 0x98, 0x41, 0x0a,
+  0x63, 0xde, 0x5e, 0xad, 0xf9, 0xe8, 0xf3, 0x8e, 0x67, 0x14, 0x93, 0x85,
+  0x54, 0x90, 0xc0, 0x38, 0x3c, 0x39, 0x25, 0x58, 0xec, 0xa9, 0x31, 0xf1,
+  0x46, 0xaa, 0x2a, 0x01, 0x26, 0x0e, 0xc0, 0x6e, 0x91, 0x93, 0xba, 0xde,
+  0xb7, 0x05, 0x87, 0x34, 0x5b, 0x12, 0x76, 0x0b, 0x85, 0x58, 0xd9, 0xf4,
+  0x17, 0x92, 0x50, 0xb3, 0x5a, 0x46, 0x5f, 0xaa, 0xd9, 0x69, 0x0b, 0x02,
+  0x6e, 0x2a, 0x4d, 0x71, 0x9b, 0xcd, 0xca, 0x05, 0x4c, 0x6a, 0x16, 0xd3,
+  0xa8, 0x77, 0x56, 0x65, 0xb3, 0xec, 0x56, 0xbc, 0xab, 0x4c, 0x67, 0xfc,
+  0xb5, 0x20, 0x16, 0xb8, 0xe0, 0x71, 0x23, 0x59, 0x2d, 0x01, 0x2a, 0x82,
+  0x3e, 0xba, 0xc3, 0xac, 0x50, 0x8e, 0xec, 0x87, 0xbe, 0xef, 0x8a, 0x70,
+  0x98, 0x19, 0xb2, 0x45, 0x1c, 0x06, 0x64, 0xe4, 0x0a, 0xb8, 0xfd, 0x5d,
+  0x2d, 0x7c, 0x2e, 0xdd, 0x6c, 0x11, 0x76, 0x16, 0x6a, 0xcd, 0x4c, 0xf6,
+  0xbe, 0xf7, 0x95, 0x26, 0x9d, 0x43, 0x06, 0x74, 0xf3, 0xf4, 0xc9, 0x53,
+  0x8b, 0x96, 0xae, 0x8c, 0x45, 0x46, 0x05, 0x71, 0xfa, 0x9c, 0x3a, 0x8e,
+  0xcd, 0x51, 0xce, 0xcc, 0x3f, 0x01, 0xa8, 0x64, 0x88, 0xb5, 0x79, 0x96,
+  0xe2, 0xcd, 0x1e, 0xa6, 0x9d, 0x30, 0x37, 0x48, 0x87, 0x92, 0x7f, 0xa1,
+  0xa9, 0x6a, 0x09, 0x36, 0xf1, 0x3e, 0xdf, 0x86, 0x14, 0xe7, 0x6d, 0x26,
+  0x43, 0xdb, 0x7b, 0x41, 0xfd, 0x70, 0xff, 0x5f, 0xf1, 0x54, 0xd2, 0x20,
+  0x58, 0x0f, 0x29, 0x2b, 0x9d, 0x5e, 0x5e, 0x86, 0x31, 0x97, 0x38, 0xfd,
+  0x6a, 0x49, 0xf1, 0x47, 0x5b, 0xc0, 0x8b, 0x7a, 0x31, 0xa7, 0xbb, 0x28,
+  0xe3, 0x6a, 0xc2, 0xb6, 0x71, 0x32, 0xe9, 0x96, 0x66, 0x79, 0xb9, 0xf5,
+  0xd3, 0xf2, 0x8e, 0x4a, 0x21, 0x5f, 0x5d, 0xe5, 0x13, 0x8a, 0xfd, 0x3b,
+  0xd6, 0x70, 0x92, 0xf1, 0xfc, 0xe0, 0x5c, 0xab, 0xaf, 0x99, 0xb1, 0x25,
+  0x8b, 0xe5, 0x78, 0x66, 0x2e, 0x6b, 0xcd, 0x67, 0x31, 0xa7, 0x0a, 0xb3,
+  0x64, 0xac, 0x2d, 0x34, 0xc7, 0xf4, 0x86, 0x30, 0x38, 0x3b, 0x39, 0x14,
+  0x08, 0x97, 0x56, 0x50, 0xc1, 0xe7, 0xa8, 0x09, 0x4d, 0x89, 0x06, 0xf3,
+  0xb2, 0xd0, 0x74, 0xb8, 0x65, 0xcd, 0x74, 0xb2, 0x88, 0xe6, 0x70, 0x95,
+  0xac, 0x04, 0x4f, 0x4a, 0xd1, 0x06, 0x31, 0xcd, 0xf1, 0x86, 0x3f, 0x98,
+  0xe9, 0x60, 0x71, 0xb3, 0xd0, 0x95, 0x56, 0x85, 0x88, 0xb5, 0x25, 0x49,
+  0xc0, 0xc2, 0xd1, 0x3b, 0xff, 0xe6, 0x7c, 0x98, 0x1c, 0x53, 0x4b, 0xdc,
+  0x27, 0x51, 0x74, 0xe1, 0xa3, 0x31, 0xbf, 0x33, 0x83, 0xbd, 0xa6, 0x0b,
+  0xec, 0xac, 0xa2, 0x7f, 0xa1, 0x35, 0xf9, 0x25, 0xbb, 0x65, 0xf1, 0xdb,
+  0xf6, 0x57, 0x4d, 0x43, 0x9a, 0x66, 0x71, 0x8e, 0xbf, 0x9b, 0xb3, 0x62,
+  0xd4, 0x2f, 0xbb, 0x4c, 0xee, 0x0b, 0x65, 0xd5, 0x22, 0xdf, 0xe2, 0x37,
+  0x13, 0xa3, 0x95, 0x41, 0xb7, 0x5a, 0xdc, 0x63, 0xfd, 0x3c, 0xe1, 0xc8,
+  0xfa, 0x27, 0x37, 0xe0, 0x6d, 0x2d, 0xd9, 0x7e, 0x16, 0xc0, 0xcb, 0x07,
+  0xab, 0x62, 0xda, 0xa9, 0x2a, 0x13, 0xb8, 0x73, 0x29, 0x81, 0x69, 0xf6,
+  0x68, 0xd4, 0x59, 0xe7, 0xbc, 0x7a, 0xf6, 0x9b, 0xfe, 0x82, 0xcc, 0x6e,
+  0xea, 0x8b, 0xd1, 0x5a, 0xcc, 0x12, 0x0c, 0x37, 0xfe, 0xbf, 0xd5, 0x8d,
+  0xb2, 0x33, 0x56, 0xf8, 0x02, 0x00,
+};
+#define BUF_SIZE 0x10000
+static voidpf zalloc_func(voidpf opaque, unsigned int items, unsigned int size)
+{
+  (void) opaque;
+  /* not a typo, keep it calloc() */
+  return (voidpf) calloc(items, size);
+}
+static void zfree_func(voidpf opaque, voidpf ptr)
+{
+  (void) opaque;
+  free(ptr);
+}
+/* Decompress and send to stdout a gzip-compressed buffer */
+void hugehelp(void)
+{
+  unsigned char* buf;
+  int status,headerlen;
+  z_stream z;
+
+  /* Make sure no gzip options are set */
+  if (hugehelpgz[3] & 0xfe)
+    return;
+
+  headerlen = 10;
+  memset(&z, 0, sizeof(z_stream));
+  z.zalloc = (alloc_func)zalloc_func;
+  z.zfree = (free_func)zfree_func;
+  z.avail_in = (unsigned int)(sizeof(hugehelpgz) - headerlen);
+  z.next_in = (unsigned char *)hugehelpgz + headerlen;
+
+  if (inflateInit2(&z, -MAX_WBITS) != Z_OK)
+    return;
+
+  buf = malloc(BUF_SIZE);
+  if (buf) {
+    while(1) {
+      z.avail_out = BUF_SIZE;
+      z.next_out = buf;
+      status = inflate(&z, Z_SYNC_FLUSH);
+      if (status == Z_OK || status == Z_STREAM_END) {
+        fwrite(buf, BUF_SIZE - z.avail_out, 1, stdout);
+        if (status == Z_STREAM_END)
+          break;
+      }
+      else
+        break;    /* Error */
+    }
+    free(buf);
+  }
+  inflateEnd(&z);
+}
+#else /* !USE_MANUAL */
+/* built-in manual is disabled, blank function */
+#include "tool_hugehelp.h"
+void hugehelp(void) {}
+#endif /* USE_MANUAL */
+#endif /* HAVE_LIBZ */
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_hugehelp.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_hugehelp.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_hugehelp.h	(revision 331)
@@ -0,0 +1,28 @@
+#ifndef HEADER_CURL_TOOL_HUGEHELP_H
+#define HEADER_CURL_TOOL_HUGEHELP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+void hugehelp(void);
+
+#endif /* HEADER_CURL_TOOL_HUGEHELP_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_libinfo.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_libinfo.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_libinfo.c	(revision 331)
@@ -0,0 +1,102 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#include "strcase.h"
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_libinfo.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+/* global variable definitions, for libcurl run-time info */
+
+curl_version_info_data *curlinfo = NULL;
+long built_in_protos = 0;
+
+/*
+ * libcurl_info_init: retrieves run-time information about libcurl,
+ * setting a global pointer 'curlinfo' to libcurl's run-time info
+ * struct, and a global bit pattern 'built_in_protos' composed of
+ * CURLPROTO_* bits indicating which protocols are actually built
+ * into library being used.
+ */
+
+CURLcode get_libcurl_info(void)
+{
+  static struct proto_name_pattern {
+    const char *proto_name;
+    long        proto_pattern;
+  } const possibly_built_in[] = {
+    { "dict",   CURLPROTO_DICT   },
+    { "file",   CURLPROTO_FILE   },
+    { "ftp",    CURLPROTO_FTP    },
+    { "ftps",   CURLPROTO_FTPS   },
+    { "gopher", CURLPROTO_GOPHER },
+    { "http",   CURLPROTO_HTTP   },
+    { "https",  CURLPROTO_HTTPS  },
+    { "imap",   CURLPROTO_IMAP   },
+    { "imaps",  CURLPROTO_IMAPS  },
+    { "ldap",   CURLPROTO_LDAP   },
+    { "ldaps",  CURLPROTO_LDAPS  },
+    { "pop3",   CURLPROTO_POP3   },
+    { "pop3s",  CURLPROTO_POP3S  },
+    { "rtmp",   CURLPROTO_RTMP   },
+    { "rtsp",   CURLPROTO_RTSP   },
+    { "scp",    CURLPROTO_SCP    },
+    { "sftp",   CURLPROTO_SFTP   },
+    { "smb",    CURLPROTO_SMB    },
+    { "smbs",   CURLPROTO_SMBS   },
+    { "smtp",   CURLPROTO_SMTP   },
+    { "smtps",  CURLPROTO_SMTPS  },
+    { "telnet", CURLPROTO_TELNET },
+    { "tftp",   CURLPROTO_TFTP   },
+    {  NULL,    0                }
+  };
+
+  struct proto_name_pattern const *p;
+  const char *const *proto;
+
+  /* Pointer to libcurl's run-time version information */
+  curlinfo = curl_version_info(CURLVERSION_NOW);
+  if(!curlinfo)
+    return CURLE_FAILED_INIT;
+
+  /* Build CURLPROTO_* bit pattern with libcurl's built-in protocols */
+  built_in_protos = 0;
+  if(curlinfo->protocols) {
+    for(proto = curlinfo->protocols; *proto; proto++) {
+      for(p = possibly_built_in; p->proto_name; p++) {
+        if(curl_strequal(*proto, p->proto_name)) {
+          built_in_protos |= p->proto_pattern;
+          break;
+        }
+      }
+    }
+  }
+
+  return CURLE_OK;
+}
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_libinfo.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_libinfo.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_libinfo.h	(revision 331)
@@ -0,0 +1,34 @@
+#ifndef HEADER_CURL_TOOL_LIBINFO_H
+#define HEADER_CURL_TOOL_LIBINFO_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+/* global variable declarations, for libcurl run-time info */
+
+extern curl_version_info_data *curlinfo;
+extern long built_in_protos;
+
+CURLcode get_libcurl_info(void);
+
+#endif /* HEADER_CURL_TOOL_LIBINFO_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_main.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_main.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_main.c	(revision 331)
@@ -0,0 +1,284 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#include <sys/stat.h>
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#ifdef USE_NSS
+#include <nspr.h>
+#include <plarenas.h>
+#endif
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_cfgable.h"
+#include "tool_convert.h"
+#include "tool_msgs.h"
+#include "tool_operate.h"
+#include "tool_panykey.h"
+#include "tool_vms.h"
+#include "tool_main.h"
+#include "tool_libinfo.h"
+
+/*
+ * This is low-level hard-hacking memory leak tracking and similar. Using
+ * the library level code from this client-side is ugly, but we do this
+ * anyway for convenience.
+ */
+#include "memdebug.h" /* keep this as LAST include */
+
+#ifdef __VMS
+/*
+ * vms_show is a global variable, used in main() as parameter for
+ * function vms_special_exit() to allow proper curl tool exiting.
+ * Its value may be set in other tool_*.c source files thanks to
+ * forward declaration present in tool_vms.h
+ */
+int vms_show = 0;
+#endif
+
+#ifdef __MINGW32__
+/*
+ * There seems to be no way to escape "*" in command-line arguments with MinGW
+ * when command-line argument globbing is enabled under the MSYS shell, so turn
+ * it off.
+ */
+int _CRT_glob = 0;
+#endif /* __MINGW32__ */
+
+/* if we build a static library for unit tests, there is no main() function */
+#ifndef UNITTESTS
+
+/*
+ * Ensure that file descriptors 0, 1 and 2 (stdin, stdout, stderr) are
+ * open before starting to run.  Otherwise, the first three network
+ * sockets opened by curl could be used for input sources, downloaded data
+ * or error logs as they will effectively be stdin, stdout and/or stderr.
+ */
+static void main_checkfds(void)
+{
+#ifdef HAVE_PIPE
+  int fd[2] = { STDIN_FILENO, STDIN_FILENO };
+  while(fd[0] == STDIN_FILENO ||
+        fd[0] == STDOUT_FILENO ||
+        fd[0] == STDERR_FILENO ||
+        fd[1] == STDIN_FILENO ||
+        fd[1] == STDOUT_FILENO ||
+        fd[1] == STDERR_FILENO)
+    if(pipe(fd) < 0)
+      return;   /* Out of handles. This isn't really a big problem now, but
+                   will be when we try to create a socket later. */
+  close(fd[0]);
+  close(fd[1]);
+#endif
+}
+
+#ifdef CURLDEBUG
+static void memory_tracking_init(void)
+{
+  char *env;
+  /* if CURL_MEMDEBUG is set, this starts memory tracking message logging */
+  env = curlx_getenv("CURL_MEMDEBUG");
+  if(env) {
+    /* use the value as file name */
+    char fname[CURL_MT_LOGFNAME_BUFSIZE];
+    if(strlen(env) >= CURL_MT_LOGFNAME_BUFSIZE)
+      env[CURL_MT_LOGFNAME_BUFSIZE-1] = '\0';
+    strcpy(fname, env);
+    curl_free(env);
+    curl_memdebug(fname);
+    /* this weird stuff here is to make curl_free() get called
+       before curl_memdebug() as otherwise memory tracking will
+       log a free() without an alloc! */
+  }
+  /* if CURL_MEMLIMIT is set, this enables fail-on-alloc-number-N feature */
+  env = curlx_getenv("CURL_MEMLIMIT");
+  if(env) {
+    char *endptr;
+    long num = strtol(env, &endptr, 10);
+    if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
+      curl_memlimit(num);
+    curl_free(env);
+  }
+}
+#else
+#  define memory_tracking_init() Curl_nop_stmt
+#endif
+
+/*
+ * This is the main global constructor for the app. Call this before
+ * _any_ libcurl usage. If this fails, *NO* libcurl functions may be
+ * used, or havoc may be the result.
+ */
+static CURLcode main_init(struct GlobalConfig *config)
+{
+  CURLcode result = CURLE_OK;
+
+#if defined(__DJGPP__) || defined(__GO32__)
+  /* stop stat() wasting time */
+  _djstat_flags |= _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE;
+#endif
+
+  /* Initialise the global config */
+  config->showerror = -1;             /* Will show errors */
+  config->errors = stderr;            /* Default errors to stderr */
+
+  /* Allocate the initial operate config */
+  config->first = config->last = malloc(sizeof(struct OperationConfig));
+  if(config->first) {
+    /* Perform the libcurl initialization */
+    result = curl_global_init(CURL_GLOBAL_DEFAULT);
+    if(!result) {
+      /* Get information about libcurl */
+      result = get_libcurl_info();
+
+      if(!result) {
+        /* Get a curl handle to use for all forthcoming curl transfers */
+        config->easy = curl_easy_init();
+        if(config->easy) {
+          /* Initialise the config */
+          config_init(config->first);
+          config->first->easy = config->easy;
+          config->first->global = config;
+        }
+        else {
+          helpf(stderr, "error initializing curl easy handle\n");
+          result = CURLE_FAILED_INIT;
+          free(config->first);
+        }
+      }
+      else {
+        helpf(stderr, "error retrieving curl library information\n");
+        free(config->first);
+      }
+    }
+    else {
+      helpf(stderr, "error initializing curl library\n");
+      free(config->first);
+    }
+  }
+  else {
+    helpf(stderr, "error initializing curl\n");
+    result = CURLE_FAILED_INIT;
+  }
+
+  return result;
+}
+
+static void free_config_fields(struct GlobalConfig *config)
+{
+  Curl_safefree(config->trace_dump);
+
+  if(config->errors_fopened && config->errors)
+    fclose(config->errors);
+  config->errors = NULL;
+
+  if(config->trace_fopened && config->trace_stream)
+    fclose(config->trace_stream);
+  config->trace_stream = NULL;
+
+  Curl_safefree(config->libcurl);
+}
+
+/*
+ * This is the main global destructor for the app. Call this after
+ * _all_ libcurl usage is done.
+ */
+static void main_free(struct GlobalConfig *config)
+{
+  /* Cleanup the easy handle */
+  curl_easy_cleanup(config->easy);
+  config->easy = NULL;
+
+  /* Main cleanup */
+  curl_global_cleanup();
+  convert_cleanup();
+  metalink_cleanup();
+#ifdef USE_NSS
+  if(PR_Initialized()) {
+    /* prevent valgrind from reporting still reachable mem from NSRP arenas */
+    PL_ArenaFinish();
+    /* prevent valgrind from reporting possibly lost memory (fd cache, ...) */
+    PR_Cleanup();
+  }
+#endif
+  free_config_fields(config);
+
+  /* Free the config structures */
+  config_free(config->last);
+  config->first = NULL;
+  config->last = NULL;
+}
+
+/*
+** curl tool main function.
+*/
+int curl_main(int argc, char *argv[])
+{
+  CURLcode result = CURLE_OK;
+  struct GlobalConfig global;
+  memset(&global, 0, sizeof(global));
+
+  main_checkfds();
+
+#if defined(HAVE_SIGNAL) && defined(SIGPIPE)
+  (void)signal(SIGPIPE, SIG_IGN);
+#endif
+
+  /* Initialize memory tracking */
+  memory_tracking_init();
+
+  /* Initialize the curl library - do not call any libcurl functions before
+     this point */
+  result = main_init(&global);
+  if(!result) {
+    /* Start our curl operation */
+    result = operate(&global, argc, argv);
+
+#ifdef __SYMBIAN32__
+    if(global.showerror)
+      tool_pressanykey();
+#endif
+
+    /* Perform the main cleanup */
+    main_free(&global);
+  }
+
+#ifdef __NOVELL_LIBC__
+  if(getenv("_IN_NETWARE_BASH_") == NULL)
+    tool_pressanykey();
+#endif
+
+#ifdef __VMS
+  vms_special_exit(result, vms_show);
+#else
+  return (int)result;
+#endif
+}
+
+#endif /* ndef UNITTESTS */
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_main.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_main.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_main.h	(revision 331)
@@ -0,0 +1,44 @@
+#ifndef HEADER_CURL_TOOL_MAIN_H
+#define HEADER_CURL_TOOL_MAIN_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#define DEFAULT_MAXREDIRS  50L
+
+#define RETRY_SLEEP_DEFAULT 1000L   /* ms */
+#define RETRY_SLEEP_MAX     600000L /* ms == 10 minutes */
+
+#ifndef STDIN_FILENO
+#  define STDIN_FILENO  fileno(stdin)
+#endif
+
+#ifndef STDOUT_FILENO
+#  define STDOUT_FILENO  fileno(stdout)
+#endif
+
+#ifndef STDERR_FILENO
+#  define STDERR_FILENO  fileno(stderr)
+#endif
+
+#endif /* HEADER_CURL_TOOL_MAIN_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_metalink.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_metalink.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_metalink.c	(revision 331)
@@ -0,0 +1,1002 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#ifdef USE_METALINK
+
+#include <sys/stat.h>
+#include <stdlib.h>
+
+#ifdef HAVE_FCNTL_H
+#  include <fcntl.h>
+#endif
+
+#undef HAVE_NSS_CONTEXT
+
+#ifdef USE_OPENSSL
+#  include <openssl/md5.h>
+#  include <openssl/sha.h>
+#elif defined(USE_GNUTLS_NETTLE)
+#  include <nettle/md5.h>
+#  include <nettle/sha.h>
+#  define MD5_CTX    struct md5_ctx
+#  define SHA_CTX    struct sha1_ctx
+#  define SHA256_CTX struct sha256_ctx
+#elif defined(USE_GNUTLS)
+#  include <gcrypt.h>
+#  define MD5_CTX    gcry_md_hd_t
+#  define SHA_CTX    gcry_md_hd_t
+#  define SHA256_CTX gcry_md_hd_t
+#elif defined(USE_NSS)
+#  include <nss.h>
+#  include <pk11pub.h>
+#  define MD5_CTX    void *
+#  define SHA_CTX    void *
+#  define SHA256_CTX void *
+#  define HAVE_NSS_CONTEXT
+   static NSSInitContext *nss_context;
+#elif defined(USE_POLARSSL)
+#  include <polarssl/md5.h>
+#  include <polarssl/sha1.h>
+#  include <polarssl/sha256.h>
+#  define MD5_CTX    md5_context
+#  define SHA_CTX    sha1_context
+#  define SHA256_CTX sha256_context
+#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
+              (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
+      (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
+              (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
+/* For Apple operating systems: CommonCrypto has the functions we need.
+   The library's headers are even backward-compatible with OpenSSL's
+   headers as long as we define COMMON_DIGEST_FOR_OPENSSL first.
+
+   These functions are available on Tiger and later, as well as iOS 2.0
+   and later. If you're building for an older cat, well, sorry. */
+#  define COMMON_DIGEST_FOR_OPENSSL
+#  include <CommonCrypto/CommonDigest.h>
+#elif defined(_WIN32)
+/* For Windows: If no other crypto library is provided, we fallback
+   to the hash functions provided within the Microsoft Windows CryptoAPI */
+#  include <wincrypt.h>
+/* Custom structure in order to store the required provider and hash handle */
+struct win32_crypto_hash {
+  HCRYPTPROV hCryptProv;
+  HCRYPTHASH hHash;
+};
+/* Custom Microsoft AES Cryptographic Provider defines required for MinGW */
+#  ifndef ALG_SID_SHA_256
+#    define ALG_SID_SHA_256  12
+#  endif
+#  ifndef CALG_SHA_256
+#    define CALG_SHA_256 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_256)
+#  endif
+#  define MD5_CTX    struct win32_crypto_hash
+#  define SHA_CTX    struct win32_crypto_hash
+#  define SHA256_CTX struct win32_crypto_hash
+#else
+#  error "Can't compile METALINK support without a crypto library."
+#endif
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_getparam.h"
+#include "tool_paramhlp.h"
+#include "tool_cfgable.h"
+#include "tool_metalink.h"
+#include "tool_msgs.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+/* Copied from tool_getparam.c */
+#define GetStr(str,val) do { \
+  if(*(str)) { \
+    free(*(str)); \
+    *(str) = NULL; \
+  } \
+  if((val)) \
+    *(str) = strdup((val)); \
+  if(!(val)) \
+    return PARAM_NO_MEM; \
+} WHILE_FALSE
+
+#if defined(USE_OPENSSL)
+/* Functions are already defined */
+#elif defined(USE_GNUTLS_NETTLE)
+
+static int MD5_Init(MD5_CTX *ctx)
+{
+  md5_init(ctx);
+  return 1;
+}
+
+static void MD5_Update(MD5_CTX *ctx,
+                       const unsigned char *input,
+                       unsigned int inputLen)
+{
+  md5_update(ctx, inputLen, input);
+}
+
+static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
+{
+  md5_digest(ctx, 16, digest);
+}
+
+static int SHA1_Init(SHA_CTX *ctx)
+{
+  sha1_init(ctx);
+  return 1;
+}
+
+static void SHA1_Update(SHA_CTX *ctx,
+                        const unsigned char *input,
+                        unsigned int inputLen)
+{
+  sha1_update(ctx, inputLen, input);
+}
+
+static void SHA1_Final(unsigned char digest[20], SHA_CTX *ctx)
+{
+  sha1_digest(ctx, 20, digest);
+}
+
+static int SHA256_Init(SHA256_CTX *ctx)
+{
+  sha256_init(ctx);
+  return 1;
+}
+
+static void SHA256_Update(SHA256_CTX *ctx,
+                          const unsigned char *input,
+                          unsigned int inputLen)
+{
+  sha256_update(ctx, inputLen, input);
+}
+
+static void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx)
+{
+  sha256_digest(ctx, 32, digest);
+}
+
+#elif defined(USE_GNUTLS)
+
+static int MD5_Init(MD5_CTX *ctx)
+{
+  gcry_md_open(ctx, GCRY_MD_MD5, 0);
+  return 1;
+}
+
+static void MD5_Update(MD5_CTX *ctx,
+                       const unsigned char *input,
+                       unsigned int inputLen)
+{
+  gcry_md_write(*ctx, input, inputLen);
+}
+
+static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
+{
+  memcpy(digest, gcry_md_read(*ctx, 0), 16);
+  gcry_md_close(*ctx);
+}
+
+static int SHA1_Init(SHA_CTX *ctx)
+{
+  gcry_md_open(ctx, GCRY_MD_SHA1, 0);
+  return 1;
+}
+
+static void SHA1_Update(SHA_CTX *ctx,
+                        const unsigned char *input,
+                        unsigned int inputLen)
+{
+  gcry_md_write(*ctx, input, inputLen);
+}
+
+static void SHA1_Final(unsigned char digest[20], SHA_CTX *ctx)
+{
+  memcpy(digest, gcry_md_read(*ctx, 0), 20);
+  gcry_md_close(*ctx);
+}
+
+static int SHA256_Init(SHA256_CTX *ctx)
+{
+  gcry_md_open(ctx, GCRY_MD_SHA256, 0);
+  return 1;
+}
+
+static void SHA256_Update(SHA256_CTX *ctx,
+                          const unsigned char *input,
+                          unsigned int inputLen)
+{
+  gcry_md_write(*ctx, input, inputLen);
+}
+
+static void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx)
+{
+  memcpy(digest, gcry_md_read(*ctx, 0), 32);
+  gcry_md_close(*ctx);
+}
+
+#elif defined(USE_NSS)
+
+static int nss_hash_init(void **pctx, SECOidTag hash_alg)
+{
+  PK11Context *ctx;
+
+  /* we have to initialize NSS if not initialized alraedy */
+  if(!NSS_IsInitialized() && !nss_context) {
+    static NSSInitParameters params;
+    params.length = sizeof params;
+    nss_context = NSS_InitContext("", "", "", "", &params, NSS_INIT_READONLY
+        | NSS_INIT_NOCERTDB   | NSS_INIT_NOMODDB       | NSS_INIT_FORCEOPEN
+        | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
+  }
+
+  ctx = PK11_CreateDigestContext(hash_alg);
+  if(!ctx)
+    return /* failure */ 0;
+
+  if(PK11_DigestBegin(ctx) != SECSuccess) {
+    PK11_DestroyContext(ctx, PR_TRUE);
+    return /* failure */ 0;
+  }
+
+  *pctx = ctx;
+  return /* success */ 1;
+}
+
+static void nss_hash_final(void **pctx, unsigned char *out, unsigned int len)
+{
+  PK11Context *ctx = *pctx;
+  unsigned int outlen;
+  PK11_DigestFinal(ctx, out, &outlen, len);
+  PK11_DestroyContext(ctx, PR_TRUE);
+}
+
+static int MD5_Init(MD5_CTX *pctx)
+{
+  return nss_hash_init(pctx, SEC_OID_MD5);
+}
+
+static void MD5_Update(MD5_CTX *pctx,
+                       const unsigned char *input,
+                       unsigned int input_len)
+{
+  PK11_DigestOp(*pctx, input, input_len);
+}
+
+static void MD5_Final(unsigned char digest[16], MD5_CTX *pctx)
+{
+  nss_hash_final(pctx, digest, 16);
+}
+
+static int SHA1_Init(SHA_CTX *pctx)
+{
+  return nss_hash_init(pctx, SEC_OID_SHA1);
+}
+
+static void SHA1_Update(SHA_CTX *pctx,
+                        const unsigned char *input,
+                        unsigned int input_len)
+{
+  PK11_DigestOp(*pctx, input, input_len);
+}
+
+static void SHA1_Final(unsigned char digest[20], SHA_CTX *pctx)
+{
+  nss_hash_final(pctx, digest, 20);
+}
+
+static int SHA256_Init(SHA256_CTX *pctx)
+{
+  return nss_hash_init(pctx, SEC_OID_SHA256);
+}
+
+static void SHA256_Update(SHA256_CTX *pctx,
+                          const unsigned char *input,
+                          unsigned int input_len)
+{
+  PK11_DigestOp(*pctx, input, input_len);
+}
+
+static void SHA256_Final(unsigned char digest[32], SHA256_CTX *pctx)
+{
+  nss_hash_final(pctx, digest, 32);
+}
+
+#elif defined(USE_POLARSSL)
+
+static int MD5_Init(MD5_CTX *ctx)
+{
+  md5_starts(ctx);
+  return 1;
+}
+
+static void MD5_Update(MD5_CTX *ctx,
+                       const unsigned char *input,
+                       unsigned int inputLen)
+{
+  md5_update(ctx, input, inputLen);
+}
+
+static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
+{
+  md5_finish(ctx, digest);
+}
+
+static int SHA1_Init(SHA_CTX *ctx)
+{
+  sha1_starts(ctx);
+  return 1;
+}
+
+static void SHA1_Update(SHA_CTX *ctx,
+                        const unsigned char *input,
+                        unsigned int inputLen)
+{
+  sha1_update(ctx, input, inputLen);
+}
+
+static void SHA1_Final(unsigned char digest[20], SHA_CTX *ctx)
+{
+  sha1_finish(ctx, digest);
+}
+
+static int SHA256_Init(SHA256_CTX *ctx)
+{
+  sha256_starts(ctx, 0); /* 0 = sha256 */
+  return 1;
+}
+
+static void SHA256_Update(SHA256_CTX *ctx,
+                          const unsigned char *input,
+                          unsigned int inputLen)
+{
+  sha256_update(ctx, input, inputLen);
+}
+
+static void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx)
+{
+  sha256_finish(ctx, digest);
+}
+
+#elif defined(_WIN32)
+
+static void win32_crypto_final(struct win32_crypto_hash *ctx,
+                               unsigned char *digest,
+                               unsigned int digestLen)
+{
+  unsigned long length;
+  CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
+  if(length == digestLen)
+    CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0);
+  if(ctx->hHash)
+    CryptDestroyHash(ctx->hHash);
+  if(ctx->hCryptProv)
+    CryptReleaseContext(ctx->hCryptProv, 0);
+}
+
+static int MD5_Init(MD5_CTX *ctx)
+{
+  if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
+                         PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
+    CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash);
+  }
+  return 1;
+}
+
+static void MD5_Update(MD5_CTX *ctx,
+                       const unsigned char *input,
+                       unsigned int inputLen)
+{
+  CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
+}
+
+static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
+{
+  win32_crypto_final(ctx, digest, 16);
+}
+
+static int SHA1_Init(SHA_CTX *ctx)
+{
+  if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
+                         PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
+    CryptCreateHash(ctx->hCryptProv, CALG_SHA1, 0, 0, &ctx->hHash);
+  }
+  return 1;
+}
+
+static void SHA1_Update(SHA_CTX *ctx,
+                        const unsigned char *input,
+                        unsigned int inputLen)
+{
+  CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
+}
+
+static void SHA1_Final(unsigned char digest[20], SHA_CTX *ctx)
+{
+  win32_crypto_final(ctx, digest, 20);
+}
+
+static int SHA256_Init(SHA256_CTX *ctx)
+{
+  if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL,
+                         PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
+    CryptCreateHash(ctx->hCryptProv, CALG_SHA_256, 0, 0, &ctx->hHash);
+  }
+  return 1;
+}
+
+static void SHA256_Update(SHA256_CTX *ctx,
+                          const unsigned char *input,
+                          unsigned int inputLen)
+{
+  CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
+}
+
+static void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx)
+{
+  win32_crypto_final(ctx, digest, 32);
+}
+
+#endif /* CRYPTO LIBS */
+
+const digest_params MD5_DIGEST_PARAMS[] = {
+  {
+    (Curl_digest_init_func) MD5_Init,
+    (Curl_digest_update_func) MD5_Update,
+    (Curl_digest_final_func) MD5_Final,
+    sizeof(MD5_CTX),
+    16
+  }
+};
+
+const digest_params SHA1_DIGEST_PARAMS[] = {
+  {
+    (Curl_digest_init_func) SHA1_Init,
+    (Curl_digest_update_func) SHA1_Update,
+    (Curl_digest_final_func) SHA1_Final,
+    sizeof(SHA_CTX),
+    20
+  }
+};
+
+const digest_params SHA256_DIGEST_PARAMS[] = {
+  {
+    (Curl_digest_init_func) SHA256_Init,
+    (Curl_digest_update_func) SHA256_Update,
+    (Curl_digest_final_func) SHA256_Final,
+    sizeof(SHA256_CTX),
+    32
+  }
+};
+
+static const metalink_digest_def SHA256_DIGEST_DEF[] = {
+  {"sha-256", SHA256_DIGEST_PARAMS}
+};
+
+static const metalink_digest_def SHA1_DIGEST_DEF[] = {
+  {"sha-1", SHA1_DIGEST_PARAMS}
+};
+
+static const metalink_digest_def MD5_DIGEST_DEF[] = {
+  {"md5", MD5_DIGEST_PARAMS}
+};
+
+/*
+ * The alias of supported hash functions in the order by preference
+ * (basically stronger hash comes first). We included "sha-256" and
+ * "sha256". The former is the name defined in the IANA registry named
+ * "Hash Function Textual Names". The latter is widely (and
+ * historically) used in Metalink version 3.
+ */
+static const metalink_digest_alias digest_aliases[] = {
+  {"sha-256", SHA256_DIGEST_DEF},
+  {"sha256", SHA256_DIGEST_DEF},
+  {"sha-1", SHA1_DIGEST_DEF},
+  {"sha1", SHA1_DIGEST_DEF},
+  {"md5", MD5_DIGEST_DEF},
+  {NULL, NULL}
+};
+
+digest_context *Curl_digest_init(const digest_params *dparams)
+{
+  digest_context *ctxt;
+
+  /* Create digest context */
+  ctxt = malloc(sizeof *ctxt);
+
+  if(!ctxt)
+    return ctxt;
+
+  ctxt->digest_hashctx = malloc(dparams->digest_ctxtsize);
+
+  if(!ctxt->digest_hashctx) {
+    free(ctxt);
+    return NULL;
+  }
+
+  ctxt->digest_hash = dparams;
+
+  if(dparams->digest_init(ctxt->digest_hashctx) != 1) {
+    free(ctxt->digest_hashctx);
+    free(ctxt);
+    return NULL;
+  }
+
+  return ctxt;
+}
+
+int Curl_digest_update(digest_context *context,
+                       const unsigned char *data,
+                       unsigned int len)
+{
+  (*context->digest_hash->digest_update)(context->digest_hashctx, data, len);
+
+  return 0;
+}
+
+int Curl_digest_final(digest_context *context, unsigned char *result)
+{
+  if(result)
+    (*context->digest_hash->digest_final)(result, context->digest_hashctx);
+
+  free(context->digest_hashctx);
+  free(context);
+
+  return 0;
+}
+
+static unsigned char hex_to_uint(const char *s)
+{
+  char buf[3];
+  unsigned long val;
+  buf[0] = s[0];
+  buf[1] = s[1];
+  buf[2] = 0;
+  val = strtoul(buf, NULL, 16);
+  return (unsigned char)(val&0xff);
+}
+
+/*
+ * Check checksum of file denoted by filename. The expected hash value
+ * is given in hex_hash which is hex-encoded string.
+ *
+ * This function returns 1 if it succeeds or one of the following
+ * integers:
+ *
+ * 0:
+ *   Checksum didn't match.
+ * -1:
+ *   Could not open file; or could not read data from file.
+ * -2:
+ *   Hash algorithm not available.
+ */
+static int check_hash(const char *filename,
+                      const metalink_digest_def *digest_def,
+                      const unsigned char *digest, FILE *error)
+{
+  unsigned char *result;
+  digest_context *dctx;
+  int check_ok, flags, fd;
+
+  flags = O_RDONLY;
+#ifdef O_BINARY
+  /* O_BINARY is required in order to avoid binary EOF in text mode */
+  flags |= O_BINARY;
+#endif
+
+  fd = open(filename, flags);
+  if(fd == -1) {
+    fprintf(error, "Metalink: validating (%s) [%s] FAILED (%s)\n", filename,
+            digest_def->hash_name, strerror(errno));
+    return -1;
+  }
+
+  dctx = Curl_digest_init(digest_def->dparams);
+  if(!dctx) {
+    fprintf(error, "Metalink: validating (%s) [%s] FAILED (%s)\n", filename,
+            digest_def->hash_name, "failed to initialize hash algorithm");
+    close(fd);
+    return -2;
+  }
+
+  result = malloc(digest_def->dparams->digest_resultlen);
+  if(!result) {
+    close(fd);
+    Curl_digest_final(dctx, NULL);
+    return -1;
+  }
+  while(1) {
+    unsigned char buf[4096];
+    ssize_t len = read(fd, buf, sizeof(buf));
+    if(len == 0) {
+      break;
+    }
+    else if(len == -1) {
+      fprintf(error, "Metalink: validating (%s) [%s] FAILED (%s)\n", filename,
+              digest_def->hash_name, strerror(errno));
+      Curl_digest_final(dctx, result);
+      close(fd);
+      return -1;
+    }
+    Curl_digest_update(dctx, buf, (unsigned int)len);
+  }
+  Curl_digest_final(dctx, result);
+  check_ok = memcmp(result, digest,
+                    digest_def->dparams->digest_resultlen) == 0;
+  /* sha*sum style verdict output */
+  if(check_ok)
+    fprintf(error, "Metalink: validating (%s) [%s] OK\n", filename,
+            digest_def->hash_name);
+  else
+    fprintf(error, "Metalink: validating (%s) [%s] FAILED (digest mismatch)\n",
+            filename, digest_def->hash_name);
+
+  free(result);
+  close(fd);
+  return check_ok;
+}
+
+int metalink_check_hash(struct GlobalConfig *config,
+                        metalinkfile *mlfile,
+                        const char *filename)
+{
+  int rv;
+  fprintf(config->errors, "Metalink: validating (%s)...\n", filename);
+  if(mlfile->checksum == NULL) {
+    fprintf(config->errors,
+            "Metalink: validating (%s) FAILED (digest missing)\n", filename);
+    return -2;
+  }
+  rv = check_hash(filename, mlfile->checksum->digest_def,
+                  mlfile->checksum->digest, config->errors);
+  return rv;
+}
+
+static metalink_checksum *new_metalink_checksum_from_hex_digest
+(const metalink_digest_def *digest_def, const char *hex_digest)
+{
+  metalink_checksum *chksum;
+  unsigned char *digest;
+  size_t i;
+  size_t len = strlen(hex_digest);
+  digest = malloc(len/2);
+  if(!digest)
+    return 0;
+
+  for(i = 0; i < len; i += 2) {
+    digest[i/2] = hex_to_uint(hex_digest + i);
+  }
+  chksum = malloc(sizeof(metalink_checksum));
+  if(chksum) {
+    chksum->digest_def = digest_def;
+    chksum->digest = digest;
+  }
+  else
+    free(digest);
+  return chksum;
+}
+
+static metalink_resource *new_metalink_resource(const char *url)
+{
+  metalink_resource *res;
+  res = malloc(sizeof(metalink_resource));
+  if(res) {
+    res->next = NULL;
+    res->url = strdup(url);
+    if(!res->url) {
+      free(res);
+      return NULL;
+    }
+  }
+  return res;
+}
+
+/* Returns nonzero if hex_digest is properly formatted; that is each
+   letter is in [0-9A-Za-z] and the length of the string equals to the
+   result length of digest * 2. */
+static int check_hex_digest(const char *hex_digest,
+                            const metalink_digest_def *digest_def)
+{
+  size_t i;
+  for(i = 0; hex_digest[i]; ++i) {
+    char c = hex_digest[i];
+    if(!(('0' <= c && c <= '9') || ('a' <= c && c <= 'z') ||
+         ('A' <= c && c <= 'Z'))) {
+      return 0;
+    }
+  }
+  return digest_def->dparams->digest_resultlen * 2 == i;
+}
+
+static metalinkfile *new_metalinkfile(metalink_file_t *fileinfo)
+{
+  metalinkfile *f;
+  f = (metalinkfile*)malloc(sizeof(metalinkfile));
+  if(!f)
+    return NULL;
+
+  f->next = NULL;
+  f->filename = strdup(fileinfo->name);
+  if(!f->filename) {
+    free(f);
+    return NULL;
+  }
+  f->checksum = NULL;
+  f->resource = NULL;
+  if(fileinfo->checksums) {
+    const metalink_digest_alias *digest_alias;
+    for(digest_alias = digest_aliases; digest_alias->alias_name;
+        ++digest_alias) {
+      metalink_checksum_t **p;
+      for(p = fileinfo->checksums; *p; ++p) {
+        if(curl_strequal(digest_alias->alias_name, (*p)->type) &&
+           check_hex_digest((*p)->hash, digest_alias->digest_def)) {
+          f->checksum =
+            new_metalink_checksum_from_hex_digest(digest_alias->digest_def,
+                                                  (*p)->hash);
+          break;
+        }
+      }
+      if(f->checksum) {
+        break;
+      }
+    }
+  }
+  if(fileinfo->resources) {
+    metalink_resource_t **p;
+    metalink_resource root, *tail;
+    root.next = NULL;
+    tail = &root;
+    for(p = fileinfo->resources; *p; ++p) {
+      metalink_resource *res;
+      /* Filter by type if it is non-NULL. In Metalink v3, type
+         includes the type of the resource. In curl, we are only
+         interested in HTTP, HTTPS and FTP. In addition to them,
+         Metalink v3 file may contain bittorrent type URL, which
+         points to the BitTorrent metainfo file. We ignore it here.
+         In Metalink v4, type was deprecated and all
+         fileinfo->resources point to the target file. BitTorrent
+         metainfo file URL may be appeared in fileinfo->metaurls.
+      */
+      if((*p)->type == NULL ||
+         curl_strequal((*p)->type, "http") ||
+         curl_strequal((*p)->type, "https") ||
+         curl_strequal((*p)->type, "ftp") ||
+         curl_strequal((*p)->type, "ftps")) {
+        res = new_metalink_resource((*p)->url);
+        if(res) {
+          tail->next = res;
+          tail = res;
+        }
+        else {
+          tail = root.next;
+
+          /* clean up the linked list */
+          while(tail) {
+            res = tail->next;
+            free(tail->url);
+            free(tail);
+            tail = res;
+          }
+          free(f->filename);
+          free(f);
+          return NULL;
+        }
+      }
+    }
+    f->resource = root.next;
+  }
+  return f;
+}
+
+int parse_metalink(struct OperationConfig *config, struct OutStruct *outs,
+                   const char *metalink_url)
+{
+  metalink_error_t r;
+  metalink_t* metalink;
+  metalink_file_t **files;
+  bool warnings = FALSE;
+
+  /* metlaink_parse_final deletes outs->metalink_parser */
+  r = metalink_parse_final(outs->metalink_parser, NULL, 0, &metalink);
+  outs->metalink_parser = NULL;
+  if(r != 0) {
+    return -1;
+  }
+  if(metalink->files == NULL) {
+    fprintf(config->global->errors, "Metalink: parsing (%s) WARNING "
+            "(missing or invalid file name)\n",
+            metalink_url);
+    metalink_delete(metalink);
+    return -1;
+  }
+  for(files = metalink->files; *files; ++files) {
+    struct getout *url;
+    /* Skip an entry which has no resource. */
+    if(!(*files)->resources) {
+      fprintf(config->global->errors, "Metalink: parsing (%s) WARNING "
+              "(missing or invalid resource)\n",
+              metalink_url);
+      continue;
+    }
+    if(config->url_get ||
+       ((config->url_get = config->url_list) != NULL)) {
+      /* there's a node here, if it already is filled-in continue to
+         find an "empty" node */
+      while(config->url_get && (config->url_get->flags & GETOUT_URL))
+        config->url_get = config->url_get->next;
+    }
+
+    /* now there might or might not be an available node to fill in! */
+
+    if(config->url_get)
+      /* existing node */
+      url = config->url_get;
+    else
+      /* there was no free node, create one! */
+      url = new_getout(config);
+
+    if(url) {
+      metalinkfile *mlfile = new_metalinkfile(*files);
+      if(!mlfile)
+        break;
+
+      if(!mlfile->checksum) {
+        warnings = TRUE;
+        fprintf(config->global->errors,
+                "Metalink: parsing (%s) WARNING (digest missing)\n",
+                metalink_url);
+      }
+      /* Set name as url */
+      GetStr(&url->url, mlfile->filename);
+
+      /* set flag metalink here */
+      url->flags |= GETOUT_URL | GETOUT_METALINK;
+
+      if(config->metalinkfile_list) {
+        config->metalinkfile_last->next = mlfile;
+        config->metalinkfile_last = mlfile;
+      }
+      else {
+        config->metalinkfile_list = config->metalinkfile_last = mlfile;
+      }
+    }
+  }
+  metalink_delete(metalink);
+  return (warnings) ? -2 : 0;
+}
+
+size_t metalink_write_cb(void *buffer, size_t sz, size_t nmemb,
+                         void *userdata)
+{
+  struct OutStruct *outs = userdata;
+  struct OperationConfig *config = outs->config;
+  int rv;
+
+  /*
+   * Once that libcurl has called back tool_write_cb() the returned value
+   * is checked against the amount that was intended to be written, if
+   * it does not match then it fails with CURLE_WRITE_ERROR. So at this
+   * point returning a value different from sz*nmemb indicates failure.
+   */
+  const size_t failure = (sz && nmemb) ? 0 : 1;
+
+  if(!config)
+    return failure;
+
+  rv = metalink_parse_update(outs->metalink_parser, buffer, sz * nmemb);
+  if(rv == 0)
+    return sz * nmemb;
+  else {
+    fprintf(config->global->errors, "Metalink: parsing FAILED\n");
+    return failure;
+  }
+}
+
+/*
+ * Returns nonzero if content_type includes mediatype.
+ */
+static int check_content_type(const char *content_type, const char *media_type)
+{
+  const char *ptr = content_type;
+  size_t media_type_len = strlen(media_type);
+  for(; *ptr && (*ptr == ' ' || *ptr == '\t'); ++ptr);
+  if(!*ptr) {
+    return 0;
+  }
+  return curl_strnequal(ptr, media_type, media_type_len) &&
+    (*(ptr + media_type_len) == '\0' || *(ptr + media_type_len) == ' ' ||
+     *(ptr + media_type_len) == '\t' || *(ptr + media_type_len) == ';');
+}
+
+int check_metalink_content_type(const char *content_type)
+{
+  return check_content_type(content_type, "application/metalink+xml");
+}
+
+int count_next_metalink_resource(metalinkfile *mlfile)
+{
+  int count = 0;
+  metalink_resource *res;
+  for(res = mlfile->resource; res; res = res->next, ++count);
+  return count;
+}
+
+static void delete_metalink_checksum(metalink_checksum *chksum)
+{
+  if(chksum == NULL) {
+    return;
+  }
+  Curl_safefree(chksum->digest);
+  Curl_safefree(chksum);
+}
+
+static void delete_metalink_resource(metalink_resource *res)
+{
+  if(res == NULL) {
+    return;
+  }
+  Curl_safefree(res->url);
+  Curl_safefree(res);
+}
+
+static void delete_metalinkfile(metalinkfile *mlfile)
+{
+  metalink_resource *res;
+  if(mlfile == NULL) {
+    return;
+  }
+  Curl_safefree(mlfile->filename);
+  delete_metalink_checksum(mlfile->checksum);
+  for(res = mlfile->resource; res;) {
+    metalink_resource *next;
+    next = res->next;
+    delete_metalink_resource(res);
+    res = next;
+  }
+  Curl_safefree(mlfile);
+}
+
+void clean_metalink(struct OperationConfig *config)
+{
+  while(config->metalinkfile_list) {
+    metalinkfile *mlfile = config->metalinkfile_list;
+    config->metalinkfile_list = config->metalinkfile_list->next;
+    delete_metalinkfile(mlfile);
+  }
+  config->metalinkfile_last = 0;
+}
+
+void metalink_cleanup(void)
+{
+#ifdef HAVE_NSS_CONTEXT
+  if(nss_context) {
+    NSS_ShutdownContext(nss_context);
+    nss_context = NULL;
+  }
+#endif
+}
+
+#endif /* USE_METALINK */
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_metalink.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_metalink.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_metalink.h	(revision 331)
@@ -0,0 +1,167 @@
+#ifndef HEADER_CURL_TOOL_METALINK_H
+#define HEADER_CURL_TOOL_METALINK_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+struct GlobalConfig;
+struct OperationConfig;
+
+/* returns 1 for success, 0 otherwise (we use OpenSSL *_Init fncs directly) */
+typedef int (* Curl_digest_init_func)(void *context);
+
+typedef void (* Curl_digest_update_func)(void *context,
+                                         const unsigned char *data,
+                                         unsigned int len);
+typedef void (* Curl_digest_final_func)(unsigned char *result, void *context);
+
+typedef struct {
+  Curl_digest_init_func     digest_init;   /* Initialize context procedure */
+  Curl_digest_update_func   digest_update; /* Update context with data */
+  Curl_digest_final_func    digest_final;  /* Get final result procedure */
+  unsigned int           digest_ctxtsize;  /* Context structure size */
+  unsigned int           digest_resultlen; /* Result length (bytes) */
+} digest_params;
+
+typedef struct {
+  const digest_params   *digest_hash;      /* Hash function definition */
+  void                  *digest_hashctx;   /* Hash function context */
+} digest_context;
+
+digest_context * Curl_digest_init(const digest_params *dparams);
+int Curl_digest_update(digest_context *context,
+                       const unsigned char *data,
+                       unsigned int len);
+int Curl_digest_final(digest_context *context, unsigned char *result);
+
+typedef struct {
+  const char *hash_name;
+  const digest_params *dparams;
+} metalink_digest_def;
+
+typedef struct {
+  const char *alias_name;
+  const metalink_digest_def *digest_def;
+} metalink_digest_alias;
+
+typedef struct metalink_checksum {
+  const metalink_digest_def *digest_def;
+  /* raw digest value, not ascii hex digest */
+  unsigned char *digest;
+} metalink_checksum;
+
+typedef struct metalink_resource {
+  struct metalink_resource *next;
+  char *url;
+} metalink_resource;
+
+typedef struct metalinkfile {
+  struct metalinkfile *next;
+  char *filename;
+  metalink_checksum *checksum;
+  metalink_resource *resource;
+} metalinkfile;
+
+#ifdef USE_METALINK
+
+/*
+ * curl requires libmetalink 0.1.0 or newer
+ */
+#define CURL_REQ_LIBMETALINK_MAJOR  0
+#define CURL_REQ_LIBMETALINK_MINOR  1
+#define CURL_REQ_LIBMETALINK_PATCH  0
+
+#define CURL_REQ_LIBMETALINK_VERS  ((CURL_REQ_LIBMETALINK_MAJOR * 10000) + \
+                                    (CURL_REQ_LIBMETALINK_MINOR * 100) + \
+                                     CURL_REQ_LIBMETALINK_PATCH)
+
+extern const digest_params MD5_DIGEST_PARAMS[1];
+extern const digest_params SHA1_DIGEST_PARAMS[1];
+extern const digest_params SHA256_DIGEST_PARAMS[1];
+
+#include <metalink/metalink.h>
+
+/*
+ * Counts the resource in the metalinkfile.
+ */
+int count_next_metalink_resource(metalinkfile *mlfile);
+void clean_metalink(struct OperationConfig *config);
+
+/*
+ * Performs final parse operation and extracts information from
+ * Metalink and creates metalinkfile structs.
+ *
+ * This function returns 0 if it succeeds without warnings, or one of
+ * the following negative error codes:
+ *
+ * -1: Parsing failed; or no file is found
+ * -2: Parsing succeeded with some warnings.
+ */
+int parse_metalink(struct OperationConfig *config, struct OutStruct *outs,
+                   const char *metalink_url);
+
+/*
+ * Callback function for CURLOPT_WRITEFUNCTION
+ */
+size_t metalink_write_cb(void *buffer, size_t sz, size_t nmemb,
+                         void *userdata);
+
+/*
+ * Returns nonzero if content_type includes "application/metalink+xml"
+ * media-type. The check is done in case-insensitive manner.
+ */
+int check_metalink_content_type(const char *content_type);
+
+/*
+ * Check checksum of file denoted by filename.
+ *
+ * This function returns 1 if the checksum matches or one of the
+ * following integers:
+ *
+ * 0:
+ *   Checksum didn't match.
+ * -1:
+ *   Could not open file; or could not read data from file.
+ * -2:
+ *   No checksum in Metalink supported, hash algorithm not available, or
+ *   Metalink does not contain checksum.
+ */
+int metalink_check_hash(struct GlobalConfig *config,
+                        metalinkfile *mlfile,
+                        const char *filename);
+
+/*
+ * Release resources allocated at global scope.
+ */
+void metalink_cleanup(void);
+
+#else /* USE_METALINK */
+
+#define count_next_metalink_resource(x)  0
+#define clean_metalink(x)  (void)x
+
+/* metalink_cleanup() takes no arguments */
+#define metalink_cleanup() Curl_nop_stmt
+
+#endif /* USE_METALINK */
+
+#endif /* HEADER_CURL_TOOL_METALINK_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_msgs.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_msgs.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_msgs.c	(revision 331)
@@ -0,0 +1,121 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_cfgable.h"
+#include "tool_msgs.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+#define WARN_PREFIX "Warning: "
+#define NOTE_PREFIX "Note: "
+
+static void voutf(struct GlobalConfig *config,
+                  const char *prefix,
+                  const char *fmt,
+                  va_list ap)
+{
+  size_t width = (79 - strlen(prefix));
+  if(!config->mute) {
+    size_t len;
+    char *ptr;
+    char print_buffer[256];
+
+    len = vsnprintf(print_buffer, sizeof(print_buffer), fmt, ap);
+
+    ptr = print_buffer;
+    while(len > 0) {
+      fputs(prefix, config->errors);
+
+      if(len > width) {
+        size_t cut = width-1;
+
+        while(!ISSPACE(ptr[cut]) && cut) {
+          cut--;
+        }
+        if(0 == cut)
+          /* not a single cutting position was found, just cut it at the
+             max text width then! */
+          cut = width-1;
+
+        (void)fwrite(ptr, cut + 1, 1, config->errors);
+        fputs("\n", config->errors);
+        ptr += cut + 1; /* skip the space too */
+        len -= cut;
+      }
+      else {
+        fputs(ptr, config->errors);
+        len = 0;
+      }
+    }
+  }
+}
+
+/*
+ * Emit 'note' formatted message on configured 'errors' stream, if verbose was
+ * selected.
+ */
+void notef(struct GlobalConfig *config, const char *fmt, ...)
+{
+  va_list ap;
+  va_start(ap, fmt);
+  if(config->tracetype)
+    voutf(config, NOTE_PREFIX, fmt, ap);
+  va_end(ap);
+}
+
+/*
+ * Emit warning formatted message on configured 'errors' stream unless
+ * mute (--silent) was selected.
+ */
+
+void warnf(struct GlobalConfig *config, const char *fmt, ...)
+{
+  va_list ap;
+  va_start(ap, fmt);
+  voutf(config, WARN_PREFIX, fmt, ap);
+  va_end(ap);
+}
+/*
+ * Emit help formatted message on given stream.
+ */
+
+void helpf(FILE *errors, const char *fmt, ...)
+{
+  va_list ap;
+  if(fmt) {
+    va_start(ap, fmt);
+    fputs("curl: ", errors); /* prefix it */
+    vfprintf(errors, fmt, ap);
+    va_end(ap);
+  }
+  fprintf(errors, "curl: try 'curl --help' "
+#ifdef USE_MANUAL
+          "or 'curl --manual' "
+#endif
+          "for more information\n");
+}
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_msgs.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_msgs.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_msgs.h	(revision 331)
@@ -0,0 +1,32 @@
+#ifndef HEADER_CURL_TOOL_MSGS_H
+#define HEADER_CURL_TOOL_MSGS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+void warnf(struct GlobalConfig *config, const char *fmt, ...);
+void notef(struct GlobalConfig *config, const char *fmt, ...);
+
+void helpf(FILE *errors, const char *fmt, ...);
+
+#endif /* HEADER_CURL_TOOL_MSGS_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_operate.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_operate.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_operate.c	(revision 331)
@@ -0,0 +1,2090 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#ifdef HAVE_FCNTL_H
+#  include <fcntl.h>
+#endif
+
+#ifdef HAVE_UTIME_H
+#  include <utime.h>
+#elif defined(HAVE_SYS_UTIME_H)
+#  include <sys/utime.h>
+#endif
+
+#ifdef HAVE_LOCALE_H
+#  include <locale.h>
+#endif
+
+#ifdef __VMS
+#  include <fabdef.h>
+#endif
+
+#include "strcase.h"
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_binmode.h"
+#include "tool_cfgable.h"
+#include "tool_cb_dbg.h"
+#include "tool_cb_hdr.h"
+#include "tool_cb_prg.h"
+#include "tool_cb_rea.h"
+#include "tool_cb_see.h"
+#include "tool_cb_wrt.h"
+#include "tool_dirhie.h"
+#include "tool_doswin.h"
+#include "tool_easysrc.h"
+#include "tool_getparam.h"
+#include "tool_helpers.h"
+#include "tool_homedir.h"
+#include "tool_libinfo.h"
+#include "tool_main.h"
+#include "tool_metalink.h"
+#include "tool_msgs.h"
+#include "tool_operate.h"
+#include "tool_operhlp.h"
+#include "tool_paramhlp.h"
+#include "tool_parsecfg.h"
+#include "tool_setopt.h"
+#include "tool_sleep.h"
+#include "tool_urlglob.h"
+#include "tool_util.h"
+#include "tool_writeout.h"
+#include "tool_xattr.h"
+#include "tool_vms.h"
+#include "tool_help.h"
+#include "tool_hugehelp.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+#ifdef CURLDEBUG
+/* libcurl's debug builds provide an extra function */
+CURLcode curl_easy_perform_ev(CURL *easy);
+#endif
+
+#define CURLseparator  "--_curl_--"
+
+#ifndef O_BINARY
+/* since O_BINARY as used in bitmasks, setting it to zero makes it usable in
+   source code but yet it doesn't ruin anything */
+#  define O_BINARY 0
+#endif
+
+#define CURL_CA_CERT_ERRORMSG                                               \
+  "More details here: https://curl.haxx.se/docs/sslcerts.html\n\n"          \
+  "curl failed to verify the legitimacy of the server and therefore "       \
+  "could not\nestablish a secure connection to it. To learn more about "    \
+  "this situation and\nhow to fix it, please visit the web page mentioned " \
+  "above.\n"
+
+static bool is_fatal_error(CURLcode code)
+{
+  switch(code) {
+  /* TODO: Should CURLE_SSL_CACERT be included as critical error ? */
+  case CURLE_FAILED_INIT:
+  case CURLE_OUT_OF_MEMORY:
+  case CURLE_UNKNOWN_OPTION:
+  case CURLE_FUNCTION_NOT_FOUND:
+  case CURLE_BAD_FUNCTION_ARGUMENT:
+    /* critical error */
+    return TRUE;
+  default:
+    break;
+  }
+
+  /* no error or not critical */
+  return FALSE;
+}
+
+#ifdef __VMS
+/*
+ * get_vms_file_size does what it takes to get the real size of the file
+ *
+ * For fixed files, find out the size of the EOF block and adjust.
+ *
+ * For all others, have to read the entire file in, discarding the contents.
+ * Most posted text files will be small, and binary files like zlib archives
+ * and CD/DVD images should be either a STREAM_LF format or a fixed format.
+ *
+ */
+static curl_off_t vms_realfilesize(const char *name,
+                                   const struct_stat *stat_buf)
+{
+  char buffer[8192];
+  curl_off_t count;
+  int ret_stat;
+  FILE * file;
+
+  /* !checksrc! disable FOPENMODE 1 */
+  file = fopen(name, "r"); /* VMS */
+  if(file == NULL) {
+    return 0;
+  }
+  count = 0;
+  ret_stat = 1;
+  while(ret_stat > 0) {
+    ret_stat = fread(buffer, 1, sizeof(buffer), file);
+    if(ret_stat != 0)
+      count += ret_stat;
+  }
+  fclose(file);
+
+  return count;
+}
+
+/*
+ *
+ *  VmsSpecialSize checks to see if the stat st_size can be trusted and
+ *  if not to call a routine to get the correct size.
+ *
+ */
+static curl_off_t VmsSpecialSize(const char *name,
+                                 const struct_stat *stat_buf)
+{
+  switch(stat_buf->st_fab_rfm) {
+  case FAB$C_VAR:
+  case FAB$C_VFC:
+    return vms_realfilesize(name, stat_buf);
+    break;
+  default:
+    return stat_buf->st_size;
+  }
+}
+#endif /* __VMS */
+
+#if defined(HAVE_UTIME) || \
+    (defined(WIN32) && (SIZEOF_CURL_OFF_T >= 8))
+static void setfiletime(long filetime, const char *filename,
+                        FILE *error_stream)
+{
+  if(filetime >= 0) {
+/* Windows utime() may attempt to adjust our unix gmt 'filetime' by a daylight
+   saving time offset and since it's GMT that is bad behavior. When we have
+   access to a 64-bit type we can bypass utime and set the times directly. */
+#if defined(WIN32) && (SIZEOF_CURL_OFF_T >= 8)
+    HANDLE hfile;
+
+#if (SIZEOF_LONG >= 8)
+    /* 910670515199 is the maximum unix filetime that can be used as a
+       Windows FILETIME without overflow: 30827-12-31T23:59:59. */
+    if(filetime > CURL_OFF_T_C(910670515199)) {
+      fprintf(error_stream,
+              "Failed to set filetime %ld on outfile: overflow\n",
+              filetime);
+      return;
+    }
+#endif /* SIZEOF_LONG >= 8 */
+
+    hfile = CreateFileA(filename, FILE_WRITE_ATTRIBUTES,
+                        (FILE_SHARE_READ | FILE_SHARE_WRITE |
+                         FILE_SHARE_DELETE),
+                        NULL, OPEN_EXISTING, 0, NULL);
+    if(hfile != INVALID_HANDLE_VALUE) {
+      curl_off_t converted = ((curl_off_t)filetime * 10000000) +
+                             CURL_OFF_T_C(116444736000000000);
+      FILETIME ft;
+      ft.dwLowDateTime = (DWORD)(converted & 0xFFFFFFFF);
+      ft.dwHighDateTime = (DWORD)(converted >> 32);
+      if(!SetFileTime(hfile, NULL, &ft, &ft)) {
+        fprintf(error_stream,
+                "Failed to set filetime %ld on outfile: "
+                "SetFileTime failed: GetLastError %u\n",
+                filetime, GetLastError());
+      }
+      CloseHandle(hfile);
+    }
+    else {
+      fprintf(error_stream,
+              "Failed to set filetime %ld on outfile: "
+              "CreateFile failed: GetLastError %u\n",
+              filetime, GetLastError());
+    }
+
+#elif defined(HAVE_UTIMES)
+    struct timeval times[2];
+    times[0].tv_sec = times[1].tv_sec = filetime;
+    times[0].tv_usec = times[1].tv_usec = 0;
+    if(utimes(filename, times)) {
+      fprintf(error_stream,
+              "Failed to set filetime %ld on outfile: errno %d\n",
+              filetime, errno);
+    }
+
+#elif defined(HAVE_UTIME)
+    struct utimbuf times;
+    times.actime = (time_t)filetime;
+    times.modtime = (time_t)filetime;
+    if(utime(filename, &times)) {
+      fprintf(error_stream,
+              "Failed to set filetime %ld on outfile: errno %d\n",
+              filetime, errno);
+    }
+#endif
+  }
+}
+#endif /* defined(HAVE_UTIME) || \
+          (defined(WIN32) && (SIZEOF_CURL_OFF_T >= 8)) */
+
+#define BUFFER_SIZE (100*1024)
+
+static CURLcode operate_do(struct GlobalConfig *global,
+                           struct OperationConfig *config)
+{
+  char errorbuffer[CURL_ERROR_SIZE];
+  struct ProgressData progressbar;
+  struct getout *urlnode;
+
+  struct HdrCbData hdrcbdata;
+  struct OutStruct heads;
+
+  metalinkfile *mlfile_last = NULL;
+
+  CURL *curl = config->easy;
+  char *httpgetfields = NULL;
+
+  CURLcode result = CURLE_OK;
+  unsigned long li;
+  bool capath_from_env;
+
+  /* Save the values of noprogress and isatty to restore them later on */
+  bool orig_noprogress = global->noprogress;
+  bool orig_isatty = global->isatty;
+
+  errorbuffer[0] = '\0';
+
+  /* default headers output stream is stdout */
+  memset(&hdrcbdata, 0, sizeof(struct HdrCbData));
+  memset(&heads, 0, sizeof(struct OutStruct));
+  heads.stream = stdout;
+  heads.config = config;
+
+  /*
+  ** Beyond this point no return'ing from this function allowed.
+  ** Jump to label 'quit_curl' in order to abandon this function
+  ** from outside of nested loops further down below.
+  */
+
+  /* Check we have a url */
+  if(!config->url_list || !config->url_list->url) {
+    helpf(global->errors, "no URL specified!\n");
+    result = CURLE_FAILED_INIT;
+    goto quit_curl;
+  }
+
+  /* On WIN32 we can't set the path to curl-ca-bundle.crt
+   * at compile time. So we look here for the file in two ways:
+   * 1: look at the environment variable CURL_CA_BUNDLE for a path
+   * 2: if #1 isn't found, use the windows API function SearchPath()
+   *    to find it along the app's path (includes app's dir and CWD)
+   *
+   * We support the environment variable thing for non-Windows platforms
+   * too. Just for the sake of it.
+   */
+  capath_from_env = false;
+  if(!config->cacert &&
+     !config->capath &&
+     !config->insecure_ok) {
+    char *env;
+    env = curlx_getenv("CURL_CA_BUNDLE");
+    if(env) {
+      config->cacert = strdup(env);
+      if(!config->cacert) {
+        curl_free(env);
+        helpf(global->errors, "out of memory\n");
+        result = CURLE_OUT_OF_MEMORY;
+        goto quit_curl;
+      }
+    }
+    else {
+      env = curlx_getenv("SSL_CERT_DIR");
+      if(env) {
+        config->capath = strdup(env);
+        if(!config->capath) {
+          curl_free(env);
+          helpf(global->errors, "out of memory\n");
+          result = CURLE_OUT_OF_MEMORY;
+          goto quit_curl;
+        }
+        capath_from_env = true;
+      }
+      else {
+        env = curlx_getenv("SSL_CERT_FILE");
+        if(env) {
+          config->cacert = strdup(env);
+          if(!config->cacert) {
+            curl_free(env);
+            helpf(global->errors, "out of memory\n");
+            result = CURLE_OUT_OF_MEMORY;
+            goto quit_curl;
+          }
+        }
+      }
+    }
+
+    if(env)
+      curl_free(env);
+#ifdef WIN32
+    else {
+      result = FindWin32CACert(config, "curl-ca-bundle.crt");
+      if(result)
+        goto quit_curl;
+    }
+#endif
+  }
+
+  if(config->postfields) {
+    if(config->use_httpget) {
+      /* Use the postfields data for a http get */
+      httpgetfields = strdup(config->postfields);
+      Curl_safefree(config->postfields);
+      if(!httpgetfields) {
+        helpf(global->errors, "out of memory\n");
+        result = CURLE_OUT_OF_MEMORY;
+        goto quit_curl;
+      }
+      if(SetHTTPrequest(config,
+                        (config->no_body?HTTPREQ_HEAD:HTTPREQ_GET),
+                        &config->httpreq)) {
+        result = CURLE_FAILED_INIT;
+        goto quit_curl;
+      }
+    }
+    else {
+      if(SetHTTPrequest(config, HTTPREQ_SIMPLEPOST, &config->httpreq)) {
+        result = CURLE_FAILED_INIT;
+        goto quit_curl;
+      }
+    }
+  }
+
+  /* Single header file for all URLs */
+  if(config->headerfile) {
+    /* open file for output: */
+    if(strcmp(config->headerfile, "-")) {
+      FILE *newfile = fopen(config->headerfile, "wb");
+      if(!newfile) {
+        warnf(config->global, "Failed to open %s\n", config->headerfile);
+        result = CURLE_WRITE_ERROR;
+        goto quit_curl;
+      }
+      else {
+        heads.filename = config->headerfile;
+        heads.s_isreg = TRUE;
+        heads.fopened = TRUE;
+        heads.stream = newfile;
+      }
+    }
+    else {
+      /* always use binary mode for protocol header output */
+      set_binmode(heads.stream);
+    }
+  }
+
+  /*
+  ** Nested loops start here.
+  */
+
+  /* loop through the list of given URLs */
+
+  for(urlnode = config->url_list; urlnode; urlnode = urlnode->next) {
+
+    unsigned long up; /* upload file counter within a single upload glob */
+    char *infiles; /* might be a glob pattern */
+    char *outfiles;
+    unsigned long infilenum;
+    URLGlob *inglob;
+
+    int metalink = 0; /* nonzero for metalink download. */
+    metalinkfile *mlfile;
+    metalink_resource *mlres;
+
+    outfiles = NULL;
+    infilenum = 1;
+    inglob = NULL;
+
+    if(urlnode->flags & GETOUT_METALINK) {
+      metalink = 1;
+      if(mlfile_last == NULL) {
+        mlfile_last = config->metalinkfile_list;
+      }
+      mlfile = mlfile_last;
+      mlfile_last = mlfile_last->next;
+      mlres = mlfile->resource;
+    }
+    else {
+      mlfile = NULL;
+      mlres = NULL;
+    }
+
+    /* urlnode->url is the full URL (it might be NULL) */
+
+    if(!urlnode->url) {
+      /* This node has no URL. Free node data without destroying the
+         node itself nor modifying next pointer and continue to next */
+      Curl_safefree(urlnode->outfile);
+      Curl_safefree(urlnode->infile);
+      urlnode->flags = 0;
+      continue; /* next URL please */
+    }
+
+    /* save outfile pattern before expansion */
+    if(urlnode->outfile) {
+      outfiles = strdup(urlnode->outfile);
+      if(!outfiles) {
+        helpf(global->errors, "out of memory\n");
+        result = CURLE_OUT_OF_MEMORY;
+        break;
+      }
+    }
+
+    infiles = urlnode->infile;
+
+    if(!config->globoff && infiles) {
+      /* Unless explicitly shut off */
+      result = glob_url(&inglob, infiles, &infilenum,
+                        global->showerror?global->errors:NULL);
+      if(result) {
+        Curl_safefree(outfiles);
+        break;
+      }
+    }
+
+    /* Here's the loop for uploading multiple files within the same
+       single globbed string. If no upload, we enter the loop once anyway. */
+    for(up = 0 ; up < infilenum; up++) {
+
+      char *uploadfile; /* a single file, never a glob */
+      int separator;
+      URLGlob *urls;
+      unsigned long urlnum;
+
+      uploadfile = NULL;
+      urls = NULL;
+      urlnum = 0;
+
+      if(!up && !infiles)
+        Curl_nop_stmt;
+      else {
+        if(inglob) {
+          result = glob_next_url(&uploadfile, inglob);
+          if(result == CURLE_OUT_OF_MEMORY)
+            helpf(global->errors, "out of memory\n");
+        }
+        else if(!up) {
+          uploadfile = strdup(infiles);
+          if(!uploadfile) {
+            helpf(global->errors, "out of memory\n");
+            result = CURLE_OUT_OF_MEMORY;
+          }
+        }
+        else
+          uploadfile = NULL;
+        if(!uploadfile)
+          break;
+      }
+
+      if(metalink) {
+        /* For Metalink download, we don't use glob. Instead we use
+           the number of resources as urlnum. */
+        urlnum = count_next_metalink_resource(mlfile);
+      }
+      else
+      if(!config->globoff) {
+        /* Unless explicitly shut off, we expand '{...}' and '[...]'
+           expressions and return total number of URLs in pattern set */
+        result = glob_url(&urls, urlnode->url, &urlnum,
+                          global->showerror?global->errors:NULL);
+        if(result) {
+          Curl_safefree(uploadfile);
+          break;
+        }
+      }
+      else
+        urlnum = 1; /* without globbing, this is a single URL */
+
+      /* if multiple files extracted to stdout, insert separators! */
+      separator = ((!outfiles || !strcmp(outfiles, "-")) && urlnum > 1);
+
+      /* Here's looping around each globbed URL */
+      for(li = 0 ; li < urlnum; li++) {
+
+        int infd;
+        bool infdopen;
+        char *outfile;
+        struct OutStruct outs;
+        struct InStruct input;
+        struct timeval retrystart;
+        curl_off_t uploadfilesize;
+        long retry_numretries;
+        long retry_sleep_default;
+        long retry_sleep;
+        char *this_url = NULL;
+        int metalink_next_res = 0;
+
+        outfile = NULL;
+        infdopen = FALSE;
+        infd = STDIN_FILENO;
+        uploadfilesize = -1; /* -1 means unknown */
+
+        /* default output stream is stdout */
+        memset(&outs, 0, sizeof(struct OutStruct));
+        outs.stream = stdout;
+        outs.config = config;
+
+        if(metalink) {
+          /* For Metalink download, use name in Metalink file as
+             filename. */
+          outfile = strdup(mlfile->filename);
+          if(!outfile) {
+            result = CURLE_OUT_OF_MEMORY;
+            goto show_error;
+          }
+          this_url = strdup(mlres->url);
+          if(!this_url) {
+            result = CURLE_OUT_OF_MEMORY;
+            goto show_error;
+          }
+        }
+        else {
+          if(urls) {
+            result = glob_next_url(&this_url, urls);
+            if(result)
+              goto show_error;
+          }
+          else if(!li) {
+            this_url = strdup(urlnode->url);
+            if(!this_url) {
+              result = CURLE_OUT_OF_MEMORY;
+              goto show_error;
+            }
+          }
+          else
+            this_url = NULL;
+          if(!this_url)
+            break;
+
+          if(outfiles) {
+            outfile = strdup(outfiles);
+            if(!outfile) {
+              result = CURLE_OUT_OF_MEMORY;
+              goto show_error;
+            }
+          }
+        }
+
+        if(((urlnode->flags&GETOUT_USEREMOTE) ||
+            (outfile && strcmp("-", outfile))) &&
+           (metalink || !config->use_metalink)) {
+
+          /*
+           * We have specified a file name to store the result in, or we have
+           * decided we want to use the remote file name.
+           */
+
+          if(!outfile) {
+            /* extract the file name from the URL */
+            result = get_url_file_name(&outfile, this_url);
+            if(result)
+              goto show_error;
+            if(!*outfile && !config->content_disposition) {
+              helpf(global->errors, "Remote file name has no length!\n");
+              result = CURLE_WRITE_ERROR;
+              goto quit_urls;
+            }
+          }
+          else if(urls) {
+            /* fill '#1' ... '#9' terms from URL pattern */
+            char *storefile = outfile;
+            result = glob_match_url(&outfile, storefile, urls);
+            Curl_safefree(storefile);
+            if(result) {
+              /* bad globbing */
+              warnf(config->global, "bad output glob!\n");
+              goto quit_urls;
+            }
+          }
+
+          /* Create the directory hierarchy, if not pre-existent to a multiple
+             file output call */
+
+          if(config->create_dirs || metalink) {
+            result = create_dir_hierarchy(outfile, global->errors);
+            /* create_dir_hierarchy shows error upon CURLE_WRITE_ERROR */
+            if(result == CURLE_WRITE_ERROR)
+              goto quit_urls;
+            if(result) {
+              goto show_error;
+            }
+          }
+
+          if((urlnode->flags & GETOUT_USEREMOTE)
+             && config->content_disposition) {
+            /* Our header callback MIGHT set the filename */
+            DEBUGASSERT(!outs.filename);
+          }
+
+          if(config->resume_from_current) {
+            /* We're told to continue from where we are now. Get the size
+               of the file as it is now and open it for append instead */
+            struct_stat fileinfo;
+            /* VMS -- Danger, the filesize is only valid for stream files */
+            if(0 == stat(outfile, &fileinfo))
+              /* set offset to current file size: */
+              config->resume_from = fileinfo.st_size;
+            else
+              /* let offset be 0 */
+              config->resume_from = 0;
+          }
+
+          if(config->resume_from) {
+#ifdef __VMS
+            /* open file for output, forcing VMS output format into stream
+               mode which is needed for stat() call above to always work. */
+            FILE *file = fopen(outfile, config->resume_from?"ab":"wb",
+                               "ctx=stm", "rfm=stmlf", "rat=cr", "mrs=0");
+#else
+            /* open file for output: */
+            FILE *file = fopen(outfile, config->resume_from?"ab":"wb");
+#endif
+            if(!file) {
+              helpf(global->errors, "Can't open '%s'!\n", outfile);
+              result = CURLE_WRITE_ERROR;
+              goto quit_urls;
+            }
+            outs.fopened = TRUE;
+            outs.stream = file;
+            outs.init = config->resume_from;
+          }
+          else {
+            outs.stream = NULL; /* open when needed */
+          }
+          outs.filename = outfile;
+          outs.s_isreg = TRUE;
+        }
+
+        if(uploadfile && !stdin_upload(uploadfile)) {
+          /*
+           * We have specified a file to upload and it isn't "-".
+           */
+          struct_stat fileinfo;
+
+          this_url = add_file_name_to_url(curl, this_url, uploadfile);
+          if(!this_url) {
+            result = CURLE_OUT_OF_MEMORY;
+            goto show_error;
+          }
+          /* VMS Note:
+           *
+           * Reading binary from files can be a problem...  Only FIXED, VAR
+           * etc WITHOUT implied CC will work Others need a \n appended to a
+           * line
+           *
+           * - Stat gives a size but this is UNRELIABLE in VMS As a f.e. a
+           * fixed file with implied CC needs to have a byte added for every
+           * record processed, this can by derived from Filesize & recordsize
+           * for VARiable record files the records need to be counted!  for
+           * every record add 1 for linefeed and subtract 2 for the record
+           * header for VARIABLE header files only the bare record data needs
+           * to be considered with one appended if implied CC
+           */
+#ifdef __VMS
+          /* Calculate the real upload site for VMS */
+          infd = -1;
+          if(stat(uploadfile, &fileinfo) == 0) {
+            fileinfo.st_size = VmsSpecialSize(uploadfile, &fileinfo);
+            switch(fileinfo.st_fab_rfm) {
+            case FAB$C_VAR:
+            case FAB$C_VFC:
+            case FAB$C_STMCR:
+              infd = open(uploadfile, O_RDONLY | O_BINARY);
+              break;
+            default:
+              infd = open(uploadfile, O_RDONLY | O_BINARY,
+                          "rfm=stmlf", "ctx=stm");
+            }
+          }
+          if(infd == -1)
+#else
+          infd = open(uploadfile, O_RDONLY | O_BINARY);
+          if((infd == -1) || fstat(infd, &fileinfo))
+#endif
+          {
+            helpf(global->errors, "Can't open '%s'!\n", uploadfile);
+            if(infd != -1) {
+              close(infd);
+              infd = STDIN_FILENO;
+            }
+            result = CURLE_READ_ERROR;
+            goto quit_urls;
+          }
+          infdopen = TRUE;
+
+          /* we ignore file size for char/block devices, sockets, etc. */
+          if(S_ISREG(fileinfo.st_mode))
+            uploadfilesize = fileinfo.st_size;
+
+        }
+        else if(uploadfile && stdin_upload(uploadfile)) {
+          /* count to see if there are more than one auth bit set
+             in the authtype field */
+          int authbits = 0;
+          int bitcheck = 0;
+          while(bitcheck < 32) {
+            if(config->authtype & (1UL << bitcheck++)) {
+              authbits++;
+              if(authbits > 1) {
+                /* more than one, we're done! */
+                break;
+              }
+            }
+          }
+
+          /*
+           * If the user has also selected --anyauth or --proxy-anyauth
+           * we should warn him/her.
+           */
+          if(config->proxyanyauth || (authbits>1)) {
+            warnf(config->global,
+                  "Using --anyauth or --proxy-anyauth with upload from stdin"
+                  " involves a big risk of it not working. Use a temporary"
+                  " file or a fixed auth type instead!\n");
+          }
+
+          DEBUGASSERT(infdopen == FALSE);
+          DEBUGASSERT(infd == STDIN_FILENO);
+
+          set_binmode(stdin);
+          if(!strcmp(uploadfile, ".")) {
+            if(curlx_nonblock((curl_socket_t)infd, TRUE) < 0)
+              warnf(config->global,
+                    "fcntl failed on fd=%d: %s\n", infd, strerror(errno));
+          }
+        }
+
+        if(uploadfile && config->resume_from_current)
+          config->resume_from = -1; /* -1 will then force get-it-yourself */
+
+        if(output_expected(this_url, uploadfile) && outs.stream &&
+           isatty(fileno(outs.stream)))
+          /* we send the output to a tty, therefore we switch off the progress
+             meter */
+          global->noprogress = global->isatty = TRUE;
+        else {
+          /* progress meter is per download, so restore config
+             values */
+          global->noprogress = orig_noprogress;
+          global->isatty = orig_isatty;
+        }
+
+        if(urlnum > 1 && !global->mute) {
+          fprintf(global->errors, "\n[%lu/%lu]: %s --> %s\n",
+                  li + 1, urlnum, this_url, outfile ? outfile : "<stdout>");
+          if(separator)
+            printf("%s%s\n", CURLseparator, this_url);
+        }
+        if(httpgetfields) {
+          char *urlbuffer;
+          /* Find out whether the url contains a file name */
+          const char *pc = strstr(this_url, "://");
+          char sep = '?';
+          if(pc)
+            pc += 3;
+          else
+            pc = this_url;
+
+          pc = strrchr(pc, '/'); /* check for a slash */
+
+          if(pc) {
+            /* there is a slash present in the URL */
+
+            if(strchr(pc, '?'))
+              /* Ouch, there's already a question mark in the URL string, we
+                 then append the data with an ampersand separator instead! */
+              sep = '&';
+          }
+          /*
+           * Then append ? followed by the get fields to the url.
+           */
+          if(pc)
+            urlbuffer = aprintf("%s%c%s", this_url, sep, httpgetfields);
+          else
+            /* Append  / before the ? to create a well-formed url
+               if the url contains a hostname only
+            */
+            urlbuffer = aprintf("%s/?%s", this_url, httpgetfields);
+
+          if(!urlbuffer) {
+            result = CURLE_OUT_OF_MEMORY;
+            goto show_error;
+          }
+
+          Curl_safefree(this_url); /* free previous URL */
+          this_url = urlbuffer; /* use our new URL instead! */
+        }
+
+        if(!global->errors)
+          global->errors = stderr;
+
+        if((!outfile || !strcmp(outfile, "-")) && !config->use_ascii) {
+          /* We get the output to stdout and we have not got the ASCII/text
+             flag, then set stdout to be binary */
+          set_binmode(stdout);
+        }
+
+        /* explicitly passed to stdout means okaying binary gunk */
+        config->terminal_binary_ok = (outfile && !strcmp(outfile, "-"));
+
+        if(!config->tcp_nodelay)
+          my_setopt(curl, CURLOPT_TCP_NODELAY, 0L);
+
+        if(config->tcp_fastopen)
+          my_setopt(curl, CURLOPT_TCP_FASTOPEN, 1L);
+
+        /* where to store */
+        my_setopt(curl, CURLOPT_WRITEDATA, &outs);
+        my_setopt(curl, CURLOPT_INTERLEAVEDATA, &outs);
+        if(metalink || !config->use_metalink)
+          /* what call to write */
+          my_setopt(curl, CURLOPT_WRITEFUNCTION, tool_write_cb);
+#ifdef USE_METALINK
+        else
+          /* Set Metalink specific write callback function to parse
+             XML data progressively. */
+          my_setopt(curl, CURLOPT_WRITEFUNCTION, metalink_write_cb);
+#endif /* USE_METALINK */
+
+        /* for uploads */
+        input.fd = infd;
+        input.config = config;
+        /* Note that if CURLOPT_READFUNCTION is fread (the default), then
+         * lib/telnet.c will Curl_poll() on the input file descriptor
+         * rather then calling the READFUNCTION at regular intervals.
+         * The circumstances in which it is preferable to enable this
+         * behaviour, by omitting to set the READFUNCTION & READDATA options,
+         * have not been determined.
+         */
+        my_setopt(curl, CURLOPT_READDATA, &input);
+        /* what call to read */
+        my_setopt(curl, CURLOPT_READFUNCTION, tool_read_cb);
+
+        /* in 7.18.0, the CURLOPT_SEEKFUNCTION/DATA pair is taking over what
+           CURLOPT_IOCTLFUNCTION/DATA pair previously provided for seeking */
+        my_setopt(curl, CURLOPT_SEEKDATA, &input);
+        my_setopt(curl, CURLOPT_SEEKFUNCTION, tool_seek_cb);
+
+        if(config->recvpersecond &&
+           (config->recvpersecond < BUFFER_SIZE))
+          /* use a smaller sized buffer for better sleeps */
+          my_setopt(curl, CURLOPT_BUFFERSIZE, (long)config->recvpersecond);
+        else
+          my_setopt(curl, CURLOPT_BUFFERSIZE, (long)BUFFER_SIZE);
+
+        /* size of uploaded file: */
+        if(uploadfilesize != -1)
+          my_setopt(curl, CURLOPT_INFILESIZE_LARGE, uploadfilesize);
+        my_setopt_str(curl, CURLOPT_URL, this_url);     /* what to fetch */
+        my_setopt(curl, CURLOPT_NOPROGRESS, global->noprogress?1L:0L);
+        if(config->no_body) {
+          my_setopt(curl, CURLOPT_NOBODY, 1L);
+          my_setopt(curl, CURLOPT_HEADER, 1L);
+        }
+        /* If --metalink is used, we ignore --include (headers in
+           output) option because mixing headers to the body will
+           confuse XML parser and/or hash check will fail. */
+        else if(!config->use_metalink)
+          my_setopt(curl, CURLOPT_HEADER, config->include_headers?1L:0L);
+
+        if(config->oauth_bearer)
+          my_setopt_str(curl, CURLOPT_XOAUTH2_BEARER, config->oauth_bearer);
+
+#if !defined(CURL_DISABLE_PROXY)
+        {
+          /* TODO: Make this a run-time check instead of compile-time one. */
+
+          my_setopt_str(curl, CURLOPT_PROXY, config->proxy);
+          /* new in libcurl 7.5 */
+          if(config->proxy)
+            my_setopt_enum(curl, CURLOPT_PROXYTYPE, config->proxyver);
+
+          my_setopt_str(curl, CURLOPT_PROXYUSERPWD, config->proxyuserpwd);
+
+          /* new in libcurl 7.3 */
+          my_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, config->proxytunnel?1L:0L);
+
+          /* new in libcurl 7.52.0 */
+          if(config->preproxy)
+            my_setopt_str(curl, CURLOPT_PRE_PROXY, config->preproxy);
+
+          /* new in libcurl 7.10.6 */
+          if(config->proxyanyauth)
+            my_setopt_bitmask(curl, CURLOPT_PROXYAUTH,
+                              (long)CURLAUTH_ANY);
+          else if(config->proxynegotiate)
+            my_setopt_bitmask(curl, CURLOPT_PROXYAUTH,
+                              (long)CURLAUTH_GSSNEGOTIATE);
+          else if(config->proxyntlm)
+            my_setopt_bitmask(curl, CURLOPT_PROXYAUTH,
+                              (long)CURLAUTH_NTLM);
+          else if(config->proxydigest)
+            my_setopt_bitmask(curl, CURLOPT_PROXYAUTH,
+                              (long)CURLAUTH_DIGEST);
+          else if(config->proxybasic)
+            my_setopt_bitmask(curl, CURLOPT_PROXYAUTH,
+                              (long)CURLAUTH_BASIC);
+
+          /* new in libcurl 7.19.4 */
+          my_setopt_str(curl, CURLOPT_NOPROXY, config->noproxy);
+
+          my_setopt(curl, CURLOPT_SUPPRESS_CONNECT_HEADERS,
+                    config->suppress_connect_headers?1L:0L);
+        }
+#endif /* !CURL_DISABLE_PROXY */
+
+        my_setopt(curl, CURLOPT_FAILONERROR, config->failonerror?1L:0L);
+        my_setopt(curl, CURLOPT_REQUEST_TARGET, config->request_target);
+        my_setopt(curl, CURLOPT_UPLOAD, uploadfile?1L:0L);
+        my_setopt(curl, CURLOPT_DIRLISTONLY, config->dirlistonly?1L:0L);
+        my_setopt(curl, CURLOPT_APPEND, config->ftp_append?1L:0L);
+
+        if(config->netrc_opt)
+          my_setopt_enum(curl, CURLOPT_NETRC, (long)CURL_NETRC_OPTIONAL);
+        else if(config->netrc || config->netrc_file)
+          my_setopt_enum(curl, CURLOPT_NETRC, (long)CURL_NETRC_REQUIRED);
+        else
+          my_setopt_enum(curl, CURLOPT_NETRC, (long)CURL_NETRC_IGNORED);
+
+        if(config->netrc_file)
+          my_setopt_str(curl, CURLOPT_NETRC_FILE, config->netrc_file);
+
+        my_setopt(curl, CURLOPT_TRANSFERTEXT, config->use_ascii?1L:0L);
+        if(config->login_options)
+          my_setopt_str(curl, CURLOPT_LOGIN_OPTIONS, config->login_options);
+        my_setopt_str(curl, CURLOPT_USERPWD, config->userpwd);
+        my_setopt_str(curl, CURLOPT_RANGE, config->range);
+        my_setopt(curl, CURLOPT_ERRORBUFFER, errorbuffer);
+        my_setopt(curl, CURLOPT_TIMEOUT_MS, (long)(config->timeout * 1000));
+
+        switch(config->httpreq) {
+        case HTTPREQ_SIMPLEPOST:
+          my_setopt_str(curl, CURLOPT_POSTFIELDS,
+                        config->postfields);
+          my_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE,
+                    config->postfieldsize);
+          break;
+        case HTTPREQ_MIMEPOST:
+          my_setopt_mimepost(curl, CURLOPT_MIMEPOST, config->mimepost);
+          break;
+        default:
+          break;
+        }
+
+        /* new in libcurl 7.10.6 (default is Basic) */
+        if(config->authtype)
+          my_setopt_bitmask(curl, CURLOPT_HTTPAUTH, (long)config->authtype);
+
+        my_setopt_slist(curl, CURLOPT_HTTPHEADER, config->headers);
+
+        if(built_in_protos & (CURLPROTO_HTTP | CURLPROTO_RTSP)) {
+          my_setopt_str(curl, CURLOPT_REFERER, config->referer);
+          my_setopt_str(curl, CURLOPT_USERAGENT, config->useragent);
+        }
+
+        if(built_in_protos & CURLPROTO_HTTP) {
+
+          long postRedir = 0;
+
+          my_setopt(curl, CURLOPT_FOLLOWLOCATION,
+                    config->followlocation?1L:0L);
+          my_setopt(curl, CURLOPT_UNRESTRICTED_AUTH,
+                    config->unrestricted_auth?1L:0L);
+
+          my_setopt(curl, CURLOPT_AUTOREFERER, config->autoreferer?1L:0L);
+
+          /* new in libcurl 7.36.0 */
+          if(config->proxyheaders) {
+            my_setopt_slist(curl, CURLOPT_PROXYHEADER, config->proxyheaders);
+            my_setopt(curl, CURLOPT_HEADEROPT, CURLHEADER_SEPARATE);
+          }
+
+          /* new in libcurl 7.5 */
+          my_setopt(curl, CURLOPT_MAXREDIRS, config->maxredirs);
+
+          if(config->httpversion)
+            my_setopt_enum(curl, CURLOPT_HTTP_VERSION, config->httpversion);
+          else if(curlinfo->features & CURL_VERSION_HTTP2) {
+            my_setopt_enum(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS);
+          }
+
+          /* curl 7.19.1 (the 301 version existed in 7.18.2),
+             303 was added in 7.26.0 */
+          if(config->post301)
+            postRedir |= CURL_REDIR_POST_301;
+          if(config->post302)
+            postRedir |= CURL_REDIR_POST_302;
+          if(config->post303)
+            postRedir |= CURL_REDIR_POST_303;
+          my_setopt(curl, CURLOPT_POSTREDIR, postRedir);
+
+          /* new in libcurl 7.21.6 */
+          if(config->encoding)
+            my_setopt_str(curl, CURLOPT_ACCEPT_ENCODING, "");
+
+          /* new in libcurl 7.21.6 */
+          if(config->tr_encoding)
+            my_setopt(curl, CURLOPT_TRANSFER_ENCODING, 1L);
+
+        } /* (built_in_protos & CURLPROTO_HTTP) */
+
+        my_setopt_str(curl, CURLOPT_FTPPORT, config->ftpport);
+        my_setopt(curl, CURLOPT_LOW_SPEED_LIMIT,
+                  config->low_speed_limit);
+        my_setopt(curl, CURLOPT_LOW_SPEED_TIME, config->low_speed_time);
+        my_setopt(curl, CURLOPT_MAX_SEND_SPEED_LARGE,
+                  config->sendpersecond);
+        my_setopt(curl, CURLOPT_MAX_RECV_SPEED_LARGE,
+                  config->recvpersecond);
+
+        if(config->use_resume)
+          my_setopt(curl, CURLOPT_RESUME_FROM_LARGE, config->resume_from);
+        else
+          my_setopt(curl, CURLOPT_RESUME_FROM_LARGE, CURL_OFF_T_C(0));
+
+        my_setopt_str(curl, CURLOPT_KEYPASSWD, config->key_passwd);
+        my_setopt_str(curl, CURLOPT_PROXY_KEYPASSWD, config->proxy_key_passwd);
+
+        if(built_in_protos & (CURLPROTO_SCP|CURLPROTO_SFTP)) {
+
+          /* SSH and SSL private key uses same command-line option */
+          /* new in libcurl 7.16.1 */
+          my_setopt_str(curl, CURLOPT_SSH_PRIVATE_KEYFILE, config->key);
+          /* new in libcurl 7.16.1 */
+          my_setopt_str(curl, CURLOPT_SSH_PUBLIC_KEYFILE, config->pubkey);
+
+          /* new in libcurl 7.17.1: SSH host key md5 checking allows us
+             to fail if we are not talking to who we think we should */
+          my_setopt_str(curl, CURLOPT_SSH_HOST_PUBLIC_KEY_MD5,
+                        config->hostpubmd5);
+
+          /* new in libcurl 7.56.0 */
+          if(config->ssh_compression)
+            my_setopt(curl, CURLOPT_SSH_COMPRESSION, 1L);
+        }
+
+        if(config->cacert)
+          my_setopt_str(curl, CURLOPT_CAINFO, config->cacert);
+        if(config->proxy_cacert)
+          my_setopt_str(curl, CURLOPT_PROXY_CAINFO, config->proxy_cacert);
+
+        if(config->capath) {
+          result = res_setopt_str(curl, CURLOPT_CAPATH, config->capath);
+          if(result == CURLE_NOT_BUILT_IN) {
+            warnf(config->global, "ignoring %s, not supported by libcurl\n",
+                  capath_from_env?
+                  "SSL_CERT_DIR environment variable":"--capath");
+          }
+          else if(result)
+            goto show_error;
+        }
+        /* For the time being if --proxy-capath is not set then we use the
+           --capath value for it, if any. See #1257 */
+        if(config->proxy_capath || config->capath) {
+          result = res_setopt_str(curl, CURLOPT_PROXY_CAPATH,
+                                  (config->proxy_capath ?
+                                   config->proxy_capath :
+                                   config->capath));
+          if(result == CURLE_NOT_BUILT_IN) {
+            if(config->proxy_capath) {
+              warnf(config->global,
+                    "ignoring --proxy-capath, not supported by libcurl\n");
+            }
+          }
+          else if(result)
+            goto show_error;
+        }
+
+        if(config->crlfile)
+          my_setopt_str(curl, CURLOPT_CRLFILE, config->crlfile);
+        if(config->proxy_crlfile)
+          my_setopt_str(curl, CURLOPT_PROXY_CRLFILE, config->proxy_crlfile);
+        else if(config->crlfile) /* CURLOPT_PROXY_CRLFILE default is crlfile */
+          my_setopt_str(curl, CURLOPT_PROXY_CRLFILE, config->crlfile);
+
+        if(config->pinnedpubkey)
+          my_setopt_str(curl, CURLOPT_PINNEDPUBLICKEY, config->pinnedpubkey);
+
+        if(curlinfo->features & CURL_VERSION_SSL) {
+          my_setopt_str(curl, CURLOPT_SSLCERT, config->cert);
+          my_setopt_str(curl, CURLOPT_PROXY_SSLCERT, config->proxy_cert);
+          my_setopt_str(curl, CURLOPT_SSLCERTTYPE, config->cert_type);
+          my_setopt_str(curl, CURLOPT_PROXY_SSLCERTTYPE,
+                        config->proxy_cert_type);
+          my_setopt_str(curl, CURLOPT_SSLKEY, config->key);
+          my_setopt_str(curl, CURLOPT_PROXY_SSLKEY, config->proxy_key);
+          my_setopt_str(curl, CURLOPT_SSLKEYTYPE, config->key_type);
+          my_setopt_str(curl, CURLOPT_PROXY_SSLKEYTYPE,
+                        config->proxy_key_type);
+
+          if(config->insecure_ok) {
+            my_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
+            my_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
+          }
+          else {
+            my_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
+            /* libcurl default is strict verifyhost -> 2L   */
+            /* my_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L); */
+          }
+          if(config->proxy_insecure_ok) {
+            my_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 0L);
+            my_setopt(curl, CURLOPT_PROXY_SSL_VERIFYHOST, 0L);
+          }
+          else {
+            my_setopt(curl, CURLOPT_PROXY_SSL_VERIFYPEER, 1L);
+          }
+
+          if(config->verifystatus)
+            my_setopt(curl, CURLOPT_SSL_VERIFYSTATUS, 1L);
+
+          if(config->falsestart)
+            my_setopt(curl, CURLOPT_SSL_FALSESTART, 1L);
+
+          my_setopt_enum(curl, CURLOPT_SSLVERSION,
+                         config->ssl_version | config->ssl_version_max);
+          my_setopt_enum(curl, CURLOPT_PROXY_SSLVERSION,
+                         config->proxy_ssl_version);
+        }
+        if(config->path_as_is)
+          my_setopt(curl, CURLOPT_PATH_AS_IS, 1L);
+
+        if(built_in_protos & (CURLPROTO_SCP|CURLPROTO_SFTP)) {
+          if(!config->insecure_ok) {
+            char *home;
+            char *file;
+            result = CURLE_OUT_OF_MEMORY;
+            home = homedir();
+            if(home) {
+              file = aprintf("%s/%sssh/known_hosts", home, DOT_CHAR);
+              if(file) {
+                /* new in curl 7.19.6 */
+                result = res_setopt_str(curl, CURLOPT_SSH_KNOWNHOSTS, file);
+                curl_free(file);
+                if(result == CURLE_UNKNOWN_OPTION)
+                  /* libssh2 version older than 1.1.1 */
+                  result = CURLE_OK;
+              }
+              Curl_safefree(home);
+            }
+            if(result)
+              goto show_error;
+          }
+        }
+
+        if(config->no_body || config->remote_time) {
+          /* no body or use remote time */
+          my_setopt(curl, CURLOPT_FILETIME, 1L);
+        }
+
+        my_setopt(curl, CURLOPT_CRLF, config->crlf?1L:0L);
+        my_setopt_slist(curl, CURLOPT_QUOTE, config->quote);
+        my_setopt_slist(curl, CURLOPT_POSTQUOTE, config->postquote);
+        my_setopt_slist(curl, CURLOPT_PREQUOTE, config->prequote);
+
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+        if(config->cookie)
+          my_setopt_str(curl, CURLOPT_COOKIE, config->cookie);
+
+        if(config->cookiefile)
+          my_setopt_str(curl, CURLOPT_COOKIEFILE, config->cookiefile);
+
+        /* new in libcurl 7.9 */
+        if(config->cookiejar)
+          my_setopt_str(curl, CURLOPT_COOKIEJAR, config->cookiejar);
+
+        /* new in libcurl 7.9.7 */
+        my_setopt(curl, CURLOPT_COOKIESESSION, config->cookiesession?1L:0L);
+#else
+        if(config->cookie || config->cookiefile || config->cookiejar) {
+          warnf(config->global, "cookie option(s) used even though cookie "
+                "support is disabled!\n");
+          return CURLE_NOT_BUILT_IN;
+        }
+#endif
+
+        my_setopt_enum(curl, CURLOPT_TIMECONDITION, (long)config->timecond);
+        my_setopt(curl, CURLOPT_TIMEVALUE, (long)config->condtime);
+        my_setopt_str(curl, CURLOPT_CUSTOMREQUEST, config->customrequest);
+        customrequest_helper(config, config->httpreq, config->customrequest);
+        my_setopt(curl, CURLOPT_STDERR, global->errors);
+
+        /* three new ones in libcurl 7.3: */
+        my_setopt_str(curl, CURLOPT_INTERFACE, config->iface);
+        my_setopt_str(curl, CURLOPT_KRBLEVEL, config->krblevel);
+
+        progressbarinit(&progressbar, config);
+        if((global->progressmode == CURL_PROGRESS_BAR) &&
+           !global->noprogress && !global->mute) {
+          /* we want the alternative style, then we have to implement it
+             ourselves! */
+          my_setopt(curl, CURLOPT_XFERINFOFUNCTION, tool_progress_cb);
+          my_setopt(curl, CURLOPT_XFERINFODATA, &progressbar);
+        }
+
+        /* new in libcurl 7.24.0: */
+        if(config->dns_servers)
+          my_setopt_str(curl, CURLOPT_DNS_SERVERS, config->dns_servers);
+
+        /* new in libcurl 7.33.0: */
+        if(config->dns_interface)
+          my_setopt_str(curl, CURLOPT_DNS_INTERFACE, config->dns_interface);
+        if(config->dns_ipv4_addr)
+          my_setopt_str(curl, CURLOPT_DNS_LOCAL_IP4, config->dns_ipv4_addr);
+        if(config->dns_ipv6_addr)
+        my_setopt_str(curl, CURLOPT_DNS_LOCAL_IP6, config->dns_ipv6_addr);
+
+        /* new in libcurl 7.6.2: */
+        my_setopt_slist(curl, CURLOPT_TELNETOPTIONS, config->telnet_options);
+
+        /* new in libcurl 7.7: */
+        my_setopt_str(curl, CURLOPT_RANDOM_FILE, config->random_file);
+        my_setopt_str(curl, CURLOPT_EGDSOCKET, config->egd_file);
+        my_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS,
+                  (long)(config->connecttimeout * 1000));
+
+        if(config->cipher_list)
+          my_setopt_str(curl, CURLOPT_SSL_CIPHER_LIST, config->cipher_list);
+
+        if(config->proxy_cipher_list)
+          my_setopt_str(curl, CURLOPT_PROXY_SSL_CIPHER_LIST,
+                        config->proxy_cipher_list);
+
+        /* new in libcurl 7.9.2: */
+        if(config->disable_epsv)
+          /* disable it */
+          my_setopt(curl, CURLOPT_FTP_USE_EPSV, 0L);
+
+        /* new in libcurl 7.10.5 */
+        if(config->disable_eprt)
+          /* disable it */
+          my_setopt(curl, CURLOPT_FTP_USE_EPRT, 0L);
+
+        if(global->tracetype != TRACE_NONE) {
+          my_setopt(curl, CURLOPT_DEBUGFUNCTION, tool_debug_cb);
+          my_setopt(curl, CURLOPT_DEBUGDATA, config);
+          my_setopt(curl, CURLOPT_VERBOSE, 1L);
+        }
+
+        /* new in curl 7.9.3 */
+        if(config->engine) {
+          result = res_setopt_str(curl, CURLOPT_SSLENGINE, config->engine);
+          if(result)
+            goto show_error;
+        }
+
+        /* new in curl 7.10.7, extended in 7.19.4. Modified to use
+           CREATE_DIR_RETRY in 7.49.0 */
+        my_setopt(curl, CURLOPT_FTP_CREATE_MISSING_DIRS,
+                  (long)(config->ftp_create_dirs?
+                         CURLFTP_CREATE_DIR_RETRY:
+                         CURLFTP_CREATE_DIR_NONE));
+
+        /* new in curl 7.10.8 */
+        if(config->max_filesize)
+          my_setopt(curl, CURLOPT_MAXFILESIZE_LARGE,
+                    config->max_filesize);
+
+        if(4 == config->ip_version)
+          my_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
+        else if(6 == config->ip_version)
+          my_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V6);
+        else
+          my_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_WHATEVER);
+
+        /* new in curl 7.15.5 */
+        if(config->ftp_ssl_reqd)
+          my_setopt_enum(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
+
+        /* new in curl 7.11.0 */
+        else if(config->ftp_ssl)
+          my_setopt_enum(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_TRY);
+
+        /* new in curl 7.16.0 */
+        else if(config->ftp_ssl_control)
+          my_setopt_enum(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_CONTROL);
+
+        /* new in curl 7.16.1 */
+        if(config->ftp_ssl_ccc)
+          my_setopt_enum(curl, CURLOPT_FTP_SSL_CCC,
+                         (long)config->ftp_ssl_ccc_mode);
+
+        /* new in curl 7.19.4 */
+        if(config->socks5_gssapi_nec)
+          my_setopt_str(curl, CURLOPT_SOCKS5_GSSAPI_NEC,
+                        config->socks5_gssapi_nec);
+
+        /* new in curl 7.55.0 */
+        if(config->socks5_auth)
+          my_setopt_bitmask(curl, CURLOPT_SOCKS5_AUTH,
+                            (long)config->socks5_auth);
+
+        /* new in curl 7.43.0 */
+        if(config->proxy_service_name)
+          my_setopt_str(curl, CURLOPT_PROXY_SERVICE_NAME,
+                        config->proxy_service_name);
+
+        /* new in curl 7.43.0 */
+        if(config->service_name)
+          my_setopt_str(curl, CURLOPT_SERVICE_NAME,
+                        config->service_name);
+
+        /* curl 7.13.0 */
+        my_setopt_str(curl, CURLOPT_FTP_ACCOUNT, config->ftp_account);
+
+        my_setopt(curl, CURLOPT_IGNORE_CONTENT_LENGTH, config->ignorecl?1L:0L);
+
+        /* curl 7.14.2 */
+        my_setopt(curl, CURLOPT_FTP_SKIP_PASV_IP, config->ftp_skip_ip?1L:0L);
+
+        /* curl 7.15.1 */
+        my_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long)config->ftp_filemethod);
+
+        /* curl 7.15.2 */
+        if(config->localport) {
+          my_setopt(curl, CURLOPT_LOCALPORT, (long)config->localport);
+          my_setopt_str(curl, CURLOPT_LOCALPORTRANGE,
+                        (long)config->localportrange);
+        }
+
+        /* curl 7.15.5 */
+        my_setopt_str(curl, CURLOPT_FTP_ALTERNATIVE_TO_USER,
+                      config->ftp_alternative_to_user);
+
+        /* curl 7.16.0 */
+        if(config->disable_sessionid)
+          /* disable it */
+          my_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE, 0L);
+
+        /* curl 7.16.2 */
+        if(config->raw) {
+          my_setopt(curl, CURLOPT_HTTP_CONTENT_DECODING, 0L);
+          my_setopt(curl, CURLOPT_HTTP_TRANSFER_DECODING, 0L);
+        }
+
+        /* curl 7.17.1 */
+        if(!config->nokeepalive) {
+          my_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
+          if(config->alivetime != 0) {
+            my_setopt(curl, CURLOPT_TCP_KEEPIDLE, config->alivetime);
+            my_setopt(curl, CURLOPT_TCP_KEEPINTVL, config->alivetime);
+          }
+        }
+        else
+          my_setopt(curl, CURLOPT_TCP_KEEPALIVE, 0L);
+
+        /* curl 7.20.0 */
+        if(config->tftp_blksize)
+          my_setopt(curl, CURLOPT_TFTP_BLKSIZE, config->tftp_blksize);
+
+        if(config->mail_from)
+          my_setopt_str(curl, CURLOPT_MAIL_FROM, config->mail_from);
+
+        if(config->mail_rcpt)
+          my_setopt_slist(curl, CURLOPT_MAIL_RCPT, config->mail_rcpt);
+
+        /* curl 7.20.x */
+        if(config->ftp_pret)
+          my_setopt(curl, CURLOPT_FTP_USE_PRET, 1L);
+
+        if(config->proto_present)
+          my_setopt_flags(curl, CURLOPT_PROTOCOLS, config->proto);
+        if(config->proto_redir_present)
+          my_setopt_flags(curl, CURLOPT_REDIR_PROTOCOLS, config->proto_redir);
+
+        if(config->content_disposition
+           && (urlnode->flags & GETOUT_USEREMOTE))
+          hdrcbdata.honor_cd_filename = TRUE;
+        else
+          hdrcbdata.honor_cd_filename = FALSE;
+
+        hdrcbdata.outs = &outs;
+        hdrcbdata.heads = &heads;
+
+        my_setopt(curl, CURLOPT_HEADERFUNCTION, tool_header_cb);
+        my_setopt(curl, CURLOPT_HEADERDATA, &hdrcbdata);
+
+        if(config->resolve)
+          /* new in 7.21.3 */
+          my_setopt_slist(curl, CURLOPT_RESOLVE, config->resolve);
+
+        if(config->connect_to)
+          /* new in 7.49.0 */
+          my_setopt_slist(curl, CURLOPT_CONNECT_TO, config->connect_to);
+
+        /* new in 7.21.4 */
+        if(curlinfo->features & CURL_VERSION_TLSAUTH_SRP) {
+          if(config->tls_username)
+            my_setopt_str(curl, CURLOPT_TLSAUTH_USERNAME,
+                          config->tls_username);
+          if(config->tls_password)
+            my_setopt_str(curl, CURLOPT_TLSAUTH_PASSWORD,
+                          config->tls_password);
+          if(config->tls_authtype)
+            my_setopt_str(curl, CURLOPT_TLSAUTH_TYPE,
+                          config->tls_authtype);
+          if(config->proxy_tls_username)
+            my_setopt_str(curl, CURLOPT_PROXY_TLSAUTH_USERNAME,
+                          config->proxy_tls_username);
+          if(config->proxy_tls_password)
+            my_setopt_str(curl, CURLOPT_PROXY_TLSAUTH_PASSWORD,
+                          config->proxy_tls_password);
+          if(config->proxy_tls_authtype)
+            my_setopt_str(curl, CURLOPT_PROXY_TLSAUTH_TYPE,
+                          config->proxy_tls_authtype);
+        }
+
+        /* new in 7.22.0 */
+        if(config->gssapi_delegation)
+          my_setopt_str(curl, CURLOPT_GSSAPI_DELEGATION,
+                        config->gssapi_delegation);
+
+        /* new in 7.25.0 and 7.44.0 */
+        {
+          long mask = (config->ssl_allow_beast ? CURLSSLOPT_ALLOW_BEAST : 0) |
+                      (config->ssl_no_revoke ? CURLSSLOPT_NO_REVOKE : 0);
+          if(mask)
+            my_setopt_bitmask(curl, CURLOPT_SSL_OPTIONS, mask);
+        }
+
+        if(config->proxy_ssl_allow_beast)
+          my_setopt(curl, CURLOPT_PROXY_SSL_OPTIONS,
+                    (long)CURLSSLOPT_ALLOW_BEAST);
+
+        if(config->mail_auth)
+          my_setopt_str(curl, CURLOPT_MAIL_AUTH, config->mail_auth);
+
+        /* new in 7.31.0 */
+        if(config->sasl_ir)
+          my_setopt(curl, CURLOPT_SASL_IR, 1L);
+
+        if(config->nonpn) {
+          my_setopt(curl, CURLOPT_SSL_ENABLE_NPN, 0L);
+        }
+
+        if(config->noalpn) {
+          my_setopt(curl, CURLOPT_SSL_ENABLE_ALPN, 0L);
+        }
+
+        /* new in 7.40.0, abstract support added in 7.53.0 */
+        if(config->unix_socket_path) {
+          if(config->abstract_unix_socket) {
+            my_setopt_str(curl, CURLOPT_ABSTRACT_UNIX_SOCKET,
+                          config->unix_socket_path);
+          }
+          else {
+            my_setopt_str(curl, CURLOPT_UNIX_SOCKET_PATH,
+                          config->unix_socket_path);
+          }
+        }
+        /* new in 7.45.0 */
+        if(config->proto_default)
+          my_setopt_str(curl, CURLOPT_DEFAULT_PROTOCOL, config->proto_default);
+
+        /* new in 7.47.0 */
+        if(config->expect100timeout > 0)
+          my_setopt_str(curl, CURLOPT_EXPECT_100_TIMEOUT_MS,
+                        (long)(config->expect100timeout*1000));
+
+        /* new in 7.48.0 */
+        if(config->tftp_no_options)
+          my_setopt(curl, CURLOPT_TFTP_NO_OPTIONS, 1L);
+
+        /* initialize retry vars for loop below */
+        retry_sleep_default = (config->retry_delay) ?
+          config->retry_delay*1000L : RETRY_SLEEP_DEFAULT; /* ms */
+
+        retry_numretries = config->req_retry;
+        retry_sleep = retry_sleep_default; /* ms */
+        retrystart = tvnow();
+
+#ifndef CURL_DISABLE_LIBCURL_OPTION
+        if(global->libcurl) {
+          result = easysrc_perform();
+          if(result)
+            goto show_error;
+        }
+#endif
+
+        for(;;) {
+#ifdef USE_METALINK
+          if(!metalink && config->use_metalink) {
+            /* If outs.metalink_parser is non-NULL, delete it first. */
+            if(outs.metalink_parser)
+              metalink_parser_context_delete(outs.metalink_parser);
+            outs.metalink_parser = metalink_parser_context_new();
+            if(outs.metalink_parser == NULL) {
+              result = CURLE_OUT_OF_MEMORY;
+              goto show_error;
+            }
+            fprintf(config->global->errors,
+                    "Metalink: parsing (%s) metalink/XML...\n", this_url);
+          }
+          else if(metalink)
+            fprintf(config->global->errors,
+                    "Metalink: fetching (%s) from (%s)...\n",
+                    mlfile->filename, this_url);
+#endif /* USE_METALINK */
+
+#ifdef CURLDEBUG
+          if(config->test_event_based)
+            result = curl_easy_perform_ev(curl);
+          else
+#endif
+          result = curl_easy_perform(curl);
+
+          if(!result && !outs.stream && !outs.bytes) {
+            /* we have received no data despite the transfer was successful
+               ==> force cration of an empty output file (if an output file
+               was specified) */
+            long cond_unmet = 0L;
+            /* do not create (or even overwrite) the file in case we get no
+               data because of unmet condition */
+            curl_easy_getinfo(curl, CURLINFO_CONDITION_UNMET, &cond_unmet);
+            if(!cond_unmet && !tool_create_output_file(&outs))
+              result = CURLE_WRITE_ERROR;
+          }
+
+          if(outs.is_cd_filename && outs.stream && !global->mute &&
+             outs.filename)
+            printf("curl: Saved to filename '%s'\n", outs.filename);
+
+          /* if retry-max-time is non-zero, make sure we haven't exceeded the
+             time */
+          if(retry_numretries &&
+             (!config->retry_maxtime ||
+              (tvdiff(tvnow(), retrystart) <
+               config->retry_maxtime*1000L)) ) {
+            enum {
+              RETRY_NO,
+              RETRY_TIMEOUT,
+              RETRY_CONNREFUSED,
+              RETRY_HTTP,
+              RETRY_FTP,
+              RETRY_LAST /* not used */
+            } retry = RETRY_NO;
+            long response;
+            if((CURLE_OPERATION_TIMEDOUT == result) ||
+               (CURLE_COULDNT_RESOLVE_HOST == result) ||
+               (CURLE_COULDNT_RESOLVE_PROXY == result) ||
+               (CURLE_FTP_ACCEPT_TIMEOUT == result))
+              /* retry timeout always */
+              retry = RETRY_TIMEOUT;
+            else if(config->retry_connrefused &&
+                    (CURLE_COULDNT_CONNECT == result)) {
+              long oserrno;
+              curl_easy_getinfo(curl, CURLINFO_OS_ERRNO, &oserrno);
+              if(ECONNREFUSED == oserrno)
+                retry = RETRY_CONNREFUSED;
+            }
+            else if((CURLE_OK == result) ||
+                    (config->failonerror &&
+                     (CURLE_HTTP_RETURNED_ERROR == result))) {
+              /* If it returned OK. _or_ failonerror was enabled and it
+                 returned due to such an error, check for HTTP transient
+                 errors to retry on. */
+              char *effective_url = NULL;
+              curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &effective_url);
+              if(effective_url &&
+                 checkprefix("http", effective_url)) {
+                /* This was HTTP(S) */
+                curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
+
+                switch(response) {
+                case 500: /* Internal Server Error */
+                case 502: /* Bad Gateway */
+                case 503: /* Service Unavailable */
+                case 504: /* Gateway Timeout */
+                  retry = RETRY_HTTP;
+                  /*
+                   * At this point, we have already written data to the output
+                   * file (or terminal). If we write to a file, we must rewind
+                   * or close/re-open the file so that the next attempt starts
+                   * over from the beginning.
+                   *
+                   * TODO: similar action for the upload case. We might need
+                   * to start over reading from a previous point if we have
+                   * uploaded something when this was returned.
+                   */
+                  break;
+                }
+              }
+            } /* if CURLE_OK */
+            else if(result) {
+              curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
+
+              if(response/100 == 4)
+                /*
+                 * This is typically when the FTP server only allows a certain
+                 * amount of users and we are not one of them.  All 4xx codes
+                 * are transient.
+                 */
+                retry = RETRY_FTP;
+            }
+
+            if(retry) {
+              static const char * const m[]={
+                NULL,
+                "timeout",
+                "connection refused",
+                "HTTP error",
+                "FTP error"
+              };
+
+              warnf(config->global, "Transient problem: %s "
+                    "Will retry in %ld seconds. "
+                    "%ld retries left.\n",
+                    m[retry], retry_sleep/1000L, retry_numretries);
+
+              tool_go_sleep(retry_sleep);
+              retry_numretries--;
+              if(!config->retry_delay) {
+                retry_sleep *= 2;
+                if(retry_sleep > RETRY_SLEEP_MAX)
+                  retry_sleep = RETRY_SLEEP_MAX;
+              }
+              if(outs.bytes && outs.filename && outs.stream) {
+                int rc;
+                /* We have written data to a output file, we truncate file
+                 */
+                if(!global->mute)
+                  fprintf(global->errors, "Throwing away %"
+                          CURL_FORMAT_CURL_OFF_T " bytes\n",
+                          outs.bytes);
+                fflush(outs.stream);
+                /* truncate file at the position where we started appending */
+#ifdef HAVE_FTRUNCATE
+                if(ftruncate(fileno(outs.stream), outs.init)) {
+                  /* when truncate fails, we can't just append as then we'll
+                     create something strange, bail out */
+                  if(!global->mute)
+                    fprintf(global->errors,
+                            "failed to truncate, exiting\n");
+                  result = CURLE_WRITE_ERROR;
+                  goto quit_urls;
+                }
+                /* now seek to the end of the file, the position where we
+                   just truncated the file in a large file-safe way */
+                rc = fseek(outs.stream, 0, SEEK_END);
+#else
+                /* ftruncate is not available, so just reposition the file
+                   to the location we would have truncated it. This won't
+                   work properly with large files on 32-bit systems, but
+                   most of those will have ftruncate. */
+                rc = fseek(outs.stream, (long)outs.init, SEEK_SET);
+#endif
+                if(rc) {
+                  if(!global->mute)
+                    fprintf(global->errors,
+                            "failed seeking to end of file, exiting\n");
+                  result = CURLE_WRITE_ERROR;
+                  goto quit_urls;
+                }
+                outs.bytes = 0; /* clear for next round */
+              }
+              continue; /* curl_easy_perform loop */
+            }
+          } /* if retry_numretries */
+          else if(metalink) {
+            /* Metalink: Decide to try the next resource or
+               not. Basically, we want to try the next resource if
+               download was not successful. */
+            long response;
+            if(CURLE_OK == result) {
+              /* TODO We want to try next resource when download was
+                 not successful. How to know that? */
+              char *effective_url = NULL;
+              curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &effective_url);
+              if(effective_url &&
+                 curl_strnequal(effective_url, "http", 4)) {
+                /* This was HTTP(S) */
+                curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
+                if(response != 200 && response != 206) {
+                  metalink_next_res = 1;
+                  fprintf(global->errors,
+                          "Metalink: fetching (%s) from (%s) FAILED "
+                          "(HTTP status code %ld)\n",
+                          mlfile->filename, this_url, response);
+                }
+              }
+            }
+            else {
+              metalink_next_res = 1;
+              fprintf(global->errors,
+                      "Metalink: fetching (%s) from (%s) FAILED (%s)\n",
+                      mlfile->filename, this_url,
+                      (errorbuffer[0]) ?
+                      errorbuffer : curl_easy_strerror(result));
+            }
+          }
+          if(metalink && !metalink_next_res)
+            fprintf(global->errors, "Metalink: fetching (%s) from (%s) OK\n",
+                    mlfile->filename, this_url);
+
+          /* In all ordinary cases, just break out of loop here */
+          break; /* curl_easy_perform loop */
+
+        }
+
+        if((global->progressmode == CURL_PROGRESS_BAR) &&
+           progressbar.calls)
+          /* if the custom progress bar has been displayed, we output a
+             newline here */
+          fputs("\n", progressbar.out);
+
+        if(config->writeout)
+          ourWriteOut(curl, &outs, config->writeout);
+
+        /*
+        ** Code within this loop may jump directly here to label 'show_error'
+        ** in order to display an error message for CURLcode stored in 'res'
+        ** variable and exit loop once that necessary writing and cleanup
+        ** in label 'quit_urls' has been done.
+        */
+
+        show_error:
+
+#ifdef __VMS
+        if(is_vms_shell()) {
+          /* VMS DCL shell behavior */
+          if(!global->showerror)
+            vms_show = VMSSTS_HIDE;
+        }
+        else
+#endif
+        if(config->synthetic_error) {
+          ;
+        }
+        else if(result && global->showerror) {
+          fprintf(global->errors, "curl: (%d) %s\n", result, (errorbuffer[0]) ?
+                  errorbuffer : curl_easy_strerror(result));
+          if(result == CURLE_SSL_CACERT)
+            fputs(CURL_CA_CERT_ERRORMSG, global->errors);
+        }
+
+        /* Fall through comment to 'quit_urls' label */
+
+        /*
+        ** Upon error condition and always that a message has already been
+        ** displayed, code within this loop may jump directly here to label
+        ** 'quit_urls' otherwise it should jump to 'show_error' label above.
+        **
+        ** When 'res' variable is _not_ CURLE_OK loop will exit once that
+        ** all code following 'quit_urls' has been executed. Otherwise it
+        ** will loop to the beginning from where it may exit if there are
+        ** no more urls left.
+        */
+
+        quit_urls:
+
+        /* Set file extended attributes */
+        if(!result && config->xattr && outs.fopened && outs.stream) {
+          int rc = fwrite_xattr(curl, fileno(outs.stream));
+          if(rc)
+            warnf(config->global, "Error setting extended attributes: %s\n",
+                  strerror(errno));
+        }
+
+        /* Close the file */
+        if(outs.fopened && outs.stream) {
+          int rc = fclose(outs.stream);
+          if(!result && rc) {
+            /* something went wrong in the writing process */
+            result = CURLE_WRITE_ERROR;
+            fprintf(global->errors, "(%d) Failed writing body\n", result);
+          }
+        }
+        else if(!outs.s_isreg && outs.stream) {
+          /* Dump standard stream buffered data */
+          int rc = fflush(outs.stream);
+          if(!result && rc) {
+            /* something went wrong in the writing process */
+            result = CURLE_WRITE_ERROR;
+            fprintf(global->errors, "(%d) Failed writing body\n", result);
+          }
+        }
+
+#ifdef __AMIGA__
+        if(!result && outs.s_isreg && outs.filename) {
+          /* Set the url (up to 80 chars) as comment for the file */
+          if(strlen(url) > 78)
+            url[79] = '\0';
+          SetComment(outs.filename, url);
+        }
+#endif
+
+#if defined(HAVE_UTIME) || \
+    (defined(WIN32) && (SIZEOF_CURL_OFF_T >= 8))
+        /* File time can only be set _after_ the file has been closed */
+        if(!result && config->remote_time && outs.s_isreg && outs.filename) {
+          /* Ask libcurl if we got a remote file time */
+          long filetime = -1;
+          curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime);
+          if(filetime >= 0)
+            setfiletime(filetime, outs.filename, config->global->errors);
+        }
+#endif /* defined(HAVE_UTIME) || \
+          (defined(WIN32) && (SIZEOF_CURL_OFF_T >= 8)) */
+
+#ifdef USE_METALINK
+        if(!metalink && config->use_metalink && result == CURLE_OK) {
+          int rv = parse_metalink(config, &outs, this_url);
+          if(rv == 0)
+            fprintf(config->global->errors, "Metalink: parsing (%s) OK\n",
+                    this_url);
+          else if(rv == -1)
+            fprintf(config->global->errors, "Metalink: parsing (%s) FAILED\n",
+                    this_url);
+        }
+        else if(metalink && result == CURLE_OK && !metalink_next_res) {
+          int rv = metalink_check_hash(global, mlfile, outs.filename);
+          if(rv == 0) {
+            metalink_next_res = 1;
+          }
+        }
+#endif /* USE_METALINK */
+
+        /* No more business with this output struct */
+        if(outs.alloc_filename)
+          Curl_safefree(outs.filename);
+#ifdef USE_METALINK
+        if(outs.metalink_parser)
+          metalink_parser_context_delete(outs.metalink_parser);
+#endif /* USE_METALINK */
+        memset(&outs, 0, sizeof(struct OutStruct));
+        hdrcbdata.outs = NULL;
+
+        /* Free loop-local allocated memory and close loop-local opened fd */
+
+        Curl_safefree(outfile);
+        Curl_safefree(this_url);
+
+        if(infdopen)
+          close(infd);
+
+        if(metalink) {
+          /* Should exit if error is fatal. */
+          if(is_fatal_error(result)) {
+            break;
+          }
+          if(!metalink_next_res)
+            break;
+          mlres = mlres->next;
+          if(mlres == NULL)
+            /* TODO If metalink_next_res is 1 and mlres is NULL,
+             * set res to error code
+             */
+            break;
+        }
+        else
+        if(urlnum > 1) {
+          /* when url globbing, exit loop upon critical error */
+          if(is_fatal_error(result))
+            break;
+        }
+        else if(result)
+          /* when not url globbing, exit loop upon any error */
+          break;
+
+      } /* loop to the next URL */
+
+      /* Free loop-local allocated memory */
+
+      Curl_safefree(uploadfile);
+
+      if(urls) {
+        /* Free list of remaining URLs */
+        glob_cleanup(urls);
+        urls = NULL;
+      }
+
+      if(infilenum > 1) {
+        /* when file globbing, exit loop upon critical error */
+        if(is_fatal_error(result))
+          break;
+      }
+      else if(result)
+        /* when not file globbing, exit loop upon any error */
+        break;
+
+    } /* loop to the next globbed upload file */
+
+    /* Free loop-local allocated memory */
+
+    Curl_safefree(outfiles);
+
+    if(inglob) {
+      /* Free list of globbed upload files */
+      glob_cleanup(inglob);
+      inglob = NULL;
+    }
+
+    /* Free this URL node data without destroying the
+       the node itself nor modifying next pointer. */
+    Curl_safefree(urlnode->url);
+    Curl_safefree(urlnode->outfile);
+    Curl_safefree(urlnode->infile);
+    urlnode->flags = 0;
+
+    /*
+    ** Bail out upon critical errors or --fail-early
+    */
+    if(is_fatal_error(result) || (result && global->fail_early))
+      goto quit_curl;
+
+  } /* for-loop through all URLs */
+
+  /*
+  ** Nested loops end here.
+  */
+
+  quit_curl:
+
+  /* Reset the global config variables */
+  global->noprogress = orig_noprogress;
+  global->isatty = orig_isatty;
+
+  /* Free function-local referenced allocated memory */
+  Curl_safefree(httpgetfields);
+
+  /* Free list of given URLs */
+  clean_getout(config);
+
+  hdrcbdata.heads = NULL;
+
+  /* Close function-local opened file descriptors */
+  if(heads.fopened && heads.stream)
+    fclose(heads.stream);
+
+  if(heads.alloc_filename)
+    Curl_safefree(heads.filename);
+
+  /* Release metalink related resources here */
+  clean_metalink(config);
+
+  return result;
+}
+
+CURLcode operate(struct GlobalConfig *config, int argc, argv_item_t argv[])
+{
+  CURLcode result = CURLE_OK;
+
+  /* Setup proper locale from environment */
+#ifdef HAVE_SETLOCALE
+  setlocale(LC_ALL, "");
+#endif
+
+  /* Parse .curlrc if necessary */
+  if((argc == 1) ||
+     (!curl_strequal(argv[1], "-q") &&
+      !curl_strequal(argv[1], "--disable"))) {
+    parseconfig(NULL, config); /* ignore possible failure */
+
+    /* If we had no arguments then make sure a url was specified in .curlrc */
+    if((argc < 2) && (!config->first->url_list)) {
+      helpf(config->errors, NULL);
+      result = CURLE_FAILED_INIT;
+    }
+  }
+
+  if(!result) {
+    /* Parse the command line arguments */
+    ParameterError res = parse_args(config, argc, argv);
+    if(res) {
+      result = CURLE_OK;
+
+      /* Check if we were asked for the help */
+      if(res == PARAM_HELP_REQUESTED)
+        tool_help();
+      /* Check if we were asked for the manual */
+      else if(res == PARAM_MANUAL_REQUESTED)
+        hugehelp();
+      /* Check if we were asked for the version information */
+      else if(res == PARAM_VERSION_INFO_REQUESTED)
+        tool_version_info();
+      /* Check if we were asked to list the SSL engines */
+      else if(res == PARAM_ENGINES_REQUESTED)
+        tool_list_engines(config->easy);
+      else if(res == PARAM_LIBCURL_UNSUPPORTED_PROTOCOL)
+        result = CURLE_UNSUPPORTED_PROTOCOL;
+      else
+        result = CURLE_FAILED_INIT;
+    }
+    else {
+#ifndef CURL_DISABLE_LIBCURL_OPTION
+      if(config->libcurl) {
+        /* Initialise the libcurl source output */
+        result = easysrc_init();
+      }
+#endif
+
+      /* Perform the main operations */
+      if(!result) {
+        size_t count = 0;
+        struct OperationConfig *operation = config->first;
+
+        /* Get the required aguments for each operation */
+        while(!result && operation) {
+          result = get_args(operation, count++);
+
+          operation = operation->next;
+        }
+
+        /* Set the current operation pointer */
+        config->current = config->first;
+
+        /* Perform each operation */
+        while(!result && config->current) {
+          result = operate_do(config, config->current);
+
+          config->current = config->current->next;
+
+          if(config->current && config->current->easy)
+            curl_easy_reset(config->current->easy);
+        }
+
+#ifndef CURL_DISABLE_LIBCURL_OPTION
+        if(config->libcurl) {
+          /* Cleanup the libcurl source output */
+          easysrc_cleanup();
+
+          /* Dump the libcurl code if previously enabled */
+          dumpeasysrc(config);
+        }
+#endif
+      }
+      else
+        helpf(config->errors, "out of memory\n");
+    }
+  }
+
+  return result;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_operate.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_operate.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_operate.h	(revision 331)
@@ -0,0 +1,29 @@
+#ifndef HEADER_CURL_TOOL_OPERATE_H
+#define HEADER_CURL_TOOL_OPERATE_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+CURLcode operate(struct GlobalConfig *config, int argc, argv_item_t argv[]);
+
+#endif /* HEADER_CURL_TOOL_OPERATE_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_operhlp.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_operhlp.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_operhlp.c	(revision 331)
@@ -0,0 +1,190 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#include "strcase.h"
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_cfgable.h"
+#include "tool_convert.h"
+#include "tool_doswin.h"
+#include "tool_operhlp.h"
+#include "tool_metalink.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+void clean_getout(struct OperationConfig *config)
+{
+  struct getout *next;
+  struct getout *node = config->url_list;
+
+  while(node) {
+    next = node->next;
+    Curl_safefree(node->url);
+    Curl_safefree(node->outfile);
+    Curl_safefree(node->infile);
+    Curl_safefree(node);
+    node = next;
+  }
+  config->url_list = NULL;
+}
+
+bool output_expected(const char *url, const char *uploadfile)
+{
+  if(!uploadfile)
+    return TRUE;  /* download */
+  if(checkprefix("http://", url) || checkprefix("https://", url))
+    return TRUE;   /* HTTP(S) upload */
+
+  return FALSE; /* non-HTTP upload, probably no output should be expected */
+}
+
+bool stdin_upload(const char *uploadfile)
+{
+  return (!strcmp(uploadfile, "-") ||
+          !strcmp(uploadfile, ".")) ? TRUE : FALSE;
+}
+
+/*
+ * Adds the file name to the URL if it doesn't already have one.
+ * url will be freed before return if the returned pointer is different
+ */
+char *add_file_name_to_url(CURL *curl, char *url, const char *filename)
+{
+  /* If no file name part is given in the URL, we add this file name */
+  char *ptr = strstr(url, "://");
+  if(ptr)
+    ptr += 3;
+  else
+    ptr = url;
+  ptr = strrchr(ptr, '/');
+  if(!ptr || !strlen(++ptr)) {
+    /* The URL has no file name part, add the local file name. In order
+       to be able to do so, we have to create a new URL in another
+       buffer.*/
+
+    /* We only want the part of the local path that is on the right
+       side of the rightmost slash and backslash. */
+    const char *filep = strrchr(filename, '/');
+    char *file2 = strrchr(filep?filep:filename, '\\');
+    char *encfile;
+
+    if(file2)
+      filep = file2 + 1;
+    else if(filep)
+      filep++;
+    else
+      filep = filename;
+
+    /* URL encode the file name */
+    encfile = curl_easy_escape(curl, filep, 0 /* use strlen */);
+    if(encfile) {
+      char *urlbuffer;
+      if(ptr)
+        /* there is a trailing slash on the URL */
+        urlbuffer = aprintf("%s%s", url, encfile);
+      else
+        /* there is no trailing slash on the URL */
+        urlbuffer = aprintf("%s/%s", url, encfile);
+
+      curl_free(encfile);
+      Curl_safefree(url);
+
+      if(!urlbuffer)
+        return NULL;
+
+      url = urlbuffer; /* use our new URL instead! */
+    }
+    else
+      Curl_safefree(url);
+  }
+  return url;
+}
+
+/* Extracts the name portion of the URL.
+ * Returns a pointer to a heap-allocated string or NULL if
+ * no name part, at location indicated by first argument.
+ */
+CURLcode get_url_file_name(char **filename, const char *url)
+{
+  const char *pc, *pc2;
+
+  *filename = NULL;
+
+  /* Find and get the remote file name */
+  pc = strstr(url, "://");
+  if(pc)
+    pc += 3;
+  else
+    pc = url;
+
+  pc2 = strrchr(pc, '\\');
+  pc = strrchr(pc, '/');
+  if(pc2 && (!pc || pc < pc2))
+    pc = pc2;
+
+  if(pc)
+    /* duplicate the string beyond the slash */
+    pc++;
+  else
+    /* no slash => empty string */
+    pc = "";
+
+  *filename = strdup(pc);
+  if(!*filename)
+    return CURLE_OUT_OF_MEMORY;
+
+#if defined(MSDOS) || defined(WIN32)
+  {
+    char *sanitized;
+    SANITIZEcode sc = sanitize_file_name(&sanitized, *filename, 0);
+    Curl_safefree(*filename);
+    if(sc)
+      return CURLE_URL_MALFORMAT;
+    *filename = sanitized;
+  }
+#endif /* MSDOS || WIN32 */
+
+  /* in case we built debug enabled, we allow an environment variable
+   * named CURL_TESTDIR to prefix the given file name to put it into a
+   * specific directory
+   */
+#ifdef DEBUGBUILD
+  {
+    char *tdir = curlx_getenv("CURL_TESTDIR");
+    if(tdir) {
+      char buffer[512]; /* suitably large */
+      snprintf(buffer, sizeof(buffer), "%s/%s", tdir, *filename);
+      Curl_safefree(*filename);
+      *filename = strdup(buffer); /* clone the buffer */
+      curl_free(tdir);
+      if(!*filename)
+        return CURLE_OUT_OF_MEMORY;
+    }
+  }
+#endif
+
+  return CURLE_OK;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_operhlp.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_operhlp.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_operhlp.h	(revision 331)
@@ -0,0 +1,39 @@
+#ifndef HEADER_CURL_TOOL_OPERHLP_H
+#define HEADER_CURL_TOOL_OPERHLP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+struct OperationConfig;
+
+void clean_getout(struct OperationConfig *config);
+
+bool output_expected(const char *url, const char *uploadfile);
+
+bool stdin_upload(const char *uploadfile);
+
+char *add_file_name_to_url(CURL *curl, char *url, const char *filename);
+
+CURLcode get_url_file_name(char **filename, const char *url);
+
+#endif /* HEADER_CURL_TOOL_OPERHLP_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_panykey.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_panykey.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_panykey.c	(revision 331)
@@ -0,0 +1,48 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#if defined(__SYMBIAN32__) || defined(NETWARE)
+
+#ifdef NETWARE
+#  ifdef __NOVELL_LIBC__
+#    include <screen.h>
+#  else
+#    include <nwconio.h>
+#  endif
+#endif
+
+#include "tool_panykey.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+void tool_pressanykey(void)
+{
+#if defined(__SYMBIAN32__)
+  getchar();
+#elif defined(NETWARE)
+  pressanykey();
+#endif
+}
+
+#endif /* __SYMBIAN32__ || NETWARE */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_panykey.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_panykey.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_panykey.h	(revision 331)
@@ -0,0 +1,37 @@
+#ifndef HEADER_CURL_TOOL_PANYKEY_H
+#define HEADER_CURL_TOOL_PANYKEY_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#if defined(__SYMBIAN32__) || defined(NETWARE)
+
+void tool_pressanykey(void);
+
+#else
+
+#define tool_pressanykey() Curl_nop_stmt
+
+#endif
+
+#endif /* HEADER_CURL_TOOL_PANYKEY_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_paramhlp.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_paramhlp.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_paramhlp.c	(revision 331)
@@ -0,0 +1,610 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#include "strcase.h"
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_cfgable.h"
+#include "tool_getparam.h"
+#include "tool_getpass.h"
+#include "tool_homedir.h"
+#include "tool_msgs.h"
+#include "tool_paramhlp.h"
+#include "tool_version.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+struct getout *new_getout(struct OperationConfig *config)
+{
+  struct getout *node = calloc(1, sizeof(struct getout));
+  struct getout *last = config->url_last;
+  if(node) {
+    /* append this new node last in the list */
+    if(last)
+      last->next = node;
+    else
+      config->url_list = node; /* first node */
+
+    /* move the last pointer */
+    config->url_last = node;
+
+    node->flags = config->default_node_flags;
+  }
+  return node;
+}
+
+ParameterError file2string(char **bufp, FILE *file)
+{
+  char buffer[256];
+  char *ptr;
+  char *string = NULL;
+  size_t stringlen = 0;
+  size_t buflen;
+
+  if(file) {
+    while(fgets(buffer, sizeof(buffer), file)) {
+      ptr = strchr(buffer, '\r');
+      if(ptr)
+        *ptr = '\0';
+      ptr = strchr(buffer, '\n');
+      if(ptr)
+        *ptr = '\0';
+      buflen = strlen(buffer);
+      ptr = realloc(string, stringlen + buflen + 1);
+      if(!ptr) {
+        Curl_safefree(string);
+        return PARAM_NO_MEM;
+      }
+      string = ptr;
+      strcpy(string + stringlen, buffer);
+      stringlen += buflen;
+    }
+  }
+  *bufp = string;
+  return PARAM_OK;
+}
+
+ParameterError file2memory(char **bufp, size_t *size, FILE *file)
+{
+  char *newbuf;
+  char *buffer = NULL;
+  size_t alloc = 512;
+  size_t nused = 0;
+  size_t nread;
+
+  if(file) {
+    do {
+      if(!buffer || (alloc == nused)) {
+        /* size_t overflow detection for huge files */
+        if(alloc + 1 > ((size_t)-1)/2) {
+          Curl_safefree(buffer);
+          return PARAM_NO_MEM;
+        }
+        alloc *= 2;
+        /* allocate an extra char, reserved space, for null termination */
+        newbuf = realloc(buffer, alloc + 1);
+        if(!newbuf) {
+          Curl_safefree(buffer);
+          return PARAM_NO_MEM;
+        }
+        buffer = newbuf;
+      }
+      nread = fread(buffer + nused, 1, alloc-nused, file);
+      nused += nread;
+    } while(nread);
+    /* null terminate the buffer in case it's used as a string later */
+    buffer[nused] = '\0';
+    /* free trailing slack space, if possible */
+    if(alloc != nused) {
+      newbuf = realloc(buffer, nused + 1);
+      if(!newbuf) {
+        Curl_safefree(buffer);
+        return PARAM_NO_MEM;
+      }
+      buffer = newbuf;
+    }
+    /* discard buffer if nothing was read */
+    if(!nused) {
+      Curl_safefree(buffer); /* no string */
+    }
+  }
+  *size = nused;
+  *bufp = buffer;
+  return PARAM_OK;
+}
+
+void cleanarg(char *str)
+{
+#ifdef HAVE_WRITABLE_ARGV
+  /* now that GetStr has copied the contents of nextarg, wipe the next
+   * argument out so that the username:password isn't displayed in the
+   * system process list */
+  if(str) {
+    size_t len = strlen(str);
+    memset(str, ' ', len);
+  }
+#else
+  (void)str;
+#endif
+}
+
+/*
+ * Parse the string and write the long in the given address. Return PARAM_OK
+ * on success, otherwise a parameter specific error enum.
+ *
+ * Since this function gets called with the 'nextarg' pointer from within the
+ * getparameter a lot, we must check it for NULL before accessing the str
+ * data.
+ */
+
+ParameterError str2num(long *val, const char *str)
+{
+  if(str) {
+    char *endptr;
+    long num;
+    errno = 0;
+    num = strtol(str, &endptr, 10);
+    if(errno == ERANGE)
+      return PARAM_NUMBER_TOO_LARGE;
+    if((endptr != str) && (endptr == str + strlen(str))) {
+      *val = num;
+      return PARAM_OK;  /* Ok */
+    }
+  }
+  return PARAM_BAD_NUMERIC; /* badness */
+}
+
+/*
+ * Parse the string and write the long in the given address. Return PARAM_OK
+ * on success, otherwise a parameter error enum. ONLY ACCEPTS POSITIVE NUMBERS!
+ *
+ * Since this function gets called with the 'nextarg' pointer from within the
+ * getparameter a lot, we must check it for NULL before accessing the str
+ * data.
+ */
+
+ParameterError str2unum(long *val, const char *str)
+{
+  ParameterError result = str2num(val, str);
+  if(result != PARAM_OK)
+    return result;
+  if(*val < 0)
+    return PARAM_NEGATIVE_NUMERIC;
+
+  return PARAM_OK;
+}
+
+/*
+ * Parse the string and write the double in the given address. Return PARAM_OK
+ * on success, otherwise a parameter specific error enum.
+ *
+ * The 'max' argument is the maximum value allowed, as the numbers are often
+ * multiplied when later used.
+ *
+ * Since this function gets called with the 'nextarg' pointer from within the
+ * getparameter a lot, we must check it for NULL before accessing the str
+ * data.
+ */
+
+static ParameterError str2double(double *val, const char *str, long max)
+{
+  if(str) {
+    char *endptr;
+    double num;
+    errno = 0;
+    num = strtod(str, &endptr);
+    if(errno == ERANGE)
+      return PARAM_NUMBER_TOO_LARGE;
+    if(num > max) {
+      /* too large */
+      return PARAM_NUMBER_TOO_LARGE;
+    }
+    if((endptr != str) && (endptr == str + strlen(str))) {
+      *val = num;
+      return PARAM_OK;  /* Ok */
+    }
+  }
+  return PARAM_BAD_NUMERIC; /* badness */
+}
+
+/*
+ * Parse the string and write the double in the given address. Return PARAM_OK
+ * on success, otherwise a parameter error enum. ONLY ACCEPTS POSITIVE NUMBERS!
+ *
+ * The 'max' argument is the maximum value allowed, as the numbers are often
+ * multiplied when later used.
+ *
+ * Since this function gets called with the 'nextarg' pointer from within the
+ * getparameter a lot, we must check it for NULL before accessing the str
+ * data.
+ */
+
+ParameterError str2udouble(double *valp, const char *str, long max)
+{
+  double value;
+  ParameterError result = str2double(&value, str, max);
+  if(result != PARAM_OK)
+    return result;
+  if(value < 0)
+    return PARAM_NEGATIVE_NUMERIC;
+
+  *valp = value;
+  return PARAM_OK;
+}
+
+/*
+ * Parse the string and modify the long in the given address. Return
+ * non-zero on failure, zero on success.
+ *
+ * The string is a list of protocols
+ *
+ * Since this function gets called with the 'nextarg' pointer from within the
+ * getparameter a lot, we must check it for NULL before accessing the str
+ * data.
+ */
+
+long proto2num(struct OperationConfig *config, long *val, const char *str)
+{
+  char *buffer;
+  const char *sep = ",";
+  char *token;
+
+  static struct sprotos {
+    const char *name;
+    long bit;
+  } const protos[] = {
+    { "all", CURLPROTO_ALL },
+    { "http", CURLPROTO_HTTP },
+    { "https", CURLPROTO_HTTPS },
+    { "ftp", CURLPROTO_FTP },
+    { "ftps", CURLPROTO_FTPS },
+    { "scp", CURLPROTO_SCP },
+    { "sftp", CURLPROTO_SFTP },
+    { "telnet", CURLPROTO_TELNET },
+    { "ldap", CURLPROTO_LDAP },
+    { "ldaps", CURLPROTO_LDAPS },
+    { "dict", CURLPROTO_DICT },
+    { "file", CURLPROTO_FILE },
+    { "tftp", CURLPROTO_TFTP },
+    { "imap", CURLPROTO_IMAP },
+    { "imaps", CURLPROTO_IMAPS },
+    { "pop3", CURLPROTO_POP3 },
+    { "pop3s", CURLPROTO_POP3S },
+    { "smtp", CURLPROTO_SMTP },
+    { "smtps", CURLPROTO_SMTPS },
+    { "rtsp", CURLPROTO_RTSP },
+    { "gopher", CURLPROTO_GOPHER },
+    { "smb", CURLPROTO_SMB },
+    { "smbs", CURLPROTO_SMBS },
+    { NULL, 0 }
+  };
+
+  if(!str)
+    return 1;
+
+  buffer = strdup(str); /* because strtok corrupts it */
+  if(!buffer)
+    return 1;
+
+  /* Allow strtok() here since this isn't used threaded */
+  /* !checksrc! disable BANNEDFUNC 2 */
+  for(token = strtok(buffer, sep);
+      token;
+      token = strtok(NULL, sep)) {
+    enum e_action { allow, deny, set } action = allow;
+
+    struct sprotos const *pp;
+
+    /* Process token modifiers */
+    while(!ISALNUM(*token)) { /* may be NULL if token is all modifiers */
+      switch (*token++) {
+      case '=':
+        action = set;
+        break;
+      case '-':
+        action = deny;
+        break;
+      case '+':
+        action = allow;
+        break;
+      default: /* Includes case of terminating NULL */
+        Curl_safefree(buffer);
+        return 1;
+      }
+    }
+
+    for(pp = protos; pp->name; pp++) {
+      if(curl_strequal(token, pp->name)) {
+        switch(action) {
+        case deny:
+          *val &= ~(pp->bit);
+          break;
+        case allow:
+          *val |= pp->bit;
+          break;
+        case set:
+          *val = pp->bit;
+          break;
+        }
+        break;
+      }
+    }
+
+    if(!(pp->name)) { /* unknown protocol */
+      /* If they have specified only this protocol, we say treat it as
+         if no protocols are allowed */
+      if(action == set)
+        *val = 0;
+      warnf(config->global, "unrecognized protocol '%s'\n", token);
+    }
+  }
+  Curl_safefree(buffer);
+  return 0;
+}
+
+/**
+ * Check if the given string is a protocol supported by libcurl
+ *
+ * @param str  the protocol name
+ * @return PARAM_OK  protocol supported
+ * @return PARAM_LIBCURL_UNSUPPORTED_PROTOCOL  protocol not supported
+ * @return PARAM_REQUIRES_PARAMETER   missing parameter
+ */
+int check_protocol(const char *str)
+{
+  const char * const *pp;
+  const curl_version_info_data *curlinfo = curl_version_info(CURLVERSION_NOW);
+  if(!str)
+    return PARAM_REQUIRES_PARAMETER;
+  for(pp = curlinfo->protocols; *pp; pp++) {
+    if(curl_strequal(*pp, str))
+      return PARAM_OK;
+  }
+  return PARAM_LIBCURL_UNSUPPORTED_PROTOCOL;
+}
+
+/**
+ * Parses the given string looking for an offset (which may be a
+ * larger-than-integer value). The offset CANNOT be negative!
+ *
+ * @param val  the offset to populate
+ * @param str  the buffer containing the offset
+ * @return PARAM_OK if successful, a parameter specific error enum if failure.
+ */
+ParameterError str2offset(curl_off_t *val, const char *str)
+{
+  char *endptr;
+  if(str[0] == '-')
+    /* offsets aren't negative, this indicates weird input */
+    return PARAM_NEGATIVE_NUMERIC;
+
+#if(SIZEOF_CURL_OFF_T > SIZEOF_LONG)
+  {
+    CURLofft offt = curlx_strtoofft(str, &endptr, 0, val);
+    if(CURL_OFFT_FLOW == offt)
+      return PARAM_NUMBER_TOO_LARGE;
+    else if(CURL_OFFT_INVAL == offt)
+      return PARAM_BAD_NUMERIC;
+  }
+#else
+  errno = 0;
+  *val = strtol(str, &endptr, 0);
+  if((*val == LONG_MIN || *val == LONG_MAX) && errno == ERANGE)
+    return PARAM_NUMBER_TOO_LARGE;
+#endif
+  if((endptr != str) && (endptr == str + strlen(str)))
+    return PARAM_OK;
+
+  return PARAM_BAD_NUMERIC;
+}
+
+static CURLcode checkpasswd(const char *kind, /* for what purpose */
+                            const size_t i,   /* operation index */
+                            const bool last,  /* TRUE if last operation */
+                            char **userpwd)   /* pointer to allocated string */
+{
+  char *psep;
+  char *osep;
+
+  if(!*userpwd)
+    return CURLE_OK;
+
+  /* Attempt to find the password separator */
+  psep = strchr(*userpwd, ':');
+
+  /* Attempt to find the options separator */
+  osep = strchr(*userpwd, ';');
+
+  if(!psep && **userpwd != ';') {
+    /* no password present, prompt for one */
+    char passwd[256] = "";
+    char prompt[256];
+    size_t passwdlen;
+    size_t userlen = strlen(*userpwd);
+    char *passptr;
+
+    if(osep)
+      *osep = '\0';
+
+    /* build a nice-looking prompt */
+    if(!i && last)
+      curlx_msnprintf(prompt, sizeof(prompt),
+                      "Enter %s password for user '%s':",
+                      kind, *userpwd);
+    else
+      curlx_msnprintf(prompt, sizeof(prompt),
+                      "Enter %s password for user '%s' on URL #%"
+                      CURL_FORMAT_CURL_OFF_TU ":",
+                      kind, *userpwd, (curl_off_t) (i + 1));
+
+    /* get password */
+    getpass_r(prompt, passwd, sizeof(passwd));
+    passwdlen = strlen(passwd);
+
+    if(osep)
+      *osep = ';';
+
+    /* extend the allocated memory area to fit the password too */
+    passptr = realloc(*userpwd,
+                      passwdlen + 1 + /* an extra for the colon */
+                      userlen + 1);   /* an extra for the zero */
+    if(!passptr)
+      return CURLE_OUT_OF_MEMORY;
+
+    /* append the password separated with a colon */
+    passptr[userlen] = ':';
+    memcpy(&passptr[userlen + 1], passwd, passwdlen + 1);
+    *userpwd = passptr;
+  }
+
+  return CURLE_OK;
+}
+
+ParameterError add2list(struct curl_slist **list, const char *ptr)
+{
+  struct curl_slist *newlist = curl_slist_append(*list, ptr);
+  if(newlist)
+    *list = newlist;
+  else
+    return PARAM_NO_MEM;
+
+  return PARAM_OK;
+}
+
+int ftpfilemethod(struct OperationConfig *config, const char *str)
+{
+  if(curl_strequal("singlecwd", str))
+    return CURLFTPMETHOD_SINGLECWD;
+  if(curl_strequal("nocwd", str))
+    return CURLFTPMETHOD_NOCWD;
+  if(curl_strequal("multicwd", str))
+    return CURLFTPMETHOD_MULTICWD;
+
+  warnf(config->global, "unrecognized ftp file method '%s', using default\n",
+        str);
+
+  return CURLFTPMETHOD_MULTICWD;
+}
+
+int ftpcccmethod(struct OperationConfig *config, const char *str)
+{
+  if(curl_strequal("passive", str))
+    return CURLFTPSSL_CCC_PASSIVE;
+  if(curl_strequal("active", str))
+    return CURLFTPSSL_CCC_ACTIVE;
+
+  warnf(config->global, "unrecognized ftp CCC method '%s', using default\n",
+        str);
+
+  return CURLFTPSSL_CCC_PASSIVE;
+}
+
+long delegation(struct OperationConfig *config, char *str)
+{
+  if(curl_strequal("none", str))
+    return CURLGSSAPI_DELEGATION_NONE;
+  if(curl_strequal("policy", str))
+    return CURLGSSAPI_DELEGATION_POLICY_FLAG;
+  if(curl_strequal("always", str))
+    return CURLGSSAPI_DELEGATION_FLAG;
+
+  warnf(config->global, "unrecognized delegation method '%s', using none\n",
+        str);
+
+  return CURLGSSAPI_DELEGATION_NONE;
+}
+
+/*
+ * my_useragent: returns allocated string with default user agent
+ */
+static char *my_useragent(void)
+{
+  return strdup(CURL_NAME "/" CURL_VERSION);
+}
+
+CURLcode get_args(struct OperationConfig *config, const size_t i)
+{
+  CURLcode result = CURLE_OK;
+  bool last = (config->next ? FALSE : TRUE);
+
+  /* Check we have a password for the given host user */
+  if(config->userpwd && !config->oauth_bearer) {
+    result = checkpasswd("host", i, last, &config->userpwd);
+    if(result)
+      return result;
+  }
+
+  /* Check we have a password for the given proxy user */
+  if(config->proxyuserpwd) {
+    result = checkpasswd("proxy", i, last, &config->proxyuserpwd);
+    if(result)
+      return result;
+  }
+
+  /* Check we have a user agent */
+  if(!config->useragent) {
+    config->useragent = my_useragent();
+    if(!config->useragent) {
+      helpf(config->global->errors, "out of memory\n");
+      result = CURLE_OUT_OF_MEMORY;
+    }
+  }
+
+  return result;
+}
+
+/*
+ * Parse the string and modify ssl_version in the val argument. Return PARAM_OK
+ * on success, otherwise a parameter error enum. ONLY ACCEPTS POSITIVE NUMBERS!
+ *
+ * Since this function gets called with the 'nextarg' pointer from within the
+ * getparameter a lot, we must check it for NULL before accessing the str
+ * data.
+ */
+
+ParameterError str2tls_max(long *val, const char *str)
+{
+   static struct s_tls_max {
+    const char *tls_max_str;
+    long tls_max;
+  } const tls_max_array[] = {
+    { "default", CURL_SSLVERSION_MAX_DEFAULT },
+    { "1.0",     CURL_SSLVERSION_MAX_TLSv1_0 },
+    { "1.1",     CURL_SSLVERSION_MAX_TLSv1_1 },
+    { "1.2",     CURL_SSLVERSION_MAX_TLSv1_2 },
+    { "1.3",     CURL_SSLVERSION_MAX_TLSv1_3 }
+  };
+  size_t i = 0;
+  if(!str)
+    return PARAM_REQUIRES_PARAMETER;
+  for(i = 0; i < sizeof(tls_max_array)/sizeof(tls_max_array[0]); i++) {
+    if(!strcmp(str, tls_max_array[i].tls_max_str)) {
+      *val = tls_max_array[i].tls_max;
+      return PARAM_OK;
+    }
+  }
+  return PARAM_BAD_USE;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_paramhlp.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_paramhlp.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_paramhlp.h	(revision 331)
@@ -0,0 +1,56 @@
+#ifndef HEADER_CURL_TOOL_PARAMHLP_H
+#define HEADER_CURL_TOOL_PARAMHLP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+struct getout *new_getout(struct OperationConfig *config);
+
+ParameterError file2string(char **bufp, FILE *file);
+
+ParameterError file2memory(char **bufp, size_t *size, FILE *file);
+
+void cleanarg(char *str);
+
+ParameterError str2num(long *val, const char *str);
+ParameterError str2unum(long *val, const char *str);
+ParameterError str2udouble(double *val, const char *str, long max);
+
+long proto2num(struct OperationConfig *config, long *val, const char *str);
+
+int check_protocol(const char *str);
+
+ParameterError str2offset(curl_off_t *val, const char *str);
+
+CURLcode get_args(struct OperationConfig *config, const size_t i);
+
+ParameterError add2list(struct curl_slist **list, const char *ptr);
+
+int ftpfilemethod(struct OperationConfig *config, const char *str);
+
+int ftpcccmethod(struct OperationConfig *config, const char *str);
+
+long delegation(struct OperationConfig *config, char *str);
+
+ParameterError str2tls_max(long *val, const char *str);
+
+#endif /* HEADER_CURL_TOOL_PARAMHLP_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_parsecfg.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_parsecfg.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_parsecfg.c	(revision 331)
@@ -0,0 +1,361 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_cfgable.h"
+#include "tool_getparam.h"
+#include "tool_helpers.h"
+#include "tool_homedir.h"
+#include "tool_msgs.h"
+#include "tool_parsecfg.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+#define CURLRC DOT_CHAR "curlrc"
+
+/* only acknowledge colon or equals as separators if the option was not
+   specified with an initial dash! */
+#define ISSEP(x,dash) (!dash && (((x) == '=') || ((x) == ':')))
+
+static const char *unslashquote(const char *line, char *param);
+static char *my_get_line(FILE *fp);
+
+/* return 0 on everything-is-fine, and non-zero otherwise */
+int parseconfig(const char *filename, struct GlobalConfig *global)
+{
+  int res;
+  FILE *file;
+  char filebuffer[512];
+  bool usedarg = FALSE;
+  char *home;
+  int rc = 0;
+  struct OperationConfig *operation = global->first;
+
+  if(!filename || !*filename) {
+    /* NULL or no file name attempts to load .curlrc from the homedir! */
+
+#ifndef __AMIGA__
+    filename = CURLRC;   /* sensible default */
+    home = homedir();    /* portable homedir finder */
+    if(home) {
+      if(strlen(home) < (sizeof(filebuffer) - strlen(CURLRC))) {
+        snprintf(filebuffer, sizeof(filebuffer),
+                 "%s%s%s", home, DIR_CHAR, CURLRC);
+
+#ifdef WIN32
+        /* Check if the file exists - if not, try CURLRC in the same
+         * directory as our executable
+         */
+        file = fopen(filebuffer, FOPEN_READTEXT);
+        if(file != NULL) {
+          fclose(file);
+          filename = filebuffer;
+        }
+        else {
+          /* Get the filename of our executable. GetModuleFileName is
+           * already declared via inclusions done in setup header file.
+           * We assume that we are using the ASCII version here.
+           */
+          int n = GetModuleFileNameA(0, filebuffer, sizeof(filebuffer));
+          if(n > 0 && n < (int)sizeof(filebuffer)) {
+            /* We got a valid filename - get the directory part */
+            char *lastdirchar = strrchr(filebuffer, '\\');
+            if(lastdirchar) {
+              size_t remaining;
+              *lastdirchar = 0;
+              /* If we have enough space, build the RC filename */
+              remaining = sizeof(filebuffer) - strlen(filebuffer);
+              if(strlen(CURLRC) < remaining - 1) {
+                snprintf(lastdirchar, remaining,
+                         "%s%s", DIR_CHAR, CURLRC);
+                /* Don't bother checking if it exists - we do
+                 * that later
+                 */
+                filename = filebuffer;
+              }
+            }
+          }
+        }
+#else /* WIN32 */
+        filename = filebuffer;
+#endif /* WIN32 */
+      }
+      Curl_safefree(home); /* we've used it, now free it */
+    }
+
+# else /* __AMIGA__ */
+    /* On AmigaOS all the config files are into env:
+     */
+    filename = "ENV:" CURLRC;
+
+#endif
+  }
+
+  if(strcmp(filename, "-"))
+    file = fopen(filename, FOPEN_READTEXT);
+  else
+    file = stdin;
+
+  if(file) {
+    char *line;
+    char *aline;
+    char *option;
+    char *param;
+    int lineno = 0;
+    bool alloced_param;
+    bool dashed_option;
+
+    while(NULL != (aline = my_get_line(file))) {
+      lineno++;
+      line = aline;
+      alloced_param = FALSE;
+
+      /* line with # in the first non-blank column is a comment! */
+      while(*line && ISSPACE(*line))
+        line++;
+
+      switch(*line) {
+      case '#':
+      case '/':
+      case '\r':
+      case '\n':
+      case '*':
+      case '\0':
+        Curl_safefree(aline);
+        continue;
+      }
+
+      /* the option keywords starts here */
+      option = line;
+
+      /* the option starts with a dash? */
+      dashed_option = option[0]=='-'?TRUE:FALSE;
+
+      while(*line && !ISSPACE(*line) && !ISSEP(*line, dashed_option))
+        line++;
+      /* ... and has ended here */
+
+      if(*line)
+        *line++ = '\0'; /* zero terminate, we have a local copy of the data */
+
+#ifdef DEBUG_CONFIG
+      fprintf(stderr, "GOT: %s\n", option);
+#endif
+
+      /* pass spaces and separator(s) */
+      while(*line && (ISSPACE(*line) || ISSEP(*line, dashed_option)))
+        line++;
+
+      /* the parameter starts here (unless quoted) */
+      if(*line == '\"') {
+        /* quoted parameter, do the quote dance */
+        line++;
+        param = malloc(strlen(line) + 1); /* parameter */
+        if(!param) {
+          /* out of memory */
+          Curl_safefree(aline);
+          rc = 1;
+          break;
+        }
+        alloced_param = TRUE;
+        (void)unslashquote(line, param);
+      }
+      else {
+        param = line; /* parameter starts here */
+        while(*line && !ISSPACE(*line))
+          line++;
+
+        if(*line) {
+          *line = '\0'; /* zero terminate */
+
+          /* to detect mistakes better, see if there's data following */
+          line++;
+          /* pass all spaces */
+          while(*line && ISSPACE(*line))
+            line++;
+
+          switch(*line) {
+          case '\0':
+          case '\r':
+          case '\n':
+          case '#': /* comment */
+            break;
+          default:
+            warnf(operation->global, "%s:%d: warning: '%s' uses unquoted "
+                  "white space in the line that may cause side-effects!\n",
+                  filename, lineno, option);
+          }
+        }
+        if(!*param)
+          /* do this so getparameter can check for required parameters.
+             Otherwise it always thinks there's a parameter. */
+          param = NULL;
+      }
+
+#ifdef DEBUG_CONFIG
+      fprintf(stderr, "PARAM: \"%s\"\n",(param ? param : "(null)"));
+#endif
+      res = getparameter(option, param, &usedarg, global, operation);
+
+      if(!res && param && *param && !usedarg)
+        /* we passed in a parameter that wasn't used! */
+        res = PARAM_GOT_EXTRA_PARAMETER;
+
+      if(res == PARAM_NEXT_OPERATION) {
+        if(operation->url_list && operation->url_list->url) {
+          /* Allocate the next config */
+          operation->next = malloc(sizeof(struct OperationConfig));
+          if(operation->next) {
+            /* Initialise the newly created config */
+            config_init(operation->next);
+
+            /* Copy the easy handle */
+            operation->next->easy = global->easy;
+
+            /* Set the global config pointer */
+            operation->next->global = global;
+
+            /* Update the last operation pointer */
+            global->last = operation->next;
+
+            /* Move onto the new config */
+            operation->next->prev = operation;
+            operation = operation->next;
+          }
+          else
+            res = PARAM_NO_MEM;
+        }
+      }
+
+      if(res != PARAM_OK && res != PARAM_NEXT_OPERATION) {
+        /* the help request isn't really an error */
+        if(!strcmp(filename, "-")) {
+          filename = "<stdin>";
+        }
+        if(res != PARAM_HELP_REQUESTED &&
+           res != PARAM_MANUAL_REQUESTED &&
+           res != PARAM_VERSION_INFO_REQUESTED &&
+           res != PARAM_ENGINES_REQUESTED) {
+          const char *reason = param2text(res);
+          warnf(operation->global, "%s:%d: warning: '%s' %s\n",
+                filename, lineno, option, reason);
+        }
+      }
+
+      if(alloced_param)
+        Curl_safefree(param);
+
+      Curl_safefree(aline);
+    }
+    if(file != stdin)
+      fclose(file);
+  }
+  else
+    rc = 1; /* couldn't open the file */
+
+  return rc;
+}
+
+/*
+ * Copies the string from line to the buffer at param, unquoting
+ * backslash-quoted characters and NUL-terminating the output string.
+ * Stops at the first non-backslash-quoted double quote character or the
+ * end of the input string. param must be at least as long as the input
+ * string.  Returns the pointer after the last handled input character.
+ */
+static const char *unslashquote(const char *line, char *param)
+{
+  while(*line && (*line != '\"')) {
+    if(*line == '\\') {
+      char out;
+      line++;
+
+      /* default is to output the letter after the backslash */
+      switch(out = *line) {
+      case '\0':
+        continue; /* this'll break out of the loop */
+      case 't':
+        out = '\t';
+        break;
+      case 'n':
+        out = '\n';
+        break;
+      case 'r':
+        out = '\r';
+        break;
+      case 'v':
+        out = '\v';
+        break;
+      }
+      *param++ = out;
+      line++;
+    }
+    else
+      *param++ = *line++;
+  }
+  *param = '\0'; /* always zero terminate */
+  return line;
+}
+
+/*
+ * Reads a line from the given file, ensuring is NUL terminated.
+ * The pointer must be freed by the caller.
+ * NULL is returned on an out of memory condition.
+ */
+static char *my_get_line(FILE *fp)
+{
+  char buf[4096];
+  char *nl = NULL;
+  char *line = NULL;
+
+  do {
+    if(NULL == fgets(buf, sizeof(buf), fp))
+      break;
+    if(!line) {
+      line = strdup(buf);
+      if(!line)
+        return NULL;
+    }
+    else {
+      char *ptr;
+      size_t linelen = strlen(line);
+      ptr = realloc(line, linelen + strlen(buf) + 1);
+      if(!ptr) {
+        Curl_safefree(line);
+        return NULL;
+      }
+      line = ptr;
+      strcpy(&line[linelen], buf);
+    }
+    nl = strchr(line, '\n');
+  } while(!nl);
+
+  if(nl)
+    *nl = '\0';
+
+  return line;
+}
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_parsecfg.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_parsecfg.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_parsecfg.h	(revision 331)
@@ -0,0 +1,29 @@
+#ifndef HEADER_CURL_TOOL_PARSECFG_H
+#define HEADER_CURL_TOOL_PARSECFG_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+int parseconfig(const char *filename, struct GlobalConfig *config);
+
+#endif /* HEADER_CURL_TOOL_PARSECFG_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_sdecls.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_sdecls.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_sdecls.h	(revision 331)
@@ -0,0 +1,151 @@
+#ifndef HEADER_CURL_TOOL_SDECLS_H
+#define HEADER_CURL_TOOL_SDECLS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+#ifdef USE_METALINK
+#  include <metalink/metalink.h>
+#endif /* USE_METALINK */
+
+/*
+ * OutStruct variables keep track of information relative to curl's
+ * output writing, which may take place to a standard stream or a file.
+ *
+ * 'filename' member is either a pointer to a file name string or NULL
+ * when dealing with a standard stream.
+ *
+ * 'alloc_filename' member is TRUE when string pointed by 'filename' has been
+ * dynamically allocated and 'belongs' to this OutStruct, otherwise FALSE.
+ *
+ * 'is_cd_filename' member is TRUE when string pointed by 'filename' has been
+ * set using a server-specified Content-Disposition filename, otherwise FALSE.
+ *
+ * 's_isreg' member is TRUE when output goes to a regular file, this also
+ * implies that output is 'seekable' and 'appendable' and also that member
+ * 'filename' points to file name's string. For any standard stream member
+ * 's_isreg' will be FALSE.
+ *
+ * 'fopened' member is TRUE when output goes to a regular file and it
+ * has been fopen'ed, requiring it to be closed later on. In any other
+ * case this is FALSE.
+ *
+ * 'stream' member is a pointer to a stream controlling object as returned
+ * from a 'fopen' call or a standard stream.
+ *
+ * 'config' member is a pointer to associated 'OperationConfig' struct.
+ *
+ * 'bytes' member represents amount written so far.
+ *
+ * 'init' member holds original file size or offset at which truncation is
+ * taking place. Always zero unless appending to a non-empty regular file.
+ *
+ * 'metalink_parser' member is a pointer to Metalink XML parser
+ * context.
+ */
+
+struct OutStruct {
+  char *filename;
+  bool alloc_filename;
+  bool is_cd_filename;
+  bool s_isreg;
+  bool fopened;
+  FILE *stream;
+  struct OperationConfig *config;
+  curl_off_t bytes;
+  curl_off_t init;
+#ifdef USE_METALINK
+  metalink_parser_context_t *metalink_parser;
+#endif /* USE_METALINK */
+};
+
+
+/*
+ * InStruct variables keep track of information relative to curl's
+ * input reading, which may take place from stdin or from some file.
+ *
+ * 'fd' member is either 'stdin' file descriptor number STDIN_FILENO
+ * or a file descriptor as returned from an 'open' call for some file.
+ *
+ * 'config' member is a pointer to associated 'OperationConfig' struct.
+ */
+
+struct InStruct {
+  int fd;
+  struct OperationConfig *config;
+};
+
+
+/*
+ * A linked list of these 'getout' nodes contain URL's to fetch,
+ * as well as information relative to where URL contents should
+ * be stored or which file should be uploaded.
+ */
+
+struct getout {
+  struct getout *next;      /* next one */
+  char          *url;       /* the URL we deal with */
+  char          *outfile;   /* where to store the output */
+  char          *infile;    /* file to upload, if GETOUT_UPLOAD is set */
+  int            flags;     /* options - composed of GETOUT_* bits */
+};
+
+#define GETOUT_OUTFILE    (1<<0)  /* set when outfile is deemed done */
+#define GETOUT_URL        (1<<1)  /* set when URL is deemed done */
+#define GETOUT_USEREMOTE  (1<<2)  /* use remote file name locally */
+#define GETOUT_UPLOAD     (1<<3)  /* if set, -T has been used */
+#define GETOUT_NOUPLOAD   (1<<4)  /* if set, -T "" has been used */
+#define GETOUT_METALINK   (1<<5)  /* set when Metalink download */
+
+/*
+ * 'trace' enumeration represents curl's output look'n feel possibilities.
+ */
+
+typedef enum {
+  TRACE_NONE,  /* no trace/verbose output at all */
+  TRACE_BIN,   /* tcpdump inspired look */
+  TRACE_ASCII, /* like *BIN but without the hex output */
+  TRACE_PLAIN  /* -v/--verbose type */
+} trace;
+
+
+/*
+ * 'HttpReq' enumeration represents HTTP request types.
+ */
+
+typedef enum {
+  HTTPREQ_UNSPEC,  /* first in list */
+  HTTPREQ_GET,
+  HTTPREQ_HEAD,
+  HTTPREQ_MIMEPOST,
+  HTTPREQ_SIMPLEPOST
+} HttpReq;
+
+
+/*
+ * Complete struct declarations which have OperationConfig struct members,
+ * just in case this header is directly included in some source file.
+ */
+
+#include "tool_cfgable.h"
+
+#endif /* HEADER_CURL_TOOL_SDECLS_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_setopt.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_setopt.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_setopt.c	(revision 331)
@@ -0,0 +1,704 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#ifndef CURL_DISABLE_LIBCURL_OPTION
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+
+#include "tool_cfgable.h"
+#include "tool_easysrc.h"
+#include "tool_setopt.h"
+#include "tool_convert.h"
+
+#include "mime.h"
+#include "memdebug.h" /* keep this as LAST include */
+
+/* Lookup tables for converting setopt values back to symbols */
+/* For enums, values may be in any order. */
+/* For bit masks, put combinations first, then single bits, */
+/* and finally any "NONE" value. */
+
+#define NV(e) {#e, e}
+#define NV1(e, v) {#e, (v)}
+#define NVEND {NULL, 0}         /* sentinel to mark end of list */
+
+const NameValue setopt_nv_CURLPROXY[] = {
+  NV(CURLPROXY_HTTP),
+  NV(CURLPROXY_HTTP_1_0),
+  NV(CURLPROXY_HTTPS),
+  NV(CURLPROXY_SOCKS4),
+  NV(CURLPROXY_SOCKS5),
+  NV(CURLPROXY_SOCKS4A),
+  NV(CURLPROXY_SOCKS5_HOSTNAME),
+  NVEND,
+};
+
+const NameValue setopt_nv_CURL_SOCKS_PROXY[] = {
+  NV(CURLPROXY_SOCKS4),
+  NV(CURLPROXY_SOCKS5),
+  NV(CURLPROXY_SOCKS4A),
+  NV(CURLPROXY_SOCKS5_HOSTNAME),
+  NVEND,
+};
+
+const NameValueUnsigned setopt_nv_CURLAUTH[] = {
+  NV(CURLAUTH_ANY),             /* combination */
+  NV(CURLAUTH_ANYSAFE),         /* combination */
+  NV(CURLAUTH_BASIC),
+  NV(CURLAUTH_DIGEST),
+  NV(CURLAUTH_GSSNEGOTIATE),
+  NV(CURLAUTH_NTLM),
+  NV(CURLAUTH_DIGEST_IE),
+  NV(CURLAUTH_NTLM_WB),
+  NV(CURLAUTH_ONLY),
+  NV(CURLAUTH_NONE),
+  NVEND,
+};
+
+const NameValue setopt_nv_CURL_HTTP_VERSION[] = {
+  NV(CURL_HTTP_VERSION_NONE),
+  NV(CURL_HTTP_VERSION_1_0),
+  NV(CURL_HTTP_VERSION_1_1),
+  NV(CURL_HTTP_VERSION_2_0),
+  NV(CURL_HTTP_VERSION_2TLS),
+  NVEND,
+};
+
+const NameValue setopt_nv_CURL_SSLVERSION[] = {
+  NV(CURL_SSLVERSION_DEFAULT),
+  NV(CURL_SSLVERSION_TLSv1),
+  NV(CURL_SSLVERSION_SSLv2),
+  NV(CURL_SSLVERSION_SSLv3),
+  NV(CURL_SSLVERSION_TLSv1_0),
+  NV(CURL_SSLVERSION_TLSv1_1),
+  NV(CURL_SSLVERSION_TLSv1_2),
+  NV(CURL_SSLVERSION_TLSv1_3),
+  NVEND,
+};
+
+const NameValue setopt_nv_CURL_TIMECOND[] = {
+  NV(CURL_TIMECOND_IFMODSINCE),
+  NV(CURL_TIMECOND_IFUNMODSINCE),
+  NV(CURL_TIMECOND_LASTMOD),
+  NV(CURL_TIMECOND_NONE),
+  NVEND,
+};
+
+const NameValue setopt_nv_CURLFTPSSL_CCC[] = {
+  NV(CURLFTPSSL_CCC_NONE),
+  NV(CURLFTPSSL_CCC_PASSIVE),
+  NV(CURLFTPSSL_CCC_ACTIVE),
+  NVEND,
+};
+
+const NameValue setopt_nv_CURLUSESSL[] = {
+  NV(CURLUSESSL_NONE),
+  NV(CURLUSESSL_TRY),
+  NV(CURLUSESSL_CONTROL),
+  NV(CURLUSESSL_ALL),
+  NVEND,
+};
+
+const NameValueUnsigned setopt_nv_CURLSSLOPT[] = {
+  NV(CURLSSLOPT_ALLOW_BEAST),
+  NV(CURLSSLOPT_NO_REVOKE),
+  NVEND,
+};
+
+const NameValue setopt_nv_CURL_NETRC[] = {
+  NV(CURL_NETRC_IGNORED),
+  NV(CURL_NETRC_OPTIONAL),
+  NV(CURL_NETRC_REQUIRED),
+  NVEND,
+};
+
+/* These mappings essentially triplicated - see
+ * tool_libinfo.c and tool_paramhlp.c */
+const NameValue setopt_nv_CURLPROTO[] = {
+  NV(CURLPROTO_ALL),            /* combination */
+  NV(CURLPROTO_DICT),
+  NV(CURLPROTO_FILE),
+  NV(CURLPROTO_FTP),
+  NV(CURLPROTO_FTPS),
+  NV(CURLPROTO_GOPHER),
+  NV(CURLPROTO_HTTP),
+  NV(CURLPROTO_HTTPS),
+  NV(CURLPROTO_IMAP),
+  NV(CURLPROTO_IMAPS),
+  NV(CURLPROTO_LDAP),
+  NV(CURLPROTO_LDAPS),
+  NV(CURLPROTO_POP3),
+  NV(CURLPROTO_POP3S),
+  NV(CURLPROTO_RTSP),
+  NV(CURLPROTO_SCP),
+  NV(CURLPROTO_SFTP),
+  NV(CURLPROTO_SMB),
+  NV(CURLPROTO_SMBS),
+  NV(CURLPROTO_SMTP),
+  NV(CURLPROTO_SMTPS),
+  NV(CURLPROTO_TELNET),
+  NV(CURLPROTO_TFTP),
+  NVEND,
+};
+
+/* These options have non-zero default values. */
+static const NameValue setopt_nv_CURLNONZERODEFAULTS[] = {
+  NV1(CURLOPT_SSL_VERIFYPEER, 1),
+  NV1(CURLOPT_SSL_VERIFYHOST, 1),
+  NV1(CURLOPT_SSL_ENABLE_NPN, 1),
+  NV1(CURLOPT_SSL_ENABLE_ALPN, 1),
+  NV1(CURLOPT_TCP_NODELAY, 1),
+  NV1(CURLOPT_PROXY_SSL_VERIFYPEER, 1),
+  NV1(CURLOPT_PROXY_SSL_VERIFYHOST, 1),
+  NV1(CURLOPT_SOCKS5_AUTH, 1),
+  NVEND
+};
+
+/* Format and add code; jump to nomem on malloc error */
+#define ADD(args) do { \
+  ret = easysrc_add args; \
+  if(ret) \
+    goto nomem; \
+} WHILE_FALSE
+#define ADDF(args) do { \
+  ret = easysrc_addf args; \
+  if(ret) \
+    goto nomem; \
+} WHILE_FALSE
+
+#define DECL0(s) ADD((&easysrc_decl, s))
+#define DECL1(f,a) ADDF((&easysrc_decl, f,a))
+
+#define DATA0(s) ADD((&easysrc_data, s))
+#define DATA1(f,a) ADDF((&easysrc_data, f,a))
+#define DATA2(f,a,b) ADDF((&easysrc_data, f,a,b))
+#define DATA3(f,a,b,c) ADDF((&easysrc_data, f,a,b,c))
+
+#define CODE0(s) ADD((&easysrc_code, s))
+#define CODE1(f,a) ADDF((&easysrc_code, f,a))
+#define CODE2(f,a,b) ADDF((&easysrc_code, f,a,b))
+#define CODE3(f,a,b,c) ADDF((&easysrc_code, f,a,b,c))
+
+#define CLEAN0(s) ADD((&easysrc_clean, s))
+#define CLEAN1(f,a) ADDF((&easysrc_clean, f,a))
+
+#define REM0(s) ADD((&easysrc_toohard, s))
+#define REM1(f,a) ADDF((&easysrc_toohard, f,a))
+#define REM2(f,a,b) ADDF((&easysrc_toohard, f,a,b))
+
+/* Escape string to C string syntax.  Return NULL if out of memory.
+ * Is this correct for those wacky EBCDIC guys? */
+static char *c_escape(const char *str, size_t len)
+{
+  const char *s;
+  unsigned char c;
+  char *escaped, *e;
+
+  if(len == CURL_ZERO_TERMINATED)
+    len = strlen(str);
+
+  /* Check for possible overflow. */
+  if(len > (~(size_t) 0) / 4)
+    return NULL;
+
+  /* Allocate space based on worst-case */
+  escaped = malloc(4 * len + 1);
+  if(!escaped)
+    return NULL;
+
+  e = escaped;
+  for(s = str; (c = *s) != '\0'; s++) {
+    if(c == '\n') {
+      strcpy(e, "\\n");
+      e += 2;
+    }
+    else if(c == '\r') {
+      strcpy(e, "\\r");
+      e += 2;
+    }
+    else if(c == '\t') {
+      strcpy(e, "\\t");
+      e += 2;
+    }
+    else if(c == '\\') {
+      strcpy(e, "\\\\");
+      e += 2;
+    }
+    else if(c == '"') {
+      strcpy(e, "\\\"");
+      e += 2;
+    }
+    else if(! isprint(c)) {
+      snprintf(e, 5, "\\%03o", (unsigned)c);
+      e += 4;
+    }
+    else
+      *e++ = c;
+  }
+  *e = '\0';
+  return escaped;
+}
+
+/* setopt wrapper for enum types */
+CURLcode tool_setopt_enum(CURL *curl, struct GlobalConfig *config,
+                          const char *name, CURLoption tag,
+                          const NameValue *nvlist, long lval)
+{
+  CURLcode ret = CURLE_OK;
+  bool skip = FALSE;
+
+  ret = curl_easy_setopt(curl, tag, lval);
+  if(!lval)
+    skip = TRUE;
+
+  if(config->libcurl && !skip && !ret) {
+    /* we only use this for real if --libcurl was used */
+    const NameValue *nv = NULL;
+    for(nv = nvlist; nv->name; nv++) {
+      if(nv->value == lval) break; /* found it */
+    }
+    if(! nv->name) {
+      /* If no definition was found, output an explicit value.
+       * This could happen if new values are defined and used
+       * but the NameValue list is not updated. */
+      CODE2("curl_easy_setopt(hnd, %s, %ldL);", name, lval);
+    }
+    else {
+      CODE2("curl_easy_setopt(hnd, %s, (long)%s);", name, nv->name);
+    }
+  }
+
+ nomem:
+  return ret;
+}
+
+/* setopt wrapper for flags */
+CURLcode tool_setopt_flags(CURL *curl, struct GlobalConfig *config,
+                           const char *name, CURLoption tag,
+                           const NameValue *nvlist, long lval)
+{
+  CURLcode ret = CURLE_OK;
+  bool skip = FALSE;
+
+  ret = curl_easy_setopt(curl, tag, lval);
+  if(!lval)
+    skip = TRUE;
+
+  if(config->libcurl && !skip && !ret) {
+    /* we only use this for real if --libcurl was used */
+    char preamble[80];          /* should accommodate any symbol name */
+    long rest = lval;           /* bits not handled yet */
+    const NameValue *nv = NULL;
+    snprintf(preamble, sizeof(preamble),
+             "curl_easy_setopt(hnd, %s, ", name);
+    for(nv = nvlist; nv->name; nv++) {
+      if((nv->value & ~ rest) == 0) {
+        /* all value flags contained in rest */
+        rest &= ~ nv->value;    /* remove bits handled here */
+        CODE3("%s(long)%s%s",
+              preamble, nv->name, rest ? " |" : ");");
+        if(!rest)
+          break;                /* handled them all */
+        /* replace with all spaces for continuation line */
+        snprintf(preamble, sizeof(preamble), "%*s", strlen(preamble), "");
+      }
+    }
+    /* If any bits have no definition, output an explicit value.
+     * This could happen if new bits are defined and used
+     * but the NameValue list is not updated. */
+    if(rest)
+      CODE2("%s%ldL);", preamble, rest);
+  }
+
+ nomem:
+  return ret;
+}
+
+/* setopt wrapper for bitmasks */
+CURLcode tool_setopt_bitmask(CURL *curl, struct GlobalConfig *config,
+                             const char *name, CURLoption tag,
+                             const NameValueUnsigned *nvlist,
+                             long lval)
+{
+  CURLcode ret = CURLE_OK;
+  bool skip = FALSE;
+
+  ret = curl_easy_setopt(curl, tag, lval);
+  if(!lval)
+    skip = TRUE;
+
+  if(config->libcurl && !skip && !ret) {
+    /* we only use this for real if --libcurl was used */
+    char preamble[80];
+    unsigned long rest = (unsigned long)lval;
+    const NameValueUnsigned *nv = NULL;
+    snprintf(preamble, sizeof(preamble),
+             "curl_easy_setopt(hnd, %s, ", name);
+    for(nv = nvlist; nv->name; nv++) {
+      if((nv->value & ~ rest) == 0) {
+        /* all value flags contained in rest */
+        rest &= ~ nv->value;    /* remove bits handled here */
+        CODE3("%s(long)%s%s",
+              preamble, nv->name, rest ? " |" : ");");
+        if(!rest)
+          break;                /* handled them all */
+        /* replace with all spaces for continuation line */
+        snprintf(preamble, sizeof(preamble), "%*s", strlen(preamble), "");
+      }
+    }
+    /* If any bits have no definition, output an explicit value.
+     * This could happen if new bits are defined and used
+     * but the NameValue list is not updated. */
+    if(rest)
+      CODE2("%s%luUL);", preamble, rest);
+  }
+
+ nomem:
+  return ret;
+}
+
+/* Generate code for a struct curl_slist. */
+static CURLcode libcurl_generate_slist(struct curl_slist *slist, int *slistno)
+{
+  CURLcode ret = CURLE_OK;
+  char *escaped = NULL;
+
+  /* May need several slist variables, so invent name */
+  *slistno = ++easysrc_slist_count;
+
+  DECL1("struct curl_slist *slist%d;", *slistno);
+  DATA1("slist%d = NULL;", *slistno);
+  CLEAN1("curl_slist_free_all(slist%d);", *slistno);
+  CLEAN1("slist%d = NULL;", *slistno);
+  for(; slist; slist = slist->next) {
+    Curl_safefree(escaped);
+    escaped = c_escape(slist->data, CURL_ZERO_TERMINATED);
+    if(!escaped)
+      return CURLE_OUT_OF_MEMORY;
+    DATA3("slist%d = curl_slist_append(slist%d, \"%s\");",
+                                       *slistno, *slistno, escaped);
+  }
+
+ nomem:
+  Curl_safefree(escaped);
+  return ret;
+}
+
+/* Generate source code for a mime structure. */
+static CURLcode libcurl_generate_mime(curl_mime *mime, int *mimeno)
+{
+  CURLcode ret = CURLE_OK;
+  int i;
+  curl_off_t size;
+  curl_mimepart *part;
+  char *filename;
+  char *escaped = NULL;
+  char *cp;
+  char *data;
+
+  /* May need several mime variables, so invent name */
+  *mimeno = ++easysrc_mime_count;
+
+  DECL1("curl_mime *mime%d;", *mimeno);
+  DATA1("mime%d = NULL;", *mimeno);
+  CODE1("mime%d = curl_mime_init(hnd);", *mimeno);
+  CLEAN1("curl_mime_free(mime%d);", *mimeno);
+  CLEAN1("mime%d = NULL;", *mimeno);
+  if(mime->firstpart) {
+    DECL1("curl_mimepart *part%d;", *mimeno);
+    for(part = mime->firstpart; part; part = part->nextpart) {
+      CODE2("part%d = curl_mime_addpart(mime%d);", *mimeno, *mimeno);
+      filename = part->filename;
+      switch(part->kind) {
+      case MIMEKIND_FILE:
+        Curl_safefree(escaped);
+        escaped = c_escape(part->data, CURL_ZERO_TERMINATED);
+        if(!escaped)
+          return CURLE_OUT_OF_MEMORY;
+        CODE2("curl_mime_filedata(part%d, \"%s\");", *mimeno, escaped);
+        if(!filename)
+          CODE1("curl_mime_filename(part%d, NULL);", *mimeno);
+        else {
+          /* Fast check to see if remote file name is base name. */
+          filename = part->data;
+          for(cp = filename; *cp; cp++)
+            if(*cp == '/' || *cp == '\\')
+              filename = cp + 1;
+          if(!part->filename || !strcmp(filename, part->filename))
+            filename = NULL;
+          else
+            filename = part->filename;
+        }
+        break;
+      case MIMEKIND_CALLBACK:
+        /* Can only be reading stdin in the current context. */
+        CODE1("curl_mime_data_cb(part%d, -1, (curl_read_callback) fread, \\",
+              *mimeno);
+        CODE0("                  (curl_seek_callback) fseek, NULL, stdin);");
+        break;
+      case MIMEKIND_DATA:
+#ifdef CURL_DOES_CONVERSIONS
+          /* Data is stored in ASCII and we want in in the host character
+             code. Convert it back for output. */
+          data = malloc(part->datasize + 1);
+          if(!data) {
+            ret = CURLE_OUT_OF_MEMORY;
+            goto nomem;
+          }
+          memcpy(data, part->data, part->datasize + 1);
+          ret = convert_from_network(data, strlen(data));
+          if(ret) {
+            Curl_safefree(data);
+            goto nomem;
+          }
+#else
+        data = part->data;
+#endif
+
+        /* Are there any nul byte in data? */
+        for(cp = data; *cp; cp++)
+          ;
+        size = (cp == data + part->datasize)? (curl_off_t) -1: part->datasize;
+        Curl_safefree(escaped);
+        escaped = c_escape(data, (size_t) part->datasize);
+#ifdef CURL_DOES_CONVERSIONS
+        Curl_safefree(data);
+#endif
+        if(!escaped)
+          return CURLE_OUT_OF_MEMORY;
+        if(size >= 0)
+          CODE3("curl_mime_data(part%d, \"%s\", %" CURL_FORMAT_CURL_OFF_T ");",
+                                *mimeno, escaped, size);
+        else
+          CODE2("curl_mime_data(part%d, \"%s\", CURL_ZERO_TERMINATED);",
+                                *mimeno, escaped);
+        break;
+      case MIMEKIND_MULTIPART:
+        ret = libcurl_generate_mime(part->arg, &i);
+        if(ret)
+          goto nomem;
+        CODE2("curl_mime_subparts(part%d, mime%d);", *mimeno, i);
+        CODE1("mime%d = NULL;", i);   /* Avoid freeing in CLEAN sequence. */
+        break;
+      default:
+        /* Other cases not possible in this context. */
+        break;
+      }
+
+      if(part->encoder) {
+        Curl_safefree(escaped);
+        escaped = c_escape(part->encoder->name, CURL_ZERO_TERMINATED);
+        if(!escaped)
+          return CURLE_OUT_OF_MEMORY;
+        CODE2("curl_mime_encoder(part%d, \"%s\");", *mimeno, escaped);
+      }
+
+      if(filename) {
+        Curl_safefree(escaped);
+        escaped = c_escape(filename, CURL_ZERO_TERMINATED);
+        if(!escaped)
+          return CURLE_OUT_OF_MEMORY;
+        CODE2("curl_mime_filename(part%d, \"%s\");", *mimeno, escaped);
+      }
+
+      if(part->name) {
+        Curl_safefree(escaped);
+        escaped = c_escape(part->name, CURL_ZERO_TERMINATED);
+        if(!escaped)
+          return CURLE_OUT_OF_MEMORY;
+        CODE2("curl_mime_name(part%d, \"%s\");", *mimeno, escaped);
+      }
+
+      if(part->mimetype) {
+        Curl_safefree(escaped);
+        escaped = c_escape(part->mimetype, CURL_ZERO_TERMINATED);
+        if(!escaped)
+          return CURLE_OUT_OF_MEMORY;
+        CODE2("curl_mime_type(part%d, \"%s\");", *mimeno, escaped);
+      }
+
+      if(part->userheaders) {
+        int ownership = part->flags & MIME_USERHEADERS_OWNER? 1: 0;
+
+        ret = libcurl_generate_slist(part->userheaders, &i);
+        if(ret)
+          goto nomem;
+        CODE3("curl_mime_headers(part%d, slist%d, %d);",
+              *mimeno, i, ownership);
+        if(ownership)
+          CODE1("slist%d = NULL;", i); /* Prevent freeing in CLEAN sequence. */
+      }
+    }
+  }
+
+nomem:
+  Curl_safefree(escaped);
+  return ret;
+}
+
+/* setopt wrapper for CURLOPT_MIMEPOST */
+CURLcode tool_setopt_mimepost(CURL *curl, struct GlobalConfig *config,
+                              const char *name, CURLoption tag,
+                              curl_mime *mimepost)
+{
+  CURLcode ret = CURLE_OK;
+
+  ret = curl_easy_setopt(curl, tag, mimepost);
+
+  if(config->libcurl && mimepost && !ret) {
+    int i;
+
+    ret = libcurl_generate_mime(mimepost, &i);
+
+    if(!ret)
+      CODE2("curl_easy_setopt(hnd, %s, mime%d);", name, i);
+  }
+
+nomem:
+  return ret;
+}
+
+/* setopt wrapper for curl_slist options */
+CURLcode tool_setopt_slist(CURL *curl, struct GlobalConfig *config,
+                           const char *name, CURLoption tag,
+                           struct curl_slist *list)
+{
+  CURLcode ret = CURLE_OK;
+
+  ret = curl_easy_setopt(curl, tag, list);
+
+  if(config->libcurl && list && !ret) {
+    int i;
+
+    ret = libcurl_generate_slist(list, &i);
+    if(!ret)
+      CODE2("curl_easy_setopt(hnd, %s, slist%d);", name, i);
+  }
+
+ nomem:
+  return ret;
+}
+
+/* generic setopt wrapper for all other options.
+ * Some type information is encoded in the tag value. */
+CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *config,
+                     const char *name, CURLoption tag, ...)
+{
+  va_list arg;
+  char buf[256];
+  const char *value = NULL;
+  bool remark = FALSE;
+  bool skip = FALSE;
+  bool escape = FALSE;
+  char *escaped = NULL;
+  CURLcode ret = CURLE_OK;
+
+  va_start(arg, tag);
+
+  if(tag < CURLOPTTYPE_OBJECTPOINT) {
+    /* Value is expected to be a long */
+    long lval = va_arg(arg, long);
+    long defval = 0L;
+    const NameValue *nv = NULL;
+    for(nv = setopt_nv_CURLNONZERODEFAULTS; nv->name; nv++) {
+      if(!strcmp(name, nv->name)) {
+        defval = nv->value;
+        break; /* found it */
+      }
+    }
+
+    snprintf(buf, sizeof(buf), "%ldL", lval);
+    value = buf;
+    ret = curl_easy_setopt(curl, tag, lval);
+    if(lval == defval)
+      skip = TRUE;
+  }
+  else if(tag < CURLOPTTYPE_OFF_T) {
+    /* Value is some sort of object pointer */
+    void *pval = va_arg(arg, void *);
+
+    /* function pointers are never printable */
+    if(tag >= CURLOPTTYPE_FUNCTIONPOINT) {
+      if(pval) {
+        value = "functionpointer";
+        remark = TRUE;
+      }
+      else
+        skip = TRUE;
+    }
+
+    else if(pval && str) {
+      value = (char *)pval;
+      escape = TRUE;
+    }
+    else if(pval) {
+      value = "objectpointer";
+      remark = TRUE;
+    }
+    else
+      skip = TRUE;
+
+    ret = curl_easy_setopt(curl, tag, pval);
+
+  }
+  else {
+    /* Value is expected to be curl_off_t */
+    curl_off_t oval = va_arg(arg, curl_off_t);
+    snprintf(buf, sizeof(buf),
+             "(curl_off_t)%" CURL_FORMAT_CURL_OFF_T, oval);
+    value = buf;
+    ret = curl_easy_setopt(curl, tag, oval);
+
+    if(!oval)
+      skip = TRUE;
+  }
+
+  va_end(arg);
+
+  if(config->libcurl && !skip && !ret) {
+    /* we only use this for real if --libcurl was used */
+
+    if(remark)
+      REM2("%s set to a %s", name, value);
+    else {
+      if(escape) {
+        escaped = c_escape(value, CURL_ZERO_TERMINATED);
+        if(!escaped) {
+          ret = CURLE_OUT_OF_MEMORY;
+          goto nomem;
+        }
+        CODE2("curl_easy_setopt(hnd, %s, \"%s\");", name, escaped);
+      }
+      else
+        CODE2("curl_easy_setopt(hnd, %s, %s);", name, value);
+    }
+  }
+
+ nomem:
+  Curl_safefree(escaped);
+  return ret;
+}
+
+#endif /* CURL_DISABLE_LIBCURL_OPTION */
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_setopt.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_setopt.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_setopt.h	(revision 331)
@@ -0,0 +1,153 @@
+#ifndef HEADER_CURL_TOOL_SETOPT_H
+#define HEADER_CURL_TOOL_SETOPT_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+/*
+ * Macros used in operate()
+ */
+
+#define SETOPT_CHECK(v) do { \
+  result = (v); \
+  if(result) \
+    goto show_error; \
+} WHILE_FALSE
+
+#ifndef CURL_DISABLE_LIBCURL_OPTION
+
+/* Associate symbolic names with option values */
+typedef struct {
+  const char *name;
+  long value;
+} NameValue;
+
+typedef struct {
+  const char *name;
+  unsigned long value;
+} NameValueUnsigned;
+
+extern const NameValue setopt_nv_CURLPROXY[];
+extern const NameValue setopt_nv_CURL_SOCKS_PROXY[];
+extern const NameValue setopt_nv_CURL_HTTP_VERSION[];
+extern const NameValue setopt_nv_CURL_SSLVERSION[];
+extern const NameValue setopt_nv_CURL_TIMECOND[];
+extern const NameValue setopt_nv_CURLFTPSSL_CCC[];
+extern const NameValue setopt_nv_CURLUSESSL[];
+extern const NameValueUnsigned setopt_nv_CURLSSLOPT[];
+extern const NameValue setopt_nv_CURL_NETRC[];
+extern const NameValue setopt_nv_CURLPROTO[];
+extern const NameValueUnsigned setopt_nv_CURLAUTH[];
+
+/* Map options to NameValue sets */
+#define setopt_nv_CURLOPT_HTTP_VERSION setopt_nv_CURL_HTTP_VERSION
+#define setopt_nv_CURLOPT_HTTPAUTH setopt_nv_CURLAUTH
+#define setopt_nv_CURLOPT_SSLVERSION setopt_nv_CURL_SSLVERSION
+#define setopt_nv_CURLOPT_PROXY_SSLVERSION setopt_nv_CURL_SSLVERSION
+#define setopt_nv_CURLOPT_TIMECONDITION setopt_nv_CURL_TIMECOND
+#define setopt_nv_CURLOPT_FTP_SSL_CCC setopt_nv_CURLFTPSSL_CCC
+#define setopt_nv_CURLOPT_USE_SSL setopt_nv_CURLUSESSL
+#define setopt_nv_CURLOPT_SSL_OPTIONS setopt_nv_CURLSSLOPT
+#define setopt_nv_CURLOPT_NETRC setopt_nv_CURL_NETRC
+#define setopt_nv_CURLOPT_PROTOCOLS setopt_nv_CURLPROTO
+#define setopt_nv_CURLOPT_REDIR_PROTOCOLS setopt_nv_CURLPROTO
+#define setopt_nv_CURLOPT_PROXYTYPE setopt_nv_CURLPROXY
+#define setopt_nv_CURLOPT_PROXYAUTH setopt_nv_CURLAUTH
+#define setopt_nv_CURLOPT_SOCKS5_AUTH setopt_nv_CURLAUTH
+
+/* Intercept setopt calls for --libcurl */
+
+CURLcode tool_setopt_enum(CURL *curl, struct GlobalConfig *config,
+                          const char *name, CURLoption tag,
+                          const NameValue *nv, long lval);
+CURLcode tool_setopt_flags(CURL *curl, struct GlobalConfig *config,
+                           const char *name, CURLoption tag,
+                           const NameValue *nv, long lval);
+CURLcode tool_setopt_bitmask(CURL *curl, struct GlobalConfig *config,
+                             const char *name, CURLoption tag,
+                             const NameValueUnsigned *nv, long lval);
+CURLcode tool_setopt_mimepost(CURL *curl, struct GlobalConfig *config,
+                              const char *name, CURLoption tag,
+                              curl_mime *mimepost);
+CURLcode tool_setopt_slist(CURL *curl, struct GlobalConfig *config,
+                           const char *name, CURLoption tag,
+                           struct curl_slist *list);
+CURLcode tool_setopt(CURL *curl, bool str, struct GlobalConfig *config,
+                     const char *name, CURLoption tag, ...);
+
+#define my_setopt(x,y,z) \
+  SETOPT_CHECK(tool_setopt(x, FALSE, global, #y, y, z))
+
+#define my_setopt_str(x,y,z) \
+  SETOPT_CHECK(tool_setopt(x, TRUE, global, #y, y, z))
+
+#define my_setopt_enum(x,y,z) \
+  SETOPT_CHECK(tool_setopt_enum(x, global, #y, y, setopt_nv_ ## y, z))
+
+#define my_setopt_flags(x,y,z) \
+  SETOPT_CHECK(tool_setopt_flags(x, global, #y, y, setopt_nv_ ## y, z))
+
+#define my_setopt_bitmask(x,y,z) \
+  SETOPT_CHECK(tool_setopt_bitmask(x, global, #y, y, setopt_nv_ ## y, z))
+
+#define my_setopt_mimepost(x,y,z) \
+  SETOPT_CHECK(tool_setopt_mimepost(x, global, #y, y, z))
+
+#define my_setopt_slist(x,y,z) \
+  SETOPT_CHECK(tool_setopt_slist(x, global, #y, y, z))
+
+#define res_setopt(x,y,z) tool_setopt(x, FALSE, global, #y, y, z)
+
+#define res_setopt_str(x,y,z) tool_setopt(x, TRUE, global, #y, y, z)
+
+#else /* CURL_DISABLE_LIBCURL_OPTION */
+
+/* No --libcurl, so pass options directly to library */
+
+#define my_setopt(x,y,z) \
+  SETOPT_CHECK(curl_easy_setopt(x, y, z))
+
+#define my_setopt_str(x,y,z) \
+  SETOPT_CHECK(curl_easy_setopt(x, y, z))
+
+#define my_setopt_enum(x,y,z) \
+  SETOPT_CHECK(curl_easy_setopt(x, y, z))
+
+#define my_setopt_flags(x,y,z) \
+  SETOPT_CHECK(curl_easy_setopt(x, y, z))
+
+#define my_setopt_bitmask(x,y,z) \
+  SETOPT_CHECK(curl_easy_setopt(x, y, z))
+
+#define my_setopt_mimepost(x,y,z) \
+  SETOPT_CHECK(curl_easy_setopt(x, y, z))
+
+#define my_setopt_slist(x,y,z) \
+  SETOPT_CHECK(curl_easy_setopt(x, y, z))
+
+#define res_setopt(x,y,z) curl_easy_setopt(x,y,z)
+
+#define res_setopt_str(x,y,z) curl_easy_setopt(x,y,z)
+
+#endif /* CURL_DISABLE_LIBCURL_OPTION */
+
+#endif /* HEADER_CURL_TOOL_SETOPT_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_setup.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_setup.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_setup.h	(revision 331)
@@ -0,0 +1,74 @@
+#ifndef HEADER_CURL_TOOL_SETUP_H
+#define HEADER_CURL_TOOL_SETUP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#define CURL_NO_OLDIES
+
+/*
+ * curl_setup.h may define preprocessor macros such as _FILE_OFFSET_BITS and
+ * _LARGE_FILES in order to support files larger than 2 GB. On platforms
+ * where this happens it is mandatory that these macros are defined before
+ * any system header file is included, otherwise file handling function
+ * prototypes will be misdeclared and curl tool may not build properly;
+ * therefore we must include curl_setup.h before curl.h when building curl.
+ */
+
+#include "curl_setup.h" /* from the lib directory */
+
+/*
+ * curl tool certainly uses libcurl's external interface.
+ */
+
+#include <curl/curl.h> /* external interface */
+
+/*
+ * Platform specific stuff.
+ */
+
+#if defined(macintosh) && defined(__MRC__)
+#  define main(x,y) curl_main(x,y)
+#endif
+
+#ifdef TPF
+#  undef select
+   /* change which select is used for the curl command line tool */
+#  define select(a,b,c,d,e) tpf_select_bsd(a,b,c,d,e)
+   /* and turn off the progress meter */
+#  define CONF_DEFAULT (0|CONF_NOPROGRESS)
+#endif
+
+#ifndef OS
+#  define OS "unknown"
+#endif
+
+#ifndef UNPRINTABLE_CHAR
+   /* define what to use for unprintable characters */
+#  define UNPRINTABLE_CHAR '.'
+#endif
+
+#ifndef HAVE_STRDUP
+#  include "tool_strdup.h"
+#endif
+
+#endif /* HEADER_CURL_TOOL_SETUP_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_sleep.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_sleep.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_sleep.c	(revision 331)
@@ -0,0 +1,58 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#ifdef HAVE_SYS_SELECT_H
+#  include <sys/select.h>
+#endif
+
+#ifdef HAVE_POLL_H
+#  include <poll.h>
+#elif defined(HAVE_SYS_POLL_H)
+#  include <sys/poll.h>
+#endif
+
+#ifdef MSDOS
+#  include <dos.h>
+#endif
+
+#include "tool_sleep.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+void tool_go_sleep(long ms)
+{
+#if defined(MSDOS)
+  delay(ms);
+#elif defined(WIN32)
+  Sleep(ms);
+#elif defined(HAVE_POLL_FINE)
+  (void)poll((void *)0, 0, (int)ms);
+#else
+  struct timeval timeout;
+  timeout.tv_sec = ms / 1000L;
+  ms = ms % 1000L;
+  timeout.tv_usec = (int)ms * 1000;
+  select(0, NULL,  NULL, NULL, &timeout);
+#endif
+}
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_sleep.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_sleep.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_sleep.h	(revision 331)
@@ -0,0 +1,29 @@
+#ifndef HEADER_CURL_TOOL_SLEEP_H
+#define HEADER_CURL_TOOL_SLEEP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+void tool_go_sleep(long ms);
+
+#endif /* HEADER_CURL_TOOL_SLEEP_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_strdup.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_strdup.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_strdup.c	(revision 331)
@@ -0,0 +1,47 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2015, 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_strdup.h"
+
+#ifndef HAVE_STRDUP
+char *strdup(const char *str)
+{
+  size_t len;
+  char *newstr;
+
+  if(!str)
+    return (char *)NULL;
+
+  len = strlen(str);
+
+  if(len >= ((size_t)-1) / sizeof(char))
+    return (char *)NULL;
+
+  newstr = malloc((len + 1)*sizeof(char));
+  if(!newstr)
+    return (char *)NULL;
+
+  memcpy(newstr, str, (len + 1)*sizeof(char));
+
+  return newstr;
+
+}
+#endif
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_strdup.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_strdup.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_strdup.h	(revision 331)
@@ -0,0 +1,30 @@
+#ifndef HEADER_TOOL_STRDUP_H
+#define HEADER_TOOL_STRDUP_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#ifndef HAVE_STRDUP
+extern char *strdup(const char *str);
+#endif
+
+#endif /* HEADER_TOOL_STRDUP_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_urlglob.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_urlglob.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_urlglob.c	(revision 331)
@@ -0,0 +1,713 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+#include "tool_cfgable.h"
+#include "tool_doswin.h"
+#include "tool_urlglob.h"
+#include "tool_vms.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+#define GLOBERROR(string, column, code) \
+  glob->error = string, glob->pos = column, code
+
+void glob_cleanup(URLGlob* glob);
+
+static CURLcode glob_fixed(URLGlob *glob, char *fixed, size_t len)
+{
+  URLPattern *pat = &glob->pattern[glob->size];
+  pat->type = UPTSet;
+  pat->content.Set.size = 1;
+  pat->content.Set.ptr_s = 0;
+  pat->globindex = -1;
+
+  pat->content.Set.elements = malloc(sizeof(char *));
+
+  if(!pat->content.Set.elements)
+    return GLOBERROR("out of memory", 0, CURLE_OUT_OF_MEMORY);
+
+  pat->content.Set.elements[0] = malloc(len + 1);
+  if(!pat->content.Set.elements[0])
+    return GLOBERROR("out of memory", 0, CURLE_OUT_OF_MEMORY);
+
+  memcpy(pat->content.Set.elements[0], fixed, len);
+  pat->content.Set.elements[0][len] = 0;
+
+  return CURLE_OK;
+}
+
+/* multiply
+ *
+ * Multiplies and checks for overflow.
+ */
+static int multiply(unsigned long *amount, long with)
+{
+  unsigned long sum = *amount * with;
+  if(!with) {
+    *amount = 0;
+    return 0;
+  }
+  if(sum/with != *amount)
+    return 1; /* didn't fit, bail out */
+  *amount = sum;
+  return 0;
+}
+
+static CURLcode glob_set(URLGlob *glob, char **patternp,
+                         size_t *posp, unsigned long *amount,
+                         int globindex)
+{
+  /* processes a set expression with the point behind the opening '{'
+     ','-separated elements are collected until the next closing '}'
+  */
+  URLPattern *pat;
+  bool done = FALSE;
+  char *buf = glob->glob_buffer;
+  char *pattern = *patternp;
+  char *opattern = pattern;
+  size_t opos = *posp-1;
+
+  pat = &glob->pattern[glob->size];
+  /* patterns 0,1,2,... correspond to size=1,3,5,... */
+  pat->type = UPTSet;
+  pat->content.Set.size = 0;
+  pat->content.Set.ptr_s = 0;
+  pat->content.Set.elements = NULL;
+  pat->globindex = globindex;
+
+  while(!done) {
+    switch (*pattern) {
+    case '\0':                  /* URL ended while set was still open */
+      return GLOBERROR("unmatched brace", opos, CURLE_URL_MALFORMAT);
+
+    case '{':
+    case '[':                   /* no nested expressions at this time */
+      return GLOBERROR("nested brace", *posp, CURLE_URL_MALFORMAT);
+
+    case '}':                           /* set element completed */
+      if(opattern == pattern)
+        return GLOBERROR("empty string within braces", *posp,
+                         CURLE_URL_MALFORMAT);
+
+      /* add 1 to size since it'll be incremented below */
+      if(multiply(amount, pat->content.Set.size + 1))
+        return GLOBERROR("range overflow", 0, CURLE_URL_MALFORMAT);
+
+      /* fall-through */
+    case ',':
+
+      *buf = '\0';
+      if(pat->content.Set.elements) {
+        char **new_arr = realloc(pat->content.Set.elements,
+                                 (pat->content.Set.size + 1) * sizeof(char *));
+        if(!new_arr)
+          return GLOBERROR("out of memory", 0, CURLE_OUT_OF_MEMORY);
+
+        pat->content.Set.elements = new_arr;
+      }
+      else
+        pat->content.Set.elements = malloc(sizeof(char *));
+
+      if(!pat->content.Set.elements)
+        return GLOBERROR("out of memory", 0, CURLE_OUT_OF_MEMORY);
+
+      pat->content.Set.elements[pat->content.Set.size] =
+        strdup(glob->glob_buffer);
+      if(!pat->content.Set.elements[pat->content.Set.size])
+        return GLOBERROR("out of memory", 0, CURLE_OUT_OF_MEMORY);
+      ++pat->content.Set.size;
+
+      if(*pattern == '}') {
+        pattern++; /* pass the closing brace */
+        done = TRUE;
+        continue;
+      }
+
+      buf = glob->glob_buffer;
+      ++pattern;
+      ++(*posp);
+      break;
+
+    case ']':                           /* illegal closing bracket */
+      return GLOBERROR("unexpected close bracket", *posp, CURLE_URL_MALFORMAT);
+
+    case '\\':                          /* escaped character, skip '\' */
+      if(pattern[1]) {
+        ++pattern;
+        ++(*posp);
+      }
+      /* intentional fallthrough */
+    default:
+      *buf++ = *pattern++;              /* copy character to set element */
+      ++(*posp);
+    }
+  }
+
+  *patternp = pattern; /* return with the new position */
+  return CURLE_OK;
+}
+
+static CURLcode glob_range(URLGlob *glob, char **patternp,
+                           size_t *posp, unsigned long *amount,
+                           int globindex)
+{
+  /* processes a range expression with the point behind the opening '['
+     - char range: e.g. "a-z]", "B-Q]"
+     - num range: e.g. "0-9]", "17-2000]"
+     - num range with leading zeros: e.g. "001-999]"
+     expression is checked for well-formedness and collected until the next ']'
+  */
+  URLPattern *pat;
+  int rc;
+  char *pattern = *patternp;
+  char *c;
+
+  pat = &glob->pattern[glob->size];
+  pat->globindex = globindex;
+
+  if(ISALPHA(*pattern)) {
+    /* character range detected */
+    char min_c;
+    char max_c;
+    char end_c;
+    unsigned long step = 1;
+
+    pat->type = UPTCharRange;
+
+    rc = sscanf(pattern, "%c-%c%c", &min_c, &max_c, &end_c);
+
+    if(rc == 3) {
+      if(end_c == ':') {
+        char *endp;
+        errno = 0;
+        step = strtoul(&pattern[4], &endp, 10);
+        if(errno || &pattern[4] == endp || *endp != ']')
+          step = 0;
+        else
+          pattern = endp + 1;
+      }
+      else if(end_c != ']')
+        /* then this is wrong */
+        rc = 0;
+      else
+        /* end_c == ']' */
+        pattern += 4;
+    }
+
+    *posp += (pattern - *patternp);
+
+    if(rc != 3 || !step || step > (unsigned)INT_MAX ||
+       (min_c == max_c && step != 1) ||
+       (min_c != max_c && (min_c > max_c || step > (unsigned)(max_c - min_c) ||
+                           (max_c - min_c) > ('z' - 'a'))))
+      /* the pattern is not well-formed */
+      return GLOBERROR("bad range", *posp, CURLE_URL_MALFORMAT);
+
+    /* if there was a ":[num]" thing, use that as step or else use 1 */
+    pat->content.CharRange.step = (int)step;
+    pat->content.CharRange.ptr_c = pat->content.CharRange.min_c = min_c;
+    pat->content.CharRange.max_c = max_c;
+
+    if(multiply(amount, ((pat->content.CharRange.max_c -
+                          pat->content.CharRange.min_c) /
+                         pat->content.CharRange.step + 1)))
+      return GLOBERROR("range overflow", *posp, CURLE_URL_MALFORMAT);
+  }
+  else if(ISDIGIT(*pattern)) {
+    /* numeric range detected */
+    unsigned long min_n;
+    unsigned long max_n = 0;
+    unsigned long step_n = 0;
+    char *endp;
+
+    pat->type = UPTNumRange;
+    pat->content.NumRange.padlength = 0;
+
+    if(*pattern == '0') {
+      /* leading zero specified, count them! */
+      c = pattern;
+      while(ISDIGIT(*c)) {
+        c++;
+        ++pat->content.NumRange.padlength; /* padding length is set for all
+                                              instances of this pattern */
+      }
+    }
+
+    errno = 0;
+    min_n = strtoul(pattern, &endp, 10);
+    if(errno || (endp == pattern))
+      endp = NULL;
+    else {
+      if(*endp != '-')
+        endp = NULL;
+      else {
+        pattern = endp + 1;
+        while(*pattern && ISBLANK(*pattern))
+          pattern++;
+        if(!ISDIGIT(*pattern)) {
+          endp = NULL;
+          goto fail;
+        }
+        errno = 0;
+        max_n = strtoul(pattern, &endp, 10);
+        if(errno)
+          /* overflow */
+          endp = NULL;
+        else if(*endp == ':') {
+          pattern = endp + 1;
+          errno = 0;
+          step_n = strtoul(pattern, &endp, 10);
+          if(errno)
+            /* over/underflow situation */
+            endp = NULL;
+        }
+        else
+          step_n = 1;
+        if(endp && (*endp == ']')) {
+          pattern = endp + 1;
+        }
+        else
+          endp = NULL;
+      }
+    }
+
+    fail:
+    *posp += (pattern - *patternp);
+
+    if(!endp || !step_n ||
+       (min_n == max_n && step_n != 1) ||
+       (min_n != max_n && (min_n > max_n || step_n > (max_n - min_n))))
+      /* the pattern is not well-formed */
+      return GLOBERROR("bad range", *posp, CURLE_URL_MALFORMAT);
+
+    /* typecasting to ints are fine here since we make sure above that we
+       are within 31 bits */
+    pat->content.NumRange.ptr_n = pat->content.NumRange.min_n = min_n;
+    pat->content.NumRange.max_n = max_n;
+    pat->content.NumRange.step = step_n;
+
+    if(multiply(amount, ((pat->content.NumRange.max_n -
+                          pat->content.NumRange.min_n) /
+                         pat->content.NumRange.step + 1)))
+      return GLOBERROR("range overflow", *posp, CURLE_URL_MALFORMAT);
+  }
+  else
+    return GLOBERROR("bad range specification", *posp, CURLE_URL_MALFORMAT);
+
+  *patternp = pattern;
+  return CURLE_OK;
+}
+
+static bool peek_ipv6(const char *str, size_t *skip)
+{
+  /*
+   * Scan for a potential IPv6 literal.
+   * - Valid globs contain a hyphen and <= 1 colon.
+   * - IPv6 literals contain no hyphens and >= 2 colons.
+   */
+  size_t i = 0;
+  size_t colons = 0;
+  if(str[i++] != '[') {
+    return FALSE;
+  }
+  for(;;) {
+    const char c = str[i++];
+    if(ISALNUM(c) || c == '.' || c == '%') {
+      /* ok */
+    }
+    else if(c == ':') {
+      colons++;
+    }
+    else if(c == ']') {
+      *skip = i;
+      return colons >= 2 ? TRUE : FALSE;
+    }
+    else {
+      return FALSE;
+    }
+  }
+}
+
+static CURLcode glob_parse(URLGlob *glob, char *pattern,
+                           size_t pos, unsigned long *amount)
+{
+  /* processes a literal string component of a URL
+     special characters '{' and '[' branch to set/range processing functions
+   */
+  CURLcode res = CURLE_OK;
+  int globindex = 0; /* count "actual" globs */
+
+  *amount = 1;
+
+  while(*pattern && !res) {
+    char *buf = glob->glob_buffer;
+    size_t sublen = 0;
+    while(*pattern && *pattern != '{') {
+      if(*pattern == '[') {
+        /* skip over IPv6 literals and [] */
+        size_t skip = 0;
+        if(!peek_ipv6(pattern, &skip) && (pattern[1] == ']'))
+          skip = 2;
+        if(skip) {
+          memcpy(buf, pattern, skip);
+          buf += skip;
+          pattern += skip;
+          sublen += skip;
+          continue;
+        }
+        break;
+      }
+      if(*pattern == '}' || *pattern == ']')
+        return GLOBERROR("unmatched close brace/bracket", pos,
+                         CURLE_URL_MALFORMAT);
+
+      /* only allow \ to escape known "special letters" */
+      if(*pattern == '\\' &&
+         (*(pattern + 1) == '{' || *(pattern + 1) == '[' ||
+          *(pattern + 1) == '}' || *(pattern + 1) == ']') ) {
+
+        /* escape character, skip '\' */
+        ++pattern;
+        ++pos;
+      }
+      *buf++ = *pattern++; /* copy character to literal */
+      ++pos;
+      sublen++;
+    }
+    if(sublen) {
+      /* we got a literal string, add it as a single-item list */
+      *buf = '\0';
+      res = glob_fixed(glob, glob->glob_buffer, sublen);
+    }
+    else {
+      switch (*pattern) {
+      case '\0': /* done  */
+        break;
+
+      case '{':
+        /* process set pattern */
+        pattern++;
+        pos++;
+        res = glob_set(glob, &pattern, &pos, amount, globindex++);
+        break;
+
+      case '[':
+        /* process range pattern */
+        pattern++;
+        pos++;
+        res = glob_range(glob, &pattern, &pos, amount, globindex++);
+        break;
+      }
+    }
+
+    if(++glob->size >= GLOB_PATTERN_NUM)
+      return GLOBERROR("too many globs", pos, CURLE_URL_MALFORMAT);
+  }
+  return res;
+}
+
+CURLcode glob_url(URLGlob **glob, char *url, unsigned long *urlnum,
+                  FILE *error)
+{
+  /*
+   * We can deal with any-size, just make a buffer with the same length
+   * as the specified URL!
+   */
+  URLGlob *glob_expand;
+  unsigned long amount = 0;
+  char *glob_buffer;
+  CURLcode res;
+
+  *glob = NULL;
+
+  glob_buffer = malloc(strlen(url) + 1);
+  if(!glob_buffer)
+    return CURLE_OUT_OF_MEMORY;
+  glob_buffer[0] = 0;
+
+  glob_expand = calloc(1, sizeof(URLGlob));
+  if(!glob_expand) {
+    Curl_safefree(glob_buffer);
+    return CURLE_OUT_OF_MEMORY;
+  }
+  glob_expand->urllen = strlen(url);
+  glob_expand->glob_buffer = glob_buffer;
+
+  res = glob_parse(glob_expand, url, 1, &amount);
+  if(!res)
+    *urlnum = amount;
+  else {
+    if(error && glob_expand->error) {
+      char text[128];
+      const char *t;
+      if(glob_expand->pos) {
+        snprintf(text, sizeof(text), "%s in column %zu", glob_expand->error,
+                 glob_expand->pos);
+        t = text;
+      }
+      else
+        t = glob_expand->error;
+
+      /* send error description to the error-stream */
+      fprintf(error, "curl: (%d) [globbing] %s\n", res, t);
+    }
+    /* it failed, we cleanup */
+    glob_cleanup(glob_expand);
+    *urlnum = 1;
+    return res;
+  }
+
+  *glob = glob_expand;
+  return CURLE_OK;
+}
+
+void glob_cleanup(URLGlob* glob)
+{
+  size_t i;
+  int elem;
+
+  for(i = 0; i < glob->size; i++) {
+    if((glob->pattern[i].type == UPTSet) &&
+       (glob->pattern[i].content.Set.elements)) {
+      for(elem = glob->pattern[i].content.Set.size - 1;
+          elem >= 0;
+          --elem) {
+        Curl_safefree(glob->pattern[i].content.Set.elements[elem]);
+      }
+      Curl_safefree(glob->pattern[i].content.Set.elements);
+    }
+  }
+  Curl_safefree(glob->glob_buffer);
+  Curl_safefree(glob);
+}
+
+CURLcode glob_next_url(char **globbed, URLGlob *glob)
+{
+  URLPattern *pat;
+  size_t i;
+  size_t len;
+  size_t buflen = glob->urllen + 1;
+  char *buf = glob->glob_buffer;
+
+  *globbed = NULL;
+
+  if(!glob->beenhere)
+    glob->beenhere = 1;
+  else {
+    bool carry = TRUE;
+
+    /* implement a counter over the index ranges of all patterns, starting
+       with the rightmost pattern */
+    for(i = 0; carry && (i < glob->size); i++) {
+      carry = FALSE;
+      pat = &glob->pattern[glob->size - 1 - i];
+      switch(pat->type) {
+      case UPTSet:
+        if((pat->content.Set.elements) &&
+           (++pat->content.Set.ptr_s == pat->content.Set.size)) {
+          pat->content.Set.ptr_s = 0;
+          carry = TRUE;
+        }
+        break;
+      case UPTCharRange:
+        pat->content.CharRange.ptr_c =
+          (char)(pat->content.CharRange.step +
+                 (int)((unsigned char)pat->content.CharRange.ptr_c));
+        if(pat->content.CharRange.ptr_c > pat->content.CharRange.max_c) {
+          pat->content.CharRange.ptr_c = pat->content.CharRange.min_c;
+          carry = TRUE;
+        }
+        break;
+      case UPTNumRange:
+        pat->content.NumRange.ptr_n += pat->content.NumRange.step;
+        if(pat->content.NumRange.ptr_n > pat->content.NumRange.max_n) {
+          pat->content.NumRange.ptr_n = pat->content.NumRange.min_n;
+          carry = TRUE;
+        }
+        break;
+      default:
+        printf("internal error: invalid pattern type (%d)\n", (int)pat->type);
+        return CURLE_FAILED_INIT;
+      }
+    }
+    if(carry) {         /* first pattern ptr has run into overflow, done! */
+      /* TODO: verify if this should actally return CURLE_OK. */
+      return CURLE_OK; /* CURLE_OK to match previous behavior */
+    }
+  }
+
+  for(i = 0; i < glob->size; ++i) {
+    pat = &glob->pattern[i];
+    switch(pat->type) {
+    case UPTSet:
+      if(pat->content.Set.elements) {
+        snprintf(buf, buflen, "%s",
+                 pat->content.Set.elements[pat->content.Set.ptr_s]);
+        len = strlen(buf);
+        buf += len;
+        buflen -= len;
+      }
+      break;
+    case UPTCharRange:
+      if(buflen) {
+        *buf++ = pat->content.CharRange.ptr_c;
+        *buf = '\0';
+        buflen--;
+      }
+      break;
+    case UPTNumRange:
+      snprintf(buf, buflen, "%0*ld",
+               pat->content.NumRange.padlength,
+               pat->content.NumRange.ptr_n);
+      len = strlen(buf);
+      buf += len;
+      buflen -= len;
+      break;
+    default:
+      printf("internal error: invalid pattern type (%d)\n", (int)pat->type);
+      return CURLE_FAILED_INIT;
+    }
+  }
+
+  *globbed = strdup(glob->glob_buffer);
+  if(!*globbed)
+    return CURLE_OUT_OF_MEMORY;
+
+  return CURLE_OK;
+}
+
+CURLcode glob_match_url(char **result, char *filename, URLGlob *glob)
+{
+  char *target;
+  size_t allocsize;
+  char numbuf[18];
+  char *appendthis = NULL;
+  size_t appendlen = 0;
+  size_t stringlen = 0;
+
+  *result = NULL;
+
+  /* We cannot use the glob_buffer for storage here since the filename may
+   * be longer than the URL we use. We allocate a good start size, then
+   * we need to realloc in case of need.
+   */
+  allocsize = strlen(filename) + 1; /* make it at least one byte to store the
+                                       trailing zero */
+  target = malloc(allocsize);
+  if(!target)
+    return CURLE_OUT_OF_MEMORY;
+
+  while(*filename) {
+    if(*filename == '#' && ISDIGIT(filename[1])) {
+      unsigned long i;
+      char *ptr = filename;
+      unsigned long num = strtoul(&filename[1], &filename, 10);
+      URLPattern *pat = NULL;
+
+      if(num < glob->size) {
+        num--; /* make it zero based */
+        /* find the correct glob entry */
+        for(i = 0; i<glob->size; i++) {
+          if(glob->pattern[i].globindex == (int)num) {
+            pat = &glob->pattern[i];
+            break;
+          }
+        }
+      }
+
+      if(pat) {
+        switch(pat->type) {
+        case UPTSet:
+          if(pat->content.Set.elements) {
+            appendthis = pat->content.Set.elements[pat->content.Set.ptr_s];
+            appendlen =
+              strlen(pat->content.Set.elements[pat->content.Set.ptr_s]);
+          }
+          break;
+        case UPTCharRange:
+          numbuf[0] = pat->content.CharRange.ptr_c;
+          numbuf[1] = 0;
+          appendthis = numbuf;
+          appendlen = 1;
+          break;
+        case UPTNumRange:
+          snprintf(numbuf, sizeof(numbuf), "%0*lu",
+                   pat->content.NumRange.padlength,
+                   pat->content.NumRange.ptr_n);
+          appendthis = numbuf;
+          appendlen = strlen(numbuf);
+          break;
+        default:
+          fprintf(stderr, "internal error: invalid pattern type (%d)\n",
+                  (int)pat->type);
+          Curl_safefree(target);
+          return CURLE_FAILED_INIT;
+        }
+      }
+      else {
+        /* #[num] out of range, use the #[num] in the output */
+        filename = ptr;
+        appendthis = filename++;
+        appendlen = 1;
+      }
+    }
+    else {
+      appendthis = filename++;
+      appendlen = 1;
+    }
+    if(appendlen + stringlen >= allocsize) {
+      char *newstr;
+      /* we append a single byte to allow for the trailing byte to be appended
+         at the end of this function outside the while() loop */
+      allocsize = (appendlen + stringlen) * 2;
+      newstr = realloc(target, allocsize + 1);
+      if(!newstr) {
+        Curl_safefree(target);
+        return CURLE_OUT_OF_MEMORY;
+      }
+      target = newstr;
+    }
+    memcpy(&target[stringlen], appendthis, appendlen);
+    stringlen += appendlen;
+  }
+  target[stringlen]= '\0';
+
+#if defined(MSDOS) || defined(WIN32)
+  {
+    char *sanitized;
+    SANITIZEcode sc = sanitize_file_name(&sanitized, target,
+                                         (SANITIZE_ALLOW_PATH |
+                                          SANITIZE_ALLOW_RESERVED));
+    Curl_safefree(target);
+    if(sc)
+      return CURLE_URL_MALFORMAT;
+    target = sanitized;
+  }
+#endif /* MSDOS || WIN32 */
+
+  *result = target;
+  return CURLE_OK;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_urlglob.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_urlglob.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_urlglob.h	(revision 331)
@@ -0,0 +1,77 @@
+#ifndef HEADER_CURL_TOOL_URLGLOB_H
+#define HEADER_CURL_TOOL_URLGLOB_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+typedef enum {
+  UPTSet = 1,
+  UPTCharRange,
+  UPTNumRange
+} URLPatternType;
+
+typedef struct {
+  URLPatternType type;
+  int globindex; /* the number of this particular glob or -1 if not used
+                    within {} or [] */
+  union {
+    struct {
+      char **elements;
+      int size;
+      int ptr_s;
+    } Set;
+    struct {
+      char min_c;
+      char max_c;
+      char ptr_c;
+      int step;
+    } CharRange;
+    struct {
+      unsigned long min_n;
+      unsigned long max_n;
+      int padlength;
+      unsigned long ptr_n;
+      unsigned long step;
+    } NumRange;
+  } content;
+} URLPattern;
+
+/* the total number of globs supported */
+#define GLOB_PATTERN_NUM 100
+
+typedef struct {
+  URLPattern pattern[GLOB_PATTERN_NUM];
+  size_t size;
+  size_t urllen;
+  char *glob_buffer;
+  char beenhere;
+  const char *error; /* error message */
+  size_t pos;        /* column position of error or 0 */
+} URLGlob;
+
+CURLcode glob_url(URLGlob**, char *, unsigned long *, FILE *);
+CURLcode glob_next_url(char **, URLGlob *);
+CURLcode glob_match_url(char **, char *, URLGlob *);
+void glob_cleanup(URLGlob* glob);
+
+#endif /* HEADER_CURL_TOOL_URLGLOB_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_util.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_util.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_util.c	(revision 331)
@@ -0,0 +1,126 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#include "tool_util.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+#if defined(WIN32) && !defined(MSDOS)
+
+struct timeval tvnow(void)
+{
+  /*
+  ** GetTickCount() is available on _all_ Windows versions from W95 up
+  ** to nowadays. Returns milliseconds elapsed since last system boot,
+  ** increases monotonically and wraps once 49.7 days have elapsed.
+  **
+  ** GetTickCount64() is available on Windows version from Windows Vista
+  ** and Windows Server 2008 up to nowadays. The resolution of the
+  ** function is limited to the resolution of the system timer, which
+  ** is typically in the range of 10 milliseconds to 16 milliseconds.
+  */
+  struct timeval now;
+#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
+  ULONGLONG milliseconds = GetTickCount64();
+#else
+  DWORD milliseconds = GetTickCount();
+#endif
+  now.tv_sec = (long)(milliseconds / 1000);
+  now.tv_usec = (milliseconds % 1000) * 1000;
+  return now;
+}
+
+#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC)
+
+struct timeval tvnow(void)
+{
+  /*
+  ** clock_gettime() is granted to be increased monotonically when the
+  ** monotonic clock is queried. Time starting point is unspecified, it
+  ** could be the system start-up time, the Epoch, or something else,
+  ** in any case the time starting point does not change once that the
+  ** system has started up.
+  */
+  struct timeval now;
+  struct timespec tsnow;
+  if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) {
+    now.tv_sec = tsnow.tv_sec;
+    now.tv_usec = tsnow.tv_nsec / 1000;
+  }
+  /*
+  ** Even when the configure process has truly detected monotonic clock
+  ** availability, it might happen that it is not actually available at
+  ** run-time. When this occurs simply fallback to other time source.
+  */
+#ifdef HAVE_GETTIMEOFDAY
+  else
+    (void)gettimeofday(&now, NULL);
+#else
+  else {
+    now.tv_sec = (long)time(NULL);
+    now.tv_usec = 0;
+  }
+#endif
+  return now;
+}
+
+#elif defined(HAVE_GETTIMEOFDAY)
+
+struct timeval tvnow(void)
+{
+  /*
+  ** gettimeofday() is not granted to be increased monotonically, due to
+  ** clock drifting and external source time synchronization it can jump
+  ** forward or backward in time.
+  */
+  struct timeval now;
+  (void)gettimeofday(&now, NULL);
+  return now;
+}
+
+#else
+
+struct timeval tvnow(void)
+{
+  /*
+  ** time() returns the value of time in seconds since the Epoch.
+  */
+  struct timeval now;
+  now.tv_sec = (long)time(NULL);
+  now.tv_usec = 0;
+  return now;
+}
+
+#endif
+
+/*
+ * Make sure that the first argument is the more recent time, as otherwise
+ * we'll get a weird negative time-diff back...
+ *
+ * Returns: the time difference in number of milliseconds.
+ */
+long tvdiff(struct timeval newer, struct timeval older)
+{
+  return (long)(newer.tv_sec-older.tv_sec)*1000+
+    (long)(newer.tv_usec-older.tv_usec)/1000;
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_util.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_util.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_util.h	(revision 331)
@@ -0,0 +1,37 @@
+#ifndef HEADER_CURL_TOOL_UTIL_H
+#define HEADER_CURL_TOOL_UTIL_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+struct timeval tvnow(void);
+
+/*
+ * Make sure that the first argument (t1) is the more recent time and t2 is
+ * the older time, as otherwise you get a weird negative time-diff back...
+ *
+ * Returns: the time difference in number of milliseconds.
+ */
+long tvdiff(struct timeval t1, struct timeval t2);
+
+#endif /* HEADER_CURL_TOOL_UTIL_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_version.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_version.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_version.h	(revision 331)
@@ -0,0 +1,34 @@
+#ifndef HEADER_CURL_TOOL_VERSION_H
+#define HEADER_CURL_TOOL_VERSION_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include <curl/curlver.h>
+
+#define CURL_NAME "curl"
+#define CURL_COPYRIGHT LIBCURL_COPYRIGHT
+#define CURL_VERSION "7.57.0"
+#define CURL_VERSION_MAJOR LIBCURL_VERSION_MAJOR
+#define CURL_VERSION_MINOR LIBCURL_VERSION_MINOR
+#define CURL_VERSION_PATCH LIBCURL_VERSION_PATCH
+#define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "
+
+#endif /* HEADER_CURL_TOOL_VERSION_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_vms.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_vms.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_vms.c	(revision 331)
@@ -0,0 +1,219 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#ifdef __VMS
+
+#if defined(__DECC) && !defined(__VAX) && \
+    defined(__CRTL_VER) && (__CRTL_VER >= 70301000)
+#include <unixlib.h>
+#endif
+
+#define ENABLE_CURLX_PRINTF
+#include "curlx.h"
+
+#include "curlmsg_vms.h"
+#include "tool_vms.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+void decc$__posix_exit(int __status);
+void decc$exit(int __status);
+
+static int vms_shell = -1;
+
+/* VMS has a DCL shell and and also has Unix shells ported to it.
+ * When curl is running under a Unix shell, we want it to be as much
+ * like Unix as possible.
+ */
+int is_vms_shell(void)
+{
+  char *shell;
+
+  /* Have we checked the shell yet? */
+  if(vms_shell >= 0)
+    return vms_shell;
+
+  shell = getenv("SHELL");
+
+  /* No shell, means DCL */
+  if(shell == NULL) {
+    vms_shell = 1;
+    return 1;
+  }
+
+  /* Have to make sure some one did not set shell to DCL */
+  if(strcmp(shell, "DCL") == 0) {
+    vms_shell = 1;
+    return 1;
+  }
+
+  vms_shell = 0;
+  return 0;
+}
+
+/*
+ * VMS has two exit() routines.  When running under a Unix style shell, then
+ * Unix style and the __posix_exit() routine is used.
+ *
+ * When running under the DCL shell, then the VMS encoded codes and decc$exit()
+ * is used.
+ *
+ * We can not use exit() or return a code from main() because the actual
+ * routine called depends on both the compiler version, compile options, and
+ * feature macro settings, and one of the exit routines is hidden at compile
+ * time.
+ *
+ * Since we want Curl to work properly under the VMS DCL shell and Unix
+ * shells under VMS, this routine should compile correctly regardless of
+ * the settings.
+ */
+
+void vms_special_exit(int code, int vms_show)
+{
+  int vms_code;
+
+  /* The Posix exit mode is only available after VMS 7.0 */
+#if __CRTL_VER >= 70000000
+  if(is_vms_shell() == 0) {
+    decc$__posix_exit(code);
+  }
+#endif
+
+  if(code > CURL_LAST) {   /* If CURL_LAST exceeded then */
+    vms_code = CURL_LAST;  /* curlmsg.h is out of sync.  */
+  }
+  else {
+    vms_code = vms_cond[code] | vms_show;
+  }
+  decc$exit(vms_code);
+}
+
+#if defined(__DECC) && !defined(__VAX) && \
+    defined(__CRTL_VER) && (__CRTL_VER >= 70301000)
+
+/*
+ * 2004-09-19 SMS.
+ *
+ * decc_init()
+ *
+ * On non-VAX systems, use LIB$INITIALIZE to set a collection of C
+ * RTL features without using the DECC$* logical name method, nor
+ * requiring the user to define the corresponding logical names.
+ */
+
+/* Structure to hold a DECC$* feature name and its desired value. */
+typedef struct {
+  char *name;
+  int value;
+} decc_feat_t;
+
+/* Array of DECC$* feature names and their desired values. */
+static decc_feat_t decc_feat_array[] = {
+  /* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */
+  { "DECC$ARGV_PARSE_STYLE", 1 },
+  /* Preserve case for file names on ODS5 disks. */
+  { "DECC$EFS_CASE_PRESERVE", 1 },
+  /* Enable multiple dots (and most characters) in ODS5 file names,
+     while preserving VMS-ness of ";version". */
+  { "DECC$EFS_CHARSET", 1 },
+  /* List terminator. */
+  { (char *)NULL, 0 }
+};
+
+/* Flag to sense if decc_init() was called. */
+static int decc_init_done = -1;
+
+/* LIB$INITIALIZE initialization function. */
+static void decc_init(void)
+{
+  int feat_index;
+  int feat_value;
+  int feat_value_max;
+  int feat_value_min;
+  int i;
+  int sts;
+
+  /* Set the global flag to indicate that LIB$INITIALIZE worked. */
+  decc_init_done = 1;
+
+  /* Loop through all items in the decc_feat_array[]. */
+  for(i = 0; decc_feat_array[i].name != NULL; i++) {
+
+    /* Get the feature index. */
+    feat_index = decc$feature_get_index(decc_feat_array[i].name);
+
+    if(feat_index >= 0) {
+      /* Valid item.  Collect its properties. */
+      feat_value = decc$feature_get_value(feat_index, 1);
+      feat_value_min = decc$feature_get_value(feat_index, 2);
+      feat_value_max = decc$feature_get_value(feat_index, 3);
+
+      if((decc_feat_array[i].value >= feat_value_min) &&
+         (decc_feat_array[i].value <= feat_value_max)) {
+        /* Valid value.  Set it if necessary. */
+        if(feat_value != decc_feat_array[i].value) {
+          sts = decc$feature_set_value(feat_index, 1,
+                                       decc_feat_array[i].value);
+        }
+      }
+      else {
+        /* Invalid DECC feature value. */
+        printf(" INVALID DECC FEATURE VALUE, %d: %d <= %s <= %d.\n",
+               feat_value,
+               feat_value_min, decc_feat_array[i].name, feat_value_max);
+      }
+    }
+    else {
+      /* Invalid DECC feature name. */
+      printf(" UNKNOWN DECC FEATURE: %s.\n", decc_feat_array[i].name);
+    }
+
+  }
+}
+
+/* Get "decc_init()" into a valid, loaded LIB$INITIALIZE PSECT. */
+
+#pragma nostandard
+
+/* Establish the LIB$INITIALIZE PSECTs, with proper alignment and
+   other attributes.  Note that "nopic" is significant only on VAX. */
+#pragma extern_model save
+#pragma extern_model strict_refdef "LIB$INITIALIZ" 2, nopic, nowrt
+const int spare[8] = {0};
+#pragma extern_model strict_refdef "LIB$INITIALIZE" 2, nopic, nowrt
+void (*const x_decc_init)() = decc_init;
+#pragma extern_model restore
+
+/* Fake reference to ensure loading the LIB$INITIALIZE PSECT. */
+#pragma extern_model save
+int LIB$INITIALIZE(void);
+#pragma extern_model strict_refdef
+int dmy_lib$initialize = (int) LIB$INITIALIZE;
+#pragma extern_model restore
+
+#pragma standard
+
+#endif /* __DECC && !__VAX && __CRTL_VER && __CRTL_VER >= 70301000 */
+
+#endif /* __VMS */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_vms.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_vms.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_vms.h	(revision 331)
@@ -0,0 +1,47 @@
+#ifndef HEADER_CURL_TOOL_VMS_H
+#define HEADER_CURL_TOOL_VMS_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#ifdef __VMS
+
+/*
+ * Forward-declaration of global variable vms_show defined
+ * in tool_main.c, used in main() as parameter for function
+ * vms_special_exit() to allow proper curl tool exiting.
+ */
+extern int vms_show;
+
+int is_vms_shell(void);
+void vms_special_exit(int code, int vms_show);
+
+#undef exit
+#define exit(__code) vms_special_exit((__code), (0))
+
+#define  VMS_STS(c,f,e,s) (((c&0xF)<<28)|((f&0xFFF)<<16)|((e&0x1FFF)<3)|(s&7))
+#define  VMSSTS_HIDE  VMS_STS(1,0,0,0)
+
+#endif /* __VMS */
+
+#endif /* HEADER_CURL_TOOL_VMS_H */
+
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_writeout.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_writeout.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_writeout.c	(revision 331)
@@ -0,0 +1,369 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+#define ENABLE_CURLX_PRINTF
+/* use our own printf() functions */
+#include "curlx.h"
+#include "tool_cfgable.h"
+#include "tool_writeout.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+typedef enum {
+  VAR_NONE,       /* must be the first */
+  VAR_TOTAL_TIME,
+  VAR_NAMELOOKUP_TIME,
+  VAR_CONNECT_TIME,
+  VAR_APPCONNECT_TIME,
+  VAR_PRETRANSFER_TIME,
+  VAR_STARTTRANSFER_TIME,
+  VAR_SIZE_DOWNLOAD,
+  VAR_SIZE_UPLOAD,
+  VAR_SPEED_DOWNLOAD,
+  VAR_SPEED_UPLOAD,
+  VAR_HTTP_CODE,
+  VAR_HTTP_CODE_PROXY,
+  VAR_HEADER_SIZE,
+  VAR_REQUEST_SIZE,
+  VAR_EFFECTIVE_URL,
+  VAR_CONTENT_TYPE,
+  VAR_NUM_CONNECTS,
+  VAR_REDIRECT_TIME,
+  VAR_REDIRECT_COUNT,
+  VAR_FTP_ENTRY_PATH,
+  VAR_REDIRECT_URL,
+  VAR_SSL_VERIFY_RESULT,
+  VAR_PROXY_SSL_VERIFY_RESULT,
+  VAR_EFFECTIVE_FILENAME,
+  VAR_PRIMARY_IP,
+  VAR_PRIMARY_PORT,
+  VAR_LOCAL_IP,
+  VAR_LOCAL_PORT,
+  VAR_HTTP_VERSION,
+  VAR_SCHEME,
+  VAR_NUM_OF_VARS /* must be the last */
+} replaceid;
+
+struct variable {
+  const char *name;
+  replaceid id;
+};
+
+
+static const struct variable replacements[]={
+  {"url_effective", VAR_EFFECTIVE_URL},
+  {"http_code", VAR_HTTP_CODE},
+  {"response_code", VAR_HTTP_CODE},
+  {"http_connect", VAR_HTTP_CODE_PROXY},
+  {"time_total", VAR_TOTAL_TIME},
+  {"time_namelookup", VAR_NAMELOOKUP_TIME},
+  {"time_connect", VAR_CONNECT_TIME},
+  {"time_appconnect", VAR_APPCONNECT_TIME},
+  {"time_pretransfer", VAR_PRETRANSFER_TIME},
+  {"time_starttransfer", VAR_STARTTRANSFER_TIME},
+  {"size_header", VAR_HEADER_SIZE},
+  {"size_request", VAR_REQUEST_SIZE},
+  {"size_download", VAR_SIZE_DOWNLOAD},
+  {"size_upload", VAR_SIZE_UPLOAD},
+  {"speed_download", VAR_SPEED_DOWNLOAD},
+  {"speed_upload", VAR_SPEED_UPLOAD},
+  {"content_type", VAR_CONTENT_TYPE},
+  {"num_connects", VAR_NUM_CONNECTS},
+  {"time_redirect", VAR_REDIRECT_TIME},
+  {"num_redirects", VAR_REDIRECT_COUNT},
+  {"ftp_entry_path", VAR_FTP_ENTRY_PATH},
+  {"redirect_url", VAR_REDIRECT_URL},
+  {"ssl_verify_result", VAR_SSL_VERIFY_RESULT},
+  {"proxy_ssl_verify_result", VAR_PROXY_SSL_VERIFY_RESULT},
+  {"filename_effective", VAR_EFFECTIVE_FILENAME},
+  {"remote_ip", VAR_PRIMARY_IP},
+  {"remote_port", VAR_PRIMARY_PORT},
+  {"local_ip", VAR_LOCAL_IP},
+  {"local_port", VAR_LOCAL_PORT},
+  {"http_version", VAR_HTTP_VERSION},
+  {"scheme", VAR_SCHEME},
+  {NULL, VAR_NONE}
+};
+
+void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo)
+{
+  FILE *stream = stdout;
+  const char *ptr = writeinfo;
+  char *stringp = NULL;
+  long longinfo;
+  double doubleinfo;
+
+  while(ptr && *ptr) {
+    if('%' == *ptr && ptr[1]) {
+      if('%' == ptr[1]) {
+        /* an escaped %-letter */
+        fputc('%', stream);
+        ptr += 2;
+      }
+      else {
+        /* this is meant as a variable to output */
+        char *end;
+        char keepit;
+        int i;
+        if('{' == ptr[1]) {
+          bool match = FALSE;
+          end = strchr(ptr, '}');
+          ptr += 2; /* pass the % and the { */
+          if(!end) {
+            fputs("%{", stream);
+            continue;
+          }
+          keepit = *end;
+          *end = 0; /* zero terminate */
+          for(i = 0; replacements[i].name; i++) {
+            if(curl_strequal(ptr, replacements[i].name)) {
+              match = TRUE;
+              switch(replacements[i].id) {
+              case VAR_EFFECTIVE_URL:
+                if((CURLE_OK ==
+                    curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &stringp))
+                   && stringp)
+                  fputs(stringp, stream);
+                break;
+              case VAR_HTTP_CODE:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &longinfo))
+                  fprintf(stream, "%03ld", longinfo);
+                break;
+              case VAR_HTTP_CODE_PROXY:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_HTTP_CONNECTCODE,
+                                     &longinfo))
+                  fprintf(stream, "%03ld", longinfo);
+                break;
+              case VAR_HEADER_SIZE:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_HEADER_SIZE, &longinfo))
+                  fprintf(stream, "%ld", longinfo);
+                break;
+              case VAR_REQUEST_SIZE:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_REQUEST_SIZE, &longinfo))
+                  fprintf(stream, "%ld", longinfo);
+                break;
+              case VAR_NUM_CONNECTS:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_NUM_CONNECTS, &longinfo))
+                  fprintf(stream, "%ld", longinfo);
+                break;
+              case VAR_REDIRECT_COUNT:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_REDIRECT_COUNT, &longinfo))
+                  fprintf(stream, "%ld", longinfo);
+                break;
+              case VAR_REDIRECT_TIME:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_REDIRECT_TIME,
+                                     &doubleinfo))
+                  fprintf(stream, "%.6f", doubleinfo);
+                break;
+              case VAR_TOTAL_TIME:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &doubleinfo))
+                  fprintf(stream, "%.6f", doubleinfo);
+                break;
+              case VAR_NAMELOOKUP_TIME:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_NAMELOOKUP_TIME,
+                                     &doubleinfo))
+                  fprintf(stream, "%.6f", doubleinfo);
+                break;
+              case VAR_CONNECT_TIME:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_CONNECT_TIME, &doubleinfo))
+                  fprintf(stream, "%.6f", doubleinfo);
+                break;
+              case VAR_APPCONNECT_TIME:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_APPCONNECT_TIME,
+                                     &doubleinfo))
+                  fprintf(stream, "%.6f", doubleinfo);
+                break;
+              case VAR_PRETRANSFER_TIME:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_PRETRANSFER_TIME,
+                                     &doubleinfo))
+                  fprintf(stream, "%.6f", doubleinfo);
+                break;
+              case VAR_STARTTRANSFER_TIME:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_STARTTRANSFER_TIME,
+                                     &doubleinfo))
+                  fprintf(stream, "%.6f", doubleinfo);
+                break;
+              case VAR_SIZE_UPLOAD:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_SIZE_UPLOAD, &doubleinfo))
+                  fprintf(stream, "%.0f", doubleinfo);
+                break;
+              case VAR_SIZE_DOWNLOAD:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD,
+                                     &doubleinfo))
+                  fprintf(stream, "%.0f", doubleinfo);
+                break;
+              case VAR_SPEED_DOWNLOAD:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_SPEED_DOWNLOAD,
+                                     &doubleinfo))
+                  fprintf(stream, "%.3f", doubleinfo);
+                break;
+              case VAR_SPEED_UPLOAD:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD, &doubleinfo))
+                  fprintf(stream, "%.3f", doubleinfo);
+                break;
+              case VAR_CONTENT_TYPE:
+                if((CURLE_OK ==
+                    curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &stringp))
+                   && stringp)
+                  fputs(stringp, stream);
+                break;
+              case VAR_FTP_ENTRY_PATH:
+                if((CURLE_OK ==
+                    curl_easy_getinfo(curl, CURLINFO_FTP_ENTRY_PATH, &stringp))
+                   && stringp)
+                  fputs(stringp, stream);
+                break;
+              case VAR_REDIRECT_URL:
+                if((CURLE_OK ==
+                    curl_easy_getinfo(curl, CURLINFO_REDIRECT_URL, &stringp))
+                   && stringp)
+                  fputs(stringp, stream);
+                break;
+              case VAR_SSL_VERIFY_RESULT:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_SSL_VERIFYRESULT,
+                                     &longinfo))
+                  fprintf(stream, "%ld", longinfo);
+                break;
+              case VAR_PROXY_SSL_VERIFY_RESULT:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_PROXY_SSL_VERIFYRESULT,
+                                     &longinfo))
+                  fprintf(stream, "%ld", longinfo);
+                break;
+              case VAR_EFFECTIVE_FILENAME:
+                if(outs->filename)
+                  fprintf(stream, "%s", outs->filename);
+                break;
+              case VAR_PRIMARY_IP:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_PRIMARY_IP,
+                                     &stringp))
+                  fprintf(stream, "%s", stringp);
+                break;
+              case VAR_PRIMARY_PORT:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_PRIMARY_PORT,
+                                     &longinfo))
+                  fprintf(stream, "%ld", longinfo);
+                break;
+              case VAR_LOCAL_IP:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_LOCAL_IP,
+                                     &stringp))
+                  fprintf(stream, "%s", stringp);
+                break;
+              case VAR_LOCAL_PORT:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_LOCAL_PORT,
+                                     &longinfo))
+                  fprintf(stream, "%ld", longinfo);
+                break;
+              case VAR_HTTP_VERSION:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_HTTP_VERSION,
+                                     &longinfo)) {
+                  const char *version = "0";
+                  switch(longinfo) {
+                  case CURL_HTTP_VERSION_1_0:
+                    version = "1.0";
+                    break;
+                  case CURL_HTTP_VERSION_1_1:
+                    version = "1.1";
+                    break;
+                  case CURL_HTTP_VERSION_2_0:
+                    version = "2";
+                    break;
+                  }
+
+                  fprintf(stream, version);
+                }
+                break;
+              case VAR_SCHEME:
+                if(CURLE_OK ==
+                   curl_easy_getinfo(curl, CURLINFO_SCHEME,
+                                     &stringp))
+                  fprintf(stream, "%s", stringp);
+                break;
+              default:
+                break;
+              }
+              break;
+            }
+          }
+          if(!match) {
+            fprintf(stderr, "curl: unknown --write-out variable: '%s'\n", ptr);
+          }
+          ptr = end + 1; /* pass the end */
+          *end = keepit;
+        }
+        else {
+          /* illegal syntax, then just output the characters that are used */
+          fputc('%', stream);
+          fputc(ptr[1], stream);
+          ptr += 2;
+        }
+      }
+    }
+    else if('\\' == *ptr && ptr[1]) {
+      switch(ptr[1]) {
+      case 'r':
+        fputc('\r', stream);
+        break;
+      case 'n':
+        fputc('\n', stream);
+        break;
+      case 't':
+        fputc('\t', stream);
+        break;
+      default:
+        /* unknown, just output this */
+        fputc(*ptr, stream);
+        fputc(ptr[1], stream);
+        break;
+      }
+      ptr += 2;
+    }
+    else {
+      fputc(*ptr, stream);
+      ptr++;
+    }
+  }
+
+}
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_writeout.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_writeout.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_writeout.h	(revision 331)
@@ -0,0 +1,28 @@
+#ifndef HEADER_CURL_TOOL_WRITEOUT_H
+#define HEADER_CURL_TOOL_WRITEOUT_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo);
+
+#endif /* HEADER_CURL_TOOL_WRITEOUT_H */
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_xattr.c
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_xattr.c	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_xattr.c	(revision 331)
@@ -0,0 +1,90 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+#ifdef HAVE_FSETXATTR
+#  include <sys/xattr.h> /* header from libc, not from libattr */
+#  define USE_XATTR
+#elif defined(__FreeBSD_version) && (__FreeBSD_version > 500000)
+#  include <sys/types.h>
+#  include <sys/extattr.h>
+#  define USE_XATTR
+#endif
+
+#include "tool_xattr.h"
+
+#include "memdebug.h" /* keep this as LAST include */
+
+#ifdef USE_XATTR
+
+/* mapping table of curl metadata to extended attribute names */
+static const struct xattr_mapping {
+  const char *attr; /* name of the xattr */
+  CURLINFO info;
+} mappings[] = {
+  /* mappings proposed by
+   * https://freedesktop.org/wiki/CommonExtendedAttributes/
+   */
+  { "user.xdg.origin.url", CURLINFO_EFFECTIVE_URL },
+  { "user.mime_type",      CURLINFO_CONTENT_TYPE },
+  { NULL,                  CURLINFO_NONE } /* last element, abort loop here */
+};
+
+/* store metadata from the curl request alongside the downloaded
+ * file using extended attributes
+ */
+int fwrite_xattr(CURL *curl, int fd)
+{
+  int i = 0;
+  int err = 0;
+
+  /* loop through all xattr-curlinfo pairs and abort on a set error */
+  while(err == 0 && mappings[i].attr != NULL) {
+    char *value = NULL;
+    CURLcode result = curl_easy_getinfo(curl, mappings[i].info, &value);
+    if(!result && value) {
+#ifdef HAVE_FSETXATTR_6
+      err = fsetxattr(fd, mappings[i].attr, value, strlen(value), 0, 0);
+#elif defined(HAVE_FSETXATTR_5)
+      err = fsetxattr(fd, mappings[i].attr, value, strlen(value), 0);
+#elif defined(__FreeBSD_version)
+      err = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, mappings[i].attr, value,
+                           strlen(value));
+      /* FreeBSD's extattr_set_fd returns the length of the extended attribute
+       */
+      err = err < 0 ? err : 0;
+#endif
+    }
+    i++;
+  }
+
+  return err;
+}
+#else
+int fwrite_xattr(CURL *curl, int fd)
+{
+  (void)curl;
+  (void)fd;
+
+  return 0;
+}
+#endif
Index: EcnlProtoTool/trunk/curl-7.57.0/src/tool_xattr.h
===================================================================
--- EcnlProtoTool/trunk/curl-7.57.0/src/tool_xattr.h	(revision 331)
+++ EcnlProtoTool/trunk/curl-7.57.0/src/tool_xattr.h	(revision 331)
@@ -0,0 +1,28 @@
+#ifndef HEADER_CURL_TOOL_XATTR_H
+#define HEADER_CURL_TOOL_XATTR_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at https://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+#include "tool_setup.h"
+
+int fwrite_xattr(CURL *curl, int fd);
+
+#endif /* HEADER_CURL_TOOL_XATTR_H */
Index: EcnlProtoTool/trunk/mbed_api/.cproject
===================================================================
--- EcnlProtoTool/trunk/mbed_api/.cproject	(revision 331)
+++ EcnlProtoTool/trunk/mbed_api/.cproject	(revision 331)
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.1999115066">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.1999115066" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactExtension="a" artifactName="mbed_api" buildArtefactType="com.renesas.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=com.renesas.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf *.lst *.lis *.lpp *.map" description="" id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.1999115066" name="Debug" parent="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id">
+					<folderInfo id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.1999115066." name="/" resourcePath="">
+						<toolChain id="com.renesas.cdt.library.rz.debug.win32.toolchain.Id.1444898039" name="KPIT GNUARM-NONE-EABI Toolchain" superClass="com.renesas.cdt.library.rz.debug.win32.toolchain.Id">
+							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.PE" id="com.renesas.cdt.rz.libraryProject.debug.win32.targetplatform.Id.417414325" name="Target Platform" osList="win32,linux" superClass="com.renesas.cdt.rz.libraryProject.debug.win32.targetplatform.Id"/>
+							<builder buildPath="${workspace_loc:/mbed_api}/Debug" id="com.renesas.cdt.rz.library.project.debug.win32.builder.Id.1026711547" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.renesas.cdt.rz.library.project.debug.win32.builder.Id"/>
+							<tool id="com.renesas.cdt.rz.libraryProject.debug.win32.tool.compiler.Id.1464099988" name="Compiler" superClass="com.renesas.cdt.rz.libraryProject.debug.win32.tool.compiler.Id">
+								<option defaultValue="true" id="com.renesas.cdt.core.Compiler.option.misc2.1650703967" name="æ¨æºã·ã¹ãã ã»ãã£ã¬ã¯ããªã¼ã§ãããã¼ã»ãã¡ã¤ã«ãæ¤ç´¢ããªã (-nostdinc)" superClass="com.renesas.cdt.core.Compiler.option.misc2" valueType="boolean"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.dataEndian.396195566" name="ã¨ã³ãã£ã¢ã³" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.dataEndian" value="Little-endian" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.instructionset.1309707879" name="å½ä»¤ã»ãã" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.instructionset" value="ARM" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.interworking.318160267" name="ã¤ã³ã¿ã¼ã»ã¯ã¼ã­ã³ã°" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.interworking" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.targetfpu.1176349968" name="ã¿ã¼ã²ãã FPU (-mfpu)" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.targetfpu" value="vfpv3-d16" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.floatingpointabi.535009700" name="æµ®åå°æ°ç¹ ABI (-mfloat-abi=name)" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.floatingpointabi" value="Hard" valueType="enumerated"/>
+								<option id="com.renesas.cdt.core.Compiler.option.warnStackSize.1919208342" name="Warn if stack size exceeds the limit (-Wstack-usage) (H')" superClass="com.renesas.cdt.core.Compiler.option.warnStackSize" value="100" valueType="string"/>
+								<option id="com.renesas.cdt.core.Compiler.option.CPUSeries.318068373" name="CPU ã·ãªã¼ãº" superClass="com.renesas.cdt.core.Compiler.option.CPUSeries" value="RZ/A" valueType="string"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.architecture.1196905908" name="ã¢ã¼ã­ãã¯ãã£ã¼" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.architecture" value="armv7-a" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.cpuType.70735302" name="CPU ã¿ã¤ã" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.cpuType" value="cortex-a9" valueType="enumerated"/>
+								<option id="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal.1654052344" name="Decimal representation of '-Wstack-usage'" superClass="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal" value="256" valueType="string"/>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.core.Compiler.option.includeFileDir.2079620586" name="ã¤ã³ã¯ã«ã¼ãã»ãã¡ã¤ã«ã»ãã£ã¬ã¯ããªã¼" superClass="com.renesas.cdt.core.Compiler.option.includeFileDir" valueType="includePath">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/musl-1.1.18/include}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre/mbed/common}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre/mbed/api}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre/mbed/hal}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/include}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src}&quot;"/>
+								</option>
+								<option id="com.renesas.cdt.core.Compiler.option.misc21.1058742108" name="å®è¡æã«å¼ã³åºãå¯è½ãªãã¼ã¸ã§ã³ã®é¢æ°ãå¥éåºåãã (-fkeep-inline-functions)" superClass="com.renesas.cdt.core.Compiler.option.misc21" value="true" valueType="boolean"/>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.rz.Debug.Compiler.option.library.userDefinedOptions.258955288" name="ã¦ã¼ã¶ã¼å®ç¾©ãªãã·ã§ã³" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.userDefinedOptions" valueType="stringList">
+									<listOptionValue builtIn="false" value="-fPIC"/>
+								</option>
+								<inputType id="%Base.Compiler.C.InputType.Id.976055988" name="C å
+¥å" superClass="%Base.Compiler.C.InputType.Id"/>
+								<inputType id="Base.Compiler.CPP.InputType.Id.384212094" name="C++ å
+¥å" superClass="Base.Compiler.CPP.InputType.Id"/>
+							</tool>
+							<tool id="com.renesas.cdt.library.rz.Debug.win32.tool.assembler.Id.458281786" name="Assembler" superClass="com.renesas.cdt.library.rz.Debug.win32.tool.assembler.Id">
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.dataEndian.1774402683" name="ã¨ã³ãã£ã¢ã³" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.dataEndian" value="Little-endian" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.instructionset.37280990" name="å½ä»¤ã»ãã" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.instructionset" value="ARM" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.targetfpu.954079859" name="ã¿ã¼ã²ãã FPU (-mfpu)" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.targetfpu" value="vfpv3-d16" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.floatingpointabi.613317599" name="æµ®åå°æ°ç¹ ABI (-mfloat-abi=name)" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.floatingpointabi" value="Hard" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.architecture.595192512" name="ã¢ã¼ã­ãã¯ãã£ã¼" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.architecture" value="armv7-a" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.cpuType.2146674240" name="CPU ã¿ã¤ã" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.cpuType" value="cortex-a9" valueType="enumerated"/>
+								<inputType id="%Base.Assembler.inputType.Id.1532003886" name="ã¢ã»ã³ãã©ã¼å
+¥åã¿ã¤ã" superClass="%Base.Assembler.inputType.Id"/>
+							</tool>
+							<tool id="com.renesas.cdt.library.rz.debug.win32.tool.archive.Id.2062995098" name="Archive Generator" superClass="com.renesas.cdt.library.rz.debug.win32.tool.archive.Id"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="mbed_api.com.renesas.cdt.rz.library.projectType.Id.295772913" name="Static Library (Renesas)" projectType="com.renesas.cdt.rz.library.projectType.Id"/>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+	<storageModule moduleId="refreshScope" versionNumber="2">
+		<configuration configurationName="Debug">
+			<resource resourceType="PROJECT" workspacePath="/mbed_api"/>
+		</configuration>
+	</storageModule>
+</cproject>
Index: EcnlProtoTool/trunk/mbed_api/.info
===================================================================
--- EcnlProtoTool/trunk/mbed_api/.info	(revision 331)
+++ EcnlProtoTool/trunk/mbed_api/.info	(revision 331)
@@ -0,0 +1,7 @@
+TOOL_CHAIN=KPIT GNUARM-NONE-EABI Toolchain
+VERSION=v16.01
+TC_INSTALL=C:\Program Files (x86)\KPIT\GNUARM-NONEv16.01-EABI\arm-none-eabi\arm-none-eabi\
+GCC_STRING=5.2-GNUARM-NONE_v16.01
+VERSION_IDE=
+E2STUDIO_VERSION=5.4.0.018
+ACTIVE_CONFIGURATION=Debug
Index: EcnlProtoTool/trunk/mbed_api/.project
===================================================================
--- EcnlProtoTool/trunk/mbed_api/.project	(revision 331)
+++ EcnlProtoTool/trunk/mbed_api/.project	(revision 331)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>mbed_api</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>com.renesas.cdt.core.genmakebuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>com.renesas.cdt.core.kpitcnature</nature>
+		<nature>com.renesas.cdt.core.kpitccnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+	</natures>
+</projectDescription>
Index: EcnlProtoTool/trunk/mbed_api/src/mbed_api.c
===================================================================
--- EcnlProtoTool/trunk/mbed_api/src/mbed_api.c	(revision 331)
+++ EcnlProtoTool/trunk/mbed_api/src/mbed_api.c	(revision 331)
@@ -0,0 +1,323 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ *
+ *  Copyright (C) 2017 Cores Co., Ltd. Japan
+ *
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+ *  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+ *  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+ *      ã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+ *        å ±åãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+ *      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+ *      å
+è²¬ãããã¨ï¼
+ *
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+ *  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+ *  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+ *  ã®è²¬ä»»ãè² ããªãï¼
+ *
+ *  @(#) $Id$
+ */
+#include "mbedcall.h"
+#include "mbed_api.h"
+
+#define __asm_mbedcall(...) do { \
+	__asm__ __volatile__ ( "push { lr }" ); \
+	__asm__ __volatile__ ( "svc 1" \
+	: "=r"(r0) : __VA_ARGS__ : "memory"); \
+	__asm__ __volatile__ ( "pop { lr }" ); \
+	return r0; \
+	} while (0)
+
+static inline long __mbedcall0(long n)
+{
+	register long r7 __asm__("r7") = n;
+	register long r0 __asm__("r0");
+	__asm_mbedcall("r"(r7));
+}
+
+static inline long __mbedcall1(long n, long a)
+{
+	register long r7 __asm__("r7") = n;
+	register long r0 __asm__("r0") = a;
+	__asm_mbedcall("r"(r7), "0"(r0));
+}
+
+static inline long __mbedcall2(long n, long a, long b)
+{
+	register long r7 __asm__("r7") = n;
+	register long r0 __asm__("r0") = a;
+	register long r1 __asm__("r1") = b;
+	__asm_mbedcall("r"(r7), "0"(r0), "r"(r1));
+}
+
+static inline long __mbedcall3(long n, long a, long b, long c)
+{
+	register long r7 __asm__("r7") = n;
+	register long r0 __asm__("r0") = a;
+	register long r1 __asm__("r1") = b;
+	register long r2 __asm__("r2") = c;
+	__asm_mbedcall("r"(r7), "0"(r0), "r"(r1), "r"(r2));
+}
+
+static inline long __mbedcall4(long n, long a, long b, long c, long d)
+{
+	register long r7 __asm__("r7") = n;
+	register long r0 __asm__("r0") = a;
+	register long r1 __asm__("r1") = b;
+	register long r2 __asm__("r2") = c;
+	register long r3 __asm__("r3") = d;
+	__asm_mbedcall("r"(r7), "0"(r0), "r"(r1), "r"(r2), "r"(r3));
+}
+
+static inline long __mbedcall5(long n, long a, long b, long c, long d, long e)
+{
+	register long r7 __asm__("r7") = n;
+	register long r0 __asm__("r0") = a;
+	register long r1 __asm__("r1") = b;
+	register long r2 __asm__("r2") = c;
+	register long r3 __asm__("r3") = d;
+	register long r4 __asm__("r4") = e;
+	__asm_mbedcall("r"(r7), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4));
+}
+
+static inline long __mbedcall6(long n, long a, long b, long c, long d, long e, long f)
+{
+	register long r7 __asm__("r7") = n;
+	register long r0 __asm__("r0") = a;
+	register long r1 __asm__("r1") = b;
+	register long r2 __asm__("r2") = c;
+	register long r3 __asm__("r3") = d;
+	register long r4 __asm__("r4") = e;
+	register long r5 __asm__("r5") = f;
+	__asm_mbedcall("r"(r7), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5));
+}
+
+void analogin_init(analogin_t *obj, PinName pin)
+{
+	__mbedcall2(MBED_analogin_init, (long)obj, (long)pin);
+}
+
+uint16_t analogin_read_u16(analogin_t *obj)
+{
+	return __mbedcall1(MBED_analogin_read_u16, (long)obj);
+}
+
+void gpio_init(gpio_t *obj, PinName pin)
+{
+	__mbedcall2(MBED_gpio_init, (long)obj, (long)pin);
+}
+
+void gpio_mode(gpio_t *obj, PinMode mode)
+{
+	__mbedcall2(MBED_gpio_mode, (long)obj, (long)mode);
+}
+
+void gpio_dir(gpio_t *obj, PinDirection direction)
+{
+	__mbedcall2(MBED_gpio_dir, (long)obj, (long)direction);
+}
+
+void gpio_write(gpio_t *obj, int value)
+{
+	__mbedcall2(MBED_gpio_write, (long)obj, (long)value);
+}
+
+int  gpio_read(gpio_t *obj)
+{
+	return __mbedcall1(MBED_gpio_read, (long)obj);
+}
+
+int i2c_start(i2c_t *obj)
+{
+	return __mbedcall1(MBED_i2c_start, (long)obj);
+}
+
+int i2c_stop(i2c_t *obj)
+{
+	return __mbedcall1(MBED_i2c_stop, (long)obj);
+}
+
+void i2c_init(i2c_t *obj, PinName sda, PinName scl)
+{
+	__mbedcall3(MBED_i2c_init, (long)obj, (long)sda, (long)scl);
+}
+
+int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
+{
+	return __mbedcall5(MBED_i2c_read, (long)obj, (long)address, (long)data, (long)length, (long)stop);
+}
+
+int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
+{
+	return __mbedcall5(MBED_i2c_write, (long)obj, (long)address, (long)data, (long)length, (long)stop);
+}
+
+int i2c_byte_read(i2c_t *obj, int last)
+{
+	return __mbedcall2(MBED_i2c_byte_read, (long)obj, (long)last);
+}
+
+int i2c_byte_write(i2c_t *obj, int data)
+{
+	return __mbedcall2(MBED_i2c_byte_write, (long)obj, (long)data);
+}
+
+void pin_function(PinName pin, int function)
+{
+	__mbedcall2(MBED_pin_function, (long)pin, (long)function);
+}
+
+void pin_mode(PinName pin, PinMode mode)
+{
+	__mbedcall2(MBED_pin_mode, (long)pin, (long)mode);
+}
+
+void pwmout_free(pwmout_t* obj)
+{
+	__mbedcall1(MBED_pwmout_free, (long)obj);
+}
+
+void pwmout_init(pwmout_t* obj, PinName pin)
+{
+	__mbedcall2(MBED_pwmout_init, (long)obj, (long)pin);
+}
+
+void pwmout_pulsewidth_us(pwmout_t* obj, int us)
+{
+	__mbedcall2(MBED_pwmout_pulsewidth_us, (long)obj, (long)us);
+}
+
+void rtc_init(void)
+{
+	__mbedcall0(MBED_rtc_init);
+}
+
+void rtc_free(void)
+{
+	__mbedcall0(MBED_rtc_free);
+}
+
+int rtc_isenabled(void)
+{
+	return __mbedcall0(MBED_rtc_isenabled);
+}
+
+time_t rtc_read(void)
+{
+	return __mbedcall0(MBED_rtc_read);
+}
+
+void rtc_write(time_t t)
+{
+	__mbedcall1(MBED_rtc_write, (long)t);
+}
+
+void serial_baud(serial_t *obj, int baudrate)
+{
+	__mbedcall2(MBED_serial_baud, (long)obj, (long)baudrate);
+}
+
+void serial_init(serial_t *obj, PinName tx, PinName rx)
+{
+	__mbedcall3(MBED_serial_init, (long)obj, (long)tx, (long)rx);
+}
+
+int serial_readable(serial_t *obj)
+{
+	return __mbedcall1(MBED_serial_readable, (long)obj);
+}
+
+int serial_getc(serial_t *obj)
+{
+	return __mbedcall1(MBED_serial_getc, (long)obj);
+}
+
+void serial_putc(serial_t *obj, int c)
+{
+	__mbedcall2(MBED_serial_putc, (long)obj, (long)c);
+}
+
+void us_ticker_init(void)
+{
+	__mbedcall0(MBED_us_ticker_init);
+}
+
+uint32_t us_ticker_read(void)
+{
+	return __mbedcall0(MBED_us_ticker_read);
+}
+
+void us_ticker_set_interrupt(timestamp_t timestamp)
+{
+	__mbedcall1(MBED_us_ticker_set_interrupt, (long)timestamp);
+}
+
+void us_ticker_disable_interrupt(void)
+{
+	__mbedcall0(MBED_us_ticker_disable_interrupt);
+}
+
+void us_ticker_clear_interrupt(void)
+{
+	__mbedcall0(MBED_us_ticker_clear_interrupt);
+}
+
+int SD_begin()
+{
+	return __mbedcall0(MBED_SD_begin);
+}
+
+void __disable_irq()
+{
+	__mbedcall0(MBED___disable_irq);
+}
+
+void __enable_irq()
+{
+	__mbedcall0(MBED___enable_irq);
+}
+
+#include "assert.c"
+#include "board.c"
+#include "error.c"
+#include "gpio.c"
+#include "lp_ticker_api.c"
+#include "mbed_interface.c"
+#include "pinmap_common.c"
+//#include "rtc_time.c"
+#include "semihost_api.c"
+#include "ticker_api.c"
+#include "us_ticker_api.c"
+#include "wait_api.c"
Index: EcnlProtoTool/trunk/mbed_api/src/mbed_api.h
===================================================================
--- EcnlProtoTool/trunk/mbed_api/src/mbed_api.h	(revision 331)
+++ EcnlProtoTool/trunk/mbed_api/src/mbed_api.h	(revision 331)
@@ -0,0 +1,192 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2014-2017 Cores Co., Ltd. Japan
+ * 
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+ *  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+ *  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+ *      ã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+ *        å ±åãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+ *      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+ *      å
+è²¬ãããã¨ï¼
+ * 
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+ *  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+ *  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+ *  ã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+#ifndef _MBED_API_H_
+#define _MBED_API_H_
+
+#include <time.h>
+#include <stdint.h>
+
+void mbed_api_init(void);
+
+typedef enum {
+	PIN_LED0 = 100,
+	PIN_LED1,
+	PIN_LED2,
+	PIN_LED3,
+	NC = (int)0xFFFFFFFF
+} PinName;
+
+typedef enum {
+	PIN_INPUT,
+	PIN_OUTPUT
+} PinDirection;
+
+typedef enum {
+	PullUp = 0,
+	PullDown = 3,
+	PullNone = 2,
+	OpenDrain = 4,
+	PullDefault = PullDown
+} PinMode;
+
+typedef struct gpio_s {
+	unsigned char __dummy[24];
+} gpio_t;
+
+void gpio_init(gpio_t *obj, PinName pin);
+void gpio_mode(gpio_t *obj, PinMode mode);
+void gpio_dir(gpio_t *obj, PinDirection direction);
+
+void gpio_write(gpio_t *obj, int value);
+int gpio_read(gpio_t *obj);
+
+void gpio_init_in(gpio_t* gpio, PinName pin);
+void gpio_init_out(gpio_t* gpio, PinName pin);
+
+typedef struct analogin_s {
+	unsigned char __dummy[24];
+} analogin_t;
+
+void analogin_init(analogin_t *obj, PinName pin);
+uint16_t analogin_read_u16(analogin_t *obj);
+
+typedef struct dac_s {
+	unsigned char __dummy[24];
+} dac_t;
+
+void analogout_init(dac_t *obj, PinName pin);
+void analogout_write_u16(dac_t *obj, uint16_t value);
+
+void pin_function(PinName pin, int function);
+void pin_mode(PinName pin, PinMode mode);
+
+typedef struct pwmout_s {
+	unsigned char __dummy[24];
+} pwmout_t;
+
+void pwmout_init(pwmout_t* obj, PinName pin);
+void pwmout_free(pwmout_t* obj);
+
+void pwmout_period_us(pwmout_t* obj, int us);
+void pwmout_pulsewidth_us(pwmout_t* obj, int us);
+
+void arduino_tick();
+
+typedef enum {
+    ParityNone = 0,
+    ParityOdd = 1,
+    ParityEven = 2,
+    ParityForced1 = 3,
+    ParityForced0 = 4
+} SerialParity;
+
+typedef enum {
+    FlowControlNone,
+    FlowControlRTS,
+    FlowControlCTS,
+    FlowControlRTSCTS
+} FlowControl;
+
+typedef struct serial_s {
+	unsigned char __dummy[24];
+} serial_t;
+
+typedef struct spi_s {
+	unsigned char __dummy[24];
+} spi_t;
+
+void serial_init(serial_t *obj, PinName tx, PinName rx);
+void serial_free(serial_t *obj);
+void serial_baud(serial_t *obj, int baudrate);
+void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits);
+int serial_getc(serial_t *obj);
+void serial_putc(serial_t *obj, int c);
+int serial_readable(serial_t *obj);
+int serial_writable(serial_t *obj);
+
+typedef struct i2c_s {
+	unsigned char __dummy[24];
+} i2c_t;
+
+void i2c_init(i2c_t *obj, PinName sda, PinName scl);
+void i2c_frequency(i2c_t *obj, int hz);
+int i2c_start(i2c_t *obj);
+int i2c_stop(i2c_t *obj);
+int i2c_read(i2c_t *obj, int address, char *data, int length, int stop);
+int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop);
+int i2c_byte_read(i2c_t *obj, int last);
+int i2c_byte_write(i2c_t *obj, int data);
+
+void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel);
+void spi_free(spi_t *obj);
+void spi_format(spi_t *obj, int bits, int mode, int slave);
+void spi_frequency(spi_t *obj, int hz);
+int spi_master_write(spi_t *obj, int value);
+
+void rtc_init(void);
+void rtc_free(void);
+int rtc_isenabled(void);
+time_t rtc_read(void);
+void rtc_write(time_t t);
+
+typedef uint32_t timestamp_t;
+
+void us_ticker_init(void);
+timestamp_t us_ticker_read(void);
+void us_ticker_set_interrupt(timestamp_t timestamp);
+void us_ticker_disable_interrupt(void);
+void us_ticker_clear_interrupt(void);
+
+void wait_ms(int ms);
+void wait_us(int us);
+
+#endif /* _MBED_API_H_ */
Index: EcnlProtoTool/trunk/mbed_api/src/mbedcall.h
===================================================================
--- EcnlProtoTool/trunk/mbed_api/src/mbedcall.h	(revision 331)
+++ EcnlProtoTool/trunk/mbed_api/src/mbedcall.h	(revision 331)
@@ -0,0 +1,37 @@
+#define MBED_analogin_init	1
+#define MBED_analogin_read_u16	2
+#define MBED_gpio_init	3
+#define MBED_gpio_mode	4
+#define MBED_gpio_dir	5
+#define MBED_gpio_write	6
+#define MBED_gpio_read	7
+#define MBED_i2c_start	8
+#define MBED_i2c_stop	9
+#define MBED_i2c_init	10
+#define MBED_i2c_read	11
+#define MBED_i2c_write	12
+#define MBED_i2c_byte_read	13
+#define MBED_i2c_byte_write	14
+#define MBED_pin_function	15
+#define MBED_pin_mode	16
+#define MBED_pwmout_free	17
+#define MBED_pwmout_init	18
+#define MBED_pwmout_pulsewidth_us	19
+#define MBED_rtc_init	20
+#define MBED_rtc_free	21
+#define MBED_rtc_isenabled	22
+#define MBED_rtc_read	23
+#define MBED_rtc_write	24
+#define MBED_serial_baud	25
+#define MBED_serial_init	26
+#define MBED_serial_readable	27
+#define MBED_serial_getc	28
+#define MBED_serial_putc	29
+#define MBED_us_ticker_init	30
+#define MBED_us_ticker_disable_interrupt	31
+#define MBED_us_ticker_clear_interrupt	32
+#define MBED_us_ticker_set_interrupt	33
+#define MBED_us_ticker_read	34
+#define MBED_SD_begin	35
+#define MBED___enable_irq	36
+#define MBED___disable_irq	37
Index: EcnlProtoTool/trunk/mrbgems/mruby-digest/.gitignore
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-digest/.gitignore	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-digest/.gitignore	(revision 331)
@@ -0,0 +1,5 @@
+gem_*
+gem-*
+mrb-*.a
+src/*.o
+/tmp
Index: EcnlProtoTool/trunk/mrbgems/mruby-digest/.travis.yml
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-digest/.travis.yml	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-digest/.travis.yml	(revision 331)
@@ -0,0 +1,23 @@
+dist: trusty
+sudo: required
+install:
+  - sudo apt-get -qq update
+  - sudo apt-get -qq install build-essential rake bison git curl zlib1g-dev
+env:
+  global:
+    - CFLAGS=-I/opt/include LDFLAGS=-L/opt/lib
+  matrix:
+    - SSL_VERSION=openssl-1.0.2 DOWNLOAD_URL="https://www.openssl.org/source/${SSL_VERSION}-latest.tar.gz"
+    - SSL_VERSION=openssl-1.1.0 DOWNLOAD_URL="https://www.openssl.org/source/${SSL_VERSION}-latest.tar.gz"
+    - SSL_VERSION=libressl-2.5.5 DOWNLOAD_URL="https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/${SSL_VERSION}.tar.gz"
+    - SSL_VERSION=libressl-2.6.2 DOWNLOAD_URL="https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/${SSL_VERSION}.tar.gz"
+before_script:
+  - curl -sSfL $DOWNLOAD_URL | tar xz
+  - pushd ${SSL_VERSION}*
+  - ./config --prefix=/opt shared zlib -fPIC > /dev/null
+  - make > /dev/null
+  - sudo make install_sw > /dev/null
+  - popd
+  - sudo ldconfig /opt/lib
+script:
+  - "ruby run_test.rb all test"
Index: EcnlProtoTool/trunk/mrbgems/mruby-digest/Makefile
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-digest/Makefile	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-digest/Makefile	(revision 331)
@@ -0,0 +1,14 @@
+GEM := mruby-digest
+
+include $(MAKEFILE_4_GEM)
+
+GEM_C_FILES := $(wildcard $(SRC_DIR)/*.c)
+GEM_OBJECTS := $(patsubst %.c, %.o, $(GEM_C_FILES))
+
+GEM_RB_FILES := $(wildcard $(MRB_DIR)/*.rb)
+
+gem-all : $(GEM_OBJECTS) gem-c-and-rb-files
+
+gem-clean : gem-clean-c-and-rb-files
+
+gem-test : gem-test-c-and-rb-files
Index: EcnlProtoTool/trunk/mrbgems/mruby-digest/README.md
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-digest/README.md	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-digest/README.md	(revision 331)
@@ -0,0 +1,56 @@
+mruby-digest
+=========
+
+## Features
+
+Message Digest and HMAC classes are available.  They are compatible with CRuby's ones.
+
+- Digest::MD5, Digest::RMD160, Digest::SHA1, Digest::SHA256, Digest::SHA384 and
+  Digest::SHA512
+  - Note: some of them are not available if libcrypto.a does not support them on your system.
+- Digest::HMAC
+
+## Install
+ - add conf.gem line to `build_config.rb`
+
+```ruby
+MRuby::Build.new do |conf|
+
+    # ... (snip) ...
+
+    conf.gem :git => 'https://github.com/iij/mruby-digest.git'
+end
+```
+
+## Usage
+```ruby
+Digest::MD5.digest('ruby')
+Digest::MD5.hexdigest('ruby')
+```
+
+## Requirement
+- OpenSSL library (libcrypto.a) on Unix systems
+- Common Crypto library on MacOSX
+
+## License
+
+Copyright (c) 2012 Internet Initiative Japan Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a 
+copy of this software and associated documentation files (the "Software"), 
+to deal in the Software without restriction, including without limitation 
+the rights to use, copy, modify, merge, publish, distribute, sublicense, 
+and/or sell copies of the Software, and to permit persons to whom the 
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in 
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+DEALINGS IN THE SOFTWARE.
+
Index: EcnlProtoTool/trunk/mrbgems/mruby-digest/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-digest/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-digest/mrbgem.rake	(revision 331)
@@ -0,0 +1,6 @@
+MRuby::Gem::Specification.new('mruby-digest') do |spec|
+  spec.license = 'MIT'
+  spec.authors = 'Internet Initiative Japan Inc.'
+
+  spec.linker.libraries << 'crypto' unless RUBY_PLATFORM =~ /darwin/
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-digest/mrblib/digest.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-digest/mrblib/digest.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-digest/mrblib/digest.rb	(revision 331)
@@ -0,0 +1,46 @@
+if Object.const_defined? :Digest
+module Digest
+  class Base
+    def self.digest(data)
+      self.new.update(data).digest
+    end
+    def self.file(path)
+      self.new.update(File.open(path).read)
+    end
+    def self.hexdigest(data)
+      self.new.update(data).hexdigest
+    end
+    def ==(other)
+      if other.kind_of? String
+        self.hexdigest == other
+      else 
+        self.digest == other.digest
+      end
+    end
+    def file(path)
+      self.update(File.open(path).read)
+    end
+    def hexdigest!
+      x = self.hexdigest
+      self.reset
+      x
+    end
+
+    alias length digest_length
+    alias size digest_length
+    alias to_s hexdigest
+    alias << update
+  end
+
+  class HMAC
+    def self.digest(data, key, digest)
+      self.new(key, digest).update(data).digest
+    end
+    def self.hexdigest(data, key, digest)
+      self.new(key, digest).update(data).hexdigest
+    end
+
+    alias << update
+  end
+end
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-digest/run_test.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-digest/run_test.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-digest/run_test.rb	(revision 331)
@@ -0,0 +1,26 @@
+#!/usr/bin/env ruby
+#
+# mrbgems test runner
+#
+
+gemname = File.basename(File.dirname(File.expand_path __FILE__))
+
+if __FILE__ == $0
+  repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby'
+  build_args = ARGV
+  build_args = ['all', 'test']  if build_args.nil? or build_args.empty?
+
+  Dir.mkdir 'tmp'  unless File.exist?('tmp')
+  unless File.exist?(dir)
+    system "git clone #{repository} #{dir}"
+  end
+
+  exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}])
+end
+
+MRuby::Build.new do |conf|
+  toolchain :gcc
+  conf.gembox 'default'
+
+  conf.gem File.expand_path(File.dirname(__FILE__))
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-digest/src/digest.c
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-digest/src/digest.c	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-digest/src/digest.c	(revision 331)
@@ -0,0 +1,879 @@
+/*
+** digest.c - Digest and subclasses
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include "mruby.h"
+
+#ifdef __APPLE__
+#define USE_DIGEST_OSX_COMMONCRYPTO
+#else
+#define USE_DIGEST_OPENSSL
+#endif
+
+#if defined(USE_DIGEST_OPENSSL)
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/sha.h>
+#elif defined(USE_DIGEST_OSX_COMMONCRYPTO)
+#include <CommonCrypto/CommonDigest.h>
+#include <CommonCrypto/CommonHMAC.h>
+#else
+#error "define USE_DIGEST_OPENSSL or USE_DIGEST_OSX_COMMONCRYPTO"
+#endif
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include "mruby/array.h"
+#include "mruby/class.h"
+#include "mruby/data.h"
+#include "mruby/string.h"
+#include "mruby/variable.h"
+
+#define TYPESYM "__type__"
+
+
+/*
+ * library-independent layer API
+ */
+enum {
+	MD_TYPE_MD5,
+	MD_TYPE_RMD160,
+	MD_TYPE_SHA1,
+	MD_TYPE_SHA256,
+	MD_TYPE_SHA384,
+	MD_TYPE_SHA512,
+};
+
+struct mrb_md;
+struct mrb_hmac;
+
+static void lib_init(void);
+static int lib_md_block_length(const struct mrb_md *);
+static mrb_value lib_md_digest(mrb_state *, const struct mrb_md *);
+static mrb_value lib_md_digest_bang(mrb_state *, struct mrb_md *);
+static int lib_md_digest_length(const struct mrb_md *);
+static void lib_md_free(mrb_state *, void *);
+static void lib_md_init(mrb_state *, struct mrb_md *, int);
+static void lib_md_init_copy(mrb_state *, struct mrb_md *, struct mrb_md *);
+static void lib_md_reset(mrb_state *, struct mrb_md *);
+static void lib_md_update(mrb_state *, struct mrb_md *, unsigned char *, mrb_int);
+
+static mrb_value lib_hmac_digest(mrb_state *, const struct mrb_hmac *);
+static int lib_hmac_block_length(const struct mrb_hmac *);
+static int lib_hmac_digest_length(const struct mrb_hmac *);
+static void lib_hmac_free(mrb_state *, void *);
+static void lib_hmac_init(mrb_state *, struct mrb_hmac *, int, const unsigned char *, mrb_int);
+static void lib_hmac_update(mrb_state *, struct mrb_hmac *, unsigned char *, mrb_int);
+
+
+#if defined(USE_DIGEST_OPENSSL)
+/*
+ * OpenSSL Implementation
+ */
+
+#define HAVE_MD5
+
+#ifndef OPENSSL_NO_RIPEMD
+#define HAVE_RMD160
+#endif
+
+#define HAVE_SHA1
+#ifdef SHA256_DIGEST_LENGTH
+#define HAVE_SHA256
+#endif
+#ifdef SHA512_DIGEST_LENGTH
+#define HAVE_SHA384
+#define HAVE_SHA512
+#endif
+
+struct mrb_md {
+  EVP_MD_CTX *ctx;
+};
+
+struct mrb_hmac {
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined LIBRESSL_VERSION_NUMBER)
+  HMAC_CTX *ctx;
+#else
+  HMAC_CTX ctx;
+#endif
+  const EVP_MD *md;
+};
+
+static void
+lib_md_free(mrb_state *mrb, void *ptr)
+{
+  struct mrb_md *md = ptr;
+
+  if (md != NULL) {
+    if (md->ctx != NULL) {
+      EVP_MD_CTX_destroy(md->ctx);
+    }
+    mrb_free(mrb, md);
+  }
+}
+
+static void
+lib_hmac_free(mrb_state *mrb, void *ptr)
+{
+  struct mrb_hmac *hmac = ptr;
+
+  if (hmac != NULL) {
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined LIBRESSL_VERSION_NUMBER)
+    HMAC_CTX_free(hmac->ctx);
+#else
+    HMAC_CTX_cleanup(&hmac->ctx);
+#endif
+    mrb_free(mrb, hmac);
+  }
+}
+
+static struct mrb_data_type mrb_md_type = { "MD", lib_md_free };
+static struct mrb_data_type mrb_hmac_type = { "HMAC", lib_hmac_free };
+
+static void
+lib_init(void)
+{
+  OpenSSL_add_all_digests();
+}
+
+static int
+lib_md_block_length(const struct mrb_md *md)
+{
+  return EVP_MD_CTX_block_size(md->ctx);
+}
+
+static mrb_value
+lib_md_digest(mrb_state *mrb, const struct mrb_md *md)
+{
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined LIBRESSL_VERSION_NUMBER)
+  EVP_MD_CTX *ctx;
+#else
+  EVP_MD_CTX ctx;
+#endif
+  unsigned int mdlen;
+  unsigned char mdstr[EVP_MAX_MD_SIZE];
+
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined LIBRESSL_VERSION_NUMBER)
+  ctx = EVP_MD_CTX_new();
+  EVP_MD_CTX_copy(ctx, md->ctx);
+  EVP_DigestFinal(ctx, mdstr, &mdlen);
+  EVP_MD_CTX_free(ctx);
+#else
+  EVP_MD_CTX_copy(&ctx, md->ctx);
+  EVP_DigestFinal(&ctx, mdstr, &mdlen);
+#endif
+  return mrb_str_new(mrb, (char *)mdstr, mdlen);
+}
+
+static mrb_value
+lib_md_digest_bang(mrb_state *mrb, struct mrb_md *md)
+{
+  unsigned int mdlen;
+  unsigned char mdstr[EVP_MAX_MD_SIZE];
+
+  EVP_DigestFinal_ex(md->ctx, mdstr, &mdlen);
+  EVP_DigestInit_ex(md->ctx, EVP_MD_CTX_md(md->ctx), NULL);
+  return mrb_str_new(mrb, (char *)mdstr, mdlen);
+}
+
+static int
+lib_md_digest_length(const struct mrb_md *md)
+{
+  return EVP_MD_CTX_size(md->ctx);
+}
+
+const EVP_MD *
+md_type_md(int type)
+{
+  switch (type) {
+  case MD_TYPE_MD5:	return EVP_md5();
+#ifdef HAVE_RMD160
+  case MD_TYPE_RMD160:	return EVP_ripemd160();
+#endif
+  case MD_TYPE_SHA1:	return EVP_sha1();
+#ifdef HAVE_SHA256
+  case MD_TYPE_SHA256:	return EVP_sha256();
+#endif
+#ifdef HAVE_SHA512
+  case MD_TYPE_SHA384:	return EVP_sha384();
+  case MD_TYPE_SHA512:	return EVP_sha512();
+#endif
+  default:		return NULL;
+  }
+}
+
+static void
+lib_md_init(mrb_state *mrb, struct mrb_md *md, int type)
+{
+  const EVP_MD *evpmd;
+
+  md->ctx = NULL;
+  evpmd = md_type_md(type);
+  if (!evpmd) {
+    mrb_raise(mrb, E_NOTIMP_ERROR, "not supported");
+  }
+  md->ctx = EVP_MD_CTX_create();
+  EVP_DigestInit_ex(md->ctx, evpmd, NULL);
+}
+
+static void
+lib_md_init_copy(mrb_state *mrb, struct mrb_md *mdnew, struct mrb_md *mdold)
+{
+  mdnew->ctx = EVP_MD_CTX_create();
+  EVP_DigestInit_ex(mdnew->ctx, EVP_MD_CTX_md(mdold->ctx), NULL);
+}
+
+static void
+lib_md_reset(mrb_state *mrb, struct mrb_md *md)
+{
+  //EVP_MD_CTX_init(&md->ctx);
+  EVP_DigestInit_ex(md->ctx, EVP_MD_CTX_md(md->ctx), NULL);
+}
+
+static void
+lib_md_update(mrb_state *mrb, struct mrb_md *md, unsigned char *str, mrb_int len)
+{
+#if MRB_INT_MAX > SIZE_MAX
+  if (len > SIZE_MAX) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "too long string (not supported yet)");
+  }
+#endif
+  EVP_DigestUpdate(md->ctx, str, len);
+}
+
+static mrb_value
+lib_hmac_digest(mrb_state *mrb, const struct mrb_hmac *hmac)
+{
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined LIBRESSL_VERSION_NUMBER)
+  HMAC_CTX *ctx;
+#else
+  HMAC_CTX ctx;
+#endif
+  unsigned int mdlen;
+  unsigned char mdstr[EVP_MAX_MD_SIZE];
+
+  memcpy(&ctx, &hmac->ctx, sizeof(ctx));
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined LIBRESSL_VERSION_NUMBER)
+  HMAC_Final(ctx, mdstr, &mdlen);
+#else
+  HMAC_Final(&ctx, mdstr, &mdlen);
+#endif
+  return mrb_str_new(mrb, (char *)mdstr, mdlen);
+}
+
+static int
+lib_hmac_block_length(const struct mrb_hmac *hmac)
+{
+  return EVP_MD_block_size(hmac->md);
+}
+
+static int
+lib_hmac_digest_length(const struct mrb_hmac *hmac)
+{
+  return EVP_MD_size(hmac->md);
+}
+
+static void
+lib_hmac_init(mrb_state *mrb, struct mrb_hmac *hmac, int type, const unsigned char *key, mrb_int keylen)
+{
+#if MRB_INT_MAX > INT_MAX
+  if (keylen > INT_MAX) {
+      mrb_raise(mrb, E_ARGUMENT_ERROR, "too long key");
+  }
+#endif
+  hmac->md = md_type_md(type);
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined LIBRESSL_VERSION_NUMBER)
+  hmac->ctx = HMAC_CTX_new();
+  HMAC_Init_ex(hmac->ctx, key, keylen, hmac->md, NULL);
+#else
+  HMAC_CTX_init(&hmac->ctx);
+  HMAC_Init_ex(&hmac->ctx, key, keylen, hmac->md, NULL);
+#endif
+}
+
+static void
+lib_hmac_update(mrb_state *mrb, struct mrb_hmac *hmac, unsigned char *data, mrb_int len)
+{
+#if MRB_INT_MAX > INT_MAX
+  if (len > INT_MAX) {
+      mrb_raise(mrb, E_ARGUMENT_ERROR, "too long string (not supported yet)");
+  }
+#endif
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined LIBRESSL_VERSION_NUMBER)
+  HMAC_Update(hmac->ctx, data, len);
+#else
+  HMAC_Update(&hmac->ctx, data, len);
+#endif
+}
+
+#elif defined(USE_DIGEST_OSX_COMMONCRYPTO)
+/*
+ * Mac OS X CommonCrypto Implementation
+ */
+
+#define HAVE_MD5
+/* #define HAVE_RMD160 */
+#define HAVE_SHA1
+#define HAVE_SHA256
+#define HAVE_SHA384
+#define HAVE_SHA512
+
+struct mrb_md {
+  int type;
+  void *ctx;
+  int ctx_size;
+};
+
+struct mrb_hmac {
+  int type;
+  CCHmacContext ctx;
+};
+
+static int
+md_ctx_size(int type)
+{
+  switch (type) {
+  case MD_TYPE_MD5:	return sizeof(CC_MD5_CTX);
+  case MD_TYPE_SHA1:	return sizeof(CC_SHA1_CTX);
+  case MD_TYPE_SHA256:	return sizeof(CC_SHA256_CTX);
+  case MD_TYPE_SHA384:	return sizeof(CC_SHA512_CTX);	/* ! */
+  case MD_TYPE_SHA512:	return sizeof(CC_SHA512_CTX);
+  default:		return 0;
+  }
+}
+
+static void
+lib_md_free(mrb_state *mrb, void *ptr)
+{
+  struct mrb_md *md = ptr;
+
+  memset(md->ctx, 0, md_ctx_size(md->type));
+  mrb_free(mrb, md->ctx);
+  mrb_free(mrb, md);
+}
+
+static void
+lib_hmac_free(mrb_state *mrb, void *ptr)
+{
+  struct mrb_hmac *hmac = ptr;
+
+  memset(&hmac->ctx, 0, sizeof(hmac->ctx));
+  mrb_free(mrb, hmac);
+}
+
+static struct mrb_data_type mrb_md_type = { "MD", lib_md_free };
+static struct mrb_data_type mrb_hmac_type = { "HMAC", lib_hmac_free };
+
+#define MAX_DIGEST_LENGTH	CC_SHA512_DIGEST_LENGTH
+
+union ctx_union {
+  CC_MD5_CTX md5;
+  CC_SHA1_CTX sha1;
+  CC_SHA256_CTX sha256;
+  /* we don't have CC_SHA384_CTX! */
+  CC_SHA512_CTX sha512;
+};
+
+static void
+lib_init(void)
+{
+}
+
+static int
+md_block_length(int type)
+{
+  switch (type) {
+  case MD_TYPE_MD5:	return CC_MD5_BLOCK_BYTES;
+  case MD_TYPE_SHA1:	return CC_SHA1_BLOCK_BYTES;
+  case MD_TYPE_SHA256:	return CC_SHA256_BLOCK_BYTES;
+  case MD_TYPE_SHA384:	return CC_SHA384_BLOCK_BYTES;
+  case MD_TYPE_SHA512:	return CC_SHA512_BLOCK_BYTES;
+  default:		return 0;
+  }
+}
+
+static int
+lib_md_block_length(const struct mrb_md *md)
+{
+  return md_block_length(md->type);
+}
+
+static void
+md_init(int type, void *ctxp)
+{
+  switch (type) {
+  case MD_TYPE_MD5:	CC_MD5_Init(ctxp);    break;
+  case MD_TYPE_SHA1:	CC_SHA1_Init(ctxp);   break;
+  case MD_TYPE_SHA256:	CC_SHA256_Init(ctxp); break;
+  case MD_TYPE_SHA384:	CC_SHA384_Init(ctxp); break;
+  case MD_TYPE_SHA512:	CC_SHA512_Init(ctxp); break;
+  default:				      break;
+  }
+}
+
+static void
+md_final(int type, unsigned char *str, void *ctx)
+{
+  switch (type) {
+  case MD_TYPE_MD5:	CC_MD5_Final(str, ctx);		break;
+  case MD_TYPE_SHA1:	CC_SHA1_Final(str, ctx);	break;
+  case MD_TYPE_SHA256:	CC_SHA256_Final(str, ctx);	break;
+  case MD_TYPE_SHA384:	CC_SHA384_Final(str, ctx);	break;
+  case MD_TYPE_SHA512:	CC_SHA512_Final(str, ctx);	break;
+  default:						break;
+  }
+}
+
+static int
+md_digest_length(int type)
+{
+  switch (type) {
+  case MD_TYPE_MD5:	return 16;
+  case MD_TYPE_SHA1:	return 20;
+  case MD_TYPE_SHA256:	return 32;
+  case MD_TYPE_SHA384:	return 48;
+  case MD_TYPE_SHA512:	return 64;
+  default:		return 0;
+  }
+}
+
+static mrb_value
+lib_md_digest(mrb_state *mrb, const struct mrb_md *md)
+{
+  union ctx_union ctx;
+  unsigned char mdstr[MAX_DIGEST_LENGTH];
+
+  memcpy(&ctx, md->ctx, md_ctx_size(md->type));
+  md_final(md->type, mdstr, &ctx);
+  return mrb_str_new(mrb, (char *)mdstr, md_digest_length(md->type));
+}
+
+static mrb_value
+lib_md_digest_bang(mrb_state *mrb, struct mrb_md *md)
+{
+  unsigned char mdstr[MAX_DIGEST_LENGTH];
+
+  md_final(md->type, mdstr, md->ctx);
+  md_init(md->type, md->ctx);
+  return mrb_str_new(mrb, (char *)mdstr, md_digest_length(md->type));
+}
+
+static int
+lib_md_digest_length(const struct mrb_md *md)
+{
+  return md_digest_length(md->type);
+}
+
+static void
+lib_md_init(mrb_state *mrb, struct mrb_md *md, int type)
+{
+  int ctxsize;
+
+  ctxsize = md_ctx_size(type);
+  if (ctxsize == 0) {
+    mrb_raise(mrb, E_NOTIMP_ERROR, "not supported");
+  }
+  md->type = type;
+  md->ctx = NULL;
+  md->ctx = mrb_malloc(mrb, ctxsize);
+  md_init(type, md->ctx);
+}
+
+static void
+lib_md_init_copy(mrb_state *mrb, struct mrb_md *mdnew, struct mrb_md *mdold)
+{
+  lib_md_init(mrb, mdnew, mdold->type);
+}
+
+static void
+lib_md_reset(mrb_state *mrb, struct mrb_md *md)
+{
+  md_init(md->type, md->ctx);
+}
+
+static void
+lib_md_update(mrb_state *mrb, struct mrb_md *md, unsigned char *data, mrb_int len)
+{
+  if (sizeof(len) > sizeof(CC_LONG)) {
+    if (len != (CC_LONG)len) {
+      mrb_raise(mrb, E_ARGUMENT_ERROR, "too long string (not supported yet)");
+    }
+  }
+  switch (md->type) {
+  case MD_TYPE_MD5:	CC_MD5_Update(md->ctx, data, len);	break;
+  case MD_TYPE_SHA1:	CC_SHA1_Update(md->ctx, data, len);	break;
+  case MD_TYPE_SHA256:	CC_SHA256_Update(md->ctx, data, len);	break;
+  case MD_TYPE_SHA384:	CC_SHA384_Update(md->ctx, data, len);	break;
+  case MD_TYPE_SHA512:	CC_SHA512_Update(md->ctx, data, len);	break;
+  default: break;
+  }
+}
+
+static int
+lib_hmac_block_length(const struct mrb_hmac *hmac)
+{
+  return md_block_length(hmac->type);
+}
+
+static mrb_value
+lib_hmac_digest(mrb_state *mrb, const struct mrb_hmac *hmac)
+{
+  CCHmacContext ctx;
+  unsigned char str[MAX_DIGEST_LENGTH];
+
+  memcpy(&ctx, &hmac->ctx, sizeof(ctx));
+  CCHmacFinal(&ctx, str);
+  return mrb_str_new(mrb, (const char *)str, md_digest_length(hmac->type));
+}
+
+static int
+lib_hmac_digest_length(const struct mrb_hmac *hmac)
+{
+  return md_digest_length(hmac->type);
+}
+
+static void
+lib_hmac_init(mrb_state *mrb, struct mrb_hmac *hmac, int type, const unsigned char *key, mrb_int keylen)
+{
+  CCHmacAlgorithm algorithm;
+
+#if MRB_INT_MAX > SIZE_MAX
+  if (len > SIZE_MAX) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "too long key");
+  }
+#endif
+  switch (type) {
+  case MD_TYPE_MD5:    algorithm = kCCHmacAlgMD5;    break;
+  case MD_TYPE_SHA1:   algorithm = kCCHmacAlgSHA1;   break;
+  case MD_TYPE_SHA256: algorithm = kCCHmacAlgSHA256; break;
+  case MD_TYPE_SHA384: algorithm = kCCHmacAlgSHA384; break;
+  case MD_TYPE_SHA512: algorithm = kCCHmacAlgSHA512; break;
+  default:
+    mrb_raisef(mrb, E_RUNTIME_ERROR, "mruby-digest: internal error: unexpected HMAC type: %S", mrb_fixnum_value(type));
+    algorithm = 0;
+    break;
+  }
+  hmac->type = type;
+  CCHmacInit(&hmac->ctx, algorithm, key, keylen);
+}
+
+static void
+lib_hmac_update(mrb_state *mrb, struct mrb_hmac *hmac, unsigned char *data, mrb_int len)
+{
+#if MRB_INT_MAX > SIZE_MAX
+  if (len > SIZE_MAX) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "too long string");
+  }
+#endif
+  CCHmacUpdate(&hmac->ctx, data, len);
+}
+
+#endif
+
+static void
+basecheck(mrb_state *mrb, mrb_value self, struct mrb_md **mdp)
+{
+  struct RClass *c;
+  struct mrb_md *md;
+  mrb_value t;
+
+  c = mrb_obj_class(mrb, self);
+  t = mrb_const_get(mrb, mrb_obj_value(c), mrb_intern_lit(mrb, TYPESYM));
+  if (mrb_nil_p(t)) {
+    mrb_raise(mrb, E_NOTIMP_ERROR, "Digest::Base is an abstract class");
+  }
+  md = (struct mrb_md *)DATA_PTR(self);
+  if (!md) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "no md found (BUG?)");
+  }
+  if (mdp) *mdp = md;
+}
+
+static mrb_value
+mrb_digest_block_length(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_md *md;
+
+  basecheck(mrb, self, &md);
+  return mrb_fixnum_value(lib_md_block_length(md));
+}
+
+static mrb_value
+mrb_digest_digest(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_md *md;
+
+  md = (struct mrb_md *)DATA_PTR(self);
+  if (!md) return mrb_nil_value();
+  return lib_md_digest(mrb, md);
+}
+
+static mrb_value
+mrb_digest_digest_bang(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_md *md;
+
+  md = (struct mrb_md *)DATA_PTR(self);
+  if (!md) return mrb_nil_value();
+  return lib_md_digest_bang(mrb, md);
+}
+
+static mrb_value
+mrb_digest_digest_length(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_md *md;
+
+  basecheck(mrb, self, &md);
+  return mrb_fixnum_value(lib_md_digest_length(md));
+}
+
+static mrb_value
+digest2hexdigest(mrb_state *mrb, mrb_value b)
+{
+  mrb_value h;
+  int i, len;
+  char *bp, buf[3];
+
+  bp = RSTRING_PTR(b);
+  len = RSTRING_LEN(b);
+  h = mrb_str_buf_new(mrb, len * 2);
+  for (i = 0; i < len; i++) {
+    snprintf(buf, sizeof(buf), "%02x", (unsigned char )bp[i]);
+    mrb_str_buf_cat(mrb, h, buf, 2);
+  }
+  return h;
+}
+
+static mrb_value
+mrb_digest_hexdigest(mrb_state *mrb, mrb_value self)
+{
+  return digest2hexdigest(mrb, mrb_digest_digest(mrb, self));
+}
+
+static mrb_value
+mrb_digest_init(mrb_state *mrb, mrb_value self)
+{
+  struct RClass *c;
+  struct mrb_md *md;
+  mrb_value t;
+
+  md = (struct mrb_md *)DATA_PTR(self);
+  if (md) {
+    lib_md_free(mrb, md);
+  }
+  DATA_TYPE(self) = &mrb_md_type;
+  DATA_PTR(self) = NULL;
+
+  c = mrb_obj_class(mrb, self);
+  if (!mrb_const_defined(mrb, mrb_obj_value(c), mrb_intern_lit(mrb, TYPESYM))) {
+    mrb_raise(mrb, E_NOTIMP_ERROR, "Digest::Base is an abstract class");
+  }
+  t = mrb_const_get(mrb, mrb_obj_value(c), mrb_intern_lit(mrb, TYPESYM));
+#if 0
+  if (lib_md_supported(t)) {
+    mrb_raise(mrb, E_NOTIMP_ERROR, "unknown algorithm");
+  }
+#endif
+
+  md = (struct mrb_md *)mrb_malloc(mrb, sizeof(*md));
+  DATA_PTR(self) = md;
+  lib_md_init(mrb, md, mrb_fixnum(t));
+  return self;
+}
+
+static mrb_value
+mrb_digest_init_copy(mrb_state *mrb, mrb_value copy)
+{
+  struct mrb_md *m1, *m2;
+  mrb_value src;
+
+  mrb_get_args(mrb, "o", &src);
+  if (mrb_obj_equal(mrb, copy, src)) return copy;
+  if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) {
+    mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class");
+  }
+  if (!DATA_PTR(copy)) {
+    DATA_PTR(copy) = mrb_malloc(mrb, sizeof(struct mrb_md));
+    DATA_TYPE(copy) = &mrb_md_type;
+  }
+  m1 = DATA_PTR(src);
+  m2 = DATA_PTR(copy);
+  lib_md_init_copy(mrb, m2, m1);
+  return copy;
+}
+
+static mrb_value
+mrb_digest_reset(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_md *md;
+
+  md = (struct mrb_md *)DATA_PTR(self);
+  if (!md) return mrb_nil_value();
+  lib_md_reset(mrb, md);
+  return self;
+}
+
+static mrb_value
+mrb_digest_update(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_md *md;
+  mrb_int len;
+  char *str;
+
+  md = (struct mrb_md *)DATA_PTR(self);
+  if (!md) return mrb_nil_value();
+  mrb_get_args(mrb, "s", &str, &len);
+  lib_md_update(mrb, md, (unsigned char *)str, len);
+  return self;
+}
+
+static mrb_value
+mrb_hmac_block_length(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_hmac *hmac;
+
+  hmac = (struct mrb_hmac *)DATA_PTR(self);
+  if (!hmac) return mrb_nil_value();
+  return mrb_fixnum_value(lib_hmac_block_length(hmac));
+}
+
+static mrb_value
+mrb_hmac_digest(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_hmac *hmac;
+
+  hmac = (struct mrb_hmac *)DATA_PTR(self);
+  if (!hmac) return mrb_nil_value();
+  return lib_hmac_digest(mrb, hmac);
+}
+
+static mrb_value
+mrb_hmac_digest_length(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_hmac *hmac;
+
+  hmac = (struct mrb_hmac *)DATA_PTR(self);
+  if (!hmac) return mrb_nil_value();
+  return mrb_fixnum_value(lib_hmac_digest_length(hmac));
+}
+
+static mrb_value
+mrb_hmac_hexdigest(mrb_state *mrb, mrb_value self)
+{
+  return digest2hexdigest(mrb, mrb_hmac_digest(mrb, self));
+}
+
+static mrb_value
+mrb_hmac_init(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_hmac *hmac;
+  mrb_value digest, t;
+  mrb_int keylen;
+  char *key;
+
+  hmac = (struct mrb_hmac *)DATA_PTR(self);
+  if (hmac) {
+    lib_hmac_free(mrb, hmac);
+  }
+  DATA_TYPE(self) = &mrb_hmac_type;
+  DATA_PTR(self) = NULL;
+
+  mrb_get_args(mrb, "so", &key, &keylen, &digest);
+  t = mrb_const_get(mrb, digest, mrb_intern_lit(mrb, TYPESYM));
+  if (mrb_nil_p(t)) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "not a digester");
+  }
+
+  hmac = (struct mrb_hmac *)mrb_malloc(mrb, sizeof(*hmac));
+  DATA_PTR(self) = hmac;
+  lib_hmac_init(mrb, hmac, mrb_fixnum(t), (unsigned char *)key, keylen);
+  return self;
+}
+
+static mrb_value
+mrb_hmac_init_copy(mrb_state *mrb, mrb_value copy)
+{
+  mrb_raise(mrb, E_RUNTIME_ERROR, "cannot duplicate HMAC");
+  return copy;
+}
+
+static mrb_value
+mrb_hmac_update(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_hmac *hmac;
+  mrb_int len;
+  char *str;
+
+  hmac = (struct mrb_hmac *)DATA_PTR(self);
+  if (!hmac) return mrb_nil_value();
+  mrb_get_args(mrb, "s", &str, &len);
+  lib_hmac_update(mrb, hmac, (unsigned char *)str, len);
+  return self;
+}
+
+
+void
+mrb_mruby_digest_gem_init(mrb_state *mrb)
+{
+  struct RClass *b, *d, *h;
+
+  lib_init();
+
+  d = mrb_define_module(mrb, "Digest");
+
+  b = mrb_define_class_under(mrb, d, "Base", mrb->object_class);
+  mrb_define_method(mrb, b, "block_length",    mrb_digest_block_length,  MRB_ARGS_NONE());
+  mrb_define_method(mrb, b, "digest",          mrb_digest_digest,        MRB_ARGS_NONE());
+  mrb_define_method(mrb, b, "digest!",         mrb_digest_digest_bang,   MRB_ARGS_NONE()); /* XXX: can be defined in mrblib... */
+  mrb_define_method(mrb, b, "digest_length",   mrb_digest_digest_length, MRB_ARGS_NONE());
+  //mrb_define_method(mrb, b, "file",            mrb_digest_file,          MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, b, "hexdigest",       mrb_digest_hexdigest,     MRB_ARGS_NONE());
+  //mrb_define_method(mrb, b, "hexdigest!",      mrb_digest_hexdigest_bang, MRB_ARGS_NONE()); /* XXX: can be defined in mrblib... */
+  mrb_define_method(mrb, b, "initialize",      mrb_digest_init,          MRB_ARGS_NONE());
+  mrb_define_method(mrb, b, "initialize_copy", mrb_digest_init_copy,     MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, b, "reset",           mrb_digest_reset,         MRB_ARGS_NONE());
+  mrb_define_method(mrb, b, "update",          mrb_digest_update,        MRB_ARGS_REQ(1));
+
+#define DEFCLASS(n)						\
+do {								\
+  struct RClass *a = mrb_define_class_under(mrb, d, #n, b);	\
+  MRB_SET_INSTANCE_TT(a, MRB_TT_DATA);				\
+  mrb_define_const(mrb, a, TYPESYM, mrb_fixnum_value(MD_TYPE_##n));	\
+} while (0)
+
+#ifdef HAVE_MD5
+  DEFCLASS(MD5);
+#endif
+#ifdef HAVE_RMD160
+  DEFCLASS(RMD160);
+#endif
+#ifdef HAVE_SHA1
+  DEFCLASS(SHA1);
+#endif
+#ifdef HAVE_SHA256
+  DEFCLASS(SHA256);
+#endif
+#ifdef HAVE_SHA384
+  DEFCLASS(SHA384);
+#endif
+#ifdef HAVE_SHA512
+  DEFCLASS(SHA512);
+#endif
+
+  h = mrb_define_class_under(mrb, d, "HMAC", mrb->object_class);
+  MRB_SET_INSTANCE_TT(h, MRB_TT_DATA);
+  mrb_define_method(mrb, h, "block_length",    mrb_hmac_block_length,  MRB_ARGS_NONE());
+  mrb_define_method(mrb, h, "digest",          mrb_hmac_digest,        MRB_ARGS_NONE());
+  mrb_define_method(mrb, h, "digest_length",   mrb_hmac_digest_length, MRB_ARGS_NONE());
+  mrb_define_method(mrb, h, "hexdigest",       mrb_hmac_hexdigest,     MRB_ARGS_NONE());
+  mrb_define_method(mrb, h, "initialize",      mrb_hmac_init,          MRB_ARGS_REQ(2));
+  mrb_define_method(mrb, h, "initialize_copy", mrb_hmac_init_copy,     MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, h, "update",          mrb_hmac_update,        MRB_ARGS_REQ(1));
+}
+
+void
+mrb_mruby_digest_gem_final(mrb_state *mrb)
+{
+}
Index: EcnlProtoTool/trunk/mrbgems/mruby-digest/test/digest.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-digest/test/digest.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-digest/test/digest.rb	(revision 331)
@@ -0,0 +1,203 @@
+##
+# Digest Test
+
+if Object.const_defined?(:Digest)
+  assert('Digest') do
+    Digest.class == Module
+  end
+
+  assert('Digest::Base') do
+    Digest::Base.class == Class
+  end
+
+  assert('Digest::Base#new') do
+    e1 = nil
+    begin
+      Digest::Base.new
+    rescue NotImplementedError => e
+      e1 = e
+    end
+    e1.class == NotImplementedError
+  end
+
+  assert('Digest::MD5') do
+    Digest::MD5.class == Class
+  end
+
+  assert('Digest::MD5 superclass') do
+    Digest::MD5.superclass == Digest::Base
+  end
+
+  assert('Digest::MD5.digest') do
+    Digest::MD5.digest('ruby') == "X\xE5=\x13$\xEE\xF6&_\xDB\x97\xB0\x8E\xD9\xAA\xDF"
+  end
+
+  #assert('Digest::MD5.file')
+
+  assert('Digest::MD5.hexdigest') do
+    Digest::MD5.hexdigest('ruby') == "58e53d1324eef6265fdb97b08ed9aadf"
+  end
+
+  assert('Digest::MD5#update') do
+    d = Digest::MD5.new
+    d.update('ruby')
+    d.hexdigest == "58e53d1324eef6265fdb97b08ed9aadf"
+  end
+
+  assert('Digest::MD5#update 2') do
+    d = Digest::MD5.new
+    d.update('ruby')
+    d.update('digest')
+    d.hexdigest == "2ac1b3e3db06239e3244817f281450f1"
+  end
+
+  assert('Digest::MD5#<<') do
+    a = Digest::MD5.new
+    b = Digest::MD5.new
+    a.update('ruby')
+    b << "r" << "u" << "b" << "y"
+    a.hexdigest == b.hexdigest
+  end
+
+  assert('Digest::MD5#== with Digest::XXX') do
+    x1 = Digest::MD5.new.update("ruby")
+    x2 = Digest::MD5.new.update("ruby")
+    x3 = Digest::MD5.new.update("RUBY")
+    (x1 == x2) == true and
+    (x1 == x3) == false
+  end
+
+  assert('Digest::MD5#== with String') do
+    Digest::MD5.new.update("ruby") == "58e53d1324eef6265fdb97b08ed9aadf"
+  end
+
+  assert('Digest::MD5#block_length') do
+    Digest::MD5.new.block_length == 64
+  end
+
+  assert('Digest::MD5#digest') do
+    Digest::MD5.new.update("ruby").digest == "X\xE5=\x13$\xEE\xF6&_\xDB\x97\xB0\x8E\xD9\xAA\xDF"
+  end
+
+  assert('Digest::MD5#digest!') do
+    d = Digest::MD5.new.update("ruby")
+    d.digest!
+    #d.digest! == "\xD4\x1D\x8C\xD9\x8F\x00\xB2\x04\xE9\x80\t\x98\xEC\xF8B~"
+    # XXX: mrbtest dumps core!
+    d.digest! == Digest::MD5.new.digest
+  end
+
+  assert('Digest::MD5#digest_length') do
+    d = Digest::MD5.new
+    n = 16
+    d.digest_length == n and
+    d.length == n and
+    d.size == n
+  end
+
+  #assert('Digest::MD5#file')
+
+  assert('Digest::MD5#hexdigest') do
+    d = Digest::MD5.new.update("ruby")
+    s = "58e53d1324eef6265fdb97b08ed9aadf"
+    d.hexdigest == s and
+    d.to_s == s
+  end
+
+  assert('Digest::MD5#hexdigest!') do
+    d = Digest::MD5.new.update("ruby")
+    d.hexdigest!
+    d.hexdigest! == "d41d8cd98f00b204e9800998ecf8427e"
+  end
+
+  assert('Digest::MD5#reset') do
+    d = Digest::MD5.new.update("ruby")
+    d.reset
+    d.hexdigest! == "d41d8cd98f00b204e9800998ecf8427e"
+  end
+
+  if Digest.const_defined? :RMD160
+    assert('Digest::RMD160#hexdigest') do
+      d = Digest::RMD160.new.update("ruby")
+      s = "29d9b710bc50866fa2399c3061cd02c0c8ffa197"
+      d.hexdigest == s
+    end
+  end
+
+  if Digest.const_defined? :SHA1
+    assert('Digest::SHA1#hexdigest') do
+      d = Digest::SHA1.new.update("ruby")
+      s = "18e40e1401eef67e1ae69efab09afb71f87ffb81"
+      d.hexdigest == s
+    end
+  end
+
+  if Digest.const_defined? :SHA256
+    assert('Digest::SHA256#hexdigest') do
+      d = Digest::SHA256.new.update("ruby")
+      s = "b9138194ffe9e7c8bb6d79d1ed56259553d18d9cb60b66e3ba5aa2e5b078055a"
+      d.hexdigest == s
+    end
+  end
+
+  if Digest.const_defined? :SHA384
+    assert('Digest::SHA384#hexdigest') do
+      d = Digest::SHA384.new.update("ruby")
+      s = "635365ef93ebf2c7a4e40b0b497da727ab8c2914eb9f052e6be40476f95d3daf44786790f5f0e843fab419b43022e069"
+      d.hexdigest == s
+    end
+  end
+
+  if Digest.const_defined? :SHA512
+    assert('Digest::SHA512#hexdigest') do
+      d = Digest::SHA512.new.update("ruby")
+      s = "423408d7723a3d80baefa804bd50b61a89667efec1713386a7b8efe28e5d13968307a908778cad210d7aa2dfe7db9a2aa86895f9fc1eeefcc99814310b207a6b"
+      d.hexdigest == s
+    end
+  end
+
+  assert('Digest::HMAC') do
+    Digest::HMAC.class == Class
+  end
+
+  assert('Digest::HMAC.digest') do
+    Digest::HMAC.digest("data", "hash key", Digest::SHA1) == "\xFD \xECC=\xFD\x97\x0E\xEC!FW\xCF\xB5Gl]\x913f"
+  end
+
+  assert('Digest::HMAC.hexdigest') do
+    Digest::HMAC.hexdigest("data", "hash key", Digest::SHA1) == "fd20ec433dfd970eec214657cfb5476c5d913366"
+  end
+
+  assert('Digest::HMAC#<<') do
+    a = Digest::HMAC.new('hash key', Digest::SHA1)
+    b = Digest::HMAC.new('hash key', Digest::SHA1)
+    a.update('ruby')
+    b << "r" << "u" << "b" << "y"
+    a.hexdigest == b.hexdigest
+  end
+
+  assert('Digest::HMAC#block_length') do
+    d = Digest::HMAC.new("hash key", Digest::SHA1)
+    d.block_length == 64
+  end
+
+  assert('Digest::HMAC#digest_length') do
+    d = Digest::HMAC.new("hash key", Digest::SHA1)
+    d.digest_length == 20
+  end
+
+  # assert('Digest::HMAC#reset')
+
+  assert('Digest::HMAC#update') do
+    d = Digest::HMAC.new("hash key", Digest::SHA1)
+    d.update('data')
+    d.hexdigest == "fd20ec433dfd970eec214657cfb5476c5d913366"
+  end
+
+  assert('Digest::HMAC#update 2') do
+    d = Digest::HMAC.new("hash key", Digest::SHA1)
+    d.update('ruby')
+    d.update('digest')
+    d.hexdigest == "e4be3728777e43deba3aa522a4247ea83b19a1c7"
+  end
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-dir/.gitignore
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-dir/.gitignore	(revision 321)
+++ EcnlProtoTool/trunk/mrbgems/mruby-dir/.gitignore	(revision 331)
Index: EcnlProtoTool/trunk/mrbgems/mruby-dir/.travis.yml
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-dir/.travis.yml	(revision 321)
+++ EcnlProtoTool/trunk/mrbgems/mruby-dir/.travis.yml	(revision 331)
Index: EcnlProtoTool/trunk/mrbgems/mruby-dir/README.md
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-dir/README.md	(revision 321)
+++ EcnlProtoTool/trunk/mrbgems/mruby-dir/README.md	(revision 331)
Index: EcnlProtoTool/trunk/mrbgems/mruby-dir/src/dir.c
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-dir/src/dir.c	(revision 321)
+++ EcnlProtoTool/trunk/mrbgems/mruby-dir/src/dir.c	(revision 331)
@@ -11,5 +11,5 @@
 #include "error.h"
 #include <sys/types.h>
-#if (defined(_WIN32) || defined(_WIN64)) && !defined(MUSL_LIBC)
+#if defined(_WIN32) || defined(_WIN64)
   #define MAXPATHLEN 1024
  #if !defined(PATH_MAX)
@@ -23,8 +23,4 @@
   #define mkdir _mkdir
   #define chdir _chdir
-#elif defined(__NEWLIB__)
-  #include <sys/param.h>
-  #include "_dirent.h"
-  #include <unistd.h>
 #else
   #include <sys/param.h>
@@ -161,5 +157,5 @@
   mrb_get_args(mrb, "S|i", &spath, &mode);
   path = mrb_str_to_cstr(mrb, spath);
-#if (!defined(_WIN32) && !defined(_WIN64)) || defined(MUSL_LIBC)
+#ifndef _WIN32
   if (mkdir(path, mode) == -1) {
 #else
Index: EcnlProtoTool/trunk/mrbgems/mruby-env/.gitignore
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-env/.gitignore	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-env/.gitignore	(revision 331)
@@ -0,0 +1,1 @@
+/tmp
Index: EcnlProtoTool/trunk/mrbgems/mruby-env/.travis.yml
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-env/.travis.yml	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-env/.travis.yml	(revision 331)
@@ -0,0 +1,2 @@
+script:
+  - "ruby run_test.rb all test"
Index: EcnlProtoTool/trunk/mrbgems/mruby-env/README.md
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-env/README.md	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-env/README.md	(revision 331)
@@ -0,0 +1,52 @@
+mruby-env
+=========
+
+mruby-env provides "ENV" object, which is a hash-like accessor
+for environment variables.
+
+### Methods
+
+```
+[] []= clear delete has_key? include? inspect key? keys
+member? size store to_a to_hash to_s values
+```
+
+
+### To build:
+
+Prerequisites:
+
+    * mruby
+    * libc
+
+    activate GEMs in *build_config.rb*
+    * conf.gem :github => 'iij/mruby-env'
+    ruby ./minirake
+
+### To run the tests:
+
+    ruby ./minirake test
+
+
+## License
+
+Copyright (c) 2012 Internet Initiative Japan Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a 
+copy of this software and associated documentation files (the "Software"), 
+to deal in the Software without restriction, including without limitation 
+the rights to use, copy, modify, merge, publish, distribute, sublicense, 
+and/or sell copies of the Software, and to permit persons to whom the 
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in 
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+DEALINGS IN THE SOFTWARE.
+
Index: EcnlProtoTool/trunk/mrbgems/mruby-env/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-env/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-env/mrbgem.rake	(revision 331)
@@ -0,0 +1,4 @@
+MRuby::Gem::Specification.new('mruby-env') do |spec|
+  spec.license = 'MIT'
+  spec.authors = 'Internet Initiative Japan Inc.'
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-env/mrblib/env.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-env/mrblib/env.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-env/mrblib/env.rb	(revision 331)
@@ -0,0 +1,30 @@
+class << ENV
+  NONE = Object.new
+
+  alias include? has_key?
+  alias key? has_key?
+  alias member? has_key?
+
+  def clear
+    self.keys.each { |k| self.delete(k) }
+    self
+  end
+
+  def delete(key)
+    old = self[key]
+    self[key] = nil
+    old
+  end
+
+  def fetch(key, default = NONE, &block)
+    if key?(key)
+      self[key]
+    elsif block
+      block.call(key)
+    elsif default != NONE
+      default
+    else
+      raise KeyError, "key not found: #{key}"
+    end
+  end
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-env/run_test.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-env/run_test.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-env/run_test.rb	(revision 331)
@@ -0,0 +1,27 @@
+#!/usr/bin/env ruby
+#
+# mrbgems test runner
+#
+
+if __FILE__ == $0
+  repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby'
+  build_args = ARGV
+
+  Dir.mkdir 'tmp'  unless File.exist?('tmp')
+  unless File.exist?(dir)
+    system "git clone #{repository} #{dir}"
+  end
+
+  exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}])
+end
+
+MRuby::Build.new do |conf|
+  toolchain :gcc
+  conf.gembox 'default'
+
+  conf.gem :core => 'mruby-time'
+  conf.gem :github => 'iij/mruby-io'
+  conf.gem :github => 'iij/mruby-mtest'
+
+  conf.gem File.expand_path(File.dirname(__FILE__))
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-env/src/env.c
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-env/src/env.c	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-env/src/env.c	(revision 331)
@@ -0,0 +1,243 @@
+/*
+** env.c - ENV is a Hash-like accessor for environment variables.
+**
+*/
+
+#include "mruby.h"
+#include "mruby/hash.h"
+#include "mruby/khash.h"
+#include "mruby/class.h"
+#include "mruby/array.h"
+#include "mruby/string.h"
+#include "mruby/variable.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef _WIN32
+int
+unsetenv(const char* name)
+{
+  int r;
+  char* p = malloc(strlen(name) + 2);
+  if (!p) return -1;
+  strcpy(p, name);
+  strcat(p, "=");
+  r = _putenv(p);
+  free(p);
+  return r;
+}
+
+int
+setenv(const char* name, const char* value, int overwrite)
+{
+  int r;
+  char* p = malloc(strlen(name) + strlen(value) + 2);
+  if (!p) return -1;
+  strcpy(p, name);
+  strcat(p, "=");
+  strcat(p, value);
+  r = _putenv(p);
+  free(p);
+  return r;
+}
+#define environ _environ
+#else
+extern char **environ;
+#endif
+
+
+mrb_value
+mrb_env_aget(mrb_state *mrb, mrb_value self)
+{
+  mrb_value key;
+  const char *cname, *cvalue;
+
+  mrb_get_args(mrb, "S", &key);
+  cname = mrb_string_value_cstr(mrb, &key);
+  cvalue = getenv(cname);
+  if (cvalue != NULL) {
+    return mrb_str_new_cstr(mrb, cvalue);
+  } else {
+    return mrb_nil_value();
+  }
+}
+
+mrb_value
+mrb_env_has_key(mrb_state *mrb, mrb_value self)
+{
+  mrb_value name;
+  const char *key;
+  mrb_get_args(mrb, "S", &name);
+  key = mrb_str_to_cstr(mrb, name);
+  if (getenv(key) != NULL) {
+    return mrb_true_value();
+  } else { 
+    return mrb_false_value();
+  }
+}
+
+mrb_value
+mrb_env_keys(mrb_state *mrb, mrb_value self)
+{
+  int i;
+  mrb_value ary;
+
+  ary = mrb_ary_new(mrb);
+  for (i = 0; environ[i] != NULL; i++) {
+    char *str = strchr(environ[i], '=');
+    if (str != NULL) {
+      int len = str - environ[i];
+      mrb_ary_push(mrb, ary, mrb_str_new(mrb, environ[i], len));
+    }
+  }
+
+  return ary;
+}
+
+mrb_value
+mrb_env_values(mrb_state *mrb, mrb_value self)
+{
+  int i;
+  mrb_value ary;
+
+  ary = mrb_ary_new(mrb);
+  for (i = 0; environ[i] != NULL; i++) {
+    char *str = strchr(environ[i], '=');
+    if (str) {
+      int len;
+      str++;
+      len = strlen(str);
+      mrb_ary_push(mrb, ary, mrb_str_new(mrb, str, len));
+    }
+  }
+
+  return ary;
+}
+
+static mrb_value
+mrb_env_size(mrb_state *mrb, mrb_value self)
+{
+  int i;
+
+  for (i = 0; environ[i] != NULL; i++)
+    ;
+
+  return mrb_fixnum_value(i);
+}
+
+static mrb_value
+mrb_env_to_hash(mrb_state *mrb, mrb_value self)
+{
+  int i;
+  mrb_value hash;
+
+  hash = mrb_hash_new(mrb);
+  for (i = 0; environ[i] != NULL; i++) {
+    char *str = strchr(environ[i], '=');
+    if (str != NULL) {
+      mrb_value val;
+      int ai = mrb_gc_arena_save(mrb);
+      int len = str - environ[i];
+      mrb_value key = mrb_str_new(mrb, environ[i], len);
+      str++;
+      val = mrb_str_new(mrb, str, strlen(str));
+      mrb_hash_set(mrb, hash, key, val);
+      mrb_gc_arena_restore(mrb, ai);
+    }
+  }
+
+  return hash;
+}
+
+static mrb_value
+mrb_env_to_a(mrb_state *mrb, mrb_value self)
+{
+  int i;
+  mrb_value ary;
+
+  ary = mrb_ary_new(mrb);
+  for (i = 0; environ[i] != NULL; i++) {
+    char *str = strchr(environ[i], '=');
+    if (str != NULL) {
+      int ai = mrb_gc_arena_save(mrb);
+      mrb_value elem = mrb_ary_new(mrb);
+      int len = str - environ[i];
+      mrb_ary_push(mrb, elem, mrb_str_new(mrb, environ[i], len));
+      str++;
+      mrb_ary_push(mrb, elem, mrb_str_new(mrb, str, strlen(str)));
+      mrb_ary_push(mrb, ary, elem);
+      mrb_gc_arena_restore(mrb, ai);
+    }
+  }
+
+  return ary;
+}
+
+static mrb_value
+mrb_env_inspect(mrb_state *mrb, mrb_value self)
+{
+  mrb_value hash = mrb_env_to_hash(mrb, self);
+  return mrb_funcall(mrb, hash, "inspect", 0);
+}
+
+static mrb_value
+mrb_env_to_s(mrb_state *mrb, mrb_value self)
+{
+  return mrb_str_new_cstr(mrb, "ENV");
+}
+
+static mrb_value
+mrb_env_aset(mrb_state *mrb, mrb_value self)
+{
+  mrb_value name, value;
+  const char *cname, *cvalue;
+
+  mrb_get_args(mrb, "So", &name, &value);
+  cname = mrb_string_value_cstr(mrb, &name);
+
+  if (mrb_nil_p(value)) {
+    if (unsetenv(cname) != 0) {
+      mrb_raise(mrb, E_RUNTIME_ERROR, "can't delete environment variable");
+    }
+  } else {
+    mrb_convert_type(mrb, value, MRB_TT_STRING, "String", "to_str");
+    cvalue = mrb_string_value_cstr(mrb, &value);
+    if (setenv(cname, cvalue, 1) != 0) {
+      mrb_raise(mrb, E_RUNTIME_ERROR, "can't change environment variable");
+    }
+  }
+  return value;
+}
+
+void
+mrb_mruby_env_gem_init(mrb_state *mrb)
+{
+  struct RObject *e;
+
+  e = (struct RObject*) mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class);
+#if defined(MRUBY_RELEASE_NO) && MRUBY_RELEASE_NO >= 10000
+  mrb_include_module(mrb, (struct RClass*)e, mrb_module_get(mrb, "Enumerable"));
+#else
+  mrb_include_module(mrb, (struct RClass*)e, mrb_class_get(mrb, "Enumerable"));
+#endif
+
+  mrb_define_singleton_method(mrb, e,"[]",       mrb_env_aget,       MRB_ARGS_REQ(1));
+  mrb_define_singleton_method(mrb, e,"[]=",      mrb_env_aset,       MRB_ARGS_REQ(2));
+  mrb_define_singleton_method(mrb, e,"has_key?", mrb_env_has_key,    MRB_ARGS_REQ(1));
+  mrb_define_singleton_method(mrb, e,"inspect",  mrb_env_inspect,    MRB_ARGS_NONE());
+  mrb_define_singleton_method(mrb, e,"keys",     mrb_env_keys,       MRB_ARGS_NONE());
+  mrb_define_singleton_method(mrb, e,"size",     mrb_env_size,       MRB_ARGS_NONE());
+  mrb_define_singleton_method(mrb, e,"store",    mrb_env_aset,       MRB_ARGS_REQ(2));
+  mrb_define_singleton_method(mrb, e,"to_a",     mrb_env_to_a,       MRB_ARGS_NONE());
+  mrb_define_singleton_method(mrb, e,"to_hash",  mrb_env_to_hash,    MRB_ARGS_NONE());
+  mrb_define_singleton_method(mrb, e,"to_s",     mrb_env_to_s,       MRB_ARGS_NONE());
+  mrb_define_singleton_method(mrb, e,"values",   mrb_env_values,     MRB_ARGS_NONE());
+
+  mrb_define_global_const(mrb, "ENV", mrb_obj_value(e));
+}
+
+void
+mrb_mruby_env_gem_final(mrb_state *mrb)
+{
+}
Index: EcnlProtoTool/trunk/mrbgems/mruby-env/test/env_test.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-env/test/env_test.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-env/test/env_test.rb	(revision 331)
@@ -0,0 +1,131 @@
+##
+# ENV test
+#
+
+if Object.const_defined?(:MTest)
+  class ENVTest < MTest::Unit::TestCase
+    def test_env_class
+      assert_equal(Object, ENV.class)
+    end
+
+    def setup
+      @env_hash = ENV.to_hash
+      ENV.clear
+    end
+
+    def teardown
+      ENV.clear
+      @env_hash.each do |k, v|
+        ENV[k] = v
+      end
+    end
+
+    def set_dummy_env
+      ENV['FOO'] = 'bar'
+    end
+
+    def test_size_empty
+      assert_equal(0, ENV.size)
+    end
+
+    def test_keys_empty
+      assert_empty(ENV.keys)
+    end
+
+    def test_values_empty
+      assert_empty(ENV.values)
+    end
+
+    def test_env_to_s_empty
+      assert_equal("ENV", ENV.to_s)
+    end
+
+    def test_env_inspect_empty
+      assert_equal("{}", ENV.inspect)
+    end
+
+    def test_env_to_hash_empty
+      assert_equal({}, ENV.to_hash)
+    end
+
+    def test_env_get_val
+      set_dummy_env
+      assert_equal('bar', ENV['FOO'])
+    end
+
+    def test_env_keys
+      set_dummy_env
+      assert_equal(['FOO'], ENV.keys)
+    end
+
+    def test_env_values
+      set_dummy_env
+      assert_equal(['bar'], ENV.values)
+    end
+
+    def test_env_to_s
+      set_dummy_env
+      assert_equal("ENV", ENV.to_s)
+    end
+
+    def test_env_has_key
+      set_dummy_env
+      assert_true  ENV.has_key?("FOO")
+      assert_false ENV.has_key?("BAR")
+    end
+
+    def test_env_inspect
+      set_dummy_env
+      assert_equal("{\"FOO\"=>\"bar\"}", ENV.inspect)
+    end
+
+    def test_env_delete
+      set_dummy_env
+      old = ENV['FOO']
+      ret = ENV.delete('FOO')
+      assert_equal(0, ENV.size)
+      assert_equal(old, ret)
+      assert_equal(nil, ENV.delete('nosuchenv'))
+    end
+
+    def test_env_fetch
+      set_dummy_env
+      assert_equal 'bar', ENV.fetch('FOO')
+      assert_equal 'val', ENV.fetch('BAR', 'val')
+      assert_equal 'val2', ENV.fetch('BAR') { |key| 'val2' }
+      assert_raise(KeyError) do
+        ENV.fetch('BAR')
+      end
+    end
+
+    def test_env_subst_nil
+      set_dummy_env
+      ENV['FOO'] = nil
+      assert_equal(0, ENV.size)
+    end
+
+    def test_env_store
+      ENV['a'] = 'b'
+      assert_equal 'b', ENV['a']
+
+      ENV['a'] = 'c'
+      assert_equal 'c', ENV['a']
+
+      ENV['a'] = nil
+      assert_equal nil, ENV['a']
+
+      ENV['b'] = nil
+      assert_equal nil, ENV['b']
+      assert_equal 0, ENV.size
+    end
+  end
+
+  if $ok_test
+    MTest::Unit.new.mrbtest
+  else
+    MTest::Unit.new.run
+  end
+else
+  $asserts << "test skip of mruby-env/test/env_test.rb"  if $asserts
+end
+
Index: EcnlProtoTool/trunk/mrbgems/mruby-errno/.gitignore
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-errno/.gitignore	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-errno/.gitignore	(revision 331)
@@ -0,0 +1,1 @@
+/tmp
Index: EcnlProtoTool/trunk/mrbgems/mruby-errno/.travis.yml
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-errno/.travis.yml	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-errno/.travis.yml	(revision 331)
@@ -0,0 +1,2 @@
+script:
+  - "ruby run_test.rb all test"
Index: EcnlProtoTool/trunk/mrbgems/mruby-errno/README.md
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-errno/README.md	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-errno/README.md	(revision 331)
@@ -0,0 +1,27 @@
+mruby-errno
+===========
+
+Errno module for mruby
+
+
+## License
+
+Copyright (c) 2013 Internet Initiative Japan Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a 
+copy of this software and associated documentation files (the "Software"), 
+to deal in the Software without restriction, including without limitation 
+the rights to use, copy, modify, merge, publish, distribute, sublicense, 
+and/or sell copies of the Software, and to permit persons to whom the 
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in 
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+DEALINGS IN THE SOFTWARE.
Index: EcnlProtoTool/trunk/mrbgems/mruby-errno/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-errno/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-errno/mrbgem.rake	(revision 331)
@@ -0,0 +1,6 @@
+MRuby::Gem::Specification.new('mruby-errno') do |spec|
+  spec.license = 'MIT'
+  spec.authors = 'Internet Initiative Japan Inc.'
+
+  spec.cc.include_paths << "#{build.root}/src"
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-errno/run_test.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-errno/run_test.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-errno/run_test.rb	(revision 331)
@@ -0,0 +1,26 @@
+#!/usr/bin/env ruby
+#
+# mrbgems test runner
+#
+
+gemname = File.basename(File.dirname(File.expand_path __FILE__))
+
+if __FILE__ == $0
+  repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby'
+  build_args = ARGV
+  build_args = ['all', 'test']  if build_args.nil? or build_args.empty?
+
+  Dir.mkdir 'tmp'  unless File.exist?('tmp')
+  unless File.exist?(dir)
+    system "git clone #{repository} #{dir}"
+  end
+
+  exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}])
+end
+
+MRuby::Build.new do |conf|
+  toolchain :gcc
+  conf.gembox 'default'
+
+  conf.gem File.expand_path(File.dirname(__FILE__))
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-errno/src/errno.c
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-errno/src/errno.c	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-errno/src/errno.c	(revision 331)
@@ -0,0 +1,175 @@
+#include "mruby.h"
+#include "mruby/array.h"
+#include "mruby/class.h"
+#include "mruby/hash.h"
+#include "mruby/numeric.h"
+#include "mruby/string.h"
+#include "mruby/variable.h"
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#if MRUBY_RELEASE_NO < 10000
+static struct RClass *
+mrb_module_get(mrb_state *mrb, const char *name)
+{
+  return mrb_class_get(mrb, name);
+}
+#endif
+
+static mrb_value
+mrb_sce_init(mrb_state *mrb, mrb_value self)
+{
+  mrb_value c, e2c, m, str;
+  mrb_int n;
+  int argc, no_errno = 0;
+  char buf[20];
+
+  argc = mrb_get_args(mrb, "o|i", &m, &n);
+  if (argc == 1) {
+    if (mrb_type(m) == MRB_TT_FIXNUM) {
+      n = mrb_fixnum(m);
+      m = mrb_nil_value();
+    } else {
+      no_errno = 1;
+    }
+  }
+  if (!no_errno) {
+    e2c = mrb_const_get(mrb, mrb_obj_value(mrb_module_get(mrb, "Errno")), mrb_intern_lit(mrb, "Errno2class"));
+    c = mrb_hash_fetch(mrb, e2c, mrb_fixnum_value(n), mrb_nil_value());
+    if (!mrb_nil_p(c)) {
+      mrb_basic_ptr(self)->c = mrb_class_ptr(c);
+      str = mrb_str_new_cstr(mrb, strerror(n));
+    } else {
+      mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "errno"), mrb_fixnum_value(n));
+      str = mrb_str_new_cstr(mrb, "Unknown error: ");
+      snprintf(buf, sizeof(buf), "%d", (int)n);
+      mrb_str_cat2(mrb, str, buf);
+    }
+  } else {
+    str = mrb_str_new_cstr(mrb, "unknown error");
+  }
+  if (!mrb_nil_p(m)) {
+    mrb_str_cat2(mrb, str, " - ");
+    mrb_str_append(mrb, str, m);
+  }
+  mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "mesg"), str);
+  return self;
+}
+
+static mrb_value
+mrb_sce_errno(mrb_state *mrb, mrb_value self)
+{
+  struct RClass *c;
+  mrb_sym sym;
+
+  c = mrb_class(mrb, self);
+  sym = mrb_intern_lit(mrb, "Errno");
+#if MRUBY_RELEASE_NO < 10000
+  if (mrb_const_defined_at(mrb, c, sym)) {
+#else
+  if (mrb_const_defined_at(mrb, mrb_obj_value(c), sym)) {
+#endif
+    return mrb_const_get(mrb, mrb_obj_value(c), sym);
+  } else {
+    sym = mrb_intern_lit(mrb, "errno");
+    return mrb_attr_get(mrb, self, sym);
+  }
+}
+
+static mrb_value
+mrb_sce_to_s(mrb_state *mrb, mrb_value self)
+{
+  return mrb_attr_get(mrb, self, mrb_intern_lit(mrb, "mesg"));
+}
+
+static mrb_value
+mrb_sce_sys_fail(mrb_state *mrb, mrb_value cls)
+{
+  struct RClass *cl, *sce;
+  mrb_value e, msg;
+  mrb_int no;
+  int argc;
+  char name[8];
+
+  sce = mrb_class_get(mrb, "SystemCallError");
+  argc = mrb_get_args(mrb, "i|S", &no, &msg);
+  if (argc == 1) {
+    e = mrb_funcall(mrb, mrb_obj_value(sce), "new", 1, mrb_fixnum_value(no));
+  } else {
+    e = mrb_funcall(mrb, mrb_obj_value(sce), "new", 2, msg, mrb_fixnum_value(no));
+  }
+  if (mrb_obj_class(mrb, e) == sce) {
+    snprintf(name, sizeof(name), "E%03ld", (long)no);
+    cl = mrb_define_class_under(mrb, mrb_module_get(mrb, "Errno"), name, sce);
+    mrb_define_const(mrb, cl, "Errno", mrb_fixnum_value(no));
+    mrb_basic_ptr(e)->c = cl;
+  }
+  mrb_exc_raise(mrb, e);
+  return mrb_nil_value();  /* NOTREACHED */
+}
+
+static mrb_value
+mrb_exxx_init(mrb_state *mrb, mrb_value self)
+{
+  mrb_value m, no, str;
+
+  no = mrb_const_get(mrb, mrb_obj_value(mrb_class(mrb, self)), mrb_intern_lit(mrb, "Errno"));
+  str = mrb_str_new_cstr(mrb, strerror(mrb_fixnum(no)));
+
+  m = mrb_nil_value();
+  mrb_get_args(mrb, "|S", &m);
+  if (!mrb_nil_p(m)) {
+    mrb_str_cat2(mrb, str, " - ");
+    mrb_str_append(mrb, str, m);
+  }
+  mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "mesg"), str);
+  return self;
+}
+
+void
+mrb_mruby_errno_gem_init(mrb_state *mrb)
+{
+  struct RClass *e, *eno, *sce, *ste;
+  mrb_value h, noerror;
+
+  ste = mrb_class_get(mrb, "StandardError");
+
+  sce = mrb_define_class(mrb, "SystemCallError", ste);
+  mrb_define_class_method(mrb, sce, "_sys_fail", mrb_sce_sys_fail, MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, sce, "errno", mrb_sce_errno, MRB_ARGS_NONE());
+  mrb_define_method(mrb, sce, "to_s", mrb_sce_to_s, MRB_ARGS_NONE());
+  mrb_define_method(mrb, sce, "initialize", mrb_sce_init, MRB_ARGS_ARG(1, 1));
+
+  eno = mrb_define_module(mrb, "Errno");
+  h = mrb_hash_new(mrb);
+  mrb_define_const(mrb, eno, "Errno2class", h);
+
+  e = mrb_define_class_under(mrb, eno, "NOERROR", sce);
+  mrb_define_const(mrb, e, "Errno", mrb_fixnum_value(0));
+  mrb_define_method(mrb, e, "initialize", mrb_exxx_init, MRB_ARGS_OPT(1));
+  //mrb_define_method(mrb, e, "===", mrb_exxx_cmp, MRB_ARGS_REQ(1));
+  noerror = mrb_obj_value(e);
+
+#define itsdefined(SYM) \
+  do {									\
+    int ai = mrb_gc_arena_save(mrb);					\
+    e = mrb_define_class_under(mrb, eno, #SYM, sce);			\
+    mrb_define_const(mrb, e, "Errno", mrb_fixnum_value(SYM));		\
+    mrb_define_method(mrb, e, "initialize", mrb_exxx_init, MRB_ARGS_OPT(1)); \
+    mrb_hash_set(mrb, h, mrb_fixnum_value(SYM), mrb_obj_value(e));	\
+    mrb_gc_arena_restore(mrb, ai);					\
+  } while (0)
+
+#define itsnotdefined(SYM) \
+  do {									\
+    mrb_define_const(mrb, eno, #SYM, noerror);				\
+  } while (0)
+
+#include "known_errors_def.cstub"
+}
+
+void
+mrb_mruby_errno_gem_final(mrb_state *mrb)
+{
+}
Index: EcnlProtoTool/trunk/mrbgems/mruby-errno/src/gen.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-errno/src/gen.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-errno/src/gen.rb	(revision 331)
@@ -0,0 +1,25 @@
+#!/usr/bin/env ruby
+
+Dir.chdir(File.dirname($0))
+
+e = File.open("known_errors_e2c.cstub", "w")
+d = File.open("known_errors_def.cstub", "w")
+
+IO.readlines("known_errors.def").each { |name|
+  next if name =~ /^#/
+  name.strip!
+
+  e.write <<CODE
+#ifdef #{name}
+  { #{name}, NULL, },
+#endif
+CODE
+
+  d.write <<CODE
+#ifdef #{name}
+  itsdefined(#{name});
+#else
+  itsnotdefined(#{name});
+#endif
+CODE
+}
Index: EcnlProtoTool/trunk/mrbgems/mruby-errno/src/known_errors.def
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-errno/src/known_errors.def	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-errno/src/known_errors.def	(revision 331)
@@ -0,0 +1,145 @@
+EPERM
+ENOENT
+ESRCH
+EINTR
+EIO
+ENXIO
+E2BIG
+ENOEXEC
+EBADF
+ECHILD
+EAGAIN
+ENOMEM
+EACCES
+EFAULT
+ENOTBLK
+EBUSY
+EEXIST
+EXDEV
+ENODEV
+ENOTDIR
+EISDIR
+EINVAL
+ENFILE
+EMFILE
+ENOTTY
+ETXTBSY
+EFBIG
+ENOSPC
+ESPIPE
+EROFS
+EMLINK
+EPIPE
+EDOM
+ERANGE
+EDEADLK
+ENAMETOOLONG
+ENOLCK
+ENOSYS
+ENOTEMPTY
+ELOOP
+EWOULDBLOCK
+ENOMSG
+EIDRM
+ECHRNG
+EL2NSYNC
+EL3HLT
+EL3RST
+ELNRNG
+EUNATCH
+ENOCSI
+EL2HLT
+EBADE
+EBADR
+EXFULL
+ENOANO
+EBADRQC
+EBADSLT
+EDEADLOCK
+EBFONT
+ENOSTR
+ENODATA
+ETIME
+ENOSR
+ENONET
+ENOPKG
+EREMOTE
+ENOLINK
+EADV
+ESRMNT
+ECOMM
+EPROTO
+EMULTIHOP
+EDOTDOT
+EBADMSG
+EOVERFLOW
+ENOTUNIQ
+EBADFD
+EREMCHG
+ELIBACC
+ELIBBAD
+ELIBSCN
+ELIBMAX
+ELIBEXEC
+EILSEQ
+ERESTART
+ESTRPIPE
+EUSERS
+ENOTSOCK
+EDESTADDRREQ
+EMSGSIZE
+EPROTOTYPE
+ENOPROTOOPT
+EPROTONOSUPPORT
+ESOCKTNOSUPPORT
+EOPNOTSUPP
+EPFNOSUPPORT
+EAFNOSUPPORT
+EADDRINUSE
+EADDRNOTAVAIL
+ENETDOWN
+ENETUNREACH
+ENETRESET
+ECONNABORTED
+ECONNRESET
+ENOBUFS
+EISCONN
+ENOTCONN
+ESHUTDOWN
+ETOOMANYREFS
+ETIMEDOUT
+ECONNREFUSED
+EHOSTDOWN
+EHOSTUNREACH
+EALREADY
+EINPROGRESS
+ESTALE
+EUCLEAN
+ENOTNAM
+ENAVAIL
+EISNAM
+EREMOTEIO
+EDQUOT
+ECANCELED
+EKEYEXPIRED
+EKEYREJECTED
+EKEYREVOKED
+EMEDIUMTYPE
+ENOKEY
+ENOMEDIUM
+ENOTRECOVERABLE
+EOWNERDEAD
+ERFKILL
+EAUTH
+EBADRPC
+EDOOFUS
+EFTYPE
+ENEEDAUTH
+ENOATTR
+ENOTSUP
+EPROCLIM
+EPROCUNAVAIL
+EPROGMISMATCH
+EPROGUNAVAIL
+ERPCMISMATCH
+EIPSEC
Index: EcnlProtoTool/trunk/mrbgems/mruby-errno/src/known_errors_def.cstub
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-errno/src/known_errors_def.cstub	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-errno/src/known_errors_def.cstub	(revision 331)
@@ -0,0 +1,725 @@
+#ifdef EPERM
+  itsdefined(EPERM);
+#else
+  itsnotdefined(EPERM);
+#endif
+#ifdef ENOENT
+  itsdefined(ENOENT);
+#else
+  itsnotdefined(ENOENT);
+#endif
+#ifdef ESRCH
+  itsdefined(ESRCH);
+#else
+  itsnotdefined(ESRCH);
+#endif
+#ifdef EINTR
+  itsdefined(EINTR);
+#else
+  itsnotdefined(EINTR);
+#endif
+#ifdef EIO
+  itsdefined(EIO);
+#else
+  itsnotdefined(EIO);
+#endif
+#ifdef ENXIO
+  itsdefined(ENXIO);
+#else
+  itsnotdefined(ENXIO);
+#endif
+#ifdef E2BIG
+  itsdefined(E2BIG);
+#else
+  itsnotdefined(E2BIG);
+#endif
+#ifdef ENOEXEC
+  itsdefined(ENOEXEC);
+#else
+  itsnotdefined(ENOEXEC);
+#endif
+#ifdef EBADF
+  itsdefined(EBADF);
+#else
+  itsnotdefined(EBADF);
+#endif
+#ifdef ECHILD
+  itsdefined(ECHILD);
+#else
+  itsnotdefined(ECHILD);
+#endif
+#ifdef EAGAIN
+  itsdefined(EAGAIN);
+#else
+  itsnotdefined(EAGAIN);
+#endif
+#ifdef ENOMEM
+  itsdefined(ENOMEM);
+#else
+  itsnotdefined(ENOMEM);
+#endif
+#ifdef EACCES
+  itsdefined(EACCES);
+#else
+  itsnotdefined(EACCES);
+#endif
+#ifdef EFAULT
+  itsdefined(EFAULT);
+#else
+  itsnotdefined(EFAULT);
+#endif
+#ifdef ENOTBLK
+  itsdefined(ENOTBLK);
+#else
+  itsnotdefined(ENOTBLK);
+#endif
+#ifdef EBUSY
+  itsdefined(EBUSY);
+#else
+  itsnotdefined(EBUSY);
+#endif
+#ifdef EEXIST
+  itsdefined(EEXIST);
+#else
+  itsnotdefined(EEXIST);
+#endif
+#ifdef EXDEV
+  itsdefined(EXDEV);
+#else
+  itsnotdefined(EXDEV);
+#endif
+#ifdef ENODEV
+  itsdefined(ENODEV);
+#else
+  itsnotdefined(ENODEV);
+#endif
+#ifdef ENOTDIR
+  itsdefined(ENOTDIR);
+#else
+  itsnotdefined(ENOTDIR);
+#endif
+#ifdef EISDIR
+  itsdefined(EISDIR);
+#else
+  itsnotdefined(EISDIR);
+#endif
+#ifdef EINVAL
+  itsdefined(EINVAL);
+#else
+  itsnotdefined(EINVAL);
+#endif
+#ifdef ENFILE
+  itsdefined(ENFILE);
+#else
+  itsnotdefined(ENFILE);
+#endif
+#ifdef EMFILE
+  itsdefined(EMFILE);
+#else
+  itsnotdefined(EMFILE);
+#endif
+#ifdef ENOTTY
+  itsdefined(ENOTTY);
+#else
+  itsnotdefined(ENOTTY);
+#endif
+#ifdef ETXTBSY
+  itsdefined(ETXTBSY);
+#else
+  itsnotdefined(ETXTBSY);
+#endif
+#ifdef EFBIG
+  itsdefined(EFBIG);
+#else
+  itsnotdefined(EFBIG);
+#endif
+#ifdef ENOSPC
+  itsdefined(ENOSPC);
+#else
+  itsnotdefined(ENOSPC);
+#endif
+#ifdef ESPIPE
+  itsdefined(ESPIPE);
+#else
+  itsnotdefined(ESPIPE);
+#endif
+#ifdef EROFS
+  itsdefined(EROFS);
+#else
+  itsnotdefined(EROFS);
+#endif
+#ifdef EMLINK
+  itsdefined(EMLINK);
+#else
+  itsnotdefined(EMLINK);
+#endif
+#ifdef EPIPE
+  itsdefined(EPIPE);
+#else
+  itsnotdefined(EPIPE);
+#endif
+#ifdef EDOM
+  itsdefined(EDOM);
+#else
+  itsnotdefined(EDOM);
+#endif
+#ifdef ERANGE
+  itsdefined(ERANGE);
+#else
+  itsnotdefined(ERANGE);
+#endif
+#ifdef EDEADLK
+  itsdefined(EDEADLK);
+#else
+  itsnotdefined(EDEADLK);
+#endif
+#ifdef ENAMETOOLONG
+  itsdefined(ENAMETOOLONG);
+#else
+  itsnotdefined(ENAMETOOLONG);
+#endif
+#ifdef ENOLCK
+  itsdefined(ENOLCK);
+#else
+  itsnotdefined(ENOLCK);
+#endif
+#ifdef ENOSYS
+  itsdefined(ENOSYS);
+#else
+  itsnotdefined(ENOSYS);
+#endif
+#ifdef ENOTEMPTY
+  itsdefined(ENOTEMPTY);
+#else
+  itsnotdefined(ENOTEMPTY);
+#endif
+#ifdef ELOOP
+  itsdefined(ELOOP);
+#else
+  itsnotdefined(ELOOP);
+#endif
+#ifdef EWOULDBLOCK
+  itsdefined(EWOULDBLOCK);
+#else
+  itsnotdefined(EWOULDBLOCK);
+#endif
+#ifdef ENOMSG
+  itsdefined(ENOMSG);
+#else
+  itsnotdefined(ENOMSG);
+#endif
+#ifdef EIDRM
+  itsdefined(EIDRM);
+#else
+  itsnotdefined(EIDRM);
+#endif
+#ifdef ECHRNG
+  itsdefined(ECHRNG);
+#else
+  itsnotdefined(ECHRNG);
+#endif
+#ifdef EL2NSYNC
+  itsdefined(EL2NSYNC);
+#else
+  itsnotdefined(EL2NSYNC);
+#endif
+#ifdef EL3HLT
+  itsdefined(EL3HLT);
+#else
+  itsnotdefined(EL3HLT);
+#endif
+#ifdef EL3RST
+  itsdefined(EL3RST);
+#else
+  itsnotdefined(EL3RST);
+#endif
+#ifdef ELNRNG
+  itsdefined(ELNRNG);
+#else
+  itsnotdefined(ELNRNG);
+#endif
+#ifdef EUNATCH
+  itsdefined(EUNATCH);
+#else
+  itsnotdefined(EUNATCH);
+#endif
+#ifdef ENOCSI
+  itsdefined(ENOCSI);
+#else
+  itsnotdefined(ENOCSI);
+#endif
+#ifdef EL2HLT
+  itsdefined(EL2HLT);
+#else
+  itsnotdefined(EL2HLT);
+#endif
+#ifdef EBADE
+  itsdefined(EBADE);
+#else
+  itsnotdefined(EBADE);
+#endif
+#ifdef EBADR
+  itsdefined(EBADR);
+#else
+  itsnotdefined(EBADR);
+#endif
+#ifdef EXFULL
+  itsdefined(EXFULL);
+#else
+  itsnotdefined(EXFULL);
+#endif
+#ifdef ENOANO
+  itsdefined(ENOANO);
+#else
+  itsnotdefined(ENOANO);
+#endif
+#ifdef EBADRQC
+  itsdefined(EBADRQC);
+#else
+  itsnotdefined(EBADRQC);
+#endif
+#ifdef EBADSLT
+  itsdefined(EBADSLT);
+#else
+  itsnotdefined(EBADSLT);
+#endif
+#ifdef EDEADLOCK
+  itsdefined(EDEADLOCK);
+#else
+  itsnotdefined(EDEADLOCK);
+#endif
+#ifdef EBFONT
+  itsdefined(EBFONT);
+#else
+  itsnotdefined(EBFONT);
+#endif
+#ifdef ENOSTR
+  itsdefined(ENOSTR);
+#else
+  itsnotdefined(ENOSTR);
+#endif
+#ifdef ENODATA
+  itsdefined(ENODATA);
+#else
+  itsnotdefined(ENODATA);
+#endif
+#ifdef ETIME
+  itsdefined(ETIME);
+#else
+  itsnotdefined(ETIME);
+#endif
+#ifdef ENOSR
+  itsdefined(ENOSR);
+#else
+  itsnotdefined(ENOSR);
+#endif
+#ifdef ENONET
+  itsdefined(ENONET);
+#else
+  itsnotdefined(ENONET);
+#endif
+#ifdef ENOPKG
+  itsdefined(ENOPKG);
+#else
+  itsnotdefined(ENOPKG);
+#endif
+#ifdef EREMOTE
+  itsdefined(EREMOTE);
+#else
+  itsnotdefined(EREMOTE);
+#endif
+#ifdef ENOLINK
+  itsdefined(ENOLINK);
+#else
+  itsnotdefined(ENOLINK);
+#endif
+#ifdef EADV
+  itsdefined(EADV);
+#else
+  itsnotdefined(EADV);
+#endif
+#ifdef ESRMNT
+  itsdefined(ESRMNT);
+#else
+  itsnotdefined(ESRMNT);
+#endif
+#ifdef ECOMM
+  itsdefined(ECOMM);
+#else
+  itsnotdefined(ECOMM);
+#endif
+#ifdef EPROTO
+  itsdefined(EPROTO);
+#else
+  itsnotdefined(EPROTO);
+#endif
+#ifdef EMULTIHOP
+  itsdefined(EMULTIHOP);
+#else
+  itsnotdefined(EMULTIHOP);
+#endif
+#ifdef EDOTDOT
+  itsdefined(EDOTDOT);
+#else
+  itsnotdefined(EDOTDOT);
+#endif
+#ifdef EBADMSG
+  itsdefined(EBADMSG);
+#else
+  itsnotdefined(EBADMSG);
+#endif
+#ifdef EOVERFLOW
+  itsdefined(EOVERFLOW);
+#else
+  itsnotdefined(EOVERFLOW);
+#endif
+#ifdef ENOTUNIQ
+  itsdefined(ENOTUNIQ);
+#else
+  itsnotdefined(ENOTUNIQ);
+#endif
+#ifdef EBADFD
+  itsdefined(EBADFD);
+#else
+  itsnotdefined(EBADFD);
+#endif
+#ifdef EREMCHG
+  itsdefined(EREMCHG);
+#else
+  itsnotdefined(EREMCHG);
+#endif
+#ifdef ELIBACC
+  itsdefined(ELIBACC);
+#else
+  itsnotdefined(ELIBACC);
+#endif
+#ifdef ELIBBAD
+  itsdefined(ELIBBAD);
+#else
+  itsnotdefined(ELIBBAD);
+#endif
+#ifdef ELIBSCN
+  itsdefined(ELIBSCN);
+#else
+  itsnotdefined(ELIBSCN);
+#endif
+#ifdef ELIBMAX
+  itsdefined(ELIBMAX);
+#else
+  itsnotdefined(ELIBMAX);
+#endif
+#ifdef ELIBEXEC
+  itsdefined(ELIBEXEC);
+#else
+  itsnotdefined(ELIBEXEC);
+#endif
+#ifdef EILSEQ
+  itsdefined(EILSEQ);
+#else
+  itsnotdefined(EILSEQ);
+#endif
+#ifdef ERESTART
+  itsdefined(ERESTART);
+#else
+  itsnotdefined(ERESTART);
+#endif
+#ifdef ESTRPIPE
+  itsdefined(ESTRPIPE);
+#else
+  itsnotdefined(ESTRPIPE);
+#endif
+#ifdef EUSERS
+  itsdefined(EUSERS);
+#else
+  itsnotdefined(EUSERS);
+#endif
+#ifdef ENOTSOCK
+  itsdefined(ENOTSOCK);
+#else
+  itsnotdefined(ENOTSOCK);
+#endif
+#ifdef EDESTADDRREQ
+  itsdefined(EDESTADDRREQ);
+#else
+  itsnotdefined(EDESTADDRREQ);
+#endif
+#ifdef EMSGSIZE
+  itsdefined(EMSGSIZE);
+#else
+  itsnotdefined(EMSGSIZE);
+#endif
+#ifdef EPROTOTYPE
+  itsdefined(EPROTOTYPE);
+#else
+  itsnotdefined(EPROTOTYPE);
+#endif
+#ifdef ENOPROTOOPT
+  itsdefined(ENOPROTOOPT);
+#else
+  itsnotdefined(ENOPROTOOPT);
+#endif
+#ifdef EPROTONOSUPPORT
+  itsdefined(EPROTONOSUPPORT);
+#else
+  itsnotdefined(EPROTONOSUPPORT);
+#endif
+#ifdef ESOCKTNOSUPPORT
+  itsdefined(ESOCKTNOSUPPORT);
+#else
+  itsnotdefined(ESOCKTNOSUPPORT);
+#endif
+#ifdef EOPNOTSUPP
+  itsdefined(EOPNOTSUPP);
+#else
+  itsnotdefined(EOPNOTSUPP);
+#endif
+#ifdef EPFNOSUPPORT
+  itsdefined(EPFNOSUPPORT);
+#else
+  itsnotdefined(EPFNOSUPPORT);
+#endif
+#ifdef EAFNOSUPPORT
+  itsdefined(EAFNOSUPPORT);
+#else
+  itsnotdefined(EAFNOSUPPORT);
+#endif
+#ifdef EADDRINUSE
+  itsdefined(EADDRINUSE);
+#else
+  itsnotdefined(EADDRINUSE);
+#endif
+#ifdef EADDRNOTAVAIL
+  itsdefined(EADDRNOTAVAIL);
+#else
+  itsnotdefined(EADDRNOTAVAIL);
+#endif
+#ifdef ENETDOWN
+  itsdefined(ENETDOWN);
+#else
+  itsnotdefined(ENETDOWN);
+#endif
+#ifdef ENETUNREACH
+  itsdefined(ENETUNREACH);
+#else
+  itsnotdefined(ENETUNREACH);
+#endif
+#ifdef ENETRESET
+  itsdefined(ENETRESET);
+#else
+  itsnotdefined(ENETRESET);
+#endif
+#ifdef ECONNABORTED
+  itsdefined(ECONNABORTED);
+#else
+  itsnotdefined(ECONNABORTED);
+#endif
+#ifdef ECONNRESET
+  itsdefined(ECONNRESET);
+#else
+  itsnotdefined(ECONNRESET);
+#endif
+#ifdef ENOBUFS
+  itsdefined(ENOBUFS);
+#else
+  itsnotdefined(ENOBUFS);
+#endif
+#ifdef EISCONN
+  itsdefined(EISCONN);
+#else
+  itsnotdefined(EISCONN);
+#endif
+#ifdef ENOTCONN
+  itsdefined(ENOTCONN);
+#else
+  itsnotdefined(ENOTCONN);
+#endif
+#ifdef ESHUTDOWN
+  itsdefined(ESHUTDOWN);
+#else
+  itsnotdefined(ESHUTDOWN);
+#endif
+#ifdef ETOOMANYREFS
+  itsdefined(ETOOMANYREFS);
+#else
+  itsnotdefined(ETOOMANYREFS);
+#endif
+#ifdef ETIMEDOUT
+  itsdefined(ETIMEDOUT);
+#else
+  itsnotdefined(ETIMEDOUT);
+#endif
+#ifdef ECONNREFUSED
+  itsdefined(ECONNREFUSED);
+#else
+  itsnotdefined(ECONNREFUSED);
+#endif
+#ifdef EHOSTDOWN
+  itsdefined(EHOSTDOWN);
+#else
+  itsnotdefined(EHOSTDOWN);
+#endif
+#ifdef EHOSTUNREACH
+  itsdefined(EHOSTUNREACH);
+#else
+  itsnotdefined(EHOSTUNREACH);
+#endif
+#ifdef EALREADY
+  itsdefined(EALREADY);
+#else
+  itsnotdefined(EALREADY);
+#endif
+#ifdef EINPROGRESS
+  itsdefined(EINPROGRESS);
+#else
+  itsnotdefined(EINPROGRESS);
+#endif
+#ifdef ESTALE
+  itsdefined(ESTALE);
+#else
+  itsnotdefined(ESTALE);
+#endif
+#ifdef EUCLEAN
+  itsdefined(EUCLEAN);
+#else
+  itsnotdefined(EUCLEAN);
+#endif
+#ifdef ENOTNAM
+  itsdefined(ENOTNAM);
+#else
+  itsnotdefined(ENOTNAM);
+#endif
+#ifdef ENAVAIL
+  itsdefined(ENAVAIL);
+#else
+  itsnotdefined(ENAVAIL);
+#endif
+#ifdef EISNAM
+  itsdefined(EISNAM);
+#else
+  itsnotdefined(EISNAM);
+#endif
+#ifdef EREMOTEIO
+  itsdefined(EREMOTEIO);
+#else
+  itsnotdefined(EREMOTEIO);
+#endif
+#ifdef EDQUOT
+  itsdefined(EDQUOT);
+#else
+  itsnotdefined(EDQUOT);
+#endif
+#ifdef ECANCELED
+  itsdefined(ECANCELED);
+#else
+  itsnotdefined(ECANCELED);
+#endif
+#ifdef EKEYEXPIRED
+  itsdefined(EKEYEXPIRED);
+#else
+  itsnotdefined(EKEYEXPIRED);
+#endif
+#ifdef EKEYREJECTED
+  itsdefined(EKEYREJECTED);
+#else
+  itsnotdefined(EKEYREJECTED);
+#endif
+#ifdef EKEYREVOKED
+  itsdefined(EKEYREVOKED);
+#else
+  itsnotdefined(EKEYREVOKED);
+#endif
+#ifdef EMEDIUMTYPE
+  itsdefined(EMEDIUMTYPE);
+#else
+  itsnotdefined(EMEDIUMTYPE);
+#endif
+#ifdef ENOKEY
+  itsdefined(ENOKEY);
+#else
+  itsnotdefined(ENOKEY);
+#endif
+#ifdef ENOMEDIUM
+  itsdefined(ENOMEDIUM);
+#else
+  itsnotdefined(ENOMEDIUM);
+#endif
+#ifdef ENOTRECOVERABLE
+  itsdefined(ENOTRECOVERABLE);
+#else
+  itsnotdefined(ENOTRECOVERABLE);
+#endif
+#ifdef EOWNERDEAD
+  itsdefined(EOWNERDEAD);
+#else
+  itsnotdefined(EOWNERDEAD);
+#endif
+#ifdef ERFKILL
+  itsdefined(ERFKILL);
+#else
+  itsnotdefined(ERFKILL);
+#endif
+#ifdef EAUTH
+  itsdefined(EAUTH);
+#else
+  itsnotdefined(EAUTH);
+#endif
+#ifdef EBADRPC
+  itsdefined(EBADRPC);
+#else
+  itsnotdefined(EBADRPC);
+#endif
+#ifdef EDOOFUS
+  itsdefined(EDOOFUS);
+#else
+  itsnotdefined(EDOOFUS);
+#endif
+#ifdef EFTYPE
+  itsdefined(EFTYPE);
+#else
+  itsnotdefined(EFTYPE);
+#endif
+#ifdef ENEEDAUTH
+  itsdefined(ENEEDAUTH);
+#else
+  itsnotdefined(ENEEDAUTH);
+#endif
+#ifdef ENOATTR
+  itsdefined(ENOATTR);
+#else
+  itsnotdefined(ENOATTR);
+#endif
+#ifdef ENOTSUP
+  itsdefined(ENOTSUP);
+#else
+  itsnotdefined(ENOTSUP);
+#endif
+#ifdef EPROCLIM
+  itsdefined(EPROCLIM);
+#else
+  itsnotdefined(EPROCLIM);
+#endif
+#ifdef EPROCUNAVAIL
+  itsdefined(EPROCUNAVAIL);
+#else
+  itsnotdefined(EPROCUNAVAIL);
+#endif
+#ifdef EPROGMISMATCH
+  itsdefined(EPROGMISMATCH);
+#else
+  itsnotdefined(EPROGMISMATCH);
+#endif
+#ifdef EPROGUNAVAIL
+  itsdefined(EPROGUNAVAIL);
+#else
+  itsnotdefined(EPROGUNAVAIL);
+#endif
+#ifdef ERPCMISMATCH
+  itsdefined(ERPCMISMATCH);
+#else
+  itsnotdefined(ERPCMISMATCH);
+#endif
+#ifdef EIPSEC
+  itsdefined(EIPSEC);
+#else
+  itsnotdefined(EIPSEC);
+#endif
Index: EcnlProtoTool/trunk/mrbgems/mruby-errno/src/known_errors_e2c.cstub
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-errno/src/known_errors_e2c.cstub	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-errno/src/known_errors_e2c.cstub	(revision 331)
@@ -0,0 +1,435 @@
+#ifdef EPERM
+  { EPERM, NULL, },
+#endif
+#ifdef ENOENT
+  { ENOENT, NULL, },
+#endif
+#ifdef ESRCH
+  { ESRCH, NULL, },
+#endif
+#ifdef EINTR
+  { EINTR, NULL, },
+#endif
+#ifdef EIO
+  { EIO, NULL, },
+#endif
+#ifdef ENXIO
+  { ENXIO, NULL, },
+#endif
+#ifdef E2BIG
+  { E2BIG, NULL, },
+#endif
+#ifdef ENOEXEC
+  { ENOEXEC, NULL, },
+#endif
+#ifdef EBADF
+  { EBADF, NULL, },
+#endif
+#ifdef ECHILD
+  { ECHILD, NULL, },
+#endif
+#ifdef EAGAIN
+  { EAGAIN, NULL, },
+#endif
+#ifdef ENOMEM
+  { ENOMEM, NULL, },
+#endif
+#ifdef EACCES
+  { EACCES, NULL, },
+#endif
+#ifdef EFAULT
+  { EFAULT, NULL, },
+#endif
+#ifdef ENOTBLK
+  { ENOTBLK, NULL, },
+#endif
+#ifdef EBUSY
+  { EBUSY, NULL, },
+#endif
+#ifdef EEXIST
+  { EEXIST, NULL, },
+#endif
+#ifdef EXDEV
+  { EXDEV, NULL, },
+#endif
+#ifdef ENODEV
+  { ENODEV, NULL, },
+#endif
+#ifdef ENOTDIR
+  { ENOTDIR, NULL, },
+#endif
+#ifdef EISDIR
+  { EISDIR, NULL, },
+#endif
+#ifdef EINVAL
+  { EINVAL, NULL, },
+#endif
+#ifdef ENFILE
+  { ENFILE, NULL, },
+#endif
+#ifdef EMFILE
+  { EMFILE, NULL, },
+#endif
+#ifdef ENOTTY
+  { ENOTTY, NULL, },
+#endif
+#ifdef ETXTBSY
+  { ETXTBSY, NULL, },
+#endif
+#ifdef EFBIG
+  { EFBIG, NULL, },
+#endif
+#ifdef ENOSPC
+  { ENOSPC, NULL, },
+#endif
+#ifdef ESPIPE
+  { ESPIPE, NULL, },
+#endif
+#ifdef EROFS
+  { EROFS, NULL, },
+#endif
+#ifdef EMLINK
+  { EMLINK, NULL, },
+#endif
+#ifdef EPIPE
+  { EPIPE, NULL, },
+#endif
+#ifdef EDOM
+  { EDOM, NULL, },
+#endif
+#ifdef ERANGE
+  { ERANGE, NULL, },
+#endif
+#ifdef EDEADLK
+  { EDEADLK, NULL, },
+#endif
+#ifdef ENAMETOOLONG
+  { ENAMETOOLONG, NULL, },
+#endif
+#ifdef ENOLCK
+  { ENOLCK, NULL, },
+#endif
+#ifdef ENOSYS
+  { ENOSYS, NULL, },
+#endif
+#ifdef ENOTEMPTY
+  { ENOTEMPTY, NULL, },
+#endif
+#ifdef ELOOP
+  { ELOOP, NULL, },
+#endif
+#ifdef EWOULDBLOCK
+  { EWOULDBLOCK, NULL, },
+#endif
+#ifdef ENOMSG
+  { ENOMSG, NULL, },
+#endif
+#ifdef EIDRM
+  { EIDRM, NULL, },
+#endif
+#ifdef ECHRNG
+  { ECHRNG, NULL, },
+#endif
+#ifdef EL2NSYNC
+  { EL2NSYNC, NULL, },
+#endif
+#ifdef EL3HLT
+  { EL3HLT, NULL, },
+#endif
+#ifdef EL3RST
+  { EL3RST, NULL, },
+#endif
+#ifdef ELNRNG
+  { ELNRNG, NULL, },
+#endif
+#ifdef EUNATCH
+  { EUNATCH, NULL, },
+#endif
+#ifdef ENOCSI
+  { ENOCSI, NULL, },
+#endif
+#ifdef EL2HLT
+  { EL2HLT, NULL, },
+#endif
+#ifdef EBADE
+  { EBADE, NULL, },
+#endif
+#ifdef EBADR
+  { EBADR, NULL, },
+#endif
+#ifdef EXFULL
+  { EXFULL, NULL, },
+#endif
+#ifdef ENOANO
+  { ENOANO, NULL, },
+#endif
+#ifdef EBADRQC
+  { EBADRQC, NULL, },
+#endif
+#ifdef EBADSLT
+  { EBADSLT, NULL, },
+#endif
+#ifdef EDEADLOCK
+  { EDEADLOCK, NULL, },
+#endif
+#ifdef EBFONT
+  { EBFONT, NULL, },
+#endif
+#ifdef ENOSTR
+  { ENOSTR, NULL, },
+#endif
+#ifdef ENODATA
+  { ENODATA, NULL, },
+#endif
+#ifdef ETIME
+  { ETIME, NULL, },
+#endif
+#ifdef ENOSR
+  { ENOSR, NULL, },
+#endif
+#ifdef ENONET
+  { ENONET, NULL, },
+#endif
+#ifdef ENOPKG
+  { ENOPKG, NULL, },
+#endif
+#ifdef EREMOTE
+  { EREMOTE, NULL, },
+#endif
+#ifdef ENOLINK
+  { ENOLINK, NULL, },
+#endif
+#ifdef EADV
+  { EADV, NULL, },
+#endif
+#ifdef ESRMNT
+  { ESRMNT, NULL, },
+#endif
+#ifdef ECOMM
+  { ECOMM, NULL, },
+#endif
+#ifdef EPROTO
+  { EPROTO, NULL, },
+#endif
+#ifdef EMULTIHOP
+  { EMULTIHOP, NULL, },
+#endif
+#ifdef EDOTDOT
+  { EDOTDOT, NULL, },
+#endif
+#ifdef EBADMSG
+  { EBADMSG, NULL, },
+#endif
+#ifdef EOVERFLOW
+  { EOVERFLOW, NULL, },
+#endif
+#ifdef ENOTUNIQ
+  { ENOTUNIQ, NULL, },
+#endif
+#ifdef EBADFD
+  { EBADFD, NULL, },
+#endif
+#ifdef EREMCHG
+  { EREMCHG, NULL, },
+#endif
+#ifdef ELIBACC
+  { ELIBACC, NULL, },
+#endif
+#ifdef ELIBBAD
+  { ELIBBAD, NULL, },
+#endif
+#ifdef ELIBSCN
+  { ELIBSCN, NULL, },
+#endif
+#ifdef ELIBMAX
+  { ELIBMAX, NULL, },
+#endif
+#ifdef ELIBEXEC
+  { ELIBEXEC, NULL, },
+#endif
+#ifdef EILSEQ
+  { EILSEQ, NULL, },
+#endif
+#ifdef ERESTART
+  { ERESTART, NULL, },
+#endif
+#ifdef ESTRPIPE
+  { ESTRPIPE, NULL, },
+#endif
+#ifdef EUSERS
+  { EUSERS, NULL, },
+#endif
+#ifdef ENOTSOCK
+  { ENOTSOCK, NULL, },
+#endif
+#ifdef EDESTADDRREQ
+  { EDESTADDRREQ, NULL, },
+#endif
+#ifdef EMSGSIZE
+  { EMSGSIZE, NULL, },
+#endif
+#ifdef EPROTOTYPE
+  { EPROTOTYPE, NULL, },
+#endif
+#ifdef ENOPROTOOPT
+  { ENOPROTOOPT, NULL, },
+#endif
+#ifdef EPROTONOSUPPORT
+  { EPROTONOSUPPORT, NULL, },
+#endif
+#ifdef ESOCKTNOSUPPORT
+  { ESOCKTNOSUPPORT, NULL, },
+#endif
+#ifdef EOPNOTSUPP
+  { EOPNOTSUPP, NULL, },
+#endif
+#ifdef EPFNOSUPPORT
+  { EPFNOSUPPORT, NULL, },
+#endif
+#ifdef EAFNOSUPPORT
+  { EAFNOSUPPORT, NULL, },
+#endif
+#ifdef EADDRINUSE
+  { EADDRINUSE, NULL, },
+#endif
+#ifdef EADDRNOTAVAIL
+  { EADDRNOTAVAIL, NULL, },
+#endif
+#ifdef ENETDOWN
+  { ENETDOWN, NULL, },
+#endif
+#ifdef ENETUNREACH
+  { ENETUNREACH, NULL, },
+#endif
+#ifdef ENETRESET
+  { ENETRESET, NULL, },
+#endif
+#ifdef ECONNABORTED
+  { ECONNABORTED, NULL, },
+#endif
+#ifdef ECONNRESET
+  { ECONNRESET, NULL, },
+#endif
+#ifdef ENOBUFS
+  { ENOBUFS, NULL, },
+#endif
+#ifdef EISCONN
+  { EISCONN, NULL, },
+#endif
+#ifdef ENOTCONN
+  { ENOTCONN, NULL, },
+#endif
+#ifdef ESHUTDOWN
+  { ESHUTDOWN, NULL, },
+#endif
+#ifdef ETOOMANYREFS
+  { ETOOMANYREFS, NULL, },
+#endif
+#ifdef ETIMEDOUT
+  { ETIMEDOUT, NULL, },
+#endif
+#ifdef ECONNREFUSED
+  { ECONNREFUSED, NULL, },
+#endif
+#ifdef EHOSTDOWN
+  { EHOSTDOWN, NULL, },
+#endif
+#ifdef EHOSTUNREACH
+  { EHOSTUNREACH, NULL, },
+#endif
+#ifdef EALREADY
+  { EALREADY, NULL, },
+#endif
+#ifdef EINPROGRESS
+  { EINPROGRESS, NULL, },
+#endif
+#ifdef ESTALE
+  { ESTALE, NULL, },
+#endif
+#ifdef EUCLEAN
+  { EUCLEAN, NULL, },
+#endif
+#ifdef ENOTNAM
+  { ENOTNAM, NULL, },
+#endif
+#ifdef ENAVAIL
+  { ENAVAIL, NULL, },
+#endif
+#ifdef EISNAM
+  { EISNAM, NULL, },
+#endif
+#ifdef EREMOTEIO
+  { EREMOTEIO, NULL, },
+#endif
+#ifdef EDQUOT
+  { EDQUOT, NULL, },
+#endif
+#ifdef ECANCELED
+  { ECANCELED, NULL, },
+#endif
+#ifdef EKEYEXPIRED
+  { EKEYEXPIRED, NULL, },
+#endif
+#ifdef EKEYREJECTED
+  { EKEYREJECTED, NULL, },
+#endif
+#ifdef EKEYREVOKED
+  { EKEYREVOKED, NULL, },
+#endif
+#ifdef EMEDIUMTYPE
+  { EMEDIUMTYPE, NULL, },
+#endif
+#ifdef ENOKEY
+  { ENOKEY, NULL, },
+#endif
+#ifdef ENOMEDIUM
+  { ENOMEDIUM, NULL, },
+#endif
+#ifdef ENOTRECOVERABLE
+  { ENOTRECOVERABLE, NULL, },
+#endif
+#ifdef EOWNERDEAD
+  { EOWNERDEAD, NULL, },
+#endif
+#ifdef ERFKILL
+  { ERFKILL, NULL, },
+#endif
+#ifdef EAUTH
+  { EAUTH, NULL, },
+#endif
+#ifdef EBADRPC
+  { EBADRPC, NULL, },
+#endif
+#ifdef EDOOFUS
+  { EDOOFUS, NULL, },
+#endif
+#ifdef EFTYPE
+  { EFTYPE, NULL, },
+#endif
+#ifdef ENEEDAUTH
+  { ENEEDAUTH, NULL, },
+#endif
+#ifdef ENOATTR
+  { ENOATTR, NULL, },
+#endif
+#ifdef ENOTSUP
+  { ENOTSUP, NULL, },
+#endif
+#ifdef EPROCLIM
+  { EPROCLIM, NULL, },
+#endif
+#ifdef EPROCUNAVAIL
+  { EPROCUNAVAIL, NULL, },
+#endif
+#ifdef EPROGMISMATCH
+  { EPROGMISMATCH, NULL, },
+#endif
+#ifdef EPROGUNAVAIL
+  { EPROGUNAVAIL, NULL, },
+#endif
+#ifdef ERPCMISMATCH
+  { ERPCMISMATCH, NULL, },
+#endif
+#ifdef EIPSEC
+  { EIPSEC, NULL, },
+#endif
Index: EcnlProtoTool/trunk/mrbgems/mruby-errno/test/errno.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-errno/test/errno.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-errno/test/errno.rb	(revision 331)
@@ -0,0 +1,60 @@
+assert('Errno') do
+  Errno.class == Module
+end
+
+assert('SystemCallError') do
+  SystemCallError.class == Class
+end
+
+assert('SystemCallError superclass') do
+  SystemCallError.superclass == StandardError
+end
+
+assert('SystemCallError#initialize') do
+  SystemCallError.new("a").message == "unknown error - a" and
+  SystemCallError.new("a", 12345).message == "Unknown error: 12345 - a" and
+  SystemCallError.new(12345).message == "Unknown error: 12345"
+end
+
+assert('SystemCallError#errno') do
+  assert_equal 1, SystemCallError.new("a", 1).errno
+  assert_equal 1, SystemCallError.new(1).errno
+  assert_equal 12345, SystemCallError.new("a", 12345).errno
+  assert_equal 23456, SystemCallError.new(23456).errno
+end
+
+assert('SystemCallError#inspect') do
+  SystemCallError.new("a").inspect == "SystemCallError: unknown error - a"
+  end
+
+assert('Errno::NOERROR') do
+  Errno::NOERROR.class == Class
+end
+
+# Is there any platform does not have EPERM?
+assert('Errno::EPERM') do
+  Errno::EPERM.class == Class
+end
+
+assert('Errno::EPERM superclass') do
+  Errno::EPERM.superclass == SystemCallError
+end
+
+assert('Errno::EPERM::Errno') do
+  Errno::EPERM::Errno.is_a? Fixnum
+end
+
+assert('Errno::EPERM#message') do
+  msg = Errno::EPERM.new.message
+  Errno::EPERM.new("a").message == "#{msg} - a"
+end
+
+assert('Errno::EPERM#inspect 1') do
+  msg = Errno::EPERM.new.message
+  Errno::EPERM.new.inspect == "Errno::EPERM: #{msg}"
+end
+
+assert('Errno::EPERM#inspect 2') do
+  msg = Errno::EPERM.new.message
+  Errno::EPERM.new("a").inspect == "Errno::EPERM: #{msg} - a"
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-iijson/.gitignore
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-iijson/.gitignore	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-iijson/.gitignore	(revision 331)
@@ -0,0 +1,1 @@
+/tmp
Index: EcnlProtoTool/trunk/mrbgems/mruby-iijson/.travis.yml
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-iijson/.travis.yml	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-iijson/.travis.yml	(revision 331)
@@ -0,0 +1,2 @@
+script:
+  - "ruby run_test.rb all test"
Index: EcnlProtoTool/trunk/mrbgems/mruby-iijson/README.md
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-iijson/README.md	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-iijson/README.md	(revision 331)
@@ -0,0 +1,87 @@
+# mruby-iijson
+[![Build Status](https://travis-ci.org/iij/mruby-iijson.svg?branch=master)](https://travis-ci.org/iij/mruby-iijson)
+
+"mruby-iijson" is JSON module for mruby.
+
+
+## Implemented Methods:
+ - [JSON.dump](http://docs.ruby-lang.org/en/2.2.0/JSON.html#method-i-dump)
+ - [JSON.generate](http://docs.ruby-lang.org/en/2.2.0/JSON.html#method-i-generate)
+ - [JSON.load](http://docs.ruby-lang.org/en/2.2.0/JSON.html#method-i-load)
+ - [JSON.parse](http://docs.ruby-lang.org/en/2.2.0/JSON.html#method-i-parse)
+ - `Array#to_json`, `Fixnum#to_json`, `Float#to_json`, `Hash#to_json`, `String#to_json`, ...
+
+## Example:
+
+```Ruby
+str = '{
+  "Image": {
+    "Width":  800,
+    "Height": 600,
+    "Title":  "View from 15th Floor",
+    "Thumbnail": {
+      "Url":    "http://www.example.com/image/481989943",
+      "Height": 125,
+      "Width":  "100"
+    },
+    "IDs": [116, 943, 234, 38793]
+  }
+}'
+p JSON.parse(str)
+
+h = {
+  :precision => "zip",
+  :Latitude  =>  37.7668,
+  :Longitude => -122.3959,
+  :Address   => "",
+  :City      => "SAN FRANCISCO",
+  :State     => "CA",
+  :Zip       => "94107",
+  :Country   => "US"
+}
+p h.to_json
+puts JSON.generate(h, {:pretty_print => true, :indent_with => 2})
+```
+
+```
+{"Image"=>{"Width"=>800, "Height"=>600, "Title"=>"View from 15th Floor", "Thumbnail"=>{"Url"=>"http://www.example.com/image/481989943", "Height"=>125, "Width"=>"100"}, "IDs"=>[116, 943, 234, 38793]}}
+"{\"precision\":\"zip\",\"Latitude\":37.766800000000003,\"Longitude\":-122.3959,\"Address\":\"\",\"City\":\"SAN FRANCISCO\",\"State\":\"CA\",\"Zip\":\"94107\",\"Country\":\"US\"}"
+{
+  "precision": "zip",
+  "Latitude": 37.766800000000003,
+  "Longitude": -122.3959,
+  "Address": "",
+  "City": "SAN FRANCISCO",
+  "State": "CA",
+  "Zip": "94107",
+  "Country": "US"
+}
+```
+
+
+## Caveats
+
+ - JSON.generate won't return if input Array/Hash has circular reference.
+
+
+## License
+
+Copyright (c) 2014 Internet Initiative Japan Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a 
+copy of this software and associated documentation files (the "Software"), 
+to deal in the Software without restriction, including without limitation 
+the rights to use, copy, modify, merge, publish, distribute, sublicense, 
+and/or sell copies of the Software, and to permit persons to whom the 
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in 
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+DEALINGS IN THE SOFTWARE.
Index: EcnlProtoTool/trunk/mrbgems/mruby-iijson/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-iijson/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-iijson/mrbgem.rake	(revision 331)
@@ -0,0 +1,6 @@
+MRuby::Gem::Specification.new('mruby-iijson') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'Internet Initiative Japan Inc.'
+
+  spec.add_dependency "mruby-sprintf", :core => "mruby-sprintf"
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-iijson/mrblib/json.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-iijson/mrblib/json.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-iijson/mrblib/json.rb	(revision 331)
@@ -0,0 +1,129 @@
+module JSON
+  def self.dump(object, io=nil, limit=nil)
+    state = {}
+    state[:max_nesting] = limit if limit
+    begin
+      js = JSON.generate(object, nil, state)
+    rescue JSON::NestingError
+      raise ArgumentError, "exceeded depth limit"
+    end
+    if io
+      io.write js
+      io
+    else
+      js
+    end
+  end
+
+  def self.generate(obj, options=nil, state=nil)
+    options = (options || {}).to_hash unless options.is_a? Hash
+    options[:pretty_print] ||= false
+    options[:indent_with] ||= 2
+    state = (state || {}).to_hash unless state.is_a? Hash
+    state[:max_nesting] ||= 100
+    state[:nesting] = 0
+    self.generate0(obj, options, state)
+  end
+
+  def self.generate0(obj, options, state)
+    if state[:nesting] >= state[:max_nesting]
+      raise JSON::NestingError, "nesting of #{state[:nesting]} is too deep"
+    end
+
+    pretty = options[:pretty_print]
+    
+    if pretty
+      indent = options[:indent_with].class == Fixnum ? " " * options[:indent_with] : options[:indent_with]
+    else
+      indent = ""
+    end
+
+    nl = pretty ? "\n" : ""
+
+    if obj == false
+      return "false"
+
+    elsif obj == nil
+      return "null"
+
+    elsif obj == true
+      return "true"
+
+    elsif obj.is_a? Hash
+      members = []
+      state[:nesting] += 1
+      obj.each { |k, v|
+        members << JSON.generate0(k, options, state) + ":" + (pretty ? " " : "") + JSON.generate0(v, options, state)
+      }
+      if pretty
+        members.map! { |k| (indent * state[:nesting]) + "#{k}" }.join("_")
+      end
+      state[:nesting] -= 1
+      return "{" + nl + members.join("," + nl) + nl + (indent * state[:nesting]) + "}"
+
+    elsif obj.is_a? Array
+      state[:nesting] += 1
+      members = obj.map { |v| JSON.generate0(v, options, state) }
+      if pretty
+        members.map! { |k| (indent * state[:nesting]) + "#{k}" }.join("_")
+      end
+      state[:nesting] -= 1
+      return "[" + nl + members.join("," + nl) + nl + (indent * state[:nesting]) + "]"
+
+    elsif obj.is_a? Fixnum
+      return obj.to_s
+
+    elsif obj.is_a? Float
+      if obj.infinite? or obj.nan?
+        raise GeneratorError, "#{obj.to_s} not allowed in JSON"
+      end
+      sprintf "%.17g", obj
+
+    else
+      a = []
+      obj.to_s.each_char { |ch|
+        a << if ch < "\x20"
+          case ch 
+          when "\x08"
+            "\\b"
+          when "\x0c"
+            "\\f"
+          when "\x0a"
+            "\\n"
+          when "\x0d"
+            "\\r"
+          when "\x09"
+            "\\t"
+          else
+            raise GeneratorError, "cannot convert #{ch.inspect} to JSON"
+          end
+        elsif ch == '"'
+          '\\"'
+        elsif ch == '\\'
+          "\\\\"
+        else
+          ch
+        end
+      }
+      return '"' + a.join + '"'
+    end
+  end
+
+  def self.load(source)  # TODO: proc, options
+    source = source.read unless source.is_a? String
+    JSON.parse source
+  end
+  
+  class JSONError < StandardError; end
+  class GeneratorError < JSONError; end
+  class ParserError < JSONError; end
+  class NestingError < ParserError; end
+end
+
+unless Float.method_defined? :nan?
+  class Float
+    def nan?
+      not (self == self)
+    end
+  end
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-iijson/mrblib/to_json.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-iijson/mrblib/to_json.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-iijson/mrblib/to_json.rb	(revision 331)
@@ -0,0 +1,47 @@
+class Array
+  def to_json
+    JSON.generate(self)
+  end
+end
+
+class FalseClass
+  def to_json
+    JSON.generate(self)
+  end
+end
+
+class Fixnum
+  def to_json
+    JSON.generate(self)
+  end
+end
+
+class Float
+  def to_json
+    JSON.generate(self)
+  end
+end
+
+class Hash
+  def to_json
+    JSON.generate(self)
+  end
+end
+
+class NilClass
+  def to_json
+    JSON.generate(self)
+  end
+end
+
+class String
+  def to_json
+    JSON.generate(self)
+  end
+end
+
+class TrueClass
+  def to_json
+    JSON.generate(self)
+  end
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-iijson/run_test.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-iijson/run_test.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-iijson/run_test.rb	(revision 331)
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+#
+# mrbgems test runner
+#
+
+if __FILE__ == $0
+  repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby'
+  build_args = ARGV
+
+  Dir.mkdir 'tmp'  unless File.exist?('tmp')
+  unless File.exist?(dir)
+    system "git clone #{repository} #{dir}"
+  end
+
+  exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}])
+end
+
+MRuby::Build.new do |conf|
+  toolchain :gcc
+  conf.gembox 'default'
+
+  conf.gem File.expand_path(File.dirname(__FILE__))
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-iijson/src/json.c
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-iijson/src/json.c	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-iijson/src/json.c	(revision 331)
@@ -0,0 +1,641 @@
+#include <ctype.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include "mruby.h"
+#include "mruby/array.h"
+#include "mruby/hash.h"
+#include "mruby/string.h"
+#include "mruby/value.h"
+
+#define E_JSON_PARSER_ERROR (mrb_class_get_under(mrb, mrb_module_get(mrb, "JSON"), "ParserError"))
+
+#define JSON_EOF -1
+
+#define DEFAULT_MAX_NESTING 100
+
+struct json_parser {
+  mrb_state *mrb;
+  mrb_value src;
+  unsigned int cursor;
+  unsigned int lineno;
+  int nesting;
+
+  int max_nesting;
+};
+
+static void json_check_nesting(struct json_parser *);
+static int json_delimiter_p(char ch);
+static int json_getc(struct json_parser *);
+static void json_skip_ws(struct json_parser *);
+static void json_ungetc(struct json_parser *);
+static int json_unicode2utf8(uint32_t, char *);
+static int json_whitespace_p(char ch);
+
+static int json_parse_array(struct json_parser *, mrb_value *);
+static int json_parse_object(struct json_parser *, mrb_value *);
+static int json_parse_number2(struct json_parser *, int, mrb_value *, mrb_int, int);
+static int json_parse_string(struct json_parser *, mrb_value *);
+static int json_parse_value(struct json_parser *, mrb_value *);
+
+#if MRUBY_RELEASE_NO < 10000
+static struct RClass *
+mrb_module_get(mrb_state *mrb, const char *name)
+{
+  return mrb_class_get(mrb, name);
+}
+#endif
+#if !defined(MRB_PRId)
+#if defined(MRB_INT64)
+# define MRB_PRId PRId64
+#elif defined(MRB_INT16)
+# define MRB_PRId PRId16
+#else
+# define MRB_PRId PRId32
+#endif
+#endif  /* !defined(MRB_PRId) */
+
+static void
+json_check_nesting(struct json_parser *parser)
+{
+  mrb_state *mrb = parser->mrb;
+
+  if (parser->max_nesting != -1) {
+    if (parser->nesting >= parser->max_nesting) {
+      // +1 for compatibility with CRuby
+      mrb_raisef(mrb, E_JSON_PARSER_ERROR, "nesting of %S is too deep", mrb_fixnum_value(parser->nesting+1));
+    }
+  }
+}
+
+static int
+json_delimiter_p(char ch)
+{
+  return (json_whitespace_p(ch) || ch == ',' || ch == ']' || ch == '}');
+}
+
+static int
+json_getc(struct json_parser *parser)
+{
+  if (parser->cursor < RSTRING_LEN(parser->src)) {
+    unsigned char ch = RSTRING_PTR(parser->src)[parser->cursor];
+    parser->cursor++;
+    return ch;
+  } else {
+    return JSON_EOF;
+  }
+}
+
+static int
+json_parse_readstring(struct json_parser *parser, const char *str)
+{
+  size_t len;
+  int ch;
+
+  len = strlen(str);
+  if (parser->cursor + len > RSTRING_LEN(parser->src))
+    return 0;
+  if (memcmp(str, RSTRING_PTR(parser->src) + parser->cursor, len) != 0)
+    return -1;
+  parser->cursor += len;
+  if (parser->cursor == RSTRING_LEN(parser->src))
+    return 1;
+  ch = RSTRING_PTR(parser->src)[parser->cursor];
+  if (!json_delimiter_p(ch))
+    return -1;
+  return 1;
+}
+
+static void
+json_skip_ws(struct json_parser *parser)
+{
+  int ch;
+
+  do {
+    ch = json_getc(parser);
+    if (ch == 0x0a)
+      parser->lineno++;
+  } while (json_whitespace_p(ch));
+  if (ch != JSON_EOF) {
+    json_ungetc(parser);
+  }
+}
+
+static void
+json_ungetc(struct json_parser *parser)
+{
+  if (parser->cursor > 0)
+    parser->cursor--;
+}
+
+static int
+json_unicode2utf8(uint32_t unicode, char *cp)
+{
+  int n = 0;
+  if (unicode < 0x80) {
+    cp[n++] = unicode;
+  } else if (unicode < 0x800) {
+    cp[n++] = 0xc0 + (unicode >> 6);
+    cp[n++] = 0x80 + (unicode & 0x3f);
+  } else if (unicode < 0x10000) {
+    cp[n++] = 0xe0 + (unicode >> 12);
+    cp[n++] = 0x80 + ((unicode >> 6) & 0x3f);
+    cp[n++] = 0x80 + (unicode & 0x3f);
+  } else {
+    cp[n++] = 0xf0 + (unicode >> 18);
+    cp[n++] = 0x80 + ((unicode >> 12) & 0x3f);
+    cp[n++] = 0x80 + ((unicode >> 6) & 0x3f);
+    cp[n++] = 0x80 + (unicode & 0x3f);
+  }
+  return n;
+}
+
+static int
+json_whitespace_p(char ch)
+{
+  return (ch == 0x20 || ch == 0x09 || ch == 0x0a || ch == 0x0d);
+}
+
+static int
+json_parse_array(struct json_parser *parser, mrb_value *result)
+{
+  mrb_state *mrb = parser->mrb;
+  mrb_value ary, v;
+  int ch;
+
+  json_check_nesting(parser);
+
+  ary = mrb_ary_new(mrb);
+
+  json_skip_ws(parser);
+  ch = json_getc(parser);
+  if (ch == ']') { /* easy case */
+    *result = ary;
+    return 1;
+  }
+  if (ch == JSON_EOF) {
+    mrb_raise(mrb, E_JSON_PARSER_ERROR, "JSON_EOF in array(1)");
+  }
+  json_ungetc(parser);
+
+  while (1) {
+    parser->nesting++;
+    if (json_parse_value(parser, &v) != 1) {
+      mrb_raise(mrb, E_JSON_PARSER_ERROR, "error in array");
+    }
+    parser->nesting--;
+
+    mrb_ary_push(mrb, ary, v);
+
+    json_skip_ws(parser);
+    ch = json_getc(parser);
+    if (ch == ']') {
+      break;
+    }
+    if (ch == JSON_EOF) {
+      mrb_raise(mrb, E_JSON_PARSER_ERROR, "JSON_EOF in array(2)");
+    }
+    if (ch != ',') {
+      mrb_raise(mrb, E_JSON_PARSER_ERROR, "not ',' in array");
+    }
+  }
+  *result = ary;
+  return 1;
+}
+
+static int
+json_parse_object(struct json_parser *parser, mrb_value *result)
+{
+  mrb_state *mrb = parser->mrb;
+  mrb_value h, k, v;
+  int ch;
+
+  json_check_nesting(parser);
+
+  h = mrb_hash_new(mrb);
+
+  json_skip_ws(parser);
+  ch = json_getc(parser);
+  if (ch == '}') { /* easy case */
+    *result = h;
+    return 1;
+  }
+  if (ch == JSON_EOF) {
+    mrb_raise(mrb, E_JSON_PARSER_ERROR, "EOF in object(1)");
+  }
+  json_ungetc(parser);
+
+  while (1) {
+    parser->nesting++;
+    if (json_parse_value(parser, &k) != 1) {
+      mrb_raise(mrb, E_JSON_PARSER_ERROR, "error in object key");
+    }
+    parser->nesting--;
+    if (! mrb_string_p(k)) {
+      mrb_raise(mrb, E_JSON_PARSER_ERROR, "key is not a string");
+    }
+
+    json_skip_ws(parser);
+
+    ch = json_getc(parser);
+    if (ch == JSON_EOF) {
+      mrb_raise(mrb, E_JSON_PARSER_ERROR, "EOF in object(2)");
+    }
+    if (ch != ':') {
+      mrb_raise(mrb, E_JSON_PARSER_ERROR, "no ':' in object");
+    }
+
+    parser->nesting++;
+    if (json_parse_value(parser, &v) != 1) {
+      mrb_raise(mrb, E_JSON_PARSER_ERROR, "error in object value");
+    }
+    parser->nesting--;
+
+    mrb_hash_set(mrb, h, k, v);
+
+    json_skip_ws(parser);
+    ch = json_getc(parser);
+    if (ch == '}') {
+      break;
+    }
+    if (ch == JSON_EOF) {
+      mrb_raise(mrb, E_JSON_PARSER_ERROR, "EOF in object(3)");
+    }
+    if (ch != ',') {
+      mrb_raise(mrb, E_JSON_PARSER_ERROR, "no ',' in object");
+    }
+  }
+  *result = h;
+  return 1;
+}
+
+static int
+json_parse_number(struct json_parser *parser, int ch, mrb_value *result)
+{
+  mrb_state *mrb = parser->mrb;
+  mrb_int num;
+  int d, sign;
+
+  if (ch == '-') {
+    sign = -1;
+    ch = json_getc(parser);
+    if (ch == JSON_EOF) {
+      mrb_raise(mrb, E_JSON_PARSER_ERROR, "no character following minus");
+    }
+    if (!isdigit(ch)) {
+      mrb_raise(mrb, E_JSON_PARSER_ERROR, "character following minus is not a digit");
+    }
+  } else {
+    sign = 1;
+  }
+  num = (ch - '0') * sign;
+  while (1) {
+    ch = json_getc(parser);
+    if (ch == JSON_EOF) {
+      break;
+    }
+    if (isdigit(ch)) {
+      if (num == 0) {
+        mrb_raise(mrb, E_JSON_PARSER_ERROR, "leading zeros are not allowed");
+      }
+      d = (ch - '0') * sign;
+      if (num < MRB_INT_MIN / 10 ||
+          (num == MRB_INT_MIN / 10 && d < MRB_INT_MIN - num * 10) ||
+          num > MRB_INT_MAX / 10 ||
+          (num == MRB_INT_MAX / 10 && d > MRB_INT_MAX - num * 10)) {
+        return json_parse_number2(parser, ch, result, num, sign);
+      }
+      num = num * 10 + d;
+    } else if (ch == '.' || ch == 'e' || ch == 'E') {
+      return json_parse_number2(parser, ch, result, num, sign);
+    } else if (json_delimiter_p(ch)) {
+      json_ungetc(parser);
+      break;
+    } else {
+      mrb_raise(mrb, E_JSON_PARSER_ERROR, "invalid number");
+    }
+  }
+  *result = mrb_fixnum_value(num);
+  return 1;
+}
+
+static int
+json_parse_number2(struct json_parser *parser, int ch, mrb_value *result, mrb_int num, int sign)
+{
+  mrb_state *mrb = parser->mrb;
+  double d;
+  int i, state;
+  char buf[64];
+
+  /*
+   * "-"? ("0" | [1-9] digit* ) ("." digit+ )? ([eE][-+] digit+)?
+   * state:            000000    111 222222     33334444 555555
+   */
+  i = snprintf(buf, sizeof(buf), "%s%"MRB_PRId"%c",
+      (num == 0 && sign < 0) ? "-" : "",
+      num, ch);
+
+  if (isdigit(ch))
+    state = 0;
+  else if (ch == '.')
+    state = 1;
+  else /* (ch == 'e' || ch == 'E') */
+    state = 3;
+
+  while (1) {
+    ch = json_getc(parser);
+    if (ch == JSON_EOF)
+      break;
+    switch (state) {
+      case 0:
+        if (isdigit(ch))
+          ; /* read more digits */
+        else if (ch == '.')
+          state = 1;
+        else if (ch == 'e' || ch == 'E')
+          state = 3;
+        else if (json_delimiter_p(ch)) {
+          json_ungetc(parser);
+          state = -1;
+        } else
+          goto formaterr;
+        break;
+      case 1:
+        if (!isdigit(ch))
+          goto formaterr;
+        state = 2;
+        break;
+      case 2:
+        if (isdigit(ch))
+          ; /* read more digits */
+        else if (ch == 'e' || ch == 'E')
+          state = 3;
+        else if (json_delimiter_p(ch)) {
+          json_ungetc(parser);
+          state = -1;
+        } else
+          goto formaterr;
+        break;
+      case 3:
+        if (ch == '-' || ch == '+')
+          state = 4;
+        else if (isdigit(ch))
+          state = 5;
+        else
+          goto formaterr;
+        break;
+      case 4:
+        if (!isdigit(ch))
+          goto formaterr;
+        state = 5;
+        break;
+      case 5:
+      default:
+        if (isdigit(ch))
+          ; /* read more digits */
+        else {
+          json_ungetc(parser);
+          state = -1;
+        }
+        break;
+    }
+    if (state == -1)
+      break;
+    if (i == sizeof(buf) - 1) {
+      mrb_raise(mrb, E_JSON_PARSER_ERROR, "floating point number too long");
+    }
+    buf[i++] = ch;
+  }
+  buf[i] = '\0';
+  sscanf(buf, "%lf", &d);
+  *result = mrb_float_value(mrb, d);
+  return 1;
+
+formaterr:
+  mrb_raise(mrb, E_JSON_PARSER_ERROR, "floating point number error");
+  return -1;
+}
+
+static int
+json_parse_string(struct json_parser *parser, mrb_value *result)
+{
+  mrb_state *mrb = parser->mrb;
+  mrb_value str;
+  uint32_t unicode;
+  uint16_t utf16;
+  int ch, i, n;
+  char *cp;
+
+  str = mrb_str_buf_new(mrb, 30);
+  cp = RSTRING_PTR(str);
+  n = 0;
+  unicode = 0;
+
+  while (1) {
+    ch = json_getc(parser);
+    if (ch == JSON_EOF) {
+      mrb_raise(mrb, E_JSON_PARSER_ERROR, "EOF in string");
+    }
+    
+    if (ch == '"') {
+      break;
+    } else if (ch == '\\') {
+      ch = json_getc(parser);
+      if (ch == JSON_EOF) {
+        mrb_raise(mrb, E_JSON_PARSER_ERROR, "EOF following escape char");
+      }
+      switch (ch) {
+        case '"':
+        case '\\':
+        case '/':
+          break;
+        case 'b':
+          ch = 0x08;
+          break;
+        case 'f':
+          ch = 0x0c;
+          break;
+        case 'n':
+          ch = 0x0a;
+          break;
+        case 'r':
+          ch = 0x0d;
+          break;
+        case 't':
+          ch = 0x09;
+          break;
+        case 'u':
+          utf16 = 0;
+          for (i = 0; i < 4; i++) {
+            ch = json_getc(parser);
+            if (ch == JSON_EOF) {
+              mrb_raise(mrb, E_JSON_PARSER_ERROR, "invalid unicode escape");
+            }
+            if (ch >= '0' && ch <= '9') {
+              ch -= '0';
+            } else if (ch >= 'A' && ch <= 'F') {
+              ch = (ch - 'A') + 10;
+            } else if (ch >= 'a' && ch <= 'f') {
+              ch = (ch - 'a') + 10;
+            } else {
+              mrb_raise(mrb, E_JSON_PARSER_ERROR, "invalid unicode character");
+            }
+            utf16 *= 16;
+            utf16 += ch;
+          }
+
+          if (n + 8 >= RSTRING_CAPA(str)) {
+            mrb_str_resize(mrb, str, RSTRING_CAPA(str)*2);
+            cp = RSTRING_PTR(str);
+          }
+
+          if ((utf16 & 0xf800) == 0xd800) {
+            if ((utf16 & 0xfc00) == 0xd800) {
+              /* high surrogate */
+              unicode = utf16;
+              continue;
+            } else {
+              /* low surrogate */
+              if (unicode > 0) {
+                unicode = ((unicode & 0x03ff) + 0x040) << 10;
+                unicode += utf16 & 0x03ff;
+              } else {
+                /* error: low surrogate comes first... */
+              }
+            }
+          } else {
+            if (unicode > 0) {
+              /* error: high surrogate not followed by low surrogate */
+              n += json_unicode2utf8(unicode, &cp[n]);
+            }
+            unicode = utf16;
+          }
+
+          n += json_unicode2utf8(unicode, &cp[n]);
+          unicode = 0;
+          continue;
+        default:
+          mrb_raise(mrb, E_JSON_PARSER_ERROR, "invalid escape char");
+          break;
+      }
+    } else if (ch < 0x20) {
+      mrb_raise(mrb, E_JSON_PARSER_ERROR, "invalid char");
+    }
+
+    if (n + 1 == RSTRING_CAPA(str)) {
+      mrb_str_resize(mrb, str, RSTRING_CAPA(str)*2);
+      cp = RSTRING_PTR(str);
+    }
+    cp[n++] = ch;
+  }
+  cp[n] = '\0';
+  mrb_str_resize(mrb, str, n);
+  *result = str;
+  return 1;
+}
+
+static int
+json_parse_value(struct json_parser *parser, mrb_value *result)
+{
+  mrb_state *mrb = parser->mrb;
+  int ch;
+
+  do {
+    ch = json_getc(parser);
+    if (ch == JSON_EOF)
+      return 0;
+  } while (json_whitespace_p(ch));
+
+  switch (ch) {
+    case '0': case '1': case '2': case '3': case '4':
+    case '5': case '6': case '7': case '8': case '9':
+    case '-':
+      if (json_parse_number(parser, ch, result) != 1) {
+        mrb_raise(mrb, E_JSON_PARSER_ERROR, "number...?");
+      }
+      break;
+
+    case '"':
+      if (json_parse_string(parser, result) != 1) {
+        mrb_raise(mrb, E_JSON_PARSER_ERROR, "string...?");
+      }
+      break;
+
+    case '[':
+      if (json_parse_array(parser, result) != 1) {
+        mrb_raise(mrb, E_JSON_PARSER_ERROR, "array...?");
+      }
+      break;
+
+    case '{':
+      if (json_parse_object(parser, result) != 1) {
+        mrb_raise(mrb, E_JSON_PARSER_ERROR, "object...?");
+      }
+      break;
+
+    case 'f':
+      if (json_parse_readstring(parser, "alse") != 1) {
+        mrb_raise(mrb, E_JSON_PARSER_ERROR, "unexpected f");
+      }
+      *result = mrb_false_value();
+      break;
+
+    case 'n':
+      if (json_parse_readstring(parser, "ull") != 1) {
+        mrb_raise(mrb, E_JSON_PARSER_ERROR, "unexpected n");
+      }
+      *result = mrb_nil_value();
+      break;
+
+    case 't':
+      if (json_parse_readstring(parser, "rue") != 1) {
+        mrb_raise(mrb, E_JSON_PARSER_ERROR, "unexpected t");
+      }
+      *result = mrb_true_value();
+      break;
+
+    default:
+      mrb_raise(mrb, E_JSON_PARSER_ERROR, "unexpected character");
+  }
+
+  return 1;
+}
+
+static mrb_value
+mrb_json_parse(mrb_state *mrb, mrb_value mod)
+{
+  struct json_parser parser;
+  mrb_value obj, options, source;
+
+  mrb_get_args(mrb, "S|H", &source, &options);
+
+  parser.mrb         = mrb;
+  parser.src         = source;
+  parser.cursor      = 0;
+  parser.lineno      = 0;
+  parser.nesting     = 0;
+  parser.max_nesting = DEFAULT_MAX_NESTING;
+
+  if (json_parse_value(&parser, &obj) == 0) {
+    mrb_raise(mrb, E_JSON_PARSER_ERROR, "no JSON value");
+  }
+
+  // if we have extra characters:
+  // unexpected token at '3' (JSON::ParserError)
+
+  return obj;
+}
+
+void
+mrb_mruby_iijson_gem_init(mrb_state *mrb)
+{
+  struct RClass *m;
+
+  m = mrb_define_module(mrb, "JSON");
+  mrb_define_module_function(mrb, m, "parse", mrb_json_parse, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1));
+}
+
+void
+mrb_mruby_iijson_gem_final(mrb_state *mrb)
+{
+}
Index: EcnlProtoTool/trunk/mrbgems/mruby-iijson/test/json.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-iijson/test/json.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-iijson/test/json.rb	(revision 331)
@@ -0,0 +1,145 @@
+assert('JSON.dump') do
+  class JsonTestIo
+    def initialize
+      @buf = ""
+    end
+    def write(str)
+      @buf += str
+    end
+    attr_reader :buf
+  end
+  assert_equal "[1]", JSON.dump([1])
+
+  jio = JsonTestIo.new
+  JSON.dump(["abc"], jio)
+  assert_equal '["abc"]', jio.buf
+
+  assert_raise(ArgumentError) do
+    JSON.dump({:a => {:b => {} } }, nil, 2)
+  end
+  JSON.dump({:a=>{:b=>{}}}, nil, 3)  # should not raise
+end
+
+assert('JSON.generate: false') do
+  assert_equal "false", JSON.generate(false)
+end
+
+assert('JSON.generate: null') do
+  assert_equal "null", JSON.generate(nil)
+end
+
+assert('JSON.generate: true') do
+  assert_equal "true", JSON.generate(true)
+end
+
+assert('JSON.generate: object') do
+  assert_equal '{"key":"value"}', JSON.generate({ "key" => "value" })
+  assert_equal '{"ten":10}', JSON.generate({ :ten => 10 })
+end
+
+assert('JSON.generate: array') do
+  assert_equal '[null,1,"two"]', JSON.generate([ nil, 1, "two"])
+end
+
+assert('JSON.generate: number (Fixnum)') do
+  str = JSON.generate [1]
+  assert_equal "[1]", str
+end
+
+assert('JSON.generate: number (Float)') do
+  str = JSON.generate [134.625]
+  assert_equal "[134.625]", str
+end
+
+assert('JSON.generate: string') do
+  assert_equal "\"abc\"", JSON.generate("abc")
+  assert_equal "\"\\\"\\\\/\\b\\f\\n\\r\\t\"",
+    JSON.generate("\x22\x5c\x2f\x08\x0c\x0a\x0d\x09")
+end
+
+assert('JSON.load') do
+  assert_equal [1,2,3], JSON.load("[1,2,3]")
+
+  class JsonTestReader
+    def read
+      '{"abc":123}'
+    end
+  end
+  assert_equal({"abc"=>123}, JSON.load(JsonTestReader.new))
+end
+
+assert('JSON.parse: text from RFC4726') do
+  str = '{
+    "Image": {
+      "Width":  800,
+      "Height": 600,
+      "Title":  "View from 15th Floor",
+      "Thumbnail": {
+        "Url":    "http://www.example.com/image/481989943",
+        "Height": 125,
+        "Width":  "100"
+      },
+      "IDs": [116, 943, 234, 38793]
+    }
+  }'
+  hash = {
+    "Image" => {
+      "Width" => 800,
+      "Height" => 600,
+      "Title" => "View from 15th Floor",
+      "Thumbnail" => {
+        "Url" => "http://www.example.com/image/481989943",
+        "Height" => 125,
+        "Width" => "100"
+      },
+      "IDs" => [116, 943, 234, 38793]
+    }
+  }
+  assert_equal hash, JSON.parse(str)
+
+  # We cannot compare `str` with `JSON.generate(hash)` because Hash entries
+  # will be in a random order.
+  assert_equal hash, JSON.parse(JSON.generate(hash))
+end
+
+assert('JSON::ParserError') do
+  assert_raise(JSON::ParserError) do
+    JSON.parse "[xxx]"
+  end
+end
+
+assert('JSON.parse: empty string is not a valid JSON text') do
+  assert_raise(JSON::ParserError) do
+    JSON.parse ""
+  end
+end
+
+assert('JSON.parse: parsing numbers around MRB_INT_MIN/MRB_INT_MAX') do
+  int_min = TestJSON::MRB_INT_MIN
+  int_max = TestJSON::MRB_INT_MAX
+
+  assert_kind_of Fixnum, JSON.load(int_min.to_s)
+  assert_equal int_min, JSON.load(int_min.to_s)
+
+  assert_kind_of Fixnum, JSON.load(int_max.to_s)
+  assert_equal int_max, JSON.load(int_max.to_s)
+
+  assert_kind_of Float, JSON.load((int_min-1).to_s)
+  assert_float (int_min-1)/int_min, JSON.load((int_min-1).to_s)/int_min
+
+  assert_kind_of Float, JSON.load((int_max+1).to_s)
+  assert_float (int_max+1)/int_max, JSON.load((int_max+1).to_s)/int_max
+end
+
+assert('#to_json') do
+  assert_equal 'false',     false.to_json
+  assert_equal 'null',      nil.to_json
+  assert_equal 'true',      true.to_json
+  assert_equal '1',         1.to_json
+  assert_equal '3.125',      3.125.to_json
+  assert_equal '"str"',     "str".to_json
+  assert_equal '["one",2]', [ "one", 2 ].to_json
+  assert_equal '{"a":1}',   { "a" => 1 }.to_json
+  assert_equal TestJSON::MRB_INT_MIN.to_s, TestJSON::MRB_INT_MIN.to_json
+  assert_equal TestJSON::MRB_INT_MAX.to_s, TestJSON::MRB_INT_MAX.to_json
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-iijson/test/testjson.c
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-iijson/test/testjson.c	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-iijson/test/testjson.c	(revision 331)
@@ -0,0 +1,11 @@
+#include "mruby.h"
+#include "mruby/value.h"
+#include "mruby/variable.h"
+
+void
+mrb_mruby_iijson_gem_test(mrb_state* mrb)
+{
+  struct RClass *c = mrb_define_module(mrb, "TestJSON");
+  mrb_const_set(mrb, mrb_obj_value(c), mrb_intern_lit(mrb, "MRB_INT_MIN"), mrb_fixnum_value(MRB_INT_MIN));
+  mrb_const_set(mrb, mrb_obj_value(c), mrb_intern_lit(mrb, "MRB_INT_MAX"), mrb_fixnum_value(MRB_INT_MAX));
+}
Index: EcnlProtoTool/trunk/mrbgems/mruby-io/README.md
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-io/README.md	(revision 321)
+++ EcnlProtoTool/trunk/mrbgems/mruby-io/README.md	(revision 331)
@@ -1,6 +1,8 @@
 mruby-io
 ========
+[![Build Status](https://travis-ci.org/iij/mruby-io.svg?branch=master)](https://travis-ci.org/iij/mruby-io)
 
-IO, File module for mruby
+
+`IO` and `File` classes for mruby
 
 ## Installation
@@ -63,5 +65,5 @@
 | IO#internal_encoding       |          |      |
 | IO#ioctl                   |          |      |
-| IO#isatty, IO#tty?         |          |      |
+| IO#isatty, IO#tty?         |    o     |      |
 | IO#lineno                  |          |      |
 | IO#lineno=                 |          |      |
@@ -107,5 +109,5 @@
 | File.blockdev?              |          | FileTest |
 | File.chardev?               |          | FileTest |
-| File.chmod                  |          |      |
+| File.chmod                  |   o      |      |
 | File.chown                  |          |      |
 | File.ctime                  |          |      |
@@ -135,5 +137,5 @@
 | File.readable?              |          | FileTest |
 | File.readable_real?         |          | FileTest |
-| File.readlink               |          |      |
+| File.readlink               |   o      |      |
 | File.realdirpath            |          |      |
 | File.realpath               |   o      |      |
Index: EcnlProtoTool/trunk/mrbgems/mruby-io/mrblib/io.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-io/mrblib/io.rb	(revision 321)
+++ EcnlProtoTool/trunk/mrbgems/mruby-io/mrblib/io.rb	(revision 331)
@@ -124,12 +124,10 @@
     str = string.is_a?(String) ? string : string.to_s
     return str.size unless str.size > 0
-
+    if 0 < @buf.length
+      # reset real pos ignore buf
+      seek(pos, SEEK_SET)
+    end
     len = syswrite(str)
-    if len != -1
-      @pos += len
-      return len
-    end
-
-    raise IOError
+    len
   end
 
@@ -152,5 +150,5 @@
   def pos
     raise IOError if closed?
-    @pos
+    sysseek(0, SEEK_CUR) - @buf.length
   end
   alias_method :tell, :pos
@@ -166,5 +164,5 @@
   def seek(i, whence = SEEK_SET)
     raise IOError if closed?
-    @pos = sysseek(i, whence)
+    sysseek(i, whence)
     @buf = ''
     0
@@ -178,5 +176,4 @@
   def ungetc(substr)
     raise TypeError.new "expect String, got #{substr.class}" unless substr.is_a?(String)
-    @pos -= substr.size
     if @buf.empty?
       @buf = substr.dup
@@ -187,5 +184,5 @@
   end
 
-  def read(length = nil)
+  def read(length = nil, outbuf = "")
     unless length.nil?
       unless length.is_a? Fixnum
@@ -201,27 +198,30 @@
 
     array = []
-    start_pos = @pos
     while 1
       begin
         _read_buf
-      rescue EOFError => e
+      rescue EOFError
         array = nil if array.empty? and (not length.nil?) and length != 0
         break
       end
 
-      if length && (@pos - start_pos + @buf.size) >= length
-        len = length - (@pos - start_pos)
-        array.push @buf[0, len]
-        @pos += len
-        @buf = @buf[len, @buf.size - len]
-        break
+      if length
+        consume = (length <= @buf.size) ? length : @buf.size
+        array.push @buf[0, consume]
+        @buf = @buf[consume, @buf.size - consume]
+        length -= consume
+        break if length == 0
       else
         array.push @buf
-        @pos += @buf.size
         @buf = ''
       end
     end
 
-    array && array.join
+    if array.nil?
+      outbuf.replace("")
+      nil
+    else
+      outbuf.replace(array.join)
+    end
   end
 
@@ -246,28 +246,23 @@
 
     array = []
-    start_pos = @pos
     while 1
       begin
         _read_buf
-      rescue EOFError => e
+      rescue EOFError
         array = nil if array.empty?
         break
       end
 
-      if limit && (@pos - start_pos + @buf.size) >= limit
-        len = limit - (@pos - start_pos)
-        array.push @buf[0, len]
-        @pos += len
-        @buf = @buf[len, @buf.size - len]
+      if limit && limit <= @buf.size
+        array.push @buf[0, limit]
+        @buf = @buf[limit, @buf.size - limit]
         break
       elsif idx = @buf.index(rs)
         len = idx + rs.size
         array.push @buf[0, len]
-        @pos += len
         @buf = @buf[len, @buf.size - len]
         break
       else
         array.push @buf
-        @pos += @buf.size
         @buf = ''
       end
@@ -282,5 +277,5 @@
     begin
       readline(*args)
-    rescue EOFError => e
+    rescue EOFError
       nil
     end
@@ -291,5 +286,4 @@
     c = @buf[0]
     @buf = @buf[1, @buf.size]
-    @pos += 1
     c
   end
@@ -298,5 +292,5 @@
     begin
       readchar
-    rescue EOFError => e
+    rescue EOFError
       nil
     end
Index: EcnlProtoTool/trunk/mrbgems/mruby-io/src/file.c
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-io/src/file.c	(revision 321)
+++ EcnlProtoTool/trunk/mrbgems/mruby-io/src/file.c	(revision 331)
@@ -46,10 +46,4 @@
   #include <pwd.h>
 #endif
-#if defined(__NEWLIB__)
-  #define _MAX_DIR		253
-  #define _MAX_DRIVE	2
-  #define PATH_MAX		(_MAX_DRIVE + _MAX_DIR)
-  #define MAXPATHLEN	(_MAX_DRIVE + _MAX_DIR)
-#endif
 
 #define FILE_SEPARATOR "/"
@@ -81,5 +75,5 @@
 mrb_file_s_umask(mrb_state *mrb, mrb_value klass)
 {
-#if defined(_WIN32) || defined(_WIN64) || defined(__NEWLIB__)
+#if defined(_WIN32) || defined(_WIN64)
   /* nothing to do on windows */
   return mrb_fixnum_value(0);
@@ -126,7 +120,9 @@
   dst = mrb_string_value_cstr(mrb, &to);
   if (rename(src, dst) < 0) {
+#if defined(_WIN32) || defined(_WIN64)
     if (CHMOD(dst, 0666) == 0 && UNLINK(dst) == 0 && rename(src, dst) == 0) {
       return mrb_fixnum_value(0);
     }
+#endif
     mrb_sys_fail(mrb, mrb_str_to_cstr(mrb, mrb_format(mrb, "(%S, %S)", from, to)));
   }
@@ -253,5 +249,5 @@
 mrb_file__gethome(mrb_state *mrb, mrb_value klass)
 {
-#if !defined(_WIN32) && !defined(_WIN64) && !defined(__NEWLIB__)
+#ifndef _WIN32
   mrb_value username;
   int argc;
@@ -288,5 +284,5 @@
 mrb_file_flock(mrb_state *mrb, mrb_value self)
 {
-#if defined(_WIN32) || defined(_WIN64) || defined(sun) || defined(__NEWLIB__)
+#if defined(_WIN32) || defined(_WIN64) || defined(sun)
   mrb_raise(mrb, E_NOTIMP_ERROR, "flock is not supported on Illumos/Solaris/Windows");
 #else
@@ -322,5 +318,5 @@
 mrb_file_s_symlink(mrb_state *mrb, mrb_value klass)
 {
-#if defined(_WIN32) || defined(_WIN64) || defined(__NEWLIB__)
+#if defined(_WIN32) || defined(_WIN64)
   mrb_raise(mrb, E_NOTIMP_ERROR, "symlink is not supported on this platform");
 #else
@@ -362,5 +358,5 @@
 static mrb_value
 mrb_file_s_readlink(mrb_state *mrb, mrb_value klass) {
-#if defined(_WIN32) || defined(_WIN64) || defined(__NEWLIB__)
+#if defined(_WIN32) || defined(_WIN64)
   mrb_raise(mrb, E_NOTIMP_ERROR, "readlink is not supported on this platform");
   return mrb_nil_value(); // unreachable
Index: EcnlProtoTool/trunk/mrbgems/mruby-io/src/file_test.c
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-io/src/file_test.c	(revision 321)
+++ EcnlProtoTool/trunk/mrbgems/mruby-io/src/file_test.c	(revision 331)
@@ -22,6 +22,5 @@
   #include <winsock.h>
 #else
-  //#define LSTAT lstat
-  #define LSTAT stat
+  #define LSTAT lstat
   #include <sys/file.h>
   #include <sys/param.h>
Index: EcnlProtoTool/trunk/mrbgems/mruby-io/src/io.c
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-io/src/io.c	(revision 321)
+++ EcnlProtoTool/trunk/mrbgems/mruby-io/src/io.c	(revision 331)
@@ -190,5 +190,5 @@
 }
 
-#if !defined(_WIN32) && !defined(_WIN64) && !defined(__NEWLIB__)
+#ifndef _WIN32
 static int
 mrb_cloexec_pipe(mrb_state *mrb, int fildes[2])
@@ -265,5 +265,5 @@
 #endif
 
-#if !defined(_WIN32) && !defined(_WIN64) && !defined(__NEWLIB__)
+#ifndef _WIN32
 static int
 option_to_fd(mrb_state *mrb, mrb_value obj, const char *key)
@@ -390,5 +390,4 @@
 
       mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@buf"), mrb_str_new_cstr(mrb, ""));
-      mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@pos"), mrb_fixnum_value(0));
 
       fptr = mrb_io_alloc(mrb);
@@ -444,5 +443,4 @@
 
   mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@buf"), mrb_str_new_cstr(mrb, ""));
-  mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@pos"), mrb_fixnum_value(0));
 
   fptr = (struct mrb_io *)DATA_PTR(io);
@@ -488,5 +486,5 @@
   }
 
-#if !defined(_WIN32) && !defined(_WIN64) && !defined(__NEWLIB__)
+#if !defined(_WIN32) && !defined(_WIN64)
   if (fptr->pid != 0) {
     pid_t pid;
@@ -557,4 +555,5 @@
 mrb_cloexec_open(mrb_state *mrb, const char *pathname, mrb_int flags, mrb_int mode)
 {
+  mrb_value emsg;
   int fd, retry = FALSE;
 
@@ -577,5 +576,8 @@
       }
     }
-    mrb_sys_fail(mrb, "open");
+
+    emsg = mrb_format(mrb, "open %S", mrb_str_new_cstr(mrb, pathname));
+    mrb_str_modify(mrb, mrb_str_ptr(emsg));
+    mrb_sys_fail(mrb, RSTRING_PTR(emsg));
   }
 
@@ -620,5 +622,8 @@
   mrb_get_args(mrb, "i|S", &maxlen, &buf);
   if (maxlen < 0) {
-    return mrb_nil_value();
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "negative expanding string size");
+  }
+  else if (maxlen == 0) {
+    return mrb_str_new(mrb, NULL, maxlen);
   }
 
@@ -626,9 +631,15 @@
     buf = mrb_str_new(mrb, NULL, maxlen);
   }
+
   if (RSTRING_LEN(buf) != maxlen) {
     buf = mrb_str_resize(mrb, buf, maxlen);
-  }
-
-  fptr = (struct mrb_io *)mrb_get_datatype(mrb, io, &mrb_io_type);
+  } else {
+    mrb_str_modify(mrb, RSTRING(buf));
+  }
+
+  fptr = (struct mrb_io *)io_get_open_fptr(mrb, io);
+  if (!fptr->readable) {
+    mrb_raise(mrb, E_IO_ERROR, "not opened for reading");
+  }
   ret = read(fptr->fd, RSTRING_PTR(buf), maxlen);
   switch (ret) {
@@ -702,4 +713,7 @@
   }
   length = write(fd, RSTRING_PTR(buf), RSTRING_LEN(buf));
+  if (length == -1) {
+    mrb_sys_fail(mrb, 0);
+  }
 
   return mrb_fixnum_value(length);
@@ -773,5 +787,5 @@
 }
 
-#if !defined(_WIN32) && !defined(_WIN64) && !defined(__NEWLIB__)
+#ifndef _WIN32
 static mrb_value
 mrb_io_s_pipe(mrb_state *mrb, mrb_value klass)
@@ -789,5 +803,4 @@
   r = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type));
   mrb_iv_set(mrb, r, mrb_intern_cstr(mrb, "@buf"), mrb_str_new_cstr(mrb, ""));
-  mrb_iv_set(mrb, r, mrb_intern_cstr(mrb, "@pos"), mrb_fixnum_value(0));
   fptr_r = mrb_io_alloc(mrb);
   fptr_r->fd = pipes[0];
@@ -800,5 +813,4 @@
   w = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type));
   mrb_iv_set(mrb, w, mrb_intern_cstr(mrb, "@buf"), mrb_str_new_cstr(mrb, ""));
-  mrb_iv_set(mrb, w, mrb_intern_cstr(mrb, "@pos"), mrb_fixnum_value(0));
   fptr_w = mrb_io_alloc(mrb);
   fptr_w->fd = pipes[1];
@@ -1072,5 +1084,5 @@
 
   mrb_include_module(mrb, io, mrb_module_get(mrb, "Enumerable")); /* 15.2.20.3 */
-#if !defined(_WIN32) && !defined(_WIN64) && !defined(__NEWLIB__)
+#ifndef _WIN32
   mrb_define_class_method(mrb, io, "_popen",  mrb_io_s_popen,   MRB_ARGS_ANY());
   mrb_define_class_method(mrb, io, "_sysclose",  mrb_io_s_sysclose, MRB_ARGS_REQ(1));
@@ -1079,5 +1091,5 @@
   mrb_define_class_method(mrb, io, "select",  mrb_io_s_select,  MRB_ARGS_ANY());
   mrb_define_class_method(mrb, io, "sysopen", mrb_io_s_sysopen, MRB_ARGS_ANY());
-#if !defined(_WIN32) && !defined(_WIN64) && !defined(__NEWLIB__)
+#ifndef _WIN32
   mrb_define_class_method(mrb, io, "_pipe", mrb_io_s_pipe, MRB_ARGS_NONE());
 #endif
Index: EcnlProtoTool/trunk/mrbgems/mruby-io/test/io.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-io/test/io.rb	(revision 321)
+++ EcnlProtoTool/trunk/mrbgems/mruby-io/test/io.rb	(revision 331)
@@ -141,4 +141,11 @@
 end
 
+assert "IO#read(n) with n > IO::BUF_SIZE" do
+  r,w = IO.pipe
+  n = IO::BUF_SIZE+1
+  w.write 'a'*n
+  assert_equal r.read(n), 'a'*n
+end
+
 assert('IO#readchar', '15.2.20.5.15') do
   # almost same as IO#getc
@@ -182,4 +189,14 @@
   assert_equal 0, io.write("")
   io.close
+
+  io = IO.open(IO.sysopen($mrbtest_io_wfname, "r+"), "r+")
+  assert_equal 7, io.write("abcdefg")
+  io.rewind
+  assert_equal "ab", io.read(2)
+  assert_equal 3, io.write("123")
+  io.rewind
+  assert_equal "ab123fg", io.read
+  io.close
+
   true
 end
@@ -234,6 +251,20 @@
     io.sysread(10000)
   end
-  io.close
-  io.closed?
+
+  assert_raise RuntimeError do
+    io.sysread(5, "abcde".freeze)
+  end
+
+  io.close
+  assert_equal "", io.sysread(0)
+  assert_raise(IOError) { io.sysread(1) }
+  assert_raise(ArgumentError) { io.sysread(-1) }
+  io.closed?
+
+  fd = IO.sysopen $mrbtest_io_wfname, "w"
+  io = IO.new fd, "w"
+  assert_raise(IOError) { io.sysread(1) }
+  io.close
+  true
 end
 
Index: EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/.travis.yml
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/.travis.yml	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/.travis.yml	(revision 331)
@@ -0,0 +1,2 @@
+script:
+  - "ruby run_test.rb all test"
Index: EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/README.md
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/README.md	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/README.md	(revision 331)
@@ -0,0 +1,36 @@
+# mruby-ipaddr
+
+[IPAddr](http://www.ruby-doc.org/stdlib-2.0/libdoc/ipaddr/rdoc/IPAddr.html) class for mruby
+
+## Requirement
+- [mruby-socket](https://github.com/iij/mruby-socket)
+- inet\_ntop(3) and inet\_pton(3)
+
+## Limitation
+
+- Some methods are missing:
+  #& #<< #>> #in6\_arpa #ip6\_int #ipv4\_compat? #ipv4\_mapped #ipv4\_mapped?
+  #mask! #native #reverse #set #succ #to\_i #to\_range #|
+- Conversion from/to Integer is not supported.
+
+## License
+
+Copyright (c) 2013 Internet Initiative Japan Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
Index: EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/mrbgem.rake	(revision 331)
@@ -0,0 +1,7 @@
+MRuby::Gem::Specification.new('mruby-ipaddr') do |spec|
+  spec.license = 'MIT'
+  spec.authors = 'Internet Initiative Japan Inc.'
+  spec.add_dependency 'mruby-sprintf'
+  spec.add_dependency 'mruby-pack'
+  spec.add_dependency 'mruby-socket'
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/mrblib/ipaddr.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/mrblib/ipaddr.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/mrblib/ipaddr.rb	(revision 331)
@@ -0,0 +1,186 @@
+class IPAddr
+  # @family is either AF_INET or AF_INET6.
+  # @addr is a String represents IP address as an octet string.
+  # @mask is a String represents netmask as an octet string.
+
+  def initialize(addr='::', family=Socket::AF_UNSPEC)
+    a, m = addr.split('/', 2)
+    if family == Socket::AF_UNSPEC
+      begin
+        @addr = IPSocket.pton(Socket::AF_INET, a)
+        @family = Socket::AF_INET
+      rescue ArgumentError
+        @addr = IPSocket.pton(Socket::AF_INET6, a)
+        @family = Socket::AF_INET6
+      end
+    else
+      @addr = IPSocket.pton(family, a)
+      @family = family
+    end
+    if m
+      initialize_makemask(m)
+      _applymask
+    else
+      if @family == Socket::AF_INET
+        @mask = "\xff" * 4
+      elsif @family == Socket::AF_INET6
+        @mask = "\xff" * 16
+      end
+    end
+  end
+
+  def initialize_makemask(m)
+    if @family == Socket::AF_INET and m.include?('.')
+      @mask = IPSocket.pton(Socket::AF_INET, m)
+    elsif @family == Socket::AF_INET6 and m.include?(':')
+      @mask = IPSocket.pton(Socket::AF_INET6, m)
+    else
+      ma = []
+      mi = m.to_i
+      mlen = (ipv4?) ? 32 : 128
+      while mlen > 0
+        if mi >= 8
+          ma << 0xff
+        elsif mi <= 0
+          ma << 0
+        else
+          ma << (0xff ^ (0xff >> mi))
+        end
+        mi -= 8
+        mlen -= 8
+      end
+      @mask = ma.pack("C*")
+    end
+  end
+
+  def self.new_ntoh(addr)
+    raise TypeError, "can't convert to String" unless addr.is_a? String
+    if addr.size == 4
+      a = IPAddr.new("0.0.0.0")
+      f = Socket::AF_INET
+    elsif addr.size == 16
+      a = IPAddr.new("::")
+      f = Socket::AF_INET6
+    else
+      raise ArgumentError, "length of addr must be 4 or 16"
+    end
+    a.set2(addr, f)
+  end
+
+  # private
+  def _applymask
+    a = @addr.unpack("C*")
+    m = @mask.unpack("C*")
+    (0...a.size).each { |i| a[i] &= m[i] }
+    @addr = a.pack("C*")
+  end
+
+  # private
+  def _mask
+    @mask
+  end
+
+  #def &(other)
+  #def <<(num)
+
+  def <=>(other)
+    if @family == other.family
+      @addr <=> other.hton
+    else
+      nil
+    end
+  end
+
+  def ==(other)
+    if other.is_a? String
+      self.eql? IPAddr.new(other)
+    else
+      self.eql? other
+    end
+  end
+
+  #def ===(ipaddr)
+  #alias include? ===
+  #def >>(num)
+
+  def eql?(other)
+    @addr == other.hton and @mask == other._mask and @family == other.family
+  end
+
+  def family
+    @family
+  end
+
+  def hash
+    @addr.hash ^ @mask.hash ^ @family.hash
+  end
+
+  def hton
+    @addr
+  end
+
+  def inspect
+    def a2s(a)
+      if @family == Socket::AF_INET
+        return a.unpack("C*").map { |b| format("%u", b) }.join('.')
+      else
+        bytes = a.unpack("C*").map { |x| format "%02x", x }
+        return (0..7).map { |i| bytes[i*2, 2].join }.join(':')
+      end
+    end
+    format "#<%s: %s:%s/%s>",
+      self.class, (ipv4? ? 'IPv4' : 'IPv6'), a2s(@addr), a2s(@mask)
+  end
+
+  def ipv4?
+    @family == Socket::AF_INET
+  end
+
+  def ipv6?
+    @family == Socket::AF_INET6
+  end
+
+  def mask(prefixlen)
+    a = @addr.unpack("C*")
+    i = prefixlen.divmod(8)[0]             # mruby 1.0.0 lacks Integer#div
+    if prefixlen % 8 != 0
+      a[i] &= ~(0xff >> (prefixlen % 8))
+      i += 1
+    end
+    (i..a.size-1).each { |i| a[i] = 0 }
+    IPAddr.new('::', Socket::AF_INET6).set2(a.pack("C*"), @family)
+  end
+
+  # private
+  def set2(a, f)
+    @addr = a
+    @family = f
+    if @family == Socket::AF_INET
+      @mask = "\xff" * 4
+    elsif @family == Socket::AF_INET6
+      @mask = "\xff" * 16
+    end
+    self
+  end
+
+  def to_s
+    IPAddr.ntop(@addr)
+  end
+
+  def ~
+    a = @addr.unpack("C*").map { |b| b ^ 0xff }.pack("C*")
+    IPAddr.new('::', Socket::AF_INET6).set2(a, @family)
+  end
+
+  alias to_string to_s
+
+  # mruby extension
+  def is_netaddr?(prefixlen)
+    (self <=> self.mask(prefixlen)) == 0
+  end
+
+  def is_bcastaddr?(prefixlen)
+    i = ~self
+    (i <=> i.mask(prefixlen)) == 0
+  end
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/run_test.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/run_test.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/run_test.rb	(revision 331)
@@ -0,0 +1,27 @@
+#!/usr/bin/env ruby
+#
+# mrbgems test runner
+#
+
+if __FILE__ == $0
+  repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby'
+  build_args = ARGV
+
+  Dir.mkdir 'tmp'  unless File.exist?('tmp')
+  unless File.exist?(dir)
+    system "git clone #{repository} #{dir}"
+  end
+
+  exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}])
+end
+
+MRuby::Build.new do |conf|
+  toolchain :gcc
+  conf.gembox 'default'
+
+  conf.gem :git => 'https://github.com/iij/mruby-io.git'
+  conf.gem :git => 'https://github.com/iij/mruby-socket.git'
+  conf.gem :git => 'https://github.com/iij/mruby-pack.git'
+
+  conf.gem File.expand_path(File.dirname(__FILE__))
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/src/ipaddr.c
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/src/ipaddr.c	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/src/ipaddr.c	(revision 331)
@@ -0,0 +1,72 @@
+#include "mruby.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include "mruby/string.h"
+
+static mrb_value
+mrb_ipaddr_ntop(mrb_state *mrb, mrb_value klass)
+{ 
+  mrb_int af, n;
+  char *addr, buf[50];
+
+  mrb_get_args(mrb, "s", &addr, &n);
+  if (n == 4) {
+    af = AF_INET;
+  } else if (n == 16) {
+    af = AF_INET6;
+  } else {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address");
+  }
+  if (inet_ntop(af, addr, buf, sizeof(buf)) == NULL)
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address");
+  return mrb_str_new_cstr(mrb, buf);
+}
+
+static mrb_value
+mrb_ipaddr_pton(mrb_state *mrb, mrb_value klass)
+{ 
+  mrb_int af, n;
+  mrb_value s;
+  char *bp, buf[50];
+
+  mrb_get_args(mrb, "is", &af, &bp, &n);
+  if (n > sizeof(buf) - 1)
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address");
+  memcpy(buf, bp, n);
+  buf[n] = '\0';
+
+  if (af == AF_INET) {
+    struct in_addr in;
+    if (inet_pton(AF_INET, buf, (void *)&in.s_addr) != 1) {
+      mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address");
+    }
+    s = mrb_str_new(mrb, (char *)&in.s_addr, 4);
+  } else if (af == AF_INET6) {
+    struct in6_addr in6;
+    if (inet_pton(AF_INET6, buf, (void *)&in6.s6_addr) != 1) {
+      mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid address");
+    }
+    s = mrb_str_new(mrb, (char *)&in6.s6_addr, 16);
+  } else
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "unsupported address family");
+
+  return s;
+}
+
+void
+mrb_mruby_ipaddr_gem_init(mrb_state *mrb)
+{
+  struct RClass *c;
+
+  c = mrb_define_class(mrb, "IPAddr", mrb->object_class);
+  mrb_define_class_method(mrb, c, "_pton", mrb_ipaddr_pton, MRB_ARGS_REQ(1));
+  mrb_define_class_method(mrb, c, "ntop", mrb_ipaddr_ntop, MRB_ARGS_REQ(1));
+}
+
+void
+mrb_mruby_ipaddr_gem_final(mrb_state *mrb)
+{
+}
Index: EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/test/ipaddr.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/test/ipaddr.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-ipaddr/test/ipaddr.rb	(revision 331)
@@ -0,0 +1,111 @@
+assert('IPAddr') do
+  IPAddr.class == Class
+end
+
+assert('IPAddr#initialize') do
+  n1 = IPAddr.new
+  n2 = IPAddr.new('::')
+  n3 = IPAddr.new('::', Socket::AF_UNSPEC)
+  n4 = IPAddr.new('127.0.0.1')
+  assert_equal(n1, n2)
+  assert_equal(n1, n3)
+  assert_not_equal(n1, n4)
+
+  a = IPAddr.new('192.0.2.1/24')
+  b = IPAddr.new('192.0.2.1/24', Socket::AF_INET)
+  c = IPAddr.new('192.0.2.1/255.255.255.0')
+  assert_equal(a, b)
+  assert_equal(a, c)
+
+  a = IPAddr.new('2001:db8::1/64')
+  b = IPAddr.new('2001:db8::1/64', Socket::AF_INET6)
+  c = IPAddr.new('2001:db8::1/ffff:ffff:ffff:ffff::')
+  assert_equal(a, b)
+  assert_equal(a, c)
+end
+
+assert('IPAddr.new_ntoh') do
+  a = IPAddr.new_ntoh("\300\250\001\001")
+  b = IPAddr.new("192.168.1.1")
+  assert_equal(a, b)
+
+  a = IPAddr.new_ntoh("\040\001\015\270\0\0\0\0\0\0\0\0\0\0\0\001")
+  b = IPAddr.new("2001:db8::1")
+  assert_equal(a, b)
+end
+
+assert('IPAddr.ntop') do
+  IPAddr.ntop("\300\250\001\001") == "192.168.1.1" and
+    IPAddr.ntop("\040\001\015\270\0\0\0\0\0\0\0\0\0\0\0\001") == "2001:db8::1"
+end
+
+assert('IPAddr#<=>') do
+  x = IPAddr.new('1.1.1.1')
+  a = IPAddr.new('1.1.1.0')
+  b = IPAddr.new('1.1.1.2')
+  c = IPAddr.new('1.1.1.1')
+  d = IPAddr.new('2001:db8::1')
+  (x <=> a) > 0 and (x <=> b) < 0 and (x <=> c) == 0 and (x <=> d) == nil
+end
+
+assert('IPAddr#==') do
+  assert_true(IPAddr.new("192.168.0.1") == "192.168.0.1")
+  assert_false(IPAddr.new("192.168.0.1") == IPAddr.new("192.168.0.1/24"))
+end
+
+assert('IPAddr#eql?') do
+  assert_true(IPAddr.new("192.2.0.1").eql? IPAddr.new("192.2.0.1"))
+  assert_false(IPAddr.new("192.2.0.1").eql? IPAddr.new("192.2.0.1/24"))
+  assert_false(IPAddr.new("0.0.0.1").eql? IPAddr.new("::1"))
+end
+
+assert('IPAddr#family') do
+  a = IPAddr.new('192.0.2.1', Socket::AF_INET)
+  b = IPAddr.new('2001:db8::1', Socket::AF_INET6)
+  c = IPAddr.new('192.0.2.1', Socket::AF_UNSPEC)
+  d = IPAddr.new('2001:db8::1', Socket::AF_UNSPEC)
+  a.family == Socket::AF_INET and
+  b.family == Socket::AF_INET6 and
+  c.family == Socket::AF_INET and
+  d.family == Socket::AF_INET6
+end
+
+assert('IPAddr#hash') do
+  a = IPAddr.new("192.0.2.1").hash
+  b = IPAddr.new("192.0.2.1").hash
+  c = IPAddr.new("192.0.2.2").hash
+  a == b and a != c
+end
+
+assert('IPAddr#hton') do
+  IPAddr.new('1.2.3.4').hton == "\x01\x02\x03\x04"
+end
+
+assert('IPAddr#ipv4?') do
+  a = IPAddr.new('192.0.2.1', Socket::AF_INET)
+  b = IPAddr.new('2001:db8::1', Socket::AF_INET6)
+  c = IPAddr.new('192.0.2.1', Socket::AF_UNSPEC)
+  d = IPAddr.new('2001:db8::1', Socket::AF_UNSPEC)
+  a.ipv4? and (not b.ipv4?) and c.ipv4? and (not d.ipv4?)
+end
+
+assert('IPAddr#ipv6?') do
+  a = IPAddr.new('192.0.2.1', Socket::AF_INET)
+  b = IPAddr.new('2001:db8::1', Socket::AF_INET6)
+  c = IPAddr.new('192.0.2.1', Socket::AF_UNSPEC)
+  d = IPAddr.new('2001:db8::1', Socket::AF_UNSPEC)
+  (not a.ipv6?) and b.ipv6? and (not c.ipv6?) and d.ipv6?
+end
+
+assert('IPAddr#mask') do
+  IPAddr.new('192.0.2.1').mask(24).hton == "\xc0\x00\x02\x00"
+end
+
+assert('IPAddr#to_s') do
+  IPAddr.new('192.0.2.1').to_s == '192.0.2.1' and
+  IPAddr.new('2001:db8::3').to_s == '2001:db8::3'
+end
+
+assert('IPAddr#~') do
+  (~IPAddr.new('192.0.2.1')).to_s == '63.255.253.254'
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-mock/.gitignore
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-mock/.gitignore	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-mock/.gitignore	(revision 331)
@@ -0,0 +1,1 @@
+/tmp
Index: EcnlProtoTool/trunk/mrbgems/mruby-mock/.travis.yml
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-mock/.travis.yml	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-mock/.travis.yml	(revision 331)
@@ -0,0 +1,2 @@
+script:
+  - "ruby run_test.rb all test"
Index: EcnlProtoTool/trunk/mrbgems/mruby-mock/README.md
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-mock/README.md	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-mock/README.md	(revision 331)
@@ -0,0 +1,50 @@
+mruby-mock
+==========
+
+Mock class for mruby (experimental)
+
+
+## License
+
+Copyright (c) 2013 Internet Initiative Japan Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a 
+copy of this software and associated documentation files (the "Software"), 
+to deal in the Software without restriction, including without limitation 
+the rights to use, copy, modify, merge, publish, distribute, sublicense, 
+and/or sell copies of the Software, and to permit persons to whom the 
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in 
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+DEALINGS IN THE SOFTWARE.
+
+
+## For example:
+
+test.rb: 
+
+     mock = Mocks::Mock.new
+     mock.stubs(:code).returns("200")
+     mock.stubs(:body).returns("success")
+
+     p mock.code
+     p mock.body
+
+run:
+
+     $ mruby test.rb
+     "200"
+     "success"
+     
+	
+
+
+        
Index: EcnlProtoTool/trunk/mrbgems/mruby-mock/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-mock/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-mock/mrbgem.rake	(revision 331)
@@ -0,0 +1,4 @@
+MRuby::Gem::Specification.new('mruby-mock') do |spec|
+  spec.license = 'MIT'
+  spec.authors = 'Internet Initiative Japan Inc.'
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-mock/mrblib/expectation.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-mock/mrblib/expectation.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-mock/mrblib/expectation.rb	(revision 331)
@@ -0,0 +1,35 @@
+module Mocks
+  class Expectation < Hash
+    def add_stub(expected_method)
+      self[:method] = expected_method
+      self[:history] = []
+
+      self
+    end
+
+    def returns(expected_return)
+      self[:returns] = expected_return
+
+      self
+    end
+
+    def with(*expected_args)
+      self[:with] = expected_args
+
+      self
+    end
+
+    def at_least(min)
+      self[:minimum_number] = min
+    end
+
+    def at_most(max)
+      self[:maximum_number] = max
+    end
+
+    def times(num)
+      self[:times] = num
+    end
+
+  end
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-mock/mrblib/mock.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-mock/mrblib/mock.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-mock/mrblib/mock.rb	(revision 331)
@@ -0,0 +1,7 @@
+module Mocks
+  module TestDouble; end  # define empty module
+
+  class Mock
+    include TestDouble
+  end
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-mock/mrblib/test_double.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-mock/mrblib/test_double.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-mock/mrblib/test_double.rb	(revision 331)
@@ -0,0 +1,71 @@
+module Mocks
+  module TestDouble
+#    attr_reader :mocks
+    def initialize
+      $_mruby_mock_expectations ||= { }
+    end
+
+    def self.extended(instance)
+      instance.instance_eval do
+        def method_missing(name, *args, &block)
+          if $_mruby_mock_expectations[self]
+            $_mruby_mock_expectations[self][name][:invoked] = true
+
+            hash = { :expected_args => $_mruby_mock_expectations[self][name][:with] == args }
+            hash[:expected_args] = true if args.empty? && $_mruby_mock_expectations[self][name][:with].nil?
+            hash[:args] = args
+            $_mruby_mock_expectations[self][name][:history] << hash
+
+            return $_mruby_mock_expectations[self][name][:returns]
+          else
+            super
+          end
+        end
+      end
+    end
+
+    def stubs(method)
+      $_mruby_mock_expectations ||= { }
+      $_mruby_mock_expectations[self] ||= { }
+      $_mruby_mock_expectations[self][method] ||= Mocks::Expectation.new
+
+      unless self.class == Mocks::Mock
+        self.class.class_eval do
+          if method_defined?(method)
+            alias_method "original_#{method}".to_sym, method
+            undef_method(method)
+          end
+        end
+      end
+      $_mruby_mock_expectations[self][method].add_stub(method)
+
+    end
+
+    def original_method(method)
+      self.send("original_#{method}")
+    end
+
+    def method_missing(name, *args, &block)
+      if $_mruby_mock_expectations[self]
+        $_mruby_mock_expectations[self][name][:invoked] = true
+
+        hash = { :expected_args => $_mruby_mock_expectations[self][name][:with] == args }
+        hash[:expected_args] = true if args.empty? && $_mruby_mock_expectations[self][name][:with].nil?
+        hash[:args] = args
+        $_mruby_mock_expectations[self][name][:history] << hash
+
+        return $_mruby_mock_expectations[self][name][:returns]
+      else
+        super
+      end
+    end
+
+  end
+
+end
+
+BasicObject.class_eval do
+  def mocks
+    mock = self.new.instance_eval { self.extend ::Mocks::TestDouble }
+  end
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-mock/run_test.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-mock/run_test.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-mock/run_test.rb	(revision 331)
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+#
+# mrbgems test runner
+#
+
+if __FILE__ == $0
+  repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby'
+  build_args = ARGV
+
+  Dir.mkdir 'tmp'  unless File.exist?('tmp')
+  unless File.exist?(dir)
+    system "git clone #{repository} #{dir}"
+  end
+
+  exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}])
+end
+
+MRuby::Build.new do |conf|
+  toolchain :gcc
+  conf.gembox 'default'
+
+  conf.gem File.expand_path(File.dirname(__FILE__))
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-onig-regexp/src/mruby_onig_regexp.c
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-onig-regexp/src/mruby_onig_regexp.c	(revision 321)
+++ EcnlProtoTool/trunk/mrbgems/mruby-onig-regexp/src/mruby_onig_regexp.c	(revision 331)
@@ -36,5 +36,5 @@
 #define ONIG_EXTERN extern
 #endif
-#include "oniguruma.h"
+#include "onigmo.h"
 
 #ifdef MRUBY_VERSION
@@ -947,5 +947,4 @@
   mrb_define_const(mrb, clazz, "NOTBOL", mrb_fixnum_value(ONIG_OPTION_NOTBOL));
   mrb_define_const(mrb, clazz, "NOTEOL", mrb_fixnum_value(ONIG_OPTION_NOTEOL));
-  mrb_define_const(mrb, clazz, "POSIX_REGION", mrb_fixnum_value(ONIG_OPTION_POSIX_REGION));
 #ifdef ONIG_OPTION_ASCII_RANGE
   mrb_define_const(mrb, clazz, "ASCII_RANGE", mrb_fixnum_value(ONIG_OPTION_ASCII_RANGE));
Index: EcnlProtoTool/trunk/mrbgems/mruby-pack/README.md
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-pack/README.md	(revision 321)
+++ EcnlProtoTool/trunk/mrbgems/mruby-pack/README.md	(revision 331)
@@ -39,7 +39,10 @@
  - S : 16-bit unsigned, native endian (`uint16_t`)
  - s : 16-bit signed, native endian (`int16_t`)
+ - U : UTF-8 character
  - V : 32-bit unsigned, VAX (little-endian) byte order
  - v : 16-bit unsigned, VAX (little-endian) byte order
+ - x : null byte
  - Z : same as "a", except that null is added with *
+
 
 
Index: EcnlProtoTool/trunk/mrbgems/mruby-pack/src/pack.c
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-pack/src/pack.c	(revision 321)
+++ EcnlProtoTool/trunk/mrbgems/mruby-pack/src/pack.c	(revision 331)
@@ -78,5 +78,5 @@
 hex2int(unsigned char ch)
 {
-  if (ch >= '0' && ch <= '9') 
+  if (ch >= '0' && ch <= '9')
     return ch - '0';
   else if (ch >= 'A' && ch <= 'F')
@@ -415,6 +415,10 @@
   char utf8[4];
   int len;
-  
-  unsigned long c = mrb_fixnum(o);
+  unsigned long c = 0;
+
+  if (mrb_float_p(o)) {
+    goto range_error;
+  }
+  c = mrb_fixnum(o);
 
   /* Unicode character */
@@ -435,5 +439,5 @@
     len = 3;
   }
-  else {
+  else if (c < 0x200000) {
     utf8[0] = (char)(0xF0 |  (c >> 18)        );
     utf8[1] = (char)(0x80 | ((c >> 12) & 0x3F));
@@ -442,9 +446,87 @@
     len = 4;
   }
-  
+  else {
+range_error:
+    mrb_raise(mrb, E_RANGE_ERROR, "pack(U): value out of range");
+  }
+
   str = str_len_ensure(mrb, str, sidx + len);
   memcpy(RSTRING_PTR(str) + sidx, utf8, len);
-  
+
   return len;
+}
+
+static const unsigned long utf8_limits[] = {
+  0x0,        /* 1 */
+  0x80,       /* 2 */
+  0x800,      /* 3 */
+  0x10000,    /* 4 */
+  0x200000,   /* 5 */
+  0x4000000,  /* 6 */
+  0x80000000, /* 7 */
+};
+
+static unsigned long
+utf8_to_uv(mrb_state *mrb, const char *p, long *lenp)
+{
+  int c = *p++ & 0xff;
+  unsigned long uv = c;
+  long n;
+
+  if (!(uv & 0x80)) {
+    *lenp = 1;
+    return uv;
+  }
+  if (!(uv & 0x40)) {
+    *lenp = 1;
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character");
+  }
+
+  if      (!(uv & 0x20)) { n = 2; uv &= 0x1f; }
+  else if (!(uv & 0x10)) { n = 3; uv &= 0x0f; }
+  else if (!(uv & 0x08)) { n = 4; uv &= 0x07; }
+  else if (!(uv & 0x04)) { n = 5; uv &= 0x03; }
+  else if (!(uv & 0x02)) { n = 6; uv &= 0x01; }
+  else {
+    *lenp = 1;
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character");
+  }
+  if (n > *lenp) {
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character (expected %S bytes, given %S bytes)",
+    mrb_fixnum_value(n), mrb_fixnum_value(*lenp));
+  }
+  *lenp = n--;
+  if (n != 0) {
+    while (n--) {
+      c = *p++ & 0xff;
+      if ((c & 0xc0) != 0x80) {
+        *lenp -= n + 1;
+        mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed UTF-8 character");
+      }
+      else {
+        c &= 0x3f;
+        uv = uv << 6 | c;
+      }
+    }
+  }
+  n = *lenp - 1;
+  if (uv < utf8_limits[n]) {
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "redundant UTF-8 sequence");
+  }
+  return uv;
+}
+
+static int
+unpack_utf8(mrb_state *mrb, const unsigned char * src, int srclen, mrb_value ary, unsigned int flags)
+{
+  unsigned long uv;
+  long lenp = srclen;
+
+  if (srclen == 0) {
+    return 1;
+  }
+  uv = utf8_to_uv(mrb, (const char *)src, &lenp);
+  mrb_ary_push(mrb, ary, mrb_fixnum_value((mrb_int)uv));
+  return (int)lenp;
 }
 
@@ -483,5 +565,5 @@
     *dptr++ = pad;
   }
- 
+
   return dptr - dptr0;
 }
@@ -542,5 +624,5 @@
     slen = count;
   }
-    
+
   dst = str_len_ensure(mrb, dst, didx + count);
   dptr = RSTRING_PTR(dst) + didx;
@@ -1148,4 +1230,9 @@
         srcidx += unpack_double(mrb, sptr, srclen - srcidx, result, flags);
         break;
+      case PACK_DIR_UTF8:
+        srcidx += unpack_utf8(mrb, sptr, srclen - srcidx, result, flags);
+        break;
+      default:
+        mrb_raise(mrb, E_RUNTIME_ERROR, "mruby-pack's bug");
       }
       if (count > 0) {
Index: EcnlProtoTool/trunk/mrbgems/mruby-pack/test/pack.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-pack/test/pack.rb	(revision 321)
+++ EcnlProtoTool/trunk/mrbgems/mruby-pack/test/pack.rb	(revision 331)
@@ -146,2 +146,20 @@
   assert_pack 'I', str, [12345]
 end
+
+assert 'pack/unpack "U"' do
+  assert_equal [], "".unpack("U")
+  assert_equal [], "".unpack("U*")
+  assert_equal [65, 66], "ABC".unpack("U2")
+  assert_equal [12371, 12435, 12395, 12385, 12399, 19990, 30028], "こんにちは世界".unpack("U*")
+
+  assert_equal "", [].pack("U")
+  assert_equal "", [].pack("U*")
+  assert_equal "AB", [65, 66, 67].pack("U2")
+  assert_equal "こんにちは世界", [12371, 12435, 12395, 12385, 12399, 19990, 30028].pack("U*")
+
+  assert_equal "\000", [0].pack("U")
+
+  assert_raise(RangeError) { [-0x40000000].pack("U") }
+  assert_raise(RangeError) { [-1].pack("U") }
+  assert_raise(RangeError) { [0x40000000].pack("U") }
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-require/.gitignore
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-require/.gitignore	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-require/.gitignore	(revision 331)
@@ -0,0 +1,1 @@
+/tmp
Index: EcnlProtoTool/trunk/mrbgems/mruby-require/.travis.yml
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-require/.travis.yml	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-require/.travis.yml	(revision 331)
@@ -0,0 +1,2 @@
+script:
+  - "ruby run_test.rb all test"
Index: EcnlProtoTool/trunk/mrbgems/mruby-require/README.md
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-require/README.md	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-require/README.md	(revision 331)
@@ -0,0 +1,59 @@
+mruby-require
+=============
+
+"mruby-require" is a mrbgem, provides
+[require](http://docs.ruby-lang.org/ja/2.0.0/class/Kernel.html#M_REQUIRE) and
+[load](http://docs.ruby-lang.org/ja/2.0.0/class/Kernel.html#M_LOAD) for mruby.
+
+### Example:
+
+```Ruby
+# a.rb
+
+require "b"
+
+b = Bclass.new
+p b.method
+```
+```Ruby
+# b.rb
+
+class Bclass
+  def method
+    "BBB"
+  end
+end
+```
+```sh
+% mruby a.rb
+"BBB"
+```
+
+
+### To run the tests:
+
+    ruby run_test.rb
+
+
+## License
+
+Copyright (c) 2013 Internet Initiative Japan Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a 
+copy of this software and associated documentation files (the "Software"), 
+to deal in the Software without restriction, including without limitation 
+the rights to use, copy, modify, merge, publish, distribute, sublicense, 
+and/or sell copies of the Software, and to permit persons to whom the 
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in 
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+DEALINGS IN THE SOFTWARE.
+
Index: EcnlProtoTool/trunk/mrbgems/mruby-require/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-require/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-require/mrbgem.rake	(revision 331)
@@ -0,0 +1,14 @@
+MRuby::Gem::Specification.new('mruby-require') do |spec|
+  spec.license = 'MIT'
+  spec.authors = 'Internet Initiative Japan Inc.'
+
+  spec.add_dependency 'mruby-array-ext'
+  spec.add_dependency 'mruby-dir'
+  spec.add_dependency 'mruby-io'
+  spec.add_dependency 'mruby-tempfile'
+  spec.add_dependency 'mruby-time'
+  spec.add_dependency 'mruby-eval'
+
+  spec.cc.include_paths << "#{build.root}/src"
+end
+
Index: EcnlProtoTool/trunk/mrbgems/mruby-require/mrblib/require.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-require/mrblib/require.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-require/mrblib/require.rb	(revision 331)
@@ -0,0 +1,97 @@
+class LoadError < ScriptError; end
+
+begin
+  eval "1", nil
+  def _require_eval_load(*args)
+    self.eval(*args)
+  end
+rescue ArgumentError
+  def _require_eval_load(*args)
+    self.eval(args[0])
+  end
+end
+
+module Kernel
+  def load(path)
+    raise TypeError unless path.class == String
+
+    if File.exist?(path) && File.extname(path) == ".mrb"
+      _load_mrb_file path
+    elsif File.exist?(path)
+      # _load_rb_str File.open(path).read.to_s, path
+      _require_eval_load File.open(path).read.to_s, nil, path
+    else
+      raise LoadError.new "File not found -- #{path}"
+    end
+
+    true
+  end
+
+  def require(path)
+    raise TypeError unless path.class == String
+
+    # require method can load .rb, .mrb or without-ext filename only.
+    unless ["", ".rb", ".mrb"].include? File.extname(path)
+      raise LoadError.new "cannot load such file -- #{path}"
+    end
+
+    filenames = []
+    if File.extname(path).size == 0
+      filenames << "#{path}.rb"
+      filenames << "#{path}.mrb"
+    else
+      filenames << path
+    end
+
+    dir = nil
+    filename = nil
+    if ['/', '.'].include? path[0]
+      path0 = filenames.find do |fname|
+        File.file?(fname) && File.exist?(fname)
+      end
+    else
+      dir = ($LOAD_PATH || []).find do |dir0|
+        filename = filenames.find do |fname|
+          path0 = File.join dir0, fname
+          File.file?(path0) && File.exist?(path0)
+        end
+      end
+      path0 = dir && filename ? File.join(dir, filename) : nil
+    end
+
+    if path0 && File.exist?(path0) && File.file?(path0)
+      __require__ path0
+    else
+      raise LoadError.new "cannot load such file -- #{path}"
+    end
+  end
+
+  def __require__(realpath)
+    raise LoadError.new "File not found -- #{realpath}"  unless File.exist? realpath
+    $" ||= []
+    $__mruby_loading_files__ ||= []
+
+    # already required
+    return false  if ($" + $__mruby_loading_files__).include?(realpath)
+
+    $__mruby_loading_files__ << realpath
+    load realpath
+    $" << realpath
+    $__mruby_loading_files__.delete realpath
+
+    true
+  end
+end
+
+
+$LOAD_PATH ||= []
+$LOAD_PATH << '.'
+
+if Object.const_defined?(:ENV)
+  $LOAD_PATH.unshift(*ENV['MRBLIB'].split(':')) unless ENV['MRBLIB'].nil?
+end
+
+$LOAD_PATH.uniq!
+
+$" ||= []
+$__mruby_loading_files__ ||= []
Index: EcnlProtoTool/trunk/mrbgems/mruby-require/run_test.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-require/run_test.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-require/run_test.rb	(revision 331)
@@ -0,0 +1,29 @@
+#!/usr/bin/env ruby
+#
+# mrbgems test runner
+#
+
+if __FILE__ == $0
+  repository, dir = 'https://github.com/mruby/mruby.git', 'tmp/mruby'
+
+  build_args = ARGV
+
+  Dir.mkdir 'tmp'  unless File.exist?('tmp')
+  unless File.exist?(dir)
+    system "git clone #{repository} #{dir}"
+  end
+
+  exit system(%Q[cd #{dir}; MRUBY_CONFIG=#{File.expand_path __FILE__} ruby minirake #{build_args.join(' ')}])
+end
+
+MRuby::Build.new do |conf|
+  toolchain :gcc
+  conf.gembox 'default'
+
+  conf.gem :core => 'mruby-eval'
+  conf.gem :git => 'https://github.com/iij/mruby-io.git'
+  conf.gem :git => 'https://github.com/iij/mruby-dir.git'
+  conf.gem :git => 'https://github.com/iij/mruby-tempfile.git'
+
+  conf.gem File.expand_path(File.dirname(__FILE__))
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-require/src/require.c
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-require/src/require.c	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-require/src/require.c	(revision 331)
@@ -0,0 +1,208 @@
+#if !(defined(_WIN32) || defined(_WIN64))
+#include <err.h>
+#endif
+#include <fcntl.h>
+#include <setjmp.h>
+#include <unistd.h>
+
+#include "mruby.h"
+#include "mruby/compile.h"
+#include "mruby/dump.h"
+#include "mruby/string.h"
+#include "mruby/proc.h"
+
+#include "opcode.h"
+#include "error.h"
+
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#define E_LOAD_ERROR (mrb_class_get(mrb, "LoadError"))
+
+#if MRUBY_RELEASE_NO < 10000
+mrb_value mrb_yield_internal(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_value self, struct RClass *c);
+#define mrb_yield_with_class mrb_yield_internal
+#endif
+
+#if defined(_WIN32) || defined(_WIN64)
+  #include <windows.h>
+  int mkstemp(char *template)
+  {
+    DWORD pathSize;
+    char pathBuffer[1000];
+    char tempFilename[MAX_PATH];
+    UINT uniqueNum;
+    pathSize = GetTempPath(1000, pathBuffer);
+    if (pathSize < 1000) { pathBuffer[pathSize] = 0; }
+    else                 { pathBuffer[0] = 0; }
+    uniqueNum = GetTempFileName(pathBuffer, template, 0, tempFilename);
+    if (uniqueNum == 0) return -1;
+    strncpy(template, tempFilename, MAX_PATH);
+    return open(tempFilename, _O_RDWR|_O_BINARY);
+  }
+#endif
+
+static void
+replace_stop_with_return(mrb_state *mrb, mrb_irep *irep)
+{
+  if (irep->iseq[irep->ilen - 1] == MKOP_A(OP_STOP, 0)) {
+    irep->iseq = mrb_realloc(mrb, irep->iseq, (irep->ilen + 1) * sizeof(mrb_code));
+    irep->iseq[irep->ilen - 1] = MKOP_A(OP_LOADNIL, 0);
+    irep->iseq[irep->ilen] = MKOP_AB(OP_RETURN, 0, OP_R_NORMAL);
+    irep->ilen++;
+  }
+}
+
+static int
+compile_rb2mrb(mrb_state *mrb0, const char *code, int code_len, const char *path, FILE* tmpfp)
+{
+  mrb_state *mrb = mrb_open();
+  mrb_value result;
+  mrbc_context *c;
+  int ret = -1;
+  int debuginfo = 1;
+  mrb_irep *irep;
+
+  c = mrbc_context_new(mrb);
+  c->no_exec = 1;
+  if (path != NULL) {
+    mrbc_filename(mrb, c, path);
+  }
+
+  result = mrb_load_nstring_cxt(mrb, code, code_len, c);
+  if (mrb_undef_p(result)) {
+    mrbc_context_free(mrb, c);
+    mrb_close(mrb);
+    return MRB_DUMP_GENERAL_FAILURE;
+  }
+
+  irep = mrb_proc_ptr(result)->body.irep;
+  ret = mrb_dump_irep_binary(mrb, irep, debuginfo, tmpfp);
+
+  mrbc_context_free(mrb, c);
+  mrb_close(mrb);
+
+  return ret;
+}
+
+static void
+eval_load_irep(mrb_state *mrb, mrb_irep *irep)
+{
+  int ai;
+  struct RProc *proc;
+
+  replace_stop_with_return(mrb, irep);
+  proc = mrb_proc_new(mrb, irep);
+  proc->target_class = mrb->object_class;
+
+  ai = mrb_gc_arena_save(mrb);
+  mrb_yield_with_class(mrb, mrb_obj_value(proc), 0, NULL, mrb_top_self(mrb), mrb->object_class);
+  mrb_gc_arena_restore(mrb, ai);
+}
+
+static mrb_value
+mrb_require_load_rb_str(mrb_state *mrb, mrb_value self)
+{
+  char *path_ptr = NULL;
+#if defined(_WIN32) || defined(_WIN64)
+  char tmpname[MAX_PATH] = "tmp.XXXXXXXX";
+#else
+  char tmpname[] = "tmp.XXXXXXXX";
+#endif
+  mode_t mask;
+  FILE *tmpfp = NULL;
+  int fd = -1, ret;
+  mrb_irep *irep;
+  mrb_value code, path = mrb_nil_value();
+
+  mrb_get_args(mrb, "S|S", &code, &path);
+  if (!mrb_string_p(path)) {
+    path = mrb_str_new_cstr(mrb, "-");
+  }
+  path_ptr = mrb_str_to_cstr(mrb, path);
+
+  mask = umask(077);
+  fd = mkstemp(tmpname);
+  if (fd == -1) {
+    mrb_sys_fail(mrb, "can't create mkstemp() at mrb_require_load_rb_str");
+  }
+  umask(mask);
+
+  tmpfp = fdopen(fd, "r+");
+  if (tmpfp == NULL) {
+    close(fd);
+    mrb_sys_fail(mrb, "can't open temporay file at mrb_require_load_rb_str");
+  }
+
+  ret = compile_rb2mrb(mrb, RSTRING_PTR(code), RSTRING_LEN(code), path_ptr, tmpfp);
+  if (ret != MRB_DUMP_OK) {
+    fclose(tmpfp);
+    remove(tmpname);
+    mrb_raisef(mrb, E_LOAD_ERROR, "can't load file -- %S", path);
+    return mrb_nil_value();
+  }
+
+  rewind(tmpfp);
+  irep = mrb_read_irep_file(mrb, tmpfp);
+  fclose(tmpfp);
+  remove(tmpname);
+
+  if (irep) {
+    eval_load_irep(mrb, irep);
+  } else if (mrb->exc) {
+    // fail to load
+    longjmp(*(jmp_buf*)mrb->jmp, 1);
+  } else {
+    mrb_raisef(mrb, E_LOAD_ERROR, "can't load file -- %S", path);
+    return mrb_nil_value();
+  }
+
+  return mrb_true_value();
+}
+
+static mrb_value
+mrb_require_load_mrb_file(mrb_state *mrb, mrb_value self)
+{
+  char *path_ptr = NULL;
+  FILE *fp = NULL;
+  mrb_irep *irep;
+  mrb_value path;
+
+  mrb_get_args(mrb, "S", &path);
+  path_ptr = mrb_str_to_cstr(mrb, path);
+
+  fp = fopen(path_ptr, "rb");
+  if (fp == NULL) {
+    mrb_raisef(mrb, E_LOAD_ERROR, "can't open file -- %S", path);
+  }
+
+  irep = mrb_read_irep_file(mrb, fp);
+  fclose(fp);
+
+  if (irep) {
+    eval_load_irep(mrb, irep);
+  } else if (mrb->exc) {
+    // fail to load
+    longjmp(*(jmp_buf*)mrb->jmp, 1);
+  } else {
+    mrb_raisef(mrb, E_LOAD_ERROR, "can't load file -- %S", path);
+    return mrb_nil_value();
+  }
+
+  return mrb_true_value();
+}
+
+void
+mrb_mruby_require_gem_init(mrb_state *mrb)
+{
+  struct RClass *krn;
+  krn = mrb->kernel_module;
+
+  mrb_define_method(mrb, krn, "_load_rb_str",   mrb_require_load_rb_str,   MRB_ARGS_ANY());
+  mrb_define_method(mrb, krn, "_load_mrb_file", mrb_require_load_mrb_file, MRB_ARGS_REQ(1));
+}
+
+void
+mrb_mruby_require_gem_final(mrb_state *mrb)
+{
+}
Index: EcnlProtoTool/trunk/mrbgems/mruby-require/test/d/required.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-require/test/d/required.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-require/test/d/required.rb	(revision 331)
@@ -0,0 +1,19 @@
+# global variables
+$gvar0 = 1
+$gvar1 = 1
+
+# toplevel local variables
+lvar0 = 1
+lvar1 = 1
+
+# define a procedure
+def proc0
+  :proc0
+end
+
+# define a new method of an existing class.
+class MrubyRequireClass
+  def foo
+    :foo
+  end
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-require/test/require.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-require/test/require.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-require/test/require.rb	(revision 331)
@@ -0,0 +1,28 @@
+assert("Kernel.require") do
+  # see d/required.rb
+  $gvar1 = 0
+  lvar1 = 0
+  class MrubyRequireClass; end
+
+  assert_true require(File.join(File.dirname(__FILE__), "d", "required.rb"))
+
+  # Kernel.require can create a global variable
+  assert_equal 1, $gvar0
+
+  # Kernel.require can change value of a global variable
+  assert_equal 1, $gvar1
+
+  # Kernel.require cannot create a local variable
+  assert_raise(NoMethodError) do
+    lvar0
+  end
+
+  # Kernel.require cannot change value of a local variable
+  assert_equal 0, lvar1
+
+  # Kernel.require can define a toplevel procedure
+  assert_equal :proc0, proc0
+
+  # Kernel.require can add a method to an existing class
+  assert_equal :foo, MrubyRequireClass.new.foo
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-require/test/test.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-require/test/test.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-require/test/test.rb	(revision 331)
@@ -0,0 +1,34 @@
+$" = [] # init
+
+assert "Kernel#_load_rb_str" do
+  assert_equal true, self.methods.include?(:_load_rb_str)
+  assert_equal false, Object.const_defined?(:LOAD_RB_STR_TEST)
+  _load_rb_str("LOAD_RB_STR_TEST = 1")
+  assert_equal true, Object.const_defined?(:LOAD_RB_STR_TEST)
+end
+
+assert "$LOAD_PATH check" do
+  assert_equal Array, $LOAD_PATH.class
+end
+
+assert '$" check' do
+  assert_equal [], $"
+end
+
+assert('load - error check') do
+  assert_raise TypeError, "load(nil) should raise TypeError" do
+    load nil
+  end
+  assert_raise LoadError, "load('notfound') should raise LoadError" do
+    load 'notfound'
+  end
+end
+
+assert('require - error check') do
+  assert_raise TypeError, "require(nil) should raise TypeError" do
+    require nil
+  end
+  assert_raise LoadError, "require('notfound') should raise LoadError" do
+    require "notfound"
+  end
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-require/test/test2.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-require/test/test2.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-require/test/test2.rb	(revision 331)
@@ -0,0 +1,139 @@
+$dir = File.join(Dir.tmpdir, "mruby-require-test-#{Time.now.to_i}.#{Time.now.usec}")
+
+def test_setup
+  Dir.mkdir($dir)  unless File.exist?($dir)
+
+  File.open(File.join($dir, "test.rb"), "w") do |fp|
+    fp.puts "$require_test_variable = 123"
+  end
+
+  File.open(File.join($dir, "test_dir.rb"), "w") do |fp|
+    fp.puts "$test_dir = 'test_dir'"
+  end
+  Dir.mkdir(File.join($dir, "test_dir"))
+  File.open(File.join($dir, "test_dir", "test_dir.rb"), "w") do |fp|
+    fp.puts "$test_dir2 = 'test_dir/test_dir'"
+  end
+
+  File.open(File.join($dir, "test_conf.conf"), "w") do |fp|
+    fp.puts "$test_conf = 'test_conf'"
+  end
+
+  File.open(File.join($dir, "empty.rb"), "w")
+
+  test_reset
+end
+
+def test_reset
+  $require_test_variable = nil
+  $test_dir = nil
+  $test_dir2 = nil
+  $test_conf = nil
+  $LOAD_PATH = [$dir]
+  $" = []
+end
+
+def remove_file_recursive(path)
+  if File.directory? path
+    Dir.entries(path).each do |entry|
+      next if ['.', '..'].include?(entry)
+      remove_file_recursive File.join(path, entry)
+    end
+    Dir.unlink path
+  else
+    File.unlink path
+  end
+end
+
+def test_cleanup
+  if $dir && File.exist?($dir)
+    remove_file_recursive $dir
+  end
+end
+
+#####
+test_setup
+#####
+
+assert("require 'test' should be success") do
+  test_reset
+
+  assert_true require("test"), "require returns true when success"
+  assert_equal [File.join($dir, "test.rb")], $"
+  assert_equal 123, $require_test_variable
+  $require_test_variable = 789
+  assert_false require("test"), "2nd require should returns false"
+  assert_equal 789, $require_test_variable
+
+  test_reset
+
+  assert_true require("test.rb"), "require should be success with '.rb'"
+  assert_equal [File.join($dir, "test.rb")], $"
+end
+
+assert("require with absolute path should be success") do
+  test_reset
+  assert_true require(File.join($dir, "test"))
+  assert_equal [File.join($dir, "test.rb")], $"
+
+  test_reset
+  assert_true require(File.join($dir, "test.rb"))
+  assert_equal [File.join($dir, "test.rb")], $"
+end
+
+assert("require with absolute path && empty load_path") do
+  test_reset
+  $LOAD_PATH = []
+
+  assert_raise LoadError, "cannot load test.rb" do
+    require "test"
+  end
+  assert_equal true, require(File.join($dir, "test"))
+end
+
+assert("require 'test_dir' should be success") do
+  test_reset
+
+  assert_true require("test_dir"), "require 'test_dir' should be load 'test_dir.rb'"
+  assert_equal [File.join($dir, "test_dir.rb")], $"
+  assert_true require("test_dir/test_dir"), "require 'test_dir/test_dir' should be success"
+  assert_equal 'test_dir/test_dir', $test_dir2
+end
+
+assert("require 'test_conf' should be fail") do
+  test_reset
+
+  assert_raise LoadError, "require 'test_conf.conf' should be fail" do
+    require("test_conf.conf")
+  end
+  assert_raise LoadError, "require method can't load *.conf" do
+    require File.join($dir, "test_conf.conf")
+  end
+end
+
+assert("require 'empty' should be success") do
+  test_reset
+
+  assert_true require("empty")
+  assert_equal 0, File.size(File.join($dir, "empty.rb"))
+end
+
+assert("load 'test.rb' should be success") do
+  test_reset
+
+  assert_true load(File.join($dir, "test.rb"))
+  assert_equal 123, $require_test_variable
+  assert_true $".empty?
+end
+
+assert("load 'test_conf.conf' should be success") do
+  test_reset
+
+  assert_equal true, load(File.join($dir, "test_conf.conf"))
+  assert_equal "test_conf", $test_conf
+end
+
+
+#####
+test_cleanup
+#####
Index: EcnlProtoTool/trunk/mrbgems/mruby-require/test/test_context.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-require/test/test_context.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-require/test/test_context.rb	(revision 331)
@@ -0,0 +1,33 @@
+$dir = File.join(Dir.tmpdir, "mruby-require-test-#{Time.now.to_i}.#{Time.now.usec}")
+
+def test_setup
+  Dir.mkdir($dir) unless File.exist?($dir)
+
+  File.open(File.join($dir, "foo.rb"), "w") do |f|
+    f.puts "$require_context = self"
+  end
+end
+
+def test_cleanup
+  if $dir && File.exist?($dir)
+    Dir.entries($dir).each do |e|
+      next if ['.', '..'].include? e
+      File.unlink File.join($dir,e)
+    end
+    Dir.unlink $dir
+  end
+end
+
+
+#####
+test_setup
+#####
+
+assert("require context") do
+  require File.join($dir, 'foo.rb')
+  assert_equal self, $require_context
+end
+
+#####
+test_cleanup
+#####
Index: EcnlProtoTool/trunk/mrbgems/mruby-require/test/test_nest_loop.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-require/test/test_nest_loop.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-require/test/test_nest_loop.rb	(revision 331)
@@ -0,0 +1,58 @@
+$dir = File.join(Dir.tmpdir, "mruby-require-test-#{Time.now.to_i}.#{Time.now.usec}")
+
+def test_setup
+  Dir.mkdir($dir)
+
+  File.open(File.join($dir, "loop1.rb"), "w") do |fp|
+    fp.puts "require 'loop2.rb'"
+    fp.puts "$loop1 = 'loop1'"
+  end
+  File.open(File.join($dir, "loop2.rb"), "w") do |fp|
+    fp.puts "require 'loop1.rb'"
+    fp.puts "$loop2 = 'loop2'"
+  end
+
+  $require_test_count = 10
+  (1..$require_test_count-1).each do |i|
+    File.open(File.join($dir, "#{i+1}.rb"), "w") do |fp|
+      fp.puts "require '#{i}'"
+      fp.puts "s = 0"
+      (0..100).each{|num| fp.puts "s += #{num}" }
+    end
+  end
+  File.open(File.join($dir, "1.rb"), "w") do |fp|
+    fp.puts "$require_test_0 = 123"
+  end
+
+  $LOAD_PATH = [$dir]
+end
+
+def test_cleanup
+  if $dir && File.exist?($dir)
+    Dir.entries($dir).each do |e|
+      next if ['.', '..'].include? e
+      File.unlink File.join($dir,e)
+    end
+    Dir.unlink $dir
+  end
+end
+
+#####
+test_setup
+#####
+
+assert("require loop check") do
+  require 'loop1'
+  assert_equal 'loop1', $loop1
+  assert_equal 'loop2', $loop2
+end
+
+assert("require nest") do
+  before = $".size
+  require "#{$require_test_count}"
+  assert_equal before + $require_test_count, $".size
+end
+
+#####
+test_cleanup
+#####
Index: EcnlProtoTool/trunk/mrbgems/mruby-socket/README.md
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-socket/README.md	(revision 321)
+++ EcnlProtoTool/trunk/mrbgems/mruby-socket/README.md	(revision 331)
@@ -37,19 +37,19 @@
 Copyright (c) 2013 Internet Initiative Japan Inc.
 
-Permission is hereby granted, free of charge, to any person obtaining a 
-copy of this software and associated documentation files (the "Software"), 
-to deal in the Software without restriction, including without limitation 
-the rights to use, copy, modify, merge, publish, distribute, sublicense, 
-and/or sell copies of the Software, and to permit persons to whom the 
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
 Software is furnished to do so, subject to the following conditions:
 
-The above copyright notice and this permission notice shall be included in 
+The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.
 
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 DEALINGS IN THE SOFTWARE.
Index: EcnlProtoTool/trunk/mrbgems/mruby-socket/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-socket/mrbgem.rake	(revision 321)
+++ EcnlProtoTool/trunk/mrbgems/mruby-socket/mrbgem.rake	(revision 331)
@@ -4,5 +4,5 @@
 
   spec.cc.include_paths << "#{build.root}/src"
-  
+
   # If Windows, use winsock
   if ( /mswin|mingw|win32/ =~ RUBY_PLATFORM ) then
Index: EcnlProtoTool/trunk/mrbgems/mruby-socket/mrblib/socket.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-socket/mrblib/socket.rb	(revision 321)
+++ EcnlProtoTool/trunk/mrbgems/mruby-socket/mrblib/socket.rb	(revision 331)
@@ -155,5 +155,5 @@
   end
 
-  def to_sockaddr 
+  def to_sockaddr
     @sockaddr
   end
@@ -234,5 +234,5 @@
       s = nil
       e = SocketError
-      Addrinfo.foreach(host, service) { |ai|
+      Addrinfo.foreach(host, service, nil, Socket::SOCK_STREAM, Socket::IPPROTO_TCP) do |ai|
         begin
           s = Socket._socket(ai.afamily, Socket::SOCK_STREAM, 0)
@@ -245,10 +245,13 @@
           Socket._connect(s, ai.to_sockaddr)
           super(s, "r+")
-          return
+          e = nil
+          break
         rescue => e0
           e = e0
         end
-      }
-      raise e
+      end
+      if e != nil
+        raise e
+      end
     end
   end
Index: EcnlProtoTool/trunk/mrbgems/mruby-socket/src/const.cstub
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-socket/src/const.cstub	(revision 321)
+++ EcnlProtoTool/trunk/mrbgems/mruby-socket/src/const.cstub	(revision 331)
Index: EcnlProtoTool/trunk/mrbgems/mruby-socket/src/socket.c
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-socket/src/socket.c	(revision 321)
+++ EcnlProtoTool/trunk/mrbgems/mruby-socket/src/socket.c	(revision 331)
@@ -4,18 +4,27 @@
 ** See Copyright Notice in mruby.h
 */
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <unistd.h>
+
+#ifdef _WIN32
+  #define _WIN32_WINNT 0x0501
+
+  #include <winsock2.h>
+  #include <ws2tcpip.h>
+  #include <windows.h>
+
+  #define SHUT_RDWR SD_BOTH
+#else
+  #include <sys/types.h>
+  #include <sys/socket.h>
+  #include <sys/un.h>
+  #include <netinet/in.h>
+  #include <netinet/tcp.h>
+  #include <arpa/inet.h>
+  #include <fcntl.h>
+  #include <netdb.h>
+  #include <unistd.h>
+#endif
+
 #include <stddef.h>
 #include <string.h>
-
-/*#include <unistd.h>*/
-extern int gethostname(char *name, size_t len);
 
 #include "mruby.h"
@@ -27,10 +36,4 @@
 #include "error.h"
 
-#ifndef NI_MAXHOST
-#define NI_MAXHOST 255
-#endif
-#ifndef NI_MAXSERV
-#define NI_MAXSERV 32
-#endif
 #define E_SOCKET_ERROR             (mrb_class_get(mrb, "SocketError"))
 
@@ -41,5 +44,5 @@
 #endif
 
-//#ifdef _WIN32
+#ifdef _WIN32
 const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
 {
@@ -59,5 +62,5 @@
 	memset(&in, 0, sizeof(in));
 	in.sin6_family = AF_INET6;
-	memcpy(&in.sin6_addr, src, sizeof(struct in6_addr));
+	memcpy(&in.sin6_addr, src, sizeof(struct in_addr6));
 	getnameinfo((struct sockaddr *)&in, sizeof(struct
 		    sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST);
@@ -92,5 +95,5 @@
 }
 
-//#endif
+#endif
 
 static mrb_value
@@ -192,4 +195,5 @@
 }
 
+#ifndef _WIN32
 static mrb_value
 mrb_addrinfo_unix_path(mrb_state *mrb, mrb_value self)
@@ -202,4 +206,5 @@
   return mrb_str_new_cstr(mrb, ((struct sockaddr_un *)RSTRING_PTR(sastr))->sun_path);
 }
+#endif
 
 static mrb_value
@@ -256,5 +261,5 @@
 static mrb_value
 mrb_basicsocket_getpeereid(mrb_state *mrb, mrb_value self)
-{ 
+{
 #ifdef HAVE_GETPEEREID
   mrb_value ary;
@@ -262,5 +267,5 @@
   uid_t euid;
   int s;
-  
+
   s = socket_fd(mrb, self);
   if (getpeereid(s, &euid, &egid) != 0)
@@ -279,8 +284,8 @@
 static mrb_value
 mrb_basicsocket_getpeername(mrb_state *mrb, mrb_value self)
-{ 
+{
   struct sockaddr_storage ss;
   socklen_t salen;
-  
+
   salen = sizeof(ss);
   if (getpeername(socket_fd(mrb, self), (struct sockaddr *)&ss, &salen) != 0)
@@ -292,8 +297,8 @@
 static mrb_value
 mrb_basicsocket_getsockname(mrb_state *mrb, mrb_value self)
-{ 
+{
   struct sockaddr_storage ss;
   socklen_t salen;
-  
+
   salen = sizeof(ss);
   if (getsockname(socket_fd(mrb, self), (struct sockaddr *)&ss, &salen) != 0)
@@ -305,5 +310,5 @@
 static mrb_value
 mrb_basicsocket_getsockopt(mrb_state *mrb, mrb_value self)
-{ 
+{
   char opt[8];
   int s;
@@ -325,5 +330,5 @@
 static mrb_value
 mrb_basicsocket_recv(mrb_state *mrb, mrb_value self)
-{ 
+{
   int n;
   mrb_int maxlen, flags = 0;
@@ -341,5 +346,5 @@
 static mrb_value
 mrb_basicsocket_recvfrom(mrb_state *mrb, mrb_value self)
-{ 
+{
   int n;
   mrb_int maxlen, flags = 0;
@@ -364,5 +369,5 @@
 static mrb_value
 mrb_basicsocket_send(mrb_state *mrb, mrb_value self)
-{ 
+{
   int n;
   mrb_int flags;
@@ -383,10 +388,18 @@
 static mrb_value
 mrb_basicsocket_setnonblock(mrb_state *mrb, mrb_value self)
-{ 
+{
   int fd, flags;
   mrb_value bool;
+#ifdef _WIN32
+  u_long mode = 1;
+#endif
 
   mrb_get_args(mrb, "o", &bool);
   fd = socket_fd(mrb, self);
+#ifdef _WIN32
+  flags = ioctlsocket(fd, FIONBIO, &mode);
+  if (flags != NO_ERROR)
+    mrb_sys_fail(mrb, "ioctlsocket");
+#else
   flags = fcntl(fd, F_GETFL, 0);
   if (flags == 1)
@@ -398,4 +411,5 @@
   if (fcntl(fd, F_SETFL, flags) == -1)
     mrb_sys_fail(mrb, "fcntl");
+#endif
   return mrb_nil_value();
 }
@@ -403,5 +417,5 @@
 static mrb_value
 mrb_basicsocket_setsockopt(mrb_state *mrb, mrb_value self)
-{ 
+{
   int argc, s;
   mrb_int level = 0, optname;
@@ -420,6 +434,11 @@
       optval = mrb_str_new(mrb, (char *)&i, sizeof(i));
     } else if (mrb_fixnum_p(optval)) {
-      mrb_int i = mrb_fixnum(optval);
-      optval = mrb_str_new(mrb, (char *)&i, sizeof(i));
+      if (optname == IP_MULTICAST_TTL || optname == IP_MULTICAST_LOOP) {
+        char uc = mrb_fixnum(optval);
+        optval = mrb_str_new(mrb, &uc, sizeof(uc));
+      } else {
+        mrb_int i = mrb_fixnum(optval);
+        optval = mrb_str_new(mrb, (char *)&i, sizeof(i));
+      }
     } else {
       mrb_raise(mrb, E_ARGUMENT_ERROR, "optval should be true, false, an integer, or a string");
@@ -443,5 +462,5 @@
 static mrb_value
 mrb_basicsocket_shutdown(mrb_state *mrb, mrb_value self)
-{ 
+{
   mrb_int how = SHUT_RDWR;
 
@@ -454,5 +473,5 @@
 static mrb_value
 mrb_ipsocket_ntop(mrb_state *mrb, mrb_value klass)
-{ 
+{
   mrb_int af, n;
   char *addr, buf[50];
@@ -468,5 +487,5 @@
 static mrb_value
 mrb_ipsocket_pton(mrb_state *mrb, mrb_value klass)
-{ 
+{
   mrb_int af, n;
   char *bp, buf[50];
@@ -498,5 +517,5 @@
 static mrb_value
 mrb_ipsocket_recvfrom(mrb_state *mrb, mrb_value self)
-{ 
+{
   struct sockaddr_storage ss;
   socklen_t socklen;
@@ -528,5 +547,5 @@
   mrb_value buf;
   size_t bufsize;
-  
+
 #ifdef HOST_NAME_MAX
   bufsize = HOST_NAME_MAX + 1;
@@ -568,8 +587,8 @@
 {
   mrb_value sastr;
-  int s;
+  mrb_int s;
 
   mrb_get_args(mrb, "iS", &s, &sastr);
-  if (bind(s, (struct sockaddr *)RSTRING_PTR(sastr), (socklen_t)RSTRING_LEN(sastr)) == -1) {
+  if (bind((int)s, (struct sockaddr *)RSTRING_PTR(sastr), (socklen_t)RSTRING_LEN(sastr)) == -1) {
     mrb_sys_fail(mrb, "bind");
   }
@@ -581,8 +600,8 @@
 {
   mrb_value sastr;
-  int s;
+  mrb_int s;
 
   mrb_get_args(mrb, "iS", &s, &sastr);
-  if (connect(s, (struct sockaddr *)RSTRING_PTR(sastr), (socklen_t)RSTRING_LEN(sastr)) == -1) {
+  if (connect((int)s, (struct sockaddr *)RSTRING_PTR(sastr), (socklen_t)RSTRING_LEN(sastr)) == -1) {
     mrb_sys_fail(mrb, "connect");
   }
@@ -593,8 +612,8 @@
 mrb_socket_listen(mrb_state *mrb, mrb_value klass)
 {
-  int backlog, s;
+  mrb_int backlog, s;
 
   mrb_get_args(mrb, "ii", &s, &backlog);
-  if (listen(s, backlog) == -1) {
+  if (listen((int)s, (int)backlog) == -1) {
     mrb_sys_fail(mrb, "listen");
   }
@@ -623,7 +642,11 @@
 mrb_socket_sockaddr_un(mrb_state *mrb, mrb_value klass)
 {
+#ifdef _WIN32
+  mrb_raise(mrb, E_NOTIMP_ERROR, "sockaddr_un unsupported on Windows");
+  return mrb_nil_value();
+#else
   struct sockaddr_un *sunp;
   mrb_value path, s;
-  
+
   mrb_get_args(mrb, "S", &path);
   if (RSTRING_LEN(path) > sizeof(sunp->sun_path) - 1) {
@@ -637,4 +660,5 @@
   mrb_str_resize(mrb, s, sizeof(struct sockaddr_un));
   return s;
+#endif
 }
 
@@ -642,4 +666,8 @@
 mrb_socket_socketpair(mrb_state *mrb, mrb_value klass)
 {
+#ifdef _WIN32
+  mrb_raise(mrb, E_NOTIMP_ERROR, "socketpair unsupported on Windows");
+  return mrb_nil_value();
+#else
   mrb_value ary;
   mrb_int domain, type, protocol;
@@ -655,4 +683,5 @@
   mrb_ary_push(mrb, ary, mrb_fixnum_value(sv[1]));
   return ary;
+#endif
 }
 
@@ -686,4 +715,80 @@
  * will break on socket descriptors.
  */
+#ifdef _WIN32
+static mrb_value
+mrb_win32_basicsocket_close(mrb_state *mrb, mrb_value self)
+{
+  if (closesocket(socket_fd(mrb, self)) != NO_ERROR)
+    mrb_raise(mrb, E_SOCKET_ERROR, "closesocket unsuccessful");
+  return mrb_nil_value();
+}
+
+#define E_EOF_ERROR                (mrb_class_get(mrb, "EOFError"))
+static mrb_value
+mrb_win32_basicsocket_sysread(mrb_state *mrb, mrb_value self)
+{
+  int sd, ret;
+  mrb_value buf = mrb_nil_value();
+  mrb_int maxlen;
+
+  mrb_get_args(mrb, "i|S", &maxlen, &buf);
+  if (maxlen < 0) {
+    return mrb_nil_value();
+  }
+
+  if (mrb_nil_p(buf)) {
+    buf = mrb_str_new(mrb, NULL, maxlen);
+  }
+  if (RSTRING_LEN(buf) != maxlen) {
+    buf = mrb_str_resize(mrb, buf, maxlen);
+  }
+
+  sd = socket_fd(mrb, self);
+  ret = recv(sd, RSTRING_PTR(buf), maxlen, 0);
+
+  switch (ret) {
+    case 0: /* EOF */
+      if (maxlen == 0) {
+        buf = mrb_str_new_cstr(mrb, "");
+      } else {
+        mrb_raise(mrb, E_EOF_ERROR, "sysread failed: End of File");
+      }
+      break;
+    case SOCKET_ERROR: /* Error */
+      mrb_sys_fail(mrb, "recv");
+      break;
+    default:
+      if (RSTRING_LEN(buf) != ret) {
+        buf = mrb_str_resize(mrb, buf, ret);
+      }
+      break;
+  }
+
+  return buf;
+}
+
+static mrb_value
+mrb_win32_basicsocket_sysseek(mrb_state *mrb, mrb_value self)
+{
+  mrb_raise(mrb, E_NOTIMP_ERROR, "sysseek not implemented for windows sockets");
+  return mrb_nil_value();
+}
+
+static mrb_value
+mrb_win32_basicsocket_syswrite(mrb_state *mrb, mrb_value self)
+{
+  int n;
+  SOCKET sd;
+  mrb_value str;
+
+  sd = socket_fd(mrb, self);
+  mrb_get_args(mrb, "S", &str);
+  n = send(sd, RSTRING_PTR(str), RSTRING_LEN(str), 0);
+  if (n == SOCKET_ERROR)
+    mrb_sys_fail(mrb, "send");
+  return mrb_fixnum_value(n);
+}
+
+#endif
 
 void
@@ -693,5 +798,13 @@
   struct RClass *constants;
 
+#ifdef _WIN32
+  WSADATA wsaData;
+  int result;
+  result = WSAStartup(MAKEWORD(2,2), &wsaData);
+  if (result != NO_ERROR)
+    mrb_raise(mrb, E_RUNTIME_ERROR, "WSAStartup failed");
+#else
   struct RClass *usock;
+#endif
 
   ai = mrb_define_class(mrb, "Addrinfo", mrb->object_class);
@@ -699,5 +812,7 @@
   mrb_define_class_method(mrb, ai, "getaddrinfo", mrb_addrinfo_getaddrinfo, MRB_ARGS_REQ(2)|MRB_ARGS_OPT(4));
   mrb_define_method(mrb, ai, "getnameinfo", mrb_addrinfo_getnameinfo, MRB_ARGS_OPT(1));
+#ifndef _WIN32
   mrb_define_method(mrb, ai, "unix_path", mrb_addrinfo_unix_path, MRB_ARGS_NONE());
+#endif
 
   io = mrb_class_get(mrb, "IO");
@@ -746,5 +861,7 @@
   //mrb_define_method(mrb, sock, "sysaccept", mrb_socket_accept, MRB_ARGS_NONE());
 
+#ifndef _WIN32
   usock = mrb_define_class(mrb, "UNIXSocket", bsock);
+#endif
   //mrb_define_class_method(mrb, usock, "pair", mrb_unixsocket_open, MRB_ARGS_OPT(2));
   //mrb_define_class_method(mrb, usock, "socketpair", mrb_unixsocket_open, MRB_ARGS_OPT(2));
@@ -755,4 +872,10 @@
 
   /* Windows IO Method Overrides on BasicSocket */
+#ifdef _WIN32
+  mrb_define_method(mrb, bsock, "close", mrb_win32_basicsocket_close, MRB_ARGS_NONE());
+  mrb_define_method(mrb, bsock, "sysread", mrb_win32_basicsocket_sysread, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1));
+  mrb_define_method(mrb, bsock, "sysseek", mrb_win32_basicsocket_sysseek, MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, bsock, "syswrite", mrb_win32_basicsocket_syswrite, MRB_ARGS_REQ(1));
+#endif
 
   constants = mrb_define_module_under(mrb, sock, "Constants");
@@ -774,3 +897,6 @@
     freeaddrinfo(mrb_cptr(ai));
   }
-}
+#ifdef _WIN32
+  WSACleanup();
+#endif
+}
Index: EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/.gitignore
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/.gitignore	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/.gitignore	(revision 331)
@@ -0,0 +1,1 @@
+openssldir
Index: EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/README.md
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/README.md	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/README.md	(revision 331)
@@ -0,0 +1,98 @@
+# mruby-tls-openssl
+
+"mruby-tls-openssl" is a TLS library for mruby using OpenSSL.  
+Though very small number of APIs are implemented currently, you can write a [HTTP2 client](https://github.com/iij/mruby-tls-openssl/blob/master/http2.rb) with it.
+
+## API
+
+ - TLS.new(host, opts={})
+   - Open a new TLS connection to `host`.  `host` can be either a hostname
+     (String) or a TCP socket (TCPSocket).
+   - Supported keys in `opts`:
+     - :alpn => str
+       - send str as a protocol for ALPN
+     - :certs => str
+       - pathname of the file contains trusted root CA certificate(s)
+     - :identity => str
+       - a server's identity expected
+     - :ignore_certificate_validity => boolean
+       - ignore "Not Before" and "Not After" fields of certificates
+     - :port => Integer
+       - port number (used only when `host` is a string)
+     - :sni => false (default) | true | String
+       - use Server Name Indication (SNI)
+         - false  : don't send SNI extention
+         - true   : send `opts[:identity]` or `host` as a server name
+         - String : send it as a server name
+     - :version => str
+       - TLS version: one of "TLSv1.0", "TLSv1.1", "TLSv1.2", or "any"
+ - TLS#read(len=)
+   - Read `len` bytes from TLS connection.
+ - TLS#write(str)
+   - Write str to TLS connection.
+ - TLS#close
+   - Close TLS connection
+
+## Example
+
+```Ruby
+# verify server's identity
+tls = TLS.new "github.com", { :port => 443, :certs => "digicert.crt", :identity => "github.com" }
+tls.write "GET / HTTP/1.1\r\nHost: github.com\r\nConnection: close\r\n\r\n"
+p tls.read
+tls.close
+```
+
+## How to use TLS ALPN Extension
+
+If you want to use TLS ALPN Extension, build and install OpenSSL 1.0.2
+(or later) into `openssldir` directory:
+
+```
+% cd mruby-tls-openssl
+% curl https://www.openssl.org/source/openssl-1.0.2a.tar.gz | tar xzf -
+% cd openssl-1.0.2a
+% ./config --openssldir=`pwd`/../openssldir no-shared no-threads
+% make
+% make install
+```
+
+then build mruby.
+
+
+## Compile with LibreSSL
+
+To try [LibreSSL](http://www.libressl.org), install it to `openssldir`:
+
+```
+% cd mruby-tls-openssl
+% curl -O http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-2.1.4.tar.gz
+% tar xzf libressl-2.1.4.tar.gz
+% cd libressl-2.1.4
+% ./configure --disable-shared --prefix=`pwd`/../openssldir
+% make
+% make install
+```
+
+
+## License
+
+Copyright (c) 2014 Internet Initiative Japan Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a 
+copy of this software and associated documentation files (the "Software"), 
+to deal in the Software without restriction, including without limitation 
+the rights to use, copy, modify, merge, publish, distribute, sublicense, 
+and/or sell copies of the Software, and to permit persons to whom the 
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in 
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+DEALINGS IN THE SOFTWARE.
Index: EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/http2.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/http2.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/http2.rb	(revision 331)
@@ -0,0 +1,337 @@
+# Required mrbgems: mruby-pack, mruby-regexp-pcre(or some regexp mrbgem)
+
+# TODO:
+# - connect via proxy
+
+module HTTP2
+  FRAME_TYPE_DATA     = 0
+  FRAME_TYPE_HEADERS  = 1
+  FRAME_TYPE_SETTINGS = 4
+  FRAME_TYPE_GOAWAY   = 7
+  FRAME_TYPE_BLOCK    = 11
+
+  class Client
+    FRAME_FLAG_SETTINGS_ACK = 0x1
+
+    def initialize(host, port=443)
+      @tls = TLS.new host, {
+        :version => "TLSv1.2",
+        :port    => port,
+        :alpn    => "h2",
+        :certs   => "nghttp2.crt", :identity => "nghttp2"
+      }
+      @recvbuf = ""
+      @my_next_stream_id = 1
+      @window = 0
+      @streams = {}
+
+      @settings = {
+        :header_table_size => 4096,
+        :enable_push => 1,
+        :max_concurrent_streams => -1,  # no limit
+        :enable_push => 1,
+        :initial_window_size => 65535,
+        :compress_data => 0
+      }
+
+      self.connect
+    end
+
+    def close
+      # send goaway
+      @tls.close
+    end
+
+    def connect
+      self.send_magic
+      self.send_settings_frame
+      self.wait_for :settings_ack
+    end
+
+    def get path, &block
+      stream = self.new_stream
+      self.send_headers_frame path
+      self.wait_for :data_end
+      $stdout.write stream.response_body
+    end
+
+    def make_frame(type, flags, stream, payload)
+      len = [payload.size/65536, payload.size/256, payload.size].map {
+        |x| x % 256 }.pack("C3")
+      len + [type, flags, stream].pack("CCN") + payload
+    end
+
+    def new_stream
+      id = @my_next_stream_id
+      @my_next_stream_id += 2
+      stream = Stream.new(self, id, @settings)
+      @streams[id] = stream
+      stream
+    end
+
+    def send_frame f
+      puts "send_frame: #{f.inspect}" if $debug
+      @tls.write f.to_bytes
+    end
+
+    def send_magic
+      @tls.write "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
+    end
+
+    def send_settings_frame
+      payload = ""
+      frame = make_frame(4, 0, 0, "")
+      puts "send_settings_frame: #{frame.inspect}" if $debug
+      @tls.write frame
+    end
+
+    def send_headers_frame path
+      def make_a_header(key, val)
+        "\x00" + [key.length].pack("C") + key + [val.length].pack("C") + val
+      end
+
+      payload = "\x00\x00"
+      payload = ""
+      payload += make_a_header(":method", "GET")
+      payload += make_a_header(":scheme", "https")
+      payload += make_a_header(":authority", "1.2.3.4:80")
+      payload += make_a_header(":path", path)
+
+      frame = make_frame(FRAME_TYPE_HEADERS, 5, 1, payload)
+      @tls.write frame
+    end
+
+    def send_window_update(stream_id, inc)
+      self.send_frame WindowUpdateFrame.make_update(stream_id, inc)
+      self.send_frame WindowUpdateFrame.make_update(0, inc)
+    end
+
+    def recv_frame
+      loop do
+        f = Frame.parse @recvbuf
+        if f
+          @recvbuf[0, f.bytelen] = ""
+          return f
+        end
+        bytes = @tls.read(1000)
+        @recvbuf += bytes
+      end
+    end
+
+    def stream id
+      @streams[id]
+    end
+
+    def wait_for cond
+      while frame = self.recv_frame
+        if frame.is_a? SettingsFrame
+          if frame.ack?
+            break if cond == :settings_ack
+          else
+            @settings = frame.settings
+            self.send_frame SettingsFrame.make_ack_frame
+          end
+        elsif frame.is_a? DataFrame
+          stream = @streams[frame.stream_id]
+          stream.recv_data_frame(frame)
+          break if cond == :data_end and frame.end_stream?
+        end
+        puts "wait_for receive: #{frame.inspect}" if $debug
+      end
+    end
+  end
+
+  class Stream
+    def initialize(client, id, settings)
+      @client = client
+      @id     = id
+      @window = settings[:initial_window_size]
+
+      @response_body = ""
+    end
+
+    attr_reader :response_body
+
+    def close
+    end
+
+    def recv_data_frame dframe
+      @response_body += dframe.payload
+      @client.send_window_update(@id, dframe.len) if dframe.len > 0
+    end
+  end
+
+  class Frame
+    HEADERLEN = 9
+
+    def initialize(len, type, flags, stream_id, payload)
+      @len       = len
+      @type      = type
+      @flags     = flags
+      @stream_id = stream_id
+      @payload   = payload
+    end
+
+    attr_reader :len, :type, :flags, :stream_id, :payload
+
+    def self.parse buf
+      return nil if buf.size < HEADERLEN
+      len0, len1, len2, type, flags, stream_id = buf.unpack("C3CCN")
+      len = len0*65536 + len1*256 + len2
+      return nil if buf.size < HEADERLEN + len
+      payload = buf[HEADERLEN, len]
+
+      args = [ len, type, flags, stream_id, payload ]
+      case type
+      when HTTP2::FRAME_TYPE_DATA
+        f = DataFrame.parse(*args)
+      when HTTP2::FRAME_TYPE_HEADERS
+        f = HeadersFrame.parse(*args)
+      when HTTP2::FRAME_TYPE_SETTINGS
+        f = SettingsFrame.parse(*args)
+      when HTTP2::FRAME_TYPE_GOAWAY
+        f = GoawayFrame.parse(*args)
+      when HTTP2::FRAME_TYPE_BLOCK
+        f = BlockFrame.parse(*args)
+      else
+      raise "unsupported frame type: #{type}"
+      end
+      f
+    end
+
+    def bytelen
+      HEADERLEN + @len
+    end
+
+    def to_bytes
+      lens = [payload.size/65536, payload.size/256, payload.size].map {
+        |x| x % 256 }.pack("C3")
+      lens + [ @type, @flags, @stream_id ].pack("CCN") + @payload
+    end
+
+    def inspect
+      format "<%s len=%d flags=0x%02x stream-id=%d%s>", self.class, @len, @flags, @stream_id, inspect_payload
+    end
+
+    def inspect_payload
+      ""
+    end
+  end
+
+  class DataFrame < Frame
+    def self.parse(len, type, flags, stream_id, payload)
+      f = self.new(len, type, flags, stream_id, payload)
+    end
+
+    def end_stream?
+      (@flags & 1) > 0
+    end
+  end
+
+  class HeadersFrame < Frame
+    def self.parse(len, type, flags, stream_id, payload)
+      f = self.new(len, type, flags, stream_id, payload)
+    end
+  end
+
+  class SettingsFrame < Frame
+    def self.make_ack_frame
+      self.new(0, 4, 1, 0, "")
+    end
+
+    def self.parse(len, type, flags, stream_id, payload)
+      if (flags & 1) == 0
+        s = payload.dup
+        h = {}
+        while s.length > 0
+          t, v = s.unpack("nN")
+          case t
+          when 1
+            h[:header_table_size] = v
+          when 2
+            h[:enable_push] = v
+          when 3
+            h[:max_concurrent_streams] = v
+          when 4
+            h[:initial_window_size] = v
+          when 5
+            h[:compress_data] = v
+          else
+            raise "unknown settings parameter: #{t} = #{v}"
+          end
+          s = s[6..-1]
+        end
+        f = self.new len, type, flags, stream_id, payload
+        f.settings = h
+      else
+        # SETTINGS ACK frame
+        f = self.new len, type, flags, stream_id, payload
+      end
+      f
+    end
+
+    attr_accessor :settings
+
+    def ack?
+      (flags & 1) == 1
+    end
+  end
+
+  class WindowUpdateFrame < Frame
+    attr_accessor :inc
+
+    def self.parse(len, type, flags, stream_id, payload)
+      f = self.new(len, type, flags, stream_id, payload)
+    end
+
+    def self.make_update(stream_id, inc)
+      payload = [ inc ].pack("N")
+      f = self.new(payload.size, 8, 0, stream_id, payload)
+      f.inc = inc
+      f
+    end
+
+    def inspect_payload
+      " inc=#{@inc}"
+    end
+  end
+
+  class GoawayFrame < Frame
+    attr_accessor :laststream, :ecode, :debugdata
+
+    def self.parse(len, type, flags, stream_id, payload)
+      f = self.new(len, type, flags, stream_id, payload)
+      f.laststream, f.ecode, f.debugdata = payload.unpack("NNa*")
+      f
+    end
+
+    def inspect_payload
+      " last_stream_id=#{@laststream} error_code=#{@ecode} additional_debug_data=\"#{@debugdata}\""
+    end
+  end
+
+  class BlockFrame < Frame
+    def self.parse(len, type, flags, stream_id, payload)
+      f = self.new(len, type, flags, stream_id, payload)
+    end
+  end
+end
+
+
+$debug = true
+if ARGV.size != 1
+  puts "usage: mruby http2.rb <url>"
+  exit
+end
+
+unless ARGV[0] =~ Regexp.new('https://([^:/]+)(:\d+)?(/.*)')
+  puts "unsupported url: #{ARGV[0]}"
+  exit 1
+end
+host = $1
+port = ($2) ? $2[1..-1].to_i : 443
+path = $3 || ""
+
+http2 = HTTP2::Client.new host, port
+http2.get path
+http2.close
Index: EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/include/win32netcompat.h
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/include/win32netcompat.h	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/include/win32netcompat.h	(revision 331)
@@ -0,0 +1,78 @@
+/*
+ * Public domain
+ *
+ * BSD socket emulation code for Winsock2
+ * Brent Cook <bcook@openbsd.org>
+ */
+
+/*
+ * From
+ * https://raw.githubusercontent.com/libressl-portable/portable/master/include/compat/win32netcompat.h
+ * https://raw.githubusercontent.com/libressl-portable/portable/master/include/compat/arpa/inet.h
+ * https://raw.githubusercontent.com/libressl-portable/portable/master/include/compat/arpa/nameser.h
+ */
+
+#ifndef LIBCRYPTOCOMPAT_WIN32NETCOMPAT_H
+#define LIBCRYPTOCOMPAT_WIN32NETCOMPAT_H
+
+#ifdef _WIN32
+
+#include <ws2tcpip.h>
+#include <errno.h>
+#include <unistd.h>
+
+#ifndef SHUT_RDWR
+#define SHUT_RDWR SD_BOTH
+#endif
+#ifndef SHUT_RD
+#define SHUT_RD   SD_RECEIVE
+#endif
+#ifndef SHUT_WR
+#define SHUT_WR   SD_SEND
+#endif
+
+int posix_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
+
+int posix_close(int fd);
+ssize_t posix_read(int fd, void *buf, size_t count);
+
+ssize_t posix_write(int fd, const void *buf, size_t count);
+
+int posix_getsockopt(int sockfd, int level, int optname,
+  void *optval, socklen_t *optlen);
+
+int posix_setsockopt(int sockfd, int level, int optname,
+  const void *optval, socklen_t optlen);
+
+#ifndef NO_REDEF_POSIX_FUNCTIONS
+#define connect(sockfd, addr, addrlen) posix_connect(sockfd, addr, addrlen)
+#define close(fd) posix_close(fd)
+#define read(fd, buf, count) posix_read(fd, buf, count)
+#define write(fd, buf, count) posix_write(fd, buf, count)
+#define getsockopt(sockfd, level, optname, optval, optlen) \
+  posix_getsockopt(sockfd, level, optname, optval, optlen)
+#define setsockopt(sockfd, level, optname, optval, optlen) \
+  posix_setsockopt(sockfd, level, optname, optval, optlen)
+#endif
+
+#ifndef AI_ADDRCONFIG
+#define AI_ADDRCONFIG               0x00000400
+#endif
+
+#ifndef INADDRSZ
+#define INADDRSZ 4
+#endif
+
+#ifndef IN6ADDRSZ
+#define IN6ADDRSZ 16
+#endif
+
+#ifndef INT16SZ
+#define INT16SZ 2
+#endif
+
+int inet_pton(int af, const char * src, void * dst);
+
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/mrbgem.rake	(revision 331)
@@ -0,0 +1,10 @@
+MRuby::Gem::Specification.new('mruby-tls-openssl') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'Internet Initiative Japan Inc.'
+
+  spec.add_dependency 'mruby-io'
+  spec.add_dependency 'mruby-socket'
+
+  spec.linker.libraries << 'ssl'
+  spec.linker.libraries << 'crypto'
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/mrblib/tls.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/mrblib/tls.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/mrblib/tls.rb	(revision 331)
@@ -0,0 +1,77 @@
+class TLS
+  def self.open(hostname, opts={})
+    tls = self.new(hostname, opts)
+    if block_given?
+      yield tls
+      tls.close
+    end
+    tls
+  end
+
+  def initialize(host, opts={})
+    if host.is_a? String
+      @sock = TCPSocket.new(host, opts[:port] || 443)
+    else
+      @sock = host
+      host = nil
+    end
+
+    @ctx = OpenSSL::SSL_CTX.new (opts[:version] || "any")
+    if opts[:certs]
+      @ctx.load_verify_locations opts[:certs]
+      @ctx.set_verify opts[:ignore_certificate_validity]
+      @ctx.set_verify_depth 5
+    end
+    if opts[:alpn]
+      @ctx.set_alpn_protos opts[:alpn]
+    end
+    @ssl = OpenSSL::SSL.new(@ctx)
+    @ssl.set_fd(@sock.fileno)
+    if opts[:sni]
+      if opts[:sni].is_a? String
+        servername = opts[:sni]
+      else
+        servername = opts[:identity] || host
+      end
+      unless servername
+        raise RuntimeError, 'requested SNI but identity is not known'
+      end
+      @ssl.set_tlsext_host_name(servername)
+    end
+
+    @ssl.connect
+
+    if opts[:certs]
+      @ssl.get_verify_result
+      if opts[:identity]
+        @ssl.check_identity opts[:identity]
+      end
+    end
+  end
+
+  def close
+    @ssl.shutdown
+  end
+
+  def read(length=nil, outbuf=nil)
+    return @ssl.read(length) if length
+
+    result = ""
+    while true
+      s = @ssl.read
+      break unless s
+      result += s
+    end
+    result
+  end
+
+  def write(str)
+    n = 0
+    while str.size > 0
+      i = @ssl.write(str)
+      n += i
+      str = str[i..-1]
+    end
+    n
+  end
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/src/inet_pton.c
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/src/inet_pton.c	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/src/inet_pton.c	(revision 331)
@@ -0,0 +1,211 @@
+/*  $OpenBSD: inet_pton.c,v 1.9 2015/01/16 16:48:51 deraadt Exp $ */
+// from https://raw.githubusercontent.com/libressl-portable/portable/master/crypto/compat/inet_pton.c
+
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+#ifdef _WIN32
+#include <win32netcompat.h>
+#include <sys/types.h>
+#include <string.h>
+#include <errno.h>
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int  inet_pton4(const char *src, u_char *dst);
+static int  inet_pton6(const char *src, u_char *dst);
+
+/* int
+ * inet_pton(af, src, dst)
+ *  convert from presentation format (which usually means ASCII printable)
+ *  to network format (which is usually some kind of binary format).
+ * return:
+ *  1 if the address was valid for the specified address family
+ *  0 if the address wasn't valid (`dst' is untouched in this case)
+ *  -1 if some other error occurred (`dst' is untouched in this case, too)
+ * author:
+ *  Paul Vixie, 1996.
+ */
+int
+inet_pton(int af, const char *src, void *dst)
+{
+  switch (af) {
+  case AF_INET:
+    return (inet_pton4(src, dst));
+  case AF_INET6:
+    return (inet_pton6(src, dst));
+  default:
+    errno = EAFNOSUPPORT;
+    return (-1);
+  }
+  /* NOTREACHED */
+}
+
+/* int
+ * inet_pton4(src, dst)
+ *  like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ *  1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ *  does not touch `dst' unless it's returning 1.
+ * author:
+ *  Paul Vixie, 1996.
+ */
+static int
+inet_pton4(const char *src, u_char *dst)
+{
+  static const char digits[] = "0123456789";
+  int saw_digit, octets, ch;
+  u_char tmp[INADDRSZ], *tp;
+
+  saw_digit = 0;
+  octets = 0;
+  *(tp = tmp) = 0;
+  while ((ch = *src++) != '\0') {
+    const char *pch;
+
+    if ((pch = strchr(digits, ch)) != NULL) {
+      u_int new = *tp * 10 + (pch - digits);
+
+      if (new > 255)
+        return (0);
+      if (! saw_digit) {
+        if (++octets > 4)
+          return (0);
+        saw_digit = 1;
+      }
+      *tp = new;
+    } else if (ch == '.' && saw_digit) {
+      if (octets == 4)
+        return (0);
+      *++tp = 0;
+      saw_digit = 0;
+    } else
+      return (0);
+  }
+  if (octets < 4)
+    return (0);
+
+  memcpy(dst, tmp, INADDRSZ);
+  return (1);
+}
+
+/* int
+ * inet_pton6(src, dst)
+ *  convert presentation level address to network order binary form.
+ * return:
+ *  1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ *  does not touch `dst' unless it's returning 1.
+ * credit:
+ *  inspired by Mark Andrews.
+ * author:
+ *  Paul Vixie, 1996.
+ */
+static int
+inet_pton6(const char *src, u_char *dst)
+{
+  static const char xdigits_l[] = "0123456789abcdef",
+        xdigits_u[] = "0123456789ABCDEF";
+  u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
+  const char *xdigits, *curtok;
+  int ch, saw_xdigit, count_xdigit;
+  u_int val;
+
+  memset((tp = tmp), '\0', IN6ADDRSZ);
+  endp = tp + IN6ADDRSZ;
+  colonp = NULL;
+  /* Leading :: requires some special handling. */
+  if (*src == ':')
+    if (*++src != ':')
+      return (0);
+  curtok = src;
+  saw_xdigit = count_xdigit = 0;
+  val = 0;
+  while ((ch = *src++) != '\0') {
+    const char *pch;
+
+    if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+      pch = strchr((xdigits = xdigits_u), ch);
+    if (pch != NULL) {
+      if (count_xdigit >= 4)
+        return (0);
+      val <<= 4;
+      val |= (pch - xdigits);
+      if (val > 0xffff)
+        return (0);
+      saw_xdigit = 1;
+      count_xdigit++;
+      continue;
+    }
+    if (ch == ':') {
+      curtok = src;
+      if (!saw_xdigit) {
+        if (colonp)
+          return (0);
+        colonp = tp;
+        continue;
+      } else if (*src == '\0') {
+        return (0);
+      }
+      if (tp + INT16SZ > endp)
+        return (0);
+      *tp++ = (u_char) (val >> 8) & 0xff;
+      *tp++ = (u_char) val & 0xff;
+      saw_xdigit = 0;
+      count_xdigit = 0;
+      val = 0;
+      continue;
+    }
+    if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
+        inet_pton4(curtok, tp) > 0) {
+      tp += INADDRSZ;
+      saw_xdigit = 0;
+      count_xdigit = 0;
+      break;  /* '\0' was seen by inet_pton4(). */
+    }
+    return (0);
+  }
+  if (saw_xdigit) {
+    if (tp + INT16SZ > endp)
+      return (0);
+    *tp++ = (u_char) (val >> 8) & 0xff;
+    *tp++ = (u_char) val & 0xff;
+  }
+  if (colonp != NULL) {
+    /*
+     * Since some memmove()'s erroneously fail to handle
+     * overlapping regions, we'll do the shift by hand.
+     */
+    const int n = tp - colonp;
+    int i;
+
+    if (tp == endp)
+      return (0);
+    for (i = 1; i <= n; i++) {
+      endp[- i] = colonp[n - i];
+      colonp[n - i] = 0;
+    }
+    tp = endp;
+  }
+  if (tp != endp)
+    return (0);
+  memcpy(dst, tmp, IN6ADDRSZ);
+  return (1);
+}
+#endif
Index: EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/src/openssl.c
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/src/openssl.c	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/src/openssl.c	(revision 331)
@@ -0,0 +1,555 @@
+#include <sys/types.h>
+#ifndef _WIN32
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#else
+#include <win32netcompat.h>
+#endif
+#include <sys/time.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/opensslv.h>
+#include <openssl/rand.h>
+#include <openssl/ssl.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/x509_vfy.h>
+
+#include "mruby.h"
+#include "mruby/class.h"
+#include "mruby/data.h"
+#include "mruby/string.h"
+
+/*
+ * OpenSSL::SSL_CTX
+ */
+
+struct mrb_openssl_ssl_ctx {
+  SSL_CTX *ctx;
+};
+
+static void mrb_openssl_ssl_ctx_free(mrb_state *mrb, void *ptr);
+
+const static struct mrb_data_type mrb_openssl_ssl_ctx_type = { "OpenSSL::SSL_CTX", mrb_openssl_ssl_ctx_free };
+
+static void
+mrb_openssl_ssl_ctx_free(mrb_state *mrb, void *ptr)
+{
+  struct mrb_openssl_ssl_ctx *mrb_ctx = ptr;
+  if (mrb_ctx->ctx != NULL) {
+    SSL_CTX_free(mrb_ctx->ctx);
+  }
+  mrb_free(mrb, ptr);
+}
+
+static const SSL_METHOD *
+method_str_to_val(mrb_state *mrb, mrb_value str)
+{
+  const char *cp;
+  size_t len;
+
+  cp  = RSTRING_PTR(str);
+  len = RSTRING_LEN(str);
+  if (strncmp("TLSv1.0", cp, len) == 0) {
+    return TLSv1_client_method();
+  } else if (strncmp("TLSv1.1", cp, len) == 0) {
+    return TLSv1_1_client_method();
+  } else if (strncmp("TLSv1.2", cp, len) == 0) {
+    return TLSv1_2_client_method();
+  } else if (strncmp("any", cp, len) == 0) {
+    return SSLv23_client_method();
+  }
+
+  mrb_raisef(mrb, E_RUNTIME_ERROR, "TLS/SSL version %S is not supported", str);
+  return NULL;
+}
+
+static mrb_value
+mrb_openssl_ssl_ctx_init(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_openssl_ssl_ctx *mrb_ctx;
+  SSL_CTX *ctx;
+  const SSL_METHOD *method;
+  mrb_value str;
+
+  mrb_get_args(mrb, "S", &str);
+  method = method_str_to_val(mrb, str);
+
+  ctx = SSL_CTX_new(method);
+  if (ctx == NULL) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "SSL_CTX_new failed");
+  }
+
+  mrb_ctx = (struct mrb_openssl_ssl_ctx *)mrb_malloc(mrb, sizeof(*mrb_ctx));
+  mrb_ctx->ctx = ctx;
+  DATA_TYPE(self) = &mrb_openssl_ssl_ctx_type;
+  DATA_PTR(self)  = mrb_ctx;
+  return self;
+}
+
+static mrb_value
+mrb_openssl_ssl_ctx_load_verify_locations(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_openssl_ssl_ctx *mrb_ctx;
+  mrb_value str;
+  char *cp;
+
+  mrb_ctx = mrb_data_get_ptr(mrb, self, &mrb_openssl_ssl_ctx_type);
+  mrb_get_args(mrb, "S", &str);
+  cp = mrb_str_to_cstr(mrb, str);
+  if (SSL_CTX_load_verify_locations(mrb_ctx->ctx, cp, NULL) != 1) {
+    mrb_raisef(mrb, E_RUNTIME_ERROR, "SSL_CTX_load_verify_locations(\"%S\") failed", str);
+  }
+  return self;
+}
+
+static mrb_value
+mrb_openssl_ssl_ctx_set_alpn_protos(mrb_state *mrb, mrb_value self)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER)
+  struct mrb_openssl_ssl_ctx *mrb_ctx;
+  mrb_value buf, str;
+  mrb_int len;
+  unsigned char *cp;
+
+  mrb_ctx = mrb_data_get_ptr(mrb, self, &mrb_openssl_ssl_ctx_type);
+  mrb_get_args(mrb, "S", &str);
+  len = RSTRING_LEN(str);
+  buf = mrb_str_buf_new(mrb, len+1);
+  cp = (unsigned char *)RSTRING_PTR(buf);
+  *cp = (unsigned char)len; /* XXX len must be <= 255 */
+  memcpy(cp+1, RSTRING_PTR(str), len);
+  if (SSL_CTX_set_alpn_protos(mrb_ctx->ctx, cp, len+1) != 0) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "SSL_CTX_set_alpn_protos() failed");
+  }
+  return self;
+#else
+  mrb_raise(mrb, E_NOTIMP_ERROR, "SSL_CTX_set_alpn_protos() is not available");
+  return self;
+#endif
+}
+
+static mrb_value
+mrb_openssl_ssl_ctx_set_verify_depth(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_openssl_ssl_ctx *mrb_ctx;
+  mrb_int n;
+
+  mrb_ctx = mrb_data_get_ptr(mrb, self, &mrb_openssl_ssl_ctx_type);
+  mrb_get_args(mrb, "i", &n);
+  SSL_CTX_set_verify_depth(mrb_ctx->ctx, n);
+  return self;
+}
+
+static int
+ssl_ctx_verify_callback_ignorevalidity(int ok, X509_STORE_CTX *ctx)
+{
+  if (ok == 0) {
+    int ecode = X509_STORE_CTX_get_error(ctx);
+    if (ecode == X509_V_ERR_CERT_NOT_YET_VALID || ecode == X509_V_ERR_CERT_HAS_EXPIRED) {
+      X509_STORE_CTX_set_error(ctx, X509_V_OK);
+      return 1;
+    }
+  }
+  return ok;
+}
+
+static mrb_value
+mrb_openssl_ssl_ctx_set_verify(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_openssl_ssl_ctx *mrb_ctx;
+  mrb_value b = mrb_nil_value();
+  mrb_get_args(mrb, "|o", &b);
+  mrb_ctx = mrb_data_get_ptr(mrb, self, &mrb_openssl_ssl_ctx_type);
+  if (mrb_bool(b)) { // :ignore_certificate_validity
+    SSL_CTX_set_verify(mrb_ctx->ctx, SSL_VERIFY_PEER, ssl_ctx_verify_callback_ignorevalidity);
+  } else {
+    SSL_CTX_set_verify(mrb_ctx->ctx, SSL_VERIFY_PEER, NULL);
+  }
+  return self;
+}
+
+/*
+ * OpenSSL::SSL
+ */
+
+struct mrb_openssl_ssl {
+  SSL *ssl;
+};
+static void mrb_openssl_ssl_free(mrb_state *mrb, void *ptr);
+
+const static struct mrb_data_type mrb_openssl_ssl_type = { "OpenSSL::SSL", mrb_openssl_ssl_free };
+
+static void
+mrb_openssl_ssl_free(mrb_state *mrb, void *ptr)
+{
+  struct mrb_openssl_ssl *mrb_ssl = ptr;
+  if (mrb_ssl->ssl != NULL) {
+    SSL_free(mrb_ssl->ssl);
+  }
+  mrb_free(mrb, ptr);
+}
+
+int
+mrb_openssl_match_dns_id(const char *ref_id, const char *pr_id)
+{
+  const char *dotp, *pr_domain, *ref_domain;
+
+  if (strchr(pr_id, '*') == NULL) {
+    /* no wildcard characters - it's easy */
+    return strcasecmp(ref_id, pr_id) == 0;
+  }
+
+  /* Note: we don't support partial matching like "f*.com". */
+
+  if (pr_id[0] != '*' || pr_id[1] != '.') {
+    /* reject any wildcard identifier DOES NOT start with "*." */
+    return 0;
+  }
+
+  /* where pr_id = "*.example.com", pr_domain points to "example.com" */
+  pr_domain = pr_id + 2;
+
+  if (strchr(pr_domain, '*') != NULL) {
+    /* reject multiple wildcard characters (e.g. "*.*.com", "*.example.*") */
+    return 0;
+  }
+
+  /* where pr_domain = "example.com", dotp points to ".com" */
+  dotp = strchr(pr_domain, '.');
+  if (dotp == NULL) {
+    /* reject "*.tld" and "*." */
+    return 0;
+  }
+
+  if (! isalnum(dotp[1])) {
+    /* reject invalid domain name (e.g. "*.com.", "*.net..", "*.foo.-org") */
+    return 0;
+  }
+
+  ref_domain = strchr(ref_id, '.');
+  if (ref_domain == NULL) {
+    /* if ref_id has no dot, it never matches */
+    return 0;
+  }
+  ref_domain++;
+
+  return strcasecmp(pr_domain, ref_domain) == 0;
+}
+
+static mrb_value
+mrb_openssl_ssl_check_identity(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_openssl_ssl *mrb_ssl;
+  ASN1_STRING *as;
+  GENERAL_NAME *name;
+  STACK_OF(GENERAL_NAME) *altnames;
+  X509 *cert;
+  X509_NAME *subj;
+  int addrlen, cplen, i, j, n, ok;
+  char addrbuf[16];
+  const char *cp, *idstr;
+  mrb_value id;
+
+  mrb_ssl = mrb_data_get_ptr(mrb, self, &mrb_openssl_ssl_type);
+  mrb_get_args(mrb, "S", &id);
+  idstr = mrb_str_to_cstr(mrb, id);
+
+  cert = SSL_get_peer_certificate(mrb_ssl->ssl);
+  if (cert == NULL) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "SSL_get_peer_certificate() failed");
+  }
+
+  if (inet_pton(AF_INET, idstr, addrbuf) == 1) {
+    addrlen = 4;
+  } else if (inet_pton(AF_INET6, idstr, addrbuf) == 1) {
+    addrlen = 16;
+  } else {
+    addrlen = -1;
+  }
+
+  altnames = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
+  if (altnames != NULL) {
+    ok = -1;
+
+    n = sk_GENERAL_NAME_num(altnames);
+    for (i = 0; i < n; i++) {
+      name = sk_GENERAL_NAME_value(altnames, i);
+      if (addrlen == -1 && name->type == GEN_DNS) {
+        ok = 0;
+        cp = (const char *)ASN1_STRING_data(name->d.ia5);
+        cplen = ASN1_STRING_length(name->d.ia5);
+        if (strlen(cp) != cplen) {
+          /* contains NUL character! it should be a malicious certificate. */
+          ok = 0;
+          break;
+        }
+        if (mrb_openssl_match_dns_id(idstr, cp)) {
+          ok = 1;
+          break;
+        }
+      } else if (addrlen != -1 && name->type == GEN_IPADD) {
+        ok = 0;
+        cp = (const char *)ASN1_STRING_data(name->d.iPAddress);
+        cplen = ASN1_STRING_length(name->d.iPAddress);
+        if (cplen == addrlen && memcmp(cp, addrbuf, cplen) == 0) {
+          ok = 1;
+          break;
+        }
+      }
+    }
+    sk_GENERAL_NAME_free(altnames);
+
+    if (ok == 1) {
+      X509_free(cert);
+      return mrb_true_value();
+    } else if (ok == 0) {
+      X509_free(cert);
+      if (addrlen == -1) {
+        mrb_raisef(mrb, E_RUNTIME_ERROR, "dNSName of server certificate does not match \"%S\"", id);
+      }
+      else {
+        mrb_raisef(mrb, E_RUNTIME_ERROR, "iPAddress of server certificate does not match \"%S\"", id);
+      }
+    }
+  }
+
+  if (addrlen != -1) {
+    X509_free(cert);
+    mrb_raise(mrb, E_RUNTIME_ERROR, "identity is an IP address but server certificate does not have iPAddress");
+  }
+
+  subj = X509_get_subject_name(cert);
+  if (subj == NULL) {
+    X509_free(cert);
+    mrb_raise(mrb, E_RUNTIME_ERROR, "server certificate has neither subjectAltName nor subjectName");
+  }
+
+  j = -1;
+  do {
+    i = j;
+    j = X509_NAME_get_index_by_NID(subj, NID_commonName, i);
+  } while (j != -1);
+  if (i == -1) {
+    X509_free(cert);
+    mrb_raise(mrb, E_RUNTIME_ERROR, "server certificate has no commonName");
+  }
+
+   as = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subj, i));
+   if (as == NULL) {
+     X509_free(cert);
+     mrb_raise(mrb, E_RUNTIME_ERROR, "X509_NAME_ENTRY_get_data failed");
+   }
+   cp = (const char *)ASN1_STRING_data(as);
+   cplen = ASN1_STRING_length(as);
+   if (strlen(cp) != cplen) {
+     X509_free(cert);
+     mrb_raise(mrb, E_RUNTIME_ERROR, "CN includes NUL char!");
+   }
+
+   if (! mrb_openssl_match_dns_id(idstr, cp)) {
+     char buf[128];
+     snprintf(buf, sizeof(buf), "CN differs from Host: CN=%s, Host=%s", cp, idstr);
+     X509_free(cert);
+     mrb_raise(mrb, E_RUNTIME_ERROR, buf);
+   }
+
+   X509_free(cert);
+   return mrb_true_value();
+}
+
+static mrb_value
+mrb_openssl_ssl_connect(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_openssl_ssl *mrb_ssl;
+  int ret;
+
+  mrb_ssl = mrb_data_get_ptr(mrb, self, &mrb_openssl_ssl_type);
+  ret = SSL_connect(mrb_ssl->ssl);
+  if (ret != 1) {
+    mrb_value reason;
+    unsigned long e, ecode = 0;
+    long result;
+    while ((e = ERR_get_error()) != 0) {
+      ecode = e;
+    }
+    reason = mrb_str_new_cstr(mrb, ERR_reason_error_string(ecode));
+
+    result = SSL_get_verify_result(mrb_ssl->ssl);
+    if (result != X509_V_OK) {
+      mrb_str_cat_cstr(mrb, reason, ": ");
+      mrb_str_cat_cstr(mrb, reason, X509_verify_cert_error_string(result));
+    }
+
+    mrb_raisef(mrb, E_RUNTIME_ERROR, "SSL_connect() failed: %S", reason);
+  }
+  return self;
+}
+
+static mrb_value
+mrb_openssl_ssl_get_verify_result(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_openssl_ssl *mrb_ssl;
+  long result;
+
+  mrb_ssl = mrb_data_get_ptr(mrb, self, &mrb_openssl_ssl_type);
+  result = SSL_get_verify_result(mrb_ssl->ssl);
+  if (result != X509_V_OK) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "certificate verification error");
+  }
+  return mrb_true_value();
+}
+
+static mrb_value
+mrb_openssl_ssl_set_fd(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_openssl_ssl *mrb_ssl;
+  mrb_int fd;
+
+  mrb_ssl = mrb_data_get_ptr(mrb, self, &mrb_openssl_ssl_type);
+  mrb_get_args(mrb, "i", &fd);
+  if (SSL_set_fd(mrb_ssl->ssl, fd) == 0) {
+    mrb_raisef(mrb, E_RUNTIME_ERROR, "SSL_set_fd(%S) failed", mrb_fixnum_value(fd));
+  }
+  return self;
+}
+
+static mrb_value
+mrb_openssl_ssl_set_tlsext_host_name(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_openssl_ssl *mrb_ssl;
+  mrb_value str;
+  char *cp;
+
+  mrb_ssl = mrb_data_get_ptr(mrb, self, &mrb_openssl_ssl_type);
+  mrb_get_args(mrb, "S", &str);
+  cp = mrb_str_to_cstr(mrb, str);
+  if (SSL_set_tlsext_host_name(mrb_ssl->ssl, cp) == 0) {
+    mrb_raisef(mrb, E_RUNTIME_ERROR, "SSL_set_tlsext_host_name(\"%S\") failed", str);
+  }
+  return self;
+}
+
+static mrb_value
+mrb_openssl_ssl_read(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_openssl_ssl *mrb_ssl;
+  mrb_value buf;
+  mrb_int len = 0;
+  size_t bufsize;
+  int n;
+
+  mrb_ssl = mrb_data_get_ptr(mrb, self, &mrb_openssl_ssl_type);
+  mrb_get_args(mrb, "|i", &len);
+
+  if (len > 0) {
+    bufsize = len;
+  } else {
+    bufsize = 16384;    /* TLS record size */
+  }
+  buf = mrb_str_buf_new(mrb, bufsize);
+  n = SSL_read(mrb_ssl->ssl, RSTRING_PTR(buf), bufsize);
+  if (n == 0) {
+    return mrb_nil_value();
+  } else if (n < 0) {
+    mrb_raisef(mrb, E_RUNTIME_ERROR, "SSL_read returns %S", mrb_fixnum_value(n));
+  }
+  mrb_str_resize(mrb, buf, n);
+  return buf;
+}
+
+static mrb_value
+mrb_openssl_ssl_shutdown(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_openssl_ssl *mrb_ssl;
+  int r;
+
+  mrb_ssl = mrb_data_get_ptr(mrb, self, &mrb_openssl_ssl_type);
+  r = SSL_shutdown(mrb_ssl->ssl);
+  if (r < 0) {
+    mrb_raisef(mrb, E_RUNTIME_ERROR, "SSL_shutdown returns %S", mrb_fixnum_value(r));
+  }
+  return mrb_fixnum_value(r);
+}
+
+static mrb_value
+mrb_openssl_ssl_write(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_openssl_ssl *mrb_ssl;
+  mrb_int len;
+  int n;
+  char *cp;
+
+  mrb_ssl = mrb_data_get_ptr(mrb, self, &mrb_openssl_ssl_type);
+  mrb_get_args(mrb, "s", &cp, &len);
+  n = SSL_write(mrb_ssl->ssl, cp, len);
+  return mrb_fixnum_value(n);
+}
+
+static mrb_value
+mrb_openssl_ssl_init(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_openssl_ssl *mrb_ssl;
+  struct mrb_openssl_ssl_ctx *mrb_ctx;
+  SSL *ssl;
+  mrb_value v_ctx;
+
+  mrb_get_args(mrb, "o", &v_ctx);
+  mrb_ctx = mrb_data_get_ptr(mrb, v_ctx, &mrb_openssl_ssl_ctx_type);
+
+  mrb_ssl = (struct mrb_openssl_ssl *)mrb_malloc(mrb, sizeof(*mrb_ssl));
+
+  ssl = SSL_new(mrb_ctx->ctx);
+  if (ssl == NULL) {
+    mrb_free(mrb, mrb_ssl);
+    mrb_raise(mrb, E_RUNTIME_ERROR, "SSL_new failed");
+  }
+
+  mrb_ssl->ssl = ssl;
+  DATA_TYPE(self) = &mrb_openssl_ssl_type;
+  DATA_PTR(self)  = mrb_ssl;
+  return self;
+}
+
+void
+mrb_mruby_tls_openssl_gem_init(mrb_state *mrb)
+{
+  struct RClass *c_ctx, *c_ssl, *m;
+
+  SSL_load_error_strings();
+  SSL_library_init();
+
+  m = mrb_define_module(mrb, "OpenSSL");
+
+  c_ssl = mrb_define_class_under(mrb, m, "SSL", mrb->object_class);
+  MRB_SET_INSTANCE_TT(c_ssl, MRB_TT_DATA);
+  mrb_define_method(mrb, c_ssl, "initialize", mrb_openssl_ssl_init, MRB_ARGS_NONE());
+  mrb_define_method(mrb, c_ssl, "check_identity", mrb_openssl_ssl_check_identity, MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, c_ssl, "connect", mrb_openssl_ssl_connect, MRB_ARGS_NONE());
+  mrb_define_method(mrb, c_ssl, "get_verify_result", mrb_openssl_ssl_get_verify_result, MRB_ARGS_NONE());
+  mrb_define_method(mrb, c_ssl, "read", mrb_openssl_ssl_read, MRB_ARGS_OPT(2));
+  mrb_define_method(mrb, c_ssl, "set_fd", mrb_openssl_ssl_set_fd, MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, c_ssl, "set_tlsext_host_name", mrb_openssl_ssl_set_tlsext_host_name, MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, c_ssl, "shutdown", mrb_openssl_ssl_shutdown, MRB_ARGS_NONE());
+  mrb_define_method(mrb, c_ssl, "write", mrb_openssl_ssl_write, MRB_ARGS_REQ(1));
+
+  c_ctx = mrb_define_class_under(mrb, m, "SSL_CTX", mrb->object_class);
+  MRB_SET_INSTANCE_TT(c_ctx, MRB_TT_DATA);
+  mrb_define_method(mrb, c_ctx, "initialize", mrb_openssl_ssl_ctx_init, MRB_ARGS_NONE());
+  mrb_define_method(mrb, c_ctx, "load_verify_locations", mrb_openssl_ssl_ctx_load_verify_locations, MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, c_ctx, "set_alpn_protos", mrb_openssl_ssl_ctx_set_alpn_protos, MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, c_ctx, "set_verify", mrb_openssl_ssl_ctx_set_verify, MRB_ARGS_NONE());
+  mrb_define_method(mrb, c_ctx, "set_verify_depth", mrb_openssl_ssl_ctx_set_verify_depth, MRB_ARGS_REQ(1));
+}
+
+void
+mrb_mruby_tls_openssl_gem_final(mrb_state *mrb)
+{
+}
Index: EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/test/openssl.rb
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/test/openssl.rb	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/test/openssl.rb	(revision 331)
@@ -0,0 +1,29 @@
+assert('certificate identity matching') do
+  def ok(ref_id, pr_id)
+    msg = "matching TLS identity: reference=#{ref_id.inspect}, presented=#{pr_id.inspect}"
+    assert_true(OpenSSLTest.match_dns_id(ref_id, pr_id), msg)
+  end
+  def ng(ref_id, pr_id)
+    msg = "matching TLS identity: reference=#{ref_id.inspect}, presented=#{pr_id.inspect}"
+    assert_false(OpenSSLTest.match_dns_id(ref_id, pr_id), msg)
+  end
+
+  ok "www.example.com", "www.example.com"
+  ok "WwW.ExAmPlE.CoM", "wWw.eXaMpLe.cOm"
+
+  ok "www.example.com", "*.example.com"
+  ok "WwW.ExAmPlE.CoM", "*.eXaMpLe.cOm"
+  ok "www.a.example.com", "*.a.example.com"
+
+  ng "www.example.com", "*"
+  ng "www.example.com", "w*.example.com"
+  ng "www.example.com", "*w.example.com"
+  ng "www.example.com", "www.*.com"
+  ng "example.com", "*."
+  ng "example.com", "*.com"
+  ng "example.com.", "*.com."
+
+  ng "example.com", "*.example.com"
+  ng "foo.bar.example.com", "*.example.com"
+  ng "foo.bar.example.com", "*.*.example.com"
+end
Index: EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/test/test_openssl.c
===================================================================
--- EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/test/test_openssl.c	(revision 331)
+++ EcnlProtoTool/trunk/mrbgems/mruby-tls-openssl/test/test_openssl.c	(revision 331)
@@ -0,0 +1,23 @@
+#include "mruby.h"
+#include "mruby/string.h"
+
+extern int mrb_openssl_match_dns_id(const char *, const char *);
+
+mrb_value
+mrb_tls_openssl_test_match_dns_id(mrb_state *mrb, mrb_value klass)
+{
+  mrb_value refid, prid;
+  int result;
+
+  mrb_get_args(mrb, "SS", &refid, &prid);
+  result = mrb_openssl_match_dns_id(mrb_str_to_cstr(mrb, refid), mrb_str_to_cstr(mrb, prid));
+  return mrb_bool_value(result);
+}
+
+void
+mrb_mruby_tls_openssl_gem_test(mrb_state *mrb)
+{
+  struct RClass *c = mrb_define_module(mrb, "OpenSSLTest");
+
+  mrb_define_class_method(mrb, c, "match_dns_id", mrb_tls_openssl_test_match_dns_id, MRB_ARGS_REQ(2));
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/.cproject
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/.cproject	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/.cproject	(revision 331)
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="com.renesas.cdt.rz.debug.win32.configuration.Id.1552447583">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.renesas.cdt.rz.debug.win32.configuration.Id.1552447583" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactName="mruby" buildArtefactType="com.renesas.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=com.renesas.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf *.lst *.lis *.lpp *.map libgcc.a" description="" id="com.renesas.cdt.rz.debug.win32.configuration.Id.1552447583" name="Debug" parent="com.renesas.cdt.rz.debug.win32.configuration.Id">
+					<folderInfo id="com.renesas.cdt.rz.debug.win32.configuration.Id.1552447583." name="/" resourcePath="">
+						<toolChain id="com.renesas.cdt.rz.debug.win32.toolchain.Id.87786683" name="KPIT GNUARM-NONE-EABI Toolchain" superClass="com.renesas.cdt.rz.debug.win32.toolchain.Id">
+							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.PE" id="com.renesas.cdt.rz.debug.win32.targetplatform.Id.1600182357" name="Target Platform" osList="all" superClass="com.renesas.cdt.rz.debug.win32.targetplatform.Id"/>
+							<builder buildPath="${workspace_loc:/mruby-1.3.0}" id="com.renesas.cdt.rz.debug.win32.builder.Id.1846611762" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Builder" superClass="com.renesas.cdt.rz.debug.win32.builder.Id"/>
+							<tool id="com.renesas.cdt.rz.debug.win32.tool.libgen.Id.1116635171" name="Library Generator" superClass="com.renesas.cdt.rz.debug.win32.tool.libgen.Id">
+								<option id="com.renesas.cdt.core.LibraryGenerator.option.ctype.458951408" name="ctype.h : æå­ãæ±ããã§ãã¯ãã¾ã" superClass="com.renesas.cdt.core.LibraryGenerator.option.ctype" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.core.LibraryGenerator.option.math.1642753503" name="math.h : ä¸è§é¢æ°ãªã©æ°å¤ã®è¨ç®ãè¡ãã¾ã" superClass="com.renesas.cdt.core.LibraryGenerator.option.math" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.core.LibraryGenerator.option.stdio.961659227" name="stdio.h : å
+¥å/åºåãè¡ãã¾ã" superClass="com.renesas.cdt.core.LibraryGenerator.option.stdio" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.core.LibraryGenerator.option.stdlib.509673709" name="stdlib.h : æ ¼ç´é åã®ç®¡çãªã© C ãã­ã°ã©ã ã®æ¨æºå¦çãè¡ãã¾ã" superClass="com.renesas.cdt.core.LibraryGenerator.option.stdlib" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.core.LibraryGenerator.option.string.1550848672" name="string.h : æå­åã®æ¯è¼ã¨ã³ãã¼ãè¡ãã¾ã" superClass="com.renesas.cdt.core.LibraryGenerator.option.string" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.core.LibraryGenerator.option.selectLibrary.422121936" name="ã©ã¤ãã©ãªã¼ã®é¸æ" superClass="com.renesas.cdt.core.LibraryGenerator.option.selectLibrary" value="com.renesas.core.LibraryGenerator.option.selectLibrary.newLib" valueType="enumerated"/>
+								<option id="com.renesas.cdt.core.LibraryGenerator.option.libraryType.1589977374" name="ã©ã¤ãã©ãªã¼å" superClass="com.renesas.cdt.core.LibraryGenerator.option.libraryType" value="com.renesas.cdt.core.LibraryGenerator.option.libraryType.projectBuilt" valueType="enumerated"/>
+								<option id="com.renesas.cdt.core.LibraryGenerator.option.misc9.1198648676" name="åé¢æ°ããåºåãã¡ã¤ã«å
+ã®å¯¾å¿ããã»ã¯ã·ã§ã³ã«é
+ç½®ãã (-ffunction-sections)" superClass="com.renesas.cdt.core.LibraryGenerator.option.misc9" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.core.LibraryGenerator.option.misc14.1587684955" name="é¢æ°ã®ã¢ãã¬ã¹ãã¬ã¸ã¹ã¿ã¼ã«ç½®ããªã (-fno-function-cse)" superClass="com.renesas.cdt.core.LibraryGenerator.option.misc14" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.core.LibraryGenerator.option.misc36.1213035210" name="Parse the whole compilation unit before starting to produce code ( -funit-at-a-time)" superClass="com.renesas.cdt.core.LibraryGenerator.option.misc36" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.core.LibraryGenerator.option.misc10.1626842453" name="åãã¼ã¿ããåºåãã¡ã¤ã«å
+ã®å¯¾å¿ããã»ã¯ã·ã§ã³ã«é
+ç½®ãã (-fdata-sections)" superClass="com.renesas.cdt.core.LibraryGenerator.option.misc10" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.core.LibraryGenerator.option.misc37.476113883" name="Align branch targets to a power-of-two boundary (-falign-jumps)" superClass="com.renesas.cdt.core.LibraryGenerator.option.misc37" value="true" valueType="boolean"/>
+							</tool>
+							<tool id="com.renesas.cdt.rz.debug.win32.tool.compiler.Id.2114772705" name="Compiler" superClass="com.renesas.cdt.rz.debug.win32.tool.compiler.Id">
+								<option defaultValue="true" id="com.renesas.cdt.core.Compiler.option.misc2.2071139574" name="æ¨æºã·ã¹ãã ã»ãã£ã¬ã¯ããªã¼ã§ãããã¼ã»ãã¡ã¤ã«ãæ¤ç´¢ããªã (-nostdinc)" superClass="com.renesas.cdt.core.Compiler.option.misc2" value="false" valueType="boolean"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.architecture.712090671" name="ã¢ã¼ã­ãã¯ãã£ã¼" superClass="com.renesas.cdt.rz.Debug.Compiler.option.architecture" value="com.renesas.cdt.rz.Debug.Compiler.option.architecture.armv7a" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.cpuType.1792387458" name="CPU ã¿ã¤ã" superClass="com.renesas.cdt.rz.Debug.Compiler.option.cpuType" value="com.renesas.cdt.rz.Debug.Compiler.option.cpuType.rza" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.dataEndian.1830244232" name="ã¨ã³ãã£ã¢ã³" superClass="com.renesas.cdt.rz.Debug.Compiler.option.dataEndian" value="com.renesas.cdt.rz.Debug.Compiler.option.dataEndian.little" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.instructionset.1447259851" name="å½ä»¤ã»ãã" superClass="com.renesas.cdt.rz.Debug.Compiler.option.instructionset" value="com.renesas.cdt.rz.Debug.Compiler.option.instructionset.arm" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.interworking.260043818" name="ã¤ã³ã¿ã¼ã»ã¯ã¼ã­ã³ã° (-mthumb-interwork)" superClass="com.renesas.cdt.rz.Debug.Compiler.option.interworking" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.targetfpu.367057389" name="ã¿ã¼ã²ãã FPU (-mfpu)" superClass="com.renesas.cdt.rz.Debug.Compiler.option.targetfpu" value="com.renesas.cdt.rz.Debug.Compiler.option.targetfpu.vfp" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.floatingpointabi.1426976645" name="æµ®åå°æ°ç¹ ABI (-mfloat-abi=name)" superClass="com.renesas.cdt.rz.Debug.Compiler.option.floatingpointabi" value="com.renesas.cdt.rz.Debug.Compiler.option.floatingpointabi.soft" valueType="enumerated"/>
+								<option id="com.renesas.cdt.core.Compiler.option.warnStackSize.1147490000" name="Warn if stack size exceeds the limit (-Wstack-usage) (H')" superClass="com.renesas.cdt.core.Compiler.option.warnStackSize" value="100" valueType="string"/>
+								<option id="com.renesas.cdt.core.Compiler.option.CPUSeries.1824596418" name="CPU ã·ãªã¼ãº" superClass="com.renesas.cdt.core.Compiler.option.CPUSeries" value="RZ/A" valueType="string"/>
+								<option id="com.renesas.cdt.core.Compiler.option.device.961121392" name="Device" superClass="com.renesas.cdt.core.Compiler.option.device" value="R7S721001" valueType="string"/>
+								<option id="com.renesas.cdt.core.Compiler.option.deviceShortName.635132041" name="DeviceShortName" superClass="com.renesas.cdt.core.Compiler.option.deviceShortName" value="R7S721001" valueType="string"/>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.rz.Debug.Compiler.option.macroDefines.57380421" name="ãã¯ã­å®ç¾©" superClass="com.renesas.cdt.rz.Debug.Compiler.option.macroDefines" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="SIMULATOR_DEBUG"/>
+									<listOptionValue builtIn="false" value="CPPAPP"/>
+								</option>
+								<inputType id="%Base.Compiler.C.InputType.Id.379655366" name="C å
+¥å" superClass="%Base.Compiler.C.InputType.Id"/>
+								<inputType id="Base.Compiler.CPP.InputType.Id.1101890027" name="C++ å
+¥å" superClass="Base.Compiler.CPP.InputType.Id"/>
+							</tool>
+							<tool id="com.renesas.cdt.rz.debug.win32.tool.assembler.Id.1166037999" name="Assembler" superClass="com.renesas.cdt.rz.debug.win32.tool.assembler.Id">
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.architecture.1178720663" name="ã¢ã¼ã­ãã¯ãã£ã¼" superClass="com.renesas.cdt.rz.Debug.Assembler.option.architecture" value="com.renesas.cdt.rz.Debug.Assembler.option.architecture.armv7a" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.cpuType.1700798679" name="CPU ã¿ã¤ã" superClass="com.renesas.cdt.rz.Debug.Assembler.option.cpuType" value="com.renesas.cdt.rz.Debug.Assembler.option.cpuType.rza" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.dataEndian.835685972" name="ã¨ã³ãã£ã¢ã³" superClass="com.renesas.cdt.rz.Debug.Assembler.option.dataEndian" value="com.renesas.cdt.rz.Debug.Assembler.option.dataEndian.little" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.instructionset.1591801771" name="å½ä»¤ã»ãã" superClass="com.renesas.cdt.rz.Debug.Assembler.option.instructionset" value="com.renesas.cdt.rz.Debug.Assembler.option.instructionset.arm" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.targetfpu.1672411105" name="ã¿ã¼ã²ãã FPU (-mfpu)" superClass="com.renesas.cdt.rz.Debug.Assembler.option.targetfpu" value="com.renesas.cdt.rz.Debug.Assembler.option.targetfpu.vfp" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.floatingpointabi.1400638226" name="æµ®åå°æ°ç¹ ABI (-mfloat-abi=name)" superClass="com.renesas.cdt.rz.Debug.Assembler.option.floatingpointabi" value="com.renesas.cdt.rz.Debug.Assembler.option.floatingpointabi.soft" valueType="enumerated"/>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.core.Assembler.option.includeFileDirectories.1632699435" name="ã¤ã³ã¯ã«ã¼ãã»ãã¡ã¤ã«ã»ãã£ã¬ã¯ããªã¼" superClass="com.renesas.cdt.core.Assembler.option.includeFileDirectories" valueType="includePath">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}/src&quot;"/>
+								</option>
+								<inputType id="%Base.Assembler.inputType.Id.1006307562" name="ã¢ã»ã³ãã©ã¼å
+¥åã¿ã¤ã" superClass="%Base.Assembler.inputType.Id"/>
+							</tool>
+							<tool id="com.renesas.cdt.rz.debug.win32.tool.linker.Id.497903742" name="Linker" superClass="com.renesas.cdt.rz.debug.win32.tool.linker.Id">
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.rz.Debug.Linker.option.archiveSearchDirectories.2062570669" name="ã¢ã¼ã«ã¤ãæ¤ç´¢ãã£ã¬ã¯ããªã¼" superClass="com.renesas.cdt.rz.Debug.Linker.option.archiveSearchDirectories" valueType="stringList">
+									<listOptionValue builtIn="false" value="&quot;${CONFIGDIR}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${TCINSTALL}/lib/gcc/arm-none-eabi/${GCC_VERSION}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${TCINSTALL}/arm-none-eabi/lib&quot;"/>
+								</option>
+								<option id="com.renesas.cdt.rz.Debug.Linker.option.dataEndian.718941051" name="ã¨ã³ãã£ã¢ã³" superClass="com.renesas.cdt.rz.Debug.Linker.option.dataEndian" value="com.renesas.cdt.rz.Debug.Linker.option.dataEndian.little" valueType="enumerated"/>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.rz.Debug.Linker.option.archiveLibraryFiles.6194456" name="ã¢ã¼ã«ã¤ã ( ã©ã¤ãã©ãªã¼ ) ãã¡ã¤ã«" superClass="com.renesas.cdt.rz.Debug.Linker.option.archiveLibraryFiles" valueType="stringList">
+									<listOptionValue builtIn="false" value="${BuildArtifactFileBaseName}"/>
+									<listOptionValue builtIn="false" value="gcc"/>
+									<listOptionValue builtIn="false" value="stdc++"/>
+								</option>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.core.Linker.option.userDefinedOptions.947383497" name="ã¦ã¼ã¶ã¼å®ç¾©ãªãã·ã§ã³" superClass="com.renesas.cdt.core.Linker.option.userDefinedOptions" valueType="stringList">
+									<listOptionValue builtIn="false" value="-e_PowerON_Reset"/>
+								</option>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.core.Linker.option.linkOrderList.298210254" name="" superClass="com.renesas.cdt.core.Linker.option.linkOrderList" valueType="stringList">
+									<listOptionValue builtIn="false" value="&quot;.\src\hardware_setup.o&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;.\src\interrupt_handlers.o&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;.\src\mruby.o&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;.\src\reset_program.o&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;.\src\vector_table.o&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;.\libmruby.a&quot;"/>
+								</option>
+							</tool>
+							<tool id="com.renesas.cdt.rz.debug.win32.tool.objcopy.Id.1923834783" name="Objcopy" superClass="com.renesas.cdt.rz.debug.win32.tool.objcopy.Id"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="mruby.com.renesas.cdt.rz.projectType.win32.Id.3696189" name="Executable (Renesas)" projectType="com.renesas.cdt.rz.projectType.win32.Id"/>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+	<storageModule moduleId="refreshScope" versionNumber="2">
+		<configuration configurationName="Debug">
+			<resource resourceType="PROJECT" workspacePath="/mruby"/>
+		</configuration>
+	</storageModule>
+</cproject>
Index: EcnlProtoTool/trunk/mruby-1.3.0/.gitignore
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/.gitignore	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/.gitignore	(revision 331)
@@ -0,0 +1,26 @@
+# /
+*.bak
+*.d
+*.o
+/benchmark/**/*.dat
+/benchmark/*.pdf
+/benchmark/*.png
+*.orig
+*.pdb
+*.rej
+*.sav
+*.swp
+*.tmp
+*~
+.DS_Store
+.ccmalloc
+.svn
+/.git
+cscope.out
+tags
+/src/y.tab.c
+/bin
+/build
+/mruby-source-*.gem
+doc/api
+.yardoc
Index: EcnlProtoTool/trunk/mruby-1.3.0/.gitlab-ci.yml
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/.gitlab-ci.yml	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/.gitlab-ci.yml	(revision 331)
@@ -0,0 +1,3214 @@
+---
+stages:
+- pretest
+- test
+pretest:
+  stage: pretest
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.1
+  tags:
+  - linux
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+  script: "./minirake all test"
+Test gcc-4.7 32bit:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-m32 -DMRB_WORD_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 32bit_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 32bit_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 32bit_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 32bit_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-m32 -DMRB_INT16=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 32bit_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 32bit_int16_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 32bit_int16_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 32bit_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-m32 -DMRB_INT64=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 32bit_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 32bit_float:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 32bit_float_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 32bit_float_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 32bit_float_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 32bit_float_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 32bit_float_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 64bit:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 64bit_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 64bit_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-DMRB_NAN_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 64bit_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 64bit_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-DMRB_INT16=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 64bit_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 64bit_int16_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 64bit_int16_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 64bit_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 64bit_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 64bit_float:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 64bit_float_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 64bit_float_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 64bit_float_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 64bit_float_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.7 64bit_float_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc47_0.7
+  variables:
+    CC: gcc-4.7
+    CXX: g++-4.7
+    LD: gcc-4.7
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 32bit:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-m32 -DMRB_WORD_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 32bit_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 32bit_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 32bit_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 32bit_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-m32 -DMRB_INT16=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 32bit_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 32bit_int16_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 32bit_int16_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 32bit_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-m32 -DMRB_INT64=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 32bit_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 32bit_float:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 32bit_float_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 32bit_float_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 32bit_float_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 32bit_float_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 32bit_float_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 64bit:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 64bit_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 64bit_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-DMRB_NAN_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 64bit_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 64bit_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-DMRB_INT16=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 64bit_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 64bit_int16_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 64bit_int16_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 64bit_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 64bit_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 64bit_float:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 64bit_float_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 64bit_float_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 64bit_float_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 64bit_float_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.8 64bit_float_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc48_0.7
+  variables:
+    CC: gcc-4.8
+    CXX: g++-4.8
+    LD: gcc-4.8
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 32bit:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-m32 -DMRB_WORD_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 32bit_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 32bit_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 32bit_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 32bit_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-m32 -DMRB_INT16=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 32bit_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 32bit_int16_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 32bit_int16_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 32bit_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-m32 -DMRB_INT64=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 32bit_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 32bit_float:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 32bit_float_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 32bit_float_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 32bit_float_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 32bit_float_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 32bit_float_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 64bit:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 64bit_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 64bit_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-DMRB_NAN_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 64bit_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 64bit_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-DMRB_INT16=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 64bit_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 64bit_int16_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 64bit_int16_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 64bit_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 64bit_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 64bit_float:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 64bit_float_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 64bit_float_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 64bit_float_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 64bit_float_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-4.9 64bit_float_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc49_0.7
+  variables:
+    CC: gcc-4.9
+    CXX: g++-4.9
+    LD: gcc-4.9
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-5 32bit:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-m32 -DMRB_WORD_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-5 32bit_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-5 32bit_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-5 32bit_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-5 32bit_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-m32 -DMRB_INT16=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-5 32bit_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-5 32bit_int16_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-5 32bit_int16_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-5 32bit_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-m32 -DMRB_INT64=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-5 32bit_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-5 32bit_float:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-5 32bit_float_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-5 32bit_float_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-5 32bit_float_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-5 32bit_float_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-5 32bit_float_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-5 64bit:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-5 64bit_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-5 64bit_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-DMRB_NAN_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-5 64bit_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-5 64bit_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-DMRB_INT16=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-5 64bit_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-5 64bit_int16_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-5 64bit_int16_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-5 64bit_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-5 64bit_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-5 64bit_float:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-5 64bit_float_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-5 64bit_float_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-5 64bit_float_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-5 64bit_float_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-5 64bit_float_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc5_0.7
+  variables:
+    CC: gcc-5
+    CXX: g++-5
+    LD: gcc-5
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-6 32bit:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-m32 -DMRB_WORD_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-6 32bit_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-6 32bit_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-6 32bit_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-6 32bit_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-m32 -DMRB_INT16=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-6 32bit_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-6 32bit_int16_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-6 32bit_int16_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-6 32bit_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-m32 -DMRB_INT64=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-6 32bit_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-6 32bit_float:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-6 32bit_float_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-6 32bit_float_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-6 32bit_float_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-6 32bit_float_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-6 32bit_float_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test gcc-6 64bit:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-6 64bit_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-6 64bit_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-DMRB_NAN_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-6 64bit_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-6 64bit_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-DMRB_INT16=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-6 64bit_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-6 64bit_int16_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-6 64bit_int16_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-6 64bit_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-6 64bit_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-6 64bit_float:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-6 64bit_float_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-6 64bit_float_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-6 64bit_float_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-6 64bit_float_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test gcc-6 64bit_float_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:gcc6_0.7
+  variables:
+    CC: gcc-6
+    CXX: g++-6
+    LD: gcc-6
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.5 32bit:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-m32 -DMRB_WORD_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.5 32bit_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.5 32bit_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.5 32bit_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.5 32bit_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-m32 -DMRB_INT16=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.5 32bit_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.5 32bit_int16_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.5 32bit_int16_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.5 32bit_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-m32 -DMRB_INT64=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.5 32bit_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.5 32bit_float:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.5 32bit_float_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.5 32bit_float_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.5 32bit_float_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.5 32bit_float_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.5 32bit_float_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.5 64bit:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.5 64bit_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.5 64bit_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-DMRB_NAN_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.5 64bit_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.5 64bit_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-DMRB_INT16=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.5 64bit_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.5 64bit_int16_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.5 64bit_int16_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.5 64bit_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.5 64bit_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.5 64bit_float:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.5 64bit_float_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.5 64bit_float_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.5 64bit_float_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.5 64bit_float_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.5 64bit_float_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang35_0.7
+  variables:
+    CC: clang-3.5
+    CXX: clang++-3.5
+    LD: clang-3.5
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.6 32bit:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-m32 -DMRB_WORD_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.6 32bit_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.6 32bit_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.6 32bit_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.6 32bit_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-m32 -DMRB_INT16=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.6 32bit_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.6 32bit_int16_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.6 32bit_int16_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.6 32bit_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-m32 -DMRB_INT64=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.6 32bit_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.6 32bit_float:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.6 32bit_float_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.6 32bit_float_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.6 32bit_float_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.6 32bit_float_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.6 32bit_float_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.6 64bit:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.6 64bit_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.6 64bit_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-DMRB_NAN_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.6 64bit_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.6 64bit_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-DMRB_INT16=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.6 64bit_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.6 64bit_int16_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.6 64bit_int16_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.6 64bit_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.6 64bit_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.6 64bit_float:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.6 64bit_float_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.6 64bit_float_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.6 64bit_float_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.6 64bit_float_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.6 64bit_float_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang36_0.7
+  variables:
+    CC: clang-3.6
+    CXX: clang++-3.6
+    LD: clang-3.6
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.7 32bit:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-m32 -DMRB_WORD_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.7 32bit_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.7 32bit_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.7 32bit_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.7 32bit_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-m32 -DMRB_INT16=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.7 32bit_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.7 32bit_int16_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.7 32bit_int16_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.7 32bit_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-m32 -DMRB_INT64=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.7 32bit_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.7 32bit_float:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.7 32bit_float_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.7 32bit_float_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.7 32bit_float_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.7 32bit_float_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.7 32bit_float_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.7 64bit:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.7 64bit_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.7 64bit_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-DMRB_NAN_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.7 64bit_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.7 64bit_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-DMRB_INT16=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.7 64bit_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.7 64bit_int16_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.7 64bit_int16_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.7 64bit_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.7 64bit_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.7 64bit_float:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.7 64bit_float_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.7 64bit_float_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.7 64bit_float_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.7 64bit_float_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.7 64bit_float_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang37_0.7
+  variables:
+    CC: clang-3.7
+    CXX: clang++-3.7
+    LD: clang-3.7
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.8 32bit:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-m32 -DMRB_WORD_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.8 32bit_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.8 32bit_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.8 32bit_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.8 32bit_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-m32 -DMRB_INT16=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.8 32bit_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.8 32bit_int16_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.8 32bit_int16_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.8 32bit_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-m32 -DMRB_INT64=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.8 32bit_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.8 32bit_float:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.8 32bit_float_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.8 32bit_float_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.8 32bit_float_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.8 32bit_float_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.8 32bit_float_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.8 64bit:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.8 64bit_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.8 64bit_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-DMRB_NAN_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.8 64bit_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.8 64bit_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-DMRB_INT16=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.8 64bit_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.8 64bit_int16_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.8 64bit_int16_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.8 64bit_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.8 64bit_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.8 64bit_float:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.8 64bit_float_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.8 64bit_float_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.8 64bit_float_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.8 64bit_float_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.8 64bit_float_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang38_0.7
+  variables:
+    CC: clang-3.8
+    CXX: clang++-3.8
+    LD: clang-3.8
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.9 32bit:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-m32 -DMRB_WORD_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.9 32bit_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-m32 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.9 32bit_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-m32 -DMRB_NAN_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.9 32bit_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-m32 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.9 32bit_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-m32 -DMRB_INT16=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.9 32bit_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.9 32bit_int16_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.9 32bit_int16_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-m32 -DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.9 32bit_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-m32 -DMRB_INT64=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.9 32bit_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-m32 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.9 32bit_float:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.9 32bit_float_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.9 32bit_float_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.9 32bit_float_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.9 32bit_float_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.9 32bit_float_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-m32 -DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: "-m32"
+  script: env; ./minirake --verbose all test
+Test clang-3.9 64bit:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.9 64bit_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.9 64bit_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-DMRB_NAN_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.9 64bit_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.9 64bit_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-DMRB_INT16=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.9 64bit_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.9 64bit_int16_nan:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.9 64bit_int16_nan_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-DMRB_INT16=1 -DMRB_NAN_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.9 64bit_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.9 64bit_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.9 64bit_float:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.9 64bit_float_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.9 64bit_float_int16:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.9 64bit_float_int16_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT16=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.9 64bit_float_int64:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
+Test clang-3.9 64bit_float_int64_utf8:
+  stage: test
+  image: registry.gitlab.com/dabroz/mruby:clang39_0.7
+  variables:
+    CC: clang-3.9
+    CXX: clang++-3.9
+    LD: clang-3.9
+    CFLAGS: "-DMRB_USE_FLOAT=1 -DMRB_INT64=1 -DMRB_WORD_BOXING=1 -DMRB_UTF8_STRING=1"
+    LDFLAGS: ''
+  script: env; ./minirake --verbose all test
Index: EcnlProtoTool/trunk/mruby-1.3.0/.info
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/.info	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/.info	(revision 331)
@@ -0,0 +1,7 @@
+TOOL_CHAIN=KPIT GNUARM-NONE-EABI Toolchain
+VERSION=v16.01
+TC_INSTALL=C:\Program Files (x86)\KPIT\GNUARM-NONEv16.01-EABI\arm-none-eabi\arm-none-eabi\
+GCC_STRING=5.2-GNUARM-NONE_v16.01
+VERSION_IDE=
+E2STUDIO_VERSION=5.4.0.018
+ACTIVE_CONFIGURATION=Debug
Index: EcnlProtoTool/trunk/mruby-1.3.0/.project
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/.project	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/.project	(revision 331)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>mruby-1.3.0</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+			<triggers>clean,full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>org.eclipse.cdt.core.ccnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+	</natures>
+</projectDescription>
Index: EcnlProtoTool/trunk/mruby-1.3.0/.travis.yml
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/.travis.yml	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/.travis.yml	(revision 331)
@@ -0,0 +1,18 @@
+language: c
+
+sudo: false
+
+matrix:
+  include:
+    - os: linux
+      sudo: 9000
+    - os: osx
+      osx_image: xcode7.1
+
+addons:
+  apt:
+    packages:
+      - gperf
+
+env: MRUBY_CONFIG=travis_config.rb
+script: "./minirake all test"
Index: EcnlProtoTool/trunk/mruby-1.3.0/.yardopts
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/.yardopts	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/.yardopts	(revision 331)
@@ -0,0 +1,17 @@
+--markup markdown
+--plugin mruby
+--plugin coderay
+--output-dir doc/api
+
+src/**/*.c
+mrblib/**/*.rb
+include/**/*.h
+
+mrbgems/*/src/**/*.c
+mrbgems/*/mrblib/**/*.rb
+mrbgems/*/include/**/*.h
+-
+AUTHORS
+MITL
+CONTRIBUTING.md
+doc/guides/*.md
Index: EcnlProtoTool/trunk/mruby-1.3.0/AUTHORS
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/AUTHORS	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/AUTHORS	(revision 331)
@@ -0,0 +1,38 @@
+Original Authors "mruby developers" are:
+   Yukihiro Matsumoto
+   SCSK KYUSHU CORPORATION
+   Kyushu Institute of Technology
+   Network Applied Communication Laboratory, Inc.
+   Daniel Bovensiepen
+   Jon Maken
+   Bjorn De Meyer
+   Yuichiro MASUI
+   Masamitsu MURASE
+   Masaki Muranaka
+   Internet Initiative Japan Inc.
+   Tadashi FUKUZAWA
+   MATSUMOTO Ryosuke
+   Yasuhiro Matsumoto
+   Koji Yoshioka
+   Jun Hiroe
+   Narihiro Nakamura
+   Yuichi Nishiwaki
+   Tatsuhiko Kubo
+   Takeshi Watanabe
+   Yuki Kurihara
+   specified non-profit corporation mruby Forum
+   Kazuaki Tanaka
+   Hiromasa Ishii
+   Hiroshi Mimaki
+   Satoshi Odawara
+   Mitsubishi Electric Micro-Computer Application Software Co.,Ltd.
+   Ralph Desir(Mav7)
+   Hiroyuki Matsuzaki
+   Yuhei Okazaki
+   Manycolors, Inc.
+   Shota Nakano
+   Yuichi Osawa
+   Terence Lee
+   Zachary Scott
+   Tomasz DÄ
+browski
Index: EcnlProtoTool/trunk/mruby-1.3.0/CONTRIBUTING.md
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/CONTRIBUTING.md	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/CONTRIBUTING.md	(revision 331)
@@ -0,0 +1,68 @@
+# How to contribute
+
+mruby is an open-source project which is looking forward to each contribution.
+
+## Your Pull Request
+
+To make it easy to review and understand your change please keep the following
+things in mind before submitting your pull request:
+
+* Work on the latest possible state of **mruby/master**
+* Create a branch which is dedicated to your change
+* Test your changes before creating a pull request (```./minirake test```)
+* If possible write a test case which confirms your change
+* Don't mix several features or bug-fixes in one pull request
+* Create a meaningful commit message
+* Explain your change (i.e. with a link to the issue you are fixing)
+* Use mrbgem to provide non ISO features (classes, modules and methods) unless
+  you have a special reason to implement them in the core
+
+## Coding conventions
+
+How to style your C and Ruby code which you want to submit.
+
+### C code
+
+The core part (parser, bytecode-interpreter, core-lib, etc.) of mruby is
+written in the C programming language. Please note the following hints for your
+C code:
+
+#### Comply with C99 (ISO/IEC 9899:1999)
+
+mruby should be highly portable to other systems and compilers. For this it is
+recommended to keep your code as close as possible to the C99 standard
+(http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf).
+
+Although we target C99, Visual C++ is also an important target for mruby. For
+this reason a declaration of a local variable has to be at the beginning of a
+scope block.
+
+#### Reduce library dependencies to a minimum
+
+The dependencies to libraries should be kept to an absolute minimum. This
+increases the portability but makes it also easier to cut away parts of mruby
+on-demand.
+
+#### Don't use C++ style comments
+
+    /* This is the preferred comment style */
+
+Use C++ style comments only for temporary comment e.g. commenting out some code lines.
+
+#### Insert a break after the method return value:
+
+    int
+    main(void)
+    {
+      ...
+    }
+
+### Ruby code
+
+Parts of the standard library of mruby are written in the Ruby programming
+language itself. Please note the following hints for your Ruby code:
+
+#### Comply with the Ruby standard (ISO/IEC 30170:2012)
+
+mruby is currently targeting to execute Ruby code which complies to ISO/IEC
+30170:2012 (http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=59579).
Index: EcnlProtoTool/trunk/mruby-1.3.0/ChangeLog
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/ChangeLog	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/ChangeLog	(revision 331)
@@ -0,0 +1,15 @@
+Thu Apl 19 17:25:18 2012  Yukihiro Matsumoto  <matz@ruby-lang.org>
+
+	* first release version 1.0.0 released.
+
+Local variables:
+add-log-time-format: (lambda ()
+  (let* ((time (current-time))
+	 (system-time-locale "C")
+	 (diff (+ (cadr time) 32400))
+	 (lo (% diff 65536))
+	 (hi (+ (car time) (/ diff 65536))))
+  (format-time-string "%a %b %e %H:%M:%S %Y" (list hi lo) t)))
+indent-tabs-mode: t
+tab-width: 8
+end:
Index: EcnlProtoTool/trunk/mruby-1.3.0/LEGAL
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/LEGAL	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/LEGAL	(revision 331)
@@ -0,0 +1,6 @@
+LEGAL NOTICE INFORMATION
+------------------------
+
+All the files in this distribution are covered under the MIT license
+(see the file MITL) except some files mentioned below:
+
Index: EcnlProtoTool/trunk/mruby-1.3.0/MITL
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/MITL	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/MITL	(revision 331)
@@ -0,0 +1,20 @@
+Copyright (c) 2017 mruby developers
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
Index: EcnlProtoTool/trunk/mruby-1.3.0/Makefile
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/Makefile	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/Makefile	(revision 331)
@@ -0,0 +1,17 @@
+# mruby is using Rake (http://rake.rubyforge.org) as a build tool.
+# We provide a minimalistic version called minirake inside of our
+# codebase.
+
+RAKE = build.bat
+
+all :
+	$(RAKE)
+.PHONY : all
+
+test : all
+	$(RAKE) test
+.PHONY : test
+
+clean :
+	$(RAKE) clean
+.PHONY : clean
Index: EcnlProtoTool/trunk/mruby-1.3.0/NEWS
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/NEWS	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/NEWS	(revision 331)
@@ -0,0 +1,13 @@
+* NEWS
+
+This document is a list of user visible feature changes made between
+releases except for bug fixes.
+
+Note that each entry is kept so brief that no reason behind or
+reference information is supplied with.  For a full list of changes
+with all sufficient information, see the ChangeLog file.
+
+
+** Information about first release v1.0.0
+
+
Index: EcnlProtoTool/trunk/mruby-1.3.0/README.md
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/README.md	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/README.md	(revision 331)
@@ -0,0 +1,92 @@
+[![Build Status][build-status-img]][travis-ci]
+
+## What is mruby
+
+mruby is the lightweight implementation of the Ruby language complying to (part
+of) the [ISO standard][ISO-standard]. Its syntax is Ruby 1.9 compatible.
+
+mruby can be linked and embedded within your application.  We provide the
+interpreter program "mruby" and the interactive mruby shell "mirb" as examples.
+You can also compile Ruby programs into compiled byte code using the mruby
+compiler "mrbc".  All those tools reside in the "bin" directory.  "mrbc" is
+also able to generate compiled byte code in a C source file, see the "mrbtest"
+program under the "test" directory for an example.
+
+This achievement was sponsored by the Regional Innovation Creation R&D Programs
+of the Ministry of Economy, Trade and Industry of Japan.
+
+## How to get mruby
+
+The stable version 1.3.0 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/1.3.0.zip](https://github.com/mruby/mruby/archive/1.3.0.zip)
+
+The latest development version of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/zipball/master](https://github.com/mruby/mruby/zipball/master)
+
+The trunk of the mruby source tree can be checked out with the
+following command:
+
+    $ git clone https://github.com/mruby/mruby.git
+
+You can also install and compile mruby using [ruby-install](https://github.com/postmodern/ruby-install), [ruby-build](https://github.com/rbenv/ruby-build) or [rvm](https://github.com/rvm/rvm).
+
+## mruby home-page
+
+The URL of the mruby home-page is: [http://www.mruby.org](http://www.mruby.org).
+
+## Mailing list
+
+We don't have a mailing list, but you can use [GitHub issues](https://github.com/mruby/mruby).
+
+## How to compile and install (mruby and gems)
+
+See the [doc/guides/compile.md](doc/guides/compile.md) file.
+
+## Running Tests
+
+To run the tests, execute the following from the project's root directory.
+
+    $ make test
+
+Or
+
+    $ ruby ./minirake test
+
+## How to customize mruby (mrbgems)
+
+mruby contains a package manager called *mrbgems*. To create extensions
+in C and/or Ruby you should create a *GEM*. For a documentation of how to
+use mrbgems consult the file [doc/guides/mrbgems.md](doc/guides/mrbgems.md). For example code of
+how to use mrbgems look into the folder *examples/mrbgems/*.
+
+## License
+
+mruby is released under the [MIT License](MITL).
+
+## Note for License
+
+mruby has chosen a MIT License due to its permissive license allowing
+developers to target various environments such as embedded systems.
+However, the license requires the display of the copyright notice and license
+information in manuals for instance. Doing so for big projects can be
+complicated or troublesome.  This is why mruby has decided to display "mruby
+developers" as the copyright name to make it simple conventionally.
+In the future, mruby might ask you to distribute your new code
+(that you will commit,) under the MIT License as a member of
+"mruby developers" but contributors will keep their copyright.
+(We did not intend for contributors to transfer or waive their copyrights,
+Actual copyright holder name (contributors) will be listed in the AUTHORS
+file.)
+
+Please ask us if you want to distribute your code under another license.
+
+## How to Contribute
+
+See the [contribution guidelines][contribution-guidelines], and then send a pull
+request to <http://github.com/mruby/mruby>.  We consider you have granted
+non-exclusive right to your contributed code under MIT license.  If you want to
+be named as one of mruby developers, please include an update to the AUTHORS
+file in your pull request.
+
+[ISO-standard]: http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=59579
+[build-status-img]: https://travis-ci.org/mruby/mruby.svg?branch=master
+[contribution-guidelines]: CONTRIBUTING.md
+[travis-ci]: https://travis-ci.org/mruby/mruby
Index: EcnlProtoTool/trunk/mruby-1.3.0/Rakefile
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/Rakefile	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/Rakefile	(revision 331)
@@ -0,0 +1,150 @@
+# encoding: utf-8
+# Build description.
+# basic build file for mruby
+MRUBY_ROOT = File.dirname(File.expand_path(__FILE__))
+MRUBY_BUILD_HOST_IS_CYGWIN = RUBY_PLATFORM.include?('cygwin')
+MRUBY_BUILD_HOST_IS_OPENBSD = RUBY_PLATFORM.include?('openbsd')
+
+# load build systems
+load "#{MRUBY_ROOT}/tasks/ruby_ext.rake"
+load "#{MRUBY_ROOT}/tasks/mruby_build.rake"
+load "#{MRUBY_ROOT}/tasks/mrbgem_spec.rake"
+
+# load configuration file
+MRUBY_CONFIG = (ENV['MRUBY_CONFIG'] && ENV['MRUBY_CONFIG'] != '') ? ENV['MRUBY_CONFIG'] : "#{MRUBY_ROOT}/build_config.rb"
+load MRUBY_CONFIG
+
+# load basic rules
+MRuby.each_target do |build|
+  build.define_rules
+end
+
+# load custom rules
+load "#{MRUBY_ROOT}/src/mruby_core.rake"
+load "#{MRUBY_ROOT}/mrblib/mrblib.rake"
+
+load "#{MRUBY_ROOT}/tasks/mrbgems.rake"
+load "#{MRUBY_ROOT}/tasks/libmruby.rake"
+
+load "#{MRUBY_ROOT}/tasks/benchmark.rake"
+
+load "#{MRUBY_ROOT}/tasks/gitlab.rake"
+
+##############################
+# generic build targets, rules
+task :default => :all
+
+bin_path = ENV['INSTALL_DIR'] || "#{MRUBY_ROOT}/bin"
+FileUtils.mkdir_p bin_path, { :verbose => $verbose }
+
+depfiles = MRuby.targets['host'].bins.map do |bin|
+  install_path = MRuby.targets['host'].exefile("#{bin_path}/#{bin}")
+  source_path = MRuby.targets['host'].exefile("#{MRuby.targets['host'].build_dir}/bin/#{bin}")
+
+  file install_path => source_path do |t|
+    FileUtils.rm_f t.name, { :verbose => $verbose }
+    FileUtils.cp t.prerequisites.first, t.name, { :verbose => $verbose }
+  end
+
+  install_path
+end
+
+MRuby.each_target do |target|
+  gems.map do |gem|
+    current_dir = gem.dir.relative_path_from(Dir.pwd)
+    relative_from_root = gem.dir.relative_path_from(MRUBY_ROOT)
+    current_build_dir = File.expand_path "#{build_dir}/#{relative_from_root}"
+
+    if current_build_dir !~ /^#{build_dir}/
+      current_build_dir = "#{build_dir}/mrbgems/#{gem.name}"
+    end
+
+    gem.bins.each do |bin|
+      exec = exefile("#{build_dir}/bin/#{bin}")
+      objs = Dir.glob("#{current_dir}/tools/#{bin}/*.{c,cpp,cxx,cc}").map { |f| objfile(f.pathmap("#{current_build_dir}/tools/#{bin}/%n")) }
+
+      file exec => objs + [libfile("#{build_dir}/lib/libmruby")] do |t|
+        gem_flags = gems.map { |g| g.linker.flags }
+        gem_flags_before_libraries = gems.map { |g| g.linker.flags_before_libraries }
+        gem_flags_after_libraries = gems.map { |g| g.linker.flags_after_libraries }
+        gem_libraries = gems.map { |g| g.linker.libraries }
+        gem_library_paths = gems.map { |g| g.linker.library_paths }
+        linker.run t.name, t.prerequisites, gem_libraries, gem_library_paths, gem_flags, gem_flags_before_libraries, gem_flags_after_libraries
+      end
+
+      if target == MRuby.targets['host']
+        install_path = MRuby.targets['host'].exefile("#{bin_path}/#{bin}")
+
+        file install_path => exec do |t|
+          FileUtils.rm_f t.name, { :verbose => $verbose }
+          FileUtils.cp t.prerequisites.first, t.name, { :verbose => $verbose }
+        end
+        depfiles += [ install_path ]
+      elsif target == MRuby.targets['host-debug']
+        unless MRuby.targets['host'].gems.map {|g| g.bins}.include?([bin])
+          install_path = MRuby.targets['host-debug'].exefile("#{bin_path}/#{bin}")
+
+          file install_path => exec do |t|
+            FileUtils.rm_f t.name, { :verbose => $verbose }
+            FileUtils.cp t.prerequisites.first, t.name, { :verbose => $verbose }
+          end
+          depfiles += [ install_path ]
+        end
+      else
+        depfiles += [ exec ]
+      end
+    end
+  end
+end
+
+depfiles += MRuby.targets.map { |n, t|
+  [t.libfile("#{t.build_dir}/lib/libmruby")]
+}.flatten
+
+depfiles += MRuby.targets.reject { |n, t| n == 'host' }.map { |n, t|
+  t.bins.map { |bin| t.exefile("#{t.build_dir}/bin/#{bin}") }
+}.flatten
+
+desc "build all targets, install (locally) in-repo"
+task :all => depfiles do
+  puts
+  puts "Build summary:"
+  puts
+  MRuby.each_target do
+    print_build_summary
+  end
+end
+
+desc "run all mruby tests"
+task :test => ["all"] do
+  MRuby.each_target do
+    run_test if test_enabled?
+  end
+end
+
+desc "clean all built and in-repo installed artifacts"
+task :clean do
+  MRuby.each_target do |t|
+    FileUtils.rm_rf t.build_dir, { :verbose => $verbose }
+  end
+  FileUtils.rm_f depfiles, { :verbose => $verbose }
+  puts "Cleaned up target build folder"
+end
+
+desc "clean everything!"
+task :deep_clean => ["clean"] do
+  MRuby.each_target do |t|
+    FileUtils.rm_rf t.gem_clone_dir, { :verbose => $verbose }
+  end
+  puts "Cleaned up mrbgems build folder"
+end
+
+desc 'generate document'
+task :doc do
+  begin
+    sh "mrbdoc"
+  rescue
+    puts "ERROR: To generate documents, you should install yard-mruby gem."
+    puts "  $ gem install yard-mruby"
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/TODO
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/TODO	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/TODO	(revision 331)
@@ -0,0 +1,10 @@
+Things to do (Things that are not done yet)
+
+* special variables ($1,$2..)
+* super in aliased methods
+* multi-assignment decomposing
+* keyword arguments in def statement
+
+Things to improve (Done but things to fix)
+
+* Make additions as they are noticed.
Index: EcnlProtoTool/trunk/mruby-1.3.0/appveyor.yml
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/appveyor.yml	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/appveyor.yml	(revision 331)
@@ -0,0 +1,27 @@
+version: "{build}"
+
+os: Visual Studio 2015
+
+clone_depth: 50
+
+
+environment:
+  matrix:
+    # Visual Studio 2015 64bit
+    - visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
+      machine: amd64
+
+    # Visual Studio 2013 64bit
+    - visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat
+      machine: amd64
+
+
+init:
+  - call "%visualcpp%" %machine%
+  # For using bison.exe
+  - set PATH=%PATH%;C:\cygwin\bin;
+
+
+build_script:
+  - set MRUBY_CONFIG=appveyor_config.rb
+  - ruby .\minirake test
Index: EcnlProtoTool/trunk/mruby-1.3.0/appveyor_config.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/appveyor_config.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/appveyor_config.rb	(revision 331)
@@ -0,0 +1,50 @@
+MRuby::Build.new('debug') do |conf|
+  toolchain :visualcpp
+  enable_debug
+
+  # include all core GEMs
+  conf.gembox 'full-core'
+  conf.compilers.each do |c|
+    c.defines += %w(MRB_GC_STRESS MRB_GC_FIXED_ARENA)
+  end
+
+  build_mrbc_exec
+end
+
+MRuby::Build.new('full-debug') do |conf|
+  toolchain :visualcpp
+  enable_debug
+
+  # include all core GEMs
+  conf.gembox 'full-core'
+  conf.cc.defines = %w(MRB_ENABLE_DEBUG_HOOK)
+
+  conf.enable_test
+end
+
+MRuby::Build.new do |conf|
+  toolchain :visualcpp
+
+  # include all core GEMs
+  conf.gembox 'full-core'
+  conf.compilers.each do |c|
+    c.defines += %w(MRB_GC_FIXED_ARENA)
+  end
+  conf.enable_bintest
+  conf.enable_test
+end
+
+MRuby::Build.new('cxx_abi') do |conf|
+  toolchain :visualcpp
+
+  conf.gembox 'full-core'
+  conf.compilers.each do |c|
+    c.defines += %w(MRB_GC_FIXED_ARENA)
+  end
+  conf.enable_bintest
+  conf.enable_test
+
+  enable_cxx_abi
+
+  build_mrbc_exec
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/benchmark/bm_ao_render.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/benchmark/bm_ao_render.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/benchmark/bm_ao_render.rb	(revision 331)
@@ -0,0 +1,314 @@
+# AO render benchmark
+# Original program (C) Syoyo Fujita in Javascript (and other languages)
+#      https://code.google.com/p/aobench/
+# Ruby(yarv2llvm) version by Hideki Miura
+# mruby version by Hideki Miura
+#
+
+IMAGE_WIDTH = 64
+IMAGE_HEIGHT = 64
+NSUBSAMPLES = 2
+NAO_SAMPLES = 8
+
+module Rand
+  # Use xorshift
+  @@x = 123456789
+  @@y = 362436069
+  @@z = 521288629
+  @@w = 88675123
+  BNUM = 1 << 29
+  BNUMF = BNUM.to_f
+  def self.rand
+    x = @@x
+    t = x ^ ((x & 0xfffff) << 11)
+    w = @@w
+    @@x, @@y, @@z = @@y, @@z, w
+    w = @@w = (w ^ (w >> 19) ^ (t ^ (t >> 8)))
+    (w % BNUM) / BNUMF
+  end
+end
+
+class Vec
+  def initialize(x, y, z)
+    @x = x
+    @y = y
+    @z = z
+  end
+
+  def x=(v); @x = v; end
+  def y=(v); @y = v; end
+  def z=(v); @z = v; end
+  def x; @x; end
+  def y; @y; end
+  def z; @z; end
+
+  def vadd(b)
+    Vec.new(@x + b.x, @y + b.y, @z + b.z)
+  end
+
+  def vsub(b)
+    Vec.new(@x - b.x, @y - b.y, @z - b.z)
+  end
+
+  def vcross(b)
+    Vec.new(@y * b.z - @z * b.y,
+            @z * b.x - @x * b.z,
+            @x * b.y - @y * b.x)
+  end
+
+  def vdot(b)
+    r = @x * b.x + @y * b.y + @z * b.z
+    r
+  end
+
+  def vlength
+    Math.sqrt(@x * @x + @y * @y + @z * @z)
+  end
+
+  def vnormalize
+    len = vlength
+    v = Vec.new(@x, @y, @z)
+    if len > 1.0e-17 then
+      v.x = v.x / len
+      v.y = v.y / len
+      v.z = v.z / len
+    end
+    v
+  end
+end
+
+
+class Sphere
+  def initialize(center, radius)
+    @center = center
+    @radius = radius
+  end
+
+  def center; @center; end
+  def radius; @radius; end
+
+  def intersect(ray, isect)
+    rs = ray.org.vsub(@center)
+    b = rs.vdot(ray.dir)
+    c = rs.vdot(rs) - (@radius * @radius)
+    d = b * b - c
+    if d > 0.0 then
+      t = - b - Math.sqrt(d)
+
+      if t > 0.0 and t < isect.t then
+        isect.t = t
+        isect.hit = true
+        isect.pl = Vec.new(ray.org.x + ray.dir.x * t,
+                          ray.org.y + ray.dir.y * t,
+                          ray.org.z + ray.dir.z * t)
+        n = isect.pl.vsub(@center)
+        isect.n = n.vnormalize
+      end
+    end
+  end
+end
+
+class Plane
+  def initialize(p, n)
+    @p = p
+    @n = n
+  end
+
+  def intersect(ray, isect)
+    d = -@p.vdot(@n)
+    v = ray.dir.vdot(@n)
+    v0 = v
+    if v < 0.0 then
+      v0 = -v
+    end
+    if v0 < 1.0e-17 then
+      return
+    end
+
+    t = -(ray.org.vdot(@n) + d) / v
+
+    if t > 0.0 and t < isect.t then
+      isect.hit = true
+      isect.t = t
+      isect.n = @n
+      isect.pl = Vec.new(ray.org.x + t * ray.dir.x,
+                        ray.org.y + t * ray.dir.y,
+                        ray.org.z + t * ray.dir.z)
+    end
+  end
+end
+
+class Ray
+  def initialize(org, dir)
+    @org = org
+    @dir = dir
+  end
+
+  def org; @org; end
+  def org=(v); @org = v; end
+  def dir; @dir; end
+  def dir=(v); @dir = v; end
+end
+
+class Isect
+  def initialize
+    @t = 10000000.0
+    @hit = false
+    @pl = Vec.new(0.0, 0.0, 0.0)
+    @n = Vec.new(0.0, 0.0, 0.0)
+  end
+
+  def t; @t; end
+  def t=(v); @t = v; end
+  def hit; @hit; end
+  def hit=(v); @hit = v; end
+  def pl; @pl; end
+  def pl=(v); @pl = v; end
+  def n; @n; end
+  def n=(v); @n = v; end
+end
+
+def clamp(f)
+  i = f * 255.5
+  if i > 255.0 then
+    i = 255.0
+  end
+  if i < 0.0 then
+    i = 0.0
+  end
+  i.to_i
+end
+
+def otherBasis(basis, n)
+  basis[2] = Vec.new(n.x, n.y, n.z)
+  basis[1] = Vec.new(0.0, 0.0, 0.0)
+
+  if n.x < 0.6 and n.x > -0.6 then
+    basis[1].x = 1.0
+  elsif n.y < 0.6 and n.y > -0.6 then
+    basis[1].y = 1.0
+  elsif n.z < 0.6 and n.z > -0.6 then
+    basis[1].z = 1.0
+  else
+    basis[1].x = 1.0
+  end
+
+  basis[0] = basis[1].vcross(basis[2])
+  basis[0] = basis[0].vnormalize
+
+  basis[1] = basis[2].vcross(basis[0])
+  basis[1] = basis[1].vnormalize
+end
+
+class Scene
+  def initialize
+    @spheres = Array.new
+    @spheres[0] = Sphere.new(Vec.new(-2.0, 0.0, -3.5), 0.5)
+    @spheres[1] = Sphere.new(Vec.new(-0.5, 0.0, -3.0), 0.5)
+    @spheres[2] = Sphere.new(Vec.new(1.0, 0.0, -2.2), 0.5)
+    @plane = Plane.new(Vec.new(0.0, -0.5, 0.0), Vec.new(0.0, 1.0, 0.0))
+  end
+
+  def ambient_occlusion(isect)
+    basis = Array.new(3)
+    otherBasis(basis, isect.n)
+
+    ntheta    = NAO_SAMPLES
+    nphi      = NAO_SAMPLES
+    eps       = 0.0001
+    occlusion = 0.0
+
+    p0 = Vec.new(isect.pl.x + eps * isect.n.x,
+                isect.pl.y + eps * isect.n.y,
+                isect.pl.z + eps * isect.n.z)
+    nphi.times do |j|
+      ntheta.times do |i|
+        r = Rand::rand
+        phi = 2.0 * 3.14159265 * Rand::rand
+        x = Math.cos(phi) * Math.sqrt(1.0 - r)
+        y = Math.sin(phi) * Math.sqrt(1.0 - r)
+        z = Math.sqrt(r)
+
+        rx = x * basis[0].x + y * basis[1].x + z * basis[2].x
+        ry = x * basis[0].y + y * basis[1].y + z * basis[2].y
+        rz = x * basis[0].z + y * basis[1].z + z * basis[2].z
+
+        raydir = Vec.new(rx, ry, rz)
+        ray = Ray.new(p0, raydir)
+
+        occisect = Isect.new
+        @spheres[0].intersect(ray, occisect)
+        @spheres[1].intersect(ray, occisect)
+        @spheres[2].intersect(ray, occisect)
+        @plane.intersect(ray, occisect)
+        if occisect.hit then
+          occlusion = occlusion + 1.0
+        else
+          0.0
+        end
+      end
+    end
+
+    occlusion = (ntheta.to_f * nphi.to_f - occlusion) / (ntheta.to_f * nphi.to_f)
+    Vec.new(occlusion, occlusion, occlusion)
+  end
+
+  def render(w, h, nsubsamples)
+    cnt = 0
+    nsf = nsubsamples.to_f
+    h.times do |y|
+      w.times do |x|
+        rad = Vec.new(0.0, 0.0, 0.0)
+
+        # Subsmpling
+        nsubsamples.times do |v|
+          nsubsamples.times do |u|
+            cnt = cnt + 1
+            wf = w.to_f
+            hf = h.to_f
+            xf = x.to_f
+            yf = y.to_f
+            uf = u.to_f
+            vf = v.to_f
+
+            px = (xf + (uf / nsf) - (wf / 2.0)) / (wf / 2.0)
+            py = -(yf + (vf / nsf) - (hf / 2.0)) / (hf / 2.0)
+
+            eye = Vec.new(px, py, -1.0).vnormalize
+
+            ray = Ray.new(Vec.new(0.0, 0.0, 0.0), eye)
+
+            isect = Isect.new
+            @spheres[0].intersect(ray, isect)
+            @spheres[1].intersect(ray, isect)
+            @spheres[2].intersect(ray, isect)
+            @plane.intersect(ray, isect)
+            if isect.hit then
+              col = ambient_occlusion(isect)
+              rad.x = rad.x + col.x
+              rad.y = rad.y + col.y
+              rad.z = rad.z + col.z
+            else
+              0.0
+            end
+          end
+        end
+
+        r = rad.x / (nsf * nsf)
+        g = rad.y / (nsf * nsf)
+        b = rad.z / (nsf * nsf)
+        printf("%c", clamp(r))
+        printf("%c", clamp(g))
+        printf("%c", clamp(b))
+      end
+    end
+  end
+end
+
+# File.open("ao.ppm", "w") do |fp|
+  printf("P6\n")
+  printf("%d %d\n", IMAGE_WIDTH, IMAGE_HEIGHT)
+  printf("255\n", IMAGE_WIDTH, IMAGE_HEIGHT)
+  Scene.new.render(IMAGE_WIDTH, IMAGE_HEIGHT, NSUBSAMPLES)
+#  Scene.new.render(256, 256, 2)
+# end
Index: EcnlProtoTool/trunk/mruby-1.3.0/benchmark/bm_app_lc_fizzbuzz.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/benchmark/bm_app_lc_fizzbuzz.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/benchmark/bm_app_lc_fizzbuzz.rb	(revision 331)
@@ -0,0 +1,52 @@
+#
+# FizzBuzz program using only lambda calculus
+#
+# This program is quoted from
+#   "Understanding Computation" by Tom Stuart
+#   http://computationbook.com/
+#
+# You can understand why this program works fine by reading this book.
+#
+
+solution = -> k { -> f { -> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> l { -> x { -> g { -> b { b }[-> p { p[-> x { -> y { x } }] }[l]][x][-> y { g[f[-> l { -> p { p[-> x { -> y { y } }] }[-> p { p[-> x { -> y { y } }] }[l]] }[l]][x][g]][-> l { -> p { p[-> x { -> y { x } }] }[-> p { p[-> x { -> y { y } }] }[l]] }[l]][y] }] } } } }][k][-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][-> l { -> x { -> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[l][f[x]] } }] } }[-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[m][n]][-> x { -> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[f[-> n { -> p { -> x { p[n[p][x]] } } }[m]][n]][m][x] }][-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]] } } }][-> p { -> x { p[x] } }][-> p { -> x { p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[x]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] } }]][-> n { -> b { b }[-> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][m]][-> x { f[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]][n][x] }][m] } } }][n][-> p { -> x { p[p[p[p[p[p[p[p[p[p[p[p[p[p[p[x]]]]]]]]]]]]]]] } }]]][-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]][-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]][-> b { b }[-> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][m]][-> x { f[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]][n][x] }][m] } } }][n][-> p { -> x { p[p[p[x]]] } }]]][-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]][-> b { b }[-> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][m]][-> x { f[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]][n][x] }][m] } } }][n][-> p { -> x { p[p[p[p[p[x]]]]] } }]]][-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]]][-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> n { -> p { -> x { p[n[p][x]] } } }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]]]][-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]][-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> n { -> l { -> x { -> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> l { -> x { -> g { -> b { b }[-> p { p[-> x { -> y { x } }] }[l]][x][-> y { g[f[-> l { -> p { p[-> x { -> y { y } }] }[-> p { p[-> x { -> y { y } }] }[l]] }[l]][x][g]][-> l { -> p { p[-> x { -> y { x } }] }[-> p { p[-> x { -> y { y } }] }[l]] }[l]][y] }] } } } }][l][-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }[-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][x]][-> l { -> x { -> x { -> y { -> f { f[x][y] } } }[-> x { -> y { y } }][-> x { -> y { -> f { f[x][y] } } }[x][l]] } }] } }[-> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }[-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]]][-> x { -> y { -> f { f[x][y] } } }[-> x { -> y { x } }][-> x { -> y { x } }]][-> x { f[-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][m]][-> x { -> n { -> p { -> x { p[n[p][x]] } } }[f[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]][n]][x] }][-> p { -> x { x } }] } } }][n][-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]][x] }]][-> f { -> x { f[-> y { x[x][y] }] }[-> x { f[-> y { x[x][y] }] }] }[-> f { -> m { -> n { -> b { b }[-> m { -> n { -> n { n[-> x { -> x { -> y { y } } }][-> x { -> y { x } }] }[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]] } }[n][m]][-> x { f[-> m { -> n { n[-> n { -> p { p[-> x { -> y { x } }] }[n[-> p { -> x { -> y { -> f { f[x][y] } } }[-> p { p[-> x { -> y { y } }] }[p]][-> n { -> p { -> x { p[n[p][x]] } } }[-> p { p[-> x { -> y { y } }] }[p]]] }][-> x { -> y { -> f { f[x][y] } } }[-> p { -> x { x } }][-> p { -> x { x } }]]] }][m] } }[m][n]][n][x] }][m] } } }][n][-> m { -> n { n[-> m { -> n { n[-> n { -> p { -> x { p[n[p][x]] } } }][m] } }[m]][-> p { -> x { x } }] } }[-> p { -> x { p[p[x]] } }][-> p { -> x { p[p[p[p[p[x]]]]] } }]]] } }][n]]]] }]
+
+FIRST     = -> l { LEFT[RIGHT[l]] }
+IF        = -> b { b }
+LEFT      = -> p { p[-> x { -> y { x } } ] }
+RIGHT     = -> p { p[-> x { -> y { y } } ] }
+IS_EMPTY  = LEFT
+REST      = -> l { RIGHT[RIGHT[l]] }
+
+def to_integer(proc)
+  proc[-> n { n + 1 }][0]
+end
+
+def to_boolean(proc)
+  IF[proc][true][false]
+end
+
+def to_array(proc)
+  array = []
+
+  until to_boolean(IS_EMPTY[proc])
+    array.push(FIRST[proc])
+    proc = REST[proc]
+  end
+
+  array
+end
+
+def to_char(c)
+  '0123456789BFiuz'.slice(to_integer(c))
+end
+
+def to_string(s)
+  to_array(s).map { |c| to_char(c) }.join
+end
+
+answer = to_array(solution).map do |p|
+  to_string(p)
+end
+
+answer_str = answer.to_a
+# puts answer_str
Index: EcnlProtoTool/trunk/mruby-1.3.0/benchmark/bm_fib.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/benchmark/bm_fib.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/benchmark/bm_fib.rb	(revision 331)
@@ -0,0 +1,7 @@
+
+def fib n
+  return n if n < 2
+  fib(n-2) + fib(n-1)
+end
+
+puts fib(37)
Index: EcnlProtoTool/trunk/mruby-1.3.0/benchmark/bm_so_lists.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/benchmark/bm_so_lists.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/benchmark/bm_so_lists.rb	(revision 331)
@@ -0,0 +1,47 @@
+#from http://www.bagley.org/~doug/shootout/bench/lists/lists.ruby
+
+NUM = 300
+SIZE = 10000
+
+def test_lists()
+  # create a list of integers (Li1) from 1 to SIZE
+  li1 = (1..SIZE).to_a
+  # copy the list to li2 (not by individual items)
+  li2 = li1.dup
+  # remove each individual item from left side of li2 and
+  # append to right side of li3 (preserving order)
+  li3 = Array.new
+  while (not li2.empty?)
+    li3.push(li2.shift)
+  end
+  # li2 must now be empty
+  # remove each individual item from right side of li3 and
+  # append to right side of li2 (reversing list)
+  while (not li3.empty?)
+    li2.push(li3.pop)
+  end
+  # li3 must now be empty
+  # reverse li1 in place
+  li1.reverse!
+  # check that first item is now SIZE
+  if li1[0] != SIZE then
+    p "not SIZE"
+    0
+  else
+    # compare li1 and li2 for equality
+    if li1 != li2 then
+      return(0)
+    else
+      # return the length of the list
+      li1.length
+    end
+  end
+end
+
+i = 0
+while i<NUM
+  i += 1
+  result = test_lists()
+end
+
+result
Index: EcnlProtoTool/trunk/mruby-1.3.0/benchmark/build_config_boxing.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/benchmark/build_config_boxing.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/benchmark/build_config_boxing.rb	(revision 331)
@@ -0,0 +1,28 @@
+MRuby::Build.new do |conf|
+  toolchain :gcc
+end
+
+MRuby::Build.new('no_boxing') do |conf|
+  toolchain :gcc
+
+  conf.gembox 'default'
+end
+
+MRuby::Build.new('word_boxing') do |conf|
+  toolchain :gcc
+
+  conf.gembox 'default'
+  conf.compilers.each do |c|
+    c.defines += %w(MRB_WORD_BOXING)
+  end
+end
+
+MRuby::Build.new('nan_boxing') do |conf|
+  toolchain :gcc
+
+  conf.gembox 'default'
+  conf.compilers.each do |c|
+    c.defines += %w(MRB_NAN_BOXING)
+  end
+end
+
Index: EcnlProtoTool/trunk/mruby-1.3.0/benchmark/build_config_cc.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/benchmark/build_config_cc.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/benchmark/build_config_cc.rb	(revision 331)
@@ -0,0 +1,13 @@
+MRuby::Build.new do |conf|
+  toolchain :gcc
+end
+
+MRuby::Build.new('gcc') do |conf|
+  toolchain :gcc
+  conf.gembox 'default'
+end
+
+MRuby::Build.new('clang') do |conf|
+  toolchain :clang
+  conf.gembox 'default'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/benchmark/plot.gpl
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/benchmark/plot.gpl	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/benchmark/plot.gpl	(revision 331)
@@ -0,0 +1,5 @@
+set yrange [0:]
+set terminal pngcairo font 'Sans, 8' lw 1 size 1400,1024
+set xtics rotate by -45
+set style histogram errorbars gap 2 lw 1
+set style fill solid border -1
Index: EcnlProtoTool/trunk/mruby-1.3.0/build.bat
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/build.bat	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/build.bat	(revision 331)
@@ -0,0 +1,9 @@
+set DIR=%~dp0
+set PATH=%PATH%;%DIR%\..\tools\bin
+
+rem call "%VS140COMNTOOLS%..\..\VC\vcvarsall.bat" x86
+call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x86
+
+cd /d %DIR%
+
+ruby -Eutf-8 ./minirake %1
Index: EcnlProtoTool/trunk/mruby-1.3.0/build_config.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/build_config.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/build_config.rb	(revision 331)
@@ -0,0 +1,212 @@
+MRuby::Build.new do |conf|
+  # load specific toolchain settings
+
+  # Gets set by the VS command prompts.
+  if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
+    toolchain :visualcpp
+  else
+    toolchain :gcc
+  end
+
+  enable_debug
+
+  # Use mrbgems
+  # conf.gem 'examples/mrbgems/ruby_extension_example'
+  # conf.gem 'examples/mrbgems/c_extension_example' do |g|
+  #   g.cc.flags << '-g' # append cflags in this gem
+  # end
+  # conf.gem 'examples/mrbgems/c_and_ruby_extension_example'
+  # conf.gem :core => 'mruby-eval'
+  # conf.gem :mgem => 'mruby-io'
+  # conf.gem :github => 'iij/mruby-io'
+  # conf.gem :git => 'git@github.com:iij/mruby-io.git', :branch => 'master', :options => '-v'
+
+  # include the default GEMs
+  conf.gembox 'default'
+  # C compiler settings
+  # conf.cc do |cc|
+  #   cc.command = ENV['CC'] || 'gcc'
+  #   cc.flags = [ENV['CFLAGS'] || %w()]
+  #   cc.include_paths = ["#{root}/include"]
+  #   cc.defines = %w(DISABLE_GEMS)
+  #   cc.option_include_path = '-I%s'
+  #   cc.option_define = '-D%s'
+  #   cc.compile_options = "%{flags} -MMD -o %{outfile} -c %{infile}"
+  # end
+
+  # mrbc settings
+  # conf.mrbc do |mrbc|
+  #   mrbc.compile_options = "-g -B%{funcname} -o-" # The -g option is required for line numbers
+  # end
+
+  # Linker settings
+  # conf.linker do |linker|
+  #   linker.command = ENV['LD'] || 'gcc'
+  #   linker.flags = [ENV['LDFLAGS'] || []]
+  #   linker.flags_before_libraries = []
+  #   linker.libraries = %w()
+  #   linker.flags_after_libraries = []
+  #   linker.library_paths = []
+  #   linker.option_library = '-l%s'
+  #   linker.option_library_path = '-L%s'
+  #   linker.link_options = "%{flags} -o %{outfile} %{objs} %{libs}"
+  # end
+
+  # Archiver settings
+  # conf.archiver do |archiver|
+  #   archiver.command = ENV['AR'] || 'ar'
+  #   archiver.archive_options = 'rs %{outfile} %{objs}'
+  # end
+
+  # Parser generator settings
+  # conf.yacc do |yacc|
+  #   yacc.command = ENV['YACC'] || 'bison'
+  #   yacc.compile_options = '-o %{outfile} %{infile}'
+  # end
+
+  # gperf settings
+  # conf.gperf do |gperf|
+  #   gperf.command = 'gperf'
+  #   gperf.compile_options = '-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" %{infile} > %{outfile}'
+  # end
+
+  # file extensions
+  # conf.exts do |exts|
+  #   exts.object = '.o'
+  #   exts.executable = '' # '.exe' if Windows
+  #   exts.library = '.a'
+  # end
+
+  # file separetor
+  # conf.file_separator = '/'
+
+  # bintest
+  # conf.enable_bintest
+end
+
+MRuby::Build.new('host-debug') do |conf|
+  # load specific toolchain settings
+
+  # Gets set by the VS command prompts.
+  if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
+    toolchain :visualcpp
+  else
+    toolchain :gcc
+  end
+
+  enable_debug
+
+  # include the default GEMs
+  conf.gembox 'default'
+
+  # C compiler settings
+  conf.cc.defines = %w(MRB_ENABLE_DEBUG_HOOK)
+
+  # Generate mruby debugger command (require mruby-eval)
+  conf.gem :core => "mruby-bin-debugger"
+
+  # bintest
+  # conf.enable_bintest
+end
+
+#MRuby::Build.new('test') do |conf|
+#  # Gets set by the VS command prompts.
+#  if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
+#    toolchain :visualcpp
+#  else
+#    toolchain :gcc
+#  end
+#
+#  enable_debug
+#  conf.enable_bintest
+#  conf.enable_test
+#
+#  conf.gembox 'default'
+#end
+
+# Define cross build settings
+# MRuby::CrossBuild.new('32bit') do |conf|
+#   toolchain :gcc
+#
+#   conf.cc.flags << "-m32"
+#   conf.linker.flags << "-m32"
+#
+#   conf.build_mrbtest_lib_only
+#
+#   conf.gem 'examples/mrbgems/c_and_ruby_extension_example'
+#
+#   conf.test_runner.command = 'env'
+#
+# end
+
+# Define cross build settings
+MRuby::CrossBuild.new('arm-none-eabi') do |conf|
+  toolchain :gcc
+
+  conf.cc.command = "arm-none-eabi-gcc"
+  conf.cxx.command = "arm-none-eabi-g++"
+  conf.linker.command = "arm-none-eabi-gcc"
+  conf.archiver.command = "arm-none-eabi-ar"
+
+  conf.cc.flags << %w(-MD -MP -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing -nostdinc)
+  conf.cc.include_paths  << "../musl-1.1.18/include"
+
+  conf.linker.flags << %w(-nostdlib)
+  conf.linker.library_paths << "../musl-1.1.18/lib"
+  conf.linker.libraries << %w(c gcc)
+
+  #configuration for low memory environment
+  conf.cc.defines << %w(MRB_GC_STRESS)
+  #conf.cc.defines << %w(DISABLE_STDIO)
+  conf.cc.defines = %w(MRB_ENABLE_DEBUG_HOOK)
+
+  conf.build_mrbtest_lib_only
+
+  conf.gem "#{root}/mrbgems/mruby-compiler"
+  conf.gem "#{root}/mrbgems/mruby-numeric-ext"
+  conf.gem "#{root}/mrbgems/mruby-string-ext"
+  conf.gem '../mrbgems/mruby-onig-regexp'  do |g|
+    g.cc.include_paths  << "../onigmo-6.1.3/src"
+  end
+  conf.gem "#{root}/../mrbgems/mruby-blockly"
+  conf.gem "#{root}/../mrbgems/mruby-digest" do |g|
+    g.cc.include_paths << "#{g.dir}/../../openssl-1.1.0e/include"
+  end
+  conf.gem "#{root}/../mrbgems/mruby-dir"
+  conf.gem "#{root}/../mrbgems/mruby-env"
+  conf.gem "#{root}/../mrbgems/mruby-errno"
+  conf.gem "#{root}/../mrbgems/mruby-iijson"
+  conf.gem "#{root}/../mrbgems/mruby-io"
+  conf.gem "#{root}/../mrbgems/mruby-ipaddr"
+  conf.gem "#{root}/../mrbgems/mruby-mock"
+  conf.gem "#{root}/../mrbgems/mruby-pack"
+  conf.gem "#{root}/../mrbgems/mruby-require"
+  conf.gem "#{root}/../mrbgems/mruby-socket"
+  conf.gem "#{root}/../mrbgems/mruby-tls-openssl" do |g|
+    g.cc.include_paths << "#{g.dir}/../../openssl-1.1.0e/include"
+  end
+  conf.gem "#{root}/../mrbgems/mruby-arduino" do |g|
+    g.cc.include_paths << "#{g.dir}/../../prototool/src"
+    g.cc.include_paths << "#{g.dir}/../../mbed_api/src"
+  end
+  conf.gem "#{root}/../mrbgems/mruby-ecnl"
+  conf.gem "#{root}/../mrbgems/mruby-others"
+
+  conf.bins = []
+
+  # conf.test_runner.command = 'env'
+end
+=begin
+MRuby::CrossBuild.new("emscripten") do |conf|
+  toolchain :emscripten
+
+  conf.archiver.command = "llvm-ar"
+  conf.linker.flags << '--save-bc %{outfile}.bc --pre-js ../webapp/webmrbc/pre.js --post-js ../webapp/webmrbc/post.js --use-preload-plugins'
+  #conf.linker.flags << '-s BINARYEN=1'
+  #conf.exts.executable = '.html'
+
+  # include the default GEMs
+  conf.gembox 'default'
+  conf.gem :core => 'mruby-bin-mrbc'
+end
+=end
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_and_ruby_extension_example/README.md
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_and_ruby_extension_example/README.md	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_and_ruby_extension_example/README.md	(revision 331)
@@ -0,0 +1,4 @@
+C and Ruby Extension Example
+=========
+
+This is an example gem which implements a C and Ruby extension.
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_and_ruby_extension_example/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_and_ruby_extension_example/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_and_ruby_extension_example/mrbgem.rake	(revision 331)
@@ -0,0 +1,23 @@
+MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+
+  # Add compile flags
+  # spec.cc.flags << ''
+
+  # Add cflags to all
+  # spec.mruby.cc.flags << '-g'
+
+  # Add libraries
+  # spec.linker.libraries << 'external_lib'
+
+  # Default build files
+  # spec.rbfiles = Dir.glob("#{dir}/mrblib/*.rb")
+  # spec.objs = Dir.glob("#{dir}/src/*.{c,cpp,m,asm,S}").map { |f| objfile(f.relative_path_from(dir).pathmap("#{build_dir}/%X")) }
+  # spec.test_rbfiles = Dir.glob("#{dir}/test/*.rb")
+  # spec.test_objs = Dir.glob("#{dir}/test/*.{c,cpp,m,asm,S}").map { |f| objfile(f.relative_path_from(dir).pathmap("#{build_dir}/%X")) }
+  # spec.test_preload = 'test/assert.rb'
+
+  # Values accessible as TEST_ARGS inside test scripts
+  # spec.test_args = {'tmp_dir' => Dir::tmpdir}
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_and_ruby_extension_example/mrblib/example.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_and_ruby_extension_example/mrblib/example.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_and_ruby_extension_example/mrblib/example.rb	(revision 331)
@@ -0,0 +1,5 @@
+module CRubyExtension
+  def CRubyExtension.ruby_method
+    puts "A Ruby Extension"
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_and_ruby_extension_example/src/example.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_and_ruby_extension_example/src/example.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_and_ruby_extension_example/src/example.c	(revision 331)
@@ -0,0 +1,20 @@
+#include <mruby.h>
+#include <stdio.h>
+
+static mrb_value
+mrb_c_method(mrb_state *mrb, mrb_value self)
+{
+  puts("A C Extension");
+  return self;
+}
+
+void
+mrb_c_and_ruby_extension_example_gem_init(mrb_state* mrb) {
+  struct RClass *class_cextension = mrb_define_module(mrb, "CRubyExtension");
+  mrb_define_class_method(mrb, class_cextension, "c_method", mrb_c_method, MRB_ARGS_NONE());
+}
+
+void
+mrb_c_and_ruby_extension_example_gem_final(mrb_state* mrb) {
+  /* finalizer */
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_and_ruby_extension_example/test/example.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_and_ruby_extension_example/test/example.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_and_ruby_extension_example/test/example.rb	(revision 331)
@@ -0,0 +1,7 @@
+assert('C and Ruby Extension Example 1') do
+  CRubyExtension.respond_to? :c_method
+end
+
+assert('C and Ruby Extension Example 2') do
+  CRubyExtension.respond_to? :ruby_method
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_extension_example/README.md
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_extension_example/README.md	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_extension_example/README.md	(revision 331)
@@ -0,0 +1,4 @@
+C Extension Example
+=========
+
+This is an example gem which implements a C extension.
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_extension_example/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_extension_example/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_extension_example/mrbgem.rake	(revision 331)
@@ -0,0 +1,23 @@
+MRuby::Gem::Specification.new('c_extension_example') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+
+  # Add compile flags
+  # spec.cc.flags << '-g'
+
+  # Add cflags to all
+  # spec.mruby.cc.flags << '-g'
+
+  # Add libraries
+  # spec.linker.libraries << 'external_lib'
+
+  # Default build files
+  # spec.rbfiles = Dir.glob("#{dir}/mrblib/*.rb")
+  # spec.objs = Dir.glob("#{dir}/src/*.{c,cpp,m,asm,S}").map { |f| objfile(f.relative_path_from(dir).pathmap("#{build_dir}/%X")) }
+  # spec.test_rbfiles = Dir.glob("#{dir}/test/*.rb")
+  # spec.test_objs = Dir.glob("#{dir}/test/*.{c,cpp,m,asm,S}").map { |f| objfile(f.relative_path_from(dir).pathmap("#{build_dir}/%X")) }
+  # spec.test_preload = 'test/assert.rb'
+
+  # Values accessible as TEST_ARGS inside test scripts
+  # spec.test_args = {'tmp_dir' => Dir::tmpdir}
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_extension_example/src/example.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_extension_example/src/example.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_extension_example/src/example.c	(revision 331)
@@ -0,0 +1,20 @@
+#include <mruby.h>
+#include <stdio.h>
+
+static mrb_value
+mrb_c_method(mrb_state *mrb, mrb_value self)
+{
+  puts("A C Extension");
+  return self;
+}
+
+void
+mrb_c_extension_example_gem_init(mrb_state* mrb) {
+  struct RClass *class_cextension = mrb_define_module(mrb, "CExtension");
+  mrb_define_class_method(mrb, class_cextension, "c_method", mrb_c_method, MRB_ARGS_NONE());
+}
+
+void
+mrb_c_extension_example_gem_final(mrb_state* mrb) {
+  /* finalizer */
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_extension_example/test/example.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_extension_example/test/example.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_extension_example/test/example.c	(revision 331)
@@ -0,0 +1,7 @@
+#include <mruby.h>
+
+void
+mrb_c_extension_example_gem_test(mrb_state *mrb)
+{
+  /* test initializer in C */
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_extension_example/test/example.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_extension_example/test/example.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/c_extension_example/test/example.rb	(revision 331)
@@ -0,0 +1,3 @@
+assert('C Extension Example') do
+  CExtension.respond_to? :c_method
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/ruby_extension_example/README.md
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/ruby_extension_example/README.md	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/ruby_extension_example/README.md	(revision 331)
@@ -0,0 +1,4 @@
+Pure Ruby Extension Example
+=========
+
+This is an example gem which implements a pure Ruby extension.
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/ruby_extension_example/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/ruby_extension_example/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/ruby_extension_example/mrbgem.rake	(revision 331)
@@ -0,0 +1,25 @@
+MRuby::Gem::Specification.new('ruby_extension_example') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+
+  # Add compile flags
+  # spec.cc.flags << ''
+
+  # Add cflags to all
+  # spec.mruby.cc.flags << '-g'
+
+  # Add libraries
+  # spec.linker.libraries << 'external_lib'
+
+  spec.add_dependency('mruby-print', :core => 'mruby-print')
+
+  # Default build files
+  # spec.rbfiles = Dir.glob("#{dir}/mrblib/*.rb")
+  # spec.objs = Dir.glob("#{dir}/src/*.{c,cpp,m,asm,S}").map { |f| objfile(f.relative_path_from(dir).pathmap("#{build_dir}/%X")) }
+  # spec.test_rbfiles = Dir.glob("#{dir}/test/*.rb")
+  # spec.test_objs = Dir.glob("#{dir}/test/*.{c,cpp,m,asm,S}").map { |f| objfile(f.relative_path_from(dir).pathmap("#{build_dir}/%X")) }
+  # spec.test_preload = 'test/assert.rb'
+
+  # Values accessible as TEST_ARGS inside test scripts
+  # spec.test_args = {'tmp_dir' => Dir::tmpdir}
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/ruby_extension_example/mrblib/example.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/ruby_extension_example/mrblib/example.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/ruby_extension_example/mrblib/example.rb	(revision 331)
@@ -0,0 +1,5 @@
+class RubyExtension
+  def RubyExtension.ruby_method
+    puts "A Ruby Extension"
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/ruby_extension_example/test/example.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/ruby_extension_example/test/example.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/mrbgems/ruby_extension_example/test/example.rb	(revision 331)
@@ -0,0 +1,3 @@
+assert('Ruby Extension Example') do
+  RubyExtension.respond_to? :ruby_method
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_ArduinoDue.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_ArduinoDue.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_ArduinoDue.rb	(revision 331)
@@ -0,0 +1,91 @@
+MRuby::Build.new do |conf|
+
+  # Gets set by the VS command prompts.
+  if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
+    toolchain :visualcpp
+  else
+    toolchain :gcc
+  end
+
+  enable_debug
+
+  # include the default GEMs
+  conf.gembox 'default'
+
+end
+
+# Cross Compiling configuration for Arduino Due
+# http://arduino.cc/en/Main/ArduinoBoardDue
+#
+# Requires Arduino IDE >= 1.5
+MRuby::CrossBuild.new("ArduinoDue") do |conf|
+  toolchain :gcc
+
+  # Mac OS X, Arduino IDE <= 1.5.6
+  # ARDUINO_PATH = '/Applications/Arduino.app/Contents/Resources/Java'
+  # Mac OS X, Arduino IDE >= 1.5.7
+  # ARDUINO_PATH = '/Applications/Arduino.app/Contents/Java'
+  # GNU Linux
+  ARDUINO_PATH = '/opt/arduino'
+   # Arduino IDE <= 1.5.6
+  BIN_PATH = "#{ARDUINO_PATH}/hardware/tools/g++_arm_none_eabi/bin"
+  # Arduino IDE >= 1.5.7
+  # BIN_PATH = "#{ARDUINO_PATH}/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin"
+  SAM_PATH = "#{ARDUINO_PATH}/hardware/arduino/sam"
+  TARGET_PATH = "#{SAM_PATH}/variants/arduino_due_x"
+
+  conf.cc do |cc|
+    cc.command = "#{BIN_PATH}/arm-none-eabi-gcc"
+    cc.include_paths << ["#{SAM_PATH}/system/libsam", "#{SAM_PATH}/system/CMSIS/CMSIS/Include/",
+                        "#{SAM_PATH}/system/CMSIS/Device/ATMEL/",
+                        "#{SAM_PATH}/cores/arduino", "#{SAM_PATH}/libraries","#{TARGET_PATH}"]
+    cc.flags = %w(-g -Os -w -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500
+                -Dprintf=iprintf -mcpu=cortex-m3 -DF_CPU=84000000L -DARDUINO=156 -DARDUINO_SAM_DUE -DARDUINO_ARCH_SAM
+                -D__SAM3X8E__ -mthumb -DUSB_PID=0x003e -DUSB_VID=0x2341 -DUSBCON -DUSB_MANUFACTURER="Unknown" -DUSB_PRODUCT="Arduino Due")
+    cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
+
+    #configuration for low memory environment
+    cc.defines << %w(MRB_HEAP_PAGE_SIZE=64)
+    cc.defines << %w(MRB_USE_IV_SEGLIST)
+    cc.defines << %w(KHASH_DEFAULT_SIZE=8)
+    cc.defines << %w(MRB_STR_BUF_MIN_SIZE=20)
+    cc.defines << %w(MRB_GC_STRESS)
+    #cc.defines << %w(MRB_DISABLE_STDIO) #if you dont need stdio.
+    #cc.defines << %w(POOL_PAGE_SIZE=1000) #effective only for use with mruby-eval
+  end
+
+  conf.cxx do |cxx|
+    cxx.command = conf.cc.command.dup
+    cxx.include_paths = conf.cc.include_paths.dup
+    cxx.flags = conf.cc.flags.dup
+    cxx.flags << %w(-fno-rtti -fno-exceptions)
+    cxx.defines = conf.cc.defines.dup
+    cxx.compile_options = conf.cc.compile_options.dup
+  end
+
+  conf.archiver do |archiver|
+    archiver.command = "#{BIN_PATH}/arm-none-eabi-ar"
+    archiver.archive_options = 'rcs %{outfile} %{objs}'
+  end
+
+  #no executables
+  conf.bins = []
+
+  #do not build executable test
+  conf.build_mrbtest_lib_only
+
+  #disable C++ exception
+  conf.disable_cxx_exception
+
+  #gems from core
+  conf.gem :core => "mruby-print"
+  conf.gem :core => "mruby-math"
+  conf.gem :core => "mruby-enum-ext"
+
+  #light-weight regular expression
+  conf.gem :github => "masamitsu-murase/mruby-hs-regexp", :branch => "master"
+
+  #Arduino API
+  #conf.gem :github =>"kyab/mruby-arduino", :branch => "master"
+
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_IntelEdison.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_IntelEdison.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_IntelEdison.rb	(revision 331)
@@ -0,0 +1,69 @@
+# Cross-compiling setup for Intel Edison (poky linux) platform
+# Get SDK from here: https://software.intel.com/en-us/iot/hardware/edison/downloads
+# REMEMBER to check and update the SDK root in the constant POKY_EDISON_PATH
+
+MRuby::Build.new do |conf|
+  toolchain :gcc
+  conf.gembox 'default'
+  conf.cc.defines = %w(ENABLE_READLINE)
+  conf.gembox 'default'
+
+  #lightweight regular expression
+  conf.gem :github => "pbosetti/mruby-hs-regexp", :branch => "master"
+
+end
+
+# Define cross build settings
+MRuby::CrossBuild.new('core2-32-poky-linux') do |conf|
+  toolchain :gcc
+
+  # Mac OS X
+  #
+  POKY_EDISON_PATH = '/opt/poky-edison/1.7.2'
+
+  POKY_EDISON_SYSROOT =  "#{POKY_EDISON_PATH}/sysroots/core2-32-poky-linux"
+  POKY_EDISON_X86_PATH = "#{POKY_EDISON_PATH}/sysroots/i386-pokysdk-darwin"
+  POKY_EDISON_BIN_PATH = "#{POKY_EDISON_X86_PATH}/usr/bin/i586-poky-linux"
+
+
+  conf.cc do |cc|
+    cc.command = "#{POKY_EDISON_BIN_PATH}/i586-poky-linux-gcc"
+    cc.include_paths << ["#{POKY_EDISON_SYSROOT}/usr/include", "#{POKY_EDISON_X86_PATH}/usr/include"]
+    cc.flags = %w(-m32 -march=core2 -mtune=core2 -msse3 -mfpmath=sse -mstackrealign -fno-omit-frame-pointer)
+    cc.flags << %w(-O2 -pipe -g -feliminate-unused-debug-types)
+    cc.flags << "--sysroot=#{POKY_EDISON_SYSROOT}"
+    cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
+    cc.defines = %w(ENABLE_READLINE)
+  end
+
+  conf.cxx do |cxx|
+    cxx.command = "#{POKY_EDISON_BIN_PATH}/i586-poky-linux-g++"
+    cxx.include_paths = conf.cc.include_paths.dup
+    cxx.include_paths << ["#{POKY_EDISON_SYSROOT}/usr/include/c++/4.9.1"]
+    cxx.flags = conf.cc.flags.dup
+    cxx.defines = conf.cc.defines.dup
+    cxx.compile_options = conf.cc.compile_options.dup
+  end
+
+  conf.archiver do |archiver|
+    archiver.command = "#{POKY_EDISON_BIN_PATH}/i586-poky-linux-ar"
+    archiver.archive_options = 'rcs %{outfile} %{objs}'
+  end
+
+  conf.linker do |linker|
+    linker.command = "#{POKY_EDISON_BIN_PATH}/i586-poky-linux-g++"
+    linker.flags = %w(-m32 -march=i586)
+    linker.flags << "--sysroot=#{POKY_EDISON_SYSROOT}"
+    linker.flags << %w(-O1)
+    linker.libraries = %w(m pthread)
+  end
+
+  #do not build executable test
+  conf.build_mrbtest_lib_only
+
+  conf.gembox 'default'
+
+  #lightweight regular expression
+  conf.gem :github => "pbosetti/mruby-hs-regexp", :branch => "master"
+
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_IntelGalileo.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_IntelGalileo.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_IntelGalileo.rb	(revision 331)
@@ -0,0 +1,106 @@
+MRuby::Build.new do |conf|
+
+  # Gets set by the VS command prompts.
+  if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
+    toolchain :visualcpp
+  else
+    toolchain :gcc
+  end
+
+  enable_debug
+
+  # include the default GEMs
+  conf.gembox 'default'
+
+end
+
+
+# Cross Compiling configuration for Intel Galileo on Arduino environment
+# http://arduino.cc/en/ArduinoCertified/IntelGalileo
+#
+# Requires Arduino IDE for Intel Galileo
+MRuby::CrossBuild.new("Galileo") do |conf|
+  toolchain :gcc
+
+  # Mac OS X
+  # Assume you renamed Arduino.app to Arduino_Galileo.app
+  GALILEO_ARDUINO_PATH = '/Applications/Arduino_Galileo.app/Contents/Resources/Java'
+  # GNU Linux
+  #ARDUINO_GALILEO_PATH = '/opt/arduino'
+
+  GALILEO_BIN_PATH = "#{GALILEO_ARDUINO_PATH}/hardware/tools/x86/i386-pokysdk-darwin/usr/bin/i586-poky-linux-uclibc"
+  GALILEO_SYSROOT =  "#{GALILEO_ARDUINO_PATH}/hardware/tools/x86/i586-poky-linux-uclibc"
+  GALILEO_X86_PATH = "#{GALILEO_ARDUINO_PATH}/hardware/arduino/x86"
+
+
+  conf.cc do |cc|
+    cc.command = "#{GALILEO_BIN_PATH}/i586-poky-linux-uclibc-gcc"
+    cc.include_paths << ["#{GALILEO_X86_PATH}/cores/arduino", "#{GALILEO_X86_PATH}/variants/galileo_fab_d"]
+    cc.flags = %w(-m32 -march=i586 -c -g -Os -w
+              -ffunction-sections -fdata-sections -MMD -DARDUINO=153)
+    cc.flags << "--sysroot=#{GALILEO_SYSROOT}"
+    cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
+  end
+
+  conf.cxx do |cxx|
+    cxx.command = "#{GALILEO_BIN_PATH}/i586-poky-linux-uclibc-g++"
+    cxx.include_paths = conf.cc.include_paths.dup
+    cxx.include_paths << "#{GALILEO_ARDUINO_PATH}/hardware/tools/x86/i586-poky-linux-uclibc/usr/include/c++"
+    cxx.include_paths << "#{GALILEO_ARDUINO_PATH}/hardware/tools/x86/i586-poky-linux-uclibc/usr/include/c++/i586-poky-linux-uclibc"
+    cxx.flags = conf.cc.flags.dup
+    cxx.defines = conf.cc.defines.dup
+    cxx.compile_options = conf.cc.compile_options.dup
+  end
+
+  conf.archiver do |archiver|
+    archiver.command = "#{GALILEO_BIN_PATH}/i586-poky-linux-uclibc-ar"
+    archiver.archive_options = 'rcs %{outfile} %{objs}'
+  end
+
+  conf.linker do |linker|
+    linker.command = "#{GALILEO_BIN_PATH}/i586-poky-linux-uclibc-g++"
+    linker.flags = %w(-m32 -march=i586)
+    linker.flags << "--sysroot=#{GALILEO_SYSROOT}"
+    linker.flags << %w(-Os -Wl,--gc-sections)
+    linker.libraries = %w(m pthread)
+  end
+
+  #no executables
+  conf.bins = []
+
+  #do not build executable test
+  conf.build_mrbtest_lib_only
+
+  #official mrbgems
+  conf.gem :core => "mruby-sprintf"
+  conf.gem :core => "mruby-print"
+  conf.gem :core => "mruby-math"
+  conf.gem :core => "mruby-time"
+  conf.gem :core => "mruby-struct"
+  conf.gem :core => "mruby-enum-ext"
+  conf.gem :core => "mruby-string-ext"
+  conf.gem :core => "mruby-numeric-ext"
+  conf.gem :core => "mruby-array-ext"
+  conf.gem :core => "mruby-hash-ext"
+  conf.gem :core => "mruby-range-ext"
+  conf.gem :core => "mruby-proc-ext"
+  conf.gem :core => "mruby-symbol-ext"
+  conf.gem :core => "mruby-random"
+  conf.gem :core => "mruby-object-ext"
+  conf.gem :core => "mruby-objectspace"
+  conf.gem :core => "mruby-fiber"
+  conf.gem :core => "mruby-toplevel-ext"
+
+  #lightweigh regular expression
+  conf.gem :github => "masamitsu-murase/mruby-hs-regexp", :branch => "master"
+
+  #Arduino API
+  #conf.gem :github =>"kyab/mruby-arduino", :branch => "master" do |g|
+  #  g.cxx.include_paths << "#{GALILEO_X86_PATH}/libraries/Wire"
+  #  g.cxx.include_paths << "#{GALILEO_X86_PATH}/libraries/Servo"
+
+    #enable unsupported Servo class
+  #  g.cxx.defines << "MRUBY_ARDUINO_GALILEO_ENABLE_SERVO"
+  #end
+
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_RX630.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_RX630.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_RX630.rb	(revision 331)
@@ -0,0 +1,82 @@
+MRuby::Build.new do |conf|
+
+  # Gets set by the VS command prompts.
+  if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
+    toolchain :visualcpp
+  else
+    toolchain :gcc
+  end
+
+  enable_debug
+
+  # include the default GEMs
+  conf.gembox 'default'
+
+end
+
+# Cross Compiling configuration for RX630
+# http://gadget.renesas.com/
+#
+# Requires gnurx_v14.03
+MRuby::CrossBuild.new("RX630") do |conf|
+  toolchain :gcc
+
+  # Linux
+  BIN_PATH = "/usr/share/gnurx_v14.03_elf-1/bin"
+
+  conf.cc do |cc|
+    cc.command = "#{BIN_PATH}/rx-elf-gcc"
+    cc.flags = "-Wall -g -O2 -flto -mcpu=rx600 -m64bit-doubles"
+    cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
+
+    #configuration for low memory environment
+    cc.defines << %w(MRB_USE_FLOAT)
+    cc.defines << %w(MRB_HEAP_PAGE_SIZE=64)
+    cc.defines << %w(MRB_USE_IV_SEGLIST)
+    cc.defines << %w(KHASH_DEFAULT_SIZE=8)
+    cc.defines << %w(MRB_STR_BUF_MIN_SIZE=20)
+    cc.defines << %w(MRB_GC_STRESS)
+    cc.defines << %w(MRB_DISABLE_STDIO) #if you dont need stdio.
+    #cc.defines << %w(POOL_PAGE_SIZE=1000) #effective only for use with mruby-eval
+  end
+
+  conf.cxx do |cxx|
+    cxx.command = conf.cc.command.dup
+    cxx.include_paths = conf.cc.include_paths.dup
+    cxx.flags = conf.cc.flags.dup
+    cxx.defines = conf.cc.defines.dup
+    cxx.compile_options = conf.cc.compile_options.dup
+  end
+
+  conf.linker do |linker|
+    linker.command="#{BIN_PATH}/rx-elf-ld"
+  end
+
+  conf.archiver do |archiver|
+    archiver.command = "#{BIN_PATH}/rx-elf-ar"
+    archiver.archive_options = 'rcs %{outfile} %{objs}'
+  end
+
+  #no executables
+  conf.bins = []
+
+  #do not build executable test
+  conf.build_mrbtest_lib_only
+
+  #disable C++ exception
+  conf.disable_cxx_exception
+
+  #gems from core
+  conf.gem :core => "mruby-sprintf"
+  conf.gem :core => "mruby-print"
+  conf.gem :core => "mruby-math"
+  conf.gem :core => "mruby-enum-ext"
+  conf.gem :core => "mruby-numeric-ext"
+
+  #light-weight regular expression
+  #conf.gem :github => "masamitsu-murase/mruby-hs-regexp", :branch => "master"
+
+  #Arduino API
+  #conf.gem :github =>"kyab/mruby-arduino", :branch => "master"
+
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_android_arm64-v8a.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_android_arm64-v8a.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_android_arm64-v8a.rb	(revision 331)
@@ -0,0 +1,26 @@
+MRuby::Build.new do |conf|
+
+  # Gets set by the VS command prompts.
+  if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
+    toolchain :visualcpp
+  else
+    toolchain :gcc
+  end
+
+  enable_debug
+
+  # include the default GEMs
+  conf.gembox 'default'
+end
+
+# Requires Android NDK r13 or later.
+MRuby::CrossBuild.new('android-arm64-v8a') do |conf|
+  params = { 
+    :arch => 'arm64-v8a', 
+    :platform => 'android-24',
+    :toolchain => :clang,
+  }
+  toolchain :android, params
+
+  conf.gembox 'default'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_android_armeabi.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_android_armeabi.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_android_armeabi.rb	(revision 331)
@@ -0,0 +1,26 @@
+MRuby::Build.new do |conf|
+
+  # Gets set by the VS command prompts.
+  if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
+    toolchain :visualcpp
+  else
+    toolchain :gcc
+  end
+
+  enable_debug
+
+  # include the default GEMs
+  conf.gembox 'default'
+end
+
+# Requires Android NDK r13 or later.
+MRuby::CrossBuild.new('android-armeabi') do |conf|
+  params = { 
+    :arch => 'armeabi', 
+    :platform => 'android-24',
+    :toolchain => :clang,
+  }
+  toolchain :android, params
+
+  conf.gembox 'default'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_android_armeabi_v7a_neon_hard.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_android_armeabi_v7a_neon_hard.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_android_armeabi_v7a_neon_hard.rb	(revision 331)
@@ -0,0 +1,28 @@
+MRuby::Build.new do |conf|
+
+  # Gets set by the VS command prompts.
+  if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
+    toolchain :visualcpp
+  else
+    toolchain :gcc
+  end
+
+  enable_debug
+
+  # include the default GEMs
+  conf.gembox 'default'
+end
+
+# Requires Android NDK r13 or later.
+MRuby::CrossBuild.new('android-armeabi-v7a-neon-hard') do |conf|
+  params = {
+    :arch => 'armeabi-v7a',
+    :mfpu => 'neon',
+    :mfloat_abi => 'hard',
+    :platform => 'android-24',
+    :toolchain => :clang,
+  }
+  toolchain :android, params
+
+  conf.gembox 'default'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_chipKITMax32.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_chipKITMax32.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/examples/targets/build_config_chipKITMax32.rb	(revision 331)
@@ -0,0 +1,87 @@
+MRuby::Build.new do |conf|
+
+  # Gets set by the VS command prompts.
+  if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
+    toolchain :visualcpp
+  else
+    toolchain :gcc
+  end
+
+  enable_debug
+
+  # include the default GEMs
+  conf.gembox 'default'
+
+end
+
+# Cross Compiling configuration for Digilent chipKIT Max32
+# http://www.digilentinc.com/Products/Detail.cfm?Prod=CHIPKIT-MAX32
+#
+# Requires MPIDE (https://github.com/chipKIT32/chipKIT32-MAX)
+#
+# This configuration is based on @kyab's version
+# http://d.hatena.ne.jp/kyab/20130201
+MRuby::CrossBuild.new("chipKITMax32") do |conf|
+  toolchain :gcc
+
+  # Mac OS X
+  # MPIDE_PATH = '/Applications/Mpide.app/Contents/Resources/Java'
+  # GNU Linux
+  MPIDE_PATH = '/opt/mpide-0023-linux-20120903'
+
+  PIC32_PATH = "#{MPIDE_PATH}/hardware/pic32"
+
+  conf.cc do |cc|
+    cc.command = "#{PIC32_PATH}/compiler/pic32-tools/bin/pic32-gcc"
+    cc.include_paths << ["#{PIC32_PATH}/cores/pic32",
+                        "#{PIC32_PATH}/variants/Max32",
+                        "#{PIC32_PATH}/libraries"]
+    cc.flags = %w(-O2 -mno-smart-io -w -ffunction-sections -fdata-sections -g -mdebugger -Wcast-align
+                -fno-short-double -mprocessor=32MX795F512L -DF_CPU=80000000L -DARDUINO=23 -D_BOARD_MEGA_
+                -DMPIDEVER=0x01000202 -DMPIDE=23)
+    cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
+
+    #configuration for low memory environment
+    cc.defines << %w(MRB_HEAP_PAGE_SIZE=64)
+    cc.defines << %w(MRB_USE_IV_SEGLIST)
+    cc.defines << %w(KHASH_DEFAULT_SIZE=8)
+    cc.defines << %w(MRB_STR_BUF_MIN_SIZE=20)
+    cc.defines << %w(MRB_GC_STRESS)
+    #cc.defines << %w(MRB_DISABLE_STDIO) #if you dont need stdio.
+    #cc.defines << %w(POOL_PAGE_SIZE=1000) #effective only for use with mruby-eval
+  end
+
+  conf.cxx do |cxx|
+    cxx.command = conf.cc.command.dup
+    cxx.include_paths = conf.cc.include_paths.dup
+    cxx.flags = conf.cc.flags.dup
+    cxx.defines = conf.cc.defines.dup
+    cxx.compile_options = conf.cc.compile_options.dup
+  end
+
+  conf.archiver do |archiver|
+    archiver.command = "#{PIC32_PATH}/compiler/pic32-tools/bin/pic32-ar"
+    archiver.archive_options = 'rcs %{outfile} %{objs}'
+  end
+
+  #no executables
+  conf.bins = []
+
+  #do not build test executable
+  conf.build_mrbtest_lib_only
+
+  #disable C++ exception
+  conf.disable_cxx_exception
+
+  #gems from core
+  conf.gem :core => "mruby-print"
+  conf.gem :core => "mruby-math"
+  conf.gem :core => "mruby-enum-ext"
+
+  #light-weight regular expression
+  conf.gem :github => "masamitsu-murase/mruby-hs-regexp", :branch => "master"
+
+  #Arduino API
+  #conf.gem :github =>"kyab/mruby-arduino", :branch => "master"
+
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mrbconf.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mrbconf.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mrbconf.h	(revision 331)
@@ -0,0 +1,125 @@
+/*
+** mrbconf.h - mruby core configuration
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBYCONF_H
+#define MRUBYCONF_H
+
+#include <limits.h>
+#include <stdint.h>
+
+/* architecture selection: */
+/* specify -DMRB_32BIT or -DMRB_64BIT to override */
+#if !defined(MRB_32BIT) && !defined(MRB_64BIT)
+#if UINT64_MAX == SIZE_MAX
+#define MRB_64BIT
+#else
+#define MRB_32BIT
+#endif
+#endif
+
+#if defined(MRB_32BIT) && defined(MRB_64BIT)
+#error Cannot build for 32 and 64 bit architecture at the same time
+#endif
+
+/* configuration options: */
+/* add -DMRB_USE_FLOAT to use float instead of double for floating point numbers */
+//#define MRB_USE_FLOAT
+
+/* add -DMRB_INT16 to use 16bit integer for mrb_int; conflict with MRB_INT64 */
+//#define MRB_INT16
+
+/* add -DMRB_INT64 to use 64bit integer for mrb_int; conflict with MRB_INT16 */
+//#define MRB_INT64
+
+/* represent mrb_value in boxed double; conflict with MRB_USE_FLOAT */
+//#define MRB_NAN_BOXING
+
+/* define on big endian machines; used by MRB_NAN_BOXING */
+//#define MRB_ENDIAN_BIG
+
+/* represent mrb_value as a word (natural unit of data for the processor) */
+//#define MRB_WORD_BOXING
+
+/* string class to handle UTF-8 encoding */
+#define MRB_UTF8_STRING
+
+/* argv max size in mrb_funcall */
+//#define MRB_FUNCALL_ARGC_MAX 16
+
+/* number of object per heap page */
+//#define MRB_HEAP_PAGE_SIZE 1024
+
+/* use segmented list for IV table */
+//#define MRB_USE_IV_SEGLIST
+
+/* initial size for IV khash; ignored when MRB_USE_IV_SEGLIST is set */
+//#define MRB_IVHASH_INIT_SIZE 8
+
+/* if _etext and _edata available, mruby can reduce memory used by symbols */
+//#define MRB_USE_ETEXT_EDATA
+
+/* do not use __init_array_start to determine readonly data section;
+   effective only when MRB_USE_ETEXT_EDATA is defined */
+//#define MRB_NO_INIT_ARRAY_START
+
+/* turn off generational GC by default */
+//#define MRB_GC_TURN_OFF_GENERATIONAL
+
+/* default size of khash table bucket */
+//#define KHASH_DEFAULT_SIZE 32
+
+/* allocated memory address alignment */
+//#define POOL_ALIGNMENT 4
+
+/* page size of memory pool */
+//#define POOL_PAGE_SIZE 16000
+
+/* initial minimum size for string buffer */
+//#define MRB_STR_BUF_MIN_SIZE 128
+
+/* arena size */
+//#define MRB_GC_ARENA_SIZE 100
+
+/* fixed size GC arena */
+//#define MRB_GC_FIXED_ARENA
+
+/* state atexit stack size */
+//#define MRB_FIXED_STATE_ATEXIT_STACK_SIZE 5
+
+/* fixed size state atexit stack */
+//#define MRB_FIXED_STATE_ATEXIT_STACK
+
+/* -DMRB_DISABLE_XXXX to drop following features */
+//#define MRB_DISABLE_STDIO	/* use of stdio */
+
+/* -DMRB_ENABLE_XXXX to enable following features */
+//#define MRB_ENABLE_DEBUG_HOOK	/* hooks for debugger */
+
+/* end of configuration */
+
+/* define MRB_DISABLE_XXXX from DISABLE_XXX (for compatibility) */
+#ifdef DISABLE_STDIO
+#define MRB_DISABLE_STDIO
+#endif
+
+/* define MRB_ENABLE_XXXX from ENABLE_XXX (for compatibility) */
+#ifdef ENABLE_DEBUG
+#define MRB_ENABLE_DEBUG_HOOK
+#endif
+
+#ifndef MRB_DISABLE_STDIO
+# include <stdio.h>
+#endif
+
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+#ifndef TRUE
+# define TRUE 1
+#endif
+
+#endif  /* MRUBYCONF_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby.h	(revision 331)
@@ -0,0 +1,1210 @@
+/*
+** mruby - An embeddable Ruby implementation
+**
+** Copyright (c) mruby developers 2010-2017
+**
+** Permission is hereby granted, free of charge, to any person obtaining
+** a copy of this software and associated documentation files (the
+** "Software"), to deal in the Software without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Software, and to
+** permit persons to whom the Software is furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be
+** included in all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**
+** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
+*/
+
+#ifndef MRUBY_H
+#define MRUBY_H
+
+#ifdef __cplusplus
+#define __STDC_LIMIT_MACROS
+#define __STDC_CONSTANT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+#include <limits.h>
+
+#ifdef __cplusplus
+#ifndef SIZE_MAX
+#ifdef __SIZE_MAX__
+#define SIZE_MAX __SIZE_MAX__
+#else
+#define SIZE_MAX std::numeric_limits<size_t>::max()
+#endif
+#endif
+#endif
+
+#ifdef MRB_DEBUG
+#include <assert.h>
+#define mrb_assert(p) assert(p)
+#define mrb_assert_int_fit(t1,n,t2,max) assert((n)>=0 && ((sizeof(n)<=sizeof(t2))||(n<=(t1)(max))))
+#else
+#define mrb_assert(p) ((void)0)
+#define mrb_assert_int_fit(t1,n,t2,max) ((void)0)
+#endif
+
+#if __STDC_VERSION__ >= 201112L
+#define mrb_static_assert(exp, str) _Static_assert(exp, str)
+#else
+#define mrb_static_assert(exp, str) mrb_assert(exp)
+#endif
+
+#include "mrbconf.h"
+
+#ifdef MRB_USE_FLOAT
+#define MRB_FLOAT_EPSILON FLT_EPSILON
+#else
+#define MRB_FLOAT_EPSILON DBL_EPSILON
+#endif
+
+#include "mruby/common.h"
+#include <mruby/value.h>
+#include <mruby/gc.h>
+#include <mruby/version.h>
+
+/**
+ * MRuby C API entry point
+ */
+MRB_BEGIN_DECL
+
+typedef uint32_t mrb_code;
+
+/**
+ * Required arguments signature type.
+ */
+typedef uint32_t mrb_aspec;
+
+
+struct mrb_irep;
+struct mrb_state;
+
+/**
+ * Function pointer type of custom allocator used in @see mrb_open_allocf.
+ *
+ * The function pointing it must behave similarly as realloc except:
+ * - If ptr is NULL it must allocate new space.
+ * - If s is NULL, ptr must be freed.
+ *
+ * See @see mrb_default_allocf for the default implementation.
+ */
+typedef void* (*mrb_allocf) (struct mrb_state *mrb, void*, size_t, void *ud);
+
+#ifndef MRB_FIXED_STATE_ATEXIT_STACK_SIZE
+#define MRB_FIXED_STATE_ATEXIT_STACK_SIZE 5
+#endif
+
+typedef struct {
+  mrb_sym mid;
+  struct RProc *proc;
+  mrb_value *stackent;
+  int nregs;
+  int ridx;
+  int epos;
+  struct REnv *env;
+  mrb_code *pc;                 /* return address */
+  mrb_code *err;                /* error position */
+  int argc;
+  int acc;
+  struct RClass *target_class;
+} mrb_callinfo;
+
+enum mrb_fiber_state {
+  MRB_FIBER_CREATED = 0,
+  MRB_FIBER_RUNNING,
+  MRB_FIBER_RESUMED,
+  MRB_FIBER_SUSPENDED,
+  MRB_FIBER_TRANSFERRED,
+  MRB_FIBER_TERMINATED,
+};
+
+struct mrb_context {
+  struct mrb_context *prev;
+
+  mrb_value *stack;                       /* stack of virtual machine */
+  mrb_value *stbase, *stend;
+
+  mrb_callinfo *ci;
+  mrb_callinfo *cibase, *ciend;
+
+  mrb_code **rescue;                      /* exception handler stack */
+  int rsize;
+  struct RProc **ensure;                  /* ensure handler stack */
+  int esize, eidx;
+
+  enum mrb_fiber_state status;
+  mrb_bool vmexec;
+  struct RFiber *fib;
+};
+
+struct mrb_jmpbuf;
+
+typedef void (*mrb_atexit_func)(struct mrb_state*);
+
+#define MRB_STATE_NO_REGEXP 1
+#define MRB_STATE_REGEXP    2
+
+typedef struct mrb_state {
+  struct mrb_jmpbuf *jmp;
+
+  uint32_t flags;
+  mrb_allocf allocf;                      /* memory allocation function */
+  void *allocf_ud;                        /* auxiliary data of allocf */
+
+  struct mrb_context *c;
+  struct mrb_context *root_c;
+  struct iv_tbl *globals;                 /* global variable table */
+
+  struct RObject *exc;                    /* exception */
+
+  struct RObject *top_self;
+  struct RClass *object_class;            /* Object class */
+  struct RClass *class_class;
+  struct RClass *module_class;
+  struct RClass *proc_class;
+  struct RClass *string_class;
+  struct RClass *array_class;
+  struct RClass *hash_class;
+
+  struct RClass *float_class;
+  struct RClass *fixnum_class;
+  struct RClass *true_class;
+  struct RClass *false_class;
+  struct RClass *nil_class;
+  struct RClass *symbol_class;
+  struct RClass *kernel_module;
+
+  struct alloca_header *mems;
+  mrb_gc gc;
+
+  mrb_sym symidx;
+  struct kh_n2s *name2sym;      /* symbol hash */
+  struct symbol_name *symtbl;   /* symbol table */
+  size_t symcapa;
+
+#ifdef MRB_ENABLE_DEBUG_HOOK
+  void (*code_fetch_hook)(struct mrb_state* mrb, struct mrb_irep *irep, mrb_code *pc, mrb_value *regs);
+  void (*debug_op_hook)(struct mrb_state* mrb, struct mrb_irep *irep, mrb_code *pc, mrb_value *regs);
+#endif
+
+#ifdef MRB_BYTECODE_DECODE_OPTION
+  mrb_code (*bytecode_decoder)(struct mrb_state* mrb, mrb_code code);
+#endif
+
+  struct RClass *eException_class;
+  struct RClass *eStandardError_class;
+  struct RObject *nomem_err;              /* pre-allocated NoMemoryError */
+  struct RObject *stack_err;              /* pre-allocated SysStackError */
+#ifdef MRB_GC_FIXED_ARENA
+  struct RObject *arena_err;              /* pre-allocated arena overfow error */
+#endif
+
+  void *ud; /* auxiliary data */
+
+#ifdef MRB_FIXED_STATE_ATEXIT_STACK
+  mrb_atexit_func atexit_stack[MRB_FIXED_STATE_ATEXIT_STACK_SIZE];
+#else
+  mrb_atexit_func *atexit_stack;
+#endif
+  mrb_int atexit_stack_len;
+} mrb_state;
+
+
+typedef mrb_value (*mrb_func_t)(mrb_state *mrb, mrb_value);
+
+/**
+ * Defines a new class.
+ *
+ * If you're creating a gem it may look something like this:
+ *
+ *      !!!c
+ *      void mrb_example_gem_init(mrb_state* mrb) {
+ *          struct RClass *example_class;
+ *          example_class = mrb_define_class(mrb, "Example_Class", mrb->object_class);
+ *      }
+ *
+ *      void mrb_example_gem_final(mrb_state* mrb) {
+ *          //free(TheAnimals);
+ *      }
+ *
+ * @param [mrb_state *] mrb The current mruby state.
+ * @param [const char *] name The name of the defined class.
+ * @param [struct RClass *] super The new class parent.
+ * @return [struct RClass *] Reference to the newly defined class.
+ * @see mrb_define_class_under
+ */
+MRB_API struct RClass *mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super);
+
+/**
+ * Defines a new module.
+ *
+ * @param [mrb_state *] mrb_state* The current mruby state.
+ * @param [const char *] char* The name of the module.
+ * @return [struct RClass *] Reference to the newly defined module.
+ */
+MRB_API struct RClass *mrb_define_module(mrb_state *, const char*);
+MRB_API mrb_value mrb_singleton_class(mrb_state*, mrb_value);
+
+/**
+ * Include a module in another class or module.
+ * Equivalent to:
+ *
+ *   module B
+ *     include A
+ *   end
+ * @param [mrb_state *] mrb_state* The current mruby state.
+ * @param [struct RClass *] RClass* A reference to module or a class.
+ * @param [struct RClass *] RClass* A reference to the module to be included.
+ */
+MRB_API void mrb_include_module(mrb_state*, struct RClass*, struct RClass*);
+
+/**
+ * Prepends a module in another class or module.
+ *
+ * Equivalent to:
+ *  module B
+ *    prepend A
+ *  end
+ * @param [mrb_state *] mrb_state* The current mruby state.
+ * @param [struct RClass *] RClass* A reference to module or a class.
+ * @param [struct RClass *] RClass* A reference to the module to be prepended.
+ */
+MRB_API void mrb_prepend_module(mrb_state*, struct RClass*, struct RClass*);
+
+/**
+ * Defines a global function in ruby.
+ *
+ * If you're creating a gem it may look something like this
+ *
+ * Example:
+ *
+ *     !!!c
+ *     mrb_value example_method(mrb_state* mrb, mrb_value self)
+ *     {
+ *          puts("Executing example command!");
+ *          return self;
+ *     }
+ *
+ *     void mrb_example_gem_init(mrb_state* mrb)
+ *     {
+ *           mrb_define_method(mrb, mrb->kernel_module, "example_method", example_method, MRB_ARGS_NONE());
+ *     }
+ *
+ * @param [mrb_state *] mrb The MRuby state reference.
+ * @param [struct RClass *] cla The class pointer where the method will be defined.
+ * @param [const char *] name The name of the method being defined.
+ * @param [mrb_func_t] func The function pointer to the method definition.
+ * @param [mrb_aspec] aspec The method parameters declaration.
+ */
+MRB_API void mrb_define_method(mrb_state *mrb, struct RClass *cla, const char *name, mrb_func_t func, mrb_aspec aspec);
+
+/**
+ * Defines a class method.
+ *
+ * Example:
+ *
+ *     # Ruby style
+ *     class Foo
+ *       def Foo.bar
+ *       end
+ *     end
+ *     // C style
+ *     mrb_value bar_method(mrb_state* mrb, mrb_value self){
+ *       return mrb_nil_value();
+ *     }
+ *     void mrb_example_gem_init(mrb_state* mrb){
+ *       struct RClass *foo;
+ *       foo = mrb_define_class(mrb, "Foo", mrb->object_class);
+ *       mrb_define_class_method(mrb, foo, "bar", bar_method, MRB_ARGS_NONE());
+ *     }
+ * @param [mrb_state *] mrb_state* The MRuby state reference.
+ * @param [struct RClass *] RClass* The class where the class method will be defined.
+ * @param [const char *] char* The name of the class method being defined.
+ * @param [mrb_func_t] mrb_func_t The function pointer to the class method definition.
+ * @param [mrb_aspec] mrb_aspec The method parameters declaration.
+ */
+MRB_API void mrb_define_class_method(mrb_state *, struct RClass *, const char *, mrb_func_t, mrb_aspec);
+MRB_API void mrb_define_singleton_method(mrb_state*, struct RObject*, const char*, mrb_func_t, mrb_aspec);
+
+/**
+ *  Defines a module fuction.
+ *
+ * Example:
+ *
+ *        # Ruby style
+ *        module Foo
+ *          def Foo.bar
+ *          end
+ *        end
+ *        // C style
+ *        mrb_value bar_method(mrb_state* mrb, mrb_value self){
+ *          return mrb_nil_value();
+ *        }
+ *        void mrb_example_gem_init(mrb_state* mrb){
+ *          struct RClass *foo;
+ *          foo = mrb_define_module(mrb, "Foo");
+ *          mrb_define_module_function(mrb, foo, "bar", bar_method, MRB_ARGS_NONE());
+ *        }
+ *  @param [mrb_state *] mrb_state* The MRuby state reference.
+ *  @param [struct RClass *] RClass* The module where the module function will be defined.
+ *  @param [const char *] char* The name of the module function being defined.
+ *  @param [mrb_func_t] mrb_func_t The function pointer to the module function definition.
+ *  @param [mrb_aspec] mrb_aspec The method parameters declaration.
+ */
+MRB_API void mrb_define_module_function(mrb_state*, struct RClass*, const char*, mrb_func_t, mrb_aspec);
+
+/**
+ *  Defines a constant.
+ *
+ * Example:
+ *
+ *          # Ruby style
+ *          class ExampleClass
+ *            AGE = 22
+ *          end
+ *          // C style
+ *          #include <stdio.h>
+ *          #include <mruby.h>
+ *
+ *          void
+ *          mrb_example_gem_init(mrb_state* mrb){
+ *            mrb_define_const(mrb, mrb->kernel_module, "AGE", mrb_fixnum_value(22));
+ *          }
+ *
+ *          mrb_value
+ *          mrb_example_gem_final(mrb_state* mrb){
+ *          }
+ *  @param [mrb_state *] mrb_state* The MRuby state reference.
+ *  @param [struct RClass *] RClass* A class or module the constant is defined in.
+ *  @param [const char *] name The name of the constant being defined.
+ *  @param [mrb_value] mrb_value The value for the constant.
+ */
+MRB_API void mrb_define_const(mrb_state*, struct RClass*, const char *name, mrb_value);
+
+/**
+ * Undefines a method.
+ *
+ * Example:
+ *
+ *     # Ruby style
+ *
+ *     class ExampleClassA
+ *       def example_method
+ *         "example"
+ *       end
+ *     end
+ *     ExampleClassA.new.example_method # => example
+ *
+ *     class ExampleClassB < ExampleClassA
+ *       undef_method :example_method
+ *     end
+ *
+ *     ExampleClassB.new.example_method # => undefined method 'example_method' for ExampleClassB (NoMethodError)
+ *
+ *     // C style
+ *     #include <stdio.h>
+ *     #include <mruby.h>
+ *
+ *     mrb_value
+ *     mrb_example_method(mrb_state *mrb){
+ *       return mrb_str_new_lit(mrb, "example");
+ *     }
+ *
+ *     void
+ *     mrb_example_gem_init(mrb_state* mrb){
+ *       struct RClass *example_class_a;
+ *       struct RClass *example_class_b;
+ *       struct RClass *example_class_c;
+ *
+ *       example_class_a = mrb_define_class(mrb, "ExampleClassA", mrb->object_class);
+ *       mrb_define_method(mrb, example_class_a, "example_method", mrb_example_method, MRB_ARGS_NONE());
+ *       example_class_b = mrb_define_class(mrb, "ExampleClassB", example_class_a);
+ *       example_class_c = mrb_define_class(mrb, "ExampleClassC", example_class_b);
+ *       mrb_undef_method(mrb, example_class_c, "example_method");
+ *     }
+ *
+ *     mrb_example_gem_final(mrb_state* mrb){
+ *     }
+ * @param [mrb_state*] mrb_state* The mruby state reference.
+ * @param [struct RClass*] RClass* A class the method will be undefined from.
+ * @param [const char*] constchar* The name of the method to be undefined.
+ */
+MRB_API void mrb_undef_method(mrb_state*, struct RClass*, const char*);
+
+/**
+ * Undefine a class method.
+ * Example:
+ *
+ *      # Ruby style
+ *      class ExampleClass
+ *        def self.example_method
+ *          "example"
+ *        end
+ *      end
+ *
+ *     ExampleClass.example_method
+ *
+ *     // C style
+ *     #include <stdio.h>
+ *     #include <mruby.h>
+ *
+ *     mrb_value
+ *     mrb_example_method(mrb_state *mrb){
+ *       return mrb_str_new_lit(mrb, "example");
+ *     }
+ *
+ *     void
+ *     mrb_example_gem_init(mrb_state* mrb){
+ *       struct RClass *example_class;
+ *       example_class = mrb_define_class(mrb, "ExampleClass", mrb->object_class);
+ *       mrb_define_class_method(mrb, example_class, "example_method", mrb_example_method, MRB_ARGS_NONE());
+ *       mrb_undef_class_method(mrb, example_class, "example_method");
+ *      }
+ *
+ *      void
+ *      mrb_example_gem_final(mrb_state* mrb){
+ *      }
+ * @param [mrb_state*] mrb_state* The mruby state reference.
+ * @param [RClass*] RClass* A class the class method will be undefined from.
+ * @param [constchar*] constchar* The name of the class method to be undefined.
+ */
+MRB_API void mrb_undef_class_method(mrb_state*, struct RClass*, const char*);
+
+/**
+ * Initialize a new object instace of c class.
+ *
+ * Example:
+ *
+ *     # Ruby style
+ *     class ExampleClass
+ *     end
+ *
+ *     p ExampleClass # => #<ExampleClass:0x9958588>
+ *     // C style
+ *     #include <stdio.h>
+ *     #include <mruby.h>
+ *
+ *     void
+ *     mrb_example_gem_init(mrb_state* mrb) {
+ *       struct RClass *example_class;
+ *       mrb_value obj;
+ *       example_class = mrb_define_class(mrb, "ExampleClass", mrb->object_class); # => class ExampleClass; end
+ *       obj = mrb_obj_new(mrb, example_class, 0, NULL); # => ExampleClass.new
+ *       mrb_p(mrb, obj); // => Kernel#p
+ *      }
+ * @param [mrb_state*] mrb The current mruby state.
+ * @param [RClass*] c Reference to the class of the new object.
+ * @param [mrb_int] argc Number of arguments in argv
+ * @param [const mrb_value *] argv Array of mrb_value to initialize the object
+ * @return [mrb_value] The newly initialized object
+ */
+MRB_API mrb_value mrb_obj_new(mrb_state *mrb, struct RClass *c, mrb_int argc, const mrb_value *argv);
+
+/** @see mrb_obj_new */
+MRB_INLINE mrb_value mrb_class_new_instance(mrb_state *mrb, mrb_int argc, const mrb_value *argv, struct RClass *c)
+{
+  return mrb_obj_new(mrb,c,argc,argv);
+}
+
+MRB_API mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv);
+
+/**
+ * Creates a new instance of Class, Class.
+ *
+ * Example:
+ *
+ *      void
+ *      mrb_example_gem_init(mrb_state* mrb) {
+ *        struct RClass *example_class;
+ *
+ *        mrb_value obj;
+ *        example_class = mrb_class_new(mrb, mrb->object_class);
+ *        obj = mrb_obj_new(mrb, example_class, 0, NULL); // => #<#<Class:0x9a945b8>:0x9a94588>
+ *        mrb_p(mrb, obj); // => Kernel#p
+ *       }
+ *
+ * @param [mrb_state*] mrb The current mruby state.
+ * @param [struct RClass *] super The super class or parent.
+ * @return [struct RClass *] Reference to the new class.
+ */
+MRB_API struct RClass * mrb_class_new(mrb_state *mrb, struct RClass *super);
+
+/**
+ * Creates a new module, Module.
+ *
+ * Example:
+ *      void
+ *      mrb_example_gem_init(mrb_state* mrb) {
+ *        struct RClass *example_module;
+ *
+ *        example_module = mrb_module_new(mrb);
+ *      }
+ *
+ * @param [mrb_state*] mrb The current mruby state.
+ * @return [struct RClass *] Reference to the new module.
+ */
+MRB_API struct RClass * mrb_module_new(mrb_state *mrb);
+
+/**
+ * Returns an mrb_bool. True if class was defined, and false if the class was not defined.
+ *
+ * Example:
+ *     void
+ *     mrb_example_gem_init(mrb_state* mrb) {
+ *       struct RClass *example_class;
+ *       mrb_bool cd;
+ *
+ *       example_class = mrb_define_class(mrb, "ExampleClass", mrb->object_class);
+ *       cd = mrb_class_defined(mrb, "ExampleClass");
+ *
+ *       // If mrb_class_defined returns 1 then puts "True"
+ *       // If mrb_class_defined returns 0 then puts "False"
+ *       if (cd == 1){
+ *         puts("True");
+ *       }
+ *       else {
+ *         puts("False");
+ *       }
+ *      }
+ *
+ * @param [mrb_state*] mrb The current mruby state.
+ * @param [const char *] name A string representing the name of the class.
+ * @return [mrb_bool] A boolean value.
+ */
+MRB_API mrb_bool mrb_class_defined(mrb_state *mrb, const char *name);
+
+/**
+ * Gets a class.
+ * @param [mrb_state*] mrb The current mruby state.
+ * @param [const char *] name The name of the class.
+ * @return [struct RClass *] A reference to the class.
+*/
+MRB_API struct RClass * mrb_class_get(mrb_state *mrb, const char *name);
+
+/**
+ * Gets a exception class.
+ * @param [mrb_state*] mrb The current mruby state.
+ * @param [const char *] name The name of the class.
+ * @return [struct RClass *] A reference to the class.
+*/
+MRB_API struct RClass * mrb_exc_get(mrb_state *mrb, const char *name);
+
+/**
+ * Returns an mrb_bool. True if inner class was defined, and false if the inner class was not defined.
+ *
+ * Example:
+ *     void
+ *     mrb_example_gem_init(mrb_state* mrb) {
+ *       struct RClass *example_outer, *example_inner;
+ *       mrb_bool cd;
+ *
+ *       example_outer = mrb_define_module(mrb, "ExampleOuter");
+ *
+ *       example_inner = mrb_define_class_under(mrb, example_outer, "ExampleInner", mrb->object_class);
+ *       cd = mrb_class_defined_under(mrb, example_outer, "ExampleInner");
+ *
+ *       // If mrb_class_defined_under returns 1 then puts "True"
+ *       // If mrb_class_defined_under returns 0 then puts "False"
+ *       if (cd == 1){
+ *         puts("True");
+ *       }
+ *       else {
+ *         puts("False");
+ *       }
+ *      }
+ *
+ * @param [mrb_state*] mrb The current mruby state.
+ * @param [struct RClass *] outer The name of the outer class.
+ * @param [const char *] name A string representing the name of the inner class.
+ * @return [mrb_bool] A boolean value.
+ */
+MRB_API mrb_bool mrb_class_defined_under(mrb_state *mrb, struct RClass *outer, const char *name);
+
+/**
+ * Gets a child class.
+ * @param [mrb_state*] mrb The current mruby state.
+ * @param [struct RClass *] outer The name of the parent class.
+ * @param [const char *] name The name of the class.
+ * @return [struct RClass *] A reference to the class.
+*/
+MRB_API struct RClass * mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name);
+
+/**
+ * Gets a module.
+ * @param [mrb_state*] mrb The current mruby state.
+ * @param [const char *] name The name of the module.
+ * @return [struct RClass *] A reference to the module.
+*/
+MRB_API struct RClass * mrb_module_get(mrb_state *mrb, const char *name);
+
+/**
+ * Gets a module defined under another module.
+ * @param [mrb_state*] mrb The current mruby state.
+ * @param [struct RClass *] outer The name of the outer module.
+ * @param [const char *] name The name of the module.
+ * @return [struct RClass *] A reference to the module.
+*/
+MRB_API struct RClass * mrb_module_get_under(mrb_state *mrb, struct RClass *outer, const char *name);
+MRB_API mrb_value mrb_notimplement_m(mrb_state*, mrb_value);
+
+/**
+ * Duplicate an object.
+ *
+ * Equivalent to:
+ *   Object#dup
+ * @param [mrb_state*] mrb The current mruby state.
+ * @param [mrb_value] obj Object to be duplicate.
+ * @return [mrb_value] The newly duplicated object.
+ */
+MRB_API mrb_value mrb_obj_dup(mrb_state *mrb, mrb_value obj);
+MRB_API mrb_value mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char *method);
+
+/**
+ * Returns true if obj responds to the given method. If the method was defined for that
+ * class it returns true, it returns false otherwise.
+ *
+ *      Example:
+ *      # Ruby style
+ *      class ExampleClass
+ *        def example_method
+ *        end
+ *      end
+ *
+ *      ExampleClass.new.respond_to?(:example_method) # => true
+ *
+ *      // C style
+ *      void
+ *      mrb_example_gem_init(mrb_state* mrb) {
+ *        struct RClass *example_class;
+ *        mrb_sym mid;
+ *        mrb_bool obj_resp;
+ *
+ *        example_class = mrb_define_class(mrb, "ExampleClass", mrb->object_class);
+ *        mrb_define_method(mrb, example_class, "example_method", exampleMethod, MRB_ARGS_NONE());
+ *        mid = mrb_intern_str(mrb, mrb_str_new_lit(mrb, "example_method" ));
+ *        obj_resp = mrb_obj_respond_to(mrb, example_class, mid); // => 1(true in Ruby world)
+ *
+ *        // If mrb_obj_respond_to returns 1 then puts "True"
+ *        // If mrb_obj_respond_to returns 0 then puts "False"
+ *        if (obj_resp == 1) {
+ *          puts("True");
+ *        }
+ *        else if (obj_resp == 0) {
+ *          puts("False");
+ *        }
+ *      }
+ *
+ * @param [mrb_state*] mrb The current mruby state.
+ * @param [struct RClass *] c A reference to a class.
+ * @param [mrb_sym] mid A symbol referencing a method id.
+ * @return [mrb_bool] A boolean value.
+ */
+MRB_API mrb_bool mrb_obj_respond_to(mrb_state *mrb, struct RClass* c, mrb_sym mid);
+
+/**
+ * Defines a new class under a given module
+ *
+ * @param [mrb_state*] mrb The current mruby state.
+ * @param [struct RClass *] outer Reference to the module under which the new class will be defined
+ * @param [const char *] name The name of the defined class
+ * @param [struct RClass *] super The new class parent
+ * @return [struct RClass *] Reference to the newly defined class
+ * @see mrb_define_class
+ */
+MRB_API struct RClass * mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super);
+
+MRB_API struct RClass * mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name);
+
+/**
+ * Function requires n arguments.
+ *
+ * @param n
+ *      The number of required arguments.
+ */
+#define MRB_ARGS_REQ(n)     ((mrb_aspec)((n)&0x1f) << 18)
+
+/**
+ * Funtion takes n optional arguments
+ *
+ * @param n
+ *      The number of optional arguments.
+ */
+#define MRB_ARGS_OPT(n)     ((mrb_aspec)((n)&0x1f) << 13)
+
+/**
+ * Funtion takes n1 mandatory arguments and n2 optional arguments
+ *
+ * @param n1
+ *      The number of required arguments.
+ * @param n2
+ *      The number of optional arguments.
+ */
+#define MRB_ARGS_ARG(n1,n2)   (MRB_ARGS_REQ(n1)|MRB_ARGS_OPT(n2))
+
+/** rest argument */
+#define MRB_ARGS_REST()     ((mrb_aspec)(1 << 12))
+
+/** required arguments after rest */
+#define MRB_ARGS_POST(n)    ((mrb_aspec)((n)&0x1f) << 7)
+
+/** keyword arguments (n of keys, kdict) */
+#define MRB_ARGS_KEY(n1,n2) ((mrb_aspec)((((n1)&0x1f) << 2) | ((n2)?(1<<1):0)))
+
+/**
+ * Function takes a block argument
+ */
+#define MRB_ARGS_BLOCK()    ((mrb_aspec)1)
+
+/**
+ * Function accepts any number of arguments
+ */
+#define MRB_ARGS_ANY()      MRB_ARGS_REST()
+
+/**
+ * Function accepts no arguments
+ */
+#define MRB_ARGS_NONE()     ((mrb_aspec)0)
+
+/**
+ * Format specifiers for {mrb_get_args} function
+ *
+ * Must be a C string composed of the following format specifiers:
+ *
+ * | char | Ruby type      | C types           | Notes                                               |
+ * |:----:|----------------|-------------------|----------------------------------------------------|
+ * | `o`  | {Object}       | {mrb_value}       | Could be used to retrieve any type of argument     |
+ * | `C`  | {Class}/{Module} | {mrb_value}     |                                                    |
+ * | `S`  | {String}       | {mrb_value}       | when `!` follows, the value may be `nil`           |
+ * | `A`  | {Array}        | {mrb_value}       | when `!` follows, the value may be `nil`           |
+ * | `H`  | {Hash}         | {mrb_value}       | when `!` follows, the value may be `nil`           |
+ * | `s`  | {String}       | char *, {mrb_int} |  Receive two arguments; `s!` gives (`NULL`,`0`) for `nil`       |
+ * | `z`  | {String}       | char *            | `NULL` terminated string; `z!` gives `NULL` for `nil`           |
+ * | `a`  | {Array}        | {mrb_value} *, {mrb_int} | Receive two arguments; `a!` gives (`NULL`,`0`) for `nil` |
+ * | `f`  | {Float}        | {mrb_float}       |                                                    |
+ * | `i`  | {Integer}      | {mrb_int}         |                                                    |
+ * | `b`  | boolean        | {mrb_bool}        |                                                    |
+ * | `n`  | {Symbol}       | {mrb_sym}         |                                                    |
+ * | `&`  | block          | {mrb_value}       |                                                    |
+ * | `*`  | rest arguments | {mrb_value} *, {mrb_int} | Receive the rest of arguments as an array.  |
+ * | &vert; | optional     |                   | After this spec following specs would be optional. |
+ * | `?`  | optional given | {mrb_bool}        | `TRUE` if preceding argument is given. Used to check optional argument is given. |
+ *
+ * @see mrb_get_args
+ */
+typedef const char *mrb_args_format;
+
+/**
+ * Retrieve arguments from mrb_state.
+ *
+ * When applicable, implicit conversions (such as `to_str`, `to_ary`, `to_hash`) are
+ * applied to received arguments.
+ * Used inside a function of mrb_func_t type.
+ *
+ * @param mrb The current MRuby state.
+ * @param format [mrb_args_format] is a list of format specifiers
+ * @param ... The passing variadic arguments must be a pointer of retrieving type.
+ * @return the number of arguments retrieved.
+ * @see mrb_args_format
+ */
+MRB_API mrb_int mrb_get_args(mrb_state *mrb, mrb_args_format format, ...);
+
+static inline mrb_sym
+mrb_get_mid(mrb_state *mrb) /* get method symbol */
+{
+  return mrb->c->ci->mid;
+}
+
+static inline int
+mrb_get_argc(mrb_state *mrb) /* get argc */
+{
+  return mrb->c->ci->argc;
+}
+
+/* `strlen` for character string literals (use with caution or `strlen` instead)
+    Adjacent string literals are concatenated in C/C++ in translation phase 6.
+    If `lit` is not one, the compiler will report a syntax error:
+     MSVC: "error C2143: syntax error : missing ')' before 'string'"
+     GCC:  "error: expected ')' before string constant"
+*/
+#define mrb_strlen_lit(lit) (sizeof(lit "") - 1)
+
+/**
+ * Call existing ruby functions.
+ *
+ *      #include <stdio.h>
+ *      #include <mruby.h>
+ *      #include "mruby/compile.h"
+ *
+ *      int
+ *      main()
+ *      {
+ *        mrb_int i = 99;
+ *        mrb_state *mrb = mrb_open();
+ *
+ *        if (!mrb) { }
+ *        FILE *fp = fopen("test.rb","r");
+ *        mrb_value obj = mrb_load_file(mrb,fp);
+ *        mrb_funcall(mrb, obj, "method_name", 1, mrb_fixnum_value(i));
+ *        fclose(fp);
+ *        mrb_close(mrb);
+ *       }
+ * @param [mrb_state*] mrb_state* The current mruby state.
+ * @param [mrb_value] mrb_value A reference to an mruby value.
+ * @param [const char*] const char* The name of the method.
+ * @param [mrb_int] mrb_int The number of arguments the method has.
+ * @param [...] ... Variadic values(not type safe!).
+ * @return [mrb_value] mrb_value mruby function value.
+ */
+MRB_API mrb_value mrb_funcall(mrb_state*, mrb_value, const char*, mrb_int,...);
+/**
+ * Call existing ruby functions. This is basically the type safe version of mrb_funcall.
+ *
+ *      #include <stdio.h>
+ *      #include <mruby.h>
+ *      #include "mruby/compile.h"
+ *      int
+ *      main()
+ *      {
+ *        mrb_int i = 99;
+ *        mrb_state *mrb = mrb_open();
+ *
+ *        if (!mrb) { }
+ *        mrb_sym m_sym = mrb_intern_lit(mrb, "method_name"); // Symbol for method.
+ *
+ *        FILE *fp = fopen("test.rb","r");
+ *        mrb_value obj = mrb_load_file(mrb,fp);
+ *        mrb_funcall_argv(mrb, obj, m_sym, 1, &obj); // Calling ruby function from test.rb.
+ *        fclose(fp);
+ *        mrb_close(mrb);
+ *       }
+ * @param [mrb_state*] mrb_state* The current mruby state.
+ * @param [mrb_value] mrb_value A reference to an mruby value.
+ * @param [mrb_sym] mrb_sym The symbol representing the method.
+ * @param [mrb_int] mrb_int The number of arguments the method has.
+ * @param [const mrb_value*] mrb_value* Pointer to the object.
+ * @return [mrb_value] mrb_value mruby function value.
+ * @see mrb_funcall
+ */
+MRB_API mrb_value mrb_funcall_argv(mrb_state*, mrb_value, mrb_sym, mrb_int, const mrb_value*);
+/**
+ * Call existing ruby functions with a block.
+ */
+MRB_API mrb_value mrb_funcall_with_block(mrb_state*, mrb_value, mrb_sym, mrb_int, const mrb_value*, mrb_value);
+/**
+ * Create a symbol
+ *
+ *     # Ruby style:
+ *     :pizza # => :pizza
+ *
+ *     // C style:
+ *     mrb_sym m_sym = mrb_intern_lit(mrb, "pizza"); //  => :pizza
+ * @param [mrb_state*] mrb_state* The current mruby state.
+ * @param [const char*] const char* The name of the method.
+ * @return [mrb_sym] mrb_sym A symbol.
+ */
+MRB_API mrb_sym mrb_intern_cstr(mrb_state*,const char*);
+MRB_API mrb_sym mrb_intern(mrb_state*,const char*,size_t);
+MRB_API mrb_sym mrb_intern_static(mrb_state*,const char*,size_t);
+#define mrb_intern_lit(mrb, lit) mrb_intern_static(mrb, lit, mrb_strlen_lit(lit))
+MRB_API mrb_sym mrb_intern_str(mrb_state*,mrb_value);
+MRB_API mrb_value mrb_check_intern_cstr(mrb_state*,const char*);
+MRB_API mrb_value mrb_check_intern(mrb_state*,const char*,size_t);
+MRB_API mrb_value mrb_check_intern_str(mrb_state*,mrb_value);
+MRB_API const char *mrb_sym2name(mrb_state*,mrb_sym);
+MRB_API const char *mrb_sym2name_len(mrb_state*,mrb_sym,mrb_int*);
+MRB_API mrb_value mrb_sym2str(mrb_state*,mrb_sym);
+
+MRB_API void *mrb_malloc(mrb_state*, size_t);         /* raise RuntimeError if no mem */
+MRB_API void *mrb_calloc(mrb_state*, size_t, size_t); /* ditto */
+MRB_API void *mrb_realloc(mrb_state*, void*, size_t); /* ditto */
+MRB_API void *mrb_realloc_simple(mrb_state*, void*, size_t); /* return NULL if no memory available */
+MRB_API void *mrb_malloc_simple(mrb_state*, size_t);  /* return NULL if no memory available */
+MRB_API struct RBasic *mrb_obj_alloc(mrb_state*, enum mrb_vtype, struct RClass*);
+MRB_API void mrb_free(mrb_state*, void*);
+
+MRB_API mrb_value mrb_str_new(mrb_state *mrb, const char *p, size_t len);
+
+/**
+ * Turns a C string into a Ruby string value.
+ */
+MRB_API mrb_value mrb_str_new_cstr(mrb_state*, const char*);
+MRB_API mrb_value mrb_str_new_static(mrb_state *mrb, const char *p, size_t len);
+#define mrb_str_new_lit(mrb, lit) mrb_str_new_static(mrb, (lit), mrb_strlen_lit(lit))
+
+#ifdef _WIN32
+char* mrb_utf8_from_locale(const char *p, size_t len);
+char* mrb_locale_from_utf8(const char *p, size_t len);
+#define mrb_locale_free(p) free(p)
+#define mrb_utf8_free(p) free(p)
+#else
+#define mrb_utf8_from_locale(p, l) (p)
+#define mrb_locale_from_utf8(p, l) (p)
+#define mrb_locale_free(p)
+#define mrb_utf8_free(p)
+#endif
+
+/**
+ * Creates new mrb_state.
+ *
+ * @return
+ *      Pointer to the newly created mrb_state.
+ */
+MRB_API mrb_state* mrb_open(void);
+
+/**
+ * Create new mrb_state with custom allocators.
+ *
+ * @param f
+ *      Reference to the allocation function.
+ * @param ud
+ *      User data will be passed to custom allocator f.
+ *      If user data isn't required just pass NULL.
+ * @return
+ *      Pointer to the newly created mrb_state.
+ */
+MRB_API mrb_state* mrb_open_allocf(mrb_allocf f, void *ud, mrb_bool disable_gems);
+
+/**
+ * Create new mrb_state with just the MRuby core
+ *
+ * @param f
+ *      Reference to the allocation function.
+ *      Use mrb_default_allocf for the default
+ * @param ud
+ *      User data will be passed to custom allocator f.
+ *      If user data isn't required just pass NULL.
+ * @return
+ *      Pointer to the newly created mrb_state.
+ */
+MRB_API mrb_state* mrb_open_core(mrb_allocf f, void *ud);
+
+/**
+ * Closes and frees a mrb_state.
+ *
+ * @param mrb
+ *      Pointer to the mrb_state to be closed.
+ */
+MRB_API void mrb_close(mrb_state *mrb);
+
+/**
+ * The default allocation function.
+ *
+ * @see mrb_allocf
+ */
+MRB_API void* mrb_default_allocf(mrb_state*, void*, size_t, void*);
+
+MRB_API mrb_value mrb_top_self(mrb_state *);
+MRB_API mrb_value mrb_run(mrb_state*, struct RProc*, mrb_value);
+MRB_API mrb_value mrb_top_run(mrb_state*, struct RProc*, mrb_value, unsigned int);
+MRB_API mrb_value mrb_vm_run(mrb_state*, struct RProc*, mrb_value, unsigned int);
+MRB_API mrb_value mrb_vm_exec(mrb_state*, struct RProc*, mrb_code*);
+/* compatibility macros */
+#define mrb_toplevel_run_keep(m,p,k) mrb_top_run((m),(p),mrb_top_self(m),(k))
+#define mrb_toplevel_run(m,p) mrb_toplevel_run_keep((m),(p),0)
+#define mrb_context_run(m,p,s,k) mrb_vm_run((m),(p),(s),(k))
+
+MRB_API void mrb_p(mrb_state*, mrb_value);
+MRB_API mrb_int mrb_obj_id(mrb_value obj);
+MRB_API mrb_sym mrb_obj_to_sym(mrb_state *mrb, mrb_value name);
+
+MRB_API mrb_bool mrb_obj_eq(mrb_state*, mrb_value, mrb_value);
+MRB_API mrb_bool mrb_obj_equal(mrb_state*, mrb_value, mrb_value);
+MRB_API mrb_bool mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
+MRB_API mrb_value mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base);
+MRB_API mrb_value mrb_Integer(mrb_state *mrb, mrb_value val);
+MRB_API mrb_value mrb_Float(mrb_state *mrb, mrb_value val);
+MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj);
+MRB_API mrb_bool mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
+
+MRB_API void mrb_garbage_collect(mrb_state*);
+MRB_API void mrb_full_gc(mrb_state*);
+MRB_API void mrb_incremental_gc(mrb_state *);
+MRB_API int mrb_gc_arena_save(mrb_state*);
+MRB_API void mrb_gc_arena_restore(mrb_state*,int);
+MRB_API void mrb_gc_mark(mrb_state*,struct RBasic*);
+#define mrb_gc_mark_value(mrb,val) do {\
+  if (!mrb_immediate_p(val)) mrb_gc_mark((mrb), mrb_basic_ptr(val)); \
+} while (0)
+MRB_API void mrb_field_write_barrier(mrb_state *, struct RBasic*, struct RBasic*);
+#define mrb_field_write_barrier_value(mrb, obj, val) do{\
+  if (!mrb_immediate_p(val)) mrb_field_write_barrier((mrb), (obj), mrb_basic_ptr(val)); \
+} while (0)
+MRB_API void mrb_write_barrier(mrb_state *, struct RBasic*);
+
+MRB_API mrb_value mrb_check_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method);
+MRB_API mrb_value mrb_any_to_s(mrb_state *mrb, mrb_value obj);
+MRB_API const char * mrb_obj_classname(mrb_state *mrb, mrb_value obj);
+MRB_API struct RClass* mrb_obj_class(mrb_state *mrb, mrb_value obj);
+MRB_API mrb_value mrb_class_path(mrb_state *mrb, struct RClass *c);
+MRB_API mrb_value mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method);
+MRB_API mrb_bool mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c);
+MRB_API mrb_value mrb_obj_inspect(mrb_state *mrb, mrb_value self);
+MRB_API mrb_value mrb_obj_clone(mrb_state *mrb, mrb_value self);
+
+#ifndef ISPRINT
+#define ISASCII(c) ((unsigned)(c) <= 0x7f)
+#define ISPRINT(c) (((unsigned)(c) - 0x20) < 0x5f)
+#define ISSPACE(c) ((c) == ' ' || (unsigned)(c) - '\t' < 5)
+#define ISUPPER(c) (((unsigned)(c) - 'A') < 26)
+#define ISLOWER(c) (((unsigned)(c) - 'a') < 26)
+#define ISALPHA(c) ((((unsigned)(c) | 0x20) - 'a') < 26)
+#define ISDIGIT(c) (((unsigned)(c) - '0') < 10)
+#define ISXDIGIT(c) (ISDIGIT(c) || ((unsigned)(c) | 0x20) - 'a' < 6)
+#define ISALNUM(c) (ISALPHA(c) || ISDIGIT(c))
+#define ISBLANK(c) ((c) == ' ' || (c) == '\t')
+#define ISCNTRL(c) ((unsigned)(c) < 0x20 || (c) == 0x7f)
+#define TOUPPER(c) (ISLOWER(c) ? ((c) & 0x5f) : (c))
+#define TOLOWER(c) (ISUPPER(c) ? ((c) | 0x20) : (c))
+#endif
+
+MRB_API mrb_value mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, size_t len);
+MRB_API mrb_noreturn void mrb_exc_raise(mrb_state *mrb, mrb_value exc);
+
+MRB_API mrb_noreturn void mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg);
+MRB_API mrb_noreturn void mrb_raisef(mrb_state *mrb, struct RClass *c, const char *fmt, ...);
+MRB_API mrb_noreturn void mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...);
+MRB_API void mrb_warn(mrb_state *mrb, const char *fmt, ...);
+MRB_API mrb_noreturn void mrb_bug(mrb_state *mrb, const char *fmt, ...);
+MRB_API void mrb_print_backtrace(mrb_state *mrb);
+MRB_API void mrb_print_error(mrb_state *mrb);
+
+/* macros to get typical exception objects
+   note:
+   + those E_* macros requires mrb_state* variable named mrb.
+   + exception objects obtained from those macros are local to mrb
+*/
+#define E_RUNTIME_ERROR             (mrb_exc_get(mrb, "RuntimeError"))
+#define E_TYPE_ERROR                (mrb_exc_get(mrb, "TypeError"))
+#define E_ARGUMENT_ERROR            (mrb_exc_get(mrb, "ArgumentError"))
+#define E_INDEX_ERROR               (mrb_exc_get(mrb, "IndexError"))
+#define E_RANGE_ERROR               (mrb_exc_get(mrb, "RangeError"))
+#define E_NAME_ERROR                (mrb_exc_get(mrb, "NameError"))
+#define E_NOMETHOD_ERROR            (mrb_exc_get(mrb, "NoMethodError"))
+#define E_SCRIPT_ERROR              (mrb_exc_get(mrb, "ScriptError"))
+#define E_SYNTAX_ERROR              (mrb_exc_get(mrb, "SyntaxError"))
+#define E_LOCALJUMP_ERROR           (mrb_exc_get(mrb, "LocalJumpError"))
+#define E_REGEXP_ERROR              (mrb_exc_get(mrb, "RegexpError"))
+
+#define E_NOTIMP_ERROR              (mrb_exc_get(mrb, "NotImplementedError"))
+#define E_FLOATDOMAIN_ERROR         (mrb_exc_get(mrb, "FloatDomainError"))
+
+#define E_KEY_ERROR                 (mrb_exc_get(mrb, "KeyError"))
+
+MRB_API mrb_value mrb_yield(mrb_state *mrb, mrb_value b, mrb_value arg);
+MRB_API mrb_value mrb_yield_argv(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv);
+MRB_API mrb_value mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv, mrb_value self, struct RClass *c);
+
+/* continue execution to the proc */
+/* this function should always be called as the last function of a method */
+/* e.g. return mrb_yield_cont(mrb, proc, self, argc, argv); */
+mrb_value mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const mrb_value *argv);
+
+/* mrb_gc_protect() leaves the object in the arena */
+MRB_API void mrb_gc_protect(mrb_state *mrb, mrb_value obj);
+/* mrb_gc_register() keeps the object from GC. */
+MRB_API void mrb_gc_register(mrb_state *mrb, mrb_value obj);
+/* mrb_gc_unregister() removes the object from GC root. */
+MRB_API void mrb_gc_unregister(mrb_state *mrb, mrb_value obj);
+
+MRB_API mrb_value mrb_to_int(mrb_state *mrb, mrb_value val);
+#define mrb_int(mrb, val) mrb_fixnum(mrb_to_int(mrb, val))
+MRB_API void mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t);
+
+typedef enum call_type {
+  CALL_PUBLIC,
+  CALL_FCALL,
+  CALL_VCALL,
+  CALL_TYPE_MAX
+} call_type;
+
+MRB_API void mrb_define_alias(mrb_state *mrb, struct RClass *klass, const char *name1, const char *name2);
+MRB_API const char *mrb_class_name(mrb_state *mrb, struct RClass* klass);
+MRB_API void mrb_define_global_const(mrb_state *mrb, const char *name, mrb_value val);
+
+MRB_API mrb_value mrb_attr_get(mrb_state *mrb, mrb_value obj, mrb_sym id);
+
+MRB_API mrb_bool mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid);
+MRB_API mrb_bool mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c);
+MRB_API mrb_bool mrb_func_basic_p(mrb_state *mrb, mrb_value obj, mrb_sym mid, mrb_func_t func);
+
+
+/*
+ * Resume a Fiber
+ *
+ * @mrbgem mruby-fiber
+ */
+MRB_API mrb_value mrb_fiber_resume(mrb_state *mrb, mrb_value fib, mrb_int argc, const mrb_value *argv);
+
+/*
+ * Yield a Fiber
+ *
+ * @mrbgem mruby-fiber
+ */
+MRB_API mrb_value mrb_fiber_yield(mrb_state *mrb, mrb_int argc, const mrb_value *argv);
+
+/*
+ * FiberError reference
+ *
+ * @mrbgem mruby-fiber
+ */
+#define E_FIBER_ERROR (mrb_exc_get(mrb, "FiberError"))
+
+/* memory pool implementation */
+typedef struct mrb_pool mrb_pool;
+MRB_API struct mrb_pool* mrb_pool_open(mrb_state*);
+MRB_API void mrb_pool_close(struct mrb_pool*);
+MRB_API void* mrb_pool_alloc(struct mrb_pool*, size_t);
+MRB_API void* mrb_pool_realloc(struct mrb_pool*, void*, size_t oldlen, size_t newlen);
+MRB_API mrb_bool mrb_pool_can_realloc(struct mrb_pool*, void*, size_t);
+MRB_API void* mrb_alloca(mrb_state *mrb, size_t);
+
+MRB_API void mrb_state_atexit(mrb_state *mrb, mrb_atexit_func func);
+
+MRB_API void mrb_show_version(mrb_state *mrb);
+MRB_API void mrb_show_copyright(mrb_state *mrb);
+
+MRB_API mrb_value mrb_format(mrb_state *mrb, const char *format, ...);
+
+#if 0
+/* memcpy and memset does not work with gdb reverse-next on my box */
+/* use naive memcpy and memset instead */
+#undef memcpy
+#undef memset
+static inline void*
+mrbmemcpy(void *dst, const void *src, size_t n)
+{
+  char *d = dst;
+  const char *s = src;
+  while (n--)
+    *d++ = *s++;
+  return d;
+}
+#define memcpy(a,b,c) mrbmemcpy(a,b,c)
+
+static inline void*
+mrbmemset(void *s, int c, size_t n)
+{
+  char *t = s;
+  while (n--)
+    *t++ = c;
+  return s;
+}
+#define memset(a,b,c) mrbmemset(a,b,c)
+#endif
+
+MRB_END_DECL
+
+#endif  /* MRUBY_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/array.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/array.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/array.h	(revision 331)
@@ -0,0 +1,261 @@
+/*
+** mruby/array.h - Array class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_ARRAY_H
+#define MRUBY_ARRAY_H
+
+#include "common.h"
+
+/*
+ * Array class
+ */
+MRB_BEGIN_DECL
+
+
+typedef struct mrb_shared_array {
+  int refcnt;
+  mrb_int len;
+  mrb_value *ptr;
+} mrb_shared_array;
+
+struct RArray {
+  MRB_OBJECT_HEADER;
+  mrb_int len;
+  union {
+    mrb_int capa;
+    mrb_shared_array *shared;
+  } aux;
+  mrb_value *ptr;
+};
+
+#define mrb_ary_ptr(v)    ((struct RArray*)(mrb_ptr(v)))
+#define mrb_ary_value(p)  mrb_obj_value((void*)(p))
+#define RARRAY(v)  ((struct RArray*)(mrb_ptr(v)))
+
+#define RARRAY_LEN(a) (RARRAY(a)->len)
+#define RARRAY_PTR(a) ((const mrb_value*)RARRAY(a)->ptr)
+#define MRB_ARY_SHARED      256
+#define ARY_SHARED_P(a) ((a)->flags & MRB_ARY_SHARED)
+#define ARY_SET_SHARED_FLAG(a) ((a)->flags |= MRB_ARY_SHARED)
+#define ARY_UNSET_SHARED_FLAG(a) ((a)->flags &= ~MRB_ARY_SHARED)
+
+void mrb_ary_decref(mrb_state*, mrb_shared_array*);
+MRB_API void mrb_ary_modify(mrb_state*, struct RArray*);
+MRB_API mrb_value mrb_ary_new_capa(mrb_state*, mrb_int);
+
+/*
+ * Initializes a new array.
+ *
+ * Equivalent to:
+ *
+ *      Array.new
+ *
+ * @param mrb The mruby state reference.
+ * @return The initialized array.
+ */
+MRB_API mrb_value mrb_ary_new(mrb_state *mrb);
+
+/*
+ * Initializes a new array with initial values
+ *
+ * Equivalent to:
+ *
+ *      Array[value1, value2, ...]
+ *
+ * @param mrb The mruby state reference.
+ * @param size The numer of values.
+ * @param vals The actual values.
+ * @return The initialized array.
+ */
+MRB_API mrb_value mrb_ary_new_from_values(mrb_state *mrb, mrb_int size, const mrb_value *vals);
+
+/*
+ * Initializes a new array with two initial values
+ *
+ * Equivalent to:
+ *
+ *      Array[car, cdr]
+ *
+ * @param mrb The mruby state reference.
+ * @param car The first value.
+ * @param cdr The second value.
+ * @return The initialized array.
+ */
+MRB_API mrb_value mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr);
+
+/*
+ * Concatenate two arrays. The target array will be modified
+ *
+ * Equivalent to:
+ *      ary.concat(other)
+ *
+ * @param mrb The mruby state reference.
+ * @param self The target array.
+ * @param other The array that will be concatenated to self.
+ */
+MRB_API void mrb_ary_concat(mrb_state *mrb, mrb_value self, mrb_value other);
+
+/*
+ * Create an array from the input. It tries calling to_a on the
+ * value. If value does not respond to that, it creates a new
+ * array with just this value.
+ *
+ * @param mrb The mruby state reference.
+ * @param value The value to change into an array.
+ * @return An array representation of value.
+ */
+MRB_API mrb_value mrb_ary_splat(mrb_state *mrb, mrb_value value);
+
+/*
+ * Pushes value into array.
+ *
+ * Equivalent to:
+ *
+ *      ary << value
+ *
+ * @param mrb The mruby state reference.
+ * @param ary The array in which the value will be pushed
+ * @param value The value to be pushed into array
+ */
+MRB_API void mrb_ary_push(mrb_state *mrb, mrb_value array, mrb_value value);
+
+/*
+ * Pops the last element from the array.
+ *
+ * Equivalent to:
+ *
+ *      ary.pop
+ *
+ * @param mrb The mruby state reference.
+ * @param ary The array from which the value will be popped.
+ * @return The popped value.
+ */
+MRB_API mrb_value mrb_ary_pop(mrb_state *mrb, mrb_value ary);
+
+/*
+ * Returns a reference to an element of the array on the given index.
+ *
+ * Equivalent to:
+ *
+ *      ary[n]
+ *
+ * @param mrb The mruby state reference.
+ * @param ary The target array.
+ * @param n The array index being referenced
+ * @return The referenced value.
+ */
+MRB_API mrb_value mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n);
+
+/*
+ * Sets a value on an array at the given index
+ *
+ * Equivalent to:
+ *
+ *      ary[n] = val
+ *
+ * @param mrb The mruby state reference.
+ * @param ary The target array.
+ * @param n The array index being referenced.
+ * @param val The value being setted.
+ */
+MRB_API void mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val);
+
+/*
+ * Replace the array with another array
+ *
+ * Equivalent to:
+ *
+ *      ary.replace(other)
+ *
+ * @param mrb The mruby state reference
+ * @param self The target array.
+ * @param other The array to replace it with.
+ */
+MRB_API void mrb_ary_replace(mrb_state *mrb, mrb_value self, mrb_value other);
+MRB_API mrb_value mrb_check_array_type(mrb_state *mrb, mrb_value self);
+
+/*
+ * Unshift an element into an array
+ *
+ * Equivalent to:
+ *
+ *     ary.unshift(item)
+ *
+ * @param mrb The mruby state reference.
+ * @param self The target array.
+ * @param item The item to unshift.
+ */
+MRB_API mrb_value mrb_ary_unshift(mrb_state *mrb, mrb_value self, mrb_value item);
+MRB_API mrb_value mrb_ary_entry(mrb_value ary, mrb_int offset);
+
+/*
+ * Shifts the first element from the array.
+ *
+ * Equivalent to:
+ *
+ *      ary.shift
+ *
+ * @param mrb The mruby state reference.
+ * @param self The array from which the value will be shifted.
+ * @return The shifted value.
+ */
+MRB_API mrb_value mrb_ary_shift(mrb_state *mrb, mrb_value self);
+
+/*
+ * Removes all elements from this array
+ *
+ * Equivalent to:
+ *
+ *      ary.clear
+ *
+ * @param mrb The mruby state reference.
+ * @param self The target array.
+ * @return self
+ */
+MRB_API mrb_value mrb_ary_clear(mrb_state *mrb, mrb_value self);
+
+/*
+ * Join the array elements together in a string
+ *
+ * Equivalent to:
+ *
+ *      ary.join(sep="")
+ *
+ * @param mrb The mruby state reference.
+ * @param ary The target array
+ * @param sep The separater, can be NULL
+ */
+MRB_API mrb_value mrb_ary_join(mrb_state *mrb, mrb_value ary, mrb_value sep);
+
+/*
+ * Update the capacity of the array
+ *
+ * @param mrb The mruby state reference.
+ * @param ary The target array.
+ * @param new_len The new capacity of the array
+ */
+MRB_API mrb_value mrb_ary_resize(mrb_state *mrb, mrb_value ary, mrb_int new_len);
+
+static inline mrb_int
+mrb_ary_len(mrb_state *mrb, mrb_value ary)
+{
+  (void)mrb;
+  mrb_assert(mrb_array_p(ary));
+  return RARRAY_LEN(ary);
+}
+
+static inline mrb_value
+ary_elt(mrb_value ary, mrb_int offset)
+{
+  if (offset < 0 || RARRAY_LEN(ary) <= offset) {
+    return mrb_nil_value();
+  }
+  return RARRAY_PTR(ary)[offset];
+}
+
+MRB_END_DECL
+
+#endif  /* MRUBY_ARRAY_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/boxing_nan.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/boxing_nan.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/boxing_nan.h	(revision 331)
@@ -0,0 +1,98 @@
+/*
+** mruby/boxing_nan.h - nan boxing mrb_value definition
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_BOXING_NAN_H
+#define MRUBY_BOXING_NAN_H
+
+#ifdef MRB_USE_FLOAT
+# error ---->> MRB_NAN_BOXING and MRB_USE_FLOAT conflict <<----
+#endif
+
+#ifdef MRB_INT64
+# error ---->> MRB_NAN_BOXING and MRB_INT64 conflict <<----
+#endif
+
+#define MRB_FIXNUM_SHIFT 0
+#define MRB_TT_HAS_BASIC MRB_TT_OBJECT
+
+#ifdef MRB_ENDIAN_BIG
+#define MRB_ENDIAN_LOHI(a,b) a b
+#else
+#define MRB_ENDIAN_LOHI(a,b) b a
+#endif
+
+/* value representation by nan-boxing:
+ *   float : FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF
+ *   object: 111111111111TTTT TTPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP PPPPPPPPPPPPPPPP
+ *   int   : 1111111111110001 0000000000000000 IIIIIIIIIIIIIIII IIIIIIIIIIIIIIII
+ *   sym   : 1111111111110001 0100000000000000 SSSSSSSSSSSSSSSS SSSSSSSSSSSSSSSS
+ * In order to get enough bit size to save TT, all pointers are shifted 2 bits
+ * in the right direction. Also, TTTTTT is the mrb_vtype + 1;
+ */
+typedef struct mrb_value {
+  union {
+    mrb_float f;
+    union {
+      void *p;
+      struct {
+        MRB_ENDIAN_LOHI(
+          uint32_t ttt;
+          ,union {
+            mrb_int i;
+            mrb_sym sym;
+          };
+        )
+      };
+    } value;
+  };
+} mrb_value;
+
+#define mrb_float_pool(mrb,f) mrb_float_value(mrb,f)
+
+#define mrb_tt(o)       ((enum mrb_vtype)(((o).value.ttt & 0xfc000)>>14)-1)
+#define mrb_type(o)     (enum mrb_vtype)((uint32_t)0xfff00000 < (o).value.ttt ? mrb_tt(o) : MRB_TT_FLOAT)
+#define mrb_ptr(o)      ((void*)((((uintptr_t)0x3fffffffffff)&((uintptr_t)((o).value.p)))<<2))
+#define mrb_float(o)    (o).f
+#define mrb_cptr(o)     mrb_ptr(o)
+#define mrb_fixnum(o)   (o).value.i
+#define mrb_symbol(o)   (o).value.sym
+
+#ifdef MRB_64BIT
+#define BOXNAN_SHIFT_LONG_POINTER(v) (((uintptr_t)(v)>>34)&0x3fff)
+#else
+#define BOXNAN_SHIFT_LONG_POINTER(v) 0
+#endif
+
+#define BOXNAN_SET_VALUE(o, tt, attr, v) do {\
+  (o).attr = (v);\
+  (o).value.ttt = 0xfff00000 | (((tt)+1)<<14);\
+} while (0)
+
+#define BOXNAN_SET_OBJ_VALUE(o, tt, v) do {\
+  (o).value.p = (void*)((uintptr_t)(v)>>2);\
+  (o).value.ttt = (0xfff00000|(((tt)+1)<<14)|BOXNAN_SHIFT_LONG_POINTER(v));\
+} while (0)
+
+#define SET_FLOAT_VALUE(mrb,r,v) do { \
+  if (v != v) { \
+    (r).value.ttt = 0x7ff80000; \
+    (r).value.i = 0; \
+  } \
+  else { \
+    (r).f = v; \
+  }} while(0)
+
+#define SET_NIL_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, value.i, 0)
+#define SET_FALSE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_FALSE, value.i, 1)
+#define SET_TRUE_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_TRUE, value.i, 1)
+#define SET_BOOL_VALUE(r,b) BOXNAN_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1)
+#define SET_INT_VALUE(r,n) BOXNAN_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
+#define SET_SYM_VALUE(r,v) BOXNAN_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
+#define SET_OBJ_VALUE(r,v) BOXNAN_SET_OBJ_VALUE(r, (((struct RObject*)(v))->tt), (v))
+#define SET_CPTR_VALUE(mrb,r,v) BOXNAN_SET_OBJ_VALUE(r, MRB_TT_CPTR, v)
+#define SET_UNDEF_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0)
+
+#endif  /* MRUBY_BOXING_NAN_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/boxing_no.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/boxing_no.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/boxing_no.h	(revision 331)
@@ -0,0 +1,48 @@
+/*
+** mruby/boxing_no.h - unboxed mrb_value definition
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_BOXING_NO_H
+#define MRUBY_BOXING_NO_H
+
+#define MRB_FIXNUM_SHIFT 0
+#define MRB_TT_HAS_BASIC MRB_TT_OBJECT
+
+typedef struct mrb_value {
+  union {
+    mrb_float f;
+    void *p;
+    mrb_int i;
+    mrb_sym sym;
+  } value;
+  enum mrb_vtype tt;
+} mrb_value;
+
+#define mrb_float_pool(mrb,f) mrb_float_value(mrb,f)
+
+#define mrb_ptr(o)      (o).value.p
+#define mrb_cptr(o)     mrb_ptr(o)
+#define mrb_float(o)    (o).value.f
+#define mrb_fixnum(o)   (o).value.i
+#define mrb_symbol(o)   (o).value.sym
+#define mrb_type(o)     (o).tt
+
+#define BOXNIX_SET_VALUE(o, ttt, attr, v) do {\
+  (o).tt = ttt;\
+  (o).attr = v;\
+} while (0)
+
+#define SET_NIL_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_FALSE, value.i, 0)
+#define SET_FALSE_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_FALSE, value.i, 1)
+#define SET_TRUE_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_TRUE, value.i, 1)
+#define SET_BOOL_VALUE(r,b) BOXNIX_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1)
+#define SET_INT_VALUE(r,n) BOXNIX_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
+#define SET_FLOAT_VALUE(mrb,r,v) BOXNIX_SET_VALUE(r, MRB_TT_FLOAT, value.f, (v))
+#define SET_SYM_VALUE(r,v) BOXNIX_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
+#define SET_OBJ_VALUE(r,v) BOXNIX_SET_VALUE(r, (((struct RObject*)(v))->tt), value.p, (v))
+#define SET_CPTR_VALUE(mrb,r,v) BOXNIX_SET_VALUE(r, MRB_TT_CPTR, value.p, v)
+#define SET_UNDEF_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0)
+
+#endif  /* MRUBY_BOXING_NO_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/boxing_word.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/boxing_word.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/boxing_word.h	(revision 331)
@@ -0,0 +1,120 @@
+/*
+** mruby/boxing_word.h - word boxing mrb_value definition
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_BOXING_WORD_H
+#define MRUBY_BOXING_WORD_H
+
+#if defined(MRB_INT16)
+# error MRB_INT16 is too small for MRB_WORD_BOXING.
+#endif
+
+#if defined(MRB_INT64) && !defined(MRB_64BIT)
+#error MRB_INT64 cannot be used with MRB_WORD_BOXING in 32-bit mode.
+#endif
+
+struct RFloat {
+  MRB_OBJECT_HEADER;
+  mrb_float f;
+};
+
+struct RCptr {
+  MRB_OBJECT_HEADER;
+  void *p;
+};
+
+#define MRB_FIXNUM_SHIFT 1
+#define MRB_TT_HAS_BASIC MRB_TT_FLOAT
+
+enum mrb_special_consts {
+  MRB_Qnil    = 0,
+  MRB_Qfalse  = 2,
+  MRB_Qtrue   = 4,
+  MRB_Qundef  = 6,
+};
+
+#define MRB_FIXNUM_FLAG   0x01
+#define MRB_SYMBOL_FLAG   0x0e
+#define MRB_SPECIAL_SHIFT 8
+
+typedef union mrb_value {
+  union {
+    void *p;
+    struct {
+      unsigned int i_flag : MRB_FIXNUM_SHIFT;
+      mrb_int i : (MRB_INT_BIT - MRB_FIXNUM_SHIFT);
+    };
+    struct {
+      unsigned int sym_flag : MRB_SPECIAL_SHIFT;
+      mrb_sym sym : (sizeof(mrb_sym) * CHAR_BIT);
+    };
+    struct RBasic *bp;
+    struct RFloat *fp;
+    struct RCptr *vp;
+  } value;
+  unsigned long w;
+} mrb_value;
+
+MRB_API mrb_value mrb_word_boxing_cptr_value(struct mrb_state*, void*);
+MRB_API mrb_value mrb_word_boxing_float_value(struct mrb_state*, mrb_float);
+MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float);
+
+#define mrb_float_pool(mrb,f) mrb_word_boxing_float_pool(mrb,f)
+
+#define mrb_ptr(o)     (o).value.p
+#define mrb_cptr(o)    (o).value.vp->p
+#define mrb_float(o)   (o).value.fp->f
+#define mrb_fixnum(o)  ((mrb_int)(o).value.i)
+#define mrb_symbol(o)  (o).value.sym
+
+static inline enum mrb_vtype
+mrb_type(mrb_value o)
+{
+  switch (o.w) {
+  case MRB_Qfalse:
+  case MRB_Qnil:
+    return MRB_TT_FALSE;
+  case MRB_Qtrue:
+    return MRB_TT_TRUE;
+  case MRB_Qundef:
+    return MRB_TT_UNDEF;
+  }
+  if (o.value.i_flag == MRB_FIXNUM_FLAG) {
+    return MRB_TT_FIXNUM;
+  }
+  if (o.value.sym_flag == MRB_SYMBOL_FLAG) {
+    return MRB_TT_SYMBOL;
+  }
+  return o.value.bp->tt;
+}
+
+#define mrb_bool(o)    ((o).w != MRB_Qnil && (o).w != MRB_Qfalse)
+#define mrb_fixnum_p(o) ((o).value.i_flag == MRB_FIXNUM_FLAG)
+#define mrb_undef_p(o) ((o).w == MRB_Qundef)
+#define mrb_nil_p(o)  ((o).w == MRB_Qnil)
+
+#define BOXWORD_SET_VALUE(o, ttt, attr, v) do { \
+  switch (ttt) {\
+  case MRB_TT_FALSE:  (o).w = (v) ? MRB_Qfalse : MRB_Qnil; break;\
+  case MRB_TT_TRUE:   (o).w = MRB_Qtrue; break;\
+  case MRB_TT_UNDEF:  (o).w = MRB_Qundef; break;\
+  case MRB_TT_FIXNUM: (o).w = 0;(o).value.i_flag = MRB_FIXNUM_FLAG; (o).attr = (v); break;\
+  case MRB_TT_SYMBOL: (o).w = 0;(o).value.sym_flag = MRB_SYMBOL_FLAG; (o).attr = (v); break;\
+  default:            (o).w = 0; (o).attr = (v); if ((o).value.bp) (o).value.bp->tt = ttt; break;\
+  }\
+} while (0)
+
+#define SET_FLOAT_VALUE(mrb,r,v) r = mrb_word_boxing_float_value(mrb, v)
+#define SET_CPTR_VALUE(mrb,r,v) r = mrb_word_boxing_cptr_value(mrb, v)
+#define SET_NIL_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_FALSE, value.i, 0)
+#define SET_FALSE_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_FALSE, value.i, 1)
+#define SET_TRUE_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_TRUE, value.i, 1)
+#define SET_BOOL_VALUE(r,b) BOXWORD_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1)
+#define SET_INT_VALUE(r,n) BOXWORD_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
+#define SET_SYM_VALUE(r,v) BOXWORD_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
+#define SET_OBJ_VALUE(r,v) BOXWORD_SET_VALUE(r, (((struct RObject*)(v))->tt), value.p, (v))
+#define SET_UNDEF_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0)
+
+#endif  /* MRUBY_BOXING_WORD_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/class.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/class.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/class.h	(revision 331)
@@ -0,0 +1,90 @@
+/*
+** mruby/class.h - Class class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_CLASS_H
+#define MRUBY_CLASS_H
+
+#include "common.h"
+
+/**
+ * Class class
+ */
+MRB_BEGIN_DECL
+
+struct RClass {
+  MRB_OBJECT_HEADER;
+  struct iv_tbl *iv;
+  struct kh_mt *mt;
+  struct RClass *super;
+};
+
+#define mrb_class_ptr(v)    ((struct RClass*)(mrb_ptr(v)))
+#define RCLASS_SUPER(v)     (((struct RClass*)(mrb_ptr(v)))->super)
+#define RCLASS_IV_TBL(v)    (((struct RClass*)(mrb_ptr(v)))->iv)
+#define RCLASS_M_TBL(v)     (((struct RClass*)(mrb_ptr(v)))->mt)
+
+static inline struct RClass*
+mrb_class(mrb_state *mrb, mrb_value v)
+{
+  switch (mrb_type(v)) {
+  case MRB_TT_FALSE:
+    if (mrb_fixnum(v))
+      return mrb->false_class;
+    return mrb->nil_class;
+  case MRB_TT_TRUE:
+    return mrb->true_class;
+  case MRB_TT_SYMBOL:
+    return mrb->symbol_class;
+  case MRB_TT_FIXNUM:
+    return mrb->fixnum_class;
+  case MRB_TT_FLOAT:
+    return mrb->float_class;
+  case MRB_TT_CPTR:
+    return mrb->object_class;
+  case MRB_TT_ENV:
+    return NULL;
+  default:
+    return mrb_obj_ptr(v)->c;
+  }
+}
+
+/* TODO: figure out where to put user flags */
+#define MRB_FLAG_IS_FROZEN (1 << 18)
+#define MRB_FLAG_IS_PREPENDED (1 << 19)
+#define MRB_FLAG_IS_ORIGIN (1 << 20)
+#define MRB_CLASS_ORIGIN(c) do {\
+  if (c->flags & MRB_FLAG_IS_PREPENDED) {\
+    c = c->super;\
+    while (!(c->flags & MRB_FLAG_IS_ORIGIN)) {\
+      c = c->super;\
+    }\
+  }\
+} while (0)
+#define MRB_INSTANCE_TT_MASK (0xFF)
+#define MRB_SET_INSTANCE_TT(c, tt) c->flags = ((c->flags & ~MRB_INSTANCE_TT_MASK) | (char)tt)
+#define MRB_INSTANCE_TT(c) (enum mrb_vtype)(c->flags & MRB_INSTANCE_TT_MASK)
+
+MRB_API struct RClass* mrb_define_class_id(mrb_state*, mrb_sym, struct RClass*);
+MRB_API struct RClass* mrb_define_module_id(mrb_state*, mrb_sym);
+MRB_API struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym);
+MRB_API struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym);
+MRB_API void mrb_define_method_raw(mrb_state*, struct RClass*, mrb_sym, struct RProc *);
+MRB_API void mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec);
+MRB_API void mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b);
+
+MRB_API struct RClass *mrb_class_outer_module(mrb_state*, struct RClass *);
+MRB_API struct RProc *mrb_method_search_vm(mrb_state*, struct RClass**, mrb_sym);
+MRB_API struct RProc *mrb_method_search(mrb_state*, struct RClass*, mrb_sym);
+
+MRB_API struct RClass* mrb_class_real(struct RClass* cl);
+
+void mrb_gc_mark_mt(mrb_state*, struct RClass*);
+size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*);
+void mrb_gc_free_mt(mrb_state*, struct RClass*);
+
+MRB_END_DECL
+
+#endif  /* MRUBY_CLASS_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/common.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/common.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/common.h	(revision 331)
@@ -0,0 +1,72 @@
+/*
+**"common.h - mruby common platform definition"
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_COMMON_H
+#define MRUBY_COMMON_H
+
+
+#ifdef __cplusplus
+#ifdef MRB_ENABLE_CXX_ABI
+#define MRB_BEGIN_DECL
+#define MRB_END_DECL
+#else
+# define MRB_BEGIN_DECL extern "C" {
+# define MRB_END_DECL	}
+#endif
+#else
+/** Start declarations in C mode */
+# define MRB_BEGIN_DECL
+/** End declarations in C mode */
+# define MRB_END_DECL
+#endif
+
+/**
+ * Shared compiler macros
+ */
+MRB_BEGIN_DECL
+
+/** Declare a function that never returns. */
+#if __STDC_VERSION__ >= 201112L
+# define mrb_noreturn _Noreturn
+#elif defined __GNUC__ && !defined __STRICT_ANSI__
+# define mrb_noreturn __attribute__((noreturn))
+#elif defined _MSC_VER
+# define mrb_noreturn __declspec(noreturn)
+#else
+# define mrb_noreturn
+#endif
+
+/** Mark a function as deprecated. */
+#if defined __GNUC__ && !defined __STRICT_ANSI__
+# define mrb_deprecated __attribute__((deprecated))
+#elif defined _MSC_VER
+# define mrb_deprecated __declspec(deprecated)
+#else
+# define mrb_deprecated
+#endif
+
+/** Declare a function as always inlined. */
+#if defined(_MSC_VER)
+# define MRB_INLINE static __inline
+#else
+# define MRB_INLINE static inline
+#endif
+
+
+/** Declare a public MRuby API function. */
+#if defined(MRB_BUILD_AS_DLL)
+#if defined(MRB_CORE) || defined(MRB_LIB)
+# define MRB_API __declspec(dllexport)
+#else
+# define MRB_API __declspec(dllimport)
+#endif
+#else
+# define MRB_API extern
+#endif
+
+MRB_END_DECL
+
+#endif  /* MRUBY_COMMON_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/compile.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/compile.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/compile.h	(revision 331)
@@ -0,0 +1,193 @@
+/*
+** mruby/compile.h - mruby parser
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_COMPILE_H
+#define MRUBY_COMPILE_H
+
+#include "common.h"
+
+/**
+ * MRuby Compiler
+ */
+MRB_BEGIN_DECL
+
+#include <mruby.h>
+
+struct mrb_jmpbuf;
+
+struct mrb_parser_state;
+/* load context */
+typedef struct mrbc_context {
+  mrb_sym *syms;
+  int slen;
+  char *filename;
+  short lineno;
+  int (*partial_hook)(struct mrb_parser_state*);
+  void *partial_data;
+  struct RClass *target_class;
+  mrb_bool capture_errors:1;
+  mrb_bool dump_result:1;
+  mrb_bool no_exec:1;
+  mrb_bool keep_lv:1;
+  mrb_bool no_optimize:1;
+} mrbc_context;
+
+MRB_API mrbc_context* mrbc_context_new(mrb_state *mrb);
+MRB_API void mrbc_context_free(mrb_state *mrb, mrbc_context *cxt);
+MRB_API const char *mrbc_filename(mrb_state *mrb, mrbc_context *c, const char *s);
+MRB_API void mrbc_partial_hook(mrb_state *mrb, mrbc_context *c, int (*partial_hook)(struct mrb_parser_state*), void*data);
+
+/* AST node structure */
+typedef struct mrb_ast_node {
+  struct mrb_ast_node *car, *cdr;
+  uint16_t lineno, filename_index;
+} mrb_ast_node;
+
+/* lexer states */
+enum mrb_lex_state_enum {
+  EXPR_BEG,                   /* ignore newline, +/- is a sign. */
+  EXPR_END,                   /* newline significant, +/- is an operator. */
+  EXPR_ENDARG,                /* ditto, and unbound braces. */
+  EXPR_ENDFN,                 /* ditto, and unbound braces. */
+  EXPR_ARG,                   /* newline significant, +/- is an operator. */
+  EXPR_CMDARG,                /* newline significant, +/- is an operator. */
+  EXPR_MID,                   /* newline significant, +/- is an operator. */
+  EXPR_FNAME,                 /* ignore newline, no reserved words. */
+  EXPR_DOT,                   /* right after '.' or '::', no reserved words. */
+  EXPR_CLASS,                 /* immediate after 'class', no here document. */
+  EXPR_VALUE,                 /* alike EXPR_BEG but label is disallowed. */
+  EXPR_MAX_STATE
+};
+
+/* saved error message */
+struct mrb_parser_message {
+  int lineno;
+  int column;
+  char* message;
+};
+
+#define STR_FUNC_PARSING 0x01
+#define STR_FUNC_EXPAND  0x02
+#define STR_FUNC_REGEXP  0x04
+#define STR_FUNC_WORD    0x08
+#define STR_FUNC_SYMBOL  0x10
+#define STR_FUNC_ARRAY   0x20
+#define STR_FUNC_HEREDOC 0x40
+#define STR_FUNC_XQUOTE  0x80
+
+enum mrb_string_type {
+  str_not_parsing  = (0),
+  str_squote   = (STR_FUNC_PARSING),
+  str_dquote   = (STR_FUNC_PARSING|STR_FUNC_EXPAND),
+  str_regexp   = (STR_FUNC_PARSING|STR_FUNC_REGEXP|STR_FUNC_EXPAND),
+  str_sword    = (STR_FUNC_PARSING|STR_FUNC_WORD|STR_FUNC_ARRAY),
+  str_dword    = (STR_FUNC_PARSING|STR_FUNC_WORD|STR_FUNC_ARRAY|STR_FUNC_EXPAND),
+  str_ssym     = (STR_FUNC_PARSING|STR_FUNC_SYMBOL),
+  str_ssymbols = (STR_FUNC_PARSING|STR_FUNC_SYMBOL|STR_FUNC_ARRAY),
+  str_dsymbols = (STR_FUNC_PARSING|STR_FUNC_SYMBOL|STR_FUNC_ARRAY|STR_FUNC_EXPAND),
+  str_heredoc  = (STR_FUNC_PARSING|STR_FUNC_HEREDOC),
+  str_xquote   = (STR_FUNC_PARSING|STR_FUNC_XQUOTE|STR_FUNC_EXPAND),
+};
+
+/* heredoc structure */
+struct mrb_parser_heredoc_info {
+  mrb_bool allow_indent:1;
+  mrb_bool line_head:1;
+  enum mrb_string_type type;
+  const char *term;
+  int term_len;
+  mrb_ast_node *doc;
+};
+
+#define MRB_PARSER_TOKBUF_MAX 65536
+#define MRB_PARSER_TOKBUF_SIZE 256
+
+/* parser structure */
+struct mrb_parser_state {
+  mrb_state *mrb;
+  struct mrb_pool *pool;
+  mrb_ast_node *cells;
+  const char *s, *send;
+#ifndef MRB_DISABLE_STDIO
+  FILE *f;
+#endif
+  mrbc_context *cxt;
+  char const *filename;
+  int lineno;
+  int column;
+
+  enum mrb_lex_state_enum lstate;
+  mrb_ast_node *lex_strterm; /* (type nest_level beg . end) */
+
+  unsigned int cond_stack;
+  unsigned int cmdarg_stack;
+  int paren_nest;
+  int lpar_beg;
+  int in_def, in_single;
+  mrb_bool cmd_start:1;
+  mrb_ast_node *locals;
+
+  mrb_ast_node *pb;
+  char *tokbuf;
+  char buf[MRB_PARSER_TOKBUF_SIZE];
+  int tidx;
+  int tsiz;
+
+  mrb_ast_node *all_heredocs;	/* list of mrb_parser_heredoc_info* */
+  mrb_ast_node *heredocs_from_nextline;
+  mrb_ast_node *parsing_heredoc;
+  mrb_ast_node *lex_strterm_before_heredoc;
+  mrb_bool heredoc_end_now:1; /* for mirb */
+
+  void *ylval;
+
+  size_t nerr;
+  size_t nwarn;
+  mrb_ast_node *tree;
+
+  mrb_bool no_optimize:1;
+  mrb_bool capture_errors:1;
+  struct mrb_parser_message error_buffer[10];
+  struct mrb_parser_message warn_buffer[10];
+
+  mrb_sym* filename_table;
+  size_t filename_table_length;
+  int current_filename_index;
+
+  struct mrb_jmpbuf* jmp;
+};
+
+MRB_API struct mrb_parser_state* mrb_parser_new(mrb_state*);
+MRB_API void mrb_parser_free(struct mrb_parser_state*);
+MRB_API void mrb_parser_parse(struct mrb_parser_state*,mrbc_context*);
+MRB_API double mrb_float_read(const char*, char**);
+
+MRB_API void mrb_parser_set_filename(struct mrb_parser_state*, char const*);
+MRB_API char const* mrb_parser_get_filename(struct mrb_parser_state*, uint16_t idx);
+
+/* utility functions */
+#ifndef MRB_DISABLE_STDIO
+MRB_API struct mrb_parser_state* mrb_parse_file(mrb_state*,FILE*,mrbc_context*);
+#endif
+MRB_API struct mrb_parser_state* mrb_parse_string(mrb_state*,const char*,mrbc_context*);
+MRB_API struct mrb_parser_state* mrb_parse_nstring(mrb_state*,const char*,int,mrbc_context*);
+MRB_API struct RProc* mrb_generate_code(mrb_state*, struct mrb_parser_state*);
+MRB_API mrb_value mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c);
+
+/* program load functions */
+#ifndef MRB_DISABLE_STDIO
+MRB_API mrb_value mrb_load_file(mrb_state*,FILE*);
+MRB_API mrb_value mrb_load_file_cxt(mrb_state*,FILE*, mrbc_context *cxt);
+#endif
+MRB_API mrb_value mrb_load_string(mrb_state *mrb, const char *s);
+MRB_API mrb_value mrb_load_nstring(mrb_state *mrb, const char *s, int len);
+MRB_API mrb_value mrb_load_string_cxt(mrb_state *mrb, const char *s, mrbc_context *cxt);
+MRB_API mrb_value mrb_load_nstring_cxt(mrb_state *mrb, const char *s, int len, mrbc_context *cxt);
+
+/** @} */
+MRB_END_DECL
+
+#endif /* MRUBY_COMPILE_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/data.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/data.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/data.h	(revision 331)
@@ -0,0 +1,75 @@
+/*
+** mruby/data.h - Data class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_DATA_H
+#define MRUBY_DATA_H
+
+#include "common.h"
+
+/**
+ * Custom C wrapped data.
+ *
+ * Defining Ruby wrappers around native objects.
+ */
+MRB_BEGIN_DECL
+
+/**
+ * Custom data type description.
+ */
+typedef struct mrb_data_type {
+  /** data type name */
+  const char *struct_name;
+
+  /** data type release function pointer */
+  void (*dfree)(mrb_state *mrb, void*);
+} mrb_data_type;
+
+struct RData {
+  MRB_OBJECT_HEADER;
+  struct iv_tbl *iv;
+  const mrb_data_type *type;
+  void *data;
+};
+
+MRB_API struct RData *mrb_data_object_alloc(mrb_state *mrb, struct RClass* klass, void *datap, const mrb_data_type *type);
+
+#define Data_Wrap_Struct(mrb,klass,type,ptr)\
+  mrb_data_object_alloc(mrb,klass,ptr,type)
+
+#define Data_Make_Struct(mrb,klass,strct,type,sval,data) do { \
+  sval = mrb_malloc(mrb, sizeof(strct));                     \
+  { static const strct zero = { 0 }; *sval = zero; };\
+  data = Data_Wrap_Struct(mrb,klass,type,sval);\
+} while (0)
+
+#define RDATA(obj)         ((struct RData *)(mrb_ptr(obj)))
+#define DATA_PTR(d)        (RDATA(d)->data)
+#define DATA_TYPE(d)       (RDATA(d)->type)
+MRB_API void mrb_data_check_type(mrb_state *mrb, mrb_value, const mrb_data_type*);
+MRB_API void *mrb_data_get_ptr(mrb_state *mrb, mrb_value, const mrb_data_type*);
+#define DATA_GET_PTR(mrb,obj,dtype,type) (type*)mrb_data_get_ptr(mrb,obj,dtype)
+MRB_API void *mrb_data_check_get_ptr(mrb_state *mrb, mrb_value, const mrb_data_type*);
+#define DATA_CHECK_GET_PTR(mrb,obj,dtype,type) (type*)mrb_data_check_get_ptr(mrb,obj,dtype)
+
+/* obsolete functions and macros */
+#define mrb_data_check_and_get(mrb,obj,dtype) mrb_data_get_ptr(mrb,obj,dtype)
+#define mrb_get_datatype(mrb,val,type) mrb_data_get_ptr(mrb, val, type)
+#define mrb_check_datatype(mrb,val,type) mrb_data_get_ptr(mrb, val, type)
+#define Data_Get_Struct(mrb,obj,type,sval) do {\
+  *(void**)&sval = mrb_data_get_ptr(mrb, obj, type); \
+} while (0)
+
+static inline void
+mrb_data_init(mrb_value v, void *ptr, const mrb_data_type *type)
+{
+  mrb_assert(mrb_type(v) == MRB_TT_DATA);
+  DATA_PTR(v) = ptr;
+  DATA_TYPE(v) = type;
+}
+
+MRB_END_DECL
+
+#endif /* MRUBY_DATA_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/debug.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/debug.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/debug.h	(revision 331)
@@ -0,0 +1,66 @@
+/*
+** mruby/debug.h - mruby debug info
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_DEBUG_H
+#define MRUBY_DEBUG_H
+
+#include "common.h"
+
+/**
+ * MRuby Debugging.
+ */
+MRB_BEGIN_DECL
+
+typedef enum mrb_debug_line_type {
+  mrb_debug_line_ary = 0,
+  mrb_debug_line_flat_map = 1
+} mrb_debug_line_type;
+
+typedef struct mrb_irep_debug_info_line {
+  uint32_t start_pos;
+  uint16_t line;
+} mrb_irep_debug_info_line;
+
+typedef struct mrb_irep_debug_info_file {
+  uint32_t start_pos;
+  const char *filename;
+  mrb_sym filename_sym;
+  uint32_t line_entry_count;
+  mrb_debug_line_type line_type;
+  union {
+    void *ptr;
+    mrb_irep_debug_info_line *flat_map;
+    uint16_t *ary;
+  } lines;
+} mrb_irep_debug_info_file;
+
+typedef struct mrb_irep_debug_info {
+  uint32_t pc_count;
+  uint16_t flen;
+  mrb_irep_debug_info_file **files;
+} mrb_irep_debug_info;
+
+/*
+ * get line from irep's debug info and program counter
+ * @return returns NULL if not found
+ */
+MRB_API const char *mrb_debug_get_filename(mrb_irep *irep, uint32_t pc);
+
+/*
+ * get line from irep's debug info and program counter
+ * @return returns -1 if not found
+ */
+MRB_API int32_t mrb_debug_get_line(mrb_irep *irep, uint32_t pc);
+
+MRB_API mrb_irep_debug_info_file *mrb_debug_info_append_file(
+    mrb_state *mrb, mrb_irep *irep,
+    uint32_t start_pos, uint32_t end_pos);
+MRB_API mrb_irep_debug_info *mrb_debug_info_alloc(mrb_state *mrb, mrb_irep *irep);
+MRB_API void mrb_debug_info_free(mrb_state *mrb, mrb_irep_debug_info *d);
+
+MRB_END_DECL
+
+#endif /* MRUBY_DEBUG_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/dump.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/dump.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/dump.h	(revision 331)
@@ -0,0 +1,215 @@
+/*
+** mruby/dump.h - mruby binary dumper (mrbc binary format)
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_DUMP_H
+#define MRUBY_DUMP_H
+
+#include <mruby.h>
+#include <mruby/irep.h>
+#include "common.h"
+
+/**
+ * Dumping compiled mruby script.
+ */
+MRB_BEGIN_DECL
+
+#define DUMP_DEBUG_INFO 1
+#define DUMP_ENDIAN_BIG 2
+#define DUMP_ENDIAN_LIL 4
+#define DUMP_ENDIAN_NAT 6
+#define DUMP_ENDIAN_MASK 6
+
+int mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size);
+#ifndef MRB_DISABLE_STDIO
+int mrb_dump_irep_binary(mrb_state*, mrb_irep*, uint8_t, FILE*);
+int mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep*, uint8_t flags, FILE *f, const char *initname);
+mrb_irep *mrb_read_irep_file(mrb_state*, FILE*);
+MRB_API mrb_value mrb_load_irep_file(mrb_state*,FILE*);
+MRB_API mrb_value mrb_load_irep_file_cxt(mrb_state*, FILE*, mrbc_context*);
+#endif
+MRB_API mrb_irep *mrb_read_irep(mrb_state*, const uint8_t*);
+
+/* dump/load error code
+ *
+ * NOTE: MRB_DUMP_GENERAL_FAILURE is caused by
+ * unspecified issues like malloc failed.
+ */
+#define MRB_DUMP_OK                     0
+#define MRB_DUMP_GENERAL_FAILURE      (-1)
+#define MRB_DUMP_WRITE_FAULT          (-2)
+#define MRB_DUMP_READ_FAULT           (-3)
+#define MRB_DUMP_CRC_ERROR            (-4)
+#define MRB_DUMP_INVALID_FILE_HEADER  (-5)
+#define MRB_DUMP_INVALID_IREP         (-6)
+#define MRB_DUMP_INVALID_ARGUMENT     (-7)
+
+/* null symbol length */
+#define MRB_DUMP_NULL_SYM_LEN         0xFFFF
+
+/* Rite Binary File header */
+#define RITE_BINARY_IDENT              "RITE"
+#define RITE_BINARY_IDENT_LIL          "ETIR"
+#define RITE_BINARY_FORMAT_VER         "0004"
+#define RITE_COMPILER_NAME             "MATZ"
+#define RITE_COMPILER_VERSION          "0000"
+
+#define RITE_VM_VER                    "0000"
+
+#define RITE_BINARY_EOF                "END\0"
+#define RITE_SECTION_IREP_IDENT        "IREP"
+#define RITE_SECTION_LINENO_IDENT      "LINE"
+#define RITE_SECTION_DEBUG_IDENT       "DBG\0"
+#define RITE_SECTION_LV_IDENT          "LVAR"
+
+#define MRB_DUMP_DEFAULT_STR_LEN      128
+#define MRB_DUMP_ALIGNMENT            sizeof(uint32_t)
+
+#ifdef __CA850__
+#pragma pack(1)
+#elif __RX
+#pragma pack
+#elif _MSC_VER
+#pragma pack(push, 1)
+#endif
+#ifndef __GNUC__
+#define __attribute__(x)
+#endif // !__GNUC__
+
+/* binary header */
+struct rite_binary_header {
+  uint8_t binary_ident[4];    /* Binary Identifier */
+  uint8_t binary_version[4];  /* Binary Format Version */
+  uint8_t binary_crc[2];      /* Binary CRC */
+  uint8_t binary_size[4];     /* Binary Size */
+  uint8_t compiler_name[4];   /* Compiler name */
+  uint8_t compiler_version[4];
+} __attribute__((packed));
+
+/* section header */
+#define RITE_SECTION_HEADER \
+  uint8_t section_ident[4]; \
+  uint8_t section_size[4]
+
+struct rite_section_header {
+  RITE_SECTION_HEADER;
+} __attribute__((packed));
+
+struct rite_section_irep_header {
+  RITE_SECTION_HEADER;
+
+  uint8_t rite_version[4];    /* Rite Instruction Specification Version */
+} __attribute__((packed));
+
+struct rite_section_lineno_header {
+  RITE_SECTION_HEADER;
+} __attribute__((packed));
+
+struct rite_section_debug_header {
+  RITE_SECTION_HEADER;
+} __attribute__((packed));
+
+struct rite_section_lv_header {
+  RITE_SECTION_HEADER;
+} __attribute__((packed));
+
+#define RITE_LV_NULL_MARK              UINT16_MAX
+
+struct rite_binary_footer {
+  RITE_SECTION_HEADER;
+} __attribute__((packed));
+
+#ifdef __CA850__
+#pragma pack(8)
+#elif __RX
+#pragma unpack
+#elif _MSC_VER
+#pragma pack(pop)
+#endif
+
+static inline int
+bigendian_p()
+{
+  int i;
+  char *p;
+
+  i = 1;
+  p = (char*)&i;
+  return p[0]?0:1;
+}
+
+static inline size_t
+uint8_to_bin(uint8_t s, uint8_t *bin)
+{
+  *bin = s;
+  return sizeof(uint8_t);
+}
+
+static inline size_t
+uint16_to_bin(uint16_t s, uint8_t *bin)
+{
+  *bin++ = (s >> 8) & 0xff;
+  *bin   = s & 0xff;
+  return sizeof(uint16_t);
+}
+
+static inline size_t
+uint32_to_bin(uint32_t l, uint8_t *bin)
+{
+  *bin++ = (l >> 24) & 0xff;
+  *bin++ = (l >> 16) & 0xff;
+  *bin++ = (l >> 8) & 0xff;
+  *bin   = l & 0xff;
+  return sizeof(uint32_t);
+}
+
+static inline size_t
+uint32l_to_bin(uint32_t l, uint8_t *bin)
+{
+  bin[3] = (l >> 24) & 0xff;
+  bin[2] = (l >> 16) & 0xff;
+  bin[1] = (l >> 8) & 0xff;
+  bin[0] = l & 0xff;
+  return sizeof(uint32_t);
+}
+
+static inline uint32_t
+bin_to_uint32(const uint8_t *bin)
+{
+  return (uint32_t)bin[0] << 24 |
+         (uint32_t)bin[1] << 16 |
+         (uint32_t)bin[2] << 8  |
+         (uint32_t)bin[3];
+}
+
+static inline uint32_t
+bin_to_uint32l(const uint8_t *bin)
+{
+  return (uint32_t)bin[3] << 24 |
+         (uint32_t)bin[2] << 16 |
+         (uint32_t)bin[1] << 8  |
+         (uint32_t)bin[0];
+}
+
+static inline uint16_t
+bin_to_uint16(const uint8_t *bin)
+{
+  return (uint16_t)bin[0] << 8 |
+         (uint16_t)bin[1];
+}
+
+static inline uint8_t
+bin_to_uint8(const uint8_t *bin)
+{
+  return (uint8_t)bin[0];
+}
+
+MRB_END_DECL
+
+/** @internal crc.c */
+uint16_t
+calc_crc_16_ccitt(const uint8_t *src, size_t nbytes, uint16_t crc);
+
+#endif  /* MRUBY_DUMP_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/error.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/error.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/error.h	(revision 331)
@@ -0,0 +1,76 @@
+/*
+** mruby/error.h - Exception class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_ERROR_H
+#define MRUBY_ERROR_H
+
+#include "common.h"
+
+/**
+ * MRuby error handling.
+ */
+MRB_BEGIN_DECL
+
+struct RException {
+  MRB_OBJECT_HEADER;
+  struct iv_tbl *iv;
+};
+
+#define mrb_exc_ptr(v) ((struct RException*)mrb_ptr(v))
+
+MRB_API void mrb_sys_fail(mrb_state *mrb, const char *mesg);
+MRB_API mrb_value mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str);
+#define mrb_exc_new_str_lit(mrb, c, lit) mrb_exc_new_str(mrb, c, mrb_str_new_lit(mrb, lit))
+MRB_API mrb_value mrb_make_exception(mrb_state *mrb, int argc, const mrb_value *argv);
+MRB_API mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc);
+MRB_API mrb_value mrb_get_backtrace(mrb_state *mrb);
+MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, const char *fmt, ...);
+
+/* declaration for fail method */
+MRB_API mrb_value mrb_f_raise(mrb_state*, mrb_value);
+
+struct RBreak {
+  MRB_OBJECT_HEADER;
+  struct iv_tbl *iv;
+  struct RProc *proc;
+  mrb_value val;
+};
+
+/**
+ * Protect
+ *
+ * @mrbgem mruby-error
+ */
+MRB_API mrb_value mrb_protect(mrb_state *mrb, mrb_func_t body, mrb_value data, mrb_bool *state);
+
+/**
+ * Ensure
+ *
+ * @mrbgem mruby-error
+ */
+MRB_API mrb_value mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
+                             mrb_func_t ensure, mrb_value e_data);
+
+/**
+ * Rescue
+ *
+ * @mrbgem mruby-error
+ */
+MRB_API mrb_value mrb_rescue(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
+                             mrb_func_t rescue, mrb_value r_data);
+
+/**
+ * Rescue exception
+ *
+ * @mrbgem mruby-error
+ */
+MRB_API mrb_value mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
+                                        mrb_func_t rescue, mrb_value r_data,
+                                        mrb_int len, struct RClass **classes);
+
+MRB_END_DECL
+
+#endif  /* MRUBY_ERROR_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/gc.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/gc.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/gc.h	(revision 331)
@@ -0,0 +1,80 @@
+/*
+** mruby/gc.h - garbage collector for mruby
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_GC_H
+#define MRUBY_GC_H
+
+#include "common.h"
+
+/**
+ * Uncommon memory management stuffs.
+ */
+MRB_BEGIN_DECL
+
+
+struct mrb_state;
+
+#define MRB_EACH_OBJ_OK 0
+#define MRB_EACH_OBJ_BREAK 1
+typedef int (mrb_each_object_callback)(struct mrb_state *mrb, struct RBasic *obj, void *data);
+void mrb_objspace_each_objects(struct mrb_state *mrb, mrb_each_object_callback *callback, void *data);
+MRB_API void mrb_free_context(struct mrb_state *mrb, struct mrb_context *c);
+
+#ifndef MRB_GC_ARENA_SIZE
+#define MRB_GC_ARENA_SIZE 100
+#endif
+
+typedef enum {
+  MRB_GC_STATE_ROOT = 0,
+  MRB_GC_STATE_MARK,
+  MRB_GC_STATE_SWEEP
+} mrb_gc_state;
+
+typedef struct mrb_heap_page {
+  struct RBasic *freelist;
+  struct mrb_heap_page *prev;
+  struct mrb_heap_page *next;
+  struct mrb_heap_page *free_next;
+  struct mrb_heap_page *free_prev;
+  mrb_bool old:1;
+  void *objects[];
+} mrb_heap_page;
+
+typedef struct mrb_gc {
+  mrb_heap_page *heaps;                /* heaps for GC */
+  mrb_heap_page *sweeps;
+  mrb_heap_page *free_heaps;
+  size_t live; /* count of live objects */
+#ifdef MRB_GC_FIXED_ARENA
+  struct RBasic *arena[MRB_GC_ARENA_SIZE]; /* GC protection array */
+#else
+  struct RBasic **arena;                   /* GC protection array */
+  int arena_capa;
+#endif
+  int arena_idx;
+
+  mrb_gc_state state; /* state of gc */
+  int current_white_part; /* make white object by white_part */
+  struct RBasic *gray_list; /* list of gray objects to be traversed incrementally */
+  struct RBasic *atomic_gray_list; /* list of objects to be traversed atomically */
+  size_t live_after_mark;
+  size_t threshold;
+  int interval_ratio;
+  int step_ratio;
+  mrb_bool iterating     :1;
+  mrb_bool disabled      :1;
+  mrb_bool full          :1;
+  mrb_bool generational  :1;
+  mrb_bool out_of_memory :1;
+  size_t majorgc_old_threshold;
+} mrb_gc;
+
+MRB_API mrb_bool
+mrb_object_dead_p(struct mrb_state *mrb, struct RBasic *object);
+
+MRB_END_DECL
+
+#endif  /* MRUBY_GC_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/hash.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/hash.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/hash.h	(revision 331)
@@ -0,0 +1,182 @@
+/*
+** mruby/hash.h - Hash class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_HASH_H
+#define MRUBY_HASH_H
+
+#include "common.h"
+#include <mruby/khash.h>
+
+/**
+ * Hash class
+ */
+MRB_BEGIN_DECL
+
+struct RHash {
+  MRB_OBJECT_HEADER;
+  struct iv_tbl *iv;
+  struct kh_ht *ht;
+};
+
+#define mrb_hash_ptr(v)    ((struct RHash*)(mrb_ptr(v)))
+#define mrb_hash_value(p)  mrb_obj_value((void*)(p))
+
+MRB_API mrb_value mrb_hash_new_capa(mrb_state*, mrb_int);
+
+/*
+ * Initializes a new hash.
+ *
+ * Equivalent to:
+ *
+ *      Hash.new
+ *
+ * @param mrb The mruby state reference.
+ * @return The initialized hash.
+ */
+MRB_API mrb_value mrb_hash_new(mrb_state *mrb);
+
+/*
+ * Sets a keys and values to hashes.
+ *
+ * Equivalent to:
+ *
+ *      hash[key] = val
+ *
+ * @param mrb The mruby state reference.
+ * @param hash The target hash.
+ * @param key The key to set.
+ * @param val The value to set.
+ * @return The value.
+ */
+MRB_API void mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val);
+
+/*
+ * Gets a value from a key. If the key is not found, the default of the
+ * hash is used.
+ *
+ * Equivalent to:
+ *
+ *     hash[key]
+ *
+ * @param mrb The mruby state reference.
+ * @param hash The target hash.
+ * @param key The key to get.
+ * @return The found value.
+ */
+MRB_API mrb_value mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key);
+
+/*
+ * Gets a value from a key. If the key is not found, the default parameter is
+ * used.
+ *
+ * Equivalent to:
+ *
+ *     hash.hash_key?(key) ? hash[key] : def
+ *
+ * @param mrb The mruby state reference.
+ * @param hash The target hash.
+ * @param key The key to get.
+ * @param def The default value.
+ * @return The found value.
+ */
+MRB_API mrb_value mrb_hash_fetch(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value def);
+
+/*
+ * Deletes hash key and value pair.
+ *
+ * Equivalent to:
+ *
+ *     hash.delete(key)
+ *
+ * @param mrb The mruby state reference.
+ * @param hash The target hash.
+ * @param key The key to delete.
+ * @return The deleted value.
+ */
+MRB_API mrb_value mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key);
+
+/*
+ * Gets an array of keys.
+ *
+ * Equivalent to:
+ *
+ *     hash.keys
+ *
+ * @param mrb The mruby state reference.
+ * @param hash The target hash.
+ * @return An array with the keys of the hash.
+ */
+MRB_API mrb_value mrb_hash_keys(mrb_state *mrb, mrb_value hash);
+MRB_API mrb_value mrb_check_hash_type(mrb_state *mrb, mrb_value hash);
+
+/*
+ * Check if the hash is empty
+ *
+ * Equivalent to:
+ *
+ *     hash.empty?
+ *
+ * @param mrb The mruby state reference.
+ * @param self The target hash.
+ * @return True if the hash is empty, false otherwise.
+ */
+MRB_API mrb_value mrb_hash_empty_p(mrb_state *mrb, mrb_value self);
+
+/*
+ * Gets an array of values.
+ *
+ * Equivalent to:
+ *
+ *     hash.values
+ *
+ * @param mrb The mruby state reference.
+ * @param hash The target hash.
+ * @return An array with the values of the hash.
+ */
+MRB_API mrb_value mrb_hash_values(mrb_state *mrb, mrb_value hash);
+
+/*
+ * Clears the hash.
+ *
+ * Equivalent to:
+ *
+ *     hash.clear
+ *
+ * @param mrb The mruby state reference.
+ * @param hash The target hash.
+ * @return The hash
+ */
+MRB_API mrb_value mrb_hash_clear(mrb_state *mrb, mrb_value hash);
+
+/* declaration of struct kh_ht */
+/* be careful when you touch the internal */
+typedef struct {
+  mrb_value v;
+  mrb_int n;
+} mrb_hash_value;
+
+KHASH_DECLARE(ht, mrb_value, mrb_hash_value, TRUE)
+
+/* RHASH_TBL allocates st_table if not available. */
+#define RHASH(obj)   ((struct RHash*)(mrb_ptr(obj)))
+#define RHASH_TBL(h)          (RHASH(h)->ht)
+#define RHASH_IFNONE(h)       mrb_iv_get(mrb, (h), mrb_intern_lit(mrb, "ifnone"))
+#define RHASH_PROCDEFAULT(h)  RHASH_IFNONE(h)
+MRB_API struct kh_ht * mrb_hash_tbl(mrb_state *mrb, mrb_value hash);
+
+#define MRB_HASH_DEFAULT      1
+#define MRB_HASH_PROC_DEFAULT 2
+#define MRB_RHASH_DEFAULT_P(h) (RHASH(h)->flags & MRB_HASH_DEFAULT)
+#define MRB_RHASH_PROCDEFAULT_P(h) (RHASH(h)->flags & MRB_HASH_PROC_DEFAULT)
+
+/* GC functions */
+void mrb_gc_mark_hash(mrb_state*, struct RHash*);
+size_t mrb_gc_mark_hash_size(mrb_state*, struct RHash*);
+void mrb_gc_free_hash(mrb_state*, struct RHash*);
+
+MRB_END_DECL
+
+#endif  /* MRUBY_HASH_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/irep.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/irep.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/irep.h	(revision 331)
@@ -0,0 +1,61 @@
+/*
+** mruby/irep.h - mrb_irep structure
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_IREP_H
+#define MRUBY_IREP_H
+
+#include "common.h"
+#include <mruby/compile.h>
+
+/**
+ * Compiled mruby scripts.
+ */
+MRB_BEGIN_DECL
+
+enum irep_pool_type {
+  IREP_TT_STRING,
+  IREP_TT_FIXNUM,
+  IREP_TT_FLOAT,
+};
+
+struct mrb_locals {
+  mrb_sym name;
+  uint16_t r;
+};
+
+/* Program data array struct */
+typedef struct mrb_irep {
+  uint16_t nlocals;        /* Number of local variables */
+  uint16_t nregs;          /* Number of register variables */
+  uint8_t flags;
+
+  mrb_code *iseq;
+  mrb_value *pool;
+  mrb_sym *syms;
+  struct mrb_irep **reps;
+
+  struct mrb_locals *lv;
+  /* debug info */
+  mrb_bool own_filename;
+  const char *filename;
+  uint16_t *lines;
+  struct mrb_irep_debug_info* debug_info;
+
+  size_t ilen, plen, slen, rlen, refcnt;
+} mrb_irep;
+
+#define MRB_ISEQ_NO_FREE 1
+
+MRB_API mrb_irep *mrb_add_irep(mrb_state *mrb);
+MRB_API mrb_value mrb_load_irep(mrb_state*, const uint8_t*);
+MRB_API mrb_value mrb_load_irep_cxt(mrb_state*, const uint8_t*, mrbc_context*);
+void mrb_irep_free(mrb_state*, struct mrb_irep*);
+void mrb_irep_incref(mrb_state*, struct mrb_irep*);
+void mrb_irep_decref(mrb_state*, struct mrb_irep*);
+
+MRB_END_DECL
+
+#endif  /* MRUBY_IREP_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/istruct.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/istruct.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/istruct.h	(revision 331)
@@ -0,0 +1,47 @@
+/*
+** mruby/istruct.h - Inline structures
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_ISTRUCT_H
+#define MRUBY_ISTRUCT_H
+
+#include "common.h"
+#include <string.h>
+
+/**
+ * Inline structures that fit in RVALUE
+ *
+ * They cannot have finalizer, and cannot have instance variables.
+ */
+MRB_BEGIN_DECL
+
+#define ISTRUCT_DATA_SIZE (sizeof(void*) * 3)
+
+struct RIstruct {
+  MRB_OBJECT_HEADER;
+  char inline_data[ISTRUCT_DATA_SIZE];
+};
+
+#define RISTRUCT(obj)         ((struct RIstruct*)(mrb_ptr(obj)))
+#define ISTRUCT_PTR(obj)      (RISTRUCT(obj)->inline_data)
+
+MRB_INLINE mrb_int mrb_istruct_size()
+{
+  return ISTRUCT_DATA_SIZE;
+}
+
+MRB_INLINE void* mrb_istruct_ptr(mrb_value object)
+{
+  return ISTRUCT_PTR(object);
+}
+
+MRB_INLINE void mrb_istruct_copy(mrb_value dest, mrb_value src)
+{
+  memcpy(ISTRUCT_PTR(dest), ISTRUCT_PTR(src), ISTRUCT_DATA_SIZE);
+}
+
+MRB_END_DECL
+
+#endif /* MRUBY_ISTRUCT_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/khash.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/khash.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/khash.h	(revision 331)
@@ -0,0 +1,274 @@
+/*
+** mruby/khash.c - Hash for mruby
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_KHASH_H
+#define MRUBY_KHASH_H
+
+#include <string.h>
+
+#include <mruby.h>
+#include "common.h"
+
+/**
+ * khash definitions used in mruby's hash table.
+ */
+MRB_BEGIN_DECL
+
+typedef uint32_t khint_t;
+typedef khint_t khiter_t;
+
+#ifndef KHASH_DEFAULT_SIZE
+# define KHASH_DEFAULT_SIZE 32
+#endif
+#define KHASH_MIN_SIZE 8
+
+#define UPPER_BOUND(x) ((x)>>2|(x)>>1)
+
+/* extern uint8_t __m[]; */
+
+/* mask for flags */
+static const uint8_t __m_empty[]  = {0x02, 0x08, 0x20, 0x80};
+static const uint8_t __m_del[]    = {0x01, 0x04, 0x10, 0x40};
+static const uint8_t __m_either[] = {0x03, 0x0c, 0x30, 0xc0};
+
+
+#define __ac_isempty(ed_flag, i) (ed_flag[(i)/4]&__m_empty[(i)%4])
+#define __ac_isdel(ed_flag, i) (ed_flag[(i)/4]&__m_del[(i)%4])
+#define __ac_iseither(ed_flag, i) (ed_flag[(i)/4]&__m_either[(i)%4])
+#define khash_power2(v) do { \
+  v--;\
+  v |= v >> 1;\
+  v |= v >> 2;\
+  v |= v >> 4;\
+  v |= v >> 8;\
+  v |= v >> 16;\
+  v++;\
+} while (0)
+#define khash_mask(h) ((h)->n_buckets-1)
+#define khash_upper_bound(h) (UPPER_BOUND((h)->n_buckets))
+
+/* declare struct kh_xxx and kh_xxx_funcs
+
+   name: hash name
+   khkey_t: key data type
+   khval_t: value data type
+   kh_is_map: (0: hash set / 1: hash map)
+*/
+#define KHASH_DECLARE(name, khkey_t, khval_t, kh_is_map)                \
+  typedef struct kh_##name {                                            \
+    khint_t n_buckets;                                                  \
+    khint_t size;                                                       \
+    khint_t n_occupied;                                                 \
+    uint8_t *ed_flags;                                                  \
+    khkey_t *keys;                                                      \
+    khval_t *vals;                                                      \
+  } kh_##name##_t;                                                      \
+  void kh_alloc_##name(mrb_state *mrb, kh_##name##_t *h);               \
+  kh_##name##_t *kh_init_##name##_size(mrb_state *mrb, khint_t size);   \
+  kh_##name##_t *kh_init_##name(mrb_state *mrb);                        \
+  void kh_destroy_##name(mrb_state *mrb, kh_##name##_t *h);             \
+  void kh_clear_##name(mrb_state *mrb, kh_##name##_t *h);               \
+  khint_t kh_get_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key);           \
+  khint_t kh_put_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key, int *ret); \
+  void kh_resize_##name(mrb_state *mrb, kh_##name##_t *h, khint_t new_n_buckets); \
+  void kh_del_##name(mrb_state *mrb, kh_##name##_t *h, khint_t x);                \
+  kh_##name##_t *kh_copy_##name(mrb_state *mrb, kh_##name##_t *h);
+
+static inline void
+kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
+{
+  while (len-- > 0) {
+    *p++ = c;
+  }
+}
+
+/* define kh_xxx_funcs
+
+   name: hash name
+   khkey_t: key data type
+   khval_t: value data type
+   kh_is_map: (0: hash set / 1: hash map)
+   __hash_func: hash function
+   __hash_equal: hash comparation function
+*/
+#define KHASH_DEFINE(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
+  void kh_alloc_##name(mrb_state *mrb, kh_##name##_t *h)                \
+  {                                                                     \
+    khint_t sz = h->n_buckets;                                          \
+    size_t len = sizeof(khkey_t) + (kh_is_map ? sizeof(khval_t) : 0);   \
+    uint8_t *p = (uint8_t*)mrb_malloc(mrb, sizeof(uint8_t)*sz/4+len*sz); \
+    h->size = h->n_occupied = 0;                                        \
+    h->keys = (khkey_t *)p;                                             \
+    h->vals = kh_is_map ? (khval_t *)(p+sizeof(khkey_t)*sz) : NULL;     \
+    h->ed_flags = p+len*sz;                                             \
+    kh_fill_flags(h->ed_flags, 0xaa, sz/4);                             \
+  }                                                                     \
+  kh_##name##_t *kh_init_##name##_size(mrb_state *mrb, khint_t size) {  \
+    kh_##name##_t *h = (kh_##name##_t*)mrb_calloc(mrb, 1, sizeof(kh_##name##_t)); \
+    if (size < KHASH_MIN_SIZE)                                          \
+      size = KHASH_MIN_SIZE;                                            \
+    khash_power2(size);                                                 \
+    h->n_buckets = size;                                                \
+    kh_alloc_##name(mrb, h);                                            \
+    return h;                                                           \
+  }                                                                     \
+  kh_##name##_t *kh_init_##name(mrb_state *mrb) {                       \
+    return kh_init_##name##_size(mrb, KHASH_DEFAULT_SIZE);              \
+  }                                                                     \
+  void kh_destroy_##name(mrb_state *mrb, kh_##name##_t *h)              \
+  {                                                                     \
+    if (h) {                                                            \
+      mrb_free(mrb, h->keys);                                           \
+      mrb_free(mrb, h);                                                 \
+    }                                                                   \
+  }                                                                     \
+  void kh_clear_##name(mrb_state *mrb, kh_##name##_t *h)                \
+  {                                                                     \
+    (void)mrb;                                                          \
+    if (h && h->ed_flags) {                                             \
+      kh_fill_flags(h->ed_flags, 0xaa, h->n_buckets/4);                 \
+      h->size = h->n_occupied = 0;                                      \
+    }                                                                   \
+  }                                                                     \
+  khint_t kh_get_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key)  \
+  {                                                                     \
+    khint_t k = __hash_func(mrb,key) & khash_mask(h), step = 0;         \
+    (void)mrb;                                                          \
+    while (!__ac_isempty(h->ed_flags, k)) {                             \
+      if (!__ac_isdel(h->ed_flags, k)) {                                \
+        if (__hash_equal(mrb,h->keys[k], key)) return k;                \
+      }                                                                 \
+      k = (k+(++step)) & khash_mask(h);                                 \
+    }                                                                   \
+    return kh_end(h);                                                   \
+  }                                                                     \
+  void kh_resize_##name(mrb_state *mrb, kh_##name##_t *h, khint_t new_n_buckets) \
+  {                                                                     \
+    if (new_n_buckets < KHASH_MIN_SIZE)                                 \
+      new_n_buckets = KHASH_MIN_SIZE;                                   \
+    khash_power2(new_n_buckets);                                        \
+    {                                                                   \
+      kh_##name##_t hh;                                                 \
+      uint8_t *old_ed_flags = h->ed_flags;                              \
+      khkey_t *old_keys = h->keys;                                      \
+      khval_t *old_vals = h->vals;                                      \
+      khint_t old_n_buckets = h->n_buckets;                             \
+      khint_t i;                                                        \
+      hh.n_buckets = new_n_buckets;                                     \
+      kh_alloc_##name(mrb, &hh);                                        \
+      /* relocate */                                                    \
+      for (i=0 ; i<old_n_buckets ; i++) {                               \
+        if (!__ac_iseither(old_ed_flags, i)) {                          \
+          khint_t k = kh_put_##name(mrb, &hh, old_keys[i], NULL);       \
+          if (kh_is_map) kh_value(&hh,k) = old_vals[i];                 \
+        }                                                               \
+      }                                                                 \
+      /* copy hh to h */                                                \
+      *h = hh;                                                          \
+      mrb_free(mrb, old_keys);                                          \
+    }                                                                   \
+  }                                                                     \
+  khint_t kh_put_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key, int *ret) \
+  {                                                                     \
+    khint_t k, del_k, step = 0;                                         \
+    if (h->n_occupied >= khash_upper_bound(h)) {                        \
+      kh_resize_##name(mrb, h, h->n_buckets*2);                         \
+    }                                                                   \
+    k = __hash_func(mrb,key) & khash_mask(h);                           \
+    del_k = kh_end(h);                                                  \
+    while (!__ac_isempty(h->ed_flags, k)) {                             \
+      if (!__ac_isdel(h->ed_flags, k)) {                                \
+        if (__hash_equal(mrb,h->keys[k], key)) {                        \
+          if (ret) *ret = 0;                                            \
+          return k;                                                     \
+        }                                                               \
+      }                                                                 \
+      else if (del_k == kh_end(h)) {                                    \
+        del_k = k;                                                      \
+      }                                                                 \
+      k = (k+(++step)) & khash_mask(h);                                 \
+    }                                                                   \
+    if (del_k != kh_end(h)) {                                           \
+      /* put at del */                                                  \
+      h->keys[del_k] = key;                                             \
+      h->ed_flags[del_k/4] &= ~__m_del[del_k%4];                        \
+      h->size++;                                                        \
+      if (ret) *ret = 2;                                                \
+      return del_k;                                                     \
+    }                                                                   \
+    else {                                                              \
+      /* put at empty */                                                \
+      h->keys[k] = key;                                                 \
+      h->ed_flags[k/4] &= ~__m_empty[k%4];                              \
+      h->size++;                                                        \
+      h->n_occupied++;                                                  \
+      if (ret) *ret = 1;                                                \
+      return k;                                                         \
+    }                                                                   \
+  }                                                                     \
+  void kh_del_##name(mrb_state *mrb, kh_##name##_t *h, khint_t x)       \
+  {                                                                     \
+    (void)mrb;                                                          \
+    mrb_assert(x != h->n_buckets && !__ac_iseither(h->ed_flags, x));    \
+    h->ed_flags[x/4] |= __m_del[x%4];                                   \
+    h->size--;                                                          \
+  }                                                                     \
+  kh_##name##_t *kh_copy_##name(mrb_state *mrb, kh_##name##_t *h)       \
+  {                                                                     \
+    kh_##name##_t *h2;                                                  \
+    khiter_t k, k2;                                                     \
+                                                                        \
+    h2 = kh_init_##name(mrb);                                           \
+    for (k = kh_begin(h); k != kh_end(h); k++) {                        \
+      if (kh_exist(h, k)) {                                             \
+        k2 = kh_put_##name(mrb, h2, kh_key(h, k), NULL);                \
+        if (kh_is_map) kh_value(h2, k2) = kh_value(h, k);               \
+      }                                                                 \
+    }                                                                   \
+    return h2;                                                          \
+  }
+
+
+#define khash_t(name) kh_##name##_t
+
+#define kh_init_size(name,mrb,size) kh_init_##name##_size(mrb,size)
+#define kh_init(name,mrb) kh_init_##name(mrb)
+#define kh_destroy(name, mrb, h) kh_destroy_##name(mrb, h)
+#define kh_clear(name, mrb, h) kh_clear_##name(mrb, h)
+#define kh_resize(name, mrb, h, s) kh_resize_##name(mrb, h, s)
+#define kh_put(name, mrb, h, k) kh_put_##name(mrb, h, k, NULL)
+#define kh_put2(name, mrb, h, k, r) kh_put_##name(mrb, h, k, r)
+#define kh_get(name, mrb, h, k) kh_get_##name(mrb, h, k)
+#define kh_del(name, mrb, h, k) kh_del_##name(mrb, h, k)
+#define kh_copy(name, mrb, h) kh_copy_##name(mrb, h)
+
+#define kh_exist(h, x) (!__ac_iseither((h)->ed_flags, (x)))
+#define kh_key(h, x) ((h)->keys[x])
+#define kh_val(h, x) ((h)->vals[x])
+#define kh_value(h, x) ((h)->vals[x])
+#define kh_begin(h) (khint_t)(0)
+#define kh_end(h) ((h)->n_buckets)
+#define kh_size(h) ((h)->size)
+#define kh_n_buckets(h) ((h)->n_buckets)
+
+#define kh_int_hash_func(mrb,key) (khint_t)((key)^((key)<<2)^((key)>>2))
+#define kh_int_hash_equal(mrb,a, b) (a == b)
+#define kh_int64_hash_func(mrb,key) (khint_t)((key)>>33^(key)^(key)<<11)
+#define kh_int64_hash_equal(mrb,a, b) (a == b)
+static inline khint_t __ac_X31_hash_string(const char *s)
+{
+    khint_t h = *s;
+    if (h) for (++s ; *s; ++s) h = (h << 5) - h + *s;
+    return h;
+}
+#define kh_str_hash_func(mrb,key) __ac_X31_hash_string(key)
+#define kh_str_hash_equal(mrb,a, b) (strcmp(a, b) == 0)
+
+typedef const char *kh_cstr_t;
+
+MRB_END_DECL
+
+#endif  /* MRUBY_KHASH_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/numeric.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/numeric.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/numeric.h	(revision 331)
@@ -0,0 +1,157 @@
+/*
+** mruby/numeric.h - Numeric, Integer, Float, Fixnum class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_NUMERIC_H
+#define MRUBY_NUMERIC_H
+
+#include "common.h"
+
+/**
+ * Numeric class and it's sub-classes.
+ *
+ * Integer, Float and Fixnum
+ */
+MRB_BEGIN_DECL
+
+#define POSFIXABLE(f) ((f) <= MRB_INT_MAX)
+#define NEGFIXABLE(f) ((f) >= MRB_INT_MIN)
+#define FIXABLE(f) (POSFIXABLE(f) && NEGFIXABLE(f))
+
+#ifdef MRB_INT64
+#define FIXABLE_FLOAT(f) FIXABLE((mrb_int)(f))
+#else
+#define FIXABLE_FLOAT(f) FIXABLE(f)
+#endif
+
+MRB_API mrb_value mrb_flo_to_fixnum(mrb_state *mrb, mrb_value val);
+MRB_API mrb_value mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, int base);
+/* ArgumentError if format string doesn't match /%(\.[0-9]+)?[aAeEfFgG]/ */
+MRB_API mrb_value mrb_float_to_str(mrb_state *mrb, mrb_value x, const char *fmt);
+MRB_API mrb_float mrb_to_flo(mrb_state *mrb, mrb_value x);
+
+mrb_value mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y);
+mrb_value mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y);
+mrb_value mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y);
+mrb_value mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y);
+
+#ifndef __has_builtin
+  #define __has_builtin(x) 0
+#endif
+
+#if (defined(__GNUC__) && __GNUC__ >= 5) ||   \
+    (__has_builtin(__builtin_add_overflow) && \
+     __has_builtin(__builtin_sub_overflow) && \
+     __has_builtin(__builtin_mul_overflow))
+# define MRB_HAVE_TYPE_GENERIC_CHECKED_ARITHMETIC_BUILTINS
+#endif
+
+/*
+// Clang 3.8 and 3.9 have problem compiling mruby in 32-bit mode, when MRB_INT64 is set
+// because of missing __mulodi4 and similar functions in its runtime. We need to use custom
+// implementation for them.
+*/
+#ifdef MRB_HAVE_TYPE_GENERIC_CHECKED_ARITHMETIC_BUILTINS
+#if defined(__clang__) && (__clang_major__ == 3) && (__clang_minor__ >= 8) && \
+    defined(MRB_32BIT) && defined(MRB_INT64)
+#undef MRB_HAVE_TYPE_GENERIC_CHECKED_ARITHMETIC_BUILTINS
+#endif
+#endif
+
+#ifdef MRB_HAVE_TYPE_GENERIC_CHECKED_ARITHMETIC_BUILTINS
+
+#ifndef MRB_WORD_BOXING
+# define WBCHK(x) 0
+#else
+# define WBCHK(x) !FIXABLE(x)
+#endif
+
+static inline mrb_bool
+mrb_int_add_overflow(mrb_int augend, mrb_int addend, mrb_int *sum)
+{
+  return __builtin_add_overflow(augend, addend, sum) || WBCHK(*sum);
+}
+
+static inline mrb_bool
+mrb_int_sub_overflow(mrb_int minuend, mrb_int subtrahend, mrb_int *difference)
+{
+  return __builtin_sub_overflow(minuend, subtrahend, difference) || WBCHK(*difference);
+}
+
+static inline mrb_bool
+mrb_int_mul_overflow(mrb_int multiplier, mrb_int multiplicand, mrb_int *product)
+{
+  return __builtin_mul_overflow(multiplier, multiplicand, product) || WBCHK(*product);
+}
+
+#undef WBCHK
+
+#else
+
+#define MRB_UINT_MAKE2(n) uint ## n ## _t
+#define MRB_UINT_MAKE(n) MRB_UINT_MAKE2(n)
+#define mrb_uint MRB_UINT_MAKE(MRB_INT_BIT)
+
+#define MRB_INT_OVERFLOW_MASK ((mrb_uint)1 << (MRB_INT_BIT - 1 - MRB_FIXNUM_SHIFT))
+
+static inline mrb_bool
+mrb_int_add_overflow(mrb_int augend, mrb_int addend, mrb_int *sum)
+{
+  mrb_uint x = (mrb_uint)augend;
+  mrb_uint y = (mrb_uint)addend;
+  mrb_uint z = (mrb_uint)(x + y);
+  *sum = (mrb_int)z;
+  return !!(((x ^ z) & (y ^ z)) & MRB_INT_OVERFLOW_MASK);
+}
+
+static inline mrb_bool
+mrb_int_sub_overflow(mrb_int minuend, mrb_int subtrahend, mrb_int *difference)
+{
+  mrb_uint x = (mrb_uint)minuend;
+  mrb_uint y = (mrb_uint)subtrahend;
+  mrb_uint z = (mrb_uint)(x - y);
+  *difference = (mrb_int)z;
+  return !!(((x ^ z) & (~y ^ z)) & MRB_INT_OVERFLOW_MASK);
+}
+
+static inline mrb_bool
+mrb_int_mul_overflow(mrb_int multiplier, mrb_int multiplicand, mrb_int *product)
+{
+#if MRB_INT_BIT == 32
+  int64_t n = (int64_t)multiplier * multiplicand;
+  *product = (mrb_int)n;
+  return !FIXABLE(n);
+#else
+  if (multiplier > 0) {
+    if (multiplicand > 0) {
+      if (multiplier > MRB_INT_MAX / multiplicand) return TRUE;
+    }
+    else {
+      if (multiplicand < MRB_INT_MAX / multiplier) return TRUE;
+    }
+  }
+  else {
+    if (multiplicand > 0) {
+      if (multiplier < MRB_INT_MAX / multiplicand) return TRUE;
+    }
+    else {
+      if (multiplier != 0 && multiplicand < MRB_INT_MAX / multiplier) return TRUE;
+    }
+  }
+  *product = multiplier * multiplicand;
+  return FALSE;
+#endif
+}
+
+#undef MRB_INT_OVERFLOW_MASK
+#undef mrb_uint
+#undef MRB_UINT_MAKE
+#undef MRB_UINT_MAKE2
+
+#endif
+
+MRB_END_DECL
+
+#endif  /* MRUBY_NUMERIC_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/object.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/object.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/object.h	(revision 331)
@@ -0,0 +1,43 @@
+/*
+** mruby/object.h - mruby object definition
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_OBJECT_H
+#define MRUBY_OBJECT_H
+
+#define MRB_OBJECT_HEADER \
+  enum mrb_vtype tt:8;\
+  uint32_t color:3;\
+  uint32_t flags:21;\
+  struct RClass *c;\
+  struct RBasic *gcnext
+
+#define MRB_FLAG_TEST(obj, flag) ((obj)->flags & flag)
+
+
+struct RBasic {
+  MRB_OBJECT_HEADER;
+};
+#define mrb_basic_ptr(v) ((struct RBasic*)(mrb_ptr(v)))
+
+#define MRB_FROZEN_P(o) ((o)->flags & MRB_FLAG_IS_FROZEN)
+#define MRB_SET_FROZEN_FLAG(o) ((o)->flags |= MRB_FLAG_IS_FROZEN)
+#define MRB_UNSET_FROZEN_FLAG(o) ((o)->flags &= ~MRB_FLAG_IS_FROZEN)
+
+struct RObject {
+  MRB_OBJECT_HEADER;
+  struct iv_tbl *iv;
+};
+#define mrb_obj_ptr(v)   ((struct RObject*)(mrb_ptr(v)))
+
+#define mrb_immediate_p(x) (mrb_type(x) < MRB_TT_HAS_BASIC)
+#define mrb_special_const_p(x) mrb_immediate_p(x)
+
+struct RFiber {
+  MRB_OBJECT_HEADER;
+  struct mrb_context *cxt;
+};
+
+#endif  /* MRUBY_OBJECT_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/opcode.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/opcode.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/opcode.h	(revision 331)
@@ -0,0 +1,161 @@
+/*
+** mruby/opcode.h - RiteVM operation codes
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_OPCODE_H
+#define MRUBY_OPCODE_H
+
+#define MAXARG_Bx        (0xffff)
+#define MAXARG_sBx       (MAXARG_Bx>>1)         /* 'sBx' is signed */
+
+/* instructions: packed 32 bit      */
+/* -------------------------------  */
+/*     A:B:C:OP = 9: 9: 7: 7        */
+/*      A:Bx:OP =    9:16: 7        */
+/*        Ax:OP =      25: 7        */
+/*   A:Bz:Cz:OP = 9:14: 2: 7        */
+
+#define GET_OPCODE(i)            ((int)(((mrb_code)(i)) & 0x7f))
+#define GETARG_A(i)              ((int)((((mrb_code)(i)) >> 23) & 0x1ff))
+#define GETARG_B(i)              ((int)((((mrb_code)(i)) >> 14) & 0x1ff))
+#define GETARG_C(i)              ((int)((((mrb_code)(i)) >>  7) & 0x7f))
+#define GETARG_Bx(i)             ((int)((((mrb_code)(i)) >>  7) & 0xffff))
+#define GETARG_sBx(i)            ((int)(GETARG_Bx(i)-MAXARG_sBx))
+#define GETARG_Ax(i)             ((int32_t)((((mrb_code)(i)) >>  7) & 0x1ffffff))
+#define GETARG_UNPACK_b(i,n1,n2) ((int)((((mrb_code)(i)) >> (7+(n2))) & (((1<<(n1))-1))))
+#define GETARG_UNPACK_c(i,n1,n2) ((int)((((mrb_code)(i)) >> 7) & (((1<<(n2))-1))))
+#define GETARG_b(i)              GETARG_UNPACK_b(i,14,2)
+#define GETARG_c(i)              GETARG_UNPACK_c(i,14,2)
+
+#define MKOPCODE(op)          ((op) & 0x7f)
+#define MKARG_A(c)            ((mrb_code)((c) & 0x1ff) << 23)
+#define MKARG_B(c)            ((mrb_code)((c) & 0x1ff) << 14)
+#define MKARG_C(c)            (((c) & 0x7f) <<  7)
+#define MKARG_Bx(v)           ((mrb_code)((v) & 0xffff) << 7)
+#define MKARG_sBx(v)          MKARG_Bx((v)+MAXARG_sBx)
+#define MKARG_Ax(v)           ((mrb_code)((v) & 0x1ffffff) << 7)
+#define MKARG_PACK(b,n1,c,n2) ((((b) & ((1<<n1)-1)) << (7+n2))|(((c) & ((1<<n2)-1)) << 7))
+#define MKARG_bc(b,c)         MKARG_PACK(b,14,c,2)
+
+#define MKOP_A(op,a)        (MKOPCODE(op)|MKARG_A(a))
+#define MKOP_AB(op,a,b)     (MKOP_A(op,a)|MKARG_B(b))
+#define MKOP_ABC(op,a,b,c)  (MKOP_AB(op,a,b)|MKARG_C(c))
+#define MKOP_ABx(op,a,bx)   (MKOP_A(op,a)|MKARG_Bx(bx))
+#define MKOP_Bx(op,bx)      (MKOPCODE(op)|MKARG_Bx(bx))
+#define MKOP_sBx(op,sbx)    (MKOPCODE(op)|MKARG_sBx(sbx))
+#define MKOP_AsBx(op,a,sbx) (MKOP_A(op,a)|MKARG_sBx(sbx))
+#define MKOP_Ax(op,ax)      (MKOPCODE(op)|MKARG_Ax(ax))
+#define MKOP_Abc(op,a,b,c)  (MKOP_A(op,a)|MKARG_bc(b,c))
+
+enum {
+  /*-----------------------------------------------------------------------
+  operation code  operand description
+  ------------------------------------------------------------------------*/
+  OP_NOP=0,/*                                                             */
+  OP_MOVE,/*      A B     R(A) := R(B)                                    */
+  OP_LOADL,/*     A Bx    R(A) := Pool(Bx)                                */
+  OP_LOADI,/*     A sBx   R(A) := sBx                                     */
+  OP_LOADSYM,/*   A Bx    R(A) := Syms(Bx)                                */
+  OP_LOADNIL,/*   A       R(A) := nil                                     */
+  OP_LOADSELF,/*  A       R(A) := self                                    */
+  OP_LOADT,/*     A       R(A) := true                                    */
+  OP_LOADF,/*     A       R(A) := false                                   */
+
+  OP_GETGLOBAL,/* A Bx    R(A) := getglobal(Syms(Bx))                     */
+  OP_SETGLOBAL,/* A Bx    setglobal(Syms(Bx), R(A))                       */
+  OP_GETSPECIAL,/*A Bx    R(A) := Special[Bx]                             */
+  OP_SETSPECIAL,/*A Bx    Special[Bx] := R(A)                             */
+  OP_GETIV,/*     A Bx    R(A) := ivget(Syms(Bx))                         */
+  OP_SETIV,/*     A Bx    ivset(Syms(Bx),R(A))                            */
+  OP_GETCV,/*     A Bx    R(A) := cvget(Syms(Bx))                         */
+  OP_SETCV,/*     A Bx    cvset(Syms(Bx),R(A))                            */
+  OP_GETCONST,/*  A Bx    R(A) := constget(Syms(Bx))                      */
+  OP_SETCONST,/*  A Bx    constset(Syms(Bx),R(A))                         */
+  OP_GETMCNST,/*  A Bx    R(A) := R(A)::Syms(Bx)                          */
+  OP_SETMCNST,/*  A Bx    R(A+1)::Syms(Bx) := R(A)                        */
+  OP_GETUPVAR,/*  A B C   R(A) := uvget(B,C)                              */
+  OP_SETUPVAR,/*  A B C   uvset(B,C,R(A))                                 */
+
+  OP_JMP,/*       sBx     pc+=sBx                                         */
+  OP_JMPIF,/*     A sBx   if R(A) pc+=sBx                                 */
+  OP_JMPNOT,/*    A sBx   if !R(A) pc+=sBx                                */
+  OP_ONERR,/*     sBx     rescue_push(pc+sBx)                             */
+  OP_RESCUE,/*    A B C   if A (if C exc=R(A) else R(A) := exc);
+                          if B R(B) := exc.isa?(R(B)); clear(exc)         */
+  OP_POPERR,/*    A       A.times{rescue_pop()}                           */
+  OP_RAISE,/*     A       raise(R(A))                                     */
+  OP_EPUSH,/*     Bx      ensure_push(SEQ[Bx])                            */
+  OP_EPOP,/*      A       A.times{ensure_pop().call}                      */
+
+  OP_SEND,/*      A B C   R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C))    */
+  OP_SENDB,/*     A B C   R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C),&R(A+C+1))*/
+  OP_FSEND,/*     A B C   R(A) := fcall(R(A),Syms(B),R(A+1),...,R(A+C-1)) */
+  OP_CALL,/*      A       R(A) := self.call(frame.argc, frame.argv)       */
+  OP_SUPER,/*     A C     R(A) := super(R(A+1),... ,R(A+C+1))             */
+  OP_ARGARY,/*    A Bx    R(A) := argument array (16=6:1:5:4)             */
+  OP_ENTER,/*     Ax      arg setup according to flags (23=5:5:1:5:5:1:1) */
+  OP_KARG,/*      A B C   R(A) := kdict[Syms(B)]; if C kdict.rm(Syms(B))  */
+  OP_KDICT,/*     A C     R(A) := kdict                                   */
+
+  OP_RETURN,/*    A B     return R(A) (B=normal,in-block return/break)    */
+  OP_TAILCALL,/*  A B C   return call(R(A),Syms(B),*R(C))                 */
+  OP_BLKPUSH,/*   A Bx    R(A) := block (16=6:1:5:4)                      */
+
+  OP_ADD,/*       A B C   R(A) := R(A)+R(A+1) (Syms[B]=:+,C=1)            */
+  OP_ADDI,/*      A B C   R(A) := R(A)+C (Syms[B]=:+)                     */
+  OP_SUB,/*       A B C   R(A) := R(A)-R(A+1) (Syms[B]=:-,C=1)            */
+  OP_SUBI,/*      A B C   R(A) := R(A)-C (Syms[B]=:-)                     */
+  OP_MUL,/*       A B C   R(A) := R(A)*R(A+1) (Syms[B]=:*,C=1)            */
+  OP_DIV,/*       A B C   R(A) := R(A)/R(A+1) (Syms[B]=:/,C=1)            */
+  OP_EQ,/*        A B C   R(A) := R(A)==R(A+1) (Syms[B]=:==,C=1)          */
+  OP_LT,/*        A B C   R(A) := R(A)<R(A+1)  (Syms[B]=:<,C=1)           */
+  OP_LE,/*        A B C   R(A) := R(A)<=R(A+1) (Syms[B]=:<=,C=1)          */
+  OP_GT,/*        A B C   R(A) := R(A)>R(A+1)  (Syms[B]=:>,C=1)           */
+  OP_GE,/*        A B C   R(A) := R(A)>=R(A+1) (Syms[B]=:>=,C=1)          */
+
+  OP_ARRAY,/*     A B C   R(A) := ary_new(R(B),R(B+1)..R(B+C))            */
+  OP_ARYCAT,/*    A B     ary_cat(R(A),R(B))                              */
+  OP_ARYPUSH,/*   A B     ary_push(R(A),R(B))                             */
+  OP_AREF,/*      A B C   R(A) := R(B)[C]                                 */
+  OP_ASET,/*      A B C   R(B)[C] := R(A)                                 */
+  OP_APOST,/*     A B C   *R(A),R(A+1)..R(A+C) := R(A)                    */
+
+  OP_STRING,/*    A Bx    R(A) := str_dup(Lit(Bx))                        */
+  OP_STRCAT,/*    A B     str_cat(R(A),R(B))                              */
+
+  OP_HASH,/*      A B C   R(A) := hash_new(R(B),R(B+1)..R(B+C))           */
+  OP_LAMBDA,/*    A Bz Cz R(A) := lambda(SEQ[Bz],Cz)                      */
+  OP_RANGE,/*     A B C   R(A) := range_new(R(B),R(B+1),C)                */
+
+  OP_OCLASS,/*    A       R(A) := ::Object                                */
+  OP_CLASS,/*     A B     R(A) := newclass(R(A),Syms(B),R(A+1))           */
+  OP_MODULE,/*    A B     R(A) := newmodule(R(A),Syms(B))                 */
+  OP_EXEC,/*      A Bx    R(A) := blockexec(R(A),SEQ[Bx])                 */
+  OP_METHOD,/*    A B     R(A).newmethod(Syms(B),R(A+1))                  */
+  OP_SCLASS,/*    A B     R(A) := R(B).singleton_class                    */
+  OP_TCLASS,/*    A       R(A) := target_class                            */
+
+  OP_DEBUG,/*     A B C   print R(A),R(B),R(C)                            */
+  OP_STOP,/*              stop VM                                         */
+  OP_ERR,/*       Bx      raise RuntimeError with message Lit(Bx)         */
+
+  OP_RSVD1,/*             reserved instruction #1                         */
+  OP_RSVD2,/*             reserved instruction #2                         */
+  OP_RSVD3,/*             reserved instruction #3                         */
+  OP_RSVD4,/*             reserved instruction #4                         */
+  OP_RSVD5,/*             reserved instruction #5                         */
+};
+
+#define OP_L_STRICT  1
+#define OP_L_CAPTURE 2
+#define OP_L_METHOD  OP_L_STRICT
+#define OP_L_LAMBDA  (OP_L_STRICT|OP_L_CAPTURE)
+#define OP_L_BLOCK   OP_L_CAPTURE
+
+#define OP_R_NORMAL 0
+#define OP_R_BREAK  1
+#define OP_R_RETURN 2
+
+#endif  /* MRUBY_OPCODE_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/proc.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/proc.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/proc.h	(revision 331)
@@ -0,0 +1,83 @@
+/*
+** mruby/proc.h - Proc class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_PROC_H
+#define MRUBY_PROC_H
+
+#include "common.h"
+#include <mruby/irep.h>
+
+/**
+ * Proc class
+ */
+MRB_BEGIN_DECL
+
+struct REnv {
+  MRB_OBJECT_HEADER;
+  mrb_value *stack;
+  ptrdiff_t cioff;
+  union {
+    mrb_sym mid;
+    struct mrb_context *c;
+  } cxt;
+};
+
+#define MRB_SET_ENV_STACK_LEN(e,len) (e)->flags = (unsigned int)(len)
+#define MRB_ENV_STACK_LEN(e) ((mrb_int)(e)->flags)
+#define MRB_ENV_UNSHARE_STACK(e) ((e)->cioff = -1)
+#define MRB_ENV_STACK_SHARED_P(e) ((e)->cioff >= 0)
+
+MRB_API void mrb_env_unshare(mrb_state*, struct REnv*);
+
+struct RProc {
+  MRB_OBJECT_HEADER;
+  union {
+    mrb_irep *irep;
+    mrb_func_t func;
+  } body;
+  struct RClass *target_class;
+  struct REnv *env;
+};
+
+/* aspec access */
+#define MRB_ASPEC_REQ(a)          (((a) >> 18) & 0x1f)
+#define MRB_ASPEC_OPT(a)          (((a) >> 13) & 0x1f)
+#define MRB_ASPEC_REST(a)         (((a) >> 12) & 0x1)
+#define MRB_ASPEC_POST(a)         (((a) >> 7) & 0x1f)
+#define MRB_ASPEC_KEY(a)          (((a) >> 2) & 0x1f)
+#define MRB_ASPEC_KDICT(a)        ((a) & (1<<1))
+#define MRB_ASPEC_BLOCK(a)        ((a) & 1)
+
+#define MRB_PROC_CFUNC 128
+#define MRB_PROC_CFUNC_P(p) (((p)->flags & MRB_PROC_CFUNC) != 0)
+#define MRB_PROC_STRICT 256
+#define MRB_PROC_STRICT_P(p) (((p)->flags & MRB_PROC_STRICT) != 0)
+#define MRB_PROC_ORPHAN 512
+#define MRB_PROC_ORPHAN_P(p) (((p)->flags & MRB_PROC_ORPHAN) != 0)
+
+#define mrb_proc_ptr(v)    ((struct RProc*)(mrb_ptr(v)))
+
+struct RProc *mrb_proc_new(mrb_state*, mrb_irep*);
+struct RProc *mrb_closure_new(mrb_state*, mrb_irep*);
+MRB_API struct RProc *mrb_proc_new_cfunc(mrb_state*, mrb_func_t);
+MRB_API struct RProc *mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals);
+void mrb_proc_copy(struct RProc *a, struct RProc *b);
+
+/* implementation of #send method */
+MRB_API mrb_value mrb_f_send(mrb_state *mrb, mrb_value self);
+
+/* following functions are defined in mruby-proc-ext so please include it when using */
+MRB_API struct RProc *mrb_proc_new_cfunc_with_env(mrb_state*, mrb_func_t, mrb_int, const mrb_value*);
+MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state*, mrb_int);
+/* old name */
+#define mrb_cfunc_env_get(mrb, idx) mrb_proc_cfunc_env_get(mrb, idx)
+
+#include <mruby/khash.h>
+KHASH_DECLARE(mt, mrb_sym, struct RProc*, TRUE)
+
+MRB_END_DECL
+
+#endif  /* MRUBY_PROC_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/range.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/range.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/range.h	(revision 331)
@@ -0,0 +1,49 @@
+/*
+** mruby/range.h - Range class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_RANGE_H
+#define MRUBY_RANGE_H
+
+#include "common.h"
+
+/**
+ * Range class
+ */
+MRB_BEGIN_DECL
+
+typedef struct mrb_range_edges {
+  mrb_value beg;
+  mrb_value end;
+} mrb_range_edges;
+
+struct RRange {
+  MRB_OBJECT_HEADER;
+  mrb_range_edges *edges;
+  mrb_bool excl : 1;
+};
+
+MRB_API struct RRange* mrb_range_ptr(mrb_state *mrb, mrb_value v);
+#define mrb_range_raw_ptr(v) ((struct RRange*)mrb_ptr(v))
+#define mrb_range_value(p)  mrb_obj_value((void*)(p))
+
+/*
+ * Initializes a Range.
+ *
+ * If the third parameter is FALSE then it includes the last value in the range.
+ * If the third parameter is TRUE then it excludes the last value in the range.
+ *
+ * @param start the beginning value.
+ * @param end the ending value.
+ * @param exclude represents the inclusion or exclusion of the last value.
+ */
+MRB_API mrb_value mrb_range_new(mrb_state *mrb, mrb_value start, mrb_value end, mrb_bool exclude);
+
+MRB_API mrb_int mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc);
+mrb_value mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, const mrb_value *argv, mrb_value (*func)(mrb_state*, mrb_value, mrb_int));
+
+MRB_END_DECL
+
+#endif  /* MRUBY_RANGE_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/re.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/re.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/re.h	(revision 331)
@@ -0,0 +1,16 @@
+/*
+** mruby/re.h - Regexp class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_RE_H
+#define MRUBY_RE_H
+
+MRB_BEGIN_DECL
+
+#define REGEXP_CLASS          "Regexp"
+
+MRB_END_DECL
+
+#endif  /* RE_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/string.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/string.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/string.h	(revision 331)
@@ -0,0 +1,422 @@
+/*
+** mruby/string.h - String class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_STRING_H
+#define MRUBY_STRING_H
+
+#include "common.h"
+
+/**
+ * String class
+ */
+MRB_BEGIN_DECL
+
+extern const char mrb_digitmap[];
+
+#define RSTRING_EMBED_LEN_MAX ((mrb_int)(sizeof(void*) * 3 - 1))
+
+struct RString {
+  MRB_OBJECT_HEADER;
+  union {
+    struct {
+      mrb_int len;
+      union {
+        mrb_int capa;
+        struct mrb_shared_string *shared;
+      } aux;
+      char *ptr;
+    } heap;
+    char ary[RSTRING_EMBED_LEN_MAX + 1];
+  } as;
+};
+
+#define RSTR_EMBED_P(s) ((s)->flags & MRB_STR_EMBED)
+#define RSTR_SET_EMBED_FLAG(s) ((s)->flags |= MRB_STR_EMBED)
+#define RSTR_UNSET_EMBED_FLAG(s) ((s)->flags &= ~(MRB_STR_EMBED|MRB_STR_EMBED_LEN_MASK))
+#define RSTR_SET_EMBED_LEN(s, n) do {\
+  size_t tmp_n = (n);\
+  s->flags &= ~MRB_STR_EMBED_LEN_MASK;\
+  s->flags |= (tmp_n) << MRB_STR_EMBED_LEN_SHIFT;\
+} while (0)
+#define RSTR_SET_LEN(s, n) do {\
+  if (RSTR_EMBED_P(s)) {\
+    RSTR_SET_EMBED_LEN((s),(n));\
+  }\
+  else {\
+    s->as.heap.len = (mrb_int)(n);\
+  }\
+} while (0)
+#define RSTR_EMBED_LEN(s)\
+  (mrb_int)(((s)->flags & MRB_STR_EMBED_LEN_MASK) >> MRB_STR_EMBED_LEN_SHIFT)
+#define RSTR_PTR(s) ((RSTR_EMBED_P(s)) ? (s)->as.ary : (s)->as.heap.ptr)
+#define RSTR_LEN(s) ((RSTR_EMBED_P(s)) ? RSTR_EMBED_LEN(s) : (s)->as.heap.len)
+#define RSTR_CAPA(s) (RSTR_EMBED_P(s) ? RSTRING_EMBED_LEN_MAX : (s)->as.heap.aux.capa)
+
+#define RSTR_SHARED_P(s) ((s)->flags & MRB_STR_SHARED)
+#define RSTR_SET_SHARED_FLAG(s) ((s)->flags |= MRB_STR_SHARED)
+#define RSTR_UNSET_SHARED_FLAG(s) ((s)->flags &= ~MRB_STR_SHARED)
+
+#define RSTR_NOFREE_P(s) ((s)->flags & MRB_STR_NOFREE)
+#define RSTR_SET_NOFREE_FLAG(s) ((s)->flags |= MRB_STR_NOFREE)
+#define RSTR_UNSET_NOFREE_FLAG(s) ((s)->flags &= ~MRB_STR_NOFREE)
+
+/*
+ * Returns a pointer from a Ruby string
+ */
+#define mrb_str_ptr(s)       ((struct RString*)(mrb_ptr(s)))
+#define RSTRING(s)           mrb_str_ptr(s)
+#define RSTRING_PTR(s)       RSTR_PTR(RSTRING(s))
+#define RSTRING_EMBED_LEN(s) RSTR_EMBED_LEN(RSTRING(s))
+#define RSTRING_LEN(s)       RSTR_LEN(RSTRING(s))
+#define RSTRING_CAPA(s)      RSTR_CAPA(RSTRING(s))
+#define RSTRING_END(s)       (RSTRING_PTR(s) + RSTRING_LEN(s))
+MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*);
+
+#define MRB_STR_SHARED    1
+#define MRB_STR_NOFREE    2
+#define MRB_STR_NO_UTF    8
+#define MRB_STR_EMBED    16
+#define MRB_STR_EMBED_LEN_MASK 0x3e0
+#define MRB_STR_EMBED_LEN_SHIFT 5
+
+void mrb_gc_free_str(mrb_state*, struct RString*);
+MRB_API void mrb_str_modify(mrb_state*, struct RString*);
+/*
+ * Appends self to other. Returns self as a concatnated string.
+ *
+ *
+ *  Example:
+ *
+ *     !!!c
+ *     int
+ *     main(int argc,
+ *          char **argv)
+ *     {
+ *       // Variable declarations.
+ *       mrb_value str1;
+ *       mrb_value str2;
+ *
+ *       mrb_state *mrb = mrb_open();
+ *       if (!mrb)
+ *       {
+ *          // handle error
+ *       }
+ *
+ *       // Creates new Ruby strings.
+ *       str1 = mrb_str_new_lit(mrb, "abc");
+ *       str2 = mrb_str_new_lit(mrb, "def");
+ *
+ *       // Concatnates str2 to str1.
+ *       mrb_str_concat(mrb, str1, str2);
+ *
+ *      // Prints new Concatnated Ruby string.
+ *      mrb_p(mrb, str1);
+ *
+ *      mrb_close(mrb);
+ *      return 0;
+ *    }
+ *
+ *
+ *  Result:
+ *
+ *     => "abcdef"
+ *
+ * @param [mrb_state] mrb The current mruby state.
+ * @param [mrb_value] self String to concatenate.
+ * @param [mrb_value] other String to append to self.
+ * @return [mrb_value] Returns a new String appending other to self.
+ */
+MRB_API void mrb_str_concat(mrb_state*, mrb_value, mrb_value);
+
+/*
+ * Adds two strings together.
+ *
+ *
+ *  Example:
+ *
+ *     !!!c
+ *     int
+ *     main(int argc,
+ *          char **argv)
+ *     {
+ *       // Variable declarations.
+ *       mrb_value a;
+ *       mrb_value b;
+ *       mrb_value c;
+ *
+ *       mrb_state *mrb = mrb_open();
+ *       if (!mrb)
+ *       {
+ *          // handle error
+ *       }
+ *
+ *       // Creates two Ruby strings from the passed in C strings.
+ *       a = mrb_str_new_lit(mrb, "abc");
+ *       b = mrb_str_new_lit(mrb, "def");
+ *
+ *       // Prints both C strings.
+ *       mrb_p(mrb, a);
+ *       mrb_p(mrb, b);
+ *
+ *       // Concatnates both Ruby strings.
+ *       c = mrb_str_plus(mrb, a, b);
+ *
+ *      // Prints new Concatnated Ruby string.
+ *      mrb_p(mrb, c);
+ *
+ *      mrb_close(mrb);
+ *      return 0;
+ *    }
+ *
+ *
+ *  Result:
+ *
+ *     => "abc"  # First string
+ *     => "def"  # Second string
+ *     => "abcdef" # First & Second concatnated.
+ *
+ * @param [mrb_state] mrb The current mruby state.
+ * @param [mrb_value] a First string to concatenate.
+ * @param [mrb_value] b Second string to concatenate.
+ * @return [mrb_value] Returns a new String containing a concatenated to b.
+ */
+MRB_API mrb_value mrb_str_plus(mrb_state*, mrb_value, mrb_value);
+
+/*
+ * Converts pointer into a Ruby string.
+ *
+ * @param [mrb_state] mrb The current mruby state.
+ * @param [void*] p The pointer to convert to Ruby string.
+ * @return [mrb_value] Returns a new Ruby String.
+ */
+MRB_API mrb_value mrb_ptr_to_str(mrb_state *, void*);
+
+/*
+ * Returns an object as a Ruby string.
+ *
+ * @param [mrb_state] mrb The current mruby state.
+ * @param [mrb_value] obj An object to return as a Ruby string.
+ * @return [mrb_value] An object as a Ruby string.
+ */
+MRB_API mrb_value mrb_obj_as_string(mrb_state *mrb, mrb_value obj);
+
+/*
+ * Resizes the string's length. Returns the amount of characters
+ * in the specified by len.
+ *
+ * Example:
+ *
+ *     !!!c
+ *     int
+ *     main(int argc,
+ *          char **argv)
+ *     {
+ *         // Variable declaration.
+ *         mrb_value str;
+ *
+ *         mrb_state *mrb = mrb_open();
+ *         if (!mrb)
+ *         {
+ *            // handle error
+ *         }
+ *         // Creates a new string.
+ *         str = mrb_str_new_lit(mrb, "Hello, world!");
+ *         // Returns 5 characters of
+ *         mrb_str_resize(mrb, str, 5);
+ *         mrb_p(mrb, str);
+ *
+ *         mrb_close(mrb);
+ *         return 0;
+ *      }
+ *
+ * Result:
+ *
+ *     => "Hello"
+ *
+ * @param [mrb_state] mrb The current mruby state.
+ * @param [mrb_value] str The Ruby string to resize.
+ * @param [mrb_value] len The length.
+ * @return [mrb_value] An object as a Ruby string.
+ */
+MRB_API mrb_value mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len);
+
+/*
+ * Returns a sub string.
+ *
+ *  Example:
+ *
+ *     !!!c
+ *     int
+ *     main(int argc,
+ *     char const **argv)
+ *     {
+ *       // Variable declarations.
+ *       mrb_value str1;
+ *       mrb_value str2;
+ *
+ *       mrb_state *mrb = mrb_open();
+ *       if (!mrb)
+ *       {
+ *         // handle error
+ *       }
+ *       // Creates new string.
+ *       str1 = mrb_str_new_lit(mrb, "Hello, world!");
+ *       // Returns a sub-string within the range of 0..2
+ *       str2 = mrb_str_substr(mrb, str1, 0, 2);
+ *
+ *       // Prints sub-string.
+ *       mrb_p(mrb, str2);
+ *
+ *       mrb_close(mrb);
+ *       return 0;
+ *     }
+ *
+ *  Result:
+ *
+ *     => "He"
+ *
+ * @param [mrb_state] mrb The current mruby state.
+ * @param [mrb_value] str Ruby string.
+ * @param [mrb_int] beg The beginning point of the sub-string.
+ * @param [mrb_int] len The end point of the sub-string.
+ * @return [mrb_value] An object as a Ruby sub-string.
+ */
+MRB_API mrb_value mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len);
+
+/*
+ * Returns a Ruby string type.
+ *
+ *
+ * @param [mrb_state] mrb The current mruby state.
+ * @param [mrb_value] str Ruby string.
+ * @return [mrb_value] A Ruby string.
+ */
+MRB_API mrb_value mrb_string_type(mrb_state *mrb, mrb_value str);
+
+MRB_API mrb_value mrb_check_string_type(mrb_state *mrb, mrb_value str);
+MRB_API mrb_value mrb_str_buf_new(mrb_state *mrb, size_t capa);
+
+MRB_API const char *mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr);
+MRB_API const char *mrb_string_value_ptr(mrb_state *mrb, mrb_value str);
+/*
+ * Returns the length of the Ruby string.
+ *
+ *
+ * @param [mrb_state] mrb The current mruby state.
+ * @param [mrb_value] str Ruby string.
+ * @return [mrb_int] The length of the passed in Ruby string.
+ */
+MRB_API mrb_int mrb_string_value_len(mrb_state *mrb, mrb_value str);
+
+/*
+ * Duplicates a string object.
+ *
+ *
+ * @param [mrb_state] mrb The current mruby state.
+ * @param [mrb_value] str Ruby string.
+ * @return [mrb_value] Duplicated Ruby string.
+ */
+MRB_API mrb_value mrb_str_dup(mrb_state *mrb, mrb_value str);
+
+/*
+ * Returns a symbol from a passed in Ruby string.
+ *
+ * @param [mrb_state] mrb The current mruby state.
+ * @param [mrb_value] self Ruby string.
+ * @return [mrb_value] A symbol.
+ */
+MRB_API mrb_value mrb_str_intern(mrb_state *mrb, mrb_value self);
+
+MRB_API mrb_value mrb_str_to_inum(mrb_state *mrb, mrb_value str, mrb_int base, mrb_bool badcheck);
+MRB_API double mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck);
+
+/*
+ * Returns a converted string type.
+ */
+MRB_API mrb_value mrb_str_to_str(mrb_state *mrb, mrb_value str);
+
+/*
+ * Returns true if the strings match and false if the strings don't match.
+ *
+ * @param [mrb_state] mrb The current mruby state.
+ * @param [mrb_value] str1 Ruby string to compare.
+ * @param [mrb_value] str2 Ruby string to compare.
+ * @return [mrb_value] boolean value.
+ */
+MRB_API mrb_bool mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2);
+
+/*
+ * Returns a concated string comprised of a Ruby string and a C string.
+ *
+ * @param [mrb_state] mrb The current mruby state.
+ * @param [mrb_value] str Ruby string.
+ * @param [const char *] ptr A C string.
+ * @param [size_t] len length of C string.
+ * @return [mrb_value] A Ruby string.
+ * @see mrb_str_cat_cstr
+ */
+MRB_API mrb_value mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len);
+
+/*
+ * Returns a concated string comprised of a Ruby string and a C string.
+ *
+ * @param [mrb_state] mrb The current mruby state.
+ * @param [mrb_value] str Ruby string.
+ * @param [const char *] ptr A C string.
+ * @return [mrb_value] A Ruby string.
+ * @see mrb_str_cat
+ */
+MRB_API mrb_value mrb_str_cat_cstr(mrb_state *mrb, mrb_value str, const char *ptr);
+MRB_API mrb_value mrb_str_cat_str(mrb_state *mrb, mrb_value str, mrb_value str2);
+#define mrb_str_cat_lit(mrb, str, lit) mrb_str_cat(mrb, str, lit, mrb_strlen_lit(lit))
+
+/*
+ * Adds str2 to the end of str1.
+ */
+MRB_API mrb_value mrb_str_append(mrb_state *mrb, mrb_value str, mrb_value str2);
+
+/*
+ * Returns 0 if both Ruby strings are equal. Returns a value < 0 if Ruby str1 is less than Ruby str2. Returns a value > 0 if Ruby str2 is greater than Ruby str1.
+ */
+MRB_API int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2);
+
+/*
+ * Returns a newly allocated C string from a Ruby string.
+ * This is an utility function to pass a Ruby string to C library functions.
+ *
+ * - Returned string does not contain any NUL characters (but terminator).
+ * - It raises an ArgumentError exception if Ruby string contains
+ *   NUL characters.
+ * - Retured string will be freed automatically on next GC.
+ * - Caller can modify returned string without affecting Ruby string
+ *   (e.g. it can be used for mkstemp(3)).
+ *
+ * @param [mrb_state *] mrb The current mruby state.
+ * @param [mrb_value] str Ruby string. Must be an instance of String.
+ * @return [char *] A newly allocated C string.
+ */
+MRB_API char *mrb_str_to_cstr(mrb_state *mrb, mrb_value str);
+
+mrb_value mrb_str_pool(mrb_state *mrb, mrb_value str);
+mrb_int mrb_str_hash(mrb_state *mrb, mrb_value str);
+mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str);
+
+/*
+ * Returns a printable version of str, surrounded by quote marks, with special characters escaped.
+ */
+mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str);
+
+void mrb_noregexp(mrb_state *mrb, mrb_value self);
+void mrb_regexp_check(mrb_state *mrb, mrb_value obj);
+
+/* For backward compatibility */
+#define mrb_str_cat2(mrb, str, ptr) mrb_str_cat_cstr(mrb, str, ptr)
+#define mrb_str_buf_cat(mrb, str, ptr, len) mrb_str_cat(mrb, str, ptr, len)
+#define mrb_str_buf_append(mrb, str, str2) mrb_str_cat_str(mrb, str, str2)
+
+MRB_END_DECL
+
+#endif  /* MRUBY_STRING_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/throw.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/throw.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/throw.h	(revision 331)
@@ -0,0 +1,55 @@
+/*
+** mruby/throw.h - mruby exception throwing handler
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRB_THROW_H
+#define MRB_THROW_H
+
+#if defined(MRB_ENABLE_CXX_ABI)
+# if !defined(__cplusplus)
+#  error Trying to use C++ exception handling in C code
+# endif
+#endif
+
+#if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus)
+
+#define MRB_TRY(buf) do { try {
+#define MRB_CATCH(buf) } catch(mrb_jmpbuf_impl e) { if (e != (buf)->impl) { throw e; }
+#define MRB_END_EXC(buf)  } } while(0)
+
+#define MRB_THROW(buf) throw((buf)->impl)
+typedef mrb_int mrb_jmpbuf_impl;
+
+#else
+
+#include <setjmp.h>
+
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+#define MRB_SETJMP _setjmp
+#define MRB_LONGJMP _longjmp
+#else
+#define MRB_SETJMP setjmp
+#define MRB_LONGJMP longjmp
+#endif
+
+#define MRB_TRY(buf) do { if (MRB_SETJMP((buf)->impl) == 0) {
+#define MRB_CATCH(buf) } else {
+#define MRB_END_EXC(buf) } } while(0)
+
+#define MRB_THROW(buf) MRB_LONGJMP((buf)->impl, 1);
+#define mrb_jmpbuf_impl jmp_buf
+
+#endif
+
+struct mrb_jmpbuf {
+  mrb_jmpbuf_impl impl;
+
+#if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus)
+  static mrb_int jmpbuf_id;
+  mrb_jmpbuf() : impl(jmpbuf_id++) {}
+#endif
+};
+
+#endif  /* MRB_THROW_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/value.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/value.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/value.h	(revision 331)
@@ -0,0 +1,303 @@
+/*
+** mruby/value.h - mruby value definitions
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_VALUE_H
+#define MRUBY_VALUE_H
+
+#include "common.h"
+
+/**
+ * MRuby Value definition functions and macros.
+ */
+MRB_BEGIN_DECL
+
+typedef uint32_t mrb_sym;
+typedef uint8_t mrb_bool;
+struct mrb_state;
+
+#if defined(MRB_INT16) && defined(MRB_INT64)
+# error "You can't define MRB_INT16 and MRB_INT64 at the same time."
+#endif
+
+#if defined _MSC_VER && _MSC_VER < 1800
+# define PRIo64 "llo"
+# define PRId64 "lld"
+# define PRIx64 "llx"
+# define PRIo16 "ho"
+# define PRId16 "hd"
+# define PRIx16 "hx"
+# define PRIo32 "o"
+# define PRId32 "d"
+# define PRIx32 "x"
+#else
+# include <inttypes.h>
+#endif
+
+#if defined(MRB_INT64)
+  typedef int64_t mrb_int;
+# define MRB_INT_BIT 64
+# define MRB_INT_MIN (INT64_MIN>>MRB_FIXNUM_SHIFT)
+# define MRB_INT_MAX (INT64_MAX>>MRB_FIXNUM_SHIFT)
+# define MRB_PRIo PRIo64
+# define MRB_PRId PRId64
+# define MRB_PRIx PRIx64
+#elif defined(MRB_INT16)
+  typedef int16_t mrb_int;
+# define MRB_INT_BIT 16
+# define MRB_INT_MIN (INT16_MIN>>MRB_FIXNUM_SHIFT)
+# define MRB_INT_MAX (INT16_MAX>>MRB_FIXNUM_SHIFT)
+# define MRB_PRIo PRIo16
+# define MRB_PRId PRId16
+# define MRB_PRIx PRIx16
+#else
+  typedef int32_t mrb_int;
+# define MRB_INT_BIT 32
+# define MRB_INT_MIN (INT32_MIN>>MRB_FIXNUM_SHIFT)
+# define MRB_INT_MAX (INT32_MAX>>MRB_FIXNUM_SHIFT)
+# define MRB_PRIo PRIo32
+# define MRB_PRId PRId32
+# define MRB_PRIx PRIx32
+#endif
+
+
+MRB_API double mrb_float_read(const char*, char**);
+#ifdef MRB_USE_FLOAT
+  typedef float mrb_float;
+#else
+  typedef double mrb_float;
+#endif
+
+#if defined _MSC_VER && _MSC_VER < 1900
+# ifndef __cplusplus
+#  define inline __inline
+# endif
+# include <stdarg.h>
+MRB_API int mrb_msvc_vsnprintf(char *s, size_t n, const char *format, va_list arg);
+MRB_API int mrb_msvc_snprintf(char *s, size_t n, const char *format, ...);
+# define vsnprintf(s, n, format, arg) mrb_msvc_vsnprintf(s, n, format, arg)
+# define snprintf(s, n, format, ...) mrb_msvc_snprintf(s, n, format, __VA_ARGS__)
+# if _MSC_VER < 1800
+#  include <float.h>
+#  define isfinite(n) _finite(n)
+#  define isnan _isnan
+#  define isinf(n) (!_finite(n) && !_isnan(n))
+#  define signbit(n) (_copysign(1.0, (n)) < 0.0)
+static const unsigned int IEEE754_INFINITY_BITS_SINGLE = 0x7F800000;
+#  define INFINITY (*(float *)&IEEE754_INFINITY_BITS_SINGLE)
+#  define NAN ((float)(INFINITY - INFINITY))
+# endif
+#endif
+
+enum mrb_vtype {
+  MRB_TT_FALSE = 0,   /*   0 */
+  MRB_TT_FREE,        /*   1 */
+  MRB_TT_TRUE,        /*   2 */
+  MRB_TT_FIXNUM,      /*   3 */
+  MRB_TT_SYMBOL,      /*   4 */
+  MRB_TT_UNDEF,       /*   5 */
+  MRB_TT_FLOAT,       /*   6 */
+  MRB_TT_CPTR,        /*   7 */
+  MRB_TT_OBJECT,      /*   8 */
+  MRB_TT_CLASS,       /*   9 */
+  MRB_TT_MODULE,      /*  10 */
+  MRB_TT_ICLASS,      /*  11 */
+  MRB_TT_SCLASS,      /*  12 */
+  MRB_TT_PROC,        /*  13 */
+  MRB_TT_ARRAY,       /*  14 */
+  MRB_TT_HASH,        /*  15 */
+  MRB_TT_STRING,      /*  16 */
+  MRB_TT_RANGE,       /*  17 */
+  MRB_TT_EXCEPTION,   /*  18 */
+  MRB_TT_FILE,        /*  19 */
+  MRB_TT_ENV,         /*  20 */
+  MRB_TT_DATA,        /*  21 */
+  MRB_TT_FIBER,       /*  22 */
+  MRB_TT_ISTRUCT,     /*  23 */
+  MRB_TT_BREAK,       /*  24 */
+  MRB_TT_MAXDEFINE    /*  25 */
+};
+
+#include <mruby/object.h>
+
+#ifdef MRB_DOCUMENTATION_BLOCK
+
+/**
+ * @abstract
+ * MRuby value boxing.
+ *
+ * Actual implementation depends on configured boxing type.
+ *
+ * @see mruby/boxing_no.h Default boxing representation
+ * @see mruby/boxing_word.h Word representation
+ * @see mruby/boxing_nan.h Boxed double representation
+ */
+typedef void mrb_value;
+
+#endif
+
+#if defined(MRB_NAN_BOXING)
+#include "boxing_nan.h"
+#elif defined(MRB_WORD_BOXING)
+#include "boxing_word.h"
+#else
+#include "boxing_no.h"
+#endif
+
+#ifndef mrb_fixnum_p
+#define mrb_fixnum_p(o) (mrb_type(o) == MRB_TT_FIXNUM)
+#endif
+#ifndef mrb_undef_p
+#define mrb_undef_p(o) (mrb_type(o) == MRB_TT_UNDEF)
+#endif
+#ifndef mrb_nil_p
+#define mrb_nil_p(o)  (mrb_type(o) == MRB_TT_FALSE && !mrb_fixnum(o))
+#endif
+#ifndef mrb_bool
+#define mrb_bool(o)   (mrb_type(o) != MRB_TT_FALSE)
+#endif
+#define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT)
+#define mrb_symbol_p(o) (mrb_type(o) == MRB_TT_SYMBOL)
+#define mrb_array_p(o) (mrb_type(o) == MRB_TT_ARRAY)
+#define mrb_string_p(o) (mrb_type(o) == MRB_TT_STRING)
+#define mrb_hash_p(o) (mrb_type(o) == MRB_TT_HASH)
+#define mrb_cptr_p(o) (mrb_type(o) == MRB_TT_CPTR)
+#define mrb_exception_p(o) (mrb_type(o) == MRB_TT_EXCEPTION)
+#define mrb_test(o)   mrb_bool(o)
+MRB_API mrb_bool mrb_regexp_p(struct mrb_state*, mrb_value);
+
+/*
+ * Returns a float in Ruby.
+ */
+MRB_INLINE mrb_value mrb_float_value(struct mrb_state *mrb, mrb_float f)
+{
+  mrb_value v;
+  (void) mrb;
+  SET_FLOAT_VALUE(mrb, v, f);
+  return v;
+}
+
+static inline mrb_value
+mrb_cptr_value(struct mrb_state *mrb, void *p)
+{
+  mrb_value v;
+  (void) mrb;
+  SET_CPTR_VALUE(mrb,v,p);
+  return v;
+}
+
+/*
+ * Returns a fixnum in Ruby.
+ */
+MRB_INLINE mrb_value mrb_fixnum_value(mrb_int i)
+{
+  mrb_value v;
+  SET_INT_VALUE(v, i);
+  return v;
+}
+
+static inline mrb_value
+mrb_symbol_value(mrb_sym i)
+{
+  mrb_value v;
+  SET_SYM_VALUE(v, i);
+  return v;
+}
+
+static inline mrb_value
+mrb_obj_value(void *p)
+{
+  mrb_value v;
+  SET_OBJ_VALUE(v, (struct RBasic*)p);
+  mrb_assert(p == mrb_ptr(v));
+  mrb_assert(((struct RBasic*)p)->tt == mrb_type(v));
+  return v;
+}
+
+
+/*
+ * Get a nil mrb_value object.
+ *
+ * @return
+ *      nil mrb_value object reference.
+ */
+MRB_INLINE mrb_value mrb_nil_value(void)
+{
+  mrb_value v;
+  SET_NIL_VALUE(v);
+  return v;
+}
+
+/*
+ * Returns false in Ruby.
+ */
+MRB_INLINE mrb_value mrb_false_value(void)
+{
+  mrb_value v;
+  SET_FALSE_VALUE(v);
+  return v;
+}
+
+/*
+ * Returns true in Ruby.
+ */
+MRB_INLINE mrb_value mrb_true_value(void)
+{
+  mrb_value v;
+  SET_TRUE_VALUE(v);
+  return v;
+}
+
+static inline mrb_value
+mrb_bool_value(mrb_bool boolean)
+{
+  mrb_value v;
+  SET_BOOL_VALUE(v, boolean);
+  return v;
+}
+
+static inline mrb_value
+mrb_undef_value(void)
+{
+  mrb_value v;
+  SET_UNDEF_VALUE(v);
+  return v;
+}
+
+#ifdef MRB_USE_ETEXT_EDATA
+#if (defined(__APPLE__) && defined(__MACH__))
+#include <mach-o/getsect.h>
+static inline mrb_bool
+mrb_ro_data_p(const char *p)
+{
+  return (const char*)get_etext() < p && p < (const char*)get_edata();
+}
+#else
+extern char _etext[];
+#ifdef MRB_NO_INIT_ARRAY_START
+extern char _edata[];
+
+static inline mrb_bool
+mrb_ro_data_p(const char *p)
+{
+  return _etext < p && p < _edata;
+}
+#else
+extern char __init_array_start[];
+
+static inline mrb_bool
+mrb_ro_data_p(const char *p)
+{
+  return _etext < p && p < (char*)&__init_array_start;
+}
+#endif
+#endif
+#else
+# define mrb_ro_data_p(p) FALSE
+#endif
+
+MRB_END_DECL
+
+#endif  /* MRUBY_VALUE_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/variable.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/variable.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/variable.h	(revision 331)
@@ -0,0 +1,140 @@
+/*
+** mruby/variable.h - mruby variables
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_VARIABLE_H
+#define MRUBY_VARIABLE_H
+
+#include "common.h"
+
+/**
+ * Functions to access mruby variables.
+ */
+MRB_BEGIN_DECL
+
+typedef struct global_variable {
+  int   counter;
+  mrb_value *data;
+  mrb_value (*getter)(void);
+  void  (*setter)(void);
+  /* void  (*marker)(); */
+  /* int block_trace; */
+  /* struct trace_var *trace; */
+} global_variable;
+
+struct global_entry {
+  global_variable *var;
+  mrb_sym id;
+};
+
+mrb_value mrb_vm_special_get(mrb_state*, mrb_sym);
+void mrb_vm_special_set(mrb_state*, mrb_sym, mrb_value);
+mrb_value mrb_vm_iv_get(mrb_state*, mrb_sym);
+void mrb_vm_iv_set(mrb_state*, mrb_sym, mrb_value);
+mrb_value mrb_vm_cv_get(mrb_state*, mrb_sym);
+void mrb_vm_cv_set(mrb_state*, mrb_sym, mrb_value);
+mrb_value mrb_vm_const_get(mrb_state*, mrb_sym);
+void mrb_vm_const_set(mrb_state*, mrb_sym, mrb_value);
+MRB_API mrb_value mrb_const_get(mrb_state*, mrb_value, mrb_sym);
+MRB_API void mrb_const_set(mrb_state*, mrb_value, mrb_sym, mrb_value);
+MRB_API mrb_bool mrb_const_defined(mrb_state*, mrb_value, mrb_sym);
+MRB_API void mrb_const_remove(mrb_state*, mrb_value, mrb_sym);
+
+MRB_API mrb_bool mrb_iv_p(mrb_state *mrb, mrb_sym sym);
+MRB_API void mrb_iv_check(mrb_state *mrb, mrb_sym sym);
+MRB_API mrb_value mrb_obj_iv_get(mrb_state *mrb, struct RObject *obj, mrb_sym sym);
+MRB_API void mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v);
+MRB_API mrb_bool mrb_obj_iv_defined(mrb_state *mrb, struct RObject *obj, mrb_sym sym);
+MRB_API void mrb_obj_iv_ifnone(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v);
+MRB_API mrb_value mrb_iv_get(mrb_state *mrb, mrb_value obj, mrb_sym sym);
+MRB_API void mrb_iv_set(mrb_state *mrb, mrb_value obj, mrb_sym sym, mrb_value v);
+MRB_API mrb_bool mrb_iv_defined(mrb_state*, mrb_value, mrb_sym);
+MRB_API mrb_value mrb_iv_remove(mrb_state *mrb, mrb_value obj, mrb_sym sym);
+MRB_API void mrb_iv_copy(mrb_state *mrb, mrb_value dst, mrb_value src);
+MRB_API mrb_bool mrb_const_defined_at(mrb_state *mrb, mrb_value mod, mrb_sym id);
+
+/**
+ * Get a global variable. Will return nil if the var does not exist
+ *
+ * Example:
+ *
+ *     !!!ruby
+ *     # Ruby style
+ *     var = $value
+ *
+ *     !!!c
+ *     // C style
+ *     mrb_sym sym = mrb_intern_lit(mrb, "$value");
+ *     mrb_value var = mrb_gv_get(mrb, sym);
+ *
+ * @param mrb The mruby state reference
+ * @param sym The name of the global variable
+ * @return The value of that global variable. May be nil
+ */
+MRB_API mrb_value mrb_gv_get(mrb_state *mrb, mrb_sym sym);
+
+/**
+ * Set a global variable
+ *
+ * Example:
+ *
+ *     !!!ruby
+ *     # Ruby style
+ *     $value = "foo"
+ *
+ *     !!!c
+ *     // C style
+ *     mrb_sym sym = mrb_intern_lit(mrb, "$value");
+ *     mrb_gv_set(mrb, sym, mrb_str_new_lit("foo"));
+ *
+ * @param mrb The mruby state reference
+ * @param sym The name of the global variable
+ * @param val The value of the global variable
+ */
+MRB_API void mrb_gv_set(mrb_state *mrb, mrb_sym sym, mrb_value val);
+
+/**
+ * Remove a global variable.
+ *
+ * Example:
+ *
+ *     !!!ruby
+ *     # Ruby style
+ *     $value = nil
+ *
+ *     !!!c
+ *     // C style
+ *     mrb_sym sym = mrb_intern_lit(mrb, "$value");
+ *     mrb_gv_remove(mrb, sym);
+ *
+ * @param mrb The mruby state reference
+ * @param sym The name of the global variable
+ * @param val The value of the global variable
+ */
+MRB_API void mrb_gv_remove(mrb_state *mrb, mrb_sym sym);
+
+MRB_API mrb_value mrb_cv_get(mrb_state *mrb, mrb_value mod, mrb_sym sym);
+MRB_API void mrb_mod_cv_set(mrb_state *mrb, struct RClass * c, mrb_sym sym, mrb_value v);
+MRB_API void mrb_cv_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v);
+MRB_API mrb_bool mrb_cv_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym);
+mrb_value mrb_obj_iv_inspect(mrb_state*, struct RObject*);
+mrb_value mrb_mod_constants(mrb_state *mrb, mrb_value mod);
+mrb_value mrb_f_global_variables(mrb_state *mrb, mrb_value self);
+mrb_value mrb_obj_instance_variables(mrb_state*, mrb_value);
+mrb_value mrb_mod_class_variables(mrb_state*, mrb_value);
+mrb_value mrb_mod_cv_get(mrb_state *mrb, struct RClass * c, mrb_sym sym);
+mrb_bool mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym);
+mrb_sym mrb_class_sym(mrb_state *mrb, struct RClass *c, struct RClass *outer);
+
+/* GC functions */
+void mrb_gc_mark_gv(mrb_state*);
+void mrb_gc_free_gv(mrb_state*);
+void mrb_gc_mark_iv(mrb_state*, struct RObject*);
+size_t mrb_gc_mark_iv_size(mrb_state*, struct RObject*);
+void mrb_gc_free_iv(mrb_state*, struct RObject*);
+
+MRB_END_DECL
+
+#endif  /* MRUBY_VARIABLE_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/version.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/version.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/include/mruby/version.h	(revision 331)
@@ -0,0 +1,110 @@
+/*
+** mruby/version.h - mruby version definition
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_VERSION_H
+#define MRUBY_VERSION_H
+
+#include "common.h"
+
+/**
+ * mruby version definition macros
+ */
+MRB_BEGIN_DECL
+
+/*
+ * A passed in expression.
+ */
+#define MRB_STRINGIZE0(expr) #expr
+
+/*
+ * Passes in an expression to MRB_STRINGIZE0.
+ */
+#define MRB_STRINGIZE(expr) MRB_STRINGIZE0(expr)
+
+/*
+ * The version of Ruby used by mruby.
+ */
+#define MRUBY_RUBY_VERSION "1.9"
+
+/*
+ * Ruby engine.
+ */
+#define MRUBY_RUBY_ENGINE  "mruby"
+
+/*
+ * Major release version number.
+ */
+#define MRUBY_RELEASE_MAJOR 1
+
+/*
+ * Minor release version number.
+ */
+#define MRUBY_RELEASE_MINOR 3
+
+/*
+ * Tiny release version number.
+ */
+#define MRUBY_RELEASE_TEENY 0
+
+/*
+ * The mruby version.
+ */
+#define MRUBY_VERSION MRB_STRINGIZE(MRUBY_RELEASE_MAJOR) "." MRB_STRINGIZE(MRUBY_RELEASE_MINOR) "." MRB_STRINGIZE(MRUBY_RELEASE_TEENY)
+
+/*
+ * Release number.
+ */
+#define MRUBY_RELEASE_NO (MRUBY_RELEASE_MAJOR * 100 * 100 + MRUBY_RELEASE_MINOR * 100 + MRUBY_RELEASE_TEENY)
+
+/*
+ * Release year.
+ */
+#define MRUBY_RELEASE_YEAR 2017
+
+/*
+ * Release month.
+ */
+#define MRUBY_RELEASE_MONTH 7
+
+/*
+ * Release day.
+ */
+#define MRUBY_RELEASE_DAY 4
+
+/*
+ * Release date as a string.
+ */
+#define MRUBY_RELEASE_DATE MRB_STRINGIZE(MRUBY_RELEASE_YEAR) "-" MRB_STRINGIZE(MRUBY_RELEASE_MONTH) "-" MRB_STRINGIZE(MRUBY_RELEASE_DAY)
+
+/*
+ * The year mruby was first created.
+ */
+#define MRUBY_BIRTH_YEAR 2010
+
+/*
+ * MRuby's authors.
+ */
+#define MRUBY_AUTHOR "mruby developers"
+
+/*
+ * mruby's version, and release date.
+ */
+#define MRUBY_DESCRIPTION      \
+  "mruby " MRUBY_VERSION       \
+  " (" MRUBY_RELEASE_DATE ") " \
+
+/*
+ * mruby's copyright information.
+ */
+#define MRUBY_COPYRIGHT                \
+  "mruby - Copyright (c) "             \
+  MRB_STRINGIZE(MRUBY_BIRTH_YEAR)"-"   \
+  MRB_STRINGIZE(MRUBY_RELEASE_YEAR)" " \
+  MRUBY_AUTHOR                         \
+
+MRB_END_DECL
+
+#endif  /* MRUBY_VERSION_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/lib/mruby/source.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/lib/mruby/source.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/lib/mruby/source.rb	(revision 331)
@@ -0,0 +1,30 @@
+require "pathname"
+
+module MRuby
+  module Source
+    # MRuby's source root directory
+    ROOT = Pathname.new(File.expand_path('../../../',__FILE__))
+
+    # Reads a constant defined at version.h
+    MRUBY_READ_VERSION_CONSTANT = Proc.new { |name| ROOT.join('include','mruby','version.h').read.match(/^#define #{name} +"?([\w\. ]+)"?$/)[1] }
+
+    MRUBY_RUBY_VERSION = MRUBY_READ_VERSION_CONSTANT['MRUBY_RUBY_VERSION']
+    MRUBY_RUBY_ENGINE = MRUBY_READ_VERSION_CONSTANT['MRUBY_RUBY_ENGINE']
+
+    MRUBY_RELEASE_MAJOR = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_RELEASE_MAJOR'])
+    MRUBY_RELEASE_MINOR = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_RELEASE_MINOR'])
+    MRUBY_RELEASE_TEENY = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_RELEASE_TEENY'])
+
+    MRUBY_VERSION = [MRUBY_RELEASE_MAJOR,MRUBY_RELEASE_MINOR,MRUBY_RELEASE_TEENY].join('.')
+    MRUBY_RELEASE_NO = (MRUBY_RELEASE_MAJOR * 100 * 100 + MRUBY_RELEASE_MINOR * 100 + MRUBY_RELEASE_TEENY)
+
+    MRUBY_RELEASE_YEAR = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_RELEASE_YEAR'])
+    MRUBY_RELEASE_MONTH = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_RELEASE_MONTH'])
+    MRUBY_RELEASE_DAY = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_RELEASE_DAY'])
+    MRUBY_RELEASE_DATE = [MRUBY_RELEASE_YEAR,MRUBY_RELEASE_MONTH,MRUBY_RELEASE_DAY].join('.')
+
+    MRUBY_BIRTH_YEAR = Integer(MRUBY_READ_VERSION_CONSTANT['MRUBY_BIRTH_YEAR'])
+
+    MRUBY_AUTHOR = MRUBY_READ_VERSION_CONSTANT['MRUBY_AUTHOR']
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/minirake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/minirake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/minirake	(revision 331)
@@ -0,0 +1,487 @@
+#!/usr/bin/env ruby
+
+# Original is https://github.com/jimweirich/rake/
+# Copyright (c) 2003 Jim Weirich
+# License: MIT-LICENSE
+
+require 'getoptlong'
+require 'fileutils'
+
+class String
+  def ext(newext='')
+    return self.dup if ['.', '..'].include? self
+    if newext != ''
+      newext = (newext =~ /^\./) ? newext : ("." + newext)
+    end
+    self.chomp(File.extname(self)) << newext
+  end
+
+  def pathmap(spec=nil, &block)
+    return self if spec.nil?
+    result = ''
+    spec.scan(/%\{[^}]*\}-?\d*[sdpfnxX%]|%-?\d+d|%.|[^%]+/) do |frag|
+      case frag
+      when '%f'
+        result << File.basename(self)
+      when '%n'
+        result << File.basename(self).ext
+      when '%d'
+        result << File.dirname(self)
+      when '%x'
+        result << File.extname(self)
+      when '%X'
+        result << self.ext
+      when '%p'
+        result << self
+      when '%s'
+        result << (File::ALT_SEPARATOR || File::SEPARATOR)
+      when '%-'
+        # do nothing
+      when '%%'
+        result << "%"
+      when /%(-?\d+)d/
+        result << pathmap_partial($1.to_i)
+      when /^%\{([^}]*)\}(\d*[dpfnxX])/
+        patterns, operator = $1, $2
+        result << pathmap('%' + operator).pathmap_replace(patterns, &block)
+      when /^%/
+        fail ArgumentError, "Unknown pathmap specifier #{frag} in '#{spec}'"
+      else
+        result << frag
+      end
+    end
+    result
+  end
+end
+
+module MiniRake
+  class Task
+    TASKS = Hash.new
+    RULES = Array.new
+
+    # List of prerequisites for a task.
+    attr_reader :prerequisites
+
+    # Source dependency for rule synthesized tasks.  Nil if task was not
+    # sythesized from a rule.
+    attr_accessor :source
+
+    # Create a task named +task_name+ with no actions or prerequisites..
+    # use +enhance+ to add actions and prerequisites.
+    def initialize(task_name)
+      @name = task_name
+      @prerequisites = []
+      @actions = []
+    end
+
+    # Enhance a task with prerequisites or actions.  Returns self.
+    def enhance(deps=nil, &block)
+      @prerequisites |= deps if deps
+      @actions << block if block_given?
+      self
+    end
+
+    # Name of the task.
+    def name
+      @name.to_s
+    end
+
+    # Invoke the task if it is needed.  Prerequites are invoked first.
+    def invoke
+      puts "Invoke #{name} (already=[#{@already_invoked}], needed=[#{needed?}])" if $trace
+      return if @already_invoked
+      @already_invoked = true
+      prerequisites = @prerequisites.collect{ |n| n.is_a?(Proc) ? n.call(name) : n }.flatten
+      prerequisites.each { |n| Task[n].invoke }
+      execute if needed?
+    end
+
+    # Execute the actions associated with this task.
+    def execute
+      puts "Execute #{name}" if $trace
+      self.class.enhance_with_matching_rule(name) if @actions.empty?
+      unless $dryrun
+        @actions.each { |act| act.call(self) }
+      end
+    end
+
+    # Is this task needed?
+    def needed?
+      true
+    end
+
+    # Timestamp for this task.  Basic tasks return the current time for
+    # their time stamp.  Other tasks can be more sophisticated.
+    def timestamp
+      Time.now
+    end
+
+    # Class Methods ----------------------------------------------------
+
+    class << self
+
+      # Clear the task list.  This cause rake to immediately forget all
+      # the tasks that have been assigned.  (Normally used in the unit
+      # tests.)
+      def clear
+        TASKS.clear
+        RULES.clear
+      end
+
+      # List of all defined tasks.
+      def tasks
+        TASKS.keys.sort.collect { |tn| Task[tn] }
+      end
+
+      # Return a task with the given name.  If the task is not currently
+      # known, try to synthesize one from the defined rules.  If no
+      # rules are found, but an existing file matches the task name,
+      # assume it is a file task with no dependencies or actions.
+      def [](task_name)
+        task_name = task_name.to_s
+        if task_name.end_with?(":")
+          task_name = task_name.slice(0, task_name.length - 1)
+        end
+        if task = TASKS[task_name]
+          return task
+        end
+        if task = enhance_with_matching_rule(task_name)
+          return task
+        end
+        if File.exist?(task_name)
+          return FileTask.define_task(task_name)
+        end
+        fail "Don't know how to rake #{task_name}"
+      end
+
+      # Define a task given +args+ and an option block.  If a rule with
+      # the given name already exists, the prerequisites and actions are
+      # added to the existing task.
+      def define_task(args, &block)
+        task_name, deps = resolve_args(args)
+        lookup(task_name).enhance([deps].flatten, &block)
+      end
+
+      # Define a rule for synthesizing tasks.
+      def create_rule(args, &block)
+        pattern, deps = resolve_args(args)
+        pattern = Regexp.new(Regexp.quote(pattern) + '$') if String === pattern
+        RULES << [pattern, deps, block]
+      end
+
+
+      # Lookup a task.  Return an existing task if found, otherwise
+      # create a task of the current type.
+      def lookup(task_name)
+        name = task_name.to_s
+        TASKS[name] ||= self.new(name)
+      end
+
+      # If a rule can be found that matches the task name, enhance the
+      # task with the prerequisites and actions from the rule.  Set the
+      # source attribute of the task appropriately for the rule.  Return
+      # the enhanced task or nil of no rule was found.
+      def enhance_with_matching_rule(task_name)
+        RULES.each do |pattern, extensions, block|
+          if pattern.match(task_name)
+            ext = extensions.first
+            deps = extensions[1..-1]
+            case ext
+            when String
+              source = task_name.sub(/\.[^.]*$/, ext)
+            when Proc
+              source = ext.call(task_name)
+            else
+              fail "Don't know how to handle rule dependent: #{ext.inspect}"
+            end
+            if File.exist?(source)
+              task = FileTask.define_task({task_name => [source]+deps}, &block)
+              task.source = source
+              return task
+            end
+          end
+        end
+        nil
+      end
+
+      private
+
+      # Resolve the arguments for a task/rule.
+      def resolve_args(args)
+        case args
+        when Hash
+          fail "Too Many Task Names: #{args.keys.join(' ')}" if args.size > 1
+          fail "No Task Name Given" if args.size < 1
+          task_name = args.keys[0]
+          deps = args[task_name]
+          deps = [deps] if (String===deps) || (Regexp===deps) || (Proc===deps)
+        else
+          task_name = args
+          deps = []
+        end
+        [task_name, deps]
+      end
+    end
+  end
+
+
+  ######################################################################
+  class FileTask < Task
+    # Is this file task needed?  Yes if it doesn't exist, or if its time
+    # stamp is out of date.
+    def needed?
+      return true unless File.exist?(name)
+      prerequisites = @prerequisites.collect{ |n| n.is_a?(Proc) ? n.call(name) : n }.flatten
+      latest_prereq = prerequisites.collect{|n| Task[n].timestamp}.max
+      return false if latest_prereq.nil?
+      timestamp < latest_prereq
+    end
+
+    # Time stamp for file task.
+    def timestamp
+      return Time.at(0) unless File.exist?(name)
+      stat = File::stat(name.to_s)
+      stat.directory? ? Time.at(0) : stat.mtime
+    end
+  end
+
+  module DSL
+    # Declare a basic task.
+    def task(args, &block)
+      MiniRake::Task.define_task(args, &block)
+    end
+
+    # Declare a file task.
+    def file(args, &block)
+      MiniRake::FileTask.define_task(args, &block)
+    end
+
+    # Declare a set of files tasks to create the given directories on
+    # demand.
+    def directory(args, &block)
+      MiniRake::FileTask.define_task(args) do |t|
+        block.call(t) unless block.nil?
+        dir = args.is_a?(Hash) ? args.keys.first : args
+        (dir.split(File::SEPARATOR) + ['']).inject do |acc, part|
+          (acc + File::SEPARATOR).tap do |d|
+            Dir.mkdir(d) unless File.exists? d
+          end + part
+        end
+      end
+    end
+
+    # Declare a rule for auto-tasks.
+    def rule(args, &block)
+      MiniRake::Task.create_rule(args, &block)
+    end
+
+    # Write a message to standard out if $verbose is enabled.
+    def log(msg)
+      print "  " if $trace && $verbose
+      puts msg if $verbose
+    end
+
+    # Run the system command +cmd+.
+    def sh(cmd)
+      puts cmd if $verbose
+      system(cmd) or fail "Command Failed: [#{cmd}]"
+    end
+
+    def desc(text)
+    end
+  end
+end
+
+Rake = MiniRake
+extend MiniRake::DSL
+
+
+######################################################################
+# Task Definition Functions ...
+
+######################################################################
+# Rake main application object.  When invoking +rake+ from the command
+# line, a RakeApp object is created and run.
+#
+class RakeApp
+  RAKEFILES = ['rakefile', 'Rakefile']
+
+  OPTIONS = [
+    ['--dry-run',  '-n', GetoptLong::NO_ARGUMENT,
+      "Do a dry run without executing actions."],
+    ['--help',     '-H', GetoptLong::NO_ARGUMENT,
+      "Display this help message."],
+    ['--libdir',   '-I', GetoptLong::REQUIRED_ARGUMENT,
+      "Include LIBDIR in the search path for required modules."],
+    ['--nosearch', '-N', GetoptLong::NO_ARGUMENT,
+      "Do not search parent directories for the Rakefile."],
+    ['--quiet',    '-q', GetoptLong::NO_ARGUMENT,
+      "Do not log messages to standard output (default)."],
+    ['--rakefile', '-f', GetoptLong::REQUIRED_ARGUMENT,
+      "Use FILE as the rakefile."],
+    ['--require',  '-r', GetoptLong::REQUIRED_ARGUMENT,
+      "Require MODULE before executing rakefile."],
+    ['--tasks',    '-T', GetoptLong::NO_ARGUMENT,
+      "Display the tasks and dependencies, then exit."],
+    ['--pull-gems','-p', GetoptLong::NO_ARGUMENT,
+      "Pull all git mrbgems."],
+    ['--trace',    '-t', GetoptLong::NO_ARGUMENT,
+      "Turn on invoke/execute tracing."],
+    ['--usage',    '-h', GetoptLong::NO_ARGUMENT,
+      "Display usage."],
+    ['--verbose',  '-v', GetoptLong::NO_ARGUMENT,
+      "Log message to standard output."],
+    ['--directory', '-C', GetoptLong::REQUIRED_ARGUMENT,
+      "Change executing directory of rakefiles."]
+  ]
+
+  # Create a RakeApp object.
+  def initialize
+    @rakefile = nil
+    @nosearch = false
+  end
+
+  # True if one of the files in RAKEFILES is in the current directory.
+  # If a match is found, it is copied into @rakefile.
+  def have_rakefile
+    RAKEFILES.each do |fn|
+      if File.exist?(fn)
+        @rakefile = fn
+        return true
+      end
+    end
+    return false
+  end
+
+  # Display the program usage line.
+  def usage
+      puts "rake [-f rakefile] {options} targets..."
+  end
+
+  # Display the rake command line help.
+  def help
+    usage
+    puts
+    puts "Options are ..."
+    puts
+    OPTIONS.sort.each do |long, short, mode, desc|
+      if mode == GetoptLong::REQUIRED_ARGUMENT
+        if desc =~ /\b([A-Z]{2,})\b/
+          long = long + "=#{$1}"
+        end
+      end
+      printf "  %-20s (%s)\n", long, short
+      printf "      %s\n", desc
+    end
+  end
+
+  # Display the tasks and dependencies.
+  def display_tasks
+    MiniRake::Task.tasks.each do |t|
+      puts "#{t.class} #{t.name}"
+      t.prerequisites.each { |pre| puts "    #{pre}" }
+    end
+  end
+
+  # Return a list of the command line options supported by the
+  # program.
+  def command_line_options
+    OPTIONS.collect { |lst| lst[0..-2] }
+  end
+
+  # Do the option defined by +opt+ and +value+.
+  def do_option(opt, value)
+    case opt
+    when '--dry-run'
+      $dryrun = true
+      $trace = true
+    when '--help'
+      help
+      exit
+    when '--libdir'
+      $:.push(value)
+    when '--nosearch'
+      @nosearch = true
+    when '--quiet'
+      $verbose = false
+    when '--rakefile'
+      RAKEFILES.clear
+      RAKEFILES << value
+    when '--require'
+      require value
+    when '--tasks'
+      $show_tasks = true
+    when '--pull-gems'
+      $pull_gems = true
+    when '--trace'
+      $trace = true
+    when '--usage'
+      usage
+      exit
+    when '--verbose'
+      $verbose = true
+    when '--version'
+      puts "rake, version #{RAKEVERSION}"
+      exit
+    when '--directory'
+      Dir.chdir value
+    else
+      fail "Unknown option: #{opt}"
+    end
+  end
+
+  # Read and handle the command line options.
+  def handle_options
+    $verbose = false
+    $pull_gems = false
+    opts = GetoptLong.new(*command_line_options)
+    opts.each { |opt, value| do_option(opt, value) }
+  end
+
+  # Run the +rake+ application.
+  def run
+    handle_options
+    begin
+      here = Dir.pwd
+      while ! have_rakefile
+        Dir.chdir("..")
+        if Dir.pwd == here || @nosearch
+          fail "No Rakefile found (looking for: #{RAKEFILES.join(', ')})"
+        end
+        here = Dir.pwd
+      end
+      tasks = []
+      ARGV.each do |task_name|
+        if /^(\w+)=(.*)/.match(task_name)
+          ENV[$1] = $2
+        else
+          tasks << task_name
+        end
+      end
+      puts "(in #{Dir.pwd})"
+      $rakefile = @rakefile
+      load @rakefile
+      if $show_tasks
+        display_tasks
+      else
+        tasks.push("default") if tasks.size == 0
+        tasks.each do |task_name|
+          MiniRake::Task[task_name].invoke
+        end
+      end
+    rescue Exception => ex
+      puts "rake aborted!"
+      puts ex.message
+      if $trace
+        puts ex.backtrace.join("\n")
+      else
+        puts ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || ""
+      end
+      exit 1
+    end
+  end
+end
+
+if __FILE__ == $0 then
+  RakeApp.new.run
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/default.gembox
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/default.gembox	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/default.gembox	(revision 331)
@@ -0,0 +1,79 @@
+MRuby::GemBox.new do |conf|
+  # Use standard Kernel#sprintf method
+  conf.gem :core => "mruby-sprintf"
+
+  # Use standard print/puts/p
+  conf.gem :core => "mruby-print"
+
+  # Use standard Math module
+  conf.gem :core => "mruby-math"
+
+  # Use standard Time class
+  conf.gem :core => "mruby-time"
+
+  # Use standard Struct class
+  conf.gem :core => "mruby-struct"
+
+  # Use Enumerable module extension
+  conf.gem :core => "mruby-enum-ext"
+
+  # Use String class extension
+  conf.gem :core => "mruby-string-ext"
+
+  # Use Numeric class extension
+  conf.gem :core => "mruby-numeric-ext"
+
+  # Use Array class extension
+  conf.gem :core => "mruby-array-ext"
+
+  # Use Hash class extension
+  conf.gem :core => "mruby-hash-ext"
+
+  # Use Range class extension
+  conf.gem :core => "mruby-range-ext"
+
+  # Use Proc class extension
+  conf.gem :core => "mruby-proc-ext"
+
+  # Use Symbol class extension
+  conf.gem :core => "mruby-symbol-ext"
+
+  # Use Random class
+  conf.gem :core => "mruby-random"
+
+  # Use Object class extension
+  conf.gem :core => "mruby-object-ext"
+
+  # Use ObjectSpace class
+  conf.gem :core => "mruby-objectspace"
+
+  # Use Fiber class
+  conf.gem :core => "mruby-fiber"
+
+  # Use Enumerator class (require mruby-fiber)
+  conf.gem :core => "mruby-enumerator"
+
+  # Use Enumerator::Lazy class (require mruby-enumerator)
+  conf.gem :core => "mruby-enum-lazy"
+
+  # Use toplevel object (main) methods extension
+  conf.gem :core => "mruby-toplevel-ext"
+
+  # Generate mirb command
+  conf.gem :core => "mruby-bin-mirb"
+
+  # Generate mruby command
+  conf.gem :core => "mruby-bin-mruby"
+
+  # Generate mruby-strip command
+  conf.gem :core => "mruby-bin-strip"
+
+  # Use Kernel module extension
+  conf.gem :core => "mruby-kernel-ext"
+
+  # Use class/module extension
+  conf.gem :core => "mruby-class-ext"
+
+  # Use mruby-compiler to build other mrbgems
+  conf.gem :core => "mruby-compiler"
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/full-core.gembox
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/full-core.gembox	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/full-core.gembox	(revision 331)
@@ -0,0 +1,9 @@
+MRuby::GemBox.new do |conf|
+  conf.gem :core => "mruby-sprintf"
+  conf.gem :core => "mruby-print"
+
+  Dir.glob("#{root}/mrbgems/mruby-*/mrbgem.rake") do |x|
+    g = File.basename File.dirname x
+    conf.gem :core => g unless g =~ /^mruby-(print|sprintf|bin-debugger|test)$/
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-array-ext/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-array-ext/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-array-ext/mrbgem.rake	(revision 331)
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-array-ext') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'Array class extension'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-array-ext/mrblib/array.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-array-ext/mrblib/array.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-array-ext/mrblib/array.rb	(revision 331)
@@ -0,0 +1,765 @@
+class Array
+  ##
+  # call-seq:
+  #    Array.try_convert(obj) -> array or nil
+  #
+  # Tries to convert +obj+ into an array, using +to_ary+ method.
+  # converted array or +nil+ if +obj+ cannot be converted for any reason.
+  # This method can be used to check if an argument is an array.
+  #
+  #    Array.try_convert([1])   #=> [1]
+  #    Array.try_convert("1")   #=> nil
+  #
+  #    if tmp = Array.try_convert(arg)
+  #      # the argument is an array
+  #    elsif tmp = String.try_convert(arg)
+  #      # the argument is a string
+  #    end
+  #
+  def self.try_convert(obj)
+    if obj.respond_to?(:to_ary)
+      obj.to_ary
+    else
+      nil
+    end
+  end
+
+  ##
+  # call-seq:
+  #    ary.uniq!                -> ary or nil
+  #    ary.uniq! { |item| ... } -> ary or nil
+  #
+  # Removes duplicate elements from +self+.
+  # Returns <code>nil</code> if no changes are made (that is, no
+  # duplicates are found).
+  #
+  #    a = [ "a", "a", "b", "b", "c" ]
+  #    a.uniq!   #=> ["a", "b", "c"]
+  #    b = [ "a", "b", "c" ]
+  #    b.uniq!   #=> nil
+  #    c = [["student","sam"], ["student","george"], ["teacher","matz"]]
+  #    c.uniq! { |s| s.first } # => [["student", "sam"], ["teacher", "matz"]]
+  #
+  def uniq!(&block)
+    ary = self.dup
+    result = []
+    if block
+      hash = {}
+      while ary.size > 0
+        val = ary.shift
+        key = block.call(val)
+        hash[key] = val unless hash.has_key?(key)
+      end
+      hash.each_value do |value|
+        result << value
+      end
+    else
+      while ary.size > 0
+        result << ary.shift
+        ary.delete(result.last)
+      end
+    end
+    if result.size == self.size
+      nil
+    else
+      self.replace(result)
+    end
+  end
+
+  ##
+  # call-seq:
+  #    ary.uniq                -> new_ary
+  #    ary.uniq { |item| ... } -> new_ary
+  #
+  # Returns a new array by removing duplicate values in +self+.
+  #
+  #    a = [ "a", "a", "b", "b", "c" ]
+  #    a.uniq   #=> ["a", "b", "c"]
+  #
+  #    b = [["student","sam"], ["student","george"], ["teacher","matz"]]
+  #    b.uniq { |s| s.first } # => [["student", "sam"], ["teacher", "matz"]]
+  #
+  def uniq(&block)
+    ary = self.dup
+    if block
+      ary.uniq!(&block)
+    else
+      ary.uniq!
+    end
+    ary
+  end
+
+  ##
+  # call-seq:
+  #    ary - other_ary    -> new_ary
+  #
+  # Array Difference---Returns a new array that is a copy of
+  # the original array, removing any items that also appear in
+  # <i>other_ary</i>. (If you need set-like behavior, see the
+  # library class Set.)
+  #
+  #    [ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ]  #=>  [ 3, 3, 5 ]
+  #
+  def -(elem)
+    raise TypeError, "can't convert #{elem.class} into Array" unless elem.class == Array
+
+    hash = {}
+    array = []
+    elem.each { |x| hash[x] = true }
+    self.each { |x| array << x unless hash[x] }
+    array
+  end
+
+  ##
+  # call-seq:
+  #    ary | other_ary     -> new_ary
+  #
+  # Set Union---Returns a new array by joining this array with
+  # <i>other_ary</i>, removing duplicates.
+  #
+  #    [ "a", "b", "c" ] | [ "c", "d", "a" ]
+  #           #=> [ "a", "b", "c", "d" ]
+  #
+  def |(elem)
+    raise TypeError, "can't convert #{elem.class} into Array" unless elem.class == Array
+
+    ary = self + elem
+    ary.uniq! or ary
+  end
+
+  ##
+  # call-seq:
+  #    ary & other_ary      -> new_ary
+  #
+  # Set Intersection---Returns a new array
+  # containing elements common to the two arrays, with no duplicates.
+  #
+  #    [ 1, 1, 3, 5 ] & [ 1, 2, 3 ]   #=> [ 1, 3 ]
+  #
+  def &(elem)
+    raise TypeError, "can't convert #{elem.class} into Array" unless elem.class == Array
+
+    hash = {}
+    array = []
+    elem.each{|v| hash[v] = true }
+    self.each do |v|
+      if hash[v]
+        array << v
+        hash.delete v
+      end
+    end
+    array
+  end
+
+  ##
+  # call-seq:
+  #    ary.flatten -> new_ary
+  #    ary.flatten(level) -> new_ary
+  #
+  # Returns a new array that is a one-dimensional flattening of this
+  # array (recursively). That is, for every element that is an array,
+  # extract its elements into the new array.  If the optional
+  # <i>level</i> argument determines the level of recursion to flatten.
+  #
+  #    s = [ 1, 2, 3 ]           #=> [1, 2, 3]
+  #    t = [ 4, 5, 6, [7, 8] ]   #=> [4, 5, 6, [7, 8]]
+  #    a = [ s, t, 9, 10 ]       #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
+  #    a.flatten                 #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+  #    a = [ 1, 2, [3, [4, 5] ] ]
+  #    a.flatten(1)              #=> [1, 2, 3, [4, 5]]
+  #
+  def flatten(depth=nil)
+    ar = []
+    self.each do |e|
+      if e.is_a?(Array) && (depth.nil? || depth > 0)
+        ar += e.flatten(depth.nil? ? nil : depth - 1)
+      else
+        ar << e
+      end
+    end
+    ar
+  end
+
+  ##
+  # call-seq:
+  #    ary.flatten!        -> ary or nil
+  #    ary.flatten!(level) -> array or nil
+  #
+  # Flattens +self+ in place.
+  # Returns <code>nil</code> if no modifications were made (i.e.,
+  # <i>ary</i> contains no subarrays.)  If the optional <i>level</i>
+  # argument determines the level of recursion to flatten.
+  #
+  #    a = [ 1, 2, [3, [4, 5] ] ]
+  #    a.flatten!   #=> [1, 2, 3, 4, 5]
+  #    a.flatten!   #=> nil
+  #    a            #=> [1, 2, 3, 4, 5]
+  #    a = [ 1, 2, [3, [4, 5] ] ]
+  #    a.flatten!(1) #=> [1, 2, 3, [4, 5]]
+  #
+  def flatten!(depth=nil)
+    modified = false
+    ar = []
+    self.each do |e|
+      if e.is_a?(Array) && (depth.nil? || depth > 0)
+        ar += e.flatten(depth.nil? ? nil : depth - 1)
+        modified = true
+      else
+        ar << e
+      end
+    end
+    if modified
+      self.replace(ar)
+    else
+      nil
+    end
+  end
+
+  ##
+  # call-seq:
+  #    ary.compact     -> new_ary
+  #
+  # Returns a copy of +self+ with all +nil+ elements removed.
+  #
+  #    [ "a", nil, "b", nil, "c", nil ].compact
+  #                      #=> [ "a", "b", "c" ]
+  #
+  def compact
+    result = self.dup
+    result.compact!
+    result
+  end
+
+  ##
+  # call-seq:
+  #    ary.compact!    -> ary  or  nil
+  #
+  # Removes +nil+ elements from the array.
+  # Returns +nil+ if no changes were made, otherwise returns
+  # <i>ary</i>.
+  #
+  #    [ "a", nil, "b", nil, "c" ].compact! #=> [ "a", "b", "c" ]
+  #    [ "a", "b", "c" ].compact!           #=> nil
+  #
+  def compact!
+    result = self.select { |e| !e.nil? }
+    if result.size == self.size
+      nil
+    else
+      self.replace(result)
+    end
+  end
+
+  # for efficiency
+  def reverse_each(&block)
+    return to_enum :reverse_each unless block_given?
+
+    i = self.size - 1
+    while i>=0
+      block.call(self[i])
+      i -= 1
+    end
+    self
+  end
+
+  NONE=Object.new
+  ##
+  #  call-seq:
+  #     ary.fetch(index)                    -> obj
+  #     ary.fetch(index, default)           -> obj
+  #     ary.fetch(index) { |index| block }  -> obj
+  #
+  #  Tries to return the element at position +index+, but throws an IndexError
+  #  exception if the referenced +index+ lies outside of the array bounds.  This
+  #  error can be prevented by supplying a second argument, which will act as a
+  #  +default+ value.
+  #
+  #  Alternatively, if a block is given it will only be executed when an
+  #  invalid +index+ is referenced.
+  #
+  #  Negative values of +index+ count from the end of the array.
+  #
+  #     a = [ 11, 22, 33, 44 ]
+  #     a.fetch(1)               #=> 22
+  #     a.fetch(-1)              #=> 44
+  #     a.fetch(4, 'cat')        #=> "cat"
+  #     a.fetch(100) { |i| puts "#{i} is out of bounds" }
+  #                              #=> "100 is out of bounds"
+  #
+
+  def fetch(n=nil, ifnone=NONE, &block)
+    warn "block supersedes default value argument" if !n.nil? && ifnone != NONE && block
+
+    idx = n
+    if idx < 0
+      idx += size
+    end
+    if idx < 0 || size <= idx
+      return block.call(n) if block
+      if ifnone == NONE
+        raise IndexError, "index #{n} outside of array bounds: #{-size}...#{size}"
+      end
+      return ifnone
+    end
+    self[idx]
+  end
+
+  ##
+  #  call-seq:
+  #     ary.fill(obj)                                 -> ary
+  #     ary.fill(obj, start [, length])               -> ary
+  #     ary.fill(obj, range )                         -> ary
+  #     ary.fill { |index| block }                    -> ary
+  #     ary.fill(start [, length] ) { |index| block } -> ary
+  #     ary.fill(range) { |index| block }             -> ary
+  #
+  #  The first three forms set the selected elements of +self+ (which
+  #  may be the entire array) to +obj+.
+  #
+  #  A +start+ of +nil+ is equivalent to zero.
+  #
+  #  A +length+ of +nil+ is equivalent to the length of the array.
+  #
+  #  The last three forms fill the array with the value of the given block,
+  #  which is passed the absolute index of each element to be filled.
+  #
+  #  Negative values of +start+ count from the end of the array, where +-1+ is
+  #  the last element.
+  #
+  #     a = [ "a", "b", "c", "d" ]
+  #     a.fill("x")              #=> ["x", "x", "x", "x"]
+  #     a.fill("w", -1)          #=> ["x", "x", "x", "w"]
+  #     a.fill("z", 2, 2)        #=> ["x", "x", "z", "z"]
+  #     a.fill("y", 0..1)        #=> ["y", "y", "z", "z"]
+  #     a.fill { |i| i*i }       #=> [0, 1, 4, 9]
+  #     a.fill(-2) { |i| i*i*i } #=> [0, 1, 8, 27]
+  #     a.fill(1, 2) { |i| i+1 } #=> [0, 2, 3, 27]
+  #     a.fill(0..1) { |i| i+1 } #=> [1, 2, 3, 27]
+  #
+
+  def fill(arg0=nil, arg1=nil, arg2=nil, &block)
+    if arg0.nil? && arg1.nil? && arg2.nil? && !block
+      raise ArgumentError, "wrong number of arguments (0 for 1..3)"
+    end
+
+    beg = len = 0
+    ary = []
+    if block
+      if arg0.nil? && arg1.nil? && arg2.nil?
+        # ary.fill { |index| block }                    -> ary
+        beg = 0
+        len = self.size
+      elsif !arg0.nil? && arg0.kind_of?(Range)
+        # ary.fill(range) { |index| block }             -> ary
+        beg = arg0.begin
+        beg += self.size if beg < 0
+        len = arg0.end
+        len += self.size if len < 0
+        len += 1 unless arg0.exclude_end?
+      elsif !arg0.nil?
+        # ary.fill(start [, length] ) { |index| block } -> ary
+        beg = arg0
+        beg += self.size if beg < 0
+        if arg1.nil?
+          len = self.size
+        else
+          len = arg0 + arg1
+        end
+      end
+    else
+      if !arg0.nil? && arg1.nil? && arg2.nil?
+        # ary.fill(obj)                                 -> ary
+        beg = 0
+        len = self.size
+      elsif !arg0.nil? && !arg1.nil? && arg1.kind_of?(Range)
+        # ary.fill(obj, range )                         -> ary
+        beg = arg1.begin
+        beg += self.size if beg < 0
+        len = arg1.end
+        len += self.size if len < 0
+        len += 1 unless arg1.exclude_end?
+      elsif !arg0.nil? && !arg1.nil?
+        # ary.fill(obj, start [, length])               -> ary
+        beg = arg1
+        beg += self.size if beg < 0
+        if arg2.nil?
+          len = self.size
+        else
+          len = beg + arg2
+        end
+      end
+    end
+
+    i = beg
+    if block
+      while i < len
+        self[i] = block.call(i)
+        i += 1
+      end
+    else
+      while i < len
+        self[i] = arg0
+        i += 1
+      end
+    end
+    self
+  end
+
+  ##
+  #  call-seq:
+  #     ary.rotate(count=1)    -> new_ary
+  #
+  #  Returns a new array by rotating +self+ so that the element at +count+ is
+  #  the first element of the new array.
+  #
+  #  If +count+ is negative then it rotates in the opposite direction, starting
+  #  from the end of +self+ where +-1+ is the last element.
+  #
+  #     a = [ "a", "b", "c", "d" ]
+  #     a.rotate         #=> ["b", "c", "d", "a"]
+  #     a                #=> ["a", "b", "c", "d"]
+  #     a.rotate(2)      #=> ["c", "d", "a", "b"]
+  #     a.rotate(-3)     #=> ["b", "c", "d", "a"]
+
+  def rotate(count=1)
+    ary = []
+    len = self.length
+
+    if len > 0
+      idx = (count < 0) ? (len - (~count % len) - 1) : (count % len) # rotate count
+      len.times do
+        ary << self[idx]
+        idx += 1
+        idx = 0 if idx > len-1
+      end
+    end
+    ary
+  end
+
+  ##
+  #  call-seq:
+  #     ary.rotate!(count=1)   -> ary
+  #
+  #  Rotates +self+ in place so that the element at +count+ comes first, and
+  #  returns +self+.
+  #
+  #  If +count+ is negative then it rotates in the opposite direction, starting
+  #  from the end of the array where +-1+ is the last element.
+  #
+  #     a = [ "a", "b", "c", "d" ]
+  #     a.rotate!        #=> ["b", "c", "d", "a"]
+  #     a                #=> ["b", "c", "d", "a"]
+  #     a.rotate!(2)     #=> ["d", "a", "b", "c"]
+  #     a.rotate!(-3)    #=> ["a", "b", "c", "d"]
+
+  def rotate!(count=1)
+    self.replace(self.rotate(count))
+  end
+
+  ##
+  #  call-seq:
+  #     ary.delete_if { |item| block }  -> ary
+  #     ary.delete_if                   -> Enumerator
+  #
+  #  Deletes every element of +self+ for which block evaluates to +true+.
+  #
+  #  The array is changed instantly every time the block is called, not after
+  #  the iteration is over.
+  #
+  #  See also Array#reject!
+  #
+  #  If no block is given, an Enumerator is returned instead.
+  #
+  #     scores = [ 97, 42, 75 ]
+  #     scores.delete_if {|score| score < 80 }   #=> [97]
+
+  def delete_if(&block)
+    return to_enum :delete_if unless block_given?
+
+    idx = 0
+    while idx < self.size do
+      if block.call(self[idx])
+        self.delete_at(idx)
+      else
+        idx += 1
+      end
+    end
+    self
+  end
+
+  ##
+  #  call-seq:
+  #     ary.reject! { |item| block }  -> ary or nil
+  #     ary.reject!                   -> Enumerator
+  #
+  #  Equivalent to Array#delete_if, deleting elements from +self+ for which the
+  #  block evaluates to +true+, but returns +nil+ if no changes were made.
+  #
+  #  The array is changed instantly every time the block is called, not after
+  #  the iteration is over.
+  #
+  #  See also Enumerable#reject and Array#delete_if.
+  #
+  #  If no block is given, an Enumerator is returned instead.
+
+  def reject!(&block)
+    return to_enum :reject! unless block_given?
+
+    len = self.size
+    idx = 0
+    while idx < self.size do
+      if block.call(self[idx])
+        self.delete_at(idx)
+      else
+        idx += 1
+      end
+    end
+    if self.size == len
+      nil
+    else
+      self
+    end
+  end
+
+  ##
+  #  call-seq:
+  #     ary.insert(index, obj...)  -> ary
+  #
+  #  Inserts the given values before the element with the given +index+.
+  #
+  #  Negative indices count backwards from the end of the array, where +-1+ is
+  #  the last element.
+  #
+  #     a = %w{ a b c d }
+  #     a.insert(2, 99)         #=> ["a", "b", 99, "c", "d"]
+  #     a.insert(-2, 1, 2, 3)   #=> ["a", "b", 99, "c", 1, 2, 3, "d"]
+
+  def insert(idx, *args)
+    idx += self.size + 1 if idx < 0
+    self[idx, 0] = args
+    self
+  end
+
+  ##
+  #  call-seq:
+  #     ary.bsearch {|x| block }  -> elem
+  #
+  #  By using binary search, finds a value from this array which meets
+  #  the given condition in O(log n) where n is the size of the array.
+  #
+  #  You can use this method in two use cases: a find-minimum mode and
+  #  a find-any mode.  In either case, the elements of the array must be
+  #  monotone (or sorted) with respect to the block.
+  #
+  #  In find-minimum mode (this is a good choice for typical use case),
+  #  the block must return true or false, and there must be an index i
+  #  (0 <= i <= ary.size) so that:
+  #
+  #  - the block returns false for any element whose index is less than
+  #    i, and
+  #  - the block returns true for any element whose index is greater
+  #    than or equal to i.
+  #
+  #  This method returns the i-th element.  If i is equal to ary.size,
+  #  it returns nil.
+  #
+  #     ary = [0, 4, 7, 10, 12]
+  #     ary.bsearch {|x| x >=   4 } #=> 4
+  #     ary.bsearch {|x| x >=   6 } #=> 7
+  #     ary.bsearch {|x| x >=  -1 } #=> 0
+  #     ary.bsearch {|x| x >= 100 } #=> nil
+  #
+  #  In find-any mode (this behaves like libc's bsearch(3)), the block
+  #  must return a number, and there must be two indices i and j
+  #  (0 <= i <= j <= ary.size) so that:
+  #
+  #  - the block returns a positive number for ary[k] if 0 <= k < i,
+  #  - the block returns zero for ary[k] if i <= k < j, and
+  #  - the block returns a negative number for ary[k] if
+  #    j <= k < ary.size.
+  #
+  #  Under this condition, this method returns any element whose index
+  #  is within i...j.  If i is equal to j (i.e., there is no element
+  #  that satisfies the block), this method returns nil.
+  #
+  #     ary = [0, 4, 7, 10, 12]
+  #     # try to find v such that 4 <= v < 8
+  #     ary.bsearch {|x| 1 - (x / 4).truncate } #=> 4 or 7
+  #     # try to find v such that 8 <= v < 10
+  #     ary.bsearch {|x| 4 - (x / 2).truncate } #=> nil
+  #
+  #  You must not mix the two modes at a time; the block must always
+  #  return either true/false, or always return a number.  It is
+  #  undefined which value is actually picked up at each iteration.
+
+  def bsearch(&block)
+    return to_enum :bsearch unless block_given?
+
+    low = 0
+    high = self.size
+    satisfied = false
+    while low < high
+      mid = low + ((high - low) / 2).truncate
+      val = self[mid]
+      v = block.call(val)
+      if v.is_a?(Integer)
+        return val if v == 0
+        smaller = v < 0
+      elsif v == true
+        satisfied = true
+        smaller = true
+      elsif v == false || v.nil?
+        smaller = false
+      end
+      if smaller
+        high = mid
+      else
+        low = mid + 1
+      end
+    end
+    return nil if low == self.size
+    return nil unless satisfied
+    self[low]
+  end
+
+  ##
+  #  call-seq:
+  #     ary.delete_if { |item| block }  -> ary
+  #     ary.delete_if                   -> Enumerator
+  #
+  #  Deletes every element of +self+ for which block evaluates to +true+.
+  #
+  #  The array is changed instantly every time the block is called, not after
+  #  the iteration is over.
+  #
+  #  See also Array#reject!
+  #
+  #  If no block is given, an Enumerator is returned instead.
+  #
+  #     scores = [ 97, 42, 75 ]
+  #     scores.delete_if {|score| score < 80 }   #=> [97]
+
+  def delete_if(&block)
+    return to_enum :delete_if unless block_given?
+
+    idx = 0
+    while idx < self.size do
+      if block.call(self[idx])
+        self.delete_at(idx)
+      else
+        idx += 1
+      end
+    end
+    self
+  end
+
+  ##
+  #  call-seq:
+  #     ary.keep_if { |item| block } -> ary
+  #     ary.keep_if                  -> Enumerator
+  #
+  #  Deletes every element of +self+ for which the given block evaluates to
+  #  +false+.
+  #
+  #  See also Array#select!
+  #
+  #  If no block is given, an Enumerator is returned instead.
+  #
+  #     a = [1, 2, 3, 4, 5]
+  #     a.keep_if { |val| val > 3 } #=> [4, 5]
+
+  def keep_if(&block)
+    return to_enum :keep_if unless block_given?
+
+    idx = 0
+    len = self.size
+    while idx < self.size do
+      if block.call(self[idx])
+        idx += 1
+      else
+        self.delete_at(idx)
+      end
+    end
+    self
+  end
+
+  ##
+  #  call-seq:
+  #     ary.select!  {|item| block } -> ary or nil
+  #     ary.select!                  -> Enumerator
+  #
+  #  Invokes the given block passing in successive elements from +self+,
+  #  deleting elements for which the block returns a +false+ value.
+  #
+  #  If changes were made, it will return +self+, otherwise it returns +nil+.
+  #
+  #  See also Array#keep_if
+  #
+  #  If no block is given, an Enumerator is returned instead.
+
+  def select!(&block)
+    return to_enum :select! unless block_given?
+
+    result = []
+    self.each do |x|
+      result << x if block.call(x)
+    end
+    return nil if self.size == result.size
+    self.replace(result)
+  end
+
+  ##
+  #  call-seq:
+  #     ary.index(val)            -> int or nil
+  #     ary.index {|item| block } ->  int or nil
+  #
+  #  Returns the _index_ of the first object in +ary+ such that the object is
+  #  <code>==</code> to +obj+.
+  #
+  #  If a block is given instead of an argument, returns the _index_ of the
+  #  first object for which the block returns +true+.  Returns +nil+ if no
+  #  match is found.
+  #
+  # ISO 15.2.12.5.14
+  def index(val=NONE, &block)
+    return to_enum(:find_index, val) if !block && val == NONE
+
+    if block
+      idx = 0
+      self.each do |*e|
+        return idx if block.call(*e)
+        idx += 1
+      end
+    else
+      return self.__ary_index(val)
+    end
+    nil
+  end
+
+  ##
+  #  call-seq:
+  #     ary.to_ary -> ary
+  #
+  #  Returns +self+.
+  #
+  def to_ary
+    self
+  end
+
+  ##
+  # call-seq:
+  #   ary.dig(idx, ...)                 -> object
+  #
+  # Extracts the nested value specified by the sequence of <i>idx</i>
+  # objects by calling +dig+ at each step, returning +nil+ if any
+  # intermediate step is +nil+.
+  #
+  def dig(idx,*args)
+    n = self[idx]
+    if args.size > 0
+      n&.dig(*args)
+    else
+      n
+    end
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-array-ext/src/array.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-array-ext/src/array.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-array-ext/src/array.c	(revision 331)
@@ -0,0 +1,243 @@
+#include <mruby.h>
+#include <mruby/value.h>
+#include <mruby/array.h>
+#include <mruby/range.h>
+#include <mruby/hash.h>
+
+/*
+ *  call-seq:
+ *     ary.assoc(obj)   -> new_ary  or  nil
+ *
+ *  Searches through an array whose elements are also arrays
+ *  comparing _obj_ with the first element of each contained array
+ *  using obj.==.
+ *  Returns the first contained array that matches (that
+ *  is, the first associated array),
+ *  or +nil+ if no match is found.
+ *  See also <code>Array#rassoc</code>.
+ *
+ *     s1 = [ "colors", "red", "blue", "green" ]
+ *     s2 = [ "letters", "a", "b", "c" ]
+ *     s3 = "foo"
+ *     a  = [ s1, s2, s3 ]
+ *     a.assoc("letters")  #=> [ "letters", "a", "b", "c" ]
+ *     a.assoc("foo")      #=> nil
+ */
+
+static mrb_value
+mrb_ary_assoc(mrb_state *mrb, mrb_value ary)
+{
+  mrb_int i;
+  mrb_value v, k;
+
+  mrb_get_args(mrb, "o", &k);
+
+  for (i = 0; i < RARRAY_LEN(ary); ++i) {
+    v = mrb_check_array_type(mrb, RARRAY_PTR(ary)[i]);
+    if (!mrb_nil_p(v) && RARRAY_LEN(v) > 0 &&
+        mrb_equal(mrb, RARRAY_PTR(v)[0], k))
+      return v;
+  }
+  return mrb_nil_value();
+}
+
+/*
+ *  call-seq:
+ *     ary.rassoc(obj) -> new_ary or nil
+ *
+ *  Searches through the array whose elements are also arrays. Compares
+ *  _obj_ with the second element of each contained array using
+ *  <code>==</code>. Returns the first contained array that matches. See
+ *  also <code>Array#assoc</code>.
+ *
+ *     a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ]
+ *     a.rassoc("two")    #=> [2, "two"]
+ *     a.rassoc("four")   #=> nil
+ */
+
+static mrb_value
+mrb_ary_rassoc(mrb_state *mrb, mrb_value ary)
+{
+  mrb_int i;
+  mrb_value v, value;
+
+  mrb_get_args(mrb, "o", &value);
+
+  for (i = 0; i < RARRAY_LEN(ary); ++i) {
+    v = RARRAY_PTR(ary)[i];
+    if (mrb_type(v) == MRB_TT_ARRAY &&
+        RARRAY_LEN(v) > 1 &&
+        mrb_equal(mrb, RARRAY_PTR(v)[1], value))
+      return v;
+  }
+  return mrb_nil_value();
+}
+
+/*
+ *  call-seq:
+ *     ary.at(index)   ->   obj  or nil
+ *
+ *  Returns the element at _index_. A
+ *  negative index counts from the end of +self+.  Returns +nil+
+ *  if the index is out of range. See also <code>Array#[]</code>.
+ *
+ *     a = [ "a", "b", "c", "d", "e" ]
+ *     a.at(0)     #=> "a"
+ *     a.at(-1)    #=> "e"
+ */
+
+static mrb_value
+mrb_ary_at(mrb_state *mrb, mrb_value ary)
+{
+  mrb_int pos;
+  mrb_get_args(mrb, "i", &pos);
+
+  return mrb_ary_entry(ary, pos);
+}
+
+static mrb_value
+mrb_ary_values_at(mrb_state *mrb, mrb_value self)
+{
+  mrb_int argc;
+  mrb_value *argv;
+
+  mrb_get_args(mrb, "*", &argv, &argc);
+
+  return mrb_get_values_at(mrb, self, RARRAY_LEN(self), argc, argv, mrb_ary_ref);
+}
+
+/*
+ *  call-seq:
+ *     ary.to_h   ->   Hash
+ *
+ *  Returns the result of interpreting <i>aray</i> as an array of
+ *  <tt>[key, value]</tt> paris.
+ *
+ *      [[:foo, :bar], [1, 2]].to_h
+ *        # => {:foo => :bar, 1 => 2}
+ *
+ */
+
+static mrb_value
+mrb_ary_to_h(mrb_state *mrb, mrb_value ary)
+{
+  mrb_int i;
+  mrb_value v, hash;
+
+  hash = mrb_hash_new_capa(mrb, 0);
+
+  for (i = 0; i < RARRAY_LEN(ary); ++i) {
+    v = mrb_check_array_type(mrb, RARRAY_PTR(ary)[i]);
+
+    if (mrb_nil_p(v)) {
+      mrb_raisef(mrb, E_TYPE_ERROR, "wrong element type %S at %S (expected array)",
+        mrb_str_new_cstr(mrb,  mrb_obj_classname(mrb, ary_elt(ary, i))),
+        mrb_fixnum_value(i)
+      );
+    }
+
+    if (RARRAY_LEN(v) != 2) {
+      mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong array length at %S (expected 2, was %S)",
+        mrb_fixnum_value(i),
+        mrb_fixnum_value(RARRAY_LEN(v))
+      );
+    }
+
+    mrb_hash_set(mrb, hash, RARRAY_PTR(v)[0], RARRAY_PTR(v)[1]);
+  }
+
+  return hash;
+}
+
+/*
+ *  call-seq:
+ *     ary.slice!(index)         -> obj or nil
+ *     ary.slice!(start, length) -> new_ary or nil
+ *     ary.slice!(range)         -> new_ary or nil
+ *
+ *  Deletes the element(s) given by an +index+ (optionally up to +length+
+ *  elements) or by a +range+.
+ *
+ *  Returns the deleted object (or objects), or +nil+ if the +index+ is out of
+ *  range.
+ *
+ *     a = [ "a", "b", "c" ]
+ *     a.slice!(1)     #=> "b"
+ *     a               #=> ["a", "c"]
+ *     a.slice!(-1)    #=> "c"
+ *     a               #=> ["a"]
+ *     a.slice!(100)   #=> nil
+ *     a               #=> ["a"]
+ */
+
+static mrb_value
+mrb_ary_slice_bang(mrb_state *mrb, mrb_value self)
+{
+  struct RArray *a = mrb_ary_ptr(self);
+  mrb_int i, j, k, len;
+  mrb_value index;
+  mrb_value val;
+  mrb_value *ptr;
+  mrb_value ary;
+
+  mrb_ary_modify(mrb, a);
+
+  if (mrb_get_args(mrb, "o|i", &index, &len) == 1) {
+    switch (mrb_type(index)) {
+    case MRB_TT_RANGE:
+      if (mrb_range_beg_len(mrb, index, &i, &len, a->len, TRUE) == 1) {
+        goto delete_pos_len;
+      }
+      else {
+        return mrb_nil_value();
+      }
+    case MRB_TT_FIXNUM:
+      val = mrb_funcall(mrb, self, "delete_at", 1, index);
+      return val;
+    default:
+      val = mrb_funcall(mrb, self, "delete_at", 1, index);
+      return val;
+    }
+  }
+
+  i = mrb_fixnum(index);
+ delete_pos_len:
+  if (i < 0) i += a->len;
+  if (i < 0 || a->len < i) return mrb_nil_value();
+  if (len < 0) return mrb_nil_value();
+  if (a->len == i) return mrb_ary_new(mrb);
+  if (len > a->len - i) len = a->len - i;
+
+  ary = mrb_ary_new_capa(mrb, len);
+
+  for (j = i, k = 0; k < len; ++j, ++k) {
+    mrb_ary_push(mrb, ary, a->ptr[j]);
+  }
+
+  ptr = a->ptr + i;
+  for (j = i; j < a->len - len; ++j) {
+    *ptr = *(ptr+len);
+    ++ptr;
+  }
+
+  mrb_ary_resize(mrb, self, a->len - len);
+  return ary;
+}
+
+void
+mrb_mruby_array_ext_gem_init(mrb_state* mrb)
+{
+  struct RClass * a = mrb->array_class;
+
+  mrb_define_method(mrb, a, "assoc",  mrb_ary_assoc,  MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, a, "at",     mrb_ary_at,     MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, a, "rassoc", mrb_ary_rassoc, MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, a, "values_at", mrb_ary_values_at, MRB_ARGS_ANY());
+  mrb_define_method(mrb, a, "to_h",   mrb_ary_to_h, MRB_ARGS_REQ(0));
+  mrb_define_method(mrb, a, "slice!", mrb_ary_slice_bang,   MRB_ARGS_ANY());
+}
+
+void
+mrb_mruby_array_ext_gem_final(mrb_state* mrb)
+{
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-array-ext/test/array.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-array-ext/test/array.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-array-ext/test/array.rb	(revision 331)
@@ -0,0 +1,354 @@
+##
+# Array(Ext) Test
+
+assert("Array.try_convert") do
+  assert_nil Array.try_convert(0)
+  assert_nil Array.try_convert(nil)
+  assert_equal [], Array.try_convert([])
+  assert_equal [1,2,3], Array.try_convert([1,2,3])
+end
+
+assert("Array#assoc") do
+  s1 = [ "colors", "red", "blue", "green" ]
+  s2 = [ "letters", "a", "b", "c" ]
+  s3 = "foo"
+  a  = [ s1, s2, s3 ]
+
+  assert_equal [ "letters", "a", "b", "c" ], a.assoc("letters")
+  assert_nil a.assoc("foo")
+end
+
+assert("Array#at") do
+  a = [ "a", "b", "c", "d", "e" ]
+  assert_equal "a", a.at(0)
+  assert_equal "e", a.at(-1)
+end
+
+assert("Array#rassoc") do
+  a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ]
+
+  assert_equal [2, "two"], a.rassoc("two")
+  assert_nil a.rassoc("four")
+end
+
+assert("Array#uniq!") do
+  a = [1, 2, 3, 1]
+  a.uniq!
+  assert_equal [1, 2, 3], a
+
+  b = [ "a", "b", "c" ]
+  assert_nil b.uniq!
+
+  c = [["student","sam"], ["student","george"], ["teacher","matz"]]
+  assert_equal [["student", "sam"], ["teacher", "matz"]], c.uniq! { |s| s.first }
+
+  d = [["student","sam"], ["teacher","matz"]]
+  assert_nil d.uniq! { |s| s.first }
+end
+
+assert("Array#uniq") do
+  a = [1, 2, 3, 1]
+  assert_equal [1, 2, 3], a.uniq
+  assert_equal [1, 2, 3, 1], a
+
+  b = [["student","sam"], ["student","george"], ["teacher","matz"]]
+  assert_equal [["student", "sam"], ["teacher", "matz"]], b.uniq { |s| s.first }
+end
+
+assert("Array#-") do
+  a = [1, 2, 3, 1]
+  b = [1]
+  c = 1
+
+  assert_raise(TypeError) { a - c }
+  assert_equal [2, 3], (a - b)
+  assert_equal [1, 2, 3, 1], a
+end
+
+assert("Array#|") do
+  a = [1, 2, 3, 1]
+  b = [1, 4]
+  c = 1
+
+  assert_raise(TypeError) { a | c }
+  assert_equal [1, 2, 3, 4], (a | b)
+  assert_equal [1, 2, 3, 1], a
+end
+
+assert("Array#&") do
+  a = [1, 2, 3, 1]
+  b = [1, 4]
+  c = 1
+
+  assert_raise(TypeError) { a & c }
+  assert_equal [1], (a & b)
+  assert_equal [1, 2, 3, 1], a
+end
+
+assert("Array#flatten") do
+  assert_equal [1, 2, "3", {4=>5}, :'6'],    [1, 2, "3", {4=>5}, :'6'].flatten
+  assert_equal [1, 2, 3, 4, 5, 6], [1, 2,    [3, 4, 5], 6].flatten
+  assert_equal [1, 2, 3, 4, 5, 6], [1, 2,    [3, [4, 5], 6]].flatten
+  assert_equal [1, [2, [3, [4, [5, [6]]]]]], [1, [2, [3, [4, [5, [6]]]]]].flatten(0)
+  assert_equal [1, 2, [3, [4, [5, [6]]]]],   [1, [2, [3, [4, [5, [6]]]]]].flatten(1)
+  assert_equal [1, 2, 3, [4, [5, [6]]]],     [1, [2, [3, [4, [5, [6]]]]]].flatten(2)
+  assert_equal [1, 2, 3, 4, [5, [6]]],       [1, [2, [3, [4, [5, [6]]]]]].flatten(3)
+  assert_equal [1, 2, 3, 4, 5, [6]],         [1, [2, [3, [4, [5, [6]]]]]].flatten(4)
+  assert_equal [1, 2, 3, 4, 5, 6],           [1, [2, [3, [4, [5, [6]]]]]].flatten(5)
+end
+
+assert("Array#flatten!") do
+  assert_equal [1, 2, 3, 4, 5, 6], [1, 2, [3, [4, 5], 6]].flatten!
+end
+
+assert("Array#compact") do
+  a = [1, nil, "2", nil, :t, false, nil]
+  assert_equal [1, "2", :t, false], a.compact
+  assert_equal [1, nil, "2", nil, :t, false, nil], a
+end
+
+assert("Array#compact!") do
+  a = [1, nil, "2", nil, :t, false, nil]
+  a.compact!
+  assert_equal [1, "2", :t, false], a
+end
+
+assert("Array#fetch") do
+  a = [ 11, 22, 33, 44 ]
+  assert_equal 22, a.fetch(1)
+  assert_equal 44, a.fetch(-1)
+  assert_equal 'cat', a.fetch(4, 'cat')
+  ret = 0
+  a.fetch(100) { |i| ret = i }
+  assert_equal 100, ret
+  assert_raise(IndexError) { a.fetch(100) }
+end
+
+assert("Array#fill") do
+  a = [ "a", "b", "c", "d" ]
+  assert_equal ["x", "x", "x", "x"], a.fill("x")
+  assert_equal ["x", "x", "x", "w"], a.fill("w", -1)
+  assert_equal ["x", "x", "z", "z"], a.fill("z", 2, 2)
+  assert_equal ["y", "y", "z", "z"], a.fill("y", 0..1)
+  assert_equal [0, 1, 4, 9], a.fill { |i| i*i }
+  assert_equal [0, 1, 8, 27], a.fill(-2) { |i| i*i*i }
+  assert_equal [0, 2, 3, 27], a.fill(1, 2) { |i| i+1 }
+  assert_equal [1, 2, 3, 27], a.fill(0..1) { |i| i+1 }
+  assert_raise(ArgumentError) { a.fill }
+
+  assert_equal([0, 1, 2, 3, -1, 5], [0, 1, 2, 3, 4, 5].fill(-1, -2, 1))
+  assert_equal([0, 1, 2, 3, -1, -1, -1], [0, 1, 2, 3, 4, 5].fill(-1, -2, 3))
+  assert_equal([0, 1, 2, -1, -1, 5], [0, 1, 2, 3, 4, 5].fill(-1, 3..4))
+  assert_equal([0, 1, 2, -1, 4, 5], [0, 1, 2, 3, 4, 5].fill(-1, 3...4))
+  assert_equal([0, 1, -1, -1, -1, 5], [0, 1, 2, 3, 4, 5].fill(-1, 2..-2))
+  assert_equal([0, 1, -1, -1, 4, 5], [0, 1, 2, 3, 4, 5].fill(-1, 2...-2))
+  assert_equal([0, 1, 2, 13, 14, 5], [0, 1, 2, 3, 4, 5].fill(3..4){|i| i+10})
+  assert_equal([0, 1, 2, 13, 4, 5], [0, 1, 2, 3, 4, 5].fill(3...4){|i| i+10})
+  assert_equal([0, 1, 12, 13, 14, 5], [0, 1, 2, 3, 4, 5].fill(2..-2){|i| i+10})
+  assert_equal([0, 1, 12, 13, 4, 5], [0, 1, 2, 3, 4, 5].fill(2...-2){|i| i+10})
+
+  assert_equal [1, 2, 3, 4, 'x', 'x'], [1, 2, 3, 4, 5, 6].fill('x', -2..-1)
+  assert_equal [1, 2, 3, 4, 'x', 6], [1, 2, 3, 4, 5, 6].fill('x', -2...-1)
+  assert_equal [1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6].fill('x', -2...-2)
+  assert_equal [1, 2, 3, 4, 'x', 6], [1, 2, 3, 4, 5, 6].fill('x', -2..-2)
+  assert_equal [1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6].fill('x', -2..0)
+end
+
+assert("Array#reverse_each") do
+  a = [ "a", "b", "c", "d" ]
+  b = []
+  a.reverse_each do |i|
+    b << i
+  end
+  assert_equal [ "d", "c", "b", "a" ], b
+
+  if Object.const_defined?(:Enumerator)
+    assert_equal [ "d", "c", "b", "a" ], a.reverse_each.to_a
+  else
+    true
+  end
+end
+
+assert("Array#rotate") do
+  a = ["a", "b", "c", "d"]
+  assert_equal ["b", "c", "d", "a"], a.rotate
+  assert_equal ["a", "b", "c", "d"], a
+  assert_equal ["c", "d", "a", "b"], a.rotate(2)
+  assert_equal ["b", "c", "d", "a"], a.rotate(-3)
+  assert_equal ["c", "d", "a", "b"], a.rotate(10)
+  assert_equal [], [].rotate
+end
+
+assert("Array#rotate!") do
+  a = ["a", "b", "c", "d"]
+  assert_equal ["b", "c", "d", "a"], a.rotate!
+  assert_equal ["b", "c", "d", "a"], a
+  assert_equal ["d", "a", "b", "c"], a.rotate!(2)
+  assert_equal ["a", "b", "c", "d"], a.rotate!(-3)
+  assert_equal ["c", "d", "a", "b"], a.rotate(10)
+  assert_equal [], [].rotate!
+end
+
+assert("Array#delete_if") do
+  a = [1, 2, 3, 4, 5]
+  assert_equal [1, 2, 3, 4, 5], a.delete_if { false }
+  assert_equal [1, 2, 3, 4, 5], a
+
+  a = [1, 2, 3, 4, 5]
+  assert_equal [], a.delete_if { true }
+  assert_equal [], a
+
+  a = [1, 2, 3, 4, 5]
+  assert_equal [1, 2, 3], a.delete_if { |i| i > 3 }
+  assert_equal [1, 2, 3], a
+end
+
+assert("Array#reject!") do
+  a = [1, 2, 3, 4, 5]
+  assert_nil a.reject! { false }
+  assert_equal [1, 2, 3, 4, 5], a
+
+  a = [1, 2, 3, 4, 5]
+  assert_equal [], a.reject! { true }
+  assert_equal [], a
+
+  a = [1, 2, 3, 4, 5]
+  assert_equal [1, 2, 3], a.reject! { |val| val > 3 }
+  assert_equal [1, 2, 3], a
+end
+
+assert("Array#insert") do
+  a = ["a", "b", "c", "d"]
+  assert_equal ["a", "b", 99, "c", "d"], a.insert(2, 99)
+  assert_equal ["a", "b", 99, "c", 1, 2, 3, "d"], a.insert(-2, 1, 2, 3)
+
+  b = ["a", "b", "c", "d"]
+  assert_equal ["a", "b", "c", "d", nil, nil, 99], b.insert(6, 99)
+end
+
+assert("Array#bsearch") do
+  # Find minimum mode
+  a = [0, 4, 7, 10, 12]
+  assert_include [4, 7], a.bsearch {|x| x >= 4 }
+  assert_equal 7, a.bsearch {|x| x >= 6 }
+  assert_equal 0, a.bsearch {|x| x >= -1 }
+  assert_nil a.bsearch {|x| x >= 100 }
+
+  # Find any mode
+  a = [0, 4, 7, 10, 12]
+  assert_include [4, 7], a.bsearch {|x| 1 - (x / 4).truncate }
+  assert_nil a.bsearch {|x| 4 - (x / 2).truncate }
+  assert_equal(nil, a.bsearch {|x| 1 })
+  assert_equal(nil, a.bsearch {|x| -1 })
+end
+
+assert("Array#delete_if") do
+  a = [1, 2, 3, 4, 5]
+  assert_equal [1, 2, 3, 4, 5], a.delete_if { false }
+  assert_equal [1, 2, 3, 4, 5], a
+
+  a = [1, 2, 3, 4, 5]
+  assert_equal [], a.delete_if { true }
+  assert_equal [], a
+
+  a = [ 1, 2, 3, 4, 5 ]
+  assert_equal [1, 2, 3], a.delete_if { |val| val > 3 }
+end
+
+assert("Array#keep_if") do
+  a = [1, 2, 3, 4, 5]
+  assert_equal [1, 2, 3, 4, 5], a.keep_if { true }
+  assert_equal [1, 2, 3, 4, 5], a
+
+  a = [1, 2, 3, 4, 5]
+  assert_equal [], a.keep_if { false }
+  assert_equal [], a
+
+  a = [1, 2, 3, 4, 5]
+  assert_equal [4, 5], a.keep_if { |val| val > 3 }
+  assert_equal [4, 5], a
+end
+
+assert("Array#select!") do
+  a = [1, 2, 3, 4, 5]
+  assert_nil a.select! { true }
+  assert_equal [1, 2, 3, 4, 5], a
+
+  a = [1, 2, 3, 4, 5]
+  assert_equal [], a.select! { false }
+  assert_equal [], a
+
+  a = [1, 2, 3, 4, 5]
+  assert_equal [4, 5], a.select! { |val| val > 3 }
+  assert_equal [4, 5], a
+end
+
+assert('Array#values_at') do
+  a = %w{red green purple white none}
+
+  assert_equal %w{red purple none}, a.values_at(0, 2, 4)
+  assert_equal ['green', 'white', nil, nil], a.values_at(1, 3, 5, 7)
+  assert_equal ['none', 'white', 'white', nil], a.values_at(-1, -2, -2, -7)
+  assert_equal ['none', nil, nil, 'red', 'green', 'purple'], a.values_at(4..6, 0...3)
+  assert_raise(TypeError) { a.values_at 'tt' }
+end
+
+assert('Array#to_h') do
+  assert_equal({}, [].to_h)
+  assert_equal({a: 1, b:2}, [[:a, 1], [:b, 2]].to_h)
+
+  assert_raise(TypeError)     { [1].to_h }
+  assert_raise(ArgumentError) { [[1]].to_h }
+end
+
+assert('Array#to_h (Modified)') do
+  class A
+    def to_ary
+      $a.clear
+      nil
+    end
+  end
+  $a = [A.new]
+  assert_raise(TypeError) { $a.to_h }
+end
+
+assert("Array#index (block)") do
+  assert_nil (1..10).to_a.index { |i| i % 5 == 0 and i % 7 == 0 }
+  assert_equal 34, (1..100).to_a.index { |i| i % 5 == 0 and i % 7 == 0 }
+end
+
+assert("Array#to_ary") do
+  assert_equal [], [].to_ary
+  assert_equal [1,2,3], [1,2,3].to_ary
+end
+
+assert("Array#dig") do
+  h = [[[1]], 0]
+  assert_equal(1, h.dig(0, 0, 0))
+  assert_nil(h.dig(2, 0))
+  assert_raise(TypeError) {h.dig(:a)}
+end
+
+assert("Array#slice!") do
+  a = [1, 2, 3]
+  b = a.slice!(0)
+  c = [1, 2, 3, 4, 5]
+  d = c.slice!(0, 2)
+  e = [1, 2, 3, 4, 5]
+  f = e.slice!(1..3)
+  g = [1, 2, 3]
+  h = g.slice!(-1)
+  i = [1, 2, 3]
+  j = i.slice!(0, -1)
+
+  assert_equal(a, [2, 3])
+  assert_equal(b, 1)
+  assert_equal(c, [3, 4, 5])
+  assert_equal(d, [1, 2])
+  assert_equal(e, [1, 5])
+  assert_equal(f, [2, 3, 4])
+  assert_equal(g, [1, 2])
+  assert_equal(h, 3)
+  assert_equal(i, [1, 2, 3])
+  assert_equal(j, nil)
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/bintest/mrdb.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/bintest/mrdb.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/bintest/mrdb.rb	(revision 331)
@@ -0,0 +1,286 @@
+require 'open3'
+require 'tempfile'
+
+class BinTest_MrubyBinDebugger
+  @debug1=false
+  @debug2=true
+  @debug3=true
+  def self.test(rubysource, testcase)
+    script, bin = Tempfile.new(['test', '.rb']), Tempfile.new(['test', '.mrb'])
+
+    # .rb
+    script.write rubysource
+    script.flush
+
+    # compile
+    `./bin/mrbc -g -o "#{bin.path}" "#{script.path}"`
+
+    # add mrdb quit
+    testcase << {:cmd=>"quit"}
+
+    stdin_data = testcase.map{|t| t[:cmd]}.join("\n") << "\n"
+
+    ["bin/mrdb #{script.path}","bin/mrdb -b #{bin.path}"].each do |cmd|
+      o, s = Open3.capture2(cmd, :stdin_data => stdin_data)
+
+      exp_vals = testcase.map{|t| t.fetch(:exp, nil)}
+      unexp_vals = testcase.map{|t| t.fetch(:unexp, nil)}
+
+if @debug1
+  o.split("\n").each_with_index do |i,actual|
+    p [i,actual]
+  end
+end
+      # compare actual / expected
+      o.split("\n").each do |actual|
+        next if actual.empty?
+        exp = exp_vals.shift
+if @debug2
+  a = true
+  a = actual.include?(exp) unless exp.nil?
+  p [actual, exp] unless a
+end
+        assert_true actual.include?(exp) unless exp.nil?
+      end
+      # compare actual / unexpected
+      o.split("\n").each do |actual|
+        next if actual.empty?
+        unexp = unexp_vals.shift
+if @debug3
+  a = false
+  a = actual.include?(unexp) unless unexp.nil?
+  p [actual, unexp] if a
+end
+        assert_false actual.include?(unexp) unless unexp.nil?
+      end
+    end
+  end
+end
+
+INVCMD = "invalid command"
+
+assert('mruby-bin-debugger(mrdb) command line') do
+  # ruby source
+  src = "foo = 'foo'\n"
+
+  str = ""
+  103.times {
+    str += "1234567890"
+  }
+  cmd = "p a=#{str}"
+
+  # test case
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>cmd[0...1023], :unexp=>'command line too long.'}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>cmd[0...1024], :unexp=>'command line too long.'}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>cmd[0...1025], :exp=>'command line too long.'}])
+end
+
+assert('mruby-bin-debugger(mrdb) command: "break"') do
+  # ruby source
+  src = "foo = 'foo'\n"
+
+  # test case
+  tc = []
+  tc << {:cmd=>"b",     :unexp=>INVCMD}
+  tc << {:cmd=>"br",    :unexp=>INVCMD}
+  tc << {:cmd=>"brea",  :unexp=>INVCMD}
+  tc << {:cmd=>"break", :unexp=>INVCMD}
+  BinTest_MrubyBinDebugger.test(src, tc)
+
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"bl",     :exp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"breaka", :exp=>INVCMD}])
+end
+
+assert('mruby-bin-debugger(mrdb) command: "continue"') do
+  # ruby source
+  src = "foo = 'foo'\n"
+
+  # test case
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"c",         :unexp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"co",        :unexp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"continu",   :unexp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"continue",  :unexp=>INVCMD}])
+
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"cn",        :exp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"continuee", :exp=>INVCMD}])
+end
+
+assert('mruby-bin-debugger(mrdb) command: "delete"') do
+  # ruby source
+  src = "foo = 'foo'\n"
+
+  # test case
+  tc = []
+  tc << {:cmd=>"d 1",      :unexp=>INVCMD}
+  tc << {:cmd=>"de 1",     :unexp=>INVCMD}
+  tc << {:cmd=>"delet 1",  :unexp=>INVCMD}
+  tc << {:cmd=>"delete 1", :unexp=>INVCMD}
+  BinTest_MrubyBinDebugger.test(src, tc)
+
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"dd 1",      :exp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"deletee 1", :exp=>INVCMD}])
+end
+
+assert('mruby-bin-debugger(mrdb) command: "disable"') do
+  # ruby source
+  src = "foo = 'foo'\n"
+
+  # test case
+  tc = []
+  tc << {:cmd=>"dis",     :unexp=>INVCMD}
+  tc << {:cmd=>"disa",    :unexp=>INVCMD}
+  tc << {:cmd=>"disabl",  :unexp=>INVCMD}
+  tc << {:cmd=>"disable", :unexp=>INVCMD}
+  BinTest_MrubyBinDebugger.test(src, tc)
+
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"di",       :exp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"disb",     :exp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"disablee", :exp=>INVCMD}])
+end
+
+assert('mruby-bin-debugger(mrdb) command: "enable"') do
+  # ruby source
+  src = "foo = 'foo'\n"
+
+  # test case
+  tc = []
+  tc << {:cmd=>"en",     :unexp=>INVCMD}
+  tc << {:cmd=>"ena",    :unexp=>INVCMD}
+  tc << {:cmd=>"enabl",  :unexp=>INVCMD}
+  tc << {:cmd=>"enable", :unexp=>INVCMD}
+  BinTest_MrubyBinDebugger.test(src, tc)
+
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"e",       :exp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"enb",     :exp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"enablee", :exp=>INVCMD}])
+end
+
+assert('mruby-bin-debugger(mrdb) command: "eval"') do
+  # ruby source
+  src = "foo = 'foo'\n"
+
+  # test case
+  tc = []
+  tc << {:cmd=>"ev",   :unexp=>INVCMD}
+  tc << {:cmd=>"eva",  :unexp=>INVCMD}
+  tc << {:cmd=>"eval", :unexp=>INVCMD}
+  BinTest_MrubyBinDebugger.test(src, tc)
+
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"e",     :exp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"evl",   :exp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"evall", :exp=>INVCMD}])
+end
+
+assert('mruby-bin-debugger(mrdb) command: "help"') do
+  # ruby source
+  src = "foo = 'foo'\n"
+
+  # test case
+  tc = []
+  tc << {:cmd=>"h",    :unexp=>INVCMD}
+  tc << {:cmd=>"he",   :unexp=>INVCMD}
+  tc << {:cmd=>"hel",  :unexp=>INVCMD}
+  tc << {:cmd=>"help", :unexp=>INVCMD}
+  BinTest_MrubyBinDebugger.test(src, tc)
+
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"hl",    :exp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"helpp", :exp=>INVCMD}])
+end
+
+assert('mruby-bin-debugger(mrdb) command: "info breakpoints"') do
+  # ruby source
+  src = "foo = 'foo'\n"
+
+  # test case
+  tc = []
+  tc << {:cmd=>"i b",              :unexp=>INVCMD}
+  tc << {:cmd=>"in  b",            :unexp=>INVCMD}
+  tc << {:cmd=>"i    br",          :unexp=>INVCMD}
+  tc << {:cmd=>"inf breakpoint",   :unexp=>INVCMD}
+  tc << {:cmd=>"info breakpoints", :unexp=>INVCMD}
+  BinTest_MrubyBinDebugger.test(src, tc)
+
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"ii b",              :exp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"i bb",              :exp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"infoo breakpoints", :exp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"info breakpointss", :exp=>INVCMD}])
+end
+
+assert('mruby-bin-debugger(mrdb) command: "list"') do
+  # ruby source
+  src = "foo = 'foo'\n"
+
+  # test case
+  tc = []
+  tc << {:cmd=>"l",    :unexp=>INVCMD}
+  tc << {:cmd=>"li",   :unexp=>INVCMD}
+  tc << {:cmd=>"lis",  :unexp=>INVCMD}
+  tc << {:cmd=>"list", :unexp=>INVCMD}
+  BinTest_MrubyBinDebugger.test(src, tc)
+
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"ll",    :exp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"listt", :exp=>INVCMD}])
+end
+
+assert('mruby-bin-debugger(mrdb) command: "print"') do
+  # ruby source
+  src = "foo = 'foo'\n"
+
+  # test case
+  tc = []
+  tc << {:cmd=>"p",     :unexp=>INVCMD}
+  tc << {:cmd=>"pr",    :unexp=>INVCMD}
+  tc << {:cmd=>"prin",  :unexp=>INVCMD}
+  tc << {:cmd=>"print", :unexp=>INVCMD}
+  BinTest_MrubyBinDebugger.test(src, tc)
+
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"pp",     :exp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"printt", :exp=>INVCMD}])
+end
+
+assert('mruby-bin-debugger(mrdb) command: "quit"') do
+  # ruby source
+  src = "foo = 'foo'\n"
+
+  # test case
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"q",    :unexp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"qu",   :unexp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"qui",  :unexp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"quit", :unexp=>INVCMD}])
+
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"qq",    :exp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"quitt", :exp=>INVCMD}])
+end
+
+assert('mruby-bin-debugger(mrdb) command: "run"') do
+  # ruby source
+  src = "foo = 'foo'\n"
+
+  # test case
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"r",   :unexp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"ru",  :unexp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"run", :unexp=>INVCMD}])
+
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"rr",   :exp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"runn", :exp=>INVCMD}])
+end
+
+assert('mruby-bin-debugger(mrdb) command: "step"') do
+  # ruby source
+  src = <<"SRC"
+while true
+  foo = 'foo'
+end
+SRC
+
+  # test case
+  tc = []
+  tc << {:cmd=>"s",    :unexp=>INVCMD}
+  tc << {:cmd=>"st",   :unexp=>INVCMD}
+  tc << {:cmd=>"ste",  :unexp=>INVCMD}
+  tc << {:cmd=>"step", :unexp=>INVCMD}
+  BinTest_MrubyBinDebugger.test(src, tc)
+
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"ss",    :exp=>INVCMD}])
+  BinTest_MrubyBinDebugger.test(src, [{:cmd=>"stepp", :exp=>INVCMD}])
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/bintest/print.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/bintest/print.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/bintest/print.rb	(revision 331)
@@ -0,0 +1,701 @@
+require 'open3'
+require 'tempfile'
+
+class BinTest_MrubyBinDebugger
+  @debug1=false
+  @debug2=true
+  def self.test(rubysource, testcase)
+    script, bin = Tempfile.new(['test', '.rb']), Tempfile.new(['test', '.mrb'])
+
+    # .rb
+    script.write rubysource
+    script.flush
+
+    # compile
+    `./bin/mrbc -g -o "#{bin.path}" "#{script.path}"`
+
+    # add mrdb quit
+    testcase << {:cmd=>"quit"}
+
+    stdin_data = testcase.map{|t| t[:cmd]}.join("\n") << "\n"
+
+    ["bin/mrdb #{script.path}","bin/mrdb -b #{bin.path}"].each do |cmd|
+      o, s = Open3.capture2(cmd, :stdin_data => stdin_data)
+
+      exp_vals = testcase.map{|t| t.fetch(:exp, nil)}
+=begin
+if @debug1
+  o.split("\n").each_with_index do |i,actual|
+    p [i,actual]
+  end
+end
+      # compare actual / expected
+      o.split("\n").each do |actual|
+        next if actual.empty?
+        exp = exp_vals.shift
+if @debug2
+  a = true
+  a = actual.include?(exp) unless exp.nil?
+  p [actual, exp] unless a
+end
+        assert_true actual.include?(exp) unless exp.nil?
+      end
+=end
+      idx = 0
+      exp_vals.each do |exp|
+        next if exp.nil?
+        idx = o.index(exp, idx)
+        assert_false idx.nil?
+        break unless idx
+        idx += 1
+      end
+    end
+  end
+end
+
+assert('mruby-bin-debugger(print) invalid arguments') do
+  # ruby source
+  src =  "foo = 'foo'\n"
+
+  # test case
+  tc = []
+  tc << {:cmd=>"p",   :exp=>"Parameter not specified."}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) nomal') do
+  # ruby source
+  src = <<"SRC"
+foo = 'foo'
+bar = foo
+baz = bar
+SRC
+
+  # test case
+  tc = []
+  tc << {:cmd=>"s"}
+  tc << {:cmd=>"p (1+2)",   :exp=>'$1 = 3'}
+  tc << {:cmd=>"p foo",     :exp=>'$2 = "foo"'}
+  tc << {:cmd=>"p foo*=2",  :exp=>'$3 = "foofoo"'}
+  tc << {:cmd=>"s"}
+  tc << {:cmd=>"p bar",     :exp=>'$4 = "foofoo"'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) error') do
+  # ruby source
+  src =  "foo = 'foo'\n"
+
+  # test case
+  tc = []
+  tc << {:cmd=>"p (1+2",  :exp=>'$1 = SyntaxError'}
+  tc << {:cmd=>"p bar",   :exp=>'$2 = NoMethodError'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+# Kernel#instance_eval(string) does't work multiple statements.
+=begin
+assert('mruby-bin-debugger(print) multiple statements') do
+  # ruby source
+  src = <<"SRC"
+x = 0
+y = 0
+z = 0
+SRC
+
+  # test case
+  tc = []
+  tc << {:cmd=>"s",}
+  tc << {:cmd=>"p x=1;x+=2",  :exp=>"3"}
+  tc << {:cmd=>"s",}
+  tc << {:cmd=>"p x",         :exp=>"3"}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+=end
+
+assert('mruby-bin-debugger(print) scope:top') do
+  # ruby source (bp is break point)
+  src = "bp=nil\n"
+
+  # test case
+  tc = []
+  tc << {:cmd=>"p self",  :exp=>'$1 = main'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) scope:class') do
+  # ruby source (bp is break point)
+  src = <<"SRC"
+class TestClassScope
+  bp = nil
+end
+SRC
+
+  # test case
+  tc = []
+  tc << {:cmd=>"s"}
+  tc << {:cmd=>"p self",  :exp=>'$1 = TestClassScope'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) scope:module') do
+  # ruby source (bp is break point)
+  src = <<"SRC"
+class TestModuleScope
+  bp = nil
+end
+SRC
+
+  # test case
+  tc = []
+  tc << {:cmd=>"s"}
+  tc << {:cmd=>"p self",  :exp=>'$1 = TestModuleScope'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) scope:instance method') do
+  # ruby source (bp is break point)
+  src = <<"SRC"
+class TestMethodScope
+  def m
+    bp = nil
+  end
+end
+TestMethodScope.new.m
+SRC
+
+  tc = []
+  tc << {:cmd=>"b 3"}
+  tc << {:cmd=>"r"}
+  tc << {:cmd=>"p self",  :exp=>'$1 = #<TestMethodScope:'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) scope:class method') do
+  # ruby source (bp is break point)
+  src = <<"SRC"
+class TestClassMethodScope
+  def self.cm
+    bp = nil
+  end
+end
+TestClassMethodScope.cm
+SRC
+
+  tc = []
+  tc << {:cmd=>"b 3"}
+  tc << {:cmd=>"r"}
+  tc << {:cmd=>"p self",  :exp=>'$1 = TestClassMethodScope'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) scope:block') do
+  # ruby source (bp is break point)
+  src = <<"SRC"
+1.times do
+  bp = nil
+end
+class TestBlockScope
+  1.times do
+    bp = nil
+  end
+  def m
+    1.times do
+      bp = nil
+    end
+  end
+end
+TestBlockScope.new.m
+SRC
+
+  tc = []
+  tc << {:cmd=>"b 2"}
+  tc << {:cmd=>"b 6"}
+  tc << {:cmd=>"b 10"}
+  tc << {:cmd=>"c"}
+  tc << {:cmd=>"p self", :exp=>'$1 = main'}
+  tc << {:cmd=>"c"}
+  tc << {:cmd=>"p self", :exp=>'$2 = TestBlockScope'}
+  tc << {:cmd=>"c"}
+  tc << {:cmd=>"p self", :exp=>'$3 = #<TestBlockScope:'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) same name:local variabe') do
+  # ruby source (bp is break point)
+  src = <<"SRC"
+lv = 'top'
+class TestLocalVariableName
+  lv = 'class'
+  def m
+    lv = 'instance method'
+    bp = nil
+  end
+  bp = nil
+end
+TestLocalVariableName.new.m
+bp = nil
+SRC
+
+  tc = []
+  tc << {:cmd=>"b 6"}
+  tc << {:cmd=>"b 8"}
+  tc << {:cmd=>"b 11"}
+  tc << {:cmd=>"r"}
+  tc << {:cmd=>"p lv", :exp=>'$1 = "class"'}
+  tc << {:cmd=>"c"}
+  tc << {:cmd=>"p lv", :exp=>'$2 = "instance method"'}
+  tc << {:cmd=>"c"}
+  tc << {:cmd=>"p lv", :exp=>'$3 = "top"'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) same name:instance variabe') do
+  # ruby source (bp is break point)
+  src = <<"SRC"
+@iv = 'top'
+class TestInstanceVariableName
+  def initialize(v)
+    @iv = v
+  end
+  def m
+    bp = nil
+  end
+end
+i1 = TestInstanceVariableName.new('instance1')
+i2 = TestInstanceVariableName.new('instance2')
+i1.m
+i2.m
+bp = nil
+SRC
+
+  tc = []
+  tc << {:cmd=>"b 7"}
+  tc << {:cmd=>"b 14"}
+  tc << {:cmd=>"r"}
+  tc << {:cmd=>"p @iv", :exp=>'$1 = "instance1"'}
+  tc << {:cmd=>"c"}
+  tc << {:cmd=>"p @iv", :exp=>'$2 = "instance2"'}
+  tc << {:cmd=>"c"}
+  tc << {:cmd=>"p @iv", :exp=>'$3 = "top"'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+# Kernel#instance_eval(string) does't work const.
+=begin
+assert('mruby-bin-debugger(print) same name:const') do
+  # ruby source (bp is break point)
+  src = <<"SRC"
+CONST='top'
+class TestConstNameSuperClass
+  CONST='super class'
+  def m
+    bp = nil
+  end
+end
+class TestConstNameSubClass < TestConstNameSuperClass
+  CONST='sub class'
+  def m
+    bp = nil
+  end
+end
+
+TestConstNameSuperClass.new.m()
+TestConstNameSubClass.new.m()
+bp = nil
+SRC
+
+  # todo: wait for 'break' to be implimented
+  tc = []
+  9.times { tc << {:cmd=>"s"} }
+  tc << {:cmd=>"p CONST", :exp=>"super class"}
+  3.times { tc << {:cmd=>"s"} }
+  tc << {:cmd=>"p CONST", :exp=>"sub class"}
+  1.times { tc << {:cmd=>"s"} }
+  tc << {:cmd=>"p CONST", :exp=>"top"}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+=end
+
+assert('mruby-bin-debugger(print) Literal:Numeric') do
+  # ruby source
+  src =  "foo = 'foo'\n"
+
+  # test case
+  tc = []
+  tc << {:cmd=>"p 100",     :exp=>'$1 = 100'}
+  tc << {:cmd=>"p -0b100",  :exp=>'$2 = -4'}
+  tc << {:cmd=>"p +0100",   :exp=>'$3 = 64'}
+  tc << {:cmd=>"p 0x100",   :exp=>'$4 = 256'}
+  tc << {:cmd=>"p 1_234",   :exp=>'$5 = 1234'}
+  tc << {:cmd=>"p 0b1000_0000", :exp=>"$6 = #{0b1000_0000.to_s}"}
+  tc << {:cmd=>"p 0x1000_0000", :exp=>"$7 = #{0x1000_0000.to_s}"}
+
+  tc << {:cmd=>"p 3.14",    :exp=>'$8 = 3.14'}
+  tc << {:cmd=>"p -12.3",   :exp=>'$9 = -12.3'}
+  tc << {:cmd=>"p +12.000", :exp=>'$10 = 12.0'}
+  tc << {:cmd=>"p 1e4",     :exp=>'$11 = 10000.0'}
+  tc << {:cmd=>"p -0.1e-2", :exp=>'$12 = -0.001'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) Literal:String') do
+  # ruby source
+  src = <<"SRC"
+foo = 'foo'
+bar = "bar"
+baz = "baz"
+SRC
+
+  # test case
+  tc = []
+  tc << {:cmd=>"s"}
+  tc << {:cmd=>"s"}
+
+  tc << {:cmd=>'p "str"',        :exp=>'$1 = "str"'}
+  tc << {:cmd=>'p "s\tt\rr\n"',  :exp=>'$2 = "s\\tt\\rr\\n"'}
+  tc << {:cmd=>'p "\C-a\C-z"',   :exp=>'$3 = "\\001\\032"'}
+  tc << {:cmd=>'p "#{foo+bar}"', :exp=>'$4 = "foobar"'}
+
+  tc << {:cmd=>'p \'str\'',          :exp=>'$5 = "str"'}
+  tc << {:cmd=>'p \'s\\tt\\rr\\n\'', :exp=>'$6 = "s\\\\tt\\\\rr\\\\n"'}
+  tc << {:cmd=>'p \'\\C-a\\C-z\'',   :exp=>'$7 = "\\\\C-a\\\\C-z"'}
+  tc << {:cmd=>'p \'#{foo+bar}\'',   :exp=>'$8 = "#{foo+bar}"'}
+
+  tc << {:cmd=>'p %!str!',        :exp=>'$9 = "str"'}
+  tc << {:cmd=>'p %!s\tt\rr\n!',  :exp=>'$10 = "s\\tt\\rr\\n"'}
+  tc << {:cmd=>'p %!\C-a\C-z!',   :exp=>'$11 = "\\001\\032"'}
+  tc << {:cmd=>'p %!#{foo+bar}!', :exp=>'$12 = "foobar"'}
+
+  tc << {:cmd=>'p %Q!str!',        :exp=>'$13 = "str"'}
+  tc << {:cmd=>'p %Q!s\tt\rr\n!',  :exp=>'$14 = "s\\tt\\rr\\n"'}
+  tc << {:cmd=>'p %Q!\C-a\C-z!',   :exp=>'$15 = "\\001\\032"'}
+  tc << {:cmd=>'p %Q!#{foo+bar}!', :exp=>'$16 = "foobar"'}
+
+  tc << {:cmd=>'p %q!str!',          :exp=>'$17 = "str"'}
+  tc << {:cmd=>'p %q!s\\tt\\rr\\n!', :exp=>'$18 = "s\\\\tt\\\\rr\\\\n"'}
+  tc << {:cmd=>'p %q!\\C-a\\C-z!',   :exp=>'$19 = "\\\\C-a\\\\C-z"'}
+  tc << {:cmd=>'p %q!#{foo+bar}!',   :exp=>'$20 = "#{foo+bar}"'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) Literal:Array') do
+  # ruby source
+  src = <<"SRC"
+foo = 'foo'
+bar = "bar"
+baz = "baz"
+SRC
+
+  # test case
+  tc = []
+  tc << {:cmd=>"s"}
+  tc << {:cmd=>"s"}
+
+  tc << {:cmd=>'p []',                      :exp=>'$1 = []'}
+  tc << {:cmd=>'p [ 5,  12,   8,    10, ]', :exp=>'$2 = [5, 12, 8, 10]'}
+  tc << {:cmd=>'p [1,2.5,"#{foo+bar}"]',    :exp=>'$3 = [1, 2.5, "foobar"]'}
+  tc << {:cmd=>'p %w[3.14 A\ &\ B #{foo}]', :exp=>'$4 = ["3.14", "A & B", "#{foo}"]'}
+  tc << {:cmd=>'p %W[3.14 A\ &\ B #{foo}]', :exp=>'$5 = ["3.14", "A & B", "foo"]'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) Literal:Hash') do
+  # ruby source
+  src = <<"SRC"
+foo = 'foo'
+bar = "bar"
+baz = "baz"
+SRC
+
+  # test case
+  tc = []
+  tc << {:cmd=>"s"}
+  tc << {:cmd=>"s"}
+
+  tc << {:cmd=>'p {}',                              :exp=>'$1 = {}'}
+  tc << {:cmd=>'p {"one"=>1,"two"=>2}',             :exp=>'$2 = {"one"=>1, "two"=>2}'}
+  tc << {:cmd=>'p {:eins=>"1",   :zwei=>"2", }',    :exp=>'$3 = {:eins=>"1", :zwei=>"2"}'}
+  tc << {:cmd=>'p {uno:"one", dos: 2}',             :exp=>'$4 = {:uno=>"one", :dos=>2}'}
+  tc << {:cmd=>'p {"one"=>1, :zwei=>2, tres:3}',    :exp=>'$5 = {"one"=>1, :zwei=>2, :tres=>3}'}
+  tc << {:cmd=>'p {:foo=>"#{foo}",:bar=>"#{bar}"}', :exp=>'$6 = {:foo=>"foo", :bar=>"bar"}'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) Literal:Range') do
+  # ruby source
+  src = "foo = 'foo'\n"
+
+  # test case
+  tc = []
+  tc << {:cmd=>'p 1..10',    :exp=>'$1 = 1..10'}
+  tc << {:cmd=>'p 1...10',   :exp=>'$2 = 1...10'}
+  tc << {:cmd=>'p 100..10',  :exp=>'$3 = 100..10'}
+  tc << {:cmd=>'p 1 ... 10', :exp=>'$4 = 1...10'}
+
+  tc << {:cmd=>'p "1" .. "9"',  :exp=>'$5 = "1".."9"'}
+  tc << {:cmd=>'p "A" ... "Z"', :exp=>'$6 = "A"..."Z"'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) Literal:Symbol') do
+  # ruby source
+  src = <<"SRC"
+foo = 'foo'
+bar = "bar"
+baz = "baz"
+SRC
+
+  # test case
+  tc = []
+  tc << {:cmd=>"s"}
+  tc << {:cmd=>"s"}
+
+  tc << {:cmd=>'p :sym',          :exp=>'$1 = :sym'}
+  tc << {:cmd=>'p :"sd"',         :exp=>'$2 = :sd'}
+  tc << {:cmd=>"p :'ss'",         :exp=>'$3 = :ss'}
+  tc << {:cmd=>'p :"123"',        :exp=>'$4 = :"123"'}
+  tc << {:cmd=>'p :"#{foo} baz"', :exp=>'$5 = :"foo baz"'}
+  tc << {:cmd=>'p %s!symsym!',    :exp=>'$6 = :symsym'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) Unary operation') do
+  # ruby source
+  src = "foo = 'foo'\n"
+
+  # test case
+  tc = []
+  tc << {:cmd=>'p +10',    :exp=>'$1 = 10'}
+  tc << {:cmd=>'p -100',   :exp=>'$2 = -100'}
+  tc << {:cmd=>'p !true',  :exp=>'$3 = false'}
+  tc << {:cmd=>'p !false', :exp=>'$4 = true'}
+  tc << {:cmd=>'p !nil',   :exp=>'$5 = true'}
+  tc << {:cmd=>'p !1',     :exp=>'$6 = false'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) Binary operation') do
+  # ruby source
+  src = <<"SRC"
+CONST = 100
+a,b,c = 1, 5, 8
+foo,bar,baz = 'foo','bar','baz'
+ary = []
+SRC
+
+  # test case
+  tc = []
+  tc << {:cmd=>'s'}
+  tc << {:cmd=>'s'}
+  tc << {:cmd=>'s'}
+
+  tc << {:cmd=>'p a+1',   :exp=>'$1 = 2'}
+  tc << {:cmd=>'p 2-b',   :exp=>'$2 = -3'}
+  tc << {:cmd=>'p c * 3', :exp=>'$3 = 24'}
+  tc << {:cmd=>'p a/b',   :exp=>'$4 = 0.2'}
+  tc << {:cmd=>'p c%b',   :exp=>'$5 = 3'}
+  tc << {:cmd=>'p 2**10', :exp=>'$6 = 1024'}
+  tc << {:cmd=>'p ~3',    :exp=>'$7 = -4'}
+
+  tc << {:cmd=>'p 1<<2',  :exp=>'$8 = 4'}
+  tc << {:cmd=>'p 64>>5', :exp=>'$9 = 2'}
+
+  tc << {:cmd=>'p a|c',   :exp=>'$10 = 9'}
+  tc << {:cmd=>'p a&b',   :exp=>'$11 = 1'}
+  tc << {:cmd=>'p a^b',   :exp=>'$12 = 4'}
+
+  tc << {:cmd=>'p a>b',   :exp=>'$13 = false'}
+  tc << {:cmd=>'p a<b',   :exp=>'$14 = true'}
+  tc << {:cmd=>'p b>=5',  :exp=>'$15 = true'}
+  tc << {:cmd=>'p b<=5',  :exp=>'$16 = true'}
+
+  tc << {:cmd=>'p "A"<=>"B"', :exp=>'$17 = -1'}
+  tc << {:cmd=>'p "A"=="B"',  :exp=>'$18 = false'}
+  tc << {:cmd=>'p "A"==="B"', :exp=>'$19 = false'}
+  tc << {:cmd=>'p "A"!="B"',  :exp=>'$20 = true'}
+
+  tc << {:cmd=>'p false || true', :exp=>'$21 = true'}
+  tc << {:cmd=>'p false && true', :exp=>'$22 = false'}
+
+  tc << {:cmd=>'p not nil',        :exp=>'$23 = true'}
+  tc << {:cmd=>'p false or true',  :exp=>'$24 = true'}
+  tc << {:cmd=>'p false and true', :exp=>'$25 = false'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) Ternary operation') do
+  # ruby source
+  src = <<"SRC"
+CONST = 100
+a,b,c = 1, 5, -10
+foo,bar,baz = 'foo','bar','baz'
+ary = []
+SRC
+
+  # test case
+  tc = []
+  tc << {:cmd=>'s'}
+  tc << {:cmd=>'s'}
+  tc << {:cmd=>'s'}
+
+  tc << {:cmd=>'p (a < b) ? a : b',          :exp=>'$1 = 1'}
+  tc << {:cmd=>'p (a > b) ? a : b',          :exp=>'$2 = 5'}
+  tc << {:cmd=>'p true ? "true" : "false"',  :exp=>'$3 = "true"'}
+  tc << {:cmd=>'p false ? "true" : "false"', :exp=>'$4 = "false"'}
+  tc << {:cmd=>'p nil ? "true" : "false"',   :exp=>'$5 = "false"'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) Substitution:simple') do
+  # ruby source
+  src = <<"SRC"
+CONST = 100
+a,b,c = 1, 5, -10
+foo,bar,baz = 'foo','bar','baz'
+ary = []
+SRC
+
+  # test case
+  tc = []
+  tc << {:cmd=>'s'}
+  tc << {:cmd=>'s'}
+  tc << {:cmd=>'s'}
+
+  tc << {:cmd=>'p a=2',               :exp=>'$1 = 2'}
+  tc << {:cmd=>'p foo=[foo,bar,baz]', :exp=>'$2 = ["foo", "bar", "baz"]'}
+
+  tc << {:cmd=>'p undefined=-1',      :exp=>'$3 = -1'}
+  tc << {:cmd=>'p "#{undefined}"',    :exp=>'$4 = NoMethodError'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) Substitution:self') do
+  # ruby source
+  src = <<"SRC"
+CONST = 100
+a,b,c = 1, 5, -10
+foo,bar,baz = 'foo','bar','baz'
+ary = []
+SRC
+
+  # test case
+  tc = []
+  tc << {:cmd=>'s'}
+  tc << {:cmd=>'s'}
+  tc << {:cmd=>'s'}
+
+  tc << {:cmd=>'p a+=9',   :exp=>'$1 = 10'}
+  tc << {:cmd=>'p b-=c',   :exp=>'$2 = 15'}
+  tc << {:cmd=>'p bar*=2', :exp=>'$3 = "barbar"'}
+  tc << {:cmd=>'p a/=4',   :exp=>'$4 = 2.5'}
+  tc << {:cmd=>'p c%=4',   :exp=>'$5 = 2'}
+
+  tc << {:cmd=>'p b&=0b0101', :exp=>'$6 = 5'}
+  tc << {:cmd=>'p c|=0x10',   :exp=>'$7 = 18'}
+
+  tc << {:cmd=>'p "#{a} #{b} #{c}"',     :exp=>'$8 = "2.5 5 18"'}
+  tc << {:cmd=>'p "#{foo}#{bar}#{baz}"', :exp=>'$9 = "foobarbarbaz"'}
+
+  tc << {:cmd=>'p a,b,c=[10,20,30]',:exp=>'$10 = [10, 20, 30]'}
+  tc << {:cmd=>'p [a,b,c]',         :exp=>'$11 = [10, 20, 30]'}
+  tc << {:cmd=>'p a,b=b,a',         :exp=>'$12 = [20, 10]'}
+  tc << {:cmd=>'p [a,b]',           :exp=>'$13 = [20, 10]'}
+
+  tc << {:cmd=>'p undefined=-1',    :exp=>'$14 = -1'}
+  tc << {:cmd=>'p "#{undefined}"',  :exp=>'$15 = NoMethodError'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) Substitution:multiple') do
+  # ruby source
+  src = <<"SRC"
+CONST = 100
+a,b,c = 1, 5, -10
+foo,bar,baz = 'foo','bar','baz'
+ary = []
+SRC
+
+  # test case
+  tc = []
+  tc << {:cmd=>'s'}
+  tc << {:cmd=>'s'}
+  tc << {:cmd=>'s'}
+
+  tc << {:cmd=>'p a,b=[10,20]',   :exp=>'$1 = [10, 20]'}
+  tc << {:cmd=>'p [a,b,c]',       :exp=>'$2 = [10, 20, -10]'}
+
+  tc << {:cmd=>'p foo,bar=["FOO","BAR","BAZ"]', :exp=>'$3 = ["FOO", "BAR", "BAZ"]'}
+  tc << {:cmd=>'p [foo,bar,baz]', :exp=>'$4 = ["FOO", "BAR", "baz"]'}
+
+  tc << {:cmd=>'p a,foo=foo,a',   :exp=>'$5 = ["FOO", 10]'}
+  tc << {:cmd=>'p [a,foo]',       :exp=>'$6 = ["FOO", 10]'}
+
+#  tc << {:cmd=>'p a,*b=[123, 456, 789]'}
+#  tc << {:cmd=>'p [a,b]',       :exp=>'[123, [456, 789]]'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
+assert('mruby-bin-debugger(print) Substitution:self') do
+  # ruby source
+  src = <<"SRC"
+CONST = 100
+a,b,c = 1, 5, -10
+foo,bar,baz = 'foo','bar','baz'
+ary = []
+SRC
+
+  # test case
+  tc = []
+  tc << {:cmd=>'s'}
+  tc << {:cmd=>'s'}
+  tc << {:cmd=>'s'}
+
+  tc << {:cmd=>'p a+=9',   :exp=>'$1 = 10'}
+  tc << {:cmd=>'p b-=c',   :exp=>'$2 = 15'}
+  tc << {:cmd=>'p bar*=2', :exp=>'$3 = "barbar"'}
+  tc << {:cmd=>'p a/=4',   :exp=>'$4 = 2.5'}
+  tc << {:cmd=>'p c%=4',   :exp=>'$5 = 2'}
+
+  tc << {:cmd=>'p b&=0b0101', :exp=>'$6 = 5'}
+  tc << {:cmd=>'p c|=0x10',   :exp=>'$7 = 18'}
+
+  tc << {:cmd=>'p "#{a} #{b} #{c}"',     :exp=>'$8 = "2.5 5 18"'}
+  tc << {:cmd=>'p "#{foo}#{bar}#{baz}"', :exp=>'$9 = "foobarbarbaz"'}
+
+  tc << {:cmd=>'p a,b,c=[10,20,30]',:exp=>'$10 = [10, 20, 30]'}
+  tc << {:cmd=>'p [a,b,c]',         :exp=>'$11 = [10, 20, 30]'}
+  tc << {:cmd=>'p a,b=b,a',         :exp=>'$12 = [20, 10]'}
+  tc << {:cmd=>'p [a,b]',           :exp=>'$13 = [20, 10]'}
+
+  tc << {:cmd=>'p undefined=-1',    :exp=>'$14 = -1'}
+  tc << {:cmd=>'p "#{undefined}"',  :exp=>'$15 = NoMethodError'}
+
+  BinTest_MrubyBinDebugger.test(src, tc)
+end
+
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/mrbgem.rake	(revision 331)
@@ -0,0 +1,9 @@
+MRuby::Gem::Specification.new('mruby-bin-debugger') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'mruby debugger command'
+
+  spec.add_dependency('mruby-eval', :core => 'mruby-eval')
+
+  spec.bins = %w(mrdb)
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c	(revision 331)
@@ -0,0 +1,518 @@
+/*
+** apibreak.c
+**
+*/
+
+#include <string.h>
+#include <mruby.h>
+#include <mruby/irep.h>
+#include "mrdb.h"
+#include <mruby/debug.h>
+#include <mruby/opcode.h>
+#include <mruby/class.h>
+#include <mruby/proc.h>
+#include <mruby/variable.h>
+#include "mrdberror.h"
+#include "apibreak.h"
+
+#define MAX_BREAKPOINTNO (MAX_BREAKPOINT * 1024)
+#define MRB_DEBUG_BP_FILE_OK   (0x0001)
+#define MRB_DEBUG_BP_LINENO_OK (0x0002)
+
+static uint16_t
+check_lineno(mrb_irep_debug_info_file *info_file, uint16_t lineno)
+{
+  uint32_t count = info_file->line_entry_count;
+  uint16_t l_idx;
+
+  if (info_file->line_type == mrb_debug_line_ary) {
+    for (l_idx = 0; l_idx < count; ++l_idx) {
+      if (lineno == info_file->lines.ary[l_idx]) {
+        return lineno;
+      }
+    }
+  }
+  else {
+    for (l_idx = 0; l_idx < count; ++l_idx) {
+      if (lineno == info_file->lines.flat_map[l_idx].line) {
+        return lineno;
+      }
+    }
+  }
+
+  return 0;
+}
+
+static int32_t
+get_break_index(mrb_debug_context *dbg, uint32_t bpno)
+{
+  uint32_t i;
+  int32_t index;
+  char hit = FALSE;
+
+  for(i = 0 ; i < dbg->bpnum; i++) {
+    if (dbg->bp[i].bpno == bpno) {
+      hit = TRUE;
+      index = i;
+      break;
+    }
+  }
+
+  if (hit == FALSE) {
+    return MRB_DEBUG_BREAK_INVALID_NO;
+  }
+
+  return index;
+}
+
+static void
+free_breakpoint(mrb_state *mrb, mrb_debug_breakpoint *bp)
+{
+  switch(bp->type) {
+    case MRB_DEBUG_BPTYPE_LINE:
+      mrb_free(mrb, (void*)bp->point.linepoint.file);
+      break;
+    case MRB_DEBUG_BPTYPE_METHOD:
+      mrb_free(mrb, (void*)bp->point.methodpoint.method_name);
+      if (bp->point.methodpoint.class_name != NULL) {
+        mrb_free(mrb, (void*)bp->point.methodpoint.class_name);
+      }
+      break;
+    default:
+      break;
+  }
+}
+
+static uint16_t
+check_file_lineno(struct mrb_irep *irep, const char *file, uint16_t lineno)
+{
+  mrb_irep_debug_info_file *info_file;
+  uint16_t result = 0;
+  uint16_t f_idx;
+  uint16_t fix_lineno;
+  uint16_t i;
+
+  for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) {
+    info_file = irep->debug_info->files[f_idx];
+    if (!strcmp(info_file->filename, file)) {
+      result = MRB_DEBUG_BP_FILE_OK;
+
+      fix_lineno = check_lineno(info_file, lineno);
+      if (fix_lineno != 0) {
+        return result | MRB_DEBUG_BP_LINENO_OK;
+      }
+    }
+    for (i=0; i < irep->rlen; ++i) {
+      result  |= check_file_lineno(irep->reps[i], file, lineno);
+      if (result == (MRB_DEBUG_BP_FILE_OK | MRB_DEBUG_BP_LINENO_OK)) {
+        return result;
+      }
+    }
+  }
+  return result;
+}
+
+static const char*
+get_class_name(mrb_state *mrb, struct RClass *class_obj)
+{
+  struct RClass *outer;
+  mrb_sym class_sym;
+
+  outer = mrb_class_outer_module(mrb, class_obj);
+  class_sym = mrb_class_sym(mrb, class_obj, outer);
+  return mrb_sym2name(mrb, class_sym);
+}
+
+static int32_t
+compare_break_method(mrb_state *mrb, mrb_debug_breakpoint *bp, struct RClass *class_obj, mrb_sym method_sym, mrb_bool* isCfunc)
+{
+  const char* class_name;
+  const char* method_name;
+  struct RProc* m;
+  struct RClass* sc;
+  const char* sn;
+  mrb_sym ssym;
+  mrb_debug_methodpoint *method_p;
+  mrb_bool is_defined;
+
+  method_name = mrb_sym2name(mrb, method_sym);
+
+  method_p = &bp->point.methodpoint;
+  if (strcmp(method_p->method_name, method_name) == 0) {
+    class_name = get_class_name(mrb, class_obj);
+    if (class_name == NULL) {
+      if (method_p->class_name == NULL) {
+        return bp->bpno;
+      }
+    }
+    else if (method_p->class_name != NULL) {
+      m = mrb_method_search_vm(mrb, &class_obj, method_sym);
+      if (m == NULL) {
+        return MRB_DEBUG_OK;
+      }
+      if (MRB_PROC_CFUNC_P(m)) {
+        *isCfunc = TRUE;
+      }
+
+      is_defined = mrb_class_defined(mrb, method_p->class_name);
+      if (is_defined == FALSE) {
+        return MRB_DEBUG_OK;
+      }
+
+      sc = mrb_class_get(mrb, method_p->class_name);
+      ssym = mrb_symbol(mrb_check_intern_cstr(mrb, method_p->method_name));
+      m = mrb_method_search_vm(mrb, &sc, ssym);
+      if (m == NULL) {
+        return MRB_DEBUG_OK;
+      }
+
+      class_name = get_class_name(mrb, class_obj);
+      sn = get_class_name(mrb, sc);
+      if (strcmp(sn, class_name) == 0) {
+        return bp->bpno;
+      }
+    }
+  }
+  return MRB_DEBUG_OK;
+}
+
+int32_t
+mrb_debug_set_break_line(mrb_state *mrb, mrb_debug_context *dbg, const char *file, uint16_t lineno)
+{
+  int32_t index;
+  char* set_file;
+  uint16_t result;
+
+  if ((mrb == NULL)||(dbg == NULL)||(file == NULL)) {
+    return MRB_DEBUG_INVALID_ARGUMENT;
+  }
+
+  if (dbg->bpnum >= MAX_BREAKPOINT) {
+    return MRB_DEBUG_BREAK_NUM_OVER;
+  }
+
+  if (dbg->next_bpno > MAX_BREAKPOINTNO) {
+    return MRB_DEBUG_BREAK_NO_OVER;
+  }
+
+  /* file and lineno check (line type mrb_debug_line_ary only.) */
+  result = check_file_lineno(dbg->root_irep, file, lineno);
+  if (result == 0) {
+    return MRB_DEBUG_BREAK_INVALID_FILE;
+  }
+  else if (result == MRB_DEBUG_BP_FILE_OK) {
+    return MRB_DEBUG_BREAK_INVALID_LINENO;
+  }
+
+  set_file = mrb_malloc(mrb, strlen(file) + 1);
+
+  index = dbg->bpnum;
+  dbg->bp[index].bpno = dbg->next_bpno;
+  dbg->next_bpno++;
+  dbg->bp[index].enable = TRUE;
+  dbg->bp[index].type = MRB_DEBUG_BPTYPE_LINE;
+  dbg->bp[index].point.linepoint.lineno = lineno;
+  dbg->bpnum++;
+
+  strncpy(set_file, file, strlen(file) + 1);
+
+  dbg->bp[index].point.linepoint.file = set_file;
+
+  return dbg->bp[index].bpno;
+}
+
+int32_t
+mrb_debug_set_break_method(mrb_state *mrb, mrb_debug_context *dbg, const char *class_name, const char *method_name)
+{
+  int32_t index;
+  char* set_class;
+  char* set_method;
+
+  if ((mrb == NULL) || (dbg == NULL) || (method_name == NULL)) {
+    return MRB_DEBUG_INVALID_ARGUMENT;
+  }
+
+  if (dbg->bpnum >= MAX_BREAKPOINT) {
+    return MRB_DEBUG_BREAK_NUM_OVER;
+  }
+
+  if (dbg->next_bpno > MAX_BREAKPOINTNO) {
+    return MRB_DEBUG_BREAK_NO_OVER;
+  }
+
+  if (class_name != NULL) {
+    set_class = mrb_malloc(mrb, strlen(class_name) + 1);
+    strncpy(set_class, class_name, strlen(class_name) + 1);
+  }
+  else {
+    set_class = NULL;
+  }
+
+  set_method = mrb_malloc(mrb, strlen(method_name) + 1);
+
+  strncpy(set_method, method_name, strlen(method_name) + 1);
+
+  index = dbg->bpnum;
+  dbg->bp[index].bpno = dbg->next_bpno;
+  dbg->next_bpno++;
+  dbg->bp[index].enable = TRUE;
+  dbg->bp[index].type = MRB_DEBUG_BPTYPE_METHOD;
+  dbg->bp[index].point.methodpoint.method_name = set_method;
+  dbg->bp[index].point.methodpoint.class_name = set_class;
+  dbg->bpnum++;
+
+  return dbg->bp[index].bpno;
+}
+
+int32_t
+mrb_debug_get_breaknum(mrb_state *mrb, mrb_debug_context *dbg)
+{
+  if ((mrb == NULL) || (dbg == NULL)) {
+    return MRB_DEBUG_INVALID_ARGUMENT;
+  }
+
+  return dbg->bpnum;
+}
+
+int32_t
+mrb_debug_get_break_all(mrb_state *mrb, mrb_debug_context *dbg, uint32_t size, mrb_debug_breakpoint *bp)
+{
+  uint32_t get_size = 0;
+
+  if ((mrb == NULL) || (dbg == NULL) || (bp == NULL)) {
+    return MRB_DEBUG_INVALID_ARGUMENT;
+  }
+
+  if (dbg->bpnum >= size) {
+    get_size = size;
+  }
+  else {
+    get_size = dbg->bpnum;
+  }
+
+  memcpy(bp, dbg->bp, sizeof(mrb_debug_breakpoint) * get_size);
+
+  return get_size;
+}
+
+int32_t
+mrb_debug_get_break(mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno, mrb_debug_breakpoint *bp)
+{
+  int32_t index;
+
+  if ((mrb == NULL) || (dbg == NULL) || (bp == NULL)) {
+    return MRB_DEBUG_INVALID_ARGUMENT;
+  }
+
+  index = get_break_index(dbg, bpno);
+  if (index == MRB_DEBUG_BREAK_INVALID_NO) {
+    return MRB_DEBUG_BREAK_INVALID_NO;
+  }
+
+  bp->bpno = dbg->bp[index].bpno;
+  bp->enable = dbg->bp[index].enable;
+  bp->point = dbg->bp[index].point;
+  bp->type = dbg->bp[index].type;
+
+  return 0;
+}
+
+int32_t
+mrb_debug_delete_break(mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno)
+{
+  uint32_t i;
+  int32_t index;
+
+  if ((mrb == NULL) ||(dbg == NULL)) {
+    return MRB_DEBUG_INVALID_ARGUMENT;
+  }
+
+  index = get_break_index(dbg, bpno);
+  if (index == MRB_DEBUG_BREAK_INVALID_NO) {
+    return MRB_DEBUG_BREAK_INVALID_NO;
+  }
+
+  free_breakpoint(mrb, &dbg->bp[index]);
+
+  for(i = index ; i < dbg->bpnum; i++) {
+    if ((i + 1) == dbg->bpnum) {
+      memset(&dbg->bp[i], 0, sizeof(mrb_debug_breakpoint));
+    }
+    else {
+      memcpy(&dbg->bp[i], &dbg->bp[i + 1], sizeof(mrb_debug_breakpoint));
+    }
+  }
+
+  dbg->bpnum--;
+
+  return MRB_DEBUG_OK;
+}
+
+int32_t
+mrb_debug_delete_break_all(mrb_state *mrb, mrb_debug_context *dbg)
+{
+  uint32_t i;
+
+  if ((mrb == NULL) || (dbg == NULL)) {
+    return MRB_DEBUG_INVALID_ARGUMENT;
+  }
+
+  for(i = 0 ; i < dbg->bpnum ; i++) {
+    free_breakpoint(mrb, &dbg->bp[i]);
+  }
+
+  dbg->bpnum = 0;
+
+  return MRB_DEBUG_OK;
+}
+
+int32_t
+mrb_debug_enable_break(mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno)
+{
+  int32_t index = 0;
+
+  if ((mrb == NULL) || (dbg == NULL)) {
+    return MRB_DEBUG_INVALID_ARGUMENT;
+  }
+
+  index = get_break_index(dbg, bpno);
+  if (index == MRB_DEBUG_BREAK_INVALID_NO) {
+    return MRB_DEBUG_BREAK_INVALID_NO;
+  }
+
+  dbg->bp[index].enable = TRUE;
+
+  return MRB_DEBUG_OK;
+}
+
+int32_t
+mrb_debug_enable_break_all(mrb_state *mrb, mrb_debug_context *dbg)
+{
+  uint32_t i;
+
+  if ((mrb == NULL) || (dbg == NULL)) {
+    return MRB_DEBUG_INVALID_ARGUMENT;
+  }
+
+  for(i = 0 ; i < dbg->bpnum; i++) {
+    dbg->bp[i].enable = TRUE;
+  }
+
+  return MRB_DEBUG_OK;
+}
+
+int32_t
+mrb_debug_disable_break(mrb_state *mrb, mrb_debug_context *dbg, uint32_t bpno)
+{
+  int32_t index = 0;
+
+  if ((mrb == NULL) || (dbg == NULL)) {
+    return MRB_DEBUG_INVALID_ARGUMENT;
+  }
+
+  index = get_break_index(dbg, bpno);
+  if (index == MRB_DEBUG_BREAK_INVALID_NO) {
+    return MRB_DEBUG_BREAK_INVALID_NO;
+  }
+
+  dbg->bp[index].enable = FALSE;
+
+  return MRB_DEBUG_OK;
+}
+
+int32_t
+mrb_debug_disable_break_all(mrb_state *mrb, mrb_debug_context *dbg)
+{
+  uint32_t i;
+
+  if ((mrb == NULL) || (dbg == NULL)) {
+    return MRB_DEBUG_INVALID_ARGUMENT;
+  }
+
+  for(i = 0 ; i < dbg->bpnum; i++) {
+    dbg->bp[i].enable = FALSE;
+  }
+
+  return MRB_DEBUG_OK;
+}
+
+static mrb_bool
+check_start_pc_for_line(mrb_irep *irep, mrb_code *pc, uint16_t line)
+{
+  if (pc > irep->iseq) {
+    if (line == mrb_debug_get_line(irep, (uint32_t)(pc - irep->iseq - 1))) {
+      return FALSE;
+    }
+  }
+  return TRUE;
+}
+
+int32_t
+mrb_debug_check_breakpoint_line(mrb_state *mrb, mrb_debug_context *dbg, const char *file, uint16_t line)
+{
+  mrb_debug_breakpoint *bp;
+  mrb_debug_linepoint *line_p;
+  uint32_t i;
+
+  if ((mrb == NULL) || (dbg == NULL) || (file == NULL) || (line <= 0)) {
+    return MRB_DEBUG_INVALID_ARGUMENT;
+  }
+
+  if (!check_start_pc_for_line(dbg->irep, dbg->pc, line)) {
+    return MRB_DEBUG_OK;
+  }
+
+  bp = dbg->bp;
+  for(i=0; i<dbg->bpnum; i++) {
+    switch (bp->type) {
+      case MRB_DEBUG_BPTYPE_LINE:
+        if (bp->enable == TRUE) {
+          line_p = &bp->point.linepoint;
+          if ((strcmp(line_p->file, file) == 0) && (line_p->lineno == line)) {
+            return bp->bpno;
+          }
+        }
+        break;
+      case MRB_DEBUG_BPTYPE_METHOD:
+        break;
+      case MRB_DEBUG_BPTYPE_NONE:
+      default:
+        return MRB_DEBUG_OK;
+    }
+    bp++;
+  }
+  return MRB_DEBUG_OK;
+}
+
+
+int32_t
+mrb_debug_check_breakpoint_method(mrb_state *mrb, mrb_debug_context *dbg, struct RClass *class_obj, mrb_sym method_sym, mrb_bool* isCfunc)
+{
+  mrb_debug_breakpoint *bp;
+  int32_t bpno;
+  uint32_t i;
+
+  if ((mrb == NULL) || (dbg == NULL) || (class_obj == NULL)) {
+    return MRB_DEBUG_INVALID_ARGUMENT;
+  }
+
+  bp = dbg->bp;
+  for(i=0; i<dbg->bpnum; i++) {
+    if (bp->type == MRB_DEBUG_BPTYPE_METHOD) {
+      if (bp->enable == TRUE) {
+        bpno = compare_break_method(mrb, bp, class_obj, method_sym, isCfunc);
+        if (bpno > 0) {
+          return bpno;
+        }
+      }
+    }
+    else if (bp->type == MRB_DEBUG_BPTYPE_NONE) {
+      break;
+    }
+    bp++;
+  }
+
+  return 0;
+}
+
+
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.h	(revision 331)
@@ -0,0 +1,26 @@
+/*
+** apibreak.h
+**
+*/
+
+#ifndef APIBREAK_H_
+#define APIBREAK_H_
+
+#include <mruby.h>
+#include "mrdb.h"
+
+int32_t mrb_debug_set_break_line(mrb_state *, mrb_debug_context *, const char *, uint16_t);
+int32_t mrb_debug_set_break_method(mrb_state *, mrb_debug_context *, const char *, const char *);
+int32_t mrb_debug_get_breaknum(mrb_state *, mrb_debug_context *);
+int32_t mrb_debug_get_break_all(mrb_state *, mrb_debug_context *, uint32_t, mrb_debug_breakpoint bp[]);
+int32_t mrb_debug_get_break(mrb_state *, mrb_debug_context *, uint32_t, mrb_debug_breakpoint *);
+int32_t mrb_debug_delete_break(mrb_state *, mrb_debug_context *, uint32_t);
+int32_t mrb_debug_delete_break_all(mrb_state *, mrb_debug_context *);
+int32_t mrb_debug_enable_break(mrb_state *, mrb_debug_context *, uint32_t);
+int32_t mrb_debug_enable_break_all(mrb_state *, mrb_debug_context *);
+int32_t mrb_debug_disable_break(mrb_state *, mrb_debug_context *, uint32_t);
+int32_t mrb_debug_disable_break_all(mrb_state *, mrb_debug_context *);
+int32_t mrb_debug_check_breakpoint_line(mrb_state *, mrb_debug_context *, const char *, uint16_t);
+int32_t mrb_debug_check_breakpoint_method(mrb_state *, mrb_debug_context *, struct RClass *, mrb_sym, mrb_bool*);
+
+#endif /* APIBREAK_H_ */
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c	(revision 331)
@@ -0,0 +1,235 @@
+/*
+ * apilist.c
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "mrdb.h"
+#include "mrdberror.h"
+#include "apilist.h"
+#include <mruby/compile.h>
+#include <mruby/irep.h>
+#include <mruby/debug.h>
+
+#define LINE_BUF_SIZE MAX_COMMAND_LINE
+
+typedef struct source_file {
+  char *path;
+  uint16_t lineno;
+  FILE *fp;
+} source_file;
+
+static void
+source_file_free(mrb_state *mrb, source_file *file)
+{
+  if (file != NULL) {
+    if (file->path != NULL) {
+      mrb_free(mrb, file->path);
+    }
+    if (file->fp != NULL) {
+      fclose(file->fp);
+      file->fp = NULL;
+    }
+    mrb_free(mrb, file);
+  }
+}
+
+static char*
+build_path(mrb_state *mrb, const char *dir, const char *base)
+{
+  int len;
+  char *path = NULL;
+
+  len = strlen(base) + 1;
+
+  if (strcmp(dir, ".")) {
+    len += strlen(dir) + sizeof("/") - 1;
+  }
+
+  path = mrb_malloc(mrb, len);
+  memset(path, 0, len);
+
+  if (strcmp(dir, ".")) {
+    strcat(path, dir);
+    strcat(path, "/");
+  }
+  strcat(path, base);
+
+  return path;
+}
+
+static char*
+dirname(mrb_state *mrb, const char *path)
+{
+  size_t len;
+  char *p, *dir;
+
+  if (path == NULL) {
+    return NULL;
+  }
+
+  p = strrchr(path, '/');
+  len = p != NULL ? (size_t)(p - path) : strlen(path);
+
+  dir = mrb_malloc(mrb, len + 1);
+  strncpy(dir, path, len);
+  dir[len] = '\0';
+
+  return dir;
+}
+
+static source_file*
+source_file_new(mrb_state *mrb, mrb_debug_context *dbg, char *filename)
+{
+  source_file *file = NULL;
+
+  file = mrb_malloc(mrb, sizeof(source_file));
+
+  memset(file, '\0', sizeof(source_file));
+  file->fp = fopen(filename, "rb");
+
+  if (file->fp == NULL) {
+    source_file_free(mrb, file);
+    return NULL;
+  }
+
+  file->lineno = 1;
+  file->path = mrb_malloc(mrb, strlen(filename) + 1);
+  strcpy(file->path, filename);
+  return file;
+}
+
+static mrb_bool
+remove_newlines(char *s, FILE *fp)
+{
+  int c;
+  char *p;
+  size_t len;
+
+  if ((len = strlen(s)) == 0) {
+    return FALSE;
+  }
+
+  p = s + len - 1;
+
+  if (*p != '\r' && *p != '\n') {
+    return FALSE;
+  }
+
+  if (*p == '\r') {
+    /* peek the next character and skip '\n' */
+    if ((c = fgetc(fp)) != '\n') {
+      ungetc(c, fp);
+    }
+  }
+
+  /* remove trailing newline characters */
+  while (s <= p && (*p == '\r' || *p == '\n')) {
+    *p-- = '\0';
+  }
+
+  return TRUE;
+}
+
+static void
+show_lines(source_file *file, uint16_t line_min, uint16_t line_max)
+{
+  char buf[LINE_BUF_SIZE];
+  int show_lineno = 1, found_newline = 0, is_printed = 0;
+
+  if (file->fp == NULL) {
+    return;
+  }
+
+  while (fgets(buf, sizeof(buf), file->fp) != NULL) {
+    found_newline = remove_newlines(buf, file->fp);
+
+    if (line_min <= file->lineno) {
+      if (show_lineno) {
+        printf("%-8d", file->lineno);
+      }
+      show_lineno = found_newline;
+      printf(found_newline ? "%s\n" : "%s", buf);
+      is_printed = 1;
+    }
+
+    if (found_newline) {
+      if (line_max < ++file->lineno) {
+        break;
+      }
+    }
+  }
+
+  if (is_printed && !found_newline) {
+    printf("\n");
+  }
+}
+
+char*
+mrb_debug_get_source(mrb_state *mrb, mrdb_state *mrdb, const char *srcpath, const char *filename)
+{
+  int i;
+  FILE *fp;
+  const char *search_path[3];
+  char *path = NULL;
+
+  search_path[0] = srcpath;
+  search_path[1] = dirname(mrb, mrb_debug_get_filename(mrdb->dbg->root_irep, 0));
+  search_path[2] = ".";
+
+  for (i = 0; i < 3; i++) {
+    if (search_path[i] == NULL) {
+      continue;
+    }
+
+    if ((path = build_path(mrb, search_path[i], filename)) == NULL) {
+      continue;
+    }
+
+    if ((fp = fopen(path, "rb")) == NULL) {
+      mrb_free(mrb, path);
+      path = NULL;
+      continue;
+    }
+    fclose(fp);
+    break;
+  }
+
+  mrb_free(mrb, (void *)search_path[1]);
+
+  return path;
+}
+
+int32_t
+mrb_debug_list(mrb_state *mrb, mrb_debug_context *dbg, char *filename, uint16_t line_min, uint16_t line_max)
+{
+  char *ext;
+  source_file *file;
+
+  if (mrb == NULL || dbg == NULL || filename == NULL) {
+    return MRB_DEBUG_INVALID_ARGUMENT;
+  }
+
+  ext = strrchr(filename, '.');
+
+  if (ext == NULL || strcmp(ext, ".rb")) {
+    printf("List command only supports .rb file.\n");
+    return MRB_DEBUG_INVALID_ARGUMENT;
+  }
+
+  if (line_min > line_max) {
+    return MRB_DEBUG_INVALID_ARGUMENT;
+  }
+
+  if ((file = source_file_new(mrb, dbg, filename)) != NULL) {
+    show_lines(file, line_min, line_max);
+    source_file_free(mrb, file);
+    return MRB_DEBUG_OK;
+  }
+  else {
+    printf("Invalid source file named %s.\n", filename);
+    return MRB_DEBUG_INVALID_ARGUMENT;
+  }
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h	(revision 331)
@@ -0,0 +1,14 @@
+/*
+ * apilist.h
+ */
+
+#ifndef APILIST_H_
+#define APILIST_H_
+
+#include <mruby.h>
+#include "mrdb.h"
+
+int32_t mrb_debug_list(mrb_state *, mrb_debug_context *, char *, uint16_t, uint16_t);
+char* mrb_debug_get_source(mrb_state *, mrdb_state *, const char *, const char *);
+
+#endif /* APILIST_H_ */
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c	(revision 331)
@@ -0,0 +1,78 @@
+/*
+** apiprint.c
+**
+*/
+
+#include <string.h>
+#include "mrdb.h"
+#include <mruby/value.h>
+#include <mruby/class.h>
+#include <mruby/compile.h>
+#include <mruby/error.h>
+#include <mruby/numeric.h>
+#include <mruby/string.h>
+#include "apiprint.h"
+
+static void
+mrdb_check_syntax(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t len)
+{
+  mrbc_context *c;
+
+  c = mrbc_context_new(mrb);
+  c->no_exec = TRUE;
+  c->capture_errors = TRUE;
+  c->filename = (char*)dbg->prvfile;
+  c->lineno = dbg->prvline;
+
+  /* Load program */
+  mrb_load_nstring_cxt(mrb, expr, len, c);
+
+  mrbc_context_free(mrb, c);
+}
+
+mrb_value
+mrb_debug_eval(mrb_state *mrb, mrb_debug_context *dbg, const char *expr, size_t len, mrb_bool *exc)
+{
+  void (*tmp)(struct mrb_state *, struct mrb_irep *, mrb_code *, mrb_value *);
+  mrb_value ruby_code;
+  mrb_value s;
+  mrb_value v;
+  mrb_value recv;
+
+  /* disable code_fetch_hook */
+  tmp = mrb->code_fetch_hook;
+  mrb->code_fetch_hook = NULL;
+
+  mrdb_check_syntax(mrb, dbg, expr, len);
+  if (mrb->exc) {
+    v = mrb_obj_value(mrb->exc);
+    mrb->exc = 0;
+  }
+  else {
+    /*
+     * begin
+     *   expr
+     * rescue => e
+     *   e
+     * end
+     */
+    ruby_code = mrb_str_new_lit(mrb, "begin\n");
+    ruby_code = mrb_str_cat(mrb, ruby_code, expr, len);
+    ruby_code = mrb_str_cat_lit(mrb, ruby_code, "\nrescue => e\ne\nend");
+
+    recv = dbg->regs[0];
+
+    v =  mrb_funcall(mrb, recv, "instance_eval", 1, ruby_code);
+  }
+
+  if (exc) {
+    *exc = mrb_obj_is_kind_of(mrb, v, mrb->eException_class);
+  }
+
+  s = mrb_funcall(mrb, v, "inspect", 0);
+
+  /* enable code_fetch_hook */
+  mrb->code_fetch_hook = tmp;
+
+  return s;
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.h	(revision 331)
@@ -0,0 +1,13 @@
+/*
+ * apiprint.h
+ */
+
+#ifndef APIPRINT_H_
+#define APIPRINT_H_
+
+#include <mruby.h>
+#include "mrdb.h"
+
+mrb_value mrb_debug_eval(mrb_state*, mrb_debug_context*, const char*, size_t, mrb_bool*);
+
+#endif /* APIPRINT_H_ */
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c	(revision 331)
@@ -0,0 +1,436 @@
+/*
+** cmdbreak.c
+**
+*/
+
+#include <ctype.h>
+#include <string.h>
+#include <mruby.h>
+#include <mruby/dump.h>
+#include <mruby/debug.h>
+#include <mruby/string.h>
+#include "mrdb.h"
+#include "mrdberror.h"
+#include "apibreak.h"
+
+#define BREAK_SET_MSG_LINE                  "Breakpoint %d: file %s, line %d.\n"
+#define BREAK_SET_MSG_METHOD                "Breakpoint %d: method %s.\n"
+#define BREAK_SET_MSG_CLASS_METHOD          "Breakpoint %d: class %s, method %s.\n"
+#define BREAK_INFO_MSG_HEADER               "Num     Type           Enb What"
+#define BREAK_INFO_MSG_LINEBREAK            "%-8ubreakpoint     %s   at %s:%u\n"
+#define BREAK_INFO_MSG_METHODBREAK          "%-8ubreakpoint     %s   in %s:%s\n"
+#define BREAK_INFO_MSG_METHODBREAK_NOCLASS  "%-8ubreakpoint     %s   in %s\n"
+#define BREAK_INFO_MSG_ENABLE               "y"
+#define BREAK_INFO_MSG_DISABLE              "n"
+
+#define BREAK_ERR_MSG_INVALIDARG            "Internal error."
+#define BREAK_ERR_MSG_BLANK                 "Try \'help break\' for more information."
+#define BREAK_ERR_MSG_RANGEOVER             "The line number range is from 1 to 65535."
+#define BREAK_ERR_MSG_NUMOVER               "Exceeded the setable number of breakpoint."
+#define BREAK_ERR_MSG_NOOVER                "Breakno is over the available number.Please 'quit' and restart mrdb."
+#define BREAK_ERR_MSG_INVALIDSTR            "String \'%s\' is invalid.\n"
+#define BREAK_ERR_MSG_INVALIDLINENO         "Line %d in file \"%s\" is unavailable.\n"
+#define BREAK_ERR_MSG_INVALIDCLASS          "Class name \'%s\' is invalid.\n"
+#define BREAK_ERR_MSG_INVALIDMETHOD         "Method name \'%s\' is invalid.\n"
+#define BREAK_ERR_MSG_INVALIDFILE           "Source file named \"%s\" is unavailable.\n"
+#define BREAK_ERR_MSG_INVALIDBPNO           "warning: bad breakpoint number at or near '%s'\n"
+#define BREAK_ERR_MSG_INVALIDBPNO_INFO      "Args must be numbers variables."
+#define BREAK_ERR_MSG_NOBPNO                "No breakpoint number %d.\n"
+#define BREAK_ERR_MSG_NOBPNO_INFO           "No breakpoint matching '%d'\n"
+#define BREAK_ERR_MSG_NOBPNO_INFOALL        "No breakpoints."
+
+#define LINENO_MAX_DIGIT 6
+#define BPNO_LETTER_NUM 9
+
+typedef int32_t (*all_command_func)(mrb_state *, mrb_debug_context *);
+typedef int32_t (*select_command_func)(mrb_state *, mrb_debug_context *, uint32_t);
+
+static void
+print_api_common_error(int32_t error)
+{
+  switch(error) {
+    case MRB_DEBUG_INVALID_ARGUMENT:
+      puts(BREAK_ERR_MSG_INVALIDARG);
+      break;
+    default:
+      break;
+  }
+}
+
+#undef STRTOUL
+#define STRTOUL(ul,s) { \
+    int i; \
+    ul = 0; \
+    for(i=0; ISDIGIT(s[i]); i++) ul = 10*ul + (s[i] -'0'); \
+}
+
+static int32_t
+parse_breakpoint_no(char* args)
+{
+  char* ps = args;
+  uint32_t l;
+
+  if ((*ps == '0')||(strlen(ps) >= BPNO_LETTER_NUM)) {
+    return 0;
+  }
+
+  while (!(ISBLANK(*ps)||ISCNTRL(*ps))) {
+    if (!ISDIGIT(*ps)) {
+      return 0;
+    }
+    ps++;
+  }
+
+  STRTOUL(l, args);
+  return l;
+}
+
+static mrb_bool
+exe_set_command_all(mrb_state *mrb, mrdb_state *mrdb, all_command_func func)
+{
+  int32_t ret = MRB_DEBUG_OK;
+
+  if (mrdb->wcnt == 1) {
+    ret = func(mrb, mrdb->dbg);
+    print_api_common_error(ret);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static void
+exe_set_command_select(mrb_state *mrb, mrdb_state *mrdb, select_command_func func)
+{
+  char* ps;
+  int32_t ret = MRB_DEBUG_OK;
+  int32_t bpno = 0;
+  int32_t i;
+
+  for(i=1; i<mrdb->wcnt; i++) {
+    ps = mrdb->words[i];
+    bpno = parse_breakpoint_no(ps);
+    if (bpno == 0) {
+      printf(BREAK_ERR_MSG_INVALIDBPNO, ps);
+      break;
+    }
+    ret = func(mrb, mrdb->dbg, (uint32_t)bpno);
+    if (ret == MRB_DEBUG_BREAK_INVALID_NO) {
+      printf(BREAK_ERR_MSG_NOBPNO, bpno);
+    }
+    else if (ret != MRB_DEBUG_OK) {
+      print_api_common_error(ret);
+    }
+  }
+}
+
+mrb_debug_bptype
+check_bptype(char* args)
+{
+  char* ps = args;
+
+  if (ISBLANK(*ps)||ISCNTRL(*ps)) {
+    puts(BREAK_ERR_MSG_BLANK);
+    return MRB_DEBUG_BPTYPE_NONE;
+  }
+
+  if (!ISDIGIT(*ps)) {
+    return MRB_DEBUG_BPTYPE_METHOD;
+  }
+
+  while (!(ISBLANK(*ps)||ISCNTRL(*ps))) {
+    if (!ISDIGIT(*ps)) {
+      printf(BREAK_ERR_MSG_INVALIDSTR, args);
+      return MRB_DEBUG_BPTYPE_NONE;
+    }
+    ps++;
+  }
+
+  if ((*args == '0')||(strlen(args) >= LINENO_MAX_DIGIT)) {
+    puts(BREAK_ERR_MSG_RANGEOVER);
+    return MRB_DEBUG_BPTYPE_NONE;
+  }
+
+  return MRB_DEBUG_BPTYPE_LINE;
+}
+
+static void
+print_breakpoint(mrb_debug_breakpoint *bp)
+{
+  const char* enable_letter[] = {BREAK_INFO_MSG_DISABLE, BREAK_INFO_MSG_ENABLE};
+
+  if (bp->type == MRB_DEBUG_BPTYPE_LINE) {
+    printf(BREAK_INFO_MSG_LINEBREAK,
+      bp->bpno, enable_letter[bp->enable], bp->point.linepoint.file, bp->point.linepoint.lineno);
+  }
+  else {
+    if (bp->point.methodpoint.class_name == NULL) {
+      printf(BREAK_INFO_MSG_METHODBREAK_NOCLASS,
+        bp->bpno, enable_letter[bp->enable], bp->point.methodpoint.method_name);
+    }
+    else {
+      printf(BREAK_INFO_MSG_METHODBREAK,
+        bp->bpno, enable_letter[bp->enable], bp->point.methodpoint.class_name, bp->point.methodpoint.method_name);
+    }
+  }
+}
+
+static void
+info_break_all(mrb_state *mrb, mrdb_state *mrdb)
+{
+  int32_t bpnum = 0;
+  int32_t i = 0;
+  int32_t ret = MRB_DEBUG_OK;
+  mrb_debug_breakpoint *bp_list;
+
+  bpnum = mrb_debug_get_breaknum(mrb, mrdb->dbg);
+  if (bpnum < 0) {
+    print_api_common_error(bpnum);
+    return;
+  }
+  else if (bpnum == 0) {
+    puts(BREAK_ERR_MSG_NOBPNO_INFOALL);
+    return;
+  }
+  bp_list = (mrb_debug_breakpoint*)mrb_malloc(mrb, bpnum * sizeof(mrb_debug_breakpoint));
+
+  ret = mrb_debug_get_break_all(mrb, mrdb->dbg, (uint32_t)bpnum, bp_list);
+  if (ret < 0) {
+    print_api_common_error(ret);
+    return;
+  }
+  puts(BREAK_INFO_MSG_HEADER);
+  for(i = 0 ; i < bpnum ; i++) {
+    print_breakpoint(&bp_list[i]);
+  }
+
+  mrb_free(mrb, bp_list);
+}
+
+static void
+info_break_select(mrb_state *mrb, mrdb_state *mrdb)
+{
+  int32_t ret = MRB_DEBUG_OK;
+  int32_t bpno = 0;
+  char* ps = mrdb->command;
+  mrb_debug_breakpoint bp;
+  mrb_bool isFirst = TRUE;
+  int32_t i;
+
+  for(i=2; i<mrdb->wcnt; i++) {
+    ps = mrdb->words[i];
+    bpno = parse_breakpoint_no(ps);
+    if (bpno == 0) {
+      puts(BREAK_ERR_MSG_INVALIDBPNO_INFO);
+      break;
+    }
+
+    ret = mrb_debug_get_break(mrb, mrdb->dbg, bpno, &bp);
+    if (ret == MRB_DEBUG_BREAK_INVALID_NO) {
+      printf(BREAK_ERR_MSG_NOBPNO_INFO, bpno);
+      break;
+    }
+    else if (ret != MRB_DEBUG_OK) {
+      print_api_common_error(ret);
+      break;
+    }
+    else if (isFirst == TRUE) {
+      isFirst = FALSE;
+      puts(BREAK_INFO_MSG_HEADER);
+    }
+    print_breakpoint(&bp);
+  }
+}
+
+mrb_debug_bptype
+parse_breakcommand(mrdb_state *mrdb, const char **file, uint32_t *line, char **cname, char **method)
+{
+  mrb_debug_context *dbg = mrdb->dbg;
+  char *args;
+  char *body;
+  mrb_debug_bptype type;
+  uint32_t l;
+
+  if (mrdb->wcnt <= 1) {
+    puts(BREAK_ERR_MSG_BLANK);
+    return MRB_DEBUG_BPTYPE_NONE;
+  }
+
+  args = mrdb->words[1];
+  if ((body = strrchr(args, ':')) == NULL) {
+    body = args;
+    type = check_bptype(body);
+  }
+  else {
+    if (body == args) {
+      printf(BREAK_ERR_MSG_INVALIDSTR, args);
+      return MRB_DEBUG_BPTYPE_NONE;
+    }
+    *body = '\0';
+    type = check_bptype(++body);
+  }
+
+  switch(type) {
+    case MRB_DEBUG_BPTYPE_LINE:
+      STRTOUL(l, body);
+      if (l <= 65535) {
+        *line = l;
+        *file = (body == args)? mrb_debug_get_filename(dbg->irep, (uint32_t)(dbg->pc - dbg->irep->iseq)): args;
+      }
+      else {
+        puts(BREAK_ERR_MSG_RANGEOVER);
+        type = MRB_DEBUG_BPTYPE_NONE;
+      }
+      break;
+    case MRB_DEBUG_BPTYPE_METHOD:
+      if (body == args) {
+        /* method only */
+        if (ISUPPER(*body)||ISLOWER(*body)||(*body == '_')) {
+          *method = body;
+          *cname = NULL;
+        }
+        else {
+          printf(BREAK_ERR_MSG_INVALIDMETHOD, args);
+          type = MRB_DEBUG_BPTYPE_NONE;
+        }
+      }
+      else {
+        if (ISUPPER(*args)) {
+          switch(*body) {
+            case '@': case '$': case '?': case '.': case ',': case ':':
+            case ';': case '#': case '\\': case '\'': case '\"':
+            printf(BREAK_ERR_MSG_INVALIDMETHOD, body);
+            type = MRB_DEBUG_BPTYPE_NONE;
+            break;
+          default:
+            *method = body;
+            *cname = args;
+            break;
+          }
+        }
+        else {
+          printf(BREAK_ERR_MSG_INVALIDCLASS, args);
+          type = MRB_DEBUG_BPTYPE_NONE;
+        }
+      }
+      break;
+    case MRB_DEBUG_BPTYPE_NONE:
+    default:
+      break;
+  }
+
+  return type;
+}
+
+dbgcmd_state
+dbgcmd_break(mrb_state *mrb, mrdb_state *mrdb)
+{
+  mrb_debug_bptype type;
+  mrb_debug_context *dbg = mrdb->dbg;
+  const char *file = NULL;
+  uint32_t line = 0;
+  char *cname = NULL;
+  char *method = NULL;
+  int32_t ret;
+
+  type = parse_breakcommand(mrdb, &file, &line, &cname, &method);
+  switch (type) {
+    case MRB_DEBUG_BPTYPE_LINE:
+      ret = mrb_debug_set_break_line(mrb, dbg, file, line);
+      break;
+    case MRB_DEBUG_BPTYPE_METHOD:
+      ret = mrb_debug_set_break_method(mrb, dbg, cname, method);
+      break;
+    case MRB_DEBUG_BPTYPE_NONE:
+    default:
+      return DBGST_PROMPT;
+  }
+
+  if (ret >= 0) {
+    if (type == MRB_DEBUG_BPTYPE_LINE) {
+      printf(BREAK_SET_MSG_LINE, ret, file, line);
+    }
+    else if ((type == MRB_DEBUG_BPTYPE_METHOD)&&(cname == NULL)) {
+      printf(BREAK_SET_MSG_METHOD, ret, method);
+    }
+    else {
+      printf(BREAK_SET_MSG_CLASS_METHOD, ret, cname, method);
+    }
+  }
+  else {
+    switch (ret) {
+      case MRB_DEBUG_BREAK_INVALID_LINENO:
+        printf(BREAK_ERR_MSG_INVALIDLINENO, line, file);
+        break;
+      case MRB_DEBUG_BREAK_INVALID_FILE:
+        printf(BREAK_ERR_MSG_INVALIDFILE, file);
+        break;
+      case MRB_DEBUG_BREAK_NUM_OVER:
+        puts(BREAK_ERR_MSG_NUMOVER);
+        break;
+      case MRB_DEBUG_BREAK_NO_OVER:
+        puts(BREAK_ERR_MSG_NOOVER);
+        break;
+      case MRB_DEBUG_INVALID_ARGUMENT:
+        puts(BREAK_ERR_MSG_INVALIDARG);
+        break;
+      case MRB_DEBUG_NOBUF:
+        puts("T.B.D.");
+        break;
+      default:
+        break;
+    }
+  }
+
+  return DBGST_PROMPT;
+}
+
+dbgcmd_state
+dbgcmd_info_break(mrb_state *mrb, mrdb_state *mrdb)
+{
+  if (mrdb->wcnt == 2) {
+    info_break_all(mrb, mrdb);
+  }
+  else {
+    info_break_select(mrb, mrdb);
+  }
+
+  return DBGST_PROMPT;
+}
+
+dbgcmd_state
+dbgcmd_delete(mrb_state *mrb, mrdb_state *mrdb)
+{
+  mrb_bool ret = FALSE;
+
+  ret = exe_set_command_all(mrb, mrdb, mrb_debug_delete_break_all);
+  if (ret != TRUE) {
+    exe_set_command_select(mrb, mrdb, mrb_debug_delete_break);
+  }
+
+  return DBGST_PROMPT;
+}
+
+dbgcmd_state
+dbgcmd_enable(mrb_state *mrb, mrdb_state *mrdb)
+{
+  mrb_bool ret = FALSE;
+
+  ret = exe_set_command_all(mrb, mrdb, mrb_debug_enable_break_all);
+  if (ret != TRUE) {
+    exe_set_command_select(mrb, mrdb, mrb_debug_enable_break);
+  }
+
+  return DBGST_PROMPT;
+}
+
+dbgcmd_state
+dbgcmd_disable(mrb_state *mrb, mrdb_state *mrdb)
+{
+  mrb_bool ret = FALSE;
+
+  ret = exe_set_command_all(mrb, mrdb, mrb_debug_disable_break_all);
+  if (ret != TRUE) {
+    exe_set_command_select(mrb, mrdb, mrb_debug_disable_break);
+  }
+  return DBGST_PROMPT;
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c	(revision 331)
@@ -0,0 +1,501 @@
+/*
+** cmdmisc.c - mruby debugger miscellaneous command functions
+**
+*/
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "apilist.h"
+#include <mruby/compile.h>
+
+typedef struct help_msg {
+  const char *cmd1;
+  const char *cmd2;
+  const char *short_msg;
+  const char *long_msg;
+} help_msg;
+
+static help_msg help_msg_list[] = {
+  {
+    "b[reak]", NULL, "Set breakpoint",
+    "Usage: break [file:]line\n"
+    "       break [class:]method\n"
+    "\n"
+    "Set breakpoint at specified line or method.\n"
+    "If \'[file:]line\' is specified, break at start of code for that line (in a file).\n"
+    "If \'[class:]method\' is specified, break at start of code for that method (of the class).\n"
+  },
+  {
+    "c[ontinue]", NULL, "Continue program being debugged",
+    "Usage: continue [N]\n"
+    "\n"
+    "Continue program stopped by a breakpoint.\n"
+    "If N, which is non negative value, is passed,\n"
+    "proceed program until the N-th breakpoint is coming.\n"
+    "If N is not passed, N is assumed 1.\n"
+  },
+  {
+    "d[elete]", NULL, "Delete some breakpoints",
+    "Usage: delete [bpno1 [bpno2 [... [bpnoN]]]]\n"
+    "\n"
+    "Delete some breakpoints.\n"
+    "Arguments are breakpoint numbers with spaces in between.\n"
+    "To delete all breakpoints, give no argument.\n"
+  },
+  {
+    "dis[able]", NULL, "Disable some breakpoints",
+    "Usage: disable [bpno1 [bpno2 [... [bpnoN]]]]\n"
+    "\n"
+    "Disable some breakpoints.\n"
+    "Arguments are breakpoint numbers with spaces in between.\n"
+    "To disable all breakpoints, give no argument.\n"
+  },
+  {
+    "en[able]", NULL, "Enable some breakpoints",
+    "Usage: enable [bpno1 [bpno2 [... [bpnoN]]]]\n"
+    "\n"
+    "Enable some breakpoints.\n"
+    "Arguments are breakpoint numbers with spaces in between.\n"
+    "To enable all breakpoints, give no argument.\n"
+  },
+  {
+    "ev[al]", NULL, "Evaluate expression",
+    "Usage: eval expr\n"
+    "\n"
+    "It evaluates and prints the value of the mruby expression.\n"
+    "This is equivalent to the \'print\' command.\n"
+  },
+  {
+    "h[elp]", NULL, "Print this help",
+    "Usage: help [command]\n"
+    "\n"
+    "With no arguments, help displays a short list of commands.\n"
+    "With a command name as help argument, help displays how to use that command.\n"
+  },
+  {
+    "i[nfo]", "b[reakpoints]", "Status of breakpoints",
+    "Usage: info breakpoints [bpno1 [bpno2 [... [bpnoN]]]]\n"
+    "\n"
+    "Status of specified breakpoints (all user-settable breakpoints if no argument).\n"
+    "Arguments are breakpoint numbers with spaces in between.\n"
+  },
+  {
+    "l[ist]", NULL, "List specified line",
+    "Usage: list\n"
+    "       list first[,last]\n"
+    "       list filename:first[,last]\n"
+    "\n"
+    "Print lines from a source file.\n"
+    "\n"
+    "With first and last, list prints lines from first to last.\n"
+    "When last is empty, it stands for ten lines away from first.\n"
+    "With filename, list prints lines in the specified source file.\n"
+  },
+  {
+    "p[rint]", NULL, "Print value of expression",
+    "Usage: print expr\n"
+    "\n"
+    "It evaluates and prints the value of the mruby expression.\n"
+    "This is equivalent to the \'eval\' command.\n"
+  },
+  {
+    "q[uit]", NULL, "Exit mrdb",
+    "Usage: quit\n"
+    "\n"
+    "Exit mrdb.\n"
+  },
+  {
+    "r[un]", NULL, "Start debugged program",
+    "Usage: run\n"
+    "\n"
+    "Start debugged program.\n"
+  },
+  {
+    "s[tep]", NULL, "Step program until it reaches a different source line",
+    "Usage: step\n"
+    "\n"
+    "Step program until it reaches a different source line.\n"
+  },
+  { NULL, NULL, NULL, NULL }
+};
+
+typedef struct listcmd_parser_state {
+  mrb_bool parse_error;
+  mrb_bool has_line_min;
+  mrb_bool has_line_max;
+  char *filename;
+  uint16_t line_min;
+  uint16_t line_max;
+} listcmd_parser_state;
+
+static listcmd_parser_state*
+listcmd_parser_state_new(mrb_state *mrb)
+{
+  listcmd_parser_state *st = mrb_malloc(mrb, sizeof(listcmd_parser_state));
+  memset(st, 0, sizeof(listcmd_parser_state));
+  return st;
+}
+
+static void
+listcmd_parser_state_free(mrb_state *mrb, listcmd_parser_state *st)
+{
+  if (st != NULL) {
+    if (st->filename != NULL) {
+      mrb_free(mrb, st->filename);
+    }
+    mrb_free(mrb, st);
+  }
+}
+
+static mrb_bool
+parse_uint(char **sp, uint16_t *n)
+{
+  char *p;
+  int i;
+
+  if (*sp == NULL || **sp == '\0') {
+    return FALSE;
+  }
+
+  for (p = *sp; *p != '\0' && ISDIGIT(*p); p++) ;
+
+  if (p != *sp && (i = atoi(*sp)) >= 0) {
+    *n = (uint16_t)i;
+    *sp = p;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static mrb_bool
+skip_char(char **sp, char c)
+{
+  if (*sp != NULL && **sp == c) {
+    ++*sp;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static mrb_bool
+parse_lineno(mrb_state *mrb, char **sp, listcmd_parser_state *st)
+{
+  if (*sp == NULL || **sp == '\0') {
+    return FALSE;
+  }
+
+  st->has_line_min = FALSE;
+  st->has_line_max = FALSE;
+
+  if (parse_uint(sp, &st->line_min)) {
+    st->has_line_min = TRUE;
+  }
+  else {
+    return FALSE;
+  }
+
+  if (skip_char(sp, ',')) {
+    if (parse_uint(sp, &st->line_max)) {
+      st->has_line_max = TRUE;
+    }
+    else {
+      st->parse_error = TRUE;
+      return FALSE;
+    }
+  }
+  return TRUE;
+}
+
+static mrb_bool
+parse_filename(mrb_state *mrb, char **sp, listcmd_parser_state *st)
+{
+  char *p;
+  int len;
+
+  if (st->filename != NULL) {
+    mrb_free(mrb, st->filename);
+    st->filename = NULL;
+  }
+
+  if ((p = strchr(*sp, ':')) != NULL) {
+    len = p - *sp;
+  }
+  else {
+    len = strlen(*sp);
+  }
+
+  if (len > 0) {
+    st->filename = mrb_malloc(mrb, len + 1);
+    strncpy(st->filename, *sp, len);
+    st->filename[len] = '\0';
+    *sp += len;
+    return TRUE;
+  }
+  else {
+    return FALSE;
+  }
+}
+
+char*
+replace_ext(mrb_state *mrb, const char *filename, const char *ext)
+{
+  size_t len;
+  char *p, *s;
+
+  if (filename == NULL) {
+    return NULL;
+  }
+
+  if ((p = strrchr(filename, '.')) != NULL && strchr(p, '/') == NULL) {
+    len = p - filename;
+  }
+  else {
+    len = strlen(filename);
+  }
+
+  s = mrb_malloc(mrb, len + strlen(ext) + 1);
+  memset(s, '\0', len + strlen(ext) + 1);
+  strncpy(s, filename, len);
+  strcat(s, ext);
+
+  return s;
+}
+
+static mrb_bool
+parse_listcmd_args(mrb_state *mrb, mrdb_state *mrdb, listcmd_parser_state *st)
+{
+  char *p;
+
+  switch (mrdb->wcnt) {
+  case 2:
+    p = mrdb->words[1];
+
+    /* mrdb->words[1] ::= <lineno> | <filename> ':' <lineno> | <filename> */
+    if (!parse_lineno(mrb, &p, st)) {
+      if (parse_filename(mrb, &p, st)) {
+        if (skip_char(&p, ':')) {
+          if (!parse_lineno(mrb, &p, st)) {
+            st->parse_error = TRUE;
+          }
+        }
+      }
+      else {
+        st->parse_error = TRUE;
+      }
+    }
+    if (*p != '\0') {
+      st->parse_error = TRUE;
+    }
+    break;
+  case 1:
+  case 0:
+    /* do nothing */
+    break;
+  default:
+    st->parse_error = TRUE;
+    printf("too many arguments\n");
+    break;
+  }
+
+  if (!st->parse_error) {
+    if (!st->has_line_min) {
+      st->line_min = (!st->filename && mrdb->dbg->prvline > 0) ? mrdb->dbg->prvline : 1;
+    }
+
+    if (!st->has_line_max) {
+      st->line_max = st->line_min + 9;
+    }
+
+    if (st->filename == NULL) {
+      if (mrdb->dbg->prvfile && strcmp(mrdb->dbg->prvfile, "-")) {
+        st->filename = replace_ext(mrb, mrdb->dbg->prvfile, ".rb");
+      }
+    }
+  }
+
+  if (st->parse_error || st->filename == NULL) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+static mrb_bool
+check_cmd_pattern(const char *pattern, const char *cmd)
+{
+  char *lbracket, *rbracket, *p, *q;
+
+  if (pattern == NULL && cmd == NULL) {
+    return TRUE;
+  }
+  if (pattern == NULL || cmd == NULL) {
+    return FALSE;
+  }
+  if ((lbracket = strchr(pattern, '[')) == NULL) {
+    return !strcmp(pattern, cmd);
+  }
+  if ((rbracket = strchr(pattern, ']')) == NULL) {
+    return FALSE;
+  }
+  if (strncmp(pattern, cmd, lbracket - pattern)) {
+    return FALSE;
+  }
+
+  p = lbracket + 1;
+  q = (char *)cmd + (lbracket - pattern);
+
+  for ( ; p < rbracket && *q != '\0'; p++, q++) {
+    if (*p != *q) {
+      break;
+    }
+  }
+  return *q == '\0';
+}
+
+static help_msg*
+get_help_msg(char *cmd1, char *cmd2)
+{
+  help_msg *p;
+
+  if (cmd1 == NULL) {
+    return NULL;
+  }
+  for (p = help_msg_list; p->cmd1 != NULL; p++) {
+    if (check_cmd_pattern(p->cmd1, cmd1) && check_cmd_pattern(p->cmd2, cmd2)) {
+      return p;
+    }
+  }
+  return NULL;
+}
+
+static mrb_bool
+show_short_help(void)
+{
+  help_msg *p;
+
+  printf("Commands\n");
+
+  for (p = help_msg_list; p->cmd1 != NULL; p++) {
+    if (p->cmd2 == NULL) {
+      printf("  %s -- %s\n", p->cmd1, p->short_msg);
+    }
+    else {
+      printf("  %s %s -- %s\n", p->cmd1, p->cmd2, p->short_msg);
+    }
+  }
+  return TRUE;
+}
+
+static mrb_bool
+show_long_help(char *cmd1, char *cmd2)
+{
+  help_msg *help;
+
+  if ((help = get_help_msg(cmd1, cmd2)) == NULL) {
+    return FALSE;
+  }
+  printf("%s", help->long_msg);
+  return TRUE;
+}
+
+dbgcmd_state
+dbgcmd_list(mrb_state *mrb, mrdb_state *mrdb)
+{
+  char *filename;
+  listcmd_parser_state *st = listcmd_parser_state_new(mrb);
+
+  if (parse_listcmd_args(mrb, mrdb, st)) {
+    if ((filename = mrb_debug_get_source(mrb, mrdb, mrdb->srcpath, st->filename)) == NULL) {
+      filename = st->filename;
+    }
+    mrb_debug_list(mrb, mrdb->dbg, filename, st->line_min, st->line_max);
+
+    if (filename != NULL && filename != st->filename) {
+      mrb_free(mrb, filename);
+    }
+    listcmd_parser_state_free(mrb, st);
+  }
+
+  return DBGST_PROMPT;
+}
+
+dbgcmd_state
+dbgcmd_help(mrb_state *mrb, mrdb_state *mrdb)
+{
+  mrb_bool is_valid;
+  int i;
+
+  switch (mrdb->wcnt) {
+  case 0:
+  case 1:
+    is_valid = show_short_help();
+    break;
+  case 2:
+    is_valid = show_long_help(mrdb->words[1], NULL);
+    break;
+  case 3:
+    is_valid = show_long_help(mrdb->words[1], mrdb->words[2]);
+    break;
+  default:
+    is_valid = FALSE;
+    break;
+  }
+
+  if (!is_valid) {
+    printf("Invalid command \"");
+    for (i = 1; i < mrdb->wcnt; i++) {
+      printf("%s%s", i == 1 ? "" : " ", mrdb->words[i]);
+    }
+    printf("\". Try \"help\".\n");
+  }
+
+  return DBGST_PROMPT;
+}
+
+dbgcmd_state
+dbgcmd_quit(mrb_state *mrb, mrdb_state *mrdb)
+{
+  switch (mrdb->dbg->xm) {
+  case DBG_RUN:
+  case DBG_STEP:
+  case DBG_NEXT:
+    while (1) {
+      char c;
+      int buf;
+
+      printf("The program is running.  Exit anyway? (y or n) ");
+      fflush(stdout);
+
+      if ((buf = getchar()) == EOF) {
+        mrdb->dbg->xm = DBG_QUIT;
+        break;
+      }
+      c = buf;
+      while (buf != '\n' && (buf = getchar()) != EOF) ;
+
+      if (c == 'y' || c == 'Y') {
+        mrdb->dbg->xm = DBG_QUIT;
+        break;
+      }
+      else if (c == 'n' || c == 'N') {
+        break;
+      }
+      else {
+        printf("Please answer y or n.\n");
+      }
+    }
+    break;
+  default:
+    mrdb->dbg->xm = DBG_QUIT;
+    break;
+  }
+
+  if (mrdb->dbg->xm == DBG_QUIT) {
+    struct RClass *exc;
+    exc = mrb_define_class(mrb, "DebuggerExit", mrb_class_get(mrb, "Exception"));
+    mrb_raise(mrb, exc, "Exit mrdb.");
+  }
+  return DBGST_PROMPT;
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/cmdprint.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/cmdprint.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/cmdprint.c	(revision 331)
@@ -0,0 +1,58 @@
+/*
+** cmdprint.c - mruby debugger print command functions
+**
+*/
+
+#include <string.h>
+#include "mrdb.h"
+#include <mruby/value.h>
+#include <mruby/class.h>
+#include <mruby/compile.h>
+#include <mruby/error.h>
+#include <mruby/numeric.h>
+#include <mruby/string.h>
+#include "apiprint.h"
+
+dbgcmd_state
+dbgcmd_print(mrb_state *mrb, mrdb_state *mrdb)
+{
+  mrb_value expr;
+  mrb_value result;
+  mrb_value s;
+  uint8_t wcnt;
+  int ai;
+
+  if (mrdb->wcnt <= 1) {
+    puts("Parameter not specified.");
+    return DBGST_PROMPT;
+  }
+
+  ai = mrb_gc_arena_save(mrb);
+
+  /* eval expr */
+  expr = mrb_str_new_cstr(mrb, NULL);
+  for (wcnt=1; wcnt<mrdb->wcnt; wcnt++) {
+    expr = mrb_str_cat_lit(mrb, expr, " ");
+    expr = mrb_str_cat_cstr(mrb, expr, mrdb->words[wcnt]);
+  }
+
+  result = mrb_debug_eval(mrb, mrdb->dbg, RSTRING_PTR(expr), RSTRING_LEN(expr), NULL);
+
+  /* $print_no = result */
+  s = mrb_str_cat_lit(mrb, result, "\0");
+  printf("$%lu = %s\n", (unsigned long)mrdb->print_no++, RSTRING_PTR(s));
+
+  if (mrdb->print_no == 0) {
+    mrdb->print_no = 1;
+  }
+
+  mrb_gc_arena_restore(mrb, ai);
+
+  return DBGST_PROMPT;
+}
+
+dbgcmd_state
+dbgcmd_eval(mrb_state *mrb, mrdb_state *mrdb)
+{
+  return dbgcmd_print(mrb, mrdb);
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c	(revision 331)
@@ -0,0 +1,64 @@
+/*
+** cmdrun.c - mruby debugger run command functions
+**
+*/
+
+#include <mruby/opcode.h>
+#include "mrdb.h"
+
+dbgcmd_state
+dbgcmd_run(mrb_state *mrb, mrdb_state *mrdb)
+{
+  mrb_debug_context *dbg = mrdb->dbg;
+
+  if (dbg->xm == DBG_INIT){
+    dbg->xm = DBG_RUN;
+  }
+  else {
+    dbg->xm = DBG_QUIT;
+    if (dbg->xphase == DBG_PHASE_RUNNING){
+      struct RClass *exc;
+      puts("Start it from the beginning.");
+      exc = mrb_define_class(mrb, "DebuggerRestart", mrb_class_get(mrb, "Exception"));
+      mrb_raise(mrb, exc, "Restart mrdb.");
+    }
+  }
+
+  return DBGST_RESTART;
+}
+
+dbgcmd_state
+dbgcmd_continue(mrb_state *mrb, mrdb_state *mrdb)
+{
+  mrb_debug_context *dbg = mrdb->dbg;
+  int ccnt = 1;
+
+  if (mrdb->wcnt > 1){
+    sscanf(mrdb->words[1], "%d", &ccnt);
+  }
+  dbg->ccnt = (uint16_t)(ccnt > 0 ? ccnt : 1);  /* count of continue */
+
+  if (dbg->xphase == DBG_PHASE_AFTER_RUN){
+    puts("The program is not running.");
+    dbg->xm = DBG_QUIT;
+  }
+  else {
+    dbg->xm = DBG_RUN;
+  }
+  return DBGST_CONTINUE;
+}
+
+dbgcmd_state
+dbgcmd_step(mrb_state *mrb, mrdb_state *mrdb)
+{
+  mrdb->dbg->xm = DBG_STEP;
+  return DBGST_CONTINUE;
+}
+
+dbgcmd_state
+dbgcmd_next(mrb_state *mrb, mrdb_state *mrdb)
+{
+  mrdb->dbg->xm = DBG_NEXT;
+  mrdb->dbg->prvci = mrb->c->ci;
+  return DBGST_CONTINUE;
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c	(revision 331)
@@ -0,0 +1,759 @@
+/*
+** mrdb.c - mruby debugger
+**
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include <mruby.h>
+#include <mruby/dump.h>
+#include <mruby/debug.h>
+#include <mruby/class.h>
+#include <mruby/opcode.h>
+#include <mruby/variable.h>
+
+#include "mrdb.h"
+#include "apibreak.h"
+#include "apilist.h"
+
+void mrdb_state_free(mrb_state *);
+
+static mrb_debug_context *_debug_context = NULL;
+static mrdb_state *_mrdb_state = NULL;
+
+struct _args {
+  FILE *rfp;
+  char* fname;
+  char* srcpath;
+  int argc;
+  char** argv;
+  mrb_bool mrbfile : 1;
+};
+
+typedef struct debug_command {
+  const char *cmd1;
+  const char *cmd2;
+  uint8_t len1;
+  uint8_t len2;
+  uint8_t div;
+  debug_command_id id;
+  debug_command_func func;
+} debug_command;
+
+static const debug_command debug_command_list[] = {
+  {"break",     NULL,           1, 0, 0, DBGCMD_BREAK,          dbgcmd_break},           /* b[reak] */
+  {"continue",  NULL,           1, 0, 0, DBGCMD_CONTINUE,       dbgcmd_continue},        /* c[ontinue] */
+  {"delete",    NULL,           1, 0, 1, DBGCMD_DELETE,         dbgcmd_delete},          /* d[elete] */
+  {"disable",   NULL,           3, 0, 1, DBGCMD_DISABLE,        dbgcmd_disable},         /* dis[able] */
+  {"enable",    NULL,           2, 0, 1, DBGCMD_ENABLE,         dbgcmd_enable},          /* en[able] */
+  {"eval",      NULL,           2, 0, 0, DBGCMD_EVAL,           dbgcmd_eval},            /* ev[al] */
+  {"help",      NULL,           1, 0, 1, DBGCMD_HELP,           dbgcmd_help},            /* h[elp] */
+  {"info",      "breakpoints",  1, 1, 1, DBGCMD_INFO_BREAK,     dbgcmd_info_break},      /* i[nfo] b[reakpoints] */
+  {"list",      NULL,           1, 0, 1, DBGCMD_LIST,           dbgcmd_list},            /* l[ist] */
+  {"print",     NULL,           1, 0, 0, DBGCMD_PRINT,          dbgcmd_print},           /* p[rint] */
+  {"quit",      NULL,           1, 0, 0, DBGCMD_QUIT,           dbgcmd_quit},            /* q[uit] */
+  {"run",       NULL,           1, 0, 0, DBGCMD_RUN,            dbgcmd_run},             /* r[un] */
+  {"step",      NULL,           1, 0, 1, DBGCMD_STEP,           dbgcmd_step},            /* s[tep] */
+  {"next",      NULL,           1, 0, 1, DBGCMD_NEXT,           dbgcmd_next},            /* n[ext] */
+  {NULL}
+};
+
+
+static void
+usage(const char *name)
+{
+  static const char *const usage_msg[] = {
+  "switches:",
+  "-b           load and execute RiteBinary (mrb) file",
+  "-d           specify source directory",
+  "--version    print the version",
+  "--copyright  print the copyright",
+  NULL
+  };
+  const char *const *p = usage_msg;
+
+  printf("Usage: %s [switches] programfile\n", name);
+  while (*p) {
+    printf("  %s\n", *p++);
+  }
+}
+
+static int
+parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
+{
+  char **origargv = argv;
+  static const struct _args args_zero = { 0 };
+
+  *args = args_zero;
+
+  for (argc--,argv++; argc > 0; argc--,argv++) {
+    char *item;
+    if (argv[0][0] != '-') break;
+
+    item = argv[0] + 1;
+    switch (*item++) {
+    case 'b':
+      args->mrbfile = TRUE;
+      break;
+    case 'd':
+      if (item[0]) {
+        goto append_srcpath;
+      }
+      else if (argc > 1) {
+        argc--; argv++;
+        item = argv[0];
+append_srcpath:
+        if (!args->srcpath) {
+          size_t buflen;
+          char *buf;
+
+          buflen = strlen(item) + 1;
+          buf = (char *)mrb_malloc(mrb, buflen);
+          memcpy(buf, item, buflen);
+          args->srcpath = buf;
+        }
+        else {
+          size_t srcpathlen;
+          size_t itemlen;
+
+          srcpathlen = strlen(args->srcpath);
+          itemlen = strlen(item);
+          args->srcpath =
+            (char *)mrb_realloc(mrb, args->srcpath, srcpathlen + itemlen + 2);
+          args->srcpath[srcpathlen] = '\n';
+          memcpy(args->srcpath + srcpathlen + 1, item, itemlen + 1);
+        }
+      }
+      else {
+        printf("%s: No path specified for -d\n", *origargv);
+        return EXIT_SUCCESS;
+      }
+      break;
+    case '-':
+      if (strcmp((*argv) + 2, "version") == 0) {
+        mrb_show_version(mrb);
+        exit(EXIT_SUCCESS);
+      }
+      else if (strcmp((*argv) + 2, "copyright") == 0) {
+        mrb_show_copyright(mrb);
+        exit(EXIT_SUCCESS);
+      }
+    default:
+      return EXIT_FAILURE;
+    }
+  }
+
+  if (args->rfp == NULL) {
+    if (*argv == NULL) {
+      printf("%s: Program file not specified.\n", *origargv);
+      return EXIT_FAILURE;
+    }
+    else {
+      args->rfp = fopen(argv[0], args->mrbfile ? "rb" : "r");
+      if (args->rfp == NULL) {
+        printf("%s: Cannot open program file. (%s)\n", *origargv, *argv);
+        return EXIT_FAILURE;
+      }
+      args->fname = argv[0];
+      argc--; argv++;
+    }
+  }
+  args->argv = (char **)mrb_realloc(mrb, args->argv, sizeof(char*) * (argc + 1));
+  memcpy(args->argv, argv, (argc+1) * sizeof(char*));
+  args->argc = argc;
+
+  return EXIT_SUCCESS;
+}
+
+static void
+cleanup(mrb_state *mrb, struct _args *args)
+{
+  if (args->rfp)
+    fclose(args->rfp);
+  if (args->srcpath)
+    mrb_free(mrb, args->srcpath);
+  if (args->argv)
+    mrb_free(mrb, args->argv);
+  mrdb_state_free(mrb);
+  mrb_close(mrb);
+}
+
+static mrb_debug_context*
+mrb_debug_context_new(mrb_state *mrb)
+{
+  mrb_debug_context *dbg = mrb_malloc(mrb, sizeof(mrb_debug_context));
+
+  memset(dbg, 0, sizeof(mrb_debug_context));
+
+  dbg->xm = DBG_INIT;
+  dbg->xphase = DBG_PHASE_BEFORE_RUN;
+  dbg->next_bpno = 1;
+
+  return dbg;
+}
+
+mrb_debug_context*
+mrb_debug_context_get(mrb_state *mrb)
+{
+  if (!_debug_context) {
+    _debug_context = mrb_debug_context_new(mrb);
+  }
+  return _debug_context;
+}
+
+void
+mrb_debug_context_set(mrb_debug_context *dbg)
+{
+  _debug_context = dbg;
+}
+
+void
+mrb_debug_context_free(mrb_state *mrb)
+{
+  if (_debug_context) {
+    mrb_debug_delete_break_all(mrb, _debug_context);
+    mrb_free(mrb, _debug_context);
+    _debug_context = NULL;
+  }
+}
+
+static mrdb_state*
+mrdb_state_new(mrb_state *mrb)
+{
+  mrdb_state *mrdb = mrb_malloc(mrb, sizeof(mrdb_state));
+
+  memset(mrdb, 0, sizeof(mrdb_state));
+
+  mrdb->dbg = mrb_debug_context_get(mrb);
+  mrdb->command = mrb_malloc(mrb, MAX_COMMAND_LINE+1);
+  mrdb->print_no = 1;
+
+  return mrdb;
+}
+
+mrdb_state*
+mrdb_state_get(mrb_state *mrb)
+{
+  if (!_mrdb_state) {
+    _mrdb_state = mrdb_state_new(mrb);
+  }
+  return _mrdb_state;
+}
+
+void
+mrdb_state_set(mrdb_state *mrdb)
+{
+  _mrdb_state = mrdb;
+}
+
+void
+mrdb_state_free(mrb_state *mrb)
+{
+  mrb_debug_context_free(mrb);
+  if (_mrdb_state) {
+    mrb_free(mrb, _mrdb_state->command);
+    mrb_free(mrb, _mrdb_state);
+    _mrdb_state = NULL;
+  }
+}
+
+static char*
+get_command(mrb_state *mrb, mrdb_state *mrdb)
+{
+  int i;
+  int c;
+
+  for (i=0; i<MAX_COMMAND_LINE; i++) {
+    if ((c=getchar()) == EOF || c == '\n') break;
+    mrdb->command[i] = c;
+  }
+
+  if (i == 0 && feof(stdin)) {
+    clearerr(stdin);
+    strcpy(mrdb->command, "quit");
+    i += sizeof("quit") - 1;
+  }
+
+  if (i == MAX_COMMAND_LINE) {
+    for ( ; (c=getchar()) != EOF && c !='\n'; i++) ;
+  }
+
+  if (i > MAX_COMMAND_LINE) {
+    printf("command line too long.\n");
+    i = 0; /* discard command data */
+  }
+  mrdb->command[i] = '\0';
+
+  return mrdb->command;
+}
+
+static char*
+pick_out_word(mrb_state *mrb, char **pp)
+{
+  char *ps;
+
+  for (ps=*pp; ISBLANK(*ps); ps++) ;
+  if (*ps == '\0') {
+    return NULL;
+  }
+
+  if (*ps == '\"' || *ps == '\'') {
+    *pp = strchr(ps+1, *ps);
+    if (*pp) (*pp)++;
+  }
+  else {
+    *pp = strpbrk(ps, " \t");
+  }
+
+  if (!*pp) {
+    *pp = ps + strlen(ps);
+  }
+
+  if (**pp != '\0') {
+    **pp = '\0';
+    (*pp)++;
+  }
+
+  return ps;
+}
+
+static debug_command*
+parse_command(mrb_state *mrb, mrdb_state *mrdb, char *buf)
+{
+  debug_command *cmd = NULL;
+  char *p = buf;
+  size_t wlen;
+
+  /* get word #1 */
+  mrdb->words[0] = pick_out_word(mrb, &p);
+  if (!mrdb->words[0]) {
+    return NULL;
+  }
+  mrdb->wcnt = 1;
+  /* set remain parameter */
+  for ( ; *p && ISBLANK(*p); p++) ;
+  if (*p) {
+    mrdb->words[mrdb->wcnt++] = p;
+  }
+
+  /* check word #1 */
+  for (cmd=(debug_command*)debug_command_list; cmd->cmd1; cmd++) {
+    wlen = strlen(mrdb->words[0]);
+    if (wlen >= cmd->len1 &&
+        strncmp(mrdb->words[0], cmd->cmd1, wlen) == 0) {
+      break;
+    }
+  }
+
+  if (cmd->cmd2) {
+    if (mrdb->wcnt > 1) {
+      /* get word #2 */
+      mrdb->words[1] = pick_out_word(mrb, &p);
+      if (mrdb->words[1]) {
+        /* update remain parameter */
+        for ( ; *p && ISBLANK(*p); p++) ;
+        if (*p) {
+          mrdb->words[mrdb->wcnt++] = p;
+        }
+      }
+    }
+
+    /* check word #1,#2 */
+    for ( ; cmd->cmd1; cmd++) {
+      wlen = strlen(mrdb->words[0]);
+      if (wlen < cmd->len1 ||
+          strncmp(mrdb->words[0], cmd->cmd1, wlen)) {
+        continue;
+      }
+
+      if (!cmd->cmd2) break;          /* word #1 only */
+
+      if (mrdb->wcnt == 1) continue;  /* word #2 not specified */
+
+      wlen = strlen(mrdb->words[1]);
+      if (wlen >= cmd->len2 &&
+          strncmp(mrdb->words[1], cmd->cmd2, wlen) == 0) {
+        break;  /* word #1 and #2 */
+      }
+    }
+  }
+
+  /* divide remain parameters */
+  if (cmd->cmd1 && cmd->div) {
+    p = mrdb->words[--mrdb->wcnt];
+    for ( ; mrdb->wcnt<MAX_COMMAND_WORD; mrdb->wcnt++) {
+      mrdb->words[mrdb->wcnt] = pick_out_word(mrb, &p);
+      if (!mrdb->words[mrdb->wcnt]) {
+        break;
+      }
+    }
+  }
+
+  return cmd->cmd1 ? cmd : NULL;
+}
+
+static void
+print_info_stopped_break(mrb_state *mrb, mrdb_state *mrdb)
+{
+  mrb_debug_breakpoint bp;
+  int32_t ret;
+  uint16_t lineno;
+  const char *file;
+  const char *method_name;
+  const char *class_name;
+
+  ret = mrb_debug_get_break(mrb, mrdb->dbg, mrdb->dbg->stopped_bpno, &bp);
+  if (ret == 0) {
+    switch(bp.type) {
+      case MRB_DEBUG_BPTYPE_LINE:
+        file = bp.point.linepoint.file;
+        lineno = bp.point.linepoint.lineno;
+        printf("Breakpoint %d, at %s:%d\n", bp.bpno, file, lineno);
+        break;
+      case MRB_DEBUG_BPTYPE_METHOD:
+        method_name = bp.point.methodpoint.method_name;
+        class_name = bp.point.methodpoint.class_name;
+        if (class_name == NULL) {
+          printf("Breakpoint %d, %s\n", bp.bpno, method_name);
+        }
+        else {
+          printf("Breakpoint %d, %s:%s\n", bp.bpno, class_name, method_name);
+        }
+        if (mrdb->dbg->isCfunc) {
+          printf("Stopped before calling the C function.\n");
+        }
+        break;
+      default:
+        break;
+    }
+  }
+}
+
+static void
+print_info_stopped_step_next(mrb_state *mrb, mrdb_state *mrdb)
+{
+  const char* file = mrdb->dbg->prvfile;
+  uint16_t lineno = mrdb->dbg->prvline;
+  printf("%s:%d\n", file, lineno);
+}
+
+static void
+print_info_stopped_code(mrb_state *mrb, mrdb_state *mrdb)
+{
+  char* file = mrb_debug_get_source(mrb, mrdb, mrdb->srcpath, mrdb->dbg->prvfile);
+  uint16_t lineno = mrdb->dbg->prvline;
+  if (file != NULL) {
+    mrb_debug_list(mrb, mrdb->dbg, file, lineno, lineno);
+    mrb_free(mrb, file);
+  }
+}
+
+static void
+print_info_stopped(mrb_state *mrb, mrdb_state *mrdb)
+{
+  switch(mrdb->dbg->bm) {
+    case BRK_BREAK:
+      print_info_stopped_break(mrb, mrdb);
+      print_info_stopped_code(mrb, mrdb);
+      break;
+    case BRK_STEP:
+    case BRK_NEXT:
+      print_info_stopped_step_next(mrb, mrdb);
+      print_info_stopped_code(mrb, mrdb);
+      break;
+    default:
+      break;
+  }
+}
+
+static debug_command*
+get_and_parse_command(mrb_state *mrb, mrdb_state *mrdb)
+{
+  debug_command *cmd = NULL;
+  char *p;
+  int i;
+
+  while (!cmd) {
+    for (p=NULL; !p || *p=='\0'; ) {
+      printf("(%s:%d) ", mrdb->dbg->prvfile, mrdb->dbg->prvline);
+      fflush(stdout);
+      p = get_command(mrb, mrdb);
+    }
+
+    cmd = parse_command(mrb, mrdb, p);
+#ifdef _DBG_MRDB_PARSER_
+    for (i=0; i<mrdb->wcnt; i++) {
+      printf("%d: %s\n", i, mrdb->words[i]);
+    }
+#endif
+    if (!cmd) {
+      printf("invalid command (");
+      for (i=0; i<mrdb->wcnt; i++) {
+        if (i>0) {
+          printf(" ");
+        }
+        printf("%s", mrdb->words[i]);
+      }
+      puts(")");
+    }
+  }
+  return cmd;
+}
+
+static int32_t
+check_method_breakpoint(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, mrb_value *regs)
+{
+  struct RClass* c;
+  mrb_sym sym;
+  int32_t bpno;
+  mrb_bool isCfunc;
+
+  mrb_debug_context *dbg = mrb_debug_context_get(mrb);
+
+  isCfunc = FALSE;
+  bpno = dbg->method_bpno;
+  dbg->method_bpno = 0;
+
+  switch(GET_OPCODE(*pc)) {
+    case OP_SEND:
+    case OP_SENDB:
+      c = mrb_class(mrb, regs[GETARG_A(*pc)]);
+      sym = irep->syms[GETARG_B(*pc)];
+      break;
+    case OP_SUPER:
+      c = mrb->c->ci->target_class->super;
+      sym = mrb->c->ci->mid;
+      break;
+    default:
+      sym = 0;
+      break;
+  }
+  if (sym != 0) {
+    dbg->method_bpno = mrb_debug_check_breakpoint_method(mrb, dbg, c, sym, &isCfunc);
+    if (isCfunc) {
+      bpno = dbg->method_bpno;
+      dbg->method_bpno = 0;
+    }
+  }
+  dbg->isCfunc = isCfunc;
+  return bpno;
+}
+
+static void
+mrb_code_fetch_hook(mrb_state *mrb, mrb_irep *irep, mrb_code *pc, mrb_value *regs)
+{
+  const char *file;
+  int32_t line;
+  int32_t bpno;
+
+  mrb_debug_context *dbg = mrb_debug_context_get(mrb);
+
+  mrb_assert(dbg);
+
+  dbg->irep = irep;
+  dbg->pc   = pc;
+  dbg->regs = regs;
+
+  if (dbg->xphase == DBG_PHASE_RESTART) {
+    dbg->root_irep = irep;
+    dbg->prvfile = NULL;
+    dbg->prvline = 0;
+    dbg->prvci = NULL;
+    dbg->xm = DBG_RUN;
+    dbg->xphase = DBG_PHASE_RUNNING;
+  }
+
+  file = mrb_debug_get_filename(irep, (uint32_t)(pc - irep->iseq));
+  line = mrb_debug_get_line(irep, (uint32_t)(pc - irep->iseq));
+
+  switch (dbg->xm) {
+  case DBG_STEP:
+    if (!file || (dbg->prvfile == file && dbg->prvline == line)) {
+      return;
+    }
+    dbg->method_bpno = 0;
+    dbg->bm = BRK_STEP;
+    break;
+
+  case DBG_NEXT:
+    if (!file || (dbg->prvfile == file && dbg->prvline == line)) {
+      return;
+    }
+    if ((intptr_t)(dbg->prvci) < (intptr_t)(mrb->c->ci)) {
+      return;
+    }
+    dbg->prvci = NULL;
+    dbg->method_bpno = 0;
+    dbg->bm = BRK_NEXT;
+    break;
+
+  case DBG_RUN:
+    bpno = check_method_breakpoint(mrb, irep, pc, regs);
+    if (bpno > 0) {
+      dbg->stopped_bpno = bpno;
+      dbg->bm = BRK_BREAK;
+      break;
+    }
+    if (dbg->prvfile != file || dbg->prvline != line) {
+      bpno = mrb_debug_check_breakpoint_line(mrb, dbg, file, line);
+      if (bpno > 0) {
+        dbg->stopped_bpno = bpno;
+        dbg->bm = BRK_BREAK;
+        break;
+      }
+    }
+    dbg->prvfile = file;
+    dbg->prvline = line;
+    return;
+  case DBG_INIT:
+    dbg->root_irep = irep;
+    dbg->bm = BRK_INIT;
+    if (!file || line < 0) {
+      puts("Cannot get debugging information.");
+    }
+    break;
+
+  default:
+    return;
+  }
+
+  dbg->prvfile = file;
+  dbg->prvline = line;
+
+  if (dbg->bm == BRK_BREAK && --dbg->ccnt > 0) {
+    return;
+  }
+  dbg->break_hook(mrb, dbg);
+
+  dbg->xphase = DBG_PHASE_RUNNING;
+}
+
+static mrdb_exemode
+mrb_debug_break_hook(mrb_state *mrb, mrb_debug_context *dbg)
+{
+  debug_command *cmd;
+  dbgcmd_state st = DBGST_CONTINUE;
+  mrdb_state *mrdb = mrdb_state_get(mrb);
+
+  print_info_stopped(mrb, mrdb);
+
+  while (1) {
+    cmd = get_and_parse_command(mrb, mrdb);
+    mrb_assert(cmd);
+
+    st = cmd->func(mrb, mrdb);
+
+    if ((st == DBGST_CONTINUE) || (st == DBGST_RESTART)) break;
+  }
+  return dbg->xm;
+}
+
+int
+main(int argc, char **argv)
+{
+  mrb_state *mrb = mrb_open();
+  int n = -1;
+  struct _args args;
+  mrb_value v;
+  mrdb_state *mrdb;
+  mrdb_state *mrdb_backup;
+  mrb_debug_context* dbg_backup;
+  debug_command *cmd;
+
+ l_restart:
+
+  if (mrb == NULL) {
+    fputs("Invalid mrb_state, exiting mruby\n", stderr);
+    return EXIT_FAILURE;
+  }
+
+  /* parse command parameters */
+  n = parse_args(mrb, argc, argv, &args);
+  if (n == EXIT_FAILURE || args.rfp == NULL) {
+    cleanup(mrb, &args);
+    usage(argv[0]);
+    return n;
+  }
+
+  /* initialize debugger information */
+  mrdb = mrdb_state_get(mrb);
+  mrb_assert(mrdb && mrdb->dbg);
+  mrdb->srcpath = args.srcpath;
+
+  if (mrdb->dbg->xm == DBG_QUIT) {
+    mrdb->dbg->xphase = DBG_PHASE_RESTART;
+  }
+  else {
+    mrdb->dbg->xphase = DBG_PHASE_BEFORE_RUN;
+  }
+  mrdb->dbg->xm = DBG_INIT;
+  mrdb->dbg->ccnt = 1;
+
+  /* setup hook functions */
+  mrb->code_fetch_hook = mrb_code_fetch_hook;
+  mrdb->dbg->break_hook = mrb_debug_break_hook;
+
+  if (args.mrbfile) { /* .mrb */
+    v = mrb_load_irep_file(mrb, args.rfp);
+  }
+  else {              /* .rb */
+    mrbc_context *cc = mrbc_context_new(mrb);
+    mrbc_filename(mrb, cc, args.fname);
+    v = mrb_load_file_cxt(mrb, args.rfp, cc);
+    mrbc_context_free(mrb, cc);
+  }
+  if (mrdb->dbg->xm == DBG_QUIT && !mrb_undef_p(v) && mrb->exc) {
+    const char *classname = mrb_obj_classname(mrb, mrb_obj_value(mrb->exc));
+    if (!strcmp(classname, "DebuggerExit")) {
+      cleanup(mrb, &args);
+      return 0;
+    }
+    if (!strcmp(classname, "DebuggerRestart")) {
+      mrdb_backup = mrdb_state_get(mrb);
+      dbg_backup = mrb_debug_context_get(mrb);
+
+      mrdb_state_set(NULL);
+      mrb_debug_context_set(NULL);
+
+      cleanup(mrb, &args);
+      mrb = mrb_open();
+
+      mrdb_state_set(mrdb_backup);
+      mrb_debug_context_set(dbg_backup);
+
+      goto l_restart;
+    }
+  }
+  puts("mruby application exited.");
+  mrdb->dbg->xphase = DBG_PHASE_AFTER_RUN;
+  if (!mrb_undef_p(v)) {
+    if (mrb->exc) {
+      mrb_print_error(mrb);
+    }
+    else {
+      printf(" => ");
+      mrb_p(mrb, v);
+    }
+  }
+
+  mrdb->dbg->prvfile = "-";
+  mrdb->dbg->prvline = 0;
+
+  while (1) {
+    cmd = get_and_parse_command(mrb, mrdb);
+    mrb_assert(cmd);
+
+    if (cmd->id == DBGCMD_QUIT) {
+      break;
+    }
+
+    if ( cmd->func(mrb, mrdb) == DBGST_RESTART ) goto l_restart;
+  }
+
+  cleanup(mrb, &args);
+
+  return 0;
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h	(revision 331)
@@ -0,0 +1,165 @@
+/*
+** mrdb.h - mruby debugger
+**
+*/
+
+#ifndef MRDB_H
+#define MRDB_H
+
+#include <mruby.h>
+
+#include "mrdbconf.h"
+
+#ifdef _MSC_VER
+# define __func__ __FUNCTION__
+#endif
+
+#define MAX_COMMAND_WORD (16)
+
+typedef enum debug_command_id {
+  DBGCMD_RUN,
+  DBGCMD_CONTINUE,
+  DBGCMD_NEXT,
+  DBGCMD_STEP,
+  DBGCMD_BREAK,
+  DBGCMD_INFO_BREAK,
+  DBGCMD_WATCH,
+  DBGCMD_INFO_WATCH,
+  DBGCMD_ENABLE,
+  DBGCMD_DISABLE,
+  DBGCMD_DELETE,
+  DBGCMD_PRINT,
+  DBGCMD_DISPLAY,
+  DBGCMD_INFO_DISPLAY,
+  DBGCMD_DELETE_DISPLAY,
+  DBGCMD_EVAL,
+  DBGCMD_BACKTRACE,
+  DBGCMD_LIST,
+  DBGCMD_HELP,
+  DBGCMD_QUIT,
+  DBGCMD_UNKNOWN
+} debug_command_id;
+
+typedef enum dbgcmd_state {
+  DBGST_CONTINUE,
+  DBGST_PROMPT,
+  DBGST_COMMAND_ERROR,
+  DBGST_MAX,
+  DBGST_RESTART
+} dbgcmd_state;
+
+typedef enum mrdb_exemode {
+  DBG_INIT,
+  DBG_RUN,
+  DBG_STEP,
+  DBG_NEXT,
+  DBG_QUIT,
+} mrdb_exemode;
+
+typedef enum mrdb_exephase {
+  DBG_PHASE_BEFORE_RUN,
+  DBG_PHASE_RUNNING,
+  DBG_PHASE_AFTER_RUN,
+  DBG_PHASE_RESTART,
+} mrdb_exephase;
+
+typedef enum mrdb_brkmode {
+  BRK_INIT,
+  BRK_BREAK,
+  BRK_STEP,
+  BRK_NEXT,
+  BRK_QUIT,
+} mrdb_brkmode;
+
+typedef enum {
+  MRB_DEBUG_BPTYPE_NONE,
+  MRB_DEBUG_BPTYPE_LINE,
+  MRB_DEBUG_BPTYPE_METHOD,
+} mrb_debug_bptype;
+
+struct mrb_irep;
+struct mrbc_context;
+struct mrb_debug_context;
+
+typedef struct mrb_debug_linepoint {
+  const char *file;
+  uint16_t lineno;
+} mrb_debug_linepoint;
+
+typedef struct mrb_debug_methodpoint {
+  const char *class_name;
+  const char *method_name;
+} mrb_debug_methodpoint;
+
+typedef struct mrb_debug_breakpoint {
+  uint32_t bpno;
+  uint8_t enable;
+  mrb_debug_bptype type;
+  union point {
+    mrb_debug_linepoint linepoint;
+    mrb_debug_methodpoint methodpoint;
+  } point;
+} mrb_debug_breakpoint;
+
+typedef struct mrb_debug_context {
+  struct mrb_irep *root_irep;
+  struct mrb_irep *irep;
+  mrb_code *pc;
+  mrb_value *regs;
+
+  const char *prvfile;
+  int32_t prvline;
+  mrb_callinfo *prvci;
+
+  mrdb_exemode xm;
+  mrdb_exephase xphase;
+  mrdb_brkmode bm;
+  int16_t bmi;
+
+  uint16_t ccnt;
+  uint16_t scnt;
+
+  mrb_debug_breakpoint bp[MAX_BREAKPOINT];
+  uint32_t bpnum;
+  int32_t next_bpno;
+  int32_t method_bpno;
+  int32_t stopped_bpno;
+  mrb_bool isCfunc;
+
+  mrdb_exemode (*break_hook)(mrb_state *mrb, struct mrb_debug_context *dbg);
+
+} mrb_debug_context;
+
+typedef struct mrdb_state {
+  char *command;
+  uint8_t wcnt;
+  uint8_t pi;
+  char *words[MAX_COMMAND_WORD];
+  const char *srcpath;
+  uint32_t print_no;
+
+  mrb_debug_context *dbg;
+} mrdb_state;
+
+typedef dbgcmd_state (*debug_command_func)(mrb_state*, mrdb_state*);
+
+/* cmdrun.c */
+dbgcmd_state dbgcmd_run(mrb_state*, mrdb_state*);
+dbgcmd_state dbgcmd_continue(mrb_state*, mrdb_state*);
+dbgcmd_state dbgcmd_step(mrb_state*, mrdb_state*);
+dbgcmd_state dbgcmd_next(mrb_state*, mrdb_state*);
+/* cmdbreak.c */
+dbgcmd_state dbgcmd_break(mrb_state*, mrdb_state*);
+dbgcmd_state dbgcmd_info_break(mrb_state*, mrdb_state*);
+dbgcmd_state dbgcmd_delete(mrb_state*, mrdb_state*);
+dbgcmd_state dbgcmd_enable(mrb_state*, mrdb_state*);
+dbgcmd_state dbgcmd_disable(mrb_state*, mrdb_state*);
+/* cmdprint.c */
+dbgcmd_state dbgcmd_print(mrb_state*, mrdb_state*);
+dbgcmd_state dbgcmd_eval(mrb_state*, mrdb_state*);
+/* cmdmisc.c */
+dbgcmd_state dbgcmd_list(mrb_state*, mrdb_state*);
+dbgcmd_state dbgcmd_help(mrb_state*, mrdb_state*);
+dbgcmd_state dbgcmd_quit(mrb_state*, mrdb_state*);
+
+#endif
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/mrdbconf.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/mrdbconf.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/mrdbconf.h	(revision 331)
@@ -0,0 +1,16 @@
+/*
+** mrdbconf.h - mruby debugger configuration
+**
+*/
+
+#ifndef MRDBCONF_H
+#define MRDBCONF_H
+
+/* configuration options: */
+/* maximum size for command buffer */
+#define MAX_COMMAND_LINE 1024
+
+/* maximum number of setable breakpoint */
+#define MAX_BREAKPOINT 5
+
+#endif
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/mrdberror.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/mrdberror.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-debugger/tools/mrdb/mrdberror.h	(revision 331)
@@ -0,0 +1,20 @@
+/*
+** mrdberror.h - mruby debugger error code
+**
+*/
+
+#ifndef MRDBERROR_H
+#define MRDBERROR_H
+
+#define MRB_DEBUG_OK                   (0)
+#define MRB_DEBUG_NOBUF                (-1)
+#define MRB_DEBUG_INVALID_ARGUMENT     (-2)
+
+#define MRB_DEBUG_BREAK_INVALID_LINENO (-11)
+#define MRB_DEBUG_BREAK_INVALID_FILE   (-12)
+#define MRB_DEBUG_BREAK_INVALID_NO     (-13)
+#define MRB_DEBUG_BREAK_NUM_OVER       (-14)
+#define MRB_DEBUG_BREAK_NO_OVER        (-15)
+
+#endif
+
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mirb/bintest/mirb.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mirb/bintest/mirb.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mirb/bintest/mirb.rb	(revision 331)
@@ -0,0 +1,12 @@
+require 'open3'
+
+assert('mirb normal operations') do
+  o, s = Open3.capture2('bin/mirb', :stdin_data => "a=1\nb=2\na+b\n")
+  assert_true o.include?('=> 3')
+  assert_true o.include?('=> 2')
+end
+
+assert('regression for #1563') do
+  o, s = Open3.capture2('bin/mirb', :stdin_data => "a=1;b=2;c=3\nb\nc")
+  assert_true o.include?('=> 3')
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mirb/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mirb/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mirb/mrbgem.rake	(revision 331)
@@ -0,0 +1,33 @@
+MRuby::Gem::Specification.new('mruby-bin-mirb') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'mirb command'
+
+  if spec.build.cc.search_header_path 'readline/readline.h'
+    spec.cc.defines << "ENABLE_READLINE"
+    if spec.build.cc.search_header_path 'termcap.h'
+      if MRUBY_BUILD_HOST_IS_CYGWIN || MRUBY_BUILD_HOST_IS_OPENBSD
+        if spec.build.cc.search_header_path 'termcap.h'
+          if MRUBY_BUILD_HOST_IS_CYGWIN then
+            spec.linker.libraries << 'ncurses'
+          else
+            spec.linker.libraries << 'termcap'
+          end
+        end
+      end
+    end
+    if RUBY_PLATFORM.include?('netbsd')
+      spec.linker.libraries << 'edit'
+    else
+      spec.linker.libraries << 'readline'
+      if spec.build.cc.search_header_path 'curses.h'
+        spec.linker.libraries << 'ncurses'
+      end
+    end
+  elsif spec.build.cc.search_header_path 'linenoise.h'
+    spec.cc.defines << "ENABLE_LINENOISE"
+  end
+
+  spec.bins = %w(mirb)
+  spec.add_dependency('mruby-compiler', :core => 'mruby-compiler')
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c	(revision 331)
@@ -0,0 +1,584 @@
+/*
+** mirb - Embeddable Interactive Ruby Shell
+**
+** This program takes code from the user in
+** an interactive way and executes it
+** immediately. It's a REPL...
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include <signal.h>
+#include <setjmp.h>
+
+#ifdef ENABLE_READLINE
+#include <readline/readline.h>
+#include <readline/history.h>
+#define MIRB_ADD_HISTORY(line) add_history(line)
+#define MIRB_READLINE(ch) readline(ch)
+#define MIRB_WRITE_HISTORY(path) write_history(path)
+#define MIRB_READ_HISTORY(path) read_history(path)
+#define MIRB_USING_HISTORY() using_history()
+#elif defined(ENABLE_LINENOISE)
+#define ENABLE_READLINE
+#include <linenoise.h>
+#define MIRB_ADD_HISTORY(line) linenoiseHistoryAdd(line)
+#define MIRB_READLINE(ch) linenoise(ch)
+#define MIRB_WRITE_HISTORY(path) linenoiseHistorySave(path)
+#define MIRB_READ_HISTORY(path) linenoiseHistoryLoad(history_path)
+#define MIRB_USING_HISTORY()
+#endif
+
+#ifndef _WIN32
+#define MIRB_SIGSETJMP(env) sigsetjmp(env, 1)
+#define MIRB_SIGLONGJMP(env, val) siglongjmp(env, val)
+#define SIGJMP_BUF sigjmp_buf
+#else
+#define MIRB_SIGSETJMP(env) setjmp(env)
+#define MIRB_SIGLONGJMP(env, val) longjmp(env, val)
+#define SIGJMP_BUF jmp_buf
+#endif
+
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/proc.h>
+#include <mruby/compile.h>
+#include <mruby/string.h>
+
+#ifdef ENABLE_READLINE
+
+static const char history_file_name[] = ".mirb_history";
+
+static char *
+get_history_path(mrb_state *mrb)
+{
+  char *path = NULL;
+  const char *home = getenv("HOME");
+
+#ifdef _WIN32
+  if (home != NULL) {
+    home = getenv("USERPROFILE");
+  }
+#endif
+
+  if (home != NULL) {
+    int len = snprintf(NULL, 0, "%s/%s", home, history_file_name);
+    if (len >= 0) {
+      size_t size = len + 1;
+      path = (char *)mrb_malloc_simple(mrb, size);
+      if (path != NULL) {
+        int n = snprintf(path, size, "%s/%s", home, history_file_name);
+        if (n != len) {
+          mrb_free(mrb, path);
+          path = NULL;
+        }
+      }
+    }
+  }
+
+  return path;
+}
+
+#endif
+
+static void
+p(mrb_state *mrb, mrb_value obj, int prompt)
+{
+  mrb_value val;
+
+  val = mrb_funcall(mrb, obj, "inspect", 0);
+  if (prompt) {
+    if (!mrb->exc) {
+      fputs(" => ", stdout);
+    }
+    else {
+      val = mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0);
+    }
+  }
+  if (!mrb_string_p(val)) {
+    val = mrb_obj_as_string(mrb, obj);
+  }
+  fwrite(RSTRING_PTR(val), RSTRING_LEN(val), 1, stdout);
+  putc('\n', stdout);
+}
+
+/* Guess if the user might want to enter more
+ * or if he wants an evaluation of his code now */
+static mrb_bool
+is_code_block_open(struct mrb_parser_state *parser)
+{
+  mrb_bool code_block_open = FALSE;
+
+  /* check for heredoc */
+  if (parser->parsing_heredoc != NULL) return TRUE;
+  if (parser->heredoc_end_now) {
+    parser->heredoc_end_now = FALSE;
+    return FALSE;
+  }
+
+  /* check for unterminated string */
+  if (parser->lex_strterm) return TRUE;
+
+  /* check if parser error are available */
+  if (0 < parser->nerr) {
+    const char unexpected_end[] = "syntax error, unexpected $end";
+    const char *message = parser->error_buffer[0].message;
+
+    /* a parser error occur, we have to check if */
+    /* we need to read one more line or if there is */
+    /* a different issue which we have to show to */
+    /* the user */
+
+    if (strncmp(message, unexpected_end, sizeof(unexpected_end) - 1) == 0) {
+      code_block_open = TRUE;
+    }
+    else if (strcmp(message, "syntax error, unexpected keyword_end") == 0) {
+      code_block_open = FALSE;
+    }
+    else if (strcmp(message, "syntax error, unexpected tREGEXP_BEG") == 0) {
+      code_block_open = FALSE;
+    }
+    return code_block_open;
+  }
+
+  switch (parser->lstate) {
+
+  /* all states which need more code */
+
+  case EXPR_BEG:
+    /* beginning of a statement, */
+    /* that means previous line ended */
+    code_block_open = FALSE;
+    break;
+  case EXPR_DOT:
+    /* a message dot was the last token, */
+    /* there has to come more */
+    code_block_open = TRUE;
+    break;
+  case EXPR_CLASS:
+    /* a class keyword is not enough! */
+    /* we need also a name of the class */
+    code_block_open = TRUE;
+    break;
+  case EXPR_FNAME:
+    /* a method name is necessary */
+    code_block_open = TRUE;
+    break;
+  case EXPR_VALUE:
+    /* if, elsif, etc. without condition */
+    code_block_open = TRUE;
+    break;
+
+  /* now all the states which are closed */
+
+  case EXPR_ARG:
+    /* an argument is the last token */
+    code_block_open = FALSE;
+    break;
+
+  /* all states which are unsure */
+
+  case EXPR_CMDARG:
+    break;
+  case EXPR_END:
+    /* an expression was ended */
+    break;
+  case EXPR_ENDARG:
+    /* closing parenthese */
+    break;
+  case EXPR_ENDFN:
+    /* definition end */
+    break;
+  case EXPR_MID:
+    /* jump keyword like break, return, ... */
+    break;
+  case EXPR_MAX_STATE:
+    /* don't know what to do with this token */
+    break;
+  default:
+    /* this state is unexpected! */
+    break;
+  }
+
+  return code_block_open;
+}
+
+struct _args {
+  FILE *rfp;
+  mrb_bool verbose      : 1;
+  int argc;
+  char** argv;
+};
+
+static void
+usage(const char *name)
+{
+  static const char *const usage_msg[] = {
+  "switches:",
+  "-v           print version number, then run in verbose mode",
+  "--verbose    run in verbose mode",
+  "--version    print the version",
+  "--copyright  print the copyright",
+  NULL
+  };
+  const char *const *p = usage_msg;
+
+  printf("Usage: %s [switches]\n", name);
+  while (*p)
+    printf("  %s\n", *p++);
+}
+
+static int
+parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
+{
+  static const struct _args args_zero = { 0 };
+
+  *args = args_zero;
+
+  for (argc--,argv++; argc > 0; argc--,argv++) {
+    char *item;
+    if (argv[0][0] != '-') break;
+
+    item = argv[0] + 1;
+    switch (*item++) {
+    case 'v':
+      if (!args->verbose) mrb_show_version(mrb);
+      args->verbose = TRUE;
+      break;
+    case '-':
+      if (strcmp((*argv) + 2, "version") == 0) {
+        mrb_show_version(mrb);
+        exit(EXIT_SUCCESS);
+      }
+      else if (strcmp((*argv) + 2, "verbose") == 0) {
+        args->verbose = TRUE;
+        break;
+      }
+      else if (strcmp((*argv) + 2, "copyright") == 0) {
+        mrb_show_copyright(mrb);
+        exit(EXIT_SUCCESS);
+      }
+    default:
+      return EXIT_FAILURE;
+    }
+  }
+
+  if (args->rfp == NULL) {
+    if (*argv != NULL) {
+      args->rfp = fopen(argv[0], "r");
+      if (args->rfp == NULL) {
+        printf("Cannot open program file. (%s)\n", *argv);
+        return EXIT_FAILURE;
+      }
+      argc--; argv++;
+    }
+  }
+  args->argv = (char **)mrb_realloc(mrb, args->argv, sizeof(char*) * (argc + 1));
+  memcpy(args->argv, argv, (argc+1) * sizeof(char*));
+  args->argc = argc;
+
+  return EXIT_SUCCESS;
+}
+
+static void
+cleanup(mrb_state *mrb, struct _args *args)
+{
+  if (args->rfp)
+    fclose(args->rfp);
+  mrb_free(mrb, args->argv);
+  mrb_close(mrb);
+}
+
+/* Print a short remark for the user */
+static void
+print_hint(void)
+{
+  printf("mirb - Embeddable Interactive Ruby Shell\n\n");
+}
+
+#ifndef ENABLE_READLINE
+/* Print the command line prompt of the REPL */
+static void
+print_cmdline(int code_block_open)
+{
+  if (code_block_open) {
+    printf("* ");
+  }
+  else {
+    printf("> ");
+  }
+  fflush(stdout);
+}
+#endif
+
+void mrb_codedump_all(mrb_state*, struct RProc*);
+
+static int
+check_keyword(const char *buf, const char *word)
+{
+  const char *p = buf;
+  size_t len = strlen(word);
+
+  /* skip preceding spaces */
+  while (*p && isspace((unsigned char)*p)) {
+    p++;
+  }
+  /* check keyword */
+  if (strncmp(p, word, len) != 0) {
+    return 0;
+  }
+  p += len;
+  /* skip trailing spaces */
+  while (*p) {
+    if (!isspace((unsigned char)*p)) return 0;
+    p++;
+  }
+  return 1;
+}
+
+
+#ifndef ENABLE_READLINE
+volatile sig_atomic_t input_canceled = 0;
+void
+ctrl_c_handler(int signo)
+{
+  input_canceled = 1;
+}
+#else
+SIGJMP_BUF ctrl_c_buf;
+void
+ctrl_c_handler(int signo)
+{
+  MIRB_SIGLONGJMP(ctrl_c_buf, 1);
+}
+#endif
+
+int
+main(int argc, char **argv)
+{
+  char ruby_code[4096] = { 0 };
+  char last_code_line[1024] = { 0 };
+#ifndef ENABLE_READLINE
+  int last_char;
+  size_t char_index;
+#else
+  char *history_path;
+  char* line;
+#endif
+  mrbc_context *cxt;
+  struct mrb_parser_state *parser;
+  mrb_state *mrb;
+  mrb_value result;
+  struct _args args;
+  mrb_value ARGV;
+  int n;
+  int i;
+  mrb_bool code_block_open = FALSE;
+  int ai;
+  unsigned int stack_keep = 0;
+
+  /* new interpreter instance */
+  mrb = mrb_open();
+  if (mrb == NULL) {
+    fputs("Invalid mrb interpreter, exiting mirb\n", stderr);
+    return EXIT_FAILURE;
+  }
+
+  n = parse_args(mrb, argc, argv, &args);
+  if (n == EXIT_FAILURE) {
+    cleanup(mrb, &args);
+    usage(argv[0]);
+    return n;
+  }
+
+  ARGV = mrb_ary_new_capa(mrb, args.argc);
+  for (i = 0; i < args.argc; i++) {
+    char* utf8 = mrb_utf8_from_locale(args.argv[i], -1);
+    if (utf8) {
+      mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, utf8));
+      mrb_utf8_free(utf8);
+    }
+  }
+  mrb_define_global_const(mrb, "ARGV", ARGV);
+
+#ifdef ENABLE_READLINE
+  history_path = get_history_path(mrb);
+  if (history_path == NULL) {
+    fputs("failed to get history path\n", stderr);
+    mrb_close(mrb);
+    return EXIT_FAILURE;
+  }
+
+  MIRB_USING_HISTORY();
+  MIRB_READ_HISTORY(history_path);
+#endif
+
+  print_hint();
+
+  cxt = mrbc_context_new(mrb);
+  cxt->capture_errors = TRUE;
+  cxt->lineno = 1;
+  mrbc_filename(mrb, cxt, "(mirb)");
+  if (args.verbose) cxt->dump_result = TRUE;
+
+  ai = mrb_gc_arena_save(mrb);
+
+  while (TRUE) {
+    char *utf8;
+
+    if (args.rfp) {
+      if (fgets(last_code_line, sizeof(last_code_line)-1, args.rfp) != NULL)
+        goto done;
+      break;
+    }
+
+#ifndef ENABLE_READLINE
+    print_cmdline(code_block_open);
+
+    signal(SIGINT, ctrl_c_handler);
+    char_index = 0;
+    while ((last_char = getchar()) != '\n') {
+      if (last_char == EOF) break;
+      if (char_index >= sizeof(last_code_line)-2) {
+        fputs("input string too long\n", stderr);
+        continue;
+      }
+      last_code_line[char_index++] = last_char;
+    }
+    signal(SIGINT, SIG_DFL);
+    if (input_canceled) {
+      ruby_code[0] = '\0';
+      last_code_line[0] = '\0';
+      code_block_open = FALSE;
+      puts("^C");
+      input_canceled = 0;
+      continue;
+    }
+    if (last_char == EOF) {
+      fputs("\n", stdout);
+      break;
+    }
+
+    last_code_line[char_index++] = '\n';
+    last_code_line[char_index] = '\0';
+#else
+    if (MIRB_SIGSETJMP(ctrl_c_buf) == 0) {
+      ;
+    }
+    else {
+      ruby_code[0] = '\0';
+      last_code_line[0] = '\0';
+      code_block_open = FALSE;
+      puts("^C");
+    }
+    signal(SIGINT, ctrl_c_handler);
+    line = MIRB_READLINE(code_block_open ? "* " : "> ");
+    signal(SIGINT, SIG_DFL);
+
+    if (line == NULL) {
+      printf("\n");
+      break;
+    }
+    if (strlen(line) > sizeof(last_code_line)-2) {
+      fputs("input string too long\n", stderr);
+      continue;
+    }
+    strcpy(last_code_line, line);
+    strcat(last_code_line, "\n");
+    MIRB_ADD_HISTORY(line);
+    free(line);
+#endif
+
+done:
+
+    if (code_block_open) {
+      if (strlen(ruby_code)+strlen(last_code_line) > sizeof(ruby_code)-1) {
+        fputs("concatenated input string too long\n", stderr);
+        continue;
+      }
+      strcat(ruby_code, last_code_line);
+    }
+    else {
+      if (check_keyword(last_code_line, "quit") || check_keyword(last_code_line, "exit")) {
+        break;
+      }
+      strcpy(ruby_code, last_code_line);
+    }
+
+    utf8 = mrb_utf8_from_locale(ruby_code, -1);
+    if (!utf8) abort();
+
+    /* parse code */
+    parser = mrb_parser_new(mrb);
+    if (parser == NULL) {
+      fputs("create parser state error\n", stderr);
+      break;
+    }
+    parser->s = utf8;
+    parser->send = utf8 + strlen(utf8);
+    parser->lineno = cxt->lineno;
+    mrb_parser_parse(parser, cxt);
+    code_block_open = is_code_block_open(parser);
+    mrb_utf8_free(utf8);
+
+    if (code_block_open) {
+      /* no evaluation of code */
+    }
+    else {
+      if (0 < parser->nerr) {
+        /* syntax error */
+        printf("line %d: %s\n", parser->error_buffer[0].lineno, parser->error_buffer[0].message);
+      }
+      else {
+        /* generate bytecode */
+        struct RProc *proc = mrb_generate_code(mrb, parser);
+        if (proc == NULL) {
+          fputs("codegen error\n", stderr);
+          mrb_parser_free(parser);
+          break;
+        }
+
+        if (args.verbose) {
+          mrb_codedump_all(mrb, proc);
+        }
+        /* pass a proc for evaluation */
+        /* evaluate the bytecode */
+        result = mrb_vm_run(mrb,
+            proc,
+            mrb_top_self(mrb),
+            stack_keep);
+        stack_keep = proc->body.irep->nlocals;
+        /* did an exception occur? */
+        if (mrb->exc) {
+          p(mrb, mrb_obj_value(mrb->exc), 0);
+          mrb->exc = 0;
+        }
+        else {
+          /* no */
+          if (!mrb_respond_to(mrb, result, mrb_intern_lit(mrb, "inspect"))){
+            result = mrb_any_to_s(mrb, result);
+          }
+          p(mrb, result, 1);
+        }
+      }
+      ruby_code[0] = '\0';
+      last_code_line[0] = '\0';
+      mrb_gc_arena_restore(mrb, ai);
+    }
+    mrb_parser_free(parser);
+    cxt->lineno++;
+  }
+
+#ifdef ENABLE_READLINE
+  MIRB_WRITE_HISTORY(history_path);
+  mrb_free(mrb, history_path);
+#endif
+
+  mrbc_context_free(mrb, cxt);
+  mrb_close(mrb);
+
+  return 0;
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mrbc/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mrbc/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mrbc/mrbgem.rake	(revision 331)
@@ -0,0 +1,16 @@
+MRuby::Gem::Specification.new 'mruby-bin-mrbc' do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'mruby compiler executable'
+
+  spec.add_dependency 'mruby-compiler', :core => 'mruby-compiler'
+
+  exec = exefile("#{build.build_dir}/bin/mrbc")
+  mrbc_objs = Dir.glob("#{spec.dir}/tools/mrbc/*.c").map { |f| objfile(f.pathmap("#{spec.build_dir}/tools/mrbc/%n")) }.flatten
+
+  file exec => mrbc_objs + [libfile("#{build.build_dir}/lib/libmruby_core")] do |t|
+    build.linker.run t.name, t.prerequisites
+  end
+
+  build.bins << 'mrbc' unless build.bins.find { |v| v == 'mrbc' }
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c	(revision 331)
@@ -0,0 +1,336 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mruby.h>
+#include <mruby/compile.h>
+#include <mruby/dump.h>
+#include <mruby/proc.h>
+
+#define RITEBIN_EXT ".mrb"
+#define C_EXT       ".c"
+
+struct mrbc_args {
+  int argc;
+  char **argv;
+  int idx;
+  const char *prog;
+  const char *outfile;
+  const char *initname;
+  mrb_bool check_syntax : 1;
+  mrb_bool verbose      : 1;
+  unsigned int flags    : 4;
+};
+
+static void
+usage(const char *name)
+{
+  static const char *const usage_msg[] = {
+  "switches:",
+  "-c           check syntax only",
+  "-o<outfile>  place the output into <outfile>",
+  "-v           print version number, then turn on verbose mode",
+  "-g           produce debugging information",
+  "-B<symbol>   binary <symbol> output in C language format",
+  "-e           generate little endian iseq data",
+  "-E           generate big endian iseq data",
+  "--verbose    run at verbose mode",
+  "--version    print the version",
+  "--copyright  print the copyright",
+  NULL
+  };
+  const char *const *p = usage_msg;
+
+  printf("Usage: %s [switches] programfile\n", name);
+  while (*p)
+    printf("  %s\n", *p++);
+}
+
+static char *
+get_outfilename(mrb_state *mrb, char *infile, const char *ext)
+{
+  size_t infilelen;
+  size_t extlen;
+  char *outfile;
+  char *p;
+
+  infilelen = strlen(infile);
+  extlen = strlen(ext);
+  outfile = (char*)mrb_malloc(mrb, infilelen + extlen + 1);
+  memcpy(outfile, infile, infilelen + 1);
+  if (*ext) {
+    if ((p = strrchr(outfile, '.')) == NULL)
+      p = outfile + infilelen;
+    memcpy(p, ext, extlen + 1);
+  }
+
+  return outfile;
+}
+
+static int
+parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args)
+{
+  char *outfile = NULL;
+  static const struct mrbc_args args_zero = { 0 };
+  int i;
+
+  *args = args_zero;
+  args->argc = argc;
+  args->argv = argv;
+  args->prog = argv[0];
+
+  for (i=1; i<argc; i++) {
+    if (argv[i][0] == '-') {
+      switch ((argv[i])[1]) {
+      case 'o':
+        if (args->outfile) {
+          fprintf(stderr, "%s: an output file is already specified. (%s)\n",
+                  args->prog, outfile);
+          return -1;
+        }
+        if (argv[i][2] == '\0' && argv[i+1]) {
+          i++;
+          args->outfile = get_outfilename(mrb, argv[i], "");
+        }
+        else {
+          args->outfile = get_outfilename(mrb, argv[i] + 2, "");
+        }
+        break;
+      case 'B':
+        if (argv[i][2] == '\0' && argv[i+1]) {
+          i++;
+          args->initname = argv[i];
+        }
+        else {
+          args->initname = argv[i]+2;
+        }
+        if (*args->initname == '\0') {
+          fprintf(stderr, "%s: function name is not specified.\n", args->prog);
+          return -1;
+        }
+        break;
+      case 'c':
+        args->check_syntax = TRUE;
+        break;
+      case 'v':
+        if (!args->verbose) mrb_show_version(mrb);
+        args->verbose = TRUE;
+        break;
+      case 'g':
+        args->flags |= DUMP_DEBUG_INFO;
+        break;
+      case 'E':
+        args->flags = DUMP_ENDIAN_BIG | (args->flags & ~DUMP_ENDIAN_MASK);
+        break;
+      case 'e':
+        args->flags = DUMP_ENDIAN_LIL | (args->flags & ~DUMP_ENDIAN_MASK);
+        break;
+      case 'h':
+        return -1;
+      case '-':
+        if (argv[i][1] == '\n') {
+          return i;
+        }
+        if (strcmp(argv[i] + 2, "version") == 0) {
+          mrb_show_version(mrb);
+          exit(EXIT_SUCCESS);
+        }
+        else if (strcmp(argv[i] + 2, "verbose") == 0) {
+          args->verbose = TRUE;
+          break;
+        }
+        else if (strcmp(argv[i] + 2, "copyright") == 0) {
+          mrb_show_copyright(mrb);
+          exit(EXIT_SUCCESS);
+        }
+        return -1;
+      default:
+        return i;
+      }
+    }
+    else {
+      break;
+    }
+  }
+  if (args->verbose && args->initname && (args->flags & DUMP_ENDIAN_MASK) == 0) {
+    fprintf(stderr, "%s: generating %s endian C file. specify -e/-E for cross compiling.\n",
+            args->prog, bigendian_p() ? "big" : "little");
+  }
+  return i;
+}
+
+static void
+cleanup(mrb_state *mrb, struct mrbc_args *args)
+{
+  mrb_free(mrb, (void*)args->outfile);
+  mrb_close(mrb);
+}
+
+static int
+partial_hook(struct mrb_parser_state *p)
+{
+  mrbc_context *c = p->cxt;
+  struct mrbc_args *args = (struct mrbc_args *)c->partial_data;
+  const char *fn;
+
+  if (p->f) fclose(p->f);
+  if (args->idx >= args->argc) {
+    p->f = NULL;
+    return -1;
+  }
+  fn = args->argv[args->idx++];
+  p->f = fopen(fn, "r");
+  if (p->f == NULL) {
+    fprintf(stderr, "%s: cannot open program file. (%s)\n", args->prog, fn);
+    return -1;
+  }
+  mrb_parser_set_filename(p, fn);
+  return 0;
+}
+
+static mrb_value
+load_file(mrb_state *mrb, struct mrbc_args *args)
+{
+  mrbc_context *c;
+  mrb_value result;
+  char *input = args->argv[args->idx];
+  FILE *infile;
+  mrb_bool need_close = FALSE;
+
+  c = mrbc_context_new(mrb);
+  if (args->verbose)
+    c->dump_result = TRUE;
+  c->no_exec = TRUE;
+  if (input[0] == '-' && input[1] == '\0') {
+    infile = stdin;
+  }
+  else {
+    need_close = TRUE;
+    if ((infile = fopen(input, "r")) == NULL) {
+      fprintf(stderr, "%s: cannot open program file. (%s)\n", args->prog, input);
+      return mrb_nil_value();
+    }
+  }
+  mrbc_filename(mrb, c, input);
+  args->idx++;
+  if (args->idx < args->argc) {
+    need_close = FALSE;
+    mrbc_partial_hook(mrb, c, partial_hook, (void*)args);
+  }
+
+  result = mrb_load_file_cxt(mrb, infile, c);
+  if (need_close) fclose(infile);
+  mrbc_context_free(mrb, c);
+  if (mrb_undef_p(result)) {
+    return mrb_nil_value();
+  }
+  return result;
+}
+
+static int
+dump_file(mrb_state *mrb, FILE *wfp, const char *outfile, struct RProc *proc, struct mrbc_args *args)
+{
+  int n = MRB_DUMP_OK;
+  mrb_irep *irep = proc->body.irep;
+
+  if (args->initname) {
+    n = mrb_dump_irep_cfunc(mrb, irep, args->flags, wfp, args->initname);
+    if (n == MRB_DUMP_INVALID_ARGUMENT) {
+      fprintf(stderr, "%s: invalid C language symbol name\n", args->initname);
+    }
+  }
+  else {
+    n = mrb_dump_irep_binary(mrb, irep, args->flags, wfp);
+  }
+  if (n != MRB_DUMP_OK) {
+    fprintf(stderr, "%s: error in mrb dump (%s) %d\n", args->prog, outfile, n);
+  }
+  return n;
+}
+
+int
+main(int argc, char **argv)
+{
+  mrb_state *mrb = mrb_open();
+  int n, result;
+  struct mrbc_args args;
+  FILE *wfp;
+  mrb_value load;
+
+  if (mrb == NULL) {
+    fputs("Invalid mrb_state, exiting mrbc\n", stderr);
+    return EXIT_FAILURE;
+  }
+
+  n = parse_args(mrb, argc, argv, &args);
+  if (n < 0) {
+    cleanup(mrb, &args);
+    usage(argv[0]);
+    return EXIT_FAILURE;
+  }
+  if (n == argc) {
+    fprintf(stderr, "%s: no program file given\n", args.prog);
+    return EXIT_FAILURE;
+  }
+  if (args.outfile == NULL && !args.check_syntax) {
+    if (n + 1 == argc) {
+      args.outfile = get_outfilename(mrb, argv[n], args.initname ? C_EXT : RITEBIN_EXT);
+    }
+    else {
+      fprintf(stderr, "%s: output file should be specified to compile multiple files\n", args.prog);
+      return EXIT_FAILURE;
+    }
+  }
+
+  args.idx = n;
+  load = load_file(mrb, &args);
+  if (mrb_nil_p(load)) {
+    cleanup(mrb, &args);
+    return EXIT_FAILURE;
+  }
+  if (args.check_syntax) {
+    printf("%s:%s:Syntax OK\n", args.prog, argv[n]);
+  }
+
+  if (args.check_syntax) {
+    cleanup(mrb, &args);
+    return EXIT_SUCCESS;
+  }
+
+  if (args.outfile) {
+    if (strcmp("-", args.outfile) == 0) {
+      wfp = stdout;
+    }
+    else if ((wfp = fopen(args.outfile, "wb")) == NULL) {
+      fprintf(stderr, "%s: cannot open output file:(%s)\n", args.prog, args.outfile);
+      return EXIT_FAILURE;
+    }
+  }
+  else {
+    fprintf(stderr, "Output file is required\n");
+    return EXIT_FAILURE;
+  }
+  result = dump_file(mrb, wfp, args.outfile, mrb_proc_ptr(load), &args);
+  fclose(wfp);
+  cleanup(mrb, &args);
+  if (result != MRB_DUMP_OK) {
+    return EXIT_FAILURE;
+  }
+  return EXIT_SUCCESS;
+}
+
+void
+mrb_init_mrblib(mrb_state *mrb)
+{
+}
+
+#ifndef DISABLE_GEMS
+void
+mrb_init_mrbgems(mrb_state *mrb)
+{
+}
+
+void
+mrb_final_mrbgems(mrb_state *mrb)
+{
+}
+#endif
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mruby-config/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mruby-config/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mruby-config/mrbgem.rake	(revision 331)
@@ -0,0 +1,30 @@
+module MRuby
+  class Build
+    def exefile(name)
+      if name.is_a?(Array)
+        name.flatten.map { |n| exefile(n) }
+      elsif name !~ /\./
+        "#{name}#{exts.executable}"
+      else
+        name
+      end
+    end
+  end
+end
+
+MRuby.each_target do
+  next if kind_of? MRuby::CrossBuild
+
+  mruby_config = 'mruby-config' + (ENV['OS'] == 'Windows_NT' ? '.bat' : '')
+  mruby_config_path = "#{build_dir}/bin/#{mruby_config}"
+  @bins << mruby_config
+
+  file mruby_config_path => libfile("#{build_dir}/lib/libmruby") do |t|
+    FileUtils.copy "#{File.dirname(__FILE__)}/#{mruby_config}", t.name
+    config = Hash[open("#{build_dir}/lib/libmruby.flags.mak").read.split("\n").map {|x| a = x.split(/\s*=\s*/, 2); [a[0], a[1].gsub('\\"', '"') ]}]
+    IO.write(t.name, File.open(t.name) {|f|
+      f.read.gsub (/echo (MRUBY_CFLAGS|MRUBY_LIBS|MRUBY_LDFLAGS_BEFORE_LIBS|MRUBY_LDFLAGS|MRUBY_LIBMRUBY_PATH)/) {|x| config[$1].empty? ? '' : "echo #{config[$1]}"}
+    })
+    FileUtils.chmod(0755, t.name)
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mruby-config/mruby-config
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mruby-config/mruby-config	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mruby-config/mruby-config	(revision 331)
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+while [ $# -gt 0 ]; do
+  case $1 in
+    --cflags) echo MRUBY_CFLAGS;;
+    --ldflags) echo MRUBY_LDFLAGS;;
+    --ldflags-before-libs) echo MRUBY_LDFLAGS_BEFORE_LIBS;;
+    --libs) echo MRUBY_LIBS;;
+    --libmruby-path) echo MRUBY_LIBMRUBY_PATH;;
+    --help) echo "Usage: mruby-config [switches]"
+            echo "  switches:"
+            echo "  --cflags                    print flags passed to compiler"
+            echo "  --ldflags                   print flags passed to linker"
+            echo "  --ldflags-before-libs       print flags passed to linker before linked libraries"
+            echo "  --libs                      print linked libraries"
+            echo "  --libmruby-path             print libmruby path"
+            exit 0;;
+  esac
+  shift
+done
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mruby-config/mruby-config.bat
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mruby-config/mruby-config.bat	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mruby-config/mruby-config.bat	(revision 331)
@@ -0,0 +1,42 @@
+@echo off
+
+:top
+shift
+if "%0" equ "" goto :eof
+if "%0" equ "--cflags" goto cflags
+if "%0" equ "--ldflags" goto ldflags
+if "%0" equ "--ldflags-before-libs" goto ldflagsbeforelibs
+if "%0" equ "--libs" goto libs
+if "%0" equ "--libmruby-path" goto libmrubypath
+if "%0" equ "--help" goto showhelp
+echo Invalid Option
+goto :eof
+
+:cflags
+echo MRUBY_CFLAGS
+goto top
+
+:libs
+echo MRUBY_LIBS
+goto top
+
+:ldflags
+echo MRUBY_LDFLAGS
+goto top
+
+:ldflagsbeforelibs
+echo MRUBY_LDFLAGS_BEFORE_LIBS
+goto top
+
+:libmrubypath
+echo MRUBY_LIBMRUBY_PATH
+goto top
+
+:showhelp
+echo Usage: mruby-config [switches]
+echo   switches:
+echo   --cflags                   print flags passed to compiler
+echo   --ldflags                  print flags passed to linker
+echo   --ldflags-before-libs      print flags passed to linker before linked libraries
+echo   --libs                     print linked libraries
+echo   --libmruby-path            print libmruby path
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mruby/bintest/mruby.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mruby/bintest/mruby.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mruby/bintest/mruby.rb	(revision 331)
@@ -0,0 +1,60 @@
+require 'tempfile'
+
+assert('regression for #1564') do
+  o = `#{cmd('mruby')} -e #{shellquote('<<')} 2>&1`
+  assert_include o, "-e:1:2: syntax error"
+  o = `#{cmd('mruby')} -e #{shellquote('<<-')} 2>&1`
+  assert_include o, "-e:1:3: syntax error"
+end
+
+assert('regression for #1572') do
+  script, bin = Tempfile.new('test.rb'), Tempfile.new('test.mrb')
+  File.write script.path, 'p "ok"'
+  system "#{cmd('mrbc')} -g -o #{bin.path} #{script.path}"
+  o = `#{cmd('mruby')} -b #{bin.path}`.strip
+  assert_equal o, '"ok"'
+end
+
+assert '$0 value' do
+  script, bin = Tempfile.new('test.rb'), Tempfile.new('test.mrb')
+
+  # .rb script
+  script.write "p $0\n"
+  script.flush
+  assert_equal "\"#{script.path}\"", `#{cmd('mruby')} "#{script.path}"`.chomp
+
+  # .mrb file
+  `#{cmd('mrbc')} -o "#{bin.path}" "#{script.path}"`
+  assert_equal "\"#{bin.path}\"", `#{cmd('mruby')} -b "#{bin.path}"`.chomp
+
+  # one liner
+  assert_equal '"-e"', `#{cmd('mruby')} -e #{shellquote('p $0')}`.chomp
+end
+
+assert '__END__', '8.6' do
+  script = Tempfile.new('test.rb')
+
+  script.write <<EOS
+p 'test'
+  __END__ = 'fin'
+p __END__
+__END__
+p 'legend'
+EOS
+  script.flush
+  assert_equal "\"test\"\n\"fin\"\n", `#{cmd('mruby')} #{script.path}`
+end
+
+assert('garbage collecting built-in classes') do
+  script = Tempfile.new('test.rb')
+
+  script.write <<RUBY
+NilClass = nil
+GC.start
+Array.dup
+print nil.class.to_s
+RUBY
+  script.flush
+  assert_equal "NilClass", `#{cmd('mruby')} #{script.path}`
+  assert_equal 0, $?.exitstatus
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mruby/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mruby/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mruby/mrbgem.rake	(revision 331)
@@ -0,0 +1,13 @@
+MRuby::Gem::Specification.new('mruby-bin-mruby') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'mruby command'
+  spec.bins = %w(mruby)
+  spec.add_dependency('mruby-compiler', :core => 'mruby-compiler')
+  spec.add_dependency('mruby-error', :core => 'mruby-error')
+
+  if build.cxx_exception_enabled?
+    @objs << build.compile_as_cxx("#{spec.dir}/tools/mruby/mruby.c", "#{spec.build_dir}/tools/mruby/mruby.cxx")
+    @objs.delete_if { |v| v == objfile("#{spec.build_dir}/tools/mruby/mruby") }
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c	(revision 331)
@@ -0,0 +1,254 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/compile.h>
+#include <mruby/dump.h>
+#include <mruby/variable.h>
+
+#ifdef MRB_DISABLE_STDIO
+static void
+p(mrb_state *mrb, mrb_value obj)
+{
+  mrb_value val = mrb_inspect(mrb, obj);
+
+  fwrite(RSTRING_PTR(val), RSTRING_LEN(val), 1, stdout);
+  putc('\n', stdout);
+}
+#else
+#define p(mrb,obj) mrb_p(mrb,obj)
+#endif
+
+struct _args {
+  FILE *rfp;
+  char* cmdline;
+  mrb_bool fname        : 1;
+  mrb_bool mrbfile      : 1;
+  mrb_bool check_syntax : 1;
+  mrb_bool verbose      : 1;
+  int argc;
+  char** argv;
+};
+
+static void
+usage(const char *name)
+{
+  static const char *const usage_msg[] = {
+  "switches:",
+  "-b           load and execute RiteBinary (mrb) file",
+  "-c           check syntax only",
+  "-e 'command' one line of script",
+  "-v           print version number, then run in verbose mode",
+  "--verbose    run in verbose mode",
+  "--version    print the version",
+  "--copyright  print the copyright",
+  NULL
+  };
+  const char *const *p = usage_msg;
+
+  printf("Usage: %s [switches] programfile\n", name);
+  while (*p)
+    printf("  %s\n", *p++);
+}
+
+static int
+parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
+{
+  char **origargv = argv;
+  static const struct _args args_zero = { 0 };
+
+  *args = args_zero;
+
+  for (argc--,argv++; argc > 0; argc--,argv++) {
+    char *item;
+    if (argv[0][0] != '-') break;
+
+    if (strlen(*argv) <= 1) {
+      argc--; argv++;
+      args->rfp = stdin;
+      break;
+    }
+
+    item = argv[0] + 1;
+    switch (*item++) {
+    case 'b':
+      args->mrbfile = TRUE;
+      break;
+    case 'c':
+      args->check_syntax = TRUE;
+      break;
+    case 'e':
+      if (item[0]) {
+        goto append_cmdline;
+      }
+      else if (argc > 1) {
+        argc--; argv++;
+        item = argv[0];
+append_cmdline:
+        if (!args->cmdline) {
+          size_t buflen;
+          char *buf;
+
+          buflen = strlen(item) + 1;
+          buf = (char *)mrb_malloc(mrb, buflen);
+          memcpy(buf, item, buflen);
+          args->cmdline = buf;
+        }
+        else {
+          size_t cmdlinelen;
+          size_t itemlen;
+
+          cmdlinelen = strlen(args->cmdline);
+          itemlen = strlen(item);
+          args->cmdline =
+            (char *)mrb_realloc(mrb, args->cmdline, cmdlinelen + itemlen + 2);
+          args->cmdline[cmdlinelen] = '\n';
+          memcpy(args->cmdline + cmdlinelen + 1, item, itemlen + 1);
+        }
+      }
+      else {
+        printf("%s: No code specified for -e\n", *origargv);
+        return EXIT_SUCCESS;
+      }
+      break;
+    case 'v':
+      if (!args->verbose) mrb_show_version(mrb);
+      args->verbose = TRUE;
+      break;
+    case '-':
+      if (strcmp((*argv) + 2, "version") == 0) {
+        mrb_show_version(mrb);
+        exit(EXIT_SUCCESS);
+      }
+      else if (strcmp((*argv) + 2, "verbose") == 0) {
+        args->verbose = TRUE;
+        break;
+      }
+      else if (strcmp((*argv) + 2, "copyright") == 0) {
+        mrb_show_copyright(mrb);
+        exit(EXIT_SUCCESS);
+      }
+    default:
+      return EXIT_FAILURE;
+    }
+  }
+
+  if (args->rfp == NULL && args->cmdline == NULL) {
+    if (*argv == NULL) args->rfp = stdin;
+    else {
+      args->rfp = fopen(argv[0], args->mrbfile ? "rb" : "r");
+      if (args->rfp == NULL) {
+        printf("%s: Cannot open program file. (%s)\n", *origargv, *argv);
+        return EXIT_FAILURE;
+      }
+      args->fname = TRUE;
+      args->cmdline = argv[0];
+      argc--; argv++;
+    }
+  }
+  args->argv = (char **)mrb_realloc(mrb, args->argv, sizeof(char*) * (argc + 1));
+  memcpy(args->argv, argv, (argc+1) * sizeof(char*));
+  args->argc = argc;
+
+  return EXIT_SUCCESS;
+}
+
+static void
+cleanup(mrb_state *mrb, struct _args *args)
+{
+  if (args->rfp && args->rfp != stdin)
+    fclose(args->rfp);
+  if (!args->fname)
+    mrb_free(mrb, args->cmdline);
+  mrb_free(mrb, args->argv);
+  mrb_close(mrb);
+}
+
+int
+main(int argc, char **argv)
+{
+  mrb_state *mrb = mrb_open();
+  int n = -1;
+  int i;
+  struct _args args;
+  mrb_value ARGV;
+  mrbc_context *c;
+  mrb_value v;
+  mrb_sym zero_sym;
+
+  if (mrb == NULL) {
+    fputs("Invalid mrb_state, exiting mruby\n", stderr);
+    return EXIT_FAILURE;
+  }
+
+  n = parse_args(mrb, argc, argv, &args);
+  if (n == EXIT_FAILURE || (args.cmdline == NULL && args.rfp == NULL)) {
+    cleanup(mrb, &args);
+    usage(argv[0]);
+    return n;
+  }
+  else {
+    int ai = mrb_gc_arena_save(mrb);
+    ARGV = mrb_ary_new_capa(mrb, args.argc);
+    for (i = 0; i < args.argc; i++) {
+      char* utf8 = mrb_utf8_from_locale(args.argv[i], -1);
+      if (utf8) {
+        mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, utf8));
+        mrb_utf8_free(utf8);
+      }
+    }
+    mrb_define_global_const(mrb, "ARGV", ARGV);
+
+    c = mrbc_context_new(mrb);
+    if (args.verbose)
+      c->dump_result = TRUE;
+    if (args.check_syntax)
+      c->no_exec = TRUE;
+
+    /* Set $0 */
+    zero_sym = mrb_intern_lit(mrb, "$0");
+    if (args.rfp) {
+      const char *cmdline;
+      cmdline = args.cmdline ? args.cmdline : "-";
+      mrbc_filename(mrb, c, cmdline);
+      mrb_gv_set(mrb, zero_sym, mrb_str_new_cstr(mrb, cmdline));
+    }
+    else {
+      mrbc_filename(mrb, c, "-e");
+      mrb_gv_set(mrb, zero_sym, mrb_str_new_lit(mrb, "-e"));
+    }
+
+    /* Load program */
+    if (args.mrbfile) {
+      v = mrb_load_irep_file_cxt(mrb, args.rfp, c);
+    }
+    else if (args.rfp) {
+      v = mrb_load_file_cxt(mrb, args.rfp, c);
+    }
+    else {
+      char* utf8 = mrb_utf8_from_locale(args.cmdline, -1);
+      if (!utf8) abort();
+      v = mrb_load_string_cxt(mrb, utf8, c);
+      mrb_utf8_free(utf8);
+    }
+
+    mrb_gc_arena_restore(mrb, ai);
+    mrbc_context_free(mrb, c);
+    if (mrb->exc) {
+      if (mrb_undef_p(v)) {
+        mrb_p(mrb, mrb_obj_value(mrb->exc));
+      }
+      else {
+        mrb_print_error(mrb);
+      }
+      n = -1;
+    }
+    else if (args.check_syntax) {
+      printf("Syntax OK\n");
+    }
+  }
+  cleanup(mrb, &args);
+
+  return n == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-strip/bintest/mruby-strip.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-strip/bintest/mruby-strip.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-strip/bintest/mruby-strip.rb	(revision 331)
@@ -0,0 +1,73 @@
+require 'tempfile'
+
+assert('no files') do
+  o = `#{cmd('mruby-strip')} 2>&1`
+  assert_equal 1, $?.exitstatus
+  assert_equal "no files to strip", o.split("\n")[0]
+end
+
+assert('file not found') do
+  o = `#{cmd('mruby-strip')} not_found.mrb 2>&1`
+  assert_equal 1, $?.exitstatus
+  assert_equal "can't open file for reading not_found.mrb\n", o
+end
+
+assert('not irep file') do
+  t = Tempfile.new('script.rb')
+  t.write 'p test\n'
+  t.flush
+  o = `#{cmd('mruby-strip')} #{t.path} 2>&1`
+  assert_equal 1, $?.exitstatus
+  assert_equal "can't read irep file #{t.path}\n", o
+end
+
+assert('success') do
+  script_file, compiled1, compiled2 =
+    Tempfile.new('script.rb'), Tempfile.new('c1.mrb'), Tempfile.new('c2.mrb')
+  script_file.write "p 'test'\n"
+  script_file.flush
+  `#{cmd('mrbc')} -g -o #{compiled1.path} #{script_file.path}`
+  `#{cmd('mrbc')} -g -o #{compiled2.path} #{script_file.path}`
+
+  o = `#{cmd('mruby-strip')} #{compiled1.path}`
+  assert_equal 0, $?.exitstatus
+  assert_equal "", o
+  assert_equal `#{cmd('mruby')} #{script_file.path}`, `#{cmd('mruby')} -b #{compiled1.path}`
+
+  o = `#{cmd('mruby-strip')} #{compiled1.path} #{compiled2.path}`
+  assert_equal 0, $?.exitstatus
+  assert_equal "", o
+end
+
+assert('check debug section') do
+  script_file, with_debug, without_debug =
+    Tempfile.new('script.rb'), Tempfile.new('c1.mrb'), Tempfile.new('c2.mrb')
+  script_file.write "p 'test'\n"
+  script_file.flush
+  `#{cmd('mrbc')} -o #{without_debug.path} #{script_file.path}`
+  `#{cmd('mrbc')} -g -o #{with_debug.path} #{script_file.path}`
+
+  assert_true with_debug.size >= without_debug.size
+
+  `#{cmd('mruby-strip')} #{with_debug.path}`
+  assert_equal without_debug.size, with_debug.size
+end
+
+assert('check lv section') do
+  script_file, with_lv, without_lv =
+    Tempfile.new('script.rb'), Tempfile.new('c1.mrb'), Tempfile.new('c2.mrb')
+  script_file.write <<EOS
+a, b = 0, 1
+a += b
+p Kernel.local_variables
+EOS
+  script_file.flush
+  `#{cmd('mrbc')} -o #{with_lv.path} #{script_file.path}`
+  `#{cmd('mrbc')} -o #{without_lv.path} #{script_file.path}`
+
+  `#{cmd('mruby-strip')} -l #{without_lv.path}`
+  assert_true without_lv.size < with_lv.size
+
+  assert_equal '[:a, :b]', `#{cmd('mruby')} -b #{with_lv.path}`.chomp
+  assert_equal '[]', `#{cmd('mruby')} -b #{without_lv.path}`.chomp
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-strip/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-strip/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-strip/mrbgem.rake	(revision 331)
@@ -0,0 +1,6 @@
+MRuby::Gem::Specification.new('mruby-bin-strip') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'irep dump debug section remover command'
+  spec.bins = %w(mruby-strip)
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c	(revision 331)
@@ -0,0 +1,155 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mruby.h>
+#include <mruby/irep.h>
+#include <mruby/dump.h>
+
+struct strip_args {
+  int argc_start;
+  int argc;
+  char **argv;
+  mrb_bool lvar;
+};
+
+
+static void
+irep_remove_lv(mrb_state *mrb, mrb_irep *irep)
+{
+  size_t i;
+
+  if (irep->lv) {
+    mrb_free(mrb, irep->lv);
+    irep->lv = NULL;
+  }
+
+  for (i = 0; i < irep->rlen; ++i) {
+    irep_remove_lv(mrb, irep->reps[i]);
+  }
+}
+
+static void
+print_usage(const char *f)
+{
+  printf("Usage: %s [switches] irepfiles\n", f);
+  printf("switches:\n");
+  printf("  -l, --lvar   remove LVAR section too.\n");
+}
+
+static int
+parse_args(int argc, char **argv, struct strip_args *args)
+{
+  int i;
+
+  args->argc_start = 0;
+  args->argc = argc;
+  args->argv = argv;
+  args->lvar = FALSE;
+
+  for (i = 1; i < argc; ++i) {
+    const size_t len = strlen(argv[i]);
+    if (len >= 2 && argv[i][0] == '-') {
+      switch (argv[i][1]) {
+      case 'l':
+        args->lvar = TRUE;
+        break;
+      case '-':
+        if (strncmp((*argv) + 2, "lvar", len) == 0) {
+          args->lvar = TRUE;
+          break;
+        }
+      default:
+        return -1;
+      }
+    }
+    else {
+      break;
+    }
+  }
+
+  args->argc_start = i;
+  return i;
+}
+
+static int
+strip(mrb_state *mrb, struct strip_args *args)
+{
+  int i;
+
+  for (i = args->argc_start; i < args->argc; ++i) {
+    char *filename;
+    FILE *rfile;
+    mrb_irep *irep;
+    FILE *wfile;
+    int dump_result;
+
+    filename = args->argv[i];
+    rfile = fopen(filename, "rb");
+    if (rfile == NULL) {
+      fprintf(stderr, "can't open file for reading %s\n", filename);
+      return EXIT_FAILURE;
+    }
+
+    irep = mrb_read_irep_file(mrb, rfile);
+    fclose(rfile);
+    if (irep == NULL) {
+      fprintf(stderr, "can't read irep file %s\n", filename);
+      return EXIT_FAILURE;
+    }
+
+    /* clear lv if --lvar is enabled */
+    if (args->lvar) {
+      irep_remove_lv(mrb, irep);
+    }
+
+    wfile = fopen(filename, "wb");
+    if (wfile == NULL) {
+      fprintf(stderr, "can't open file for writing %s\n", filename);
+      mrb_irep_decref(mrb, irep);
+      return EXIT_FAILURE;
+    }
+
+    /* debug flag must always be false */
+    dump_result = mrb_dump_irep_binary(mrb, irep, FALSE, wfile);
+
+    fclose(wfile);
+    mrb_irep_decref(mrb, irep);
+
+    if (dump_result != MRB_DUMP_OK) {
+      fprintf(stderr, "error occurred during dumping %s\n", filename);
+      return EXIT_FAILURE;
+    }
+  }
+  return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char **argv)
+{
+  struct strip_args args;
+  int args_result;
+  mrb_state *mrb;
+  int ret;
+
+  if (argc <= 1) {
+    printf("no files to strip\n");
+    print_usage(argv[0]);
+    return EXIT_FAILURE;
+  }
+
+  args_result = parse_args(argc, argv, &args);
+  if (args_result < 0) {
+    print_usage(argv[0]);
+    return EXIT_FAILURE;
+  }
+  mrb = mrb_open_core(mrb_default_allocf, NULL);
+  if (mrb == NULL) {
+    fputs("Invalid mrb_state, exiting mruby-strip\n", stderr);
+    return EXIT_FAILURE;
+  }
+
+  ret = strip(mrb, &args);
+
+  mrb_close(mrb);
+  return ret;
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-class-ext/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-class-ext/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-class-ext/mrbgem.rake	(revision 331)
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-class-ext') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'class/module extension'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-class-ext/src/class.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-class-ext/src/class.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-class-ext/src/class.c	(revision 331)
@@ -0,0 +1,23 @@
+#include "mruby.h"
+#include "mruby/class.h"
+#include "mruby/string.h"
+
+static mrb_value
+mrb_mod_name(mrb_state *mrb, mrb_value self)
+{
+  mrb_value name = mrb_class_path(mrb, mrb_class_ptr(self));
+  return mrb_nil_p(name)? name : mrb_str_dup(mrb, name);
+}
+
+void
+mrb_mruby_class_ext_gem_init(mrb_state *mrb)
+{
+  struct RClass *mod = mrb->module_class;
+
+  mrb_define_method(mrb, mod, "name", mrb_mod_name, MRB_ARGS_NONE());
+}
+
+void
+mrb_mruby_class_ext_gem_final(mrb_state *mrb)
+{
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-class-ext/test/module.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-class-ext/test/module.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-class-ext/test/module.rb	(revision 331)
@@ -0,0 +1,10 @@
+assert 'Module#name' do
+  module A
+    class B
+    end
+  end
+
+  assert_nil A::B.singleton_class.name
+  assert_equal 'Fixnum', Fixnum.name
+  assert_equal 'A::B', A::B.name
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/bintest/mrbc.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/bintest/mrbc.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/bintest/mrbc.rb	(revision 331)
@@ -0,0 +1,30 @@
+require 'tempfile'
+
+assert('Compiling multiple files without new line in last line. #2361') do
+  a, b, out = Tempfile.new('a.rb'), Tempfile.new('b.rb'), Tempfile.new('out.mrb')
+  a.write('module A; end')
+  a.flush
+  b.write('module B; end')
+  b.flush
+  result = `#{cmd('mrbc')} -c -o #{out.path} #{a.path} #{b.path} 2>&1`
+  assert_equal "#{cmd('mrbc')}:#{a.path}:Syntax OK", result.chomp
+  assert_equal 0, $?.exitstatus
+end
+
+assert('parsing function with void argument') do
+  a, out = Tempfile.new('a.rb'), Tempfile.new('out.mrb')
+  a.write('f ()')
+  a.flush
+  result = `#{cmd('mrbc')} -c -o #{out.path} #{a.path} 2>&1`
+  assert_equal "#{cmd('mrbc')}:#{a.path}:Syntax OK", result.chomp
+  assert_equal 0, $?.exitstatus
+end
+
+assert('embedded document with invalid terminator') do
+  a, out = Tempfile.new('a.rb'), Tempfile.new('out.mrb')
+  a.write("=begin\n=endx\n")
+  a.flush
+  result = `#{cmd('mrbc')} -c -o #{out.path} #{a.path} 2>&1`
+  assert_equal "#{a.path}:3:0: embedded document meets end of file", result.chomp
+  assert_equal 1, $?.exitstatus
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/core/codegen.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/core/codegen.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/core/codegen.c	(revision 331)
@@ -0,0 +1,3024 @@
+/*
+** codegen.c - mruby code generator
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <ctype.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mruby.h>
+#include <mruby/compile.h>
+#include <mruby/proc.h>
+#include <mruby/numeric.h>
+#include <mruby/string.h>
+#include <mruby/debug.h>
+#include "node.h"
+#include <mruby/opcode.h>
+#include <mruby/re.h>
+#include <mruby/throw.h>
+
+#ifndef MRB_CODEGEN_LEVEL_MAX
+#define MRB_CODEGEN_LEVEL_MAX 1024
+#endif
+
+typedef mrb_ast_node node;
+typedef struct mrb_parser_state parser_state;
+
+enum looptype {
+  LOOP_NORMAL,
+  LOOP_BLOCK,
+  LOOP_FOR,
+  LOOP_BEGIN,
+  LOOP_RESCUE,
+};
+
+struct loopinfo {
+  enum looptype type;
+  int pc1, pc2, pc3, acc;
+  int ensure_level;
+  struct loopinfo *prev;
+};
+
+typedef struct scope {
+  mrb_state *mrb;
+  mrb_pool *mpool;
+  struct mrb_jmpbuf jmp;
+
+  struct scope *prev;
+
+  node *lv;
+
+  int sp;
+  int pc;
+  int lastlabel;
+  int ainfo:15;
+  mrb_bool mscope:1;
+
+  struct loopinfo *loop;
+  int ensure_level;
+  char const *filename;
+  uint16_t lineno;
+
+  mrb_code *iseq;
+  uint16_t *lines;
+  int icapa;
+
+  mrb_irep *irep;
+  size_t pcapa;
+  size_t scapa;
+  size_t rcapa;
+
+  uint16_t nlocals;
+  uint16_t nregs;
+  int ai;
+
+  int debug_start_pos;
+  uint16_t filename_index;
+  parser_state* parser;
+
+  int rlev;                     /* recursion levels */
+} codegen_scope;
+
+static codegen_scope* scope_new(mrb_state *mrb, codegen_scope *prev, node *lv);
+static void scope_finish(codegen_scope *s);
+static struct loopinfo *loop_push(codegen_scope *s, enum looptype t);
+static void loop_break(codegen_scope *s, node *tree);
+static void loop_pop(codegen_scope *s, int val);
+
+static void gen_assignment(codegen_scope *s, node *tree, int sp, int val);
+static void gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val);
+
+static void codegen(codegen_scope *s, node *tree, int val);
+static void raise_error(codegen_scope *s, const char *msg);
+
+static void
+codegen_error(codegen_scope *s, const char *message)
+{
+  if (!s) return;
+  while (s->prev) {
+    codegen_scope *tmp = s->prev;
+    mrb_free(s->mrb, s->iseq);
+    mrb_pool_close(s->mpool);
+    s = tmp;
+  }
+#ifndef MRB_DISABLE_STDIO
+  if (s->filename && s->lineno) {
+    fprintf(stderr, "codegen error:%s:%d: %s\n", s->filename, s->lineno, message);
+  }
+  else {
+    fprintf(stderr, "codegen error: %s\n", message);
+  }
+#endif
+  MRB_THROW(&s->jmp);
+}
+
+static void*
+codegen_palloc(codegen_scope *s, size_t len)
+{
+  void *p = mrb_pool_alloc(s->mpool, len);
+
+  if (!p) codegen_error(s, "pool memory allocation");
+  return p;
+}
+
+static void*
+codegen_malloc(codegen_scope *s, size_t len)
+{
+  void *p = mrb_malloc_simple(s->mrb, len);
+
+  if (!p) codegen_error(s, "mrb_malloc");
+  return p;
+}
+
+static void*
+codegen_realloc(codegen_scope *s, void *p, size_t len)
+{
+  p = mrb_realloc_simple(s->mrb, p, len);
+
+  if (!p && len > 0) codegen_error(s, "mrb_realloc");
+  return p;
+}
+
+static int
+new_label(codegen_scope *s)
+{
+  s->lastlabel = s->pc;
+  return s->pc;
+}
+
+static inline int
+genop(codegen_scope *s, mrb_code i)
+{
+  if (s->pc == s->icapa) {
+    s->icapa *= 2;
+    s->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->icapa);
+    if (s->lines) {
+      s->lines = (uint16_t*)codegen_realloc(s, s->lines, sizeof(short)*s->icapa);
+      s->irep->lines = s->lines;
+    }
+  }
+  s->iseq[s->pc] = i;
+  if (s->lines) {
+    s->lines[s->pc] = s->lineno;
+  }
+  return s->pc++;
+}
+
+#define NOVAL  0
+#define VAL    1
+
+static mrb_bool
+no_optimize(codegen_scope *s)
+{
+  if (s && s->parser && s->parser->no_optimize)
+    return TRUE;
+  return FALSE;
+}
+
+static int
+genop_peep(codegen_scope *s, mrb_code i, int val)
+{
+  /* peephole optimization */
+  if (!no_optimize(s) && s->lastlabel != s->pc && s->pc > 0) {
+    mrb_code i0 = s->iseq[s->pc-1];
+    int c1 = GET_OPCODE(i);
+    int c0 = GET_OPCODE(i0);
+
+    switch (c1) {
+    case OP_MOVE:
+      if (GETARG_A(i) == GETARG_B(i)) {
+        /* skip useless OP_MOVE */
+        return 0;
+      }
+      if (val) break;
+      switch (c0) {
+      case OP_MOVE:
+        if (GETARG_A(i) == GETARG_A(i0)) {
+          /* skip overriden OP_MOVE */
+          s->pc--;
+          s->iseq[s->pc] = i;
+        }
+        if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i) == GETARG_B(i0)) {
+          /* skip swapping OP_MOVE */
+          return 0;
+        }
+        if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
+          s->pc--;
+          return genop_peep(s, MKOP_AB(OP_MOVE, GETARG_A(i), GETARG_B(i0)), val);
+        }
+        break;
+      case OP_LOADI:
+        if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
+          s->iseq[s->pc-1] = MKOP_AsBx(OP_LOADI, GETARG_A(i), GETARG_sBx(i0));
+          return 0;
+        }
+        break;
+      case OP_ARRAY:
+      case OP_HASH:
+      case OP_RANGE:
+      case OP_AREF:
+      case OP_GETUPVAR:
+        if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
+          s->iseq[s->pc-1] = MKOP_ABC(c0, GETARG_A(i), GETARG_B(i0), GETARG_C(i0));
+          return 0;
+        }
+        break;
+      case OP_LOADSYM:
+      case OP_GETGLOBAL:
+      case OP_GETIV:
+      case OP_GETCV:
+      case OP_GETCONST:
+      case OP_GETSPECIAL:
+      case OP_LOADL:
+      case OP_STRING:
+        if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
+          s->iseq[s->pc-1] = MKOP_ABx(c0, GETARG_A(i), GETARG_Bx(i0));
+          return 0;
+        }
+        break;
+      case OP_SCLASS:
+        if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
+          s->iseq[s->pc-1] = MKOP_AB(c0, GETARG_A(i), GETARG_B(i0));
+          return 0;
+        }
+        break;
+      case OP_LOADNIL:
+      case OP_LOADSELF:
+      case OP_LOADT:
+      case OP_LOADF:
+      case OP_OCLASS:
+        if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
+          s->iseq[s->pc-1] = MKOP_A(c0, GETARG_A(i));
+          return 0;
+        }
+        break;
+      default:
+        break;
+      }
+      break;
+    case OP_SETIV:
+    case OP_SETCV:
+    case OP_SETCONST:
+    case OP_SETMCNST:
+    case OP_SETGLOBAL:
+      if (val) break;
+      if (c0 == OP_MOVE) {
+        if (GETARG_A(i) == GETARG_A(i0)) {
+          s->iseq[s->pc-1] = MKOP_ABx(c1, GETARG_B(i0), GETARG_Bx(i));
+          return 0;
+        }
+      }
+      break;
+    case OP_SETUPVAR:
+      if (val) break;
+      if (c0 == OP_MOVE) {
+        if (GETARG_A(i) == GETARG_A(i0)) {
+          s->iseq[s->pc-1] = MKOP_ABC(c1, GETARG_B(i0), GETARG_B(i), GETARG_C(i));
+          return 0;
+        }
+      }
+      break;
+    case OP_EPOP:
+      if (c0 == OP_EPOP) {
+        s->iseq[s->pc-1] = MKOP_A(OP_EPOP, GETARG_A(i0)+GETARG_A(i));
+        return 0;
+      }
+      break;
+    case OP_POPERR:
+      if (c0 == OP_POPERR) {
+        s->iseq[s->pc-1] = MKOP_A(OP_POPERR, GETARG_A(i0)+GETARG_A(i));
+        return 0;
+      }
+      break;
+    case OP_RETURN:
+      switch (c0) {
+      case OP_RETURN:
+        return 0;
+      case OP_MOVE:
+        if (GETARG_A(i0) >= s->nlocals) {
+          s->iseq[s->pc-1] = MKOP_AB(OP_RETURN, GETARG_B(i0), OP_R_NORMAL);
+          return 0;
+        }
+        break;
+      case OP_SETIV:
+      case OP_SETCV:
+      case OP_SETCONST:
+      case OP_SETMCNST:
+      case OP_SETUPVAR:
+      case OP_SETGLOBAL:
+        s->pc--;
+        genop_peep(s, i0, NOVAL);
+        i0 = s->iseq[s->pc-1];
+        return genop(s, MKOP_AB(OP_RETURN, GETARG_A(i0), OP_R_NORMAL));
+#if 0
+      case OP_SEND:
+        if (GETARG_B(i) == OP_R_NORMAL && GETARG_A(i) == GETARG_A(i0)) {
+          s->iseq[s->pc-1] = MKOP_ABC(OP_TAILCALL, GETARG_A(i0), GETARG_B(i0), GETARG_C(i0));
+          return;
+        }
+        break;
+#endif
+      default:
+        break;
+      }
+      break;
+    case OP_ADD:
+    case OP_SUB:
+      if (c0 == OP_LOADI) {
+        int c = GETARG_sBx(i0);
+
+        if (c1 == OP_SUB) c = -c;
+        if (c > 127 || c < -127) break;
+        if (0 <= c)
+          s->iseq[s->pc-1] = MKOP_ABC(OP_ADDI, GETARG_A(i), GETARG_B(i), c);
+        else
+          s->iseq[s->pc-1] = MKOP_ABC(OP_SUBI, GETARG_A(i), GETARG_B(i), -c);
+        return 0;
+      }
+    case OP_STRCAT:
+      if (c0 == OP_STRING) {
+        mrb_value v = s->irep->pool[GETARG_Bx(i0)];
+
+        if (mrb_string_p(v) && RSTRING_LEN(v) == 0) {
+          s->pc--;
+          return 0;
+        }
+      }
+      if (c0 == OP_LOADNIL) {
+        if (GETARG_B(i) == GETARG_A(i0)) {
+          s->pc--;
+          return 0;
+        }
+      }
+      break;
+    case OP_JMPIF:
+    case OP_JMPNOT:
+      if (c0 == OP_MOVE && GETARG_A(i) == GETARG_A(i0)) {
+        s->iseq[s->pc-1] = MKOP_AsBx(c1, GETARG_B(i0), GETARG_sBx(i));
+        return s->pc-1;
+      }
+      break;
+    default:
+      break;
+    }
+  }
+  return genop(s, i);
+}
+
+static void
+scope_error(codegen_scope *s)
+{
+  exit(EXIT_FAILURE);
+}
+
+static inline void
+dispatch(codegen_scope *s, int pc)
+{
+  int diff = s->pc - pc;
+  mrb_code i = s->iseq[pc];
+  int c = GET_OPCODE(i);
+
+  s->lastlabel = s->pc;
+  switch (c) {
+  case OP_JMP:
+  case OP_JMPIF:
+  case OP_JMPNOT:
+  case OP_ONERR:
+    break;
+  default:
+#ifndef MRB_DISABLE_STDIO
+    fprintf(stderr, "bug: dispatch on non JMP op\n");
+#endif
+    scope_error(s);
+    break;
+  }
+  if (diff > MAXARG_sBx) {
+    codegen_error(s, "too distant jump address");
+  }
+  s->iseq[pc] = MKOP_AsBx(c, GETARG_A(i), diff);
+}
+
+static void
+dispatch_linked(codegen_scope *s, int pc)
+{
+  mrb_code i;
+  int pos;
+
+  if (!pc) return;
+  for (;;) {
+    i = s->iseq[pc];
+    pos = GETARG_sBx(i);
+    dispatch(s, pc);
+    if (!pos) break;
+    pc = pos;
+  }
+}
+
+#define nregs_update do {if (s->sp > s->nregs) s->nregs = s->sp;} while (0)
+static void
+push_(codegen_scope *s)
+{
+  if (s->sp > 511) {
+    codegen_error(s, "too complex expression");
+  }
+  s->sp++;
+  nregs_update;
+}
+
+static void
+push_n_(codegen_scope *s, size_t n)
+{
+  if (s->sp+n > 511) {
+    codegen_error(s, "too complex expression");
+  }
+  s->sp+=n;
+  nregs_update;
+}
+
+#define push() push_(s)
+#define push_n(n) push_n_(s,n)
+#define pop_(s) ((s)->sp--)
+#define pop() pop_(s)
+#define pop_n(n) (s->sp-=(n))
+#define cursp() (s->sp)
+
+static inline int
+new_lit(codegen_scope *s, mrb_value val)
+{
+  size_t i;
+  mrb_value *pv;
+
+  switch (mrb_type(val)) {
+  case MRB_TT_STRING:
+    for (i=0; i<s->irep->plen; i++) {
+      mrb_int len;
+      pv = &s->irep->pool[i];
+
+      if (mrb_type(*pv) != MRB_TT_STRING) continue;
+      if ((len = RSTRING_LEN(*pv)) != RSTRING_LEN(val)) continue;
+      if (memcmp(RSTRING_PTR(*pv), RSTRING_PTR(val), len) == 0)
+        return i;
+    }
+    break;
+  case MRB_TT_FLOAT:
+    for (i=0; i<s->irep->plen; i++) {
+      pv = &s->irep->pool[i];
+      if (mrb_type(*pv) != MRB_TT_FLOAT) continue;
+      if (mrb_float(*pv) == mrb_float(val)) return i;
+    }
+    break;
+  case MRB_TT_FIXNUM:
+    for (i=0; i<s->irep->plen; i++) {
+      pv = &s->irep->pool[i];
+      if (!mrb_fixnum_p(*pv)) continue;
+      if (mrb_fixnum(*pv) == mrb_fixnum(val)) return i;
+    }
+    break;
+  default:
+    /* should not happen */
+    return 0;
+  }
+
+  if (s->irep->plen == s->pcapa) {
+    s->pcapa *= 2;
+    s->irep->pool = (mrb_value *)codegen_realloc(s, s->irep->pool, sizeof(mrb_value)*s->pcapa);
+  }
+
+  pv = &s->irep->pool[s->irep->plen];
+  i = s->irep->plen++;
+
+  switch (mrb_type(val)) {
+  case MRB_TT_STRING:
+    *pv = mrb_str_pool(s->mrb, val);
+    break;
+
+  case MRB_TT_FLOAT:
+#ifdef MRB_WORD_BOXING
+    *pv = mrb_float_pool(s->mrb, mrb_float(val));
+    break;
+#endif
+  case MRB_TT_FIXNUM:
+    *pv = val;
+    break;
+
+  default:
+    /* should not happen */
+    break;
+  }
+  return i;
+}
+
+/* method symbols should be fit in 9 bits */
+#define MAXMSYMLEN 512
+/* maximum symbol numbers */
+#define MAXSYMLEN 65536
+
+static int
+new_msym(codegen_scope *s, mrb_sym sym)
+{
+  size_t i, len;
+
+  mrb_assert(s->irep);
+
+  len = s->irep->slen;
+  if (len > MAXMSYMLEN) len = MAXMSYMLEN;
+  for (i=0; i<len; i++) {
+    if (s->irep->syms[i] == sym) return i;
+    if (s->irep->syms[i] == 0) break;
+  }
+  if (i == MAXMSYMLEN) {
+    codegen_error(s, "too many symbols (max " MRB_STRINGIZE(MAXMSYMLEN) ")");
+  }
+  s->irep->syms[i] = sym;
+  if (i == s->irep->slen) s->irep->slen++;
+  return i;
+}
+
+static int
+new_sym(codegen_scope *s, mrb_sym sym)
+{
+  size_t i;
+
+  for (i=0; i<s->irep->slen; i++) {
+    if (s->irep->syms[i] == sym) return i;
+  }
+  if (s->irep->slen == MAXSYMLEN) {
+    codegen_error(s, "too many symbols (max " MRB_STRINGIZE(MAXSYMLEN) ")");
+  }
+
+  if (s->irep->slen > MAXMSYMLEN/2 && s->scapa == MAXMSYMLEN) {
+    s->scapa = MAXSYMLEN;
+    s->irep->syms = (mrb_sym *)codegen_realloc(s, s->irep->syms, sizeof(mrb_sym)*MAXSYMLEN);
+    for (i = s->irep->slen; i < MAXMSYMLEN; i++) {
+      static const mrb_sym mrb_sym_zero = { 0 };
+      s->irep->syms[i] = mrb_sym_zero;
+    }
+    s->irep->slen = MAXMSYMLEN;
+  }
+  s->irep->syms[s->irep->slen] = sym;
+  return s->irep->slen++;
+}
+
+static int
+node_len(node *tree)
+{
+  int n = 0;
+
+  while (tree) {
+    n++;
+    tree = tree->cdr;
+  }
+  return n;
+}
+
+#define sym(x) ((mrb_sym)(intptr_t)(x))
+#define lv_name(lv) sym((lv)->car)
+static int
+lv_idx(codegen_scope *s, mrb_sym id)
+{
+  node *lv = s->lv;
+  int n = 1;
+
+  while (lv) {
+    if (lv_name(lv) == id) return n;
+    n++;
+    lv = lv->cdr;
+  }
+  return 0;
+}
+
+static void
+for_body(codegen_scope *s, node *tree)
+{
+  codegen_scope *prev = s;
+  int idx;
+  struct loopinfo *lp;
+  node *n2;
+  mrb_code c;
+
+  /* generate receiver */
+  codegen(s, tree->cdr->car, VAL);
+  /* generate loop-block */
+  s = scope_new(s->mrb, s, NULL);
+  if (s == NULL) {
+    raise_error(prev, "unexpected scope");
+  }
+
+  push();                       /* push for a block parameter */
+
+  /* generate loop variable */
+  n2 = tree->car;
+  genop(s, MKOP_Ax(OP_ENTER, 0x40000));
+  if (n2->car && !n2->car->cdr && !n2->cdr) {
+    gen_assignment(s, n2->car->car, 1, NOVAL);
+  }
+  else {
+    gen_vmassignment(s, n2, 1, VAL);
+  }
+  /* construct loop */
+  lp = loop_push(s, LOOP_FOR);
+  lp->pc2 = new_label(s);
+
+  /* loop body */
+  codegen(s, tree->cdr->cdr->car, VAL);
+  pop();
+  if (s->pc > 0) {
+    c = s->iseq[s->pc-1];
+    if (GET_OPCODE(c) != OP_RETURN || GETARG_B(c) != OP_R_NORMAL || s->pc == s->lastlabel)
+      genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
+  }
+  loop_pop(s, NOVAL);
+  scope_finish(s);
+  s = prev;
+  genop(s, MKOP_Abc(OP_LAMBDA, cursp(), s->irep->rlen-1, OP_L_BLOCK));
+  pop();
+  idx = new_msym(s, mrb_intern_lit(s->mrb, "each"));
+  genop(s, MKOP_ABC(OP_SENDB, cursp(), idx, 0));
+}
+
+static int
+lambda_body(codegen_scope *s, node *tree, int blk)
+{
+  mrb_code c;
+  codegen_scope *parent = s;
+  s = scope_new(s->mrb, s, tree->car);
+  if (s == NULL) {
+    raise_error(parent, "unexpected scope");
+  }
+
+  s->mscope = !blk;
+
+  if (blk) {
+    struct loopinfo *lp = loop_push(s, LOOP_BLOCK);
+    lp->pc1 = new_label(s);
+  }
+  tree = tree->cdr;
+  if (tree->car) {
+    mrb_aspec a;
+    int ma, oa, ra, pa, ka, kd, ba;
+    int pos, i;
+    node *n, *opt;
+
+    ma = node_len(tree->car->car);
+    n = tree->car->car;
+    while (n) {
+      n = n->cdr;
+    }
+    oa = node_len(tree->car->cdr->car);
+    ra = tree->car->cdr->cdr->car ? 1 : 0;
+    pa = node_len(tree->car->cdr->cdr->cdr->car);
+    ka = kd = 0;
+    ba = tree->car->cdr->cdr->cdr->cdr ? 1 : 0;
+
+    if (ma > 0x1f || oa > 0x1f || pa > 0x1f || ka > 0x1f) {
+      codegen_error(s, "too many formal arguments");
+    }
+    a = ((mrb_aspec)(ma & 0x1f) << 18)
+      | ((mrb_aspec)(oa & 0x1f) << 13)
+      | ((ra & 1) << 12)
+      | ((pa & 0x1f) << 7)
+      | ((ka & 0x1f) << 2)
+      | ((kd & 1)<< 1)
+      | (ba & 1);
+    s->ainfo = (((ma+oa) & 0x3f) << 6) /* (12bits = 6:1:5) */
+      | ((ra & 1) << 5)
+      | (pa & 0x1f);
+    genop(s, MKOP_Ax(OP_ENTER, a));
+    pos = new_label(s);
+    for (i=0; i<oa; i++) {
+      new_label(s);
+      genop(s, MKOP_sBx(OP_JMP, 0));
+    }
+    if (oa > 0) {
+      genop(s, MKOP_sBx(OP_JMP, 0));
+    }
+    opt = tree->car->cdr->car;
+    i = 0;
+    while (opt) {
+      int idx;
+
+      dispatch(s, pos+i);
+      codegen(s, opt->car->cdr, VAL);
+      idx = lv_idx(s, (mrb_sym)(intptr_t)opt->car->car);
+      pop();
+      genop_peep(s, MKOP_AB(OP_MOVE, idx, cursp()), NOVAL);
+      i++;
+      opt = opt->cdr;
+    }
+    if (oa > 0) {
+      dispatch(s, pos+i);
+    }
+  }
+  codegen(s, tree->cdr->car, VAL);
+  pop();
+  if (s->pc > 0) {
+    c = s->iseq[s->pc-1];
+    if (GET_OPCODE(c) != OP_RETURN || GETARG_B(c) != OP_R_NORMAL || s->pc == s->lastlabel) {
+      if (s->nregs == 0) {
+        genop(s, MKOP_A(OP_LOADNIL, 0));
+        genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
+      }
+      else {
+        genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
+      }
+    }
+  }
+  if (blk) {
+    loop_pop(s, NOVAL);
+  }
+  scope_finish(s);
+  return parent->irep->rlen - 1;
+}
+
+static int
+scope_body(codegen_scope *s, node *tree, int val)
+{
+  codegen_scope *scope = scope_new(s->mrb, s, tree->car);
+  if (scope == NULL) {
+    raise_error(s, "unexpected scope");
+  }
+
+  codegen(scope, tree->cdr, VAL);
+  if (!s->iseq) {
+    genop(scope, MKOP_A(OP_STOP, 0));
+  }
+  else if (!val) {
+    genop(scope, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
+  }
+  else {
+    if (scope->nregs == 0) {
+      genop(scope, MKOP_A(OP_LOADNIL, 0));
+      genop(scope, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
+    }
+    else {
+      genop_peep(scope, MKOP_AB(OP_RETURN, scope->sp-1, OP_R_NORMAL), NOVAL);
+    }
+  }
+  scope_finish(scope);
+  if (!s->irep) {
+    /* should not happen */
+    return 0;
+  }
+  return s->irep->rlen - 1;
+}
+
+static mrb_bool
+nosplat(node *t)
+{
+  while (t) {
+    if ((intptr_t)t->car->car == NODE_SPLAT) return FALSE;
+    t = t->cdr;
+  }
+  return TRUE;
+}
+
+static mrb_sym
+attrsym(codegen_scope *s, mrb_sym a)
+{
+  const char *name;
+  mrb_int len;
+  char *name2;
+
+  name = mrb_sym2name_len(s->mrb, a, &len);
+  name2 = (char *)codegen_palloc(s,
+                                 (size_t)len
+                                 + 1 /* '=' */
+                                 + 1 /* '\0' */
+                                 );
+  mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX);
+  memcpy(name2, name, (size_t)len);
+  name2[len] = '=';
+  name2[len+1] = '\0';
+
+  return mrb_intern(s->mrb, name2, len+1);
+}
+
+#define CALL_MAXARGS 127
+
+static int
+gen_values(codegen_scope *s, node *t, int val, int extra)
+{
+  int n = 0;
+  int is_splat;
+
+  while (t) {
+    is_splat = (intptr_t)t->car->car == NODE_SPLAT; /* splat mode */
+    if (
+      n+extra >= CALL_MAXARGS - 1 /* need to subtract one because vm.c expects an array if n == CALL_MAXARGS */
+      || is_splat) {
+      if (val) {
+        if (is_splat && n == 0 && (intptr_t)t->car->cdr->car == NODE_ARRAY) {
+          codegen(s, t->car->cdr, VAL);
+          pop();
+        }
+        else {
+          pop_n(n);
+          genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n));
+          push();
+          codegen(s, t->car, VAL);
+          pop(); pop();
+          if (is_splat) {
+            genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));
+          }
+          else {
+            genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));
+          }
+        }
+        t = t->cdr;
+        while (t) {
+          push();
+          codegen(s, t->car, VAL);
+          pop(); pop();
+          if ((intptr_t)t->car->car == NODE_SPLAT) {
+            genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));
+          }
+          else {
+            genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));
+          }
+          t = t->cdr;
+        }
+      }
+      else {
+        while (t) {
+          codegen(s, t->car, NOVAL);
+          t = t->cdr;
+        }
+      }
+      return -1;
+    }
+    /* normal (no splat) mode */
+    codegen(s, t->car, val);
+    n++;
+    t = t->cdr;
+  }
+  return n;
+}
+
+static void
+gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe)
+{
+  mrb_sym sym = name ? name : sym(tree->cdr->car);
+  int idx, skip = 0;
+  int n = 0, noop = 0, sendv = 0, blk = 0;
+
+  codegen(s, tree->car, VAL); /* receiver */
+  if (safe) {
+    int recv = cursp()-1;
+    genop(s, MKOP_A(OP_LOADNIL, cursp()));
+    push();
+    genop(s, MKOP_AB(OP_MOVE, cursp(), recv));
+    push(); pop();              /* space for a block */
+    pop();
+    idx = new_msym(s, mrb_intern_lit(s->mrb, "=="));
+    genop(s, MKOP_ABC(OP_EQ, cursp(), idx, 1));
+    skip = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), 0));
+  }
+  idx = new_msym(s, sym);
+  tree = tree->cdr->cdr->car;
+  if (tree) {
+    n = gen_values(s, tree->car, VAL, sp?1:0);
+    if (n < 0) {
+      n = noop = sendv = 1;
+      push();
+    }
+  }
+  if (sp) {
+    if (sendv) {
+      pop();
+      genop(s, MKOP_AB(OP_ARYPUSH, cursp(), sp));
+      push();
+    }
+    else {
+      genop(s, MKOP_AB(OP_MOVE, cursp(), sp));
+      push();
+      n++;
+    }
+  }
+  if (tree && tree->cdr) {
+    noop = 1;
+    codegen(s, tree->cdr, VAL);
+    pop();
+  }
+  else {
+    blk = cursp();
+  }
+  push();pop();
+  pop_n(n+1);
+  {
+    mrb_int symlen;
+    const char *symname = mrb_sym2name_len(s->mrb, sym, &symlen);
+
+    if (!noop && symlen == 1 && symname[0] == '+' && n == 1)  {
+      genop_peep(s, MKOP_ABC(OP_ADD, cursp(), idx, n), val);
+    }
+    else if (!noop && symlen == 1 && symname[0] == '-' && n == 1)  {
+      genop_peep(s, MKOP_ABC(OP_SUB, cursp(), idx, n), val);
+    }
+    else if (!noop && symlen == 1 && symname[0] == '*' && n == 1)  {
+      genop(s, MKOP_ABC(OP_MUL, cursp(), idx, n));
+    }
+    else if (!noop && symlen == 1 && symname[0] == '/' && n == 1)  {
+      genop(s, MKOP_ABC(OP_DIV, cursp(), idx, n));
+    }
+    else if (!noop && symlen == 1 && symname[0] == '<' && n == 1)  {
+      genop(s, MKOP_ABC(OP_LT, cursp(), idx, n));
+    }
+    else if (!noop && symlen == 2 && symname[0] == '<' && symname[1] == '=' && n == 1)  {
+      genop(s, MKOP_ABC(OP_LE, cursp(), idx, n));
+    }
+    else if (!noop && symlen == 1 && symname[0] == '>' && n == 1)  {
+      genop(s, MKOP_ABC(OP_GT, cursp(), idx, n));
+    }
+    else if (!noop && symlen == 2 && symname[0] == '>' && symname[1] == '=' && n == 1)  {
+      genop(s, MKOP_ABC(OP_GE, cursp(), idx, n));
+    }
+    else if (!noop && symlen == 2 && symname[0] == '=' && symname[1] == '=' && n == 1)  {
+      genop(s, MKOP_ABC(OP_EQ, cursp(), idx, n));
+    }
+    else {
+      if (sendv) n = CALL_MAXARGS;
+      if (blk > 0) {                   /* no block */
+        genop(s, MKOP_ABC(OP_SEND, cursp(), idx, n));
+      }
+      else {
+        genop(s, MKOP_ABC(OP_SENDB, cursp(), idx, n));
+      }
+    }
+  }
+  if (safe) {
+    dispatch(s, skip);
+  }
+  if (val) {
+    push();
+  }
+}
+
+static void
+gen_assignment(codegen_scope *s, node *tree, int sp, int val)
+{
+  int idx;
+  int type = (intptr_t)tree->car;
+
+  tree = tree->cdr;
+  switch (type) {
+  case NODE_GVAR:
+    idx = new_sym(s, sym(tree));
+    genop_peep(s, MKOP_ABx(OP_SETGLOBAL, sp, idx), val);
+    break;
+  case NODE_LVAR:
+    idx = lv_idx(s, sym(tree));
+    if (idx > 0) {
+      if (idx != sp) {
+        genop_peep(s, MKOP_AB(OP_MOVE, idx, sp), val);
+      }
+      break;
+    }
+    else {                      /* upvar */
+      int lv = 0;
+      codegen_scope *up = s->prev;
+
+      while (up) {
+        idx = lv_idx(up, sym(tree));
+        if (idx > 0) {
+          genop_peep(s, MKOP_ABC(OP_SETUPVAR, sp, idx, lv), val);
+          break;
+        }
+        lv++;
+        up = up->prev;
+      }
+    }
+    break;
+  case NODE_IVAR:
+    idx = new_sym(s, sym(tree));
+    genop_peep(s, MKOP_ABx(OP_SETIV, sp, idx), val);
+    break;
+  case NODE_CVAR:
+    idx = new_sym(s, sym(tree));
+    genop_peep(s, MKOP_ABx(OP_SETCV, sp, idx), val);
+    break;
+  case NODE_CONST:
+    idx = new_sym(s, sym(tree));
+    genop_peep(s, MKOP_ABx(OP_SETCONST, sp, idx), val);
+    break;
+  case NODE_COLON2:
+    idx = new_sym(s, sym(tree->cdr));
+    genop_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), NOVAL);
+    push();
+    codegen(s, tree->car, VAL);
+    pop_n(2);
+    genop_peep(s, MKOP_ABx(OP_SETMCNST, cursp(), idx), val);
+    break;
+
+  case NODE_CALL:
+  case NODE_SCALL:
+    push();
+    gen_call(s, tree, attrsym(s, sym(tree->cdr->car)), sp, NOVAL,
+             type == NODE_SCALL);
+    pop();
+    if (val) {
+      genop_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), val);
+    }
+    break;
+
+  case NODE_MASGN:
+    gen_vmassignment(s, tree->car, sp, val);
+    break;
+
+  /* splat without assignment */
+  case NODE_NIL:
+    break;
+
+  default:
+#ifndef MRB_DISABLE_STDIO
+    fprintf(stderr, "unknown lhs %d\n", type);
+#endif
+    break;
+  }
+  if (val) push();
+}
+
+static void
+gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val)
+{
+  int n = 0, post = 0;
+  node *t, *p;
+
+  if (tree->car) {              /* pre */
+    t = tree->car;
+    n = 0;
+    while (t) {
+      genop(s, MKOP_ABC(OP_AREF, cursp(), rhs, n));
+      gen_assignment(s, t->car, cursp(), NOVAL);
+      n++;
+      t = t->cdr;
+    }
+  }
+  t = tree->cdr;
+  if (t) {
+    if (t->cdr) {               /* post count */
+      p = t->cdr->car;
+      while (p) {
+        post++;
+        p = p->cdr;
+      }
+    }
+    if (val) {
+      genop(s, MKOP_AB(OP_MOVE, cursp(), rhs));
+    }
+    else {
+      pop();
+    }
+    push_n(post);
+    pop_n(post);
+    genop(s, MKOP_ABC(OP_APOST, cursp(), n, post));
+    n = 1;
+    if (t->car) {               /* rest */
+      gen_assignment(s, t->car, cursp(), NOVAL);
+    }
+    if (t->cdr && t->cdr->car) {
+      t = t->cdr->car;
+      while (t) {
+        gen_assignment(s, t->car, cursp()+n, NOVAL);
+        t = t->cdr;
+        n++;
+      }
+    }
+    if (!val) {
+      push();
+    }
+  }
+}
+
+static void
+gen_send_intern(codegen_scope *s)
+{
+  pop();
+  genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "intern")), 0));
+  push();
+}
+static void
+gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val)
+{
+  if (val) {
+    int i = 0, j = 0;
+
+    while (tree) {
+      switch ((intptr_t)tree->car->car) {
+      case NODE_STR:
+        if ((tree->cdr == NULL) && ((intptr_t)tree->car->cdr->cdr == 0))
+          break;
+        /* fall through */
+      case NODE_BEGIN:
+        codegen(s, tree->car, VAL);
+        ++j;
+        break;
+
+      case NODE_LITERAL_DELIM:
+        if (j > 0) {
+          j = 0;
+          ++i;
+          if (sym)
+            gen_send_intern(s);
+        }
+        break;
+      }
+      if (j >= 2) {
+        pop(); pop();
+        genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
+        push();
+        j = 1;
+      }
+      tree = tree->cdr;
+    }
+    if (j > 0) {
+      ++i;
+      if (sym)
+        gen_send_intern(s);
+    }
+    pop_n(i);
+    genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), i));
+    push();
+  }
+  else {
+    while (tree) {
+      switch ((intptr_t)tree->car->car) {
+      case NODE_BEGIN: case NODE_BLOCK:
+        codegen(s, tree->car, NOVAL);
+      }
+      tree = tree->cdr;
+    }
+  }
+}
+
+static void
+raise_error(codegen_scope *s, const char *msg)
+{
+  int idx = new_lit(s, mrb_str_new_cstr(s->mrb, msg));
+
+  genop(s, MKOP_ABx(OP_ERR, 1, idx));
+}
+
+static double
+readint_float(codegen_scope *s, const char *p, int base)
+{
+  const char *e = p + strlen(p);
+  double f = 0;
+  int n;
+
+  if (*p == '+') p++;
+  while (p < e) {
+    char c = *p;
+    c = tolower((unsigned char)c);
+    for (n=0; n<base; n++) {
+      if (mrb_digitmap[n] == c) {
+        f *= base;
+        f += n;
+        break;
+      }
+    }
+    if (n == base) {
+      codegen_error(s, "malformed readint input");
+    }
+    p++;
+  }
+  return f;
+}
+
+static mrb_int
+readint_mrb_int(codegen_scope *s, const char *p, int base, mrb_bool neg, mrb_bool *overflow)
+{
+  const char *e = p + strlen(p);
+  mrb_int result = 0;
+  int n;
+
+  mrb_assert(base >= 2 && base <= 36);
+  if (*p == '+') p++;
+  while (p < e) {
+    char c = *p;
+    c = tolower((unsigned char)c);
+    for (n=0; n<base; n++) {
+      if (mrb_digitmap[n] == c) {
+        break;
+      }
+    }
+    if (n == base) {
+      codegen_error(s, "malformed readint input");
+    }
+
+    if (neg) {
+      if ((MRB_INT_MIN + n)/base > result) {
+        *overflow = TRUE;
+        return 0;
+      }
+      result *= base;
+      result -= n;
+    }
+    else {
+      if ((MRB_INT_MAX - n)/base < result) {
+        *overflow = TRUE;
+        return 0;
+      }
+      result *= base;
+      result += n;
+    }
+    p++;
+  }
+  *overflow = FALSE;
+  return result;
+}
+
+static void
+gen_retval(codegen_scope *s, node *tree)
+{
+  if ((intptr_t)tree->car == NODE_SPLAT) {
+    genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), 0));
+    push();
+    codegen(s, tree, VAL);
+    pop(); pop();
+    genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));
+  }
+  else {
+    codegen(s, tree, VAL);
+    pop();
+  }
+}
+
+static void
+codegen(codegen_scope *s, node *tree, int val)
+{
+  int nt;
+  int rlev = s->rlev;
+
+  if (!tree) {
+    if (val) {
+      genop(s, MKOP_A(OP_LOADNIL, cursp()));
+      push();
+    }
+    return;
+  }
+
+  s->rlev++;
+  if (s->rlev > MRB_CODEGEN_LEVEL_MAX) {
+    codegen_error(s, "too complex expression");
+  }
+  if (s->irep && s->filename_index != tree->filename_index) {
+    s->irep->filename = mrb_parser_get_filename(s->parser, s->filename_index);
+    mrb_debug_info_append_file(s->mrb, s->irep, s->debug_start_pos, s->pc);
+    s->debug_start_pos = s->pc;
+    s->filename_index = tree->filename_index;
+    s->filename = mrb_parser_get_filename(s->parser, tree->filename_index);
+  }
+
+  nt = (intptr_t)tree->car;
+  s->lineno = tree->lineno;
+  tree = tree->cdr;
+  switch (nt) {
+  case NODE_BEGIN:
+    if (val && !tree) {
+      genop(s, MKOP_A(OP_LOADNIL, cursp()));
+      push();
+    }
+    while (tree) {
+      codegen(s, tree->car, tree->cdr ? NOVAL : val);
+      tree = tree->cdr;
+    }
+    break;
+
+  case NODE_RESCUE:
+    {
+      int onerr, noexc, exend, pos1, pos2, tmp;
+      struct loopinfo *lp;
+
+      if (tree->car == NULL) goto exit;
+      onerr = genop(s, MKOP_Bx(OP_ONERR, 0));
+      lp = loop_push(s, LOOP_BEGIN);
+      lp->pc1 = onerr;
+      codegen(s, tree->car, VAL);
+      pop();
+      lp->type = LOOP_RESCUE;
+      noexc = genop(s, MKOP_Bx(OP_JMP, 0));
+      dispatch(s, onerr);
+      tree = tree->cdr;
+      exend = 0;
+      pos1 = 0;
+      if (tree->car) {
+        node *n2 = tree->car;
+        int exc = cursp();
+
+        genop(s, MKOP_ABC(OP_RESCUE, exc, 0, 0));
+        push();
+        while (n2) {
+          node *n3 = n2->car;
+          node *n4 = n3->car;
+
+          if (pos1) dispatch(s, pos1);
+          pos2 = 0;
+          do {
+            if (n4 && n4->car && (intptr_t)n4->car->car == NODE_SPLAT) {
+              codegen(s, n4->car, VAL);
+              genop(s, MKOP_AB(OP_MOVE, cursp(), exc));
+              pop();
+              genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1));
+            }
+            else {
+              if (n4) {
+                codegen(s, n4->car, VAL);
+              }
+              else {
+                genop(s, MKOP_ABx(OP_GETCONST, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "StandardError"))));
+                push();
+              }
+              pop();
+              genop(s, MKOP_ABC(OP_RESCUE, exc, cursp(), 1));
+            }
+            tmp = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));
+            pos2 = tmp;
+            if (n4) {
+              n4 = n4->cdr;
+            }
+          } while (n4);
+          pos1 = genop(s, MKOP_sBx(OP_JMP, 0));
+          dispatch_linked(s, pos2);
+
+          pop();
+          if (n3->cdr->car) {
+            gen_assignment(s, n3->cdr->car, exc, NOVAL);
+          }
+          if (n3->cdr->cdr->car) {
+            codegen(s, n3->cdr->cdr->car, val);
+            if (val) pop();
+          }
+          tmp = genop(s, MKOP_sBx(OP_JMP, exend));
+          exend = tmp;
+          n2 = n2->cdr;
+          push();
+        }
+        if (pos1) {
+          dispatch(s, pos1);
+          genop(s, MKOP_A(OP_RAISE, exc));
+        }
+      }
+      pop();
+      tree = tree->cdr;
+      dispatch(s, noexc);
+      genop(s, MKOP_A(OP_POPERR, 1));
+      if (tree->car) {
+        codegen(s, tree->car, val);
+      }
+      else if (val) {
+        push();
+      }
+      dispatch_linked(s, exend);
+      loop_pop(s, NOVAL);
+    }
+    break;
+
+  case NODE_ENSURE:
+    if (!tree->cdr || !tree->cdr->cdr ||
+        ((intptr_t)tree->cdr->cdr->car == NODE_BEGIN &&
+         tree->cdr->cdr->cdr)) {
+      int idx;
+      int epush = s->pc;
+
+      genop(s, MKOP_Bx(OP_EPUSH, 0));
+      s->ensure_level++;
+      codegen(s, tree->car, val);
+      idx = scope_body(s, tree->cdr, NOVAL);
+      s->iseq[epush] = MKOP_Bx(OP_EPUSH, idx);
+      s->ensure_level--;
+      genop_peep(s, MKOP_A(OP_EPOP, 1), NOVAL);
+    }
+    else {                      /* empty ensure ignored */
+      codegen(s, tree->car, val);
+    }
+    break;
+
+  case NODE_LAMBDA:
+    if (val) {
+      int idx = lambda_body(s, tree, 1);
+
+      genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_LAMBDA));
+      push();
+    }
+    break;
+
+  case NODE_BLOCK:
+    if (val) {
+      int idx = lambda_body(s, tree, 1);
+
+      genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_BLOCK));
+      push();
+    }
+    break;
+
+  case NODE_IF:
+    {
+      int pos1, pos2;
+      node *e = tree->cdr->cdr->car;
+
+      if (!tree->car) {
+        codegen(s, e, val);
+        goto exit;
+      }
+      switch ((intptr_t)tree->car->car) {
+      case NODE_TRUE:
+      case NODE_INT:
+      case NODE_STR:
+        codegen(s, tree->cdr->car, val);
+        goto exit;
+      case NODE_FALSE:
+      case NODE_NIL:
+        codegen(s, e, val);
+        goto exit;
+      }
+      codegen(s, tree->car, VAL);
+      pop();
+      pos1 = genop_peep(s, MKOP_AsBx(OP_JMPNOT, cursp(), 0), NOVAL);
+
+      codegen(s, tree->cdr->car, val);
+      if (e) {
+        if (val) pop();
+        pos2 = genop(s, MKOP_sBx(OP_JMP, 0));
+        dispatch(s, pos1);
+        codegen(s, e, val);
+        dispatch(s, pos2);
+      }
+      else {
+        if (val) {
+          pop();
+          pos2 = genop(s, MKOP_sBx(OP_JMP, 0));
+          dispatch(s, pos1);
+          genop(s, MKOP_A(OP_LOADNIL, cursp()));
+          dispatch(s, pos2);
+          push();
+        }
+        else {
+          dispatch(s, pos1);
+        }
+      }
+    }
+    break;
+
+  case NODE_AND:
+    {
+      int pos;
+
+      codegen(s, tree->car, VAL);
+      pop();
+      pos = genop(s, MKOP_AsBx(OP_JMPNOT, cursp(), 0));
+      codegen(s, tree->cdr, val);
+      dispatch(s, pos);
+    }
+    break;
+
+  case NODE_OR:
+    {
+      int pos;
+
+      codegen(s, tree->car, VAL);
+      pop();
+      pos = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), 0));
+      codegen(s, tree->cdr, val);
+      dispatch(s, pos);
+    }
+    break;
+
+  case NODE_WHILE:
+    {
+      struct loopinfo *lp = loop_push(s, LOOP_NORMAL);
+
+      lp->pc1 = genop(s, MKOP_sBx(OP_JMP, 0));
+      lp->pc2 = new_label(s);
+      codegen(s, tree->cdr, NOVAL);
+      dispatch(s, lp->pc1);
+      codegen(s, tree->car, VAL);
+      pop();
+      genop(s, MKOP_AsBx(OP_JMPIF, cursp(), lp->pc2 - s->pc));
+
+      loop_pop(s, val);
+    }
+    break;
+
+  case NODE_UNTIL:
+    {
+      struct loopinfo *lp = loop_push(s, LOOP_NORMAL);
+
+      lp->pc1 = genop(s, MKOP_sBx(OP_JMP, 0));
+      lp->pc2 = new_label(s);
+      codegen(s, tree->cdr, NOVAL);
+      dispatch(s, lp->pc1);
+      codegen(s, tree->car, VAL);
+      pop();
+      genop(s, MKOP_AsBx(OP_JMPNOT, cursp(), lp->pc2 - s->pc));
+
+      loop_pop(s, val);
+    }
+    break;
+
+  case NODE_FOR:
+    for_body(s, tree);
+    if (val) push();
+    break;
+
+  case NODE_CASE:
+    {
+      int head = 0;
+      int pos1, pos2, pos3, tmp;
+      node *n;
+
+      pos3 = 0;
+      if (tree->car) {
+        head = cursp();
+        codegen(s, tree->car, VAL);
+      }
+      tree = tree->cdr;
+      while (tree) {
+        n = tree->car->car;
+        pos1 = pos2 = 0;
+        while (n) {
+          codegen(s, n->car, VAL);
+          if (head) {
+            genop(s, MKOP_AB(OP_MOVE, cursp(), head));
+            pop();
+            if ((intptr_t)n->car->car == NODE_SPLAT) {
+              genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1));
+            }
+            else {
+              genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "===")), 1));
+            }
+          }
+          else {
+            pop();
+          }
+          tmp = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));
+          pos2 = tmp;
+          n = n->cdr;
+        }
+        if (tree->car->car) {
+          pos1 = genop(s, MKOP_sBx(OP_JMP, 0));
+          dispatch_linked(s, pos2);
+        }
+        codegen(s, tree->car->cdr, val);
+        if (val) pop();
+        tmp = genop(s, MKOP_sBx(OP_JMP, pos3));
+        pos3 = tmp;
+        if (pos1) dispatch(s, pos1);
+        tree = tree->cdr;
+      }
+      if (val) {
+        int pos = cursp();
+        genop(s, MKOP_A(OP_LOADNIL, cursp()));
+        if (pos3) dispatch_linked(s, pos3);
+        if (head) pop();
+        if (cursp() != pos) {
+          genop(s, MKOP_AB(OP_MOVE, cursp(), pos));
+        }
+        push();
+      }
+      else {
+        if (pos3) {
+          dispatch_linked(s, pos3);
+        }
+        if (head) {
+          pop();
+        }
+      }
+    }
+    break;
+
+  case NODE_SCOPE:
+    scope_body(s, tree, NOVAL);
+    break;
+
+  case NODE_FCALL:
+  case NODE_CALL:
+    gen_call(s, tree, 0, 0, val, 0);
+    break;
+  case NODE_SCALL:
+    gen_call(s, tree, 0, 0, val, 1);
+    break;
+
+  case NODE_DOT2:
+    codegen(s, tree->car, val);
+    codegen(s, tree->cdr, val);
+    if (val) {
+      pop(); pop();
+      genop(s, MKOP_ABC(OP_RANGE, cursp(), cursp(), FALSE));
+      push();
+    }
+    break;
+
+  case NODE_DOT3:
+    codegen(s, tree->car, val);
+    codegen(s, tree->cdr, val);
+    if (val) {
+      pop(); pop();
+      genop(s, MKOP_ABC(OP_RANGE, cursp(), cursp(), TRUE));
+      push();
+    }
+    break;
+
+  case NODE_COLON2:
+    {
+      int sym = new_sym(s, sym(tree->cdr));
+
+      codegen(s, tree->car, VAL);
+      pop();
+      genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
+      if (val) push();
+    }
+    break;
+
+  case NODE_COLON3:
+    {
+      int sym = new_sym(s, sym(tree));
+
+      genop(s, MKOP_A(OP_OCLASS, cursp()));
+      genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
+      if (val) push();
+    }
+    break;
+
+  case NODE_ARRAY:
+    {
+      int n;
+
+      n = gen_values(s, tree, val, 0);
+      if (n >= 0) {
+        if (val) {
+          pop_n(n);
+          genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n));
+          push();
+        }
+      }
+      else if (val) {
+        push();
+      }
+    }
+    break;
+
+  case NODE_HASH:
+    {
+      int len = 0;
+      mrb_bool update = FALSE;
+
+      while (tree) {
+        codegen(s, tree->car->car, val);
+        codegen(s, tree->car->cdr, val);
+        len++;
+        tree = tree->cdr;
+        if (val && len == 126) {
+          pop_n(len*2);
+          genop(s, MKOP_ABC(OP_HASH, cursp(), cursp(), len));
+          if (update) {
+            pop();
+            genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__update")), 1));
+          }
+          push();
+          update = TRUE;
+          len = 0;
+        }
+      }
+      if (val) {
+        pop_n(len*2);
+        genop(s, MKOP_ABC(OP_HASH, cursp(), cursp(), len));
+        if (update) {
+          pop();
+          genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__update")), 1));
+        }
+        push();
+      }
+    }
+    break;
+
+  case NODE_SPLAT:
+    codegen(s, tree, val);
+    break;
+
+  case NODE_ASGN:
+    codegen(s, tree->cdr, VAL);
+    pop();
+    gen_assignment(s, tree->car, cursp(), val);
+    break;
+
+  case NODE_MASGN:
+    {
+      int len = 0, n = 0, post = 0;
+      node *t = tree->cdr, *p;
+      int rhs = cursp();
+
+      if ((intptr_t)t->car == NODE_ARRAY && t->cdr && nosplat(t->cdr)) {
+        /* fixed rhs */
+        t = t->cdr;
+        while (t) {
+          codegen(s, t->car, VAL);
+          len++;
+          t = t->cdr;
+        }
+        tree = tree->car;
+        if (tree->car) {                /* pre */
+          t = tree->car;
+          n = 0;
+          while (t) {
+            if (n < len) {
+              gen_assignment(s, t->car, rhs+n, NOVAL);
+              n++;
+            }
+            else {
+              genop(s, MKOP_A(OP_LOADNIL, rhs+n));
+              gen_assignment(s, t->car, rhs+n, NOVAL);
+            }
+            t = t->cdr;
+          }
+        }
+        t = tree->cdr;
+        if (t) {
+          if (t->cdr) {         /* post count */
+            p = t->cdr->car;
+            while (p) {
+              post++;
+              p = p->cdr;
+            }
+          }
+          if (t->car) {         /* rest (len - pre - post) */
+            int rn;
+
+            if (len < post + n) {
+              rn = 0;
+            }
+            else {
+              rn = len - post - n;
+            }
+            genop(s, MKOP_ABC(OP_ARRAY, cursp(), rhs+n, rn));
+            gen_assignment(s, t->car, cursp(), NOVAL);
+            n += rn;
+          }
+          if (t->cdr && t->cdr->car) {
+            t = t->cdr->car;
+            while (n<len) {
+              gen_assignment(s, t->car, rhs+n, NOVAL);
+              t = t->cdr;
+              n++;
+            }
+          }
+        }
+        pop_n(len);
+        if (val) {
+          genop(s, MKOP_ABC(OP_ARRAY, rhs, rhs, len));
+          push();
+        }
+      }
+      else {
+        /* variable rhs */
+        codegen(s, t, VAL);
+        gen_vmassignment(s, tree->car, rhs, val);
+        if (!val) {
+          pop();
+        }
+      }
+    }
+    break;
+
+  case NODE_OP_ASGN:
+    {
+      mrb_sym sym = sym(tree->cdr->car);
+      mrb_int len;
+      const char *name = mrb_sym2name_len(s->mrb, sym, &len);
+      int idx, callargs = -1, vsp = -1;
+
+      if ((len == 2 && name[0] == '|' && name[1] == '|') &&
+          ((intptr_t)tree->car->car == NODE_CONST ||
+           (intptr_t)tree->car->car == NODE_CVAR)) {
+        int onerr, noexc, exc;
+        struct loopinfo *lp;
+
+        onerr = genop(s, MKOP_Bx(OP_ONERR, 0));
+        lp = loop_push(s, LOOP_BEGIN);
+        lp->pc1 = onerr;
+        exc = cursp();
+        codegen(s, tree->car, VAL);
+        lp->type = LOOP_RESCUE;
+        genop(s, MKOP_A(OP_POPERR, 1));
+        noexc = genop(s, MKOP_Bx(OP_JMP, 0));
+        dispatch(s, onerr);
+        genop(s, MKOP_ABC(OP_RESCUE, exc, 0, 0));
+        genop(s, MKOP_A(OP_LOADF, exc));
+        dispatch(s, noexc);
+        loop_pop(s, NOVAL);
+      }
+      else if ((intptr_t)tree->car->car == NODE_CALL) {
+        node *n = tree->car->cdr;
+
+        if (val) {
+          vsp = cursp();
+          push();
+        }
+        codegen(s, n->car, VAL);   /* receiver */
+        idx = new_msym(s, sym(n->cdr->car));
+        if (n->cdr->cdr->car) {
+          int base = cursp()-1;
+          int nargs = gen_values(s, n->cdr->cdr->car->car, VAL, 1);
+
+          /* copy receiver and arguments */
+          if (nargs >= 0) {
+            int i;
+
+            genop(s, MKOP_AB(OP_MOVE, cursp(), base));
+            for (i=0; i<nargs; i++) {
+              genop(s, MKOP_AB(OP_MOVE, cursp()+i+1, base+i+1));
+            }
+            push_n(nargs+1);
+            pop_n(nargs+1);
+            callargs = nargs;
+          }
+          else {
+            /* varargs */
+            push();
+            genop(s, MKOP_AB(OP_MOVE, cursp(), base));
+            genop(s, MKOP_AB(OP_MOVE, cursp()+1, base+1));
+            callargs = CALL_MAXARGS;
+          }
+          genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs));
+        }
+        else {
+          genop(s, MKOP_AB(OP_MOVE, cursp(), cursp()-1));
+          genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 0));
+          callargs = 0;
+        }
+        push();
+      }
+      else {
+        codegen(s, tree->car, VAL);
+      }
+      if (len == 2 &&
+          ((name[0] == '|' && name[1] == '|') ||
+           (name[0] == '&' && name[1] == '&'))) {
+        int pos;
+
+        pop();
+        if (val) {
+          if (vsp >= 0) {
+            genop(s, MKOP_AB(OP_MOVE, vsp, cursp()));
+          }
+          pos = genop(s, MKOP_AsBx(name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0));
+        }
+        else {
+          pos = genop_peep(s, MKOP_AsBx(name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0), NOVAL);
+        }
+        codegen(s, tree->cdr->cdr->car, VAL);
+        pop();
+        if (val && vsp >= 0) {
+          genop(s, MKOP_AB(OP_MOVE, vsp, cursp()));
+        }
+        if ((intptr_t)tree->car->car == NODE_CALL) {
+          mrb_sym m = sym(tree->car->cdr->cdr->car);
+          mrb_sym m2 = attrsym(s, m);
+
+          idx = new_msym(s, m2);
+          pop();
+          if (callargs == CALL_MAXARGS) {
+            genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));
+            pop();
+            genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs));
+          }
+          else {
+            pop_n(callargs);
+            genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs+1));
+          }
+        }
+        else {
+          gen_assignment(s, tree->car, cursp(), val);
+        }
+        dispatch(s, pos);
+        goto exit;
+      }
+      codegen(s, tree->cdr->cdr->car, VAL);
+      push(); pop();
+      pop(); pop();
+
+      idx = new_msym(s, sym);
+      if (len == 1 && name[0] == '+')  {
+        genop_peep(s, MKOP_ABC(OP_ADD, cursp(), idx, 1), val);
+      }
+      else if (len == 1 && name[0] == '-')  {
+        genop_peep(s, MKOP_ABC(OP_SUB, cursp(), idx, 1), val);
+      }
+      else if (len == 1 && name[0] == '*')  {
+        genop(s, MKOP_ABC(OP_MUL, cursp(), idx, 1));
+      }
+      else if (len == 1 && name[0] == '/')  {
+        genop(s, MKOP_ABC(OP_DIV, cursp(), idx, 1));
+      }
+      else if (len == 1 && name[0] == '<')  {
+        genop(s, MKOP_ABC(OP_LT, cursp(), idx, 1));
+      }
+      else if (len == 2 && name[0] == '<' && name[1] == '=')  {
+        genop(s, MKOP_ABC(OP_LE, cursp(), idx, 1));
+      }
+      else if (len == 1 && name[0] == '>')  {
+        genop(s, MKOP_ABC(OP_GT, cursp(), idx, 1));
+      }
+      else if (len == 2 && name[0] == '>' && name[1] == '=')  {
+        genop(s, MKOP_ABC(OP_GE, cursp(), idx, 1));
+      }
+      else {
+        genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 1));
+      }
+      if (callargs < 0) {
+        gen_assignment(s, tree->car, cursp(), val);
+      }
+      else {
+        if (val && vsp >= 0) {
+          genop(s, MKOP_AB(OP_MOVE, vsp, cursp()));
+        }
+        if (callargs == CALL_MAXARGS) {
+          pop();
+          genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));
+        }
+        else {
+          pop_n(callargs);
+          callargs++;
+        }
+        pop();
+        idx = new_msym(s, attrsym(s,sym(tree->car->cdr->cdr->car)));
+        genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs));
+      }
+    }
+    break;
+
+  case NODE_SUPER:
+    {
+      codegen_scope *s2 = s;
+      int lv = 0;
+      int n = 0, noop = 0, sendv = 0;
+
+      push();        /* room for receiver */
+      while (!s2->mscope) {
+        lv++;
+        s2 = s2->prev;
+        if (!s2) break;
+      }
+      genop(s, MKOP_ABx(OP_ARGARY, cursp(), (lv & 0xf)));
+      push(); push();         /* ARGARY pushes two values */
+      pop(); pop();
+      if (tree) {
+        node *args = tree->car;
+        if (args) {
+          n = gen_values(s, args, VAL, 0);
+          if (n < 0) {
+            n = noop = sendv = 1;
+            push();
+          }
+        }
+      }
+      if (tree && tree->cdr) {
+        codegen(s, tree->cdr, VAL);
+        pop();
+      }
+      else {
+        genop(s, MKOP_A(OP_LOADNIL, cursp()));
+        push(); pop();
+      }
+      pop_n(n+1);
+      if (sendv) n = CALL_MAXARGS;
+      genop(s, MKOP_ABC(OP_SUPER, cursp(), 0, n));
+      if (val) push();
+    }
+    break;
+
+  case NODE_ZSUPER:
+    {
+      codegen_scope *s2 = s;
+      int lv = 0, ainfo = 0;
+
+      push();        /* room for receiver */
+      while (!s2->mscope) {
+        lv++;
+        s2 = s2->prev;
+        if (!s2) break;
+      }
+      if (s2) ainfo = s2->ainfo;
+      genop(s, MKOP_ABx(OP_ARGARY, cursp(), (ainfo<<4)|(lv & 0xf)));
+      push(); push(); pop();    /* ARGARY pushes two values */
+      if (tree && tree->cdr) {
+        codegen(s, tree->cdr, VAL);
+        pop();
+      }
+      pop(); pop();
+      genop(s, MKOP_ABC(OP_SUPER, cursp(), 0, CALL_MAXARGS));
+      if (val) push();
+    }
+    break;
+
+  case NODE_RETURN:
+    if (tree) {
+      gen_retval(s, tree);
+    }
+    else {
+      genop(s, MKOP_A(OP_LOADNIL, cursp()));
+    }
+    if (s->loop) {
+      genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_RETURN));
+    }
+    else {
+      genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
+    }
+    if (val) push();
+    break;
+
+  case NODE_YIELD:
+    {
+      codegen_scope *s2 = s;
+      int lv = 0, ainfo = 0;
+      int n = 0, sendv = 0;
+
+      while (!s2->mscope) {
+        lv++;
+        s2 = s2->prev;
+        if (!s2) break;
+      }
+      if (s2) ainfo = s2->ainfo;
+      push();
+      if (tree) {
+        n = gen_values(s, tree, VAL, 0);
+        if (n < 0) {
+          n = sendv = 1;
+          push();
+        }
+      }
+      pop_n(n+1);
+      genop(s, MKOP_ABx(OP_BLKPUSH, cursp(), (ainfo<<4)|(lv & 0xf)));
+      if (sendv) n = CALL_MAXARGS;
+      genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "call")), n));
+      if (val) push();
+    }
+    break;
+
+  case NODE_BREAK:
+    loop_break(s, tree);
+    if (val) push();
+    break;
+
+  case NODE_NEXT:
+    if (!s->loop) {
+      raise_error(s, "unexpected next");
+    }
+    else if (s->loop->type == LOOP_NORMAL) {
+      if (s->ensure_level > s->loop->ensure_level) {
+        genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL);
+      }
+      codegen(s, tree, NOVAL);
+      genop(s, MKOP_sBx(OP_JMP, s->loop->pc1 - s->pc));
+    }
+    else {
+      if (tree) {
+        codegen(s, tree, VAL);
+        pop();
+      }
+      else {
+        genop(s, MKOP_A(OP_LOADNIL, cursp()));
+      }
+      genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
+    }
+    if (val) push();
+    break;
+
+  case NODE_REDO:
+    if (!s->loop || s->loop->type == LOOP_BEGIN || s->loop->type == LOOP_RESCUE) {
+      raise_error(s, "unexpected redo");
+    }
+    else {
+      if (s->ensure_level > s->loop->ensure_level) {
+        genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL);
+      }
+      genop(s, MKOP_sBx(OP_JMP, s->loop->pc2 - s->pc));
+    }
+    if (val) push();
+    break;
+
+  case NODE_RETRY:
+    {
+      const char *msg = "unexpected retry";
+
+      if (!s->loop) {
+        raise_error(s, msg);
+      }
+      else {
+        struct loopinfo *lp = s->loop;
+        int n = 0;
+
+        while (lp && lp->type != LOOP_RESCUE) {
+          if (lp->type == LOOP_BEGIN) {
+            n++;
+          }
+          lp = lp->prev;
+        }
+        if (!lp) {
+          raise_error(s, msg);
+        }
+        else {
+          if (n > 0) {
+            while (n--) {
+              genop_peep(s, MKOP_A(OP_POPERR, 1), NOVAL);
+            }
+          }
+          if (s->ensure_level > lp->ensure_level) {
+            genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - lp->ensure_level), NOVAL);
+          }
+          genop(s, MKOP_sBx(OP_JMP, lp->pc1 - s->pc));
+        }
+      }
+      if (val) push();
+    }
+    break;
+
+  case NODE_LVAR:
+    if (val) {
+      int idx = lv_idx(s, sym(tree));
+
+      if (idx > 0) {
+        genop_peep(s, MKOP_AB(OP_MOVE, cursp(), idx), NOVAL);
+      }
+      else {
+        int lv = 0;
+        codegen_scope *up = s->prev;
+
+        while (up) {
+          idx = lv_idx(up, sym(tree));
+          if (idx > 0) {
+            genop(s, MKOP_ABC(OP_GETUPVAR, cursp(), idx, lv));
+            break;
+          }
+          lv++;
+          up = up->prev;
+        }
+      }
+      push();
+    }
+    break;
+
+  case NODE_GVAR:
+    if (val) {
+      int sym = new_sym(s, sym(tree));
+
+      genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));
+      push();
+    }
+    break;
+
+  case NODE_IVAR:
+    if (val) {
+      int sym = new_sym(s, sym(tree));
+
+      genop(s, MKOP_ABx(OP_GETIV, cursp(), sym));
+      push();
+    }
+    break;
+
+  case NODE_CVAR:
+    if (val) {
+      int sym = new_sym(s, sym(tree));
+
+      genop(s, MKOP_ABx(OP_GETCV, cursp(), sym));
+      push();
+    }
+    break;
+
+  case NODE_CONST:
+    {
+      int sym = new_sym(s, sym(tree));
+
+      genop(s, MKOP_ABx(OP_GETCONST, cursp(), sym));
+      if (val) {
+        push();
+      }
+    }
+    break;
+
+  case NODE_DEFINED:
+    codegen(s, tree, VAL);
+    break;
+
+  case NODE_BACK_REF:
+    if (val) {
+      char buf[3];
+      int sym;
+
+      buf[0] = '$';
+      buf[1] = (char)(intptr_t)tree;
+      buf[2] = 0;
+      sym = new_sym(s, mrb_intern_cstr(s->mrb, buf));
+      genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));
+      push();
+    }
+    break;
+
+  case NODE_NTH_REF:
+    if (val) {
+      mrb_state *mrb = s->mrb;
+      mrb_value str;
+      int sym;
+
+      str = mrb_format(mrb, "$%S", mrb_fixnum_value((mrb_int)(intptr_t)tree));
+      sym = new_sym(s, mrb_intern_str(mrb, str));
+      genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));
+      push();
+    }
+    break;
+
+  case NODE_ARG:
+    /* should not happen */
+    break;
+
+  case NODE_BLOCK_ARG:
+    codegen(s, tree, VAL);
+    break;
+
+  case NODE_INT:
+    if (val) {
+      char *p = (char*)tree->car;
+      int base = (intptr_t)tree->cdr->car;
+      mrb_int i;
+      mrb_code co;
+      mrb_bool overflow;
+
+      i = readint_mrb_int(s, p, base, FALSE, &overflow);
+      if (overflow) {
+        double f = readint_float(s, p, base);
+        int off = new_lit(s, mrb_float_value(s->mrb, f));
+
+        genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
+      }
+      else {
+        if (i < MAXARG_sBx && i > -MAXARG_sBx) {
+          co = MKOP_AsBx(OP_LOADI, cursp(), i);
+        }
+        else {
+          int off = new_lit(s, mrb_fixnum_value(i));
+          co = MKOP_ABx(OP_LOADL, cursp(), off);
+        }
+        genop(s, co);
+      }
+      push();
+    }
+    break;
+
+  case NODE_FLOAT:
+    if (val) {
+      char *p = (char*)tree;
+      mrb_float f = mrb_float_read(p, NULL);
+      int off = new_lit(s, mrb_float_value(s->mrb, f));
+
+      genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
+      push();
+    }
+    break;
+
+  case NODE_NEGATE:
+    {
+      nt = (intptr_t)tree->car;
+      tree = tree->cdr;
+      switch (nt) {
+      case NODE_FLOAT:
+        if (val) {
+          char *p = (char*)tree;
+          mrb_float f = mrb_float_read(p, NULL);
+          int off = new_lit(s, mrb_float_value(s->mrb, -f));
+
+          genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
+          push();
+        }
+        break;
+
+      case NODE_INT:
+        if (val) {
+          char *p = (char*)tree->car;
+          int base = (intptr_t)tree->cdr->car;
+          mrb_int i;
+          mrb_code co;
+          mrb_bool overflow;
+
+          i = readint_mrb_int(s, p, base, TRUE, &overflow);
+          if (overflow) {
+            double f = readint_float(s, p, base);
+            int off = new_lit(s, mrb_float_value(s->mrb, -f));
+
+            genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
+          }
+          else {
+            if (i < MAXARG_sBx && i > -MAXARG_sBx) {
+              co = MKOP_AsBx(OP_LOADI, cursp(), i);
+            }
+            else {
+              int off = new_lit(s, mrb_fixnum_value(i));
+              co = MKOP_ABx(OP_LOADL, cursp(), off);
+            }
+            genop(s, co);
+          }
+          push();
+        }
+        break;
+
+      default:
+        if (val) {
+          int sym = new_msym(s, mrb_intern_lit(s->mrb, "-"));
+
+          genop(s, MKOP_ABx(OP_LOADI, cursp(), 0));
+          push();
+          codegen(s, tree, VAL);
+          pop(); pop();
+          genop(s, MKOP_ABC(OP_SUB, cursp(), sym, 2));
+        }
+        else {
+          codegen(s, tree, NOVAL);
+        }
+        break;
+      }
+    }
+    break;
+
+  case NODE_STR:
+    if (val) {
+      char *p = (char*)tree->car;
+      size_t len = (intptr_t)tree->cdr;
+      int ai = mrb_gc_arena_save(s->mrb);
+      int off = new_lit(s, mrb_str_new(s->mrb, p, len));
+
+      mrb_gc_arena_restore(s->mrb, ai);
+      genop(s, MKOP_ABx(OP_STRING, cursp(), off));
+      push();
+    }
+    break;
+
+  case NODE_HEREDOC:
+    tree = ((struct mrb_parser_heredoc_info *)tree)->doc;
+    /* fall through */
+  case NODE_DSTR:
+    if (val) {
+      node *n = tree;
+
+      if (!n) {
+        genop(s, MKOP_A(OP_LOADNIL, cursp()));
+        push();
+        break;
+      }
+      codegen(s, n->car, VAL);
+      n = n->cdr;
+      while (n) {
+        codegen(s, n->car, VAL);
+        pop(); pop();
+        genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
+        push();
+        n = n->cdr;
+      }
+    }
+    else {
+      node *n = tree;
+
+      while (n) {
+        if ((intptr_t)n->car->car != NODE_STR) {
+          codegen(s, n->car, NOVAL);
+        }
+        n = n->cdr;
+      }
+    }
+    break;
+
+  case NODE_WORDS:
+    gen_literal_array(s, tree, FALSE, val);
+    break;
+
+  case NODE_SYMBOLS:
+    gen_literal_array(s, tree, TRUE, val);
+    break;
+
+  case NODE_DXSTR:
+    {
+      node *n;
+      int ai = mrb_gc_arena_save(s->mrb);
+      int sym = new_sym(s, mrb_intern_lit(s->mrb, "Kernel"));
+
+      genop(s, MKOP_A(OP_LOADSELF, cursp()));
+      push();
+      codegen(s, tree->car, VAL);
+      n = tree->cdr;
+      while (n) {
+        if ((intptr_t)n->car->car == NODE_XSTR) {
+          n->car->car = (struct mrb_ast_node*)(intptr_t)NODE_STR;
+          mrb_assert(!n->cdr); /* must be the end */
+        }
+        codegen(s, n->car, VAL);
+        pop(); pop();
+        genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
+        push();
+        n = n->cdr;
+      }
+      push();                   /* for block */
+      pop_n(3);
+      sym = new_sym(s, mrb_intern_lit(s->mrb, "`"));
+      genop(s, MKOP_ABC(OP_SEND, cursp(), sym, 1));
+      if (val) push();
+      mrb_gc_arena_restore(s->mrb, ai);
+    }
+    break;
+
+  case NODE_XSTR:
+    {
+      char *p = (char*)tree->car;
+      size_t len = (intptr_t)tree->cdr;
+      int ai = mrb_gc_arena_save(s->mrb);
+      int off = new_lit(s, mrb_str_new(s->mrb, p, len));
+      int sym;
+
+      genop(s, MKOP_A(OP_LOADSELF, cursp()));
+      push();
+      genop(s, MKOP_ABx(OP_STRING, cursp(), off));
+      push(); push();
+      pop_n(3);
+      sym = new_sym(s, mrb_intern_lit(s->mrb, "`"));
+      genop(s, MKOP_ABC(OP_SEND, cursp(), sym, 1));
+      if (val) push();
+      mrb_gc_arena_restore(s->mrb, ai);
+    }
+    break;
+
+  case NODE_REGX:
+    if (val) {
+      char *p1 = (char*)tree->car;
+      char *p2 = (char*)tree->cdr->car;
+      char *p3 = (char*)tree->cdr->cdr;
+      int ai = mrb_gc_arena_save(s->mrb);
+      int sym = new_sym(s, mrb_intern_lit(s->mrb, REGEXP_CLASS));
+      int off = new_lit(s, mrb_str_new_cstr(s->mrb, p1));
+      int argc = 1;
+
+      genop(s, MKOP_A(OP_OCLASS, cursp()));
+      genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
+      push();
+      genop(s, MKOP_ABx(OP_STRING, cursp(), off));
+      if (p2 || p3) {
+        push();
+        if (p2) {
+          off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
+          genop(s, MKOP_ABx(OP_STRING, cursp(), off));
+        }
+        else {
+          genop(s, MKOP_A(OP_LOADNIL, cursp()));
+        }
+        argc++;
+        if (p3) {
+          push();
+          off = new_lit(s, mrb_str_new(s->mrb, p3, 1));
+          genop(s, MKOP_ABx(OP_STRING, cursp(), off));
+          argc++;
+          pop();
+        }
+        pop();
+      }
+      pop();
+      sym = new_sym(s, mrb_intern_lit(s->mrb, "compile"));
+      genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc));
+      mrb_gc_arena_restore(s->mrb, ai);
+      push();
+    }
+    break;
+
+  case NODE_DREGX:
+    if (val) {
+      node *n = tree->car;
+      int ai = mrb_gc_arena_save(s->mrb);
+      int sym = new_sym(s, mrb_intern_lit(s->mrb, REGEXP_CLASS));
+      int argc = 1;
+      int off;
+      char *p;
+
+      genop(s, MKOP_A(OP_OCLASS, cursp()));
+      genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
+      push();
+      codegen(s, n->car, VAL);
+      n = n->cdr;
+      while (n) {
+        codegen(s, n->car, VAL);
+        pop(); pop();
+        genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
+        push();
+        n = n->cdr;
+      }
+      n = tree->cdr->cdr;
+      if (n->car) {
+        p = (char*)n->car;
+        off = new_lit(s, mrb_str_new_cstr(s->mrb, p));
+        codegen(s, tree->car, VAL);
+        genop(s, MKOP_ABx(OP_STRING, cursp(), off));
+        pop();
+        genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
+      }
+      if (n->cdr->car) {
+        char *p2 = (char*)n->cdr->car;
+
+        push();
+        off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
+        genop(s, MKOP_ABx(OP_STRING, cursp(), off));
+        argc++;
+      }
+      if (n->cdr->cdr) {
+        char *p2 = (char*)n->cdr->cdr;
+
+        push();
+        off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
+        genop(s, MKOP_ABx(OP_STRING, cursp(), off));
+        argc++;
+      }
+      pop_n(argc);
+      sym = new_sym(s, mrb_intern_lit(s->mrb, "compile"));
+      genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc));
+      mrb_gc_arena_restore(s->mrb, ai);
+      push();
+    }
+    else {
+      node *n = tree->car;
+
+      while (n) {
+        if ((intptr_t)n->car->car != NODE_STR) {
+          codegen(s, n->car, NOVAL);
+        }
+        n = n->cdr;
+      }
+    }
+    break;
+
+  case NODE_SYM:
+    if (val) {
+      int sym = new_sym(s, sym(tree));
+
+      genop(s, MKOP_ABx(OP_LOADSYM, cursp(), sym));
+      push();
+    }
+    break;
+
+  case NODE_DSYM:
+    codegen(s, tree, val);
+    if (val) {
+      gen_send_intern(s);
+    }
+    break;
+
+  case NODE_SELF:
+    if (val) {
+      genop(s, MKOP_A(OP_LOADSELF, cursp()));
+      push();
+    }
+    break;
+
+  case NODE_NIL:
+    if (val) {
+      genop(s, MKOP_A(OP_LOADNIL, cursp()));
+      push();
+    }
+    break;
+
+  case NODE_TRUE:
+    if (val) {
+      genop(s, MKOP_A(OP_LOADT, cursp()));
+      push();
+    }
+    break;
+
+  case NODE_FALSE:
+    if (val) {
+      genop(s, MKOP_A(OP_LOADF, cursp()));
+      push();
+    }
+    break;
+
+  case NODE_ALIAS:
+    {
+      int a = new_msym(s, sym(tree->car));
+      int b = new_msym(s, sym(tree->cdr));
+      int c = new_msym(s, mrb_intern_lit(s->mrb, "alias_method"));
+
+      genop(s, MKOP_A(OP_TCLASS, cursp()));
+      push();
+      genop(s, MKOP_ABx(OP_LOADSYM, cursp(), a));
+      push();
+      genop(s, MKOP_ABx(OP_LOADSYM, cursp(), b));
+      push();
+      genop(s, MKOP_A(OP_LOADNIL, cursp()));
+      push();
+      pop_n(4);
+      genop(s, MKOP_ABC(OP_SEND, cursp(), c, 2));
+      if (val) {
+        push();
+      }
+    }
+   break;
+
+  case NODE_UNDEF:
+    {
+      int undef = new_msym(s, mrb_intern_lit(s->mrb, "undef_method"));
+      int num = 0;
+      node *t = tree;
+
+      genop(s, MKOP_A(OP_TCLASS, cursp()));
+      push();
+      while (t) {
+        int symbol;
+        if (num >= CALL_MAXARGS - 1) {
+          pop_n(num);
+          genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), num));
+          while (t) {
+            symbol = new_msym(s, sym(t->car));
+            push();
+            genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol));
+            pop();
+            genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));
+            t = t->cdr;
+          }
+          num = CALL_MAXARGS;
+          break;
+        }
+        symbol = new_msym(s, sym(t->car));
+        genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol));
+        push();
+        t = t->cdr;
+        num++;
+      }
+      pop();
+      if (num < CALL_MAXARGS) {
+        pop_n(num);
+      }
+      genop(s, MKOP_ABC(OP_SEND, cursp(), undef, num));
+      if (val) {
+        push();
+      }
+    }
+    break;
+
+  case NODE_CLASS:
+    {
+      int idx;
+
+      if (tree->car->car == (node*)0) {
+        genop(s, MKOP_A(OP_LOADNIL, cursp()));
+        push();
+      }
+      else if (tree->car->car == (node*)1) {
+        genop(s, MKOP_A(OP_OCLASS, cursp()));
+        push();
+      }
+      else {
+        codegen(s, tree->car->car, VAL);
+      }
+      if (tree->cdr->car) {
+        codegen(s, tree->cdr->car, VAL);
+      }
+      else {
+        genop(s, MKOP_A(OP_LOADNIL, cursp()));
+        push();
+      }
+      pop(); pop();
+      idx = new_msym(s, sym(tree->car->cdr));
+      genop(s, MKOP_AB(OP_CLASS, cursp(), idx));
+      idx = scope_body(s, tree->cdr->cdr->car, val);
+      genop(s, MKOP_ABx(OP_EXEC, cursp(), idx));
+      if (val) {
+        push();
+      }
+    }
+    break;
+
+  case NODE_MODULE:
+    {
+      int idx;
+
+      if (tree->car->car == (node*)0) {
+        genop(s, MKOP_A(OP_LOADNIL, cursp()));
+        push();
+      }
+      else if (tree->car->car == (node*)1) {
+        genop(s, MKOP_A(OP_OCLASS, cursp()));
+        push();
+      }
+      else {
+        codegen(s, tree->car->car, VAL);
+      }
+      pop();
+      idx = new_msym(s, sym(tree->car->cdr));
+      genop(s, MKOP_AB(OP_MODULE, cursp(), idx));
+      idx = scope_body(s, tree->cdr->car, val);
+      genop(s, MKOP_ABx(OP_EXEC, cursp(), idx));
+      if (val) {
+        push();
+      }
+    }
+    break;
+
+  case NODE_SCLASS:
+    {
+      int idx;
+
+      codegen(s, tree->car, VAL);
+      pop();
+      genop(s, MKOP_AB(OP_SCLASS, cursp(), cursp()));
+      idx = scope_body(s, tree->cdr->car, val);
+      genop(s, MKOP_ABx(OP_EXEC, cursp(), idx));
+      if (val) {
+        push();
+      }
+    }
+    break;
+
+  case NODE_DEF:
+    {
+      int sym = new_msym(s, sym(tree->car));
+      int idx = lambda_body(s, tree->cdr, 0);
+
+      genop(s, MKOP_A(OP_TCLASS, cursp()));
+      push();
+      genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_METHOD));
+      push(); pop();
+      pop();
+      genop(s, MKOP_AB(OP_METHOD, cursp(), sym));
+      if (val) {
+        genop(s, MKOP_ABx(OP_LOADSYM, cursp(), sym));
+        push();
+      }
+    }
+    break;
+
+  case NODE_SDEF:
+    {
+      node *recv = tree->car;
+      int sym = new_msym(s, sym(tree->cdr->car));
+      int idx = lambda_body(s, tree->cdr->cdr, 0);
+
+      codegen(s, recv, VAL);
+      pop();
+      genop(s, MKOP_AB(OP_SCLASS, cursp(), cursp()));
+      push();
+      genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_METHOD));
+      pop();
+      genop(s, MKOP_AB(OP_METHOD, cursp(), sym));
+      if (val) {
+        genop(s, MKOP_ABx(OP_LOADSYM, cursp(), sym));
+        push();
+      }
+    }
+    break;
+
+  case NODE_POSTEXE:
+    codegen(s, tree, NOVAL);
+    break;
+
+  default:
+    break;
+  }
+ exit:
+  s->rlev = rlev;
+}
+
+static void
+scope_add_irep(codegen_scope *s, mrb_irep *irep)
+{
+  if (s->irep == NULL) {
+    s->irep = irep;
+    return;
+  }
+  if (s->irep->rlen == s->rcapa) {
+    s->rcapa *= 2;
+    s->irep->reps = (mrb_irep**)codegen_realloc(s, s->irep->reps, sizeof(mrb_irep*)*s->rcapa);
+  }
+  s->irep->reps[s->irep->rlen] = irep;
+  s->irep->rlen++;
+}
+
+static codegen_scope*
+scope_new(mrb_state *mrb, codegen_scope *prev, node *lv)
+{
+  static const codegen_scope codegen_scope_zero = { 0 };
+  mrb_pool *pool = mrb_pool_open(mrb);
+  codegen_scope *p = (codegen_scope *)mrb_pool_alloc(pool, sizeof(codegen_scope));
+
+  if (!p) return NULL;
+  *p = codegen_scope_zero;
+  p->mrb = mrb;
+  p->mpool = pool;
+  if (!prev) return p;
+  p->prev = prev;
+  p->ainfo = -1;
+  p->mscope = 0;
+
+  p->irep = mrb_add_irep(mrb);
+  scope_add_irep(prev, p->irep);
+
+  p->rcapa = 8;
+  p->irep->reps = (mrb_irep**)mrb_malloc(mrb, sizeof(mrb_irep*)*p->rcapa);
+
+  p->icapa = 1024;
+  p->iseq = (mrb_code*)mrb_malloc(mrb, sizeof(mrb_code)*p->icapa);
+  p->irep->iseq = NULL;
+
+  p->pcapa = 32;
+  p->irep->pool = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value)*p->pcapa);
+  p->irep->plen = 0;
+
+  p->scapa = MAXMSYMLEN;
+  p->irep->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*p->scapa);
+  p->irep->slen = 0;
+
+  p->lv = lv;
+  p->sp += node_len(lv)+1;        /* add self */
+  p->nlocals = p->sp;
+  if (lv) {
+    node *n = lv;
+    size_t i = 0;
+
+    p->irep->lv = (struct mrb_locals*)mrb_malloc(mrb, sizeof(struct mrb_locals) * (p->nlocals - 1));
+    for (i=0, n=lv; n; i++,n=n->cdr) {
+      p->irep->lv[i].name = lv_name(n);
+      if (lv_name(n)) {
+        p->irep->lv[i].r = lv_idx(p, lv_name(n));
+      }
+      else {
+        p->irep->lv[i].r = 0;
+      }
+    }
+    mrb_assert(i + 1 == p->nlocals);
+  }
+  p->ai = mrb_gc_arena_save(mrb);
+
+  p->filename = prev->filename;
+  if (p->filename) {
+    p->lines = (uint16_t*)mrb_malloc(mrb, sizeof(short)*p->icapa);
+  }
+  p->lineno = prev->lineno;
+
+  /* debug setting */
+  p->debug_start_pos = 0;
+  if (p->filename) {
+    mrb_debug_info_alloc(mrb, p->irep);
+    p->irep->filename = p->filename;
+    p->irep->lines = p->lines;
+  }
+  else {
+    p->irep->debug_info = NULL;
+  }
+  p->parser = prev->parser;
+  p->filename_index = prev->filename_index;
+
+  p->rlev = prev->rlev+1;
+
+  return p;
+}
+
+static void
+scope_finish(codegen_scope *s)
+{
+  mrb_state *mrb = s->mrb;
+  mrb_irep *irep = s->irep;
+  size_t fname_len;
+  char *fname;
+
+  irep->flags = 0;
+  if (s->iseq) {
+    irep->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->pc);
+    irep->ilen = s->pc;
+    if (s->lines) {
+      irep->lines = (uint16_t *)codegen_realloc(s, s->lines, sizeof(uint16_t)*s->pc);
+    }
+    else {
+      irep->lines = 0;
+    }
+  }
+  irep->pool = (mrb_value*)codegen_realloc(s, irep->pool, sizeof(mrb_value)*irep->plen);
+  irep->syms = (mrb_sym*)codegen_realloc(s, irep->syms, sizeof(mrb_sym)*irep->slen);
+  irep->reps = (mrb_irep**)codegen_realloc(s, irep->reps, sizeof(mrb_irep*)*irep->rlen);
+  if (s->filename) {
+    irep->filename = mrb_parser_get_filename(s->parser, s->filename_index);
+    mrb_debug_info_append_file(mrb, irep, s->debug_start_pos, s->pc);
+
+    fname_len = strlen(s->filename);
+    fname = (char*)codegen_malloc(s, fname_len + 1);
+    memcpy(fname, s->filename, fname_len);
+    fname[fname_len] = '\0';
+    irep->filename = fname;
+    irep->own_filename = TRUE;
+  }
+
+  irep->nlocals = s->nlocals;
+  irep->nregs = s->nregs;
+
+  mrb_gc_arena_restore(mrb, s->ai);
+  mrb_pool_close(s->mpool);
+}
+
+static struct loopinfo*
+loop_push(codegen_scope *s, enum looptype t)
+{
+  struct loopinfo *p = (struct loopinfo *)codegen_palloc(s, sizeof(struct loopinfo));
+
+  p->type = t;
+  p->pc1 = p->pc2 = p->pc3 = 0;
+  p->prev = s->loop;
+  p->ensure_level = s->ensure_level;
+  p->acc = cursp();
+  s->loop = p;
+
+  return p;
+}
+
+static void
+loop_break(codegen_scope *s, node *tree)
+{
+  if (!s->loop) {
+    codegen(s, tree, NOVAL);
+    raise_error(s, "unexpected break");
+  }
+  else {
+    struct loopinfo *loop;
+
+    if (tree) {
+      gen_retval(s, tree);
+    }
+
+    loop = s->loop;
+    while (loop && loop->type == LOOP_BEGIN) {
+      genop_peep(s, MKOP_A(OP_POPERR, 1), NOVAL);
+      loop = loop->prev;
+    }
+    while (loop && loop->type == LOOP_RESCUE) {
+      loop = loop->prev;
+    }
+    if (!loop) {
+      raise_error(s, "unexpected break");
+      return;
+    }
+
+    if (loop->type == LOOP_NORMAL) {
+      int tmp;
+
+      if (s->ensure_level > s->loop->ensure_level) {
+        genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL);
+      }
+      if (tree) {
+        genop_peep(s, MKOP_AB(OP_MOVE, loop->acc, cursp()), NOVAL);
+      }
+      tmp = genop(s, MKOP_sBx(OP_JMP, loop->pc3));
+      loop->pc3 = tmp;
+    }
+    else {
+      if (!tree) {
+        genop(s, MKOP_A(OP_LOADNIL, cursp()));
+      }
+      genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_BREAK));
+    }
+  }
+}
+
+static void
+loop_pop(codegen_scope *s, int val)
+{
+  dispatch_linked(s, s->loop->pc3);
+  if (val) {
+    genop(s, MKOP_A(OP_LOADNIL, cursp()));
+  }
+  s->loop = s->loop->prev;
+  if (val) push();
+}
+
+MRB_API struct RProc*
+mrb_generate_code(mrb_state *mrb, parser_state *p)
+{
+  codegen_scope *scope = scope_new(mrb, 0, 0);
+  struct RProc *proc;
+  struct mrb_jmpbuf *prev_jmp = mrb->jmp;
+
+  if (!scope) {
+    return NULL;
+  }
+  scope->mrb = mrb;
+  scope->parser = p;
+  scope->filename = p->filename;
+  scope->filename_index = p->current_filename_index;
+
+  MRB_TRY(&scope->jmp) {
+    mrb->jmp = &scope->jmp; 
+    /* prepare irep */
+    codegen(scope, p->tree, NOVAL);
+    proc = mrb_proc_new(mrb, scope->irep);
+    mrb_irep_decref(mrb, scope->irep);
+    mrb_pool_close(scope->mpool);
+    proc->c = NULL;
+    mrb->jmp = prev_jmp;
+    return proc;
+  }
+  MRB_CATCH(&scope->jmp) {
+    mrb_irep_decref(mrb, scope->irep);
+    mrb_pool_close(scope->mpool);
+    mrb->jmp = prev_jmp;
+    return NULL;
+  }
+  MRB_END_EXC(&scope->jmp);
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/core/keywords
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/core/keywords	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/core/keywords	(revision 331)
@@ -0,0 +1,50 @@
+%{
+struct kwtable {const char *name; int id[2]; enum mrb_lex_state_enum state;};
+const struct kwtable *mrb_reserved_word(const char *, unsigned int);
+static const struct kwtable *reserved_word(const char *, unsigned int);
+#define mrb_reserved_word(str, len) reserved_word(str, len)
+%}
+
+struct kwtable;
+%%
+__ENCODING__, {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END
+__FILE__,     {keyword__FILE__,     keyword__FILE__},     EXPR_END
+__LINE__,     {keyword__LINE__,     keyword__LINE__},     EXPR_END
+BEGIN,        {keyword_BEGIN,       keyword_BEGIN},       EXPR_END
+END,          {keyword_END,         keyword_END},         EXPR_END
+alias,        {keyword_alias,       keyword_alias},       EXPR_FNAME
+and,          {keyword_and,         keyword_and},         EXPR_VALUE
+begin,        {keyword_begin,       keyword_begin},       EXPR_BEG
+break,        {keyword_break,       keyword_break},       EXPR_MID
+case,         {keyword_case,        keyword_case},        EXPR_VALUE
+class,        {keyword_class,       keyword_class},       EXPR_CLASS
+def,          {keyword_def,         keyword_def},         EXPR_FNAME
+do,           {keyword_do,          keyword_do},          EXPR_BEG
+else,         {keyword_else,        keyword_else},        EXPR_BEG
+elsif,        {keyword_elsif,       keyword_elsif},       EXPR_VALUE
+end,          {keyword_end,         keyword_end},         EXPR_END
+ensure,       {keyword_ensure,      keyword_ensure},      EXPR_BEG
+false,        {keyword_false,       keyword_false},       EXPR_END
+for,          {keyword_for,         keyword_for},         EXPR_VALUE
+if,           {keyword_if,          modifier_if},         EXPR_VALUE
+in,           {keyword_in,          keyword_in},          EXPR_VALUE
+module,       {keyword_module,      keyword_module},      EXPR_VALUE
+next,         {keyword_next,        keyword_next},        EXPR_MID
+nil,          {keyword_nil,         keyword_nil},         EXPR_END
+not,          {keyword_not,         keyword_not},         EXPR_ARG
+or,           {keyword_or,          keyword_or},          EXPR_VALUE
+redo,         {keyword_redo,        keyword_redo},        EXPR_END
+rescue,       {keyword_rescue,      modifier_rescue},     EXPR_MID
+retry,        {keyword_retry,       keyword_retry},       EXPR_END
+return,       {keyword_return,      keyword_return},      EXPR_MID
+self,         {keyword_self,        keyword_self},        EXPR_END
+super,        {keyword_super,       keyword_super},       EXPR_ARG
+then,         {keyword_then,        keyword_then},        EXPR_BEG
+true,         {keyword_true,        keyword_true},        EXPR_END
+undef,        {keyword_undef,       keyword_undef},       EXPR_FNAME
+unless,       {keyword_unless,      modifier_unless},     EXPR_VALUE
+until,        {keyword_until,       modifier_until},      EXPR_VALUE
+when,         {keyword_when,        keyword_when},        EXPR_VALUE
+while,        {keyword_while,       modifier_while},      EXPR_VALUE
+yield,        {keyword_yield,       keyword_yield},       EXPR_ARG
+%%
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/core/lex.def
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/core/lex.def	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/core/lex.def	(revision 331)
@@ -0,0 +1,212 @@
+/* ANSI-C code produced by gperf version 3.0.4 */
+/* Command-line: gperf -L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k'1,3,$' /home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords  */
+
+#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
+      && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
+      && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
+      && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
+      && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
+      && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
+      && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
+      && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
+      && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
+      && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
+      && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
+      && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
+      && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
+      && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
+      && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
+      && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
+      && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
+      && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
+      && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
+      && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
+      && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
+      && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
+      && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
+/* The character set is not based on ISO-646.  */
+#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
+#endif
+
+#line 1 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+
+struct kwtable {const char *name; int id[2]; enum mrb_lex_state_enum state;};
+const struct kwtable *mrb_reserved_word(const char *, unsigned int);
+static const struct kwtable *reserved_word(const char *, unsigned int);
+#define mrb_reserved_word(str, len) reserved_word(str, len)
+#line 8 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+struct kwtable;
+
+#define TOTAL_KEYWORDS 40
+#define MIN_WORD_LENGTH 2
+#define MAX_WORD_LENGTH 12
+#define MIN_HASH_VALUE 8
+#define MAX_HASH_VALUE 50
+/* maximum key range = 43, duplicates = 0 */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static unsigned int
+hash (register const char *str, register unsigned int len)
+{
+  static const unsigned char asso_values[] =
+    {
+      51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+      51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+      51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+      51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+      51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+      51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+      51, 51, 51, 51, 51, 51, 14, 51, 16,  8,
+      11, 13, 51, 51, 51, 51, 10, 51, 13, 51,
+      51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+      51, 51, 51, 51, 51, 11, 51, 13,  1, 26,
+       4,  1,  8, 28, 51, 23, 51,  1,  1, 27,
+       5, 19, 21, 51,  8,  3,  3, 11, 51, 21,
+      24, 16, 51, 51, 51, 51, 51, 51, 51, 51,
+      51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+      51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+      51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+      51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+      51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+      51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+      51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+      51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+      51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+      51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+      51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+      51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+      51, 51, 51, 51, 51, 51
+    };
+  register int hval = len;
+
+  switch (hval)
+    {
+      default:
+        hval += asso_values[(unsigned char)str[2]];
+      /*FALLTHROUGH*/
+      case 2:
+      case 1:
+        hval += asso_values[(unsigned char)str[0]];
+        break;
+    }
+  return hval + asso_values[(unsigned char)str[len - 1]];
+}
+
+#ifdef __GNUC__
+__inline
+#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
+__attribute__ ((__gnu_inline__))
+#endif
+#endif
+const struct kwtable *
+mrb_reserved_word (register const char *str, register unsigned int len)
+{
+  static const struct kwtable wordlist[] =
+    {
+      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
+#line 18 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"break",        {keyword_break,       keyword_break},       EXPR_MID},
+#line 23 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"else",         {keyword_else,        keyword_else},        EXPR_BEG},
+#line 33 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"nil",          {keyword_nil,         keyword_nil},         EXPR_END},
+#line 26 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"ensure",       {keyword_ensure,      keyword_ensure},      EXPR_BEG},
+#line 25 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"end",          {keyword_end,         keyword_end},         EXPR_END},
+#line 42 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"then",         {keyword_then,        keyword_then},        EXPR_BEG},
+#line 34 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"not",          {keyword_not,         keyword_not},         EXPR_ARG},
+#line 27 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"false",        {keyword_false,       keyword_false},       EXPR_END},
+#line 40 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"self",         {keyword_self,        keyword_self},        EXPR_END},
+#line 24 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"elsif",        {keyword_elsif,       keyword_elsif},       EXPR_VALUE},
+#line 37 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"rescue",       {keyword_rescue,      modifier_rescue},     EXPR_MID},
+#line 43 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"true",         {keyword_true,        keyword_true},        EXPR_END},
+#line 46 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"until",        {keyword_until,       modifier_until},      EXPR_VALUE},
+#line 45 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"unless",       {keyword_unless,      modifier_unless},     EXPR_VALUE},
+#line 39 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"return",       {keyword_return,      keyword_return},      EXPR_MID},
+#line 21 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"def",          {keyword_def,         keyword_def},         EXPR_FNAME},
+#line 16 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"and",          {keyword_and,         keyword_and},         EXPR_VALUE},
+#line 22 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"do",           {keyword_do,          keyword_do},          EXPR_BEG},
+#line 49 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"yield",        {keyword_yield,       keyword_yield},       EXPR_ARG},
+#line 28 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"for",          {keyword_for,         keyword_for},         EXPR_VALUE},
+#line 44 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"undef",        {keyword_undef,       keyword_undef},       EXPR_FNAME},
+#line 35 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"or",           {keyword_or,          keyword_or},          EXPR_VALUE},
+#line 30 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"in",           {keyword_in,          keyword_in},          EXPR_VALUE},
+#line 47 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"when",         {keyword_when,        keyword_when},        EXPR_VALUE},
+#line 38 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"retry",        {keyword_retry,       keyword_retry},       EXPR_END},
+#line 29 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"if",           {keyword_if,          modifier_if},         EXPR_VALUE},
+#line 19 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"case",         {keyword_case,        keyword_case},        EXPR_VALUE},
+#line 36 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"redo",         {keyword_redo,        keyword_redo},        EXPR_END},
+#line 32 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"next",         {keyword_next,        keyword_next},        EXPR_MID},
+#line 41 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"super",        {keyword_super,       keyword_super},       EXPR_ARG},
+#line 31 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"module",       {keyword_module,      keyword_module},      EXPR_VALUE},
+#line 17 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"begin",        {keyword_begin,       keyword_begin},       EXPR_BEG},
+#line 12 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"__LINE__",     {keyword__LINE__,     keyword__LINE__},     EXPR_END},
+#line 11 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"__FILE__",     {keyword__FILE__,     keyword__FILE__},     EXPR_END},
+#line 10 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"__ENCODING__", {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END},
+#line 14 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"END",          {keyword_END,         keyword_END},         EXPR_END},
+#line 15 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"alias",        {keyword_alias,       keyword_alias},       EXPR_FNAME},
+#line 13 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"BEGIN",        {keyword_BEGIN,       keyword_BEGIN},       EXPR_END},
+      {""},
+#line 20 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"class",        {keyword_class,       keyword_class},       EXPR_CLASS},
+      {""}, {""},
+#line 48 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+      {"while",        {keyword_while,       modifier_while},      EXPR_VALUE}
+    };
+
+  if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
+    {
+      register int key = hash (str, len);
+
+      if (key <= MAX_HASH_VALUE && key >= 0)
+        {
+          register const char *s = wordlist[key].name;
+
+          if (*str == *s && !strcmp (str + 1, s + 1))
+            return &wordlist[key];
+        }
+    }
+  return 0;
+}
+#line 50 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords"
+
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/core/node.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/core/node.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/core/node.h	(revision 331)
@@ -0,0 +1,118 @@
+/*
+** node.h - nodes of abstract syntax tree
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_COMPILER_NODE_H
+#define MRUBY_COMPILER_NODE_H
+
+enum node_type {
+  NODE_METHOD,
+  NODE_FBODY,
+  NODE_CFUNC,
+  NODE_SCOPE,
+  NODE_BLOCK,
+  NODE_IF,
+  NODE_CASE,
+  NODE_WHEN,
+  NODE_OPT_N,
+  NODE_WHILE,
+  NODE_UNTIL,
+  NODE_ITER,
+  NODE_FOR,
+  NODE_BREAK,
+  NODE_NEXT,
+  NODE_REDO,
+  NODE_RETRY,
+  NODE_BEGIN,
+  NODE_RESCUE,
+  NODE_ENSURE,
+  NODE_AND,
+  NODE_OR,
+  NODE_NOT,
+  NODE_MASGN,
+  NODE_ASGN,
+  NODE_CDECL,
+  NODE_CVASGN,
+  NODE_CVDECL,
+  NODE_OP_ASGN,
+  NODE_CALL,
+  NODE_SCALL,
+  NODE_FCALL,
+  NODE_VCALL,
+  NODE_SUPER,
+  NODE_ZSUPER,
+  NODE_ARRAY,
+  NODE_ZARRAY,
+  NODE_HASH,
+  NODE_RETURN,
+  NODE_YIELD,
+  NODE_LVAR,
+  NODE_DVAR,
+  NODE_GVAR,
+  NODE_IVAR,
+  NODE_CONST,
+  NODE_CVAR,
+  NODE_NTH_REF,
+  NODE_BACK_REF,
+  NODE_MATCH,
+  NODE_MATCH2,
+  NODE_MATCH3,
+  NODE_INT,
+  NODE_FLOAT,
+  NODE_NEGATE,
+  NODE_LAMBDA,
+  NODE_SYM,
+  NODE_STR,
+  NODE_DSTR,
+  NODE_XSTR,
+  NODE_DXSTR,
+  NODE_REGX,
+  NODE_DREGX,
+  NODE_DREGX_ONCE,
+  NODE_LIST,
+  NODE_ARG,
+  NODE_ARGSCAT,
+  NODE_ARGSPUSH,
+  NODE_SPLAT,
+  NODE_TO_ARY,
+  NODE_SVALUE,
+  NODE_BLOCK_ARG,
+  NODE_DEF,
+  NODE_SDEF,
+  NODE_ALIAS,
+  NODE_UNDEF,
+  NODE_CLASS,
+  NODE_MODULE,
+  NODE_SCLASS,
+  NODE_COLON2,
+  NODE_COLON3,
+  NODE_CREF,
+  NODE_DOT2,
+  NODE_DOT3,
+  NODE_FLIP2,
+  NODE_FLIP3,
+  NODE_ATTRSET,
+  NODE_SELF,
+  NODE_NIL,
+  NODE_TRUE,
+  NODE_FALSE,
+  NODE_DEFINED,
+  NODE_NEWLINE,
+  NODE_POSTEXE,
+  NODE_ALLOCA,
+  NODE_DMETHOD,
+  NODE_BMETHOD,
+  NODE_MEMO,
+  NODE_IFUNC,
+  NODE_DSYM,
+  NODE_ATTRASGN,
+  NODE_HEREDOC,
+  NODE_LITERAL_DELIM,
+  NODE_WORDS,
+  NODE_SYMBOLS,
+  NODE_LAST
+};
+
+#endif  /* MRUBY_COMPILER_NODE_H */
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/core/parse.y
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/core/parse.y	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/core/parse.y	(revision 331)
@@ -0,0 +1,6644 @@
+/*
+** parse.y - mruby parser
+**
+** See Copyright Notice in mruby.h
+*/
+
+%{
+#undef PARSER_DEBUG
+#ifdef PARSER_DEBUG
+# define YYDEBUG 1
+#endif
+#define YYERROR_VERBOSE 1
+/*
+ * Force yacc to use our memory management.  This is a little evil because
+ * the macros assume that "parser_state *p" is in scope
+ */
+#define YYMALLOC(n)    mrb_malloc(p->mrb, (n))
+#define YYFREE(o)      mrb_free(p->mrb, (o))
+#define YYSTACK_USE_ALLOCA 0
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mruby.h>
+#include <mruby/compile.h>
+#include <mruby/proc.h>
+#include <mruby/error.h>
+#include <mruby/throw.h>
+#include "node.h"
+
+#define YYLEX_PARAM p
+
+typedef mrb_ast_node node;
+typedef struct mrb_parser_state parser_state;
+typedef struct mrb_parser_heredoc_info parser_heredoc_info;
+
+static int yyparse(parser_state *p);
+static int yylex(void *lval, parser_state *p);
+static void yyerror(parser_state *p, const char *s);
+static void yywarn(parser_state *p, const char *s);
+static void yywarning(parser_state *p, const char *s);
+static void backref_error(parser_state *p, node *n);
+static void void_expr_error(parser_state *p, node *n);
+static void tokadd(parser_state *p, int32_t c);
+
+#define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c))
+
+typedef unsigned int stack_type;
+
+#define BITSTACK_PUSH(stack, n) ((stack) = ((stack)<<1)|((n)&1))
+#define BITSTACK_POP(stack)     ((stack) = (stack) >> 1)
+#define BITSTACK_LEXPOP(stack)  ((stack) = ((stack) >> 1) | ((stack) & 1))
+#define BITSTACK_SET_P(stack)   ((stack)&1)
+
+#define COND_PUSH(n)    BITSTACK_PUSH(p->cond_stack, (n))
+#define COND_POP()      BITSTACK_POP(p->cond_stack)
+#define COND_LEXPOP()   BITSTACK_LEXPOP(p->cond_stack)
+#define COND_P()        BITSTACK_SET_P(p->cond_stack)
+
+#define CMDARG_PUSH(n)  BITSTACK_PUSH(p->cmdarg_stack, (n))
+#define CMDARG_POP()    BITSTACK_POP(p->cmdarg_stack)
+#define CMDARG_LEXPOP() BITSTACK_LEXPOP(p->cmdarg_stack)
+#define CMDARG_P()      BITSTACK_SET_P(p->cmdarg_stack)
+
+#define SET_LINENO(c,n) ((c)->lineno = (n))
+#define NODE_LINENO(c,n) do {\
+  if (n) {\
+     (c)->filename_index = (n)->filename_index;\
+     (c)->lineno = (n)->lineno;\
+  }\
+} while (0)
+
+#define sym(x) ((mrb_sym)(intptr_t)(x))
+#define nsym(x) ((node*)(intptr_t)(x))
+#define nint(x) ((node*)(intptr_t)(x))
+#define intn(x) ((int)(intptr_t)(x))
+
+static inline mrb_sym
+intern_cstr_gen(parser_state *p, const char *s)
+{
+  return mrb_intern_cstr(p->mrb, s);
+}
+#define intern_cstr(s) intern_cstr_gen(p,(s))
+
+static inline mrb_sym
+intern_gen(parser_state *p, const char *s, size_t len)
+{
+  return mrb_intern(p->mrb, s, len);
+}
+#define intern(s,len) intern_gen(p,(s),(len))
+
+static inline mrb_sym
+intern_gen_c(parser_state *p, const char c)
+{
+  return mrb_intern(p->mrb, &c, 1);
+}
+#define intern_c(c) intern_gen_c(p,(c))
+
+static void
+cons_free_gen(parser_state *p, node *cons)
+{
+  cons->cdr = p->cells;
+  p->cells = cons;
+}
+#define cons_free(c) cons_free_gen(p, (c))
+
+static void*
+parser_palloc(parser_state *p, size_t size)
+{
+  void *m = mrb_pool_alloc(p->pool, size);
+
+  if (!m) {
+    MRB_THROW(p->jmp);
+  }
+  return m;
+}
+
+static node*
+cons_gen(parser_state *p, node *car, node *cdr)
+{
+  node *c;
+
+  if (p->cells) {
+    c = p->cells;
+    p->cells = p->cells->cdr;
+  }
+  else {
+    c = (node *)parser_palloc(p, sizeof(mrb_ast_node));
+  }
+
+  c->car = car;
+  c->cdr = cdr;
+  c->lineno = p->lineno;
+  c->filename_index = p->current_filename_index;
+  return c;
+}
+#define cons(a,b) cons_gen(p,(a),(b))
+
+static node*
+list1_gen(parser_state *p, node *a)
+{
+  return cons(a, 0);
+}
+#define list1(a) list1_gen(p, (a))
+
+static node*
+list2_gen(parser_state *p, node *a, node *b)
+{
+  return cons(a, cons(b,0));
+}
+#define list2(a,b) list2_gen(p, (a),(b))
+
+static node*
+list3_gen(parser_state *p, node *a, node *b, node *c)
+{
+  return cons(a, cons(b, cons(c,0)));
+}
+#define list3(a,b,c) list3_gen(p, (a),(b),(c))
+
+static node*
+list4_gen(parser_state *p, node *a, node *b, node *c, node *d)
+{
+  return cons(a, cons(b, cons(c, cons(d, 0))));
+}
+#define list4(a,b,c,d) list4_gen(p, (a),(b),(c),(d))
+
+static node*
+list5_gen(parser_state *p, node *a, node *b, node *c, node *d, node *e)
+{
+  return cons(a, cons(b, cons(c, cons(d, cons(e, 0)))));
+}
+#define list5(a,b,c,d,e) list5_gen(p, (a),(b),(c),(d),(e))
+
+static node*
+list6_gen(parser_state *p, node *a, node *b, node *c, node *d, node *e, node *f)
+{
+  return cons(a, cons(b, cons(c, cons(d, cons(e, cons(f, 0))))));
+}
+#define list6(a,b,c,d,e,f) list6_gen(p, (a),(b),(c),(d),(e),(f))
+
+static node*
+append_gen(parser_state *p, node *a, node *b)
+{
+  node *c = a;
+
+  if (!a) return b;
+  while (c->cdr) {
+    c = c->cdr;
+  }
+  if (b) {
+    c->cdr = b;
+  }
+  return a;
+}
+#define append(a,b) append_gen(p,(a),(b))
+#define push(a,b) append_gen(p,(a),list1(b))
+
+static char*
+parser_strndup(parser_state *p, const char *s, size_t len)
+{
+  char *b = (char *)parser_palloc(p, len+1);
+
+  memcpy(b, s, len);
+  b[len] = '\0';
+  return b;
+}
+#undef strndup
+#define strndup(s,len) parser_strndup(p, s, len)
+
+static char*
+parser_strdup(parser_state *p, const char *s)
+{
+  return parser_strndup(p, s, strlen(s));
+}
+#undef strdup
+#define strdup(s) parser_strdup(p, s)
+
+/* xxx ----------------------------- */
+
+static node*
+local_switch(parser_state *p)
+{
+  node *prev = p->locals;
+
+  p->locals = cons(0, 0);
+  return prev;
+}
+
+static void
+local_resume(parser_state *p, node *prev)
+{
+  p->locals = prev;
+}
+
+static void
+local_nest(parser_state *p)
+{
+  p->locals = cons(0, p->locals);
+}
+
+static void
+local_unnest(parser_state *p)
+{
+  if (p->locals) {
+    p->locals = p->locals->cdr;
+  }
+}
+
+static mrb_bool
+local_var_p(parser_state *p, mrb_sym sym)
+{
+  node *l = p->locals;
+
+  while (l) {
+    node *n = l->car;
+    while (n) {
+      if (sym(n->car) == sym) return TRUE;
+      n = n->cdr;
+    }
+    l = l->cdr;
+  }
+  return FALSE;
+}
+
+static void
+local_add_f(parser_state *p, mrb_sym sym)
+{
+  if (p->locals) {
+    p->locals->car = push(p->locals->car, nsym(sym));
+  }
+}
+
+static void
+local_add(parser_state *p, mrb_sym sym)
+{
+  if (!local_var_p(p, sym)) {
+    local_add_f(p, sym);
+  }
+}
+
+static node*
+locals_node(parser_state *p)
+{
+  return p->locals ? p->locals->car : NULL;
+}
+
+/* (:scope (vars..) (prog...)) */
+static node*
+new_scope(parser_state *p, node *body)
+{
+  return cons((node*)NODE_SCOPE, cons(locals_node(p), body));
+}
+
+/* (:begin prog...) */
+static node*
+new_begin(parser_state *p, node *body)
+{
+  if (body) {
+    return list2((node*)NODE_BEGIN, body);
+  }
+  return cons((node*)NODE_BEGIN, 0);
+}
+
+#define newline_node(n) (n)
+
+/* (:rescue body rescue else) */
+static node*
+new_rescue(parser_state *p, node *body, node *resq, node *els)
+{
+  return list4((node*)NODE_RESCUE, body, resq, els);
+}
+
+static node*
+new_mod_rescue(parser_state *p, node *body, node *resq)
+{
+  return new_rescue(p, body, list1(list3(0, 0, resq)), 0);
+}
+
+/* (:ensure body ensure) */
+static node*
+new_ensure(parser_state *p, node *a, node *b)
+{
+  return cons((node*)NODE_ENSURE, cons(a, cons(0, b)));
+}
+
+/* (:nil) */
+static node*
+new_nil(parser_state *p)
+{
+  return list1((node*)NODE_NIL);
+}
+
+/* (:true) */
+static node*
+new_true(parser_state *p)
+{
+  return list1((node*)NODE_TRUE);
+}
+
+/* (:false) */
+static node*
+new_false(parser_state *p)
+{
+  return list1((node*)NODE_FALSE);
+}
+
+/* (:alias new old) */
+static node*
+new_alias(parser_state *p, mrb_sym a, mrb_sym b)
+{
+  return cons((node*)NODE_ALIAS, cons(nsym(a), nsym(b)));
+}
+
+/* (:if cond then else) */
+static node*
+new_if(parser_state *p, node *a, node *b, node *c)
+{
+  void_expr_error(p, a);
+  return list4((node*)NODE_IF, a, b, c);
+}
+
+/* (:unless cond then else) */
+static node*
+new_unless(parser_state *p, node *a, node *b, node *c)
+{
+  void_expr_error(p, a);
+  return list4((node*)NODE_IF, a, c, b);
+}
+
+/* (:while cond body) */
+static node*
+new_while(parser_state *p, node *a, node *b)
+{
+  void_expr_error(p, a);
+  return cons((node*)NODE_WHILE, cons(a, b));
+}
+
+/* (:until cond body) */
+static node*
+new_until(parser_state *p, node *a, node *b)
+{
+  void_expr_error(p, a);
+  return cons((node*)NODE_UNTIL, cons(a, b));
+}
+
+/* (:for var obj body) */
+static node*
+new_for(parser_state *p, node *v, node *o, node *b)
+{
+  void_expr_error(p, o);
+  return list4((node*)NODE_FOR, v, o, b);
+}
+
+/* (:case a ((when ...) body) ((when...) body)) */
+static node*
+new_case(parser_state *p, node *a, node *b)
+{
+  node *n = list2((node*)NODE_CASE, a);
+  node *n2 = n;
+
+  void_expr_error(p, a);
+  while (n2->cdr) {
+    n2 = n2->cdr;
+  }
+  n2->cdr = b;
+  return n;
+}
+
+/* (:postexe a) */
+static node*
+new_postexe(parser_state *p, node *a)
+{
+  return cons((node*)NODE_POSTEXE, a);
+}
+
+/* (:self) */
+static node*
+new_self(parser_state *p)
+{
+  return list1((node*)NODE_SELF);
+}
+
+/* (:call a b c) */
+static node*
+new_call(parser_state *p, node *a, mrb_sym b, node *c, int pass)
+{
+  node *n = list4(nint(pass?NODE_CALL:NODE_SCALL), a, nsym(b), c);
+  void_expr_error(p, a);
+  NODE_LINENO(n, a);
+  return n;
+}
+
+/* (:fcall self mid args) */
+static node*
+new_fcall(parser_state *p, mrb_sym b, node *c)
+{
+  node *n = new_self(p);
+  NODE_LINENO(n, c);
+  n = list4((node*)NODE_FCALL, n, nsym(b), c);
+  NODE_LINENO(n, c);
+  return n;
+}
+
+/* (:super . c) */
+static node*
+new_super(parser_state *p, node *c)
+{
+  return cons((node*)NODE_SUPER, c);
+}
+
+/* (:zsuper) */
+static node*
+new_zsuper(parser_state *p)
+{
+  return list1((node*)NODE_ZSUPER);
+}
+
+/* (:yield . c) */
+static node*
+new_yield(parser_state *p, node *c)
+{
+  if (c) {
+    if (c->cdr) {
+      yyerror(p, "both block arg and actual block given");
+    }
+    return cons((node*)NODE_YIELD, c->car);
+  }
+  return cons((node*)NODE_YIELD, 0);
+}
+
+/* (:return . c) */
+static node*
+new_return(parser_state *p, node *c)
+{
+  return cons((node*)NODE_RETURN, c);
+}
+
+/* (:break . c) */
+static node*
+new_break(parser_state *p, node *c)
+{
+  return cons((node*)NODE_BREAK, c);
+}
+
+/* (:next . c) */
+static node*
+new_next(parser_state *p, node *c)
+{
+  return cons((node*)NODE_NEXT, c);
+}
+
+/* (:redo) */
+static node*
+new_redo(parser_state *p)
+{
+  return list1((node*)NODE_REDO);
+}
+
+/* (:retry) */
+static node*
+new_retry(parser_state *p)
+{
+  return list1((node*)NODE_RETRY);
+}
+
+/* (:dot2 a b) */
+static node*
+new_dot2(parser_state *p, node *a, node *b)
+{
+  return cons((node*)NODE_DOT2, cons(a, b));
+}
+
+/* (:dot3 a b) */
+static node*
+new_dot3(parser_state *p, node *a, node *b)
+{
+  return cons((node*)NODE_DOT3, cons(a, b));
+}
+
+/* (:colon2 b c) */
+static node*
+new_colon2(parser_state *p, node *b, mrb_sym c)
+{
+  void_expr_error(p, b);
+  return cons((node*)NODE_COLON2, cons(b, nsym(c)));
+}
+
+/* (:colon3 . c) */
+static node*
+new_colon3(parser_state *p, mrb_sym c)
+{
+  return cons((node*)NODE_COLON3, nsym(c));
+}
+
+/* (:and a b) */
+static node*
+new_and(parser_state *p, node *a, node *b)
+{
+  return cons((node*)NODE_AND, cons(a, b));
+}
+
+/* (:or a b) */
+static node*
+new_or(parser_state *p, node *a, node *b)
+{
+  return cons((node*)NODE_OR, cons(a, b));
+}
+
+/* (:array a...) */
+static node*
+new_array(parser_state *p, node *a)
+{
+  return cons((node*)NODE_ARRAY, a);
+}
+
+/* (:splat . a) */
+static node*
+new_splat(parser_state *p, node *a)
+{
+  return cons((node*)NODE_SPLAT, a);
+}
+
+/* (:hash (k . v) (k . v)...) */
+static node*
+new_hash(parser_state *p, node *a)
+{
+  return cons((node*)NODE_HASH, a);
+}
+
+/* (:sym . a) */
+static node*
+new_sym(parser_state *p, mrb_sym sym)
+{
+  return cons((node*)NODE_SYM, nsym(sym));
+}
+
+static mrb_sym
+new_strsym(parser_state *p, node* str)
+{
+  const char *s = (const char*)str->cdr->car;
+  size_t len = (size_t)str->cdr->cdr;
+
+  return mrb_intern(p->mrb, s, len);
+}
+
+/* (:lvar . a) */
+static node*
+new_lvar(parser_state *p, mrb_sym sym)
+{
+  return cons((node*)NODE_LVAR, nsym(sym));
+}
+
+/* (:gvar . a) */
+static node*
+new_gvar(parser_state *p, mrb_sym sym)
+{
+  return cons((node*)NODE_GVAR, nsym(sym));
+}
+
+/* (:ivar . a) */
+static node*
+new_ivar(parser_state *p, mrb_sym sym)
+{
+  return cons((node*)NODE_IVAR, nsym(sym));
+}
+
+/* (:cvar . a) */
+static node*
+new_cvar(parser_state *p, mrb_sym sym)
+{
+  return cons((node*)NODE_CVAR, nsym(sym));
+}
+
+/* (:const . a) */
+static node*
+new_const(parser_state *p, mrb_sym sym)
+{
+  return cons((node*)NODE_CONST, nsym(sym));
+}
+
+/* (:undef a...) */
+static node*
+new_undef(parser_state *p, mrb_sym sym)
+{
+  return list2((node*)NODE_UNDEF, nsym(sym));
+}
+
+/* (:class class super body) */
+static node*
+new_class(parser_state *p, node *c, node *s, node *b)
+{
+  void_expr_error(p, s);
+  return list4((node*)NODE_CLASS, c, s, cons(locals_node(p), b));
+}
+
+/* (:sclass obj body) */
+static node*
+new_sclass(parser_state *p, node *o, node *b)
+{
+  void_expr_error(p, o);
+  return list3((node*)NODE_SCLASS, o, cons(locals_node(p), b));
+}
+
+/* (:module module body) */
+static node*
+new_module(parser_state *p, node *m, node *b)
+{
+  return list3((node*)NODE_MODULE, m, cons(locals_node(p), b));
+}
+
+/* (:def m lv (arg . body)) */
+static node*
+new_def(parser_state *p, mrb_sym m, node *a, node *b)
+{
+  return list5((node*)NODE_DEF, nsym(m), locals_node(p), a, b);
+}
+
+/* (:sdef obj m lv (arg . body)) */
+static node*
+new_sdef(parser_state *p, node *o, mrb_sym m, node *a, node *b)
+{
+  void_expr_error(p, o);
+  return list6((node*)NODE_SDEF, o, nsym(m), locals_node(p), a, b);
+}
+
+/* (:arg . sym) */
+static node*
+new_arg(parser_state *p, mrb_sym sym)
+{
+  return cons((node*)NODE_ARG, nsym(sym));
+}
+
+/* (m o r m2 b) */
+/* m: (a b c) */
+/* o: ((a . e1) (b . e2)) */
+/* r: a */
+/* m2: (a b c) */
+/* b: a */
+static node*
+new_args(parser_state *p, node *m, node *opt, mrb_sym rest, node *m2, mrb_sym blk)
+{
+  node *n;
+
+  n = cons(m2, nsym(blk));
+  n = cons(nsym(rest), n);
+  n = cons(opt, n);
+  return cons(m, n);
+}
+
+/* (:block_arg . a) */
+static node*
+new_block_arg(parser_state *p, node *a)
+{
+  return cons((node*)NODE_BLOCK_ARG, a);
+}
+
+/* (:block arg body) */
+static node*
+new_block(parser_state *p, node *a, node *b)
+{
+  return list4((node*)NODE_BLOCK, locals_node(p), a, b);
+}
+
+/* (:lambda arg body) */
+static node*
+new_lambda(parser_state *p, node *a, node *b)
+{
+  return list4((node*)NODE_LAMBDA, locals_node(p), a, b);
+}
+
+/* (:asgn lhs rhs) */
+static node*
+new_asgn(parser_state *p, node *a, node *b)
+{
+  void_expr_error(p, b);
+  return cons((node*)NODE_ASGN, cons(a, b));
+}
+
+/* (:masgn mlhs=(pre rest post)  mrhs) */
+static node*
+new_masgn(parser_state *p, node *a, node *b)
+{
+  void_expr_error(p, b);
+  return cons((node*)NODE_MASGN, cons(a, b));
+}
+
+/* (:asgn lhs rhs) */
+static node*
+new_op_asgn(parser_state *p, node *a, mrb_sym op, node *b)
+{
+  void_expr_error(p, b);
+  return list4((node*)NODE_OP_ASGN, a, nsym(op), b);
+}
+
+/* (:int . i) */
+static node*
+new_int(parser_state *p, const char *s, int base)
+{
+  return list3((node*)NODE_INT, (node*)strdup(s), nint(base));
+}
+
+/* (:float . i) */
+static node*
+new_float(parser_state *p, const char *s)
+{
+  return cons((node*)NODE_FLOAT, (node*)strdup(s));
+}
+
+/* (:str . (s . len)) */
+static node*
+new_str(parser_state *p, const char *s, int len)
+{
+  return cons((node*)NODE_STR, cons((node*)strndup(s, len), nint(len)));
+}
+
+/* (:dstr . a) */
+static node*
+new_dstr(parser_state *p, node *a)
+{
+  return cons((node*)NODE_DSTR, a);
+}
+
+/* (:str . (s . len)) */
+static node*
+new_xstr(parser_state *p, const char *s, int len)
+{
+  return cons((node*)NODE_XSTR, cons((node*)strndup(s, len), nint(len)));
+}
+
+/* (:xstr . a) */
+static node*
+new_dxstr(parser_state *p, node *a)
+{
+  return cons((node*)NODE_DXSTR, a);
+}
+
+/* (:dsym . a) */
+static node*
+new_dsym(parser_state *p, node *a)
+{
+  return cons((node*)NODE_DSYM, new_dstr(p, a));
+}
+
+/* (:regx . (s . (opt . enc))) */
+static node*
+new_regx(parser_state *p, const char *p1, const char* p2, const char* p3)
+{
+  return cons((node*)NODE_REGX, cons((node*)p1, cons((node*)p2, (node*)p3)));
+}
+
+/* (:dregx . (a . b)) */
+static node*
+new_dregx(parser_state *p, node *a, node *b)
+{
+  return cons((node*)NODE_DREGX, cons(a, b));
+}
+
+/* (:backref . n) */
+static node*
+new_back_ref(parser_state *p, int n)
+{
+  return cons((node*)NODE_BACK_REF, nint(n));
+}
+
+/* (:nthref . n) */
+static node*
+new_nth_ref(parser_state *p, int n)
+{
+  return cons((node*)NODE_NTH_REF, nint(n));
+}
+
+/* (:heredoc . a) */
+static node*
+new_heredoc(parser_state *p)
+{
+  parser_heredoc_info *inf = (parser_heredoc_info *)parser_palloc(p, sizeof(parser_heredoc_info));
+  return cons((node*)NODE_HEREDOC, (node*)inf);
+}
+
+static void
+new_bv(parser_state *p, mrb_sym id)
+{
+}
+
+static node*
+new_literal_delim(parser_state *p)
+{
+  return cons((node*)NODE_LITERAL_DELIM, 0);
+}
+
+/* (:words . a) */
+static node*
+new_words(parser_state *p, node *a)
+{
+  return cons((node*)NODE_WORDS, a);
+}
+
+/* (:symbols . a) */
+static node*
+new_symbols(parser_state *p, node *a)
+{
+  return cons((node*)NODE_SYMBOLS, a);
+}
+
+/* xxx ----------------------------- */
+
+/* (:call a op) */
+static node*
+call_uni_op(parser_state *p, node *recv, const char *m)
+{
+  void_expr_error(p, recv);
+  return new_call(p, recv, intern_cstr(m), 0, 1);
+}
+
+/* (:call a op b) */
+static node*
+call_bin_op(parser_state *p, node *recv, const char *m, node *arg1)
+{
+  return new_call(p, recv, intern_cstr(m), list1(list1(arg1)), 1);
+}
+
+static void
+args_with_block(parser_state *p, node *a, node *b)
+{
+  if (b) {
+    if (a->cdr) {
+      yyerror(p, "both block arg and actual block given");
+    }
+    a->cdr = b;
+  }
+}
+
+static void
+call_with_block(parser_state *p, node *a, node *b)
+{
+  node *n;
+
+  switch ((enum node_type)intn(a->car)) {
+  case NODE_SUPER:
+  case NODE_ZSUPER:
+    if (!a->cdr) a->cdr = cons(0, b);
+    else {
+      args_with_block(p, a->cdr, b);
+    }
+    break;
+  case NODE_CALL:
+  case NODE_FCALL:
+  case NODE_SCALL:
+    n = a->cdr->cdr->cdr;
+    if (!n->car) n->car = cons(0, b);
+    else {
+      args_with_block(p, n->car, b);
+    }
+    break;
+  default:
+    break;
+  }
+}
+
+static node*
+negate_lit(parser_state *p, node *n)
+{
+  return cons((node*)NODE_NEGATE, n);
+}
+
+static node*
+cond(node *n)
+{
+  return n;
+}
+
+static node*
+ret_args(parser_state *p, node *n)
+{
+  if (n->cdr) {
+    yyerror(p, "block argument should not be given");
+    return NULL;
+  }
+  if (!n->car->cdr) return n->car->car;
+  return new_array(p, n->car);
+}
+
+static void
+assignable(parser_state *p, node *lhs)
+{
+  if (intn(lhs->car) == NODE_LVAR) {
+    local_add(p, sym(lhs->cdr));
+  }
+}
+
+static node*
+var_reference(parser_state *p, node *lhs)
+{
+  node *n;
+
+  if (intn(lhs->car) == NODE_LVAR) {
+    if (!local_var_p(p, sym(lhs->cdr))) {
+      n = new_fcall(p, sym(lhs->cdr), 0);
+      cons_free(lhs);
+      return n;
+    }
+  }
+
+  return lhs;
+}
+
+typedef enum mrb_string_type  string_type;
+
+static node*
+new_strterm(parser_state *p, string_type type, int term, int paren)
+{
+  return cons(nint(type), cons((node*)0, cons(nint(paren), nint(term))));
+}
+
+static void
+end_strterm(parser_state *p)
+{
+  cons_free(p->lex_strterm->cdr->cdr);
+  cons_free(p->lex_strterm->cdr);
+  cons_free(p->lex_strterm);
+  p->lex_strterm = NULL;
+}
+
+static parser_heredoc_info *
+parsing_heredoc_inf(parser_state *p)
+{
+  node *nd = p->parsing_heredoc;
+  if (nd == NULL)
+    return NULL;
+  /* mrb_assert(nd->car->car == NODE_HEREDOC); */
+  return (parser_heredoc_info*)nd->car->cdr;
+}
+
+static void
+heredoc_treat_nextline(parser_state *p)
+{
+  if (p->heredocs_from_nextline == NULL)
+    return;
+  if (p->parsing_heredoc == NULL) {
+    node *n;
+    p->parsing_heredoc = p->heredocs_from_nextline;
+    p->lex_strterm_before_heredoc = p->lex_strterm;
+    p->lex_strterm = new_strterm(p, parsing_heredoc_inf(p)->type, 0, 0);
+    n = p->all_heredocs;
+    if (n) {
+      while (n->cdr)
+        n = n->cdr;
+      n->cdr = p->parsing_heredoc;
+    }
+    else {
+      p->all_heredocs = p->parsing_heredoc;
+    }
+  }
+  else {
+    node *n, *m;
+    m = p->heredocs_from_nextline;
+    while (m->cdr)
+      m = m->cdr;
+    n = p->all_heredocs;
+    mrb_assert(n != NULL);
+    if (n == p->parsing_heredoc) {
+      m->cdr = n;
+      p->all_heredocs = p->heredocs_from_nextline;
+      p->parsing_heredoc = p->heredocs_from_nextline;
+    }
+    else {
+      while (n->cdr != p->parsing_heredoc) {
+        n = n->cdr;
+        mrb_assert(n != NULL);
+      }
+      m->cdr = n->cdr;
+      n->cdr = p->heredocs_from_nextline;
+      p->parsing_heredoc = p->heredocs_from_nextline;
+    }
+  }
+  p->heredocs_from_nextline = NULL;
+}
+
+static void
+heredoc_end(parser_state *p)
+{
+  p->parsing_heredoc = p->parsing_heredoc->cdr;
+  if (p->parsing_heredoc == NULL) {
+    p->lstate = EXPR_BEG;
+    p->cmd_start = TRUE;
+    end_strterm(p);
+    p->lex_strterm = p->lex_strterm_before_heredoc;
+    p->lex_strterm_before_heredoc = NULL;
+    p->heredoc_end_now = TRUE;
+  }
+  else {
+    /* next heredoc */
+    p->lex_strterm->car = nint(parsing_heredoc_inf(p)->type);
+  }
+}
+#define is_strterm_type(p,str_func) (intn((p)->lex_strterm->car) & (str_func))
+
+/* xxx ----------------------------- */
+
+%}
+
+%pure-parser
+%parse-param {parser_state *p}
+%lex-param {parser_state *p}
+
+%union {
+    node *nd;
+    mrb_sym id;
+    int num;
+    stack_type stack;
+    const struct vtable *vars;
+}
+
+%token <num>
+        keyword_class
+        keyword_module
+        keyword_def
+        keyword_begin
+        keyword_if
+        keyword_unless
+        keyword_while
+        keyword_until
+        keyword_for
+
+%token
+        keyword_undef
+        keyword_rescue
+        keyword_ensure
+        keyword_end
+        keyword_then
+        keyword_elsif
+        keyword_else
+        keyword_case
+        keyword_when
+        keyword_break
+        keyword_next
+        keyword_redo
+        keyword_retry
+        keyword_in
+        keyword_do
+        keyword_do_cond
+        keyword_do_block
+        keyword_do_LAMBDA
+        keyword_return
+        keyword_yield
+        keyword_super
+        keyword_self
+        keyword_nil
+        keyword_true
+        keyword_false
+        keyword_and
+        keyword_or
+        keyword_not
+        modifier_if
+        modifier_unless
+        modifier_while
+        modifier_until
+        modifier_rescue
+        keyword_alias
+        keyword_BEGIN
+        keyword_END
+        keyword__LINE__
+        keyword__FILE__
+        keyword__ENCODING__
+
+%token <id>  tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL
+%token <nd>  tINTEGER tFLOAT tCHAR tXSTRING tREGEXP
+%token <nd>  tSTRING tSTRING_PART tSTRING_MID tLABEL_END
+%token <nd>  tNTH_REF tBACK_REF
+%token <num> tREGEXP_END
+
+%type <nd> singleton string string_rep string_interp xstring regexp
+%type <nd> literal numeric cpath symbol
+%type <nd> top_compstmt top_stmts top_stmt
+%type <nd> bodystmt compstmt stmts stmt expr arg primary command command_call method_call
+%type <nd> expr_value arg_rhs primary_value
+%type <nd> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
+%type <nd> args call_args opt_call_args
+%type <nd> paren_args opt_paren_args variable
+%type <nd> command_args aref_args opt_block_arg block_arg var_ref var_lhs
+%type <nd> command_asgn command_rhs mrhs superclass block_call block_command
+%type <nd> f_block_optarg f_block_opt
+%type <nd> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
+%type <nd> assoc_list assocs assoc undef_list backref for_var
+%type <nd> block_param opt_block_param block_param_def f_opt
+%type <nd> bv_decls opt_bv_decl bvar f_larglist lambda_body
+%type <nd> brace_block cmd_brace_block do_block lhs none f_bad_arg
+%type <nd> mlhs mlhs_list mlhs_post mlhs_basic mlhs_item mlhs_node mlhs_inner
+%type <id> fsym sym basic_symbol operation operation2 operation3
+%type <id> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_opt_asgn
+%type <nd> heredoc words symbols
+%type <num> call_op call_op2     /* 0:'&.', 1:'.', 2:'::' */
+
+%token tUPLUS             /* unary+ */
+%token tUMINUS            /* unary- */
+%token tPOW               /* ** */
+%token tCMP               /* <=> */
+%token tEQ                /* == */
+%token tEQQ               /* === */
+%token tNEQ               /* != */
+%token tGEQ               /* >= */
+%token tLEQ               /* <= */
+%token tANDOP tOROP       /* && and || */
+%token tMATCH tNMATCH     /* =~ and !~ */
+%token tDOT2 tDOT3        /* .. and ... */
+%token tAREF tASET        /* [] and []= */
+%token tLSHFT tRSHFT      /* << and >> */
+%token tCOLON2            /* :: */
+%token tCOLON3            /* :: at EXPR_BEG */
+%token <id> tOP_ASGN      /* +=, -=  etc. */
+%token tASSOC             /* => */
+%token tLPAREN            /* ( */
+%token tLPAREN_ARG        /* ( */
+%token tRPAREN            /* ) */
+%token tLBRACK            /* [ */
+%token tLBRACE            /* { */
+%token tLBRACE_ARG        /* { */
+%token tSTAR              /* * */
+%token tAMPER             /* & */
+%token tLAMBDA            /* -> */
+%token tANDDOT            /* &. */
+%token tSYMBEG tREGEXP_BEG tWORDS_BEG tSYMBOLS_BEG
+%token tSTRING_BEG tXSTRING_BEG tSTRING_DVAR tLAMBEG
+%token <nd> tHEREDOC_BEG  /* <<, <<- */
+%token tHEREDOC_END tLITERAL_DELIM tHD_LITERAL_DELIM
+%token <nd> tHD_STRING_PART tHD_STRING_MID
+
+/*
+ * precedence table
+ */
+
+%nonassoc tLOWEST
+%nonassoc tLBRACE_ARG
+
+%nonassoc  modifier_if modifier_unless modifier_while modifier_until
+%left  keyword_or keyword_and
+%right keyword_not
+%right '=' tOP_ASGN
+%left modifier_rescue
+%right '?' ':'
+%nonassoc tDOT2 tDOT3
+%left  tOROP
+%left  tANDOP
+%nonassoc  tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
+%left  '>' tGEQ '<' tLEQ
+%left  '|' '^'
+%left  '&'
+%left  tLSHFT tRSHFT
+%left  '+' '-'
+%left  '*' '/' '%'
+%right tUMINUS_NUM tUMINUS
+%right tPOW
+%right '!' '~' tUPLUS
+
+%token tLAST_TOKEN
+
+%%
+program         :   {
+                      p->lstate = EXPR_BEG;
+                      if (!p->locals) p->locals = cons(0,0);
+                    }
+                  top_compstmt
+                    {
+                      p->tree = new_scope(p, $2);
+                      NODE_LINENO(p->tree, $2);
+                    }
+                ;
+
+top_compstmt    : top_stmts opt_terms
+                    {
+                      $$ = $1;
+                    }
+                ;
+
+top_stmts       : none
+                    {
+                      $$ = new_begin(p, 0);
+                    }
+                | top_stmt
+                    {
+                      $$ = new_begin(p, $1);
+                      NODE_LINENO($$, $1);
+                    }
+                | top_stmts terms top_stmt
+                    {
+                      $$ = push($1, newline_node($3));
+                    }
+                | error top_stmt
+                    {
+                      $$ = new_begin(p, 0);
+                    }
+                ;
+
+top_stmt        : stmt
+                | keyword_BEGIN
+                    {
+                      $<nd>$ = local_switch(p);
+                    }
+                  '{' top_compstmt '}'
+                    {
+                      yyerror(p, "BEGIN not supported");
+                      local_resume(p, $<nd>2);
+                      $$ = 0;
+                    }
+                ;
+
+bodystmt        : compstmt
+                  opt_rescue
+                  opt_else
+                  opt_ensure
+                    {
+                      if ($2) {
+                        $$ = new_rescue(p, $1, $2, $3);
+                        NODE_LINENO($$, $1);
+                      }
+                      else if ($3) {
+                        yywarn(p, "else without rescue is useless");
+                        $$ = push($1, $3);
+                      }
+                      else {
+                        $$ = $1;
+                      }
+                      if ($4) {
+                        if ($$) {
+                          $$ = new_ensure(p, $$, $4);
+                        }
+                        else {
+                          $$ = push($4, new_nil(p));
+                        }
+                      }
+                    }
+                ;
+
+compstmt        : stmts opt_terms
+                    {
+                      $$ = $1;
+                    }
+                ;
+
+stmts           : none
+                    {
+                      $$ = new_begin(p, 0);
+                    }
+                | stmt
+                    {
+                      $$ = new_begin(p, $1);
+                      NODE_LINENO($$, $1);
+                    }
+                | stmts terms stmt
+                    {
+                      $$ = push($1, newline_node($3));
+                    }
+                | error stmt
+                    {
+                      $$ = new_begin(p, $2);
+                    }
+                ;
+
+stmt            : keyword_alias fsym {p->lstate = EXPR_FNAME;} fsym
+                    {
+                      $$ = new_alias(p, $2, $4);
+                    }
+                | keyword_undef undef_list
+                    {
+                      $$ = $2;
+                    }
+                | stmt modifier_if expr_value
+                    {
+                      $$ = new_if(p, cond($3), $1, 0);
+                    }
+                | stmt modifier_unless expr_value
+                    {
+                      $$ = new_unless(p, cond($3), $1, 0);
+                    }
+                | stmt modifier_while expr_value
+                    {
+                      $$ = new_while(p, cond($3), $1);
+                    }
+                | stmt modifier_until expr_value
+                    {
+                      $$ = new_until(p, cond($3), $1);
+                    }
+                | stmt modifier_rescue stmt
+                    {
+                      $$ = new_mod_rescue(p, $1, $3);
+                    }
+                | keyword_END '{' compstmt '}'
+                    {
+                      yyerror(p, "END not supported");
+                      $$ = new_postexe(p, $3);
+                    }
+                | command_asgn
+                | mlhs '=' command_call
+                    {
+                      $$ = new_masgn(p, $1, $3);
+                    }
+                | lhs '=' mrhs
+                    {
+                      $$ = new_asgn(p, $1, new_array(p, $3));
+                    }
+                | mlhs '=' arg
+                    {
+                      $$ = new_masgn(p, $1, $3);
+                    }
+                | mlhs '=' mrhs
+                    {
+                      $$ = new_masgn(p, $1, new_array(p, $3));
+                    }
+                | expr
+                ;
+
+command_asgn    : lhs '=' command_rhs
+                    {
+                      $$ = new_asgn(p, $1, $3);
+                    }
+                | var_lhs tOP_ASGN command_rhs
+                    {
+                      $$ = new_op_asgn(p, $1, $2, $3);
+                    }
+                | primary_value '[' opt_call_args rbracket tOP_ASGN command_rhs
+                    {
+                      $$ = new_op_asgn(p, new_call(p, $1, intern("[]",2), $3, '.'), $5, $6);
+                    }
+                | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
+                    {
+                      $$ = new_op_asgn(p, new_call(p, $1, $3, 0, $2), $4, $5);
+                    }
+                | primary_value call_op tCONSTANT tOP_ASGN command_rhs
+                    {
+                      $$ = new_op_asgn(p, new_call(p, $1, $3, 0, $2), $4, $5);
+                    }
+                | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
+                    {
+                      yyerror(p, "constant re-assignment");
+                      $$ = 0;
+                    }
+                | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
+                    {
+                      $$ = new_op_asgn(p, new_call(p, $1, $3, 0, tCOLON2), $4, $5);
+                    }
+                | backref tOP_ASGN command_rhs
+                    {
+                      backref_error(p, $1);
+                      $$ = new_begin(p, 0);
+                    }
+		;
+
+command_rhs     : command_call   %prec tOP_ASGN
+                | command_call modifier_rescue stmt
+                    {
+                      $$ = new_mod_rescue(p, $1, $3);
+                    }
+                | command_asgn
+                ;
+
+
+expr            : command_call
+                | expr keyword_and expr
+                    {
+                      $$ = new_and(p, $1, $3);
+                    }
+                | expr keyword_or expr
+                    {
+                      $$ = new_or(p, $1, $3);
+                    }
+                | keyword_not opt_nl expr
+                    {
+                      $$ = call_uni_op(p, cond($3), "!");
+                    }
+                | '!' command_call
+                    {
+                      $$ = call_uni_op(p, cond($2), "!");
+                    }
+                | arg
+                ;
+
+expr_value      : expr
+                    {
+                      if (!$1) $$ = new_nil(p);
+                      else {
+                        $$ = $1;
+                      }
+                    }
+                ;
+
+command_call    : command
+                | block_command
+                ;
+
+block_command   : block_call
+                | block_call call_op2 operation2 command_args
+                    {
+                      $$ = new_call(p, $1, $3, $4, $2);
+                    }
+                ;
+
+cmd_brace_block : tLBRACE_ARG
+                    {
+                      local_nest(p);
+                    }
+                  opt_block_param
+                  compstmt
+                  '}'
+                    {
+                      $$ = new_block(p, $3, $4);
+                      local_unnest(p);
+                    }
+                ;
+
+command         : operation command_args       %prec tLOWEST
+                    {
+                      $$ = new_fcall(p, $1, $2);
+                    }
+                | operation command_args cmd_brace_block
+                    {
+                      args_with_block(p, $2, $3);
+                      $$ = new_fcall(p, $1, $2);
+                    }
+                | primary_value call_op operation2 command_args     %prec tLOWEST
+                    {
+                      $$ = new_call(p, $1, $3, $4, $2);
+                    }
+                | primary_value call_op operation2 command_args cmd_brace_block
+                    {
+                      args_with_block(p, $4, $5);
+                      $$ = new_call(p, $1, $3, $4, $2);
+                   }
+                | primary_value tCOLON2 operation2 command_args %prec tLOWEST
+                    {
+                      $$ = new_call(p, $1, $3, $4, tCOLON2);
+                    }
+                | primary_value tCOLON2 operation2 command_args cmd_brace_block
+                    {
+                      args_with_block(p, $4, $5);
+                      $$ = new_call(p, $1, $3, $4, tCOLON2);
+                    }
+                | keyword_super command_args
+                    {
+                      $$ = new_super(p, $2);
+                    }
+                | keyword_yield command_args
+                    {
+                      $$ = new_yield(p, $2);
+                    }
+                | keyword_return call_args
+                    {
+                      $$ = new_return(p, ret_args(p, $2));
+                    }
+                | keyword_break call_args
+                    {
+                      $$ = new_break(p, ret_args(p, $2));
+                    }
+                | keyword_next call_args
+                    {
+                      $$ = new_next(p, ret_args(p, $2));
+                    }
+                ;
+
+mlhs            : mlhs_basic
+                    {
+                      $$ = $1;
+                    }
+                | tLPAREN mlhs_inner rparen
+                    {
+                      $$ = $2;
+                    }
+                ;
+
+mlhs_inner      : mlhs_basic
+                | tLPAREN mlhs_inner rparen
+                    {
+                      $$ = $2;
+                    }
+                ;
+
+mlhs_basic      : mlhs_list
+                    {
+                      $$ = list1($1);
+                    }
+                | mlhs_list mlhs_item
+                    {
+                      $$ = list1(push($1,$2));
+                    }
+                | mlhs_list tSTAR mlhs_node
+                    {
+                      $$ = list2($1, $3);
+                    }
+                | mlhs_list tSTAR mlhs_node ',' mlhs_post
+                    {
+                      $$ = list3($1, $3, $5);
+                    }
+                | mlhs_list tSTAR
+                    {
+                      $$ = list2($1, new_nil(p));
+                    }
+                | mlhs_list tSTAR ',' mlhs_post
+                    {
+                      $$ = list3($1, new_nil(p), $4);
+                    }
+                | tSTAR mlhs_node
+                    {
+                      $$ = list2(0, $2);
+                    }
+                | tSTAR mlhs_node ',' mlhs_post
+                    {
+                      $$ = list3(0, $2, $4);
+                    }
+                | tSTAR
+                    {
+                      $$ = list2(0, new_nil(p));
+                    }
+                | tSTAR ',' mlhs_post
+                    {
+                      $$ = list3(0, new_nil(p), $3);
+                    }
+                ;
+
+mlhs_item       : mlhs_node
+                | tLPAREN mlhs_inner rparen
+                    {
+                      $$ = new_masgn(p, $2, NULL);
+                    }
+                ;
+
+mlhs_list       : mlhs_item ','
+                    {
+                      $$ = list1($1);
+                    }
+                | mlhs_list mlhs_item ','
+                    {
+                      $$ = push($1, $2);
+                    }
+                ;
+
+mlhs_post       : mlhs_item
+                    {
+                      $$ = list1($1);
+                    }
+                | mlhs_list mlhs_item
+                    {
+                      $$ = push($1, $2);
+                    }
+                ;
+
+mlhs_node       : variable
+                    {
+                      assignable(p, $1);
+                    }
+                | primary_value '[' opt_call_args rbracket
+                    {
+                      $$ = new_call(p, $1, intern("[]",2), $3, '.');
+                    }
+                | primary_value call_op tIDENTIFIER
+                    {
+                      $$ = new_call(p, $1, $3, 0, $2);
+                    }
+                | primary_value tCOLON2 tIDENTIFIER
+                    {
+                      $$ = new_call(p, $1, $3, 0, tCOLON2);
+                    }
+                | primary_value call_op tCONSTANT
+                    {
+                      $$ = new_call(p, $1, $3, 0, $2);
+                    }
+                | primary_value tCOLON2 tCONSTANT
+                    {
+                      if (p->in_def || p->in_single)
+                        yyerror(p, "dynamic constant assignment");
+                      $$ = new_colon2(p, $1, $3);
+                    }
+                | tCOLON3 tCONSTANT
+                    {
+                      if (p->in_def || p->in_single)
+                        yyerror(p, "dynamic constant assignment");
+                      $$ = new_colon3(p, $2);
+                    }
+                | backref
+                    {
+                      backref_error(p, $1);
+                      $$ = 0;
+                    }
+                ;
+
+lhs             : variable
+                    {
+                      assignable(p, $1);
+                    }
+                | primary_value '[' opt_call_args rbracket
+                    {
+                      $$ = new_call(p, $1, intern("[]",2), $3, '.');
+                    }
+                | primary_value call_op tIDENTIFIER
+                    {
+                      $$ = new_call(p, $1, $3, 0, $2);
+                    }
+                | primary_value tCOLON2 tIDENTIFIER
+                    {
+                      $$ = new_call(p, $1, $3, 0, tCOLON2);
+                    }
+                | primary_value call_op tCONSTANT
+                    {
+                      $$ = new_call(p, $1, $3, 0, $2);
+                    }
+                | primary_value tCOLON2 tCONSTANT
+                    {
+                      if (p->in_def || p->in_single)
+                        yyerror(p, "dynamic constant assignment");
+                      $$ = new_colon2(p, $1, $3);
+                    }
+                | tCOLON3 tCONSTANT
+                    {
+                      if (p->in_def || p->in_single)
+                        yyerror(p, "dynamic constant assignment");
+                      $$ = new_colon3(p, $2);
+                    }
+                | backref
+                    {
+                      backref_error(p, $1);
+                      $$ = 0;
+                    }
+                ;
+
+cname           : tIDENTIFIER
+                    {
+                      yyerror(p, "class/module name must be CONSTANT");
+                    }
+                | tCONSTANT
+                ;
+
+cpath           : tCOLON3 cname
+                    {
+                      $$ = cons((node*)1, nsym($2));
+                    }
+                | cname
+                    {
+                      $$ = cons((node*)0, nsym($1));
+                    }
+                | primary_value tCOLON2 cname
+                    {
+                      void_expr_error(p, $1);
+                      $$ = cons($1, nsym($3));
+                    }
+                ;
+
+fname           : tIDENTIFIER
+                | tCONSTANT
+                | tFID
+                | op
+                    {
+                      p->lstate = EXPR_ENDFN;
+                      $$ = $1;
+                    }
+                | reswords
+                    {
+                      p->lstate = EXPR_ENDFN;
+                      $$ = $<id>1;
+                    }
+                ;
+
+fsym            : fname
+                | basic_symbol
+                ;
+
+undef_list      : fsym
+                    {
+                      $$ = new_undef(p, $1);
+                    }
+                | undef_list ',' {p->lstate = EXPR_FNAME;} fsym
+                    {
+                      $$ = push($1, nsym($4));
+                    }
+                ;
+
+op              : '|'           { $$ = intern_c('|');   }
+                | '^'           { $$ = intern_c('^');   }
+                | '&'           { $$ = intern_c('&');   }
+                | tCMP          { $$ = intern("<=>",3); }
+                | tEQ           { $$ = intern("==",2);  }
+                | tEQQ          { $$ = intern("===",3); }
+                | tMATCH        { $$ = intern("=~",2);  }
+                | tNMATCH       { $$ = intern("!~",2);  }
+                | '>'           { $$ = intern_c('>');   }
+                | tGEQ          { $$ = intern(">=",2);  }
+                | '<'           { $$ = intern_c('<');   }
+                | tLEQ          { $$ = intern("<=",2);  }
+                | tNEQ          { $$ = intern("!=",2);  }
+                | tLSHFT        { $$ = intern("<<",2);  }
+                | tRSHFT        { $$ = intern(">>",2);  }
+                | '+'           { $$ = intern_c('+');   }
+                | '-'           { $$ = intern_c('-');   }
+                | '*'           { $$ = intern_c('*');   }
+                | tSTAR         { $$ = intern_c('*');   }
+                | '/'           { $$ = intern_c('/');   }
+                | '%'           { $$ = intern_c('%');   }
+                | tPOW          { $$ = intern("**",2);  }
+                | '!'           { $$ = intern_c('!');   }
+                | '~'           { $$ = intern_c('~');   }
+                | tUPLUS        { $$ = intern("+@",2);  }
+                | tUMINUS       { $$ = intern("-@",2);  }
+                | tAREF         { $$ = intern("[]",2);  }
+                | tASET         { $$ = intern("[]=",3); }
+                | '`'           { $$ = intern_c('`');   }
+                ;
+
+reswords        : keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
+                | keyword_BEGIN | keyword_END
+                | keyword_alias | keyword_and | keyword_begin
+                | keyword_break | keyword_case | keyword_class | keyword_def
+                | keyword_do | keyword_else | keyword_elsif
+                | keyword_end | keyword_ensure | keyword_false
+                | keyword_for | keyword_in | keyword_module | keyword_next
+                | keyword_nil | keyword_not | keyword_or | keyword_redo
+                | keyword_rescue | keyword_retry | keyword_return | keyword_self
+                | keyword_super | keyword_then | keyword_true | keyword_undef
+                | keyword_when | keyword_yield | keyword_if | keyword_unless
+                | keyword_while | keyword_until
+                ;
+
+arg             : lhs '=' arg_rhs
+                    {
+                      $$ = new_asgn(p, $1, $3);
+                    }
+                | var_lhs tOP_ASGN arg_rhs
+                    {
+                      $$ = new_op_asgn(p, $1, $2, $3);
+                    }
+                | primary_value '[' opt_call_args rbracket tOP_ASGN arg_rhs
+                    {
+                      $$ = new_op_asgn(p, new_call(p, $1, intern("[]",2), $3, '.'), $5, $6);
+                    }
+                | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
+                    {
+                      $$ = new_op_asgn(p, new_call(p, $1, $3, 0, $2), $4, $5);
+                    }
+                | primary_value call_op tCONSTANT tOP_ASGN arg_rhs
+                    {
+                      $$ = new_op_asgn(p, new_call(p, $1, $3, 0, $2), $4, $5);
+                    }
+                | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
+                    {
+                      $$ = new_op_asgn(p, new_call(p, $1, $3, 0, tCOLON2), $4, $5);
+                    }
+                | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
+                    {
+                      yyerror(p, "constant re-assignment");
+                      $$ = new_begin(p, 0);
+                    }
+                | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
+                    {
+                      yyerror(p, "constant re-assignment");
+                      $$ = new_begin(p, 0);
+                    }
+                | backref tOP_ASGN arg_rhs
+                    {
+                      backref_error(p, $1);
+                      $$ = new_begin(p, 0);
+                    }
+                | arg tDOT2 arg
+                    {
+                      $$ = new_dot2(p, $1, $3);
+                    }
+                | arg tDOT3 arg
+                    {
+                      $$ = new_dot3(p, $1, $3);
+                    }
+                | arg '+' arg
+                    {
+                      $$ = call_bin_op(p, $1, "+", $3);
+                    }
+                | arg '-' arg
+                    {
+                      $$ = call_bin_op(p, $1, "-", $3);
+                    }
+                | arg '*' arg
+                    {
+                      $$ = call_bin_op(p, $1, "*", $3);
+                    }
+                | arg '/' arg
+                    {
+                      $$ = call_bin_op(p, $1, "/", $3);
+                    }
+                | arg '%' arg
+                    {
+                      $$ = call_bin_op(p, $1, "%", $3);
+                    }
+                | arg tPOW arg
+                    {
+                      $$ = call_bin_op(p, $1, "**", $3);
+                    }
+                | tUMINUS_NUM tINTEGER tPOW arg
+                    {
+                      $$ = call_uni_op(p, call_bin_op(p, $2, "**", $4), "-@");
+                    }
+                | tUMINUS_NUM tFLOAT tPOW arg
+                    {
+                      $$ = call_uni_op(p, call_bin_op(p, $2, "**", $4), "-@");
+                    }
+                | tUPLUS arg
+                    {
+                      $$ = call_uni_op(p, $2, "+@");
+                    }
+                | tUMINUS arg
+                    {
+                      $$ = call_uni_op(p, $2, "-@");
+                    }
+                | arg '|' arg
+                    {
+                      $$ = call_bin_op(p, $1, "|", $3);
+                    }
+                | arg '^' arg
+                    {
+                      $$ = call_bin_op(p, $1, "^", $3);
+                    }
+                | arg '&' arg
+                    {
+                      $$ = call_bin_op(p, $1, "&", $3);
+                    }
+                | arg tCMP arg
+                    {
+                      $$ = call_bin_op(p, $1, "<=>", $3);
+                    }
+                | arg '>' arg
+                    {
+                      $$ = call_bin_op(p, $1, ">", $3);
+                    }
+                | arg tGEQ arg
+                    {
+                      $$ = call_bin_op(p, $1, ">=", $3);
+                    }
+                | arg '<' arg
+                    {
+                      $$ = call_bin_op(p, $1, "<", $3);
+                    }
+                | arg tLEQ arg
+                    {
+                      $$ = call_bin_op(p, $1, "<=", $3);
+                    }
+                | arg tEQ arg
+                    {
+                      $$ = call_bin_op(p, $1, "==", $3);
+                    }
+                | arg tEQQ arg
+                    {
+                      $$ = call_bin_op(p, $1, "===", $3);
+                    }
+                | arg tNEQ arg
+                    {
+                      $$ = call_bin_op(p, $1, "!=", $3);
+                    }
+                | arg tMATCH arg
+                    {
+                      $$ = call_bin_op(p, $1, "=~", $3);
+                    }
+                | arg tNMATCH arg
+                    {
+                      $$ = call_bin_op(p, $1, "!~", $3);
+                    }
+                | '!' arg
+                    {
+                      $$ = call_uni_op(p, cond($2), "!");
+                    }
+                | '~' arg
+                    {
+                      $$ = call_uni_op(p, cond($2), "~");
+                    }
+                | arg tLSHFT arg
+                    {
+                      $$ = call_bin_op(p, $1, "<<", $3);
+                    }
+                | arg tRSHFT arg
+                    {
+                      $$ = call_bin_op(p, $1, ">>", $3);
+                    }
+                | arg tANDOP arg
+                    {
+                      $$ = new_and(p, $1, $3);
+                    }
+                | arg tOROP arg
+                    {
+                      $$ = new_or(p, $1, $3);
+                    }
+                | arg '?' arg opt_nl ':' arg
+                    {
+                      $$ = new_if(p, cond($1), $3, $6);
+                    }
+                | primary
+                    {
+                      $$ = $1;
+                    }
+                ;
+
+aref_args       : none
+                | args trailer
+                    {
+                      $$ = $1;
+                      NODE_LINENO($$, $1);
+                    }
+                | args comma assocs trailer
+                    {
+                      $$ = push($1, new_hash(p, $3));
+                    }
+                | assocs trailer
+                    {
+                      $$ = cons(new_hash(p, $1), 0);
+                      NODE_LINENO($$, $1);
+                    }
+                ;
+
+arg_rhs         : arg %prec tOP_ASGN
+                    {
+                      $$ = $1;
+                    }
+                | arg modifier_rescue arg
+                    {
+                      void_expr_error(p, $1);
+                      void_expr_error(p, $3);
+                      $$ = new_mod_rescue(p, $1, $3);
+                    }
+                ;
+
+paren_args      : '(' opt_call_args rparen
+                    {
+                      $$ = $2;
+                    }
+                ;
+
+opt_paren_args  : none
+                | paren_args
+                ;
+
+opt_call_args   : none
+                | call_args
+                | args ','
+                    {
+                      $$ = cons($1,0);
+                      NODE_LINENO($$, $1);
+                    }
+                | args comma assocs ','
+                    {
+                      $$ = cons(push($1, new_hash(p, $3)), 0);
+                      NODE_LINENO($$, $1);
+                    }
+                | assocs ','
+                    {
+                      $$ = cons(list1(new_hash(p, $1)), 0);
+                      NODE_LINENO($$, $1);
+                    }
+                ;
+
+call_args       : command
+                    {
+                      void_expr_error(p, $1);
+                      $$ = cons(list1($1), 0);
+                      NODE_LINENO($$, $1);
+                    }
+                | args opt_block_arg
+                    {
+                      $$ = cons($1, $2);
+                      NODE_LINENO($$, $1);
+                    }
+                | assocs opt_block_arg
+                    {
+                      $$ = cons(list1(new_hash(p, $1)), $2);
+                      NODE_LINENO($$, $1);
+                    }
+                | args comma assocs opt_block_arg
+                    {
+                      $$ = cons(push($1, new_hash(p, $3)), $4);
+                      NODE_LINENO($$, $1);
+                    }
+                | block_arg
+                    {
+                      $$ = cons(0, $1);
+                      NODE_LINENO($$, $1);
+                    }
+                ;
+
+command_args    :  {
+                      $<stack>$ = p->cmdarg_stack;
+                      CMDARG_PUSH(1);
+                    }
+                  call_args
+                    {
+                      p->cmdarg_stack = $<stack>1;
+                      $$ = $2;
+                    }
+                ;
+
+block_arg       : tAMPER arg
+                    {
+                      $$ = new_block_arg(p, $2);
+                    }
+                ;
+
+opt_block_arg   : comma block_arg
+                    {
+                      $$ = $2;
+                    }
+                | none
+                    {
+                      $$ = 0;
+                    }
+                ;
+
+comma           : ','
+                | ','  heredoc_bodies
+                ;
+
+args            : arg
+                    {
+                      void_expr_error(p, $1);
+                      $$ = cons($1, 0);
+                      NODE_LINENO($$, $1);
+                    }
+                | tSTAR arg
+                    {
+                      void_expr_error(p, $2);
+                      $$ = cons(new_splat(p, $2), 0);
+                      NODE_LINENO($$, $2);
+                    }
+                | args comma arg
+                    {
+                      void_expr_error(p, $3);
+                      $$ = push($1, $3);
+                    }
+                | args comma tSTAR arg
+                    {
+                      void_expr_error(p, $4);
+                      $$ = push($1, new_splat(p, $4));
+                    }
+                ;
+
+mrhs            : args comma arg
+                    {
+                      void_expr_error(p, $3);
+                      $$ = push($1, $3);
+                    }
+                | args comma tSTAR arg
+                    {
+                      void_expr_error(p, $4);
+                      $$ = push($1, new_splat(p, $4));
+                    }
+                | tSTAR arg
+                    {
+                      void_expr_error(p, $2);
+                      $$ = list1(new_splat(p, $2));
+                    }
+                ;
+
+primary         : literal
+                | string
+                | xstring
+                | regexp
+                | heredoc
+                | var_ref
+                | backref
+                | tFID
+                    {
+                      $$ = new_fcall(p, $1, 0);
+                    }
+                | keyword_begin
+                    {
+                      $<stack>$ = p->cmdarg_stack;
+                      p->cmdarg_stack = 0;
+                    }
+                  bodystmt
+                  keyword_end
+                    {
+                      p->cmdarg_stack = $<stack>2;
+                      $$ = $3;
+                    }
+                | tLPAREN_ARG
+                    {
+                      $<stack>$ = p->cmdarg_stack;
+                      p->cmdarg_stack = 0;
+                    }
+                  stmt {p->lstate = EXPR_ENDARG;} rparen
+                    {
+                      p->cmdarg_stack = $<stack>2;
+                      $$ = $3;
+                    }
+                | tLPAREN_ARG {p->lstate = EXPR_ENDARG;} rparen
+                    {
+                      $$ = new_nil(p);
+                    }
+                | tLPAREN compstmt ')'
+                    {
+                      $$ = $2;
+                    }
+                | primary_value tCOLON2 tCONSTANT
+                    {
+                      $$ = new_colon2(p, $1, $3);
+                    }
+                | tCOLON3 tCONSTANT
+                    {
+                      $$ = new_colon3(p, $2);
+                    }
+                | tLBRACK aref_args ']'
+                    {
+                      $$ = new_array(p, $2);
+                      NODE_LINENO($$, $2);
+                    }
+                | tLBRACE assoc_list '}'
+                    {
+                      $$ = new_hash(p, $2);
+                      NODE_LINENO($$, $2);
+                    }
+                | keyword_return
+                    {
+                      $$ = new_return(p, 0);
+                    }
+                | keyword_yield opt_paren_args
+                    {
+                      $$ = new_yield(p, $2);
+                    }
+                | keyword_not '(' expr rparen
+                    {
+                      $$ = call_uni_op(p, cond($3), "!");
+                    }
+                | keyword_not '(' rparen
+                    {
+                      $$ = call_uni_op(p, new_nil(p), "!");
+                    }
+                | operation brace_block
+                    {
+                      $$ = new_fcall(p, $1, cons(0, $2));
+                    }
+                | method_call
+                | method_call brace_block
+                    {
+                      call_with_block(p, $1, $2);
+                      $$ = $1;
+                    }
+                | tLAMBDA
+                    {
+                      local_nest(p);
+                      $<num>$ = p->lpar_beg;
+                      p->lpar_beg = ++p->paren_nest;
+                    }
+                  f_larglist
+                    {
+                      $<stack>$ = p->cmdarg_stack;
+                      p->cmdarg_stack = 0;
+                    }
+                  lambda_body
+                    {
+                      p->lpar_beg = $<num>2;
+                      $$ = new_lambda(p, $3, $5);
+                      local_unnest(p);
+                      p->cmdarg_stack = $<stack>4;
+                      CMDARG_LEXPOP();
+                    }
+                | keyword_if expr_value then
+                  compstmt
+                  if_tail
+                  keyword_end
+                    {
+                      $$ = new_if(p, cond($2), $4, $5);
+                      SET_LINENO($$, $1);
+                    }
+                | keyword_unless expr_value then
+                  compstmt
+                  opt_else
+                  keyword_end
+                    {
+                      $$ = new_unless(p, cond($2), $4, $5);
+                      SET_LINENO($$, $1);
+                    }
+                | keyword_while {COND_PUSH(1);} expr_value do {COND_POP();}
+                  compstmt
+                  keyword_end
+                    {
+                      $$ = new_while(p, cond($3), $6);
+                      SET_LINENO($$, $1);
+                    }
+                | keyword_until {COND_PUSH(1);} expr_value do {COND_POP();}
+                  compstmt
+                  keyword_end
+                    {
+                      $$ = new_until(p, cond($3), $6);
+                      SET_LINENO($$, $1);
+                    }
+                | keyword_case expr_value opt_terms
+                  case_body
+                  keyword_end
+                    {
+                      $$ = new_case(p, $2, $4);
+                    }
+                | keyword_case opt_terms case_body keyword_end
+                    {
+                      $$ = new_case(p, 0, $3);
+                    }
+                | keyword_for for_var keyword_in
+                  {COND_PUSH(1);}
+                  expr_value do
+                  {COND_POP();}
+                  compstmt
+                  keyword_end
+                    {
+                      $$ = new_for(p, $2, $5, $8);
+                      SET_LINENO($$, $1);
+                    }
+                | keyword_class
+                  cpath superclass
+                    {
+                      if (p->in_def || p->in_single)
+                        yyerror(p, "class definition in method body");
+                      $<nd>$ = local_switch(p);
+                    }
+                  bodystmt
+                  keyword_end
+                    {
+                      $$ = new_class(p, $2, $3, $5);
+                      SET_LINENO($$, $1);
+                      local_resume(p, $<nd>4);
+                    }
+                | keyword_class
+                  tLSHFT expr
+                    {
+                      $<num>$ = p->in_def;
+                      p->in_def = 0;
+                    }
+                  term
+                    {
+                      $<nd>$ = cons(local_switch(p), nint(p->in_single));
+                      p->in_single = 0;
+                    }
+                  bodystmt
+                  keyword_end
+                    {
+                      $$ = new_sclass(p, $3, $7);
+                      SET_LINENO($$, $1);
+                      local_resume(p, $<nd>6->car);
+                      p->in_def = $<num>4;
+                      p->in_single = intn($<nd>6->cdr);
+                    }
+                | keyword_module
+                  cpath
+                    {
+                      if (p->in_def || p->in_single)
+                        yyerror(p, "module definition in method body");
+                      $<nd>$ = local_switch(p);
+                    }
+                  bodystmt
+                  keyword_end
+                    {
+                      $$ = new_module(p, $2, $4);
+                      SET_LINENO($$, $1);
+                      local_resume(p, $<nd>3);
+                    }
+                | keyword_def fname
+                    {
+                      $<stack>$ = p->cmdarg_stack;
+                      p->cmdarg_stack = 0;
+                    }
+                    {
+                      p->in_def++;
+                      $<nd>$ = local_switch(p);
+                    }
+                  f_arglist
+                  bodystmt
+                  keyword_end
+                    {
+                      $$ = new_def(p, $2, $5, $6);
+                      SET_LINENO($$, $1);
+                      local_resume(p, $<nd>4);
+                      p->in_def--;
+                      p->cmdarg_stack = $<stack>3;
+                    }
+                | keyword_def singleton dot_or_colon
+                    {
+                      p->lstate = EXPR_FNAME;
+                      $<stack>$ = p->cmdarg_stack;
+                      p->cmdarg_stack = 0;
+                    }
+                    fname
+                    {
+                      p->in_single++;
+                      p->lstate = EXPR_ENDFN; /* force for args */
+                      $<nd>$ = local_switch(p);
+                    }
+                  f_arglist
+                  bodystmt
+                  keyword_end
+                    {
+                      $$ = new_sdef(p, $2, $5, $7, $8);
+                      SET_LINENO($$, $1);
+                      local_resume(p, $<nd>6);
+                      p->in_single--;
+                      p->cmdarg_stack = $<stack>4;
+                    }
+                | keyword_break
+                    {
+                      $$ = new_break(p, 0);
+                    }
+                | keyword_next
+                    {
+                      $$ = new_next(p, 0);
+                    }
+                | keyword_redo
+                    {
+                      $$ = new_redo(p);
+                    }
+                | keyword_retry
+                    {
+                      $$ = new_retry(p);
+                    }
+                ;
+
+primary_value   : primary
+                    {
+                      $$ = $1;
+                      if (!$$) $$ = new_nil(p);
+                    }
+                ;
+
+then            : term
+                | keyword_then
+                | term keyword_then
+                ;
+
+do              : term
+                | keyword_do_cond
+                ;
+
+if_tail         : opt_else
+                | keyword_elsif expr_value then
+                  compstmt
+                  if_tail
+                    {
+                      $$ = new_if(p, cond($2), $4, $5);
+                    }
+                ;
+
+opt_else        : none
+                | keyword_else compstmt
+                    {
+                      $$ = $2;
+                    }
+                ;
+
+for_var         : lhs
+                    {
+                      $$ = list1(list1($1));
+                    }
+                | mlhs
+                ;
+
+f_marg          : f_norm_arg
+                    {
+                      $$ = new_arg(p, $1);
+                    }
+                | tLPAREN f_margs rparen
+                    {
+                      $$ = new_masgn(p, $2, 0);
+                    }
+                ;
+
+f_marg_list     : f_marg
+                    {
+                      $$ = list1($1);
+                    }
+                | f_marg_list ',' f_marg
+                    {
+                      $$ = push($1, $3);
+                    }
+                ;
+
+f_margs         : f_marg_list
+                    {
+                      $$ = list3($1,0,0);
+                    }
+                | f_marg_list ',' tSTAR f_norm_arg
+                    {
+                      $$ = list3($1, new_arg(p, $4), 0);
+                    }
+                | f_marg_list ',' tSTAR f_norm_arg ',' f_marg_list
+                    {
+                      $$ = list3($1, new_arg(p, $4), $6);
+                    }
+                | f_marg_list ',' tSTAR
+                    {
+                      $$ = list3($1, (node*)-1, 0);
+                    }
+                | f_marg_list ',' tSTAR ',' f_marg_list
+                    {
+                      $$ = list3($1, (node*)-1, $5);
+                    }
+                | tSTAR f_norm_arg
+                    {
+                      $$ = list3(0, new_arg(p, $2), 0);
+                    }
+                | tSTAR f_norm_arg ',' f_marg_list
+                    {
+                      $$ = list3(0, new_arg(p, $2), $4);
+                    }
+                | tSTAR
+                    {
+                      $$ = list3(0, (node*)-1, 0);
+                    }
+                | tSTAR ',' f_marg_list
+                    {
+                      $$ = list3(0, (node*)-1, $3);
+                    }
+                ;
+
+block_param     : f_arg ',' f_block_optarg ',' f_rest_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, $1, $3, $5, 0, $6);
+                    }
+                | f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, $1, $3, $5, $7, $8);
+                    }
+                | f_arg ',' f_block_optarg opt_f_block_arg
+                    {
+                      $$ = new_args(p, $1, $3, 0, 0, $4);
+                    }
+                | f_arg ',' f_block_optarg ',' f_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, $1, $3, 0, $5, $6);
+                    }
+                | f_arg ',' f_rest_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, $1, 0, $3, 0, $4);
+                    }
+                | f_arg ','
+                    {
+                      $$ = new_args(p, $1, 0, 0, 0, 0);
+                    }
+                | f_arg ',' f_rest_arg ',' f_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, $1, 0, $3, $5, $6);
+                    }
+                | f_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, $1, 0, 0, 0, $2);
+                    }
+                | f_block_optarg ',' f_rest_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, 0, $1, $3, 0, $4);
+                    }
+                | f_block_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, 0, $1, $3, $5, $6);
+                    }
+                | f_block_optarg opt_f_block_arg
+                    {
+                      $$ = new_args(p, 0, $1, 0, 0, $2);
+                    }
+                | f_block_optarg ',' f_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, 0, $1, 0, $3, $4);
+                    }
+                | f_rest_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, 0, 0, $1, 0, $2);
+                    }
+                | f_rest_arg ',' f_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, 0, 0, $1, $3, $4);
+                    }
+                | f_block_arg
+                    {
+                      $$ = new_args(p, 0, 0, 0, 0, $1);
+                    }
+                ;
+
+opt_block_param : none
+                | block_param_def
+                    {
+                      p->cmd_start = TRUE;
+                      $$ = $1;
+                    }
+                ;
+
+block_param_def : '|' opt_bv_decl '|'
+                    {
+                      $$ = 0;
+                    }
+                | tOROP
+                    {
+                      $$ = 0;
+                    }
+                | '|' block_param opt_bv_decl '|'
+                    {
+                      $$ = $2;
+                    }
+                ;
+
+
+opt_bv_decl     : opt_nl
+                    {
+                      $$ = 0;
+                    }
+                | opt_nl ';' bv_decls opt_nl
+                    {
+                      $$ = 0;
+                    }
+                ;
+
+bv_decls        : bvar
+                | bv_decls ',' bvar
+                ;
+
+bvar            : tIDENTIFIER
+                    {
+                      local_add_f(p, $1);
+                      new_bv(p, $1);
+                    }
+                | f_bad_arg
+                ;
+
+f_larglist      : '(' f_args opt_bv_decl ')'
+                    {
+                      $$ = $2;
+                    }
+                | f_args
+                    {
+                      $$ = $1;
+                    }
+                ;
+
+lambda_body     : tLAMBEG compstmt '}'
+                    {
+                      $$ = $2;
+                    }
+                | keyword_do_LAMBDA compstmt keyword_end
+                    {
+                      $$ = $2;
+                    }
+                ;
+
+do_block        : keyword_do_block
+                    {
+                      local_nest(p);
+                    }
+                  opt_block_param
+                  compstmt
+                  keyword_end
+                    {
+                      $$ = new_block(p,$3,$4);
+                      local_unnest(p);
+                    }
+                ;
+
+block_call      : command do_block
+                    {
+                      if ($1->car == (node*)NODE_YIELD) {
+                        yyerror(p, "block given to yield");
+                      }
+                      else {
+                        call_with_block(p, $1, $2);
+                      }
+                      $$ = $1;
+                    }
+                | block_call call_op2 operation2 opt_paren_args
+                    {
+                      $$ = new_call(p, $1, $3, $4, $2);
+                    }
+                | block_call call_op2 operation2 opt_paren_args brace_block
+                    {
+                      $$ = new_call(p, $1, $3, $4, $2);
+                      call_with_block(p, $$, $5);
+                    }
+                | block_call call_op2 operation2 command_args do_block
+                    {
+                      $$ = new_call(p, $1, $3, $4, $2);
+                      call_with_block(p, $$, $5);
+                    }
+                ;
+
+method_call     : operation paren_args
+                    {
+                      $$ = new_fcall(p, $1, $2);
+                    }
+                | primary_value call_op operation2 opt_paren_args
+                    {
+                      $$ = new_call(p, $1, $3, $4, $2);
+                    }
+                | primary_value tCOLON2 operation2 paren_args
+                    {
+                      $$ = new_call(p, $1, $3, $4, tCOLON2);
+                    }
+                | primary_value tCOLON2 operation3
+                    {
+                      $$ = new_call(p, $1, $3, 0, tCOLON2);
+                    }
+                | primary_value call_op paren_args
+                    {
+                      $$ = new_call(p, $1, intern("call",4), $3, $2);
+                    }
+                | primary_value tCOLON2 paren_args
+                    {
+                      $$ = new_call(p, $1, intern("call",4), $3, tCOLON2);
+                    }
+                | keyword_super paren_args
+                    {
+                      $$ = new_super(p, $2);
+                    }
+                | keyword_super
+                    {
+                      $$ = new_zsuper(p);
+                    }
+                | primary_value '[' opt_call_args rbracket
+                    {
+                      $$ = new_call(p, $1, intern("[]",2), $3, '.');
+                    }
+                ;
+
+brace_block     : '{'
+                    {
+                      local_nest(p);
+                      $<num>$ = p->lineno;
+                    }
+                  opt_block_param
+                  compstmt '}'
+                    {
+                      $$ = new_block(p,$3,$4);
+                      SET_LINENO($$, $<num>2);
+                      local_unnest(p);
+                    }
+                | keyword_do
+                    {
+                      local_nest(p);
+                      $<num>$ = p->lineno;
+                    }
+                  opt_block_param
+                  compstmt keyword_end
+                    {
+                      $$ = new_block(p,$3,$4);
+                      SET_LINENO($$, $<num>2);
+                      local_unnest(p);
+                    }
+                ;
+
+case_body       : keyword_when args then
+                  compstmt
+                  cases
+                    {
+                      $$ = cons(cons($2, $4), $5);
+                    }
+                ;
+
+cases           : opt_else
+                    {
+                      if ($1) {
+                        $$ = cons(cons(0, $1), 0);
+                      }
+                      else {
+                        $$ = 0;
+                      }
+                    }
+                | case_body
+                ;
+
+opt_rescue      : keyword_rescue exc_list exc_var then
+                  compstmt
+                  opt_rescue
+                    {
+                      $$ = list1(list3($2, $3, $5));
+                      if ($6) $$ = append($$, $6);
+                    }
+                | none
+                ;
+
+exc_list        : arg
+                    {
+                        $$ = list1($1);
+                    }
+                | mrhs
+                | none
+                ;
+
+exc_var         : tASSOC lhs
+                    {
+                      $$ = $2;
+                    }
+                | none
+                ;
+
+opt_ensure      : keyword_ensure compstmt
+                    {
+                      $$ = $2;
+                    }
+                | none
+                ;
+
+literal         : numeric
+                | symbol
+                | words
+                | symbols
+                ;
+
+string          : tCHAR
+                | tSTRING
+                | tSTRING_BEG tSTRING
+                    {
+                      $$ = $2;
+                    }
+                | tSTRING_BEG string_rep tSTRING
+                    {
+                      $$ = new_dstr(p, push($2, $3));
+                    }
+                ;
+
+string_rep      : string_interp
+                | string_rep string_interp
+                    {
+                      $$ = append($1, $2);
+                    }
+                ;
+
+string_interp   : tSTRING_MID
+                    {
+                      $$ = list1($1);
+                    }
+                | tSTRING_PART
+                    {
+                      $<nd>$ = p->lex_strterm;
+                      p->lex_strterm = NULL;
+                    }
+                  compstmt
+                  '}'
+                    {
+                      p->lex_strterm = $<nd>2;
+                      $$ = list2($1, $3);
+                    }
+                | tLITERAL_DELIM
+                    {
+                      $$ = list1(new_literal_delim(p));
+                    }
+                | tHD_LITERAL_DELIM heredoc_bodies
+                    {
+                      $$ = list1(new_literal_delim(p));
+                    }
+                ;
+
+xstring         : tXSTRING_BEG tXSTRING
+                    {
+                        $$ = $2;
+                    }
+                | tXSTRING_BEG string_rep tXSTRING
+                    {
+                      $$ = new_dxstr(p, push($2, $3));
+                    }
+                ;
+
+regexp          : tREGEXP_BEG tREGEXP
+                    {
+                        $$ = $2;
+                    }
+                | tREGEXP_BEG string_rep tREGEXP
+                    {
+                      $$ = new_dregx(p, $2, $3);
+                    }
+                ;
+
+heredoc         : tHEREDOC_BEG
+                ;
+
+heredoc_bodies  : heredoc_body
+                | heredoc_bodies heredoc_body
+                ;
+
+heredoc_body    : tHEREDOC_END
+                    {
+                      parser_heredoc_info * inf = parsing_heredoc_inf(p);
+                      inf->doc = push(inf->doc, new_str(p, "", 0));
+                      heredoc_end(p);
+                    }
+                | heredoc_string_rep tHEREDOC_END
+                    {
+                      heredoc_end(p);
+                    }
+                ;
+
+heredoc_string_rep : heredoc_string_interp
+                   | heredoc_string_rep heredoc_string_interp
+                   ;
+
+heredoc_string_interp : tHD_STRING_MID
+                    {
+                      parser_heredoc_info * inf = parsing_heredoc_inf(p);
+                      inf->doc = push(inf->doc, $1);
+                      heredoc_treat_nextline(p);
+                    }
+                | tHD_STRING_PART
+                    {
+                      $<nd>$ = p->lex_strterm;
+                      p->lex_strterm = NULL;
+                    }
+                  compstmt
+                  '}'
+                    {
+                      parser_heredoc_info * inf = parsing_heredoc_inf(p);
+                      p->lex_strterm = $<nd>2;
+                      inf->doc = push(push(inf->doc, $1), $3);
+                    }
+                ;
+
+words           : tWORDS_BEG tSTRING
+                    {
+                      $$ = new_words(p, list1($2));
+                    }
+                | tWORDS_BEG string_rep tSTRING
+                    {
+                      $$ = new_words(p, push($2, $3));
+                    }
+                ;
+
+
+symbol          : basic_symbol
+                    {
+                      $$ = new_sym(p, $1);
+                    }
+                | tSYMBEG tSTRING_BEG string_rep tSTRING
+                    {
+                      p->lstate = EXPR_END;
+                      $$ = new_dsym(p, push($3, $4));
+                    }
+                ;
+
+basic_symbol    : tSYMBEG sym
+                    {
+                      p->lstate = EXPR_END;
+                      $$ = $2;
+                    }
+                ;
+
+sym             : fname
+                | tIVAR
+                | tGVAR
+                | tCVAR
+                | tSTRING
+                    {
+                      $$ = new_strsym(p, $1);
+                    }
+                | tSTRING_BEG tSTRING
+                    {
+                      $$ = new_strsym(p, $2);
+                    }
+                ;
+
+symbols         : tSYMBOLS_BEG tSTRING
+                    {
+                      $$ = new_symbols(p, list1($2));
+                    }
+                | tSYMBOLS_BEG string_rep tSTRING
+                    {
+                      $$ = new_symbols(p, push($2, $3));
+                    }
+                ;
+
+numeric         : tINTEGER
+                | tFLOAT
+                | tUMINUS_NUM tINTEGER          %prec tLOWEST
+                    {
+                      $$ = negate_lit(p, $2);
+                    }
+                | tUMINUS_NUM tFLOAT            %prec tLOWEST
+                    {
+                      $$ = negate_lit(p, $2);
+                    }
+                ;
+
+variable        : tIDENTIFIER
+                    {
+                      $$ = new_lvar(p, $1);
+                    }
+                | tIVAR
+                    {
+                      $$ = new_ivar(p, $1);
+                    }
+                | tGVAR
+                    {
+                      $$ = new_gvar(p, $1);
+                    }
+                | tCVAR
+                    {
+                      $$ = new_cvar(p, $1);
+                    }
+                | tCONSTANT
+                    {
+                      $$ = new_const(p, $1);
+                    }
+                ;
+
+var_lhs         : variable
+                    {
+                      assignable(p, $1);
+                    }
+                ;
+
+var_ref         : variable
+                    {
+                      $$ = var_reference(p, $1);
+                    }
+                | keyword_nil
+                    {
+                      $$ = new_nil(p);
+                    }
+                | keyword_self
+                    {
+                      $$ = new_self(p);
+                    }
+                | keyword_true
+                    {
+                      $$ = new_true(p);
+                    }
+                | keyword_false
+                    {
+                      $$ = new_false(p);
+                    }
+                | keyword__FILE__
+                    {
+                      const char *fn = p->filename;
+                      if (!fn) {
+                        fn = "(null)";
+                      }
+                      $$ = new_str(p, fn, strlen(fn));
+                    }
+                | keyword__LINE__
+                    {
+                      char buf[16];
+
+                      snprintf(buf, sizeof(buf), "%d", p->lineno);
+                      $$ = new_int(p, buf, 10);
+                    }
+                ;
+
+backref         : tNTH_REF
+                | tBACK_REF
+                ;
+
+superclass      : /* term */
+                    {
+                      $$ = 0;
+                    }
+                | '<'
+                    {
+                      p->lstate = EXPR_BEG;
+                      p->cmd_start = TRUE;
+                    }
+                  expr_value term
+                    {
+                      $$ = $3;
+                    } /*
+                | error term
+                    {
+                      yyerrok;
+                      $$ = 0;
+                    } */
+                ;
+
+f_arglist       : '(' f_args rparen
+                    {
+                      $$ = $2;
+                      p->lstate = EXPR_BEG;
+                      p->cmd_start = TRUE;
+                    }
+                | f_args term
+                    {
+                      $$ = $1;
+                    }
+                ;
+
+f_args          : f_arg ',' f_optarg ',' f_rest_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, $1, $3, $5, 0, $6);
+                    }
+                | f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, $1, $3, $5, $7, $8);
+                    }
+                | f_arg ',' f_optarg opt_f_block_arg
+                    {
+                      $$ = new_args(p, $1, $3, 0, 0, $4);
+                    }
+                | f_arg ',' f_optarg ',' f_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, $1, $3, 0, $5, $6);
+                    }
+                | f_arg ',' f_rest_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, $1, 0, $3, 0, $4);
+                    }
+                | f_arg ',' f_rest_arg ',' f_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, $1, 0, $3, $5, $6);
+                    }
+                | f_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, $1, 0, 0, 0, $2);
+                    }
+                | f_optarg ',' f_rest_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, 0, $1, $3, 0, $4);
+                    }
+                | f_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, 0, $1, $3, $5, $6);
+                    }
+                | f_optarg opt_f_block_arg
+                    {
+                      $$ = new_args(p, 0, $1, 0, 0, $2);
+                    }
+                | f_optarg ',' f_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, 0, $1, 0, $3, $4);
+                    }
+                | f_rest_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, 0, 0, $1, 0, $2);
+                    }
+                | f_rest_arg ',' f_arg opt_f_block_arg
+                    {
+                      $$ = new_args(p, 0, 0, $1, $3, $4);
+                    }
+                | f_block_arg
+                    {
+                      $$ = new_args(p, 0, 0, 0, 0, $1);
+                    }
+                | /* none */
+                    {
+                      local_add_f(p, 0);
+                      $$ = new_args(p, 0, 0, 0, 0, 0);
+                    }
+                ;
+
+f_bad_arg       : tCONSTANT
+                    {
+                      yyerror(p, "formal argument cannot be a constant");
+                      $$ = 0;
+                    }
+                | tIVAR
+                    {
+                      yyerror(p, "formal argument cannot be an instance variable");
+                      $$ = 0;
+                    }
+                | tGVAR
+                    {
+                      yyerror(p, "formal argument cannot be a global variable");
+                      $$ = 0;
+                    }
+                | tCVAR
+                    {
+                      yyerror(p, "formal argument cannot be a class variable");
+                      $$ = 0;
+                    }
+                ;
+
+f_norm_arg      : f_bad_arg
+                    {
+                      $$ = 0;
+                    }
+                | tIDENTIFIER
+                    {
+                      local_add_f(p, $1);
+                      $$ = $1;
+                    }
+                ;
+
+f_arg_item      : f_norm_arg
+                    {
+                      $$ = new_arg(p, $1);
+                    }
+                | tLPAREN f_margs rparen
+                    {
+                      $$ = new_masgn(p, $2, 0);
+                    }
+                ;
+
+f_arg           : f_arg_item
+                    {
+                      $$ = list1($1);
+                    }
+                | f_arg ',' f_arg_item
+                    {
+                      $$ = push($1, $3);
+                    }
+                ;
+
+f_opt_asgn      : tIDENTIFIER '='
+                    {
+                      local_add_f(p, $1);
+                      $$ = $1;
+                    }
+                ;
+
+f_opt           : f_opt_asgn arg
+                    {
+                      void_expr_error(p, $2);
+                      $$ = cons(nsym($1), $2);
+                    }
+                ;
+
+f_block_opt     : f_opt_asgn primary_value
+                    {
+                      void_expr_error(p, $2);
+                      $$ = cons(nsym($1), $2);
+                    }
+                ;
+
+f_block_optarg  : f_block_opt
+                    {
+                      $$ = list1($1);
+                    }
+                | f_block_optarg ',' f_block_opt
+                    {
+                      $$ = push($1, $3);
+                    }
+                ;
+
+f_optarg        : f_opt
+                    {
+                      $$ = list1($1);
+                    }
+                | f_optarg ',' f_opt
+                    {
+                      $$ = push($1, $3);
+                    }
+                ;
+
+restarg_mark    : '*'
+                | tSTAR
+                ;
+
+f_rest_arg      : restarg_mark tIDENTIFIER
+                    {
+                      local_add_f(p, $2);
+                      $$ = $2;
+                    }
+                | restarg_mark
+                    {
+                      local_add_f(p, 0);
+                      $$ = -1;
+                    }
+                ;
+
+blkarg_mark     : '&'
+                | tAMPER
+                ;
+
+f_block_arg     : blkarg_mark tIDENTIFIER
+                    {
+                      local_add_f(p, $2);
+                      $$ = $2;
+                    }
+                ;
+
+opt_f_block_arg : ',' f_block_arg
+                    {
+                      $$ = $2;
+                    }
+                | none
+                    {
+                      local_add_f(p, 0);
+                      $$ = 0;
+                    }
+                ;
+
+singleton       : var_ref
+                    {
+                      $$ = $1;
+                      if (!$$) $$ = new_nil(p);
+                    }
+                | '(' {p->lstate = EXPR_BEG;} expr rparen
+                    {
+                      if ($3 == 0) {
+                        yyerror(p, "can't define singleton method for ().");
+                      }
+                      else {
+                        switch ((enum node_type)intn($3->car)) {
+                        case NODE_STR:
+                        case NODE_DSTR:
+                        case NODE_XSTR:
+                        case NODE_DXSTR:
+                        case NODE_DREGX:
+                        case NODE_MATCH:
+                        case NODE_FLOAT:
+                        case NODE_ARRAY:
+                        case NODE_HEREDOC:
+                          yyerror(p, "can't define singleton method for literals");
+                        default:
+                          break;
+                        }
+                      }
+                      $$ = $3;
+                    }
+                ;
+
+assoc_list      : none
+                | assocs trailer
+                    {
+                      $$ = $1;
+                    }
+                ;
+
+assocs          : assoc
+                    {
+                      $$ = list1($1);
+                      NODE_LINENO($$, $1);
+                    }
+                | assocs ',' assoc
+                    {
+                      $$ = push($1, $3);
+                    }
+                ;
+
+assoc           : arg tASSOC arg
+                    {
+                      void_expr_error(p, $1);
+                      void_expr_error(p, $3);
+                      $$ = cons($1, $3);
+                    }
+                | tLABEL arg
+                    {
+                      void_expr_error(p, $2);
+                      $$ = cons(new_sym(p, $1), $2);
+                    }
+                | tLABEL_END arg
+                    {
+                      void_expr_error(p, $2);
+                      $$ = cons(new_sym(p, new_strsym(p, $1)), $2);
+                    }
+                | tSTRING_BEG tLABEL_END arg
+                    {
+                      void_expr_error(p, $3);
+                      $$ = cons(new_sym(p, new_strsym(p, $2)), $3);
+                    }
+                | tSTRING_BEG string_rep tLABEL_END arg
+                    {
+                      void_expr_error(p, $4);
+                      $$ = cons(new_dsym(p, push($2, $3)), $4);
+                    }
+                ;
+
+operation       : tIDENTIFIER
+                | tCONSTANT
+                | tFID
+                ;
+
+operation2      : tIDENTIFIER
+                | tCONSTANT
+                | tFID
+                | op
+                ;
+
+operation3      : tIDENTIFIER
+                | tFID
+                | op
+                ;
+
+dot_or_colon    : '.'
+                | tCOLON2
+                ;
+
+call_op         : '.'
+                    {
+                      $$ = '.';
+                    }
+                | tANDDOT
+                    {
+                      $$ = 0;
+                    }
+                ;
+
+call_op2        : call_op
+                | tCOLON2
+                    {
+                      $$ = tCOLON2;
+                    }
+                ;
+
+opt_terms       : /* none */
+                | terms
+                ;
+
+opt_nl          : /* none */
+                | nl
+                ;
+
+rparen          : opt_nl ')'
+                ;
+
+rbracket        : opt_nl ']'
+                ;
+
+trailer         : /* none */
+                | nl
+                | comma
+                ;
+
+term            : ';' {yyerrok;}
+                | nl
+                | heredoc_body
+                ;
+
+nl              : '\n'
+                    {
+                      p->lineno++;
+                      p->column = 0;
+                    }
+                ;
+
+terms           : term
+                | terms term
+                ;
+
+none            : /* none */
+                    {
+                      $$ = 0;
+                    }
+                ;
+%%
+#define pylval  (*((YYSTYPE*)(p->ylval)))
+
+static void
+yyerror(parser_state *p, const char *s)
+{
+  char* c;
+  int n;
+
+  if (! p->capture_errors) {
+#ifndef MRB_DISABLE_STDIO
+    if (p->filename) {
+      fprintf(stderr, "%s:%d:%d: %s\n", p->filename, p->lineno, p->column, s);
+    }
+    else {
+      fprintf(stderr, "line %d:%d: %s\n", p->lineno, p->column, s);
+    }
+#endif
+  }
+  else if (p->nerr < sizeof(p->error_buffer) / sizeof(p->error_buffer[0])) {
+    n = strlen(s);
+    c = (char *)parser_palloc(p, n + 1);
+    memcpy(c, s, n + 1);
+    p->error_buffer[p->nerr].message = c;
+    p->error_buffer[p->nerr].lineno = p->lineno;
+    p->error_buffer[p->nerr].column = p->column;
+  }
+  p->nerr++;
+}
+
+static void
+yyerror_i(parser_state *p, const char *fmt, int i)
+{
+  char buf[256];
+
+  snprintf(buf, sizeof(buf), fmt, i);
+  yyerror(p, buf);
+}
+
+static void
+yywarn(parser_state *p, const char *s)
+{
+  char* c;
+  int n;
+
+  if (! p->capture_errors) {
+#ifndef MRB_DISABLE_STDIO
+    if (p->filename) {
+      fprintf(stderr, "%s:%d:%d: %s\n", p->filename, p->lineno, p->column, s);
+    }
+    else {
+      fprintf(stderr, "line %d:%d: %s\n", p->lineno, p->column, s);
+    }
+#endif
+  }
+  else if (p->nwarn < sizeof(p->warn_buffer) / sizeof(p->warn_buffer[0])) {
+    n = strlen(s);
+    c = (char *)parser_palloc(p, n + 1);
+    memcpy(c, s, n + 1);
+    p->warn_buffer[p->nwarn].message = c;
+    p->warn_buffer[p->nwarn].lineno = p->lineno;
+    p->warn_buffer[p->nwarn].column = p->column;
+  }
+  p->nwarn++;
+}
+
+static void
+yywarning(parser_state *p, const char *s)
+{
+  yywarn(p, s);
+}
+
+static void
+yywarning_s(parser_state *p, const char *fmt, const char *s)
+{
+  char buf[256];
+
+  snprintf(buf, sizeof(buf), fmt, s);
+  yywarning(p, buf);
+}
+
+static void
+backref_error(parser_state *p, node *n)
+{
+  int c;
+
+  c = (int)(intptr_t)n->car;
+
+  if (c == NODE_NTH_REF) {
+    yyerror_i(p, "can't set variable $%" MRB_PRId, (mrb_int)(intptr_t)n->cdr);
+  }
+  else if (c == NODE_BACK_REF) {
+    yyerror_i(p, "can't set variable $%c", (int)(intptr_t)n->cdr);
+  }
+  else {
+    mrb_bug(p->mrb, "Internal error in backref_error() : n=>car == %S", mrb_fixnum_value(c));
+  }
+}
+
+static void
+void_expr_error(parser_state *p, node *n)
+{
+  int c;
+
+  if (n == NULL) return;
+  c = (int)(intptr_t)n->car;
+  switch (c) {
+  case NODE_BREAK:
+  case NODE_RETURN:
+  case NODE_NEXT:
+  case NODE_REDO:
+  case NODE_RETRY:
+    yyerror(p, "void value expression");
+    break;
+  case NODE_AND:
+  case NODE_OR:
+    void_expr_error(p, n->cdr->car);
+    void_expr_error(p, n->cdr->cdr);
+    break;
+  case NODE_BEGIN:
+    if (n->cdr) {
+      while (n->cdr) {
+        n = n->cdr;
+      }
+      void_expr_error(p, n->car);
+    }
+    break;
+  default:
+    break;
+  }
+}
+
+static void pushback(parser_state *p, int c);
+static mrb_bool peeks(parser_state *p, const char *s);
+static mrb_bool skips(parser_state *p, const char *s);
+
+static inline int
+nextc(parser_state *p)
+{
+  int c;
+
+  if (p->pb) {
+    node *tmp;
+
+    c = (int)(intptr_t)p->pb->car;
+    tmp = p->pb;
+    p->pb = p->pb->cdr;
+    cons_free(tmp);
+  }
+  else {
+#ifndef MRB_DISABLE_STDIO
+    if (p->f) {
+      if (feof(p->f)) goto eof;
+      c = fgetc(p->f);
+      if (c == EOF) goto eof;
+    }
+    else
+#endif
+      if (!p->s || p->s >= p->send) {
+        goto eof;
+      }
+      else {
+        c = (unsigned char)*p->s++;
+      }
+  }
+  if (c >= 0) {
+    p->column++;
+  }
+  if (c == '\r') {
+    c = nextc(p);
+    if (c != '\n') {
+      pushback(p, c);
+      return '\r';
+    }
+    return c;
+  }
+  return c;
+
+  eof:
+  if (!p->cxt) return -1;
+  else {
+    if (p->cxt->partial_hook(p) < 0)
+      return -1;                /* end of program(s) */
+    return -2;                  /* end of a file in the program files */
+  }
+}
+
+static void
+pushback(parser_state *p, int c)
+{
+  if (c >= 0) {
+    p->column--;
+  }
+  p->pb = cons((node*)(intptr_t)c, p->pb);
+}
+
+static void
+skip(parser_state *p, char term)
+{
+  int c;
+
+  for (;;) {
+    c = nextc(p);
+    if (c < 0) break;
+    if (c == term) break;
+  }
+}
+
+static int
+peekc_n(parser_state *p, int n)
+{
+  node *list = 0;
+  int c0;
+
+  do {
+    c0 = nextc(p);
+    if (c0 == -1) return c0;    /* do not skip partial EOF */
+    if (c0 >= 0) --p->column;
+    list = push(list, (node*)(intptr_t)c0);
+  } while(n--);
+  if (p->pb) {
+    p->pb = append((node*)list, p->pb);
+  }
+  else {
+    p->pb = list;
+  }
+  return c0;
+}
+
+static mrb_bool
+peek_n(parser_state *p, int c, int n)
+{
+  return peekc_n(p, n) == c && c >= 0;
+}
+#define peek(p,c) peek_n((p), (c), 0)
+
+static mrb_bool
+peeks(parser_state *p, const char *s)
+{
+  int len = strlen(s);
+
+#ifndef MRB_DISABLE_STDIO
+  if (p->f) {
+    int n = 0;
+    while (*s) {
+      if (!peek_n(p, *s++, n++)) return FALSE;
+    }
+    return TRUE;
+  }
+  else
+#endif
+    if (p->s && p->s + len <= p->send) {
+      if (memcmp(p->s, s, len) == 0) return TRUE;
+    }
+  return FALSE;
+}
+
+static mrb_bool
+skips(parser_state *p, const char *s)
+{
+  int c;
+
+  for (;;) {
+    /* skip until first char */
+    for (;;) {
+      c = nextc(p);
+      if (c < 0) return FALSE;
+      if (c == '\n') {
+        p->lineno++;
+        p->column = 0;
+      }
+      if (c == *s) break;
+    }
+    s++;
+    if (peeks(p, s)) {
+      int len = strlen(s);
+
+      while (len--) {
+        if (nextc(p) == '\n') {
+          p->lineno++;
+          p->column = 0;
+        }
+      }
+      return TRUE;
+    }
+    else{
+      s--;
+    }
+  }
+  return FALSE;
+}
+
+
+static int
+newtok(parser_state *p)
+{
+  if (p->tokbuf != p->buf) {
+    mrb_free(p->mrb, p->tokbuf);
+    p->tokbuf = p->buf;
+    p->tsiz = MRB_PARSER_TOKBUF_SIZE;
+  }
+  p->tidx = 0;
+  return p->column - 1;
+}
+
+static void
+tokadd(parser_state *p, int32_t c)
+{
+  char utf8[4];
+  int i, len;
+
+  /* mrb_assert(-0x10FFFF <= c && c <= 0xFF); */
+  if (c >= 0) {
+    /* Single byte from source or non-Unicode escape */
+    utf8[0] = (char)c;
+    len = 1;
+  }
+  else {
+    /* Unicode character */
+    c = -c;
+    if (c < 0x80) {
+      utf8[0] = (char)c;
+      len = 1;
+    }
+    else if (c < 0x800) {
+      utf8[0] = (char)(0xC0 | (c >> 6));
+      utf8[1] = (char)(0x80 | (c & 0x3F));
+      len = 2;
+    }
+    else if (c < 0x10000) {
+      utf8[0] = (char)(0xE0 |  (c >> 12)        );
+      utf8[1] = (char)(0x80 | ((c >>  6) & 0x3F));
+      utf8[2] = (char)(0x80 | ( c        & 0x3F));
+      len = 3;
+    }
+    else {
+      utf8[0] = (char)(0xF0 |  (c >> 18)        );
+      utf8[1] = (char)(0x80 | ((c >> 12) & 0x3F));
+      utf8[2] = (char)(0x80 | ((c >>  6) & 0x3F));
+      utf8[3] = (char)(0x80 | ( c        & 0x3F));
+      len = 4;
+    }
+  }
+  if (p->tidx+len >= p->tsiz) {
+    if (p->tsiz >= MRB_PARSER_TOKBUF_MAX) {
+      p->tidx += len;
+      return;
+    }
+    p->tsiz *= 2;
+    if (p->tokbuf == p->buf) {
+      p->tokbuf = (char*)mrb_malloc(p->mrb, p->tsiz);
+      memcpy(p->tokbuf, p->buf, MRB_PARSER_TOKBUF_SIZE);
+    }
+    else {
+      p->tokbuf = (char*)mrb_realloc(p->mrb, p->tokbuf, p->tsiz);
+    }
+  }
+  for (i = 0; i < len; i++) {
+    p->tokbuf[p->tidx++] = utf8[i];
+  }
+}
+
+static int
+toklast(parser_state *p)
+{
+  return p->tokbuf[p->tidx-1];
+}
+
+static void
+tokfix(parser_state *p)
+{
+  if (p->tidx >= MRB_PARSER_TOKBUF_MAX) {
+    p->tidx = MRB_PARSER_TOKBUF_MAX-1;
+    yyerror(p, "string too long (truncated)");
+  }
+  p->tokbuf[p->tidx] = '\0';
+}
+
+static const char*
+tok(parser_state *p)
+{
+  return p->tokbuf;
+}
+
+static int
+toklen(parser_state *p)
+{
+  return p->tidx;
+}
+
+#define IS_ARG() (p->lstate == EXPR_ARG || p->lstate == EXPR_CMDARG)
+#define IS_END() (p->lstate == EXPR_END || p->lstate == EXPR_ENDARG || p->lstate == EXPR_ENDFN)
+#define IS_BEG() (p->lstate == EXPR_BEG || p->lstate == EXPR_MID || p->lstate == EXPR_VALUE || p->lstate == EXPR_CLASS)
+#define IS_SPCARG(c) (IS_ARG() && space_seen && !ISSPACE(c))
+#define IS_LABEL_POSSIBLE() ((p->lstate == EXPR_BEG && !cmd_state) || IS_ARG())
+#define IS_LABEL_SUFFIX(n) (peek_n(p, ':',(n)) && !peek_n(p, ':', (n)+1))
+
+static int
+scan_oct(const int *start, int len, int *retlen)
+{
+  const int *s = start;
+  int retval = 0;
+
+  /* mrb_assert(len <= 3) */
+  while (len-- && *s >= '0' && *s <= '7') {
+    retval <<= 3;
+    retval |= *s++ - '0';
+  }
+  *retlen = s - start;
+
+  return retval;
+}
+
+static int32_t
+scan_hex(const int *start, int len, int *retlen)
+{
+  static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF";
+  const int *s = start;
+  int32_t retval = 0;
+  char *tmp;
+
+  /* mrb_assert(len <= 8) */
+  while (len-- && *s && (tmp = (char*)strchr(hexdigit, *s))) {
+    retval <<= 4;
+    retval |= (tmp - hexdigit) & 15;
+    s++;
+  }
+  *retlen = s - start;
+
+  return retval;
+}
+
+static int32_t
+read_escape_unicode(parser_state *p, int limit)
+{
+  int32_t c;
+  int buf[9];
+  int i;
+
+  /* Look for opening brace */
+  i = 0;
+  buf[0] = nextc(p);
+  if (buf[0] < 0) goto eof;
+  if (ISXDIGIT(buf[0])) {
+    /* \uxxxx form */
+    for (i=1; i<limit; i++) {
+      buf[i] = nextc(p);
+      if (buf[i] < 0) goto eof;
+      if (!ISXDIGIT(buf[i])) {
+        pushback(p, buf[i]);
+        break;
+      }
+    }
+  }
+  else {
+    pushback(p, buf[0]);
+  }
+  c = scan_hex(buf, i, &i);
+  if (i == 0) {
+  eof:
+    yyerror(p, "Invalid escape character syntax");
+    return -1;
+  }
+  if (c < 0 || c > 0x10FFFF || (c & 0xFFFFF800) == 0xD800) {
+    yyerror(p, "Invalid Unicode code point");
+    return -1;
+  }
+  return c;
+}
+
+/* Return negative to indicate Unicode code point */
+static int32_t
+read_escape(parser_state *p)
+{
+  int32_t c;
+
+  switch (c = nextc(p)) {
+  case '\\':/* Backslash */
+    return c;
+
+  case 'n':/* newline */
+    return '\n';
+
+  case 't':/* horizontal tab */
+    return '\t';
+
+  case 'r':/* carriage-return */
+    return '\r';
+
+  case 'f':/* form-feed */
+    return '\f';
+
+  case 'v':/* vertical tab */
+    return '\13';
+
+  case 'a':/* alarm(bell) */
+    return '\007';
+
+  case 'e':/* escape */
+    return 033;
+
+  case '0': case '1': case '2': case '3': /* octal constant */
+  case '4': case '5': case '6': case '7':
+  {
+    int buf[3];
+    int i;
+
+    buf[0] = c;
+    for (i=1; i<3; i++) {
+      buf[i] = nextc(p);
+      if (buf[i] < 0) goto eof;
+      if (buf[i] < '0' || '7' < buf[i]) {
+        pushback(p, buf[i]);
+        break;
+      }
+    }
+    c = scan_oct(buf, i, &i);
+  }
+  return c;
+
+  case 'x':     /* hex constant */
+  {
+    int buf[2];
+    int i;
+
+    for (i=0; i<2; i++) {
+      buf[i] = nextc(p);
+      if (buf[i] < 0) goto eof;
+      if (!ISXDIGIT(buf[i])) {
+        pushback(p, buf[i]);
+        break;
+      }
+    }
+    c = scan_hex(buf, i, &i);
+    if (i == 0) {
+      yyerror(p, "Invalid escape character syntax");
+      return 0;
+    }
+  }
+  return c;
+
+  case 'u':     /* Unicode */
+    if (peek(p, '{')) {
+      /* \u{xxxxxxxx} form */
+      nextc(p);
+      c = read_escape_unicode(p, 8);
+      if (c < 0) return 0;
+      if (nextc(p) != '}') goto eof;
+    }
+    else {
+      c = read_escape_unicode(p, 4);
+      if (c < 0) return 0;
+    }
+  return -c;
+
+  case 'b':/* backspace */
+    return '\010';
+
+  case 's':/* space */
+    return ' ';
+
+  case 'M':
+    if ((c = nextc(p)) != '-') {
+      yyerror(p, "Invalid escape character syntax");
+      pushback(p, c);
+      return '\0';
+    }
+    if ((c = nextc(p)) == '\\') {
+      return read_escape(p) | 0x80;
+    }
+    else if (c < 0) goto eof;
+    else {
+      return ((c & 0xff) | 0x80);
+    }
+
+  case 'C':
+    if ((c = nextc(p)) != '-') {
+      yyerror(p, "Invalid escape character syntax");
+      pushback(p, c);
+      return '\0';
+    }
+  case 'c':
+    if ((c = nextc(p))== '\\') {
+      c = read_escape(p);
+    }
+    else if (c == '?')
+      return 0177;
+    else if (c < 0) goto eof;
+    return c & 0x9f;
+
+    eof:
+  case -1:
+  case -2:                      /* end of a file */
+    yyerror(p, "Invalid escape character syntax");
+    return '\0';
+
+  default:
+    return c;
+  }
+}
+
+static int
+parse_string(parser_state *p)
+{
+  int c;
+  string_type type = (string_type)(intptr_t)p->lex_strterm->car;
+  int nest_level = (intptr_t)p->lex_strterm->cdr->car;
+  int beg = (intptr_t)p->lex_strterm->cdr->cdr->car;
+  int end = (intptr_t)p->lex_strterm->cdr->cdr->cdr;
+  parser_heredoc_info *hinf = (type & STR_FUNC_HEREDOC) ? parsing_heredoc_inf(p) : NULL;
+  int cmd_state = p->cmd_start;
+
+  if (beg == 0) beg = -3;       /* should never happen */
+  if (end == 0) end = -3;
+  newtok(p);
+  while ((c = nextc(p)) != end || nest_level != 0) {
+    if (hinf && (c == '\n' || c < 0)) {
+      mrb_bool line_head;
+      tokadd(p, '\n');
+      tokfix(p);
+      p->lineno++;
+      p->column = 0;
+      line_head = hinf->line_head;
+      hinf->line_head = TRUE;
+      if (line_head) {
+        /* check whether end of heredoc */
+        const char *s = tok(p);
+        int len = toklen(p);
+        if (hinf->allow_indent) {
+          while (ISSPACE(*s) && len > 0) {
+            ++s;
+            --len;
+          }
+        }
+        if ((len-1 == hinf->term_len) && (strncmp(s, hinf->term, len-1) == 0)) {
+          if (c < 0) {
+            p->parsing_heredoc = NULL;
+          }
+          else {
+            return tHEREDOC_END;
+          }
+        }
+      }
+      if (c < 0) {
+        char buf[256];
+        snprintf(buf, sizeof(buf), "can't find heredoc delimiter \"%s\" anywhere before EOF", hinf->term);
+        yyerror(p, buf);
+        return 0;
+      }
+      pylval.nd = new_str(p, tok(p), toklen(p));
+      return tHD_STRING_MID;
+    }
+    if (c < 0) {
+      yyerror(p, "unterminated string meets end of file");
+      return 0;
+    }
+    else if (c == beg) {
+      nest_level++;
+      p->lex_strterm->cdr->car = (node*)(intptr_t)nest_level;
+    }
+    else if (c == end) {
+      nest_level--;
+      p->lex_strterm->cdr->car = (node*)(intptr_t)nest_level;
+    }
+    else if (c == '\\') {
+      c = nextc(p);
+      if (type & STR_FUNC_EXPAND) {
+        if (c == end || c == beg) {
+          tokadd(p, c);
+        }
+        else if (c == '\n') {
+          p->lineno++;
+          p->column = 0;
+          if (type & STR_FUNC_ARRAY) {
+            tokadd(p, '\n');
+          }
+        }
+        else if (type & STR_FUNC_REGEXP) {
+          tokadd(p, '\\');
+          tokadd(p, c);
+        }
+        else if (c == 'u' && peek(p, '{')) {
+          /* \u{xxxx xxxx xxxx} form */
+          nextc(p);
+          while (1) {
+            do c = nextc(p); while (ISSPACE(c));
+            if (c == '}') break;
+            pushback(p, c);
+            c = read_escape_unicode(p, 8);
+            if (c < 0) break;
+            tokadd(p, -c);
+          }
+          if (hinf)
+            hinf->line_head = FALSE;
+        }
+        else {
+          pushback(p, c);
+          tokadd(p, read_escape(p));
+          if (hinf)
+            hinf->line_head = FALSE;
+        }
+      }
+      else {
+        if (c != beg && c != end) {
+          if (c == '\n') {
+            p->lineno++;
+            p->column = 0;
+          }
+          if (!(c == '\\' || ((type & STR_FUNC_ARRAY) && ISSPACE(c)))) {
+            tokadd(p, '\\');
+          }
+        }
+        tokadd(p, c);
+      }
+      continue;
+    }
+    else if ((c == '#') && (type & STR_FUNC_EXPAND)) {
+      c = nextc(p);
+      if (c == '{') {
+        tokfix(p);
+        p->lstate = EXPR_BEG;
+        p->cmd_start = TRUE;
+        pylval.nd = new_str(p, tok(p), toklen(p));
+        if (hinf) {
+          hinf->line_head = FALSE;
+          return tHD_STRING_PART;
+        }
+        return tSTRING_PART;
+      }
+      tokadd(p, '#');
+      pushback(p, c);
+      continue;
+    }
+    if ((type & STR_FUNC_ARRAY) && ISSPACE(c)) {
+      if (toklen(p) == 0) {
+        do {
+          if (c == '\n') {
+            p->lineno++;
+            p->column = 0;
+            heredoc_treat_nextline(p);
+            if (p->parsing_heredoc != NULL) {
+              return tHD_LITERAL_DELIM;
+            }
+          }
+          c = nextc(p);
+        } while (ISSPACE(c));
+        pushback(p, c);
+        return tLITERAL_DELIM;
+      }
+      else {
+        pushback(p, c);
+        tokfix(p);
+        pylval.nd = new_str(p, tok(p), toklen(p));
+        return tSTRING_MID;
+      }
+    }
+    if (c == '\n') {
+      p->lineno++;
+      p->column = 0;
+    }
+    tokadd(p, c);
+  }
+
+  tokfix(p);
+  p->lstate = EXPR_END;
+  end_strterm(p);
+
+  if (type & STR_FUNC_XQUOTE) {
+    pylval.nd = new_xstr(p, tok(p), toklen(p));
+    return tXSTRING;
+  }
+
+  if (type & STR_FUNC_REGEXP) {
+    int f = 0;
+    int re_opt;
+    char *s = strndup(tok(p), toklen(p));
+    char flags[3];
+    char *flag = flags;
+    char enc = '\0';
+    char *encp;
+    char *dup;
+
+    newtok(p);
+    while (re_opt = nextc(p), re_opt >= 0 && ISALPHA(re_opt)) {
+      switch (re_opt) {
+      case 'i': f |= 1; break;
+      case 'x': f |= 2; break;
+      case 'm': f |= 4; break;
+      case 'u': f |= 16; break;
+      case 'n': f |= 32; break;
+      default: tokadd(p, re_opt); break;
+      }
+    }
+    pushback(p, re_opt);
+    if (toklen(p)) {
+      char msg[128];
+      tokfix(p);
+      snprintf(msg, sizeof(msg), "unknown regexp option%s - %s",
+          toklen(p) > 1 ? "s" : "", tok(p));
+      yyerror(p, msg);
+    }
+    if (f != 0) {
+      if (f & 1) *flag++ = 'i';
+      if (f & 2) *flag++ = 'x';
+      if (f & 4) *flag++ = 'm';
+      if (f & 16) enc = 'u';
+      if (f & 32) enc = 'n';
+    }
+    if (flag > flags) {
+      dup = strndup(flags, (size_t)(flag - flags));
+    }
+    else {
+      dup = NULL;
+    }
+    if (enc) {
+      encp = strndup(&enc, 1);
+    }
+    else {
+      encp = NULL;
+    }
+    pylval.nd = new_regx(p, s, dup, encp);
+
+    return tREGEXP;
+  }
+  pylval.nd = new_str(p, tok(p), toklen(p));
+  if (IS_LABEL_POSSIBLE()) {
+    if (IS_LABEL_SUFFIX(0)) {
+      p->lstate = EXPR_BEG;
+      nextc(p);
+      return tLABEL_END;
+    }
+  }
+
+  return tSTRING;
+}
+
+
+static int
+heredoc_identifier(parser_state *p)
+{
+  int c;
+  int type = str_heredoc;
+  mrb_bool indent = FALSE;
+  mrb_bool quote = FALSE;
+  node *newnode;
+  parser_heredoc_info *info;
+
+  c = nextc(p);
+  if (ISSPACE(c) || c == '=') {
+    pushback(p, c);
+    return 0;
+  }
+  if (c == '-') {
+    indent = TRUE;
+    c = nextc(p);
+  }
+  if (c == '\'' || c == '"') {
+    int term = c;
+    if (c == '\'')
+      quote = TRUE;
+    newtok(p);
+    while ((c = nextc(p)) >= 0 && c != term) {
+      if (c == '\n') {
+        c = -1;
+        break;
+      }
+      tokadd(p, c);
+    }
+    if (c < 0) {
+      yyerror(p, "unterminated here document identifier");
+      return 0;
+    }
+  }
+  else {
+    if (c < 0) {
+      return 0;                 /* missing here document identifier */
+    }
+    if (! identchar(c)) {
+      pushback(p, c);
+      if (indent) pushback(p, '-');
+      return 0;
+    }
+    newtok(p);
+    do {
+      tokadd(p, c);
+    } while ((c = nextc(p)) >= 0 && identchar(c));
+    pushback(p, c);
+  }
+  tokfix(p);
+  newnode = new_heredoc(p);
+  info = (parser_heredoc_info*)newnode->cdr;
+  info->term = strndup(tok(p), toklen(p));
+  info->term_len = toklen(p);
+  if (! quote)
+    type |= STR_FUNC_EXPAND;
+  info->type = (string_type)type;
+  info->allow_indent = indent;
+  info->line_head = TRUE;
+  info->doc = NULL;
+  p->heredocs_from_nextline = push(p->heredocs_from_nextline, newnode);
+  p->lstate = EXPR_END;
+
+  pylval.nd = newnode;
+  return tHEREDOC_BEG;
+}
+
+static int
+arg_ambiguous(parser_state *p)
+{
+  yywarning(p, "ambiguous first argument; put parentheses or even spaces");
+  return 1;
+}
+
+#include "lex.def"
+
+static int
+parser_yylex(parser_state *p)
+{
+  int32_t c;
+  int space_seen = 0;
+  int cmd_state;
+  enum mrb_lex_state_enum last_state;
+  int token_column;
+
+  if (p->lex_strterm) {
+    if (is_strterm_type(p, STR_FUNC_HEREDOC)) {
+      if (p->parsing_heredoc != NULL)
+        return parse_string(p);
+    }
+    else
+      return parse_string(p);
+  }
+  cmd_state = p->cmd_start;
+  p->cmd_start = FALSE;
+  retry:
+  last_state = p->lstate;
+  switch (c = nextc(p)) {
+  case '\004':  /* ^D */
+  case '\032':  /* ^Z */
+  case '\0':    /* NUL */
+  case -1:      /* end of script. */
+    if (p->heredocs_from_nextline)
+      goto maybe_heredoc;
+    return 0;
+
+  /* white spaces */
+  case ' ': case '\t': case '\f': case '\r':
+  case '\13':   /* '\v' */
+    space_seen = 1;
+    goto retry;
+
+  case '#':     /* it's a comment */
+    skip(p, '\n');
+    /* fall through */
+  case -2:      /* end of a file */
+  case '\n':
+    maybe_heredoc:
+    heredoc_treat_nextline(p);
+  switch (p->lstate) {
+  case EXPR_BEG:
+  case EXPR_FNAME:
+  case EXPR_DOT:
+  case EXPR_CLASS:
+  case EXPR_VALUE:
+    p->lineno++;
+    p->column = 0;
+    if (p->parsing_heredoc != NULL) {
+      if (p->lex_strterm) {
+        return parse_string(p);
+      }
+    }
+    goto retry;
+  default:
+    break;
+  }
+  if (p->parsing_heredoc != NULL) {
+    return '\n';
+  }
+  while ((c = nextc(p))) {
+    switch (c) {
+    case ' ': case '\t': case '\f': case '\r':
+    case '\13': /* '\v' */
+      space_seen = 1;
+      break;
+    case '.':
+      if ((c = nextc(p)) != '.') {
+        pushback(p, c);
+        pushback(p, '.');
+        goto retry;
+      }
+    case -1:                  /* EOF */
+    case -2:                  /* end of a file */
+      goto normal_newline;
+    default:
+      pushback(p, c);
+      goto normal_newline;
+    }
+  }
+  normal_newline:
+  p->cmd_start = TRUE;
+  p->lstate = EXPR_BEG;
+  return '\n';
+
+  case '*':
+    if ((c = nextc(p)) == '*') {
+      if ((c = nextc(p)) == '=') {
+        pylval.id = intern("**",2);
+        p->lstate = EXPR_BEG;
+        return tOP_ASGN;
+      }
+      pushback(p, c);
+      c = tPOW;
+    }
+    else {
+      if (c == '=') {
+        pylval.id = intern_c('*');
+        p->lstate = EXPR_BEG;
+        return tOP_ASGN;
+      }
+      pushback(p, c);
+      if (IS_SPCARG(c)) {
+        yywarning(p, "'*' interpreted as argument prefix");
+        c = tSTAR;
+      }
+      else if (IS_BEG()) {
+        c = tSTAR;
+      }
+      else {
+        c = '*';
+      }
+    }
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+    }
+    else {
+      p->lstate = EXPR_BEG;
+    }
+    return c;
+
+  case '!':
+    c = nextc(p);
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+      if (c == '@') {
+        return '!';
+      }
+    }
+    else {
+      p->lstate = EXPR_BEG;
+    }
+    if (c == '=') {
+      return tNEQ;
+    }
+    if (c == '~') {
+      return tNMATCH;
+    }
+    pushback(p, c);
+    return '!';
+
+  case '=':
+    if (p->column == 1) {
+      static const char begin[] = "begin";
+      static const char end[] = "\n=end";
+      if (peeks(p, begin)) {
+        c = peekc_n(p, sizeof(begin)-1);
+        if (c < 0 || ISSPACE(c)) {
+          do {
+            if (!skips(p, end)) {
+              yyerror(p, "embedded document meets end of file");
+              return 0;
+            }
+            c = nextc(p);
+          } while (!(c < 0 || ISSPACE(c)));
+          if (c != '\n') skip(p, '\n');
+          p->lineno++;
+          p->column = 0;
+          goto retry;
+        }
+      }
+    }
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+    }
+    else {
+      p->lstate = EXPR_BEG;
+    }
+    if ((c = nextc(p)) == '=') {
+      if ((c = nextc(p)) == '=') {
+        return tEQQ;
+      }
+      pushback(p, c);
+      return tEQ;
+    }
+    if (c == '~') {
+      return tMATCH;
+    }
+    else if (c == '>') {
+      return tASSOC;
+    }
+    pushback(p, c);
+    return '=';
+
+  case '<':
+    c = nextc(p);
+    if (c == '<' &&
+        p->lstate != EXPR_DOT &&
+        p->lstate != EXPR_CLASS &&
+        !IS_END() &&
+        (!IS_ARG() || space_seen)) {
+      int token = heredoc_identifier(p);
+      if (token)
+        return token;
+    }
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+    }
+    else {
+      p->lstate = EXPR_BEG;
+      if (p->lstate == EXPR_CLASS) {
+        p->cmd_start = TRUE;
+      }
+    }
+    if (c == '=') {
+      if ((c = nextc(p)) == '>') {
+        return tCMP;
+      }
+      pushback(p, c);
+      return tLEQ;
+    }
+    if (c == '<') {
+      if ((c = nextc(p)) == '=') {
+        pylval.id = intern("<<",2);
+        p->lstate = EXPR_BEG;
+        return tOP_ASGN;
+      }
+      pushback(p, c);
+      return tLSHFT;
+    }
+    pushback(p, c);
+    return '<';
+
+  case '>':
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+    }
+    else {
+      p->lstate = EXPR_BEG;
+    }
+    if ((c = nextc(p)) == '=') {
+      return tGEQ;
+    }
+    if (c == '>') {
+      if ((c = nextc(p)) == '=') {
+        pylval.id = intern(">>",2);
+        p->lstate = EXPR_BEG;
+        return tOP_ASGN;
+      }
+      pushback(p, c);
+      return tRSHFT;
+    }
+    pushback(p, c);
+    return '>';
+
+  case '"':
+    p->lex_strterm = new_strterm(p, str_dquote, '"', 0);
+    return tSTRING_BEG;
+
+  case '\'':
+    p->lex_strterm = new_strterm(p, str_squote, '\'', 0);
+    return parse_string(p);
+
+  case '`':
+    if (p->lstate == EXPR_FNAME) {
+      p->lstate = EXPR_ENDFN;
+      return '`';
+    }
+    if (p->lstate == EXPR_DOT) {
+      if (cmd_state)
+        p->lstate = EXPR_CMDARG;
+      else
+        p->lstate = EXPR_ARG;
+      return '`';
+    }
+    p->lex_strterm = new_strterm(p, str_xquote, '`', 0);
+    return tXSTRING_BEG;
+
+  case '?':
+    if (IS_END()) {
+      p->lstate = EXPR_VALUE;
+      return '?';
+    }
+    c = nextc(p);
+    if (c < 0) {
+      yyerror(p, "incomplete character syntax");
+      return 0;
+    }
+    if (ISSPACE(c)) {
+      if (!IS_ARG()) {
+        int c2;
+        switch (c) {
+        case ' ':
+          c2 = 's';
+          break;
+        case '\n':
+          c2 = 'n';
+          break;
+        case '\t':
+          c2 = 't';
+          break;
+        case '\v':
+          c2 = 'v';
+          break;
+        case '\r':
+          c2 = 'r';
+          break;
+        case '\f':
+          c2 = 'f';
+          break;
+        default:
+          c2 = 0;
+          break;
+        }
+        if (c2) {
+          char buf[256];
+          snprintf(buf, sizeof(buf), "invalid character syntax; use ?\\%c", c2);
+          yyerror(p, buf);
+        }
+      }
+      ternary:
+      pushback(p, c);
+      p->lstate = EXPR_VALUE;
+      return '?';
+    }
+    newtok(p);
+    /* need support UTF-8 if configured */
+    if ((isalnum(c) || c == '_')) {
+      int c2 = nextc(p);
+      pushback(p, c2);
+      if ((isalnum(c2) || c2 == '_')) {
+        goto ternary;
+      }
+    }
+    if (c == '\\') {
+      c = read_escape(p);
+      tokadd(p, c);
+    }
+    else {
+      tokadd(p, c);
+    }
+    tokfix(p);
+    pylval.nd = new_str(p, tok(p), toklen(p));
+    p->lstate = EXPR_END;
+    return tCHAR;
+
+  case '&':
+    if ((c = nextc(p)) == '&') {
+      p->lstate = EXPR_BEG;
+      if ((c = nextc(p)) == '=') {
+        pylval.id = intern("&&",2);
+        p->lstate = EXPR_BEG;
+        return tOP_ASGN;
+      }
+      pushback(p, c);
+      return tANDOP;
+    }
+    else if (c == '.') {
+      p->lstate = EXPR_DOT;
+      return tANDDOT;
+    }
+    else if (c == '=') {
+      pylval.id = intern_c('&');
+      p->lstate = EXPR_BEG;
+      return tOP_ASGN;
+    }
+    pushback(p, c);
+    if (IS_SPCARG(c)) {
+      yywarning(p, "'&' interpreted as argument prefix");
+      c = tAMPER;
+    }
+    else if (IS_BEG()) {
+      c = tAMPER;
+    }
+    else {
+      c = '&';
+    }
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+    }
+    else {
+      p->lstate = EXPR_BEG;
+    }
+    return c;
+
+  case '|':
+    if ((c = nextc(p)) == '|') {
+      p->lstate = EXPR_BEG;
+      if ((c = nextc(p)) == '=') {
+        pylval.id = intern("||",2);
+        p->lstate = EXPR_BEG;
+        return tOP_ASGN;
+      }
+      pushback(p, c);
+      return tOROP;
+    }
+    if (c == '=') {
+      pylval.id = intern_c('|');
+      p->lstate = EXPR_BEG;
+      return tOP_ASGN;
+    }
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+    }
+    else {
+      p->lstate = EXPR_BEG;
+    }
+    pushback(p, c);
+    return '|';
+
+  case '+':
+    c = nextc(p);
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+      if (c == '@') {
+        return tUPLUS;
+      }
+      pushback(p, c);
+      return '+';
+    }
+    if (c == '=') {
+      pylval.id = intern_c('+');
+      p->lstate = EXPR_BEG;
+      return tOP_ASGN;
+    }
+    if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous(p))) {
+      p->lstate = EXPR_BEG;
+      pushback(p, c);
+      if (c >= 0 && ISDIGIT(c)) {
+        c = '+';
+        goto start_num;
+      }
+      return tUPLUS;
+    }
+    p->lstate = EXPR_BEG;
+    pushback(p, c);
+    return '+';
+
+  case '-':
+    c = nextc(p);
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+      if (c == '@') {
+        return tUMINUS;
+      }
+      pushback(p, c);
+      return '-';
+    }
+    if (c == '=') {
+      pylval.id = intern_c('-');
+      p->lstate = EXPR_BEG;
+      return tOP_ASGN;
+    }
+    if (c == '>') {
+      p->lstate = EXPR_ENDFN;
+      return tLAMBDA;
+    }
+    if (IS_BEG() || (IS_SPCARG(c) && arg_ambiguous(p))) {
+      p->lstate = EXPR_BEG;
+      pushback(p, c);
+      if (c >= 0 && ISDIGIT(c)) {
+        return tUMINUS_NUM;
+      }
+      return tUMINUS;
+    }
+    p->lstate = EXPR_BEG;
+    pushback(p, c);
+    return '-';
+
+  case '.':
+    p->lstate = EXPR_BEG;
+    if ((c = nextc(p)) == '.') {
+      if ((c = nextc(p)) == '.') {
+        return tDOT3;
+      }
+      pushback(p, c);
+      return tDOT2;
+    }
+    pushback(p, c);
+    if (c >= 0 && ISDIGIT(c)) {
+      yyerror(p, "no .<digit> floating literal anymore; put 0 before dot");
+    }
+    p->lstate = EXPR_DOT;
+    return '.';
+
+    start_num:
+  case '0': case '1': case '2': case '3': case '4':
+  case '5': case '6': case '7': case '8': case '9':
+  {
+    int is_float, seen_point, seen_e, nondigit;
+
+    is_float = seen_point = seen_e = nondigit = 0;
+    p->lstate = EXPR_END;
+    newtok(p);
+    if (c == '-' || c == '+') {
+      tokadd(p, c);
+      c = nextc(p);
+    }
+    if (c == '0') {
+#define no_digits() do {yyerror(p,"numeric literal without digits"); return 0;} while (0)
+      int start = toklen(p);
+      c = nextc(p);
+      if (c == 'x' || c == 'X') {
+        /* hexadecimal */
+        c = nextc(p);
+        if (c >= 0 && ISXDIGIT(c)) {
+          do {
+            if (c == '_') {
+              if (nondigit) break;
+              nondigit = c;
+              continue;
+            }
+            if (!ISXDIGIT(c)) break;
+            nondigit = 0;
+            tokadd(p, tolower(c));
+          } while ((c = nextc(p)) >= 0);
+        }
+        pushback(p, c);
+        tokfix(p);
+        if (toklen(p) == start) {
+          no_digits();
+        }
+        else if (nondigit) goto trailing_uc;
+        pylval.nd = new_int(p, tok(p), 16);
+        return tINTEGER;
+      }
+      if (c == 'b' || c == 'B') {
+        /* binary */
+        c = nextc(p);
+        if (c == '0' || c == '1') {
+          do {
+            if (c == '_') {
+              if (nondigit) break;
+              nondigit = c;
+              continue;
+            }
+            if (c != '0' && c != '1') break;
+            nondigit = 0;
+            tokadd(p, c);
+          } while ((c = nextc(p)) >= 0);
+        }
+        pushback(p, c);
+        tokfix(p);
+        if (toklen(p) == start) {
+          no_digits();
+        }
+        else if (nondigit) goto trailing_uc;
+        pylval.nd = new_int(p, tok(p), 2);
+        return tINTEGER;
+      }
+      if (c == 'd' || c == 'D') {
+        /* decimal */
+        c = nextc(p);
+        if (c >= 0 && ISDIGIT(c)) {
+          do {
+            if (c == '_') {
+              if (nondigit) break;
+              nondigit = c;
+              continue;
+            }
+            if (!ISDIGIT(c)) break;
+            nondigit = 0;
+            tokadd(p, c);
+          } while ((c = nextc(p)) >= 0);
+        }
+        pushback(p, c);
+        tokfix(p);
+        if (toklen(p) == start) {
+          no_digits();
+        }
+        else if (nondigit) goto trailing_uc;
+        pylval.nd = new_int(p, tok(p), 10);
+        return tINTEGER;
+      }
+      if (c == '_') {
+        /* 0_0 */
+        goto octal_number;
+      }
+      if (c == 'o' || c == 'O') {
+        /* prefixed octal */
+        c = nextc(p);
+        if (c < 0 || c == '_' || !ISDIGIT(c)) {
+          no_digits();
+        }
+      }
+      if (c >= '0' && c <= '7') {
+        /* octal */
+        octal_number:
+        do {
+          if (c == '_') {
+            if (nondigit) break;
+            nondigit = c;
+            continue;
+          }
+          if (c < '0' || c > '9') break;
+          if (c > '7') goto invalid_octal;
+          nondigit = 0;
+          tokadd(p, c);
+        } while ((c = nextc(p)) >= 0);
+
+        if (toklen(p) > start) {
+          pushback(p, c);
+          tokfix(p);
+          if (nondigit) goto trailing_uc;
+          pylval.nd = new_int(p, tok(p), 8);
+          return tINTEGER;
+        }
+        if (nondigit) {
+          pushback(p, c);
+          goto trailing_uc;
+        }
+      }
+      if (c > '7' && c <= '9') {
+        invalid_octal:
+        yyerror(p, "Invalid octal digit");
+      }
+      else if (c == '.' || c == 'e' || c == 'E') {
+        tokadd(p, '0');
+      }
+      else {
+        pushback(p, c);
+        pylval.nd = new_int(p, "0", 10);
+        return tINTEGER;
+      }
+    }
+
+    for (;;) {
+      switch (c) {
+      case '0': case '1': case '2': case '3': case '4':
+      case '5': case '6': case '7': case '8': case '9':
+        nondigit = 0;
+        tokadd(p, c);
+        break;
+
+      case '.':
+        if (nondigit) goto trailing_uc;
+        if (seen_point || seen_e) {
+          goto decode_num;
+        }
+        else {
+          int c0 = nextc(p);
+          if (c0 < 0 || !ISDIGIT(c0)) {
+            pushback(p, c0);
+            goto decode_num;
+          }
+          c = c0;
+        }
+        tokadd(p, '.');
+        tokadd(p, c);
+        is_float++;
+        seen_point++;
+        nondigit = 0;
+        break;
+
+      case 'e':
+      case 'E':
+        if (nondigit) {
+          pushback(p, c);
+          c = nondigit;
+          goto decode_num;
+        }
+        if (seen_e) {
+          goto decode_num;
+        }
+        tokadd(p, c);
+        seen_e++;
+        is_float++;
+        nondigit = c;
+        c = nextc(p);
+        if (c != '-' && c != '+') continue;
+        tokadd(p, c);
+        nondigit = c;
+        break;
+
+      case '_':       /* '_' in number just ignored */
+        if (nondigit) goto decode_num;
+        nondigit = c;
+        break;
+
+      default:
+        goto decode_num;
+      }
+      c = nextc(p);
+    }
+
+    decode_num:
+    pushback(p, c);
+    if (nondigit) {
+      trailing_uc:
+      yyerror_i(p, "trailing '%c' in number", nondigit);
+    }
+    tokfix(p);
+    if (is_float) {
+      double d;
+      char *endp;
+
+      errno = 0;
+      d = mrb_float_read(tok(p), &endp);
+      if (d == 0 && endp == tok(p)) {
+        yywarning_s(p, "corrupted float value %s", tok(p));
+      }
+      else if (errno == ERANGE) {
+        yywarning_s(p, "float %s out of range", tok(p));
+        errno = 0;
+      }
+      pylval.nd = new_float(p, tok(p));
+      return tFLOAT;
+    }
+    pylval.nd = new_int(p, tok(p), 10);
+    return tINTEGER;
+  }
+
+  case ')':
+  case ']':
+    p->paren_nest--;
+    /* fall through */
+  case '}':
+    COND_LEXPOP();
+    CMDARG_LEXPOP();
+    if (c == ')')
+      p->lstate = EXPR_ENDFN;
+    else
+      p->lstate = EXPR_ENDARG;
+    return c;
+
+  case ':':
+    c = nextc(p);
+    if (c == ':') {
+      if (IS_BEG() || p->lstate == EXPR_CLASS || IS_SPCARG(-1)) {
+        p->lstate = EXPR_BEG;
+        return tCOLON3;
+      }
+      p->lstate = EXPR_DOT;
+      return tCOLON2;
+    }
+    if (IS_END() || ISSPACE(c)) {
+      pushback(p, c);
+      p->lstate = EXPR_BEG;
+      return ':';
+    }
+    pushback(p, c);
+    p->lstate = EXPR_FNAME;
+    return tSYMBEG;
+
+  case '/':
+    if (IS_BEG()) {
+      p->lex_strterm = new_strterm(p, str_regexp, '/', 0);
+      return tREGEXP_BEG;
+    }
+    if ((c = nextc(p)) == '=') {
+      pylval.id = intern_c('/');
+      p->lstate = EXPR_BEG;
+      return tOP_ASGN;
+    }
+    pushback(p, c);
+    if (IS_SPCARG(c)) {
+      p->lex_strterm = new_strterm(p, str_regexp, '/', 0);
+      return tREGEXP_BEG;
+    }
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+    }
+    else {
+      p->lstate = EXPR_BEG;
+    }
+    return '/';
+
+  case '^':
+    if ((c = nextc(p)) == '=') {
+      pylval.id = intern_c('^');
+      p->lstate = EXPR_BEG;
+      return tOP_ASGN;
+    }
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+    }
+    else {
+      p->lstate = EXPR_BEG;
+    }
+    pushback(p, c);
+    return '^';
+
+  case ';':
+    p->lstate = EXPR_BEG;
+    return ';';
+
+  case ',':
+    p->lstate = EXPR_BEG;
+    return ',';
+
+  case '~':
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      if ((c = nextc(p)) != '@') {
+        pushback(p, c);
+      }
+      p->lstate = EXPR_ARG;
+    }
+    else {
+      p->lstate = EXPR_BEG;
+    }
+    return '~';
+
+  case '(':
+    if (IS_BEG()) {
+      c = tLPAREN;
+    }
+    else if (IS_SPCARG(-1)) {
+      c = tLPAREN_ARG;
+    }
+    p->paren_nest++;
+    COND_PUSH(0);
+    CMDARG_PUSH(0);
+    p->lstate = EXPR_BEG;
+    return c;
+
+  case '[':
+    p->paren_nest++;
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+      if ((c = nextc(p)) == ']') {
+        if ((c = nextc(p)) == '=') {
+          return tASET;
+        }
+        pushback(p, c);
+        return tAREF;
+      }
+      pushback(p, c);
+      return '[';
+    }
+    else if (IS_BEG()) {
+      c = tLBRACK;
+    }
+    else if (IS_ARG() && space_seen) {
+      c = tLBRACK;
+    }
+    p->lstate = EXPR_BEG;
+    COND_PUSH(0);
+    CMDARG_PUSH(0);
+    return c;
+
+  case '{':
+    if (p->lpar_beg && p->lpar_beg == p->paren_nest) {
+      p->lstate = EXPR_BEG;
+      p->lpar_beg = 0;
+      p->paren_nest--;
+      COND_PUSH(0);
+      CMDARG_PUSH(0);
+      return tLAMBEG;
+    }
+    if (IS_ARG() || p->lstate == EXPR_END || p->lstate == EXPR_ENDFN)
+      c = '{';          /* block (primary) */
+    else if (p->lstate == EXPR_ENDARG)
+      c = tLBRACE_ARG;  /* block (expr) */
+    else
+      c = tLBRACE;      /* hash */
+    COND_PUSH(0);
+    CMDARG_PUSH(0);
+    p->lstate = EXPR_BEG;
+    return c;
+
+  case '\\':
+    c = nextc(p);
+    if (c == '\n') {
+      p->lineno++;
+      p->column = 0;
+      space_seen = 1;
+      goto retry; /* skip \\n */
+    }
+    pushback(p, c);
+    return '\\';
+
+  case '%':
+    if (IS_BEG()) {
+      int term;
+      int paren;
+
+      c = nextc(p);
+      quotation:
+      if (c < 0 || !ISALNUM(c)) {
+        term = c;
+        c = 'Q';
+      }
+      else {
+        term = nextc(p);
+        if (isalnum(term)) {
+          yyerror(p, "unknown type of %string");
+          return 0;
+        }
+      }
+      if (c < 0 || term < 0) {
+        yyerror(p, "unterminated quoted string meets end of file");
+        return 0;
+      }
+      paren = term;
+      if (term == '(') term = ')';
+      else if (term == '[') term = ']';
+      else if (term == '{') term = '}';
+      else if (term == '<') term = '>';
+      else paren = 0;
+
+      switch (c) {
+      case 'Q':
+        p->lex_strterm = new_strterm(p, str_dquote, term, paren);
+        return tSTRING_BEG;
+
+      case 'q':
+        p->lex_strterm = new_strterm(p, str_squote, term, paren);
+        return parse_string(p);
+
+      case 'W':
+        p->lex_strterm = new_strterm(p, str_dword, term, paren);
+        return tWORDS_BEG;
+
+      case 'w':
+        p->lex_strterm = new_strterm(p, str_sword, term, paren);
+        return tWORDS_BEG;
+
+      case 'x':
+        p->lex_strterm = new_strterm(p, str_xquote, term, paren);
+        return tXSTRING_BEG;
+
+      case 'r':
+        p->lex_strterm = new_strterm(p, str_regexp, term, paren);
+        return tREGEXP_BEG;
+
+      case 's':
+        p->lex_strterm = new_strterm(p, str_ssym, term, paren);
+        return tSYMBEG;
+
+      case 'I':
+        p->lex_strterm = new_strterm(p, str_dsymbols, term, paren);
+        return tSYMBOLS_BEG;
+
+      case 'i':
+        p->lex_strterm = new_strterm(p, str_ssymbols, term, paren);
+        return tSYMBOLS_BEG;
+
+      default:
+        yyerror(p, "unknown type of %string");
+        return 0;
+      }
+    }
+    if ((c = nextc(p)) == '=') {
+      pylval.id = intern_c('%');
+      p->lstate = EXPR_BEG;
+      return tOP_ASGN;
+    }
+    if (IS_SPCARG(c)) {
+      goto quotation;
+    }
+    if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
+      p->lstate = EXPR_ARG;
+    }
+    else {
+      p->lstate = EXPR_BEG;
+    }
+    pushback(p, c);
+    return '%';
+
+  case '$':
+    p->lstate = EXPR_END;
+    token_column = newtok(p);
+    c = nextc(p);
+    if (c < 0) {
+      yyerror(p, "incomplete global variable syntax");
+      return 0;
+    }
+    switch (c) {
+    case '_':     /* $_: last read line string */
+      c = nextc(p);
+      if (c >= 0 && identchar(c)) { /* if there is more after _ it is a variable */
+        tokadd(p, '$');
+        tokadd(p, c);
+        break;
+      }
+      pushback(p, c);
+      c = '_';
+      /* fall through */
+    case '~':     /* $~: match-data */
+    case '*':     /* $*: argv */
+    case '$':     /* $$: pid */
+    case '?':     /* $?: last status */
+    case '!':     /* $!: error string */
+    case '@':     /* $@: error position */
+    case '/':     /* $/: input record separator */
+    case '\\':    /* $\: output record separator */
+    case ';':     /* $;: field separator */
+    case ',':     /* $,: output field separator */
+    case '.':     /* $.: last read line number */
+    case '=':     /* $=: ignorecase */
+    case ':':     /* $:: load path */
+    case '<':     /* $<: reading filename */
+    case '>':     /* $>: default output handle */
+    case '\"':    /* $": already loaded files */
+      tokadd(p, '$');
+      tokadd(p, c);
+      tokfix(p);
+      pylval.id = intern_cstr(tok(p));
+      return tGVAR;
+
+    case '-':
+      tokadd(p, '$');
+      tokadd(p, c);
+      c = nextc(p);
+      pushback(p, c);
+      gvar:
+      tokfix(p);
+      pylval.id = intern_cstr(tok(p));
+      return tGVAR;
+
+    case '&':     /* $&: last match */
+    case '`':     /* $`: string before last match */
+    case '\'':    /* $': string after last match */
+    case '+':     /* $+: string matches last pattern */
+      if (last_state == EXPR_FNAME) {
+        tokadd(p, '$');
+        tokadd(p, c);
+        goto gvar;
+      }
+      pylval.nd = new_back_ref(p, c);
+      return tBACK_REF;
+
+    case '1': case '2': case '3':
+    case '4': case '5': case '6':
+    case '7': case '8': case '9':
+      do {
+        tokadd(p, c);
+        c = nextc(p);
+      } while (c >= 0 && isdigit(c));
+      pushback(p, c);
+      if (last_state == EXPR_FNAME) goto gvar;
+      tokfix(p);
+      {
+        unsigned long n = strtoul(tok(p), NULL, 10);
+        if (n > INT_MAX) {
+          yyerror_i(p, "capture group index must be <= %d", INT_MAX);
+          return 0;
+        }
+        pylval.nd = new_nth_ref(p, (int)n);
+      }
+      return tNTH_REF;
+
+    default:
+      if (!identchar(c)) {
+        pushback(p,  c);
+        return '$';
+      }
+      /* fall through */
+    case '0':
+      tokadd(p, '$');
+    }
+    break;
+
+    case '@':
+      c = nextc(p);
+      token_column = newtok(p);
+      tokadd(p, '@');
+      if (c == '@') {
+        tokadd(p, '@');
+        c = nextc(p);
+      }
+      if (c < 0) {
+        if (p->tidx == 1) {
+          yyerror(p, "incomplete instance variable syntax");
+        }
+        else {
+          yyerror(p, "incomplete class variable syntax");
+        }
+        return 0;
+      }
+      else if (isdigit(c)) {
+        if (p->tidx == 1) {
+          yyerror_i(p, "'@%c' is not allowed as an instance variable name", c);
+        }
+        else {
+          yyerror_i(p, "'@@%c' is not allowed as a class variable name", c);
+        }
+        return 0;
+      }
+      if (!identchar(c)) {
+        pushback(p, c);
+        return '@';
+      }
+      break;
+
+    case '_':
+      token_column = newtok(p);
+      break;
+
+    default:
+      if (!identchar(c)) {
+        yyerror_i(p,  "Invalid char '\\x%02X' in expression", c);
+        goto retry;
+      }
+
+      token_column = newtok(p);
+      break;
+  }
+
+  do {
+    tokadd(p, c);
+    c = nextc(p);
+    if (c < 0) break;
+  } while (identchar(c));
+  if (token_column == 0 && toklen(p) == 7 && (c < 0 || c == '\n') &&
+      strncmp(tok(p), "__END__", toklen(p)) == 0)
+    return -1;
+
+  switch (tok(p)[0]) {
+  case '@': case '$':
+    pushback(p, c);
+    break;
+  default:
+    if ((c == '!' || c == '?') && !peek(p, '=')) {
+      tokadd(p, c);
+    }
+    else {
+      pushback(p, c);
+    }
+  }
+  tokfix(p);
+  {
+    int result = 0;
+
+    switch (tok(p)[0]) {
+    case '$':
+      p->lstate = EXPR_END;
+      result = tGVAR;
+      break;
+    case '@':
+      p->lstate = EXPR_END;
+      if (tok(p)[1] == '@')
+        result = tCVAR;
+      else
+        result = tIVAR;
+      break;
+
+    default:
+      if (toklast(p) == '!' || toklast(p) == '?') {
+        result = tFID;
+      }
+      else {
+        if (p->lstate == EXPR_FNAME) {
+          if ((c = nextc(p)) == '=' && !peek(p, '~') && !peek(p, '>') &&
+              (!peek(p, '=') || (peek_n(p, '>', 1)))) {
+            result = tIDENTIFIER;
+            tokadd(p, c);
+            tokfix(p);
+          }
+          else {
+            pushback(p, c);
+          }
+        }
+        if (result == 0 && ISUPPER(tok(p)[0])) {
+          result = tCONSTANT;
+        }
+        else {
+          result = tIDENTIFIER;
+        }
+      }
+
+      if (IS_LABEL_POSSIBLE()) {
+        if (IS_LABEL_SUFFIX(0)) {
+          p->lstate = EXPR_BEG;
+          nextc(p);
+          tokfix(p);
+          pylval.id = intern_cstr(tok(p));
+          return tLABEL;
+        }
+      }
+      if (p->lstate != EXPR_DOT) {
+        const struct kwtable *kw;
+
+        /* See if it is a reserved word.  */
+        kw = mrb_reserved_word(tok(p), toklen(p));
+        if (kw) {
+          enum mrb_lex_state_enum state = p->lstate;
+          pylval.num = p->lineno;
+          p->lstate = kw->state;
+          if (state == EXPR_FNAME) {
+            pylval.id = intern_cstr(kw->name);
+            return kw->id[0];
+          }
+          if (p->lstate == EXPR_BEG) {
+            p->cmd_start = TRUE;
+          }
+          if (kw->id[0] == keyword_do) {
+            if (p->lpar_beg && p->lpar_beg == p->paren_nest) {
+              p->lpar_beg = 0;
+              p->paren_nest--;
+              return keyword_do_LAMBDA;
+            }
+            if (COND_P()) return keyword_do_cond;
+            if (CMDARG_P() && state != EXPR_CMDARG)
+              return keyword_do_block;
+            if (state == EXPR_ENDARG || state == EXPR_BEG)
+              return keyword_do_block;
+            return keyword_do;
+          }
+          if (state == EXPR_BEG || state == EXPR_VALUE)
+            return kw->id[0];
+          else {
+            if (kw->id[0] != kw->id[1])
+              p->lstate = EXPR_BEG;
+            return kw->id[1];
+          }
+        }
+      }
+
+      if (IS_BEG() || p->lstate == EXPR_DOT || IS_ARG()) {
+        if (cmd_state) {
+          p->lstate = EXPR_CMDARG;
+        }
+        else {
+          p->lstate = EXPR_ARG;
+        }
+      }
+      else if (p->lstate == EXPR_FNAME) {
+        p->lstate = EXPR_ENDFN;
+      }
+      else {
+        p->lstate = EXPR_END;
+      }
+    }
+    {
+      mrb_sym ident = intern_cstr(tok(p));
+
+      pylval.id = ident;
+#if 0
+      if (last_state != EXPR_DOT && islower(tok(p)[0]) && lvar_defined(ident)) {
+        p->lstate = EXPR_END;
+      }
+#endif
+    }
+    return result;
+  }
+}
+
+static int
+yylex(void *lval, parser_state *p)
+{
+  p->ylval = lval;
+  return parser_yylex(p);
+}
+
+static void
+parser_init_cxt(parser_state *p, mrbc_context *cxt)
+{
+  if (!cxt) return;
+  if (cxt->filename) mrb_parser_set_filename(p, cxt->filename);
+  if (cxt->lineno) p->lineno = cxt->lineno;
+  if (cxt->syms) {
+    int i;
+
+    p->locals = cons(0,0);
+    for (i=0; i<cxt->slen; i++) {
+      local_add_f(p, cxt->syms[i]);
+    }
+  }
+  p->capture_errors = cxt->capture_errors;
+  p->no_optimize = cxt->no_optimize;
+  if (cxt->partial_hook) {
+    p->cxt = cxt;
+  }
+}
+
+static void
+parser_update_cxt(parser_state *p, mrbc_context *cxt)
+{
+  node *n, *n0;
+  int i = 0;
+
+  if (!cxt) return;
+  if ((int)(intptr_t)p->tree->car != NODE_SCOPE) return;
+  n0 = n = p->tree->cdr->car;
+  while (n) {
+    i++;
+    n = n->cdr;
+  }
+  cxt->syms = (mrb_sym *)mrb_realloc(p->mrb, cxt->syms, i*sizeof(mrb_sym));
+  cxt->slen = i;
+  for (i=0, n=n0; n; i++,n=n->cdr) {
+    cxt->syms[i] = sym(n->car);
+  }
+}
+
+void mrb_codedump_all(mrb_state*, struct RProc*);
+void mrb_parser_dump(mrb_state *mrb, node *tree, int offset);
+
+MRB_API void
+mrb_parser_parse(parser_state *p, mrbc_context *c)
+{
+  struct mrb_jmpbuf buf1;
+  p->jmp = &buf1;
+
+  MRB_TRY(p->jmp) {
+    int n;
+
+    p->cmd_start = TRUE;
+    p->in_def = p->in_single = 0;
+    p->nerr = p->nwarn = 0;
+    p->lex_strterm = NULL;
+
+    parser_init_cxt(p, c);
+
+    if (p->mrb->jmp) {
+      n = yyparse(p);
+    }
+    else {
+      struct mrb_jmpbuf buf2;
+
+      p->mrb->jmp = &buf2;
+      MRB_TRY(p->mrb->jmp) {
+        n = yyparse(p);
+      }
+      MRB_CATCH(p->mrb->jmp) {
+        p->nerr++;
+      }
+      MRB_END_EXC(p->mrb->jmp);
+      p->mrb->jmp = 0;
+    }
+    if (n != 0 || p->nerr > 0) {
+      p->tree = 0;
+      return;
+    }
+    if (!p->tree) {
+      p->tree = new_nil(p);
+    }
+    parser_update_cxt(p, c);
+    if (c && c->dump_result) {
+      mrb_parser_dump(p->mrb, p->tree, 0);
+    }
+  }
+  MRB_CATCH(p->jmp) {
+    yyerror(p, "memory allocation error");
+    p->nerr++;
+    p->tree = 0;
+    return;
+  }
+  MRB_END_EXC(p->jmp);
+}
+
+MRB_API parser_state*
+mrb_parser_new(mrb_state *mrb)
+{
+  mrb_pool *pool;
+  parser_state *p;
+  static const parser_state parser_state_zero = { 0 };
+
+  pool = mrb_pool_open(mrb);
+  if (!pool) return NULL;
+  p = (parser_state *)mrb_pool_alloc(pool, sizeof(parser_state));
+  if (!p) return NULL;
+
+  *p = parser_state_zero;
+  p->mrb = mrb;
+  p->pool = pool;
+
+  p->s = p->send = NULL;
+#ifndef MRB_DISABLE_STDIO
+  p->f = NULL;
+#endif
+
+  p->cmd_start = TRUE;
+  p->in_def = p->in_single = 0;
+
+  p->capture_errors = FALSE;
+  p->lineno = 1;
+  p->column = 0;
+#if defined(PARSER_TEST) || defined(PARSER_DEBUG)
+  yydebug = 1;
+#endif
+  p->tsiz = MRB_PARSER_TOKBUF_SIZE;
+  p->tokbuf = p->buf;
+
+  p->lex_strterm = NULL;
+  p->all_heredocs = p->parsing_heredoc = NULL;
+  p->lex_strterm_before_heredoc = NULL;
+
+  p->current_filename_index = -1;
+  p->filename_table = NULL;
+  p->filename_table_length = 0;
+
+  return p;
+}
+
+MRB_API void
+mrb_parser_free(parser_state *p) {
+  if (p->tokbuf != p->buf) {
+    mrb_free(p->mrb, p->tokbuf);
+  }
+  mrb_pool_close(p->pool);
+}
+
+MRB_API mrbc_context*
+mrbc_context_new(mrb_state *mrb)
+{
+  return (mrbc_context *)mrb_calloc(mrb, 1, sizeof(mrbc_context));
+}
+
+MRB_API void
+mrbc_context_free(mrb_state *mrb, mrbc_context *cxt)
+{
+  mrb_free(mrb, cxt->filename);
+  mrb_free(mrb, cxt->syms);
+  mrb_free(mrb, cxt);
+}
+
+MRB_API const char*
+mrbc_filename(mrb_state *mrb, mrbc_context *c, const char *s)
+{
+  if (s) {
+    int len = strlen(s);
+    char *p = (char *)mrb_malloc(mrb, len + 1);
+
+    memcpy(p, s, len + 1);
+    if (c->filename) {
+      mrb_free(mrb, c->filename);
+    }
+    c->filename = p;
+  }
+  return c->filename;
+}
+
+MRB_API void
+mrbc_partial_hook(mrb_state *mrb, mrbc_context *c, int (*func)(struct mrb_parser_state*), void *data)
+{
+  c->partial_hook = func;
+  c->partial_data = data;
+}
+
+MRB_API void
+mrb_parser_set_filename(struct mrb_parser_state *p, const char *f)
+{
+  mrb_sym sym;
+  size_t i;
+  mrb_sym* new_table;
+
+  sym = mrb_intern_cstr(p->mrb, f);
+  p->filename = mrb_sym2name_len(p->mrb, sym, NULL);
+  p->lineno = (p->filename_table_length > 0)? 0 : 1;
+
+  for (i = 0; i < p->filename_table_length; ++i) {
+    if (p->filename_table[i] == sym) {
+      p->current_filename_index = i;
+      return;
+    }
+  }
+
+  p->current_filename_index = p->filename_table_length++;
+
+  new_table = (mrb_sym*)parser_palloc(p, sizeof(mrb_sym) * p->filename_table_length);
+  if (p->filename_table) {
+    memmove(new_table, p->filename_table, sizeof(mrb_sym) * p->filename_table_length);
+  }
+  p->filename_table = new_table;
+  p->filename_table[p->filename_table_length - 1] = sym;
+}
+
+MRB_API char const*
+mrb_parser_get_filename(struct mrb_parser_state* p, uint16_t idx) {
+  if (idx >= p->filename_table_length) { return NULL; }
+  else {
+    return mrb_sym2name_len(p->mrb, p->filename_table[idx], NULL);
+  }
+}
+
+#ifndef MRB_DISABLE_STDIO
+MRB_API parser_state*
+mrb_parse_file(mrb_state *mrb, FILE *f, mrbc_context *c)
+{
+  parser_state *p;
+
+  p = mrb_parser_new(mrb);
+  if (!p) return NULL;
+  p->s = p->send = NULL;
+  p->f = f;
+
+  mrb_parser_parse(p, c);
+  return p;
+}
+#endif
+
+MRB_API parser_state*
+mrb_parse_nstring(mrb_state *mrb, const char *s, int len, mrbc_context *c)
+{
+  parser_state *p;
+
+  p = mrb_parser_new(mrb);
+  if (!p) return NULL;
+  p->s = s;
+  p->send = s + len;
+
+  mrb_parser_parse(p, c);
+  return p;
+}
+
+MRB_API parser_state*
+mrb_parse_string(mrb_state *mrb, const char *s, mrbc_context *c)
+{
+  return mrb_parse_nstring(mrb, s, strlen(s), c);
+}
+
+MRB_API mrb_value
+mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c)
+{
+  struct RClass *target = mrb->object_class;
+  struct RProc *proc;
+  mrb_value v;
+  unsigned int keep = 0;
+
+  if (!p) {
+    return mrb_undef_value();
+  }
+  if (!p->tree || p->nerr) {
+    if (p->capture_errors) {
+      char buf[256];
+      int n;
+
+      n = snprintf(buf, sizeof(buf), "line %d: %s\n",
+          p->error_buffer[0].lineno, p->error_buffer[0].message);
+      mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, n));
+      mrb_parser_free(p);
+      return mrb_undef_value();
+    }
+    else {
+      if (mrb->exc == NULL) {
+        mrb->exc = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, E_SYNTAX_ERROR, "syntax error"));
+      }
+      mrb_parser_free(p);
+      return mrb_undef_value();
+    }
+  }
+  proc = mrb_generate_code(mrb, p);
+  mrb_parser_free(p);
+  if (proc == NULL) {
+    if (mrb->exc == NULL) {
+      mrb->exc = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, E_SCRIPT_ERROR, "codegen error"));
+    }
+    return mrb_undef_value();
+  }
+  if (c) {
+    if (c->dump_result) mrb_codedump_all(mrb, proc);
+    if (c->no_exec) return mrb_obj_value(proc);
+    if (c->target_class) {
+      target = c->target_class;
+    }
+    if (c->keep_lv) {
+      keep = c->slen + 1;
+    }
+    else {
+      c->keep_lv = TRUE;
+    }
+  }
+  proc->target_class = target;
+  if (mrb->c->ci) {
+    mrb->c->ci->target_class = target;
+  }
+  v = mrb_top_run(mrb, proc, mrb_top_self(mrb), keep);
+  if (mrb->exc) return mrb_nil_value();
+  return v;
+}
+
+#ifndef MRB_DISABLE_STDIO
+MRB_API mrb_value
+mrb_load_file_cxt(mrb_state *mrb, FILE *f, mrbc_context *c)
+{
+  return mrb_load_exec(mrb, mrb_parse_file(mrb, f, c), c);
+}
+
+MRB_API mrb_value
+mrb_load_file(mrb_state *mrb, FILE *f)
+{
+  return mrb_load_file_cxt(mrb, f, NULL);
+}
+#endif
+
+MRB_API mrb_value
+mrb_load_nstring_cxt(mrb_state *mrb, const char *s, int len, mrbc_context *c)
+{
+  return mrb_load_exec(mrb, mrb_parse_nstring(mrb, s, len, c), c);
+}
+
+MRB_API mrb_value
+mrb_load_nstring(mrb_state *mrb, const char *s, int len)
+{
+  return mrb_load_nstring_cxt(mrb, s, len, NULL);
+}
+
+MRB_API mrb_value
+mrb_load_string_cxt(mrb_state *mrb, const char *s, mrbc_context *c)
+{
+  return mrb_load_nstring_cxt(mrb, s, strlen(s), c);
+}
+
+MRB_API mrb_value
+mrb_load_string(mrb_state *mrb, const char *s)
+{
+  return mrb_load_string_cxt(mrb, s, NULL);
+}
+
+#ifndef MRB_DISABLE_STDIO
+
+static void
+dump_prefix(node *tree, int offset)
+{
+  printf("%05d ", tree->lineno);
+  while (offset--) {
+    putc(' ', stdout);
+    putc(' ', stdout);
+  }
+}
+
+static void
+dump_recur(mrb_state *mrb, node *tree, int offset)
+{
+  while (tree) {
+    mrb_parser_dump(mrb, tree->car, offset);
+    tree = tree->cdr;
+  }
+}
+
+#endif
+
+void
+mrb_parser_dump(mrb_state *mrb, node *tree, int offset)
+{
+#ifndef MRB_DISABLE_STDIO
+  int nodetype;
+
+  if (!tree) return;
+  again:
+  dump_prefix(tree, offset);
+  nodetype = (int)(intptr_t)tree->car;
+  tree = tree->cdr;
+  switch (nodetype) {
+  case NODE_BEGIN:
+    printf("NODE_BEGIN:\n");
+    dump_recur(mrb, tree, offset+1);
+    break;
+
+  case NODE_RESCUE:
+    printf("NODE_RESCUE:\n");
+    if (tree->car) {
+      dump_prefix(tree, offset+1);
+      printf("body:\n");
+      mrb_parser_dump(mrb, tree->car, offset+2);
+    }
+    tree = tree->cdr;
+    if (tree->car) {
+      node *n2 = tree->car;
+
+      dump_prefix(n2, offset+1);
+      printf("rescue:\n");
+      while (n2) {
+        node *n3 = n2->car;
+        if (n3->car) {
+          dump_prefix(n2, offset+2);
+          printf("handle classes:\n");
+          dump_recur(mrb, n3->car, offset+3);
+        }
+        if (n3->cdr->car) {
+          dump_prefix(n3, offset+2);
+          printf("exc_var:\n");
+          mrb_parser_dump(mrb, n3->cdr->car, offset+3);
+        }
+        if (n3->cdr->cdr->car) {
+          dump_prefix(n3, offset+2);
+          printf("rescue body:\n");
+          mrb_parser_dump(mrb, n3->cdr->cdr->car, offset+3);
+        }
+        n2 = n2->cdr;
+      }
+    }
+    tree = tree->cdr;
+    if (tree->car) {
+      dump_prefix(tree, offset+1);
+      printf("else:\n");
+      mrb_parser_dump(mrb, tree->car, offset+2);
+    }
+    break;
+
+  case NODE_ENSURE:
+    printf("NODE_ENSURE:\n");
+    dump_prefix(tree, offset+1);
+    printf("body:\n");
+    mrb_parser_dump(mrb, tree->car, offset+2);
+    dump_prefix(tree, offset+1);
+    printf("ensure:\n");
+    mrb_parser_dump(mrb, tree->cdr->cdr, offset+2);
+    break;
+
+  case NODE_LAMBDA:
+    printf("NODE_BLOCK:\n");
+    goto block;
+
+  case NODE_BLOCK:
+    block:
+    printf("NODE_BLOCK:\n");
+    tree = tree->cdr;
+    if (tree->car) {
+      node *n = tree->car;
+
+      if (n->car) {
+        dump_prefix(n, offset+1);
+        printf("mandatory args:\n");
+        dump_recur(mrb, n->car, offset+2);
+      }
+      n = n->cdr;
+      if (n->car) {
+        dump_prefix(n, offset+1);
+        printf("optional args:\n");
+        {
+          node *n2 = n->car;
+
+          while (n2) {
+            dump_prefix(n2, offset+2);
+            printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
+            mrb_parser_dump(mrb, n2->car->cdr, 0);
+            n2 = n2->cdr;
+          }
+        }
+      }
+      n = n->cdr;
+      if (n->car) {
+        dump_prefix(n, offset+1);
+        printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
+      }
+      n = n->cdr;
+      if (n->car) {
+        dump_prefix(n, offset+1);
+        printf("post mandatory args:\n");
+        dump_recur(mrb, n->car, offset+2);
+      }
+      if (n->cdr) {
+        dump_prefix(n, offset+1);
+        printf("blk=&%s\n", mrb_sym2name(mrb, sym(n->cdr)));
+      }
+    }
+    dump_prefix(tree, offset+1);
+    printf("body:\n");
+    mrb_parser_dump(mrb, tree->cdr->car, offset+2);
+    break;
+
+  case NODE_IF:
+    printf("NODE_IF:\n");
+    dump_prefix(tree, offset+1);
+    printf("cond:\n");
+    mrb_parser_dump(mrb, tree->car, offset+2);
+    dump_prefix(tree, offset+1);
+    printf("then:\n");
+    mrb_parser_dump(mrb, tree->cdr->car, offset+2);
+    if (tree->cdr->cdr->car) {
+      dump_prefix(tree, offset+1);
+      printf("else:\n");
+      mrb_parser_dump(mrb, tree->cdr->cdr->car, offset+2);
+    }
+    break;
+
+  case NODE_AND:
+    printf("NODE_AND:\n");
+    mrb_parser_dump(mrb, tree->car, offset+1);
+    mrb_parser_dump(mrb, tree->cdr, offset+1);
+    break;
+
+  case NODE_OR:
+    printf("NODE_OR:\n");
+    mrb_parser_dump(mrb, tree->car, offset+1);
+    mrb_parser_dump(mrb, tree->cdr, offset+1);
+    break;
+
+  case NODE_CASE:
+    printf("NODE_CASE:\n");
+    if (tree->car) {
+      mrb_parser_dump(mrb, tree->car, offset+1);
+    }
+    tree = tree->cdr;
+    while (tree) {
+      dump_prefix(tree, offset+1);
+      printf("case:\n");
+      dump_recur(mrb, tree->car->car, offset+2);
+      dump_prefix(tree, offset+1);
+      printf("body:\n");
+      mrb_parser_dump(mrb, tree->car->cdr, offset+2);
+      tree = tree->cdr;
+    }
+    break;
+
+  case NODE_WHILE:
+    printf("NODE_WHILE:\n");
+    dump_prefix(tree, offset+1);
+    printf("cond:\n");
+    mrb_parser_dump(mrb, tree->car, offset+2);
+    dump_prefix(tree, offset+1);
+    printf("body:\n");
+    mrb_parser_dump(mrb, tree->cdr, offset+2);
+    break;
+
+  case NODE_UNTIL:
+    printf("NODE_UNTIL:\n");
+    dump_prefix(tree, offset+1);
+    printf("cond:\n");
+    mrb_parser_dump(mrb, tree->car, offset+2);
+    dump_prefix(tree, offset+1);
+    printf("body:\n");
+    mrb_parser_dump(mrb, tree->cdr, offset+2);
+    break;
+
+  case NODE_FOR:
+    printf("NODE_FOR:\n");
+    dump_prefix(tree, offset+1);
+    printf("var:\n");
+    {
+      node *n2 = tree->car;
+
+      if (n2->car) {
+        dump_prefix(n2, offset+2);
+        printf("pre:\n");
+        dump_recur(mrb, n2->car, offset+3);
+      }
+      n2 = n2->cdr;
+      if (n2) {
+        if (n2->car) {
+          dump_prefix(n2, offset+2);
+          printf("rest:\n");
+          mrb_parser_dump(mrb, n2->car, offset+3);
+        }
+        n2 = n2->cdr;
+        if (n2) {
+          if (n2->car) {
+            dump_prefix(n2, offset+2);
+            printf("post:\n");
+            dump_recur(mrb, n2->car, offset+3);
+          }
+        }
+      }
+    }
+    tree = tree->cdr;
+    dump_prefix(tree, offset+1);
+    printf("in:\n");
+    mrb_parser_dump(mrb, tree->car, offset+2);
+    tree = tree->cdr;
+    dump_prefix(tree, offset+1);
+    printf("do:\n");
+    mrb_parser_dump(mrb, tree->car, offset+2);
+    break;
+
+  case NODE_SCOPE:
+    printf("NODE_SCOPE:\n");
+    {
+      node *n2 = tree->car;
+      mrb_bool first_lval = TRUE;
+
+      if (n2 && (n2->car || n2->cdr)) {
+        dump_prefix(n2, offset+1);
+        printf("local variables:\n");
+        dump_prefix(n2, offset+2);
+        while (n2) {
+          if (n2->car) {
+            if (!first_lval) printf(", ");
+            printf("%s", mrb_sym2name(mrb, sym(n2->car)));
+            first_lval = FALSE;
+          }
+          n2 = n2->cdr;
+        }
+        printf("\n");
+      }
+    }
+    tree = tree->cdr;
+    offset++;
+    goto again;
+
+  case NODE_FCALL:
+  case NODE_CALL:
+  case NODE_SCALL:
+    switch (nodetype) {
+    case NODE_FCALL:
+      printf("NODE_FCALL:\n"); break;
+    case NODE_CALL:
+      printf("NODE_CALL(.):\n"); break;
+    case NODE_SCALL:
+      printf("NODE_SCALL(&.):\n"); break;
+    default:
+      break;
+    }
+    mrb_parser_dump(mrb, tree->car, offset+1);
+    dump_prefix(tree, offset+1);
+    printf("method='%s' (%d)\n",
+        mrb_sym2name(mrb, sym(tree->cdr->car)),
+        (int)(intptr_t)tree->cdr->car);
+    tree = tree->cdr->cdr->car;
+    if (tree) {
+      dump_prefix(tree, offset+1);
+      printf("args:\n");
+      dump_recur(mrb, tree->car, offset+2);
+      if (tree->cdr) {
+        dump_prefix(tree, offset+1);
+        printf("block:\n");
+        mrb_parser_dump(mrb, tree->cdr, offset+2);
+      }
+    }
+    break;
+
+  case NODE_DOT2:
+    printf("NODE_DOT2:\n");
+    mrb_parser_dump(mrb, tree->car, offset+1);
+    mrb_parser_dump(mrb, tree->cdr, offset+1);
+    break;
+
+  case NODE_DOT3:
+    printf("NODE_DOT3:\n");
+    mrb_parser_dump(mrb, tree->car, offset+1);
+    mrb_parser_dump(mrb, tree->cdr, offset+1);
+    break;
+
+  case NODE_COLON2:
+    printf("NODE_COLON2:\n");
+    mrb_parser_dump(mrb, tree->car, offset+1);
+    dump_prefix(tree, offset+1);
+    printf("::%s\n", mrb_sym2name(mrb, sym(tree->cdr)));
+    break;
+
+  case NODE_COLON3:
+    printf("NODE_COLON3: ::%s\n", mrb_sym2name(mrb, sym(tree)));
+    break;
+
+  case NODE_ARRAY:
+    printf("NODE_ARRAY:\n");
+    dump_recur(mrb, tree, offset+1);
+    break;
+
+  case NODE_HASH:
+    printf("NODE_HASH:\n");
+    while (tree) {
+      dump_prefix(tree, offset+1);
+      printf("key:\n");
+      mrb_parser_dump(mrb, tree->car->car, offset+2);
+      dump_prefix(tree, offset+1);
+      printf("value:\n");
+      mrb_parser_dump(mrb, tree->car->cdr, offset+2);
+      tree = tree->cdr;
+    }
+    break;
+
+  case NODE_SPLAT:
+    printf("NODE_SPLAT:\n");
+    mrb_parser_dump(mrb, tree, offset+1);
+    break;
+
+  case NODE_ASGN:
+    printf("NODE_ASGN:\n");
+    dump_prefix(tree, offset+1);
+    printf("lhs:\n");
+    mrb_parser_dump(mrb, tree->car, offset+2);
+    dump_prefix(tree, offset+1);
+    printf("rhs:\n");
+    mrb_parser_dump(mrb, tree->cdr, offset+2);
+    break;
+
+  case NODE_MASGN:
+    printf("NODE_MASGN:\n");
+    dump_prefix(tree, offset+1);
+    printf("mlhs:\n");
+    {
+      node *n2 = tree->car;
+
+      if (n2->car) {
+        dump_prefix(tree, offset+2);
+        printf("pre:\n");
+        dump_recur(mrb, n2->car, offset+3);
+      }
+      n2 = n2->cdr;
+      if (n2) {
+        if (n2->car) {
+          dump_prefix(n2, offset+2);
+          printf("rest:\n");
+          if (n2->car == (node*)-1) {
+            dump_prefix(n2, offset+2);
+            printf("(empty)\n");
+          }
+          else {
+            mrb_parser_dump(mrb, n2->car, offset+3);
+          }
+        }
+        n2 = n2->cdr;
+        if (n2) {
+          if (n2->car) {
+            dump_prefix(n2, offset+2);
+            printf("post:\n");
+            dump_recur(mrb, n2->car, offset+3);
+          }
+        }
+      }
+    }
+    dump_prefix(tree, offset+1);
+    printf("rhs:\n");
+    mrb_parser_dump(mrb, tree->cdr, offset+2);
+    break;
+
+  case NODE_OP_ASGN:
+    printf("NODE_OP_ASGN:\n");
+    dump_prefix(tree, offset+1);
+    printf("lhs:\n");
+    mrb_parser_dump(mrb, tree->car, offset+2);
+    tree = tree->cdr;
+    dump_prefix(tree, offset+1);
+    printf("op='%s' (%d)\n", mrb_sym2name(mrb, sym(tree->car)), (int)(intptr_t)tree->car);
+    tree = tree->cdr;
+    mrb_parser_dump(mrb, tree->car, offset+1);
+    break;
+
+  case NODE_SUPER:
+    printf("NODE_SUPER:\n");
+    if (tree) {
+      dump_prefix(tree, offset+1);
+      printf("args:\n");
+      dump_recur(mrb, tree->car, offset+2);
+      if (tree->cdr) {
+        dump_prefix(tree, offset+1);
+        printf("block:\n");
+        mrb_parser_dump(mrb, tree->cdr, offset+2);
+      }
+    }
+    break;
+
+  case NODE_ZSUPER:
+    printf("NODE_ZSUPER\n");
+    break;
+
+  case NODE_RETURN:
+    printf("NODE_RETURN:\n");
+    mrb_parser_dump(mrb, tree, offset+1);
+    break;
+
+  case NODE_YIELD:
+    printf("NODE_YIELD:\n");
+    dump_recur(mrb, tree, offset+1);
+    break;
+
+  case NODE_BREAK:
+    printf("NODE_BREAK:\n");
+    mrb_parser_dump(mrb, tree, offset+1);
+    break;
+
+  case NODE_NEXT:
+    printf("NODE_NEXT:\n");
+    mrb_parser_dump(mrb, tree, offset+1);
+    break;
+
+  case NODE_REDO:
+    printf("NODE_REDO\n");
+    break;
+
+  case NODE_RETRY:
+    printf("NODE_RETRY\n");
+    break;
+
+  case NODE_LVAR:
+    printf("NODE_LVAR %s\n", mrb_sym2name(mrb, sym(tree)));
+    break;
+
+  case NODE_GVAR:
+    printf("NODE_GVAR %s\n", mrb_sym2name(mrb, sym(tree)));
+    break;
+
+  case NODE_IVAR:
+    printf("NODE_IVAR %s\n", mrb_sym2name(mrb, sym(tree)));
+    break;
+
+  case NODE_CVAR:
+    printf("NODE_CVAR %s\n", mrb_sym2name(mrb, sym(tree)));
+    break;
+
+  case NODE_CONST:
+    printf("NODE_CONST %s\n", mrb_sym2name(mrb, sym(tree)));
+    break;
+
+  case NODE_MATCH:
+    printf("NODE_MATCH:\n");
+    dump_prefix(tree, offset + 1);
+    printf("lhs:\n");
+    mrb_parser_dump(mrb, tree->car, offset + 2);
+    dump_prefix(tree, offset + 1);
+    printf("rhs:\n");
+    mrb_parser_dump(mrb, tree->cdr, offset + 2);
+    break;
+
+  case NODE_BACK_REF:
+    printf("NODE_BACK_REF: $%c\n", (int)(intptr_t)tree);
+    break;
+
+  case NODE_NTH_REF:
+    printf("NODE_NTH_REF: $%" MRB_PRId "\n", (mrb_int)(intptr_t)tree);
+    break;
+
+  case NODE_ARG:
+    printf("NODE_ARG %s\n", mrb_sym2name(mrb, sym(tree)));
+    break;
+
+  case NODE_BLOCK_ARG:
+    printf("NODE_BLOCK_ARG:\n");
+    mrb_parser_dump(mrb, tree, offset+1);
+    break;
+
+  case NODE_INT:
+    printf("NODE_INT %s base %d\n", (char*)tree->car, (int)(intptr_t)tree->cdr->car);
+    break;
+
+  case NODE_FLOAT:
+    printf("NODE_FLOAT %s\n", (char*)tree);
+    break;
+
+  case NODE_NEGATE:
+    printf("NODE_NEGATE\n");
+    mrb_parser_dump(mrb, tree, offset+1);
+    break;
+
+  case NODE_STR:
+    printf("NODE_STR \"%s\" len %d\n", (char*)tree->car, (int)(intptr_t)tree->cdr);
+    break;
+
+  case NODE_DSTR:
+    printf("NODE_DSTR\n");
+    dump_recur(mrb, tree, offset+1);
+    break;
+
+  case NODE_XSTR:
+    printf("NODE_XSTR \"%s\" len %d\n", (char*)tree->car, (int)(intptr_t)tree->cdr);
+    break;
+
+  case NODE_DXSTR:
+    printf("NODE_DXSTR\n");
+    dump_recur(mrb, tree, offset+1);
+    break;
+
+  case NODE_REGX:
+    printf("NODE_REGX /%s/%s\n", (char*)tree->car, (char*)tree->cdr);
+    break;
+
+  case NODE_DREGX:
+    printf("NODE_DREGX\n");
+    dump_recur(mrb, tree->car, offset+1);
+    dump_prefix(tree, offset);
+    printf("tail: %s\n", (char*)tree->cdr->cdr->car);
+    if (tree->cdr->cdr->cdr->car) {
+      dump_prefix(tree, offset);
+      printf("opt: %s\n", (char*)tree->cdr->cdr->cdr->car);
+    }
+    if (tree->cdr->cdr->cdr->cdr) {
+      dump_prefix(tree, offset);
+      printf("enc: %s\n", (char*)tree->cdr->cdr->cdr->cdr);
+    }
+    break;
+
+  case NODE_SYM:
+    printf("NODE_SYM :%s (%d)\n", mrb_sym2name(mrb, sym(tree)),
+           (int)(intptr_t)tree);
+    break;
+
+  case NODE_SELF:
+    printf("NODE_SELF\n");
+    break;
+
+  case NODE_NIL:
+    printf("NODE_NIL\n");
+    break;
+
+  case NODE_TRUE:
+    printf("NODE_TRUE\n");
+    break;
+
+  case NODE_FALSE:
+    printf("NODE_FALSE\n");
+    break;
+
+  case NODE_ALIAS:
+    printf("NODE_ALIAS %s %s:\n",
+        mrb_sym2name(mrb, sym(tree->car)),
+        mrb_sym2name(mrb, sym(tree->cdr)));
+    break;
+
+  case NODE_UNDEF:
+    printf("NODE_UNDEF");
+    {
+      node *t = tree;
+      while (t) {
+        printf(" %s", mrb_sym2name(mrb, sym(t->car)));
+        t = t->cdr;
+      }
+    }
+    printf(":\n");
+    break;
+
+  case NODE_CLASS:
+    printf("NODE_CLASS:\n");
+    if (tree->car->car == (node*)0) {
+      dump_prefix(tree, offset+1);
+      printf(":%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
+    }
+    else if (tree->car->car == (node*)1) {
+      dump_prefix(tree, offset+1);
+      printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
+    }
+    else {
+      mrb_parser_dump(mrb, tree->car->car, offset+1);
+      dump_prefix(tree, offset+1);
+      printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
+    }
+    if (tree->cdr->car) {
+      dump_prefix(tree, offset+1);
+      printf("super:\n");
+      mrb_parser_dump(mrb, tree->cdr->car, offset+2);
+    }
+    dump_prefix(tree, offset+1);
+    printf("body:\n");
+    mrb_parser_dump(mrb, tree->cdr->cdr->car->cdr, offset+2);
+    break;
+
+  case NODE_MODULE:
+    printf("NODE_MODULE:\n");
+    if (tree->car->car == (node*)0) {
+      dump_prefix(tree, offset+1);
+      printf(":%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
+    }
+    else if (tree->car->car == (node*)1) {
+      dump_prefix(tree, offset+1);
+      printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
+    }
+    else {
+      mrb_parser_dump(mrb, tree->car->car, offset+1);
+      dump_prefix(tree, offset+1);
+      printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr)));
+    }
+    dump_prefix(tree, offset+1);
+    printf("body:\n");
+    mrb_parser_dump(mrb, tree->cdr->car->cdr, offset+2);
+    break;
+
+  case NODE_SCLASS:
+    printf("NODE_SCLASS:\n");
+    mrb_parser_dump(mrb, tree->car, offset+1);
+    dump_prefix(tree, offset+1);
+    printf("body:\n");
+    mrb_parser_dump(mrb, tree->cdr->car->cdr, offset+2);
+    break;
+
+  case NODE_DEF:
+    printf("NODE_DEF:\n");
+    dump_prefix(tree, offset+1);
+    printf("%s\n", mrb_sym2name(mrb, sym(tree->car)));
+    tree = tree->cdr;
+    {
+      node *n2 = tree->car;
+      mrb_bool first_lval = TRUE;
+
+      if (n2 && (n2->car || n2->cdr)) {
+        dump_prefix(n2, offset+1);
+        printf("local variables:\n");
+        dump_prefix(n2, offset+2);
+        while (n2) {
+          if (n2->car) {
+            if (!first_lval) printf(", ");
+            printf("%s", mrb_sym2name(mrb, sym(n2->car)));
+            first_lval = FALSE;
+          }
+          n2 = n2->cdr;
+        }
+        printf("\n");
+      }
+    }
+    tree = tree->cdr;
+    if (tree->car) {
+      node *n = tree->car;
+
+      if (n->car) {
+        dump_prefix(n, offset+1);
+        printf("mandatory args:\n");
+        dump_recur(mrb, n->car, offset+2);
+      }
+      n = n->cdr;
+      if (n->car) {
+        dump_prefix(n, offset+1);
+        printf("optional args:\n");
+        {
+          node *n2 = n->car;
+
+          while (n2) {
+            dump_prefix(n2, offset+2);
+            printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
+            mrb_parser_dump(mrb, n2->car->cdr, 0);
+            n2 = n2->cdr;
+          }
+        }
+      }
+      n = n->cdr;
+      if (n->car) {
+        dump_prefix(n, offset+1);
+        printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
+      }
+      n = n->cdr;
+      if (n->car) {
+        dump_prefix(n, offset+1);
+        printf("post mandatory args:\n");
+        dump_recur(mrb, n->car, offset+2);
+      }
+      if (n->cdr) {
+        dump_prefix(n, offset+1);
+        printf("blk=&%s\n", mrb_sym2name(mrb, sym(n->cdr)));
+      }
+    }
+    mrb_parser_dump(mrb, tree->cdr->car, offset+1);
+    break;
+
+  case NODE_SDEF:
+    printf("NODE_SDEF:\n");
+    mrb_parser_dump(mrb, tree->car, offset+1);
+    tree = tree->cdr;
+    dump_prefix(tree, offset+1);
+    printf(":%s\n", mrb_sym2name(mrb, sym(tree->car)));
+    tree = tree->cdr->cdr;
+    if (tree->car) {
+      node *n = tree->car;
+
+      if (n->car) {
+        dump_prefix(n, offset+1);
+        printf("mandatory args:\n");
+        dump_recur(mrb, n->car, offset+2);
+      }
+      n = n->cdr;
+      if (n->car) {
+        dump_prefix(n, offset+1);
+        printf("optional args:\n");
+        {
+          node *n2 = n->car;
+
+          while (n2) {
+            dump_prefix(n2, offset+2);
+            printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
+            mrb_parser_dump(mrb, n2->car->cdr, 0);
+            n2 = n2->cdr;
+          }
+        }
+      }
+      n = n->cdr;
+      if (n->car) {
+        dump_prefix(n, offset+1);
+        printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
+      }
+      n = n->cdr;
+      if (n->car) {
+        dump_prefix(n, offset+1);
+        printf("post mandatory args:\n");
+        dump_recur(mrb, n->car, offset+2);
+      }
+      n = n->cdr;
+      if (n) {
+        dump_prefix(n, offset+1);
+        printf("blk=&%s\n", mrb_sym2name(mrb, sym(n)));
+      }
+    }
+    tree = tree->cdr;
+    mrb_parser_dump(mrb, tree->car, offset+1);
+    break;
+
+  case NODE_POSTEXE:
+    printf("NODE_POSTEXE:\n");
+    mrb_parser_dump(mrb, tree, offset+1);
+    break;
+
+  case NODE_HEREDOC:
+    printf("NODE_HEREDOC (<<%s):\n", ((parser_heredoc_info*)tree)->term);
+    dump_recur(mrb, ((parser_heredoc_info*)tree)->doc, offset+1);
+    break;
+
+  default:
+    printf("node type: %d (0x%x)\n", nodetype, (unsigned)nodetype);
+    break;
+  }
+#endif
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-compiler/mrbgem.rake	(revision 331)
@@ -0,0 +1,40 @@
+MRuby::Gem::Specification.new 'mruby-compiler' do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'mruby compiler library'
+
+  current_dir = spec.dir
+  current_build_dir = spec.build_dir
+
+  lex_def = "#{current_dir}/core/lex.def"
+  core_objs = Dir.glob("#{current_dir}/core/*.c").map { |f|
+    next nil if build.cxx_exception_enabled? and f =~ /(codegen).c$/
+    objfile(f.pathmap("#{current_build_dir}/core/%n"))
+  }.compact
+
+  if build.cxx_exception_enabled?
+    core_objs <<
+      build.compile_as_cxx("#{current_build_dir}/core/y.tab.c", "#{current_build_dir}/core/y.tab.cxx",
+                           objfile("#{current_build_dir}/y.tab"), ["#{current_dir}/core"]) <<
+      build.compile_as_cxx("#{current_dir}/core/codegen.c", "#{current_build_dir}/core/codegen.cxx")
+  else
+    core_objs << objfile("#{current_build_dir}/core/y.tab")
+    file objfile("#{current_build_dir}/core/y.tab") => "#{current_build_dir}/core/y.tab.c" do |t|
+      cc.run t.name, t.prerequisites.first, [], ["#{current_dir}/core"]
+    end
+  end
+  file objfile("#{current_build_dir}/core/y.tab") => lex_def
+
+  # Parser
+  file "#{current_build_dir}/core/y.tab.c" => ["#{current_dir}/core/parse.y"] do |t|
+    yacc.run t.name, t.prerequisites.first
+  end
+
+  # Lexical analyzer
+  file lex_def => "#{current_dir}/core/keywords" do |t|
+    gperf.run t.name, t.prerequisites.first
+  end
+
+  file libfile("#{build.build_dir}/lib/libmruby_core") => core_objs
+  build.libmruby << core_objs
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enum-ext/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enum-ext/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enum-ext/mrbgem.rake	(revision 331)
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-enum-ext') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'Enumerable module extension'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enum-ext/mrblib/enum.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enum-ext/mrblib/enum.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enum-ext/mrblib/enum.rb	(revision 331)
@@ -0,0 +1,711 @@
+##
+# Enumerable
+#
+module Enumerable
+  ##
+  # call-seq:
+  #    enum.drop(n)               -> array
+  #
+  # Drops first n elements from <i>enum</i>, and returns rest elements
+  # in an array.
+  #
+  #    a = [1, 2, 3, 4, 5, 0]
+  #    a.drop(3)             #=> [4, 5, 0]
+
+  def drop(n)
+    raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)
+    raise ArgumentError, "attempt to drop negative size" if n < 0
+
+    n = n.to_int
+    ary = []
+    self.each {|*val| n == 0 ? ary << val.__svalue : n -= 1 }
+    ary
+  end
+
+  ##
+  # call-seq:
+  #    enum.drop_while {|arr| block }   -> array
+  #    enum.drop_while                  -> an_enumerator
+  #
+  # Drops elements up to, but not including, the first element for
+  # which the block returns +nil+ or +false+ and returns an array
+  # containing the remaining elements.
+  #
+  # If no block is given, an enumerator is returned instead.
+  #
+  #    a = [1, 2, 3, 4, 5, 0]
+  #    a.drop_while {|i| i < 3 }   #=> [3, 4, 5, 0]
+
+  def drop_while(&block)
+    return to_enum :drop_while unless block
+
+    ary, state = [], false
+    self.each do |*val|
+      state = true if !state and !block.call(*val)
+      ary << val.__svalue if state
+    end
+    ary
+  end
+
+  ##
+  # call-seq:
+  #    enum.take(n)               -> array
+  #
+  # Returns first n elements from <i>enum</i>.
+  #
+  #    a = [1, 2, 3, 4, 5, 0]
+  #    a.take(3)             #=> [1, 2, 3]
+
+  def take(n)
+    raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)
+    i = n.to_int
+    raise ArgumentError, "attempt to take negative size" if i < 0
+    ary = []
+    return ary if i == 0
+    self.each do |*val|
+      ary << val.__svalue
+      i -= 1
+      break if i == 0
+    end
+    ary
+  end
+
+  ##
+  # call-seq:
+  #    enum.take_while {|arr| block }   -> array
+  #    enum.take_while                  -> an_enumerator
+  #
+  # Passes elements to the block until the block returns +nil+ or +false+,
+  # then stops iterating and returns an array of all prior elements.
+  #
+  # If no block is given, an enumerator is returned instead.
+  #
+  #     a = [1, 2, 3, 4, 5, 0]
+  #     a.take_while {|i| i < 3 }   #=> [1, 2]
+  #
+  def take_while(&block)
+    return to_enum :take_while unless block
+
+    ary = []
+    self.each do |*val|
+      return ary unless block.call(*val)
+      ary << val.__svalue
+    end
+    ary
+  end
+
+  ##
+  # Iterates the given block for each array of consecutive <n>
+  # elements.
+  #
+  # @return [nil]
+  #
+  # @example
+  #     (1..10).each_cons(3) {|a| p a}
+  #     # outputs below
+  #     [1, 2, 3]
+  #     [2, 3, 4]
+  #     [3, 4, 5]
+  #     [4, 5, 6]
+  #     [5, 6, 7]
+  #     [6, 7, 8]
+  #     [7, 8, 9]
+  #     [8, 9, 10]
+
+  def each_cons(n, &block)
+    raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)
+    raise ArgumentError, "invalid size" if n <= 0
+
+    return to_enum(:each_cons,n) unless block
+    ary = []
+    n = n.to_int
+    self.each do |*val|
+      ary.shift if ary.size == n
+      ary << val.__svalue
+      block.call(ary.dup) if ary.size == n
+    end
+    nil
+  end
+
+  ##
+  # Iterates the given block for each slice of <n> elements.
+  #
+  # @return [nil]
+  #
+  # @example
+  #     (1..10).each_slice(3) {|a| p a}
+  #     # outputs below
+  #     [1, 2, 3]
+  #     [4, 5, 6]
+  #     [7, 8, 9]
+  #     [10]
+
+  def each_slice(n, &block)
+    raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)
+    raise ArgumentError, "invalid slice size" if n <= 0
+
+    return to_enum(:each_slice,n) unless block
+    ary = []
+    n = n.to_int
+    self.each do |*val|
+      ary << val.__svalue
+      if ary.size == n
+        block.call(ary)
+        ary = []
+      end
+    end
+    block.call(ary) unless ary.empty?
+    nil
+  end
+
+  ##
+  # call-seq:
+  #    enum.group_by {| obj | block }  -> a_hash
+  #    enum.group_by                   -> an_enumerator
+  #
+  # Returns a hash, which keys are evaluated result from the
+  # block, and values are arrays of elements in <i>enum</i>
+  # corresponding to the key.
+  #
+  #     (1..6).group_by {|i| i%3}   #=> {0=>[3, 6], 1=>[1, 4], 2=>[2, 5]}
+  #
+  def group_by(&block)
+    return to_enum :group_by unless block
+
+    h = {}
+    self.each do |*val|
+      key = block.call(*val)
+      sv = val.__svalue
+      h.key?(key) ? (h[key] << sv) : (h[key] = [sv])
+    end
+    h
+  end
+
+  ##
+  # call-seq:
+  #    enum.sort_by { |obj| block }   -> array
+  #    enum.sort_by                   -> an_enumerator
+  #
+  # Sorts <i>enum</i> using a set of keys generated by mapping the
+  # values in <i>enum</i> through the given block.
+  #
+  # If no block is given, an enumerator is returned instead.
+
+  def sort_by(&block)
+    return to_enum :sort_by unless block
+
+    ary = []
+    orig = []
+    self.each_with_index{|e, i|
+      orig.push(e)
+      ary.push([block.call(e), i])
+    }
+    if ary.size > 1
+      __sort_sub__(ary, ::Array.new(ary.size), 0, 0, ary.size - 1) do |a,b|
+        a <=> b
+      end
+    end
+    ary.collect{|e,i| orig[i]}
+  end
+
+  NONE = Object.new
+  ##
+  # call-seq:
+  #    enum.first       ->  obj or nil
+  #    enum.first(n)    ->  an_array
+  #
+  # Returns the first element, or the first +n+ elements, of the enumerable.
+  # If the enumerable is empty, the first form returns <code>nil</code>, and the
+  # second form returns an empty array.
+  def first(*args)
+    case args.length
+    when 0
+      self.each do |*val|
+        return val.__svalue
+      end
+      return nil
+    when 1
+      n = args[0]
+      raise TypeError, "no implicit conversion of #{n.class} into Integer" unless n.respond_to?(:to_int)
+      i = n.to_int
+      raise ArgumentError, "attempt to take negative size" if i < 0
+      ary = []
+      return ary if i == 0
+      self.each do |*val|
+        ary << val.__svalue
+        i -= 1
+        break if i == 0
+      end
+      ary
+    else
+      raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 0..1)"
+    end
+  end
+
+  ##
+  # call-seq:
+  #    enum.count                 -> int
+  #    enum.count(item)           -> int
+  #    enum.count { |obj| block } -> int
+  #
+  # Returns the number of items in +enum+ through enumeration.
+  # If an argument is given, the number of items in +enum+ that
+  # are equal to +item+ are counted.  If a block is given, it
+  # counts the number of elements yielding a true value.
+  def count(v=NONE, &block)
+    count = 0
+    if block
+      self.each do |*val|
+        count += 1 if block.call(*val)
+      end
+    else
+      if v == NONE
+        self.each { count += 1 }
+      else
+        self.each do |*val|
+          count += 1 if val.__svalue == v
+        end
+      end
+    end
+    count
+  end
+
+  ##
+  # call-seq:
+  #    enum.flat_map       { |obj| block } -> array
+  #    enum.collect_concat { |obj| block } -> array
+  #    enum.flat_map                       -> an_enumerator
+  #    enum.collect_concat                 -> an_enumerator
+  #
+  # Returns a new array with the concatenated results of running
+  # <em>block</em> once for every element in <i>enum</i>.
+  #
+  # If no block is given, an enumerator is returned instead.
+  #
+  #    [1, 2, 3, 4].flat_map { |e| [e, -e] } #=> [1, -1, 2, -2, 3, -3, 4, -4]
+  #    [[1, 2], [3, 4]].flat_map { |e| e + [100] } #=> [1, 2, 100, 3, 4, 100]
+  def flat_map(&block)
+    return to_enum :flat_map unless block
+
+    ary = []
+    self.each do |*e|
+      e2 = block.call(*e)
+      if e2.respond_to? :each
+        e2.each {|e3| ary.push(e3) }
+      else
+        ary.push(e2)
+      end
+    end
+    ary
+  end
+  alias collect_concat flat_map
+
+  ##
+  # call-seq:
+  #    enum.max_by {|obj| block }      -> obj
+  #    enum.max_by                     -> an_enumerator
+  #
+  # Returns the object in <i>enum</i> that gives the maximum
+  # value from the given block.
+  #
+  # If no block is given, an enumerator is returned instead.
+  #
+  #    %w[albatross dog horse].max_by {|x| x.length }   #=> "albatross"
+
+  def max_by(&block)
+    return to_enum :max_by unless block
+
+    first = true
+    max = nil
+    max_cmp = nil
+
+    self.each do |*val|
+      if first
+        max = val.__svalue
+        max_cmp = block.call(*val)
+        first = false
+      else
+        if (cmp = block.call(*val)) > max_cmp
+          max = val.__svalue
+          max_cmp = cmp
+        end
+      end
+    end
+    max
+  end
+
+  ##
+  # call-seq:
+  #    enum.min_by {|obj| block }      -> obj
+  #    enum.min_by                     -> an_enumerator
+  #
+  # Returns the object in <i>enum</i> that gives the minimum
+  # value from the given block.
+  #
+  # If no block is given, an enumerator is returned instead.
+  #
+  #    %w[albatross dog horse].min_by {|x| x.length }   #=> "dog"
+
+  def min_by(&block)
+    return to_enum :min_by unless block
+
+    first = true
+    min = nil
+    min_cmp = nil
+
+    self.each do |*val|
+      if first
+        min = val.__svalue
+        min_cmp = block.call(*val)
+        first = false
+      else
+        if (cmp = block.call(*val)) < min_cmp
+          min = val.__svalue
+          min_cmp = cmp
+        end
+      end
+    end
+    min
+  end
+
+  ##
+  #  call-seq:
+  #     enum.minmax                  -> [min, max]
+  #     enum.minmax { |a, b| block } -> [min, max]
+  #
+  #  Returns two elements array which contains the minimum and the
+  #  maximum value in the enumerable.  The first form assumes all
+  #  objects implement <code>Comparable</code>; the second uses the
+  #  block to return <em>a <=> b</em>.
+  #
+  #     a = %w(albatross dog horse)
+  #     a.minmax                                  #=> ["albatross", "horse"]
+  #     a.minmax { |a, b| a.length <=> b.length } #=> ["dog", "albatross"]
+
+  def minmax(&block)
+    max = nil
+    min = nil
+    first = true
+
+    self.each do |*val|
+      if first
+        val = val.__svalue
+        max = val
+        min = val
+        first = false
+      else
+        val = val.__svalue
+        if block
+          max = val if block.call(val, max) > 0
+          min = val if block.call(val, min) < 0
+        else
+          max = val if (val <=> max) > 0
+          min = val if (val <=> min) < 0
+        end
+      end
+    end
+    [min, max]
+  end
+
+  ##
+  #  call-seq:
+  #     enum.minmax_by { |obj| block } -> [min, max]
+  #     enum.minmax_by                 -> an_enumerator
+  #
+  #  Returns a two element array containing the objects in
+  #  <i>enum</i> that correspond to the minimum and maximum values respectively
+  #  from the given block.
+  #
+  #  If no block is given, an enumerator is returned instead.
+  #
+  #     %w(albatross dog horse).minmax_by { |x| x.length }   #=> ["dog", "albatross"]
+
+  def minmax_by(&block)
+    return to_enum :minmax_by unless block
+
+    max = nil
+    max_cmp = nil
+    min = nil
+    min_cmp = nil
+    first = true
+
+    self.each do |*val|
+      if first
+        max = min = val.__svalue
+        max_cmp = min_cmp = block.call(*val)
+        first = false
+     else
+        if (cmp = block.call(*val)) > max_cmp
+          max = val.__svalue
+          max_cmp = cmp
+        end
+        if (cmp = block.call(*val)) < min_cmp
+          min = val.__svalue
+          min_cmp = cmp
+        end
+      end
+    end
+    [min, max]
+  end
+
+  ##
+  #  call-seq:
+  #     enum.none? [{ |obj| block }]   -> true or false
+  #
+  #  Passes each element of the collection to the given block. The method
+  #  returns <code>true</code> if the block never returns <code>true</code>
+  #  for all elements. If the block is not given, <code>none?</code> will return
+  #  <code>true</code> only if none of the collection members is true.
+  #
+  #     %w(ant bear cat).none? { |word| word.length == 5 } #=> true
+  #     %w(ant bear cat).none? { |word| word.length >= 4 } #=> false
+  #     [].none?                                           #=> true
+  #     [nil, false].none?                                 #=> true
+  #     [nil, true].none?                                  #=> false
+
+  def none?(&block)
+    if block
+      self.each do |*val|
+        return false if block.call(*val)
+      end
+    else
+      self.each do |*val|
+        return false if val.__svalue
+      end
+    end
+    true
+  end
+
+  ##
+  #  call-seq:
+  #    enum.one? [{ |obj| block }]   -> true or false
+  #
+  # Passes each element of the collection to the given block. The method
+  # returns <code>true</code> if the block returns <code>true</code>
+  # exactly once. If the block is not given, <code>one?</code> will return
+  # <code>true</code> only if exactly one of the collection members is
+  # true.
+  #
+  #    %w(ant bear cat).one? { |word| word.length == 4 }  #=> true
+  #    %w(ant bear cat).one? { |word| word.length > 4 }   #=> false
+  #    %w(ant bear cat).one? { |word| word.length < 4 }   #=> false
+  #    [nil, true, 99].one?                               #=> false
+  #    [nil, true, false].one?                            #=> true
+  #
+
+  def one?(&block)
+    count = 0
+    if block
+      self.each do |*val|
+        count += 1 if block.call(*val)
+        return false if count > 1
+      end
+    else
+      self.each do |*val|
+        count += 1 if val.__svalue
+        return false if count > 1
+      end
+    end
+
+    count == 1 ? true : false
+  end
+
+  ##
+  #  call-seq:
+  #    enum.each_with_object(obj) { |(*args), memo_obj| ... }  ->  obj
+  #    enum.each_with_object(obj)                              ->  an_enumerator
+  #
+  #  Iterates the given block for each element with an arbitrary
+  #  object given, and returns the initially given object.
+  #
+  #  If no block is given, returns an enumerator.
+  #
+  #     (1..10).each_with_object([]) { |i, a| a << i*2 }
+  #     #=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
+  #
+
+  def each_with_object(obj=nil, &block)
+    raise ArgumentError, "wrong number of arguments (0 for 1)" if obj.nil?
+
+    return to_enum(:each_with_object, obj) unless block
+
+    self.each {|*val| block.call(val.__svalue, obj) }
+    obj
+  end
+
+  ##
+  #  call-seq:
+  #     enum.reverse_each { |item| block } ->  enum
+  #     enum.reverse_each                  ->  an_enumerator
+  #
+  #  Builds a temporary array and traverses that array in reverse order.
+  #
+  #  If no block is given, an enumerator is returned instead.
+  #
+  #      (1..3).reverse_each { |v| p v }
+  #
+  #    produces:
+  #
+  #      3
+  #      2
+  #      1
+  #
+
+  def reverse_each(&block)
+    return to_enum :reverse_each unless block
+
+    ary = self.to_a
+    i = ary.size - 1
+    while i>=0
+      block.call(ary[i])
+      i -= 1
+    end
+    self
+  end
+
+  ##
+  #  call-seq:
+  #     enum.cycle(n=nil) { |obj| block }  ->  nil
+  #     enum.cycle(n=nil)                  ->  an_enumerator
+  #
+  #  Calls <i>block</i> for each element of <i>enum</i> repeatedly _n_
+  #  times or forever if none or +nil+ is given.  If a non-positive
+  #  number is given or the collection is empty, does nothing.  Returns
+  #  +nil+ if the loop has finished without getting interrupted.
+  #
+  #  Enumerable#cycle saves elements in an internal array so changes
+  #  to <i>enum</i> after the first pass have no effect.
+  #
+  #  If no block is given, an enumerator is returned instead.
+  #
+  #     a = ["a", "b", "c"]
+  #     a.cycle { |x| puts x }  # print, a, b, c, a, b, c,.. forever.
+  #     a.cycle(2) { |x| puts x }  # print, a, b, c, a, b, c.
+  #
+
+  def cycle(nv = nil, &block)
+    return to_enum(:cycle, nv) unless block
+
+    n = nil
+
+    if nv.nil?
+      n = -1
+    else
+      unless nv.respond_to?(:to_int)
+        raise TypeError, "no implicit conversion of #{nv.class} into Integer"
+      end
+      n = nv.to_int
+      unless n.kind_of?(Integer)
+        raise TypeError, "no implicit conversion of #{nv.class} into Integer"
+      end
+      return nil if n <= 0
+    end
+
+    ary = []
+    each do |*i|
+      ary.push(i)
+      yield(*i)
+    end
+    return nil if ary.empty?
+
+    while n < 0 || 0 < (n -= 1)
+      ary.each do |i|
+        yield(*i)
+      end
+    end
+
+    nil
+  end
+
+  ##
+  #  call-seq:
+  #     enum.find_index(value)          -> int or nil
+  #     enum.find_index { |obj| block } -> int or nil
+  #     enum.find_index                 -> an_enumerator
+  #
+  #  Compares each entry in <i>enum</i> with <em>value</em> or passes
+  #  to <em>block</em>.  Returns the index for the first for which the
+  #  evaluated value is non-false.  If no object matches, returns
+  #  <code>nil</code>
+  #
+  #  If neither block nor argument is given, an enumerator is returned instead.
+  #
+  #     (1..10).find_index  { |i| i % 5 == 0 and i % 7 == 0 }  #=> nil
+  #     (1..100).find_index { |i| i % 5 == 0 and i % 7 == 0 }  #=> 34
+  #     (1..100).find_index(50)                                #=> 49
+  #
+
+  def find_index(val=NONE, &block)
+    return to_enum(:find_index, val) if !block && val == NONE
+
+    idx = 0
+    if block
+      self.each do |*e|
+        return idx if block.call(*e)
+        idx += 1
+      end
+    else
+      self.each do |*e|
+        return idx if e.__svalue == val
+        idx += 1
+      end
+    end
+    nil
+  end
+
+  ##
+  #  call-seq:
+  #     enum.zip(arg, ...)                  -> an_array_of_array
+  #
+  #  Takes one element from <i>enum</i> and merges corresponding
+  #  elements from each <i>args</i>.  This generates a sequence of
+  #  <em>n</em>-element arrays, where <em>n</em> is one more than the
+  #  count of arguments.  The length of the resulting sequence will be
+  #  <code>enum#size</code>.  If the size of any argument is less than
+  #  <code>enum#size</code>, <code>nil</code> values are supplied.
+  #
+
+  def zip(*arg)
+    ary = []
+    arg = arg.map{|a|a.to_a}
+    i = 0
+    self.each do |*val|
+      a = []
+      a.push(val.__svalue)
+      idx = 0
+      while idx < arg.size
+        a.push(arg[idx][i])
+        idx += 1
+      end
+      ary.push(a)
+      i += 1
+    end
+    ary
+  end
+
+  ##
+  #  call-seq:
+  #     enum.to_h  -> hash
+  #
+  #  Returns the result of interpreting <i>enum</i> as a list of
+  #  <tt>[key, value]</tt> pairs.
+  #
+  #     %i[hello world].each_with_index.to_h
+  #       # => {:hello => 0, :world => 1}
+  #
+
+  def to_h
+    h = {}
+    self.each do |*v|
+      v = v.__svalue
+      raise TypeError, "wrong element type #{v.class} (expected Array)" unless v.is_a? Array
+      raise ArgumentError, "element has wrong array length (expected 2, was #{v.size})" if v.size != 2
+      h[v[0]] = v[1]
+    end
+    h
+  end
+
+  def nil.to_h
+    {}
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enum-ext/test/enum.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enum-ext/test/enum.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enum-ext/test/enum.rb	(revision 331)
@@ -0,0 +1,171 @@
+##
+# Enumerable(Ext) Test
+
+assert("Enumerable#drop") do
+  a = [1, 2, 3, 4, 5, 0]
+
+  assert_equal [4, 5, 0], a.drop(3)
+  assert_equal [], a.drop(6)
+end
+
+assert("Enumerable#drop_while") do
+  a = [1, 2, 3, 4, 5, 0]
+  assert_equal [3, 4, 5, 0], a.drop_while {|i| i < 3 }
+end
+
+assert("Enumerable#take") do
+  a = [1, 2, 3, 4, 5, 0]
+  assert_equal [1, 2, 3], a.take(3)
+end
+
+assert("Enumerable#take_while") do
+  a = [1, 2, 3, 4, 5, 0]
+  assert_equal [1, 2], a.take_while {|i| i < 3}
+end
+
+assert("Enumerable#each_cons") do
+  a = []
+  b = (1..5).each_cons(3){|e| a << e}
+  assert_equal [[1, 2, 3], [2, 3, 4], [3, 4, 5]], a
+  assert_equal nil, b
+end
+
+assert("Enumerable#each_slice") do
+  a = []
+  b = (1..10).each_slice(3){|e| a << e}
+  assert_equal [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]], a
+  assert_equal nil, b
+end
+
+assert("Enumerable#group_by") do
+  r = (1..6).group_by {|i| i % 3 }
+  assert_equal [3, 6], r[0]
+  assert_equal [1, 4], r[1]
+  assert_equal [2, 5], r[2]
+end
+
+assert("Enumerable#sort_by") do
+  assert_equal ["car", "train", "bicycle"], %w{car bicycle train}.sort_by {|e| e.length}
+end
+
+assert("Enumerable#first") do
+  a = Object.new
+  a.extend Enumerable
+  def a.each
+    yield 1
+    yield 2
+    yield 3
+  end
+  assert_equal 1, a.first
+  assert_equal [1, 2], a.first(2)
+  assert_equal [1, 2, 3], a.first(10)
+  a = Object.new
+  a.extend Enumerable
+  def a.each
+  end
+  assert_nil a.first
+end
+
+assert("Enumerable#count") do
+  a = [1, 2, 4, 2]
+  assert_equal 4, a.count
+  assert_equal 2, a.count(2)
+  assert_equal 3, a.count{|x| x % 2 == 0}
+end
+
+assert("Enumerable#flat_map") do
+  assert_equal [1, 2, 3, 4], [1, 2, 3, 4].flat_map { |e| e }
+  assert_equal [1, -1, 2, -2, 3, -3, 4, -4], [1, 2, 3, 4].flat_map { |e| [e, -e] }
+  assert_equal [1, 2, 100, 3, 4, 100], [[1, 2], [3, 4]].flat_map { |e| e + [100] }
+end
+
+assert("Enumerable#max_by") do
+  assert_equal "albatross", %w[albatross dog horse].max_by { |x| x.length }
+end
+
+assert("Enumerable#min_by") do
+  assert_equal "dog", %w[albatross dog horse].min_by { |x| x.length }
+end
+
+assert("Enumerable#minmax") do
+  a = %w(albatross dog horse)
+  assert_equal ["albatross", "horse"], a.minmax
+  assert_equal ["dog", "albatross"], a.minmax { |a, b| a.length <=> b.length }
+end
+
+assert("Enumerable#minmax_by") do
+  assert_equal ["dog", "albatross"], %w(albatross dog horse).minmax_by { |x| x.length }
+end
+
+assert("Enumerable#none?") do
+  assert_true %w(ant bear cat).none? { |word| word.length == 5 }
+  assert_false %w(ant bear cat).none? { |word| word.length >= 4 }
+  assert_true [].none?
+  assert_true [nil, false].none?
+  assert_false [nil, true].none?
+end
+
+assert("Enumerable#one?") do
+  assert_true %w(ant bear cat).one? { |word| word.length == 4 }
+  assert_false %w(ant bear cat).one? { |word| word.length > 4 }
+  assert_false %w(ant bear cat).one? { |word| word.length < 4 }
+  assert_false [nil, true, 99].one?
+  assert_true [nil, true, false].one?
+end
+
+assert("Enumerable#each_with_object") do
+  assert_true [2, 4, 6, 8, 10, 12, 14, 16, 18, 20], (1..10).each_with_object([]) { |i, a| a << i*2 }
+  assert_raise(ArgumentError) { (1..10).each_with_object() { |i, a| a << i*2 } }
+end
+
+assert("Enumerable#reverse_each") do
+  r = (1..3)
+  a = []
+  assert_equal (1..3), r.reverse_each { |v| a << v }
+  assert_equal [3, 2, 1], a
+end
+
+assert("Enumerable#cycle") do
+  a = []
+  ["a", "b", "c"].cycle(2) { |v| a << v }
+  assert_equal ["a", "b", "c", "a", "b", "c"], a
+  assert_raise(TypeError) { ["a", "b", "c"].cycle("a") { |v| a << v } }
+
+  empty = Class.new do
+    include Enumerable
+    def each
+    end
+  end
+  assert_nil empty.new.cycle { break :nope }
+end
+
+assert("Enumerable#find_index") do
+  assert_nil (1..10).find_index { |i| i % 5 == 0 and i % 7 == 0 }
+  assert_equal 34, (1..100).find_index { |i| i % 5 == 0 and i % 7 == 0 }
+  assert_equal 49 ,(1..100).find_index(50)
+end
+
+assert("Enumerable#zip") do
+  a = [ 4, 5, 6 ]
+  b = [ 7, 8, 9 ]
+  assert_equal [[4, 7], [5, 8], [6, 9]], a.zip(b)
+  assert_equal [[1, 4, 7], [2, 5, 8], [3, 6, 9]], [1, 2, 3].zip(a, b)
+  assert_equal [[1, 4, 7], [2, 5, 8]], [1, 2].zip(a, b)
+  assert_equal [[4, 1, 8], [5, 2, nil], [6, nil, nil]], a.zip([1, 2], [8])
+end
+
+assert("Enumerable#to_h") do
+  c = Class.new {
+    include Enumerable
+    def each
+      yield [1,2]
+      yield [3,4]
+    end
+  }
+  h0 = {1=>2, 3=>4}
+  h = c.new.to_h
+  assert_equal Hash, h.class
+  assert_equal h0, h
+  # mruby-enum-ext also provides nil.to_h
+  assert_equal Hash.new, nil.to_h
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enum-lazy/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enum-lazy/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enum-lazy/mrbgem.rake	(revision 331)
@@ -0,0 +1,7 @@
+MRuby::Gem::Specification.new('mruby-enum-lazy') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'Enumerator::Lazy class'
+  spec.add_dependency('mruby-enumerator', :core => 'mruby-enumerator')
+  spec.add_dependency('mruby-enum-ext', :core => 'mruby-enum-ext')
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enum-lazy/mrblib/lazy.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enum-lazy/mrblib/lazy.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enum-lazy/mrblib/lazy.rb	(revision 331)
@@ -0,0 +1,160 @@
+module Enumerable
+
+  # = Enumerable#lazy implementation
+  #
+  # Enumerable#lazy returns an instance of Enumerator::Lazy.
+  # You can use it just like as normal Enumerable object,
+  # except these methods act as 'lazy':
+  #
+  #   - map       collect
+  #   - select    find_all
+  #   - reject
+  #   - grep
+  #   - drop
+  #   - drop_while
+  #   - take_while
+  #   - flat_map  collect_concat
+  #   - zip
+  def lazy
+    Enumerator::Lazy.new(self)
+  end
+end
+
+class Enumerator
+  # == Acknowledgements
+  #
+  #   Based on https://github.com/yhara/enumerable-lazy
+  #   Inspired by https://github.com/antimon2/enumerable_lz
+  #   http://jp.rubyist.net/magazine/?0034-Enumerable_lz (ja)
+  class Lazy < Enumerator
+    def initialize(obj, &block)
+      super(){|yielder|
+        begin
+          obj.each{|x|
+            if block
+              block.call(yielder, x)
+            else
+              yielder << x
+            end
+          }
+        rescue StopIteration
+        end
+      }
+    end
+
+    def to_enum(meth=:each, *args, &block)
+      lz = Lazy.new(self, &block)
+      lz.obj = self
+      lz.meth = meth
+      lz.args = args
+      lz
+    end
+    alias enum_for to_enum
+
+    def map(&block)
+      Lazy.new(self){|yielder, val|
+        yielder << block.call(val)
+      }
+    end
+    alias collect map
+
+    def select(&block)
+      Lazy.new(self){|yielder, val|
+        if block.call(val)
+          yielder << val
+        end
+      }
+    end
+    alias find_all select
+
+    def reject(&block)
+      Lazy.new(self){|yielder, val|
+        if not block.call(val)
+          yielder << val
+        end
+      }
+    end
+
+    def grep(pattern)
+      Lazy.new(self){|yielder, val|
+        if pattern === val
+          yielder << val
+        end
+      }
+    end
+
+    def drop(n)
+      dropped = 0
+      Lazy.new(self){|yielder, val|
+        if dropped < n
+          dropped += 1
+        else
+          yielder << val
+        end
+      }
+    end
+
+    def drop_while(&block)
+      dropping = true
+      Lazy.new(self){|yielder, val|
+        if dropping
+          if not block.call(val)
+            yielder << val
+            dropping = false
+          end
+        else
+          yielder << val
+        end
+      }
+    end
+
+    def take(n)
+      if n == 0
+        return Lazy.new(self){raise StopIteration}
+      end
+      taken = 0
+      Lazy.new(self){|yielder, val|
+        yielder << val
+        taken += 1
+        if taken >= n
+          raise StopIteration
+        end
+      }
+    end
+
+    def take_while(&block)
+      Lazy.new(self){|yielder, val|
+        if block.call(val)
+          yielder << val
+        else
+          raise StopIteration
+        end
+      }
+    end
+
+    def flat_map(&block)
+      Lazy.new(self){|yielder, val|
+        ary = block.call(val)
+        # TODO: check ary is an Array
+        ary.each{|x|
+          yielder << x
+        }
+      }
+    end
+    alias collect_concat flat_map
+
+    def zip(*args, &block)
+      enums = [self] + args
+      Lazy.new(self){|yielder, val|
+        ary = enums.map{|e| e.next}
+        if block
+          yielder << block.call(ary)
+        else
+          yielder << ary
+        end
+      }
+    end
+
+    alias force to_a
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enum-lazy/test/lazy.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enum-lazy/test/lazy.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enum-lazy/test/lazy.rb	(revision 331)
@@ -0,0 +1,53 @@
+assert("Enumerator::Lazy") do
+  a = [1, 2]
+  assert_equal Enumerator::Lazy, a.lazy.class
+end
+
+assert("Enumerator::Lazy laziness") do
+  a = Object.new
+  def a.each
+    return to_enum :each unless block_given?
+    self.b << 10
+    yield 1
+    self.b << 20
+    yield 2
+    self.b << 30
+    yield 3
+    self.b << 40
+    yield 4
+    self.b << 50
+    yield 5
+  end
+  def a.b(b=nil)
+    @b = b if b
+    @b
+  end
+
+  a.b([])
+  assert_equal [1,2], a.each.lazy.take(2).force
+  assert_equal [10,20], a.b
+
+  a.b([])
+  assert_equal [2,4], a.each.lazy.select{|x|x%2==0}.take(2).force
+  assert_equal [10,20,30,40], a.b
+
+  a.b([])
+  assert_equal [1], a.each.lazy.take_while{|x|x<2}.take(1).force
+  assert_equal [10], a.b
+
+  a.b([])
+  assert_equal [1], a.each.lazy.take_while{|x|x<2}.take(4).force
+  assert_equal [10,20], a.b
+end
+
+assert("Enumrator::Lazy#to_enum") do
+  lazy_enum = (0..Float::INFINITY).lazy.to_enum(:each_slice, 2)
+  assert_kind_of Enumerator::Lazy, lazy_enum
+  assert_equal [0*1, 2*3, 4*5, 6*7], lazy_enum.map { |a| a.first * a.last }.first(4)
+end
+
+assert("Enumerator::Lazy#zip with cycle") do
+  e1 = [1, 2, 3].cycle
+  e2 = [:a, :b].cycle
+  assert_equal [[1,:a],[2,:b],[3,:a]], e1.lazy.zip(e2).first(3)
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enumerator/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enumerator/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enumerator/mrbgem.rake	(revision 331)
@@ -0,0 +1,7 @@
+MRuby::Gem::Specification.new('mruby-enumerator') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.add_dependency('mruby-fiber', :core => 'mruby-fiber')
+  spec.add_dependency 'mruby-enum-ext', :core => 'mruby-enum-ext'
+  spec.summary = 'Enumerator class'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enumerator/mrblib/enumerator.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enumerator/mrblib/enumerator.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enumerator/mrblib/enumerator.rb	(revision 331)
@@ -0,0 +1,641 @@
+##
+# enumerator.rb Enumerator class
+# See Copyright Notice in mruby.h
+
+##
+# A class which allows both internal and external iteration.
+#
+# An Enumerator can be created by the following methods.
+# - {Kernel#to_enum}
+# - {Kernel#enum_for}
+# - {Enumerator#initialize Enumerator.new}
+#
+# Most methods have two forms: a block form where the contents
+# are evaluated for each item in the enumeration, and a non-block form
+# which returns a new Enumerator wrapping the iteration.
+#
+#       enumerator = %w(one two three).each
+#       puts enumerator.class # => Enumerator
+#
+#       enumerator.each_with_object("foo") do |item, obj|
+#         puts "#{obj}: #{item}"
+#       end
+#
+#       # foo: one
+#       # foo: two
+#       # foo: three
+#
+#       enum_with_obj = enumerator.each_with_object("foo")
+#       puts enum_with_obj.class # => Enumerator
+#
+#       enum_with_obj.each do |item, obj|
+#         puts "#{obj}: #{item}"
+#       end
+#
+#       # foo: one
+#       # foo: two
+#       # foo: three
+#
+# This allows you to chain Enumerators together.  For example, you
+# can map a list's elements to strings containing the index
+# and the element as a string via:
+#
+#       puts %w[foo bar baz].map.with_index { |w, i| "#{i}:#{w}" }
+#       # => ["0:foo", "1:bar", "2:baz"]
+#
+# An Enumerator can also be used as an external iterator.
+# For example, Enumerator#next returns the next value of the iterator
+# or raises StopIteration if the Enumerator is at the end.
+#
+#       e = [1,2,3].each   # returns an enumerator object.
+#       puts e.next   # => 1
+#       puts e.next   # => 2
+#       puts e.next   # => 3
+#       puts e.next   # raises StopIteration
+#
+# You can use this to implement an internal iterator as follows:
+#
+#       def ext_each(e)
+#         while true
+#           begin
+#             vs = e.next_values
+#           rescue StopIteration
+#             return $!.result
+#           end
+#           y = yield(*vs)
+#           e.feed y
+#         end
+#       end
+#
+#       o = Object.new
+#
+#       def o.each
+#         puts yield
+#         puts yield(1)
+#         puts yield(1, 2)
+#         3
+#       end
+#
+#       # use o.each as an internal iterator directly.
+#       puts o.each {|*x| puts x; [:b, *x] }
+#       # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3
+#
+#       # convert o.each to an external iterator for
+#       # implementing an internal iterator.
+#       puts ext_each(o.to_enum) {|*x| puts x; [:b, *x] }
+#       # => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3
+#
+class Enumerator
+  include Enumerable
+
+  ##
+  # @overload initialize(size = nil, &block)
+  # @overload initialize(obj, method = :each, *args)
+  #
+  # Creates a new Enumerator object, which can be used as an
+  # Enumerable.
+  #
+  # In the first form, iteration is defined by the given block, in
+  # which a "yielder" object, given as block parameter, can be used to
+  # yield a value by calling the +yield+ method (aliased as +<<+):
+  #
+  #     fib = Enumerator.new do |y|
+  #       a = b = 1
+  #       loop do
+  #         y << a
+  #         a, b = b, a + b
+  #       end
+  #     end
+  #
+  #     p fib.take(10) # => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
+  #
+  def initialize(obj=nil, meth=:each, *args, &block)
+    if block_given?
+      obj = Generator.new(&block)
+    else
+      raise ArgumentError unless obj
+    end
+
+    @obj = obj
+    @meth = meth
+    @args = args.dup
+    @fib = nil
+    @dst = nil
+    @lookahead = nil
+    @feedvalue = nil
+    @stop_exc = false
+  end
+  attr_accessor :obj, :meth, :args, :fib
+  private :obj, :meth, :args, :fib
+
+  def initialize_copy(obj)
+    raise TypeError, "can't copy type #{obj.class}" unless obj.kind_of? Enumerator
+    raise TypeError, "can't copy execution context" if obj.fib
+    @obj = obj.obj
+    @meth = obj.meth
+    @args = obj.args
+    @fib = nil
+    @lookahead = nil
+    @feedvalue = nil
+    self
+  end
+
+  ##
+  # call-seq:
+  #   e.with_index(offset = 0) {|(*args), idx| ... }
+  #   e.with_index(offset = 0)
+  #
+  # Iterates the given block for each element with an index, which
+  # starts from +offset+.  If no block is given, returns a new Enumerator
+  # that includes the index, starting from +offset+
+  #
+  # +offset+:: the starting index to use
+  #
+  def with_index(offset=0)
+    return to_enum :with_index, offset unless block_given?
+    offset = if offset.nil?
+      0
+    elsif offset.respond_to?(:to_int)
+      offset.to_int
+    else
+      raise TypeError, "no implicit conversion of #{offset.class} into Integer"
+    end
+
+    n = offset - 1
+    enumerator_block_call do |*i|
+      n += 1
+      yield i.__svalue, n
+    end
+  end
+
+  ##
+  # call-seq:
+  #   e.each_with_index {|(*args), idx| ... }
+  #   e.each_with_index
+  #
+  # Same as Enumerator#with_index(0), i.e. there is no starting offset.
+  #
+  # If no block is given, a new Enumerator is returned that includes the index.
+  #
+  def each_with_index(&block)
+    with_index(0, &block)
+  end
+
+  ##
+  # call-seq:
+  #   e.each_with_object(obj) {|(*args), obj| ... }
+  #   e.each_with_object(obj)
+  #   e.with_object(obj) {|(*args), obj| ... }
+  #   e.with_object(obj)
+  #
+  # Iterates the given block for each element with an arbitrary object, +obj+,
+  # and returns +obj+
+  #
+  # If no block is given, returns a new Enumerator.
+  #
+  # @example
+  #   to_three = Enumerator.new do |y|
+  #     3.times do |x|
+  #       y << x
+  #     end
+  #   end
+  #
+  #   to_three_with_string = to_three.with_object("foo")
+  #   to_three_with_string.each do |x,string|
+  #     puts "#{string}: #{x}"
+  #   end
+  #
+  #   # => foo:0
+  #   # => foo:1
+  #   # => foo:2
+  #
+  def with_object(object)
+    return to_enum(:with_object, object) unless block_given?
+
+    enumerator_block_call do |i|
+      yield [i,object]
+    end
+    object
+  end
+
+  def inspect
+    return "#<#{self.class}: uninitialized>" unless @obj
+
+    if @args && @args.size > 0
+      args = @args.join(", ")
+      "#<#{self.class}: #{@obj}:#{@meth}(#{args})>"
+    else
+      "#<#{self.class}: #{@obj}:#{@meth}>"
+    end
+  end
+
+  ##
+  # call-seq:
+  #   enum.each { |elm| block }                    -> obj
+  #   enum.each                                    -> enum
+  #   enum.each(*appending_args) { |elm| block }   -> obj
+  #   enum.each(*appending_args)                   -> an_enumerator
+  #
+  # Iterates over the block according to how this Enumerator was constructed.
+  # If no block and no arguments are given, returns self.
+  #
+  # === Examples
+  #
+  #   "Hello, world!".scan(/\w+/)                     #=> ["Hello", "world"]
+  #   "Hello, world!".to_enum(:scan, /\w+/).to_a      #=> ["Hello", "world"]
+  #   "Hello, world!".to_enum(:scan).each(/\w+/).to_a #=> ["Hello", "world"]
+  #
+  #   obj = Object.new
+  #
+  #   def obj.each_arg(a, b=:b, *rest)
+  #     yield a
+  #     yield b
+  #     yield rest
+  #     :method_returned
+  #   end
+  #
+  #   enum = obj.to_enum :each_arg, :a, :x
+  #
+  #   enum.each.to_a                  #=> [:a, :x, []]
+  #   enum.each.equal?(enum)          #=> true
+  #   enum.each { |elm| elm }         #=> :method_returned
+  #
+  #   enum.each(:y, :z).to_a          #=> [:a, :x, [:y, :z]]
+  #   enum.each(:y, :z).equal?(enum)  #=> false
+  #   enum.each(:y, :z) { |elm| elm } #=> :method_returned
+  #
+  def each(*argv, &block)
+    obj = self
+    if 0 < argv.length
+      obj = self.dup
+      args = obj.args
+      if !args.empty?
+        args = args.dup
+        args.concat argv
+      else
+        args = argv.dup
+      end
+      obj.args = args
+    end
+    return obj unless block_given?
+    enumerator_block_call(&block)
+  end
+
+  def enumerator_block_call(&block)
+    @obj.__send__ @meth, *@args, &block
+  end
+  private :enumerator_block_call
+
+  ##
+  # call-seq:
+  #   e.next   -> object
+  #
+  # Returns the next object in the enumerator, and move the internal position
+  # forward.  When the position reached at the end, StopIteration is raised.
+  #
+  # === Example
+  #
+  #   a = [1,2,3]
+  #   e = a.to_enum
+  #   p e.next   #=> 1
+  #   p e.next   #=> 2
+  #   p e.next   #=> 3
+  #   p e.next   #raises StopIteration
+  #
+  # Note that enumeration sequence by +next+ does not affect other non-external
+  # enumeration methods, unless the underlying iteration methods itself has
+  # side-effect
+  #
+  def next
+    next_values.__svalue
+  end
+
+  ##
+  # call-seq:
+  #   e.next_values   -> array
+  #
+  # Returns the next object as an array in the enumerator, and move the
+  # internal position forward.  When the position reached at the end,
+  # StopIteration is raised.
+  #
+  # This method can be used to distinguish <code>yield</code> and <code>yield
+  # nil</code>.
+  #
+  # === Example
+  #
+  #   o = Object.new
+  #   def o.each
+  #     yield
+  #     yield 1
+  #     yield 1, 2
+  #     yield nil
+  #     yield [1, 2]
+  #   end
+  #   e = o.to_enum
+  #   p e.next_values
+  #   p e.next_values
+  #   p e.next_values
+  #   p e.next_values
+  #   p e.next_values
+  #   e = o.to_enum
+  #   p e.next
+  #   p e.next
+  #   p e.next
+  #   p e.next
+  #   p e.next
+  #
+  #   ## yield args       next_values      next
+  #   #  yield            []               nil
+  #   #  yield 1          [1]              1
+  #   #  yield 1, 2       [1, 2]           [1, 2]
+  #   #  yield nil        [nil]            nil
+  #   #  yield [1, 2]     [[1, 2]]         [1, 2]
+  #
+  # Note that +next_values+ does not affect other non-external enumeration
+  # methods unless underlying iteration method itself has side-effect
+  #
+  def next_values
+    if @lookahead
+      vs = @lookahead
+      @lookahead = nil
+      return vs
+    end
+    raise @stop_exc if @stop_exc
+
+    curr = Fiber.current
+
+    if !@fib || !@fib.alive?
+      @dst = curr
+      @fib = Fiber.new do
+        result = each do |*args|
+          feedvalue = nil
+          Fiber.yield args
+          if @feedvalue
+            feedvalue = @feedvalue
+            @feedvalue = nil
+          end
+          feedvalue
+        end
+        @stop_exc = StopIteration.new "iteration reached an end"
+        @stop_exc.result = result
+        Fiber.yield nil
+      end
+      @lookahead = nil
+    end
+
+    vs = @fib.resume curr
+    if @stop_exc
+      @fib = nil
+      @dst = nil
+      @lookahead = nil
+      @feedvalue = nil
+      raise @stop_exc
+    end
+    vs
+  end
+
+  ##
+  # call-seq:
+  #   e.peek   -> object
+  #
+  # Returns the next object in the enumerator, but doesn't move the internal
+  # position forward.  If the position is already at the end, StopIteration
+  # is raised.
+  #
+  # === Example
+  #
+  #   a = [1,2,3]
+  #   e = a.to_enum
+  #   p e.next   #=> 1
+  #   p e.peek   #=> 2
+  #   p e.peek   #=> 2
+  #   p e.peek   #=> 2
+  #   p e.next   #=> 2
+  #   p e.next   #=> 3
+  #   p e.next   #raises StopIteration
+  #
+  def peek
+    peek_values.__svalue
+  end
+
+  ##
+  # call-seq:
+  #   e.peek_values   -> array
+  #
+  # Returns the next object as an array, similar to Enumerator#next_values, but
+  # doesn't move the internal position forward.  If the position is already at
+  # the end, StopIteration is raised.
+  #
+  # === Example
+  #
+  #   o = Object.new
+  #   def o.each
+  #     yield
+  #     yield 1
+  #     yield 1, 2
+  #   end
+  #   e = o.to_enum
+  #   p e.peek_values    #=> []
+  #   e.next
+  #   p e.peek_values    #=> [1]
+  #   p e.peek_values    #=> [1]
+  #   e.next
+  #   p e.peek_values    #=> [1, 2]
+  #   e.next
+  #   p e.peek_values    # raises StopIteration
+  #
+  def peek_values
+    if @lookahead.nil?
+      @lookahead = next_values
+    end
+    @lookahead.dup
+  end
+
+  ##
+  # call-seq:
+  #   e.rewind   -> e
+  #
+  # Rewinds the enumeration sequence to the beginning.
+  #
+  # If the enclosed object responds to a "rewind" method, it is called.
+  #
+  def rewind
+    @obj.rewind if @obj.respond_to? :rewind
+    @fib = nil
+    @dst = nil
+    @lookahead = nil
+    @feedvalue = nil
+    @stop_exc = false
+    self
+  end
+
+  ##
+  # call-seq:
+  #   e.feed obj   -> nil
+  #
+  # Sets the value to be returned by the next yield inside +e+.
+  #
+  # If the value is not set, the yield returns nil.
+  #
+  # This value is cleared after being yielded.
+  #
+  #   # Array#map passes the array's elements to "yield" and collects the
+  #   # results of "yield" as an array.
+  #   # Following example shows that "next" returns the passed elements and
+  #   # values passed to "feed" are collected as an array which can be
+  #   # obtained by StopIteration#result.
+  #   e = [1,2,3].map
+  #   p e.next           #=> 1
+  #   e.feed "a"
+  #   p e.next           #=> 2
+  #   e.feed "b"
+  #   p e.next           #=> 3
+  #   e.feed "c"
+  #   begin
+  #     e.next
+  #   rescue StopIteration
+  #     p $!.result      #=> ["a", "b", "c"]
+  #   end
+  #
+  #   o = Object.new
+  #   def o.each
+  #     x = yield         # (2) blocks
+  #     p x               # (5) => "foo"
+  #     x = yield         # (6) blocks
+  #     p x               # (8) => nil
+  #     x = yield         # (9) blocks
+  #     p x               # not reached w/o another e.next
+  #   end
+  #
+  #   e = o.to_enum
+  #   e.next              # (1)
+  #   e.feed "foo"        # (3)
+  #   e.next              # (4)
+  #   e.next              # (7)
+  #                       # (10)
+  #
+  def feed(value)
+    raise TypeError, "feed value already set" if @feedvalue
+    @feedvalue = value
+    nil
+  end
+
+  # just for internal
+  class Generator
+    include Enumerable
+    def initialize(&block)
+      raise TypeError, "wrong argument type #{self.class} (expected Proc)" unless block.kind_of? Proc
+
+      @proc = block
+    end
+
+    def each(*args, &block)
+      args.unshift Yielder.new(&block)
+      @proc.call(*args)
+    end
+  end
+
+  # just for internal
+  class Yielder
+    def initialize(&block)
+      raise LocalJumpError, "no block given" unless block_given?
+
+      @proc = block
+    end
+
+    def yield(*args)
+      @proc.call(*args)
+    end
+
+    def << *args
+      self.yield(*args)
+      self
+    end
+  end
+end
+
+module Kernel
+  ##
+  # call-seq:
+  #   obj.to_enum(method = :each, *args)                 -> enum
+  #   obj.enum_for(method = :each, *args)                -> enum
+  #   obj.to_enum(method = :each, *args) {|*args| block} -> enum
+  #   obj.enum_for(method = :each, *args){|*args| block} -> enum
+  #
+  # Creates a new Enumerator which will enumerate by calling +method+ on
+  # +obj+, passing +args+ if any.
+  #
+  # If a block is given, it will be used to calculate the size of
+  # the enumerator without the need to iterate it (see Enumerator#size).
+  #
+  # === Examples
+  #
+  #   str = "xyz"
+  #
+  #   enum = str.enum_for(:each_byte)
+  #   enum.each { |b| puts b }
+  #   # => 120
+  #   # => 121
+  #   # => 122
+  #
+  #   # protect an array from being modified by some_method
+  #   a = [1, 2, 3]
+  #   some_method(a.to_enum)
+  #
+  # It is typical to call to_enum when defining methods for
+  # a generic Enumerable, in case no block is passed.
+  #
+  # Here is such an example, with parameter passing and a sizing block:
+  #
+  #     module Enumerable
+  #       # a generic method to repeat the values of any enumerable
+  #       def repeat(n)
+  #         raise ArgumentError, "#{n} is negative!" if n < 0
+  #         unless block_given?
+  #           return to_enum(__method__, n) do # __method__ is :repeat here
+  #             sz = size     # Call size and multiply by n...
+  #             sz * n if sz  # but return nil if size itself is nil
+  #           end
+  #         end
+  #         each do |*val|
+  #           n.times { yield *val }
+  #         end
+  #       end
+  #     end
+  #
+  #     %i[hello world].repeat(2) { |w| puts w }
+  #       # => Prints 'hello', 'hello', 'world', 'world'
+  #     enum = (1..14).repeat(3)
+  #       # => returns an Enumerator when called without a block
+  #     enum.first(4) # => [1, 1, 1, 2]
+  #
+  def to_enum(meth=:each, *args)
+    Enumerator.new self, meth, *args
+  end
+  alias :enum_for :to_enum
+end
+
+module Enumerable
+  # use Enumerator to use infinite sequence
+  def zip(*arg)
+    ary = []
+    arg = arg.map{|a|a.each}
+    i = 0
+    self.each do |*val|
+      a = []
+      a.push(val.__svalue)
+      idx = 0
+      while idx < arg.size
+        begin
+          a.push(arg[idx].next)
+        rescue StopIteration
+          a.push(nil)
+        end
+        idx += 1
+      end
+      ary.push(a)
+      i += 1
+    end
+    ary
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enumerator/test/enumerator.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enumerator/test/enumerator.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-enumerator/test/enumerator.rb	(revision 331)
@@ -0,0 +1,546 @@
+@obj = Object.new
+class << @obj
+  include Enumerable
+  def foo *a
+    a.each { |x| yield x }
+  end
+end
+
+assert 'Enumerator' do
+  assert_equal Class, Enumerator.class
+end
+
+assert 'Enumerator' do
+  assert_equal Object, Enumerator.superclass
+end
+
+assert 'Enumerator.new' do
+  assert_equal [0,1,2], 3.times.map{|i| i}.sort
+  assert_equal [:x,:y,:z], [:x,:y,:z].each.map{|i| i}.sort
+  assert_equal [[:x,1],[:y,2]], {x:1, y:2}.each.map{|i| i}.sort
+  assert_equal [1,2,3], @obj.to_enum(:foo, 1,2,3).to_a
+  assert_equal [1,2,3], Enumerator.new(@obj, :foo, 1,2,3).to_a
+  assert_equal [1,2,3], Enumerator.new { |y| i = 0; loop { y << (i += 1) } }.take(3)
+  assert_raise(ArgumentError) { Enumerator.new }
+  enum = @obj.to_enum
+  assert_raise(NoMethodError) { enum.each {} }
+
+  # examples
+  fib = Enumerator.new do |y|
+    a = b = 1
+    loop do
+      y << a
+      a, b = b, a + b
+    end
+  end
+  assert_equal fib.take(10), [1,1,2,3,5,8,13,21,34,55]
+end
+
+assert 'Enumerator#initialize_copy' do
+  assert_equal [1, 2, 3], @obj.to_enum(:foo, 1, 2, 3).dup.to_a
+  e = @obj.to_enum :foo, 1, 2, 3
+  assert_nothing_raised { assert_equal(1, e.next) }
+  assert_raise(TypeError) { e.dup }
+
+  e = Enumerator.new { |y| i = 0; loop { y << (i += 1) } }.dup
+  assert_nothing_raised { assert_equal(1, e.next) }
+  assert_raise(TypeError) { e.dup }
+end
+
+assert 'Enumerator#with_index' do
+  assert_equal([[1,0],[2,1],[3,2]], @obj.to_enum(:foo, 1, 2, 3).with_index.to_a)
+  assert_equal([[1,5],[2,6],[3,7]], @obj.to_enum(:foo, 1, 2, 3).with_index(5).to_a)
+  a = []
+  @obj.to_enum(:foo, 1, 2, 3).with_index(10).with_index(20) { |*i| a << i }
+  assert_equal [[[1, 10], 20], [[2, 11], 21], [[3, 12], 22]], a
+end
+
+assert 'Enumerator#with_index nonnum offset' do
+  s = Object.new
+  def s.to_int; 1 end
+  assert_equal([[1,1],[2,2],[3,3]], @obj.to_enum(:foo, 1, 2, 3).with_index(s).to_a)
+end
+
+assert 'Enumerator#with_index string offset' do
+  assert_raise(TypeError){ @obj.to_enum(:foo, 1, 2, 3).with_index('1').to_a }
+end
+
+assert 'Enumerator#each_with_index' do
+  assert_equal([[1,0],[2,1],[3,2]], @obj.to_enum(:foo, 1, 2, 3).each_with_index.to_a)
+  a = []
+  @obj.to_enum(:foo, 1, 2, 3).each_with_index {|*i| a << i}
+  assert_equal([[1, 0], [2, 1], [3, 2]], a)
+end
+
+assert 'Enumerator#with_object' do
+  obj = [0, 1]
+  ret = (1..10).each.with_object(obj) {|i, memo|
+    memo[0] += i
+    memo[1] *= i
+  }
+  assert_true(obj.equal?(ret))
+  assert_equal([55, 3628800], ret)
+end
+
+assert 'Enumerator#with_object arguments' do
+  to_three = Enumerator.new do |y|
+    3.times do |x|
+      y << x
+    end
+  end
+
+  a = []
+  to_three_with_string = to_three.with_object("foo")
+  to_three_with_string.each do |x,string|
+    a << "#{string}:#{x}"
+  end
+  assert_equal ["foo:0","foo:1","foo:2"], a
+end
+
+assert 'Enumerator#inspect' do
+  e = (0..10).each
+  assert_equal("#<Enumerator: 0..10:each>", e.inspect)
+  e = Enumerator.new("FooObject", :foo, 1)
+  assert_equal("#<Enumerator: FooObject:foo(1)>", e.inspect)
+  e = Enumerator.new("FooObject", :foo, 1, 2, 3)
+  assert_equal("#<Enumerator: FooObject:foo(1, 2, 3)>", e.inspect)
+end
+
+assert 'Enumerator#each' do
+  o = Object.new
+  def o.each(ary)
+    ary << 1
+    yield
+  end
+  ary = []
+  e = o.to_enum.each(ary)
+  e.next
+  assert_equal([1], ary)
+end
+
+assert 'Enumerator#each arguments' do
+  obj = Object.new
+
+  def obj.each_arg(a, b=:b, *rest)
+    yield a
+    yield b
+    yield rest
+    :method_returned
+  end
+
+  enum = obj.to_enum :each_arg, :a, :x
+
+  assert_equal [:a, :x, []], enum.each.to_a
+  assert_true enum.each.equal?(enum)
+  assert_equal :method_returned, enum.each { |elm| elm }
+
+  assert_equal [:a, :x, [:y, :z]], enum.each(:y, :z).to_a
+  assert_false enum.each(:y, :z).equal?(enum)
+  assert_equal :method_returned, enum.each(:y, :z) { |elm| elm }
+end
+
+assert 'Enumerator#next' do
+  e = 3.times
+  3.times { |i|
+    assert_equal i, e.next
+  }
+  assert_raise(StopIteration) { e.next }
+end
+
+assert 'Enumerator#next_values' do
+  o = Object.new
+  def o.each
+    yield
+    yield 1
+    yield 1, 2
+  end
+  e = o.to_enum
+  assert_equal nil, e.next
+  assert_equal 1, e.next
+  assert_equal [1,2], e.next
+  e = o.to_enum
+  assert_equal [], e.next_values
+  assert_equal [1], e.next_values
+  assert_equal [1,2], e.next_values
+end
+
+assert 'Enumerator#peek' do
+  a = [1]
+  e = a.each
+  assert_equal 1, e.peek
+  assert_equal 1, e.peek
+  assert_equal 1, e.next
+  assert_raise(StopIteration) { e.peek }
+  assert_raise(StopIteration) { e.peek }
+end
+
+assert 'Enumerator#peek modify' do
+  o = Object.new
+  def o.each
+    yield 1,2
+  end
+  e = o.to_enum
+  a = e.peek
+  a << 3
+  assert_equal([1,2], e.peek)
+end
+
+assert 'Enumerator#peek_values' do
+  o = Object.new
+  def o.each
+    yield
+    yield 1
+    yield 1, 2
+  end
+  e = o.to_enum
+  assert_equal nil, e.peek
+  assert_equal nil, e.next
+  assert_equal 1, e.peek
+  assert_equal 1, e.next
+  assert_equal [1,2], e.peek
+  assert_equal [1,2], e.next
+  e = o.to_enum
+  assert_equal [], e.peek_values
+  assert_equal [], e.next_values
+  assert_equal [1], e.peek_values
+  assert_equal [1], e.next_values
+  assert_equal [1,2], e.peek_values
+  assert_equal [1,2], e.next_values
+  e = o.to_enum
+  assert_equal [], e.peek_values
+  assert_equal nil, e.next
+  assert_equal [1], e.peek_values
+  assert_equal 1, e.next
+  assert_equal [1,2], e.peek_values
+  assert_equal [1,2], e.next
+  e = o.to_enum
+  assert_equal nil, e.peek
+  assert_equal [], e.next_values
+  assert_equal 1, e.peek
+  assert_equal [1], e.next_values
+  assert_equal [1,2], e.peek
+  assert_equal [1,2], e.next_values
+end
+
+assert 'Enumerator#peek_values modify' do
+  o = Object.new
+  def o.each
+    yield 1,2
+  end
+  e = o.to_enum
+  a = e.peek_values
+  a << 3
+  assert_equal [1,2], e.peek
+end
+
+assert 'Enumerator#feed' do
+  o = Object.new
+  def o.each(ary)
+    ary << yield
+    ary << yield
+    ary << yield
+  end
+  ary = []
+  e = o.to_enum :each, ary
+  e.next
+  e.feed 1
+  e.next
+  e.feed 2
+  e.next
+  e.feed 3
+  assert_raise(StopIteration) { e.next }
+  assert_equal [1,2,3], ary
+end
+
+assert 'Enumerator#feed mixed' do
+  o = Object.new
+  def o.each(ary)
+    ary << yield
+    ary << yield
+    ary << yield
+  end
+  ary = []
+  e = o.to_enum :each, ary
+  e.next
+  e.feed 1
+  e.next
+  e.next
+  e.feed 3
+  assert_raise(StopIteration) { e.next }
+  assert_equal [1,nil,3], ary
+end
+
+assert 'Enumerator#feed twice' do
+  o = Object.new
+  def o.each(ary)
+    ary << yield
+    ary << yield
+    ary << yield
+  end
+  ary = []
+  e = o.to_enum :each, ary
+  e.feed 1
+  assert_raise(TypeError) { e.feed 2 }
+end
+
+assert 'Enumerator#feed before first next' do
+  o = Object.new
+  def o.each(ary)
+    ary << yield
+    ary << yield
+    ary << yield
+  end
+  ary = []
+  e = o.to_enum :each, ary
+  e.feed 1
+  e.next
+  e.next
+  assert_equal [1], ary
+end
+
+assert 'Enumerator#feed yielder' do
+  x = nil
+  e = Enumerator.new {|y| x = y.yield; 10 }
+  e.next
+  e.feed 100
+  assert_raise(StopIteration) { e.next }
+  assert_equal 100, x
+end
+
+assert 'Enumerator#rewind' do
+  e = @obj.to_enum(:foo, 1, 2, 3)
+  assert_equal 1, e.next
+  assert_equal 2, e.next
+  e.rewind
+  assert_equal 1, e.next
+  assert_equal 2, e.next
+  assert_equal 3, e.next
+  assert_raise(StopIteration) { e.next }
+end
+
+assert 'Enumerator#rewind clear feed' do
+  o = Object.new
+  def o.each(ary)
+    ary << yield
+    ary << yield
+    ary << yield
+  end
+  ary = []
+  e = o.to_enum(:each, ary)
+  e.next
+  e.feed 1
+  e.next
+  e.feed 2
+  e.rewind
+  e.next
+  e.next
+  assert_equal([1,nil], ary)
+end
+
+assert 'Enumerator#rewind clear' do
+  o = Object.new
+  def o.each(ary)
+    ary << yield
+    ary << yield
+    ary << yield
+  end
+  ary = []
+  e = o.to_enum :each, ary
+  e.next
+  e.feed 1
+  e.next
+  e.feed 2
+  e.rewind
+  e.next
+  e.next
+  assert_equal [1,nil], ary
+end
+
+assert 'Enumerator::Generator' do
+  # note: Enumerator::Generator is a class just for internal
+  g = Enumerator::Generator.new {|y| y << 1 << 2 << 3; :foo }
+  g2 = g.dup
+  a = []
+  assert_equal(:foo, g.each {|x| a << x })
+  assert_equal([1, 2, 3], a)
+  a = []
+  assert_equal(:foo, g2.each {|x| a << x })
+  assert_equal([1, 2, 3], a)
+end
+
+assert 'Enumerator::Generator args' do
+  g = Enumerator::Generator.new {|y, x| y << 1 << 2 << 3; x }
+  a = []
+  assert_equal(:bar, g.each(:bar) {|x| a << x })
+  assert_equal([1, 2, 3], a)
+end
+
+assert 'Enumerator::Yielder' do
+  # note: Enumerator::Yielder is a class just for internal
+  a = []
+  y = Enumerator::Yielder.new {|x| a << x }
+  assert_equal(y, y << 1 << 2 << 3)
+  assert_equal([1, 2, 3], a)
+
+  a = []
+  y = Enumerator::Yielder.new {|x| a << x }
+  assert_equal([1], y.yield(1))
+  assert_equal([1, 2], y.yield(2))
+  assert_equal([1, 2, 3], y.yield(3))
+
+  assert_raise(LocalJumpError) { Enumerator::Yielder.new }
+end
+
+assert 'next after StopIteration' do
+  a = [1]
+  e = a.each
+  assert_equal(1, e.next)
+  assert_raise(StopIteration) { e.next }
+  assert_raise(StopIteration) { e.next }
+  e.rewind
+  assert_equal(1, e.next)
+  assert_raise(StopIteration) { e.next }
+  assert_raise(StopIteration) { e.next }
+end
+
+assert 'gc' do
+  assert_nothing_raised do
+    1.times do
+      foo = [1,2,3].to_enum
+      GC.start
+    end
+    GC.start
+  end
+end
+
+assert 'nested iteration' do
+  def (o = Object.new).each
+    yield :ok1
+    yield [:ok2, :x].each.next
+  end
+  e = o.to_enum
+  assert_equal :ok1, e.next
+  assert_equal :ok2, e.next
+  assert_raise(StopIteration) { e.next }
+end
+
+assert 'Kernel#to_enum' do
+  assert_equal Enumerator, [].to_enum.class
+  assert_raise(ArgumentError){ nil.to_enum }
+end
+
+assert 'modifying existing methods' do
+  assert_equal Enumerator, loop.class
+  e = 3.times
+  i = 0
+  loop_ret = loop {
+    assert_equal i, e.next
+    i += 1
+  }
+end
+
+assert 'Integral#times' do
+  a = 3
+  b = a.times
+  c = []
+  b.with_object(c) do |i, obj|
+    obj << i
+  end
+  assert_equal 3, a
+  assert_equal Enumerator, b.class
+  assert_equal [0,1,2], c
+end
+
+assert 'Enumerable#each_with_index' do
+  assert_equal [['a',0],['b',1],['c',2]], ['a','b','c'].each_with_index.to_a
+end
+
+assert 'Enumerable#map' do
+  a = [1,2,3]
+  b = a.map
+  c = b.with_index do |i, index|
+    [i*i, index*index]
+  end
+  assert_equal [1,2,3], a
+  assert_equal [[1,0],[4,1],[9,4]], c
+end
+
+assert 'Enumerable#find_all' do
+  assert_equal [[3,4]], [[1,2],[3,4],[5,6]].find_all.each{ |i| i[1] == 4 }
+end
+
+assert 'Array#each_index' do
+  a = [1,2,3]
+  b = a.each_index
+  c = []
+  b.with_index do |index1,index2|
+    c << [index1+2,index2+5]
+  end
+  assert_equal [1,2,3], a
+  assert_equal [[2,5],[3,6],[4,7]], c
+end
+
+assert 'Array#map!' do
+  a = [1,2,3]
+  b = a.map!
+  b.with_index do |i, index|
+    [i*i, index*index]
+  end
+  assert_equal [[1,0],[4,1],[9,4]], a
+end
+
+assert 'Hash#each' do
+  a = {a:1,b:2}
+  b = a.each
+  c = []
+  b.each do |k,v|
+    c << [k,v]
+  end
+  assert_equal [[:a,1], [:b,2]], c.sort
+end
+
+assert 'Hash#each_key' do
+  assert_equal [:a,:b], {a:1,b:2}.each_key.to_a.sort
+end
+
+assert 'Hash#each_value' do
+  assert_equal [1,2], {a:1,b:2}.each_value.to_a.sort
+end
+
+assert 'Hash#select' do
+  h = {1=>2,3=>4,5=>6}
+  hret = h.select.with_index {|a,b| a[1] == 4}
+  assert_equal({3=>4}, hret)
+  assert_equal({1=>2,3=>4,5=>6}, h)
+end
+
+assert 'Hash#select!' do
+  h = {1=>2,3=>4,5=>6}
+  hret = h.select!.with_index {|a,b| a[1] == 4}
+  assert_equal h, hret
+  assert_equal({3=>4}, h)
+end
+
+assert 'Hash#reject' do
+  h = {1=>2,3=>4,5=>6}
+  hret = h.reject.with_index {|a,b| a[1] == 4}
+  assert_equal({1=>2,5=>6}, hret)
+  assert_equal({1=>2,3=>4,5=>6}, h)
+end
+
+assert 'Hash#reject!' do
+  h = {1=>2,3=>4,5=>6}
+  hret = h.reject!.with_index {|a,b| a[1] == 4}
+  assert_equal h, hret
+  assert_equal({1=>2,5=>6}, h)
+end
+
+assert 'Range#each' do
+  a = (1..5)
+  b = a.each
+  c = []
+  b.each do |i|
+    c << i
+  end
+  assert_equal [1,2,3,4,5], c
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-error/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-error/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-error/mrbgem.rake	(revision 331)
@@ -0,0 +1,10 @@
+MRuby::Gem::Specification.new('mruby-error') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'extensional error handling'
+
+  if build.cxx_exception_enabled?
+    @objs << build.compile_as_cxx("#{spec.dir}/src/exception.c", "#{spec.build_dir}/src/exception.cxx")
+    @objs.delete_if { |v| v == objfile("#{spec.build_dir}/src/exception") }
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-error/src/exception.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-error/src/exception.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-error/src/exception.c	(revision 331)
@@ -0,0 +1,100 @@
+#include <mruby.h>
+#include <mruby/throw.h>
+#include <mruby/error.h>
+
+MRB_API mrb_value
+mrb_protect(mrb_state *mrb, mrb_func_t body, mrb_value data, mrb_bool *state)
+{
+  struct mrb_jmpbuf *prev_jmp = mrb->jmp;
+  struct mrb_jmpbuf c_jmp;
+  mrb_value result = mrb_nil_value();
+
+  if (state) { *state = FALSE; }
+
+  MRB_TRY(&c_jmp) {
+    mrb->jmp = &c_jmp;
+    result = body(mrb, data);
+    mrb->jmp = prev_jmp;
+  } MRB_CATCH(&c_jmp) {
+    mrb->jmp = prev_jmp;
+    result = mrb_obj_value(mrb->exc);
+    mrb->exc = NULL;
+    if (state) { *state = TRUE; }
+  } MRB_END_EXC(&c_jmp);
+
+  mrb_gc_protect(mrb, result);
+  return result;
+}
+
+MRB_API mrb_value
+mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t ensure, mrb_value e_data)
+{
+  struct mrb_jmpbuf *prev_jmp = mrb->jmp;
+  struct mrb_jmpbuf c_jmp;
+  mrb_value result;
+
+  MRB_TRY(&c_jmp) {
+    mrb->jmp = &c_jmp;
+    result = body(mrb, b_data);
+    mrb->jmp = prev_jmp;
+  } MRB_CATCH(&c_jmp) {
+    mrb->jmp = prev_jmp;
+    ensure(mrb, e_data);
+    MRB_THROW(mrb->jmp); /* rethrow catched exceptions */
+  } MRB_END_EXC(&c_jmp);
+
+  ensure(mrb, e_data);
+  mrb_gc_protect(mrb, result);
+  return result;
+}
+
+MRB_API mrb_value
+mrb_rescue(mrb_state *mrb, mrb_func_t body, mrb_value b_data,
+           mrb_func_t rescue, mrb_value r_data)
+{
+  return mrb_rescue_exceptions(mrb, body, b_data, rescue, r_data, 1, &mrb->eStandardError_class);
+}
+
+MRB_API mrb_value
+mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t rescue, mrb_value r_data,
+                      mrb_int len, struct RClass **classes)
+{
+  struct mrb_jmpbuf *prev_jmp = mrb->jmp;
+  struct mrb_jmpbuf c_jmp;
+  mrb_value result;
+  mrb_bool error_matched = FALSE;
+  mrb_int i;
+
+  MRB_TRY(&c_jmp) {
+    mrb->jmp = &c_jmp;
+    result = body(mrb, b_data);
+    mrb->jmp = prev_jmp;
+  } MRB_CATCH(&c_jmp) {
+    mrb->jmp = prev_jmp;
+
+    for (i = 0; i < len; ++i) {
+      if (mrb_obj_is_kind_of(mrb, mrb_obj_value(mrb->exc), classes[i])) {
+        error_matched = TRUE;
+        break;
+      }
+    }
+
+    if (!error_matched) { MRB_THROW(mrb->jmp); }
+
+    mrb->exc = NULL;
+    result = rescue(mrb, r_data);
+  } MRB_END_EXC(&c_jmp);
+
+  mrb_gc_protect(mrb, result);
+  return result;
+}
+
+void
+mrb_mruby_error_gem_init(mrb_state *mrb)
+{
+}
+
+void
+mrb_mruby_error_gem_final(mrb_state *mrb)
+{
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-error/test/exception.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-error/test/exception.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-error/test/exception.c	(revision 331)
@@ -0,0 +1,59 @@
+#include <mruby.h>
+#include <mruby/error.h>
+#include <mruby/array.h>
+
+static mrb_value
+protect_cb(mrb_state *mrb, mrb_value b)
+{
+  return mrb_yield_argv(mrb, b, 0, NULL);
+}
+
+static mrb_value
+run_protect(mrb_state *mrb, mrb_value self)
+{
+  mrb_value b;
+  mrb_value ret[2];
+  mrb_bool state;
+  mrb_get_args(mrb, "&", &b);
+  ret[0] = mrb_protect(mrb, protect_cb, b, &state);
+  ret[1] = mrb_bool_value(state);
+  return mrb_ary_new_from_values(mrb, 2, ret);
+}
+
+static mrb_value
+run_ensure(mrb_state *mrb, mrb_value self)
+{
+  mrb_value b, e;
+  mrb_get_args(mrb, "oo", &b, &e);
+  return mrb_ensure(mrb, protect_cb, b, protect_cb, e);
+}
+
+static mrb_value
+run_rescue(mrb_state *mrb, mrb_value self)
+{
+  mrb_value b, r;
+  mrb_get_args(mrb, "oo", &b, &r);
+  return mrb_rescue(mrb, protect_cb, b, protect_cb, r);
+}
+
+static mrb_value
+run_rescue_exceptions(mrb_state *mrb, mrb_value self)
+{
+  mrb_value b, r;
+  struct RClass *cls[1];
+  mrb_get_args(mrb, "oo", &b, &r);
+  cls[0] = E_TYPE_ERROR;
+  return mrb_rescue_exceptions(mrb, protect_cb, b, protect_cb, r, 1, cls);
+}
+
+void
+mrb_mruby_error_gem_test(mrb_state *mrb)
+{
+  struct RClass *cls;
+
+  cls = mrb_define_class(mrb, "ExceptionTest", mrb->object_class);
+  mrb_define_module_function(mrb, cls, "mrb_protect", run_protect, MRB_ARGS_NONE() | MRB_ARGS_BLOCK());
+  mrb_define_module_function(mrb, cls, "mrb_ensure", run_ensure, MRB_ARGS_REQ(2));
+  mrb_define_module_function(mrb, cls, "mrb_rescue", run_rescue, MRB_ARGS_REQ(2));
+  mrb_define_module_function(mrb, cls, "mrb_rescue_exceptions", run_rescue_exceptions, MRB_ARGS_REQ(2));
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-error/test/exception.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-error/test/exception.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-error/test/exception.rb	(revision 331)
@@ -0,0 +1,55 @@
+assert 'mrb_protect' do
+  # no failure in protect returns [result, false]
+  assert_equal ['test', false] do
+    ExceptionTest.mrb_protect { 'test' }
+  end
+  # failure in protect returns [exception, true]
+  result = ExceptionTest.mrb_protect { raise 'test' }
+  assert_kind_of RuntimeError, result[0]
+  assert_true result[1]
+end
+
+assert 'mrb_ensure' do
+  a = false
+  assert_equal 'test' do
+    ExceptionTest.mrb_ensure Proc.new { 'test' }, Proc.new { a = true }
+  end
+  assert_true a
+
+  a = false
+  assert_raise RuntimeError do
+    ExceptionTest.mrb_ensure Proc.new { raise 'test' }, Proc.new { a = true }
+  end
+  assert_true a
+end
+
+assert 'mrb_rescue' do
+  assert_equal 'test' do
+    ExceptionTest.mrb_rescue Proc.new { 'test' }, Proc.new {}
+  end
+
+  class CustomExp < Exception
+  end
+
+  assert_raise CustomExp do
+    ExceptionTest.mrb_rescue Proc.new { raise CustomExp.new 'test' }, Proc.new { 'rescue' }
+  end
+
+  assert_equal 'rescue' do
+    ExceptionTest.mrb_rescue Proc.new { raise 'test' }, Proc.new { 'rescue' }
+  end
+end
+
+assert 'mrb_rescue_exceptions' do
+  assert_equal 'test' do
+    ExceptionTest.mrb_rescue_exceptions Proc.new { 'test' }, Proc.new {}
+  end
+
+  assert_raise RangeError do
+    ExceptionTest.mrb_rescue_exceptions Proc.new { raise RangeError.new 'test' }, Proc.new { 'rescue' }
+  end
+
+  assert_equal 'rescue' do
+    ExceptionTest.mrb_rescue_exceptions Proc.new { raise TypeError.new 'test' }, Proc.new { 'rescue' }
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-eval/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-eval/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-eval/mrbgem.rake	(revision 331)
@@ -0,0 +1,7 @@
+MRuby::Gem::Specification.new('mruby-eval') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'standard Kernel#eval method'
+
+  add_dependency 'mruby-compiler', :core => 'mruby-compiler'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-eval/src/eval.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-eval/src/eval.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-eval/src/eval.c	(revision 331)
@@ -0,0 +1,292 @@
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/compile.h>
+#include <mruby/irep.h>
+#include <mruby/proc.h>
+#include <mruby/opcode.h>
+#include <mruby/error.h>
+
+mrb_value mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p);
+mrb_value mrb_obj_instance_eval(mrb_state *mrb, mrb_value self);
+
+static struct mrb_irep *
+get_closure_irep(mrb_state *mrb, int level)
+{
+  struct mrb_context *c = mrb->c;
+  struct REnv *e = c->ci[-1].proc->env;
+  struct RProc *proc;
+
+  if (level == 0) {
+    proc = c->ci[-1].proc;
+    if (MRB_PROC_CFUNC_P(proc)) {
+      return NULL;
+    }
+    return proc->body.irep;
+  }
+
+  while (--level) {
+    e = (struct REnv*)e->c;
+    if (!e) return NULL;
+  }
+
+  if (!e) return NULL;
+  if (!MRB_ENV_STACK_SHARED_P(e)) return NULL;
+  c = e->cxt.c;
+  proc = c->cibase[e->cioff].proc;
+
+  if (!proc || MRB_PROC_CFUNC_P(proc)) {
+    return NULL;
+  }
+  return proc->body.irep;
+}
+
+static inline mrb_code
+search_variable(mrb_state *mrb, mrb_sym vsym, int bnest)
+{
+  mrb_irep *virep;
+  int level;
+  int pos;
+
+  for (level = 0; (virep = get_closure_irep(mrb, level)); level++) {
+    if (!virep || virep->lv == NULL) {
+      continue;
+    }
+    for (pos = 0; pos < virep->nlocals - 1; pos++) {
+      if (vsym == virep->lv[pos].name) {
+        return (MKARG_B(pos + 1) | MKARG_C(level + bnest));
+      }
+    }
+  }
+
+  return 0;
+}
+
+static mrb_bool
+potential_upvar_p(struct mrb_locals *lv, uint16_t v, int argc, uint16_t nlocals)
+{
+  if (v >= nlocals) return FALSE;
+  /* skip arguments  */
+  if (v < argc+1) return FALSE;
+  return TRUE;
+}
+
+static void
+patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest)
+{
+  size_t i;
+  mrb_code c;
+  int argc = 0;
+
+  for (i = 0; i < irep->ilen; i++) {
+    c = irep->iseq[i];
+    switch(GET_OPCODE(c)){
+    case OP_ENTER:
+      {
+        mrb_aspec ax = GETARG_Ax(c);
+        /* extra 1 means a slot for block */
+        argc = MRB_ASPEC_REQ(ax)+MRB_ASPEC_OPT(ax)+MRB_ASPEC_REST(ax)+MRB_ASPEC_POST(ax)+1;
+      }
+      break;
+
+    case OP_EPUSH:
+      patch_irep(mrb, irep->reps[GETARG_Bx(c)], bnest + 1);
+      break;
+
+    case OP_LAMBDA:
+      {
+        int arg_c = GETARG_c(c);
+        if (arg_c & OP_L_CAPTURE) {
+          patch_irep(mrb, irep->reps[GETARG_b(c)], bnest + 1);
+        }
+      }
+      break;
+
+    case OP_SEND:
+      if (GETARG_C(c) != 0) {
+        break;
+      }
+      {
+        mrb_code arg = search_variable(mrb, irep->syms[GETARG_B(c)], bnest);
+        if (arg != 0) {
+          /* must replace */
+          irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg;
+        }
+      }
+      break;
+
+    case OP_MOVE:
+      /* src part */
+      if (potential_upvar_p(irep->lv, GETARG_B(c), argc, irep->nlocals)) {
+        mrb_code arg = search_variable(mrb, irep->lv[GETARG_B(c) - 1].name, bnest);
+        if (arg != 0) {
+          /* must replace */
+          irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg;
+        }
+      }
+      /* dst part */
+      if (potential_upvar_p(irep->lv, GETARG_A(c), argc, irep->nlocals)) {
+        mrb_code arg = search_variable(mrb, irep->lv[GETARG_A(c) - 1].name, bnest);
+        if (arg != 0) {
+          /* must replace */
+          irep->iseq[i] = MKOPCODE(OP_SETUPVAR) | MKARG_A(GETARG_B(c)) | arg;
+        }
+      }
+      break;
+
+    case OP_STOP:
+      if (mrb->c->ci->acc >= 0) {
+        irep->iseq[i] = MKOP_AB(OP_RETURN, irep->nlocals, OP_R_NORMAL);
+      }
+      break;
+    }
+  }
+}
+
+void mrb_codedump_all(mrb_state*, struct RProc*);
+
+static struct RProc*
+create_proc_from_string(mrb_state *mrb, char *s, int len, mrb_value binding, const char *file, mrb_int line)
+{
+  mrbc_context *cxt;
+  struct mrb_parser_state *p;
+  struct RProc *proc;
+  struct REnv *e;
+  struct mrb_context *c = mrb->c;
+
+  if (!mrb_nil_p(binding)) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "Binding of eval must be nil.");
+  }
+
+  cxt = mrbc_context_new(mrb);
+  cxt->lineno = line;
+
+  mrbc_filename(mrb, cxt, file ? file : "(eval)");
+  cxt->capture_errors = TRUE;
+  cxt->no_optimize = TRUE;
+
+  p = mrb_parse_nstring(mrb, s, len, cxt);
+
+  /* only occur when memory ran out */
+  if (!p) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to create parser state.");
+  }
+
+  if (0 < p->nerr) {
+    /* parse error */
+    mrb_value str;
+
+    if (file) {
+      str = mrb_format(mrb, " file %S line %S: %S",
+                       mrb_str_new_cstr(mrb, file),
+                       mrb_fixnum_value(p->error_buffer[0].lineno),
+                       mrb_str_new_cstr(mrb, p->error_buffer[0].message));
+    }
+    else {
+      str = mrb_format(mrb, " line %S: %S",
+                       mrb_fixnum_value(p->error_buffer[0].lineno),
+                       mrb_str_new_cstr(mrb, p->error_buffer[0].message));
+    }
+    mrb_parser_free(p);
+    mrbc_context_free(mrb, cxt);
+    mrb_exc_raise(mrb, mrb_exc_new_str(mrb, E_SYNTAX_ERROR, str));
+  }
+
+  proc = mrb_generate_code(mrb, p);
+  if (proc == NULL) {
+    /* codegen error */
+    mrb_parser_free(p);
+    mrbc_context_free(mrb, cxt);
+    mrb_raise(mrb, E_SCRIPT_ERROR, "codegen error");
+  }
+  if (c->ci[-1].proc->target_class) {
+    proc->target_class = c->ci[-1].proc->target_class;
+  }
+  e = c->ci[-1].proc->env;
+  if (!e) e = c->ci[-1].env;
+  e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)e);
+  e->cxt.c = c;
+  e->cioff = c->ci - c->cibase;
+  e->stack = c->ci->stackent;
+  MRB_SET_ENV_STACK_LEN(e, c->ci->proc->body.irep->nlocals);
+  c->ci->target_class = proc->target_class;
+  c->ci->env = 0;
+  proc->env = e;
+  patch_irep(mrb, proc->body.irep, 0);
+
+  mrb_parser_free(p);
+  mrbc_context_free(mrb, cxt);
+
+  return proc;
+}
+
+static mrb_value
+exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc)
+{
+  if (mrb->c->ci->acc < 0) {
+    mrb_value ret = mrb_top_run(mrb, proc, mrb->c->stack[0], 0);
+    if (mrb->exc) {
+      mrb_exc_raise(mrb, mrb_obj_value(mrb->exc));
+    }
+    return ret;
+  }
+  return mrb_exec_irep(mrb, self, proc);
+}
+
+static mrb_value
+f_eval(mrb_state *mrb, mrb_value self)
+{
+  char *s;
+  mrb_int len;
+  mrb_value binding = mrb_nil_value();
+  char *file = NULL;
+  mrb_int line = 1;
+  struct RProc *proc;
+
+  mrb_get_args(mrb, "s|ozi", &s, &len, &binding, &file, &line);
+
+  proc = create_proc_from_string(mrb, s, len, binding, file, line);
+  mrb_assert(!MRB_PROC_CFUNC_P(proc));
+  return exec_irep(mrb, self, proc);
+}
+
+static mrb_value
+f_instance_eval(mrb_state *mrb, mrb_value self)
+{
+  mrb_value b;
+  mrb_int argc; mrb_value *argv;
+
+  mrb_get_args(mrb, "*&", &argv, &argc, &b);
+
+  if (mrb_nil_p(b)) {
+    char *s;
+    mrb_int len;
+    char *file = NULL;
+    mrb_int line = 1;
+    mrb_value cv;
+    struct RProc *proc;
+
+    mrb_get_args(mrb, "s|zi", &s, &len, &file, &line);
+    cv = mrb_singleton_class(mrb, self);
+    proc = create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line);
+    proc->target_class = mrb_class_ptr(cv);
+    mrb->c->ci->env = NULL;
+    mrb_assert(!MRB_PROC_CFUNC_P(proc));
+    return exec_irep(mrb, self, proc);
+  }
+  else {
+    mrb_get_args(mrb, "&", &b);
+    return mrb_obj_instance_eval(mrb, self);
+  }
+}
+
+void
+mrb_mruby_eval_gem_init(mrb_state* mrb)
+{
+  mrb_define_module_function(mrb, mrb->kernel_module, "eval", f_eval, MRB_ARGS_ARG(1, 3));
+  mrb_define_method(mrb, mrb->kernel_module, "instance_eval", f_instance_eval, MRB_ARGS_ARG(1, 2));
+}
+
+void
+mrb_mruby_eval_gem_final(mrb_state* mrb)
+{
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-eval/test/eval.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-eval/test/eval.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-eval/test/eval.rb	(revision 331)
@@ -0,0 +1,101 @@
+assert('Kernel.eval', '15.3.1.2.3') do
+  assert_equal(10) { Kernel.eval '1 * 10' }
+  assert_equal('aaa') { Kernel.eval "'a' * 3" }
+  assert_equal(10) {
+    a = 10
+    Kernel.eval "a"
+  }
+  assert_equal(20) {
+    a = 10
+    Kernel.eval "a = 20"
+    a
+  }
+  assert_equal(15) {
+    c = 5
+    lambda {
+      a = 10
+      Kernel.eval "c = a + c"
+    }.call
+    c
+  }
+  assert_equal(5) {
+    c = 5
+    lambda {
+      Kernel.eval 'lambda { c }.call'
+    }.call
+  }
+  assert_equal(15) {
+    c = 5
+    lambda {
+      a = 10
+      Kernel.eval 'lambda { c = a + c }.call'
+    }.call
+    c
+  }
+  assert_equal(2) {
+    a = 10
+    Kernel.eval 'def f(a); b=a.send(:+, 1); end'
+    f(1)
+  }
+end
+
+assert('Kernel#eval', '15.3.1.3.12') do
+  assert_equal(10) { eval '1 * 10' }
+end
+
+assert('rest arguments of eval') do
+  assert_raise(ArgumentError) { Kernel.eval('0', 0, 'test', 0) }
+  assert_equal ['test', 'test.rb', 10] do
+    Kernel.eval('[\'test\', __FILE__, __LINE__]', nil, 'test.rb', 10)
+  end
+end
+
+assert 'eval syntax error' do
+  assert_raise(SyntaxError) do
+    eval 'p "test'
+  end
+end
+
+assert('String instance_eval') do
+  obj = Object.new
+  obj.instance_variable_set :@test, 'test'
+  assert_raise(ArgumentError) { obj.instance_eval(0) { } }
+  assert_raise(ArgumentError) { obj.instance_eval('0', 'test', 0, 'test') }
+  assert_equal(['test.rb', 10]) { obj.instance_eval('[__FILE__, __LINE__]', 'test.rb', 10)}
+  assert_equal('test') { obj.instance_eval('@test') }
+  assert_equal('test') { obj.instance_eval { @test } }
+  o = Object.new
+  assert_equal ['', o, o], o.instance_eval("[''].each { |s| break [s, o, self] }")
+end
+
+assert('Kernel.#eval(string) context') do
+  class TestEvalConstScope
+    EVAL_CONST_CLASS = 'class'
+    def const_string
+      eval 'EVAL_CONST_CLASS'
+    end
+  end
+  obj = TestEvalConstScope.new
+  assert_raise(NameError) { eval 'EVAL_CONST_CLASS' }
+  assert_equal('class') { obj.const_string }
+end
+
+assert('Object#instance_eval with begin-rescue-ensure execution order') do
+  class HellRaiser
+    def raise_hell
+      order = [:enter_raise_hell]
+      begin
+        order.push :begin
+        self.instance_eval("raise 'error'")
+      rescue
+        order.push :rescue
+      ensure
+        order.push :ensure
+      end
+      order
+    end
+  end
+
+  hell_raiser = HellRaiser.new
+  assert_equal([:enter_raise_hell, :begin, :rescue, :ensure], hell_raiser.raise_hell)
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-exit/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-exit/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-exit/mrbgem.rake	(revision 331)
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-exit') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'Kernel#exit method'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-exit/src/mruby-exit.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-exit/src/mruby-exit.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-exit/src/mruby-exit.c	(revision 331)
@@ -0,0 +1,24 @@
+#include <stdlib.h>
+#include <mruby.h>
+
+static mrb_value
+f_exit(mrb_state *mrb, mrb_value self)
+{
+  mrb_int i = EXIT_SUCCESS;
+
+  mrb_get_args(mrb, "|i", &i);
+  exit(i);
+  /* not reached */
+  return mrb_nil_value();
+}
+
+void
+mrb_mruby_exit_gem_init(mrb_state* mrb)
+{
+  mrb_define_method(mrb, mrb->kernel_module, "exit", f_exit, MRB_ARGS_OPT(1));
+}
+
+void
+mrb_mruby_exit_gem_final(mrb_state* mrb)
+{
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-fiber/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-fiber/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-fiber/mrbgem.rake	(revision 331)
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-fiber') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'Fiber class'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-fiber/src/fiber.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-fiber/src/fiber.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-fiber/src/fiber.c	(revision 331)
@@ -0,0 +1,419 @@
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/class.h>
+#include <mruby/proc.h>
+
+#define fiber_ptr(o) ((struct RFiber*)mrb_ptr(o))
+
+#define FIBER_STACK_INIT_SIZE 64
+#define FIBER_CI_INIT_SIZE 8
+#define CI_ACC_RESUMED -3
+
+/*
+ *  call-seq:
+ *     Fiber.new{...} -> obj
+ *
+ *  Creates a fiber, whose execution is suspend until it is explicitly
+ *  resumed using <code>Fiber#resume</code> method.
+ *  The code running inside the fiber can give up control by calling
+ *  <code>Fiber.yield</code> in which case it yields control back to caller
+ *  (the caller of the <code>Fiber#resume</code>).
+ *
+ *  Upon yielding or termination the Fiber returns the value of the last
+ *  executed expression
+ *
+ *  For instance:
+ *
+ *    fiber = Fiber.new do
+ *      Fiber.yield 1
+ *      2
+ *    end
+ *
+ *    puts fiber.resume
+ *    puts fiber.resume
+ *    puts fiber.resume
+ *
+ *  <em>produces</em>
+ *
+ *    1
+ *    2
+ *    resuming dead fiber (FiberError)
+ *
+ *  The <code>Fiber#resume</code> method accepts an arbitrary number of
+ *  parameters, if it is the first call to <code>resume</code> then they
+ *  will be passed as block arguments. Otherwise they will be the return
+ *  value of the call to <code>Fiber.yield</code>
+ *
+ *  Example:
+ *
+ *    fiber = Fiber.new do |first|
+ *      second = Fiber.yield first + 2
+ *    end
+ *
+ *    puts fiber.resume 10
+ *    puts fiber.resume 14
+ *    puts fiber.resume 18
+ *
+ *  <em>produces</em>
+ *
+ *    12
+ *    14
+ *    resuming dead fiber (FiberError)
+ *
+ */
+static mrb_value
+fiber_init(mrb_state *mrb, mrb_value self)
+{
+  static const struct mrb_context mrb_context_zero = { 0 };
+  struct RFiber *f = fiber_ptr(self);
+  struct mrb_context *c;
+  struct RProc *p;
+  mrb_callinfo *ci;
+  mrb_value blk;
+  size_t slen;
+
+  mrb_get_args(mrb, "&", &blk);
+
+  if (f->cxt) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "cannot initialize twice");
+  }
+  if (mrb_nil_p(blk)) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Fiber object without a block");
+  }
+  p = mrb_proc_ptr(blk);
+  if (MRB_PROC_CFUNC_P(p)) {
+    mrb_raise(mrb, E_FIBER_ERROR, "tried to create Fiber from C defined method");
+  }
+
+  c = (struct mrb_context*)mrb_malloc(mrb, sizeof(struct mrb_context));
+  *c = mrb_context_zero;
+  f->cxt = c;
+
+  /* initialize VM stack */
+  slen = FIBER_STACK_INIT_SIZE;
+  if (p->body.irep->nregs > slen) {
+    slen += p->body.irep->nregs;
+  }
+  c->stbase = (mrb_value *)mrb_malloc(mrb, slen*sizeof(mrb_value));
+  c->stend = c->stbase + slen;
+  c->stack = c->stbase;
+
+#ifdef MRB_NAN_BOXING
+  {
+    mrb_value *p = c->stbase;
+    mrb_value *pend = c->stend;
+
+    while (p < pend) {
+      SET_NIL_VALUE(*p);
+      p++;
+    }
+  }
+#else
+  memset(c->stbase, 0, slen * sizeof(mrb_value));
+#endif
+
+  /* copy receiver from a block */
+  c->stack[0] = mrb->c->stack[0];
+
+  /* initialize callinfo stack */
+  c->cibase = (mrb_callinfo *)mrb_calloc(mrb, FIBER_CI_INIT_SIZE, sizeof(mrb_callinfo));
+  c->ciend = c->cibase + FIBER_CI_INIT_SIZE;
+  c->ci = c->cibase;
+  c->ci->stackent = c->stack;
+
+  /* adjust return callinfo */
+  ci = c->ci;
+  ci->target_class = p->target_class;
+  ci->proc = p;
+  ci->pc = p->body.irep->iseq;
+  ci->nregs = p->body.irep->nregs;
+  ci[1] = ci[0];
+  c->ci++;                      /* push dummy callinfo */
+
+  c->fib = f;
+  c->status = MRB_FIBER_CREATED;
+
+  return self;
+}
+
+static struct mrb_context*
+fiber_check(mrb_state *mrb, mrb_value fib)
+{
+  struct RFiber *f = fiber_ptr(fib);
+
+  mrb_assert(f->tt == MRB_TT_FIBER);
+  if (!f->cxt) {
+    mrb_raise(mrb, E_FIBER_ERROR, "uninitialized Fiber");
+  }
+  return f->cxt;
+}
+
+static mrb_value
+fiber_result(mrb_state *mrb, const mrb_value *a, mrb_int len)
+{
+  if (len == 0) return mrb_nil_value();
+  if (len == 1) return a[0];
+  return mrb_ary_new_from_values(mrb, len, a);
+}
+
+/* mark return from context modifying method */
+#define MARK_CONTEXT_MODIFY(c) (c)->ci->target_class = NULL
+
+static void
+fiber_check_cfunc(mrb_state *mrb, struct mrb_context *c)
+{
+  mrb_callinfo *ci;
+
+  for (ci = c->ci; ci >= c->cibase; ci--) {
+    if (ci->acc < 0) {
+      mrb_raise(mrb, E_FIBER_ERROR, "can't cross C function boundary");
+    }
+  }
+}
+
+static void
+fiber_switch_context(mrb_state *mrb, struct mrb_context *c)
+{
+  if (mrb->c->fib) {
+    mrb_write_barrier(mrb, (struct RBasic*)mrb->c->fib);
+  }
+  c->status = MRB_FIBER_RUNNING;
+  mrb->c = c;
+}
+
+static mrb_value
+fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mrb_bool resume, mrb_bool vmexec)
+{
+  struct mrb_context *c = fiber_check(mrb, self);
+  struct mrb_context *old_c = mrb->c;
+  mrb_value value;
+
+  fiber_check_cfunc(mrb, c);
+  if (resume && c->status == MRB_FIBER_TRANSFERRED) {
+    mrb_raise(mrb, E_FIBER_ERROR, "resuming transferred fiber");
+  }
+  if (c->status == MRB_FIBER_RUNNING || c->status == MRB_FIBER_RESUMED) {
+    mrb_raise(mrb, E_FIBER_ERROR, "double resume (fib)");
+  }
+  if (c->status == MRB_FIBER_TERMINATED) {
+    mrb_raise(mrb, E_FIBER_ERROR, "resuming dead fiber");
+  }
+  mrb->c->status = resume ? MRB_FIBER_RESUMED : MRB_FIBER_TRANSFERRED;
+  c->prev = resume ? mrb->c : (c->prev ? c->prev : mrb->root_c);
+  if (c->status == MRB_FIBER_CREATED) {
+    mrb_value *b, *e;
+
+    if (len >= c->stend - c->stack) {
+      mrb_raise(mrb, E_FIBER_ERROR, "too many arguments to fiber");
+    }
+    b = c->stack+1;
+    e = b + len;
+    while (b<e) {
+      *b++ = *a++;
+    }
+    c->cibase->argc = len;
+    value = c->stack[0] = c->ci->proc->env->stack[0];
+  }
+  else {
+    value = fiber_result(mrb, a, len);
+  }
+  fiber_switch_context(mrb, c);
+
+  if (vmexec) {
+    c->vmexec = TRUE;
+    value = mrb_vm_exec(mrb, c->ci[-1].proc, c->ci->pc);
+    mrb->c = old_c;
+  }
+  else {
+    MARK_CONTEXT_MODIFY(c);
+  }
+  return value;
+}
+
+/*
+ *  call-seq:
+ *     fiber.resume(args, ...) -> obj
+ *
+ *  Resumes the fiber from the point at which the last <code>Fiber.yield</code>
+ *  was called, or starts running it if it is the first call to
+ *  <code>resume</code>. Arguments passed to resume will be the value of
+ *  the <code>Fiber.yield</code> expression or will be passed as block
+ *  parameters to the fiber's block if this is the first <code>resume</code>.
+ *
+ *  Alternatively, when resume is called it evaluates to the arguments passed
+ *  to the next <code>Fiber.yield</code> statement inside the fiber's block
+ *  or to the block value if it runs to completion without any
+ *  <code>Fiber.yield</code>
+ */
+static mrb_value
+fiber_resume(mrb_state *mrb, mrb_value self)
+{
+  mrb_value *a;
+  mrb_int len;
+  mrb_bool vmexec = FALSE;
+
+  mrb_get_args(mrb, "*", &a, &len);
+  if (mrb->c->ci->acc < 0) {
+    vmexec = TRUE;
+  }
+  return fiber_switch(mrb, self, len, a, TRUE, vmexec);
+}
+
+/* resume thread with given arguments */
+MRB_API mrb_value
+mrb_fiber_resume(mrb_state *mrb, mrb_value fib, mrb_int len, const mrb_value *a)
+{
+  return fiber_switch(mrb, fib, len, a, TRUE, TRUE);
+}
+
+/*
+ *  call-seq:
+ *     fiber.alive? -> true or false
+ *
+ *  Returns true if the fiber can still be resumed. After finishing
+ *  execution of the fiber block this method will always return false.
+ */
+static mrb_value
+fiber_alive_p(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_context *c = fiber_check(mrb, self);
+  return mrb_bool_value(c->status != MRB_FIBER_TERMINATED);
+}
+
+static mrb_value
+fiber_eq(mrb_state *mrb, mrb_value self)
+{
+  mrb_value other;
+  mrb_get_args(mrb, "o", &other);
+
+  if (mrb_type(other) != MRB_TT_FIBER) {
+    return mrb_false_value();
+  }
+  return mrb_bool_value(fiber_ptr(self) == fiber_ptr(other));
+}
+
+/*
+ *  call-seq:
+ *     fiber.transfer(args, ...) -> obj
+ *
+ *  Transfers control to receiver fiber of the method call.
+ *  Unlike <code>resume</code> the receiver wouldn't be pushed to call
+ * stack of fibers. Instead it will switch to the call stack of
+ * transferring fiber.
+ *  When resuming a fiber that was transferred to another fiber it would
+ * cause double resume error. Though when the fiber is re-transferred
+ * and <code>Fiber.yield</code> is called, the fiber would be resumable.
+ */
+static mrb_value
+fiber_transfer(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_context *c = fiber_check(mrb, self);
+  mrb_value* a;
+  mrb_int len;
+
+  fiber_check_cfunc(mrb, mrb->c);
+  mrb_get_args(mrb, "*", &a, &len);
+
+  if (c == mrb->root_c) {
+    mrb->c->status = MRB_FIBER_TRANSFERRED;
+    fiber_switch_context(mrb, c);
+    MARK_CONTEXT_MODIFY(c);
+    return fiber_result(mrb, a, len);
+  }
+
+  if (c == mrb->c) {
+    return fiber_result(mrb, a, len);
+  }
+
+  return fiber_switch(mrb, self, len, a, FALSE, FALSE);
+}
+
+/* yield values to the caller fiber */
+/* mrb_fiber_yield() must be called as `return mrb_fiber_yield(...)` */
+MRB_API mrb_value
+mrb_fiber_yield(mrb_state *mrb, mrb_int len, const mrb_value *a)
+{
+  struct mrb_context *c = mrb->c;
+
+  if (!c->prev) {
+    mrb_raise(mrb, E_FIBER_ERROR, "can't yield from root fiber");
+  }
+
+  fiber_check_cfunc(mrb, c);
+  c->prev->status = MRB_FIBER_RUNNING;
+  c->status = MRB_FIBER_SUSPENDED;
+  fiber_switch_context(mrb, c->prev);
+  c->prev = NULL;
+  if (c->vmexec) {
+    c->vmexec = FALSE;
+    mrb->c->ci->acc = CI_ACC_RESUMED;
+  }
+  MARK_CONTEXT_MODIFY(mrb->c);
+  return fiber_result(mrb, a, len);
+}
+
+/*
+ *  call-seq:
+ *     Fiber.yield(args, ...) -> obj
+ *
+ *  Yields control back to the context that resumed the fiber, passing
+ *  along any arguments that were passed to it. The fiber will resume
+ *  processing at this point when <code>resume</code> is called next.
+ *  Any arguments passed to the next <code>resume</code> will be the
+ *
+ *  mruby limitation: Fiber resume/yield cannot cross C function boundary.
+ *  thus you cannot yield from #initialize which is called by mrb_funcall().
+ */
+static mrb_value
+fiber_yield(mrb_state *mrb, mrb_value self)
+{
+  mrb_value *a;
+  mrb_int len;
+
+  mrb_get_args(mrb, "*", &a, &len);
+  return mrb_fiber_yield(mrb, len, a);
+}
+
+/*
+ *  call-seq:
+ *     Fiber.current() -> fiber
+ *
+ *  Returns the current fiber. If you are not running in the context of
+ *  a fiber this method will return the root fiber.
+ */
+static mrb_value
+fiber_current(mrb_state *mrb, mrb_value self)
+{
+  if (!mrb->c->fib) {
+    struct RFiber *f = (struct RFiber*)mrb_obj_alloc(mrb, MRB_TT_FIBER, mrb_class_ptr(self));
+
+    f->cxt = mrb->c;
+    mrb->c->fib = f;
+  }
+  return mrb_obj_value(mrb->c->fib);
+}
+
+void
+mrb_mruby_fiber_gem_init(mrb_state* mrb)
+{
+  struct RClass *c;
+
+  c = mrb_define_class(mrb, "Fiber", mrb->object_class);
+  MRB_SET_INSTANCE_TT(c, MRB_TT_FIBER);
+
+  mrb_define_method(mrb, c, "initialize", fiber_init,    MRB_ARGS_NONE());
+  mrb_define_method(mrb, c, "resume",     fiber_resume,  MRB_ARGS_ANY());
+  mrb_define_method(mrb, c, "transfer",   fiber_transfer, MRB_ARGS_ANY());
+  mrb_define_method(mrb, c, "alive?",     fiber_alive_p, MRB_ARGS_NONE());
+  mrb_define_method(mrb, c, "==",         fiber_eq,      MRB_ARGS_REQ(1));
+
+  mrb_define_class_method(mrb, c, "yield", fiber_yield, MRB_ARGS_ANY());
+  mrb_define_class_method(mrb, c, "current", fiber_current, MRB_ARGS_NONE());
+
+  mrb_define_class(mrb, "FiberError", mrb->eStandardError_class);
+}
+
+void
+mrb_mruby_fiber_gem_final(mrb_state* mrb)
+{
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-fiber/test/fiber.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-fiber/test/fiber.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-fiber/test/fiber.rb	(revision 331)
@@ -0,0 +1,208 @@
+assert('Fiber.new') do
+  f = Fiber.new{}
+  assert_kind_of Fiber, f
+end
+
+assert('Fiber#resume') do
+  f = Fiber.new{|x| x }
+  assert_equal 2, f.resume(2)
+end
+
+assert('Fiber#transfer') do
+  f2 = nil
+  f1 = Fiber.new do |v|
+    Fiber.yield v
+    f2.transfer
+  end
+  f2 = Fiber.new do
+    f1.transfer(1)
+    f1.transfer(1)
+    Fiber.yield 2
+  end
+  assert_equal 1, f2.resume
+  assert_raise(FiberError) { f2.resume }
+  assert_equal 2, f2.transfer
+  assert_raise(FiberError) { f1.resume }
+  f1.transfer
+  f2.resume
+  assert_false f1.alive?
+  assert_false f2.alive?
+end
+
+assert('Fiber#alive?') do
+  f = Fiber.new{ Fiber.yield }
+  f.resume
+  assert_true f.alive?
+  f.resume
+  assert_false f.alive?
+end
+
+assert('Fiber#==') do
+  root = Fiber.current
+  assert_equal root, root
+  assert_equal root, Fiber.current
+  assert_false root != Fiber.current
+  f = Fiber.new {
+    assert_false root == Fiber.current
+  }
+  f.resume
+  assert_false f == root
+  assert_true f != root
+end
+
+assert('Fiber.yield') do
+  f = Fiber.new{|x| Fiber.yield x }
+  assert_equal 3, f.resume(3)
+  assert_true f.alive?
+end
+
+assert('FiberError') do
+  assert_equal StandardError, FiberError.superclass
+end
+
+assert('Fiber iteration') do
+  f1 = Fiber.new{
+    [1,2,3].each{|x| Fiber.yield(x)}
+  }
+  f2 = Fiber.new{
+    [9,8,7].each{|x| Fiber.yield(x)}
+  }
+  a = []
+  3.times {
+    a << f1.resume
+    a << f2.resume
+  }
+  assert_equal [1,9,2,8,3,7], a
+end
+
+assert('Fiber with splat in the block argument list') {
+  Fiber.new{|*x|x}.resume(1) == [1]
+}
+
+assert('Fiber raises on resume when dead') do
+  assert_raise(FiberError) do
+    f = Fiber.new{}
+    f.resume
+    assert_false f.alive?
+    f.resume
+  end
+end
+
+assert('Yield raises when called on root fiber') do
+  assert_raise(FiberError) { Fiber.yield }
+end
+
+assert('Double resume of Fiber') do
+  f1 = Fiber.new {}
+  f2 = Fiber.new {
+    f1.resume
+    assert_raise(FiberError) { f2.resume }
+    Fiber.yield 0
+  }
+  assert_equal 0, f2.resume
+  f2.resume
+  assert_false f1.alive?
+  assert_false f2.alive?
+end
+
+assert('Recursive resume of Fiber') do
+  f1, f2 = nil, nil
+  f1 = Fiber.new { assert_raise(FiberError) { f2.resume } }
+  f2 = Fiber.new {
+    f1.resume
+    Fiber.yield 0
+  }
+  f3 = Fiber.new {
+    f2.resume
+  }
+  assert_equal 0, f3.resume
+  f2.resume
+  assert_false f1.alive?
+  assert_false f2.alive?
+  assert_false f3.alive?
+end
+
+assert('Root fiber resume') do
+  root = Fiber.current
+  assert_raise(FiberError) { root.resume }
+  f = Fiber.new {
+    assert_raise(FiberError) { root.resume }
+  }
+  f.resume
+  assert_false f.alive?
+end
+
+assert('Fiber without block') do
+  assert_raise(ArgumentError) { Fiber.new }
+end
+
+
+assert('Transfer to self.') do
+  result = []
+  f = Fiber.new { result << :start; f.transfer; result << :end  }
+  f.transfer
+  assert_equal [:start, :end], result
+
+  result = []
+  f = Fiber.new { result << :start; f.transfer; result << :end  }
+  f.resume
+  assert_equal [:start, :end], result
+end
+
+assert('Resume transferred fiber') do
+  f = Fiber.new {
+    assert_raise(FiberError) { f.resume }
+  }
+  f.transfer
+end
+
+assert('Root fiber transfer.') do
+  result = nil
+  root = Fiber.current
+  f = Fiber.new {
+    result = :ok
+    root.transfer
+  }
+  f.resume
+  assert_true f.alive?
+  assert_equal :ok, result
+end
+
+assert('Break nested fiber with root fiber transfer') do
+  root = Fiber.current
+
+  result = nil
+  f2 = nil
+  f1 = Fiber.new {
+    Fiber.yield f2.resume
+    result = :f1
+  }
+  f2 = Fiber.new {
+    result = :to_root
+    root.transfer :from_f2
+    result = :f2
+  }
+  assert_equal :from_f2, f1.resume
+  assert_equal :to_root, result
+  assert_equal :f2, f2.transfer
+  assert_equal :f2, result
+  assert_false f2.alive?
+  assert_equal :f1, f1.resume
+  assert_equal :f1, result
+  assert_false f1.alive?
+end
+
+assert('CRuby Fiber#transfer test.') do
+  ary = []
+  f2 = nil
+  f1 = Fiber.new{
+    ary << f2.transfer(:foo)
+    :ok
+  }
+  f2 = Fiber.new{
+    ary << f1.transfer(:baz)
+    :ng
+  }
+  assert_equal :ok, f1.transfer
+  assert_equal [:baz], ary
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-hash-ext/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-hash-ext/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-hash-ext/mrbgem.rake	(revision 331)
@@ -0,0 +1,7 @@
+MRuby::Gem::Specification.new('mruby-hash-ext') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'Hash class extension'
+  spec.add_dependency 'mruby-enum-ext', :core => 'mruby-enum-ext'
+  spec.add_dependency 'mruby-array-ext', :core => 'mruby-array-ext'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-hash-ext/mrblib/hash.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-hash-ext/mrblib/hash.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-hash-ext/mrblib/hash.rb	(revision 331)
@@ -0,0 +1,385 @@
+class Hash
+
+  #  ISO does not define Hash#each_pair, so each_pair is defined in gem.
+  alias each_pair each
+
+  ##
+  # call-seq:
+  #     Hash[ key, value, ... ] -> new_hash
+  #     Hash[ [ [key, value], ... ] ] -> new_hash
+  #     Hash[ object ] -> new_hash
+  #
+  # Creates a new hash populated with the given objects.
+  #
+  # Similar to the literal `{ _key_ => _value_, ... }`. In the first
+  # form, keys and values occur in pairs, so there must be an even number of
+  # arguments.
+  #
+  # The second and third form take a single argument which is either an array
+  # of key-value pairs or an object convertible to a hash.
+  #
+  #     Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200}
+  #     Hash[ [ ["a", 100], ["b", 200] ] ] #=> {"a"=>100, "b"=>200}
+  #     Hash["a" => 100, "b" => 200] #=> {"a"=>100, "b"=>200}
+  #
+
+  def self.[](*object)
+    length = object.length
+    if length == 1
+      o = object[0]
+      if o.respond_to?(:to_hash)
+        h = self.new
+        object[0].to_hash.each { |k, v| h[k] = v }
+        return h
+      elsif o.respond_to?(:to_a)
+        h = self.new
+        o.to_a.each do |i|
+          raise ArgumentError, "wrong element type #{i.class} (expected array)" unless i.respond_to?(:to_a)
+          k, v = nil
+          case i.size
+          when 2
+            k = i[0]
+            v = i[1]
+          when 1
+            k = i[0]
+          else
+            raise ArgumentError, "invalid number of elements (#{i.size} for 1..2)"
+          end
+          h[k] = v
+        end
+        return h
+      end
+    end
+    unless length % 2 == 0
+      raise ArgumentError, 'odd number of arguments for Hash'
+    end
+    h = self.new
+    0.step(length - 2, 2) do |i|
+      h[object[i]] = object[i + 1]
+    end
+    h
+  end
+
+  ##
+  # call-seq:
+  #     Hash.try_convert(obj) -> hash or nil
+  #
+  # Try to convert <i>obj</i> into a hash, using to_hash method.
+  # Returns converted hash or nil if <i>obj</i> cannot be converted
+  # for any reason.
+  #
+  #     Hash.try_convert({1=>2})   # => {1=>2}
+  #     Hash.try_convert("1=>2")   # => nil
+  #
+  def self.try_convert(obj)
+    if obj.respond_to?(:to_hash)
+      obj.to_hash
+    else
+      nil
+    end
+  end
+
+  ##
+  # call-seq:
+  #     hsh.merge!(other_hash)                                 -> hsh
+  #     hsh.merge!(other_hash){|key, oldval, newval| block}    -> hsh
+  #
+  #  Adds the contents of _other_hash_ to _hsh_.  If no block is specified,
+  #  entries with duplicate keys are overwritten with the values from
+  #  _other_hash_, otherwise the value of each duplicate key is determined by
+  #  calling the block with the key, its value in _hsh_ and its value in
+  #  _other_hash_.
+  #
+  #     h1 = { "a" => 100, "b" => 200 }
+  #     h2 = { "b" => 254, "c" => 300 }
+  #     h1.merge!(h2)   #=> {"a"=>100, "b"=>254, "c"=>300}
+  #
+  #     h1 = { "a" => 100, "b" => 200 }
+  #     h2 = { "b" => 254, "c" => 300 }
+  #     h1.merge!(h2) { |key, v1, v2| v1 }
+  #                     #=> {"a"=>100, "b"=>200, "c"=>300}
+  #
+
+  def merge!(other, &block)
+    raise TypeError, "can't convert argument into Hash" unless other.respond_to?(:to_hash)
+    if block
+      other.each_key{|k|
+        self[k] = (self.has_key?(k))? block.call(k, self[k], other[k]): other[k]
+      }
+    else
+      other.each_key{|k| self[k] = other[k]}
+    end
+    self
+  end
+
+  alias update merge!
+
+  ##
+  #  call-seq:
+  #     hsh.fetch(key [, default] )       -> obj
+  #     hsh.fetch(key) {| key | block }   -> obj
+  #
+  #  Returns a value from the hash for the given key. If the key can't be
+  #  found, there are several options: With no other arguments, it will
+  #  raise an <code>KeyError</code> exception; if <i>default</i> is
+  #  given, then that will be returned; if the optional code block is
+  #  specified, then that will be run and its result returned.
+  #
+  #     h = { "a" => 100, "b" => 200 }
+  #     h.fetch("a")                            #=> 100
+  #     h.fetch("z", "go fish")                 #=> "go fish"
+  #     h.fetch("z") { |el| "go fish, #{el}"}   #=> "go fish, z"
+  #
+  #  The following example shows that an exception is raised if the key
+  #  is not found and a default value is not supplied.
+  #
+  #     h = { "a" => 100, "b" => 200 }
+  #     h.fetch("z")
+  #
+  #  <em>produces:</em>
+  #
+  #     prog.rb:2:in 'fetch': key not found (KeyError)
+  #      from prog.rb:2
+  #
+
+  def fetch(key, none=NONE, &block)
+    unless self.key?(key)
+      if block
+        block.call(key)
+      elsif none != NONE
+        none
+      else
+        raise KeyError, "Key not found: #{key}"
+      end
+    else
+      self[key]
+    end
+  end
+
+  ##
+  #  call-seq:
+  #     hsh.delete_if {| key, value | block }  -> hsh
+  #     hsh.delete_if                          -> an_enumerator
+  #
+  #  Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
+  #  evaluates to <code>true</code>.
+  #
+  #  If no block is given, an enumerator is returned instead.
+  #
+  #     h = { "a" => 100, "b" => 200, "c" => 300 }
+  #     h.delete_if {|key, value| key >= "b" }   #=> {"a"=>100}
+  #
+
+  def delete_if(&block)
+    return to_enum :delete_if unless block_given?
+
+    self.each do |k, v|
+      self.delete(k) if block.call(k, v)
+    end
+    self
+  end
+
+  ##
+  #  call-seq:
+  #     hash.flatten -> an_array
+  #     hash.flatten(level) -> an_array
+  #
+  #  Returns a new array that is a one-dimensional flattening of this
+  #  hash. That is, for every key or value that is an array, extract
+  #  its elements into the new array.  Unlike Array#flatten, this
+  #  method does not flatten recursively by default.  The optional
+  #  <i>level</i> argument determines the level of recursion to flatten.
+  #
+  #     a =  {1=> "one", 2 => [2,"two"], 3 => "three"}
+  #     a.flatten    # => [1, "one", 2, [2, "two"], 3, "three"]
+  #     a.flatten(2) # => [1, "one", 2, 2, "two", 3, "three"]
+  #
+
+  def flatten(level=1)
+    self.to_a.flatten(level)
+  end
+
+  ##
+  #  call-seq:
+  #     hsh.invert -> new_hash
+  #
+  #  Returns a new hash created by using <i>hsh</i>'s values as keys, and
+  #  the keys as values.
+  #
+  #     h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 }
+  #     h.invert   #=> {0=>"a", 100=>"m", 200=>"d", 300=>"y"}
+  #
+
+  def invert
+    h = self.class.new
+    self.each {|k, v| h[v] = k }
+    h
+  end
+
+  ##
+  #  call-seq:
+  #     hsh.keep_if {| key, value | block }  -> hsh
+  #     hsh.keep_if                          -> an_enumerator
+  #
+  #  Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
+  #  evaluates to false.
+  #
+  #  If no block is given, an enumerator is returned instead.
+  #
+
+  def keep_if(&block)
+    return to_enum :keep_if unless block_given?
+
+    keys = []
+    self.each do |k, v|
+      unless block.call([k, v])
+        self.delete(k)
+      end
+    end
+    self
+  end
+
+  ##
+  #  call-seq:
+  #     hsh.key(value)    -> key
+  #
+  #  Returns the key of an occurrence of a given value. If the value is
+  #  not found, returns <code>nil</code>.
+  #
+  #     h = { "a" => 100, "b" => 200, "c" => 300, "d" => 300 }
+  #     h.key(200)   #=> "b"
+  #     h.key(300)   #=> "c"
+  #     h.key(999)   #=> nil
+  #
+
+  def key(val)
+    self.each do |k, v|
+      return k if v == val
+    end
+    nil
+  end
+
+  ##
+  #  call-seq:
+  #     hsh.to_h     -> hsh or new_hash
+  #
+  #  Returns +self+. If called on a subclass of Hash, converts
+  #  the receiver to a Hash object.
+  #
+  def to_h
+    self
+  end
+
+  ##
+  #  call-seq:
+  #    hash < other -> true or false
+  #
+  #  Returns <code>true</code> if <i>hash</i> is subset of
+  #  <i>other</i>.
+  #
+  #     h1 = {a:1, b:2}
+  #     h2 = {a:1, b:2, c:3}
+  #     h1 < h2    #=> true
+  #     h2 < h1    #=> false
+  #     h1 < h1    #=> false
+  #
+  def <(hash)
+    begin
+      hash = hash.to_hash
+    rescue NoMethodError
+      raise TypeError, "can't convert #{hash.class} to Hash"
+    end
+    size < hash.size and all? {|key, val|
+      hash.key?(key) and hash[key] == val
+    }
+  end
+
+  ##
+  #  call-seq:
+  #    hash <= other -> true or false
+  #
+  #  Returns <code>true</code> if <i>hash</i> is subset of
+  #  <i>other</i> or equals to <i>other</i>.
+  #
+  #     h1 = {a:1, b:2}
+  #     h2 = {a:1, b:2, c:3}
+  #     h1 <= h2   #=> true
+  #     h2 <= h1   #=> false
+  #     h1 <= h1   #=> true
+  #
+  def <=(hash)
+    begin
+      hash = hash.to_hash
+    rescue NoMethodError
+      raise TypeError, "can't convert #{hash.class} to Hash"
+    end
+    size <= hash.size and all? {|key, val|
+      hash.key?(key) and hash[key] == val
+    }
+  end
+
+  ##
+  #  call-seq:
+  #    hash > other -> true or false
+  #
+  #  Returns <code>true</code> if <i>other</i> is subset of
+  #  <i>hash</i>.
+  #
+  #     h1 = {a:1, b:2}
+  #     h2 = {a:1, b:2, c:3}
+  #     h1 > h2    #=> false
+  #     h2 > h1    #=> true
+  #     h1 > h1    #=> false
+  #
+  def >(hash)
+    begin
+      hash = hash.to_hash
+    rescue NoMethodError
+      raise TypeError, "can't convert #{hash.class} to Hash"
+    end
+    size > hash.size and hash.all? {|key, val|
+      key?(key) and self[key] == val
+    }
+  end
+
+  ##
+  #  call-seq:
+  #    hash >= other -> true or false
+  #
+  #  Returns <code>true</code> if <i>other</i> is subset of
+  #  <i>hash</i> or equals to <i>hash</i>.
+  #
+  #     h1 = {a:1, b:2}
+  #     h2 = {a:1, b:2, c:3}
+  #     h1 >= h2   #=> false
+  #     h2 >= h1   #=> true
+  #     h1 >= h1   #=> true
+  #
+  def >=(hash)
+    begin
+      hash = hash.to_hash
+    rescue NoMethodError
+      raise TypeError, "can't convert #{hash.class} to Hash"
+    end
+    size >= hash.size and hash.all? {|key, val|
+      key?(key) and self[key] == val
+    }
+  end
+
+  ##
+  # call-seq:
+  #   hsh.dig(key,...)                 -> object
+  #
+  # Extracts the nested value specified by the sequence of <i>key</i>
+  # objects by calling +dig+ at each step, returning +nil+ if any
+  # intermediate step is +nil+.
+  #
+  def dig(idx,*args)
+    n = self[idx]
+    if args.size > 0
+      n&.dig(*args)
+    else
+      n
+    end
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-hash-ext/src/hash-ext.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-hash-ext/src/hash-ext.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-hash-ext/src/hash-ext.c	(revision 331)
@@ -0,0 +1,51 @@
+/*
+** hash.c - Hash class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/hash.h>
+
+/*
+ * call-seq:
+ *   hsh.values_at(key, ...)   -> array
+ *
+ * Return an array containing the values associated with the given keys.
+ * Also see <code>Hash.select</code>.
+ *
+ *   h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
+ *   h.values_at("cow", "cat")  #=> ["bovine", "feline"]
+ */
+
+static mrb_value
+hash_values_at(mrb_state *mrb, mrb_value hash)
+{
+  mrb_value *argv, result;
+  mrb_int argc, i;
+  int ai;
+
+  mrb_get_args(mrb, "*", &argv, &argc);
+  result = mrb_ary_new_capa(mrb, argc);
+  ai = mrb_gc_arena_save(mrb);
+  for (i = 0; i < argc; i++) {
+    mrb_ary_push(mrb, result, mrb_hash_get(mrb, hash, argv[i]));
+    mrb_gc_arena_restore(mrb, ai);
+  }
+  return result;
+}
+
+void
+mrb_mruby_hash_ext_gem_init(mrb_state *mrb)
+{
+  struct RClass *h;
+
+  h = mrb->hash_class;
+  mrb_define_method(mrb, h, "values_at", hash_values_at, MRB_ARGS_ANY());
+}
+
+void
+mrb_mruby_hash_ext_gem_final(mrb_state *mrb)
+{
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-hash-ext/test/hash.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-hash-ext/test/hash.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-hash-ext/test/hash.rb	(revision 331)
@@ -0,0 +1,256 @@
+##
+# Hash(Ext) Test
+
+assert('Hash.[] Hash') do
+  a = Hash['a_key' => 'a_value']
+
+  assert_equal({'a_key' => 'a_value'}, a)
+end
+
+assert('Hash.[] [ [ ["b_key", "b_value" ] ] ]') do
+  a = Hash[ [ ['b_key', 'b_value'] ] ]
+
+  assert_equal({'b_key' => 'b_value'}, a)
+
+  a = Hash[ [ ] ]
+
+  assert_equal({}, a)
+
+  assert_raise(ArgumentError) do
+    Hash[ [ ['b_key', 'b_value', 'b_over'] ] ]
+  end
+
+  assert_raise(ArgumentError) do
+    Hash[ [ [] ] ]
+  end
+end
+
+assert('Hash.[] "c_key", "c_value"') do
+  a = Hash['c_key', 'c_value', 'd_key', 1]
+
+  assert_equal({'c_key' => 'c_value', 'd_key' => 1}, a)
+
+  a = Hash[]
+
+  assert_equal({}, a)
+
+  assert_raise(ArgumentError) do
+    Hash['d_key']
+  end
+end
+
+assert('Hash.[] for sub class') do
+  sub_hash_class = Class.new(Hash)
+  sub_hash = sub_hash_class[]
+  assert_equal(sub_hash_class, sub_hash.class)
+end
+
+assert('Hash.try_convert') do
+  assert_nil Hash.try_convert(nil)
+  assert_nil Hash.try_convert("{1=>2}")
+  assert_equal({1=>2}, Hash.try_convert({1=>2}))
+end
+
+assert('Hash#merge!') do
+  a = { 'abc_key' => 'abc_value', 'cba_key' => 'cba_value' }
+  b = { 'cba_key' => 'XXX',  'xyz_key' => 'xyz_value' }
+
+  result_1 = a.merge! b
+
+  a = { 'abc_key' => 'abc_value', 'cba_key' => 'cba_value' }
+  result_2 = a.merge!(b) do |key, original, new|
+    original
+  end
+
+  assert_equal({'abc_key' => 'abc_value', 'cba_key' => 'XXX',
+               'xyz_key' => 'xyz_value' }, result_1)
+  assert_equal({'abc_key' => 'abc_value', 'cba_key' => 'cba_value',
+               'xyz_key' => 'xyz_value' }, result_2)
+
+  assert_raise(TypeError) do
+    { 'abc_key' => 'abc_value' }.merge! "a"
+  end
+end
+
+assert('Hash#values_at') do
+  h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
+  assert_equal ["bovine", "feline"], h.values_at("cow", "cat")
+
+  keys = []
+  (0...1000).each { |v| keys.push "#{v}" }
+  h = Hash.new { |hash,k| hash[k] = k }
+  assert_equal keys, h.values_at(*keys)
+end
+
+assert('Hash#fetch') do
+  h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
+  assert_equal "feline", h.fetch("cat")
+  assert_equal "mickey", h.fetch("mouse", "mickey")
+  assert_equal "minny", h.fetch("mouse"){"minny"}
+  assert_equal "mouse", h.fetch("mouse"){|k| k}
+  assert_raise(KeyError) do
+    h.fetch("gnu")
+  end
+end
+
+assert("Hash#delete_if") do
+  base = { 1 => 'one', 2 => false, true => 'true', 'cat' => 99 }
+  h1   = { 1 => 'one', 2 => false, true => 'true' }
+  h2   = { 2 => false, 'cat' => 99 }
+  h3   = { 2 => false }
+
+  h = base.dup
+  assert_equal(h, h.delete_if { false })
+  assert_equal({}, h.delete_if { true })
+
+  h = base.dup
+  assert_equal(h1, h.delete_if {|k,v| k.instance_of?(String) })
+  assert_equal(h1, h)
+
+  h = base.dup
+  assert_equal(h2, h.delete_if {|k,v| v.instance_of?(String) })
+  assert_equal(h2, h)
+
+  h = base.dup
+  assert_equal(h3, h.delete_if {|k,v| v })
+  assert_equal(h3, h)
+
+  h = base.dup
+  n = 0
+  h.delete_if {|*a|
+    n += 1
+    assert_equal(2, a.size)
+    assert_equal(base[a[0]], a[1])
+    h.shift
+    true
+  }
+  assert_equal(base.size, n)
+end
+
+assert("Hash#flatten") do
+  a =  {1=> "one", 2 => [2,"two"], 3 => [3, ["three"]]}
+  assert_equal [1, "one", 2, [2, "two"], 3, [3, ["three"]]], a.flatten
+  assert_equal [[1, "one"], [2, [2, "two"]], [3, [3, ["three"]]]], a.flatten(0)
+  assert_equal [1, "one", 2, [2, "two"], 3, [3, ["three"]]], a.flatten(1)
+  assert_equal [1, "one", 2, 2, "two", 3, 3, ["three"]], a.flatten(2)
+  assert_equal [1, "one", 2, 2, "two", 3, 3, "three"], a.flatten(3)
+end
+
+assert("Hash#invert") do
+  h = { 1 => 'one', 2 => 'two', 3 => 'three',
+        true => 'true', nil => 'nil' }.invert
+  assert_equal 1, h['one']
+  assert_equal true, h['true']
+  assert_equal nil, h['nil']
+
+  h = { 'a' => 1, 'b' => 2, 'c' => 1 }.invert
+  assert_equal(2, h.length)
+  assert_include(%w[a c], h[1])
+  assert_equal('b', h[2])
+end
+
+assert("Hash#invert with sub class") do
+  sub_hash_class = Class.new(Hash)
+  sub_hash = sub_hash_class.new
+  assert_equal(sub_hash_class, sub_hash.invert.class)
+end
+
+assert("Hash#keep_if") do
+  h = { 1 => 2, 3 => 4, 5 => 6 }
+  assert_equal({3=>4,5=>6}, h.keep_if {|k, v| k + v >= 7 })
+  h = { 1 => 2, 3 => 4, 5 => 6 }
+  assert_equal({ 1 => 2, 3=> 4, 5 =>6} , h.keep_if { true })
+end
+
+assert("Hash#key") do
+  h = { "a" => 100, "b" => 200, "c" => 300, "d" => 300, nil => 'nil', 'nil' => nil }
+  assert_equal "b", h.key(200)
+  assert_equal "c", h.key(300)
+  assert_nil h.key(999)
+  assert_nil h.key('nil')
+  assert_equal 'nil', h.key(nil)
+end
+
+assert("Hash#to_h") do
+  h = { "a" => 100, "b" => 200 }
+  assert_equal Hash, h.to_h.class
+  assert_equal h, h.to_h
+end
+
+assert('Hash#<') do
+  h1 = {a:1, b:2}
+  h2 = {a:1, b:2, c:3}
+
+  assert_false(h1 < h1)
+  assert_true(h1 < h2)
+  assert_false(h2 < h1)
+  assert_false(h2 < h2)
+
+  h1 = {a:1}
+  h2 = {a:2}
+
+  assert_false(h1 < h1)
+  assert_false(h1 < h2)
+  assert_false(h2 < h1)
+  assert_false(h2 < h2)
+end
+
+assert('Hash#<=') do
+  h1 = {a:1, b:2}
+  h2 = {a:1, b:2, c:3}
+
+  assert_true(h1 <= h1)
+  assert_true(h1 <= h2)
+  assert_false(h2 <= h1)
+  assert_true(h2 <= h2)
+
+  h1 = {a:1}
+  h2 = {a:2}
+
+  assert_true(h1 <= h1)
+  assert_false(h1 <= h2)
+  assert_false(h2 <= h1)
+  assert_true(h2 <= h2)
+end
+
+assert('Hash#>=') do
+  h1 = {a:1, b:2}
+  h2 = {a:1, b:2, c:3}
+
+  assert_true(h1 >= h1)
+  assert_false(h1 >= h2)
+  assert_true(h2 >= h1)
+  assert_true(h2 >= h2)
+
+  h1 = {a:1}
+  h2 = {a:2}
+
+  assert_true(h1 >= h1)
+  assert_false(h1 >= h2)
+  assert_false(h2 >= h1)
+  assert_true(h2 >= h2)
+end
+
+assert('Hash#>') do
+  h1 = {a:1, b:2}
+  h2 = {a:1, b:2, c:3}
+
+  assert_false(h1 > h1)
+  assert_false(h1 > h2)
+  assert_true(h2 > h1)
+  assert_false(h2 > h2)
+
+  h1 = {a:1}
+  h2 = {a:2}
+
+  assert_false(h1 > h1)
+  assert_false(h1 > h2)
+  assert_false(h2 > h1)
+  assert_false(h2 > h2)
+end
+
+assert("Hash#dig") do
+  h = {a:{b:{c:1}}}
+  assert_equal(1, h.dig(:a, :b, :c))
+  assert_nil(h.dig(:d))
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-inline-struct/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-inline-struct/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-inline-struct/mrbgem.rake	(revision 331)
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-inline-struct') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'inline structure'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-inline-struct/test/inline.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-inline-struct/test/inline.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-inline-struct/test/inline.c	(revision 331)
@@ -0,0 +1,83 @@
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/string.h>
+#include <mruby/istruct.h>
+
+static mrb_value
+istruct_test_initialize(mrb_state *mrb, mrb_value self)
+{
+  char *string = (char*)mrb_istruct_ptr(self);
+  mrb_int size = mrb_istruct_size();
+  mrb_value object;
+  mrb_get_args(mrb, "o", &object);
+
+  if (mrb_float_p(object))
+  {
+    snprintf(string, size, "float(%.3f)", mrb_float(object));
+  }
+  else if (mrb_fixnum_p(object))
+  {
+    snprintf(string, size, "fixnum(%" MRB_PRId ")", mrb_fixnum(object));
+  }
+  else if (mrb_string_p(object))
+  {
+    snprintf(string, size, "string(%s)", mrb_string_value_cstr(mrb, &object));
+  }
+
+  string[size - 1] = 0; // force NULL at the end
+  return self;
+}
+
+static mrb_value
+istruct_test_to_s(mrb_state *mrb, mrb_value self)
+{
+  return mrb_str_new_cstr(mrb, (const char*)mrb_istruct_ptr(self));
+}
+
+static mrb_value
+istruct_test_length(mrb_state *mrb, mrb_value self)
+{
+  return mrb_fixnum_value(mrb_istruct_size());
+}
+
+static mrb_value
+istruct_test_test_receive(mrb_state *mrb, mrb_value self)
+{
+  mrb_value object;
+  mrb_get_args(mrb, "o", &object);
+  if (mrb_obj_class(mrb, object) != mrb_class_get(mrb, "InlineStructTest"))
+  {
+    mrb_raisef(mrb, E_TYPE_ERROR, "Expected InlineStructTest");
+  }
+  return mrb_bool_value(((char*)mrb_istruct_ptr(object))[0] == 's');
+}
+
+static mrb_value
+istruct_test_test_receive_direct(mrb_state *mrb, mrb_value self)
+{
+  char *ptr;
+  mrb_get_args(mrb, "I", &ptr);
+  return mrb_bool_value(ptr[0] == 's');
+}
+
+static mrb_value
+istruct_test_mutate(mrb_state *mrb, mrb_value self)
+{
+  char *ptr = (char*)mrb_istruct_ptr(self);
+  memcpy(ptr, "mutate", 6);
+  return mrb_nil_value();
+}
+
+void mrb_mruby_inline_struct_gem_test(mrb_state *mrb)
+{
+  struct RClass *cls;
+
+  cls = mrb_define_class(mrb, "InlineStructTest", mrb->object_class);
+  MRB_SET_INSTANCE_TT(cls, MRB_TT_ISTRUCT);
+  mrb_define_method(mrb, cls, "initialize", istruct_test_initialize, MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, cls, "to_s", istruct_test_to_s, MRB_ARGS_NONE());
+  mrb_define_method(mrb, cls, "mutate", istruct_test_mutate, MRB_ARGS_NONE());
+  mrb_define_class_method(mrb, cls, "length", istruct_test_length, MRB_ARGS_NONE());
+  mrb_define_class_method(mrb, cls, "test_receive", istruct_test_test_receive, MRB_ARGS_REQ(1));
+  mrb_define_class_method(mrb, cls, "test_receive_direct", istruct_test_test_receive_direct, MRB_ARGS_REQ(1));
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-inline-struct/test/inline.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-inline-struct/test/inline.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-inline-struct/test/inline.rb	(revision 331)
@@ -0,0 +1,151 @@
+##
+# InlineStruct Test
+
+class InlineStructTest
+  def extra_method
+    :ok
+  end
+
+  def test_ivar_set
+    @var = :ivar
+  end
+
+  def test_ivar_get
+    @vat
+  end
+end
+
+assert('InlineStructTest#dup') do
+  obj = InlineStructTest.new(1)
+  assert_equal obj.to_s, 'fixnum(1)'
+  assert_equal obj.dup.to_s, 'fixnum(1)'
+end
+
+assert('InlineStructTest#clone') do
+  obj = InlineStructTest.new(1)
+  assert_equal obj.to_s, 'fixnum(1)'
+  assert_equal obj.clone.to_s, 'fixnum(1)'
+end
+
+assert('InlineStruct#object_id') do
+  obj1 = InlineStructTest.new(1)
+  obj2 = InlineStructTest.new(1)
+  assert_not_equal obj1, obj2
+  assert_not_equal obj1.object_id, obj2.object_id
+  assert_not_equal obj1.object_id, obj1.dup.object_id
+  assert_not_equal obj1.object_id, obj1.clone.object_id
+end
+
+assert('InlineStructTest#mutate (dup)') do
+  obj1 = InlineStructTest.new("foo")
+  assert_equal obj1.to_s, "string(foo)"
+  obj2 = obj1.dup
+  assert_equal obj2.to_s, "string(foo)"
+  obj1.mutate
+  assert_equal obj1.to_s, "mutate(foo)"
+  assert_equal obj2.to_s, "string(foo)"
+end
+
+assert('InlineStructTest#mutate (clone)') do
+  obj1 = InlineStructTest.new("foo")
+  assert_equal obj1.to_s, "string(foo)"
+  obj2 = obj1.clone
+  assert_equal obj2.to_s, "string(foo)"
+  obj1.mutate
+  assert_equal obj1.to_s, "mutate(foo)"
+  assert_equal obj2.to_s, "string(foo)"
+end
+
+assert('InlineStructTest#test_receive(string)') do
+  assert_equal InlineStructTest.test_receive(InlineStructTest.new('a')), true
+end
+
+assert('InlineStructTest#test_receive(float)') do
+  assert_equal InlineStructTest.test_receive(InlineStructTest.new(1.25)), false
+end
+
+assert('InlineStructTest#test_receive(invalid object)') do
+  assert_raise(TypeError) do
+    InlineStructTest.test_receive([])
+  end
+end
+
+assert('InlineStructTest#test_receive(string)') do
+  assert_equal InlineStructTest.test_receive_direct(InlineStructTest.new('a')), true
+end
+
+assert('InlineStructTest#test_receive(float)') do
+  assert_equal InlineStructTest.test_receive_direct(InlineStructTest.new(1.25)), false
+end
+
+assert('InlineStructTest#test_receive(invalid object)') do
+  assert_raise(TypeError) do
+    InlineStructTest.test_receive_direct([])
+  end
+end
+
+assert('InlineStructTest#extra_method') do
+  assert_equal InlineStructTest.new(1).extra_method, :ok
+end
+
+assert('InlineStructTest instance variable') do
+  obj = InlineStructTest.new(1)
+  assert_raise(ArgumentError) do
+    obj.test_ivar_set
+  end
+  assert_equal obj.test_ivar_get, nil
+end
+
+# 64-bit mode
+if InlineStructTest.length == 24
+  assert('InlineStructTest length [64 bit]') do
+    assert_equal InlineStructTest.length, 3 * 8
+  end
+
+  assert('InlineStructTest w/float [64 bit]') do
+    obj = InlineStructTest.new(1.25)
+    assert_equal obj.to_s, "float(1.250)"
+  end
+
+  assert('InlineStructTest w/fixnum [64 bit]') do
+    obj = InlineStructTest.new(42)
+    assert_equal obj.to_s, "fixnum(42)"
+  end
+
+  assert('InlineStructTest w/string [64 bit]') do
+    obj = InlineStructTest.new("hello")
+    assert_equal obj.to_s, "string(hello)"
+  end
+
+  assert('InlineStructTest w/long string [64 bit]') do
+    obj = InlineStructTest.new("this won't fit in 3 * 8 bytes available for the structure")
+    assert_equal obj.to_s, "string(this won't fit i"
+  end
+end
+
+# 32-bit mode
+if InlineStructTest.length == 12
+  assert('InlineStructTest length [32 bit]') do
+    assert_equal InlineStructTest.length, 3 * 4
+  end
+
+  assert('InlineStructTest w/float [32 bit]') do
+    obj = InlineStructTest.new(1.25)
+    assert_equal obj.to_s, "float(1.250"
+  end
+
+  assert('InlineStructTest w/fixnum [32 bit]') do
+    obj = InlineStructTest.new(42)
+    assert_equal obj.to_s, "fixnum(42)"
+  end
+
+  assert('InlineStructTest w/string [32 bit]') do
+    obj = InlineStructTest.new("hello")
+    assert_equal obj.to_s, "string(hell"
+  end
+
+  assert('InlineStructTest w/long string [32 bit]') do
+    obj = InlineStructTest.new("this won't fit in 3 * 4 bytes available for the structure")
+    assert_equal obj.to_s, "string(this"
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-kernel-ext/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-kernel-ext/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-kernel-ext/mrbgem.rake	(revision 331)
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-kernel-ext') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'Kernel module extension'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-kernel-ext/src/kernel.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-kernel-ext/src/kernel.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-kernel-ext/src/kernel.c	(revision 331)
@@ -0,0 +1,243 @@
+#include <mruby.h>
+#include <mruby/error.h>
+#include <mruby/array.h>
+#include <mruby/hash.h>
+#include <mruby/range.h>
+
+static mrb_value
+mrb_f_caller(mrb_state *mrb, mrb_value self)
+{
+  mrb_value bt, v, length;
+  mrb_int bt_len, argc, lev, n;
+
+  bt = mrb_get_backtrace(mrb);
+  bt_len = RARRAY_LEN(bt);
+  argc = mrb_get_args(mrb, "|oo", &v, &length);
+
+  switch (argc) {
+    case 0:
+      lev = 1;
+      n = bt_len - lev;
+      break;
+    case 1:
+      if (mrb_type(v) == MRB_TT_RANGE) {
+        mrb_int beg, len;
+        if (mrb_range_beg_len(mrb, v, &beg, &len, bt_len, TRUE) == 1) {
+          lev = beg;
+          n = len;
+        }
+        else {
+          return mrb_nil_value();
+        }
+      }
+      else {
+        v = mrb_to_int(mrb, v);
+        lev = mrb_fixnum(v);
+        if (lev < 0) {
+          mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%S)", v);
+        }
+        n = bt_len - lev;
+      }
+      break;
+    case 2:
+      lev = mrb_fixnum(mrb_to_int(mrb, v));
+      n = mrb_fixnum(mrb_to_int(mrb, length));
+      if (lev < 0) {
+        mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%S)", v);
+      }
+      if (n < 0) {
+        mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative size (%S)", length);
+      }
+      break;
+    default:
+      lev = n = 0;
+      break;
+  }
+
+  if (n == 0) {
+    return mrb_ary_new(mrb);
+  }
+
+  return mrb_funcall(mrb, bt, "[]", 2, mrb_fixnum_value(lev), mrb_fixnum_value(n));
+}
+
+/*
+ *  call-seq:
+ *     __method__         -> symbol
+ *
+ *  Returns the name at the definition of the current method as a
+ *  Symbol.
+ *  If called outside of a method, it returns <code>nil</code>.
+ *
+ */
+static mrb_value
+mrb_f_method(mrb_state *mrb, mrb_value self)
+{
+  mrb_callinfo *ci = mrb->c->ci;
+  ci--;
+  if (ci->mid)
+    return mrb_symbol_value(ci->mid);
+  else
+    return mrb_nil_value();
+}
+
+/*
+ *  call-seq:
+ *     Integer(arg,base=0)    -> integer
+ *
+ *  Converts <i>arg</i> to a <code>Fixnum</code>.
+ *  Numeric types are converted directly (with floating point numbers
+ *  being truncated).    <i>base</i> (0, or between 2 and 36) is a base for
+ *  integer string representation.  If <i>arg</i> is a <code>String</code>,
+ *  when <i>base</i> is omitted or equals to zero, radix indicators
+ *  (<code>0</code>, <code>0b</code>, and <code>0x</code>) are honored.
+ *  In any case, strings should be strictly conformed to numeric
+ *  representation. This behavior is different from that of
+ *  <code>String#to_i</code>.  Non string values will be converted using
+ *  <code>to_int</code>, and <code>to_i</code>. Passing <code>nil</code>
+ *  raises a TypeError.
+ *
+ *     Integer(123.999)    #=> 123
+ *     Integer("0x1a")     #=> 26
+ *     Integer(Time.new)   #=> 1204973019
+ *     Integer("0930", 10) #=> 930
+ *     Integer("111", 2)   #=> 7
+ *     Integer(nil)        #=> TypeError
+ */
+static mrb_value
+mrb_f_integer(mrb_state *mrb, mrb_value self)
+{
+  mrb_value arg;
+  mrb_int base = 0;
+
+  mrb_get_args(mrb, "o|i", &arg, &base);
+  return mrb_convert_to_integer(mrb, arg, base);
+}
+
+/*
+ *  call-seq:
+ *     Float(arg)    -> float
+ *
+ *  Returns <i>arg</i> converted to a float. Numeric types are converted
+ *  directly, the rest are converted using <i>arg</i>.to_f.
+ *
+ *     Float(1)           #=> 1.0
+ *     Float(123.456)     #=> 123.456
+ *     Float("123.456")   #=> 123.456
+ *     Float(nil)         #=> TypeError
+ */
+static mrb_value
+mrb_f_float(mrb_state *mrb, mrb_value self)
+{
+  mrb_value arg;
+
+  mrb_get_args(mrb, "o", &arg);
+  return mrb_Float(mrb, arg);
+}
+
+/*
+ *  call-seq:
+ *     String(arg)   -> string
+ *
+ *  Returns <i>arg</i> as an <code>String</code>.
+ *
+ *  First tries to call its <code>to_str</code> method, then its to_s method.
+ *
+ *     String(self)        #=> "main"
+ *     String(self.class)  #=> "Object"
+ *     String(123456)      #=> "123456"
+ */
+static mrb_value
+mrb_f_string(mrb_state *mrb, mrb_value self)
+{
+  mrb_value arg, tmp;
+
+  mrb_get_args(mrb, "o", &arg);
+  tmp = mrb_check_convert_type(mrb, arg, MRB_TT_STRING, "String", "to_str");
+  if (mrb_nil_p(tmp)) {
+    tmp = mrb_check_convert_type(mrb, arg, MRB_TT_STRING, "String", "to_s");
+  }
+  return tmp;
+}
+
+/*
+ *  call-seq:
+ *     Array(arg)    -> array
+ *
+ *  Returns +arg+ as an Array.
+ *
+ *  First tries to call Array#to_ary on +arg+, then Array#to_a.
+ *
+ *     Array(1..5)   #=> [1, 2, 3, 4, 5]
+ *
+ */
+static mrb_value
+mrb_f_array(mrb_state *mrb, mrb_value self)
+{
+  mrb_value arg, tmp;
+
+  mrb_get_args(mrb, "o", &arg);
+  tmp = mrb_check_convert_type(mrb, arg, MRB_TT_ARRAY, "Array", "to_ary");
+  if (mrb_nil_p(tmp)) {
+    tmp = mrb_check_convert_type(mrb, arg, MRB_TT_ARRAY, "Array", "to_a");
+  }
+  if (mrb_nil_p(tmp)) {
+    return mrb_ary_new_from_values(mrb, 1, &arg);
+  }
+
+  return tmp;
+}
+
+/*
+ *  call-seq:
+ *     Hash(arg)    -> hash
+ *
+ *  Converts <i>arg</i> to a <code>Hash</code> by calling
+ *  <i>arg</i><code>.to_hash</code>. Returns an empty <code>Hash</code> when
+ *  <i>arg</i> is <tt>nil</tt> or <tt>[]</tt>.
+ *
+ *      Hash([])          #=> {}
+ *      Hash(nil)         #=> {}
+ *      Hash(key: :value) #=> {:key => :value}
+ *      Hash([1, 2, 3])   #=> TypeError
+ *
+ */
+static mrb_value
+mrb_f_hash(mrb_state *mrb, mrb_value self)
+{
+  mrb_value arg, tmp;
+
+  mrb_get_args(mrb, "o", &arg);
+  if (mrb_nil_p(arg)) {
+    return mrb_hash_new(mrb);
+  }
+  tmp = mrb_check_convert_type(mrb, arg, MRB_TT_HASH, "Hash", "to_hash");
+  if (mrb_nil_p(tmp)) {
+    if (mrb_array_p(arg) && RARRAY_LEN(arg) == 0) {
+      return mrb_hash_new(mrb);
+    }
+    mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into Hash",
+      mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, arg)));
+  }
+  return tmp;
+}
+
+void
+mrb_mruby_kernel_ext_gem_init(mrb_state *mrb)
+{
+  struct RClass *krn = mrb->kernel_module;
+
+  mrb_define_module_function(mrb, krn, "fail", mrb_f_raise, MRB_ARGS_OPT(2));
+  mrb_define_module_function(mrb, krn, "caller", mrb_f_caller, MRB_ARGS_OPT(2));
+  mrb_define_method(mrb, krn, "__method__", mrb_f_method, MRB_ARGS_NONE());
+  mrb_define_module_function(mrb, krn, "Integer", mrb_f_integer, MRB_ARGS_ANY());
+  mrb_define_module_function(mrb, krn, "Float", mrb_f_float, MRB_ARGS_REQ(1));
+  mrb_define_module_function(mrb, krn, "String", mrb_f_string, MRB_ARGS_REQ(1));
+  mrb_define_module_function(mrb, krn, "Array", mrb_f_array, MRB_ARGS_REQ(1));
+  mrb_define_module_function(mrb, krn, "Hash", mrb_f_hash, MRB_ARGS_REQ(1));
+}
+
+void
+mrb_mruby_kernel_ext_gem_final(mrb_state *mrb)
+{
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-kernel-ext/test/kernel.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-kernel-ext/test/kernel.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-kernel-ext/test/kernel.rb	(revision 331)
@@ -0,0 +1,86 @@
+assert('Kernel.fail, Kernel#fail') do
+  assert_raise(RuntimeError) { fail }
+  assert_raise(RuntimeError) { Kernel.fail }
+end
+
+assert('Kernel.caller, Kernel#caller') do
+  skip "backtrace isn't available" if caller(0).empty?
+
+  caller_lineno = __LINE__ + 3
+  c = Class.new do
+    def foo(*args)
+      caller(*args)
+    end
+
+    def bar(*args)
+      foo(*args)
+    end
+
+    def baz(*args)
+      bar(*args)
+    end
+  end
+  assert_equal "kernel.rb:#{caller_lineno}:in foo", c.new.baz(0)[0][-19..-1]
+  assert_equal "bar", c.new.baz[0][-3..-1]
+  assert_equal "foo", c.new.baz(0)[0][-3..-1]
+  assert_equal "bar", c.new.baz(1)[0][-3..-1]
+  assert_equal "baz", c.new.baz(2)[0][-3..-1]
+  assert_equal ["foo", "bar"], c.new.baz(0, 2).map { |i| i[-3..-1] }
+  assert_equal ["bar", "baz"], c.new.baz(1..2).map { |i| i[-3..-1] }
+  assert_nil c.new.baz(10..20)
+  assert_raise(ArgumentError) { c.new.baz(-1) }
+  assert_raise(ArgumentError) { c.new.baz(-1, 1) }
+  assert_raise(ArgumentError) { c.new.baz(1, -1) }
+  assert_raise(TypeError) { c.new.baz(nil) }
+end
+
+assert('Kernel#__method__') do
+  assert_equal(:m, Class.new {def m; __method__; end}.new.m)
+  assert_equal(:m, Class.new {define_method(:m) {__method__}}.new.m)
+  c = Class.new do
+    [:m1, :m2].each do |m|
+      define_method(m) do
+        __method__
+      end
+    end
+  end
+  assert_equal(:m1, c.new.m1)
+  assert_equal(:m2, c.new.m2)
+end
+
+assert('Kernel#Integer') do
+  assert_equal(123, Integer(123.999))
+  assert_equal(26, Integer("0x1a"))
+  assert_equal(930, Integer("0930", 10))
+  assert_equal(7, Integer("111", 2))
+  assert_equal(0, Integer("0"))
+  assert_equal(0, Integer("00000"))
+  assert_raise(TypeError) { Integer(nil) }
+end
+
+assert('Kernel#Float') do
+  assert_equal(1.0, Float(1))
+  assert_equal(123.456, Float(123.456))
+  assert_equal(123.456, Float("123.456"))
+  assert_raise(TypeError) { Float(nil) }
+end
+
+assert('Kernel#String') do
+  assert_equal("main", String(self))
+  assert_equal("Object", String(self.class))
+  assert_equal("123456", String(123456))
+end
+
+assert('Kernel#Array') do
+  assert_equal([1], Kernel.Array(1))
+  assert_equal([1, 2, 3, 4, 5], Kernel.Array([1, 2, 3, 4, 5]))
+  assert_equal([1, 2, 3, 4, 5], Kernel.Array(1..5))
+  assert_equal([[:a, 1], [:b, 2], [:c, 3]], Kernel.Array({a:1, b:2, c:3}))
+end
+
+assert('Kernel#Hash') do
+  assert_equal({}, Hash([]))
+  assert_equal({}, Hash(nil))
+  assert_equal({:key => :value}, Hash(key: :value))
+  assert_raise(TypeError) { Hash([1, 2, 3]) }
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-math/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-math/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-math/mrbgem.rake	(revision 331)
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-math') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'standard Math module'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-math/src/math.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-math/src/math.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-math/src/math.c	(revision 331)
@@ -0,0 +1,783 @@
+/*
+** math.c - Math module
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <mruby.h>
+#include <mruby/array.h>
+
+#include <math.h>
+
+static void
+domain_error(mrb_state *mrb, const char *func)
+{
+  struct RClass *math = mrb_module_get(mrb, "Math");
+  struct RClass *domainerror = mrb_class_get_under(mrb, math, "DomainError");
+  mrb_value str = mrb_str_new_cstr(mrb, func);
+  mrb_raisef(mrb, domainerror, "Numerical argument is out of domain - %S", str);
+}
+
+/* math functions not provided by Microsoft Visual C++ 2012 or older */
+#if defined _MSC_VER && _MSC_VER <= 1700
+
+#include <float.h>
+
+#define MATH_TOLERANCE 1E-12
+
+double
+asinh(double x)
+{
+  double xa, ya, y;
+
+  /* Basic formula loses precision for x < 0, but asinh is an odd function */
+  xa = fabs(x);
+  if (xa > 3.16227E+18) {
+    /* Prevent x*x from overflowing; basic formula reduces to log(2*x) */
+    ya = log(xa) + 0.69314718055994530942;
+  }
+  else {
+    /* Basic formula for asinh */
+    ya = log(xa + sqrt(xa*xa + 1.0));
+  }
+
+  y = _copysign(ya, x);
+  return y;
+}
+
+double
+acosh(double x)
+{
+  double y;
+
+  if (x > 3.16227E+18) {
+    /* Prevent x*x from overflowing; basic formula reduces to log(2*x) */
+    y = log(x) + 0.69314718055994530942;
+  }
+  else {
+    /* Basic formula for acosh */
+    y = log(x + sqrt(x*x - 1.0));
+  }
+
+  return y;
+}
+
+double
+atanh(double x)
+{
+  double y;
+
+  if (fabs(x) < 1E-2) {
+    /* The sums 1+x and 1-x lose precision for small x.  Use the polynomial
+       instead. */
+    double x2 = x * x;
+    y = x*(1.0 + x2*(1.0/3.0 + x2*(1.0/5.0 + x2*(1.0/7.0))));
+  }
+  else {
+    /* Basic formula for atanh */
+    y = 0.5 * (log(1.0+x) - log(1.0-x));
+  }
+
+  return y;
+}
+
+double
+cbrt(double x)
+{
+  double xa, ya, y;
+
+  /* pow(x, y) is undefined for x < 0 and y not an integer, but cbrt is an
+     odd function */
+  xa = fabs(x);
+  ya = pow(xa, 1.0/3.0);
+  y = _copysign(ya, x);
+  return y;
+}
+
+/* Declaration of complementary Error function */
+double
+erfc(double x);
+
+/*
+** Implementations of error functions
+** credits to http://www.digitalmars.com/archives/cplusplus/3634.html
+*/
+
+/* Implementation of Error function */
+double
+erf(double x)
+{
+  static const double two_sqrtpi =  1.128379167095512574;
+  double sum  = x;
+  double term = x;
+  double xsqr = x*x;
+  int j= 1;
+  if (fabs(x) > 2.2) {
+    return 1.0 - erfc(x);
+  }
+  do {
+    term *= xsqr/j;
+    sum  -= term/(2*j+1);
+    ++j;
+    term *= xsqr/j;
+    sum  += term/(2*j+1);
+    ++j;
+  } while (fabs(term/sum) > MATH_TOLERANCE);
+  return two_sqrtpi*sum;
+}
+
+/* Implementation of complementary Error function */
+double
+erfc(double x)
+{
+  static const double one_sqrtpi=  0.564189583547756287;
+  double a = 1;
+  double b = x;
+  double c = x;
+  double d = x*x+0.5;
+  double q1;
+  double q2 = b/d;
+  double n = 1.0;
+  double t;
+  if (fabs(x) < 2.2) {
+    return 1.0 - erf(x);
+  }
+  if (x < 0.0) { /*signbit(x)*/
+    return 2.0 - erfc(-x);
+  }
+  do {
+    t  = a*n+b*x;
+    a  = b;
+    b  = t;
+    t  = c*n+d*x;
+    c  = d;
+    d  = t;
+    n += 0.5;
+    q1 = q2;
+    q2 = b/d;
+  } while (fabs(q1-q2)/q2 > MATH_TOLERANCE);
+  return one_sqrtpi*exp(-x*x)*q2;
+}
+
+#endif
+
+#if (defined _MSC_VER && _MSC_VER < 1800) || defined __ANDROID__ || (defined __FreeBSD__  &&  __FreeBSD_version < 803000)
+
+double
+log2(double x)
+{
+    return log10(x)/log10(2.0);
+}
+
+#endif
+
+/*
+  TRIGONOMETRIC FUNCTIONS
+*/
+
+/*
+ *  call-seq:
+ *     Math.sin(x)    -> float
+ *
+ *  Computes the sine of <i>x</i> (expressed in radians). Returns
+ *  -1..1.
+ */
+static mrb_value
+math_sin(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+
+  mrb_get_args(mrb, "f", &x);
+  x = sin(x);
+
+  return mrb_float_value(mrb, x);
+}
+
+/*
+ *  call-seq:
+ *     Math.cos(x)    -> float
+ *
+ *  Computes the cosine of <i>x</i> (expressed in radians). Returns
+ *  -1..1.
+ */
+static mrb_value
+math_cos(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+
+  mrb_get_args(mrb, "f", &x);
+  x = cos(x);
+
+  return mrb_float_value(mrb, x);
+}
+
+/*
+ *  call-seq:
+ *     Math.tan(x)    -> float
+ *
+ *  Returns the tangent of <i>x</i> (expressed in radians).
+ */
+static mrb_value
+math_tan(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+
+  mrb_get_args(mrb, "f", &x);
+  x = tan(x);
+
+  return mrb_float_value(mrb, x);
+}
+
+/*
+  INVERSE TRIGONOMETRIC FUNCTIONS
+*/
+
+/*
+ *  call-seq:
+ *     Math.asin(x)    -> float
+ *
+ *  Computes the arc sine of <i>x</i>.
+ *  @return computed value between `-(PI/2)` and `(PI/2)`.
+ */
+static mrb_value
+math_asin(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+
+  mrb_get_args(mrb, "f", &x);
+  if (x < -1.0 || x > 1.0) {
+    domain_error(mrb, "asin");
+  }
+  x = asin(x);
+
+  return mrb_float_value(mrb, x);
+}
+
+/*
+ *  call-seq:
+ *     Math.acos(x)    -> float
+ *
+ *  Computes the arc cosine of <i>x</i>. Returns 0..PI.
+ */
+static mrb_value
+math_acos(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+
+  mrb_get_args(mrb, "f", &x);
+  if (x < -1.0 || x > 1.0) {
+    domain_error(mrb, "acos");
+  }
+  x = acos(x);
+
+  return mrb_float_value(mrb, x);
+}
+
+/*
+ *  call-seq:
+ *     Math.atan(x)    -> float
+ *
+ *  Computes the arc tangent of <i>x</i>. Returns `-(PI/2) .. (PI/2)`.
+ */
+static mrb_value
+math_atan(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+
+  mrb_get_args(mrb, "f", &x);
+  x = atan(x);
+
+  return mrb_float_value(mrb, x);
+}
+
+/*
+ *  call-seq:
+ *     Math.atan2(y, x)  -> float
+ *
+ *  Computes the arc tangent given <i>y</i> and <i>x</i>. Returns
+ *  -PI..PI.
+ *
+ *    Math.atan2(-0.0, -1.0) #=> -3.141592653589793
+ *    Math.atan2(-1.0, -1.0) #=> -2.356194490192345
+ *    Math.atan2(-1.0, 0.0)  #=> -1.5707963267948966
+ *    Math.atan2(-1.0, 1.0)  #=> -0.7853981633974483
+ *    Math.atan2(-0.0, 1.0)  #=> -0.0
+ *    Math.atan2(0.0, 1.0)   #=> 0.0
+ *    Math.atan2(1.0, 1.0)   #=> 0.7853981633974483
+ *    Math.atan2(1.0, 0.0)   #=> 1.5707963267948966
+ *    Math.atan2(1.0, -1.0)  #=> 2.356194490192345
+ *    Math.atan2(0.0, -1.0)  #=> 3.141592653589793
+ *
+ */
+static mrb_value
+math_atan2(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x, y;
+
+  mrb_get_args(mrb, "ff", &x, &y);
+  x = atan2(x, y);
+
+  return mrb_float_value(mrb, x);
+}
+
+
+
+/*
+  HYPERBOLIC TRIG FUNCTIONS
+*/
+/*
+ *  call-seq:
+ *     Math.sinh(x)    -> float
+ *
+ *  Computes the hyperbolic sine of <i>x</i> (expressed in
+ *  radians).
+ */
+static mrb_value
+math_sinh(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+
+  mrb_get_args(mrb, "f", &x);
+  x = sinh(x);
+
+  return mrb_float_value(mrb, x);
+}
+
+/*
+ *  call-seq:
+ *     Math.cosh(x)    -> float
+ *
+ *  Computes the hyperbolic cosine of <i>x</i> (expressed in radians).
+ */
+static mrb_value
+math_cosh(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+
+  mrb_get_args(mrb, "f", &x);
+  x = cosh(x);
+
+  return mrb_float_value(mrb, x);
+}
+
+/*
+ *  call-seq:
+ *     Math.tanh()    -> float
+ *
+ *  Computes the hyperbolic tangent of <i>x</i> (expressed in
+ *  radians).
+ */
+static mrb_value
+math_tanh(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+
+  mrb_get_args(mrb, "f", &x);
+  x = tanh(x);
+
+  return mrb_float_value(mrb, x);
+}
+
+
+/*
+  INVERSE HYPERBOLIC TRIG FUNCTIONS
+*/
+
+/*
+ *  call-seq:
+ *     Math.asinh(x)    -> float
+ *
+ *  Computes the inverse hyperbolic sine of <i>x</i>.
+ */
+static mrb_value
+math_asinh(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+
+  mrb_get_args(mrb, "f", &x);
+
+  x = asinh(x);
+
+  return mrb_float_value(mrb, x);
+}
+
+/*
+ *  call-seq:
+ *     Math.acosh(x)    -> float
+ *
+ *  Computes the inverse hyperbolic cosine of <i>x</i>.
+ */
+static mrb_value
+math_acosh(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+
+  mrb_get_args(mrb, "f", &x);
+  if (x < 1.0) {
+    domain_error(mrb, "acosh");
+  }
+  x = acosh(x);
+
+  return mrb_float_value(mrb, x);
+}
+
+/*
+ *  call-seq:
+ *     Math.atanh(x)    -> float
+ *
+ *  Computes the inverse hyperbolic tangent of <i>x</i>.
+ */
+static mrb_value
+math_atanh(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+
+  mrb_get_args(mrb, "f", &x);
+  if (x < -1.0 || x > 1.0) {
+    domain_error(mrb, "atanh");
+  }
+  x = atanh(x);
+
+  return mrb_float_value(mrb, x);
+}
+
+/*
+  EXPONENTIALS AND LOGARITHMS
+*/
+
+/*
+ *  call-seq:
+ *     Math.exp(x)    -> float
+ *
+ *  Returns e**x.
+ *
+ *    Math.exp(0)       #=> 1.0
+ *    Math.exp(1)       #=> 2.718281828459045
+ *    Math.exp(1.5)     #=> 4.4816890703380645
+ *
+ */
+static mrb_value
+math_exp(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+
+  mrb_get_args(mrb, "f", &x);
+  x = exp(x);
+
+  return mrb_float_value(mrb, x);
+}
+
+/*
+ *  call-seq:
+ *     Math.log(numeric)    -> float
+ *     Math.log(num,base)   -> float
+ *
+ *  Returns the natural logarithm of <i>numeric</i>.
+ *  If additional second argument is given, it will be the base
+ *  of logarithm.
+ *
+ *    Math.log(1)          #=> 0.0
+ *    Math.log(Math::E)    #=> 1.0
+ *    Math.log(Math::E**3) #=> 3.0
+ *    Math.log(12,3)       #=> 2.2618595071429146
+ *
+ */
+static mrb_value
+math_log(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x, base;
+  int argc;
+
+  argc = mrb_get_args(mrb, "f|f", &x, &base);
+  if (x < 0.0) {
+    domain_error(mrb, "log");
+  }
+  x = log(x);
+  if (argc == 2) {
+    if (base < 0.0) {
+      domain_error(mrb, "log");
+    }
+    x /= log(base);
+  }
+  return mrb_float_value(mrb, x);
+}
+
+/*
+ *  call-seq:
+ *     Math.log2(numeric)    -> float
+ *
+ *  Returns the base 2 logarithm of <i>numeric</i>.
+ *
+ *    Math.log2(1)      #=> 0.0
+ *    Math.log2(2)      #=> 1.0
+ *    Math.log2(32768)  #=> 15.0
+ *    Math.log2(65536)  #=> 16.0
+ *
+ */
+static mrb_value
+math_log2(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+
+  mrb_get_args(mrb, "f", &x);
+  if (x < 0.0) {
+    domain_error(mrb, "log2");
+  }
+  x = log2(x);
+
+  return mrb_float_value(mrb, x);
+}
+
+/*
+ *  call-seq:
+ *     Math.log10(numeric)    -> float
+ *
+ *  Returns the base 10 logarithm of <i>numeric</i>.
+ *
+ *    Math.log10(1)       #=> 0.0
+ *    Math.log10(10)      #=> 1.0
+ *    Math.log10(10**100) #=> 100.0
+ *
+ */
+static mrb_value
+math_log10(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+
+  mrb_get_args(mrb, "f", &x);
+  if (x < 0.0) {
+    domain_error(mrb, "log10");
+  }
+  x = log10(x);
+
+  return mrb_float_value(mrb, x);
+}
+
+/*
+ *  call-seq:
+ *     Math.sqrt(numeric)    -> float
+ *
+ *  Returns the square root of <i>numeric</i>.
+ *
+ */
+static mrb_value
+math_sqrt(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+
+  mrb_get_args(mrb, "f", &x);
+  if (x < 0.0) {
+    domain_error(mrb, "sqrt");
+  }
+  x = sqrt(x);
+
+  return mrb_float_value(mrb, x);
+}
+
+
+/*
+ *  call-seq:
+ *     Math.cbrt(numeric)    -> float
+ *
+ *  Returns the cube root of <i>numeric</i>.
+ *
+ *    -9.upto(9) {|x|
+ *      p [x, Math.cbrt(x), Math.cbrt(x)**3]
+ *    }
+ *    #=>
+ *    [-9, -2.0800838230519, -9.0]
+ *    [-8, -2.0, -8.0]
+ *    [-7, -1.91293118277239, -7.0]
+ *    [-6, -1.81712059283214, -6.0]
+ *    [-5, -1.7099759466767, -5.0]
+ *    [-4, -1.5874010519682, -4.0]
+ *    [-3, -1.44224957030741, -3.0]
+ *    [-2, -1.25992104989487, -2.0]
+ *    [-1, -1.0, -1.0]
+ *    [0, 0.0, 0.0]
+ *    [1, 1.0, 1.0]
+ *    [2, 1.25992104989487, 2.0]
+ *    [3, 1.44224957030741, 3.0]
+ *    [4, 1.5874010519682, 4.0]
+ *    [5, 1.7099759466767, 5.0]
+ *    [6, 1.81712059283214, 6.0]
+ *    [7, 1.91293118277239, 7.0]
+ *    [8, 2.0, 8.0]
+ *    [9, 2.0800838230519, 9.0]
+ *
+ */
+static mrb_value
+math_cbrt(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+
+  mrb_get_args(mrb, "f", &x);
+  x = cbrt(x);
+
+  return mrb_float_value(mrb, x);
+}
+
+
+/*
+ *  call-seq:
+ *     Math.frexp(numeric)    -> [ fraction, exponent ]
+ *
+ *  Returns a two-element array containing the normalized fraction (a
+ *  <code>Float</code>) and exponent (a <code>Fixnum</code>) of
+ *  <i>numeric</i>.
+ *
+ *     fraction, exponent = Math.frexp(1234)   #=> [0.6025390625, 11]
+ *     fraction * 2**exponent                  #=> 1234.0
+ */
+static mrb_value
+math_frexp(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+  int exp;
+
+  mrb_get_args(mrb, "f", &x);
+  x = frexp(x, &exp);
+
+  return mrb_assoc_new(mrb, mrb_float_value(mrb, x), mrb_fixnum_value(exp));
+}
+
+/*
+ *  call-seq:
+ *     Math.ldexp(flt, int) -> float
+ *
+ *  Returns the value of <i>flt</i>*(2**<i>int</i>).
+ *
+ *     fraction, exponent = Math.frexp(1234)
+ *     Math.ldexp(fraction, exponent)   #=> 1234.0
+ */
+static mrb_value
+math_ldexp(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+  mrb_int   i;
+
+  mrb_get_args(mrb, "fi", &x, &i);
+  x = ldexp(x, i);
+
+  return mrb_float_value(mrb, x);
+}
+
+/*
+ *  call-seq:
+ *     Math.hypot(x, y)    -> float
+ *
+ *  Returns sqrt(x**2 + y**2), the hypotenuse of a right-angled triangle
+ *  with sides <i>x</i> and <i>y</i>.
+ *
+ *     Math.hypot(3, 4)   #=> 5.0
+ */
+static mrb_value
+math_hypot(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x, y;
+
+  mrb_get_args(mrb, "ff", &x, &y);
+  x = hypot(x, y);
+
+  return mrb_float_value(mrb, x);
+}
+
+/*
+ * call-seq:
+ *    Math.erf(x)  -> float
+ *
+ *  Calculates the error function of x.
+ */
+static mrb_value
+math_erf(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+
+  mrb_get_args(mrb, "f", &x);
+  x = erf(x);
+
+  return mrb_float_value(mrb, x);
+}
+
+
+/*
+ * call-seq:
+ *    Math.erfc(x)  -> float
+ *
+ *  Calculates the complementary error function of x.
+ */
+static mrb_value
+math_erfc(mrb_state *mrb, mrb_value obj)
+{
+  mrb_float x;
+
+  mrb_get_args(mrb, "f", &x);
+  x = erfc(x);
+
+  return mrb_float_value(mrb, x);
+}
+
+/* ------------------------------------------------------------------------*/
+void
+mrb_mruby_math_gem_init(mrb_state* mrb)
+{
+  struct RClass *mrb_math;
+  mrb_math = mrb_define_module(mrb, "Math");
+
+  mrb_define_class_under(mrb, mrb_math, "DomainError", mrb->eStandardError_class);
+
+#ifdef M_PI
+  mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(mrb, M_PI));
+#else
+  mrb_define_const(mrb, mrb_math, "PI", mrb_float_value(mrb, atan(1.0)*4.0));
+#endif
+
+#ifdef M_E
+  mrb_define_const(mrb, mrb_math, "E", mrb_float_value(mrb, M_E));
+#else
+  mrb_define_const(mrb, mrb_math, "E", mrb_float_value(mrb, exp(1.0)));
+#endif
+
+#ifdef MRB_USE_FLOAT
+  mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(mrb, 1e-5));
+#else
+  mrb_define_const(mrb, mrb_math, "TOLERANCE", mrb_float_value(mrb, 1e-12));
+#endif
+
+  mrb_define_module_function(mrb, mrb_math, "sin", math_sin, MRB_ARGS_REQ(1));
+  mrb_define_module_function(mrb, mrb_math, "cos", math_cos, MRB_ARGS_REQ(1));
+  mrb_define_module_function(mrb, mrb_math, "tan", math_tan, MRB_ARGS_REQ(1));
+
+  mrb_define_module_function(mrb, mrb_math, "asin", math_asin, MRB_ARGS_REQ(1));
+  mrb_define_module_function(mrb, mrb_math, "acos", math_acos, MRB_ARGS_REQ(1));
+  mrb_define_module_function(mrb, mrb_math, "atan", math_atan, MRB_ARGS_REQ(1));
+  mrb_define_module_function(mrb, mrb_math, "atan2", math_atan2, MRB_ARGS_REQ(2));
+
+  mrb_define_module_function(mrb, mrb_math, "sinh", math_sinh, MRB_ARGS_REQ(1));
+  mrb_define_module_function(mrb, mrb_math, "cosh", math_cosh, MRB_ARGS_REQ(1));
+  mrb_define_module_function(mrb, mrb_math, "tanh", math_tanh, MRB_ARGS_REQ(1));
+
+  mrb_define_module_function(mrb, mrb_math, "asinh", math_asinh, MRB_ARGS_REQ(1));
+  mrb_define_module_function(mrb, mrb_math, "acosh", math_acosh, MRB_ARGS_REQ(1));
+  mrb_define_module_function(mrb, mrb_math, "atanh", math_atanh, MRB_ARGS_REQ(1));
+
+  mrb_define_module_function(mrb, mrb_math, "exp", math_exp, MRB_ARGS_REQ(1));
+  mrb_define_module_function(mrb, mrb_math, "log", math_log, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1));
+  mrb_define_module_function(mrb, mrb_math, "log2", math_log2, MRB_ARGS_REQ(1));
+  mrb_define_module_function(mrb, mrb_math, "log10", math_log10, MRB_ARGS_REQ(1));
+  mrb_define_module_function(mrb, mrb_math, "sqrt", math_sqrt, MRB_ARGS_REQ(1));
+  mrb_define_module_function(mrb, mrb_math, "cbrt", math_cbrt, MRB_ARGS_REQ(1));
+
+  mrb_define_module_function(mrb, mrb_math, "frexp", math_frexp, MRB_ARGS_REQ(1));
+  mrb_define_module_function(mrb, mrb_math, "ldexp", math_ldexp, MRB_ARGS_REQ(2));
+
+  mrb_define_module_function(mrb, mrb_math, "hypot", math_hypot, MRB_ARGS_REQ(2));
+
+  mrb_define_module_function(mrb, mrb_math, "erf",  math_erf,  MRB_ARGS_REQ(1));
+  mrb_define_module_function(mrb, mrb_math, "erfc", math_erfc, MRB_ARGS_REQ(1));
+}
+
+void
+mrb_mruby_math_gem_final(mrb_state* mrb)
+{
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-math/test/math.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-math/test/math.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-math/test/math.rb	(revision 331)
@@ -0,0 +1,152 @@
+##
+# Math Test
+
+##
+# Performs fuzzy check for equality on methods returning floats
+# on the basis of the Math::TOLERANCE constant.
+def check_float(a, b)
+  tolerance = Math::TOLERANCE
+  a = a.to_f
+  b = b.to_f
+  if a.finite? and b.finite?
+    (a-b).abs < tolerance
+  else
+    true
+  end
+end
+
+assert('Math.sin 0') do
+  check_float(Math.sin(0), 0)
+end
+
+assert('Math.sin PI/2') do
+  check_float(Math.sin(Math::PI / 2), 1)
+end
+
+assert('Math.cos 0') do
+  check_float(Math.cos(0), 1)
+end
+
+assert('Math.cos PI/2') do
+  check_float(Math.cos(Math::PI / 2), 0)
+end
+
+assert('Math.tan 0') do
+  check_float(Math.tan(0), 0)
+end
+
+assert('Math.tan PI/4') do
+  check_float(Math.tan(Math::PI / 4), 1)
+end
+
+assert('Fundamental trig identities') do
+  result = true
+  N = 13
+  N.times do |i|
+    a  = Math::PI / N * i
+    ca = Math::PI / 2 - a
+    s  = Math.sin(a)
+    c  = Math.cos(a)
+    t  = Math.tan(a)
+    result &= check_float(s, Math.cos(ca))
+    result &= check_float(t, 1 / Math.tan(ca))
+    result &= check_float(s ** 2 + c ** 2, 1)
+    result &= check_float(t ** 2 + 1, (1/c) ** 2)
+    result &= check_float((1/t) ** 2 + 1, (1/s) ** 2)
+  end
+  result
+end
+
+assert('Math.erf 0') do
+  check_float(Math.erf(0), 0)
+end
+
+assert('Math.exp 0') do
+  check_float(Math.exp(0), 1.0)
+end
+
+assert('Math.exp 1') do
+  check_float(Math.exp(1), 2.718281828459045)
+end
+
+assert('Math.exp 1.5') do
+  check_float(Math.exp(1.5), 4.4816890703380645)
+end
+
+assert('Math.log 1') do
+  check_float(Math.log(1), 0)
+end
+
+assert('Math.log E') do
+  check_float(Math.log(Math::E), 1.0)
+end
+
+assert('Math.log E**3') do
+  check_float(Math.log(Math::E**3), 3.0)
+end
+
+assert('Math.log2 1') do
+  check_float(Math.log2(1), 0.0)
+end
+
+assert('Math.log2 2') do
+  check_float(Math.log2(2), 1.0)
+end
+
+assert('Math.log10 1') do
+  check_float(Math.log10(1), 0.0)
+end
+
+assert('Math.log10 10') do
+  check_float(Math.log10(10), 1.0)
+end
+
+assert('Math.log10 10**100') do
+  check_float(Math.log10(10**100), 100.0)
+end
+
+assert('Math.sqrt') do
+  num = [0.0, 1.0, 2.0, 3.0, 4.0]
+  sqr = [0, 1, 4, 9, 16]
+  result = true
+  sqr.each_with_index do |v,i|
+    result &= check_float(Math.sqrt(v), num[i])
+  end
+  result
+end
+
+assert('Math.cbrt') do
+  num = [-2.0, -1.0, 0.0, 1.0, 2.0]
+  cub = [-8, -1, 0, 1, 8]
+  result = true
+  cub.each_with_index do |v,i|
+    result &= check_float(Math.cbrt(v), num[i])
+  end
+  result
+end
+
+assert('Math.hypot') do
+  check_float(Math.hypot(3, 4), 5.0)
+end
+
+assert('Math.frexp 1234') do
+  n = 1234
+  fraction, exponent = Math.frexp(n)
+  check_float(Math.ldexp(fraction, exponent), n)
+end
+
+assert('Math.erf 1') do
+  check_float(Math.erf(1), 0.842700792949715)
+end
+
+assert('Math.erfc 1') do
+  check_float(Math.erfc(1), 0.157299207050285)
+end
+
+assert('Math.erf -1') do
+  check_float(Math.erf(-1), -0.8427007929497148)
+end
+
+assert('Math.erfc -1') do
+  check_float(Math.erfc(-1), 1.8427007929497148)
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-numeric-ext/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-numeric-ext/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-numeric-ext/mrbgem.rake	(revision 331)
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-numeric-ext') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'Numeric class extension'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb	(revision 331)
@@ -0,0 +1,17 @@
+module Integral
+  def div(other)
+    self.divmod(other)[0]
+  end
+
+  def zero?
+    self == 0
+  end
+
+  def nonzero?
+    if self == 0
+      nil
+    else
+      self
+    end
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-numeric-ext/src/numeric_ext.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-numeric-ext/src/numeric_ext.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-numeric-ext/src/numeric_ext.c	(revision 331)
@@ -0,0 +1,30 @@
+#include <limits.h>
+#include <mruby.h>
+
+static mrb_value
+mrb_int_chr(mrb_state *mrb, mrb_value x)
+{
+  mrb_int chr;
+  char c;
+
+  chr = mrb_fixnum(x);
+  if (chr >= (1 << CHAR_BIT)) {
+    mrb_raisef(mrb, E_RANGE_ERROR, "%S out of char range", x);
+  }
+  c = (char)chr;
+
+  return mrb_str_new(mrb, &c, 1);
+}
+
+void
+mrb_mruby_numeric_ext_gem_init(mrb_state* mrb)
+{
+  struct RClass *i = mrb_class_get(mrb, "Integer");
+
+  mrb_define_method(mrb, i, "chr", mrb_int_chr, MRB_ARGS_NONE());
+}
+
+void
+mrb_mruby_numeric_ext_gem_final(mrb_state* mrb)
+{
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-numeric-ext/test/numeric.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-numeric-ext/test/numeric.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-numeric-ext/test/numeric.rb	(revision 331)
@@ -0,0 +1,28 @@
+##
+# Numeric(Ext) Test
+
+assert('Integer#chr') do
+  assert_equal("A", 65.chr)
+  assert_equal("B", 0x42.chr)
+
+  # multibyte encoding (not support yet)
+  assert_raise(RangeError) { 256.chr }
+end
+
+assert('Integer#div') do
+  assert_equal 52, 365.div(7)
+end
+
+assert('Float#div') do
+  assert_float 52, 365.2425.div(7)
+end
+
+assert('Integer#zero?') do
+  assert_equal true, 0.zero?
+  assert_equal false, 1.zero?
+end
+
+assert('Integer#nonzero?') do
+  assert_equal nil, 0.nonzero?
+  assert_equal 1000, 1000.nonzero?
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-object-ext/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-object-ext/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-object-ext/mrbgem.rake	(revision 331)
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-object-ext') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'Object class extension'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-object-ext/mrblib/object.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-object-ext/mrblib/object.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-object-ext/mrblib/object.rb	(revision 331)
@@ -0,0 +1,19 @@
+class Object
+  ##
+  #  call-seq:
+  #     obj.tap{|x|...}    -> obj
+  #
+  #  Yields <code>x</code> to the block, and then returns <code>x</code>.
+  #  The primary purpose of this method is to "tap into" a method chain,
+  #  in order to perform operations on intermediate results within the chain.
+  #
+  #  (1..10)                .tap {|x| puts "original: #{x.inspect}"}
+  #    .to_a                .tap {|x| puts "array: #{x.inspect}"}
+  #    .select {|x| x%2==0} .tap {|x| puts "evens: #{x.inspect}"}
+  #    .map { |x| x*x }     .tap {|x| puts "squares: #{x.inspect}"}
+  #
+  def tap
+    yield self
+    self
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-object-ext/src/object.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-object-ext/src/object.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-object-ext/src/object.c	(revision 331)
@@ -0,0 +1,109 @@
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/class.h>
+#include <mruby/proc.h>
+
+/*
+ *  call-seq:
+ *     nil.to_a    -> []
+ *
+ *  Always returns an empty array.
+ */
+
+static mrb_value
+nil_to_a(mrb_state *mrb, mrb_value obj)
+{
+  return mrb_ary_new(mrb);
+}
+
+/*
+ *  call-seq:
+ *     nil.to_f    -> 0.0
+ *
+ *  Always returns zero.
+ */
+
+static mrb_value
+nil_to_f(mrb_state *mrb, mrb_value obj)
+{
+  return mrb_float_value(mrb, 0.0);
+}
+
+/*
+ *  call-seq:
+ *     nil.to_i    -> 0
+ *
+ *  Always returns zero.
+ */
+
+static mrb_value
+nil_to_i(mrb_state *mrb, mrb_value obj)
+{
+  return mrb_fixnum_value(0);
+}
+
+/*
+ *  call-seq:
+ *     obj.instance_exec(arg...) {|var...| block }                       -> obj
+ *
+ *  Executes the given block within the context of the receiver
+ *  (_obj_). In order to set the context, the variable +self+ is set
+ *  to _obj_ while the code is executing, giving the code access to
+ *  _obj_'s instance variables.  Arguments are passed as block parameters.
+ *
+ *     class KlassWithSecret
+ *       def initialize
+ *         @secret = 99
+ *       end
+ *     end
+ *     k = KlassWithSecret.new
+ *     k.instance_exec(5) {|x| @secret+x }   #=> 104
+ */
+
+static mrb_value
+mrb_obj_instance_exec(mrb_state *mrb, mrb_value self)
+{
+  const mrb_value *argv;
+  mrb_int argc;
+  mrb_value blk;
+  struct RClass *c;
+  mrb_value args;
+
+  mrb_get_args(mrb, "*&", &argv, &argc, &blk);
+
+  if (mrb_nil_p(blk)) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
+  }
+
+  switch (mrb_type(self)) {
+  case MRB_TT_SYMBOL:
+  case MRB_TT_FIXNUM:
+  case MRB_TT_FLOAT:
+    c = NULL;
+    break;
+  default:
+    c = mrb_class_ptr(mrb_singleton_class(mrb, self));
+    break;
+  }
+  args = mrb_ary_new_from_values(mrb, argc, argv);
+  argv = RARRAY_PTR(args);
+  mrb->c->ci->target_class = c;
+  return mrb_yield_cont(mrb, blk, self, argc, argv);
+}
+
+void
+mrb_mruby_object_ext_gem_init(mrb_state* mrb)
+{
+  struct RClass * n = mrb->nil_class;
+
+  mrb_define_method(mrb, n, "to_a", nil_to_a,       MRB_ARGS_NONE());
+  mrb_define_method(mrb, n, "to_f", nil_to_f,       MRB_ARGS_NONE());
+  mrb_define_method(mrb, n, "to_i", nil_to_i,       MRB_ARGS_NONE());
+
+  mrb_define_method(mrb, mrb->kernel_module, "instance_exec", mrb_obj_instance_exec, MRB_ARGS_ANY() | MRB_ARGS_BLOCK());
+}
+
+void
+mrb_mruby_object_ext_gem_final(mrb_state* mrb)
+{
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-object-ext/test/nil.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-object-ext/test/nil.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-object-ext/test/nil.rb	(revision 331)
@@ -0,0 +1,11 @@
+assert('NilClass#to_a') do
+  assert_equal [], nil.to_a
+end
+
+assert('NilClass#to_f') do
+  assert_equal 0.0, nil.to_f
+end
+
+assert('NilClass#to_i') do
+  assert_equal 0, nil.to_i
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-object-ext/test/object.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-object-ext/test/object.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-object-ext/test/object.rb	(revision 331)
@@ -0,0 +1,53 @@
+assert('Object#instance_exec') do
+  class KlassWithSecret
+    def initialize
+      @secret = 99
+    end
+  end
+  k = KlassWithSecret.new
+  assert_equal 104, k.instance_exec(5) {|x| @secret+x }
+end
+
+assert('Object#tap') do
+  ret = []
+  (1..10)                 .tap {|x| ret << "original: #{x.inspect}"}
+     .to_a                .tap {|x| ret << "array: #{x.inspect}"}
+     .select {|x| x%2==0} .tap {|x| ret << "evens: #{x.inspect}"}
+     .map { |x| x*x }     .tap {|x| ret << "squares: #{x.inspect}"}
+
+  assert_equal [
+    "original: 1..10",
+    "array: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]",
+    "evens: [2, 4, 6, 8, 10]",
+    "squares: [4, 16, 36, 64, 100]"
+  ], ret
+  assert_equal(:tap_ok, Class.new {def m; tap{return :tap_ok}; end}.new.m)
+end
+
+assert('instance_exec on primitives with class and module definition') do
+  begin
+    class A
+      1.instance_exec do
+        class B
+        end
+      end
+    end
+
+    assert_kind_of Class, A::B
+  ensure
+    Object.remove_const :A
+  end
+
+  begin
+    class A
+      1.instance_exec do
+        module B
+        end
+      end
+    end
+
+    assert_kind_of Module, A::B
+  ensure
+    Object.remove_const :A
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-objectspace/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-objectspace/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-objectspace/mrbgem.rake	(revision 331)
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-objectspace') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'ObjectSpace class'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-objectspace/src/mruby_objectspace.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-objectspace/src/mruby_objectspace.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-objectspace/src/mruby_objectspace.c	(revision 331)
@@ -0,0 +1,187 @@
+#include <mruby.h>
+#include <mruby/gc.h>
+#include <mruby/hash.h>
+#include <mruby/class.h>
+
+struct os_count_struct {
+  mrb_int total;
+  mrb_int freed;
+  mrb_int counts[MRB_TT_MAXDEFINE+1];
+};
+
+static int
+os_count_object_type(mrb_state *mrb, struct RBasic *obj, void *data)
+{
+  struct os_count_struct *obj_count;
+  obj_count = (struct os_count_struct*)data;
+
+  obj_count->total++;
+
+  if (mrb_object_dead_p(mrb, obj)) {
+    obj_count->freed++;
+  }
+  else {
+    obj_count->counts[obj->tt]++;
+  }
+  return MRB_EACH_OBJ_OK;
+}
+
+/*
+ *  call-seq:
+ *     ObjectSpace.count_objects([result_hash]) -> hash
+ *
+ *  Counts objects for each type.
+ *
+ *  It returns a hash, such as:
+ *  {
+ *    :TOTAL=>10000,
+ *    :FREE=>3011,
+ *    :T_OBJECT=>6,
+ *    :T_CLASS=>404,
+ *    # ...
+ *  }
+ *
+ *  If the optional argument +result_hash+ is given,
+ *  it is overwritten and returned. This is intended to avoid probe effect.
+ *
+ */
+
+static mrb_value
+os_count_objects(mrb_state *mrb, mrb_value self)
+{
+  struct os_count_struct obj_count = { 0 };
+  mrb_int i;
+  mrb_value hash;
+
+  if (mrb_get_args(mrb, "|H", &hash) == 0) {
+    hash = mrb_hash_new(mrb);
+  }
+
+  if (!mrb_test(mrb_hash_empty_p(mrb, hash))) {
+    mrb_hash_clear(mrb, hash);
+  }
+
+  mrb_objspace_each_objects(mrb, os_count_object_type, &obj_count);
+
+  mrb_hash_set(mrb, hash, mrb_symbol_value(mrb_intern_lit(mrb, "TOTAL")), mrb_fixnum_value(obj_count.total));
+  mrb_hash_set(mrb, hash, mrb_symbol_value(mrb_intern_lit(mrb, "FREE")), mrb_fixnum_value(obj_count.freed));
+
+  for (i = MRB_TT_FALSE; i < MRB_TT_MAXDEFINE; i++) {
+    mrb_value type;
+    switch (i) {
+#define COUNT_TYPE(t) case (MRB_T ## t): type = mrb_symbol_value(mrb_intern_lit(mrb, #t)); break;
+      COUNT_TYPE(T_FALSE);
+      COUNT_TYPE(T_FREE);
+      COUNT_TYPE(T_TRUE);
+      COUNT_TYPE(T_FIXNUM);
+      COUNT_TYPE(T_SYMBOL);
+      COUNT_TYPE(T_UNDEF);
+      COUNT_TYPE(T_FLOAT);
+      COUNT_TYPE(T_CPTR);
+      COUNT_TYPE(T_OBJECT);
+      COUNT_TYPE(T_CLASS);
+      COUNT_TYPE(T_MODULE);
+      COUNT_TYPE(T_ICLASS);
+      COUNT_TYPE(T_SCLASS);
+      COUNT_TYPE(T_PROC);
+      COUNT_TYPE(T_ARRAY);
+      COUNT_TYPE(T_HASH);
+      COUNT_TYPE(T_STRING);
+      COUNT_TYPE(T_RANGE);
+      COUNT_TYPE(T_EXCEPTION);
+      COUNT_TYPE(T_FILE);
+      COUNT_TYPE(T_ENV);
+      COUNT_TYPE(T_DATA);
+      COUNT_TYPE(T_FIBER);
+#undef COUNT_TYPE
+    default:
+      type = mrb_fixnum_value(i); break;
+    }
+    if (obj_count.counts[i])
+      mrb_hash_set(mrb, hash, type, mrb_fixnum_value(obj_count.counts[i]));
+  }
+
+  return hash;
+}
+
+struct os_each_object_data {
+  mrb_value block;
+  struct RClass *target_module;
+  mrb_int count;
+};
+
+static int
+os_each_object_cb(mrb_state *mrb, struct RBasic *obj, void *ud)
+{
+  struct os_each_object_data *d = (struct os_each_object_data*)ud;
+
+  /* filter dead objects */
+  if (mrb_object_dead_p(mrb, obj)) {
+    return MRB_EACH_OBJ_OK;
+  }
+
+  /* filter internal objects */
+  switch (obj->tt) {
+  case MRB_TT_ENV:
+  case MRB_TT_ICLASS:
+    return MRB_EACH_OBJ_OK;
+  default:
+    break;
+  }
+
+  /* filter half baked (or internal) objects */
+  if (!obj->c) return MRB_EACH_OBJ_OK;
+
+  /* filter class kind if target module defined */
+  if (d->target_module && !mrb_obj_is_kind_of(mrb, mrb_obj_value(obj), d->target_module)) {
+    return MRB_EACH_OBJ_OK;
+  }
+
+  mrb_yield(mrb, d->block, mrb_obj_value(obj));
+  ++d->count;
+  return MRB_EACH_OBJ_OK;
+}
+
+/*
+ *  call-seq:
+ *     ObjectSpace.each_object([module]) {|obj| ... } -> fixnum
+ *
+ *  Calls the block once for each object in this Ruby process.
+ *  Returns the number of objects found.
+ *  If the optional argument +module+ is given,
+ *  calls the block for only those classes or modules
+ *  that match (or are a subclass of) +module+.
+ *
+ *  If no block is given, ArgumentError is raised.
+ *
+ */
+
+static mrb_value
+os_each_object(mrb_state *mrb, mrb_value self)
+{
+  mrb_value cls = mrb_nil_value();
+  struct os_each_object_data d;
+  mrb_get_args(mrb, "&|C", &d.block, &cls);
+
+  if (mrb_nil_p(d.block)) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "Expected block in ObjectSpace.each_object.");
+  }
+
+  d.target_module = mrb_nil_p(cls) ? NULL : mrb_class_ptr(cls);
+  d.count = 0;
+  mrb_objspace_each_objects(mrb, os_each_object_cb, &d);
+  return mrb_fixnum_value(d.count);
+}
+
+void
+mrb_mruby_objectspace_gem_init(mrb_state *mrb)
+{
+  struct RClass *os = mrb_define_module(mrb, "ObjectSpace");
+  mrb_define_class_method(mrb, os, "count_objects", os_count_objects, MRB_ARGS_OPT(1));
+  mrb_define_class_method(mrb, os, "each_object", os_each_object, MRB_ARGS_OPT(1));
+}
+
+void
+mrb_mruby_objectspace_gem_final(mrb_state *mrb)
+{
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-objectspace/test/objectspace.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-objectspace/test/objectspace.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-objectspace/test/objectspace.rb	(revision 331)
@@ -0,0 +1,60 @@
+assert('ObjectSpace.count_objects') do
+  h = {}
+  f = Fiber.new {} if Object.const_defined? :Fiber
+  ObjectSpace.count_objects(h)
+  assert_kind_of(Hash, h)
+  assert_true(h.keys.all? {|x| x.is_a?(Symbol) || x.is_a?(Integer) })
+  assert_true(h.values.all? {|x| x.is_a?(Integer) })
+
+  assert_true(h.has_key?(:TOTAL))
+  assert_true(h.has_key?(:FREE))
+  assert_true(h.has_key?(:T_FIBER)) if Object.const_defined? :Fiber
+
+  assert_equal(h[:TOTAL] * 2, h.values.reduce(:+))
+
+  h = ObjectSpace.count_objects
+  assert_kind_of(Hash, h)
+  assert_true(h.keys.all? {|x| x.is_a?(Symbol) || x.is_a?(Integer) })
+  assert_true(h.values.all? {|x| x.is_a?(Integer) })
+
+  assert_raise(TypeError) { ObjectSpace.count_objects(1) }
+
+  h0 = {:T_FOO=>1000}
+  h = ObjectSpace.count_objects(h0)
+  assert_false(h0.has_key?(:T_FOO))
+
+  GC.start
+  h_after = {}
+  h_before = ObjectSpace.count_objects
+
+  objs = []
+  1000.times do
+    objs << {}
+  end
+  objs = nil
+  ObjectSpace.count_objects(h)
+  GC.start
+  ObjectSpace.count_objects(h_after)
+
+  assert_equal(h[:T_HASH], h_before[:T_HASH] + 1000)
+  assert_equal(h_after[:T_HASH], h_before[:T_HASH])
+end
+
+assert('ObjectSpace.each_object') do
+  objs = []
+  objs_count = ObjectSpace.each_object { |obj|
+    objs << obj
+  }
+  assert_equal objs.length, objs_count
+
+  arys = []
+  arys_count = ObjectSpace.each_object(Array) { |obj|
+    arys << obj
+  }
+  assert_equal arys.length, arys_count
+  assert_true arys.length < objs.length
+end
+
+assert 'Check class pointer of ObjectSpace.each_object.' do
+  ObjectSpace.each_object { |obj| !obj }
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-print/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-print/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-print/mrbgem.rake	(revision 331)
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-print') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'standard print/puts/p'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-print/mrblib/print.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-print/mrblib/print.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-print/mrblib/print.rb	(revision 331)
@@ -0,0 +1,64 @@
+##
+# Kernel
+#
+# ISO 15.3.1
+module Kernel
+  ##
+  # Invoke method +print+ on STDOUT and passing +*args+
+  #
+  # ISO 15.3.1.2.10
+  def print(*args)
+    i = 0
+    len = args.size
+    while i < len
+      __printstr__ args[i].to_s
+      i += 1
+    end
+  end
+
+  ##
+  # Invoke method +puts+ on STDOUT and passing +*args*+
+  #
+  # ISO 15.3.1.2.11
+  def puts(*args)
+    i = 0
+    len = args.size
+    while i < len
+      s = args[i].to_s
+      __printstr__ s
+      __printstr__ "\n" if (s[-1] != "\n")
+      i += 1
+    end
+    __printstr__ "\n" if len == 0
+    nil
+  end
+
+  ##
+  # Print human readable object description
+  #
+  # ISO 15.3.1.3.34
+  def p(*args)
+    i = 0
+    len = args.size
+    while i < len
+      __printstr__ args[i].inspect
+      __printstr__ "\n"
+      i += 1
+    end
+    args[0]
+  end
+
+  unless Kernel.respond_to?(:sprintf)
+    def printf(*args)
+      raise NotImplementedError.new('printf not available')
+    end
+    def sprintf(*args)
+      raise NotImplementedError.new('sprintf not available')
+    end
+  else
+    def printf(*args)
+      __printstr__(sprintf(*args))
+      nil
+    end
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-print/src/print.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-print/src/print.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-print/src/print.c	(revision 331)
@@ -0,0 +1,63 @@
+#include <mruby.h>
+#include <mruby/string.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#if defined(_WIN32)
+# include <windows.h>
+# include <io.h>
+#ifdef _MSC_VER
+# define isatty(x) _isatty(x)
+# define fileno(x) _fileno(x)
+#endif
+#endif
+
+static void
+printstr(mrb_state *mrb, mrb_value obj)
+{
+  if (mrb_string_p(obj)) {
+#if defined(_WIN32)
+    if (isatty(fileno(stdout))) {
+      DWORD written;
+      int mlen = RSTRING_LEN(obj);
+      char* utf8 = RSTRING_PTR(obj);
+      int wlen = MultiByteToWideChar(CP_UTF8, 0, utf8, mlen, NULL, 0);
+      wchar_t* utf16 = (wchar_t*)mrb_malloc(mrb, (wlen+1) * sizeof(wchar_t));
+      if (utf16 == NULL) return;
+      if (MultiByteToWideChar(CP_UTF8, 0, utf8, mlen, utf16, wlen) > 0) {
+        utf16[wlen] = 0;
+        WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),
+          utf16, wlen, &written, NULL);
+      }
+      mrb_free(mrb, utf16);
+    } else
+#endif
+      fwrite(RSTRING_PTR(obj), RSTRING_LEN(obj), 1, stdout);
+  }
+}
+
+/* 15.3.1.2.9  */
+/* 15.3.1.3.34 */
+mrb_value
+mrb_printstr(mrb_state *mrb, mrb_value self)
+{
+  mrb_value argv;
+
+  mrb_get_args(mrb, "o", &argv);
+  printstr(mrb, argv);
+
+  return argv;
+}
+
+void
+mrb_mruby_print_gem_init(mrb_state* mrb)
+{
+  struct RClass *krn;
+  krn = mrb->kernel_module;
+  mrb_define_method(mrb, krn, "__printstr__", mrb_printstr, MRB_ARGS_REQ(1));
+}
+
+void
+mrb_mruby_print_gem_final(mrb_state* mrb)
+{
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-proc-ext/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-proc-ext/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-proc-ext/mrbgem.rake	(revision 331)
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-proc-ext') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'Proc class extension'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-proc-ext/mrblib/proc.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-proc-ext/mrblib/proc.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-proc-ext/mrblib/proc.rb	(revision 331)
@@ -0,0 +1,42 @@
+class Proc
+
+  def ===(*args)
+    call(*args)
+  end
+
+  def yield(*args)
+    call(*args)
+  end
+
+  def to_proc
+    self
+  end
+
+  def curry(arity=self.arity)
+    type = :proc
+    abs = lambda {|a| a < 0 ? -a - 1 : a}
+    arity = abs[arity]
+    if lambda?
+      type = :lambda
+      self_arity = self.arity
+      if (self_arity >= 0 && arity != self_arity) ||
+         (self_arity < 0 && abs[self_arity] > arity)
+        raise ArgumentError, "wrong number of arguments (#{arity} for #{abs[self_arity]})"
+      end
+    end
+
+    pproc = self
+    make_curry = proc do |given_args=[]|
+      send(type) do |*args|
+        new_args = given_args + args
+        if new_args.size >= arity
+          pproc[*new_args]
+        else
+          make_curry[new_args]
+        end
+      end
+    end
+    make_curry.call
+  end
+
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-proc-ext/src/proc.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-proc-ext/src/proc.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-proc-ext/src/proc.c	(revision 331)
@@ -0,0 +1,173 @@
+#include <mruby.h>
+#include <mruby/proc.h>
+#include <mruby/opcode.h>
+#include <mruby/array.h>
+#include <mruby/string.h>
+#include <mruby/debug.h>
+
+static mrb_value
+mrb_proc_lambda(mrb_state *mrb, mrb_value self)
+{
+  struct RProc *p = mrb_proc_ptr(self);
+  return mrb_bool_value(MRB_PROC_STRICT_P(p));
+}
+
+static mrb_value
+mrb_proc_source_location(mrb_state *mrb, mrb_value self)
+{
+  struct RProc *p = mrb_proc_ptr(self);
+
+  if (MRB_PROC_CFUNC_P(p)) {
+    return mrb_nil_value();
+  }
+  else {
+    mrb_irep *irep = p->body.irep;
+    int32_t line;
+    const char *filename;
+
+    filename = mrb_debug_get_filename(irep, 0);
+    line = mrb_debug_get_line(irep, 0);
+
+    return (!filename && line == -1)? mrb_nil_value()
+        : mrb_assoc_new(mrb, mrb_str_new_cstr(mrb, filename), mrb_fixnum_value(line));
+  }
+}
+
+static mrb_value
+mrb_proc_inspect(mrb_state *mrb, mrb_value self)
+{
+  struct RProc *p = mrb_proc_ptr(self);
+  mrb_value str = mrb_str_new_lit(mrb, "#<Proc:");
+  mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_cptr(self)));
+
+  if (!MRB_PROC_CFUNC_P(p)) {
+    mrb_irep *irep = p->body.irep;
+    const char *filename;
+    int32_t line;
+    mrb_str_cat_lit(mrb, str, "@");
+
+    filename = mrb_debug_get_filename(irep, 0);
+    mrb_str_cat_cstr(mrb, str, filename ? filename : "-");
+    mrb_str_cat_lit(mrb, str, ":");
+
+    line = mrb_debug_get_line(irep, 0);
+    if (line != -1) {
+      str = mrb_format(mrb, "%S:%S", str, mrb_fixnum_value(line));
+    }
+    else {
+      mrb_str_cat_lit(mrb, str, "-");
+    }
+  }
+
+  if (MRB_PROC_STRICT_P(p)) {
+    mrb_str_cat_lit(mrb, str, " (lambda)");
+  }
+
+  mrb_str_cat_lit(mrb, str, ">");
+  return str;
+}
+
+static mrb_value
+mrb_kernel_proc(mrb_state *mrb, mrb_value self)
+{
+  mrb_value blk;
+
+  mrb_get_args(mrb, "&", &blk);
+  if (mrb_nil_p(blk)) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block");
+  }
+
+  return blk;
+}
+
+/*
+ * call-seq:
+ *    prc.parameters  -> array
+ *
+ * Returns the parameter information of this proc.
+ *
+ *    prc = lambda{|x, y=42, *other|}
+ *    prc.parameters  #=> [[:req, :x], [:opt, :y], [:rest, :other]]
+ */
+
+static mrb_value
+mrb_proc_parameters(mrb_state *mrb, mrb_value self)
+{
+  struct parameters_type {
+    int size;
+    const char *name;
+  } *p, parameters_list [] = {
+    {0, "req"},
+    {0, "opt"},
+    {0, "rest"},
+    {0, "req"},
+    {0, "block"},
+    {0, NULL}
+  };
+  const struct RProc *proc = mrb_proc_ptr(self);
+  const struct mrb_irep *irep = proc->body.irep;
+  mrb_aspec aspec;
+  mrb_value sname, parameters;
+  int i, j;
+
+  if (MRB_PROC_CFUNC_P(proc)) {
+    // TODO cfunc aspec is not implemented yet
+    return mrb_ary_new(mrb);
+  }
+  if (!irep) {
+    return mrb_ary_new(mrb);
+  }
+  if (!irep->lv) {
+    return mrb_ary_new(mrb);
+  }
+  if (GET_OPCODE(*irep->iseq) != OP_ENTER) {
+    return mrb_ary_new(mrb);
+  }
+
+  if (!MRB_PROC_STRICT_P(proc)) {
+    parameters_list[0].name = "opt";
+    parameters_list[3].name = "opt";
+  }
+
+  aspec = GETARG_Ax(*irep->iseq);
+  parameters_list[0].size = MRB_ASPEC_REQ(aspec);
+  parameters_list[1].size = MRB_ASPEC_OPT(aspec);
+  parameters_list[2].size = MRB_ASPEC_REST(aspec);
+  parameters_list[3].size = MRB_ASPEC_POST(aspec);
+  parameters_list[4].size = MRB_ASPEC_BLOCK(aspec);
+
+  parameters = mrb_ary_new_capa(mrb, irep->nlocals-1);
+
+  for (i = 0, p = parameters_list; p->name; p++) {
+    if (p->size <= 0) continue;
+    sname = mrb_symbol_value(mrb_intern_cstr(mrb, p->name));
+    for (j = 0; j < p->size; i++, j++) {
+      mrb_value a = mrb_ary_new(mrb);
+      mrb_ary_push(mrb, a, sname);
+      if (irep->lv[i].name) {
+        mrb_ary_push(mrb, a, mrb_symbol_value(irep->lv[i].name));
+      }
+      mrb_ary_push(mrb, parameters, a);
+    }
+  }
+  return parameters;
+}
+
+void
+mrb_mruby_proc_ext_gem_init(mrb_state* mrb)
+{
+  struct RClass *p = mrb->proc_class;
+  mrb_define_method(mrb, p, "lambda?",         mrb_proc_lambda,          MRB_ARGS_NONE());
+  mrb_define_method(mrb, p, "source_location", mrb_proc_source_location, MRB_ARGS_NONE());
+  mrb_define_method(mrb, p, "to_s",            mrb_proc_inspect,         MRB_ARGS_NONE());
+  mrb_define_method(mrb, p, "inspect",         mrb_proc_inspect,         MRB_ARGS_NONE());
+  mrb_define_method(mrb, p, "parameters",      mrb_proc_parameters,      MRB_ARGS_NONE());
+
+  mrb_define_class_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE());
+  mrb_define_method(mrb, mrb->kernel_module,       "proc", mrb_kernel_proc, MRB_ARGS_NONE());
+}
+
+void
+mrb_mruby_proc_ext_gem_final(mrb_state* mrb)
+{
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-proc-ext/test/proc.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-proc-ext/test/proc.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-proc-ext/test/proc.c	(revision 331)
@@ -0,0 +1,56 @@
+#include <mruby.h>
+#include <mruby/proc.h>
+#include <mruby/class.h>
+
+static mrb_value
+return_func_name(mrb_state *mrb, mrb_value self)
+{
+  return mrb_cfunc_env_get(mrb, 0);
+}
+
+static mrb_value
+proc_new_cfunc_with_env(mrb_state *mrb, mrb_value self)
+{
+  mrb_sym n;
+  mrb_value n_val;
+  mrb_get_args(mrb, "n", &n);
+  n_val = mrb_symbol_value(n);
+  mrb_define_method_raw(mrb, mrb_class_ptr(self), n,
+                        mrb_proc_new_cfunc_with_env(mrb, return_func_name, 1, &n_val));
+  return self;
+}
+
+static mrb_value
+return_env(mrb_state *mrb, mrb_value self)
+{
+  mrb_int idx;
+  mrb_get_args(mrb, "i", &idx);
+  return mrb_cfunc_env_get(mrb, idx);
+}
+
+static mrb_value
+cfunc_env_get(mrb_state *mrb, mrb_value self)
+{
+  mrb_sym n;
+  mrb_value *argv; mrb_int argc;
+  mrb_get_args(mrb, "na", &n, &argv, &argc);
+  mrb_define_method_raw(mrb, mrb_class_ptr(self), n,
+                        mrb_proc_new_cfunc_with_env(mrb, return_env, argc, argv));
+  return self;
+}
+
+static mrb_value
+cfunc_without_env(mrb_state *mrb, mrb_value self)
+{
+  return mrb_cfunc_env_get(mrb, 0);
+}
+
+void mrb_mruby_proc_ext_gem_test(mrb_state *mrb)
+{
+  struct RClass *cls;
+
+  cls = mrb_define_class(mrb, "ProcExtTest", mrb->object_class);
+  mrb_define_module_function(mrb, cls, "mrb_proc_new_cfunc_with_env", proc_new_cfunc_with_env, MRB_ARGS_REQ(1));
+  mrb_define_module_function(mrb, cls, "mrb_cfunc_env_get", cfunc_env_get, MRB_ARGS_REQ(2));
+  mrb_define_module_function(mrb, cls, "cfunc_without_env", cfunc_without_env, MRB_ARGS_NONE());
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-proc-ext/test/proc.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-proc-ext/test/proc.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-proc-ext/test/proc.rb	(revision 331)
@@ -0,0 +1,92 @@
+##
+# Proc(Ext) Test
+
+assert('Proc#source_location') do
+  loc = Proc.new {}.source_location
+  next true if loc.nil?
+  assert_equal loc[0][-7, 7], 'proc.rb'
+  assert_equal loc[1], 5
+end
+
+assert('Proc#inspect') do
+  ins = Proc.new{}.inspect
+  assert_kind_of String, ins
+end
+
+assert('Proc#lambda?') do
+  assert_true lambda{}.lambda?
+  assert_true !Proc.new{}.lambda?
+end
+
+assert('Proc#===') do
+  proc = Proc.new {|a| a * 2}
+  assert_equal 20, (proc === 10)
+end
+
+assert('Proc#yield') do
+  proc = Proc.new {|a| a * 2}
+  assert_equal 20, proc.yield(10)
+end
+
+assert('Proc#curry') do
+  b = proc {|x, y, z| (x||0) + (y||0) + (z||0) }
+  assert_equal 6, b.curry[1][2][3]
+  assert_equal 6, b.curry[1, 2][3, 4]
+  assert_equal 6, b.curry(5)[1][2][3][4][5]
+  assert_equal 6, b.curry(5)[1, 2][3, 4][5]
+  assert_equal 1, b.curry(1)[1]
+
+  b = lambda {|x, y, z| (x||0) + (y||0) + (z||0) }
+  assert_equal 6, b.curry[1][2][3]
+  assert_raise(ArgumentError) { b.curry[1, 2][3, 4] }
+  assert_raise(ArgumentError) { b.curry(5) }
+  assert_raise(ArgumentError) { b.curry(1) }
+
+  assert_false(proc{}.curry.lambda?)
+  assert_true(lambda{}.curry.lambda?)
+end
+
+assert('Proc#parameters') do
+  assert_equal([], Proc.new {}.parameters)
+  assert_equal([], Proc.new {||}.parameters)
+  assert_equal([[:opt, :a]], Proc.new {|a|}.parameters)
+  assert_equal([[:req, :a]], lambda {|a|}.parameters)
+  assert_equal([[:opt, :a]], lambda {|a=nil|}.parameters)
+  assert_equal([[:req, :a]], ->(a){}.parameters)
+  assert_equal([[:rest]], lambda { |*| }.parameters)
+  assert_equal([[:rest, :a]], Proc.new {|*a|}.parameters)
+  assert_equal([[:opt, :a], [:opt, :b], [:opt, :c], [:opt, :d], [:rest, :e], [:opt, :f], [:opt, :g], [:block, :h]], Proc.new {|a,b,c=:c,d=:d,*e,f,g,&h|}.parameters)
+  assert_equal([[:req, :a], [:req, :b], [:opt, :c], [:opt, :d], [:rest, :e], [:req, :f], [:req, :g], [:block, :h]], lambda {|a,b,c=:c,d=:d,*e,f,g,&h|}.parameters)
+end
+
+assert('Proc#to_proc') do
+  proc = Proc.new {}
+  assert_equal proc, proc.to_proc
+end
+
+assert('Kernel#proc') do
+  assert_true !proc{|a|}.lambda?
+end
+
+assert('mrb_proc_new_cfunc_with_env') do
+  ProcExtTest.mrb_proc_new_cfunc_with_env(:test)
+  ProcExtTest.mrb_proc_new_cfunc_with_env(:mruby)
+
+  t = ProcExtTest.new
+
+  assert_equal :test, t.test
+  assert_equal :mruby, t.mruby
+end
+
+assert('mrb_cfunc_env_get') do
+  ProcExtTest.mrb_cfunc_env_get :get_int, [0, 1, 2]
+
+  t = ProcExtTest.new
+
+  assert_raise(TypeError) { t.cfunc_without_env }
+
+  assert_raise(IndexError) { t.get_int(-1) }
+  assert_raise(IndexError) { t.get_int(3) }
+
+  assert_equal 1, t.get_int(1)
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-random/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-random/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-random/mrbgem.rake	(revision 331)
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-random') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'Random class'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-random/src/mt19937ar.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-random/src/mt19937ar.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-random/src/mt19937ar.c	(revision 331)
@@ -0,0 +1,226 @@
+/*
+** mt19937ar.c - MT Random functions
+**
+** Copyright (C) 1997 - 2016, Makoto Matsumoto and Takuji Nishimura,
+** All rights reserved.
+**
+** Permission is hereby granted, free of charge, to any person obtaining
+** a copy of this software and associated documentation files (the
+** "Software"), to deal in the Software without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Software, and to
+** permit persons to whom the Software is furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be
+** included in all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**
+** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
+**
+** Any feedback is very welcome.
+** http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
+** email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
+**
+** This version is modified by mruby developers. If you see any problem,
+** contact us first at https://github.com/mruby/mruby/issues
+*/
+
+#include <mruby.h>
+#include "mt19937ar.h"
+
+/* Period parameters */
+/* #define N 624 */
+#define M 397
+#define MATRIX_A 0x9908b0dfUL   /* constant vector a */
+#define UPPER_MASK 0x80000000UL /* most significant w-r bits */
+#define LOWER_MASK 0x7fffffffUL /* least significant r bits */
+
+#if 0 /* dead_code */
+static unsigned long mt[N]; /* the array for the state vector  */
+static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
+#endif /* dead_code */
+
+void mrb_random_init_genrand(mt_state *t, unsigned long s)
+{
+    t->mt[0]= s & 0xffffffffUL;
+    for (t->mti=1; t->mti<N; t->mti++) {
+        t->mt[t->mti] =
+	    (1812433253UL * (t->mt[t->mti-1] ^ (t->mt[t->mti-1] >> 30)) + t->mti);
+        t->mt[t->mti] &= 0xffffffffUL;
+    }
+}
+
+unsigned long mrb_random_genrand_int32(mt_state *t)
+{
+    unsigned long y;
+    static const unsigned long mag01[2]={0x0UL, MATRIX_A};
+    /* mag01[x] = x * MATRIX_A  for x=0,1 */
+
+    if (t->mti >= N) { /* generate N words at one time */
+        int kk;
+
+        if (t->mti == N+1)   /* if init_genrand() has not been called, */
+            mrb_random_init_genrand(t, 5489UL); /* a default initial seed is used */
+
+        for (kk=0;kk<N-M;kk++) {
+            y = (t->mt[kk]&UPPER_MASK)|(t->mt[kk+1]&LOWER_MASK);
+            t->mt[kk] = t->mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
+        }
+        for (;kk<N-1;kk++) {
+            y = (t->mt[kk]&UPPER_MASK)|(t->mt[kk+1]&LOWER_MASK);
+            t->mt[kk] = t->mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
+        }
+        y = (t->mt[N-1]&UPPER_MASK)|(t->mt[0]&LOWER_MASK);
+        t->mt[N-1] = t->mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
+
+        t->mti = 0;
+    }
+
+    y = t->mt[t->mti++];
+
+    /* Tempering */
+    y ^= (y >> 11);
+    y ^= (y << 7) & 0x9d2c5680UL;
+    y ^= (y << 15) & 0xefc60000UL;
+    y ^= (y >> 18);
+
+    t->gen.int_ = y;
+
+    return y;
+}
+
+double mrb_random_genrand_real1(mt_state *t)
+{
+    mrb_random_genrand_int32(t);
+    t->gen.double_ =  t->gen.int_*(1.0/4294967295.0);
+    return t->gen.double_;
+    /* divided by 2^32-1 */
+}
+
+#if 0 /* dead_code */
+/* initializes mt[N] with a seed */
+void init_genrand(unsigned long s)
+{
+    mt[0]= s & 0xffffffffUL;
+    for (mti=1; mti<N; mti++) {
+        mt[mti] =
+	    (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
+        /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
+        /* In the previous versions, MSBs of the seed affect   */
+        /* only MSBs of the array mt[].                        */
+        /* 2002/01/09 modified by Makoto Matsumoto             */
+        mt[mti] &= 0xffffffffUL;
+        /* for >32 bit machines */
+    }
+}
+
+/* initialize by an array with array-length */
+/* init_key is the array for initializing keys */
+/* key_length is its length */
+/* slight change for C++, 2004/2/26 */
+void init_by_array(unsigned long init_key[], int key_length)
+{
+    int i, j, k;
+    init_genrand(19650218UL);
+    i=1; j=0;
+    k = (N>key_length ? N : key_length);
+    for (; k; k--) {
+        mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))
+          + init_key[j] + j; /* non linear */
+        mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
+        i++; j++;
+        if (i>=N) { mt[0] = mt[N-1]; i=1; }
+        if (j>=key_length) j=0;
+    }
+    for (k=N-1; k; k--) {
+        mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL))
+          - i; /* non linear */
+        mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
+        i++;
+        if (i>=N) { mt[0] = mt[N-1]; i=1; }
+    }
+
+    mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
+}
+
+/* generates a random number on [0,0xffffffff]-interval */
+unsigned long genrand_int32(void)
+{
+    unsigned long y;
+    static const unsigned long mag01[2]={0x0UL, MATRIX_A};
+    /* mag01[x] = x * MATRIX_A  for x=0,1 */
+
+    if (mti >= N) { /* generate N words at one time */
+        int kk;
+
+        if (mti == N+1)   /* if init_genrand() has not been called, */
+            init_genrand(5489UL); /* a default initial seed is used */
+
+        for (kk=0;kk<N-M;kk++) {
+            y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
+            mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
+        }
+        for (;kk<N-1;kk++) {
+            y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
+            mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];
+        }
+        y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);
+        mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];
+
+        mti = 0;
+    }
+
+    y = mt[mti++];
+
+    /* Tempering */
+    y ^= (y >> 11);
+    y ^= (y << 7) & 0x9d2c5680UL;
+    y ^= (y << 15) & 0xefc60000UL;
+    y ^= (y >> 18);
+
+    return y;
+}
+
+/* generates a random number on [0,0x7fffffff]-interval */
+long genrand_int31(void)
+{
+    return (long)(genrand_int32()>>1);
+}
+
+/* generates a random number on [0,1]-real-interval */
+double genrand_real1(void)
+{
+    return genrand_int32()*(1.0/4294967295.0);
+    /* divided by 2^32-1 */
+}
+
+/* generates a random number on [0,1)-real-interval */
+double genrand_real2(void)
+{
+    return genrand_int32()*(1.0/4294967296.0);
+    /* divided by 2^32 */
+}
+
+/* generates a random number on (0,1)-real-interval */
+double genrand_real3(void)
+{
+    return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0);
+    /* divided by 2^32 */
+}
+
+/* generates a random number on [0,1) with 53-bit resolution*/
+double genrand_res53(void)
+{
+    unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6;
+    return(a*67108864.0+b)*(1.0/9007199254740992.0);
+}
+/* These real versions are due to Isaku Wada, 2002/01/09 added */
+#endif /* dead_code */
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-random/src/mt19937ar.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-random/src/mt19937ar.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-random/src/mt19937ar.h	(revision 331)
@@ -0,0 +1,80 @@
+/*
+** mt19937ar.h - MT Random functions
+**
+** Copyright (C) 1997 - 2016, Makoto Matsumoto and Takuji Nishimura,
+** All rights reserved.
+**
+** Permission is hereby granted, free of charge, to any person obtaining
+** a copy of this software and associated documentation files (the
+** "Software"), to deal in the Software without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Software, and to
+** permit persons to whom the Software is furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be
+** included in all copies or substantial portions of the Software.
+**
+** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+**
+** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
+**
+** Any feedback is very welcome.
+** http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
+** email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
+**
+** This version is modified by mruby developers. If you see any problem,
+** contact us first at https://github.com/mruby/mruby/issues
+*/
+
+#define N 624
+
+typedef struct {
+  unsigned long mt[N];
+  int mti;
+  union {
+    unsigned long int_;
+    double double_;
+  } gen;
+
+  mrb_int seed;
+  mrb_bool has_seed : 1;
+} mt_state;
+
+void mrb_random_init_genrand(mt_state *, unsigned long);
+unsigned long mrb_random_genrand_int32(mt_state *);
+double mrb_random_genrand_real1(mt_state *t);
+
+/* initializes mt[N] with a seed */
+void init_genrand(unsigned long s);
+
+/* initialize by an array with array-length */
+/* init_key is the array for initializing keys */
+/* key_length is its length */
+/* slight change for C++, 2004/2/26 */
+void init_by_array(unsigned long init_key[], int key_length);
+
+/* generates a random number on [0,0xffffffff]-interval */
+unsigned long genrand_int32(void);
+
+/* generates a random number on [0,0x7fffffff]-interval */
+long genrand_int31(void);
+
+/* These real versions are due to Isaku Wada, 2002/01/09 added */
+/* generates a random number on [0,1]-real-interval */
+double genrand_real1(void);
+
+/* generates a random number on [0,1)-real-interval */
+double genrand_real2(void);
+
+/* generates a random number on (0,1)-real-interval */
+double genrand_real3(void);
+
+/* generates a random number on [0,1) with 53-bit resolution*/
+double genrand_res53(void);
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-random/src/random.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-random/src/random.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-random/src/random.c	(revision 331)
@@ -0,0 +1,347 @@
+/*
+** random.c - Random module
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <mruby.h>
+#include <mruby/variable.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+#include <mruby/array.h>
+#include "mt19937ar.h"
+
+#include <time.h>
+
+static char const MT_STATE_KEY[] = "$mrb_i_mt_state";
+
+static const struct mrb_data_type mt_state_type = {
+  MT_STATE_KEY, mrb_free,
+};
+
+static mrb_value mrb_random_rand(mrb_state *mrb, mrb_value self);
+static mrb_value mrb_random_srand(mrb_state *mrb, mrb_value self);
+
+static void
+mt_srand(mt_state *t, unsigned long seed)
+{
+  mrb_random_init_genrand(t, seed);
+}
+
+static unsigned long
+mt_rand(mt_state *t)
+{
+  return mrb_random_genrand_int32(t);
+}
+
+static double
+mt_rand_real(mt_state *t)
+{
+  return mrb_random_genrand_real1(t);
+}
+
+static mrb_value
+mrb_random_mt_srand(mrb_state *mrb, mt_state *t, mrb_value seed)
+{
+  if (mrb_nil_p(seed)) {
+    seed = mrb_fixnum_value((mrb_int)(time(NULL) + mt_rand(t)));
+    if (mrb_fixnum(seed) < 0) {
+      seed = mrb_fixnum_value(0 - mrb_fixnum(seed));
+    }
+  }
+
+  mt_srand(t, (unsigned) mrb_fixnum(seed));
+
+  return seed;
+}
+
+static mrb_value
+mrb_random_mt_rand(mrb_state *mrb, mt_state *t, mrb_value max)
+{
+  mrb_value value;
+
+  if (mrb_fixnum(max) == 0) {
+    value = mrb_float_value(mrb, mt_rand_real(t));
+  }
+  else {
+    value = mrb_fixnum_value(mt_rand(t) % mrb_fixnum(max));
+  }
+
+  return value;
+}
+
+static mrb_value
+get_opt(mrb_state* mrb)
+{
+  mrb_value arg;
+
+  arg = mrb_nil_value();
+  mrb_get_args(mrb, "|o", &arg);
+
+  if (!mrb_nil_p(arg)) {
+    arg = mrb_check_convert_type(mrb, arg, MRB_TT_FIXNUM, "Fixnum", "to_int");
+    if (mrb_nil_p(arg)) {
+      mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid argument type");
+    }
+    if (mrb_fixnum(arg) < 0) {
+      arg = mrb_fixnum_value(0 - mrb_fixnum(arg));
+    }
+  }
+  return arg;
+}
+
+static mrb_value
+get_random(mrb_state *mrb) {
+  return mrb_const_get(mrb,
+             mrb_obj_value(mrb_class_get(mrb, "Random")),
+             mrb_intern_lit(mrb, "DEFAULT"));
+}
+
+static mt_state *
+get_random_state(mrb_state *mrb)
+{
+  mrb_value random_val = get_random(mrb);
+  return DATA_GET_PTR(mrb, random_val, &mt_state_type, mt_state);
+}
+
+static mrb_value
+mrb_random_g_rand(mrb_state *mrb, mrb_value self)
+{
+  mrb_value random = get_random(mrb);
+  return mrb_random_rand(mrb, random);
+}
+
+static mrb_value
+mrb_random_g_srand(mrb_state *mrb, mrb_value self)
+{
+  mrb_value random = get_random(mrb);
+  return mrb_random_srand(mrb, random);
+}
+
+static mrb_value
+mrb_random_init(mrb_state *mrb, mrb_value self)
+{
+  mrb_value seed;
+  mt_state *t;
+
+  seed = get_opt(mrb);
+
+  /* avoid memory leaks */
+  t = (mt_state*)DATA_PTR(self);
+  if (t) {
+    mrb_free(mrb, t);
+  }
+  mrb_data_init(self, NULL, &mt_state_type);
+
+  t = (mt_state *)mrb_malloc(mrb, sizeof(mt_state));
+  t->mti = N + 1;
+
+  seed = mrb_random_mt_srand(mrb, t, seed);
+  if (mrb_nil_p(seed)) {
+    t->has_seed = FALSE;
+  }
+  else {
+    mrb_assert(mrb_fixnum_p(seed));
+    t->has_seed = TRUE;
+    t->seed = mrb_fixnum(seed);
+  }
+
+  mrb_data_init(self, t, &mt_state_type);
+
+  return self;
+}
+
+static void
+mrb_random_rand_seed(mrb_state *mrb, mt_state *t)
+{
+  if (!t->has_seed) {
+    mrb_random_mt_srand(mrb, t, mrb_nil_value());
+  }
+}
+
+static mrb_value
+mrb_random_rand(mrb_state *mrb, mrb_value self)
+{
+  mrb_value max;
+  mt_state *t = DATA_GET_PTR(mrb, self, &mt_state_type, mt_state);
+
+  max = get_opt(mrb);
+  mrb_random_rand_seed(mrb, t);
+  return mrb_random_mt_rand(mrb, t, max);
+}
+
+static mrb_value
+mrb_random_srand(mrb_state *mrb, mrb_value self)
+{
+  mrb_value seed;
+  mrb_value old_seed;
+  mt_state *t = DATA_GET_PTR(mrb, self, &mt_state_type, mt_state);
+
+  seed = get_opt(mrb);
+  seed = mrb_random_mt_srand(mrb, t, seed);
+  old_seed = t->has_seed? mrb_fixnum_value(t->seed) : mrb_nil_value();
+  if (mrb_nil_p(seed)) {
+    t->has_seed = FALSE;
+  }
+  else {
+    mrb_assert(mrb_fixnum_p(seed));
+    t->has_seed = TRUE;
+    t->seed = mrb_fixnum(seed);
+  }
+
+  return old_seed;
+}
+
+/*
+ *  call-seq:
+ *     ary.shuffle!   ->   ary
+ *
+ *  Shuffles elements in self in place.
+ */
+
+static mrb_value
+mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary)
+{
+  mrb_int i;
+  mt_state *random = NULL;
+
+  if (RARRAY_LEN(ary) > 1) {
+    mrb_get_args(mrb, "|d", &random, &mt_state_type);
+
+    if (random == NULL) {
+      random = get_random_state(mrb);
+    }
+    mrb_random_rand_seed(mrb, random);
+
+    mrb_ary_modify(mrb, mrb_ary_ptr(ary));
+
+    for (i = RARRAY_LEN(ary) - 1; i > 0; i--)  {
+      mrb_int j;
+      mrb_value tmp;
+
+      j = mrb_fixnum(mrb_random_mt_rand(mrb, random, mrb_fixnum_value(RARRAY_LEN(ary))));
+
+      tmp = RARRAY_PTR(ary)[i];
+      mrb_ary_ptr(ary)->ptr[i] = RARRAY_PTR(ary)[j];
+      mrb_ary_ptr(ary)->ptr[j] = tmp;
+    }
+  }
+
+  return ary;
+}
+
+/*
+ *  call-seq:
+ *     ary.shuffle   ->   new_ary
+ *
+ *  Returns a new array with elements of self shuffled.
+ */
+
+static mrb_value
+mrb_ary_shuffle(mrb_state *mrb, mrb_value ary)
+{
+  mrb_value new_ary = mrb_ary_new_from_values(mrb, RARRAY_LEN(ary), RARRAY_PTR(ary));
+  mrb_ary_shuffle_bang(mrb, new_ary);
+
+  return new_ary;
+}
+
+/*
+ *  call-seq:
+ *     ary.sample      ->   obj
+ *     ary.sample(n)   ->   new_ary
+ *
+ *  Choose a random element or +n+ random elements from the array.
+ *
+ *  The elements are chosen by using random and unique indices into the array
+ *  in order to ensure that an element doesn't repeat itself unless the array
+ *  already contained duplicate elements.
+ *
+ *  If the array is empty the first form returns +nil+ and the second form
+ *  returns an empty array.
+ */
+
+static mrb_value
+mrb_ary_sample(mrb_state *mrb, mrb_value ary)
+{
+  mrb_int n = 0;
+  mrb_bool given;
+  mt_state *random = NULL;
+  mrb_int len;
+
+  mrb_get_args(mrb, "|i?d", &n, &given, &random, &mt_state_type);
+  if (random == NULL) {
+    random = get_random_state(mrb);
+  }
+  mrb_random_rand_seed(mrb, random);
+  mt_rand(random);
+  len = RARRAY_LEN(ary);
+  if (!given) {                 /* pick one element */
+    switch (len) {
+    case 0:
+      return mrb_nil_value();
+    case 1:
+      return RARRAY_PTR(ary)[0];
+    default:
+      return RARRAY_PTR(ary)[mt_rand(random) % len];
+    }
+  }
+  else {
+    mrb_value result;
+    mrb_int i, j;
+
+    if (n < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "negative sample number");
+    if (n > len) n = len;
+    result = mrb_ary_new_capa(mrb, n);
+    for (i=0; i<n; i++) {
+      mrb_int r;
+
+      for (;;) {
+      retry:
+        r = mt_rand(random) % len;
+
+        for (j=0; j<i; j++) {
+          if (mrb_fixnum(RARRAY_PTR(result)[j]) == r) {
+            goto retry;         /* retry if duplicate */
+          }
+        }
+        break;
+      }
+      mrb_ary_push(mrb, result, mrb_fixnum_value(r));
+    }
+    for (i=0; i<n; i++) {
+      mrb_ary_set(mrb, result, i, RARRAY_PTR(ary)[mrb_fixnum(RARRAY_PTR(result)[i])]);
+    }
+    return result;
+  }
+}
+
+
+void mrb_mruby_random_gem_init(mrb_state *mrb)
+{
+  struct RClass *random;
+  struct RClass *array = mrb->array_class;
+
+  mrb_define_method(mrb, mrb->kernel_module, "rand", mrb_random_g_rand, MRB_ARGS_OPT(1));
+  mrb_define_method(mrb, mrb->kernel_module, "srand", mrb_random_g_srand, MRB_ARGS_OPT(1));
+
+  random = mrb_define_class(mrb, "Random", mrb->object_class);
+  MRB_SET_INSTANCE_TT(random, MRB_TT_DATA);
+  mrb_define_class_method(mrb, random, "rand", mrb_random_g_rand, MRB_ARGS_OPT(1));
+  mrb_define_class_method(mrb, random, "srand", mrb_random_g_srand, MRB_ARGS_OPT(1));
+
+  mrb_define_method(mrb, random, "initialize", mrb_random_init, MRB_ARGS_OPT(1));
+  mrb_define_method(mrb, random, "rand", mrb_random_rand, MRB_ARGS_OPT(1));
+  mrb_define_method(mrb, random, "srand", mrb_random_srand, MRB_ARGS_OPT(1));
+
+  mrb_define_method(mrb, array, "shuffle", mrb_ary_shuffle, MRB_ARGS_OPT(1));
+  mrb_define_method(mrb, array, "shuffle!", mrb_ary_shuffle_bang, MRB_ARGS_OPT(1));
+  mrb_define_method(mrb, array, "sample", mrb_ary_sample, MRB_ARGS_OPT(2));
+
+  mrb_const_set(mrb, mrb_obj_value(random), mrb_intern_lit(mrb, "DEFAULT"),
+          mrb_obj_new(mrb, random, 0, NULL));
+}
+
+void mrb_mruby_random_gem_final(mrb_state *mrb)
+{
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-random/src/random.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-random/src/random.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-random/src/random.h	(revision 331)
@@ -0,0 +1,12 @@
+/*
+** random.h - Random module
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifndef MRUBY_RANDOM_H
+#define MRUBY_RANDOM_H
+
+void mrb_mruby_random_gem_init(mrb_state *mrb);
+
+#endif
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-random/test/random.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-random/test/random.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-random/test/random.rb	(revision 331)
@@ -0,0 +1,88 @@
+##
+# Random Test
+
+assert("Random#srand") do
+  r1 = Random.new(123)
+  r2 = Random.new(123)
+  r1.rand == r2.rand
+end
+
+assert("Kernel::srand") do
+  srand(234)
+  r1 = rand
+  srand(234)
+  r2 = rand
+  r1 == r2
+end
+
+assert("Random::srand") do
+  Random.srand(345)
+  r1 = rand
+  srand(345)
+  r2 = Random.rand
+  r1 == r2
+end
+
+assert("fixnum") do
+  rand(3).class == Fixnum
+end
+
+assert("float") do
+  rand.class == Float
+end
+
+assert("Array#shuffle") do
+  ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+  shuffled = ary.shuffle
+
+  ary == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and shuffled != ary and 10.times { |x| ary.include? x }
+end
+
+assert('Array#shuffle!') do
+  ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+  ary.shuffle!
+
+  ary != [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and 10.times { |x| ary.include? x }
+end
+
+assert("Array#shuffle(random)") do
+  assert_raise(TypeError) do
+    # this will cause an exception due to the wrong argument
+    [1, 2].shuffle "Not a Random instance"
+  end
+
+  # verify that the same seed causes the same results
+  ary1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+  shuffle1 = ary1.shuffle Random.new 345
+  ary2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+  shuffle2 = ary2.shuffle Random.new 345
+
+  ary1 != shuffle1 and 10.times { |x| shuffle1.include? x } and shuffle1 == shuffle2
+end
+
+assert('Array#shuffle!(random)') do
+  assert_raise(TypeError) do
+    # this will cause an exception due to the wrong argument
+    [1, 2].shuffle! "Not a Random instance"
+  end
+
+  # verify that the same seed causes the same results
+  ary1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+  ary1.shuffle! Random.new 345
+  ary2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+  ary2.shuffle! Random.new 345
+
+  ary1 != [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] and 10.times { |x| ary1.include? x } and ary1 == ary2
+end
+
+assert('Array#sample checks input length after reading arguments') do
+  $ary = [1, 2, 3]
+  class ArrayChange
+    def to_i
+      $ary << 4
+      4
+    end
+  end
+
+  assert_equal [1, 2, 3, 4], $ary.sample(ArrayChange.new).sort
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-range-ext/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-range-ext/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-range-ext/mrbgem.rake	(revision 331)
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-range-ext') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'Range class extension'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-range-ext/mrblib/range.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-range-ext/mrblib/range.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-range-ext/mrblib/range.rb	(revision 331)
@@ -0,0 +1,31 @@
+class Range
+  ##
+  # call-seq:
+  #    rng.first    -> obj
+  #    rng.first(n) -> an_array
+  #
+  # Returns the first object in the range, or an array of the first +n+
+  # elements.
+  #
+  #   (10..20).first     #=> 10
+  #   (10..20).first(3)  #=> [10, 11, 12]
+  #
+  def first(*args)
+    return self.begin if args.empty?
+
+    raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 1)" unless args.length == 1
+    nv = args[0]
+    raise TypeError, "no implicit conversion from nil to integer" if nv.nil?
+    raise TypeError, "no implicit conversion of #{nv.class} into Integer" unless nv.respond_to?(:to_int)
+    n = nv.to_int
+    raise TypeError, "no implicit conversion of #{nv.class} into Integer" unless n.kind_of?(Integer)
+    raise ArgumentError, "negative array size (or size too big)" unless 0 <= n
+    ary = []
+    each do |i|
+      break if n <= 0
+      ary.push(i)
+      n -= 1
+    end
+    ary
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-range-ext/src/range.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-range-ext/src/range.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-range-ext/src/range.c	(revision 331)
@@ -0,0 +1,177 @@
+#include <mruby.h>
+#include <mruby/range.h>
+#include <math.h>
+#include <float.h>
+
+static mrb_bool
+r_le(mrb_state *mrb, mrb_value a, mrb_value b)
+{
+  mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
+  /* output :a < b => -1, a = b =>  0, a > b => +1 */
+
+  if (mrb_fixnum_p(r)) {
+    mrb_int c = mrb_fixnum(r);
+    if (c == 0 || c == -1) return TRUE;
+  }
+
+  return FALSE;
+}
+
+static mrb_bool
+r_lt(mrb_state *mrb, mrb_value a, mrb_value b)
+{
+  mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b);
+  /* output :a < b => -1, a = b =>  0, a > b => +1 */
+
+  return mrb_fixnum_p(r) && mrb_fixnum(r) == -1;
+}
+
+/*
+ *  call-seq:
+ *     rng.cover?(obj)  ->  true or false
+ *
+ *  Returns <code>true</code> if +obj+ is between the begin and end of
+ *  the range.
+ *
+ *  This tests <code>begin <= obj <= end</code> when #exclude_end? is +false+
+ *  and <code>begin <= obj < end</code> when #exclude_end? is +true+.
+ *
+ *     ("a".."z").cover?("c")    #=> true
+ *     ("a".."z").cover?("5")    #=> false
+ *     ("a".."z").cover?("cc")   #=> true
+ */
+static mrb_value
+mrb_range_cover(mrb_state *mrb, mrb_value range)
+{
+  mrb_value val;
+  struct RRange *r = mrb_range_ptr(mrb, range);
+  mrb_value beg, end;
+
+  mrb_get_args(mrb, "o", &val);
+
+  beg = r->edges->beg;
+  end = r->edges->end;
+
+  if (r_le(mrb, beg, val)) {
+    if (r->excl) {
+      if (r_lt(mrb, val, end))
+        return mrb_true_value();
+    }
+    else {
+      if (r_le(mrb, val, end))
+        return mrb_true_value();
+    }
+  }
+
+  return mrb_false_value();
+}
+
+/*
+ *  call-seq:
+ *     rng.last    -> obj
+ *     rng.last(n) -> an_array
+ *
+ *  Returns the last object in the range,
+ *  or an array of the last +n+ elements.
+ *
+ *  Note that with no arguments +last+ will return the object that defines
+ *  the end of the range even if #exclude_end? is +true+.
+ *
+ *    (10..20).last      #=> 20
+ *    (10...20).last     #=> 20
+ *    (10..20).last(3)   #=> [18, 19, 20]
+ *    (10...20).last(3)  #=> [17, 18, 19]
+ */
+static mrb_value
+mrb_range_last(mrb_state *mrb, mrb_value range)
+{
+  mrb_value num;
+  mrb_value array;
+  struct RRange *r = mrb_range_ptr(mrb, range);
+
+  if (mrb_get_args(mrb, "|o", &num) == 0) {
+    return r->edges->end;
+  }
+
+  array = mrb_funcall(mrb, range, "to_a", 0);
+  return mrb_funcall(mrb, array, "last", 1, mrb_to_int(mrb, num));
+}
+
+/*
+ *  call-seq:
+ *     rng.size                   -> num
+ *
+ *  Returns the number of elements in the range. Both the begin and the end of
+ *  the Range must be Numeric, otherwise nil is returned.
+ *
+ *    (10..20).size    #=> 11
+ *    ('a'..'z').size  #=> nil
+ */
+
+static mrb_value
+mrb_range_size(mrb_state *mrb, mrb_value range)
+{
+  struct RRange *r = mrb_range_ptr(mrb, range);
+  mrb_value beg, end;
+  mrb_float beg_f, end_f;
+  mrb_bool num_p = TRUE;
+  mrb_bool excl;
+
+  beg = r->edges->beg;
+  end = r->edges->end;
+  excl = r->excl;
+  if (mrb_fixnum_p(beg)) {
+    beg_f = (mrb_float)mrb_fixnum(beg);
+  }
+  else if (mrb_float_p(beg)) {
+    beg_f = mrb_float(beg);
+  }
+  else {
+    num_p = FALSE;
+  }
+  if (mrb_fixnum_p(end)) {
+    end_f = (mrb_float)mrb_fixnum(end);
+  }
+  else if (mrb_float_p(end)) {
+    end_f = mrb_float(end);
+  }
+  else {
+    num_p = FALSE;
+  }
+  if (num_p) {
+    mrb_float n = end_f - beg_f;
+    mrb_float err = (fabs(beg_f) + fabs(end_f) + fabs(end_f-beg_f)) * MRB_FLOAT_EPSILON;
+
+    if (err>0.5) err=0.5;
+    if (excl) {
+      if (n<=0) return mrb_fixnum_value(0);
+      if (n<1)
+        n = 0;
+      else
+        n = floor(n - err);
+    }
+    else {
+      if (n<0) return mrb_fixnum_value(0);
+      n = floor(n + err);
+    }
+    if (isinf(n+1))
+      return mrb_float_value(mrb, INFINITY);
+    return mrb_fixnum_value((mrb_int)n+1);
+  }
+  return mrb_nil_value();
+}
+
+void
+mrb_mruby_range_ext_gem_init(mrb_state* mrb)
+{
+  struct RClass * s = mrb_class_get(mrb, "Range");
+
+  mrb_define_method(mrb, s, "cover?", mrb_range_cover, MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, s, "last",   mrb_range_last,  MRB_ARGS_OPT(1));
+  mrb_define_method(mrb, s, "size",   mrb_range_size,  MRB_ARGS_NONE());
+}
+
+void
+mrb_mruby_range_ext_gem_final(mrb_state* mrb)
+{
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-range-ext/test/range.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-range-ext/test/range.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-range-ext/test/range.rb	(revision 331)
@@ -0,0 +1,32 @@
+##
+# Range(Ext) Test
+
+assert('Range#cover?') do
+  assert_true ("a".."z").cover?("c")
+  assert_true !("a".."z").cover?("5")
+  assert_true ("a".."z").cover?("cc")
+end
+
+assert('Range#first') do
+  assert_equal 10, (10..20).first
+  assert_equal [10, 11, 12], (10..20).first(3)
+  assert_equal [0, 1, 2], (0..Float::INFINITY).first(3)
+end
+
+assert('Range#last') do
+  assert_equal 20, (10..20).last
+  assert_equal 20, (10...20).last
+  assert_equal [18, 19, 20], (10..20).last(3)
+  assert_equal [17, 18, 19], (10...20).last(3)
+end
+
+assert('Range#size') do
+  assert_equal 42, (1..42).size
+  assert_equal 41, (1...42).size
+  assert_equal 6, (1...6.3).size
+  assert_equal 5, (1...6.0).size
+  assert_equal 5, (1.1...6).size
+  assert_equal 15, (1.0..15.9).size
+  assert_equal Float::INFINITY, (0..Float::INFINITY).size
+  assert_nil ('a'..'z').size
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-sprintf/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-sprintf/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-sprintf/mrbgem.rake	(revision 331)
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-sprintf') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'standard Kernel#sprintf method'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-sprintf/mrblib/string.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-sprintf/mrblib/string.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-sprintf/mrblib/string.rb	(revision 331)
@@ -0,0 +1,9 @@
+class String
+  def %(args)
+    if args.is_a? Array
+      sprintf(self, *args)
+    else
+      sprintf(self, args)
+    end
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-sprintf/src/kernel.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-sprintf/src/kernel.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-sprintf/src/kernel.c	(revision 331)
@@ -0,0 +1,30 @@
+/*
+** kernel.c - Kernel module suppliment
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <mruby.h>
+
+mrb_value mrb_f_sprintf(mrb_state *mrb, mrb_value obj); /* in sprintf.c */
+
+void
+mrb_mruby_sprintf_gem_init(mrb_state* mrb)
+{
+  struct RClass *krn;
+
+  if (mrb->kernel_module == NULL) {
+    mrb->kernel_module = mrb_define_module(mrb, "Kernel"); /* Might be PARANOID. */
+  }
+  krn = mrb->kernel_module;
+
+  mrb_define_method(mrb, krn, "sprintf", mrb_f_sprintf, MRB_ARGS_ANY());
+  mrb_define_method(mrb, krn, "format",  mrb_f_sprintf, MRB_ARGS_ANY());
+}
+
+void
+mrb_mruby_sprintf_gem_final(mrb_state* mrb)
+{
+  /* nothing to do. */
+}
+
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-sprintf/src/sprintf.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-sprintf/src/sprintf.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-sprintf/src/sprintf.c	(revision 331)
@@ -0,0 +1,1123 @@
+/*
+** sprintf.c - Kernel.#sprintf
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <mruby.h>
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <mruby/string.h>
+#include <mruby/hash.h>
+#include <mruby/numeric.h>
+#include <math.h>
+#include <ctype.h>
+
+#define BIT_DIGITS(N)   (((N)*146)/485 + 1)  /* log2(10) =~ 146/485 */
+#define BITSPERDIG MRB_INT_BIT
+#define EXTENDSIGN(n, l) (((~0U << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0U << (n)))
+
+mrb_value mrb_str_format(mrb_state *, int, const mrb_value *, mrb_value);
+static void fmt_setup(char*,size_t,int,int,mrb_int,mrb_int);
+
+static char*
+remove_sign_bits(char *str, int base)
+{
+  char *t;
+
+  t = str;
+  if (base == 16) {
+    while (*t == 'f') {
+      t++;
+    }
+  }
+  else if (base == 8) {
+    *t |= EXTENDSIGN(3, strlen(t));
+    while (*t == '7') {
+      t++;
+    }
+  }
+  else if (base == 2) {
+    while (*t == '1') {
+      t++;
+    }
+  }
+
+  return t;
+}
+
+static char
+sign_bits(int base, const char *p)
+{
+  char c;
+
+  switch (base) {
+  case 16:
+    if (*p == 'X') c = 'F';
+    else c = 'f';
+    break;
+  case 8:
+    c = '7'; break;
+  case 2:
+    c = '1'; break;
+  default:
+    c = '.'; break;
+  }
+  return c;
+}
+
+static mrb_value
+mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base)
+{
+  char buf[66], *b = buf + sizeof buf;
+  mrb_int num = mrb_fixnum(x);
+  uint64_t val = (uint64_t)num;
+  char d;
+
+  if (base != 2) {
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %S", mrb_fixnum_value(base));
+  }
+  if (val == 0) {
+    return mrb_str_new_lit(mrb, "0");
+  }
+  *--b = '\0';
+  do {
+    *--b = mrb_digitmap[(int)(val % base)];
+  } while (val /= base);
+
+  if (num < 0) {
+    b = remove_sign_bits(b, base);
+    switch (base) {
+    case 16: d = 'f'; break;
+    case 8:  d = '7'; break;
+    case 2:  d = '1'; break;
+    default: d = 0;   break;
+    }
+
+    if (d && *b != d) {
+      *--b = d;
+    }
+  }
+
+  return mrb_str_new_cstr(mrb, b);
+}
+
+#define FNONE  0
+#define FSHARP 1
+#define FMINUS 2
+#define FPLUS  4
+#define FZERO  8
+#define FSPACE 16
+#define FWIDTH 32
+#define FPREC  64
+#define FPREC0 128
+
+#define CHECK(l) do {\
+/*  int cr = ENC_CODERANGE(result);*/\
+  while ((l) >= bsiz - blen) {\
+    bsiz*=2;\
+    if (bsiz < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "too big specifier"); \
+  }\
+  mrb_str_resize(mrb, result, bsiz);\
+/*  ENC_CODERANGE_SET(result, cr);*/\
+  buf = RSTRING_PTR(result);\
+} while (0)
+
+#define PUSH(s, l) do { \
+  CHECK(l);\
+  memcpy(&buf[blen], s, l);\
+  blen += (l);\
+} while (0)
+
+#define FILL(c, l) do { \
+  CHECK(l);\
+  memset(&buf[blen], c, l);\
+  blen += (l);\
+} while (0)
+
+static void
+check_next_arg(mrb_state *mrb, int posarg, int nextarg)
+{
+  switch (posarg) {
+  case -1:
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with numbered", mrb_fixnum_value(nextarg));
+    break;
+  case -2:
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with named", mrb_fixnum_value(nextarg));
+    break;
+  default:
+    break;
+  }
+}
+
+static void
+check_pos_arg(mrb_state *mrb, int posarg, int n)
+{
+  if (posarg > 0) {
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after unnumbered(%S)",
+               mrb_fixnum_value(n), mrb_fixnum_value(posarg));
+  }
+  if (posarg == -2) {
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after named", mrb_fixnum_value(n));
+  }
+  if (n < 1) {
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid index - %S$", mrb_fixnum_value(n));
+  }
+}
+
+static void
+check_name_arg(mrb_state *mrb, int posarg, const char *name, int len)
+{
+  if (posarg > 0) {
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after unnumbered(%S)",
+               mrb_str_new(mrb, (name), (len)), mrb_fixnum_value(posarg));
+  }
+  if (posarg == -1) {
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after numbered", mrb_str_new(mrb, (name), (len)));
+  }
+}
+
+#define GETNEXTARG() (\
+  check_next_arg(mrb, posarg, nextarg),\
+  (posarg = nextarg++, GETNTHARG(posarg)))
+
+#define GETARG() (!mrb_undef_p(nextvalue) ? nextvalue : GETNEXTARG())
+
+#define GETPOSARG(n) (\
+  check_pos_arg(mrb, posarg, n),\
+  (posarg = -1, GETNTHARG(n)))
+
+#define GETNTHARG(nth) \
+  ((nth >= argc) ? (mrb_raise(mrb, E_ARGUMENT_ERROR, "too few arguments"), mrb_undef_value()) : argv[nth])
+
+#define GETNAMEARG(id, name, len) (\
+  check_name_arg(mrb, posarg, name, len),\
+  (posarg = -2, mrb_hash_fetch(mrb, get_hash(mrb, &hash, argc, argv), id, mrb_undef_value())))
+
+#define GETNUM(n, val) \
+  for (; p < end && ISDIGIT(*p); p++) {\
+    int next_n = 10 * n + (*p - '0'); \
+    if (next_n / 10 != n) {\
+      mrb_raise(mrb, E_ARGUMENT_ERROR, #val " too big"); \
+    } \
+    n = next_n; \
+  } \
+  if (p >= end) { \
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed format string - %*[0-9]"); \
+  }
+
+#define GETASTER(num) do { \
+  mrb_value tmp_v; \
+  t = p++; \
+  n = 0; \
+  GETNUM(n, val); \
+  if (*p == '$') { \
+    tmp_v = GETPOSARG(n); \
+  } \
+  else { \
+    tmp_v = GETNEXTARG(); \
+    p = t; \
+  } \
+  num = mrb_int(mrb, tmp_v); \
+} while (0)
+
+static mrb_value
+get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv)
+{
+  mrb_value tmp;
+
+  if (!mrb_undef_p(*hash)) return *hash;
+  if (argc != 2) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "one hash required");
+  }
+  tmp = mrb_check_convert_type(mrb, argv[1], MRB_TT_HASH, "Hash", "to_hash");
+  if (mrb_nil_p(tmp)) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "one hash required");
+  }
+  return (*hash = tmp);
+}
+
+/*
+ *  call-seq:
+ *     format(format_string [, arguments...] )   -> string
+ *     sprintf(format_string [, arguments...] )  -> string
+ *
+ *  Returns the string resulting from applying <i>format_string</i> to
+ *  any additional arguments.  Within the format string, any characters
+ *  other than format sequences are copied to the result.
+ *
+ *  The syntax of a format sequence is follows.
+ *
+ *    %[flags][width][.precision]type
+ *
+ *  A format
+ *  sequence consists of a percent sign, followed by optional flags,
+ *  width, and precision indicators, then terminated with a field type
+ *  character.  The field type controls how the corresponding
+ *  <code>sprintf</code> argument is to be interpreted, while the flags
+ *  modify that interpretation.
+ *
+ *  The field type characters are:
+ *
+ *      Field |  Integer Format
+ *      ------+--------------------------------------------------------------
+ *        b   | Convert argument as a binary number.
+ *            | Negative numbers will be displayed as a two's complement
+ *            | prefixed with '..1'.
+ *        B   | Equivalent to 'b', but uses an uppercase 0B for prefix
+ *            | in the alternative format by #.
+ *        d   | Convert argument as a decimal number.
+ *        i   | Identical to 'd'.
+ *        o   | Convert argument as an octal number.
+ *            | Negative numbers will be displayed as a two's complement
+ *            | prefixed with '..7'.
+ *        u   | Identical to 'd'.
+ *        x   | Convert argument as a hexadecimal number.
+ *            | Negative numbers will be displayed as a two's complement
+ *            | prefixed with '..f' (representing an infinite string of
+ *            | leading 'ff's).
+ *        X   | Equivalent to 'x', but uses uppercase letters.
+ *
+ *      Field |  Float Format
+ *      ------+--------------------------------------------------------------
+ *        e   | Convert floating point argument into exponential notation
+ *            | with one digit before the decimal point as [-]d.dddddde[+-]dd.
+ *            | The precision specifies the number of digits after the decimal
+ *            | point (defaulting to six).
+ *        E   | Equivalent to 'e', but uses an uppercase E to indicate
+ *            | the exponent.
+ *        f   | Convert floating point argument as [-]ddd.dddddd,
+ *            | where the precision specifies the number of digits after
+ *            | the decimal point.
+ *        g   | Convert a floating point number using exponential form
+ *            | if the exponent is less than -4 or greater than or
+ *            | equal to the precision, or in dd.dddd form otherwise.
+ *            | The precision specifies the number of significant digits.
+ *        G   | Equivalent to 'g', but use an uppercase 'E' in exponent form.
+ *        a   | Convert floating point argument as [-]0xh.hhhhp[+-]dd,
+ *            | which is consisted from optional sign, "0x", fraction part
+ *            | as hexadecimal, "p", and exponential part as decimal.
+ *        A   | Equivalent to 'a', but use uppercase 'X' and 'P'.
+ *
+ *      Field |  Other Format
+ *      ------+--------------------------------------------------------------
+ *        c   | Argument is the numeric code for a single character or
+ *            | a single character string itself.
+ *        p   | The valuing of argument.inspect.
+ *        s   | Argument is a string to be substituted.  If the format
+ *            | sequence contains a precision, at most that many characters
+ *            | will be copied.
+ *        %   | A percent sign itself will be displayed.  No argument taken.
+ *
+ *  The flags modifies the behavior of the formats.
+ *  The flag characters are:
+ *
+ *    Flag     | Applies to    | Meaning
+ *    ---------+---------------+-----------------------------------------
+ *    space    | bBdiouxX      | Leave a space at the start of
+ *             | aAeEfgG       | non-negative numbers.
+ *             | (numeric fmt) | For 'o', 'x', 'X', 'b' and 'B', use
+ *             |               | a minus sign with absolute value for
+ *             |               | negative values.
+ *    ---------+---------------+-----------------------------------------
+ *    (digit)$ | all           | Specifies the absolute argument number
+ *             |               | for this field.  Absolute and relative
+ *             |               | argument numbers cannot be mixed in a
+ *             |               | sprintf string.
+ *    ---------+---------------+-----------------------------------------
+ *     #       | bBoxX         | Use an alternative format.
+ *             | aAeEfgG       | For the conversions 'o', increase the precision
+ *             |               | until the first digit will be '0' if
+ *             |               | it is not formatted as complements.
+ *             |               | For the conversions 'x', 'X', 'b' and 'B'
+ *             |               | on non-zero, prefix the result with "0x",
+ *             |               | "0X", "0b" and "0B", respectively.
+ *             |               | For 'a', 'A', 'e', 'E', 'f', 'g', and 'G',
+ *             |               | force a decimal point to be added,
+ *             |               | even if no digits follow.
+ *             |               | For 'g' and 'G', do not remove trailing zeros.
+ *    ---------+---------------+-----------------------------------------
+ *    +        | bBdiouxX      | Add a leading plus sign to non-negative
+ *             | aAeEfgG       | numbers.
+ *             | (numeric fmt) | For 'o', 'x', 'X', 'b' and 'B', use
+ *             |               | a minus sign with absolute value for
+ *             |               | negative values.
+ *    ---------+---------------+-----------------------------------------
+ *    -        | all           | Left-justify the result of this conversion.
+ *    ---------+---------------+-----------------------------------------
+ *    0 (zero) | bBdiouxX      | Pad with zeros, not spaces.
+ *             | aAeEfgG       | For 'o', 'x', 'X', 'b' and 'B', radix-1
+ *             | (numeric fmt) | is used for negative numbers formatted as
+ *             |               | complements.
+ *    ---------+---------------+-----------------------------------------
+ *    *        | all           | Use the next argument as the field width.
+ *             |               | If negative, left-justify the result. If the
+ *             |               | asterisk is followed by a number and a dollar
+ *             |               | sign, use the indicated argument as the width.
+ *
+ *  Examples of flags:
+ *
+ *   # '+' and space flag specifies the sign of non-negative numbers.
+ *   sprintf("%d", 123)  #=> "123"
+ *   sprintf("%+d", 123) #=> "+123"
+ *   sprintf("% d", 123) #=> " 123"
+ *
+ *   # '#' flag for 'o' increases number of digits to show '0'.
+ *   # '+' and space flag changes format of negative numbers.
+ *   sprintf("%o", 123)   #=> "173"
+ *   sprintf("%#o", 123)  #=> "0173"
+ *   sprintf("%+o", -123) #=> "-173"
+ *   sprintf("%o", -123)  #=> "..7605"
+ *   sprintf("%#o", -123) #=> "..7605"
+ *
+ *   # '#' flag for 'x' add a prefix '0x' for non-zero numbers.
+ *   # '+' and space flag disables complements for negative numbers.
+ *   sprintf("%x", 123)   #=> "7b"
+ *   sprintf("%#x", 123)  #=> "0x7b"
+ *   sprintf("%+x", -123) #=> "-7b"
+ *   sprintf("%x", -123)  #=> "..f85"
+ *   sprintf("%#x", -123) #=> "0x..f85"
+ *   sprintf("%#x", 0)    #=> "0"
+ *
+ *   # '#' for 'X' uses the prefix '0X'.
+ *   sprintf("%X", 123)  #=> "7B"
+ *   sprintf("%#X", 123) #=> "0X7B"
+ *
+ *   # '#' flag for 'b' add a prefix '0b' for non-zero numbers.
+ *   # '+' and space flag disables complements for negative numbers.
+ *   sprintf("%b", 123)   #=> "1111011"
+ *   sprintf("%#b", 123)  #=> "0b1111011"
+ *   sprintf("%+b", -123) #=> "-1111011"
+ *   sprintf("%b", -123)  #=> "..10000101"
+ *   sprintf("%#b", -123) #=> "0b..10000101"
+ *   sprintf("%#b", 0)    #=> "0"
+ *
+ *   # '#' for 'B' uses the prefix '0B'.
+ *   sprintf("%B", 123)  #=> "1111011"
+ *   sprintf("%#B", 123) #=> "0B1111011"
+ *
+ *   # '#' for 'e' forces to show the decimal point.
+ *   sprintf("%.0e", 1)  #=> "1e+00"
+ *   sprintf("%#.0e", 1) #=> "1.e+00"
+ *
+ *   # '#' for 'f' forces to show the decimal point.
+ *   sprintf("%.0f", 1234)  #=> "1234"
+ *   sprintf("%#.0f", 1234) #=> "1234."
+ *
+ *   # '#' for 'g' forces to show the decimal point.
+ *   # It also disables stripping lowest zeros.
+ *   sprintf("%g", 123.4)   #=> "123.4"
+ *   sprintf("%#g", 123.4)  #=> "123.400"
+ *   sprintf("%g", 123456)  #=> "123456"
+ *   sprintf("%#g", 123456) #=> "123456."
+ *
+ *  The field width is an optional integer, followed optionally by a
+ *  period and a precision.  The width specifies the minimum number of
+ *  characters that will be written to the result for this field.
+ *
+ *  Examples of width:
+ *
+ *   # padding is done by spaces,       width=20
+ *   # 0 or radix-1.             <------------------>
+ *   sprintf("%20d", 123)   #=> "                 123"
+ *   sprintf("%+20d", 123)  #=> "                +123"
+ *   sprintf("%020d", 123)  #=> "00000000000000000123"
+ *   sprintf("%+020d", 123) #=> "+0000000000000000123"
+ *   sprintf("% 020d", 123) #=> " 0000000000000000123"
+ *   sprintf("%-20d", 123)  #=> "123                 "
+ *   sprintf("%-+20d", 123) #=> "+123                "
+ *   sprintf("%- 20d", 123) #=> " 123                "
+ *   sprintf("%020x", -123) #=> "..ffffffffffffffff85"
+ *
+ *  For
+ *  numeric fields, the precision controls the number of decimal places
+ *  displayed.  For string fields, the precision determines the maximum
+ *  number of characters to be copied from the string.  (Thus, the format
+ *  sequence <code>%10.10s</code> will always contribute exactly ten
+ *  characters to the result.)
+ *
+ *  Examples of precisions:
+ *
+ *   # precision for 'd', 'o', 'x' and 'b' is
+ *   # minimum number of digits               <------>
+ *   sprintf("%20.8d", 123)  #=> "            00000123"
+ *   sprintf("%20.8o", 123)  #=> "            00000173"
+ *   sprintf("%20.8x", 123)  #=> "            0000007b"
+ *   sprintf("%20.8b", 123)  #=> "            01111011"
+ *   sprintf("%20.8d", -123) #=> "           -00000123"
+ *   sprintf("%20.8o", -123) #=> "            ..777605"
+ *   sprintf("%20.8x", -123) #=> "            ..ffff85"
+ *   sprintf("%20.8b", -11)  #=> "            ..110101"
+ *
+ *   # "0x" and "0b" for '#x' and '#b' is not counted for
+ *   # precision but "0" for '#o' is counted.  <------>
+ *   sprintf("%#20.8d", 123)  #=> "            00000123"
+ *   sprintf("%#20.8o", 123)  #=> "            00000173"
+ *   sprintf("%#20.8x", 123)  #=> "          0x0000007b"
+ *   sprintf("%#20.8b", 123)  #=> "          0b01111011"
+ *   sprintf("%#20.8d", -123) #=> "           -00000123"
+ *   sprintf("%#20.8o", -123) #=> "            ..777605"
+ *   sprintf("%#20.8x", -123) #=> "          0x..ffff85"
+ *   sprintf("%#20.8b", -11)  #=> "          0b..110101"
+ *
+ *   # precision for 'e' is number of
+ *   # digits after the decimal point           <------>
+ *   sprintf("%20.8e", 1234.56789) #=> "      1.23456789e+03"
+ *
+ *   # precision for 'f' is number of
+ *   # digits after the decimal point               <------>
+ *   sprintf("%20.8f", 1234.56789) #=> "       1234.56789000"
+ *
+ *   # precision for 'g' is number of
+ *   # significant digits                          <------->
+ *   sprintf("%20.8g", 1234.56789) #=> "           1234.5679"
+ *
+ *   #                                         <------->
+ *   sprintf("%20.8g", 123456789)  #=> "       1.2345679e+08"
+ *
+ *   # precision for 's' is
+ *   # maximum number of characters                    <------>
+ *   sprintf("%20.8s", "string test") #=> "            string t"
+ *
+ *  Examples:
+ *
+ *     sprintf("%d %04x", 123, 123)               #=> "123 007b"
+ *     sprintf("%08b '%4s'", 123, 123)            #=> "01111011 ' 123'"
+ *     sprintf("%1$*2$s %2$d %1$s", "hello", 8)   #=> "   hello 8 hello"
+ *     sprintf("%1$*2$s %2$d", "hello", -8)       #=> "hello    -8"
+ *     sprintf("%+g:% g:%-g", 1.23, 1.23, 1.23)   #=> "+1.23: 1.23:1.23"
+ *     sprintf("%u", -123)                        #=> "-123"
+ *
+ *  For more complex formatting, Ruby supports a reference by name.
+ *  %<name>s style uses format style, but %{name} style doesn't.
+ *
+ *  Exapmles:
+ *    sprintf("%<foo>d : %<bar>f", { :foo => 1, :bar => 2 })
+ *      #=> 1 : 2.000000
+ *    sprintf("%{foo}f", { :foo => 1 })
+ *      # => "1f"
+ */
+
+mrb_value
+mrb_f_sprintf(mrb_state *mrb, mrb_value obj)
+{
+  mrb_int argc;
+  mrb_value *argv;
+
+  mrb_get_args(mrb, "*", &argv, &argc);
+
+  if (argc <= 0) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "too few arguments");
+    return mrb_nil_value();
+  }
+  else {
+    return mrb_str_format(mrb, argc - 1, argv + 1, argv[0]);
+  }
+}
+
+mrb_value
+mrb_str_format(mrb_state *mrb, int argc, const mrb_value *argv, mrb_value fmt)
+{
+  const char *p, *end;
+  char *buf;
+  mrb_int blen;
+  mrb_int bsiz;
+  mrb_value result;
+  mrb_int n;
+  mrb_int width;
+  mrb_int prec;
+  int flags = FNONE;
+  int nextarg = 1;
+  int posarg = 0;
+  mrb_value nextvalue;
+  mrb_value str;
+  mrb_value hash = mrb_undef_value();
+
+#define CHECK_FOR_WIDTH(f)                                                  \
+  if ((f) & FWIDTH) {                                                       \
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "width given twice");         \
+  }                                                                         \
+  if ((f) & FPREC0) {                                                       \
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "width after precision");     \
+  }
+#define CHECK_FOR_FLAGS(f)                                                  \
+  if ((f) & FWIDTH) {                                                       \
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "flag after width");          \
+  }                                                                         \
+  if ((f) & FPREC0) {                                                       \
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "flag after precision");      \
+  }
+
+  ++argc;
+  --argv;
+  fmt = mrb_str_to_str(mrb, fmt);
+  p = RSTRING_PTR(fmt);
+  end = p + RSTRING_LEN(fmt);
+  blen = 0;
+  bsiz = 120;
+  result = mrb_str_buf_new(mrb, bsiz);
+  buf = RSTRING_PTR(result);
+  memset(buf, 0, bsiz);
+
+  for (; p < end; p++) {
+    const char *t;
+    mrb_sym id = 0;
+
+    for (t = p; t < end && *t != '%'; t++) ;
+    if (t + 1 == end) ++t;
+    PUSH(p, t - p);
+    if (t >= end)
+      goto sprint_exit; /* end of fmt string */
+
+    p = t + 1;    /* skip '%' */
+
+    width = prec = -1;
+    nextvalue = mrb_undef_value();
+
+retry:
+    switch (*p) {
+      default:
+        mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed format string - \\%%S", mrb_str_new(mrb, p, 1));
+        break;
+
+      case ' ':
+        CHECK_FOR_FLAGS(flags);
+        flags |= FSPACE;
+        p++;
+        goto retry;
+
+      case '#':
+        CHECK_FOR_FLAGS(flags);
+        flags |= FSHARP;
+        p++;
+        goto retry;
+
+      case '+':
+        CHECK_FOR_FLAGS(flags);
+        flags |= FPLUS;
+        p++;
+        goto retry;
+
+      case '-':
+        CHECK_FOR_FLAGS(flags);
+        flags |= FMINUS;
+        p++;
+        goto retry;
+
+      case '0':
+        CHECK_FOR_FLAGS(flags);
+        flags |= FZERO;
+        p++;
+        goto retry;
+
+      case '1': case '2': case '3': case '4':
+      case '5': case '6': case '7': case '8': case '9':
+        n = 0;
+        GETNUM(n, width);
+        if (*p == '$') {
+          if (!mrb_undef_p(nextvalue)) {
+            mrb_raisef(mrb, E_ARGUMENT_ERROR, "value given twice - %S$", mrb_fixnum_value(n));
+          }
+          nextvalue = GETPOSARG(n);
+          p++;
+          goto retry;
+        }
+        CHECK_FOR_WIDTH(flags);
+        width = n;
+        flags |= FWIDTH;
+        goto retry;
+
+      case '<':
+      case '{': {
+        const char *start = p;
+        char term = (*p == '<') ? '>' : '}';
+        mrb_value symname;
+
+        for (; p < end && *p != term; )
+          p++;
+        if (id) {
+          mrb_raisef(mrb, E_ARGUMENT_ERROR, "name%S after <%S>",
+                     mrb_str_new(mrb, start, p - start + 1), mrb_sym2str(mrb, id));
+        }
+        symname = mrb_str_new(mrb, start + 1, p - start - 1);
+        id = mrb_intern_str(mrb, symname);
+        nextvalue = GETNAMEARG(mrb_symbol_value(id), start, (int)(p - start + 1));
+        if (mrb_undef_p(nextvalue)) {
+          mrb_raisef(mrb, E_KEY_ERROR, "key%S not found", mrb_str_new(mrb, start, p - start + 1));
+        }
+        if (term == '}') goto format_s;
+        p++;
+        goto retry;
+      }
+
+      case '*':
+        CHECK_FOR_WIDTH(flags);
+        flags |= FWIDTH;
+        GETASTER(width);
+        if (width < 0) {
+          flags |= FMINUS;
+          width = -width;
+        }
+        p++;
+        goto retry;
+
+      case '.':
+        if (flags & FPREC0) {
+          mrb_raise(mrb, E_ARGUMENT_ERROR, "precision given twice");
+        }
+        flags |= FPREC|FPREC0;
+
+        prec = 0;
+        p++;
+        if (*p == '*') {
+          GETASTER(prec);
+          if (prec < 0) {  /* ignore negative precision */
+            flags &= ~FPREC;
+          }
+          p++;
+          goto retry;
+        }
+
+        GETNUM(prec, precision);
+        goto retry;
+
+      case '\n':
+      case '\0':
+        p--;
+        /* fallthrough */
+      case '%':
+        if (flags != FNONE) {
+          mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format character - %");
+        }
+        PUSH("%", 1);
+        break;
+
+      case 'c': {
+        mrb_value val = GETARG();
+        mrb_value tmp;
+        char *c;
+
+        tmp = mrb_check_string_type(mrb, val);
+        if (!mrb_nil_p(tmp)) {
+          if (mrb_fixnum(mrb_funcall(mrb, tmp, "size", 0)) != 1 ) {
+            mrb_raise(mrb, E_ARGUMENT_ERROR, "%c requires a character");
+          }
+        }
+        else if (mrb_fixnum_p(val)) {
+          tmp = mrb_funcall(mrb, val, "chr", 0);
+        }
+        else {
+          mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid character");
+        }
+        mrb_check_type(mrb, tmp, MRB_TT_STRING);
+        c = RSTRING_PTR(tmp);
+        n = RSTRING_LEN(tmp);
+        if (!(flags & FWIDTH)) {
+          PUSH(c, n);
+        }
+        else if ((flags & FMINUS)) {
+          PUSH(c, n);
+          if (width>0) FILL(' ', width-1);
+        }
+        else {
+          if (width>0) FILL(' ', width-1);
+          PUSH(c, n);
+        }
+      }
+      break;
+
+      case 's':
+      case 'p':
+  format_s:
+      {
+        mrb_value arg = GETARG();
+        mrb_int len;
+        mrb_int slen;
+
+        if (*p == 'p') arg = mrb_inspect(mrb, arg);
+        str = mrb_obj_as_string(mrb, arg);
+        len = RSTRING_LEN(str);
+        if (RSTRING(result)->flags & MRB_STR_EMBED) {
+          mrb_int tmp_n = len;
+          RSTRING(result)->flags &= ~MRB_STR_EMBED_LEN_MASK;
+          RSTRING(result)->flags |= tmp_n << MRB_STR_EMBED_LEN_SHIFT;
+        }
+        else {
+          RSTRING(result)->as.heap.len = blen;
+        }
+        if (flags&(FPREC|FWIDTH)) {
+          slen = RSTRING_LEN(str);
+          if (slen < 0) {
+            mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid mbstring sequence");
+          }
+          if ((flags&FPREC) && (prec < slen)) {
+            char *p = RSTRING_PTR(str) + prec;
+            slen = prec;
+            len = p - RSTRING_PTR(str);
+          }
+          /* need to adjust multi-byte string pos */
+          if ((flags&FWIDTH) && (width > slen)) {
+            width -= (int)slen;
+            if (!(flags&FMINUS)) {
+              FILL(' ', width);
+            }
+            PUSH(RSTRING_PTR(str), len);
+            if (flags&FMINUS) {
+              FILL(' ', width);
+            }
+            break;
+          }
+        }
+        PUSH(RSTRING_PTR(str), len);
+      }
+      break;
+
+      case 'd':
+      case 'i':
+      case 'o':
+      case 'x':
+      case 'X':
+      case 'b':
+      case 'B':
+      case 'u': {
+        mrb_value val = GETARG();
+        char nbuf[68], *s;
+        const char *prefix = NULL;
+        int sign = 0, dots = 0;
+        char sc = 0;
+        mrb_int v = 0;
+        int base;
+        mrb_int len;
+
+        switch (*p) {
+          case 'd':
+          case 'i':
+            sign = 1; break;
+          default:
+            break;
+        }
+        if (flags & FSHARP) {
+          switch (*p) {
+            case 'o': prefix = "0"; break;
+            case 'x': prefix = "0x"; break;
+            case 'X': prefix = "0X"; break;
+            case 'b': prefix = "0b"; break;
+            case 'B': prefix = "0B"; break;
+            default: break;
+          }
+        }
+
+  bin_retry:
+        switch (mrb_type(val)) {
+          case MRB_TT_FLOAT:
+            val = mrb_flo_to_fixnum(mrb, val);
+            if (mrb_fixnum_p(val)) goto bin_retry;
+            break;
+          case MRB_TT_STRING:
+            val = mrb_str_to_inum(mrb, val, 0, TRUE);
+            goto bin_retry;
+          case MRB_TT_FIXNUM:
+            v = mrb_fixnum(val);
+            break;
+          default:
+            val = mrb_Integer(mrb, val);
+            goto bin_retry;
+        }
+
+        switch (*p) {
+          case 'o':
+            base = 8; break;
+          case 'x':
+          case 'X':
+            base = 16; break;
+          case 'b':
+          case 'B':
+            base = 2; break;
+          case 'u':
+          case 'd':
+          case 'i':
+          default:
+            base = 10; break;
+        }
+
+        if (base == 2) {
+          if (v < 0 && !sign) {
+            val = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base);
+            dots = 1;
+          }
+          else {
+            val = mrb_fixnum_to_str(mrb, mrb_fixnum_value(v), base);
+          }
+        }
+        if (sign) {
+          if (v > 0) {
+            if (flags & FPLUS) {
+              sc = '+';
+              width--;
+            }
+            else if (flags & FSPACE) {
+              sc = ' ';
+              width--;
+            }
+          }
+          switch (base) {
+          case 2:
+            strncpy(nbuf, RSTRING_PTR(val), sizeof(nbuf));
+            break;
+          case 8:
+            snprintf(nbuf, sizeof(nbuf), "%" MRB_PRIo, v);
+            break;
+          case 10:
+            snprintf(nbuf, sizeof(nbuf), "%" MRB_PRId, v);
+            break;
+          case 16:
+            snprintf(nbuf, sizeof(nbuf), "%" MRB_PRIx, v);
+            break;
+          }
+          s = nbuf;
+        }
+        else {
+          s = nbuf;
+          if (base != 10 && v < 0) {
+            dots = 1;
+          }
+          switch (base) {
+          case 2:
+            strncpy(++s, RSTRING_PTR(val), sizeof(nbuf)-1);
+            break;
+          case 8:
+            snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRIo, v);
+            break;
+          case 10:
+            snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRId, v);
+            break;
+          case 16:
+            snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRIx, v);
+            break;
+          }
+          if (v < 0) {
+            char d;
+
+            s = remove_sign_bits(s, base);
+            switch (base) {
+              case 16: d = 'f'; break;
+              case 8:  d = '7'; break;
+              case 2:  d = '1'; break;
+              default: d = 0; break;
+            }
+
+            if (d && *s != d) {
+              *--s = d;
+            }
+          }
+        }
+        {
+          size_t size;
+          size = strlen(s);
+          /* PARANOID: assert(size <= MRB_INT_MAX) */
+          len = (mrb_int)size;
+        }
+
+        if (dots) {
+          prec -= 2;
+          width -= 2;
+        }
+
+        if (*p == 'X') {
+          char *pp = s;
+          int c;
+          while ((c = (int)(unsigned char)*pp) != 0) {
+            *pp = toupper(c);
+            pp++;
+          }
+        }
+
+        if (prefix && !prefix[1]) { /* octal */
+          if (dots) {
+            prefix = NULL;
+          }
+          else if (len == 1 && *s == '0') {
+            len = 0;
+            if (flags & FPREC) prec--;
+          }
+          else if ((flags & FPREC) && (prec > len)) {
+            prefix = NULL;
+          }
+        }
+        else if (len == 1 && *s == '0') {
+          prefix = NULL;
+        }
+
+        if (prefix) {
+          size_t size;
+          size = strlen(prefix);
+          /* PARANOID: assert(size <= MRB_INT_MAX).
+           *  this check is absolutely paranoid. */
+          width -= (mrb_int)size;
+        }
+
+        if ((flags & (FZERO|FMINUS|FPREC)) == FZERO) {
+          prec = width;
+          width = 0;
+        }
+        else {
+          if (prec < len) {
+            if (!prefix && prec == 0 && len == 1 && *s == '0') len = 0;
+            prec = len;
+          }
+          width -= prec;
+        }
+
+        if (!(flags&FMINUS) && width > 0) {
+          FILL(' ', width);
+        }
+
+        if (sc) PUSH(&sc, 1);
+
+        if (prefix) {
+          int plen = (int)strlen(prefix);
+          PUSH(prefix, plen);
+        }
+        if (dots) PUSH("..", 2);
+
+        if (prec > len) {
+          CHECK(prec - len);
+          if (v < 0) {
+            char c = sign_bits(base, p);
+            FILL(c, prec - len);
+          }
+          else if ((flags & (FMINUS|FPREC)) != FMINUS) {
+            char c = '0';
+            FILL(c, prec - len);
+          }
+        }
+        PUSH(s, len);
+        if (width > 0) {
+          FILL(' ', width);
+        }
+      }
+      break;
+
+      case 'f':
+      case 'g':
+      case 'G':
+      case 'e':
+      case 'E':
+      case 'a':
+      case 'A': {
+        mrb_value val = GETARG();
+        double fval;
+        int i, need = 6;
+        char fbuf[32];
+
+        fval = mrb_float(mrb_Float(mrb, val));
+        if (!isfinite(fval)) {
+          const char *expr;
+          const int elen = 3;
+          char sign = '\0';
+
+          if (isnan(fval)) {
+            expr = "NaN";
+          }
+          else {
+            expr = "Inf";
+          }
+          need = elen;
+          if (!isnan(fval) && fval < 0.0)
+            sign = '-';
+          else if (flags & (FPLUS|FSPACE))
+            sign = (flags & FPLUS) ? '+' : ' ';
+          if (sign)
+	    ++need;
+          if ((flags & FWIDTH) && need < width)
+            need = width;
+
+          if (need < 0) {
+            mrb_raise(mrb, E_ARGUMENT_ERROR, "width too big");
+          }
+          FILL(' ', need);
+          if (flags & FMINUS) {
+            if (sign)
+              buf[blen - need--] = sign;
+            memcpy(&buf[blen - need], expr, elen);
+          }
+          else {
+            if (sign)
+              buf[blen - elen - 1] = sign;
+            memcpy(&buf[blen - elen], expr, elen);
+          }
+          break;
+        }
+
+        fmt_setup(fbuf, sizeof(fbuf), *p, flags, width, prec);
+        need = 0;
+        if (*p != 'e' && *p != 'E') {
+          i = INT_MIN;
+          frexp(fval, &i);
+          if (i > 0)
+            need = BIT_DIGITS(i);
+        }
+        need += (flags&FPREC) ? prec : 6;
+        if ((flags&FWIDTH) && need < width)
+          need = width;
+        need += 20;
+        if (need <= 0) {
+          mrb_raise(mrb, E_ARGUMENT_ERROR,
+                    (width > prec ? "width too big" : "prec too big"));
+        }
+
+        CHECK(need);
+        n = snprintf(&buf[blen], need, fbuf, fval);
+        if (n < 0) {
+          mrb_raise(mrb, E_RUNTIME_ERROR, "formatting error");
+        }
+        blen += n;
+      }
+      break;
+    }
+    flags = FNONE;
+  }
+
+  sprint_exit:
+#if 0
+  /* XXX - We cannot validate the number of arguments if (digit)$ style used.
+   */
+  if (posarg >= 0 && nextarg < argc) {
+    const char *mesg = "too many arguments for format string";
+    if (mrb_test(ruby_debug)) mrb_raise(mrb, E_ARGUMENT_ERROR, mesg);
+    if (mrb_test(ruby_verbose)) mrb_warn(mrb, "%S", mrb_str_new_cstr(mrb, mesg));
+  }
+#endif
+  mrb_str_resize(mrb, result, blen);
+
+  return result;
+}
+
+static void
+fmt_setup(char *buf, size_t size, int c, int flags, mrb_int width, mrb_int prec)
+{
+  char *end = buf + size;
+  int n;
+
+  *buf++ = '%';
+  if (flags & FSHARP) *buf++ = '#';
+  if (flags & FPLUS)  *buf++ = '+';
+  if (flags & FMINUS) *buf++ = '-';
+  if (flags & FZERO)  *buf++ = '0';
+  if (flags & FSPACE) *buf++ = ' ';
+
+  if (flags & FWIDTH) {
+    n = snprintf(buf, end - buf, "%d", (int)width);
+    buf += n;
+  }
+
+  if (flags & FPREC) {
+    n = snprintf(buf, end - buf, ".%d", (int)prec);
+    buf += n;
+  }
+
+  *buf++ = c;
+  *buf = '\0';
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-sprintf/test/sprintf.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-sprintf/test/sprintf.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-sprintf/test/sprintf.rb	(revision 331)
@@ -0,0 +1,103 @@
+#assert('Kernel.sprintf') do
+#end
+
+assert('String#%') do
+  assert_equal "one=1", "one=%d" % 1
+  assert_equal "1 one 1.0", "%d %s %3.1f" % [ 1, "one", 1.01 ]
+  assert_equal "123 < 456", "%{num} < %<str>s" % { num: 123, str: "456" }
+  assert_equal 15, ("%b" % (1<<14)).size
+end
+
+assert('String#% with inf') do
+  inf = Float::INFINITY
+
+  assert_equal "Inf", "%f" % inf
+  assert_equal "Inf", "%2f" % inf
+  assert_equal "Inf", "%3f" % inf
+  assert_equal " Inf", "%4f" % inf
+  assert_equal "  Inf", "%5f" % inf
+
+  assert_equal "+Inf", "%+f" % inf
+  assert_equal "+Inf", "%+2f" % inf
+  assert_equal "+Inf", "%+3f" % inf
+  assert_equal "+Inf", "%+4f" % inf
+  assert_equal " +Inf", "%+5f" % inf
+
+  assert_equal "Inf", "%-f" % inf
+  assert_equal "Inf", "%-2f" % inf
+  assert_equal "Inf", "%-3f" % inf
+  assert_equal "Inf ", "%-4f" % inf
+  assert_equal "Inf  ", "%-5f" % inf
+
+  assert_equal " Inf", "% f" % inf
+  assert_equal " Inf", "% 2f" % inf
+  assert_equal " Inf", "% 3f" % inf
+  assert_equal " Inf", "% 4f" % inf
+  assert_equal "  Inf", "% 5f" % inf
+end
+
+assert('String#% with nan') do
+  nan = Float::NAN
+
+  assert_equal "NaN", "%f" % nan
+  assert_equal "NaN", "%2f" % nan
+  assert_equal "NaN", "%3f" % nan
+  assert_equal " NaN", "%4f" % nan
+  assert_equal "  NaN", "%5f" % nan
+
+  assert_equal "+NaN", "%+f" % nan
+  assert_equal "+NaN", "%+2f" % nan
+  assert_equal "+NaN", "%+3f" % nan
+  assert_equal "+NaN", "%+4f" % nan
+  assert_equal " +NaN", "%+5f" % nan
+
+  assert_equal "NaN", "%-f" % nan
+  assert_equal "NaN", "%-2f" % nan
+  assert_equal "NaN", "%-3f" % nan
+  assert_equal "NaN ", "%-4f" % nan
+  assert_equal "NaN  ", "%-5f" % nan
+
+  assert_equal " NaN", "% f" % nan
+  assert_equal " NaN", "% 2f" % nan
+  assert_equal " NaN", "% 3f" % nan
+  assert_equal " NaN", "% 4f" % nan
+  assert_equal "  NaN", "% 5f" % nan
+end
+
+assert("String#% with invalid chr") do
+  begin
+    class Fixnum
+      alias_method :chr_, :chr if method_defined?(:chr)
+
+      def chr
+        nil
+      end
+    end
+
+    assert_raise TypeError do
+      "%c" % 0
+    end
+  ensure
+    class Fixnum
+      if method_defined?(:chr_)
+        alias_method :chr, :chr_
+        remove_method :chr_
+      end
+    end
+  end
+end
+
+assert("String#% %b") do
+  assert_equal("..10115", "%0b5" % -5)
+end
+
+assert("String#% invalid format") do
+  assert_raise ArgumentError do
+    "%?" % ""
+  end
+end
+
+assert("String#% invalid format shared substring") do
+  fmt = ("x"*30+"%!")[0...-1]
+  assert_equal fmt, sprintf(fmt, "")
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-string-ext/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-string-ext/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-string-ext/mrbgem.rake	(revision 331)
@@ -0,0 +1,6 @@
+MRuby::Gem::Specification.new('mruby-string-ext') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'String class extension'
+  spec.add_test_dependency 'mruby-enumerator', core: 'mruby-enumerator'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-string-ext/mrblib/string.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-string-ext/mrblib/string.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-string-ext/mrblib/string.rb	(revision 331)
@@ -0,0 +1,355 @@
+class String
+
+  ##
+  #  call-seq:
+  #     String.try_convert(obj) -> string or nil
+  #
+  # Try to convert <i>obj</i> into a String, using to_str method.
+  # Returns converted string or nil if <i>obj</i> cannot be converted
+  # for any reason.
+  #
+  #     String.try_convert("str")     #=> "str"
+  #     String.try_convert(/re/)      #=> nil
+  #
+  def self.try_convert(obj)
+    if obj.respond_to?(:to_str)
+      obj.to_str
+    else
+      nil
+    end
+  end
+
+  ##
+  # call-seq:
+  #    string.clear    ->  string
+  #
+  # Makes string empty.
+  #
+  #    a = "abcde"
+  #    a.clear    #=> ""
+  #
+  def clear
+    self.replace("")
+  end
+
+  ##
+  # call-seq:
+  #    str.lstrip   -> new_str
+  #
+  # Returns a copy of <i>str</i> with leading whitespace removed. See also
+  # <code>String#rstrip</code> and <code>String#strip</code>.
+  #
+  #    "  hello  ".lstrip   #=> "hello  "
+  #    "hello".lstrip       #=> "hello"
+  #
+  def lstrip
+    a = 0
+    z = self.size - 1
+    a += 1 while a <= z and " \f\n\r\t\v".include?(self[a])
+    (z >= 0) ? self[a..z] : ""
+  end
+
+  ##
+  # call-seq:
+  #    str.rstrip   -> new_str
+  #
+  # Returns a copy of <i>str</i> with trailing whitespace removed. See also
+  # <code>String#lstrip</code> and <code>String#strip</code>.
+  #
+  #    "  hello  ".rstrip   #=> "  hello"
+  #    "hello".rstrip       #=> "hello"
+  #
+  def rstrip
+    a = 0
+    z = self.size - 1
+    z -= 1 while a <= z and " \f\n\r\t\v\0".include?(self[z])
+    (z >= 0) ? self[a..z] : ""
+  end
+
+  ##
+  # call-seq:
+  #    str.strip   -> new_str
+  #
+  # Returns a copy of <i>str</i> with leading and trailing whitespace removed.
+  #
+  #    "    hello    ".strip   #=> "hello"
+  #    "\tgoodbye\r\n".strip   #=> "goodbye"
+  #
+  def strip
+    a = 0
+    z = self.size - 1
+    a += 1 while a <= z and " \f\n\r\t\v".include?(self[a])
+    z -= 1 while a <= z and " \f\n\r\t\v\0".include?(self[z])
+    (z >= 0) ? self[a..z] : ""
+  end
+
+  ##
+  # call-seq:
+  #    str.lstrip!   -> self or nil
+  #
+  # Removes leading whitespace from <i>str</i>, returning <code>nil</code> if no
+  # change was made. See also <code>String#rstrip!</code> and
+  # <code>String#strip!</code>.
+  #
+  #    "  hello  ".lstrip   #=> "hello  "
+  #    "hello".lstrip!      #=> nil
+  #
+  def lstrip!
+    raise RuntimeError, "can't modify frozen String" if frozen?
+    s = self.lstrip
+    (s == self) ? nil : self.replace(s)
+  end
+
+  ##
+  # call-seq:
+  #    str.rstrip!   -> self or nil
+  #
+  # Removes trailing whitespace from <i>str</i>, returning <code>nil</code> if
+  # no change was made. See also <code>String#lstrip!</code> and
+  # <code>String#strip!</code>.
+  #
+  #    "  hello  ".rstrip   #=> "  hello"
+  #    "hello".rstrip!      #=> nil
+  #
+  def rstrip!
+    raise RuntimeError, "can't modify frozen String" if frozen?
+    s = self.rstrip
+    (s == self) ? nil : self.replace(s)
+  end
+
+  ##
+  #  call-seq:
+  #     str.strip!   -> str or nil
+  #
+  #  Removes leading and trailing whitespace from <i>str</i>. Returns
+  #  <code>nil</code> if <i>str</i> was not altered.
+  #
+  def strip!
+    raise RuntimeError, "can't modify frozen String" if frozen?
+    s = self.strip
+    (s == self) ? nil : self.replace(s)
+  end
+
+  ##
+  # call-seq:
+  #    str.casecmp(other_str)   -> -1, 0, +1 or nil
+  #
+  # Case-insensitive version of <code>String#<=></code>.
+  #
+  #    "abcdef".casecmp("abcde")     #=> 1
+  #    "aBcDeF".casecmp("abcdef")    #=> 0
+  #    "abcdef".casecmp("abcdefg")   #=> -1
+  #    "abcdef".casecmp("ABCDEF")    #=> 0
+  #
+  def casecmp(str)
+    self.downcase <=> str.to_str.downcase
+  rescue NoMethodError
+    raise TypeError, "no implicit conversion of #{str.class} into String"
+  end
+
+  def partition(sep)
+    raise TypeError, "type mismatch: #{sep.class} given" unless sep.is_a? String
+    n = index(sep)
+    unless n.nil?
+      m = n + sep.size
+      [ slice(0, n), sep, slice(m, size - m) ]
+    else
+      [ self, "", "" ]
+    end
+  end
+
+  def rpartition(sep)
+    raise TypeError, "type mismatch: #{sep.class} given" unless sep.is_a? String
+    n = rindex(sep)
+    unless n.nil?
+      m = n + sep.size
+      [ slice(0, n), sep, slice(m, size - m) ]
+    else
+      [ "", "", self ]
+    end
+  end
+
+  ##
+  # call-seq:
+  #    str.slice!(fixnum)           -> new_str or nil
+  #    str.slice!(fixnum, fixnum)   -> new_str or nil
+  #    str.slice!(range)            -> new_str or nil
+  #    str.slice!(other_str)        -> new_str or nil
+  #
+  # Deletes the specified portion from <i>str</i>, and returns the portion
+  # deleted.
+  #
+  #    string = "this is a string"
+  #    string.slice!(2)        #=> "i"
+  #    string.slice!(3..6)     #=> " is "
+  #    string.slice!("r")      #=> "r"
+  #    string                  #=> "thsa sting"
+  #
+  def slice!(arg1, arg2=nil)
+    raise RuntimeError, "can't modify frozen String" if frozen?
+    raise "wrong number of arguments (for 1..2)" if arg1.nil? && arg2.nil?
+
+    if !arg1.nil? && !arg2.nil?
+      idx = arg1
+      idx += self.size if arg1 < 0
+      if idx >= 0 && idx <= self.size && arg2 > 0
+        str = self[idx, arg2]
+      else
+        return nil
+      end
+    else
+      validated = false
+      if arg1.kind_of?(Range)
+        beg = arg1.begin
+        ed = arg1.end
+        beg += self.size if beg < 0
+        ed += self.size if ed < 0
+        ed -= 1 if arg1.exclude_end?
+        validated = true
+      elsif arg1.kind_of?(String)
+        validated = true
+      else
+        idx = arg1
+        idx += self.size if arg1 < 0
+        validated = true if idx >=0 && arg1 < self.size
+      end
+      if validated
+        str = self[arg1]
+      else
+        return nil
+      end
+    end
+    unless str.nil? || str == ""
+      if !arg1.nil? && !arg2.nil?
+        idx = arg1 >= 0 ? arg1 : self.size+arg1
+        str2 = self[0...idx] + self[idx+arg2..-1].to_s
+      else
+        if arg1.kind_of?(Range)
+          idx = beg >= 0 ? beg : self.size+beg
+          idx2 = ed>= 0 ? ed : self.size+ed
+          str2 = self[0...idx] + self[idx2+1..-1].to_s
+        elsif arg1.kind_of?(String)
+          idx = self.index(arg1)
+          str2 = self[0...idx] + self[idx+arg1.size..-1] unless idx.nil?
+        else
+          idx = arg1 >= 0 ? arg1 : self.size+arg1
+          str2 = self[0...idx] + self[idx+1..-1].to_s
+        end
+      end
+      self.replace(str2) unless str2.nil?
+    end
+    str
+  end
+
+  ##
+  #  call-seq:
+  #     str.insert(index, other_str)   -> str
+  #
+  #  Inserts <i>other_str</i> before the character at the given
+  #  <i>index</i>, modifying <i>str</i>. Negative indices count from the
+  #  end of the string, and insert <em>after</em> the given character.
+  #  The intent is insert <i>aString</i> so that it starts at the given
+  #  <i>index</i>.
+  #
+  #     "abcd".insert(0, 'X')    #=> "Xabcd"
+  #     "abcd".insert(3, 'X')    #=> "abcXd"
+  #     "abcd".insert(4, 'X')    #=> "abcdX"
+  #     "abcd".insert(-3, 'X')   #=> "abXcd"
+  #     "abcd".insert(-1, 'X')   #=> "abcdX"
+  #
+  def insert(idx, str)
+    if idx == -1
+      return self << str
+    elsif idx < 0
+      idx += 1
+    end
+    self[idx, 0] = str
+    self
+  end
+
+  ##
+  #  call-seq:
+  #     str.ljust(integer, padstr=' ')   -> new_str
+  #
+  #  If <i>integer</i> is greater than the length of <i>str</i>, returns a new
+  #  <code>String</code> of length <i>integer</i> with <i>str</i> left justified
+  #  and padded with <i>padstr</i>; otherwise, returns <i>str</i>.
+  #
+  #     "hello".ljust(4)            #=> "hello"
+  #     "hello".ljust(20)           #=> "hello               "
+  #     "hello".ljust(20, '1234')   #=> "hello123412341234123"
+  def ljust(idx, padstr = ' ')
+    raise ArgumentError, 'zero width padding' if padstr == ''
+    return self if idx <= self.size
+    pad_repetitions = (idx / padstr.length).ceil
+    padding = (padstr * pad_repetitions)[0...(idx - self.length)]
+    self + padding
+  end
+
+  ##
+  #  call-seq:
+  #     str.rjust(integer, padstr=' ')   -> new_str
+  #
+  #  If <i>integer</i> is greater than the length of <i>str</i>, returns a new
+  #  <code>String</code> of length <i>integer</i> with <i>str</i> right justified
+  #  and padded with <i>padstr</i>; otherwise, returns <i>str</i>.
+  #
+  #     "hello".rjust(4)            #=> "hello"
+  #     "hello".rjust(20)           #=> "               hello"
+  #     "hello".rjust(20, '1234')   #=> "123412341234123hello"
+  def rjust(idx, padstr = ' ')
+    raise ArgumentError, 'zero width padding' if padstr == ''
+    return self if idx <= self.size
+    pad_repetitions = (idx / padstr.length).ceil
+    padding = (padstr * pad_repetitions)[0...(idx - self.length)]
+    padding + self
+  end
+
+  def chars(&block)
+    if block_given?
+      self.split('').each do |i|
+        block.call(i)
+      end
+      self
+    else
+      self.split('')
+    end
+  end
+
+  def each_char(&block)
+    return to_enum :each_char unless block
+
+    split('').each do |i|
+      block.call(i)
+    end
+    self
+  end
+
+  def codepoints(&block)
+    len = self.size
+
+    if block_given?
+      self.split('').each do|x|
+        block.call(x.ord)
+      end
+      self
+    else
+      self.split('').map{|x| x.ord}
+    end
+  end
+  alias each_codepoint codepoints
+
+  ##
+  # call-seq:
+  #    str.prepend(other_str)  -> str
+  #
+  # Prepend---Prepend the given string to <i>str</i>.
+  #
+  #    a = "world"
+  #    a.prepend("hello ") #=> "hello world"
+  #    a                   #=> "hello world"
+  def prepend(arg)
+    self[0, 0] = arg
+    self
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-string-ext/src/string.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-string-ext/src/string.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-string-ext/src/string.c	(revision 331)
@@ -0,0 +1,677 @@
+#include <string.h>
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/class.h>
+#include <mruby/string.h>
+#include <mruby/range.h>
+
+static mrb_value
+mrb_str_getbyte(mrb_state *mrb, mrb_value str)
+{
+  mrb_int pos;
+  mrb_get_args(mrb, "i", &pos);
+
+  if (pos < 0)
+    pos += RSTRING_LEN(str);
+  if (pos < 0 ||  RSTRING_LEN(str) <= pos)
+    return mrb_nil_value();
+
+  return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[pos]);
+}
+
+static mrb_value
+mrb_str_setbyte(mrb_state *mrb, mrb_value str)
+{
+  mrb_int pos, byte;
+  long len;
+
+  mrb_get_args(mrb, "ii", &pos, &byte);
+
+  len = RSTRING_LEN(str);
+  if (pos < -len || len <= pos)
+    mrb_raisef(mrb, E_INDEX_ERROR, "index %S is out of array", mrb_fixnum_value(pos));
+  if (pos < 0)
+    pos += len;
+
+  mrb_str_modify(mrb, mrb_str_ptr(str));
+  byte &= 0xff;
+  RSTRING_PTR(str)[pos] = byte;
+  return mrb_fixnum_value((unsigned char)byte);
+}
+
+static mrb_value
+mrb_str_byteslice(mrb_state *mrb, mrb_value str)
+{
+  mrb_value a1;
+  mrb_int len;
+  int argc;
+
+  argc = mrb_get_args(mrb, "o|i", &a1, &len);
+  if (argc == 2) {
+    return mrb_str_substr(mrb, str, mrb_fixnum(a1), len);
+  }
+  switch (mrb_type(a1)) {
+  case MRB_TT_RANGE:
+    {
+      mrb_int beg;
+
+      len = RSTRING_LEN(str);
+      switch (mrb_range_beg_len(mrb, a1, &beg, &len, len, TRUE)) {
+      case 0:                   /* not range */
+        break;
+      case 1:                   /* range */
+        return mrb_str_substr(mrb, str, beg, len);
+      case 2:                   /* out of range */
+        mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", a1);
+        break;
+      }
+      return mrb_nil_value();
+    }
+  case MRB_TT_FLOAT:
+    a1 = mrb_fixnum_value((mrb_int)mrb_float(a1));
+    /* fall through */
+  case MRB_TT_FIXNUM:
+    return mrb_str_substr(mrb, str, mrb_fixnum(a1), 1);
+  default:
+    mrb_raise(mrb, E_TYPE_ERROR, "wrong type of argument");
+  }
+  /* not reached */
+  return mrb_nil_value();
+}
+
+/*
+ *  call-seq:
+ *     str.swapcase!   -> str or nil
+ *
+ *  Equivalent to <code>String#swapcase</code>, but modifies the receiver in
+ *  place, returning <i>str</i>, or <code>nil</code> if no changes were made.
+ *  Note: case conversion is effective only in ASCII region.
+ */
+static mrb_value
+mrb_str_swapcase_bang(mrb_state *mrb, mrb_value str)
+{
+  char *p, *pend;
+  int modify = 0;
+  struct RString *s = mrb_str_ptr(str);
+
+  mrb_str_modify(mrb, s);
+  p = RSTRING_PTR(str);
+  pend = p + RSTRING_LEN(str);
+  while (p < pend) {
+    if (ISUPPER(*p)) {
+      *p = TOLOWER(*p);
+      modify = 1;
+    }
+    else if (ISLOWER(*p)) {
+      *p = TOUPPER(*p);
+      modify = 1;
+    }
+    p++;
+  }
+
+  if (modify) return str;
+  return mrb_nil_value();
+}
+
+/*
+ *  call-seq:
+ *     str.swapcase   -> new_str
+ *
+ *  Returns a copy of <i>str</i> with uppercase alphabetic characters converted
+ *  to lowercase and lowercase characters converted to uppercase.
+ *  Note: case conversion is effective only in ASCII region.
+ *
+ *     "Hello".swapcase          #=> "hELLO"
+ *     "cYbEr_PuNk11".swapcase   #=> "CyBeR_pUnK11"
+ */
+static mrb_value
+mrb_str_swapcase(mrb_state *mrb, mrb_value self)
+{
+  mrb_value str;
+
+  str = mrb_str_dup(mrb, self);
+  mrb_str_swapcase_bang(mrb, str);
+  return str;
+}
+
+static mrb_value mrb_fixnum_chr(mrb_state *mrb, mrb_value num);
+
+/*
+ *  call-seq:
+ *     str << integer       -> str
+ *     str.concat(integer)  -> str
+ *     str << obj           -> str
+ *     str.concat(obj)      -> str
+ *
+ *  Append---Concatenates the given object to <i>str</i>. If the object is a
+ *  <code>Integer</code>, it is considered as a codepoint, and is converted
+ *  to a character before concatenation.
+ *
+ *     a = "hello "
+ *     a << "world"   #=> "hello world"
+ *     a.concat(33)   #=> "hello world!"
+ */
+static mrb_value
+mrb_str_concat2(mrb_state *mrb, mrb_value self)
+{
+  mrb_value str;
+
+  mrb_get_args(mrb, "o", &str);
+  if (mrb_fixnum_p(str))
+    str = mrb_fixnum_chr(mrb, str);
+  else
+    str = mrb_string_type(mrb, str);
+  mrb_str_concat(mrb, self, str);
+  return self;
+}
+
+/*
+ *  call-seq:
+ *     str.start_with?([prefixes]+)   -> true or false
+ *
+ *  Returns true if +str+ starts with one of the +prefixes+ given.
+ *
+ *    "hello".start_with?("hell")               #=> true
+ *
+ *    # returns true if one of the prefixes matches.
+ *    "hello".start_with?("heaven", "hell")     #=> true
+ *    "hello".start_with?("heaven", "paradise") #=> false
+ *    "h".start_with?("heaven", "hell")         #=> false
+ */
+static mrb_value
+mrb_str_start_with(mrb_state *mrb, mrb_value self)
+{
+  mrb_value *argv, sub;
+  mrb_int argc, i;
+  mrb_get_args(mrb, "*", &argv, &argc);
+
+  for (i = 0; i < argc; i++) {
+    size_t len_l, len_r;
+    int ai = mrb_gc_arena_save(mrb);
+    sub = mrb_string_type(mrb, argv[i]);
+    mrb_gc_arena_restore(mrb, ai);
+    len_l = RSTRING_LEN(self);
+    len_r = RSTRING_LEN(sub);
+    if (len_l >= len_r) {
+      if (memcmp(RSTRING_PTR(self), RSTRING_PTR(sub), len_r) == 0) {
+        return mrb_true_value();
+      }
+    }
+  }
+  return mrb_false_value();
+}
+
+/*
+ *  call-seq:
+ *     str.end_with?([suffixes]+)   -> true or false
+ *
+ *  Returns true if +str+ ends with one of the +suffixes+ given.
+ */
+static mrb_value
+mrb_str_end_with(mrb_state *mrb, mrb_value self)
+{
+  mrb_value *argv, sub;
+  mrb_int argc, i;
+  mrb_get_args(mrb, "*", &argv, &argc);
+
+  for (i = 0; i < argc; i++) {
+    size_t len_l, len_r;
+    int ai = mrb_gc_arena_save(mrb);
+    sub = mrb_string_type(mrb, argv[i]);
+    mrb_gc_arena_restore(mrb, ai);
+    len_l = RSTRING_LEN(self);
+    len_r = RSTRING_LEN(sub);
+    if (len_l >= len_r) {
+      if (memcmp(RSTRING_PTR(self) + (len_l - len_r),
+                 RSTRING_PTR(sub),
+                 len_r) == 0) {
+        return mrb_true_value();
+      }
+    }
+  }
+  return mrb_false_value();
+}
+
+static mrb_value
+mrb_str_hex(mrb_state *mrb, mrb_value self)
+{
+  return mrb_str_to_inum(mrb, self, 16, FALSE);
+}
+
+static mrb_value
+mrb_str_oct(mrb_state *mrb, mrb_value self)
+{
+  return mrb_str_to_inum(mrb, self, 8, FALSE);
+}
+
+/*
+ *  call-seq:
+ *     string.chr    ->  string
+ *
+ *  Returns a one-character string at the beginning of the string.
+ *
+ *     a = "abcde"
+ *     a.chr    #=> "a"
+ */
+static mrb_value
+mrb_str_chr(mrb_state *mrb, mrb_value self)
+{
+  return mrb_str_substr(mrb, self, 0, 1);
+}
+
+static mrb_value
+mrb_fixnum_chr(mrb_state *mrb, mrb_value num)
+{
+  mrb_int cp = mrb_fixnum(num);
+#ifdef MRB_UTF8_STRING
+  char utf8[4];
+  mrb_int len;
+
+  if (cp < 0 || 0x10FFFF < cp) {
+    mrb_raisef(mrb, E_RANGE_ERROR, "%S out of char range", num);
+  }
+  if (cp < 0x80) {
+    utf8[0] = (char)cp;
+    len = 1;
+  }
+  else if (cp < 0x800) {
+    utf8[0] = (char)(0xC0 | (cp >> 6));
+    utf8[1] = (char)(0x80 | (cp & 0x3F));
+    len = 2;
+  }
+  else if (cp < 0x10000) {
+    utf8[0] = (char)(0xE0 |  (cp >> 12));
+    utf8[1] = (char)(0x80 | ((cp >>  6) & 0x3F));
+    utf8[2] = (char)(0x80 | ( cp        & 0x3F));
+    len = 3;
+  }
+  else {
+    utf8[0] = (char)(0xF0 |  (cp >> 18));
+    utf8[1] = (char)(0x80 | ((cp >> 12) & 0x3F));
+    utf8[2] = (char)(0x80 | ((cp >>  6) & 0x3F));
+    utf8[3] = (char)(0x80 | ( cp        & 0x3F));
+    len = 4;
+  }
+  return mrb_str_new(mrb, utf8, len);
+#else
+  char c;
+
+  if (cp < 0 || 0xff < cp) {
+    mrb_raisef(mrb, E_RANGE_ERROR, "%S out of char range", num);
+  }
+  c = (char)cp;
+  return mrb_str_new(mrb, &c, 1);
+#endif
+}
+
+/*
+ *  call-seq:
+ *     string.lines    ->  array of string
+ *
+ *  Returns strings per line;
+ *
+ *     a = "abc\ndef"
+ *     a.lines    #=> ["abc\n", "def"]
+ */
+static mrb_value
+mrb_str_lines(mrb_state *mrb, mrb_value self)
+{
+  mrb_value result;
+  mrb_value blk;
+  int ai;
+  mrb_int len;
+  mrb_value arg;
+  char *b = RSTRING_PTR(self);
+  char *p = b, *t;
+  char *e = b + RSTRING_LEN(self);
+
+  mrb_get_args(mrb, "&", &blk);
+
+  result = mrb_ary_new(mrb);
+  ai = mrb_gc_arena_save(mrb);
+  if (!mrb_nil_p(blk)) {
+    while (p < e) {
+      t = p;
+      while (p < e && *p != '\n') p++;
+      if (*p == '\n') p++;
+      len = (mrb_int) (p - t);
+      arg = mrb_str_new(mrb, t, len);
+      mrb_yield_argv(mrb, blk, 1, &arg);
+      mrb_gc_arena_restore(mrb, ai);
+      if (b != RSTRING_PTR(self)) {
+        ptrdiff_t diff = p - b;
+        b = RSTRING_PTR(self);
+        p = b + diff;
+      }
+      e = b + RSTRING_LEN(self);
+    }
+    return self;
+  }
+  while (p < e) {
+    t = p;
+    while (p < e && *p != '\n') p++;
+    if (*p == '\n') p++;
+    len = (mrb_int) (p - t);
+    mrb_ary_push(mrb, result, mrb_str_new(mrb, t, len));
+    mrb_gc_arena_restore(mrb, ai);
+  }
+  return result;
+}
+
+/*
+ *  call-seq:
+ *     string.succ    ->  string
+ *
+ *  Returns next sequence of the string;
+ *
+ *     a = "abc"
+ *     a.succ    #=> "abd"
+ */
+static mrb_value
+mrb_str_succ_bang(mrb_state *mrb, mrb_value self)
+{
+  mrb_value result;
+  unsigned char *p, *e, *b, *t;
+  const char *prepend;
+  struct RString *s = mrb_str_ptr(self);
+  mrb_int l;
+
+  if (RSTRING_LEN(self) == 0)
+    return self;
+
+  mrb_str_modify(mrb, s);
+  l = RSTRING_LEN(self);
+  b = p = (unsigned char*) RSTRING_PTR(self);
+  t = e = p + l;
+  *(e--) = 0;
+
+  // find trailing ascii/number
+  while (e >= b) {
+    if (ISALNUM(*e))
+      break;
+    e--;
+  }
+  if (e < b) {
+    e = p + l - 1;
+    result = mrb_str_new_lit(mrb, "");
+  }
+  else {
+    // find leading letter of the ascii/number
+    b = e;
+    while (b > p) {
+      if (!ISALNUM(*b) || (ISALNUM(*b) && *b != '9' && *b != 'z' && *b != 'Z'))
+        break;
+      b--;
+    }
+    if (!ISALNUM(*b))
+      b++;
+    result = mrb_str_new(mrb, (char*) p, b - p);
+  }
+
+  while (e >= b) {
+    if (!ISALNUM(*e)) {
+      if (*e == 0xff) {
+        mrb_str_cat_lit(mrb, result, "\x01");
+        (*e) = 0;
+      }
+      else
+        (*e)++;
+      break;
+    }
+    prepend = NULL;
+    if (*e == '9') {
+      if (e == b) prepend = "1";
+      *e = '0';
+    }
+    else if (*e == 'z') {
+      if (e == b) prepend = "a";
+      *e = 'a';
+    }
+    else if (*e == 'Z') {
+      if (e == b) prepend = "A";
+      *e = 'A';
+    }
+    else {
+      (*e)++;
+      break;
+    }
+    if (prepend) mrb_str_cat_cstr(mrb, result, prepend);
+    e--;
+  }
+  result = mrb_str_cat(mrb, result, (char*) b, t - b);
+  l = RSTRING_LEN(result);
+  mrb_str_resize(mrb, self, l);
+  memcpy(RSTRING_PTR(self), RSTRING_PTR(result), l);
+  return self;
+}
+
+static mrb_value
+mrb_str_succ(mrb_state *mrb, mrb_value self)
+{
+  mrb_value str;
+
+  str = mrb_str_dup(mrb, self);
+  mrb_str_succ_bang(mrb, str);
+  return str;
+}
+
+#ifdef MRB_UTF8_STRING
+static const char utf8len_codepage_zero[256] =
+{
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,
+};
+
+static mrb_int
+utf8code(unsigned char* p)
+{
+  mrb_int len;
+
+  if (p[0] < 0x80)
+    return p[0];
+
+  len = utf8len_codepage_zero[p[0]];
+  if (len > 1 && (p[1] & 0xc0) == 0x80) {
+    if (len == 2)
+      return ((p[0] & 0x1f) << 6) + (p[1] & 0x3f);
+    if ((p[2] & 0xc0) == 0x80) {
+      if (len == 3)
+        return ((p[0] & 0x0f) << 12) + ((p[1] & 0x3f) << 6)
+          + (p[2] & 0x3f);
+      if ((p[3] & 0xc0) == 0x80) {
+        if (len == 4)
+          return ((p[0] & 0x07) << 18) + ((p[1] & 0x3f) << 12)
+            + ((p[2] & 0x3f) << 6) + (p[3] & 0x3f);
+        if ((p[4] & 0xc0) == 0x80) {
+          if (len == 5)
+            return ((p[0] & 0x03) << 24) + ((p[1] & 0x3f) << 18)
+              + ((p[2] & 0x3f) << 12) + ((p[3] & 0x3f) << 6)
+              + (p[4] & 0x3f);
+          if ((p[5] & 0xc0) == 0x80 && len == 6)
+            return ((p[0] & 0x01) << 30) + ((p[1] & 0x3f) << 24)
+              + ((p[2] & 0x3f) << 18) + ((p[3] & 0x3f) << 12)
+              + ((p[4] & 0x3f) << 6) + (p[5] & 0x3f);
+        }
+      }
+    }
+  }
+  return p[0];
+}
+
+static mrb_value
+mrb_str_ord(mrb_state* mrb, mrb_value str)
+{
+  if (RSTRING_LEN(str) == 0)
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "empty string");
+  return mrb_fixnum_value(utf8code((unsigned char*) RSTRING_PTR(str)));
+}
+#else
+static mrb_value
+mrb_str_ord(mrb_state* mrb, mrb_value str)
+{
+  if (RSTRING_LEN(str) == 0)
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "empty string");
+  return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[0]);
+}
+#endif
+
+static mrb_bool
+all_digits_p(const char *s, mrb_int len)
+{
+  while (len-- > 0) {
+    if (!ISDIGIT(*s)) return FALSE;
+    s++;
+  }
+  return TRUE;
+}
+
+/*
+ *  call-seq:
+ *     str.upto(other_str, exclusive=false) {|s| block }   -> str
+ *     str.upto(other_str, exclusive=false)                -> an_enumerator
+ *
+ *  Iterates through successive values, starting at <i>str</i> and
+ *  ending at <i>other_str</i> inclusive, passing each value in turn to
+ *  the block. The <code>String#succ</code> method is used to generate
+ *  each value.  If optional second argument exclusive is omitted or is false,
+ *  the last value will be included; otherwise it will be excluded.
+ *
+ *  If no block is given, an enumerator is returned instead.
+ *
+ *     "a8".upto("b6") {|s| print s, ' ' }
+ *     for s in "a8".."b6"
+ *       print s, ' '
+ *     end
+ *
+ *  <em>produces:</em>
+ *
+ *     a8 a9 b0 b1 b2 b3 b4 b5 b6
+ *     a8 a9 b0 b1 b2 b3 b4 b5 b6
+ *
+ *  If <i>str</i> and <i>other_str</i> contains only ascii numeric characters,
+ *  both are recognized as decimal numbers. In addition, the width of
+ *  string (e.g. leading zeros) is handled appropriately.
+ *
+ *     "9".upto("11").to_a   #=> ["9", "10", "11"]
+ *     "25".upto("5").to_a   #=> []
+ *     "07".upto("11").to_a  #=> ["07", "08", "09", "10", "11"]
+ */
+static mrb_value
+mrb_str_upto(mrb_state *mrb, mrb_value beg)
+{
+  mrb_value end;
+  mrb_value exclusive = mrb_false_value();
+  mrb_value block = mrb_nil_value();
+  mrb_value current, after_end;
+  mrb_int n;
+  mrb_bool excl;
+
+  mrb_get_args(mrb, "o|o&", &end, &exclusive, &block);
+
+  if (mrb_nil_p(block)) {
+    return mrb_funcall(mrb, beg, "to_enum", 3, mrb_symbol_value(mrb_intern_lit(mrb, "upto")), end, exclusive);
+  }
+  end = mrb_string_type(mrb, end);
+  excl = mrb_test(exclusive);
+
+  /* single character */
+  if (RSTRING_LEN(beg) == 1 && RSTRING_LEN(end) == 1 &&
+  ISASCII(RSTRING_PTR(beg)[0]) && ISASCII(RSTRING_PTR(end)[0])) {
+    char c = RSTRING_PTR(beg)[0];
+    char e = RSTRING_PTR(end)[0];
+    int ai = mrb_gc_arena_save(mrb);
+
+    if (c > e || (excl && c == e)) return beg;
+    for (;;) {
+      mrb_yield(mrb, block, mrb_str_new(mrb, &c, 1));
+      mrb_gc_arena_restore(mrb, ai);
+      if (!excl && c == e) break;
+      c++;
+      if (excl && c == e) break;
+    }
+    return beg;
+  }
+  /* both edges are all digits */
+  if (ISDIGIT(RSTRING_PTR(beg)[0]) && ISDIGIT(RSTRING_PTR(end)[0]) &&
+      all_digits_p(RSTRING_PTR(beg), RSTRING_LEN(beg)) &&
+      all_digits_p(RSTRING_PTR(end), RSTRING_LEN(end))) {
+    int ai = mrb_gc_arena_save(mrb);
+    mrb_int min_width = RSTRING_LEN(beg);
+    mrb_int max_width = RSTRING_LEN(end);
+    mrb_int bi = mrb_int(mrb, mrb_str_to_inum(mrb, beg, 10, FALSE));
+    mrb_int ei = mrb_int(mrb, mrb_str_to_inum(mrb, end, 10, FALSE));
+    mrb_value str = mrb_str_new(mrb, NULL, max_width);
+    char *buf = RSTRING_PTR(str);
+
+    while (bi <= ei) {
+      if (excl && bi == ei) break;
+      snprintf(buf, max_width+1, "%.*" MRB_PRId, (int)min_width, bi);
+      mrb_yield(mrb, block, mrb_str_new(mrb, buf, strlen(buf)));
+      mrb_gc_arena_restore(mrb, ai);
+      bi++;
+    }
+
+    return beg;
+  }
+  /* normal case */
+  n = mrb_int(mrb, mrb_funcall(mrb, beg, "<=>", 1, end));
+  if (n > 0 || (excl && n == 0)) return beg;
+
+  after_end = mrb_funcall(mrb, end, "succ", 0);
+  current = mrb_str_dup(mrb, beg);
+  while (!mrb_str_equal(mrb, current, after_end)) {
+    int ai = mrb_gc_arena_save(mrb);
+    mrb_value next = mrb_nil_value();
+    if (excl || !mrb_str_equal(mrb, current, end))
+      next = mrb_funcall(mrb, current, "succ", 0);
+    mrb_yield(mrb, block, current);
+    if (mrb_nil_p(next)) break;
+    current = mrb_str_to_str(mrb, next);
+    if (excl && mrb_str_equal(mrb, current, end)) break;
+    if (RSTRING_LEN(current) > RSTRING_LEN(end) || RSTRING_LEN(current) == 0)
+      break;
+    mrb_gc_arena_restore(mrb, ai);
+  }
+
+  return beg;
+}
+
+void
+mrb_mruby_string_ext_gem_init(mrb_state* mrb)
+{
+  struct RClass * s = mrb->string_class;
+
+  mrb_define_method(mrb, s, "dump",            mrb_str_dump,            MRB_ARGS_NONE());
+  mrb_define_method(mrb, s, "getbyte",         mrb_str_getbyte,         MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, s, "setbyte",         mrb_str_setbyte,         MRB_ARGS_REQ(2));
+  mrb_define_method(mrb, s, "byteslice",       mrb_str_byteslice,       MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1));
+  mrb_define_method(mrb, s, "swapcase!",       mrb_str_swapcase_bang,   MRB_ARGS_NONE());
+  mrb_define_method(mrb, s, "swapcase",        mrb_str_swapcase,        MRB_ARGS_NONE());
+  mrb_define_method(mrb, s, "concat",          mrb_str_concat2,         MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, s, "<<",              mrb_str_concat2,         MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, s, "start_with?",     mrb_str_start_with,      MRB_ARGS_REST());
+  mrb_define_method(mrb, s, "end_with?",       mrb_str_end_with,        MRB_ARGS_REST());
+  mrb_define_method(mrb, s, "hex",             mrb_str_hex,             MRB_ARGS_NONE());
+  mrb_define_method(mrb, s, "oct",             mrb_str_oct,             MRB_ARGS_NONE());
+  mrb_define_method(mrb, s, "chr",             mrb_str_chr,             MRB_ARGS_NONE());
+  mrb_define_method(mrb, s, "lines",           mrb_str_lines,           MRB_ARGS_NONE());
+  mrb_define_method(mrb, s, "succ",            mrb_str_succ,            MRB_ARGS_NONE());
+  mrb_define_method(mrb, s, "succ!",           mrb_str_succ_bang,       MRB_ARGS_NONE());
+  mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "next"), mrb_intern_lit(mrb, "succ"));
+  mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "next!"), mrb_intern_lit(mrb, "succ!"));
+  mrb_define_method(mrb, s, "ord", mrb_str_ord, MRB_ARGS_NONE());
+  mrb_define_method(mrb, s, "upto", mrb_str_upto, MRB_ARGS_ANY());
+
+  mrb_define_method(mrb, mrb->fixnum_class, "chr", mrb_fixnum_chr, MRB_ARGS_NONE());
+}
+
+void
+mrb_mruby_string_ext_gem_final(mrb_state* mrb)
+{
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-string-ext/test/string.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-string-ext/test/string.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-string-ext/test/string.rb	(revision 331)
@@ -0,0 +1,667 @@
+##
+# String(Ext) Test
+
+UTF8STRING = ("\343\201\202".size == 1)
+
+assert('String.try_convert') do
+  assert_nil String.try_convert(nil)
+  assert_nil String.try_convert(:foo)
+  assert_equal "", String.try_convert("")
+  assert_equal "1,2,3", String.try_convert("1,2,3")
+end
+
+assert('String#getbyte') do
+  str1 = "hello"
+  bytes1 = [104, 101, 108, 108, 111]
+  assert_equal bytes1[0], str1.getbyte(0)
+  assert_equal bytes1[-1], str1.getbyte(-1)
+  assert_equal bytes1[6], str1.getbyte(6)
+
+  str2 = "\xFF"
+  bytes2 = [0xFF]
+  assert_equal bytes2[0], str2.getbyte(0)
+end
+
+assert('String#setbyte') do
+  str1 = "hello"
+  h = "H".getbyte(0)
+  str1.setbyte(0, h)
+  assert_equal(h, str1.getbyte(0))
+  assert_equal("Hello", str1)
+end
+
+assert("String#setbyte raises IndexError if arg conversion resizes String") do
+  $s = "01234\n"
+  class Tmp
+      def to_i
+          $s.chomp! ''
+          95
+      end
+  end
+  tmp = Tmp.new
+  assert_raise(IndexError) { $s.setbyte(5, tmp) }
+end
+
+assert('String#byteslice') do
+  str1 = "hello"
+  assert_equal("e", str1.byteslice(1))
+  assert_equal("o", str1.byteslice(-1))
+  assert_equal("ell", str1.byteslice(1..3))
+  assert_equal("el", str1.byteslice(1...3))
+end
+
+assert('String#dump') do
+  ("\1" * 100).dump     # should not raise an exception - regress #1210
+  "\0".inspect == "\"\\000\"" and
+  "foo".dump == "\"foo\""
+end
+
+assert('String#strip') do
+  s = "  abc  "
+  "".strip == "" and " \t\r\n\f\v".strip == "" and
+  "\0a\0".strip == "\0a" and
+  "abc".strip     == "abc" and
+  "  abc".strip   == "abc" and
+  "abc  ".strip   == "abc" and
+  "  abc  ".strip == "abc" and
+  s == "  abc  "
+end
+
+assert('String#lstrip') do
+  s = "  abc  "
+  s.lstrip
+  "".lstrip == "" and " \t\r\n\f\v".lstrip == "" and
+  "\0a\0".lstrip == "\0a\0" and
+  "abc".lstrip     == "abc"   and
+  "  abc".lstrip   == "abc"   and
+  "abc  ".lstrip   == "abc  " and
+  "  abc  ".lstrip == "abc  " and
+  s == "  abc  "
+end
+
+assert('String#rstrip') do
+  s = "  abc  "
+  s.rstrip
+  "".rstrip == "" and " \t\r\n\f\v".rstrip == "" and
+  "\0a\0".rstrip == "\0a" and
+  "abc".rstrip     == "abc"   and
+  "  abc".rstrip   == "  abc" and
+  "abc  ".rstrip   == "abc"   and
+  "  abc  ".rstrip == "  abc" and
+  s == "  abc  "
+end
+
+assert('String#strip!') do
+  s = "  abc  "
+  t = "abc"
+  s.strip! == "abc" and s == "abc" and t.strip! == nil
+end
+
+assert('String#lstrip!') do
+  s = "  abc  "
+  t = "abc  "
+  s.lstrip! == "abc  " and s == "abc  " and t.lstrip! == nil
+end
+
+assert('String#rstrip!') do
+  s = "  abc  "
+  t = "  abc"
+  s.rstrip! == "  abc" and s == "  abc" and t.rstrip! == nil
+end
+
+assert('String#swapcase') do
+  assert_equal "hELLO", "Hello".swapcase
+  assert_equal "CyBeR_pUnK11", "cYbEr_PuNk11".swapcase
+end
+
+assert('String#swapcase!') do
+  s = "Hello"
+  t = s.clone
+  t.swapcase!
+  assert_equal s.swapcase, t
+end
+
+assert('String#concat') do
+  assert_equal "Hello World!", "Hello " << "World" << 33
+  assert_equal "Hello World!", "Hello ".concat("World").concat(33)
+
+  o = Object.new
+  def o.to_str
+    "to_str"
+  end
+  assert_equal "hi to_str", "hi " << o
+
+  assert_raise(TypeError) { "".concat(Object.new) }
+end
+
+assert('String#casecmp') do
+  assert_equal 1, "abcdef".casecmp("abcde")
+  assert_equal 0, "aBcDeF".casecmp("abcdef")
+  assert_equal(-1, "abcdef".casecmp("abcdefg"))
+  assert_equal 0, "abcdef".casecmp("ABCDEF")
+  o = Object.new
+  def o.to_str
+    "ABCDEF"
+  end
+  assert_equal 0, "abcdef".casecmp(o)
+end
+
+assert('String#start_with?') do
+  assert_true "hello".start_with?("heaven", "hell")
+  assert_true !"hello".start_with?("heaven", "paradise")
+  assert_true !"h".start_with?("heaven", "hell")
+  assert_raise TypeError do "hello".start_with?(true) end
+end
+
+assert('String#end_with?') do
+  assert_true "string".end_with?("ing", "mng")
+  assert_true !"string".end_with?("str", "tri")
+  assert_true !"ng".end_with?("ing", "mng")
+  assert_raise TypeError do "hello".end_with?(true) end
+end
+
+assert('String#partition') do
+  assert_equal ["a", "x", "axa"], "axaxa".partition("x")
+  assert_equal ["aaaaa", "", ""], "aaaaa".partition("x")
+  assert_equal ["", "", "aaaaa"], "aaaaa".partition("")
+  assert_equal ["", "a", "aaaa"], "aaaaa".partition("a")
+  assert_equal ["aaaa", "b", ""], "aaaab".partition("b")
+  assert_equal ["", "b", "aaaa"], "baaaa".partition("b")
+  assert_equal ["", "", ""],      "".partition("a")
+end
+
+assert('String#rpartition') do
+  assert_equal ["axa", "x", "a"], "axaxa".rpartition("x")
+  assert_equal ["", "", "aaaaa"], "aaaaa".rpartition("x")
+  assert_equal ["aaaaa", "", ""], "aaaaa".rpartition("")
+  assert_equal ["aaaa", "a", ""], "aaaaa".rpartition("a")
+  assert_equal ["aaaa", "b", ""], "aaaab".rpartition("b")
+  assert_equal ["", "b", "aaaa"], "baaaa".rpartition("b")
+  assert_equal ["", "", ""],      "".rpartition("a")
+end
+
+assert('String#hex') do
+  assert_equal 16, "10".hex
+  assert_equal 255, "ff".hex
+  assert_equal 16, "0x10".hex
+  assert_equal (-16), "-0x10".hex
+  assert_equal 0, "xyz".hex
+  assert_equal 16, "10z".hex
+  assert_equal 16, "1_0".hex
+  assert_equal 0, "".hex
+end
+
+assert('String#oct') do
+  assert_equal 8, "10".oct
+  assert_equal 7, "7".oct
+  assert_equal 0, "8".oct
+  assert_equal 0, "9".oct
+  assert_equal 0, "xyz".oct
+  assert_equal 8, "10z".oct
+  assert_equal 8, "1_0".oct
+  assert_equal 8, "010".oct
+  assert_equal (-8), "-10".oct
+end
+
+assert('String#chr') do
+  assert_equal "a", "abcde".chr
+  # test Fixnum#chr as well
+  assert_equal "a", 97.chr
+end
+
+assert('String#lines') do
+  assert_equal ["Hel\n", "lo\n", "World!"], "Hel\nlo\nWorld!".lines
+  assert_equal ["Hel\n", "lo\n", "World!\n"], "Hel\nlo\nWorld!\n".lines
+  assert_equal ["\n", "\n", "\n"], "\n\n\n".lines
+  assert_equal [], "".lines
+end
+
+assert('String#clear') do
+  # embed string
+  s = "foo"
+  assert_equal("", s.clear)
+  assert_equal("", s)
+
+  # not embed string and not shared string
+  s = "foo" * 100
+  a = s
+  assert_equal("", s.clear)
+  assert_equal("", s)
+  assert_equal("", a)
+
+  # shared string
+  s = "foo" * 100
+  a = s[10, 90]                # create shared string
+  assert_equal("", s.clear)    # clear
+  assert_equal("", s)          # s is cleared
+  assert_not_equal("", a)      # a should not be affected
+end
+
+assert('String#slice!') do
+  a = "AooBar"
+  b = a.dup
+  assert_equal "A", a.slice!(0)
+  assert_equal "AooBar", b
+
+  a = "FooBar"
+  assert_equal "r", a.slice!(-1)
+  assert_equal "FooBa", a
+
+  a = "FooBar"
+  assert_nil a.slice!(6)
+  assert_nil a.slice!(-7)
+  assert_equal "FooBar", a
+
+  a = "FooBar"
+  assert_equal "Foo", a.slice!(0, 3)
+  assert_equal "Bar", a
+
+  a = "FooBar"
+  assert_equal "Bar", a.slice!(-3, 3)
+  assert_equal "Foo", a
+
+  a = "FooBar"
+  assert_equal "", a.slice!(6, 2)
+  assert_equal "FooBar", a
+
+  a = "FooBar"
+  assert_nil a.slice!(-7,10)
+  assert_equal "FooBar", a
+
+  a = "FooBar"
+  assert_equal "Foo", a.slice!(0..2)
+  assert_equal "Bar", a
+
+  a = "FooBar"
+  assert_equal "Bar", a.slice!(-3..-1)
+  assert_equal "Foo", a
+
+  a = "FooBar"
+  assert_equal "", a.slice!(6..2)
+  assert_equal "FooBar", a
+
+  a = "FooBar"
+  assert_nil a.slice!(-10..-7)
+  assert_equal "FooBar", a
+
+  a = "FooBar"
+  assert_equal "Foo", a.slice!("Foo")
+  assert_equal "Bar", a
+
+  a = "FooBar"
+  assert_nil a.slice!("xyzzy")
+  assert_equal "FooBar", a
+
+  assert_raise(ArgumentError) { "foo".slice! }
+end
+
+assert('String#succ') do
+  assert_equal "", "".succ
+  assert_equal "1", "0".succ
+  assert_equal "10", "9".succ
+  assert_equal "01", "00".succ
+  assert_equal "a1", "a0".succ
+  assert_equal "A1", "A0".succ
+  assert_equal "10", "09".succ
+  assert_equal "b0", "a9".succ
+  assert_equal "B0", "A9".succ
+
+  assert_equal "b", "a".succ
+  assert_equal "aa", "z".succ
+  assert_equal "ab", "aa".succ
+  assert_equal "Ab", "Aa".succ
+  assert_equal "0b", "0a".succ
+  assert_equal "ba", "az".succ
+  assert_equal "Ba", "Az".succ
+  assert_equal "1a", "0z".succ
+
+  assert_equal "B", "A".succ
+  assert_equal "AA", "Z".succ
+  assert_equal "AB", "AA".succ
+  assert_equal "aB", "aA".succ
+  assert_equal "0B", "0A".succ
+  assert_equal "BA", "AZ".succ
+  assert_equal "bA", "aZ".succ
+  assert_equal "1A", "0Z".succ
+
+  assert_equal ".", "-".succ
+  assert_equal "\x01\x00", "\xff".succ
+  assert_equal "-b", "-a".succ
+  assert_equal "-aa", "-z".succ
+  assert_equal "-a-b-", "-a-a-".succ
+  assert_equal "-b-", "-a-".succ
+  assert_equal "-aa-", "-z-".succ
+  assert_equal "あb", "あa".succ
+  assert_equal "あba", "あaz".succ
+
+  a = ""; a.succ!
+  assert_equal "", a
+  a = "0"; a.succ!
+  assert_equal "1", a
+  a = "9"; a.succ!
+  assert_equal "10", a
+  a = "00"; a.succ!
+  assert_equal "01", a
+  a = "a0"; a.succ!
+  assert_equal "a1", a
+  a = "A0"; a.succ!
+  assert_equal "A1", a
+  a = "09"; a.succ!
+  assert_equal "10", a
+  a = "a9"; a.succ!
+  assert_equal "b0", a
+  a = "A9"; a.succ!
+  assert_equal "B0", a
+
+  a = "a"; a.succ!
+  assert_equal "b", a
+  a = "z"; a.succ!
+  assert_equal "aa", a
+  a = "aa"; a.succ!
+  assert_equal "ab", a
+  a = "Aa"; a.succ!
+  assert_equal "Ab", a
+  a = "0a"; a.succ!
+  assert_equal "0b", a
+  a = "az"; a.succ!
+  assert_equal "ba", a
+  a = "Az"; a.succ!
+  assert_equal "Ba", a
+  a = "0z"; a.succ!
+  assert_equal "1a", a
+
+  a = "A"; a.succ!
+  assert_equal "B", a
+  a = "Z"; a.succ!
+  assert_equal "AA", a
+  a = "AA"; a.succ!
+  assert_equal "AB", a
+  a = "aA"; a.succ!
+  assert_equal "aB", a
+  a = "0A"; a.succ!
+  assert_equal "0B", a
+  a = "AZ"; a.succ!
+  assert_equal "BA", a
+  a = "aZ"; a.succ!
+  assert_equal "bA", a
+  a = "0Z"; a.succ!
+  assert_equal "1A", a
+
+  a = "-"; a.succ!
+  assert_equal ".", a
+  a = "\xff"; a.succ!
+  assert_equal "\x01\x00", a
+  a = "-a"; a.succ!
+  assert_equal "-b", a
+  a = "-z"; a.succ!
+  assert_equal "-aa", a
+  a = "-a-a-"; a.succ!
+  assert_equal "-a-b-", a
+  a = "-a-"; a.succ!
+  assert_equal "-b-", a
+  a = "-z-"; a.succ!
+  assert_equal "-aa-", a
+  a = "あb"; a.succ!
+  assert_equal "あc", a
+  a = "あaz"; a.succ!
+  assert_equal "あba", a
+end
+
+assert('String#next') do
+  assert_equal "01", "00".next
+
+  a = "00"; a.next!
+  assert_equal "01", a
+end
+
+assert('String#insert') do
+  assert_equal "Xabcd", "abcd".insert(0, 'X')
+  assert_equal "abcXd", "abcd".insert(3, 'X')
+  assert_equal "abcdX", "abcd".insert(4, 'X')
+  assert_equal "abXcd", "abcd".insert(-3, 'X')
+  assert_equal "abcdX", "abcd".insert(-1, 'X')
+  assert_raise(IndexError) { "abcd".insert(5, 'X') }
+  assert_raise(IndexError) { "abcd".insert(-6, 'X') }
+
+  a = "abcd"
+  a.insert(0, 'X')
+  assert_equal "Xabcd", a
+end
+
+assert('String#prepend') do
+  a = "world"
+  assert_equal "hello world", a.prepend("hello ")
+  assert_equal "hello world", a
+end
+
+assert('String#ljust') do
+  assert_equal "hello", "hello".ljust(4)
+  assert_equal "hello               ", "hello".ljust(20)
+  assert_equal 20, "hello".ljust(20).length
+  assert_equal "hello123412341234123", "hello".ljust(20, '1234')
+  assert_equal "hello", "hello".ljust(-3)
+end
+
+assert('String#rjust') do
+  assert_equal "hello", "hello".rjust(4)
+  assert_equal "               hello", "hello".rjust(20)
+  assert_equal 20, "hello".rjust(20).length
+  assert_equal "123412341234123hello", "hello".rjust(20, '1234')
+  assert_equal "hello", "hello".rjust(-3)
+end
+
+if UTF8STRING
+  assert('String#ljust with UTF8') do
+    assert_equal "helloん              ", "helloん".ljust(20)
+    assert_equal "helloó                            ", "helloó".ljust(34)
+    assert_equal 34, "helloó".ljust(34).length
+    assert_equal "helloんんんんんんんんんんんんんん", "hello".ljust(19, 'ん')
+    assert_equal "helloんんんんんんんんんんんんんんん", "hello".ljust(20, 'ん')
+  end
+
+  assert('String#rjust with UTF8') do
+    assert_equal "              helloん", "helloん".rjust(20)
+    assert_equal "                            helloó", "helloó".rjust(34)
+    # assert_equal 34, "helloó".rjust(34).length
+    assert_equal "んんんんんんんんんんんんんんhello", "hello".rjust(19, 'ん')
+    assert_equal "んんんんんんんんんんんんんんんhello", "hello".rjust(20, 'ん')
+  end
+
+  assert('UTF8 byte counting') do
+    ret = '                                  '
+    ret[-6..-1] = "helloó"
+    assert_equal 34, ret.length
+  end
+end
+
+assert('String#ljust should not change string') do
+  a = "hello"
+  a.ljust(20)
+  assert_equal "hello", a
+end
+
+assert('String#rjust should not change string') do
+  a = "hello"
+  a.rjust(20)
+  assert_equal "hello", a
+end
+
+assert('String#ljust should raise on zero width padding') do
+  assert_raise(ArgumentError) { "foo".ljust(10, '') }
+end
+
+assert('String#rjust should raise on zero width padding') do
+  assert_raise(ArgumentError) { "foo".rjust(10, '') }
+end
+
+assert('String#upto') do
+  assert_equal %w(a8 a9 b0 b1 b2 b3 b4 b5 b6), "a8".upto("b6").to_a
+  assert_equal ["9", "10", "11"], "9".upto("11").to_a
+  assert_equal [], "25".upto("5").to_a
+  assert_equal ["07", "08", "09", "10", "11"], "07".upto("11").to_a
+
+if UTF8STRING
+  assert_equal ["あ", "ぃ", "い", "ぅ", "う", "ぇ", "え", "ぉ", "お"], "あ".upto("お").to_a
+end
+
+  assert_equal ["9", ":", ";", "<", "=", ">", "?", "@", "A"], "9".upto("A").to_a
+
+  a     = "aa"
+  start = "aa"
+  count = 0
+  assert_equal("aa", a.upto("zz") {|s|
+    assert_equal(start, s)
+    start.succ!
+    count += 1
+  })
+  assert_equal(676, count)
+
+  a     = "a"
+  start = "a"
+  count = 0
+  assert_equal("a", a.upto("a") {|s|
+    assert_equal(start, s)
+    start.succ!
+    count += 1
+  })
+  assert_equal(1, count)
+
+  a     = "a"
+  start = "a"
+  count = 0
+  assert_equal("a", a.upto("b", true) {|s|
+    assert_equal(start, s)
+    start.succ!
+    count += 1
+  })
+  assert_equal(1, count)
+
+  a     = "0"
+  start = "0"
+  count = 0
+  assert_equal("0", a.upto("0") {|s|
+    assert_equal(start, s)
+    start.succ!
+    count += 1
+  })
+  assert_equal(1, count)
+
+  a     = "0"
+  start = "0"
+  count = 0
+  assert_equal("0", a.upto("-1") {|s|
+    assert_equal(start, s)
+    start.succ!
+    count += 1
+  })
+  assert_equal(0, count)
+
+  a     = "-1"
+  start = "-1"
+  count = 0
+  assert_equal("-1", a.upto("-2") {|s|
+    assert_equal(start, s)
+    start.succ!
+    count += 1
+  })
+  assert_equal(2, count)
+
+  assert_raise(TypeError) { "a".upto(:c) {} }
+end
+
+assert('String#ord') do
+  got = "hello!".split('').map {|x| x.ord}
+  expect = [104, 101, 108, 108, 111, 33]
+  unless UTF8STRING
+    got << "\xff".ord
+    expect << 0xff
+  end
+  assert_equal expect, got
+end
+
+assert('String#ord(UTF-8)') do
+  got = "こんにちは世界!".split('').map {|x| x.ord}
+  expect = [0x3053,0x3093,0x306b,0x3061,0x306f,0x4e16,0x754c,0x21]
+  assert_equal expect, got
+end if UTF8STRING
+
+assert('String#chr') do
+  assert_equal "h", "hello!".chr
+end
+assert('String#chr(UTF-8)') do
+  assert_equal "こ", "こんにちは世界!".chr
+end if UTF8STRING
+
+assert('String#chars') do
+  expect = ["h", "e", "l", "l", "o", "!"]
+  assert_equal expect, "hello!".chars
+  s = ""
+  "hello!".chars do |x|
+    s += x
+  end
+  assert_equal "hello!", s
+end
+
+assert('String#chars(UTF-8)') do
+  expect = ['こ', 'ん', 'に', 'ち', 'は', '世', '界', '!']
+  assert_equal expect, "こんにちは世界!".chars
+  s = ""
+  "こんにちは世界!".chars do |x|
+    s += x
+  end
+  assert_equal "こんにちは世界!", s
+end if UTF8STRING
+
+assert('String#each_char') do
+  s = ""
+  "hello!".each_char do |x|
+    s += x
+  end
+  assert_equal "hello!", s
+end
+
+assert('String#each_char(UTF-8)') do
+  s = ""
+  "こんにちは世界!".each_char do |x|
+    s += x
+  end
+  assert_equal "こんにちは世界!", s
+end if UTF8STRING
+
+assert('String#codepoints') do
+  expect = [104, 101, 108, 108, 111, 33]
+  assert_equal expect, "hello!".codepoints
+  cp = []
+  "hello!".codepoints do |x|
+    cp << x
+  end
+  assert_equal expect, cp
+end
+
+assert('String#codepoints(UTF-8)') do
+  expect = [12371, 12435, 12395, 12385, 12399, 19990, 30028, 33]
+  assert_equal expect, "こんにちは世界!".codepoints
+  cp = []
+  "こんにちは世界!".codepoints do |x|
+    cp << x
+  end
+  assert_equal expect, cp
+end if UTF8STRING
+
+assert('String#each_codepoint') do
+  expect = [104, 101, 108, 108, 111, 33]
+  cp = []
+  "hello!".each_codepoint do |x|
+    cp << x
+  end
+  assert_equal expect, cp
+end
+
+assert('String#each_codepoint(UTF-8)') do
+  expect = [12371, 12435, 12395, 12385, 12399, 19990, 30028, 33]
+  cp = []
+  "こんにちは世界!".each_codepoint do |x|
+    cp << x
+  end
+  assert_equal expect, cp
+end if UTF8STRING
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-struct/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-struct/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-struct/mrbgem.rake	(revision 331)
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-struct') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'standard Struct class'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-struct/mrblib/struct.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-struct/mrblib/struct.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-struct/mrblib/struct.rb	(revision 331)
@@ -0,0 +1,103 @@
+##
+# Struct
+#
+# ISO 15.2.18
+
+if Object.const_defined?(:Struct)
+  class Struct
+
+    ##
+    # Calls the given block for each element of +self+
+    # and pass the respective element.
+    #
+    # ISO 15.2.18.4.4
+    def each(&block)
+      self.class.members.each{|field|
+        block.call(self[field])
+      }
+      self
+    end
+
+    ##
+    # Calls the given block for each element of +self+
+    # and pass the name and value of the respectiev
+    # element.
+    #
+    # ISO 15.2.18.4.5
+    def each_pair(&block)
+      self.class.members.each{|field|
+        block.call(field.to_sym, self[field])
+      }
+      self
+    end
+
+    ##
+    # Calls the given block for each element of +self+
+    # and returns an array with all elements of which
+    # block is not false.
+    #
+    # ISO 15.2.18.4.7
+    def select(&block)
+      ary = []
+      self.class.members.each{|field|
+        val = self[field]
+        ary.push(val) if block.call(val)
+      }
+      ary
+    end
+
+    def _inspect
+      name = self.class.to_s
+      if name[0] == "#"
+        str = "#<struct "
+      else
+        str = "#<struct #{name} "
+      end
+      buf = []
+      self.each_pair do |k,v|
+        buf.push [k.to_s + "=" + v._inspect]
+      end
+      str + buf.join(", ") + ">"
+    end
+
+    ##
+    # call-seq:
+    #   struct.to_s      -> string
+    #   struct.inspect   -> string
+    #
+    # Describe the contents of this struct in a string.
+    #
+    # 15.2.18.4.10(x)
+    #
+    def inspect
+      begin
+        self._inspect
+      rescue SystemStackError
+        "#<struct #{self.class.to_s}:...>"
+      end
+    end
+
+    ##
+    # 15.2.18.4.11(x)
+    #
+    alias to_s inspect
+  end
+
+  ##
+  # call-seq:
+  #   hsh.dig(key,...)                 -> object
+  #
+  # Extracts the nested value specified by the sequence of <i>key</i>
+  # objects by calling +dig+ at each step, returning +nil+ if any
+  # intermediate step is +nil+.
+  #
+  def dig(idx,*args)
+    n = self[idx]
+    if args.size > 0
+      n&.dig(*args)
+    else
+      n
+    end
+  end
+end
+
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-struct/src/struct.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-struct/src/struct.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-struct/src/struct.c	(revision 331)
@@ -0,0 +1,715 @@
+/*
+** struct.c - Struct class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <string.h>
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/string.h>
+#include <mruby/class.h>
+#include <mruby/variable.h>
+#include <mruby/hash.h>
+#include <mruby/range.h>
+
+#define RSTRUCT_LEN(st) mrb_ary_ptr(st)->len
+#define RSTRUCT_PTR(st) mrb_ary_ptr(st)->ptr
+
+static struct RClass *
+struct_class(mrb_state *mrb)
+{
+  return mrb_class_get(mrb, "Struct");
+}
+
+static inline mrb_value
+struct_ivar_get(mrb_state *mrb, mrb_value c, mrb_sym id)
+{
+  struct RClass* kclass;
+  struct RClass* sclass = struct_class(mrb);
+  mrb_value ans;
+
+  for (;;) {
+    ans = mrb_iv_get(mrb, c, id);
+    if (!mrb_nil_p(ans)) return ans;
+    kclass = RCLASS_SUPER(c);
+    if (kclass == 0 || kclass == sclass)
+      return mrb_nil_value();
+    c = mrb_obj_value(kclass);
+  }
+}
+
+static mrb_value
+struct_s_members(mrb_state *mrb, struct RClass *klass)
+{
+  mrb_value members = struct_ivar_get(mrb, mrb_obj_value(klass), mrb_intern_lit(mrb, "__members__"));
+
+  if (mrb_nil_p(members)) {
+    mrb_raise(mrb, E_TYPE_ERROR, "uninitialized struct");
+  }
+  if (!mrb_array_p(members)) {
+    mrb_raise(mrb, E_TYPE_ERROR, "corrupted struct");
+  }
+  return members;
+}
+
+static mrb_value
+struct_members(mrb_state *mrb, mrb_value s)
+{
+  mrb_value members = struct_s_members(mrb, mrb_obj_class(mrb, s));
+  if (!mrb_array_p(s)) {
+    mrb_raise(mrb, E_TYPE_ERROR, "corrupted struct");
+  }
+  if (RSTRUCT_LEN(s) != RARRAY_LEN(members)) {
+    if (RSTRUCT_LEN(s) == 0) {  /* probably uninitialized */
+      mrb_ary_resize(mrb, s, RARRAY_LEN(members));
+    }
+    else {
+      mrb_raisef(mrb, E_TYPE_ERROR,
+                 "struct size differs (%S required %S given)",
+                 mrb_fixnum_value(RARRAY_LEN(members)), mrb_fixnum_value(RSTRUCT_LEN(s)));
+    }
+  }
+  return members;
+}
+
+static mrb_value
+mrb_struct_s_members_m(mrb_state *mrb, mrb_value klass)
+{
+  mrb_value members, ary;
+
+  members = struct_s_members(mrb, mrb_class_ptr(klass));
+  ary = mrb_ary_new_capa(mrb, RARRAY_LEN(members));
+  mrb_ary_replace(mrb, ary, members);
+  return ary;
+}
+
+static void
+mrb_struct_modify(mrb_state *mrb, mrb_value strct)
+{
+  if (MRB_FROZEN_P(mrb_basic_ptr(strct))) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen struct");
+  }
+
+  mrb_write_barrier(mrb, mrb_basic_ptr(strct));
+}
+
+/* 15.2.18.4.6  */
+/*
+ *  call-seq:
+ *     struct.members    -> array
+ *
+ *  Returns an array of strings representing the names of the instance
+ *  variables.
+ *
+ *     Customer = Struct.new(:name, :address, :zip)
+ *     joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
+ *     joe.members   #=> [:name, :address, :zip]
+ */
+
+static mrb_value
+mrb_struct_members(mrb_state *mrb, mrb_value obj)
+{
+  return mrb_struct_s_members_m(mrb, mrb_obj_value(mrb_obj_class(mrb, obj)));
+}
+
+static mrb_value struct_aref_sym(mrb_state *mrb, mrb_value obj, mrb_sym id);
+
+static mrb_value
+mrb_struct_ref(mrb_state *mrb, mrb_value obj)
+{
+  return struct_aref_sym(mrb, obj, mrb->c->ci->mid);
+}
+
+static mrb_sym
+mrb_id_attrset(mrb_state *mrb, mrb_sym id)
+{
+  const char *name;
+  char *buf;
+  mrb_int len;
+  mrb_sym mid;
+
+  name = mrb_sym2name_len(mrb, id, &len);
+  buf = (char *)mrb_malloc(mrb, (size_t)len+2);
+  memcpy(buf, name, (size_t)len);
+  buf[len] = '=';
+  buf[len+1] = '\0';
+
+  mid = mrb_intern(mrb, buf, len+1);
+  mrb_free(mrb, buf);
+  return mid;
+}
+
+static mrb_value mrb_struct_aset_sym(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val);
+
+static mrb_value
+mrb_struct_set_m(mrb_state *mrb, mrb_value obj)
+{
+  mrb_value val;
+
+  const char *name;
+  mrb_int slen;
+  mrb_sym mid;
+
+  mrb_get_args(mrb, "o", &val);
+
+  /* get base id */
+  name = mrb_sym2name_len(mrb, mrb->c->ci->mid, &slen);
+  mid = mrb_intern(mrb, name, slen-1); /* omit last "=" */
+
+  return mrb_struct_aset_sym(mrb, obj, mid, val);
+}
+
+static mrb_bool
+is_local_id(mrb_state *mrb, const char *name)
+{
+  if (!name) return FALSE;
+  return !ISUPPER(name[0]);
+}
+
+static mrb_bool
+is_const_id(mrb_state *mrb, const char *name)
+{
+  if (!name) return FALSE;
+  return ISUPPER(name[0]);
+}
+
+static void
+make_struct_define_accessors(mrb_state *mrb, mrb_value members, struct RClass *c)
+{
+  const mrb_value *ptr_members = RARRAY_PTR(members);
+  mrb_int i;
+  mrb_int len = RARRAY_LEN(members);
+  int ai = mrb_gc_arena_save(mrb);
+
+  for (i=0; i<len; i++) {
+    mrb_sym id = mrb_symbol(ptr_members[i]);
+    const char *name = mrb_sym2name_len(mrb, id, NULL);
+
+    if (is_local_id(mrb, name) || is_const_id(mrb, name)) {
+      mrb_define_method_id(mrb, c, id, mrb_struct_ref, MRB_ARGS_NONE());
+      mrb_define_method_id(mrb, c, mrb_id_attrset(mrb, id), mrb_struct_set_m, MRB_ARGS_REQ(1));
+      mrb_gc_arena_restore(mrb, ai);
+    }
+  }
+}
+
+static mrb_value
+make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * klass)
+{
+  mrb_value nstr;
+  mrb_sym id;
+  struct RClass *c;
+
+  if (mrb_nil_p(name)) {
+    c = mrb_class_new(mrb, klass);
+  }
+  else {
+    /* old style: should we warn? */
+    name = mrb_str_to_str(mrb, name);
+    id = mrb_obj_to_sym(mrb, name);
+    if (!is_const_id(mrb, mrb_sym2name_len(mrb, id, NULL))) {
+      mrb_name_error(mrb, id, "identifier %S needs to be constant", name);
+    }
+    if (mrb_const_defined_at(mrb, mrb_obj_value(klass), id)) {
+      mrb_warn(mrb, "redefining constant Struct::%S", name);
+      mrb_const_remove(mrb, mrb_obj_value(klass), id);
+    }
+    c = mrb_define_class_under(mrb, klass, RSTRING_PTR(name), klass);
+  }
+  MRB_SET_INSTANCE_TT(c, MRB_TT_ARRAY);
+  nstr = mrb_obj_value(c);
+  mrb_iv_set(mrb, nstr, mrb_intern_lit(mrb, "__members__"), members);
+
+  mrb_define_class_method(mrb, c, "new", mrb_instance_new, MRB_ARGS_ANY());
+  mrb_define_class_method(mrb, c, "[]", mrb_instance_new, MRB_ARGS_ANY());
+  mrb_define_class_method(mrb, c, "members", mrb_struct_s_members_m, MRB_ARGS_NONE());
+  /* RSTRUCT(nstr)->basic.c->super = c->c; */
+  make_struct_define_accessors(mrb, members, c);
+  return nstr;
+}
+
+/* 15.2.18.3.1  */
+/*
+ *  call-seq:
+ *     Struct.new( [aString] [, aSym]+> )    -> StructClass
+ *     StructClass.new(arg, ...)             -> obj
+ *     StructClass[arg, ...]                 -> obj
+ *
+ *  Creates a new class, named by <i>aString</i>, containing accessor
+ *  methods for the given symbols. If the name <i>aString</i> is
+ *  omitted, an anonymous structure class will be created. Otherwise,
+ *  the name of this struct will appear as a constant in class
+ *  <code>Struct</code>, so it must be unique for all
+ *  <code>Struct</code>s in the system and should start with a capital
+ *  letter. Assigning a structure class to a constant effectively gives
+ *  the class the name of the constant.
+ *
+ *  <code>Struct::new</code> returns a new <code>Class</code> object,
+ *  which can then be used to create specific instances of the new
+ *  structure. The number of actual parameters must be
+ *  less than or equal to the number of attributes defined for this
+ *  class; unset parameters default to <code>nil</code>.  Passing too many
+ *  parameters will raise an <code>ArgumentError</code>.
+ *
+ *  The remaining methods listed in this section (class and instance)
+ *  are defined for this generated class.
+ *
+ *     # Create a structure with a name in Struct
+ *     Struct.new("Customer", :name, :address)    #=> Struct::Customer
+ *     Struct::Customer.new("Dave", "123 Main")   #=> #<struct Struct::Customer name="Dave", address="123 Main">
+ *
+ *     # Create a structure named by its constant
+ *     Customer = Struct.new(:name, :address)     #=> Customer
+ *     Customer.new("Dave", "123 Main")           #=> #<struct Customer name="Dave", address="123 Main">
+ */
+static mrb_value
+mrb_struct_s_def(mrb_state *mrb, mrb_value klass)
+{
+  mrb_value name, rest;
+  mrb_value *pargv;
+  mrb_int argcnt;
+  mrb_int i;
+  mrb_value b, st;
+  mrb_sym id;
+  mrb_value *argv;
+  mrb_int argc;
+
+  name = mrb_nil_value();
+  rest = mrb_nil_value();
+  mrb_get_args(mrb, "*&", &argv, &argc, &b);
+  if (argc == 0) { /* special case to avoid crash */
+    rest = mrb_ary_new(mrb);
+  }
+  else {
+    if (argc > 0) name = argv[0];
+    pargv = &argv[1];
+    argcnt = argc-1;
+    if (!mrb_nil_p(name) && mrb_symbol_p(name)) {
+      /* 1stArgument:symbol -> name=nil rest=argv[0]-[n] */
+      name = mrb_nil_value();
+      pargv = &argv[0];
+      argcnt++;
+    }
+    rest = mrb_ary_new_from_values(mrb, argcnt, pargv);
+    for (i=0; i<RARRAY_LEN(rest); i++) {
+      id = mrb_obj_to_sym(mrb, RARRAY_PTR(rest)[i]);
+      mrb_ary_set(mrb, rest, i, mrb_symbol_value(id));
+    }
+  }
+  st = make_struct(mrb, name, rest, mrb_class_ptr(klass));
+  if (!mrb_nil_p(b)) {
+    mrb_yield_with_class(mrb, b, 1, &st, st, mrb_class_ptr(st));
+  }
+
+  return st;
+}
+
+static mrb_int
+num_members(mrb_state *mrb, struct RClass *klass)
+{
+  mrb_value members;
+
+  members = struct_ivar_get(mrb, mrb_obj_value(klass), mrb_intern_lit(mrb, "__members__"));
+  if (!mrb_array_p(members)) {
+    mrb_raise(mrb, E_TYPE_ERROR, "broken members");
+  }
+  return RARRAY_LEN(members);
+}
+
+/* 15.2.18.4.8  */
+/*
+ */
+static mrb_value
+mrb_struct_initialize_withArg(mrb_state *mrb, mrb_int argc, mrb_value *argv, mrb_value self)
+{
+  struct RClass *klass = mrb_obj_class(mrb, self);
+  mrb_int i, n;
+
+  n = num_members(mrb, klass);
+  if (n < argc) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "struct size differs");
+  }
+
+  for (i = 0; i < argc; i++) {
+    mrb_ary_set(mrb, self, i, argv[i]);
+  }
+  for (i = argc; i < n; i++) {
+    mrb_ary_set(mrb, self, i, mrb_nil_value());
+  }
+  return self;
+}
+
+static mrb_value
+mrb_struct_initialize(mrb_state *mrb, mrb_value self)
+{
+  mrb_value *argv;
+  mrb_int argc;
+
+  mrb_get_args(mrb, "*", &argv, &argc);
+  return mrb_struct_initialize_withArg(mrb, argc, argv, self);
+}
+
+/* 15.2.18.4.9  */
+/* :nodoc: */
+static mrb_value
+mrb_struct_init_copy(mrb_state *mrb, mrb_value copy)
+{
+  mrb_value s;
+
+  mrb_get_args(mrb, "o", &s);
+
+  if (mrb_obj_equal(mrb, copy, s)) return copy;
+  if (!mrb_obj_is_instance_of(mrb, s, mrb_obj_class(mrb, copy))) {
+    mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class");
+  }
+  if (!mrb_array_p(s)) {
+    mrb_raise(mrb, E_TYPE_ERROR, "corrupted struct");
+  }
+  mrb_ary_replace(mrb, copy, s);
+  return copy;
+}
+
+static mrb_value
+struct_aref_sym(mrb_state *mrb, mrb_value obj, mrb_sym id)
+{
+  mrb_value members, *ptr;
+  const mrb_value *ptr_members;
+  mrb_int i, len;
+
+  members = struct_members(mrb, obj);
+  ptr_members = RARRAY_PTR(members);
+  len = RARRAY_LEN(members);
+  ptr = RSTRUCT_PTR(obj);
+  for (i=0; i<len; i++) {
+    mrb_value slot = ptr_members[i];
+    if (mrb_symbol_p(slot) && mrb_symbol(slot) == id) {
+      return ptr[i];
+    }
+  }
+  mrb_raisef(mrb, E_INDEX_ERROR, "'%S' is not a struct member", mrb_sym2str(mrb, id));
+  return mrb_nil_value();       /* not reached */
+}
+
+static mrb_value
+struct_aref_int(mrb_state *mrb, mrb_value s, mrb_int i)
+{
+  if (i < 0) i = RSTRUCT_LEN(s) + i;
+  if (i < 0)
+      mrb_raisef(mrb, E_INDEX_ERROR,
+                 "offset %S too small for struct(size:%S)",
+                 mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s)));
+  if (RSTRUCT_LEN(s) <= i)
+    mrb_raisef(mrb, E_INDEX_ERROR,
+               "offset %S too large for struct(size:%S)",
+               mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s)));
+  return RSTRUCT_PTR(s)[i];
+}
+
+/* 15.2.18.4.2  */
+/*
+ *  call-seq:
+ *     struct[symbol]    -> anObject
+ *     struct[fixnum]    -> anObject
+ *
+ *  Attribute Reference---Returns the value of the instance variable
+ *  named by <i>symbol</i>, or indexed (0..length-1) by
+ *  <i>fixnum</i>. Will raise <code>NameError</code> if the named
+ *  variable does not exist, or <code>IndexError</code> if the index is
+ *  out of range.
+ *
+ *     Customer = Struct.new(:name, :address, :zip)
+ *     joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
+ *
+ *     joe["name"]   #=> "Joe Smith"
+ *     joe[:name]    #=> "Joe Smith"
+ *     joe[0]        #=> "Joe Smith"
+ */
+static mrb_value
+mrb_struct_aref(mrb_state *mrb, mrb_value s)
+{
+  mrb_value idx;
+
+  mrb_get_args(mrb, "o", &idx);
+  if (mrb_string_p(idx)) {
+    mrb_value sym = mrb_check_intern_str(mrb, idx);
+
+    if (mrb_nil_p(sym)) {
+      mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%S' in struct", idx);
+    }
+    idx = sym;
+  }
+  if (mrb_symbol_p(idx)) {
+    return struct_aref_sym(mrb, s, mrb_symbol(idx));
+  }
+  return struct_aref_int(mrb, s, mrb_int(mrb, idx));
+}
+
+static mrb_value
+mrb_struct_aset_sym(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val)
+{
+  mrb_value members, *ptr;
+  const mrb_value *ptr_members;
+  mrb_int i, len;
+
+  members = struct_members(mrb, s);
+  len = RARRAY_LEN(members);
+  ptr = RSTRUCT_PTR(s);
+  ptr_members = RARRAY_PTR(members);
+  for (i=0; i<len; i++) {
+    if (mrb_symbol(ptr_members[i]) == id) {
+      mrb_struct_modify(mrb, s);
+      ptr[i] = val;
+      return val;
+    }
+  }
+  mrb_name_error(mrb, id, "no member '%S' in struct", mrb_sym2str(mrb, id));
+  return val;                   /* not reach */
+}
+
+/* 15.2.18.4.3  */
+/*
+ *  call-seq:
+ *     struct[symbol] = obj    -> obj
+ *     struct[fixnum] = obj    -> obj
+ *
+ *  Attribute Assignment---Assigns to the instance variable named by
+ *  <i>symbol</i> or <i>fixnum</i> the value <i>obj</i> and
+ *  returns it. Will raise a <code>NameError</code> if the named
+ *  variable does not exist, or an <code>IndexError</code> if the index
+ *  is out of range.
+ *
+ *     Customer = Struct.new(:name, :address, :zip)
+ *     joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
+ *
+ *     joe["name"] = "Luke"
+ *     joe[:zip]   = "90210"
+ *
+ *     joe.name   #=> "Luke"
+ *     joe.zip    #=> "90210"
+ */
+
+static mrb_value
+mrb_struct_aset(mrb_state *mrb, mrb_value s)
+{
+  mrb_int i;
+  mrb_value idx;
+  mrb_value val;
+
+  mrb_get_args(mrb, "oo", &idx, &val);
+
+  if (mrb_string_p(idx)) {
+    mrb_value sym = mrb_check_intern_str(mrb, idx);
+
+    if (mrb_nil_p(sym)) {
+      mrb_name_error(mrb, mrb_intern_str(mrb, idx), "no member '%S' in struct", idx);
+    }
+    idx = sym;
+  }
+  if (mrb_symbol_p(idx)) {
+    return mrb_struct_aset_sym(mrb, s, mrb_symbol(idx), val);
+  }
+
+  i = mrb_int(mrb, idx);
+  if (i < 0) i = RSTRUCT_LEN(s) + i;
+  if (i < 0) {
+    mrb_raisef(mrb, E_INDEX_ERROR,
+               "offset %S too small for struct(size:%S)",
+               mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s)));
+  }
+  if (RSTRUCT_LEN(s) <= i) {
+    mrb_raisef(mrb, E_INDEX_ERROR,
+               "offset %S too large for struct(size:%S)",
+               mrb_fixnum_value(i), mrb_fixnum_value(RSTRUCT_LEN(s)));
+  }
+  mrb_struct_modify(mrb, s);
+  return RSTRUCT_PTR(s)[i] = val;
+}
+
+/* 15.2.18.4.1  */
+/*
+ *  call-seq:
+ *     struct == other_struct     -> true or false
+ *
+ *  Equality---Returns <code>true</code> if <i>other_struct</i> is
+ *  equal to this one: they must be of the same class as generated by
+ *  <code>Struct::new</code>, and the values of all instance variables
+ *  must be equal (according to <code>Object#==</code>).
+ *
+ *     Customer = Struct.new(:name, :address, :zip)
+ *     joe   = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
+ *     joejr = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
+ *     jane  = Customer.new("Jane Doe", "456 Elm, Anytown NC", 12345)
+ *     joe == joejr   #=> true
+ *     joe == jane    #=> false
+ */
+
+static mrb_value
+mrb_struct_equal(mrb_state *mrb, mrb_value s)
+{
+  mrb_value s2;
+  mrb_value *ptr, *ptr2;
+  mrb_int i, len;
+
+  mrb_get_args(mrb, "o", &s2);
+  if (mrb_obj_equal(mrb, s, s2)) {
+    return mrb_true_value();
+  }
+  if (mrb_obj_class(mrb, s) != mrb_obj_class(mrb, s2)) {
+    return mrb_false_value();
+  }
+  if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
+    mrb_bug(mrb, "inconsistent struct"); /* should never happen */
+  }
+  ptr = RSTRUCT_PTR(s);
+  ptr2 = RSTRUCT_PTR(s2);
+  len = RSTRUCT_LEN(s);
+  for (i=0; i<len; i++) {
+    if (!mrb_equal(mrb, ptr[i], ptr2[i])) {
+      return mrb_false_value();
+    }
+  }
+
+  return mrb_true_value();
+}
+
+/* 15.2.18.4.12(x)  */
+/*
+ * code-seq:
+ *   struct.eql?(other)   -> true or false
+ *
+ * Two structures are equal if they are the same object, or if all their
+ * fields are equal (using <code>eql?</code>).
+ */
+static mrb_value
+mrb_struct_eql(mrb_state *mrb, mrb_value s)
+{
+  mrb_value s2;
+  mrb_value *ptr, *ptr2;
+  mrb_int i, len;
+
+  mrb_get_args(mrb, "o", &s2);
+  if (mrb_obj_equal(mrb, s, s2)) {
+    return mrb_true_value();
+  }
+  if (mrb_obj_class(mrb, s) != mrb_obj_class(mrb, s2)) {
+    return mrb_false_value();
+  }
+  if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
+    mrb_bug(mrb, "inconsistent struct"); /* should never happen */
+  }
+  ptr = RSTRUCT_PTR(s);
+  ptr2 = RSTRUCT_PTR(s2);
+  len = RSTRUCT_LEN(s);
+  for (i=0; i<len; i++) {
+    if (!mrb_eql(mrb, ptr[i], ptr2[i])) {
+      return mrb_false_value();
+    }
+  }
+
+  return mrb_true_value();
+}
+
+/*
+ * call-seq:
+ *    struct.length   -> Fixnum
+ *    struct.size     -> Fixnum
+ *
+ * Returns number of struct members.
+ */
+static mrb_value
+mrb_struct_len(mrb_state *mrb, mrb_value self)
+{
+  return mrb_fixnum_value(RSTRUCT_LEN(self));
+}
+
+/*
+ * call-seq:
+ *    struct.to_a    -> array
+ *    struct.values  -> array
+ *
+ * Create an array from struct values.
+ */
+static mrb_value
+mrb_struct_to_a(mrb_state *mrb, mrb_value self)
+{
+  return mrb_ary_new_from_values(mrb, RSTRUCT_LEN(self), RSTRUCT_PTR(self));
+}
+
+/*
+ * call-seq:
+ *    struct.to_h -> hash
+ *
+ * Create a hash from member names and struct values.
+ */
+static mrb_value
+mrb_struct_to_h(mrb_state *mrb, mrb_value self)
+{
+  mrb_value members, ret;
+  mrb_int i;
+
+  members = struct_members(mrb, self);
+  ret = mrb_hash_new_capa(mrb, RARRAY_LEN(members));
+
+  for (i = 0; i < RARRAY_LEN(members); ++i) {
+    mrb_hash_set(mrb, ret, RARRAY_PTR(members)[i], RSTRUCT_PTR(self)[i]);
+  }
+
+  return ret;
+}
+
+static mrb_value
+mrb_struct_values_at(mrb_state *mrb, mrb_value self)
+{
+  mrb_int argc;
+  mrb_value *argv;
+
+  mrb_get_args(mrb, "*", &argv, &argc);
+
+  return mrb_get_values_at(mrb, self, RSTRUCT_LEN(self), argc, argv, struct_aref_int);
+}
+
+/*
+ *  A <code>Struct</code> is a convenient way to bundle a number of
+ *  attributes together, using accessor methods, without having to write
+ *  an explicit class.
+ *
+ *  The <code>Struct</code> class is a generator of specific classes,
+ *  each one of which is defined to hold a set of variables and their
+ *  accessors. In these examples, we'll call the generated class
+ *  "<i>Customer</i>Class," and we'll show an example instance of that
+ *  class as "<i>Customer</i>Inst."
+ *
+ *  In the descriptions that follow, the parameter <i>symbol</i> refers
+ *  to a symbol, which is either a quoted string or a
+ *  <code>Symbol</code> (such as <code>:name</code>).
+ */
+void
+mrb_mruby_struct_gem_init(mrb_state* mrb)
+{
+  struct RClass *st;
+  st = mrb_define_class(mrb, "Struct",  mrb->object_class);
+  MRB_SET_INSTANCE_TT(st, MRB_TT_ARRAY);
+
+  mrb_define_class_method(mrb, st, "new",             mrb_struct_s_def,       MRB_ARGS_ANY());  /* 15.2.18.3.1  */
+
+  mrb_define_method(mrb, st,       "==",              mrb_struct_equal,       MRB_ARGS_REQ(1)); /* 15.2.18.4.1  */
+  mrb_define_method(mrb, st,       "[]",              mrb_struct_aref,        MRB_ARGS_REQ(1)); /* 15.2.18.4.2  */
+  mrb_define_method(mrb, st,       "[]=",             mrb_struct_aset,        MRB_ARGS_REQ(2)); /* 15.2.18.4.3  */
+  mrb_define_method(mrb, st,       "members",         mrb_struct_members,     MRB_ARGS_NONE()); /* 15.2.18.4.6  */
+  mrb_define_method(mrb, st,       "initialize",      mrb_struct_initialize,  MRB_ARGS_ANY());  /* 15.2.18.4.8  */
+  mrb_define_method(mrb, st,       "initialize_copy", mrb_struct_init_copy,   MRB_ARGS_REQ(1)); /* 15.2.18.4.9  */
+  mrb_define_method(mrb, st,       "eql?",            mrb_struct_eql,         MRB_ARGS_REQ(1)); /* 15.2.18.4.12(x)  */
+
+  mrb_define_method(mrb, st,        "size",           mrb_struct_len,         MRB_ARGS_NONE());
+  mrb_define_method(mrb, st,        "length",         mrb_struct_len,         MRB_ARGS_NONE());
+  mrb_define_method(mrb, st,        "to_a",           mrb_struct_to_a,        MRB_ARGS_NONE());
+  mrb_define_method(mrb, st,        "values",         mrb_struct_to_a,        MRB_ARGS_NONE());
+  mrb_define_method(mrb, st,        "to_h",           mrb_struct_to_h,        MRB_ARGS_NONE());
+  mrb_define_method(mrb, st,        "values_at",      mrb_struct_values_at,   MRB_ARGS_ANY());
+}
+
+void
+mrb_mruby_struct_gem_final(mrb_state* mrb)
+{
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-struct/test/struct.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-struct/test/struct.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-struct/test/struct.rb	(revision 331)
@@ -0,0 +1,212 @@
+##
+# Struct ISO Test
+
+assert('Struct', '15.2.18') do
+  assert_equal Class, Struct.class
+end
+
+assert('Struct.new', '15.2.18.3.1') do
+  c = Struct.new(:m1, :m2)
+  assert_equal Struct, c.superclass
+  assert_equal [:m1, :m2], c.members
+end
+
+# Check crash bug with Struc.new and no params.
+assert('Struct.new', '15.2.18.3.1') do
+  c = Struct.new()
+  assert_equal Struct, c.superclass
+  assert_equal [], c.members
+end
+
+assert('Struct#==', '15.2.18.4.1') do
+  c = Struct.new(:m1, :m2)
+  cc1 = c.new(1,2)
+  cc2 = c.new(1,2)
+  assert_true cc1 == cc2
+
+  Struct.new(:m1, :m2) { def foo; end }
+  assert_raise(NoMethodError) { Struct.new(:m1).new.foo }
+end
+
+assert('Struct#[]', '15.2.18.4.2') do
+  c = Struct.new(:m1, :m2)
+  cc = c.new(1,2)
+  assert_equal 1, cc[:m1]
+  assert_equal 2, cc["m2"]
+  assert_equal 1, cc[0]
+  assert_equal 2, cc[-1]
+  assert_raise(TypeError) { cc[[]] }
+  assert_raise(IndexError) { cc[2] }
+  assert_raise(NameError) { cc['tama'] }
+end
+
+assert('Struct#[]=', '15.2.18.4.3') do
+  c = Struct.new(:m1, :m2)
+  cc = c.new(1,2)
+  cc[:m1] = 3
+  assert_equal 3, cc[:m1]
+  cc["m2"] = 3
+  assert_equal 3, cc["m2"]
+  cc[0] = 4
+  assert_equal 4, cc[0]
+  cc[-1] = 5
+  assert_equal 5, cc[-1]
+  assert_raise(TypeError) { cc[[]] = 3 }
+  assert_raise(IndexError) { cc[2] = 7 }
+  assert_raise(NameError) { cc['pochi'] = 8 }
+end
+
+assert('Struct#each', '15.2.18.4.4') do
+  c = Struct.new(:m1, :m2)
+  cc = c.new(1,2)
+  a = []
+  cc.each{|x|
+    a << x
+  }
+  assert_equal [1, 2], a
+end
+
+assert('Struct#each_pair', '15.2.18.4.5') do
+  c = Struct.new(:m1, :m2)
+  cc = c.new(1,2)
+  a = []
+  cc.each_pair{|k,v|
+    a << [k,v]
+  }
+  assert_equal [[:m1, 1], [:m2, 2]], a
+end
+
+assert('Struct#members', '15.2.18.4.6') do
+  c = Struct.new(:m1, :m2)
+  assert_equal [:m1, :m2], c.new(1,2).members
+end
+
+assert('Struct#select', '15.2.18.4.7') do
+  c = Struct.new(:m1, :m2)
+  assert_equal([2]) { c.new(1,2).select{|v| v % 2 == 0} }
+end
+
+assert('large struct') do
+  c = Struct.new(:m1, :m2, :m3, :m4, :m5, :m6, :m7, :m8, :m9, :m10, :m11, :m12, :m13)
+  cc = c.new(1,2,3,4,5,6,7,8,9,10,11,12,13)
+  assert_equal 1, cc.m1
+  assert_equal 2, cc.m2
+  assert_equal 3, cc.m3
+  assert_equal 4, cc.m4
+  assert_equal 5, cc.m5
+  assert_equal 6, cc.m6
+  assert_equal 7, cc.m7
+  assert_equal 8, cc.m8
+  assert_equal 9, cc.m9
+  assert_equal 10, cc.m10
+  assert_equal 13, cc.m13
+
+  cc.m13 = 'test'
+  assert_equal 'test', cc.m13
+
+  assert_raise(NoMethodError) { cc.m14 }
+end
+
+assert('wrong struct arg count') do
+  c = Struct.new(:m1)
+  assert_raise ArgumentError do
+    cc = c.new(1,2,3)
+  end
+end
+
+assert('struct dup') do
+  c = Struct.new(:m1, :m2, :m3, :m4, :m5)
+  cc = c.new(1,2,3,4,5)
+  assert_nothing_raised {
+    assert_equal(cc, cc.dup)
+  }
+end
+
+assert('struct inspect') do
+  c = Struct.new(:m1, :m2, :m3, :m4, :m5)
+  cc = c.new(1,2,3,4,5)
+  assert_equal "#<struct m1=1, m2=2, m3=3, m4=4, m5=5>", cc.inspect
+end
+
+assert('Struct#length, Struct#size') do
+  s = Struct.new(:f1, :f2).new(0, 1)
+  assert_equal 2, s.size
+  assert_equal 2, s.length
+end
+
+assert('Struct#to_a, Struct#values') do
+  s = Struct.new(:mem1, :mem2).new('a', 'b')
+  assert_equal ['a', 'b'], s.to_a
+  assert_equal ['a', 'b'], s.values
+end
+
+assert('Struct#to_h') do
+  s = Struct.new(:white, :red, :green).new('ruuko', 'yuzuki', 'hitoe')
+  assert_equal(:white => 'ruuko', :red => 'yuzuki', :green => 'hitoe') { s.to_h }
+end
+
+assert('Struct#values_at') do
+  a = Struct.new(:blue, :purple).new('aki', 'io')
+  assert_equal ['aki'], a.values_at(0)
+  assert_equal ['io', 'aki'], a.values_at(1, 0)
+  assert_raise(IndexError) { a.values_at 2 }
+end
+
+assert("Struct#dig") do
+  a = Struct.new(:blue, :purple).new('aki', Struct.new(:red).new(1))
+  assert_equal 'aki', a.dig(:blue)
+  assert_equal 1, a.dig(:purple, :red)
+  assert_equal 1, a.dig(1, 0)
+end
+
+assert("Struct.new removes existing constant") do
+  skip "redefining Struct with same name cause warnings"
+  begin
+    assert_not_equal Struct.new("Test", :a), Struct.new("Test", :a, :b)
+  ensure
+    Struct.remove_const :Test
+  end
+end
+
+assert("Struct#initialize_copy requires struct to be the same type") do
+  begin
+    Struct.new("Test", :a)
+    a = Struct::Test.new("a")
+    Struct.remove_const :Test
+    Struct.new("Test", :a, :b)
+    assert_raise(TypeError) do
+      a.initialize_copy(Struct::Test.new("a", "b"))
+    end
+  ensure
+    Struct.remove_const :Test
+  end
+end
+
+assert("Struct.new does not allow array") do
+  assert_raise(TypeError) do
+    Struct.new("Test", [:a])
+  end
+end
+
+assert("Struct.new generates subclass of Struct") do
+  begin
+    original_struct = Struct
+    Struct = String
+    assert_equal original_struct, original_struct.new.superclass
+  ensure
+    Struct = original_struct
+  end
+end
+
+assert 'Struct#freeze' do
+  c = Struct.new :m
+
+  o = c.new
+  o.m = :test
+  assert_equal :test, o.m
+
+  o.freeze
+  assert_raise(RuntimeError) { o.m = :modify }
+  assert_raise(RuntimeError) { o[:m] = :modify }
+  assert_equal :test, o.m
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-symbol-ext/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-symbol-ext/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-symbol-ext/mrbgem.rake	(revision 331)
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-symbol-ext') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'Symbol class extension'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-symbol-ext/mrblib/symbol.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-symbol-ext/mrblib/symbol.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-symbol-ext/mrblib/symbol.rb	(revision 331)
@@ -0,0 +1,65 @@
+class Symbol
+  include Comparable
+
+  alias intern to_sym
+
+  def to_proc
+    ->(obj,*args,&block) do
+      obj.__send__(self, *args, &block)
+    end
+  end
+
+  ##
+  # call-seq:
+  #   sym.capitalize  -> symbol
+  #
+  # Same as <code>sym.to_s.capitalize.intern</code>.
+
+  def capitalize
+    (self.to_s.capitalize! || self).to_sym
+  end
+
+  ##
+  # call-seq:
+  #   sym.downcase  -> symbol
+  #
+  # Same as <code>sym.to_s.downcase.intern</code>.
+
+  def downcase
+    (self.to_s.downcase! || self).to_sym
+  end
+
+  ##
+  # call-seq:
+  #   sym.upcase    -> symbol
+  #
+  # Same as <code>sym.to_s.upcase.intern</code>.
+
+  def upcase
+    (self.to_s.upcase! || self).to_sym
+  end
+
+  ##
+  # call-seq:
+  #   sym.casecmp(other)  -> -1, 0, +1 or nil
+  #
+  # Case-insensitive version of <code>Symbol#<=></code>.
+
+  def casecmp(other)
+    return nil unless other.kind_of?(Symbol)
+    lhs =  self.to_s; lhs.upcase!
+    rhs = other.to_s; rhs.upcase!
+    lhs <=> rhs
+  end
+
+  #
+  # call-seq:
+  #   sym.empty?   -> true or false
+  #
+  # Returns that _sym_ is :"" or not.
+
+  def empty?
+    self.length == 0
+  end
+
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-symbol-ext/src/symbol.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-symbol-ext/src/symbol.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-symbol-ext/src/symbol.c	(revision 331)
@@ -0,0 +1,64 @@
+#include <mruby.h>
+#include <mruby/khash.h>
+#include <mruby/array.h>
+
+typedef struct symbol_name {
+  size_t len;
+  const char *name;
+} symbol_name;
+
+/*
+ *  call-seq:
+ *     Symbol.all_symbols    => array
+ *
+ *  Returns an array of all the symbols currently in Ruby's symbol
+ *  table.
+ *
+ *     Symbol.all_symbols.size    #=> 903
+ *     Symbol.all_symbols[1,20]   #=> [:floor, :ARGV, :Binding, :symlink,
+ *                                     :chown, :EOFError, :$;, :String,
+ *                                     :LOCK_SH, :"setuid?", :$<,
+ *                                     :default_proc, :compact, :extend,
+ *                                     :Tms, :getwd, :$=, :ThreadGroup,
+ *                                     :wait2, :$>]
+ */
+static mrb_value
+mrb_sym_all_symbols(mrb_state *mrb, mrb_value self)
+{
+  mrb_sym i, lim;
+  mrb_value ary = mrb_ary_new_capa(mrb, mrb->symidx);
+
+  for (i=1, lim=mrb->symidx+1; i<lim; i++) {
+    mrb_ary_push(mrb, ary, mrb_symbol_value(i));
+  }
+
+  return ary;
+}
+
+/*
+ * call-seq:
+ *   sym.length    -> integer
+ *
+ * Same as <code>sym.to_s.length</code>.
+ */
+static mrb_value
+mrb_sym_length(mrb_state *mrb, mrb_value self)
+{
+  mrb_int len;
+  mrb_sym2name_len(mrb, mrb_symbol(self), &len);
+  return mrb_fixnum_value(len);
+}
+
+void
+mrb_mruby_symbol_ext_gem_init(mrb_state* mrb)
+{
+  struct RClass *s = mrb->symbol_class;
+  mrb_define_class_method(mrb, s, "all_symbols", mrb_sym_all_symbols, MRB_ARGS_NONE());
+  mrb_define_method(mrb, s, "length", mrb_sym_length, MRB_ARGS_NONE());
+  mrb_define_method(mrb, s, "size", mrb_sym_length, MRB_ARGS_NONE());
+}
+
+void
+mrb_mruby_symbol_ext_gem_final(mrb_state* mrb)
+{
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-symbol-ext/test/symbol.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-symbol-ext/test/symbol.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-symbol-ext/test/symbol.rb	(revision 331)
@@ -0,0 +1,48 @@
+##
+# Symbol(Ext) Test
+
+assert('Symbol#to_proc') do
+  assert_equal 5, :abs.to_proc[-5]
+end
+
+assert('Symbol.all_symbols') do
+  foo = [:__symbol_test_1, :__symbol_test_2, :__symbol_test_3].sort
+  symbols = Symbol.all_symbols.select{|sym|sym.to_s.include? '__symbol_test'}.sort
+  assert_equal foo, symbols
+end
+
+assert("Symbol#length") do
+  assert_equal 5, :hello.size
+  assert_equal 5, :mruby.length
+end
+
+assert("Symbol#capitalize") do
+  assert_equal :Hello, :hello.capitalize
+  assert_equal :Hello, :HELLO.capitalize
+  assert_equal :Hello, :Hello.capitalize
+end
+
+assert("Symbol#downcase") do
+  assert_equal :hello, :hEllO.downcase
+  assert_equal :hello, :hello.downcase
+end
+
+assert("Symbol#upcase") do
+  assert_equal :HELLO, :hEllO.upcase
+  assert_equal :HELLO, :HELLO.upcase
+end
+
+assert("Symbol#casecmp") do
+  assert_equal 0, :HELLO.casecmp(:hEllO)
+  assert_equal 1, :HELLO.casecmp(:hEllN)
+  assert_equal(-1, :HELLO.casecmp(:hEllP))
+  assert_nil :HELLO.casecmp("hEllO")
+end
+
+assert("Symbol#empty?") do
+  assert_true :''.empty?
+end
+
+assert('Symbol#intern') do
+  assert_equal :test, :test.intern
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-test/README.md
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-test/README.md	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-test/README.md	(revision 331)
@@ -0,0 +1,7 @@
+Running Tests
+=============
+
+To run the tests, execute the following from the project's root directory.
+
+    $ make test
+
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-test/driver.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-test/driver.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-test/driver.c	(revision 331)
@@ -0,0 +1,172 @@
+/*
+** mrbtest - Test for Embeddable Ruby
+**
+** This program runs Ruby test programs in test/t directory
+** against the current mruby implementation.
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <mruby.h>
+#include <mruby/proc.h>
+#include <mruby/data.h>
+#include <mruby/compile.h>
+#include <mruby/string.h>
+#include <mruby/variable.h>
+#include <mruby/array.h>
+
+void
+mrb_init_mrbtest(mrb_state *);
+
+/* Print a short remark for the user */
+static void
+print_hint(void)
+{
+  printf("mrbtest - Embeddable Ruby Test\n\n");
+}
+
+static int
+check_error(mrb_state *mrb)
+{
+  /* Error check */
+  /* $ko_test and $kill_test should be 0 */
+  mrb_value ko_test = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$ko_test"));
+  mrb_value kill_test = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$kill_test"));
+
+  return mrb_fixnum_p(ko_test) && mrb_fixnum(ko_test) == 0 && mrb_fixnum_p(kill_test) && mrb_fixnum(kill_test) == 0;
+}
+
+static int
+eval_test(mrb_state *mrb)
+{
+  /* evaluate the test */
+  mrb_funcall(mrb, mrb_top_self(mrb), "report", 0);
+  /* did an exception occur? */
+  if (mrb->exc) {
+    mrb_print_error(mrb);
+    mrb->exc = 0;
+    return EXIT_FAILURE;
+  }
+  else if (!check_error(mrb)) {
+    return EXIT_FAILURE;
+  }
+  return EXIT_SUCCESS;
+}
+
+static void
+t_printstr(mrb_state *mrb, mrb_value obj)
+{
+  char *s;
+  int len;
+
+  if (mrb_string_p(obj)) {
+    s = RSTRING_PTR(obj);
+    len = RSTRING_LEN(obj);
+    fwrite(s, len, 1, stdout);
+  }
+}
+
+mrb_value
+mrb_t_printstr(mrb_state *mrb, mrb_value self)
+{
+  mrb_value argv;
+
+  mrb_get_args(mrb, "o", &argv);
+  t_printstr(mrb, argv);
+
+  return argv;
+}
+
+void
+mrb_init_test_driver(mrb_state *mrb, mrb_bool verbose)
+{
+  struct RClass *krn, *mrbtest;
+
+  krn = mrb->kernel_module;
+  mrb_define_method(mrb, krn, "__t_printstr__", mrb_t_printstr, MRB_ARGS_REQ(1));
+
+  mrbtest = mrb_define_module(mrb, "Mrbtest");
+
+  mrb_define_const(mrb, mrbtest, "FIXNUM_MAX", mrb_fixnum_value(MRB_INT_MAX));
+  mrb_define_const(mrb, mrbtest, "FIXNUM_MIN", mrb_fixnum_value(MRB_INT_MIN));
+  mrb_define_const(mrb, mrbtest, "FIXNUM_BIT", mrb_fixnum_value(MRB_INT_BIT));
+
+#ifdef MRB_USE_FLOAT
+  mrb_define_const(mrb, mrbtest, "FLOAT_TOLERANCE", mrb_float_value(mrb, 1e-6));
+#else
+  mrb_define_const(mrb, mrbtest, "FLOAT_TOLERANCE", mrb_float_value(mrb, 1e-12));
+#endif
+
+  if (verbose) {
+    mrb_gv_set(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"), mrb_true_value());
+  }
+}
+
+void
+mrb_t_pass_result(mrb_state *mrb_dst, mrb_state *mrb_src)
+{
+  mrb_value res_src;
+
+  if (mrb_src->exc) {
+    mrb_print_error(mrb_src);
+    exit(EXIT_FAILURE);
+  }
+
+#define TEST_COUNT_PASS(name)                                           \
+  do {                                                                  \
+    res_src = mrb_gv_get(mrb_src, mrb_intern_lit(mrb_src, "$" #name));  \
+    if (mrb_fixnum_p(res_src)) {                                        \
+      mrb_value res_dst = mrb_gv_get(mrb_dst, mrb_intern_lit(mrb_dst, "$" #name)); \
+      mrb_gv_set(mrb_dst, mrb_intern_lit(mrb_dst, "$" #name), mrb_fixnum_value(mrb_fixnum(res_dst) + mrb_fixnum(res_src))); \
+    }                                                                   \
+  } while (FALSE)                                                       \
+
+  TEST_COUNT_PASS(ok_test);
+  TEST_COUNT_PASS(ko_test);
+  TEST_COUNT_PASS(kill_test);
+
+#undef TEST_COUNT_PASS
+
+  res_src = mrb_gv_get(mrb_src, mrb_intern_lit(mrb_src, "$asserts"));
+
+  if (mrb_array_p(res_src)) {
+    mrb_int i;
+    mrb_value res_dst = mrb_gv_get(mrb_dst, mrb_intern_lit(mrb_dst, "$asserts"));
+    for (i = 0; i < RARRAY_LEN(res_src); ++i) {
+      mrb_value val_src = RARRAY_PTR(res_src)[i];
+      mrb_ary_push(mrb_dst, res_dst, mrb_str_new(mrb_dst, RSTRING_PTR(val_src), RSTRING_LEN(val_src)));
+    }
+  }
+}
+
+int
+main(int argc, char **argv)
+{
+  mrb_state *mrb;
+  int ret;
+  mrb_bool verbose = FALSE;
+
+  print_hint();
+
+  /* new interpreter instance */
+  mrb = mrb_open();
+  if (mrb == NULL) {
+    fprintf(stderr, "Invalid mrb_state, exiting test driver");
+    return EXIT_FAILURE;
+  }
+
+  if (argc == 2 && argv[1][0] == '-' && argv[1][1] == 'v') {
+    printf("verbose mode: enable\n\n");
+    verbose = TRUE;
+  }
+
+  mrb_init_test_driver(mrb, verbose);
+  mrb_init_mrbtest(mrb);
+  ret = eval_test(mrb);
+  mrb_close(mrb);
+
+  return ret;
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-test/init_mrbtest.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-test/init_mrbtest.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-test/init_mrbtest.c	(revision 331)
@@ -0,0 +1,38 @@
+#include <stdlib.h>
+#include <mruby.h>
+#include <mruby/irep.h>
+#include <mruby/variable.h>
+
+extern const uint8_t mrbtest_assert_irep[];
+
+void mrbgemtest_init(mrb_state* mrb);
+void mrb_init_test_driver(mrb_state* mrb, mrb_bool verbose);
+void mrb_t_pass_result(mrb_state *mrb_dst, mrb_state *mrb_src);
+
+void
+mrb_init_mrbtest(mrb_state *mrb)
+{
+  mrb_state *core_test;
+
+  mrb_load_irep(mrb, mrbtest_assert_irep);
+
+  core_test = mrb_open_core(mrb_default_allocf, NULL);
+  if (core_test == NULL) {
+    fprintf(stderr, "Invalid mrb_state, exiting %s", __FUNCTION__);
+    exit(EXIT_FAILURE);
+  }
+  mrb_init_test_driver(core_test, mrb_test(mrb_gv_get(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"))));
+  mrb_load_irep(core_test, mrbtest_assert_irep);
+  mrb_t_pass_result(mrb, core_test);
+
+#ifndef DISABLE_GEMS
+  mrbgemtest_init(mrb);
+#endif
+
+  if (mrb->exc) {
+    mrb_print_error(mrb);
+    exit(EXIT_FAILURE);
+  }
+  mrb_close(core_test);
+}
+
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-test/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-test/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-test/mrbgem.rake	(revision 331)
@@ -0,0 +1,187 @@
+MRuby::Gem::Specification.new('mruby-test') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'mruby test'
+
+  build.bins << 'mrbtest'
+  spec.add_dependency('mruby-compiler', :core => 'mruby-compiler')
+
+  spec.test_rbfiles = Dir.glob("#{MRUBY_ROOT}/test/t/*.rb")
+
+  clib = "#{build_dir}/mrbtest.c"
+  mlib = clib.ext(exts.object)
+  exec = exefile("#{build.build_dir}/bin/mrbtest")
+
+  libmruby = libfile("#{build.build_dir}/lib/libmruby")
+  libmruby_core = libfile("#{build.build_dir}/lib/libmruby_core")
+
+  mrbtest_lib = libfile("#{build_dir}/mrbtest")
+  mrbtest_objs = []
+
+  driver_obj = objfile("#{build_dir}/driver")
+  driver = "#{spec.dir}/driver.c"
+
+  assert_c = "#{build_dir}/assert.c"
+  assert_rb = "#{MRUBY_ROOT}/test/assert.rb"
+  assert_lib = assert_c.ext(exts.object)
+  mrbtest_objs << assert_lib
+
+  file assert_lib => assert_c
+  file assert_c => assert_rb do |t|
+    open(t.name, 'w') do |f|
+      mrbc.run f, assert_rb, 'mrbtest_assert_irep'
+    end
+  end
+
+  gem_table = build.gems.generate_gem_table build
+
+  build.gems.each do |g|
+    test_rbobj = g.test_rbireps.ext(exts.object)
+    g.test_objs << test_rbobj
+    dep_list = build.gems.tsort_dependencies(g.test_dependencies, gem_table).select(&:generate_functions)
+
+    file test_rbobj => g.test_rbireps
+    file g.test_rbireps => [g.test_rbfiles].flatten do |t|
+      FileUtils.mkdir_p File.dirname(t.name)
+      open(t.name, 'w') do |f|
+        g.print_gem_test_header(f)
+        test_preload = g.test_preload and [g.dir, MRUBY_ROOT].map {|dir|
+          File.expand_path(g.test_preload, dir)
+        }.find {|file| File.exist?(file) }
+
+        f.puts %Q[/*]
+        f.puts %Q[ * This file contains a test code for #{g.name} gem.]
+        f.puts %Q[ *]
+        f.puts %Q[ * IMPORTANT:]
+        f.puts %Q[ *   This file was generated!]
+        f.puts %Q[ *   All manual changes will get lost.]
+        f.puts %Q[ */]
+        if test_preload.nil?
+          f.puts %Q[extern const uint8_t mrbtest_assert_irep[];]
+        else
+          g.build.mrbc.run f, test_preload, "gem_test_irep_#{g.funcname}_preload"
+        end
+        g.test_rbfiles.flatten.each_with_index do |rbfile, i|
+          g.build.mrbc.run f, rbfile, "gem_test_irep_#{g.funcname}_#{i}"
+        end
+        f.puts %Q[void mrb_#{g.funcname}_gem_test(mrb_state *mrb);] unless g.test_objs.empty?
+        dep_list.each do |d|
+          f.puts %Q[void GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb_state *mrb);]
+          f.puts %Q[void GENERATED_TMP_mrb_#{d.funcname}_gem_final(mrb_state *mrb);]
+        end
+        f.puts %Q[void mrb_init_test_driver(mrb_state *mrb, mrb_bool verbose);]
+        f.puts %Q[void mrb_t_pass_result(mrb_state *dst, mrb_state *src);]
+        f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb) {]
+        unless g.test_rbfiles.empty?
+          f.puts %Q[  mrb_state *mrb2;]
+          unless g.test_args.empty?
+            f.puts %Q[  mrb_value test_args_hash;]
+          end
+          f.puts %Q[  int ai;]
+          g.test_rbfiles.count.times do |i|
+            f.puts %Q[  ai = mrb_gc_arena_save(mrb);]
+            f.puts %Q[  mrb2 = mrb_open_core(mrb_default_allocf, NULL);]
+            f.puts %Q[  if (mrb2 == NULL) {]
+            f.puts %Q[    fprintf(stderr, "Invalid mrb_state, exiting \%s", __FUNCTION__);]
+            f.puts %Q[    exit(EXIT_FAILURE);]
+            f.puts %Q[  }]
+            dep_list.each do |d|
+              f.puts %Q[  GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb2);]
+              f.puts %Q[  mrb_state_atexit(mrb2, GENERATED_TMP_mrb_#{d.funcname}_gem_final);]
+            end
+            f.puts %Q[  mrb_init_test_driver(mrb2, mrb_test(mrb_gv_get(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"))));]
+            if test_preload.nil?
+              f.puts %Q[  mrb_load_irep(mrb2, mrbtest_assert_irep);]
+            else
+              f.puts %Q[  mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_preload);]
+            end
+            f.puts %Q[  if (mrb2->exc) {]
+            f.puts %Q[    mrb_print_error(mrb2);]
+            f.puts %Q[    exit(EXIT_FAILURE);]
+            f.puts %Q[  }]
+            f.puts %Q[  mrb_const_set(mrb2, mrb_obj_value(mrb2->object_class), mrb_intern_lit(mrb2, "GEMNAME"), mrb_str_new(mrb2, "#{g.name}", #{g.name.length}));]
+
+            unless g.test_args.empty?
+              f.puts %Q[  test_args_hash = mrb_hash_new_capa(mrb, #{g.test_args.length}); ]
+              g.test_args.each do |arg_name, arg_value|
+                escaped_arg_name = arg_name.gsub('\\', '\\\\\\\\').gsub('"', '\"')
+                escaped_arg_value = arg_value.gsub('\\', '\\\\\\\\').gsub('"', '\"')
+                f.puts %Q[  mrb_hash_set(mrb2, test_args_hash, mrb_str_new(mrb2, "#{escaped_arg_name.to_s}", #{escaped_arg_name.to_s.length}), mrb_str_new(mrb2, "#{escaped_arg_value.to_s}", #{escaped_arg_value.to_s.length})); ]
+              end
+              f.puts %Q[  mrb_const_set(mrb2, mrb_obj_value(mrb2->object_class), mrb_intern_lit(mrb2, "TEST_ARGS"), test_args_hash); ]
+            end
+
+            f.puts %Q[  mrb_#{g.funcname}_gem_test(mrb2);] if g.custom_test_init?
+
+            f.puts %Q[  mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_#{i});]
+            f.puts %Q[  ]
+
+            f.puts %Q[  mrb_t_pass_result(mrb, mrb2);]
+            f.puts %Q[  mrb_close(mrb2);]
+            f.puts %Q[  mrb_gc_arena_restore(mrb, ai);]
+          end
+        end
+        f.puts %Q[}]
+      end
+    end
+  end
+
+  build.gems.each do |v|
+    mrbtest_objs.concat v.test_objs
+  end
+
+  file mrbtest_lib => mrbtest_objs do |t|
+    build.archiver.run t.name, t.prerequisites
+  end
+
+  unless build.build_mrbtest_lib_only?
+    file exec => [driver_obj, mlib, mrbtest_lib, libmruby_core, libmruby] do |t|
+      gem_flags = build.gems.map { |g| g.linker.flags }
+      gem_flags_before_libraries = build.gems.map { |g| g.linker.flags_before_libraries }
+      gem_flags_after_libraries = build.gems.map { |g| g.linker.flags_after_libraries }
+      gem_libraries = build.gems.map { |g| g.linker.libraries }
+      gem_library_paths = build.gems.map { |g| g.linker.library_paths }
+      build.linker.run t.name, t.prerequisites, gem_libraries, gem_library_paths, gem_flags, gem_flags_before_libraries
+    end
+  end
+
+  init = "#{spec.dir}/init_mrbtest.c"
+
+  # store the last gem selection and make the re-build
+  # of the test gem depending on a change to the gem
+  # selection
+  active_gems = "#{build_dir}/active_gems.lst"
+  FileUtils.mkdir_p File.dirname(active_gems)
+  open(active_gems, 'w+') do |f|
+    build.gems.each do |g|
+      f.puts g.name
+    end
+  end
+  file clib => active_gems
+
+  file mlib => clib
+  file clib => init do |t|
+    _pp "GEN", "*.rb", "#{clib.relative_path}"
+    FileUtils.mkdir_p File.dirname(clib)
+    open(clib, 'w') do |f|
+      f.puts %Q[/*]
+      f.puts %Q[ * This file contains a list of all]
+      f.puts %Q[ * test functions.]
+      f.puts %Q[ *]
+      f.puts %Q[ * IMPORTANT:]
+      f.puts %Q[ *   This file was generated!]
+      f.puts %Q[ *   All manual changes will get lost.]
+      f.puts %Q[ */]
+      f.puts %Q[]
+      f.puts IO.read(init)
+      build.gems.each do |g|
+        f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb);]
+      end
+      f.puts %Q[void mrbgemtest_init(mrb_state* mrb) {]
+      build.gems.each do |g|
+        f.puts %Q[    GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb);]
+      end
+      f.puts %Q[}]
+    end
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-time/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-time/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-time/mrbgem.rake	(revision 331)
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-time') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'standard Time class'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-time/mrblib/time.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-time/mrblib/time.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-time/mrblib/time.rb	(revision 331)
@@ -0,0 +1,9 @@
+class Time
+  def sunday?;  wday == 0 end
+  def monday?;  wday == 1 end
+  def tuesday?;  wday == 2 end
+  def wednesday?;  wday == 3 end
+  def thursday?;  wday == 4 end
+  def friday?;  wday == 5 end
+  def saturday?;  wday == 6 end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-time/src/time.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-time/src/time.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-time/src/time.c	(revision 331)
@@ -0,0 +1,874 @@
+/*
+** time.c - Time class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <math.h>
+#include <time.h>
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+
+#ifndef DISABLE_STDIO
+#include <stdio.h>
+#else
+#include <string.h>
+#endif
+
+#define NDIV(x,y) (-(-((x)+1)/(y))-1)
+
+#if _MSC_VER < 1800
+double round(double x) {
+  if (x >= 0.0) {
+    return (double)((int)(x + 0.5));
+  }
+  else {
+    return (double)((int)(x - 0.5));
+  }
+}
+#endif
+
+#if !defined(__MINGW64__) && defined(_WIN32)
+# define llround(x) round(x)
+#endif
+
+#if defined(__MINGW64__) || defined(__MINGW32__)
+# include <sys/time.h>
+#endif
+
+/** Time class configuration */
+
+/* gettimeofday(2) */
+/* C99 does not have gettimeofday that is required to retrieve microseconds */
+/* uncomment following macro on platforms without gettimeofday(2) */
+/* #define NO_GETTIMEOFDAY */
+
+/* gmtime(3) */
+/* C99 does not have reentrant gmtime_r() so it might cause troubles under */
+/* multi-threading environment.  undef following macro on platforms that */
+/* does not have gmtime_r() and localtime_r(). */
+/* #define NO_GMTIME_R */
+
+#ifdef _WIN32
+#if _MSC_VER
+/* Win32 platform do not provide gmtime_r/localtime_r; emulate them using gmtime_s/localtime_s */
+#define gmtime_r(tp, tm)    ((gmtime_s((tm), (tp)) == 0) ? (tm) : NULL)
+#define localtime_r(tp, tm)    ((localtime_s((tm), (tp)) == 0) ? (tm) : NULL)
+#else
+#define NO_GMTIME_R
+#endif
+#endif
+
+/* asctime(3) */
+/* mruby usually use its own implementation of struct tm to string conversion */
+/* except when DISABLE_STDIO is set. In that case, it uses asctime() or asctime_r(). */
+/* By default mruby tries to use asctime_r() which is reentrant. */
+/* Undef following macro on platforms that does not have asctime_r(). */
+/* #define NO_ASCTIME_R */
+
+/* timegm(3) */
+/* mktime() creates tm structure for localtime; timegm() is for UTC time */
+/* define following macro to use probably faster timegm() on the platform */
+/* #define USE_SYSTEM_TIMEGM */
+
+/** end of Time class configuration */
+
+#ifndef NO_GETTIMEOFDAY
+# ifdef _WIN32
+#  define WIN32_LEAN_AND_MEAN  /* don't include winsock.h */
+#  include <windows.h>
+#  define gettimeofday my_gettimeofday
+
+#  ifdef _MSC_VER
+#    define UI64(x) x##ui64
+#  else
+#    define UI64(x) x##ull
+#  endif
+
+typedef long suseconds_t;
+
+# if (!defined __MINGW64__) && (!defined __MINGW32__)
+struct timeval {
+  time_t tv_sec;
+  suseconds_t tv_usec;
+};
+# endif
+
+static int
+gettimeofday(struct timeval *tv, void *tz)
+{
+  if (tz) {
+    mrb_assert(0);  /* timezone is not supported */
+  }
+  if (tv) {
+    union {
+      FILETIME ft;
+      unsigned __int64 u64;
+    } t;
+    GetSystemTimeAsFileTime(&t.ft);   /* 100 ns intervals since Windows epoch */
+    t.u64 -= UI64(116444736000000000);  /* Unix epoch bias */
+    t.u64 /= 10;                      /* to microseconds */
+    tv->tv_sec = (time_t)(t.u64 / (1000 * 1000));
+    tv->tv_usec = t.u64 % (1000 * 1000);
+  }
+  return 0;
+}
+# else
+#  include <sys/time.h>
+# endif
+#endif
+#ifdef NO_GMTIME_R
+#define gmtime_r(t,r) gmtime(t)
+#define localtime_r(t,r) localtime(t)
+#endif
+
+#ifndef USE_SYSTEM_TIMEGM
+#define timegm my_timgm
+
+static unsigned int
+is_leapyear(unsigned int y)
+{
+  return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0);
+}
+
+static time_t
+timegm(struct tm *tm)
+{
+  static const unsigned int ndays[2][12] = {
+    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
+  };
+  time_t r = 0;
+  int i;
+  unsigned int *nday = (unsigned int*) ndays[is_leapyear(tm->tm_year+1900)];
+
+  for (i = 70; i < tm->tm_year; ++i)
+    r += is_leapyear(i+1900) ? 366*24*60*60 : 365*24*60*60;
+  for (i = 0; i < tm->tm_mon; ++i)
+    r += nday[i] * 24 * 60 * 60;
+  r += (tm->tm_mday - 1) * 24 * 60 * 60;
+  r += tm->tm_hour * 60 * 60;
+  r += tm->tm_min * 60;
+  r += tm->tm_sec;
+  return r;
+}
+#endif
+
+/* Since we are limited to using ISO C99, this implementation is based
+* on time_t. That means the resolution of time is only precise to the
+* second level. Also, there are only 2 timezones, namely UTC and LOCAL.
+*/
+
+enum mrb_timezone {
+  MRB_TIMEZONE_NONE   = 0,
+  MRB_TIMEZONE_UTC    = 1,
+  MRB_TIMEZONE_LOCAL  = 2,
+  MRB_TIMEZONE_LAST   = 3
+};
+
+typedef struct mrb_timezone_name {
+  const char name[8];
+  size_t len;
+} mrb_timezone_name;
+
+static const mrb_timezone_name timezone_names[] = {
+  { "none", sizeof("none") - 1 },
+  { "UTC", sizeof("UTC") - 1 },
+  { "LOCAL", sizeof("LOCAL") - 1 },
+};
+
+#ifndef DISABLE_STDIO
+static const char mon_names[12][4] = {
+  "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
+};
+
+static const char wday_names[7][4] = {
+  "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
+};
+#endif
+
+struct mrb_time {
+  time_t              sec;
+  time_t              usec;
+  enum mrb_timezone   timezone;
+  struct tm           datetime;
+};
+
+static const struct mrb_data_type mrb_time_type = { "Time", mrb_free };
+
+/** Updates the datetime of a mrb_time based on it's timezone and
+seconds setting. Returns self on success, NULL of failure. */
+static struct mrb_time*
+time_update_datetime(mrb_state *mrb, struct mrb_time *self)
+{
+  struct tm *aid;
+
+  if (self->timezone == MRB_TIMEZONE_UTC) {
+    aid = gmtime_r(&self->sec, &self->datetime);
+  }
+  else {
+    aid = localtime_r(&self->sec, &self->datetime);
+  }
+  if (!aid) {
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, (mrb_float)self->sec));
+    /* not reached */
+    return NULL;
+  }
+#ifdef NO_GMTIME_R
+  self->datetime = *aid; /* copy data */
+#endif
+
+  return self;
+}
+
+static mrb_value
+mrb_time_wrap(mrb_state *mrb, struct RClass *tc, struct mrb_time *tm)
+{
+  return mrb_obj_value(Data_Wrap_Struct(mrb, tc, &mrb_time_type, tm));
+}
+
+void mrb_check_num_exact(mrb_state *mrb, mrb_float num);
+
+/* Allocates a mrb_time object and initializes it. */
+static struct mrb_time*
+time_alloc(mrb_state *mrb, double sec, double usec, enum mrb_timezone timezone)
+{
+  struct mrb_time *tm;
+  time_t tsec = 0;
+
+  mrb_check_num_exact(mrb, (mrb_float)sec);
+  mrb_check_num_exact(mrb, (mrb_float)usec);
+
+  if (sizeof(time_t) == 4 && (sec > (double)INT32_MAX || (double)INT32_MIN > sec)) {
+    goto out_of_range;
+  }
+  if (sizeof(time_t) == 8 && (sec > (double)INT64_MAX || (double)INT64_MIN > sec)) {
+    goto out_of_range;
+  }
+  tsec  = (time_t)sec;
+  if ((sec > 0 && tsec < 0) || (sec < 0 && (double)tsec > sec)) {
+  out_of_range:
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, sec));
+  }
+  tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(struct mrb_time));
+  tm->sec  = tsec;
+  tm->usec = (time_t)llround((sec - tm->sec) * 1.0e6 + usec);
+  if (tm->usec < 0) {
+    long sec2 = (long)NDIV(usec,1000000); /* negative div */
+    tm->usec -= sec2 * 1000000;
+    tm->sec += sec2;
+  }
+  else if (tm->usec >= 1000000) {
+    long sec2 = (long)(usec / 1000000);
+    tm->usec -= sec2 * 1000000;
+    tm->sec += sec2;
+  }
+  tm->timezone = timezone;
+  time_update_datetime(mrb, tm);
+
+  return tm;
+}
+
+static mrb_value
+mrb_time_make(mrb_state *mrb, struct RClass *c, double sec, double usec, enum mrb_timezone timezone)
+{
+  return mrb_time_wrap(mrb, c, time_alloc(mrb, sec, usec, timezone));
+}
+
+static struct mrb_time*
+current_mrb_time(mrb_state *mrb)
+{
+  struct mrb_time *tm;
+
+  tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm));
+#if defined(TIME_UTC)
+  {
+    struct timespec ts;
+    if (timespec_get(&ts, TIME_UTC) == 0) {
+      mrb_free(mrb, tm);
+      mrb_raise(mrb, E_RUNTIME_ERROR, "timespec_get() failed for unknown reasons");
+    }
+    tm->sec = ts.tv_sec;
+    tm->usec = ts.tv_nsec / 1000;
+  }
+#elif defined(NO_GETTIMEOFDAY)
+  {
+    static time_t last_sec = 0, last_usec = 0;
+
+    tm->sec  = time(NULL);
+    if (tm->sec != last_sec) {
+      last_sec = tm->sec;
+      last_usec = 0;
+    }
+    else {
+      /* add 1 usec to differentiate two times */
+      last_usec += 1;
+    }
+    tm->usec = last_usec;
+  }
+#else
+  {
+    struct timeval tv;
+
+    gettimeofday(&tv, NULL);
+    tm->sec = tv.tv_sec;
+    tm->usec = tv.tv_usec;
+  }
+#endif
+  tm->timezone = MRB_TIMEZONE_LOCAL;
+  time_update_datetime(mrb, tm);
+
+  return tm;
+}
+
+/* Allocates a new Time object with given millis value. */
+static mrb_value
+mrb_time_now(mrb_state *mrb, mrb_value self)
+{
+  return mrb_time_wrap(mrb, mrb_class_ptr(self), current_mrb_time(mrb));
+}
+
+/* 15.2.19.6.1 */
+/* Creates an instance of time at the given time in seconds, etc. */
+static mrb_value
+mrb_time_at(mrb_state *mrb, mrb_value self)
+{
+  mrb_float f, f2 = 0;
+
+  mrb_get_args(mrb, "f|f", &f, &f2);
+  return mrb_time_make(mrb, mrb_class_ptr(self), f, f2, MRB_TIMEZONE_LOCAL);
+}
+
+static struct mrb_time*
+time_mktime(mrb_state *mrb, mrb_int ayear, mrb_int amonth, mrb_int aday,
+  mrb_int ahour, mrb_int amin, mrb_int asec, mrb_int ausec,
+  enum mrb_timezone timezone)
+{
+  time_t nowsecs;
+  struct tm nowtime = { 0 };
+
+  nowtime.tm_year  = (int)ayear  - 1900;
+  nowtime.tm_mon   = (int)amonth - 1;
+  nowtime.tm_mday  = (int)aday;
+  nowtime.tm_hour  = (int)ahour;
+  nowtime.tm_min   = (int)amin;
+  nowtime.tm_sec   = (int)asec;
+  nowtime.tm_isdst = -1;
+
+  if (nowtime.tm_mon  < 0 || nowtime.tm_mon  > 11
+      || nowtime.tm_mday < 1 || nowtime.tm_mday > 31
+      || nowtime.tm_hour < 0 || nowtime.tm_hour > 24
+      || (nowtime.tm_hour == 24 && (nowtime.tm_min > 0 || nowtime.tm_sec > 0))
+      || nowtime.tm_min  < 0 || nowtime.tm_min  > 59
+      || nowtime.tm_sec  < 0 || nowtime.tm_sec  > 60)
+    mrb_raise(mrb, E_RUNTIME_ERROR, "argument out of range");
+
+  if (timezone == MRB_TIMEZONE_UTC) {
+    nowsecs = timegm(&nowtime);
+  }
+  else {
+    nowsecs = mktime(&nowtime);
+  }
+  if (nowsecs == (time_t)-1) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "Not a valid time.");
+  }
+
+  return time_alloc(mrb, (double)nowsecs, ausec, timezone);
+}
+
+/* 15.2.19.6.2 */
+/* Creates an instance of time at the given time in UTC. */
+static mrb_value
+mrb_time_gm(mrb_state *mrb, mrb_value self)
+{
+  mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0, amin = 0, asec = 0, ausec = 0;
+
+  mrb_get_args(mrb, "i|iiiiii",
+                &ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec);
+  return mrb_time_wrap(mrb, mrb_class_ptr(self),
+          time_mktime(mrb, ayear, amonth, aday, ahour, amin, asec, ausec, MRB_TIMEZONE_UTC));
+}
+
+
+/* 15.2.19.6.3 */
+/* Creates an instance of time at the given time in local time zone. */
+static mrb_value
+mrb_time_local(mrb_state *mrb, mrb_value self)
+{
+  mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0, amin = 0, asec = 0, ausec = 0;
+
+  mrb_get_args(mrb, "i|iiiiii",
+                &ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec);
+  return mrb_time_wrap(mrb, mrb_class_ptr(self),
+          time_mktime(mrb, ayear, amonth, aday, ahour, amin, asec, ausec, MRB_TIMEZONE_LOCAL));
+}
+
+static struct mrb_time*
+time_get_ptr(mrb_state *mrb, mrb_value time)
+{
+  struct mrb_time *tm;
+
+  tm = DATA_GET_PTR(mrb, time, &mrb_time_type, struct mrb_time);
+  if (!tm) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized time");
+  }
+  return tm;
+}
+
+static mrb_value
+mrb_time_eq(mrb_state *mrb, mrb_value self)
+{
+  mrb_value other;
+  struct mrb_time *tm1, *tm2;
+  mrb_bool eq_p;
+
+  mrb_get_args(mrb, "o", &other);
+  tm1 = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);
+  tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time);
+  eq_p = tm1 && tm2 && tm1->sec == tm2->sec && tm1->usec == tm2->usec;
+
+  return mrb_bool_value(eq_p);
+}
+
+static mrb_value
+mrb_time_cmp(mrb_state *mrb, mrb_value self)
+{
+  mrb_value other;
+  struct mrb_time *tm1, *tm2;
+
+  mrb_get_args(mrb, "o", &other);
+  tm1 = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);
+  tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time);
+  if (!tm1 || !tm2) return mrb_nil_value();
+  if (tm1->sec > tm2->sec) {
+    return mrb_fixnum_value(1);
+  }
+  else if (tm1->sec < tm2->sec) {
+    return mrb_fixnum_value(-1);
+  }
+  /* tm1->sec == tm2->sec */
+  if (tm1->usec > tm2->usec) {
+    return mrb_fixnum_value(1);
+  }
+  else if (tm1->usec < tm2->usec) {
+    return mrb_fixnum_value(-1);
+  }
+  return mrb_fixnum_value(0);
+}
+
+static mrb_value
+mrb_time_plus(mrb_state *mrb, mrb_value self)
+{
+  mrb_float f;
+  struct mrb_time *tm;
+
+  mrb_get_args(mrb, "f", &f);
+  tm = time_get_ptr(mrb, self);
+  return mrb_time_make(mrb, mrb_obj_class(mrb, self), (double)tm->sec+f, (double)tm->usec, tm->timezone);
+}
+
+static mrb_value
+mrb_time_minus(mrb_state *mrb, mrb_value self)
+{
+  mrb_float f;
+  mrb_value other;
+  struct mrb_time *tm, *tm2;
+
+  mrb_get_args(mrb, "o", &other);
+  tm = time_get_ptr(mrb, self);
+  tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time);
+  if (tm2) {
+    f = (mrb_float)(tm->sec - tm2->sec)
+      + (mrb_float)(tm->usec - tm2->usec) / 1.0e6;
+    return mrb_float_value(mrb, f);
+  }
+  else {
+    mrb_get_args(mrb, "f", &f);
+    return mrb_time_make(mrb, mrb_obj_class(mrb, self), (double)tm->sec-f, (double)tm->usec, tm->timezone);
+  }
+}
+
+/* 15.2.19.7.30 */
+/* Returns week day number of time. */
+static mrb_value
+mrb_time_wday(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_time *tm;
+
+  tm = time_get_ptr(mrb, self);
+  return mrb_fixnum_value(tm->datetime.tm_wday);
+}
+
+/* 15.2.19.7.31 */
+/* Returns year day number of time. */
+static mrb_value
+mrb_time_yday(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_time *tm;
+
+  tm = time_get_ptr(mrb, self);
+  return mrb_fixnum_value(tm->datetime.tm_yday + 1);
+}
+
+/* 15.2.19.7.32 */
+/* Returns year of time. */
+static mrb_value
+mrb_time_year(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_time *tm;
+
+  tm = time_get_ptr(mrb, self);
+  return mrb_fixnum_value(tm->datetime.tm_year + 1900);
+}
+
+/* 15.2.19.7.33 */
+/* Returns name of time's timezone. */
+static mrb_value
+mrb_time_zone(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_time *tm;
+
+  tm = time_get_ptr(mrb, self);
+  if (tm->timezone <= MRB_TIMEZONE_NONE) return mrb_nil_value();
+  if (tm->timezone >= MRB_TIMEZONE_LAST) return mrb_nil_value();
+  return mrb_str_new_static(mrb,
+                            timezone_names[tm->timezone].name,
+                            timezone_names[tm->timezone].len);
+}
+
+/* 15.2.19.7.4 */
+/* Returns a string that describes the time. */
+static mrb_value
+mrb_time_asctime(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_time *tm = time_get_ptr(mrb, self);
+  struct tm *d = &tm->datetime;
+  int len;
+
+#if defined(DISABLE_STDIO)
+  char *s;
+# ifdef NO_ASCTIME_R
+  s = asctime(d);
+# else
+  char buf[32];
+  s = asctime_r(d, buf);
+# endif
+  len = strlen(s)-1;            /* truncate the last newline */
+#else
+  char buf[256];
+
+  len = snprintf(buf, sizeof(buf), "%s %s %02d %02d:%02d:%02d %s%d",
+    wday_names[d->tm_wday], mon_names[d->tm_mon], d->tm_mday,
+    d->tm_hour, d->tm_min, d->tm_sec,
+    tm->timezone == MRB_TIMEZONE_UTC ? "UTC " : "",
+    d->tm_year + 1900);
+#endif
+  return mrb_str_new(mrb, buf, len);
+}
+
+/* 15.2.19.7.6 */
+/* Returns the day in the month of the time. */
+static mrb_value
+mrb_time_day(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_time *tm;
+
+  tm = time_get_ptr(mrb, self);
+  return mrb_fixnum_value(tm->datetime.tm_mday);
+}
+
+
+/* 15.2.19.7.7 */
+/* Returns true if daylight saving was applied for this time. */
+static mrb_value
+mrb_time_dst_p(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_time *tm;
+
+  tm = time_get_ptr(mrb, self);
+  return mrb_bool_value(tm->datetime.tm_isdst);
+}
+
+/* 15.2.19.7.8 */
+/* 15.2.19.7.10 */
+/* Returns the Time object of the UTC(GMT) timezone. */
+static mrb_value
+mrb_time_getutc(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_time *tm, *tm2;
+
+  tm = time_get_ptr(mrb, self);
+  tm2 = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm));
+  *tm2 = *tm;
+  tm2->timezone = MRB_TIMEZONE_UTC;
+  time_update_datetime(mrb, tm2);
+  return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2);
+}
+
+/* 15.2.19.7.9 */
+/* Returns the Time object of the LOCAL timezone. */
+static mrb_value
+mrb_time_getlocal(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_time *tm, *tm2;
+
+  tm = time_get_ptr(mrb, self);
+  tm2 = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm));
+  *tm2 = *tm;
+  tm2->timezone = MRB_TIMEZONE_LOCAL;
+  time_update_datetime(mrb, tm2);
+  return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2);
+}
+
+/* 15.2.19.7.15 */
+/* Returns hour of time. */
+static mrb_value
+mrb_time_hour(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_time *tm;
+
+  tm = time_get_ptr(mrb, self);
+  return mrb_fixnum_value(tm->datetime.tm_hour);
+}
+
+/* 15.2.19.7.16 */
+/* Initializes a time by setting the amount of milliseconds since the epoch.*/
+static mrb_value
+mrb_time_initialize(mrb_state *mrb, mrb_value self)
+{
+  mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0,
+  amin = 0, asec = 0, ausec = 0;
+  int n;
+  struct mrb_time *tm;
+
+  n = mrb_get_args(mrb, "|iiiiiii",
+       &ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec);
+  tm = (struct mrb_time*)DATA_PTR(self);
+  if (tm) {
+    mrb_free(mrb, tm);
+  }
+  mrb_data_init(self, NULL, &mrb_time_type);
+
+  if (n == 0) {
+    tm = current_mrb_time(mrb);
+  }
+  else {
+    tm = time_mktime(mrb, ayear, amonth, aday, ahour, amin, asec, ausec, MRB_TIMEZONE_LOCAL);
+  }
+  mrb_data_init(self, tm, &mrb_time_type);
+  return self;
+}
+
+/* 15.2.19.7.17(x) */
+/* Initializes a copy of this time object. */
+static mrb_value
+mrb_time_initialize_copy(mrb_state *mrb, mrb_value copy)
+{
+  mrb_value src;
+  struct mrb_time *t1, *t2;
+
+  mrb_get_args(mrb, "o", &src);
+  if (mrb_obj_equal(mrb, copy, src)) return copy;
+  if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) {
+    mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class");
+  }
+  t1 = (struct mrb_time *)DATA_PTR(copy);
+  t2 = (struct mrb_time *)DATA_PTR(src);
+  if (!t2) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized time");
+  }
+  if (!t1) {
+    t1 = (struct mrb_time *)mrb_malloc(mrb, sizeof(struct mrb_time));
+    mrb_data_init(copy, t1, &mrb_time_type);
+  }
+  *t1 = *t2;
+  return copy;
+}
+
+/* 15.2.19.7.18 */
+/* Sets the timezone attribute of the Time object to LOCAL. */
+static mrb_value
+mrb_time_localtime(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_time *tm;
+
+  tm = time_get_ptr(mrb, self);
+  tm->timezone = MRB_TIMEZONE_LOCAL;
+  time_update_datetime(mrb, tm);
+  return self;
+}
+
+/* 15.2.19.7.19 */
+/* Returns day of month of time. */
+static mrb_value
+mrb_time_mday(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_time *tm;
+
+  tm = time_get_ptr(mrb, self);
+  return mrb_fixnum_value(tm->datetime.tm_mday);
+}
+
+/* 15.2.19.7.20 */
+/* Returns minutes of time. */
+static mrb_value
+mrb_time_min(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_time *tm;
+
+  tm = time_get_ptr(mrb, self);
+  return mrb_fixnum_value(tm->datetime.tm_min);
+}
+
+/* 15.2.19.7.21 and 15.2.19.7.22 */
+/* Returns month of time. */
+static mrb_value
+mrb_time_mon(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_time *tm;
+
+  tm = time_get_ptr(mrb, self);
+  return mrb_fixnum_value(tm->datetime.tm_mon + 1);
+}
+
+/* 15.2.19.7.23 */
+/* Returns seconds in minute of time. */
+static mrb_value
+mrb_time_sec(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_time *tm;
+
+  tm = time_get_ptr(mrb, self);
+  return mrb_fixnum_value(tm->datetime.tm_sec);
+}
+
+
+/* 15.2.19.7.24 */
+/* Returns a Float with the time since the epoch in seconds. */
+static mrb_value
+mrb_time_to_f(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_time *tm;
+
+  tm = time_get_ptr(mrb, self);
+  return mrb_float_value(mrb, (mrb_float)tm->sec + (mrb_float)tm->usec/1.0e6);
+}
+
+/* 15.2.19.7.25 */
+/* Returns a Fixnum with the time since the epoch in seconds. */
+static mrb_value
+mrb_time_to_i(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_time *tm;
+
+  tm = time_get_ptr(mrb, self);
+  if (tm->sec > MRB_INT_MAX || tm->sec < MRB_INT_MIN) {
+    return mrb_float_value(mrb, (mrb_float)tm->sec);
+  }
+  return mrb_fixnum_value((mrb_int)tm->sec);
+}
+
+/* 15.2.19.7.26 */
+/* Returns a Float with the time since the epoch in microseconds. */
+static mrb_value
+mrb_time_usec(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_time *tm;
+
+  tm = time_get_ptr(mrb, self);
+  if (tm->usec > MRB_INT_MAX || tm->usec < MRB_INT_MIN) {
+    return mrb_float_value(mrb, (mrb_float)tm->usec);
+  }
+  return mrb_fixnum_value((mrb_int)tm->usec);
+}
+
+/* 15.2.19.7.27 */
+/* Sets the timezone attribute of the Time object to UTC. */
+static mrb_value
+mrb_time_utc(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_time *tm;
+
+  tm = time_get_ptr(mrb, self);
+  tm->timezone = MRB_TIMEZONE_UTC;
+  time_update_datetime(mrb, tm);
+  return self;
+}
+
+/* 15.2.19.7.28 */
+/* Returns true if this time is in the UTC timezone false if not. */
+static mrb_value
+mrb_time_utc_p(mrb_state *mrb, mrb_value self)
+{
+  struct mrb_time *tm;
+
+  tm = time_get_ptr(mrb, self);
+  return mrb_bool_value(tm->timezone == MRB_TIMEZONE_UTC);
+}
+
+
+void
+mrb_mruby_time_gem_init(mrb_state* mrb)
+{
+  struct RClass *tc;
+  /* ISO 15.2.19.2 */
+  tc = mrb_define_class(mrb, "Time", mrb->object_class);
+  MRB_SET_INSTANCE_TT(tc, MRB_TT_DATA);
+  mrb_include_module(mrb, tc, mrb_module_get(mrb, "Comparable"));
+  mrb_define_class_method(mrb, tc, "at", mrb_time_at, MRB_ARGS_ARG(1, 1));      /* 15.2.19.6.1 */
+  mrb_define_class_method(mrb, tc, "gm", mrb_time_gm, MRB_ARGS_ARG(1,6));       /* 15.2.19.6.2 */
+  mrb_define_class_method(mrb, tc, "local", mrb_time_local, MRB_ARGS_ARG(1,6)); /* 15.2.19.6.3 */
+  mrb_define_class_method(mrb, tc, "mktime", mrb_time_local, MRB_ARGS_ARG(1,6));/* 15.2.19.6.4 */
+  mrb_define_class_method(mrb, tc, "now", mrb_time_now, MRB_ARGS_NONE());       /* 15.2.19.6.5 */
+  mrb_define_class_method(mrb, tc, "utc", mrb_time_gm, MRB_ARGS_ARG(1,6));      /* 15.2.19.6.6 */
+
+  mrb_define_method(mrb, tc, "=="     , mrb_time_eq     , MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, tc, "<=>"    , mrb_time_cmp    , MRB_ARGS_REQ(1)); /* 15.2.19.7.1 */
+  mrb_define_method(mrb, tc, "+"      , mrb_time_plus   , MRB_ARGS_REQ(1)); /* 15.2.19.7.2 */
+  mrb_define_method(mrb, tc, "-"      , mrb_time_minus  , MRB_ARGS_REQ(1)); /* 15.2.19.7.3 */
+  mrb_define_method(mrb, tc, "to_s"   , mrb_time_asctime, MRB_ARGS_NONE());
+  mrb_define_method(mrb, tc, "inspect", mrb_time_asctime, MRB_ARGS_NONE());
+  mrb_define_method(mrb, tc, "asctime", mrb_time_asctime, MRB_ARGS_NONE()); /* 15.2.19.7.4 */
+  mrb_define_method(mrb, tc, "ctime"  , mrb_time_asctime, MRB_ARGS_NONE()); /* 15.2.19.7.5 */
+  mrb_define_method(mrb, tc, "day"    , mrb_time_day    , MRB_ARGS_NONE()); /* 15.2.19.7.6 */
+  mrb_define_method(mrb, tc, "dst?"   , mrb_time_dst_p  , MRB_ARGS_NONE()); /* 15.2.19.7.7 */
+  mrb_define_method(mrb, tc, "getgm"  , mrb_time_getutc , MRB_ARGS_NONE()); /* 15.2.19.7.8 */
+  mrb_define_method(mrb, tc, "getlocal",mrb_time_getlocal,MRB_ARGS_NONE()); /* 15.2.19.7.9 */
+  mrb_define_method(mrb, tc, "getutc" , mrb_time_getutc , MRB_ARGS_NONE()); /* 15.2.19.7.10 */
+  mrb_define_method(mrb, tc, "gmt?"   , mrb_time_utc_p  , MRB_ARGS_NONE()); /* 15.2.19.7.11 */
+  mrb_define_method(mrb, tc, "gmtime" , mrb_time_utc    , MRB_ARGS_NONE()); /* 15.2.19.7.13 */
+  mrb_define_method(mrb, tc, "hour"   , mrb_time_hour, MRB_ARGS_NONE());    /* 15.2.19.7.15 */
+  mrb_define_method(mrb, tc, "localtime", mrb_time_localtime, MRB_ARGS_NONE()); /* 15.2.19.7.18 */
+  mrb_define_method(mrb, tc, "mday"   , mrb_time_mday, MRB_ARGS_NONE());    /* 15.2.19.7.19 */
+  mrb_define_method(mrb, tc, "min"    , mrb_time_min, MRB_ARGS_NONE());     /* 15.2.19.7.20 */
+
+  mrb_define_method(mrb, tc, "mon"  , mrb_time_mon, MRB_ARGS_NONE());       /* 15.2.19.7.21 */
+  mrb_define_method(mrb, tc, "month", mrb_time_mon, MRB_ARGS_NONE());       /* 15.2.19.7.22 */
+
+  mrb_define_method(mrb, tc, "sec" , mrb_time_sec, MRB_ARGS_NONE());        /* 15.2.19.7.23 */
+  mrb_define_method(mrb, tc, "to_i", mrb_time_to_i, MRB_ARGS_NONE());       /* 15.2.19.7.25 */
+  mrb_define_method(mrb, tc, "to_f", mrb_time_to_f, MRB_ARGS_NONE());       /* 15.2.19.7.24 */
+  mrb_define_method(mrb, tc, "usec", mrb_time_usec, MRB_ARGS_NONE());       /* 15.2.19.7.26 */
+  mrb_define_method(mrb, tc, "utc" , mrb_time_utc, MRB_ARGS_NONE());        /* 15.2.19.7.27 */
+  mrb_define_method(mrb, tc, "utc?", mrb_time_utc_p,MRB_ARGS_NONE());       /* 15.2.19.7.28 */
+  mrb_define_method(mrb, tc, "wday", mrb_time_wday, MRB_ARGS_NONE());       /* 15.2.19.7.30 */
+  mrb_define_method(mrb, tc, "yday", mrb_time_yday, MRB_ARGS_NONE());       /* 15.2.19.7.31 */
+  mrb_define_method(mrb, tc, "year", mrb_time_year, MRB_ARGS_NONE());       /* 15.2.19.7.32 */
+  mrb_define_method(mrb, tc, "zone", mrb_time_zone, MRB_ARGS_NONE());       /* 15.2.19.7.33 */
+
+  mrb_define_method(mrb, tc, "initialize", mrb_time_initialize, MRB_ARGS_REQ(1)); /* 15.2.19.7.16 */
+  mrb_define_method(mrb, tc, "initialize_copy", mrb_time_initialize_copy, MRB_ARGS_REQ(1)); /* 15.2.19.7.17 */
+
+  /*
+    methods not available:
+      gmt_offset(15.2.19.7.12)
+      gmtoff(15.2.19.7.14)
+      utc_offset(15.2.19.7.29)
+  */
+}
+
+void
+mrb_mruby_time_gem_final(mrb_state* mrb)
+{
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-time/test/time.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-time/test/time.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-time/test/time.rb	(revision 331)
@@ -0,0 +1,228 @@
+##
+# Time ISO Test
+
+assert('Time.new', '15.2.3.3.3') do
+  Time.new.class == Time
+end
+
+assert('Time', '15.2.19') do
+  Time.class == Class
+end
+
+assert('Time.at', '15.2.19.6.1') do
+  assert_kind_of(Time, Time.at(1300000000.0))
+
+  assert_raise(FloatDomainError) { Time.at(Float::NAN) }
+  assert_raise(FloatDomainError) { Time.at(Float::INFINITY) }
+  assert_raise(FloatDomainError) { Time.at(-Float::INFINITY) }
+  assert_raise(FloatDomainError) { Time.at(0, Float::NAN) }
+  assert_raise(FloatDomainError) { Time.at(0, Float::INFINITY) }
+  assert_raise(FloatDomainError) { Time.at(0, -Float::INFINITY) }
+end
+
+assert('Time.gm', '15.2.19.6.2') do
+  Time.gm(2012, 12, 23)
+end
+
+assert('Time.local', '15.2.19.6.3') do
+  Time.local(2012, 12, 23)
+end
+
+assert('Time.mktime', '15.2.19.6.4') do
+  Time.mktime(2012, 12, 23)
+end
+
+assert('Time.now', '15.2.19.6.5') do
+  Time.now.class == Time
+end
+
+assert('Time.utc', '15.2.19.6.6') do
+  Time.utc(2012, 12, 23)
+end
+
+assert('Time#+', '15.2.19.7.1') do
+  t1 = Time.at(1300000000.0)
+  t2 = t1.+(60)
+
+  assert_equal(t2.utc.asctime, "Sun Mar 13 07:07:40 UTC 2011")
+
+  assert_raise(FloatDomainError) { Time.at(0) + Float::NAN }
+  assert_raise(FloatDomainError) { Time.at(0) + Float::INFINITY }
+  assert_raise(FloatDomainError) { Time.at(0) + -Float::INFINITY }
+end
+
+assert('Time#-', '15.2.19.7.2') do
+  t1 = Time.at(1300000000.0)
+  t2 = t1.-(60)
+
+  assert_equal(t2.utc.asctime, "Sun Mar 13 07:05:40 UTC 2011")
+
+  assert_raise(FloatDomainError) { Time.at(0) - Float::NAN }
+  assert_raise(FloatDomainError) { Time.at(0) - Float::INFINITY }
+  assert_raise(FloatDomainError) { Time.at(0) - -Float::INFINITY }
+end
+
+assert('Time#<=>', '15.2.19.7.3') do
+  t1 = Time.at(1300000000.0)
+  t2 = Time.at(1400000000.0)
+  t3 = Time.at(1500000000.0)
+
+  t2.<=>(t1) == 1 and
+    t2.<=>(t2) == 0 and
+    t2.<=>(t3) == -1 and
+    t2.<=>(nil) == nil
+end
+
+assert('Time#asctime', '15.2.19.7.4') do
+  Time.at(1300000000.0).utc.asctime == "Sun Mar 13 07:06:40 UTC 2011"
+end
+
+assert('Time#ctime', '15.2.19.7.5') do
+  Time.at(1300000000.0).utc.ctime == "Sun Mar 13 07:06:40 UTC 2011"
+end
+
+assert('Time#day', '15.2.19.7.6') do
+  Time.gm(2012, 12, 23).day == 23
+end
+
+assert('Time#dst?', '15.2.19.7.7') do
+  not Time.gm(2012, 12, 23).utc.dst?
+end
+
+assert('Time#getgm', '15.2.19.7.8') do
+  Time.at(1300000000.0).getgm.asctime == "Sun Mar 13 07:06:40 UTC 2011"
+end
+
+assert('Time#getlocal', '15.2.19.7.9') do
+  t1 = Time.at(1300000000.0)
+  t2 = Time.at(1300000000.0)
+  t3 = t1.getlocal
+
+  t1 == t3 and t3 == t2.getlocal
+end
+
+assert('Time#getutc', '15.2.19.7.10') do
+  Time.at(1300000000.0).getutc.asctime == "Sun Mar 13 07:06:40 UTC 2011"
+end
+
+assert('Time#gmt?', '15.2.19.7.11') do
+  Time.at(1300000000.0).utc.gmt?
+end
+
+# ATM not implemented
+# assert('Time#gmt_offset', '15.2.19.7.12') do
+
+assert('Time#gmtime', '15.2.19.7.13') do
+  Time.at(1300000000.0).gmtime
+end
+
+# ATM not implemented
+# assert('Time#gmtoff', '15.2.19.7.14') do
+
+assert('Time#hour', '15.2.19.7.15') do
+  Time.gm(2012, 12, 23, 7, 6).hour == 7
+end
+
+# ATM doesn't really work
+# assert('Time#initialize', '15.2.19.7.16') do
+
+assert('Time#initialize_copy', '15.2.19.7.17') do
+  time_tmp_2 = Time.at(7.0e6)
+  time_tmp_2.clone == time_tmp_2
+end
+
+assert('Time#localtime', '15.2.19.7.18') do
+  t1 = Time.at(1300000000.0)
+  t2 = Time.at(1300000000.0)
+
+  t1.localtime
+  t1 == t2.getlocal
+end
+
+assert('Time#mday', '15.2.19.7.19') do
+  Time.gm(2012, 12, 23).mday == 23
+end
+
+assert('Time#min', '15.2.19.7.20') do
+  Time.gm(2012, 12, 23, 7, 6).min == 6
+end
+
+assert('Time#mon', '15.2.19.7.21') do
+  Time.gm(2012, 12, 23).mon == 12
+end
+
+assert('Time#month', '15.2.19.7.22') do
+  Time.gm(2012, 12, 23).month == 12
+end
+
+assert('Times#sec', '15.2.19.7.23') do
+  Time.gm(2012, 12, 23, 7, 6, 40).sec == 40
+end
+
+assert('Time#to_f', '15.2.19.7.24') do
+  Time.at(1300000000.0).to_f == 1300000000.0
+end
+
+assert('Time#to_i', '15.2.19.7.25') do
+  Time.at(1300000000.0).to_i == 1300000000
+end
+
+assert('Time#usec', '15.2.19.7.26') do
+  Time.at(1300000000.0).usec == 0
+end
+
+assert('Time#utc', '15.2.19.7.27') do
+  Time.at(1300000000.0).utc
+end
+
+assert('Time#utc?', '15.2.19.7.28') do
+  Time.at(1300000000.0).utc.utc?
+end
+
+# ATM not implemented
+# assert('Time#utc_offset', '15.2.19.7.29') do
+
+assert('Time#wday', '15.2.19.7.30') do
+  Time.gm(2012, 12, 23).wday == 0
+end
+
+assert('Time#yday', '15.2.19.7.31') do
+  Time.gm(2012, 12, 23).yday == 358
+end
+
+assert('Time#year', '15.2.19.7.32') do
+  Time.gm(2012, 12, 23).year == 2012
+end
+
+assert('Time#zone', '15.2.19.7.33') do
+  Time.at(1300000000.0).utc.zone == 'UTC'
+end
+
+# Not ISO specified
+
+assert('Time#to_s') do
+  Time.at(1300000000.0).utc.to_s == "Sun Mar 13 07:06:40 UTC 2011"
+end
+
+assert('Time#inspect') do
+  Time.at(1300000000.0).utc.inspect == "Sun Mar 13 07:06:40 UTC 2011"
+end
+
+assert('day of week methods') do
+  t = Time.gm(2012, 12, 24)
+  assert_false t.sunday?
+  assert_true t.monday?
+  assert_false t.tuesday?
+  assert_false t.wednesday?
+  assert_false t.thursday?
+  assert_false t.friday?
+  assert_false t.saturday?
+end
+
+assert('2000 times 500us make a second') do
+  t = Time.utc 2015
+  2000.times do
+    t += 0.0005
+  end
+  t.usec == 0
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-toplevel-ext/mrbgem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-toplevel-ext/mrbgem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-toplevel-ext/mrbgem.rake	(revision 331)
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-toplevel-ext') do |spec|
+  spec.license = 'MIT'
+  spec.author  = 'mruby developers'
+  spec.summary = 'toplevel object (main) methods extension'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb	(revision 331)
@@ -0,0 +1,11 @@
+
+def self.include (*modules)
+  self.class.include(*modules)
+end
+
+def self.private(*methods)
+end
+def self.protected(*methods)
+end
+def self.public(*methods)
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-toplevel-ext/test/toplevel.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-toplevel-ext/test/toplevel.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-toplevel-ext/test/toplevel.rb	(revision 331)
@@ -0,0 +1,24 @@
+##
+# Toplevel Self(Ext) Test
+
+assert('Toplevel#include') do
+  module ToplevelTestModule1
+    def method_foo
+      :foo
+    end
+
+    CONST_BAR = :bar
+  end
+
+  module ToplevelTestModule2
+    CONST_BAR = :bar2
+  end
+
+  self.include ToplevelTestModule2, ToplevelTestModule1
+
+  assert_true self.class.included_modules.include?( ToplevelTestModule1 )
+  assert_true self.class.included_modules.include?( ToplevelTestModule2 )
+  assert_equal :foo, method_foo
+  assert_equal :bar2, CONST_BAR
+end
+
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrblib/00class.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrblib/00class.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrblib/00class.rb	(revision 331)
@@ -0,0 +1,26 @@
+class Module
+   # 15.2.2.4.12
+  def attr_accessor(*names)
+    attr_reader(*names)
+    attr_writer(*names)
+  end
+  # 15.2.2.4.11
+  def attr(name)
+    attr_reader(name)
+  end
+
+  # 15.2.2.4.27
+  def include(*args)
+    args.reverse.each do |m|
+      m.append_features(self)
+      m.included(self)
+    end
+  end
+
+  def prepend(*args)
+    args.reverse.each do |m|
+      m.prepend_features(self)
+      m.prepended(self)
+    end
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrblib/10error.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrblib/10error.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrblib/10error.rb	(revision 331)
@@ -0,0 +1,56 @@
+# ISO 15.2.24
+class ArgumentError < StandardError
+end
+
+# ISO 15.2.25
+class LocalJumpError < StandardError
+end
+
+# ISO 15.2.26
+class RangeError < StandardError
+end
+
+class FloatDomainError < RangeError
+end
+
+# ISO 15.2.26
+class RegexpError < StandardError
+end
+
+# ISO 15.2.29
+class TypeError < StandardError
+end
+
+# ISO 15.2.31
+class NameError < StandardError
+  attr_accessor :name
+
+  def initialize(message=nil, name=nil)
+    @name = name
+    super(message)
+  end
+end
+
+# ISO 15.2.32
+class NoMethodError < NameError
+  attr_reader :args
+
+  def initialize(message=nil, name=nil, args=nil)
+    @args = args
+    super message, name
+  end
+end
+
+# ISO 15.2.33
+class IndexError < StandardError
+end
+
+class KeyError < IndexError
+end
+
+class NotImplementedError < ScriptError
+end
+
+class StopIteration < IndexError
+  attr_accessor :result
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrblib/array.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrblib/array.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrblib/array.rb	(revision 331)
@@ -0,0 +1,201 @@
+##
+# Array
+#
+# ISO 15.2.12
+class Array
+
+  ##
+  # Calls the given block for each element of +self+
+  # and pass the respective element.
+  #
+  # ISO 15.2.12.5.10
+  def each(&block)
+    return to_enum :each unless block_given?
+
+    idx = 0
+    while idx < length
+      block.call(self[idx])
+      idx += 1
+    end
+    self
+  end
+
+  ##
+  # Calls the given block for each element of +self+
+  # and pass the index of the respective element.
+  #
+  # ISO 15.2.12.5.11
+  def each_index(&block)
+    return to_enum :each_index unless block_given?
+
+    idx = 0
+    while idx < length
+      block.call(idx)
+      idx += 1
+    end
+    self
+  end
+
+  ##
+  # Calls the given block for each element of +self+
+  # and pass the respective element. Each element will
+  # be replaced by the resulting values.
+  #
+  # ISO 15.2.12.5.7
+  def collect!(&block)
+    return to_enum :collect! unless block_given?
+
+    self.each_index { |idx| self[idx] = block.call(self[idx]) }
+    self
+  end
+
+  ##
+  # Alias for collect!
+  #
+  # ISO 15.2.12.5.20
+  alias map! collect!
+
+  ##
+  # Private method for Array creation.
+  #
+  # ISO 15.2.12.5.15
+  def initialize(size=0, obj=nil, &block)
+    raise TypeError, "expected Integer for 1st argument" unless size.kind_of? Integer
+    raise ArgumentError, "negative array size" if size < 0
+
+    self.clear
+    if size > 0
+      self[size - 1] = nil # allocate
+
+      idx = 0
+      while idx < size
+        self[idx] = (block)? block.call(idx): obj
+        idx += 1
+      end
+    end
+
+    self
+  end
+
+  def _inspect
+    return "[]" if self.size == 0
+    "["+self.map{|x|x.inspect}.join(", ")+"]"
+  end
+  ##
+  # Return the contents of this array as a string.
+  #
+  # ISO 15.2.12.5.31 (x)
+  def inspect
+    begin
+      self._inspect
+    rescue SystemStackError
+      "[...]"
+    end
+  end
+  # ISO 15.2.12.5.32 (x)
+  alias to_s inspect
+
+  ##
+  #  Equality---Two arrays are equal if they contain the same number
+  #  of elements and if each element is equal to (according to
+  #  Object.==) the corresponding element in the other array.
+  #
+  # ISO 15.2.12.5.33 (x)
+  def ==(other)
+    other = self.__ary_eq(other)
+    return false if other == false
+    return true  if other == true
+    len = self.size
+    i = 0
+    while i < len
+      return false if self[i] != other[i]
+      i += 1
+    end
+    return true
+  end
+
+  ##
+  #  Returns <code>true</code> if +self+ and _other_ are the same object,
+  #  or are both arrays with the same content.
+  #
+  # ISO 15.2.12.5.34 (x)
+  def eql?(other)
+    other = self.__ary_eq(other)
+    return false if other == false
+    return true  if other == true
+    len = self.size
+    i = 0
+    while i < len
+      return false unless self[i].eql?(other[i])
+      i += 1
+    end
+    return true
+  end
+
+  ##
+  #  Comparison---Returns an integer (-1, 0, or +1)
+  #  if this array is less than, equal to, or greater than <i>other_ary</i>.
+  #  Each object in each array is compared (using <=>). If any value isn't
+  #  equal, then that inequality is the return value. If all the
+  #  values found are equal, then the return is based on a
+  #  comparison of the array lengths.  Thus, two arrays are
+  #  "equal" according to <code>Array#<=></code> if and only if they have
+  #  the same length and the value of each element is equal to the
+  #  value of the corresponding element in the other array.
+  #
+  # ISO 15.2.12.5.36 (x)
+  def <=>(other)
+    other = self.__ary_cmp(other)
+    return 0 if 0 == other
+    return nil if nil == other
+
+    len = self.size
+    n = other.size
+    len = n if len > n
+    i = 0
+    while i < len
+      n = (self[i] <=> other[i])
+      return n if n.nil? || n != 0
+      i += 1
+    end
+    len = self.size - other.size
+    if len == 0
+      0
+    elsif len > 0
+      1
+    else
+      -1
+    end
+  end
+
+  ##
+  # Delete element with index +key+
+  def delete(key, &block)
+    while i = self.index(key)
+      self.delete_at(i)
+      ret = key
+    end
+    return block.call if ret.nil? && block
+    ret
+  end
+
+  # internal method to convert multi-value to single value
+  def __svalue
+    return self.first if self.size < 2
+    self
+  end
+end
+
+##
+# Array is enumerable
+class Array
+  # ISO 15.2.12.3
+  include Enumerable
+
+  ##
+  # Sort all elements and replace +self+ with these
+  # elements.
+  def sort!(&block)
+    self.replace(self.sort(&block))
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrblib/class.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrblib/class.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrblib/class.rb	(revision 331)
@@ -0,0 +1,11 @@
+class Module
+   # 15.2.2.4.12
+  def attr_accessor(*names)
+    attr_reader(*names)
+    attr_writer(*names)
+  end
+  # 15.2.2.4.11
+  def attr(name)
+    attr_reader(name)
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrblib/compar.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrblib/compar.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrblib/compar.rb	(revision 331)
@@ -0,0 +1,84 @@
+##
+# Comparable
+#
+# ISO 15.3.3
+module Comparable
+
+  ##
+  # Return true if +self+ is less
+  # than +other+. Otherwise return
+  # false.
+  #
+  # ISO 15.3.3.2.1
+  def < other
+    cmp = self <=> other
+    if cmp.nil?
+      raise ArgumentError, "comparison of #{self.class} with #{other.class} failed"
+    end
+    cmp < 0
+  end
+
+  ##
+  # Return true if +self+ is less
+  # than or equal to +other+.
+  # Otherwise return false.
+  #
+  # ISO 15.3.3.2.2
+  def <= other
+    cmp = self <=> other
+    if cmp.nil?
+      raise ArgumentError, "comparison of #{self.class} with #{other.class} failed"
+    end
+    cmp <= 0
+  end
+
+  ##
+  # Return true if +self+ is equal
+  # to +other+. Otherwise return
+  # false.
+  #
+  # ISO 15.3.3.2.3
+  def == other
+    cmp = self <=> other
+    cmp == 0
+  end
+
+  ##
+  # Return true if +self+ is greater
+  # than +other+. Otherwise return
+  # false.
+  #
+  # ISO 15.3.3.2.4
+  def > other
+    cmp = self <=> other
+    if cmp.nil?
+      raise ArgumentError, "comparison of #{self.class} with #{other.class} failed"
+    end
+    cmp > 0
+  end
+
+  ##
+  # Return true if +self+ is greater
+  # than or equal to +other+.
+  # Otherwise return false.
+  #
+  # ISO 15.3.3.2.5
+  def >= other
+    cmp = self <=> other
+    if cmp.nil?
+      raise ArgumentError, "comparison of #{self.class} with #{other.class} failed"
+    end
+    cmp >= 0
+  end
+
+  ##
+  # Return true if +self+ is greater
+  # than or equal to +min+ and
+  # less than or equal to +max+.
+  # Otherwise return false.
+  #
+  # ISO 15.3.3.2.6
+  def between?(min, max)
+    self >= min and self <= max
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrblib/enum.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrblib/enum.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrblib/enum.rb	(revision 331)
@@ -0,0 +1,392 @@
+##
+# Enumerable
+#
+# The <code>Enumerable</code> mixin provides collection classes with
+# several traversal and searching methods, and with the ability to
+# sort. The class must provide a method `each`, which
+# yields successive members of the collection. If
+# {Enumerable#max}, {#min}, or
+# {#sort} is used, the objects in the collection must also
+# implement a meaningful `<=>` operator, as these methods
+# rely on an ordering between members of the collection.
+#
+# @ISO 15.3.2
+module Enumerable
+
+  ##
+  # Call the given block for each element
+  # which is yield by +each+. Return false
+  # if one block value is false. Otherwise
+  # return true. If no block is given and
+  # +self+ is false return false.
+  #
+  # ISO 15.3.2.2.1
+  def all?(&block)
+    if block
+      self.each{|*val| return false unless block.call(*val)}
+    else
+      self.each{|*val| return false unless val.__svalue}
+    end
+    true
+  end
+
+  ##
+  # Call the given block for each element
+  # which is yield by +each+. Return true
+  # if one block value is true. Otherwise
+  # return false. If no block is given and
+  # +self+ is true object return true.
+  #
+  # ISO 15.3.2.2.2
+  def any?(&block)
+    if block
+      self.each{|*val| return true if block.call(*val)}
+    else
+      self.each{|*val| return true if val.__svalue}
+    end
+    false
+  end
+
+  ##
+  # Call the given block for each element
+  # which is yield by +each+. Append all
+  # values of each block together and
+  # return this value.
+  #
+  # ISO 15.3.2.2.3
+  def collect(&block)
+    return to_enum :collect unless block
+
+    ary = []
+    self.each{|*val| ary.push(block.call(*val))}
+    ary
+  end
+
+  ##
+  # Call the given block for each element
+  # which is yield by +each+. Return
+  # +ifnone+ if no block value was true.
+  # Otherwise return the first block value
+  # which had was true.
+  #
+  # ISO 15.3.2.2.4
+  def detect(ifnone=nil, &block)
+    ret = ifnone
+    self.each{|*val|
+      if block.call(*val)
+        ret = val.__svalue
+        break
+      end
+    }
+    ret
+  end
+
+  ##
+  # Call the given block for each element
+  # which is yield by +each+. Pass an
+  # index to the block which starts at 0
+  # and increase by 1 for each element.
+  #
+  # ISO 15.3.2.2.5
+  def each_with_index(&block)
+    return to_enum :each_with_index unless block
+
+    i = 0
+    self.each{|*val|
+      block.call(val.__svalue, i)
+      i += 1
+    }
+    self
+  end
+
+  ##
+  # Return an array of all elements which
+  # are yield by +each+.
+  #
+  # ISO 15.3.2.2.6
+  def entries
+    ary = []
+    self.each{|*val|
+      # __svalue is an internal method
+      ary.push val.__svalue
+    }
+    ary
+  end
+
+  ##
+  # Alias for find
+  #
+  # ISO 15.3.2.2.7
+  alias find detect
+
+  ##
+  # Call the given block for each element
+  # which is yield by +each+. Return an array
+  # which contains all elements whose block
+  # value was true.
+  #
+  # ISO 15.3.2.2.8
+  def find_all(&block)
+    return to_enum :find_all unless block
+
+    ary = []
+    self.each{|*val|
+      ary.push(val.__svalue) if block.call(*val)
+    }
+    ary
+  end
+
+  ##
+  # Call the given block for each element
+  # which is yield by +each+ and which return
+  # value was true when invoking === with
+  # +pattern+. Return an array with all
+  # elements or the respective block values.
+  #
+  # ISO 15.3.2.2.9
+  def grep(pattern, &block)
+    ary = []
+    self.each{|*val|
+      sv = val.__svalue
+      if pattern === sv
+        ary.push((block)? block.call(*val): sv)
+      end
+    }
+    ary
+  end
+
+  ##
+  # Return true if at least one element which
+  # is yield by +each+ returns a true value
+  # by invoking == with +obj+. Otherwise return
+  # false.
+  #
+  # ISO 15.3.2.2.10
+  def include?(obj)
+    self.each{|*val|
+      return true if val.__svalue == obj
+    }
+    false
+  end
+
+  ##
+  # Call the given block for each element
+  # which is yield by +each+. Return value
+  # is the sum of all block values. Pass
+  # to each block the current sum and the
+  # current element.
+  #
+  # ISO 15.3.2.2.11
+  def inject(*args, &block)
+    raise ArgumentError, "too many arguments" if args.size > 2
+    if Symbol === args[-1]
+      sym = args[-1]
+      block = ->(x,y){x.__send__(sym,y)}
+      args.pop
+    end
+    if args.empty?
+      flag = true  # no initial argument
+      result = nil
+    else
+      flag = false
+      result = args[0]
+    end
+    self.each{|*val|
+      val = val.__svalue
+      if flag
+        # push first element as initial
+        flag = false
+        result = val
+      else
+        result = block.call(result, val)
+      end
+    }
+    result
+  end
+  alias reduce inject
+
+  ##
+  # Alias for collect
+  #
+  # ISO 15.3.2.2.12
+  alias map collect
+
+  ##
+  # Return the maximum value of all elements
+  # yield by +each+. If no block is given <=>
+  # will be invoked to define this value. If
+  # a block is given it will be used instead.
+  #
+  # ISO 15.3.2.2.13
+  def max(&block)
+    flag = true  # 1st element?
+    result = nil
+    self.each{|*val|
+      val = val.__svalue
+      if flag
+        # 1st element
+        result = val
+        flag = false
+      else
+        if block
+          result = val if block.call(val, result) > 0
+        else
+          result = val if (val <=> result) > 0
+        end
+      end
+    }
+    result
+  end
+
+  ##
+  # Return the minimum value of all elements
+  # yield by +each+. If no block is given <=>
+  # will be invoked to define this value. If
+  # a block is given it will be used instead.
+  #
+  # ISO 15.3.2.2.14
+  def min(&block)
+    flag = true  # 1st element?
+    result = nil
+    self.each{|*val|
+      val = val.__svalue
+      if flag
+        # 1st element
+        result = val
+        flag = false
+      else
+        if block
+          result = val if block.call(val, result) < 0
+        else
+          result = val if (val <=> result) < 0
+        end
+      end
+    }
+    result
+  end
+
+  ##
+  # Alias for include?
+  #
+  # ISO 15.3.2.2.15
+  alias member? include?
+
+  ##
+  # Call the given block for each element
+  # which is yield by +each+. Return an
+  # array which contains two arrays. The
+  # first array contains all elements
+  # whose block value was true. The second
+  # array contains all elements whose
+  # block value was false.
+  #
+  # ISO 15.3.2.2.16
+  def partition(&block)
+    ary_T = []
+    ary_F = []
+    self.each{|*val|
+      if block.call(*val)
+        ary_T.push(val.__svalue)
+      else
+        ary_F.push(val.__svalue)
+      end
+    }
+    [ary_T, ary_F]
+  end
+
+  ##
+  # Call the given block for each element
+  # which is yield by +each+. Return an
+  # array which contains only the elements
+  # whose block value was false.
+  #
+  # ISO 15.3.2.2.17
+  def reject(&block)
+    ary = []
+    self.each{|*val|
+      ary.push(val.__svalue) unless block.call(*val)
+    }
+    ary
+  end
+
+  ##
+  # Alias for find_all.
+  #
+  # ISO 15.3.2.2.18
+  alias select find_all
+
+  ##
+  # TODO
+  # Does this OK? Please test it.
+  def __sort_sub__(sorted, work, src_ary, head, tail, &block)
+    if head == tail
+      sorted[head] = work[head] if src_ary == 1
+      return
+    end
+
+    # on current step, which is a src ary?
+    if src_ary == 0
+      src, dst = sorted, work
+    else
+      src, dst = work, sorted
+    end
+
+    key = src[head]    # key value for dividing values
+    i, j = head, tail  # position to store on the dst ary
+
+    (head + 1).upto(tail){|idx|
+      if ((block)? block.call(src[idx], key): (src[idx] <=> key)) > 0
+        # larger than key
+        dst[j] = src[idx]
+        j -= 1
+      else
+        dst[i] = src[idx]
+        i += 1
+      end
+    }
+
+    sorted[i] = key
+
+    # sort each sub-array
+    src_ary = (src_ary + 1) % 2  # exchange a src ary
+    __sort_sub__(sorted, work, src_ary, head, i - 1, &block) if i > head
+    __sort_sub__(sorted, work, src_ary, i + 1, tail, &block) if i < tail
+  end
+#  private :__sort_sub__
+
+  ##
+  # Return a sorted array of all elements
+  # which are yield by +each+. If no block
+  # is given <=> will be invoked on each
+  # element to define the order. Otherwise
+  # the given block will be used for
+  # sorting.
+  #
+  # ISO 15.3.2.2.19
+  def sort(&block)
+    ary = []
+    self.each{|*val| ary.push(val.__svalue)}
+    if ary.size > 1
+      __sort_sub__(ary, ::Array.new(ary.size), 0, 0, ary.size - 1, &block)
+    end
+    ary
+  end
+
+  ##
+  # Alias for entries.
+  #
+  # ISO 15.3.2.2.20
+  alias to_a entries
+
+  # redefine #hash 15.3.1.3.15
+  def hash
+    h = 12347
+    i = 0
+    self.each do |e|
+      n = (e.hash & (0x7fffffff >> (i % 16))) << (i % 16)
+      h ^= n
+      i += 1
+    end
+    h
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrblib/error.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrblib/error.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrblib/error.rb	(revision 331)
@@ -0,0 +1,56 @@
+# ISO 15.2.24
+class ArgumentError < StandardError
+end
+
+# ISO 15.2.25
+class LocalJumpError < StandardError
+end
+
+# ISO 15.2.26
+class RangeError < StandardError
+end
+
+class FloatDomainError < RangeError
+end
+
+# ISO 15.2.26
+class RegexpError < StandardError
+end
+
+# ISO 15.2.29
+class TypeError < StandardError
+end
+
+# ISO 15.2.31
+class NameError < StandardError
+  attr_accessor :name
+
+  def initialize(message=nil, name=nil)
+    @name = name
+    super(message)
+  end
+end
+
+# ISO 15.2.32
+class NoMethodError < NameError
+  attr_reader :args
+
+  def initialize(message=nil, name=nil, args=nil)
+    @args = args
+    super message, name
+  end
+end
+
+# ISO 15.2.33
+class IndexError < StandardError
+end
+
+class KeyError < IndexError
+end
+
+class NotImplementedError < ScriptError
+end
+
+class StopIteration < IndexError
+  attr_accessor :result
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrblib/hash.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrblib/hash.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrblib/hash.rb	(revision 331)
@@ -0,0 +1,358 @@
+##
+# Hash
+#
+# ISO 15.2.13
+class Hash
+  ##
+  #  Equality---Two hashes are equal if they each contain the same number
+  #  of keys and if each key-value pair is equal to (according to
+  #  <code>Object#==</code>) the corresponding elements in the other
+  #  hash.
+  #
+  # ISO 15.2.13.4.1
+  def ==(hash)
+    return true if self.equal?(hash)
+    begin
+      hash = hash.to_hash
+    rescue NoMethodError
+      return false
+    end
+    return false if self.size != hash.size
+    self.each do |k,v|
+      return false unless hash.key?(k)
+      return false unless self[k] == hash[k]
+    end
+    return true
+  end
+
+  ##
+  # Returns <code>true</code> if <i>hash</i> and <i>other</i> are
+  # both hashes with the same content compared by eql?.
+  #
+  # ISO 15.2.13.4.32 (x)
+  def eql?(hash)
+    return true if self.equal?(hash)
+    begin
+      hash = hash.to_hash
+    rescue NoMethodError
+      return false
+    end
+    return false if self.size != hash.size
+    self.each do |k,v|
+      return false unless hash.key?(k)
+      return false unless self[k].eql?(hash[k])
+    end
+    return true
+  end
+
+  ##
+  # Delete the element with the key +key+.
+  # Return the value of the element if +key+
+  # was found. Return nil if nothing was
+  # found. If a block is given, call the
+  # block with the value of the element.
+  #
+  # ISO 15.2.13.4.8
+  def delete(key, &block)
+    if block && !self.has_key?(key)
+      block.call(key)
+    else
+      self.__delete(key)
+    end
+  end
+
+  ##
+  # Calls the given block for each element of +self+
+  # and pass the key and value of each element.
+  #
+  # call-seq:
+  #   hsh.each      {| key, value | block } -> hsh
+  #   hsh.each_pair {| key, value | block } -> hsh
+  #   hsh.each                              -> an_enumerator
+  #   hsh.each_pair                         -> an_enumerator
+  #
+  #
+  # If no block is given, an enumerator is returned instead.
+  #
+  #     h = { "a" => 100, "b" => 200 }
+  #     h.each {|key, value| puts "#{key} is #{value}" }
+  #
+  # <em>produces:</em>
+  #
+  # a is 100
+  # b is 200
+  #
+  # ISO 15.2.13.4.9
+  def each(&block)
+    return to_enum :each unless block_given?
+
+    keys = self.keys
+    vals = self.values
+    len = self.size
+    i = 0
+    while i < len
+      block.call [keys[i], vals[i]]
+      i += 1
+    end
+    self
+  end
+
+  ##
+  # Calls the given block for each element of +self+
+  # and pass the key of each element.
+  #
+  # call-seq:
+  #   hsh.each_key {| key | block } -> hsh
+  #   hsh.each_key                  -> an_enumerator
+  #
+  # If no block is given, an enumerator is returned instead.
+  #
+  #   h = { "a" => 100, "b" => 200 }
+  #   h.each_key {|key| puts key }
+  #
+  # <em>produces:</em>
+  #
+  #  a
+  #  b
+  #
+  # ISO 15.2.13.4.10
+  def each_key(&block)
+    return to_enum :each_key unless block_given?
+
+    self.keys.each{|k| block.call(k)}
+    self
+  end
+
+  ##
+  # Calls the given block for each element of +self+
+  # and pass the value of each element.
+  #
+  # call-seq:
+  #   hsh.each_value {| value | block } -> hsh
+  #   hsh.each_value                    -> an_enumerator
+  #
+  # If no block is given, an enumerator is returned instead.
+  #
+  #  h = { "a" => 100, "b" => 200 }
+  #  h.each_value {|value| puts value }
+  #
+  # <em>produces:</em>
+  #
+  #  100
+  #  200
+  #
+  # ISO 15.2.13.4.11
+  def each_value(&block)
+    return to_enum :each_value unless block_given?
+
+    self.keys.each{|k| block.call(self[k])}
+    self
+  end
+
+  ##
+  # Replaces the contents of <i>hsh</i> with the contents of other hash
+  #
+  # ISO 15.2.13.4.23
+  def replace(hash)
+    raise TypeError, "can't convert argument into Hash" unless hash.respond_to?(:to_hash)
+    self.clear
+    hash = hash.to_hash
+    hash.each_key{|k|
+      self[k] = hash[k]
+    }
+    if hash.default_proc
+      self.default_proc = hash.default_proc
+    else
+      self.default = hash.default
+    end
+    self
+  end
+  # ISO 15.2.13.4.17
+  alias initialize_copy replace
+
+  ##
+  # Return a hash which contains the content of
+  # +self+ and +other+. If a block is given
+  # it will be called for each element with
+  # a duplicate key. The value of the block
+  # will be the final value of this element.
+  #
+  # ISO 15.2.13.4.22
+  def merge(other, &block)
+    h = {}
+    raise TypeError, "can't convert argument into Hash" unless other.respond_to?(:to_hash)
+    other = other.to_hash
+    self.each_key{|k| h[k] = self[k]}
+    if block
+      other.each_key{|k|
+        h[k] = (self.has_key?(k))? block.call(k, self[k], other[k]): other[k]
+      }
+    else
+      other.each_key{|k| h[k] = other[k]}
+    end
+    h
+  end
+
+  # internal method for Hash inspection
+  def _inspect
+    return "{}" if self.size == 0
+    "{"+self.map {|k,v|
+      k._inspect + "=>" + v._inspect
+    }.join(", ")+"}"
+  end
+  ##
+  # Return the contents of this hash as a string.
+ #
+  # ISO 15.2.13.4.30 (x)
+  def inspect
+    begin
+      self._inspect
+    rescue SystemStackError
+      "{...}"
+    end
+  end
+  # ISO 15.2.13.4.31 (x)
+  alias to_s inspect
+
+  ##
+  #  call-seq:
+  #     hsh.reject! {| key, value | block }  -> hsh or nil
+  #     hsh.reject!                          -> an_enumerator
+  #
+  #  Equivalent to <code>Hash#delete_if</code>, but returns
+  #  <code>nil</code> if no changes were made.
+  #
+  #  1.8/1.9 Hash#reject! returns Hash; ISO says nothing.
+  #
+  def reject!(&b)
+    return to_enum :reject! unless block_given?
+
+    keys = []
+    self.each{|k,v|
+      if b.call([k, v])
+        keys.push(k)
+      end
+    }
+    return nil if keys.size == 0
+    keys.each{|k|
+      self.delete(k)
+    }
+    self
+  end
+
+  ##
+  #  call-seq:
+  #     hsh.reject {|key, value| block}   -> a_hash
+  #     hsh.reject                        -> an_enumerator
+  #
+  #  Returns a new hash consisting of entries for which the block returns false.
+  #
+  #  If no block is given, an enumerator is returned instead.
+  #
+  #     h = { "a" => 100, "b" => 200, "c" => 300 }
+  #     h.reject {|k,v| k < "b"}  #=> {"b" => 200, "c" => 300}
+  #     h.reject {|k,v| v > 100}  #=> {"a" => 100}
+  #
+  #  1.8/1.9 Hash#reject returns Hash; ISO says nothing.
+  #
+  def reject(&b)
+    return to_enum :reject unless block_given?
+
+    h = {}
+    self.each{|k,v|
+      unless b.call([k, v])
+        h[k] = v
+      end
+    }
+    h
+  end
+
+  ##
+  #  call-seq:
+  #     hsh.select! {| key, value | block }  -> hsh or nil
+  #     hsh.select!                          -> an_enumerator
+  #
+  #  Equivalent to <code>Hash#keep_if</code>, but returns
+  #  <code>nil</code> if no changes were made.
+  #
+  #  1.9 Hash#select! returns Hash; ISO says nothing.
+  #
+  def select!(&b)
+    return to_enum :select! unless block_given?
+
+    keys = []
+    self.each{|k,v|
+      unless b.call([k, v])
+        keys.push(k)
+      end
+    }
+    return nil if keys.size == 0
+    keys.each{|k|
+      self.delete(k)
+    }
+    self
+  end
+
+  ##
+  #  call-seq:
+  #     hsh.select {|key, value| block}   -> a_hash
+  #     hsh.select                        -> an_enumerator
+  #
+  #  Returns a new hash consisting of entries for which the block returns true.
+  #
+  #  If no block is given, an enumerator is returned instead.
+  #
+  #     h = { "a" => 100, "b" => 200, "c" => 300 }
+  #     h.select {|k,v| k > "a"}  #=> {"b" => 200, "c" => 300}
+  #     h.select {|k,v| v < 200}  #=> {"a" => 100}
+  #
+  #  1.9 Hash#select returns Hash; ISO says nothing
+  #
+  def select(&b)
+    return to_enum :select unless block_given?
+
+    h = {}
+    self.each{|k,v|
+      if b.call([k, v])
+        h[k] = v
+      end
+    }
+    h
+  end
+
+  ##
+  #  call-seq:
+  #    hsh.rehash -> hsh
+  #
+  #  Rebuilds the hash based on the current hash values for each key. If
+  #  values of key objects have changed since they were inserted, this
+  #  method will reindex <i>hsh</i>.
+  #
+  #     h = {"AAA" => "b"}
+  #     h.keys[0].chop!
+  #     h          #=> {"AA"=>"b"}
+  #     h["AA"]    #=> nil
+  #     h.rehash   #=> {"AA"=>"b"}
+  #     h["AA"]    #=> "b"
+  #
+  def rehash
+    h = {}
+    self.each{|k,v|
+      h[k] = v
+    }
+    self.replace(h)
+  end
+
+  def __update(h)
+    h.each_key{|k| self[k] = h[k]}
+    self
+  end
+end
+
+##
+# Hash is enumerable
+#
+# ISO 15.2.13.3
+class Hash
+  include Enumerable
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrblib/init_mrblib.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrblib/init_mrblib.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrblib/init_mrblib.c	(revision 331)
@@ -0,0 +1,11 @@
+#include <mruby.h>
+#include <mruby/irep.h>
+
+extern const uint8_t mrblib_irep[];
+
+void
+mrb_init_mrblib(mrb_state *mrb)
+{
+  mrb_load_irep(mrb, mrblib_irep);
+}
+
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrblib/kernel.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrblib/kernel.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrblib/kernel.rb	(revision 331)
@@ -0,0 +1,50 @@
+##
+# Kernel
+#
+# ISO 15.3.1
+module Kernel
+
+  # 15.3.1.2.1 Kernel.`
+  # provided by Kernel#`
+  # 15.3.1.3.5
+  def `(s)
+    raise NotImplementedError.new("backquotes not implemented")
+  end
+
+  ##
+  # 15.3.1.2.3  Kernel.eval
+  # 15.3.1.3.12 Kernel#eval
+  # NotImplemented by mruby core; use mruby-eval gem
+
+  ##
+  # ISO 15.3.1.2.8 Kernel.loop
+  # provided by Kernel#loop
+
+  ##
+  # Calls the given block repetitively.
+  #
+  # ISO 15.3.1.3.29
+  def loop(&block)
+    return to_enum :loop unless block
+
+    while true
+      yield
+    end
+  rescue StopIteration => e
+    e.result
+  end
+
+  # 11.4.4 Step c)
+  def !~(y)
+    !(self =~ y)
+  end
+
+  # internal method for inspect
+  def _inspect
+    self.inspect
+  end
+
+  def to_enum(*a)
+    raise NotImplementedError.new("fiber required for enumerator")
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrblib/mrblib.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrblib/mrblib.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrblib/mrblib.rake	(revision 331)
@@ -0,0 +1,18 @@
+MRuby.each_target do
+  current_dir = File.dirname(__FILE__)
+  relative_from_root = File.dirname(__FILE__).relative_path_from(MRUBY_ROOT)
+  current_build_dir = "#{build_dir}/#{relative_from_root}"
+
+  self.libmruby << objfile("#{current_build_dir}/mrblib")
+
+  file objfile("#{current_build_dir}/mrblib") => "#{current_build_dir}/mrblib.c"
+  file "#{current_build_dir}/mrblib.c" => [mrbcfile, __FILE__] + Dir.glob("#{current_dir}/*.rb").sort do |t|
+    _, _, *rbfiles = t.prerequisites
+    FileUtils.mkdir_p File.dirname(t.name)
+    open(t.name, 'w') do |f|
+      _pp "GEN", "*.rb", "#{t.name.relative_path}"
+      f.puts File.read("#{current_dir}/init_mrblib.c")
+      mrbc.run f, rbfiles, 'mrblib_irep'
+    end
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrblib/numeric.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrblib/numeric.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrblib/numeric.rb	(revision 331)
@@ -0,0 +1,173 @@
+##
+# Numeric
+#
+# ISO 15.2.7
+class Numeric
+  include Comparable
+  ##
+  # Returns the receiver simply.
+  #
+  # ISO 15.2.7.4.1
+  def +@
+    self
+  end
+
+  ##
+  # Returns the receiver's value, negated.
+  #
+  # ISO 15.2.7.4.2
+  def -@
+    0 - self
+  end
+
+  ##
+  # Returns the absolute value of the receiver.
+  #
+  # ISO 15.2.7.4.3
+  def abs
+    if self < 0
+      -self
+    else
+      self
+    end
+  end
+end
+
+##
+# Integral
+#
+# mruby special - module to share methods between Floats and Integers
+#                 to make them compatible
+module Integral
+  ##
+  # Calls the given block once for each Integer
+  # from +self+ downto +num+.
+  #
+  # ISO 15.2.8.3.15
+  def downto(num, &block)
+    return to_enum(:downto, num) unless block_given?
+
+    i = self.to_i
+    while i >= num
+      block.call(i)
+      i -= 1
+    end
+    self
+  end
+
+  ##
+  # Returns self + 1
+  #
+  # ISO 15.2.8.3.19
+  def next
+    self + 1
+  end
+  # ISO 15.2.8.3.21
+  alias succ next
+
+  ##
+  # Calls the given block +self+ times.
+  #
+  # ISO 15.2.8.3.22
+  def times &block
+    return to_enum :times unless block_given?
+
+    i = 0
+    while i < self
+      block.call i
+      i += 1
+    end
+    self
+  end
+
+  ##
+  # Calls the given block once for each Integer
+  # from +self+ upto +num+.
+  #
+  # ISO 15.2.8.3.27
+  def upto(num, &block)
+    return to_enum(:upto, num) unless block_given?
+
+    i = self.to_i
+    while i <= num
+      block.call(i)
+      i += 1
+    end
+    self
+  end
+
+  ##
+  # Calls the given block from +self+ to +num+
+  # incremented by +step+ (default 1).
+  #
+  def step(num=nil, step=1, &block)
+    raise ArgumentError, "step can't be 0" if step == 0
+    return to_enum(:step, num, step) unless block_given?
+
+    i = if num.kind_of? Float then self.to_f else self end
+    if num == nil
+      while true
+        block.call(i)
+        i+=step
+      end
+      return self
+    end
+    if step > 0
+      while i <= num
+        block.call(i)
+        i += step
+      end
+    else
+      while i >= num
+        block.call(i)
+        i += step
+      end
+    end
+    self
+  end
+end
+
+##
+# Integer
+#
+# ISO 15.2.8
+class Integer
+  include Integral
+  ##
+  # Returns the receiver simply.
+  #
+  # ISO 15.2.8.3.14
+  def ceil
+    self
+  end
+
+  ##
+  # Returns the receiver simply.
+  #
+  # ISO 15.2.8.3.17
+  def floor
+    self
+  end
+
+  ##
+  # Returns the receiver simply.
+  #
+  # ISO 15.2.8.3.24
+  alias round floor
+
+  ##
+  # Returns the receiver simply.
+  #
+  # ISO 15.2.8.3.26
+  alias truncate floor
+end
+
+##
+# Float
+#
+# ISO 15.2.9
+class Float
+  # mruby special - since mruby integers may be upgraded to floats,
+  # floats should be compatible to integers.
+  include Integral
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrblib/range.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrblib/range.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrblib/range.rb	(revision 331)
@@ -0,0 +1,67 @@
+##
+# Range
+#
+# ISO 15.2.14
+class Range
+
+  ##
+  # Calls the given block for each element of +self+
+  # and pass the respective element.
+  #
+  # ISO 15.2.14.4.4
+  def each(&block)
+    return to_enum :each unless block_given?
+
+    val = self.first
+    last = self.last
+
+    if val.kind_of?(Fixnum) && last.kind_of?(Fixnum) # fixnums are special
+      lim = last
+      lim += 1 unless exclude_end?
+      i = val
+      while i < lim
+        block.call(i)
+        i += 1
+      end
+      return self
+    end
+
+    if val.kind_of?(String) && last.kind_of?(String) # fixnums are special
+      if val.respond_to? :upto
+        return val.upto(last, exclude_end?, &block)
+      else
+        str_each = true
+      end
+    end
+
+    raise TypeError, "can't iterate" unless val.respond_to? :succ
+
+    return self if (val <=> last) > 0
+
+    while (val <=> last) < 0
+      block.call(val)
+      val = val.succ
+      if str_each
+        break if val.size > last.size
+      end
+    end
+
+    block.call(val) if !exclude_end? && (val <=> last) == 0
+    self
+  end
+
+  # redefine #hash 15.3.1.3.15
+  def hash
+    h = first.hash ^ last.hash
+    h += 1 if self.exclude_end?
+    h
+  end
+end
+
+##
+# Range is enumerable
+#
+# ISO 15.2.14.3
+class Range
+  include Enumerable
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrblib/string.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrblib/string.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrblib/string.rb	(revision 331)
@@ -0,0 +1,275 @@
+##
+# String
+#
+# ISO 15.2.10
+class String
+  include Comparable
+  ##
+  # Calls the given block for each line
+  # and pass the respective line.
+  #
+  # ISO 15.2.10.5.15
+  def each_line(rs = "\n", &block)
+    return to_enum(:each_line, rs, &block) unless block
+    return block.call(self) if rs.nil?
+    rs = rs.to_str
+    offset = 0
+    rs_len = rs.length
+    this = dup
+    while pos = this.index(rs, offset)
+      block.call(this[offset, pos + rs_len - offset])
+      offset = pos + rs_len
+    end
+    block.call(this[offset, this.size - offset]) if this.size > offset
+    self
+  end
+
+  # private method for gsub/sub
+  def __sub_replace(pre, m, post)
+    s = ""
+    i = 0
+    while j = index("\\", i)
+      break if j == length-1
+      t = case self[j+1]
+          when "\\"
+            "\\"
+          when "`"
+            pre
+          when "&", "0"
+            m
+          when "'"
+            post
+          when "1", "2", "3", "4", "5", "6", "7", "8", "9"
+            ""
+          else
+            self[j, 2]
+          end
+      s += self[i, j-i] + t
+      i = j + 2
+    end
+    s + self[i, length-i]
+  end
+
+  ##
+  # Replace all matches of +pattern+ with +replacement+.
+  # Call block (if given) for each match and replace
+  # +pattern+ with the value of the block. Return the
+  # final value.
+  #
+  # ISO 15.2.10.5.18
+  def gsub(*args, &block)
+    return to_enum(:gsub, *args) if args.length == 1 && !block
+    raise ArgumentError, "wrong number of arguments" unless (1..2).include?(args.length)
+
+    pattern, replace = *args
+    plen = pattern.length
+    if args.length == 2 && block
+      block = nil
+    end
+    if !replace.nil? || !block
+      replace = replace.to_str
+    end
+    offset = 0
+    result = []
+    while found = index(pattern, offset)
+      result << self[offset, found - offset]
+      offset = found + plen
+      result << if block
+        block.call(pattern).to_s
+      else
+        replace.__sub_replace(self[0, found], pattern, self[offset..-1] || "")
+      end
+      if plen == 0
+        result << self[offset, 1]
+        offset += 1
+      end
+    end
+    result << self[offset..-1] if offset < length
+    result.join
+  end
+
+  ##
+  # Replace all matches of +pattern+ with +replacement+.
+  # Call block (if given) for each match and replace
+  # +pattern+ with the value of the block. Modify
+  # +self+ with the final value.
+  #
+  # ISO 15.2.10.5.19
+  def gsub!(*args, &block)
+    raise RuntimeError, "can't modify frozen String" if frozen?
+    return to_enum(:gsub!, *args) if args.length == 1 && !block
+    str = self.gsub(*args, &block)
+    return nil if str == self
+    self.replace(str)
+  end
+
+  ##
+  # Calls the given block for each match of +pattern+
+  # If no block is given return an array with all
+  # matches of +pattern+.
+  #
+  # ISO 15.2.10.5.32
+  def scan(reg, &block)
+    ### *** TODO *** ###
+    unless Object.const_defined?(:Regexp)
+      raise NotImplementedError, "scan not available (yet)"
+    end
+  end
+
+  ##
+  # Replace only the first match of +pattern+ with
+  # +replacement+. Call block (if given) for each
+  # match and replace +pattern+ with the value of the
+  # block. Return the final value.
+  #
+  # ISO 15.2.10.5.36
+  def sub(*args, &block)
+    unless (1..2).include?(args.length)
+      raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 2)"
+    end
+
+    pattern, replace = *args
+    pattern = pattern.to_str
+    if args.length == 2 && block
+      block = nil
+    end
+    if !block
+      replace = replace.to_str
+    end
+    result = []
+    this = dup
+    found = index(pattern)
+    return this unless found
+    result << this[0, found]
+    offset = found + pattern.length
+    result << if block
+      block.call(pattern).to_s
+    else
+      replace.__sub_replace(this[0, found], pattern, this[offset..-1] || "")
+    end
+    result << this[offset..-1] if offset < length
+    result.join
+  end
+
+  ##
+  # Replace only the first match of +pattern+ with
+  # +replacement+. Call block (if given) for each
+  # match and replace +pattern+ with the value of the
+  # block. Modify +self+ with the final value.
+  #
+  # ISO 15.2.10.5.37
+  def sub!(*args, &block)
+    raise RuntimeError, "can't modify frozen String" if frozen?
+    str = self.sub(*args, &block)
+    return nil if str == self
+    self.replace(str)
+  end
+
+  ##
+  # Call the given block for each character of
+  # +self+.
+  def each_char(&block)
+    pos = 0
+    while pos < self.size
+      block.call(self[pos])
+      pos += 1
+    end
+    self
+  end
+
+  ##
+  # Call the given block for each byte of +self+.
+  def each_byte(&block)
+    bytes = self.bytes
+    pos = 0
+    while pos < bytes.size
+      block.call(bytes[pos])
+      pos += 1
+    end
+    self
+  end
+
+  ##
+  # Modify +self+ by replacing the content of +self+.
+  # The portion of the string affected is determined using the same criteria as +String#[]+.
+  def []=(*args)
+    anum = args.size
+    if anum == 2
+      pos, value = args
+      case pos
+      when String
+        posnum = self.index(pos)
+        if posnum
+          b = self[0, posnum.to_i]
+          a = self[(posnum + pos.length)..-1]
+          self.replace([b, value, a].join(''))
+        else
+          raise IndexError, "string not matched"
+        end
+      when Range
+        head = pos.begin
+        tail = pos.end
+        tail += self.length if tail < 0
+        unless pos.exclude_end?
+          tail += 1
+        end
+        return self[head, tail-head]=value
+      else
+        pos += self.length if pos < 0
+        if pos < 0 || pos > self.length
+          raise IndexError, "index #{args[0]} out of string"
+        end
+        b = self[0, pos.to_i]
+        a = self[pos + 1..-1]
+        self.replace([b, value, a].join(''))
+      end
+      return value
+    elsif anum == 3
+      pos, len, value = args
+      pos += self.length if pos < 0
+      if pos < 0 || pos > self.length
+        raise IndexError, "index #{args[0]} out of string"
+      end
+      if len < 0
+        raise IndexError, "negative length #{len}"
+      end
+      b = self[0, pos.to_i]
+      a = self[pos + len..-1]
+      self.replace([b, value, a].join(''))
+      return value
+    else
+      raise ArgumentError, "wrong number of arguments (#{anum} for 2..3)"
+    end
+  end
+
+  ##
+  # ISO 15.2.10.5.3
+  def =~(re)
+    raise TypeError, "type mismatch: String given" if re.respond_to? :to_str
+    re =~ self
+  end
+
+  ##
+  # ISO 15.2.10.5.27
+  def match(re, &block)
+    if re.respond_to? :to_str
+      if Object.const_defined?(:Regexp)
+        r = Regexp.new(re)
+        r.match(self, &block)
+      else
+        raise NotImplementedError, "String#match needs Regexp class"
+      end
+    else
+      re.match(self, &block)
+    end
+  end
+end
+
+##
+# String is comparable
+#
+# ISO 15.2.10.3
+module Comparable; end
+class String
+  include Comparable
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/mruby-source.gemspec
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mruby-source.gemspec	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mruby-source.gemspec	(revision 331)
@@ -0,0 +1,18 @@
+# coding: utf-8
+lib = File.expand_path('../lib', __FILE__)
+$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
+require 'mruby/source'
+
+Gem::Specification.new do |spec|
+  spec.name          = "mruby-source"
+  spec.version       = MRuby::Source::MRUBY_VERSION
+  spec.authors       = [ MRuby::Source::MRUBY_AUTHOR ]
+
+  spec.summary       = %q{MRuby source code wrapper.}
+  spec.description   = %q{MRuby source code wrapper for use with Ruby libs.}
+  spec.homepage      = "http://www.mruby.org/"
+  spec.license       = "MIT"
+
+  spec.files         = `git ls-files -z`.split("\x0")
+  spec.require_paths = ["lib"]
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/array.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/array.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/array.c	(revision 331)
@@ -0,0 +1,1182 @@
+/*
+** array.c - Array class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/class.h>
+#include <mruby/string.h>
+#include <mruby/range.h>
+#include "value_array.h"
+
+#define ARY_DEFAULT_LEN   4
+#define ARY_SHRINK_RATIO  5 /* must be larger than 2 */
+#define ARY_C_MAX_SIZE (SIZE_MAX / sizeof(mrb_value))
+#define ARY_MAX_SIZE ((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? (mrb_int)ARY_C_MAX_SIZE : MRB_INT_MAX-1)
+
+static struct RArray*
+ary_new_capa(mrb_state *mrb, mrb_int capa)
+{
+  struct RArray *a;
+  size_t blen;
+
+  if (capa > ARY_MAX_SIZE) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
+  }
+  blen = capa * sizeof(mrb_value);
+
+  a = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class);
+  a->ptr = (mrb_value *)mrb_malloc(mrb, blen);
+  a->aux.capa = capa;
+  a->len = 0;
+
+  return a;
+}
+
+MRB_API mrb_value
+mrb_ary_new_capa(mrb_state *mrb, mrb_int capa)
+{
+  struct RArray *a = ary_new_capa(mrb, capa);
+  return mrb_obj_value(a);
+}
+
+MRB_API mrb_value
+mrb_ary_new(mrb_state *mrb)
+{
+  return mrb_ary_new_capa(mrb, 0);
+}
+
+/*
+ * to copy array, use this instead of memcpy because of portability
+ * * gcc on ARM may fail optimization of memcpy
+ *   http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3934.html
+ * * gcc on MIPS also fail
+ *   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39755
+ * * memcpy doesn't exist on freestanding environment
+ *
+ * If you optimize for binary size, use memcpy instead of this at your own risk
+ * of above portability issue.
+ *
+ * see also http://togetter.com/li/462898
+ *
+ */
+static inline void
+array_copy(mrb_value *dst, const mrb_value *src, mrb_int size)
+{
+  mrb_int i;
+
+  for (i = 0; i < size; i++) {
+    dst[i] = src[i];
+  }
+}
+
+MRB_API mrb_value
+mrb_ary_new_from_values(mrb_state *mrb, mrb_int size, const mrb_value *vals)
+{
+  struct RArray *a = ary_new_capa(mrb, size);
+
+  array_copy(a->ptr, vals, size);
+  a->len = size;
+
+  return mrb_obj_value(a);
+}
+
+MRB_API mrb_value
+mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr)
+{
+  struct RArray *a;
+
+  a = ary_new_capa(mrb, 2);
+  a->ptr[0] = car;
+  a->ptr[1] = cdr;
+  a->len = 2;
+  return mrb_obj_value(a);
+}
+
+static void
+ary_fill_with_nil(mrb_value *ptr, mrb_int size)
+{
+  mrb_value nil = mrb_nil_value();
+
+  while (size--) {
+    *ptr++ = nil;
+  }
+}
+
+static void
+ary_modify(mrb_state *mrb, struct RArray *a)
+{
+  if (MRB_FROZEN_P(a)) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen array");
+  }
+
+  if (ARY_SHARED_P(a)) {
+    mrb_shared_array *shared = a->aux.shared;
+
+    if (shared->refcnt == 1 && a->ptr == shared->ptr) {
+      a->ptr = shared->ptr;
+      a->aux.capa = a->len;
+      mrb_free(mrb, shared);
+    }
+    else {
+      mrb_value *ptr, *p;
+      mrb_int len;
+
+      p = a->ptr;
+      len = a->len * sizeof(mrb_value);
+      ptr = (mrb_value *)mrb_malloc(mrb, len);
+      if (p) {
+        array_copy(ptr, p, a->len);
+      }
+      a->ptr = ptr;
+      a->aux.capa = a->len;
+      mrb_ary_decref(mrb, shared);
+    }
+    ARY_UNSET_SHARED_FLAG(a);
+  }
+}
+
+MRB_API void
+mrb_ary_modify(mrb_state *mrb, struct RArray* a)
+{
+  mrb_write_barrier(mrb, (struct RBasic*)a);
+  ary_modify(mrb, a);
+}
+
+static void
+ary_make_shared(mrb_state *mrb, struct RArray *a)
+{
+  if (!ARY_SHARED_P(a)) {
+    mrb_shared_array *shared = (mrb_shared_array *)mrb_malloc(mrb, sizeof(mrb_shared_array));
+
+    shared->refcnt = 1;
+    if (a->aux.capa > a->len) {
+      a->ptr = shared->ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*a->len+1);
+    }
+    else {
+      shared->ptr = a->ptr;
+    }
+    shared->len = a->len;
+    a->aux.shared = shared;
+    ARY_SET_SHARED_FLAG(a);
+  }
+}
+
+static void
+ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len)
+{
+  mrb_int capa = a->aux.capa;
+
+  if (len > ARY_MAX_SIZE) {
+  size_error:
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
+  }
+
+  if (capa == 0) {
+    capa = ARY_DEFAULT_LEN;
+  }
+  while (capa < len) {
+    if (capa <= ARY_MAX_SIZE / 2) {
+      capa *= 2;
+    }
+    else {
+      capa = len;
+    }
+  }
+  if (capa < len || capa > ARY_MAX_SIZE) {
+    goto size_error;
+  }
+
+  if (capa > a->aux.capa) {
+    mrb_value *expanded_ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*capa);
+
+    a->aux.capa = capa;
+    a->ptr = expanded_ptr;
+  }
+}
+
+static void
+ary_shrink_capa(mrb_state *mrb, struct RArray *a)
+{
+  mrb_int capa = a->aux.capa;
+
+  if (capa < ARY_DEFAULT_LEN * 2) return;
+  if (capa <= a->len * ARY_SHRINK_RATIO) return;
+
+  do {
+    capa /= 2;
+    if (capa < ARY_DEFAULT_LEN) {
+      capa = ARY_DEFAULT_LEN;
+      break;
+    }
+  } while (capa > a->len * ARY_SHRINK_RATIO);
+
+  if (capa > a->len && capa < a->aux.capa) {
+    a->aux.capa = capa;
+    a->ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*capa);
+  }
+}
+
+MRB_API mrb_value
+mrb_ary_resize(mrb_state *mrb, mrb_value ary, mrb_int new_len)
+{
+  mrb_int old_len;
+  struct RArray *a = mrb_ary_ptr(ary);
+
+  ary_modify(mrb, a);
+  old_len = RARRAY_LEN(ary);
+  if (old_len != new_len) {
+    a->len = new_len;
+    if (new_len < old_len) {
+      ary_shrink_capa(mrb, a);
+    }
+    else {
+      ary_expand_capa(mrb, a, new_len);
+      ary_fill_with_nil(a->ptr + old_len, new_len - old_len);
+    }
+  }
+
+  return ary;
+}
+
+static mrb_value
+mrb_ary_s_create(mrb_state *mrb, mrb_value klass)
+{
+  mrb_value ary;
+  mrb_value *vals;
+  mrb_int len;
+  struct RArray *a;
+
+  mrb_get_args(mrb, "*", &vals, &len);
+  ary = mrb_ary_new_from_values(mrb, len, vals);
+  a = mrb_ary_ptr(ary);
+  a->c = mrb_class_ptr(klass);
+
+  return ary;
+}
+
+static void
+ary_concat(mrb_state *mrb, struct RArray *a, struct RArray *a2)
+{
+  mrb_int len;
+
+  if (a2->len > ARY_MAX_SIZE - a->len) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
+  }
+  len = a->len + a2->len;
+
+  ary_modify(mrb, a);
+  if (a->aux.capa < len) {
+    ary_expand_capa(mrb, a, len);
+  }
+  array_copy(a->ptr+a->len, a2->ptr, a2->len);
+  mrb_write_barrier(mrb, (struct RBasic*)a);
+  a->len = len;
+}
+
+MRB_API void
+mrb_ary_concat(mrb_state *mrb, mrb_value self, mrb_value other)
+{
+  struct RArray *a2 = mrb_ary_ptr(other);
+
+  ary_concat(mrb, mrb_ary_ptr(self), a2);
+}
+
+static mrb_value
+mrb_ary_concat_m(mrb_state *mrb, mrb_value self)
+{
+  mrb_value ary;
+
+  mrb_get_args(mrb, "A", &ary);
+  mrb_ary_concat(mrb, self, ary);
+  return self;
+}
+
+static mrb_value
+mrb_ary_plus(mrb_state *mrb, mrb_value self)
+{
+  struct RArray *a1 = mrb_ary_ptr(self);
+  struct RArray *a2;
+  mrb_value *ptr;
+  mrb_int blen;
+
+  mrb_get_args(mrb, "a", &ptr, &blen);
+  if (ARY_MAX_SIZE - blen < a1->len) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
+  }
+  a2 = ary_new_capa(mrb, a1->len + blen);
+  array_copy(a2->ptr, a1->ptr, a1->len);
+  array_copy(a2->ptr + a1->len, ptr, blen);
+  a2->len = a1->len + blen;
+
+  return mrb_obj_value(a2);
+}
+
+static void
+ary_replace(mrb_state *mrb, struct RArray *a, mrb_value *argv, mrb_int len)
+{
+  ary_modify(mrb, a);
+  if (a->aux.capa < len)
+    ary_expand_capa(mrb, a, len);
+  array_copy(a->ptr, argv, len);
+  mrb_write_barrier(mrb, (struct RBasic*)a);
+  a->len = len;
+}
+
+MRB_API void
+mrb_ary_replace(mrb_state *mrb, mrb_value self, mrb_value other)
+{
+  struct RArray *a1 = mrb_ary_ptr(self);
+  struct RArray *a2 = mrb_ary_ptr(other);
+
+  if (a1 != a2) {
+    ary_replace(mrb, a1, a2->ptr, a2->len);
+  }
+}
+
+static mrb_value
+mrb_ary_replace_m(mrb_state *mrb, mrb_value self)
+{
+  mrb_value other;
+
+  mrb_get_args(mrb, "A", &other);
+  mrb_ary_replace(mrb, self, other);
+
+  return self;
+}
+
+static mrb_value
+mrb_ary_times(mrb_state *mrb, mrb_value self)
+{
+  struct RArray *a1 = mrb_ary_ptr(self);
+  struct RArray *a2;
+  mrb_value *ptr;
+  mrb_int times;
+
+  mrb_get_args(mrb, "i", &times);
+  if (times < 0) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument");
+  }
+  if (times == 0) return mrb_ary_new(mrb);
+  if (ARY_MAX_SIZE / times < a1->len) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
+  }
+  a2 = ary_new_capa(mrb, a1->len * times);
+  ptr = a2->ptr;
+  while (times--) {
+    array_copy(ptr, a1->ptr, a1->len);
+    ptr += a1->len;
+    a2->len += a1->len;
+  }
+
+  return mrb_obj_value(a2);
+}
+
+static mrb_value
+mrb_ary_reverse_bang(mrb_state *mrb, mrb_value self)
+{
+  struct RArray *a = mrb_ary_ptr(self);
+
+  if (a->len > 1) {
+    mrb_value *p1, *p2;
+
+    ary_modify(mrb, a);
+    p1 = a->ptr;
+    p2 = a->ptr + a->len - 1;
+
+    while (p1 < p2) {
+      mrb_value tmp = *p1;
+      *p1++ = *p2;
+      *p2-- = tmp;
+    }
+  }
+  return self;
+}
+
+static mrb_value
+mrb_ary_reverse(mrb_state *mrb, mrb_value self)
+{
+  struct RArray *a = mrb_ary_ptr(self), *b = ary_new_capa(mrb, a->len);
+
+  if (a->len > 0) {
+    mrb_value *p1, *p2, *e;
+
+    p1 = a->ptr;
+    e  = p1 + a->len;
+    p2 = b->ptr + a->len - 1;
+    while (p1 < e) {
+      *p2-- = *p1++;
+    }
+    b->len = a->len;
+  }
+  return mrb_obj_value(b);
+}
+
+MRB_API void
+mrb_ary_push(mrb_state *mrb, mrb_value ary, mrb_value elem)
+{
+  struct RArray *a = mrb_ary_ptr(ary);
+
+  ary_modify(mrb, a);
+  if (a->len == a->aux.capa)
+    ary_expand_capa(mrb, a, a->len + 1);
+  a->ptr[a->len++] = elem;
+  mrb_field_write_barrier_value(mrb, (struct RBasic*)a, elem);
+}
+
+static mrb_value
+mrb_ary_push_m(mrb_state *mrb, mrb_value self)
+{
+  mrb_value *argv;
+  mrb_int len;
+
+  mrb_get_args(mrb, "*", &argv, &len);
+  while (len--) {
+    mrb_ary_push(mrb, self, *argv++);
+  }
+
+  return self;
+}
+
+MRB_API mrb_value
+mrb_ary_pop(mrb_state *mrb, mrb_value ary)
+{
+  struct RArray *a = mrb_ary_ptr(ary);
+
+  ary_modify(mrb, a);
+  if (a->len == 0) return mrb_nil_value();
+  return a->ptr[--a->len];
+}
+
+#define ARY_SHIFT_SHARED_MIN 10
+
+MRB_API mrb_value
+mrb_ary_shift(mrb_state *mrb, mrb_value self)
+{
+  struct RArray *a = mrb_ary_ptr(self);
+  mrb_value val;
+
+  ary_modify(mrb, a);
+  if (a->len == 0) return mrb_nil_value();
+  if (ARY_SHARED_P(a)) {
+  L_SHIFT:
+    val = a->ptr[0];
+    a->ptr++;
+    a->len--;
+    return val;
+  }
+  if (a->len > ARY_SHIFT_SHARED_MIN) {
+    ary_make_shared(mrb, a);
+    goto L_SHIFT;
+  }
+  else {
+    mrb_value *ptr = a->ptr;
+    mrb_int size = a->len;
+
+    val = *ptr;
+    while (--size) {
+      *ptr = *(ptr+1);
+      ++ptr;
+    }
+    --a->len;
+  }
+  return val;
+}
+
+/* self = [1,2,3]
+   item = 0
+   self.unshift item
+   p self #=> [0, 1, 2, 3] */
+MRB_API mrb_value
+mrb_ary_unshift(mrb_state *mrb, mrb_value self, mrb_value item)
+{
+  struct RArray *a = mrb_ary_ptr(self);
+
+  if (ARY_SHARED_P(a)
+      && a->aux.shared->refcnt == 1 /* shared only referenced from this array */
+      && a->ptr - a->aux.shared->ptr >= 1) /* there's room for unshifted item */ {
+    a->ptr--;
+    a->ptr[0] = item;
+  }
+  else {
+    ary_modify(mrb, a);
+    if (a->aux.capa < a->len + 1)
+      ary_expand_capa(mrb, a, a->len + 1);
+    value_move(a->ptr + 1, a->ptr, a->len);
+    a->ptr[0] = item;
+  }
+  a->len++;
+  mrb_field_write_barrier_value(mrb, (struct RBasic*)a, item);
+
+  return self;
+}
+
+static mrb_value
+mrb_ary_unshift_m(mrb_state *mrb, mrb_value self)
+{
+  struct RArray *a = mrb_ary_ptr(self);
+  mrb_value *vals;
+  mrb_int len;
+
+  mrb_get_args(mrb, "*", &vals, &len);
+  if (len > ARY_MAX_SIZE - a->len) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
+  }
+  if (ARY_SHARED_P(a)
+      && a->aux.shared->refcnt == 1 /* shared only referenced from this array */
+      && a->ptr - a->aux.shared->ptr >= len) /* there's room for unshifted item */ {
+    a->ptr -= len;
+  }
+  else {
+    ary_modify(mrb, a);
+    if (len == 0) return self;
+    if (a->aux.capa < a->len + len)
+      ary_expand_capa(mrb, a, a->len + len);
+    value_move(a->ptr + len, a->ptr, a->len);
+  }
+  array_copy(a->ptr, vals, len);
+  a->len += len;
+  while (len--) {
+    mrb_field_write_barrier_value(mrb, (struct RBasic*)a, vals[len]);
+  }
+
+  return self;
+}
+
+MRB_API mrb_value
+mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n)
+{
+  struct RArray *a = mrb_ary_ptr(ary);
+
+  /* range check */
+  if (n < 0) n += a->len;
+  if (n < 0 || a->len <= n) return mrb_nil_value();
+
+  return a->ptr[n];
+}
+
+MRB_API void
+mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val)
+{
+  struct RArray *a = mrb_ary_ptr(ary);
+
+  ary_modify(mrb, a);
+  /* range check */
+  if (n < 0) {
+    n += a->len;
+    if (n < 0) {
+      mrb_raisef(mrb, E_INDEX_ERROR, "index %S out of array", mrb_fixnum_value(n - a->len));
+    }
+  }
+  if (a->len <= n) {
+    if (a->aux.capa <= n)
+      ary_expand_capa(mrb, a, n + 1);
+    ary_fill_with_nil(a->ptr + a->len, n + 1 - a->len);
+    a->len = n + 1;
+  }
+
+  a->ptr[n] = val;
+  mrb_field_write_barrier_value(mrb, (struct RBasic*)a, val);
+}
+
+static struct RArray*
+ary_dup(mrb_state *mrb, struct RArray *a)
+{
+  struct RArray *d = ary_new_capa(mrb, a->len);
+
+  ary_replace(mrb, d, a->ptr, a->len);
+  return d;
+}
+
+MRB_API mrb_value
+mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_value rpl)
+{
+  struct RArray *a = mrb_ary_ptr(ary);
+  const mrb_value *argv;
+  mrb_int argc;
+  mrb_int tail;
+
+  ary_modify(mrb, a);
+
+  /* len check */
+  if (len < 0) mrb_raisef(mrb, E_INDEX_ERROR, "negative length (%S)", mrb_fixnum_value(len));
+
+  /* range check */
+  if (head < 0) {
+    head += a->len;
+    if (head < 0) {
+      mrb_raise(mrb, E_INDEX_ERROR, "index is out of array");
+    }
+  }
+  tail = head + len;
+  if (a->len < len || a->len < tail) {
+    len = a->len - head;
+  }
+
+  /* size check */
+  if (mrb_array_p(rpl)) {
+    argc = RARRAY_LEN(rpl);
+    argv = RARRAY_PTR(rpl);
+    if (argv == a->ptr) {
+      struct RArray *r;
+
+      if (argc > 32767) {
+        mrb_raise(mrb, E_ARGUMENT_ERROR, "too big recursive splice");
+      }
+      r = ary_dup(mrb, a);
+      argv = r->ptr;
+    }
+  }
+  else {
+    argc = 1;
+    argv = &rpl;
+  }
+  if (head >= a->len) {
+    if (head > ARY_MAX_SIZE - argc) {
+      mrb_raisef(mrb, E_INDEX_ERROR, "index %S too big", mrb_fixnum_value(head));
+    }
+    len = head + argc;
+    if (len > a->aux.capa) {
+      ary_expand_capa(mrb, a, head + argc);
+    }
+    ary_fill_with_nil(a->ptr + a->len, head - a->len);
+    if (argc > 0) {
+      array_copy(a->ptr + head, argv, argc);
+    }
+    a->len = len;
+  }
+  else {
+    mrb_int alen;
+
+    if (a->len - len > ARY_MAX_SIZE - argc) {
+      mrb_raisef(mrb, E_INDEX_ERROR, "index %S too big", mrb_fixnum_value(a->len + argc - len));
+    }
+    alen = a->len + argc - len;
+    if (alen > a->aux.capa) {
+      ary_expand_capa(mrb, a, alen);
+    }
+
+    if (len != argc) {
+      tail = head + len;
+      value_move(a->ptr + head + argc, a->ptr + tail, a->len - tail);
+      a->len = alen;
+    }
+    if (argc > 0) {
+      value_move(a->ptr + head, argv, argc);
+    }
+  }
+  mrb_write_barrier(mrb, (struct RBasic*)a);
+  return ary;
+}
+
+void
+mrb_ary_decref(mrb_state *mrb, mrb_shared_array *shared)
+{
+  shared->refcnt--;
+  if (shared->refcnt == 0) {
+    mrb_free(mrb, shared->ptr);
+    mrb_free(mrb, shared);
+  }
+}
+
+static mrb_value
+ary_subseq(mrb_state *mrb, struct RArray *a, mrb_int beg, mrb_int len)
+{
+  struct RArray *b;
+
+  ary_make_shared(mrb, a);
+  b  = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class);
+  b->ptr = a->ptr + beg;
+  b->len = len;
+  b->aux.shared = a->aux.shared;
+  b->aux.shared->refcnt++;
+  ARY_SET_SHARED_FLAG(b);
+
+  return mrb_obj_value(b);
+}
+
+static mrb_int
+aget_index(mrb_state *mrb, mrb_value index)
+{
+  if (mrb_fixnum_p(index)) {
+    return mrb_fixnum(index);
+  }
+  else if (mrb_float_p(index)) {
+    return (mrb_int)mrb_float(index);
+  }
+  else {
+    mrb_int i, argc;
+    mrb_value *argv;
+
+    mrb_get_args(mrb, "i*", &i, &argv, &argc);
+    return i;
+  }
+}
+
+/*
+ *  call-seq:
+ *     ary[index]                -> obj     or nil
+ *     ary[start, length]        -> new_ary or nil
+ *     ary[range]                -> new_ary or nil
+ *     ary.slice(index)          -> obj     or nil
+ *     ary.slice(start, length)  -> new_ary or nil
+ *     ary.slice(range)          -> new_ary or nil
+ *
+ *  Element Reference --- Returns the element at +index+, or returns a
+ *  subarray starting at the +start+ index and continuing for +length+
+ *  elements, or returns a subarray specified by +range+ of indices.
+ *
+ *  Negative indices count backward from the end of the array (-1 is the last
+ *  element).  For +start+ and +range+ cases the starting index is just before
+ *  an element.  Additionally, an empty array is returned when the starting
+ *  index for an element range is at the end of the array.
+ *
+ *  Returns +nil+ if the index (or starting index) are out of range.
+ *
+ *  a = [ "a", "b", "c", "d", "e" ]
+ *  a[1]     => "b"
+ *  a[1,2]   => ["b", "c"]
+ *  a[1..-2] => ["b", "c", "d"]
+ *
+ */
+
+static mrb_value
+mrb_ary_aget(mrb_state *mrb, mrb_value self)
+{
+  struct RArray *a = mrb_ary_ptr(self);
+  mrb_int i, len;
+  mrb_value index;
+
+  if (mrb_get_args(mrb, "o|i", &index, &len) == 1) {
+    switch (mrb_type(index)) {
+      /* a[n..m] */
+    case MRB_TT_RANGE:
+      if (mrb_range_beg_len(mrb, index, &i, &len, a->len, TRUE) == 1) {
+        return ary_subseq(mrb, a, i, len);
+      }
+      else {
+        return mrb_nil_value();
+      }
+    case MRB_TT_FIXNUM:
+      return mrb_ary_ref(mrb, self, mrb_fixnum(index));
+    default:
+      return mrb_ary_ref(mrb, self, aget_index(mrb, index));
+    }
+  }
+
+  i = aget_index(mrb, index);
+  if (i < 0) i += a->len;
+  if (i < 0 || a->len < i) return mrb_nil_value();
+  if (len < 0) return mrb_nil_value();
+  if (a->len == i) return mrb_ary_new(mrb);
+  if (len > a->len - i) len = a->len - i;
+
+  return ary_subseq(mrb, a, i, len);
+}
+
+/*
+ *  call-seq:
+ *     ary[index]         = obj                      ->  obj
+ *     ary[start, length] = obj or other_ary or nil  ->  obj or other_ary or nil
+ *     ary[range]         = obj or other_ary or nil  ->  obj or other_ary or nil
+ *
+ *  Element Assignment --- Sets the element at +index+, or replaces a subarray
+ *  from the +start+ index for +length+ elements, or replaces a subarray
+ *  specified by the +range+ of indices.
+ *
+ *  If indices are greater than the current capacity of the array, the array
+ *  grows automatically.  Elements are inserted into the array at +start+ if
+ *  +length+ is zero.
+ *
+ *  Negative indices will count backward from the end of the array.  For
+ *  +start+ and +range+ cases the starting index is just before an element.
+ *
+ *  An IndexError is raised if a negative index points past the beginning of
+ *  the array.
+ *
+ *  See also Array#push, and Array#unshift.
+ *
+ *     a = Array.new
+ *     a[4] = "4";                 #=> [nil, nil, nil, nil, "4"]
+ *     a[0, 3] = [ 'a', 'b', 'c' ] #=> ["a", "b", "c", nil, "4"]
+ *     a[1..2] = [ 1, 2 ]          #=> ["a", 1, 2, nil, "4"]
+ *     a[0, 2] = "?"               #=> ["?", 2, nil, "4"]
+ *     a[0..2] = "A"               #=> ["A", "4"]
+ *     a[-1]   = "Z"               #=> ["A", "Z"]
+ *     a[1..-1] = nil              #=> ["A", nil]
+ *     a[1..-1] = []               #=> ["A"]
+ *     a[0, 0] = [ 1, 2 ]          #=> [1, 2, "A"]
+ *     a[3, 0] = "B"               #=> [1, 2, "A", "B"]
+ */
+
+static mrb_value
+mrb_ary_aset(mrb_state *mrb, mrb_value self)
+{
+  mrb_value v1, v2, v3;
+  mrb_int i, len;
+
+  mrb_ary_modify(mrb, mrb_ary_ptr(self));
+  if (mrb_get_args(mrb, "oo|o", &v1, &v2, &v3) == 2) {
+    /* a[n..m] = v */
+    switch (mrb_range_beg_len(mrb, v1, &i, &len, RARRAY_LEN(self), FALSE)) {
+    case 0:                   /* not range */
+      mrb_ary_set(mrb, self, aget_index(mrb, v1), v2);
+      break;
+    case 1:                   /* range */
+      mrb_ary_splice(mrb, self, i, len, v2);
+      break;
+    case 2:                   /* out of range */
+      mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", v1);
+      break;
+    }
+    return v2;
+  }
+
+  /* a[n,m] = v */
+  mrb_ary_splice(mrb, self, aget_index(mrb, v1), aget_index(mrb, v2), v3);
+  return v3;
+}
+
+static mrb_value
+mrb_ary_delete_at(mrb_state *mrb, mrb_value self)
+{
+  struct RArray *a = mrb_ary_ptr(self);
+  mrb_int   index;
+  mrb_value val;
+  mrb_value *ptr;
+  mrb_int len;
+
+  mrb_get_args(mrb, "i", &index);
+  if (index < 0) index += a->len;
+  if (index < 0 || a->len <= index) return mrb_nil_value();
+
+  ary_modify(mrb, a);
+  val = a->ptr[index];
+
+  ptr = a->ptr + index;
+  len = a->len - index;
+  while (--len) {
+    *ptr = *(ptr+1);
+    ++ptr;
+  }
+  --a->len;
+
+  ary_shrink_capa(mrb, a);
+
+  return val;
+}
+
+static mrb_value
+mrb_ary_first(mrb_state *mrb, mrb_value self)
+{
+  struct RArray *a = mrb_ary_ptr(self);
+  mrb_int size;
+
+  if (mrb_get_args(mrb, "|i", &size) == 0) {
+    return (a->len > 0)? a->ptr[0]: mrb_nil_value();
+  }
+  if (size < 0) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "negative array size");
+  }
+
+  if (size > a->len) size = a->len;
+  if (ARY_SHARED_P(a)) {
+    return ary_subseq(mrb, a, 0, size);
+  }
+  return mrb_ary_new_from_values(mrb, size, a->ptr);
+}
+
+static mrb_value
+mrb_ary_last(mrb_state *mrb, mrb_value self)
+{
+  struct RArray *a = mrb_ary_ptr(self);
+  mrb_int size;
+
+  if (mrb_get_args(mrb, "|i", &size) == 0)
+    return (a->len > 0)? a->ptr[a->len - 1]: mrb_nil_value();
+
+  if (size < 0) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "negative array size");
+  }
+  if (size > a->len) size = a->len;
+  if (ARY_SHARED_P(a) || size > ARY_DEFAULT_LEN) {
+    return ary_subseq(mrb, a, a->len - size, size);
+  }
+  return mrb_ary_new_from_values(mrb, size, a->ptr + a->len - size);
+}
+
+static mrb_value
+mrb_ary_index_m(mrb_state *mrb, mrb_value self)
+{
+  mrb_value obj;
+  mrb_int i;
+
+  mrb_get_args(mrb, "o", &obj);
+  for (i = 0; i < RARRAY_LEN(self); i++) {
+    if (mrb_equal(mrb, RARRAY_PTR(self)[i], obj)) {
+      return mrb_fixnum_value(i);
+    }
+  }
+  return mrb_nil_value();
+}
+
+static mrb_value
+mrb_ary_rindex_m(mrb_state *mrb, mrb_value self)
+{
+  mrb_value obj;
+  mrb_int i, len;
+
+  mrb_get_args(mrb, "o", &obj);
+  for (i = RARRAY_LEN(self) - 1; i >= 0; i--) {
+    if (mrb_equal(mrb, RARRAY_PTR(self)[i], obj)) {
+      return mrb_fixnum_value(i);
+    }
+    if (i > (len = RARRAY_LEN(self))) {
+      i = len;
+    }
+  }
+  return mrb_nil_value();
+}
+
+MRB_API mrb_value
+mrb_ary_splat(mrb_state *mrb, mrb_value v)
+{
+  mrb_value a, recv_class;
+
+  if (mrb_array_p(v)) {
+    return v;
+  }
+
+  if (!mrb_respond_to(mrb, v, mrb_intern_lit(mrb, "to_a"))) {
+    return mrb_ary_new_from_values(mrb, 1, &v);
+  }
+
+  a = mrb_funcall(mrb, v, "to_a", 0);
+  if (mrb_array_p(a)) {
+    return a;
+  }
+  else if (mrb_nil_p(a)) {
+    return mrb_ary_new_from_values(mrb, 1, &v);
+  }
+  else {
+    recv_class = mrb_obj_value(mrb_obj_class(mrb, v));
+    mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Array (%S#to_a gives %S)",
+      recv_class,
+      recv_class,
+      mrb_obj_value(mrb_obj_class(mrb, a))
+    );
+    /* not reached */
+    return mrb_undef_value();
+  }
+}
+
+static mrb_value
+mrb_ary_size(mrb_state *mrb, mrb_value self)
+{
+  struct RArray *a = mrb_ary_ptr(self);
+
+  return mrb_fixnum_value(a->len);
+}
+
+MRB_API mrb_value
+mrb_ary_clear(mrb_state *mrb, mrb_value self)
+{
+  struct RArray *a = mrb_ary_ptr(self);
+
+  ary_modify(mrb, a);
+  if (ARY_SHARED_P(a)) {
+    mrb_ary_decref(mrb, a->aux.shared);
+    ARY_UNSET_SHARED_FLAG(a);
+  }
+  else {
+    mrb_free(mrb, a->ptr);
+  }
+  a->len = 0;
+  a->aux.capa = 0;
+  a->ptr = 0;
+
+  return self;
+}
+
+static mrb_value
+mrb_ary_empty_p(mrb_state *mrb, mrb_value self)
+{
+  struct RArray *a = mrb_ary_ptr(self);
+
+  return mrb_bool_value(a->len == 0);
+}
+
+MRB_API mrb_value
+mrb_check_array_type(mrb_state *mrb, mrb_value ary)
+{
+  return mrb_check_convert_type(mrb, ary, MRB_TT_ARRAY, "Array", "to_ary");
+}
+
+MRB_API mrb_value
+mrb_ary_entry(mrb_value ary, mrb_int offset)
+{
+  if (offset < 0) {
+    offset += RARRAY_LEN(ary);
+  }
+  return ary_elt(ary, offset);
+}
+
+static mrb_value
+join_ary(mrb_state *mrb, mrb_value ary, mrb_value sep, mrb_value list)
+{
+  mrb_int i;
+  mrb_value result, val, tmp;
+
+  /* check recursive */
+  for (i=0; i<RARRAY_LEN(list); i++) {
+    if (mrb_obj_equal(mrb, ary, RARRAY_PTR(list)[i])) {
+      mrb_raise(mrb, E_ARGUMENT_ERROR, "recursive array join");
+    }
+  }
+
+  mrb_ary_push(mrb, list, ary);
+
+  result = mrb_str_buf_new(mrb, 64);
+
+  for (i=0; i<RARRAY_LEN(ary); i++) {
+    if (i > 0 && !mrb_nil_p(sep)) {
+      mrb_str_cat_str(mrb, result, sep);
+    }
+
+    val = RARRAY_PTR(ary)[i];
+    switch (mrb_type(val)) {
+    case MRB_TT_ARRAY:
+    ary_join:
+      val = join_ary(mrb, val, sep, list);
+      /* fall through */
+
+    case MRB_TT_STRING:
+    str_join:
+      mrb_str_cat_str(mrb, result, val);
+      break;
+
+    default:
+      if (!mrb_immediate_p(val)) {
+        tmp = mrb_check_string_type(mrb, val);
+        if (!mrb_nil_p(tmp)) {
+          val = tmp;
+          goto str_join;
+        }
+        tmp = mrb_check_convert_type(mrb, val, MRB_TT_ARRAY, "Array", "to_ary");
+        if (!mrb_nil_p(tmp)) {
+          val = tmp;
+          goto ary_join;
+        }
+      }
+      val = mrb_obj_as_string(mrb, val);
+      goto str_join;
+    }
+  }
+
+  mrb_ary_pop(mrb, list);
+
+  return result;
+}
+
+MRB_API mrb_value
+mrb_ary_join(mrb_state *mrb, mrb_value ary, mrb_value sep)
+{
+  if (!mrb_nil_p(sep)) {
+    sep = mrb_obj_as_string(mrb, sep);
+  }
+  return join_ary(mrb, ary, sep, mrb_ary_new(mrb));
+}
+
+/*
+ *  call-seq:
+ *     ary.join(sep="")    -> str
+ *
+ *  Returns a string created by converting each element of the array to
+ *  a string, separated by <i>sep</i>.
+ *
+ *     [ "a", "b", "c" ].join        #=> "abc"
+ *     [ "a", "b", "c" ].join("-")   #=> "a-b-c"
+ */
+
+static mrb_value
+mrb_ary_join_m(mrb_state *mrb, mrb_value ary)
+{
+  mrb_value sep = mrb_nil_value();
+
+  mrb_get_args(mrb, "|S!", &sep);
+  return mrb_ary_join(mrb, ary, sep);
+}
+
+static mrb_value
+mrb_ary_eq(mrb_state *mrb, mrb_value ary1)
+{
+  mrb_value ary2;
+
+  mrb_get_args(mrb, "o", &ary2);
+  if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value();
+  if (!mrb_array_p(ary2)) {
+    return mrb_false_value();
+  }
+  if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value();
+
+  return ary2;
+}
+
+static mrb_value
+mrb_ary_cmp(mrb_state *mrb, mrb_value ary1)
+{
+  mrb_value ary2;
+
+  mrb_get_args(mrb, "o", &ary2);
+  if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_fixnum_value(0);
+  if (!mrb_array_p(ary2)) {
+    return mrb_nil_value();
+  }
+
+  return ary2;
+}
+
+void
+mrb_init_array(mrb_state *mrb)
+{
+  struct RClass *a;
+
+  mrb->array_class = a = mrb_define_class(mrb, "Array", mrb->object_class);            /* 15.2.12 */
+  MRB_SET_INSTANCE_TT(a, MRB_TT_ARRAY);
+
+  mrb_define_class_method(mrb, a, "[]",        mrb_ary_s_create,     MRB_ARGS_ANY());  /* 15.2.12.4.1 */
+
+  mrb_define_method(mrb, a, "+",               mrb_ary_plus,         MRB_ARGS_REQ(1)); /* 15.2.12.5.1  */
+  mrb_define_method(mrb, a, "*",               mrb_ary_times,        MRB_ARGS_REQ(1)); /* 15.2.12.5.2  */
+  mrb_define_method(mrb, a, "<<",              mrb_ary_push_m,       MRB_ARGS_REQ(1)); /* 15.2.12.5.3  */
+  mrb_define_method(mrb, a, "[]",              mrb_ary_aget,         MRB_ARGS_ANY());  /* 15.2.12.5.4  */
+  mrb_define_method(mrb, a, "[]=",             mrb_ary_aset,         MRB_ARGS_ANY());  /* 15.2.12.5.5  */
+  mrb_define_method(mrb, a, "clear",           mrb_ary_clear,        MRB_ARGS_NONE()); /* 15.2.12.5.6  */
+  mrb_define_method(mrb, a, "concat",          mrb_ary_concat_m,     MRB_ARGS_REQ(1)); /* 15.2.12.5.8  */
+  mrb_define_method(mrb, a, "delete_at",       mrb_ary_delete_at,    MRB_ARGS_REQ(1)); /* 15.2.12.5.9  */
+  mrb_define_method(mrb, a, "empty?",          mrb_ary_empty_p,      MRB_ARGS_NONE()); /* 15.2.12.5.12 */
+  mrb_define_method(mrb, a, "first",           mrb_ary_first,        MRB_ARGS_OPT(1)); /* 15.2.12.5.13 */
+  mrb_define_method(mrb, a, "index",           mrb_ary_index_m,      MRB_ARGS_REQ(1)); /* 15.2.12.5.14 */
+  mrb_define_method(mrb, a, "initialize_copy", mrb_ary_replace_m,    MRB_ARGS_REQ(1)); /* 15.2.12.5.16 */
+  mrb_define_method(mrb, a, "join",            mrb_ary_join_m,       MRB_ARGS_ANY());  /* 15.2.12.5.17 */
+  mrb_define_method(mrb, a, "last",            mrb_ary_last,         MRB_ARGS_ANY());  /* 15.2.12.5.18 */
+  mrb_define_method(mrb, a, "length",          mrb_ary_size,         MRB_ARGS_NONE()); /* 15.2.12.5.19 */
+  mrb_define_method(mrb, a, "pop",             mrb_ary_pop,          MRB_ARGS_NONE()); /* 15.2.12.5.21 */
+  mrb_define_method(mrb, a, "push",            mrb_ary_push_m,       MRB_ARGS_ANY());  /* 15.2.12.5.22 */
+  mrb_define_method(mrb, a, "append",          mrb_ary_push_m,       MRB_ARGS_ANY());
+  mrb_define_method(mrb, a, "replace",         mrb_ary_replace_m,    MRB_ARGS_REQ(1)); /* 15.2.12.5.23 */
+  mrb_define_method(mrb, a, "reverse",         mrb_ary_reverse,      MRB_ARGS_NONE()); /* 15.2.12.5.24 */
+  mrb_define_method(mrb, a, "reverse!",        mrb_ary_reverse_bang, MRB_ARGS_NONE()); /* 15.2.12.5.25 */
+  mrb_define_method(mrb, a, "rindex",          mrb_ary_rindex_m,     MRB_ARGS_REQ(1)); /* 15.2.12.5.26 */
+  mrb_define_method(mrb, a, "shift",           mrb_ary_shift,        MRB_ARGS_NONE()); /* 15.2.12.5.27 */
+  mrb_define_method(mrb, a, "size",            mrb_ary_size,         MRB_ARGS_NONE()); /* 15.2.12.5.28 */
+  mrb_define_method(mrb, a, "slice",           mrb_ary_aget,         MRB_ARGS_ANY());  /* 15.2.12.5.29 */
+  mrb_define_method(mrb, a, "unshift",         mrb_ary_unshift_m,    MRB_ARGS_ANY());  /* 15.2.12.5.30 */
+  mrb_define_method(mrb, a, "prepend",         mrb_ary_unshift_m,    MRB_ARGS_ANY());
+
+  mrb_define_method(mrb, a, "__ary_eq",        mrb_ary_eq,           MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, a, "__ary_cmp",       mrb_ary_cmp,          MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, a, "__ary_index",     mrb_ary_index_m,      MRB_ARGS_REQ(1)); /* kept for mruby-array-ext */
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/backtrace.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/backtrace.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/backtrace.c	(revision 331)
@@ -0,0 +1,248 @@
+/*
+** backtrace.c -
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <mruby.h>
+#include <mruby/variable.h>
+#include <mruby/proc.h>
+#include <mruby/array.h>
+#include <mruby/string.h>
+#include <mruby/class.h>
+#include <mruby/debug.h>
+#include <mruby/error.h>
+#include <mruby/numeric.h>
+#include <mruby/data.h>
+
+struct backtrace_location {
+  int lineno;
+  const char *filename;
+  mrb_sym method_id;
+};
+
+typedef void (*each_backtrace_func)(mrb_state*, int i, struct backtrace_location*, void*);
+
+static const mrb_data_type bt_type = { "Backtrace", mrb_free };
+
+static void
+each_backtrace(mrb_state *mrb, mrb_int ciidx, mrb_code *pc0, each_backtrace_func func, void *data)
+{
+  int i, j;
+
+  if (ciidx >= mrb->c->ciend - mrb->c->cibase)
+    ciidx = 10; /* ciidx is broken... */
+
+  for (i=ciidx, j=0; i >= 0; i--,j++) {
+    struct backtrace_location loc;
+    mrb_callinfo *ci;
+    mrb_irep *irep;
+    mrb_code *pc;
+
+    ci = &mrb->c->cibase[i];
+
+    if (!ci->proc) continue;
+    if (MRB_PROC_CFUNC_P(ci->proc)) continue;
+
+    irep = ci->proc->body.irep;
+    if (!irep) continue;
+
+    if (mrb->c->cibase[i].err) {
+      pc = mrb->c->cibase[i].err;
+    }
+    else if (i+1 <= ciidx) {
+      pc = mrb->c->cibase[i+1].pc - 1;
+    }
+    else {
+      pc = pc0;
+    }
+    loc.filename = mrb_debug_get_filename(irep, (uint32_t)(pc - irep->iseq));
+    loc.lineno = mrb_debug_get_line(irep, (uint32_t)(pc - irep->iseq));
+
+    if (loc.lineno == -1) continue;
+
+    if (!loc.filename) {
+      loc.filename = "(unknown)";
+    }
+
+    loc.method_id = ci->mid;
+    func(mrb, j, &loc, data);
+  }
+}
+
+#ifndef MRB_DISABLE_STDIO
+
+static void
+print_backtrace(mrb_state *mrb, mrb_value backtrace)
+{
+  int i, n;
+  FILE *stream = stderr;
+
+  if (!mrb_array_p(backtrace)) return;
+  fprintf(stream, "trace:\n");
+
+  n = RARRAY_LEN(backtrace);
+  for (i=0; n--; i++) {
+    mrb_value entry = RARRAY_PTR(backtrace)[n];
+
+    if (mrb_string_p(entry)) {
+      fprintf(stream, "\t[%d] %.*s\n", i, (int)RSTRING_LEN(entry), RSTRING_PTR(entry));
+    }
+  }
+}
+
+static void
+print_packed_backtrace(mrb_state *mrb, mrb_value packed)
+{
+  FILE *stream = stderr;
+  struct backtrace_location *bt;
+  int n, i;
+
+  bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, packed, &bt_type);
+  if (bt == NULL) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "broken backtrace");
+  }
+  n = (mrb_int)RDATA(packed)->flags;
+
+  fprintf(stream, "trace:\n");
+  for (i = 0; n--; i++) {
+    int ai = mrb_gc_arena_save(mrb);
+    struct backtrace_location *entry = &bt[n];
+    if (entry->filename == NULL) continue;
+    fprintf(stream, "\t[%d] %s:%d", (int)i, entry->filename, entry->lineno);
+    if (entry->method_id != 0) {
+      const char *method_name;
+
+      method_name = mrb_sym2name(mrb, entry->method_id);
+      fprintf(stream, ":in %s", method_name);
+      mrb_gc_arena_restore(mrb, ai);
+    }
+    fprintf(stream, "\n");
+  }
+}
+
+/* mrb_print_backtrace
+
+   function to retrieve backtrace information from the last exception.
+*/
+
+MRB_API void
+mrb_print_backtrace(mrb_state *mrb)
+{
+  mrb_value backtrace;
+
+  if (!mrb->exc) {
+    return;
+  }
+
+  backtrace = mrb_obj_iv_get(mrb, mrb->exc, mrb_intern_lit(mrb, "backtrace"));
+  if (mrb_nil_p(backtrace)) return;
+  if (mrb_array_p(backtrace)) {
+    print_backtrace(mrb, backtrace);
+  }
+  else {
+    print_packed_backtrace(mrb, backtrace);
+  }
+}
+#else
+
+MRB_API void
+mrb_print_backtrace(mrb_state *mrb)
+{
+}
+
+#endif
+
+static void
+pack_backtrace_i(mrb_state *mrb,
+                 int i,
+                 struct backtrace_location *loc,
+                 void *data)
+{
+  struct backtrace_location *entry = (struct backtrace_location*)data;
+
+  entry[i] = *loc;
+}
+
+static mrb_value
+packed_backtrace(mrb_state *mrb)
+{
+  struct RData *backtrace;
+  ptrdiff_t ciidx = mrb->c->ci - mrb->c->cibase;
+  mrb_int len = (ciidx+1)*sizeof(struct backtrace_location);
+  void *ptr;
+
+  ptr = mrb_malloc(mrb, len);
+  memset(ptr, 0, len);
+  backtrace = mrb_data_object_alloc(mrb, NULL, ptr, &bt_type);
+  backtrace->flags = (unsigned int)ciidx+1;
+  each_backtrace(mrb, ciidx, mrb->c->ci->pc, pack_backtrace_i, ptr);
+  return mrb_obj_value(backtrace);
+}
+
+void
+mrb_keep_backtrace(mrb_state *mrb, mrb_value exc)
+{
+  mrb_value backtrace;
+  int ai = mrb_gc_arena_save(mrb);
+
+  backtrace = packed_backtrace(mrb);
+  mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "backtrace"), backtrace);
+  mrb_gc_arena_restore(mrb, ai);
+}
+
+mrb_value
+mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace)
+{
+  struct backtrace_location *bt;
+  mrb_int n, i;
+
+  if (mrb_nil_p(backtrace)) return mrb_ary_new_capa(mrb, 0);
+  if (mrb_array_p(backtrace)) return backtrace;
+  bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, backtrace, &bt_type);
+  if (bt == NULL) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "broken backtrace");
+  }
+  n = (mrb_int)RDATA(backtrace)->flags;
+  backtrace = mrb_ary_new_capa(mrb, n);
+  for (i = 0; i < n; i++) {
+    int ai = mrb_gc_arena_save(mrb);
+    struct backtrace_location *entry = &bt[i];
+    mrb_value btline;
+
+    if (entry->filename == NULL) continue;
+    btline = mrb_format(mrb, "%S:%S",
+                              mrb_str_new_cstr(mrb, entry->filename),
+                              mrb_fixnum_value(entry->lineno));
+    if (entry->method_id != 0) {
+      mrb_str_cat_lit(mrb, btline, ":in ");
+      mrb_str_cat_cstr(mrb, btline, mrb_sym2name(mrb, entry->method_id));
+    }
+    mrb_ary_push(mrb, backtrace, btline);
+    mrb_gc_arena_restore(mrb, ai);
+  }
+
+  return backtrace;
+}
+
+MRB_API mrb_value
+mrb_exc_backtrace(mrb_state *mrb, mrb_value exc)
+{
+  mrb_sym attr_name;
+  mrb_value backtrace;
+
+  attr_name = mrb_intern_lit(mrb, "backtrace");
+  backtrace = mrb_iv_get(mrb, exc, attr_name);
+  if (mrb_nil_p(backtrace) || mrb_array_p(backtrace)) {
+    return backtrace;
+  }
+  backtrace = mrb_unpack_backtrace(mrb, backtrace);
+  mrb_iv_set(mrb, exc, attr_name, backtrace);
+  return backtrace;
+}
+
+MRB_API mrb_value
+mrb_get_backtrace(mrb_state *mrb)
+{
+  return mrb_unpack_backtrace(mrb, packed_backtrace(mrb));
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/class.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/class.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/class.c	(revision 331)
@@ -0,0 +1,2364 @@
+/*
+** class.c - Class class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <stdarg.h>
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/class.h>
+#include <mruby/numeric.h>
+#include <mruby/proc.h>
+#include <mruby/string.h>
+#include <mruby/variable.h>
+#include <mruby/error.h>
+#include <mruby/data.h>
+#include <mruby/istruct.h>
+
+KHASH_DEFINE(mt, mrb_sym, struct RProc*, TRUE, kh_int_hash_func, kh_int_hash_equal)
+
+void
+mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c)
+{
+  khiter_t k;
+  khash_t(mt) *h = c->mt;
+
+  if (!h) return;
+  for (k = kh_begin(h); k != kh_end(h); k++) {
+    if (kh_exist(h, k)) {
+      struct RProc *m = kh_value(h, k);
+      if (m) {
+        mrb_gc_mark(mrb, (struct RBasic*)m);
+      }
+    }
+  }
+}
+
+size_t
+mrb_gc_mark_mt_size(mrb_state *mrb, struct RClass *c)
+{
+  khash_t(mt) *h = c->mt;
+
+  if (!h) return 0;
+  return kh_size(h);
+}
+
+void
+mrb_gc_free_mt(mrb_state *mrb, struct RClass *c)
+{
+  kh_destroy(mt, mrb, c->mt);
+}
+
+static void
+name_class(mrb_state *mrb, struct RClass *c, mrb_sym name)
+{
+  mrb_obj_iv_set(mrb, (struct RObject*)c,
+                 mrb_intern_lit(mrb, "__classid__"), mrb_symbol_value(name));
+}
+
+static void
+setup_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id)
+{
+  name_class(mrb, c, id);
+  mrb_obj_iv_set(mrb, (struct RObject*)outer, id, mrb_obj_value(c));
+  if (outer != mrb->object_class) {
+    mrb_obj_iv_set(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"),
+                   mrb_obj_value(outer));
+  }
+}
+
+#define make_metaclass(mrb, c) prepare_singleton_class((mrb), (struct RBasic*)(c))
+
+static void
+prepare_singleton_class(mrb_state *mrb, struct RBasic *o)
+{
+  struct RClass *sc, *c;
+
+  if (o->c->tt == MRB_TT_SCLASS) return;
+  sc = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_SCLASS, mrb->class_class);
+  sc->mt = kh_init(mt, mrb);
+  sc->iv = 0;
+  if (o->tt == MRB_TT_CLASS) {
+    c = (struct RClass*)o;
+    if (!c->super) {
+      sc->super = mrb->class_class;
+    }
+    else {
+      sc->super = c->super->c;
+    }
+  }
+  else if (o->tt == MRB_TT_SCLASS) {
+    c = (struct RClass*)o;
+    while (c->super->tt == MRB_TT_ICLASS)
+      c = c->super;
+    make_metaclass(mrb, c->super);
+    sc->super = c->super->c;
+  }
+  else {
+    sc->super = o->c;
+    prepare_singleton_class(mrb, (struct RBasic*)sc);
+  }
+  o->c = sc;
+  mrb_field_write_barrier(mrb, (struct RBasic*)o, (struct RBasic*)sc);
+  mrb_field_write_barrier(mrb, (struct RBasic*)sc, (struct RBasic*)o);
+  mrb_obj_iv_set(mrb, (struct RObject*)sc, mrb_intern_lit(mrb, "__attached__"), mrb_obj_value(o));
+}
+
+static struct RClass *
+class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id)
+{
+  mrb_value c = mrb_const_get(mrb, mrb_obj_value(klass), id);
+
+  mrb_check_type(mrb, c, MRB_TT_CLASS);
+  return mrb_class_ptr(c);
+}
+
+static struct RClass *
+module_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id)
+{
+  mrb_value c = mrb_const_get(mrb, mrb_obj_value(klass), id);
+
+  mrb_check_type(mrb, c, MRB_TT_MODULE);
+  return mrb_class_ptr(c);
+}
+
+static mrb_bool
+class_ptr_p(mrb_value obj)
+{
+  switch (mrb_type(obj)) {
+  case MRB_TT_CLASS:
+  case MRB_TT_SCLASS:
+  case MRB_TT_MODULE:
+    return TRUE;
+  default:
+    return FALSE;
+  }
+}
+
+MRB_API struct RClass*
+mrb_class_outer_module(mrb_state *mrb, struct RClass *c)
+{
+  mrb_value outer;
+  struct RClass *cls;
+
+  outer = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"));
+  if (mrb_nil_p(outer)) return NULL;
+  cls = mrb_class_ptr(outer);
+  if (cls->tt == MRB_TT_SCLASS)
+  {
+    mrb_value klass;
+    klass = mrb_obj_iv_get(mrb, (struct RObject *)cls,
+                           mrb_intern_lit(mrb, "__attached__"));
+    if (class_ptr_p(klass)) {
+      cls = mrb_class_ptr(klass);
+    }
+  }
+  return cls;
+}
+
+static void
+check_if_class_or_module(mrb_state *mrb, mrb_value obj)
+{
+  if (!class_ptr_p(obj)) {
+    mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a class/module", mrb_inspect(mrb, obj));
+  }
+}
+
+static struct RClass*
+define_module(mrb_state *mrb, mrb_sym name, struct RClass *outer)
+{
+  struct RClass *m;
+
+  if (mrb_const_defined_at(mrb, mrb_obj_value(outer), name)) {
+    return module_from_sym(mrb, outer, name);
+  }
+  m = mrb_module_new(mrb);
+  setup_class(mrb, outer, m, name);
+
+  return m;
+}
+
+MRB_API struct RClass*
+mrb_define_module_id(mrb_state *mrb, mrb_sym name)
+{
+  return define_module(mrb, name, mrb->object_class);
+}
+
+MRB_API struct RClass*
+mrb_define_module(mrb_state *mrb, const char *name)
+{
+  return define_module(mrb, mrb_intern_cstr(mrb, name), mrb->object_class);
+}
+
+MRB_API struct RClass*
+mrb_vm_define_module(mrb_state *mrb, mrb_value outer, mrb_sym id)
+{
+  check_if_class_or_module(mrb, outer);
+  if (mrb_const_defined_at(mrb, outer, id)) {
+    mrb_value old = mrb_const_get(mrb, outer, id);
+
+    if (mrb_type(old) != MRB_TT_MODULE) {
+      mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a module", mrb_inspect(mrb, old));
+    }
+    return mrb_class_ptr(old);
+  }
+  return define_module(mrb, id, mrb_class_ptr(outer));
+}
+
+MRB_API struct RClass*
+mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name)
+{
+  mrb_sym id = mrb_intern_cstr(mrb, name);
+  struct RClass * c = define_module(mrb, id, outer);
+
+  setup_class(mrb, outer, c, id);
+  return c;
+}
+
+static struct RClass*
+find_origin(struct RClass *c)
+{
+  MRB_CLASS_ORIGIN(c);
+  return c;
+}
+
+static struct RClass*
+define_class(mrb_state *mrb, mrb_sym name, struct RClass *super, struct RClass *outer)
+{
+  struct RClass * c;
+
+  if (mrb_const_defined_at(mrb, mrb_obj_value(outer), name)) {
+    c = class_from_sym(mrb, outer, name);
+    MRB_CLASS_ORIGIN(c);
+    if (super && mrb_class_real(c->super) != super) {
+      mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for Class %S (%S not %S)",
+                 mrb_sym2str(mrb, name),
+                 mrb_obj_value(c->super), mrb_obj_value(super));
+    }
+    return c;
+  }
+
+  c = mrb_class_new(mrb, super);
+  setup_class(mrb, outer, c, name);
+
+  return c;
+}
+
+MRB_API struct RClass*
+mrb_define_class_id(mrb_state *mrb, mrb_sym name, struct RClass *super)
+{
+  if (!super) {
+    mrb_warn(mrb, "no super class for '%S', Object assumed", mrb_sym2str(mrb, name));
+  }
+  return define_class(mrb, name, super, mrb->object_class);
+}
+
+MRB_API struct RClass*
+mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super)
+{
+  return mrb_define_class_id(mrb, mrb_intern_cstr(mrb, name), super);
+}
+
+static mrb_value mrb_bob_init(mrb_state *mrb, mrb_value cv);
+
+static void
+mrb_class_inherited(mrb_state *mrb, struct RClass *super, struct RClass *klass)
+{
+  mrb_value s;
+  mrb_sym mid;
+
+  if (!super)
+    super = mrb->object_class;
+  s = mrb_obj_value(super);
+  mid = mrb_intern_lit(mrb, "inherited");
+  if (!mrb_func_basic_p(mrb, s, mid, mrb_bob_init)) {
+    mrb_value c = mrb_obj_value(klass);
+    mrb_funcall_argv(mrb, mrb_obj_value(super), mid, 1, &c);
+  }
+}
+
+MRB_API struct RClass*
+mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id)
+{
+  struct RClass *s;
+  struct RClass *c;
+
+  if (!mrb_nil_p(super)) {
+    if (mrb_type(super) != MRB_TT_CLASS) {
+      mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%S given)",
+                 mrb_inspect(mrb, super));
+    }
+    s = mrb_class_ptr(super);
+  }
+  else {
+    s = 0;
+  }
+  check_if_class_or_module(mrb, outer);
+  if (mrb_const_defined_at(mrb, outer, id)) {
+    mrb_value old = mrb_const_get(mrb, outer, id);
+
+    if (mrb_type(old) != MRB_TT_CLASS) {
+      mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a class", mrb_inspect(mrb, old));
+    }
+    c = mrb_class_ptr(old);
+    if (s) {
+      /* check super class */
+      if (mrb_class_real(c->super) != s) {
+        mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for class %S", old);
+      }
+    }
+    return c;
+  }
+  c = define_class(mrb, id, s, mrb_class_ptr(outer));
+  mrb_class_inherited(mrb, mrb_class_real(c->super), c);
+
+  return c;
+}
+
+MRB_API mrb_bool
+mrb_class_defined(mrb_state *mrb, const char *name)
+{
+  mrb_value sym = mrb_check_intern_cstr(mrb, name);
+  if (mrb_nil_p(sym)) {
+    return FALSE;
+  }
+  return mrb_const_defined(mrb, mrb_obj_value(mrb->object_class), mrb_symbol(sym));
+}
+
+MRB_API mrb_bool
+mrb_class_defined_under(mrb_state *mrb, struct RClass *outer, const char *name)
+{
+  mrb_value sym = mrb_check_intern_cstr(mrb, name);
+  if (mrb_nil_p(sym)) {
+    return FALSE;
+  }
+  return mrb_const_defined_at(mrb, mrb_obj_value(outer), mrb_symbol(sym));
+}
+
+MRB_API struct RClass *
+mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name)
+{
+  return class_from_sym(mrb, outer, mrb_intern_cstr(mrb, name));
+}
+
+MRB_API struct RClass *
+mrb_class_get(mrb_state *mrb, const char *name)
+{
+  return mrb_class_get_under(mrb, mrb->object_class, name);
+}
+
+MRB_API struct RClass *
+mrb_exc_get(mrb_state *mrb, const char *name)
+{
+  struct RClass *exc, *e;
+  mrb_value c = mrb_const_get(mrb, mrb_obj_value(mrb->object_class),
+                              mrb_intern_cstr(mrb, name));
+
+  if (mrb_type(c) != MRB_TT_CLASS) {
+    mrb_raise(mrb, mrb->eException_class, "exception corrupted");
+  }
+  exc = e = mrb_class_ptr(c);
+
+  while (e) {
+    if (e == mrb->eException_class)
+      return exc;
+    e = e->super;
+  }
+  return mrb->eException_class;
+}
+
+MRB_API struct RClass *
+mrb_module_get_under(mrb_state *mrb, struct RClass *outer, const char *name)
+{
+  return module_from_sym(mrb, outer, mrb_intern_cstr(mrb, name));
+}
+
+MRB_API struct RClass *
+mrb_module_get(mrb_state *mrb, const char *name)
+{
+  return mrb_module_get_under(mrb, mrb->object_class, name);
+}
+
+/*!
+ * Defines a class under the namespace of \a outer.
+ * \param outer  a class which contains the new class.
+ * \param id     name of the new class
+ * \param super  a class from which the new class will derive.
+ *               NULL means \c Object class.
+ * \return the created class
+ * \throw TypeError if the constant name \a name is already taken but
+ *                  the constant is not a \c Class.
+ * \throw NameError if the class is already defined but the class can not
+ *                  be reopened because its superclass is not \a super.
+ * \post top-level constant named \a name refers the returned class.
+ *
+ * \note if a class named \a name is already defined and its superclass is
+ *       \a super, the function just returns the defined class.
+ */
+MRB_API struct RClass *
+mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super)
+{
+  mrb_sym id = mrb_intern_cstr(mrb, name);
+  struct RClass * c;
+
+#if 0
+  if (!super) {
+    mrb_warn(mrb, "no super class for '%S::%S', Object assumed",
+             mrb_obj_value(outer), mrb_sym2str(mrb, id));
+  }
+#endif
+  c = define_class(mrb, id, super, outer);
+  setup_class(mrb, outer, c, id);
+  return c;
+}
+
+MRB_API void
+mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, struct RProc *p)
+{
+  khash_t(mt) *h;
+  khiter_t k;
+  MRB_CLASS_ORIGIN(c);
+  h = c->mt;
+
+  if (MRB_FROZEN_P(c)) {
+    if (c->tt == MRB_TT_MODULE)
+      mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen module");
+    else
+      mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen class");
+  }
+  if (!h) h = c->mt = kh_init(mt, mrb);
+  k = kh_put(mt, mrb, h, mid);
+  kh_value(h, k) = p;
+  if (p) {
+    p->c = NULL;
+    mrb_field_write_barrier(mrb, (struct RBasic *)c, (struct RBasic *)p);
+  }
+}
+
+MRB_API void
+mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec)
+{
+  struct RProc *p;
+  int ai = mrb_gc_arena_save(mrb);
+
+  p = mrb_proc_new_cfunc(mrb, func);
+  p->target_class = c;
+  mrb_define_method_raw(mrb, c, mid, p);
+  mrb_gc_arena_restore(mrb, ai);
+}
+
+MRB_API void
+mrb_define_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
+{
+  mrb_define_method_id(mrb, c, mrb_intern_cstr(mrb, name), func, aspec);
+}
+
+/* a function to raise NotImplementedError with current method name */
+MRB_API void
+mrb_notimplement(mrb_state *mrb)
+{
+  const char *str;
+  mrb_int len;
+  mrb_callinfo *ci = mrb->c->ci;
+
+  if (ci->mid) {
+    str = mrb_sym2name_len(mrb, ci->mid, &len);
+    mrb_raisef(mrb, E_NOTIMP_ERROR,
+      "%S() function is unimplemented on this machine",
+      mrb_str_new_static(mrb, str, (size_t)len));
+  }
+}
+
+/* a function to be replacement of unimplemented method */
+MRB_API mrb_value
+mrb_notimplement_m(mrb_state *mrb, mrb_value self)
+{
+  mrb_notimplement(mrb);
+  /* not reached */
+  return mrb_nil_value();
+}
+
+static mrb_value
+check_type(mrb_state *mrb, mrb_value val, enum mrb_vtype t, const char *c, const char *m)
+{
+  mrb_value tmp;
+
+  tmp = mrb_check_convert_type(mrb, val, t, c, m);
+  if (mrb_nil_p(tmp)) {
+    mrb_raisef(mrb, E_TYPE_ERROR, "expected %S", mrb_str_new_cstr(mrb, c));
+  }
+  return tmp;
+}
+
+static mrb_value
+to_str(mrb_state *mrb, mrb_value val)
+{
+  return check_type(mrb, val, MRB_TT_STRING, "String", "to_str");
+}
+
+static mrb_value
+to_ary(mrb_state *mrb, mrb_value val)
+{
+  return check_type(mrb, val, MRB_TT_ARRAY, "Array", "to_ary");
+}
+
+static mrb_value
+to_hash(mrb_state *mrb, mrb_value val)
+{
+  return check_type(mrb, val, MRB_TT_HASH, "Hash", "to_hash");
+}
+
+static mrb_sym
+to_sym(mrb_state *mrb, mrb_value ss)
+{
+  if (mrb_type(ss) == MRB_TT_SYMBOL) {
+    return mrb_symbol(ss);
+  }
+  else if (mrb_string_p(ss)) {
+    return mrb_intern_str(mrb, to_str(mrb, ss));
+  }
+  else {
+    mrb_value obj = mrb_funcall(mrb, ss, "inspect", 0);
+    mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", obj);
+    /* not reached */
+    return 0;
+  }
+}
+
+/*
+  retrieve arguments from mrb_state.
+
+  mrb_get_args(mrb, format, ...)
+
+  returns number of arguments parsed.
+
+  format specifiers:
+
+    string  mruby type     C type                 note
+    ----------------------------------------------------------------------------------------------
+    o:      Object         [mrb_value]
+    C:      class/module   [mrb_value]
+    S:      String         [mrb_value]            when ! follows, the value may be nil
+    A:      Array          [mrb_value]            when ! follows, the value may be nil
+    H:      Hash           [mrb_value]            when ! follows, the value may be nil
+    s:      String         [char*,mrb_int]        Receive two arguments; s! gives (NULL,0) for nil
+    z:      String         [char*]                NUL terminated string; z! gives NULL for nil
+    a:      Array          [mrb_value*,mrb_int]   Receive two arguments; a! gives (NULL,0) for nil
+    f:      Float          [mrb_float]
+    i:      Integer        [mrb_int]
+    b:      Boolean        [mrb_bool]
+    n:      Symbol         [mrb_sym]
+    d:      Data           [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified
+    I:      Inline struct  [void*]
+    &:      Block          [mrb_value]
+    *:      rest argument  [mrb_value*,mrb_int]   Receive the rest of the arguments as an array.
+    |:      optional                              Next argument of '|' and later are optional.
+    ?:      optional given [mrb_bool]             true if preceding argument (optional) is given.
+ */
+MRB_API mrb_int
+mrb_get_args(mrb_state *mrb, const char *format, ...)
+{
+  char c;
+  int i = 0;
+  va_list ap;
+  int argc = mrb->c->ci->argc;
+  int arg_i = 0;
+  mrb_bool array_argv;
+  mrb_bool opt = FALSE;
+  mrb_bool given = TRUE;
+
+  va_start(ap, format);
+  if (argc < 0) {
+    struct RArray *a = mrb_ary_ptr(mrb->c->stack[1]);
+
+    argc = a->len;
+    array_argv = TRUE;
+  }
+  else {
+    array_argv = FALSE;
+  }
+
+#define ARGV \
+  (array_argv ? mrb_ary_ptr(mrb->c->stack[1])->ptr : (mrb->c->stack + 1))
+
+  while ((c = *format++)) {
+    switch (c) {
+    case '|': case '*': case '&': case '?':
+      break;
+    default:
+      if (argc <= i) {
+        if (opt) {
+          given = FALSE;
+        }
+        else {
+          mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
+        }
+      }
+      break;
+    }
+
+    switch (c) {
+    case 'o':
+      {
+        mrb_value *p;
+
+        p = va_arg(ap, mrb_value*);
+        if (i < argc) {
+          *p = ARGV[arg_i++];
+          i++;
+        }
+      }
+      break;
+    case 'C':
+      {
+        mrb_value *p;
+
+        p = va_arg(ap, mrb_value*);
+        if (i < argc) {
+          mrb_value ss;
+
+          ss = ARGV[arg_i++];
+          if (!class_ptr_p(ss)) {
+            mrb_raisef(mrb, E_TYPE_ERROR, "%S is not class/module", ss);
+          }
+          *p = ss;
+          i++;
+        }
+      }
+      break;
+    case 'S':
+      {
+        mrb_value *p;
+
+        p = va_arg(ap, mrb_value*);
+        if (*format == '!') {
+          format++;
+          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
+            *p = ARGV[arg_i++];
+            i++;
+            break;
+          }
+        }
+        if (i < argc) {
+          *p = to_str(mrb, ARGV[arg_i++]);
+          i++;
+        }
+      }
+      break;
+    case 'A':
+      {
+        mrb_value *p;
+
+        p = va_arg(ap, mrb_value*);
+        if (*format == '!') {
+          format++;
+          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
+            *p = ARGV[arg_i++];
+            i++;
+            break;
+          }
+        }
+        if (i < argc) {
+          *p = to_ary(mrb, ARGV[arg_i++]);
+          i++;
+        }
+      }
+      break;
+    case 'H':
+      {
+        mrb_value *p;
+
+        p = va_arg(ap, mrb_value*);
+        if (*format == '!') {
+          format++;
+          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
+            *p = ARGV[arg_i++];
+            i++;
+            break;
+          }
+        }
+        if (i < argc) {
+          *p = to_hash(mrb, ARGV[arg_i++]);
+          i++;
+        }
+      }
+      break;
+    case 's':
+      {
+        mrb_value ss;
+        char **ps = 0;
+        mrb_int *pl = 0;
+
+        ps = va_arg(ap, char**);
+        pl = va_arg(ap, mrb_int*);
+        if (*format == '!') {
+          format++;
+          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
+            *ps = NULL;
+            *pl = 0;
+            i++; arg_i++;
+            break;
+          }
+        }
+        if (i < argc) {
+          ss = to_str(mrb, ARGV[arg_i++]);
+          *ps = RSTRING_PTR(ss);
+          *pl = RSTRING_LEN(ss);
+          i++;
+        }
+      }
+      break;
+    case 'z':
+      {
+        mrb_value ss;
+        const char **ps;
+
+        ps = va_arg(ap, const char**);
+        if (*format == '!') {
+          format++;
+          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
+            *ps = NULL;
+            i++; arg_i++;
+            break;
+          }
+        }
+        if (i < argc) {
+          ss = to_str(mrb, ARGV[arg_i++]);
+          *ps = mrb_string_value_cstr(mrb, &ss);
+          i++;
+        }
+      }
+      break;
+    case 'a':
+      {
+        mrb_value aa;
+        struct RArray *a;
+        mrb_value **pb;
+        mrb_int *pl;
+
+        pb = va_arg(ap, mrb_value**);
+        pl = va_arg(ap, mrb_int*);
+        if (*format == '!') {
+          format++;
+          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
+            *pb = 0;
+            *pl = 0;
+            i++; arg_i++;
+            break;
+          }
+        }
+        if (i < argc) {
+          aa = to_ary(mrb, ARGV[arg_i++]);
+          a = mrb_ary_ptr(aa);
+          *pb = a->ptr;
+          *pl = a->len;
+          i++;
+        }
+      }
+      break;
+    case 'I':
+      {
+        void* *p;
+        mrb_value ss;
+
+        p = va_arg(ap, void**);
+        if (i < argc) {
+          ss = ARGV[arg_i];
+          if (mrb_type(ss) != MRB_TT_ISTRUCT)
+          {
+            mrb_raisef(mrb, E_TYPE_ERROR, "%S is not inline struct", ss);
+          }
+          *p = mrb_istruct_ptr(ss);
+          arg_i++;
+          i++;
+        }
+      }
+      break;
+    case 'f':
+      {
+        mrb_float *p;
+
+        p = va_arg(ap, mrb_float*);
+        if (i < argc) {
+          *p = mrb_to_flo(mrb, ARGV[arg_i]);
+          arg_i++;
+          i++;
+        }
+      }
+      break;
+    case 'i':
+      {
+        mrb_int *p;
+
+        p = va_arg(ap, mrb_int*);
+        if (i < argc) {
+          switch (mrb_type(ARGV[arg_i])) {
+            case MRB_TT_FIXNUM:
+              *p = mrb_fixnum(ARGV[arg_i]);
+              break;
+            case MRB_TT_FLOAT:
+              {
+                mrb_float f = mrb_float(ARGV[arg_i]);
+
+                if (!FIXABLE_FLOAT(f)) {
+                  mrb_raise(mrb, E_RANGE_ERROR, "float too big for int");
+                }
+                *p = (mrb_int)f;
+              }
+              break;
+            case MRB_TT_STRING:
+              mrb_raise(mrb, E_TYPE_ERROR, "no implicit conversion of String into Integer");
+              break;
+            default:
+              *p = mrb_fixnum(mrb_Integer(mrb, ARGV[arg_i]));
+              break;
+          }
+          arg_i++;
+          i++;
+        }
+      }
+      break;
+    case 'b':
+      {
+        mrb_bool *boolp = va_arg(ap, mrb_bool*);
+
+        if (i < argc) {
+          mrb_value b = ARGV[arg_i++];
+          *boolp = mrb_test(b);
+          i++;
+        }
+      }
+      break;
+    case 'n':
+      {
+        mrb_sym *symp;
+
+        symp = va_arg(ap, mrb_sym*);
+        if (i < argc) {
+          mrb_value ss;
+
+          ss = ARGV[arg_i++];
+          *symp = to_sym(mrb, ss);
+          i++;
+        }
+      }
+      break;
+    case 'd':
+      {
+        void** datap;
+        struct mrb_data_type const* type;
+
+        datap = va_arg(ap, void**);
+        type = va_arg(ap, struct mrb_data_type const*);
+        if (*format == '!') {
+          format++;
+          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
+            *datap = 0;
+            i++; arg_i++;
+            break;
+          }
+        }
+        if (i < argc) {
+          *datap = mrb_data_get_ptr(mrb, ARGV[arg_i++], type);
+          ++i;
+        }
+      }
+      break;
+
+    case '&':
+      {
+        mrb_value *p, *bp;
+
+        p = va_arg(ap, mrb_value*);
+        if (mrb->c->ci->argc < 0) {
+          bp = mrb->c->stack + 2;
+        }
+        else {
+          bp = mrb->c->stack + mrb->c->ci->argc + 1;
+        }
+        *p = *bp;
+      }
+      break;
+    case '|':
+      opt = TRUE;
+      break;
+    case '?':
+      {
+        mrb_bool *p;
+
+        p = va_arg(ap, mrb_bool*);
+        *p = given;
+      }
+      break;
+
+    case '*':
+      {
+        mrb_value **var;
+        mrb_int *pl;
+
+        var = va_arg(ap, mrb_value**);
+        pl = va_arg(ap, mrb_int*);
+        if (argc > i) {
+          *pl = argc-i;
+          if (*pl > 0) {
+            *var = ARGV + arg_i;
+          }
+          i = argc;
+          arg_i += *pl;
+        }
+        else {
+          *pl = 0;
+          *var = NULL;
+        }
+      }
+      break;
+    default:
+      mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid argument specifier %S", mrb_str_new(mrb, &c, 1));
+      break;
+    }
+  }
+
+#undef ARGV
+
+  if (!c && argc > i) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
+  }
+  va_end(ap);
+  return i;
+}
+
+static struct RClass*
+boot_defclass(mrb_state *mrb, struct RClass *super)
+{
+  struct RClass *c;
+
+  c = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_CLASS, mrb->class_class);
+  if (super) {
+    c->super = super;
+    mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)super);
+  }
+  else {
+    c->super = mrb->object_class;
+  }
+  c->mt = kh_init(mt, mrb);
+  return c;
+}
+
+static void
+boot_initmod(mrb_state *mrb, struct RClass *mod)
+{
+  if (!mod->mt) {
+    mod->mt = kh_init(mt, mrb);
+  }
+}
+
+static struct RClass*
+include_class_new(mrb_state *mrb, struct RClass *m, struct RClass *super)
+{
+  struct RClass *ic = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, mrb->class_class);
+  if (m->tt == MRB_TT_ICLASS) {
+    m = m->c;
+  }
+  MRB_CLASS_ORIGIN(m);
+  ic->iv = m->iv;
+  ic->mt = m->mt;
+  ic->super = super;
+  if (m->tt == MRB_TT_ICLASS) {
+    ic->c = m->c;
+  }
+  else {
+    ic->c = m;
+  }
+  return ic;
+}
+
+static int
+include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, struct RClass *m, int search_super)
+{
+  struct RClass *p, *ic;
+  void *klass_mt = find_origin(c)->mt;
+
+  while (m) {
+    int superclass_seen = 0;
+
+    if (m->flags & MRB_FLAG_IS_PREPENDED)
+      goto skip;
+
+    if (klass_mt && klass_mt == m->mt)
+      return -1;
+
+    p = c->super;
+    while(p) {
+      if (p->tt == MRB_TT_ICLASS) {
+        if (p->mt == m->mt) {
+          if (!superclass_seen) {
+            ins_pos = p; /* move insert point */
+          }
+          goto skip;
+        }
+      } else if (p->tt == MRB_TT_CLASS) {
+        if (!search_super) break;
+        superclass_seen = 1;
+      }
+      p = p->super;
+    }
+
+    ic = include_class_new(mrb, m, ins_pos->super);
+    ins_pos->super = ic;
+    mrb_field_write_barrier(mrb, (struct RBasic*)ins_pos, (struct RBasic*)ins_pos->super);
+    ins_pos = ic;
+  skip:
+    m = m->super;
+  }
+  return 0;
+}
+
+MRB_API void
+mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
+{
+  int changed = include_module_at(mrb, c, find_origin(c), m, 1);
+  if (changed < 0) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic include detected");
+  }
+}
+
+MRB_API void
+mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
+{
+  struct RClass *origin;
+  int changed = 0;
+
+  if (!(c->flags & MRB_FLAG_IS_PREPENDED)) {
+    origin = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, c);
+    origin->flags |= MRB_FLAG_IS_ORIGIN;
+    origin->super = c->super;
+    c->super = origin;
+    origin->mt = c->mt;
+    c->mt = kh_init(mt, mrb);
+    mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)origin);
+    c->flags |= MRB_FLAG_IS_PREPENDED;
+  }
+  changed = include_module_at(mrb, c, c, m, 0);
+  if (changed < 0) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic prepend detected");
+  }
+}
+
+static mrb_value
+mrb_mod_prepend_features(mrb_state *mrb, mrb_value mod)
+{
+  mrb_value klass;
+
+  mrb_check_type(mrb, mod, MRB_TT_MODULE);
+  mrb_get_args(mrb, "C", &klass);
+  mrb_prepend_module(mrb, mrb_class_ptr(klass), mrb_class_ptr(mod));
+  return mod;
+}
+
+static mrb_value
+mrb_mod_append_features(mrb_state *mrb, mrb_value mod)
+{
+  mrb_value klass;
+
+  mrb_check_type(mrb, mod, MRB_TT_MODULE);
+  mrb_get_args(mrb, "C", &klass);
+  mrb_include_module(mrb, mrb_class_ptr(klass), mrb_class_ptr(mod));
+  return mod;
+}
+
+/* 15.2.2.4.28 */
+/*
+ *  call-seq:
+ *     mod.include?(module)    -> true or false
+ *
+ *  Returns <code>true</code> if <i>module</i> is included in
+ *  <i>mod</i> or one of <i>mod</i>'s ancestors.
+ *
+ *     module A
+ *     end
+ *     class B
+ *       include A
+ *     end
+ *     class C < B
+ *     end
+ *     B.include?(A)   #=> true
+ *     C.include?(A)   #=> true
+ *     A.include?(A)   #=> false
+ */
+static mrb_value
+mrb_mod_include_p(mrb_state *mrb, mrb_value mod)
+{
+  mrb_value mod2;
+  struct RClass *c = mrb_class_ptr(mod);
+
+  mrb_get_args(mrb, "C", &mod2);
+  mrb_check_type(mrb, mod2, MRB_TT_MODULE);
+
+  while (c) {
+    if (c->tt == MRB_TT_ICLASS) {
+      if (c->c == mrb_class_ptr(mod2)) return mrb_true_value();
+    }
+    c = c->super;
+  }
+  return mrb_false_value();
+}
+
+static mrb_value
+mrb_mod_ancestors(mrb_state *mrb, mrb_value self)
+{
+  mrb_value result;
+  struct RClass *c = mrb_class_ptr(self);
+  result = mrb_ary_new(mrb);
+  while (c) {
+    if (c->tt == MRB_TT_ICLASS) {
+      mrb_ary_push(mrb, result, mrb_obj_value(c->c));
+    }
+    else if (!(c->flags & MRB_FLAG_IS_PREPENDED)) {
+      mrb_ary_push(mrb, result, mrb_obj_value(c));
+    }
+    c = c->super;
+  }
+
+  return result;
+}
+
+static mrb_value
+mrb_mod_extend_object(mrb_state *mrb, mrb_value mod)
+{
+  mrb_value obj;
+
+  mrb_check_type(mrb, mod, MRB_TT_MODULE);
+  mrb_get_args(mrb, "o", &obj);
+  mrb_include_module(mrb, mrb_class_ptr(mrb_singleton_class(mrb, obj)), mrb_class_ptr(mod));
+  return mod;
+}
+
+static mrb_value
+mrb_mod_included_modules(mrb_state *mrb, mrb_value self)
+{
+  mrb_value result;
+  struct RClass *c = mrb_class_ptr(self);
+  struct RClass *origin = c;
+
+  MRB_CLASS_ORIGIN(origin);
+  result = mrb_ary_new(mrb);
+  while (c) {
+    if (c != origin && c->tt == MRB_TT_ICLASS) {
+      if (c->c->tt == MRB_TT_MODULE) {
+        mrb_ary_push(mrb, result, mrb_obj_value(c->c));
+      }
+    }
+    c = c->super;
+  }
+
+  return result;
+}
+
+static mrb_value
+mrb_mod_initialize(mrb_state *mrb, mrb_value mod)
+{
+  mrb_value b;
+  struct RClass *m = mrb_class_ptr(mod);
+  boot_initmod(mrb, m); /* bootstrap a newly initialized module */
+  mrb_get_args(mrb, "|&", &b);
+  if (!mrb_nil_p(b)) {
+    mrb_yield_with_class(mrb, b, 1, &mod, mod, m);
+  }
+  return mod;
+}
+
+mrb_value mrb_class_instance_method_list(mrb_state*, mrb_bool, struct RClass*, int);
+
+/* 15.2.2.4.33 */
+/*
+ *  call-seq:
+ *     mod.instance_methods(include_super=true)   -> array
+ *
+ *  Returns an array containing the names of the public and protected instance
+ *  methods in the receiver. For a module, these are the public and protected methods;
+ *  for a class, they are the instance (not singleton) methods. With no
+ *  argument, or with an argument that is <code>false</code>, the
+ *  instance methods in <i>mod</i> are returned, otherwise the methods
+ *  in <i>mod</i> and <i>mod</i>'s superclasses are returned.
+ *
+ *     module A
+ *       def method1()  end
+ *     end
+ *     class B
+ *       def method2()  end
+ *     end
+ *     class C < B
+ *       def method3()  end
+ *     end
+ *
+ *     A.instance_methods                #=> [:method1]
+ *     B.instance_methods(false)         #=> [:method2]
+ *     C.instance_methods(false)         #=> [:method3]
+ *     C.instance_methods(true).length   #=> 43
+ */
+
+static mrb_value
+mrb_mod_instance_methods(mrb_state *mrb, mrb_value mod)
+{
+  struct RClass *c = mrb_class_ptr(mod);
+  mrb_bool recur = TRUE;
+  mrb_get_args(mrb, "|b", &recur);
+  return mrb_class_instance_method_list(mrb, recur, c, 0);
+}
+
+/* implementation of module_eval/class_eval */
+mrb_value mrb_mod_module_eval(mrb_state*, mrb_value);
+
+static mrb_value
+mrb_mod_dummy_visibility(mrb_state *mrb, mrb_value mod)
+{
+  return mod;
+}
+
+MRB_API mrb_value
+mrb_singleton_class(mrb_state *mrb, mrb_value v)
+{
+  struct RBasic *obj;
+
+  switch (mrb_type(v)) {
+  case MRB_TT_FALSE:
+    if (mrb_nil_p(v))
+      return mrb_obj_value(mrb->nil_class);
+    return mrb_obj_value(mrb->false_class);
+  case MRB_TT_TRUE:
+    return mrb_obj_value(mrb->true_class);
+  case MRB_TT_CPTR:
+    return mrb_obj_value(mrb->object_class);
+  case MRB_TT_SYMBOL:
+  case MRB_TT_FIXNUM:
+  case MRB_TT_FLOAT:
+    mrb_raise(mrb, E_TYPE_ERROR, "can't define singleton");
+    return mrb_nil_value();    /* not reached */
+  default:
+    break;
+  }
+  obj = mrb_basic_ptr(v);
+  prepare_singleton_class(mrb, obj);
+  return mrb_obj_value(obj->c);
+}
+
+MRB_API void
+mrb_define_singleton_method(mrb_state *mrb, struct RObject *o, const char *name, mrb_func_t func, mrb_aspec aspec)
+{
+  prepare_singleton_class(mrb, (struct RBasic*)o);
+  mrb_define_method_id(mrb, o->c, mrb_intern_cstr(mrb, name), func, aspec);
+}
+
+MRB_API void
+mrb_define_class_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
+{
+  mrb_define_singleton_method(mrb, (struct RObject*)c, name, func, aspec);
+}
+
+MRB_API void
+mrb_define_module_function(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
+{
+  mrb_define_class_method(mrb, c, name, func, aspec);
+  mrb_define_method(mrb, c, name, func, aspec);
+}
+
+MRB_API struct RProc*
+mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
+{
+  khiter_t k;
+  struct RProc *m;
+  struct RClass *c = *cp;
+
+  while (c) {
+    khash_t(mt) *h = c->mt;
+
+    if (h) {
+      k = kh_get(mt, mrb, h, mid);
+      if (k != kh_end(h)) {
+        m = kh_value(h, k);
+        if (!m) break;
+        *cp = c;
+        return m;
+      }
+    }
+    c = c->super;
+  }
+  return NULL;                  /* no method */
+}
+
+MRB_API struct RProc*
+mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid)
+{
+  struct RProc *m;
+
+  m = mrb_method_search_vm(mrb, &c, mid);
+  if (!m) {
+    mrb_value inspect = mrb_funcall(mrb, mrb_obj_value(c), "inspect", 0);
+    if (mrb_string_p(inspect) && RSTRING_LEN(inspect) > 64) {
+      inspect = mrb_any_to_s(mrb, mrb_obj_value(c));
+    }
+    mrb_name_error(mrb, mid, "undefined method '%S' for class %S",
+               mrb_sym2str(mrb, mid), inspect);
+  }
+  return m;
+}
+
+static mrb_value
+attr_reader(mrb_state *mrb, mrb_value obj)
+{
+  mrb_value name = mrb_proc_cfunc_env_get(mrb, 0);
+  return mrb_iv_get(mrb, obj, to_sym(mrb, name));
+}
+
+static mrb_value
+mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod)
+{
+  struct RClass *c = mrb_class_ptr(mod);
+  mrb_value *argv;
+  mrb_int argc, i;
+  int ai;
+
+  mrb_get_args(mrb, "*", &argv, &argc);
+  ai = mrb_gc_arena_save(mrb);
+  for (i=0; i<argc; i++) {
+    mrb_value name, str;
+    mrb_sym method, sym;
+
+    method = to_sym(mrb, argv[i]);
+    name = mrb_sym2str(mrb, method);
+    str = mrb_str_buf_new(mrb, RSTRING_LEN(name)+1);
+    mrb_str_cat_lit(mrb, str, "@");
+    mrb_str_cat_str(mrb, str, name);
+    sym = mrb_intern_str(mrb, str);
+    mrb_iv_check(mrb, sym);
+    name = mrb_symbol_value(sym);
+    mrb_define_method_raw(mrb, c, method,
+                          mrb_proc_new_cfunc_with_env(mrb, attr_reader, 1, &name));
+    mrb_gc_arena_restore(mrb, ai);
+  }
+  return mrb_nil_value();
+}
+
+static mrb_value
+attr_writer(mrb_state *mrb, mrb_value obj)
+{
+  mrb_value name = mrb_proc_cfunc_env_get(mrb, 0);
+  mrb_value val;
+
+  mrb_get_args(mrb, "o", &val);
+  mrb_iv_set(mrb, obj, to_sym(mrb, name), val);
+  return val;
+}
+
+static mrb_value
+mrb_mod_attr_writer(mrb_state *mrb, mrb_value mod)
+{
+  struct RClass *c = mrb_class_ptr(mod);
+  mrb_value *argv;
+  mrb_int argc, i;
+  int ai;
+
+  mrb_get_args(mrb, "*", &argv, &argc);
+  ai = mrb_gc_arena_save(mrb);
+  for (i=0; i<argc; i++) {
+    mrb_value name, str, attr;
+    mrb_sym method, sym;
+
+    method = to_sym(mrb, argv[i]);
+
+    /* prepare iv name (@name) */
+    name = mrb_sym2str(mrb, method);
+    str = mrb_str_buf_new(mrb, RSTRING_LEN(name)+1);
+    mrb_str_cat_lit(mrb, str, "@");
+    mrb_str_cat_str(mrb, str, name);
+    sym = mrb_intern_str(mrb, str);
+    mrb_iv_check(mrb, sym);
+    attr = mrb_symbol_value(sym);
+
+    /* prepare method name (name=) */
+    str = mrb_str_buf_new(mrb, RSTRING_LEN(str));
+    mrb_str_cat_str(mrb, str, name);
+    mrb_str_cat_lit(mrb, str, "=");
+    method = mrb_intern_str(mrb, str);
+
+    mrb_define_method_raw(mrb, c, method,
+                          mrb_proc_new_cfunc_with_env(mrb, attr_writer, 1, &attr));
+    mrb_gc_arena_restore(mrb, ai);
+  }
+  return mrb_nil_value();
+}
+
+static mrb_value
+mrb_instance_alloc(mrb_state *mrb, mrb_value cv)
+{
+  struct RClass *c = mrb_class_ptr(cv);
+  struct RObject *o;
+  enum mrb_vtype ttype = MRB_INSTANCE_TT(c);
+
+  if (c->tt == MRB_TT_SCLASS)
+    mrb_raise(mrb, E_TYPE_ERROR, "can't create instance of singleton class");
+
+  if (ttype == 0) ttype = MRB_TT_OBJECT;
+  if (ttype <= MRB_TT_CPTR) {
+    mrb_raisef(mrb, E_TYPE_ERROR, "can't create instance of %S", cv);
+  }
+  o = (struct RObject*)mrb_obj_alloc(mrb, ttype, c);
+  return mrb_obj_value(o);
+}
+
+/*
+ *  call-seq:
+ *     class.new(args, ...)    ->  obj
+ *
+ *  Creates a new object of <i>class</i>'s class, then
+ *  invokes that object's <code>initialize</code> method,
+ *  passing it <i>args</i>. This is the method that ends
+ *  up getting called whenever an object is constructed using
+ *  `.new`.
+ *
+ */
+
+MRB_API mrb_value
+mrb_instance_new(mrb_state *mrb, mrb_value cv)
+{
+  mrb_value obj, blk;
+  mrb_value *argv;
+  mrb_int argc;
+
+  mrb_get_args(mrb, "*&", &argv, &argc, &blk);
+  obj = mrb_instance_alloc(mrb, cv);
+  mrb_funcall_with_block(mrb, obj, mrb_intern_lit(mrb, "initialize"), argc, argv, blk);
+
+  return obj;
+}
+
+MRB_API mrb_value
+mrb_obj_new(mrb_state *mrb, struct RClass *c, mrb_int argc, const mrb_value *argv)
+{
+  mrb_value obj;
+  mrb_sym mid;
+
+  obj = mrb_instance_alloc(mrb, mrb_obj_value(c));
+  mid = mrb_intern_lit(mrb, "initialize");
+  if (!mrb_func_basic_p(mrb, obj, mid, mrb_bob_init)) {
+    mrb_funcall_argv(mrb, obj, mid, argc, argv);
+  }
+  return obj;
+}
+
+static mrb_value
+mrb_class_initialize(mrb_state *mrb, mrb_value c)
+{
+  mrb_value a, b;
+
+  mrb_get_args(mrb, "|C&", &a, &b);
+  if (!mrb_nil_p(b)) {
+    mrb_yield_with_class(mrb, b, 1, &c, c, mrb_class_ptr(c));
+  }
+  return c;
+}
+
+static mrb_value
+mrb_class_new_class(mrb_state *mrb, mrb_value cv)
+{
+  mrb_int n;
+  mrb_value super, blk;
+  mrb_value new_class;
+  mrb_sym mid;
+
+  n = mrb_get_args(mrb, "|C&", &super, &blk);
+  if (n == 0) {
+    super = mrb_obj_value(mrb->object_class);
+  }
+  new_class = mrb_obj_value(mrb_class_new(mrb, mrb_class_ptr(super)));
+  mid = mrb_intern_lit(mrb, "initialize");
+  if (!mrb_func_basic_p(mrb, new_class, mid, mrb_bob_init)) {
+    mrb_funcall_with_block(mrb, new_class, mid, n, &super, blk);
+  }
+  mrb_class_inherited(mrb, mrb_class_ptr(super), mrb_class_ptr(new_class));
+  return new_class;
+}
+
+static mrb_value
+mrb_class_superclass(mrb_state *mrb, mrb_value klass)
+{
+  struct RClass *c;
+
+  c = mrb_class_ptr(klass);
+  c = find_origin(c)->super;
+  while (c && c->tt == MRB_TT_ICLASS) {
+    c = find_origin(c)->super;
+  }
+  if (!c) return mrb_nil_value();
+  return mrb_obj_value(c);
+}
+
+static mrb_value
+mrb_bob_init(mrb_state *mrb, mrb_value cv)
+{
+  return mrb_nil_value();
+}
+
+static mrb_value
+mrb_bob_not(mrb_state *mrb, mrb_value cv)
+{
+  return mrb_bool_value(!mrb_test(cv));
+}
+
+/* 15.3.1.3.1  */
+/* 15.3.1.3.10 */
+/* 15.3.1.3.11 */
+/*
+ *  call-seq:
+ *     obj == other        -> true or false
+ *     obj.equal?(other)   -> true or false
+ *     obj.eql?(other)     -> true or false
+ *
+ *  Equality---At the <code>Object</code> level, <code>==</code> returns
+ *  <code>true</code> only if <i>obj</i> and <i>other</i> are the
+ *  same object. Typically, this method is overridden in descendant
+ *  classes to provide class-specific meaning.
+ *
+ *  Unlike <code>==</code>, the <code>equal?</code> method should never be
+ *  overridden by subclasses: it is used to determine object identity
+ *  (that is, <code>a.equal?(b)</code> iff <code>a</code> is the same
+ *  object as <code>b</code>).
+ *
+ *  The <code>eql?</code> method returns <code>true</code> if
+ *  <i>obj</i> and <i>anObject</i> have the same value. Used by
+ *  <code>Hash</code> to test members for equality.  For objects of
+ *  class <code>Object</code>, <code>eql?</code> is synonymous with
+ *  <code>==</code>. Subclasses normally continue this tradition, but
+ *  there are exceptions. <code>Numeric</code> types, for example,
+ *  perform type conversion across <code>==</code>, but not across
+ *  <code>eql?</code>, so:
+ *
+ *     1 == 1.0     #=> true
+ *     1.eql? 1.0   #=> false
+ */
+mrb_value
+mrb_obj_equal_m(mrb_state *mrb, mrb_value self)
+{
+  mrb_value arg;
+
+  mrb_get_args(mrb, "o", &arg);
+  return mrb_bool_value(mrb_obj_equal(mrb, self, arg));
+}
+
+static mrb_value
+mrb_obj_not_equal_m(mrb_state *mrb, mrb_value self)
+{
+  mrb_value arg;
+
+  mrb_get_args(mrb, "o", &arg);
+  return mrb_bool_value(!mrb_equal(mrb, self, arg));
+}
+
+MRB_API mrb_bool
+mrb_obj_respond_to(mrb_state *mrb, struct RClass* c, mrb_sym mid)
+{
+  khiter_t k;
+
+  while (c) {
+    khash_t(mt) *h = c->mt;
+
+    if (h) {
+      k = kh_get(mt, mrb, h, mid);
+      if (k != kh_end(h)) {
+        if (kh_value(h, k)) {
+          return TRUE;  /* method exists */
+        }
+        else {
+          return FALSE; /* undefined method */
+        }
+      }
+    }
+    c = c->super;
+  }
+  return FALSE;         /* no method */
+}
+
+MRB_API mrb_bool
+mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid)
+{
+  return mrb_obj_respond_to(mrb, mrb_class(mrb, obj), mid);
+}
+
+MRB_API mrb_value
+mrb_class_path(mrb_state *mrb, struct RClass *c)
+{
+  mrb_value path;
+  const char *name;
+  mrb_sym classpath = mrb_intern_lit(mrb, "__classpath__");
+
+  path = mrb_obj_iv_get(mrb, (struct RObject*)c, classpath);
+  if (mrb_nil_p(path)) {
+    struct RClass *outer = mrb_class_outer_module(mrb, c);
+    mrb_sym sym = mrb_class_sym(mrb, c, outer);
+    mrb_int len;
+
+    if (sym == 0) {
+      return mrb_nil_value();
+    }
+    else if (outer && outer != c && outer != mrb->object_class) {
+      mrb_value base = mrb_class_path(mrb, outer);
+      path = mrb_str_buf_new(mrb, 0);
+      if (mrb_nil_p(base)) {
+        mrb_str_cat_lit(mrb, path, "#<Class:");
+        mrb_str_concat(mrb, path, mrb_ptr_to_str(mrb, outer));
+        mrb_str_cat_lit(mrb, path, ">");
+      }
+      else {
+        mrb_str_concat(mrb, path, base);
+      }
+      mrb_str_cat_lit(mrb, path, "::");
+      name = mrb_sym2name_len(mrb, sym, &len);
+      mrb_str_cat(mrb, path, name, len);
+    }
+    else {
+      name = mrb_sym2name_len(mrb, sym, &len);
+      path = mrb_str_new(mrb, name, len);
+    }
+    if (!MRB_FROZEN_P(c)) {
+      mrb_obj_iv_set(mrb, (struct RObject*)c, classpath, path);
+    }
+  }
+  return mrb_str_dup(mrb, path);
+}
+
+MRB_API struct RClass *
+mrb_class_real(struct RClass* cl)
+{
+  if (cl == 0)
+    return NULL;
+  while ((cl->tt == MRB_TT_SCLASS) || (cl->tt == MRB_TT_ICLASS)) {
+    cl = cl->super;
+  }
+  return cl;
+}
+
+MRB_API const char*
+mrb_class_name(mrb_state *mrb, struct RClass* c)
+{
+  mrb_value path = mrb_class_path(mrb, c);
+  if (mrb_nil_p(path)) {
+    path = mrb_str_new_lit(mrb, "#<Class:");
+    mrb_str_concat(mrb, path, mrb_ptr_to_str(mrb, c));
+    mrb_str_cat_lit(mrb, path, ">");
+  }
+  return RSTRING_PTR(path);
+}
+
+MRB_API const char*
+mrb_obj_classname(mrb_state *mrb, mrb_value obj)
+{
+  return mrb_class_name(mrb, mrb_obj_class(mrb, obj));
+}
+
+/*!
+ * Ensures a class can be derived from super.
+ *
+ * \param super a reference to an object.
+ * \exception TypeError if \a super is not a Class or \a super is a singleton class.
+ */
+static void
+mrb_check_inheritable(mrb_state *mrb, struct RClass *super)
+{
+  if (super->tt != MRB_TT_CLASS) {
+    mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%S given)", mrb_obj_value(super));
+  }
+  if (super->tt == MRB_TT_SCLASS) {
+    mrb_raise(mrb, E_TYPE_ERROR, "can't make subclass of singleton class");
+  }
+  if (super == mrb->class_class) {
+    mrb_raise(mrb, E_TYPE_ERROR, "can't make subclass of Class");
+  }
+}
+
+/*!
+ * Creates a new class.
+ * \param super     a class from which the new class derives.
+ * \exception TypeError \a super is not inheritable.
+ * \exception TypeError \a super is the Class class.
+ */
+MRB_API struct RClass*
+mrb_class_new(mrb_state *mrb, struct RClass *super)
+{
+  struct RClass *c;
+
+  if (super) {
+    mrb_check_inheritable(mrb, super);
+  }
+  c = boot_defclass(mrb, super);
+  if (super) {
+    MRB_SET_INSTANCE_TT(c, MRB_INSTANCE_TT(super));
+  }
+  make_metaclass(mrb, c);
+
+  return c;
+}
+
+/*!
+ * Creates a new module.
+ */
+MRB_API struct RClass*
+mrb_module_new(mrb_state *mrb)
+{
+  struct RClass *m = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_MODULE, mrb->module_class);
+  boot_initmod(mrb, m);
+  return m;
+}
+
+/*
+ *  call-seq:
+ *     obj.class    => class
+ *
+ *  Returns the class of <i>obj</i>, now preferred over
+ *  <code>Object#type</code>, as an object's type in Ruby is only
+ *  loosely tied to that object's class. This method must always be
+ *  called with an explicit receiver, as <code>class</code> is also a
+ *  reserved word in Ruby.
+ *
+ *     1.class      #=> Fixnum
+ *     self.class   #=> Object
+ */
+
+MRB_API struct RClass*
+mrb_obj_class(mrb_state *mrb, mrb_value obj)
+{
+  return mrb_class_real(mrb_class(mrb, obj));
+}
+
+MRB_API void
+mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b)
+{
+  struct RProc *m = mrb_method_search(mrb, c, b);
+
+  mrb_define_method_raw(mrb, c, a, m);
+}
+
+/*!
+ * Defines an alias of a method.
+ * \param klass  the class which the original method belongs to
+ * \param name1  a new name for the method
+ * \param name2  the original name of the method
+ */
+MRB_API void
+mrb_define_alias(mrb_state *mrb, struct RClass *klass, const char *name1, const char *name2)
+{
+  mrb_alias_method(mrb, klass, mrb_intern_cstr(mrb, name1), mrb_intern_cstr(mrb, name2));
+}
+
+/*
+ * call-seq:
+ *   mod.to_s   -> string
+ *
+ * Return a string representing this module or class. For basic
+ * classes and modules, this is the name. For singletons, we
+ * show information on the thing we're attached to as well.
+ */
+
+static mrb_value
+mrb_mod_to_s(mrb_state *mrb, mrb_value klass)
+{
+  mrb_value str;
+
+  if (mrb_type(klass) == MRB_TT_SCLASS) {
+    mrb_value v = mrb_iv_get(mrb, klass, mrb_intern_lit(mrb, "__attached__"));
+
+    str = mrb_str_new_lit(mrb, "#<Class:");
+
+    if (class_ptr_p(v)) {
+      mrb_str_cat_str(mrb, str, mrb_inspect(mrb, v));
+    }
+    else {
+      mrb_str_cat_str(mrb, str, mrb_any_to_s(mrb, v));
+    }
+    return mrb_str_cat_lit(mrb, str, ">");
+  }
+  else {
+    struct RClass *c;
+    mrb_value path;
+
+    str = mrb_str_buf_new(mrb, 32);
+    c = mrb_class_ptr(klass);
+    path = mrb_class_path(mrb, c);
+
+    if (mrb_nil_p(path)) {
+      switch (mrb_type(klass)) {
+        case MRB_TT_CLASS:
+          mrb_str_cat_lit(mrb, str, "#<Class:");
+          break;
+
+        case MRB_TT_MODULE:
+          mrb_str_cat_lit(mrb, str, "#<Module:");
+          break;
+
+        default:
+          /* Shouldn't be happened? */
+          mrb_str_cat_lit(mrb, str, "#<??????:");
+          break;
+      }
+      mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, c));
+      return mrb_str_cat_lit(mrb, str, ">");
+    }
+    else {
+      return path;
+    }
+  }
+}
+
+static mrb_value
+mrb_mod_alias(mrb_state *mrb, mrb_value mod)
+{
+  struct RClass *c = mrb_class_ptr(mod);
+  mrb_sym new_name, old_name;
+
+  mrb_get_args(mrb, "nn", &new_name, &old_name);
+  mrb_alias_method(mrb, c, new_name, old_name);
+  return mrb_nil_value();
+}
+
+static void
+undef_method(mrb_state *mrb, struct RClass *c, mrb_sym a)
+{
+  if (!mrb_obj_respond_to(mrb, c, a)) {
+    mrb_name_error(mrb, a, "undefined method '%S' for class '%S'", mrb_sym2str(mrb, a), mrb_obj_value(c));
+  }
+  else {
+    mrb_define_method_raw(mrb, c, a, NULL);
+  }
+}
+
+MRB_API void
+mrb_undef_method(mrb_state *mrb, struct RClass *c, const char *name)
+{
+  undef_method(mrb, c, mrb_intern_cstr(mrb, name));
+}
+
+MRB_API void
+mrb_undef_class_method(mrb_state *mrb, struct RClass *c, const char *name)
+{
+  mrb_undef_method(mrb,  mrb_class_ptr(mrb_singleton_class(mrb, mrb_obj_value(c))), name);
+}
+
+static mrb_value
+mrb_mod_undef(mrb_state *mrb, mrb_value mod)
+{
+  struct RClass *c = mrb_class_ptr(mod);
+  mrb_int argc;
+  mrb_value *argv;
+
+  mrb_get_args(mrb, "*", &argv, &argc);
+  while (argc--) {
+    undef_method(mrb, c, to_sym(mrb, *argv));
+    argv++;
+  }
+  return mrb_nil_value();
+}
+
+static mrb_value
+mod_define_method(mrb_state *mrb, mrb_value self)
+{
+  struct RClass *c = mrb_class_ptr(self);
+  struct RProc *p;
+  mrb_sym mid;
+  mrb_value proc = mrb_undef_value();
+  mrb_value blk;
+
+  mrb_get_args(mrb, "n|o&", &mid, &proc, &blk);
+  switch (mrb_type(proc)) {
+    case MRB_TT_PROC:
+      blk = proc;
+      break;
+    case MRB_TT_UNDEF:
+      /* ignored */
+      break;
+    default:
+      mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected Proc)", mrb_obj_value(mrb_obj_class(mrb, proc)));
+      break;
+  }
+  if (mrb_nil_p(blk)) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
+  }
+  p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
+  mrb_proc_copy(p, mrb_proc_ptr(blk));
+  p->flags |= MRB_PROC_STRICT;
+  mrb_define_method_raw(mrb, c, mid, p);
+  return mrb_symbol_value(mid);
+}
+
+static void
+check_cv_name_str(mrb_state *mrb, mrb_value str)
+{
+  const char *s = RSTRING_PTR(str);
+  mrb_int len = RSTRING_LEN(str);
+
+  if (len < 3 || !(s[0] == '@' && s[1] == '@')) {
+    mrb_name_error(mrb, mrb_intern_str(mrb, str), "'%S' is not allowed as a class variable name", str);
+  }
+}
+
+static void
+check_cv_name_sym(mrb_state *mrb, mrb_sym id)
+{
+  check_cv_name_str(mrb, mrb_sym2str(mrb, id));
+}
+
+/* 15.2.2.4.16 */
+/*
+ *  call-seq:
+ *     obj.class_variable_defined?(symbol)    -> true or false
+ *
+ *  Returns <code>true</code> if the given class variable is defined
+ *  in <i>obj</i>.
+ *
+ *     class Fred
+ *       @@foo = 99
+ *     end
+ *     Fred.class_variable_defined?(:@@foo)    #=> true
+ *     Fred.class_variable_defined?(:@@bar)    #=> false
+ */
+
+static mrb_value
+mrb_mod_cvar_defined(mrb_state *mrb, mrb_value mod)
+{
+  mrb_sym id;
+
+  mrb_get_args(mrb, "n", &id);
+  check_cv_name_sym(mrb, id);
+  return mrb_bool_value(mrb_cv_defined(mrb, mod, id));
+}
+
+/* 15.2.2.4.17 */
+/*
+ *  call-seq:
+ *     mod.class_variable_get(symbol)    -> obj
+ *
+ *  Returns the value of the given class variable (or throws a
+ *  <code>NameError</code> exception). The <code>@@</code> part of the
+ *  variable name should be included for regular class variables
+ *
+ *     class Fred
+ *       @@foo = 99
+ *     end
+ *     Fred.class_variable_get(:@@foo)     #=> 99
+ */
+
+static mrb_value
+mrb_mod_cvar_get(mrb_state *mrb, mrb_value mod)
+{
+  mrb_sym id;
+
+  mrb_get_args(mrb, "n", &id);
+  check_cv_name_sym(mrb, id);
+  return mrb_cv_get(mrb, mod, id);
+}
+
+/* 15.2.2.4.18 */
+/*
+ *  call-seq:
+ *     obj.class_variable_set(symbol, obj)    -> obj
+ *
+ *  Sets the class variable names by <i>symbol</i> to
+ *  <i>object</i>.
+ *
+ *     class Fred
+ *       @@foo = 99
+ *       def foo
+ *         @@foo
+ *       end
+ *     end
+ *     Fred.class_variable_set(:@@foo, 101)     #=> 101
+ *     Fred.new.foo                             #=> 101
+ */
+
+static mrb_value
+mrb_mod_cvar_set(mrb_state *mrb, mrb_value mod)
+{
+  mrb_value value;
+  mrb_sym id;
+
+  mrb_get_args(mrb, "no", &id, &value);
+  check_cv_name_sym(mrb, id);
+  mrb_cv_set(mrb, mod, id, value);
+  return value;
+}
+
+/* 15.2.2.4.39 */
+/*
+ *  call-seq:
+ *     remove_class_variable(sym)    -> obj
+ *
+ *  Removes the definition of the <i>sym</i>, returning that
+ *  constant's value.
+ *
+ *     class Dummy
+ *       @@var = 99
+ *       puts @@var
+ *       p class_variables
+ *       remove_class_variable(:@@var)
+ *       p class_variables
+ *     end
+ *
+ *  <em>produces:</em>
+ *
+ *     99
+ *     [:@@var]
+ *     []
+ */
+
+static mrb_value
+mrb_mod_remove_cvar(mrb_state *mrb, mrb_value mod)
+{
+  mrb_value val;
+  mrb_sym id;
+
+  mrb_get_args(mrb, "n", &id);
+  check_cv_name_sym(mrb, id);
+
+  val = mrb_iv_remove(mrb, mod, id);
+  if (!mrb_undef_p(val)) return val;
+
+  if (mrb_cv_defined(mrb, mod, id)) {
+    mrb_name_error(mrb, id, "cannot remove %S for %S",
+                   mrb_sym2str(mrb, id), mod);
+  }
+
+  mrb_name_error(mrb, id, "class variable %S not defined for %S",
+                 mrb_sym2str(mrb, id), mod);
+
+ /* not reached */
+ return mrb_nil_value();
+}
+
+/* 15.2.2.4.34 */
+/*
+ *  call-seq:
+ *     mod.method_defined?(symbol)    -> true or false
+ *
+ *  Returns +true+ if the named method is defined by
+ *  _mod_ (or its included modules and, if _mod_ is a class,
+ *  its ancestors). Public and protected methods are matched.
+ *
+ *     module A
+ *       def method1()  end
+ *     end
+ *     class B
+ *       def method2()  end
+ *     end
+ *     class C < B
+ *       include A
+ *       def method3()  end
+ *     end
+ *
+ *     A.method_defined? :method1    #=> true
+ *     C.method_defined? "method1"   #=> true
+ *     C.method_defined? "method2"   #=> true
+ *     C.method_defined? "method3"   #=> true
+ *     C.method_defined? "method4"   #=> false
+ */
+
+static mrb_value
+mrb_mod_method_defined(mrb_state *mrb, mrb_value mod)
+{
+  mrb_sym id;
+
+  mrb_get_args(mrb, "n", &id);
+  return mrb_bool_value(mrb_obj_respond_to(mrb, mrb_class_ptr(mod), id));
+}
+
+static void
+remove_method(mrb_state *mrb, mrb_value mod, mrb_sym mid)
+{
+  struct RClass *c = mrb_class_ptr(mod);
+  khash_t(mt) *h = find_origin(c)->mt;
+  khiter_t k;
+
+  if (h) {
+    k = kh_get(mt, mrb, h, mid);
+    if (k != kh_end(h)) {
+      kh_del(mt, mrb, h, k);
+      mrb_funcall(mrb, mod, "method_removed", 1, mrb_symbol_value(mid));
+      return;
+    }
+  }
+
+  mrb_name_error(mrb, mid, "method '%S' not defined in %S",
+    mrb_sym2str(mrb, mid), mod);
+}
+
+/* 15.2.2.4.41 */
+/*
+ *  call-seq:
+ *     remove_method(symbol)   -> self
+ *
+ *  Removes the method identified by _symbol_ from the current
+ *  class. For an example, see <code>Module.undef_method</code>.
+ */
+
+static mrb_value
+mrb_mod_remove_method(mrb_state *mrb, mrb_value mod)
+{
+  mrb_int argc;
+  mrb_value *argv;
+
+  mrb_get_args(mrb, "*", &argv, &argc);
+  while (argc--) {
+    remove_method(mrb, mod, to_sym(mrb, *argv));
+    argv++;
+  }
+  return mod;
+}
+
+
+
+static void
+check_const_name_str(mrb_state *mrb, mrb_value str)
+{
+  if (RSTRING_LEN(str) < 1 || !ISUPPER(*RSTRING_PTR(str))) {
+    mrb_name_error(mrb, mrb_intern_str(mrb, str), "wrong constant name %S", str);
+  }
+}
+
+static void
+check_const_name_sym(mrb_state *mrb, mrb_sym id)
+{
+  check_const_name_str(mrb, mrb_sym2str(mrb, id));
+}
+
+static mrb_value
+const_defined(mrb_state *mrb, mrb_value mod, mrb_sym id, mrb_bool inherit)
+{
+  if (inherit) {
+    return mrb_bool_value(mrb_const_defined(mrb, mod, id));
+  }
+  return mrb_bool_value(mrb_const_defined_at(mrb, mod, id));
+}
+
+static mrb_value
+mrb_mod_const_defined(mrb_state *mrb, mrb_value mod)
+{
+  mrb_sym id;
+  mrb_bool inherit = TRUE;
+
+  mrb_get_args(mrb, "n|b", &id, &inherit);
+  check_const_name_sym(mrb, id);
+  return const_defined(mrb, mod, id, inherit);
+}
+
+static mrb_value
+mrb_mod_const_get(mrb_state *mrb, mrb_value mod)
+{
+  mrb_sym id;
+
+  mrb_get_args(mrb, "n", &id);
+  check_const_name_sym(mrb, id);
+  return mrb_const_get(mrb, mod, id);
+}
+
+static mrb_value
+mrb_mod_const_set(mrb_state *mrb, mrb_value mod)
+{
+  mrb_sym id;
+  mrb_value value;
+
+  mrb_get_args(mrb, "no", &id, &value);
+  check_const_name_sym(mrb, id);
+  mrb_const_set(mrb, mod, id, value);
+  return value;
+}
+
+static mrb_value
+mrb_mod_remove_const(mrb_state *mrb, mrb_value mod)
+{
+  mrb_sym id;
+  mrb_value val;
+
+  mrb_get_args(mrb, "n", &id);
+  check_const_name_sym(mrb, id);
+  val = mrb_iv_remove(mrb, mod, id);
+  if (mrb_undef_p(val)) {
+    mrb_name_error(mrb, id, "constant %S not defined", mrb_sym2str(mrb, id));
+  }
+  return val;
+}
+
+static mrb_value
+mrb_mod_const_missing(mrb_state *mrb, mrb_value mod)
+{
+  mrb_sym sym;
+
+  mrb_get_args(mrb, "n", &sym);
+
+  if (mrb_class_real(mrb_class_ptr(mod)) != mrb->object_class) {
+    mrb_name_error(mrb, sym, "uninitialized constant %S::%S",
+                   mod,
+                   mrb_sym2str(mrb, sym));
+  }
+  else {
+    mrb_name_error(mrb, sym, "uninitialized constant %S",
+                   mrb_sym2str(mrb, sym));
+  }
+  /* not reached */
+  return mrb_nil_value();
+}
+
+static mrb_value
+mrb_mod_s_constants(mrb_state *mrb, mrb_value mod)
+{
+  mrb_raise(mrb, E_NOTIMP_ERROR, "Module.constants not implemented");
+  return mrb_nil_value();       /* not reached */
+}
+
+static mrb_value
+mrb_mod_eqq(mrb_state *mrb, mrb_value mod)
+{
+  mrb_value obj;
+  mrb_bool eqq;
+
+  mrb_get_args(mrb, "o", &obj);
+  eqq = mrb_obj_is_kind_of(mrb, obj, mrb_class_ptr(mod));
+
+  return mrb_bool_value(eqq);
+}
+
+MRB_API mrb_value
+mrb_mod_module_function(mrb_state *mrb, mrb_value mod)
+{
+  mrb_value *argv;
+  mrb_int argc, i;
+  mrb_sym mid;
+  struct RProc *method_rproc;
+  struct RClass *rclass;
+  int ai;
+
+  mrb_check_type(mrb, mod, MRB_TT_MODULE);
+
+  mrb_get_args(mrb, "*", &argv, &argc);
+  if (argc == 0) {
+    /* set MODFUNC SCOPE if implemented */
+    return mod;
+  }
+
+  /* set PRIVATE method visibility if implemented */
+  /* mrb_mod_dummy_visibility(mrb, mod); */
+
+  for (i=0; i<argc; i++) {
+    mrb_check_type(mrb, argv[i], MRB_TT_SYMBOL);
+
+    mid = mrb_symbol(argv[i]);
+    rclass = mrb_class_ptr(mod);
+    method_rproc = mrb_method_search(mrb, rclass, mid);
+
+    prepare_singleton_class(mrb, (struct RBasic*)rclass);
+    ai = mrb_gc_arena_save(mrb);
+    mrb_define_method_raw(mrb, rclass->c, mid, method_rproc);
+    mrb_gc_arena_restore(mrb, ai);
+  }
+
+  return mod;
+}
+
+/* implementation of __id__ */
+mrb_value mrb_obj_id_m(mrb_state *mrb, mrb_value self);
+/* implementation of instance_eval */
+mrb_value mrb_obj_instance_eval(mrb_state*, mrb_value);
+
+void
+mrb_init_class(mrb_state *mrb)
+{
+  struct RClass *bob;           /* BasicObject */
+  struct RClass *obj;           /* Object */
+  struct RClass *mod;           /* Module */
+  struct RClass *cls;           /* Class */
+
+  /* boot class hierarchy */
+  bob = boot_defclass(mrb, 0);
+  obj = boot_defclass(mrb, bob); mrb->object_class = obj;
+  mod = boot_defclass(mrb, obj); mrb->module_class = mod;/* obj -> mod */
+  cls = boot_defclass(mrb, mod); mrb->class_class = cls; /* obj -> cls */
+  /* fix-up loose ends */
+  bob->c = obj->c = mod->c = cls->c = cls;
+  make_metaclass(mrb, bob);
+  make_metaclass(mrb, obj);
+  make_metaclass(mrb, mod);
+  make_metaclass(mrb, cls);
+
+  /* name basic classes */
+  mrb_define_const(mrb, bob, "BasicObject", mrb_obj_value(bob));
+  mrb_define_const(mrb, obj, "BasicObject", mrb_obj_value(bob));
+  mrb_define_const(mrb, obj, "Object",      mrb_obj_value(obj));
+  mrb_define_const(mrb, obj, "Module",      mrb_obj_value(mod));
+  mrb_define_const(mrb, obj, "Class",       mrb_obj_value(cls));
+
+  /* name each classes */
+  name_class(mrb, bob, mrb_intern_lit(mrb, "BasicObject"));
+  name_class(mrb, obj, mrb_intern_lit(mrb, "Object"));           /* 15.2.1 */
+  name_class(mrb, mod, mrb_intern_lit(mrb, "Module"));           /* 15.2.2 */
+  name_class(mrb, cls, mrb_intern_lit(mrb, "Class"));            /* 15.2.3 */
+
+  mrb->proc_class = mrb_define_class(mrb, "Proc", mrb->object_class);  /* 15.2.17 */
+  MRB_SET_INSTANCE_TT(mrb->proc_class, MRB_TT_PROC);
+
+  MRB_SET_INSTANCE_TT(cls, MRB_TT_CLASS);
+  mrb_define_method(mrb, bob, "initialize",              mrb_bob_init,             MRB_ARGS_NONE());
+  mrb_define_method(mrb, bob, "!",                       mrb_bob_not,              MRB_ARGS_NONE());
+  mrb_define_method(mrb, bob, "==",                      mrb_obj_equal_m,          MRB_ARGS_REQ(1)); /* 15.3.1.3.1  */
+  mrb_define_method(mrb, bob, "!=",                      mrb_obj_not_equal_m,      MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, bob, "__id__",                  mrb_obj_id_m,             MRB_ARGS_NONE()); /* 15.3.1.3.3  */
+  mrb_define_method(mrb, bob, "__send__",                mrb_f_send,               MRB_ARGS_ANY());  /* 15.3.1.3.4  */
+  mrb_define_method(mrb, bob, "instance_eval",           mrb_obj_instance_eval,    MRB_ARGS_ANY());  /* 15.3.1.3.18 */
+
+  mrb_define_class_method(mrb, cls, "new",               mrb_class_new_class,      MRB_ARGS_OPT(1));
+  mrb_define_method(mrb, cls, "superclass",              mrb_class_superclass,     MRB_ARGS_NONE()); /* 15.2.3.3.4 */
+  mrb_define_method(mrb, cls, "new",                     mrb_instance_new,         MRB_ARGS_ANY());  /* 15.2.3.3.3 */
+  mrb_define_method(mrb, cls, "initialize",              mrb_class_initialize,     MRB_ARGS_OPT(1)); /* 15.2.3.3.1 */
+  mrb_define_method(mrb, cls, "inherited",               mrb_bob_init,             MRB_ARGS_REQ(1));
+
+  MRB_SET_INSTANCE_TT(mod, MRB_TT_MODULE);
+  mrb_define_method(mrb, mod, "class_variable_defined?", mrb_mod_cvar_defined,     MRB_ARGS_REQ(1)); /* 15.2.2.4.16 */
+  mrb_define_method(mrb, mod, "class_variable_get",      mrb_mod_cvar_get,         MRB_ARGS_REQ(1)); /* 15.2.2.4.17 */
+  mrb_define_method(mrb, mod, "class_variable_set",      mrb_mod_cvar_set,         MRB_ARGS_REQ(2)); /* 15.2.2.4.18 */
+  mrb_define_method(mrb, mod, "extend_object",           mrb_mod_extend_object,    MRB_ARGS_REQ(1)); /* 15.2.2.4.25 */
+  mrb_define_method(mrb, mod, "extended",                mrb_bob_init,             MRB_ARGS_REQ(1)); /* 15.2.2.4.26 */
+  mrb_define_method(mrb, mod, "prepended",               mrb_bob_init,             MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, mod, "prepend_features",        mrb_mod_prepend_features, MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, mod, "include?",                mrb_mod_include_p,        MRB_ARGS_REQ(1)); /* 15.2.2.4.28 */
+  mrb_define_method(mrb, mod, "append_features",         mrb_mod_append_features,  MRB_ARGS_REQ(1)); /* 15.2.2.4.10 */
+  mrb_define_method(mrb, mod, "class_eval",              mrb_mod_module_eval,      MRB_ARGS_ANY());  /* 15.2.2.4.15 */
+  mrb_define_method(mrb, mod, "included",                mrb_bob_init,             MRB_ARGS_REQ(1)); /* 15.2.2.4.29 */
+  mrb_define_method(mrb, mod, "included_modules",        mrb_mod_included_modules, MRB_ARGS_NONE()); /* 15.2.2.4.30 */
+  mrb_define_method(mrb, mod, "initialize",              mrb_mod_initialize,       MRB_ARGS_NONE()); /* 15.2.2.4.31 */
+  mrb_define_method(mrb, mod, "instance_methods",        mrb_mod_instance_methods, MRB_ARGS_ANY());  /* 15.2.2.4.33 */
+  mrb_define_method(mrb, mod, "method_defined?",         mrb_mod_method_defined,   MRB_ARGS_REQ(1)); /* 15.2.2.4.34 */
+  mrb_define_method(mrb, mod, "module_eval",             mrb_mod_module_eval,      MRB_ARGS_ANY());  /* 15.2.2.4.35 */
+  mrb_define_method(mrb, mod, "module_function",         mrb_mod_module_function,  MRB_ARGS_ANY());
+  mrb_define_method(mrb, mod, "private",                 mrb_mod_dummy_visibility, MRB_ARGS_ANY());  /* 15.2.2.4.36 */
+  mrb_define_method(mrb, mod, "protected",               mrb_mod_dummy_visibility, MRB_ARGS_ANY());  /* 15.2.2.4.37 */
+  mrb_define_method(mrb, mod, "public",                  mrb_mod_dummy_visibility, MRB_ARGS_ANY());  /* 15.2.2.4.38 */
+  mrb_define_method(mrb, mod, "remove_class_variable",   mrb_mod_remove_cvar,      MRB_ARGS_REQ(1)); /* 15.2.2.4.39 */
+  mrb_define_method(mrb, mod, "remove_method",           mrb_mod_remove_method,    MRB_ARGS_ANY());  /* 15.2.2.4.41 */
+  mrb_define_method(mrb, mod, "method_removed",          mrb_bob_init,             MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, mod, "attr_reader",             mrb_mod_attr_reader,      MRB_ARGS_ANY());  /* 15.2.2.4.13 */
+  mrb_define_method(mrb, mod, "attr_writer",             mrb_mod_attr_writer,      MRB_ARGS_ANY());  /* 15.2.2.4.14 */
+  mrb_define_method(mrb, mod, "to_s",                    mrb_mod_to_s,             MRB_ARGS_NONE());
+  mrb_define_method(mrb, mod, "inspect",                 mrb_mod_to_s,             MRB_ARGS_NONE());
+  mrb_define_method(mrb, mod, "alias_method",            mrb_mod_alias,            MRB_ARGS_ANY());  /* 15.2.2.4.8 */
+  mrb_define_method(mrb, mod, "ancestors",               mrb_mod_ancestors,        MRB_ARGS_NONE()); /* 15.2.2.4.9 */
+  mrb_define_method(mrb, mod, "undef_method",            mrb_mod_undef,            MRB_ARGS_ANY());  /* 15.2.2.4.41 */
+  mrb_define_method(mrb, mod, "const_defined?",          mrb_mod_const_defined,    MRB_ARGS_ARG(1,1)); /* 15.2.2.4.20 */
+  mrb_define_method(mrb, mod, "const_get",               mrb_mod_const_get,        MRB_ARGS_REQ(1)); /* 15.2.2.4.21 */
+  mrb_define_method(mrb, mod, "const_set",               mrb_mod_const_set,        MRB_ARGS_REQ(2)); /* 15.2.2.4.23 */
+  mrb_define_method(mrb, mod, "constants",               mrb_mod_constants,        MRB_ARGS_OPT(1)); /* 15.2.2.4.24 */
+  mrb_define_method(mrb, mod, "remove_const",            mrb_mod_remove_const,     MRB_ARGS_REQ(1)); /* 15.2.2.4.40 */
+  mrb_define_method(mrb, mod, "const_missing",           mrb_mod_const_missing,    MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, mod, "define_method",           mod_define_method,        MRB_ARGS_ARG(1,1));
+  mrb_define_method(mrb, mod, "class_variables",         mrb_mod_class_variables,  MRB_ARGS_NONE()); /* 15.2.2.4.19 */
+  mrb_define_method(mrb, mod, "===",                     mrb_mod_eqq,              MRB_ARGS_REQ(1));
+  mrb_define_class_method(mrb, mod, "constants",         mrb_mod_s_constants,      MRB_ARGS_ANY());  /* 15.2.2.3.1 */
+
+  mrb_undef_method(mrb, cls, "append_features");
+  mrb_undef_method(mrb, cls, "extend_object");
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/codedump.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/codedump.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/codedump.c	(revision 331)
@@ -0,0 +1,474 @@
+#include <mruby.h>
+#include <mruby/irep.h>
+#include <mruby/debug.h>
+#include <mruby/opcode.h>
+#include <mruby/string.h>
+#include <mruby/proc.h>
+
+#ifndef MRB_DISABLE_STDIO
+static int
+print_r(mrb_state *mrb, mrb_irep *irep, size_t n, int pre)
+{
+  size_t i;
+
+  if (n == 0) return 0;
+
+  for (i=0; i+1<irep->nlocals; i++) {
+    if (irep->lv[i].r == n) {
+      mrb_sym sym = irep->lv[i].name;
+      if (pre) printf(" ");
+      printf("R%d:%s", (int)n, mrb_sym2name(mrb, sym));
+      return 1;
+    }
+  }
+  return 0;
+}
+
+#define RA  1
+#define RB  2
+#define RAB 3
+
+static void
+print_lv(mrb_state *mrb, mrb_irep *irep, mrb_code c, int r)
+{
+  int pre = 0;
+
+  if (!irep->lv
+      || ((!(r & RA) || GETARG_A(c) >= irep->nlocals)
+       && (!(r & RB) || GETARG_B(c) >= irep->nlocals))) {
+    printf("\n");
+    return;
+  }
+  printf("\t; ");
+  if (r & RA) {
+    pre = print_r(mrb, irep, GETARG_A(c), 0);
+  }
+  if (r & RB) {
+    print_r(mrb, irep, GETARG_B(c), pre);
+  }
+  printf("\n");
+}
+#endif
+
+static void
+codedump(mrb_state *mrb, mrb_irep *irep)
+{
+#ifndef MRB_DISABLE_STDIO
+  int i;
+  int ai;
+  mrb_code c;
+  const char *file = NULL, *next_file;
+  int32_t line;
+
+  if (!irep) return;
+  printf("irep %p nregs=%d nlocals=%d pools=%d syms=%d reps=%d\n", (void*)irep,
+         irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen, (int)irep->rlen);
+
+  for (i = 0; i < (int)irep->ilen; i++) {
+    ai = mrb_gc_arena_save(mrb);
+
+    next_file = mrb_debug_get_filename(irep, i);
+    if (next_file && file != next_file) {
+      printf("file: %s\n", next_file);
+      file = next_file;
+    }
+    line = mrb_debug_get_line(irep, i);
+    if (line < 0) {
+      printf("      ");
+    }
+    else {
+      printf("%5d ", line);
+    }
+
+    printf("%03d ", i);
+    c = irep->iseq[i];
+    switch (GET_OPCODE(c)) {
+    case OP_NOP:
+      printf("OP_NOP\n");
+      break;
+    case OP_MOVE:
+      printf("OP_MOVE\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c));
+      print_lv(mrb, irep, c, RAB);
+      break;
+    case OP_LOADL:
+      {
+        mrb_value v = irep->pool[GETARG_Bx(c)];
+        mrb_value s = mrb_inspect(mrb, v);
+        printf("OP_LOADL\tR%d\tL(%d)\t; %s", GETARG_A(c), GETARG_Bx(c), RSTRING_PTR(s));
+      }
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_LOADI:
+      printf("OP_LOADI\tR%d\t%d\t", GETARG_A(c), GETARG_sBx(c));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_LOADSYM:
+      printf("OP_LOADSYM\tR%d\t:%s", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_LOADNIL:
+      printf("OP_LOADNIL\tR%d\t\t", GETARG_A(c));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_LOADSELF:
+      printf("OP_LOADSELF\tR%d\t\t", GETARG_A(c));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_LOADT:
+      printf("OP_LOADT\tR%d\t\t", GETARG_A(c));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_LOADF:
+      printf("OP_LOADF\tR%d\t\t", GETARG_A(c));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_GETGLOBAL:
+      printf("OP_GETGLOBAL\tR%d\t:%s", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_SETGLOBAL:
+      printf("OP_SETGLOBAL\t:%s\tR%d\t",
+             mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
+             GETARG_A(c));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_GETCONST:
+      printf("OP_GETCONST\tR%d\t:%s", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_SETCONST:
+      printf("OP_SETCONST\t:%s\tR%d\t",
+             mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
+             GETARG_A(c));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_GETMCNST:
+      printf("OP_GETMCNST\tR%d\tR%d::%s", GETARG_A(c), GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
+      print_lv(mrb, irep, c, RAB);
+      break;
+    case OP_SETMCNST:
+      printf("OP_SETMCNST\tR%d::%s\tR%d", GETARG_A(c)+1,
+             mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
+             GETARG_A(c));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_GETIV:
+      printf("OP_GETIV\tR%d\t%s", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_SETIV:
+      printf("OP_SETIV\t%s\tR%d",
+             mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
+             GETARG_A(c));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_GETUPVAR:
+      printf("OP_GETUPVAR\tR%d\t%d\t%d",
+             GETARG_A(c), GETARG_B(c), GETARG_C(c));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_SETUPVAR:
+      printf("OP_SETUPVAR\tR%d\t%d\t%d",
+             GETARG_A(c), GETARG_B(c), GETARG_C(c));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_GETCV:
+      printf("OP_GETCV\tR%d\t%s", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_SETCV:
+      printf("OP_SETCV\t%s\tR%d",
+             mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
+             GETARG_A(c));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_JMP:
+      printf("OP_JMP\t%03d\n", i+GETARG_sBx(c));
+      break;
+    case OP_JMPIF:
+      printf("OP_JMPIF\tR%d\t%03d\n", GETARG_A(c), i+GETARG_sBx(c));
+      break;
+    case OP_JMPNOT:
+      printf("OP_JMPNOT\tR%d\t%03d\n", GETARG_A(c), i+GETARG_sBx(c));
+      break;
+    case OP_SEND:
+      printf("OP_SEND\tR%d\t:%s\t%d\n", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
+             GETARG_C(c));
+      break;
+    case OP_SENDB:
+      printf("OP_SENDB\tR%d\t:%s\t%d\n", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
+             GETARG_C(c));
+      break;
+    case OP_TAILCALL:
+      printf("OP_TAILCALL\tR%d\t:%s\t%d\n", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
+             GETARG_C(c));
+      break;
+    case OP_SUPER:
+      printf("OP_SUPER\tR%d\t%d\n", GETARG_A(c),
+             GETARG_C(c));
+      break;
+    case OP_ARGARY:
+      printf("OP_ARGARY\tR%d\t%d:%d:%d:%d", GETARG_A(c),
+             (GETARG_Bx(c)>>10)&0x3f,
+             (GETARG_Bx(c)>>9)&0x1,
+             (GETARG_Bx(c)>>4)&0x1f,
+             (GETARG_Bx(c)>>0)&0xf);
+      print_lv(mrb, irep, c, RA);
+      break;
+
+    case OP_ENTER:
+      printf("OP_ENTER\t%d:%d:%d:%d:%d:%d:%d\n",
+             (GETARG_Ax(c)>>18)&0x1f,
+             (GETARG_Ax(c)>>13)&0x1f,
+             (GETARG_Ax(c)>>12)&0x1,
+             (GETARG_Ax(c)>>7)&0x1f,
+             (GETARG_Ax(c)>>2)&0x1f,
+             (GETARG_Ax(c)>>1)&0x1,
+             GETARG_Ax(c) & 0x1);
+      break;
+    case OP_RETURN:
+      printf("OP_RETURN\tR%d", GETARG_A(c));
+      switch (GETARG_B(c)) {
+      case OP_R_NORMAL:
+        printf("\tnormal\t"); break;
+      case OP_R_RETURN:
+        printf("\treturn\t"); break;
+      case OP_R_BREAK:
+        printf("\tbreak\t"); break;
+      default:
+        printf("\tbroken\t"); break;
+      }
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_BLKPUSH:
+      printf("OP_BLKPUSH\tR%d\t%d:%d:%d:%d", GETARG_A(c),
+             (GETARG_Bx(c)>>10)&0x3f,
+             (GETARG_Bx(c)>>9)&0x1,
+             (GETARG_Bx(c)>>4)&0x1f,
+             (GETARG_Bx(c)>>0)&0xf);
+      print_lv(mrb, irep, c, RA);
+      break;
+
+    case OP_LAMBDA:
+      printf("OP_LAMBDA\tR%d\tI(%+d)\t", GETARG_A(c), GETARG_b(c)+1);
+      switch (GETARG_c(c)) {
+      case OP_L_METHOD:
+        printf("method"); break;
+      case OP_L_BLOCK:
+        printf("block"); break;
+      case OP_L_LAMBDA:
+        printf("lambda"); break;
+      }
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_RANGE:
+      printf("OP_RANGE\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c));
+      print_lv(mrb, irep, c, RAB);
+      break;
+    case OP_METHOD:
+      printf("OP_METHOD\tR%d\t:%s", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_B(c)]));
+      print_lv(mrb, irep, c, RA);
+      break;
+
+    case OP_ADD:
+      printf("OP_ADD\tR%d\t:%s\t%d\n", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
+             GETARG_C(c));
+      break;
+    case OP_ADDI:
+      printf("OP_ADDI\tR%d\t:%s\t%d\n", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
+             GETARG_C(c));
+      break;
+    case OP_SUB:
+      printf("OP_SUB\tR%d\t:%s\t%d\n", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
+             GETARG_C(c));
+      break;
+    case OP_SUBI:
+      printf("OP_SUBI\tR%d\t:%s\t%d\n", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
+             GETARG_C(c));
+      break;
+    case OP_MUL:
+      printf("OP_MUL\tR%d\t:%s\t%d\n", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
+             GETARG_C(c));
+      break;
+    case OP_DIV:
+      printf("OP_DIV\tR%d\t:%s\t%d\n", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
+             GETARG_C(c));
+      break;
+    case OP_LT:
+      printf("OP_LT\tR%d\t:%s\t%d\n", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
+             GETARG_C(c));
+      break;
+    case OP_LE:
+      printf("OP_LE\tR%d\t:%s\t%d\n", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
+             GETARG_C(c));
+      break;
+    case OP_GT:
+      printf("OP_GT\tR%d\t:%s\t%d\n", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
+             GETARG_C(c));
+      break;
+    case OP_GE:
+      printf("OP_GE\tR%d\t:%s\t%d\n", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
+             GETARG_C(c));
+      break;
+    case OP_EQ:
+      printf("OP_EQ\t\tR%d\t:%s\t%d\n", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
+             GETARG_C(c));
+      break;
+
+    case OP_STOP:
+      printf("OP_STOP\n");
+      break;
+
+    case OP_ARRAY:
+      printf("OP_ARRAY\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c));
+      print_lv(mrb, irep, c, RAB);
+      break;
+    case OP_ARYCAT:
+      printf("OP_ARYCAT\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c));
+      print_lv(mrb, irep, c, RAB);
+      break;
+    case OP_ARYPUSH:
+      printf("OP_ARYPUSH\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c));
+      print_lv(mrb, irep, c, RAB);
+      break;
+    case OP_AREF:
+      printf("OP_AREF\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c));
+      print_lv(mrb, irep, c, RAB);
+      break;
+    case OP_APOST:
+      printf("OP_APOST\tR%d\t%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_STRING:
+      {
+        mrb_value v = irep->pool[GETARG_Bx(c)];
+        mrb_value s = mrb_str_dump(mrb, mrb_str_new(mrb, RSTRING_PTR(v), RSTRING_LEN(v)));
+        printf("OP_STRING\tR%d\tL(%d)\t; %s", GETARG_A(c), GETARG_Bx(c), RSTRING_PTR(s));
+      }
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_STRCAT:
+      printf("OP_STRCAT\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c));
+      print_lv(mrb, irep, c, RAB);
+      break;
+    case OP_HASH:
+      printf("OP_HASH\tR%d\tR%d\t%d", GETARG_A(c), GETARG_B(c), GETARG_C(c));
+      print_lv(mrb, irep, c, RAB);
+      break;
+
+    case OP_OCLASS:
+      printf("OP_OCLASS\tR%d\t\t", GETARG_A(c));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_CLASS:
+      printf("OP_CLASS\tR%d\t:%s", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_B(c)]));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_MODULE:
+      printf("OP_MODULE\tR%d\t:%s", GETARG_A(c),
+             mrb_sym2name(mrb, irep->syms[GETARG_B(c)]));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_EXEC:
+      printf("OP_EXEC\tR%d\tI(%+d)", GETARG_A(c), GETARG_Bx(c)+1);
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_SCLASS:
+      printf("OP_SCLASS\tR%d\tR%d\t", GETARG_A(c), GETARG_B(c));
+      print_lv(mrb, irep, c, RAB);
+      break;
+    case OP_TCLASS:
+      printf("OP_TCLASS\tR%d\t\t", GETARG_A(c));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_ERR:
+      {
+        mrb_value v = irep->pool[GETARG_Bx(c)];
+        mrb_value s = mrb_str_dump(mrb, mrb_str_new(mrb, RSTRING_PTR(v), RSTRING_LEN(v)));
+        printf("OP_ERR\t%s\n", RSTRING_PTR(s));
+      }
+      break;
+    case OP_EPUSH:
+      printf("OP_EPUSH\t:I(%+d)\n", GETARG_Bx(c)+1);
+      break;
+    case OP_ONERR:
+      printf("OP_ONERR\t%03d\n", i+GETARG_sBx(c));
+      break;
+    case OP_RESCUE:
+      {
+        int a = GETARG_A(c);
+        int b = GETARG_B(c);
+        int cnt = GETARG_C(c);
+
+        if (b == 0) {
+          printf("OP_RESCUE\tR%d\t\t%s", a, cnt ? "cont" : "");
+          print_lv(mrb, irep, c, RA);
+          break;
+        }
+        else {
+          printf("OP_RESCUE\tR%d\tR%d\t%s", a, b, cnt ? "cont" : "");
+          print_lv(mrb, irep, c, RAB);
+          break;
+        }
+      }
+      break;
+    case OP_RAISE:
+      printf("OP_RAISE\tR%d\t\t", GETARG_A(c));
+      print_lv(mrb, irep, c, RA);
+      break;
+    case OP_POPERR:
+      printf("OP_POPERR\t%d\t\t\n", GETARG_A(c));
+      break;
+    case OP_EPOP:
+      printf("OP_EPOP\t%d\n", GETARG_A(c));
+      break;
+
+    default:
+      printf("OP_unknown %d\t%d\t%d\t%d\n", GET_OPCODE(c),
+             GETARG_A(c), GETARG_B(c), GETARG_C(c));
+      break;
+    }
+    mrb_gc_arena_restore(mrb, ai);
+  }
+  printf("\n");
+#endif
+}
+
+static void
+codedump_recur(mrb_state *mrb, mrb_irep *irep)
+{
+  size_t i;
+
+  codedump(mrb, irep);
+  for (i=0; i<irep->rlen; i++) {
+    codedump_recur(mrb, irep->reps[i]);
+  }
+}
+
+void
+mrb_codedump_all(mrb_state *mrb, struct RProc *proc)
+{
+  codedump_recur(mrb, proc->body.irep);
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/compar.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/compar.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/compar.c	(revision 331)
@@ -0,0 +1,13 @@
+/*
+** compar.c - Comparable module
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <mruby.h>
+
+void
+mrb_init_comparable(mrb_state *mrb)
+{
+  mrb_define_module(mrb, "Comparable");  /* 15.3.3 */
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/crc.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/crc.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/crc.c	(revision 331)
@@ -0,0 +1,39 @@
+/*
+** crc.c - calculate CRC
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <limits.h>
+#include <stdint.h>
+#include <stddef.h>
+
+/* Calculate CRC (CRC-16-CCITT)
+**
+**  0000_0000_0000_0000_0000_0000_0000_0000
+**          ^|------- CRC -------|- work --|
+**        carry
+*/
+#define  CRC_16_CCITT       0x11021ul        /* x^16+x^12+x^5+1 */
+#define  CRC_XOR_PATTERN    (CRC_16_CCITT << 8)
+#define  CRC_CARRY_BIT      (0x01000000)
+
+uint16_t
+calc_crc_16_ccitt(const uint8_t *src, size_t nbytes, uint16_t crc)
+{
+  size_t ibyte;
+  uint32_t ibit;
+  uint32_t crcwk = crc << 8;
+
+  for (ibyte = 0; ibyte < nbytes; ibyte++) {
+    crcwk |= *src++;
+    for (ibit = 0; ibit < CHAR_BIT; ibit++) {
+      crcwk <<= 1;
+      if (crcwk & CRC_CARRY_BIT) {
+        crcwk ^= CRC_XOR_PATTERN;
+      }
+    }
+  }
+  return (uint16_t)(crcwk >> 8);
+}
+
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/debug.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/debug.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/debug.c	(revision 331)
@@ -0,0 +1,217 @@
+#include <string.h>
+#include <mruby.h>
+#include <mruby/irep.h>
+#include <mruby/debug.h>
+
+static mrb_irep_debug_info_file *
+get_file(mrb_irep_debug_info *info, uint32_t pc)
+{
+  mrb_irep_debug_info_file **ret;
+  int32_t count;
+
+  if (pc >= info->pc_count) { return NULL; }
+  /* get upper bound */
+  ret = info->files;
+  count =  info->flen;
+  while (count > 0) {
+    int32_t step = count / 2;
+    mrb_irep_debug_info_file **it = ret + step;
+    if (!(pc < (*it)->start_pos)) {
+      ret = it + 1;
+      count -= step + 1;
+    }
+    else { count = step; }
+  }
+
+  --ret;
+
+  /* check returning file exists inside debug info */
+  mrb_assert(info->files <= ret && ret < (info->files + info->flen));
+  /* check pc is within the range of returning file */
+  mrb_assert((*ret)->start_pos <= pc &&
+             pc < (((ret + 1 - info->files) < info->flen)
+                   ? (*(ret+1))->start_pos : info->pc_count));
+
+  return *ret;
+}
+
+static mrb_debug_line_type
+select_line_type(const uint16_t *lines, size_t lines_len)
+{
+  size_t line_count = 0;
+  int prev_line = -1;
+  size_t i;
+  for (i = 0; i < lines_len; ++i) {
+    if (lines[i] != prev_line) {
+      ++line_count;
+    }
+  }
+  return (sizeof(uint16_t) * lines_len) <= (sizeof(mrb_irep_debug_info_line) * line_count)
+      ? mrb_debug_line_ary : mrb_debug_line_flat_map;
+}
+
+MRB_API char const*
+mrb_debug_get_filename(mrb_irep *irep, uint32_t pc)
+{
+  if (irep && pc < irep->ilen) {
+    mrb_irep_debug_info_file* f = NULL;
+    if (!irep->debug_info) { return irep->filename; }
+    else if ((f = get_file(irep->debug_info, pc))) {
+      return f->filename;
+    }
+  }
+  return NULL;
+}
+
+MRB_API int32_t
+mrb_debug_get_line(mrb_irep *irep, uint32_t pc)
+{
+  if (irep && pc < irep->ilen) {
+    mrb_irep_debug_info_file* f = NULL;
+    if (!irep->debug_info) {
+      return irep->lines? irep->lines[pc] : -1;
+    }
+    else if ((f = get_file(irep->debug_info, pc))) {
+      switch (f->line_type) {
+        case mrb_debug_line_ary:
+          mrb_assert(f->start_pos <= pc && pc < (f->start_pos + f->line_entry_count));
+          return f->lines.ary[pc - f->start_pos];
+
+        case mrb_debug_line_flat_map: {
+          /* get upper bound */
+          mrb_irep_debug_info_line *ret = f->lines.flat_map;
+          uint32_t count = f->line_entry_count;
+          while (count > 0) {
+            int32_t step = count / 2;
+            mrb_irep_debug_info_line *it = ret + step;
+            if (!(pc < it->start_pos)) {
+              ret = it + 1;
+              count -= step + 1;
+            }
+            else { count = step; }
+          }
+
+          --ret;
+
+          /* check line entry pointer range */
+          mrb_assert(f->lines.flat_map <= ret && ret < (f->lines.flat_map + f->line_entry_count));
+          /* check pc range */
+          mrb_assert(ret->start_pos <= pc &&
+                     pc < (((uint32_t)(ret + 1 - f->lines.flat_map) < f->line_entry_count)
+                           ? (ret+1)->start_pos : irep->debug_info->pc_count));
+
+          return ret->line;
+        }
+      }
+    }
+  }
+  return -1;
+}
+
+MRB_API mrb_irep_debug_info *
+mrb_debug_info_alloc(mrb_state *mrb, mrb_irep *irep)
+{
+  static const mrb_irep_debug_info initial = { 0, 0, NULL };
+  mrb_irep_debug_info *ret;
+
+  mrb_assert(!irep->debug_info);
+  ret = (mrb_irep_debug_info *)mrb_malloc(mrb, sizeof(*ret));
+  *ret = initial;
+  irep->debug_info = ret;
+  return ret;
+}
+
+MRB_API mrb_irep_debug_info_file *
+mrb_debug_info_append_file(mrb_state *mrb, mrb_irep *irep,
+                           uint32_t start_pos, uint32_t end_pos)
+{
+  mrb_irep_debug_info *info;
+  mrb_irep_debug_info_file *ret;
+  uint32_t file_pc_count;
+  size_t fn_len;
+  mrb_int len;
+  uint32_t i;
+
+  if (!irep->debug_info) { return NULL; }
+
+  mrb_assert(irep->filename);
+  mrb_assert(irep->lines);
+
+  info = irep->debug_info;
+
+  if (info->flen > 0 && strcmp(irep->filename, info->files[info->flen - 1]->filename) == 0) {
+    return NULL;
+  }
+
+  ret = (mrb_irep_debug_info_file *)mrb_malloc(mrb, sizeof(*ret));
+  info->files =
+      (mrb_irep_debug_info_file**)(
+          info->files
+          ? mrb_realloc(mrb, info->files, sizeof(mrb_irep_debug_info_file*) * (info->flen + 1))
+          : mrb_malloc(mrb, sizeof(mrb_irep_debug_info_file*)));
+  info->files[info->flen++] = ret;
+
+  file_pc_count = end_pos - start_pos;
+
+  ret->start_pos = start_pos;
+  info->pc_count = end_pos;
+
+  fn_len = strlen(irep->filename);
+  ret->filename_sym = mrb_intern(mrb, irep->filename, fn_len);
+  len = 0;
+  ret->filename = mrb_sym2name_len(mrb, ret->filename_sym, &len);
+
+  ret->line_type = select_line_type(irep->lines + start_pos, end_pos - start_pos);
+  ret->lines.ptr = NULL;
+
+  switch (ret->line_type) {
+    case mrb_debug_line_ary:
+      ret->line_entry_count = file_pc_count;
+      ret->lines.ary = (uint16_t*)mrb_malloc(mrb, sizeof(uint16_t) * file_pc_count);
+      for (i = 0; i < file_pc_count; ++i) {
+        ret->lines.ary[i] = irep->lines[start_pos + i];
+      }
+      break;
+
+    case mrb_debug_line_flat_map: {
+      uint16_t prev_line = 0;
+      mrb_irep_debug_info_line m;
+      ret->lines.flat_map = (mrb_irep_debug_info_line*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info_line) * 1);
+      ret->line_entry_count = 0;
+      for (i = 0; i < file_pc_count; ++i) {
+        if (irep->lines[start_pos + i] == prev_line) { continue; }
+
+        ret->lines.flat_map = (mrb_irep_debug_info_line*)mrb_realloc(
+            mrb, ret->lines.flat_map,
+            sizeof(mrb_irep_debug_info_line) * (ret->line_entry_count + 1));
+        m.start_pos = start_pos + i;
+        m.line = irep->lines[start_pos + i];
+        ret->lines.flat_map[ret->line_entry_count] = m;
+
+        /* update */
+        ++ret->line_entry_count;
+        prev_line = irep->lines[start_pos + i];
+      }
+    } break;
+
+    default: mrb_assert(0); break;
+  }
+
+  return ret;
+}
+
+MRB_API void
+mrb_debug_info_free(mrb_state *mrb, mrb_irep_debug_info *d)
+{
+  uint32_t i;
+
+  if (!d) { return; }
+
+  for (i = 0; i < d->flen; ++i) {
+    mrb_assert(d->files[i]);
+    mrb_free(mrb, d->files[i]->lines.ptr);
+    mrb_free(mrb, d->files[i]);
+  }
+  mrb_free(mrb, d->files);
+  mrb_free(mrb, d);
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/dump.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/dump.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/dump.c	(revision 331)
@@ -0,0 +1,1098 @@
+/*
+** dump.c - mruby binary dumper (mrbc binary format)
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <string.h>
+#include <limits.h>
+#include <mruby/dump.h>
+#include <mruby/string.h>
+#include <mruby/irep.h>
+#include <mruby/numeric.h>
+#include <mruby/debug.h>
+
+#define FLAG_BYTEORDER_NATIVE 2
+#define FLAG_BYTEORDER_NONATIVE 0
+
+#ifdef MRB_USE_FLOAT
+#define MRB_FLOAT_FMT "%.8e"
+#else
+#define MRB_FLOAT_FMT "%.16e"
+#endif
+
+static size_t get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep);
+
+#if UINT32_MAX > SIZE_MAX
+# error This code cannot be built on your environment.
+#endif
+
+static size_t
+write_padding(uint8_t *buf)
+{
+  const size_t align = MRB_DUMP_ALIGNMENT;
+  size_t pad_len = -(intptr_t)buf & (align-1);
+  if (pad_len > 0) {
+    memset(buf, 0, pad_len);
+  }
+  return pad_len;
+}
+
+static size_t
+get_irep_header_size(mrb_state *mrb)
+{
+  size_t size = 0;
+
+  size += sizeof(uint32_t) * 1;
+  size += sizeof(uint16_t) * 3;
+
+  return size;
+}
+
+static ptrdiff_t
+write_irep_header(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
+{
+  uint8_t *cur = buf;
+
+  cur += uint32_to_bin((uint32_t)get_irep_record_size_1(mrb, irep), cur);  /* record size */
+  cur += uint16_to_bin((uint16_t)irep->nlocals, cur);  /* number of local variable */
+  cur += uint16_to_bin((uint16_t)irep->nregs, cur);  /* number of register variable */
+  cur += uint16_to_bin((uint16_t)irep->rlen, cur);  /* number of child irep */
+
+  return cur - buf;
+}
+
+
+static size_t
+get_iseq_block_size(mrb_state *mrb, mrb_irep *irep)
+{
+  size_t size = 0;
+
+  size += sizeof(uint32_t); /* ilen */
+  size += sizeof(uint32_t); /* max padding */
+  size += sizeof(uint32_t) * irep->ilen; /* iseq(n) */
+
+  return size;
+}
+
+static ptrdiff_t
+write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf, uint8_t flags)
+{
+  uint8_t *cur = buf;
+  uint32_t iseq_no;
+
+  cur += uint32_to_bin(irep->ilen, cur); /* number of opcode */
+  cur += write_padding(cur);
+  switch (flags & DUMP_ENDIAN_NAT) {
+  case DUMP_ENDIAN_BIG:
+    if (bigendian_p()) goto native;
+    for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) {
+      cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* opcode */
+    }
+    break;
+  case DUMP_ENDIAN_LIL:
+    if (!bigendian_p()) goto native;
+    for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) {
+      cur += uint32l_to_bin(irep->iseq[iseq_no], cur); /* opcode */
+    }
+    break;
+
+  native:
+  case DUMP_ENDIAN_NAT:
+    memcpy(cur, irep->iseq, irep->ilen * sizeof(mrb_code));
+    cur += irep->ilen * sizeof(mrb_code);
+    break;
+  }
+
+  return cur - buf;
+}
+
+
+static size_t
+get_pool_block_size(mrb_state *mrb, mrb_irep *irep)
+{
+  size_t size = 0;
+  size_t pool_no;
+  mrb_value str;
+
+  size += sizeof(uint32_t); /* plen */
+  size += irep->plen * (sizeof(uint8_t) + sizeof(uint16_t)); /* len(n) */
+
+  for (pool_no = 0; pool_no < irep->plen; pool_no++) {
+    int ai = mrb_gc_arena_save(mrb);
+
+    switch (mrb_type(irep->pool[pool_no])) {
+    case MRB_TT_FIXNUM:
+      str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10);
+      {
+        mrb_int len = RSTRING_LEN(str);
+        mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX);
+        size += (size_t)len;
+      }
+      break;
+
+    case MRB_TT_FLOAT:
+      str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT);
+      {
+        mrb_int len = RSTRING_LEN(str);
+        mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX);
+        size += (size_t)len;
+      }
+      break;
+
+    case MRB_TT_STRING:
+      {
+        mrb_int len = RSTRING_LEN(irep->pool[pool_no]);
+        mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX);
+        size += (size_t)len;
+      }
+      break;
+
+    default:
+      break;
+    }
+    mrb_gc_arena_restore(mrb, ai);
+  }
+
+  return size;
+}
+
+static ptrdiff_t
+write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
+{
+  size_t pool_no;
+  uint8_t *cur = buf;
+  uint16_t len;
+  mrb_value str;
+  const char *char_ptr;
+
+  cur += uint32_to_bin(irep->plen, cur); /* number of pool */
+
+  for (pool_no = 0; pool_no < irep->plen; pool_no++) {
+    int ai = mrb_gc_arena_save(mrb);
+
+    switch (mrb_type(irep->pool[pool_no])) {
+    case MRB_TT_FIXNUM:
+      cur += uint8_to_bin(IREP_TT_FIXNUM, cur); /* data type */
+      str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10);
+      break;
+
+    case MRB_TT_FLOAT:
+      cur += uint8_to_bin(IREP_TT_FLOAT, cur); /* data type */
+      str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT);
+      break;
+
+    case MRB_TT_STRING:
+      cur += uint8_to_bin(IREP_TT_STRING, cur); /* data type */
+      str = irep->pool[pool_no];
+      break;
+
+    default:
+      continue;
+    }
+
+    char_ptr = RSTRING_PTR(str);
+    {
+      mrb_int tlen = RSTRING_LEN(str);
+      mrb_assert_int_fit(mrb_int, tlen, uint16_t, UINT16_MAX);
+      len = (uint16_t)tlen;
+    }
+
+    cur += uint16_to_bin(len, cur); /* data length */
+    memcpy(cur, char_ptr, (size_t)len);
+    cur += len;
+
+    mrb_gc_arena_restore(mrb, ai);
+  }
+
+  return cur - buf;
+}
+
+
+static size_t
+get_syms_block_size(mrb_state *mrb, mrb_irep *irep)
+{
+  size_t size = 0;
+  uint32_t sym_no;
+  mrb_int len;
+
+  size += sizeof(uint32_t); /* slen */
+  for (sym_no = 0; sym_no < irep->slen; sym_no++) {
+    size += sizeof(uint16_t); /* snl(n) */
+    if (irep->syms[sym_no] != 0) {
+      mrb_sym2name_len(mrb, irep->syms[sym_no], &len);
+      size += len + 1; /* sn(n) + null char */
+    }
+  }
+
+  return size;
+}
+
+static ptrdiff_t
+write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
+{
+  uint32_t sym_no;
+  uint8_t *cur = buf;
+  const char *name;
+
+  cur += uint32_to_bin(irep->slen, cur); /* number of symbol */
+
+  for (sym_no = 0; sym_no < irep->slen; sym_no++) {
+    if (irep->syms[sym_no] != 0) {
+      mrb_int len;
+
+      name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len);
+
+      mrb_assert_int_fit(mrb_int, len, uint16_t, UINT16_MAX);
+      cur += uint16_to_bin((uint16_t)len, cur); /* length of symbol name */
+      memcpy(cur, name, len); /* symbol name */
+      cur += (uint16_t)len;
+      *cur++ = '\0';
+    }
+    else {
+      cur += uint16_to_bin(MRB_DUMP_NULL_SYM_LEN, cur); /* length of symbol name */
+    }
+  }
+
+  return cur - buf;
+}
+
+static size_t
+get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep)
+{
+  size_t size = 0;
+
+  size += get_irep_header_size(mrb);
+  size += get_iseq_block_size(mrb, irep);
+  size += get_pool_block_size(mrb, irep);
+  size += get_syms_block_size(mrb, irep);
+  return size;
+}
+
+static size_t
+get_irep_record_size(mrb_state *mrb, mrb_irep *irep)
+{
+  size_t size = 0;
+  size_t irep_no;
+
+  size = get_irep_record_size_1(mrb, irep);
+  for (irep_no = 0; irep_no < irep->rlen; irep_no++) {
+    size += get_irep_record_size(mrb, irep->reps[irep_no]);
+  }
+  return size;
+}
+
+static int
+write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, size_t *irep_record_size, uint8_t flags)
+{
+  uint32_t i;
+  uint8_t *src = bin;
+
+  if (irep == NULL) {
+    return MRB_DUMP_INVALID_IREP;
+  }
+
+  *irep_record_size = get_irep_record_size_1(mrb, irep);
+  if (*irep_record_size == 0) {
+    return MRB_DUMP_GENERAL_FAILURE;
+  }
+
+  bin += write_irep_header(mrb, irep, bin);
+  bin += write_iseq_block(mrb, irep, bin, flags);
+  bin += write_pool_block(mrb, irep, bin);
+  bin += write_syms_block(mrb, irep, bin);
+
+  for (i = 0; i < irep->rlen; i++) {
+    int result;
+    size_t rsize;
+
+    result = write_irep_record(mrb, irep->reps[i], bin, &rsize, flags);
+    if (result != MRB_DUMP_OK) {
+      return result;
+    }
+    bin += rsize;
+  }
+  *irep_record_size = bin - src;
+  return MRB_DUMP_OK;
+}
+
+static uint32_t
+write_footer(mrb_state *mrb, uint8_t *bin)
+{
+  struct rite_binary_footer footer;
+
+  memcpy(footer.section_ident, RITE_BINARY_EOF, sizeof(footer.section_ident));
+  uint32_to_bin(sizeof(struct rite_binary_footer), footer.section_size);
+  memcpy(bin, &footer, sizeof(struct rite_binary_footer));
+
+  return sizeof(struct rite_binary_footer);
+}
+
+
+static int
+write_section_irep_header(mrb_state *mrb, size_t section_size, uint8_t *bin)
+{
+  struct rite_section_irep_header *header = (struct rite_section_irep_header*)bin;
+
+  memcpy(header->section_ident, RITE_SECTION_IREP_IDENT, sizeof(header->section_ident));
+
+  mrb_assert_int_fit(size_t, section_size, uint32_t, UINT32_MAX);
+  uint32_to_bin((uint32_t)section_size, header->section_size);
+  memcpy(header->rite_version, RITE_VM_VER, sizeof(header->rite_version));
+
+  return MRB_DUMP_OK;
+}
+
+static int
+write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, size_t *len_p, uint8_t flags)
+{
+  int result;
+  size_t rsize = 0;
+  uint8_t *cur = bin;
+
+  if (mrb == NULL || bin == NULL) {
+    return MRB_DUMP_INVALID_ARGUMENT;
+  }
+
+  cur += sizeof(struct rite_section_irep_header);
+
+  result = write_irep_record(mrb, irep, cur, &rsize, flags);
+  if (result != MRB_DUMP_OK) {
+    return result;
+  }
+  *len_p = cur - bin + rsize;
+  write_section_irep_header(mrb, *len_p, bin);
+
+  return MRB_DUMP_OK;
+}
+
+static int
+write_section_lineno_header(mrb_state *mrb, size_t section_size, uint8_t *bin)
+{
+  struct rite_section_lineno_header *header = (struct rite_section_lineno_header*)bin;
+
+  memcpy(header->section_ident, RITE_SECTION_LINENO_IDENT, sizeof(header->section_ident));
+  uint32_to_bin((uint32_t)section_size, header->section_size);
+
+  return MRB_DUMP_OK;
+}
+
+static size_t
+get_lineno_record_size(mrb_state *mrb, mrb_irep *irep)
+{
+  size_t size = 0;
+
+  size += sizeof(uint32_t); /* record size */
+  size += sizeof(uint16_t); /* filename size */
+  if (irep->filename) {
+    size += strlen(irep->filename); /* filename */
+  }
+  size += sizeof(uint32_t); /* niseq */
+  if (irep->lines) {
+    size += sizeof(uint16_t) * irep->ilen; /* lineno */
+  }
+
+  return size;
+}
+
+static size_t
+write_lineno_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t* bin)
+{
+  uint8_t *cur = bin;
+  size_t iseq_no;
+  size_t filename_len;
+  ptrdiff_t diff;
+
+  cur += sizeof(uint32_t); /* record size */
+
+  if (irep->filename) {
+    filename_len = strlen(irep->filename);
+  }
+  else {
+    filename_len = 0;
+  }
+  mrb_assert_int_fit(size_t, filename_len, uint16_t, UINT16_MAX);
+  cur += uint16_to_bin((uint16_t)filename_len, cur); /* filename size */
+
+  if (filename_len) {
+    memcpy(cur, irep->filename, filename_len);
+    cur += filename_len; /* filename */
+  }
+
+  if (irep->lines) {
+    mrb_assert_int_fit(size_t, irep->ilen, uint32_t, UINT32_MAX);
+    cur += uint32_to_bin((uint32_t)(irep->ilen), cur); /* niseq */
+    for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) {
+      cur += uint16_to_bin(irep->lines[iseq_no], cur); /* opcode */
+    }
+  }
+  else {
+    cur += uint32_to_bin(0, cur); /* niseq */
+  }
+
+  diff = cur - bin;
+  mrb_assert_int_fit(ptrdiff_t, diff, uint32_t, UINT32_MAX);
+
+  uint32_to_bin((uint32_t)diff, bin); /* record size */
+
+  mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);
+  return (size_t)diff;
+}
+
+static size_t
+write_lineno_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin)
+{
+  size_t i;
+  size_t rlen, size = 0;
+
+  rlen = write_lineno_record_1(mrb, irep, bin);
+  bin += rlen;
+  size += rlen;
+  for (i=0; i<irep->rlen; i++) {
+    rlen = write_lineno_record(mrb, irep, bin);
+    bin += rlen;
+    size += rlen;
+  }
+  return size;
+}
+
+static int
+write_section_lineno(mrb_state *mrb, mrb_irep *irep, uint8_t *bin)
+{
+  size_t section_size = 0;
+  size_t rlen = 0; /* size of irep record */
+  uint8_t *cur = bin;
+
+  if (mrb == NULL || bin == NULL) {
+    return MRB_DUMP_INVALID_ARGUMENT;
+  }
+
+  cur += sizeof(struct rite_section_lineno_header);
+  section_size += sizeof(struct rite_section_lineno_header);
+
+  rlen = write_lineno_record(mrb, irep, cur);
+  section_size += rlen;
+
+  write_section_lineno_header(mrb, section_size, bin);
+
+  return MRB_DUMP_OK;
+}
+
+static size_t
+get_debug_record_size(mrb_state *mrb, mrb_irep *irep)
+{
+  size_t ret = 0;
+  uint16_t f_idx;
+  size_t i;
+
+  ret += sizeof(uint32_t); /* record size */
+  ret += sizeof(uint16_t); /* file count */
+
+  for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) {
+    mrb_irep_debug_info_file const* file = irep->debug_info->files[f_idx];
+
+    ret += sizeof(uint32_t); /* position */
+    ret += sizeof(uint16_t); /* filename index */
+
+    /* lines */
+    ret += sizeof(uint32_t); /* entry count */
+    ret += sizeof(uint8_t); /* line type */
+    switch (file->line_type) {
+      case mrb_debug_line_ary:
+        ret += sizeof(uint16_t) * (size_t)(file->line_entry_count);
+        break;
+
+      case mrb_debug_line_flat_map:
+        ret += (sizeof(uint32_t) + sizeof(uint16_t)) * (size_t)(file->line_entry_count);
+        break;
+
+      default: mrb_assert(0); break;
+    }
+  }
+  for (i=0; i<irep->rlen; i++) {
+    ret += get_debug_record_size(mrb, irep->reps[i]);
+  }
+
+  return ret;
+}
+
+static int
+find_filename_index(const mrb_sym *ary, int ary_len, mrb_sym s)
+{
+  int i;
+
+  for (i = 0; i < ary_len; ++i) {
+    if (ary[i] == s) { return i; }
+  }
+  return -1;
+}
+
+static size_t
+get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, uint16_t *lp)
+{
+  mrb_sym *filenames = *fp;
+  size_t i, size = 0;
+  mrb_irep_debug_info *di = irep->debug_info;
+
+  mrb_assert(lp);
+  for (i = 0; i < di->flen; ++i) {
+    mrb_irep_debug_info_file *file;
+    mrb_int filename_len;
+
+    file = di->files[i];
+    if (find_filename_index(filenames, *lp, file->filename_sym) == -1) {
+      /* register filename */
+      *lp += 1;
+      *fp = filenames = (mrb_sym *)mrb_realloc(mrb, filenames, sizeof(mrb_sym) * (*lp));
+      filenames[*lp - 1] = file->filename_sym;
+
+      /* filename */
+      mrb_sym2name_len(mrb, file->filename_sym, &filename_len);
+      size += sizeof(uint16_t) + (size_t)filename_len;
+    }
+  }
+  for (i=0; i<irep->rlen; i++) {
+    size += get_filename_table_size(mrb, irep->reps[i], fp, lp);
+  }
+  return size;
+}
+
+static size_t
+write_debug_record_1(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, uint16_t filenames_len)
+{
+  uint8_t *cur;
+  uint16_t f_idx;
+  ptrdiff_t ret;
+
+  cur = bin + sizeof(uint32_t); /* skip record size */
+  cur += uint16_to_bin(irep->debug_info->flen, cur); /* file count */
+
+  for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) {
+    int filename_idx;
+    const mrb_irep_debug_info_file *file = irep->debug_info->files[f_idx];
+
+    /* position */
+    cur += uint32_to_bin(file->start_pos, cur);
+
+    /* filename index */
+    filename_idx = find_filename_index(filenames, filenames_len,
+                                                  file->filename_sym);
+    mrb_assert_int_fit(int, filename_idx, uint16_t, UINT16_MAX);
+    cur += uint16_to_bin((uint16_t)filename_idx, cur);
+
+    /* lines */
+    cur += uint32_to_bin(file->line_entry_count, cur);
+    cur += uint8_to_bin(file->line_type, cur);
+    switch (file->line_type) {
+      case mrb_debug_line_ary: {
+        uint32_t l;
+        for (l = 0; l < file->line_entry_count; ++l) {
+          cur += uint16_to_bin(file->lines.ary[l], cur);
+        }
+      } break;
+
+      case mrb_debug_line_flat_map: {
+        uint32_t line;
+        for (line = 0; line < file->line_entry_count; ++line) {
+          cur += uint32_to_bin(file->lines.flat_map[line].start_pos, cur);
+          cur += uint16_to_bin(file->lines.flat_map[line].line, cur);
+        }
+      } break;
+
+      default: mrb_assert(0); break;
+    }
+  }
+
+  ret = cur - bin;
+  mrb_assert_int_fit(ptrdiff_t, ret, uint32_t, UINT32_MAX);
+  uint32_to_bin(ret, bin);
+
+  mrb_assert_int_fit(ptrdiff_t, ret, size_t, SIZE_MAX);
+  return (size_t)ret;
+}
+
+static size_t
+write_debug_record(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, mrb_sym const* filenames, uint16_t filenames_len)
+{
+  size_t size, len;
+  size_t irep_no;
+
+  size = len = write_debug_record_1(mrb, irep, bin, filenames, filenames_len);
+  bin += len;
+  for (irep_no = 0; irep_no < irep->rlen; irep_no++) {
+    len = write_debug_record(mrb, irep->reps[irep_no], bin, filenames, filenames_len);
+    bin += len;
+    size += len;
+  }
+
+  mrb_assert(size == get_debug_record_size(mrb, irep));
+  return size;
+}
+
+static int
+write_section_debug(mrb_state *mrb, mrb_irep *irep, uint8_t *cur, mrb_sym const *filenames, uint16_t filenames_len)
+{
+  size_t section_size = 0;
+  const uint8_t *bin = cur;
+  struct rite_section_debug_header *header;
+  size_t dlen;
+  uint16_t i;
+  char const *sym; mrb_int sym_len;
+
+  if (mrb == NULL || cur == NULL) {
+    return MRB_DUMP_INVALID_ARGUMENT;
+  }
+
+  header = (struct rite_section_debug_header *)bin;
+  cur += sizeof(struct rite_section_debug_header);
+  section_size += sizeof(struct rite_section_debug_header);
+
+  /* filename table */
+  cur += uint16_to_bin(filenames_len, cur);
+  section_size += sizeof(uint16_t);
+  for (i = 0; i < filenames_len; ++i) {
+    sym = mrb_sym2name_len(mrb, filenames[i], &sym_len);
+    mrb_assert(sym);
+    cur += uint16_to_bin(sym_len, cur);
+    memcpy(cur, sym, sym_len);
+    cur += sym_len;
+    section_size += sizeof(uint16_t) + sym_len;
+  }
+
+  /* debug records */
+  dlen = write_debug_record(mrb, irep, cur, filenames, filenames_len);
+  section_size += dlen;
+
+  memcpy(header->section_ident, RITE_SECTION_DEBUG_IDENT, sizeof(header->section_ident));
+  mrb_assert(section_size <= INT32_MAX);
+  uint32_to_bin(section_size, header->section_size);
+
+  return MRB_DUMP_OK;
+}
+
+static void
+create_lv_sym_table(mrb_state *mrb, const mrb_irep *irep, mrb_sym **syms, uint32_t *syms_len)
+{
+  size_t i;
+
+  if (*syms == NULL) {
+    *syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * 1);
+  }
+
+  for (i = 0; i + 1 < irep->nlocals; ++i) {
+    mrb_sym const name = irep->lv[i].name;
+    if (name == 0) continue;
+    if (find_filename_index(*syms, *syms_len, name) != -1) continue;
+
+    ++(*syms_len);
+    *syms = (mrb_sym*)mrb_realloc(mrb, *syms, sizeof(mrb_sym) * (*syms_len));
+    (*syms)[*syms_len - 1] = name;
+  }
+
+  for (i = 0; i < irep->rlen; ++i) {
+    create_lv_sym_table(mrb, irep->reps[i], syms, syms_len);
+  }
+}
+
+static int
+write_lv_sym_table(mrb_state *mrb, uint8_t **start, mrb_sym const *syms, uint32_t syms_len)
+{
+  uint8_t *cur = *start;
+  uint32_t i;
+  const char *str;
+  mrb_int str_len;
+
+  cur += uint32_to_bin(syms_len, cur);
+
+  for (i = 0; i < syms_len; ++i) {
+    str = mrb_sym2name_len(mrb, syms[i], &str_len);
+    cur += uint16_to_bin(str_len, cur);
+    memcpy(cur, str, str_len);
+    cur += str_len;
+  }
+
+  *start = cur;
+
+  return MRB_DUMP_OK;
+}
+
+static int
+write_lv_record(mrb_state *mrb, const mrb_irep *irep, uint8_t **start, mrb_sym const *syms, uint32_t syms_len)
+{
+  uint8_t *cur = *start;
+  size_t i;
+
+  for (i = 0; i + 1 < irep->nlocals; ++i) {
+    if (irep->lv[i].name == 0) {
+      cur += uint16_to_bin(RITE_LV_NULL_MARK, cur);
+      cur += uint16_to_bin(0, cur);
+    }
+    else {
+      int const sym_idx = find_filename_index(syms, syms_len, irep->lv[i].name);
+      mrb_assert(sym_idx != -1); /* local variable name must be in syms */
+
+      cur += uint16_to_bin(sym_idx, cur);
+      cur += uint16_to_bin(irep->lv[i].r, cur);
+    }
+  }
+
+  for (i = 0; i < irep->rlen; ++i) {
+    write_lv_record(mrb, irep->reps[i], &cur, syms, syms_len);
+  }
+
+  *start = cur;
+
+  return MRB_DUMP_OK;
+}
+
+static size_t
+get_lv_record_size(mrb_state *mrb, mrb_irep *irep)
+{
+  size_t ret = 0, i;
+
+  ret += (sizeof(uint16_t) + sizeof(uint16_t)) * (irep->nlocals - 1);
+
+  for (i = 0; i < irep->rlen; ++i) {
+    ret += get_lv_record_size(mrb, irep->reps[i]);
+  }
+
+  return ret;
+}
+
+static size_t
+get_lv_section_size(mrb_state *mrb, mrb_irep *irep, mrb_sym const *syms, uint32_t syms_len)
+{
+  size_t ret = 0, i;
+
+  ret += sizeof(uint32_t); /* syms_len */
+  ret += sizeof(uint16_t) * syms_len; /* symbol name lengths */
+  for (i = 0; i < syms_len; ++i) {
+    mrb_int str_len;
+    mrb_sym2name_len(mrb, syms[i], &str_len);
+    ret += str_len;
+  }
+
+  ret += get_lv_record_size(mrb, irep);
+
+  return ret;
+}
+
+static int
+write_section_lv(mrb_state *mrb, mrb_irep *irep, uint8_t *start, mrb_sym const *syms, uint32_t const syms_len)
+{
+  uint8_t *cur = start;
+  struct rite_section_lv_header *header;
+  ptrdiff_t diff;
+  int result = MRB_DUMP_OK;
+
+  if (mrb == NULL || cur == NULL) {
+    return MRB_DUMP_INVALID_ARGUMENT;
+  }
+
+  header = (struct rite_section_lv_header*)cur;
+  cur += sizeof(struct rite_section_lv_header);
+
+  result = write_lv_sym_table(mrb, &cur, syms, syms_len);
+  if (result != MRB_DUMP_OK) {
+    goto lv_section_exit;
+  }
+
+  result = write_lv_record(mrb, irep, &cur, syms, syms_len);
+  if (result != MRB_DUMP_OK) {
+    goto lv_section_exit;
+  }
+
+  memcpy(header->section_ident, RITE_SECTION_LV_IDENT, sizeof(header->section_ident));
+
+  diff = cur - start;
+  mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);
+  uint32_to_bin(diff, header->section_size);
+
+lv_section_exit:
+  return result;
+}
+
+static int
+write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin, uint8_t flags)
+{
+  struct rite_binary_header *header = (struct rite_binary_header *)bin;
+  uint16_t crc;
+  uint32_t offset;
+
+  switch (flags & DUMP_ENDIAN_NAT) {
+  endian_big:
+  case DUMP_ENDIAN_BIG:
+    memcpy(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident));
+    break;
+  endian_little:
+  case DUMP_ENDIAN_LIL:
+    memcpy(header->binary_ident, RITE_BINARY_IDENT_LIL, sizeof(header->binary_ident));
+    break;
+
+  case DUMP_ENDIAN_NAT:
+    if (bigendian_p()) goto endian_big;
+    goto endian_little;
+    break;
+  }
+
+  memcpy(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version));
+  memcpy(header->compiler_name, RITE_COMPILER_NAME, sizeof(header->compiler_name));
+  memcpy(header->compiler_version, RITE_COMPILER_VERSION, sizeof(header->compiler_version));
+  mrb_assert(binary_size <= UINT32_MAX);
+  uint32_to_bin((uint32_t)binary_size, header->binary_size);
+
+  offset = (&(header->binary_crc[0]) - bin) + sizeof(uint16_t);
+  crc = calc_crc_16_ccitt(bin + offset, binary_size - offset, 0);
+  uint16_to_bin(crc, header->binary_crc);
+
+  return MRB_DUMP_OK;
+}
+
+static mrb_bool
+is_debug_info_defined(mrb_irep *irep)
+{
+  size_t i;
+
+  if (!irep->debug_info) return FALSE;
+  for (i=0; i<irep->rlen; i++) {
+    if (!is_debug_info_defined(irep->reps[i])) return FALSE;
+  }
+  return TRUE;
+}
+
+static mrb_bool
+is_lv_defined(mrb_irep *irep)
+{
+  size_t i;
+
+  if (irep->lv) { return TRUE; }
+
+  for (i = 0; i < irep->rlen; ++i) {
+    if (is_lv_defined(irep->reps[i])) { return TRUE; }
+  }
+
+  return FALSE;
+}
+
+static uint8_t
+dump_flags(uint8_t flags, uint8_t native)
+{
+  if (native == FLAG_BYTEORDER_NATIVE) {
+    if ((flags & DUMP_ENDIAN_NAT) == 0) {
+      return (flags & DUMP_DEBUG_INFO) | DUMP_ENDIAN_NAT;
+    }
+    return flags;
+  }
+  if ((flags & DUMP_ENDIAN_NAT) == 0) {
+    return (flags & DUMP_DEBUG_INFO) | DUMP_ENDIAN_BIG;
+  }
+  return flags;
+}
+
+static int
+dump_irep(mrb_state *mrb, mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size)
+{
+  int result = MRB_DUMP_GENERAL_FAILURE;
+  size_t malloc_size;
+  size_t section_irep_size;
+  size_t section_lineno_size = 0, section_lv_size = 0;
+  uint8_t *cur = NULL;
+  mrb_bool const debug_info_defined = is_debug_info_defined(irep), lv_defined = is_lv_defined(irep);
+  mrb_sym *lv_syms = NULL; uint32_t lv_syms_len = 0;
+  mrb_sym *filenames = NULL; uint16_t filenames_len = 0;
+
+  if (mrb == NULL) {
+    *bin = NULL;
+    return MRB_DUMP_GENERAL_FAILURE;
+  }
+
+  section_irep_size = sizeof(struct rite_section_irep_header);
+  section_irep_size += get_irep_record_size(mrb, irep);
+
+  /* DEBUG section size */
+  if (flags & DUMP_DEBUG_INFO) {
+    if (debug_info_defined) {
+      section_lineno_size += sizeof(struct rite_section_debug_header);
+      /* filename table */
+      filenames = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) + 1);
+
+      /* filename table size */
+      section_lineno_size += sizeof(uint16_t);
+      section_lineno_size += get_filename_table_size(mrb, irep, &filenames, &filenames_len);
+
+      section_lineno_size += get_debug_record_size(mrb, irep);
+    }
+    else {
+      section_lineno_size += sizeof(struct rite_section_lineno_header);
+      section_lineno_size += get_lineno_record_size(mrb, irep);
+    }
+  }
+
+  if (lv_defined) {
+    section_lv_size += sizeof(struct rite_section_lv_header);
+    create_lv_sym_table(mrb, irep, &lv_syms, &lv_syms_len);
+    section_lv_size += get_lv_section_size(mrb, irep, lv_syms, lv_syms_len);
+  }
+
+  malloc_size = sizeof(struct rite_binary_header) +
+                section_irep_size + section_lineno_size + section_lv_size +
+                sizeof(struct rite_binary_footer);
+  cur = *bin = (uint8_t*)mrb_malloc(mrb, malloc_size);
+  cur += sizeof(struct rite_binary_header);
+
+  result = write_section_irep(mrb, irep, cur, &section_irep_size, flags);
+  if (result != MRB_DUMP_OK) {
+    goto error_exit;
+  }
+  cur += section_irep_size;
+  *bin_size = sizeof(struct rite_binary_header) +
+              section_irep_size + section_lineno_size + section_lv_size +
+              sizeof(struct rite_binary_footer);
+
+  /* write DEBUG section */
+  if (flags & DUMP_DEBUG_INFO) {
+    if (debug_info_defined) {
+      result = write_section_debug(mrb, irep, cur, filenames, filenames_len);
+    }
+    else {
+      result = write_section_lineno(mrb, irep, cur);
+    }
+    if (result != MRB_DUMP_OK) {
+      goto error_exit;
+    }
+    cur += section_lineno_size;
+  }
+
+  if (lv_defined) {
+    result = write_section_lv(mrb, irep, cur, lv_syms, lv_syms_len);
+    if (result != MRB_DUMP_OK) {
+      goto error_exit;
+    }
+    cur += section_lv_size;
+  }
+
+  write_footer(mrb, cur);
+  write_rite_binary_header(mrb, *bin_size, *bin, flags);
+
+error_exit:
+  if (result != MRB_DUMP_OK) {
+    mrb_free(mrb, *bin);
+    *bin = NULL;
+  }
+  mrb_free(mrb, lv_syms);
+  mrb_free(mrb, filenames);
+  return result;
+}
+
+int
+mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size)
+{
+  return dump_irep(mrb, irep, dump_flags(flags, FLAG_BYTEORDER_NONATIVE), bin, bin_size);
+}
+
+#ifndef MRB_DISABLE_STDIO
+
+int
+mrb_dump_irep_binary(mrb_state *mrb, mrb_irep *irep, uint8_t flags, FILE* fp)
+{
+  uint8_t *bin = NULL;
+  size_t bin_size = 0;
+  int result;
+
+  if (fp == NULL) {
+    return MRB_DUMP_INVALID_ARGUMENT;
+  }
+
+  result = dump_irep(mrb, irep, dump_flags(flags, FLAG_BYTEORDER_NONATIVE), &bin, &bin_size);
+  if (result == MRB_DUMP_OK) {
+    if (fwrite(bin, sizeof(bin[0]), bin_size, fp) != bin_size) {
+      result = MRB_DUMP_WRITE_FAULT;
+    }
+  }
+
+  mrb_free(mrb, bin);
+  return result;
+}
+
+static mrb_bool
+dump_bigendian_p(uint8_t flags)
+{
+  switch (flags & DUMP_ENDIAN_NAT) {
+  case DUMP_ENDIAN_BIG:
+    return TRUE;
+  case DUMP_ENDIAN_LIL:
+    return FALSE;
+  default:
+  case DUMP_ENDIAN_NAT:
+    return bigendian_p();
+  }
+}
+
+int
+mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep *irep, uint8_t flags, FILE *fp, const char *initname)
+{
+  uint8_t *bin = NULL;
+  size_t bin_size = 0, bin_idx = 0;
+  int result;
+
+  if (fp == NULL || initname == NULL || initname[0] == '\0') {
+    return MRB_DUMP_INVALID_ARGUMENT;
+  }
+  flags = dump_flags(flags, FLAG_BYTEORDER_NATIVE);
+  result = dump_irep(mrb, irep, flags, &bin, &bin_size);
+  if (result == MRB_DUMP_OK) {
+    if (!dump_bigendian_p(flags)) {
+      if (fprintf(fp, "/* dumped in little endian order.\n"
+                  "   use `mrbc -E` option for big endian CPU. */\n") < 0) {
+        mrb_free(mrb, bin);
+        return MRB_DUMP_WRITE_FAULT;
+      }
+    }
+    else {
+      if (fprintf(fp, "/* dumped in big endian order.\n"
+                  "   use `mrbc -e` option for better performance on little endian CPU. */\n") < 0) {
+        mrb_free(mrb, bin);
+        return MRB_DUMP_WRITE_FAULT;
+      }
+    }
+    if (fprintf(fp, "#include <stdint.h>\n") < 0) { /* for uint8_t under at least Darwin */
+      mrb_free(mrb, bin);
+      return MRB_DUMP_WRITE_FAULT;
+    }
+    if (fprintf(fp,
+          "extern const uint8_t %s[];\n"
+          "const uint8_t\n"
+          "#if defined __GNUC__\n"
+          "__attribute__((aligned(%u)))\n"
+          "#elif defined _MSC_VER\n"
+          "__declspec(align(%u))\n"
+          "#endif\n"
+          "%s[] = {",
+          initname,
+          (uint16_t)MRB_DUMP_ALIGNMENT, (uint16_t)MRB_DUMP_ALIGNMENT, initname) < 0) {
+      mrb_free(mrb, bin);
+      return MRB_DUMP_WRITE_FAULT;
+    }
+    while (bin_idx < bin_size) {
+      if (bin_idx % 16 == 0) {
+        if (fputs("\n", fp) == EOF) {
+          mrb_free(mrb, bin);
+          return MRB_DUMP_WRITE_FAULT;
+        }
+      }
+      if (fprintf(fp, "0x%02x,", bin[bin_idx++]) < 0) {
+        mrb_free(mrb, bin);
+        return MRB_DUMP_WRITE_FAULT;
+      }
+    }
+    if (fputs("\n};\n", fp) == EOF) {
+      mrb_free(mrb, bin);
+      return MRB_DUMP_WRITE_FAULT;
+    }
+  }
+
+  mrb_free(mrb, bin);
+  return result;
+}
+
+#endif /* MRB_DISABLE_STDIO */
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/enum.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/enum.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/enum.c	(revision 331)
@@ -0,0 +1,14 @@
+/*
+** enum.c - Enumerable module
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <mruby.h>
+
+void
+mrb_init_enumerable(mrb_state *mrb)
+{
+  mrb_define_module(mrb, "Enumerable");  /* 15.3.2 */
+}
+
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/error.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/error.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/error.c	(revision 331)
@@ -0,0 +1,500 @@
+/*
+** error.c - Exception class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/irep.h>
+#include <mruby/proc.h>
+#include <mruby/string.h>
+#include <mruby/variable.h>
+#include <mruby/debug.h>
+#include <mruby/error.h>
+#include <mruby/class.h>
+#include <mruby/throw.h>
+
+MRB_API mrb_value
+mrb_exc_new(mrb_state *mrb, struct RClass *c, const char *ptr, size_t len)
+{
+  mrb_value arg = mrb_str_new(mrb, ptr, len);
+  return mrb_obj_new(mrb, c, 1, &arg);
+}
+
+MRB_API mrb_value
+mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value str)
+{
+  str = mrb_str_to_str(mrb, str);
+  return mrb_obj_new(mrb, c, 1, &str);
+}
+
+/*
+ * call-seq:
+ *    Exception.new(msg = nil)   ->  exception
+ *
+ *  Construct a new Exception object, optionally passing in
+ *  a message.
+ */
+
+static mrb_value
+exc_initialize(mrb_state *mrb, mrb_value exc)
+{
+  mrb_value mesg;
+  mrb_int argc;
+  mrb_value *argv;
+
+  if (mrb_get_args(mrb, "|o*", &mesg, &argv, &argc) >= 1) {
+    mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "mesg"), mesg);
+  }
+  return exc;
+}
+
+/*
+ *  Document-method: exception
+ *
+ *  call-seq:
+ *     exc.exception(string)  ->  an_exception or exc
+ *
+ *  With no argument, or if the argument is the same as the receiver,
+ *  return the receiver. Otherwise, create a new
+ *  exception object of the same class as the receiver, but with a
+ *  message equal to <code>string</code>.
+ *
+ */
+
+static mrb_value
+exc_exception(mrb_state *mrb, mrb_value self)
+{
+  mrb_value exc;
+  mrb_value a;
+  int argc;
+
+  argc = mrb_get_args(mrb, "|o", &a);
+  if (argc == 0) return self;
+  if (mrb_obj_equal(mrb, self, a)) return self;
+  exc = mrb_obj_clone(mrb, self);
+  mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "mesg"), a);
+
+  return exc;
+}
+
+/*
+ * call-seq:
+ *   exception.to_s   ->  string
+ *
+ * Returns exception's message (or the name of the exception if
+ * no message is set).
+ */
+
+static mrb_value
+exc_to_s(mrb_state *mrb, mrb_value exc)
+{
+  mrb_value mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg"));
+  struct RObject *p;
+
+  if (!mrb_string_p(mesg)) {
+    return mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, exc));
+  }
+  p = mrb_obj_ptr(mesg);
+  if (!p->c) {
+    p->c = mrb->string_class;
+  }
+  return mesg;
+}
+
+/*
+ * call-seq:
+ *   exception.message   ->  string
+ *
+ * Returns the result of invoking <code>exception.to_s</code>.
+ * Normally this returns the exception's message or name.
+ */
+
+static mrb_value
+exc_message(mrb_state *mrb, mrb_value exc)
+{
+  return mrb_funcall(mrb, exc, "to_s", 0);
+}
+
+/*
+ * call-seq:
+ *   exception.inspect   -> string
+ *
+ * Returns this exception's file name, line number,
+ * message and class name.
+ * If file name or line number is not set,
+ * returns message and class name.
+ */
+
+static mrb_value
+exc_inspect(mrb_state *mrb, mrb_value exc)
+{
+  mrb_value str, mesg, file, line;
+  mrb_bool append_mesg;
+  const char *cname;
+
+  mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg"));
+  file = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "file"));
+  line = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "line"));
+
+  append_mesg = !mrb_nil_p(mesg);
+  if (append_mesg) {
+    mesg = mrb_obj_as_string(mrb, mesg);
+    append_mesg = RSTRING_LEN(mesg) > 0;
+  }
+
+  cname = mrb_obj_classname(mrb, exc);
+  str = mrb_str_new_cstr(mrb, cname);
+  if (mrb_string_p(file) && mrb_fixnum_p(line)) {
+    if (append_mesg) {
+      str = mrb_format(mrb, "%S:%S:%S (%S)", file, line, mesg, str);
+    }
+    else {
+      str = mrb_format(mrb, "%S:%S:%S", file, line, str);
+    }
+  }
+  else if (append_mesg) {
+    str = mrb_format(mrb, "%S:%S", str, mesg);
+  }
+  return str;
+}
+
+void mrb_keep_backtrace(mrb_state *mrb, mrb_value exc);
+
+static void
+set_backtrace(mrb_state *mrb, mrb_value exc, mrb_value backtrace)
+{
+  if (!mrb_array_p(backtrace)) {
+  type_err:
+    mrb_raise(mrb, E_TYPE_ERROR, "backtrace must be Array of String");
+  }
+  else {
+    const mrb_value *p = RARRAY_PTR(backtrace);
+    const mrb_value *pend = p + RARRAY_LEN(backtrace);
+
+    while (p < pend) {
+      if (!mrb_string_p(*p)) goto type_err;
+      p++;
+    }
+  }
+  mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "backtrace"), backtrace);
+}
+
+static mrb_value
+exc_set_backtrace(mrb_state *mrb, mrb_value exc)
+{
+  mrb_value backtrace;
+
+  mrb_get_args(mrb, "o", &backtrace);
+  set_backtrace(mrb, exc, backtrace);
+  return backtrace;
+}
+
+static void
+exc_debug_info(mrb_state *mrb, struct RObject *exc)
+{
+  mrb_callinfo *ci = mrb->c->ci;
+  mrb_code *pc = ci->pc;
+
+  while (ci >= mrb->c->cibase) {
+    mrb_code *err = ci->err;
+
+    if (!err && pc) err = pc - 1;
+    if (err && ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) {
+      mrb_irep *irep = ci->proc->body.irep;
+
+      int32_t const line = mrb_debug_get_line(irep, (uint32_t)(err - irep->iseq));
+      char const* file = mrb_debug_get_filename(irep, (uint32_t)(err - irep->iseq));
+      if (line != -1 && file) {
+        mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "file"), mrb_str_new_cstr(mrb, file));
+        mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "line"), mrb_fixnum_value(line));
+        return;
+      }
+    }
+    pc = ci->pc;
+    ci--;
+  }
+}
+
+void
+mrb_exc_set(mrb_state *mrb, mrb_value exc)
+{
+  if (mrb_nil_p(exc)) {
+    mrb->exc = 0;
+  }
+  else {
+    mrb->exc = mrb_obj_ptr(exc);
+    if (!mrb->gc.out_of_memory) {
+      exc_debug_info(mrb, mrb->exc);
+      mrb_keep_backtrace(mrb, exc);
+    }
+  }
+}
+
+MRB_API mrb_noreturn void
+mrb_exc_raise(mrb_state *mrb, mrb_value exc)
+{
+  if (!mrb_obj_is_kind_of(mrb, exc, mrb->eException_class)) {
+    mrb_raise(mrb, E_TYPE_ERROR, "exception object expected");
+  }
+  mrb_exc_set(mrb, exc);
+  if (!mrb->jmp) {
+    mrb_p(mrb, exc);
+    abort();
+  }
+  MRB_THROW(mrb->jmp);
+}
+
+MRB_API mrb_noreturn void
+mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg)
+{
+  mrb_exc_raise(mrb, mrb_exc_new_str(mrb, c, mrb_str_new_cstr(mrb, msg)));
+}
+
+MRB_API mrb_value
+mrb_vformat(mrb_state *mrb, const char *format, va_list ap)
+{
+  const char *p = format;
+  const char *b = p;
+  ptrdiff_t size;
+  mrb_value ary = mrb_ary_new_capa(mrb, 4);
+  int ai = mrb_gc_arena_save(mrb);
+
+  while (*p) {
+    const char c = *p++;
+
+    if (c == '%') {
+      if (*p == 'S') {
+        size = p - b - 1;
+        mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size));
+        mrb_ary_push(mrb, ary, va_arg(ap, mrb_value));
+        b = p + 1;
+      }
+    }
+    else if (c == '\\') {
+      if (*p) {
+        size = p - b - 1;
+        mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size));
+        mrb_ary_push(mrb, ary, mrb_str_new(mrb, p, 1));
+        b = ++p;
+      }
+      else {
+        break;
+      }
+    }
+    mrb_gc_arena_restore(mrb, ai);
+  }
+  if (b == format) {
+    return mrb_str_new_cstr(mrb, format);
+  }
+  else {
+    size = p - b;
+    if (size > 0) {
+      mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size));
+      mrb_gc_arena_restore(mrb, ai);
+    }
+    return mrb_ary_join(mrb, ary, mrb_nil_value());
+  }
+}
+
+MRB_API mrb_value
+mrb_format(mrb_state *mrb, const char *format, ...)
+{
+  va_list ap;
+  mrb_value str;
+
+  va_start(ap, format);
+  str = mrb_vformat(mrb, format, ap);
+  va_end(ap);
+
+  return str;
+}
+
+static mrb_noreturn void
+raise_va(mrb_state *mrb, struct RClass *c, const char *fmt, va_list ap, int argc, mrb_value *argv)
+{
+  mrb_value mesg;
+
+  mesg = mrb_vformat(mrb, fmt, ap);
+  if (argv == NULL) {
+    argv = &mesg;
+  }
+  else {
+    argv[0] = mesg;
+  }
+  mrb_exc_raise(mrb, mrb_obj_new(mrb, c, argc+1, argv));
+}
+
+MRB_API mrb_noreturn void
+mrb_raisef(mrb_state *mrb, struct RClass *c, const char *fmt, ...)
+{
+  va_list args;
+
+  va_start(args, fmt);
+  raise_va(mrb, c, fmt, args, 0, NULL);
+  va_end(args);
+}
+
+MRB_API mrb_noreturn void
+mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...)
+{
+  mrb_value argv[2];
+  va_list args;
+
+  va_start(args, fmt);
+  argv[1] = mrb_symbol_value(id);
+  raise_va(mrb, E_NAME_ERROR, fmt, args, 1, argv);
+  va_end(args);
+}
+
+MRB_API void
+mrb_warn(mrb_state *mrb, const char *fmt, ...)
+{
+#ifndef MRB_DISABLE_STDIO
+  va_list ap;
+  mrb_value str;
+
+  va_start(ap, fmt);
+  str = mrb_vformat(mrb, fmt, ap);
+  fputs("warning: ", stderr);
+  fwrite(RSTRING_PTR(str), RSTRING_LEN(str), 1, stderr);
+  va_end(ap);
+#endif
+}
+
+MRB_API mrb_noreturn void
+mrb_bug(mrb_state *mrb, const char *fmt, ...)
+{
+#ifndef MRB_DISABLE_STDIO
+  va_list ap;
+  mrb_value str;
+
+  va_start(ap, fmt);
+  str = mrb_vformat(mrb, fmt, ap);
+  fputs("bug: ", stderr);
+  fwrite(RSTRING_PTR(str), RSTRING_LEN(str), 1, stderr);
+  va_end(ap);
+#endif
+  exit(EXIT_FAILURE);
+}
+
+MRB_API mrb_value
+mrb_make_exception(mrb_state *mrb, int argc, const mrb_value *argv)
+{
+  mrb_value mesg;
+  int n;
+
+  mesg = mrb_nil_value();
+  switch (argc) {
+    case 0:
+    break;
+    case 1:
+      if (mrb_nil_p(argv[0]))
+        break;
+      if (mrb_string_p(argv[0])) {
+        mesg = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, argv[0]);
+        break;
+      }
+      n = 0;
+      goto exception_call;
+
+    case 2:
+    case 3:
+      n = 1;
+exception_call:
+      {
+        mrb_sym exc = mrb_intern_lit(mrb, "exception");
+        if (mrb_respond_to(mrb, argv[0], exc)) {
+          mesg = mrb_funcall_argv(mrb, argv[0], exc, n, argv+1);
+        }
+        else {
+          /* undef */
+          mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected");
+        }
+      }
+
+      break;
+    default:
+      mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 0..3)", mrb_fixnum_value(argc));
+      break;
+  }
+  if (argc > 0) {
+    if (!mrb_obj_is_kind_of(mrb, mesg, mrb->eException_class))
+      mrb_raise(mrb, mrb->eException_class, "exception object expected");
+    if (argc > 2)
+      set_backtrace(mrb, mesg, argv[2]);
+  }
+
+  return mesg;
+}
+
+MRB_API void
+mrb_sys_fail(mrb_state *mrb, const char *mesg)
+{
+  struct RClass *sce;
+  mrb_int no;
+
+  no = (mrb_int)errno;
+  if (mrb_class_defined(mrb, "SystemCallError")) {
+    sce = mrb_class_get(mrb, "SystemCallError");
+    if (mesg != NULL) {
+      mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 2, mrb_fixnum_value(no), mrb_str_new_cstr(mrb, mesg));
+    }
+    else {
+      mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 1, mrb_fixnum_value(no));
+    }
+  }
+  else {
+    mrb_raise(mrb, E_RUNTIME_ERROR, mesg);
+  }
+}
+
+MRB_API mrb_noreturn void
+mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, char const* fmt, ...)
+{
+  mrb_value exc;
+  mrb_value argv[3];
+  va_list ap;
+
+  va_start(ap, fmt);
+  argv[0] = mrb_vformat(mrb, fmt, ap);
+  argv[1] = mrb_symbol_value(id);
+  argv[2] = args;
+  va_end(ap);
+  exc = mrb_obj_new(mrb, E_NOMETHOD_ERROR, 3, argv);
+  mrb_exc_raise(mrb, exc);
+}
+
+void
+mrb_init_exception(mrb_state *mrb)
+{
+  struct RClass *exception, *script_error, *stack_error, *nomem_error;
+
+  mrb->eException_class = exception = mrb_define_class(mrb, "Exception", mrb->object_class); /* 15.2.22 */
+  MRB_SET_INSTANCE_TT(exception, MRB_TT_EXCEPTION);
+  mrb_define_class_method(mrb, exception, "exception", mrb_instance_new,  MRB_ARGS_ANY());
+  mrb_define_method(mrb, exception, "exception",       exc_exception,     MRB_ARGS_ANY());
+  mrb_define_method(mrb, exception, "initialize",      exc_initialize,    MRB_ARGS_ANY());
+  mrb_define_method(mrb, exception, "to_s",            exc_to_s,          MRB_ARGS_NONE());
+  mrb_define_method(mrb, exception, "message",         exc_message,       MRB_ARGS_NONE());
+  mrb_define_method(mrb, exception, "inspect",         exc_inspect,       MRB_ARGS_NONE());
+  mrb_define_method(mrb, exception, "backtrace",       mrb_exc_backtrace, MRB_ARGS_NONE());
+  mrb_define_method(mrb, exception, "set_backtrace",   exc_set_backtrace, MRB_ARGS_REQ(1));
+
+  mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */
+  mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class);          /* 15.2.28 */
+  script_error = mrb_define_class(mrb, "ScriptError", mrb->eException_class);                /* 15.2.37 */
+  mrb_define_class(mrb, "SyntaxError", script_error);                                        /* 15.2.38 */
+  stack_error = mrb_define_class(mrb, "SystemStackError", exception);
+  mrb->stack_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, stack_error, "stack level too deep"));
+
+  nomem_error = mrb_define_class(mrb, "NoMemoryError", exception);
+  mrb->nomem_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, nomem_error, "Out of memory"));
+#ifdef MRB_GC_FIXED_ARENA
+  mrb->arena_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, nomem_error, "arena overflow error"));
+#endif
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/error.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/error.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/error.h	(revision 331)
@@ -0,0 +1,3 @@
+/* this header file is to be removed soon.
+   added for compatibility purpose (1.0.0) */
+#include <mruby/error.h>
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/etc.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/etc.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/etc.c	(revision 331)
@@ -0,0 +1,232 @@
+/*
+** etc.c -
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <mruby.h>
+#include <mruby/string.h>
+#include <mruby/data.h>
+#include <mruby/class.h>
+#include <mruby/re.h>
+#include <mruby/irep.h>
+
+MRB_API struct RData*
+mrb_data_object_alloc(mrb_state *mrb, struct RClass *klass, void *ptr, const mrb_data_type *type)
+{
+  struct RData *data;
+
+  data = (struct RData*)mrb_obj_alloc(mrb, MRB_TT_DATA, klass);
+  data->data = ptr;
+  data->type = type;
+
+  return data;
+}
+
+MRB_API void
+mrb_data_check_type(mrb_state *mrb, mrb_value obj, const mrb_data_type *type)
+{
+  if (mrb_type(obj) != MRB_TT_DATA) {
+    mrb_check_type(mrb, obj, MRB_TT_DATA);
+  }
+  if (DATA_TYPE(obj) != type) {
+    const mrb_data_type *t2 = DATA_TYPE(obj);
+
+    if (t2) {
+      mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected %S)",
+                 mrb_str_new_cstr(mrb, t2->struct_name), mrb_str_new_cstr(mrb, type->struct_name));
+    }
+    else {
+      struct RClass *c = mrb_class(mrb, obj);
+
+      mrb_raisef(mrb, E_TYPE_ERROR, "uninitialized %S (expected %S)",
+                 mrb_obj_value(c), mrb_str_new_cstr(mrb, type->struct_name));
+    }
+  }
+}
+
+MRB_API void*
+mrb_data_check_get_ptr(mrb_state *mrb, mrb_value obj, const mrb_data_type *type)
+{
+  if (mrb_type(obj) != MRB_TT_DATA) {
+    return NULL;
+  }
+  if (DATA_TYPE(obj) != type) {
+    return NULL;
+  }
+  return DATA_PTR(obj);
+}
+
+MRB_API void*
+mrb_data_get_ptr(mrb_state *mrb, mrb_value obj, const mrb_data_type *type)
+{
+  mrb_data_check_type(mrb, obj, type);
+  return DATA_PTR(obj);
+}
+
+MRB_API mrb_sym
+mrb_obj_to_sym(mrb_state *mrb, mrb_value name)
+{
+  mrb_sym id;
+
+  switch (mrb_type(name)) {
+    default:
+      name = mrb_check_string_type(mrb, name);
+      if (mrb_nil_p(name)) {
+        name = mrb_inspect(mrb, name);
+        mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", name);
+      }
+      /* fall through */
+    case MRB_TT_STRING:
+      name = mrb_str_intern(mrb, name);
+      /* fall through */
+    case MRB_TT_SYMBOL:
+      id = mrb_symbol(name);
+  }
+  return id;
+}
+
+MRB_API mrb_int
+mrb_float_id(mrb_float f)
+{
+  const char *p = (const char*)&f;
+  int len = sizeof(f);
+  mrb_int id = 0;
+
+  while (len--) {
+    id = id*65599 + *p;
+    p++;
+  }
+  id = id + (id>>5);
+
+  return id;
+}
+
+MRB_API mrb_int
+mrb_obj_id(mrb_value obj)
+{
+  mrb_int tt = mrb_type(obj);
+
+#define MakeID2(p,t) (mrb_int)(((intptr_t)(p))^(t))
+#define MakeID(p)    MakeID2(p,tt)
+
+  switch (tt) {
+  case MRB_TT_FREE:
+  case MRB_TT_UNDEF:
+    return MakeID(0); /* not define */
+  case MRB_TT_FALSE:
+    if (mrb_nil_p(obj))
+      return MakeID(1);
+    return MakeID(0);
+  case MRB_TT_TRUE:
+    return MakeID(1);
+  case MRB_TT_SYMBOL:
+    return MakeID(mrb_symbol(obj));
+  case MRB_TT_FIXNUM:
+    return MakeID2(mrb_float_id((mrb_float)mrb_fixnum(obj)), MRB_TT_FLOAT);
+  case MRB_TT_FLOAT:
+    return MakeID(mrb_float_id(mrb_float(obj)));
+  case MRB_TT_STRING:
+  case MRB_TT_OBJECT:
+  case MRB_TT_CLASS:
+  case MRB_TT_MODULE:
+  case MRB_TT_ICLASS:
+  case MRB_TT_SCLASS:
+  case MRB_TT_PROC:
+  case MRB_TT_ARRAY:
+  case MRB_TT_HASH:
+  case MRB_TT_RANGE:
+  case MRB_TT_EXCEPTION:
+  case MRB_TT_FILE:
+  case MRB_TT_DATA:
+  case MRB_TT_ISTRUCT:
+  default:
+    return MakeID(mrb_ptr(obj));
+  }
+}
+
+#ifdef MRB_WORD_BOXING
+MRB_API mrb_value
+mrb_word_boxing_float_value(mrb_state *mrb, mrb_float f)
+{
+  mrb_value v;
+
+  v.value.p = mrb_obj_alloc(mrb, MRB_TT_FLOAT, mrb->float_class);
+  v.value.fp->f = f;
+  return v;
+}
+
+MRB_API mrb_value
+mrb_word_boxing_float_pool(mrb_state *mrb, mrb_float f)
+{
+  struct RFloat *nf = (struct RFloat *)mrb_malloc(mrb, sizeof(struct RFloat));
+  nf->tt = MRB_TT_FLOAT;
+  nf->c = mrb->float_class;
+  nf->f = f;
+  return mrb_obj_value(nf);
+}
+
+MRB_API mrb_value
+mrb_word_boxing_cptr_value(mrb_state *mrb, void *p)
+{
+  mrb_value v;
+
+  v.value.p = mrb_obj_alloc(mrb, MRB_TT_CPTR, mrb->object_class);
+  v.value.vp->p = p;
+  return v;
+}
+#endif  /* MRB_WORD_BOXING */
+
+MRB_API mrb_bool
+mrb_regexp_p(mrb_state *mrb, mrb_value v)
+{
+  if (mrb->flags & MRB_STATE_NO_REGEXP) {
+    return FALSE;
+  }
+  if ((mrb->flags & MRB_STATE_REGEXP) || mrb_class_defined(mrb, REGEXP_CLASS)) {
+    mrb->flags |= MRB_STATE_REGEXP;
+    return mrb_obj_is_kind_of(mrb, v, mrb_class_get(mrb, REGEXP_CLASS));
+  }
+  else {
+    mrb->flags |= MRB_STATE_REGEXP;
+    mrb->flags |= MRB_STATE_NO_REGEXP;
+  }
+  return FALSE;
+}
+
+#if defined _MSC_VER && _MSC_VER < 1900
+
+#ifndef va_copy
+static void
+mrb_msvc_va_copy(va_list *dest, va_list src)
+{
+  *dest = src;
+}
+#define va_copy(dest, src) mrb_msvc_va_copy(&(dest), src)
+#endif
+
+MRB_API int
+mrb_msvc_vsnprintf(char *s, size_t n, const char *format, va_list arg)
+{
+  int cnt;
+  va_list argcp;
+  va_copy(argcp, arg);
+  if (n == 0 || (cnt = _vsnprintf_s(s, n, _TRUNCATE, format, argcp)) < 0) {
+    cnt = _vscprintf(format, arg);
+  }
+  va_end(argcp);
+  return cnt;
+}
+
+MRB_API int
+mrb_msvc_snprintf(char *s, size_t n, const char *format, ...)
+{
+  va_list arg;
+  int ret;
+  va_start(arg, format);
+  ret = mrb_msvc_vsnprintf(s, n, format, arg);
+  va_end(arg);
+  return ret;
+}
+
+#endif  /* defined _MSC_VER && _MSC_VER < 1900 */
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/fmt_fp.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/fmt_fp.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/fmt_fp.c	(revision 331)
@@ -0,0 +1,371 @@
+/*
+
+Most code in this file originates from musl (src/stdio/vfprintf.c)
+which, just like mruby itself, is licensed under the MIT license.
+
+Copyright (c) 2005-2014 Rich Felker, et al.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include <limits.h>
+#include <string.h>
+#include <stdint.h>
+#include <math.h>
+#include <float.h>
+#include <ctype.h>
+
+#include <mruby.h>
+#include <mruby/string.h>
+
+struct fmt_args {
+  mrb_state *mrb;
+  mrb_value str;
+};
+
+#define MAX(a,b) ((a)>(b) ? (a) : (b))
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+
+/* Convenient bit representation for modifier flags, which all fall
+ * within 31 codepoints of the space character. */
+
+#define ALT_FORM   (1U<<('#'-' '))
+#define ZERO_PAD   (1U<<('0'-' '))
+#define LEFT_ADJ   (1U<<('-'-' '))
+#define PAD_POS    (1U<<(' '-' '))
+#define MARK_POS   (1U<<('+'-' '))
+
+static void
+out(struct fmt_args *f, const char *s, size_t l)
+{
+  mrb_str_cat(f->mrb, f->str, s, l);
+}
+
+#define PAD_SIZE 256
+static void
+pad(struct fmt_args *f, char c, int w, int l, int fl)
+{
+  char pad[PAD_SIZE];
+  if (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return;
+  l = w - l;
+  memset(pad, c, l>PAD_SIZE ? PAD_SIZE : l);
+  for (; l >= PAD_SIZE; l -= PAD_SIZE)
+    out(f, pad, PAD_SIZE);
+  out(f, pad, l);
+}
+
+static const char xdigits[16] = {
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+};
+
+static char*
+fmt_u(uint32_t x, char *s)
+{
+  for (; x; x /= 10) *--s = '0' + x % 10;
+  return s;
+}
+
+/* Do not override this check. The floating point printing code below
+ * depends on the float.h constants being right. If they are wrong, it
+ * may overflow the stack. */
+#if LDBL_MANT_DIG == 53
+typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)];
+#endif
+
+static int
+fmt_fp(struct fmt_args *f, long double y, int w, int p, int fl, int t)
+{
+  uint32_t big[(LDBL_MANT_DIG+28)/29 + 1          // mantissa expansion
+    + (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9]; // exponent expansion
+  uint32_t *a, *d, *r, *z;
+  uint32_t i;
+  int e2=0, e, j, l;
+  char buf[9+LDBL_MANT_DIG/4], *s;
+  const char *prefix="-0X+0X 0X-0x+0x 0x";
+  int pl;
+  char ebuf0[3*sizeof(int)], *ebuf=&ebuf0[3*sizeof(int)], *estr;
+
+  pl=1;
+  if (signbit(y)) {
+    y=-y;
+  } else if (fl & MARK_POS) {
+    prefix+=3;
+  } else if (fl & PAD_POS) {
+    prefix+=6;
+  } else prefix++, pl=0;
+
+  if (!isfinite(y)) {
+    const char *ss = (t&32)?"inf":"INF";
+    if (y!=y) ss=(t&32)?"nan":"NAN";
+    pad(f, ' ', w, 3+pl, fl&~ZERO_PAD);
+    out(f, prefix, pl);
+    out(f, ss, 3);
+    pad(f, ' ', w, 3+pl, fl^LEFT_ADJ);
+    return MAX(w, 3+pl);
+  }
+
+  y = frexp((double)y, &e2) * 2;
+  if (y) e2--;
+
+  if ((t|32)=='a') {
+    long double round = 8.0;
+    int re;
+
+    if (t&32) prefix += 9;
+    pl += 2;
+
+    if (p<0 || p>=LDBL_MANT_DIG/4-1) re=0;
+    else re=LDBL_MANT_DIG/4-1-p;
+
+    if (re) {
+      while (re--) round*=16;
+      if (*prefix=='-') {
+        y=-y;
+        y-=round;
+        y+=round;
+        y=-y;
+      }
+      else {
+        y+=round;
+        y-=round;
+      }
+    }
+
+    estr=fmt_u(e2<0 ? -e2 : e2, ebuf);
+    if (estr==ebuf) *--estr='0';
+    *--estr = (e2<0 ? '-' : '+');
+    *--estr = t+('p'-'a');
+
+    s=buf;
+    do {
+      int x=(int)y;
+      *s++=xdigits[x]|(t&32);
+      y=16*(y-x);
+      if (s-buf==1 && (y||p>0||(fl&ALT_FORM))) *s++='.';
+    } while (y);
+
+    if (p && s-buf-2 < p)
+      l = (p+2) + (ebuf-estr);
+    else
+      l = (s-buf) + (ebuf-estr);
+
+    pad(f, ' ', w, pl+l, fl);
+    out(f, prefix, pl);
+    pad(f, '0', w, pl+l, fl^ZERO_PAD);
+    out(f, buf, s-buf);
+    pad(f, '0', l-(ebuf-estr)-(s-buf), 0, 0);
+    out(f, estr, ebuf-estr);
+    pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
+    return MAX(w, pl+l);
+  }
+  if (p<0) p=6;
+
+  if (y) y *= 268435456.0, e2-=28;
+
+  if (e2<0) a=r=z=big;
+  else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1;
+
+  do {
+    *z = (uint32_t)y;
+    y = 1000000000*(y-*z++);
+  } while (y);
+
+  while (e2>0) {
+    uint32_t carry=0;
+    int sh=MIN(29,e2);
+    for (d=z-1; d>=a; d--) {
+      uint64_t x = ((uint64_t)*d<<sh)+carry;
+      *d = x % 1000000000;
+      carry = (uint32_t)(x / 1000000000);
+    }
+    if (carry) *--a = carry;
+    while (z>a && !z[-1]) z--;
+    e2-=sh;
+  }
+  while (e2<0) {
+    uint32_t carry=0, *b;
+    int sh=MIN(9,-e2), need=1+(p+LDBL_MANT_DIG/3+8)/9;
+    for (d=a; d<z; d++) {
+      uint32_t rm = *d & ((1<<sh)-1);
+      *d = (*d>>sh) + carry;
+      carry = (1000000000>>sh) * rm;
+    }
+    if (!*a) a++;
+    if (carry) *z++ = carry;
+    /* Avoid (slow!) computation past requested precision */
+    b = (t|32)=='f' ? r : a;
+    if (z-b > need) z = b+need;
+    e2+=sh;
+  }
+
+  if (a<z) for (i=10, e=9*(r-a); *a>=i; i*=10, e++);
+  else e=0;
+
+  /* Perform rounding: j is precision after the radix (possibly neg) */
+  j = p - ((t|32)!='f')*e - ((t|32)=='g' && p);
+  if (j < 9*(z-r-1)) {
+    uint32_t x;
+    /* We avoid C's broken division of negative numbers */
+    d = r + 1 + ((j+9*LDBL_MAX_EXP)/9 - LDBL_MAX_EXP);
+    j += 9*LDBL_MAX_EXP;
+    j %= 9;
+    for (i=10, j++; j<9; i*=10, j++);
+    x = *d % i;
+    /* Are there any significant digits past j? */
+    if (x || d+1!=z) {
+      long double round = 2/LDBL_EPSILON;
+      long double small;
+      if (*d/i & 1) round += 2;
+      if (x<i/2) small=0.5;
+      else if (x==i/2 && d+1==z) small=1.0;
+      else small=1.5;
+      if (pl && *prefix=='-') round*=-1, small*=-1;
+      *d -= x;
+      /* Decide whether to round by probing round+small */
+      if (round+small != round) {
+        *d = *d + i;
+        while (*d > 999999999) {
+          *d--=0;
+          if (d<a) *--a=0;
+          (*d)++;
+        }
+        for (i=10, e=9*(r-a); *a>=i; i*=10, e++);
+      }
+    }
+    if (z>d+1) z=d+1;
+  }
+  for (; z>a && !z[-1]; z--);
+
+  if ((t|32)=='g') {
+    if (!p) p++;
+    if (p>e && e>=-4) {
+      t--;
+      p-=e+1;
+    }
+    else {
+      t-=2;
+      p--;
+    }
+    if (!(fl&ALT_FORM)) {
+      /* Count trailing zeros in last place */
+      if (z>a && z[-1]) for (i=10, j=0; z[-1]%i==0; i*=10, j++);
+      else j=9;
+      if ((t|32)=='f')
+        p = MIN(p,MAX(0,9*(z-r-1)-j));
+      else
+        p = MIN(p,MAX(0,9*(z-r-1)+e-j));
+    }
+  }
+  l = 1 + p + (p || (fl&ALT_FORM));
+  if ((t|32)=='f') {
+    if (e>0) l+=e;
+  }
+  else {
+    estr=fmt_u(e<0 ? -e : e, ebuf);
+    while(ebuf-estr<2) *--estr='0';
+    *--estr = (e<0 ? '-' : '+');
+    *--estr = t;
+    l += ebuf-estr;
+  }
+
+  pad(f, ' ', w, pl+l, fl);
+  out(f, prefix, pl);
+  pad(f, '0', w, pl+l, fl^ZERO_PAD);
+
+  if ((t|32)=='f') {
+    if (a>r) a=r;
+    for (d=a; d<=r; d++) {
+      char *ss = fmt_u(*d, buf+9);
+      if (d!=a) while (ss>buf) *--ss='0';
+      else if (ss==buf+9) *--ss='0';
+      out(f, ss, buf+9-ss);
+    }
+    if (p || (fl&ALT_FORM)) out(f, ".", 1);
+    for (; d<z && p>0; d++, p-=9) {
+      char *ss = fmt_u(*d, buf+9);
+      while (ss>buf) *--ss='0';
+      out(f, ss, MIN(9,p));
+    }
+    pad(f, '0', p+9, 9, 0);
+  }
+  else {
+    if (z<=a) z=a+1;
+    for (d=a; d<z && p>=0; d++) {
+      char *ss = fmt_u(*d, buf+9);
+      if (ss==buf+9) *--ss='0';
+      if (d!=a) while (ss>buf) *--ss='0';
+      else {
+        out(f, ss++, 1);
+        if (p>0||(fl&ALT_FORM)) out(f, ".", 1);
+      }
+      out(f, ss, MIN(buf+9-ss, p));
+      p -= buf+9-ss;
+    }
+    pad(f, '0', p+18, 18, 0);
+    out(f, estr, ebuf-estr);
+  }
+
+  pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
+
+  return MAX(w, pl+l);
+}
+
+static int
+fmt_core(struct fmt_args *f, const char *fmt, mrb_float flo)
+{
+  int p;
+
+  if (*fmt != '%') {
+    return -1;
+  }
+  ++fmt;
+
+  if (*fmt == '.') {
+    ++fmt;
+    for (p = 0; ISDIGIT(*fmt); ++fmt) {
+      p = 10 * p + (*fmt - '0');
+    }
+  }
+  else {
+    p = -1;
+  }
+
+  switch (*fmt) {
+  case 'e': case 'f': case 'g': case 'a':
+  case 'E': case 'F': case 'G': case 'A':
+    return fmt_fp(f, flo, 0, p, 0, *fmt);
+  default:
+    return -1;
+  }
+}
+
+mrb_value
+mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt)
+{
+  struct fmt_args f;
+
+  f.mrb = mrb;
+  f.str = mrb_str_buf_new(mrb, 24);
+  if (fmt_core(&f, fmt, mrb_float(flo)) < 0) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format string");
+  }
+  return f.str;
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/gc.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/gc.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/gc.c	(revision 331)
@@ -0,0 +1,1842 @@
+/*
+** gc.c - garbage collector for mruby
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <string.h>
+#include <stdlib.h>
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+#include <mruby/hash.h>
+#include <mruby/proc.h>
+#include <mruby/range.h>
+#include <mruby/string.h>
+#include <mruby/variable.h>
+#include <mruby/gc.h>
+#include <mruby/error.h>
+#include <mruby/throw.h>
+
+/*
+  = Tri-color Incremental Garbage Collection
+
+  mruby's GC is Tri-color Incremental GC with Mark & Sweep.
+  Algorithm details are omitted.
+  Instead, the implementation part is described below.
+
+  == Object's Color
+
+  Each object can be painted in three colors:
+
+    * White - Unmarked.
+    * Gray - Marked, But the child objects are unmarked.
+    * Black - Marked, the child objects are also marked.
+
+  == Two White Types
+
+  There're two white color types in a flip-flop fashion: White-A and White-B,
+  which respectively represent the Current White color (the newly allocated
+  objects in the current GC cycle) and the Sweep Target White color (the
+  dead objects to be swept).
+
+  A and B will be switched just at the beginning of the next GC cycle. At
+  that time, all the dead objects have been swept, while the newly created
+  objects in the current GC cycle which finally remains White are now
+  regarded as dead objects. Instead of traversing all the White-A objects and
+  painting them as White-B, just switch the meaning of White-A and White-B as
+  this will be much cheaper.
+
+  As a result, the objects we sweep in the current GC cycle are always
+  left from the previous GC cycle. This allows us to sweep objects
+  incrementally, without the disturbance of the newly created objects.
+
+  == Execution Timing
+
+  GC Execution Time and Each step interval are decided by live objects count.
+  List of Adjustment API:
+
+    * gc_interval_ratio_set
+    * gc_step_ratio_set
+
+  For details, see the comments for each function.
+
+  == Write Barrier
+
+  mruby implementer and C extension library writer must insert a write
+  barrier when updating a reference from a field of an object.
+  When updating a reference from a field of object A to object B,
+  two different types of write barrier are available:
+
+    * mrb_field_write_barrier - target B object for a mark.
+    * mrb_write_barrier       - target A object for a mark.
+
+  == Generational Mode
+
+  mruby's GC offers an Generational Mode while re-using the tri-color GC
+  infrastructure. It will treat the Black objects as Old objects after each
+  sweep phase, instead of painting them White. The key ideas are still the same
+  as traditional generational GC:
+
+    * Minor GC - just traverse the Young objects (Gray objects) in the mark
+                 phase, then only sweep the newly created objects, and leave
+                 the Old objects live.
+
+    * Major GC - same as a full regular GC cycle.
+
+  The difference from "traditional" generational GC is, that the major GC
+  in mruby is triggered incrementally in a tri-color manner.
+
+
+  For details, see the comments for each function.
+
+*/
+
+struct free_obj {
+  MRB_OBJECT_HEADER;
+  struct RBasic *next;
+};
+
+typedef struct {
+  union {
+    struct free_obj free;
+    struct RBasic basic;
+    struct RObject object;
+    struct RClass klass;
+    struct RString string;
+    struct RArray array;
+    struct RHash hash;
+    struct RRange range;
+    struct RData data;
+    struct RProc proc;
+    struct REnv env;
+    struct RException exc;
+    struct RBreak brk;
+#ifdef MRB_WORD_BOXING
+    struct RFloat floatv;
+    struct RCptr cptr;
+#endif
+  } as;
+} RVALUE;
+
+#ifdef GC_PROFILE
+#include <stdio.h>
+#include <sys/time.h>
+
+static double program_invoke_time = 0;
+static double gc_time = 0;
+static double gc_total_time = 0;
+
+static double
+gettimeofday_time(void)
+{
+  struct timeval tv;
+  gettimeofday(&tv, NULL);
+  return tv.tv_sec + tv.tv_usec * 1e-6;
+}
+
+#define GC_INVOKE_TIME_REPORT(with) do {\
+  fprintf(stderr, "%s\n", with);\
+  fprintf(stderr, "gc_invoke: %19.3f\n", gettimeofday_time() - program_invoke_time);\
+  fprintf(stderr, "is_generational: %d\n", is_generational(gc));\
+  fprintf(stderr, "is_major_gc: %d\n", is_major_gc(gc));\
+} while(0)
+
+#define GC_TIME_START do {\
+  gc_time = gettimeofday_time();\
+} while(0)
+
+#define GC_TIME_STOP_AND_REPORT do {\
+  gc_time = gettimeofday_time() - gc_time;\
+  gc_total_time += gc_time;\
+  fprintf(stderr, "gc_state: %d\n", gc->state);\
+  fprintf(stderr, "live: %zu\n", gc->live);\
+  fprintf(stderr, "majorgc_old_threshold: %zu\n", gc->majorgc_old_threshold);\
+  fprintf(stderr, "gc_threshold: %zu\n", gc->threshold);\
+  fprintf(stderr, "gc_time: %30.20f\n", gc_time);\
+  fprintf(stderr, "gc_total_time: %30.20f\n\n", gc_total_time);\
+} while(0)
+#else
+#define GC_INVOKE_TIME_REPORT(s)
+#define GC_TIME_START
+#define GC_TIME_STOP_AND_REPORT
+#endif
+
+#ifdef GC_DEBUG
+#define DEBUG(x) (x)
+#else
+#define DEBUG(x)
+#endif
+
+#ifndef MRB_HEAP_PAGE_SIZE
+#define MRB_HEAP_PAGE_SIZE 1024
+#endif
+
+#define GC_STEP_SIZE 1024
+
+/* white: 011, black: 100, gray: 000 */
+#define GC_GRAY 0
+#define GC_WHITE_A 1
+#define GC_WHITE_B (1 << 1)
+#define GC_BLACK (1 << 2)
+#define GC_WHITES (GC_WHITE_A | GC_WHITE_B)
+#define GC_COLOR_MASK 7
+
+#define paint_gray(o) ((o)->color = GC_GRAY)
+#define paint_black(o) ((o)->color = GC_BLACK)
+#define paint_white(o) ((o)->color = GC_WHITES)
+#define paint_partial_white(s, o) ((o)->color = (s)->current_white_part)
+#define is_gray(o) ((o)->color == GC_GRAY)
+#define is_white(o) ((o)->color & GC_WHITES)
+#define is_black(o) ((o)->color & GC_BLACK)
+#define flip_white_part(s) ((s)->current_white_part = other_white_part(s))
+#define other_white_part(s) ((s)->current_white_part ^ GC_WHITES)
+#define is_dead(s, o) (((o)->color & other_white_part(s) & GC_WHITES) || (o)->tt == MRB_TT_FREE)
+
+#define objects(p) ((RVALUE *)p->objects)
+
+MRB_API void*
+mrb_realloc_simple(mrb_state *mrb, void *p,  size_t len)
+{
+  void *p2;
+
+  p2 = (mrb->allocf)(mrb, p, len, mrb->allocf_ud);
+  if (!p2 && len > 0 && mrb->gc.heaps) {
+    mrb_full_gc(mrb);
+    p2 = (mrb->allocf)(mrb, p, len, mrb->allocf_ud);
+  }
+
+  return p2;
+}
+
+MRB_API void*
+mrb_realloc(mrb_state *mrb, void *p, size_t len)
+{
+  void *p2;
+
+  p2 = mrb_realloc_simple(mrb, p, len);
+  if (len == 0) return p2;
+  if (p2 == NULL) {
+    if (mrb->gc.out_of_memory) {
+      mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err));
+      /* mrb_panic(mrb); */
+    }
+    else {
+      mrb->gc.out_of_memory = TRUE;
+      mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err));
+    }
+  }
+  else {
+    mrb->gc.out_of_memory = FALSE;
+  }
+
+  return p2;
+}
+
+MRB_API void*
+mrb_malloc(mrb_state *mrb, size_t len)
+{
+  return mrb_realloc(mrb, 0, len);
+}
+
+MRB_API void*
+mrb_malloc_simple(mrb_state *mrb, size_t len)
+{
+  return mrb_realloc_simple(mrb, 0, len);
+}
+
+MRB_API void*
+mrb_calloc(mrb_state *mrb, size_t nelem, size_t len)
+{
+  void *p;
+
+  if (nelem > 0 && len > 0 &&
+      nelem <= SIZE_MAX / len) {
+    size_t size;
+    size = nelem * len;
+    p = mrb_malloc(mrb, size);
+
+    memset(p, 0, size);
+  }
+  else {
+    p = NULL;
+  }
+
+  return p;
+}
+
+MRB_API void
+mrb_free(mrb_state *mrb, void *p)
+{
+  (mrb->allocf)(mrb, p, 0, mrb->allocf_ud);
+}
+
+MRB_API mrb_bool
+mrb_object_dead_p(mrb_state *mrb, struct RBasic *object) {
+  return is_dead(&mrb->gc, object);
+}
+
+static void
+link_heap_page(mrb_gc *gc, mrb_heap_page *page)
+{
+  page->next = gc->heaps;
+  if (gc->heaps)
+    gc->heaps->prev = page;
+  gc->heaps = page;
+}
+
+static void
+unlink_heap_page(mrb_gc *gc, mrb_heap_page *page)
+{
+  if (page->prev)
+    page->prev->next = page->next;
+  if (page->next)
+    page->next->prev = page->prev;
+  if (gc->heaps == page)
+    gc->heaps = page->next;
+  page->prev = NULL;
+  page->next = NULL;
+}
+
+static void
+link_free_heap_page(mrb_gc *gc, mrb_heap_page *page)
+{
+  page->free_next = gc->free_heaps;
+  if (gc->free_heaps) {
+    gc->free_heaps->free_prev = page;
+  }
+  gc->free_heaps = page;
+}
+
+static void
+unlink_free_heap_page(mrb_gc *gc, mrb_heap_page *page)
+{
+  if (page->free_prev)
+    page->free_prev->free_next = page->free_next;
+  if (page->free_next)
+    page->free_next->free_prev = page->free_prev;
+  if (gc->free_heaps == page)
+    gc->free_heaps = page->free_next;
+  page->free_prev = NULL;
+  page->free_next = NULL;
+}
+
+static void
+add_heap(mrb_state *mrb, mrb_gc *gc)
+{
+  mrb_heap_page *page = (mrb_heap_page *)mrb_calloc(mrb, 1, sizeof(mrb_heap_page) + MRB_HEAP_PAGE_SIZE * sizeof(RVALUE));
+  RVALUE *p, *e;
+  struct RBasic *prev = NULL;
+
+  for (p = objects(page), e=p+MRB_HEAP_PAGE_SIZE; p<e; p++) {
+    p->as.free.tt = MRB_TT_FREE;
+    p->as.free.next = prev;
+    prev = &p->as.basic;
+  }
+  page->freelist = prev;
+
+  link_heap_page(gc, page);
+  link_free_heap_page(gc, page);
+}
+
+#define DEFAULT_GC_INTERVAL_RATIO 200
+#define DEFAULT_GC_STEP_RATIO 200
+#define DEFAULT_MAJOR_GC_INC_RATIO 200
+#define is_generational(gc) ((gc)->generational)
+#define is_major_gc(gc) (is_generational(gc) && (gc)->full)
+#define is_minor_gc(gc) (is_generational(gc) && !(gc)->full)
+
+void
+mrb_gc_init(mrb_state *mrb, mrb_gc *gc)
+{
+#ifndef MRB_GC_FIXED_ARENA
+  gc->arena = (struct RBasic**)mrb_malloc(mrb, sizeof(struct RBasic*)*MRB_GC_ARENA_SIZE);
+  gc->arena_capa = MRB_GC_ARENA_SIZE;
+#endif
+
+  gc->current_white_part = GC_WHITE_A;
+  gc->heaps = NULL;
+  gc->free_heaps = NULL;
+  add_heap(mrb, gc);
+  gc->interval_ratio = DEFAULT_GC_INTERVAL_RATIO;
+  gc->step_ratio = DEFAULT_GC_STEP_RATIO;
+#ifndef MRB_GC_TURN_OFF_GENERATIONAL
+  gc->generational = TRUE;
+  gc->full = TRUE;
+#endif
+
+#ifdef GC_PROFILE
+  program_invoke_time = gettimeofday_time();
+#endif
+}
+
+static void obj_free(mrb_state *mrb, struct RBasic *obj, int end);
+
+void
+free_heap(mrb_state *mrb, mrb_gc *gc)
+{
+  mrb_heap_page *page = gc->heaps;
+  mrb_heap_page *tmp;
+  RVALUE *p, *e;
+
+  while (page) {
+    tmp = page;
+    page = page->next;
+    for (p = objects(tmp), e=p+MRB_HEAP_PAGE_SIZE; p<e; p++) {
+      if (p->as.free.tt != MRB_TT_FREE)
+        obj_free(mrb, &p->as.basic, TRUE);
+    }
+    mrb_free(mrb, tmp);
+  }
+}
+
+void
+mrb_gc_destroy(mrb_state *mrb, mrb_gc *gc)
+{
+  free_heap(mrb, gc);
+#ifndef MRB_GC_FIXED_ARENA
+  mrb_free(mrb, gc->arena);
+#endif
+}
+
+static void
+gc_protect(mrb_state *mrb, mrb_gc *gc, struct RBasic *p)
+{
+#ifdef MRB_GC_FIXED_ARENA
+  if (gc->arena_idx >= MRB_GC_ARENA_SIZE) {
+    /* arena overflow error */
+    gc->arena_idx = MRB_GC_ARENA_SIZE - 4; /* force room in arena */
+    mrb_exc_raise(mrb, mrb_obj_value(mrb->arena_err));
+  }
+#else
+  if (gc->arena_idx >= gc->arena_capa) {
+    /* extend arena */
+    gc->arena_capa = (int)(gc->arena_capa * 1.5);
+    gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*gc->arena_capa);
+  }
+#endif
+  gc->arena[gc->arena_idx++] = p;
+}
+
+/* mrb_gc_protect() leaves the object in the arena */
+MRB_API void
+mrb_gc_protect(mrb_state *mrb, mrb_value obj)
+{
+  if (mrb_immediate_p(obj)) return;
+  gc_protect(mrb, &mrb->gc, mrb_basic_ptr(obj));
+}
+
+#define GC_ROOT_NAME "_gc_root_"
+
+/* mrb_gc_register() keeps the object from GC.
+
+   Register your object when it's exported to C world,
+   without reference from Ruby world, e.g. callback
+   arguments.  Don't forget to remove the object using
+   mrb_gc_unregister, otherwise your object will leak.
+*/
+
+MRB_API void
+mrb_gc_register(mrb_state *mrb, mrb_value obj)
+{
+  mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME);
+  mrb_value table = mrb_gv_get(mrb, root);
+
+  if (mrb_nil_p(table) || mrb_type(table) != MRB_TT_ARRAY) {
+    table = mrb_ary_new(mrb);
+    mrb_gv_set(mrb, root, table);
+  }
+  mrb_ary_push(mrb, table, obj);
+}
+
+/* mrb_gc_unregister() removes the object from GC root. */
+MRB_API void
+mrb_gc_unregister(mrb_state *mrb, mrb_value obj)
+{
+  mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME);
+  mrb_value table = mrb_gv_get(mrb, root);
+  struct RArray *a;
+  mrb_int i;
+
+  if (mrb_nil_p(table)) return;
+  if (mrb_type(table) != MRB_TT_ARRAY) {
+    mrb_gv_set(mrb, root, mrb_nil_value());
+    return;
+  }
+  a = mrb_ary_ptr(table);
+  mrb_ary_modify(mrb, a);
+  for (i = 0; i < a->len; i++) {
+    if (mrb_obj_eq(mrb, a->ptr[i], obj)) {
+      a->len--;
+      memmove(&a->ptr[i], &a->ptr[i + 1], (a->len - i) * sizeof(a->ptr[i]));
+      break;
+    }
+  }
+}
+
+MRB_API struct RBasic*
+mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls)
+{
+  struct RBasic *p;
+  static const RVALUE RVALUE_zero = { { { MRB_TT_FALSE } } };
+  mrb_gc *gc = &mrb->gc;
+
+  if (cls) {
+    enum mrb_vtype tt;
+
+    switch (cls->tt) {
+    case MRB_TT_CLASS:
+    case MRB_TT_SCLASS:
+    case MRB_TT_MODULE:
+    case MRB_TT_ENV:
+      break;
+    default:
+      mrb_raise(mrb, E_TYPE_ERROR, "allocation failure");
+    }
+    tt = MRB_INSTANCE_TT(cls);
+    if (tt != MRB_TT_FALSE &&
+        ttype != MRB_TT_SCLASS &&
+        ttype != MRB_TT_ICLASS &&
+        ttype != MRB_TT_ENV &&
+        ttype != tt) {
+      mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %S", mrb_obj_value(cls));
+    }
+  }
+
+#ifdef MRB_GC_STRESS
+  mrb_full_gc(mrb);
+#endif
+  if (gc->threshold < gc->live) {
+    mrb_incremental_gc(mrb);
+  }
+  if (gc->free_heaps == NULL) {
+    add_heap(mrb, gc);
+  }
+
+  p = gc->free_heaps->freelist;
+  gc->free_heaps->freelist = ((struct free_obj*)p)->next;
+  if (gc->free_heaps->freelist == NULL) {
+    unlink_free_heap_page(gc, gc->free_heaps);
+  }
+
+  gc->live++;
+  gc_protect(mrb, gc, p);
+  *(RVALUE *)p = RVALUE_zero;
+  p->tt = ttype;
+  p->c = cls;
+  paint_partial_white(gc, p);
+  return p;
+}
+
+static inline void
+add_gray_list(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
+{
+#ifdef MRB_GC_STRESS
+  if (obj->tt > MRB_TT_MAXDEFINE) {
+    abort();
+  }
+#endif
+  paint_gray(obj);
+  obj->gcnext = gc->gray_list;
+  gc->gray_list = obj;
+}
+
+static void
+mark_context_stack(mrb_state *mrb, struct mrb_context *c)
+{
+  size_t i;
+  size_t e;
+  mrb_value nil;
+  int nregs;
+
+  if (c->stack == NULL) return;
+  e = c->stack - c->stbase;
+  if (c->ci) {
+    nregs = c->ci->argc + 2;
+    if (c->ci->nregs > nregs)
+      nregs = c->ci->nregs;
+    e += nregs;
+  }
+  if (c->stbase + e > c->stend) e = c->stend - c->stbase;
+  for (i=0; i<e; i++) {
+    mrb_value v = c->stbase[i];
+
+    if (!mrb_immediate_p(v)) {
+      mrb_gc_mark(mrb, mrb_basic_ptr(v));
+    }
+  }
+  e = c->stend - c->stbase;
+  nil = mrb_nil_value();
+  for (; i<e; i++) {
+    c->stbase[i] = nil;
+  }
+}
+
+static void
+mark_context(mrb_state *mrb, struct mrb_context *c)
+{
+  int i;
+  mrb_callinfo *ci;
+
+  /* mark VM stack */
+  mark_context_stack(mrb, c);
+
+  /* mark call stack */
+  if (c->cibase) {
+    for (ci = c->cibase; ci <= c->ci; ci++) {
+      mrb_gc_mark(mrb, (struct RBasic*)ci->env);
+      mrb_gc_mark(mrb, (struct RBasic*)ci->proc);
+      mrb_gc_mark(mrb, (struct RBasic*)ci->target_class);
+    }
+  }
+  /* mark ensure stack */
+  for (i=0; i<c->esize; i++) {
+    if (c->ensure[i] == NULL) break;
+    mrb_gc_mark(mrb, (struct RBasic*)c->ensure[i]);
+  }
+  /* mark fibers */
+  mrb_gc_mark(mrb, (struct RBasic*)c->fib);
+  if (c->prev) {
+    mark_context(mrb, c->prev);
+  }
+}
+
+static void
+gc_mark_children(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
+{
+  mrb_assert(is_gray(obj));
+  paint_black(obj);
+  gc->gray_list = obj->gcnext;
+  mrb_gc_mark(mrb, (struct RBasic*)obj->c);
+  switch (obj->tt) {
+  case MRB_TT_ICLASS:
+    {
+      struct RClass *c = (struct RClass*)obj;
+      if (MRB_FLAG_TEST(c, MRB_FLAG_IS_ORIGIN))
+        mrb_gc_mark_mt(mrb, c);
+      mrb_gc_mark(mrb, (struct RBasic*)((struct RClass*)obj)->super);
+    }
+    break;
+
+  case MRB_TT_CLASS:
+  case MRB_TT_MODULE:
+  case MRB_TT_SCLASS:
+    {
+      struct RClass *c = (struct RClass*)obj;
+
+      mrb_gc_mark_mt(mrb, c);
+      mrb_gc_mark(mrb, (struct RBasic*)c->super);
+    }
+    /* fall through */
+
+  case MRB_TT_OBJECT:
+  case MRB_TT_DATA:
+  case MRB_TT_EXCEPTION:
+    mrb_gc_mark_iv(mrb, (struct RObject*)obj);
+    break;
+
+  case MRB_TT_PROC:
+    {
+      struct RProc *p = (struct RProc*)obj;
+
+      mrb_gc_mark(mrb, (struct RBasic*)p->env);
+      mrb_gc_mark(mrb, (struct RBasic*)p->target_class);
+    }
+    break;
+
+  case MRB_TT_ENV:
+    {
+      struct REnv *e = (struct REnv*)obj;
+      mrb_int i, len;
+
+      if (MRB_ENV_STACK_SHARED_P(e)) {
+        if (e->cxt.c->fib) {
+          mrb_gc_mark(mrb, (struct RBasic*)e->cxt.c->fib);
+        }
+        break;
+      }
+      len = MRB_ENV_STACK_LEN(e);
+      for (i=0; i<len; i++) {
+        mrb_gc_mark_value(mrb, e->stack[i]);
+      }
+    }
+    break;
+
+  case MRB_TT_FIBER:
+    {
+      struct mrb_context *c = ((struct RFiber*)obj)->cxt;
+
+      if (c) mark_context(mrb, c);
+    }
+    break;
+
+  case MRB_TT_ARRAY:
+    {
+      struct RArray *a = (struct RArray*)obj;
+      size_t i, e;
+
+      for (i=0,e=a->len; i<e; i++) {
+        mrb_gc_mark_value(mrb, a->ptr[i]);
+      }
+    }
+    break;
+
+  case MRB_TT_HASH:
+    mrb_gc_mark_iv(mrb, (struct RObject*)obj);
+    mrb_gc_mark_hash(mrb, (struct RHash*)obj);
+    break;
+
+  case MRB_TT_STRING:
+    break;
+
+  case MRB_TT_RANGE:
+    {
+      struct RRange *r = (struct RRange*)obj;
+
+      if (r->edges) {
+        mrb_gc_mark_value(mrb, r->edges->beg);
+        mrb_gc_mark_value(mrb, r->edges->end);
+      }
+    }
+    break;
+
+  default:
+    break;
+  }
+}
+
+MRB_API void
+mrb_gc_mark(mrb_state *mrb, struct RBasic *obj)
+{
+  if (obj == 0) return;
+  if (!is_white(obj)) return;
+  mrb_assert((obj)->tt != MRB_TT_FREE);
+  add_gray_list(mrb, &mrb->gc, obj);
+}
+
+static void
+obj_free(mrb_state *mrb, struct RBasic *obj, int end)
+{
+  DEBUG(fprintf(stderr, "obj_free(%p,tt=%d)\n",obj,obj->tt));
+  switch (obj->tt) {
+    /* immediate - no mark */
+  case MRB_TT_TRUE:
+  case MRB_TT_FIXNUM:
+  case MRB_TT_SYMBOL:
+    /* cannot happen */
+    return;
+
+  case MRB_TT_FLOAT:
+#ifdef MRB_WORD_BOXING
+    break;
+#else
+    return;
+#endif
+
+  case MRB_TT_OBJECT:
+    mrb_gc_free_iv(mrb, (struct RObject*)obj);
+    break;
+
+  case MRB_TT_EXCEPTION:
+    mrb_gc_free_iv(mrb, (struct RObject*)obj);
+    break;
+
+  case MRB_TT_CLASS:
+  case MRB_TT_MODULE:
+  case MRB_TT_SCLASS:
+    mrb_gc_free_mt(mrb, (struct RClass*)obj);
+    mrb_gc_free_iv(mrb, (struct RObject*)obj);
+    break;
+  case MRB_TT_ICLASS:
+    if (MRB_FLAG_TEST(obj, MRB_FLAG_IS_ORIGIN))
+      mrb_gc_free_mt(mrb, (struct RClass*)obj);
+    break;
+  case MRB_TT_ENV:
+    {
+      struct REnv *e = (struct REnv*)obj;
+
+      if (MRB_ENV_STACK_SHARED_P(e)) {
+        /* cannot be freed */
+        return;
+      }
+      mrb_free(mrb, e->stack);
+      e->stack = NULL;
+    }
+    break;
+
+  case MRB_TT_FIBER:
+    {
+      struct mrb_context *c = ((struct RFiber*)obj)->cxt;
+
+      if (!end && c && c != mrb->root_c) {
+        mrb_callinfo *ci = c->ci;
+        mrb_callinfo *ce = c->cibase;
+
+        while (ce <= ci) {
+          struct REnv *e = ci->env;
+          if (e && !is_dead(&mrb->gc, e) &&
+              e->tt == MRB_TT_ENV && MRB_ENV_STACK_SHARED_P(e)) {
+            mrb_env_unshare(mrb, e);
+          }
+          ci--;
+        }
+        mrb_free_context(mrb, c);
+      }
+    }
+    break;
+
+  case MRB_TT_ARRAY:
+    if (ARY_SHARED_P(obj))
+      mrb_ary_decref(mrb, ((struct RArray*)obj)->aux.shared);
+    else
+      mrb_free(mrb, ((struct RArray*)obj)->ptr);
+    break;
+
+  case MRB_TT_HASH:
+    mrb_gc_free_iv(mrb, (struct RObject*)obj);
+    mrb_gc_free_hash(mrb, (struct RHash*)obj);
+    break;
+
+  case MRB_TT_STRING:
+    mrb_gc_free_str(mrb, (struct RString*)obj);
+    break;
+
+  case MRB_TT_PROC:
+    {
+      struct RProc *p = (struct RProc*)obj;
+
+      if (!MRB_PROC_CFUNC_P(p) && p->body.irep) {
+        mrb_irep_decref(mrb, p->body.irep);
+      }
+    }
+    break;
+
+  case MRB_TT_RANGE:
+    mrb_free(mrb, ((struct RRange*)obj)->edges);
+    break;
+
+  case MRB_TT_DATA:
+    {
+      struct RData *d = (struct RData*)obj;
+      if (d->type && d->type->dfree) {
+        d->type->dfree(mrb, d->data);
+      }
+      mrb_gc_free_iv(mrb, (struct RObject*)obj);
+    }
+    break;
+
+  default:
+    break;
+  }
+  obj->tt = MRB_TT_FREE;
+}
+
+static void
+root_scan_phase(mrb_state *mrb, mrb_gc *gc)
+{
+  int i, e;
+
+  if (!is_minor_gc(gc)) {
+    gc->gray_list = NULL;
+    gc->atomic_gray_list = NULL;
+  }
+
+  mrb_gc_mark_gv(mrb);
+  /* mark arena */
+  for (i=0,e=gc->arena_idx; i<e; i++) {
+    mrb_gc_mark(mrb, gc->arena[i]);
+  }
+  /* mark class hierarchy */
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->object_class);
+
+  /* mark built-in classes */
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->class_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->module_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->proc_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->string_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->array_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->hash_class);
+
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->float_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->fixnum_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->true_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->false_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->nil_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->symbol_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->kernel_module);
+
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->eException_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->eStandardError_class);
+
+  /* mark top_self */
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->top_self);
+  /* mark exception */
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->exc);
+  /* mark pre-allocated exception */
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->nomem_err);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->stack_err);
+#ifdef MRB_GC_FIXED_ARENA
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->arena_err);
+#endif
+
+  mark_context(mrb, mrb->c);
+  if (mrb->root_c != mrb->c) {
+    mark_context(mrb, mrb->root_c);
+  }
+}
+
+static size_t
+gc_gray_mark(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
+{
+  size_t children = 0;
+
+  gc_mark_children(mrb, gc, obj);
+
+  switch (obj->tt) {
+  case MRB_TT_ICLASS:
+    children++;
+    break;
+
+  case MRB_TT_CLASS:
+  case MRB_TT_SCLASS:
+  case MRB_TT_MODULE:
+    {
+      struct RClass *c = (struct RClass*)obj;
+
+      children += mrb_gc_mark_iv_size(mrb, (struct RObject*)obj);
+      children += mrb_gc_mark_mt_size(mrb, c);
+      children++;
+    }
+    break;
+
+  case MRB_TT_OBJECT:
+  case MRB_TT_DATA:
+  case MRB_TT_EXCEPTION:
+    children += mrb_gc_mark_iv_size(mrb, (struct RObject*)obj);
+    break;
+
+  case MRB_TT_ENV:
+    children += (int)obj->flags;
+    break;
+
+  case MRB_TT_FIBER:
+    {
+      struct mrb_context *c = ((struct RFiber*)obj)->cxt;
+      size_t i;
+      mrb_callinfo *ci;
+
+      if (!c) break;
+      /* mark stack */
+      i = c->stack - c->stbase;
+      if (c->ci) i += c->ci->nregs;
+      if (c->stbase + i > c->stend) i = c->stend - c->stbase;
+      children += i;
+
+      /* mark ensure stack */
+      children += c->eidx;
+
+      /* mark closure */
+      if (c->cibase) {
+        for (i=0, ci = c->cibase; ci <= c->ci; i++, ci++)
+          ;
+      }
+      children += i;
+    }
+    break;
+
+  case MRB_TT_ARRAY:
+    {
+      struct RArray *a = (struct RArray*)obj;
+      children += a->len;
+    }
+    break;
+
+  case MRB_TT_HASH:
+    children += mrb_gc_mark_iv_size(mrb, (struct RObject*)obj);
+    children += mrb_gc_mark_hash_size(mrb, (struct RHash*)obj);
+    break;
+
+  case MRB_TT_PROC:
+  case MRB_TT_RANGE:
+    children+=2;
+    break;
+
+  default:
+    break;
+  }
+  return children;
+}
+
+
+static void
+gc_mark_gray_list(mrb_state *mrb, mrb_gc *gc) {
+  while (gc->gray_list) {
+    if (is_gray(gc->gray_list))
+      gc_mark_children(mrb, gc, gc->gray_list);
+    else
+      gc->gray_list = gc->gray_list->gcnext;
+  }
+}
+
+
+static size_t
+incremental_marking_phase(mrb_state *mrb, mrb_gc *gc, size_t limit)
+{
+  size_t tried_marks = 0;
+
+  while (gc->gray_list && tried_marks < limit) {
+    tried_marks += gc_gray_mark(mrb, gc, gc->gray_list);
+  }
+
+  return tried_marks;
+}
+
+static void
+final_marking_phase(mrb_state *mrb, mrb_gc *gc)
+{
+  int i, e;
+
+  /* mark arena */
+  for (i=0,e=gc->arena_idx; i<e; i++) {
+    mrb_gc_mark(mrb, gc->arena[i]);
+  }
+  mrb_gc_mark_gv(mrb);
+  mark_context(mrb, mrb->c);
+  mark_context(mrb, mrb->root_c);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->exc);
+  gc_mark_gray_list(mrb, gc);
+  mrb_assert(gc->gray_list == NULL);
+  gc->gray_list = gc->atomic_gray_list;
+  gc->atomic_gray_list = NULL;
+  gc_mark_gray_list(mrb, gc);
+  mrb_assert(gc->gray_list == NULL);
+}
+
+static void
+prepare_incremental_sweep(mrb_state *mrb, mrb_gc *gc)
+{
+  gc->state = MRB_GC_STATE_SWEEP;
+  gc->sweeps = gc->heaps;
+  gc->live_after_mark = gc->live;
+}
+
+static size_t
+incremental_sweep_phase(mrb_state *mrb, mrb_gc *gc, size_t limit)
+{
+  mrb_heap_page *page = gc->sweeps;
+  size_t tried_sweep = 0;
+
+  while (page && (tried_sweep < limit)) {
+    RVALUE *p = objects(page);
+    RVALUE *e = p + MRB_HEAP_PAGE_SIZE;
+    size_t freed = 0;
+    mrb_bool dead_slot = TRUE;
+    mrb_bool full = (page->freelist == NULL);
+
+    if (is_minor_gc(gc) && page->old) {
+      /* skip a slot which doesn't contain any young object */
+      p = e;
+      dead_slot = FALSE;
+    }
+    while (p<e) {
+      if (is_dead(gc, &p->as.basic)) {
+        if (p->as.basic.tt != MRB_TT_FREE) {
+          obj_free(mrb, &p->as.basic, FALSE);
+          if (p->as.basic.tt == MRB_TT_FREE) {
+            p->as.free.next = page->freelist;
+            page->freelist = (struct RBasic*)p;
+            freed++;
+          }
+          else {
+            dead_slot = FALSE;
+          }
+        }
+      }
+      else {
+        if (!is_generational(gc))
+          paint_partial_white(gc, &p->as.basic); /* next gc target */
+        dead_slot = FALSE;
+      }
+      p++;
+    }
+
+    /* free dead slot */
+    if (dead_slot && freed < MRB_HEAP_PAGE_SIZE) {
+      mrb_heap_page *next = page->next;
+
+      unlink_heap_page(gc, page);
+      unlink_free_heap_page(gc, page);
+      mrb_free(mrb, page);
+      page = next;
+    }
+    else {
+      if (full && freed > 0) {
+        link_free_heap_page(gc, page);
+      }
+      if (page->freelist == NULL && is_minor_gc(gc))
+        page->old = TRUE;
+      else
+        page->old = FALSE;
+      page = page->next;
+    }
+    tried_sweep += MRB_HEAP_PAGE_SIZE;
+    gc->live -= freed;
+    gc->live_after_mark -= freed;
+  }
+  gc->sweeps = page;
+  return tried_sweep;
+}
+
+static size_t
+incremental_gc(mrb_state *mrb, mrb_gc *gc, size_t limit)
+{
+  switch (gc->state) {
+  case MRB_GC_STATE_ROOT:
+    root_scan_phase(mrb, gc);
+    gc->state = MRB_GC_STATE_MARK;
+    flip_white_part(gc);
+    return 0;
+  case MRB_GC_STATE_MARK:
+    if (gc->gray_list) {
+      return incremental_marking_phase(mrb, gc, limit);
+    }
+    else {
+      final_marking_phase(mrb, gc);
+      prepare_incremental_sweep(mrb, gc);
+      return 0;
+    }
+  case MRB_GC_STATE_SWEEP: {
+     size_t tried_sweep = 0;
+     tried_sweep = incremental_sweep_phase(mrb, gc, limit);
+     if (tried_sweep == 0)
+       gc->state = MRB_GC_STATE_ROOT;
+     return tried_sweep;
+  }
+  default:
+    /* unknown state */
+    mrb_assert(0);
+    return 0;
+  }
+}
+
+static void
+incremental_gc_until(mrb_state *mrb, mrb_gc *gc, mrb_gc_state to_state)
+{
+  do {
+    incremental_gc(mrb, gc, SIZE_MAX);
+  } while (gc->state != to_state);
+}
+
+static void
+incremental_gc_step(mrb_state *mrb, mrb_gc *gc)
+{
+  size_t limit = 0, result = 0;
+  limit = (GC_STEP_SIZE/100) * gc->step_ratio;
+  while (result < limit) {
+    result += incremental_gc(mrb, gc, limit);
+    if (gc->state == MRB_GC_STATE_ROOT)
+      break;
+  }
+
+  gc->threshold = gc->live + GC_STEP_SIZE;
+}
+
+static void
+clear_all_old(mrb_state *mrb, mrb_gc *gc)
+{
+  mrb_bool origin_mode = gc->generational;
+
+  mrb_assert(is_generational(gc));
+  if (is_major_gc(gc)) {
+    /* finish the half baked GC */
+    incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT);
+  }
+
+  /* Sweep the dead objects, then reset all the live objects
+   * (including all the old objects, of course) to white. */
+  gc->generational = FALSE;
+  prepare_incremental_sweep(mrb, gc);
+  incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT);
+  gc->generational = origin_mode;
+
+  /* The gray objects have already been painted as white */
+  gc->atomic_gray_list = gc->gray_list = NULL;
+}
+
+MRB_API void
+mrb_incremental_gc(mrb_state *mrb)
+{
+  mrb_gc *gc = &mrb->gc;
+
+  if (gc->disabled || gc->iterating) return;
+
+  GC_INVOKE_TIME_REPORT("mrb_incremental_gc()");
+  GC_TIME_START;
+
+  if (is_minor_gc(gc)) {
+    incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT);
+  }
+  else {
+    incremental_gc_step(mrb, gc);
+  }
+
+  if (gc->state == MRB_GC_STATE_ROOT) {
+    mrb_assert(gc->live >= gc->live_after_mark);
+    gc->threshold = (gc->live_after_mark/100) * gc->interval_ratio;
+    if (gc->threshold < GC_STEP_SIZE) {
+      gc->threshold = GC_STEP_SIZE;
+    }
+
+    if (is_major_gc(gc)) {
+      gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;
+      gc->full = FALSE;
+    }
+    else if (is_minor_gc(gc)) {
+      if (gc->live > gc->majorgc_old_threshold) {
+        clear_all_old(mrb, gc);
+        gc->full = TRUE;
+      }
+    }
+  }
+
+  GC_TIME_STOP_AND_REPORT;
+}
+
+/* Perform a full gc cycle */
+MRB_API void
+mrb_full_gc(mrb_state *mrb)
+{
+  mrb_gc *gc = &mrb->gc;
+
+  if (gc->disabled || gc->iterating) return;
+
+  GC_INVOKE_TIME_REPORT("mrb_full_gc()");
+  GC_TIME_START;
+
+  if (is_generational(gc)) {
+    /* clear all the old objects back to young */
+    clear_all_old(mrb, gc);
+    gc->full = TRUE;
+  }
+  else if (gc->state != MRB_GC_STATE_ROOT) {
+    /* finish half baked GC cycle */
+    incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT);
+  }
+
+  incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT);
+  gc->threshold = (gc->live_after_mark/100) * gc->interval_ratio;
+
+  if (is_generational(gc)) {
+    gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;
+    gc->full = FALSE;
+  }
+
+  GC_TIME_STOP_AND_REPORT;
+}
+
+MRB_API void
+mrb_garbage_collect(mrb_state *mrb)
+{
+  mrb_full_gc(mrb);
+}
+
+MRB_API int
+mrb_gc_arena_save(mrb_state *mrb)
+{
+  return mrb->gc.arena_idx;
+}
+
+MRB_API void
+mrb_gc_arena_restore(mrb_state *mrb, int idx)
+{
+  mrb_gc *gc = &mrb->gc;
+
+#ifndef MRB_GC_FIXED_ARENA
+  int capa = gc->arena_capa;
+
+  if (idx < capa / 2) {
+    capa = (int)(capa * 0.66);
+    if (capa < MRB_GC_ARENA_SIZE) {
+      capa = MRB_GC_ARENA_SIZE;
+    }
+    if (capa != gc->arena_capa) {
+      gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*capa);
+      gc->arena_capa = capa;
+    }
+  }
+#endif
+  gc->arena_idx = idx;
+}
+
+/*
+ * Field write barrier
+ *   Paint obj(Black) -> value(White) to obj(Black) -> value(Gray).
+ */
+
+MRB_API void
+mrb_field_write_barrier(mrb_state *mrb, struct RBasic *obj, struct RBasic *value)
+{
+  mrb_gc *gc = &mrb->gc;
+
+  if (!is_black(obj)) return;
+  if (!is_white(value)) return;
+
+  mrb_assert(gc->state == MRB_GC_STATE_MARK || (!is_dead(gc, value) && !is_dead(gc, obj)));
+  mrb_assert(is_generational(gc) || gc->state != MRB_GC_STATE_ROOT);
+
+  if (is_generational(gc) || gc->state == MRB_GC_STATE_MARK) {
+    add_gray_list(mrb, gc, value);
+  }
+  else {
+    mrb_assert(gc->state == MRB_GC_STATE_SWEEP);
+    paint_partial_white(gc, obj); /* for never write barriers */
+  }
+}
+
+/*
+ * Write barrier
+ *   Paint obj(Black) to obj(Gray).
+ *
+ *   The object that is painted gray will be traversed atomically in final
+ *   mark phase. So you use this write barrier if it's frequency written spot.
+ *   e.g. Set element on Array.
+ */
+
+MRB_API void
+mrb_write_barrier(mrb_state *mrb, struct RBasic *obj)
+{
+  mrb_gc *gc = &mrb->gc;
+
+  if (!is_black(obj)) return;
+
+  mrb_assert(!is_dead(gc, obj));
+  mrb_assert(is_generational(gc) || gc->state != MRB_GC_STATE_ROOT);
+  paint_gray(obj);
+  obj->gcnext = gc->atomic_gray_list;
+  gc->atomic_gray_list = obj;
+}
+
+/*
+ *  call-seq:
+ *     GC.start                     -> nil
+ *
+ *  Initiates full garbage collection.
+ *
+ */
+
+static mrb_value
+gc_start(mrb_state *mrb, mrb_value obj)
+{
+  mrb_full_gc(mrb);
+  return mrb_nil_value();
+}
+
+/*
+ *  call-seq:
+ *     GC.enable    -> true or false
+ *
+ *  Enables garbage collection, returning <code>true</code> if garbage
+ *  collection was previously disabled.
+ *
+ *     GC.disable   #=> false
+ *     GC.enable    #=> true
+ *     GC.enable    #=> false
+ *
+ */
+
+static mrb_value
+gc_enable(mrb_state *mrb, mrb_value obj)
+{
+  mrb_bool old = mrb->gc.disabled;
+
+  mrb->gc.disabled = FALSE;
+
+  return mrb_bool_value(old);
+}
+
+/*
+ *  call-seq:
+ *     GC.disable    -> true or false
+ *
+ *  Disables garbage collection, returning <code>true</code> if garbage
+ *  collection was already disabled.
+ *
+ *     GC.disable   #=> false
+ *     GC.disable   #=> true
+ *
+ */
+
+static mrb_value
+gc_disable(mrb_state *mrb, mrb_value obj)
+{
+  mrb_bool old = mrb->gc.disabled;
+
+  mrb->gc.disabled = TRUE;
+
+  return mrb_bool_value(old);
+}
+
+/*
+ *  call-seq:
+ *     GC.interval_ratio      -> fixnum
+ *
+ *  Returns ratio of GC interval. Default value is 200(%).
+ *
+ */
+
+static mrb_value
+gc_interval_ratio_get(mrb_state *mrb, mrb_value obj)
+{
+  return mrb_fixnum_value(mrb->gc.interval_ratio);
+}
+
+/*
+ *  call-seq:
+ *     GC.interval_ratio = fixnum    -> nil
+ *
+ *  Updates ratio of GC interval. Default value is 200(%).
+ *  GC start as soon as after end all step of GC if you set 100(%).
+ *
+ */
+
+static mrb_value
+gc_interval_ratio_set(mrb_state *mrb, mrb_value obj)
+{
+  mrb_int ratio;
+
+  mrb_get_args(mrb, "i", &ratio);
+  mrb->gc.interval_ratio = ratio;
+  return mrb_nil_value();
+}
+
+/*
+ *  call-seq:
+ *     GC.step_ratio    -> fixnum
+ *
+ *  Returns step span ratio of Incremental GC. Default value is 200(%).
+ *
+ */
+
+static mrb_value
+gc_step_ratio_get(mrb_state *mrb, mrb_value obj)
+{
+  return mrb_fixnum_value(mrb->gc.step_ratio);
+}
+
+/*
+ *  call-seq:
+ *     GC.step_ratio = fixnum   -> nil
+ *
+ *  Updates step span ratio of Incremental GC. Default value is 200(%).
+ *  1 step of incrementalGC becomes long if a rate is big.
+ *
+ */
+
+static mrb_value
+gc_step_ratio_set(mrb_state *mrb, mrb_value obj)
+{
+  mrb_int ratio;
+
+  mrb_get_args(mrb, "i", &ratio);
+  mrb->gc.step_ratio = ratio;
+  return mrb_nil_value();
+}
+
+static void
+change_gen_gc_mode(mrb_state *mrb, mrb_gc *gc, mrb_bool enable)
+{
+  if (gc->disabled || gc->iterating) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "generational mode changed when GC disabled");
+    return;
+  }
+  if (is_generational(gc) && !enable) {
+    clear_all_old(mrb, gc);
+    mrb_assert(gc->state == MRB_GC_STATE_ROOT);
+    gc->full = FALSE;
+  }
+  else if (!is_generational(gc) && enable) {
+    incremental_gc_until(mrb, gc, MRB_GC_STATE_ROOT);
+    gc->majorgc_old_threshold = gc->live_after_mark/100 * DEFAULT_MAJOR_GC_INC_RATIO;
+    gc->full = FALSE;
+  }
+  gc->generational = enable;
+}
+
+/*
+ *  call-seq:
+ *     GC.generational_mode -> true or false
+ *
+ *  Returns generational or normal gc mode.
+ *
+ */
+
+static mrb_value
+gc_generational_mode_get(mrb_state *mrb, mrb_value self)
+{
+  return mrb_bool_value(mrb->gc.generational);
+}
+
+/*
+ *  call-seq:
+ *     GC.generational_mode = true or false -> true or false
+ *
+ *  Changes to generational or normal gc mode.
+ *
+ */
+
+static mrb_value
+gc_generational_mode_set(mrb_state *mrb, mrb_value self)
+{
+  mrb_bool enable;
+
+  mrb_get_args(mrb, "b", &enable);
+  if (mrb->gc.generational != enable)
+    change_gen_gc_mode(mrb, &mrb->gc, enable);
+
+  return mrb_bool_value(enable);
+}
+
+
+static void
+gc_each_objects(mrb_state *mrb, mrb_gc *gc, mrb_each_object_callback *callback, void *data)
+{
+  mrb_heap_page* page;
+
+  page = gc->heaps;
+  while (page != NULL) {
+    RVALUE *p;
+    int i;
+
+    p = objects(page);
+    for (i=0; i < MRB_HEAP_PAGE_SIZE; i++) {
+      if ((*callback)(mrb, &p[i].as.basic, data) == MRB_EACH_OBJ_BREAK)
+        return;
+    }
+    page = page->next;
+  }
+}
+
+void
+mrb_objspace_each_objects(mrb_state *mrb, mrb_each_object_callback *callback, void *data)
+{
+  mrb_bool iterating = mrb->gc.iterating;
+
+  mrb->gc.iterating = TRUE;
+  if (iterating) {
+    gc_each_objects(mrb, &mrb->gc, callback, data);
+  }
+  else {
+    struct mrb_jmpbuf *prev_jmp = mrb->jmp;
+    struct mrb_jmpbuf c_jmp;
+
+    MRB_TRY(&c_jmp) {
+      mrb->jmp = &c_jmp;
+      gc_each_objects(mrb, &mrb->gc, callback, data);
+      mrb->jmp = prev_jmp;
+      mrb->gc.iterating = iterating; 
+   } MRB_CATCH(&c_jmp) {
+      mrb->gc.iterating = iterating;
+      mrb->jmp = prev_jmp;
+      MRB_THROW(prev_jmp);
+    } MRB_END_EXC(&c_jmp);
+  }
+}
+
+#ifdef GC_TEST
+#ifdef GC_DEBUG
+static mrb_value gc_test(mrb_state *, mrb_value);
+#endif
+#endif
+
+void
+mrb_init_gc(mrb_state *mrb)
+{
+  struct RClass *gc;
+
+  gc = mrb_define_module(mrb, "GC");
+
+  mrb_define_class_method(mrb, gc, "start", gc_start, MRB_ARGS_NONE());
+  mrb_define_class_method(mrb, gc, "enable", gc_enable, MRB_ARGS_NONE());
+  mrb_define_class_method(mrb, gc, "disable", gc_disable, MRB_ARGS_NONE());
+  mrb_define_class_method(mrb, gc, "interval_ratio", gc_interval_ratio_get, MRB_ARGS_NONE());
+  mrb_define_class_method(mrb, gc, "interval_ratio=", gc_interval_ratio_set, MRB_ARGS_REQ(1));
+  mrb_define_class_method(mrb, gc, "step_ratio", gc_step_ratio_get, MRB_ARGS_NONE());
+  mrb_define_class_method(mrb, gc, "step_ratio=", gc_step_ratio_set, MRB_ARGS_REQ(1));
+  mrb_define_class_method(mrb, gc, "generational_mode=", gc_generational_mode_set, MRB_ARGS_REQ(1));
+  mrb_define_class_method(mrb, gc, "generational_mode", gc_generational_mode_get, MRB_ARGS_NONE());
+#ifdef GC_TEST
+#ifdef GC_DEBUG
+  mrb_define_class_method(mrb, gc, "test", gc_test, MRB_ARGS_NONE());
+#endif
+#endif
+}
+
+#ifdef GC_TEST
+#ifdef GC_DEBUG
+void
+test_mrb_field_write_barrier(void)
+{
+  mrb_state *mrb = mrb_open();
+  struct RBasic *obj, *value;
+  mrb_gc *gc = &mrb->gc;
+
+  puts("test_mrb_field_write_barrier");
+  gc->generational = FALSE;
+  obj = mrb_basic_ptr(mrb_ary_new(mrb));
+  value = mrb_basic_ptr(mrb_str_new_lit(mrb, "value"));
+  paint_black(obj);
+  paint_partial_white(gc, value);
+
+
+  puts("  in MRB_GC_STATE_MARK");
+  gc->state = MRB_GC_STATE_MARK;
+  mrb_field_write_barrier(mrb, obj, value);
+
+  mrb_assert(is_gray(value));
+
+
+  puts("  in MRB_GC_STATE_SWEEP");
+  paint_partial_white(gc, value);
+  gc->state = MRB_GC_STATE_SWEEP;
+  mrb_field_write_barrier(mrb, obj, value);
+
+  mrb_assert(obj->color & gc->current_white_part);
+  mrb_assert(value->color & gc->current_white_part);
+
+
+  puts("  fail with black");
+  gc->state = MRB_GC_STATE_MARK;
+  paint_white(obj);
+  paint_partial_white(gc, value);
+  mrb_field_write_barrier(mrb, obj, value);
+
+  mrb_assert(obj->color & gc->current_white_part);
+
+
+  puts("  fail with gray");
+  gc->state = MRB_GC_STATE_MARK;
+  paint_black(obj);
+  paint_gray(value);
+  mrb_field_write_barrier(mrb, obj, value);
+
+  mrb_assert(is_gray(value));
+
+
+  {
+    puts("test_mrb_field_write_barrier_value");
+    obj = mrb_basic_ptr(mrb_ary_new(mrb));
+    mrb_value value = mrb_str_new_lit(mrb, "value");
+    paint_black(obj);
+    paint_partial_white(gc, mrb_basic_ptr(value));
+
+    gc->state = MRB_GC_STATE_MARK;
+    mrb_field_write_barrier_value(mrb, obj, value);
+
+    mrb_assert(is_gray(mrb_basic_ptr(value)));
+  }
+
+  mrb_close(mrb);
+}
+
+void
+test_mrb_write_barrier(void)
+{
+  mrb_state *mrb = mrb_open();
+  struct RBasic *obj;
+  mrb_gc *gc = &mrb->gc;
+
+  puts("test_mrb_write_barrier");
+  obj = mrb_basic_ptr(mrb_ary_new(mrb));
+  paint_black(obj);
+
+  puts("  in MRB_GC_STATE_MARK");
+  gc->state = MRB_GC_STATE_MARK;
+  mrb_write_barrier(mrb, obj);
+
+  mrb_assert(is_gray(obj));
+  mrb_assert(gc->atomic_gray_list == obj);
+
+
+  puts("  fail with gray");
+  paint_gray(obj);
+  mrb_write_barrier(mrb, obj);
+
+  mrb_assert(is_gray(obj));
+
+  mrb_close(mrb);
+}
+
+void
+test_add_gray_list(void)
+{
+  mrb_state *mrb = mrb_open();
+  struct RBasic *obj1, *obj2;
+  mrb_gc *gc = &mrb->gc;
+
+  puts("test_add_gray_list");
+  change_gen_gc_mode(mrb, gc, FALSE);
+  mrb_assert(gc->gray_list == NULL);
+  obj1 = mrb_basic_ptr(mrb_str_new_lit(mrb, "test"));
+  add_gray_list(mrb, gc, obj1);
+  mrb_assert(gc->gray_list == obj1);
+  mrb_assert(is_gray(obj1));
+
+  obj2 = mrb_basic_ptr(mrb_str_new_lit(mrb, "test"));
+  add_gray_list(mrb, gc, obj2);
+  mrb_assert(gc->gray_list == obj2);
+  mrb_assert(gc->gray_list->gcnext == obj1);
+  mrb_assert(is_gray(obj2));
+
+  mrb_close(mrb);
+}
+
+void
+test_gc_gray_mark(void)
+{
+  mrb_state *mrb = mrb_open();
+  mrb_value obj_v, value_v;
+  struct RBasic *obj;
+  size_t gray_num = 0;
+  mrb_gc *gc = &mrb->gc;
+
+  puts("test_gc_gray_mark");
+
+  puts("  in MRB_TT_CLASS");
+  obj = (struct RBasic*)mrb->object_class;
+  paint_gray(obj);
+  gray_num = gc_gray_mark(mrb, gc, obj);
+  mrb_assert(is_black(obj));
+  mrb_assert(gray_num > 1);
+
+  puts("  in MRB_TT_ARRAY");
+  obj_v = mrb_ary_new(mrb);
+  value_v = mrb_str_new_lit(mrb, "test");
+  paint_gray(mrb_basic_ptr(obj_v));
+  paint_partial_white(gc, mrb_basic_ptr(value_v));
+  mrb_ary_push(mrb, obj_v, value_v);
+  gray_num = gc_gray_mark(mrb, gc, mrb_basic_ptr(obj_v));
+  mrb_assert(is_black(mrb_basic_ptr(obj_v)));
+  mrb_assert(is_gray(mrb_basic_ptr(value_v)));
+  mrb_assert(gray_num == 1);
+
+  mrb_close(mrb);
+}
+
+void
+test_incremental_gc(void)
+{
+  mrb_state *mrb = mrb_open();
+  size_t max = ~0, live = 0, total = 0, freed = 0;
+  RVALUE *free;
+  mrb_heap_page *page;
+  mrb_gc *gc = &mrb->gc;
+
+  puts("test_incremental_gc");
+  change_gen_gc_mode(mrb, gc, FALSE);
+
+  puts("  in mrb_full_gc");
+  mrb_full_gc(mrb);
+
+  mrb_assert(gc->state == MRB_GC_STATE_ROOT);
+  puts("  in MRB_GC_STATE_ROOT");
+  incremental_gc(mrb, gc, max);
+  mrb_assert(gc->state == MRB_GC_STATE_MARK);
+  puts("  in MRB_GC_STATE_MARK");
+  incremental_gc_until(mrb, gc, MRB_GC_STATE_SWEEP);
+  mrb_assert(gc->state == MRB_GC_STATE_SWEEP);
+
+  puts("  in MRB_GC_STATE_SWEEP");
+  page = gc->heaps;
+  while (page) {
+    RVALUE *p = objects(page);
+    RVALUE *e = p + MRB_HEAP_PAGE_SIZE;
+    while (p<e) {
+      if (is_black(&p->as.basic)) {
+        live++;
+      }
+      if (is_gray(&p->as.basic) && !is_dead(gc, &p->as.basic)) {
+        printf("%p\n", &p->as.basic);
+      }
+      p++;
+    }
+    page = page->next;
+    total += MRB_HEAP_PAGE_SIZE;
+  }
+
+  mrb_assert(gc->gray_list == NULL);
+
+  incremental_gc(mrb, gc, max);
+  mrb_assert(gc->state == MRB_GC_STATE_SWEEP);
+
+  incremental_gc(mrb, gc, max);
+  mrb_assert(gc->state == MRB_GC_STATE_ROOT);
+
+  free = (RVALUE*)gc->heaps->freelist;
+  while (free) {
+   freed++;
+   free = (RVALUE*)free->as.free.next;
+  }
+
+  mrb_assert(gc->live == live);
+  mrb_assert(gc->live == total-freed);
+
+  puts("test_incremental_gc(gen)");
+  incremental_gc_until(mrb, gc, MRB_GC_STATE_SWEEP);
+  change_gen_gc_mode(mrb, gc, TRUE);
+
+  mrb_assert(gc->full == FALSE);
+  mrb_assert(gc->state == MRB_GC_STATE_ROOT);
+
+  puts("  in minor");
+  mrb_assert(is_minor_gc(gc));
+  mrb_assert(gc->majorgc_old_threshold > 0);
+  gc->majorgc_old_threshold = 0;
+  mrb_incremental_gc(mrb);
+  mrb_assert(gc->full == TRUE);
+  mrb_assert(gc->state == MRB_GC_STATE_ROOT);
+
+  puts("  in major");
+  mrb_assert(is_major_gc(gc));
+  do {
+    mrb_incremental_gc(mrb);
+  } while (gc->state != MRB_GC_STATE_ROOT);
+  mrb_assert(gc->full == FALSE);
+
+  mrb_close(mrb);
+}
+
+void
+test_incremental_sweep_phase(void)
+{
+  mrb_state *mrb = mrb_open();
+  mrb_gc *gc = &mrb->gc;
+
+  puts("test_incremental_sweep_phase");
+
+  add_heap(mrb, gc);
+  gc->sweeps = gc->heaps;
+
+  mrb_assert(gc->heaps->next->next == NULL);
+  mrb_assert(gc->free_heaps->next->next == NULL);
+  incremental_sweep_phase(mrb, gc, MRB_HEAP_PAGE_SIZE * 3);
+
+  mrb_assert(gc->heaps->next == NULL);
+  mrb_assert(gc->heaps == gc->free_heaps);
+
+  mrb_close(mrb);
+}
+
+static mrb_value
+gc_test(mrb_state *mrb, mrb_value self)
+{
+  test_mrb_field_write_barrier();
+  test_mrb_write_barrier();
+  test_add_gray_list();
+  test_gc_gray_mark();
+  test_incremental_gc();
+  test_incremental_sweep_phase();
+  return mrb_nil_value();
+}
+#endif  /* GC_DEBUG */
+#endif  /* GC_TEST */
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/hash.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/hash.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/hash.c	(revision 331)
@@ -0,0 +1,917 @@
+/*
+** hash.c - Hash class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/class.h>
+#include <mruby/hash.h>
+#include <mruby/khash.h>
+#include <mruby/string.h>
+#include <mruby/variable.h>
+
+/* a function to get hash value of a float number */
+mrb_int mrb_float_id(mrb_float f);
+
+static inline khint_t
+mrb_hash_ht_hash_func(mrb_state *mrb, mrb_value key)
+{
+  enum mrb_vtype t = mrb_type(key);
+  mrb_value hv;
+  const char *p;
+  mrb_int i, len;
+  khint_t h;
+
+  switch (t) {
+  case MRB_TT_STRING:
+    p = RSTRING_PTR(key);
+    len = RSTRING_LEN(key);
+    h = 0;
+    for (i=0; i<len; i++) {
+      h = (h << 5) - h + *p++;
+    }
+    return h;
+
+  case MRB_TT_SYMBOL:
+    h = (khint_t)mrb_symbol(key);
+    return kh_int_hash_func(mrb, h);
+
+  case MRB_TT_FIXNUM:
+    h = (khint_t)mrb_float_id((mrb_float)mrb_fixnum(key));
+    return kh_int_hash_func(mrb, h);
+
+  case MRB_TT_FLOAT:
+    h = (khint_t)mrb_float_id(mrb_float(key));
+    return kh_int_hash_func(mrb, h);
+
+  default:
+    hv = mrb_funcall(mrb, key, "hash", 0);
+    h = (khint_t)t ^ mrb_fixnum(hv);
+    return kh_int_hash_func(mrb, h);
+  }
+}
+
+static inline khint_t
+mrb_hash_ht_hash_equal(mrb_state *mrb, mrb_value a, mrb_value b)
+{
+  enum mrb_vtype t = mrb_type(a);
+
+  switch (t) {
+  case MRB_TT_STRING:
+    return mrb_str_equal(mrb, a, b);
+
+  case MRB_TT_SYMBOL:
+    if (mrb_type(b) != MRB_TT_SYMBOL) return FALSE;
+    return mrb_symbol(a) == mrb_symbol(b);
+
+  case MRB_TT_FIXNUM:
+    switch (mrb_type(b)) {
+    case MRB_TT_FIXNUM:
+      return mrb_fixnum(a) == mrb_fixnum(b);
+    case MRB_TT_FLOAT:
+      return (mrb_float)mrb_fixnum(a) == mrb_float(b);
+    default:
+      return FALSE;
+    }
+
+  case MRB_TT_FLOAT:
+    switch (mrb_type(b)) {
+    case MRB_TT_FIXNUM:
+      return mrb_float(a) == (mrb_float)mrb_fixnum(b);
+    case MRB_TT_FLOAT:
+      return mrb_float(a) == mrb_float(b);
+    default:
+      return FALSE;
+    }
+
+  default:
+    return mrb_eql(mrb, a, b);
+  }
+}
+
+KHASH_DEFINE (ht, mrb_value, mrb_hash_value, TRUE, mrb_hash_ht_hash_func, mrb_hash_ht_hash_equal)
+
+static void mrb_hash_modify(mrb_state *mrb, mrb_value hash);
+
+static inline mrb_value
+mrb_hash_ht_key(mrb_state *mrb, mrb_value key)
+{
+  if (mrb_string_p(key) && !MRB_FROZEN_P(mrb_str_ptr(key))) {
+    key = mrb_str_dup(mrb, key);
+    MRB_SET_FROZEN_FLAG(mrb_str_ptr(key));
+  }
+  return key;
+}
+
+#define KEY(key) mrb_hash_ht_key(mrb, key)
+
+void
+mrb_gc_mark_hash(mrb_state *mrb, struct RHash *hash)
+{
+  khiter_t k;
+  khash_t(ht) *h = hash->ht;
+
+  if (!h) return;
+  for (k = kh_begin(h); k != kh_end(h); k++) {
+    if (kh_exist(h, k)) {
+      mrb_value key = kh_key(h, k);
+      mrb_value val = kh_value(h, k).v;
+
+      mrb_gc_mark_value(mrb, key);
+      mrb_gc_mark_value(mrb, val);
+    }
+  }
+}
+
+size_t
+mrb_gc_mark_hash_size(mrb_state *mrb, struct RHash *hash)
+{
+  if (!hash->ht) return 0;
+  return kh_size(hash->ht)*2;
+}
+
+void
+mrb_gc_free_hash(mrb_state *mrb, struct RHash *hash)
+{
+  if (hash->ht) kh_destroy(ht, mrb, hash->ht);
+}
+
+
+MRB_API mrb_value
+mrb_hash_new_capa(mrb_state *mrb, mrb_int capa)
+{
+  struct RHash *h;
+
+  h = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class);
+  h->ht = kh_init(ht, mrb);
+  if (capa > 0) {
+    kh_resize(ht, mrb, h->ht, capa);
+  }
+  h->iv = 0;
+  return mrb_obj_value(h);
+}
+
+MRB_API mrb_value
+mrb_hash_new(mrb_state *mrb)
+{
+  return mrb_hash_new_capa(mrb, 0);
+}
+
+static mrb_value mrb_hash_default(mrb_state *mrb, mrb_value hash);
+static mrb_value hash_default(mrb_state *mrb, mrb_value hash, mrb_value key);
+
+MRB_API mrb_value
+mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key)
+{
+  khash_t(ht) *h = RHASH_TBL(hash);
+  khiter_t k;
+  mrb_sym mid;
+
+  if (h) {
+    k = kh_get(ht, mrb, h, key);
+    if (k != kh_end(h))
+      return kh_value(h, k).v;
+  }
+
+  mid = mrb_intern_lit(mrb, "default");
+  if (mrb_func_basic_p(mrb, hash, mid, mrb_hash_default)) {
+    return hash_default(mrb, hash, key);
+  }
+  /* xxx mrb_funcall_tailcall(mrb, hash, "default", 1, key); */
+  return mrb_funcall_argv(mrb, hash, mid, 1, &key);
+}
+
+MRB_API mrb_value
+mrb_hash_fetch(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value def)
+{
+  khash_t(ht) *h = RHASH_TBL(hash);
+  khiter_t k;
+
+  if (h) {
+    k = kh_get(ht, mrb, h, key);
+    if (k != kh_end(h))
+      return kh_value(h, k).v;
+  }
+
+  /* not found */
+  return def;
+}
+
+MRB_API void
+mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val)
+{
+  khash_t(ht) *h;
+  khiter_t k;
+  int r;
+
+  mrb_hash_modify(mrb, hash);
+  h = RHASH_TBL(hash);
+
+  if (!h) h = RHASH_TBL(hash) = kh_init(ht, mrb);
+  k = kh_put2(ht, mrb, h, key, &r);
+  kh_value(h, k).v = val;
+
+  if (r != 0) {
+    /* expand */
+    int ai = mrb_gc_arena_save(mrb);
+    key = kh_key(h, k) = KEY(key);
+    mrb_gc_arena_restore(mrb, ai);
+    kh_value(h, k).n = kh_size(h)-1;
+  }
+
+  mrb_field_write_barrier_value(mrb, (struct RBasic*)RHASH(hash), key);
+  mrb_field_write_barrier_value(mrb, (struct RBasic*)RHASH(hash), val);
+  return;
+}
+
+static mrb_value
+mrb_hash_dup(mrb_state *mrb, mrb_value hash)
+{
+  struct RHash* ret;
+  khash_t(ht) *h, *ret_h;
+  khiter_t k, ret_k;
+  mrb_value ifnone, vret;
+
+  h = RHASH_TBL(hash);
+  ret = (struct RHash*)mrb_obj_alloc(mrb, MRB_TT_HASH, mrb->hash_class);
+  ret->ht = kh_init(ht, mrb);
+
+  if (h && kh_size(h) > 0) {
+    ret_h = ret->ht;
+
+    for (k = kh_begin(h); k != kh_end(h); k++) {
+      if (kh_exist(h, k)) {
+        int ai = mrb_gc_arena_save(mrb);
+        ret_k = kh_put(ht, mrb, ret_h, KEY(kh_key(h, k)));
+        mrb_gc_arena_restore(mrb, ai);
+        kh_val(ret_h, ret_k).v = kh_val(h, k).v;
+        kh_val(ret_h, ret_k).n = kh_size(ret_h)-1;
+      }
+    }
+  }
+
+  if (MRB_RHASH_DEFAULT_P(hash)) {
+    ret->flags |= MRB_HASH_DEFAULT;
+  }
+  if (MRB_RHASH_PROCDEFAULT_P(hash)) {
+    ret->flags |= MRB_HASH_PROC_DEFAULT;
+  }
+  vret = mrb_obj_value(ret);
+  ifnone = RHASH_IFNONE(hash);
+  if (!mrb_nil_p(ifnone)) {
+      mrb_iv_set(mrb, vret, mrb_intern_lit(mrb, "ifnone"), ifnone);
+  }
+  return vret;
+}
+
+MRB_API mrb_value
+mrb_check_hash_type(mrb_state *mrb, mrb_value hash)
+{
+  return mrb_check_convert_type(mrb, hash, MRB_TT_HASH, "Hash", "to_hash");
+}
+
+MRB_API khash_t(ht)*
+mrb_hash_tbl(mrb_state *mrb, mrb_value hash)
+{
+  khash_t(ht) *h = RHASH_TBL(hash);
+
+  if (!h) {
+    return RHASH_TBL(hash) = kh_init(ht, mrb);
+  }
+  return h;
+}
+
+static void
+mrb_hash_modify(mrb_state *mrb, mrb_value hash)
+{
+  if (MRB_FROZEN_P(mrb_hash_ptr(hash))) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen hash");
+  }
+  mrb_hash_tbl(mrb, hash);
+}
+
+/* 15.2.13.4.16 */
+/*
+ *  call-seq:
+ *     Hash.new                          -> new_hash
+ *     Hash.new(obj)                     -> new_hash
+ *     Hash.new {|hash, key| block }     -> new_hash
+ *
+ *  Returns a new, empty hash. If this hash is subsequently accessed by
+ *  a key that doesn't correspond to a hash entry, the value returned
+ *  depends on the style of <code>new</code> used to create the hash. In
+ *  the first form, the access returns <code>nil</code>. If
+ *  <i>obj</i> is specified, this single object will be used for
+ *  all <em>default values</em>. If a block is specified, it will be
+ *  called with the hash object and the key, and should return the
+ *  default value. It is the block's responsibility to store the value
+ *  in the hash if required.
+ *
+ *      h = Hash.new("Go Fish")
+ *      h["a"] = 100
+ *      h["b"] = 200
+ *      h["a"]           #=> 100
+ *      h["c"]           #=> "Go Fish"
+ *      # The following alters the single default object
+ *      h["c"].upcase!   #=> "GO FISH"
+ *      h["d"]           #=> "GO FISH"
+ *      h.keys           #=> ["a", "b"]
+ *
+ *      # While this creates a new default object each time
+ *      h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" }
+ *      h["c"]           #=> "Go Fish: c"
+ *      h["c"].upcase!   #=> "GO FISH: C"
+ *      h["d"]           #=> "Go Fish: d"
+ *      h.keys           #=> ["c", "d"]
+ *
+ */
+
+static mrb_value
+mrb_hash_init(mrb_state *mrb, mrb_value hash)
+{
+  mrb_value block, ifnone;
+  mrb_bool ifnone_p;
+
+  ifnone = mrb_nil_value();
+  mrb_get_args(mrb, "&|o?", &block, &ifnone, &ifnone_p);
+  mrb_hash_modify(mrb, hash);
+  if (!mrb_nil_p(block)) {
+    if (ifnone_p) {
+      mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
+    }
+    RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
+    ifnone = block;
+  }
+  if (!mrb_nil_p(ifnone)) {
+    RHASH(hash)->flags |= MRB_HASH_DEFAULT;
+    mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
+  }
+  return hash;
+}
+
+/* 15.2.13.4.2  */
+/*
+ *  call-seq:
+ *     hsh[key]    ->  value
+ *
+ *  Element Reference---Retrieves the <i>value</i> object corresponding
+ *  to the <i>key</i> object. If not found, returns the default value (see
+ *  <code>Hash::new</code> for details).
+ *
+ *     h = { "a" => 100, "b" => 200 }
+ *     h["a"]   #=> 100
+ *     h["c"]   #=> nil
+ *
+ */
+static mrb_value
+mrb_hash_aget(mrb_state *mrb, mrb_value self)
+{
+  mrb_value key;
+
+  mrb_get_args(mrb, "o", &key);
+  return mrb_hash_get(mrb, self, key);
+}
+
+static mrb_value
+hash_default(mrb_state *mrb, mrb_value hash, mrb_value key)
+{
+  if (MRB_RHASH_DEFAULT_P(hash)) {
+    if (MRB_RHASH_PROCDEFAULT_P(hash)) {
+      return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key);
+    }
+    else {
+      return RHASH_IFNONE(hash);
+    }
+  }
+  return mrb_nil_value();
+}
+
+/* 15.2.13.4.5  */
+/*
+ *  call-seq:
+ *     hsh.default(key=nil)   -> obj
+ *
+ *  Returns the default value, the value that would be returned by
+ *  <i>hsh</i>[<i>key</i>] if <i>key</i> did not exist in <i>hsh</i>.
+ *  See also <code>Hash::new</code> and <code>Hash#default=</code>.
+ *
+ *     h = Hash.new                            #=> {}
+ *     h.default                               #=> nil
+ *     h.default(2)                            #=> nil
+ *
+ *     h = Hash.new("cat")                     #=> {}
+ *     h.default                               #=> "cat"
+ *     h.default(2)                            #=> "cat"
+ *
+ *     h = Hash.new {|h,k| h[k] = k.to_i*10}   #=> {}
+ *     h.default                               #=> nil
+ *     h.default(2)                            #=> 20
+ */
+
+static mrb_value
+mrb_hash_default(mrb_state *mrb, mrb_value hash)
+{
+  mrb_value key;
+  mrb_bool given;
+
+  mrb_get_args(mrb, "|o?", &key, &given);
+  if (MRB_RHASH_DEFAULT_P(hash)) {
+    if (MRB_RHASH_PROCDEFAULT_P(hash)) {
+      if (!given) return mrb_nil_value();
+      return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key);
+    }
+    else {
+      return RHASH_IFNONE(hash);
+    }
+  }
+  return mrb_nil_value();
+}
+
+/* 15.2.13.4.6  */
+/*
+ *  call-seq:
+ *     hsh.default = obj     -> obj
+ *
+ *  Sets the default value, the value returned for a key that does not
+ *  exist in the hash. It is not possible to set the default to a
+ *  <code>Proc</code> that will be executed on each key lookup.
+ *
+ *     h = { "a" => 100, "b" => 200 }
+ *     h.default = "Go fish"
+ *     h["a"]     #=> 100
+ *     h["z"]     #=> "Go fish"
+ *     # This doesn't do what you might hope...
+ *     h.default = proc do |hash, key|
+ *       hash[key] = key + key
+ *     end
+ *     h[2]       #=> #<Proc:0x401b3948@-:6>
+ *     h["cat"]   #=> #<Proc:0x401b3948@-:6>
+ */
+
+static mrb_value
+mrb_hash_set_default(mrb_state *mrb, mrb_value hash)
+{
+  mrb_value ifnone;
+
+  mrb_get_args(mrb, "o", &ifnone);
+  mrb_hash_modify(mrb, hash);
+  mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
+  RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT;
+  if (!mrb_nil_p(ifnone)) {
+    RHASH(hash)->flags |= MRB_HASH_DEFAULT;
+  }
+  else {
+    RHASH(hash)->flags &= ~MRB_HASH_DEFAULT;
+  }
+  return ifnone;
+}
+
+/* 15.2.13.4.7  */
+/*
+ *  call-seq:
+ *     hsh.default_proc -> anObject
+ *
+ *  If <code>Hash::new</code> was invoked with a block, return that
+ *  block, otherwise return <code>nil</code>.
+ *
+ *     h = Hash.new {|h,k| h[k] = k*k }   #=> {}
+ *     p = h.default_proc                 #=> #<Proc:0x401b3d08@-:1>
+ *     a = []                             #=> []
+ *     p.call(a, 2)
+ *     a                                  #=> [nil, nil, 4]
+ */
+
+
+static mrb_value
+mrb_hash_default_proc(mrb_state *mrb, mrb_value hash)
+{
+  if (MRB_RHASH_PROCDEFAULT_P(hash)) {
+    return RHASH_PROCDEFAULT(hash);
+  }
+  return mrb_nil_value();
+}
+
+/*
+ *  call-seq:
+ *     hsh.default_proc = proc_obj     -> proc_obj
+ *
+ *  Sets the default proc to be executed on each key lookup.
+ *
+ *     h.default_proc = proc do |hash, key|
+ *       hash[key] = key + key
+ *     end
+ *     h[2]       #=> 4
+ *     h["cat"]   #=> "catcat"
+ */
+
+static mrb_value
+mrb_hash_set_default_proc(mrb_state *mrb, mrb_value hash)
+{
+  mrb_value ifnone;
+
+  mrb_get_args(mrb, "o", &ifnone);
+  mrb_hash_modify(mrb, hash);
+  mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
+  if (!mrb_nil_p(ifnone)) {
+    RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
+    RHASH(hash)->flags |= MRB_HASH_DEFAULT;
+  }
+  else {
+    RHASH(hash)->flags &= ~MRB_HASH_DEFAULT;
+    RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT;
+  }
+
+  return ifnone;
+}
+
+MRB_API mrb_value
+mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key)
+{
+  khash_t(ht) *h = RHASH_TBL(hash);
+  khiter_t k;
+  mrb_value delVal;
+  mrb_int n;
+
+  if (h) {
+    k = kh_get(ht, mrb, h, key);
+    if (k != kh_end(h)) {
+      delVal = kh_value(h, k).v;
+      n = kh_value(h, k).n;
+      kh_del(ht, mrb, h, k);
+      for (k = kh_begin(h); k != kh_end(h); k++) {
+        if (!kh_exist(h, k)) continue;
+        if (kh_value(h, k).n > n) kh_value(h, k).n--;
+      }
+      return delVal;
+    }
+  }
+
+  /* not found */
+  return mrb_nil_value();
+}
+
+/* 15.2.13.4.8  */
+/*
+ *  call-seq:
+ *     hsh.delete(key)                   -> value
+ *     hsh.delete(key) {| key | block }  -> value
+ *
+ *  Deletes and returns a key-value pair from <i>hsh</i> whose key is
+ *  equal to <i>key</i>. If the key is not found, returns the
+ *  <em>default value</em>. If the optional code block is given and the
+ *  key is not found, pass in the key and return the result of
+ *  <i>block</i>.
+ *
+ *      h = { "a" => 100, "b" => 200 }
+ *      h.delete("a")                              #=> 100
+ *      h.delete("z")                              #=> nil
+ *      h.delete("z") { |el| "#{el} not found" }   #=> "z not found"
+ *
+ */
+static mrb_value
+mrb_hash_delete(mrb_state *mrb, mrb_value self)
+{
+  mrb_value key;
+
+  mrb_get_args(mrb, "o", &key);
+  mrb_hash_modify(mrb, self);
+  return mrb_hash_delete_key(mrb, self, key);
+}
+
+/* 15.2.13.4.24 */
+/*
+ *  call-seq:
+ *     hsh.shift -> anArray or obj
+ *
+ *  Removes a key-value pair from <i>hsh</i> and returns it as the
+ *  two-item array <code>[</code> <i>key, value</i> <code>]</code>, or
+ *  the hash's default value if the hash is empty.
+ *
+ *      h = { 1 => "a", 2 => "b", 3 => "c" }
+ *      h.shift   #=> [1, "a"]
+ *      h         #=> {2=>"b", 3=>"c"}
+ */
+
+static mrb_value
+mrb_hash_shift(mrb_state *mrb, mrb_value hash)
+{
+  khash_t(ht) *h = RHASH_TBL(hash);
+  khiter_t k;
+  mrb_value delKey, delVal;
+
+  mrb_hash_modify(mrb, hash);
+  if (h && kh_size(h) > 0) {
+    for (k = kh_begin(h); k != kh_end(h); k++) {
+      if (!kh_exist(h, k)) continue;
+
+      delKey = kh_key(h, k);
+      mrb_gc_protect(mrb, delKey);
+      delVal = mrb_hash_delete_key(mrb, hash, delKey);
+      mrb_gc_protect(mrb, delVal);
+
+      return mrb_assoc_new(mrb, delKey, delVal);
+    }
+  }
+
+  if (MRB_RHASH_DEFAULT_P(hash)) {
+    if (MRB_RHASH_PROCDEFAULT_P(hash)) {
+      return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, mrb_nil_value());
+    }
+    else {
+      return RHASH_IFNONE(hash);
+    }
+  }
+  return mrb_nil_value();
+}
+
+/* 15.2.13.4.4  */
+/*
+ *  call-seq:
+ *     hsh.clear -> hsh
+ *
+ *  Removes all key-value pairs from `hsh`.
+ *
+ *      h = { "a" => 100, "b" => 200 }   #=> {"a"=>100, "b"=>200}
+ *      h.clear                          #=> {}
+ *
+ */
+
+MRB_API mrb_value
+mrb_hash_clear(mrb_state *mrb, mrb_value hash)
+{
+  khash_t(ht) *h = RHASH_TBL(hash);
+
+  mrb_hash_modify(mrb, hash);
+  if (h) kh_clear(ht, mrb, h);
+  return hash;
+}
+
+/* 15.2.13.4.3  */
+/* 15.2.13.4.26 */
+/*
+ *  call-seq:
+ *     hsh[key] = value        -> value
+ *     hsh.store(key, value)   -> value
+ *
+ *  Element Assignment---Associates the value given by
+ *  <i>value</i> with the key given by <i>key</i>.
+ *  <i>key</i> should not have its value changed while it is in
+ *  use as a key (a <code>String</code> passed as a key will be
+ *  duplicated and frozen).
+ *
+ *      h = { "a" => 100, "b" => 200 }
+ *      h["a"] = 9
+ *      h["c"] = 4
+ *      h   #=> {"a"=>9, "b"=>200, "c"=>4}
+ *
+ */
+static mrb_value
+mrb_hash_aset(mrb_state *mrb, mrb_value self)
+{
+  mrb_value key, val;
+
+  mrb_get_args(mrb, "oo", &key, &val);
+  mrb_hash_set(mrb, self, key, val);
+  return val;
+}
+
+/* 15.2.13.4.20 */
+/* 15.2.13.4.25 */
+/*
+ *  call-seq:
+ *     hsh.length    ->  fixnum
+ *     hsh.size      ->  fixnum
+ *
+ *  Returns the number of key-value pairs in the hash.
+ *
+ *     h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 }
+ *     h.length        #=> 4
+ *     h.delete("a")   #=> 200
+ *     h.length        #=> 3
+ */
+static mrb_value
+mrb_hash_size_m(mrb_state *mrb, mrb_value self)
+{
+  khash_t(ht) *h = RHASH_TBL(self);
+
+  if (!h) return mrb_fixnum_value(0);
+  return mrb_fixnum_value(kh_size(h));
+}
+
+/* 15.2.13.4.12 */
+/*
+ *  call-seq:
+ *     hsh.empty?    -> true or false
+ *
+ *  Returns <code>true</code> if <i>hsh</i> contains no key-value pairs.
+ *
+ *     {}.empty?   #=> true
+ *
+ */
+MRB_API mrb_value
+mrb_hash_empty_p(mrb_state *mrb, mrb_value self)
+{
+  khash_t(ht) *h = RHASH_TBL(self);
+
+  if (h) return mrb_bool_value(kh_size(h) == 0);
+  return mrb_true_value();
+}
+
+/* 15.2.13.4.29 (x)*/
+/*
+ * call-seq:
+ *    hsh.to_hash   => hsh
+ *
+ * Returns +self+.
+ */
+
+static mrb_value
+mrb_hash_to_hash(mrb_state *mrb, mrb_value hash)
+{
+  return hash;
+}
+
+/* 15.2.13.4.19 */
+/*
+ *  call-seq:
+ *     hsh.keys    -> array
+ *
+ *  Returns a new array populated with the keys from this hash. See also
+ *  <code>Hash#values</code>.
+ *
+ *     h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 }
+ *     h.keys   #=> ["a", "b", "c", "d"]
+ *
+ */
+
+MRB_API mrb_value
+mrb_hash_keys(mrb_state *mrb, mrb_value hash)
+{
+  khash_t(ht) *h = RHASH_TBL(hash);
+  khiter_t k;
+  mrb_int end;
+  mrb_value ary;
+  mrb_value *p;
+
+  if (!h || kh_size(h) == 0) return mrb_ary_new(mrb);
+  ary = mrb_ary_new_capa(mrb, kh_size(h));
+  end = kh_size(h)-1;
+  mrb_ary_set(mrb, ary, end, mrb_nil_value());
+  p = mrb_ary_ptr(ary)->ptr;
+  for (k = kh_begin(h); k != kh_end(h); k++) {
+    if (kh_exist(h, k)) {
+      mrb_value kv = kh_key(h, k);
+      mrb_hash_value hv = kh_value(h, k);
+
+      if (hv.n <= end) {
+        p[hv.n] = kv;
+      }
+      else {
+        p[end] = kv;
+      }
+    }
+  }
+  return ary;
+}
+
+/* 15.2.13.4.28 */
+/*
+ *  call-seq:
+ *     hsh.values    -> array
+ *
+ *  Returns a new array populated with the values from <i>hsh</i>. See
+ *  also <code>Hash#keys</code>.
+ *
+ *     h = { "a" => 100, "b" => 200, "c" => 300 }
+ *     h.values   #=> [100, 200, 300]
+ *
+ */
+
+MRB_API mrb_value
+mrb_hash_values(mrb_state *mrb, mrb_value hash)
+{
+  khash_t(ht) *h = RHASH_TBL(hash);
+  khiter_t k;
+  mrb_value ary;
+
+  if (!h) return mrb_ary_new(mrb);
+  ary = mrb_ary_new_capa(mrb, kh_size(h));
+  for (k = kh_begin(h); k != kh_end(h); k++) {
+    if (kh_exist(h, k)) {
+      mrb_hash_value hv = kh_value(h, k);
+
+      mrb_ary_set(mrb, ary, hv.n, hv.v);
+    }
+  }
+  return ary;
+}
+
+/* 15.2.13.4.13 */
+/* 15.2.13.4.15 */
+/* 15.2.13.4.18 */
+/* 15.2.13.4.21 */
+/*
+ *  call-seq:
+ *     hsh.has_key?(key)    -> true or false
+ *     hsh.include?(key)    -> true or false
+ *     hsh.key?(key)        -> true or false
+ *     hsh.member?(key)     -> true or false
+ *
+ *  Returns <code>true</code> if the given key is present in <i>hsh</i>.
+ *
+ *     h = { "a" => 100, "b" => 200 }
+ *     h.has_key?("a")   #=> true
+ *     h.has_key?("z")   #=> false
+ *
+ */
+
+static mrb_value
+mrb_hash_has_key(mrb_state *mrb, mrb_value hash)
+{
+  mrb_value key;
+  khash_t(ht) *h;
+  khiter_t k;
+
+  mrb_get_args(mrb, "o", &key);
+
+  h = RHASH_TBL(hash);
+  if (h) {
+    k = kh_get(ht, mrb, h, key);
+    return mrb_bool_value(k != kh_end(h));
+  }
+  return mrb_false_value();
+}
+
+/* 15.2.13.4.14 */
+/* 15.2.13.4.27 */
+/*
+ *  call-seq:
+ *     hsh.has_value?(value)    -> true or false
+ *     hsh.value?(value)        -> true or false
+ *
+ *  Returns <code>true</code> if the given value is present for some key
+ *  in <i>hsh</i>.
+ *
+ *     h = { "a" => 100, "b" => 200 }
+ *     h.has_value?(100)   #=> true
+ *     h.has_value?(999)   #=> false
+ */
+
+static mrb_value
+mrb_hash_has_value(mrb_state *mrb, mrb_value hash)
+{
+  mrb_value val;
+  khash_t(ht) *h;
+  khiter_t k;
+
+  mrb_get_args(mrb, "o", &val);
+  h = RHASH_TBL(hash);
+
+  if (h) {
+    for (k = kh_begin(h); k != kh_end(h); k++) {
+      if (!kh_exist(h, k)) continue;
+
+      if (mrb_equal(mrb, kh_value(h, k).v, val)) {
+        return mrb_true_value();
+      }
+    }
+  }
+  return mrb_false_value();
+}
+
+void
+mrb_init_hash(mrb_state *mrb)
+{
+  struct RClass *h;
+
+  mrb->hash_class = h = mrb_define_class(mrb, "Hash", mrb->object_class);              /* 15.2.13 */
+  MRB_SET_INSTANCE_TT(h, MRB_TT_HASH);
+
+  mrb_define_method(mrb, h, "[]",              mrb_hash_aget,        MRB_ARGS_REQ(1)); /* 15.2.13.4.2  */
+  mrb_define_method(mrb, h, "[]=",             mrb_hash_aset,        MRB_ARGS_REQ(2)); /* 15.2.13.4.3  */
+  mrb_define_method(mrb, h, "clear",           mrb_hash_clear,       MRB_ARGS_NONE()); /* 15.2.13.4.4  */
+  mrb_define_method(mrb, h, "default",         mrb_hash_default,     MRB_ARGS_ANY());  /* 15.2.13.4.5  */
+  mrb_define_method(mrb, h, "default=",        mrb_hash_set_default, MRB_ARGS_REQ(1)); /* 15.2.13.4.6  */
+  mrb_define_method(mrb, h, "default_proc",    mrb_hash_default_proc,MRB_ARGS_NONE()); /* 15.2.13.4.7  */
+  mrb_define_method(mrb, h, "default_proc=",   mrb_hash_set_default_proc,MRB_ARGS_REQ(1)); /* 15.2.13.4.7  */
+  mrb_define_method(mrb, h, "__delete",        mrb_hash_delete,      MRB_ARGS_REQ(1)); /* core of 15.2.13.4.8  */
+  mrb_define_method(mrb, h, "empty?",          mrb_hash_empty_p,     MRB_ARGS_NONE()); /* 15.2.13.4.12 */
+  mrb_define_method(mrb, h, "has_key?",        mrb_hash_has_key,     MRB_ARGS_REQ(1)); /* 15.2.13.4.13 */
+  mrb_define_method(mrb, h, "has_value?",      mrb_hash_has_value,   MRB_ARGS_REQ(1)); /* 15.2.13.4.14 */
+  mrb_define_method(mrb, h, "include?",        mrb_hash_has_key,     MRB_ARGS_REQ(1)); /* 15.2.13.4.15 */
+  mrb_define_method(mrb, h, "initialize",      mrb_hash_init,        MRB_ARGS_OPT(1)); /* 15.2.13.4.16 */
+  mrb_define_method(mrb, h, "key?",            mrb_hash_has_key,     MRB_ARGS_REQ(1)); /* 15.2.13.4.18 */
+  mrb_define_method(mrb, h, "keys",            mrb_hash_keys,        MRB_ARGS_NONE()); /* 15.2.13.4.19 */
+  mrb_define_method(mrb, h, "length",          mrb_hash_size_m,      MRB_ARGS_NONE()); /* 15.2.13.4.20 */
+  mrb_define_method(mrb, h, "member?",         mrb_hash_has_key,     MRB_ARGS_REQ(1)); /* 15.2.13.4.21 */
+  mrb_define_method(mrb, h, "shift",           mrb_hash_shift,       MRB_ARGS_NONE()); /* 15.2.13.4.24 */
+  mrb_define_method(mrb, h, "dup",             mrb_hash_dup,         MRB_ARGS_NONE());
+  mrb_define_method(mrb, h, "size",            mrb_hash_size_m,      MRB_ARGS_NONE()); /* 15.2.13.4.25 */
+  mrb_define_method(mrb, h, "store",           mrb_hash_aset,        MRB_ARGS_REQ(2)); /* 15.2.13.4.26 */
+  mrb_define_method(mrb, h, "value?",          mrb_hash_has_value,   MRB_ARGS_REQ(1)); /* 15.2.13.4.27 */
+  mrb_define_method(mrb, h, "values",          mrb_hash_values,      MRB_ARGS_NONE()); /* 15.2.13.4.28 */
+
+  mrb_define_method(mrb, h, "to_hash",         mrb_hash_to_hash,     MRB_ARGS_NONE()); /* 15.2.13.4.29 (x)*/
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/init.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/init.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/init.c	(revision 331)
@@ -0,0 +1,51 @@
+/*
+** init.c - initialize mruby core
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <mruby.h>
+
+void mrb_init_symtbl(mrb_state*);
+void mrb_init_class(mrb_state*);
+void mrb_init_object(mrb_state*);
+void mrb_init_kernel(mrb_state*);
+void mrb_init_comparable(mrb_state*);
+void mrb_init_enumerable(mrb_state*);
+void mrb_init_symbol(mrb_state*);
+void mrb_init_string(mrb_state*);
+void mrb_init_exception(mrb_state*);
+void mrb_init_proc(mrb_state*);
+void mrb_init_array(mrb_state*);
+void mrb_init_hash(mrb_state*);
+void mrb_init_numeric(mrb_state*);
+void mrb_init_range(mrb_state*);
+void mrb_init_gc(mrb_state*);
+void mrb_init_math(mrb_state*);
+void mrb_init_version(mrb_state*);
+void mrb_init_mrblib(mrb_state*);
+
+#define DONE mrb_gc_arena_restore(mrb, 0);
+void
+mrb_init_core(mrb_state *mrb)
+{
+  mrb_init_symtbl(mrb); DONE;
+
+  mrb_init_class(mrb); DONE;
+  mrb_init_object(mrb); DONE;
+  mrb_init_kernel(mrb); DONE;
+  mrb_init_comparable(mrb); DONE;
+  mrb_init_enumerable(mrb); DONE;
+
+  mrb_init_symbol(mrb); DONE;
+  mrb_init_string(mrb); DONE;
+  mrb_init_exception(mrb); DONE;
+  mrb_init_proc(mrb); DONE;
+  mrb_init_array(mrb); DONE;
+  mrb_init_hash(mrb); DONE;
+  mrb_init_numeric(mrb); DONE;
+  mrb_init_range(mrb); DONE;
+  mrb_init_gc(mrb); DONE;
+  mrb_init_version(mrb); DONE;
+  mrb_init_mrblib(mrb); DONE;
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/kernel.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/kernel.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/kernel.c	(revision 331)
@@ -0,0 +1,1245 @@
+/*
+** kernel.c - Kernel module
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/hash.h>
+#include <mruby/class.h>
+#include <mruby/proc.h>
+#include <mruby/string.h>
+#include <mruby/variable.h>
+#include <mruby/error.h>
+#include <mruby/istruct.h>
+
+typedef enum {
+  NOEX_PUBLIC    = 0x00,
+  NOEX_NOSUPER   = 0x01,
+  NOEX_PRIVATE   = 0x02,
+  NOEX_PROTECTED = 0x04,
+  NOEX_MASK      = 0x06,
+  NOEX_BASIC     = 0x08,
+  NOEX_UNDEF     = NOEX_NOSUPER,
+  NOEX_MODFUNC   = 0x12,
+  NOEX_SUPER     = 0x20,
+  NOEX_VCALL     = 0x40,
+  NOEX_RESPONDS  = 0x80
+} mrb_method_flag_t;
+
+MRB_API mrb_bool
+mrb_func_basic_p(mrb_state *mrb, mrb_value obj, mrb_sym mid, mrb_func_t func)
+{
+  struct RProc *me = mrb_method_search(mrb, mrb_class(mrb, obj), mid);
+  if (MRB_PROC_CFUNC_P(me) && (me->body.func == func))
+    return TRUE;
+  return FALSE;
+}
+
+static mrb_bool
+mrb_obj_basic_to_s_p(mrb_state *mrb, mrb_value obj)
+{
+  return mrb_func_basic_p(mrb, obj, mrb_intern_lit(mrb, "to_s"), mrb_any_to_s);
+}
+
+/* 15.3.1.3.17 */
+/*
+ *  call-seq:
+ *     obj.inspect   -> string
+ *
+ *  Returns a string containing a human-readable representation of
+ *  <i>obj</i>. If not overridden and no instance variables, uses the
+ *  <code>to_s</code> method to generate the string.
+ *  <i>obj</i>.  If not overridden, uses the <code>to_s</code> method to
+ *  generate the string.
+ *
+ *     [ 1, 2, 3..4, 'five' ].inspect   #=> "[1, 2, 3..4, \"five\"]"
+ *     Time.new.inspect                 #=> "2008-03-08 19:43:39 +0900"
+ */
+MRB_API mrb_value
+mrb_obj_inspect(mrb_state *mrb, mrb_value obj)
+{
+  if ((mrb_type(obj) == MRB_TT_OBJECT) && mrb_obj_basic_to_s_p(mrb, obj)) {
+    return mrb_obj_iv_inspect(mrb, mrb_obj_ptr(obj));
+  }
+  return mrb_any_to_s(mrb, obj);
+}
+
+/* 15.3.1.3.2  */
+/*
+ *  call-seq:
+ *     obj === other   -> true or false
+ *
+ *  Case Equality---For class <code>Object</code>, effectively the same
+ *  as calling  <code>#==</code>, but typically overridden by descendants
+ *  to provide meaningful semantics in <code>case</code> statements.
+ */
+static mrb_value
+mrb_equal_m(mrb_state *mrb, mrb_value self)
+{
+  mrb_value arg;
+
+  mrb_get_args(mrb, "o", &arg);
+  return mrb_bool_value(mrb_equal(mrb, self, arg));
+}
+
+/* 15.3.1.3.3  */
+/* 15.3.1.3.33 */
+/*
+ *  Document-method: __id__
+ *  Document-method: object_id
+ *
+ *  call-seq:
+ *     obj.__id__       -> fixnum
+ *     obj.object_id    -> fixnum
+ *
+ *  Returns an integer identifier for <i>obj</i>. The same number will
+ *  be returned on all calls to <code>id</code> for a given object, and
+ *  no two active objects will share an id.
+ *  <code>Object#object_id</code> is a different concept from the
+ *  <code>:name</code> notation, which returns the symbol id of
+ *  <code>name</code>. Replaces the deprecated <code>Object#id</code>.
+ */
+mrb_value
+mrb_obj_id_m(mrb_state *mrb, mrb_value self)
+{
+  return mrb_fixnum_value(mrb_obj_id(self));
+}
+
+/* 15.3.1.2.2  */
+/* 15.3.1.2.5  */
+/* 15.3.1.3.6  */
+/* 15.3.1.3.25 */
+/*
+ *  call-seq:
+ *     block_given?   -> true or false
+ *     iterator?      -> true or false
+ *
+ *  Returns <code>true</code> if <code>yield</code> would execute a
+ *  block in the current context. The <code>iterator?</code> form
+ *  is mildly deprecated.
+ *
+ *     def try
+ *       if block_given?
+ *         yield
+ *       else
+ *         "no block"
+ *       end
+ *     end
+ *     try                  #=> "no block"
+ *     try { "hello" }      #=> "hello"
+ *     try do "hello" end   #=> "hello"
+ */
+static mrb_value
+mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self)
+{
+  mrb_callinfo *ci = mrb->c->ci;
+  mrb_value *bp;
+
+  bp = ci->stackent + 1;
+  ci--;
+  if (ci <= mrb->c->cibase) {
+    return mrb_false_value();
+  }
+  /* block_given? called within block; check upper scope */
+  if (ci->proc->env) {
+    struct REnv *e = ci->proc->env;
+
+    while (e->c) {
+      e = (struct REnv*)e->c;
+    }
+    /* top-level does not have block slot (always false) */
+    if (e->stack == mrb->c->stbase)
+      return mrb_false_value();
+    if (e->stack && e->cioff < 0) {
+      /* use saved block arg position */
+      bp = &e->stack[-e->cioff];
+      ci = 0;                 /* no callinfo available */
+    }
+    else {
+      ci = e->cxt.c->cibase + e->cioff;
+      bp = ci[1].stackent + 1;
+    }
+  }
+  if (ci && ci->argc > 0) {
+    bp += ci->argc;
+  }
+  if (mrb_nil_p(*bp))
+    return mrb_false_value();
+  return mrb_true_value();
+}
+
+/* 15.3.1.3.7  */
+/*
+ *  call-seq:
+ *     obj.class    -> class
+ *
+ *  Returns the class of <i>obj</i>. This method must always be
+ *  called with an explicit receiver, as <code>class</code> is also a
+ *  reserved word in Ruby.
+ *
+ *     1.class      #=> Fixnum
+ *     self.class   #=> Object
+ */
+static mrb_value
+mrb_obj_class_m(mrb_state *mrb, mrb_value self)
+{
+  return mrb_obj_value(mrb_obj_class(mrb, self));
+}
+
+static struct RClass*
+mrb_singleton_class_clone(mrb_state *mrb, mrb_value obj)
+{
+  struct RClass *klass = mrb_basic_ptr(obj)->c;
+
+  if (klass->tt != MRB_TT_SCLASS)
+    return klass;
+  else {
+    /* copy singleton(unnamed) class */
+    struct RClass *clone = (struct RClass*)mrb_obj_alloc(mrb, klass->tt, mrb->class_class);
+
+    switch (mrb_type(obj)) {
+    case MRB_TT_CLASS:
+    case MRB_TT_SCLASS:
+      break;
+    default:
+      clone->c = mrb_singleton_class_clone(mrb, mrb_obj_value(klass));
+      break;
+    }
+    clone->super = klass->super;
+    if (klass->iv) {
+      mrb_iv_copy(mrb, mrb_obj_value(clone), mrb_obj_value(klass));
+      mrb_obj_iv_set(mrb, (struct RObject*)clone, mrb_intern_lit(mrb, "__attached__"), obj);
+    }
+    if (klass->mt) {
+      clone->mt = kh_copy(mt, mrb, klass->mt);
+    }
+    else {
+      clone->mt = kh_init(mt, mrb);
+    }
+    clone->tt = MRB_TT_SCLASS;
+    return clone;
+  }
+}
+
+static void
+copy_class(mrb_state *mrb, mrb_value dst, mrb_value src)
+{
+  struct RClass *dc = mrb_class_ptr(dst);
+  struct RClass *sc = mrb_class_ptr(src);
+  /* if the origin is not the same as the class, then the origin and
+     the current class need to be copied */
+  if (sc->flags & MRB_FLAG_IS_PREPENDED) {
+    struct RClass *c0 = sc->super;
+    struct RClass *c1 = dc;
+
+    /* copy prepended iclasses */
+    while (!(c0->flags & MRB_FLAG_IS_ORIGIN)) {
+      c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0)));
+      c1 = c1->super;
+      c0 = c0->super;
+    }
+    c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0)));
+    c1->super->flags |= MRB_FLAG_IS_ORIGIN;
+  }
+  if (sc->mt) {
+    dc->mt = kh_copy(mt, mrb, sc->mt);
+  }
+  else {
+    dc->mt = kh_init(mt, mrb);
+  }
+  dc->super = sc->super;
+  MRB_SET_INSTANCE_TT(dc, MRB_INSTANCE_TT(sc));
+}
+
+static void
+init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj)
+{
+  switch (mrb_type(obj)) {
+    case MRB_TT_CLASS:
+    case MRB_TT_MODULE:
+      copy_class(mrb, dest, obj);
+      /* fall through */
+    case MRB_TT_OBJECT:
+    case MRB_TT_SCLASS:
+    case MRB_TT_HASH:
+    case MRB_TT_DATA:
+    case MRB_TT_EXCEPTION:
+      mrb_iv_copy(mrb, dest, obj);
+      break;
+    case MRB_TT_ISTRUCT:
+      mrb_istruct_copy(dest, obj);
+      break;
+
+    default:
+      break;
+  }
+  mrb_funcall(mrb, dest, "initialize_copy", 1, obj);
+}
+
+/* 15.3.1.3.8  */
+/*
+ *  call-seq:
+ *     obj.clone -> an_object
+ *
+ *  Produces a shallow copy of <i>obj</i>---the instance variables of
+ *  <i>obj</i> are copied, but not the objects they reference. Copies
+ *  the frozen state of <i>obj</i>. See also the discussion
+ *  under <code>Object#dup</code>.
+ *
+ *     class Klass
+ *        attr_accessor :str
+ *     end
+ *     s1 = Klass.new      #=> #<Klass:0x401b3a38>
+ *     s1.str = "Hello"    #=> "Hello"
+ *     s2 = s1.clone       #=> #<Klass:0x401b3998 @str="Hello">
+ *     s2.str[1,4] = "i"   #=> "i"
+ *     s1.inspect          #=> "#<Klass:0x401b3a38 @str=\"Hi\">"
+ *     s2.inspect          #=> "#<Klass:0x401b3998 @str=\"Hi\">"
+ *
+ *  This method may have class-specific behavior.  If so, that
+ *  behavior will be documented under the #+initialize_copy+ method of
+ *  the class.
+ *
+ *  Some Class(True False Nil Symbol Fixnum Float) Object  cannot clone.
+ */
+MRB_API mrb_value
+mrb_obj_clone(mrb_state *mrb, mrb_value self)
+{
+  struct RObject *p;
+  mrb_value clone;
+
+  if (mrb_immediate_p(self)) {
+    mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %S", self);
+  }
+  if (mrb_type(self) == MRB_TT_SCLASS) {
+    mrb_raise(mrb, E_TYPE_ERROR, "can't clone singleton class");
+  }
+  p = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self));
+  p->c = mrb_singleton_class_clone(mrb, self);
+  clone = mrb_obj_value(p);
+  init_copy(mrb, clone, self);
+
+  return clone;
+}
+
+/* 15.3.1.3.9  */
+/*
+ *  call-seq:
+ *     obj.dup -> an_object
+ *
+ *  Produces a shallow copy of <i>obj</i>---the instance variables of
+ *  <i>obj</i> are copied, but not the objects they reference.
+ *  <code>dup</code> copies the frozen state of <i>obj</i>. See also
+ *  the discussion under <code>Object#clone</code>. In general,
+ *  <code>clone</code> and <code>dup</code> may have different semantics
+ *  in descendant classes. While <code>clone</code> is used to duplicate
+ *  an object, including its internal state, <code>dup</code> typically
+ *  uses the class of the descendant object to create the new instance.
+ *
+ *  This method may have class-specific behavior.  If so, that
+ *  behavior will be documented under the #+initialize_copy+ method of
+ *  the class.
+ */
+
+MRB_API mrb_value
+mrb_obj_dup(mrb_state *mrb, mrb_value obj)
+{
+  struct RBasic *p;
+  mrb_value dup;
+
+  if (mrb_immediate_p(obj)) {
+    mrb_raisef(mrb, E_TYPE_ERROR, "can't dup %S", obj);
+  }
+  if (mrb_type(obj) == MRB_TT_SCLASS) {
+    mrb_raise(mrb, E_TYPE_ERROR, "can't dup singleton class");
+  }
+  p = mrb_obj_alloc(mrb, mrb_type(obj), mrb_obj_class(mrb, obj));
+  dup = mrb_obj_value(p);
+  init_copy(mrb, dup, obj);
+
+  return dup;
+}
+
+static mrb_value
+mrb_obj_extend(mrb_state *mrb, mrb_int argc, mrb_value *argv, mrb_value obj)
+{
+  mrb_int i;
+
+  if (argc == 0) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (at least 1)");
+  }
+  for (i = 0; i < argc; i++) {
+    mrb_check_type(mrb, argv[i], MRB_TT_MODULE);
+  }
+  while (argc--) {
+    mrb_funcall(mrb, argv[argc], "extend_object", 1, obj);
+    mrb_funcall(mrb, argv[argc], "extended", 1, obj);
+  }
+  return obj;
+}
+
+/* 15.3.1.3.13 */
+/*
+ *  call-seq:
+ *     obj.extend(module, ...)    -> obj
+ *
+ *  Adds to _obj_ the instance methods from each module given as a
+ *  parameter.
+ *
+ *     module Mod
+ *       def hello
+ *         "Hello from Mod.\n"
+ *       end
+ *     end
+ *
+ *     class Klass
+ *       def hello
+ *         "Hello from Klass.\n"
+ *       end
+ *     end
+ *
+ *     k = Klass.new
+ *     k.hello         #=> "Hello from Klass.\n"
+ *     k.extend(Mod)   #=> #<Klass:0x401b3bc8>
+ *     k.hello         #=> "Hello from Mod.\n"
+ */
+static mrb_value
+mrb_obj_extend_m(mrb_state *mrb, mrb_value self)
+{
+  mrb_value *argv;
+  mrb_int argc;
+  mrb_value args;
+
+  mrb_get_args(mrb, "*", &argv, &argc);
+  args = mrb_ary_new_from_values(mrb, argc, argv);
+  argv = (mrb_value*)RARRAY_PTR(args);
+  return mrb_obj_extend(mrb, argc, argv, self);
+}
+
+static mrb_value
+mrb_obj_freeze(mrb_state *mrb, mrb_value self)
+{
+  struct RBasic *b;
+
+  switch (mrb_type(self)) {
+    case MRB_TT_FALSE:
+    case MRB_TT_TRUE:
+    case MRB_TT_FIXNUM:
+    case MRB_TT_SYMBOL:
+    case MRB_TT_FLOAT:
+      return self;
+    default:
+      break;
+  }
+
+  b = mrb_basic_ptr(self);
+  if (!MRB_FROZEN_P(b)) {
+    MRB_SET_FROZEN_FLAG(b);
+  }
+  return self;
+}
+
+static mrb_value
+mrb_obj_frozen(mrb_state *mrb, mrb_value self)
+{
+  struct RBasic *b;
+
+  switch (mrb_type(self)) {
+    case MRB_TT_FALSE:
+    case MRB_TT_TRUE:
+    case MRB_TT_FIXNUM:
+    case MRB_TT_SYMBOL:
+    case MRB_TT_FLOAT:
+      return mrb_true_value();
+    default:
+      break;
+  }
+
+  b = mrb_basic_ptr(self);
+  if (!MRB_FROZEN_P(b)) {
+    return mrb_false_value();
+  }
+  return mrb_true_value();
+}
+
+/* 15.3.1.3.15 */
+/*
+ *  call-seq:
+ *     obj.hash    -> fixnum
+ *
+ *  Generates a <code>Fixnum</code> hash value for this object. This
+ *  function must have the property that <code>a.eql?(b)</code> implies
+ *  <code>a.hash == b.hash</code>. The hash value is used by class
+ *  <code>Hash</code>. Any hash value that exceeds the capacity of a
+ *  <code>Fixnum</code> will be truncated before being used.
+ */
+MRB_API mrb_value
+mrb_obj_hash(mrb_state *mrb, mrb_value self)
+{
+  return mrb_fixnum_value(mrb_obj_id(self));
+}
+
+/* 15.3.1.3.16 */
+static mrb_value
+mrb_obj_init_copy(mrb_state *mrb, mrb_value self)
+{
+  mrb_value orig;
+
+  mrb_get_args(mrb, "o", &orig);
+  if (mrb_obj_equal(mrb, self, orig)) return self;
+  if ((mrb_type(self) != mrb_type(orig)) || (mrb_obj_class(mrb, self) != mrb_obj_class(mrb, orig))) {
+      mrb_raise(mrb, E_TYPE_ERROR, "initialize_copy should take same class object");
+  }
+  return self;
+}
+
+
+MRB_API mrb_bool
+mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c)
+{
+  if (mrb_obj_class(mrb, obj) == c) return TRUE;
+  return FALSE;
+}
+
+/* 15.3.1.3.19 */
+/*
+ *  call-seq:
+ *     obj.instance_of?(class)    -> true or false
+ *
+ *  Returns <code>true</code> if <i>obj</i> is an instance of the given
+ *  class. See also <code>Object#kind_of?</code>.
+ */
+static mrb_value
+obj_is_instance_of(mrb_state *mrb, mrb_value self)
+{
+  mrb_value arg;
+
+  mrb_get_args(mrb, "C", &arg);
+
+  return mrb_bool_value(mrb_obj_is_instance_of(mrb, self, mrb_class_ptr(arg)));
+}
+
+/* 15.3.1.3.20 */
+/*
+ *  call-seq:
+ *     obj.instance_variable_defined?(symbol)    -> true or false
+ *
+ *  Returns <code>true</code> if the given instance variable is
+ *  defined in <i>obj</i>.
+ *
+ *     class Fred
+ *       def initialize(p1, p2)
+ *         @a, @b = p1, p2
+ *       end
+ *     end
+ *     fred = Fred.new('cat', 99)
+ *     fred.instance_variable_defined?(:@a)    #=> true
+ *     fred.instance_variable_defined?("@b")   #=> true
+ *     fred.instance_variable_defined?("@c")   #=> false
+ */
+static mrb_value
+mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self)
+{
+  mrb_sym sym;
+
+  mrb_get_args(mrb, "n", &sym);
+  mrb_iv_check(mrb, sym);
+  return mrb_bool_value(mrb_iv_defined(mrb, self, sym));
+}
+
+/* 15.3.1.3.21 */
+/*
+ *  call-seq:
+ *     obj.instance_variable_get(symbol)    -> obj
+ *
+ *  Returns the value of the given instance variable, or nil if the
+ *  instance variable is not set. The <code>@</code> part of the
+ *  variable name should be included for regular instance
+ *  variables. Throws a <code>NameError</code> exception if the
+ *  supplied symbol is not valid as an instance variable name.
+ *
+ *     class Fred
+ *       def initialize(p1, p2)
+ *         @a, @b = p1, p2
+ *       end
+ *     end
+ *     fred = Fred.new('cat', 99)
+ *     fred.instance_variable_get(:@a)    #=> "cat"
+ *     fred.instance_variable_get("@b")   #=> 99
+ */
+static mrb_value
+mrb_obj_ivar_get(mrb_state *mrb, mrb_value self)
+{
+  mrb_sym iv_name;
+
+  mrb_get_args(mrb, "n", &iv_name);
+  mrb_iv_check(mrb, iv_name);
+  return mrb_iv_get(mrb, self, iv_name);
+}
+
+/* 15.3.1.3.22 */
+/*
+ *  call-seq:
+ *     obj.instance_variable_set(symbol, obj)    -> obj
+ *
+ *  Sets the instance variable names by <i>symbol</i> to
+ *  <i>object</i>, thereby frustrating the efforts of the class's
+ *  author to attempt to provide proper encapsulation. The variable
+ *  did not have to exist prior to this call.
+ *
+ *     class Fred
+ *       def initialize(p1, p2)
+ *         @a, @b = p1, p2
+ *       end
+ *     end
+ *     fred = Fred.new('cat', 99)
+ *     fred.instance_variable_set(:@a, 'dog')   #=> "dog"
+ *     fred.instance_variable_set(:@c, 'cat')   #=> "cat"
+ *     fred.inspect                             #=> "#<Fred:0x401b3da8 @a=\"dog\", @b=99, @c=\"cat\">"
+ */
+static mrb_value
+mrb_obj_ivar_set(mrb_state *mrb, mrb_value self)
+{
+  mrb_sym iv_name;
+  mrb_value val;
+
+  mrb_get_args(mrb, "no", &iv_name, &val);
+  mrb_iv_check(mrb, iv_name);
+  mrb_iv_set(mrb, self, iv_name, val);
+  return val;
+}
+
+/* 15.3.1.3.24 */
+/* 15.3.1.3.26 */
+/*
+ *  call-seq:
+ *     obj.is_a?(class)       -> true or false
+ *     obj.kind_of?(class)    -> true or false
+ *
+ *  Returns <code>true</code> if <i>class</i> is the class of
+ *  <i>obj</i>, or if <i>class</i> is one of the superclasses of
+ *  <i>obj</i> or modules included in <i>obj</i>.
+ *
+ *     module M;    end
+ *     class A
+ *       include M
+ *     end
+ *     class B < A; end
+ *     class C < B; end
+ *     b = B.new
+ *     b.instance_of? A   #=> false
+ *     b.instance_of? B   #=> true
+ *     b.instance_of? C   #=> false
+ *     b.instance_of? M   #=> false
+ *     b.kind_of? A       #=> true
+ *     b.kind_of? B       #=> true
+ *     b.kind_of? C       #=> false
+ *     b.kind_of? M       #=> true
+ */
+static mrb_value
+mrb_obj_is_kind_of_m(mrb_state *mrb, mrb_value self)
+{
+  mrb_value arg;
+
+  mrb_get_args(mrb, "C", &arg);
+
+  return mrb_bool_value(mrb_obj_is_kind_of(mrb, self, mrb_class_ptr(arg)));
+}
+
+KHASH_DECLARE(st, mrb_sym, char, FALSE)
+KHASH_DEFINE(st, mrb_sym, char, FALSE, kh_int_hash_func, kh_int_hash_equal)
+
+static void
+method_entry_loop(mrb_state *mrb, struct RClass* klass, khash_t(st)* set)
+{
+  khint_t i;
+
+  khash_t(mt) *h = klass->mt;
+  if (!h) return;
+  for (i=0;i<kh_end(h);i++) {
+    if (kh_exist(h, i) && kh_value(h, i)) {
+      kh_put(st, mrb, set, kh_key(h, i));
+    }
+  }
+}
+
+mrb_value
+mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* klass, int obj)
+{
+  khint_t i;
+  mrb_value ary;
+  mrb_bool prepended = FALSE;
+  struct RClass* oldklass;
+  khash_t(st)* set = kh_init(st, mrb);
+
+  if (!recur && (klass->flags & MRB_FLAG_IS_PREPENDED)) {
+    MRB_CLASS_ORIGIN(klass);
+    prepended = TRUE;
+  }
+
+  oldklass = 0;
+  while (klass && (klass != oldklass)) {
+    method_entry_loop(mrb, klass, set);
+    if ((klass->tt == MRB_TT_ICLASS && !prepended) ||
+        (klass->tt == MRB_TT_SCLASS)) {
+    }
+    else {
+      if (!recur) break;
+    }
+    oldklass = klass;
+    klass = klass->super;
+  }
+
+  ary = mrb_ary_new(mrb);
+  for (i=0;i<kh_end(set);i++) {
+    if (kh_exist(set, i)) {
+      mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i)));
+    }
+  }
+  kh_destroy(st, mrb, set);
+
+  return ary;
+}
+
+static mrb_value
+mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj)
+{
+  khint_t i;
+  mrb_value ary;
+  struct RClass* klass;
+  khash_t(st)* set = kh_init(st, mrb);
+
+  klass = mrb_class(mrb, obj);
+
+  if (klass && (klass->tt == MRB_TT_SCLASS)) {
+      method_entry_loop(mrb, klass, set);
+      klass = klass->super;
+  }
+  if (recur) {
+      while (klass && ((klass->tt == MRB_TT_SCLASS) || (klass->tt == MRB_TT_ICLASS))) {
+        method_entry_loop(mrb, klass, set);
+        klass = klass->super;
+      }
+  }
+
+  ary = mrb_ary_new(mrb);
+  for (i=0;i<kh_end(set);i++) {
+    if (kh_exist(set, i)) {
+      mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i)));
+    }
+  }
+  kh_destroy(st, mrb, set);
+
+  return ary;
+}
+
+static mrb_value
+mrb_obj_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj, mrb_method_flag_t flag)
+{
+  return mrb_class_instance_method_list(mrb, recur, mrb_class(mrb, obj), 0);
+}
+/* 15.3.1.3.31 */
+/*
+ *  call-seq:
+ *     obj.methods    -> array
+ *
+ *  Returns a list of the names of methods publicly accessible in
+ *  <i>obj</i>. This will include all the methods accessible in
+ *  <i>obj</i>'s ancestors.
+ *
+ *     class Klass
+ *       def kMethod()
+ *       end
+ *     end
+ *     k = Klass.new
+ *     k.methods[0..9]    #=> [:kMethod, :respond_to?, :nil?, :is_a?,
+ *                        #    :class, :instance_variable_set,
+ *                        #    :methods, :extend, :__send__, :instance_eval]
+ *     k.methods.length   #=> 42
+ */
+static mrb_value
+mrb_obj_methods_m(mrb_state *mrb, mrb_value self)
+{
+  mrb_bool recur = TRUE;
+  mrb_get_args(mrb, "|b", &recur);
+  return mrb_obj_methods(mrb, recur, self, (mrb_method_flag_t)0); /* everything but private */
+}
+
+/* 15.3.1.3.32 */
+/*
+ * call_seq:
+ *   nil.nil?               -> true
+ *   <anything_else>.nil?   -> false
+ *
+ * Only the object <i>nil</i> responds <code>true</code> to <code>nil?</code>.
+ */
+static mrb_value
+mrb_false(mrb_state *mrb, mrb_value self)
+{
+  return mrb_false_value();
+}
+
+/* 15.3.1.3.36 */
+/*
+ *  call-seq:
+ *     obj.private_methods(all=true)   -> array
+ *
+ *  Returns the list of private methods accessible to <i>obj</i>. If
+ *  the <i>all</i> parameter is set to <code>false</code>, only those methods
+ *  in the receiver will be listed.
+ */
+static mrb_value
+mrb_obj_private_methods(mrb_state *mrb, mrb_value self)
+{
+  mrb_bool recur = TRUE;
+  mrb_get_args(mrb, "|b", &recur);
+  return mrb_obj_methods(mrb, recur, self, NOEX_PRIVATE); /* private attribute not define */
+}
+
+/* 15.3.1.3.37 */
+/*
+ *  call-seq:
+ *     obj.protected_methods(all=true)   -> array
+ *
+ *  Returns the list of protected methods accessible to <i>obj</i>. If
+ *  the <i>all</i> parameter is set to <code>false</code>, only those methods
+ *  in the receiver will be listed.
+ */
+static mrb_value
+mrb_obj_protected_methods(mrb_state *mrb, mrb_value self)
+{
+  mrb_bool recur = TRUE;
+  mrb_get_args(mrb, "|b", &recur);
+  return mrb_obj_methods(mrb, recur, self, NOEX_PROTECTED); /* protected attribute not define */
+}
+
+/* 15.3.1.3.38 */
+/*
+ *  call-seq:
+ *     obj.public_methods(all=true)   -> array
+ *
+ *  Returns the list of public methods accessible to <i>obj</i>. If
+ *  the <i>all</i> parameter is set to <code>false</code>, only those methods
+ *  in the receiver will be listed.
+ */
+static mrb_value
+mrb_obj_public_methods(mrb_state *mrb, mrb_value self)
+{
+  mrb_bool recur = TRUE;
+  mrb_get_args(mrb, "|b", &recur);
+  return mrb_obj_methods(mrb, recur, self, NOEX_PUBLIC); /* public attribute not define */
+}
+
+/* 15.3.1.2.12  */
+/* 15.3.1.3.40 */
+/*
+ *  call-seq:
+ *     raise
+ *     raise(string)
+ *     raise(exception [, string])
+ *
+ *  With no arguments, raises a <code>RuntimeError</code>
+ *  With a single +String+ argument, raises a
+ *  +RuntimeError+ with the string as a message. Otherwise,
+ *  the first parameter should be the name of an +Exception+
+ *  class (or an object that returns an +Exception+ object when sent
+ *  an +exception+ message). The optional second parameter sets the
+ *  message associated with the exception, and the third parameter is an
+ *  array of callback information. Exceptions are caught by the
+ *  +rescue+ clause of <code>begin...end</code> blocks.
+ *
+ *     raise "Failed to create socket"
+ *     raise ArgumentError, "No parameters", caller
+ */
+MRB_API mrb_value
+mrb_f_raise(mrb_state *mrb, mrb_value self)
+{
+  mrb_value a[2], exc;
+  int argc;
+
+
+  argc = mrb_get_args(mrb, "|oo", &a[0], &a[1]);
+  switch (argc) {
+  case 0:
+    mrb_raise(mrb, E_RUNTIME_ERROR, "");
+    break;
+  case 1:
+    if (mrb_string_p(a[0])) {
+      a[1] = a[0];
+      argc = 2;
+      a[0] = mrb_obj_value(E_RUNTIME_ERROR);
+    }
+    /* fall through */
+  default:
+    exc = mrb_make_exception(mrb, argc, a);
+    mrb_exc_raise(mrb, exc);
+    break;
+  }
+  return mrb_nil_value();            /* not reached */
+}
+
+/* 15.3.1.3.41 */
+/*
+ *  call-seq:
+ *     obj.remove_instance_variable(symbol)    -> obj
+ *
+ *  Removes the named instance variable from <i>obj</i>, returning that
+ *  variable's value.
+ *
+ *     class Dummy
+ *       attr_reader :var
+ *       def initialize
+ *         @var = 99
+ *       end
+ *       def remove
+ *         remove_instance_variable(:@var)
+ *       end
+ *     end
+ *     d = Dummy.new
+ *     d.var      #=> 99
+ *     d.remove   #=> 99
+ *     d.var      #=> nil
+ */
+static mrb_value
+mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self)
+{
+  mrb_sym sym;
+  mrb_value val;
+
+  mrb_get_args(mrb, "n", &sym);
+  mrb_iv_check(mrb, sym);
+  val = mrb_iv_remove(mrb, self, sym);
+  if (mrb_undef_p(val)) {
+    mrb_name_error(mrb, sym, "instance variable %S not defined", mrb_sym2str(mrb, sym));
+  }
+  return val;
+}
+
+void
+mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args)
+{
+  mrb_sym inspect;
+  mrb_value repr;
+
+  inspect = mrb_intern_lit(mrb, "inspect");
+  if (mrb->c->ci > mrb->c->cibase && mrb->c->ci[-1].mid == inspect) {
+    /* method missing in inspect; avoid recursion */
+    repr = mrb_any_to_s(mrb, self);
+  }
+  else if (mrb_respond_to(mrb, self, inspect) && mrb->c->ci - mrb->c->cibase < 16) {
+    repr = mrb_funcall_argv(mrb, self, inspect, 0, 0);
+    if (mrb_string_p(repr) && RSTRING_LEN(repr) > 64) {
+      repr = mrb_any_to_s(mrb, self);
+    }
+  }
+  else {
+    repr = mrb_any_to_s(mrb, self);
+  }
+
+  mrb_no_method_error(mrb, name, args, "undefined method '%S' for %S",
+                      mrb_sym2str(mrb, name), repr);
+}
+
+/* 15.3.1.3.30 */
+/*
+ *  call-seq:
+ *     obj.method_missing(symbol [, *args] )   -> result
+ *
+ *  Invoked by Ruby when <i>obj</i> is sent a message it cannot handle.
+ *  <i>symbol</i> is the symbol for the method called, and <i>args</i>
+ *  are any arguments that were passed to it. By default, the interpreter
+ *  raises an error when this method is called. However, it is possible
+ *  to override the method to provide more dynamic behavior.
+ *  If it is decided that a particular method should not be handled, then
+ *  <i>super</i> should be called, so that ancestors can pick up the
+ *  missing method.
+ *  The example below creates
+ *  a class <code>Roman</code>, which responds to methods with names
+ *  consisting of roman numerals, returning the corresponding integer
+ *  values.
+ *
+ *     class Roman
+ *       def romanToInt(str)
+ *         # ...
+ *       end
+ *       def method_missing(methId)
+ *         str = methId.id2name
+ *         romanToInt(str)
+ *       end
+ *     end
+ *
+ *     r = Roman.new
+ *     r.iv      #=> 4
+ *     r.xxiii   #=> 23
+ *     r.mm      #=> 2000
+ */
+#ifdef MRB_DEFAULT_METHOD_MISSING
+static mrb_value
+mrb_obj_missing(mrb_state *mrb, mrb_value mod)
+{
+  mrb_sym name;
+  mrb_value *a;
+  mrb_int alen;
+
+  mrb_get_args(mrb, "n*", &name, &a, &alen);
+  mrb_method_missing(mrb, name, mod, mrb_ary_new_from_values(mrb, alen, a));
+  /* not reached */
+  return mrb_nil_value();
+}
+#endif
+
+static inline mrb_bool
+basic_obj_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym id, int pub)
+{
+  return mrb_respond_to(mrb, obj, id);
+}
+/* 15.3.1.3.43 */
+/*
+ *  call-seq:
+ *     obj.respond_to?(symbol, include_private=false) -> true or false
+ *
+ *  Returns +true+ if _obj_ responds to the given
+ *  method. Private methods are included in the search only if the
+ *  optional second parameter evaluates to +true+.
+ *
+ *  If the method is not implemented,
+ *  as Process.fork on Windows, File.lchmod on GNU/Linux, etc.,
+ *  false is returned.
+ *
+ *  If the method is not defined, <code>respond_to_missing?</code>
+ *  method is called and the result is returned.
+ */
+static mrb_value
+obj_respond_to(mrb_state *mrb, mrb_value self)
+{
+  mrb_value mid;
+  mrb_sym id, rtm_id;
+  mrb_bool priv = FALSE, respond_to_p = TRUE;
+
+  mrb_get_args(mrb, "o|b", &mid, &priv);
+
+  if (mrb_symbol_p(mid)) {
+    id = mrb_symbol(mid);
+  }
+  else {
+    mrb_value tmp;
+    if (mrb_string_p(mid)) {
+      tmp = mrb_check_intern_str(mrb, mid);
+    }
+    else {
+      tmp = mrb_check_string_type(mrb, mid);
+      if (mrb_nil_p(tmp)) {
+        tmp = mrb_inspect(mrb, mid);
+        mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", tmp);
+      }
+      tmp = mrb_check_intern_str(mrb, tmp);
+    }
+    if (mrb_nil_p(tmp)) {
+      respond_to_p = FALSE;
+    }
+    else {
+      id = mrb_symbol(tmp);
+    }
+  }
+
+  if (respond_to_p) {
+    respond_to_p = basic_obj_respond_to(mrb, self, id, !priv);
+  }
+
+  if (!respond_to_p) {
+    rtm_id = mrb_intern_lit(mrb, "respond_to_missing?");
+    if (basic_obj_respond_to(mrb, self, rtm_id, !priv)) {
+      mrb_value args[2], v;
+      args[0] = mid;
+      args[1] = mrb_bool_value(priv);
+      v = mrb_funcall_argv(mrb, self, rtm_id, 2, args);
+      return mrb_bool_value(mrb_bool(v));
+    }
+  }
+  return mrb_bool_value(respond_to_p);
+}
+
+/* 15.3.1.3.45 */
+/*
+ *  call-seq:
+ *     obj.singleton_methods(all=true)    -> array
+ *
+ *  Returns an array of the names of singleton methods for <i>obj</i>.
+ *  If the optional <i>all</i> parameter is true, the list will include
+ *  methods in modules included in <i>obj</i>.
+ *  Only public and protected singleton methods are returned.
+ *
+ *     module Other
+ *       def three() end
+ *     end
+ *
+ *     class Single
+ *       def Single.four() end
+ *     end
+ *
+ *     a = Single.new
+ *
+ *     def a.one()
+ *     end
+ *
+ *     class << a
+ *       include Other
+ *       def two()
+ *       end
+ *     end
+ *
+ *     Single.singleton_methods    #=> [:four]
+ *     a.singleton_methods(false)  #=> [:two, :one]
+ *     a.singleton_methods         #=> [:two, :one, :three]
+ */
+static mrb_value
+mrb_obj_singleton_methods_m(mrb_state *mrb, mrb_value self)
+{
+  mrb_bool recur = TRUE;
+  mrb_get_args(mrb, "|b", &recur);
+  return mrb_obj_singleton_methods(mrb, recur, self);
+}
+
+static mrb_value
+mod_define_singleton_method(mrb_state *mrb, mrb_value self)
+{
+  struct RProc *p;
+  mrb_sym mid;
+  mrb_value blk = mrb_nil_value();
+
+  mrb_get_args(mrb, "n&", &mid, &blk);
+  if (mrb_nil_p(blk)) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
+  }
+  p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
+  mrb_proc_copy(p, mrb_proc_ptr(blk));
+  p->flags |= MRB_PROC_STRICT;
+  mrb_define_method_raw(mrb, mrb_class_ptr(mrb_singleton_class(mrb, self)), mid, p);
+  return mrb_symbol_value(mid);
+}
+
+static mrb_value
+mrb_obj_ceqq(mrb_state *mrb, mrb_value self)
+{
+  mrb_value v;
+  mrb_int i, len;
+  mrb_sym eqq = mrb_intern_lit(mrb, "===");
+  mrb_value ary = mrb_ary_splat(mrb, self);
+
+  mrb_get_args(mrb, "o", &v);
+  len = RARRAY_LEN(ary);
+  for (i=0; i<len; i++) {
+    mrb_value c = mrb_funcall_argv(mrb, mrb_ary_entry(ary, i), eqq, 1, &v);
+    if (mrb_test(c)) return mrb_true_value();
+  }
+  return mrb_false_value();
+}
+
+static mrb_value
+mrb_local_variables(mrb_state *mrb, mrb_value self)
+{
+  struct RProc *proc;
+  mrb_value vars;
+  struct mrb_irep *irep;
+  size_t i;
+
+  proc = mrb->c->ci[-1].proc;
+
+  if (MRB_PROC_CFUNC_P(proc)) {
+    return mrb_ary_new(mrb);
+  }
+
+  irep = proc->body.irep;
+  if (!irep->lv) {
+    return mrb_ary_new(mrb);
+  }
+  vars = mrb_hash_new(mrb);
+  for (i = 0; i + 1 < irep->nlocals; ++i) {
+    if (irep->lv[i].name) {
+      mrb_hash_set(mrb, vars, mrb_symbol_value(irep->lv[i].name), mrb_true_value());
+    }
+  }
+  if (proc->env) {
+    struct REnv *e = proc->env;
+
+    while (e) {
+      if (MRB_ENV_STACK_SHARED_P(e) &&
+          !MRB_PROC_CFUNC_P(e->cxt.c->cibase[e->cioff].proc)) {
+        irep = e->cxt.c->cibase[e->cioff].proc->body.irep;
+        if (irep->lv) {
+          for (i = 0; i + 1 < irep->nlocals; ++i) {
+            if (irep->lv[i].name) {
+              mrb_hash_set(mrb, vars, mrb_symbol_value(irep->lv[i].name), mrb_true_value());
+            }
+          }
+        }
+      }
+      e = (struct REnv*)e->c;
+    }
+  }
+
+  return mrb_hash_keys(mrb, vars);
+}
+
+mrb_value mrb_obj_equal_m(mrb_state *mrb, mrb_value);
+void
+mrb_init_kernel(mrb_state *mrb)
+{
+  struct RClass *krn;
+
+  mrb->kernel_module = krn = mrb_define_module(mrb, "Kernel");                                                    /* 15.3.1 */
+  mrb_define_class_method(mrb, krn, "block_given?",         mrb_f_block_given_p_m,           MRB_ARGS_NONE());    /* 15.3.1.2.2  */
+  mrb_define_class_method(mrb, krn, "global_variables",     mrb_f_global_variables,          MRB_ARGS_NONE());    /* 15.3.1.2.4  */
+  mrb_define_class_method(mrb, krn, "iterator?",            mrb_f_block_given_p_m,           MRB_ARGS_NONE());    /* 15.3.1.2.5  */
+  mrb_define_class_method(mrb, krn, "local_variables",      mrb_local_variables,             MRB_ARGS_NONE());    /* 15.3.1.2.7  */
+;     /* 15.3.1.2.11 */
+  mrb_define_class_method(mrb, krn, "raise",                mrb_f_raise,                     MRB_ARGS_OPT(2));    /* 15.3.1.2.12 */
+
+  mrb_define_method(mrb, krn, "singleton_class",            mrb_singleton_class,             MRB_ARGS_NONE());
+
+  mrb_define_method(mrb, krn, "===",                        mrb_equal_m,                     MRB_ARGS_REQ(1));    /* 15.3.1.3.2  */
+  mrb_define_method(mrb, krn, "block_given?",               mrb_f_block_given_p_m,           MRB_ARGS_NONE());    /* 15.3.1.3.6  */
+  mrb_define_method(mrb, krn, "class",                      mrb_obj_class_m,                 MRB_ARGS_NONE());    /* 15.3.1.3.7  */
+  mrb_define_method(mrb, krn, "clone",                      mrb_obj_clone,                   MRB_ARGS_NONE());    /* 15.3.1.3.8  */
+  mrb_define_method(mrb, krn, "dup",                        mrb_obj_dup,                     MRB_ARGS_NONE());    /* 15.3.1.3.9  */
+  mrb_define_method(mrb, krn, "eql?",                       mrb_obj_equal_m,                 MRB_ARGS_REQ(1));    /* 15.3.1.3.10 */
+  mrb_define_method(mrb, krn, "equal?",                     mrb_obj_equal_m,                 MRB_ARGS_REQ(1));    /* 15.3.1.3.11 */
+  mrb_define_method(mrb, krn, "extend",                     mrb_obj_extend_m,                MRB_ARGS_ANY());     /* 15.3.1.3.13 */
+  mrb_define_method(mrb, krn, "freeze",                     mrb_obj_freeze,                  MRB_ARGS_NONE());
+  mrb_define_method(mrb, krn, "frozen?",                    mrb_obj_frozen,                  MRB_ARGS_NONE());
+  mrb_define_method(mrb, krn, "global_variables",           mrb_f_global_variables,          MRB_ARGS_NONE());    /* 15.3.1.3.14 */
+  mrb_define_method(mrb, krn, "hash",                       mrb_obj_hash,                    MRB_ARGS_NONE());    /* 15.3.1.3.15 */
+  mrb_define_method(mrb, krn, "initialize_copy",            mrb_obj_init_copy,               MRB_ARGS_REQ(1));    /* 15.3.1.3.16 */
+  mrb_define_method(mrb, krn, "inspect",                    mrb_obj_inspect,                 MRB_ARGS_NONE());    /* 15.3.1.3.17 */
+  mrb_define_method(mrb, krn, "instance_of?",               obj_is_instance_of,              MRB_ARGS_REQ(1));    /* 15.3.1.3.19 */
+  mrb_define_method(mrb, krn, "instance_variable_defined?", mrb_obj_ivar_defined,            MRB_ARGS_REQ(1));    /* 15.3.1.3.20 */
+  mrb_define_method(mrb, krn, "instance_variable_get",      mrb_obj_ivar_get,                MRB_ARGS_REQ(1));    /* 15.3.1.3.21 */
+  mrb_define_method(mrb, krn, "instance_variable_set",      mrb_obj_ivar_set,                MRB_ARGS_REQ(2));    /* 15.3.1.3.22 */
+  mrb_define_method(mrb, krn, "instance_variables",         mrb_obj_instance_variables,      MRB_ARGS_NONE());    /* 15.3.1.3.23 */
+  mrb_define_method(mrb, krn, "is_a?",                      mrb_obj_is_kind_of_m,            MRB_ARGS_REQ(1));    /* 15.3.1.3.24 */
+  mrb_define_method(mrb, krn, "iterator?",                  mrb_f_block_given_p_m,           MRB_ARGS_NONE());    /* 15.3.1.3.25 */
+  mrb_define_method(mrb, krn, "kind_of?",                   mrb_obj_is_kind_of_m,            MRB_ARGS_REQ(1));    /* 15.3.1.3.26 */
+  mrb_define_method(mrb, krn, "local_variables",            mrb_local_variables,             MRB_ARGS_NONE());    /* 15.3.1.3.28 */
+#ifdef MRB_DEFAULT_METHOD_MISSING
+  mrb_define_method(mrb, krn, "method_missing",             mrb_obj_missing,                 MRB_ARGS_ANY());     /* 15.3.1.3.30 */
+#endif
+  mrb_define_method(mrb, krn, "methods",                    mrb_obj_methods_m,               MRB_ARGS_OPT(1));    /* 15.3.1.3.31 */
+  mrb_define_method(mrb, krn, "nil?",                       mrb_false,                       MRB_ARGS_NONE());    /* 15.3.1.3.32 */
+  mrb_define_method(mrb, krn, "object_id",                  mrb_obj_id_m,                    MRB_ARGS_NONE());    /* 15.3.1.3.33 */
+  mrb_define_method(mrb, krn, "private_methods",            mrb_obj_private_methods,         MRB_ARGS_OPT(1));    /* 15.3.1.3.36 */
+  mrb_define_method(mrb, krn, "protected_methods",          mrb_obj_protected_methods,       MRB_ARGS_OPT(1));    /* 15.3.1.3.37 */
+  mrb_define_method(mrb, krn, "public_methods",             mrb_obj_public_methods,          MRB_ARGS_OPT(1));    /* 15.3.1.3.38 */
+  mrb_define_method(mrb, krn, "raise",                      mrb_f_raise,                     MRB_ARGS_ANY());     /* 15.3.1.3.40 */
+  mrb_define_method(mrb, krn, "remove_instance_variable",   mrb_obj_remove_instance_variable,MRB_ARGS_REQ(1));    /* 15.3.1.3.41 */
+  mrb_define_method(mrb, krn, "respond_to?",                obj_respond_to,                  MRB_ARGS_ANY());     /* 15.3.1.3.43 */
+  mrb_define_method(mrb, krn, "send",                       mrb_f_send,                      MRB_ARGS_ANY());     /* 15.3.1.3.44 */
+  mrb_define_method(mrb, krn, "singleton_methods",          mrb_obj_singleton_methods_m,     MRB_ARGS_OPT(1));    /* 15.3.1.3.45 */
+  mrb_define_method(mrb, krn, "define_singleton_method",    mod_define_singleton_method,     MRB_ARGS_ANY());
+  mrb_define_method(mrb, krn, "to_s",                       mrb_any_to_s,                    MRB_ARGS_NONE());    /* 15.3.1.3.46 */
+  mrb_define_method(mrb, krn, "__case_eqq",                 mrb_obj_ceqq,                    MRB_ARGS_REQ(1));    /* internal */
+
+  mrb_include_module(mrb, mrb->object_class, mrb->kernel_module);
+  mrb_alias_method(mrb, mrb->module_class, mrb_intern_lit(mrb, "dup"), mrb_intern_lit(mrb, "clone"));
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/load.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/load.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/load.c	(revision 331)
@@ -0,0 +1,709 @@
+/*
+** load.c - mruby binary loader
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mruby/dump.h>
+#include <mruby/irep.h>
+#include <mruby/proc.h>
+#include <mruby/string.h>
+#include <mruby/debug.h>
+#include <mruby/error.h>
+
+#if SIZE_MAX < UINT32_MAX
+# error size_t must be at least 32 bits wide
+#endif
+
+#define FLAG_BYTEORDER_BIG 2
+#define FLAG_BYTEORDER_LIL 4
+#define FLAG_BYTEORDER_NATIVE 8
+#define FLAG_SRC_MALLOC 1
+#define FLAG_SRC_STATIC 0
+
+#define SIZE_ERROR_MUL(nmemb, size) ((nmemb) > SIZE_MAX / (size))
+
+static size_t
+skip_padding(const uint8_t *buf)
+{
+  const size_t align = MRB_DUMP_ALIGNMENT;
+  return -(intptr_t)buf & (align-1);
+}
+
+static size_t
+offset_crc_body(void)
+{
+  struct rite_binary_header header;
+  return ((uint8_t *)header.binary_crc - (uint8_t *)&header) + sizeof(header.binary_crc);
+}
+
+static mrb_irep*
+read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags)
+{
+  size_t i;
+  const uint8_t *src = bin;
+  ptrdiff_t diff;
+  uint16_t tt, pool_data_len, snl;
+  size_t plen;
+  int ai = mrb_gc_arena_save(mrb);
+  mrb_irep *irep = mrb_add_irep(mrb);
+
+  /* skip record size */
+  src += sizeof(uint32_t);
+
+  /* number of local variable */
+  irep->nlocals = bin_to_uint16(src);
+  src += sizeof(uint16_t);
+
+  /* number of register variable */
+  irep->nregs = bin_to_uint16(src);
+  src += sizeof(uint16_t);
+
+  /* number of child irep */
+  irep->rlen = (size_t)bin_to_uint16(src);
+  src += sizeof(uint16_t);
+
+  /* Binary Data Section */
+  /* ISEQ BLOCK */
+  irep->ilen = (size_t)bin_to_uint32(src);
+  src += sizeof(uint32_t);
+  src += skip_padding(src);
+
+  if (irep->ilen > 0) {
+    if (SIZE_ERROR_MUL(irep->ilen, sizeof(mrb_code))) {
+      return NULL;
+    }
+    if ((flags & FLAG_SRC_MALLOC) == 0 &&
+        (flags & FLAG_BYTEORDER_NATIVE)) {
+      irep->iseq = (mrb_code*)src;
+      src += sizeof(uint32_t) * irep->ilen;
+      irep->flags |= MRB_ISEQ_NO_FREE;
+    }
+    else {
+      irep->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen);
+      if (flags & FLAG_BYTEORDER_NATIVE) {
+        memcpy(irep->iseq, src, sizeof(uint32_t) * irep->ilen);
+        src += sizeof(uint32_t) * irep->ilen;
+      }
+      else if (flags & FLAG_BYTEORDER_BIG) {
+        for (i = 0; i < irep->ilen; i++) {
+          irep->iseq[i] = (mrb_code)bin_to_uint32(src);     /* iseq */
+          src += sizeof(uint32_t);
+        }
+      }
+      else {
+        for (i = 0; i < irep->ilen; i++) {
+          irep->iseq[i] = (mrb_code)bin_to_uint32l(src);     /* iseq */
+          src += sizeof(uint32_t);
+        }
+      }
+    }
+  }
+
+  /* POOL BLOCK */
+  plen = (size_t)bin_to_uint32(src); /* number of pool */
+  src += sizeof(uint32_t);
+  if (plen > 0) {
+    if (SIZE_ERROR_MUL(plen, sizeof(mrb_value))) {
+      return NULL;
+    }
+    irep->pool = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * plen);
+
+    for (i = 0; i < plen; i++) {
+      mrb_value s;
+
+      tt = *src++; /* pool TT */
+      pool_data_len = bin_to_uint16(src); /* pool data length */
+      src += sizeof(uint16_t);
+      if (flags & FLAG_SRC_MALLOC) {
+        s = mrb_str_new(mrb, (char *)src, pool_data_len);
+      }
+      else {
+        s = mrb_str_new_static(mrb, (char *)src, pool_data_len);
+      }
+      src += pool_data_len;
+      switch (tt) { /* pool data */
+      case IREP_TT_FIXNUM:
+        irep->pool[i] = mrb_str_to_inum(mrb, s, 10, FALSE);
+        break;
+
+      case IREP_TT_FLOAT:
+        irep->pool[i] = mrb_float_pool(mrb, mrb_str_to_dbl(mrb, s, FALSE));
+        break;
+
+      case IREP_TT_STRING:
+        irep->pool[i] = mrb_str_pool(mrb, s);
+        break;
+
+      default:
+        /* should not happen */
+        irep->pool[i] = mrb_nil_value();
+        break;
+      }
+      irep->plen++;
+      mrb_gc_arena_restore(mrb, ai);
+    }
+  }
+
+  /* SYMS BLOCK */
+  irep->slen = (size_t)bin_to_uint32(src);  /* syms length */
+  src += sizeof(uint32_t);
+  if (irep->slen > 0) {
+    if (SIZE_ERROR_MUL(irep->slen, sizeof(mrb_sym))) {
+      return NULL;
+    }
+    irep->syms = (mrb_sym *)mrb_malloc(mrb, sizeof(mrb_sym) * irep->slen);
+
+    for (i = 0; i < irep->slen; i++) {
+      snl = bin_to_uint16(src);               /* symbol name length */
+      src += sizeof(uint16_t);
+
+      if (snl == MRB_DUMP_NULL_SYM_LEN) {
+        irep->syms[i] = 0;
+        continue;
+      }
+
+      if (flags & FLAG_SRC_MALLOC) {
+        irep->syms[i] = mrb_intern(mrb, (char *)src, snl);
+      }
+      else {
+        irep->syms[i] = mrb_intern_static(mrb, (char *)src, snl);
+      }
+      src += snl + 1;
+
+      mrb_gc_arena_restore(mrb, ai);
+    }
+  }
+
+  irep->reps = (mrb_irep**)mrb_malloc(mrb, sizeof(mrb_irep*)*irep->rlen);
+
+  diff = src - bin;
+  mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);
+  *len = (size_t)diff;
+
+  return irep;
+}
+
+static mrb_irep*
+read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags)
+{
+  mrb_irep *irep = read_irep_record_1(mrb, bin, len, flags);
+  size_t i;
+
+  if (irep == NULL) {
+    return NULL;
+  }
+
+  bin += *len;
+  for (i=0; i<irep->rlen; i++) {
+    size_t rlen;
+
+    irep->reps[i] = read_irep_record(mrb, bin, &rlen, flags);
+    if (irep->reps[i] == NULL) {
+      return NULL;
+    }
+    bin += rlen;
+    *len += rlen;
+  }
+  return irep;
+}
+
+static mrb_irep*
+read_section_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags)
+{
+  size_t len;
+
+  bin += sizeof(struct rite_section_irep_header);
+  return read_irep_record(mrb, bin, &len, flags);
+}
+
+static int
+read_lineno_record_1(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, size_t *len)
+{
+  size_t i, fname_len, niseq;
+  char *fname;
+  uint16_t *lines;
+
+  *len = 0;
+  bin += sizeof(uint32_t); /* record size */
+  *len += sizeof(uint32_t);
+  fname_len = bin_to_uint16(bin);
+  bin += sizeof(uint16_t);
+  *len += sizeof(uint16_t);
+  fname = (char *)mrb_malloc(mrb, fname_len + 1);
+  memcpy(fname, bin, fname_len);
+  fname[fname_len] = '\0';
+  bin += fname_len;
+  *len += fname_len;
+
+  niseq = (size_t)bin_to_uint32(bin);
+  bin += sizeof(uint32_t); /* niseq */
+  *len += sizeof(uint32_t);
+
+  if (SIZE_ERROR_MUL(niseq, sizeof(uint16_t))) {
+    return MRB_DUMP_GENERAL_FAILURE;
+  }
+  lines = (uint16_t *)mrb_malloc(mrb, niseq * sizeof(uint16_t));
+  for (i = 0; i < niseq; i++) {
+    lines[i] = bin_to_uint16(bin);
+    bin += sizeof(uint16_t); /* niseq */
+    *len += sizeof(uint16_t);
+  }
+
+  irep->filename = fname;
+  irep->lines = lines;
+  return MRB_DUMP_OK;
+}
+
+static int
+read_lineno_record(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep, size_t *lenp)
+{
+  int result = read_lineno_record_1(mrb, bin, irep, lenp);
+  size_t i;
+
+  if (result != MRB_DUMP_OK) return result;
+  for (i = 0; i < irep->rlen; i++) {
+    size_t len;
+
+    result = read_lineno_record(mrb, bin, irep->reps[i], &len);
+    if (result != MRB_DUMP_OK) break;
+    bin += len;
+    *lenp += len;
+  }
+  return result;
+}
+
+static int
+read_section_lineno(mrb_state *mrb, const uint8_t *bin, mrb_irep *irep)
+{
+  size_t len;
+
+  len = 0;
+  bin += sizeof(struct rite_section_lineno_header);
+
+  /* Read Binary Data Section */
+  return read_lineno_record(mrb, bin, irep, &len);
+}
+
+static int
+read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t *record_len, const mrb_sym *filenames, size_t filenames_len)
+{
+  const uint8_t *bin = start;
+  ptrdiff_t diff;
+  size_t record_size, i;
+  uint16_t f_idx;
+
+  if (irep->debug_info) { return MRB_DUMP_INVALID_IREP; }
+
+  irep->debug_info = (mrb_irep_debug_info*)mrb_malloc(mrb, sizeof(mrb_irep_debug_info));
+  irep->debug_info->pc_count = irep->ilen;
+
+  record_size = (size_t)bin_to_uint32(bin);
+  bin += sizeof(uint32_t);
+
+  irep->debug_info->flen = bin_to_uint16(bin);
+  irep->debug_info->files = (mrb_irep_debug_info_file**)mrb_malloc(mrb, sizeof(mrb_irep_debug_info*) * irep->debug_info->flen);
+  bin += sizeof(uint16_t);
+
+  for (f_idx = 0; f_idx < irep->debug_info->flen; ++f_idx) {
+    mrb_irep_debug_info_file *file;
+    uint16_t filename_idx;
+    mrb_int len;
+
+    file = (mrb_irep_debug_info_file *)mrb_malloc(mrb, sizeof(*file));
+    irep->debug_info->files[f_idx] = file;
+
+    file->start_pos = bin_to_uint32(bin);
+    bin += sizeof(uint32_t);
+
+    /* filename */
+    filename_idx = bin_to_uint16(bin);
+    bin += sizeof(uint16_t);
+    mrb_assert(filename_idx < filenames_len);
+    file->filename_sym = filenames[filename_idx];
+    len = 0;
+    file->filename = mrb_sym2name_len(mrb, file->filename_sym, &len);
+
+    file->line_entry_count = bin_to_uint32(bin);
+    bin += sizeof(uint32_t);
+    file->line_type = (mrb_debug_line_type)bin_to_uint8(bin);
+    bin += sizeof(uint8_t);
+    switch (file->line_type) {
+      case mrb_debug_line_ary: {
+        uint32_t l;
+
+        file->lines.ary = (uint16_t *)mrb_malloc(mrb, sizeof(uint16_t) * (size_t)(file->line_entry_count));
+        for (l = 0; l < file->line_entry_count; ++l) {
+          file->lines.ary[l] = bin_to_uint16(bin);
+          bin += sizeof(uint16_t);
+        }
+      } break;
+
+      case mrb_debug_line_flat_map: {
+        uint32_t l;
+
+        file->lines.flat_map = (mrb_irep_debug_info_line*)mrb_malloc(
+            mrb, sizeof(mrb_irep_debug_info_line) * (size_t)(file->line_entry_count));
+        for (l = 0; l < file->line_entry_count; ++l) {
+          file->lines.flat_map[l].start_pos = bin_to_uint32(bin);
+          bin += sizeof(uint32_t);
+          file->lines.flat_map[l].line = bin_to_uint16(bin);
+          bin += sizeof(uint16_t);
+        }
+      } break;
+
+      default: return MRB_DUMP_GENERAL_FAILURE;
+    }
+  }
+
+  diff = bin - start;
+  mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);
+
+  if (record_size != (size_t)diff) {
+    return MRB_DUMP_GENERAL_FAILURE;
+  }
+
+  for (i = 0; i < irep->rlen; i++) {
+    size_t len;
+    int ret;
+
+    ret = read_debug_record(mrb, bin, irep->reps[i], &len, filenames, filenames_len);
+    if (ret != MRB_DUMP_OK) return ret;
+    bin += len;
+  }
+
+  diff = bin - start;
+  mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);
+  *record_len = (size_t)diff;
+
+  return MRB_DUMP_OK;
+}
+
+static int
+read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t flags)
+{
+  const uint8_t *bin;
+  ptrdiff_t diff;
+  struct rite_section_debug_header *header;
+  uint16_t i;
+  size_t len = 0;
+  int result;
+  uint16_t filenames_len;
+  mrb_sym *filenames;
+
+  bin = start;
+  header = (struct rite_section_debug_header *)bin;
+  bin += sizeof(struct rite_section_debug_header);
+
+  filenames_len = bin_to_uint16(bin);
+  bin += sizeof(uint16_t);
+  filenames = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * (size_t)filenames_len);
+  for (i = 0; i < filenames_len; ++i) {
+    uint16_t f_len = bin_to_uint16(bin);
+    bin += sizeof(uint16_t);
+    if (flags & FLAG_SRC_MALLOC) {
+      filenames[i] = mrb_intern(mrb, (const char *)bin, (size_t)f_len);
+    }
+    else {
+      filenames[i] = mrb_intern_static(mrb, (const char *)bin, (size_t)f_len);
+    }
+    bin += f_len;
+  }
+
+  result = read_debug_record(mrb, bin, irep, &len, filenames, filenames_len);
+  if (result != MRB_DUMP_OK) goto debug_exit;
+
+  bin += len;
+  diff = bin - start;
+  mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);
+  if ((uint32_t)diff != bin_to_uint32(header->section_size)) {
+    result = MRB_DUMP_GENERAL_FAILURE;
+  }
+
+debug_exit:
+  mrb_free(mrb, filenames);
+  return result;
+}
+
+static int
+read_lv_record(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, size_t *record_len, mrb_sym const *syms, uint32_t syms_len)
+{
+  const uint8_t *bin = start;
+  size_t i;
+  ptrdiff_t diff;
+
+  irep->lv = (struct mrb_locals*)mrb_malloc(mrb, sizeof(struct mrb_locals) * (irep->nlocals - 1));
+
+  for (i = 0; i + 1< irep->nlocals; ++i) {
+    uint16_t const sym_idx = bin_to_uint16(bin);
+    bin += sizeof(uint16_t);
+    if (sym_idx == RITE_LV_NULL_MARK) {
+      irep->lv[i].name = 0;
+      irep->lv[i].r = 0;
+    }
+    else {
+      if (sym_idx >= syms_len) {
+        return MRB_DUMP_GENERAL_FAILURE;
+      }
+      irep->lv[i].name = syms[sym_idx];
+
+      irep->lv[i].r = bin_to_uint16(bin);
+    }
+    bin += sizeof(uint16_t);
+  }
+
+  for (i = 0; i < irep->rlen; ++i) {
+    size_t len;
+    int ret;
+
+    ret = read_lv_record(mrb, bin, irep->reps[i], &len, syms, syms_len);
+    if (ret != MRB_DUMP_OK) return ret;
+    bin += len;
+  }
+
+  diff = bin - start;
+  mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);
+  *record_len = (size_t)diff;
+
+  return MRB_DUMP_OK;
+}
+
+static int
+read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t flags)
+{
+  const uint8_t *bin;
+  ptrdiff_t diff;
+  struct rite_section_lv_header const *header;
+  uint32_t i;
+  size_t len = 0;
+  int result;
+  uint32_t syms_len;
+  mrb_sym *syms;
+  mrb_sym (*intern_func)(mrb_state*, const char*, size_t) =
+    (flags & FLAG_SRC_MALLOC)? mrb_intern : mrb_intern_static;
+
+  bin = start;
+  header = (struct rite_section_lv_header const*)bin;
+  bin += sizeof(struct rite_section_lv_header);
+
+  syms_len = bin_to_uint32(bin);
+  bin += sizeof(uint32_t);
+  syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym) * (size_t)syms_len);
+  for (i = 0; i < syms_len; ++i) {
+    uint16_t const str_len = bin_to_uint16(bin);
+    bin += sizeof(uint16_t);
+
+    syms[i] = intern_func(mrb, (const char*)bin, str_len);
+    bin += str_len;
+  }
+
+  result = read_lv_record(mrb, bin, irep, &len, syms, syms_len);
+  if (result != MRB_DUMP_OK) goto lv_exit;
+
+  bin += len;
+  diff = bin - start;
+  mrb_assert_int_fit(ptrdiff_t, diff, size_t, SIZE_MAX);
+  if ((uint32_t)diff != bin_to_uint32(header->section_size)) {
+    result = MRB_DUMP_GENERAL_FAILURE;
+  }
+
+lv_exit:
+  mrb_free(mrb, syms);
+  return result;
+}
+
+static int
+read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc, uint8_t *flags)
+{
+  const struct rite_binary_header *header = (const struct rite_binary_header *)bin;
+
+  if (memcmp(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident)) == 0) {
+    if (bigendian_p())
+      *flags |= FLAG_BYTEORDER_NATIVE;
+    else
+      *flags |= FLAG_BYTEORDER_BIG;
+  }
+  else if (memcmp(header->binary_ident, RITE_BINARY_IDENT_LIL, sizeof(header->binary_ident)) == 0) {
+    if (bigendian_p())
+      *flags |= FLAG_BYTEORDER_LIL;
+    else
+      *flags |= FLAG_BYTEORDER_NATIVE;
+  }
+  else {
+    return MRB_DUMP_INVALID_FILE_HEADER;
+  }
+
+  if (crc) {
+    *crc = bin_to_uint16(header->binary_crc);
+  }
+  *bin_size = (size_t)bin_to_uint32(header->binary_size);
+
+  return MRB_DUMP_OK;
+}
+
+static mrb_irep*
+read_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags)
+{
+  int result;
+  mrb_irep *irep = NULL;
+  const struct rite_section_header *section_header;
+  uint16_t crc;
+  size_t bin_size = 0;
+  size_t n;
+
+  if ((mrb == NULL) || (bin == NULL)) {
+    return NULL;
+  }
+
+  result = read_binary_header(bin, &bin_size, &crc, &flags);
+  if (result != MRB_DUMP_OK) {
+    return NULL;
+  }
+
+  n = offset_crc_body();
+  if (crc != calc_crc_16_ccitt(bin + n, bin_size - n, 0)) {
+    return NULL;
+  }
+
+  bin += sizeof(struct rite_binary_header);
+  do {
+    section_header = (const struct rite_section_header *)bin;
+    if (memcmp(section_header->section_ident, RITE_SECTION_IREP_IDENT, sizeof(section_header->section_ident)) == 0) {
+      irep = read_section_irep(mrb, bin, flags);
+      if (!irep) return NULL;
+    }
+    else if (memcmp(section_header->section_ident, RITE_SECTION_LINENO_IDENT, sizeof(section_header->section_ident)) == 0) {
+      if (!irep) return NULL;   /* corrupted data */
+      result = read_section_lineno(mrb, bin, irep);
+      if (result < MRB_DUMP_OK) {
+        return NULL;
+      }
+    }
+    else if (memcmp(section_header->section_ident, RITE_SECTION_DEBUG_IDENT, sizeof(section_header->section_ident)) == 0) {
+      if (!irep) return NULL;   /* corrupted data */
+      result = read_section_debug(mrb, bin, irep, flags);
+      if (result < MRB_DUMP_OK) {
+        return NULL;
+      }
+    }
+    else if (memcmp(section_header->section_ident, RITE_SECTION_LV_IDENT, sizeof(section_header->section_ident)) == 0) {
+      if (!irep) return NULL;
+      result = read_section_lv(mrb, bin, irep, flags);
+      if (result < MRB_DUMP_OK) {
+        return NULL;
+      }
+    }
+    bin += bin_to_uint32(section_header->section_size);
+  } while (memcmp(section_header->section_ident, RITE_BINARY_EOF, sizeof(section_header->section_ident)) != 0);
+
+  return irep;
+}
+
+mrb_irep*
+mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
+{
+#ifdef MRB_USE_ETEXT_EDATA
+  uint8_t flags = mrb_ro_data_p((char*)bin) ? FLAG_SRC_STATIC : FLAG_SRC_MALLOC;
+#else
+  uint8_t flags = FLAG_SRC_STATIC;
+#endif
+
+  return read_irep(mrb, bin, flags);
+}
+
+void mrb_exc_set(mrb_state *mrb, mrb_value exc);
+
+static void
+irep_error(mrb_state *mrb)
+{
+  mrb_exc_set(mrb, mrb_exc_new_str_lit(mrb, E_SCRIPT_ERROR, "irep load error"));
+}
+
+MRB_API mrb_value
+mrb_load_irep_cxt(mrb_state *mrb, const uint8_t *bin, mrbc_context *c)
+{
+  mrb_irep *irep = mrb_read_irep(mrb, bin);
+  struct RProc *proc;
+
+  if (!irep) {
+    irep_error(mrb);
+    return mrb_nil_value();
+  }
+  proc = mrb_proc_new(mrb, irep);
+  mrb_irep_decref(mrb, irep);
+  if (c && c->no_exec) return mrb_obj_value(proc);
+  return mrb_top_run(mrb, proc, mrb_top_self(mrb), 0);
+}
+
+MRB_API mrb_value
+mrb_load_irep(mrb_state *mrb, const uint8_t *bin)
+{
+  return mrb_load_irep_cxt(mrb, bin, NULL);
+}
+
+#ifndef MRB_DISABLE_STDIO
+
+mrb_irep*
+mrb_read_irep_file(mrb_state *mrb, FILE* fp)
+{
+  mrb_irep *irep = NULL;
+  uint8_t *buf;
+  const size_t header_size = sizeof(struct rite_binary_header);
+  size_t buf_size = 0;
+  uint8_t flags = 0;
+  int result;
+
+  if ((mrb == NULL) || (fp == NULL)) {
+    return NULL;
+  }
+
+  buf = (uint8_t*)mrb_malloc(mrb, header_size);
+  if (fread(buf, header_size, 1, fp) == 0) {
+    goto irep_exit;
+  }
+  result = read_binary_header(buf, &buf_size, NULL, &flags);
+  if (result != MRB_DUMP_OK || buf_size <= header_size) {
+    goto irep_exit;
+  }
+
+  buf = (uint8_t*)mrb_realloc(mrb, buf, buf_size);
+  if (fread(buf+header_size, buf_size-header_size, 1, fp) == 0) {
+    goto irep_exit;
+  }
+  irep = read_irep(mrb, buf, FLAG_SRC_MALLOC);
+
+irep_exit:
+  mrb_free(mrb, buf);
+  return irep;
+}
+
+void mrb_codedump_all(mrb_state*, struct RProc*);
+
+MRB_API mrb_value
+mrb_load_irep_file_cxt(mrb_state *mrb, FILE* fp, mrbc_context *c)
+{
+  mrb_irep *irep = mrb_read_irep_file(mrb, fp);
+  mrb_value val;
+  struct RProc *proc;
+
+  if (!irep) {
+    irep_error(mrb);
+    return mrb_nil_value();
+  }
+  proc = mrb_proc_new(mrb, irep);
+  mrb_irep_decref(mrb, irep);
+  if (c && c->dump_result) mrb_codedump_all(mrb, proc);
+  if (c && c->no_exec) return mrb_obj_value(proc);
+  val = mrb_top_run(mrb, proc, mrb_top_self(mrb), 0);
+  return val;
+}
+
+MRB_API mrb_value
+mrb_load_irep_file(mrb_state *mrb, FILE* fp)
+{
+  return mrb_load_irep_file_cxt(mrb, fp, NULL);
+}
+#endif /* MRB_DISABLE_STDIO */
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/mruby_core.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/mruby_core.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/mruby_core.rake	(revision 331)
@@ -0,0 +1,19 @@
+MRuby.each_target do
+  current_dir = File.dirname(__FILE__).relative_path_from(Dir.pwd)
+  relative_from_root = File.dirname(__FILE__).relative_path_from(MRUBY_ROOT)
+  current_build_dir = "#{build_dir}/#{relative_from_root}"
+
+  objs = Dir.glob("#{current_dir}/*.c").map { |f|
+    next nil if cxx_exception_enabled? and f =~ /(error|vm).c$/
+    objfile(f.pathmap("#{current_build_dir}/%n"))
+  }.compact
+
+  if cxx_exception_enabled?
+    objs += %w(vm error).map { |v| compile_as_cxx "#{current_dir}/#{v}.c", "#{current_build_dir}/#{v}.cxx" }
+  end
+  self.libmruby << objs
+
+  file libfile("#{build_dir}/lib/libmruby_core") => objs do |t|
+    archiver.run t.name, t.prerequisites
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/numeric.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/numeric.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/numeric.c	(revision 331)
@@ -0,0 +1,1374 @@
+/*
+** numeric.c - Numeric, Integer, Float, Fixnum class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <float.h>
+#include <limits.h>
+#include <math.h>
+#include <stdlib.h>
+
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/numeric.h>
+#include <mruby/string.h>
+#include <mruby/class.h>
+
+#ifdef MRB_USE_FLOAT
+#define trunc(f) truncf(f)
+#define floor(f) floorf(f)
+#define ceil(f) ceilf(f)
+#define fmod(x,y) fmodf(x,y)
+#define MRB_FLO_TO_STR_FMT "%.7g"
+#else
+#define MRB_FLO_TO_STR_FMT "%.14g"
+#endif
+
+MRB_API mrb_float
+mrb_to_flo(mrb_state *mrb, mrb_value val)
+{
+  switch (mrb_type(val)) {
+  case MRB_TT_FIXNUM:
+    return (mrb_float)mrb_fixnum(val);
+  case MRB_TT_FLOAT:
+    break;
+  default:
+    mrb_raise(mrb, E_TYPE_ERROR, "non float value");
+  }
+  return mrb_float(val);
+}
+
+/*
+ * call-seq:
+ *
+ *  num ** other  ->  num
+ *
+ * Raises <code>num</code> the <code>other</code> power.
+ *
+ *    2.0**3      #=> 8.0
+ */
+static mrb_value
+num_pow(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+  mrb_float d;
+
+  mrb_get_args(mrb, "o", &y);
+  if (mrb_fixnum_p(x) && mrb_fixnum_p(y)) {
+    /* try ipow() */
+    mrb_int base = mrb_fixnum(x);
+    mrb_int exp = mrb_fixnum(y);
+    mrb_int result = 1;
+
+    if (exp < 0) goto float_pow;
+    for (;;) {
+      if (exp & 1) {
+        if (mrb_int_mul_overflow(result, base, &result)) {
+          goto float_pow;
+        }
+      }
+      exp >>= 1;
+      if (exp == 0) break;
+      if (mrb_int_mul_overflow(base, base, &base)) {
+        goto float_pow;
+      }
+    }
+    return mrb_fixnum_value(result);
+  }
+ float_pow:
+  d = pow(mrb_to_flo(mrb, x), mrb_to_flo(mrb, y));
+  return mrb_float_value(mrb, d);
+}
+
+/* 15.2.8.3.4  */
+/* 15.2.9.3.4  */
+/*
+ * call-seq:
+ *   num / other  ->  num
+ *
+ * Performs division: the class of the resulting object depends on
+ * the class of <code>num</code> and on the magnitude of the
+ * result.
+ */
+
+mrb_value
+mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y)
+{
+  return mrb_float_value(mrb, mrb_to_flo(mrb, x) / mrb_to_flo(mrb, y));
+}
+
+/* 15.2.9.3.19(x) */
+/*
+ *  call-seq:
+ *     num.quo(numeric)  ->  real
+ *
+ *  Returns most exact division.
+ */
+
+static mrb_value
+num_div(mrb_state *mrb, mrb_value x)
+{
+  mrb_float y;
+
+  mrb_get_args(mrb, "f", &y);
+  return mrb_float_value(mrb, mrb_to_flo(mrb, x) / y);
+}
+
+/********************************************************************
+ *
+ * Document-class: Float
+ *
+ *  <code>Float</code> objects represent inexact real numbers using
+ *  the native architecture's double-precision floating point
+ *  representation.
+ */
+
+/* 15.2.9.3.16(x) */
+/*
+ *  call-seq:
+ *     flt.to_s  ->  string
+ *
+ *  Returns a string containing a representation of self. As well as a
+ *  fixed or exponential form of the number, the call may return
+ *  "<code>NaN</code>", "<code>Infinity</code>", and
+ *  "<code>-Infinity</code>".
+ */
+
+static mrb_value
+flo_to_s(mrb_state *mrb, mrb_value flt)
+{
+  if (isnan(mrb_float(flt))) {
+    return mrb_str_new_lit(mrb, "NaN");
+  }
+  return mrb_float_to_str(mrb, flt, MRB_FLO_TO_STR_FMT);
+}
+
+/* 15.2.9.3.2  */
+/*
+ * call-seq:
+ *   float - other  ->  float
+ *
+ * Returns a new float which is the difference of <code>float</code>
+ * and <code>other</code>.
+ */
+
+static mrb_value
+flo_minus(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+
+  mrb_get_args(mrb, "o", &y);
+  return mrb_float_value(mrb, mrb_float(x) - mrb_to_flo(mrb, y));
+}
+
+/* 15.2.9.3.3  */
+/*
+ * call-seq:
+ *   float * other  ->  float
+ *
+ * Returns a new float which is the product of <code>float</code>
+ * and <code>other</code>.
+ */
+
+static mrb_value
+flo_mul(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+
+  mrb_get_args(mrb, "o", &y);
+  return mrb_float_value(mrb, mrb_float(x) * mrb_to_flo(mrb, y));
+}
+
+static void
+flodivmod(mrb_state *mrb, mrb_float x, mrb_float y, mrb_float *divp, mrb_float *modp)
+{
+  mrb_float div;
+  mrb_float mod;
+
+  if (y == 0.0) {
+    div = INFINITY;
+    mod = NAN;
+  }
+  else {
+    mod = fmod(x, y);
+    if (isinf(x) && isfinite(y))
+      div = x;
+    else
+      div = (x - mod) / y;
+    if (y*mod < 0) {
+      mod += y;
+      div -= 1.0;
+    }
+  }
+
+  if (modp) *modp = mod;
+  if (divp) *divp = div;
+}
+
+/* 15.2.9.3.5  */
+/*
+ *  call-seq:
+ *     flt % other        ->  float
+ *     flt.modulo(other)  ->  float
+ *
+ *  Return the modulo after division of <code>flt</code> by <code>other</code>.
+ *
+ *     6543.21.modulo(137)      #=> 104.21
+ *     6543.21.modulo(137.24)   #=> 92.9299999999996
+ */
+
+static mrb_value
+flo_mod(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+  mrb_float mod;
+
+  mrb_get_args(mrb, "o", &y);
+
+  flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), 0, &mod);
+  return mrb_float_value(mrb, mod);
+}
+
+/* 15.2.8.3.16 */
+/*
+ *  call-seq:
+ *     num.eql?(numeric)  ->  true or false
+ *
+ *  Returns <code>true</code> if <i>num</i> and <i>numeric</i> are the
+ *  same type and have equal values.
+ *
+ *     1 == 1.0          #=> true
+ *     1.eql?(1.0)       #=> false
+ *     (1.0).eql?(1.0)   #=> true
+ */
+static mrb_value
+fix_eql(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+
+  mrb_get_args(mrb, "o", &y);
+  if (!mrb_fixnum_p(y)) return mrb_false_value();
+  return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y));
+}
+
+static mrb_value
+flo_eql(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+
+  mrb_get_args(mrb, "o", &y);
+  if (!mrb_float_p(y)) return mrb_false_value();
+  return mrb_bool_value(mrb_float(x) == (mrb_float)mrb_fixnum(y));
+}
+
+/* 15.2.9.3.7  */
+/*
+ *  call-seq:
+ *     flt == obj  ->  true or false
+ *
+ *  Returns <code>true</code> only if <i>obj</i> has the same value
+ *  as <i>flt</i>. Contrast this with <code>Float#eql?</code>, which
+ *  requires <i>obj</i> to be a <code>Float</code>.
+ *
+ *     1.0 == 1   #=> true
+ *
+ */
+
+static mrb_value
+flo_eq(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+  mrb_get_args(mrb, "o", &y);
+
+  switch (mrb_type(y)) {
+  case MRB_TT_FIXNUM:
+    return mrb_bool_value(mrb_float(x) == (mrb_float)mrb_fixnum(y));
+  case MRB_TT_FLOAT:
+    return mrb_bool_value(mrb_float(x) == mrb_float(y));
+  default:
+    return mrb_false_value();
+  }
+}
+
+static int64_t
+value_int64(mrb_state *mrb, mrb_value x)
+{
+  switch (mrb_type(x)) {
+  case MRB_TT_FIXNUM:
+    return (int64_t)mrb_fixnum(x);
+    break;
+  case MRB_TT_FLOAT:
+    return (int64_t)mrb_float(x);
+  default:
+    mrb_raise(mrb, E_TYPE_ERROR, "cannot convert to Integer");
+    break;
+  }
+  /* not reached */
+  return 0;
+}
+
+static mrb_value
+int64_value(mrb_state *mrb, int64_t v)
+{
+  if (FIXABLE(v)) {
+    return mrb_fixnum_value((mrb_int)v);
+  }
+  return mrb_float_value(mrb, (mrb_float)v);
+}
+
+static mrb_value
+flo_rev(mrb_state *mrb, mrb_value x)
+{
+  int64_t v1;
+  mrb_get_args(mrb, "");
+  v1 = (int64_t)mrb_float(x);
+  return int64_value(mrb, ~v1);
+}
+
+static mrb_value
+flo_and(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+  int64_t v1, v2;
+  mrb_get_args(mrb, "o", &y);
+
+  v1 = (int64_t)mrb_float(x);
+  v2 = value_int64(mrb, y);
+  return int64_value(mrb, v1 & v2);
+}
+
+static mrb_value
+flo_or(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+  int64_t v1, v2;
+  mrb_get_args(mrb, "o", &y);
+
+  v1 = (int64_t)mrb_float(x);
+  v2 = value_int64(mrb, y);
+  return int64_value(mrb, v1 | v2);
+}
+
+static mrb_value
+flo_xor(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+  int64_t v1, v2;
+  mrb_get_args(mrb, "o", &y);
+
+  v1 = (int64_t)mrb_float(x);
+  v2 = value_int64(mrb, y);
+  return int64_value(mrb, v1 ^ v2);
+}
+
+static mrb_value
+flo_shift(mrb_state *mrb, mrb_value x, mrb_int width)
+{
+  mrb_float val;
+
+  if (width == 0) {
+    return x;
+  }
+  val = mrb_float(x);
+  if (width < 0) {
+    while (width++) {
+      val /= 2;
+    }
+#if defined(_ISOC99_SOURCE)
+    val = trunc(val);
+#else
+    val = val > 0 ? floor(val) : ceil(val);
+#endif
+    if (val == 0 && mrb_float(x) < 0) {
+      return mrb_fixnum_value(-1);
+    }
+  }
+  else {
+    while (width--) {
+      val *= 2;
+    }
+  }
+  if (FIXABLE_FLOAT(val)) {
+    return mrb_fixnum_value((mrb_int)val);
+  }
+  return mrb_float_value(mrb, val);
+}
+
+static mrb_value
+flo_lshift(mrb_state *mrb, mrb_value x)
+{
+  mrb_int width;
+
+  mrb_get_args(mrb, "i", &width);
+  return flo_shift(mrb, x, -width);
+}
+
+static mrb_value
+flo_rshift(mrb_state *mrb, mrb_value x)
+{
+  mrb_int width;
+
+  mrb_get_args(mrb, "i", &width);
+  return flo_shift(mrb, x, width);
+}
+
+/* 15.2.8.3.18 */
+/*
+ * call-seq:
+ *   flt.hash  ->  integer
+ *
+ * Returns a hash code for this float.
+ */
+static mrb_value
+flo_hash(mrb_state *mrb, mrb_value num)
+{
+  mrb_float d;
+  char *c;
+  size_t i;
+  mrb_int hash;
+
+  d = (mrb_float)mrb_fixnum(num);
+  /* normalize -0.0 to 0.0 */
+  if (d == 0) d = 0.0;
+  c = (char*)&d;
+  for (hash=0,i=0; i<sizeof(mrb_float); i++) {
+    hash = (hash * 971) ^ (unsigned char)c[i];
+  }
+  if (hash < 0) hash = -hash;
+  return mrb_fixnum_value(hash);
+}
+
+/* 15.2.9.3.13 */
+/*
+ * call-seq:
+ *   flt.to_f  ->  self
+ *
+ * As <code>flt</code> is already a float, returns +self+.
+ */
+
+static mrb_value
+flo_to_f(mrb_state *mrb, mrb_value num)
+{
+  return num;
+}
+
+/* 15.2.9.3.11 */
+/*
+ *  call-seq:
+ *     flt.infinite?  ->  nil, -1, +1
+ *
+ *  Returns <code>nil</code>, -1, or +1 depending on whether <i>flt</i>
+ *  is finite, -infinity, or +infinity.
+ *
+ *     (0.0).infinite?        #=> nil
+ *     (-1.0/0.0).infinite?   #=> -1
+ *     (+1.0/0.0).infinite?   #=> 1
+ */
+
+static mrb_value
+flo_infinite_p(mrb_state *mrb, mrb_value num)
+{
+  mrb_float value = mrb_float(num);
+
+  if (isinf(value)) {
+    return mrb_fixnum_value(value < 0 ? -1 : 1);
+  }
+  return mrb_nil_value();
+}
+
+/* 15.2.9.3.9  */
+/*
+ *  call-seq:
+ *     flt.finite?  ->  true or false
+ *
+ *  Returns <code>true</code> if <i>flt</i> is a valid IEEE floating
+ *  point number (it is not infinite, and <code>nan?</code> is
+ *  <code>false</code>).
+ *
+ */
+
+static mrb_value
+flo_finite_p(mrb_state *mrb, mrb_value num)
+{
+  return mrb_bool_value(isfinite(mrb_float(num)));
+}
+
+void
+mrb_check_num_exact(mrb_state *mrb, mrb_float num)
+{
+  if (isinf(num)) {
+    mrb_raise(mrb, E_FLOATDOMAIN_ERROR, num < 0 ? "-Infinity" : "Infinity");
+  }
+  if (isnan(num)) {
+    mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN");
+  }
+}
+
+/* 15.2.9.3.10 */
+/*
+ *  call-seq:
+ *     flt.floor  ->  integer
+ *
+ *  Returns the largest integer less than or equal to <i>flt</i>.
+ *
+ *     1.2.floor      #=> 1
+ *     2.0.floor      #=> 2
+ *     (-1.2).floor   #=> -2
+ *     (-2.0).floor   #=> -2
+ */
+
+static mrb_value
+flo_floor(mrb_state *mrb, mrb_value num)
+{
+  mrb_float f = floor(mrb_float(num));
+
+  mrb_check_num_exact(mrb, f);
+  if (!FIXABLE_FLOAT(f)) {
+    return mrb_float_value(mrb, f);
+  }
+  return mrb_fixnum_value((mrb_int)f);
+}
+
+/* 15.2.9.3.8  */
+/*
+ *  call-seq:
+ *     flt.ceil  ->  integer
+ *
+ *  Returns the smallest <code>Integer</code> greater than or equal to
+ *  <i>flt</i>.
+ *
+ *     1.2.ceil      #=> 2
+ *     2.0.ceil      #=> 2
+ *     (-1.2).ceil   #=> -1
+ *     (-2.0).ceil   #=> -2
+ */
+
+static mrb_value
+flo_ceil(mrb_state *mrb, mrb_value num)
+{
+  mrb_float f = ceil(mrb_float(num));
+
+  mrb_check_num_exact(mrb, f);
+  if (!FIXABLE_FLOAT(f)) {
+    return mrb_float_value(mrb, f);
+  }
+  return mrb_fixnum_value((mrb_int)f);
+}
+
+/* 15.2.9.3.12 */
+/*
+ *  call-seq:
+ *     flt.round([ndigits])  ->  integer or float
+ *
+ *  Rounds <i>flt</i> to a given precision in decimal digits (default 0 digits).
+ *  Precision may be negative.  Returns a floating point number when ndigits
+ *  is more than zero.
+ *
+ *     1.4.round      #=> 1
+ *     1.5.round      #=> 2
+ *     1.6.round      #=> 2
+ *     (-1.5).round   #=> -2
+ *
+ *     1.234567.round(2)  #=> 1.23
+ *     1.234567.round(3)  #=> 1.235
+ *     1.234567.round(4)  #=> 1.2346
+ *     1.234567.round(5)  #=> 1.23457
+ *
+ *     34567.89.round(-5) #=> 0
+ *     34567.89.round(-4) #=> 30000
+ *     34567.89.round(-3) #=> 35000
+ *     34567.89.round(-2) #=> 34600
+ *     34567.89.round(-1) #=> 34570
+ *     34567.89.round(0)  #=> 34568
+ *     34567.89.round(1)  #=> 34567.9
+ *     34567.89.round(2)  #=> 34567.89
+ *     34567.89.round(3)  #=> 34567.89
+ *
+ */
+
+static mrb_value
+flo_round(mrb_state *mrb, mrb_value num)
+{
+  double number, f;
+  mrb_int ndigits = 0;
+  mrb_int i;
+
+  mrb_get_args(mrb, "|i", &ndigits);
+  number = mrb_float(num);
+
+  if (0 < ndigits && (isinf(number) || isnan(number))) {
+    return num;
+  }
+  mrb_check_num_exact(mrb, number);
+
+  f = 1.0;
+  i = ndigits >= 0 ? ndigits : -ndigits;
+  while  (--i >= 0)
+    f = f*10.0;
+
+  if (isinf(f)) {
+    if (ndigits < 0) number = 0;
+  }
+  else {
+    double d;
+
+    if (ndigits < 0) number /= f;
+    else number *= f;
+
+    /* home-made inline implementation of round(3) */
+    if (number > 0.0) {
+      d = floor(number);
+      number = d + (number - d >= 0.5);
+    }
+    else if (number < 0.0) {
+      d = ceil(number);
+      number = d - (d - number >= 0.5);
+    }
+
+    if (ndigits < 0) number *= f;
+    else number /= f;
+  }
+
+  if (ndigits > 0) {
+    if (!isfinite(number)) return num;
+    return mrb_float_value(mrb, number);
+  }
+  return mrb_fixnum_value((mrb_int)number);
+}
+
+/* 15.2.9.3.14 */
+/* 15.2.9.3.15 */
+/*
+ *  call-seq:
+ *     flt.to_i      ->  integer
+ *     flt.to_int    ->  integer
+ *     flt.truncate  ->  integer
+ *
+ *  Returns <i>flt</i> truncated to an <code>Integer</code>.
+ */
+
+static mrb_value
+flo_truncate(mrb_state *mrb, mrb_value num)
+{
+  mrb_float f = mrb_float(num);
+
+  if (f > 0.0) f = floor(f);
+  if (f < 0.0) f = ceil(f);
+
+  mrb_check_num_exact(mrb, f);
+  if (!FIXABLE_FLOAT(f)) {
+    return mrb_float_value(mrb, f);
+  }
+  return mrb_fixnum_value((mrb_int)f);
+}
+
+static mrb_value
+flo_nan_p(mrb_state *mrb, mrb_value num)
+{
+  return mrb_bool_value(isnan(mrb_float(num)));
+}
+
+/*
+ * Document-class: Integer
+ *
+ *  <code>Integer</code> is the basis for the two concrete classes that
+ *  hold whole numbers, <code>Bignum</code> and <code>Fixnum</code>.
+ *
+ */
+
+
+/*
+ *  call-seq:
+ *     int.to_i      ->  integer
+ *     int.to_int    ->  integer
+ *
+ *  As <i>int</i> is already an <code>Integer</code>, all these
+ *  methods simply return the receiver.
+ */
+
+static mrb_value
+int_to_i(mrb_state *mrb, mrb_value num)
+{
+  return num;
+}
+
+mrb_value
+mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y)
+{
+  mrb_int a;
+
+  a = mrb_fixnum(x);
+  if (mrb_fixnum_p(y)) {
+    mrb_int b, c;
+
+    if (a == 0) return x;
+    b = mrb_fixnum(y);
+    if (mrb_int_mul_overflow(a, b, &c)) {
+      return mrb_float_value(mrb, (mrb_float)a * (mrb_float)b);
+    }
+    return mrb_fixnum_value(c);
+  }
+  return mrb_float_value(mrb, (mrb_float)a * mrb_to_flo(mrb, y));
+}
+
+/* 15.2.8.3.3  */
+/*
+ * call-seq:
+ *   fix * numeric  ->  numeric_result
+ *
+ * Performs multiplication: the class of the resulting object depends on
+ * the class of <code>numeric</code> and on the magnitude of the
+ * result.
+ */
+
+static mrb_value
+fix_mul(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+
+  mrb_get_args(mrb, "o", &y);
+  return mrb_fixnum_mul(mrb, x, y);
+}
+
+static void
+fixdivmod(mrb_state *mrb, mrb_int x, mrb_int y, mrb_int *divp, mrb_int *modp)
+{
+  mrb_int div, mod;
+
+  /* TODO: add mrb_assert(y != 0) to make sure */
+
+  if (y < 0) {
+    if (x < 0)
+      div = -x / -y;
+    else
+      div = - (x / -y);
+  }
+  else {
+    if (x < 0)
+      div = - (-x / y);
+    else
+      div = x / y;
+  }
+  mod = x - div*y;
+  if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) {
+    mod += y;
+    div -= 1;
+  }
+  if (divp) *divp = div;
+  if (modp) *modp = mod;
+}
+
+/* 15.2.8.3.5  */
+/*
+ *  call-seq:
+ *    fix % other        ->  real
+ *    fix.modulo(other)  ->  real
+ *
+ *  Returns <code>fix</code> modulo <code>other</code>.
+ *  See <code>numeric.divmod</code> for more information.
+ */
+
+static mrb_value
+fix_mod(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+  mrb_int a;
+
+  mrb_get_args(mrb, "o", &y);
+  a = mrb_fixnum(x);
+  if (mrb_fixnum_p(y)) {
+    mrb_int b, mod;
+
+    if ((b=mrb_fixnum(y)) == 0) {
+      return mrb_float_value(mrb, NAN);
+    }
+    fixdivmod(mrb, a, b, 0, &mod);
+    return mrb_fixnum_value(mod);
+  }
+  else {
+    mrb_float mod;
+
+    flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), 0, &mod);
+    return mrb_float_value(mrb, mod);
+  }
+}
+
+/*
+ *  call-seq:
+ *     fix.divmod(numeric)  ->  array
+ *
+ *  See <code>Numeric#divmod</code>.
+ */
+static mrb_value
+fix_divmod(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+
+  mrb_get_args(mrb, "o", &y);
+
+  if (mrb_fixnum_p(y)) {
+    mrb_int div, mod;
+
+    if (mrb_fixnum(y) == 0) {
+      return mrb_assoc_new(mrb, mrb_float_value(mrb, INFINITY),
+        mrb_float_value(mrb, NAN));
+    }
+    fixdivmod(mrb, mrb_fixnum(x), mrb_fixnum(y), &div, &mod);
+    return mrb_assoc_new(mrb, mrb_fixnum_value(div), mrb_fixnum_value(mod));
+  }
+  else {
+    mrb_float div, mod;
+    mrb_value a, b;
+
+    flodivmod(mrb, (mrb_float)mrb_fixnum(x), mrb_to_flo(mrb, y), &div, &mod);
+    a = mrb_float_value(mrb, (mrb_int)div);
+    b = mrb_float_value(mrb, mod);
+    return mrb_assoc_new(mrb, a, b);
+  }
+}
+
+static mrb_value
+flo_divmod(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+  mrb_float div, mod;
+  mrb_value a, b;
+
+  mrb_get_args(mrb, "o", &y);
+
+  flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), &div, &mod);
+  a = mrb_float_value(mrb, (mrb_int)div);
+  b = mrb_float_value(mrb, mod);
+  return mrb_assoc_new(mrb, a, b);
+}
+
+/* 15.2.8.3.7  */
+/*
+ * call-seq:
+ *   fix == other  ->  true or false
+ *
+ * Return <code>true</code> if <code>fix</code> equals <code>other</code>
+ * numerically.
+ *
+ *   1 == 2      #=> false
+ *   1 == 1.0    #=> true
+ */
+
+static mrb_value
+fix_equal(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+
+  mrb_get_args(mrb, "o", &y);
+  switch (mrb_type(y)) {
+  case MRB_TT_FIXNUM:
+    return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y));
+  case MRB_TT_FLOAT:
+    return mrb_bool_value((mrb_float)mrb_fixnum(x) == mrb_float(y));
+  default:
+    return mrb_false_value();
+  }
+}
+
+/* 15.2.8.3.8  */
+/*
+ * call-seq:
+ *   ~fix  ->  integer
+ *
+ * One's complement: returns a number where each bit is flipped.
+ *   ex.0---00001 (1)-> 1---11110 (-2)
+ *   ex.0---00010 (2)-> 1---11101 (-3)
+ *   ex.0---00100 (4)-> 1---11011 (-5)
+ */
+
+static mrb_value
+fix_rev(mrb_state *mrb, mrb_value num)
+{
+  mrb_int val = mrb_fixnum(num);
+
+  return mrb_fixnum_value(~val);
+}
+
+static mrb_value flo_and(mrb_state *mrb, mrb_value x);
+static mrb_value flo_or(mrb_state *mrb, mrb_value x);
+static mrb_value flo_xor(mrb_state *mrb, mrb_value x);
+#define bit_op(x,y,op1,op2) do {\
+  if (mrb_fixnum_p(y)) return mrb_fixnum_value(mrb_fixnum(x) op2 mrb_fixnum(y));\
+  return flo_ ## op1(mrb, mrb_float_value(mrb, mrb_fixnum(x)));\
+} while(0)
+
+/* 15.2.8.3.9  */
+/*
+ * call-seq:
+ *   fix & integer  ->  integer_result
+ *
+ * Bitwise AND.
+ */
+
+static mrb_value
+fix_and(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+
+  mrb_get_args(mrb, "o", &y);
+  bit_op(x, y, and, &);
+}
+
+/* 15.2.8.3.10 */
+/*
+ * call-seq:
+ *   fix | integer  ->  integer_result
+ *
+ * Bitwise OR.
+ */
+
+static mrb_value
+fix_or(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+
+  mrb_get_args(mrb, "o", &y);
+  bit_op(x, y, or, |);
+}
+
+/* 15.2.8.3.11 */
+/*
+ * call-seq:
+ *   fix ^ integer  ->  integer_result
+ *
+ * Bitwise EXCLUSIVE OR.
+ */
+
+static mrb_value
+fix_xor(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+
+  mrb_get_args(mrb, "o", &y);
+  bit_op(x, y, or, ^);
+}
+
+#define NUMERIC_SHIFT_WIDTH_MAX (MRB_INT_BIT-1)
+
+static mrb_value
+lshift(mrb_state *mrb, mrb_int val, mrb_int width)
+{
+  if (width < 0) {              /* mrb_int overflow */
+    return mrb_float_value(mrb, INFINITY);
+  }
+  if (val > 0) {
+    if ((width > NUMERIC_SHIFT_WIDTH_MAX) ||
+        (val   > (MRB_INT_MAX >> width))) {
+      goto bit_overflow;
+    }
+  }
+  else {
+    if ((width > NUMERIC_SHIFT_WIDTH_MAX) ||
+        (val   < (MRB_INT_MIN >> width))) {
+      goto bit_overflow;
+    }
+  }
+
+  return mrb_fixnum_value(val << width);
+
+bit_overflow:
+  {
+    mrb_float f = (mrb_float)val;
+    while (width--) {
+      f *= 2;
+    }
+    return mrb_float_value(mrb, f);
+  }
+}
+
+static mrb_value
+rshift(mrb_int val, mrb_int width)
+{
+  if (width < 0) {              /* mrb_int overflow */
+    return mrb_fixnum_value(0);
+  }
+  if (width >= NUMERIC_SHIFT_WIDTH_MAX) {
+    if (val < 0) {
+      return mrb_fixnum_value(-1);
+    }
+    return mrb_fixnum_value(0);
+  }
+  return mrb_fixnum_value(val >> width);
+}
+
+/* 15.2.8.3.12 */
+/*
+ * call-seq:
+ *   fix << count  ->  integer or float
+ *
+ * Shifts _fix_ left _count_ positions (right if _count_ is negative).
+ */
+
+static mrb_value
+fix_lshift(mrb_state *mrb, mrb_value x)
+{
+  mrb_int width, val;
+
+  mrb_get_args(mrb, "i", &width);
+  if (width == 0) {
+    return x;
+  }
+  val = mrb_fixnum(x);
+  if (val == 0) return x;
+  if (width < 0) {
+    return rshift(val, -width);
+  }
+  return lshift(mrb, val, width);
+}
+
+/* 15.2.8.3.13 */
+/*
+ * call-seq:
+ *   fix >> count  ->  integer or float
+ *
+ * Shifts _fix_ right _count_ positions (left if _count_ is negative).
+ */
+
+static mrb_value
+fix_rshift(mrb_state *mrb, mrb_value x)
+{
+  mrb_int width, val;
+
+  mrb_get_args(mrb, "i", &width);
+  if (width == 0) {
+    return x;
+  }
+  val = mrb_fixnum(x);
+  if (val == 0) return x;
+  if (width < 0) {
+    return lshift(mrb, val, -width);
+  }
+  return rshift(val, width);
+}
+
+/* 15.2.8.3.23 */
+/*
+ *  call-seq:
+ *     fix.to_f  ->  float
+ *
+ *  Converts <i>fix</i> to a <code>Float</code>.
+ *
+ */
+
+static mrb_value
+fix_to_f(mrb_state *mrb, mrb_value num)
+{
+  return mrb_float_value(mrb, (mrb_float)mrb_fixnum(num));
+}
+
+/*
+ *  Document-class: FloatDomainError
+ *
+ *  Raised when attempting to convert special float values
+ *  (in particular infinite or NaN)
+ *  to numerical classes which don't support them.
+ *
+ *     Float::INFINITY.to_r
+ *
+ *  <em>raises the exception:</em>
+ *
+ *     FloatDomainError: Infinity
+ */
+/* ------------------------------------------------------------------------*/
+MRB_API mrb_value
+mrb_flo_to_fixnum(mrb_state *mrb, mrb_value x)
+{
+  mrb_int z = 0;
+
+  if (!mrb_float_p(x)) {
+    mrb_raise(mrb, E_TYPE_ERROR, "non float value");
+    z = 0; /* not reached. just suppress warnings. */
+  }
+  else {
+    mrb_float d = mrb_float(x);
+
+    if (isinf(d)) {
+      mrb_raise(mrb, E_FLOATDOMAIN_ERROR, d < 0 ? "-Infinity" : "Infinity");
+    }
+    if (isnan(d)) {
+      mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN");
+    }
+    if (FIXABLE_FLOAT(d)) {
+      z = (mrb_int)d;
+    }
+    else {
+      mrb_raisef(mrb, E_ARGUMENT_ERROR, "number (%S) too big for integer", x);
+    }
+  }
+  return mrb_fixnum_value(z);
+}
+
+mrb_value
+mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y)
+{
+  mrb_int a;
+
+  a = mrb_fixnum(x);
+  if (mrb_fixnum_p(y)) {
+    mrb_int b, c;
+
+    if (a == 0) return y;
+    b = mrb_fixnum(y);
+    if (mrb_int_add_overflow(a, b, &c)) {
+      return mrb_float_value(mrb, (mrb_float)a + (mrb_float)b);
+    }
+    return mrb_fixnum_value(c);
+  }
+  return mrb_float_value(mrb, (mrb_float)a + mrb_to_flo(mrb, y));
+}
+
+/* 15.2.8.3.1  */
+/*
+ * call-seq:
+ *   fix + numeric  ->  numeric_result
+ *
+ * Performs addition: the class of the resulting object depends on
+ * the class of <code>numeric</code> and on the magnitude of the
+ * result.
+ */
+static mrb_value
+fix_plus(mrb_state *mrb, mrb_value self)
+{
+  mrb_value other;
+
+  mrb_get_args(mrb, "o", &other);
+  return mrb_fixnum_plus(mrb, self, other);
+}
+
+mrb_value
+mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y)
+{
+  mrb_int a;
+
+  a = mrb_fixnum(x);
+  if (mrb_fixnum_p(y)) {
+    mrb_int b, c;
+
+    b = mrb_fixnum(y);
+    if (mrb_int_sub_overflow(a, b, &c)) {
+      return mrb_float_value(mrb, (mrb_float)a - (mrb_float)b);
+    }
+    return mrb_fixnum_value(c);
+  }
+  return mrb_float_value(mrb, (mrb_float)a - mrb_to_flo(mrb, y));
+}
+
+/* 15.2.8.3.2  */
+/* 15.2.8.3.16 */
+/*
+ * call-seq:
+ *   fix - numeric  ->  numeric_result
+ *
+ * Performs subtraction: the class of the resulting object depends on
+ * the class of <code>numeric</code> and on the magnitude of the
+ * result.
+ */
+static mrb_value
+fix_minus(mrb_state *mrb, mrb_value self)
+{
+  mrb_value other;
+
+  mrb_get_args(mrb, "o", &other);
+  return mrb_fixnum_minus(mrb, self, other);
+}
+
+
+MRB_API mrb_value
+mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, int base)
+{
+  char buf[MRB_INT_BIT+1];
+  char *b = buf + sizeof buf;
+  mrb_int val = mrb_fixnum(x);
+
+  if (base < 2 || 36 < base) {
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %S", mrb_fixnum_value(base));
+  }
+
+  if (val == 0) {
+    *--b = '0';
+  }
+  else if (val < 0) {
+    do {
+      *--b = mrb_digitmap[-(val % base)];
+    } while (val /= base);
+    *--b = '-';
+  }
+  else {
+    do {
+      *--b = mrb_digitmap[(int)(val % base)];
+    } while (val /= base);
+  }
+
+  return mrb_str_new(mrb, b, buf + sizeof(buf) - b);
+}
+
+/* 15.2.8.3.25 */
+/*
+ *  call-seq:
+ *     fix.to_s(base=10)  ->  string
+ *
+ *  Returns a string containing the representation of <i>fix</i> radix
+ *  <i>base</i> (between 2 and 36).
+ *
+ *     12345.to_s       #=> "12345"
+ *     12345.to_s(2)    #=> "11000000111001"
+ *     12345.to_s(8)    #=> "30071"
+ *     12345.to_s(10)   #=> "12345"
+ *     12345.to_s(16)   #=> "3039"
+ *     12345.to_s(36)   #=> "9ix"
+ *
+ */
+static mrb_value
+fix_to_s(mrb_state *mrb, mrb_value self)
+{
+  mrb_int base = 10;
+
+  mrb_get_args(mrb, "|i", &base);
+  return mrb_fixnum_to_str(mrb, self, base);
+}
+
+/* 15.2.9.3.6  */
+/*
+ * call-seq:
+ *     self.f <=> other.f    => -1, 0, +1
+ *             <  => -1
+ *             =  =>  0
+ *             >  => +1
+ *  Comparison---Returns -1, 0, or +1 depending on whether <i>fix</i> is
+ *  less than, equal to, or greater than <i>numeric</i>. This is the
+ *  basis for the tests in <code>Comparable</code>.
+ */
+static mrb_value
+num_cmp(mrb_state *mrb, mrb_value self)
+{
+  mrb_value other;
+  mrb_float x, y;
+
+  mrb_get_args(mrb, "o", &other);
+
+  x = mrb_to_flo(mrb, self);
+  switch (mrb_type(other)) {
+  case MRB_TT_FIXNUM:
+    y = (mrb_float)mrb_fixnum(other);
+    break;
+  case MRB_TT_FLOAT:
+    y = mrb_float(other);
+    break;
+  default:
+    return mrb_nil_value();
+  }
+  if (x > y)
+    return mrb_fixnum_value(1);
+  else {
+    if (x < y)
+      return mrb_fixnum_value(-1);
+    return mrb_fixnum_value(0);
+  }
+}
+
+/* 15.2.9.3.1  */
+/*
+ * call-seq:
+ *   float + other  ->  float
+ *
+ * Returns a new float which is the sum of <code>float</code>
+ * and <code>other</code>.
+ */
+static mrb_value
+flo_plus(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+
+  mrb_get_args(mrb, "o", &y);
+  return mrb_float_value(mrb, mrb_float(x) + mrb_to_flo(mrb, y));
+}
+
+/* ------------------------------------------------------------------------*/
+void
+mrb_init_numeric(mrb_state *mrb)
+{
+  struct RClass *numeric, *integer, *fixnum, *fl;
+
+  /* Numeric Class */
+  numeric = mrb_define_class(mrb, "Numeric",  mrb->object_class);                /* 15.2.7 */
+
+  mrb_define_method(mrb, numeric, "**",       num_pow,         MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, numeric, "/",        num_div,         MRB_ARGS_REQ(1)); /* 15.2.8.3.4  */
+  mrb_define_method(mrb, numeric, "quo",      num_div,         MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */
+  mrb_define_method(mrb, numeric, "<=>",      num_cmp,         MRB_ARGS_REQ(1)); /* 15.2.9.3.6  */
+
+  /* Integer Class */
+  integer = mrb_define_class(mrb, "Integer",  numeric);                          /* 15.2.8 */
+  MRB_SET_INSTANCE_TT(integer, MRB_TT_FIXNUM);
+  mrb_undef_class_method(mrb, integer, "new");
+  mrb_define_method(mrb, integer, "to_i",     int_to_i,        MRB_ARGS_NONE()); /* 15.2.8.3.24 */
+  mrb_define_method(mrb, integer, "to_int",   int_to_i,        MRB_ARGS_NONE());
+  mrb_define_method(mrb, integer, "ceil",     int_to_i,        MRB_ARGS_REQ(1)); /* 15.2.8.3.8 (x) */
+  mrb_define_method(mrb, integer, "floor",    int_to_i,        MRB_ARGS_REQ(1)); /* 15.2.8.3.10 (x) */
+  mrb_define_method(mrb, integer, "round",    int_to_i,        MRB_ARGS_REQ(1)); /* 15.2.8.3.12 (x) */
+  mrb_define_method(mrb, integer, "truncate", int_to_i,        MRB_ARGS_REQ(1)); /* 15.2.8.3.15 (x) */
+
+  /* Fixnum Class */
+  mrb->fixnum_class = fixnum = mrb_define_class(mrb, "Fixnum", integer);
+  mrb_define_method(mrb, fixnum,  "+",        fix_plus,        MRB_ARGS_REQ(1)); /* 15.2.8.3.1  */
+  mrb_define_method(mrb, fixnum,  "-",        fix_minus,       MRB_ARGS_REQ(1)); /* 15.2.8.3.2  */
+  mrb_define_method(mrb, fixnum,  "*",        fix_mul,         MRB_ARGS_REQ(1)); /* 15.2.8.3.3  */
+  mrb_define_method(mrb, fixnum,  "%",        fix_mod,         MRB_ARGS_REQ(1)); /* 15.2.8.3.5  */
+  mrb_define_method(mrb, fixnum,  "==",       fix_equal,       MRB_ARGS_REQ(1)); /* 15.2.8.3.7  */
+  mrb_define_method(mrb, fixnum,  "~",        fix_rev,         MRB_ARGS_NONE()); /* 15.2.8.3.8  */
+  mrb_define_method(mrb, fixnum,  "&",        fix_and,         MRB_ARGS_REQ(1)); /* 15.2.8.3.9  */
+  mrb_define_method(mrb, fixnum,  "|",        fix_or,          MRB_ARGS_REQ(1)); /* 15.2.8.3.10 */
+  mrb_define_method(mrb, fixnum,  "^",        fix_xor,         MRB_ARGS_REQ(1)); /* 15.2.8.3.11 */
+  mrb_define_method(mrb, fixnum,  "<<",       fix_lshift,      MRB_ARGS_REQ(1)); /* 15.2.8.3.12 */
+  mrb_define_method(mrb, fixnum,  ">>",       fix_rshift,      MRB_ARGS_REQ(1)); /* 15.2.8.3.13 */
+  mrb_define_method(mrb, fixnum,  "eql?",     fix_eql,         MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */
+  mrb_define_method(mrb, fixnum,  "hash",     flo_hash,        MRB_ARGS_NONE()); /* 15.2.8.3.18 */
+  mrb_define_method(mrb, fixnum,  "to_f",     fix_to_f,        MRB_ARGS_NONE()); /* 15.2.8.3.23 */
+  mrb_define_method(mrb, fixnum,  "to_s",     fix_to_s,        MRB_ARGS_NONE()); /* 15.2.8.3.25 */
+  mrb_define_method(mrb, fixnum,  "inspect",  fix_to_s,        MRB_ARGS_NONE());
+  mrb_define_method(mrb, fixnum,  "divmod",   fix_divmod,      MRB_ARGS_REQ(1)); /* 15.2.8.3.30 (x) */
+
+  /* Float Class */
+  mrb->float_class = fl = mrb_define_class(mrb, "Float", numeric);                 /* 15.2.9 */
+  MRB_SET_INSTANCE_TT(fl, MRB_TT_FLOAT);
+  mrb_undef_class_method(mrb,  fl, "new");
+  mrb_define_method(mrb, fl,      "+",         flo_plus,       MRB_ARGS_REQ(1)); /* 15.2.9.3.1  */
+  mrb_define_method(mrb, fl,      "-",         flo_minus,      MRB_ARGS_REQ(1)); /* 15.2.9.3.2  */
+  mrb_define_method(mrb, fl,      "*",         flo_mul,        MRB_ARGS_REQ(1)); /* 15.2.9.3.3  */
+  mrb_define_method(mrb, fl,      "%",         flo_mod,        MRB_ARGS_REQ(1)); /* 15.2.9.3.5  */
+  mrb_define_method(mrb, fl,      "==",        flo_eq,         MRB_ARGS_REQ(1)); /* 15.2.9.3.7  */
+  mrb_define_method(mrb, fl,      "~",         flo_rev,        MRB_ARGS_NONE());
+  mrb_define_method(mrb, fl,      "&",         flo_and,        MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, fl,      "|",         flo_or,         MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, fl,      "^",         flo_xor,        MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, fl,      ">>",        flo_lshift,     MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, fl,      "<<",        flo_rshift,     MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, fl,      "ceil",      flo_ceil,       MRB_ARGS_NONE()); /* 15.2.9.3.8  */
+  mrb_define_method(mrb, fl,      "finite?",   flo_finite_p,   MRB_ARGS_NONE()); /* 15.2.9.3.9  */
+  mrb_define_method(mrb, fl,      "floor",     flo_floor,      MRB_ARGS_NONE()); /* 15.2.9.3.10 */
+  mrb_define_method(mrb, fl,      "infinite?", flo_infinite_p, MRB_ARGS_NONE()); /* 15.2.9.3.11 */
+  mrb_define_method(mrb, fl,      "round",     flo_round,      MRB_ARGS_OPT(1)); /* 15.2.9.3.12 */
+  mrb_define_method(mrb, fl,      "to_f",      flo_to_f,       MRB_ARGS_NONE()); /* 15.2.9.3.13 */
+  mrb_define_method(mrb, fl,      "to_i",      flo_truncate,   MRB_ARGS_NONE()); /* 15.2.9.3.14 */
+  mrb_define_method(mrb, fl,      "to_int",    flo_truncate,   MRB_ARGS_NONE());
+  mrb_define_method(mrb, fl,      "truncate",  flo_truncate,   MRB_ARGS_NONE()); /* 15.2.9.3.15 */
+  mrb_define_method(mrb, fl,      "divmod",    flo_divmod,     MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, fl,      "eql?",      flo_eql,        MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */
+
+  mrb_define_method(mrb, fl,      "to_s",      flo_to_s,       MRB_ARGS_NONE()); /* 15.2.9.3.16(x) */
+  mrb_define_method(mrb, fl,      "inspect",   flo_to_s,       MRB_ARGS_NONE());
+  mrb_define_method(mrb, fl,      "nan?",      flo_nan_p,      MRB_ARGS_NONE());
+
+#ifdef INFINITY
+  mrb_define_const(mrb, fl, "INFINITY", mrb_float_value(mrb, INFINITY));
+#endif
+#ifdef NAN
+  mrb_define_const(mrb, fl, "NAN", mrb_float_value(mrb, NAN));
+#endif
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/object.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/object.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/object.c	(revision 331)
@@ -0,0 +1,610 @@
+/*
+** object.c - Object, NilClass, TrueClass, FalseClass class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/numeric.h>
+#include <mruby/string.h>
+#include <mruby/class.h>
+
+MRB_API mrb_bool
+mrb_obj_eq(mrb_state *mrb, mrb_value v1, mrb_value v2)
+{
+  if (mrb_type(v1) != mrb_type(v2)) return FALSE;
+  switch (mrb_type(v1)) {
+  case MRB_TT_TRUE:
+    return TRUE;
+
+  case MRB_TT_FALSE:
+  case MRB_TT_FIXNUM:
+    return (mrb_fixnum(v1) == mrb_fixnum(v2));
+  case MRB_TT_SYMBOL:
+    return (mrb_symbol(v1) == mrb_symbol(v2));
+
+  case MRB_TT_FLOAT:
+    return (mrb_float(v1) == mrb_float(v2));
+
+  default:
+    return (mrb_ptr(v1) == mrb_ptr(v2));
+  }
+}
+
+MRB_API mrb_bool
+mrb_obj_equal(mrb_state *mrb, mrb_value v1, mrb_value v2)
+{
+  /* temporary definition */
+  return mrb_obj_eq(mrb, v1, v2);
+}
+
+MRB_API mrb_bool
+mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2)
+{
+  mrb_value result;
+
+  if (mrb_obj_eq(mrb, obj1, obj2)) return TRUE;
+  result = mrb_funcall(mrb, obj1, "==", 1, obj2);
+  if (mrb_test(result)) return TRUE;
+  return FALSE;
+}
+
+/*
+ * Document-class: NilClass
+ *
+ *  The class of the singleton object <code>nil</code>.
+ */
+
+/* 15.2.4.3.4  */
+/*
+ * call_seq:
+ *   nil.nil?               -> true
+ *
+ * Only the object <i>nil</i> responds <code>true</code> to <code>nil?</code>.
+ */
+
+static mrb_value
+mrb_true(mrb_state *mrb, mrb_value obj)
+{
+  return mrb_true_value();
+}
+
+/* 15.2.4.3.5  */
+/*
+ *  call-seq:
+ *     nil.to_s    -> ""
+ *
+ *  Always returns the empty string.
+ */
+
+static mrb_value
+nil_to_s(mrb_state *mrb, mrb_value obj)
+{
+  return mrb_str_new(mrb, 0, 0);
+}
+
+static mrb_value
+nil_inspect(mrb_state *mrb, mrb_value obj)
+{
+  return mrb_str_new_lit(mrb, "nil");
+}
+
+/***********************************************************************
+ *  Document-class: TrueClass
+ *
+ *  The global value <code>true</code> is the only instance of class
+ *  <code>TrueClass</code> and represents a logically true value in
+ *  boolean expressions. The class provides operators allowing
+ *  <code>true</code> to be used in logical expressions.
+ */
+
+/* 15.2.5.3.1  */
+/*
+ *  call-seq:
+ *     true & obj    -> true or false
+ *
+ *  And---Returns <code>false</code> if <i>obj</i> is
+ *  <code>nil</code> or <code>false</code>, <code>true</code> otherwise.
+ */
+
+static mrb_value
+true_and(mrb_state *mrb, mrb_value obj)
+{
+  mrb_bool obj2;
+
+  mrb_get_args(mrb, "b", &obj2);
+
+  return mrb_bool_value(obj2);
+}
+
+/* 15.2.5.3.2  */
+/*
+ *  call-seq:
+ *     true ^ obj   -> !obj
+ *
+ *  Exclusive Or---Returns <code>true</code> if <i>obj</i> is
+ *  <code>nil</code> or <code>false</code>, <code>false</code>
+ *  otherwise.
+ */
+
+static mrb_value
+true_xor(mrb_state *mrb, mrb_value obj)
+{
+  mrb_bool obj2;
+
+  mrb_get_args(mrb, "b", &obj2);
+  return mrb_bool_value(!obj2);
+}
+
+/* 15.2.5.3.3  */
+/*
+ * call-seq:
+ *   true.to_s   ->  "true"
+ *
+ * The string representation of <code>true</code> is "true".
+ */
+
+static mrb_value
+true_to_s(mrb_state *mrb, mrb_value obj)
+{
+  return mrb_str_new_lit(mrb, "true");
+}
+
+/* 15.2.5.3.4  */
+/*
+ *  call-seq:
+ *     true | obj   -> true
+ *
+ *  Or---Returns <code>true</code>. As <i>anObject</i> is an argument to
+ *  a method call, it is always evaluated; there is no short-circuit
+ *  evaluation in this case.
+ *
+ *     true |  puts("or")
+ *     true || puts("logical or")
+ *
+ *  <em>produces:</em>
+ *
+ *     or
+ */
+
+static mrb_value
+true_or(mrb_state *mrb, mrb_value obj)
+{
+  return mrb_true_value();
+}
+
+/*
+ *  Document-class: FalseClass
+ *
+ *  The global value <code>false</code> is the only instance of class
+ *  <code>FalseClass</code> and represents a logically false value in
+ *  boolean expressions. The class provides operators allowing
+ *  <code>false</code> to participate correctly in logical expressions.
+ *
+ */
+
+/* 15.2.4.3.1  */
+/* 15.2.6.3.1  */
+/*
+ *  call-seq:
+ *     false & obj   -> false
+ *     nil & obj     -> false
+ *
+ *  And---Returns <code>false</code>. <i>obj</i> is always
+ *  evaluated as it is the argument to a method call---there is no
+ *  short-circuit evaluation in this case.
+ */
+
+static mrb_value
+false_and(mrb_state *mrb, mrb_value obj)
+{
+  return mrb_false_value();
+}
+
+/* 15.2.4.3.2  */
+/* 15.2.6.3.2  */
+/*
+ *  call-seq:
+ *     false ^ obj    -> true or false
+ *     nil   ^ obj    -> true or false
+ *
+ *  Exclusive Or---If <i>obj</i> is <code>nil</code> or
+ *  <code>false</code>, returns <code>false</code>; otherwise, returns
+ *  <code>true</code>.
+ *
+ */
+
+static mrb_value
+false_xor(mrb_state *mrb, mrb_value obj)
+{
+  mrb_bool obj2;
+
+  mrb_get_args(mrb, "b", &obj2);
+  return mrb_bool_value(obj2);
+}
+
+/* 15.2.4.3.3  */
+/* 15.2.6.3.4  */
+/*
+ *  call-seq:
+ *     false | obj   ->   true or false
+ *     nil   | obj   ->   true or false
+ *
+ *  Or---Returns <code>false</code> if <i>obj</i> is
+ *  <code>nil</code> or <code>false</code>; <code>true</code> otherwise.
+ */
+
+static mrb_value
+false_or(mrb_state *mrb, mrb_value obj)
+{
+  mrb_bool obj2;
+
+  mrb_get_args(mrb, "b", &obj2);
+  return mrb_bool_value(obj2);
+}
+
+/* 15.2.6.3.3  */
+/*
+ * call-seq:
+ *   false.to_s   ->  "false"
+ *
+ * 'nuf said...
+ */
+
+static mrb_value
+false_to_s(mrb_state *mrb, mrb_value obj)
+{
+  return mrb_str_new_lit(mrb, "false");
+}
+
+void
+mrb_init_object(mrb_state *mrb)
+{
+  struct RClass *n;
+  struct RClass *t;
+  struct RClass *f;
+
+  mrb->nil_class   = n = mrb_define_class(mrb, "NilClass",   mrb->object_class);
+  MRB_SET_INSTANCE_TT(n, MRB_TT_TRUE);
+  mrb_undef_class_method(mrb, n, "new");
+  mrb_define_method(mrb, n, "&",    false_and,      MRB_ARGS_REQ(1));  /* 15.2.4.3.1  */
+  mrb_define_method(mrb, n, "^",    false_xor,      MRB_ARGS_REQ(1));  /* 15.2.4.3.2  */
+  mrb_define_method(mrb, n, "|",    false_or,       MRB_ARGS_REQ(1));  /* 15.2.4.3.3  */
+  mrb_define_method(mrb, n, "nil?", mrb_true,       MRB_ARGS_NONE());  /* 15.2.4.3.4  */
+  mrb_define_method(mrb, n, "to_s", nil_to_s,       MRB_ARGS_NONE());  /* 15.2.4.3.5  */
+  mrb_define_method(mrb, n, "inspect", nil_inspect, MRB_ARGS_NONE());
+
+  mrb->true_class  = t = mrb_define_class(mrb, "TrueClass",  mrb->object_class);
+  MRB_SET_INSTANCE_TT(t, MRB_TT_TRUE);
+  mrb_undef_class_method(mrb, t, "new");
+  mrb_define_method(mrb, t, "&",    true_and,       MRB_ARGS_REQ(1));  /* 15.2.5.3.1  */
+  mrb_define_method(mrb, t, "^",    true_xor,       MRB_ARGS_REQ(1));  /* 15.2.5.3.2  */
+  mrb_define_method(mrb, t, "to_s", true_to_s,      MRB_ARGS_NONE());  /* 15.2.5.3.3  */
+  mrb_define_method(mrb, t, "|",    true_or,        MRB_ARGS_REQ(1));  /* 15.2.5.3.4  */
+  mrb_define_method(mrb, t, "inspect", true_to_s,   MRB_ARGS_NONE());
+
+  mrb->false_class = f = mrb_define_class(mrb, "FalseClass", mrb->object_class);
+  MRB_SET_INSTANCE_TT(f, MRB_TT_TRUE);
+  mrb_undef_class_method(mrb, f, "new");
+  mrb_define_method(mrb, f, "&",    false_and,      MRB_ARGS_REQ(1));  /* 15.2.6.3.1  */
+  mrb_define_method(mrb, f, "^",    false_xor,      MRB_ARGS_REQ(1));  /* 15.2.6.3.2  */
+  mrb_define_method(mrb, f, "to_s", false_to_s,     MRB_ARGS_NONE());  /* 15.2.6.3.3  */
+  mrb_define_method(mrb, f, "|",    false_or,       MRB_ARGS_REQ(1));  /* 15.2.6.3.4  */
+  mrb_define_method(mrb, f, "inspect", false_to_s,  MRB_ARGS_NONE());
+}
+
+static mrb_value
+inspect_type(mrb_state *mrb, mrb_value val)
+{
+  if (mrb_type(val) == MRB_TT_FALSE || mrb_type(val) == MRB_TT_TRUE) {
+    return mrb_inspect(mrb, val);
+  }
+  else {
+    return mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, val));
+  }
+}
+
+static mrb_value
+convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *method, mrb_bool raise)
+{
+  mrb_sym m = 0;
+
+  m = mrb_intern_cstr(mrb, method);
+  if (!mrb_respond_to(mrb, val, m)) {
+    if (raise) {
+      mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S into %S", inspect_type(mrb, val), mrb_str_new_cstr(mrb, tname));
+    }
+    return mrb_nil_value();
+  }
+  return mrb_funcall_argv(mrb, val, m, 0, 0);
+}
+
+MRB_API mrb_value
+mrb_check_to_integer(mrb_state *mrb, mrb_value val, const char *method)
+{
+  mrb_value v;
+
+  if (mrb_fixnum_p(val)) return val;
+  v = convert_type(mrb, val, "Integer", method, FALSE);
+  if (mrb_nil_p(v) || !mrb_fixnum_p(v)) {
+    return mrb_nil_value();
+  }
+  return v;
+}
+
+MRB_API mrb_value
+mrb_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method)
+{
+  mrb_value v;
+
+  if (mrb_type(val) == type) return val;
+  v = convert_type(mrb, val, tname, method, TRUE);
+  if (mrb_type(v) != type) {
+    mrb_raisef(mrb, E_TYPE_ERROR, "%S cannot be converted to %S by #%S", val,
+               mrb_str_new_cstr(mrb, tname), mrb_str_new_cstr(mrb, method));
+  }
+  return v;
+}
+
+MRB_API mrb_value
+mrb_check_convert_type(mrb_state *mrb, mrb_value val, enum mrb_vtype type, const char *tname, const char *method)
+{
+  mrb_value v;
+
+  if (mrb_type(val) == type && type != MRB_TT_DATA && type != MRB_TT_ISTRUCT) return val;
+  v = convert_type(mrb, val, tname, method, FALSE);
+  if (mrb_nil_p(v) || mrb_type(v) != type) return mrb_nil_value();
+  return v;
+}
+
+static const struct types {
+  unsigned char type;
+  const char *name;
+} builtin_types[] = {
+/*    {MRB_TT_NIL,  "nil"}, */
+  {MRB_TT_FALSE,  "false"},
+  {MRB_TT_TRUE,   "true"},
+  {MRB_TT_FIXNUM, "Fixnum"},
+  {MRB_TT_SYMBOL, "Symbol"},  /* :symbol */
+  {MRB_TT_MODULE, "Module"},
+  {MRB_TT_OBJECT, "Object"},
+  {MRB_TT_CLASS,  "Class"},
+  {MRB_TT_ICLASS, "iClass"},  /* internal use: mixed-in module holder */
+  {MRB_TT_SCLASS, "SClass"},
+  {MRB_TT_PROC,   "Proc"},
+  {MRB_TT_FLOAT,  "Float"},
+  {MRB_TT_ARRAY,  "Array"},
+  {MRB_TT_HASH,   "Hash"},
+  {MRB_TT_STRING, "String"},
+  {MRB_TT_RANGE,  "Range"},
+/*    {MRB_TT_BIGNUM,  "Bignum"}, */
+  {MRB_TT_FILE,   "File"},
+  {MRB_TT_DATA,   "Data"},  /* internal use: wrapped C pointers */
+/*    {MRB_TT_VARMAP,  "Varmap"}, */ /* internal use: dynamic variables */
+/*    {MRB_TT_NODE,  "Node"}, */ /* internal use: syntax tree node */
+/*    {MRB_TT_UNDEF,  "undef"}, */ /* internal use: #undef; should not happen */
+  {MRB_TT_MAXDEFINE,  0}
+};
+
+MRB_API void
+mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t)
+{
+  const struct types *type = builtin_types;
+  enum mrb_vtype xt;
+
+  xt = mrb_type(x);
+  if ((xt != t) || (xt == MRB_TT_DATA) || (xt == MRB_TT_ISTRUCT)) {
+    while (type->type < MRB_TT_MAXDEFINE) {
+      if (type->type == t) {
+        const char *etype;
+
+        if (mrb_nil_p(x)) {
+          etype = "nil";
+        }
+        else if (mrb_fixnum_p(x)) {
+          etype = "Fixnum";
+        }
+        else if (mrb_type(x) == MRB_TT_SYMBOL) {
+          etype = "Symbol";
+        }
+        else if (mrb_immediate_p(x)) {
+          etype = RSTRING_PTR(mrb_obj_as_string(mrb, x));
+        }
+        else {
+          etype = mrb_obj_classname(mrb, x);
+        }
+        mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected %S)",
+                   mrb_str_new_cstr(mrb, etype), mrb_str_new_cstr(mrb, type->name));
+      }
+      type++;
+    }
+    mrb_raisef(mrb, E_TYPE_ERROR, "unknown type %S (%S given)",
+               mrb_fixnum_value(t), mrb_fixnum_value(mrb_type(x)));
+  }
+}
+
+/* 15.3.1.3.46 */
+/*
+ *  call-seq:
+ *     obj.to_s    => string
+ *
+ *  Returns a string representing <i>obj</i>. The default
+ *  <code>to_s</code> prints the object's class and an encoding of the
+ *  object id. As a special case, the top-level object that is the
+ *  initial execution context of Ruby programs returns "main."
+ */
+
+MRB_API mrb_value
+mrb_any_to_s(mrb_state *mrb, mrb_value obj)
+{
+  mrb_value str = mrb_str_buf_new(mrb, 20);
+  const char *cname = mrb_obj_classname(mrb, obj);
+
+  mrb_str_cat_lit(mrb, str, "#<");
+  mrb_str_cat_cstr(mrb, str, cname);
+  mrb_str_cat_lit(mrb, str, ":");
+  mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_ptr(obj)));
+  mrb_str_cat_lit(mrb, str, ">");
+
+  return str;
+}
+
+/*
+ *  call-seq:
+ *     obj.is_a?(class)       => true or false
+ *     obj.kind_of?(class)    => true or false
+ *
+ *  Returns <code>true</code> if <i>class</i> is the class of
+ *  <i>obj</i>, or if <i>class</i> is one of the superclasses of
+ *  <i>obj</i> or modules included in <i>obj</i>.
+ *
+ *     module M;    end
+ *     class A
+ *       include M
+ *     end
+ *     class B < A; end
+ *     class C < B; end
+ *     b = B.new
+ *     b.instance_of? A   #=> false
+ *     b.instance_of? B   #=> true
+ *     b.instance_of? C   #=> false
+ *     b.instance_of? M   #=> false
+ *     b.kind_of? A       #=> true
+ *     b.kind_of? B       #=> true
+ *     b.kind_of? C       #=> false
+ *     b.kind_of? M       #=> true
+ */
+
+MRB_API mrb_bool
+mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c)
+{
+  struct RClass *cl = mrb_class(mrb, obj);
+
+  switch (c->tt) {
+    case MRB_TT_MODULE:
+    case MRB_TT_CLASS:
+    case MRB_TT_ICLASS:
+    case MRB_TT_SCLASS:
+      break;
+
+    default:
+      mrb_raise(mrb, E_TYPE_ERROR, "class or module required");
+  }
+
+  MRB_CLASS_ORIGIN(c);
+  while (cl) {
+    if (cl == c || cl->mt == c->mt)
+      return TRUE;
+    cl = cl->super;
+  }
+  return FALSE;
+}
+
+static mrb_value
+mrb_to_integer(mrb_state *mrb, mrb_value val, const char *method)
+{
+  mrb_value v;
+
+  if (mrb_fixnum_p(val)) return val;
+  v = convert_type(mrb, val, "Integer", method, TRUE);
+  if (!mrb_obj_is_kind_of(mrb, v, mrb->fixnum_class)) {
+    mrb_value type = inspect_type(mrb, val);
+    mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Integer (%S#%S gives %S)",
+               type, type, mrb_str_new_cstr(mrb, method), inspect_type(mrb, v));
+  }
+  return v;
+}
+
+MRB_API mrb_value
+mrb_to_int(mrb_state *mrb, mrb_value val)
+{
+  return mrb_to_integer(mrb, val, "to_int");
+}
+
+MRB_API mrb_value
+mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base)
+{
+  mrb_value tmp;
+
+  if (mrb_nil_p(val)) {
+    if (base != 0) goto arg_error;
+      mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Integer");
+  }
+  switch (mrb_type(val)) {
+    case MRB_TT_FLOAT:
+      if (base != 0) goto arg_error;
+      else {
+        mrb_float f = mrb_float(val);
+        if (FIXABLE_FLOAT(f)) {
+          break;
+        }
+      }
+      return mrb_flo_to_fixnum(mrb, val);
+
+    case MRB_TT_FIXNUM:
+      if (base != 0) goto arg_error;
+      return val;
+
+    case MRB_TT_STRING:
+    string_conv:
+      return mrb_str_to_inum(mrb, val, base, TRUE);
+
+    default:
+      break;
+  }
+  if (base != 0) {
+    tmp = mrb_check_string_type(mrb, val);
+    if (!mrb_nil_p(tmp)) {
+      val = tmp;
+      goto string_conv;
+    }
+arg_error:
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value");
+  }
+  tmp = convert_type(mrb, val, "Integer", "to_int", FALSE);
+  if (mrb_nil_p(tmp)) {
+    return mrb_to_integer(mrb, val, "to_i");
+  }
+  return tmp;
+}
+
+MRB_API mrb_value
+mrb_Integer(mrb_state *mrb, mrb_value val)
+{
+  return mrb_convert_to_integer(mrb, val, 0);
+}
+
+MRB_API mrb_value
+mrb_Float(mrb_state *mrb, mrb_value val)
+{
+  if (mrb_nil_p(val)) {
+    mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Float");
+  }
+  switch (mrb_type(val)) {
+    case MRB_TT_FIXNUM:
+      return mrb_float_value(mrb, (mrb_float)mrb_fixnum(val));
+
+    case MRB_TT_FLOAT:
+      return val;
+
+    case MRB_TT_STRING:
+      return mrb_float_value(mrb, mrb_str_to_dbl(mrb, val, TRUE));
+
+    default:
+      return mrb_convert_type(mrb, val, MRB_TT_FLOAT, "Float", "to_f");
+  }
+}
+
+MRB_API mrb_value
+mrb_inspect(mrb_state *mrb, mrb_value obj)
+{
+  return mrb_obj_as_string(mrb, mrb_funcall(mrb, obj, "inspect", 0));
+}
+
+MRB_API mrb_bool
+mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2)
+{
+  if (mrb_obj_eq(mrb, obj1, obj2)) return TRUE;
+  return mrb_test(mrb_funcall(mrb, obj1, "eql?", 1, obj2));
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/opcode.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/opcode.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/opcode.h	(revision 331)
@@ -0,0 +1,2 @@
+/* this header file is to be removed soon. */
+#include <mruby/opcode.h>
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/pool.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/pool.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/pool.c	(revision 331)
@@ -0,0 +1,198 @@
+/*
+** pool.c - memory pool
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <mruby.h>
+
+/* configuration section */
+/* allocated memory address should be multiple of POOL_ALIGNMENT */
+/* or undef it if alignment does not matter */
+#ifndef POOL_ALIGNMENT
+#if INTPTR_MAX == INT64_MAX
+#define POOL_ALIGNMENT 8
+#else
+#define POOL_ALIGNMENT 4
+#endif
+#endif
+/* page size of memory pool */
+#ifndef POOL_PAGE_SIZE
+#define POOL_PAGE_SIZE 16000
+#endif
+/* end of configuration section */
+
+struct mrb_pool_page {
+  struct mrb_pool_page *next;
+  size_t offset;
+  size_t len;
+  void *last;
+  char page[];
+};
+
+struct mrb_pool {
+  mrb_state *mrb;
+  struct mrb_pool_page *pages;
+};
+
+#undef TEST_POOL
+#ifdef TEST_POOL
+
+#define mrb_malloc_simple(m,s) malloc(s)
+#define mrb_free(m,p) free(p)
+#endif
+
+#ifdef POOL_ALIGNMENT
+#  define ALIGN_PADDING(x) ((SIZE_MAX - (x) + 1) & (POOL_ALIGNMENT - 1))
+#else
+#  define ALIGN_PADDING(x) (0)
+#endif
+
+MRB_API mrb_pool*
+mrb_pool_open(mrb_state *mrb)
+{
+  mrb_pool *pool = (mrb_pool *)mrb_malloc_simple(mrb, sizeof(mrb_pool));
+
+  if (pool) {
+    pool->mrb = mrb;
+    pool->pages = NULL;
+  }
+
+  return pool;
+}
+
+MRB_API void
+mrb_pool_close(mrb_pool *pool)
+{
+  struct mrb_pool_page *page, *tmp;
+
+  if (!pool) return;
+  page = pool->pages;
+  while (page) {
+    tmp = page;
+    page = page->next;
+    mrb_free(pool->mrb, tmp);
+  }
+  mrb_free(pool->mrb, pool);
+}
+
+static struct mrb_pool_page*
+page_alloc(mrb_pool *pool, size_t len)
+{
+  struct mrb_pool_page *page;
+
+  if (len < POOL_PAGE_SIZE)
+    len = POOL_PAGE_SIZE;
+  page = (struct mrb_pool_page *)mrb_malloc_simple(pool->mrb, sizeof(struct mrb_pool_page)+len);
+  if (page) {
+    page->offset = 0;
+    page->len = len;
+  }
+
+  return page;
+}
+
+MRB_API void*
+mrb_pool_alloc(mrb_pool *pool, size_t len)
+{
+  struct mrb_pool_page *page;
+  size_t n;
+
+  if (!pool) return NULL;
+  len += ALIGN_PADDING(len);
+  page = pool->pages;
+  while (page) {
+    if (page->offset + len <= page->len) {
+      n = page->offset;
+      page->offset += len;
+      page->last = (char*)page->page+n;
+      return page->last;
+    }
+    page = page->next;
+  }
+  page = page_alloc(pool, len);
+  if (!page) return NULL;
+  page->offset = len;
+  page->next = pool->pages;
+  pool->pages = page;
+
+  page->last = (void*)page->page;
+  return page->last;
+}
+
+MRB_API mrb_bool
+mrb_pool_can_realloc(mrb_pool *pool, void *p, size_t len)
+{
+  struct mrb_pool_page *page;
+
+  if (!pool) return FALSE;
+  len += ALIGN_PADDING(len);
+  page = pool->pages;
+  while (page) {
+    if (page->last == p) {
+      size_t beg;
+
+      beg = (char*)p - page->page;
+      if (beg + len > page->len) return FALSE;
+      return TRUE;
+    }
+    page = page->next;
+  }
+  return FALSE;
+}
+
+MRB_API void*
+mrb_pool_realloc(mrb_pool *pool, void *p, size_t oldlen, size_t newlen)
+{
+  struct mrb_pool_page *page;
+  void *np;
+
+  if (!pool) return NULL;
+  oldlen += ALIGN_PADDING(oldlen);
+  newlen += ALIGN_PADDING(newlen);
+  page = pool->pages;
+  while (page) {
+    if (page->last == p) {
+      size_t beg;
+
+      beg = (char*)p - page->page;
+      if (beg + oldlen != page->offset) break;
+      if (beg + newlen > page->len) {
+        page->offset = beg;
+        break;
+      }
+      page->offset = beg + newlen;
+      return p;
+    }
+    page = page->next;
+  }
+  np = mrb_pool_alloc(pool, newlen);
+  if (np == NULL) {
+    return NULL;
+  }
+  memcpy(np, p, oldlen);
+  return np;
+}
+
+#ifdef TEST_POOL
+int
+main(void)
+{
+  int i, len = 250;
+  mrb_pool *pool;
+  void *p;
+
+  pool = mrb_pool_open(NULL);
+  p = mrb_pool_alloc(pool, len);
+  for (i=1; i<20; i++) {
+    printf("%p (len=%d) %ud\n", p, len, mrb_pool_can_realloc(pool, p, len*2));
+    p = mrb_pool_realloc(pool, p, len, len*2);
+    len *= 2;
+  }
+  mrb_pool_close(pool);
+  return 0;
+}
+#endif
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/print.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/print.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/print.c	(revision 331)
@@ -0,0 +1,47 @@
+/*
+** print.c - Kernel.#p
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <mruby.h>
+#include <mruby/string.h>
+#include <mruby/variable.h>
+
+#ifndef MRB_DISABLE_STDIO
+static void
+printstr(mrb_value obj, FILE *stream)
+{
+  if (mrb_string_p(obj)) {
+    fwrite(RSTRING_PTR(obj), RSTRING_LEN(obj), 1, stream);
+    putc('\n', stream);
+  }
+}
+#else
+# define printstr(obj, stream) (void)0
+#endif
+
+MRB_API void
+mrb_p(mrb_state *mrb, mrb_value obj)
+{
+  printstr(mrb_inspect(mrb, obj), stdout);
+}
+
+MRB_API void
+mrb_print_error(mrb_state *mrb)
+{
+  mrb_print_backtrace(mrb);
+  printstr(mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0), stderr);
+}
+
+MRB_API void
+mrb_show_version(mrb_state *mrb)
+{
+  printstr(mrb_const_get(mrb, mrb_obj_value(mrb->object_class), mrb_intern_lit(mrb, "MRUBY_DESCRIPTION")), stdout);
+}
+
+MRB_API void
+mrb_show_copyright(mrb_state *mrb)
+{
+  printstr(mrb_const_get(mrb, mrb_obj_value(mrb->object_class), mrb_intern_lit(mrb, "MRUBY_COPYRIGHT")), stdout);
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/proc.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/proc.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/proc.c	(revision 331)
@@ -0,0 +1,286 @@
+/*
+** proc.c - Proc class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/proc.h>
+#include <mruby/opcode.h>
+
+static mrb_code call_iseq[] = {
+  MKOP_A(OP_CALL, 0),
+};
+
+struct RProc *
+mrb_proc_new(mrb_state *mrb, mrb_irep *irep)
+{
+  struct RProc *p;
+  mrb_callinfo *ci = mrb->c->ci;
+
+  p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
+  p->target_class = 0;
+  if (ci) {
+    if (ci->proc)
+      p->target_class = ci->proc->target_class;
+    if (!p->target_class)
+      p->target_class = ci->target_class;
+  }
+  p->body.irep = irep;
+  p->env = 0;
+  mrb_irep_incref(mrb, irep);
+
+  return p;
+}
+
+static struct REnv*
+env_new(mrb_state *mrb, int nlocals)
+{
+  struct REnv *e;
+
+  e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->c->ci->proc->env);
+  MRB_SET_ENV_STACK_LEN(e, nlocals);
+  e->cxt.c = mrb->c;
+  e->cioff = mrb->c->ci - mrb->c->cibase;
+  e->stack = mrb->c->stack;
+
+  return e;
+}
+
+static void
+closure_setup(mrb_state *mrb, struct RProc *p, int nlocals)
+{
+  struct REnv *e;
+
+  if (!mrb->c->ci->env) {
+    e = env_new(mrb, nlocals);
+    mrb->c->ci->env = e;
+  }
+  else {
+    e = mrb->c->ci->env;
+  }
+  p->env = e;
+  mrb_field_write_barrier(mrb, (struct RBasic *)p, (struct RBasic *)p->env);
+}
+
+struct RProc *
+mrb_closure_new(mrb_state *mrb, mrb_irep *irep)
+{
+  struct RProc *p = mrb_proc_new(mrb, irep);
+
+  closure_setup(mrb, p, mrb->c->ci->proc->body.irep->nlocals);
+  return p;
+}
+
+MRB_API struct RProc *
+mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func)
+{
+  struct RProc *p;
+
+  p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
+  p->body.func = func;
+  p->flags |= MRB_PROC_CFUNC;
+  p->env = 0;
+
+  return p;
+}
+
+MRB_API struct RProc *
+mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const mrb_value *argv)
+{
+  struct RProc *p = mrb_proc_new_cfunc(mrb, func);
+  struct REnv *e;
+  int i;
+
+  p->env = e = env_new(mrb, argc);
+  mrb_field_write_barrier(mrb, (struct RBasic *)p, (struct RBasic *)p->env);
+  MRB_ENV_UNSHARE_STACK(e);
+  e->stack = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * argc);
+  if (argv) {
+    for (i = 0; i < argc; ++i) {
+      e->stack[i] = argv[i];
+    }
+  }
+  else {
+    for (i = 0; i < argc; ++i) {
+      SET_NIL_VALUE(e->stack[i]);
+    }
+  }
+  return p;
+}
+
+MRB_API struct RProc *
+mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals)
+{
+  return mrb_proc_new_cfunc_with_env(mrb, func, nlocals, NULL);
+}
+
+MRB_API mrb_value
+mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx)
+{
+  struct RProc *p = mrb->c->ci->proc;
+  struct REnv *e = p->env;
+
+  if (!MRB_PROC_CFUNC_P(p)) {
+    mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from non-cfunc proc.");
+  }
+  if (!e) {
+    mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from cfunc Proc without REnv.");
+  }
+  if (idx < 0 || MRB_ENV_STACK_LEN(e) <= idx) {
+    mrb_raisef(mrb, E_INDEX_ERROR, "Env index out of range: %S (expected: 0 <= index < %S)",
+               mrb_fixnum_value(idx), mrb_fixnum_value(MRB_ENV_STACK_LEN(e)));
+  }
+
+  return e->stack[idx];
+}
+
+void
+mrb_proc_copy(struct RProc *a, struct RProc *b)
+{
+  a->flags = b->flags;
+  a->body = b->body;
+  if (!MRB_PROC_CFUNC_P(a) && a->body.irep) {
+    a->body.irep->refcnt++;
+  }
+  a->target_class = b->target_class;
+  a->env = b->env;
+}
+
+static mrb_value
+mrb_proc_s_new(mrb_state *mrb, mrb_value proc_class)
+{
+  mrb_value blk;
+  mrb_value proc;
+  struct RProc *p;
+
+  mrb_get_args(mrb, "&", &blk);
+  if (mrb_nil_p(blk)) {
+    /* Calling Proc.new without a block is not implemented yet */
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block");
+  }
+  p = (struct RProc *)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb_class_ptr(proc_class));
+  mrb_proc_copy(p, mrb_proc_ptr(blk));
+  proc = mrb_obj_value(p);
+  mrb_funcall_with_block(mrb, proc, mrb_intern_lit(mrb, "initialize"), 0, NULL, blk);
+  return proc;
+}
+
+static mrb_value
+mrb_proc_init_copy(mrb_state *mrb, mrb_value self)
+{
+  mrb_value proc;
+
+  mrb_get_args(mrb, "o", &proc);
+  if (mrb_type(proc) != MRB_TT_PROC) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc");
+  }
+  mrb_proc_copy(mrb_proc_ptr(self), mrb_proc_ptr(proc));
+  return self;
+}
+
+int
+mrb_proc_cfunc_p(struct RProc *p)
+{
+  return MRB_PROC_CFUNC_P(p);
+}
+
+mrb_value
+mrb_proc_call_cfunc(mrb_state *mrb, struct RProc *p, mrb_value self)
+{
+  return (p->body.func)(mrb, self);
+}
+
+/* 15.2.17.4.2 */
+static mrb_value
+mrb_proc_arity(mrb_state *mrb, mrb_value self)
+{
+  struct RProc *p = mrb_proc_ptr(self);
+  struct mrb_irep *irep;
+  mrb_code *iseq;
+  mrb_aspec aspec;
+  int ma, op, ra, pa, arity;
+
+  if (MRB_PROC_CFUNC_P(p)) {
+    /* TODO cfunc aspec not implemented yet */
+    return mrb_fixnum_value(-1);
+  }
+
+  irep = p->body.irep;
+  if (!irep) {
+    return mrb_fixnum_value(0);
+  }
+
+  iseq = irep->iseq;
+  /* arity is depend on OP_ENTER */
+  if (GET_OPCODE(*iseq) != OP_ENTER) {
+    return mrb_fixnum_value(0);
+  }
+
+  aspec = GETARG_Ax(*iseq);
+  ma = MRB_ASPEC_REQ(aspec);
+  op = MRB_ASPEC_OPT(aspec);
+  ra = MRB_ASPEC_REST(aspec);
+  pa = MRB_ASPEC_POST(aspec);
+  arity = ra || (MRB_PROC_STRICT_P(p) && op) ? -(ma + pa + 1) : ma + pa;
+
+  return mrb_fixnum_value(arity);
+}
+
+/* 15.3.1.2.6  */
+/* 15.3.1.3.27 */
+/*
+ * call-seq:
+ *   lambda { |...| block }  -> a_proc
+ *
+ * Equivalent to <code>Proc.new</code>, except the resulting Proc objects
+ * check the number of parameters passed when called.
+ */
+static mrb_value
+proc_lambda(mrb_state *mrb, mrb_value self)
+{
+  mrb_value blk;
+  struct RProc *p;
+
+  mrb_get_args(mrb, "&", &blk);
+  if (mrb_nil_p(blk)) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block");
+  }
+  if (mrb_type(blk) != MRB_TT_PROC) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc");
+  }
+  p = mrb_proc_ptr(blk);
+  if (!MRB_PROC_STRICT_P(p)) {
+    struct RProc *p2 = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, p->c);
+    mrb_proc_copy(p2, p);
+    p2->flags |= MRB_PROC_STRICT;
+    return mrb_obj_value(p2);
+  }
+  return blk;
+}
+
+void
+mrb_init_proc(mrb_state *mrb)
+{
+  struct RProc *m;
+  mrb_irep *call_irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep));
+  static const mrb_irep mrb_irep_zero = { 0 };
+
+  *call_irep = mrb_irep_zero;
+  call_irep->flags = MRB_ISEQ_NO_FREE;
+  call_irep->iseq = call_iseq;
+  call_irep->ilen = 1;
+  call_irep->nregs = 2;         /* receiver and block */
+
+  mrb_define_class_method(mrb, mrb->proc_class, "new", mrb_proc_s_new, MRB_ARGS_ANY());
+  mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, mrb->proc_class, "arity", mrb_proc_arity, MRB_ARGS_NONE());
+
+  m = mrb_proc_new(mrb, call_irep);
+  mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern_lit(mrb, "call"), m);
+  mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern_lit(mrb, "[]"), m);
+
+  mrb_define_class_method(mrb, mrb->kernel_module, "lambda", proc_lambda, MRB_ARGS_NONE()); /* 15.3.1.2.6  */
+  mrb_define_method(mrb, mrb->kernel_module,       "lambda", proc_lambda, MRB_ARGS_NONE()); /* 15.3.1.3.27 */
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/range.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/range.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/range.c	(revision 331)
@@ -0,0 +1,443 @@
+/*
+** range.c - Range class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/range.h>
+#include <mruby/string.h>
+#include <mruby/array.h>
+
+#define RANGE_CLASS (mrb_class_get(mrb, "Range"))
+
+MRB_API struct RRange*
+mrb_range_ptr(mrb_state *mrb, mrb_value v)
+{
+  struct RRange *r = (struct RRange*)mrb_ptr(v);
+
+  if (r->edges == NULL) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized range");
+  }
+  return r;
+}
+
+static void
+range_check(mrb_state *mrb, mrb_value a, mrb_value b)
+{
+  mrb_value ans;
+  enum mrb_vtype ta;
+  enum mrb_vtype tb;
+
+  ta = mrb_type(a);
+  tb = mrb_type(b);
+  if ((ta == MRB_TT_FIXNUM || ta == MRB_TT_FLOAT) &&
+      (tb == MRB_TT_FIXNUM || tb == MRB_TT_FLOAT)) {
+    return;
+  }
+
+  ans =  mrb_funcall(mrb, a, "<=>", 1, b);
+  if (mrb_nil_p(ans)) {
+    /* can not be compared */
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "bad value for range");
+  }
+}
+
+MRB_API mrb_value
+mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, mrb_bool excl)
+{
+  struct RRange *r;
+
+  range_check(mrb, beg, end);
+  r = (struct RRange*)mrb_obj_alloc(mrb, MRB_TT_RANGE, RANGE_CLASS);
+  r->edges = (mrb_range_edges *)mrb_malloc(mrb, sizeof(mrb_range_edges));
+  r->edges->beg = beg;
+  r->edges->end = end;
+  r->excl = excl;
+  return mrb_range_value(r);
+}
+
+/*
+ *  call-seq:
+ *     rng.first    => obj
+ *     rng.begin    => obj
+ *
+ *  Returns the first object in <i>rng</i>.
+ */
+mrb_value
+mrb_range_beg(mrb_state *mrb, mrb_value range)
+{
+  struct RRange *r = mrb_range_ptr(mrb, range);
+
+  return r->edges->beg;
+}
+
+/*
+ *  call-seq:
+ *     rng.end    => obj
+ *     rng.last   => obj
+ *
+ *  Returns the object that defines the end of <i>rng</i>.
+ *
+ *     (1..10).end    #=> 10
+ *     (1...10).end   #=> 10
+ */
+
+mrb_value
+mrb_range_end(mrb_state *mrb, mrb_value range)
+{
+  struct RRange *r = mrb_range_ptr(mrb, range);
+
+  return r->edges->end;
+}
+
+/*
+ *  call-seq:
+ *     range.exclude_end?    => true or false
+ *
+ *  Returns <code>true</code> if <i>range</i> excludes its end value.
+ */
+mrb_value
+mrb_range_excl(mrb_state *mrb, mrb_value range)
+{
+  struct RRange *r = mrb_range_ptr(mrb, range);
+
+  return mrb_bool_value(r->excl);
+}
+
+static void
+range_init(mrb_state *mrb, mrb_value range, mrb_value beg, mrb_value end, mrb_bool exclude_end)
+{
+  struct RRange *r = mrb_range_raw_ptr(range);
+
+  range_check(mrb, beg, end);
+  r->excl = exclude_end;
+  if (!r->edges) {
+    r->edges = (mrb_range_edges *)mrb_malloc(mrb, sizeof(mrb_range_edges));
+  }
+  r->edges->beg = beg;
+  r->edges->end = end;
+}
+/*
+ *  call-seq:
+ *     Range.new(start, end, exclusive=false)    => range
+ *
+ *  Constructs a range using the given <i>start</i> and <i>end</i>. If the third
+ *  parameter is omitted or is <code>false</code>, the <i>range</i> will include
+ *  the end object; otherwise, it will be excluded.
+ */
+
+mrb_value
+mrb_range_initialize(mrb_state *mrb, mrb_value range)
+{
+  mrb_value beg, end;
+  mrb_bool exclusive;
+  int n;
+
+  n = mrb_get_args(mrb, "oo|b", &beg, &end, &exclusive);
+  if (n != 3) {
+    exclusive = FALSE;
+  }
+  /* Ranges are immutable, so that they should be initialized only once. */
+  if (mrb_range_raw_ptr(range)->edges) {
+    mrb_name_error(mrb, mrb_intern_lit(mrb, "initialize"), "`initialize' called twice");
+  }
+  range_init(mrb, range, beg, end, exclusive);
+  return range;
+}
+/*
+ *  call-seq:
+ *     range == obj    => true or false
+ *
+ *  Returns <code>true</code> only if
+ *  1) <i>obj</i> is a Range,
+ *  2) <i>obj</i> has equivalent beginning and end items (by comparing them with <code>==</code>),
+ *  3) <i>obj</i> has the same #exclude_end? setting as <i>rng</t>.
+ *
+ *    (0..2) == (0..2)            #=> true
+ *    (0..2) == Range.new(0,2)    #=> true
+ *    (0..2) == (0...2)           #=> false
+ *
+ */
+
+mrb_value
+mrb_range_eq(mrb_state *mrb, mrb_value range)
+{
+  struct RRange *rr;
+  struct RRange *ro;
+  mrb_value obj, v1, v2;
+
+  mrb_get_args(mrb, "o", &obj);
+
+  if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value();
+  if (!mrb_obj_is_instance_of(mrb, obj, mrb_obj_class(mrb, range))) { /* same class? */
+    return mrb_false_value();
+  }
+
+  rr = mrb_range_ptr(mrb, range);
+  ro = mrb_range_ptr(mrb, obj);
+  v1 = mrb_funcall(mrb, rr->edges->beg, "==", 1, ro->edges->beg);
+  v2 = mrb_funcall(mrb, rr->edges->end, "==", 1, ro->edges->end);
+  if (!mrb_bool(v1) || !mrb_bool(v2) || rr->excl != ro->excl) {
+    return mrb_false_value();
+  }
+  return mrb_true_value();
+}
+
+static mrb_bool
+r_le(mrb_state *mrb, mrb_value a, mrb_value b)
+{
+  mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
+  /* output :a < b => -1, a = b =>  0, a > b => +1 */
+
+  if (mrb_fixnum_p(r)) {
+    mrb_int c = mrb_fixnum(r);
+    if (c == 0 || c == -1) return TRUE;
+  }
+
+  return FALSE;
+}
+
+static mrb_bool
+r_gt(mrb_state *mrb, mrb_value a, mrb_value b)
+{
+  mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b);
+  /* output :a < b => -1, a = b =>  0, a > b => +1 */
+
+  return mrb_fixnum_p(r) && mrb_fixnum(r) == 1;
+}
+
+static mrb_bool
+r_ge(mrb_state *mrb, mrb_value a, mrb_value b)
+{
+  mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
+  /* output :a < b => -1, a = b =>  0, a > b => +1 */
+
+  if (mrb_fixnum_p(r)) {
+    mrb_int c = mrb_fixnum(r);
+    if (c == 0 || c == 1) return TRUE;
+  }
+
+  return FALSE;
+}
+
+/*
+ *  call-seq:
+ *     range === obj       =>  true or false
+ *     range.member?(val)  =>  true or false
+ *     range.include?(val) =>  true or false
+ *
+ */
+mrb_value
+mrb_range_include(mrb_state *mrb, mrb_value range)
+{
+  mrb_value val;
+  struct RRange *r = mrb_range_ptr(mrb, range);
+  mrb_value beg, end;
+  mrb_bool include_p;
+
+  mrb_get_args(mrb, "o", &val);
+
+  beg = r->edges->beg;
+  end = r->edges->end;
+  include_p = r_le(mrb, beg, val) &&           /* beg <= val */
+              (r->excl ? r_gt(mrb, end, val)   /* end >  val */
+                       : r_ge(mrb, end, val)); /* end >= val */
+
+  return mrb_bool_value(include_p);
+}
+
+MRB_API mrb_int
+mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc)
+{
+  mrb_int beg, end;
+  struct RRange *r;
+
+  if (mrb_type(range) != MRB_TT_RANGE) return 0;
+  r = mrb_range_ptr(mrb, range);
+
+  beg = mrb_int(mrb, r->edges->beg);
+  end = mrb_int(mrb, r->edges->end);
+
+  if (beg < 0) {
+    beg += len;
+    if (beg < 0) return 2;
+  }
+
+  if (trunc) {
+    if (beg > len) return 2;
+    if (end > len) end = len;
+  }
+
+  if (end < 0) end += len;
+  if (!r->excl && (!trunc || end < len))
+    end++;                      /* include end point */
+  len = end - beg;
+  if (len < 0) len = 0;
+
+  *begp = beg;
+  *lenp = len;
+  return 1;
+}
+
+/* 15.2.14.4.12(x) */
+/*
+ * call-seq:
+ *   rng.to_s   -> string
+ *
+ * Convert this range object to a printable form.
+ */
+
+static mrb_value
+range_to_s(mrb_state *mrb, mrb_value range)
+{
+  mrb_value str, str2;
+  struct RRange *r = mrb_range_ptr(mrb, range);
+
+  str  = mrb_obj_as_string(mrb, r->edges->beg);
+  str2 = mrb_obj_as_string(mrb, r->edges->end);
+  str  = mrb_str_dup(mrb, str);
+  mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2);
+  mrb_str_cat_str(mrb, str, str2);
+
+  return str;
+}
+
+/* 15.2.14.4.13(x) */
+/*
+ * call-seq:
+ *   rng.inspect  -> string
+ *
+ * Convert this range object to a printable form (using
+ * <code>inspect</code> to convert the start and end
+ * objects).
+ */
+
+static mrb_value
+range_inspect(mrb_state *mrb, mrb_value range)
+{
+  mrb_value str, str2;
+  struct RRange *r = mrb_range_ptr(mrb, range);
+
+  str  = mrb_inspect(mrb, r->edges->beg);
+  str2 = mrb_inspect(mrb, r->edges->end);
+  str  = mrb_str_dup(mrb, str);
+  mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2);
+  mrb_str_cat_str(mrb, str, str2);
+
+  return str;
+}
+
+/* 15.2.14.4.14(x) */
+/*
+ *  call-seq:
+ *     rng.eql?(obj)    -> true or false
+ *
+ *  Returns <code>true</code> only if <i>obj</i> is a Range, has equivalent
+ *  beginning and end items (by comparing them with #eql?), and has the same
+ *  #exclude_end? setting as <i>rng</i>.
+ *
+ *    (0..2).eql?(0..2)            #=> true
+ *    (0..2).eql?(Range.new(0,2))  #=> true
+ *    (0..2).eql?(0...2)           #=> false
+ *
+ */
+
+static mrb_value
+range_eql(mrb_state *mrb, mrb_value range)
+{
+  mrb_value obj;
+  struct RRange *r, *o;
+
+  mrb_get_args(mrb, "o", &obj);
+
+  if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value();
+  if (!mrb_obj_is_kind_of(mrb, obj, RANGE_CLASS)) {
+    return mrb_false_value();
+  }
+  if (mrb_type(obj) != MRB_TT_RANGE) return mrb_false_value();
+
+  r = mrb_range_ptr(mrb, range);
+  o = mrb_range_ptr(mrb, obj);
+  if (!mrb_eql(mrb, r->edges->beg, o->edges->beg) ||
+      !mrb_eql(mrb, r->edges->end, o->edges->end) ||
+      (r->excl != o->excl)) {
+    return mrb_false_value();
+  }
+  return mrb_true_value();
+}
+
+/* 15.2.14.4.15(x) */
+static mrb_value
+range_initialize_copy(mrb_state *mrb, mrb_value copy)
+{
+  mrb_value src;
+  struct RRange *r;
+
+  mrb_get_args(mrb, "o", &src);
+
+  if (mrb_obj_equal(mrb, copy, src)) return copy;
+  if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) {
+    mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class");
+  }
+
+  r = mrb_range_ptr(mrb, src);
+  range_init(mrb, copy, r->edges->beg, r->edges->end, r->excl);
+
+  return copy;
+}
+
+mrb_value
+mrb_get_values_at(mrb_state *mrb, mrb_value obj, mrb_int olen, mrb_int argc, const mrb_value *argv, mrb_value (*func)(mrb_state*, mrb_value, mrb_int))
+{
+  mrb_int i, j, beg, len;
+  mrb_value result;
+  result = mrb_ary_new(mrb);
+
+  for (i = 0; i < argc; ++i) {
+    if (mrb_fixnum_p(argv[i])) {
+      mrb_ary_push(mrb, result, func(mrb, obj, mrb_fixnum(argv[i])));
+    }
+    else if (mrb_range_beg_len(mrb, argv[i], &beg, &len, olen, FALSE) == 1) {
+      mrb_int const end = olen < beg + len ? olen : beg + len;
+      for (j = beg; j < end; ++j) {
+        mrb_ary_push(mrb, result, func(mrb, obj, j));
+      }
+
+      for (; j < beg + len; ++j) {
+        mrb_ary_push(mrb, result, mrb_nil_value());
+      }
+    }
+    else {
+      mrb_raisef(mrb, E_TYPE_ERROR, "invalid values selector: %S", argv[i]);
+    }
+  }
+
+  return result;
+}
+
+void
+mrb_init_range(mrb_state *mrb)
+{
+  struct RClass *r;
+
+  r = mrb_define_class(mrb, "Range", mrb->object_class);                                /* 15.2.14 */
+  MRB_SET_INSTANCE_TT(r, MRB_TT_RANGE);
+
+  mrb_define_method(mrb, r, "begin",           mrb_range_beg,         MRB_ARGS_NONE()); /* 15.2.14.4.3  */
+  mrb_define_method(mrb, r, "end",             mrb_range_end,         MRB_ARGS_NONE()); /* 15.2.14.4.5  */
+  mrb_define_method(mrb, r, "==",              mrb_range_eq,          MRB_ARGS_REQ(1)); /* 15.2.14.4.1  */
+  mrb_define_method(mrb, r, "===",             mrb_range_include,     MRB_ARGS_REQ(1)); /* 15.2.14.4.2  */
+  mrb_define_method(mrb, r, "exclude_end?",    mrb_range_excl,        MRB_ARGS_NONE()); /* 15.2.14.4.6  */
+  mrb_define_method(mrb, r, "first",           mrb_range_beg,         MRB_ARGS_NONE()); /* 15.2.14.4.7  */
+  mrb_define_method(mrb, r, "include?",        mrb_range_include,     MRB_ARGS_REQ(1)); /* 15.2.14.4.8  */
+  mrb_define_method(mrb, r, "initialize",      mrb_range_initialize,  MRB_ARGS_ANY());  /* 15.2.14.4.9  */
+  mrb_define_method(mrb, r, "last",            mrb_range_end,         MRB_ARGS_NONE()); /* 15.2.14.4.10 */
+  mrb_define_method(mrb, r, "member?",         mrb_range_include,     MRB_ARGS_REQ(1)); /* 15.2.14.4.11 */
+
+  mrb_define_method(mrb, r, "to_s",            range_to_s,            MRB_ARGS_NONE()); /* 15.2.14.4.12(x) */
+  mrb_define_method(mrb, r, "inspect",         range_inspect,         MRB_ARGS_NONE()); /* 15.2.14.4.13(x) */
+  mrb_define_method(mrb, r, "eql?",            range_eql,             MRB_ARGS_REQ(1)); /* 15.2.14.4.14(x) */
+  mrb_define_method(mrb, r, "initialize_copy", range_initialize_copy, MRB_ARGS_REQ(1)); /* 15.2.14.4.15(x) */
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/state.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/state.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/state.c	(revision 331)
@@ -0,0 +1,301 @@
+/*
+** state.c - mrb_state open/close functions
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <mruby.h>
+#include <mruby/irep.h>
+#include <mruby/variable.h>
+#include <mruby/debug.h>
+#include <mruby/string.h>
+
+void mrb_init_core(mrb_state*);
+void mrb_init_mrbgems(mrb_state*);
+
+void mrb_gc_init(mrb_state*, mrb_gc *gc);
+void mrb_gc_destroy(mrb_state*, mrb_gc *gc);
+
+static mrb_value
+inspect_main(mrb_state *mrb, mrb_value mod)
+{
+  return mrb_str_new_lit(mrb, "main");
+}
+
+MRB_API mrb_state*
+mrb_open_core(mrb_allocf f, void *ud)
+{
+  static const mrb_state mrb_state_zero = { 0 };
+  static const struct mrb_context mrb_context_zero = { 0 };
+  mrb_state *mrb;
+
+  mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud);
+  if (mrb == NULL) return NULL;
+
+  *mrb = mrb_state_zero;
+  mrb->allocf_ud = ud;
+  mrb->allocf = f;
+  mrb->atexit_stack_len = 0;
+
+  mrb_gc_init(mrb, &mrb->gc);
+  mrb->c = (struct mrb_context*)mrb_malloc(mrb, sizeof(struct mrb_context));
+  *mrb->c = mrb_context_zero;
+  mrb->root_c = mrb->c;
+
+  mrb_init_core(mrb);
+
+  return mrb;
+}
+
+void*
+mrb_default_allocf(mrb_state *mrb, void *p, size_t size, void *ud)
+{
+  if (size == 0) {
+    free(p);
+    return NULL;
+  }
+  else {
+    return realloc(p, size);
+  }
+}
+
+struct alloca_header {
+  struct alloca_header *next;
+  char buf[];
+};
+
+MRB_API void*
+mrb_alloca(mrb_state *mrb, size_t size)
+{
+  struct alloca_header *p;
+
+  p = (struct alloca_header*) mrb_malloc(mrb, sizeof(struct alloca_header)+size);
+  p->next = mrb->mems;
+  mrb->mems = p;
+  return (void*)p->buf;
+}
+
+static void
+mrb_alloca_free(mrb_state *mrb)
+{
+  struct alloca_header *p;
+  struct alloca_header *tmp;
+
+  if (mrb == NULL) return;
+  p = mrb->mems;
+
+  while (p) {
+    tmp = p;
+    p = p->next;
+    mrb_free(mrb, tmp);
+  }
+}
+
+MRB_API mrb_state*
+mrb_open(void)
+{
+  mrb_state *mrb = mrb_open_allocf(mrb_default_allocf, NULL, FALSE);
+
+  return mrb;
+}
+
+MRB_API mrb_state*
+mrb_open_allocf(mrb_allocf f, void *ud, mrb_bool disable_gems)
+{
+  mrb_state *mrb = mrb_open_core(f, ud);
+
+  if (mrb == NULL) {
+    return NULL;
+  }
+
+  if (!disable_gems) {
+    mrb_init_mrbgems(mrb);
+    mrb_gc_arena_restore(mrb, 0);
+  }
+  return mrb;
+}
+
+void mrb_free_symtbl(mrb_state *mrb);
+
+void
+mrb_irep_incref(mrb_state *mrb, mrb_irep *irep)
+{
+  irep->refcnt++;
+}
+
+void
+mrb_irep_decref(mrb_state *mrb, mrb_irep *irep)
+{
+  irep->refcnt--;
+  if (irep->refcnt == 0) {
+    mrb_irep_free(mrb, irep);
+  }
+}
+
+void
+mrb_irep_free(mrb_state *mrb, mrb_irep *irep)
+{
+  size_t i;
+
+  if (!(irep->flags & MRB_ISEQ_NO_FREE))
+    mrb_free(mrb, irep->iseq);
+  if (irep->pool) for (i=0; i<irep->plen; i++) {
+    if (mrb_type(irep->pool[i]) == MRB_TT_STRING) {
+      mrb_gc_free_str(mrb, RSTRING(irep->pool[i]));
+      mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
+    }
+#ifdef MRB_WORD_BOXING
+    else if (mrb_type(irep->pool[i]) == MRB_TT_FLOAT) {
+      mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
+    }
+#endif
+  }
+  mrb_free(mrb, irep->pool);
+  mrb_free(mrb, irep->syms);
+  for (i=0; i<irep->rlen; i++) {
+    mrb_irep_decref(mrb, irep->reps[i]);
+  }
+  mrb_free(mrb, irep->reps);
+  mrb_free(mrb, irep->lv);
+  if (irep->own_filename) {
+    mrb_free(mrb, (void *)irep->filename);
+  }
+  mrb_free(mrb, irep->lines);
+  mrb_debug_info_free(mrb, irep->debug_info);
+  mrb_free(mrb, irep);
+}
+
+mrb_value
+mrb_str_pool(mrb_state *mrb, mrb_value str)
+{
+  struct RString *s = mrb_str_ptr(str);
+  struct RString *ns;
+  char *ptr;
+  mrb_int len;
+
+  ns = (struct RString *)mrb_malloc(mrb, sizeof(struct RString));
+  ns->tt = MRB_TT_STRING;
+  ns->c = mrb->string_class;
+
+  if (RSTR_NOFREE_P(s)) {
+    ns->flags = MRB_STR_NOFREE;
+    ns->as.heap.ptr = s->as.heap.ptr;
+    ns->as.heap.len = s->as.heap.len;
+    ns->as.heap.aux.capa = 0;
+  }
+  else {
+    ns->flags = 0;
+    if (RSTR_EMBED_P(s)) {
+      ptr = s->as.ary;
+      len = RSTR_EMBED_LEN(s);
+    }
+    else {
+      ptr = s->as.heap.ptr;
+      len = s->as.heap.len;
+    }
+
+    if (len < RSTRING_EMBED_LEN_MAX) {
+      RSTR_SET_EMBED_FLAG(ns);
+      RSTR_SET_EMBED_LEN(ns, len);
+      if (ptr) {
+        memcpy(ns->as.ary, ptr, len);
+      }
+      ns->as.ary[len] = '\0';
+    }
+    else {
+      ns->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1);
+      ns->as.heap.len = len;
+      ns->as.heap.aux.capa = len;
+      if (ptr) {
+        memcpy(ns->as.heap.ptr, ptr, len);
+      }
+      ns->as.heap.ptr[len] = '\0';
+    }
+  }
+  return mrb_obj_value(ns);
+}
+
+void mrb_free_backtrace(mrb_state *mrb);
+
+MRB_API void
+mrb_free_context(mrb_state *mrb, struct mrb_context *c)
+{
+  if (!c) return;
+  mrb_free(mrb, c->stbase);
+  mrb_free(mrb, c->cibase);
+  mrb_free(mrb, c->rescue);
+  mrb_free(mrb, c->ensure);
+  mrb_free(mrb, c);
+}
+
+MRB_API void
+mrb_close(mrb_state *mrb)
+{
+  if (!mrb) return;
+  if (mrb->atexit_stack_len > 0) {
+    mrb_int i;
+    for (i = mrb->atexit_stack_len; i > 0; --i) {
+      mrb->atexit_stack[i - 1](mrb);
+    }
+#ifndef MRB_FIXED_STATE_ATEXIT_STACK
+    mrb_free(mrb, mrb->atexit_stack);
+#endif
+  }
+
+  /* free */
+  mrb_gc_free_gv(mrb);
+  mrb_free_context(mrb, mrb->root_c);
+  mrb_free_symtbl(mrb);
+  mrb_alloca_free(mrb);
+  mrb_gc_destroy(mrb, &mrb->gc);
+  mrb_free(mrb, mrb);
+}
+
+MRB_API mrb_irep*
+mrb_add_irep(mrb_state *mrb)
+{
+  static const mrb_irep mrb_irep_zero = { 0 };
+  mrb_irep *irep;
+
+  irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep));
+  *irep = mrb_irep_zero;
+  irep->refcnt = 1;
+  irep->own_filename = FALSE;
+
+  return irep;
+}
+
+MRB_API mrb_value
+mrb_top_self(mrb_state *mrb)
+{
+  if (!mrb->top_self) {
+    mrb->top_self = (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class);
+    mrb_define_singleton_method(mrb, mrb->top_self, "inspect", inspect_main, MRB_ARGS_NONE());
+    mrb_define_singleton_method(mrb, mrb->top_self, "to_s", inspect_main, MRB_ARGS_NONE());
+  }
+  return mrb_obj_value(mrb->top_self);
+}
+
+MRB_API void
+mrb_state_atexit(mrb_state *mrb, mrb_atexit_func f)
+{
+#ifdef MRB_FIXED_STATE_ATEXIT_STACK
+  if (mrb->atexit_stack_len + 1 > MRB_FIXED_STATE_ATEXIT_STACK_SIZE) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "exceeded fixed state atexit stack limit");
+  }
+#else
+  size_t stack_size;
+
+  stack_size = sizeof(mrb_atexit_func) * (mrb->atexit_stack_len + 1);
+  if (mrb->atexit_stack_len == 0) {
+    mrb->atexit_stack = (mrb_atexit_func*)mrb_malloc(mrb, stack_size);
+  }
+  else {
+    mrb->atexit_stack = (mrb_atexit_func*)mrb_realloc(mrb, mrb->atexit_stack, stack_size);
+  }
+#endif
+
+  mrb->atexit_stack[mrb->atexit_stack_len++] = f;
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/string.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/string.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/string.c	(revision 331)
@@ -0,0 +1,3022 @@
+/*
+** string.c - String class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#ifdef _MSC_VER
+# define _CRT_NONSTDC_NO_DEPRECATE
+#endif
+
+#include <float.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/class.h>
+#include <mruby/range.h>
+#include <mruby/string.h>
+#include <mruby/re.h>
+
+typedef struct mrb_shared_string {
+  mrb_bool nofree : 1;
+  int refcnt;
+  char *ptr;
+  mrb_int len;
+} mrb_shared_string;
+
+const char mrb_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+#define mrb_obj_alloc_string(mrb) ((struct RString*)mrb_obj_alloc((mrb), MRB_TT_STRING, (mrb)->string_class))
+
+static struct RString*
+str_new_static(mrb_state *mrb, const char *p, size_t len)
+{
+  struct RString *s;
+
+  if (len >= MRB_INT_MAX) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
+  }
+  s = mrb_obj_alloc_string(mrb);
+  s->as.heap.len = len;
+  s->as.heap.aux.capa = 0;             /* nofree */
+  s->as.heap.ptr = (char *)p;
+  s->flags = MRB_STR_NOFREE;
+
+  return s;
+}
+
+static struct RString*
+str_new(mrb_state *mrb, const char *p, size_t len)
+{
+  struct RString *s;
+
+  if (p && mrb_ro_data_p(p)) {
+    return str_new_static(mrb, p, len);
+  }
+  s = mrb_obj_alloc_string(mrb);
+  if (len < RSTRING_EMBED_LEN_MAX) {
+    RSTR_SET_EMBED_FLAG(s);
+    RSTR_SET_EMBED_LEN(s, len);
+    if (p) {
+      memcpy(s->as.ary, p, len);
+    }
+  }
+  else {
+    if (len >= MRB_INT_MAX) {
+      mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
+    }
+    s->as.heap.len = len;
+    s->as.heap.aux.capa = len;
+    s->as.heap.ptr = (char *)mrb_malloc(mrb, len+1);
+    if (p) {
+      memcpy(s->as.heap.ptr, p, len);
+    }
+  }
+  RSTR_PTR(s)[len] = '\0';
+  return s;
+}
+
+static inline void
+str_with_class(mrb_state *mrb, struct RString *s, mrb_value obj)
+{
+  s->c = mrb_str_ptr(obj)->c;
+}
+
+static mrb_value
+mrb_str_new_empty(mrb_state *mrb, mrb_value str)
+{
+  struct RString *s = str_new(mrb, 0, 0);
+
+  str_with_class(mrb, s, str);
+  return mrb_obj_value(s);
+}
+
+#ifndef MRB_STR_BUF_MIN_SIZE
+# define MRB_STR_BUF_MIN_SIZE 128
+#endif
+
+MRB_API mrb_value
+mrb_str_buf_new(mrb_state *mrb, size_t capa)
+{
+  struct RString *s;
+
+  s = mrb_obj_alloc_string(mrb);
+
+  if (capa >= MRB_INT_MAX) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "string capacity size too big");
+  }
+  if (capa < MRB_STR_BUF_MIN_SIZE) {
+    capa = MRB_STR_BUF_MIN_SIZE;
+  }
+  s->as.heap.len = 0;
+  s->as.heap.aux.capa = capa;
+  s->as.heap.ptr = (char *)mrb_malloc(mrb, capa+1);
+  RSTR_PTR(s)[0] = '\0';
+
+  return mrb_obj_value(s);
+}
+
+static void
+resize_capa(mrb_state *mrb, struct RString *s, size_t capacity)
+{
+#if SIZE_MAX > MRB_INT_MAX
+    mrb_assert(capacity < MRB_INT_MAX);
+#endif
+  if (RSTR_EMBED_P(s)) {
+    if (RSTRING_EMBED_LEN_MAX < capacity) {
+      char *const tmp = (char *)mrb_malloc(mrb, capacity+1);
+      const mrb_int len = RSTR_EMBED_LEN(s);
+      memcpy(tmp, s->as.ary, len);
+      RSTR_UNSET_EMBED_FLAG(s);
+      s->as.heap.ptr = tmp;
+      s->as.heap.len = len;
+      s->as.heap.aux.capa = (mrb_int)capacity;
+    }
+  }
+  else {
+    s->as.heap.ptr = (char*)mrb_realloc(mrb, RSTR_PTR(s), capacity+1);
+    s->as.heap.aux.capa = (mrb_int)capacity;
+  }
+}
+
+static void
+str_buf_cat(mrb_state *mrb, struct RString *s, const char *ptr, size_t len)
+{
+  size_t capa;
+  size_t total;
+  ptrdiff_t off = -1;
+
+  if (len == 0) return;
+  mrb_str_modify(mrb, s);
+  if (ptr >= RSTR_PTR(s) && ptr <= RSTR_PTR(s) + (size_t)RSTR_LEN(s)) {
+      off = ptr - RSTR_PTR(s);
+  }
+
+  capa = RSTR_CAPA(s);
+  if (capa <= RSTRING_EMBED_LEN_MAX)
+    capa = RSTRING_EMBED_LEN_MAX+1;
+
+  total = RSTR_LEN(s)+len;
+  if (total >= MRB_INT_MAX) {
+  size_error:
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
+  }
+  if (capa <= total) {
+    while (total > capa) {
+      if (capa <= MRB_INT_MAX / 2) {
+        capa *= 2;
+      }
+      else {
+        capa = total;
+      }
+    }
+    if (capa < total || capa > MRB_INT_MAX) {
+      goto size_error;
+    }
+    resize_capa(mrb, s, capa);
+  }
+  if (off != -1) {
+      ptr = RSTR_PTR(s) + off;
+  }
+  memcpy(RSTR_PTR(s) + RSTR_LEN(s), ptr, len);
+  mrb_assert_int_fit(size_t, total, mrb_int, MRB_INT_MAX);
+  RSTR_SET_LEN(s, total);
+  RSTR_PTR(s)[total] = '\0';   /* sentinel */
+}
+
+MRB_API mrb_value
+mrb_str_new(mrb_state *mrb, const char *p, size_t len)
+{
+  return mrb_obj_value(str_new(mrb, p, len));
+}
+
+/*
+ *  call-seq: (Caution! NULL string)
+ *     String.new(str="")   => new_str
+ *
+ *  Returns a new string object containing a copy of <i>str</i>.
+ */
+
+MRB_API mrb_value
+mrb_str_new_cstr(mrb_state *mrb, const char *p)
+{
+  struct RString *s;
+  size_t len;
+
+  if (p) {
+    len = strlen(p);
+  }
+  else {
+    len = 0;
+  }
+
+  s = str_new(mrb, p, len);
+
+  return mrb_obj_value(s);
+}
+
+MRB_API mrb_value
+mrb_str_new_static(mrb_state *mrb, const char *p, size_t len)
+{
+  struct RString *s = str_new_static(mrb, p, len);
+  return mrb_obj_value(s);
+}
+
+static void
+str_decref(mrb_state *mrb, mrb_shared_string *shared)
+{
+  shared->refcnt--;
+  if (shared->refcnt == 0) {
+    if (!shared->nofree) {
+      mrb_free(mrb, shared->ptr);
+    }
+    mrb_free(mrb, shared);
+  }
+}
+
+void
+mrb_gc_free_str(mrb_state *mrb, struct RString *str)
+{
+  if (RSTR_EMBED_P(str))
+    /* no code */;
+  else if (RSTR_SHARED_P(str))
+    str_decref(mrb, str->as.heap.aux.shared);
+  else if (!RSTR_NOFREE_P(str))
+    mrb_free(mrb, str->as.heap.ptr);
+}
+
+#ifdef MRB_UTF8_STRING
+static const char utf8len_codepage[256] =
+{
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,
+};
+
+static mrb_int
+utf8len(const char* p, const char* e)
+{
+  mrb_int len;
+  mrb_int i;
+
+  len = utf8len_codepage[(unsigned char)*p];
+  if (p + len > e) return 1;
+  for (i = 1; i < len; ++i)
+    if ((p[i] & 0xc0) != 0x80)
+      return 1;
+  return len;
+}
+
+static mrb_int
+utf8_strlen(mrb_value str, mrb_int len)
+{
+  mrb_int total = 0;
+  char* p = RSTRING_PTR(str);
+  char* e = p;
+  if (RSTRING(str)->flags & MRB_STR_NO_UTF) {
+    return RSTRING_LEN(str);
+  }
+  e += len < 0 ? RSTRING_LEN(str) : len;
+  while (p<e) {
+    p += utf8len(p, e);
+    total++;
+  }
+  if (RSTRING_LEN(str) == total) {
+    RSTRING(str)->flags |= MRB_STR_NO_UTF;
+  }
+  return total;
+}
+
+#define RSTRING_CHAR_LEN(s) utf8_strlen(s, -1)
+
+/* map character index to byte offset index */
+static mrb_int
+chars2bytes(mrb_value s, mrb_int off, mrb_int idx)
+{
+  mrb_int i, b, n;
+  const char *p = RSTRING_PTR(s) + off;
+  const char *e = RSTRING_END(s);
+
+  for (b=i=0; p<e && i<idx; i++) {
+    n = utf8len(p, e);
+    b += n;
+    p += n;
+  }
+  return b;
+}
+
+/* map byte offset to character index */
+static mrb_int
+bytes2chars(char *p, mrb_int bi)
+{
+  mrb_int i, b, n;
+
+  for (b=i=0; b<bi; i++) {
+    n = utf8len_codepage[(unsigned char)*p];
+    b += n;
+    p += n;
+  }
+  if (b != bi) return -1;
+  return i;
+}
+
+#define BYTES_ALIGN_CHECK(pos) if (pos < 0) return mrb_nil_value();
+#else
+#define RSTRING_CHAR_LEN(s) RSTRING_LEN(s)
+#define chars2bytes(p, off, ci) (ci)
+#define bytes2chars(p, bi) (bi)
+#define BYTES_ALIGN_CHECK(pos)
+#endif
+
+static inline mrb_int
+mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mrb_int n)
+{
+  const unsigned char *x = xs, *xe = xs + m;
+  const unsigned char *y = ys;
+  int i, qstable[256];
+
+  /* Preprocessing */
+  for (i = 0; i < 256; ++i)
+    qstable[i] = m + 1;
+  for (; x < xe; ++x)
+    qstable[*x] = xe - x;
+  /* Searching */
+  for (; y + m <= ys + n; y += *(qstable + y[m])) {
+    if (*xs == *y && memcmp(xs, y, m) == 0)
+      return y - ys;
+  }
+  return -1;
+}
+
+static mrb_int
+mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n)
+{
+  const unsigned char *x = (const unsigned char *)x0, *y = (const unsigned char *)y0;
+
+  if (m > n) return -1;
+  else if (m == n) {
+    return memcmp(x0, y0, m) == 0 ? 0 : -1;
+  }
+  else if (m < 1) {
+    return 0;
+  }
+  else if (m == 1) {
+    const unsigned char *ys = (const unsigned char *)memchr(y, *x, n);
+
+    if (ys)
+      return ys - y;
+    else
+      return -1;
+  }
+  return mrb_memsearch_qs((const unsigned char *)x0, m, (const unsigned char *)y0, n);
+}
+
+static void
+str_make_shared(mrb_state *mrb, struct RString *s)
+{
+  if (!RSTR_SHARED_P(s)) {
+    mrb_shared_string *shared = (mrb_shared_string *)mrb_malloc(mrb, sizeof(mrb_shared_string));
+
+    shared->refcnt = 1;
+    if (RSTR_EMBED_P(s)) {
+      const mrb_int len = RSTR_EMBED_LEN(s);
+      char *const tmp = (char *)mrb_malloc(mrb, len+1);
+      memcpy(tmp, s->as.ary, len);
+      tmp[len] = '\0';
+      RSTR_UNSET_EMBED_FLAG(s);
+      s->as.heap.ptr = tmp;
+      s->as.heap.len = len;
+      shared->nofree = FALSE;
+      shared->ptr = s->as.heap.ptr;
+    }
+    else if (RSTR_NOFREE_P(s)) {
+      shared->nofree = TRUE;
+      shared->ptr = s->as.heap.ptr;
+      RSTR_UNSET_NOFREE_FLAG(s);
+    }
+    else {
+      shared->nofree = FALSE;
+      if (s->as.heap.aux.capa > s->as.heap.len) {
+        s->as.heap.ptr = shared->ptr = (char *)mrb_realloc(mrb, s->as.heap.ptr, s->as.heap.len+1);
+      }
+      else {
+        shared->ptr = s->as.heap.ptr;
+      }
+    }
+    shared->len = s->as.heap.len;
+    s->as.heap.aux.shared = shared;
+    RSTR_SET_SHARED_FLAG(s);
+  }
+}
+
+static mrb_value
+byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
+{
+  struct RString *orig, *s;
+  mrb_shared_string *shared;
+
+  orig = mrb_str_ptr(str);
+  if (RSTR_EMBED_P(orig) || RSTR_LEN(orig) == 0) {
+    s = str_new(mrb, orig->as.ary+beg, len);
+  }
+  else {
+    str_make_shared(mrb, orig);
+    shared = orig->as.heap.aux.shared;
+    s = mrb_obj_alloc_string(mrb);
+    s->as.heap.ptr = orig->as.heap.ptr + beg;
+    s->as.heap.len = len;
+    s->as.heap.aux.shared = shared;
+    RSTR_SET_SHARED_FLAG(s);
+    shared->refcnt++;
+  }
+
+  return mrb_obj_value(s);
+}
+#ifdef MRB_UTF8_STRING
+static inline mrb_value
+str_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
+{
+  beg = chars2bytes(str, 0, beg);
+  len = chars2bytes(str, beg, len);
+
+  return byte_subseq(mrb, str, beg, len);
+}
+#else
+#define str_subseq(mrb, str, beg, len) byte_subseq(mrb, str, beg, len)
+#endif
+
+static mrb_value
+str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
+{
+  mrb_int clen = RSTRING_CHAR_LEN(str);
+
+  if (len < 0) return mrb_nil_value();
+  if (clen == 0) {
+    len = 0;
+  }
+  else if (beg < 0) {
+    beg = clen + beg;
+  }
+  if (beg > clen) return mrb_nil_value();
+  if (beg < 0) {
+    beg += clen;
+    if (beg < 0) return mrb_nil_value();
+  }
+  if (len > clen - beg)
+    len = clen - beg;
+  if (len <= 0) {
+    len = 0;
+  }
+  return str_subseq(mrb, str, beg, len);
+}
+
+static mrb_int
+str_index(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int offset)
+{
+  mrb_int pos;
+  char *s, *sptr;
+  mrb_int len, slen;
+
+  len = RSTRING_LEN(str);
+  slen = RSTRING_LEN(sub);
+  if (offset < 0) {
+    offset += len;
+    if (offset < 0) return -1;
+  }
+  if (len - offset < slen) return -1;
+  s = RSTRING_PTR(str);
+  if (offset) {
+    s += offset;
+  }
+  if (slen == 0) return offset;
+  /* need proceed one character at a time */
+  sptr = RSTRING_PTR(sub);
+  slen = RSTRING_LEN(sub);
+  len = RSTRING_LEN(str) - offset;
+  pos = mrb_memsearch(sptr, slen, s, len);
+  if (pos < 0) return pos;
+  return pos + offset;
+}
+
+static void
+check_frozen(mrb_state *mrb, struct RString *s)
+{
+  if (MRB_FROZEN_P(s)) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen string");
+  }
+}
+
+static mrb_value
+str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2)
+{
+  long len;
+
+  check_frozen(mrb, s1);
+  if (s1 == s2) return mrb_obj_value(s1);
+  s1->flags &= ~MRB_STR_NO_UTF;
+  s1->flags |= s2->flags&MRB_STR_NO_UTF;
+  len = RSTR_LEN(s2);
+  if (RSTR_SHARED_P(s1)) {
+    str_decref(mrb, s1->as.heap.aux.shared);
+  }
+  else if (!RSTR_EMBED_P(s1) && !RSTR_NOFREE_P(s1)) {
+    mrb_free(mrb, s1->as.heap.ptr);
+  }
+
+  RSTR_UNSET_NOFREE_FLAG(s1);
+
+  if (RSTR_SHARED_P(s2)) {
+L_SHARE:
+    RSTR_UNSET_EMBED_FLAG(s1);
+    s1->as.heap.ptr = s2->as.heap.ptr;
+    s1->as.heap.len = len;
+    s1->as.heap.aux.shared = s2->as.heap.aux.shared;
+    RSTR_SET_SHARED_FLAG(s1);
+    s1->as.heap.aux.shared->refcnt++;
+  }
+  else {
+    if (len <= RSTRING_EMBED_LEN_MAX) {
+      RSTR_UNSET_SHARED_FLAG(s1);
+      RSTR_SET_EMBED_FLAG(s1);
+      memcpy(s1->as.ary, RSTR_PTR(s2), len);
+      RSTR_SET_EMBED_LEN(s1, len);
+    }
+    else {
+      str_make_shared(mrb, s2);
+      goto L_SHARE;
+    }
+  }
+
+  return mrb_obj_value(s1);
+}
+
+static mrb_int
+str_rindex(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos)
+{
+  char *s, *sbeg, *t;
+  struct RString *ps = mrb_str_ptr(str);
+  mrb_int len = RSTRING_LEN(sub);
+
+  /* substring longer than string */
+  if (RSTR_LEN(ps) < len) return -1;
+  if (RSTR_LEN(ps) - pos < len) {
+    pos = RSTR_LEN(ps) - len;
+  }
+  sbeg = RSTR_PTR(ps);
+  s = RSTR_PTR(ps) + pos;
+  t = RSTRING_PTR(sub);
+  if (len) {
+    while (sbeg <= s) {
+      if (memcmp(s, t, len) == 0) {
+        return s - RSTR_PTR(ps);
+      }
+      s--;
+    }
+    return -1;
+  }
+  else {
+    return pos;
+  }
+}
+
+MRB_API mrb_int
+mrb_str_strlen(mrb_state *mrb, struct RString *s)
+{
+  mrb_int i, max = RSTR_LEN(s);
+  char *p = RSTR_PTR(s);
+
+  if (!p) return 0;
+  for (i=0; i<max; i++) {
+    if (p[i] == '\0') {
+      mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte");
+    }
+  }
+  return max;
+}
+
+#ifdef _WIN32
+#include <windows.h>
+
+char*
+mrb_utf8_from_locale(const char *str, size_t len)
+{
+  wchar_t* wcsp;
+  char* mbsp;
+  size_t mbssize, wcssize;
+
+  if (len == 0)
+    return strdup("");
+  if (len == -1)
+    len = strlen(str);
+  wcssize = MultiByteToWideChar(GetACP(), 0, str, len,  NULL, 0);
+  wcsp = (wchar_t*) malloc((wcssize + 1) * sizeof(wchar_t));
+  if (!wcsp)
+    return NULL;
+  wcssize = MultiByteToWideChar(GetACP(), 0, str, len, wcsp, wcssize + 1);
+  wcsp[wcssize] = 0;
+
+  mbssize = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) wcsp, -1, NULL, 0, NULL, NULL);
+  mbsp = (char*) malloc((mbssize + 1));
+  if (!mbsp) {
+    free(wcsp);
+    return NULL;
+  }
+  mbssize = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) wcsp, -1, mbsp, mbssize, NULL, NULL);
+  mbsp[mbssize] = 0;
+  free(wcsp);
+  return mbsp;
+}
+
+char*
+mrb_locale_from_utf8(const char *utf8, size_t len)
+{
+  wchar_t* wcsp;
+  char* mbsp;
+  size_t mbssize, wcssize;
+
+  if (len == 0)
+    return strdup("");
+  if (len == -1)
+    len = strlen(utf8);
+  wcssize = MultiByteToWideChar(CP_UTF8, 0, utf8, len,  NULL, 0);
+  wcsp = (wchar_t*) malloc((wcssize + 1) * sizeof(wchar_t));
+  if (!wcsp)
+    return NULL;
+  wcssize = MultiByteToWideChar(CP_UTF8, 0, utf8, len, wcsp, wcssize + 1);
+  wcsp[wcssize] = 0;
+  mbssize = WideCharToMultiByte(GetACP(), 0, (LPCWSTR) wcsp, -1, NULL, 0, NULL, NULL);
+  mbsp = (char*) malloc((mbssize + 1));
+  if (!mbsp) {
+    free(wcsp);
+    return NULL;
+  }
+  mbssize = WideCharToMultiByte(GetACP(), 0, (LPCWSTR) wcsp, -1, mbsp, mbssize, NULL, NULL);
+  mbsp[mbssize] = 0;
+  free(wcsp);
+  return mbsp;
+}
+#endif
+
+MRB_API void
+mrb_str_modify(mrb_state *mrb, struct RString *s)
+{
+  check_frozen(mrb, s);
+  s->flags &= ~MRB_STR_NO_UTF;
+  if (RSTR_SHARED_P(s)) {
+    mrb_shared_string *shared = s->as.heap.aux.shared;
+
+    if (shared->nofree == 0 && shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) {
+      s->as.heap.ptr = shared->ptr;
+      s->as.heap.aux.capa = shared->len;
+      RSTR_PTR(s)[s->as.heap.len] = '\0';
+      mrb_free(mrb, shared);
+    }
+    else {
+      char *ptr, *p;
+      mrb_int len;
+
+      p = RSTR_PTR(s);
+      len = s->as.heap.len;
+      if (len < RSTRING_EMBED_LEN_MAX) {
+        RSTR_SET_EMBED_FLAG(s);
+        RSTR_SET_EMBED_LEN(s, len);
+        ptr = RSTR_PTR(s);
+      }
+      else {
+        ptr = (char *)mrb_malloc(mrb, (size_t)len + 1);
+        s->as.heap.ptr = ptr;
+        s->as.heap.aux.capa = len;
+      }
+      if (p) {
+        memcpy(ptr, p, len);
+      }
+      ptr[len] = '\0';
+      str_decref(mrb, shared);
+    }
+    RSTR_UNSET_SHARED_FLAG(s);
+    return;
+  }
+  if (RSTR_NOFREE_P(s)) {
+    char *p = s->as.heap.ptr;
+    mrb_int len = s->as.heap.len;
+
+    RSTR_UNSET_NOFREE_FLAG(s);
+    if (len < RSTRING_EMBED_LEN_MAX) {
+      RSTR_SET_EMBED_FLAG(s);
+      RSTR_SET_EMBED_LEN(s, len);
+    }
+    else {
+      s->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1);
+      s->as.heap.aux.capa = len;
+    }
+    if (p) {
+      memcpy(RSTR_PTR(s), p, len);
+    }
+    RSTR_PTR(s)[len] = '\0';
+    return;
+  }
+}
+
+MRB_API mrb_value
+mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len)
+{
+  mrb_int slen;
+  struct RString *s = mrb_str_ptr(str);
+
+  mrb_str_modify(mrb, s);
+  slen = RSTR_LEN(s);
+  if (len != slen) {
+    if (slen < len || slen - len > 256) {
+      resize_capa(mrb, s, len);
+    }
+    RSTR_SET_LEN(s, len);
+    RSTR_PTR(s)[len] = '\0';   /* sentinel */
+  }
+  return str;
+}
+
+MRB_API char*
+mrb_str_to_cstr(mrb_state *mrb, mrb_value str0)
+{
+  struct RString *s;
+
+  if (!mrb_string_p(str0)) {
+    mrb_raise(mrb, E_TYPE_ERROR, "expected String");
+  }
+
+  s = str_new(mrb, RSTRING_PTR(str0), RSTRING_LEN(str0));
+  if ((strlen(RSTR_PTR(s)) ^ RSTR_LEN(s)) != 0) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte");
+  }
+  return RSTR_PTR(s);
+}
+
+/*
+ *  call-seq: (Caution! String("abcd") change)
+ *     String("abcdefg") = String("abcd") + String("efg")
+ *
+ *  Returns a new string object containing a copy of <i>str</i>.
+ */
+MRB_API void
+mrb_str_concat(mrb_state *mrb, mrb_value self, mrb_value other)
+{
+  struct RString *s1 = mrb_str_ptr(self), *s2;
+  mrb_int len;
+
+  mrb_str_modify(mrb, s1);
+  if (!mrb_string_p(other)) {
+    other = mrb_str_to_str(mrb, other);
+  }
+  s2 = mrb_str_ptr(other);
+  if (RSTR_LEN(s2) == 0) {
+    return;
+  }
+  len = RSTR_LEN(s1) + RSTR_LEN(s2);
+
+  if (len < 0 || len >= MRB_INT_MAX) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
+  }
+  if (RSTRING_CAPA(self) < len) {
+    resize_capa(mrb, s1, len);
+  }
+  memcpy(RSTR_PTR(s1)+RSTR_LEN(s1), RSTR_PTR(s2), RSTR_LEN(s2));
+  RSTR_SET_LEN(s1, len);
+  RSTR_PTR(s1)[len] = '\0';
+}
+
+/*
+ *  call-seq: (Caution! String("abcd") remain)
+ *     String("abcdefg") = String("abcd") + String("efg")
+ *
+ *  Returns a new string object containing a copy of <i>str</i>.
+ */
+MRB_API mrb_value
+mrb_str_plus(mrb_state *mrb, mrb_value a, mrb_value b)
+{
+  struct RString *s = mrb_str_ptr(a);
+  struct RString *s2 = mrb_str_ptr(b);
+  struct RString *t;
+
+  t = str_new(mrb, 0, RSTR_LEN(s) + RSTR_LEN(s2));
+  memcpy(RSTR_PTR(t), RSTR_PTR(s), RSTR_LEN(s));
+  memcpy(RSTR_PTR(t) + RSTR_LEN(s), RSTR_PTR(s2), RSTR_LEN(s2));
+
+  return mrb_obj_value(t);
+}
+
+/* 15.2.10.5.2  */
+
+/*
+ *  call-seq: (Caution! String("abcd") remain) for stack_argument
+ *     String("abcdefg") = String("abcd") + String("efg")
+ *
+ *  Returns a new string object containing a copy of <i>str</i>.
+ */
+static mrb_value
+mrb_str_plus_m(mrb_state *mrb, mrb_value self)
+{
+  mrb_value str;
+
+  mrb_get_args(mrb, "S", &str);
+  return mrb_str_plus(mrb, self, str);
+}
+
+/* 15.2.10.5.26 */
+/* 15.2.10.5.33 */
+/*
+ *  call-seq:
+ *     "abcd".size   => int
+ *
+ *  Returns the length of string.
+ */
+static mrb_value
+mrb_str_size(mrb_state *mrb, mrb_value self)
+{
+  mrb_int len = RSTRING_CHAR_LEN(self);
+  return mrb_fixnum_value(len);
+}
+
+static mrb_value
+mrb_str_bytesize(mrb_state *mrb, mrb_value self)
+{
+  mrb_int len = RSTRING_LEN(self);
+  return mrb_fixnum_value(len);
+}
+
+/* 15.2.10.5.1  */
+/*
+ *  call-seq:
+ *     str * integer   => new_str
+ *
+ *  Copy---Returns a new <code>String</code> containing <i>integer</i> copies of
+ *  the receiver.
+ *
+ *     "Ho! " * 3   #=> "Ho! Ho! Ho! "
+ */
+static mrb_value
+mrb_str_times(mrb_state *mrb, mrb_value self)
+{
+  mrb_int n,len,times;
+  struct RString *str2;
+  char *p;
+
+  mrb_get_args(mrb, "i", &times);
+  if (times < 0) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument");
+  }
+  if (times && MRB_INT_MAX / times < RSTRING_LEN(self)) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "argument too big");
+  }
+
+  len = RSTRING_LEN(self)*times;
+  str2 = str_new(mrb, 0, len);
+  str_with_class(mrb, str2, self);
+  p = RSTR_PTR(str2);
+  if (len > 0) {
+    n = RSTRING_LEN(self);
+    memcpy(p, RSTRING_PTR(self), n);
+    while (n <= len/2) {
+      memcpy(p + n, p, n);
+      n *= 2;
+    }
+    memcpy(p + n, p, len-n);
+  }
+  p[RSTR_LEN(str2)] = '\0';
+
+  return mrb_obj_value(str2);
+}
+/* -------------------------------------------------------------- */
+
+#define lesser(a,b) (((a)>(b))?(b):(a))
+
+/* ---------------------------*/
+/*
+ *  call-seq:
+ *     mrb_value str1 <=> mrb_value str2   => int
+ *                     >  1
+ *                     =  0
+ *                     <  -1
+ */
+MRB_API int
+mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2)
+{
+  mrb_int len;
+  mrb_int retval;
+  struct RString *s1 = mrb_str_ptr(str1);
+  struct RString *s2 = mrb_str_ptr(str2);
+
+  len = lesser(RSTR_LEN(s1), RSTR_LEN(s2));
+  retval = memcmp(RSTR_PTR(s1), RSTR_PTR(s2), len);
+  if (retval == 0) {
+    if (RSTR_LEN(s1) == RSTR_LEN(s2)) return 0;
+    if (RSTR_LEN(s1) > RSTR_LEN(s2))  return 1;
+    return -1;
+  }
+  if (retval > 0) return 1;
+  return -1;
+}
+
+/* 15.2.10.5.3  */
+
+/*
+ *  call-seq:
+ *     str <=> other_str   => -1, 0, +1
+ *
+ *  Comparison---Returns -1 if <i>other_str</i> is less than, 0 if
+ *  <i>other_str</i> is equal to, and +1 if <i>other_str</i> is greater than
+ *  <i>str</i>. If the strings are of different lengths, and the strings are
+ *  equal when compared up to the shortest length, then the longer string is
+ *  considered greater than the shorter one. If the variable <code>$=</code> is
+ *  <code>false</code>, the comparison is based on comparing the binary values
+ *  of each character in the string. In older versions of Ruby, setting
+ *  <code>$=</code> allowed case-insensitive comparisons; this is now deprecated
+ *  in favor of using <code>String#casecmp</code>.
+ *
+ *  <code><=></code> is the basis for the methods <code><</code>,
+ *  <code><=</code>, <code>></code>, <code>>=</code>, and <code>between?</code>,
+ *  included from module <code>Comparable</code>.  The method
+ *  <code>String#==</code> does not use <code>Comparable#==</code>.
+ *
+ *     "abcdef" <=> "abcde"     #=> 1
+ *     "abcdef" <=> "abcdef"    #=> 0
+ *     "abcdef" <=> "abcdefg"   #=> -1
+ *     "abcdef" <=> "ABCDEF"    #=> 1
+ */
+static mrb_value
+mrb_str_cmp_m(mrb_state *mrb, mrb_value str1)
+{
+  mrb_value str2;
+  mrb_int result;
+
+  mrb_get_args(mrb, "o", &str2);
+  if (!mrb_string_p(str2)) {
+    if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "to_s"))) {
+      return mrb_nil_value();
+    }
+    else if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "<=>"))) {
+      return mrb_nil_value();
+    }
+    else {
+      mrb_value tmp = mrb_funcall(mrb, str2, "<=>", 1, str1);
+
+      if (!mrb_nil_p(tmp)) return mrb_nil_value();
+      if (!mrb_fixnum_p(tmp)) {
+        return mrb_funcall(mrb, mrb_fixnum_value(0), "-", 1, tmp);
+      }
+      result = -mrb_fixnum(tmp);
+    }
+  }
+  else {
+    result = mrb_str_cmp(mrb, str1, str2);
+  }
+  return mrb_fixnum_value(result);
+}
+
+static mrb_bool
+str_eql(mrb_state *mrb, const mrb_value str1, const mrb_value str2)
+{
+  const mrb_int len = RSTRING_LEN(str1);
+
+  if (len != RSTRING_LEN(str2)) return FALSE;
+  if (memcmp(RSTRING_PTR(str1), RSTRING_PTR(str2), (size_t)len) == 0)
+    return TRUE;
+  return FALSE;
+}
+
+MRB_API mrb_bool
+mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2)
+{
+  if (mrb_immediate_p(str2)) return FALSE;
+  if (!mrb_string_p(str2)) {
+    if (mrb_nil_p(str2)) return FALSE;
+    if (!mrb_respond_to(mrb, str2, mrb_intern_lit(mrb, "to_str"))) {
+      return FALSE;
+    }
+    str2 = mrb_funcall(mrb, str2, "to_str", 0);
+    return mrb_equal(mrb, str2, str1);
+  }
+  return str_eql(mrb, str1, str2);
+}
+
+/* 15.2.10.5.4  */
+/*
+ *  call-seq:
+ *     str == obj   => true or false
+ *
+ *  Equality---
+ *  If <i>obj</i> is not a <code>String</code>, returns <code>false</code>.
+ *  Otherwise, returns <code>false</code> or <code>true</code>
+ *
+ *   caution:if <i>str</i> <code><=></code> <i>obj</i> returns zero.
+ */
+static mrb_value
+mrb_str_equal_m(mrb_state *mrb, mrb_value str1)
+{
+  mrb_value str2;
+
+  mrb_get_args(mrb, "o", &str2);
+
+  return mrb_bool_value(mrb_str_equal(mrb, str1, str2));
+}
+/* ---------------------------------- */
+MRB_API mrb_value
+mrb_str_to_str(mrb_state *mrb, mrb_value str)
+{
+  mrb_value s;
+
+  if (!mrb_string_p(str)) {
+    s = mrb_check_convert_type(mrb, str, MRB_TT_STRING, "String", "to_str");
+    if (mrb_nil_p(s)) {
+      s = mrb_convert_type(mrb, str, MRB_TT_STRING, "String", "to_s");
+    }
+    return s;
+  }
+  return str;
+}
+
+MRB_API const char*
+mrb_string_value_ptr(mrb_state *mrb, mrb_value ptr)
+{
+  mrb_value str = mrb_str_to_str(mrb, ptr);
+  return RSTRING_PTR(str);
+}
+
+MRB_API mrb_int
+mrb_string_value_len(mrb_state *mrb, mrb_value ptr)
+{
+  mrb_value str = mrb_str_to_str(mrb, ptr);
+  return RSTRING_LEN(str);
+}
+
+void
+mrb_noregexp(mrb_state *mrb, mrb_value self)
+{
+  mrb_raise(mrb, E_NOTIMP_ERROR, "Regexp class not implemented");
+}
+
+void
+mrb_regexp_check(mrb_state *mrb, mrb_value obj)
+{
+  if (mrb_regexp_p(mrb, obj)) {
+    mrb_noregexp(mrb, obj);
+  }
+}
+
+MRB_API mrb_value
+mrb_str_dup(mrb_state *mrb, mrb_value str)
+{
+  struct RString *s = mrb_str_ptr(str);
+  struct RString *dup = str_new(mrb, 0, 0);
+
+  str_with_class(mrb, dup, str);
+  return str_replace(mrb, dup, s);
+}
+
+static mrb_value
+mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx)
+{
+  mrb_int idx;
+
+  mrb_regexp_check(mrb, indx);
+  switch (mrb_type(indx)) {
+    case MRB_TT_FIXNUM:
+      idx = mrb_fixnum(indx);
+
+num_index:
+      str = str_substr(mrb, str, idx, 1);
+      if (!mrb_nil_p(str) && RSTRING_LEN(str) == 0) return mrb_nil_value();
+      return str;
+
+    case MRB_TT_STRING:
+      if (str_index(mrb, str, indx, 0) != -1)
+        return mrb_str_dup(mrb, indx);
+      return mrb_nil_value();
+
+    case MRB_TT_RANGE:
+      goto range_arg;
+
+    default:
+      indx = mrb_Integer(mrb, indx);
+      if (mrb_nil_p(indx)) {
+      range_arg:
+        {
+          mrb_int beg, len;
+
+          len = RSTRING_CHAR_LEN(str);
+          switch (mrb_range_beg_len(mrb, indx, &beg, &len, len, TRUE)) {
+          case 1:
+            return str_subseq(mrb, str, beg, len);
+          case 2:
+            return mrb_nil_value();
+          default:
+            break;
+          }
+        }
+        mrb_raise(mrb, E_TYPE_ERROR, "can't convert to Fixnum");
+      }
+      idx = mrb_fixnum(indx);
+      goto num_index;
+  }
+  return mrb_nil_value();    /* not reached */
+}
+
+/* 15.2.10.5.6  */
+/* 15.2.10.5.34 */
+/*
+ *  call-seq:
+ *     str[fixnum]                 => fixnum or nil
+ *     str[fixnum, fixnum]         => new_str or nil
+ *     str[range]                  => new_str or nil
+ *     str[regexp]                 => new_str or nil
+ *     str[regexp, fixnum]         => new_str or nil
+ *     str[other_str]              => new_str or nil
+ *     str.slice(fixnum)           => fixnum or nil
+ *     str.slice(fixnum, fixnum)   => new_str or nil
+ *     str.slice(range)            => new_str or nil
+ *     str.slice(other_str)        => new_str or nil
+ *
+ *  Element Reference---If passed a single <code>Fixnum</code>, returns the code
+ *  of the character at that position. If passed two <code>Fixnum</code>
+ *  objects, returns a substring starting at the offset given by the first, and
+ *  a length given by the second. If given a range, a substring containing
+ *  characters at offsets given by the range is returned. In all three cases, if
+ *  an offset is negative, it is counted from the end of <i>str</i>. Returns
+ *  <code>nil</code> if the initial offset falls outside the string, the length
+ *  is negative, or the beginning of the range is greater than the end.
+ *
+ *  If a <code>String</code> is given, that string is returned if it occurs in
+ *  <i>str</i>. In both cases, <code>nil</code> is returned if there is no
+ *  match.
+ *
+ *     a = "hello there"
+ *     a[1]                   #=> 101(1.8.7) "e"(1.9.2)
+ *     a[1.1]                 #=>            "e"(1.9.2)
+ *     a[1,3]                 #=> "ell"
+ *     a[1..3]                #=> "ell"
+ *     a[-3,2]                #=> "er"
+ *     a[-4..-2]              #=> "her"
+ *     a[12..-1]              #=> nil
+ *     a[-2..-4]              #=> ""
+ *     a["lo"]                #=> "lo"
+ *     a["bye"]               #=> nil
+ */
+static mrb_value
+mrb_str_aref_m(mrb_state *mrb, mrb_value str)
+{
+  mrb_value a1, a2;
+  int argc;
+
+  argc = mrb_get_args(mrb, "o|o", &a1, &a2);
+  if (argc == 2) {
+    mrb_int n1, n2;
+
+    mrb_regexp_check(mrb, a1);
+    mrb_get_args(mrb, "ii", &n1, &n2);
+    return str_substr(mrb, str, n1, n2);
+  }
+  if (argc != 1) {
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%S for 1)", mrb_fixnum_value(argc));
+  }
+  return mrb_str_aref(mrb, str, a1);
+}
+
+/* 15.2.10.5.8  */
+/*
+ *  call-seq:
+ *     str.capitalize!   => str or nil
+ *
+ *  Modifies <i>str</i> by converting the first character to uppercase and the
+ *  remainder to lowercase. Returns <code>nil</code> if no changes are made.
+ *
+ *     a = "hello"
+ *     a.capitalize!   #=> "Hello"
+ *     a               #=> "Hello"
+ *     a.capitalize!   #=> nil
+ */
+static mrb_value
+mrb_str_capitalize_bang(mrb_state *mrb, mrb_value str)
+{
+  char *p, *pend;
+  mrb_bool modify = FALSE;
+  struct RString *s = mrb_str_ptr(str);
+
+  mrb_str_modify(mrb, s);
+  if (RSTR_LEN(s) == 0 || !RSTR_PTR(s)) return mrb_nil_value();
+  p = RSTR_PTR(s); pend = RSTR_PTR(s) + RSTR_LEN(s);
+  if (ISLOWER(*p)) {
+    *p = TOUPPER(*p);
+    modify = TRUE;
+  }
+  while (++p < pend) {
+    if (ISUPPER(*p)) {
+      *p = TOLOWER(*p);
+      modify = TRUE;
+    }
+  }
+  if (modify) return str;
+  return mrb_nil_value();
+}
+
+/* 15.2.10.5.7  */
+/*
+ *  call-seq:
+ *     str.capitalize   => new_str
+ *
+ *  Returns a copy of <i>str</i> with the first character converted to uppercase
+ *  and the remainder to lowercase.
+ *
+ *     "hello".capitalize    #=> "Hello"
+ *     "HELLO".capitalize    #=> "Hello"
+ *     "123ABC".capitalize   #=> "123abc"
+ */
+static mrb_value
+mrb_str_capitalize(mrb_state *mrb, mrb_value self)
+{
+  mrb_value str;
+
+  str = mrb_str_dup(mrb, self);
+  mrb_str_capitalize_bang(mrb, str);
+  return str;
+}
+
+/* 15.2.10.5.10  */
+/*
+ *  call-seq:
+ *     str.chomp!(separator="\n")   => str or nil
+ *
+ *  Modifies <i>str</i> in place as described for <code>String#chomp</code>,
+ *  returning <i>str</i>, or <code>nil</code> if no modifications were made.
+ */
+static mrb_value
+mrb_str_chomp_bang(mrb_state *mrb, mrb_value str)
+{
+  mrb_value rs;
+  mrb_int newline;
+  char *p, *pp;
+  mrb_int rslen;
+  mrb_int len;
+  mrb_int argc;
+  struct RString *s = mrb_str_ptr(str);
+
+  mrb_str_modify(mrb, s);
+  argc = mrb_get_args(mrb, "|S", &rs);
+  len = RSTR_LEN(s);
+  if (argc == 0) {
+    if (len == 0) return mrb_nil_value();
+  smart_chomp:
+    if (RSTR_PTR(s)[len-1] == '\n') {
+      RSTR_SET_LEN(s, RSTR_LEN(s) - 1);
+      if (RSTR_LEN(s) > 0 &&
+          RSTR_PTR(s)[RSTR_LEN(s)-1] == '\r') {
+        RSTR_SET_LEN(s, RSTR_LEN(s) - 1);
+      }
+    }
+    else if (RSTR_PTR(s)[len-1] == '\r') {
+      RSTR_SET_LEN(s, RSTR_LEN(s) - 1);
+    }
+    else {
+      return mrb_nil_value();
+    }
+    RSTR_PTR(s)[RSTR_LEN(s)] = '\0';
+    return str;
+  }
+
+  if (len == 0 || mrb_nil_p(rs)) return mrb_nil_value();
+  p = RSTR_PTR(s);
+  rslen = RSTRING_LEN(rs);
+  if (rslen == 0) {
+    while (len>0 && p[len-1] == '\n') {
+      len--;
+      if (len>0 && p[len-1] == '\r')
+        len--;
+    }
+    if (len < RSTR_LEN(s)) {
+      RSTR_SET_LEN(s, len);
+      p[len] = '\0';
+      return str;
+    }
+    return mrb_nil_value();
+  }
+  if (rslen > len) return mrb_nil_value();
+  newline = RSTRING_PTR(rs)[rslen-1];
+  if (rslen == 1 && newline == '\n')
+    newline = RSTRING_PTR(rs)[rslen-1];
+  if (rslen == 1 && newline == '\n')
+    goto smart_chomp;
+
+  pp = p + len - rslen;
+  if (p[len-1] == newline &&
+     (rslen <= 1 ||
+     memcmp(RSTRING_PTR(rs), pp, rslen) == 0)) {
+    RSTR_SET_LEN(s, len - rslen);
+    p[RSTR_LEN(s)] = '\0';
+    return str;
+  }
+  return mrb_nil_value();
+}
+
+/* 15.2.10.5.9  */
+/*
+ *  call-seq:
+ *     str.chomp(separator="\n")   => new_str
+ *
+ *  Returns a new <code>String</code> with the given record separator removed
+ *  from the end of <i>str</i> (if present). If <code>$/</code> has not been
+ *  changed from the default Ruby record separator, then <code>chomp</code> also
+ *  removes carriage return characters (that is it will remove <code>\n</code>,
+ *  <code>\r</code>, and <code>\r\n</code>).
+ *
+ *     "hello".chomp            #=> "hello"
+ *     "hello\n".chomp          #=> "hello"
+ *     "hello\r\n".chomp        #=> "hello"
+ *     "hello\n\r".chomp        #=> "hello\n"
+ *     "hello\r".chomp          #=> "hello"
+ *     "hello \n there".chomp   #=> "hello \n there"
+ *     "hello".chomp("llo")     #=> "he"
+ */
+static mrb_value
+mrb_str_chomp(mrb_state *mrb, mrb_value self)
+{
+  mrb_value str;
+
+  str = mrb_str_dup(mrb, self);
+  mrb_str_chomp_bang(mrb, str);
+  return str;
+}
+
+/* 15.2.10.5.12 */
+/*
+ *  call-seq:
+ *     str.chop!   => str or nil
+ *
+ *  Processes <i>str</i> as for <code>String#chop</code>, returning <i>str</i>,
+ *  or <code>nil</code> if <i>str</i> is the empty string.  See also
+ *  <code>String#chomp!</code>.
+ */
+static mrb_value
+mrb_str_chop_bang(mrb_state *mrb, mrb_value str)
+{
+  struct RString *s = mrb_str_ptr(str);
+
+  mrb_str_modify(mrb, s);
+  if (RSTR_LEN(s) > 0) {
+    mrb_int len;
+#ifdef MRB_UTF8_STRING
+    const char* t = RSTR_PTR(s), *p = t;
+    const char* e = p + RSTR_LEN(s);
+    while (p<e) {
+      mrb_int clen = utf8len(p, e);
+      if (p + clen>=e) break;
+      p += clen;
+    }
+    len = p - t;
+#else
+    len = RSTR_LEN(s) - 1;
+#endif
+    if (RSTR_PTR(s)[len] == '\n') {
+      if (len > 0 &&
+          RSTR_PTR(s)[len-1] == '\r') {
+        len--;
+      }
+    }
+    RSTR_SET_LEN(s, len);
+    RSTR_PTR(s)[len] = '\0';
+    return str;
+  }
+  return mrb_nil_value();
+}
+
+/* 15.2.10.5.11 */
+/*
+ *  call-seq:
+ *     str.chop   => new_str
+ *
+ *  Returns a new <code>String</code> with the last character removed.  If the
+ *  string ends with <code>\r\n</code>, both characters are removed. Applying
+ *  <code>chop</code> to an empty string returns an empty
+ *  string. <code>String#chomp</code> is often a safer alternative, as it leaves
+ *  the string unchanged if it doesn't end in a record separator.
+ *
+ *     "string\r\n".chop   #=> "string"
+ *     "string\n\r".chop   #=> "string\n"
+ *     "string\n".chop     #=> "string"
+ *     "string".chop       #=> "strin"
+ *     "x".chop            #=> ""
+ */
+static mrb_value
+mrb_str_chop(mrb_state *mrb, mrb_value self)
+{
+  mrb_value str;
+  str = mrb_str_dup(mrb, self);
+  mrb_str_chop_bang(mrb, str);
+  return str;
+}
+
+/* 15.2.10.5.14 */
+/*
+ *  call-seq:
+ *     str.downcase!   => str or nil
+ *
+ *  Downcases the contents of <i>str</i>, returning <code>nil</code> if no
+ *  changes were made.
+ */
+static mrb_value
+mrb_str_downcase_bang(mrb_state *mrb, mrb_value str)
+{
+  char *p, *pend;
+  mrb_bool modify = FALSE;
+  struct RString *s = mrb_str_ptr(str);
+
+  mrb_str_modify(mrb, s);
+  p = RSTR_PTR(s);
+  pend = RSTR_PTR(s) + RSTR_LEN(s);
+  while (p < pend) {
+    if (ISUPPER(*p)) {
+      *p = TOLOWER(*p);
+      modify = TRUE;
+    }
+    p++;
+  }
+
+  if (modify) return str;
+  return mrb_nil_value();
+}
+
+/* 15.2.10.5.13 */
+/*
+ *  call-seq:
+ *     str.downcase   => new_str
+ *
+ *  Returns a copy of <i>str</i> with all uppercase letters replaced with their
+ *  lowercase counterparts. The operation is locale insensitive---only
+ *  characters 'A' to 'Z' are affected.
+ *
+ *     "hEllO".downcase   #=> "hello"
+ */
+static mrb_value
+mrb_str_downcase(mrb_state *mrb, mrb_value self)
+{
+  mrb_value str;
+
+  str = mrb_str_dup(mrb, self);
+  mrb_str_downcase_bang(mrb, str);
+  return str;
+}
+
+/* 15.2.10.5.16 */
+/*
+ *  call-seq:
+ *     str.empty?   => true or false
+ *
+ *  Returns <code>true</code> if <i>str</i> has a length of zero.
+ *
+ *     "hello".empty?   #=> false
+ *     "".empty?        #=> true
+ */
+static mrb_value
+mrb_str_empty_p(mrb_state *mrb, mrb_value self)
+{
+  struct RString *s = mrb_str_ptr(self);
+
+  return mrb_bool_value(RSTR_LEN(s) == 0);
+}
+
+/* 15.2.10.5.17 */
+/*
+ * call-seq:
+ *   str.eql?(other)   => true or false
+ *
+ * Two strings are equal if the have the same length and content.
+ */
+static mrb_value
+mrb_str_eql(mrb_state *mrb, mrb_value self)
+{
+  mrb_value str2;
+  mrb_bool eql_p;
+
+  mrb_get_args(mrb, "o", &str2);
+  eql_p = (mrb_type(str2) == MRB_TT_STRING) && str_eql(mrb, self, str2);
+
+  return mrb_bool_value(eql_p);
+}
+
+MRB_API mrb_value
+mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
+{
+  return str_substr(mrb, str, beg, len);
+}
+
+mrb_int
+mrb_str_hash(mrb_state *mrb, mrb_value str)
+{
+  /* 1-8-7 */
+  struct RString *s = mrb_str_ptr(str);
+  mrb_int len = RSTR_LEN(s);
+  char *p = RSTR_PTR(s);
+  mrb_int key = 0;
+
+  while (len--) {
+    key = key*65599 + *p;
+    p++;
+  }
+  return key + (key>>5);
+}
+
+/* 15.2.10.5.20 */
+/*
+ * call-seq:
+ *    str.hash   => fixnum
+ *
+ * Return a hash based on the string's length and content.
+ */
+static mrb_value
+mrb_str_hash_m(mrb_state *mrb, mrb_value self)
+{
+  mrb_int key = mrb_str_hash(mrb, self);
+  return mrb_fixnum_value(key);
+}
+
+/* 15.2.10.5.21 */
+/*
+ *  call-seq:
+ *     str.include? other_str   => true or false
+ *     str.include? fixnum      => true or false
+ *
+ *  Returns <code>true</code> if <i>str</i> contains the given string or
+ *  character.
+ *
+ *     "hello".include? "lo"   #=> true
+ *     "hello".include? "ol"   #=> false
+ *     "hello".include? ?h     #=> true
+ */
+static mrb_value
+mrb_str_include(mrb_state *mrb, mrb_value self)
+{
+  mrb_value str2;
+
+  mrb_get_args(mrb, "S", &str2);
+  if (str_index(mrb, self, str2, 0) < 0)
+    return mrb_bool_value(FALSE);
+  return mrb_bool_value(TRUE);
+}
+
+/* 15.2.10.5.22 */
+/*
+ *  call-seq:
+ *     str.index(substring [, offset])   => fixnum or nil
+ *     str.index(fixnum [, offset])      => fixnum or nil
+ *     str.index(regexp [, offset])      => fixnum or nil
+ *
+ *  Returns the index of the first occurrence of the given
+ *  <i>substring</i>,
+ *  character (<i>fixnum</i>), or pattern (<i>regexp</i>) in <i>str</i>.
+ *  Returns
+ *  <code>nil</code> if not found.
+ *  If the second parameter is present, it
+ *  specifies the position in the string to begin the search.
+ *
+ *     "hello".index('e')             #=> 1
+ *     "hello".index('lo')            #=> 3
+ *     "hello".index('a')             #=> nil
+ *     "hello".index(101)             #=> 1(101=0x65='e')
+ *     "hello".index(/[aeiou]/, -3)   #=> 4
+ */
+static mrb_value
+mrb_str_index(mrb_state *mrb, mrb_value str)
+{
+  mrb_value *argv;
+  mrb_int argc;
+  mrb_value sub;
+  mrb_int pos, clen;
+
+  mrb_get_args(mrb, "*", &argv, &argc);
+  if (argc == 2) {
+    mrb_get_args(mrb, "oi", &sub, &pos);
+  }
+  else {
+    pos = 0;
+    if (argc > 0)
+      sub = argv[0];
+    else
+      sub = mrb_nil_value();
+  }
+  mrb_regexp_check(mrb, sub);
+  clen = RSTRING_CHAR_LEN(str);
+  if (pos < 0) {
+    pos += clen;
+    if (pos < 0) {
+      return mrb_nil_value();
+    }
+  }
+  if (pos > clen) return mrb_nil_value();
+  pos = chars2bytes(str, 0, pos);
+
+  switch (mrb_type(sub)) {
+    default: {
+      mrb_value tmp;
+
+      tmp = mrb_check_string_type(mrb, sub);
+      if (mrb_nil_p(tmp)) {
+        mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %S given", sub);
+      }
+      sub = tmp;
+    }
+    /* fall through */
+    case MRB_TT_STRING:
+      pos = str_index(mrb, str, sub, pos);
+      break;
+  }
+
+  if (pos == -1) return mrb_nil_value();
+  pos = bytes2chars(RSTRING_PTR(str), pos);
+  BYTES_ALIGN_CHECK(pos);
+  return mrb_fixnum_value(pos);
+}
+
+#define STR_REPLACE_SHARED_MIN 10
+
+/* 15.2.10.5.24 */
+/* 15.2.10.5.28 */
+/*
+ *  call-seq:
+ *     str.replace(other_str)   => str
+ *
+ *     s = "hello"         #=> "hello"
+ *     s.replace "world"   #=> "world"
+ */
+static mrb_value
+mrb_str_replace(mrb_state *mrb, mrb_value str)
+{
+  mrb_value str2;
+
+  mrb_get_args(mrb, "S", &str2);
+  return str_replace(mrb, mrb_str_ptr(str), mrb_str_ptr(str2));
+}
+
+/* 15.2.10.5.23 */
+/*
+ *  call-seq:
+ *     String.new(str="")   => new_str
+ *
+ *  Returns a new string object containing a copy of <i>str</i>.
+ */
+static mrb_value
+mrb_str_init(mrb_state *mrb, mrb_value self)
+{
+  mrb_value str2;
+
+  if (mrb_get_args(mrb, "|S", &str2) == 0) {
+    struct RString *s = str_new(mrb, 0, 0);
+    str2 = mrb_obj_value(s);
+  }
+  str_replace(mrb, mrb_str_ptr(self), mrb_str_ptr(str2));
+  return self;
+}
+
+/* 15.2.10.5.25 */
+/* 15.2.10.5.41 */
+/*
+ *  call-seq:
+ *     str.intern   => symbol
+ *     str.to_sym   => symbol
+ *
+ *  Returns the <code>Symbol</code> corresponding to <i>str</i>, creating the
+ *  symbol if it did not previously exist. See <code>Symbol#id2name</code>.
+ *
+ *     "Koala".intern         #=> :Koala
+ *     s = 'cat'.to_sym       #=> :cat
+ *     s == :cat              #=> true
+ *     s = '@cat'.to_sym      #=> :@cat
+ *     s == :@cat             #=> true
+ *
+ *  This can also be used to create symbols that cannot be represented using the
+ *  <code>:xxx</code> notation.
+ *
+ *     'cat and dog'.to_sym   #=> :"cat and dog"
+ */
+MRB_API mrb_value
+mrb_str_intern(mrb_state *mrb, mrb_value self)
+{
+  return mrb_symbol_value(mrb_intern_str(mrb, self));
+}
+/* ---------------------------------- */
+MRB_API mrb_value
+mrb_obj_as_string(mrb_state *mrb, mrb_value obj)
+{
+  mrb_value str;
+
+  if (mrb_string_p(obj)) {
+    return obj;
+  }
+  str = mrb_funcall(mrb, obj, "to_s", 0);
+  if (!mrb_string_p(str))
+    return mrb_any_to_s(mrb, obj);
+  return str;
+}
+
+MRB_API mrb_value
+mrb_ptr_to_str(mrb_state *mrb, void *p)
+{
+  struct RString *p_str;
+  char *p1;
+  char *p2;
+  uintptr_t n = (uintptr_t)p;
+
+  p_str = str_new(mrb, NULL, 2 + sizeof(uintptr_t) * CHAR_BIT / 4);
+  p1 = RSTR_PTR(p_str);
+  *p1++ = '0';
+  *p1++ = 'x';
+  p2 = p1;
+
+  do {
+    *p2++ = mrb_digitmap[n % 16];
+    n /= 16;
+  } while (n > 0);
+  *p2 = '\0';
+  RSTR_SET_LEN(p_str, (mrb_int)(p2 - RSTR_PTR(p_str)));
+
+  while (p1 < p2) {
+    const char  c = *p1;
+    *p1++ = *--p2;
+    *p2 = c;
+  }
+
+  return mrb_obj_value(p_str);
+}
+
+MRB_API mrb_value
+mrb_string_type(mrb_state *mrb, mrb_value str)
+{
+  return mrb_convert_type(mrb, str, MRB_TT_STRING, "String", "to_str");
+}
+
+MRB_API mrb_value
+mrb_check_string_type(mrb_state *mrb, mrb_value str)
+{
+  return mrb_check_convert_type(mrb, str, MRB_TT_STRING, "String", "to_str");
+}
+
+/* 15.2.10.5.30 */
+/*
+ *  call-seq:
+ *     str.reverse!   => str
+ *
+ *  Reverses <i>str</i> in place.
+ */
+static mrb_value
+mrb_str_reverse_bang(mrb_state *mrb, mrb_value str)
+{
+#ifdef MRB_UTF8_STRING
+  mrb_int utf8_len = RSTRING_CHAR_LEN(str);
+  mrb_int len = RSTRING_LEN(str);
+
+  if (utf8_len == len) goto bytes;
+  if (utf8_len > 1) {
+    char *buf;
+    char *p, *e, *r;
+
+    mrb_str_modify(mrb, mrb_str_ptr(str));
+    len = RSTRING_LEN(str);
+    buf = (char*)mrb_malloc(mrb, (size_t)len);
+    p = buf;
+    e = buf + len;
+
+    memcpy(buf, RSTRING_PTR(str), len);
+    r = RSTRING_PTR(str) + len;
+
+    while (p<e) {
+      mrb_int clen = utf8len(p, e);
+      r -= clen;
+      memcpy(r, p, clen);
+      p += clen;
+    }
+    mrb_free(mrb, buf);
+  }
+  return str;
+
+ bytes:
+#endif
+  {
+    struct RString *s = mrb_str_ptr(str);
+    char *p, *e;
+    char c;
+
+    mrb_str_modify(mrb, s);
+    if (RSTR_LEN(s) > 1) {
+      p = RSTR_PTR(s);
+      e = p + RSTR_LEN(s) - 1;
+      while (p < e) {
+      c = *p;
+      *p++ = *e;
+      *e-- = c;
+      }
+    }
+    return str;
+  }
+}
+
+/* ---------------------------------- */
+/* 15.2.10.5.29 */
+/*
+ *  call-seq:
+ *     str.reverse   => new_str
+ *
+ *  Returns a new string with the characters from <i>str</i> in reverse order.
+ *
+ *     "stressed".reverse   #=> "desserts"
+ */
+static mrb_value
+mrb_str_reverse(mrb_state *mrb, mrb_value str)
+{
+  mrb_value str2 = mrb_str_dup(mrb, str);
+  mrb_str_reverse_bang(mrb, str2);
+  return str2;
+}
+
+/* 15.2.10.5.31 */
+/*
+ *  call-seq:
+ *     str.rindex(substring [, fixnum])   => fixnum or nil
+ *     str.rindex(fixnum [, fixnum])   => fixnum or nil
+ *     str.rindex(regexp [, fixnum])   => fixnum or nil
+ *
+ *  Returns the index of the last occurrence of the given <i>substring</i>,
+ *  character (<i>fixnum</i>), or pattern (<i>regexp</i>) in <i>str</i>. Returns
+ *  <code>nil</code> if not found. If the second parameter is present, it
+ *  specifies the position in the string to end the search---characters beyond
+ *  this point will not be considered.
+ *
+ *     "hello".rindex('e')             #=> 1
+ *     "hello".rindex('l')             #=> 3
+ *     "hello".rindex('a')             #=> nil
+ *     "hello".rindex(101)             #=> 1
+ *     "hello".rindex(/[aeiou]/, -2)   #=> 1
+ */
+static mrb_value
+mrb_str_rindex(mrb_state *mrb, mrb_value str)
+{
+  mrb_value *argv;
+  mrb_int argc;
+  mrb_value sub;
+  mrb_int pos, len = RSTRING_CHAR_LEN(str);
+
+  mrb_get_args(mrb, "*", &argv, &argc);
+  if (argc == 2) {
+    mrb_get_args(mrb, "oi", &sub, &pos);
+    if (pos < 0) {
+      pos += len;
+      if (pos < 0) {
+        mrb_regexp_check(mrb, sub);
+        return mrb_nil_value();
+      }
+    }
+    if (pos > len) pos = len;
+  }
+  else {
+    pos = len;
+    if (argc > 0)
+      sub = argv[0];
+    else
+      sub = mrb_nil_value();
+  }
+  pos = chars2bytes(str, 0, pos);
+  mrb_regexp_check(mrb, sub);
+
+  switch (mrb_type(sub)) {
+    default: {
+      mrb_value tmp;
+
+      tmp = mrb_check_string_type(mrb, sub);
+      if (mrb_nil_p(tmp)) {
+        mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %S given", sub);
+      }
+      sub = tmp;
+    }
+     /* fall through */
+    case MRB_TT_STRING:
+      pos = str_rindex(mrb, str, sub, pos);
+      if (pos >= 0) {
+        pos = bytes2chars(RSTRING_PTR(str), pos);
+        BYTES_ALIGN_CHECK(pos);
+        return mrb_fixnum_value(pos);
+      }
+      break;
+
+  } /* end of switch (TYPE(sub)) */
+  return mrb_nil_value();
+}
+
+/* 15.2.10.5.35 */
+
+/*
+ *  call-seq:
+ *     str.split(pattern="\n", [limit])   => anArray
+ *
+ *  Divides <i>str</i> into substrings based on a delimiter, returning an array
+ *  of these substrings.
+ *
+ *  If <i>pattern</i> is a <code>String</code>, then its contents are used as
+ *  the delimiter when splitting <i>str</i>. If <i>pattern</i> is a single
+ *  space, <i>str</i> is split on whitespace, with leading whitespace and runs
+ *  of contiguous whitespace characters ignored.
+ *
+ *  If <i>pattern</i> is a <code>Regexp</code>, <i>str</i> is divided where the
+ *  pattern matches. Whenever the pattern matches a zero-length string,
+ *  <i>str</i> is split into individual characters.
+ *
+ *  If <i>pattern</i> is omitted, the value of <code>$;</code> is used.  If
+ *  <code>$;</code> is <code>nil</code> (which is the default), <i>str</i> is
+ *  split on whitespace as if ' ' were specified.
+ *
+ *  If the <i>limit</i> parameter is omitted, trailing null fields are
+ *  suppressed. If <i>limit</i> is a positive number, at most that number of
+ *  fields will be returned (if <i>limit</i> is <code>1</code>, the entire
+ *  string is returned as the only entry in an array). If negative, there is no
+ *  limit to the number of fields returned, and trailing null fields are not
+ *  suppressed.
+ *
+ *     " now's  the time".split        #=> ["now's", "the", "time"]
+ *     " now's  the time".split(' ')   #=> ["now's", "the", "time"]
+ *     " now's  the time".split(/ /)   #=> ["", "now's", "", "the", "time"]
+ *     "hello".split(//)               #=> ["h", "e", "l", "l", "o"]
+ *     "hello".split(//, 3)            #=> ["h", "e", "llo"]
+ *
+ *     "mellow yellow".split("ello")   #=> ["m", "w y", "w"]
+ *     "1,2,,3,4,,".split(',')         #=> ["1", "2", "", "3", "4"]
+ *     "1,2,,3,4,,".split(',', 4)      #=> ["1", "2", "", "3,4,,"]
+ *     "1,2,,3,4,,".split(',', -4)     #=> ["1", "2", "", "3", "4", "", ""]
+ */
+
+static mrb_value
+mrb_str_split_m(mrb_state *mrb, mrb_value str)
+{
+  int argc;
+  mrb_value spat = mrb_nil_value();
+  enum {awk, string, regexp} split_type = string;
+  mrb_int i = 0;
+  mrb_int beg;
+  mrb_int end;
+  mrb_int lim = 0;
+  mrb_bool lim_p;
+  mrb_value result, tmp;
+
+  argc = mrb_get_args(mrb, "|oi", &spat, &lim);
+  lim_p = (lim > 0 && argc == 2);
+  if (argc == 2) {
+    if (lim == 1) {
+      if (RSTRING_LEN(str) == 0)
+        return mrb_ary_new_capa(mrb, 0);
+      return mrb_ary_new_from_values(mrb, 1, &str);
+    }
+    i = 1;
+  }
+
+  if (argc == 0 || mrb_nil_p(spat)) {
+    split_type = awk;
+  }
+  else {
+    if (mrb_string_p(spat)) {
+      split_type = string;
+      if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' ') {
+          split_type = awk;
+      }
+    }
+    else {
+      mrb_noregexp(mrb, str);
+    }
+  }
+
+  result = mrb_ary_new(mrb);
+  beg = 0;
+  if (split_type == awk) {
+    mrb_bool skip = TRUE;
+    mrb_int idx = 0;
+    mrb_int str_len = RSTRING_LEN(str);
+    unsigned int c;
+    int ai = mrb_gc_arena_save(mrb);
+
+    idx = end = beg;
+    while (idx < str_len) {
+      c = (unsigned char)RSTRING_PTR(str)[idx++];
+      if (skip) {
+        if (ISSPACE(c)) {
+          beg = idx;
+        }
+        else {
+          end = idx;
+          skip = FALSE;
+          if (lim_p && lim <= i) break;
+        }
+      }
+      else if (ISSPACE(c)) {
+        mrb_ary_push(mrb, result, byte_subseq(mrb, str, beg, end-beg));
+        mrb_gc_arena_restore(mrb, ai);
+        skip = TRUE;
+        beg = idx;
+        if (lim_p) ++i;
+      }
+      else {
+        end = idx;
+      }
+    }
+  }
+  else if (split_type == string) {
+    mrb_int str_len = RSTRING_LEN(str);
+    mrb_int pat_len = RSTRING_LEN(spat);
+    mrb_int idx = 0;
+    int ai = mrb_gc_arena_save(mrb);
+
+    while (idx < str_len) {
+      if (pat_len > 0) {
+        end = mrb_memsearch(RSTRING_PTR(spat), pat_len, RSTRING_PTR(str)+idx, str_len - idx);
+        if (end < 0) break;
+      }
+      else {
+        end = chars2bytes(str, idx, 1);
+      }
+      mrb_ary_push(mrb, result, byte_subseq(mrb, str, idx, end));
+      mrb_gc_arena_restore(mrb, ai);
+      idx += end + pat_len;
+      if (lim_p && lim <= ++i) break;
+    }
+    beg = idx;
+  }
+  else {
+    mrb_noregexp(mrb, str);
+  }
+  if (RSTRING_LEN(str) > 0 && (lim_p || RSTRING_LEN(str) > beg || lim < 0)) {
+    if (RSTRING_LEN(str) == beg) {
+      tmp = mrb_str_new_empty(mrb, str);
+    }
+    else {
+      tmp = byte_subseq(mrb, str, beg, RSTRING_LEN(str)-beg);
+    }
+    mrb_ary_push(mrb, result, tmp);
+  }
+  if (!lim_p && lim == 0) {
+    mrb_int len;
+    while ((len = RARRAY_LEN(result)) > 0 &&
+           (tmp = RARRAY_PTR(result)[len-1], RSTRING_LEN(tmp) == 0))
+      mrb_ary_pop(mrb, result);
+  }
+
+  return result;
+}
+
+MRB_API mrb_value
+mrb_str_len_to_inum(mrb_state *mrb, const char *str, size_t len, int base, int badcheck)
+{
+  const char *p = str;
+  const char *pend = str + len;
+  char sign = 1;
+  int c;
+  uint64_t n = 0;
+  mrb_int val;
+
+#define conv_digit(c) \
+    (ISDIGIT(c) ? ((c) - '0') : \
+     ISLOWER(c) ? ((c) - 'a' + 10) : \
+     ISUPPER(c) ? ((c) - 'A' + 10) : \
+     -1)
+
+  if (!p) {
+    if (badcheck) goto bad;
+    return mrb_fixnum_value(0);
+  }
+  while (p<pend && ISSPACE(*p))
+    p++;
+
+  if (p[0] == '+') {
+    p++;
+  }
+  else if (p[0] == '-') {
+    p++;
+    sign = 0;
+  }
+  if (base <= 0) {
+    if (p[0] == '0') {
+      switch (p[1]) {
+        case 'x': case 'X':
+          base = 16;
+          break;
+        case 'b': case 'B':
+          base = 2;
+          break;
+        case 'o': case 'O':
+          base = 8;
+          break;
+        case 'd': case 'D':
+          base = 10;
+          break;
+        default:
+          base = 8;
+          break;
+      }
+    }
+    else if (base < -1) {
+      base = -base;
+    }
+    else {
+      base = 10;
+    }
+  }
+  switch (base) {
+    case 2:
+      if (p[0] == '0' && (p[1] == 'b'||p[1] == 'B')) {
+        p += 2;
+      }
+      break;
+    case 3:
+      break;
+    case 8:
+      if (p[0] == '0' && (p[1] == 'o'||p[1] == 'O')) {
+        p += 2;
+      }
+    case 4: case 5: case 6: case 7:
+      break;
+    case 10:
+      if (p[0] == '0' && (p[1] == 'd'||p[1] == 'D')) {
+        p += 2;
+      }
+    case 9: case 11: case 12: case 13: case 14: case 15:
+      break;
+    case 16:
+      if (p[0] == '0' && (p[1] == 'x'||p[1] == 'X')) {
+        p += 2;
+      }
+      break;
+    default:
+      if (base < 2 || 36 < base) {
+        mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %S", mrb_fixnum_value(base));
+      }
+      break;
+  } /* end of switch (base) { */
+  if (p>=pend) {
+    if (badcheck) goto bad;
+    return mrb_fixnum_value(0);
+  }
+  if (*p == '0') {    /* squeeze preceding 0s */
+    p++;
+    while (p<pend) {
+      c = *p++;
+      if (c == '_') {
+        if (p<pend && *p == '_') {
+          if (badcheck) goto bad;
+          break;
+        }
+        continue;
+      }
+      if (c != '0') {
+        p--;
+        break;
+      }
+    }
+    if (*(p - 1) == '0')
+      p--;
+  }
+  if (p == pend) {
+    if (badcheck) goto bad;
+    return mrb_fixnum_value(0);
+  }
+  for ( ;p<pend;p++) {
+    if (*p == '_') {
+      p++;
+      if (p==pend) {
+        if (badcheck) goto bad;
+        continue;
+      }
+      if (*p == '_') {
+        if (badcheck) goto bad;
+        break;
+      }
+    }
+    if (badcheck && *p == '\0') {
+      goto nullbyte;
+    }
+    c = conv_digit(*p);
+    if (c < 0 || c >= base) {
+      break;
+    }
+    n *= base;
+    n += c;
+    if (n > (uint64_t)MRB_INT_MAX + (sign ? 0 : 1)) {
+      mrb_raisef(mrb, E_ARGUMENT_ERROR, "string (%S) too big for integer",
+                 mrb_str_new(mrb, str, pend-str));
+    }
+  }
+  val = (mrb_int)n;
+  if (badcheck) {
+    if (p == str) goto bad; /* no number */
+    while (p<pend && ISSPACE(*p)) p++;
+    if (p<pend) goto bad;       /* trailing garbage */
+  }
+
+  return mrb_fixnum_value(sign ? val : -val);
+ nullbyte:
+  mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte");
+  /* not reached */
+ bad:
+  mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for number(%S)",
+             mrb_inspect(mrb, mrb_str_new(mrb, str, pend-str)));
+  /* not reached */
+  return mrb_fixnum_value(0);
+}
+
+MRB_API mrb_value
+mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck)
+{
+  return mrb_str_len_to_inum(mrb, str, strlen(str), base, badcheck);
+}
+
+MRB_API const char*
+mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr)
+{
+  mrb_value str = mrb_str_to_str(mrb, *ptr);
+  struct RString *ps = mrb_str_ptr(str);
+  mrb_int len = mrb_str_strlen(mrb, ps);
+  char *p = RSTR_PTR(ps);
+
+  if (!p || p[len] != '\0') {
+    if (MRB_FROZEN_P(ps)) {
+      *ptr = str = mrb_str_dup(mrb, str);
+      ps = mrb_str_ptr(str);
+    }
+    mrb_str_modify(mrb, ps);
+    return RSTR_PTR(ps);
+  }
+  return p;
+}
+
+MRB_API mrb_value
+mrb_str_to_inum(mrb_state *mrb, mrb_value str, mrb_int base, mrb_bool badcheck)
+{
+  const char *s;
+  mrb_int len;
+
+  s = mrb_string_value_ptr(mrb, str);
+  len = RSTRING_LEN(str);
+  return mrb_str_len_to_inum(mrb, s, len, base, badcheck);
+}
+
+/* 15.2.10.5.38 */
+/*
+ *  call-seq:
+ *     str.to_i(base=10)   => integer
+ *
+ *  Returns the result of interpreting leading characters in <i>str</i> as an
+ *  integer base <i>base</i> (between 2 and 36). Extraneous characters past the
+ *  end of a valid number are ignored. If there is not a valid number at the
+ *  start of <i>str</i>, <code>0</code> is returned. This method never raises an
+ *  exception.
+ *
+ *     "12345".to_i             #=> 12345
+ *     "99 red balloons".to_i   #=> 99
+ *     "0a".to_i                #=> 0
+ *     "0a".to_i(16)            #=> 10
+ *     "hello".to_i             #=> 0
+ *     "1100101".to_i(2)        #=> 101
+ *     "1100101".to_i(8)        #=> 294977
+ *     "1100101".to_i(10)       #=> 1100101
+ *     "1100101".to_i(16)       #=> 17826049
+ */
+static mrb_value
+mrb_str_to_i(mrb_state *mrb, mrb_value self)
+{
+  mrb_int base = 10;
+
+  mrb_get_args(mrb, "|i", &base);
+  if (base < 0) {
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %S", mrb_fixnum_value(base));
+  }
+  return mrb_str_to_inum(mrb, self, base, FALSE);
+}
+
+MRB_API double
+mrb_cstr_to_dbl(mrb_state *mrb, const char * p, mrb_bool badcheck)
+{
+  char *end;
+  char buf[DBL_DIG * 4 + 10];
+  double d;
+
+  enum {max_width = 20};
+
+  if (!p) return 0.0;
+  while (ISSPACE(*p)) p++;
+
+  if (!badcheck && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
+    return 0.0;
+  }
+  d = mrb_float_read(p, &end);
+  if (p == end) {
+    if (badcheck) {
+bad:
+      mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for float(%S)", mrb_str_new_cstr(mrb, p));
+      /* not reached */
+    }
+    return d;
+  }
+  if (*end) {
+    char *n = buf;
+    char *e = buf + sizeof(buf) - 1;
+    char prev = 0;
+
+    while (p < end && n < e) prev = *n++ = *p++;
+    while (*p) {
+      if (*p == '_') {
+        /* remove underscores between digits */
+        if (badcheck) {
+          if (n == buf || !ISDIGIT(prev)) goto bad;
+          ++p;
+          if (!ISDIGIT(*p)) goto bad;
+        }
+        else {
+          while (*++p == '_');
+          continue;
+        }
+      }
+      prev = *p++;
+      if (n < e) *n++ = prev;
+    }
+    *n = '\0';
+    p = buf;
+
+    if (!badcheck && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
+      return 0.0;
+    }
+
+    d = mrb_float_read(p, &end);
+    if (badcheck) {
+      if (!end || p == end) goto bad;
+      while (*end && ISSPACE(*end)) end++;
+      if (*end) goto bad;
+    }
+  }
+  return d;
+}
+
+MRB_API double
+mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck)
+{
+  char *s;
+  mrb_int len;
+
+  str = mrb_str_to_str(mrb, str);
+  s = RSTRING_PTR(str);
+  len = RSTRING_LEN(str);
+  if (s) {
+    if (badcheck && memchr(s, '\0', len)) {
+      mrb_raise(mrb, E_ARGUMENT_ERROR, "string for Float contains null byte");
+    }
+    if (s[len]) {    /* no sentinel somehow */
+      struct RString *temp_str = str_new(mrb, s, len);
+      s = RSTR_PTR(temp_str);
+    }
+  }
+  return mrb_cstr_to_dbl(mrb, s, badcheck);
+}
+
+/* 15.2.10.5.39 */
+/*
+ *  call-seq:
+ *     str.to_f   => float
+ *
+ *  Returns the result of interpreting leading characters in <i>str</i> as a
+ *  floating point number. Extraneous characters past the end of a valid number
+ *  are ignored. If there is not a valid number at the start of <i>str</i>,
+ *  <code>0.0</code> is returned. This method never raises an exception.
+ *
+ *     "123.45e1".to_f        #=> 1234.5
+ *     "45.67 degrees".to_f   #=> 45.67
+ *     "thx1138".to_f         #=> 0.0
+ */
+static mrb_value
+mrb_str_to_f(mrb_state *mrb, mrb_value self)
+{
+  return mrb_float_value(mrb, mrb_str_to_dbl(mrb, self, FALSE));
+}
+
+/* 15.2.10.5.40 */
+/*
+ *  call-seq:
+ *     str.to_s     => str
+ *     str.to_str   => str
+ *
+ *  Returns the receiver.
+ */
+static mrb_value
+mrb_str_to_s(mrb_state *mrb, mrb_value self)
+{
+  if (mrb_obj_class(mrb, self) != mrb->string_class) {
+    return mrb_str_dup(mrb, self);
+  }
+  return self;
+}
+
+/* 15.2.10.5.43 */
+/*
+ *  call-seq:
+ *     str.upcase!   => str or nil
+ *
+ *  Upcases the contents of <i>str</i>, returning <code>nil</code> if no changes
+ *  were made.
+ */
+static mrb_value
+mrb_str_upcase_bang(mrb_state *mrb, mrb_value str)
+{
+  struct RString *s = mrb_str_ptr(str);
+  char *p, *pend;
+  mrb_bool modify = FALSE;
+
+  mrb_str_modify(mrb, s);
+  p = RSTRING_PTR(str);
+  pend = RSTRING_END(str);
+  while (p < pend) {
+    if (ISLOWER(*p)) {
+      *p = TOUPPER(*p);
+      modify = TRUE;
+    }
+    p++;
+  }
+
+  if (modify) return str;
+  return mrb_nil_value();
+}
+
+/* 15.2.10.5.42 */
+/*
+ *  call-seq:
+ *     str.upcase   => new_str
+ *
+ *  Returns a copy of <i>str</i> with all lowercase letters replaced with their
+ *  uppercase counterparts. The operation is locale insensitive---only
+ *  characters 'a' to 'z' are affected.
+ *
+ *     "hEllO".upcase   #=> "HELLO"
+ */
+static mrb_value
+mrb_str_upcase(mrb_state *mrb, mrb_value self)
+{
+  mrb_value str;
+
+  str = mrb_str_dup(mrb, self);
+  mrb_str_upcase_bang(mrb, str);
+  return str;
+}
+
+#define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{'))
+
+/*
+ *  call-seq:
+ *     str.dump   -> new_str
+ *
+ *  Produces a version of <i>str</i> with all nonprinting characters replaced by
+ *  <code>\nnn</code> notation and all special characters escaped.
+ */
+mrb_value
+mrb_str_dump(mrb_state *mrb, mrb_value str)
+{
+  mrb_int len;
+  const char *p, *pend;
+  char *q;
+  struct RString *result;
+
+  len = 2;                  /* "" */
+  p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str);
+  while (p < pend) {
+    unsigned char c = *p++;
+    switch (c) {
+      case '"':  case '\\':
+      case '\n': case '\r':
+      case '\t': case '\f':
+      case '\013': case '\010': case '\007': case '\033':
+        len += 2;
+        break;
+
+      case '#':
+        len += IS_EVSTR(p, pend) ? 2 : 1;
+        break;
+
+      default:
+        if (ISPRINT(c)) {
+          len++;
+        }
+        else {
+          len += 4;                /* \NNN */
+        }
+        break;
+    }
+  }
+
+  result = str_new(mrb, 0, len);
+  str_with_class(mrb, result, str);
+  p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str);
+  q = RSTR_PTR(result);
+  *q++ = '"';
+  while (p < pend) {
+    unsigned char c = *p++;
+
+    switch (c) {
+      case '"':
+      case '\\':
+        *q++ = '\\';
+        *q++ = c;
+        break;
+
+      case '\n':
+        *q++ = '\\';
+        *q++ = 'n';
+        break;
+
+      case '\r':
+        *q++ = '\\';
+        *q++ = 'r';
+        break;
+
+      case '\t':
+        *q++ = '\\';
+        *q++ = 't';
+        break;
+
+      case '\f':
+        *q++ = '\\';
+        *q++ = 'f';
+        break;
+
+      case '\013':
+        *q++ = '\\';
+        *q++ = 'v';
+        break;
+
+      case '\010':
+        *q++ = '\\';
+        *q++ = 'b';
+        break;
+
+      case '\007':
+        *q++ = '\\';
+        *q++ = 'a';
+        break;
+
+      case '\033':
+        *q++ = '\\';
+        *q++ = 'e';
+        break;
+
+      case '#':
+        if (IS_EVSTR(p, pend)) *q++ = '\\';
+        *q++ = '#';
+        break;
+
+      default:
+        if (ISPRINT(c)) {
+          *q++ = c;
+        }
+        else {
+          *q++ = '\\';
+          q[2] = '0' + c % 8; c /= 8;
+          q[1] = '0' + c % 8; c /= 8;
+          q[0] = '0' + c % 8;
+          q += 3;
+        }
+    }
+  }
+  *q = '"';
+  return mrb_obj_value(result);
+}
+
+MRB_API mrb_value
+mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len)
+{
+  str_buf_cat(mrb, mrb_str_ptr(str), ptr, len);
+  return str;
+}
+
+MRB_API mrb_value
+mrb_str_cat_cstr(mrb_state *mrb, mrb_value str, const char *ptr)
+{
+  return mrb_str_cat(mrb, str, ptr, strlen(ptr));
+}
+
+MRB_API mrb_value
+mrb_str_cat_str(mrb_state *mrb, mrb_value str, mrb_value str2)
+{
+  return mrb_str_cat(mrb, str, RSTRING_PTR(str2), RSTRING_LEN(str2));
+}
+
+MRB_API mrb_value
+mrb_str_append(mrb_state *mrb, mrb_value str1, mrb_value str2)
+{
+  str2 = mrb_str_to_str(mrb, str2);
+  return mrb_str_cat_str(mrb, str1, str2);
+}
+
+#define CHAR_ESC_LEN 13 /* sizeof(\x{ hex of 32bit unsigned int } \0) */
+
+/*
+ * call-seq:
+ *   str.inspect   -> string
+ *
+ * Returns a printable version of _str_, surrounded by quote marks,
+ * with special characters escaped.
+ *
+ *    str = "hello"
+ *    str[3] = "\b"
+ *    str.inspect       #=> "\"hel\\bo\""
+ */
+mrb_value
+mrb_str_inspect(mrb_state *mrb, mrb_value str)
+{
+  const char *p, *pend;
+  char buf[CHAR_ESC_LEN + 1];
+  mrb_value result = mrb_str_new_lit(mrb, "\"");
+
+  p = RSTRING_PTR(str); pend = RSTRING_END(str);
+  for (;p < pend; p++) {
+    unsigned char c, cc;
+#ifdef MRB_UTF8_STRING
+    mrb_int clen;
+
+    clen = utf8len(p, pend);
+    if (clen > 1) {
+      mrb_int i;
+
+      for (i=0; i<clen; i++) {
+        buf[i] = p[i];
+      }
+      mrb_str_cat(mrb, result, buf, clen);
+      p += clen-1;
+      continue;
+    }
+#endif
+    c = *p;
+    if (c == '"'|| c == '\\' || (c == '#' && IS_EVSTR(p+1, pend))) {
+      buf[0] = '\\'; buf[1] = c;
+      mrb_str_cat(mrb, result, buf, 2);
+      continue;
+    }
+    if (ISPRINT(c)) {
+      buf[0] = c;
+      mrb_str_cat(mrb, result, buf, 1);
+      continue;
+    }
+    switch (c) {
+      case '\n': cc = 'n'; break;
+      case '\r': cc = 'r'; break;
+      case '\t': cc = 't'; break;
+      case '\f': cc = 'f'; break;
+      case '\013': cc = 'v'; break;
+      case '\010': cc = 'b'; break;
+      case '\007': cc = 'a'; break;
+      case 033: cc = 'e'; break;
+      default: cc = 0; break;
+    }
+    if (cc) {
+      buf[0] = '\\';
+      buf[1] = (char)cc;
+      mrb_str_cat(mrb, result, buf, 2);
+      continue;
+    }
+    else {
+      buf[0] = '\\';
+      buf[3] = '0' + c % 8; c /= 8;
+      buf[2] = '0' + c % 8; c /= 8;
+      buf[1] = '0' + c % 8;
+      mrb_str_cat(mrb, result, buf, 4);
+      continue;
+    }
+  }
+  mrb_str_cat_lit(mrb, result, "\"");
+
+  return result;
+}
+
+/*
+ * call-seq:
+ *   str.bytes   -> array of fixnums
+ *
+ * Returns an array of bytes in _str_.
+ *
+ *    str = "hello"
+ *    str.bytes       #=> [104, 101, 108, 108, 111]
+ */
+static mrb_value
+mrb_str_bytes(mrb_state *mrb, mrb_value str)
+{
+  struct RString *s = mrb_str_ptr(str);
+  mrb_value a = mrb_ary_new_capa(mrb, RSTR_LEN(s));
+  unsigned char *p = (unsigned char *)(RSTR_PTR(s)), *pend = p + RSTR_LEN(s);
+
+  while (p < pend) {
+    mrb_ary_push(mrb, a, mrb_fixnum_value(p[0]));
+    p++;
+  }
+  return a;
+}
+
+/* ---------------------------*/
+void
+mrb_init_string(mrb_state *mrb)
+{
+  struct RClass *s;
+
+  mrb_static_assert(RSTRING_EMBED_LEN_MAX < (1 << 5), "pointer size too big for embedded string");
+
+  mrb->string_class = s = mrb_define_class(mrb, "String", mrb->object_class);             /* 15.2.10 */
+  MRB_SET_INSTANCE_TT(s, MRB_TT_STRING);
+
+  mrb_define_method(mrb, s, "bytesize",        mrb_str_bytesize,        MRB_ARGS_NONE());
+
+  mrb_define_method(mrb, s, "<=>",             mrb_str_cmp_m,           MRB_ARGS_REQ(1)); /* 15.2.10.5.1  */
+  mrb_define_method(mrb, s, "==",              mrb_str_equal_m,         MRB_ARGS_REQ(1)); /* 15.2.10.5.2  */
+  mrb_define_method(mrb, s, "+",               mrb_str_plus_m,          MRB_ARGS_REQ(1)); /* 15.2.10.5.4  */
+  mrb_define_method(mrb, s, "*",               mrb_str_times,           MRB_ARGS_REQ(1)); /* 15.2.10.5.5  */
+  mrb_define_method(mrb, s, "[]",              mrb_str_aref_m,          MRB_ARGS_ANY());  /* 15.2.10.5.6  */
+  mrb_define_method(mrb, s, "capitalize",      mrb_str_capitalize,      MRB_ARGS_NONE()); /* 15.2.10.5.7  */
+  mrb_define_method(mrb, s, "capitalize!",     mrb_str_capitalize_bang, MRB_ARGS_NONE()); /* 15.2.10.5.8  */
+  mrb_define_method(mrb, s, "chomp",           mrb_str_chomp,           MRB_ARGS_ANY());  /* 15.2.10.5.9  */
+  mrb_define_method(mrb, s, "chomp!",          mrb_str_chomp_bang,      MRB_ARGS_ANY());  /* 15.2.10.5.10 */
+  mrb_define_method(mrb, s, "chop",            mrb_str_chop,            MRB_ARGS_NONE()); /* 15.2.10.5.11 */
+  mrb_define_method(mrb, s, "chop!",           mrb_str_chop_bang,       MRB_ARGS_NONE()); /* 15.2.10.5.12 */
+  mrb_define_method(mrb, s, "downcase",        mrb_str_downcase,        MRB_ARGS_NONE()); /* 15.2.10.5.13 */
+  mrb_define_method(mrb, s, "downcase!",       mrb_str_downcase_bang,   MRB_ARGS_NONE()); /* 15.2.10.5.14 */
+  mrb_define_method(mrb, s, "empty?",          mrb_str_empty_p,         MRB_ARGS_NONE()); /* 15.2.10.5.16 */
+  mrb_define_method(mrb, s, "eql?",            mrb_str_eql,             MRB_ARGS_REQ(1)); /* 15.2.10.5.17 */
+
+  mrb_define_method(mrb, s, "hash",            mrb_str_hash_m,          MRB_ARGS_NONE()); /* 15.2.10.5.20 */
+  mrb_define_method(mrb, s, "include?",        mrb_str_include,         MRB_ARGS_REQ(1)); /* 15.2.10.5.21 */
+  mrb_define_method(mrb, s, "index",           mrb_str_index,           MRB_ARGS_ANY());  /* 15.2.10.5.22 */
+  mrb_define_method(mrb, s, "initialize",      mrb_str_init,            MRB_ARGS_REQ(1)); /* 15.2.10.5.23 */
+  mrb_define_method(mrb, s, "initialize_copy", mrb_str_replace,         MRB_ARGS_REQ(1)); /* 15.2.10.5.24 */
+  mrb_define_method(mrb, s, "intern",          mrb_str_intern,          MRB_ARGS_NONE()); /* 15.2.10.5.25 */
+  mrb_define_method(mrb, s, "length",          mrb_str_size,            MRB_ARGS_NONE()); /* 15.2.10.5.26 */
+  mrb_define_method(mrb, s, "replace",         mrb_str_replace,         MRB_ARGS_REQ(1)); /* 15.2.10.5.28 */
+  mrb_define_method(mrb, s, "reverse",         mrb_str_reverse,         MRB_ARGS_NONE()); /* 15.2.10.5.29 */
+  mrb_define_method(mrb, s, "reverse!",        mrb_str_reverse_bang,    MRB_ARGS_NONE()); /* 15.2.10.5.30 */
+  mrb_define_method(mrb, s, "rindex",          mrb_str_rindex,          MRB_ARGS_ANY());  /* 15.2.10.5.31 */
+  mrb_define_method(mrb, s, "size",            mrb_str_size,            MRB_ARGS_NONE()); /* 15.2.10.5.33 */
+  mrb_define_method(mrb, s, "slice",           mrb_str_aref_m,          MRB_ARGS_ANY());  /* 15.2.10.5.34 */
+  mrb_define_method(mrb, s, "split",           mrb_str_split_m,         MRB_ARGS_ANY());  /* 15.2.10.5.35 */
+
+  mrb_define_method(mrb, s, "to_f",            mrb_str_to_f,            MRB_ARGS_NONE()); /* 15.2.10.5.38 */
+  mrb_define_method(mrb, s, "to_i",            mrb_str_to_i,            MRB_ARGS_ANY());  /* 15.2.10.5.39 */
+  mrb_define_method(mrb, s, "to_s",            mrb_str_to_s,            MRB_ARGS_NONE()); /* 15.2.10.5.40 */
+  mrb_define_method(mrb, s, "to_str",          mrb_str_to_s,            MRB_ARGS_NONE());
+  mrb_define_method(mrb, s, "to_sym",          mrb_str_intern,          MRB_ARGS_NONE()); /* 15.2.10.5.41 */
+  mrb_define_method(mrb, s, "upcase",          mrb_str_upcase,          MRB_ARGS_NONE()); /* 15.2.10.5.42 */
+  mrb_define_method(mrb, s, "upcase!",         mrb_str_upcase_bang,     MRB_ARGS_NONE()); /* 15.2.10.5.43 */
+  mrb_define_method(mrb, s, "inspect",         mrb_str_inspect,         MRB_ARGS_NONE()); /* 15.2.10.5.46(x) */
+  mrb_define_method(mrb, s, "bytes",           mrb_str_bytes,           MRB_ARGS_NONE());
+}
+
+/*
+ *	Source code for the "strtod" library procedure.
+ *
+ * Copyright (c) 1988-1993 The Regents of the University of California.
+ * Copyright (c) 1994 Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies.  The University of California
+ * makes no representations about the suitability of this
+ * software for any purpose.  It is provided "as is" without
+ * express or implied warranty.
+ *
+ * RCS: @(#) $Id$
+ */
+
+#include <ctype.h>
+#include <errno.h>
+
+static const int maxExponent = 511; /* Largest possible base 10 exponent.  Any
+                                     * exponent larger than this will already
+                                     * produce underflow or overflow, so there's
+                                     * no need to worry about additional digits.
+                                     */
+static const double powersOf10[] = {/* Table giving binary powers of 10.  Entry */
+    10.,                            /* is 10^2^i.  Used to convert decimal */
+    100.,			    /* exponents into floating-point numbers. */
+    1.0e4,
+    1.0e8,
+    1.0e16,
+    1.0e32,
+    1.0e64,
+    1.0e128,
+    1.0e256
+};
+
+MRB_API double
+mrb_float_read(const char *string, char **endPtr)
+/*  const char *string;		   A decimal ASCII floating-point number,
+				 * optionally preceded by white space.
+				 * Must have form "-I.FE-X", where I is the
+				 * integer part of the mantissa, F is the
+				 * fractional part of the mantissa, and X
+				 * is the exponent.  Either of the signs
+				 * may be "+", "-", or omitted.  Either I
+				 * or F may be omitted, or both.  The decimal
+				 * point isn't necessary unless F is present.
+				 * The "E" may actually be an "e".  E and X
+				 * may both be omitted (but not just one).
+				 */
+/*  char **endPtr;		   If non-NULL, store terminating character's
+				 * address here. */
+{
+    int sign, expSign = FALSE;
+    double fraction, dblExp;
+    const double *d;
+    register const char *p;
+    register int c;
+    int exp = 0;		/* Exponent read from "EX" field. */
+    int fracExp = 0;		/* Exponent that derives from the fractional
+				 * part.  Under normal circumstatnces, it is
+				 * the negative of the number of digits in F.
+				 * However, if I is very long, the last digits
+				 * of I get dropped (otherwise a long I with a
+				 * large negative exponent could cause an
+				 * unnecessary overflow on I alone).  In this
+				 * case, fracExp is incremented one for each
+				 * dropped digit. */
+    int mantSize;		/* Number of digits in mantissa. */
+    int decPt;			/* Number of mantissa digits BEFORE decimal
+				 * point. */
+    const char *pExp;		/* Temporarily holds location of exponent
+				 * in string. */
+
+    /*
+     * Strip off leading blanks and check for a sign.
+     */
+
+    p = string;
+    while (isspace(*p)) {
+	p += 1;
+    }
+    if (*p == '-') {
+	sign = TRUE;
+	p += 1;
+    }
+    else {
+	if (*p == '+') {
+	    p += 1;
+	}
+	sign = FALSE;
+    }
+
+    /*
+     * Count the number of digits in the mantissa (including the decimal
+     * point), and also locate the decimal point.
+     */
+
+    decPt = -1;
+    for (mantSize = 0; ; mantSize += 1)
+    {
+	c = *p;
+	if (!isdigit(c)) {
+	    if ((c != '.') || (decPt >= 0)) {
+		break;
+	    }
+	    decPt = mantSize;
+	}
+	p += 1;
+    }
+
+    /*
+     * Now suck up the digits in the mantissa.  Use two integers to
+     * collect 9 digits each (this is faster than using floating-point).
+     * If the mantissa has more than 18 digits, ignore the extras, since
+     * they can't affect the value anyway.
+     */
+
+    pExp  = p;
+    p -= mantSize;
+    if (decPt < 0) {
+	decPt = mantSize;
+    }
+    else {
+	mantSize -= 1;			/* One of the digits was the point. */
+    }
+    if (mantSize > 18) {
+	if (decPt - 18 > 29999) {
+	    fracExp = 29999;
+	}
+        else {
+	    fracExp = decPt - 18;
+	}
+	mantSize = 18;
+    }
+    else {
+	fracExp = decPt - mantSize;
+    }
+    if (mantSize == 0) {
+	fraction = 0.0;
+	p = string;
+	goto done;
+    }
+    else {
+	int frac1, frac2;
+	frac1 = 0;
+	for ( ; mantSize > 9; mantSize -= 1)
+	{
+	    c = *p;
+	    p += 1;
+	    if (c == '.') {
+		c = *p;
+		p += 1;
+	    }
+	    frac1 = 10*frac1 + (c - '0');
+	}
+	frac2 = 0;
+	for (; mantSize > 0; mantSize -= 1)
+	{
+	    c = *p;
+	    p += 1;
+	    if (c == '.') {
+		c = *p;
+		p += 1;
+	    }
+	    frac2 = 10*frac2 + (c - '0');
+	}
+	fraction = (1.0e9 * frac1) + frac2;
+    }
+
+    /*
+     * Skim off the exponent.
+     */
+
+    p = pExp;
+    if ((*p == 'E') || (*p == 'e')) {
+	p += 1;
+	if (*p == '-') {
+	    expSign = TRUE;
+	    p += 1;
+	}
+        else {
+	    if (*p == '+') {
+		p += 1;
+	    }
+	    expSign = FALSE;
+	}
+	while (isdigit(*p)) {
+	    exp = exp * 10 + (*p - '0');
+	    if (exp > 19999) {
+		exp = 19999;
+	    }
+	    p += 1;
+	}
+    }
+    if (expSign) {
+	exp = fracExp - exp;
+    }
+    else {
+	exp = fracExp + exp;
+    }
+
+    /*
+     * Generate a floating-point number that represents the exponent.
+     * Do this by processing the exponent one bit at a time to combine
+     * many powers of 2 of 10. Then combine the exponent with the
+     * fraction.
+     */
+
+    if (exp < 0) {
+	expSign = TRUE;
+	exp = -exp;
+    }
+    else {
+	expSign = FALSE;
+    }
+    if (exp > maxExponent) {
+	exp = maxExponent;
+	errno = ERANGE;
+    }
+    dblExp = 1.0;
+    for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
+	if (exp & 01) {
+	    dblExp *= *d;
+	}
+    }
+    if (expSign) {
+	fraction /= dblExp;
+    }
+    else {
+	fraction *= dblExp;
+    }
+
+done:
+    if (endPtr != NULL) {
+	*endPtr = (char *) p;
+    }
+
+    if (sign) {
+	return -fraction;
+    }
+    return fraction;
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/symbol.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/symbol.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/symbol.c	(revision 331)
@@ -0,0 +1,494 @@
+/*
+** symbol.c - Symbol class
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <limits.h>
+#include <string.h>
+#include <mruby.h>
+#include <mruby/khash.h>
+#include <mruby/string.h>
+#include <mruby/dump.h>
+#include <mruby/class.h>
+
+/* ------------------------------------------------------ */
+typedef struct symbol_name {
+  mrb_bool lit : 1;
+  uint16_t len;
+  const char *name;
+} symbol_name;
+
+static inline khint_t
+sym_hash_func(mrb_state *mrb, mrb_sym s)
+{
+  khint_t h = 0;
+  size_t i, len = mrb->symtbl[s].len;
+  const char *p = mrb->symtbl[s].name;
+
+  for (i=0; i<len; i++) {
+    h = (h << 5) - h + *p++;
+  }
+  return h;
+}
+#define sym_hash_equal(mrb,a, b) (mrb->symtbl[a].len == mrb->symtbl[b].len && memcmp(mrb->symtbl[a].name, mrb->symtbl[b].name, mrb->symtbl[a].len) == 0)
+
+KHASH_DECLARE(n2s, mrb_sym, mrb_sym, FALSE)
+KHASH_DEFINE (n2s, mrb_sym, mrb_sym, FALSE, sym_hash_func, sym_hash_equal)
+/* ------------------------------------------------------ */
+
+static void
+sym_validate_len(mrb_state *mrb, size_t len)
+{
+  if (len >= RITE_LV_NULL_MARK) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "symbol length too long");
+  }
+}
+
+static mrb_sym
+sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit)
+{
+  khash_t(n2s) *h = mrb->name2sym;
+  symbol_name *sname = mrb->symtbl; /* symtbl[0] for working memory */
+  khiter_t k;
+  mrb_sym sym;
+  char *p;
+
+  sym_validate_len(mrb, len);
+  if (sname) {
+    sname->lit = lit;
+    sname->len = (uint16_t)len;
+    sname->name = name;
+    k = kh_get(n2s, mrb, h, 0);
+    if (k != kh_end(h))
+      return kh_key(h, k);
+  }
+
+  /* registering a new symbol */
+  sym = ++mrb->symidx;
+  if (mrb->symcapa < sym) {
+    if (mrb->symcapa == 0) mrb->symcapa = 100;
+    else mrb->symcapa = (size_t)(mrb->symcapa * 1.2);
+    mrb->symtbl = (symbol_name*)mrb_realloc(mrb, mrb->symtbl, sizeof(symbol_name)*(mrb->symcapa+1));
+  }
+  sname = &mrb->symtbl[sym];
+  sname->len = (uint16_t)len;
+  if (lit || mrb_ro_data_p(name)) {
+    sname->name = name;
+    sname->lit = TRUE;
+  }
+  else {
+    p = (char *)mrb_malloc(mrb, len+1);
+    memcpy(p, name, len);
+    p[len] = 0;
+    sname->name = (const char*)p;
+    sname->lit = FALSE;
+  }
+  kh_put(n2s, mrb, h, sym);
+
+  return sym;
+}
+
+MRB_API mrb_sym
+mrb_intern(mrb_state *mrb, const char *name, size_t len)
+{
+  return sym_intern(mrb, name, len, FALSE);
+}
+
+MRB_API mrb_sym
+mrb_intern_static(mrb_state *mrb, const char *name, size_t len)
+{
+  return sym_intern(mrb, name, len, TRUE);
+}
+
+MRB_API mrb_sym
+mrb_intern_cstr(mrb_state *mrb, const char *name)
+{
+  return mrb_intern(mrb, name, strlen(name));
+}
+
+MRB_API mrb_sym
+mrb_intern_str(mrb_state *mrb, mrb_value str)
+{
+  return mrb_intern(mrb, RSTRING_PTR(str), RSTRING_LEN(str));
+}
+
+MRB_API mrb_value
+mrb_check_intern(mrb_state *mrb, const char *name, size_t len)
+{
+  khash_t(n2s) *h = mrb->name2sym;
+  symbol_name *sname = mrb->symtbl;
+  khiter_t k;
+
+  sym_validate_len(mrb, len);
+  sname->len = (uint16_t)len;
+  sname->name = name;
+
+  k = kh_get(n2s, mrb, h, 0);
+  if (k != kh_end(h)) {
+    return mrb_symbol_value(kh_key(h, k));
+  }
+  return mrb_nil_value();
+}
+
+MRB_API mrb_value
+mrb_check_intern_cstr(mrb_state *mrb, const char *name)
+{
+  return mrb_check_intern(mrb, name, (mrb_int)strlen(name));
+}
+
+MRB_API mrb_value
+mrb_check_intern_str(mrb_state *mrb, mrb_value str)
+{
+  return mrb_check_intern(mrb, RSTRING_PTR(str), RSTRING_LEN(str));
+}
+
+/* lenp must be a pointer to a size_t variable */
+MRB_API const char*
+mrb_sym2name_len(mrb_state *mrb, mrb_sym sym, mrb_int *lenp)
+{
+  if (sym == 0 || mrb->symidx < sym) {
+    if (lenp) *lenp = 0;
+    return NULL;
+  }
+
+  if (lenp) *lenp = mrb->symtbl[sym].len;
+  return mrb->symtbl[sym].name;
+}
+
+void
+mrb_free_symtbl(mrb_state *mrb)
+{
+  mrb_sym i, lim;
+
+  for (i=1, lim=mrb->symidx+1; i<lim; i++) {
+    if (!mrb->symtbl[i].lit) {
+      mrb_free(mrb, (char*)mrb->symtbl[i].name);
+    }
+  }
+  mrb_free(mrb, mrb->symtbl);
+  kh_destroy(n2s, mrb, mrb->name2sym);
+}
+
+void
+mrb_init_symtbl(mrb_state *mrb)
+{
+  mrb->name2sym = kh_init(n2s, mrb);
+}
+
+/**********************************************************************
+ * Document-class: Symbol
+ *
+ *  <code>Symbol</code> objects represent names and some strings
+ *  inside the Ruby
+ *  interpreter. They are generated using the <code>:name</code> and
+ *  <code>:"string"</code> literals
+ *  syntax, and by the various <code>to_sym</code> methods. The same
+ *  <code>Symbol</code> object will be created for a given name or string
+ *  for the duration of a program's execution, regardless of the context
+ *  or meaning of that name. Thus if <code>Fred</code> is a constant in
+ *  one context, a method in another, and a class in a third, the
+ *  <code>Symbol</code> <code>:Fred</code> will be the same object in
+ *  all three contexts.
+ *
+ *     module One
+ *       class Fred
+ *       end
+ *       $f1 = :Fred
+ *     end
+ *     module Two
+ *       Fred = 1
+ *       $f2 = :Fred
+ *     end
+ *     def Fred()
+ *     end
+ *     $f3 = :Fred
+ *     $f1.object_id   #=> 2514190
+ *     $f2.object_id   #=> 2514190
+ *     $f3.object_id   #=> 2514190
+ *
+ */
+
+
+/* 15.2.11.3.1  */
+/*
+ *  call-seq:
+ *     sym == obj   -> true or false
+ *
+ *  Equality---If <i>sym</i> and <i>obj</i> are exactly the same
+ *  symbol, returns <code>true</code>.
+ */
+
+static mrb_value
+sym_equal(mrb_state *mrb, mrb_value sym1)
+{
+  mrb_value sym2;
+
+  mrb_get_args(mrb, "o", &sym2);
+
+  return mrb_bool_value(mrb_obj_equal(mrb, sym1, sym2));
+}
+
+/* 15.2.11.3.2  */
+/* 15.2.11.3.3  */
+/*
+ *  call-seq:
+ *     sym.id2name   -> string
+ *     sym.to_s      -> string
+ *
+ *  Returns the name or string corresponding to <i>sym</i>.
+ *
+ *     :fred.id2name   #=> "fred"
+ */
+static mrb_value
+mrb_sym_to_s(mrb_state *mrb, mrb_value sym)
+{
+  mrb_sym id = mrb_symbol(sym);
+  const char *p;
+  mrb_int len;
+
+  p = mrb_sym2name_len(mrb, id, &len);
+  return mrb_str_new_static(mrb, p, len);
+}
+
+/* 15.2.11.3.4  */
+/*
+ * call-seq:
+ *   sym.to_sym   -> sym
+ *   sym.intern   -> sym
+ *
+ * In general, <code>to_sym</code> returns the <code>Symbol</code> corresponding
+ * to an object. As <i>sym</i> is already a symbol, <code>self</code> is returned
+ * in this case.
+ */
+
+static mrb_value
+sym_to_sym(mrb_state *mrb, mrb_value sym)
+{
+  return sym;
+}
+
+/* 15.2.11.3.5(x)  */
+/*
+ *  call-seq:
+ *     sym.inspect    -> string
+ *
+ *  Returns the representation of <i>sym</i> as a symbol literal.
+ *
+ *     :fred.inspect   #=> ":fred"
+ */
+
+#if __STDC__
+# define SIGN_EXTEND_CHAR(c) ((signed char)(c))
+#else  /* not __STDC__ */
+/* As in Harbison and Steele.  */
+# define SIGN_EXTEND_CHAR(c) ((((unsigned char)(c)) ^ 128) - 128)
+#endif
+#define is_identchar(c) (SIGN_EXTEND_CHAR(c)!=-1&&(ISALNUM(c) || (c) == '_'))
+
+static mrb_bool
+is_special_global_name(const char* m)
+{
+  switch (*m) {
+    case '~': case '*': case '$': case '?': case '!': case '@':
+    case '/': case '\\': case ';': case ',': case '.': case '=':
+    case ':': case '<': case '>': case '\"':
+    case '&': case '`': case '\'': case '+':
+    case '0':
+      ++m;
+      break;
+    case '-':
+      ++m;
+      if (is_identchar(*m)) m += 1;
+      break;
+    default:
+      if (!ISDIGIT(*m)) return FALSE;
+      do ++m; while (ISDIGIT(*m));
+      break;
+  }
+  return !*m;
+}
+
+static mrb_bool
+symname_p(const char *name)
+{
+  const char *m = name;
+  mrb_bool localid = FALSE;
+
+  if (!m) return FALSE;
+  switch (*m) {
+    case '\0':
+      return FALSE;
+
+    case '$':
+      if (is_special_global_name(++m)) return TRUE;
+      goto id;
+
+    case '@':
+      if (*++m == '@') ++m;
+      goto id;
+
+    case '<':
+      switch (*++m) {
+        case '<': ++m; break;
+        case '=': if (*++m == '>') ++m; break;
+        default: break;
+      }
+      break;
+
+    case '>':
+      switch (*++m) {
+        case '>': case '=': ++m; break;
+        default: break;
+      }
+      break;
+
+    case '=':
+      switch (*++m) {
+        case '~': ++m; break;
+        case '=': if (*++m == '=') ++m; break;
+        default: return FALSE;
+      }
+      break;
+
+    case '*':
+      if (*++m == '*') ++m;
+      break;
+    case '!':
+      switch (*++m) {
+        case '=': case '~': ++m;
+      }
+      break;
+    case '+': case '-':
+      if (*++m == '@') ++m;
+      break;
+    case '|':
+      if (*++m == '|') ++m;
+      break;
+    case '&':
+      if (*++m == '&') ++m;
+      break;
+
+    case '^': case '/': case '%': case '~': case '`':
+      ++m;
+      break;
+
+    case '[':
+      if (*++m != ']') return FALSE;
+      if (*++m == '=') ++m;
+      break;
+
+    default:
+      localid = !ISUPPER(*m);
+id:
+      if (*m != '_' && !ISALPHA(*m)) return FALSE;
+      while (is_identchar(*m)) m += 1;
+      if (localid) {
+        switch (*m) {
+          case '!': case '?': case '=': ++m;
+          default: break;
+            }
+        }
+      break;
+  }
+  return *m ? FALSE : TRUE;
+}
+
+static mrb_value
+sym_inspect(mrb_state *mrb, mrb_value sym)
+{
+  mrb_value str;
+  const char *name;
+  mrb_int len;
+  mrb_sym id = mrb_symbol(sym);
+  char *sp;
+
+  name = mrb_sym2name_len(mrb, id, &len);
+  str = mrb_str_new(mrb, 0, len+1);
+  sp = RSTRING_PTR(str);
+  RSTRING_PTR(str)[0] = ':';
+  memcpy(sp+1, name, len);
+  mrb_assert_int_fit(mrb_int, len, size_t, SIZE_MAX);
+  if (!symname_p(name) || strlen(name) != (size_t)len) {
+    str = mrb_str_dump(mrb, str);
+    sp = RSTRING_PTR(str);
+    sp[0] = ':';
+    sp[1] = '"';
+  }
+  return str;
+}
+
+MRB_API mrb_value
+mrb_sym2str(mrb_state *mrb, mrb_sym sym)
+{
+  mrb_int len;
+  const char *name = mrb_sym2name_len(mrb, sym, &len);
+
+  if (!name) return mrb_undef_value(); /* can't happen */
+  return mrb_str_new_static(mrb, name, len);
+}
+
+MRB_API const char*
+mrb_sym2name(mrb_state *mrb, mrb_sym sym)
+{
+  mrb_int len;
+  const char *name = mrb_sym2name_len(mrb, sym, &len);
+
+  if (!name) return NULL;
+  if (symname_p(name) && strlen(name) == (size_t)len) {
+    return name;
+  }
+  else {
+    mrb_value str = mrb_str_dump(mrb, mrb_str_new_static(mrb, name, len));
+    return RSTRING_PTR(str);
+  }
+}
+
+#define lesser(a,b) (((a)>(b))?(b):(a))
+
+static mrb_value
+sym_cmp(mrb_state *mrb, mrb_value s1)
+{
+  mrb_value s2;
+  mrb_sym sym1, sym2;
+
+  mrb_get_args(mrb, "o", &s2);
+  if (mrb_type(s2) != MRB_TT_SYMBOL) return mrb_nil_value();
+  sym1 = mrb_symbol(s1);
+  sym2 = mrb_symbol(s2);
+  if (sym1 == sym2) return mrb_fixnum_value(0);
+  else {
+    const char *p1, *p2;
+    int retval;
+    mrb_int len, len1, len2;
+
+    p1 = mrb_sym2name_len(mrb, sym1, &len1);
+    p2 = mrb_sym2name_len(mrb, sym2, &len2);
+    len = lesser(len1, len2);
+    retval = memcmp(p1, p2, len);
+    if (retval == 0) {
+      if (len1 == len2) return mrb_fixnum_value(0);
+      if (len1 > len2)  return mrb_fixnum_value(1);
+      return mrb_fixnum_value(-1);
+    }
+    if (retval > 0) return mrb_fixnum_value(1);
+    return mrb_fixnum_value(-1);
+  }
+}
+
+void
+mrb_init_symbol(mrb_state *mrb)
+{
+  struct RClass *sym;
+
+  mrb->symbol_class = sym = mrb_define_class(mrb, "Symbol", mrb->object_class);                 /* 15.2.11 */
+  MRB_SET_INSTANCE_TT(sym, MRB_TT_SYMBOL);
+  mrb_undef_class_method(mrb,  sym, "new");
+
+  mrb_define_method(mrb, sym, "===",             sym_equal,      MRB_ARGS_REQ(1));              /* 15.2.11.3.1  */
+  mrb_define_method(mrb, sym, "id2name",         mrb_sym_to_s,   MRB_ARGS_NONE());              /* 15.2.11.3.2  */
+  mrb_define_method(mrb, sym, "to_s",            mrb_sym_to_s,   MRB_ARGS_NONE());              /* 15.2.11.3.3  */
+  mrb_define_method(mrb, sym, "to_sym",          sym_to_sym,     MRB_ARGS_NONE());              /* 15.2.11.3.4  */
+  mrb_define_method(mrb, sym, "inspect",         sym_inspect,    MRB_ARGS_NONE());              /* 15.2.11.3.5(x)  */
+  mrb_define_method(mrb, sym, "<=>",             sym_cmp,        MRB_ARGS_REQ(1));
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/value_array.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/value_array.h	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/value_array.h	(revision 331)
@@ -0,0 +1,27 @@
+#ifndef MRB_VALUE_ARRAY_H__
+#define MRB_VALUE_ARRAY_H__
+
+#include <mruby.h>
+
+static inline void
+value_move(mrb_value *s1, const mrb_value *s2, size_t n)
+{
+  if (s1 > s2 && s1 < s2 + n)
+  {
+    s1 += n;
+    s2 += n;
+    while (n-- > 0) {
+      *--s1 = *--s2;
+    }
+  }
+  else if (s1 != s2) {
+    while (n-- > 0) {
+      *s1++ = *s2++;
+    }
+  }
+  else {
+    /* nothing to do. */
+  }
+}
+
+#endif /* MRB_VALUE_ARRAY_H__ */
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/variable.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/variable.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/variable.c	(revision 331)
@@ -0,0 +1,1208 @@
+/*
+** variable.c - mruby variables
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/class.h>
+#include <mruby/proc.h>
+#include <mruby/string.h>
+
+typedef int (iv_foreach_func)(mrb_state*,mrb_sym,mrb_value,void*);
+
+#ifdef MRB_USE_IV_SEGLIST
+
+#ifndef MRB_SEGMENT_SIZE
+#define MRB_SEGMENT_SIZE 4
+#endif
+
+typedef struct segment {
+  mrb_sym key[MRB_SEGMENT_SIZE];
+  mrb_value val[MRB_SEGMENT_SIZE];
+  struct segment *next;
+} segment;
+
+/* Instance variable table structure */
+typedef struct iv_tbl {
+  segment *rootseg;
+  size_t size;
+  size_t last_len;
+} iv_tbl;
+
+/*
+ * Creates the instance variable table.
+ *
+ * Parameters
+ *   mrb
+ * Returns
+ *   the instance variable table.
+ */
+static iv_tbl*
+iv_new(mrb_state *mrb)
+{
+  iv_tbl *t;
+
+  t = (iv_tbl*)mrb_malloc(mrb, sizeof(iv_tbl));
+  t->size = 0;
+  t->rootseg =  NULL;
+  t->last_len = 0;
+
+  return t;
+}
+
+/*
+ * Set the value for the symbol in the instance variable table.
+ *
+ * Parameters
+ *   mrb
+ *   t     the instance variable table to be set in.
+ *   sym   the symbol to be used as the key.
+ *   val   the value to be set.
+ */
+static void
+iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val)
+{
+  segment *seg = t->rootseg;
+  segment *prev = NULL;
+  segment *matched_seg = NULL;
+  size_t matched_idx = 0;
+  size_t i;
+
+  while (seg) {
+    for (i=0; i<MRB_SEGMENT_SIZE; i++) {
+      mrb_sym key = seg->key[i];
+      /* Found room in last segment after last_len */
+      if (!seg->next && i >= t->last_len) {
+        seg->key[i] = sym;
+        seg->val[i] = val;
+        t->last_len = i+1;
+        t->size++;
+        return;
+      }
+      if (!matched_seg && key == 0) {
+        matched_seg = seg;
+        matched_idx = i;
+      }
+      else if (key == sym) {
+        seg->val[i] = val;
+        return;
+      }
+    }
+    prev = seg;
+    seg = seg->next;
+  }
+
+  /* Not found */
+  t->size++;
+  if (matched_seg) {
+    matched_seg->key[matched_idx] = sym;
+    matched_seg->val[matched_idx] = val;
+    return;
+  }
+
+  seg = (segment*)mrb_malloc(mrb, sizeof(segment));
+  if (!seg) return;
+  seg->next = NULL;
+  seg->key[0] = sym;
+  seg->val[0] = val;
+  t->last_len = 1;
+  if (prev) {
+    prev->next = seg;
+  }
+  else {
+    t->rootseg = seg;
+  }
+}
+
+/*
+ * Get a value for a symbol from the instance variable table.
+ *
+ * Parameters
+ *   mrb
+ *   t     the variable table to be searched.
+ *   sym   the symbol to be used as the key.
+ *   vp    the value pointer. Receives the value if the specified symbol is
+ *         contained in the instance variable table.
+ * Returns
+ *   true if the specified symbol is contained in the instance variable table.
+ */
+static mrb_bool
+iv_get(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
+{
+  segment *seg;
+  size_t i;
+
+  seg = t->rootseg;
+  while (seg) {
+    for (i=0; i<MRB_SEGMENT_SIZE; i++) {
+      mrb_sym key = seg->key[i];
+
+      if (!seg->next && i >= t->last_len) {
+        return FALSE;
+      }
+      if (key == sym) {
+        if (vp) *vp = seg->val[i];
+        return TRUE;
+      }
+    }
+    seg = seg->next;
+  }
+  return FALSE;
+}
+
+/*
+ * Deletes the value for the symbol from the instance variable table.
+ *
+ * Parameters
+ *   t    the variable table to be searched.
+ *   sym  the symbol to be used as the key.
+ *   vp   the value pointer. Receive the deleted value if the symbol is
+ *        contained in the instance variable table.
+ * Returns
+ *   true if the specified symbol is contained in the instance variable table.
+ */
+static mrb_bool
+iv_del(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
+{
+  segment *seg;
+  size_t i;
+
+  seg = t->rootseg;
+  while (seg) {
+    for (i=0; i<MRB_SEGMENT_SIZE; i++) {
+      mrb_sym key = seg->key[i];
+
+      if (!seg->next && i >= t->last_len) {
+        return FALSE;
+      }
+      if (key == sym) {
+        t->size--;
+        seg->key[i] = 0;
+        if (vp) *vp = seg->val[i];
+        return TRUE;
+      }
+    }
+    seg = seg->next;
+  }
+  return FALSE;
+}
+
+static mrb_bool
+iv_foreach(mrb_state *mrb, iv_tbl *t, iv_foreach_func *func, void *p)
+{
+  segment *seg;
+  size_t i;
+  int n;
+
+  seg = t->rootseg;
+  while (seg) {
+    for (i=0; i<MRB_SEGMENT_SIZE; i++) {
+      mrb_sym key = seg->key[i];
+
+      /* no value in last segment after last_len */
+      if (!seg->next && i >= t->last_len) {
+        return FALSE;
+      }
+      if (key != 0) {
+        n =(*func)(mrb, key, seg->val[i], p);
+        if (n > 0) return FALSE;
+        if (n < 0) {
+          t->size--;
+          seg->key[i] = 0;
+        }
+      }
+    }
+    seg = seg->next;
+  }
+  return TRUE;
+}
+
+static size_t
+iv_size(mrb_state *mrb, iv_tbl *t)
+{
+  segment *seg;
+  size_t size = 0;
+
+  if (!t) return 0;
+  if (t->size > 0) return t->size;
+  seg = t->rootseg;
+  while (seg) {
+    if (seg->next == NULL) {
+      size += t->last_len;
+      return size;
+    }
+    seg = seg->next;
+    size += MRB_SEGMENT_SIZE;
+  }
+  /* empty iv_tbl */
+  return 0;
+}
+
+static iv_tbl*
+iv_copy(mrb_state *mrb, iv_tbl *t)
+{
+  segment *seg;
+  iv_tbl *t2;
+
+  size_t i;
+
+  seg = t->rootseg;
+  t2 = iv_new(mrb);
+
+  while (seg != NULL) {
+    for (i=0; i<MRB_SEGMENT_SIZE; i++) {
+      mrb_sym key = seg->key[i];
+      mrb_value val = seg->val[i];
+
+      if ((seg->next == NULL) && (i >= t->last_len)) {
+        return t2;
+      }
+      iv_put(mrb, t2, key, val);
+    }
+    seg = seg->next;
+  }
+  return t2;
+}
+
+static void
+iv_free(mrb_state *mrb, iv_tbl *t)
+{
+  segment *seg;
+
+  seg = t->rootseg;
+  while (seg) {
+    segment *p = seg;
+    seg = seg->next;
+    mrb_free(mrb, p);
+  }
+  mrb_free(mrb, t);
+}
+
+#else
+
+#include <mruby/khash.h>
+
+#ifndef MRB_IVHASH_INIT_SIZE
+#define MRB_IVHASH_INIT_SIZE 8
+#endif
+
+KHASH_DECLARE(iv, mrb_sym, mrb_value, TRUE)
+KHASH_DEFINE(iv, mrb_sym, mrb_value, TRUE, kh_int_hash_func, kh_int_hash_equal)
+
+typedef struct iv_tbl {
+  khash_t(iv) h;
+} iv_tbl;
+
+static iv_tbl*
+iv_new(mrb_state *mrb)
+{
+  return (iv_tbl*)kh_init_size(iv, mrb, MRB_IVHASH_INIT_SIZE);
+}
+
+static void
+iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val)
+{
+  khash_t(iv) *h = &t->h;
+  khiter_t k;
+
+  k = kh_put(iv, mrb, h, sym);
+  kh_value(h, k) = val;
+}
+
+static mrb_bool
+iv_get(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
+{
+  khash_t(iv) *h = &t->h;
+  khiter_t k;
+
+  k = kh_get(iv, mrb, h, sym);
+  if (k != kh_end(h)) {
+    if (vp) *vp = kh_value(h, k);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static mrb_bool
+iv_del(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
+{
+  khash_t(iv) *h = &t->h;
+  khiter_t k;
+
+  if (h) {
+    k = kh_get(iv, mrb, h, sym);
+    if (k != kh_end(h)) {
+      mrb_value val = kh_value(h, k);
+      kh_del(iv, mrb, h, k);
+      if (vp) *vp = val;
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+static mrb_bool
+iv_foreach(mrb_state *mrb, iv_tbl *t, iv_foreach_func *func, void *p)
+{
+  khash_t(iv) *h = &t->h;
+  khiter_t k;
+  int n;
+
+  if (h) {
+    for (k = kh_begin(h); k != kh_end(h); k++) {
+      if (kh_exist(h, k)) {
+        n = (*func)(mrb, kh_key(h, k), kh_value(h, k), p);
+        if (n > 0) return FALSE;
+        if (n < 0) {
+          kh_del(iv, mrb, h, k);
+        }
+      }
+    }
+  }
+  return TRUE;
+}
+
+static size_t
+iv_size(mrb_state *mrb, iv_tbl *t)
+{
+  khash_t(iv) *h;
+
+  if (t && (h = &t->h)) {
+    return kh_size(h);
+  }
+  return 0;
+}
+
+static iv_tbl*
+iv_copy(mrb_state *mrb, iv_tbl *t)
+{
+  return (iv_tbl*)kh_copy(iv, mrb, &t->h);
+}
+
+static void
+iv_free(mrb_state *mrb, iv_tbl *t)
+{
+  kh_destroy(iv, mrb, &t->h);
+}
+
+#endif
+
+static int
+iv_mark_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
+{
+  mrb_gc_mark_value(mrb, v);
+  return 0;
+}
+
+static void
+mark_tbl(mrb_state *mrb, iv_tbl *t)
+{
+  if (t) {
+    iv_foreach(mrb, t, iv_mark_i, 0);
+  }
+}
+
+void
+mrb_gc_mark_gv(mrb_state *mrb)
+{
+  mark_tbl(mrb, mrb->globals);
+}
+
+void
+mrb_gc_free_gv(mrb_state *mrb)
+{
+  if (mrb->globals)
+    iv_free(mrb, mrb->globals);
+}
+
+void
+mrb_gc_mark_iv(mrb_state *mrb, struct RObject *obj)
+{
+  mark_tbl(mrb, obj->iv);
+}
+
+size_t
+mrb_gc_mark_iv_size(mrb_state *mrb, struct RObject *obj)
+{
+  return iv_size(mrb, obj->iv);
+}
+
+void
+mrb_gc_free_iv(mrb_state *mrb, struct RObject *obj)
+{
+  if (obj->iv) {
+    iv_free(mrb, obj->iv);
+  }
+}
+
+mrb_value
+mrb_vm_special_get(mrb_state *mrb, mrb_sym i)
+{
+  return mrb_fixnum_value(0);
+}
+
+void
+mrb_vm_special_set(mrb_state *mrb, mrb_sym i, mrb_value v)
+{
+}
+
+static mrb_bool
+obj_iv_p(mrb_value obj)
+{
+  switch (mrb_type(obj)) {
+    case MRB_TT_OBJECT:
+    case MRB_TT_CLASS:
+    case MRB_TT_MODULE:
+    case MRB_TT_SCLASS:
+    case MRB_TT_HASH:
+    case MRB_TT_DATA:
+    case MRB_TT_EXCEPTION:
+      return TRUE;
+    default:
+      return FALSE;
+  }
+}
+
+MRB_API mrb_value
+mrb_obj_iv_get(mrb_state *mrb, struct RObject *obj, mrb_sym sym)
+{
+  mrb_value v;
+
+  if (obj->iv && iv_get(mrb, obj->iv, sym, &v))
+    return v;
+  return mrb_nil_value();
+}
+
+MRB_API mrb_value
+mrb_iv_get(mrb_state *mrb, mrb_value obj, mrb_sym sym)
+{
+  if (obj_iv_p(obj)) {
+    return mrb_obj_iv_get(mrb, mrb_obj_ptr(obj), sym);
+  }
+  return mrb_nil_value();
+}
+
+MRB_API void
+mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
+{
+  iv_tbl *t = obj->iv;
+
+  if (MRB_FROZEN_P(obj)) {
+    mrb_raisef(mrb, E_RUNTIME_ERROR, "can't modify frozen %S", mrb_obj_value(obj));
+  }
+  if (!t) {
+    t = obj->iv = iv_new(mrb);
+  }
+  mrb_write_barrier(mrb, (struct RBasic*)obj);
+  iv_put(mrb, t, sym, v);
+}
+
+MRB_API void
+mrb_obj_iv_ifnone(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v)
+{
+  iv_tbl *t = obj->iv;
+
+  if (!t) {
+    t = obj->iv = iv_new(mrb);
+  }
+  else if (iv_get(mrb, t, sym, &v)) {
+    return;
+  }
+  mrb_write_barrier(mrb, (struct RBasic*)obj);
+  iv_put(mrb, t, sym, v);
+}
+
+MRB_API void
+mrb_iv_set(mrb_state *mrb, mrb_value obj, mrb_sym sym, mrb_value v)
+{
+  if (obj_iv_p(obj)) {
+    mrb_obj_iv_set(mrb, mrb_obj_ptr(obj), sym, v);
+  }
+  else {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "cannot set instance variable");
+  }
+}
+
+MRB_API mrb_bool
+mrb_obj_iv_defined(mrb_state *mrb, struct RObject *obj, mrb_sym sym)
+{
+  iv_tbl *t;
+
+  t = obj->iv;
+  if (t) {
+    return iv_get(mrb, t, sym, NULL);
+  }
+  return FALSE;
+}
+
+MRB_API mrb_bool
+mrb_iv_defined(mrb_state *mrb, mrb_value obj, mrb_sym sym)
+{
+  if (!obj_iv_p(obj)) return FALSE;
+  return mrb_obj_iv_defined(mrb, mrb_obj_ptr(obj), sym);
+}
+
+#define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c))
+
+MRB_API mrb_bool
+mrb_iv_p(mrb_state *mrb, mrb_sym iv_name)
+{
+  const char *s;
+  mrb_int i, len;
+
+  s = mrb_sym2name_len(mrb, iv_name, &len);
+  if (len < 2) return FALSE;
+  if (s[0] != '@') return FALSE;
+  if (s[1] == '@') return FALSE;
+  for (i=1; i<len; i++) {
+    if (!identchar(s[i])) return FALSE;
+  }
+  return TRUE;
+}
+
+MRB_API void
+mrb_iv_check(mrb_state *mrb, mrb_sym iv_name)
+{
+  if (!mrb_iv_p(mrb, iv_name)) {
+    mrb_name_error(mrb, iv_name, "'%S' is not allowed as an instance variable name", mrb_sym2str(mrb, iv_name));
+  }
+}
+
+MRB_API void
+mrb_iv_copy(mrb_state *mrb, mrb_value dest, mrb_value src)
+{
+  struct RObject *d = mrb_obj_ptr(dest);
+  struct RObject *s = mrb_obj_ptr(src);
+
+  if (d->iv) {
+    iv_free(mrb, d->iv);
+    d->iv = 0;
+  }
+  if (s->iv) {
+    mrb_write_barrier(mrb, (struct RBasic*)d);
+    d->iv = iv_copy(mrb, s->iv);
+  }
+}
+
+static int
+inspect_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
+{
+  mrb_value str = *(mrb_value*)p;
+  const char *s;
+  mrb_int len;
+  mrb_value ins;
+  char *sp = RSTRING_PTR(str);
+
+  /* need not to show internal data */
+  if (sp[0] == '-') { /* first element */
+    sp[0] = '#';
+    mrb_str_cat_lit(mrb, str, " ");
+  }
+  else {
+    mrb_str_cat_lit(mrb, str, ", ");
+  }
+  s = mrb_sym2name_len(mrb, sym, &len);
+  mrb_str_cat(mrb, str, s, len);
+  mrb_str_cat_lit(mrb, str, "=");
+  if (mrb_type(v) == MRB_TT_OBJECT) {
+    ins = mrb_any_to_s(mrb, v);
+  }
+  else {
+    ins = mrb_inspect(mrb, v);
+  }
+  mrb_str_cat_str(mrb, str, ins);
+  return 0;
+}
+
+mrb_value
+mrb_obj_iv_inspect(mrb_state *mrb, struct RObject *obj)
+{
+  iv_tbl *t = obj->iv;
+  size_t len = iv_size(mrb, t);
+
+  if (len > 0) {
+    const char *cn = mrb_obj_classname(mrb, mrb_obj_value(obj));
+    mrb_value str = mrb_str_buf_new(mrb, 30);
+
+    mrb_str_cat_lit(mrb, str, "-<");
+    mrb_str_cat_cstr(mrb, str, cn);
+    mrb_str_cat_lit(mrb, str, ":");
+    mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, obj));
+
+    iv_foreach(mrb, t, inspect_i, &str);
+    mrb_str_cat_lit(mrb, str, ">");
+    return str;
+  }
+  return mrb_any_to_s(mrb, mrb_obj_value(obj));
+}
+
+MRB_API mrb_value
+mrb_iv_remove(mrb_state *mrb, mrb_value obj, mrb_sym sym)
+{
+  if (obj_iv_p(obj)) {
+    iv_tbl *t = mrb_obj_ptr(obj)->iv;
+    mrb_value val;
+
+    if (t && iv_del(mrb, t, sym, &val)) {
+      return val;
+    }
+  }
+  return mrb_undef_value();
+}
+
+mrb_value
+mrb_vm_iv_get(mrb_state *mrb, mrb_sym sym)
+{
+  /* get self */
+  return mrb_iv_get(mrb, mrb->c->stack[0], sym);
+}
+
+void
+mrb_vm_iv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
+{
+  /* get self */
+  mrb_iv_set(mrb, mrb->c->stack[0], sym, v);
+}
+
+static int
+iv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
+{
+  mrb_value ary;
+  const char* s;
+  mrb_int len;
+
+  ary = *(mrb_value*)p;
+  s = mrb_sym2name_len(mrb, sym, &len);
+  if (len > 1 && s[0] == '@' && s[1] != '@') {
+    mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
+  }
+  return 0;
+}
+
+/* 15.3.1.3.23 */
+/*
+ *  call-seq:
+ *     obj.instance_variables    -> array
+ *
+ *  Returns an array of instance variable names for the receiver. Note
+ *  that simply defining an accessor does not create the corresponding
+ *  instance variable.
+ *
+ *     class Fred
+ *       attr_accessor :a1
+ *       def initialize
+ *         @iv = 3
+ *       end
+ *     end
+ *     Fred.new.instance_variables   #=> [:@iv]
+ */
+mrb_value
+mrb_obj_instance_variables(mrb_state *mrb, mrb_value self)
+{
+  mrb_value ary;
+
+  ary = mrb_ary_new(mrb);
+  if (obj_iv_p(self) && mrb_obj_ptr(self)->iv) {
+    iv_foreach(mrb, mrb_obj_ptr(self)->iv, iv_i, &ary);
+  }
+  return ary;
+}
+
+static int
+cv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
+{
+  mrb_value ary;
+  const char* s;
+  mrb_int len;
+
+  ary = *(mrb_value*)p;
+  s = mrb_sym2name_len(mrb, sym, &len);
+  if (len > 2 && s[0] == '@' && s[1] == '@') {
+    mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
+  }
+  return 0;
+}
+
+/* 15.2.2.4.19 */
+/*
+ *  call-seq:
+ *     mod.class_variables   -> array
+ *
+ *  Returns an array of the names of class variables in <i>mod</i>.
+ *
+ *     class One
+ *       @@var1 = 1
+ *     end
+ *     class Two < One
+ *       @@var2 = 2
+ *     end
+ *     One.class_variables   #=> [:@@var1]
+ *     Two.class_variables   #=> [:@@var2]
+ */
+mrb_value
+mrb_mod_class_variables(mrb_state *mrb, mrb_value mod)
+{
+  mrb_value ary;
+  struct RClass *c;
+
+  ary = mrb_ary_new(mrb);
+  c = mrb_class_ptr(mod);
+  while (c) {
+    if (c->iv) {
+      iv_foreach(mrb, c->iv, cv_i, &ary);
+    }
+    c = c->super;
+  }
+  return ary;
+}
+
+MRB_API mrb_value
+mrb_mod_cv_get(mrb_state *mrb, struct RClass *c, mrb_sym sym)
+{
+  struct RClass * cls = c;
+  mrb_value v;
+  int given = FALSE;
+
+  while (c) {
+    if (c->iv && iv_get(mrb, c->iv, sym, &v)) {
+      given = TRUE;
+    }
+    c = c->super;
+  }
+  if (given) return v;
+  if (cls && cls->tt == MRB_TT_SCLASS) {
+    mrb_value klass;
+
+    klass = mrb_obj_iv_get(mrb, (struct RObject *)cls,
+                           mrb_intern_lit(mrb, "__attached__"));
+    c = mrb_class_ptr(klass);
+    if (c->tt == MRB_TT_CLASS || c->tt == MRB_TT_MODULE) {
+      given = FALSE;
+      while (c) {
+        if (c->iv && iv_get(mrb, c->iv, sym, &v)) {
+          given = TRUE;
+        }
+        c = c->super;
+      }
+      if (given) return v;
+    }
+  }
+  mrb_name_error(mrb, sym, "uninitialized class variable %S in %S",
+                 mrb_sym2str(mrb, sym), mrb_obj_value(cls));
+  /* not reached */
+  return mrb_nil_value();
+}
+
+MRB_API mrb_value
+mrb_cv_get(mrb_state *mrb, mrb_value mod, mrb_sym sym)
+{
+  return mrb_mod_cv_get(mrb, mrb_class_ptr(mod), sym);
+}
+
+MRB_API void
+mrb_mod_cv_set(mrb_state *mrb, struct RClass *c, mrb_sym sym, mrb_value v)
+{
+  struct RClass * cls = c;
+
+  while (c) {
+    if (c->iv) {
+      iv_tbl *t = c->iv;
+
+      if (iv_get(mrb, t, sym, NULL)) {
+        mrb_write_barrier(mrb, (struct RBasic*)c);
+        iv_put(mrb, t, sym, v);
+        return;
+      }
+    }
+    c = c->super;
+  }
+
+  if (cls && cls->tt == MRB_TT_SCLASS) {
+    mrb_value klass;
+
+    klass = mrb_obj_iv_get(mrb, (struct RObject*)cls,
+                           mrb_intern_lit(mrb, "__attached__"));
+    switch (mrb_type(klass)) {
+    case MRB_TT_CLASS:
+    case MRB_TT_MODULE:
+    case MRB_TT_SCLASS:
+      c = mrb_class_ptr(klass);
+      break;
+    default:
+      c = cls;
+      break;
+    }
+  }
+  else{
+    c = cls;
+  }
+
+  if (!c->iv) {
+    c->iv = iv_new(mrb);
+  }
+
+  mrb_write_barrier(mrb, (struct RBasic*)c);
+  iv_put(mrb, c->iv, sym, v);
+}
+
+MRB_API void
+mrb_cv_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v)
+{
+  mrb_mod_cv_set(mrb, mrb_class_ptr(mod), sym, v);
+}
+
+MRB_API mrb_bool
+mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym)
+{
+  while (c) {
+    if (c->iv) {
+      iv_tbl *t = c->iv;
+      if (iv_get(mrb, t, sym, NULL)) return TRUE;
+    }
+    c = c->super;
+  }
+
+  return FALSE;
+}
+
+MRB_API mrb_bool
+mrb_cv_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym)
+{
+  return mrb_mod_cv_defined(mrb, mrb_class_ptr(mod), sym);
+}
+
+mrb_value
+mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym)
+{
+  struct RClass *c = mrb->c->ci->proc->target_class;
+
+  if (!c) c = mrb->c->ci->target_class;
+
+  return mrb_mod_cv_get(mrb, c, sym);
+}
+
+void
+mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
+{
+  struct RClass *c = mrb->c->ci->proc->target_class;
+
+  if (!c) c = mrb->c->ci->target_class;
+  mrb_mod_cv_set(mrb, c, sym, v);
+}
+
+static void
+mod_const_check(mrb_state *mrb, mrb_value mod)
+{
+  switch (mrb_type(mod)) {
+  case MRB_TT_CLASS:
+  case MRB_TT_MODULE:
+  case MRB_TT_SCLASS:
+    break;
+  default:
+    mrb_raise(mrb, E_TYPE_ERROR, "constant look-up for non class/module");
+    break;
+  }
+}
+
+static mrb_value
+const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym)
+{
+  struct RClass *c = base;
+  mrb_value v;
+  iv_tbl *t;
+  mrb_bool retry = FALSE;
+  mrb_value name;
+
+L_RETRY:
+  while (c) {
+    if (c->iv) {
+      t = c->iv;
+      if (iv_get(mrb, t, sym, &v))
+        return v;
+    }
+    c = c->super;
+  }
+  if (!retry && base && base->tt == MRB_TT_MODULE) {
+    c = mrb->object_class;
+    retry = TRUE;
+    goto L_RETRY;
+  }
+  name = mrb_symbol_value(sym);
+  return mrb_funcall_argv(mrb, mrb_obj_value(base), mrb_intern_lit(mrb, "const_missing"), 1, &name);
+}
+
+MRB_API mrb_value
+mrb_const_get(mrb_state *mrb, mrb_value mod, mrb_sym sym)
+{
+  mod_const_check(mrb, mod);
+  return const_get(mrb, mrb_class_ptr(mod), sym);
+}
+
+mrb_value
+mrb_vm_const_get(mrb_state *mrb, mrb_sym sym)
+{
+  struct RClass *c = mrb->c->ci->proc->target_class;
+
+  if (!c) c = mrb->c->ci->target_class;
+  if (c) {
+    struct RClass *c2;
+    mrb_value v;
+
+    if (c->iv && iv_get(mrb, c->iv, sym, &v)) {
+      return v;
+    }
+    c2 = c;
+    while (c2 && c2->tt == MRB_TT_SCLASS) {
+      mrb_value klass;
+      klass = mrb_obj_iv_get(mrb, (struct RObject *)c2,
+                             mrb_intern_lit(mrb, "__attached__"));
+      c2 = mrb_class_ptr(klass);
+    }
+    if (c2->tt == MRB_TT_CLASS || c2->tt == MRB_TT_MODULE) c = c2;
+    c2 = c;
+    for (;;) {
+      c2 = mrb_class_outer_module(mrb, c2);
+      if (!c2) break;
+      if (c2->iv && iv_get(mrb, c2->iv, sym, &v)) {
+        return v;
+      }
+    }
+  }
+  return const_get(mrb, c, sym);
+}
+
+MRB_API void
+mrb_const_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v)
+{
+  mod_const_check(mrb, mod);
+  mrb_iv_set(mrb, mod, sym, v);
+}
+
+void
+mrb_vm_const_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
+{
+  struct RClass *c = mrb->c->ci->proc->target_class;
+
+  if (!c) c = mrb->c->ci->target_class;
+  mrb_obj_iv_set(mrb, (struct RObject*)c, sym, v);
+}
+
+MRB_API void
+mrb_const_remove(mrb_state *mrb, mrb_value mod, mrb_sym sym)
+{
+  mod_const_check(mrb, mod);
+  mrb_iv_remove(mrb, mod, sym);
+}
+
+MRB_API void
+mrb_define_const(mrb_state *mrb, struct RClass *mod, const char *name, mrb_value v)
+{
+  mrb_obj_iv_set(mrb, (struct RObject*)mod, mrb_intern_cstr(mrb, name), v);
+}
+
+MRB_API void
+mrb_define_global_const(mrb_state *mrb, const char *name, mrb_value val)
+{
+  mrb_define_const(mrb, mrb->object_class, name, val);
+}
+
+static int
+const_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
+{
+  mrb_value ary;
+  const char* s;
+  mrb_int len;
+
+  ary = *(mrb_value*)p;
+  s = mrb_sym2name_len(mrb, sym, &len);
+  if (len >= 1 && ISUPPER(s[0])) {
+    mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
+  }
+  return 0;
+}
+
+/* 15.2.2.4.24 */
+/*
+ *  call-seq:
+ *     mod.constants    -> array
+ *
+ *  Returns an array of all names of contants defined in the receiver.
+ */
+mrb_value
+mrb_mod_constants(mrb_state *mrb, mrb_value mod)
+{
+  mrb_value ary;
+  mrb_bool inherit = TRUE;
+  struct RClass *c = mrb_class_ptr(mod);
+
+  mrb_get_args(mrb, "|b", &inherit);
+  ary = mrb_ary_new(mrb);
+  while (c) {
+    if (c->iv) {
+      iv_foreach(mrb, c->iv, const_i, &ary);
+    }
+    if (!inherit) break;
+    c = c->super;
+    if (c == mrb->object_class) break;
+  }
+  return ary;
+}
+
+MRB_API mrb_value
+mrb_gv_get(mrb_state *mrb, mrb_sym sym)
+{
+  mrb_value v;
+
+  if (!mrb->globals) {
+    return mrb_nil_value();
+  }
+  if (iv_get(mrb, mrb->globals, sym, &v))
+    return v;
+  return mrb_nil_value();
+}
+
+MRB_API void
+mrb_gv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
+{
+  iv_tbl *t;
+
+  if (!mrb->globals) {
+    t = mrb->globals = iv_new(mrb);
+  }
+  else {
+    t = mrb->globals;
+  }
+  iv_put(mrb, t, sym, v);
+}
+
+MRB_API void
+mrb_gv_remove(mrb_state *mrb, mrb_sym sym)
+{
+  if (!mrb->globals) {
+    return;
+  }
+  iv_del(mrb, mrb->globals, sym, NULL);
+}
+
+static int
+gv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
+{
+  mrb_value ary;
+
+  ary = *(mrb_value*)p;
+  mrb_ary_push(mrb, ary, mrb_symbol_value(sym));
+  return 0;
+}
+
+/* 15.3.1.2.4  */
+/* 15.3.1.3.14 */
+/*
+ *  call-seq:
+ *     global_variables    -> array
+ *
+ *  Returns an array of the names of global variables.
+ *
+ *     global_variables.grep /std/   #=> [:$stdin, :$stdout, :$stderr]
+ */
+mrb_value
+mrb_f_global_variables(mrb_state *mrb, mrb_value self)
+{
+  iv_tbl *t = mrb->globals;
+  mrb_value ary = mrb_ary_new(mrb);
+  size_t i;
+  char buf[3];
+
+  if (t) {
+    iv_foreach(mrb, t, gv_i, &ary);
+  }
+  buf[0] = '$';
+  buf[2] = 0;
+  for (i = 1; i <= 9; ++i) {
+    buf[1] = (char)(i + '0');
+    mrb_ary_push(mrb, ary, mrb_symbol_value(mrb_intern(mrb, buf, 2)));
+  }
+  return ary;
+}
+
+static mrb_bool
+mrb_const_defined_0(mrb_state *mrb, mrb_value mod, mrb_sym id, mrb_bool exclude, mrb_bool recurse)
+{
+  struct RClass *klass = mrb_class_ptr(mod);
+  struct RClass *tmp;
+  mrb_bool mod_retry = 0;
+
+  tmp = klass;
+retry:
+  while (tmp) {
+    if (tmp->iv && iv_get(mrb, tmp->iv, id, NULL)) {
+      return TRUE;
+    }
+    if (!recurse && (klass != mrb->object_class)) break;
+    tmp = tmp->super;
+  }
+  if (!exclude && !mod_retry && (klass->tt == MRB_TT_MODULE)) {
+    mod_retry = 1;
+    tmp = mrb->object_class;
+    goto retry;
+  }
+  return FALSE;
+}
+
+MRB_API mrb_bool
+mrb_const_defined(mrb_state *mrb, mrb_value mod, mrb_sym id)
+{
+  return mrb_const_defined_0(mrb, mod, id, TRUE, TRUE);
+}
+
+MRB_API mrb_bool
+mrb_const_defined_at(mrb_state *mrb, mrb_value mod, mrb_sym id)
+{
+  return mrb_const_defined_0(mrb, mod, id, TRUE, FALSE);
+}
+
+MRB_API mrb_value
+mrb_attr_get(mrb_state *mrb, mrb_value obj, mrb_sym id)
+{
+  return mrb_iv_get(mrb, obj, id);
+}
+
+struct csym_arg {
+  struct RClass *c;
+  mrb_sym sym;
+};
+
+static int
+csym_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
+{
+  struct csym_arg *a = (struct csym_arg*)p;
+  struct RClass *c = a->c;
+
+  if (mrb_type(v) == c->tt && mrb_class_ptr(v) == c) {
+    a->sym = sym;
+    return 1;     /* stop iteration */
+  }
+  return 0;
+}
+
+mrb_sym
+mrb_class_sym(mrb_state *mrb, struct RClass *c, struct RClass *outer)
+{
+  mrb_value name;
+
+  name = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__classid__"));
+  if (mrb_nil_p(name)) {
+
+    if (!outer) return 0;
+    else {
+      struct csym_arg arg;
+
+      arg.c = c;
+      arg.sym = 0;
+      iv_foreach(mrb, outer->iv, csym_i, &arg);
+      return arg.sym;
+    }
+  }
+  return mrb_symbol(name);
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/version.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/version.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/version.c	(revision 331)
@@ -0,0 +1,17 @@
+#include <mruby.h>
+#include <mruby/variable.h>
+
+void
+mrb_init_version(mrb_state* mrb)
+{
+  mrb_value mruby_version = mrb_str_new_lit(mrb, MRUBY_VERSION);
+
+  mrb_define_global_const(mrb, "RUBY_VERSION", mrb_str_new_lit(mrb, MRUBY_RUBY_VERSION));
+  mrb_define_global_const(mrb, "RUBY_ENGINE", mrb_str_new_lit(mrb, MRUBY_RUBY_ENGINE));
+  mrb_define_global_const(mrb, "RUBY_ENGINE_VERSION", mruby_version);
+  mrb_define_global_const(mrb, "MRUBY_VERSION", mruby_version);
+  mrb_define_global_const(mrb, "MRUBY_RELEASE_NO", mrb_fixnum_value(MRUBY_RELEASE_NO));
+  mrb_define_global_const(mrb, "MRUBY_RELEASE_DATE", mrb_str_new_lit(mrb, MRUBY_RELEASE_DATE));
+  mrb_define_global_const(mrb, "MRUBY_DESCRIPTION", mrb_str_new_lit(mrb, MRUBY_DESCRIPTION));
+  mrb_define_global_const(mrb, "MRUBY_COPYRIGHT", mrb_str_new_lit(mrb, MRUBY_COPYRIGHT));
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/vm.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/src/vm.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/vm.c	(revision 331)
@@ -0,0 +1,2904 @@
+/*
+** vm.c - virtual machine for mruby
+**
+** See Copyright Notice in mruby.h
+*/
+
+#include <stddef.h>
+#include <stdarg.h>
+#include <math.h>
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/class.h>
+#include <mruby/hash.h>
+#include <mruby/irep.h>
+#include <mruby/numeric.h>
+#include <mruby/proc.h>
+#include <mruby/range.h>
+#include <mruby/string.h>
+#include <mruby/variable.h>
+#include <mruby/error.h>
+#include <mruby/opcode.h>
+#include "value_array.h"
+#include <mruby/throw.h>
+
+#ifndef MRB_DISABLE_STDIO
+#if defined(__cplusplus)
+extern "C" {
+#endif
+void abort(void);
+#if defined(__cplusplus)
+}  /* extern "C" { */
+#endif
+#endif
+
+#define STACK_INIT_SIZE 128
+#define CALLINFO_INIT_SIZE 32
+
+#ifndef ENSURE_STACK_INIT_SIZE
+#define ENSURE_STACK_INIT_SIZE 16
+#endif
+
+#ifndef RESCUE_STACK_INIT_SIZE
+#define RESCUE_STACK_INIT_SIZE 16
+#endif
+
+/* Define amount of linear stack growth. */
+#ifndef MRB_STACK_GROWTH
+#define MRB_STACK_GROWTH 128
+#endif
+
+/* Maximum mrb_funcall() depth. Should be set lower on memory constrained systems. */
+#ifndef MRB_FUNCALL_DEPTH_MAX
+#define MRB_FUNCALL_DEPTH_MAX 512
+#endif
+
+/* Maximum stack depth. Should be set lower on memory constrained systems.
+The value below allows about 60000 recursive calls in the simplest case. */
+#ifndef MRB_STACK_MAX
+#define MRB_STACK_MAX (0x40000 - MRB_STACK_GROWTH)
+#endif
+
+#ifdef VM_DEBUG
+# define DEBUG(x) (x)
+#else
+# define DEBUG(x)
+#endif
+
+#define ARENA_RESTORE(mrb,ai) (mrb)->gc.arena_idx = (ai)
+
+#define CALL_MAXARGS 127
+
+void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args);
+
+static inline void
+stack_clear(mrb_value *from, size_t count)
+{
+#ifndef MRB_NAN_BOXING
+  const mrb_value mrb_value_zero = { { 0 } };
+
+  while (count-- > 0) {
+    *from++ = mrb_value_zero;
+  }
+#else
+  while (count-- > 0) {
+    SET_NIL_VALUE(*from);
+    from++;
+  }
+#endif
+}
+
+static inline void
+stack_copy(mrb_value *dst, const mrb_value *src, size_t size)
+{
+  while (size-- > 0) {
+    *dst++ = *src++;
+  }
+}
+
+static void
+stack_init(mrb_state *mrb)
+{
+  struct mrb_context *c = mrb->c;
+
+  /* mrb_assert(mrb->stack == NULL); */
+  c->stbase = (mrb_value *)mrb_calloc(mrb, STACK_INIT_SIZE, sizeof(mrb_value));
+  c->stend = c->stbase + STACK_INIT_SIZE;
+  c->stack = c->stbase;
+
+  /* mrb_assert(ci == NULL); */
+  c->cibase = (mrb_callinfo *)mrb_calloc(mrb, CALLINFO_INIT_SIZE, sizeof(mrb_callinfo));
+  c->ciend = c->cibase + CALLINFO_INIT_SIZE;
+  c->ci = c->cibase;
+  c->ci->target_class = mrb->object_class;
+  c->ci->stackent = c->stack;
+}
+
+static inline void
+envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t size)
+{
+  mrb_callinfo *ci = mrb->c->cibase;
+
+  if (newbase == oldbase) return;
+  while (ci <= mrb->c->ci) {
+    struct REnv *e = ci->env;
+    mrb_value *st;
+
+    if (e && MRB_ENV_STACK_SHARED_P(e) &&
+        (st = e->stack) && oldbase <= st && st < oldbase+size) {
+      ptrdiff_t off = e->stack - oldbase;
+
+      e->stack = newbase + off;
+    }
+    ci->stackent = newbase + (ci->stackent - oldbase);
+    ci++;
+  }
+}
+
+/** def rec ; $deep =+ 1 ; if $deep > 1000 ; return 0 ; end ; rec ; end  */
+
+static void
+stack_extend_alloc(mrb_state *mrb, int room)
+{
+  mrb_value *oldbase = mrb->c->stbase;
+  mrb_value *newstack;
+  size_t oldsize = mrb->c->stend - mrb->c->stbase;
+  size_t size = oldsize;
+  size_t off = mrb->c->stack - mrb->c->stbase;
+
+  if (off > size) size = off;
+#ifdef MRB_STACK_EXTEND_DOUBLING
+  if (room <= size)
+    size *= 2;
+  else
+    size += room;
+#else
+  /* Use linear stack growth.
+     It is slightly slower than doubling the stack space,
+     but it saves memory on small devices. */
+  if (room <= MRB_STACK_GROWTH)
+    size += MRB_STACK_GROWTH;
+  else
+    size += room;
+#endif
+
+  newstack = (mrb_value *)mrb_realloc(mrb, mrb->c->stbase, sizeof(mrb_value) * size);
+  if (newstack == NULL) {
+    mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
+  }
+  stack_clear(&(newstack[oldsize]), size - oldsize);
+  envadjust(mrb, oldbase, newstack, size);
+  mrb->c->stbase = newstack;
+  mrb->c->stack = mrb->c->stbase + off;
+  mrb->c->stend = mrb->c->stbase + size;
+
+  /* Raise an exception if the new stack size will be too large,
+     to prevent infinite recursion. However, do this only after resizing the stack, so mrb_raise has stack space to work with. */
+  if (size > MRB_STACK_MAX) {
+    mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
+  }
+}
+
+static inline void
+stack_extend(mrb_state *mrb, int room)
+{
+  if (mrb->c->stack + room >= mrb->c->stend) {
+    stack_extend_alloc(mrb, room);
+  }
+}
+
+static inline struct REnv*
+uvenv(mrb_state *mrb, int up)
+{
+  struct REnv *e = mrb->c->ci->proc->env;
+
+  while (up--) {
+    if (!e) return NULL;
+    e = (struct REnv*)e->c;
+  }
+  return e;
+}
+
+static inline mrb_bool
+is_strict(mrb_state *mrb, struct REnv *e)
+{
+  int cioff = e->cioff;
+
+  if (MRB_ENV_STACK_SHARED_P(e) && e->cxt.c->cibase[cioff].proc &&
+      MRB_PROC_STRICT_P(e->cxt.c->cibase[cioff].proc)) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+static inline struct REnv*
+top_env(mrb_state *mrb, struct RProc *proc)
+{
+  struct REnv *e = proc->env;
+
+  if (is_strict(mrb, e)) return e;
+  while (e->c) {
+    e = (struct REnv*)e->c;
+    if (is_strict(mrb, e)) return e;
+  }
+  return e;
+}
+
+#define CI_ACC_SKIP    -1
+#define CI_ACC_DIRECT  -2
+#define CI_ACC_RESUMED -3
+
+static mrb_callinfo*
+cipush(mrb_state *mrb)
+{
+  struct mrb_context *c = mrb->c;
+  mrb_callinfo *ci = c->ci;
+
+  int ridx = ci->ridx;
+
+  if (ci + 1 == c->ciend) {
+    ptrdiff_t size = ci - c->cibase;
+
+    c->cibase = (mrb_callinfo *)mrb_realloc(mrb, c->cibase, sizeof(mrb_callinfo)*size*2);
+    c->ci = c->cibase + size;
+    c->ciend = c->cibase + size * 2;
+  }
+  ci = ++c->ci;
+  ci->epos = mrb->c->eidx;
+  ci->ridx = ridx;
+  ci->env = 0;
+  ci->pc = 0;
+  ci->err = 0;
+  ci->proc = 0;
+  ci->acc = 0;
+
+  return ci;
+}
+
+MRB_API void
+mrb_env_unshare(mrb_state *mrb, struct REnv *e)
+{
+  size_t len = (size_t)MRB_ENV_STACK_LEN(e);
+  ptrdiff_t cioff = e->cioff;
+  mrb_value *p;
+
+  if (!MRB_ENV_STACK_SHARED_P(e)) return;
+  if (e->cxt.c != mrb->c) return;
+  if (e->cioff == 0 && e->cxt.c == mrb->root_c) return;
+  MRB_ENV_UNSHARE_STACK(e);
+  if (!e->c) {
+    /* save block argument position (negated) */
+    e->cioff = -e->cxt.c->cibase[cioff].argc-1;
+  }
+  e->cxt.mid = e->cxt.c->cibase[cioff].mid;
+  p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len);
+  if (len > 0) {
+    stack_copy(p, e->stack, len);
+  }
+  e->stack = p;
+  mrb_write_barrier(mrb, (struct RBasic *)e);
+}
+
+static void
+cipop(mrb_state *mrb)
+{
+  struct mrb_context *c = mrb->c;
+  struct REnv *env = c->ci->env;
+
+  c->ci--;
+
+  if (env) {
+    mrb_env_unshare(mrb, env);
+  }
+}
+
+void mrb_exc_set(mrb_state *mrb, mrb_value exc);
+
+static void
+ecall(mrb_state *mrb, int i)
+{
+  struct RProc *p;
+  mrb_callinfo *ci = mrb->c->ci;
+  mrb_value *self = mrb->c->stack;
+  struct RObject *exc;
+  ptrdiff_t cioff;
+  int ai = mrb_gc_arena_save(mrb);
+
+  if (i<0) return;
+  if (ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
+    mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
+  }
+  p = mrb->c->ensure[i];
+  if (!p) return;
+  mrb->c->ensure[i] = NULL;
+  cioff = ci - mrb->c->cibase;
+  ci = cipush(mrb);
+  ci->stackent = mrb->c->stack;
+  ci->mid = ci[-1].mid;
+  ci->acc = CI_ACC_SKIP;
+  ci->argc = 0;
+  ci->proc = p;
+  ci->nregs = p->body.irep->nregs;
+  ci->target_class = p->target_class;
+  mrb->c->stack = mrb->c->stack + ci[-1].nregs;
+  exc = mrb->exc; mrb->exc = 0;
+  if (exc) {
+    mrb_gc_protect(mrb, mrb_obj_value(exc));
+  }
+  mrb_run(mrb, p, *self);
+  mrb->c->ci = mrb->c->cibase + cioff;
+  if (!mrb->exc) mrb->exc = exc;
+  mrb_gc_arena_restore(mrb, ai);
+}
+
+#ifndef MRB_FUNCALL_ARGC_MAX
+#define MRB_FUNCALL_ARGC_MAX 16
+#endif
+
+MRB_API mrb_value
+mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, mrb_int argc, ...)
+{
+  mrb_value argv[MRB_FUNCALL_ARGC_MAX];
+  va_list ap;
+  mrb_int i;
+  mrb_sym mid = mrb_intern_cstr(mrb, name);
+
+  if (argc > MRB_FUNCALL_ARGC_MAX) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "Too long arguments. (limit=" MRB_STRINGIZE(MRB_FUNCALL_ARGC_MAX) ")");
+  }
+
+  va_start(ap, argc);
+  for (i = 0; i < argc; i++) {
+    argv[i] = va_arg(ap, mrb_value);
+  }
+  va_end(ap);
+  return mrb_funcall_argv(mrb, self, mid, argc, argv);
+}
+
+MRB_API mrb_value
+mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, const mrb_value *argv, mrb_value blk)
+{
+  mrb_value val;
+
+  if (!mrb->jmp) {
+    struct mrb_jmpbuf c_jmp;
+    ptrdiff_t nth_ci = mrb->c->ci - mrb->c->cibase;
+
+    MRB_TRY(&c_jmp) {
+      mrb->jmp = &c_jmp;
+      /* recursive call */
+      val = mrb_funcall_with_block(mrb, self, mid, argc, argv, blk);
+      mrb->jmp = 0;
+    }
+    MRB_CATCH(&c_jmp) { /* error */
+      while (nth_ci < (mrb->c->ci - mrb->c->cibase)) {
+        mrb->c->stack = mrb->c->ci->stackent;
+        cipop(mrb);
+      }
+      mrb->jmp = 0;
+      val = mrb_obj_value(mrb->exc);
+    }
+    MRB_END_EXC(&c_jmp);
+    mrb->jmp = 0;
+  }
+  else {
+    struct RProc *p;
+    struct RClass *c;
+    mrb_callinfo *ci;
+    int n;
+    ptrdiff_t voff = -1;
+
+    if (!mrb->c->stack) {
+      stack_init(mrb);
+    }
+    n = mrb->c->ci->nregs;
+    if (argc < 0) {
+      mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%S)", mrb_fixnum_value(argc));
+    }
+    c = mrb_class(mrb, self);
+    p = mrb_method_search_vm(mrb, &c, mid);
+    if (!p) {
+      mrb_sym missing = mrb_intern_lit(mrb, "method_missing");
+      mrb_value args = mrb_ary_new_from_values(mrb, argc, argv);
+      p = mrb_method_search_vm(mrb, &c, missing);
+      if (!p) {
+        mrb_method_missing(mrb, mid, self, args);
+      }
+      mrb_ary_unshift(mrb, args, mrb_symbol_value(mid));
+      stack_extend(mrb, n+2);
+      mrb->c->stack[n+1] = args;
+      argc = -1;
+    }
+    if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
+      mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
+    }
+    ci = cipush(mrb);
+    ci->mid = mid;
+    ci->proc = p;
+    ci->stackent = mrb->c->stack;
+    ci->argc = argc;
+    ci->target_class = c;
+    mrb->c->stack = mrb->c->stack + n;
+    if (mrb->c->stbase <= argv && argv < mrb->c->stend) {
+      voff = argv - mrb->c->stbase;
+    }
+    if (MRB_PROC_CFUNC_P(p)) {
+      ci->nregs = argc + 2;
+      stack_extend(mrb, ci->nregs);
+    }
+    else if (argc >= CALL_MAXARGS) {
+      mrb_value args = mrb_ary_new_from_values(mrb, argc, argv);
+      stack_extend(mrb, ci->nregs);
+      mrb->c->stack[1] = args;
+      ci->argc = -1;
+      argc = 1;
+    }
+    else {
+      if (argc < 0) argc = 1;
+      ci->nregs = p->body.irep->nregs + argc;
+      stack_extend(mrb, ci->nregs);
+    }
+    if (voff >= 0) {
+      argv = mrb->c->stbase + voff;
+    }
+    mrb->c->stack[0] = self;
+    if (ci->argc > 0) {
+      stack_copy(mrb->c->stack+1, argv, argc);
+    }
+    mrb->c->stack[argc+1] = blk;
+
+    if (MRB_PROC_CFUNC_P(p)) {
+      int ai = mrb_gc_arena_save(mrb);
+
+      ci->acc = CI_ACC_DIRECT;
+      val = p->body.func(mrb, self);
+      mrb->c->stack = mrb->c->ci->stackent;
+      cipop(mrb);
+      mrb_gc_arena_restore(mrb, ai);
+    }
+    else {
+      ci->acc = CI_ACC_SKIP;
+      val = mrb_run(mrb, p, self);
+    }
+  }
+  mrb_gc_protect(mrb, val);
+  return val;
+}
+
+MRB_API mrb_value
+mrb_funcall_argv(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, const mrb_value *argv)
+{
+  return mrb_funcall_with_block(mrb, self, mid, argc, argv, mrb_nil_value());
+}
+
+mrb_value
+mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p)
+{
+  mrb_callinfo *ci = mrb->c->ci;
+
+  mrb->c->stack[0] = self;
+  ci->proc = p;
+  ci->target_class = p->target_class;
+  if (MRB_PROC_CFUNC_P(p)) {
+    return p->body.func(mrb, self);
+  }
+  if (ci->argc < 0) {
+    stack_extend(mrb, (p->body.irep->nregs < 3) ? 3 : p->body.irep->nregs);
+  }
+  else {
+    stack_extend(mrb, p->body.irep->nregs);
+  }
+
+  ci->nregs = p->body.irep->nregs;
+  ci = cipush(mrb);
+  ci->nregs = 0;
+  ci->target_class = 0;
+  ci->pc = p->body.irep->iseq;
+  ci->stackent = mrb->c->stack;
+  ci->acc = 0;
+
+  return self;
+}
+
+/* 15.3.1.3.4  */
+/* 15.3.1.3.44 */
+/*
+ *  call-seq:
+ *     obj.send(symbol [, args...])        -> obj
+ *     obj.__send__(symbol [, args...])      -> obj
+ *
+ *  Invokes the method identified by _symbol_, passing it any
+ *  arguments specified. You can use <code>__send__</code> if the name
+ *  +send+ clashes with an existing method in _obj_.
+ *
+ *     class Klass
+ *       def hello(*args)
+ *         "Hello " + args.join(' ')
+ *       end
+ *     end
+ *     k = Klass.new
+ *     k.send :hello, "gentle", "readers"   #=> "Hello gentle readers"
+ */
+MRB_API mrb_value
+mrb_f_send(mrb_state *mrb, mrb_value self)
+{
+  mrb_sym name;
+  mrb_value block, *argv, *regs;
+  mrb_int argc, i, len;
+  struct RProc *p;
+  struct RClass *c;
+  mrb_callinfo *ci;
+
+  mrb_get_args(mrb, "n*&", &name, &argv, &argc, &block);
+  ci = mrb->c->ci;
+  if (ci->acc < 0) {
+  funcall:
+    return mrb_funcall_with_block(mrb, self, name, argc, argv, block);
+  }
+
+  c = mrb_class(mrb, self);
+  p = mrb_method_search_vm(mrb, &c, name);
+
+  if (!p) {                     /* call method_mising */
+    goto funcall;
+  }
+
+  ci->mid = name;
+  ci->target_class = c;
+  regs = mrb->c->stack+1;
+  /* remove first symbol from arguments */
+  if (ci->argc >= 0) {
+    for (i=0,len=ci->argc; i<len; i++) {
+      regs[i] = regs[i+1];
+    }
+    ci->argc--;
+  }
+  else {                     /* variable length arguments */
+    mrb_ary_shift(mrb, regs[0]);
+  }
+
+  return mrb_exec_irep(mrb, self, p);
+}
+
+static mrb_value
+eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c)
+{
+  struct RProc *p;
+  mrb_callinfo *ci;
+  mrb_int max = 3;
+
+  if (mrb_nil_p(blk)) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
+  }
+  ci = mrb->c->ci;
+  if (ci->acc == CI_ACC_DIRECT) {
+    ci->target_class = c;
+    return mrb_yield_cont(mrb, blk, self, 1, &self);
+  }
+  ci->target_class = c;
+  p = mrb_proc_ptr(blk);
+  ci->proc = p;
+  ci->argc = 1;
+  ci->mid = ci[-1].mid;
+  if (MRB_PROC_CFUNC_P(p)) {
+    stack_extend(mrb, 3);
+    mrb->c->stack[0] = self;
+    mrb->c->stack[1] = self;
+    mrb->c->stack[2] = mrb_nil_value();
+    return p->body.func(mrb, self);
+  }
+  ci->nregs = p->body.irep->nregs;
+  if (max < ci->nregs) max = ci->nregs;
+  stack_extend(mrb, max);
+  mrb->c->stack[0] = self;
+  mrb->c->stack[1] = self;
+  mrb->c->stack[2] = mrb_nil_value();
+  ci = cipush(mrb);
+  ci->nregs = 0;
+  ci->target_class = 0;
+  ci->pc = p->body.irep->iseq;
+  ci->stackent = mrb->c->stack;
+  ci->acc = 0;
+
+  return self;
+}
+
+/* 15.2.2.4.35 */
+/*
+ *  call-seq:
+ *     mod.class_eval {| | block }  -> obj
+ *     mod.module_eval {| | block } -> obj
+ *
+ *  Evaluates block in the context of _mod_. This can
+ *  be used to add methods to a class. <code>module_eval</code> returns
+ *  the result of evaluating its argument.
+ */
+mrb_value
+mrb_mod_module_eval(mrb_state *mrb, mrb_value mod)
+{
+  mrb_value a, b;
+
+  if (mrb_get_args(mrb, "|S&", &a, &b) == 1) {
+    mrb_raise(mrb, E_NOTIMP_ERROR, "module_eval/class_eval with string not implemented");
+  }
+  return eval_under(mrb, mod, b, mrb_class_ptr(mod));
+}
+
+/* 15.3.1.3.18 */
+/*
+ *  call-seq:
+ *     obj.instance_eval {| | block }                       -> obj
+ *
+ *  Evaluates the given block,within  the context of the receiver (_obj_).
+ *  In order to set the context, the variable +self+ is set to _obj_ while
+ *  the code is executing, giving the code access to _obj_'s
+ *  instance variables. In the version of <code>instance_eval</code>
+ *  that takes a +String+, the optional second and third
+ *  parameters supply a filename and starting line number that are used
+ *  when reporting compilation errors.
+ *
+ *     class KlassWithSecret
+ *       def initialize
+ *         @secret = 99
+ *       end
+ *     end
+ *     k = KlassWithSecret.new
+ *     k.instance_eval { @secret }   #=> 99
+ */
+mrb_value
+mrb_obj_instance_eval(mrb_state *mrb, mrb_value self)
+{
+  mrb_value a, b;
+  mrb_value cv;
+  struct RClass *c;
+
+  if (mrb_get_args(mrb, "|S&", &a, &b) == 1) {
+    mrb_raise(mrb, E_NOTIMP_ERROR, "instance_eval with string not implemented");
+  }
+  switch (mrb_type(self)) {
+  case MRB_TT_SYMBOL:
+  case MRB_TT_FIXNUM:
+  case MRB_TT_FLOAT:
+    c = 0;
+    break;
+  default:
+    cv = mrb_singleton_class(mrb, self);
+    c = mrb_class_ptr(cv);
+    break;
+  }
+  return eval_under(mrb, self, b, c);
+}
+
+MRB_API mrb_value
+mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv, mrb_value self, struct RClass *c)
+{
+  struct RProc *p;
+  mrb_sym mid = mrb->c->ci->mid;
+  mrb_callinfo *ci;
+  int n = mrb->c->ci->nregs;
+  mrb_value val;
+
+  if (mrb_nil_p(b)) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
+  }
+  if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
+    mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
+  }
+  p = mrb_proc_ptr(b);
+  ci = cipush(mrb);
+  ci->mid = mid;
+  ci->proc = p;
+  ci->stackent = mrb->c->stack;
+  ci->argc = argc;
+  ci->target_class = c;
+  ci->acc = CI_ACC_SKIP;
+  mrb->c->stack = mrb->c->stack + n;
+  if (MRB_PROC_CFUNC_P(p)) {
+    ci->nregs = argc + 2;
+    stack_extend(mrb, ci->nregs);
+  }
+  else {
+    ci->nregs = p->body.irep->nregs;
+    stack_extend(mrb, ci->nregs);
+  }
+
+  mrb->c->stack[0] = self;
+  if (argc > 0) {
+    stack_copy(mrb->c->stack+1, argv, argc);
+  }
+  mrb->c->stack[argc+1] = mrb_nil_value();
+
+  if (MRB_PROC_CFUNC_P(p)) {
+    val = p->body.func(mrb, self);
+    mrb->c->stack = mrb->c->ci->stackent;
+  }
+  else {
+    int cioff = mrb->c->ci - mrb->c->cibase;
+    val = mrb_run(mrb, p, self);
+    mrb->c->ci = mrb->c->cibase + cioff;
+  }
+  cipop(mrb);
+  return val;
+}
+
+MRB_API mrb_value
+mrb_yield_argv(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv)
+{
+  struct RProc *p = mrb_proc_ptr(b);
+
+  return mrb_yield_with_class(mrb, b, argc, argv, p->env->stack[0], p->target_class);
+}
+
+MRB_API mrb_value
+mrb_yield(mrb_state *mrb, mrb_value b, mrb_value arg)
+{
+  struct RProc *p = mrb_proc_ptr(b);
+
+  return mrb_yield_with_class(mrb, b, 1, &arg, p->env->stack[0], p->target_class);
+}
+
+mrb_value
+mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const mrb_value *argv)
+{
+  struct RProc *p;
+  mrb_callinfo *ci;
+
+  if (mrb_nil_p(b)) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
+  }
+  if (mrb_type(b) != MRB_TT_PROC) {
+    mrb_raise(mrb, E_TYPE_ERROR, "not a block");
+  }
+
+  p = mrb_proc_ptr(b);
+  ci = mrb->c->ci;
+
+  stack_extend(mrb, 3);
+  mrb->c->stack[1] = mrb_ary_new_from_values(mrb, argc, argv);
+  mrb->c->stack[2] = mrb_nil_value();
+  ci->argc = -1;
+  return mrb_exec_irep(mrb, self, p);
+}
+
+static struct RBreak*
+break_new(mrb_state *mrb, struct RProc *p, mrb_value val)
+{
+  struct RBreak *brk;
+
+  brk = (struct RBreak*)mrb_obj_alloc(mrb, MRB_TT_BREAK, NULL);
+  brk->iv = NULL;
+  brk->proc = p;
+  brk->val = val;
+
+  return brk;
+}
+
+typedef enum {
+  LOCALJUMP_ERROR_RETURN = 0,
+  LOCALJUMP_ERROR_BREAK = 1,
+  LOCALJUMP_ERROR_YIELD = 2
+} localjump_error_kind;
+
+static void
+localjump_error(mrb_state *mrb, localjump_error_kind kind)
+{
+  char kind_str[3][7] = { "return", "break", "yield" };
+  char kind_str_len[] = { 6, 5, 5 };
+  static const char lead[] = "unexpected ";
+  mrb_value msg;
+  mrb_value exc;
+
+  msg = mrb_str_buf_new(mrb, sizeof(lead) + 7);
+  mrb_str_cat(mrb, msg, lead, sizeof(lead) - 1);
+  mrb_str_cat(mrb, msg, kind_str[kind], kind_str_len[kind]);
+  exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg);
+  mrb_exc_set(mrb, exc);
+}
+
+static void
+argnum_error(mrb_state *mrb, mrb_int num)
+{
+  mrb_value exc;
+  mrb_value str;
+  mrb_int argc = mrb->c->ci->argc;
+
+  if (argc < 0) {
+    mrb_value args = mrb->c->stack[1];
+    if (mrb_array_p(args)) {
+      argc = RARRAY_LEN(args);
+    }
+  }
+  if (mrb->c->ci->mid) {
+    str = mrb_format(mrb, "'%S': wrong number of arguments (%S for %S)",
+                  mrb_sym2str(mrb, mrb->c->ci->mid),
+                  mrb_fixnum_value(argc), mrb_fixnum_value(num));
+  }
+  else {
+    str = mrb_format(mrb, "wrong number of arguments (%S for %S)",
+                     mrb_fixnum_value(argc), mrb_fixnum_value(num));
+  }
+  exc = mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str);
+  mrb_exc_set(mrb, exc);
+}
+
+#define ERR_PC_SET(mrb, pc) mrb->c->ci->err = pc;
+#define ERR_PC_CLR(mrb)     mrb->c->ci->err = 0;
+#ifdef MRB_ENABLE_DEBUG_HOOK
+#define CODE_FETCH_HOOK(mrb, irep, pc, regs) if ((mrb)->code_fetch_hook) (mrb)->code_fetch_hook((mrb), (irep), (pc), (regs));
+#else
+#define CODE_FETCH_HOOK(mrb, irep, pc, regs)
+#endif
+
+#ifdef MRB_BYTECODE_DECODE_OPTION
+#define BYTECODE_DECODER(x) ((mrb)->bytecode_decoder)?(mrb)->bytecode_decoder((mrb), (x)):(x)
+#else
+#define BYTECODE_DECODER(x) (x)
+#endif
+
+
+#if defined __GNUC__ || defined __clang__ || defined __INTEL_COMPILER
+#define DIRECT_THREADED
+#endif
+
+#ifndef DIRECT_THREADED
+
+#define INIT_DISPATCH for (;;) { i = BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (GET_OPCODE(i)) {
+#define CASE(op) case op:
+#define NEXT pc++; break
+#define JUMP break
+#define END_DISPATCH }}
+
+#else
+
+#define INIT_DISPATCH JUMP; return mrb_nil_value();
+#define CASE(op) L_ ## op:
+#define NEXT i=BYTECODE_DECODER(*++pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)]
+#define JUMP i=BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)]
+
+#define END_DISPATCH
+
+#endif
+
+MRB_API mrb_value
+mrb_vm_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep)
+{
+  mrb_irep *irep = proc->body.irep;
+  mrb_value result;
+  struct mrb_context *c = mrb->c;
+  int cioff = c->ci - c->cibase;
+  unsigned int nregs = irep->nregs;
+
+  if (!c->stack) {
+    stack_init(mrb);
+  }
+  if (stack_keep > nregs)
+    nregs = stack_keep;
+  stack_extend(mrb, nregs);
+  stack_clear(c->stack + stack_keep, nregs - stack_keep);
+  c->stack[0] = self;
+  result = mrb_vm_exec(mrb, proc, irep->iseq);
+  if (c->ci - c->cibase > cioff) {
+    c->ci = c->cibase + cioff;
+  }
+  if (mrb->c != c) {
+    if (mrb->c->fib) {
+      mrb_write_barrier(mrb, (struct RBasic*)mrb->c->fib);
+    }
+    mrb->c = c;
+  }
+  return result;
+}
+
+MRB_API mrb_value
+mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc)
+{
+  /* mrb_assert(mrb_proc_cfunc_p(proc)) */
+  mrb_irep *irep = proc->body.irep;
+  mrb_value *pool = irep->pool;
+  mrb_sym *syms = irep->syms;
+  mrb_code i;
+  int ai = mrb_gc_arena_save(mrb);
+  struct mrb_jmpbuf *prev_jmp = mrb->jmp;
+  struct mrb_jmpbuf c_jmp;
+
+#ifdef DIRECT_THREADED
+  static void *optable[] = {
+    &&L_OP_NOP, &&L_OP_MOVE,
+    &&L_OP_LOADL, &&L_OP_LOADI, &&L_OP_LOADSYM, &&L_OP_LOADNIL,
+    &&L_OP_LOADSELF, &&L_OP_LOADT, &&L_OP_LOADF,
+    &&L_OP_GETGLOBAL, &&L_OP_SETGLOBAL, &&L_OP_GETSPECIAL, &&L_OP_SETSPECIAL,
+    &&L_OP_GETIV, &&L_OP_SETIV, &&L_OP_GETCV, &&L_OP_SETCV,
+    &&L_OP_GETCONST, &&L_OP_SETCONST, &&L_OP_GETMCNST, &&L_OP_SETMCNST,
+    &&L_OP_GETUPVAR, &&L_OP_SETUPVAR,
+    &&L_OP_JMP, &&L_OP_JMPIF, &&L_OP_JMPNOT,
+    &&L_OP_ONERR, &&L_OP_RESCUE, &&L_OP_POPERR, &&L_OP_RAISE, &&L_OP_EPUSH, &&L_OP_EPOP,
+    &&L_OP_SEND, &&L_OP_SENDB, &&L_OP_FSEND,
+    &&L_OP_CALL, &&L_OP_SUPER, &&L_OP_ARGARY, &&L_OP_ENTER,
+    &&L_OP_KARG, &&L_OP_KDICT, &&L_OP_RETURN, &&L_OP_TAILCALL, &&L_OP_BLKPUSH,
+    &&L_OP_ADD, &&L_OP_ADDI, &&L_OP_SUB, &&L_OP_SUBI, &&L_OP_MUL, &&L_OP_DIV,
+    &&L_OP_EQ, &&L_OP_LT, &&L_OP_LE, &&L_OP_GT, &&L_OP_GE,
+    &&L_OP_ARRAY, &&L_OP_ARYCAT, &&L_OP_ARYPUSH, &&L_OP_AREF, &&L_OP_ASET, &&L_OP_APOST,
+    &&L_OP_STRING, &&L_OP_STRCAT, &&L_OP_HASH,
+    &&L_OP_LAMBDA, &&L_OP_RANGE, &&L_OP_OCLASS,
+    &&L_OP_CLASS, &&L_OP_MODULE, &&L_OP_EXEC,
+    &&L_OP_METHOD, &&L_OP_SCLASS, &&L_OP_TCLASS,
+    &&L_OP_DEBUG, &&L_OP_STOP, &&L_OP_ERR,
+  };
+#endif
+
+  mrb_bool exc_catched = FALSE;
+RETRY_TRY_BLOCK:
+
+  MRB_TRY(&c_jmp) {
+
+  if (exc_catched) {
+    exc_catched = FALSE;
+    if (mrb->exc && mrb->exc->tt == MRB_TT_BREAK)
+      goto L_BREAK;
+    goto L_RAISE;
+  }
+  mrb->jmp = &c_jmp;
+  mrb->c->ci->proc = proc;
+  mrb->c->ci->nregs = irep->nregs;
+
+#define regs (mrb->c->stack)
+  INIT_DISPATCH {
+    CASE(OP_NOP) {
+      /* do nothing */
+      NEXT;
+    }
+
+    CASE(OP_MOVE) {
+      /* A B    R(A) := R(B) */
+      int a = GETARG_A(i);
+      int b = GETARG_B(i);
+      regs[a] = regs[b];
+      NEXT;
+    }
+
+    CASE(OP_LOADL) {
+      /* A Bx   R(A) := Pool(Bx) */
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+#ifdef MRB_WORD_BOXING
+      mrb_value val = pool[bx];
+      if (mrb_float_p(val)) {
+        val = mrb_float_value(mrb, mrb_float(val));
+      }
+      regs[a] = val;
+#else
+      regs[a] = pool[bx];
+#endif
+      NEXT;
+    }
+
+    CASE(OP_LOADI) {
+      /* A sBx  R(A) := sBx */
+      SET_INT_VALUE(regs[GETARG_A(i)], GETARG_sBx(i));
+      NEXT;
+    }
+
+    CASE(OP_LOADSYM) {
+      /* A Bx   R(A) := Syms(Bx) */
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      SET_SYM_VALUE(regs[a], syms[bx]);
+      NEXT;
+    }
+
+    CASE(OP_LOADSELF) {
+      /* A      R(A) := self */
+      int a = GETARG_A(i);
+      regs[a] = regs[0];
+      NEXT;
+    }
+
+    CASE(OP_LOADT) {
+      /* A      R(A) := true */
+      int a = GETARG_A(i);
+      SET_TRUE_VALUE(regs[a]);
+      NEXT;
+    }
+
+    CASE(OP_LOADF) {
+      /* A      R(A) := false */
+      int a = GETARG_A(i);
+      SET_FALSE_VALUE(regs[a]);
+      NEXT;
+    }
+
+    CASE(OP_GETGLOBAL) {
+      /* A Bx   R(A) := getglobal(Syms(Bx)) */
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_value val = mrb_gv_get(mrb, syms[bx]);
+      regs[a] = val;
+      NEXT;
+    }
+
+    CASE(OP_SETGLOBAL) {
+      /* A Bx   setglobal(Syms(Bx), R(A)) */
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_gv_set(mrb, syms[bx], regs[a]);
+      NEXT;
+    }
+
+    CASE(OP_GETSPECIAL) {
+      /* A Bx   R(A) := Special[Bx] */
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_value val = mrb_vm_special_get(mrb, bx);
+      regs[a] = val;
+      NEXT;
+    }
+
+    CASE(OP_SETSPECIAL) {
+      /* A Bx   Special[Bx] := R(A) */
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_vm_special_set(mrb, bx, regs[a]);
+      NEXT;
+    }
+
+    CASE(OP_GETIV) {
+      /* A Bx   R(A) := ivget(Bx) */
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_value val = mrb_vm_iv_get(mrb, syms[bx]);
+      regs[a] = val;
+      NEXT;
+    }
+
+    CASE(OP_SETIV) {
+      /* A Bx   ivset(Syms(Bx),R(A)) */
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_vm_iv_set(mrb, syms[bx], regs[a]);
+      NEXT;
+    }
+
+    CASE(OP_GETCV) {
+      /* A Bx   R(A) := cvget(Syms(Bx)) */
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_value val;
+      ERR_PC_SET(mrb, pc);
+      val = mrb_vm_cv_get(mrb, syms[bx]);
+      ERR_PC_CLR(mrb);
+      regs[a] = val;
+      NEXT;
+    }
+
+    CASE(OP_SETCV) {
+      /* A Bx   cvset(Syms(Bx),R(A)) */
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_vm_cv_set(mrb, syms[bx], regs[a]);
+      NEXT;
+    }
+
+    CASE(OP_GETCONST) {
+      /* A Bx    R(A) := constget(Syms(Bx)) */
+      mrb_value val;
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_sym sym = syms[bx];
+
+      ERR_PC_SET(mrb, pc);
+      val = mrb_vm_const_get(mrb, sym);
+      ERR_PC_CLR(mrb);
+      regs[a] = val;
+      NEXT;
+    }
+
+    CASE(OP_SETCONST) {
+      /* A Bx   constset(Syms(Bx),R(A)) */
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_vm_const_set(mrb, syms[bx], regs[a]);
+      NEXT;
+    }
+
+    CASE(OP_GETMCNST) {
+      /* A Bx   R(A) := R(A)::Syms(Bx) */
+      mrb_value val;
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+
+      ERR_PC_SET(mrb, pc);
+      val = mrb_const_get(mrb, regs[a], syms[bx]);
+      ERR_PC_CLR(mrb);
+      regs[a] = val;
+      NEXT;
+    }
+
+    CASE(OP_SETMCNST) {
+      /* A Bx    R(A+1)::Syms(Bx) := R(A) */
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_const_set(mrb, regs[a+1], syms[bx], regs[a]);
+      NEXT;
+    }
+
+    CASE(OP_GETUPVAR) {
+      /* A B C  R(A) := uvget(B,C) */
+      int a = GETARG_A(i);
+      int b = GETARG_B(i);
+      int c = GETARG_C(i);
+      mrb_value *regs_a = regs + a;
+      struct REnv *e = uvenv(mrb, c);
+
+      if (!e) {
+        *regs_a = mrb_nil_value();
+      }
+      else {
+        *regs_a = e->stack[b];
+      }
+      NEXT;
+    }
+
+    CASE(OP_SETUPVAR) {
+      /* A B C  uvset(B,C,R(A)) */
+      int a = GETARG_A(i);
+      int b = GETARG_B(i);
+      int c = GETARG_C(i);
+
+      struct REnv *e = uvenv(mrb, c);
+
+      if (e) {
+        mrb_value *regs_a = regs + a;
+
+        if (b < MRB_ENV_STACK_LEN(e)) {
+          e->stack[b] = *regs_a;
+          mrb_write_barrier(mrb, (struct RBasic*)e);
+        }
+      }
+      NEXT;
+    }
+
+    CASE(OP_JMP) {
+      /* sBx    pc+=sBx */
+      int sbx = GETARG_sBx(i);
+      pc += sbx;
+      JUMP;
+    }
+
+    CASE(OP_JMPIF) {
+      /* A sBx  if R(A) pc+=sBx */
+      int a = GETARG_A(i);
+      int sbx = GETARG_sBx(i);
+      if (mrb_test(regs[a])) {
+        pc += sbx;
+        JUMP;
+      }
+      NEXT;
+    }
+
+    CASE(OP_JMPNOT) {
+      /* A sBx  if !R(A) pc+=sBx */
+      int a = GETARG_A(i);
+      int sbx = GETARG_sBx(i);
+      if (!mrb_test(regs[a])) {
+        pc += sbx;
+        JUMP;
+      }
+      NEXT;
+    }
+
+    CASE(OP_ONERR) {
+      /* sBx    pc+=sBx on exception */
+      int sbx = GETARG_sBx(i);
+      if (mrb->c->rsize <= mrb->c->ci->ridx) {
+        if (mrb->c->rsize == 0) mrb->c->rsize = RESCUE_STACK_INIT_SIZE;
+        else mrb->c->rsize *= 2;
+        mrb->c->rescue = (mrb_code **)mrb_realloc(mrb, mrb->c->rescue, sizeof(mrb_code*) * mrb->c->rsize);
+      }
+      mrb->c->rescue[mrb->c->ci->ridx++] = pc + sbx;
+      NEXT;
+    }
+
+    CASE(OP_RESCUE) {
+      /* A B    R(A) := exc; clear(exc); R(B) := matched (bool) */
+      int a = GETARG_A(i);
+      int b = GETARG_B(i);
+      int c = GETARG_C(i);
+      mrb_value exc;
+
+      if (c == 0) {
+        exc = mrb_obj_value(mrb->exc);
+        mrb->exc = 0;
+      }
+      else {           /* continued; exc taken from R(A) */
+        exc = regs[a];
+      }
+      if (b != 0) {
+        mrb_value e = regs[b];
+        struct RClass *ec;
+
+        switch (mrb_type(e)) {
+        case MRB_TT_CLASS:
+        case MRB_TT_MODULE:
+          break;
+        default:
+          {
+            mrb_value exc;
+
+            exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR,
+                  "class or module required for rescue clause");
+            mrb_exc_set(mrb, exc);
+            goto L_RAISE;
+          }
+        }
+        ec = mrb_class_ptr(e);
+        regs[b] = mrb_bool_value(mrb_obj_is_kind_of(mrb, exc, ec));
+      }
+      if (a != 0 && c == 0) {
+        regs[a] = exc;
+      }
+      NEXT;
+    }
+
+    CASE(OP_POPERR) {
+      /* A      A.times{rescue_pop()} */
+      int a = GETARG_A(i);
+
+      while (a--) {
+        mrb->c->ci->ridx--;
+      }
+      NEXT;
+    }
+
+    CASE(OP_RAISE) {
+      /* A      raise(R(A)) */
+      int a = GETARG_A(i);
+
+      mrb_exc_set(mrb, regs[a]);
+      goto L_RAISE;
+    }
+
+    CASE(OP_EPUSH) {
+      /* Bx     ensure_push(SEQ[Bx]) */
+      int bx = GETARG_Bx(i);
+      struct RProc *p;
+
+      p = mrb_closure_new(mrb, irep->reps[bx]);
+      /* push ensure_stack */
+      if (mrb->c->esize <= mrb->c->eidx+1) {
+        if (mrb->c->esize == 0) mrb->c->esize = ENSURE_STACK_INIT_SIZE;
+        else mrb->c->esize *= 2;
+        mrb->c->ensure = (struct RProc **)mrb_realloc(mrb, mrb->c->ensure, sizeof(struct RProc*) * mrb->c->esize);
+      }
+      mrb->c->ensure[mrb->c->eidx++] = p;
+      mrb->c->ensure[mrb->c->eidx] = NULL;
+      ARENA_RESTORE(mrb, ai);
+      NEXT;
+    }
+
+    CASE(OP_EPOP) {
+      /* A      A.times{ensure_pop().call} */
+      int a = GETARG_A(i);
+      mrb_callinfo *ci = mrb->c->ci;
+      int n, epos = ci->epos;
+
+      for (n=0; n<a && mrb->c->eidx > epos; n++) {
+        ecall(mrb, --mrb->c->eidx);
+        ARENA_RESTORE(mrb, ai);
+      }
+      NEXT;
+    }
+
+    CASE(OP_LOADNIL) {
+      /* A     R(A) := nil */
+      int a = GETARG_A(i);
+
+      SET_NIL_VALUE(regs[a]);
+      NEXT;
+    }
+
+    CASE(OP_SENDB) {
+      /* A B C  R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C),&R(A+C+1))*/
+      /* fall through */
+    };
+
+  L_SEND:
+    CASE(OP_SEND) {
+      /* A B C  R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C)) */
+      int a = GETARG_A(i);
+      int n = GETARG_C(i);
+      struct RProc *m;
+      struct RClass *c;
+      mrb_callinfo *ci = mrb->c->ci;
+      mrb_value recv, result;
+      mrb_sym mid = syms[GETARG_B(i)];
+      int bidx;
+      mrb_value blk;
+
+      recv = regs[a];
+      if (n == CALL_MAXARGS) {
+        bidx = a+2;
+      }
+      else {
+        bidx = a+n+1;
+      }
+      if (GET_OPCODE(i) != OP_SENDB) {
+        if (bidx >= ci->nregs) {
+          stack_extend(mrb, bidx+1);
+          ci->nregs = bidx+1;
+        }
+        SET_NIL_VALUE(regs[bidx]);
+        blk = mrb_nil_value();
+      }
+      else {
+        blk = regs[bidx];
+        if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) {
+          if (bidx >= ci->nregs) {
+            stack_extend(mrb, bidx+1);
+            ci->nregs = bidx+1;
+          }
+          result = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc");
+          blk = regs[bidx] = result;
+        }
+      }
+      c = mrb_class(mrb, recv);
+      m = mrb_method_search_vm(mrb, &c, mid);
+      if (!m) {
+        mrb_value sym = mrb_symbol_value(mid);
+        mrb_sym missing = mrb_intern_lit(mrb, "method_missing");
+
+        m = mrb_method_search_vm(mrb, &c, missing);
+        if (!m) {
+          mrb_value args;
+
+          if (n == CALL_MAXARGS) {
+            args = regs[a+1];
+          }
+          else {
+            args = mrb_ary_new_from_values(mrb, n, regs+a+1);
+          }
+          ERR_PC_SET(mrb, pc);
+          mrb_method_missing(mrb, mid, recv, args);
+        }
+        mid = missing;
+        if (n != CALL_MAXARGS) {
+          if (a+2 >= irep->nregs) {
+            stack_extend(mrb, a+3);
+          }
+          regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1);
+          regs[a+2] = blk;
+          n = CALL_MAXARGS;
+        }
+        mrb_ary_unshift(mrb, regs[a+1], sym);
+      }
+
+      /* push callinfo */
+      ci = cipush(mrb);
+      ci->mid = mid;
+      ci->proc = m;
+      ci->stackent = mrb->c->stack;
+      ci->target_class = c;
+
+      ci->pc = pc + 1;
+      ci->acc = a;
+
+      /* prepare stack */
+      mrb->c->stack += a;
+
+      if (MRB_PROC_CFUNC_P(m)) {
+        if (n == CALL_MAXARGS) {
+          ci->argc = -1;
+          ci->nregs = 3;
+        }
+        else {
+          ci->argc = n;
+          ci->nregs = n + 2;
+        }
+        result = m->body.func(mrb, recv);
+        mrb_gc_arena_restore(mrb, ai);
+        if (mrb->exc) goto L_RAISE;
+        ci = mrb->c->ci;
+        if (GET_OPCODE(i) == OP_SENDB) {
+          if (mrb_type(blk) == MRB_TT_PROC) {
+            struct RProc *p = mrb_proc_ptr(blk);
+
+            if (p && !MRB_PROC_STRICT_P(p) && p->env == ci[-1].env) {
+              p->flags |= MRB_PROC_ORPHAN;
+            }
+          }
+        }
+        if (!ci->target_class) { /* return from context modifying method (resume/yield) */
+          if (ci->acc == CI_ACC_RESUMED) {
+            mrb->jmp = prev_jmp;
+            return result;
+          }
+          else {
+            mrb_assert(!MRB_PROC_CFUNC_P(ci[-1].proc));
+            proc = ci[-1].proc;
+            irep = proc->body.irep;
+            pool = irep->pool;
+            syms = irep->syms;
+          }
+        }
+        mrb->c->stack[0] = result;
+        /* pop stackpos */
+        mrb->c->stack = ci->stackent;
+        pc = ci->pc;
+        cipop(mrb);
+        JUMP;
+      }
+      else {
+        /* setup environment for calling method */
+        proc = mrb->c->ci->proc = m;
+        irep = m->body.irep;
+        pool = irep->pool;
+        syms = irep->syms;
+        ci->nregs = irep->nregs;
+        if (n == CALL_MAXARGS) {
+          ci->argc = -1;
+          stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs);
+        }
+        else {
+          ci->argc = n;
+          stack_extend(mrb, irep->nregs);
+        }
+        pc = irep->iseq;
+        JUMP;
+      }
+    }
+
+    CASE(OP_FSEND) {
+      /* A B C  R(A) := fcall(R(A),Syms(B),R(A+1),... ,R(A+C-1)) */
+      /* not implemented yet */
+      NEXT;
+    }
+
+    CASE(OP_CALL) {
+      /* A      R(A) := self.call(frame.argc, frame.argv) */
+      mrb_callinfo *ci;
+      mrb_value recv = mrb->c->stack[0];
+      struct RProc *m = mrb_proc_ptr(recv);
+
+      /* replace callinfo */
+      ci = mrb->c->ci;
+      ci->target_class = m->target_class;
+      ci->proc = m;
+      if (m->env) {
+        mrb_sym mid;
+
+        if (MRB_ENV_STACK_SHARED_P(m->env)) {
+          mid = m->env->cxt.c->cibase[m->env->cioff].mid;
+        }
+        else {
+          mid = m->env->cxt.mid;
+        }
+        if (mid) ci->mid = mid;
+        if (!m->env->stack) {
+          m->env->stack = mrb->c->stack;
+        }
+      }
+
+      /* prepare stack */
+      if (MRB_PROC_CFUNC_P(m)) {
+        recv = m->body.func(mrb, recv);
+        mrb_gc_arena_restore(mrb, ai);
+        if (mrb->exc) goto L_RAISE;
+        /* pop stackpos */
+        ci = mrb->c->ci;
+        mrb->c->stack = ci->stackent;
+        regs[ci->acc] = recv;
+        pc = ci->pc;
+        cipop(mrb);
+        irep = mrb->c->ci->proc->body.irep;
+        pool = irep->pool;
+        syms = irep->syms;
+        JUMP;
+      }
+      else {
+        /* setup environment for calling method */
+        proc = m;
+        irep = m->body.irep;
+        if (!irep) {
+          mrb->c->stack[0] = mrb_nil_value();
+          goto L_RETURN;
+        }
+        pool = irep->pool;
+        syms = irep->syms;
+        ci->nregs = irep->nregs;
+        stack_extend(mrb, irep->nregs);
+        if (ci->argc < 0) {
+          if (irep->nregs > 3) {
+            stack_clear(regs+3, irep->nregs-3);
+          }
+        }
+        else if (ci->argc+2 < irep->nregs) {
+          stack_clear(regs+ci->argc+2, irep->nregs-ci->argc-2);
+        }
+        if (m->env) {
+          regs[0] = m->env->stack[0];
+        }
+        pc = irep->iseq;
+        JUMP;
+      }
+    }
+
+    CASE(OP_SUPER) {
+      /* A C  R(A) := super(R(A+1),... ,R(A+C+1)) */
+      mrb_value recv;
+      mrb_callinfo *ci = mrb->c->ci;
+      struct RProc *m;
+      struct RClass *c;
+      mrb_sym mid = ci->mid;
+      int a = GETARG_A(i);
+      int n = GETARG_C(i);
+      mrb_value blk;
+      int bidx;
+
+      if (mid == 0 || !ci->target_class) {
+        mrb_value exc;
+
+        exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method");
+        mrb_exc_set(mrb, exc);
+        goto L_RAISE;
+      }
+      recv = regs[0];
+      c = mrb->c->ci->target_class->super;
+      m = mrb_method_search_vm(mrb, &c, mid);
+      if (!m) {
+        mrb_sym missing = mrb_intern_lit(mrb, "method_missing");
+        m = mrb_method_search_vm(mrb, &c, missing);
+        if (!m) {
+          mrb_value args;
+
+          if (n == CALL_MAXARGS) {
+            args = regs[a+1];
+          }
+          else {
+            args = mrb_ary_new_from_values(mrb, n, regs+a+1);
+          }
+          ERR_PC_SET(mrb, pc);
+          mrb_method_missing(mrb, mid, recv, args);
+        }
+        mid = missing;
+        if (n == CALL_MAXARGS-1) {
+          regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1);
+          n++;
+        }
+        if (n == CALL_MAXARGS) {
+          mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid));
+        }
+        else {
+          value_move(regs+a+2, regs+a+1, ++n);
+          SET_SYM_VALUE(regs[a+1], ci->mid);
+        }
+      }
+
+      if (n == CALL_MAXARGS) {
+        bidx = a+2;
+      }
+      else {
+        bidx = a+n+1;
+      }
+      blk = regs[bidx];
+      if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) {
+        mrb_value result;
+
+        if (bidx >= ci->nregs) {
+          stack_extend(mrb, bidx+1);
+          ci->nregs = bidx+1;
+        }
+        result = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc");
+        regs[bidx] = result;
+      }
+
+      /* push callinfo */
+      ci = cipush(mrb);
+      ci->mid = mid;
+      ci->proc = m;
+      ci->stackent = mrb->c->stack;
+      ci->target_class = c;
+      ci->pc = pc + 1;
+      if (n == CALL_MAXARGS) {
+        ci->argc = -1;
+      }
+      else {
+        ci->argc = n;
+      }
+
+      /* prepare stack */
+      mrb->c->stack += a;
+      mrb->c->stack[0] = recv;
+
+      if (MRB_PROC_CFUNC_P(m)) {
+        mrb_value v;
+
+        if (n == CALL_MAXARGS) {
+          ci->nregs = 3;
+        }
+        else {
+          ci->nregs = n + 2;
+        }
+        v = m->body.func(mrb, recv);
+        mrb_gc_arena_restore(mrb, ai);
+        if (mrb->exc) goto L_RAISE;
+        ci = mrb->c->ci;
+        if (!ci->target_class) { /* return from context modifying method (resume/yield) */
+          if (ci->acc == CI_ACC_RESUMED) {
+            mrb->jmp = prev_jmp;
+            return v;
+          }
+          else {
+            mrb_assert(!MRB_PROC_CFUNC_P(ci[-1].proc));
+            proc = ci[-1].proc;
+            irep = proc->body.irep;
+            pool = irep->pool;
+            syms = irep->syms;
+          }
+        }
+        mrb->c->stack[0] = v;
+        /* pop stackpos */
+        mrb->c->stack = ci->stackent;
+        pc = ci->pc;
+        cipop(mrb);
+        JUMP;
+      }
+      else {
+        /* fill callinfo */
+        ci->acc = a;
+
+        /* setup environment for calling method */
+        ci->proc = m;
+        irep = m->body.irep;
+        pool = irep->pool;
+        syms = irep->syms;
+        ci->nregs = irep->nregs;
+        if (n == CALL_MAXARGS) {
+          stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs);
+        }
+        else {
+          stack_extend(mrb, irep->nregs);
+        }
+        pc = irep->iseq;
+        JUMP;
+      }
+    }
+
+    CASE(OP_ARGARY) {
+      /* A Bx   R(A) := argument array (16=6:1:5:4) */
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      int m1 = (bx>>10)&0x3f;
+      int r  = (bx>>9)&0x1;
+      int m2 = (bx>>4)&0x1f;
+      int lv = (bx>>0)&0xf;
+      mrb_value *stack;
+
+      if (mrb->c->ci->mid == 0 || mrb->c->ci->target_class == NULL) {
+        mrb_value exc;
+
+      L_NOSUPER:
+        exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method");
+        mrb_exc_set(mrb, exc);
+        goto L_RAISE;
+      }
+      if (lv == 0) stack = regs + 1;
+      else {
+        struct REnv *e = uvenv(mrb, lv-1);
+        if (!e) goto L_NOSUPER;
+        stack = e->stack + 1;
+      }
+      if (r == 0) {
+        regs[a] = mrb_ary_new_from_values(mrb, m1+m2, stack);
+      }
+      else {
+        mrb_value *pp = NULL;
+        struct RArray *rest;
+        int len = 0;
+
+        if (mrb_array_p(stack[m1])) {
+          struct RArray *ary = mrb_ary_ptr(stack[m1]);
+
+          pp = ary->ptr;
+          len = ary->len;
+        }
+        regs[a] = mrb_ary_new_capa(mrb, m1+len+m2);
+        rest = mrb_ary_ptr(regs[a]);
+        if (m1 > 0) {
+          stack_copy(rest->ptr, stack, m1);
+        }
+        if (len > 0) {
+          stack_copy(rest->ptr+m1, pp, len);
+        }
+        if (m2 > 0) {
+          stack_copy(rest->ptr+m1+len, stack+m1+1, m2);
+        }
+        rest->len = m1+len+m2;
+      }
+      regs[a+1] = stack[m1+r+m2];
+      ARENA_RESTORE(mrb, ai);
+      NEXT;
+    }
+
+    CASE(OP_ENTER) {
+      /* Ax             arg setup according to flags (23=5:5:1:5:5:1:1) */
+      /* number of optional arguments times OP_JMP should follow */
+      mrb_aspec ax = GETARG_Ax(i);
+      int m1 = MRB_ASPEC_REQ(ax);
+      int o  = MRB_ASPEC_OPT(ax);
+      int r  = MRB_ASPEC_REST(ax);
+      int m2 = MRB_ASPEC_POST(ax);
+      /* unused
+      int k  = MRB_ASPEC_KEY(ax);
+      int kd = MRB_ASPEC_KDICT(ax);
+      int b  = MRB_ASPEC_BLOCK(ax);
+      */
+      int argc = mrb->c->ci->argc;
+      mrb_value *argv = regs+1;
+      mrb_value *argv0 = argv;
+      int len = m1 + o + r + m2;
+      mrb_value *blk = &argv[argc < 0 ? 1 : argc];
+
+      if (argc < 0) {
+        struct RArray *ary = mrb_ary_ptr(regs[1]);
+        argv = ary->ptr;
+        argc = ary->len;
+        mrb_gc_protect(mrb, regs[1]);
+      }
+      if (mrb->c->ci->proc && MRB_PROC_STRICT_P(mrb->c->ci->proc)) {
+        if (argc >= 0) {
+          if (argc < m1 + m2 || (r == 0 && argc > len)) {
+            argnum_error(mrb, m1+m2);
+            goto L_RAISE;
+          }
+        }
+      }
+      else if (len > 1 && argc == 1 && mrb_array_p(argv[0])) {
+        mrb_gc_protect(mrb, argv[0]);
+        argc = mrb_ary_ptr(argv[0])->len;
+        argv = mrb_ary_ptr(argv[0])->ptr;
+      }
+      if (argc < len) {
+        int mlen = m2;
+        if (argc < m1+m2) {
+          if (m1 < argc)
+            mlen = argc - m1;
+          else
+            mlen = 0;
+        }
+        regs[len+1] = *blk; /* move block */
+        SET_NIL_VALUE(regs[argc+1]);
+        if (argv0 != argv) {
+          value_move(&regs[1], argv, argc-mlen); /* m1 + o */
+        }
+        if (argc < m1) {
+          stack_clear(&regs[argc+1], m1-argc);
+        }
+        if (mlen) {
+          value_move(&regs[len-m2+1], &argv[argc-mlen], mlen);
+        }
+        if (mlen < m2) {
+          stack_clear(&regs[len-m2+mlen+1], m2-mlen);
+        }
+        if (r) {
+          regs[m1+o+1] = mrb_ary_new_capa(mrb, 0);
+        }
+        if (o == 0 || argc < m1+m2) pc++;
+        else
+          pc += argc - m1 - m2 + 1;
+      }
+      else {
+        int rnum = 0;
+        if (argv0 != argv) {
+          regs[len+1] = *blk; /* move block */
+          value_move(&regs[1], argv, m1+o);
+        }
+        if (r) {
+          rnum = argc-m1-o-m2;
+          regs[m1+o+1] = mrb_ary_new_from_values(mrb, rnum, argv+m1+o);
+        }
+        if (m2) {
+          if (argc-m2 > m1) {
+            value_move(&regs[m1+o+r+1], &argv[m1+o+rnum], m2);
+          }
+        }
+        if (argv0 == argv) {
+          regs[len+1] = *blk; /* move block */
+        }
+        pc += o + 1;
+      }
+      mrb->c->ci->argc = len;
+      /* clear local (but non-argument) variables */
+      if (irep->nlocals-len-2 > 0) {
+        stack_clear(&regs[len+2], irep->nlocals-len-2);
+      }
+      JUMP;
+    }
+
+    CASE(OP_KARG) {
+      /* A B C          R(A) := kdict[Syms(B)]; if C kdict.rm(Syms(B)) */
+      /* if C == 2; raise unless kdict.empty? */
+      /* OP_JMP should follow to skip init code */
+      NEXT;
+    }
+
+    CASE(OP_KDICT) {
+      /* A C            R(A) := kdict */
+      NEXT;
+    }
+
+    L_RETURN:
+      i = MKOP_AB(OP_RETURN, GETARG_A(i), OP_R_NORMAL);
+      /* fall through */
+    CASE(OP_RETURN) {
+      /* A B     return R(A) (B=normal,in-block return/break) */
+      mrb_callinfo *ci;
+
+      ci = mrb->c->ci;
+      if (ci->mid) {
+        mrb_value blk;
+
+        if (ci->argc < 0) {
+          blk = regs[2];
+        }
+        else {
+          blk = regs[ci->argc+1];
+        }
+        if (mrb_type(blk) == MRB_TT_PROC) {
+          struct RProc *p = mrb_proc_ptr(blk);
+
+          if (!MRB_PROC_STRICT_P(proc) &&
+              ci > mrb->c->cibase && p->env == ci[-1].env) {
+            p->flags |= MRB_PROC_ORPHAN;
+          }
+        }
+      }
+
+      if (mrb->exc) {
+        mrb_callinfo *ci0;
+        mrb_value *stk;
+
+      L_RAISE:
+        ci0 = ci = mrb->c->ci;
+        if (ci == mrb->c->cibase) {
+          if (ci->ridx == 0) goto L_FTOP;
+          goto L_RESCUE;
+        }
+        stk = mrb->c->stack;
+        while (ci[0].ridx == ci[-1].ridx) {
+          cipop(mrb);
+          mrb->c->stack = ci->stackent;
+          if (ci->acc == CI_ACC_SKIP && prev_jmp) {
+            mrb->jmp = prev_jmp;
+            MRB_THROW(prev_jmp);
+          }
+          ci = mrb->c->ci;
+          if (ci == mrb->c->cibase) {
+            mrb->c->stack = stk;
+            if (ci->ridx == 0) {
+            L_FTOP:             /* fiber top */
+              if (mrb->c == mrb->root_c) {
+                mrb->c->stack = mrb->c->stbase;
+                goto L_STOP;
+              }
+              else {
+                struct mrb_context *c = mrb->c;
+
+                if (c->fib) {
+                  mrb_write_barrier(mrb, (struct RBasic*)c->fib);
+                }
+                mrb->c = c->prev;
+                c->prev = NULL;
+                goto L_RAISE;
+              }
+            }
+            break;
+          }
+          /* call ensure only when we skip this callinfo */
+          if (ci[0].ridx == ci[-1].ridx) {
+            while (mrb->c->eidx > ci->epos) {
+              ecall(mrb, --mrb->c->eidx);
+              ci = mrb->c->ci;
+            }
+          }
+        }
+      L_RESCUE:
+        if (ci->ridx == 0) goto L_STOP;
+        proc = ci->proc;
+        irep = proc->body.irep;
+        pool = irep->pool;
+        syms = irep->syms;
+        if (ci != ci0) {
+          mrb->c->stack = ci[1].stackent;
+        }
+        stack_extend(mrb, irep->nregs);
+        pc = mrb->c->rescue[--ci->ridx];
+      }
+      else {
+        int acc;
+        mrb_value v;
+
+        v = regs[GETARG_A(i)];
+        mrb_gc_protect(mrb, v);
+        switch (GETARG_B(i)) {
+        case OP_R_RETURN:
+          /* Fall through to OP_R_NORMAL otherwise */
+          if (ci->acc >=0 && proc->env && !MRB_PROC_STRICT_P(proc)) {
+            struct REnv *e = top_env(mrb, proc);
+            mrb_callinfo *ce;
+
+            if (!MRB_ENV_STACK_SHARED_P(e) || e->cxt.c != mrb->c) {
+              localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
+              goto L_RAISE;
+            }
+            
+            ce = mrb->c->cibase + e->cioff;
+            while (ci >= ce) {
+              if (ci->env) {
+                mrb_env_unshare(mrb, ci->env);
+              }
+              if (ci->acc < 0) {
+                localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
+                goto L_RAISE;
+              }
+              ci--;
+            }
+            if (ce == mrb->c->cibase) {
+              localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
+              goto L_RAISE;
+            }
+            mrb->c->stack = mrb->c->ci->stackent;
+            mrb->c->ci = ce;
+            break;
+          }
+        case OP_R_NORMAL:
+        NORMAL_RETURN:
+          if (ci == mrb->c->cibase) {
+            if (!mrb->c->prev) { /* toplevel return */
+              localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
+              goto L_RAISE;
+            }
+            if (mrb->c->prev->ci == mrb->c->prev->cibase) {
+              mrb_value exc = mrb_exc_new_str_lit(mrb, E_FIBER_ERROR, "double resume");
+              mrb_exc_set(mrb, exc);
+              goto L_RAISE;
+            }
+            while (mrb->c->eidx > 0) {
+              ecall(mrb, --mrb->c->eidx);
+            }
+            /* automatic yield at the end */
+            mrb->c->status = MRB_FIBER_TERMINATED;
+            mrb->c = mrb->c->prev;
+            mrb->c->status = MRB_FIBER_RUNNING;
+          }
+          ci = mrb->c->ci;
+          break;
+        case OP_R_BREAK:
+          if (MRB_PROC_STRICT_P(proc)) goto NORMAL_RETURN;
+          if (MRB_PROC_ORPHAN_P(proc)) { 
+            mrb_value exc;
+
+          L_BREAK_ERROR:
+            exc = mrb_exc_new_str_lit(mrb, E_LOCALJUMP_ERROR,
+                                      "break from proc-closure");
+            mrb_exc_set(mrb, exc);
+            goto L_RAISE;
+          }
+          if (!proc->env || !MRB_ENV_STACK_SHARED_P(proc->env)) {
+            goto L_BREAK_ERROR;
+          }
+          /* break from fiber block */
+          if (mrb->c->ci == mrb->c->cibase && mrb->c->ci->pc) {
+            struct mrb_context *c = mrb->c;
+
+            while (mrb->c->eidx > 0) {
+              ecall(mrb, --mrb->c->eidx);
+            }
+            mrb->c = c->prev;
+            c->prev = NULL;
+            ci = mrb->c->ci;
+          }
+          if (ci->acc < 0) {
+            while (mrb->c->eidx > mrb->c->ci->epos) {
+              ecall(mrb, --mrb->c->eidx);
+            }
+            ARENA_RESTORE(mrb, ai);
+            mrb->c->vmexec = FALSE;
+            mrb->exc = (struct RObject*)break_new(mrb, proc, v);
+            mrb->jmp = prev_jmp;
+            MRB_THROW(prev_jmp);
+          }
+          if (FALSE) {
+          L_BREAK:
+            v = ((struct RBreak*)mrb->exc)->val;
+            proc = ((struct RBreak*)mrb->exc)->proc;
+            mrb->exc = NULL;
+            ci = mrb->c->ci;
+          }
+          mrb->c->stack = ci->stackent;
+          mrb->c->ci = mrb->c->cibase + proc->env->cioff + 1;
+          while (ci > mrb->c->ci) {
+            if (ci->env) {
+              mrb_env_unshare(mrb, ci->env);
+            }
+            if (ci[-1].acc == CI_ACC_SKIP) {
+              mrb->c->ci = ci;
+              goto L_BREAK_ERROR;
+            }
+            ci--;
+          }
+          break;
+        default:
+          /* cannot happen */
+          break;
+        }
+        while (mrb->c->eidx > mrb->c->ci->epos) {
+          ecall(mrb, --mrb->c->eidx);
+        }
+        if (mrb->c->vmexec && !mrb->c->ci->target_class) {
+          ARENA_RESTORE(mrb, ai);
+          mrb->c->vmexec = FALSE;
+          mrb->jmp = prev_jmp;
+          return v;
+        }
+        ci = mrb->c->ci;
+        acc = ci->acc;
+        mrb->c->stack = ci->stackent;
+        cipop(mrb);
+        if (acc == CI_ACC_SKIP || acc == CI_ACC_DIRECT) {
+          ARENA_RESTORE(mrb, ai);
+          mrb->jmp = prev_jmp;
+          return v;
+        }
+        pc = ci->pc;
+        DEBUG(fprintf(stderr, "from :%s\n", mrb_sym2name(mrb, ci->mid)));
+        proc = mrb->c->ci->proc;
+        irep = proc->body.irep;
+        pool = irep->pool;
+        syms = irep->syms;
+
+        regs[acc] = v;
+        ARENA_RESTORE(mrb, ai);
+      }
+      JUMP;
+    }
+
+    CASE(OP_TAILCALL) {
+      /* A B C  return call(R(A),Syms(B),R(A+1),... ,R(A+C+1)) */
+      int a = GETARG_A(i);
+      int n = GETARG_C(i);
+      struct RProc *m;
+      struct RClass *c;
+      mrb_callinfo *ci;
+      mrb_value recv;
+      mrb_sym mid = syms[GETARG_B(i)];
+
+      recv = regs[a];
+      c = mrb_class(mrb, recv);
+      m = mrb_method_search_vm(mrb, &c, mid);
+      if (!m) {
+        mrb_value sym = mrb_symbol_value(mid);
+        mrb_sym missing = mrb_intern_lit(mrb, "method_missing");
+        m = mrb_method_search_vm(mrb, &c, missing);
+        if (!m) {
+          mrb_value args;
+
+          if (n == CALL_MAXARGS) {
+            args = regs[a+1];
+          }
+          else {
+            args = mrb_ary_new_from_values(mrb, n, regs+a+1);
+          }
+          ERR_PC_SET(mrb, pc);
+          mrb_method_missing(mrb, mid, recv, args);
+        }
+        mid = missing;
+        if (n == CALL_MAXARGS) {
+          mrb_ary_unshift(mrb, regs[a+1], sym);
+        }
+        else {
+          value_move(regs+a+2, regs+a+1, ++n);
+          regs[a+1] = sym;
+        }
+      }
+
+      /* replace callinfo */
+      ci = mrb->c->ci;
+      ci->mid = mid;
+      ci->target_class = c;
+      if (n == CALL_MAXARGS) {
+        ci->argc = -1;
+      }
+      else {
+        ci->argc = n;
+      }
+
+      /* move stack */
+      value_move(mrb->c->stack, &regs[a], ci->argc+1);
+
+      if (MRB_PROC_CFUNC_P(m)) {
+        mrb_value v = m->body.func(mrb, recv);
+        mrb->c->stack[0] = v;
+        mrb_gc_arena_restore(mrb, ai);
+        goto L_RETURN;
+      }
+      else {
+        /* setup environment for calling method */
+        irep = m->body.irep;
+        pool = irep->pool;
+        syms = irep->syms;
+        if (ci->argc < 0) {
+          stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs);
+        }
+        else {
+          stack_extend(mrb, irep->nregs);
+        }
+        pc = irep->iseq;
+      }
+      JUMP;
+    }
+
+    CASE(OP_BLKPUSH) {
+      /* A Bx   R(A) := block (16=6:1:5:4) */
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      int m1 = (bx>>10)&0x3f;
+      int r  = (bx>>9)&0x1;
+      int m2 = (bx>>4)&0x1f;
+      int lv = (bx>>0)&0xf;
+      mrb_value *stack;
+
+      if (lv == 0) stack = regs + 1;
+      else {
+        struct REnv *e = uvenv(mrb, lv-1);
+        if (!e || e->cioff == 0 ||
+            (!MRB_ENV_STACK_SHARED_P(e) && e->cxt.mid == 0)) {
+          localjump_error(mrb, LOCALJUMP_ERROR_YIELD);
+          goto L_RAISE;
+        }
+        stack = e->stack + 1;
+      }
+      if (mrb_nil_p(stack[m1+r+m2])) {
+        localjump_error(mrb, LOCALJUMP_ERROR_YIELD);
+        goto L_RAISE;
+      }
+      regs[a] = stack[m1+r+m2];
+      NEXT;
+    }
+
+#define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff))
+#define OP_MATH_BODY(op,v1,v2) do {\
+  v1(regs[a]) = v1(regs[a]) op v2(regs[a+1]);\
+} while(0)
+
+    CASE(OP_ADD) {
+      /* A B C  R(A) := R(A)+R(A+1) (Syms[B]=:+,C=1)*/
+      int a = GETARG_A(i);
+
+      /* need to check if op is overridden */
+      switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
+      case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
+        {
+          mrb_int x, y, z;
+          mrb_value *regs_a = regs + a;
+
+          x = mrb_fixnum(regs_a[0]);
+          y = mrb_fixnum(regs_a[1]);
+          if (mrb_int_add_overflow(x, y, &z)) {
+            SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x + (mrb_float)y);
+            break;
+          }
+          SET_INT_VALUE(regs[a], z);
+        }
+        break;
+      case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
+        {
+          mrb_int x = mrb_fixnum(regs[a]);
+          mrb_float y = mrb_float(regs[a+1]);
+          SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + y);
+        }
+        break;
+      case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
+#ifdef MRB_WORD_BOXING
+        {
+          mrb_float x = mrb_float(regs[a]);
+          mrb_int y = mrb_fixnum(regs[a+1]);
+          SET_FLOAT_VALUE(mrb, regs[a], x + y);
+        }
+#else
+        OP_MATH_BODY(+,mrb_float,mrb_fixnum);
+#endif
+        break;
+      case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
+#ifdef MRB_WORD_BOXING
+        {
+          mrb_float x = mrb_float(regs[a]);
+          mrb_float y = mrb_float(regs[a+1]);
+          SET_FLOAT_VALUE(mrb, regs[a], x + y);
+        }
+#else
+        OP_MATH_BODY(+,mrb_float,mrb_float);
+#endif
+        break;
+      case TYPES2(MRB_TT_STRING,MRB_TT_STRING):
+        regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]);
+        break;
+      default:
+        goto L_SEND;
+      }
+      ARENA_RESTORE(mrb, ai);
+      NEXT;
+    }
+
+    CASE(OP_SUB) {
+      /* A B C  R(A) := R(A)-R(A+1) (Syms[B]=:-,C=1)*/
+      int a = GETARG_A(i);
+
+      /* need to check if op is overridden */
+      switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
+      case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
+        {
+          mrb_int x, y, z;
+
+          x = mrb_fixnum(regs[a]);
+          y = mrb_fixnum(regs[a+1]);
+          if (mrb_int_sub_overflow(x, y, &z)) {
+            SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)y);
+            break;
+          }
+          SET_INT_VALUE(regs[a], z);
+        }
+        break;
+      case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
+        {
+          mrb_int x = mrb_fixnum(regs[a]);
+          mrb_float y = mrb_float(regs[a+1]);
+          SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - y);
+        }
+        break;
+      case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
+#ifdef MRB_WORD_BOXING
+        {
+          mrb_float x = mrb_float(regs[a]);
+          mrb_int y = mrb_fixnum(regs[a+1]);
+          SET_FLOAT_VALUE(mrb, regs[a], x - y);
+        }
+#else
+        OP_MATH_BODY(-,mrb_float,mrb_fixnum);
+#endif
+        break;
+      case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
+#ifdef MRB_WORD_BOXING
+        {
+          mrb_float x = mrb_float(regs[a]);
+          mrb_float y = mrb_float(regs[a+1]);
+          SET_FLOAT_VALUE(mrb, regs[a], x - y);
+        }
+#else
+        OP_MATH_BODY(-,mrb_float,mrb_float);
+#endif
+        break;
+      default:
+        goto L_SEND;
+      }
+      NEXT;
+    }
+
+    CASE(OP_MUL) {
+      /* A B C  R(A) := R(A)*R(A+1) (Syms[B]=:*,C=1)*/
+      int a = GETARG_A(i);
+
+      /* need to check if op is overridden */
+      switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
+      case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
+        {
+          mrb_int x, y, z;
+
+          x = mrb_fixnum(regs[a]);
+          y = mrb_fixnum(regs[a+1]);
+          if (mrb_int_mul_overflow(x, y, &z)) {
+            SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * (mrb_float)y);
+            break;
+          }
+          SET_INT_VALUE(regs[a], z);
+        }
+        break;
+      case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
+        {
+          mrb_int x = mrb_fixnum(regs[a]);
+          mrb_float y = mrb_float(regs[a+1]);
+          SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * y);
+        }
+        break;
+      case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
+#ifdef MRB_WORD_BOXING
+        {
+          mrb_float x = mrb_float(regs[a]);
+          mrb_int y = mrb_fixnum(regs[a+1]);
+          SET_FLOAT_VALUE(mrb, regs[a], x * y);
+        }
+#else
+        OP_MATH_BODY(*,mrb_float,mrb_fixnum);
+#endif
+        break;
+      case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
+#ifdef MRB_WORD_BOXING
+        {
+          mrb_float x = mrb_float(regs[a]);
+          mrb_float y = mrb_float(regs[a+1]);
+          SET_FLOAT_VALUE(mrb, regs[a], x * y);
+        }
+#else
+        OP_MATH_BODY(*,mrb_float,mrb_float);
+#endif
+        break;
+      default:
+        goto L_SEND;
+      }
+      NEXT;
+    }
+
+    CASE(OP_DIV) {
+      /* A B C  R(A) := R(A)/R(A+1) (Syms[B]=:/,C=1)*/
+      int a = GETARG_A(i);
+
+      /* need to check if op is overridden */
+      switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
+      case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
+        {
+          mrb_int x = mrb_fixnum(regs[a]);
+          mrb_int y = mrb_fixnum(regs[a+1]);
+          SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x / (mrb_float)y);
+        }
+        break;
+      case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
+        {
+          mrb_int x = mrb_fixnum(regs[a]);
+          mrb_float y = mrb_float(regs[a+1]);
+          SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x / y);
+        }
+        break;
+      case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
+#ifdef MRB_WORD_BOXING
+        {
+          mrb_float x = mrb_float(regs[a]);
+          mrb_int y = mrb_fixnum(regs[a+1]);
+          SET_FLOAT_VALUE(mrb, regs[a], x / y);
+        }
+#else
+        OP_MATH_BODY(/,mrb_float,mrb_fixnum);
+#endif
+        break;
+      case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
+#ifdef MRB_WORD_BOXING
+        {
+          mrb_float x = mrb_float(regs[a]);
+          mrb_float y = mrb_float(regs[a+1]);
+          SET_FLOAT_VALUE(mrb, regs[a], x / y);
+        }
+#else
+        OP_MATH_BODY(/,mrb_float,mrb_float);
+#endif
+        break;
+      default:
+        goto L_SEND;
+      }
+#ifdef MRB_NAN_BOXING
+      if (isnan(mrb_float(regs[a]))) {
+        mrb_value v = mrb_float_value(mrb, mrb_float(regs[a]));
+        regs[a] = v;
+      }
+#endif
+      NEXT;
+    }
+
+    CASE(OP_ADDI) {
+      /* A B C  R(A) := R(A)+C (Syms[B]=:+)*/
+      int a = GETARG_A(i);
+
+      /* need to check if + is overridden */
+      switch (mrb_type(regs[a])) {
+      case MRB_TT_FIXNUM:
+        {
+          mrb_int x = mrb_fixnum(regs[a]);
+          mrb_int y = GETARG_C(i);
+          mrb_int z;
+
+          if (mrb_int_add_overflow(x, y, &z)) {
+            SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + (mrb_float)y);
+            break;
+          }
+          SET_INT_VALUE(regs[a], z);
+        }
+        break;
+      case MRB_TT_FLOAT:
+#ifdef MRB_WORD_BOXING
+        {
+          mrb_float x = mrb_float(regs[a]);
+          SET_FLOAT_VALUE(mrb, regs[a], x + GETARG_C(i));
+        }
+#else
+        mrb_float(regs[a]) += GETARG_C(i);
+#endif
+        break;
+      default:
+        SET_INT_VALUE(regs[a+1], GETARG_C(i));
+        i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1);
+        goto L_SEND;
+      }
+      NEXT;
+    }
+
+    CASE(OP_SUBI) {
+      /* A B C  R(A) := R(A)-C (Syms[B]=:-)*/
+      int a = GETARG_A(i);
+      mrb_value *regs_a = regs + a;
+
+      /* need to check if + is overridden */
+      switch (mrb_type(regs_a[0])) {
+      case MRB_TT_FIXNUM:
+        {
+          mrb_int x = mrb_fixnum(regs_a[0]);
+          mrb_int y = GETARG_C(i);
+          mrb_int z;
+
+          if (mrb_int_sub_overflow(x, y, &z)) {
+            SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x - (mrb_float)y);
+          }
+          else {
+            SET_INT_VALUE(regs_a[0], z);
+          }
+        }
+        break;
+      case MRB_TT_FLOAT:
+#ifdef MRB_WORD_BOXING
+        {
+          mrb_float x = mrb_float(regs[a]);
+          SET_FLOAT_VALUE(mrb, regs[a], x - GETARG_C(i));
+        }
+#else
+        mrb_float(regs_a[0]) -= GETARG_C(i);
+#endif
+        break;
+      default:
+        SET_INT_VALUE(regs_a[1], GETARG_C(i));
+        i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1);
+        goto L_SEND;
+      }
+      NEXT;
+    }
+
+#define OP_CMP_BODY(op,v1,v2) (v1(regs[a]) op v2(regs[a+1]))
+
+#define OP_CMP(op) do {\
+  int result;\
+  /* need to check if - is overridden */\
+  switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {\
+  case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):\
+    result = OP_CMP_BODY(op,mrb_fixnum,mrb_fixnum);\
+    break;\
+  case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):\
+    result = OP_CMP_BODY(op,mrb_fixnum,mrb_float);\
+    break;\
+  case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):\
+    result = OP_CMP_BODY(op,mrb_float,mrb_fixnum);\
+    break;\
+  case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):\
+    result = OP_CMP_BODY(op,mrb_float,mrb_float);\
+    break;\
+  default:\
+    goto L_SEND;\
+  }\
+  if (result) {\
+    SET_TRUE_VALUE(regs[a]);\
+  }\
+  else {\
+    SET_FALSE_VALUE(regs[a]);\
+  }\
+} while(0)
+
+    CASE(OP_EQ) {
+      /* A B C  R(A) := R(A)==R(A+1) (Syms[B]=:==,C=1)*/
+      int a = GETARG_A(i);
+      if (mrb_obj_eq(mrb, regs[a], regs[a+1])) {
+        SET_TRUE_VALUE(regs[a]);
+      }
+      else {
+        OP_CMP(==);
+      }
+      NEXT;
+    }
+
+    CASE(OP_LT) {
+      /* A B C  R(A) := R(A)<R(A+1) (Syms[B]=:<,C=1)*/
+      int a = GETARG_A(i);
+      OP_CMP(<);
+      NEXT;
+    }
+
+    CASE(OP_LE) {
+      /* A B C  R(A) := R(A)<=R(A+1) (Syms[B]=:<=,C=1)*/
+      int a = GETARG_A(i);
+      OP_CMP(<=);
+      NEXT;
+    }
+
+    CASE(OP_GT) {
+      /* A B C  R(A) := R(A)>R(A+1) (Syms[B]=:>,C=1)*/
+      int a = GETARG_A(i);
+      OP_CMP(>);
+      NEXT;
+    }
+
+    CASE(OP_GE) {
+      /* A B C  R(A) := R(A)>=R(A+1) (Syms[B]=:>=,C=1)*/
+      int a = GETARG_A(i);
+      OP_CMP(>=);
+      NEXT;
+    }
+
+    CASE(OP_ARRAY) {
+      /* A B C          R(A) := ary_new(R(B),R(B+1)..R(B+C)) */
+      int a = GETARG_A(i);
+      int b = GETARG_B(i);
+      int c = GETARG_C(i);
+      mrb_value v = mrb_ary_new_from_values(mrb, c, &regs[b]);
+      regs[a] = v;
+      ARENA_RESTORE(mrb, ai);
+      NEXT;
+    }
+
+    CASE(OP_ARYCAT) {
+      /* A B            mrb_ary_concat(R(A),R(B)) */
+      int a = GETARG_A(i);
+      int b = GETARG_B(i);
+      mrb_value splat = mrb_ary_splat(mrb, regs[b]);
+      mrb_ary_concat(mrb, regs[a], splat);
+      ARENA_RESTORE(mrb, ai);
+      NEXT;
+    }
+
+    CASE(OP_ARYPUSH) {
+      /* A B            R(A).push(R(B)) */
+      int a = GETARG_A(i);
+      int b = GETARG_B(i);
+      mrb_ary_push(mrb, regs[a], regs[b]);
+      NEXT;
+    }
+
+    CASE(OP_AREF) {
+      /* A B C          R(A) := R(B)[C] */
+      int a = GETARG_A(i);
+      int b = GETARG_B(i);
+      int c = GETARG_C(i);
+      mrb_value v = regs[b];
+
+      if (!mrb_array_p(v)) {
+        if (c == 0) {
+          regs[a] = v;
+        }
+        else {
+          SET_NIL_VALUE(regs[a]);
+        }
+      }
+      else {
+        v = mrb_ary_ref(mrb, v, c);
+        regs[a] = v;
+      }
+      NEXT;
+    }
+
+    CASE(OP_ASET) {
+      /* A B C          R(B)[C] := R(A) */
+      int a = GETARG_A(i);
+      int b = GETARG_B(i);
+      int c = GETARG_C(i);
+      mrb_ary_set(mrb, regs[b], c, regs[a]);
+      NEXT;
+    }
+
+    CASE(OP_APOST) {
+      /* A B C  *R(A),R(A+1)..R(A+C) := R(A) */
+      int a = GETARG_A(i);
+      mrb_value v = regs[a];
+      int pre  = GETARG_B(i);
+      int post = GETARG_C(i);
+      struct RArray *ary;
+      int len, idx;
+
+      if (!mrb_array_p(v)) {
+        v = mrb_ary_new_from_values(mrb, 1, &regs[a]);
+      }
+      ary = mrb_ary_ptr(v);
+      len = ary->len;
+      if (len > pre + post) {
+        v = mrb_ary_new_from_values(mrb, len - pre - post, ary->ptr+pre);
+        regs[a++] = v;
+        while (post--) {
+          regs[a++] = ary->ptr[len-post-1];
+        }
+      }
+      else {
+        v = mrb_ary_new_capa(mrb, 0);
+        regs[a++] = v;
+        for (idx=0; idx+pre<len; idx++) {
+          regs[a+idx] = ary->ptr[pre+idx];
+        }
+        while (idx < post) {
+          SET_NIL_VALUE(regs[a+idx]);
+          idx++;
+        }
+      }
+      ARENA_RESTORE(mrb, ai);
+      NEXT;
+    }
+
+    CASE(OP_STRING) {
+      /* A Bx           R(A) := str_new(Lit(Bx)) */
+      mrb_value str = mrb_str_dup(mrb, pool[GETARG_Bx(i)]);
+      regs[GETARG_A(i)] = str;
+      ARENA_RESTORE(mrb, ai);
+      NEXT;
+    }
+
+    CASE(OP_STRCAT) {
+      /* A B    R(A).concat(R(B)) */
+      mrb_str_concat(mrb, regs[GETARG_A(i)], regs[GETARG_B(i)]);
+      NEXT;
+    }
+
+    CASE(OP_HASH) {
+      /* A B C   R(A) := hash_new(R(B),R(B+1)..R(B+C)) */
+      int b = GETARG_B(i);
+      int c = GETARG_C(i);
+      int lim = b+c*2;
+      mrb_value hash = mrb_hash_new_capa(mrb, c);
+
+      while (b < lim) {
+        mrb_hash_set(mrb, hash, regs[b], regs[b+1]);
+        b+=2;
+      }
+      regs[GETARG_A(i)] = hash;
+      ARENA_RESTORE(mrb, ai);
+      NEXT;
+    }
+
+    CASE(OP_LAMBDA) {
+      /* A b c  R(A) := lambda(SEQ[b],c) (b:c = 14:2) */
+      struct RProc *p;
+      int c = GETARG_c(i);
+
+      if (c & OP_L_CAPTURE) {
+        p = mrb_closure_new(mrb, irep->reps[GETARG_b(i)]);
+      }
+      else {
+        p = mrb_proc_new(mrb, irep->reps[GETARG_b(i)]);
+      }
+      if (c & OP_L_STRICT) p->flags |= MRB_PROC_STRICT;
+      regs[GETARG_A(i)] = mrb_obj_value(p);
+      ARENA_RESTORE(mrb, ai);
+      NEXT;
+    }
+
+    CASE(OP_OCLASS) {
+      /* A      R(A) := ::Object */
+      regs[GETARG_A(i)] = mrb_obj_value(mrb->object_class);
+      NEXT;
+    }
+
+    CASE(OP_CLASS) {
+      /* A B    R(A) := newclass(R(A),Syms(B),R(A+1)) */
+      struct RClass *c = 0, *baseclass;
+      int a = GETARG_A(i);
+      mrb_value base, super;
+      mrb_sym id = syms[GETARG_B(i)];
+
+      base = regs[a];
+      super = regs[a+1];
+      if (mrb_nil_p(base)) {
+        baseclass = mrb->c->ci->proc->target_class;
+        if (!baseclass) baseclass = mrb->c->ci->target_class;
+
+        base = mrb_obj_value(baseclass);
+      }
+      c = mrb_vm_define_class(mrb, base, super, id);
+      regs[a] = mrb_obj_value(c);
+      ARENA_RESTORE(mrb, ai);
+      NEXT;
+    }
+
+    CASE(OP_MODULE) {
+      /* A B            R(A) := newmodule(R(A),Syms(B)) */
+      struct RClass *c = 0, *baseclass;
+      int a = GETARG_A(i);
+      mrb_value base;
+      mrb_sym id = syms[GETARG_B(i)];
+
+      base = regs[a];
+      if (mrb_nil_p(base)) {
+        baseclass = mrb->c->ci->proc->target_class;
+        if (!baseclass) baseclass = mrb->c->ci->target_class;
+
+        base = mrb_obj_value(baseclass);
+      }
+      c = mrb_vm_define_module(mrb, base, id);
+      regs[a] = mrb_obj_value(c);
+      ARENA_RESTORE(mrb, ai);
+      NEXT;
+    }
+
+    CASE(OP_EXEC) {
+      /* A Bx   R(A) := blockexec(R(A),SEQ[Bx]) */
+      int a = GETARG_A(i);
+      mrb_callinfo *ci;
+      mrb_value recv = regs[a];
+      struct RProc *p;
+
+      /* prepare closure */
+      p = mrb_closure_new(mrb, irep->reps[GETARG_Bx(i)]);
+      p->c = NULL;
+
+      /* prepare stack */
+      ci = cipush(mrb);
+      ci->pc = pc + 1;
+      ci->acc = a;
+      ci->mid = 0;
+      ci->stackent = mrb->c->stack;
+      ci->argc = 0;
+      ci->target_class = mrb_class_ptr(recv);
+
+      /* prepare stack */
+      mrb->c->stack += a;
+
+      /* setup closure */
+      p->target_class = ci->target_class;
+      ci->proc = p;
+
+      irep = p->body.irep;
+      pool = irep->pool;
+      syms = irep->syms;
+      stack_extend(mrb, irep->nregs);
+      stack_clear(regs+1, irep->nregs-1);
+      ci->nregs = irep->nregs;
+      pc = irep->iseq;
+      JUMP;
+    }
+
+    CASE(OP_METHOD) {
+      /* A B            R(A).newmethod(Syms(B),R(A+1)) */
+      int a = GETARG_A(i);
+      struct RClass *c = mrb_class_ptr(regs[a]);
+      struct RProc *p = mrb_proc_ptr(regs[a+1]);
+
+      mrb_define_method_raw(mrb, c, syms[GETARG_B(i)], p);
+      ARENA_RESTORE(mrb, ai);
+      NEXT;
+    }
+
+    CASE(OP_SCLASS) {
+      /* A B    R(A) := R(B).singleton_class */
+      regs[GETARG_A(i)] = mrb_singleton_class(mrb, regs[GETARG_B(i)]);
+      ARENA_RESTORE(mrb, ai);
+      NEXT;
+    }
+
+    CASE(OP_TCLASS) {
+      /* A      R(A) := target_class */
+      if (!mrb->c->ci->target_class) {
+        mrb_value exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, "no target class or module");
+        mrb_exc_set(mrb, exc);
+        goto L_RAISE;
+      }
+      regs[GETARG_A(i)] = mrb_obj_value(mrb->c->ci->target_class);
+      NEXT;
+    }
+
+    CASE(OP_RANGE) {
+      /* A B C  R(A) := range_new(R(B),R(B+1),C) */
+      int b = GETARG_B(i);
+      mrb_value val = mrb_range_new(mrb, regs[b], regs[b+1], GETARG_C(i));
+      regs[GETARG_A(i)] = val;
+      ARENA_RESTORE(mrb, ai);
+      NEXT;
+    }
+
+    CASE(OP_DEBUG) {
+      /* A B C    debug print R(A),R(B),R(C) */
+#ifdef MRB_ENABLE_DEBUG_HOOK
+      mrb->debug_op_hook(mrb, irep, pc, regs);
+#else
+#ifndef MRB_DISABLE_STDIO
+      printf("OP_DEBUG %d %d %d\n", GETARG_A(i), GETARG_B(i), GETARG_C(i));
+#else
+      abort();
+#endif
+#endif
+      NEXT;
+    }
+
+    CASE(OP_STOP) {
+      /*        stop VM */
+    L_STOP:
+      {
+        int epos = mrb->c->ci->epos;
+
+        while (mrb->c->eidx > epos) {
+          ecall(mrb, --mrb->c->eidx);
+        }
+      }
+      ERR_PC_CLR(mrb);
+      mrb->jmp = prev_jmp;
+      if (mrb->exc) {
+        return mrb_obj_value(mrb->exc);
+      }
+      return regs[irep->nlocals];
+    }
+
+    CASE(OP_ERR) {
+      /* Bx     raise RuntimeError with message Lit(Bx) */
+      mrb_value msg = mrb_str_dup(mrb, pool[GETARG_Bx(i)]);
+      mrb_value exc;
+
+      if (GETARG_A(i) == 0) {
+        exc = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, msg);
+      }
+      else {
+        exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg);
+      }
+      mrb_exc_set(mrb, exc);
+      goto L_RAISE;
+    }
+  }
+  END_DISPATCH;
+#undef regs
+
+  }
+  MRB_CATCH(&c_jmp) {
+    exc_catched = TRUE;
+    goto RETRY_TRY_BLOCK;
+  }
+  MRB_END_EXC(&c_jmp);
+}
+
+MRB_API mrb_value
+mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
+{
+  if (mrb->c->ci->argc < 0) {
+    return mrb_vm_run(mrb, proc, self, 3); /* receiver, args and block) */
+  }
+  else {
+    return mrb_vm_run(mrb, proc, self, mrb->c->ci->argc + 2); /* argc + 2 (receiver and block) */
+  }
+}
+
+MRB_API mrb_value
+mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep)
+{
+  mrb_callinfo *ci;
+  mrb_value v;
+
+  if (!mrb->c->cibase) {
+    return mrb_vm_run(mrb, proc, self, stack_keep);
+  }
+  if (mrb->c->ci == mrb->c->cibase) {
+    mrb->c->ci->env = NULL;
+    return mrb_vm_run(mrb, proc, self, stack_keep);
+  }
+  ci = cipush(mrb);
+  ci->mid = 0;
+  ci->nregs = 1;   /* protect the receiver */
+  ci->acc = CI_ACC_SKIP;
+  ci->target_class = mrb->object_class;
+  v = mrb_vm_run(mrb, proc, self, stack_keep);
+  cipop(mrb);
+
+  return v;
+}
+
+#if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus)
+# if !defined(MRB_ENABLE_CXX_ABI)
+} /* end of extern "C" */
+# endif
+mrb_int mrb_jmpbuf::jmpbuf_id = 0;
+# if !defined(MRB_ENABLE_CXX_ABI)
+extern "C" {
+# endif
+#endif
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/benchmark.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/tasks/benchmark.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/benchmark.rake	(revision 331)
@@ -0,0 +1,91 @@
+module MRuby
+  BENCHMARK_REPEAT = 4
+end
+
+$dat_files = []
+
+def bm_files
+  Dir.glob("#{MRUBY_ROOT}/benchmark/bm_*.rb")
+end
+
+def build_config_name
+  if ENV['MRUBY_CONFIG']
+    File.basename(ENV['MRUBY_CONFIG'], '.rb').gsub('build_config_', '')
+  else
+    "build"
+  end
+end
+
+def plot_file
+  File.join(MRUBY_ROOT, 'benchmark', "#{build_config_name}.png")
+end
+
+def plot
+  opts_file = "#{MRUBY_ROOT}/benchmark/plot.gpl"
+  opts = File.read(opts_file).each_line.to_a.map(&:strip).join(';')
+
+  dat_files = $dat_files.group_by {|f| File.dirname(f).split(File::SEPARATOR)[-1]}
+
+  opts += ";set output '#{plot_file}'"
+
+  opts += ';plot '
+
+  opts += dat_files.keys.map do |data_file|
+    %Q['-' u 2:3:4:xtic(1) w hist title columnheader(1)]
+  end.join(',')
+  opts += ';'
+
+  cmd = %Q{gnuplot -p -e "#{opts}"}
+
+  IO.popen(cmd, 'w') do |p|
+    dat_files.each do |target_name, bm_files|
+      p.puts target_name.gsub('_', '-')
+      bm_files.each do |bm_file|
+        p.write File.read(bm_file)
+      end
+      p.puts "e"
+    end
+  end
+end
+
+
+MRuby.each_target do |target|
+  next if target.name == 'host'
+  mruby_bin = "#{target.build_dir}/bin/mruby"
+
+  bm_files.each do |bm_file|
+    bm_name = File.basename bm_file, ".rb"
+
+    dat_dir = File.join('benchmark', build_config_name, target.name)
+    dat_file = File.join(dat_dir, "#{bm_name}.dat")
+    $dat_files << dat_file
+
+    directory dat_dir
+
+    file dat_file => [bm_file, dat_dir, mruby_bin] do |task|
+      print bm_name
+      puts "..."
+
+      data = (0...MRuby::BENCHMARK_REPEAT).map do |n|
+        str = %x{(time -f "%e %S %U" #{mruby_bin} #{bm_file}) 2>&1 >/dev/null}
+        str.split(' ').map(&:to_f)
+      end
+
+      File.open(task.name, "w") do |f|
+        data = data.map {|_,r,s| (r + s) / 2.0}
+        min = data.min
+        max = data.max
+        avg = data.inject(&:+) / data.size
+        f.puts "#{bm_name.gsub('_', '-')} #{avg} #{min} #{max}"
+      end
+    end
+  end
+end
+
+file plot_file => $dat_files do
+  plot
+end
+
+task :benchmark => plot_file do
+  plot
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/gitlab.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/tasks/gitlab.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/gitlab.rake	(revision 331)
@@ -0,0 +1,118 @@
+CI_VERSION = '0.7'.freeze
+CI_BASE = 'ubuntu:16.10'.freeze
+CI_COMPILERS = ['gcc-4.7',
+                'gcc-4.8',
+                'gcc-4.9',
+                'gcc-5',
+                'gcc-6',
+                'clang-3.5',
+                'clang-3.6',
+                'clang-3.7',
+                'clang-3.8',
+                'clang-3.9'].freeze
+
+def ci_image_tag(compiler)
+  compiler.tr('+', 'c').delete('-').delete('.')
+end
+
+def ci_docker_tag(compiler)
+  tag = ci_image_tag(compiler)
+  "registry.gitlab.com/dabroz/mruby:#{tag}_#{CI_VERSION}"
+end
+
+def run_cmd(cmd)
+  puts cmd
+  raise 'error' unless system cmd
+end
+
+desc 'recreate docker images for GitLab builds'
+task :gitlab_dockers do
+  CI_COMPILERS.each do |compiler|
+    tag = ci_image_tag(compiler)
+    filename = "Dockerfile.#{tag}"
+    File.open(filename, 'wb') do |f|
+      f << "# #{compiler} - #{tag}\n"
+      f << "FROM #{CI_BASE}\n"
+      f << "RUN apt-get update && apt-get install -y git ruby2.3 ruby2.3-dev bison\n"
+      f << "RUN apt-get update && apt-get install -y binutils manpages\n"
+      f << "RUN apt-get update && apt-get install -y #{compiler}\n"
+      if compiler['gcc']
+        f << "RUN apt-get update && apt-get install -y libx32#{compiler}-dev\n"
+        f << "RUN apt-get update && apt-get install --no-install-recommends -y #{compiler}-multilib\n"
+      end
+      f << "RUN dpkg --add-architecture i386\n"
+      f << "RUN apt-get update && apt-get install -y linux-libc-dev:i386\n"
+      if compiler['clang']
+        f << "RUN apt-get update && apt-get install --no-install-recommends -y libc6-dev-i386\n"
+        f << "RUN apt-get update && apt-get install -y gcc gcc-multilib\n"
+      end
+    end
+    docker_tag = ci_docker_tag(compiler)
+    cmd1 = "docker build -t #{docker_tag} -f #{filename} ."
+    cmd2 = "docker push #{docker_tag}"
+    run_cmd cmd1
+    run_cmd cmd2
+    File.delete(filename)
+  end
+end
+
+desc 'create build configurations and update .gitlab-ci.yml'
+task :gitlab_config do
+  require 'yaml'
+
+  configs = []
+  [true, false].each do |mode_32|
+    ['', 'MRB_USE_FLOAT'].each do |float_conf|
+      ['', 'MRB_INT16', 'MRB_INT64'].each do |int_conf|
+        ['', 'MRB_NAN_BOXING', 'MRB_WORD_BOXING'].each do |boxing_conf|
+          ['', 'MRB_UTF8_STRING'].each do |utf8_conf|
+            next if (float_conf == 'MRB_USE_FLOAT') && (boxing_conf == 'MRB_NAN_BOXING')
+            next if (int_conf == 'MRB_INT64') && (boxing_conf == 'MRB_NAN_BOXING')
+            next if (int_conf == 'MRB_INT16') && (boxing_conf == 'MRB_WORD_BOXING')
+            next if (int_conf == 'MRB_INT64') && (boxing_conf == 'MRB_WORD_BOXING') && mode_32
+            env = [float_conf, int_conf, boxing_conf, utf8_conf].map do |conf|
+              conf == '' ? nil : "-D#{conf}=1"
+            end.compact.join(' ')
+            bit = mode_32 ? '-m32 ' : ''
+            _info = ''
+            _info += mode_32 ? '32bit ' : '64bit '
+            _info += float_conf['USE'] ? 'float ' : ''
+            _info += int_conf['16'] ? 'int16 ' : ''
+            _info += int_conf['64'] ? 'int64 ' : ''
+            _info += boxing_conf['NAN'] ? 'nan ' : ''
+            _info += boxing_conf['word'] ? 'word ' : ''
+            _info += utf8_conf['UTF8'] ? 'utf8 ' : ''
+            _info = _info.gsub(/ +/, ' ').strip.tr(' ', '_')
+            configs << { '_info' => _info, 'CFLAGS' => "#{bit}#{env}", 'LDFLAGS' => bit.strip.to_s }
+          end
+        end
+      end
+    end
+  end
+  path = './.gitlab-ci.yml'
+  data = YAML.load_file(path)
+  data.keys.select do |key|
+    key.start_with? 'Test'
+  end.each do |key|
+    data.delete(key)
+  end
+  CI_COMPILERS.each do |compiler|
+    configs.each do |config|
+      name = "Test #{compiler} #{config['_info']}"
+      hash = {
+        'CC' => compiler,
+        'CXX' => compiler.gsub('gcc', 'g++').gsub('clang', 'clang++'),
+        'LD' => compiler
+      }
+      hash = hash.merge(config)
+      hash.delete('_info')
+      data[name] = {
+        'stage' => 'test',
+        'image' => ci_docker_tag(compiler),
+        'variables' => hash,
+        'script' => 'env; ./minirake --verbose all test'
+      }
+    end
+  end
+  File.open(path, 'w') { |f| YAML.dump(data, f) }
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/libmruby.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/tasks/libmruby.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/libmruby.rake	(revision 331)
@@ -0,0 +1,24 @@
+MRuby.each_target do
+  file libfile("#{build_dir}/lib/libmruby") => libmruby.flatten do |t|
+    archiver.run t.name, t.prerequisites
+  end
+
+  file "#{build_dir}/lib/libmruby.flags.mak" => [__FILE__, libfile("#{build_dir}/lib/libmruby")] do |t|
+    open(t.name, 'w') do |f|
+      f.puts "MRUBY_CFLAGS = #{cc.all_flags}"
+
+      gem_flags = gems.map { |g| g.linker.flags }
+      gem_library_paths = gems.map { |g| g.linker.library_paths }
+      f.puts "MRUBY_LDFLAGS = #{linker.all_flags(gem_library_paths, gem_flags)} #{linker.option_library_path % "#{build_dir}/lib"}"
+
+      gem_flags_before_libraries = gems.map { |g| g.linker.flags_before_libraries }
+      f.puts "MRUBY_LDFLAGS_BEFORE_LIBS = #{[linker.flags_before_libraries, gem_flags_before_libraries].flatten.join(' ')}"
+
+      gem_libraries = gems.map { |g| g.linker.libraries }
+      f.puts "MRUBY_LIBS = #{linker.option_library % 'mruby'} #{linker.library_flags(gem_libraries)}"
+
+      f.puts "MRUBY_LIBMRUBY_PATH = #{libfile("#{build_dir}/lib/libmruby")}"
+    end
+  end
+  task :all => "#{build_dir}/lib/libmruby.flags.mak"
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/mrbgem_spec.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/tasks/mrbgem_spec.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/mrbgem_spec.rake	(revision 331)
@@ -0,0 +1,459 @@
+require 'pathname'
+require 'forwardable'
+require 'tsort'
+require 'shellwords'
+
+module MRuby
+  module Gem
+    class << self
+      attr_accessor :current
+    end
+    LinkerConfig = Struct.new(:libraries, :library_paths, :flags, :flags_before_libraries, :flags_after_libraries)
+
+    class Specification
+      include Rake::DSL
+      extend Forwardable
+      def_delegators :@build, :filename, :objfile, :libfile, :exefile
+
+      attr_accessor :name, :dir, :build
+      alias mruby build
+      attr_accessor :build_config_initializer
+      attr_accessor :mrblib_dir, :objs_dir
+
+      attr_accessor :version
+      attr_accessor :description, :summary
+      attr_accessor :homepage
+      attr_accessor :licenses, :authors
+      alias :license= :licenses=
+      alias :author= :authors=
+
+      attr_accessor :rbfiles, :objs
+      attr_accessor :test_objs, :test_rbfiles, :test_args
+      attr_accessor :test_preload
+
+      attr_accessor :bins
+
+      attr_accessor :requirements
+      attr_reader :dependencies, :conflicts
+
+      attr_accessor :export_include_paths
+
+      attr_reader :generate_functions
+
+      attr_block MRuby::Build::COMMANDS
+
+      def initialize(name, &block)
+        @name = name
+        @initializer = block
+        @version = "0.0.0"
+        @mrblib_dir = "mrblib"
+        @objs_dir = "src"
+        MRuby::Gem.current = self
+      end
+
+      def setup
+        MRuby::Gem.current = self
+        MRuby::Build::COMMANDS.each do |command|
+          instance_variable_set("@#{command}", @build.send(command).clone)
+        end
+        @linker = LinkerConfig.new([], [], [], [], [])
+
+        @rbfiles = Dir.glob("#{@dir}/#{@mrblib_dir}/**/*.rb").sort
+        @objs = Dir.glob("#{@dir}/#{@objs_dir}/*.{c,cpp,cxx,cc,m,asm,s,S}").map do |f|
+          objfile(f.relative_path_from(@dir).to_s.pathmap("#{build_dir}/%X"))
+        end
+
+        @generate_functions = !(@rbfiles.empty? && @objs.empty?)
+        @objs << objfile("#{build_dir}/gem_init") if @generate_functions
+
+        @test_rbfiles = Dir.glob("#{dir}/test/**/*.rb")
+        @test_objs = Dir.glob("#{dir}/test/*.{c,cpp,cxx,cc,m,asm,s,S}").map do |f|
+          objfile(f.relative_path_from(dir).to_s.pathmap("#{build_dir}/%X"))
+        end
+        @custom_test_init = !@test_objs.empty?
+        @test_preload = nil # 'test/assert.rb'
+        @test_args = {}
+
+        @bins = []
+
+        @requirements = []
+        @dependencies, @conflicts = [], []
+        @export_include_paths = []
+        @export_include_paths << "#{dir}/include" if File.directory? "#{dir}/include"
+
+        instance_eval(&@initializer)
+
+        if !name || !licenses || !authors
+          fail "#{name || dir} required to set name, license(s) and author(s)"
+        end
+
+        build.libmruby << @objs
+
+        instance_eval(&@build_config_initializer) if @build_config_initializer
+      end
+
+      def setup_compilers
+        compilers.each do |compiler|
+          compiler.define_rules build_dir, "#{dir}"
+          compiler.defines << %Q[MRBGEM_#{funcname.upcase}_VERSION=#{version}]
+          compiler.include_paths << "#{dir}/include" if File.directory? "#{dir}/include"
+        end
+
+        define_gem_init_builder if @generate_functions
+      end
+
+      def add_dependency(name, *requirements)
+        default_gem = requirements.last.kind_of?(Hash) ? requirements.pop : nil
+        requirements = ['>= 0.0.0'] if requirements.empty?
+        requirements.flatten!
+        @dependencies << {:gem => name, :requirements => requirements, :default => default_gem}
+      end
+
+      def add_test_dependency(*args)
+        add_dependency(*args) if build.test_enabled?
+      end
+
+      def add_conflict(name, *req)
+        @conflicts << {:gem => name, :requirements => req.empty? ? nil : req}
+      end
+
+      def self.bin=(bin)
+        @bins = [bin].flatten
+      end
+
+      def build_dir
+        "#{build.build_dir}/mrbgems/#{name}"
+      end
+
+      def test_rbireps
+        "#{build_dir}/gem_test.c"
+      end
+
+      def search_package(name, version_query=nil)
+        package_query = name
+        package_query += " #{version_query}" if version_query
+        _pp "PKG-CONFIG", package_query
+        escaped_package_query = Shellwords.escape(package_query)
+        if system("pkg-config --exists #{escaped_package_query}")
+          cc.flags += [`pkg-config --cflags #{escaped_package_query}`.strip]
+          cxx.flags += [`pkg-config --cflags #{escaped_package_query}`.strip]
+          linker.flags_before_libraries += [`pkg-config --libs #{escaped_package_query}`.strip]
+          true
+        else
+          false
+        end
+      end
+
+      def funcname
+        @funcname ||= @name.gsub('-', '_')
+      end
+
+      def compilers
+        MRuby::Build::COMPILERS.map do |c|
+          instance_variable_get("@#{c}")
+        end
+      end
+
+      def define_gem_init_builder
+        file objfile("#{build_dir}/gem_init") => [ "#{build_dir}/gem_init.c", File.join(dir, "mrbgem.rake") ]
+        file "#{build_dir}/gem_init.c" => [build.mrbcfile, __FILE__] + [rbfiles].flatten do |t|
+          FileUtils.mkdir_p build_dir
+          generate_gem_init("#{build_dir}/gem_init.c")
+        end
+      end
+
+      def generate_gem_init(fname)
+        open(fname, 'w') do |f|
+          print_gem_init_header f
+          build.mrbc.run f, rbfiles, "gem_mrblib_irep_#{funcname}" unless rbfiles.empty?
+          f.puts %Q[void mrb_#{funcname}_gem_init(mrb_state *mrb);]
+          f.puts %Q[void mrb_#{funcname}_gem_final(mrb_state *mrb);]
+          f.puts %Q[]
+          f.puts %Q[void GENERATED_TMP_mrb_#{funcname}_gem_init(mrb_state *mrb) {]
+          f.puts %Q[  int ai = mrb_gc_arena_save(mrb);]
+          f.puts %Q[  mrb_#{funcname}_gem_init(mrb);] if objs != [objfile("#{build_dir}/gem_init")]
+          unless rbfiles.empty?
+            f.puts %Q[  mrb_load_irep(mrb, gem_mrblib_irep_#{funcname});]
+            f.puts %Q[  if (mrb->exc) {]
+            f.puts %Q[    mrb_print_error(mrb);]
+            f.puts %Q[    exit(EXIT_FAILURE);]
+            f.puts %Q[  }]
+          end
+          f.puts %Q[  mrb_gc_arena_restore(mrb, ai);]
+          f.puts %Q[}]
+          f.puts %Q[]
+          f.puts %Q[void GENERATED_TMP_mrb_#{funcname}_gem_final(mrb_state *mrb) {]
+          f.puts %Q[  mrb_#{funcname}_gem_final(mrb);] if objs != [objfile("#{build_dir}/gem_init")]
+          f.puts %Q[}]
+        end
+      end # generate_gem_init
+
+      def print_gem_comment(f)
+        f.puts %Q[/*]
+        f.puts %Q[ * This file is loading the irep]
+        f.puts %Q[ * Ruby GEM code.]
+        f.puts %Q[ *]
+        f.puts %Q[ * IMPORTANT:]
+        f.puts %Q[ *   This file was generated!]
+        f.puts %Q[ *   All manual changes will get lost.]
+        f.puts %Q[ */]
+      end
+
+      def print_gem_init_header(f)
+        print_gem_comment(f)
+        f.puts %Q[#include <stdlib.h>] unless rbfiles.empty?
+        f.puts %Q[#include <mruby.h>]
+        f.puts %Q[#include <mruby/irep.h>] unless rbfiles.empty?
+      end
+
+      def print_gem_test_header(f)
+        print_gem_comment(f)
+        f.puts %Q[#include <stdio.h>]
+        f.puts %Q[#include <stdlib.h>]
+        f.puts %Q[#include <mruby.h>]
+        f.puts %Q[#include <mruby/irep.h>]
+        f.puts %Q[#include <mruby/variable.h>]
+        f.puts %Q[#include <mruby/hash.h>] unless test_args.empty?
+      end
+
+      def test_dependencies
+        [@name]
+      end
+
+      def custom_test_init?
+        @custom_test_init
+      end
+
+      def version_ok?(req_versions)
+        req_versions.map do |req|
+          cmp, ver = req.split
+          cmp_result = Version.new(version) <=> Version.new(ver)
+          case cmp
+          when '=' then cmp_result == 0
+          when '!=' then cmp_result != 0
+          when '>' then cmp_result == 1
+          when '<' then cmp_result == -1
+          when '>=' then cmp_result >= 0
+          when '<=' then cmp_result <= 0
+          when '~>'
+            Version.new(version).twiddle_wakka_ok?(Version.new(ver))
+          else
+            fail "Comparison not possible with '#{cmp}'"
+          end
+        end.all?
+      end
+    end # Specification
+
+    class Version
+      include Comparable
+      include Enumerable
+
+      def <=>(other)
+        ret = 0
+        own = to_enum
+
+        other.each do |oth|
+          begin
+            ret = own.next <=> oth
+          rescue StopIteration
+            ret = 0 <=> oth
+          end
+
+          break unless ret == 0
+        end
+
+        ret
+      end
+
+      # ~> compare algorithm
+      #
+      # Example:
+      #    ~> 2.2   means >= 2.2.0 and < 3.0.0
+      #    ~> 2.2.0 means >= 2.2.0 and < 2.3.0
+      def twiddle_wakka_ok?(other)
+        gr_or_eql = (self <=> other) >= 0
+        still_minor = (self <=> other.skip_minor) < 0
+        gr_or_eql and still_minor
+      end
+
+      def skip_minor
+        a = @ary.dup
+        a.slice!(-1)
+        a[-1] = a[-1].succ
+        a
+      end
+
+      def initialize(str)
+        @str = str
+        @ary = @str.split('.').map(&:to_i)
+      end
+
+      def each(&block); @ary.each(&block); end
+      def [](index); @ary[index]; end
+      def []=(index, value)
+        @ary[index] = value
+        @str = @ary.join('.')
+      end
+      def slice!(index)
+        @ary.slice!(index)
+        @str = @ary.join('.')
+      end
+    end # Version
+
+    class List
+      include Enumerable
+
+      def initialize
+        @ary = []
+      end
+
+      def each(&b)
+        @ary.each(&b)
+      end
+
+      def <<(gem)
+        unless @ary.detect {|g| g.dir == gem.dir }
+          @ary << gem
+        else
+          # GEM was already added to this list
+        end
+      end
+
+      def empty?
+        @ary.empty?
+      end
+
+      def generate_gem_table build
+        gem_table = @ary.reduce({}) { |res,v| res[v.name] = v; res }
+
+        default_gems = []
+        each do |g|
+          g.dependencies.each do |dep|
+            unless gem_table.key? dep[:gem]
+              if dep[:default]; default_gems << dep
+              elsif File.exist? "#{MRUBY_ROOT}/mrbgems/#{dep[:gem]}" # check core
+                default_gems << { :gem => dep[:gem], :default => { :core => dep[:gem] } }
+              else # fallback to mgem-list
+                default_gems << { :gem => dep[:gem], :default => { :mgem => dep[:gem] } }
+              end
+            end
+          end
+        end
+
+        until default_gems.empty?
+          def_gem = default_gems.pop
+
+          spec = build.gem def_gem[:default]
+          fail "Invalid gem name: #{spec.name} (Expected: #{def_gem[:gem]})" if spec.name != def_gem[:gem]
+          spec.setup
+
+          spec.dependencies.each do |dep|
+            unless gem_table.key? dep[:gem]
+              if dep[:default]; default_gems << dep
+              else default_gems << { :gem => dep[:gem], :default => { :mgem => dep[:gem] } }
+              end
+            end
+          end
+          gem_table[spec.name] = spec
+        end
+
+        each do |g|
+          g.dependencies.each do |dep|
+            name = dep[:gem]
+            req_versions = dep[:requirements]
+            dep_g = gem_table[name]
+
+            # check each GEM dependency against all available GEMs
+            if dep_g.nil?
+              fail "The GEM '#{g.name}' depends on the GEM '#{name}' but it could not be found"
+            end
+            unless dep_g.version_ok? req_versions
+              fail "#{name} version should be #{req_versions.join(' and ')} but was '#{dep_g.version}'"
+            end
+          end
+
+          cfls = g.conflicts.select { |c|
+            cfl_g = gem_table[c[:gem]]
+            cfl_g and cfl_g.version_ok?(c[:requirements] || ['>= 0.0.0'])
+          }.map { |c| "#{c[:gem]}(#{gem_table[c[:gem]].version})" }
+          fail "Conflicts of gem `#{g.name}` found: #{cfls.join ', '}" unless cfls.empty?
+        end
+
+        gem_table
+      end
+
+      def tsort_dependencies ary, table, all_dependency_listed = false
+        unless all_dependency_listed
+          left = ary.dup
+          until left.empty?
+            v = left.pop
+            table[v].dependencies.each do |dep|
+              left.push dep[:gem]
+              ary.push dep[:gem]
+            end
+          end
+        end
+
+        ary.uniq!
+        table.instance_variable_set :@root_gems, ary
+        class << table
+          include TSort
+          def tsort_each_node &b
+            @root_gems.each &b
+          end
+
+          def tsort_each_child(n, &b)
+            fetch(n).dependencies.each do |v|
+              b.call v[:gem]
+            end
+          end
+        end
+
+        begin
+          table.tsort.map { |v| table[v] }
+        rescue TSort::Cyclic => e
+          fail "Circular mrbgem dependency found: #{e.message}"
+        end
+      end
+
+      def check(build)
+        gem_table = generate_gem_table build
+
+        @ary = tsort_dependencies gem_table.keys, gem_table, true
+
+        each(&:setup_compilers)
+
+        each do |g|
+          import_include_paths(g)
+        end
+      end
+
+      def import_include_paths(g)
+        gem_table = @ary.reduce({}) { |res,v| res[v.name] = v; res }
+        g.dependencies.each do |dep|
+          dep_g = gem_table[dep[:gem]]
+          # We can do recursive call safely
+          # as circular dependency has already detected in the caller.
+          import_include_paths(dep_g)
+
+          dep_g.export_include_paths.uniq!
+          g.compilers.each do |compiler|
+            compiler.include_paths += dep_g.export_include_paths
+            g.export_include_paths += dep_g.export_include_paths
+            compiler.include_paths.uniq!
+            g.export_include_paths.uniq!
+          end
+        end
+      end
+    end # List
+  end # Gem
+
+  GemBox = Object.new
+  class << GemBox
+    attr_accessor :path
+
+    def new(&block); block.call(self); end
+    def config=(obj); @config = obj; end
+    def gem(gemdir, &block); @config.gem(gemdir, &block); end
+  end # GemBox
+end # MRuby
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/mrbgems.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/tasks/mrbgems.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/mrbgems.rake	(revision 331)
@@ -0,0 +1,96 @@
+MRuby.each_target do
+  if enable_gems?
+    # set up all gems
+    gems.each(&:setup)
+    gems.check self
+
+    # loader all gems
+    self.libmruby << objfile("#{build_dir}/mrbgems/gem_init")
+    file objfile("#{build_dir}/mrbgems/gem_init") => ["#{build_dir}/mrbgems/gem_init.c", "#{build_dir}/LEGAL"]
+    file "#{build_dir}/mrbgems/gem_init.c" => [MRUBY_CONFIG, __FILE__] do |t|
+      FileUtils.mkdir_p "#{build_dir}/mrbgems"
+      open(t.name, 'w') do |f|
+        gem_func_gems = gems.select { |g| g.generate_functions }
+        gem_func_decls = gem_func_gems.each_with_object('') do |g, s|
+          s << "void GENERATED_TMP_mrb_#{g.funcname}_gem_init(mrb_state*);\n" \
+               "void GENERATED_TMP_mrb_#{g.funcname}_gem_final(mrb_state*);\n"
+        end
+        gem_init_calls = gem_func_gems.each_with_object('') do |g, s|
+          s << "  GENERATED_TMP_mrb_#{g.funcname}_gem_init(mrb);\n"
+        end
+        gem_final_calls = gem_func_gems.each_with_object('') do |g, s|
+          s << "  GENERATED_TMP_mrb_#{g.funcname}_gem_final(mrb);\n"
+        end
+        f.puts %Q[/*]
+        f.puts %Q[ * This file contains a list of all]
+        f.puts %Q[ * initializing methods which are]
+        f.puts %Q[ * necessary to bootstrap all gems.]
+        f.puts %Q[ *]
+        f.puts %Q[ * IMPORTANT:]
+        f.puts %Q[ *   This file was generated!]
+        f.puts %Q[ *   All manual changes will get lost.]
+        f.puts %Q[ */]
+        f.puts %Q[]
+        f.puts %Q[#include <mruby.h>]
+        f.puts %Q[]
+        f.write gem_func_decls
+        f.puts %Q[]
+        f.puts %Q[static void]
+        f.puts %Q[mrb_final_mrbgems(mrb_state *mrb) {]
+        f.write gem_final_calls
+        f.puts %Q[}]
+        f.puts %Q[]
+        f.puts %Q[void]
+        f.puts %Q[mrb_init_mrbgems(mrb_state *mrb) {]
+        f.write gem_init_calls
+        f.puts %Q[  mrb_state_atexit(mrb, mrb_final_mrbgems);] unless gem_final_calls.empty?
+        f.puts %Q[}]
+      end
+    end
+  end
+
+  # legal documents
+  file "#{build_dir}/LEGAL" => [MRUBY_CONFIG, __FILE__] do |t|
+    open(t.name, 'w+') do |f|
+     f.puts <<LEGAL
+Copyright (c) #{Time.now.year} mruby developers
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+LEGAL
+
+      if enable_gems?
+        f.puts <<GEMS_LEGAL
+
+Additional Licenses
+
+Due to the reason that you choosed additional mruby packages (GEMS),
+please check the following additional licenses too:
+GEMS_LEGAL
+
+        gems.map do |g|
+          authors = [g.authors].flatten.sort.join(", ")
+          f.puts
+          f.puts "GEM: #{g.name}"
+          f.puts "Copyright (c) #{Time.now.year} #{authors}"
+          f.puts "License: #{g.licenses}"
+        end
+      end
+    end
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/mruby_build.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/tasks/mruby_build.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/mruby_build.rake	(revision 331)
@@ -0,0 +1,355 @@
+load "#{MRUBY_ROOT}/tasks/mruby_build_gem.rake"
+load "#{MRUBY_ROOT}/tasks/mruby_build_commands.rake"
+
+module MRuby
+  class << self
+    def targets
+      @targets ||= {}
+    end
+
+    def each_target(&block)
+      return to_enum(:each_target) if block.nil?
+      @targets.each do |key, target|
+        target.instance_eval(&block)
+      end
+    end
+  end
+
+  class Toolchain
+    class << self
+      attr_accessor :toolchains
+    end
+
+    def initialize(name, &block)
+      @name, @initializer = name.to_s, block
+      MRuby::Toolchain.toolchains ||= {}
+      MRuby::Toolchain.toolchains[@name] = self
+    end
+
+    def setup(conf,params={})
+      conf.instance_exec(conf, params, &@initializer)
+    end
+
+    def self.load
+      Dir.glob("#{MRUBY_ROOT}/tasks/toolchains/*.rake").each do |file|
+        Kernel.load file
+      end
+    end
+  end
+  Toolchain.load
+
+  class Build
+    class << self
+      attr_accessor :current
+    end
+    include Rake::DSL
+    include LoadGems
+    attr_accessor :name, :bins, :exts, :file_separator, :build_dir, :gem_clone_dir
+    attr_reader :libmruby, :gems, :toolchains
+    attr_writer :enable_bintest, :enable_test
+
+    COMPILERS = %w(cc cxx objc asm)
+    COMMANDS = COMPILERS + %w(linker archiver yacc gperf git exts mrbc)
+    attr_block MRuby::Build::COMMANDS
+
+    Exts = Struct.new(:object, :executable, :library)
+
+    def initialize(name='host', build_dir=nil, &block)
+      @name = name.to_s
+
+      unless MRuby.targets[@name]
+        if ENV['OS'] == 'Windows_NT'
+          @exts = Exts.new('.o', '.exe', '.a')
+        else
+          @exts = Exts.new('.o', '', '.a')
+        end
+
+        build_dir = build_dir || ENV['MRUBY_BUILD_DIR'] || "#{MRUBY_ROOT}/build"
+
+        @file_separator = '/'
+        @build_dir = "#{build_dir}/#{@name}"
+        @gem_clone_dir = "#{build_dir}/mrbgems"
+        @cc = Command::Compiler.new(self, %w(.c))
+        @cxx = Command::Compiler.new(self, %w(.cc .cxx .cpp))
+        @objc = Command::Compiler.new(self, %w(.m))
+        @asm = Command::Compiler.new(self, %w(.S .asm))
+        @linker = Command::Linker.new(self)
+        @archiver = Command::Archiver.new(self)
+        @yacc = Command::Yacc.new(self)
+        @gperf = Command::Gperf.new(self)
+        @git = Command::Git.new(self)
+        @mrbc = Command::Mrbc.new(self)
+
+        @bins = []
+        @gems, @libmruby = MRuby::Gem::List.new, []
+        @build_mrbtest_lib_only = false
+        @cxx_exception_enabled = false
+        @cxx_exception_disabled = false
+        @cxx_abi_enabled = false
+        @enable_bintest = false
+        @enable_test = false
+        @toolchains = []
+
+        MRuby.targets[@name] = self
+      end
+
+      MRuby::Build.current = MRuby.targets[@name]
+      MRuby.targets[@name].instance_eval(&block)
+
+      build_mrbc_exec if name == 'host'
+      build_mrbtest if test_enabled?
+    end
+
+    def enable_debug
+      compilers.each do |c|
+        c.defines += %w(MRB_DEBUG)
+        if toolchains.any? { |toolchain| toolchain == "gcc" }
+          c.flags += %w(-g3 -O0)
+        end
+      end
+      @mrbc.compile_options += ' -g'
+    end
+
+    def disable_cxx_exception
+      if @cxx_exception_enabled or @cxx_abi_enabled
+        raise "cxx_exception already enabled"
+      end
+      @cxx_exception_disabled = true
+    end
+
+    def enable_cxx_exception
+      return if @cxx_exception_enabled
+      return if @cxx_abi_enabled
+      if @cxx_exception_disabled
+        raise "cxx_exception disabled"
+      end
+      @cxx_exception_enabled = true
+      compilers.each { |c|
+        c.defines += %w(MRB_ENABLE_CXX_EXCEPTION)
+        c.flags << c.cxx_exception_flag
+      }
+      linker.command = cxx.command if toolchains.find { |v| v == 'gcc' }
+    end
+
+    def cxx_exception_enabled?
+      @cxx_exception_enabled
+    end
+
+    def cxx_abi_enabled?
+      @cxx_abi_enabled
+    end
+
+    def enable_cxx_abi
+      return if @cxx_abi_enabled
+      if @cxx_exception_enabled
+        raise "cxx_exception already enabled"
+      end
+      compilers.each { |c|
+        c.defines += %w(MRB_ENABLE_CXX_EXCEPTION MRB_ENABLE_CXX_ABI)
+        c.flags << c.cxx_compile_flag
+      }
+      compilers.each { |c| c.flags << c.cxx_compile_flag }
+      linker.command = cxx.command if toolchains.find { |v| v == 'gcc' }
+      @cxx_abi_enabled = true
+    end
+
+    def compile_as_cxx src, cxx_src, obj = nil, includes = []
+      src = File.absolute_path src
+      cxx_src = File.absolute_path cxx_src
+      obj = objfile(cxx_src) if obj.nil?
+
+      file cxx_src => [src, __FILE__] do |t|
+        FileUtils.mkdir_p File.dirname t.name
+        IO.write t.name, <<EOS
+#define __STDC_CONSTANT_MACROS
+#define __STDC_LIMIT_MACROS
+
+#ifndef MRB_ENABLE_CXX_ABI
+extern "C" {
+#endif
+#include "#{src}"
+#ifndef MRB_ENABLE_CXX_ABI
+}
+#endif
+EOS
+      end
+
+      file obj => cxx_src do |t|
+        cxx.run t.name, t.prerequisites.first, [], ["#{MRUBY_ROOT}/src"] + includes
+      end
+
+      obj
+    end
+
+    def enable_bintest
+      @enable_bintest = true
+    end
+
+    def bintest_enabled?
+      @enable_bintest
+    end
+
+    def toolchain(name, params={})
+      tc = Toolchain.toolchains[name.to_s]
+      fail "Unknown #{name} toolchain" unless tc
+      tc.setup(self, params)
+      @toolchains.unshift name.to_s
+    end
+
+    def primary_toolchain
+      @toolchains.first
+    end
+
+    def root
+      MRUBY_ROOT
+    end
+
+    def enable_test
+      @enable_test = true
+    end
+
+    def test_enabled?
+      @enable_test
+    end
+
+    def build_mrbtest
+      gem :core => 'mruby-test'
+    end
+
+    def build_mrbc_exec
+      gem :core => 'mruby-bin-mrbc'
+    end
+
+    def mrbcfile
+      return @mrbcfile if @mrbcfile
+
+      mrbc_build = MRuby.targets['host']
+      gems.each { |v| mrbc_build = self if v.name == 'mruby-bin-mrbc' }
+      @mrbcfile = mrbc_build.exefile("#{mrbc_build.build_dir}/bin/mrbc")
+    end
+
+    def compilers
+      COMPILERS.map do |c|
+        instance_variable_get("@#{c}")
+      end
+    end
+
+    def define_rules
+      compilers.each do |compiler|
+        if respond_to?(:enable_gems?) && enable_gems?
+          compiler.defines -= %w(DISABLE_GEMS)
+        else
+          compiler.defines += %w(DISABLE_GEMS)
+        end
+        compiler.define_rules build_dir, File.expand_path(File.join(File.dirname(__FILE__), '..'))
+      end
+    end
+
+    def filename(name)
+      if name.is_a?(Array)
+        name.flatten.map { |n| filename(n) }
+      else
+        '"%s"' % name.gsub('/', file_separator)
+      end
+    end
+
+    def cygwin_filename(name)
+      if name.is_a?(Array)
+        name.flatten.map { |n| cygwin_filename(n) }
+      else
+        '"%s"' % `cygpath -w "#{filename(name)}"`.strip
+      end
+    end
+
+    def exefile(name)
+      if name.is_a?(Array)
+        name.flatten.map { |n| exefile(n) }
+      else
+        "#{name}#{exts.executable}"
+      end
+    end
+
+    def objfile(name)
+      if name.is_a?(Array)
+        name.flatten.map { |n| objfile(n) }
+      else
+        "#{name}#{exts.object}"
+      end
+    end
+
+    def libfile(name)
+      if name.is_a?(Array)
+        name.flatten.map { |n| libfile(n) }
+      else
+        "#{name}#{exts.library}"
+      end
+    end
+
+    def build_mrbtest_lib_only
+      @build_mrbtest_lib_only = true
+    end
+
+    def build_mrbtest_lib_only?
+      @build_mrbtest_lib_only
+    end
+
+    def run_test
+      puts ">>> Test #{name} <<<"
+      mrbtest = exefile("#{build_dir}/bin/mrbtest")
+      sh "#{filename mrbtest.relative_path}#{$verbose ? ' -v' : ''}"
+      puts
+      run_bintest if bintest_enabled?
+    end
+
+    def run_bintest
+      targets = @gems.select { |v| File.directory? "#{v.dir}/bintest" }.map { |v| filename v.dir }
+      targets << filename(".") if File.directory? "./bintest"
+      sh "ruby test/bintest.rb #{targets.join ' '}"
+    end
+
+    def print_build_summary
+      puts "================================================"
+      puts "      Config Name: #{@name}"
+      puts " Output Directory: #{self.build_dir.relative_path}"
+      puts "         Binaries: #{@bins.join(', ')}" unless @bins.empty?
+      unless @gems.empty?
+        puts "    Included Gems:"
+        @gems.map do |gem|
+          gem_version = " - #{gem.version}" if gem.version != '0.0.0'
+          gem_summary = " - #{gem.summary}" if gem.summary
+          puts "             #{gem.name}#{gem_version}#{gem_summary}"
+          puts "               - Binaries: #{gem.bins.join(', ')}" unless gem.bins.empty?
+        end
+      end
+      puts "================================================"
+      puts
+    end
+  end # Build
+
+  class CrossBuild < Build
+    attr_block %w(test_runner)
+    # cross compiling targets for building native extensions.
+    # host  - arch of where the built binary will run
+    # build - arch of the machine building the binary
+    attr_accessor :host_target, :build_target
+
+    def initialize(name, build_dir=nil, &block)
+      @test_runner = Command::CrossTestRunner.new(self)
+      super
+    end
+
+    def mrbcfile
+      MRuby.targets['host'].exefile("#{MRuby.targets['host'].build_dir}/bin/mrbc")
+    end
+
+    def run_test
+      mrbtest = exefile("#{build_dir}/bin/mrbtest")
+      if (@test_runner.command == nil)
+        puts "You should run #{mrbtest} on target device."
+        puts
+      else
+        @test_runner.run(mrbtest)
+      end
+    end
+  end # CrossBuild
+end # MRuby
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/mruby_build_commands.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/tasks/mruby_build_commands.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/mruby_build_commands.rake	(revision 331)
@@ -0,0 +1,358 @@
+require 'forwardable'
+require 'digest/md5'
+
+module MRuby
+  class Command
+    include Rake::DSL
+    extend Forwardable
+    def_delegators :@build, :filename, :objfile, :libfile, :exefile, :cygwin_filename
+    attr_accessor :build, :command
+
+    def initialize(build)
+      @build = build
+    end
+
+    # clone is deep clone without @build
+    def clone
+      target = super
+      excepts = %w(@build)
+      instance_variables.each do |attr|
+        unless excepts.include?(attr.to_s)
+          val = Marshal::load(Marshal.dump(instance_variable_get(attr))) # deep clone
+          target.instance_variable_set(attr, val)
+        end
+      end
+      target
+    end
+
+    NotFoundCommands = {}
+
+    private
+    def _run(options, params={})
+      return sh command + ' ' + ( options % params ) if NotFoundCommands.key? @command
+      begin
+        sh build.filename(command) + ' ' + ( options % params )
+      rescue RuntimeError
+        NotFoundCommands[@command] = true
+        _run options, params
+      end
+    end
+  end
+
+  class Command::Compiler < Command
+    attr_accessor :flags, :include_paths, :defines, :source_exts
+    attr_accessor :compile_options, :option_define, :option_include_path, :out_ext
+    attr_accessor :cxx_compile_flag, :cxx_exception_flag
+
+    def initialize(build, source_exts=[])
+      super(build)
+      @command = ENV['CC'] || 'cc'
+      @flags = [ENV['CFLAGS'] || []]
+      @source_exts = source_exts
+      @include_paths = ["#{MRUBY_ROOT}/include"]
+      @defines = %w()
+      @option_include_path = '-I%s'
+      @option_define = '-D%s'
+      @compile_options = '%{flags} -o %{outfile} -c %{infile}'
+    end
+
+    alias header_search_paths include_paths
+    def search_header_path(name)
+      header_search_paths.find do |v|
+        File.exist? build.filename("#{v}/#{name}").sub(/^"(.*)"$/, '\1')
+      end
+    end
+
+    def search_header(name)
+      path = search_header_path name
+      path && build.filename("#{path}/#{name}").sub(/^"(.*)"$/, '\1')
+    end
+
+    def all_flags(_defineds=[], _include_paths=[], _flags=[])
+      define_flags = [defines, _defineds].flatten.map{ |d| option_define % d }
+      include_path_flags = [include_paths, _include_paths].flatten.map do |f|
+        if MRUBY_BUILD_HOST_IS_CYGWIN
+          option_include_path % cygwin_filename(f)
+        else
+          option_include_path % filename(f)
+        end
+      end
+      [flags, define_flags, include_path_flags, _flags].flatten.join(' ')
+    end
+
+    def run(outfile, infile, _defineds=[], _include_paths=[], _flags=[])
+      FileUtils.mkdir_p File.dirname(outfile)
+      _pp "CC", infile.relative_path, outfile.relative_path
+      if MRUBY_BUILD_HOST_IS_CYGWIN
+        _run compile_options, { :flags => all_flags(_defineds, _include_paths, _flags),
+                                :infile => cygwin_filename(infile), :outfile => cygwin_filename(outfile),
+                                :outdir => File.dirname(outfile), :outfilebase => File.basename(outfile, ".*") }
+      else
+        _run compile_options, { :flags => all_flags(_defineds, _include_paths, _flags),
+                                :infile => filename(infile), :outfile => filename(outfile),
+                                :outdir => File.dirname(outfile), :outfilebase => File.basename(outfile, ".*") }
+      end
+    end
+
+    def define_rules(build_dir, source_dir='')
+      @out_ext = build.exts.object
+      gemrake = File.join(source_dir, "mrbgem.rake")
+      rakedep = File.exist?(gemrake) ? [ gemrake ] : []
+
+      if build_dir.include? "mrbgems/"
+        generated_file_matcher = Regexp.new("^#{Regexp.escape build_dir}/(.*)#{Regexp.escape out_ext}$")
+      else
+        generated_file_matcher = Regexp.new("^#{Regexp.escape build_dir}/(?!mrbgems/.+/)(.*)#{Regexp.escape out_ext}$")
+      end
+      source_exts.each do |ext, compile|
+        rule generated_file_matcher => [
+          proc { |file|
+            file.sub(generated_file_matcher, "#{source_dir}/\\1#{ext}")
+          },
+          proc { |file|
+            get_dependencies(file) + rakedep
+          }
+        ] do |t|
+          run t.name, t.prerequisites.first
+        end
+
+        rule generated_file_matcher => [
+          proc { |file|
+            file.sub(generated_file_matcher, "#{build_dir}/\\1#{ext}")
+          },
+          proc { |file|
+            get_dependencies(file) + rakedep
+          }
+        ] do |t|
+          run t.name, t.prerequisites.first
+        end
+      end
+    end
+
+    private
+    def get_dependencies(file)
+      file = file.ext('d') unless File.extname(file) == '.d'
+      if File.exist?(file)
+        File.read(file).gsub("\\\n ", "").scan(/^\S+:\s+(.+)$/).flatten.map {|s| s.split(' ') }.flatten
+      else
+        []
+      end + [ MRUBY_CONFIG ]
+    end
+  end
+
+  class Command::Linker < Command
+    attr_accessor :flags, :library_paths, :flags_before_libraries, :libraries, :flags_after_libraries
+    attr_accessor :link_options, :option_library, :option_library_path
+
+    def initialize(build)
+      super
+      @command = ENV['LD'] || 'ld'
+      @flags = (ENV['LDFLAGS'] || [])
+      @flags_before_libraries, @flags_after_libraries = [], []
+      @libraries = []
+      @library_paths = []
+      @option_library = '-l%s'
+      @option_library_path = '-L%s'
+      @link_options = "%{flags} -o %{outfile} %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}"
+    end
+
+    def all_flags(_library_paths=[], _flags=[])
+      library_path_flags = [library_paths, _library_paths].flatten.map do |f|
+        if MRUBY_BUILD_HOST_IS_CYGWIN
+          option_library_path % cygwin_filename(f)
+        else
+          option_library_path % filename(f)
+        end
+      end
+      [flags, library_path_flags, _flags].flatten.join(' ')
+    end
+
+    def library_flags(_libraries)
+      [libraries, _libraries].flatten.map{ |d| option_library % d }.join(' ')
+    end
+
+    def run(outfile, objfiles, _libraries=[], _library_paths=[], _flags=[], _flags_before_libraries=[], _flags_after_libraries=[])
+      FileUtils.mkdir_p File.dirname(outfile)
+      library_flags = [libraries, _libraries].flatten.map { |d| option_library % d }
+
+      _pp "LD", outfile.relative_path
+      if MRUBY_BUILD_HOST_IS_CYGWIN
+        _run link_options, { :flags => all_flags(_library_paths, _flags),
+                             :outfile => cygwin_filename(outfile) , :objs => cygwin_filename(objfiles).join(' '),
+                             :flags_before_libraries => [flags_before_libraries, _flags_before_libraries].flatten.join(' '),
+                             :flags_after_libraries => [flags_after_libraries, _flags_after_libraries].flatten.join(' '),
+                             :libs => library_flags.join(' '),
+                             :outdir => File.dirname(outfile), :outfilebase => File.basename(outfile, ".*") }
+      else
+        _run link_options, { :flags => all_flags(_library_paths, _flags),
+                             :outfile => filename(outfile) , :objs => filename(objfiles).join(' '),
+                             :flags_before_libraries => [flags_before_libraries, _flags_before_libraries].flatten.join(' '),
+                             :flags_after_libraries => [flags_after_libraries, _flags_after_libraries].flatten.join(' '),
+                             :libs => library_flags.join(' '),
+                             :outdir => File.dirname(outfile), :outfilebase => File.basename(outfile, ".*") }
+      end
+    end
+  end
+
+  class Command::Archiver < Command
+    attr_accessor :archive_options
+
+    def initialize(build)
+      super
+      @command = ENV['AR'] || 'ar'
+      @archive_options = 'rs %{outfile} %{objs}'
+    end
+
+    def run(outfile, objfiles)
+      FileUtils.mkdir_p File.dirname(outfile)
+      _pp "AR", outfile.relative_path
+
+      # reference from emar.py
+      outfilebase = File.dirname(outfile)
+      to_delete = []
+      newargs = []
+      objfiles.each do |orig_name|
+        dir_name = File.dirname(orig_name)
+        dir_name = dir_name.relative_path_from(Dir.pwd)
+        base_name = File.basename(orig_name)
+        parts = base_name.split('.')
+        # h = Digest::MD5.new.update(orig_name).to_s
+        h = Digest::MD5.new.update(orig_name).to_s.slice(0,4)
+        parts[0] += '_' + h
+        newname = parts.join('.')
+        full_newname = File.join(dir_name, newname)
+        if not File.exists?(full_newname)
+          begin # it is ok to fail here, we just don't get hashing
+            FileUtils.cp(orig_name, full_newname)
+            newargs << full_newname
+            to_delete << full_newname
+          rescue
+          end
+        end
+      end
+
+      if MRUBY_BUILD_HOST_IS_CYGWIN
+        _run archive_options, { :outfile => cygwin_filename(outfile), :objs => cygwin_filename(newargs).join(' '), :outdir => File.dirname(outfile), :outfilebase => File.basename(outfile, ".*") }
+      else
+        _run archive_options, { :outfile => filename(outfile), :objs => filename(newargs).join(' '), :outdir => File.dirname(outfile), :outfilebase => File.basename(outfile, ".*") }
+      end
+
+      to_delete.each do |d|
+        FileUtils.rm(d)
+      end
+    end
+  end
+
+  class Command::Yacc < Command
+    attr_accessor :compile_options
+
+    def initialize(build)
+      super
+      @command = 'bison'
+      @compile_options = '-o %{outfile} %{infile}'
+    end
+
+    def run(outfile, infile)
+      FileUtils.mkdir_p File.dirname(outfile)
+      _pp "YACC", infile.relative_path, outfile.relative_path
+      _run compile_options, { :outfile => filename(outfile) , :infile => filename(infile) }
+    end
+  end
+
+  class Command::Gperf < Command
+    attr_accessor :compile_options
+
+    def initialize(build)
+      super
+      @command = 'gperf'
+      @compile_options = '-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" %{infile} > %{outfile}'
+    end
+
+    def run(outfile, infile)
+      FileUtils.mkdir_p File.dirname(outfile)
+      _pp "GPERF", infile.relative_path, outfile.relative_path
+      _run compile_options, { :outfile => filename(outfile) , :infile => filename(infile) }
+    end
+  end
+
+  class Command::Git < Command
+    attr_accessor :flags
+    attr_accessor :clone_options, :pull_options, :checkout_options
+
+    def initialize(build)
+      super
+      @command = 'git'
+      @flags = %w[]
+      @clone_options = "clone %{flags} %{url} %{dir}"
+      @pull_options = "pull"
+      @checkout_options = "checkout %{checksum_hash}"
+    end
+
+    def run_clone(dir, url, _flags = [])
+      _pp "GIT", url, dir.relative_path
+      _run clone_options, { :flags => [flags, _flags].flatten.join(' '), :url => url, :dir => filename(dir) }
+    end
+
+    def run_pull(dir, url)
+      root = Dir.pwd
+      Dir.chdir dir
+      _pp "GIT PULL", url, dir.relative_path
+      _run pull_options
+      Dir.chdir root
+    end
+
+    def run_checkout(dir, checksum_hash)
+      root = Dir.pwd
+      Dir.chdir dir
+      _pp "GIT CHECKOUT", checksum_hash
+      _run checkout_options, { :checksum_hash => checksum_hash }
+      Dir.chdir root
+    end
+  end
+
+  class Command::Mrbc < Command
+    attr_accessor :compile_options
+
+    def initialize(build)
+      super
+      @command = nil
+      @compile_options = "-B%{funcname} -o-"
+    end
+
+    def run(out, infiles, funcname)
+      @command ||= @build.mrbcfile
+      infiles = [infiles].flatten
+      infiles.each do |f|
+        _pp "MRBC", f.relative_path, nil, :indent => 2
+      end
+      IO.popen("#{filename @command} #{@compile_options % {:funcname => funcname}} #{filename(infiles).join(' ')}", 'r+') do |io|
+        out.puts io.read
+      end
+      # if mrbc execution fail, drop the file
+      if $?.exitstatus != 0
+        File.delete(out.path)
+        exit(-1)
+      end
+    end
+  end
+
+  class Command::CrossTestRunner < Command
+    attr_accessor :runner_options
+    attr_accessor :verbose_flag
+    attr_accessor :flags
+
+    def initialize(build)
+      super
+      @command = nil
+      @runner_options = '%{flags} %{infile}'
+      @verbose_flag = ''
+      @flags = []
+    end
+
+    def run(testbinfile)
+      puts "TEST for " + @build.name
+      _run runner_options, { :flags => [flags, verbose_flag].flatten.join(' '), :infile => testbinfile }
+    end
+  end
+
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/mruby_build_gem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/tasks/mruby_build_gem.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/mruby_build_gem.rake	(revision 331)
@@ -0,0 +1,122 @@
+module MRuby
+  module LoadGems
+    def gembox(gemboxfile)
+      gembox = File.expand_path("#{gemboxfile}.gembox", "#{MRUBY_ROOT}/mrbgems")
+      fail "Can't find gembox '#{gembox}'" unless File.exist?(gembox)
+
+      GemBox.config = self
+      GemBox.path = gembox
+
+      instance_eval File.read(gembox)
+
+      GemBox.path = nil
+    end
+
+    def gem(gemdir, &block)
+      caller_dir = File.expand_path(File.dirname(/^(.*?):\d/.match(caller.first).to_a[1]))
+
+      if gemdir.is_a?(Hash)
+        gemdir = load_special_path_gem(gemdir)
+      elsif GemBox.path && gemdir.is_a?(String)
+        gemdir = File.expand_path(gemdir, File.dirname(GemBox.path))
+      else
+        gemdir = File.expand_path(gemdir, caller_dir)
+      end
+
+      gemrake = File.join(gemdir, "mrbgem.rake")
+
+      fail "Can't find #{gemrake}" unless File.exist?(gemrake)
+      Gem.current = nil
+      load gemrake
+      return nil unless Gem.current
+
+      Gem.current.dir = gemdir
+      Gem.current.build = self.is_a?(MRuby::Build) ? self : MRuby::Build.current
+      Gem.current.build_config_initializer = block
+      gems << Gem.current
+
+      cxx_srcs = ['src', 'test', 'tools'].map do |subdir|
+        Dir.glob("#{Gem.current.dir}/#{subdir}/*.{cpp,cxx,cc}")
+      end.flatten
+      enable_cxx_exception unless cxx_srcs.empty?
+
+      Gem.current
+    end
+
+    def load_special_path_gem(params)
+      if params[:github]
+        params[:git] = "https://github.com/#{params[:github]}.git"
+      elsif params[:bitbucket]
+        if params[:method] == "ssh"
+          params[:git] = "git@bitbucket.org:#{params[:bitbucket]}.git"
+        else
+          params[:git] = "https://bitbucket.org/#{params[:bitbucket]}.git"
+        end
+      elsif params[:mgem]
+        mgem_list_dir = "#{gem_clone_dir}/mgem-list"
+        mgem_list_url = 'https://github.com/mruby/mgem-list.git'
+        if File.exist? mgem_list_dir
+          git.run_pull mgem_list_dir, mgem_list_url if $pull_gems
+        else
+          FileUtils.mkdir_p mgem_list_dir
+          git.run_clone mgem_list_dir, mgem_list_url, "--depth 1"
+        end
+
+        require 'yaml'
+
+        conf_path = "#{mgem_list_dir}/#{params[:mgem]}.gem"
+        conf_path = "#{mgem_list_dir}/mruby-#{params[:mgem]}.gem" unless File.exist? conf_path
+        fail "mgem not found: #{params[:mgem]}" unless File.exist? conf_path
+        conf = YAML.load File.read conf_path
+
+        fail "unknown mgem protocol: #{conf['protocol']}" if conf['protocol'] != 'git'
+        params[:git] = conf['repository']
+        params[:branch] = conf['branch'] if conf['branch']
+      end
+
+      if params[:core]
+        gemdir = "#{root}/mrbgems/#{params[:core]}"
+      elsif params[:path]
+        require 'pathname'
+        gemdir = Pathname.new(params[:path]).absolute? ? params[:path] : "#{root}/#{params[:path]}"
+      elsif params[:git]
+        url = params[:git]
+        gemdir = "#{gem_clone_dir}/#{url.match(/([-\w]+)(\.[-\w]+|)$/).to_a[1]}"
+
+        # by default the 'master' branch is used
+        branch = params[:branch] ? params[:branch] : 'master'
+
+        if File.exist?(gemdir)
+          if $pull_gems
+            git.run_pull gemdir, url
+          else
+            gemdir
+          end
+        else
+          options = [params[:options]] || []
+          options << "--recursive"
+          options << "--branch \"#{branch}\""
+          options << "--depth 1" unless params[:checksum_hash]
+          FileUtils.mkdir_p "#{gem_clone_dir}"
+          git.run_clone gemdir, url, options
+        end
+
+        if params[:checksum_hash]
+          # Jump to the specified commit
+          git.run_checkout gemdir, params[:checksum_hash]
+        else
+          # Jump to the top of the branch
+          git.run_checkout gemdir, branch if $pull_gems
+        end
+      else
+        fail "unknown gem option #{params}"
+      end
+
+      gemdir
+    end
+
+    def enable_gems?
+      !@gems.empty?
+    end
+  end # LoadGems
+end # MRuby
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/ruby_ext.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/tasks/ruby_ext.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/ruby_ext.rake	(revision 331)
@@ -0,0 +1,79 @@
+class Object
+  class << self
+    def attr_block(*syms)
+      syms.flatten.each do |sym|
+        class_eval "def #{sym}(&block);block.call(@#{sym}) if block_given?;@#{sym};end"
+      end
+    end
+  end
+end
+
+class String
+  def relative_path_from(dir)
+    Pathname.new(File.expand_path(self)).relative_path_from(Pathname.new(File.expand_path(dir))).to_s
+  end
+
+  def relative_path
+    relative_path_from(Dir.pwd)
+  end
+
+  # Compatible with 1.9 on 1.8
+  def %(params)
+    if params.is_a?(Hash)
+      str = self.clone
+      params.each do |k, v|
+        str.gsub!("%{#{k}}") { v }
+      end
+      str
+    else
+      if params.is_a?(Array)
+        sprintf(self, *params)
+      else
+        sprintf(self, params)
+      end
+    end
+  end
+end
+
+class Symbol
+  # Compatible with 1.9 on 1.8
+  def to_proc
+    proc { |obj, *args| obj.send(self, *args) }
+  end
+end
+
+module Enumerable
+  # Compatible with 1.9 on 1.8
+  def each_with_object(memo)
+    return to_enum :each_with_object, memo unless block_given?
+    each { |obj| yield obj, memo }
+    memo
+  end
+end
+
+$pp_show = true
+
+if $verbose.nil?
+  if Rake.respond_to?(:verbose) && !Rake.verbose.nil?
+    if Rake.verbose.class == TrueClass
+      # verbose message logging
+      $pp_show = false
+    else
+      $pp_show = true
+      Rake.verbose(false)
+    end
+  else
+    # could not identify rake version
+    $pp_show = false
+  end
+else
+  $pp_show = false if $verbose
+end
+
+def _pp(cmd, src, tgt=nil, options={})
+  return unless $pp_show
+
+  width = 5
+  template = options[:indent] ? "%#{width*options[:indent]}s %s %s" : "%-#{width}s %s %s"
+  puts template % [cmd, src, tgt ? "-> #{tgt}" : nil]
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/android.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/android.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/android.rake	(revision 331)
@@ -0,0 +1,321 @@
+class MRuby::Toolchain::Android
+
+  DEFAULT_ARCH = 'armeabi' # TODO : Revise if arch should have a default
+
+  DEFAULT_TOOLCHAIN = :clang
+
+  DEFAULT_NDK_HOMES = %w{
+    /usr/local/opt/android-sdk/ndk-bundle
+    /usr/local/opt/android-ndk
+    %LOCALAPPDATA%/Android/android-sdk/ndk-bundle
+    %LOCALAPPDATA%/Android/android-ndk
+    ~/Library/Android/sdk/ndk-bundle
+    ~/Library/Android/ndk
+  }
+
+  TOOLCHAINS = [:clang, :gcc]
+
+  ARCHITECTURES = %w{
+    armeabi armeabi-v7a arm64-v8a
+    x86 x86_64
+    mips mips64
+  }
+
+  class AndroidNDKHomeNotFound < StandardError
+    def message
+        <<-EOM
+Couldn't find Android NDK Home.
+Set ANDROID_NDK_HOME environment variable or set :ndk_home parameter
+        EOM
+    end
+  end
+
+  class PlatformDirNotFound < StandardError
+    def message
+        <<-EOM
+Couldn't find Android NDK platform directories.
+Set ANDROID_PLATFORM environment variable or set :platform parameter
+        EOM
+    end
+  end
+
+  attr_reader :params
+
+  def initialize(params)
+    @params = params
+  end
+
+  def bin_gcc(command)
+    command = command.to_s
+
+    command = case arch
+      when /armeabi/    then 'arm-linux-androideabi-'
+      when /arm64-v8a/  then 'aarch64-linux-android-'
+      when /x86_64/     then 'x86_64-linux-android-'
+      when /x86/        then 'i686-linux-android-'
+      when /mips64/     then 'mips64el-linux-android-'
+      when /mips/       then 'mipsel-linux-android-'
+      end + command
+
+    gcc_toolchain_path.join('bin', command).to_s
+  end
+
+  def bin(command)
+    command = command.to_s
+    toolchain_path.join('bin', command).to_s
+  end
+
+  def home_path
+    @home_path ||= Pathname(
+      params[:ndk_home] ||
+      ENV['ANDROID_NDK_HOME'] ||
+      DEFAULT_NDK_HOMES.find { |path|
+        path.gsub! '%LOCALAPPDATA%', ENV['LOCALAPPDATA'] || '%LOCALAPPDATA%'
+        path.gsub! '\\', '/'
+        path.gsub! '~', Dir.home || '~'
+        File.directory?(path)
+      } || raise(AndroidNDKHomeNotFound)
+    )
+  end
+
+  def toolchain
+    @toolchain ||= params.fetch(:toolchain){ DEFAULT_TOOLCHAIN }
+  end
+
+  def toolchain_path
+    @toolchain_path ||= case toolchain
+      when :gcc
+        gcc_toolchain_path
+      when :clang
+        home_path.join('toolchains', 'llvm' , 'prebuilt', host_platform)
+      end
+  end
+
+  def gcc_toolchain_path
+    if @gcc_toolchain_path === nil then
+      prefix = case arch
+        when /armeabi/    then 'arm-linux-androideabi-'
+        when /arm64-v8a/  then 'aarch64-linux-android-'
+        when /x86_64/     then 'x86_64-'
+        when /x86/        then 'x86-'
+        when /mips64/     then 'mips64el-linux-android-'
+        when /mips/       then 'mipsel-linux-android-'
+        end
+
+      test = case arch
+        when /armeabi/    then 'arm-linux-androideabi-*'
+        when /arm64-v8a/  then 'aarch64-linux-android-*'
+        when /x86_64/     then 'x86_64-*'
+        when /x86/        then 'x86-*'
+        when /mips64/     then 'mips64el-linux-android-*'
+        when /mips/       then 'mipsel-linux-android-*'
+        end
+
+      gcc_toolchain_version = Dir[home_path.join('toolchains', test)].map{|t| t.match(/-(\d+\.\d+)$/); $1.to_f }.max
+      @gcc_toolchain_path = home_path.join('toolchains', prefix + gcc_toolchain_version.to_s, 'prebuilt', host_platform)
+    end
+    @gcc_toolchain_path
+  end
+
+  def host_platform
+    @host_platform ||= case RUBY_PLATFORM
+      when /cygwin|mswin|mingw|bccwin|wince|emx/i
+        path = home_path.join('toolchains', 'llvm' , 'prebuilt', 'windows*')
+        Dir.glob(path.to_s){ |item|
+          next if File.file?(item)
+          path = Pathname(item)
+          break
+        }
+        path.basename
+      when /x86_64-darwin/i
+        'darwin-x86_64'
+      when /darwin/i
+        'darwin-x86'
+      when /x86_64-linux/i
+        'linux-x86_64'
+      when /linux/i
+        'linux-x86'
+      else
+        raise NotImplementedError, "Unknown host platform (#{RUBY_PLATFORM})"
+      end
+  end
+
+  def arch
+    @arch ||= (params[:arch] || ENV['ANDROID_ARCH'] || DEFAULT_ARCH).to_s
+  end
+
+  def sysroot
+    @sysroot ||= home_path.join('platforms', platform,
+        case arch
+        when /armeabi/    then 'arch-arm'
+        when /arm64-v8a/  then 'arch-arm64'
+        when /x86_64/     then 'arch-x86_64'
+        when /x86/        then 'arch-x86'
+        when /mips64/     then 'arch-mips64'
+        when /mips/       then 'arch-mips'
+        end
+      ).to_s
+  end
+
+  def platform
+    if @platform === nil then
+      @platform = params[:platform] || ENV['ANDROID_PLATFORM'] || nil
+      if @platform === nil
+        Dir.glob(home_path.join('platforms/android-*').to_s){ |item|
+          next if File.file?(item)
+          if @platform === nil
+            @platform = Integer(item.rpartition('-')[2])
+          else
+            platform = Integer(item.rpartition('-')[2])
+            @platform = platform > @platform ? platform : @platform
+          end
+        }
+        if @platform === nil
+          raise(PlatformDirNotFound)
+        else
+          @platform = "android-#{@platform}"
+        end
+      end
+    end
+    if Integer(@platform.rpartition('-')[2]) < 21
+      case arch
+      when /arm64-v8a/, /x86_64/, /mips64/
+        raise NotImplementedError, "Platform (#{@platform}) has no implementation for architecture (#{arch})"
+      end
+    end
+    @platform
+  end
+
+  def armeabi_v7a_mfpu
+    @armeabi_v7a_mfpu ||= (params[:mfpu] || 'vfpv3-d16').to_s
+  end
+
+  def armeabi_v7a_mfloat_abi
+    @armeabi_v7a_mfloat_abi ||= (params[:mfloat_abi] || 'softfp').to_s
+  end
+
+  def no_warn_mismatch
+    if %W(soft softfp).include? armeabi_v7a_mfloat_abi
+      ''
+    else
+      ',--no-warn-mismatch'
+    end
+  end
+
+  def cc
+    case toolchain
+    when :gcc then bin_gcc('gcc')
+    when :clang then bin('clang')
+    end
+  end
+
+  def ar
+    case toolchain
+    when :gcc   then bin_gcc('ar')
+    when :clang then bin_gcc('ar')
+    end
+  end
+
+  def ctarget
+    flags = []
+
+    case toolchain
+    when :gcc
+      case arch
+      when /armeabi-v7a/  then flags += %W(-march=armv7-a)
+      when /armeabi/      then flags += %W(-march=armv5te)
+      when /arm64-v8a/    then flags += %W(-march=armv8-a)
+      when /x86_64/       then flags += %W(-march=x86-64)
+      when /x86/          then flags += %W(-march=i686)
+      when /mips64/       then flags += %W(-march=mips64r6)
+      when /mips/         then flags += %W(-march=mips32)
+      end
+    when :clang
+      case arch
+      when /armeabi-v7a/  then flags += %W(-target armv7-none-linux-androideabi)
+      when /armeabi/      then flags += %W(-target armv5te-none-linux-androideabi)
+      when /arm64-v8a/    then flags += %W(-target aarch64-none-linux-android)
+      when /x86_64/       then flags += %W(-target x86_64-none-linux-android)
+      when /x86/          then flags += %W(-target i686-none-linux-android)
+      when /mips64/       then flags += %W(-target mips64el-none-linux-android)
+      when /mips/         then flags += %W(-target mipsel-none-linux-android)
+      end
+    end
+
+    case arch
+    when /armeabi-v7a/  then flags += %W(-mfpu=#{armeabi_v7a_mfpu} -mfloat-abi=#{armeabi_v7a_mfloat_abi})
+    when /armeabi/      then flags += %W(-mtune=xscale -msoft-float)
+    when /arm64-v8a/    then flags += %W()
+    when /x86_64/       then flags += %W()
+    when /x86/          then flags += %W()
+    when /mips64/       then flags += %W(-fmessage-length=0)
+    when /mips/         then flags += %W(-fmessage-length=0)
+    end
+
+    flags
+  end
+
+  def cflags
+    flags = []
+
+    flags += %W(-MMD -MP -D__android__ -DANDROID --sysroot="#{sysroot}")
+    flags += ctarget
+    case toolchain
+    when :gcc
+    when :clang
+      flags += %W(-gcc-toolchain "#{gcc_toolchain_path.to_s}" -Wno-invalid-command-line-argument -Wno-unused-command-line-argument)
+    end
+    flags += %W(-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes)
+
+    flags
+  end
+
+  def ldflags
+    flags = []
+
+    flags += %W(--sysroot="#{sysroot}")
+
+    flags
+  end
+
+  def ldflags_before_libraries
+    flags = []
+
+    case toolchain
+    when :gcc
+      case arch
+      when /armeabi-v7a/  then flags += %W(-Wl#{no_warn_mismatch})
+      end
+    when :clang
+      flags += %W(-gcc-toolchain "#{gcc_toolchain_path.to_s}")
+      case arch
+      when /armeabi-v7a/  then flags += %W(-target armv7-none-linux-androideabi -Wl,--fix-cortex-a8#{no_warn_mismatch})
+      when /armeabi/      then flags += %W(-target armv5te-none-linux-androideabi)
+      when /arm64-v8a/    then flags += %W(-target aarch64-none-linux-android)
+      when /x86_64/       then flags += %W(-target x86_64-none-linux-android)
+      when /x86/          then flags += %W(-target i686-none-linux-android)
+      when /mips64/       then flags += %W(-target mips64el-none-linux-android)
+      when /mips/         then flags += %W(-target mipsel-none-linux-android)
+      end
+    end
+    flags += %W(-no-canonical-prefixes)
+
+    flags
+  end
+end
+
+MRuby::Toolchain.new(:android) do |conf, params|
+  android = MRuby::Toolchain::Android.new(params)
+
+  toolchain android.toolchain
+
+  [conf.cc, conf.cxx, conf.objc, conf.asm].each do |cc|
+    cc.command = android.cc
+    cc.flags = android.cflags
+  end
+
+  conf.archiver.command = android.ar
+  conf.linker.command = android.cc
+  conf.linker.flags = android.ldflags
+  conf.linker.flags_before_libraries = android.ldflags_before_libraries
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/ca850.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/ca850.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/ca850.rake	(revision 331)
@@ -0,0 +1,45 @@
+MRuby::Toolchain.new(:ca850) do |conf|
+  [conf.cc, conf.cxx].each do |cc|
+    cc.command = ENV['CC'] || 'ca850.exe'
+    cc.flags = [ENV['CFLAGS'] || %w(-c -g -Xcxxcom -Xdefvar -Xpro_epi_runtime=off)]
+    cc.include_paths = ["#{MRUBY_ROOT}\\include", "#{MRUBY_ROOT}\\..\\csp\\ca850"]
+    cc.defines = %w(DISABLE_GEMS)
+    cc.option_include_path = '-I%s'
+    cc.option_define = '-D%s'
+    cc.compile_options = "-cpu f3783 \"-devpath=#{DEVICE_FILE_PATH}\" %{infile} -o %{outfile} %{flags}"
+  end
+
+  conf.linker do |linker|
+    linker.command = ENV['LD'] || 'ld850.exe'
+    linker.flags = [ENV['LDFLAGS']]
+    linker.flags_before_libraries = '-Xsid=0xffffffffffffffffffff -rc'
+    linker.libraries = %w(m c r)
+    linker.library_paths = ["#{LIBRARIES_PATH}"]
+    linker.option_library = '-l%s'
+    linker.option_library_path = '-L%s'
+    linker.link_options = "-cpu f3783 -F \"#{DEVICE_FILE_PATH}\" %{objs} -o %{outfile} %{flags} %{flags_before_libraries} %{libs} %{flags_after_libraries}"
+  end
+ 
+  conf.archiver do |archiver|
+    archiver.command = ENV['AR'] || 'ar850.exe'
+    archiver.archive_options = 'q %{outfile} %{objs}'
+  end
+ 
+  conf.yacc do |yacc|
+    yacc.command = ENV['YACC'] || 'bison.exe'
+    yacc.compile_options = '-o %{outfile} %{infile}'
+  end
+ 
+  conf.gperf do |gperf|
+    gperf.command = 'gperf.exe'
+    gperf.compile_options = '-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" %{infile} > %{outfile}'
+  end
+
+  conf.exts do |exts|
+    exts.object = '.o'
+    exts.executable = '.out'
+    exts.library = '.a'
+  end
+
+  conf.file_separator = '\\'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/ccrx.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/ccrx.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/ccrx.rake	(revision 331)
@@ -0,0 +1,44 @@
+MRuby::Toolchain.new(:ccrx) do |conf|
+  [conf.cc, conf.cxx].each do |cc|
+    cc.command = ENV['CC'] || 'ccrx.exe'
+    cc.flags = [ENV['CFLAGS'] || %w(-debug -fpu -nologo)]
+    cc.include_paths = ["#{MRUBY_ROOT}\\include"]
+    cc.defines = %w(DISABLE_GEMS)
+    cc.option_include_path = '-include=%s'
+    cc.option_define = '-define=%s'
+    cc.compile_options = "%{infile} -isa=rxv1 -lang=c99 -output=obj=%{outfile} %{flags}"
+  end
+
+  conf.linker do |linker|
+    linker.command = ENV['LD'] || 'rlink.exe'
+    linker.flags = [ENV['LDFLAGS']]
+    linker.flags_before_libraries = ''
+    linker.libraries = %w(m c r)
+    linker.option_library = '-library=%s'
+    linker.option_library_path = ''
+    linker.link_options = "-nologo -form=Absolute %{flags} %{objs} -output=%{outfile} %{flags_before_libraries} %{libs} %{flags_after_libraries}"
+  end
+
+  conf.archiver do |archiver|
+    archiver.command = ENV['AR'] || 'rlink.exe'
+    archiver.archive_options = '-nologo -form=library -noprelink -nooptimize -output=%{outfile} %{objs}'
+  end
+
+  conf.yacc do |yacc|
+    yacc.command = ENV['YACC'] || 'bison.exe'
+    yacc.compile_options = '-o %{outfile} %{infile}'
+  end
+
+  conf.gperf do |gperf|
+    gperf.command = 'gperf.exe'
+    gperf.compile_options = '-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" %{infile} > %{outfile}'
+  end
+
+  conf.exts do |exts|
+    exts.object = '.obj'
+    exts.executable = '.abs'
+    exts.library = '.lib'
+  end
+
+  conf.file_separator = '\\'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/clang.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/clang.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/clang.rake	(revision 331)
@@ -0,0 +1,9 @@
+MRuby::Toolchain.new(:clang) do |conf, _params|
+  toolchain :gcc
+
+  [conf.cc, conf.objc, conf.asm].each do |cc|
+    cc.command = ENV['CC'] || 'clang'
+  end
+  conf.cxx.command = ENV['CXX'] || 'clang++'
+  conf.linker.command = ENV['LD'] || 'clang'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/emscripten.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/emscripten.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/emscripten.rake	(revision 331)
@@ -0,0 +1,19 @@
+MRuby::Toolchain.new(:emscripten) do |conf|
+  toolchain :gcc
+
+  conf.cc do |cc|
+    cc.command = "emcc"
+    cc.flags.push(%w(-Wall -Werror-implicit-function-declaration -O0))
+    cc.flags[0].delete_at(cc.flags[0].rindex("-Og"))
+  end
+
+  conf.cxx do |cxx| 
+    cxx.command = "emcc"
+    cxx.flags.push(%w(-Wall -Werror-implicit-function-declaration -O0))
+    cxx.flags[0].delete_at(cxx.flags[0].rindex("-Og"))
+  end
+
+  conf.linker.command = "emcc"
+  conf.archiver.command = "emar"
+  conf.exts.executable = '.js'
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/gcc.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/gcc.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/gcc.rake	(revision 331)
@@ -0,0 +1,58 @@
+MRuby::Toolchain.new(:gcc) do |conf, _params|
+  [conf.cc, conf.objc, conf.asm].each do |cc|
+    cc.command = ENV['CC'] || 'gcc'
+    cc.flags = [ENV['CFLAGS'] || %w(-g -std=gnu99 -Og -Wall -Werror-implicit-function-declaration -Wdeclaration-after-statement -Wwrite-strings)]
+    cc.defines = %w(DISABLE_GEMS)
+    cc.option_include_path = '-I%s'
+    cc.option_define = '-D%s'
+    cc.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}'
+    cc.cxx_compile_flag = '-x c++ -std=c++03'
+    cc.cxx_exception_flag = '-fexceptions'
+  end
+
+  [conf.cxx].each do |cxx|
+    cxx.command = ENV['CXX'] || 'g++'
+    cxx.flags = [ENV['CXXFLAGS'] || ENV['CFLAGS'] || %w(-g -Og -Wall -Werror-implicit-function-declaration)]
+    cxx.defines = %w(DISABLE_GEMS)
+    cxx.option_include_path = '-I%s'
+    cxx.option_define = '-D%s'
+    cxx.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}'
+    cxx.cxx_compile_flag = '-x c++ -std=c++03'
+    cxx.cxx_exception_flag = '-fexceptions'
+  end
+
+  conf.linker do |linker|
+    linker.command = ENV['LD'] || 'gcc'
+    linker.flags = [ENV['LDFLAGS'] || %w()]
+    linker.libraries = %w(m)
+    linker.library_paths = []
+    linker.option_library = '-l%s'
+    linker.option_library_path = '-L%s'
+    linker.link_options = '%{flags} -o %{outfile} %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}'
+  end
+
+  [[conf.cc, 'c'], [conf.cxx, 'c++']].each do |cc, lang|
+    cc.instance_variable_set :@header_search_language, lang
+    def cc.header_search_paths
+      if @header_search_command != command
+        result = `echo | #{build.filename command} -x#{@header_search_language} -Wp,-v - -fsyntax-only 2>&1`
+        result = `echo | #{command} -x#{@header_search_language} -Wp,-v - -fsyntax-only 2>&1` if $?.exitstatus != 0
+        return include_paths if  $?.exitstatus != 0
+
+        @frameworks = []
+        @header_search_paths = result.lines.map { |v|
+          framework = v.match(/^ (.*)(?: \(framework directory\))$/)
+          if framework
+            @frameworks << framework[1]
+            next nil
+          end
+
+          v.match(/^ (.*)$/)
+        }.compact.map { |v| v[1] }.select { |v| File.directory? v }
+        @header_search_paths += include_paths
+        @header_search_command = command
+      end
+      @header_search_paths
+    end
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/openwrt.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/openwrt.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/openwrt.rake	(revision 331)
@@ -0,0 +1,38 @@
+# usage of environmental variables to set the
+# cross compiling toolchain proper
+MRuby::Toolchain.new(:openwrt) do |conf|
+  [conf.cc, conf.objc, conf.asm].each do |cc|
+    cc.command = ENV['TARGET_CC']
+    cc.flags = ENV['TARGET_CFLAGS']
+    cc.include_paths = ["#{MRUBY_ROOT}/include"]
+    cc.defines = %w(DISABLE_GEMS)
+    cc.option_include_path = '-I%s'
+    cc.option_define = '-D%s'
+    cc.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}'
+  end
+
+  [conf.cxx].each do |cxx|
+    cxx.command = ENV['TARGET_CXX']
+    cxx.flags = ENV['TARGET_CXXFLAGS']
+    cxx.include_paths = ["#{MRUBY_ROOT}/include"]
+    cxx.defines = %w(DISABLE_GEMS)
+    cxx.option_include_path = '-I%s'
+    cxx.option_define = '-D%s'
+    cxx.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}'
+   end
+
+  conf.linker do |linker|
+    linker.command = ENV['TARGET_CC']
+    linker.flags = ENV['TARGET_LDFLAGS']
+    linker.libraries = %w(m)
+    linker.library_paths = []
+    linker.option_library = '-l%s'
+    linker.option_library_path = '-L%s'
+    linker.link_options = '%{flags} -o %{outfile} %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}'
+  end
+
+  conf.archiver do |archiver|
+    archiver.command = ENV['TARGET_AR']
+    archiver.archive_options = 'rs %{outfile} %{objs}'
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/visualcpp.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/visualcpp.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/visualcpp.rake	(revision 331)
@@ -0,0 +1,71 @@
+MRuby::Toolchain.new(:visualcpp) do |conf, _params|
+  conf.cc do |cc|
+    cc.command = ENV['CC'] || 'cl.exe'
+    # C4013: implicit function declaration
+    cc.flags = [ENV['CFLAGS'] || %w(/c /nologo /W3 /we4013 /Zi /MD /O2 /utf-8 /D_CRT_SECURE_NO_WARNINGS)]
+    cc.defines = %w(DISABLE_GEMS MRB_STACK_EXTEND_DOUBLING)
+    cc.option_include_path = '/I%s'
+    cc.option_define = '/D%s'
+    cc.compile_options = "%{flags} /Fo%{outfile} %{infile}"
+    cc.cxx_compile_flag = '/TP'
+    cc.cxx_exception_flag = '/EHs'
+  end
+
+  conf.cxx do |cxx|
+    cxx.command = ENV['CXX'] || 'cl.exe'
+    cxx.flags = [ENV['CXXFLAGS'] || ENV['CFLAGS'] || %w(/c /nologo /W3 /Zi /MD /O2 /EHs /utf-8 /D_CRT_SECURE_NO_WARNINGS)]
+    cxx.defines = %w(DISABLE_GEMS MRB_STACK_EXTEND_DOUBLING)
+    cxx.option_include_path = '/I%s'
+    cxx.option_define = '/D%s'
+    cxx.compile_options = "%{flags} /Fo%{outfile} %{infile}"
+    cxx.cxx_compile_flag = '/TP'
+    cxx.cxx_exception_flag = '/EHs'
+  end
+
+  conf.linker do |linker|
+    linker.command = ENV['LD'] || 'link.exe'
+    linker.flags = [ENV['LDFLAGS'] || %w(/MANIFEST /NXCOMPAT /DYNAMICBASE /MACHINE:X86 /INCREMENTAL /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ERRORREPORT:PROMPT /NOLOGO /TLBID:1)]
+    linker.flags << "/PDB:\"#{conf.build_dir}\\vc140.pdb\""
+    #linker.flags << "/PGD:\"%{outdir}\\%{outfilebase}.pgd\""
+    linker.flags << "/ManifestFile:\"%{outdir}\\%{outfilebase}.exe.intermediate.manifest\""
+    linker.libraries = %w()
+    linker.library_paths = %w()
+    linker.option_library = '%s.lib'
+    linker.option_library_path = '/LIBPATH:%s'
+    linker.link_options = "%{flags} /OUT:%{outfile} %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}"
+  end
+
+  conf.archiver do |archiver|
+    archiver.command = ENV['AR'] || 'lib.exe'
+    archiver.archive_options = '/nologo /OUT:%{outfile} %{objs}'
+  end
+
+  conf.yacc do |yacc|
+    yacc.command = ENV['YACC'] || 'bison.exe'
+    yacc.compile_options = '-o %{outfile} %{infile}'
+  end
+
+  conf.gperf do |gperf|
+    gperf.command = 'gperf.exe'
+    gperf.compile_options = '-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" %{infile} > %{outfile}'
+  end
+
+  conf.exts do |exts|
+    exts.object = '.obj'
+    exts.executable = '.exe'
+    exts.library = '.lib'
+  end
+
+  conf.file_separator = '\\'
+
+  if require 'open3'
+    Open3.popen3 conf.cc.command do |_, _, e, _|
+      if /Version (\d{2})\.\d{2}\.\d{5}/ =~ e.gets && $1.to_i <= 17
+        m = "# VS2010/2012 support will be dropped after the next release! #"
+        h = "#" * m.length
+        puts h, m, h
+      end
+    end
+  end
+
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/assert.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/assert.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/assert.rb	(revision 331)
@@ -0,0 +1,257 @@
+$ok_test = 0
+$ko_test = 0
+$kill_test = 0
+$asserts  = []
+$test_start = Time.now if Object.const_defined?(:Time)
+
+# Implementation of print due to the reason that there might be no print
+def t_print(*args)
+  i = 0
+  len = args.size
+  while i < len
+    str = args[i].to_s
+    __t_printstr__ str rescue print str
+    i += 1
+  end
+end
+
+##
+# Create the assertion in a readable way
+def assertion_string(err, str, iso=nil, e=nil, bt=nil)
+  msg = "#{err}#{str}"
+  msg += " [#{iso}]" if iso && iso != ''
+  msg += " => #{e.message}" if e
+  msg += " (mrbgems: #{GEMNAME})" if Object.const_defined?(:GEMNAME)
+  if $mrbtest_assert && $mrbtest_assert.size > 0
+    $mrbtest_assert.each do |idx, str, diff|
+      msg += "\n - Assertion[#{idx}] Failed: #{str}\n#{diff}"
+    end
+  end
+  msg += "\nbacktrace:\n\t#{bt.join("\n\t")}" if bt
+  msg
+end
+
+##
+# Verify a code block.
+#
+# str : A remark which will be printed in case
+#       this assertion fails
+# iso : The ISO reference code of the feature
+#       which will be tested by this
+#       assertion
+def assert(str = 'Assertion failed', iso = '')
+  t_print(str, (iso != '' ? " [#{iso}]" : ''), ' : ') if $mrbtest_verbose
+  begin
+    $mrbtest_assert = []
+    $mrbtest_assert_idx = 0
+    yield
+    if($mrbtest_assert.size > 0)
+      $asserts.push(assertion_string('Fail: ', str, iso, nil))
+      $ko_test += 1
+      t_print('F')
+    else
+      $ok_test += 1
+      t_print('.')
+    end
+  rescue Exception => e
+    bt = e.backtrace if $mrbtest_verbose
+    if e.class.to_s == 'MRubyTestSkip'
+      $asserts.push "Skip: #{str} #{iso} #{e.cause}"
+      t_print('?')
+    else
+      $asserts.push(assertion_string("#{e.class}: ", str, iso, e, bt))
+      $kill_test += 1
+      t_print('X')
+  end
+  ensure
+    $mrbtest_assert = nil
+  end
+  t_print("\n") if $mrbtest_verbose
+end
+
+def assertion_diff(exp, act)
+  "    Expected: #{exp.inspect}\n" +
+  "      Actual: #{act.inspect}"
+end
+
+def assert_true(ret, msg = nil, diff = nil)
+  if $mrbtest_assert
+    $mrbtest_assert_idx += 1
+    unless ret
+      msg = "Expected #{ret.inspect} to be true" unless msg
+      diff = assertion_diff(true, ret)  unless diff
+      $mrbtest_assert.push([$mrbtest_assert_idx, msg, diff])
+    end
+  end
+  ret
+end
+
+def assert_false(ret, msg = nil, diff = nil)
+  if $mrbtest_assert
+    $mrbtest_assert_idx += 1
+    if ret
+      msg = "Expected #{ret.inspect} to be false" unless msg
+      diff = assertion_diff(false, ret) unless diff
+
+      $mrbtest_assert.push([$mrbtest_assert_idx, msg, diff])
+    end
+  end
+  !ret
+end
+
+def assert_equal(arg1, arg2 = nil, arg3 = nil)
+  if block_given?
+    exp, act, msg = arg1, yield, arg2
+  else
+    exp, act, msg = arg1, arg2, arg3
+  end
+
+  msg = "Expected to be equal" unless msg
+  diff = assertion_diff(exp, act)
+  assert_true(exp == act, msg, diff)
+end
+
+def assert_not_equal(arg1, arg2 = nil, arg3 = nil)
+  if block_given?
+    exp, act, msg = arg1, yield, arg2
+  else
+    exp, act, msg = arg1, arg2, arg3
+  end
+
+  msg = "Expected to be not equal" unless msg
+  diff = assertion_diff(exp, act)
+  assert_false(exp == act, msg, diff)
+end
+
+def assert_nil(obj, msg = nil)
+  msg = "Expected #{obj.inspect} to be nil" unless msg
+  diff = assertion_diff(nil, obj)
+  assert_true(obj.nil?, msg, diff)
+end
+
+def assert_include(collection, obj, msg = nil)
+  msg = "Expected #{collection.inspect} to include #{obj.inspect}" unless msg
+  diff = "    Collection: #{collection.inspect}\n" +
+         "        Object: #{obj.inspect}"
+  assert_true(collection.include?(obj), msg, diff)
+end
+
+def assert_not_include(collection, obj, msg = nil)
+  msg = "Expected #{collection.inspect} to not include #{obj.inspect}" unless msg
+  diff = "    Collection: #{collection.inspect}\n" +
+         "        Object: #{obj.inspect}"
+  assert_false(collection.include?(obj), msg, diff)
+end
+
+def assert_raise(*exp)
+  ret = true
+  if $mrbtest_assert
+    $mrbtest_assert_idx += 1
+    msg = exp.last.class == String ? exp.pop : nil
+    msg = msg.to_s + " : " if msg
+    should_raise = false
+    begin
+      yield
+      should_raise = true
+    rescue Exception => e
+      msg = "#{msg}#{exp.inspect} exception expected, not"
+      diff = "      Class: <#{e.class}>\n" +
+             "    Message: #{e.message}"
+      if not exp.any?{|ex| ex.instance_of?(Module) ? e.kind_of?(ex) : ex == e.class }
+        $mrbtest_assert.push([$mrbtest_assert_idx, msg, diff])
+        ret = false
+      end
+    end
+
+    exp = exp.first if exp.first
+    if should_raise
+      msg = "#{msg}#{exp.inspect} expected but nothing was raised."
+      $mrbtest_assert.push([$mrbtest_assert_idx, msg, nil])
+      ret = false
+    end
+  end
+  ret
+end
+
+def assert_nothing_raised(*exp)
+  ret = true
+  if $mrbtest_assert
+    $mrbtest_assert_idx += 1
+    msg = exp.last.class == String ? exp.pop : ""
+    begin
+      yield
+    rescue Exception => e
+      msg = "#{msg} exception raised."
+      diff = "      Class: <#{e.class}>\n" +
+             "    Message: #{e.message}"
+      $mrbtest_assert.push([$mrbtest_assert_idx, msg, diff])
+      ret = false
+    end
+  end
+  ret
+end
+
+##
+# Fails unless +obj+ is a kind of +cls+.
+def assert_kind_of(cls, obj, msg = nil)
+  msg = "Expected #{obj.inspect} to be a kind of #{cls}, not #{obj.class}" unless msg
+  diff = assertion_diff(cls, obj.class)
+  assert_true(obj.kind_of?(cls), msg, diff)
+end
+
+##
+# Fails unless +exp+ is equal to +act+ in terms of a Float
+def assert_float(exp, act, msg = nil)
+  msg = "Float #{exp} expected to be equal to float #{act}" unless msg
+  diff = assertion_diff(exp, act)
+  assert_true check_float(exp, act), msg, diff
+end
+
+##
+# Report the test result and print all assertions
+# which were reported broken.
+def report()
+  t_print("\n")
+
+  $asserts.each do |msg|
+    t_print "#{msg}\n"
+  end
+
+  $total_test = $ok_test+$ko_test+$kill_test
+  t_print("Total: #{$total_test}\n")
+
+  t_print("   OK: #{$ok_test}\n")
+  t_print("   KO: #{$ko_test}\n")
+  t_print("Crash: #{$kill_test}\n")
+
+  if Object.const_defined?(:Time)
+    t_time = Time.now - $test_start
+    t_print(" Time: #{t_time.round(2)} seconds\n")
+  end
+end
+
+##
+# Performs fuzzy check for equality on methods returning floats
+def check_float(a, b)
+  tolerance = Mrbtest::FLOAT_TOLERANCE
+  a = a.to_f
+  b = b.to_f
+  if a.finite? and b.finite?
+    (a-b).abs < tolerance
+  else
+    true
+  end
+end
+
+##
+# Skip the test
+class MRubyTestSkip < NotImplementedError
+  attr_accessor :cause
+  def initialize(cause)
+    @cause = cause
+  end
+end
+
+def skip(cause = "")
+  raise MRubyTestSkip.new(cause)
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/bintest.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/bintest.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/bintest.rb	(revision 331)
@@ -0,0 +1,33 @@
+$:.unshift File.dirname(File.dirname(File.expand_path(__FILE__)))
+require 'test/assert.rb'
+
+def cmd(s)
+  case RbConfig::CONFIG['host_os']
+  when /mswin(?!ce)|mingw|bccwin/
+    "bin\\#{s}.exe"
+  else
+    "bin/#{s}"
+  end
+end
+
+def shellquote(s)
+  case RbConfig::CONFIG['host_os']
+  when /mswin(?!ce)|mingw|bccwin/
+    "\"#{s}\""
+  else
+    "'#{s}'"
+  end
+end
+
+ARGV.each do |gem|
+  case RbConfig::CONFIG['host_os']
+  when /mswin(?!ce)|mingw|bccwin/
+    gem = gem.gsub('\\', '/')
+  end
+
+  Dir["#{gem}/bintest/**/*.rb"].each do |file|
+    load file
+  end
+end
+
+load 'test/report.rb'
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/report.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/report.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/report.rb	(revision 331)
@@ -0,0 +1,4 @@
+report
+if $ko_test > 0 or $kill_test > 0
+  raise "mrbtest failed (KO:#{$ko_test}, Crash:#{$kill_test})"
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/argumenterror.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/argumenterror.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/argumenterror.rb	(revision 331)
@@ -0,0 +1,16 @@
+##
+# ArgumentError ISO Test
+
+assert('ArgumentError', '15.2.24') do
+  e2 = nil
+  a = []
+  begin
+    # this will cause an exception due to the wrong arguments
+    a[]
+  rescue => e1
+    e2 = e1
+  end
+
+  assert_equal(Class, ArgumentError.class)
+  assert_equal(ArgumentError, e2.class)
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/array.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/array.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/array.rb	(revision 331)
@@ -0,0 +1,390 @@
+##
+# Array ISO Test
+
+assert('Array', '15.2.12') do
+  assert_equal(Class, Array.class)
+end
+
+assert('Array inclueded modules', '15.2.12.3') do
+  assert_true(Array.include?(Enumerable))
+end
+
+assert('Array.[]', '15.2.12.4.1') do
+  assert_equal([1, 2, 3], Array.[](1,2,3))
+end
+
+class SubArray < Array
+end
+
+assert('SubArray.[]') do
+  a = SubArray[1, 2, 3]
+  assert_equal(SubArray, a.class)
+end
+
+assert('Array#+', '15.2.12.5.1') do
+  assert_equal([1, 1], [1].+([1]))
+end
+
+assert('Array#*', '15.2.12.5.2') do
+  assert_raise(ArgumentError) do
+    # this will cause an exception due to the wrong argument
+    [1].*(-1)
+  end
+  assert_equal([1, 1, 1], [1].*(3))
+  assert_equal([], [1].*(0))
+end
+
+assert('Array#<<', '15.2.12.5.3') do
+  assert_equal([1, 1], [1].<<(1))
+end
+
+assert('Array#[]', '15.2.12.5.4') do
+  a = Array.new
+  assert_raise(ArgumentError) do
+    # this will cause an exception due to the wrong arguments
+    a.[]()
+  end
+  assert_raise(ArgumentError) do
+    # this will cause an exception due to the wrong arguments
+    a.[](1,2,3)
+  end
+
+  assert_equal(2, [1,2,3].[](1))
+  assert_equal(nil, [1,2,3].[](4))
+  assert_equal(3, [1,2,3].[](-1))
+  assert_equal(nil, [1,2,3].[](-4))
+
+  a = [ "a", "b", "c", "d", "e" ]
+  assert_equal("b", a[1.1])
+  assert_equal(["b", "c"], a[1,2])
+  assert_equal(["b", "c", "d"], a[1..-2])
+end
+
+assert('Array#[]=', '15.2.12.5.5') do
+  a = Array.new
+  assert_raise(ArgumentError) do
+    # this will cause an exception due to the wrong arguments
+    a.[]=()
+  end
+  assert_raise(ArgumentError) do
+    # this will cause an exception due to the wrong arguments
+    a.[]=(1,2,3,4)
+  end
+  assert_raise(IndexError) do
+    # this will cause an exception due to the wrong arguments
+    a = [1,2,3,4,5]
+    a[1, -1] = 10
+  end
+
+  assert_equal(4, [1,2,3].[]=(1,4))
+  assert_equal(3, [1,2,3].[]=(1,2,3))
+
+  a = [1,2,3,4,5]
+  a[3..-1] = 6
+  assert_equal([1,2,3,6], a)
+
+  a = [1,2,3,4,5]
+  a[3..-1] = []
+  assert_equal([1,2,3], a)
+
+  a = [1,2,3,4,5]
+  a[2...4] = 6
+  assert_equal([1,2,6,5], a)
+
+  # passing self (#3274)
+  a = [1,2,3]
+  a[1,0] = a
+  assert_equal([1,1,2,3,2,3], a)
+  a = [1,2,3]
+  a[-1,0] = a
+  assert_equal([1,2,1,2,3,3], a)
+end
+
+assert('Array#clear', '15.2.12.5.6') do
+  a = [1]
+  a.clear
+  assert_equal([], a)
+end
+
+assert('Array#collect!', '15.2.12.5.7') do
+  a = [1,2,3]
+  a.collect! { |i| i + i }
+  assert_equal([2,4,6], a)
+end
+
+assert('Array#concat', '15.2.12.5.8') do
+  assert_equal([1,2,3,4], [1, 2].concat([3, 4]))
+
+  # passing self (#3302)
+  a = [1,2,3]
+  a.concat(a)
+  assert_equal([1,2,3,1,2,3], a)
+end
+
+assert('Array#delete_at', '15.2.12.5.9') do
+  a = [1,2,3]
+  assert_equal(2, a.delete_at(1))
+  assert_equal([1,3], a)
+  assert_equal(nil, a.delete_at(3))
+  assert_equal([1,3], a)
+  assert_equal(nil, a.delete_at(-3))
+  assert_equal([1,3], a)
+  assert_equal(3, a.delete_at(-1))
+  assert_equal([1], a)
+end
+
+assert('Array#each', '15.2.12.5.10') do
+  a = [1,2,3]
+  b = 0
+  a.each {|i| b += i}
+  assert_equal(6, b)
+end
+
+assert('Array#each_index', '15.2.12.5.11') do
+  a = [1]
+  b = nil
+  a.each_index {|i| b = i}
+  assert_equal(0, b)
+end
+
+assert('Array#empty?', '15.2.12.5.12') do
+  a = []
+  b = [b]
+  assert_true([].empty?)
+  assert_false([1].empty?)
+end
+
+assert('Array#first', '15.2.12.5.13') do
+  assert_raise(ArgumentError) do
+    # this will cause an exception due to the wrong argument
+    [1,2,3].first(-1)
+  end
+  assert_raise(ArgumentError) do
+    # this will cause an exception due to the wrong argument
+    [1,2,3].first(1,2)
+  end
+
+  assert_nil([].first)
+
+  b = [1,2,3]
+  assert_equal(1, b.first)
+  assert_equal([], b.first(0))
+  assert_equal([1], b.first(1))
+  assert_equal([1,2,3], b.first(4))
+end
+
+assert('Array#index', '15.2.12.5.14') do
+  a = [1,2,3]
+
+  assert_equal(1, a.index(2))
+  assert_equal(nil, a.index(0))
+end
+
+assert('Array#initialize', '15.2.12.5.15') do
+  a = [].initialize(1)
+  b = [].initialize(2)
+  c = [].initialize(2, 1)
+  d = [].initialize(2) {|i| i}
+
+  assert_equal([nil], a)
+  assert_equal([nil,nil], b)
+  assert_equal([1,1], c)
+  assert_equal([0,1], d)
+end
+
+assert('Array#initialize_copy', '15.2.12.5.16') do
+  a = [1,2,3]
+  b = [].initialize_copy(a)
+
+  assert_equal([1,2,3], b)
+end
+
+assert('Array#join', '15.2.12.5.17') do
+  a = [1,2,3].join
+  b = [1,2,3].join(',')
+
+  assert_equal('123', a)
+  assert_equal('1,2,3', b)
+end
+
+assert('Array#last', '15.2.12.5.18') do
+  assert_raise(ArgumentError) do
+    # this will cause an exception due to the wrong argument
+    [1,2,3].last(-1)
+  end
+
+  a = [1,2,3]
+  assert_equal(3, a.last)
+  assert_nil([].last)
+end
+
+assert('Array#length', '15.2.12.5.19') do
+  a = [1,2,3]
+
+  assert_equal(3, a.length)
+end
+
+assert('Array#map!', '15.2.12.5.20') do
+  a = [1,2,3]
+  a.map! { |i| i + i }
+  assert_equal([2,4,6], a)
+end
+
+assert('Array#pop', '15.2.12.5.21') do
+  a = [1,2,3]
+  b = a.pop
+
+  assert_nil([].pop)
+  assert_equal([1,2], a)
+  assert_equal(3, b)
+end
+
+assert('Array#push', '15.2.12.5.22') do
+  a = [1,2,3]
+  b = a.push(4)
+
+  assert_equal([1,2,3,4], a)
+  assert_equal([1,2,3,4], b)
+end
+
+assert('Array#replace', '15.2.12.5.23') do
+  a = [1,2,3]
+  b = [].replace(a)
+
+  assert_equal([1,2,3], b)
+end
+
+assert('Array#reverse', '15.2.12.5.24') do
+  a = [1,2,3]
+  b = a.reverse
+
+  assert_equal([1,2,3], a)
+  assert_equal([3,2,1], b)
+end
+
+assert('Array#reverse!', '15.2.12.5.25') do
+  a = [1,2,3]
+  b = a.reverse!
+
+  assert_equal([3,2,1], a)
+  assert_equal([3,2,1], b)
+end
+
+assert('Array#rindex', '15.2.12.5.26') do
+  a = [1,2,3]
+
+  assert_equal(1, a.rindex(2))
+  assert_equal(nil, a.rindex(0))
+end
+
+assert('Array#shift', '15.2.12.5.27') do
+  a = [1,2,3]
+  b = a.shift
+
+  assert_nil([].shift)
+  assert_equal([2,3], a)
+  assert_equal(1, b)
+end
+
+assert('Array#size', '15.2.12.5.28') do
+  a = [1,2,3]
+
+  assert_equal(3, a.size)
+end
+
+assert('Array#slice', '15.2.12.5.29') do
+  a = "12345".slice(1, 3)
+  b = a.slice(0)
+
+  assert_equal("2:", "#{b}:")
+  assert_equal(2, [1,2,3].[](1))
+end
+
+assert('Array#unshift', '15.2.12.5.30') do
+  a = [2,3]
+  b = a.unshift(1)
+  c = [2,3]
+  d = c.unshift(0, 1)
+
+  assert_equal([1,2,3], a)
+  assert_equal([1,2,3], b)
+  assert_equal([0,1,2,3], c)
+  assert_equal([0,1,2,3], d)
+end
+
+assert('Array#to_s', '15.2.12.5.31 / 15.2.12.5.32') do
+  a = [2, 3,   4, 5]
+  r1 = a.to_s
+  r2 = a.inspect
+
+  assert_equal(r2, r1)
+  assert_equal("[2, 3, 4, 5]", r1)
+end
+
+assert('Array#==', '15.2.12.5.33') do
+  assert_false(["a", "c"] == ["a", "c", 7])
+  assert_true(["a", "c", 7] == ["a", "c", 7])
+  assert_false(["a", "c", 7] == ["a", "d", "f"])
+end
+
+assert('Array#eql?', '15.2.12.5.34') do
+  a1 = [ 1, 2, 3 ]
+  a2 = [ 1, 2, 3 ]
+  a3 = [ 1.0, 2.0, 3.0 ]
+
+  assert_true(a1.eql? a2)
+  assert_false(a1.eql? a3)
+end
+
+assert('Array#hash', '15.2.12.5.35') do
+  a = [ 1, 2, 3 ]
+
+  #assert_true(a.hash.is_a? Integer)
+  assert_true(a.hash.is_a? Integral)  # mruby special
+  assert_equal([1,2].hash, [1,2].hash)
+end
+
+assert('Array#<=>', '15.2.12.5.36') do
+  r1 = [ "a", "a", "c" ]    <=> [ "a", "b", "c" ]   #=> -1
+  r2 = [ 1, 2, 3, 4, 5, 6 ] <=> [ 1, 2 ]            #=> +1
+  r3 = [ "a", "b", "c" ]    <=> [ "a", "b", "c" ]   #=> 0
+
+  assert_equal(-1, r1)
+  assert_equal(+1, r2)
+  assert_equal(0, r3)
+end
+
+# Not ISO specified
+
+assert("Array (Shared Array Corruption)") do
+  a = [ "a", "b", "c", "d", "e", "f" ]
+  b = a.slice(1, 3)
+  a.clear
+  b.clear
+end
+
+assert("Array (Longish inline array)") do
+  ary = [[0, 0], [1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6], [7, 7], [8, 8], [9, 9], [10, 10], [11, 11], [12, 12], [13, 13], [14, 14], [15, 15], [16, 16], [17, 17], [18, 18], [19, 19], [20, 20], [21, 21], [22, 22], [23, 23], [24, 24], [25, 25], [26, 26], [27, 27], [28, 28], [29, 29], [30, 30], [31, 31], [32, 32], [33, 33], [34, 34], [35, 35], [36, 36], [37, 37], [38, 38], [39, 39], [40, 40], [41, 41], [42, 42], [43, 43], [44, 44], [45, 45], [46, 46], [47, 47], [48, 48], [49, 49], [50, 50], [51, 51], [52, 52], [53, 53], [54, 54], [55, 55], [56, 56], [57, 57], [58, 58], [59, 59], [60, 60], [61, 61], [62, 62], [63, 63], [64, 64], [65, 65], [66, 66], [67, 67], [68, 68], [69, 69], [70, 70], [71, 71], [72, 72], [73, 73], [74, 74], [75, 75], [76, 76], [77, 77], [78, 78], [79, 79], [80, 80], [81, 81], [82, 82], [83, 83], [84, 84], [85, 85], [86, 86], [87, 87], [88, 88], [89, 89], [90, 90], [91, 91], [92, 92], [93, 93], [94, 94], [95, 95], [96, 96], [97, 97], [98, 98], [99, 99], [100, 100], [101, 101], [102, 102], [103, 103], [104, 104], [105, 105], [106, 106], [107, 107], [108, 108], [109, 109], [110, 110], [111, 111], [112, 112], [113, 113], [114, 114], [115, 115], [116, 116], [117, 117], [118, 118], [119, 119], [120, 120], [121, 121], [122, 122], [123, 123], [124, 124], [125, 125], [126, 126], [127, 127], [128, 128], [129, 129], [130, 130], [131, 131], [132, 132], [133, 133], [134, 134], [135, 135], [136, 136], [137, 137], [138, 138], [139, 139], [140, 140], [141, 141], [142, 142], [143, 143], [144, 144], [145, 145], [146, 146], [147, 147], [148, 148], [149, 149], [150, 150], [151, 151], [152, 152], [153, 153], [154, 154], [155, 155], [156, 156], [157, 157], [158, 158], [159, 159], [160, 160], [161, 161], [162, 162], [163, 163], [164, 164], [165, 165], [166, 166], [167, 167], [168, 168], [169, 169], [170, 170], [171, 171], [172, 172], [173, 173], [174, 174], [175, 175], [176, 176], [177, 177], [178, 178], [179, 179], [180, 180], [181, 181], [182, 182], [183, 183], [184, 184], [185, 185], [186, 186], [187, 187], [188, 188], [189, 189], [190, 190], [191, 191], [192, 192], [193, 193], [194, 194], [195, 195], [196, 196], [197, 197], [198, 198], [199, 199]]
+  h = Hash.new(0)
+  ary.each {|p| h[p.class] += 1}
+  assert_equal({Array=>200}, h)
+end
+
+assert("Array#rindex") do
+  class Sneaky
+    def ==(*)
+      $a.clear
+      $a.replace([1])
+      false
+    end
+  end
+  $a = [2, 3, 4, 5, 6, 7, 8, 9, 10, Sneaky.new]
+  assert_equal 0, $a.rindex(1)
+end
+
+assert('Array#freeze') do
+  a = [].freeze
+  assert_raise(RuntimeError) do
+    a[0] = 1
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/basicobject.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/basicobject.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/basicobject.rb	(revision 331)
@@ -0,0 +1,11 @@
+##
+# BasicObject
+
+assert('BasicObject') do
+  assert_equal(Class, BasicObject.class)
+end
+
+assert('BasicObject superclass') do
+  assert_nil(BasicObject.superclass)
+end
+
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/bs_block.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/bs_block.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/bs_block.rb	(revision 331)
@@ -0,0 +1,521 @@
+##
+# Bootstrap tests for blocks
+
+assert('BS Block 1') do
+  assert_equal(1) do
+    1.times{
+      begin
+        a = 1
+      ensure
+        foo = nil
+      end
+    }
+  end
+end
+
+assert('BS Block 2') do
+  assert_equal 2, [1,2,3].find{|x| x == 2}
+end
+
+assert('BS Block 3') do
+  class E
+    include Enumerable
+    def each(&block)
+      [1, 2, 3].each(&block)
+    end
+  end
+  assert_equal 2, E.new.find {|x| x == 2 }
+end
+
+assert('BS Block 3') do
+  sum = 0
+  for x in [1, 2, 3]
+    sum += x
+  end
+  assert_equal 6, sum
+end
+
+assert('BS Block 4') do
+  sum = 0
+  for x in (1..5)
+    sum += x
+  end
+  assert_equal 15, sum
+end
+
+assert('BS Block 5') do
+  sum = 0
+  for x in []
+    sum += x
+  end
+  assert_equal 0, sum
+end
+
+assert('BS Block 6') do
+  ans = []
+  assert_equal(1) do
+    1.times{
+      for n in 1..3
+        a = n
+        ans << a
+      end
+    }
+  end
+end
+
+assert('BS Block 7') do
+  ans = []
+  assert_equal((1..3)) do
+    for m in 1..3
+      for n in 2..4
+        a = [m, n]
+        ans << a
+      end
+    end
+  end
+end
+
+assert('BS Block 8') do
+  assert_equal [1, 2, 3], (1..3).to_a
+end
+
+assert('BS Block 9') do
+  assert_equal([4, 8, 12]) do
+    (1..3).map{|e|
+      e * 4
+    }
+  end
+end
+
+assert('BS Block 10') do
+  def m
+    yield
+  end
+  def n
+    yield
+  end
+
+  assert_equal(100) do
+    m{
+      n{
+        100
+      }
+    }
+  end
+end
+
+assert('BS Block 11') do
+  def m
+    yield 1
+  end
+
+  assert_equal(20) do
+    m{|ib|
+      m{|jb|
+        i = 20
+      }
+    }
+  end
+end
+
+assert('BS Block 12') do
+  def m
+    yield 1
+  end
+
+  assert_equal(2) do
+    m{|ib|
+      m{|jb|
+        ib = 20
+        kb = 2
+      }
+    }
+  end
+end
+
+assert('BS Block 13') do
+  def iter1
+    iter2{
+      yield
+    }
+  end
+
+  def iter2
+    yield
+  end
+
+  assert_equal(3) do
+    iter1{
+      jb = 2
+      iter1{
+        jb = 3
+      }
+      jb
+    }
+  end
+end
+
+assert('BS Block 14') do
+  def iter1
+    iter2{
+      yield
+    }
+  end
+
+  def iter2
+    yield
+  end
+
+  assert_equal(2) do
+    iter1{
+      jb = 2
+      iter1{
+        jb
+      }
+      jb
+    }
+  end
+end
+
+assert('BS Block 15') do
+  def m
+    yield 1
+  end
+  assert_equal(2) do
+    m{|ib|
+      ib*2
+    }
+  end
+end
+
+assert('BS Block 16') do
+  def m
+    yield 12345, 67890
+  end
+  assert_equal(92580) do
+    m{|ib,jb|
+      ib*2+jb
+    }
+  end
+end
+
+assert('BS Block 17') do
+  def iter
+    yield 10
+  end
+
+  a = nil
+  assert_equal [10, nil] do
+    [iter{|a|
+      a
+    }, a]
+  end
+end
+
+assert('BS Block 18') do
+  def iter
+    yield 10
+  end
+
+  assert_equal(21) do
+    iter{|a|
+      iter{|a|
+        a + 1
+      } + a
+    }
+  end
+end
+
+assert('BS Block 19') do
+  def iter
+    yield 10, 20, 30, 40
+  end
+
+  a = b = c = d = nil
+  assert_equal([10, 20, 30, 40, nil, nil, nil, nil]) do
+    iter{|a, b, c, d|
+      [a, b, c, d]
+    } + [a, b, c, d]
+  end
+end
+
+assert('BS Block 20') do
+  def iter
+    yield 10, 20, 30, 40
+  end
+
+  a = b = nil
+  assert_equal([10, 20, 30, 40, nil, nil]) do
+    iter{|a, b, c, d|
+      [a, b, c, d]
+    } + [a, b]
+  end
+end
+
+assert('BS Block 21') do
+  def iter
+    yield 1, 2
+  end
+
+  assert_equal([1, [2]]) do
+    iter{|a, *b|
+      [a, b]
+    }
+  end
+end
+
+assert('BS Block 22') do
+  def iter
+    yield 1, 2
+  end
+
+  assert_equal([[1, 2]]) do
+    iter{|*a|
+      [a]
+    }
+  end
+end
+
+assert('BS Block 23') do
+  def iter
+    yield 1, 2
+  end
+
+  assert_equal([1, 2, []]) do
+    iter{|a, b, *c|
+      [a, b, c]
+    }
+  end
+end
+
+assert('BS Block 24') do
+  def m
+    yield
+  end
+  assert_equal(1) do
+    m{
+      1
+    }
+  end
+end
+
+assert('BS Block 25') do
+  def m
+    yield 123
+  end
+  assert_equal(15129) do
+    m{|ib|
+      m{|jb|
+        ib*jb
+      }
+    }
+  end
+end
+
+assert('BS Block 26') do
+  def m a
+    yield a
+  end
+  assert_equal(2) do
+    m(1){|ib|
+      m(2){|jb|
+        ib*jb
+      }
+    }
+  end
+end
+
+assert('BS Block 27') do
+  sum = 0
+  3.times{|ib|
+    2.times{|jb|
+      sum += ib + jb
+    }}
+  assert_equal sum, 9
+end
+
+assert('BS Block 28') do
+  assert_equal(10) do
+    3.times{|bl|
+      break 10
+    }
+  end
+end
+
+assert('BS Block 29') do
+  def iter
+    yield 1,2,3
+  end
+
+  assert_equal([1, 2]) do
+    iter{|i, j|
+      [i, j]
+    }
+  end
+end
+
+assert('BS Block 30') do
+  def iter
+    yield 1
+  end
+
+  assert_equal([1, nil]) do
+    iter{|i, j|
+      [i, j]
+    }
+  end
+end
+
+assert('BS Block [ruby-dev:31147]') do
+  def m
+    yield
+  end
+  assert_nil m{|&b| b}
+end
+
+assert('BS Block [ruby-dev:31160]') do
+  def m()
+    yield
+  end
+  assert_nil m {|(v,(*))|}
+end
+
+assert('BS Block [issue #750]') do
+  def m(a, *b)
+    yield
+  end
+  args = [1, 2, 3]
+  assert_equal m(*args){ 1 }, 1
+end
+
+assert('BS Block 31') do
+  def m()
+    yield
+  end
+  assert_nil m {|((*))|}
+end
+
+assert('BS Block [ruby-dev:31440]') do
+  def m
+    yield [0]
+  end
+  assert_equal m{|v, &b| v}, [0]
+end
+
+assert('BS Block 32') do
+  r = false; 1.times{|&b| r = b}
+  assert_equal NilClass, r.class
+end
+
+assert('BS Block [ruby-core:14395]') do
+  class Controller
+    def respond_to(&block)
+      responder = Responder.new
+      block.call(responder)
+      responder.respond
+    end
+    def test_for_bug
+      respond_to{|format|
+        format.js{
+          "in test"
+          render{|obj|
+            obj
+          }
+        }
+      }
+    end
+    def render(&block)
+      "in render"
+    end
+  end
+
+  class Responder
+    def method_missing(symbol, &block)
+      "enter method_missing"
+      @response = Proc.new{
+        'in method missing'
+        block.call
+      }
+      "leave method_missing"
+    end
+    def respond
+      @response.call
+    end
+  end
+  t = Controller.new
+  assert_true t.test_for_bug
+end
+
+assert("BS Block 33") do
+  module TestReturnFromNestedBlock
+    def self.test
+      1.times do
+        1.times do
+          return :ok
+        end
+      end
+      :bad
+    end
+  end
+  assert_equal :ok, TestReturnFromNestedBlock.test
+end
+
+assert("BS Block 34") do
+  module TestReturnFromNestedBlock_BSBlock34
+    def self.test
+      1.times do
+        while true
+          return :ok
+        end
+      end
+      :bad
+    end
+  end
+  assert_equal :ok, TestReturnFromNestedBlock_BSBlock34.test
+end
+
+assert("BS Block 35") do
+  module TestReturnFromNestedBlock_BSBlock35
+    def self.test
+      1.times do
+        until false
+          return :ok
+        end
+      end
+      :bad
+    end
+  end
+  assert_equal :ok, TestReturnFromNestedBlock_BSBlock35.test
+end
+
+assert('BS Block 36') do
+  def iter
+    yield 1, 2, 3, 4, 5
+  end
+
+  assert_equal([1, 2, [3, 4], 5]) do
+    iter{|a, b, *c, d|
+      [a, b, c, d]
+    }
+  end
+end
+
+assert('BS Block 37') do
+  def iter
+    yield 1, 2, 3
+  end
+
+  assert_equal([1, 2, [], 3]) do
+    iter{|a, b, *c, d|
+      [a, b, c, d]
+    }
+  end
+end
+
+assert('BS Block 38') do
+  def iter
+    yield 1,2,3,4,5,6
+  end
+
+  assert_equal [1,2,3,4,5], iter{|a,b,c=:c,d,e| [a,b,c,d,e]}
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/bs_literal.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/bs_literal.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/bs_literal.rb	(revision 331)
@@ -0,0 +1,38 @@
+##
+# Bootstrap test for literals
+
+assert('BS Literal 1') do
+  assert_true true
+end
+
+assert('BS Literal 2') do
+  assert_equal TrueClass, true.class
+end
+
+assert('BS Literal 3') do
+  assert_false false
+end
+
+assert('BS Literal 4') do
+  assert_equal FalseClass, false.class
+end
+
+assert('BS Literal 5') do
+  assert_equal 'nil', nil.inspect
+end
+
+assert('BS Literal 6') do
+  assert_equal NilClass, nil.class
+end
+
+assert('BS Literal 7') do
+  assert_equal Symbol, :sym.class
+end
+
+assert('BS Literal 8') do
+  assert_equal 1234, 1234
+end
+
+assert('BS Literal 9') do
+  assert_equal Fixnum, 1234.class
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/class.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/class.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/class.rb	(revision 331)
@@ -0,0 +1,451 @@
+##
+# Class ISO Test
+
+assert('Class', '15.2.3') do
+  assert_equal(Class, Class.class)
+end
+
+assert('Class#initialize', '15.2.3.3.1') do
+  c = Class.new do
+    def test
+      :test
+    end
+  end.new
+
+  assert_equal(c.test, :test)
+end
+
+assert('Class#initialize_copy', '15.2.3.3.2') do
+  class TestClass
+    attr_accessor :n
+    def initialize(n)
+      @n = n
+    end
+    def initialize_copy(obj)
+      @n = n
+    end
+  end
+
+  c1 = TestClass.new('Foo')
+  c2 = c1.dup
+  c3 = TestClass.new('Bar')
+
+  assert_equal(c1.n, c2.n)
+  assert_not_equal(c1.n, c3.n)
+end
+
+assert('Class#new', '15.2.3.3.3') do
+  assert_raise(TypeError, 'Singleton should raise TypeError') do
+    "a".singleton_class.new
+  end
+
+  class TestClass
+    def initialize args, &block
+      @result = if not args.nil? and block.nil?
+        # only arguments
+        :only_args
+      elsif not args.nil? and not block.nil?
+        # args and block is given
+        :args_and_block
+      else
+        # this should never happen
+        :broken
+      end
+    end
+
+    def result; @result; end
+  end
+
+  assert_equal(:only_args, TestClass.new(:arg).result)
+  # with block doesn't work yet
+end
+
+assert('Class#superclass', '15.2.3.3.4') do
+  class SubClass < String; end
+  assert_equal(String, SubClass.superclass)
+end
+
+# Not ISO specified
+
+assert('Class 1') do
+  class C1; end
+  assert_equal(Class, C1.class)
+end
+
+assert('Class 2') do
+  class C2; end
+  assert_equal(C2, C2.new.class)
+end
+
+assert('Class 3') do
+  class C3; end
+  assert_equal(Class, C3.new.class.class)
+end
+
+assert('Class 4') do
+  class C4_A; end
+  class C4 < C4_A; end
+  assert_equal(Class, C4.class)
+end
+
+assert('Class 5') do
+  class C5_A; end
+  class C5 < C5_A; end
+  assert_equal(C5, C5.new.class)
+end
+
+assert('Class 6') do
+  class C6_A; end
+  class C6 < C6_A; end
+  assert_equal(Class, C6.new.class.class)
+end
+
+assert('Class 7') do
+  class C7_A; end
+  class C7_B; end
+
+  class C7 < C7_A; end
+
+  assert_raise(TypeError) do
+    # Different superclass.
+    class C7 < C7_B; end
+  end
+end
+
+assert('Class 8') do
+  class C8_A; end
+
+  class C8; end  # superclass is Object
+
+  assert_raise(TypeError) do
+    # Different superclass.
+    class C8 < C8_A; end
+  end
+end
+
+assert('Class 9') do
+  Class9Const = "a"
+
+  assert_raise(TypeError) do
+    class Class9Const; end
+  end
+end
+
+assert('Class Module 1') do
+  module M; end
+  assert_equal(Module, M.class)
+end
+
+assert('Class Module 2') do
+  module M; end
+  class C; include M; end
+  assert_equal(C, C.new.class)
+end
+
+# nested class
+assert('Class Nested 1') do
+  class A; end
+  class A::B; end
+  assert_equal(A::B, A::B)
+end
+
+assert('Class Nested 2') do
+  class A; end
+  class A::B; end
+  assert_equal(A::B, A::B.new.class)
+end
+
+assert('Class Nested 3') do
+  class A; end
+  class A::B; end
+  assert_equal(Class, A::B.new.class.class)
+end
+
+assert('Class Nested 4') do
+  class A; end
+  class A::B; end
+  class A::B::C; end
+  assert_equal(A::B::C, A::B::C)
+end
+
+assert('Class Nested 5') do
+  class A; end
+  class A::B; end
+  class A::B::C; end
+  assert_equal(Class, A::B::C.class)
+end
+
+assert('Class Nested 6') do
+  class A; end
+  class A::B; end
+  class A::B::C; end
+  assert_equal(A::B::C, A::B::C.new.class)
+end
+
+assert('Class Nested 7') do
+  class A; end
+  class A::B; end
+  class A::B2 < A::B; end
+  assert_equal(A::B2, A::B2)
+end
+
+assert('Class Nested 8') do
+  class A; end
+  class A::B; end
+  class A::B2 < A::B; end
+  assert_equal(Class, A::B2.class)
+end
+
+assert('Class Colon 1') do
+  class A; end
+  A::C = 1
+  assert_equal(1, A::C)
+end
+
+assert('Class Colon 2') do
+  class A; class ::C; end end
+  assert_equal(C, C)
+end
+
+assert('Class Colon 3') do
+  class A; class ::C; end end
+  assert_equal(Class, C.class)
+end
+
+assert('Class Dup 1') do
+  class C; end
+  assert_equal(Class, C.dup.class)
+end
+
+assert('Class Dup 2') do
+  module M; end
+  assert_equal(Module, M.dup.class)
+end
+
+assert('Class.new') do
+  assert_equal(Class, Class.new.class)
+  a = []
+  klass = Class.new do |c|
+    a << c
+  end
+  assert_equal([klass], a)
+end
+
+assert('class to return the last value') do
+  m = class C; :m end
+  assert_equal(m, :m)
+end
+
+assert('raise when superclass is not a class') do
+  module FirstModule; end
+  assert_raise(TypeError, 'should raise TypeError') do
+    class FirstClass < FirstModule; end
+  end
+
+  class SecondClass; end
+  assert_raise(TypeError, 'should raise TypeError') do
+    class SecondClass < false; end
+  end
+
+  class ThirdClass; end
+  assert_raise(TypeError, 'should raise TypeError') do
+    class ThirdClass < ThirdClass; end
+  end
+end
+
+assert('Class#inherited') do
+  class Foo
+    @@subclass_name = nil
+    def self.inherited(subclass)
+      @@subclass_name = subclass
+    end
+    def self.subclass_name
+      @@subclass_name
+    end
+  end
+
+  assert_equal(nil, Foo.subclass_name)
+
+  class Bar < Foo
+  end
+
+  assert_equal(Bar, Foo.subclass_name)
+
+  class Baz < Bar
+  end
+
+  assert_equal(Baz, Foo.subclass_name)
+end
+
+assert('singleton tests') do
+  module FooMod
+    def run_foo_mod
+      100
+    end
+  end
+
+  bar = String.new
+
+  baz = class << bar
+    extend FooMod
+    def self.run_baz
+      200
+    end
+  end
+
+  assert_false baz.singleton_methods.include? :run_foo_mod
+  assert_false baz.singleton_methods.include? :run_baz
+
+  assert_raise(NoMethodError, 'should raise NoMethodError') do
+    baz.run_foo_mod
+  end
+  assert_raise(NoMethodError, 'should raise NoMethodError') do
+    baz.run_baz
+  end
+
+  assert_raise(NoMethodError, 'should raise NoMethodError') do
+    bar.run_foo_mod
+  end
+  assert_raise(NoMethodError, 'should raise NoMethodError') do
+    bar.run_baz
+  end
+
+  baz = class << bar
+    extend FooMod
+    def self.run_baz
+      300
+    end
+    self
+  end
+
+  assert_true baz.singleton_methods.include? :run_baz
+  assert_true baz.singleton_methods.include? :run_foo_mod
+  assert_equal 100, baz.run_foo_mod
+  assert_equal 300, baz.run_baz
+
+  assert_raise(NoMethodError, 'should raise NoMethodError') do
+    bar.run_foo_mod
+  end
+  assert_raise(NoMethodError, 'should raise NoMethodError') do
+    bar.run_baz
+  end
+
+  fv = false
+  class << fv
+    def self.run_false
+      5
+    end
+  end
+
+  nv = nil
+  class << nv
+    def self.run_nil
+      6
+    end
+  end
+
+  tv = true
+  class << tv
+    def self.run_nil
+      7
+    end
+  end
+
+  assert_raise(TypeError, 'should raise TypeError') do
+    num = 1.0
+    class << num
+      def self.run_nil
+        7
+      end
+    end
+  end
+end
+
+assert('clone Class') do
+  class Foo
+    def func
+      true
+    end
+  end
+
+  Foo.clone.new.func
+end
+
+assert('class variable and class << self style class method') do
+  class ClassVariableTest
+    @@class_variable = "value"
+    class << self
+      def class_variable
+        @@class_variable
+      end
+    end
+  end
+
+  assert_equal("value", ClassVariableTest.class_variable)
+end
+
+assert('class variable definition in singleton_class') do
+  class ClassVariableDefinitionInSingletonTest
+    class << self
+      @@class_variable = "value"
+    end
+    def class_variable
+      @@class_variable
+    end
+  end
+
+  assert_equal("value", ClassVariableDefinitionInSingletonTest.new.class_variable)
+end
+
+assert('class variable in module and class << self style class method') do
+  module ClassVariableInModuleTest
+    @@class_variable = "value"
+    class << self
+      def class_variable
+        @@class_variable
+      end
+    end
+  end
+
+  assert_equal("value", ClassVariableInModuleTest.class_variable)
+end
+
+assert('child class/module defined in singleton class get parent constant') do
+  actual = module GetParentConstantTest
+            EXPECT = "value"
+            class << self
+              class CHILD
+                class << self
+                    EXPECT
+                end
+              end
+            end
+          end
+  assert_equal("value", actual)
+end
+
+assert('overriding class variable with a module (#3235)') do
+  module ModuleWithCVar
+    @@class_variable = 1
+  end
+  class CVarOverrideTest
+    @@class_variable = 2
+    include ModuleWithCVar
+
+    assert_equal(1, @@class_variable)
+  end
+end
+
+assert('class with non-class/module outer raises TypeError') do
+  assert_raise(TypeError) { class 0::C1; end }
+  assert_raise(TypeError) { class []::C2; end }
+end
+
+assert("remove_method doesn't segfault if the passed in argument isn't a symbol") do
+  klass = Class.new
+  assert_raise(TypeError) { klass.remove_method nil }
+  assert_raise(TypeError) { klass.remove_method 123 }
+  assert_raise(TypeError) { klass.remove_method 1.23 }
+  assert_raise(NameError) { klass.remove_method "hello" }
+  assert_raise(TypeError) { klass.remove_method Class.new }
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/codegen.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/codegen.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/codegen.rb	(revision 331)
@@ -0,0 +1,75 @@
+##
+# Codegen tests
+
+assert('peephole optimization does not eliminate move whose result is reused') do
+  assert_raise LocalJumpError do
+    def method
+      yield
+    end
+    method(&a &&= 0)
+  end
+end
+
+assert('empty condition in ternary expression parses correctly') do
+  assert_equal(() ? 1 : 2, 2)
+end
+
+assert('method call with exactly 127 arguments') do
+  def args_to_ary(*args)
+    args
+  end
+
+  assert_equal [0]*127, args_to_ary(
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, \
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+  )
+end
+
+assert('nested empty heredoc') do
+  _, a = nil, <<B
+#{<<A}
+A
+B
+  assert_equal "\n", a
+end
+
+assert('splat in case splat') do
+  a = *case
+    when 0
+      * = 1
+  end
+
+  assert_equal [1], a
+end
+
+assert('undef with 127 or more arguments') do
+  assert_raise NameError do
+    undef
+      a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a,
+      a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a,
+      a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a,
+      a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a, a
+  end
+end
+
+assert('next in normal loop with 127 arguments') do
+  assert_raise NameError do
+    while true
+      next A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A
+    end
+  end
+end
+
+assert('negate literal register alignment') do
+  a = *case
+  when 0
+    -0.0
+    2
+  end
+
+  assert_equal [2], a
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/comparable.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/comparable.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/comparable.rb	(revision 331)
@@ -0,0 +1,80 @@
+
+assert('Comparable#<', '15.3.3.2.1') do
+  class Foo
+    include Comparable
+    def <=>(x)
+      x
+    end
+  end
+  assert_false(Foo.new < 0)
+  assert_false(Foo.new < 1)
+  assert_true(Foo.new < -1)
+  assert_raise(ArgumentError){ Foo.new < nil }
+end
+
+assert('Comparable#<=', '15.3.3.2.2') do
+  class Foo
+    include Comparable
+    def <=>(x)
+      x
+    end
+  end
+  assert_true(Foo.new <= 0)
+  assert_false(Foo.new <= 1)
+  assert_true(Foo.new <= -1)
+  assert_raise(ArgumentError){ Foo.new <= nil }
+end
+
+assert('Comparable#==', '15.3.3.2.3') do
+  class Foo
+    include Comparable
+    def <=>(x)
+      0
+    end
+  end
+
+  assert_true(Foo.new == Foo.new)
+end
+
+assert('Comparable#>', '15.3.3.2.4') do
+  class Foo
+    include Comparable
+    def <=>(x)
+      x
+    end
+  end
+  assert_false(Foo.new > 0)
+  assert_true(Foo.new > 1)
+  assert_false(Foo.new > -1)
+  assert_raise(ArgumentError){ Foo.new > nil }
+end
+
+assert('Comparable#>=', '15.3.3.2.5') do
+  class Foo
+    include Comparable
+    def <=>(x)
+      x
+    end
+  end
+  assert_true(Foo.new >= 0)
+  assert_true(Foo.new >= 1)
+  assert_false(Foo.new >= -1)
+  assert_raise(ArgumentError){ Foo.new >= nil }
+end
+
+assert('Comparable#between?', '15.3.3.2.6') do
+  class Foo
+    include Comparable
+    def <=>(x)
+      x
+    end
+  end
+
+  c = Foo.new
+
+  assert_false(c.between?(-1,  1))
+  assert_false(c.between?(-1, -1))
+  assert_false(c.between?( 1,  1))
+  assert_true(c.between?( 1, -1))
+  assert_true(c.between?(0, 0))
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/ensure.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/ensure.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/ensure.rb	(revision 331)
@@ -0,0 +1,54 @@
+##
+# ensure Test
+
+assert('ensure - context - yield') do
+  class EnsureYieldBreak
+    attr_reader :ensure_context
+    def try
+      yield
+    ensure
+      @ensure_context = self
+    end
+  end
+
+  yielder = EnsureYieldBreak.new
+  yielder.try do
+  end
+  assert_equal yielder, yielder.ensure_context
+end
+
+assert('ensure - context - yield and break') do
+  class EnsureYieldBreak
+    attr_reader :ensure_context
+    def try
+      yield
+    ensure
+      @ensure_context = self
+    end
+  end
+
+  yielder = EnsureYieldBreak.new
+  yielder.try do
+    break
+  end
+  assert_equal yielder, yielder.ensure_context
+end
+
+assert('ensure - context - yield and return') do
+  class EnsureYieldBreak
+    attr_reader :ensure_context
+    def try
+      yield
+    ensure
+      @ensure_context = self
+    end
+  end
+
+  yielder = EnsureYieldBreak.new
+  lambda do
+    yielder.try do
+      return
+    end
+  end.call
+  assert_equal yielder, yielder.ensure_context
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/enumerable.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/enumerable.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/enumerable.rb	(revision 331)
@@ -0,0 +1,134 @@
+##
+# Enumerable ISO Test
+
+assert('Enumerable', '15.3.2') do
+  assert_equal(Module, Enumerable.class)
+end
+
+assert('Enumerable#all?', '15.3.2.2.1') do
+  assert_true([1,2,3].all?)
+  assert_false([1,false,3].all?)
+
+  a = [2,4,6]
+  all = a.all? do |e|
+    e % 2 == 0
+  end
+  assert_true(all)
+
+  a = [2,4,7]
+  all = a.all? do |e|
+    e % 2 == 0
+  end
+  assert_false(all)
+end
+
+assert('Enumerable#any?', '15.3.2.2.2') do
+  assert_true([false,true,false].any?)
+  assert_false([false,false,false].any?)
+
+  a = [1,3,6]
+  any = a.any? do |e|
+    e % 2 == 0
+  end
+  assert_true(any)
+
+  a = [1,3,5]
+  any = a.any? do |e|
+    e % 2 == 0
+  end
+  assert_false(any)
+end
+
+assert('Enumerable#collect', '15.3.2.2.3') do
+  assert_true [1,2,3].collect { |i| i + i } == [2,4,6]
+end
+
+assert('Enumerable#detect', '15.3.2.2.4') do
+  assert_equal 1, [1,2,3].detect() { true }
+  assert_equal 'a', [1,2,3].detect("a") { false }
+end
+
+assert('Array#each_with_index', '15.3.2.2.5') do
+  a = nil
+  b = nil
+
+  [1].each_with_index {|e,i| a = e; b = i}
+
+  assert_equal(1, a)
+  assert_equal(0, b)
+end
+
+assert('Enumerable#entries', '15.3.2.2.6') do
+  assert_equal([1], [1].entries)
+end
+
+assert('Enumerable#find', '15.3.2.2.7') do
+  assert_equal 1, [1,2,3].find() { true }
+  assert_equal 'a', [1,2,3].find("a") { false }
+end
+
+assert('Enumerable#find_all', '15.3.2.2.8') do
+  assert_true [1,2,3,4,5,6,7,8,9].find_all() {|i| i%2 == 0}, [2,4,6,8]
+end
+
+assert('Enumerable#grep', '15.3.2.2.9') do
+  assert_equal [4,5,6], [1,2,3,4,5,6,7,8,9].grep(4..6)
+end
+
+assert('Enumerable#include?', '15.3.2.2.10') do
+  assert_true [1,2,3,4,5,6,7,8,9].include?(5)
+  assert_false [1,2,3,4,5,6,7,8,9].include?(0)
+end
+
+assert('Enumerable#inject', '15.3.2.2.11') do
+  assert_equal 21, [1,2,3,4,5,6].inject() {|s, n| s + n}
+  assert_equal 22, [1,2,3,4,5,6].inject(1) {|s, n| s + n}
+end
+
+assert('Enumerable#map', '15.3.2.2.12') do
+  assert_equal [2,4,6], [1,2,3].map { |i| i + i }
+end
+
+assert('Enumerable#max', '15.3.2.2.13') do
+  a = ['aaa', 'bb', 'c']
+  assert_equal 'c', a.max
+  assert_equal 'aaa', a.max {|i1,i2| i1.length <=> i2.length}
+end
+
+assert('Enumerable#min', '15.3.2.2.14') do
+  a = ['aaa', 'bb', 'c']
+  assert_equal 'aaa', a.min
+  assert_equal 'c', a.min {|i1,i2| i1.length <=> i2.length}
+end
+
+assert('Enumerable#member?', '15.3.2.2.15') do
+  assert_true [1,2,3,4,5,6,7,8,9].member?(5)
+  assert_false [1,2,3,4,5,6,7,8,9].member?(0)
+end
+
+assert('Enumerable#partition', '15.3.2.2.16') do
+  partition = [0,1,2,3,4,5,6,7,8,9].partition do |i|
+    i % 2 == 0
+  end
+  assert_equal [[0,2,4,6,8], [1,3,5,7,9]], partition
+end
+
+assert('Enumerable#reject', '15.3.2.2.17') do
+  reject = [0,1,2,3,4,5,6,7,8,9].reject do |i|
+    i % 2 == 0
+  end
+  assert_equal [1,3,5,7,9], reject
+end
+
+assert('Enumerable#select', '15.3.2.2.18') do
+  assert_equal [2,4,6,8], [1,2,3,4,5,6,7,8,9].select() {|i| i%2 == 0}
+end
+
+assert('Enumerable#sort', '15.3.2.2.19') do
+  assert_equal [1,2,3,4,6,7], [7,3,1,2,6,4].sort
+  assert_equal [7,6,4,3,2,1], [7,3,1,2,6,4].sort {|e1,e2|e2<=>e1}
+end
+
+assert('Enumerable#to_a', '15.3.2.2.20') do
+  assert_equal [1], [1].to_a
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/exception.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/exception.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/exception.rb	(revision 331)
@@ -0,0 +1,422 @@
+##
+# Exception ISO Test
+
+assert('Exception', '15.2.22') do
+  assert_equal Class, Exception.class
+end
+
+assert('Exception.exception', '15.2.22.4.1') do
+  e = Exception.exception('a')
+
+  assert_equal Exception, e.class
+end
+
+assert('Exception#exception', '15.2.22.5.1') do
+  e = Exception.new
+  re = RuntimeError.new
+  assert_equal e, e.exception
+  assert_equal e, e.exception(e)
+  assert_equal re, re.exception(re)
+  changed_re = re.exception('message has changed')
+  assert_not_equal re, changed_re
+  assert_equal 'message has changed', changed_re.message
+end
+
+assert('Exception#message', '15.2.22.5.2') do
+  e = Exception.exception('a')
+
+  assert_equal 'a', e.message
+end
+
+assert('Exception#to_s', '15.2.22.5.3') do
+  e = Exception.exception('a')
+
+  assert_equal 'a', e.to_s
+end
+
+assert('Exception.exception', '15.2.22.4.1') do
+  e = Exception.exception()
+  e.initialize('a')
+
+  assert_equal 'a', e.message
+end
+
+assert('NameError', '15.2.31') do
+  assert_raise(NameError) do
+    raise NameError.new
+  end
+
+  e = NameError.new "msg", "name"
+  assert_equal "msg", e.message
+  assert_equal "name", e.name
+end
+
+assert('ScriptError', '15.2.37') do
+  assert_raise(ScriptError) do
+    raise ScriptError.new
+  end
+end
+
+assert('SyntaxError', '15.2.38') do
+  assert_raise(SyntaxError) do
+    raise SyntaxError.new
+  end
+end
+
+# Not ISO specified
+
+assert('Exception 1') do
+r=begin
+    1+1
+  ensure
+    2+2
+  end
+  assert_equal 2, r
+end
+
+assert('Exception 2') do
+r=begin
+    1+1
+    begin
+      2+2
+    ensure
+      3+3
+    end
+  ensure
+    4+4
+  end
+  assert_equal 4, r
+end
+
+assert('Exception 3') do
+r=begin
+    1+1
+    begin
+      2+2
+    ensure
+      3+3
+    end
+  ensure
+    4+4
+    begin
+      5+5
+    ensure
+      6+6
+    end
+  end
+  assert_equal 4, r
+end
+
+assert('Exception 4') do
+  a = nil
+  1.times{|e|
+    begin
+    rescue => err
+    end
+    a = err.class
+  }
+  assert_equal NilClass, a
+end
+
+assert('Exception 5') do
+  $ans = []
+  def m
+    $!
+  end
+  def m2
+    1.times{
+      begin
+        return
+      ensure
+        $ans << m
+      end
+    }
+  end
+  m2
+  assert_equal [nil], $ans
+end
+
+assert('Exception 6') do
+  $i = 0
+  def m
+    iter{
+      begin
+        $i += 1
+        begin
+          $i += 2
+          break
+        ensure
+
+        end
+      ensure
+        $i += 4
+      end
+      $i = 0
+    }
+  end
+
+  def iter
+    yield
+  end
+  m
+  assert_equal 7, $i
+end
+
+assert('Exception 7') do
+  $i = 0
+  def m
+    begin
+      $i += 1
+      begin
+        $i += 2
+        return
+      ensure
+        $i += 3
+      end
+    ensure
+      $i += 4
+    end
+    p :end
+  end
+  m
+  assert_equal 10, $i
+end
+
+assert('Exception 8') do
+r=begin
+    1
+  rescue
+    2
+  else
+    3
+  end
+  assert_equal 3, r
+end
+
+assert('Exception 9') do
+r=begin
+    1+1
+  rescue
+    2+2
+  else
+    3+3
+  ensure
+    4+4
+  end
+  assert_equal 6, r
+end
+
+assert('Exception 10') do
+r=begin
+    1+1
+    begin
+      2+2
+    rescue
+      3+3
+    else
+      4+4
+    end
+  rescue
+    5+5
+  else
+    6+6
+  ensure
+    7+7
+  end
+  assert_equal 12, r
+end
+
+assert('Exception 11') do
+  a = :ok
+  begin
+    begin
+      raise Exception
+    rescue
+      a = :ng
+    end
+  rescue Exception
+  end
+  assert_equal :ok, a
+end
+
+assert('Exception 12') do
+  a = :ok
+  begin
+    raise Exception rescue a = :ng
+  rescue Exception
+  end
+  assert_equal :ok, a
+end
+
+assert('Exception 13') do
+  a = :ng
+  begin
+    raise StandardError
+  rescue TypeError, ArgumentError
+    a = :ng
+  rescue
+    a = :ok
+  else
+    a = :ng
+  end
+  assert_equal :ok, a
+end
+
+assert('Exception 14') do
+  def exception_test14; UnknownConstant; end
+  a = :ng
+  begin
+    send(:exception_test14)
+  rescue
+    a = :ok
+  end
+
+  assert_equal :ok, a
+end
+
+assert('Exception 15') do
+  a = begin
+        :ok
+      rescue
+        :ko
+      end
+  assert_equal :ok, a
+end
+
+assert('Exception 16') do
+  begin
+    raise "foo"
+    false
+  rescue => e
+    assert_equal "foo", e.message
+  end
+end
+
+assert('Exception 17') do
+r=begin
+    raise "a"  # RuntimeError
+  rescue ArgumentError
+    1
+  rescue StandardError
+    2
+  else
+    3
+  ensure
+    4
+  end
+  assert_equal 2, r
+end
+
+assert('Exception 18') do
+r=begin
+    0
+  rescue ArgumentError
+    1
+  rescue StandardError
+    2
+  else
+    3
+  ensure
+    4
+  end
+  assert_equal 3, r
+end
+
+assert('Exception 19') do
+  class Class4Exception19
+    def a
+      r = @e = false
+      begin
+        b
+      rescue TypeError
+        r = self.z
+      end
+      [ r, @e ]
+    end
+
+    def b
+      begin
+        1 * "b"
+      ensure
+        @e = self.zz
+      end
+    end
+
+    def zz
+      true
+    end
+    def z
+      true
+    end
+  end
+  assert_equal [true, true], Class4Exception19.new.a
+end
+
+assert('Exception#inspect without message') do
+  assert_equal "Exception", Exception.new.inspect
+end
+
+assert('Exception#backtrace') do
+  assert_nothing_raised do
+    begin
+      raise "get backtrace"
+    rescue => e
+      e.backtrace
+    end
+  end
+end
+
+assert('Raise in ensure') do
+  assert_raise(ArgumentError) do
+    begin
+      raise "" # RuntimeError
+    ensure
+      raise ArgumentError
+    end
+  end
+end
+
+def backtrace_available?
+  begin
+    raise "XXX"
+  rescue => exception
+    not exception.backtrace.empty?
+  end
+end
+
+assert('GC in rescue') do
+  skip "backtrace isn't available" unless backtrace_available?
+
+  line = nil
+  begin
+    [1].each do
+      [2].each do
+        [3].each do
+          line = __LINE__; raise "XXX"
+        end
+      end
+    end
+  rescue => exception
+    GC.start
+    assert_equal("#{__FILE__}:#{line}:in call",
+                 exception.backtrace.first)
+  end
+end
+
+assert('Method call in rescue') do
+  skip "backtrace isn't available" unless backtrace_available?
+
+  line = nil
+  begin
+    [1].each do
+      [2].each do
+        line = __LINE__; raise "XXX"
+      end
+    end
+  rescue => exception
+    [3].each do
+    end
+    assert_equal("#{__FILE__}:#{line}:in call",
+                 exception.backtrace.first)
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/false.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/false.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/false.rb	(revision 331)
@@ -0,0 +1,31 @@
+##
+# FalseClass ISO Test
+
+assert('FalseClass', '15.2.6') do
+  assert_equal Class, FalseClass.class
+end
+
+assert('FalseClass false', '15.2.6.1') do
+  assert_false false
+  assert_equal FalseClass, false.class
+  assert_false FalseClass.method_defined? :new
+end
+
+assert('FalseClass#&', '15.2.6.3.1') do
+  assert_false false.&(true)
+  assert_false false.&(false)
+end
+
+assert('FalseClass#^', '15.2.6.3.2') do
+  assert_true false.^(true)
+  assert_false false.^(false)
+end
+
+assert('FalseClass#to_s', '15.2.6.3.3') do
+  assert_equal 'false', false.to_s
+end
+
+assert('FalseClass#|', '15.2.6.3.4') do
+  assert_true false.|(true)
+  assert_false false.|(false)
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/float.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/float.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/float.rb	(revision 331)
@@ -0,0 +1,205 @@
+##
+# Float ISO Test
+
+assert('Float', '15.2.9') do
+  assert_equal Class, Float.class
+end
+
+assert('Float#+', '15.2.9.3.1') do
+  a = 3.123456788 + 0.000000001
+  b = 3.123456789 + 1
+
+  assert_float(3.123456789, a)
+  assert_float(4.123456789, b)
+
+  assert_raise(TypeError){ 0.0+nil }
+  assert_raise(TypeError){ 1.0+nil }
+end
+
+assert('Float#-', '15.2.9.3.2') do
+  a = 3.123456790 - 0.000000001
+  b = 5.123456789 - 1
+
+  assert_float(3.123456789, a)
+  assert_float(4.123456789, b)
+end
+
+assert('Float#*', '15.2.9.3.3') do
+  a = 3.125 * 3.125
+  b = 3.125 * 1
+
+  assert_float(9.765625, a)
+  assert_float(3.125   , b)
+end
+
+assert('Float#/', '15.2.9.3.4') do
+  a = 3.123456789 / 3.123456789
+  b = 3.123456789 / 1
+
+  assert_float(1.0        , a)
+  assert_float(3.123456789, b)
+end
+
+assert('Float#%', '15.2.9.3.5') do
+  a = 3.125 % 3.125
+  b = 3.125 % 1
+
+  assert_float(0.0  , a)
+  assert_float(0.125, b)
+end
+
+assert('Float#<=>', '15.2.9.3.6') do
+  a = 3.125 <=> 3.123
+  b = 3.125 <=> 3.125
+  c = 3.125 <=> 3.126
+  a2 = 3.125 <=> 3
+  c2 = 3.125 <=> 4
+
+  assert_equal( 1, a)
+  assert_equal( 0, b)
+  assert_equal(-1, c)
+  assert_equal( 1, a2)
+  assert_equal(-1, c2)
+end
+
+assert('Float#==', '15.2.9.3.7') do
+  assert_true 3.1 == 3.1
+  assert_false 3.1 == 3.2
+end
+
+assert('Float#ceil', '15.2.9.3.8') do
+  a = 3.123456789.ceil
+  b = 3.0.ceil
+  c = -3.123456789.ceil
+  d = -3.0.ceil
+
+  assert_equal( 4, a)
+  assert_equal( 3, b)
+  assert_equal(-3, c)
+  assert_equal(-3, d)
+end
+
+assert('Float#finite?', '15.2.9.3.9') do
+  assert_true 3.123456789.finite?
+  assert_false (1.0 / 0.0).finite?
+end
+
+assert('Float#floor', '15.2.9.3.10') do
+  a = 3.123456789.floor
+  b = 3.0.floor
+  c = -3.123456789.floor
+  d = -3.0.floor
+
+  assert_equal( 3, a)
+  assert_equal( 3, b)
+  assert_equal(-4, c)
+  assert_equal(-3, d)
+end
+
+assert('Float#infinite?', '15.2.9.3.11') do
+  a = 3.123456789.infinite?
+  b = (1.0 / 0.0).infinite?
+  c = (-1.0 / 0.0).infinite?
+
+  assert_nil a
+  assert_equal( 1, b)
+  assert_equal(-1, c)
+end
+
+assert('Float#round', '15.2.9.3.12') do
+  a = 3.123456789.round
+  b = 3.5.round
+  c = 3.4999.round
+  d = (-3.123456789).round
+  e = (-3.5).round
+  f = 12345.67.round(-1)
+  g = 3.423456789.round(0)
+  h = 3.423456789.round(1)
+  i = 3.423456789.round(3)
+
+  assert_equal(    3, a)
+  assert_equal(    4, b)
+  assert_equal(    3, c)
+  assert_equal(   -3, d)
+  assert_equal(   -4, e)
+  assert_equal(12350, f)
+  assert_equal(    3, g)
+  assert_float(  3.4, h)
+  assert_float(3.423, i)
+
+  assert_equal(42.0, 42.0.round(307))
+  assert_equal(1.0e307, 1.0e307.round(2))
+
+  inf = 1.0/0.0
+  assert_raise(FloatDomainError){ inf.round }
+  assert_raise(FloatDomainError){ inf.round(-1) }
+  assert_equal(inf, inf.round(1))
+  nan = 0.0/0.0
+  assert_raise(FloatDomainError){ nan.round }
+  assert_raise(FloatDomainError){ nan.round(-1) }
+  assert_true(nan.round(1).nan?)
+end
+
+assert('Float#to_f', '15.2.9.3.13') do
+  a = 3.123456789
+
+  assert_float(a, a.to_f)
+end
+
+assert('Float#to_i', '15.2.9.3.14') do
+  assert_equal(3, 3.123456789.to_i)
+  assert_raise(FloatDomainError) { Float::INFINITY.to_i }
+  assert_raise(FloatDomainError) { (-Float::INFINITY).to_i }
+  assert_raise(FloatDomainError) { Float::NAN.to_i }
+end
+
+assert('Float#truncate', '15.2.9.3.15') do
+  assert_equal( 3,  3.123456789.truncate)
+  assert_equal(-3, -3.1.truncate)
+end
+
+assert('Float#divmod') do
+  def check_floats exp, act
+    assert_float exp[0], act[0]
+    assert_float exp[1], act[1]
+  end
+
+  # Note: quotients are Float because mruby does not have Bignum.
+  check_floats [ 0,  0.0],   0.0.divmod(1)
+  check_floats [ 0,  1.1],   1.1.divmod(3)
+  check_floats [ 3,  0.2],   3.2.divmod(1)
+  check_floats [ 2,  6.3],  20.3.divmod(7)
+  check_floats [-1,  1.6],  -3.4.divmod(5)
+  check_floats [-2, -0.5],  25.5.divmod(-13)
+  check_floats [ 1, -6.6], -13.6.divmod(-7)
+  check_floats [ 3,  0.2],   9.8.divmod(3.2)
+end
+
+assert('Float#nan?') do
+  assert_true (0.0/0.0).nan?
+  assert_false 0.0.nan?
+  assert_false (1.0/0.0).nan?
+  assert_false (-1.0/0.0).nan?
+end
+
+assert('Float#<<') do
+  # Left Shift by one
+  assert_equal 46, 23.0 << 1
+
+  # Left Shift by a negative is Right Shift
+  assert_equal 23, 46.0 << -1
+end
+
+assert('Float#>>') do
+  # Right Shift by one
+  assert_equal 23, 46.0 >> 1
+
+  # Right Shift by a negative is Left Shift
+  assert_equal 46, 23.0 >> -1
+
+  # Don't raise on large Right Shift
+  assert_equal 0, 23.0 >> 128
+
+  # Don't raise on large Right Shift
+  assert_equal(-1, -23.0 >> 128)
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/gc.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/gc.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/gc.rb	(revision 331)
@@ -0,0 +1,45 @@
+# Not ISO specified
+
+assert('GC.enable') do
+  assert_false GC.disable
+  assert_true GC.enable
+  assert_false GC.enable
+end
+
+assert('GC.disable') do
+  begin
+    assert_false GC.disable
+    assert_true GC.disable
+  ensure
+    GC.enable
+  end
+end
+
+assert('GC.interval_ratio=') do
+  origin = GC.interval_ratio
+  begin
+    assert_equal 150, (GC.interval_ratio = 150)
+  ensure
+    GC.interval_ratio = origin
+  end
+end
+
+assert('GC.step_ratio=') do
+  origin = GC.step_ratio
+  begin
+    assert_equal 150, (GC.step_ratio = 150)
+  ensure
+    GC.step_ratio = origin
+  end
+end
+
+assert('GC.generational_mode=') do
+  origin = GC.generational_mode
+  begin
+    assert_false (GC.generational_mode = false)
+    assert_true (GC.generational_mode = true)
+    assert_true (GC.generational_mode = true)
+  ensure
+    GC.generational_mode = origin
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/hash.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/hash.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/hash.rb	(revision 331)
@@ -0,0 +1,375 @@
+##
+# Hash ISO Test
+
+assert('Hash', '15.2.13') do
+  assert_equal Class, Hash.class
+end
+
+assert('Hash#==', '15.2.13.4.1') do
+  assert_true({ 'abc' => 'abc' } == { 'abc' => 'abc' })
+  assert_false({ 'abc' => 'abc' } ==  { 'cba' => 'cba' })
+  assert_true({ :equal => 1 } == { :equal => 1.0 })
+  assert_false({ :a => 1 } == true)
+end
+
+assert('Hash#[]', '15.2.13.4.2') do
+  a = { 'abc' => 'abc' }
+
+  assert_equal 'abc', a['abc']
+
+  # Hash#[] should call #default (#3272)
+  hash = {}
+  def hash.default(k); self[k] = 1; end
+  hash[:foo] += 1
+
+  assert_equal 2, hash[:foo]
+end
+
+assert('Hash#[]=', '15.2.13.4.3') do
+  a = Hash.new
+  a['abc'] = 'abc'
+
+  assert_equal 'abc', a['abc']
+end
+
+assert('Hash#clear', '15.2.13.4.4') do
+  a = { 'abc' => 'abc' }
+  a.clear
+
+  assert_equal({ }, a)
+end
+
+assert('Hash#dup') do
+  a = { 'a' => 1 }
+  b = a.dup
+  a['a'] = 2
+  assert_equal({'a' => 1}, b)
+
+  c = Hash.new { |h, k| h[k] = k.upcase }
+  d = c.dup
+  assert_equal("FOO", d["foo"])
+end
+
+assert('Hash#default', '15.2.13.4.5') do
+  a = Hash.new
+  b = Hash.new('abc')
+  c = Hash.new {|s,k| s[k] = k}
+
+  assert_nil a.default
+  assert_equal 'abc', b.default
+  assert_nil c.default
+  assert_equal 'abc', c.default('abc')
+end
+
+assert('Hash#default=', '15.2.13.4.6') do
+  a = { 'abc' => 'abc' }
+  a.default = 'cba'
+
+  assert_equal 'abc', a['abc']
+  assert_equal 'cba', a['notexist']
+end
+
+assert('Hash#default_proc', '15.2.13.4.7') do
+  a = Hash.new
+  b = Hash.new {|s,k| s[k] = k + k}
+  c = b[2]
+  d = b['cat']
+
+  assert_nil a.default_proc
+  assert_equal Proc, b.default_proc.class
+  assert_equal 4, c
+  assert_equal 'catcat', d
+end
+
+assert('Hash#delete', '15.2.13.4.8') do
+  a = { 'abc' => 'abc' }
+  b = { 'abc' => 'abc' }
+  b_tmp_1 = false
+  b_tmp_2 = false
+
+  a.delete('abc')
+  b.delete('abc') do |k|
+    b_tmp_1 = true
+  end
+  b.delete('abc') do |k|
+    b_tmp_2 = true
+  end
+
+  assert_nil a.delete('cba')
+  assert_false a.has_key?('abc')
+  assert_false b_tmp_1
+  assert_true b_tmp_2
+end
+
+assert('Hash#each', '15.2.13.4.9') do
+  a = { 'abc_key' => 'abc_value' }
+  key = nil
+  value = nil
+
+  a.each  do |k,v|
+    key = k
+    value = v
+  end
+
+  assert_equal 'abc_key', key
+  assert_equal 'abc_value', value
+end
+
+assert('Hash#each_key', '15.2.13.4.10') do
+  a = { 'abc_key' => 'abc_value' }
+  key = nil
+
+  a.each_key  do |k|
+    key = k
+  end
+
+  assert_equal 'abc_key', key
+end
+
+assert('Hash#each_value', '15.2.13.4.11') do
+  a = { 'abc_key' => 'abc_value' }
+  value = nil
+
+  a.each_value  do |v|
+    value = v
+  end
+
+  assert_equal 'abc_value', value
+end
+
+assert('Hash#empty?', '15.2.13.4.12') do
+  a = { 'abc_key' => 'abc_value' }
+  b = Hash.new
+
+  assert_false a.empty?
+  assert_true b.empty?
+end
+
+assert('Hash#has_key?', '15.2.13.4.13') do
+  a = { 'abc_key' => 'abc_value' }
+  b = Hash.new
+
+  assert_true a.has_key?('abc_key')
+  assert_false b.has_key?('cba')
+end
+
+assert('Hash#has_value?', '15.2.13.4.14') do
+  a = { 'abc_key' => 'abc_value' }
+  b = Hash.new
+
+  assert_true a.has_value?('abc_value')
+  assert_false b.has_value?('cba')
+end
+
+assert('Hash#include?', '15.2.13.4.15') do
+  a = { 'abc_key' => 'abc_value' }
+  b = Hash.new
+
+  assert_true a.include?('abc_key')
+  assert_false b.include?('cba')
+end
+
+assert('Hash#initialize', '15.2.13.4.16') do
+  # Testing initialize by new.
+  h = Hash.new
+  h2 = Hash.new(:not_found)
+
+  assert_true h.is_a? Hash
+  assert_equal({ }, h)
+  assert_nil h["hello"]
+  assert_equal :not_found, h2["hello"]
+end
+
+assert('Hash#initialize_copy', '15.2.13.4.17') do
+  a = { 'abc_key' => 'abc_value' }
+  b = Hash.new.initialize_copy(a)
+
+  assert_equal({ 'abc_key' => 'abc_value' }, b)
+end
+
+assert('Hash#key?', '15.2.13.4.18') do
+  a = { 'abc_key' => 'abc_value' }
+  b = Hash.new
+
+  assert_true a.key?('abc_key')
+  assert_false b.key?('cba')
+end
+
+assert('Hash#keys', '15.2.13.4.19') do
+  a = { 'abc_key' => 'abc_value' }
+
+  assert_equal ['abc_key'], a.keys
+end
+
+assert('Hash#length', '15.2.13.4.20') do
+  a = { 'abc_key' => 'abc_value' }
+  b = Hash.new
+
+  assert_equal 1, a.length
+  assert_equal 0, b.length
+end
+
+assert('Hash#member?', '15.2.13.4.21') do
+  a = { 'abc_key' => 'abc_value' }
+  b = Hash.new
+
+  assert_true a.member?('abc_key')
+  assert_false b.member?('cba')
+end
+
+assert('Hash#merge', '15.2.13.4.22') do
+  a = { 'abc_key' => 'abc_value', 'cba_key' => 'cba_value' }
+  b = { 'cba_key' => 'XXX',  'xyz_key' => 'xyz_value' }
+
+  result_1 = a.merge b
+  result_2 = a.merge(b) do |key, original, new|
+    original
+  end
+
+  assert_equal({'abc_key' => 'abc_value', 'cba_key' => 'XXX',
+                'xyz_key' => 'xyz_value' }, result_1)
+  assert_equal({'abc_key' => 'abc_value', 'cba_key' => 'cba_value',
+                'xyz_key' => 'xyz_value' }, result_2)
+
+  assert_raise(TypeError) do
+    { 'abc_key' => 'abc_value' }.merge "a"
+  end
+end
+
+assert('Hash#replace', '15.2.13.4.23') do
+  a = { 'abc_key' => 'abc_value' }
+  b = Hash.new.replace(a)
+
+  assert_equal({ 'abc_key' => 'abc_value' }, b)
+
+  a = Hash.new(42)
+  b = {}
+  b.replace(a)
+  assert_equal(42, b[1])
+
+  a = Hash.new{|h,x| x}
+  b.replace(a)
+  assert_equal(127, b[127])
+
+   assert_raise(TypeError) do
+    { 'abc_key' => 'abc_value' }.replace "a"
+  end
+end
+
+assert('Hash#shift', '15.2.13.4.24') do
+  a = { 'abc_key' => 'abc_value', 'cba_key' => 'cba_value' }
+  b = a.shift
+
+  assert_equal Array, b.class
+  assert_equal 2, b.size
+  assert_equal 1, a.size
+
+  b = a.shift
+
+  assert_equal Array, b.class
+  assert_equal 2, b.size
+  assert_equal 0, a.size
+end
+
+assert('Hash#size', '15.2.13.4.25') do
+  a = { 'abc_key' => 'abc_value' }
+  b = Hash.new
+
+  assert_equal 1, a.size
+  assert_equal 0, b.size
+end
+
+assert('Hash#store', '15.2.13.4.26') do
+  a = Hash.new
+  a.store('abc', 'abc')
+
+  assert_equal 'abc', a['abc']
+end
+
+assert('Hash#value?', '15.2.13.4.27') do
+  a = { 'abc_key' => 'abc_value' }
+  b = Hash.new
+
+  assert_true a.value?('abc_value')
+  assert_false b.value?('cba')
+end
+
+assert('Hash#values', '15.2.13.4.28') do
+  a = { 'abc_key' => 'abc_value' }
+
+  assert_equal ['abc_value'], a.values
+end
+
+# Not ISO specified
+
+assert('Hash#eql?') do
+  a = { 'a' => 1, 'b' => 2, 'c' => 3 }
+  b = { 'a' => 1, 'b' => 2, 'c' => 3 }
+  c = { 'a' => 1.0, 'b' => 2, 'c' => 3 }
+  assert_true(a.eql?(b))
+  assert_false(a.eql?(c))
+  assert_false(a.eql?(true))
+end
+
+assert('Hash#reject') do
+  h = {:one => 1, :two => 2, :three => 3, :four => 4}
+  ret = h.reject do |k,v|
+    v % 2 == 0
+  end
+  assert_equal({:one => 1, :three => 3}, ret)
+  assert_equal({:one => 1, :two => 2, :three => 3, :four => 4}, h)
+end
+
+assert('Hash#reject!') do
+  h = {:one => 1, :two => 2, :three => 3, :four => 4}
+  ret = h.reject! do |k,v|
+    v % 2 == 0
+  end
+  assert_equal({:one => 1, :three => 3}, ret)
+  assert_equal({:one => 1, :three => 3}, h)
+end
+
+assert('Hash#select') do
+  h = {:one => 1, :two => 2, :three => 3, :four => 4}
+  ret = h.select do |k,v|
+    v % 2 == 0
+  end
+  assert_equal({:two => 2, :four => 4}, ret)
+  assert_equal({:one => 1, :two => 2, :three => 3, :four => 4}, h)
+end
+
+assert('Hash#select!') do
+  h = {:one => 1, :two => 2, :three => 3, :four => 4}
+  ret = h.select! do |k,v|
+    v % 2 == 0
+  end
+  assert_equal({:two => 2, :four => 4}, ret)
+  assert_equal({:two => 2, :four => 4}, h)
+end
+
+# Not ISO specified
+
+assert('Hash#inspect') do
+  h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300  }
+  ret = h.to_s
+
+  assert_include ret, '"c"=>300'
+  assert_include ret, '"a"=>100'
+  assert_include ret, '"d"=>400'
+end
+
+assert('Hash#rehash') do
+  h = {[:a] => "b"}
+  # hash key modified
+  h.keys[0][0] = :b
+  # h[[:b]] => nil
+  h.rehash
+  assert_equal("b", h[[:b]])
+end
+
+assert('Hash#freeze') do
+  h = {}.freeze
+  assert_raise(RuntimeError) do
+    h[:a] = 'b'
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/indexerror.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/indexerror.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/indexerror.rb	(revision 331)
@@ -0,0 +1,6 @@
+##
+# IndexError ISO Test
+
+assert('IndexError', '15.2.33') do
+  assert_equal Class, IndexError.class
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/integer.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/integer.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/integer.rb	(revision 331)
@@ -0,0 +1,268 @@
+##
+# Integer ISO Test
+
+assert('Integer', '15.2.8') do
+  assert_equal Class, Integer.class
+end
+
+assert('Integer#+', '15.2.8.3.1') do
+  a = 1+1
+  b = 1+1.0
+
+  assert_equal 2, a
+  assert_equal 2.0, b
+
+  assert_raise(TypeError){ 0+nil }
+  assert_raise(TypeError){ 1+nil }
+
+  c = Mrbtest::FIXNUM_MAX + 1
+  d = Mrbtest::FIXNUM_MAX.__send__(:+, 1)
+  e = Mrbtest::FIXNUM_MAX + 1.0
+  assert_equal Float, c.class
+  assert_equal Float, d.class
+  assert_float e, c
+  assert_float e, d
+end
+
+assert('Integer#-', '15.2.8.3.2') do
+  a = 2-1
+  b = 2-1.0
+
+  assert_equal 1, a
+  assert_equal 1.0, b
+
+  c = Mrbtest::FIXNUM_MIN - 1
+  d = Mrbtest::FIXNUM_MIN.__send__(:-, 1)
+  e = Mrbtest::FIXNUM_MIN - 1.0
+  assert_equal Float, c.class
+  assert_equal Float, d.class
+  assert_float e, c
+  assert_float e, d
+end
+
+assert('Integer#*', '15.2.8.3.3') do
+  a = 1*1
+  b = 1*1.0
+
+  assert_equal 1, a
+  assert_equal 1.0, b
+
+  assert_raise(TypeError){ 0*nil }
+  assert_raise(TypeError){ 1*nil }
+
+  c = Mrbtest::FIXNUM_MAX * 2
+  d = Mrbtest::FIXNUM_MAX.__send__(:*, 2)
+  e = Mrbtest::FIXNUM_MAX * 2.0
+  assert_equal Float, c.class
+  assert_equal Float, d.class
+  assert_float e, c
+  assert_float e, d
+end
+
+assert('Integer#/', '15.2.8.3.4') do
+  a = 2/1
+  b = 2/1.0
+
+  assert_equal 2, a
+  assert_equal 2.0, b
+end
+
+assert('Integer#%', '15.2.8.3.5') do
+  a = 1%1
+  b = 1%1.0
+  c = 2%4
+  d = 2%5
+  e = 2%-5
+  f = -2%5
+  g = -2%-5
+  h =  2%-2
+  i = -2%2
+  j = -2%-2
+
+  assert_equal 0, a
+  assert_equal 0.0, b
+  assert_equal 2, c
+  assert_equal 2, d
+  assert_equal(-3, e)
+  assert_equal 3, f
+  assert_equal(-2, g)
+  assert_equal 0, h
+  assert_equal 0, i
+  assert_equal 0, j
+end
+
+assert('Integer#<=>', '15.2.9.3.6') do
+  a = 1<=>0
+  b = 1<=>1
+  c = 1<=>2
+
+  assert_equal  1, a
+  assert_equal  0, b
+  assert_equal(-1, c)
+end
+
+assert('Integer#==', '15.2.8.3.7') do
+  a = 1==0
+  b = 1==1
+
+  assert_false a
+  assert_true b
+end
+
+assert('Integer#~', '15.2.8.3.8') do
+  # Complement
+  assert_equal(-1, ~0)
+  assert_equal(-3, ~2)
+end
+
+assert('Integer#&', '15.2.8.3.9') do
+  # Bitwise AND
+  #   0101 (5)
+  # & 0011 (3)
+  # = 0001 (1)
+  assert_equal 1, 5 & 3
+end
+
+assert('Integer#|', '15.2.8.3.10') do
+  # Bitwise OR
+  #   0101 (5)
+  # | 0011 (3)
+  # = 0111 (7)
+  assert_equal 7, 5 | 3
+end
+
+assert('Integer#^', '15.2.8.3.11') do
+  # Bitwise XOR
+  #   0101 (5)
+  # ^ 0011 (3)
+  # = 0110 (6)
+  assert_equal 6, 5 ^ 3
+end
+
+assert('Integer#<<', '15.2.8.3.12') do
+  # Left Shift by one
+  #   00010111 (23)
+  # = 00101110 (46)
+  assert_equal 46, 23 << 1
+
+  # Left Shift by a negative is Right Shift
+  assert_equal 23, 46 << -1
+
+  # Left Shift by 31 is bitShift overflow to SignedInt
+  assert_equal 2147483648, 1 << 31
+
+  # -3 Left Shift by 30 is bitShift overflow to SignedInt
+  assert_equal(-3221225472, -3 << 30)
+end
+
+assert('Integer#>>', '15.2.8.3.13') do
+  # Right Shift by one
+  #   00101110 (46)
+  # = 00010111 (23)
+  assert_equal 23, 46 >> 1
+
+  # Right Shift by a negative is Left Shift
+  assert_equal 46, 23 >> -1
+
+  # Don't raise on large Right Shift
+  assert_equal 0, 23 >> 128
+end
+
+assert('Integer#ceil', '15.2.8.3.14') do
+  assert_equal 10, 10.ceil
+end
+
+assert('Integer#downto', '15.2.8.3.15') do
+  a = 0
+  3.downto(1) do |i|
+    a += i
+  end
+  assert_equal 6, a
+end
+
+assert('Integer#eql?', '15.2.8.3.16') do
+  a = 1.eql?(1)
+  b = 1.eql?(2)
+  c = 1.eql?(nil)
+
+  assert_true a
+  assert_false b
+  assert_false c
+end
+
+assert('Integer#floor', '15.2.8.3.17') do
+  a = 1.floor
+
+  assert_equal 1, a
+end
+
+assert('Integer#next', '15.2.8.3.19') do
+  assert_equal 2, 1.next
+end
+
+assert('Integer#round', '15.2.8.3.20') do
+  assert_equal 1, 1.round
+end
+
+assert('Integer#succ', '15.2.8.3.21') do
+  assert_equal 2, 1.succ
+end
+
+assert('Integer#times', '15.2.8.3.22') do
+  a = 0
+  3.times do
+    a += 1
+  end
+  assert_equal 3, a
+end
+
+assert('Integer#to_f', '15.2.8.3.23') do
+  assert_equal 1.0, 1.to_f
+end
+
+assert('Integer#to_i', '15.2.8.3.24') do
+  assert_equal 1, 1.to_i
+end
+
+assert('Integer#to_s', '15.2.8.3.25') do
+  assert_equal '1', 1.to_s
+  assert_equal("-1", -1.to_s)
+end
+
+assert('Integer#truncate', '15.2.8.3.26') do
+  assert_equal 1, 1.truncate
+end
+
+assert('Integer#upto', '15.2.8.3.27') do
+  a = 0
+  1.upto(3) do |i|
+    a += i
+  end
+  assert_equal 6, a
+end
+
+assert('Integer#divmod', '15.2.8.3.30') do
+  assert_equal [ 0,  0],   0.divmod(1)
+  assert_equal [ 0,  1],   1.divmod(3)
+  assert_equal [ 3,  0],   3.divmod(1)
+  assert_equal [ 2,  6],  20.divmod(7)
+  assert_equal [-1,  2],  -3.divmod(5)
+  assert_equal [-2, -1],  25.divmod(-13)
+  assert_equal [ 1, -6], -13.divmod(-7)
+end
+
+# Not ISO specified
+
+assert('Integer#step') do
+  a = []
+  b = []
+  1.step(3) do |i|
+    a << i
+  end
+  1.step(6, 2) do |i|
+    b << i
+  end
+
+  assert_equal [1, 2, 3], a
+  assert_equal [1, 3, 5], b
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/kernel.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/kernel.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/kernel.rb	(revision 331)
@@ -0,0 +1,623 @@
+##
+# Kernel ISO Test
+
+assert('Kernel', '15.3.1') do
+  assert_equal Module, Kernel.class
+end
+
+assert('Kernel.block_given?', '15.3.1.2.2') do
+  def bg_try(&b)
+    if Kernel.block_given?
+      yield
+    else
+      "no block"
+    end
+  end
+
+  assert_false Kernel.block_given?
+  # test without block
+  assert_equal "no block", bg_try
+  # test with block
+  assert_equal "block" do
+    bg_try { "block" }
+  end
+  # test with block
+  assert_equal "block" do
+    bg_try do
+      "block"
+    end
+  end
+end
+
+# Kernel.eval is provided by the mruby-gem mrbgem. '15.3.1.2.3'
+
+assert('Kernel.global_variables', '15.3.1.2.4') do
+  assert_equal Array, Kernel.global_variables.class
+end
+
+assert('Kernel.iterator?', '15.3.1.2.5') do
+  assert_false Kernel.iterator?
+end
+
+assert('Kernel.lambda', '15.3.1.2.6') do
+  l = Kernel.lambda do
+    true
+  end
+
+  m = Kernel.lambda(&l)
+
+  assert_true l.call
+  assert_equal Proc, l.class
+  assert_true m.call
+  assert_equal Proc, m.class
+end
+
+# Not implemented at the moment
+#assert('Kernel.local_variables', '15.3.1.2.7') do
+#  Kernel.local_variables.class == Array
+#end
+
+assert('Kernel.loop', '15.3.1.2.8') do
+  i = 0
+
+  Kernel.loop do
+    i += 1
+    break if i == 100
+  end
+
+  assert_equal 100, i
+end
+
+assert('Kernel.p', '15.3.1.2.9') do
+  # TODO search for a way to test p to stdio
+  assert_true true
+end
+
+assert('Kernel.print', '15.3.1.2.10') do
+  # TODO search for a way to test print to stdio
+  assert_true true
+end
+
+assert('Kernel.puts', '15.3.1.2.11') do
+  # TODO search for a way to test puts to stdio
+  assert_true true
+end
+
+assert('Kernel.raise', '15.3.1.2.12') do
+  assert_raise RuntimeError do
+    Kernel.raise
+  end
+
+  assert_raise RuntimeError do
+    Kernel.raise RuntimeError.new
+  end
+end
+
+assert('Kernel#__id__', '15.3.1.3.3') do
+  assert_equal Fixnum, __id__.class
+end
+
+assert('Kernel#__send__', '15.3.1.3.4') do
+  # test with block
+  l = __send__(:lambda) do
+    true
+  end
+
+  assert_true l.call
+  assert_equal Proc, l.class
+  # test with argument
+  assert_true __send__(:respond_to?, :nil?)
+  # test without argument and without block
+  assert_equal  Array, __send__(:public_methods).class
+end
+
+assert('Kernel#block_given?', '15.3.1.3.6') do
+  def bg_try(&b)
+    if block_given?
+      yield
+    else
+      "no block"
+    end
+  end
+
+  assert_false block_given?
+  assert_equal "no block", bg_try
+  assert_equal "block" do
+    bg_try { "block" }
+  end
+  assert_equal "block" do
+    bg_try do
+      "block"
+    end
+  end
+end
+
+assert('Kernel#class', '15.3.1.3.7') do
+  assert_equal Module, Kernel.class
+end
+
+assert('Kernel#clone', '15.3.1.3.8') do
+  class KernelCloneTest
+    def initialize
+      @v = 0
+    end
+
+    def get
+      @v
+    end
+
+    def set(v)
+      @v = v
+    end
+  end
+
+  a = KernelCloneTest.new
+  a.set(1)
+  b = a.clone
+
+  def a.test
+  end
+  a.set(2)
+  c = a.clone
+
+  immutables = [ 1, :foo, true, false, nil ]
+  error_count = 0
+  immutables.each do |i|
+    begin
+      i.clone
+    rescue TypeError
+      error_count += 1
+    end
+  end
+
+  assert_equal 2, a.get
+  assert_equal 1, b.get
+  assert_equal 2, c.get
+  assert_true a.respond_to?(:test)
+  assert_false b.respond_to?(:test)
+  assert_true c.respond_to?(:test)
+end
+
+assert('Kernel#dup', '15.3.1.3.9') do
+  class KernelDupTest
+    def initialize
+      @v = 0
+    end
+
+    def get
+      @v
+    end
+
+    def set(v)
+      @v = v
+    end
+  end
+
+  a = KernelDupTest.new
+  a.set(1)
+  b = a.dup
+
+  def a.test
+  end
+  a.set(2)
+  c = a.dup
+
+  immutables = [ 1, :foo, true, false, nil ]
+  error_count = 0
+  immutables.each do |i|
+    begin
+      i.dup
+    rescue TypeError
+      error_count += 1
+    end
+  end
+
+  assert_equal immutables.size, error_count
+  assert_equal 2, a.get
+  assert_equal 1, b.get
+  assert_equal 2, c.get
+  assert_true a.respond_to?(:test)
+  assert_false b.respond_to?(:test)
+  assert_false c.respond_to?(:test)
+end
+
+assert('Kernel#dup class') do
+  assert_nothing_raised do
+    Array.dup.new(200)
+    Range.dup.new(2, 3)
+    String.dup.new("a"*50)
+  end
+end
+
+# Kernel#eval is provided by mruby-eval mrbgem '15.3.1.3.12'
+
+assert('Kernel#extend', '15.3.1.3.13') do
+  class Test4ExtendClass
+  end
+
+  module Test4ExtendModule
+    def test_method; end
+  end
+
+  a = Test4ExtendClass.new
+  a.extend(Test4ExtendModule)
+  b = Test4ExtendClass.new
+
+  assert_true a.respond_to?(:test_method)
+  assert_false b.respond_to?(:test_method)
+end
+
+assert('Kernel#extend works on toplevel', '15.3.1.3.13') do
+  module Test4ExtendModule
+    def test_method; end
+  end
+  # This would crash...
+  extend(Test4ExtendModule)
+
+  assert_true respond_to?(:test_method)
+end
+
+assert('Kernel#freeze') do
+  obj = Object.new
+  assert_equal obj, obj.freeze
+  assert_equal 0, 0.freeze
+  assert_equal :a, :a.freeze
+end
+
+assert('Kernel#global_variables', '15.3.1.3.14') do
+  assert_equal Array, global_variables.class
+end
+
+assert('Kernel#hash', '15.3.1.3.15') do
+  assert_equal hash, hash
+end
+
+assert('Kernel#inspect', '15.3.1.3.17') do
+  s = inspect
+
+  assert_equal String, s.class
+  assert_equal "main", s
+end
+
+assert('Kernel#instance_variable_defined?', '15.3.1.3.20') do
+  o = Object.new
+  o.instance_variable_set(:@a, 1)
+
+  assert_true o.instance_variable_defined?("@a")
+  assert_false o.instance_variable_defined?("@b")
+  assert_true o.instance_variable_defined?("@a"[0,2])
+  assert_true o.instance_variable_defined?("@abc"[0,2])
+end
+
+assert('Kernel#instance_variables', '15.3.1.3.23') do
+  o = Object.new
+  o.instance_eval do
+    @a = 11
+    @b = 12
+  end
+  ivars = o.instance_variables
+
+  assert_equal Array, ivars.class,
+  assert_equal(2, ivars.size)
+  assert_true ivars.include?(:@a)
+  assert_true ivars.include?(:@b)
+end
+
+assert('Kernel#is_a?', '15.3.1.3.24') do
+  assert_true is_a?(Kernel)
+  assert_false is_a?(Array)
+
+  assert_raise TypeError do
+    42.is_a?(42)
+  end
+end
+
+assert('Kernel#iterator?', '15.3.1.3.25') do
+  assert_false iterator?
+end
+
+assert('Kernel#kind_of?', '15.3.1.3.26') do
+  assert_true kind_of?(Kernel)
+  assert_false kind_of?(Array)
+end
+
+assert('Kernel#lambda', '15.3.1.3.27') do
+  l = lambda do
+    true
+  end
+
+  m = lambda(&l)
+
+  assert_true l.call
+  assert_equal Proc, l.class
+  assert_true m.call
+  assert_equal Proc, m.class
+end
+
+# Not implemented yet
+#assert('Kernel#local_variables', '15.3.1.3.28') do
+#  local_variables.class == Array
+#end
+
+assert('Kernel#loop', '15.3.1.3.29') do
+  i = 0
+
+  loop do
+    i += 1
+    break if i == 100
+  end
+
+  assert_equal i, 100
+end
+
+assert('Kernel#method_missing', '15.3.1.3.30') do
+  class MMTestClass
+    def method_missing(sym)
+      "A call to #{sym}"
+    end
+  end
+  mm_test = MMTestClass.new
+  assert_equal 'A call to no_method_named_this', mm_test.no_method_named_this
+
+  a = String.new
+  begin
+    a.no_method_named_this
+  rescue NoMethodError => e
+    assert_equal "undefined method 'no_method_named_this' for \"\"", e.message
+  end
+
+  class ShortInspectClass
+    def inspect
+      'An inspect string'
+    end
+  end
+  b = ShortInspectClass.new
+  begin
+    b.no_method_named_this
+  rescue NoMethodError => e
+    assert_equal "undefined method 'no_method_named_this' for An inspect string", e.message
+  end
+
+  class LongInspectClass
+    def inspect
+      "A" * 70
+    end
+  end
+  c = LongInspectClass.new
+  begin
+    c.no_method_named_this
+  rescue NoMethodError => e
+    assert_equal "undefined method 'no_method_named_this' for #{c.to_s}", e.message
+  end
+
+  class NoInspectClass
+    undef inspect
+  end
+  d = NoInspectClass.new
+  begin
+    d.no_method_named_this
+  rescue NoMethodError => e
+    assert_equal "undefined method 'no_method_named_this' for #{d.to_s}", e.message
+  end
+end
+
+assert('Kernel#methods', '15.3.1.3.31') do
+  assert_equal Array, methods.class
+end
+
+assert('Kernel#nil?', '15.3.1.3.32') do
+  assert_false nil?
+end
+
+assert('Kernel#object_id', '15.3.1.3.33') do
+  a = ""
+  b = ""
+  assert_not_equal a.object_id, b.object_id
+
+  assert_kind_of Numeric, object_id
+  assert_kind_of Numeric, "".object_id
+  assert_kind_of Numeric, true.object_id
+  assert_kind_of Numeric, false.object_id
+  assert_kind_of Numeric, nil.object_id
+  assert_kind_of Numeric, :no.object_id
+  assert_kind_of Numeric, 1.object_id
+  assert_kind_of Numeric, 1.0.object_id
+end
+
+# Kernel#p is defined in mruby-print mrbgem. '15.3.1.3.34'
+
+# Kernel#print is defined in mruby-print mrbgem. '15.3.1.3.35'
+
+assert('Kernel#private_methods', '15.3.1.3.36') do
+  assert_equal Array, private_methods.class
+end
+
+assert('Kernel#protected_methods', '15.3.1.3.37') do
+  assert_equal Array, protected_methods.class
+end
+
+assert('Kernel#public_methods', '15.3.1.3.38') do
+  assert_equal Array, public_methods.class
+  class Foo
+    def foo
+    end
+  end
+  assert_equal [:foo], Foo.new.public_methods(false)
+end
+
+# Kernel#puts is defined in mruby-print mrbgem. '15.3.1.3.39'
+
+assert('Kernel#raise', '15.3.1.3.40') do
+  assert_raise RuntimeError do
+    raise
+  end
+
+  assert_raise RuntimeError do
+    raise RuntimeError.new
+  end
+end
+
+assert('Kernel#remove_instance_variable', '15.3.1.3.41') do
+  class Test4RemoveInstanceVar
+    attr_reader :var
+    def initialize
+      @var = 99
+    end
+    def remove
+      remove_instance_variable(:@var)
+    end
+  end
+
+  tri = Test4RemoveInstanceVar.new
+  assert_equal 99, tri.var
+  tri.remove
+  assert_equal nil, tri.var
+  assert_raise NameError do
+    tri.remove
+  end
+end
+
+# Kernel#require is defined in mruby-require. '15.3.1.3.42'
+
+assert('Kernel#respond_to?', '15.3.1.3.43') do
+  class Test4RespondTo
+    def valid_method; end
+
+    def test_method; end
+    undef test_method
+  end
+
+  assert_raise TypeError do
+    Test4RespondTo.new.respond_to?(1)
+  end
+
+  assert_raise ArgumentError do
+    Test4RespondTo.new.respond_to?
+  end
+
+  assert_raise ArgumentError do
+    Test4RespondTo.new.respond_to? :a, true, :aa
+  end
+
+  assert_true respond_to?(:nil?)
+  assert_true Test4RespondTo.new.respond_to?(:valid_method)
+  assert_true Test4RespondTo.new.respond_to?('valid_method')
+  assert_false Test4RespondTo.new.respond_to?(:test_method)
+end
+
+assert('Kernel#send', '15.3.1.3.44') do
+  # test with block
+  l = send(:lambda) do
+    true
+  end
+
+  assert_true l.call
+  assert_equal l.class, Proc
+  # test with argument
+  assert_true send(:respond_to?, :nil?)
+  # test without argument and without block
+  assert_equal send(:public_methods).class, Array
+end
+
+assert('Kernel#singleton_methods', '15.3.1.3.45') do
+  assert_equal singleton_methods.class, Array
+end
+
+assert('Kernel#to_s', '15.3.1.3.46') do
+  assert_equal to_s.class, String
+end
+
+assert('Kernel#to_s on primitives') do
+  begin
+    Fixnum.alias_method :to_s_, :to_s
+    Fixnum.remove_method :to_s
+
+    assert_nothing_raised do
+      # segfaults if mrb_cptr is used
+      1.to_s
+    end
+  ensure
+    Fixnum.alias_method :to_s, :to_s_
+    Fixnum.remove_method :to_s_
+  end
+end
+
+assert('Kernel.local_variables', '15.3.1.2.7') do
+  a, b = 0, 1
+  a += b
+
+  vars = Kernel.local_variables.sort
+  assert_equal [:a, :b, :vars], vars
+
+  assert_equal [:a, :b, :c, :vars], Proc.new { |a, b|
+    c = 2
+    Kernel.local_variables.sort
+  }.call(-1, -2)
+end
+
+assert('Kernel#!=') do
+  str1 = "hello"
+  str2 = str1
+  str3 = "world"
+
+  assert_false (str1[1] != 'e')
+  assert_true (str1 != str3)
+  assert_false (str2 != str1)
+end
+
+# operator "!~" is defined in ISO Ruby 11.4.4.
+assert('Kernel#!~') do
+  x = "x"
+  def x.=~(other)
+    other == "x"
+  end
+  assert_false x !~ "x"
+  assert_true  x !~ "z"
+
+  y = "y"
+  def y.=~(other)
+    other == "y"
+  end
+  def y.!~(other)
+    other == "not y"
+  end
+  assert_false y !~ "y"
+  assert_false y !~ "z"
+  assert_true  y !~ "not y"
+end
+
+assert('Kernel#respond_to_missing?') do
+  class Test4RespondToMissing
+    def respond_to_missing?(method_name, include_private = false)
+      method_name == :a_method
+    end
+  end
+
+  assert_true Test4RespondToMissing.new.respond_to?(:a_method)
+  assert_false Test4RespondToMissing.new.respond_to?(:no_method)
+end
+
+assert('Kernel#global_variables') do
+  variables = global_variables
+  1.upto(9) do |i|
+    assert_equal variables.include?(:"$#{i}"), true
+  end
+end
+
+assert('Kernel#define_singleton_method') do
+  o = Object.new
+  ret = o.define_singleton_method(:test_method) do
+    :singleton_method_ok
+  end
+  assert_equal :test_method, ret
+  assert_equal :singleton_method_ok, o.test_method
+end
+
+assert('stack extend') do
+  def recurse(count, stop)
+    return count if count > stop
+    recurse(count+1, stop)
+  end
+
+  assert_equal 6, recurse(0, 5)
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/lang.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/lang.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/lang.rb	(revision 331)
@@ -0,0 +1,74 @@
+# The aim of these tests is  to detect pitfall for optimized VM.
+
+# Test for or/and
+#
+# You may think instruction fusion(OP_EQ and OP_JMPIF) for avoiding
+# generate intermediate boolean value.
+# But and/or is pitfall for this fusioning.
+#
+# For example, the following mruby code:
+#
+#   if i > 0 and i < 10 then
+#
+# compiles to the following byte code:
+#
+#    1 000 OP_LOADI      R1      0               ; R1:i
+#    2 001 OP_MOVE       R2      R1              ; R1:i
+#    2 002 OP_LOADI      R3      0
+#    2 003 OP_GT R2      :>      1
+#    2 004 OP_JMPNOT     R2      008
+#    2 005 OP_MOVE       R2      R1              ; R1:i
+#    2 006 OP_LOADI      R3      10
+#    2 007 OP_LT R2      :<      1
+#    2 008 OP_JMPNOT     R2      (The address of end of then part)
+#
+# When the instruction fusion the OP_GT and OP_JMPNOT you fell into the pitfalls.
+# The deleted intermediate boolean value is used in OP_JMPNOT (address 008).
+
+assert('and', '11.2.3') do
+  a = 1
+  if a > 0 and a < 10 then
+    b = 1
+  else
+    b = 0
+  end
+  assert_equal 1, b
+
+  if a < 0 and a < 10 then
+    b = 1
+  else
+    b = 0
+  end
+  assert_equal 0, b
+
+  if a < 0 and a > 10 then
+    b = 1
+  else
+    b = 0
+  end
+  assert_equal 0, b
+end
+
+assert('or','11.2.4') do
+  a = 1
+  if a > 0 or a < 10 then
+    b = 1
+  else
+    b = 0
+  end
+  assert_equal 1, b
+
+  if a < 0 or a < 10 then
+    b = 1
+  else
+    b = 0
+  end
+  assert_equal 1, b
+
+  if a < 0 or a > 10 then
+    b = 1
+  else
+    b = 0
+  end
+  assert_equal 0, b
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/literals.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/literals.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/literals.rb	(revision 331)
@@ -0,0 +1,337 @@
+##
+# Literals ISO Test
+
+assert('Literals Numerical', '8.7.6.2') do
+  # signed and unsigned integer
+  assert_equal 1, 1
+  assert_equal(-1, -1)
+  assert_equal(+1, +1)
+  # signed and unsigned float
+  assert_equal 1.0, 1.0
+  assert_equal(-1.0, -1.0)
+  # binary
+  assert_equal 128, 0b10000000
+  assert_equal 128, 0B10000000
+  # octal
+  assert_equal 8, 0o10
+  assert_equal 8, 0O10
+  assert_equal 8, 0_10
+  # hex
+  assert_equal 255, 0xff
+  assert_equal 255, 0Xff
+  # decimal
+  assert_equal 999, 0d999
+  assert_equal 999, 0D999
+  # decimal seperator
+  assert_equal 10000000, 10_000_000
+  assert_equal       10, 1_0
+  # integer with exponent
+  assert_equal 10.0, 1e1
+  assert_equal(0.1, 1e-1)
+  assert_equal 10.0, 1e+1
+  # float with exponent
+  assert_equal 10.0, 1.0e1
+  assert_equal(0.1, 1.0e-1)
+  assert_equal 10.0, 1.0e+1
+end
+
+assert('Literals Strings Single Quoted', '8.7.6.3.2') do
+  assert_equal 'abc', 'abc'
+  assert_equal '\'', '\''
+  assert_equal '\\', '\\'
+end
+
+assert('Literals Strings Double Quoted', '8.7.6.3.3') do
+  a = "abc"
+
+  assert_equal "abc", "abc"
+  assert_equal "\"", "\""
+  assert_equal "\\", "\\"
+  assert_equal "abc", "#{a}"
+end
+
+assert('Literals Strings Quoted Non-Expanded', '8.7.6.3.4') do
+  a = %q{abc}
+  b = %q(abc)
+  c = %q[abc]
+  d = %q<abc>
+  e = %q/abc/
+  f = %q/ab\/c/
+  g = %q{#{a}}
+
+  assert_equal 'abc', a
+  assert_equal 'abc', b
+  assert_equal 'abc', c
+  assert_equal 'abc', d
+  assert_equal 'abc', e
+  assert_equal 'ab/c', f
+  assert_equal '#{a}', g
+end
+
+assert('Literals Strings Quoted Expanded', '8.7.6.3.5') do
+  a = %Q{abc}
+  b = %Q(abc)
+  c = %Q[abc]
+  d = %Q<abc>
+  e = %Q/abc/
+  f = %Q/ab\/c/
+  g = %Q{#{a}}
+
+  assert_equal 'abc', a
+  assert_equal 'abc', b
+  assert_equal 'abc', c
+  assert_equal 'abc', d
+  assert_equal 'abc', e
+  assert_equal 'ab/c', f
+  assert_equal 'abc', g
+end
+
+assert('Literals Strings Here documents', '8.7.6.3.6') do
+  a = <<AAA
+aaa
+AAA
+   b = <<b_b
+bbb
+b_b
+    c = [<<CCC1, <<"CCC2", <<'CCC3']
+c1
+CCC1
+c 2
+CCC2
+c  3
+CCC3
+
+      d = <<DDD
+d#{1+2}DDD
+d\t
+DDD\n
+DDD
+  e = <<'EEE'
+e#{1+2}EEE
+e\t
+EEE\n
+EEE
+  f = <<"FFF"
+F
+FF#{"f"}FFF
+F
+FFF
+
+  g = <<-GGG
+  ggg
+  GGG
+  h = <<-"HHH"
+  hhh
+  HHH
+  i = <<-'III'
+  iii
+  III
+  j = [<<-JJJ1   , <<-"JJJ2"   , <<-'JJJ3' ]
+  j#{1}j
+  JJJ1
+  j#{2}j
+  JJJ2
+  j#{3}j
+  JJJ3
+
+  k = <<'KKK'.to_i
+123
+KKK
+
+  m = [<<MM1, <<MM2]
+x#{m2 = {x:<<MM3}}y
+mm3
+MM3
+mm1
+MM1
+mm2
+MM2
+
+  n = [1, "#{<<NN1}", 3,
+nn1
+NN1
+  4]
+
+  qqq = Proc.new {|*x| x.join(' $ ')}
+  q1 = qqq.call("a", <<QQ1, "c",
+q
+QQ1
+      "d")
+  q2 = qqq.call("l", "m#{<<QQ2}n",
+qq
+QQ2
+      "o")
+
+  w = %W( 1 #{<<WWW} 3
+www
+WWW
+      4 5 )
+
+  x = [1, <<XXX1,
+foo #{<<XXX2} bar
+222 #{<<XXX3} 444
+333
+XXX3
+5
+XXX2
+6
+XXX1
+    9]
+
+  z = <<'ZZZ'
+ZZZ
+
+  assert_equal "aaa\n", a
+  assert_equal "bbb\n", b
+  assert_equal ["c1\n", "c 2\n", "c  3\n"], c
+  assert_equal "d3DDD\nd\t\nDDD\n\n", d
+  assert_equal "e\#{1+2}EEE\ne\\t\nEEE\\n\n", e
+  assert_equal "F\nFFfFFF\nF\n", f
+  assert_equal "  ggg\n", g
+  assert_equal "  hhh\n", h
+  assert_equal "  iii\n", i
+  assert_equal ["  j1j\n", "  j2j\n", "  j\#{3}j\n"], j
+  assert_equal 123, k
+  assert_equal ["x{:x=>\"mm3\\n\"}y\nmm1\n", "mm2\n"], m
+  assert_equal ({:x=>"mm3\n"}), m2
+  assert_equal [1, "nn1\n", 3, 4], n
+  assert_equal "a $ q\n $ c $ d", q1
+  assert_equal "l $ mqq\nn $ o", q2
+  assert_equal ["1", "www\n", "3", "4", "5"], w
+  assert_equal [1, "foo 222 333\n 444\n5\n bar\n6\n", 9], x
+  assert_equal "", z
+
+end
+
+
+assert('Literals Array', '8.7.6.4') do
+  a = %W{abc#{1+2}def \}g}
+  b = %W(abc #{2+3} def \(g)
+  c = %W[#{3+4}]
+  d = %W< #{4+5} >
+  e = %W//
+  f = %W[[ab cd][ef]]
+  g = %W{
+    ab
+    #{-1}1
+    2#{2}
+  }
+  h = %W(a\nb
+         test\ abc
+         c\
+d
+         x\y x\\y x\\\y)
+
+  assert_equal ['abc3def', '}g'], a
+  assert_equal ['abc', '5', 'def', '(g'], b
+  assert_equal ['7'],c
+  assert_equal ['9'], d
+  assert_equal [], e
+  assert_equal ['[ab', 'cd][ef]'], f
+  assert_equal ['ab', '-11', '22'], g
+  assert_equal ["a\nb", 'test abc', "c\nd", "xy", "x\\y", "x\\y"], h
+
+  a = %w{abc#{1+2}def \}g}
+  b = %w(abc #{2+3} def \(g)
+  c = %w[#{3+4}]
+  d = %w< #{4+5} >
+  e = %w//
+  f = %w[[ab cd][ef]]
+  g = %w{
+    ab
+    #{-1}1
+    2#{2}
+  }
+  h = %w(a\nb
+         test\ abc
+         c\
+d
+         x\y x\\y x\\\y)
+
+  assert_equal ['abc#{1+2}def', '}g'], a
+  assert_equal ['abc', '#{2+3}', 'def', '(g'], b
+  assert_equal ['#{3+4}'], c
+  assert_equal ['#{4+5}'], d
+  assert_equal [], e
+  assert_equal ['[ab', 'cd][ef]'], f
+  assert_equal ['ab', '#{-1}1', '2#{2}'], g
+  assert_equal ["a\\nb", "test abc", "c\nd", "x\\y", "x\\y", "x\\\\y"], h
+end
+
+
+assert('Literals Array of symbols') do
+  a = %I{abc#{1+2}def \}g}
+  b = %I(abc #{2+3} def \(g)
+  c = %I[#{3+4}]
+  d = %I< #{4+5} >
+  e = %I//
+  f = %I[[ab cd][ef]]
+  g = %I{
+    ab
+    #{-1}1
+    2#{2}
+  }
+
+  assert_equal [:'abc3def', :'}g'], a
+  assert_equal [:'abc', :'5', :'def', :'(g'], b
+  assert_equal [:'7'],c
+  assert_equal [:'9'], d
+  assert_equal [], e
+  assert_equal [:'[ab', :'cd][ef]'], f
+  assert_equal [:'ab', :'-11', :'22'], g
+
+  a = %i{abc#{1+2}def \}g}
+  b = %i(abc #{2+3} def \(g)
+  c = %i[#{3+4}]
+  d = %i< #{4+5} >
+  e = %i//
+  f = %i[[ab cd][ef]]
+  g = %i{
+    ab
+    #{-1}1
+    2#{2}
+  }
+
+  assert_equal [:'abc#{1+2}def', :'}g'], a
+  assert_equal [:'abc', :'#{2+3}', :'def', :'(g'], b
+  assert_equal [:'#{3+4}'], c
+  assert_equal [:'#{4+5}'], d
+  assert_equal [] ,e
+  assert_equal [:'[ab', :'cd][ef]'], f
+  assert_equal [:'ab', :'#{-1}1', :'2#{2}'], g
+end
+
+assert('Literals Symbol', '8.7.6.6') do
+  # do not compile error
+  :$asd
+  :@asd
+  :@@asd
+  :asd=
+  :asd!
+  :asd?
+  :+
+  :+@
+  :if
+  :BEGIN
+
+  a = :"asd qwe"
+  b = :'foo bar'
+  c = :"a#{1+2}b"
+  d = %s(asd)
+  e = %s( foo \))
+  f = %s[asd \[
+qwe]
+  g = %s/foo#{1+2}bar/
+  h = %s{{foo bar}}
+
+  assert_equal :'asd qwe', a
+  assert_equal :"foo bar", b
+  assert_equal :a3b, c
+  assert_equal :asd, d
+  assert_equal :' foo )', e
+  assert_equal :"asd [\nqwe", f
+  assert_equal :'foo#{1+2}bar', g
+  assert_equal :'{foo bar}', h
+end
+
+# Not Implemented ATM assert('Literals Regular expression', '8.7.6.5') do
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/localjumperror.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/localjumperror.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/localjumperror.rb	(revision 331)
@@ -0,0 +1,13 @@
+##
+# LocalJumpError ISO Test
+
+assert('LocalJumpError', '15.2.25') do
+  assert_equal Class, LocalJumpError.class
+#  assert_raise LocalJumpError do
+#    # this will cause an exception due to the wrong location
+#    retry
+#  end
+end
+
+# TODO 15.2.25.2.1 LocalJumpError#exit_value
+# TODO 15.2.25.2.2 LocalJumpError#reason
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/methods.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/methods.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/methods.rb	(revision 331)
@@ -0,0 +1,109 @@
+##
+# Chapter 13.3 "Methods" ISO Test
+
+assert('The alias statement', '13.3.6 a) 4)') do
+  # check aliasing in all possible ways
+
+  def alias_test_method_original; true; end
+
+  alias alias_test_method_a alias_test_method_original
+  alias :alias_test_method_b :alias_test_method_original
+
+  assert_true(alias_test_method_original)
+  assert_true(alias_test_method_a)
+  assert_true(alias_test_method_b)
+end
+
+assert('The alias statement (overwrite original)', '13.3.6 a) 4)') do
+  # check that an aliased method can be overwritten
+  # without side effect
+
+  def alias_test_method_original; true; end
+
+  alias alias_test_method_a alias_test_method_original
+  alias :alias_test_method_b :alias_test_method_original
+
+  assert_true(alias_test_method_original)
+
+  def alias_test_method_original; false; end
+
+  assert_false(alias_test_method_original)
+  assert_true(alias_test_method_a)
+  assert_true(alias_test_method_b)
+end
+
+assert('The alias statement', '13.3.6 a) 5)') do
+  # check that alias is raising NameError if
+  # non-existing method should be undefined
+
+  assert_raise(NameError) do
+    alias new_name_a non_existing_method
+  end
+
+  assert_raise(NameError) do
+    alias :new_name_b :non_existing_method
+  end
+end
+
+assert('The undef statement', '13.3.7 a) 4)') do
+  # check that undef is undefining method
+  # based on the method name
+
+  def existing_method_a; true; end
+  def existing_method_b; true; end
+  def existing_method_c; true; end
+  def existing_method_d; true; end
+  def existing_method_e; true; end
+  def existing_method_f; true; end
+
+  # check that methods are defined
+
+  assert_true(existing_method_a, 'Method should be defined')
+  assert_true(existing_method_b, 'Method should be defined')
+  assert_true(existing_method_c, 'Method should be defined')
+  assert_true(existing_method_d, 'Method should be defined')
+  assert_true(existing_method_e, 'Method should be defined')
+  assert_true(existing_method_f, 'Method should be defined')
+
+  # undefine in all possible ways and check that method
+  # is undefined
+
+  undef existing_method_a
+  assert_raise(NoMethodError) do
+    existing_method_a
+  end
+
+  undef :existing_method_b
+  assert_raise(NoMethodError) do
+    existing_method_b
+  end
+
+  undef existing_method_c, existing_method_d
+  assert_raise(NoMethodError) do
+    existing_method_c
+  end
+  assert_raise(NoMethodError) do
+    existing_method_d
+  end
+
+  undef :existing_method_e, :existing_method_f
+  assert_raise(NoMethodError) do
+    existing_method_e
+  end
+  assert_raise(NoMethodError) do
+    existing_method_f
+  end
+end
+
+assert('The undef statement (method undefined)', '13.3.7 a) 5)') do
+  # check that undef is raising NameError if
+  # non-existing method should be undefined
+
+  assert_raise(NameError) do
+    undef non_existing_method
+  end
+
+  assert_raise(NameError) do
+    undef :non_existing_method
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/module.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/module.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/module.rb	(revision 331)
@@ -0,0 +1,862 @@
+##
+# Module ISO Test
+
+def labeled_module(name, &block)
+  Module.new do
+    singleton_class.class_eval do
+      define_method(:to_s) { name }
+      alias_method :inspect, :to_s
+    end
+    class_eval(&block) if block
+  end
+end
+
+def labeled_class(name, supklass = Object, &block)
+  Class.new(supklass) do
+    singleton_class.class_eval do
+      define_method(:to_s) { name }
+      alias_method :inspect, :to_s
+    end
+    class_eval(&block) if block
+  end
+end
+
+assert('Module', '15.2.2') do
+  assert_equal Class, Module.class
+end
+
+# TODO not implemented ATM assert('Module.constants', '15.2.2.3.1') do
+
+# TODO not implemented ATM assert('Module.nesting', '15.2.2.3.2') do
+
+assert('Module#ancestors', '15.2.2.4.9') do
+  class Test4ModuleAncestors
+  end
+  sc = Test4ModuleAncestors.singleton_class
+  r = String.ancestors
+
+  assert_equal Array, r.class
+  assert_true r.include?(String)
+  assert_true r.include?(Object)
+end
+
+assert('Module#append_features', '15.2.2.4.10') do
+  module Test4AppendFeatures
+    def self.append_features(mod)
+      Test4AppendFeatures2.const_set(:Const4AppendFeatures2, mod)
+    end
+  end
+  module Test4AppendFeatures2
+    include Test4AppendFeatures
+  end
+
+  assert_equal Test4AppendFeatures2, Test4AppendFeatures2.const_get(:Const4AppendFeatures2)
+end
+
+assert('Module#attr NameError') do
+  %w[
+    foo?
+    @foo
+    @@foo
+    $foo
+  ].each do |name|
+    module NameTest; end
+
+    assert_raise(NameError) do
+      NameTest.module_eval { attr_reader name.to_sym }
+    end
+
+    assert_raise(NameError) do
+      NameTest.module_eval { attr_writer name.to_sym }
+    end
+
+    assert_raise(NameError) do
+      NameTest.module_eval { attr name.to_sym }
+    end
+
+    assert_raise(NameError) do
+      NameTest.module_eval { attr_accessor name.to_sym }
+    end
+  end
+
+end
+
+assert('Module#attr', '15.2.2.4.11') do
+  class AttrTest
+    class << self
+      attr :cattr
+      def cattr_val=(val)
+        @cattr = val
+      end
+    end
+    attr :iattr
+    def iattr_val=(val)
+      @iattr = val
+    end
+  end
+
+  test = AttrTest.new
+  assert_true AttrTest.respond_to?(:cattr)
+  assert_true test.respond_to?(:iattr)
+
+  assert_false AttrTest.respond_to?(:cattr=)
+  assert_false test.respond_to?(:iattr=)
+
+  test.iattr_val = 'test'
+  assert_equal 'test', test.iattr
+
+  AttrTest.cattr_val = 'test'
+  assert_equal 'test', AttrTest.cattr
+end
+
+assert('Module#attr_accessor', '15.2.2.4.12') do
+  class AttrTestAccessor
+    class << self
+      attr_accessor :cattr
+    end
+    attr_accessor :iattr, 'iattr2'
+  end
+
+  attr_instance = AttrTestAccessor.new
+  assert_true AttrTestAccessor.respond_to?(:cattr=)
+  assert_true attr_instance.respond_to?(:iattr=)
+  assert_true attr_instance.respond_to?(:iattr2=)
+  assert_true AttrTestAccessor.respond_to?(:cattr)
+  assert_true attr_instance.respond_to?(:iattr)
+  assert_true attr_instance.respond_to?(:iattr2)
+
+  attr_instance.iattr = 'test'
+  assert_equal 'test', attr_instance.iattr
+
+  AttrTestAccessor.cattr = 'test'
+  assert_equal 'test', AttrTestAccessor.cattr
+end
+
+assert('Module#attr_reader', '15.2.2.4.13') do
+  class AttrTestReader
+    class << self
+      attr_reader :cattr
+      def cattr_val=(val)
+        @cattr = val
+      end
+    end
+    attr_reader :iattr, 'iattr2'
+    def iattr_val=(val)
+      @iattr = val
+    end
+  end
+
+  attr_instance = AttrTestReader.new
+  assert_true AttrTestReader.respond_to?(:cattr)
+  assert_true attr_instance.respond_to?(:iattr)
+  assert_true attr_instance.respond_to?(:iattr2)
+
+  assert_false AttrTestReader.respond_to?(:cattr=)
+  assert_false attr_instance.respond_to?(:iattr=)
+  assert_false attr_instance.respond_to?(:iattr2=)
+
+  attr_instance.iattr_val = 'test'
+  assert_equal 'test', attr_instance.iattr
+
+  AttrTestReader.cattr_val = 'test'
+  assert_equal 'test', AttrTestReader.cattr
+end
+
+assert('Module#attr_writer', '15.2.2.4.14') do
+  class AttrTestWriter
+    class << self
+      attr_writer :cattr
+      def cattr_val
+        @cattr
+      end
+    end
+    attr_writer :iattr, 'iattr2'
+    def iattr_val
+      @iattr
+    end
+  end
+
+  attr_instance = AttrTestWriter.new
+  assert_true AttrTestWriter.respond_to?(:cattr=)
+  assert_true attr_instance.respond_to?(:iattr=)
+  assert_true attr_instance.respond_to?(:iattr2=)
+
+  assert_false AttrTestWriter.respond_to?(:cattr)
+  assert_false attr_instance.respond_to?(:iattr)
+  assert_false attr_instance.respond_to?(:iattr2)
+
+  attr_instance.iattr = 'test'
+  assert_equal 'test', attr_instance.iattr_val
+
+  AttrTestWriter.cattr = 'test'
+  assert_equal 'test', AttrTestWriter.cattr_val
+end
+
+assert('Module#class_eval', '15.2.2.4.15') do
+  class Test4ClassEval
+    @a = 11
+    @b = 12
+  end
+  Test4ClassEval.class_eval do
+    def method1
+    end
+  end
+  r = Test4ClassEval.instance_methods
+
+  assert_equal 11, Test4ClassEval.class_eval{ @a }
+  assert_equal 12, Test4ClassEval.class_eval{ @b }
+  assert_equal Array, r.class
+  assert_true r.include?(:method1)
+end
+
+assert('Module#class_variable_defined?', '15.2.2.4.16') do
+  class Test4ClassVariableDefined
+    @@cv = 99
+  end
+
+  assert_true Test4ClassVariableDefined.class_variable_defined?(:@@cv)
+  assert_false Test4ClassVariableDefined.class_variable_defined?(:@@noexisting)
+end
+
+assert('Module#class_variable_get', '15.2.2.4.17') do
+  class Test4ClassVariableGet
+    @@cv = 99
+  end
+
+  assert_equal 99, Test4ClassVariableGet.class_variable_get(:@@cv)
+end
+
+assert('Module#class_variable_set', '15.2.2.4.18') do
+  class Test4ClassVariableSet
+    @@foo = 100
+    def foo
+      @@foo
+    end
+  end
+
+  assert_true Test4ClassVariableSet.class_variable_set(:@@cv, 99)
+  assert_true Test4ClassVariableSet.class_variable_set(:@@foo, 101)
+  assert_true Test4ClassVariableSet.class_variables.include? :@@cv
+  assert_equal 99, Test4ClassVariableSet.class_variable_get(:@@cv)
+  assert_equal 101, Test4ClassVariableSet.new.foo
+end
+
+assert('Module#class_variables', '15.2.2.4.19') do
+  class Test4ClassVariables1
+    @@var1 = 1
+  end
+  class Test4ClassVariables2 < Test4ClassVariables1
+    @@var2 = 2
+  end
+
+  assert_equal [:@@var1], Test4ClassVariables1.class_variables
+  assert_equal [:@@var2, :@@var1], Test4ClassVariables2.class_variables
+end
+
+assert('Module#const_defined?', '15.2.2.4.20') do
+  module Test4ConstDefined
+    Const4Test4ConstDefined = true
+  end
+
+  assert_true Test4ConstDefined.const_defined?(:Const4Test4ConstDefined)
+  assert_false Test4ConstDefined.const_defined?(:NotExisting)
+end
+
+assert('Module#const_get', '15.2.2.4.21') do
+  module Test4ConstGet
+    Const4Test4ConstGet = 42
+  end
+
+  assert_equal 42, Test4ConstGet.const_get(:Const4Test4ConstGet)
+end
+
+assert('Module#const_missing', '15.2.2.4.22') do
+  module Test4ConstMissing
+    def self.const_missing(sym)
+      42 # the answer to everything
+    end
+  end
+
+  assert_equal 42, Test4ConstMissing.const_get(:ConstDoesntExist)
+end
+
+assert('Module#const_get', '15.2.2.4.23') do
+  module Test4ConstSet
+    Const4Test4ConstSet = 42
+  end
+
+  assert_true Test4ConstSet.const_set(:Const4Test4ConstSet, 23)
+  assert_equal 23, Test4ConstSet.const_get(:Const4Test4ConstSet)
+end
+
+assert('Module#constants', '15.2.2.4.24') do
+  $n = []
+  module TestA
+    C = 1
+  end
+  class TestB
+    include TestA
+    C2 = 1
+    $n = constants.sort
+  end
+
+  assert_equal [ :C ], TestA.constants
+  assert_equal [ :C, :C2 ], $n
+end
+
+assert('Module#include', '15.2.2.4.27') do
+  module Test4Include
+    Const4Include = 42
+  end
+  module Test4Include2
+    include Test4Include
+  end
+
+  assert_equal 42, Test4Include2.const_get(:Const4Include)
+end
+
+assert('Module#include?', '15.2.2.4.28') do
+  module Test4IncludeP
+  end
+  class Test4IncludeP2
+    include Test4IncludeP
+  end
+  class Test4IncludeP3 < Test4IncludeP2
+  end
+
+  assert_true Test4IncludeP2.include?(Test4IncludeP)
+  assert_true Test4IncludeP3.include?(Test4IncludeP)
+  assert_false Test4IncludeP.include?(Test4IncludeP)
+end
+
+assert('Module#included', '15.2.2.4.29') do
+  module Test4Included
+    Const4Included = 42
+    def self.included mod
+      Test4Included.const_set(:Const4Included2, mod)
+    end
+  end
+  module Test4Included2
+    include Test4Included
+  end
+
+  assert_equal 42, Test4Included2.const_get(:Const4Included)
+  assert_equal Test4Included2, Test4Included2.const_get(:Const4Included2)
+end
+
+assert('Module#included_modules', '15.2.2.4.30') do
+  module Test4includedModules
+  end
+  module Test4includedModules2
+    include Test4includedModules
+  end
+  r = Test4includedModules2.included_modules
+
+  assert_equal Array, r.class
+  assert_true r.include?(Test4includedModules)
+end
+
+assert('Module#initialize', '15.2.2.4.31') do
+  assert_kind_of Module, Module.new
+  mod = Module.new { def hello; "hello"; end }
+  assert_equal [:hello], mod.instance_methods
+  a = nil
+  mod = Module.new { |m| a = m }
+  assert_equal mod, a
+end
+
+assert('Module#instance_methods', '15.2.2.4.33') do
+  module Test4InstanceMethodsA
+    def method1()  end
+  end
+  class Test4InstanceMethodsB
+    def method2()  end
+  end
+  class Test4InstanceMethodsC < Test4InstanceMethodsB
+    def method3()  end
+  end
+
+  r = Test4InstanceMethodsC.instance_methods(true)
+
+  assert_equal [:method1], Test4InstanceMethodsA.instance_methods
+  assert_equal [:method2], Test4InstanceMethodsB.instance_methods(false)
+  assert_equal [:method3], Test4InstanceMethodsC.instance_methods(false)
+  assert_equal Array, r.class
+  assert_true r.include?(:method3)
+  assert_true r.include?(:method2)
+end
+
+assert('Module#method_defined?', '15.2.2.4.34') do
+  module Test4MethodDefined
+    module A
+      def method1()  end
+    end
+
+    class B
+      def method2()  end
+    end
+
+    class C < B
+      include A
+      def method3()  end
+    end
+  end
+
+  assert_true Test4MethodDefined::A.method_defined? :method1
+  assert_true Test4MethodDefined::C.method_defined? :method1
+  assert_true Test4MethodDefined::C.method_defined? "method2"
+  assert_true Test4MethodDefined::C.method_defined? "method3"
+  assert_false Test4MethodDefined::C.method_defined? "method4"
+end
+
+
+assert('Module#module_eval', '15.2.2.4.35') do
+  module Test4ModuleEval
+    @a = 11
+    @b = 12
+  end
+
+  assert_equal 11, Test4ModuleEval.module_eval{ @a }
+  assert_equal 12, Test4ModuleEval.module_eval{ @b }
+end
+
+assert('Module#remove_class_variable', '15.2.2.4.39') do
+  class Test4RemoveClassVariable
+    @@cv = 99
+  end
+
+  assert_equal 99, Test4RemoveClassVariable.remove_class_variable(:@@cv)
+  assert_false Test4RemoveClassVariable.class_variables.include? :@@cv
+end
+
+assert('Module#remove_const', '15.2.2.4.40') do
+  module Test4RemoveConst
+    ExistingConst = 23
+  end
+
+  result = Test4RemoveConst.module_eval { remove_const :ExistingConst }
+
+  name_error = false
+  begin
+    Test4RemoveConst.module_eval { remove_const :NonExistingConst }
+  rescue NameError
+    name_error = true
+  end
+
+  # Constant removed from Module
+  assert_false Test4RemoveConst.const_defined? :ExistingConst
+  # Return value of binding
+  assert_equal 23, result
+  # Name Error raised when Constant doesn't exist
+  assert_true name_error
+end
+
+assert('Module#remove_method', '15.2.2.4.41') do
+  module Test4RemoveMethod
+    class Parent
+      def hello
+      end
+     end
+
+     class Child < Parent
+      def hello
+      end
+    end
+  end
+
+  assert_true Test4RemoveMethod::Child.class_eval{ remove_method :hello }
+  assert_true Test4RemoveMethod::Child.instance_methods.include? :hello
+  assert_false Test4RemoveMethod::Child.instance_methods(false).include? :hello
+end
+
+assert('Module#undef_method', '15.2.2.4.42') do
+  module Test4UndefMethod
+    class Parent
+      def hello
+      end
+     end
+
+     class Child < Parent
+      def hello
+      end
+     end
+
+     class GrandChild < Child
+     end
+  end
+  Test4UndefMethod::Child.class_eval{ undef_method :hello }
+
+  assert_true Test4UndefMethod::Parent.new.respond_to?(:hello)
+  assert_false Test4UndefMethod::Child.new.respond_to?(:hello)
+  assert_false Test4UndefMethod::GrandChild.new.respond_to?(:hello)
+  assert_false Test4UndefMethod::Child.instance_methods(false).include? :hello
+end
+
+# Not ISO specified
+
+assert('Module#define_method') do
+  c = Class.new {
+    define_method(:m1) { :ok }
+    define_method(:m2, Proc.new { :ok })
+  }
+  assert_equal c.new.m1, :ok
+  assert_equal c.new.m2, :ok
+  assert_raise(TypeError) do
+    Class.new { define_method(:n1, nil) }
+  end
+end
+
+# @!group prepend
+  assert('Module#prepend') do
+    module M0
+      def m1; [:M0] end
+    end
+    module M1
+      def m1; [:M1, super, :M1] end
+    end
+    module M2
+      def m1; [:M2, super, :M2] end
+    end
+    M3 = Module.new do
+      def m1; [:M3, super, :M3] end
+    end
+    module M4
+      def m1; [:M4, super, :M4] end
+    end
+
+    class P0
+      include M0
+      prepend M1
+      def m1; [:C0, super, :C0] end
+    end
+    class P1 < P0
+      prepend M2, M3
+      include M4
+      def m1; [:C1, super, :C1] end
+    end
+
+    obj = P1.new
+    expected = [:M2,[:M3,[:C1,[:M4,[:M1,[:C0,[:M0],:C0],:M1],:M4],:C1],:M3],:M2]
+    assert_equal(expected, obj.m1)
+  end
+
+  # mruby shouldn't be affected by this since there is
+  # no visibility control (yet)
+  assert('Module#prepend public') do
+    assert_nothing_raised('ruby/ruby #8846') do
+      Class.new.prepend(Module.new)
+    end
+  end
+
+  assert('Module#prepend inheritance') do
+    bug6654 = '[ruby-core:45914]'
+    a = labeled_module('a')
+    b = labeled_module('b') { include a }
+    c = labeled_module('c') { prepend b }
+
+    #assert bug6654 do
+      # the Module#< operator should be used here instead, but we don't have it
+      assert_include(c.ancestors, a)
+      assert_include(c.ancestors, b)
+    #end
+
+    bug8357 = '[ruby-core:54736] [Bug #8357]'
+    b = labeled_module('b') { prepend a }
+    c = labeled_class('c') { include b }
+
+    #assert bug8357 do
+      # the Module#< operator should be used here instead, but we don't have it
+      assert_include(c.ancestors, a)
+      assert_include(c.ancestors, b)
+    #end
+
+    bug8357 = '[ruby-core:54742] [Bug #8357]'
+    assert_kind_of(b, c.new, bug8357)
+  end
+
+  assert('Moduler#prepend + #instance_methods') do
+    bug6655 = '[ruby-core:45915]'
+    assert_equal(Object.instance_methods, Class.new {prepend Module.new}.instance_methods, bug6655)
+  end
+
+  assert 'Module#prepend + #singleton_methods' do
+    o = Object.new
+    o.singleton_class.class_eval {prepend Module.new}
+    assert_equal([], o.singleton_methods)
+  end
+
+  assert 'Module#prepend + #remove_method' do
+    c = Class.new do
+      prepend Module.new { def foo; end }
+    end
+    assert_raise(NameError) do
+      c.class_eval do
+        remove_method(:foo)
+      end
+    end
+    c.class_eval do
+      def foo; end
+    end
+    removed = nil
+    c.singleton_class.class_eval do
+      define_method(:method_removed) {|id| removed = id}
+    end
+    assert_nothing_raised(NoMethodError, NameError, '[Bug #7843]') do
+      c.class_eval do
+        remove_method(:foo)
+      end
+    end
+    assert_equal(:foo, removed)
+  end
+
+  assert 'Module#prepend + Class#ancestors' do
+    bug6658 = '[ruby-core:45919]'
+    m = labeled_module("m")
+    c = labeled_class("c") {prepend m}
+    assert_equal([m, c], c.ancestors[0, 2], bug6658)
+
+    bug6662 = '[ruby-dev:45868]'
+    c2 = labeled_class("c2", c)
+    anc = c2.ancestors
+    assert_equal([c2, m, c, Object], anc[0..anc.index(Object)], bug6662)
+  end
+
+  assert 'Module#prepend + Module#ancestors' do
+    bug6659 = '[ruby-dev:45861]'
+    m0 = labeled_module("m0") { def x; [:m0, *super] end }
+    m1 = labeled_module("m1") { def x; [:m1, *super] end; prepend m0 }
+    m2 = labeled_module("m2") { def x; [:m2, *super] end; prepend m1 }
+    c0 = labeled_class("c0") { def x; [:c0] end }
+    c1 = labeled_class("c1") { def x; [:c1] end; prepend m2 }
+    c2 = labeled_class("c2", c0) { def x; [:c2, *super] end; include m2 }
+    #
+    assert_equal([m0, m1], m1.ancestors, bug6659)
+    #
+    bug6662 = '[ruby-dev:45868]'
+    assert_equal([m0, m1, m2], m2.ancestors, bug6662)
+    assert_equal([m0, m1, m2, c1], c1.ancestors[0, 4], bug6662)
+    assert_equal([:m0, :m1, :m2, :c1], c1.new.x)
+    assert_equal([c2, m0, m1, m2, c0], c2.ancestors[0, 5], bug6662)
+    assert_equal([:c2, :m0, :m1, :m2, :c0], c2.new.x)
+    #
+    m3 = labeled_module("m3") { include m1; prepend m1 }
+    assert_equal([m3, m0, m1], m3.ancestors)
+    m3 = labeled_module("m3") { prepend m1; include m1 }
+    assert_equal([m0, m1, m3], m3.ancestors)
+    m3 = labeled_module("m3") { prepend m1; prepend m1 }
+    assert_equal([m0, m1, m3], m3.ancestors)
+    m3 = labeled_module("m3") { include m1; include m1 }
+    assert_equal([m3, m0, m1], m3.ancestors)
+  end
+
+  assert 'Module#prepend #instance_methods(false)' do
+    bug6660 = '[ruby-dev:45863]'
+    assert_equal([:m1], Class.new{ prepend Module.new; def m1; end }.instance_methods(false), bug6660)
+    assert_equal([:m1], Class.new(Class.new{def m2;end}){ prepend Module.new; def m1; end }.instance_methods(false), bug6660)
+  end
+
+  assert 'cyclic Module#prepend' do
+    bug7841 = '[ruby-core:52205] [Bug #7841]'
+    m1 = Module.new
+    m2 = Module.new
+    m1.instance_eval { prepend(m2) }
+    assert_raise(ArgumentError, bug7841) do
+      m2.instance_eval { prepend(m1) }
+    end
+  end
+
+  # these assertions will not run without a #assert_seperately method
+  #assert 'test_prepend_optmethod' do
+  #  bug7983 = '[ruby-dev:47124] [Bug #7983]'
+  #  assert_separately [], %{
+  #    module M
+  #      def /(other)
+  #        to_f / other
+  #      end
+  #    end
+  #    Fixnum.send(:prepend, M)
+  #    assert_equal(0.5, 1 / 2, "#{bug7983}")
+  #  }
+  #  assert_equal(0, 1 / 2)
+  #end
+
+  # mruby has no visibility control
+  assert 'Module#prepend visibility' do
+    bug8005 = '[ruby-core:53106] [Bug #8005]'
+    c = Class.new do
+      prepend Module.new {}
+      def foo() end
+      protected :foo
+    end
+    a = c.new
+    assert_true a.respond_to?(:foo), bug8005
+    assert_nothing_raised(NoMethodError, bug8005) {a.send :foo}
+  end
+
+  # mruby has no visibility control
+  assert 'Module#prepend inherited visibility' do
+    bug8238 = '[ruby-core:54105] [Bug #8238]'
+    module Test4PrependVisibilityInherited
+      class A
+        def foo() A; end
+        private :foo
+      end
+      class B < A
+        public :foo
+        prepend Module.new
+      end
+    end
+    assert_equal(Test4PrependVisibilityInherited::A, Test4PrependVisibilityInherited::B.new.foo, "#{bug8238}")
+  end
+
+  assert 'Module#prepend + #included_modules' do
+    bug8025 = '[ruby-core:53158] [Bug #8025]'
+    mixin = labeled_module("mixin")
+    c = labeled_module("c") {prepend mixin}
+    im = c.included_modules
+    assert_not_include(im, c, bug8025)
+    assert_include(im, mixin, bug8025)
+    c1 = labeled_class("c1") {prepend mixin}
+    c2 = labeled_class("c2", c1)
+    im = c2.included_modules
+    assert_not_include(im, c1, bug8025)
+    assert_not_include(im, c2, bug8025)
+    assert_include(im, mixin, bug8025)
+  end
+
+  assert 'Module#prepend super in alias' do
+    skip "super does not currently work in aliased methods"
+    bug7842 = '[Bug #7842]'
+
+    p = labeled_module("P") do
+      def m; "P"+super; end
+    end
+
+    a = labeled_class("A") do
+      def m; "A"; end
+    end
+
+    b = labeled_class("B", a) do
+      def m; "B"+super; end
+      alias m2 m
+      prepend p
+      alias m3 m
+    end
+
+    assert_nothing_raised do
+      assert_equal("BA", b.new.m2, bug7842)
+    end
+
+    assert_nothing_raised do
+      assert_equal("PBA", b.new.m3, bug7842)
+    end
+  end
+
+  assert 'Module#prepend each class' do
+    m = labeled_module("M")
+    c1 = labeled_class("C1") {prepend m}
+    c2 = labeled_class("C2", c1) {prepend m}
+    assert_equal([m, c2, m, c1], c2.ancestors[0, 4], "should be able to prepend each class")
+  end
+
+  assert 'Module#prepend no duplication' do
+    m = labeled_module("M")
+    c = labeled_class("C") {prepend m; prepend m}
+    assert_equal([m, c], c.ancestors[0, 2], "should never duplicate")
+  end
+
+  assert 'Module#prepend in superclass' do
+    m = labeled_module("M")
+    c1 = labeled_class("C1")
+    c2 = labeled_class("C2", c1) {prepend m}
+    c1.class_eval {prepend m}
+    assert_equal([m, c2, m, c1], c2.ancestors[0, 4], "should accesisble prepended module in superclass")
+  end
+
+  # requires #assert_seperately
+  #assert 'Module#prepend call super' do
+  #  assert_separately([], <<-'end;') #do
+  #    bug10847 = '[ruby-core:68093] [Bug #10847]'
+  #    module M; end
+  #    Float.prepend M
+  #    assert_nothing_raised(SystemStackError, bug10847) do
+  #      0.3.numerator
+  #    end
+  #  end;
+  #end
+# @!endgroup prepend
+
+assert('Module#to_s') do
+  module Test4to_sModules
+  end
+
+  assert_equal 'Test4to_sModules', Test4to_sModules.to_s
+end
+
+assert('Module#inspect') do
+  module Test4to_sModules
+  end
+
+  assert_equal 'Test4to_sModules', Test4to_sModules.inspect
+end
+
+assert('Issue 1467') do
+  module M1
+    def initialize()
+      super()
+    end
+  end
+
+  class C1
+    include M1
+     def initialize()
+       super()
+     end
+  end
+
+  class C2
+    include M1
+  end
+
+  C1.new
+  C2.new
+end
+
+assert('clone Module') do
+  module M1
+    def foo
+      true
+    end
+  end
+
+  class B
+    include M1.clone
+  end
+
+  B.new.foo
+end
+
+assert('Module#module_function') do
+  module M
+    def modfunc; end
+    module_function :modfunc
+  end
+
+  assert_true M.respond_to?(:modfunc)
+end
+
+assert('module with non-class/module outer raises TypeError') do
+  assert_raise(TypeError) { module 0::M1 end }
+  assert_raise(TypeError) { module []::M2 end }
+end
+
+assert('get constant of parent module in singleton class; issue #3568') do
+  actual = module GetConstantInSingletonTest
+    EXPECTED = "value"
+    class << self
+      EXPECTED
+    end
+  end
+
+  assert_equal("value", actual)
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/nameerror.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/nameerror.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/nameerror.rb	(revision 331)
@@ -0,0 +1,28 @@
+##
+# NameError ISO Test
+
+assert('NameError', '15.2.31') do
+  assert_equal Class, NameError.class
+end
+
+assert('NameError#name', '15.2.31.2.1') do
+
+  # This check is not duplicate with 15.2.31.2.2 check.
+  # Because the NameError in this test is generated in
+  # C API.
+  class TestDummy
+    alias foo bar
+  rescue NameError => e
+    $test_dummy_result = e.name
+  end
+
+  assert_equal :bar, $test_dummy_result
+end
+
+assert('NameError#initialize', '15.2.31.2.2') do
+   e = NameError.new('a', :foo)
+
+   assert_equal NameError, e.class
+   assert_equal 'a', e.message
+   assert_equal :foo, e.name
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/nil.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/nil.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/nil.rb	(revision 331)
@@ -0,0 +1,39 @@
+##
+# NilClass ISO Test
+
+assert('NilClass', '15.2.4') do
+  assert_equal Class, NilClass.class
+end
+
+assert('NilClass', '15.2.4.1') do
+  assert_equal NilClass, nil.class
+  assert_false NilClass.method_defined? :new
+end
+
+assert('NilClass#&', '15.2.4.3.1') do
+  assert_false nil.&(true)
+  assert_false nil.&(nil)
+end
+
+assert('NilClass#^', '15.2.4.3.2') do
+  assert_true nil.^(true)
+  assert_false nil.^(false)
+end
+
+assert('NilClass#|', '15.2.4.3.3') do
+  assert_true nil.|(true)
+  assert_false nil.|(false)
+end
+
+assert('NilClass#nil?', '15.2.4.3.4') do
+  assert_true nil.nil?
+end
+
+assert('NilClass#to_s', '15.2.4.3.5') do
+  assert_equal '', nil.to_s
+end
+
+assert('safe navigation') do
+  assert_nil nil&.size
+  assert_equal 0, []&.size
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/nomethoderror.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/nomethoderror.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/nomethoderror.rb	(revision 331)
@@ -0,0 +1,22 @@
+##
+# NoMethodError ISO Test
+
+assert('NoMethodError', '15.2.32') do
+  NoMethodError.class == Class
+  assert_raise NoMethodError do
+    doesNotExistAsAMethodNameForVerySure("")
+  end
+end
+
+assert('NoMethodError#args', '15.2.32.2.1') do
+  a = NoMethodError.new 'test', :test, [1, 2]
+  assert_equal [1, 2], a.args
+
+  assert_nothing_raised do
+    begin
+      doesNotExistAsAMethodNameForVerySure 3, 1, 4
+    rescue NoMethodError => e
+      assert_equal [3, 1, 4], e.args
+    end
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/numeric.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/numeric.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/numeric.rb	(revision 331)
@@ -0,0 +1,43 @@
+##
+# Numeric ISO Test
+
+assert('Numeric', '15.2.7') do
+  assert_equal Class, Numeric.class
+end
+
+assert('Numeric#+@', '15.2.7.4.1') do
+  assert_equal(+1, +1)
+end
+
+assert('Numeric#-@', '15.2.7.4.2') do
+  assert_equal(-1, -1)
+end
+
+assert('Numeric#abs', '15.2.7.4.3') do
+  assert_equal(1, 1.abs)
+  assert_equal(1.0, -1.abs)
+end
+
+assert('Numeric#pow') do
+  assert_equal(8, 2 ** 3)
+  assert_equal(-8, -2 ** 3)
+  assert_equal(1, 2 ** 0)
+  assert_equal(1, 2.2 ** 0)
+  assert_equal(0.5, 2 ** -1)
+end
+
+assert('Numeric#/', '15.2.8.3.4') do
+  n = Class.new(Numeric){ def /(x); 15.1;end }.new
+
+  assert_equal(2, 10/5)
+  assert_equal(0.0625, 1/16)
+  assert_equal(15.1, n/10)
+  assert_raise(TypeError){ 1/n }
+  assert_raise(TypeError){ 1/nil }
+end
+
+# Not ISO specified
+
+assert('Numeric#**') do
+  assert_equal 8.0, 2.0**3
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/object.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/object.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/object.rb	(revision 331)
@@ -0,0 +1,11 @@
+##
+# Object ISO Test
+
+assert('Object', '15.2.1') do
+  assert_equal Class, Object.class
+end
+
+assert('Object superclass', '15.2.1.2') do
+  assert_equal BasicObject, Object.superclass
+end
+
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/proc.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/proc.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/proc.rb	(revision 331)
@@ -0,0 +1,166 @@
+##
+# Proc ISO Test
+
+assert('Proc', '15.2.17') do
+  assert_equal Class, Proc.class
+end
+
+assert('Proc.new', '15.2.17.3.1') do
+  assert_raise ArgumentError do
+    Proc.new
+  end
+
+  assert_equal (Proc.new {}).class, Proc
+end
+
+assert('Proc#[]', '15.2.17.4.1') do
+  a = 0
+  b = Proc.new { a += 1 }
+  b.[]
+
+  a2 = 0
+  b2 = Proc.new { |i| a2 += i }
+  b2.[](5)
+
+  assert_equal 1, a
+  assert_equal 5, a2
+end
+
+assert('Proc#arity', '15.2.17.4.2') do
+  a = Proc.new {|x, y|}.arity
+  b = Proc.new {|x, *y, z|}.arity
+  c = Proc.new {|x=0, y|}.arity
+  d = Proc.new {|(x, y), z=0|}.arity
+
+  assert_equal  2, a
+  assert_equal(-3, b)
+  assert_equal  1, c
+  assert_equal  1, d
+
+  e = ->(x=0, y){}.arity
+  f = ->((x, y), z=0){}.arity
+  g = ->(x=0){}.arity
+
+  assert_equal(-2, e)
+  assert_equal(-2, f)
+  assert_equal(-1, g)
+end
+
+assert('Proc#call', '15.2.17.4.3') do
+  a = 0
+  b = Proc.new { a += 1 }
+  b.call
+
+  a2 = 0
+  b2 = Proc.new { |i| a2 += i }
+  b2.call(5)
+
+  assert_equal 1, a
+  assert_equal 5, a2
+end
+
+assert('Proc#call proc args pos block') do
+  pr = Proc.new {|a,b,&c|
+    [a, b, c.class, c&&c.call(:x)]
+  }
+  assert_equal [nil, nil, Proc, :proc], (pr.call(){ :proc })
+  assert_equal [1, nil, Proc, :proc], (pr.call(1){ :proc })
+  assert_equal [1, 2, Proc, :proc], (pr.call(1, 2){ :proc })
+  assert_equal [1, 2, Proc, :proc], (pr.call(1, 2, 3){ :proc })
+  assert_equal [1, 2, Proc, :proc], (pr.call(1, 2, 3, 4){ :proc })
+
+  assert_equal [nil, nil, Proc, :x], (pr.call(){|x| x})
+  assert_equal [1, nil, Proc, :x], (pr.call(1){|x| x})
+  assert_equal [1, 2, Proc, :x], (pr.call(1, 2){|x| x})
+  assert_equal [1, 2, Proc, :x], (pr.call(1, 2, 3){|x| x})
+  assert_equal [1, 2, Proc, :x], (pr.call(1, 2, 3, 4){|x| x})
+end
+
+assert('Proc#call proc args pos rest post') do
+  pr = Proc.new {|a,b,*c,d,e|
+    [a,b,c,d,e]
+  }
+  assert_equal [nil, nil, [], nil, nil], pr.call()
+  assert_equal [1, nil, [], nil, nil], pr.call(1)
+  assert_equal [1, 2, [], nil, nil], pr.call(1,2)
+  assert_equal [1, 2, [], 3, nil], pr.call(1,2,3)
+  assert_equal [1, 2, [], 3, 4], pr.call(1,2,3,4)
+  assert_equal [1, 2, [3], 4, 5], pr.call(1,2,3,4,5)
+  assert_equal [1, 2, [3, 4], 5, 6], pr.call(1,2,3,4,5,6)
+  assert_equal [1, 2, [3, 4, 5], 6,7], pr.call(1,2,3,4,5,6,7)
+
+  assert_equal [nil, nil, [], nil, nil], pr.call([])
+  assert_equal [1, nil, [], nil, nil], pr.call([1])
+  assert_equal [1, 2, [], nil, nil], pr.call([1,2])
+  assert_equal [1, 2, [], 3, nil], pr.call([1,2,3])
+  assert_equal [1, 2, [], 3, 4], pr.call([1,2,3,4])
+  assert_equal [1, 2, [3], 4, 5], pr.call([1,2,3,4,5])
+  assert_equal [1, 2, [3, 4], 5, 6], pr.call([1,2,3,4,5,6])
+  assert_equal [1, 2, [3, 4, 5], 6,7], pr.call([1,2,3,4,5,6,7])
+end
+
+assert('Proc#return_does_not_break_self') do
+  class TestClass
+    attr_accessor :block
+    def initialize
+    end
+    def return_array
+      @block = Proc.new { self }
+      return []
+    end
+    def return_instance_variable
+      @block = Proc.new { self }
+      return @block
+    end
+    def return_const_fixnum
+      @block = Proc.new { self }
+      return 123
+    end
+    def return_nil
+      @block = Proc.new { self }
+      return nil
+    end
+  end
+
+  c = TestClass.new
+  assert_equal [], c.return_array
+  assert_equal c, c.block.call
+
+  c.return_instance_variable
+  assert_equal c, c.block.call
+
+  assert_equal 123, c.return_const_fixnum
+  assert_equal c, c.block.call
+
+  assert_equal nil, c.return_nil
+  assert_equal c, c.block.call
+end
+
+assert('call Proc#initialize if defined') do
+  a = []
+  c = Class.new(Proc) do
+    define_method(:initialize) do
+      a << :ok
+    end
+  end
+
+  assert_kind_of c, c.new{}
+  assert_equal [:ok], a
+end
+
+assert('&obj call to_proc if defined') do
+  pr = Proc.new{}
+  def mock(&b)
+    b
+  end
+  assert_equal pr.object_id, mock(&pr).object_id
+  assert_equal pr, mock(&pr)
+
+  obj = Object.new
+  def obj.to_proc
+    Proc.new{ :from_to_proc }
+  end
+  assert_equal :from_to_proc, mock(&obj).call
+
+  assert_raise(TypeError){ mock(&(Object.new)) }
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/range.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/range.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/range.rb	(revision 331)
@@ -0,0 +1,95 @@
+##
+# Range ISO Test
+
+assert('Range', '15.2.14') do
+  assert_equal Class, Range.class
+end
+
+assert('Range#==', '15.2.14.4.1') do
+  assert_true (1..10) == (1..10)
+  assert_false (1..10) == (1..100)
+  assert_true (1..10) == Range.new(1.0, 10.0)
+end
+
+assert('Range#===', '15.2.14.4.2') do
+  a = (1..10)
+
+  assert_true a === 5
+  assert_false a === 20
+end
+
+assert('Range#begin', '15.2.14.4.3') do
+  assert_equal 1, (1..10).begin
+end
+
+assert('Range#each', '15.2.14.4.4') do
+  a = (1..3)
+  b = 0
+  a.each {|i| b += i}
+  assert_equal 6, b
+end
+
+assert('Range#end', '15.2.14.4.5') do
+  assert_equal 10, (1..10).end
+end
+
+assert('Range#exclude_end?', '15.2.14.4.6') do
+  assert_true (1...10).exclude_end?
+  assert_false (1..10).exclude_end?
+end
+
+assert('Range#first', '15.2.14.4.7') do
+  assert_equal 1, (1..10).first
+end
+
+assert('Range#include?', '15.2.14.4.8') do
+  assert_true (1..10).include?(10)
+  assert_false (1..10).include?(11)
+
+  assert_true (1...10).include?(9)
+  assert_false (1...10).include?(10)
+end
+
+assert('Range#initialize', '15.2.14.4.9') do
+  a = Range.new(1, 10, true)
+  b = Range.new(1, 10, false)
+
+  assert_equal (1...10), a
+  assert_true a.exclude_end?
+  assert_equal (1..10), b
+  assert_false b.exclude_end?
+
+  assert_raise(NameError) { (0..1).send(:initialize, 1, 3) }
+end
+
+assert('Range#last', '15.2.14.4.10') do
+  assert_equal 10, (1..10).last
+end
+
+assert('Range#member?', '15.2.14.4.11') do
+  a = (1..10)
+
+  assert_true a.member?(5)
+  assert_false a.member?(20)
+end
+
+assert('Range#to_s', '15.2.14.4.12') do
+  assert_equal "0..1", (0..1).to_s
+  assert_equal "0...1", (0...1).to_s
+  assert_equal "a..b", ("a".."b").to_s
+  assert_equal "a...b", ("a"..."b").to_s
+end
+
+assert('Range#inspect', '15.2.14.4.13') do
+  assert_equal "0..1", (0..1).inspect
+  assert_equal "0...1", (0...1).inspect
+  assert_equal "\"a\"..\"b\"", ("a".."b").inspect
+  assert_equal "\"a\"...\"b\"", ("a"..."b").inspect
+end
+
+assert('Range#eql?', '15.2.14.4.14') do
+  assert_true (1..10).eql? (1..10)
+  assert_false (1..10).eql? (1..100)
+  assert_false (1..10).eql? (Range.new(1.0, 10.0))
+  assert_false (1..10).eql? "1..10"
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/rangeerror.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/rangeerror.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/rangeerror.rb	(revision 331)
@@ -0,0 +1,6 @@
+##
+# RangeError ISO Test
+
+assert('RangeError', '15.2.26') do
+  assert_equal Class, RangeError.class
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/regexperror.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/regexperror.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/regexperror.rb	(revision 331)
@@ -0,0 +1,4 @@
+##
+# RegexpError ISO Test
+
+# TODO broken ATM assert('RegexpError', '15.2.27') do
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/runtimeerror.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/runtimeerror.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/runtimeerror.rb	(revision 331)
@@ -0,0 +1,6 @@
+##
+# RuntimeError ISO Test
+
+assert('RuntimeError', '15.2.28') do
+  assert_equal Class, RuntimeError.class
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/standarderror.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/standarderror.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/standarderror.rb	(revision 331)
@@ -0,0 +1,6 @@
+##
+# StandardError ISO Test
+
+assert('StandardError', '15.2.23') do
+  assert_equal Class, StandardError.class
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/string.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/string.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/string.rb	(revision 331)
@@ -0,0 +1,727 @@
+# coding: utf-8
+##
+# String ISO Test
+
+UTF8STRING = ("\343\201\202".size == 1)
+
+assert('String', '15.2.10') do
+  assert_equal Class, String.class
+end
+
+assert('String#<=>', '15.2.10.5.1') do
+  a = '' <=> ''
+  b = '' <=> 'not empty'
+  c = 'not empty' <=> ''
+  d = 'abc' <=> 'cba'
+  e = 'cba' <=> 'abc'
+
+  assert_equal  0, a
+  assert_equal(-1, b)
+  assert_equal  1, c
+  assert_equal(-1, d)
+  assert_equal  1, e
+end
+
+assert('String#==', '15.2.10.5.2') do
+  assert_equal 'abc', 'abc'
+  assert_not_equal 'abc', 'cba'
+end
+
+# 'String#=~', '15.2.10.5.3' will be tested in mrbgems.
+
+assert('String#+', '15.2.10.5.4') do
+  assert_equal 'ab', 'a' + 'b'
+end
+
+assert('String#*', '15.2.10.5.5') do
+  assert_equal 'aaaaa', 'a' * 5
+  assert_equal '', 'a' * 0
+  assert_raise(ArgumentError) do
+    'a' * -1
+  end
+end
+
+assert('String#[]', '15.2.10.5.6') do
+  # length of args is 1
+  a = 'abc'[0]
+  b = 'abc'[-1]
+  c = 'abc'[10]
+  d = 'abc'[-10]
+  e = 'abc'[1.1]
+
+  # length of args is 2
+  a1 = 'abc'[0, -1]
+  b1 = 'abc'[10, 0]
+  c1 = 'abc'[-10, 0]
+  d1 = 'abc'[0, 0]
+  e1 = 'abc'[1, 2]
+
+  # args is RegExp
+  # It will be tested in mrbgems.
+
+  # args is String
+  a3 = 'abc'['bc']
+  b3 = 'abc'['XX']
+
+  assert_equal 'a', 'a'
+  # assert_equal 'c', b
+  # assert_nil c
+  # assert_nil d
+  # assert_equal 'b', e
+  # assert_nil a1
+  # assert_nil b1
+  # assert_nil c1
+  # assert_equal '', d1
+  # assert_equal 'bc', e1
+  # assert_equal 'bc', a3
+  # assert_nil b3
+
+  # assert_raise(TypeError) do
+  #   a[nil]
+  # end
+end
+
+assert('String#[](UTF-8)', '15.2.10.5.6') do
+  assert_equal "ち", "こんにちは世界"[3]
+  assert_equal nil, "こんにちは世界"[20]
+  assert_equal "世", "こんにちは世界"[-2]
+  assert_equal "世界", "こんにちは世界"[-2..-1]
+  assert_equal "んに", "こんにちは世界"[1,2]
+  assert_equal "世", "こんにちは世界"["世"]
+end if UTF8STRING
+
+assert('String#[] with Range') do
+  a1 = 'abc'[1..0]
+  b1 = 'abc'[1..1]
+  c1 = 'abc'[1..2]
+  d1 = 'abc'[1..3]
+  e1 = 'abc'[1..4]
+  f1 = 'abc'[0..-2]
+  g1 = 'abc'[-2..3]
+  h1 = 'abc'[3..4]
+  i1 = 'abc'[4..5]
+  j1 = 'abcdefghijklmnopqrstuvwxyz'[1..3]
+  a2 = 'abc'[1...0]
+  b2 = 'abc'[1...1]
+  c2 = 'abc'[1...2]
+  d2 = 'abc'[1...3]
+  e2 = 'abc'[1...4]
+  f2 = 'abc'[0...-2]
+  g2 = 'abc'[-2...3]
+  h2 = 'abc'[3...4]
+  i2 = 'abc'[4...5]
+  j2 = 'abcdefghijklmnopqrstuvwxyz'[1...3]
+
+  assert_equal '', a1
+  assert_equal 'b', b1
+  assert_equal 'bc', c1
+  assert_equal 'bc', d1
+  assert_equal 'bc', e1
+  assert_equal 'ab', f1
+  assert_equal 'bc', g1
+  assert_equal '', h1
+  assert_nil i2
+  assert_equal 'bcd', j1
+  assert_equal '', a2
+  assert_equal '', b2
+  assert_equal 'b', c2
+  assert_equal 'bc', d2
+  assert_equal 'bc', e2
+  assert_equal 'a', f2
+  assert_equal 'bc', g2
+  assert_equal '', h2
+  assert_nil i2
+  assert_equal 'bc', j2
+end
+
+assert('String#[]=') do
+  # length of args is 1
+  a = 'abc'
+  a[0] = 'X'
+  assert_equal 'Xbc', a
+
+  b = 'abc'
+  b[-1] = 'X'
+  assert_equal 'abX', b
+
+  c = 'abc'
+  assert_raise(IndexError) do
+    c[10] = 'X'
+  end
+
+  d = 'abc'
+  assert_raise(IndexError) do
+    d[-10] = 'X'
+  end
+
+  e = 'abc'
+  e[1.1] = 'X'
+  assert_equal 'aXc', e
+
+
+  # length of args is 2
+  a1 = 'abc'
+  assert_raise(IndexError) do
+    a1[0, -1] = 'X'
+  end
+
+  b1 = 'abc'
+  assert_raise(IndexError) do
+    b1[10, 0] = 'X'
+  end
+
+  c1 = 'abc'
+  assert_raise(IndexError) do
+    c1[-10, 0] = 'X'
+  end
+
+  d1 = 'abc'
+  d1[0, 0] = 'X'
+  assert_equal 'Xabc', d1
+
+  e1 = 'abc'
+  e1[1, 3] = 'X'
+  assert_equal 'aX', e1
+
+  # args is RegExp
+  # It will be tested in mrbgems.
+
+  # args is String
+  a3 = 'abc'
+  a3['bc'] = 'X'
+  assert_equal a3, 'aX'
+
+  b3 = 'abc'
+  assert_raise(IndexError) do
+    b3['XX'] = 'Y'
+  end
+end
+
+assert('String#capitalize', '15.2.10.5.7') do
+  a = 'abc'
+  a.capitalize
+
+  assert_equal 'abc', a
+  assert_equal 'Abc', 'abc'.capitalize
+end
+
+assert('String#capitalize!', '15.2.10.5.8') do
+  a = 'abc'
+  a.capitalize!
+
+  assert_equal 'Abc', a
+  assert_equal nil, 'Abc'.capitalize!
+end
+
+assert('String#chomp', '15.2.10.5.9') do
+  a = 'abc'.chomp
+  b = ''.chomp
+  c = "abc\n".chomp
+  d = "abc\n\n".chomp
+  e = "abc\t".chomp("\t")
+  f = "abc\n"
+
+  f.chomp
+
+  assert_equal 'abc', a
+  assert_equal '', b
+  assert_equal 'abc', c
+  assert_equal "abc\n", d
+  assert_equal 'abc', e
+  assert_equal "abc\n", f
+end
+
+assert('String#chomp!', '15.2.10.5.10') do
+  a = 'abc'
+  b = ''
+  c = "abc\n"
+  d = "abc\n\n"
+  e = "abc\t"
+
+  a.chomp!
+  b.chomp!
+  c.chomp!
+  d.chomp!
+  e.chomp!("\t")
+
+  assert_equal 'abc', a
+  assert_equal '', b
+  assert_equal 'abc', c
+  assert_equal "abc\n", d
+  assert_equal 'abc', e
+end
+
+assert('String#chomp! uses the correct length') do
+  class A
+    def to_str
+      $s.replace("AA")
+      "A"
+    end
+  end
+
+  $s = "AAA"
+  $s.chomp!(A.new)
+  assert_equal $s, "A"
+end
+
+assert('String#chop', '15.2.10.5.11') do
+  a = ''.chop
+  b = 'abc'.chop
+  c = 'abc'
+
+  c.chop
+
+  assert_equal '', a
+  assert_equal 'ab', b
+  assert_equal 'abc', c
+end
+
+assert('String#chop(UTF-8)', '15.2.10.5.11') do
+  a = ''.chop
+  b = 'あいう'.chop
+  c = "あ\nい".chop.chop
+
+  assert_equal '', a
+  assert_equal 'あい', b
+  assert_equal 'あ', c
+end if UTF8STRING
+
+assert('String#chop!', '15.2.10.5.12') do
+  a = ''
+  b = 'abc'
+
+  a.chop!
+  b.chop!
+
+  assert_equal a, ''
+  assert_equal b, 'ab'
+end
+
+assert('String#chop!(UTF-8)', '15.2.10.5.12') do
+  a = ''
+  b = "あいうえ\n"
+  c = "あいうえ\n"
+
+  a.chop!
+  b.chop!
+  c.chop!
+  c.chop!
+
+  assert_equal a, ''
+  assert_equal b, 'あいうえ'
+  assert_equal c, 'あいう'
+end if UTF8STRING
+
+assert('String#downcase', '15.2.10.5.13') do
+  a = 'ABC'.downcase
+  b = 'ABC'
+
+  b.downcase
+
+  assert_equal 'abc', a
+  assert_equal 'ABC', b
+end
+
+assert('String#downcase!', '15.2.10.5.14') do
+  a = 'ABC'
+
+  a.downcase!
+
+  assert_equal 'abc', a
+  assert_equal nil, 'abc'.downcase!
+end
+
+assert('String#each_line', '15.2.10.5.15') do
+  a = "first line\nsecond line\nthird line"
+  list = ["first line\n", "second line\n", "third line"]
+  n_list = []
+
+  a.each_line do |line|
+    n_list << line
+  end
+
+  assert_equal list, n_list
+
+  n_list.clear
+  a.each_line("li") do |line|
+    n_list << line
+  end
+  assert_equal ["first li", "ne\nsecond li", "ne\nthird li", "ne"], n_list
+end
+
+assert('String#empty?', '15.2.10.5.16') do
+  a = ''
+  b = 'not empty'
+
+  assert_true a.empty?
+  assert_false b.empty?
+end
+
+assert('String#eql?', '15.2.10.5.17') do
+  assert_true 'abc'.eql?('abc')
+  assert_false 'abc'.eql?('cba')
+end
+
+assert('String#gsub', '15.2.10.5.18') do
+  assert_equal('aBcaBc', 'abcabc'.gsub('b', 'B'), 'gsub without block')
+  assert_equal('aBcaBc', 'abcabc'.gsub('b'){|w| w.capitalize }, 'gsub with block')
+  assert_equal('$a$a$',  '#a#a#'.gsub('#', '$'), 'mruby/mruby#847')
+  assert_equal('$a$a$',  '#a#a#'.gsub('#'){|w| '$' }, 'mruby/mruby#847 with block')
+  assert_equal('$$a$$',  '##a##'.gsub('##', '$$'), 'mruby/mruby#847 another case')
+  assert_equal('$$a$$',  '##a##'.gsub('##'){|w| '$$' }, 'mruby/mruby#847 another case with block')
+  assert_equal('A',      'a'.gsub('a', 'A'))
+  assert_equal('A',      'a'.gsub('a'){|w| w.capitalize })
+  assert_equal("<a><><>", 'a'.gsub('a', '<\0><\1><\2>'))
+  assert_equal(".h.e.l.l.o.", "hello".gsub("", "."))
+  a = []
+  assert_equal(".h.e.l.l.o.", "hello".gsub("") { |i| a << i; "." })
+  assert_equal(["", "", "", "", "", ""], a)
+  assert_raise(ArgumentError) { "".gsub }
+  assert_raise(ArgumentError) { "".gsub("", "", "") }
+end
+
+assert('String#gsub with backslash') do
+  s = 'abXcdXef'
+  assert_equal 'ab<\\>cd<\\>ef',    s.gsub('X', '<\\\\>')
+  assert_equal 'ab<X>cd<X>ef',      s.gsub('X', '<\\&>')
+  assert_equal 'ab<X>cd<X>ef',      s.gsub('X', '<\\0>')
+  assert_equal 'ab<ab>cd<abXcd>ef', s.gsub('X', '<\\`>')
+  assert_equal 'ab<cdXef>cd<ef>ef', s.gsub('X', '<\\\'>')
+end
+
+assert('String#gsub!', '15.2.10.5.19') do
+  a = 'abcabc'
+  a.gsub!('b', 'B')
+
+  b = 'abcabc'
+  b.gsub!('b') { |w| w.capitalize }
+
+  assert_equal 'aBcaBc', a
+  assert_equal 'aBcaBc', b
+end
+
+assert('String#hash', '15.2.10.5.20') do
+  a = 'abc'
+
+  assert_equal 'abc'.hash, a.hash
+end
+
+assert('String#include?', '15.2.10.5.21') do
+  assert_true 'abc'.include?('a')
+  assert_false 'abc'.include?('d')
+end
+
+assert('String#index', '15.2.10.5.22') do
+  assert_equal 0, 'abc'.index('a')
+  assert_nil 'abc'.index('d')
+  assert_equal 3, 'abcabc'.index('a', 1)
+  assert_equal 5, "hello".index("", 5)
+  assert_equal nil, "hello".index("", 6)
+end
+
+assert('String#initialize', '15.2.10.5.23') do
+  a = ''
+  a.initialize('abc')
+  assert_equal 'abc', a
+
+  a.initialize('abcdefghijklmnopqrstuvwxyz')
+  assert_equal 'abcdefghijklmnopqrstuvwxyz', a
+end
+
+assert('String#initialize_copy', '15.2.10.5.24') do
+  a = ''
+  a.initialize_copy('abc')
+
+  assert_equal 'abc', a
+end
+
+assert('String#intern', '15.2.10.5.25') do
+  assert_equal :abc, 'abc'.intern
+end
+
+assert('String#length', '15.2.10.5.26') do
+  assert_equal 3, 'abc'.length
+end
+
+# 'String#match', '15.2.10.5.27' will be tested in mrbgems.
+
+assert('String#replace', '15.2.10.5.28') do
+  a = ''
+  a.replace('abc')
+
+  assert_equal 'abc', a
+  assert_equal 'abc', 'cba'.replace(a)
+
+  b = 'abc' * 10
+  c = ('cba' * 10).dup
+  b.replace(c);
+  c.replace(b);
+  assert_equal c, b
+
+  # shared string
+  s = "foo" * 100
+  a = s[10, 90]                # create shared string
+  assert_equal("", s.replace(""))    # clear
+  assert_equal("", s)          # s is cleared
+  assert_not_equal("", a)      # a should not be affected
+end
+
+assert('String#reverse', '15.2.10.5.29') do
+  a = 'abc'
+  a.reverse
+
+  assert_equal 'abc', a
+  assert_equal 'cba', 'abc'.reverse
+end
+
+assert('String#reverse(UTF-8)', '15.2.10.5.29') do
+  assert_equal "ち", "こんにちは世界"[3]
+  assert_equal nil, "こんにちは世界"[20]
+  assert_equal "世", "こんにちは世界"[-2]
+  assert_equal "世界", "こんにちは世界"[-2..-1]
+  assert_equal "んに", "こんにちは世界"[1,2]
+  assert_equal "世", "こんにちは世界"["世"]
+end if UTF8STRING
+
+assert('String#reverse!', '15.2.10.5.30') do
+  a = 'abc'
+  a.reverse!
+
+  assert_equal 'cba', a
+  assert_equal 'cba', 'abc'.reverse!
+end
+
+assert('String#reverse!(UTF-8)', '15.2.10.5.30') do
+  a = 'こんにちは世界!'
+  a.reverse!
+
+  assert_equal '!界世はちにんこ', a
+  assert_equal '!界世はちにんこ', 'こんにちは世界!'.reverse!
+end if UTF8STRING
+
+assert('String#rindex', '15.2.10.5.31') do
+  assert_equal 0, 'abc'.rindex('a')
+  assert_nil 'abc'.rindex('d')
+  assert_equal 0, 'abcabc'.rindex('a', 1)
+  assert_equal 3, 'abcabc'.rindex('a', 4)
+end
+
+assert('String#rindex(UTF-8)', '15.2.10.5.31') do
+  str = "こんにちは世界!\nこんにちは世界!"
+  assert_nil str.index('さ')
+  assert_equal 3, str.index('ち')
+  assert_equal 12, str.index('ち', 10)
+  assert_equal nil, str.index("さ")
+end if UTF8STRING
+
+# 'String#scan', '15.2.10.5.32' will be tested in mrbgems.
+
+assert('String#size', '15.2.10.5.33') do
+  assert_equal 3, 'abc'.size
+end
+
+assert('String#size(UTF-8)', '15.2.10.5.33') do
+  str = 'こんにちは世界!'
+  assert_equal 8, str.size
+  assert_not_equal str.bytesize, str.size
+  assert_equal 2, str[1, 2].size
+end if UTF8STRING
+
+assert('String#slice', '15.2.10.5.34') do
+  # length of args is 1
+  a = 'abc'.slice(0)
+  b = 'abc'.slice(-1)
+  c = 'abc'.slice(10)
+  d = 'abc'.slice(-10)
+
+  # length of args is 2
+  a1 = 'abc'.slice(0, -1)
+  b1 = 'abc'.slice(10, 0)
+  c1 = 'abc'.slice(-10, 0)
+  d1 = 'abc'.slice(0, 0)
+  e1 = 'abc'.slice(1, 2)
+
+  # slice of shared string
+  e11 = e1.slice(0)
+
+  # args is RegExp
+  # It will be tested in mrbgems.
+
+  # args is String
+  a3 = 'abc'.slice('bc')
+  b3 = 'abc'.slice('XX')
+
+  assert_equal 'a', a
+  assert_equal 'c', b
+  assert_nil c
+  assert_nil d
+  assert_nil a1
+  assert_nil b1
+  assert_nil c1
+  assert_equal '', d1
+  assert_equal 'bc', e1
+  assert_equal 'b', e11
+  assert_equal 'bc', a3
+  assert_nil b3
+end
+
+# TODO Broken ATM
+assert('String#split', '15.2.10.5.35') do
+  # without RegExp behavior is actually unspecified
+  assert_equal ['abc', 'abc', 'abc'], 'abc abc abc'.split
+  assert_equal ["a", "b", "c", "", "d"], 'a,b,c,,d'.split(',')
+  assert_equal ['abc', 'abc', 'abc'], 'abc abc abc'.split(nil)
+  assert_equal ['a', 'b', 'c'], 'abc'.split("")
+end
+
+assert('String#split(UTF-8)', '15.2.10.5.35') do
+  got = "こんにちは世界!".split('')
+  assert_equal ['こ', 'ん', 'に', 'ち', 'は', '世', '界', '!'], got
+  got = "こんにちは世界!".split('に')
+  assert_equal ['こん', 'ちは世界!'], got
+end if UTF8STRING
+
+assert('String#sub', '15.2.10.5.36') do
+  assert_equal 'aBcabc', 'abcabc'.sub('b', 'B')
+  assert_equal 'aBcabc', 'abcabc'.sub('b') { |w| w.capitalize }
+  assert_equal 'aa$', 'aa#'.sub('#', '$')
+  assert_equal '.abc', "abc".sub("", ".")
+
+  str = "abc"
+  miss = str.sub("X", "Z")
+  assert_equal str, miss
+  assert_not_equal str.object_id, miss.object_id
+
+  a = []
+  assert_equal '.abc', "abc".sub("") { |i| a << i; "." }
+  assert_equal [""], a
+end
+
+assert('String#sub with backslash') do
+  s = 'abXcdXef'
+  assert_equal 'ab<\\>cdXef',    s.sub('X', '<\\\\>')
+  assert_equal 'ab<X>cdXef',     s.sub('X', '<\\&>')
+  assert_equal 'ab<X>cdXef',     s.sub('X', '<\\0>')
+  assert_equal 'ab<ab>cdXef',    s.sub('X', '<\\`>')
+  assert_equal 'ab<cdXef>cdXef', s.sub('X', '<\\\'>')
+end
+
+assert('String#sub!', '15.2.10.5.37') do
+  a = 'abcabc'
+  a.sub!('b', 'B')
+
+  b = 'abcabc'
+  b.sub!('b') { |w| w.capitalize }
+
+  assert_equal 'aBcabc', a
+  assert_equal 'aBcabc', b
+end
+
+assert('String#to_f', '15.2.10.5.38') do
+  a = ''.to_f
+  b = '123456789'.to_f
+  c = '12345.6789'.to_f
+  d = '1e-2147483648'.to_f
+  e = '1e2147483648'.to_f
+
+  assert_float(0.0, a)
+  assert_float(123456789.0, b)
+  assert_float(12345.6789, c)
+  assert_float(0, d)
+  assert_float(Float::INFINITY, e)
+end
+
+assert('String#to_i', '15.2.10.5.39') do
+  a = ''.to_i
+  b = '32143'.to_i
+  c = 'a'.to_i(16)
+  d = '100'.to_i(2)
+  e = '1_000'.to_i
+
+  assert_equal 0, a
+  assert_equal 32143, b
+  assert_equal 10, c
+  assert_equal 4, d
+  assert_equal 1_000, e
+end
+
+assert('String#to_s', '15.2.10.5.40') do
+  assert_equal 'abc', 'abc'.to_s
+end
+
+assert('String#to_sym', '15.2.10.5.41') do
+  assert_equal :abc, 'abc'.to_sym
+end
+
+assert('String#upcase', '15.2.10.5.42') do
+  a = 'abc'.upcase
+  b = 'abc'
+
+  b.upcase
+
+  assert_equal 'ABC', a
+  assert_equal 'abc', b
+end
+
+assert('String#upcase!', '15.2.10.5.43') do
+  a = 'abc'
+
+  a.upcase!
+
+  assert_equal 'ABC', a
+  assert_equal nil, 'ABC'.upcase!
+
+  a = 'abcdefghijklmnopqrstuvwxyz'
+  b = a.dup
+  a.upcase!
+  b.upcase!
+  assert_equal 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', b
+end
+
+assert('String#inspect', '15.2.10.5.46') do
+  # should not raise an exception - regress #1210
+  assert_nothing_raised do
+  ("\1" * 100).inspect
+  end
+
+  assert_equal "\"\\000\"", "\0".inspect
+end
+
+# Not ISO specified
+
+assert('String interpolation (mrb_str_concat for shared strings)') do
+  a = "A" * 32
+  assert_equal "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA:", "#{a}:"
+end
+
+assert('Check the usage of a NUL character') do
+  "qqq\0ppp"
+end
+
+assert('String#bytes') do
+  str1 = "hello"
+  bytes1 = [104, 101, 108, 108, 111]
+
+  str2 = "\xFF"
+  bytes2 = [0xFF]
+
+  assert_equal bytes1, str1.bytes
+  assert_equal bytes2, str2.bytes
+end
+
+assert('String#each_byte') do
+  str1 = "hello"
+  bytes1 = [104, 101, 108, 108, 111]
+  bytes2 = []
+
+  str1.each_byte {|b| bytes2 << b }
+
+  assert_equal bytes1, bytes2
+end
+
+assert('String#freeze') do
+  str = "hello"
+  str.freeze
+
+  assert_raise(RuntimeError) { str.upcase! }
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/superclass.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/superclass.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/superclass.rb	(revision 331)
@@ -0,0 +1,46 @@
+[
+  # [:Object, :implementation_defined_value, '15.2.2.1'],
+  [:Module, :Object, '15.2.2.2'],
+  [:Class, :Module, '15.2.3.2'],
+  [:NilClass, :Object, '15.2.4.2'],
+  [:TrueClass, :Object, '15.2.5.2'],
+  [:FalseClass, :Object, '15.2.6.2'],
+  [:Numeric, :Object, '15.2.7.2'],
+  [:Integer, :Numeric, '15.2.8.2'],
+  [:Float, :Numeric, '15.2.9.2'],
+  [:String, :Object, '15.2.10.2'],
+  [:Symbol, :Object, '15.2.11.2'],
+  [:Array, :Object, '15.2.12.2'],
+  [:Hash, :Object, '15.2.13.2'],
+  [:Range, :Object, '15.2.14.2'],
+#  [:Regexp, :Object, '15.2.15.2'],      #No Regexp in mruby core
+#  [:MatchData, :Object, '15.2.16.2'],
+  [:Proc, :Object, '15.2.17.2'],
+#  [:Struct, :Object, '15.2.18.2'],
+#  [:Time, :Object, '15.2.19.2'],
+#  [:IO, :Object, '15.2.20.2'],
+#  [:File, :IO, '15.2.21.2'],
+  [:Exception, :Object, '15.2.22.2'],
+  [:StandardError, :Exception, '15.2.23.2'],
+  [:ArgumentError, :StandardError, '15.2.24.2'],
+  [:LocalJumpError, :StandardError, '15.2.25.2'],
+  [:RangeError, :StandardError, '12.2.26.2'],
+  [:RegexpError, :StandardError, '12.2.27.2'],
+  [:RuntimeError, :StandardError, '12.2.28.2'],
+  [:TypeError, :StandardError, '12.2.29.2'],
+#  [:ZeroDivisionError, :StandardError, '12.2.30.2'],  # No ZeroDivisionError in mruby
+  [:NameError, :StandardError, '15.2.31.2'],
+  [:NoMethodError, :NameError, '15.2.32.2'],
+  [:IndexError, :StandardError, '15.2.33.2'],
+#  [:IOError, :StandardError, '12.2.34.2'],
+#  [:EOFError, :IOError, '12.2.35.2'],
+#  [:SystemCallError, :StandardError, '15.2.36.2'],
+  [:ScriptError, :Exception, '12.2.37.2'],
+  [:SyntaxError, :ScriptError, '12.2.38.2'],
+#  [:LoadError, :ScriptError, '12.2.39,2'],
+].each do |cls, super_cls, iso|
+  assert "Direct superclass of #{cls}", iso do
+    skip "#{cls} isn't defined" unless Object.const_defined? cls
+    assert_equal Object.const_get(super_cls), Object.const_get(cls).superclass
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/symbol.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/symbol.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/symbol.rb	(revision 331)
@@ -0,0 +1,30 @@
+##
+# Symbol ISO Test
+
+assert('Symbol') do
+  assert_equal :"a", :a
+  assert_equal :"a#{1}", :a1
+  assert_equal :'a', :a
+  assert_equal :'a#{1}', :"a\#{1}"
+end
+
+assert('Symbol', '15.2.11') do
+  assert_equal Class, Symbol.class
+end
+
+assert('Symbol#===', '15.2.11.3.1') do
+  assert_true :abc == :abc
+  assert_false :abc == :cba
+end
+
+assert('Symbol#id2name', '15.2.11.3.2') do
+  assert_equal 'abc', :abc.id2name
+end
+
+assert('Symbol#to_s', '15.2.11.3.3') do
+  assert_equal  'abc', :abc.to_s
+end
+
+assert('Symbol#to_sym', '15.2.11.3.4') do
+  assert_equal :abc, :abc.to_sym
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/syntax.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/syntax.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/syntax.rb	(revision 331)
@@ -0,0 +1,468 @@
+assert('__FILE__') do
+  file = __FILE__[-9, 9]
+  assert_equal 'syntax.rb', file
+end
+
+assert('__LINE__') do
+  assert_equal 7, __LINE__
+end
+
+assert('super', '11.3.4') do
+  assert_raise NoMethodError do
+    super
+  end
+
+  class SuperFoo
+    def foo
+      true
+    end
+    def bar(*a)
+      a
+    end
+  end
+  class SuperBar < SuperFoo
+    def foo
+      super
+    end
+    def bar(*a)
+      super(*a)
+    end
+  end
+  bar = SuperBar.new
+
+  assert_true bar.foo
+  assert_equal [1,2,3], bar.bar(1,2,3)
+end
+
+assert('yield', '11.3.5') do
+  assert_raise LocalJumpError do
+    yield
+  end
+  assert_raise LocalJumpError do
+    o = Object.new
+    def o.foo
+      yield
+    end
+    o.foo
+  end
+end
+
+assert('redo in a for loop (#3275)') do
+  sum = 0
+  for i in 1..10
+    sum += i
+    i -= 1
+    if i > 0
+      redo
+    end
+  end
+
+  assert_equal 220, sum
+end
+
+assert('Abbreviated variable assignment', '11.4.2.3.2') do
+  a ||= 1
+  b &&= 1
+  c = 1
+  c += 2
+
+  assert_equal 1, a
+  assert_nil b
+  assert_equal 3, c
+end
+
+assert('case expression', '11.5.2.2.4') do
+  # case-expression-with-expression, one when-clause
+  x = 0
+  case "a"
+  when "a"
+    x = 1
+  end
+  assert_equal 1, x
+
+  # case-expression-with-expression, multiple when-clauses
+  x = 0
+  case "b"
+  when "a"
+    x = 1
+  when "b"
+    x = 2
+  end
+  assert_equal 2, x
+
+  # no matching when-clause
+  x = 0
+  case "c"
+  when "a"
+    x = 1
+  when "b"
+    x = 2
+  end
+  assert_equal 0, x
+
+  # case-expression-with-expression, one when-clause and one else-clause
+  a = 0
+  case "c"
+  when "a"
+    x = 1
+  else
+    x = 3
+  end
+  assert_equal 3, x
+
+  # case-expression-without-expression, one when-clause
+  x = 0
+  case
+  when true
+    x = 1
+  end
+  assert_equal 1, x
+
+  # case-expression-without-expression, multiple when-clauses
+  x = 0
+  case
+  when 0 == 1
+    x = 1
+  when 1 == 1
+    x = 2
+  end
+  assert_equal 2, x
+
+  # case-expression-without-expression, one when-clause and one else-clause
+  x = 0
+  case
+  when 0 == 1
+    x = 1
+  else
+    x = 3
+  end
+  assert_equal 3, x
+
+  # multiple when-arguments
+  x = 0
+  case 4
+  when 1, 3, 5
+    x = 1
+  when 2, 4, 6
+    x = 2
+  end
+  assert_equal 2, x
+
+  # when-argument with splatting argument
+  x = :integer
+  odds  = [ 1, 3, 5, 7, 9 ]
+  evens = [ 2, 4, 6, 8 ]
+  case 5
+  when *odds
+    x = :odd
+  when *evens
+    x = :even
+  end
+  assert_equal :odd, x
+
+  true
+end
+
+assert('Nested const reference') do
+  module Syntax4Const
+    CONST1 = "hello world"
+    class Const2
+      def const1
+        CONST1
+      end
+    end
+  end
+  assert_equal "hello world", Syntax4Const::CONST1
+  assert_equal "hello world", Syntax4Const::Const2.new.const1
+end
+
+assert('Abbreviated variable assignment as returns') do
+  module Syntax4AbbrVarAsgnAsReturns
+    class A
+      def b
+        @c ||= 1
+      end
+    end
+  end
+  assert_equal 1, Syntax4AbbrVarAsgnAsReturns::A.new.b
+end
+
+assert('Splat and multiple assignment') do
+  *a = *[1,2,3]
+  b, *c = *[7,8,9]
+
+  assert_equal [1,2,3], a
+  assert_equal 7, b
+  assert_equal [8,9], c
+
+  (a, b), c = [1,2],3
+  assert_equal [1,2,3], [a,b,c]
+  (a, b), c = 1,2,3
+  assert_equal [1,nil,2], [a,b,c]
+end
+
+assert('Splat and multiple assignment from variable') do
+  a = [1, 2, 3]
+  b, *c = a
+
+  assert_equal 1, b
+  assert_equal [2, 3], c
+end
+
+assert('Splat and multiple assignment from variables') do
+  a = [1, 2, 3]
+  b = [4, 5, 6, 7]
+  c, d, *e, f, g = *a, *b
+
+  assert_equal 1, c
+  assert_equal 2, d
+  assert_equal [3, 4, 5], e
+  assert_equal 6, f
+  assert_equal 7, g
+end
+
+assert('Splat and multiple assignment in for') do
+  a = [1, 2, 3, 4, 5, 6, 7]
+  for b, c, *d, e, f in [a] do
+  end
+
+  assert_equal 1, b
+  assert_equal 2, c
+  assert_equal [3, 4, 5], d
+  assert_equal 6, e
+  assert_equal 7, f
+end
+
+assert('Splat without assignment') do
+  * = [0]
+  a, * = [1, 2]
+  assert_equal 1, a
+end
+
+assert('multiple assignment (rest)') do
+  *a = 0
+  assert_equal [0], a
+end
+
+assert('multiple assignment (rest+post)') do
+  *a, b = 0, 1, 2
+  *c, d = 3
+
+  assert_equal [0, 1], a
+  assert_equal 2, b
+  assert_equal [], c
+  assert_equal 3, d
+end
+
+assert('multiple assignment (nosplat array rhs)') do
+  a, *b = []
+  *c, d = [0]
+  e, *f, g = [1, 2]
+
+  assert_nil a
+  assert_equal [], b
+  assert_equal [], c
+  assert_equal 0, d
+  assert_equal 1, e
+  assert_equal [], f
+  assert_equal 2, g
+end
+
+assert('multiple assignment (empty array rhs #3236, #3239)') do
+  a,b,*c = []; assert_equal [nil, nil, []], [a, b, c]
+  a,b,*c = [1]; assert_equal [1, nil, []], [a, b, c]
+  a,b,*c = [nil]; assert_equal [nil,nil, []], [a, b, c]
+  a,b,*c = [[]]; assert_equal [[], nil, []], [a, b, c]
+end
+
+assert('Return values of case statements') do
+  a = [] << case 1
+  when 3 then 2
+  when 2 then 2
+  when 1 then 2
+  end
+
+  b = [] << case 1
+  when 2 then 2
+  else
+  end
+
+  def fb
+    n = 0
+    Proc.new do
+      n += 1
+      case
+      when n % 15 == 0
+      else n
+      end
+    end
+  end
+
+  assert_equal [2], a
+  assert_equal [nil], b
+  assert_equal 1, fb.call
+end
+
+assert('Return values of if and case statements') do
+  true_clause_value =
+    if true
+      1
+    else
+      case 2
+      when 3
+      end
+      4
+    end
+
+  assert_equal 1, true_clause_value
+end
+
+assert('Return values of no expression case statement') do
+  when_value =
+    case
+    when true
+      1
+    end
+
+  assert_equal 1, when_value
+end
+
+assert('splat object in assignment') do
+  o = Object.new
+  def o.to_a
+    nil
+  end
+  assert_equal [o], (a = *o)
+
+  def o.to_a
+    1
+  end
+  assert_raise(TypeError) { a = *o }
+
+  def o.to_a
+    [2]
+  end
+  assert_equal [2], (a = *o)
+end
+
+assert('splat object in case statement') do
+  o = Object.new
+  def o.to_a
+    nil
+  end
+  a = case o
+  when *o
+    1
+  end
+  assert_equal 1, a
+end
+
+assert('splat in case statement') do
+  values = [3,5,1,7,8]
+  testa = [1,2,7]
+  testb = [5,6]
+  resulta = []
+  resultb = []
+  resultc = []
+  values.each do |value|
+    case value
+    when *testa
+      resulta << value
+    when *testb
+      resultb << value
+    else
+      resultc << value
+    end
+  end
+
+  assert_equal [1,7], resulta
+  assert_equal [5], resultb
+  assert_equal [3,8], resultc
+end
+
+assert('External command execution.') do
+  module Kernel
+    sym = '`'.to_sym
+    alias_method :old_cmd, sym
+
+    results = []
+    define_method(sym) do |str|
+      results.push str
+      str
+    end
+
+    `test` # NOVAL NODE_XSTR
+    `test dynamic #{sym}` # NOVAL NODE_DXSTR
+    assert_equal ['test', 'test dynamic `'], results
+
+    t = `test` # VAL NODE_XSTR
+    assert_equal 'test', t
+    assert_equal ['test', 'test dynamic `', 'test'], results
+
+    t = `test dynamic #{sym}` # VAL NODE_DXSTR
+    assert_equal 'test dynamic `', t
+    assert_equal ['test', 'test dynamic `', 'test', 'test dynamic `'], results
+
+    alias_method sym, :old_cmd
+  end
+  true
+end
+
+assert('parenthesed do-block in cmdarg') do
+  class ParenDoBlockCmdArg
+    def test(block)
+      block.call
+    end
+  end
+  x = ParenDoBlockCmdArg.new
+  result = x.test (Proc.new do :ok; end)
+  assert_equal :ok, result
+end
+
+assert('method definition in cmdarg') do
+  if false
+    bar def foo; self.each do end end
+  end
+  true
+end
+
+assert('optional argument in the rhs default expressions') do
+  class OptArgInRHS
+    def foo
+      "method called"
+    end
+    def t(foo = foo)
+      foo
+    end
+    def t2(foo = foo())
+      foo
+    end
+  end
+  o = OptArgInRHS.new
+  assert_nil(o.t)
+  assert_equal("method called", o.t2)
+end
+
+assert('optional block argument in the rhs default expressions') do
+  assert_nil(Proc.new {|foo = foo| foo}.call)
+end
+
+assert('multiline comments work correctly') do
+=begin
+this is a comment with nothing after begin and end
+=end
+=begin  this is a comment 
+this is a comment with extra after =begin
+=end
+=begin
+this is a comment that has =end with spaces after it
+=end  
+=begin this is a comment
+this is a comment that has extra after =begin and =end with spaces after it
+=end  
+  line = __LINE__
+=begin	this is a comment
+this is a comment that has extra after =begin and =end with tabs after it
+=end	xxxxxxxxxxxxxxxxxxxxxxxxxx
+  assert_equal(line + 4, __LINE__)
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/true.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/true.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/true.rb	(revision 331)
@@ -0,0 +1,31 @@
+##
+# TrueClass ISO Test
+
+assert('TrueClass', '15.2.5') do
+  assert_equal Class, TrueClass.class
+end
+
+assert('TrueClass true', '15.2.5.1') do
+  assert_true true
+  assert_equal TrueClass, true.class
+  assert_false TrueClass.method_defined? :new
+end
+
+assert('TrueClass#&', '15.2.5.3.1') do
+  assert_true true.&(true)
+  assert_false true.&(false)
+end
+
+assert('TrueClass#^', '15.2.5.3.2') do
+  assert_false true.^(true)
+  assert_true true.^(false)
+end
+
+assert('TrueClass#to_s', '15.2.5.3.3') do
+  assert_equal 'true', true.to_s
+end
+
+assert('TrueClass#|', '15.2.5.3.4') do
+  assert_true true.|(true)
+  assert_true true.|(false)
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/typeerror.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/typeerror.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/typeerror.rb	(revision 331)
@@ -0,0 +1,6 @@
+##
+# TypeError ISO Test
+
+assert('TypeError', '15.2.29') do
+  assert_equal Class, TypeError.class
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/test/t/unicode.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/test/t/unicode.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/test/t/unicode.rb	(revision 331)
@@ -0,0 +1,39 @@
+# Test of the \u notation
+
+assert('bare \u notation test') do
+  # Mininum and maximum one byte characters
+  assert_equal("\x00", "\u0000")
+  assert_equal("\x7F", "\u007F")
+
+  # Mininum and maximum two byte characters
+  assert_equal("\xC2\x80", "\u0080")
+  assert_equal("\xDF\xBF", "\u07FF")
+
+  # Mininum and maximum three byte characters
+  assert_equal("\xE0\xA0\x80", "\u0800")
+  assert_equal("\xEF\xBF\xBF", "\uFFFF")
+
+  # Four byte characters require the \U notation
+end
+
+assert('braced \u notation test') do
+  # Mininum and maximum one byte characters
+  assert_equal("\x00", "\u{0000}")
+  assert_equal("\x7F", "\u{007F}")
+
+  # Mininum and maximum two byte characters
+  assert_equal("\xC2\x80", "\u{0080}")
+  assert_equal("\xDF\xBF", "\u{07FF}")
+
+  # Mininum and maximum three byte characters
+  assert_equal("\xE0\xA0\x80", "\u{0800}")
+  assert_equal("\xEF\xBF\xBF", "\u{FFFF}")
+
+  # Mininum and maximum four byte characters
+  assert_equal("\xF0\x90\x80\x80", "\u{10000}")
+  assert_equal("\xF4\x8F\xBF\xBF", "\u{10FFFF}")
+end
+
+assert('braced multiple \u notation test') do
+  assert_equal("ABC", "\u{41 42 43}")
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/travis_config.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/travis_config.rb	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/travis_config.rb	(revision 331)
@@ -0,0 +1,53 @@
+MRuby::Build.new('debug') do |conf|
+  toolchain :gcc
+  enable_debug
+
+  # include all core GEMs
+  conf.gembox 'full-core'
+  conf.cc.flags += %w(-Werror=declaration-after-statement)
+  conf.compilers.each do |c|
+    c.defines += %w(MRB_GC_STRESS MRB_GC_FIXED_ARENA)
+  end
+
+  build_mrbc_exec
+end
+
+MRuby::Build.new('full-debug') do |conf|
+  toolchain :gcc
+  enable_debug
+
+  # include all core GEMs
+  conf.gembox 'full-core'
+  conf.cc.defines = %w(MRB_ENABLE_DEBUG_HOOK)
+
+  conf.enable_test
+end
+
+MRuby::Build.new do |conf|
+  toolchain :gcc
+
+  # include all core GEMs
+  conf.gembox 'full-core'
+  conf.cc.flags += %w(-Werror=declaration-after-statement)
+  conf.compilers.each do |c|
+    c.defines += %w(MRB_GC_FIXED_ARENA)
+  end
+  conf.enable_bintest
+  conf.enable_test
+end
+
+MRuby::Build.new('cxx_abi') do |conf|
+  toolchain :gcc
+
+  conf.gembox 'full-core'
+  conf.cc.flags += %w(-Werror=declaration-after-statement)
+  conf.compilers.each do |c|
+    c.defines += %w(MRB_GC_FIXED_ARENA)
+  end
+  conf.enable_bintest
+  conf.enable_test
+
+  enable_cxx_abi
+
+  build_mrbc_exec
+end
Index: EcnlProtoTool/trunk/musl-1.1.18/.project
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/.project	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/.project	(revision 331)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>musl-1.1.18</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+	</buildSpec>
+	<natures>
+	</natures>
+</projectDescription>
Index: EcnlProtoTool/trunk/musl-1.1.18/COPYRIGHT
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/COPYRIGHT	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/COPYRIGHT	(revision 331)
@@ -0,0 +1,163 @@
+musl as a whole is licensed under the following standard MIT license:
+
+----------------------------------------------------------------------
+Copyright 息 2005-2014 Rich Felker, et al.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+----------------------------------------------------------------------
+
+Authors/contributors include:
+
+Alex Dowad
+Alexander Monakov
+Anthony G. Basile
+Arvid Picciani
+Bobby Bingham
+Boris Brezillon
+Brent Cook
+Chris Spiegel
+Cl辿ment Vasseur
+Daniel Micay
+Denys Vlasenko
+Emil Renner Berthing
+Felix Fietkau
+Felix Janda
+Gianluca Anzolin
+Hauke Mehrtens
+Hiltjo Posthuma
+Isaac Dunham
+Jaydeep Patil
+Jens Gustedt
+Jeremy Huntwork
+Jo-Philipp Wich
+Joakim Sindholt
+John Spencer
+Josiah Worcester
+Justin Cormack
+Khem Raj
+Kylie McClain
+Luca Barbato
+Luka Perkov
+M Farkas-Dyck (Strake)
+Mahesh Bodapati
+Michael Forney
+Natanael Copa
+Nicholas J. Kain
+orc
+Pascal Cuoq
+Petr Hosek
+Pierre Carrier
+Rich Felker
+Richard Pennington
+Shiz
+sin
+Solar Designer
+Stefan Kristiansson
+Szabolcs Nagy
+Timo Ter辰s
+Trutz Behn
+Valentin Ochs
+William Haddon
+
+Portions of this software are derived from third-party works licensed
+under terms compatible with the above MIT license:
+
+The TRE regular expression implementation (src/regex/reg* and
+src/regex/tre*) is Copyright 息 2001-2008 Ville Laurikari and licensed
+under a 2-clause BSD license (license text in the source files). The
+included version has been heavily modified by Rich Felker in 2012, in
+the interests of size, simplicity, and namespace cleanliness.
+
+Much of the math library code (src/math/* and src/complex/*) is
+Copyright 息 1993,2004 Sun Microsystems or
+Copyright 息 2003-2011 David Schultz or
+Copyright 息 2003-2009 Steven G. Kargl or
+Copyright 息 2003-2009 Bruce D. Evans or
+Copyright 息 2008 Stephen L. Moshier
+and labelled as such in comments in the individual source files. All
+have been licensed under extremely permissive terms.
+
+The ARM memcpy code (src/string/arm/memcpy_el.S) is Copyright 息 2008
+The Android Open Source Project and is licensed under a two-clause BSD
+license. It was taken from Bionic libc, used on Android.
+
+The implementation of DES for crypt (src/crypt/crypt_des.c) is
+Copyright 息 1994 David Burren. It is licensed under a BSD license.
+
+The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
+originally written by Solar Designer and placed into the public
+domain. The code also comes with a fallback permissive license for use
+in jurisdictions that may not recognize the public domain.
+
+The smoothsort implementation (src/stdlib/qsort.c) is Copyright 息 2011
+Valentin Ochs and is licensed under an MIT-style license.
+
+The BSD PRNG implementation (src/prng/random.c) and XSI search API
+(src/search/*.c) functions are Copyright 息 2011 Szabolcs Nagy and
+licensed under following terms: "Permission to use, copy, modify,
+and/or distribute this code for any purpose with or without fee is
+hereby granted. There is no warranty."
+
+The x86_64 port was written by Nicholas J. Kain and is licensed under
+the standard MIT terms.
+
+The mips and microblaze ports were originally written by Richard
+Pennington for use in the ellcc project. The original code was adapted
+by Rich Felker for build system and code conventions during upstream
+integration. It is licensed under the standard MIT terms.
+
+The mips64 port was contributed by Imagination Technologies and is
+licensed under the standard MIT terms.
+
+The powerpc port was also originally written by Richard Pennington,
+and later supplemented and integrated by John Spencer. It is licensed
+under the standard MIT terms.
+
+All other files which have no copyright comments are original works
+produced specifically for use as part of this library, written either
+by Rich Felker, the main author of the library, or by one or more
+contibutors listed above. Details on authorship of individual files
+can be found in the git version control history of the project. The
+omission of copyright and license comments in each file is in the
+interest of source tree size.
+
+In addition, permission is hereby granted for all public header files
+(include/* and arch/*/bits/*) and crt files intended to be linked into
+applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
+the copyright notice and permission notice otherwise required by the
+license, and to use these files without any requirement of
+attribution. These files include substantial contributions from:
+
+Bobby Bingham
+John Spencer
+Nicholas J. Kain
+Rich Felker
+Richard Pennington
+Stefan Kristiansson
+Szabolcs Nagy
+
+all of whom have explicitly granted such permission.
+
+This file previously contained text expressing a belief that most of
+the files covered by the above exception were sufficiently trivial not
+to be subject to copyright, resulting in confusion over whether it
+negated the permissions granted in the license. In the spirit of
+permissive licensing, and of not having licensing issues being an
+obstacle to adoption, that text has been removed.
Index: EcnlProtoTool/trunk/musl-1.1.18/INSTALL
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/INSTALL	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/INSTALL	(revision 331)
@@ -0,0 +1,185 @@
+
+Quick Installation Guide for musl libc
+======================================
+
+There are many different ways to install musl depending on your usage
+case. This document covers only the build and installation of musl by
+itself, which is useful for upgrading an existing musl-based system or
+compiler toolchain, or for using the provided musl-gcc wrapper with an
+existing non-musl-based compiler.
+
+Building complete native or cross-compiler toolchains is outside the
+scope of this INSTALL file. More information can be found on the musl
+website and community wiki.
+
+
+Build Prerequisites
+-------------------
+
+The only build-time prerequisites for musl are GNU Make and a
+freestanding C99 compiler toolchain targeting the desired instruction
+set architecture and ABI, with support for a minimal subset of "GNU C"
+extensions consisting mainly of gcc-style inline assembly, weak
+aliases, hidden visibility, and stand-alone assembly source files.
+
+GCC, LLVM/clang, Firm/cparser, and PCC have all successfully built
+musl, but GCC is the most widely used/tested. Recent compiler (and
+binutils) versions should be used if possible since some older
+versions have bugs which affect musl.
+
+The system used to build musl does not need to be Linux-based, nor do
+the Linux kernel headers need to be available.
+
+
+
+Supported Targets
+-----------------
+
+musl can be built for the following CPU instruction set architecture
+and ABI combinations:
+
+* i386
+    * Minimum CPU model is actually 80486 unless kernel emulation of
+      the `cmpxchg` instruction is added
+
+* x86_64
+    * ILP32 ABI (x32) is available as a separate arch but is still
+      experimental
+
+* ARM
+    * EABI, standard or hard-float VFP variant
+    * Little-endian default; big-endian variants also supported
+    * Compiler toolchains only support armv4t and later
+
+* AArch64
+    * Little-endian default; big-endian variants also supported
+
+* MIPS
+    * ABI is o32
+    * Big-endian default; little-endian variants also supported
+    * Default ABI variant uses FPU registers; alternate soft-float ABI
+      that does not use FPU registers or instructions is available
+    * MIPS2 or later, or kernel emulation of ll/sc (standard in Linux)
+      is required
+
+* MIPS64
+    * ABI is n64 (LP64)
+    * Big-endian default; little-endian variants also supported
+    * Default ABI variant uses FPU registers; alternate soft-float ABI
+      that does not use FPU registers or instructions is available
+
+* PowerPC
+    * Compiler toolchain must provide 64-bit long double, not IBM
+      double-double or IEEE quad
+    * For dynamic linking, compiler toolchain must be configured for
+      "secure PLT" variant
+
+* PowerPC64
+    * Both little and big endian variants are supported
+    * Compiler toolchain must provide 64-bit long double, not IBM
+      double-double or IEEE quad
+    * Compiler toolchain must use the new (ELFv2) ABI regardless of
+      whether it is for little or big endian
+
+* S390X (64-bit S390)
+
+* SuperH (SH)
+    * Standard ELF ABI or FDPIC ABI (shared-text without MMU)
+    * Little-endian by default; big-engian variant also supported
+    * Full FPU ABI or soft-float ABI is supported, but the
+      single-precision-only FPU ABI is not
+
+* Microblaze
+    * Big-endian default; little-endian variants also supported
+    * Soft-float
+    * Requires support for lwx/swx instructions
+
+* OpenRISC 1000 (or1k)
+
+
+
+Build and Installation Procedure
+--------------------------------
+
+To build and install musl:
+
+1. Run the provided configure script from the top-level source
+   directory, passing on its command line any desired options.
+
+2. Run "make" to compile.
+
+3. Run "make install" with appropriate privileges to write to the
+   target locations.
+
+The configure script attempts to determine automatically the correct
+target architecture based on the compiler being used. For some
+compilers, this may not be possible. If detection fails or selects the
+wrong architecture, you can provide an explicit selection on the
+configure command line.
+
+By default, configure installs to a prefix of "/usr/local/musl". This
+differs from the behavior of most configure scripts, and is chosen
+specifically to avoid clashing with libraries already present on the
+system. DO NOT set the prefix to "/usr", "/usr/local", or "/" unless
+you're upgrading libc on an existing musl-based system. Doing so will
+break your existing system when you run "make install" and it may be
+difficult to recover.
+
+
+
+Notes on Dynamic Linking
+------------------------
+
+If dynamic linking is enabled, one file needs to be installed outside
+of the installation prefix: /lib/ld-musl-$ARCH.so.1. This is the
+dynamic linker. Its pathname is hard-coded into all dynamic-linked
+programs, so for the sake of being able to share binaries between
+systems, a consistent location should be used everywhere. Note that
+the same applies to glibc and its dynamic linker, which is named
+/lib/ld-linux.so.2 on i386 systems.
+
+If for some reason it is impossible to install the dynamic linker in
+its standard location (for example, if you are installing without root
+privileges), the --syslibdir option to configure can be used to
+provide a different location
+
+At runtime, the dynamic linker needs to know the paths to search for
+shared libraries. You should create a text file named
+/etc/ld-musl-$ARCH.path (where $ARCH matches the architecture name
+used in the dynamic linker) containing a list of directories where you
+want the dynamic linker to search for shared libraries, separated by
+colons or newlines. If the dynamic linker has been installed in a
+non-default location, the path file also needs to reside at that
+location (../etc relative to the chosen syslibdir).
+
+If you do not intend to use dynamic linking, you may disable it by
+passing --disable-shared to configure; this also cuts the build time
+in half.
+
+
+
+Checking for Successful Installation
+------------------------------------
+
+After installing, you should be able to use musl via the musl-gcc
+wrapper. For example:
+
+cat > hello.c <<EOF
+#include <stdio.h>
+int main()
+{
+	printf("hello, world!\n");
+	return 0;
+}
+EOF
+/usr/local/musl/bin/musl-gcc hello.c
+./a.out
+
+To configure autoconf-based program to compile and link against musl,
+set the CC variable to musl-gcc when running configure, as in:
+
+CC=musl-gcc ./configure ...
+
+You will probably also want to use --prefix when building libraries to
+ensure that they are installed under the musl prefix and not in the
+main host system library directories.
Index: EcnlProtoTool/trunk/musl-1.1.18/Makefile
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/Makefile	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/Makefile	(revision 331)
@@ -0,0 +1,255 @@
+#
+# Makefile for musl (requires GNU make)
+#
+# This is how simple every makefile should be...
+# No, I take that back - actually most should be less than half this size.
+#
+# Use config.mak to override any of the following variables.
+# Do not make changes here.
+#
+
+srcdir = .
+exec_prefix = /usr/local
+bindir = $(exec_prefix)/bin
+
+prefix = /usr/local/musl
+includedir = $(prefix)/include
+libdir = $(prefix)/lib
+syslibdir = /lib
+
+SRC_DIRS = $(addprefix $(srcdir)/,src/* crt ldso)
+BASE_GLOBS = $(addsuffix /*.c,$(SRC_DIRS))
+ARCH_GLOBS = $(addsuffix /$(ARCH)/*.[csS],$(SRC_DIRS))
+BASE_SRCS = $(sort $(wildcard $(BASE_GLOBS)))
+ARCH_SRCS = $(sort $(wildcard $(ARCH_GLOBS)))
+BASE_OBJS = $(patsubst $(srcdir)/%,%.o,$(basename $(BASE_SRCS)))
+ARCH_OBJS = $(patsubst $(srcdir)/%,%.o,$(basename $(ARCH_SRCS)))
+REPLACED_OBJS = $(sort $(subst /$(ARCH)/,/,$(ARCH_OBJS)))
+ALL_OBJS = $(addprefix obj/, $(filter-out $(REPLACED_OBJS), $(sort $(BASE_OBJS) $(ARCH_OBJS))))
+
+LIBC_OBJS = $(filter obj/src/%,$(ALL_OBJS))
+LDSO_OBJS = $(filter obj/ldso/%,$(ALL_OBJS:%.o=%.lo))
+CRT_OBJS = $(filter obj/crt/%,$(ALL_OBJS))
+
+AOBJS = $(LIBC_OBJS)
+LOBJS = $(LIBC_OBJS:.o=.lo)
+GENH = obj/include/bits/alltypes.h obj/include/bits/syscall.h
+GENH_INT = obj/src/internal/version.h
+IMPH = $(addprefix $(srcdir)/, src/internal/stdio_impl.h src/internal/pthread_impl.h src/internal/locale_impl.h src/internal/libc.h)
+
+LDFLAGS =
+LDFLAGS_AUTO =
+LIBCC = -lgcc
+CPPFLAGS =
+CFLAGS =
+CFLAGS_AUTO = -Os -pipe
+CFLAGS_C99FSE = -std=c99 -ffreestanding -nostdinc 
+
+CFLAGS_ALL = $(CFLAGS_C99FSE)
+CFLAGS_ALL += -D_XOPEN_SOURCE=700 -I$(srcdir)/arch/$(ARCH) -I$(srcdir)/arch/generic -Iobj/src/internal -I$(srcdir)/src/internal -Iobj/include -I$(srcdir)/include
+CFLAGS_ALL += $(CPPFLAGS) $(CFLAGS_AUTO) $(CFLAGS)
+
+LDFLAGS_ALL = $(LDFLAGS_AUTO) $(LDFLAGS)
+
+AR      = $(CROSS_COMPILE)ar
+RANLIB  = $(CROSS_COMPILE)ranlib
+INSTALL = $(srcdir)/tools/install.sh
+
+ARCH_INCLUDES = $(wildcard $(srcdir)/arch/$(ARCH)/bits/*.h)
+GENERIC_INCLUDES = $(wildcard $(srcdir)/arch/generic/bits/*.h)
+INCLUDES = $(wildcard $(srcdir)/include/*.h $(srcdir)/include/*/*.h)
+ALL_INCLUDES = $(sort $(INCLUDES:$(srcdir)/%=%) $(GENH:obj/%=%) $(ARCH_INCLUDES:$(srcdir)/arch/$(ARCH)/%=include/%) $(GENERIC_INCLUDES:$(srcdir)/arch/generic/%=include/%))
+
+EMPTY_LIB_NAMES = m rt pthread crypt util xnet resolv dl
+EMPTY_LIBS = $(EMPTY_LIB_NAMES:%=lib/lib%.a)
+CRT_LIBS = $(addprefix lib/,$(notdir $(CRT_OBJS)))
+STATIC_LIBS = lib/libc.a lib/libce.a
+SHARED_LIBS = lib/libc.so
+TOOL_LIBS = lib/musl-gcc.specs
+ALL_LIBS = $(CRT_LIBS) $(STATIC_LIBS) $(SHARED_LIBS) $(EMPTY_LIBS) $(TOOL_LIBS)
+ALL_TOOLS = obj/musl-gcc
+
+WRAPCC_GCC = gcc
+WRAPCC_CLANG = clang
+
+LDSO_PATHNAME = $(syslibdir)/ld-musl-$(ARCH)$(SUBARCH).so.1
+
+-include config.mak
+
+ifeq ($(ARCH),)
+
+all:
+	@echo "Please set ARCH in config.mak before running make."
+	@exit 1
+
+else
+
+all: $(ALL_LIBS) $(ALL_TOOLS)
+
+OBJ_DIRS = $(sort $(patsubst %/,%,$(dir $(ALL_LIBS) $(ALL_TOOLS) $(ALL_OBJS) $(GENH) $(GENH_INT))) obj/include)
+
+$(ALL_LIBS) $(ALL_TOOLS) $(ALL_OBJS) $(ALL_OBJS:%.o=%.lo) $(GENH) $(GENH_INT): | $(OBJ_DIRS)
+
+$(OBJ_DIRS):
+	mkdir -p $@
+
+obj/include/bits/alltypes.h: $(srcdir)/arch/$(ARCH)/bits/alltypes.h.in $(srcdir)/include/alltypes.h.in $(srcdir)/tools/mkalltypes.sed
+	sed -f $(srcdir)/tools/mkalltypes.sed $(srcdir)/arch/$(ARCH)/bits/alltypes.h.in $(srcdir)/include/alltypes.h.in > $@
+
+obj/include/bits/syscall.h: $(srcdir)/arch/$(ARCH)/bits/syscall.h.in
+	cp $< $@
+	sed -n -e s/__NR_/SYS_/p < $< >> $@
+
+obj/src/internal/version.h: $(wildcard $(srcdir)/VERSION $(srcdir)/.git)
+	printf '#define VERSION "%s"\n' "$$(cd $(srcdir); sh tools/version.sh)" > $@
+
+obj/src/internal/version.o obj/src/internal/version.lo: obj/src/internal/version.h
+
+obj/crt/rcrt1.o obj/ldso/dlstart.lo obj/ldso/dynlink.lo: $(srcdir)/src/internal/dynlink.h $(srcdir)/arch/$(ARCH)/reloc.h
+
+obj/crt/crt1.o obj/crt/scrt1.o obj/crt/rcrt1.o obj/ldso/dlstart.lo: $(srcdir)/arch/$(ARCH)/crt_arch.h
+
+obj/crt/rcrt1.o: $(srcdir)/ldso/dlstart.c
+
+obj/crt/Scrt1.o obj/crt/rcrt1.o: CFLAGS_ALL += -fPIC
+
+obj/crt/$(ARCH)/crti.o: $(srcdir)/crt/$(ARCH)/crti.s
+
+obj/crt/$(ARCH)/crtn.o: $(srcdir)/crt/$(ARCH)/crtn.s
+
+OPTIMIZE_SRCS = $(wildcard $(OPTIMIZE_GLOBS:%=$(srcdir)/src/%))
+$(OPTIMIZE_SRCS:$(srcdir)/%.c=obj/%.o) $(OPTIMIZE_SRCS:$(srcdir)/%.c=obj/%.lo): CFLAGS += -O3
+
+MEMOPS_SRCS = src/string/memcpy.c src/string/memmove.c src/string/memcmp.c src/string/memset.c
+$(MEMOPS_SRCS:%.c=obj/%.o) $(MEMOPS_SRCS:%.c=obj/%.lo): CFLAGS_ALL += $(CFLAGS_MEMOPS)
+
+NOSSP_SRCS = $(wildcard crt/*.c) \
+	src/env/__libc_start_main.c src/env/__init_tls.c \
+	src/env/__stack_chk_fail.c \
+	src/thread/__set_thread_area.c src/thread/$(ARCH)/__set_thread_area.c \
+	src/string/memset.c src/string/$(ARCH)/memset.c \
+	src/string/memcpy.c src/string/$(ARCH)/memcpy.c \
+	ldso/dlstart.c ldso/dynlink.c
+$(NOSSP_SRCS:%.c=obj/%.o) $(NOSSP_SRCS:%.c=obj/%.lo): CFLAGS_ALL += $(CFLAGS_NOSSP)
+
+$(CRT_OBJS): CFLAGS_ALL += -DCRT
+
+$(LOBJS) $(LDSO_OBJS): CFLAGS_ALL += -fPIC
+
+CC_CMD = $(CC) $(CFLAGS_ALL) -c -o $@ $<
+
+# Choose invocation of assembler to be used
+ifeq ($(ADD_CFI),yes)
+	AS_CMD = LC_ALL=C awk -f $(srcdir)/tools/add-cfi.common.awk -f $(srcdir)/tools/add-cfi.$(ARCH).awk $< | $(CC) $(CFLAGS_ALL) -x assembler -c -o $@ -
+else
+	AS_CMD = $(CC_CMD)
+endif
+
+obj/%.o: $(srcdir)/%.s
+	$(AS_CMD)
+
+obj/%.o: $(srcdir)/%.S
+	$(CC_CMD)
+
+obj/%.o: $(srcdir)/%.c $(GENH) $(IMPH)
+	$(CC_CMD)
+
+obj/%.lo: $(srcdir)/%.s
+	$(AS_CMD)
+
+obj/%.lo: $(srcdir)/%.S
+	$(CC_CMD)
+
+obj/%.lo: $(srcdir)/%.c $(GENH) $(IMPH)
+	$(CC_CMD)
+
+lib/libc.so: $(LOBJS) $(LDSO_OBJS)
+	$(CC) $(CFLAGS_ALL) $(LDFLAGS_ALL) -nostdlib -shared \
+	-Wl,-e,_dlstart -o $@ $(LOBJS) $(LDSO_OBJS) $(LIBCC)
+
+lib/libc.a: $(AOBJS)
+	rm -f $@
+	$(AR) rc $@
+	@for obj in $(filter-out $(TCC_EXTRACT),$(AOBJS)); do (\
+		echo $(AR) q $@ $$obj;\
+		$(AR) q $@ $$obj; )\
+	done
+	$(RANLIB) $@
+
+lib/libce.a: $(TCC_EXTRACT)
+	rm -f $@
+	$(AR) rc $@
+	@for obj in $(TCC_EXTRACT); do (\
+		echo $(AR) q $@ $$obj;\
+		$(AR) q $@ $$obj; )\
+	done
+	$(RANLIB) $@
+
+$(EMPTY_LIBS):
+	rm -f $@
+	$(AR) rc $@
+
+lib/%.o: obj/crt/$(ARCH)/%.o
+	cp $< $@
+
+lib/%.o: obj/crt/%.o
+	cp $< $@
+
+lib/musl-gcc.specs: $(srcdir)/tools/musl-gcc.specs.sh config.mak
+	sh $< "$(includedir)" "$(libdir)" "$(LDSO_PATHNAME)" > $@
+
+obj/musl-gcc: config.mak
+	printf '#!/bin/sh\nexec "$${REALGCC:-$(WRAPCC_GCC)}" "$$@" -specs "%s/musl-gcc.specs"\n' "$(libdir)" > $@
+	chmod +x $@
+
+obj/%-clang: $(srcdir)/tools/%-clang.in config.mak
+	sed -e 's!@CC@!$(WRAPCC_CLANG)!g' -e 's!@PREFIX@!$(prefix)!g' -e 's!@INCDIR@!$(includedir)!g' -e 's!@LIBDIR@!$(libdir)!g' -e 's!@LDSO@!$(LDSO_PATHNAME)!g' $< > $@
+	chmod +x $@
+
+$(DESTDIR)$(bindir)/%: obj/%
+	$(INSTALL) -D $< $@
+
+$(DESTDIR)$(libdir)/%.so: lib/%.so
+	$(INSTALL) -D -m 755 $< $@
+
+$(DESTDIR)$(libdir)/%: lib/%
+	$(INSTALL) -D -m 644 $< $@
+
+$(DESTDIR)$(includedir)/bits/%: $(srcdir)/arch/$(ARCH)/bits/%
+	$(INSTALL) -D -m 644 $< $@
+
+$(DESTDIR)$(includedir)/bits/%: $(srcdir)/arch/generic/bits/%
+	$(INSTALL) -D -m 644 $< $@
+
+$(DESTDIR)$(includedir)/bits/%: obj/include/bits/%
+	$(INSTALL) -D -m 644 $< $@
+
+$(DESTDIR)$(includedir)/%: $(srcdir)/include/%
+	$(INSTALL) -D -m 644 $< $@
+
+$(DESTDIR)$(LDSO_PATHNAME): $(DESTDIR)$(libdir)/libc.so
+	$(INSTALL) -D -l $(libdir)/libc.so $@ || true
+
+install-libs: $(ALL_LIBS:lib/%=$(DESTDIR)$(libdir)/%) $(if $(SHARED_LIBS),$(DESTDIR)$(LDSO_PATHNAME),)
+
+install-headers: $(ALL_INCLUDES:include/%=$(DESTDIR)$(includedir)/%)
+
+install-tools: $(ALL_TOOLS:obj/%=$(DESTDIR)$(bindir)/%)
+
+install: install-libs install-headers install-tools
+
+musl-git-%.tar.gz: .git
+	 git --git-dir=$(srcdir)/.git archive --format=tar.gz --prefix=$(patsubst %.tar.gz,%,$@)/ -o $@ $(patsubst musl-git-%.tar.gz,%,$@)
+
+musl-%.tar.gz: .git
+	 git --git-dir=$(srcdir)/.git archive --format=tar.gz --prefix=$(patsubst %.tar.gz,%,$@)/ -o $@ v$(patsubst musl-%.tar.gz,%,$@)
+
+endif
+
+clean:
+	rm -rf obj lib
+
+distclean: clean
+	rm -f config.mak
+
+.PHONY: all clean install install-libs install-headers install-tools
Index: EcnlProtoTool/trunk/musl-1.1.18/README
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/README	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/README	(revision 331)
@@ -0,0 +1,23 @@
+
+    musl libc
+
+musl, pronounced like the word "mussel", is an MIT-licensed
+implementation of the standard C library targetting the Linux syscall
+API, suitable for use in a wide range of deployment environments. musl
+offers efficient static and dynamic linking support, lightweight code
+and low runtime overhead, strong fail-safe guarantees under correct
+usage, and correctness in the sense of standards conformance and
+safety. musl is built on the principle that these goals are best
+achieved through simple code that is easy to understand and maintain.
+
+The 1.1 release series for musl features coverage for all interfaces
+defined in ISO C99 and POSIX 2008 base, along with a number of
+non-standardized interfaces for compatibility with Linux, BSD, and
+glibc functionality.
+
+For basic installation instructions, see the included INSTALL file.
+Information on full musl-targeted compiler toolchains, system
+bootstrapping, and Linux distributions built on musl can be found on
+the project website:
+
+    http://www.musl-libc.org/
Index: EcnlProtoTool/trunk/musl-1.1.18/VERSION
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/VERSION	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/VERSION	(revision 331)
@@ -0,0 +1,1 @@
+1.1.18
Index: EcnlProtoTool/trunk/musl-1.1.18/WHATSNEW
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/WHATSNEW	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/WHATSNEW	(revision 331)
@@ -0,0 +1,1864 @@
+0.5.0 - initial release
+
+
+
+0.5.9 - signal ABI bugfix, various cleanup and fixes:
+
+sigset_t was wrongly defined as 1024 bytes instead of 1024 bits,
+breaking the intended ABI compatibility with the LSB/glibc sigaction
+structure. users should upgrade immediately and rebuild any libraries
+or object files that might be using the incorrect definitions.
+
+improved security against DoS with tcb shadow passwords by checking
+that the file opened was really an ordinary file.
+
+fixed a bug in the implementation of atomic ops that could have
+allowed the compiler to incorrectly reorder them (in practice, gcc
+with the default settings on i386 was not reordering them).
+
+greatly improved conformance to the C and POSIX standards regarding
+what the standard header files make visible. _POSIX_C_SOURCE is now
+needed to get POSIX functions in standard C headers, and _XOPEN_SOURCE
+or _GNU_SOURCE are required to get XSI interfaces or GNU extensions,
+respectively.
+
+many internal improvements have been made to the syscall-related code
+in preparation for porting to x86_64 and other archs.
+
+
+
+0.6.0 - x86_64 port, various important bugs fixed
+
+new x86_64 (amd64) architecture port, contributed by Nicholas J. Kain,
+along with PORTING guide. source tree layout and build system have
+been improved to accommodate further ports.
+
+various bugs that were introduced while making the headers respect C
+and POSIX namespace standards have been fixed. conformance to the
+standards has been improved.
+
+fixed an inefficiency in qsort that triggered a bug (occasionaly
+internal compiler error) in some versions of gcc.
+
+fixed a major bug in the printf %n specifier that prevented it from
+working and caused memory corruption.
+
+
+
+0.7.0 - major improvements to posix conformance and completeness
+
+implemented posix shared memory and semaphore interfaces.
+
+implemented all remaining required pthread and clock interfaces.
+
+major fixes to signal semantics.
+
+greatly improved temporary file name generation for safety against
+denial of service due to intentional name collisions.
+
+added syscall wrappers for the linux inotify interface.
+
+malloc(0) now returns a non-null pointer.
+
+fixed printf %n specifier (again), pthread_once (it was always
+hanging), and non-default-type mutex behavior.
+
+added ucontext/sigcontext support in headers to facilitate building
+libgcc with dwarf2 unwind support, and possibly other low-level tools.
+
+improved musl-gcc compiler wrapper.
+
+implemented many small missing functions here and there, minor header
+fixes, etc.
+
+
+
+0.7.1 - improvements to completeness, bug fixes
+
+implemented flockfile, wprintf, and robust mutex functions.
+
+fixed stack corruption bug in times(), minor header bugs, and some
+error return value bugs in thread interfaces.
+
+
+
+0.7.5 - new features, major optimization, and robustness
+
+implemented POSIX timers.
+
+optimized and simplified many thread-related functions.
+
+eliminated resource leak races in thread cancellation. (almost all
+existing implementations, including glibc, have these leaks.)
+
+overhauled stdio implementation to take advantage of readv/writev for
+reduced syscall load, and improved stdio's handling of error status.
+
+added syscall header and interface for applications to use and
+greatly simplified internal system for making syscalls.
+
+strangthened tmpnam/tempnam/tmpfile filename generation and made the
+straight C functions not depend on POSIX symbols.
+
+fixed pthread cancellation ABI on i386 to match the LSB/glibc ABI
+
+better double-free handling in malloc
+
+various minor bug fixes
+
+
+
+0.7.6 - major bug fixes
+
+fixed rare but serious under-allocation bug in malloc.
+
+fixed signedness bug in strchr that prevented finding high bytes.
+
+fixed serious parsing bugs in strtold.
+
+fixed statvfs syscall (it was always failing with EINVAL).
+
+fixed race condition in set*id() functions with threads (possible
+deadlock). further audit still needed though.
+
+fseek no longer sets the stream error flag on failed seeks (this was
+wrong and broke some programs, notably GNU m4).
+
+nl_langinfo is no longer a dummy function. (the functionality was
+previously implemented but accidentally left unused).
+
+various small fixes have been made to the implementations and
+prototypes for nonstandard and obsolete functions
+
+
+
+0.7.7 - more bug fixes and program-compatibility improvements
+
+fixed floating point formatting and rounding bugs in printf.
+
+fixed broken %N$ positional argument specifiers in printf.
+
+fixed misaligned read/overread bug in strchr which could lead to
+crashes scanning tiny strings at the end of a page when the next page
+is not readable, or on archs (not yet supported) that forbid
+misaligned reads.
+
+fixed breakage of statvfs on x86_64
+
+fixed crash in getmntent_r
+
+fixed bug in POSIX timers created with NULL sigevent argument
+
+improved semaphore performance, and sem_wait is now interruptable by
+signals, as required by POSIX.
+
+added many compatibility and system-level interfaces, increasing the
+proportion of busybox that works with musl.
+
+
+
+0.7.8 - more bug fixes and compatibility improvements
+
+fixed problems with ipv6 dns and address printing code that made ipv6
+support practically unusable, and some other getaddrinfo bugs.
+
+fixed broken sendmsg/recvmsg functions on x86_64 (caused by incorrect
+msghdr structure).
+
+fixed broken sigsetjmp asm on x86_64.
+
+worked around a problem with input buffering on terminals reblocking
+after getting a blank line, due to a bug in the linux readv syscall.
+
+various improvements to the "rsyscall" system used to implement
+threaded setuid, setgid, etc.
+
+exiting/cancelling the a timer handler thread no longer kills the
+timer.
+
+fixed incorrect trailing zeros on some %g conversions in printf.
+
+fixed buggy byte-swapping functions and moved them to inlines in
+byteswap.h.
+
+many small improvements to header/application compatibility, support
+for nonstandard macros, etc.
+
+
+
+0.7.9 release notes
+
+new pthread cancellation implementation:
+- safe against resource-leak/side-effect-leak race conditions
+- safe against interruption by signal handlers
+- reduced bloat in all cancellable functions
+- reduced bloat for blocking cancellation
+
+new interfaces implemented:
+- realpath (limited functionality)
+- wordexp (limited functionality)
+- flock (nonstandard)
+- forkpty (nonstandard)
+- posix_fadvise
+- posix_fallocate
+
+general bug fixes:
+- syslog function failure to communicate with syslogd
+- bug in siginfo_t definition if wait.h was included before signal.h
+- incorrect struct definitions for most of sysv ipc
+- pthread_exit/cancel on timer handler wrongly destroying the timer
+- linux dup2 ebusy workaround
+- obscure issues in non-threaded programs using some pthread functions
+- getopt_long allowed mismatch in last char of option name
+- incorrect parsing of obscure ip address forms
+- initgroups not working reliably (uninitialized var)
+- shadow pass treating empty expiry field as pass-expired-in-1970
+- bogus longjmp if pthread_exit was called from cancellation handlers
+
+x86_64-specific bug fixes:
+- fcntl file locking
+- thread stack alignment
+- broken select timeouts due to incorrect timeval definition
+
+
+
+0.7.10 release notes
+
+new features:
+- ipv6 numeric string parsing
+- eventfd syscall wrappers
+
+optimizations:
+- new qsort implementation using the smoothsort algorithm
+- much smaller/faster sigset_t handling functions
+- lowered spin count before futex wait in synchronization functions
+
+general bug fixes:
+- incorrect floating point round-to-even behavior in printf
+- major bugs in pthread barrier implementation
+- off-by-one error in scanf %n results
+- scanf failure to report EOF when scanning for literal text
+- minor missing/incorrect prototype issues
+- dependency on undefined call order in fclose
+
+compiler issue workarounds:
+- incorrect inlining of variadic functions on recent gcc versions
+- pcc preprocessor bug with recursive macro expansion
+
+
+
+0.7.11 release notes
+
+new features:
+- integrated dynamic linker
+- dynamic loading (dlopen/dlsym) (for dynamic-linked programs only)
+- XSI search.h API
+- POSIX message queues
+- POSIX spawn interfaces
+- BSD pseudo-random number generator API (random/srandom/initstate/etc.)
+- floating point environment (limited usefulness due to gcc bugs)
+
+general bug fixes:
+- possible crashes with wordexp due to uninitialized variable
+- race condition in pthread_kill (also present and unfixed in glibc/nptl)
+- pthread exit destructors called too late
+- dangerous unbounded vla in glob
+- brk/sbrk legacy functions mismatching legacy semantics
+- wcsncpy dest buffer overflow
+- strncat and wcsncat possible overflows due to double-termination
+
+
+
+0.7.12 release notes
+
+new features:
+- support for textrels in shared objects
+- rpath support in dynamic linker
+- stdio_ext.h functions (for better gnu software compatibility)
+
+bug fixes:
+- some compilers miscompiling dlopen due to misuse of longjmp
+- safe handling of invalid long-double bit patterns (affects printf)
+- workaround for bugs in linux mprotect syscall
+- thread-safety for random() functions
+- various minor issues
+
+
+
+0.8.0 release notes
+
+new features:
+- chinese and japanese legacy charset support in iconv
+- zero-syscall clock_gettime support (dynamic-linked x86_64 only)
+- futex-based locking for stdio (previously used spinlocks)
+- LD_PRELOAD and RTLD_NEXT support in dynamic linker
+- strptime (mostly working but incomplete)
+- posix aio (mostly working but not entirely conformant)
+- memory streams (fmemopen, open_memstream, ...)
+- stub/dummy implementations for various useless legacy functions
+- if_nameindex
+
+security hardening:
+- setuid, etc. should not longer be able to "partially fail" with threads
+- ensure suid programs start with fd 0,1,2 open
+- improved openpty/forkpty failure checks
+
+threads/synchronization bug fixes:
+- dangerous spurious wakeup in pthread_join lead to early return
+- race condition enabling async cancellation (delayed/lost cancellation)
+- destruction/unmapping race conditions in semaphores, mutexes, rwlocks
+- recursive rwlock_rdlock deadlock when a writer is waiting
+- race condition in sigqueue with fork
+- timer expiration thread exit wasn't running dtors
+- timer threads weren't blocking signals
+- close was wrongly cancellable after succeeding on some devices
+- robust mutex list was not reset on fork
+
+general bug fixes:
+- incorrect logic in fread (spurious blocking; crash on write-only files)
+- many corner cases and overflow cases for strtol-family functions
+- various printf integer formatting issues with flags/width/precision
+- incorrect iconv return value on failure
+- broken FD_* macros on 64-bit targets
+- clock function returning wrong value (real time not cpu time)
+- siglongjmp signal mask clobbering (off-by-one pointer error)
+- dynamic linker weak symbol resolution issues
+- fdopendir failure to set errno
+- various minor header fixes
+
+
+
+0.8.1 release notes
+
+bug fixes:
+- mismatching prototypes caused build failure on 64-bit
+- other minor prototype errors in the headers have been fixed
+- various other small omissions fixed
+
+
+
+0.8.2 release notes
+
+new features:
+- ptrace syscall support
+
+bug fixes:
+- const error (only a warning with many compilers) in lio_listio
+- minor portability fixes aimed at supporting new arch targets
+
+
+
+0.8.3 release notes
+
+new features:
+- arm port (experimental)
+- better musl-gcc wrapper script for building against musl
+- added clone system call
+
+bug fixes:
+- numerous header file typos, copy/paste errors, omissions
+- statfs and statvfs ABI are now LSB-conformant (and actually work)
+
+
+
+0.8.4 release notes
+
+new features: 
+- arm dynamic linker support
+- process-shared pthread barriers now work
+- efficient futex-requeue-based cond var broadcast
+- more optional cancellation points are now cancellable
+- printf accepts null pointers with %s, prints as "(null)"
+- recursive mutexes are now fully reentrant
+- __cxa_atexit support
+- real vfork
+- dynamic linker now gold-compatible
+- prlimit syscall
+- support for large limits with setrlimit/getrlimit (even on 32-bit)
+- glob now supports GLOB_PERIOD option (GNU extension)
+
+bug fixes:
+- many serious issues in condition variables
+- rwlock failure-to-wake deadlock issues
+- various small header files bugs/omissions
+- wrong failure return for pthread_create
+- path handling issues on execvp
+- lock count corruption with robust recursive mutexes on owner death
+- integer overflows in atoi, etc. reading most-negative value
+- spurious mremaps on every realloc of large memory chunks
+- pthread cancellation failure in single-threaded programs
+
+security:
+- avoid fd_set overflow in dns lookups
+
+
+
+0.8.5 release notes
+
+new features:
+- stdio operations are now cancellable (only when low-level io happens)
+- global ctor/dtor support in main program start code and shared libs
+- dynamic linker support for PIE executables (but missing startup code)
+- vfork support on x86_64
+- complete set of locale_t functions (all ignore the locale argument)
+- provide define float_t and double_t in math.h
+- lighter/faster cancellation cleanup handler register/unregister
+
+bug fixes:
+- gcc wrapper now supports -shared, -nostdlib, -nostartfiles
+- removed one wrongly-classified character from iswspace set (zwsp)
+- fixed crashes in dns lookup on some errors, e.g. resolv.conf missing
+- "make install" no longer tries to build shared libc if disabled
+- ptrace argument handling bugs fixed
+- work around visibility-hidden bugs in gcc 3.x
+- fix thread-pointer-loss issue when it's initialized in signal handlers
+- various minor typo/misc fixes in headers
+
+compatibility:
+- glob behaves more like traditional implementations w.r.t. GLOB_MARK
+- added legacy futimes, lutimes functions
+- more compatibility macros in sys/param.h (nonstandard header)
+- setfs[ug]id syscall wrappers (linux specific)
+- fgetpwent function (nonstandard)
+- utmp.h matches traditional version more closely
+- caddr_t now matches glibc type (void * instead of long)
+- dummy (always-fail) dlopen and dlsym functions for static linked programs
+- [efg]cvt functions (previously posix, removed from standard)
+- get_current_dir_name function (nonstandard)
+
+
+
+0.8.6 release notes
+
+bug fixes:
+- fix crash in dns lookups for all static-linked, non-threaded programs
+
+
+
+0.8.7 release notes
+
+new features:
+- c++ support with g++'s libstdc++
+- c99 math library (float, long double, complex, etc.)
+- numerous wchar_t functions
+- a64l, l64a functions
+- getdate function
+
+compatibility:
+- c89 compatibility in math.h
+- syscall.h alias for sys/syscall.h
+- memory.h alias for string.h
+- getcwd supports null buffer argument (auto-allocation)
+
+bug fixes:
+- major fenv (floating point environment) fixes and optimizations
+- strptime mishandling of day/month names
+- strtoull wrongly rejecting the highest 16 possible values as overflow
+- math.h constant expression fixes for INFINITY/NAN/etc.
+- scanf mishandling of "0" with "%x"
+
+
+
+0.8.8 release notes
+
+new feature:
+- major math correctness and performance improvements
+- many math functions implemented in asm for i386
+- some math functions (mostly long double) in asm for x86_64
+- new floating point parser/converter with correct rounding
+- implement wcstod, wcstof, and wcstold
+- new scanf implementation - cleaner, faster, more correct
+- minimal/incomplete strfmon implementation
+
+compatibility:
+- header fixes for c++
+- regex code resync with TRE; support common regex extensions
+- support for compiling apps with gcc's -funsigned-char
+- sysconf now returns dynamic limits for open files, processes
+- give dlerror proper error status stickiness
+- make alloca work even with -fno-builtin
+
+critical security fixes:
+- stack-based buffer overflow in fprintf on unbuffered files
+
+other bug fixes:
+- rare gcc register allocation (miscompilation) bug in syscall wrappers
+- printf was rejecting the valid (but redundant) %lf format specifier
+- fixed big data bloat (missing const) in math functions
+- many math fixes related to floating point exceptions and rounding
+- corrected DECIMAL_DIG definitions
+- tgammal was wrongly setting global signgam
+- crash in wordfree with uninitialized we_offs
+- fix wordexp not null-initializing the we_offs initial slots
+
+
+
+0.8.9 release notes
+
+bug fixes:
+- major breakage in strtol and family: failure to accept leading spaces
+- incorrect name for MATH_ERREXCEPT in math.h
+
+compatibility:
+- prototypes for a few additional nonstandard functions
+
+
+
+0.8.10 release notes
+
+new features:
+- correct over/underflow detection (ERANGE setting) for strtod
+- new musl-gcc wrapper, specfile based, faster and more robust
+- meaningful return strings for dlerror
+- new iswalpha, iswpunct, and wcwidth; sync'd to Unicode 6.1
+- towupper/towlower sync'd with Unicode 6.1
+- new futex-based libc-internal locks instead of spinlocks
+- experimental stack protector support (minimal; no random canary)
+- experimental gdb shared library tracking support
+
+compatibility:
+- getusershell family functions
+- getresuid and getresgid syscall wrappers
+- byte swapping macros in endian.h
+- getdtablesize was wrongly declared in unistd.h for _XOPEN_SOURCE
+
+bug fixes:
+- iconv_open wrongly rejecting most dest charsets (broken in 0.8.0)
+- sysconf failure when correct value is -1 (broken in 0.8.8)
+- scanf and strtod family functions overreading past NAN (4 bytes vs 3)
+- scanf and strtod wrongly treating "0.00000000001", etc. as 0
+- many bugs in towupper/towlower (never seriously tested before)
+- int8_t definition was wrong when gcc -funsigned-char was used
+
+
+
+0.9.0 release notes
+
+license change: MIT
+
+new features:
+- configure script, improved build system
+- full stack protector support
+- PIE support on x86 and x86_64
+- new O(1) space, O(nm) time implementation of fnmatch
+- improved support for sse2 floating point mode on x86
+
+compatibility:
+- added linux unshare syscall
+- exp10/pow10 function
+- sqrtl support on arm (previously missing)
+- removed minimal linux/*.h headers that could conflict with real ones
+- support for _LARGEFILE64_SOURCE (mapped to standard fcns with #define)
+- better c89 compatibility in headers
+- stub versions of sched_* functions (previously missing)
+- pthread stacks no longer executable (compat with hardened kernels)
+- new ar.h and lastlog.h (legacy junk)
+- various other header improvements
+
+optimization:
+- additional x86_64 math asm
+- better formula for acos use in i386 asm
+
+bug fixes:
+- large (up to a few %) errors in strtod for certain values due to bug
+- mbsnrtowcs and wcsnrtombs were completely broken (bad exit logic)
+- wide printf %.0s could fail due to uninitialized variable
+- missing dlerror strings for dlsym in some cases
+
+
+
+0.9.1 release notes
+
+new features:
+- dynamic linker can be used as a program to explicitly load/run executables
+- ldd command, usable by making a symlink to the dynamic linker named ldd
+
+bug fixes:
+- major bugs in POSIX BRE parsing inherited from TRE regex code
+- character matching bug in regex on ARM: WCHAR_MAX was assumed to be signed
+- various obscure fixes related to signals and pthread cancellation
+- remquot subnormal remainder bug
+- buggy macros in (nonstandard) sys/param.h
+- major bug in pthread barriers on x86_64 (out of bounds write)
+- utimes (legacy) function was making wrong syscall (utime instead of utimes)
+- avoid using "old" syscalls that don't exist on arm eabi linux
+- broken strrchr(str, 0)
+- broken mbsinit(0)
+- broken wcsncmp
+- syntax error in nextafter macro in tgmath.h
+- missing support for -pie in musl-gcc wrapper
+- abort could wrongly fail to terminate the program in some cases
+
+compatibility:
+- increase default thread stack size to 80k
+- support _BSD_SOURCE feature test macro
+- support _LARGEFILE64_SOURCE feature test macro (merely exposes alt names)
+- lots of legacy-compatibility improvements in headers
+- various minor GNU extension functions
+- sysconf reporting number of available CPUs/cores
+- various LSB/glibc ABI interfaces aimed at compatibility with some binaries
+- use fistpll asm mnemonic instead of fistpq for compat with clang
+
+
+
+0.9.2 release notes
+
+bug fixes:
+- pointer overflow in printf (crash on 32bit userspace, 64bit kernel)
+- printf %ls over-read bug
+- strtod failure to read -0x as negative zero
+- flush stdio after dtors, not before
+- wrong file position for buffered input streams on exit
+- popen was broken when stdin/out were already closed
+- broken wcwidth tables (missing many characters)
+- fwrite: wrong return value of partial/failed write
+- broken utf-16 conversions
+- bad buffer length check in getlogin_r
+- bad perror("") behavior; did not match perror(0)
+- broken sysinfo syscall/structure
+- stdint.h const macro signedness bugs
+- broken include guards in some headers
+- bogus localeconv values
+- cancellation-safety for popen and pclose
+- fma corner cases wrong on i386
+- fcntl F_GETOWN errno missing on failure.
+- char signedness bug in dynamic linker broke dlopen on arm
+- mprotect failure in dynamic linker caused crash instead of error
+
+build system:
+- configure check to work around hacked-up gcc versions
+- test for old binutils that can't support musl dynamic linker
+
+compatibility:
+- make _GNU_SOURCE imply _LARGEFILE64_SOURCE
+- syscall wrapper for lots of nonstandard and/or legacy linux syscalls
+- versionsort stub
+- timegm function (inverse of gmtime)
+- various minor header tweaks
+- make __freading/__fwriting semantics match traditional ones
+- added gnulib-compatibility stdio interfaces
+- added pthread_attr_setstack interface
+- make strerror_r return partial string when buffer is too small
+- duplocale should accept LC_GLOBAL_LOCALE
+- align ptsname_r to upcoming posix requirements
+- support invalid ld80 bit patterns as extra nans.
+
+
+
+0.9.3 release notes
+
+new features:
+- mips (32-bit, o32 abi) port, currently static-linked only
+- newly overhauled crypt implementation
+- improved library pathname info for debugger from the dynamic linker
+- getaddrinfo (and getservbyname) now support /etc/services lookups
+- pipe2 syscall wrapper
+- splice and vmsplice syscall wrappers
+- syscall wrappers for extended attribute interfaces
+- ioperm/iopl syscall wrappers on archs that support these operations
+
+bug fixes:
+- dlsym RTLD_NEXT library search order was wrong
+- multiple dlopen pathname and library name handling errors
+- potential race condition in detached thread exit
+- broken internal-lock-handling code not updated for futex-based __lock
+- sem_trywait spurious EAGAIN errors arising from CAS failures
+- workaround kernel bug in cmsghdr size_t vs socklen_t issue (64-bit)
+- getservby* crash on null protocol argument
+- logic error skipping failed interfaces in if_nameindex
+- various minor header/declaration related issues
+
+arm-specific bug fixes:
+- broken crti/crtn startup code when gcc crtbegin/end files are linked
+- sigsetjmp tail call optimization failure broke the function
+- incorrect little-endian assumptions in atomic.h functions
+- use of blx instruction in asm (not supported on pre-v5 arm)
+
+build system:
+- only use expensive -ffloat-store cflag on archs/compilers that need it
+- make musl-gcc wrapper support -lgcc (mainly for self-hosting)
+
+
+
+0.9.4 release notes
+
+new features:
+- blowfish crypt
+- dynamic linking on mips
+- arm hard float support
+- BSD fgetln function in stdio
+- minor header improvements for compatibility
+- support for CROSS_COMPILE variable to configure
+- legacy significand function
+- better support for SUSv3-targeted programs
+
+performance:
+- assembly (string ops based) memcpy for i386 and x86_64
+- reduce printf overhead
+
+bug fixes:
+- failure of strtod, etc. to process extremely long strings correctly
+- read overrun in wcsstr for short needles
+- various major mips issues that prevented most software from working
+- erroneous floating point exception behavior in i386/x86_64 exp asm
+- crashes on null arguments to legacy err.h functions
+- various header file/type issues
+- extremely rare/obscure race condition with robust mutexes
+- crypt now never returns null (most programs don't check, then crash)
+- missing xattr remove functions
+
+
+
+0.9.5 release notes
+
+compatibility and headers:
+- POSIX+XSI+BSD features enabled by default with no macros defined
+- most programs can now be built without adding -D_GNU_SOURCE
+- added C99 restrict keyword where required in all prototypes
+- greater C89 compatibility
+- cleaner, more-compatible public syscall.h
+- many other header fixes
+- support for compiling musl with clang/llvm
+
+new features:
+- sha 256/512 password hash functions in crypt
+- GNU hash support in dynamic linker
+- partial C11 coverage
+- dladdr function added
+- dynamic linker reports all errors instead of exiting on first error
+- syscall wrappers added for most remaining linux syscalls
+- provide POSIX O_SEARCH open mode using linux O_PATH
+
+bug fixes:
+- most atexit functions were being skipped when exiting
+- some BSD functions were not being exposed under _BSD_SOURCE
+- issues loading ssp-protected DSO into non-ssp program with dlopen
+
+debloating:
+- eliminate .eh_frame (10-15% loaded size bloat)
+- optimal inline syscall asm for ARM and MIPS
+- no longer force -O3 for shared libs
+
+
+
+0.9.6 release notes
+
+bug fixes:
+- serious breakage in definition of O_ACCMODE mask (missing a bit)
+
+new features:
+- O_EXEC open mode
+- md5 crypt hash function
+
+
+
+0.9.7 release notes
+
+new features:
+- thread-local storage (__thread/_Thread_local)
+- microblaze port
+- getopt option parsing reset support
+- vsyscall (sysenter, etc.) support on i386 (faster syscalls)
+- memmem function (GNU extension)
+- mips fenv support
+- accept "nan(n-char-sequence)" in strtod/scanf family functions
+- configure now supports compiling with pcc
+
+quality and correctness improvements:
+- close-on-exec flag for all library-internal file descriptors
+- cancellation-safety and corner-case overhaul in shm_open/sem_open
+- close EINTR vs EINPROGRESS issue
+- mark binaries as not requiring executable stack
+- better gdb compatibility in dynamic linker
+- support recursive dlopen (dlopen called from constructors)
+- posix_spawn/system/popen no longer momentarily double commit charge
+- all stdio functions wait for locks
+
+bug fixes:
+- broken sysvipc *ctl functions on 64-bit archs
+- broken shmdt on some archs
+- getaddrinfo failure with port "0"
+- dirname handling of trailing slash
+- vfork race in posix_spawn
+
+
+
+0.9.8 release notes
+
+new features:
+- powerpc port
+- dl_iterate_phdr interface
+- added mips-specific syscalls
+- thread priority scheduling
+- C11 CMPLX macro in complex.h
+- x86 port io functions in sys/io.h
+
+compatibility:
+- improved headers for trace/debugging/machine-access
+- stub functions for unsupported thread-related functionality
+
+bug fixes:
+- numerous math bugs (mostly exception flags and excess-precision issues)
+- register clobber error in i386 vsyscall asm (did not affect most callers)
+- various incorrect definitions in mips headers
+- broken dlsym asm on mips
+- empty prefix handling in configure script (--prefix="")
+- ldso search path logic issues
+- lock handling for stdio memory streams at exit time
+- invalid SO_REUSEPORT definition in socket.h (not supported by Linux)
+- broken redirection attempt to /dev/null in configure script
+
+
+
+0.9.9 release notes
+
+new features:
+- tgamma implementation (no longer lgamma wrapper with low precision)
+- various gnu extensions: sigandset, sigorset, etc.
+- futimesat function (obsolete)
+- various linux syscalls: arch_prctl, personality, etc.
+
+optimizations:
+- hyperbolic, inverse hyperbolic, and inverse trig, bessel functions
+- is* comparison macros in math.h now expand inline properly
+
+library bugs fixed:
+- calling getenv from shared library ctors was broken
+- invalid read in mmap-serviced aligned_alloc/memalign (possible crash)
+- wrong errno result in fallback path of pipe2 
+- various math functions raising spurious exceptions
+- mmap errno value on invalid offsets
+- backwards alignment logic in strlcpy
+- integer overflows in bessel functions
+- large (up to 60ulp) error in erfcf
+- dlsym/dlclose crashing on invalid library handles
+- failure to handle arch variations for cloexec/nonblock flags
+- lio_listio wrong return value for LIO_WAIT mode
+- dladdr failure to resolve PLT addresses
+- time_t/struct tm conversion off-by-one-day in december
+- malloc corruption on nonstandard kernels with non-page-aligned brk
+
+arch-specific bugs fixed:
+- arm ctors/dtors were not working with recent gcc versions
+- arm and mips setjmp/longjmp wrongly saved/restored fenv state
+- loss of precision in i386/x86_64 expl
+
+header bugs fixed:
+- incorrect PRI/SCN macros in inttypes.h for some types
+- arm sys/user.h regressions
+- failure of offsetof() to be an integer constant expression
+- tgmath return value type problems
+
+header compatibility improvements:
+- _GNU_SOURCE now enables everything; _ALL_SOURCE also works
+- scsi/scsi.h and scsi/sg.h are now provided
+- additional MAP_* flags for mmap
+- additional F_* commands and flags for fcntl
+- additional socket option, IPPROTO_* values, and multicase macros
+- thread-related waitpid flags
+- EHWPOISON added to errno.h
+- additional macros for mount, swap, and reboot operations
+- expose additional link.h structures
+- always ensure sizeof(NULL)==sizeof(void *), even in c++
+- additional flags for poll, epoll, inotify, timerfd, timex, dlfcn
+- register names in signal.h/ucontext.h for x86
+- ipc.h ipc_perm nonstandard struct field name compatibility improve
+
+
+
+0.9.10 release notes
+
+new features:
+- getifaddrs 
+- pthread_getattr_np (widely used by garbage collectors)
+- mkostemps, mkostemp, mkstemps functions (mkostemp is future-POSIX)
+- strcasestr and strverscmp (previously stubs)
+
+improvements:
+- major performance improvements in mbtowc
+- avoid filling caller-provided thread stacks with large TLS
+- debloat unnecessary static buffers
+- robust posix_spawn based on CLONE_VM instead of vfork
+- new system() and popen() based on posix_spawn
+- better strerror strings
+- further emulation of atomic close-on-exec/nonblock options for old kernels
+- provide macro constants for new-ish kernel features
+
+compatibility:
+- several nonstandard but widely-available pwd/grp/shadow functions
+- program_invocation_[short_]name
+- re-added useconds_t type used by some programs
+- some legacy arpa headers
+- dn_skipname function (legacy resolver API)
+- additional ABI aliases for supporting glibc-linked libraries/binaries
+
+general bugs fixed:
+- stale locks and bogus munmap call when pthread_create fails
+- uninitialized argument to munmap when dynlink load_library fails
+- incorrect error returns in gethostby*_r
+- memory leak in gethostbyname family
+- blank ai_canonname in getaddrinfo for non-CNAME records
+- undefined HZ macro in scsi/sg.h
+- wrong return value for wmemmove on forward-copy
+- namespace conformance in strings.h
+- various utmp.h bugs
+- unnecessary DT_SONAME in libc.so caused problems on some systems
+- multiple bugs in syslog, some possibly dangerous
+- non-functional setpriority function
+- slight mishandling of 0xf5 byte in UTF-8 decoder
+- misaligned memory accesses in mbsrtowcs
+
+arch-specific bugs fixed:
+- crash in shared library loading on arm
+- missing __aeabi_atexit needed by arm eabi
+- wrong float_t definition on x86_64
+- various low-impact type size/alignment mismatches in some headers
+- epoll struct alignment wrong on non-x86[_64] archs
+- broken pipe2 fallback code on mips with old kernels
+
+
+
+0.9.11 release notes
+
+new features:
+- %m allocation modifier for scanf
+- week number and ISO week-based-year functionality in strftime
+- per-process and per-thread cputime clocks
+- ethernet address conversion interfaces
+- legacy classful ipv4 network address interfaces
+- minimal dlinfo function (nonstandard)
+
+other improvements:
+- dynamic linker path file can now use newlines to separate paths
+- math optimizations for archs with extended precision (i386)
+- musl-gcc wrapper now exposes gcc's intrinsic headers
+- quality of rand and rand_r pseudo-random sequences
+- support for large device minor numbers (greater than 8 bits)
+- various header conformance and compatibility fixes
+
+directly user-visible bugs fixed:
+- scanf losing characters on unbuffered streams and fmemopen streams
+- failure of mbsrtowcs to record stop position when dest is full
+- failure of iconv to convert to legacy codepages
+- non-working pthread_[sg]etschedparam functions (wrong syscall arguments)
+
+other potentially-serious bugs fixed:
+- resource leaks in sem_open
+- various bugs in thread exit synchronization
+- invalid access in aio notification after aiocb free/reuse
+- synchronization in dynamic linker when new thread dlopens during ctors
+- lack of error handling for failure to read dynamic linker path file
+- creation by mmap or shmget of objects larger than PTRDIFF_MAX
+
+minor conformance bugs fixed:
+- overflow handling for the clock function
+- workaround for incorrect exceptions in fma due to compiler bugs
+- workaround wrong kernel type for sem_nsems field in struct semid_ds
+
+arch-specific bugs fixed:
+- x86_64 sigsetjmp clobbered the signal mask rather than saving it
+- misaligned stack when calling ctors/dtors (crashing on x86_64)
+
+
+
+0.9.12 release notes
+
+new features:
+- zoneinfo time zone support
+- PIE support on all supported archs
+- named sub-archs for endian and float ABI variants
+- improved support for non-root installs of the dynamic linker
+- ability to selectively build only performance-critical modules with -O3
+- simple buffer overflow detection in free/realloc
+- inet_ntop now presents v4-mapped addresses in ::ffff:a.b.c.d form
+- ldd now reports libc and the dynamic linker in its output
+
+compatibility:
+- support for new init/fini array (needed for ctors/dtors on newer gcc)
+- C++ ABI fully matches glibc/LSB, at least on x86
+- many added ABI compatibility symbols for using glibc-linked libs
+- support for STB_GNU_UNIQUE symbol bindings (found in some C++ libs)
+- macros/types for new Linux kernel features in headers
+
+bugs fixed:
+- crashes in scanf on literal mismatches (regression from adding %m)
+- dl_iterate_phdr was passing invalid phdr pointers to its callback
+- getaddrinfo with null host and AF_UNSPEC was failing to report IPv6
+- integer overflows in date/time conversion code
+- misinterpretation of pre-1930s dates as post-2038 on 32-bit archs
+- make install failed to install bits headers if make was not run first
+- shm_open was wrongly cancellable
+- low- or no-impact heap corruption in memalign
+- explicitly running the dynamic linker on PIE programs did not work
+- missing macros and sysconf for some supported POSIX option groups
+- missing close-on-exec flags for several internal fd uses
+
+arch-specific bugs:
+- wrong SIG_ATOMIC_MIN/MAX macros on x86_64
+- erfcl was missing on archs where long double is same as double
+- broken dynamic-model TLS in static-linked arm/mips/powerpc programs
+
+
+
+0.9.13 release notes
+
+new features:
+- iconv support for EUC-KR and Big5 (including HKSCS) encodings
+- field widths (POSIX 2008 feature) in strftime
+- recursive rpath and $ORIGIN support in dynamic linker
+- cpu affinity interfaces
+- support for armhf (hardfloat) floating point environment (fenv)
+- support for SSE fenv on i386 (for apps using -mfpmath=sse -msse2)
+- strftime %s format (seconds since the epoch, future POSIX requirement)
+- configure script now saves its command line as a comment in config.mak
+- legacy functions valloc and euidaccess
+
+performance:
+- optimized asm memcpy for arm
+- optimized asm memset for i386 and x86_64
+- optimized C versions of memcpy and memset for all archs
+- eliminated major spurious syscalls from posix_spawn
+- some math asm for armhf (hardfloat)
+
+workarounds for:
+- qemu-user's rt_sigaction syscall does not allow old to alias new
+- qemu-user's madvise always succeeds (broke pthread_getattr_np)
+- passing PT_INTERP to dlopen attempted to double-load libc
+- gcc 4.8.x generating self-referential (infinite recursion) memcpy/memset
+- linux's lack of support for fchdir, fchmod, fchown, fstat on O_PATH fds
+
+bugs fixed:
+- failure to honor flags for fchmodat and faccessat (linux syscall api flaws)
+- SIGEV_THREAD timer id corruption and race condition issues
+- timer thread TLS incorrectly keeping values from previous expiry run
+- ecvt/fcvt decimal position off-by-one
+- in symbol-versioned libs, symbol resolved to oldest instead of newest
+- posix_spawn not correctly reporting errno from exec failure
+- "make install" was not atomic (overwrote files rather than replacing)
+- integer overflows in strftime
+- unset/empty TZ variable was mishandled
+- strftime could crash if the struct tm did not have valid tm_zone field
+- failure of fenv functions to handle invalid arguments (required by ISO C)
+- failure of some math functions (C and i386 asm) to raise underflow flag
+- broken dn_expand function (previously not used internally)
+- race conditions with signals during fork
+- incorrect access check in mktemp (obsolete function)
+- unnecessary arbitrary limits on size of program headers in dynamic loader
+- text formatting bugs in output of err.h functions
+
+arch-specific bugs:
+- fesetenv(FE_DFL_ENV) crashed on i386
+- breakage of arm crt code when libc is compiled as thumb
+- arm/armhf (hardfloat) misidentified by configure
+- ambiguity of wait (exit status) macros on mips with signal number 127
+- wrong value of _NSIG and SIGRTMAX on mips
+
+
+
+0.9.14 release notes
+
+bugs fixed:
+- failure to properly install dynamic linker with DESTDIR set (symlink wrong)
+- rare deadlock in libc-internal locking routines
+- dynamic linker used fallback paths wrongly on (possibly transient) errors
+- popen broken when stdin or stdout was already closed in parent
+- deadlock/memory-corruption in multithreaded set*id and setrlimit functions
+- realpath failed when file was not readable
+- readpath mistakenly had cancellation points in it
+- crashes in scanf with invalid %m conversion specifiers
+- misclassificiation of some invalid ld80 float representation in fpclassify
+- various overflow and underflow flag issues in math functions
+- domain handling errors for acoshf and acoshl
+- wrong values for some sysconf properties
+- lack of proper memory barriers on arm
+
+mips-specific bugs:
+- broken sysv ipc structures
+- multiple stack-related bugs in clone, leading to crashes in parent or child
+- overflow writing sigset_t in multithreaded set*id and setrlimit functions
+
+other improvements:
+- size and performance improvements to various math functions
+- wait.h as a compatibility alias for sys/wait.h
+- various header improvements
+- support for runtime-variable page size on archs that need it (mainly mips)
+
+
+
+0.9.15 release notes
+
+new features:
+- support for mixing IPv4 and v6 nameserver addresses in resolv.conf
+- RFC 3678 multicast structures/macros in netinet/in.h
+- putspent and fgetspent functions (shadow password API)
+- timef function (obsolete, removed in POSIX 2008)
+- fanotify syscalls (Linux-specific feature)
+- semtimedop syscall (Linux-specific sysvipc extension)
+- quotactl syscall and header (filesystem quotas support)
+- drem and finite functions (obsolete BSD functions)
+- getloadavg function (non-standard)
+- herror function (non-standard and obsolete)
+- libc.so now stores and prints its version information
+- expose constants for new Linux features including O_TMPFILE
+- implement FNM_LEADING_DIR option to fnmatch (GNU extension)
+- posix_close function (accepted for inclusion in next POSIX issue)
+
+bugs fixed:
+- buffer overflow in mbsrtowcs
+- clobbering of gr_name in getgrnam_r and getgrgid_r
+- execle ignoring the environment argument
+- setenv crash on malloc failure
+- out-of-bounds access in fnmatch with FNM_PATHNAME and certain patterns
+- failure of malloc to set errno when failing to extend heap
+- incorrect errno value from getcwd with zero size
+- spurious failure in faccessat with AT_EACCESS flag with suid/sgid programs
+- several fd leaks due to missing close-on-exec flag
+- misspellings/typos in macro names in several headers
+- incorrect failure return value in inet_pton
+- various numeric ip address parsing and validation fixes
+- namespace conformance issues in several headers
+- minor header issues
+- zombie processes left by faccessat with AT_EACCESS
+- timezone file parser failing/crashing on 64-bit archs
+- hang in localtime with near-overflowing time_t values on 64-bit archs
+- timezone path search was only trying first path
+- incorrect handling of excessive-length TZ environment strings
+- timezone file loading was wrongly enforcing O_NOFOLLOW/rejecting symlinks
+- iswspace was wrongly returning true for the null character
+- various bugs in wordexp
+- putgrent could write corrupt lines after write failures
+- dn_expand misinterpreted in-packet offsets greater than 255
+- spurious strftime/wcsftime failure on len+1==bufsize case
+- incorrect underflow flag in fma corner cases
+- log*(0) wrongly returned +inf in downward-rounding mode
+- failure of fchmod, fstat, fchdir, and fchown to produce EBADF
+
+arch-specific bugs fixed:
+- i386: failure of fesetround to set sse rounding mode
+- i386: floating point limit constants misinterpreted due to excess precision
+- powerpc: broken thread pointer access when compiled with clang
+- microblaze: dynamic linker entry point code possibly clobbering argv
+
+strict conformance issues:
+- NULL definition re-aligned with POSIX (requires (void *) cast)
+- alignment of math.h is* comparison functions with C11 annex F requirements
+
+
+
+1.0.0 release notes
+
+new features:
+- support for mips softfloat ABI variant
+- legacy setkey and encrypt API for DES
+- support for BSD version of struct tcphdr in addition to GNU version
+- added ipv6 and icmpv6 protocol lookups to getprotoent-family functions
+
+new experimental ports:
+- sh (SuperH)
+- x32 (ILP32 ABI for x86_64)
+
+compatibility:
+- improved c89 compiler support in math.h
+- eliminate some compiler warnings in public headers
+- added some missing things for LFS64 APIs
+- added fallback emulation of accept4 for older kernels
+
+bugs fixed:
+- buffer overflow in printf when printing smallest denormal exactly
+- rounding errors in printf in some just-over-halfway cases
+- posix_spawn did not accept null pid pointer (crashed)
+- ftello gave incorrect result for unflushed append-mode streams
+- mishandling of n=0 case in wcsxfrm (wild buffer overrun)
+- possible system breakage during libc upgrade due to install.sh bugs
+- nftw FTW_MOUNT flag prevented walking any directories at all
+- ptsname/ptsname_r returned negated error codes
+- getprotoent function returned junk after listing valid protocols
+- wrong error code from readdir when the directory has been deleted
+- various prototype/argument-type fixes, mostly to legacy functions
+- various header namespace violations
+
+arch-specific bugs fixed:
+- fesetenv(FE_DFL_ENV) was broken on i386 and x86_64
+- strerror(EDQUOT) did not work on mips
+- recvmsg/sendmsg were broken on powerpc
+- sysv ipc was broken on powerpc and mips
+- statfs/statvfs were broken on mips
+- sigaltstack was broken on mips
+
+
+
+1.1.0 release notes
+
+new features:
+- relro memory protection in dynamic linker
+- malloc can now extend heap with mmap if brk fails
+- vdso clock_gettime/gettimeofday/time acceleration on x86_64
+- thread/library-safe versions of search.h functions (nonstandard)
+- getauxval function (nonstandard)
+- sysconf extensions to query physical memory size
+
+bugs fixed:
+- floating point printf output corruption from carry into uninitialized slot
+- possible runaway carry overflow in printf floating point
+- printf %g failure to strip trailing zeros in some cases
+- search past end of haystack in memmem
+- off-by-one error in confstr return value
+- crashes in some near-empty static programs that use stack protector
+- deadlock race in pthread_once
+- non-working clock_gettime fallback for old kernels
+
+arch-specific bugs fixed:
+- crash from missing syscall asm register clobbers on real microblaze kernel
+- crash in all nontrivial dynamic linker use on microblaze
+- incorrect rlimit constants on mips
+- broken, possibly dangerous, use of getrlimit syscall on x32 in sysconf
+
+
+
+1.1.1 release notes
+
+new features:
+- new options --preload and --library-path to dynamic linker
+- public execvpe function (nonstandard extension)
+- iconv support for cp437 and cp850
+
+bugs fixed:
+- false negatives with some periodic needles in strstr, wcsstr, and memmem
+- crash on invalid zoneinfo files
+- incorrect zero-padding of some outputs for strftime %s specifier
+- misreporting of errors in configure script when $CC does not work at all
+- treating not-yet-implemented strptime specifiers as errors
+
+compatibility:
+- configure now detects serious constant-folding bug in gcc 4.9.0
+- removed __yield symbol (unused) that clashed with some compilers
+- improvements to sysconf's handling of unsupported/invalid arguments
+
+arch-specific bugs fixed:
+- misdetection of superh ABI variant by configure on gcc 3.x
+- missing SO_RCVBUFFORCE and SO_SNDBUFFORCE in mips socket.h
+- build regression on armv6 and later with -mthumb
+
+
+
+1.1.2 release notes
+
+new features:
+- multi-protocol matches (tcp and udp) in getaddrinfo
+- support for AI_V4MAPPED and AI_ALL flags to getaddrinfo
+- reverse name lookups from /etc/hosts
+- reverse service lookups from /etc/services
+- support for service aliases in /etc/services
+- ipsec and tunneling protocols to getprotoent-family functions
+- res_send, res_mkquery, res_querydomain, and dn_comp functions
+- ipv6 scope id handling for link-local scope addresses
+- previously-unimplemented %C and %y in strptime now work
+- vdso clock_gettime acceleration on i386 (new kernel feature)
+- better O_CLOEXEC/SOCK_CLOEXEC fallbacks for old kernels
+
+bugs fixed:
+- buffer overflow in dns response parsing (CVE-2014-3484)
+- possible infinite loop in dns response parsing
+- sendfile off_t 32/64-bit size mismatch
+- incorrect end pointer in some cases when wcsrtombs stops early
+- incorrect if_nametoindex return value when interface does not exist
+- dummy "ent" function aliases that possibly shadowed real ones
+- tmpfile fd leak on memory exhaustion
+- getaddrinfo returning EAI_NONAME for some transient failures
+
+arch-specific bugs fixed:
+- broken kernel side RLIM_INFINITY on mips
+- incorrect syscall argument 6/7 types for pselect on x32
+
+
+
+1.1.3 release notes
+
+new features:
+- address sorting in getaddrinfo, etc. modeled on rfc 3484/6724
+- default timezone taken from /etc/localtime when $TZ is unset
+- getopt double-colon extension for optional arguments
+- support for TLSDESC-based (gnu2) TLS dialect on i386 and x86_64
+- sendmmsg/recvmmsg (linux-specific)
+- fmtmsg (last mandatory XSI function that was missing)
+
+compatibility:
+- treat dns rcode=2 as temporary failure, not negative result
+- working thread-pointer for pre-2.6 kernels on i386
+- further ABI-compat symbols: __xmknod[at], __sysv_signal
+
+bugs fixed:
+- memmem false positives/false negatives/crashes from invalid logic
+- gethostby*_r not setting result pointer to null on failure
+- aliasing violations in syscall.h SYSLOG_NAMES feature
+- fanotify_mark syscall arguments wrong
+
+arch-specific bugs fixed:
+- various subtle relocation bugs in powerpc and sh dynamic linker
+
+
+
+1.1.4 release notes
+
+new features:
+- experimental locale support for LC_MESSAGES and LC_TIME
+- non-stub gettext family functions for message translation
+- or1k (OpenRISC 1000) port
+- syslog options LOG_CONS and LOG_PERROR
+- issetugid function (from OpenBSD)
+- improved if_nameindex and getifaddrs functions
+
+compatibility:
+- work around bug #61144 in gcc 4.9.0 and 4.9.1
+- support getauxval(AT_SECURE) even on kernels without AT_SECURE
+
+bugs fixed:
+- empty dynamic linker error messages (regression in 1.1.3)
+- if_nameindex omitted unconfigured and ipv6-only interfaces
+- incorrect return value for fwide function
+- failure of wide printf/scanf functions to set wide orientation
+- multiple issues in legacy function getpass
+- dynamic linker did not accept colon as a separator for LD_PRELOAD
+- errno clobber in syslog caused wrong output for %m specifier
+- crash in regexec for nonzero nmatch argument with REG_NOSUB
+- minor bugs in rarely-used nl_langinfo item lookups
+
+arch-specific bugs fixed:
+- broken relocations in mips dynamic linker (regression in 1.1.3)
+- register state corruption in setjmp asm for microblaze
+- broken struct stat st_ino field on microblaze
+- broken struct stat st_dev field on big endian mips
+- broken asm register constraints in atomics on powerpc
+- missing barriers in atomics on mips, powerpc, microblaze, and sh
+
+
+
+1.1.5 release notes
+
+new features:
+- full C11 coverage (threads, UTF-16/32 API, timespec_get, etc.)
+- malloc_usable_size function (nonstandard)
+- support for new F_OFD_* fcntl operations (linux 3.15, POSIX-future)
+- new _DEFAULT_SOURCE feature test macro to request default profile
+
+performance:
+- private-futex support
+- redesigned cond var implementation with major performance improvement
+- tweaked spinning in userspace before performing futex waits
+
+bugs fixed:
+- failure of dn_expand to null-terminate name for crafted DNS packets
+- corruption of cond var mutex state when switching mutexes
+- use of uninitialized memory with application-provided thread stacks
+- false ownership of orphaned mutexes due to tid reuse
+- possible failure-to-wake for robust mutexes on owner death
+- subtle errors in robust mutex unrecoverable status handling
+- missing memory/compiler barrier spinning to obtain locks
+- wrong behavior in various zero-length stdio operations
+- buffer overflow in swab with odd argument
+- incorrect sequence generation in the rand48 family of prng functions
+- missing cancellation check in non-wait paths of sem_wait, pthread_join
+- missing barrier in pthread_once fast path
+- memory leak in regexec when input contains illegal sequence
+- various parser bugs in regcomp
+- wrong return value on overflow in some strtoul-family functions
+- broken CPU_EQUAL macro in sched.h
+- dlerror not working in static-linked programs
+- mishandling of negative non-whole-hour TZ offsets
+- incorrect case mappings for U+00DF
+- namespace pollution via accidentally-non-static function named "dummy"
+- missing __fpclassifyl and __signbitl definitions for ld64 archs
+
+
+
+1.1.6 release notes
+
+new features:
+- getopt '-' flag for processing non-option arguments
+- getopt_long argument permutation extension
+- getopt_long abbreviated options
+- ns_parserr and related DNS-packet-parsing functions
+- fnmatch FNM_CASEFOLD extension
+- support for translation of getopt error messages
+- login_tty function (legacy)
+
+performance:
+- efficient atomics on armv7+ targets
+- pthread_once shrink-wrapping of fast path
+
+compatibility:
+- baseline arm binaries now work on new cpus/kernels without kuser_helper
+- dynamic linker now honors DT_RUNPATH without DT_RPATH (new binutils)
+- arm asm is now compatible with clang's internal assembler
+- suppress macro implementations of functions when headers are used in C++
+- increased message length limit for syslog
+
+bugs fixed:
+- open ignored file creation mode argument for O_TMPFILE
+- wrong printf formatting for %#.0o with value zero
+- missing private state for uchar.h functions (null ps pointer)
+- sched_getaffinity left uninitialized data in output bit array
+- wrong return values for pthread_getaffinity_np and pthread_setaffinity_np
+- buggy handling of multibyte option chars with arguments in getopt
+- printf failed to report or stop on write errors
+- printf failed to honor '+' modifier when printing NANs
+- wcsnrtombs returned the wrong value in one code path
+- syslog failed to check for connect error
+- multi-threaded set*id() had spurious failures from ugly workaround code
+- various minor header conformance bugs (signedness, constant expressions, ...)
+
+arch-specific bugs fixed:
+- on or1k, some syscalls with 64-bit arguments were broken (misaligned)
+- usage of sahf instruction on x86_64 crashed on some early cpu models
+
+
+
+1.1.7 release notes
+
+new features:
+- alternate passwd/group backend support via nscd protocol
+- masked cancellation mode extension (experimental)
+- aio cancellation
+- aarch64 port (experimental)
+
+performance:
+- significant memset asm optimizations on i386 and x86_64
+
+compatibility:
+- suppress EINTR in semaphores for old kernels where futex restart is broken
+- always set optarg in getopt_long
+- support SOCK_RAW socket type in getaddrinfo
+- report success instead of EINPROGRESS when close is interrupted
+
+bugs fixed:
+- multithreaded set*id() was not async-signal safe, had various race bugs
+- getspnam_r returned results for partial username matches
+- wordexp bad character checker mis-counted parentheses
+- close on fd with pending aio could lead to file corruption
+- old aio implementation had numerous conformance bugs
+- malloc init code could deadlock due to race condition
+- pthread_exit did not disable cancellation
+- pthread_cond_wait could wrongly consume signal on cancellation
+- execvp wrongly stopped path search on EACCESS
+- fsync, fdatasync, and msync were not honored as cancellation points
+- fchmodat was subject to fd leak race (missing O_CLOEXEC)
+- fchmodat failed to report EOPNOTSUPP in race path
+- passwd/group lookup functions had various minor error-reporting bugs
+- isatty had false-positives/device-state-corruption for OSS sound devices
+- configure script failed to detect gcc with translated messages
+- FLT_ROUNDS macro failed to reflect rounding mode changes in fenv
+
+arch-specific bugs fixed:
+- mips fesetenv did not handle FE_DFL_ENV
+- mips POLLWRNORM and POLLWRBAND macros had wrong values
+- x32 pthread synchronization object type definitions were wrong
+- powerpc minimum signal stack size was insufficient
+
+
+
+1.1.8 release notes
+
+bugs fixed:
+- stack-based buffer overflow in inet_pton (CVE-2015-1817)
+- regcomp crash/mem-corruption with illegal bytes after backslash
+- regcomp wrongly allowed backrefs in ER
+- regcomp miscompiled character class brace-repetitions
+- regcomp wrongly processed \0 as an unmatchable backref
+- new FLT_ROUNDS definition failed to work in C++ code
+
+arch-specific bugs fixed:
+- aarch64 was missing max_align_t definition
+
+
+
+1.1.9 release notes
+
+new features:
+- ability to protect libc code itself with stack protector
+- sigsetjmp now restores signal mask after restoring context, not before
+- thread-local dlerror status/messages
+- dlerror messages are no longer truncated
+- diagnostics for constraint violations with ctype.h macros
+
+optimizations:
+- reduce cost of PIC on archs where PLT calls need a fixed GOT register
+- spin locks no longer constantly invalidate cache lines while spinning
+- code size reduction in static-linked TLS init
+
+bugs fixed:
+- failure to process robust mutexes on detached-thread exit
+- possible memory corruption due to robust mutex list on detached-thread exit
+- crash on memory exhaustion in getgr* internals
+- misaligned memory accesses in static binaries with low-alignment TLS blocks
+- multiple cases of wrongful path search continuation after transient failure
+- small memory leak on failure of dlopen with RPATH $ORIGIN
+- several small math bugs related to exception flags with non-finite args
+- mmap leak in sem_open failure path for link call
+- duplocale clobbered new locale struct with memcpy of old
+- futimes crashed with null timeval argument
+
+arch-specific bugs fixed:
+- stack protector spuriously aborted after forking on x32
+- stack protector spuriously aborted with flockfile on powerpc
+- theoretically-possible clobbering of syscall return value on mips
+- random thread-pointer setup failure on sh (uninitialized return value)
+- possible crash in dlsym on sh due to incorrectly-computed branch target
+- broken fesetenv(FE_DFL_ENV) on mips
+- dynamic linker name for sh ignored fpu/nofpu and endianness
+- various minor aarch64 bugs
+- dangling pointers in x32 syscall timespec fixup code
+
+
+
+1.1.10 release notes
+
+new features:
+- fail-safe (allocation-free) C locale for newlocale to return
+- all locale categories track requested locale name
+- rcrt1.o start file for static PIE
+
+optimizations:
+- inline atomics for sh4a
+- removed heavy atomics from locale-related code paths
+- removed global data accesses from CURRENT_LOCALE macro & callers
+- dynamic linker stage 1 size reduction
+
+compatibility:
+- better configure detection of unsupported compiler options
+- support for more relocation types in libc.so, not currently used
+- iconv_open accepts "" and "CHAR" as aliases for native (UTF-8)
+- additional LFS64 macros in sys/resource.h
+
+regressions fixed:
+- dynamic linker crash on NONE-type relocations (only mips affected)
+- inability to build as thumb2 on arm
+- failure to run under qemu-i386 user-level emulation
+- inability to access globals from libc on powerpc
+- PIE link errors in Scrt1.o under unusual usage on some archs
+
+other bugs fixed:
+- failure of ungetc/ungetwc to work on FILE streams in EOF state
+- possible null pointer dereference in gettext
+- possible initial stack misalignment on mips with PIE
+
+
+
+1.1.11 release notes
+
+new features:
+- byte-based C locale
+- vdso clock_gettime on arm
+- musl-clang wrapper
+- sh2 nommu target support
+
+performance:
+- major speed-up for dynamic linker symbol lookups with GNU hash
+
+compatibility:
+- strverscmp now matches GNU behavior in corner cases
+- empty TZ environment variable gives GMT rather than system default
+- reconnection on syslog server socket loss (syslogd restart)
+- mmap fallback in simple_malloc when brk fails
+- support for %m and %s with null pointers in wide printf variants
+- call frame information in i386 asm for improved debugger support
+
+bugs fixed:
+- spurious errors from pwd/grp functions when nscd backend is absent
+- possible invalid access on calloc with simple_malloc
+- null pointer dereferences after calling uselocale((locale_t)0)
+- erroneous support for cancellation in stdio caused data loss
+- inconsistent handling of atexit called from atexit handler
+- missing locking in error paths for ungetwc
+- btowc mishandling of out-of-range non-EOF inputs
+- negated return value of ns_skiprr, failure in related functions
+- incorrect void return type for syncfs, missing error status
+- possible failure of tempnam due to missing null termination
+- negated tm_gmtoff field in struct tm
+- off-by-one error in getsubopt leaving equals sign in value result
+
+arch-specific bugs fixed:
+- soft deadlocks on i386/x86_64 due to missing barrier in internal locks
+- regression in arm pre-v7 support for kernels with kuser helper removed
+- runaway PC on mips detached thread exit (due to kernel regression)
+- mismatched ABI for local-dynamic model TLS on mips and powerpc
+- incorrect value of some SO_* constants on mips
+- broken 64-bit syscall argument passing on aarch64
+
+
+
+1.1.12 release notes
+
+new features:
+- fdpic abi on sh2 for shareable text segment without mmu
+- general fdpic elf support in dynamic linker
+- CFI generation for x86_64 asm source files
+- protection against silently building a libc.so with missing symbols
+
+compatibility:
+- nl_langinfo(CODESET) now returns "ASCII" in byte-based C locale
+- fixed build regression due to buggy .SECONDARY in some GNU make versions
+- additional arm eabi functions needed by llvm arm backend
+- added format argument attributes to gettext function prototypes
+- static PIE no longer requires linking with -E/-rdynamic
+- eliminated spurious protected-data warnings linking against libc.so
+- avoided spurious fpu asm errors with some armhf toolchains
+
+bugs fixed:
+- fclose of stdin/stdout caused deadlock at exit
+- missing memory barrier in pthread_join
+- open_[w]memstream produced no buffer when no writes took place
+- uninitialized scopeid in address lookups from hosts file and ip literals
+- ip literals for mismatching family (v4 vs v6) were queried as hostnames
+- possible crash on OOM in regcomp
+- incorrect contents in localeconv structure (-1 instead of CHAR_MAX)
+- strftime mishandling of out-of-range struct tm members
+- wrongful attribute((const)) on pthread_self and errno location function
+
+arch-specific bugs fixed:
+- arm crt1 entry point failed to align stack pointer in some cases
+- mips fesetround failed to actually set rounding mode
+- i386 asm source CFI generation had multiple bugs
+
+
+
+1.1.13 release notes
+
+new features:
+- out-of-tree builds
+- search domains in resolv.conf
+- sh arch supports j-core (j2) cas.l atomics
+- dynamic linker includes arch/abi in output when run as a command
+- header support for new kernel features through linux 4.4
+- mips vdso clock_gettime support
+- regex BRE extensions: \|, \+, \?
+
+performance:
+- improved atomics performance on all archs with ll/sc model
+- atomic instructions are now inlined on armv6
+- use fpu sqrt for arm softfp abi on targets with vfp
+
+compatibility:
+- getnameinfo now accepts sockaddr sizes larger than needed
+- new default CFLAGS/LDFLAGS avoid entire classes of toolchain bugs
+- explicit use of float_t/double_t avoids compiler float spill bugs
+- i386 max_align_t definition now works with g++ 4.7's pseudo-c++11
+- all known protocols are added to protoent functions
+- stub utmpname, utmpxname functions
+- linker support for -Bsymbolic-functions is no longer mandatory
+- regex parsing size limits increased
+- malloc_usable_size now accepts null pointer input
+
+bugs fixed:
+- potential single-byte heap overflow in getdelim
+- mishandling of transient failure opening hosts, services, resolv.conf
+- mremap was sometimes able to allocate objects larger than PTRDIFF_MAX
+- nl_langinfo wrongly returned NULL instead of "" for invalid items
+- out-of-bounds dynamic tls allocation due to pointer/index scaling error
+- getifaddrs misreported point-to-point interface addresses
+- tdelete left tsearch trees misbalanced
+- tsearch crashed on allocation failure
+- tsearch, tfind, and tdelete failed to handle null pointer input
+- passing signal number 0 to sigaction resulted in a crash
+- getdelim updated caller's size wrongly when realloc failed
+- getdelim realloc strategy was wasteful
+- if_nametoindex returned wrong value on failure
+- missing ssp-suppression for some source files called from early-init
+- various minor resolv.conf parsing bugs
+- fwrite wrongly reported success on write errors in line-buffered flush
+- fwrite and fread wrongly returned nmemb (not 0) when size was 0
+
+nommu-specific bugs fix:
+- failure to zero bss in FDPIC shared library loader
+- unsafe writes to read-only file mapping in non-FDPIC library loader
+
+arch-specific bugs fixed:
+- sh[eb]-nofpu-fdpic was using fpu-dependent setjmp/longjmp variants
+- dynamic linker path file name was wrong for arm "softfp" targets
+- mips siginfo_t and related macros were defined incorrectly
+- possibly misaligned pointer globals on arm (from an asm source file)
+- mips dynamic linker failed to provide info needed by debugger
+- mips cancellation asm wrongly assumed validity of $gp register value
+
+
+
+1.1.14 release notes
+
+regressions fixed:
+- treatment of empty string argument as error by puts and fputs
+- make clean and distclean failure in unconfigured trees
+- sh/fdpic dynamic linker entry point hang due to wrong code
+- armhf (and arm softfp model) build failure with clang
+
+other bugs fixed:
+- wrongly clamping (rather than failing) excessive rounds in crypt-sha*
+
+
+
+1.1.15 release notes
+
+new features:
+- mips64 (full 64-bit and n32) port
+- mips r6 isa support (subarch for mips, mips64, and mipsn32 archs)
+- powerpc64 port
+- powerpc (32-bit) soft-float ABI support (subarch)
+- pthread_tryjoin_np and pthread_timedjoin_np (nonstandard extensions)
+- header-level support for linux 4.5 and 4.6 features
+- sched_getcpu (nonstandard extension) support, including vdso version
+- __STDC_ISO_10646__, __STDC_IEC_559__ macros predefined via stdc-predef.h
+- support for new elf/arch features in elf.h
+
+compatibility:
+- configure now correctly chooses cross-prefix based on build/host/target
+- abort now successfully terminates pid 1 in a container (or top-level)
+
+bugs fixed:
+- memmem read past end of haystack, possible false positives or crashes
+- buffer underflow (reverse-overflow) in ungetwc
+- double-free under certain usage of putenv
+- incorrect treatment by regcomp of * at start of BRE subexpression
+- gethostbyname[2][_r] produced ip addresses in misaligned buffers
+- looking up some invalid hostnames caused malformed dns queries
+- lookups from hosts file were inconsistent with non-matching family
+- missing h_length value in gethostbyaddr results
+- a64l function produced wrong-signed results on 64-bit archs
+- broken padding of string formats to width in wide printf variants
+- wrong results for expf(-NAN) and exp2f(-NAN)
+- wrong value for RUSAGE_CHILDREN prevented it from working
+- abort failed to provide abnormal termination with SIGABRT blocked
+
+arch-specific bugs fixed:
+- broken posix_fadvise on arm and powerpc (32-bit)
+- thread structure/dtv corruption on powerpc at thread startup
+- various wrong mips and powerpc ioctl and termios constant values
+
+
+
+1.1.16 release notes
+
+new features:
+- s390x (64-bit S/390) port
+- pthread_setname_np extension function
+- limited pthread_setattr_default_np function to set stack size defaults
+- header-level support for linux 4.7, 4.8, and 4.9 features
+- confstr _CS_V6_ENV and _CS_V7_ENV items
+
+compatibility:
+- public prototypes for abi-compat *_unlocked symbols, etc.
+- fflush_unlocked(NULL) now works
+- resolv.h __RES version macro now matches supported APIs
+- workaround for gdb bugs backtracing across signals on x86_64
+- anchors ^ and $ are now accepted in BRE subexpressions
+- building for thumb2-only arm isa levels is now possible
+
+bugs fixed:
+- integer overflows in regexec buffer allocation (CVE-2016-8859)
+- failure of regexec to report matches at offsets past INT_MAX
+- static-pie executables with initialized thread-local storage crashed
+- printf failed to catch EOVERFLOW in some cases, wrongly produced it in others
+- printf produced wrong output, result for float with precision near INT_MAX
+- printf produced wrong results with alt-form octal, zero flag, & field width
+- printf float rounding was wrong for some midpoint cases
+- swprintf printed junk after internal (256-byte) buffer filled up
+- strtod family rounded incorrectly in several corner cases
+- getmntent failed to handle long records
+- getopt_long_only wrongly treated "--" as an option
+- asctime output wrongly varied by locale
+- strftime %y specifier produced wrong output for negative tm_year
+- time zone names quoted with <> were misparsed
+- corner case integer overflow in tm_year for some date conversions
+- failure to load shared libs whose names were prefixes of standard lib names
+- wrong error codes for several failure cases in various functions
+- various asymptomatic undefined behavior
+- various minor namespace issues in headers
+
+arch-specific bugs fixed:
+- tcsetattr regression on mips (completely non-working)
+- wrong pread/pwrite syscall calling convention on sh
+- wrong preadv2/pwritev2 syscall numbers on x32
+- mrand48/jrand48 produced wrong-signedness results on 64-bit archs
+
+
+1.1.17 release notes
+
+new features:
+- RTLD_LAZY deferred symbol binding, functionally equivalent to lazy binding
+- safeguard against dlopen of multiple libc versions/instances
+- new posix_spawn flag POSIX_SPAWN_SETSID
+- posix_spawnattr_setflags now reports unknown flags as error
+- ldso option --argv0 to set argv[0]
+- added _NL_LOCALE_NAME extension to nl_langinfo
+
+compatibility:
+- dlopen local-to-global promotion no longer changes existing symbols
+- gettext now searches locale name variants for translation files
+- increased locale name length limit from 15 to 23 bytes
+- setlocale(LC_ALL, 0) returns single name if all categories are same
+- realloc no longer fails when mremap doesn't work
+- getservby* no longer treat numeric port strings as service records
+- mmap now works around incorrect EPERM error codes from kernel
+- impact of REG_* namespace pollution in x86[_64] signal.h is reduced
+- arm atomic asm now assembles correctly with new binutils
+- PAGE_SIZE on arm is no longer constant (quiet upstream ABI relaxation)
+- lsearch/lfind now pass args to compare callback in canonical order
+- STB_WEAK and STB_GNU_UNIQUE symbols now behave same as STB_GLOBAL
+- better clang CFLAGS checks in configure
+- global vis.h hack, which made lld refuse to link to libc.so, is disabled
+
+performance:
+- single-instruction optimized math functions for aarch64, s390x, powerpc64
+- fast path for ASCII in towupper/towlower
+- new mostly-integer-math fma function
+
+semantic bugs fixed:
+- POSIX-format TZ dst time transitions were wrong for southern hemisphere
+- regex REG_NEWLINE semantics were wrong with negated brackets
+- various bugs in strptime %j, %p, %C formats
+- iconv mapped some characters to legacy 8bit encodings incorrectly
+- glob failed to match "/"
+- UTF-8 decoder accepted invalid f4 9x xx xx code sequences
+- scanf %% conversion failed to consume whitespace
+- glob with GLOB_PERIOD wrongly descended into . and ..
+- nftw gave incorrect base name offset when pathname ends in "/"
+- functional regression in resolv.conf attempts option
+- scalbn could produce wrong result due to double rounding in subnormal range
+- strftime %y format wrong with negative years
+- mbsnrtowcs and wcsnrtombs mishandled input limits
+- minor issues with error codes for various functions
+
+safety/consistency bugs fixed:
+- stack-based buffer overflow in dns response processing
+- invalid free in regexec on certain error paths
+- invalid free in globfree after failed glob
+- one-byte buffer overflow in legacy getpass function
+- failed dlopen corrupted thread-local storage module list
+- race in pthread_create with priority attributes could leave signals masked
+- multithreaded set*id() functions could induce spurious EINTRs
+- dl_iterate_phdr reported wrong base address in static PIE
+- fd leak and wrong cancellation state after dns socket failure
+- memory leaks and other issues in environment-modification functions
+- read-after-free race in pthread_detach
+- memmem performed single-byte over-read in short-needle code paths
+- read via uninitialized pointer in gettext core
+- bindtextdomain broke bindings for all other domains
+- various silent undefined behavior
+- getopt clobbered optopt on success
+
+arch-specific bugs fixed:
+- x32 dynamic TLS accesses crashed
+- s390x was missing dlsym entry point (needed for RTLD_NEXT)
+- powerpc64 ldso startup could crash depending on link order
+- powerpc64 setjmp/longjmp didn't properly save/restore TOC pointer
+- thumb2 setjmp/longjmp silently broke at ld-time with text not aligned
+- fchown was broken on archs without SYS_fchown syscall
+- fstatat was broken on mips64
+- various incorrect constants in powerpc64 and mips headers
+
+
+1.1.18 release notes
+
+regression fixes:
+- glob failed to match literal . and .. path components
+- build for armv4t ISA level was broken
+
+other bug fixes:
+- stack overflow in posix_spawnp with large PATH variable in environment
Index: EcnlProtoTool/trunk/musl-1.1.18/arch/arm/bits/syscall.h.in
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/arch/arm/bits/syscall.h.in	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/arch/arm/bits/syscall.h.in	(revision 331)
@@ -0,0 +1,361 @@
+#define __NR_restart_syscall	0
+#define __NR_exit	1
+#define __NR_fork	2
+#define __NR_read	3
+#define __NR_write	4
+#define __NR_open	5
+#define __NR_close	6
+#define __NR_creat	8
+#define __NR_link	9
+#define __NR_unlink	10
+#define __NR_execve	11
+#define __NR_chdir	12
+#define __NR_mknod	14
+#define __NR_chmod	15
+#define __NR_lchown	16
+#define __NR_lseek	19
+#define __NR_getpid	20
+#define __NR_mount	21
+#define __NR_setuid	23
+#define __NR_getuid	24
+#define __NR_ptrace	26
+#define __NR_pause	29
+#define __NR_access	33
+#define __NR_nice	34
+#define __NR_sync	36
+#define __NR_kill	37
+#define __NR_rename	38
+#define __NR_mkdir	39
+#define __NR_rmdir	40
+#define __NR_dup	41
+#define __NR_pipe	42
+#define __NR_times	43
+#define __NR_brk	45
+#define __NR_setgid	46
+#define __NR_getgid	47
+#define __NR_geteuid	49
+#define __NR_getegid	50
+#define __NR_acct	51
+#define __NR_umount2	52
+#define __NR_ioctl	54
+#define __NR_fcntl	55
+#define __NR_setpgid	57
+#define __NR_umask	60
+#define __NR_chroot	61
+#define __NR_ustat	62
+#define __NR_dup2	63
+#define __NR_getppid	64
+#define __NR_getpgrp	65
+#define __NR_setsid	66
+#define __NR_sigaction	67
+#define __NR_setreuid	70
+#define __NR_setregid	71
+#define __NR_sigsuspend	72
+#define __NR_sigpending	73
+#define __NR_sethostname	74
+#define __NR_setrlimit	75
+#define __NR_getrusage	77
+#define __NR_gettimeofday	78
+#define __NR_settimeofday	79
+#define __NR_getgroups	80
+#define __NR_setgroups	81
+#define __NR_symlink	83
+#define __NR_readlink	85
+#define __NR_uselib	86
+#define __NR_swapon	87
+#define __NR_reboot	88
+#define __NR_munmap	91
+#define __NR_truncate	92
+#define __NR_ftruncate	93
+#define __NR_fchmod	94
+#define __NR_fchown	95
+#define __NR_getpriority	96
+#define __NR_setpriority	97
+#define __NR_statfs	99
+#define __NR_fstatfs	100
+#define __NR_syslog	103
+#define __NR_setitimer	104
+#define __NR_getitimer	105
+#define __NR_stat	106
+#define __NR_lstat	107
+#define __NR_fstat	108
+#define __NR_vhangup	111
+#define __NR_wait4	114
+#define __NR_swapoff	115
+#define __NR_sysinfo	116
+#define __NR_fsync	118
+#define __NR_sigreturn	119
+#define __NR_clone	120
+#define __NR_setdomainname	121
+#define __NR_uname	122
+#define __NR_adjtimex	124
+#define __NR_mprotect	125
+#define __NR_sigprocmask	126
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_quotactl	131
+#define __NR_getpgid	132
+#define __NR_fchdir	133
+#define __NR_bdflush	134
+#define __NR_sysfs	135
+#define __NR_personality	136
+#define __NR_setfsuid	138
+#define __NR_setfsgid	139
+#define __NR__llseek	140
+#define __NR_getdents	141
+#define __NR__newselect	142
+#define __NR_flock	143
+#define __NR_msync	144
+#define __NR_readv	145
+#define __NR_writev	146
+#define __NR_getsid	147
+#define __NR_fdatasync	148
+#define __NR__sysctl	149
+#define __NR_mlock	150
+#define __NR_munlock	151
+#define __NR_mlockall	152
+#define __NR_munlockall	153
+#define __NR_sched_setparam	154
+#define __NR_sched_getparam	155
+#define __NR_sched_setscheduler	156
+#define __NR_sched_getscheduler	157
+#define __NR_sched_yield	158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep	162
+#define __NR_mremap	163
+#define __NR_setresuid	164
+#define __NR_getresuid	165
+#define __NR_poll	168
+#define __NR_nfsservctl	169
+#define __NR_setresgid	170
+#define __NR_getresgid	171
+#define __NR_prctl	172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread64	180
+#define __NR_pwrite64	181
+#define __NR_chown	182
+#define __NR_getcwd	183
+#define __NR_capget	184
+#define __NR_capset	185
+#define __NR_sigaltstack	186
+#define __NR_sendfile	187
+#define __NR_vfork	190
+#define __NR_ugetrlimit	191
+#define __NR_mmap2	192
+#define __NR_truncate64	193
+#define __NR_ftruncate64	194
+#define __NR_stat64	195
+#define __NR_lstat64	196
+#define __NR_fstat64	197
+#define __NR_lchown32	198
+#define __NR_getuid32	199
+#define __NR_getgid32	200
+#define __NR_geteuid32	201
+#define __NR_getegid32	202
+#define __NR_setreuid32	203
+#define __NR_setregid32	204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32	207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_chown32	212
+#define __NR_setuid32	213
+#define __NR_setgid32	214
+#define __NR_setfsuid32	215
+#define __NR_setfsgid32	216
+#define __NR_getdents64	217
+#define __NR_pivot_root	218
+#define __NR_mincore	219
+#define __NR_madvise	220
+#define __NR_fcntl64	221
+#define __NR_gettid	224
+#define __NR_readahead	225
+#define __NR_setxattr	226
+#define __NR_lsetxattr	227
+#define __NR_fsetxattr	228
+#define __NR_getxattr	229
+#define __NR_lgetxattr	230
+#define __NR_fgetxattr	231
+#define __NR_listxattr	232
+#define __NR_llistxattr	233
+#define __NR_flistxattr	234
+#define __NR_removexattr	235
+#define __NR_lremovexattr	236
+#define __NR_fremovexattr	237
+#define __NR_tkill	238
+#define __NR_sendfile64	239
+#define __NR_futex	240
+#define __NR_sched_setaffinity	241
+#define __NR_sched_getaffinity	242
+#define __NR_io_setup	243
+#define __NR_io_destroy	244
+#define __NR_io_getevents	245
+#define __NR_io_submit	246
+#define __NR_io_cancel	247
+#define __NR_exit_group	248
+#define __NR_lookup_dcookie	249
+#define __NR_epoll_create	250
+#define __NR_epoll_ctl	251
+#define __NR_epoll_wait	252
+#define __NR_remap_file_pages	253
+#define __NR_set_tid_address	256
+#define __NR_timer_create	257
+#define __NR_timer_settime	258
+#define __NR_timer_gettime	259
+#define __NR_timer_getoverrun	260
+#define __NR_timer_delete	261
+#define __NR_clock_settime	262
+#define __NR_clock_gettime	263
+#define __NR_clock_getres	264
+#define __NR_clock_nanosleep	265
+#define __NR_statfs64	266
+#define __NR_fstatfs64	267
+#define __NR_tgkill	268
+#define __NR_utimes	269
+#define __NR_fadvise64_64	270
+#define __NR_arm_fadvise64_64	270
+#define __NR_pciconfig_iobase	271
+#define __NR_pciconfig_read	272
+#define __NR_pciconfig_write	273
+#define __NR_mq_open	274
+#define __NR_mq_unlink	275
+#define __NR_mq_timedsend	276
+#define __NR_mq_timedreceive	277
+#define __NR_mq_notify	278
+#define __NR_mq_getsetattr	279
+#define __NR_waitid	280
+#define __NR_socket	281
+#define __NR_bind	282
+#define __NR_connect	283
+#define __NR_listen	284
+#define __NR_accept	285
+#define __NR_getsockname	286
+#define __NR_getpeername	287
+#define __NR_socketpair	288
+#define __NR_send	289
+#define __NR_sendto	290
+#define __NR_recv	291
+#define __NR_recvfrom	292
+#define __NR_shutdown	293
+#define __NR_setsockopt	294
+#define __NR_getsockopt	295
+#define __NR_sendmsg	296
+#define __NR_recvmsg	297
+#define __NR_semop	298
+#define __NR_semget	299
+#define __NR_semctl	300
+#define __NR_msgsnd	301
+#define __NR_msgrcv	302
+#define __NR_msgget	303
+#define __NR_msgctl	304
+#define __NR_shmat	305
+#define __NR_shmdt	306
+#define __NR_shmget	307
+#define __NR_shmctl	308
+#define __NR_add_key	309
+#define __NR_request_key	310
+#define __NR_keyctl	311
+#define __NR_semtimedop	312
+#define __NR_vserver	313
+#define __NR_ioprio_set	314
+#define __NR_ioprio_get	315
+#define __NR_inotify_init	316
+#define __NR_inotify_add_watch	317
+#define __NR_inotify_rm_watch	318
+#define __NR_mbind	319
+#define __NR_get_mempolicy	320
+#define __NR_set_mempolicy	321
+#define __NR_openat	322
+#define __NR_mkdirat	323
+#define __NR_mknodat	324
+#define __NR_fchownat	325
+#define __NR_futimesat	326
+#define __NR_fstatat64	327
+#define __NR_unlinkat	328
+#define __NR_renameat	329
+#define __NR_linkat	330
+#define __NR_symlinkat	331
+#define __NR_readlinkat	332
+#define __NR_fchmodat	333
+#define __NR_faccessat	334
+#define __NR_pselect6	335
+#define __NR_ppoll	336
+#define __NR_unshare	337
+#define __NR_set_robust_list	338
+#define __NR_get_robust_list	339
+#define __NR_splice	340
+#define __NR_sync_file_range2	341
+#define __NR_arm_sync_file_range	341
+#define __NR_tee	342
+#define __NR_vmsplice	343
+#define __NR_move_pages	344
+#define __NR_getcpu	345
+#define __NR_epoll_pwait	346
+#define __NR_kexec_load	347
+#define __NR_utimensat	348
+#define __NR_signalfd	349
+#define __NR_timerfd_create	350
+#define __NR_eventfd	351
+#define __NR_fallocate	352
+#define __NR_timerfd_settime	353
+#define __NR_timerfd_gettime	354
+#define __NR_signalfd4	355
+#define __NR_eventfd2	356
+#define __NR_epoll_create1	357
+#define __NR_dup3	358
+#define __NR_pipe2	359
+#define __NR_inotify_init1	360
+#define __NR_preadv	361
+#define __NR_pwritev	362
+#define __NR_rt_tgsigqueueinfo	363
+#define __NR_perf_event_open	364
+#define __NR_recvmmsg	365
+#define __NR_accept4	366
+#define __NR_fanotify_init	367
+#define __NR_fanotify_mark	368
+#define __NR_prlimit64	369
+#define __NR_name_to_handle_at	370
+#define __NR_open_by_handle_at	371
+#define __NR_clock_adjtime	372
+#define __NR_syncfs	373
+#define __NR_sendmmsg	374
+#define __NR_setns	375
+#define __NR_process_vm_readv	376
+#define __NR_process_vm_writev	377
+#define __NR_kcmp		378
+#define __NR_finit_module	379
+#define __NR_sched_setattr	380
+#define __NR_sched_getattr	381
+#define __NR_renameat2	382
+#define __NR_seccomp	383
+#define __NR_getrandom	384
+#define __NR_memfd_create	385
+#define __NR_bpf	386
+#define __NR_execveat	387
+#define __NR_userfaultfd	388
+#define __NR_membarrier		389
+#define __NR_mlock2		390
+#define __NR_copy_file_range	391
+#define __NR_preadv2	392
+#define __NR_pwritev2	393
+#define __NR_pkey_mprotect	394
+#define __NR_pkey_alloc	395
+#define __NR_pkey_free	396
+
+#define __ARM_NR_breakpoint	0x0f0001
+#define __ARM_NR_cacheflush	0x0f0002
+#define __ARM_NR_usr26		0x0f0003
+#define __ARM_NR_usr32		0x0f0004
+#define __ARM_NR_set_tls	0x0f0005
+
Index: EcnlProtoTool/trunk/musl-1.1.18/arch/arm/syscall_arch.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/arch/arm/syscall_arch.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/arch/arm/syscall_arch.h	(revision 331)
@@ -0,0 +1,82 @@
+#define __SYSCALL_LL_E(x) \
+((union { long long ll; long l[2]; }){ .ll = x }).l[0], \
+((union { long long ll; long l[2]; }){ .ll = x }).l[1]
+#define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x))
+
+#define __asm_syscall(...) do { \
+	__asm__ __volatile__ ( "push { lr }" ); \
+	__asm__ __volatile__ ( "svc 0" \
+	: "=r"(r0) : __VA_ARGS__ : "memory"); \
+	__asm__ __volatile__ ( "pop { lr }" ); \
+	return r0; \
+	} while (0)
+
+static inline long __syscall0(long n)
+{
+	register long r7 __asm__("r7") = n;
+	register long r0 __asm__("r0");
+	__asm_syscall("r"(r7));
+}
+
+static inline long __syscall1(long n, long a)
+{
+	register long r7 __asm__("r7") = n;
+	register long r0 __asm__("r0") = a;
+	__asm_syscall("r"(r7), "0"(r0));
+}
+
+static inline long __syscall2(long n, long a, long b)
+{
+	register long r7 __asm__("r7") = n;
+	register long r0 __asm__("r0") = a;
+	register long r1 __asm__("r1") = b;
+	__asm_syscall("r"(r7), "0"(r0), "r"(r1));
+}
+
+static inline long __syscall3(long n, long a, long b, long c)
+{
+	register long r7 __asm__("r7") = n;
+	register long r0 __asm__("r0") = a;
+	register long r1 __asm__("r1") = b;
+	register long r2 __asm__("r2") = c;
+	__asm_syscall("r"(r7), "0"(r0), "r"(r1), "r"(r2));
+}
+
+static inline long __syscall4(long n, long a, long b, long c, long d)
+{
+	register long r7 __asm__("r7") = n;
+	register long r0 __asm__("r0") = a;
+	register long r1 __asm__("r1") = b;
+	register long r2 __asm__("r2") = c;
+	register long r3 __asm__("r3") = d;
+	__asm_syscall("r"(r7), "0"(r0), "r"(r1), "r"(r2), "r"(r3));
+}
+
+static inline long __syscall5(long n, long a, long b, long c, long d, long e)
+{
+	register long r7 __asm__("r7") = n;
+	register long r0 __asm__("r0") = a;
+	register long r1 __asm__("r1") = b;
+	register long r2 __asm__("r2") = c;
+	register long r3 __asm__("r3") = d;
+	register long r4 __asm__("r4") = e;
+	__asm_syscall("r"(r7), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4));
+}
+
+static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
+{
+	register long r7 __asm__("r7") = n;
+	register long r0 __asm__("r0") = a;
+	register long r1 __asm__("r1") = b;
+	register long r2 __asm__("r2") = c;
+	register long r3 __asm__("r3") = d;
+	register long r4 __asm__("r4") = e;
+	register long r5 __asm__("r5") = f;
+	__asm_syscall("r"(r7), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5));
+}
+
+#define VDSO_USEFUL
+#define VDSO_CGT_SYM "__vdso_clock_gettime"
+#define VDSO_CGT_VER "LINUX_2.6"
+
+#define SYSCALL_FADVISE_6_ARG
Index: EcnlProtoTool/trunk/musl-1.1.18/config.mak
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/config.mak	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/config.mak	(revision 331)
@@ -0,0 +1,61 @@
+# This version of config.mak was generated by:
+# ./configure --disable-shared
+# Any changes made here will be lost if configure is re-run
+ARCH = arm
+SUBARCH = 
+ASMSUBARCH = el
+srcdir = .
+prefix = /usr/local/musl
+exec_prefix = $(prefix)
+bindir = $(exec_prefix)/bin
+libdir = $(prefix)/lib
+includedir = $(prefix)/include
+syslibdir = /lib
+CC = arm-none-eabi-gcc
+CFLAGS = -fPIC -mcpu=cortex-a9 -march=armv7-a -mlittle-endian -marm -mthumb-interwork -mfloat-abi=hard -mfpu=vfp
+CFLAGS_AUTO = -Os -pipe -fomit-frame-pointer -fno-unwind-tables -fno-asynchronous-unwind-tables -ffunction-sections -fdata-sections -Werror=implicit-function-declaration -Werror=implicit-int -Werror=pointer-sign -Werror=pointer-arith
+CFLAGS_C99FSE = -std=c99 -nostdinc -ffreestanding -fexcess-precision=standard -frounding-math -Wa,--noexecstack
+CFLAGS_MEMOPS = -fno-tree-loop-distribute-patterns
+CFLAGS_NOSSP = -fno-stack-protector
+CPPFLAGS = 
+LDFLAGS = 
+LDFLAGS_AUTO = -Wl,--sort-section,alignment -Wl,--sort-common -Wl,--gc-sections -Wl,--hash-style=both -Wl,--no-undefined -Wl,--exclude-libs=ALL -Wl,-Bsymbolic-functions
+CROSS_COMPILE = arm-none-eabi-
+LIBCC = -lgcc
+OPTIMIZE_GLOBS = internal/*.c malloc/*.c string/*.c
+ALL_TOOLS = 
+TOOL_LIBS = 
+ADD_CFI = no
+SHARED_LIBS =
+WRAPCC_GCC = $(CC)
+TCC_EXTRACT=\
+ obj/src/env/__environ.o\
+ obj/src/env/__init_tls.o\
+ obj/src/env/__libc_start_main.o\
+ obj/src/env/putenv.o\
+ obj/src/env/setenv.o\
+ obj/src/exit/atexit.o\
+ obj/src/internal/libc.o\
+ obj/src/locale/c_locale.o\
+ obj/src/locale/locale_map.o\
+ obj/src/locale/setlocale.o\
+ obj/src/malloc/expand_heap.o\
+ obj/src/malloc/lite_malloc.o\
+ obj/src/malloc/malloc.o\
+ obj/src/misc/getopt.o\
+ obj/src/misc/syslog.o\
+ obj/src/multibyte/mbrtowc.o\
+ obj/src/network/gethostbyname2.o\
+ obj/src/network/h_errno.o\
+ obj/src/passwd/getpwent.o\
+ obj/src/prng/rand.o\
+ obj/src/signal/sigaction.o\
+ obj/src/stdio/ofl.o\
+ obj/src/stdio/stderr.o\
+ obj/src/stdio/stdin.o\
+ obj/src/stdio/stdout.o\
+ obj/src/string/strtok.o\
+ obj/src/time/__tz.o\
+ obj/src/time/gmtime.o\
+ obj/src/time/localtime.o
+ 
Index: EcnlProtoTool/trunk/musl-1.1.18/include/aio.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/aio.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/aio.h	(revision 331)
@@ -0,0 +1,69 @@
+#ifndef _AIO_H
+#define _AIO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <signal.h>
+#include <time.h>
+
+#define __NEED_ssize_t
+#define __NEED_off_t
+
+#include <bits/alltypes.h>
+
+struct aiocb {
+	int aio_fildes, aio_lio_opcode, aio_reqprio;
+	volatile void *aio_buf;
+	size_t aio_nbytes;
+	struct sigevent aio_sigevent;
+	void *__td;
+	int __lock[2];
+	volatile int __err;
+	ssize_t __ret;
+	off_t aio_offset;
+	void *__next, *__prev;
+	char __dummy4[32-2*sizeof(void *)];
+};
+
+#define AIO_CANCELED 0
+#define AIO_NOTCANCELED 1
+#define AIO_ALLDONE 2
+
+#define LIO_READ 0
+#define LIO_WRITE 1
+#define LIO_NOP 2
+
+#define LIO_WAIT 0
+#define LIO_NOWAIT 1
+
+int aio_read(struct aiocb *);
+int aio_write(struct aiocb *);
+int aio_error(const struct aiocb *);
+ssize_t aio_return(struct aiocb *);
+int aio_cancel(int, struct aiocb *);
+int aio_suspend(const struct aiocb *const [], int, const struct timespec *);
+int aio_fsync(int, struct aiocb *);
+
+int lio_listio(int, struct aiocb *__restrict const *__restrict, int, struct sigevent *__restrict);
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define aiocb64 aiocb
+#define aio_read64 aio_read
+#define aio_write64 aio_write
+#define aio_error64 aio_error
+#define aio_return64 aio_return
+#define aio_cancel64 aio_cancel
+#define aio_suspend64 aio_suspend
+#define aio_fsync64 aio_fsync
+#define lio_listio64 lio_listio
+#define off64_t off_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/alloca.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/alloca.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/alloca.h	(revision 331)
@@ -0,0 +1,21 @@
+#ifndef	_ALLOCA_H
+#define	_ALLOCA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define	__NEED_size_t
+#include <bits/alltypes.h>
+
+void *alloca(size_t);
+
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/ar.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/ar.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/ar.h	(revision 331)
@@ -0,0 +1,25 @@
+#ifndef _AR_H
+#define _AR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ARMAG "!<arch>\n"
+#define SARMAG 8
+#define ARFMAG "`\n"
+
+struct ar_hdr {
+	char ar_name[16];
+	char ar_date[12];
+	char ar_uid[6], ar_gid[6];
+	char ar_mode[8];
+	char ar_size[10];
+	char ar_fmag[2];
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/arpa/ftp.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/arpa/ftp.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/arpa/ftp.h	(revision 331)
@@ -0,0 +1,35 @@
+#ifndef _ARPA_FTP_H
+#define _ARPA_FTP_H
+#define PRELIM 1
+#define COMPLETE 2
+#define CONTINUE 3
+#define TRANSIENT 4
+#define ERROR 5
+#define TYPE_A 1
+#define TYPE_E 2
+#define TYPE_I 3
+#define TYPE_L 4
+#define FORM_N 1
+#define FORM_T 2
+#define FORM_C 3
+#define STRU_F 1
+#define STRU_R 2
+#define STRU_P 3
+#define MODE_S 1
+#define MODE_B 2
+#define MODE_C 3
+#define REC_ESC '\377'
+#define REC_EOR '\001'
+#define REC_EOF '\002'
+#define BLK_EOR 0x80
+#define BLK_EOF 0x40
+#define BLK_ERRORS 0x20
+#define BLK_RESTART 0x10
+#define BLK_BYTECOUNT 2
+#ifdef FTP_NAMES
+char *modenames[] =  {"0", "Stream", "Block", "Compressed" };
+char *strunames[] =  {"0", "File", "Record", "Page" };
+char *typenames[] =  {"0", "ASCII", "EBCDIC", "Image", "Local" };
+char *formnames[] =  {"0", "Nonprint", "Telnet", "Carriage-control" };
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/arpa/inet.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/arpa/inet.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/arpa/inet.h	(revision 331)
@@ -0,0 +1,36 @@
+#ifndef _ARPA_INET_H
+#define	_ARPA_INET_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <netinet/in.h>
+
+uint32_t htonl(uint32_t);
+uint16_t htons(uint16_t);
+uint32_t ntohl(uint32_t);
+uint16_t ntohs(uint16_t);
+
+in_addr_t inet_addr (const char *);
+in_addr_t inet_network (const char *);
+char *inet_ntoa (struct in_addr);
+int inet_pton (int, const char *__restrict, void *__restrict);
+const char *inet_ntop (int, const void *__restrict, char *__restrict, socklen_t);
+
+int inet_aton (const char *, struct in_addr *);
+struct in_addr inet_makeaddr(in_addr_t, in_addr_t);
+in_addr_t inet_lnaof(struct in_addr);
+in_addr_t inet_netof(struct in_addr);
+
+#undef INET_ADDRSTRLEN
+#undef INET6_ADDRSTRLEN
+#define INET_ADDRSTRLEN  16
+#define INET6_ADDRSTRLEN 46
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/arpa/nameser.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/arpa/nameser.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/arpa/nameser.h	(revision 331)
@@ -0,0 +1,455 @@
+#ifndef _ARPA_NAMESER_H
+#define _ARPA_NAMESER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define __NAMESER	19991006
+#define NS_PACKETSZ	512
+#define NS_MAXDNAME	1025
+#define NS_MAXMSG	65535
+#define NS_MAXCDNAME	255
+#define NS_MAXLABEL	63
+#define NS_HFIXEDSZ	12
+#define NS_QFIXEDSZ	4
+#define NS_RRFIXEDSZ	10
+#define NS_INT32SZ	4
+#define NS_INT16SZ	2
+#define NS_INT8SZ	1
+#define NS_INADDRSZ	4
+#define NS_IN6ADDRSZ	16
+#define NS_CMPRSFLGS	0xc0
+#define NS_DEFAULTPORT	53
+
+typedef enum __ns_sect {
+	ns_s_qd = 0,
+	ns_s_zn = 0,
+	ns_s_an = 1,
+	ns_s_pr = 1,
+	ns_s_ns = 2,
+	ns_s_ud = 2,
+	ns_s_ar = 3,
+	ns_s_max = 4
+} ns_sect;
+
+typedef struct __ns_msg {
+	const unsigned char *_msg, *_eom;
+	uint16_t _id, _flags, _counts[ns_s_max];
+	const unsigned char *_sections[ns_s_max];
+	ns_sect _sect;
+	int _rrnum;
+	const unsigned char *_msg_ptr;
+} ns_msg;
+
+struct _ns_flagdata {  int mask, shift;  };
+extern const struct _ns_flagdata _ns_flagdata[];
+
+#define ns_msg_id(handle) ((handle)._id + 0)
+#define ns_msg_base(handle) ((handle)._msg + 0)
+#define ns_msg_end(handle) ((handle)._eom + 0)
+#define ns_msg_size(handle) ((handle)._eom - (handle)._msg)
+#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
+#define ns_msg_getflag(handle, flag) \
+	(((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift)
+
+typedef	struct __ns_rr {
+	char		name[NS_MAXDNAME];
+	uint16_t	type;
+	uint16_t	rr_class;
+	uint32_t	ttl;
+	uint16_t	rdlength;
+	const unsigned char *rdata;
+} ns_rr;
+
+#define ns_rr_name(rr)	(((rr).name[0] != '\0') ? (rr).name : ".")
+#define ns_rr_type(rr)	((ns_type)((rr).type + 0))
+#define ns_rr_class(rr)	((ns_class)((rr).rr_class + 0))
+#define ns_rr_ttl(rr)	((rr).ttl + 0)
+#define ns_rr_rdlen(rr)	((rr).rdlength + 0)
+#define ns_rr_rdata(rr)	((rr).rdata + 0)
+
+typedef enum __ns_flag {
+	ns_f_qr,
+	ns_f_opcode,
+	ns_f_aa,
+	ns_f_tc,
+	ns_f_rd,
+	ns_f_ra,
+	ns_f_z,
+	ns_f_ad,
+	ns_f_cd,
+	ns_f_rcode,
+	ns_f_max
+} ns_flag;
+
+typedef enum __ns_opcode {
+	ns_o_query = 0,
+	ns_o_iquery = 1,
+	ns_o_status = 2,
+	ns_o_notify = 4,
+	ns_o_update = 5,
+	ns_o_max = 6
+} ns_opcode;
+
+typedef	enum __ns_rcode {
+	ns_r_noerror = 0,
+	ns_r_formerr = 1,
+	ns_r_servfail = 2,
+	ns_r_nxdomain = 3,
+	ns_r_notimpl = 4,
+	ns_r_refused = 5,
+	ns_r_yxdomain = 6,
+	ns_r_yxrrset = 7,
+	ns_r_nxrrset = 8,
+	ns_r_notauth = 9,
+	ns_r_notzone = 10,
+	ns_r_max = 11,
+	ns_r_badvers = 16,
+	ns_r_badsig = 16,
+	ns_r_badkey = 17,
+	ns_r_badtime = 18
+} ns_rcode;
+
+typedef enum __ns_update_operation {
+	ns_uop_delete = 0,
+	ns_uop_add = 1,
+	ns_uop_max = 2
+} ns_update_operation;
+
+struct ns_tsig_key {
+        char name[NS_MAXDNAME], alg[NS_MAXDNAME];
+        unsigned char *data;
+        int len;
+};
+typedef struct ns_tsig_key ns_tsig_key;
+
+struct ns_tcp_tsig_state {
+	int counter;
+	struct dst_key *key;
+	void *ctx;
+	unsigned char sig[NS_PACKETSZ];
+	int siglen;
+};
+typedef struct ns_tcp_tsig_state ns_tcp_tsig_state;
+
+#define NS_TSIG_FUDGE 300
+#define NS_TSIG_TCP_COUNT 100
+#define NS_TSIG_ALG_HMAC_MD5 "HMAC-MD5.SIG-ALG.REG.INT"
+
+#define NS_TSIG_ERROR_NO_TSIG -10
+#define NS_TSIG_ERROR_NO_SPACE -11
+#define NS_TSIG_ERROR_FORMERR -12
+
+typedef enum __ns_type {
+	ns_t_invalid = 0,
+	ns_t_a = 1,
+	ns_t_ns = 2,
+	ns_t_md = 3,
+	ns_t_mf = 4,
+	ns_t_cname = 5,
+	ns_t_soa = 6,
+	ns_t_mb = 7,
+	ns_t_mg = 8,
+	ns_t_mr = 9,
+	ns_t_null = 10,
+	ns_t_wks = 11,
+	ns_t_ptr = 12,
+	ns_t_hinfo = 13,
+	ns_t_minfo = 14,
+	ns_t_mx = 15,
+	ns_t_txt = 16,
+	ns_t_rp = 17,
+	ns_t_afsdb = 18,
+	ns_t_x25 = 19,
+	ns_t_isdn = 20,
+	ns_t_rt = 21,
+	ns_t_nsap = 22,
+	ns_t_nsap_ptr = 23,
+	ns_t_sig = 24,
+	ns_t_key = 25,
+	ns_t_px = 26,
+	ns_t_gpos = 27,
+	ns_t_aaaa = 28,
+	ns_t_loc = 29,
+	ns_t_nxt = 30,
+	ns_t_eid = 31,
+	ns_t_nimloc = 32,
+	ns_t_srv = 33,
+	ns_t_atma = 34,
+	ns_t_naptr = 35,
+	ns_t_kx = 36,
+	ns_t_cert = 37,
+	ns_t_a6 = 38,
+	ns_t_dname = 39,
+	ns_t_sink = 40,
+	ns_t_opt = 41,
+	ns_t_apl = 42,
+	ns_t_tkey = 249,
+	ns_t_tsig = 250,
+	ns_t_ixfr = 251,
+	ns_t_axfr = 252,
+	ns_t_mailb = 253,
+	ns_t_maila = 254,
+	ns_t_any = 255,
+	ns_t_zxfr = 256,
+	ns_t_max = 65536
+} ns_type;
+
+#define	ns_t_qt_p(t) (ns_t_xfr_p(t) || (t) == ns_t_any || \
+		      (t) == ns_t_mailb || (t) == ns_t_maila)
+#define	ns_t_mrr_p(t) ((t) == ns_t_tsig || (t) == ns_t_opt)
+#define ns_t_rr_p(t) (!ns_t_qt_p(t) && !ns_t_mrr_p(t))
+#define ns_t_udp_p(t) ((t) != ns_t_axfr && (t) != ns_t_zxfr)
+#define ns_t_xfr_p(t) ((t) == ns_t_axfr || (t) == ns_t_ixfr || \
+		       (t) == ns_t_zxfr)
+
+typedef enum __ns_class {
+	ns_c_invalid = 0,
+	ns_c_in = 1,
+	ns_c_2 = 2,
+	ns_c_chaos = 3,
+	ns_c_hs = 4,
+	ns_c_none = 254,
+	ns_c_any = 255,
+	ns_c_max = 65536
+} ns_class;
+
+typedef enum __ns_key_types {
+	ns_kt_rsa = 1,
+	ns_kt_dh  = 2,
+	ns_kt_dsa = 3,
+	ns_kt_private = 254
+} ns_key_types;
+
+typedef enum __ns_cert_types {
+	cert_t_pkix = 1,
+	cert_t_spki = 2,
+	cert_t_pgp  = 3,
+	cert_t_url  = 253,
+	cert_t_oid  = 254
+} ns_cert_types;
+
+#define	NS_KEY_TYPEMASK		0xC000
+#define	NS_KEY_TYPE_AUTH_CONF	0x0000
+#define	NS_KEY_TYPE_CONF_ONLY	0x8000
+#define	NS_KEY_TYPE_AUTH_ONLY	0x4000
+#define	NS_KEY_TYPE_NO_KEY	0xC000
+#define	NS_KEY_NO_AUTH		0x8000
+#define	NS_KEY_NO_CONF		0x4000
+#define	NS_KEY_RESERVED2	0x2000
+#define	NS_KEY_EXTENDED_FLAGS	0x1000
+#define	NS_KEY_RESERVED4	0x0800
+#define	NS_KEY_RESERVED5	0x0400
+#define	NS_KEY_NAME_TYPE	0x0300
+#define	NS_KEY_NAME_USER	0x0000
+#define	NS_KEY_NAME_ENTITY	0x0200
+#define	NS_KEY_NAME_ZONE	0x0100
+#define	NS_KEY_NAME_RESERVED	0x0300
+#define	NS_KEY_RESERVED8	0x0080
+#define	NS_KEY_RESERVED9	0x0040
+#define	NS_KEY_RESERVED10	0x0020
+#define	NS_KEY_RESERVED11	0x0010
+#define	NS_KEY_SIGNATORYMASK	0x000F
+#define	NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED2 | \
+				  NS_KEY_RESERVED4 | \
+				  NS_KEY_RESERVED5 | \
+				  NS_KEY_RESERVED8 | \
+				  NS_KEY_RESERVED9 | \
+				  NS_KEY_RESERVED10 | \
+				  NS_KEY_RESERVED11 )
+#define NS_KEY_RESERVED_BITMASK2 0xFFFF
+#define	NS_ALG_MD5RSA		1
+#define	NS_ALG_DH               2
+#define	NS_ALG_DSA              3
+#define	NS_ALG_DSS              NS_ALG_DSA
+#define	NS_ALG_EXPIRE_ONLY	253
+#define	NS_ALG_PRIVATE_OID	254
+
+#define NS_KEY_PROT_TLS         1
+#define NS_KEY_PROT_EMAIL       2
+#define NS_KEY_PROT_DNSSEC      3
+#define NS_KEY_PROT_IPSEC       4
+#define NS_KEY_PROT_ANY		255
+
+#define	NS_MD5RSA_MIN_BITS	 512
+#define	NS_MD5RSA_MAX_BITS	4096
+#define	NS_MD5RSA_MAX_BYTES	((NS_MD5RSA_MAX_BITS+7/8)*2+3)
+#define	NS_MD5RSA_MAX_BASE64	(((NS_MD5RSA_MAX_BYTES+2)/3)*4)
+#define NS_MD5RSA_MIN_SIZE	((NS_MD5RSA_MIN_BITS+7)/8)
+#define NS_MD5RSA_MAX_SIZE	((NS_MD5RSA_MAX_BITS+7)/8)
+
+#define NS_DSA_SIG_SIZE         41
+#define NS_DSA_MIN_SIZE         213
+#define NS_DSA_MAX_BYTES        405
+
+#define	NS_SIG_TYPE	0
+#define	NS_SIG_ALG	2
+#define	NS_SIG_LABELS	3
+#define	NS_SIG_OTTL	4
+#define	NS_SIG_EXPIR	8
+#define	NS_SIG_SIGNED	12
+#define	NS_SIG_FOOT	16
+#define	NS_SIG_SIGNER	18
+#define	NS_NXT_BITS 8
+#define	NS_NXT_BIT_SET(  n,p) (p[(n)/NS_NXT_BITS] |=  (0x80>>((n)%NS_NXT_BITS)))
+#define	NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS)))
+#define	NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] &   (0x80>>((n)%NS_NXT_BITS)))
+#define NS_NXT_MAX 127
+
+#define NS_OPT_DNSSEC_OK        0x8000U
+#define NS_OPT_NSID		3
+
+#define NS_GET16(s, cp) (void)((s) = ns_get16(((cp)+=2)-2))
+#define NS_GET32(l, cp) (void)((l) = ns_get32(((cp)+=4)-4))
+#define NS_PUT16(s, cp) ns_put16((s), ((cp)+=2)-2)
+#define NS_PUT32(l, cp) ns_put32((l), ((cp)+=4)-4)
+
+unsigned ns_get16(const unsigned char *);
+unsigned long ns_get32(const unsigned char *);
+void ns_put16(unsigned, unsigned char *);
+void ns_put32(unsigned long, unsigned char *);
+
+int ns_initparse(const unsigned char *, int, ns_msg *);
+int ns_parserr(ns_msg *, ns_sect, int, ns_rr *);
+int ns_skiprr(const unsigned char *, const unsigned char *, ns_sect, int);
+int ns_name_uncompress(const unsigned char *, const unsigned char *, const unsigned char *, char *, size_t);
+
+
+#define	__BIND		19950621
+
+typedef struct {
+	unsigned	id :16;
+#if __BYTE_ORDER == __BIG_ENDIAN
+	unsigned	qr: 1;
+	unsigned	opcode: 4;
+	unsigned	aa: 1;
+	unsigned	tc: 1;
+	unsigned	rd: 1;
+	unsigned	ra: 1;
+	unsigned	unused :1;
+	unsigned	ad: 1;
+	unsigned	cd: 1;
+	unsigned	rcode :4;
+#else
+	unsigned	rd :1;
+	unsigned	tc :1;
+	unsigned	aa :1;
+	unsigned	opcode :4;
+	unsigned	qr :1;
+	unsigned	rcode :4;
+	unsigned	cd: 1;
+	unsigned	ad: 1;
+	unsigned	unused :1;
+	unsigned	ra :1;
+#endif
+	unsigned	qdcount :16;
+	unsigned	ancount :16;
+	unsigned	nscount :16;
+	unsigned	arcount :16;
+} HEADER;
+
+#define PACKETSZ	NS_PACKETSZ
+#define MAXDNAME	NS_MAXDNAME
+#define MAXCDNAME	NS_MAXCDNAME
+#define MAXLABEL	NS_MAXLABEL
+#define	HFIXEDSZ	NS_HFIXEDSZ
+#define QFIXEDSZ	NS_QFIXEDSZ
+#define RRFIXEDSZ	NS_RRFIXEDSZ
+#define	INT32SZ		NS_INT32SZ
+#define	INT16SZ		NS_INT16SZ
+#define INT8SZ		NS_INT8SZ
+#define	INADDRSZ	NS_INADDRSZ
+#define	IN6ADDRSZ	NS_IN6ADDRSZ
+#define	INDIR_MASK	NS_CMPRSFLGS
+#define NAMESERVER_PORT	NS_DEFAULTPORT
+
+#define S_ZONE		ns_s_zn
+#define S_PREREQ	ns_s_pr
+#define S_UPDATE	ns_s_ud
+#define S_ADDT		ns_s_ar
+
+#define QUERY		ns_o_query
+#define IQUERY		ns_o_iquery
+#define STATUS		ns_o_status
+#define	NS_NOTIFY_OP	ns_o_notify
+#define	NS_UPDATE_OP	ns_o_update
+
+#define NOERROR		ns_r_noerror
+#define FORMERR		ns_r_formerr
+#define SERVFAIL	ns_r_servfail
+#define NXDOMAIN	ns_r_nxdomain
+#define NOTIMP		ns_r_notimpl
+#define REFUSED		ns_r_refused
+#define YXDOMAIN	ns_r_yxdomain
+#define YXRRSET		ns_r_yxrrset
+#define NXRRSET		ns_r_nxrrset
+#define NOTAUTH		ns_r_notauth
+#define NOTZONE		ns_r_notzone
+
+#define DELETE		ns_uop_delete
+#define ADD		ns_uop_add
+
+#define T_A		ns_t_a
+#define T_NS		ns_t_ns
+#define T_MD		ns_t_md
+#define T_MF		ns_t_mf
+#define T_CNAME		ns_t_cname
+#define T_SOA		ns_t_soa
+#define T_MB		ns_t_mb
+#define T_MG		ns_t_mg
+#define T_MR		ns_t_mr
+#define T_NULL		ns_t_null
+#define T_WKS		ns_t_wks
+#define T_PTR		ns_t_ptr
+#define T_HINFO		ns_t_hinfo
+#define T_MINFO		ns_t_minfo
+#define T_MX		ns_t_mx
+#define T_TXT		ns_t_txt
+#define	T_RP		ns_t_rp
+#define T_AFSDB		ns_t_afsdb
+#define T_X25		ns_t_x25
+#define T_ISDN		ns_t_isdn
+#define T_RT		ns_t_rt
+#define T_NSAP		ns_t_nsap
+#define T_NSAP_PTR	ns_t_nsap_ptr
+#define	T_SIG		ns_t_sig
+#define	T_KEY		ns_t_key
+#define	T_PX		ns_t_px
+#define	T_GPOS		ns_t_gpos
+#define	T_AAAA		ns_t_aaaa
+#define	T_LOC		ns_t_loc
+#define	T_NXT		ns_t_nxt
+#define	T_EID		ns_t_eid
+#define	T_NIMLOC	ns_t_nimloc
+#define	T_SRV		ns_t_srv
+#define T_ATMA		ns_t_atma
+#define T_NAPTR		ns_t_naptr
+#define T_A6		ns_t_a6
+#define T_DNAME		ns_t_dname
+#define	T_TSIG		ns_t_tsig
+#define	T_IXFR		ns_t_ixfr
+#define T_AXFR		ns_t_axfr
+#define T_MAILB		ns_t_mailb
+#define T_MAILA		ns_t_maila
+#define T_ANY		ns_t_any
+
+#define C_IN		ns_c_in
+#define C_CHAOS		ns_c_chaos
+#define C_HS		ns_c_hs
+#define C_NONE		ns_c_none
+#define C_ANY		ns_c_any
+
+#define	GETSHORT		NS_GET16
+#define	GETLONG			NS_GET32
+#define	PUTSHORT		NS_PUT16
+#define	PUTLONG			NS_PUT32
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/arpa/nameser_compat.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/arpa/nameser_compat.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/arpa/nameser_compat.h	(revision 331)
@@ -0,0 +1,2 @@
+#include <arpa/nameser.h>
+
Index: EcnlProtoTool/trunk/musl-1.1.18/include/arpa/telnet.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/arpa/telnet.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/arpa/telnet.h	(revision 331)
@@ -0,0 +1,251 @@
+#ifndef _ARPA_TELNET_H
+#define	_ARPA_TELNET_H
+
+#define	IAC	255
+#define	DONT	254
+#define	DO	253
+#define	WONT	252
+#define	WILL	251
+#define	SB	250
+#define	GA	249
+#define	EL	248
+#define	EC	247
+#define	AYT	246
+#define	AO	245
+#define	IP	244
+#define	BREAK	243
+#define	DM	242
+#define	NOP	241
+#define	SE	240
+#define EOR     239
+#define	ABORT	238
+#define	SUSP	237
+#define	xEOF	236
+
+#define SYNCH	242
+
+#define telcmds ((char [][6]){ "EOF", "SUSP", "ABORT", "EOR", "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC", "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0 })
+
+#define	TELCMD_FIRST	xEOF
+#define	TELCMD_LAST	IAC
+#define	TELCMD_OK(x)	((unsigned int)(x) <= TELCMD_LAST && \
+			 (unsigned int)(x) >= TELCMD_FIRST)
+#define	TELCMD(x)	telcmds[(x)-TELCMD_FIRST]
+
+#define TELOPT_BINARY	0
+#define TELOPT_ECHO	1
+#define	TELOPT_RCP	2
+#define	TELOPT_SGA	3
+#define	TELOPT_NAMS	4
+#define	TELOPT_STATUS	5
+#define	TELOPT_TM	6
+#define	TELOPT_RCTE	7
+#define TELOPT_NAOL 	8
+#define TELOPT_NAOP 	9
+#define TELOPT_NAOCRD	10
+#define TELOPT_NAOHTS	11
+#define TELOPT_NAOHTD	12
+#define TELOPT_NAOFFD	13
+#define TELOPT_NAOVTS	14
+#define TELOPT_NAOVTD	15
+#define TELOPT_NAOLFD	16
+#define TELOPT_XASCII	17
+#define	TELOPT_LOGOUT	18
+#define	TELOPT_BM	19
+#define	TELOPT_DET	20
+#define	TELOPT_SUPDUP	21
+#define	TELOPT_SUPDUPOUTPUT 22
+#define	TELOPT_SNDLOC	23
+#define	TELOPT_TTYPE	24
+#define	TELOPT_EOR	25
+#define	TELOPT_TUID	26
+#define	TELOPT_OUTMRK	27
+#define	TELOPT_TTYLOC	28
+#define	TELOPT_3270REGIME 29
+#define	TELOPT_X3PAD	30
+#define	TELOPT_NAWS	31
+#define	TELOPT_TSPEED	32
+#define	TELOPT_LFLOW	33
+#define TELOPT_LINEMODE	34
+#define TELOPT_XDISPLOC	35
+#define TELOPT_OLD_ENVIRON 36
+#define	TELOPT_AUTHENTICATION 37/* Authenticate */
+#define	TELOPT_ENCRYPT	38
+#define TELOPT_NEW_ENVIRON 39
+#define	TELOPT_EXOPL	255
+
+
+#define	NTELOPTS	(1+TELOPT_NEW_ENVIRON)
+#ifdef TELOPTS
+char *telopts[NTELOPTS+1] = {
+	"BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
+	"STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
+	"NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
+	"NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
+	"DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
+	"SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",
+	"TACACS UID", "OUTPUT MARKING", "TTYLOC",
+	"3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",
+	"LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION",
+	"ENCRYPT", "NEW-ENVIRON",
+	0,
+};
+#define	TELOPT_FIRST	TELOPT_BINARY
+#define	TELOPT_LAST	TELOPT_NEW_ENVIRON
+#define	TELOPT_OK(x)	((unsigned int)(x) <= TELOPT_LAST)
+#define	TELOPT(x)	telopts[(x)-TELOPT_FIRST]
+#endif
+
+#define	TELQUAL_IS	0
+#define	TELQUAL_SEND	1
+#define	TELQUAL_INFO	2
+#define	TELQUAL_REPLY	2
+#define	TELQUAL_NAME	3
+
+#define	LFLOW_OFF		0
+#define	LFLOW_ON		1
+#define	LFLOW_RESTART_ANY	2
+#define	LFLOW_RESTART_XON	3
+
+
+#define	LM_MODE		1
+#define	LM_FORWARDMASK	2
+#define	LM_SLC		3
+
+#define	MODE_EDIT	0x01
+#define	MODE_TRAPSIG	0x02
+#define	MODE_ACK	0x04
+#define MODE_SOFT_TAB	0x08
+#define MODE_LIT_ECHO	0x10
+
+#define	MODE_MASK	0x1f
+
+#define MODE_FLOW		0x0100
+#define MODE_ECHO		0x0200
+#define MODE_INBIN		0x0400
+#define MODE_OUTBIN		0x0800
+#define MODE_FORCE		0x1000
+
+#define	SLC_SYNCH	1
+#define	SLC_BRK		2
+#define	SLC_IP		3
+#define	SLC_AO		4
+#define	SLC_AYT		5
+#define	SLC_EOR		6
+#define	SLC_ABORT	7
+#define	SLC_EOF		8
+#define	SLC_SUSP	9
+#define	SLC_EC		10
+#define	SLC_EL		11
+#define	SLC_EW		12
+#define	SLC_RP		13
+#define	SLC_LNEXT	14
+#define	SLC_XON		15
+#define	SLC_XOFF	16
+#define	SLC_FORW1	17
+#define	SLC_FORW2	18
+
+#define	NSLC		18
+
+#define	SLC_NAMELIST	"0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
+			"ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
+			"LNEXT", "XON", "XOFF", "FORW1", "FORW2", 0,
+#ifdef	SLC_NAMES
+char *slc_names[] = {
+	SLC_NAMELIST
+};
+#else
+extern char *slc_names[];
+#define	SLC_NAMES SLC_NAMELIST
+#endif
+
+#define	SLC_NAME_OK(x)	((unsigned int)(x) <= NSLC)
+#define SLC_NAME(x)	slc_names[x]
+
+#define	SLC_NOSUPPORT	0
+#define	SLC_CANTCHANGE	1
+#define	SLC_VARIABLE	2
+#define	SLC_DEFAULT	3
+#define	SLC_LEVELBITS	0x03
+
+#define	SLC_FUNC	0
+#define	SLC_FLAGS	1
+#define	SLC_VALUE	2
+
+#define	SLC_ACK		0x80
+#define	SLC_FLUSHIN	0x40
+#define	SLC_FLUSHOUT	0x20
+
+#define	OLD_ENV_VAR	1
+#define	OLD_ENV_VALUE	0
+#define	NEW_ENV_VAR	0
+#define	NEW_ENV_VALUE	1
+#define	ENV_ESC		2
+#define ENV_USERVAR	3
+
+#define	AUTH_WHO_CLIENT		0
+#define	AUTH_WHO_SERVER		1
+#define	AUTH_WHO_MASK		1
+
+#define	AUTH_HOW_ONE_WAY	0
+#define	AUTH_HOW_MUTUAL		2
+#define	AUTH_HOW_MASK		2
+
+#define	AUTHTYPE_NULL		0
+#define	AUTHTYPE_KERBEROS_V4	1
+#define	AUTHTYPE_KERBEROS_V5	2
+#define	AUTHTYPE_SPX		3
+#define	AUTHTYPE_MINK		4
+#define	AUTHTYPE_CNT		5
+
+#define	AUTHTYPE_TEST		99
+
+#ifdef	AUTH_NAMES
+char *authtype_names[] = {
+	"NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0,
+};
+#else
+extern char *authtype_names[];
+#endif
+
+#define	AUTHTYPE_NAME_OK(x)	((unsigned int)(x) < AUTHTYPE_CNT)
+#define	AUTHTYPE_NAME(x)	authtype_names[x]
+
+#define	ENCRYPT_IS		0
+#define	ENCRYPT_SUPPORT		1
+#define	ENCRYPT_REPLY		2
+#define	ENCRYPT_START		3
+#define	ENCRYPT_END		4
+#define	ENCRYPT_REQSTART	5
+#define	ENCRYPT_REQEND		6
+#define	ENCRYPT_ENC_KEYID	7
+#define	ENCRYPT_DEC_KEYID	8
+#define	ENCRYPT_CNT		9
+
+#define	ENCTYPE_ANY		0
+#define	ENCTYPE_DES_CFB64	1
+#define	ENCTYPE_DES_OFB64	2
+#define	ENCTYPE_CNT		3
+
+#ifdef	ENCRYPT_NAMES
+char *encrypt_names[] = {
+	"IS", "SUPPORT", "REPLY", "START", "END",
+	"REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",
+	0,
+};
+char *enctype_names[] = {
+	"ANY", "DES_CFB64",  "DES_OFB64",  0,
+};
+#else
+extern char *encrypt_names[];
+extern char *enctype_names[];
+#endif
+
+
+#define	ENCRYPT_NAME_OK(x)	((unsigned int)(x) < ENCRYPT_CNT)
+#define	ENCRYPT_NAME(x)		encrypt_names[x]
+
+#define	ENCTYPE_NAME_OK(x)	((unsigned int)(x) < ENCTYPE_CNT)
+#define	ENCTYPE_NAME(x)		enctype_names[x]
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/arpa/tftp.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/arpa/tftp.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/arpa/tftp.h	(revision 331)
@@ -0,0 +1,31 @@
+#ifndef _ARPA_TFTP_H
+#define _ARPA_TFTP_H
+#define SEGSIZE 512
+#define RRQ 01
+#define WRQ 02
+#define DATA 03
+#define ACK 04
+#define ERROR 05
+struct tftphdr {
+	short th_opcode;
+	union {
+		unsigned short tu_block;
+		short tu_code;
+		char tu_stuff[1];
+	} th_u;
+	char th_data[1];
+};
+#define th_block th_u.tu_block
+#define th_code th_u.tu_code
+#define th_stuff th_u.tu_stuff
+#define th_msg th_data
+#define EUNDEF 0
+#define ENOTFOUND 1
+#define EACCESS 2
+#define ENOSPACE 3
+#define EBADOP 4
+#define EBADID 5
+#define EEXISTS 6
+#define ENOUSER 7
+#endif
+
Index: EcnlProtoTool/trunk/musl-1.1.18/include/assert.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/assert.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/assert.h	(revision 331)
@@ -0,0 +1,23 @@
+#include <features.h>
+
+#undef assert
+
+#ifdef NDEBUG
+#define	assert(x) (void)0
+#else
+#define assert(x) ((void)((x) || (__assert_fail(#x, __FILE__, __LINE__, __func__),0)))
+#endif
+
+#if __STDC_VERSION__ >= 201112L && !defined(__cplusplus)
+#define static_assert _Static_assert
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_Noreturn void __assert_fail (const char *, const char *, int, const char *);
+
+#ifdef __cplusplus
+}
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/alltypes.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/alltypes.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/alltypes.h	(revision 331)
@@ -0,0 +1,385 @@
+#define _Addr int
+#define _Int64 long long
+#define _Reg int
+
+#if defined(__NEED_va_list) && !defined(__DEFINED_va_list)
+typedef __builtin_va_list va_list;
+#define __DEFINED_va_list
+#endif
+
+#if defined(__NEED___isoc_va_list) && !defined(__DEFINED___isoc_va_list)
+typedef __builtin_va_list __isoc_va_list;
+#define __DEFINED___isoc_va_list
+#endif
+
+
+#ifndef __cplusplus
+#if defined(__NEED_wchar_t) && !defined(__DEFINED_wchar_t)
+typedef unsigned wchar_t;
+#define __DEFINED_wchar_t
+#endif
+
+#endif
+
+#if defined(__NEED_float_t) && !defined(__DEFINED_float_t)
+typedef float float_t;
+#define __DEFINED_float_t
+#endif
+
+#if defined(__NEED_double_t) && !defined(__DEFINED_double_t)
+typedef double double_t;
+#define __DEFINED_double_t
+#endif
+
+
+#if defined(__NEED_max_align_t) && !defined(__DEFINED_max_align_t)
+typedef struct { long long __ll; long double __ld; } max_align_t;
+#define __DEFINED_max_align_t
+#endif
+
+
+#if defined(__NEED_time_t) && !defined(__DEFINED_time_t)
+typedef long time_t;
+#define __DEFINED_time_t
+#endif
+
+#if defined(__NEED_suseconds_t) && !defined(__DEFINED_suseconds_t)
+typedef long suseconds_t;
+#define __DEFINED_suseconds_t
+#endif
+
+
+#if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t)
+typedef struct { union { int __i[9]; volatile int __vi[9]; unsigned __s[9]; } __u; } pthread_attr_t;
+#define __DEFINED_pthread_attr_t
+#endif
+
+#if defined(__NEED_pthread_mutex_t) && !defined(__DEFINED_pthread_mutex_t)
+typedef struct { union { int __i[6]; volatile int __vi[6]; volatile void *volatile __p[6]; } __u; } pthread_mutex_t;
+#define __DEFINED_pthread_mutex_t
+#endif
+
+#if defined(__NEED_mtx_t) && !defined(__DEFINED_mtx_t)
+typedef struct { union { int __i[6]; volatile int __vi[6]; volatile void *volatile __p[6]; } __u; } mtx_t;
+#define __DEFINED_mtx_t
+#endif
+
+#if defined(__NEED_pthread_cond_t) && !defined(__DEFINED_pthread_cond_t)
+typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12]; } __u; } pthread_cond_t;
+#define __DEFINED_pthread_cond_t
+#endif
+
+#if defined(__NEED_cnd_t) && !defined(__DEFINED_cnd_t)
+typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12]; } __u; } cnd_t;
+#define __DEFINED_cnd_t
+#endif
+
+#if defined(__NEED_pthread_rwlock_t) && !defined(__DEFINED_pthread_rwlock_t)
+typedef struct { union { int __i[8]; volatile int __vi[8]; void *__p[8]; } __u; } pthread_rwlock_t;
+#define __DEFINED_pthread_rwlock_t
+#endif
+
+#if defined(__NEED_pthread_barrier_t) && !defined(__DEFINED_pthread_barrier_t)
+typedef struct { union { int __i[5]; volatile int __vi[5]; void *__p[5]; } __u; } pthread_barrier_t;
+#define __DEFINED_pthread_barrier_t
+#endif
+
+#if defined(__NEED_size_t) && !defined(__DEFINED_size_t)
+typedef unsigned _Addr size_t;
+#define __DEFINED_size_t
+#endif
+
+#if defined(__NEED_uintptr_t) && !defined(__DEFINED_uintptr_t)
+typedef unsigned _Addr uintptr_t;
+#define __DEFINED_uintptr_t
+#endif
+
+#if defined(__NEED_ptrdiff_t) && !defined(__DEFINED_ptrdiff_t)
+typedef _Addr ptrdiff_t;
+#define __DEFINED_ptrdiff_t
+#endif
+
+#if defined(__NEED_ssize_t) && !defined(__DEFINED_ssize_t)
+typedef _Addr ssize_t;
+#define __DEFINED_ssize_t
+#endif
+
+#if defined(__NEED_intptr_t) && !defined(__DEFINED_intptr_t)
+typedef _Addr intptr_t;
+#define __DEFINED_intptr_t
+#endif
+
+#if defined(__NEED_regoff_t) && !defined(__DEFINED_regoff_t)
+typedef _Addr regoff_t;
+#define __DEFINED_regoff_t
+#endif
+
+#if defined(__NEED_register_t) && !defined(__DEFINED_register_t)
+typedef _Reg register_t;
+#define __DEFINED_register_t
+#endif
+
+
+#if defined(__NEED_int8_t) && !defined(__DEFINED_int8_t)
+typedef signed char     int8_t;
+#define __DEFINED_int8_t
+#endif
+
+#if defined(__NEED_int16_t) && !defined(__DEFINED_int16_t)
+typedef short           int16_t;
+#define __DEFINED_int16_t
+#endif
+
+#if defined(__NEED_int32_t) && !defined(__DEFINED_int32_t)
+typedef int             int32_t;
+#define __DEFINED_int32_t
+#endif
+
+#if defined(__NEED_int64_t) && !defined(__DEFINED_int64_t)
+typedef _Int64          int64_t;
+#define __DEFINED_int64_t
+#endif
+
+#if defined(__NEED_intmax_t) && !defined(__DEFINED_intmax_t)
+typedef _Int64          intmax_t;
+#define __DEFINED_intmax_t
+#endif
+
+#if defined(__NEED_uint8_t) && !defined(__DEFINED_uint8_t)
+typedef unsigned char   uint8_t;
+#define __DEFINED_uint8_t
+#endif
+
+#if defined(__NEED_uint16_t) && !defined(__DEFINED_uint16_t)
+typedef unsigned short  uint16_t;
+#define __DEFINED_uint16_t
+#endif
+
+#if defined(__NEED_uint32_t) && !defined(__DEFINED_uint32_t)
+typedef unsigned int    uint32_t;
+#define __DEFINED_uint32_t
+#endif
+
+#if defined(__NEED_uint64_t) && !defined(__DEFINED_uint64_t)
+typedef unsigned _Int64 uint64_t;
+#define __DEFINED_uint64_t
+#endif
+
+#if defined(__NEED_u_int64_t) && !defined(__DEFINED_u_int64_t)
+typedef unsigned _Int64 u_int64_t;
+#define __DEFINED_u_int64_t
+#endif
+
+#if defined(__NEED_uintmax_t) && !defined(__DEFINED_uintmax_t)
+typedef unsigned _Int64 uintmax_t;
+#define __DEFINED_uintmax_t
+#endif
+
+
+#if defined(__NEED_mode_t) && !defined(__DEFINED_mode_t)
+typedef unsigned mode_t;
+#define __DEFINED_mode_t
+#endif
+
+#if defined(__NEED_nlink_t) && !defined(__DEFINED_nlink_t)
+typedef unsigned _Reg nlink_t;
+#define __DEFINED_nlink_t
+#endif
+
+#if defined(__NEED_off_t) && !defined(__DEFINED_off_t)
+typedef _Int64 off_t;
+#define __DEFINED_off_t
+#endif
+
+#if defined(__NEED_ino_t) && !defined(__DEFINED_ino_t)
+typedef unsigned _Int64 ino_t;
+#define __DEFINED_ino_t
+#endif
+
+#if defined(__NEED_dev_t) && !defined(__DEFINED_dev_t)
+typedef unsigned _Int64 dev_t;
+#define __DEFINED_dev_t
+#endif
+
+#if defined(__NEED_blksize_t) && !defined(__DEFINED_blksize_t)
+typedef long blksize_t;
+#define __DEFINED_blksize_t
+#endif
+
+#if defined(__NEED_blkcnt_t) && !defined(__DEFINED_blkcnt_t)
+typedef _Int64 blkcnt_t;
+#define __DEFINED_blkcnt_t
+#endif
+
+#if defined(__NEED_fsblkcnt_t) && !defined(__DEFINED_fsblkcnt_t)
+typedef unsigned _Int64 fsblkcnt_t;
+#define __DEFINED_fsblkcnt_t
+#endif
+
+#if defined(__NEED_fsfilcnt_t) && !defined(__DEFINED_fsfilcnt_t)
+typedef unsigned _Int64 fsfilcnt_t;
+#define __DEFINED_fsfilcnt_t
+#endif
+
+
+#if defined(__NEED_wint_t) && !defined(__DEFINED_wint_t)
+typedef unsigned wint_t;
+#define __DEFINED_wint_t
+#endif
+
+#if defined(__NEED_wctype_t) && !defined(__DEFINED_wctype_t)
+typedef unsigned long wctype_t;
+#define __DEFINED_wctype_t
+#endif
+
+
+#if defined(__NEED_timer_t) && !defined(__DEFINED_timer_t)
+typedef void * timer_t;
+#define __DEFINED_timer_t
+#endif
+
+#if defined(__NEED_clockid_t) && !defined(__DEFINED_clockid_t)
+typedef int clockid_t;
+#define __DEFINED_clockid_t
+#endif
+
+#if defined(__NEED_clock_t) && !defined(__DEFINED_clock_t)
+typedef long clock_t;
+#define __DEFINED_clock_t
+#endif
+
+#if defined(__NEED_struct_timeval) && !defined(__DEFINED_struct_timeval)
+struct timeval { time_t tv_sec; suseconds_t tv_usec; };
+#define __DEFINED_struct_timeval
+#endif
+
+#if defined(__NEED_struct_timespec) && !defined(__DEFINED_struct_timespec)
+struct timespec { time_t tv_sec; long tv_nsec; };
+#define __DEFINED_struct_timespec
+#endif
+
+
+#if defined(__NEED_pid_t) && !defined(__DEFINED_pid_t)
+typedef int pid_t;
+#define __DEFINED_pid_t
+#endif
+
+#if defined(__NEED_id_t) && !defined(__DEFINED_id_t)
+typedef unsigned id_t;
+#define __DEFINED_id_t
+#endif
+
+#if defined(__NEED_uid_t) && !defined(__DEFINED_uid_t)
+typedef unsigned uid_t;
+#define __DEFINED_uid_t
+#endif
+
+#if defined(__NEED_gid_t) && !defined(__DEFINED_gid_t)
+typedef unsigned gid_t;
+#define __DEFINED_gid_t
+#endif
+
+#if defined(__NEED_key_t) && !defined(__DEFINED_key_t)
+typedef int key_t;
+#define __DEFINED_key_t
+#endif
+
+#if defined(__NEED_useconds_t) && !defined(__DEFINED_useconds_t)
+typedef unsigned useconds_t;
+#define __DEFINED_useconds_t
+#endif
+
+
+#ifdef __cplusplus
+#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t)
+typedef unsigned long pthread_t;
+#define __DEFINED_pthread_t
+#endif
+
+#else
+#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t)
+typedef struct __pthread * pthread_t;
+#define __DEFINED_pthread_t
+#endif
+
+#endif
+#if defined(__NEED_pthread_once_t) && !defined(__DEFINED_pthread_once_t)
+typedef int pthread_once_t;
+#define __DEFINED_pthread_once_t
+#endif
+
+#if defined(__NEED_pthread_key_t) && !defined(__DEFINED_pthread_key_t)
+typedef unsigned pthread_key_t;
+#define __DEFINED_pthread_key_t
+#endif
+
+#if defined(__NEED_pthread_spinlock_t) && !defined(__DEFINED_pthread_spinlock_t)
+typedef int pthread_spinlock_t;
+#define __DEFINED_pthread_spinlock_t
+#endif
+
+#if defined(__NEED_pthread_mutexattr_t) && !defined(__DEFINED_pthread_mutexattr_t)
+typedef struct { unsigned __attr; } pthread_mutexattr_t;
+#define __DEFINED_pthread_mutexattr_t
+#endif
+
+#if defined(__NEED_pthread_condattr_t) && !defined(__DEFINED_pthread_condattr_t)
+typedef struct { unsigned __attr; } pthread_condattr_t;
+#define __DEFINED_pthread_condattr_t
+#endif
+
+#if defined(__NEED_pthread_barrierattr_t) && !defined(__DEFINED_pthread_barrierattr_t)
+typedef struct { unsigned __attr; } pthread_barrierattr_t;
+#define __DEFINED_pthread_barrierattr_t
+#endif
+
+#if defined(__NEED_pthread_rwlockattr_t) && !defined(__DEFINED_pthread_rwlockattr_t)
+typedef struct { unsigned __attr[2]; } pthread_rwlockattr_t;
+#define __DEFINED_pthread_rwlockattr_t
+#endif
+
+
+#if defined(__NEED_FILE) && !defined(__DEFINED_FILE)
+typedef struct _IO_FILE FILE;
+#define __DEFINED_FILE
+#endif
+
+
+#if defined(__NEED_mbstate_t) && !defined(__DEFINED_mbstate_t)
+typedef struct __mbstate_t { unsigned __opaque1, __opaque2; } mbstate_t;
+#define __DEFINED_mbstate_t
+#endif
+
+
+#if defined(__NEED_locale_t) && !defined(__DEFINED_locale_t)
+typedef struct __locale_struct * locale_t;
+#define __DEFINED_locale_t
+#endif
+
+
+#if defined(__NEED_sigset_t) && !defined(__DEFINED_sigset_t)
+typedef struct __sigset_t { unsigned long __bits[128/sizeof(long)]; } sigset_t;
+#define __DEFINED_sigset_t
+#endif
+
+
+#if defined(__NEED_struct_iovec) && !defined(__DEFINED_struct_iovec)
+struct iovec { void *iov_base; size_t iov_len; };
+#define __DEFINED_struct_iovec
+#endif
+
+
+#if defined(__NEED_socklen_t) && !defined(__DEFINED_socklen_t)
+typedef unsigned socklen_t;
+#define __DEFINED_socklen_t
+#endif
+
+#if defined(__NEED_sa_family_t) && !defined(__DEFINED_sa_family_t)
+typedef unsigned short sa_family_t;
+#define __DEFINED_sa_family_t
+#endif
+
+
+#undef _Addr
+#undef _Int64
+#undef _Reg
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/endian.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/endian.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/endian.h	(revision 331)
@@ -0,0 +1,5 @@
+#if __ARMEB__
+#define __BYTE_ORDER __BIG_ENDIAN
+#else
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/errno.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/errno.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/errno.h	(revision 331)
@@ -0,0 +1,134 @@
+#define EPERM            1
+#define ENOENT           2
+#define ESRCH            3
+#define EINTR            4
+#define EIO              5
+#define ENXIO            6
+#define E2BIG            7
+#define ENOEXEC          8
+#define EBADF            9
+#define ECHILD          10
+#define EAGAIN          11
+#define ENOMEM          12
+#define EACCES          13
+#define EFAULT          14
+#define ENOTBLK         15
+#define EBUSY           16
+#define EEXIST          17
+#define EXDEV           18
+#define ENODEV          19
+#define ENOTDIR         20
+#define EISDIR          21
+#define EINVAL          22
+#define ENFILE          23
+#define EMFILE          24
+#define ENOTTY          25
+#define ETXTBSY         26
+#define EFBIG           27
+#define ENOSPC          28
+#define ESPIPE          29
+#define EROFS           30
+#define EMLINK          31
+#define EPIPE           32
+#define EDOM            33
+#define ERANGE          34
+#define EDEADLK         35
+#define ENAMETOOLONG    36
+#define ENOLCK          37
+#define ENOSYS          38
+#define ENOTEMPTY       39
+#define ELOOP           40
+#define EWOULDBLOCK     EAGAIN
+#define ENOMSG          42
+#define EIDRM           43
+#define ECHRNG          44
+#define EL2NSYNC        45
+#define EL3HLT          46
+#define EL3RST          47
+#define ELNRNG          48
+#define EUNATCH         49
+#define ENOCSI          50
+#define EL2HLT          51
+#define EBADE           52
+#define EBADR           53
+#define EXFULL          54
+#define ENOANO          55
+#define EBADRQC         56
+#define EBADSLT         57
+#define EDEADLOCK       EDEADLK
+#define EBFONT          59
+#define ENOSTR          60
+#define ENODATA         61
+#define ETIME           62
+#define ENOSR           63
+#define ENONET          64
+#define ENOPKG          65
+#define EREMOTE         66
+#define ENOLINK         67
+#define EADV            68
+#define ESRMNT          69
+#define ECOMM           70
+#define EPROTO          71
+#define EMULTIHOP       72
+#define EDOTDOT         73
+#define EBADMSG         74
+#define EOVERFLOW       75
+#define ENOTUNIQ        76
+#define EBADFD          77
+#define EREMCHG         78
+#define ELIBACC         79
+#define ELIBBAD         80
+#define ELIBSCN         81
+#define ELIBMAX         82
+#define ELIBEXEC        83
+#define EILSEQ          84
+#define ERESTART        85
+#define ESTRPIPE        86
+#define EUSERS          87
+#define ENOTSOCK        88
+#define EDESTADDRREQ    89
+#define EMSGSIZE        90
+#define EPROTOTYPE      91
+#define ENOPROTOOPT     92
+#define EPROTONOSUPPORT 93
+#define ESOCKTNOSUPPORT 94
+#define EOPNOTSUPP      95
+#define ENOTSUP         EOPNOTSUPP
+#define EPFNOSUPPORT    96
+#define EAFNOSUPPORT    97
+#define EADDRINUSE      98
+#define EADDRNOTAVAIL   99
+#define ENETDOWN        100
+#define ENETUNREACH     101
+#define ENETRESET       102
+#define ECONNABORTED    103
+#define ECONNRESET      104
+#define ENOBUFS         105
+#define EISCONN         106
+#define ENOTCONN        107
+#define ESHUTDOWN       108
+#define ETOOMANYREFS    109
+#define ETIMEDOUT       110
+#define ECONNREFUSED    111
+#define EHOSTDOWN       112
+#define EHOSTUNREACH    113
+#define EALREADY        114
+#define EINPROGRESS     115
+#define ESTALE          116
+#define EUCLEAN         117
+#define ENOTNAM         118
+#define ENAVAIL         119
+#define EISNAM          120
+#define EREMOTEIO       121
+#define EDQUOT          122
+#define ENOMEDIUM       123
+#define EMEDIUMTYPE     124
+#define ECANCELED       125
+#define ENOKEY          126
+#define EKEYEXPIRED     127
+#define EKEYREVOKED     128
+#define EKEYREJECTED    129
+#define EOWNERDEAD      130
+#define ENOTRECOVERABLE 131
+#define ERFKILL         132
+#define EHWPOISON       133
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/fcntl.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/fcntl.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/fcntl.h	(revision 331)
@@ -0,0 +1,40 @@
+#define O_CREAT        0100
+#define O_EXCL         0200
+#define O_NOCTTY       0400
+#define O_TRUNC       01000
+#define O_APPEND      02000
+#define O_NONBLOCK    04000
+#define O_DSYNC      010000
+#define O_SYNC     04010000
+#define O_RSYNC    04010000
+#define O_DIRECTORY  040000
+#define O_NOFOLLOW  0100000
+#define O_CLOEXEC  02000000
+
+#define O_ASYNC      020000
+#define O_DIRECT    0200000
+#define O_LARGEFILE 0400000
+#define O_NOATIME  01000000
+#define O_PATH    010000000
+#define O_TMPFILE 020040000
+#define O_NDELAY O_NONBLOCK
+
+#define F_DUPFD  0
+#define F_GETFD  1
+#define F_SETFD  2
+#define F_GETFL  3
+#define F_SETFL  4
+
+#define F_SETOWN 8
+#define F_GETOWN 9
+#define F_SETSIG 10
+#define F_GETSIG 11
+
+#define F_GETLK 12
+#define F_SETLK 13
+#define F_SETLKW 14
+
+#define F_SETOWN_EX 15
+#define F_GETOWN_EX 16
+
+#define F_GETOWNER_UIDS 17
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/fenv.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/fenv.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/fenv.h	(revision 331)
@@ -0,0 +1,23 @@
+#ifndef __ARM_PCS_VFP
+#define FE_ALL_EXCEPT 0
+#define FE_TONEAREST  0
+#else
+#define FE_INVALID    1
+#define FE_DIVBYZERO  2
+#define FE_OVERFLOW   4
+#define FE_UNDERFLOW  8
+#define FE_INEXACT    16
+#define FE_ALL_EXCEPT 31
+#define FE_TONEAREST  0
+#define FE_DOWNWARD   0x800000
+#define FE_UPWARD     0x400000
+#define FE_TOWARDZERO 0xc00000
+#endif
+
+typedef unsigned long fexcept_t;
+
+typedef struct {
+	unsigned long __cw;
+} fenv_t;
+
+#define FE_DFL_ENV      ((const fenv_t *) -1)
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/float.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/float.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/float.h	(revision 331)
@@ -0,0 +1,16 @@
+#define FLT_EVAL_METHOD 0
+
+#define LDBL_TRUE_MIN 4.94065645841246544177e-324L
+#define LDBL_MIN 2.22507385850720138309e-308L
+#define LDBL_MAX 1.79769313486231570815e+308L
+#define LDBL_EPSILON 2.22044604925031308085e-16L
+
+#define LDBL_MANT_DIG 53
+#define LDBL_MIN_EXP (-1021)
+#define LDBL_MAX_EXP 1024
+
+#define LDBL_DIG 15
+#define LDBL_MIN_10_EXP (-307)
+#define LDBL_MAX_10_EXP 308
+
+#define DECIMAL_DIG 17
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/hwcap.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/hwcap.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/hwcap.h	(revision 331)
@@ -0,0 +1,53 @@
+#define HWCAP_SWP	(1 << 0)
+#define HWCAP_HALF	(1 << 1)
+#define HWCAP_THUMB	(1 << 2)
+#define HWCAP_26BIT	(1 << 3)
+#define HWCAP_FAST_MULT	(1 << 4)
+#define HWCAP_FPA	(1 << 5)
+#define HWCAP_VFP	(1 << 6)
+#define HWCAP_EDSP	(1 << 7)
+#define HWCAP_JAVA	(1 << 8)
+#define HWCAP_IWMMXT	(1 << 9)
+#define HWCAP_CRUNCH	(1 << 10)
+#define HWCAP_THUMBEE	(1 << 11)
+#define HWCAP_NEON	(1 << 12)
+#define HWCAP_VFPv3	(1 << 13)
+#define HWCAP_VFPv3D16	(1 << 14)
+#define HWCAP_TLS	(1 << 15)
+#define HWCAP_VFPv4	(1 << 16)
+#define HWCAP_IDIVA	(1 << 17)
+#define HWCAP_IDIVT	(1 << 18)
+#define HWCAP_VFPD32	(1 << 19)
+#define HWCAP_IDIV	(HWCAP_IDIVA | HWCAP_IDIVT)
+#define HWCAP_LPAE	(1 << 20)
+#define HWCAP_EVTSTRM	(1 << 21)
+
+#define HWCAP2_AES	(1 << 0)
+#define HWCAP2_PMULL	(1 << 1)
+#define HWCAP2_SHA1	(1 << 2)
+#define HWCAP2_SHA2	(1 << 3)
+#define HWCAP2_CRC32	(1 << 4)
+
+#define HWCAP_ARM_SWP	(1 << 0)
+#define HWCAP_ARM_HALF	(1 << 1)
+#define HWCAP_ARM_THUMB	(1 << 2)
+#define HWCAP_ARM_26BIT	(1 << 3)
+#define HWCAP_ARM_FAST_MULT	(1 << 4)
+#define HWCAP_ARM_FPA	(1 << 5)
+#define HWCAP_ARM_VFP	(1 << 6)
+#define HWCAP_ARM_EDSP	(1 << 7)
+#define HWCAP_ARM_JAVA	(1 << 8)
+#define HWCAP_ARM_IWMMXT	(1 << 9)
+#define HWCAP_ARM_CRUNCH	(1 << 10)
+#define HWCAP_ARM_THUMBEE	(1 << 11)
+#define HWCAP_ARM_NEON	(1 << 12)
+#define HWCAP_ARM_VFPv3	(1 << 13)
+#define HWCAP_ARM_VFPv3D16	(1 << 14)
+#define HWCAP_ARM_TLS	(1 << 15)
+#define HWCAP_ARM_VFPv4	(1 << 16)
+#define HWCAP_ARM_IDIVA	(1 << 17)
+#define HWCAP_ARM_IDIVT	(1 << 18)
+#define HWCAP_ARM_VFPD32	(1 << 19)
+#define HWCAP_ARM_IDIV	(HWCAP_ARM_IDIVA | HWCAP_ARM_IDIVT)
+#define HWCAP_ARM_LPAE	(1 << 20)
+#define HWCAP_ARM_EVTSTRM	(1 << 21)
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/ioctl.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/ioctl.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/ioctl.h	(revision 331)
@@ -0,0 +1,205 @@
+#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) )
+#define _IOC_NONE  0U
+#define _IOC_WRITE 1U
+#define _IOC_READ  2U
+
+#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)
+#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))
+#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))
+#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))
+
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
+#define TCGETA		0x5405
+#define TCSETA		0x5406
+#define TCSETAW		0x5407
+#define TCSETAF		0x5408
+#define TCSBRK		0x5409
+#define TCXONC		0x540A
+#define TCFLSH		0x540B
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+#define TIOCGPGRP	0x540F
+#define TIOCSPGRP	0x5410
+#define TIOCOUTQ	0x5411
+#define TIOCSTI		0x5412
+#define TIOCGWINSZ	0x5413
+#define TIOCSWINSZ	0x5414
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define FIONREAD	0x541B
+#define TIOCINQ		FIONREAD
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+#define FIONBIO		0x5421
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425
+#define TIOCSBRK	0x5427
+#define TIOCCBRK	0x5428
+#define TIOCGSID	0x5429
+#define TIOCGRS485	0x542E
+#define TIOCSRS485	0x542F
+#define TIOCGPTN	0x80045430
+#define TIOCSPTLCK	0x40045431
+#define TIOCGDEV	0x80045432
+#define TCGETX		0x5432
+#define TCSETX		0x5433
+#define TCSETXF		0x5434
+#define TCSETXW		0x5435
+#define TIOCSIG		0x40045436
+#define TIOCVHANGUP	0x5437
+#define TIOCGPKT	0x80045438
+#define TIOCGPTLCK	0x80045439
+#define TIOCGEXCL	0x80045440
+
+#define FIONCLEX	0x5450
+#define FIOCLEX		0x5451
+#define FIOASYNC	0x5452
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458
+#define TIOCSERGETLSR   0x5459
+#define TIOCSERGETMULTI 0x545A
+#define TIOCSERSETMULTI 0x545B
+
+#define TIOCMIWAIT	0x545C
+#define TIOCGICOUNT	0x545D
+#define FIOQSIZE	0x5460
+
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+#define TIOCPKT_IOCTL		64
+
+#define TIOCSER_TEMT    0x01
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define TIOCM_LE        0x001
+#define TIOCM_DTR       0x002
+#define TIOCM_RTS       0x004
+#define TIOCM_ST        0x008
+#define TIOCM_SR        0x010
+#define TIOCM_CTS       0x020
+#define TIOCM_CAR       0x040
+#define TIOCM_RNG       0x080
+#define TIOCM_DSR       0x100
+#define TIOCM_CD        TIOCM_CAR
+#define TIOCM_RI        TIOCM_RNG
+#define TIOCM_OUT1      0x2000
+#define TIOCM_OUT2      0x4000
+#define TIOCM_LOOP      0x8000
+
+#define N_TTY           0
+#define N_SLIP          1
+#define N_MOUSE         2
+#define N_PPP           3
+#define N_STRIP         4
+#define N_AX25          5
+#define N_X25           6
+#define N_6PACK         7
+#define N_MASC          8
+#define N_R3964         9
+#define N_PROFIBUS_FDL  10
+#define N_IRDA          11
+#define N_SMSBLOCK      12
+#define N_HDLC          13
+#define N_SYNC_PPP      14
+#define N_HCI           15
+
+#define FIOSETOWN       0x8901
+#define SIOCSPGRP       0x8902
+#define FIOGETOWN       0x8903
+#define SIOCGPGRP       0x8904
+#define SIOCATMARK      0x8905
+#define SIOCGSTAMP      0x8906
+#define SIOCGSTAMPNS    0x8907
+
+#define SIOCADDRT       0x890B
+#define SIOCDELRT       0x890C
+#define SIOCRTMSG       0x890D
+
+#define SIOCGIFNAME     0x8910
+#define SIOCSIFLINK     0x8911
+#define SIOCGIFCONF     0x8912
+#define SIOCGIFFLAGS    0x8913
+#define SIOCSIFFLAGS    0x8914
+#define SIOCGIFADDR     0x8915
+#define SIOCSIFADDR     0x8916
+#define SIOCGIFDSTADDR  0x8917
+#define SIOCSIFDSTADDR  0x8918
+#define SIOCGIFBRDADDR  0x8919
+#define SIOCSIFBRDADDR  0x891a
+#define SIOCGIFNETMASK  0x891b
+#define SIOCSIFNETMASK  0x891c
+#define SIOCGIFMETRIC   0x891d
+#define SIOCSIFMETRIC   0x891e
+#define SIOCGIFMEM      0x891f
+#define SIOCSIFMEM      0x8920
+#define SIOCGIFMTU      0x8921
+#define SIOCSIFMTU      0x8922
+#define SIOCSIFNAME     0x8923
+#define SIOCSIFHWADDR   0x8924
+#define SIOCGIFENCAP    0x8925
+#define SIOCSIFENCAP    0x8926
+#define SIOCGIFHWADDR   0x8927
+#define SIOCGIFSLAVE    0x8929
+#define SIOCSIFSLAVE    0x8930
+#define SIOCADDMULTI    0x8931
+#define SIOCDELMULTI    0x8932
+#define SIOCGIFINDEX    0x8933
+#define SIOGIFINDEX     SIOCGIFINDEX
+#define SIOCSIFPFLAGS   0x8934
+#define SIOCGIFPFLAGS   0x8935
+#define SIOCDIFADDR     0x8936
+#define SIOCSIFHWBROADCAST 0x8937
+#define SIOCGIFCOUNT    0x8938
+
+#define SIOCGIFBR       0x8940
+#define SIOCSIFBR       0x8941
+
+#define SIOCGIFTXQLEN   0x8942
+#define SIOCSIFTXQLEN   0x8943
+
+#define SIOCDARP        0x8953
+#define SIOCGARP        0x8954
+#define SIOCSARP        0x8955
+
+#define SIOCDRARP       0x8960
+#define SIOCGRARP       0x8961
+#define SIOCSRARP       0x8962
+
+#define SIOCGIFMAP      0x8970
+#define SIOCSIFMAP      0x8971
+
+#define SIOCADDDLCI     0x8980
+#define SIOCDELDLCI     0x8981
+
+#define SIOCDEVPRIVATE		0x89F0
+#define SIOCPROTOPRIVATE	0x89E0
+
+#include <bits/ioctl_fix.h>
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/ioctl_fix.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/ioctl_fix.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/ioctl_fix.h	(revision 331)
@@ -0,0 +1,2 @@
+#undef FIOQSIZE
+#define FIOQSIZE 0x545e
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/ipc.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/ipc.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/ipc.h	(revision 331)
@@ -0,0 +1,13 @@
+struct ipc_perm {
+	key_t __ipc_perm_key;
+	uid_t uid;
+	gid_t gid;
+	uid_t cuid;
+	gid_t cgid;
+	mode_t mode;
+	int __ipc_perm_seq;
+	long __pad1;
+	long __pad2;
+};
+
+#define IPC_64 0x100
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/limits.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/limits.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/limits.h	(revision 331)
@@ -0,0 +1,7 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define LONG_BIT 32
+#endif
+
+#define LONG_MAX  0x7fffffffL
+#define LLONG_MAX  0x7fffffffffffffffLL
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/link.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/link.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/link.h	(revision 331)
@@ -0,0 +1,1 @@
+typedef uint32_t Elf_Symndx;
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/msg.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/msg.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/msg.h	(revision 331)
@@ -0,0 +1,15 @@
+struct msqid_ds {
+	struct ipc_perm msg_perm;
+	time_t msg_stime;
+	int __unused1;
+	time_t msg_rtime;
+	int __unused2;
+	time_t msg_ctime;
+	int __unused3;
+	unsigned long msg_cbytes;
+	msgqnum_t msg_qnum;
+	msglen_t msg_qbytes;
+	pid_t msg_lspid;
+	pid_t msg_lrpid;
+	unsigned long __unused[2];
+};
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/posix.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/posix.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/posix.h	(revision 331)
@@ -0,0 +1,2 @@
+#define _POSIX_V6_ILP32_OFFBIG  1
+#define _POSIX_V7_ILP32_OFFBIG  1
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/reg.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/reg.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/reg.h	(revision 331)
@@ -0,0 +1,3 @@
+#undef __WORDSIZE
+#define __WORDSIZE 32
+/* FIXME */
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/sem.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/sem.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/sem.h	(revision 331)
@@ -0,0 +1,16 @@
+struct semid_ds {
+	struct ipc_perm sem_perm;
+	time_t sem_otime;
+	time_t __unused1;
+	time_t sem_ctime;
+	time_t __unused2;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	unsigned short sem_nsems;
+	char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
+#else
+	char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
+	unsigned short sem_nsems;
+#endif
+	time_t __unused3;
+	time_t __unused4;
+};
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/setjmp.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/setjmp.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/setjmp.h	(revision 331)
@@ -0,0 +1,1 @@
+typedef unsigned long long __jmp_buf[32];
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/shm.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/shm.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/shm.h	(revision 331)
@@ -0,0 +1,28 @@
+#define SHMLBA 4096
+
+struct shmid_ds {
+	struct ipc_perm shm_perm;
+	size_t shm_segsz;
+	time_t shm_atime;
+	int __unused1;
+	time_t shm_dtime;
+	int __unused2;
+	time_t shm_ctime;
+	int __unused3;
+	pid_t shm_cpid;
+	pid_t shm_lpid;
+	unsigned long shm_nattch;
+	unsigned long __pad1;
+	unsigned long __pad2;
+};
+
+struct shminfo {
+	unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
+};
+
+struct shm_info {
+	int __used_ids;
+	unsigned long shm_tot, shm_rss, shm_swp;
+	unsigned long __swap_attempts, __swap_successes;
+};
+
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/signal.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/signal.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/signal.h	(revision 331)
@@ -0,0 +1,86 @@
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef int greg_t, gregset_t[18];
+typedef struct sigcontext {
+	unsigned long trap_no, error_code, oldmask;
+	unsigned long arm_r0, arm_r1, arm_r2, arm_r3;
+	unsigned long arm_r4, arm_r5, arm_r6, arm_r7;
+	unsigned long arm_r8, arm_r9, arm_r10, arm_fp;
+	unsigned long arm_ip, arm_sp, arm_lr, arm_pc;
+	unsigned long arm_cpsr, fault_address;
+} mcontext_t;
+#else
+typedef struct {
+	unsigned long __regs[21];
+} mcontext_t;
+#endif
+
+struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+};
+
+typedef struct __ucontext {
+	unsigned long uc_flags;
+	struct __ucontext *uc_link;
+	stack_t uc_stack;
+	mcontext_t uc_mcontext;
+	sigset_t uc_sigmask;
+	unsigned long long uc_regspace[64];
+} ucontext_t;
+
+#define SA_NOCLDSTOP  1
+#define SA_NOCLDWAIT  2
+#define SA_SIGINFO    4
+#define SA_ONSTACK    0x08000000
+#define SA_RESTART    0x10000000
+#define SA_NODEFER    0x40000000
+#define SA_RESETHAND  0x80000000
+#define SA_RESTORER   0x04000000
+
+#endif
+
+#define SIGHUP    1
+#define SIGINT    2
+#define SIGQUIT   3
+#define SIGILL    4
+#define SIGTRAP   5
+#define SIGABRT   6
+#define SIGIOT    SIGABRT
+#define SIGBUS    7
+#define SIGFPE    8
+#define SIGKILL   9
+#define SIGUSR1   10
+#define SIGSEGV   11
+#define SIGUSR2   12
+#define SIGPIPE   13
+#define SIGALRM   14
+#define SIGTERM   15
+#define SIGSTKFLT 16
+#define SIGCHLD   17
+#define SIGCONT   18
+#define SIGSTOP   19
+#define SIGTSTP   20
+#define SIGTTIN   21
+#define SIGTTOU   22
+#define SIGURG    23
+#define SIGXCPU   24
+#define SIGXFSZ   25
+#define SIGVTALRM 26
+#define SIGPROF   27
+#define SIGWINCH  28
+#define SIGIO     29
+#define SIGPOLL   29
+#define SIGPWR    30
+#define SIGSYS    31
+#define SIGUNUSED SIGSYS
+
+#define _NSIG 65
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/socket.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/socket.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/socket.h	(revision 331)
@@ -0,0 +1,15 @@
+struct msghdr {
+	void *msg_name;
+	socklen_t msg_namelen;
+	struct iovec *msg_iov;
+	int msg_iovlen;
+	void *msg_control;
+	socklen_t msg_controllen;
+	int msg_flags;
+};
+
+struct cmsghdr {
+	socklen_t cmsg_len;
+	int cmsg_level;
+	int cmsg_type;
+};
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/stat.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/stat.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/stat.h	(revision 331)
@@ -0,0 +1,21 @@
+/* copied from kernel definition, but with padding replaced
+ * by the corresponding correctly-sized userspace types. */
+
+struct stat {
+	dev_t st_dev;
+	int __st_dev_padding;
+	long __st_ino_truncated;
+	mode_t st_mode;
+	nlink_t st_nlink;
+	uid_t st_uid;
+	gid_t st_gid;
+	dev_t st_rdev;
+	int __st_rdev_padding;
+	off_t st_size;
+	blksize_t st_blksize;
+	blkcnt_t st_blocks;
+	struct timespec st_atim;
+	struct timespec st_mtim;
+	struct timespec st_ctim;
+	ino_t st_ino;
+};
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/statfs.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/statfs.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/statfs.h	(revision 331)
@@ -0,0 +1,7 @@
+struct statfs {
+	unsigned long f_type, f_bsize;
+	fsblkcnt_t f_blocks, f_bfree, f_bavail;
+	fsfilcnt_t f_files, f_ffree;
+	fsid_t f_fsid;
+	unsigned long f_namelen, f_frsize, f_flags, f_spare[4];
+};
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/stdint.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/stdint.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/stdint.h	(revision 331)
@@ -0,0 +1,20 @@
+typedef int32_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef uint32_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+
+#define INT_FAST16_MIN  INT32_MIN
+#define INT_FAST32_MIN  INT32_MIN
+
+#define INT_FAST16_MAX  INT32_MAX
+#define INT_FAST32_MAX  INT32_MAX
+
+#define UINT_FAST16_MAX UINT32_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+
+#define INTPTR_MIN      INT32_MIN
+#define INTPTR_MAX      INT32_MAX
+#define UINTPTR_MAX     UINT32_MAX
+#define PTRDIFF_MIN     INT32_MIN
+#define PTRDIFF_MAX     INT32_MAX
+#define SIZE_MAX        UINT32_MAX
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/syscall.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/syscall.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/syscall.h	(revision 331)
@@ -0,0 +1,715 @@
+#define __NR_restart_syscall	0
+#define __NR_exit	1
+#define __NR_fork	2
+#define __NR_read	3
+#define __NR_write	4
+#define __NR_open	5
+#define __NR_close	6
+#define __NR_creat	8
+#define __NR_link	9
+#define __NR_unlink	10
+#define __NR_execve	11
+#define __NR_chdir	12
+#define __NR_mknod	14
+#define __NR_chmod	15
+#define __NR_lchown	16
+#define __NR_lseek	19
+#define __NR_getpid	20
+#define __NR_mount	21
+#define __NR_setuid	23
+#define __NR_getuid	24
+#define __NR_ptrace	26
+#define __NR_pause	29
+#define __NR_access	33
+#define __NR_nice	34
+#define __NR_sync	36
+#define __NR_kill	37
+#define __NR_rename	38
+#define __NR_mkdir	39
+#define __NR_rmdir	40
+#define __NR_dup	41
+#define __NR_pipe	42
+#define __NR_times	43
+#define __NR_brk	45
+#define __NR_setgid	46
+#define __NR_getgid	47
+#define __NR_geteuid	49
+#define __NR_getegid	50
+#define __NR_acct	51
+#define __NR_umount2	52
+#define __NR_ioctl	54
+#define __NR_fcntl	55
+#define __NR_setpgid	57
+#define __NR_umask	60
+#define __NR_chroot	61
+#define __NR_ustat	62
+#define __NR_dup2	63
+#define __NR_getppid	64
+#define __NR_getpgrp	65
+#define __NR_setsid	66
+#define __NR_sigaction	67
+#define __NR_setreuid	70
+#define __NR_setregid	71
+#define __NR_sigsuspend	72
+#define __NR_sigpending	73
+#define __NR_sethostname	74
+#define __NR_setrlimit	75
+#define __NR_getrusage	77
+#define __NR_gettimeofday	78
+#define __NR_settimeofday	79
+#define __NR_getgroups	80
+#define __NR_setgroups	81
+#define __NR_symlink	83
+#define __NR_readlink	85
+#define __NR_uselib	86
+#define __NR_swapon	87
+#define __NR_reboot	88
+#define __NR_munmap	91
+#define __NR_truncate	92
+#define __NR_ftruncate	93
+#define __NR_fchmod	94
+#define __NR_fchown	95
+#define __NR_getpriority	96
+#define __NR_setpriority	97
+#define __NR_statfs	99
+#define __NR_fstatfs	100
+#define __NR_syslog	103
+#define __NR_setitimer	104
+#define __NR_getitimer	105
+#define __NR_stat	106
+#define __NR_lstat	107
+#define __NR_fstat	108
+#define __NR_vhangup	111
+#define __NR_wait4	114
+#define __NR_swapoff	115
+#define __NR_sysinfo	116
+#define __NR_fsync	118
+#define __NR_sigreturn	119
+#define __NR_clone	120
+#define __NR_setdomainname	121
+#define __NR_uname	122
+#define __NR_adjtimex	124
+#define __NR_mprotect	125
+#define __NR_sigprocmask	126
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_quotactl	131
+#define __NR_getpgid	132
+#define __NR_fchdir	133
+#define __NR_bdflush	134
+#define __NR_sysfs	135
+#define __NR_personality	136
+#define __NR_setfsuid	138
+#define __NR_setfsgid	139
+#define __NR__llseek	140
+#define __NR_getdents	141
+#define __NR__newselect	142
+#define __NR_flock	143
+#define __NR_msync	144
+#define __NR_readv	145
+#define __NR_writev	146
+#define __NR_getsid	147
+#define __NR_fdatasync	148
+#define __NR__sysctl	149
+#define __NR_mlock	150
+#define __NR_munlock	151
+#define __NR_mlockall	152
+#define __NR_munlockall	153
+#define __NR_sched_setparam	154
+#define __NR_sched_getparam	155
+#define __NR_sched_setscheduler	156
+#define __NR_sched_getscheduler	157
+#define __NR_sched_yield	158
+#define __NR_sched_get_priority_max	159
+#define __NR_sched_get_priority_min	160
+#define __NR_sched_rr_get_interval	161
+#define __NR_nanosleep	162
+#define __NR_mremap	163
+#define __NR_setresuid	164
+#define __NR_getresuid	165
+#define __NR_poll	168
+#define __NR_nfsservctl	169
+#define __NR_setresgid	170
+#define __NR_getresgid	171
+#define __NR_prctl	172
+#define __NR_rt_sigreturn	173
+#define __NR_rt_sigaction	174
+#define __NR_rt_sigprocmask	175
+#define __NR_rt_sigpending	176
+#define __NR_rt_sigtimedwait	177
+#define __NR_rt_sigqueueinfo	178
+#define __NR_rt_sigsuspend	179
+#define __NR_pread64	180
+#define __NR_pwrite64	181
+#define __NR_chown	182
+#define __NR_getcwd	183
+#define __NR_capget	184
+#define __NR_capset	185
+#define __NR_sigaltstack	186
+#define __NR_sendfile	187
+#define __NR_vfork	190
+#define __NR_ugetrlimit	191
+#define __NR_mmap2	192
+#define __NR_truncate64	193
+#define __NR_ftruncate64	194
+#define __NR_stat64	195
+#define __NR_lstat64	196
+#define __NR_fstat64	197
+#define __NR_lchown32	198
+#define __NR_getuid32	199
+#define __NR_getgid32	200
+#define __NR_geteuid32	201
+#define __NR_getegid32	202
+#define __NR_setreuid32	203
+#define __NR_setregid32	204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32	207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_chown32	212
+#define __NR_setuid32	213
+#define __NR_setgid32	214
+#define __NR_setfsuid32	215
+#define __NR_setfsgid32	216
+#define __NR_getdents64	217
+#define __NR_pivot_root	218
+#define __NR_mincore	219
+#define __NR_madvise	220
+#define __NR_fcntl64	221
+#define __NR_gettid	224
+#define __NR_readahead	225
+#define __NR_setxattr	226
+#define __NR_lsetxattr	227
+#define __NR_fsetxattr	228
+#define __NR_getxattr	229
+#define __NR_lgetxattr	230
+#define __NR_fgetxattr	231
+#define __NR_listxattr	232
+#define __NR_llistxattr	233
+#define __NR_flistxattr	234
+#define __NR_removexattr	235
+#define __NR_lremovexattr	236
+#define __NR_fremovexattr	237
+#define __NR_tkill	238
+#define __NR_sendfile64	239
+#define __NR_futex	240
+#define __NR_sched_setaffinity	241
+#define __NR_sched_getaffinity	242
+#define __NR_io_setup	243
+#define __NR_io_destroy	244
+#define __NR_io_getevents	245
+#define __NR_io_submit	246
+#define __NR_io_cancel	247
+#define __NR_exit_group	248
+#define __NR_lookup_dcookie	249
+#define __NR_epoll_create	250
+#define __NR_epoll_ctl	251
+#define __NR_epoll_wait	252
+#define __NR_remap_file_pages	253
+#define __NR_set_tid_address	256
+#define __NR_timer_create	257
+#define __NR_timer_settime	258
+#define __NR_timer_gettime	259
+#define __NR_timer_getoverrun	260
+#define __NR_timer_delete	261
+#define __NR_clock_settime	262
+#define __NR_clock_gettime	263
+#define __NR_clock_getres	264
+#define __NR_clock_nanosleep	265
+#define __NR_statfs64	266
+#define __NR_fstatfs64	267
+#define __NR_tgkill	268
+#define __NR_utimes	269
+#define __NR_fadvise64_64	270
+#define __NR_arm_fadvise64_64	270
+#define __NR_pciconfig_iobase	271
+#define __NR_pciconfig_read	272
+#define __NR_pciconfig_write	273
+#define __NR_mq_open	274
+#define __NR_mq_unlink	275
+#define __NR_mq_timedsend	276
+#define __NR_mq_timedreceive	277
+#define __NR_mq_notify	278
+#define __NR_mq_getsetattr	279
+#define __NR_waitid	280
+#define __NR_socket	281
+#define __NR_bind	282
+#define __NR_connect	283
+#define __NR_listen	284
+#define __NR_accept	285
+#define __NR_getsockname	286
+#define __NR_getpeername	287
+#define __NR_socketpair	288
+#define __NR_send	289
+#define __NR_sendto	290
+#define __NR_recv	291
+#define __NR_recvfrom	292
+#define __NR_shutdown	293
+#define __NR_setsockopt	294
+#define __NR_getsockopt	295
+#define __NR_sendmsg	296
+#define __NR_recvmsg	297
+#define __NR_semop	298
+#define __NR_semget	299
+#define __NR_semctl	300
+#define __NR_msgsnd	301
+#define __NR_msgrcv	302
+#define __NR_msgget	303
+#define __NR_msgctl	304
+#define __NR_shmat	305
+#define __NR_shmdt	306
+#define __NR_shmget	307
+#define __NR_shmctl	308
+#define __NR_add_key	309
+#define __NR_request_key	310
+#define __NR_keyctl	311
+#define __NR_semtimedop	312
+#define __NR_vserver	313
+#define __NR_ioprio_set	314
+#define __NR_ioprio_get	315
+#define __NR_inotify_init	316
+#define __NR_inotify_add_watch	317
+#define __NR_inotify_rm_watch	318
+#define __NR_mbind	319
+#define __NR_get_mempolicy	320
+#define __NR_set_mempolicy	321
+#define __NR_openat	322
+#define __NR_mkdirat	323
+#define __NR_mknodat	324
+#define __NR_fchownat	325
+#define __NR_futimesat	326
+#define __NR_fstatat64	327
+#define __NR_unlinkat	328
+#define __NR_renameat	329
+#define __NR_linkat	330
+#define __NR_symlinkat	331
+#define __NR_readlinkat	332
+#define __NR_fchmodat	333
+#define __NR_faccessat	334
+#define __NR_pselect6	335
+#define __NR_ppoll	336
+#define __NR_unshare	337
+#define __NR_set_robust_list	338
+#define __NR_get_robust_list	339
+#define __NR_splice	340
+#define __NR_sync_file_range2	341
+#define __NR_arm_sync_file_range	341
+#define __NR_tee	342
+#define __NR_vmsplice	343
+#define __NR_move_pages	344
+#define __NR_getcpu	345
+#define __NR_epoll_pwait	346
+#define __NR_kexec_load	347
+#define __NR_utimensat	348
+#define __NR_signalfd	349
+#define __NR_timerfd_create	350
+#define __NR_eventfd	351
+#define __NR_fallocate	352
+#define __NR_timerfd_settime	353
+#define __NR_timerfd_gettime	354
+#define __NR_signalfd4	355
+#define __NR_eventfd2	356
+#define __NR_epoll_create1	357
+#define __NR_dup3	358
+#define __NR_pipe2	359
+#define __NR_inotify_init1	360
+#define __NR_preadv	361
+#define __NR_pwritev	362
+#define __NR_rt_tgsigqueueinfo	363
+#define __NR_perf_event_open	364
+#define __NR_recvmmsg	365
+#define __NR_accept4	366
+#define __NR_fanotify_init	367
+#define __NR_fanotify_mark	368
+#define __NR_prlimit64	369
+#define __NR_name_to_handle_at	370
+#define __NR_open_by_handle_at	371
+#define __NR_clock_adjtime	372
+#define __NR_syncfs	373
+#define __NR_sendmmsg	374
+#define __NR_setns	375
+#define __NR_process_vm_readv	376
+#define __NR_process_vm_writev	377
+#define __NR_kcmp		378
+#define __NR_finit_module	379
+#define __NR_sched_setattr	380
+#define __NR_sched_getattr	381
+#define __NR_renameat2	382
+#define __NR_seccomp	383
+#define __NR_getrandom	384
+#define __NR_memfd_create	385
+#define __NR_bpf	386
+#define __NR_execveat	387
+#define __NR_userfaultfd	388
+#define __NR_membarrier		389
+#define __NR_mlock2		390
+#define __NR_copy_file_range	391
+#define __NR_preadv2	392
+#define __NR_pwritev2	393
+#define __NR_pkey_mprotect	394
+#define __NR_pkey_alloc	395
+#define __NR_pkey_free	396
+
+#define __ARM_NR_breakpoint	0x0f0001
+#define __ARM_NR_cacheflush	0x0f0002
+#define __ARM_NR_usr26		0x0f0003
+#define __ARM_NR_usr32		0x0f0004
+#define __ARM_NR_set_tls	0x0f0005
+
+#define SYS_restart_syscall	0
+#define SYS_exit	1
+#define SYS_fork	2
+#define SYS_read	3
+#define SYS_write	4
+#define SYS_open	5
+#define SYS_close	6
+#define SYS_creat	8
+#define SYS_link	9
+#define SYS_unlink	10
+#define SYS_execve	11
+#define SYS_chdir	12
+#define SYS_mknod	14
+#define SYS_chmod	15
+#define SYS_lchown	16
+#define SYS_lseek	19
+#define SYS_getpid	20
+#define SYS_mount	21
+#define SYS_setuid	23
+#define SYS_getuid	24
+#define SYS_ptrace	26
+#define SYS_pause	29
+#define SYS_access	33
+#define SYS_nice	34
+#define SYS_sync	36
+#define SYS_kill	37
+#define SYS_rename	38
+#define SYS_mkdir	39
+#define SYS_rmdir	40
+#define SYS_dup	41
+#define SYS_pipe	42
+#define SYS_times	43
+#define SYS_brk	45
+#define SYS_setgid	46
+#define SYS_getgid	47
+#define SYS_geteuid	49
+#define SYS_getegid	50
+#define SYS_acct	51
+#define SYS_umount2	52
+#define SYS_ioctl	54
+#define SYS_fcntl	55
+#define SYS_setpgid	57
+#define SYS_umask	60
+#define SYS_chroot	61
+#define SYS_ustat	62
+#define SYS_dup2	63
+#define SYS_getppid	64
+#define SYS_getpgrp	65
+#define SYS_setsid	66
+#define SYS_sigaction	67
+#define SYS_setreuid	70
+#define SYS_setregid	71
+#define SYS_sigsuspend	72
+#define SYS_sigpending	73
+#define SYS_sethostname	74
+#define SYS_setrlimit	75
+#define SYS_getrusage	77
+#define SYS_gettimeofday	78
+#define SYS_settimeofday	79
+#define SYS_getgroups	80
+#define SYS_setgroups	81
+#define SYS_symlink	83
+#define SYS_readlink	85
+#define SYS_uselib	86
+#define SYS_swapon	87
+#define SYS_reboot	88
+#define SYS_munmap	91
+#define SYS_truncate	92
+#define SYS_ftruncate	93
+#define SYS_fchmod	94
+#define SYS_fchown	95
+#define SYS_getpriority	96
+#define SYS_setpriority	97
+#define SYS_statfs	99
+#define SYS_fstatfs	100
+#define SYS_syslog	103
+#define SYS_setitimer	104
+#define SYS_getitimer	105
+#define SYS_stat	106
+#define SYS_lstat	107
+#define SYS_fstat	108
+#define SYS_vhangup	111
+#define SYS_wait4	114
+#define SYS_swapoff	115
+#define SYS_sysinfo	116
+#define SYS_fsync	118
+#define SYS_sigreturn	119
+#define SYS_clone	120
+#define SYS_setdomainname	121
+#define SYS_uname	122
+#define SYS_adjtimex	124
+#define SYS_mprotect	125
+#define SYS_sigprocmask	126
+#define SYS_init_module	128
+#define SYS_delete_module	129
+#define SYS_quotactl	131
+#define SYS_getpgid	132
+#define SYS_fchdir	133
+#define SYS_bdflush	134
+#define SYS_sysfs	135
+#define SYS_personality	136
+#define SYS_setfsuid	138
+#define SYS_setfsgid	139
+#define SYS__llseek	140
+#define SYS_getdents	141
+#define SYS__newselect	142
+#define SYS_flock	143
+#define SYS_msync	144
+#define SYS_readv	145
+#define SYS_writev	146
+#define SYS_getsid	147
+#define SYS_fdatasync	148
+#define SYS__sysctl	149
+#define SYS_mlock	150
+#define SYS_munlock	151
+#define SYS_mlockall	152
+#define SYS_munlockall	153
+#define SYS_sched_setparam	154
+#define SYS_sched_getparam	155
+#define SYS_sched_setscheduler	156
+#define SYS_sched_getscheduler	157
+#define SYS_sched_yield	158
+#define SYS_sched_get_priority_max	159
+#define SYS_sched_get_priority_min	160
+#define SYS_sched_rr_get_interval	161
+#define SYS_nanosleep	162
+#define SYS_mremap	163
+#define SYS_setresuid	164
+#define SYS_getresuid	165
+#define SYS_poll	168
+#define SYS_nfsservctl	169
+#define SYS_setresgid	170
+#define SYS_getresgid	171
+#define SYS_prctl	172
+#define SYS_rt_sigreturn	173
+#define SYS_rt_sigaction	174
+#define SYS_rt_sigprocmask	175
+#define SYS_rt_sigpending	176
+#define SYS_rt_sigtimedwait	177
+#define SYS_rt_sigqueueinfo	178
+#define SYS_rt_sigsuspend	179
+#define SYS_pread64	180
+#define SYS_pwrite64	181
+#define SYS_chown	182
+#define SYS_getcwd	183
+#define SYS_capget	184
+#define SYS_capset	185
+#define SYS_sigaltstack	186
+#define SYS_sendfile	187
+#define SYS_vfork	190
+#define SYS_ugetrlimit	191
+#define SYS_mmap2	192
+#define SYS_truncate64	193
+#define SYS_ftruncate64	194
+#define SYS_stat64	195
+#define SYS_lstat64	196
+#define SYS_fstat64	197
+#define SYS_lchown32	198
+#define SYS_getuid32	199
+#define SYS_getgid32	200
+#define SYS_geteuid32	201
+#define SYS_getegid32	202
+#define SYS_setreuid32	203
+#define SYS_setregid32	204
+#define SYS_getgroups32	205
+#define SYS_setgroups32	206
+#define SYS_fchown32	207
+#define SYS_setresuid32	208
+#define SYS_getresuid32	209
+#define SYS_setresgid32	210
+#define SYS_getresgid32	211
+#define SYS_chown32	212
+#define SYS_setuid32	213
+#define SYS_setgid32	214
+#define SYS_setfsuid32	215
+#define SYS_setfsgid32	216
+#define SYS_getdents64	217
+#define SYS_pivot_root	218
+#define SYS_mincore	219
+#define SYS_madvise	220
+#define SYS_fcntl64	221
+#define SYS_gettid	224
+#define SYS_readahead	225
+#define SYS_setxattr	226
+#define SYS_lsetxattr	227
+#define SYS_fsetxattr	228
+#define SYS_getxattr	229
+#define SYS_lgetxattr	230
+#define SYS_fgetxattr	231
+#define SYS_listxattr	232
+#define SYS_llistxattr	233
+#define SYS_flistxattr	234
+#define SYS_removexattr	235
+#define SYS_lremovexattr	236
+#define SYS_fremovexattr	237
+#define SYS_tkill	238
+#define SYS_sendfile64	239
+#define SYS_futex	240
+#define SYS_sched_setaffinity	241
+#define SYS_sched_getaffinity	242
+#define SYS_io_setup	243
+#define SYS_io_destroy	244
+#define SYS_io_getevents	245
+#define SYS_io_submit	246
+#define SYS_io_cancel	247
+#define SYS_exit_group	248
+#define SYS_lookup_dcookie	249
+#define SYS_epoll_create	250
+#define SYS_epoll_ctl	251
+#define SYS_epoll_wait	252
+#define SYS_remap_file_pages	253
+#define SYS_set_tid_address	256
+#define SYS_timer_create	257
+#define SYS_timer_settime	258
+#define SYS_timer_gettime	259
+#define SYS_timer_getoverrun	260
+#define SYS_timer_delete	261
+#define SYS_clock_settime	262
+#define SYS_clock_gettime	263
+#define SYS_clock_getres	264
+#define SYS_clock_nanosleep	265
+#define SYS_statfs64	266
+#define SYS_fstatfs64	267
+#define SYS_tgkill	268
+#define SYS_utimes	269
+#define SYS_fadvise64_64	270
+#define SYS_arm_fadvise64_64	270
+#define SYS_pciconfig_iobase	271
+#define SYS_pciconfig_read	272
+#define SYS_pciconfig_write	273
+#define SYS_mq_open	274
+#define SYS_mq_unlink	275
+#define SYS_mq_timedsend	276
+#define SYS_mq_timedreceive	277
+#define SYS_mq_notify	278
+#define SYS_mq_getsetattr	279
+#define SYS_waitid	280
+#define SYS_socket	281
+#define SYS_bind	282
+#define SYS_connect	283
+#define SYS_listen	284
+#define SYS_accept	285
+#define SYS_getsockname	286
+#define SYS_getpeername	287
+#define SYS_socketpair	288
+#define SYS_send	289
+#define SYS_sendto	290
+#define SYS_recv	291
+#define SYS_recvfrom	292
+#define SYS_shutdown	293
+#define SYS_setsockopt	294
+#define SYS_getsockopt	295
+#define SYS_sendmsg	296
+#define SYS_recvmsg	297
+#define SYS_semop	298
+#define SYS_semget	299
+#define SYS_semctl	300
+#define SYS_msgsnd	301
+#define SYS_msgrcv	302
+#define SYS_msgget	303
+#define SYS_msgctl	304
+#define SYS_shmat	305
+#define SYS_shmdt	306
+#define SYS_shmget	307
+#define SYS_shmctl	308
+#define SYS_add_key	309
+#define SYS_request_key	310
+#define SYS_keyctl	311
+#define SYS_semtimedop	312
+#define SYS_vserver	313
+#define SYS_ioprio_set	314
+#define SYS_ioprio_get	315
+#define SYS_inotify_init	316
+#define SYS_inotify_add_watch	317
+#define SYS_inotify_rm_watch	318
+#define SYS_mbind	319
+#define SYS_get_mempolicy	320
+#define SYS_set_mempolicy	321
+#define SYS_openat	322
+#define SYS_mkdirat	323
+#define SYS_mknodat	324
+#define SYS_fchownat	325
+#define SYS_futimesat	326
+#define SYS_fstatat64	327
+#define SYS_unlinkat	328
+#define SYS_renameat	329
+#define SYS_linkat	330
+#define SYS_symlinkat	331
+#define SYS_readlinkat	332
+#define SYS_fchmodat	333
+#define SYS_faccessat	334
+#define SYS_pselect6	335
+#define SYS_ppoll	336
+#define SYS_unshare	337
+#define SYS_set_robust_list	338
+#define SYS_get_robust_list	339
+#define SYS_splice	340
+#define SYS_sync_file_range2	341
+#define SYS_arm_sync_file_range	341
+#define SYS_tee	342
+#define SYS_vmsplice	343
+#define SYS_move_pages	344
+#define SYS_getcpu	345
+#define SYS_epoll_pwait	346
+#define SYS_kexec_load	347
+#define SYS_utimensat	348
+#define SYS_signalfd	349
+#define SYS_timerfd_create	350
+#define SYS_eventfd	351
+#define SYS_fallocate	352
+#define SYS_timerfd_settime	353
+#define SYS_timerfd_gettime	354
+#define SYS_signalfd4	355
+#define SYS_eventfd2	356
+#define SYS_epoll_create1	357
+#define SYS_dup3	358
+#define SYS_pipe2	359
+#define SYS_inotify_init1	360
+#define SYS_preadv	361
+#define SYS_pwritev	362
+#define SYS_rt_tgsigqueueinfo	363
+#define SYS_perf_event_open	364
+#define SYS_recvmmsg	365
+#define SYS_accept4	366
+#define SYS_fanotify_init	367
+#define SYS_fanotify_mark	368
+#define SYS_prlimit64	369
+#define SYS_name_to_handle_at	370
+#define SYS_open_by_handle_at	371
+#define SYS_clock_adjtime	372
+#define SYS_syncfs	373
+#define SYS_sendmmsg	374
+#define SYS_setns	375
+#define SYS_process_vm_readv	376
+#define SYS_process_vm_writev	377
+#define SYS_kcmp		378
+#define SYS_finit_module	379
+#define SYS_sched_setattr	380
+#define SYS_sched_getattr	381
+#define SYS_renameat2	382
+#define SYS_seccomp	383
+#define SYS_getrandom	384
+#define SYS_memfd_create	385
+#define SYS_bpf	386
+#define SYS_execveat	387
+#define SYS_userfaultfd	388
+#define SYS_membarrier		389
+#define SYS_mlock2		390
+#define SYS_copy_file_range	391
+#define SYS_preadv2	392
+#define SYS_pwritev2	393
+#define SYS_pkey_mprotect	394
+#define SYS_pkey_alloc	395
+#define SYS_pkey_free	396
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/termios.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/termios.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/termios.h	(revision 331)
@@ -0,0 +1,164 @@
+struct termios {
+	tcflag_t c_iflag;
+	tcflag_t c_oflag;
+	tcflag_t c_cflag;
+	tcflag_t c_lflag;
+	cc_t c_line;
+	cc_t c_cc[NCCS];
+	speed_t __c_ispeed;
+	speed_t __c_ospeed;
+};
+
+#define VINTR     0
+#define VQUIT     1
+#define VERASE    2
+#define VKILL     3
+#define VEOF      4
+#define VTIME     5
+#define VMIN      6
+#define VSWTC     7
+#define VSTART    8
+#define VSTOP     9
+#define VSUSP    10
+#define VEOL     11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE  14
+#define VLNEXT   15
+#define VEOL2    16
+
+#define IGNBRK  0000001
+#define BRKINT  0000002
+#define IGNPAR  0000004
+#define PARMRK  0000010
+#define INPCK   0000020
+#define ISTRIP  0000040
+#define INLCR   0000100
+#define IGNCR   0000200
+#define ICRNL   0000400
+#define IUCLC   0001000
+#define IXON    0002000
+#define IXANY   0004000
+#define IXOFF   0010000
+#define IMAXBEL 0020000
+#define IUTF8   0040000
+
+#define OPOST  0000001
+#define OLCUC  0000002
+#define ONLCR  0000004
+#define OCRNL  0000010
+#define ONOCR  0000020
+#define ONLRET 0000040
+#define OFILL  0000100
+#define OFDEL  0000200
+#define NLDLY  0000400
+#define NL0    0000000
+#define NL1    0000400
+#define CRDLY  0003000
+#define CR0    0000000
+#define CR1    0001000
+#define CR2    0002000
+#define CR3    0003000
+#define TABDLY 0014000
+#define TAB0   0000000
+#define TAB1   0004000
+#define TAB2   0010000
+#define TAB3   0014000
+#define BSDLY  0020000
+#define BS0    0000000
+#define BS1    0020000
+#define FFDLY  0100000
+#define FF0    0000000
+#define FF1    0100000
+
+#define VTDLY  0040000
+#define VT0    0000000
+#define VT1    0040000
+
+#define B0       0000000
+#define B50      0000001
+#define B75      0000002
+#define B110     0000003
+#define B134     0000004
+#define B150     0000005
+#define B200     0000006
+#define B300     0000007
+#define B600     0000010
+#define B1200    0000011
+#define B1800    0000012
+#define B2400    0000013
+#define B4800    0000014
+#define B9600    0000015
+#define B19200   0000016
+#define B38400   0000017
+
+#define B57600   0010001
+#define B115200  0010002
+#define B230400  0010003
+#define B460800  0010004
+#define B500000  0010005
+#define B576000  0010006
+#define B921600  0010007
+#define B1000000 0010010
+#define B1152000 0010011
+#define B1500000 0010012
+#define B2000000 0010013
+#define B2500000 0010014
+#define B3000000 0010015
+#define B3500000 0010016
+#define B4000000 0010017
+
+#define CSIZE  0000060
+#define CS5    0000000
+#define CS6    0000020
+#define CS7    0000040
+#define CS8    0000060
+#define CSTOPB 0000100
+#define CREAD  0000200
+#define PARENB 0000400
+#define PARODD 0001000
+#define HUPCL  0002000
+#define CLOCAL 0004000
+
+#define ISIG   0000001
+#define ICANON 0000002
+#define ECHO   0000010
+#define ECHOE  0000020
+#define ECHOK  0000040
+#define ECHONL 0000100
+#define NOFLSH 0000200
+#define TOSTOP 0000400
+#define IEXTEN 0100000
+
+#define TCOOFF 0
+#define TCOON  1
+#define TCIOFF 2
+#define TCION  3
+
+#define TCIFLUSH  0
+#define TCOFLUSH  1
+#define TCIOFLUSH 2
+
+#define TCSANOW   0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define EXTA    0000016
+#define EXTB    0000017
+#define CBAUD   0010017
+#define CBAUDEX 0010000
+#define CIBAUD  002003600000
+#define CMSPAR  010000000000
+#define CRTSCTS 020000000000
+
+#define XCASE   0000004
+#define ECHOCTL 0001000
+#define ECHOPRT 0002000
+#define ECHOKE  0004000
+#define FLUSHO  0010000
+#define PENDIN  0040000
+#define EXTPROC 0200000
+
+#define XTABS  0014000
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/bits/user.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/bits/user.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/bits/user.h	(revision 331)
@@ -0,0 +1,36 @@
+typedef struct user_fpregs {
+	struct fp_reg {
+		unsigned sign1:1;
+		unsigned unused:15;
+		unsigned sign2:1;
+		unsigned exponent:14;
+		unsigned j:1;
+		unsigned mantissa1:31;
+		unsigned mantissa0:32;
+	} fpregs[8];
+	unsigned fpsr:32;
+	unsigned fpcr:32;
+	unsigned char ftype[8];
+	unsigned int init_flag;
+} elf_fpregset_t;
+
+struct user_regs {
+	unsigned long uregs[18];
+};
+#define ELF_NGREG 18
+typedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];
+
+struct user {
+	struct user_regs regs;
+	int u_fpvalid;
+	unsigned long u_tsize, u_dsize, u_ssize;
+	unsigned long start_code, start_stack;
+	long signal;
+	int reserved;
+	struct user_regs *u_ar0;
+	unsigned long magic;
+	char u_comm[32];
+	int u_debugreg[8];
+	struct user_fpregs u_fp;
+	struct user_fpregs *u_fp0;
+};
Index: EcnlProtoTool/trunk/musl-1.1.18/include/byteswap.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/byteswap.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/byteswap.h	(revision 331)
@@ -0,0 +1,26 @@
+#ifndef _BYTESWAP_H
+#define _BYTESWAP_H
+
+#include <features.h>
+#include <stdint.h>
+
+static __inline uint16_t __bswap_16(uint16_t __x)
+{
+	return __x<<8 | __x>>8;
+}
+
+static __inline uint32_t __bswap_32(uint32_t __x)
+{
+	return __x>>24 | __x>>8&0xff00 | __x<<8&0xff0000 | __x<<24;
+}
+
+static __inline uint64_t __bswap_64(uint64_t __x)
+{
+	return __bswap_32(__x)+0ULL<<32 | __bswap_32(__x>>32);
+}
+
+#define bswap_16(x) __bswap_16(x)
+#define bswap_32(x) __bswap_32(x)
+#define bswap_64(x) __bswap_64(x)
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/complex.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/complex.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/complex.h	(revision 331)
@@ -0,0 +1,133 @@
+#ifndef _COMPLEX_H
+#define _COMPLEX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define complex _Complex
+#ifdef __GNUC__
+#define _Complex_I (__extension__ (0.0f+1.0fi))
+#else
+#define _Complex_I (0.0f+1.0fi)
+#endif
+#define I _Complex_I
+
+double complex cacos(double complex);
+float complex cacosf(float complex);
+long double complex cacosl(long double complex);
+
+double complex casin(double complex);
+float complex casinf(float complex);
+long double complex casinl(long double complex);
+
+double complex catan(double complex);
+float complex catanf(float complex);
+long double complex catanl(long double complex);
+
+double complex ccos(double complex);
+float complex ccosf(float complex);
+long double complex ccosl(long double complex);
+
+double complex csin(double complex);
+float complex csinf(float complex);
+long double complex csinl(long double complex);
+
+double complex ctan(double complex);
+float complex ctanf(float complex);
+long double complex ctanl(long double complex);
+
+double complex cacosh(double complex);
+float complex cacoshf(float complex);
+long double complex cacoshl(long double complex);
+
+double complex casinh(double complex);
+float complex casinhf(float complex);
+long double complex casinhl(long double complex);
+
+double complex catanh(double complex);
+float complex catanhf(float complex);
+long double complex catanhl(long double complex);
+
+double complex ccosh(double complex);
+float complex ccoshf(float complex);
+long double complex ccoshl(long double complex);
+
+double complex csinh(double complex);
+float complex csinhf(float complex);
+long double complex csinhl(long double complex);
+
+double complex ctanh(double complex);
+float complex ctanhf(float complex);
+long double complex ctanhl(long double complex);
+
+double complex cexp(double complex);
+float complex cexpf(float complex);
+long double complex cexpl(long double complex);
+
+double complex clog(double complex);
+float complex clogf(float complex);
+long double complex clogl(long double complex);
+
+double cabs(double complex);
+float cabsf(float complex);
+long double cabsl(long double complex);
+
+double complex cpow(double complex, double complex);
+float complex cpowf(float complex, float complex);
+long double complex cpowl(long double complex, long double complex);
+
+double complex csqrt(double complex);
+float complex csqrtf(float complex);
+long double complex csqrtl(long double complex);
+
+double carg(double complex);
+float cargf(float complex);
+long double cargl(long double complex);
+
+double cimag(double complex);
+float cimagf(float complex);
+long double cimagl(long double complex);
+
+double complex conj(double complex);
+float complex conjf(float complex);
+long double complex conjl(long double complex);
+
+double complex cproj(double complex);
+float complex cprojf(float complex);
+long double complex cprojl(long double complex);
+
+double creal(double complex);
+float crealf(float complex);
+long double creall(long double complex);
+
+#ifndef __cplusplus
+#define __CIMAG(x, t) \
+	(+(union { _Complex t __z; t __xy[2]; }){(_Complex t)(x)}.__xy[1])
+
+#define creal(x) ((double)(x))
+#define crealf(x) ((float)(x))
+#define creall(x) ((long double)(x))
+
+#define cimag(x) __CIMAG(x, double)
+#define cimagf(x) __CIMAG(x, float)
+#define cimagl(x) __CIMAG(x, long double)
+#endif
+
+#if __STDC_VERSION__ >= 201112L
+#if defined(_Imaginary_I)
+#define __CMPLX(x, y, t) ((t)(x) + _Imaginary_I*(t)(y))
+#elif defined(__clang__)
+#define __CMPLX(x, y, t) (+(_Complex t){ (t)(x), (t)(y) })
+#else
+#define __CMPLX(x, y, t) (__builtin_complex((t)(x), (t)(y)))
+#endif
+#define CMPLX(x, y) __CMPLX(x, y, double)
+#define CMPLXF(x, y) __CMPLX(x, y, float)
+#define CMPLXL(x, y) __CMPLX(x, y, long double)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/cpio.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/cpio.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/cpio.h	(revision 331)
@@ -0,0 +1,29 @@
+#ifndef _CPIO_H
+#define _CPIO_H
+
+#define MAGIC "070707"
+
+#define C_IRUSR  000400
+#define C_IWUSR  000200
+#define C_IXUSR  000100
+#define C_IRGRP  000040
+#define C_IWGRP  000020
+#define C_IXGRP  000010
+#define C_IROTH  000004
+#define C_IWOTH  000002
+#define C_IXOTH  000001
+
+#define C_ISUID  004000
+#define C_ISGID  002000
+#define C_ISVTX  001000
+
+#define C_ISBLK  060000
+#define C_ISCHR  020000
+#define C_ISDIR  040000
+#define C_ISFIFO 010000
+#define C_ISSOCK 0140000
+#define C_ISLNK  0120000
+#define C_ISCTG  0110000
+#define C_ISREG  0100000
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/crypt.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/crypt.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/crypt.h	(revision 331)
@@ -0,0 +1,20 @@
+#ifndef _CRYPT_H
+#define _CRYPT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct crypt_data {
+	int initialized;
+	char __buf[256];
+};
+
+char *crypt(const char *, const char *);
+char *crypt_r(const char *, const char *, struct crypt_data *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/ctype.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/ctype.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/ctype.h	(revision 331)
@@ -0,0 +1,75 @@
+#ifndef	_CTYPE_H
+#define	_CTYPE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+int   isalnum(int);
+int   isalpha(int);
+int   isblank(int);
+int   iscntrl(int);
+int   isdigit(int);
+int   isgraph(int);
+int   islower(int);
+int   isprint(int);
+int   ispunct(int);
+int   isspace(int);
+int   isupper(int);
+int   isxdigit(int);
+int   tolower(int);
+int   toupper(int);
+
+#ifndef __cplusplus
+static __inline int __isspace(int _c)
+{
+	return _c == ' ' || (unsigned)_c-'\t' < 5;
+}
+
+#define isalpha(a) (0 ? isalpha(a) : (((unsigned)(a)|32)-'a') < 26)
+#define isdigit(a) (0 ? isdigit(a) : ((unsigned)(a)-'0') < 10)
+#define islower(a) (0 ? islower(a) : ((unsigned)(a)-'a') < 26)
+#define isupper(a) (0 ? isupper(a) : ((unsigned)(a)-'A') < 26)
+#define isprint(a) (0 ? isprint(a) : ((unsigned)(a)-0x20) < 0x5f)
+#define isgraph(a) (0 ? isgraph(a) : ((unsigned)(a)-0x21) < 0x5e)
+#define isspace(a) __isspace(a)
+#endif
+
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+
+#define __NEED_locale_t
+#include <bits/alltypes.h>
+
+int   isalnum_l(int, locale_t);
+int   isalpha_l(int, locale_t);
+int   isblank_l(int, locale_t);
+int   iscntrl_l(int, locale_t);
+int   isdigit_l(int, locale_t);
+int   isgraph_l(int, locale_t);
+int   islower_l(int, locale_t);
+int   isprint_l(int, locale_t);
+int   ispunct_l(int, locale_t);
+int   isspace_l(int, locale_t);
+int   isupper_l(int, locale_t);
+int   isxdigit_l(int, locale_t);
+int   tolower_l(int, locale_t);
+int   toupper_l(int, locale_t);
+
+int   isascii(int);
+int   toascii(int);
+#define _tolower(a) ((a)|0x20)
+#define _toupper(a) ((a)&0x5f)
+#define isascii(a) (0 ? isascii(a) : (unsigned)(a) < 128)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/dirent.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/dirent.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/dirent.h	(revision 331)
@@ -0,0 +1,81 @@
+#ifndef	_DIRENT_H
+#define	_DIRENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_ino_t
+#define __NEED_off_t
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#define __NEED_size_t
+#endif
+
+#include <bits/alltypes.h>
+
+typedef struct __dirstream DIR;
+
+struct dirent {
+	ino_t d_ino;
+	off_t d_off;
+	unsigned short d_reclen;
+	unsigned char d_type;
+	char d_name[256];
+};
+
+#define d_fileno d_ino
+
+int            closedir(DIR *);
+DIR           *fdopendir(int);
+DIR           *opendir(const char *);
+struct dirent *readdir(DIR *);
+int            readdir_r(DIR *__restrict, struct dirent *__restrict, struct dirent **__restrict);
+void           rewinddir(DIR *);
+int            dirfd(DIR *);
+
+int alphasort(const struct dirent **, const struct dirent **);
+int scandir(const char *, struct dirent ***, int (*)(const struct dirent *), int (*)(const struct dirent **, const struct dirent **));
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+void           seekdir(DIR *, long);
+long           telldir(DIR *);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define DT_UNKNOWN 0
+#define DT_FIFO 1
+#define DT_CHR 2
+#define DT_DIR 4
+#define DT_BLK 6
+#define DT_REG 8
+#define DT_LNK 10
+#define DT_SOCK 12
+#define DT_WHT 14
+#define IFTODT(x) ((x)>>12 & 017)
+#define DTTOIF(x) ((x)<<12)
+int getdents(int, struct dirent *, size_t);
+#endif
+
+#ifdef _GNU_SOURCE
+int versionsort(const struct dirent **, const struct dirent **);
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define dirent64 dirent
+#define readdir64 readdir
+#define readdir64_r readdir_r
+#define scandir64 scandir
+#define alphasort64 alphasort
+#define versionsort64 versionsort
+#define off64_t off_t
+#define ino64_t ino_t
+#define getdents64 getdents
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/dlfcn.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/dlfcn.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/dlfcn.h	(revision 331)
@@ -0,0 +1,42 @@
+#ifndef	_DLFCN_H
+#define	_DLFCN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define RTLD_LAZY   1
+#define RTLD_NOW    2
+#define RTLD_NOLOAD 4
+#define RTLD_NODELETE 4096
+#define RTLD_GLOBAL 256
+#define RTLD_LOCAL  0
+
+#define RTLD_NEXT    ((void *)-1)
+#define RTLD_DEFAULT ((void *)0)
+
+#define RTLD_DI_LINKMAP 2
+
+int    dlclose(void *);
+char  *dlerror(void);
+void  *dlopen(const char *, int);
+void  *dlsym(void *__restrict, const char *__restrict);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef struct {
+	const char *dli_fname;
+	void *dli_fbase;
+	const char *dli_sname;
+	void *dli_saddr;
+} Dl_info;
+int dladdr(const void *, Dl_info *);
+int dlinfo(void *, int, void *);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/elf.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/elf.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/elf.h	(revision 331)
@@ -0,0 +1,3121 @@
+#ifndef _ELF_H
+#define _ELF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+typedef uint16_t Elf32_Half;
+typedef uint16_t Elf64_Half;
+
+typedef uint32_t Elf32_Word;
+typedef	int32_t  Elf32_Sword;
+typedef uint32_t Elf64_Word;
+typedef	int32_t  Elf64_Sword;
+
+typedef uint64_t Elf32_Xword;
+typedef	int64_t  Elf32_Sxword;
+typedef uint64_t Elf64_Xword;
+typedef	int64_t  Elf64_Sxword;
+
+typedef uint32_t Elf32_Addr;
+typedef uint64_t Elf64_Addr;
+
+typedef uint32_t Elf32_Off;
+typedef uint64_t Elf64_Off;
+
+typedef uint16_t Elf32_Section;
+typedef uint16_t Elf64_Section;
+
+typedef Elf32_Half Elf32_Versym;
+typedef Elf64_Half Elf64_Versym;
+
+#define EI_NIDENT (16)
+
+typedef struct {
+  unsigned char	e_ident[EI_NIDENT];
+  Elf32_Half	e_type;
+  Elf32_Half	e_machine;
+  Elf32_Word	e_version;
+  Elf32_Addr	e_entry;
+  Elf32_Off	e_phoff;
+  Elf32_Off	e_shoff;
+  Elf32_Word	e_flags;
+  Elf32_Half	e_ehsize;
+  Elf32_Half	e_phentsize;
+  Elf32_Half	e_phnum;
+  Elf32_Half	e_shentsize;
+  Elf32_Half	e_shnum;
+  Elf32_Half	e_shstrndx;
+} Elf32_Ehdr;
+
+typedef struct {
+  unsigned char	e_ident[EI_NIDENT];
+  Elf64_Half	e_type;
+  Elf64_Half	e_machine;
+  Elf64_Word	e_version;
+  Elf64_Addr	e_entry;
+  Elf64_Off	e_phoff;
+  Elf64_Off	e_shoff;
+  Elf64_Word	e_flags;
+  Elf64_Half	e_ehsize;
+  Elf64_Half	e_phentsize;
+  Elf64_Half	e_phnum;
+  Elf64_Half	e_shentsize;
+  Elf64_Half	e_shnum;
+  Elf64_Half	e_shstrndx;
+} Elf64_Ehdr;
+
+#define EI_MAG0		0
+#define ELFMAG0		0x7f
+
+#define EI_MAG1		1
+#define ELFMAG1		'E'
+
+#define EI_MAG2		2
+#define ELFMAG2		'L'
+
+#define EI_MAG3		3
+#define ELFMAG3		'F'
+
+
+#define	ELFMAG		"\177ELF"
+#define	SELFMAG		4
+
+#define EI_CLASS	4
+#define ELFCLASSNONE	0
+#define ELFCLASS32	1
+#define ELFCLASS64	2
+#define ELFCLASSNUM	3
+
+#define EI_DATA		5
+#define ELFDATANONE	0
+#define ELFDATA2LSB	1
+#define ELFDATA2MSB	2
+#define ELFDATANUM	3
+
+#define EI_VERSION	6
+
+
+#define EI_OSABI	7
+#define ELFOSABI_NONE		0
+#define ELFOSABI_SYSV		0
+#define ELFOSABI_HPUX		1
+#define ELFOSABI_NETBSD		2
+#define ELFOSABI_LINUX		3
+#define ELFOSABI_GNU		3
+#define ELFOSABI_SOLARIS	6
+#define ELFOSABI_AIX		7
+#define ELFOSABI_IRIX		8
+#define ELFOSABI_FREEBSD	9
+#define ELFOSABI_TRU64		10
+#define ELFOSABI_MODESTO	11
+#define ELFOSABI_OPENBSD	12
+#define ELFOSABI_ARM		97
+#define ELFOSABI_STANDALONE	255
+
+#define EI_ABIVERSION	8
+
+#define EI_PAD		9
+
+
+
+#define ET_NONE		0
+#define ET_REL		1
+#define ET_EXEC		2
+#define ET_DYN		3
+#define ET_CORE		4
+#define	ET_NUM		5
+#define ET_LOOS		0xfe00
+#define ET_HIOS		0xfeff
+#define ET_LOPROC	0xff00
+#define ET_HIPROC	0xffff
+
+
+
+#define EM_NONE		 0
+#define EM_M32		 1
+#define EM_SPARC	 2
+#define EM_386		 3
+#define EM_68K		 4
+#define EM_88K		 5
+#define EM_860		 7
+#define EM_MIPS		 8
+#define EM_S370		 9
+#define EM_MIPS_RS3_LE	10
+
+#define EM_PARISC	15
+#define EM_VPP500	17
+#define EM_SPARC32PLUS	18
+#define EM_960		19
+#define EM_PPC		20
+#define EM_PPC64	21
+#define EM_S390		22
+
+#define EM_V800		36
+#define EM_FR20		37
+#define EM_RH32		38
+#define EM_RCE		39
+#define EM_ARM		40
+#define EM_FAKE_ALPHA	41
+#define EM_SH		42
+#define EM_SPARCV9	43
+#define EM_TRICORE	44
+#define EM_ARC		45
+#define EM_H8_300	46
+#define EM_H8_300H	47
+#define EM_H8S		48
+#define EM_H8_500	49
+#define EM_IA_64	50
+#define EM_MIPS_X	51
+#define EM_COLDFIRE	52
+#define EM_68HC12	53
+#define EM_MMA		54
+#define EM_PCP		55
+#define EM_NCPU		56
+#define EM_NDR1		57
+#define EM_STARCORE	58
+#define EM_ME16		59
+#define EM_ST100	60
+#define EM_TINYJ	61
+#define EM_X86_64	62
+#define EM_PDSP		63
+
+#define EM_FX66		66
+#define EM_ST9PLUS	67
+#define EM_ST7		68
+#define EM_68HC16	69
+#define EM_68HC11	70
+#define EM_68HC08	71
+#define EM_68HC05	72
+#define EM_SVX		73
+#define EM_ST19		74
+#define EM_VAX		75
+#define EM_CRIS		76
+#define EM_JAVELIN	77
+#define EM_FIREPATH	78
+#define EM_ZSP		79
+#define EM_MMIX		80
+#define EM_HUANY	81
+#define EM_PRISM	82
+#define EM_AVR		83
+#define EM_FR30		84
+#define EM_D10V		85
+#define EM_D30V		86
+#define EM_V850		87
+#define EM_M32R		88
+#define EM_MN10300	89
+#define EM_MN10200	90
+#define EM_PJ		91
+#define EM_OR1K		92
+#define EM_OPENRISC	92
+#define EM_ARC_A5	93
+#define EM_ARC_COMPACT	93
+#define EM_XTENSA	94
+#define EM_VIDEOCORE	95
+#define EM_TMM_GPP	96
+#define EM_NS32K	97
+#define EM_TPC		98
+#define EM_SNP1K	99
+#define EM_ST200	100
+#define EM_IP2K		101
+#define EM_MAX		102
+#define EM_CR		103
+#define EM_F2MC16	104
+#define EM_MSP430	105
+#define EM_BLACKFIN	106
+#define EM_SE_C33	107
+#define EM_SEP		108
+#define EM_ARCA		109
+#define EM_UNICORE	110
+#define EM_EXCESS	111
+#define EM_DXP		112
+#define EM_ALTERA_NIOS2 113
+#define EM_CRX		114
+#define EM_XGATE	115
+#define EM_C166		116
+#define EM_M16C		117
+#define EM_DSPIC30F	118
+#define EM_CE		119
+#define EM_M32C		120
+#define EM_TSK3000	131
+#define EM_RS08		132
+#define EM_SHARC	133
+#define EM_ECOG2	134
+#define EM_SCORE7	135
+#define EM_DSP24	136
+#define EM_VIDEOCORE3	137
+#define EM_LATTICEMICO32 138
+#define EM_SE_C17	139
+#define EM_TI_C6000	140
+#define EM_TI_C2000	141
+#define EM_TI_C5500	142
+#define EM_TI_ARP32	143
+#define EM_TI_PRU	144
+#define EM_MMDSP_PLUS	160
+#define EM_CYPRESS_M8C	161
+#define EM_R32C		162
+#define EM_TRIMEDIA	163
+#define EM_QDSP6	164
+#define EM_8051		165
+#define EM_STXP7X	166
+#define EM_NDS32	167
+#define EM_ECOG1X	168
+#define EM_MAXQ30	169
+#define EM_XIMO16	170
+#define EM_MANIK	171
+#define EM_CRAYNV2	172
+#define EM_RX		173
+#define EM_METAG	174
+#define EM_MCST_ELBRUS	175
+#define EM_ECOG16	176
+#define EM_CR16		177
+#define EM_ETPU		178
+#define EM_SLE9X	179
+#define EM_L10M		180
+#define EM_K10M		181
+#define EM_AARCH64	183
+#define EM_AVR32	185
+#define EM_STM8		186
+#define EM_TILE64	187
+#define EM_TILEPRO	188
+#define EM_MICROBLAZE	189
+#define EM_CUDA		190
+#define EM_TILEGX	191
+#define EM_CLOUDSHIELD	192
+#define EM_COREA_1ST	193
+#define EM_COREA_2ND	194
+#define EM_ARC_COMPACT2	195
+#define EM_OPEN8	196
+#define EM_RL78		197
+#define EM_VIDEOCORE5	198
+#define EM_78KOR	199
+#define EM_56800EX	200
+#define EM_BA1		201
+#define EM_BA2		202
+#define EM_XCORE	203
+#define EM_MCHP_PIC	204
+#define EM_KM32		210
+#define EM_KMX32	211
+#define EM_EMX16	212
+#define EM_EMX8		213
+#define EM_KVARC	214
+#define EM_CDP		215
+#define EM_COGE		216
+#define EM_COOL		217
+#define EM_NORC		218
+#define EM_CSR_KALIMBA	219
+#define EM_Z80		220
+#define EM_VISIUM	221
+#define EM_FT32		222
+#define EM_MOXIE	223
+#define EM_AMDGPU	224
+#define EM_RISCV	243
+#define EM_BPF		247
+#define EM_NUM		248
+
+#define EM_ALPHA	0x9026
+
+#define EV_NONE		0
+#define EV_CURRENT	1
+#define EV_NUM		2
+
+typedef struct {
+  Elf32_Word	sh_name;
+  Elf32_Word	sh_type;
+  Elf32_Word	sh_flags;
+  Elf32_Addr	sh_addr;
+  Elf32_Off	sh_offset;
+  Elf32_Word	sh_size;
+  Elf32_Word	sh_link;
+  Elf32_Word	sh_info;
+  Elf32_Word	sh_addralign;
+  Elf32_Word	sh_entsize;
+} Elf32_Shdr;
+
+typedef struct {
+  Elf64_Word	sh_name;
+  Elf64_Word	sh_type;
+  Elf64_Xword	sh_flags;
+  Elf64_Addr	sh_addr;
+  Elf64_Off	sh_offset;
+  Elf64_Xword	sh_size;
+  Elf64_Word	sh_link;
+  Elf64_Word	sh_info;
+  Elf64_Xword	sh_addralign;
+  Elf64_Xword	sh_entsize;
+} Elf64_Shdr;
+
+
+
+#define SHN_UNDEF	0
+#define SHN_LORESERVE	0xff00
+#define SHN_LOPROC	0xff00
+#define SHN_BEFORE	0xff00
+
+#define SHN_AFTER	0xff01
+
+#define SHN_HIPROC	0xff1f
+#define SHN_LOOS	0xff20
+#define SHN_HIOS	0xff3f
+#define SHN_ABS		0xfff1
+#define SHN_COMMON	0xfff2
+#define SHN_XINDEX	0xffff
+#define SHN_HIRESERVE	0xffff
+
+
+
+#define SHT_NULL	  0
+#define SHT_PROGBITS	  1
+#define SHT_SYMTAB	  2
+#define SHT_STRTAB	  3
+#define SHT_RELA	  4
+#define SHT_HASH	  5
+#define SHT_DYNAMIC	  6
+#define SHT_NOTE	  7
+#define SHT_NOBITS	  8
+#define SHT_REL		  9
+#define SHT_SHLIB	  10
+#define SHT_DYNSYM	  11
+#define SHT_INIT_ARRAY	  14
+#define SHT_FINI_ARRAY	  15
+#define SHT_PREINIT_ARRAY 16
+#define SHT_GROUP	  17
+#define SHT_SYMTAB_SHNDX  18
+#define	SHT_NUM		  19
+#define SHT_LOOS	  0x60000000
+#define SHT_GNU_ATTRIBUTES 0x6ffffff5
+#define SHT_GNU_HASH	  0x6ffffff6
+#define SHT_GNU_LIBLIST	  0x6ffffff7
+#define SHT_CHECKSUM	  0x6ffffff8
+#define SHT_LOSUNW	  0x6ffffffa
+#define SHT_SUNW_move	  0x6ffffffa
+#define SHT_SUNW_COMDAT   0x6ffffffb
+#define SHT_SUNW_syminfo  0x6ffffffc
+#define SHT_GNU_verdef	  0x6ffffffd
+#define SHT_GNU_verneed	  0x6ffffffe
+#define SHT_GNU_versym	  0x6fffffff
+#define SHT_HISUNW	  0x6fffffff
+#define SHT_HIOS	  0x6fffffff
+#define SHT_LOPROC	  0x70000000
+#define SHT_HIPROC	  0x7fffffff
+#define SHT_LOUSER	  0x80000000
+#define SHT_HIUSER	  0x8fffffff
+
+#define SHF_WRITE	     (1 << 0)
+#define SHF_ALLOC	     (1 << 1)
+#define SHF_EXECINSTR	     (1 << 2)
+#define SHF_MERGE	     (1 << 4)
+#define SHF_STRINGS	     (1 << 5)
+#define SHF_INFO_LINK	     (1 << 6)
+#define SHF_LINK_ORDER	     (1 << 7)
+#define SHF_OS_NONCONFORMING (1 << 8)
+
+#define SHF_GROUP	     (1 << 9)
+#define SHF_TLS		     (1 << 10)
+#define SHF_COMPRESSED	     (1 << 11)
+#define SHF_MASKOS	     0x0ff00000
+#define SHF_MASKPROC	     0xf0000000
+#define SHF_ORDERED	     (1 << 30)
+#define SHF_EXCLUDE	     (1U << 31)
+
+typedef struct {
+  Elf32_Word	ch_type;
+  Elf32_Word	ch_size;
+  Elf32_Word	ch_addralign;
+} Elf32_Chdr;
+
+typedef struct {
+  Elf64_Word	ch_type;
+  Elf64_Word	ch_reserved;
+  Elf64_Xword	ch_size;
+  Elf64_Xword	ch_addralign;
+} Elf64_Chdr;
+
+#define ELFCOMPRESS_ZLIB	1
+#define ELFCOMPRESS_LOOS	0x60000000
+#define ELFCOMPRESS_HIOS	0x6fffffff
+#define ELFCOMPRESS_LOPROC	0x70000000
+#define ELFCOMPRESS_HIPROC	0x7fffffff
+
+
+#define GRP_COMDAT	0x1
+
+typedef struct {
+  Elf32_Word	st_name;
+  Elf32_Addr	st_value;
+  Elf32_Word	st_size;
+  unsigned char	st_info;
+  unsigned char	st_other;
+  Elf32_Section	st_shndx;
+} Elf32_Sym;
+
+typedef struct {
+  Elf64_Word	st_name;
+  unsigned char	st_info;
+  unsigned char st_other;
+  Elf64_Section	st_shndx;
+  Elf64_Addr	st_value;
+  Elf64_Xword	st_size;
+} Elf64_Sym;
+
+typedef struct {
+  Elf32_Half si_boundto;
+  Elf32_Half si_flags;
+} Elf32_Syminfo;
+
+typedef struct {
+  Elf64_Half si_boundto;
+  Elf64_Half si_flags;
+} Elf64_Syminfo;
+
+#define SYMINFO_BT_SELF		0xffff
+#define SYMINFO_BT_PARENT	0xfffe
+#define SYMINFO_BT_LOWRESERVE	0xff00
+
+#define SYMINFO_FLG_DIRECT	0x0001
+#define SYMINFO_FLG_PASSTHRU	0x0002
+#define SYMINFO_FLG_COPY	0x0004
+#define SYMINFO_FLG_LAZYLOAD	0x0008
+
+#define SYMINFO_NONE		0
+#define SYMINFO_CURRENT		1
+#define SYMINFO_NUM		2
+
+#define ELF32_ST_BIND(val)		(((unsigned char) (val)) >> 4)
+#define ELF32_ST_TYPE(val)		((val) & 0xf)
+#define ELF32_ST_INFO(bind, type)	(((bind) << 4) + ((type) & 0xf))
+
+#define ELF64_ST_BIND(val)		ELF32_ST_BIND (val)
+#define ELF64_ST_TYPE(val)		ELF32_ST_TYPE (val)
+#define ELF64_ST_INFO(bind, type)	ELF32_ST_INFO ((bind), (type))
+
+#define STB_LOCAL	0
+#define STB_GLOBAL	1
+#define STB_WEAK	2
+#define	STB_NUM		3
+#define STB_LOOS	10
+#define STB_GNU_UNIQUE	10
+#define STB_HIOS	12
+#define STB_LOPROC	13
+#define STB_HIPROC	15
+
+#define STT_NOTYPE	0
+#define STT_OBJECT	1
+#define STT_FUNC	2
+#define STT_SECTION	3
+#define STT_FILE	4
+#define STT_COMMON	5
+#define STT_TLS		6
+#define	STT_NUM		7
+#define STT_LOOS	10
+#define STT_GNU_IFUNC	10
+#define STT_HIOS	12
+#define STT_LOPROC	13
+#define STT_HIPROC	15
+
+#define STN_UNDEF	0
+
+#define ELF32_ST_VISIBILITY(o)	((o) & 0x03)
+#define ELF64_ST_VISIBILITY(o)	ELF32_ST_VISIBILITY (o)
+
+#define STV_DEFAULT	0
+#define STV_INTERNAL	1
+#define STV_HIDDEN	2
+#define STV_PROTECTED	3
+
+
+
+
+typedef struct {
+  Elf32_Addr	r_offset;
+  Elf32_Word	r_info;
+} Elf32_Rel;
+
+typedef struct {
+  Elf64_Addr	r_offset;
+  Elf64_Xword	r_info;
+} Elf64_Rel;
+
+
+
+typedef struct {
+  Elf32_Addr	r_offset;
+  Elf32_Word	r_info;
+  Elf32_Sword	r_addend;
+} Elf32_Rela;
+
+typedef struct {
+  Elf64_Addr	r_offset;
+  Elf64_Xword	r_info;
+  Elf64_Sxword	r_addend;
+} Elf64_Rela;
+
+
+
+#define ELF32_R_SYM(val)		((val) >> 8)
+#define ELF32_R_TYPE(val)		((val) & 0xff)
+#define ELF32_R_INFO(sym, type)		(((sym) << 8) + ((type) & 0xff))
+
+#define ELF64_R_SYM(i)			((i) >> 32)
+#define ELF64_R_TYPE(i)			((i) & 0xffffffff)
+#define ELF64_R_INFO(sym,type)		((((Elf64_Xword) (sym)) << 32) + (type))
+
+
+
+typedef struct {
+  Elf32_Word	p_type;
+  Elf32_Off	p_offset;
+  Elf32_Addr	p_vaddr;
+  Elf32_Addr	p_paddr;
+  Elf32_Word	p_filesz;
+  Elf32_Word	p_memsz;
+  Elf32_Word	p_flags;
+  Elf32_Word	p_align;
+} Elf32_Phdr;
+
+typedef struct {
+  Elf64_Word	p_type;
+  Elf64_Word	p_flags;
+  Elf64_Off	p_offset;
+  Elf64_Addr	p_vaddr;
+  Elf64_Addr	p_paddr;
+  Elf64_Xword	p_filesz;
+  Elf64_Xword	p_memsz;
+  Elf64_Xword	p_align;
+} Elf64_Phdr;
+
+
+
+#define	PT_NULL		0
+#define PT_LOAD		1
+#define PT_DYNAMIC	2
+#define PT_INTERP	3
+#define PT_NOTE		4
+#define PT_SHLIB	5
+#define PT_PHDR		6
+#define PT_TLS		7
+#define	PT_NUM		8
+#define PT_LOOS		0x60000000
+#define PT_GNU_EH_FRAME	0x6474e550
+#define PT_GNU_STACK	0x6474e551
+#define PT_GNU_RELRO	0x6474e552
+#define PT_LOSUNW	0x6ffffffa
+#define PT_SUNWBSS	0x6ffffffa
+#define PT_SUNWSTACK	0x6ffffffb
+#define PT_HISUNW	0x6fffffff
+#define PT_HIOS		0x6fffffff
+#define PT_LOPROC	0x70000000
+#define PT_HIPROC	0x7fffffff
+
+
+#define PN_XNUM 0xffff
+
+
+#define PF_X		(1 << 0)
+#define PF_W		(1 << 1)
+#define PF_R		(1 << 2)
+#define PF_MASKOS	0x0ff00000
+#define PF_MASKPROC	0xf0000000
+
+
+
+#define NT_PRSTATUS	1
+#define NT_FPREGSET	2
+#define NT_PRPSINFO	3
+#define NT_PRXREG	4
+#define NT_TASKSTRUCT	4
+#define NT_PLATFORM	5
+#define NT_AUXV		6
+#define NT_GWINDOWS	7
+#define NT_ASRS		8
+#define NT_PSTATUS	10
+#define NT_PSINFO	13
+#define NT_PRCRED	14
+#define NT_UTSNAME	15
+#define NT_LWPSTATUS	16
+#define NT_LWPSINFO	17
+#define NT_PRFPXREG	20
+#define NT_SIGINFO	0x53494749
+#define NT_FILE		0x46494c45
+#define NT_PRXFPREG	0x46e62b7f
+#define NT_PPC_VMX	0x100
+#define NT_PPC_SPE	0x101
+#define NT_PPC_VSX	0x102
+#define NT_386_TLS	0x200
+#define NT_386_IOPERM	0x201
+#define NT_X86_XSTATE	0x202
+#define NT_S390_HIGH_GPRS	0x300
+#define NT_S390_TIMER	0x301
+#define NT_S390_TODCMP	0x302
+#define NT_S390_TODPREG	0x303
+#define NT_S390_CTRS	0x304
+#define NT_S390_PREFIX	0x305
+#define NT_S390_LAST_BREAK	0x306
+#define NT_S390_SYSTEM_CALL	0x307
+#define NT_S390_TDB	0x308
+#define NT_ARM_VFP	0x400
+#define NT_ARM_TLS	0x401
+#define NT_ARM_HW_BREAK	0x402
+#define NT_ARM_HW_WATCH	0x403
+#define NT_ARM_SYSTEM_CALL	0x404
+#define NT_METAG_CBUF	0x500
+#define NT_METAG_RPIPE	0x501
+#define NT_METAG_TLS	0x502
+#define NT_VERSION	1
+
+
+
+
+typedef struct {
+  Elf32_Sword d_tag;
+  union {
+      Elf32_Word d_val;
+      Elf32_Addr d_ptr;
+  } d_un;
+} Elf32_Dyn;
+
+typedef struct {
+  Elf64_Sxword d_tag;
+  union {
+      Elf64_Xword d_val;
+      Elf64_Addr d_ptr;
+  } d_un;
+} Elf64_Dyn;
+
+
+
+#define DT_NULL		0
+#define DT_NEEDED	1
+#define DT_PLTRELSZ	2
+#define DT_PLTGOT	3
+#define DT_HASH		4
+#define DT_STRTAB	5
+#define DT_SYMTAB	6
+#define DT_RELA		7
+#define DT_RELASZ	8
+#define DT_RELAENT	9
+#define DT_STRSZ	10
+#define DT_SYMENT	11
+#define DT_INIT		12
+#define DT_FINI		13
+#define DT_SONAME	14
+#define DT_RPATH	15
+#define DT_SYMBOLIC	16
+#define DT_REL		17
+#define DT_RELSZ	18
+#define DT_RELENT	19
+#define DT_PLTREL	20
+#define DT_DEBUG	21
+#define DT_TEXTREL	22
+#define DT_JMPREL	23
+#define	DT_BIND_NOW	24
+#define	DT_INIT_ARRAY	25
+#define	DT_FINI_ARRAY	26
+#define	DT_INIT_ARRAYSZ	27
+#define	DT_FINI_ARRAYSZ	28
+#define DT_RUNPATH	29
+#define DT_FLAGS	30
+#define DT_ENCODING	32
+#define DT_PREINIT_ARRAY 32
+#define DT_PREINIT_ARRAYSZ 33
+#define	DT_NUM		34
+#define DT_LOOS		0x6000000d
+#define DT_HIOS		0x6ffff000
+#define DT_LOPROC	0x70000000
+#define DT_HIPROC	0x7fffffff
+#define	DT_PROCNUM	DT_MIPS_NUM
+
+#define DT_VALRNGLO	0x6ffffd00
+#define DT_GNU_PRELINKED 0x6ffffdf5
+#define DT_GNU_CONFLICTSZ 0x6ffffdf6
+#define DT_GNU_LIBLISTSZ 0x6ffffdf7
+#define DT_CHECKSUM	0x6ffffdf8
+#define DT_PLTPADSZ	0x6ffffdf9
+#define DT_MOVEENT	0x6ffffdfa
+#define DT_MOVESZ	0x6ffffdfb
+#define DT_FEATURE_1	0x6ffffdfc
+#define DT_POSFLAG_1	0x6ffffdfd
+
+#define DT_SYMINSZ	0x6ffffdfe
+#define DT_SYMINENT	0x6ffffdff
+#define DT_VALRNGHI	0x6ffffdff
+#define DT_VALTAGIDX(tag)	(DT_VALRNGHI - (tag))
+#define DT_VALNUM 12
+
+#define DT_ADDRRNGLO	0x6ffffe00
+#define DT_GNU_HASH	0x6ffffef5
+#define DT_TLSDESC_PLT	0x6ffffef6
+#define DT_TLSDESC_GOT	0x6ffffef7
+#define DT_GNU_CONFLICT	0x6ffffef8
+#define DT_GNU_LIBLIST	0x6ffffef9
+#define DT_CONFIG	0x6ffffefa
+#define DT_DEPAUDIT	0x6ffffefb
+#define DT_AUDIT	0x6ffffefc
+#define	DT_PLTPAD	0x6ffffefd
+#define	DT_MOVETAB	0x6ffffefe
+#define DT_SYMINFO	0x6ffffeff
+#define DT_ADDRRNGHI	0x6ffffeff
+#define DT_ADDRTAGIDX(tag)	(DT_ADDRRNGHI - (tag))
+#define DT_ADDRNUM 11
+
+
+
+#define DT_VERSYM	0x6ffffff0
+
+#define DT_RELACOUNT	0x6ffffff9
+#define DT_RELCOUNT	0x6ffffffa
+
+
+#define DT_FLAGS_1	0x6ffffffb
+#define	DT_VERDEF	0x6ffffffc
+
+#define	DT_VERDEFNUM	0x6ffffffd
+#define	DT_VERNEED	0x6ffffffe
+
+#define	DT_VERNEEDNUM	0x6fffffff
+#define DT_VERSIONTAGIDX(tag)	(DT_VERNEEDNUM - (tag))
+#define DT_VERSIONTAGNUM 16
+
+
+
+#define DT_AUXILIARY    0x7ffffffd
+#define DT_FILTER       0x7fffffff
+#define DT_EXTRATAGIDX(tag)	((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
+#define DT_EXTRANUM	3
+
+
+#define DF_ORIGIN	0x00000001
+#define DF_SYMBOLIC	0x00000002
+#define DF_TEXTREL	0x00000004
+#define DF_BIND_NOW	0x00000008
+#define DF_STATIC_TLS	0x00000010
+
+
+
+#define DF_1_NOW	0x00000001
+#define DF_1_GLOBAL	0x00000002
+#define DF_1_GROUP	0x00000004
+#define DF_1_NODELETE	0x00000008
+#define DF_1_LOADFLTR	0x00000010
+#define DF_1_INITFIRST	0x00000020
+#define DF_1_NOOPEN	0x00000040
+#define DF_1_ORIGIN	0x00000080
+#define DF_1_DIRECT	0x00000100
+#define DF_1_TRANS	0x00000200
+#define DF_1_INTERPOSE	0x00000400
+#define DF_1_NODEFLIB	0x00000800
+#define DF_1_NODUMP	0x00001000
+#define DF_1_CONFALT	0x00002000
+#define DF_1_ENDFILTEE	0x00004000
+#define	DF_1_DISPRELDNE	0x00008000
+#define	DF_1_DISPRELPND	0x00010000
+#define	DF_1_NODIRECT	0x00020000
+#define	DF_1_IGNMULDEF	0x00040000
+#define	DF_1_NOKSYMS	0x00080000
+#define	DF_1_NOHDR	0x00100000
+#define	DF_1_EDITED	0x00200000
+#define	DF_1_NORELOC	0x00400000
+#define	DF_1_SYMINTPOSE	0x00800000
+#define	DF_1_GLOBAUDIT	0x01000000
+#define	DF_1_SINGLETON	0x02000000
+
+#define DTF_1_PARINIT	0x00000001
+#define DTF_1_CONFEXP	0x00000002
+
+
+#define DF_P1_LAZYLOAD	0x00000001
+#define DF_P1_GROUPPERM	0x00000002
+
+
+
+
+typedef struct {
+  Elf32_Half	vd_version;
+  Elf32_Half	vd_flags;
+  Elf32_Half	vd_ndx;
+  Elf32_Half	vd_cnt;
+  Elf32_Word	vd_hash;
+  Elf32_Word	vd_aux;
+  Elf32_Word	vd_next;
+} Elf32_Verdef;
+
+typedef struct {
+  Elf64_Half	vd_version;
+  Elf64_Half	vd_flags;
+  Elf64_Half	vd_ndx;
+  Elf64_Half	vd_cnt;
+  Elf64_Word	vd_hash;
+  Elf64_Word	vd_aux;
+  Elf64_Word	vd_next;
+} Elf64_Verdef;
+
+
+
+#define VER_DEF_NONE	0
+#define VER_DEF_CURRENT	1
+#define VER_DEF_NUM	2
+
+
+#define VER_FLG_BASE	0x1
+#define VER_FLG_WEAK	0x2
+
+
+#define	VER_NDX_LOCAL		0
+#define	VER_NDX_GLOBAL		1
+#define	VER_NDX_LORESERVE	0xff00
+#define	VER_NDX_ELIMINATE	0xff01
+
+
+
+typedef struct {
+  Elf32_Word	vda_name;
+  Elf32_Word	vda_next;
+} Elf32_Verdaux;
+
+typedef struct {
+  Elf64_Word	vda_name;
+  Elf64_Word	vda_next;
+} Elf64_Verdaux;
+
+
+
+
+typedef struct {
+  Elf32_Half	vn_version;
+  Elf32_Half	vn_cnt;
+  Elf32_Word	vn_file;
+  Elf32_Word	vn_aux;
+  Elf32_Word	vn_next;
+} Elf32_Verneed;
+
+typedef struct {
+  Elf64_Half	vn_version;
+  Elf64_Half	vn_cnt;
+  Elf64_Word	vn_file;
+  Elf64_Word	vn_aux;
+  Elf64_Word	vn_next;
+} Elf64_Verneed;
+
+
+
+#define VER_NEED_NONE	 0
+#define VER_NEED_CURRENT 1
+#define VER_NEED_NUM	 2
+
+
+
+typedef struct {
+  Elf32_Word	vna_hash;
+  Elf32_Half	vna_flags;
+  Elf32_Half	vna_other;
+  Elf32_Word	vna_name;
+  Elf32_Word	vna_next;
+} Elf32_Vernaux;
+
+typedef struct {
+  Elf64_Word	vna_hash;
+  Elf64_Half	vna_flags;
+  Elf64_Half	vna_other;
+  Elf64_Word	vna_name;
+  Elf64_Word	vna_next;
+} Elf64_Vernaux;
+
+
+
+#define VER_FLG_WEAK	0x2
+
+
+
+typedef struct {
+  uint32_t a_type;
+  union {
+      uint32_t a_val;
+  } a_un;
+} Elf32_auxv_t;
+
+typedef struct {
+  uint64_t a_type;
+  union {
+      uint64_t a_val;
+  } a_un;
+} Elf64_auxv_t;
+
+
+
+#define AT_NULL		0
+#define AT_IGNORE	1
+#define AT_EXECFD	2
+#define AT_PHDR		3
+#define AT_PHENT	4
+#define AT_PHNUM	5
+#define AT_PAGESZ	6
+#define AT_BASE		7
+#define AT_FLAGS	8
+#define AT_ENTRY	9
+#define AT_NOTELF	10
+#define AT_UID		11
+#define AT_EUID		12
+#define AT_GID		13
+#define AT_EGID		14
+#define AT_CLKTCK	17
+
+
+#define AT_PLATFORM	15
+#define AT_HWCAP	16
+
+
+
+
+#define AT_FPUCW	18
+
+
+#define AT_DCACHEBSIZE	19
+#define AT_ICACHEBSIZE	20
+#define AT_UCACHEBSIZE	21
+
+
+
+#define AT_IGNOREPPC	22
+
+#define	AT_SECURE	23
+
+#define AT_BASE_PLATFORM 24
+
+#define AT_RANDOM	25
+
+#define AT_HWCAP2	26
+
+#define AT_EXECFN	31
+
+
+
+#define AT_SYSINFO	32
+#define AT_SYSINFO_EHDR	33
+
+
+
+#define AT_L1I_CACHESHAPE	34
+#define AT_L1D_CACHESHAPE	35
+#define AT_L2_CACHESHAPE	36
+#define AT_L3_CACHESHAPE	37
+
+
+
+
+typedef struct {
+  Elf32_Word n_namesz;
+  Elf32_Word n_descsz;
+  Elf32_Word n_type;
+} Elf32_Nhdr;
+
+typedef struct {
+  Elf64_Word n_namesz;
+  Elf64_Word n_descsz;
+  Elf64_Word n_type;
+} Elf64_Nhdr;
+
+
+
+
+#define ELF_NOTE_SOLARIS	"SUNW Solaris"
+
+
+#define ELF_NOTE_GNU		"GNU"
+
+
+
+
+
+#define ELF_NOTE_PAGESIZE_HINT	1
+
+
+#define NT_GNU_ABI_TAG	1
+#define ELF_NOTE_ABI	NT_GNU_ABI_TAG
+
+
+
+#define ELF_NOTE_OS_LINUX	0
+#define ELF_NOTE_OS_GNU		1
+#define ELF_NOTE_OS_SOLARIS2	2
+#define ELF_NOTE_OS_FREEBSD	3
+
+#define NT_GNU_BUILD_ID	3
+#define NT_GNU_GOLD_VERSION	4
+
+
+
+typedef struct {
+  Elf32_Xword m_value;
+  Elf32_Word m_info;
+  Elf32_Word m_poffset;
+  Elf32_Half m_repeat;
+  Elf32_Half m_stride;
+} Elf32_Move;
+
+typedef struct {
+  Elf64_Xword m_value;
+  Elf64_Xword m_info;
+  Elf64_Xword m_poffset;
+  Elf64_Half m_repeat;
+  Elf64_Half m_stride;
+} Elf64_Move;
+
+
+#define ELF32_M_SYM(info)	((info) >> 8)
+#define ELF32_M_SIZE(info)	((unsigned char) (info))
+#define ELF32_M_INFO(sym, size)	(((sym) << 8) + (unsigned char) (size))
+
+#define ELF64_M_SYM(info)	ELF32_M_SYM (info)
+#define ELF64_M_SIZE(info)	ELF32_M_SIZE (info)
+#define ELF64_M_INFO(sym, size)	ELF32_M_INFO (sym, size)
+
+#define EF_CPU32	0x00810000
+
+#define R_68K_NONE	0
+#define R_68K_32	1
+#define R_68K_16	2
+#define R_68K_8		3
+#define R_68K_PC32	4
+#define R_68K_PC16	5
+#define R_68K_PC8	6
+#define R_68K_GOT32	7
+#define R_68K_GOT16	8
+#define R_68K_GOT8	9
+#define R_68K_GOT32O	10
+#define R_68K_GOT16O	11
+#define R_68K_GOT8O	12
+#define R_68K_PLT32	13
+#define R_68K_PLT16	14
+#define R_68K_PLT8	15
+#define R_68K_PLT32O	16
+#define R_68K_PLT16O	17
+#define R_68K_PLT8O	18
+#define R_68K_COPY	19
+#define R_68K_GLOB_DAT	20
+#define R_68K_JMP_SLOT	21
+#define R_68K_RELATIVE	22
+#define R_68K_NUM	23
+
+#define R_386_NONE	   0
+#define R_386_32	   1
+#define R_386_PC32	   2
+#define R_386_GOT32	   3
+#define R_386_PLT32	   4
+#define R_386_COPY	   5
+#define R_386_GLOB_DAT	   6
+#define R_386_JMP_SLOT	   7
+#define R_386_RELATIVE	   8
+#define R_386_GOTOFF	   9
+#define R_386_GOTPC	   10
+#define R_386_32PLT	   11
+#define R_386_TLS_TPOFF	   14
+#define R_386_TLS_IE	   15
+#define R_386_TLS_GOTIE	   16
+#define R_386_TLS_LE	   17
+#define R_386_TLS_GD	   18
+#define R_386_TLS_LDM	   19
+#define R_386_16	   20
+#define R_386_PC16	   21
+#define R_386_8		   22
+#define R_386_PC8	   23
+#define R_386_TLS_GD_32	   24
+#define R_386_TLS_GD_PUSH  25
+#define R_386_TLS_GD_CALL  26
+#define R_386_TLS_GD_POP   27
+#define R_386_TLS_LDM_32   28
+#define R_386_TLS_LDM_PUSH 29
+#define R_386_TLS_LDM_CALL 30
+#define R_386_TLS_LDM_POP  31
+#define R_386_TLS_LDO_32   32
+#define R_386_TLS_IE_32	   33
+#define R_386_TLS_LE_32	   34
+#define R_386_TLS_DTPMOD32 35
+#define R_386_TLS_DTPOFF32 36
+#define R_386_TLS_TPOFF32  37
+#define R_386_SIZE32       38
+#define R_386_TLS_GOTDESC  39
+#define R_386_TLS_DESC_CALL 40
+#define R_386_TLS_DESC     41
+#define R_386_IRELATIVE	   42
+#define R_386_GOT32X	   43
+#define R_386_NUM	   44
+
+
+
+
+
+#define STT_SPARC_REGISTER	13
+
+
+
+#define EF_SPARCV9_MM		3
+#define EF_SPARCV9_TSO		0
+#define EF_SPARCV9_PSO		1
+#define EF_SPARCV9_RMO		2
+#define EF_SPARC_LEDATA		0x800000
+#define EF_SPARC_EXT_MASK	0xFFFF00
+#define EF_SPARC_32PLUS		0x000100
+#define EF_SPARC_SUN_US1	0x000200
+#define EF_SPARC_HAL_R1		0x000400
+#define EF_SPARC_SUN_US3	0x000800
+
+
+
+#define R_SPARC_NONE		0
+#define R_SPARC_8		1
+#define R_SPARC_16		2
+#define R_SPARC_32		3
+#define R_SPARC_DISP8		4
+#define R_SPARC_DISP16		5
+#define R_SPARC_DISP32		6
+#define R_SPARC_WDISP30		7
+#define R_SPARC_WDISP22		8
+#define R_SPARC_HI22		9
+#define R_SPARC_22		10
+#define R_SPARC_13		11
+#define R_SPARC_LO10		12
+#define R_SPARC_GOT10		13
+#define R_SPARC_GOT13		14
+#define R_SPARC_GOT22		15
+#define R_SPARC_PC10		16
+#define R_SPARC_PC22		17
+#define R_SPARC_WPLT30		18
+#define R_SPARC_COPY		19
+#define R_SPARC_GLOB_DAT	20
+#define R_SPARC_JMP_SLOT	21
+#define R_SPARC_RELATIVE	22
+#define R_SPARC_UA32		23
+
+
+
+#define R_SPARC_PLT32		24
+#define R_SPARC_HIPLT22		25
+#define R_SPARC_LOPLT10		26
+#define R_SPARC_PCPLT32		27
+#define R_SPARC_PCPLT22		28
+#define R_SPARC_PCPLT10		29
+#define R_SPARC_10		30
+#define R_SPARC_11		31
+#define R_SPARC_64		32
+#define R_SPARC_OLO10		33
+#define R_SPARC_HH22		34
+#define R_SPARC_HM10		35
+#define R_SPARC_LM22		36
+#define R_SPARC_PC_HH22		37
+#define R_SPARC_PC_HM10		38
+#define R_SPARC_PC_LM22		39
+#define R_SPARC_WDISP16		40
+#define R_SPARC_WDISP19		41
+#define R_SPARC_GLOB_JMP	42
+#define R_SPARC_7		43
+#define R_SPARC_5		44
+#define R_SPARC_6		45
+#define R_SPARC_DISP64		46
+#define R_SPARC_PLT64		47
+#define R_SPARC_HIX22		48
+#define R_SPARC_LOX10		49
+#define R_SPARC_H44		50
+#define R_SPARC_M44		51
+#define R_SPARC_L44		52
+#define R_SPARC_REGISTER	53
+#define R_SPARC_UA64		54
+#define R_SPARC_UA16		55
+#define R_SPARC_TLS_GD_HI22	56
+#define R_SPARC_TLS_GD_LO10	57
+#define R_SPARC_TLS_GD_ADD	58
+#define R_SPARC_TLS_GD_CALL	59
+#define R_SPARC_TLS_LDM_HI22	60
+#define R_SPARC_TLS_LDM_LO10	61
+#define R_SPARC_TLS_LDM_ADD	62
+#define R_SPARC_TLS_LDM_CALL	63
+#define R_SPARC_TLS_LDO_HIX22	64
+#define R_SPARC_TLS_LDO_LOX10	65
+#define R_SPARC_TLS_LDO_ADD	66
+#define R_SPARC_TLS_IE_HI22	67
+#define R_SPARC_TLS_IE_LO10	68
+#define R_SPARC_TLS_IE_LD	69
+#define R_SPARC_TLS_IE_LDX	70
+#define R_SPARC_TLS_IE_ADD	71
+#define R_SPARC_TLS_LE_HIX22	72
+#define R_SPARC_TLS_LE_LOX10	73
+#define R_SPARC_TLS_DTPMOD32	74
+#define R_SPARC_TLS_DTPMOD64	75
+#define R_SPARC_TLS_DTPOFF32	76
+#define R_SPARC_TLS_DTPOFF64	77
+#define R_SPARC_TLS_TPOFF32	78
+#define R_SPARC_TLS_TPOFF64	79
+#define R_SPARC_GOTDATA_HIX22	80
+#define R_SPARC_GOTDATA_LOX10	81
+#define R_SPARC_GOTDATA_OP_HIX22	82
+#define R_SPARC_GOTDATA_OP_LOX10	83
+#define R_SPARC_GOTDATA_OP	84
+#define R_SPARC_H34		85
+#define R_SPARC_SIZE32		86
+#define R_SPARC_SIZE64		87
+#define R_SPARC_GNU_VTINHERIT	250
+#define R_SPARC_GNU_VTENTRY	251
+#define R_SPARC_REV32		252
+
+#define R_SPARC_NUM		253
+
+
+
+#define DT_SPARC_REGISTER 0x70000001
+#define DT_SPARC_NUM	2
+
+
+#define EF_MIPS_NOREORDER   1
+#define EF_MIPS_PIC	    2
+#define EF_MIPS_CPIC	    4
+#define EF_MIPS_XGOT	    8
+#define EF_MIPS_64BIT_WHIRL 16
+#define EF_MIPS_ABI2	    32
+#define EF_MIPS_ABI_ON32    64
+#define EF_MIPS_FP64	    512
+#define EF_MIPS_NAN2008     1024
+#define EF_MIPS_ARCH	    0xf0000000
+
+
+
+#define EF_MIPS_ARCH_1	    0x00000000
+#define EF_MIPS_ARCH_2	    0x10000000
+#define EF_MIPS_ARCH_3	    0x20000000
+#define EF_MIPS_ARCH_4	    0x30000000
+#define EF_MIPS_ARCH_5	    0x40000000
+#define EF_MIPS_ARCH_32     0x50000000
+#define EF_MIPS_ARCH_64     0x60000000
+#define EF_MIPS_ARCH_32R2   0x70000000
+#define EF_MIPS_ARCH_64R2   0x80000000
+
+
+#define E_MIPS_ARCH_1	  0x00000000
+#define E_MIPS_ARCH_2	  0x10000000
+#define E_MIPS_ARCH_3	  0x20000000
+#define E_MIPS_ARCH_4	  0x30000000
+#define E_MIPS_ARCH_5	  0x40000000
+#define E_MIPS_ARCH_32	  0x50000000
+#define E_MIPS_ARCH_64	  0x60000000
+
+
+
+#define SHN_MIPS_ACOMMON    0xff00
+#define SHN_MIPS_TEXT	    0xff01
+#define SHN_MIPS_DATA	    0xff02
+#define SHN_MIPS_SCOMMON    0xff03
+#define SHN_MIPS_SUNDEFINED 0xff04
+
+
+
+#define SHT_MIPS_LIBLIST       0x70000000
+#define SHT_MIPS_MSYM	       0x70000001
+#define SHT_MIPS_CONFLICT      0x70000002
+#define SHT_MIPS_GPTAB	       0x70000003
+#define SHT_MIPS_UCODE	       0x70000004
+#define SHT_MIPS_DEBUG	       0x70000005
+#define SHT_MIPS_REGINFO       0x70000006
+#define SHT_MIPS_PACKAGE       0x70000007
+#define SHT_MIPS_PACKSYM       0x70000008
+#define SHT_MIPS_RELD	       0x70000009
+#define SHT_MIPS_IFACE         0x7000000b
+#define SHT_MIPS_CONTENT       0x7000000c
+#define SHT_MIPS_OPTIONS       0x7000000d
+#define SHT_MIPS_SHDR	       0x70000010
+#define SHT_MIPS_FDESC	       0x70000011
+#define SHT_MIPS_EXTSYM	       0x70000012
+#define SHT_MIPS_DENSE	       0x70000013
+#define SHT_MIPS_PDESC	       0x70000014
+#define SHT_MIPS_LOCSYM	       0x70000015
+#define SHT_MIPS_AUXSYM	       0x70000016
+#define SHT_MIPS_OPTSYM	       0x70000017
+#define SHT_MIPS_LOCSTR	       0x70000018
+#define SHT_MIPS_LINE	       0x70000019
+#define SHT_MIPS_RFDESC	       0x7000001a
+#define SHT_MIPS_DELTASYM      0x7000001b
+#define SHT_MIPS_DELTAINST     0x7000001c
+#define SHT_MIPS_DELTACLASS    0x7000001d
+#define SHT_MIPS_DWARF         0x7000001e
+#define SHT_MIPS_DELTADECL     0x7000001f
+#define SHT_MIPS_SYMBOL_LIB    0x70000020
+#define SHT_MIPS_EVENTS	       0x70000021
+#define SHT_MIPS_TRANSLATE     0x70000022
+#define SHT_MIPS_PIXIE	       0x70000023
+#define SHT_MIPS_XLATE	       0x70000024
+#define SHT_MIPS_XLATE_DEBUG   0x70000025
+#define SHT_MIPS_WHIRL	       0x70000026
+#define SHT_MIPS_EH_REGION     0x70000027
+#define SHT_MIPS_XLATE_OLD     0x70000028
+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+
+
+
+#define SHF_MIPS_GPREL	 0x10000000
+#define SHF_MIPS_MERGE	 0x20000000
+#define SHF_MIPS_ADDR	 0x40000000
+#define SHF_MIPS_STRINGS 0x80000000
+#define SHF_MIPS_NOSTRIP 0x08000000
+#define SHF_MIPS_LOCAL	 0x04000000
+#define SHF_MIPS_NAMES	 0x02000000
+#define SHF_MIPS_NODUPE	 0x01000000
+
+
+
+
+
+#define STO_MIPS_DEFAULT		0x0
+#define STO_MIPS_INTERNAL		0x1
+#define STO_MIPS_HIDDEN			0x2
+#define STO_MIPS_PROTECTED		0x3
+#define STO_MIPS_PLT			0x8
+#define STO_MIPS_SC_ALIGN_UNUSED	0xff
+
+
+#define STB_MIPS_SPLIT_COMMON		13
+
+
+
+typedef union {
+  struct {
+      Elf32_Word gt_current_g_value;
+      Elf32_Word gt_unused;
+  } gt_header;
+  struct {
+      Elf32_Word gt_g_value;
+      Elf32_Word gt_bytes;
+  } gt_entry;
+} Elf32_gptab;
+
+
+
+typedef struct {
+  Elf32_Word	ri_gprmask;
+  Elf32_Word	ri_cprmask[4];
+  Elf32_Sword	ri_gp_value;
+} Elf32_RegInfo;
+
+
+
+typedef struct {
+  unsigned char kind;
+
+  unsigned char size;
+  Elf32_Section section;
+
+  Elf32_Word info;
+} Elf_Options;
+
+
+
+#define ODK_NULL	0
+#define ODK_REGINFO	1
+#define ODK_EXCEPTIONS	2
+#define ODK_PAD		3
+#define ODK_HWPATCH	4
+#define ODK_FILL	5
+#define ODK_TAGS	6
+#define ODK_HWAND	7
+#define ODK_HWOR	8
+
+
+
+#define OEX_FPU_MIN	0x1f
+#define OEX_FPU_MAX	0x1f00
+#define OEX_PAGE0	0x10000
+#define OEX_SMM		0x20000
+#define OEX_FPDBUG	0x40000
+#define OEX_PRECISEFP	OEX_FPDBUG
+#define OEX_DISMISS	0x80000
+
+#define OEX_FPU_INVAL	0x10
+#define OEX_FPU_DIV0	0x08
+#define OEX_FPU_OFLO	0x04
+#define OEX_FPU_UFLO	0x02
+#define OEX_FPU_INEX	0x01
+
+
+
+#define OHW_R4KEOP	0x1
+#define OHW_R8KPFETCH	0x2
+#define OHW_R5KEOP	0x4
+#define OHW_R5KCVTL	0x8
+
+#define OPAD_PREFIX	0x1
+#define OPAD_POSTFIX	0x2
+#define OPAD_SYMBOL	0x4
+
+
+
+typedef struct {
+  Elf32_Word hwp_flags1;
+  Elf32_Word hwp_flags2;
+} Elf_Options_Hw;
+
+
+
+#define OHWA0_R4KEOP_CHECKED	0x00000001
+#define OHWA1_R4KEOP_CLEAN	0x00000002
+
+
+
+#define R_MIPS_NONE		0
+#define R_MIPS_16		1
+#define R_MIPS_32		2
+#define R_MIPS_REL32		3
+#define R_MIPS_26		4
+#define R_MIPS_HI16		5
+#define R_MIPS_LO16		6
+#define R_MIPS_GPREL16		7
+#define R_MIPS_LITERAL		8
+#define R_MIPS_GOT16		9
+#define R_MIPS_PC16		10
+#define R_MIPS_CALL16		11
+#define R_MIPS_GPREL32		12
+
+#define R_MIPS_SHIFT5		16
+#define R_MIPS_SHIFT6		17
+#define R_MIPS_64		18
+#define R_MIPS_GOT_DISP		19
+#define R_MIPS_GOT_PAGE		20
+#define R_MIPS_GOT_OFST		21
+#define R_MIPS_GOT_HI16		22
+#define R_MIPS_GOT_LO16		23
+#define R_MIPS_SUB		24
+#define R_MIPS_INSERT_A		25
+#define R_MIPS_INSERT_B		26
+#define R_MIPS_DELETE		27
+#define R_MIPS_HIGHER		28
+#define R_MIPS_HIGHEST		29
+#define R_MIPS_CALL_HI16	30
+#define R_MIPS_CALL_LO16	31
+#define R_MIPS_SCN_DISP		32
+#define R_MIPS_REL16		33
+#define R_MIPS_ADD_IMMEDIATE	34
+#define R_MIPS_PJUMP		35
+#define R_MIPS_RELGOT		36
+#define R_MIPS_JALR		37
+#define R_MIPS_TLS_DTPMOD32	38
+#define R_MIPS_TLS_DTPREL32	39
+#define R_MIPS_TLS_DTPMOD64	40
+#define R_MIPS_TLS_DTPREL64	41
+#define R_MIPS_TLS_GD		42
+#define R_MIPS_TLS_LDM		43
+#define R_MIPS_TLS_DTPREL_HI16	44
+#define R_MIPS_TLS_DTPREL_LO16	45
+#define R_MIPS_TLS_GOTTPREL	46
+#define R_MIPS_TLS_TPREL32	47
+#define R_MIPS_TLS_TPREL64	48
+#define R_MIPS_TLS_TPREL_HI16	49
+#define R_MIPS_TLS_TPREL_LO16	50
+#define R_MIPS_GLOB_DAT		51
+#define R_MIPS_COPY		126
+#define R_MIPS_JUMP_SLOT        127
+
+#define R_MIPS_NUM		128
+
+
+
+#define PT_MIPS_REGINFO	0x70000000
+#define PT_MIPS_RTPROC  0x70000001
+#define PT_MIPS_OPTIONS 0x70000002
+#define PT_MIPS_ABIFLAGS 0x70000003
+
+
+
+#define PF_MIPS_LOCAL	0x10000000
+
+
+
+#define DT_MIPS_RLD_VERSION  0x70000001
+#define DT_MIPS_TIME_STAMP   0x70000002
+#define DT_MIPS_ICHECKSUM    0x70000003
+#define DT_MIPS_IVERSION     0x70000004
+#define DT_MIPS_FLAGS	     0x70000005
+#define DT_MIPS_BASE_ADDRESS 0x70000006
+#define DT_MIPS_MSYM	     0x70000007
+#define DT_MIPS_CONFLICT     0x70000008
+#define DT_MIPS_LIBLIST	     0x70000009
+#define DT_MIPS_LOCAL_GOTNO  0x7000000a
+#define DT_MIPS_CONFLICTNO   0x7000000b
+#define DT_MIPS_LIBLISTNO    0x70000010
+#define DT_MIPS_SYMTABNO     0x70000011
+#define DT_MIPS_UNREFEXTNO   0x70000012
+#define DT_MIPS_GOTSYM	     0x70000013
+#define DT_MIPS_HIPAGENO     0x70000014
+#define DT_MIPS_RLD_MAP	     0x70000016
+#define DT_MIPS_DELTA_CLASS  0x70000017
+#define DT_MIPS_DELTA_CLASS_NO    0x70000018
+
+#define DT_MIPS_DELTA_INSTANCE    0x70000019
+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a
+
+#define DT_MIPS_DELTA_RELOC  0x7000001b
+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c
+
+#define DT_MIPS_DELTA_SYM    0x7000001d
+
+#define DT_MIPS_DELTA_SYM_NO 0x7000001e
+
+#define DT_MIPS_DELTA_CLASSSYM 0x70000020
+
+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021
+
+#define DT_MIPS_CXX_FLAGS    0x70000022
+#define DT_MIPS_PIXIE_INIT   0x70000023
+#define DT_MIPS_SYMBOL_LIB   0x70000024
+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
+#define DT_MIPS_OPTIONS	     0x70000029
+#define DT_MIPS_INTERFACE    0x7000002a
+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
+#define DT_MIPS_INTERFACE_SIZE 0x7000002c
+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d
+
+#define DT_MIPS_PERF_SUFFIX  0x7000002e
+
+#define DT_MIPS_COMPACT_SIZE 0x7000002f
+#define DT_MIPS_GP_VALUE     0x70000030
+#define DT_MIPS_AUX_DYNAMIC  0x70000031
+
+#define DT_MIPS_PLTGOT	     0x70000032
+
+#define DT_MIPS_RWPLT        0x70000034
+#define DT_MIPS_RLD_MAP_REL  0x70000035
+#define DT_MIPS_NUM	     0x36
+
+
+
+#define RHF_NONE		   0
+#define RHF_QUICKSTART		   (1 << 0)
+#define RHF_NOTPOT		   (1 << 1)
+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)
+#define RHF_NO_MOVE		   (1 << 3)
+#define RHF_SGI_ONLY		   (1 << 4)
+#define RHF_GUARANTEE_INIT	   (1 << 5)
+#define RHF_DELTA_C_PLUS_PLUS	   (1 << 6)
+#define RHF_GUARANTEE_START_INIT   (1 << 7)
+#define RHF_PIXIE		   (1 << 8)
+#define RHF_DEFAULT_DELAY_LOAD	   (1 << 9)
+#define RHF_REQUICKSTART	   (1 << 10)
+#define RHF_REQUICKSTARTED	   (1 << 11)
+#define RHF_CORD		   (1 << 12)
+#define RHF_NO_UNRES_UNDEF	   (1 << 13)
+#define RHF_RLD_ORDER_SAFE	   (1 << 14)
+
+
+
+typedef struct {
+  Elf32_Word l_name;
+  Elf32_Word l_time_stamp;
+  Elf32_Word l_checksum;
+  Elf32_Word l_version;
+  Elf32_Word l_flags;
+} Elf32_Lib;
+
+typedef struct {
+  Elf64_Word l_name;
+  Elf64_Word l_time_stamp;
+  Elf64_Word l_checksum;
+  Elf64_Word l_version;
+  Elf64_Word l_flags;
+} Elf64_Lib;
+
+
+
+
+#define LL_NONE		  0
+#define LL_EXACT_MATCH	  (1 << 0)
+#define LL_IGNORE_INT_VER (1 << 1)
+#define LL_REQUIRE_MINOR  (1 << 2)
+#define LL_EXPORTS	  (1 << 3)
+#define LL_DELAY_LOAD	  (1 << 4)
+#define LL_DELTA	  (1 << 5)
+
+
+
+typedef Elf32_Addr Elf32_Conflict;
+
+typedef struct {
+  Elf32_Half version;
+  unsigned char isa_level;
+  unsigned char isa_rev;
+  unsigned char gpr_size;
+  unsigned char cpr1_size;
+  unsigned char cpr2_size;
+  unsigned char fp_abi;
+  Elf32_Word isa_ext;
+  Elf32_Word ases;
+  Elf32_Word flags1;
+  Elf32_Word flags2;
+} Elf_MIPS_ABIFlags_v0;
+
+#define MIPS_AFL_REG_NONE	0x00
+#define MIPS_AFL_REG_32		0x01
+#define MIPS_AFL_REG_64		0x02
+#define MIPS_AFL_REG_128	0x03
+
+#define MIPS_AFL_ASE_DSP	0x00000001
+#define MIPS_AFL_ASE_DSPR2	0x00000002
+#define MIPS_AFL_ASE_EVA	0x00000004
+#define MIPS_AFL_ASE_MCU	0x00000008
+#define MIPS_AFL_ASE_MDMX	0x00000010
+#define MIPS_AFL_ASE_MIPS3D	0x00000020
+#define MIPS_AFL_ASE_MT		0x00000040
+#define MIPS_AFL_ASE_SMARTMIPS	0x00000080
+#define MIPS_AFL_ASE_VIRT	0x00000100
+#define MIPS_AFL_ASE_MSA	0x00000200
+#define MIPS_AFL_ASE_MIPS16	0x00000400
+#define MIPS_AFL_ASE_MICROMIPS	0x00000800
+#define MIPS_AFL_ASE_XPA	0x00001000
+#define MIPS_AFL_ASE_MASK	0x00001fff
+
+#define MIPS_AFL_EXT_XLR	  1
+#define MIPS_AFL_EXT_OCTEON2	  2
+#define MIPS_AFL_EXT_OCTEONP	  3
+#define MIPS_AFL_EXT_LOONGSON_3A  4
+#define MIPS_AFL_EXT_OCTEON	  5
+#define MIPS_AFL_EXT_5900	  6
+#define MIPS_AFL_EXT_4650	  7
+#define MIPS_AFL_EXT_4010	  8
+#define MIPS_AFL_EXT_4100	  9
+#define MIPS_AFL_EXT_3900	  10
+#define MIPS_AFL_EXT_10000	  11
+#define MIPS_AFL_EXT_SB1	  12
+#define MIPS_AFL_EXT_4111	  13
+#define MIPS_AFL_EXT_4120	  14
+#define MIPS_AFL_EXT_5400	  15
+#define MIPS_AFL_EXT_5500	  16
+#define MIPS_AFL_EXT_LOONGSON_2E  17
+#define MIPS_AFL_EXT_LOONGSON_2F  18
+
+#define MIPS_AFL_FLAGS1_ODDSPREG  1
+
+enum
+{
+  Val_GNU_MIPS_ABI_FP_ANY = 0,
+  Val_GNU_MIPS_ABI_FP_DOUBLE = 1,
+  Val_GNU_MIPS_ABI_FP_SINGLE = 2,
+  Val_GNU_MIPS_ABI_FP_SOFT = 3,
+  Val_GNU_MIPS_ABI_FP_OLD_64 = 4,
+  Val_GNU_MIPS_ABI_FP_XX = 5,
+  Val_GNU_MIPS_ABI_FP_64 = 6,
+  Val_GNU_MIPS_ABI_FP_64A = 7,
+  Val_GNU_MIPS_ABI_FP_MAX = 7
+};
+
+
+
+
+#define EF_PARISC_TRAPNIL	0x00010000
+#define EF_PARISC_EXT		0x00020000
+#define EF_PARISC_LSB		0x00040000
+#define EF_PARISC_WIDE		0x00080000
+#define EF_PARISC_NO_KABP	0x00100000
+
+#define EF_PARISC_LAZYSWAP	0x00400000
+#define EF_PARISC_ARCH		0x0000ffff
+
+
+
+#define EFA_PARISC_1_0		    0x020b
+#define EFA_PARISC_1_1		    0x0210
+#define EFA_PARISC_2_0		    0x0214
+
+
+
+#define SHN_PARISC_ANSI_COMMON	0xff00
+
+#define SHN_PARISC_HUGE_COMMON	0xff01
+
+
+
+#define SHT_PARISC_EXT		0x70000000
+#define SHT_PARISC_UNWIND	0x70000001
+#define SHT_PARISC_DOC		0x70000002
+
+
+
+#define SHF_PARISC_SHORT	0x20000000
+#define SHF_PARISC_HUGE		0x40000000
+#define SHF_PARISC_SBP		0x80000000
+
+
+
+#define STT_PARISC_MILLICODE	13
+
+#define STT_HP_OPAQUE		(STT_LOOS + 0x1)
+#define STT_HP_STUB		(STT_LOOS + 0x2)
+
+
+
+#define R_PARISC_NONE		0
+#define R_PARISC_DIR32		1
+#define R_PARISC_DIR21L		2
+#define R_PARISC_DIR17R		3
+#define R_PARISC_DIR17F		4
+#define R_PARISC_DIR14R		6
+#define R_PARISC_PCREL32	9
+#define R_PARISC_PCREL21L	10
+#define R_PARISC_PCREL17R	11
+#define R_PARISC_PCREL17F	12
+#define R_PARISC_PCREL14R	14
+#define R_PARISC_DPREL21L	18
+#define R_PARISC_DPREL14R	22
+#define R_PARISC_GPREL21L	26
+#define R_PARISC_GPREL14R	30
+#define R_PARISC_LTOFF21L	34
+#define R_PARISC_LTOFF14R	38
+#define R_PARISC_SECREL32	41
+#define R_PARISC_SEGBASE	48
+#define R_PARISC_SEGREL32	49
+#define R_PARISC_PLTOFF21L	50
+#define R_PARISC_PLTOFF14R	54
+#define R_PARISC_LTOFF_FPTR32	57
+#define R_PARISC_LTOFF_FPTR21L	58
+#define R_PARISC_LTOFF_FPTR14R	62
+#define R_PARISC_FPTR64		64
+#define R_PARISC_PLABEL32	65
+#define R_PARISC_PLABEL21L	66
+#define R_PARISC_PLABEL14R	70
+#define R_PARISC_PCREL64	72
+#define R_PARISC_PCREL22F	74
+#define R_PARISC_PCREL14WR	75
+#define R_PARISC_PCREL14DR	76
+#define R_PARISC_PCREL16F	77
+#define R_PARISC_PCREL16WF	78
+#define R_PARISC_PCREL16DF	79
+#define R_PARISC_DIR64		80
+#define R_PARISC_DIR14WR	83
+#define R_PARISC_DIR14DR	84
+#define R_PARISC_DIR16F		85
+#define R_PARISC_DIR16WF	86
+#define R_PARISC_DIR16DF	87
+#define R_PARISC_GPREL64	88
+#define R_PARISC_GPREL14WR	91
+#define R_PARISC_GPREL14DR	92
+#define R_PARISC_GPREL16F	93
+#define R_PARISC_GPREL16WF	94
+#define R_PARISC_GPREL16DF	95
+#define R_PARISC_LTOFF64	96
+#define R_PARISC_LTOFF14WR	99
+#define R_PARISC_LTOFF14DR	100
+#define R_PARISC_LTOFF16F	101
+#define R_PARISC_LTOFF16WF	102
+#define R_PARISC_LTOFF16DF	103
+#define R_PARISC_SECREL64	104
+#define R_PARISC_SEGREL64	112
+#define R_PARISC_PLTOFF14WR	115
+#define R_PARISC_PLTOFF14DR	116
+#define R_PARISC_PLTOFF16F	117
+#define R_PARISC_PLTOFF16WF	118
+#define R_PARISC_PLTOFF16DF	119
+#define R_PARISC_LTOFF_FPTR64	120
+#define R_PARISC_LTOFF_FPTR14WR	123
+#define R_PARISC_LTOFF_FPTR14DR	124
+#define R_PARISC_LTOFF_FPTR16F	125
+#define R_PARISC_LTOFF_FPTR16WF	126
+#define R_PARISC_LTOFF_FPTR16DF	127
+#define R_PARISC_LORESERVE	128
+#define R_PARISC_COPY		128
+#define R_PARISC_IPLT		129
+#define R_PARISC_EPLT		130
+#define R_PARISC_TPREL32	153
+#define R_PARISC_TPREL21L	154
+#define R_PARISC_TPREL14R	158
+#define R_PARISC_LTOFF_TP21L	162
+#define R_PARISC_LTOFF_TP14R	166
+#define R_PARISC_LTOFF_TP14F	167
+#define R_PARISC_TPREL64	216
+#define R_PARISC_TPREL14WR	219
+#define R_PARISC_TPREL14DR	220
+#define R_PARISC_TPREL16F	221
+#define R_PARISC_TPREL16WF	222
+#define R_PARISC_TPREL16DF	223
+#define R_PARISC_LTOFF_TP64	224
+#define R_PARISC_LTOFF_TP14WR	227
+#define R_PARISC_LTOFF_TP14DR	228
+#define R_PARISC_LTOFF_TP16F	229
+#define R_PARISC_LTOFF_TP16WF	230
+#define R_PARISC_LTOFF_TP16DF	231
+#define R_PARISC_GNU_VTENTRY	232
+#define R_PARISC_GNU_VTINHERIT	233
+#define R_PARISC_TLS_GD21L	234
+#define R_PARISC_TLS_GD14R	235
+#define R_PARISC_TLS_GDCALL	236
+#define R_PARISC_TLS_LDM21L	237
+#define R_PARISC_TLS_LDM14R	238
+#define R_PARISC_TLS_LDMCALL	239
+#define R_PARISC_TLS_LDO21L	240
+#define R_PARISC_TLS_LDO14R	241
+#define R_PARISC_TLS_DTPMOD32	242
+#define R_PARISC_TLS_DTPMOD64	243
+#define R_PARISC_TLS_DTPOFF32	244
+#define R_PARISC_TLS_DTPOFF64	245
+#define R_PARISC_TLS_LE21L	R_PARISC_TPREL21L
+#define R_PARISC_TLS_LE14R	R_PARISC_TPREL14R
+#define R_PARISC_TLS_IE21L	R_PARISC_LTOFF_TP21L
+#define R_PARISC_TLS_IE14R	R_PARISC_LTOFF_TP14R
+#define R_PARISC_TLS_TPREL32	R_PARISC_TPREL32
+#define R_PARISC_TLS_TPREL64	R_PARISC_TPREL64
+#define R_PARISC_HIRESERVE	255
+
+
+
+#define PT_HP_TLS		(PT_LOOS + 0x0)
+#define PT_HP_CORE_NONE		(PT_LOOS + 0x1)
+#define PT_HP_CORE_VERSION	(PT_LOOS + 0x2)
+#define PT_HP_CORE_KERNEL	(PT_LOOS + 0x3)
+#define PT_HP_CORE_COMM		(PT_LOOS + 0x4)
+#define PT_HP_CORE_PROC		(PT_LOOS + 0x5)
+#define PT_HP_CORE_LOADABLE	(PT_LOOS + 0x6)
+#define PT_HP_CORE_STACK	(PT_LOOS + 0x7)
+#define PT_HP_CORE_SHM		(PT_LOOS + 0x8)
+#define PT_HP_CORE_MMF		(PT_LOOS + 0x9)
+#define PT_HP_PARALLEL		(PT_LOOS + 0x10)
+#define PT_HP_FASTBIND		(PT_LOOS + 0x11)
+#define PT_HP_OPT_ANNOT		(PT_LOOS + 0x12)
+#define PT_HP_HSL_ANNOT		(PT_LOOS + 0x13)
+#define PT_HP_STACK		(PT_LOOS + 0x14)
+
+#define PT_PARISC_ARCHEXT	0x70000000
+#define PT_PARISC_UNWIND	0x70000001
+
+
+
+#define PF_PARISC_SBP		0x08000000
+
+#define PF_HP_PAGE_SIZE		0x00100000
+#define PF_HP_FAR_SHARED	0x00200000
+#define PF_HP_NEAR_SHARED	0x00400000
+#define PF_HP_CODE		0x01000000
+#define PF_HP_MODIFY		0x02000000
+#define PF_HP_LAZYSWAP		0x04000000
+#define PF_HP_SBP		0x08000000
+
+
+
+
+
+
+#define EF_ALPHA_32BIT		1
+#define EF_ALPHA_CANRELAX	2
+
+
+
+
+#define SHT_ALPHA_DEBUG		0x70000001
+#define SHT_ALPHA_REGINFO	0x70000002
+
+
+
+#define SHF_ALPHA_GPREL		0x10000000
+
+
+#define STO_ALPHA_NOPV		0x80
+#define STO_ALPHA_STD_GPLOAD	0x88
+
+
+
+#define R_ALPHA_NONE		0
+#define R_ALPHA_REFLONG		1
+#define R_ALPHA_REFQUAD		2
+#define R_ALPHA_GPREL32		3
+#define R_ALPHA_LITERAL		4
+#define R_ALPHA_LITUSE		5
+#define R_ALPHA_GPDISP		6
+#define R_ALPHA_BRADDR		7
+#define R_ALPHA_HINT		8
+#define R_ALPHA_SREL16		9
+#define R_ALPHA_SREL32		10
+#define R_ALPHA_SREL64		11
+#define R_ALPHA_GPRELHIGH	17
+#define R_ALPHA_GPRELLOW	18
+#define R_ALPHA_GPREL16		19
+#define R_ALPHA_COPY		24
+#define R_ALPHA_GLOB_DAT	25
+#define R_ALPHA_JMP_SLOT	26
+#define R_ALPHA_RELATIVE	27
+#define R_ALPHA_TLS_GD_HI	28
+#define R_ALPHA_TLSGD		29
+#define R_ALPHA_TLS_LDM		30
+#define R_ALPHA_DTPMOD64	31
+#define R_ALPHA_GOTDTPREL	32
+#define R_ALPHA_DTPREL64	33
+#define R_ALPHA_DTPRELHI	34
+#define R_ALPHA_DTPRELLO	35
+#define R_ALPHA_DTPREL16	36
+#define R_ALPHA_GOTTPREL	37
+#define R_ALPHA_TPREL64		38
+#define R_ALPHA_TPRELHI		39
+#define R_ALPHA_TPRELLO		40
+#define R_ALPHA_TPREL16		41
+
+#define R_ALPHA_NUM		46
+
+
+#define LITUSE_ALPHA_ADDR	0
+#define LITUSE_ALPHA_BASE	1
+#define LITUSE_ALPHA_BYTOFF	2
+#define LITUSE_ALPHA_JSR	3
+#define LITUSE_ALPHA_TLS_GD	4
+#define LITUSE_ALPHA_TLS_LDM	5
+
+
+#define DT_ALPHA_PLTRO		(DT_LOPROC + 0)
+#define DT_ALPHA_NUM		1
+
+
+
+
+#define EF_PPC_EMB		0x80000000
+
+
+#define EF_PPC_RELOCATABLE	0x00010000
+#define EF_PPC_RELOCATABLE_LIB	0x00008000
+
+
+
+#define R_PPC_NONE		0
+#define R_PPC_ADDR32		1
+#define R_PPC_ADDR24		2
+#define R_PPC_ADDR16		3
+#define R_PPC_ADDR16_LO		4
+#define R_PPC_ADDR16_HI		5
+#define R_PPC_ADDR16_HA		6
+#define R_PPC_ADDR14		7
+#define R_PPC_ADDR14_BRTAKEN	8
+#define R_PPC_ADDR14_BRNTAKEN	9
+#define R_PPC_REL24		10
+#define R_PPC_REL14		11
+#define R_PPC_REL14_BRTAKEN	12
+#define R_PPC_REL14_BRNTAKEN	13
+#define R_PPC_GOT16		14
+#define R_PPC_GOT16_LO		15
+#define R_PPC_GOT16_HI		16
+#define R_PPC_GOT16_HA		17
+#define R_PPC_PLTREL24		18
+#define R_PPC_COPY		19
+#define R_PPC_GLOB_DAT		20
+#define R_PPC_JMP_SLOT		21
+#define R_PPC_RELATIVE		22
+#define R_PPC_LOCAL24PC		23
+#define R_PPC_UADDR32		24
+#define R_PPC_UADDR16		25
+#define R_PPC_REL32		26
+#define R_PPC_PLT32		27
+#define R_PPC_PLTREL32		28
+#define R_PPC_PLT16_LO		29
+#define R_PPC_PLT16_HI		30
+#define R_PPC_PLT16_HA		31
+#define R_PPC_SDAREL16		32
+#define R_PPC_SECTOFF		33
+#define R_PPC_SECTOFF_LO	34
+#define R_PPC_SECTOFF_HI	35
+#define R_PPC_SECTOFF_HA	36
+
+
+#define R_PPC_TLS		67
+#define R_PPC_DTPMOD32		68
+#define R_PPC_TPREL16		69
+#define R_PPC_TPREL16_LO	70
+#define R_PPC_TPREL16_HI	71
+#define R_PPC_TPREL16_HA	72
+#define R_PPC_TPREL32		73
+#define R_PPC_DTPREL16		74
+#define R_PPC_DTPREL16_LO	75
+#define R_PPC_DTPREL16_HI	76
+#define R_PPC_DTPREL16_HA	77
+#define R_PPC_DTPREL32		78
+#define R_PPC_GOT_TLSGD16	79
+#define R_PPC_GOT_TLSGD16_LO	80
+#define R_PPC_GOT_TLSGD16_HI	81
+#define R_PPC_GOT_TLSGD16_HA	82
+#define R_PPC_GOT_TLSLD16	83
+#define R_PPC_GOT_TLSLD16_LO	84
+#define R_PPC_GOT_TLSLD16_HI	85
+#define R_PPC_GOT_TLSLD16_HA	86
+#define R_PPC_GOT_TPREL16	87
+#define R_PPC_GOT_TPREL16_LO	88
+#define R_PPC_GOT_TPREL16_HI	89
+#define R_PPC_GOT_TPREL16_HA	90
+#define R_PPC_GOT_DTPREL16	91
+#define R_PPC_GOT_DTPREL16_LO	92
+#define R_PPC_GOT_DTPREL16_HI	93
+#define R_PPC_GOT_DTPREL16_HA	94
+#define R_PPC_TLSGD		95
+#define R_PPC_TLSLD		96
+
+
+#define R_PPC_EMB_NADDR32	101
+#define R_PPC_EMB_NADDR16	102
+#define R_PPC_EMB_NADDR16_LO	103
+#define R_PPC_EMB_NADDR16_HI	104
+#define R_PPC_EMB_NADDR16_HA	105
+#define R_PPC_EMB_SDAI16	106
+#define R_PPC_EMB_SDA2I16	107
+#define R_PPC_EMB_SDA2REL	108
+#define R_PPC_EMB_SDA21		109
+#define R_PPC_EMB_MRKREF	110
+#define R_PPC_EMB_RELSEC16	111
+#define R_PPC_EMB_RELST_LO	112
+#define R_PPC_EMB_RELST_HI	113
+#define R_PPC_EMB_RELST_HA	114
+#define R_PPC_EMB_BIT_FLD	115
+#define R_PPC_EMB_RELSDA	116
+
+
+#define R_PPC_DIAB_SDA21_LO	180
+#define R_PPC_DIAB_SDA21_HI	181
+#define R_PPC_DIAB_SDA21_HA	182
+#define R_PPC_DIAB_RELSDA_LO	183
+#define R_PPC_DIAB_RELSDA_HI	184
+#define R_PPC_DIAB_RELSDA_HA	185
+
+
+#define R_PPC_IRELATIVE		248
+
+
+#define R_PPC_REL16		249
+#define R_PPC_REL16_LO		250
+#define R_PPC_REL16_HI		251
+#define R_PPC_REL16_HA		252
+
+
+
+#define R_PPC_TOC16		255
+
+
+#define DT_PPC_GOT		(DT_LOPROC + 0)
+#define DT_PPC_OPT		(DT_LOPROC + 1)
+#define DT_PPC_NUM		2
+
+#define PPC_OPT_TLS		1
+
+
+#define R_PPC64_NONE		R_PPC_NONE
+#define R_PPC64_ADDR32		R_PPC_ADDR32
+#define R_PPC64_ADDR24		R_PPC_ADDR24
+#define R_PPC64_ADDR16		R_PPC_ADDR16
+#define R_PPC64_ADDR16_LO	R_PPC_ADDR16_LO
+#define R_PPC64_ADDR16_HI	R_PPC_ADDR16_HI
+#define R_PPC64_ADDR16_HA	R_PPC_ADDR16_HA
+#define R_PPC64_ADDR14		R_PPC_ADDR14
+#define R_PPC64_ADDR14_BRTAKEN	R_PPC_ADDR14_BRTAKEN
+#define R_PPC64_ADDR14_BRNTAKEN	R_PPC_ADDR14_BRNTAKEN
+#define R_PPC64_REL24		R_PPC_REL24
+#define R_PPC64_REL14		R_PPC_REL14
+#define R_PPC64_REL14_BRTAKEN	R_PPC_REL14_BRTAKEN
+#define R_PPC64_REL14_BRNTAKEN	R_PPC_REL14_BRNTAKEN
+#define R_PPC64_GOT16		R_PPC_GOT16
+#define R_PPC64_GOT16_LO	R_PPC_GOT16_LO
+#define R_PPC64_GOT16_HI	R_PPC_GOT16_HI
+#define R_PPC64_GOT16_HA	R_PPC_GOT16_HA
+
+#define R_PPC64_COPY		R_PPC_COPY
+#define R_PPC64_GLOB_DAT	R_PPC_GLOB_DAT
+#define R_PPC64_JMP_SLOT	R_PPC_JMP_SLOT
+#define R_PPC64_RELATIVE	R_PPC_RELATIVE
+
+#define R_PPC64_UADDR32		R_PPC_UADDR32
+#define R_PPC64_UADDR16		R_PPC_UADDR16
+#define R_PPC64_REL32		R_PPC_REL32
+#define R_PPC64_PLT32		R_PPC_PLT32
+#define R_PPC64_PLTREL32	R_PPC_PLTREL32
+#define R_PPC64_PLT16_LO	R_PPC_PLT16_LO
+#define R_PPC64_PLT16_HI	R_PPC_PLT16_HI
+#define R_PPC64_PLT16_HA	R_PPC_PLT16_HA
+
+#define R_PPC64_SECTOFF		R_PPC_SECTOFF
+#define R_PPC64_SECTOFF_LO	R_PPC_SECTOFF_LO
+#define R_PPC64_SECTOFF_HI	R_PPC_SECTOFF_HI
+#define R_PPC64_SECTOFF_HA	R_PPC_SECTOFF_HA
+#define R_PPC64_ADDR30		37
+#define R_PPC64_ADDR64		38
+#define R_PPC64_ADDR16_HIGHER	39
+#define R_PPC64_ADDR16_HIGHERA	40
+#define R_PPC64_ADDR16_HIGHEST	41
+#define R_PPC64_ADDR16_HIGHESTA	42
+#define R_PPC64_UADDR64		43
+#define R_PPC64_REL64		44
+#define R_PPC64_PLT64		45
+#define R_PPC64_PLTREL64	46
+#define R_PPC64_TOC16		47
+#define R_PPC64_TOC16_LO	48
+#define R_PPC64_TOC16_HI	49
+#define R_PPC64_TOC16_HA	50
+#define R_PPC64_TOC		51
+#define R_PPC64_PLTGOT16	52
+#define R_PPC64_PLTGOT16_LO	53
+#define R_PPC64_PLTGOT16_HI	54
+#define R_PPC64_PLTGOT16_HA	55
+
+#define R_PPC64_ADDR16_DS	56
+#define R_PPC64_ADDR16_LO_DS	57
+#define R_PPC64_GOT16_DS	58
+#define R_PPC64_GOT16_LO_DS	59
+#define R_PPC64_PLT16_LO_DS	60
+#define R_PPC64_SECTOFF_DS	61
+#define R_PPC64_SECTOFF_LO_DS	62
+#define R_PPC64_TOC16_DS	63
+#define R_PPC64_TOC16_LO_DS	64
+#define R_PPC64_PLTGOT16_DS	65
+#define R_PPC64_PLTGOT16_LO_DS	66
+
+
+#define R_PPC64_TLS		67
+#define R_PPC64_DTPMOD64	68
+#define R_PPC64_TPREL16		69
+#define R_PPC64_TPREL16_LO	70
+#define R_PPC64_TPREL16_HI	71
+#define R_PPC64_TPREL16_HA	72
+#define R_PPC64_TPREL64		73
+#define R_PPC64_DTPREL16	74
+#define R_PPC64_DTPREL16_LO	75
+#define R_PPC64_DTPREL16_HI	76
+#define R_PPC64_DTPREL16_HA	77
+#define R_PPC64_DTPREL64	78
+#define R_PPC64_GOT_TLSGD16	79
+#define R_PPC64_GOT_TLSGD16_LO	80
+#define R_PPC64_GOT_TLSGD16_HI	81
+#define R_PPC64_GOT_TLSGD16_HA	82
+#define R_PPC64_GOT_TLSLD16	83
+#define R_PPC64_GOT_TLSLD16_LO	84
+#define R_PPC64_GOT_TLSLD16_HI	85
+#define R_PPC64_GOT_TLSLD16_HA	86
+#define R_PPC64_GOT_TPREL16_DS	87
+#define R_PPC64_GOT_TPREL16_LO_DS 88
+#define R_PPC64_GOT_TPREL16_HI	89
+#define R_PPC64_GOT_TPREL16_HA	90
+#define R_PPC64_GOT_DTPREL16_DS	91
+#define R_PPC64_GOT_DTPREL16_LO_DS 92
+#define R_PPC64_GOT_DTPREL16_HI	93
+#define R_PPC64_GOT_DTPREL16_HA	94
+#define R_PPC64_TPREL16_DS	95
+#define R_PPC64_TPREL16_LO_DS	96
+#define R_PPC64_TPREL16_HIGHER	97
+#define R_PPC64_TPREL16_HIGHERA	98
+#define R_PPC64_TPREL16_HIGHEST	99
+#define R_PPC64_TPREL16_HIGHESTA 100
+#define R_PPC64_DTPREL16_DS	101
+#define R_PPC64_DTPREL16_LO_DS	102
+#define R_PPC64_DTPREL16_HIGHER	103
+#define R_PPC64_DTPREL16_HIGHERA 104
+#define R_PPC64_DTPREL16_HIGHEST 105
+#define R_PPC64_DTPREL16_HIGHESTA 106
+#define R_PPC64_TLSGD		107
+#define R_PPC64_TLSLD		108
+#define R_PPC64_TOCSAVE		109
+#define R_PPC64_ADDR16_HIGH	110
+#define R_PPC64_ADDR16_HIGHA	111
+#define R_PPC64_TPREL16_HIGH	112
+#define R_PPC64_TPREL16_HIGHA	113
+#define R_PPC64_DTPREL16_HIGH	114
+#define R_PPC64_DTPREL16_HIGHA	115
+
+
+#define R_PPC64_JMP_IREL	247
+#define R_PPC64_IRELATIVE	248
+#define R_PPC64_REL16		249
+#define R_PPC64_REL16_LO	250
+#define R_PPC64_REL16_HI	251
+#define R_PPC64_REL16_HA	252
+
+#define EF_PPC64_ABI	3
+
+#define DT_PPC64_GLINK  (DT_LOPROC + 0)
+#define DT_PPC64_OPD	(DT_LOPROC + 1)
+#define DT_PPC64_OPDSZ	(DT_LOPROC + 2)
+#define DT_PPC64_OPT	(DT_LOPROC + 3)
+#define DT_PPC64_NUM	4
+
+#define PPC64_OPT_TLS		1
+#define PPC64_OPT_MULTI_TOC	2
+
+#define STO_PPC64_LOCAL_BIT	5
+#define STO_PPC64_LOCAL_MASK	0xe0
+#define PPC64_LOCAL_ENTRY_OFFSET(x) (1 << (((x)&0xe0)>>5) & 0xfc)
+
+
+#define EF_ARM_RELEXEC		0x01
+#define EF_ARM_HASENTRY		0x02
+#define EF_ARM_INTERWORK	0x04
+#define EF_ARM_APCS_26		0x08
+#define EF_ARM_APCS_FLOAT	0x10
+#define EF_ARM_PIC		0x20
+#define EF_ARM_ALIGN8		0x40
+#define EF_ARM_NEW_ABI		0x80
+#define EF_ARM_OLD_ABI		0x100
+#define EF_ARM_SOFT_FLOAT	0x200
+#define EF_ARM_VFP_FLOAT	0x400
+#define EF_ARM_MAVERICK_FLOAT	0x800
+
+#define EF_ARM_ABI_FLOAT_SOFT	0x200
+#define EF_ARM_ABI_FLOAT_HARD	0x400
+
+
+#define EF_ARM_SYMSARESORTED	0x04
+#define EF_ARM_DYNSYMSUSESEGIDX	0x08
+#define EF_ARM_MAPSYMSFIRST	0x10
+#define EF_ARM_EABIMASK		0XFF000000
+
+
+#define EF_ARM_BE8	    0x00800000
+#define EF_ARM_LE8	    0x00400000
+
+#define EF_ARM_EABI_VERSION(flags)	((flags) & EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN	0x00000000
+#define EF_ARM_EABI_VER1	0x01000000
+#define EF_ARM_EABI_VER2	0x02000000
+#define EF_ARM_EABI_VER3	0x03000000
+#define EF_ARM_EABI_VER4	0x04000000
+#define EF_ARM_EABI_VER5	0x05000000
+
+
+#define STT_ARM_TFUNC		STT_LOPROC
+#define STT_ARM_16BIT		STT_HIPROC
+
+
+#define SHF_ARM_ENTRYSECT	0x10000000
+#define SHF_ARM_COMDEF		0x80000000
+
+
+
+#define PF_ARM_SB		0x10000000
+
+#define PF_ARM_PI		0x20000000
+#define PF_ARM_ABS		0x40000000
+
+
+#define PT_ARM_EXIDX		(PT_LOPROC + 1)
+
+
+#define SHT_ARM_EXIDX		(SHT_LOPROC + 1)
+#define SHT_ARM_PREEMPTMAP	(SHT_LOPROC + 2)
+#define SHT_ARM_ATTRIBUTES	(SHT_LOPROC + 3)
+
+#define R_AARCH64_NONE            0
+#define R_AARCH64_P32_ABS32	1
+#define R_AARCH64_P32_COPY	180
+#define R_AARCH64_P32_GLOB_DAT	181
+#define R_AARCH64_P32_JUMP_SLOT	182
+#define R_AARCH64_P32_RELATIVE	183
+#define R_AARCH64_P32_TLS_DTPMOD 184
+#define R_AARCH64_P32_TLS_DTPREL 185
+#define R_AARCH64_P32_TLS_TPREL	186
+#define R_AARCH64_P32_TLSDESC	187
+#define R_AARCH64_P32_IRELATIVE	188
+#define R_AARCH64_ABS64         257
+#define R_AARCH64_ABS32         258
+#define R_AARCH64_ABS16		259
+#define R_AARCH64_PREL64	260
+#define R_AARCH64_PREL32	261
+#define R_AARCH64_PREL16	262
+#define R_AARCH64_MOVW_UABS_G0	263
+#define R_AARCH64_MOVW_UABS_G0_NC 264
+#define R_AARCH64_MOVW_UABS_G1	265
+#define R_AARCH64_MOVW_UABS_G1_NC 266
+#define R_AARCH64_MOVW_UABS_G2	267
+#define R_AARCH64_MOVW_UABS_G2_NC 268
+#define R_AARCH64_MOVW_UABS_G3	269
+#define R_AARCH64_MOVW_SABS_G0	270
+#define R_AARCH64_MOVW_SABS_G1	271
+#define R_AARCH64_MOVW_SABS_G2	272
+#define R_AARCH64_LD_PREL_LO19	273
+#define R_AARCH64_ADR_PREL_LO21	274
+#define R_AARCH64_ADR_PREL_PG_HI21 275
+#define R_AARCH64_ADR_PREL_PG_HI21_NC 276
+#define R_AARCH64_ADD_ABS_LO12_NC 277
+#define R_AARCH64_LDST8_ABS_LO12_NC 278
+#define R_AARCH64_TSTBR14	279
+#define R_AARCH64_CONDBR19	280
+#define R_AARCH64_JUMP26	282
+#define R_AARCH64_CALL26	283
+#define R_AARCH64_LDST16_ABS_LO12_NC 284
+#define R_AARCH64_LDST32_ABS_LO12_NC 285
+#define R_AARCH64_LDST64_ABS_LO12_NC 286
+#define R_AARCH64_MOVW_PREL_G0	287
+#define R_AARCH64_MOVW_PREL_G0_NC 288
+#define R_AARCH64_MOVW_PREL_G1	289
+#define R_AARCH64_MOVW_PREL_G1_NC 290
+#define R_AARCH64_MOVW_PREL_G2	291
+#define R_AARCH64_MOVW_PREL_G2_NC 292
+#define R_AARCH64_MOVW_PREL_G3	293
+#define R_AARCH64_LDST128_ABS_LO12_NC 299
+#define R_AARCH64_MOVW_GOTOFF_G0 300
+#define R_AARCH64_MOVW_GOTOFF_G0_NC 301
+#define R_AARCH64_MOVW_GOTOFF_G1 302
+#define R_AARCH64_MOVW_GOTOFF_G1_NC 303
+#define R_AARCH64_MOVW_GOTOFF_G2 304
+#define R_AARCH64_MOVW_GOTOFF_G2_NC 305
+#define R_AARCH64_MOVW_GOTOFF_G3 306
+#define R_AARCH64_GOTREL64	307
+#define R_AARCH64_GOTREL32	308
+#define R_AARCH64_GOT_LD_PREL19	309
+#define R_AARCH64_LD64_GOTOFF_LO15 310
+#define R_AARCH64_ADR_GOT_PAGE	311
+#define R_AARCH64_LD64_GOT_LO12_NC 312
+#define R_AARCH64_LD64_GOTPAGE_LO15 313
+#define R_AARCH64_TLSGD_ADR_PREL21 512
+#define R_AARCH64_TLSGD_ADR_PAGE21 513
+#define R_AARCH64_TLSGD_ADD_LO12_NC 514
+#define R_AARCH64_TLSGD_MOVW_G1	515
+#define R_AARCH64_TLSGD_MOVW_G0_NC 516
+#define R_AARCH64_TLSLD_ADR_PREL21 517
+#define R_AARCH64_TLSLD_ADR_PAGE21 518
+#define R_AARCH64_TLSLD_ADD_LO12_NC 519
+#define R_AARCH64_TLSLD_MOVW_G1	520
+#define R_AARCH64_TLSLD_MOVW_G0_NC 521
+#define R_AARCH64_TLSLD_LD_PREL19 522
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527
+#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540
+#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541
+#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542
+#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543
+#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548
+#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559
+#define R_AARCH64_TLSDESC_LD_PREL19 560
+#define R_AARCH64_TLSDESC_ADR_PREL21 561
+#define R_AARCH64_TLSDESC_ADR_PAGE21 562
+#define R_AARCH64_TLSDESC_LD64_LO12 563
+#define R_AARCH64_TLSDESC_ADD_LO12 564
+#define R_AARCH64_TLSDESC_OFF_G1 565
+#define R_AARCH64_TLSDESC_OFF_G0_NC 566
+#define R_AARCH64_TLSDESC_LDR	567
+#define R_AARCH64_TLSDESC_ADD	568
+#define R_AARCH64_TLSDESC_CALL	569
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573
+#define R_AARCH64_COPY         1024
+#define R_AARCH64_GLOB_DAT     1025
+#define R_AARCH64_JUMP_SLOT    1026
+#define R_AARCH64_RELATIVE     1027
+#define R_AARCH64_TLS_DTPMOD   1028
+#define R_AARCH64_TLS_DTPMOD64 1028
+#define R_AARCH64_TLS_DTPREL   1029
+#define R_AARCH64_TLS_DTPREL64 1029
+#define R_AARCH64_TLS_TPREL    1030
+#define R_AARCH64_TLS_TPREL64  1030
+#define R_AARCH64_TLSDESC      1031
+
+
+#define R_ARM_NONE		0
+#define R_ARM_PC24		1
+#define R_ARM_ABS32		2
+#define R_ARM_REL32		3
+#define R_ARM_PC13		4
+#define R_ARM_ABS16		5
+#define R_ARM_ABS12		6
+#define R_ARM_THM_ABS5		7
+#define R_ARM_ABS8		8
+#define R_ARM_SBREL32		9
+#define R_ARM_THM_PC22		10
+#define R_ARM_THM_PC8		11
+#define R_ARM_AMP_VCALL9	12
+#define R_ARM_TLS_DESC		13
+#define R_ARM_THM_SWI8		14
+#define R_ARM_XPC25		15
+#define R_ARM_THM_XPC22		16
+#define R_ARM_TLS_DTPMOD32	17
+#define R_ARM_TLS_DTPOFF32	18
+#define R_ARM_TLS_TPOFF32	19
+#define R_ARM_COPY		20
+#define R_ARM_GLOB_DAT		21
+#define R_ARM_JUMP_SLOT		22
+#define R_ARM_RELATIVE		23
+#define R_ARM_GOTOFF		24
+#define R_ARM_GOTPC		25
+#define R_ARM_GOT32		26
+#define R_ARM_PLT32		27
+#define R_ARM_CALL		28
+#define R_ARM_JUMP24		29
+#define R_ARM_THM_JUMP24	30
+#define R_ARM_BASE_ABS		31
+#define R_ARM_ALU_PCREL_7_0	32
+#define R_ARM_ALU_PCREL_15_8	33
+#define R_ARM_ALU_PCREL_23_15	34
+#define R_ARM_LDR_SBREL_11_0	35
+#define R_ARM_ALU_SBREL_19_12	36
+#define R_ARM_ALU_SBREL_27_20	37
+#define R_ARM_TARGET1		38
+#define R_ARM_SBREL31		39
+#define R_ARM_V4BX		40
+#define R_ARM_TARGET2		41
+#define R_ARM_PREL31		42
+#define R_ARM_MOVW_ABS_NC	43
+#define R_ARM_MOVT_ABS		44
+#define R_ARM_MOVW_PREL_NC	45
+#define R_ARM_MOVT_PREL		46
+#define R_ARM_THM_MOVW_ABS_NC	47
+#define R_ARM_THM_MOVT_ABS	48
+#define R_ARM_THM_MOVW_PREL_NC	49
+#define R_ARM_THM_MOVT_PREL	50
+#define R_ARM_THM_JUMP19	51
+#define R_ARM_THM_JUMP6		52
+#define R_ARM_THM_ALU_PREL_11_0	53
+#define R_ARM_THM_PC12		54
+#define R_ARM_ABS32_NOI		55
+#define R_ARM_REL32_NOI		56
+#define R_ARM_ALU_PC_G0_NC	57
+#define R_ARM_ALU_PC_G0		58
+#define R_ARM_ALU_PC_G1_NC	59
+#define R_ARM_ALU_PC_G1		60
+#define R_ARM_ALU_PC_G2		61
+#define R_ARM_LDR_PC_G1		62
+#define R_ARM_LDR_PC_G2		63
+#define R_ARM_LDRS_PC_G0	64
+#define R_ARM_LDRS_PC_G1	65
+#define R_ARM_LDRS_PC_G2	66
+#define R_ARM_LDC_PC_G0		67
+#define R_ARM_LDC_PC_G1		68
+#define R_ARM_LDC_PC_G2		69
+#define R_ARM_ALU_SB_G0_NC	70
+#define R_ARM_ALU_SB_G0		71
+#define R_ARM_ALU_SB_G1_NC	72
+#define R_ARM_ALU_SB_G1		73
+#define R_ARM_ALU_SB_G2		74
+#define R_ARM_LDR_SB_G0		75
+#define R_ARM_LDR_SB_G1		76
+#define R_ARM_LDR_SB_G2		77
+#define R_ARM_LDRS_SB_G0	78
+#define R_ARM_LDRS_SB_G1	79
+#define R_ARM_LDRS_SB_G2	80
+#define R_ARM_LDC_SB_G0		81
+#define R_ARM_LDC_SB_G1		82
+#define R_ARM_LDC_SB_G2		83
+#define R_ARM_MOVW_BREL_NC	84
+#define R_ARM_MOVT_BREL		85
+#define R_ARM_MOVW_BREL		86
+#define R_ARM_THM_MOVW_BREL_NC	87
+#define R_ARM_THM_MOVT_BREL	88
+#define R_ARM_THM_MOVW_BREL	89
+#define R_ARM_TLS_GOTDESC	90
+#define R_ARM_TLS_CALL		91
+#define R_ARM_TLS_DESCSEQ	92
+#define R_ARM_THM_TLS_CALL	93
+#define R_ARM_PLT32_ABS		94
+#define R_ARM_GOT_ABS		95
+#define R_ARM_GOT_PREL		96
+#define R_ARM_GOT_BREL12	97
+#define R_ARM_GOTOFF12		98
+#define R_ARM_GOTRELAX		99
+#define R_ARM_GNU_VTENTRY	100
+#define R_ARM_GNU_VTINHERIT	101
+#define R_ARM_THM_PC11		102
+#define R_ARM_THM_PC9		103
+#define R_ARM_TLS_GD32		104
+
+#define R_ARM_TLS_LDM32		105
+
+#define R_ARM_TLS_LDO32		106
+
+#define R_ARM_TLS_IE32		107
+
+#define R_ARM_TLS_LE32		108
+#define R_ARM_TLS_LDO12		109
+#define R_ARM_TLS_LE12		110
+#define R_ARM_TLS_IE12GP	111
+#define R_ARM_ME_TOO		128
+#define R_ARM_THM_TLS_DESCSEQ	129
+#define R_ARM_THM_TLS_DESCSEQ16	129
+#define R_ARM_THM_TLS_DESCSEQ32	130
+#define R_ARM_THM_GOT_BREL12	131
+#define R_ARM_IRELATIVE		160
+#define R_ARM_RXPC25		249
+#define R_ARM_RSBREL32		250
+#define R_ARM_THM_RPC22		251
+#define R_ARM_RREL32		252
+#define R_ARM_RABS22		253
+#define R_ARM_RPC24		254
+#define R_ARM_RBASE		255
+
+#define R_ARM_NUM		256
+
+
+
+
+#define EF_IA_64_MASKOS		0x0000000f
+#define EF_IA_64_ABI64		0x00000010
+#define EF_IA_64_ARCH		0xff000000
+
+
+#define PT_IA_64_ARCHEXT	(PT_LOPROC + 0)
+#define PT_IA_64_UNWIND		(PT_LOPROC + 1)
+#define PT_IA_64_HP_OPT_ANOT	(PT_LOOS + 0x12)
+#define PT_IA_64_HP_HSL_ANOT	(PT_LOOS + 0x13)
+#define PT_IA_64_HP_STACK	(PT_LOOS + 0x14)
+
+
+#define PF_IA_64_NORECOV	0x80000000
+
+
+#define SHT_IA_64_EXT		(SHT_LOPROC + 0)
+#define SHT_IA_64_UNWIND	(SHT_LOPROC + 1)
+
+
+#define SHF_IA_64_SHORT		0x10000000
+#define SHF_IA_64_NORECOV	0x20000000
+
+
+#define DT_IA_64_PLT_RESERVE	(DT_LOPROC + 0)
+#define DT_IA_64_NUM		1
+
+
+#define R_IA64_NONE		0x00
+#define R_IA64_IMM14		0x21
+#define R_IA64_IMM22		0x22
+#define R_IA64_IMM64		0x23
+#define R_IA64_DIR32MSB		0x24
+#define R_IA64_DIR32LSB		0x25
+#define R_IA64_DIR64MSB		0x26
+#define R_IA64_DIR64LSB		0x27
+#define R_IA64_GPREL22		0x2a
+#define R_IA64_GPREL64I		0x2b
+#define R_IA64_GPREL32MSB	0x2c
+#define R_IA64_GPREL32LSB	0x2d
+#define R_IA64_GPREL64MSB	0x2e
+#define R_IA64_GPREL64LSB	0x2f
+#define R_IA64_LTOFF22		0x32
+#define R_IA64_LTOFF64I		0x33
+#define R_IA64_PLTOFF22		0x3a
+#define R_IA64_PLTOFF64I	0x3b
+#define R_IA64_PLTOFF64MSB	0x3e
+#define R_IA64_PLTOFF64LSB	0x3f
+#define R_IA64_FPTR64I		0x43
+#define R_IA64_FPTR32MSB	0x44
+#define R_IA64_FPTR32LSB	0x45
+#define R_IA64_FPTR64MSB	0x46
+#define R_IA64_FPTR64LSB	0x47
+#define R_IA64_PCREL60B		0x48
+#define R_IA64_PCREL21B		0x49
+#define R_IA64_PCREL21M		0x4a
+#define R_IA64_PCREL21F		0x4b
+#define R_IA64_PCREL32MSB	0x4c
+#define R_IA64_PCREL32LSB	0x4d
+#define R_IA64_PCREL64MSB	0x4e
+#define R_IA64_PCREL64LSB	0x4f
+#define R_IA64_LTOFF_FPTR22	0x52
+#define R_IA64_LTOFF_FPTR64I	0x53
+#define R_IA64_LTOFF_FPTR32MSB	0x54
+#define R_IA64_LTOFF_FPTR32LSB	0x55
+#define R_IA64_LTOFF_FPTR64MSB	0x56
+#define R_IA64_LTOFF_FPTR64LSB	0x57
+#define R_IA64_SEGREL32MSB	0x5c
+#define R_IA64_SEGREL32LSB	0x5d
+#define R_IA64_SEGREL64MSB	0x5e
+#define R_IA64_SEGREL64LSB	0x5f
+#define R_IA64_SECREL32MSB	0x64
+#define R_IA64_SECREL32LSB	0x65
+#define R_IA64_SECREL64MSB	0x66
+#define R_IA64_SECREL64LSB	0x67
+#define R_IA64_REL32MSB		0x6c
+#define R_IA64_REL32LSB		0x6d
+#define R_IA64_REL64MSB		0x6e
+#define R_IA64_REL64LSB		0x6f
+#define R_IA64_LTV32MSB		0x74
+#define R_IA64_LTV32LSB		0x75
+#define R_IA64_LTV64MSB		0x76
+#define R_IA64_LTV64LSB		0x77
+#define R_IA64_PCREL21BI	0x79
+#define R_IA64_PCREL22		0x7a
+#define R_IA64_PCREL64I		0x7b
+#define R_IA64_IPLTMSB		0x80
+#define R_IA64_IPLTLSB		0x81
+#define R_IA64_COPY		0x84
+#define R_IA64_SUB		0x85
+#define R_IA64_LTOFF22X		0x86
+#define R_IA64_LDXMOV		0x87
+#define R_IA64_TPREL14		0x91
+#define R_IA64_TPREL22		0x92
+#define R_IA64_TPREL64I		0x93
+#define R_IA64_TPREL64MSB	0x96
+#define R_IA64_TPREL64LSB	0x97
+#define R_IA64_LTOFF_TPREL22	0x9a
+#define R_IA64_DTPMOD64MSB	0xa6
+#define R_IA64_DTPMOD64LSB	0xa7
+#define R_IA64_LTOFF_DTPMOD22	0xaa
+#define R_IA64_DTPREL14		0xb1
+#define R_IA64_DTPREL22		0xb2
+#define R_IA64_DTPREL64I	0xb3
+#define R_IA64_DTPREL32MSB	0xb4
+#define R_IA64_DTPREL32LSB	0xb5
+#define R_IA64_DTPREL64MSB	0xb6
+#define R_IA64_DTPREL64LSB	0xb7
+#define R_IA64_LTOFF_DTPREL22	0xba
+
+
+#define EF_SH_MACH_MASK		0x1f
+#define EF_SH_UNKNOWN		0x0
+#define EF_SH1			0x1
+#define EF_SH2			0x2
+#define EF_SH3			0x3
+#define EF_SH_DSP		0x4
+#define EF_SH3_DSP		0x5
+#define EF_SH4AL_DSP		0x6
+#define EF_SH3E			0x8
+#define EF_SH4			0x9
+#define EF_SH2E			0xb
+#define EF_SH4A			0xc
+#define EF_SH2A			0xd
+#define EF_SH4_NOFPU		0x10
+#define EF_SH4A_NOFPU		0x11
+#define EF_SH4_NOMMU_NOFPU	0x12
+#define EF_SH2A_NOFPU		0x13
+#define EF_SH3_NOMMU		0x14
+#define EF_SH2A_SH4_NOFPU	0x15
+#define EF_SH2A_SH3_NOFPU	0x16
+#define EF_SH2A_SH4		0x17
+#define EF_SH2A_SH3E		0x18
+
+#define	R_SH_NONE		0
+#define	R_SH_DIR32		1
+#define	R_SH_REL32		2
+#define	R_SH_DIR8WPN		3
+#define	R_SH_IND12W		4
+#define	R_SH_DIR8WPL		5
+#define	R_SH_DIR8WPZ		6
+#define	R_SH_DIR8BP		7
+#define	R_SH_DIR8W		8
+#define	R_SH_DIR8L		9
+#define	R_SH_SWITCH16		25
+#define	R_SH_SWITCH32		26
+#define	R_SH_USES		27
+#define	R_SH_COUNT		28
+#define	R_SH_ALIGN		29
+#define	R_SH_CODE		30
+#define	R_SH_DATA		31
+#define	R_SH_LABEL		32
+#define	R_SH_SWITCH8		33
+#define	R_SH_GNU_VTINHERIT	34
+#define	R_SH_GNU_VTENTRY	35
+#define	R_SH_TLS_GD_32		144
+#define	R_SH_TLS_LD_32		145
+#define	R_SH_TLS_LDO_32		146
+#define	R_SH_TLS_IE_32		147
+#define	R_SH_TLS_LE_32		148
+#define	R_SH_TLS_DTPMOD32	149
+#define	R_SH_TLS_DTPOFF32	150
+#define	R_SH_TLS_TPOFF32	151
+#define	R_SH_GOT32		160
+#define	R_SH_PLT32		161
+#define	R_SH_COPY		162
+#define	R_SH_GLOB_DAT		163
+#define	R_SH_JMP_SLOT		164
+#define	R_SH_RELATIVE		165
+#define	R_SH_GOTOFF		166
+#define	R_SH_GOTPC		167
+#define	R_SH_GOT20		201
+#define	R_SH_GOTOFF20		202
+#define	R_SH_GOTFUNCDESC	203
+#define	R_SH_GOTFUNCDEST20	204
+#define	R_SH_GOTOFFFUNCDESC	205
+#define	R_SH_GOTOFFFUNCDEST20	206
+#define	R_SH_FUNCDESC		207
+#define	R_SH_FUNCDESC_VALUE	208
+
+#define	R_SH_NUM		256
+
+
+
+#define R_390_NONE		0
+#define R_390_8			1
+#define R_390_12		2
+#define R_390_16		3
+#define R_390_32		4
+#define R_390_PC32		5
+#define R_390_GOT12		6
+#define R_390_GOT32		7
+#define R_390_PLT32		8
+#define R_390_COPY		9
+#define R_390_GLOB_DAT		10
+#define R_390_JMP_SLOT		11
+#define R_390_RELATIVE		12
+#define R_390_GOTOFF32		13
+#define R_390_GOTPC		14
+#define R_390_GOT16		15
+#define R_390_PC16		16
+#define R_390_PC16DBL		17
+#define R_390_PLT16DBL		18
+#define R_390_PC32DBL		19
+#define R_390_PLT32DBL		20
+#define R_390_GOTPCDBL		21
+#define R_390_64		22
+#define R_390_PC64		23
+#define R_390_GOT64		24
+#define R_390_PLT64		25
+#define R_390_GOTENT		26
+#define R_390_GOTOFF16		27
+#define R_390_GOTOFF64		28
+#define R_390_GOTPLT12		29
+#define R_390_GOTPLT16		30
+#define R_390_GOTPLT32		31
+#define R_390_GOTPLT64		32
+#define R_390_GOTPLTENT		33
+#define R_390_PLTOFF16		34
+#define R_390_PLTOFF32		35
+#define R_390_PLTOFF64		36
+#define R_390_TLS_LOAD		37
+#define R_390_TLS_GDCALL	38
+
+#define R_390_TLS_LDCALL	39
+
+#define R_390_TLS_GD32		40
+
+#define R_390_TLS_GD64		41
+
+#define R_390_TLS_GOTIE12	42
+
+#define R_390_TLS_GOTIE32	43
+
+#define R_390_TLS_GOTIE64	44
+
+#define R_390_TLS_LDM32		45
+
+#define R_390_TLS_LDM64		46
+
+#define R_390_TLS_IE32		47
+
+#define R_390_TLS_IE64		48
+
+#define R_390_TLS_IEENT		49
+
+#define R_390_TLS_LE32		50
+
+#define R_390_TLS_LE64		51
+
+#define R_390_TLS_LDO32		52
+
+#define R_390_TLS_LDO64		53
+
+#define R_390_TLS_DTPMOD	54
+#define R_390_TLS_DTPOFF	55
+#define R_390_TLS_TPOFF		56
+
+#define R_390_20		57
+#define R_390_GOT20		58
+#define R_390_GOTPLT20		59
+#define R_390_TLS_GOTIE20	60
+
+
+#define R_390_NUM		61
+
+
+
+#define R_CRIS_NONE		0
+#define R_CRIS_8		1
+#define R_CRIS_16		2
+#define R_CRIS_32		3
+#define R_CRIS_8_PCREL		4
+#define R_CRIS_16_PCREL		5
+#define R_CRIS_32_PCREL		6
+#define R_CRIS_GNU_VTINHERIT	7
+#define R_CRIS_GNU_VTENTRY	8
+#define R_CRIS_COPY		9
+#define R_CRIS_GLOB_DAT		10
+#define R_CRIS_JUMP_SLOT	11
+#define R_CRIS_RELATIVE		12
+#define R_CRIS_16_GOT		13
+#define R_CRIS_32_GOT		14
+#define R_CRIS_16_GOTPLT	15
+#define R_CRIS_32_GOTPLT	16
+#define R_CRIS_32_GOTREL	17
+#define R_CRIS_32_PLT_GOTREL	18
+#define R_CRIS_32_PLT_PCREL	19
+
+#define R_CRIS_NUM		20
+
+
+
+#define R_X86_64_NONE		0
+#define R_X86_64_64		1
+#define R_X86_64_PC32		2
+#define R_X86_64_GOT32		3
+#define R_X86_64_PLT32		4
+#define R_X86_64_COPY		5
+#define R_X86_64_GLOB_DAT	6
+#define R_X86_64_JUMP_SLOT	7
+#define R_X86_64_RELATIVE	8
+#define R_X86_64_GOTPCREL	9
+
+#define R_X86_64_32		10
+#define R_X86_64_32S		11
+#define R_X86_64_16		12
+#define R_X86_64_PC16		13
+#define R_X86_64_8		14
+#define R_X86_64_PC8		15
+#define R_X86_64_DTPMOD64	16
+#define R_X86_64_DTPOFF64	17
+#define R_X86_64_TPOFF64	18
+#define R_X86_64_TLSGD		19
+
+#define R_X86_64_TLSLD		20
+
+#define R_X86_64_DTPOFF32	21
+#define R_X86_64_GOTTPOFF	22
+
+#define R_X86_64_TPOFF32	23
+#define R_X86_64_PC64		24
+#define R_X86_64_GOTOFF64	25
+#define R_X86_64_GOTPC32	26
+#define R_X86_64_GOT64		27
+#define R_X86_64_GOTPCREL64	28
+#define R_X86_64_GOTPC64	29
+#define R_X86_64_GOTPLT64	30
+#define R_X86_64_PLTOFF64	31
+#define R_X86_64_SIZE32		32
+#define R_X86_64_SIZE64		33
+
+#define R_X86_64_GOTPC32_TLSDESC 34
+#define R_X86_64_TLSDESC_CALL   35
+
+#define R_X86_64_TLSDESC        36
+#define R_X86_64_IRELATIVE	37
+#define R_X86_64_RELATIVE64	38
+#define R_X86_64_GOTPCRELX	41
+#define R_X86_64_REX_GOTPCRELX	42
+#define R_X86_64_NUM		43
+
+
+
+#define R_MN10300_NONE		0
+#define R_MN10300_32		1
+#define R_MN10300_16		2
+#define R_MN10300_8		3
+#define R_MN10300_PCREL32	4
+#define R_MN10300_PCREL16	5
+#define R_MN10300_PCREL8	6
+#define R_MN10300_GNU_VTINHERIT	7
+#define R_MN10300_GNU_VTENTRY	8
+#define R_MN10300_24		9
+#define R_MN10300_GOTPC32	10
+#define R_MN10300_GOTPC16	11
+#define R_MN10300_GOTOFF32	12
+#define R_MN10300_GOTOFF24	13
+#define R_MN10300_GOTOFF16	14
+#define R_MN10300_PLT32		15
+#define R_MN10300_PLT16		16
+#define R_MN10300_GOT32		17
+#define R_MN10300_GOT24		18
+#define R_MN10300_GOT16		19
+#define R_MN10300_COPY		20
+#define R_MN10300_GLOB_DAT	21
+#define R_MN10300_JMP_SLOT	22
+#define R_MN10300_RELATIVE	23
+
+#define R_MN10300_NUM		24
+
+
+
+#define R_M32R_NONE		0
+#define R_M32R_16		1
+#define R_M32R_32		2
+#define R_M32R_24		3
+#define R_M32R_10_PCREL		4
+#define R_M32R_18_PCREL		5
+#define R_M32R_26_PCREL		6
+#define R_M32R_HI16_ULO		7
+#define R_M32R_HI16_SLO		8
+#define R_M32R_LO16		9
+#define R_M32R_SDA16		10
+#define R_M32R_GNU_VTINHERIT	11
+#define R_M32R_GNU_VTENTRY	12
+
+#define R_M32R_16_RELA		33
+#define R_M32R_32_RELA		34
+#define R_M32R_24_RELA		35
+#define R_M32R_10_PCREL_RELA	36
+#define R_M32R_18_PCREL_RELA	37
+#define R_M32R_26_PCREL_RELA	38
+#define R_M32R_HI16_ULO_RELA	39
+#define R_M32R_HI16_SLO_RELA	40
+#define R_M32R_LO16_RELA	41
+#define R_M32R_SDA16_RELA	42
+#define R_M32R_RELA_GNU_VTINHERIT	43
+#define R_M32R_RELA_GNU_VTENTRY	44
+#define R_M32R_REL32		45
+
+#define R_M32R_GOT24		48
+#define R_M32R_26_PLTREL	49
+#define R_M32R_COPY		50
+#define R_M32R_GLOB_DAT		51
+#define R_M32R_JMP_SLOT		52
+#define R_M32R_RELATIVE		53
+#define R_M32R_GOTOFF		54
+#define R_M32R_GOTPC24		55
+#define R_M32R_GOT16_HI_ULO	56
+
+#define R_M32R_GOT16_HI_SLO	57
+
+#define R_M32R_GOT16_LO		58
+#define R_M32R_GOTPC_HI_ULO	59
+
+#define R_M32R_GOTPC_HI_SLO	60
+
+#define R_M32R_GOTPC_LO		61
+
+#define R_M32R_GOTOFF_HI_ULO	62
+
+#define R_M32R_GOTOFF_HI_SLO	63
+
+#define R_M32R_GOTOFF_LO	64
+#define R_M32R_NUM		256
+
+#define R_MICROBLAZE_NONE 0
+#define R_MICROBLAZE_32 1
+#define R_MICROBLAZE_32_PCREL 2
+#define R_MICROBLAZE_64_PCREL 3
+#define R_MICROBLAZE_32_PCREL_LO 4
+#define R_MICROBLAZE_64 5
+#define R_MICROBLAZE_32_LO 6
+#define R_MICROBLAZE_SRO32 7
+#define R_MICROBLAZE_SRW32 8
+#define R_MICROBLAZE_64_NONE 9
+#define R_MICROBLAZE_32_SYM_OP_SYM 10
+#define R_MICROBLAZE_GNU_VTINHERIT 11
+#define R_MICROBLAZE_GNU_VTENTRY 12
+#define R_MICROBLAZE_GOTPC_64 13
+#define R_MICROBLAZE_GOT_64 14
+#define R_MICROBLAZE_PLT_64 15
+#define R_MICROBLAZE_REL 16
+#define R_MICROBLAZE_JUMP_SLOT 17
+#define R_MICROBLAZE_GLOB_DAT 18
+#define R_MICROBLAZE_GOTOFF_64 19
+#define R_MICROBLAZE_GOTOFF_32 20
+#define R_MICROBLAZE_COPY 21
+#define R_MICROBLAZE_TLS 22
+#define R_MICROBLAZE_TLSGD 23
+#define R_MICROBLAZE_TLSLD 24
+#define R_MICROBLAZE_TLSDTPMOD32 25
+#define R_MICROBLAZE_TLSDTPREL32 26
+#define R_MICROBLAZE_TLSDTPREL64 27
+#define R_MICROBLAZE_TLSGOTTPREL32 28
+#define R_MICROBLAZE_TLSTPREL32	 29
+
+#define DT_NIOS2_GP             0x70000002
+
+#define R_NIOS2_NONE		0
+#define R_NIOS2_S16		1
+#define R_NIOS2_U16		2
+#define R_NIOS2_PCREL16		3
+#define R_NIOS2_CALL26		4
+#define R_NIOS2_IMM5		5
+#define R_NIOS2_CACHE_OPX	6
+#define R_NIOS2_IMM6		7
+#define R_NIOS2_IMM8		8
+#define R_NIOS2_HI16		9
+#define R_NIOS2_LO16		10
+#define R_NIOS2_HIADJ16		11
+#define R_NIOS2_BFD_RELOC_32	12
+#define R_NIOS2_BFD_RELOC_16	13
+#define R_NIOS2_BFD_RELOC_8	14
+#define R_NIOS2_GPREL		15
+#define R_NIOS2_GNU_VTINHERIT	16
+#define R_NIOS2_GNU_VTENTRY	17
+#define R_NIOS2_UJMP		18
+#define R_NIOS2_CJMP		19
+#define R_NIOS2_CALLR		20
+#define R_NIOS2_ALIGN		21
+#define R_NIOS2_GOT16		22
+#define R_NIOS2_CALL16		23
+#define R_NIOS2_GOTOFF_LO	24
+#define R_NIOS2_GOTOFF_HA	25
+#define R_NIOS2_PCREL_LO	26
+#define R_NIOS2_PCREL_HA	27
+#define R_NIOS2_TLS_GD16	28
+#define R_NIOS2_TLS_LDM16	29
+#define R_NIOS2_TLS_LDO16	30
+#define R_NIOS2_TLS_IE16	31
+#define R_NIOS2_TLS_LE16	32
+#define R_NIOS2_TLS_DTPMOD	33
+#define R_NIOS2_TLS_DTPREL	34
+#define R_NIOS2_TLS_TPREL	35
+#define R_NIOS2_COPY		36
+#define R_NIOS2_GLOB_DAT	37
+#define R_NIOS2_JUMP_SLOT	38
+#define R_NIOS2_RELATIVE	39
+#define R_NIOS2_GOTOFF		40
+#define R_NIOS2_CALL26_NOAT	41
+#define R_NIOS2_GOT_LO		42
+#define R_NIOS2_GOT_HA		43
+#define R_NIOS2_CALL_LO		44
+#define R_NIOS2_CALL_HA		45
+
+#define R_OR1K_NONE		0
+#define R_OR1K_32		1
+#define R_OR1K_16		2
+#define R_OR1K_8		3
+#define R_OR1K_LO_16_IN_INSN	4
+#define R_OR1K_HI_16_IN_INSN	5
+#define R_OR1K_INSN_REL_26	6
+#define R_OR1K_GNU_VTENTRY	7
+#define R_OR1K_GNU_VTINHERIT	8
+#define R_OR1K_32_PCREL		9
+#define R_OR1K_16_PCREL		10
+#define R_OR1K_8_PCREL		11
+#define R_OR1K_GOTPC_HI16	12
+#define R_OR1K_GOTPC_LO16	13
+#define R_OR1K_GOT16		14
+#define R_OR1K_PLT26		15
+#define R_OR1K_GOTOFF_HI16	16
+#define R_OR1K_GOTOFF_LO16	17
+#define R_OR1K_COPY		18
+#define R_OR1K_GLOB_DAT		19
+#define R_OR1K_JMP_SLOT		20
+#define R_OR1K_RELATIVE		21
+#define R_OR1K_TLS_GD_HI16	22
+#define R_OR1K_TLS_GD_LO16	23
+#define R_OR1K_TLS_LDM_HI16	24
+#define R_OR1K_TLS_LDM_LO16	25
+#define R_OR1K_TLS_LDO_HI16	26
+#define R_OR1K_TLS_LDO_LO16	27
+#define R_OR1K_TLS_IE_HI16	28
+#define R_OR1K_TLS_IE_LO16	29
+#define R_OR1K_TLS_LE_HI16	30
+#define R_OR1K_TLS_LE_LO16	31
+#define R_OR1K_TLS_TPOFF	32
+#define R_OR1K_TLS_DTPOFF	33
+#define R_OR1K_TLS_DTPMOD	34
+
+#define R_BPF_NONE		0
+#define R_BPF_MAP_FD		1
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/endian.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/endian.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/endian.h	(revision 331)
@@ -0,0 +1,82 @@
+#ifndef _ENDIAN_H
+#define _ENDIAN_H
+
+#include <features.h>
+
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+#define __PDP_ENDIAN 3412
+
+#if defined(__GNUC__) && defined(__BYTE_ORDER__)
+#define __BYTE_ORDER __BYTE_ORDER__
+#else
+#include <bits/endian.h>
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define BIG_ENDIAN __BIG_ENDIAN
+#define LITTLE_ENDIAN __LITTLE_ENDIAN
+#define PDP_ENDIAN __PDP_ENDIAN
+#define BYTE_ORDER __BYTE_ORDER
+
+#include <stdint.h>
+
+static __inline uint16_t __bswap16(uint16_t __x)
+{
+	return __x<<8 | __x>>8;
+}
+
+static __inline uint32_t __bswap32(uint32_t __x)
+{
+	return __x>>24 | __x>>8&0xff00 | __x<<8&0xff0000 | __x<<24;
+}
+
+static __inline uint64_t __bswap64(uint64_t __x)
+{
+	return __bswap32(__x)+0ULL<<32 | __bswap32(__x>>32);
+}
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define htobe16(x) __bswap16(x)
+#define be16toh(x) __bswap16(x)
+#define betoh16(x) __bswap16(x)
+#define htobe32(x) __bswap32(x)
+#define be32toh(x) __bswap32(x)
+#define betoh32(x) __bswap32(x)
+#define htobe64(x) __bswap64(x)
+#define be64toh(x) __bswap64(x)
+#define betoh64(x) __bswap64(x)
+#define htole16(x) (uint16_t)(x)
+#define le16toh(x) (uint16_t)(x)
+#define letoh16(x) (uint16_t)(x)
+#define htole32(x) (uint32_t)(x)
+#define le32toh(x) (uint32_t)(x)
+#define letoh32(x) (uint32_t)(x)
+#define htole64(x) (uint64_t)(x)
+#define le64toh(x) (uint64_t)(x)
+#define letoh64(x) (uint64_t)(x)
+#else
+#define htobe16(x) (uint16_t)(x)
+#define be16toh(x) (uint16_t)(x)
+#define betoh16(x) (uint16_t)(x)
+#define htobe32(x) (uint32_t)(x)
+#define be32toh(x) (uint32_t)(x)
+#define betoh32(x) (uint32_t)(x)
+#define htobe64(x) (uint64_t)(x)
+#define be64toh(x) (uint64_t)(x)
+#define betoh64(x) (uint64_t)(x)
+#define htole16(x) __bswap16(x)
+#define le16toh(x) __bswap16(x)
+#define letoh16(x) __bswap16(x)
+#define htole32(x) __bswap32(x)
+#define le32toh(x) __bswap32(x)
+#define letoh32(x) __bswap32(x)
+#define htole64(x) __bswap64(x)
+#define le64toh(x) __bswap64(x)
+#define letoh64(x) __bswap64(x)
+#endif
+
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/err.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/err.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/err.h	(revision 331)
@@ -0,0 +1,25 @@
+#ifndef _ERR_H
+#define _ERR_H
+
+#include <features.h>
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void warn(const char *, ...);
+void vwarn(const char *, va_list);
+void warnx(const char *, ...);
+void vwarnx(const char *, va_list);
+
+_Noreturn void err(int, const char *, ...);
+_Noreturn void verr(int, const char *, va_list);
+_Noreturn void errx(int, const char *, ...);
+_Noreturn void verrx(int, const char *, va_list);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/errno.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/errno.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/errno.h	(revision 331)
@@ -0,0 +1,24 @@
+#ifndef	_ERRNO_H
+#define _ERRNO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/errno.h>
+
+int *__errno_location(void);
+#define errno (*__errno_location())
+
+#ifdef _GNU_SOURCE
+extern char *program_invocation_short_name, *program_invocation_name;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: EcnlProtoTool/trunk/musl-1.1.18/include/fcntl.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/fcntl.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/fcntl.h	(revision 331)
@@ -0,0 +1,187 @@
+#ifndef	_FCNTL_H
+#define	_FCNTL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_off_t
+#define __NEED_pid_t
+#define __NEED_mode_t
+
+#ifdef _GNU_SOURCE
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_struct_iovec
+#endif
+
+#include <bits/alltypes.h>
+
+#include <bits/fcntl.h>
+
+struct flock {
+	short l_type;
+	short l_whence;
+	off_t l_start;
+	off_t l_len;
+	pid_t l_pid;
+};
+
+int creat(const char *, mode_t);
+int fcntl(int, int, ...);
+int open(const char *, int, ...);
+int openat(int, const char *, int, ...);
+int posix_fadvise(int, off_t, off_t, int);
+int posix_fallocate(int, off_t, off_t);
+
+#define O_SEARCH  O_PATH
+#define O_EXEC    O_PATH
+
+#define O_ACCMODE (03|O_SEARCH)
+#define O_RDONLY  00
+#define O_WRONLY  01
+#define O_RDWR    02
+
+#define F_OFD_GETLK 36
+#define F_OFD_SETLK 37
+#define F_OFD_SETLKW 38
+
+#define F_DUPFD_CLOEXEC 1030
+
+#define F_RDLCK 0
+#define F_WRLCK 1
+#define F_UNLCK 2
+
+#define FD_CLOEXEC 1
+
+#define AT_FDCWD (-100)
+#define AT_SYMLINK_NOFOLLOW 0x100
+#define AT_REMOVEDIR 0x200
+#define AT_SYMLINK_FOLLOW 0x400
+#define AT_EACCESS 0x200
+
+#define POSIX_FADV_NORMAL     0
+#define POSIX_FADV_RANDOM     1
+#define POSIX_FADV_SEQUENTIAL 2
+#define POSIX_FADV_WILLNEED   3
+#define POSIX_FADV_DONTNEED   4
+#define POSIX_FADV_NOREUSE    5
+
+#undef SEEK_SET
+#undef SEEK_CUR
+#undef SEEK_END
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+#ifndef S_IRUSR
+#define S_ISUID 04000
+#define S_ISGID 02000
+#define S_ISVTX 01000
+#define S_IRUSR 0400
+#define S_IWUSR 0200
+#define S_IXUSR 0100
+#define S_IRWXU 0700
+#define S_IRGRP 0040
+#define S_IWGRP 0020
+#define S_IXGRP 0010
+#define S_IRWXG 0070
+#define S_IROTH 0004
+#define S_IWOTH 0002
+#define S_IXOTH 0001
+#define S_IRWXO 0007
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define AT_NO_AUTOMOUNT 0x800
+#define AT_EMPTY_PATH 0x1000
+
+#define FAPPEND O_APPEND
+#define FFSYNC O_SYNC
+#define FASYNC O_ASYNC
+#define FNONBLOCK O_NONBLOCK
+#define FNDELAY O_NDELAY
+
+#define F_OK 0
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+#define F_ULOCK 0
+#define F_LOCK  1
+#define F_TLOCK 2
+#define F_TEST  3
+
+#define F_SETLEASE	1024
+#define F_GETLEASE	1025
+#define F_NOTIFY	1026
+#define F_CANCELLK	1029
+#define F_SETPIPE_SZ	1031
+#define F_GETPIPE_SZ	1032
+#define F_ADD_SEALS	1033
+#define F_GET_SEALS	1034
+
+#define F_SEAL_SEAL	0x0001
+#define F_SEAL_SHRINK	0x0002
+#define F_SEAL_GROW	0x0004
+#define F_SEAL_WRITE	0x0008
+
+#define DN_ACCESS	0x00000001
+#define DN_MODIFY	0x00000002
+#define DN_CREATE	0x00000004
+#define DN_DELETE	0x00000008
+#define DN_RENAME	0x00000010
+#define DN_ATTRIB	0x00000020
+#define DN_MULTISHOT	0x80000000
+
+int lockf(int, int, off_t);
+#endif
+
+#if defined(_GNU_SOURCE)
+#define F_OWNER_TID 0
+#define F_OWNER_PID 1
+#define F_OWNER_PGRP 2
+#define F_OWNER_GID 2
+struct f_owner_ex {
+	int type;
+	pid_t pid;
+};
+#define FALLOC_FL_KEEP_SIZE 1
+#define FALLOC_FL_PUNCH_HOLE 2
+#define SYNC_FILE_RANGE_WAIT_BEFORE 1
+#define SYNC_FILE_RANGE_WRITE 2
+#define SYNC_FILE_RANGE_WAIT_AFTER 4
+#define SPLICE_F_MOVE 1
+#define SPLICE_F_NONBLOCK 2
+#define SPLICE_F_MORE 4
+#define SPLICE_F_GIFT 8
+int fallocate(int, int, off_t, off_t);
+#define fallocate64 fallocate
+ssize_t readahead(int, off_t, size_t);
+int sync_file_range(int, off_t, off_t, unsigned);
+ssize_t vmsplice(int, const struct iovec *, size_t, unsigned);
+ssize_t splice(int, off_t *, int, off_t *, size_t, unsigned);
+ssize_t tee(int, int, size_t, unsigned);
+#define loff_t off_t
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define F_GETLK64 F_GETLK
+#define F_SETLK64 F_SETLK
+#define F_SETLKW64 F_SETLKW
+#define flock64 flock
+#define open64 open
+#define openat64 openat
+#define creat64 creat
+#define lockf64 lockf
+#define posix_fadvise64 posix_fadvise
+#define posix_fallocate64 posix_fallocate
+#define off64_t off_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/features.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/features.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/features.h	(revision 331)
@@ -0,0 +1,38 @@
+#ifndef _FEATURES_H
+#define _FEATURES_H
+
+#if defined(_ALL_SOURCE) && !defined(_GNU_SOURCE)
+#define _GNU_SOURCE 1
+#endif
+
+#if defined(_DEFAULT_SOURCE) && !defined(_BSD_SOURCE)
+#define _BSD_SOURCE 1
+#endif
+
+#if !defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) \
+ && !defined(_XOPEN_SOURCE) && !defined(_GNU_SOURCE) \
+ && !defined(_BSD_SOURCE) && !defined(__STRICT_ANSI__)
+#define _BSD_SOURCE 1
+#define _XOPEN_SOURCE 700
+#endif
+
+#if __STDC_VERSION__ >= 199901L
+#define __restrict restrict
+#elif !defined(__GNUC__)
+#define __restrict
+#endif
+
+#if __STDC_VERSION__ >= 199901L || defined(__cplusplus)
+#define __inline inline
+#elif !defined(__GNUC__)
+#define __inline
+#endif
+
+#if __STDC_VERSION__ >= 201112L
+#elif defined(__GNUC__)
+#define _Noreturn __attribute__((__noreturn__))
+#else
+#define _Noreturn
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/fenv.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/fenv.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/fenv.h	(revision 331)
@@ -0,0 +1,28 @@
+#ifndef _FENV_H
+#define _FENV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bits/fenv.h>
+
+int feclearexcept(int);
+int fegetexceptflag(fexcept_t *, int);
+int feraiseexcept(int);
+int fesetexceptflag(const fexcept_t *, int);
+int fetestexcept(int);
+
+int fegetround(void);
+int fesetround(int);
+
+int fegetenv(fenv_t *);
+int feholdexcept(fenv_t *);
+int fesetenv(const fenv_t *);
+int feupdateenv(const fenv_t *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
Index: EcnlProtoTool/trunk/musl-1.1.18/include/float.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/float.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/float.h	(revision 331)
@@ -0,0 +1,52 @@
+#ifndef _FLOAT_H
+#define _FLOAT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int __flt_rounds(void);
+#define FLT_ROUNDS (__flt_rounds())
+
+#define FLT_RADIX 2
+
+#define FLT_TRUE_MIN 1.40129846432481707092e-45F
+#define FLT_MIN 1.17549435082228750797e-38F
+#define FLT_MAX 3.40282346638528859812e+38F
+#define FLT_EPSILON 1.1920928955078125e-07F
+
+#define FLT_MANT_DIG 24
+#define FLT_MIN_EXP (-125)
+#define FLT_MAX_EXP 128
+#define FLT_HAS_SUBNORM 1
+
+#define FLT_DIG 6
+#define FLT_DECIMAL_DIG 9
+#define FLT_MIN_10_EXP (-37)
+#define FLT_MAX_10_EXP 38
+
+#define DBL_TRUE_MIN 4.94065645841246544177e-324
+#define DBL_MIN 2.22507385850720138309e-308
+#define DBL_MAX 1.79769313486231570815e+308
+#define DBL_EPSILON 2.22044604925031308085e-16
+
+#define DBL_MANT_DIG 53
+#define DBL_MIN_EXP (-1021)
+#define DBL_MAX_EXP 1024
+#define DBL_HAS_SUBNORM 1
+
+#define DBL_DIG 15
+#define DBL_DECIMAL_DIG 17
+#define DBL_MIN_10_EXP (-307)
+#define DBL_MAX_10_EXP 308
+
+#define LDBL_HAS_SUBNORM 1
+#define LDBL_DECIMAL_DIG DECIMAL_DIG
+
+#include <bits/float.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/fmtmsg.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/fmtmsg.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/fmtmsg.h	(revision 331)
@@ -0,0 +1,47 @@
+#ifndef _FMTMSG_H
+#define _FMTMSG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MM_HARD		1
+#define MM_SOFT		2
+#define MM_FIRM		4
+
+#define MM_APPL		8
+#define MM_UTIL		16
+#define MM_OPSYS	32
+
+#define MM_RECOVER	64
+#define MM_NRECOV	128
+
+#define MM_PRINT	256
+#define MM_CONSOLE	512
+
+#define MM_NULLMC	0L
+
+#define MM_HALT		1
+#define MM_ERROR	2
+#define MM_WARNING	3
+#define MM_INFO		4
+#define MM_NOSEV	0
+
+#define MM_OK		0
+#define MM_NOTOK	(-1)
+#define MM_NOMSG	1
+#define MM_NOCON	4
+
+#define MM_NULLLBL	((char*)0)
+#define MM_NULLTXT	((char*)0)
+#define MM_NULLACT	((char*)0)
+#define MM_NULLTAG	((char*)0)
+#define MM_NULLSEV	0
+
+int fmtmsg(long, const char *, int, const char *, const char *, const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/fnmatch.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/fnmatch.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/fnmatch.h	(revision 331)
@@ -0,0 +1,24 @@
+#ifndef	_FNMATCH_H
+#define	_FNMATCH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define	FNM_PATHNAME 0x1
+#define	FNM_NOESCAPE 0x2
+#define	FNM_PERIOD   0x4
+#define	FNM_LEADING_DIR	0x8           
+#define	FNM_CASEFOLD	0x10
+#define	FNM_FILE_NAME	FNM_PATHNAME
+
+#define	FNM_NOMATCH 1
+#define FNM_NOSYS   (-1)
+
+int fnmatch(const char *, const char *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/ftw.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/ftw.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/ftw.h	(revision 331)
@@ -0,0 +1,41 @@
+#ifndef _FTW_H
+#define	_FTW_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <sys/stat.h>
+
+#define FTW_F   1
+#define FTW_D   2
+#define FTW_DNR 3
+#define FTW_NS  4
+#define FTW_SL  5
+#define FTW_DP  6
+#define FTW_SLN 7
+
+#define FTW_PHYS  1
+#define FTW_MOUNT 2
+#define FTW_CHDIR 4
+#define FTW_DEPTH 8
+
+struct FTW {
+	int base;
+	int level;
+};
+
+int ftw(const char *, int (*)(const char *, const struct stat *, int), int);
+int nftw(const char *, int (*)(const char *, const struct stat *, int, struct FTW *), int, int);
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define ftw64 ftw
+#define nftw64 nftw
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/getopt.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/getopt.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/getopt.h	(revision 331)
@@ -0,0 +1,30 @@
+#ifndef _GETOPT_H
+#define _GETOPT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int getopt(int, char * const [], const char *);
+extern char *optarg;
+extern int optind, opterr, optopt, optreset;
+
+struct option {
+	const char *name;
+	int has_arg;
+	int *flag;
+	int val;
+};
+
+int getopt_long(int, char *const *, const char *, const struct option *, int *);
+int getopt_long_only(int, char *const *, const char *, const struct option *, int *);
+
+#define no_argument        0
+#define required_argument  1
+#define optional_argument  2
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/glob.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/glob.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/glob.h	(revision 331)
@@ -0,0 +1,49 @@
+#ifndef	_GLOB_H
+#define	_GLOB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+typedef struct {
+	size_t gl_pathc;
+	char **gl_pathv;
+	size_t gl_offs;
+	int __dummy1;
+	void *__dummy2[5];
+} glob_t;
+
+int  glob(const char *__restrict, int, int (*)(const char *, int), glob_t *__restrict);
+void globfree(glob_t *);
+
+#define GLOB_ERR      0x01
+#define GLOB_MARK     0x02
+#define GLOB_NOSORT   0x04
+#define GLOB_DOOFFS   0x08
+#define GLOB_NOCHECK  0x10
+#define GLOB_APPEND   0x20
+#define GLOB_NOESCAPE 0x40
+#define	GLOB_PERIOD   0x80
+
+#define GLOB_NOSPACE 1
+#define GLOB_ABORTED 2
+#define GLOB_NOMATCH 3
+#define GLOB_NOSYS   4
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define glob64 glob
+#define globfree64 globfree
+#define glob64_t glob_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/grp.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/grp.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/grp.h	(revision 331)
@@ -0,0 +1,53 @@
+#ifndef	_GRP_H
+#define	_GRP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_gid_t
+
+#ifdef _GNU_SOURCE
+#define __NEED_FILE
+#endif
+
+#include <bits/alltypes.h>
+
+struct group {
+	char *gr_name;
+	char *gr_passwd;
+	gid_t gr_gid;
+	char **gr_mem;
+};
+
+struct group  *getgrgid(gid_t);
+struct group  *getgrnam(const char *);
+
+int getgrgid_r(gid_t, struct group *, char *, size_t, struct group **);
+int getgrnam_r(const char *, struct group *, char *, size_t, struct group **);
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+struct group  *getgrent(void);
+void           endgrent(void);
+void           setgrent(void);
+#endif
+
+#ifdef _GNU_SOURCE
+struct group  *fgetgrent(FILE *);
+int putgrent(const struct group *, FILE *);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int getgrouplist(const char *, gid_t, gid_t *, int *);
+int setgroups(size_t, const gid_t *);
+int initgroups(const char *, gid_t);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/iconv.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/iconv.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/iconv.h	(revision 331)
@@ -0,0 +1,24 @@
+#ifndef _ICONV_H
+#define _ICONV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+typedef void *iconv_t;
+
+iconv_t iconv_open(const char *, const char *);
+size_t iconv(iconv_t, char **__restrict, size_t *__restrict, char **__restrict, size_t *__restrict);
+int iconv_close(iconv_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/ifaddrs.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/ifaddrs.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/ifaddrs.h	(revision 331)
@@ -0,0 +1,35 @@
+#ifndef _IFADDRS_H
+#define _IFADDRS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+struct ifaddrs {
+	struct ifaddrs *ifa_next;
+	char *ifa_name;
+	unsigned ifa_flags;
+	struct sockaddr *ifa_addr;
+	struct sockaddr *ifa_netmask;
+	union {
+		struct sockaddr *ifu_broadaddr;
+		struct sockaddr *ifu_dstaddr;
+	} ifa_ifu;
+	void *ifa_data;
+};
+#define ifa_broadaddr ifa_ifu.ifu_broadaddr
+#define ifa_dstaddr ifa_ifu.ifu_dstaddr
+
+void freeifaddrs(struct ifaddrs *);
+int getifaddrs(struct ifaddrs **);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: EcnlProtoTool/trunk/musl-1.1.18/include/inttypes.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/inttypes.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/inttypes.h	(revision 331)
@@ -0,0 +1,229 @@
+#ifndef _INTTYPES_H
+#define _INTTYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <stdint.h>
+
+#define __NEED_wchar_t
+#include <bits/alltypes.h>
+
+typedef struct { intmax_t quot, rem; } imaxdiv_t;
+
+intmax_t imaxabs(intmax_t);
+imaxdiv_t imaxdiv(intmax_t, intmax_t);
+
+intmax_t strtoimax(const char *__restrict, char **__restrict, int);
+uintmax_t strtoumax(const char *__restrict, char **__restrict, int);
+
+intmax_t wcstoimax(const wchar_t *__restrict, wchar_t **__restrict, int);
+uintmax_t wcstoumax(const wchar_t *__restrict, wchar_t **__restrict, int);
+
+#if UINTPTR_MAX == UINT64_MAX
+#define __PRI64  "l"
+#define __PRIPTR "l"
+#else
+#define __PRI64  "ll"
+#define __PRIPTR ""
+#endif
+
+#define PRId8  "d"
+#define PRId16 "d"
+#define PRId32 "d"
+#define PRId64 __PRI64 "d"
+
+#define PRIdLEAST8  "d"
+#define PRIdLEAST16 "d"
+#define PRIdLEAST32 "d"
+#define PRIdLEAST64 __PRI64 "d"
+
+#define PRIdFAST8  "d"
+#define PRIdFAST16 "d"
+#define PRIdFAST32 "d"
+#define PRIdFAST64 __PRI64 "d"
+
+#define PRIi8  "i"
+#define PRIi16 "i"
+#define PRIi32 "i"
+#define PRIi64 __PRI64 "i"
+
+#define PRIiLEAST8  "i"
+#define PRIiLEAST16 "i"
+#define PRIiLEAST32 "i"
+#define PRIiLEAST64 __PRI64 "i"
+
+#define PRIiFAST8  "i"
+#define PRIiFAST16 "i"
+#define PRIiFAST32 "i"
+#define PRIiFAST64 __PRI64 "i"
+
+#define PRIo8  "o"
+#define PRIo16 "o"
+#define PRIo32 "o"
+#define PRIo64 __PRI64 "o"
+
+#define PRIoLEAST8  "o"
+#define PRIoLEAST16 "o"
+#define PRIoLEAST32 "o"
+#define PRIoLEAST64 __PRI64 "o"
+
+#define PRIoFAST8  "o"
+#define PRIoFAST16 "o"
+#define PRIoFAST32 "o"
+#define PRIoFAST64 __PRI64 "o"
+
+#define PRIu8  "u"
+#define PRIu16 "u"
+#define PRIu32 "u"
+#define PRIu64 __PRI64 "u"
+
+#define PRIuLEAST8  "u"
+#define PRIuLEAST16 "u"
+#define PRIuLEAST32 "u"
+#define PRIuLEAST64 __PRI64 "u"
+
+#define PRIuFAST8  "u"
+#define PRIuFAST16 "u"
+#define PRIuFAST32 "u"
+#define PRIuFAST64 __PRI64 "u"
+
+#define PRIx8  "x"
+#define PRIx16 "x"
+#define PRIx32 "x"
+#define PRIx64 __PRI64 "x"
+
+#define PRIxLEAST8  "x"
+#define PRIxLEAST16 "x"
+#define PRIxLEAST32 "x"
+#define PRIxLEAST64 __PRI64 "x"
+
+#define PRIxFAST8  "x"
+#define PRIxFAST16 "x"
+#define PRIxFAST32 "x"
+#define PRIxFAST64 __PRI64 "x"
+
+#define PRIX8  "X"
+#define PRIX16 "X"
+#define PRIX32 "X"
+#define PRIX64 __PRI64 "X"
+
+#define PRIXLEAST8  "X"
+#define PRIXLEAST16 "X"
+#define PRIXLEAST32 "X"
+#define PRIXLEAST64 __PRI64 "X"
+
+#define PRIXFAST8  "X"
+#define PRIXFAST16 "X"
+#define PRIXFAST32 "X"
+#define PRIXFAST64 __PRI64 "X"
+
+#define PRIdMAX __PRI64 "d"
+#define PRIiMAX __PRI64 "i"
+#define PRIoMAX __PRI64 "o"
+#define PRIuMAX __PRI64 "u"
+#define PRIxMAX __PRI64 "x"
+#define PRIXMAX __PRI64 "X"
+
+#define PRIdPTR __PRIPTR "d"
+#define PRIiPTR __PRIPTR "i"
+#define PRIoPTR __PRIPTR "o"
+#define PRIuPTR __PRIPTR "u"
+#define PRIxPTR __PRIPTR "x"
+#define PRIXPTR __PRIPTR "X"
+
+#define SCNd8   "hhd"
+#define SCNd16  "hd"
+#define SCNd32  "d"
+#define SCNd64  __PRI64 "d"
+
+#define SCNdLEAST8  "hhd"
+#define SCNdLEAST16 "hd"
+#define SCNdLEAST32 "d"
+#define SCNdLEAST64 __PRI64 "d"
+
+#define SCNdFAST8  "hhd"
+#define SCNdFAST16 "d"
+#define SCNdFAST32 "d"
+#define SCNdFAST64 __PRI64 "d"
+
+#define SCNi8   "hhi"
+#define SCNi16  "hi"
+#define SCNi32  "i"
+#define SCNi64  __PRI64 "i"
+
+#define SCNiLEAST8  "hhi"
+#define SCNiLEAST16 "hi"
+#define SCNiLEAST32 "i"
+#define SCNiLEAST64 __PRI64 "i"
+
+#define SCNiFAST8  "hhi"
+#define SCNiFAST16 "i"
+#define SCNiFAST32 "i"
+#define SCNiFAST64 __PRI64 "i"
+
+#define SCNu8   "hhu"
+#define SCNu16  "hu"
+#define SCNu32  "u"
+#define SCNu64  __PRI64 "u"
+
+#define SCNuLEAST8  "hhu"
+#define SCNuLEAST16 "hu"
+#define SCNuLEAST32 "u"
+#define SCNuLEAST64 __PRI64 "u"
+
+#define SCNuFAST8 "hhu"
+#define SCNuFAST16 "u"
+#define SCNuFAST32 "u"
+#define SCNuFAST64 __PRI64 "u"
+
+#define SCNo8   "hho"
+#define SCNo16  "ho"
+#define SCNo32  "o"
+#define SCNo64  __PRI64 "o"
+
+#define SCNoLEAST8  "hho"
+#define SCNoLEAST16 "ho"
+#define SCNoLEAST32 "o"
+#define SCNoLEAST64 __PRI64 "o"
+
+#define SCNoFAST8  "hho"
+#define SCNoFAST16 "o"
+#define SCNoFAST32 "o"
+#define SCNoFAST64 __PRI64 "o"
+
+#define SCNx8   "hhx"
+#define SCNx16  "hx"
+#define SCNx32  "x"
+#define SCNx64  __PRI64 "x"
+
+#define SCNxLEAST8  "hhx"
+#define SCNxLEAST16 "hx"
+#define SCNxLEAST32 "x"
+#define SCNxLEAST64 __PRI64 "x"
+
+#define SCNxFAST8  "hhx"
+#define SCNxFAST16 "x"
+#define SCNxFAST32 "x"
+#define SCNxFAST64 __PRI64 "x"
+
+#define SCNdMAX __PRI64 "d"
+#define SCNiMAX __PRI64 "i"
+#define SCNoMAX __PRI64 "o"
+#define SCNuMAX __PRI64 "u"
+#define SCNxMAX __PRI64 "x"
+
+#define SCNdPTR __PRIPTR "d"
+#define SCNiPTR __PRIPTR "i"
+#define SCNoPTR __PRIPTR "o"
+#define SCNuPTR __PRIPTR "u"
+#define SCNxPTR __PRIPTR "x"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: EcnlProtoTool/trunk/musl-1.1.18/include/iso646.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/iso646.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/iso646.h	(revision 331)
@@ -0,0 +1,20 @@
+#ifndef _ISO646_H
+#define _ISO646_H
+
+#ifndef __cplusplus
+
+#define and    &&
+#define and_eq &=
+#define bitand &
+#define bitor  |
+#define compl  ~
+#define not    !
+#define not_eq !=
+#define or     ||
+#define or_eq  |=
+#define xor    ^
+#define xor_eq ^=
+
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/langinfo.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/langinfo.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/langinfo.h	(revision 331)
@@ -0,0 +1,98 @@
+#ifndef _LANGINFO_H
+#define _LANGINFO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <nl_types.h>
+
+#define __NEED_locale_t
+
+#include <bits/alltypes.h>
+
+#define ABDAY_1 0x20000
+#define ABDAY_2 0x20001
+#define ABDAY_3 0x20002
+#define ABDAY_4 0x20003
+#define ABDAY_5 0x20004
+#define ABDAY_6 0x20005
+#define ABDAY_7 0x20006
+
+#define DAY_1 0x20007
+#define DAY_2 0x20008
+#define DAY_3 0x20009
+#define DAY_4 0x2000A
+#define DAY_5 0x2000B
+#define DAY_6 0x2000C
+#define DAY_7 0x2000D
+
+#define ABMON_1 0x2000E
+#define ABMON_2 0x2000F
+#define ABMON_3 0x20010
+#define ABMON_4 0x20011
+#define ABMON_5 0x20012
+#define ABMON_6 0x20013
+#define ABMON_7 0x20014
+#define ABMON_8 0x20015
+#define ABMON_9 0x20016
+#define ABMON_10 0x20017
+#define ABMON_11 0x20018
+#define ABMON_12 0x20019
+
+#define MON_1 0x2001A
+#define MON_2 0x2001B
+#define MON_3 0x2001C
+#define MON_4 0x2001D
+#define MON_5 0x2001E
+#define MON_6 0x2001F
+#define MON_7 0x20020
+#define MON_8 0x20021
+#define MON_9 0x20022
+#define MON_10 0x20023
+#define MON_11 0x20024
+#define MON_12 0x20025
+
+#define AM_STR 0x20026
+#define PM_STR 0x20027
+
+#define D_T_FMT 0x20028
+#define D_FMT 0x20029
+#define T_FMT 0x2002A
+#define T_FMT_AMPM 0x2002B
+
+#define ERA 0x2002C
+#define ERA_D_FMT 0x2002E
+#define ALT_DIGITS 0x2002F
+#define ERA_D_T_FMT 0x20030
+#define ERA_T_FMT 0x20031
+
+#define CODESET 14
+
+#define CRNCYSTR 0x4000F
+
+#define RADIXCHAR 0x10000
+#define THOUSEP 0x10001
+#define YESEXPR 0x50000
+#define NOEXPR 0x50001
+
+#define _NL_LOCALE_NAME(cat) (((cat)<<16) | 0xffff)
+
+#if defined(_GNU_SOURCE)
+#define NL_LOCALE_NAME(cat) _NL_LOCALE_NAME(cat)
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define YESSTR 0x50002
+#define NOSTR 0x50003
+#endif
+
+char *nl_langinfo(nl_item);
+char *nl_langinfo_l(nl_item, locale_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/lastlog.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/lastlog.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/lastlog.h	(revision 331)
@@ -0,0 +1,1 @@
+#include <utmp.h>
Index: EcnlProtoTool/trunk/musl-1.1.18/include/libgen.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/libgen.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/libgen.h	(revision 331)
@@ -0,0 +1,15 @@
+#ifndef _LIBGEN_H
+#define _LIBGEN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char *dirname(char *);
+char *basename(char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/libintl.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/libintl.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/libintl.h	(revision 331)
@@ -0,0 +1,33 @@
+#ifndef _LIBINTL_H
+#define _LIBINTL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __USE_GNU_GETTEXT 1
+#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 1 : -1)
+
+#if __GNUC__ >= 3
+#define __fa(n) __attribute__ ((__format_arg__ (n)))
+#else
+#define __fa(n)
+#endif
+
+char *gettext(const char *) __fa(1);
+char *dgettext(const char *, const char *) __fa(2);
+char *dcgettext(const char *, const char *, int) __fa(2);
+char *ngettext(const char *, const char *, unsigned long) __fa(1) __fa(2);
+char *dngettext(const char *, const char *, const char *, unsigned long) __fa(2) __fa(3);
+char *dcngettext(const char *, const char *, const char *, unsigned long, int) __fa(2) __fa(3);
+char *textdomain(const char *);
+char *bindtextdomain (const char *, const char *);
+char *bind_textdomain_codeset(const char *, const char *);
+
+#undef __fa
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/limits.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/limits.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/limits.h	(revision 331)
@@ -0,0 +1,154 @@
+#ifndef _LIMITS_H
+#define _LIMITS_H
+
+#include <features.h>
+
+/* Most limits are system-specific */
+
+#include <bits/limits.h>
+
+/* Support signed or unsigned plain-char */
+
+#if '\0'-1 > 0
+#define CHAR_MIN 0
+#define CHAR_MAX 255
+#else
+#define CHAR_MIN (-128)
+#define CHAR_MAX 127
+#endif
+
+/* Some universal constants... */
+
+#define CHAR_BIT 8
+#define SCHAR_MIN (-128)
+#define SCHAR_MAX 127
+#define UCHAR_MAX 255
+#define SHRT_MIN  (-1-0x7fff)
+#define SHRT_MAX  0x7fff
+#define USHRT_MAX 0xffff
+#define INT_MIN  (-1-0x7fffffff)
+#define INT_MAX  0x7fffffff
+#define UINT_MAX 0xffffffffU
+#define LONG_MIN (-LONG_MAX-1)
+#define ULONG_MAX (2UL*LONG_MAX+1)
+#define LLONG_MIN (-LLONG_MAX-1)
+#define ULLONG_MAX (2ULL*LLONG_MAX+1)
+
+#define MB_LEN_MAX 4
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define PIPE_BUF 4096
+#ifdef PAGE_SIZE
+#define PAGESIZE PAGE_SIZE
+#endif
+#define FILESIZEBITS 64
+#define NAME_MAX 255
+#define SYMLINK_MAX 255
+#define PATH_MAX 4096
+#define NZERO 20
+#define NGROUPS_MAX 32
+#define ARG_MAX 131072
+#define IOV_MAX 1024
+#define SYMLOOP_MAX 40
+#define WORD_BIT 32
+#define SSIZE_MAX LONG_MAX
+#define TZNAME_MAX 6
+#define TTY_NAME_MAX 32
+#define HOST_NAME_MAX 255
+
+/* Implementation choices... */
+
+#define PTHREAD_KEYS_MAX 128
+#define PTHREAD_STACK_MIN 2048
+#define PTHREAD_DESTRUCTOR_ITERATIONS 4
+#define SEM_VALUE_MAX 0x7fffffff
+#define SEM_NSEMS_MAX 256
+#define DELAYTIMER_MAX 0x7fffffff
+#define MQ_PRIO_MAX 32768
+#define LOGIN_NAME_MAX 256
+
+/* Arbitrary numbers... */
+
+#define BC_BASE_MAX 99
+#define BC_DIM_MAX 2048
+#define BC_SCALE_MAX 99
+#define BC_STRING_MAX 1000
+#define CHARCLASS_NAME_MAX 14
+#define COLL_WEIGHTS_MAX 2
+#define EXPR_NEST_MAX 32
+#define LINE_MAX 4096
+#define RE_DUP_MAX 255
+
+#define NL_ARGMAX 9
+#define NL_LANGMAX 32
+#define NL_MSGMAX 32767
+#define NL_SETMAX 255
+#define NL_TEXTMAX 2048
+
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) \
+ || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700)
+
+#define NL_NMAX 16
+
+#endif
+
+/* POSIX/SUS requirements follow. These numbers come directly
+ * from SUS and have nothing to do with the host system. */
+
+#define _POSIX_AIO_LISTIO_MAX   2
+#define _POSIX_AIO_MAX          1
+#define _POSIX_ARG_MAX          4096
+#define _POSIX_CHILD_MAX        25
+#define _POSIX_CLOCKRES_MIN     20000000
+#define _POSIX_DELAYTIMER_MAX   32
+#define _POSIX_HOST_NAME_MAX    255
+#define _POSIX_LINK_MAX         8
+#define _POSIX_LOGIN_NAME_MAX   9
+#define _POSIX_MAX_CANON        255
+#define _POSIX_MAX_INPUT        255
+#define _POSIX_MQ_OPEN_MAX      8
+#define _POSIX_MQ_PRIO_MAX      32
+#define _POSIX_NAME_MAX         14
+#define _POSIX_NGROUPS_MAX      8
+#define _POSIX_OPEN_MAX         20
+#define _POSIX_PATH_MAX         256
+#define _POSIX_PIPE_BUF         512
+#define _POSIX_RE_DUP_MAX       255
+#define _POSIX_RTSIG_MAX        8
+#define _POSIX_SEM_NSEMS_MAX    256
+#define _POSIX_SEM_VALUE_MAX    32767
+#define _POSIX_SIGQUEUE_MAX     32
+#define _POSIX_SSIZE_MAX        32767
+#define _POSIX_STREAM_MAX       8
+#define _POSIX_SS_REPL_MAX      4
+#define _POSIX_SYMLINK_MAX      255
+#define _POSIX_SYMLOOP_MAX      8
+#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
+#define _POSIX_THREAD_KEYS_MAX  128
+#define _POSIX_THREAD_THREADS_MAX 64
+#define _POSIX_TIMER_MAX        32
+#define _POSIX_TRACE_EVENT_NAME_MAX 30
+#define _POSIX_TRACE_NAME_MAX   8
+#define _POSIX_TRACE_SYS_MAX    8
+#define _POSIX_TRACE_USER_EVENT_MAX 32
+#define _POSIX_TTY_NAME_MAX     9
+#define _POSIX_TZNAME_MAX       6
+#define _POSIX2_BC_BASE_MAX     99
+#define _POSIX2_BC_DIM_MAX      2048
+#define _POSIX2_BC_SCALE_MAX    99
+#define _POSIX2_BC_STRING_MAX   1000
+#define _POSIX2_CHARCLASS_NAME_MAX 14
+#define _POSIX2_COLL_WEIGHTS_MAX 2
+#define _POSIX2_EXPR_NEST_MAX   32
+#define _POSIX2_LINE_MAX        2048
+#define _POSIX2_RE_DUP_MAX      255
+
+#define _XOPEN_IOV_MAX          16
+#define _XOPEN_NAME_MAX         255
+#define _XOPEN_PATH_MAX         1024
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/link.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/link.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/link.h	(revision 331)
@@ -0,0 +1,53 @@
+#ifndef _LINK_H
+#define _LINK_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <elf.h>
+#define __NEED_size_t
+#define __NEED_uint32_t
+#include <bits/alltypes.h>
+
+#if UINTPTR_MAX > 0xffffffff
+#define ElfW(type) Elf64_ ## type
+#else
+#define ElfW(type) Elf32_ ## type
+#endif
+
+#include <bits/link.h>
+
+struct dl_phdr_info {
+	ElfW(Addr) dlpi_addr;
+	const char *dlpi_name;
+	const ElfW(Phdr) *dlpi_phdr;
+	ElfW(Half) dlpi_phnum;
+	unsigned long long int dlpi_adds;
+	unsigned long long int dlpi_subs;
+	size_t dlpi_tls_modid;
+	void *dlpi_tls_data;
+};
+
+struct link_map {
+	ElfW(Addr) l_addr;
+	char *l_name;
+	ElfW(Dyn) *l_ld;
+	struct link_map *l_next, *l_prev;
+};
+
+struct r_debug {
+	int r_version;
+	struct link_map *r_map;
+	ElfW(Addr) r_brk;
+	enum { RT_CONSISTENT, RT_ADD, RT_DELETE } r_state;
+	ElfW(Addr) r_ldbase;
+};
+
+int dl_iterate_phdr(int (*)(struct dl_phdr_info *, size_t, void *), void *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/locale.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/locale.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/locale.h	(revision 331)
@@ -0,0 +1,86 @@
+#ifndef	_LOCALE_H
+#define	_LOCALE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#ifdef __cplusplus
+#define NULL 0L
+#else
+#define NULL ((void*)0)
+#endif
+
+#define LC_CTYPE    0
+#define LC_NUMERIC  1
+#define LC_TIME     2
+#define LC_COLLATE  3
+#define LC_MONETARY 4
+#define LC_MESSAGES 5
+#define LC_ALL      6
+
+struct lconv {
+	char *decimal_point;
+	char *thousands_sep;
+	char *grouping;
+
+	char *int_curr_symbol;
+	char *currency_symbol;
+	char *mon_decimal_point;
+	char *mon_thousands_sep;
+	char *mon_grouping;
+	char *positive_sign;
+	char *negative_sign;
+	char int_frac_digits;
+	char frac_digits;
+	char p_cs_precedes;
+	char p_sep_by_space;
+	char n_cs_precedes;
+	char n_sep_by_space;
+	char p_sign_posn;
+	char n_sign_posn;
+	char int_p_cs_precedes;
+	char int_p_sep_by_space;
+	char int_n_cs_precedes;
+	char int_n_sep_by_space;
+	char int_p_sign_posn;
+	char int_n_sign_posn;
+};
+
+
+char *setlocale (int, const char *);
+struct lconv *localeconv(void);
+
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define __NEED_locale_t
+
+#include <bits/alltypes.h>
+
+#define LC_GLOBAL_LOCALE ((locale_t)-1)
+
+#define LC_CTYPE_MASK    (1<<LC_CTYPE)
+#define LC_NUMERIC_MASK  (1<<LC_NUMERIC)
+#define LC_TIME_MASK     (1<<LC_TIME)
+#define LC_COLLATE_MASK  (1<<LC_COLLATE)
+#define LC_MONETARY_MASK (1<<LC_MONETARY)
+#define LC_MESSAGES_MASK (1<<LC_MESSAGES)
+#define LC_ALL_MASK      0x7fffffff
+
+locale_t duplocale(locale_t);
+void freelocale(locale_t);
+locale_t newlocale(int, const char *, locale_t);
+locale_t uselocale(locale_t);
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/malloc.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/malloc.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/malloc.h	(revision 331)
@@ -0,0 +1,25 @@
+#ifndef _MALLOC_H
+#define _MALLOC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+void *malloc (size_t);
+void *calloc (size_t, size_t);
+void *realloc (void *, size_t);
+void free (void *);
+void *valloc (size_t);
+void *memalign(size_t, size_t);
+
+size_t malloc_usable_size(void *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/math.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/math.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/math.h	(revision 331)
@@ -0,0 +1,430 @@
+#ifndef _MATH_H
+#define _MATH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_float_t
+#define __NEED_double_t
+#include <bits/alltypes.h>
+
+#if 100*__GNUC__+__GNUC_MINOR__ >= 303
+#define NAN       __builtin_nanf("")
+#define INFINITY  __builtin_inff()
+#else
+#define NAN       (0.0f/0.0f)
+#define INFINITY  1e5000f
+#endif
+
+#define HUGE_VALF INFINITY
+#define HUGE_VAL  ((double)INFINITY)
+#define HUGE_VALL ((long double)INFINITY)
+
+#define MATH_ERRNO  1
+#define MATH_ERREXCEPT 2
+#define math_errhandling 2
+
+#define FP_ILOGBNAN (-1-(int)(((unsigned)-1)>>1))
+#define FP_ILOGB0 FP_ILOGBNAN
+
+#define FP_NAN       0
+#define FP_INFINITE  1
+#define FP_ZERO      2
+#define FP_SUBNORMAL 3
+#define FP_NORMAL    4
+
+int __fpclassify(double);
+int __fpclassifyf(float);
+int __fpclassifyl(long double);
+
+static __inline unsigned __FLOAT_BITS(float __f)
+{
+	union {float __f; unsigned __i;} __u;
+	__u.__f = __f;
+	return __u.__i;
+}
+static __inline unsigned long long __DOUBLE_BITS(double __f)
+{
+	union {double __f; unsigned long long __i;} __u;
+	__u.__f = __f;
+	return __u.__i;
+}
+
+#define fpclassify(x) ( \
+	sizeof(x) == sizeof(float) ? __fpclassifyf(x) : \
+	sizeof(x) == sizeof(double) ? __fpclassify(x) : \
+	__fpclassifyl(x) )
+
+#define isinf(x) ( \
+	sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) == 0x7f800000 : \
+	sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) == 0x7ffULL<<52 : \
+	__fpclassifyl(x) == FP_INFINITE)
+
+#define isnan(x) ( \
+	sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) > 0x7f800000 : \
+	sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) > 0x7ffULL<<52 : \
+	__fpclassifyl(x) == FP_NAN)
+
+#define isnormal(x) ( \
+	sizeof(x) == sizeof(float) ? ((__FLOAT_BITS(x)+0x00800000) & 0x7fffffff) >= 0x01000000 : \
+	sizeof(x) == sizeof(double) ? ((__DOUBLE_BITS(x)+(1ULL<<52)) & -1ULL>>1) >= 1ULL<<53 : \
+	__fpclassifyl(x) == FP_NORMAL)
+
+#define isfinite(x) ( \
+	sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) < 0x7f800000 : \
+	sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) < 0x7ffULL<<52 : \
+	__fpclassifyl(x) > FP_INFINITE)
+
+int __signbit(double);
+int __signbitf(float);
+int __signbitl(long double);
+
+#define signbit(x) ( \
+	sizeof(x) == sizeof(float) ? (int)(__FLOAT_BITS(x)>>31) : \
+	sizeof(x) == sizeof(double) ? (int)(__DOUBLE_BITS(x)>>63) : \
+	__signbitl(x) )
+
+#define isunordered(x,y) (isnan((x)) ? ((void)(y),1) : isnan((y)))
+
+#define __ISREL_DEF(rel, op, type) \
+static __inline int __is##rel(type __x, type __y) \
+{ return !isunordered(__x,__y) && __x op __y; }
+
+__ISREL_DEF(lessf, <, float_t)
+__ISREL_DEF(less, <, double_t)
+__ISREL_DEF(lessl, <, long double)
+__ISREL_DEF(lessequalf, <=, float_t)
+__ISREL_DEF(lessequal, <=, double_t)
+__ISREL_DEF(lessequall, <=, long double)
+__ISREL_DEF(lessgreaterf, !=, float_t)
+__ISREL_DEF(lessgreater, !=, double_t)
+__ISREL_DEF(lessgreaterl, !=, long double)
+__ISREL_DEF(greaterf, >, float_t)
+__ISREL_DEF(greater, >, double_t)
+__ISREL_DEF(greaterl, >, long double)
+__ISREL_DEF(greaterequalf, >=, float_t)
+__ISREL_DEF(greaterequal, >=, double_t)
+__ISREL_DEF(greaterequall, >=, long double)
+
+#define __tg_pred_2(x, y, p) ( \
+	sizeof((x)+(y)) == sizeof(float) ? p##f(x, y) : \
+	sizeof((x)+(y)) == sizeof(double) ? p(x, y) : \
+	p##l(x, y) )
+
+#define isless(x, y)            __tg_pred_2(x, y, __isless)
+#define islessequal(x, y)       __tg_pred_2(x, y, __islessequal)
+#define islessgreater(x, y)     __tg_pred_2(x, y, __islessgreater)
+#define isgreater(x, y)         __tg_pred_2(x, y, __isgreater)
+#define isgreaterequal(x, y)    __tg_pred_2(x, y, __isgreaterequal)
+
+double      acos(double);
+float       acosf(float);
+long double acosl(long double);
+
+double      acosh(double);
+float       acoshf(float);
+long double acoshl(long double);
+
+double      asin(double);
+float       asinf(float);
+long double asinl(long double);
+
+double      asinh(double);
+float       asinhf(float);
+long double asinhl(long double);
+
+double      atan(double);
+float       atanf(float);
+long double atanl(long double);
+
+double      atan2(double, double);
+float       atan2f(float, float);
+long double atan2l(long double, long double);
+
+double      atanh(double);
+float       atanhf(float);
+long double atanhl(long double);
+
+double      cbrt(double);
+float       cbrtf(float);
+long double cbrtl(long double);
+
+double      ceil(double);
+float       ceilf(float);
+long double ceill(long double);
+
+double      copysign(double, double);
+float       copysignf(float, float);
+long double copysignl(long double, long double);
+
+double      cos(double);
+float       cosf(float);
+long double cosl(long double);
+
+double      cosh(double);
+float       coshf(float);
+long double coshl(long double);
+
+double      erf(double);
+float       erff(float);
+long double erfl(long double);
+
+double      erfc(double);
+float       erfcf(float);
+long double erfcl(long double);
+
+double      exp(double);
+float       expf(float);
+long double expl(long double);
+
+double      exp2(double);
+float       exp2f(float);
+long double exp2l(long double);
+
+double      expm1(double);
+float       expm1f(float);
+long double expm1l(long double);
+
+double      fabs(double);
+float       fabsf(float);
+long double fabsl(long double);
+
+double      fdim(double, double);
+float       fdimf(float, float);
+long double fdiml(long double, long double);
+
+double      floor(double);
+float       floorf(float);
+long double floorl(long double);
+
+double      fma(double, double, double);
+float       fmaf(float, float, float);
+long double fmal(long double, long double, long double);
+
+double      fmax(double, double);
+float       fmaxf(float, float);
+long double fmaxl(long double, long double);
+
+double      fmin(double, double);
+float       fminf(float, float);
+long double fminl(long double, long double);
+
+double      fmod(double, double);
+float       fmodf(float, float);
+long double fmodl(long double, long double);
+
+double      frexp(double, int *);
+float       frexpf(float, int *);
+long double frexpl(long double, int *);
+
+double      hypot(double, double);
+float       hypotf(float, float);
+long double hypotl(long double, long double);
+
+int         ilogb(double);
+int         ilogbf(float);
+int         ilogbl(long double);
+
+double      ldexp(double, int);
+float       ldexpf(float, int);
+long double ldexpl(long double, int);
+
+double      lgamma(double);
+float       lgammaf(float);
+long double lgammal(long double);
+
+long long   llrint(double);
+long long   llrintf(float);
+long long   llrintl(long double);
+
+long long   llround(double);
+long long   llroundf(float);
+long long   llroundl(long double);
+
+double      log(double);
+float       logf(float);
+long double logl(long double);
+
+double      log10(double);
+float       log10f(float);
+long double log10l(long double);
+
+double      log1p(double);
+float       log1pf(float);
+long double log1pl(long double);
+
+double      log2(double);
+float       log2f(float);
+long double log2l(long double);
+
+double      logb(double);
+float       logbf(float);
+long double logbl(long double);
+
+long        lrint(double);
+long        lrintf(float);
+long        lrintl(long double);
+
+long        lround(double);
+long        lroundf(float);
+long        lroundl(long double);
+
+double      modf(double, double *);
+float       modff(float, float *);
+long double modfl(long double, long double *);
+
+double      nan(const char *);
+float       nanf(const char *);
+long double nanl(const char *);
+
+double      nearbyint(double);
+float       nearbyintf(float);
+long double nearbyintl(long double);
+
+double      nextafter(double, double);
+float       nextafterf(float, float);
+long double nextafterl(long double, long double);
+
+double      nexttoward(double, long double);
+float       nexttowardf(float, long double);
+long double nexttowardl(long double, long double);
+
+double      pow(double, double);
+float       powf(float, float);
+long double powl(long double, long double);
+
+double      remainder(double, double);
+float       remainderf(float, float);
+long double remainderl(long double, long double);
+
+double      remquo(double, double, int *);
+float       remquof(float, float, int *);
+long double remquol(long double, long double, int *);
+
+double      rint(double);
+float       rintf(float);
+long double rintl(long double);
+
+double      round(double);
+float       roundf(float);
+long double roundl(long double);
+
+double      scalbln(double, long);
+float       scalblnf(float, long);
+long double scalblnl(long double, long);
+
+double      scalbn(double, int);
+float       scalbnf(float, int);
+long double scalbnl(long double, int);
+
+double      sin(double);
+float       sinf(float);
+long double sinl(long double);
+
+double      sinh(double);
+float       sinhf(float);
+long double sinhl(long double);
+
+double      sqrt(double);
+float       sqrtf(float);
+long double sqrtl(long double);
+
+double      tan(double);
+float       tanf(float);
+long double tanl(long double);
+
+double      tanh(double);
+float       tanhf(float);
+long double tanhl(long double);
+
+double      tgamma(double);
+float       tgammaf(float);
+long double tgammal(long double);
+
+double      trunc(double);
+float       truncf(float);
+long double truncl(long double);
+
+
+#if defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE)
+#undef  MAXFLOAT
+#define MAXFLOAT        3.40282346638528859812e+38F
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define M_E             2.7182818284590452354   /* e */
+#define M_LOG2E         1.4426950408889634074   /* log_2 e */
+#define M_LOG10E        0.43429448190325182765  /* log_10 e */
+#define M_LN2           0.69314718055994530942  /* log_e 2 */
+#define M_LN10          2.30258509299404568402  /* log_e 10 */
+#define M_PI            3.14159265358979323846  /* pi */
+#define M_PI_2          1.57079632679489661923  /* pi/2 */
+#define M_PI_4          0.78539816339744830962  /* pi/4 */
+#define M_1_PI          0.31830988618379067154  /* 1/pi */
+#define M_2_PI          0.63661977236758134308  /* 2/pi */
+#define M_2_SQRTPI      1.12837916709551257390  /* 2/sqrt(pi) */
+#define M_SQRT2         1.41421356237309504880  /* sqrt(2) */
+#define M_SQRT1_2       0.70710678118654752440  /* 1/sqrt(2) */
+
+extern int signgam;
+
+double      j0(double);
+double      j1(double);
+double      jn(int, double);
+
+double      y0(double);
+double      y1(double);
+double      yn(int, double);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define HUGE            3.40282346638528859812e+38F
+
+double      drem(double, double);
+float       dremf(float, float);
+
+int         finite(double);
+int         finitef(float);
+
+double      scalb(double, double);
+float       scalbf(float, float);
+
+double      significand(double);
+float       significandf(float);
+
+double      lgamma_r(double, int*);
+float       lgammaf_r(float, int*);
+
+float       j0f(float);
+float       j1f(float);
+float       jnf(int, float);
+
+float       y0f(float);
+float       y1f(float);
+float       ynf(int, float);
+#endif
+
+#ifdef _GNU_SOURCE
+long double lgammal_r(long double, int*);
+
+void        sincos(double, double*, double*);
+void        sincosf(float, float*, float*);
+void        sincosl(long double, long double*, long double*);
+
+double      exp10(double);
+float       exp10f(float);
+long double exp10l(long double);
+
+double      pow10(double);
+float       pow10f(float);
+long double pow10l(long double);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/memory.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/memory.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/memory.h	(revision 331)
@@ -0,0 +1,1 @@
+#include <string.h>
Index: EcnlProtoTool/trunk/musl-1.1.18/include/mntent.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/mntent.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/mntent.h	(revision 331)
@@ -0,0 +1,43 @@
+#ifndef _MNTENT_H
+#define _MNTENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_FILE
+#include <bits/alltypes.h>
+
+#define MOUNTED "/etc/mtab"
+
+#define MNTTYPE_IGNORE	"ignore"
+#define MNTTYPE_NFS	"nfs"
+#define MNTTYPE_SWAP	"swap"
+#define MNTOPT_DEFAULTS	"defaults"
+#define MNTOPT_RO	"ro"
+#define MNTOPT_RW	"rw"
+#define MNTOPT_SUID	"suid"
+#define MNTOPT_NOSUID	"nosuid"
+#define MNTOPT_NOAUTO	"noauto"
+
+struct mntent {
+	char *mnt_fsname;
+	char *mnt_dir;
+	char *mnt_type;
+	char *mnt_opts;
+	int mnt_freq;
+	int mnt_passno;
+};
+
+FILE *setmntent(const char *, const char *);
+int endmntent(FILE *);
+struct mntent *getmntent(FILE *);
+struct mntent *getmntent_r(FILE *, struct mntent *, char *, int);
+int addmntent(FILE *, const struct mntent *);
+char *hasmntopt(const struct mntent *, const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/monetary.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/monetary.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/monetary.h	(revision 331)
@@ -0,0 +1,23 @@
+#ifndef _MONETARY_H
+#define _MONETARY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_ssize_t
+#define __NEED_size_t
+#define __NEED_locale_t
+
+#include <bits/alltypes.h>
+
+ssize_t strfmon(char *__restrict, size_t, const char *__restrict, ...);
+ssize_t strfmon_l(char *__restrict, size_t, locale_t, const char *__restrict, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/mqueue.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/mqueue.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/mqueue.h	(revision 331)
@@ -0,0 +1,36 @@
+#ifndef _MQUEUE_H
+#define _MQUEUE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_pthread_attr_t
+#define __NEED_time_t
+#define __NEED_struct_timespec
+#include <bits/alltypes.h>
+
+typedef int mqd_t;
+struct mq_attr {
+	long mq_flags, mq_maxmsg, mq_msgsize, mq_curmsgs, __unused[4];
+};
+struct sigevent;
+
+int mq_close(mqd_t);
+int mq_getattr(mqd_t, struct mq_attr *);
+int mq_notify(mqd_t, const struct sigevent *);
+mqd_t mq_open(const char *, int, ...);
+ssize_t mq_receive(mqd_t, char *, size_t, unsigned *);
+int mq_send(mqd_t, const char *, size_t, unsigned);
+int mq_setattr(mqd_t, const struct mq_attr *__restrict, struct mq_attr *__restrict);
+ssize_t mq_timedreceive(mqd_t, char *__restrict, size_t, unsigned *__restrict, const struct timespec *__restrict);
+int mq_timedsend(mqd_t, const char *, size_t, unsigned, const struct timespec *);
+int mq_unlink(const char *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/net/ethernet.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/net/ethernet.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/net/ethernet.h	(revision 331)
@@ -0,0 +1,55 @@
+#ifndef _NET_ETHERNET_H
+#define _NET_ETHERNET_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <netinet/if_ether.h>
+
+struct ether_addr {
+	uint8_t ether_addr_octet[ETH_ALEN];
+};
+
+struct ether_header {
+	uint8_t  ether_dhost[ETH_ALEN];
+	uint8_t  ether_shost[ETH_ALEN];
+	uint16_t ether_type;
+};
+
+#define	ETHERTYPE_PUP		0x0200
+#define ETHERTYPE_SPRITE	0x0500
+#define	ETHERTYPE_IP		0x0800
+#define	ETHERTYPE_ARP		0x0806
+#define	ETHERTYPE_REVARP	0x8035
+#define ETHERTYPE_AT		0x809B
+#define ETHERTYPE_AARP		0x80F3
+#define	ETHERTYPE_VLAN		0x8100
+#define ETHERTYPE_IPX		0x8137
+#define	ETHERTYPE_IPV6		0x86dd
+#define ETHERTYPE_LOOPBACK	0x9000
+
+
+#define	ETHER_ADDR_LEN	ETH_ALEN
+#define	ETHER_TYPE_LEN	2
+#define	ETHER_CRC_LEN	4
+#define	ETHER_HDR_LEN	ETH_HLEN
+#define	ETHER_MIN_LEN	(ETH_ZLEN + ETHER_CRC_LEN)
+#define	ETHER_MAX_LEN	(ETH_FRAME_LEN + ETHER_CRC_LEN)
+
+#define	ETHER_IS_VALID_LEN(foo)	\
+	((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN)
+
+#define	ETHERTYPE_TRAIL		0x1000
+#define	ETHERTYPE_NTRAILER	16
+
+#define	ETHERMTU	ETH_DATA_LEN
+#define	ETHERMIN	(ETHER_MIN_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/net/if.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/net/if.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/net/if.h	(revision 331)
@@ -0,0 +1,134 @@
+#ifndef _NET_IF_H
+#define _NET_IF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define IF_NAMESIZE 16
+
+struct if_nameindex {
+	unsigned int if_index;
+	char *if_name;
+};
+
+unsigned int if_nametoindex (const char *);
+char *if_indextoname (unsigned int, char *);
+struct if_nameindex *if_nameindex (void);
+void if_freenameindex (struct if_nameindex *);
+
+
+
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#include <sys/socket.h>
+
+#define IFF_UP	0x1
+#define IFF_BROADCAST 0x2
+#define IFF_DEBUG 0x4
+#define IFF_LOOPBACK 0x8
+#define IFF_POINTOPOINT 0x10
+#define IFF_NOTRAILERS 0x20
+#define IFF_RUNNING 0x40
+#define IFF_NOARP 0x80
+#define IFF_PROMISC 0x100
+#define IFF_ALLMULTI 0x200
+#define IFF_MASTER 0x400
+#define IFF_SLAVE 0x800
+#define IFF_MULTICAST 0x1000
+#define IFF_PORTSEL 0x2000
+#define IFF_AUTOMEDIA 0x4000
+#define IFF_DYNAMIC 0x8000
+#define IFF_LOWER_UP 0x10000
+#define IFF_DORMANT 0x20000
+#define IFF_ECHO 0x40000
+#define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST| \
+        IFF_ECHO|IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT)
+
+struct ifaddr {
+	struct sockaddr ifa_addr;
+	union {
+		struct sockaddr	ifu_broadaddr;
+		struct sockaddr	ifu_dstaddr;
+	} ifa_ifu;
+	struct iface *ifa_ifp;
+	struct ifaddr *ifa_next;
+};
+
+#define ifa_broadaddr	ifa_ifu.ifu_broadaddr
+#define ifa_dstaddr	ifa_ifu.ifu_dstaddr
+
+struct ifmap {
+	unsigned long int mem_start;
+	unsigned long int mem_end;
+	unsigned short int base_addr;
+	unsigned char irq;
+	unsigned char dma;
+	unsigned char port;
+};
+
+#define IFHWADDRLEN	6
+#define IFNAMSIZ	IF_NAMESIZE
+
+struct ifreq {
+	union {
+		char ifrn_name[IFNAMSIZ];
+	} ifr_ifrn;
+	union {
+		struct sockaddr ifru_addr;
+		struct sockaddr ifru_dstaddr;
+		struct sockaddr ifru_broadaddr;
+		struct sockaddr ifru_netmask;
+		struct sockaddr ifru_hwaddr;
+		short int ifru_flags;
+		int ifru_ivalue;
+		int ifru_mtu;
+		struct ifmap ifru_map;
+		char ifru_slave[IFNAMSIZ];
+		char ifru_newname[IFNAMSIZ];
+		char *ifru_data;
+	} ifr_ifru;
+};
+
+#define ifr_name	ifr_ifrn.ifrn_name
+#define ifr_hwaddr	ifr_ifru.ifru_hwaddr
+#define ifr_addr	ifr_ifru.ifru_addr
+#define ifr_dstaddr	ifr_ifru.ifru_dstaddr
+#define ifr_broadaddr	ifr_ifru.ifru_broadaddr
+#define ifr_netmask	ifr_ifru.ifru_netmask
+#define ifr_flags	ifr_ifru.ifru_flags
+#define ifr_metric	ifr_ifru.ifru_ivalue
+#define ifr_mtu		ifr_ifru.ifru_mtu
+#define ifr_map		ifr_ifru.ifru_map
+#define ifr_slave	ifr_ifru.ifru_slave
+#define ifr_data	ifr_ifru.ifru_data
+#define ifr_ifindex	ifr_ifru.ifru_ivalue
+#define ifr_bandwidth	ifr_ifru.ifru_ivalue
+#define ifr_qlen	ifr_ifru.ifru_ivalue
+#define ifr_newname	ifr_ifru.ifru_newname
+#define _IOT_ifreq	_IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0)
+#define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0)
+#define _IOT_ifreq_int	_IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)
+
+struct ifconf {
+	int ifc_len;		
+	union {
+		char *ifcu_buf;
+		struct ifreq *ifcu_req;
+	} ifc_ifcu;
+};
+
+#define ifc_buf		ifc_ifcu.ifcu_buf
+#define ifc_req		ifc_ifcu.ifcu_req
+#define _IOT_ifconf _IOT(_IOTS(struct ifconf),1,0,0,0,0)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/net/if_arp.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/net/if_arp.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/net/if_arp.h	(revision 331)
@@ -0,0 +1,140 @@
+/* Nonstandard header */
+#ifndef _NET_IF_ARP_H
+#define _NET_IF_ARP_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#define MAX_ADDR_LEN	7
+
+#define	ARPOP_REQUEST	1
+#define	ARPOP_REPLY	2
+#define	ARPOP_RREQUEST	3
+#define	ARPOP_RREPLY	4
+#define	ARPOP_InREQUEST	8
+#define	ARPOP_InREPLY	9
+#define	ARPOP_NAK	10
+
+struct arphdr {
+	uint16_t ar_hrd;
+	uint16_t ar_pro;
+	uint8_t ar_hln;
+	uint8_t ar_pln;
+	uint16_t ar_op;
+};
+
+
+#define ARPHRD_NETROM	0
+#define ARPHRD_ETHER 	1
+#define	ARPHRD_EETHER	2
+#define	ARPHRD_AX25	3
+#define	ARPHRD_PRONET	4
+#define	ARPHRD_CHAOS	5
+#define	ARPHRD_IEEE802	6
+#define	ARPHRD_ARCNET	7
+#define	ARPHRD_APPLETLK	8
+#define	ARPHRD_DLCI	15
+#define	ARPHRD_ATM	19
+#define	ARPHRD_METRICOM	23
+#define ARPHRD_IEEE1394	24
+#define ARPHRD_EUI64		27
+#define ARPHRD_INFINIBAND	32
+#define ARPHRD_SLIP	256
+#define ARPHRD_CSLIP	257
+#define ARPHRD_SLIP6	258
+#define ARPHRD_CSLIP6	259
+#define ARPHRD_RSRVD	260
+#define ARPHRD_ADAPT	264
+#define ARPHRD_ROSE	270
+#define ARPHRD_X25	271
+#define ARPHRD_HWX25	272
+#define ARPHRD_CAN	280
+#define ARPHRD_PPP	512
+#define ARPHRD_CISCO	513
+#define ARPHRD_HDLC	ARPHRD_CISCO
+#define ARPHRD_LAPB	516
+#define ARPHRD_DDCMP	517
+#define	ARPHRD_RAWHDLC	518
+
+#define ARPHRD_TUNNEL	768
+#define ARPHRD_TUNNEL6	769
+#define ARPHRD_FRAD	770
+#define ARPHRD_SKIP	771
+#define ARPHRD_LOOPBACK	772
+#define ARPHRD_LOCALTLK 773
+#define ARPHRD_FDDI	774
+#define ARPHRD_BIF	775
+#define ARPHRD_SIT	776
+#define ARPHRD_IPDDP	777
+#define ARPHRD_IPGRE	778
+#define ARPHRD_PIMREG	779
+#define ARPHRD_HIPPI	780
+#define ARPHRD_ASH	781
+#define ARPHRD_ECONET	782
+#define ARPHRD_IRDA	783
+#define ARPHRD_FCPP	784
+#define ARPHRD_FCAL	785
+#define ARPHRD_FCPL	786
+#define ARPHRD_FCFABRIC 787
+#define ARPHRD_IEEE802_TR 800
+#define ARPHRD_IEEE80211 801
+#define ARPHRD_IEEE80211_PRISM 802
+#define ARPHRD_IEEE80211_RADIOTAP 803
+#define ARPHRD_IEEE802154 804
+#define ARPHRD_IEEE802154_MONITOR 805
+#define ARPHRD_PHONET 820
+#define ARPHRD_PHONET_PIPE 821
+#define ARPHRD_CAIF 822
+#define ARPHRD_IP6GRE 823
+#define ARPHRD_NETLINK 824
+#define ARPHRD_6LOWPAN 825
+
+#define ARPHRD_VOID	  0xFFFF
+#define ARPHRD_NONE	  0xFFFE
+
+struct arpreq {
+	struct sockaddr arp_pa;
+	struct sockaddr arp_ha;
+	int arp_flags;
+	struct sockaddr arp_netmask;
+	char arp_dev[16];
+};
+
+struct arpreq_old {
+	struct sockaddr arp_pa;
+	struct sockaddr arp_ha;
+	int arp_flags;
+	struct sockaddr arp_netmask;
+};
+
+#define ATF_COM		0x02
+#define	ATF_PERM	0x04
+#define	ATF_PUBL	0x08
+#define	ATF_USETRAILERS	0x10
+#define ATF_NETMASK     0x20
+#define ATF_DONTPUB	0x40
+#define ATF_MAGIC	0x80
+
+#define ARPD_UPDATE	0x01
+#define ARPD_LOOKUP	0x02
+#define ARPD_FLUSH	0x03
+
+struct arpd_request {
+	unsigned short req;
+	uint32_t ip;
+	unsigned long dev;
+	unsigned long stamp;
+	unsigned long updated;
+	unsigned char ha[MAX_ADDR_LEN];
+};
+
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/net/route.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/net/route.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/net/route.h	(revision 331)
@@ -0,0 +1,124 @@
+#ifndef _NET_ROUTE_H
+#define _NET_ROUTE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
+
+struct rtentry {
+	unsigned long int rt_pad1;
+	struct sockaddr rt_dst;
+	struct sockaddr rt_gateway;
+	struct sockaddr rt_genmask;
+	unsigned short int rt_flags;
+	short int rt_pad2;
+	unsigned long int rt_pad3;
+	unsigned char rt_tos;
+	unsigned char rt_class;
+	short int rt_pad4[sizeof(long)/2-1];
+	short int rt_metric;
+	char *rt_dev;
+	unsigned long int rt_mtu;
+	unsigned long int rt_window;
+	unsigned short int rt_irtt;
+};
+
+#define rt_mss	rt_mtu
+
+
+struct in6_rtmsg {
+	struct in6_addr rtmsg_dst;
+	struct in6_addr rtmsg_src;
+	struct in6_addr rtmsg_gateway;
+	uint32_t rtmsg_type;
+	uint16_t rtmsg_dst_len;
+	uint16_t rtmsg_src_len;
+	uint32_t rtmsg_metric;
+	unsigned long int rtmsg_info;
+	uint32_t rtmsg_flags;
+	int rtmsg_ifindex;
+};
+
+
+#define	RTF_UP		0x0001
+#define	RTF_GATEWAY	0x0002
+
+#define	RTF_HOST	0x0004
+#define RTF_REINSTATE	0x0008
+#define	RTF_DYNAMIC	0x0010
+#define	RTF_MODIFIED	0x0020
+#define RTF_MTU		0x0040
+#define RTF_MSS		RTF_MTU
+#define RTF_WINDOW	0x0080
+#define RTF_IRTT	0x0100
+#define RTF_REJECT	0x0200
+#define	RTF_STATIC	0x0400
+#define	RTF_XRESOLVE	0x0800
+#define RTF_NOFORWARD   0x1000
+#define RTF_THROW	0x2000
+#define RTF_NOPMTUDISC  0x4000
+
+#define RTF_DEFAULT	0x00010000
+#define RTF_ALLONLINK	0x00020000
+#define RTF_ADDRCONF	0x00040000
+
+#define RTF_LINKRT	0x00100000
+#define RTF_NONEXTHOP	0x00200000
+
+#define RTF_CACHE	0x01000000
+#define RTF_FLOW	0x02000000
+#define RTF_POLICY	0x04000000
+
+#define RTCF_VALVE	0x00200000
+#define RTCF_MASQ	0x00400000
+#define RTCF_NAT	0x00800000
+#define RTCF_DOREDIRECT 0x01000000
+#define RTCF_LOG	0x02000000
+#define RTCF_DIRECTSRC	0x04000000
+
+#define RTF_LOCAL	0x80000000
+#define RTF_INTERFACE	0x40000000
+#define RTF_MULTICAST	0x20000000
+#define RTF_BROADCAST	0x10000000
+#define RTF_NAT		0x08000000
+
+#define RTF_ADDRCLASSMASK	0xF8000000
+#define RT_ADDRCLASS(flags)	((uint32_t) flags >> 23)
+
+#define RT_TOS(tos)		((tos) & IPTOS_TOS_MASK)
+
+#define RT_LOCALADDR(flags)	((flags & RTF_ADDRCLASSMASK) \
+				 == (RTF_LOCAL|RTF_INTERFACE))
+
+#define RT_CLASS_UNSPEC		0
+#define RT_CLASS_DEFAULT	253
+
+#define RT_CLASS_MAIN		254
+#define RT_CLASS_LOCAL		255
+#define RT_CLASS_MAX		255
+
+
+#define RTMSG_ACK		NLMSG_ACK
+#define RTMSG_OVERRUN		NLMSG_OVERRUN
+
+#define RTMSG_NEWDEVICE		0x11
+#define RTMSG_DELDEVICE		0x12
+#define RTMSG_NEWROUTE		0x21
+#define RTMSG_DELROUTE		0x22
+#define RTMSG_NEWRULE		0x31
+#define RTMSG_DELRULE		0x32
+#define RTMSG_CONTROL		0x40
+
+#define RTMSG_AR_FAILED		0x51
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/netdb.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/netdb.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/netdb.h	(revision 331)
@@ -0,0 +1,153 @@
+#ifndef	_NETDB_H
+#define	_NETDB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <netinet/in.h>
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_size_t
+#include <bits/alltypes.h>
+#endif
+
+struct addrinfo {
+	int ai_flags;
+	int ai_family;
+	int ai_socktype;
+	int ai_protocol;
+	socklen_t ai_addrlen;
+	struct sockaddr *ai_addr;
+	char *ai_canonname;
+	struct addrinfo *ai_next;
+};
+
+#define AI_PASSIVE      0x01
+#define AI_CANONNAME    0x02
+#define AI_NUMERICHOST  0x04
+#define AI_V4MAPPED     0x08
+#define AI_ALL          0x10
+#define AI_ADDRCONFIG   0x20
+#define AI_NUMERICSERV  0x400
+
+
+#define NI_NUMERICHOST  0x01
+#define NI_NUMERICSERV  0x02
+#define NI_NOFQDN       0x04
+#define NI_NAMEREQD     0x08
+#define NI_DGRAM        0x10
+#define NI_NUMERICSCOPE 0x100
+
+#define EAI_BADFLAGS   -1
+#define EAI_NONAME     -2
+#define EAI_AGAIN      -3
+#define EAI_FAIL       -4
+#define EAI_FAMILY     -6
+#define EAI_SOCKTYPE   -7
+#define EAI_SERVICE    -8
+#define EAI_MEMORY     -10
+#define EAI_SYSTEM     -11
+#define EAI_OVERFLOW   -12
+
+int getaddrinfo (const char *__restrict, const char *__restrict, const struct addrinfo *__restrict, struct addrinfo **__restrict);
+void freeaddrinfo (struct addrinfo *);
+int getnameinfo (const struct sockaddr *__restrict, socklen_t, char *__restrict, socklen_t, char *__restrict, socklen_t, int);
+const char *gai_strerror(int);
+
+
+/* Legacy functions follow (marked OBsolete in SUS) */
+
+struct netent {
+	char *n_name;
+	char **n_aliases;
+	int n_addrtype;
+	uint32_t n_net;
+};
+
+struct hostent {
+	char *h_name;
+	char **h_aliases;
+	int h_addrtype;
+	int h_length;
+	char **h_addr_list;
+};
+#define h_addr h_addr_list[0]
+
+struct servent {
+	char *s_name;
+	char **s_aliases;
+	int s_port;
+	char *s_proto;
+};
+
+struct protoent {
+	char *p_name;
+	char **p_aliases;
+	int p_proto;
+};
+
+void sethostent (int);
+void endhostent (void);
+struct hostent *gethostent (void);
+
+void setnetent (int);
+void endnetent (void);
+struct netent *getnetent (void);
+struct netent *getnetbyaddr (uint32_t, int);
+struct netent *getnetbyname (const char *);
+
+void setservent (int);
+void endservent (void);
+struct servent *getservent (void);
+struct servent *getservbyname (const char *, const char *);
+struct servent *getservbyport (int, const char *);
+
+void setprotoent (int);
+void endprotoent (void);
+struct protoent *getprotoent (void);
+struct protoent *getprotobyname (const char *);
+struct protoent *getprotobynumber (int);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_POSIX_SOURCE) \
+ || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE+0 < 200809L) \
+ || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700)
+struct hostent *gethostbyname (const char *);
+struct hostent *gethostbyaddr (const void *, socklen_t, int);
+int *__h_errno_location(void);
+#define h_errno (*__h_errno_location())
+#define HOST_NOT_FOUND 1
+#define TRY_AGAIN      2
+#define NO_RECOVERY    3
+#define NO_DATA        4
+#define NO_ADDRESS     NO_DATA
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+void herror(const char *);
+const char *hstrerror(int);
+int gethostbyname_r(const char *, struct hostent *, char *, size_t, struct hostent **, int *);
+int gethostbyname2_r(const char *, int, struct hostent *, char *, size_t, struct hostent **, int *);
+struct hostent *gethostbyname2(const char *, int);
+int gethostbyaddr_r(const void *, socklen_t, int, struct hostent *, char *, size_t, struct hostent **, int *);
+int getservbyport_r(int, const char *, struct servent *, char *, size_t, struct servent **);
+int getservbyname_r(const char *, const char *, struct servent *, char *, size_t, struct servent **);
+#define EAI_NODATA     -5
+#define EAI_ADDRFAMILY -9
+#define EAI_INPROGRESS -100
+#define EAI_CANCELED   -101
+#define EAI_NOTCANCELED -102
+#define EAI_ALLDONE    -103
+#define EAI_INTR       -104
+#define EAI_IDN_ENCODE -105
+#define NI_MAXHOST 255
+#define NI_MAXSERV 32
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/netinet/ether.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/netinet/ether.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/netinet/ether.h	(revision 331)
@@ -0,0 +1,22 @@
+#ifndef _NETINET_ETHER_H
+#define _NETINET_ETHER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <netinet/if_ether.h>
+
+char *ether_ntoa (const struct ether_addr *);
+struct ether_addr *ether_aton (const char *);
+char *ether_ntoa_r (const struct ether_addr *, char *);
+struct ether_addr *ether_aton_r (const char *, struct ether_addr *);
+int ether_line(const char *, struct ether_addr *, char *);
+int ether_ntohost(char *, const struct ether_addr *);
+int ether_hostton(const char *, struct ether_addr *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/netinet/icmp6.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/netinet/icmp6.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/netinet/icmp6.h	(revision 331)
@@ -0,0 +1,305 @@
+#ifndef _NETINET_ICMP6_H
+#define _NETINET_ICMP6_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
+#define ICMP6_FILTER 1
+
+#define ICMP6_FILTER_BLOCK		1
+#define ICMP6_FILTER_PASS		2
+#define ICMP6_FILTER_BLOCKOTHERS	3
+#define ICMP6_FILTER_PASSONLY		4
+
+struct icmp6_filter {
+	uint32_t icmp6_filt[8];
+};
+
+struct icmp6_hdr {
+	uint8_t     icmp6_type;
+	uint8_t     icmp6_code;
+	uint16_t    icmp6_cksum;
+	union {
+		uint32_t  icmp6_un_data32[1];
+		uint16_t  icmp6_un_data16[2];
+		uint8_t   icmp6_un_data8[4];
+	} icmp6_dataun;
+};
+
+#define icmp6_data32    icmp6_dataun.icmp6_un_data32
+#define icmp6_data16    icmp6_dataun.icmp6_un_data16
+#define icmp6_data8     icmp6_dataun.icmp6_un_data8
+#define icmp6_pptr      icmp6_data32[0]
+#define icmp6_mtu       icmp6_data32[0]
+#define icmp6_id        icmp6_data16[0]
+#define icmp6_seq       icmp6_data16[1]
+#define icmp6_maxdelay  icmp6_data16[0]
+
+#define ICMP6_DST_UNREACH             1
+#define ICMP6_PACKET_TOO_BIG          2
+#define ICMP6_TIME_EXCEEDED           3
+#define ICMP6_PARAM_PROB              4
+
+#define ICMP6_INFOMSG_MASK  0x80
+
+#define ICMP6_ECHO_REQUEST          128
+#define ICMP6_ECHO_REPLY            129
+#define MLD_LISTENER_QUERY          130
+#define MLD_LISTENER_REPORT         131
+#define MLD_LISTENER_REDUCTION      132
+
+#define ICMP6_DST_UNREACH_NOROUTE     0
+#define ICMP6_DST_UNREACH_ADMIN       1
+#define ICMP6_DST_UNREACH_BEYONDSCOPE 2
+#define ICMP6_DST_UNREACH_ADDR        3
+#define ICMP6_DST_UNREACH_NOPORT      4
+
+#define ICMP6_TIME_EXCEED_TRANSIT     0
+#define ICMP6_TIME_EXCEED_REASSEMBLY  1
+
+#define ICMP6_PARAMPROB_HEADER        0
+#define ICMP6_PARAMPROB_NEXTHEADER    1
+#define ICMP6_PARAMPROB_OPTION        2
+
+#define ICMP6_FILTER_WILLPASS(type, filterp) \
+	((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0)
+
+#define ICMP6_FILTER_WILLBLOCK(type, filterp) \
+	((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0)
+
+#define ICMP6_FILTER_SETPASS(type, filterp) \
+	((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31))))
+
+#define ICMP6_FILTER_SETBLOCK(type, filterp) \
+	((((filterp)->icmp6_filt[(type) >> 5]) |=  (1 << ((type) & 31))))
+
+#define ICMP6_FILTER_SETPASSALL(filterp) \
+	memset (filterp, 0, sizeof (struct icmp6_filter));
+
+#define ICMP6_FILTER_SETBLOCKALL(filterp) \
+	memset (filterp, 0xFF, sizeof (struct icmp6_filter));
+
+#define ND_ROUTER_SOLICIT           133
+#define ND_ROUTER_ADVERT            134
+#define ND_NEIGHBOR_SOLICIT         135
+#define ND_NEIGHBOR_ADVERT          136
+#define ND_REDIRECT                 137
+
+struct nd_router_solicit {
+	struct icmp6_hdr  nd_rs_hdr;
+};
+
+#define nd_rs_type               nd_rs_hdr.icmp6_type
+#define nd_rs_code               nd_rs_hdr.icmp6_code
+#define nd_rs_cksum              nd_rs_hdr.icmp6_cksum
+#define nd_rs_reserved           nd_rs_hdr.icmp6_data32[0]
+
+struct nd_router_advert {
+	struct icmp6_hdr  nd_ra_hdr;
+	uint32_t   nd_ra_reachable;
+	uint32_t   nd_ra_retransmit;
+};
+
+#define nd_ra_type               nd_ra_hdr.icmp6_type
+#define nd_ra_code               nd_ra_hdr.icmp6_code
+#define nd_ra_cksum              nd_ra_hdr.icmp6_cksum
+#define nd_ra_curhoplimit        nd_ra_hdr.icmp6_data8[0]
+#define nd_ra_flags_reserved     nd_ra_hdr.icmp6_data8[1]
+#define ND_RA_FLAG_MANAGED       0x80
+#define ND_RA_FLAG_OTHER         0x40
+#define ND_RA_FLAG_HOME_AGENT    0x20
+#define nd_ra_router_lifetime    nd_ra_hdr.icmp6_data16[1]
+
+struct nd_neighbor_solicit {
+	struct icmp6_hdr  nd_ns_hdr;
+	struct in6_addr   nd_ns_target;
+};
+
+#define nd_ns_type               nd_ns_hdr.icmp6_type
+#define nd_ns_code               nd_ns_hdr.icmp6_code
+#define nd_ns_cksum              nd_ns_hdr.icmp6_cksum
+#define nd_ns_reserved           nd_ns_hdr.icmp6_data32[0]
+
+struct nd_neighbor_advert {
+	struct icmp6_hdr  nd_na_hdr;
+	struct in6_addr   nd_na_target;
+};
+
+#define nd_na_type               nd_na_hdr.icmp6_type
+#define nd_na_code               nd_na_hdr.icmp6_code
+#define nd_na_cksum              nd_na_hdr.icmp6_cksum
+#define nd_na_flags_reserved     nd_na_hdr.icmp6_data32[0]
+#if     __BYTE_ORDER == __BIG_ENDIAN
+#define ND_NA_FLAG_ROUTER        0x80000000
+#define ND_NA_FLAG_SOLICITED     0x40000000
+#define ND_NA_FLAG_OVERRIDE      0x20000000
+#else
+#define ND_NA_FLAG_ROUTER        0x00000080
+#define ND_NA_FLAG_SOLICITED     0x00000040
+#define ND_NA_FLAG_OVERRIDE      0x00000020
+#endif
+
+struct nd_redirect {
+	struct icmp6_hdr  nd_rd_hdr;
+	struct in6_addr   nd_rd_target;
+	struct in6_addr   nd_rd_dst;
+};
+
+#define nd_rd_type               nd_rd_hdr.icmp6_type
+#define nd_rd_code               nd_rd_hdr.icmp6_code
+#define nd_rd_cksum              nd_rd_hdr.icmp6_cksum
+#define nd_rd_reserved           nd_rd_hdr.icmp6_data32[0]
+
+struct nd_opt_hdr {
+	uint8_t  nd_opt_type;
+	uint8_t  nd_opt_len;
+};
+
+#define ND_OPT_SOURCE_LINKADDR		1
+#define ND_OPT_TARGET_LINKADDR		2
+#define ND_OPT_PREFIX_INFORMATION	3
+#define ND_OPT_REDIRECTED_HEADER	4
+#define ND_OPT_MTU			5
+#define ND_OPT_RTR_ADV_INTERVAL		7
+#define ND_OPT_HOME_AGENT_INFO		8
+
+struct nd_opt_prefix_info {
+	uint8_t   nd_opt_pi_type;
+	uint8_t   nd_opt_pi_len;
+	uint8_t   nd_opt_pi_prefix_len;
+	uint8_t   nd_opt_pi_flags_reserved;
+	uint32_t  nd_opt_pi_valid_time;
+	uint32_t  nd_opt_pi_preferred_time;
+	uint32_t  nd_opt_pi_reserved2;
+	struct in6_addr  nd_opt_pi_prefix;
+};
+
+#define ND_OPT_PI_FLAG_ONLINK	0x80
+#define ND_OPT_PI_FLAG_AUTO	0x40
+#define ND_OPT_PI_FLAG_RADDR	0x20
+
+struct nd_opt_rd_hdr {
+	uint8_t   nd_opt_rh_type;
+	uint8_t   nd_opt_rh_len;
+	uint16_t  nd_opt_rh_reserved1;
+	uint32_t  nd_opt_rh_reserved2;
+};
+
+struct nd_opt_mtu {
+	uint8_t   nd_opt_mtu_type;
+	uint8_t   nd_opt_mtu_len;
+	uint16_t  nd_opt_mtu_reserved;
+	uint32_t  nd_opt_mtu_mtu;
+};
+
+struct mld_hdr {
+	struct icmp6_hdr    mld_icmp6_hdr;
+	struct in6_addr     mld_addr;
+};
+
+#define mld_type        mld_icmp6_hdr.icmp6_type
+#define mld_code        mld_icmp6_hdr.icmp6_code
+#define mld_cksum       mld_icmp6_hdr.icmp6_cksum
+#define mld_maxdelay    mld_icmp6_hdr.icmp6_data16[0]
+#define mld_reserved    mld_icmp6_hdr.icmp6_data16[1]
+
+#define ICMP6_ROUTER_RENUMBERING    138
+
+struct icmp6_router_renum {
+	struct icmp6_hdr    rr_hdr;
+	uint8_t             rr_segnum;
+	uint8_t             rr_flags;
+	uint16_t            rr_maxdelay;
+	uint32_t            rr_reserved;
+};
+
+#define rr_type		rr_hdr.icmp6_type
+#define rr_code         rr_hdr.icmp6_code
+#define rr_cksum        rr_hdr.icmp6_cksum
+#define rr_seqnum       rr_hdr.icmp6_data32[0]
+
+#define ICMP6_RR_FLAGS_TEST             0x80
+#define ICMP6_RR_FLAGS_REQRESULT        0x40
+#define ICMP6_RR_FLAGS_FORCEAPPLY       0x20
+#define ICMP6_RR_FLAGS_SPECSITE         0x10
+#define ICMP6_RR_FLAGS_PREVDONE         0x08
+
+struct rr_pco_match {
+	uint8_t             rpm_code;
+	uint8_t             rpm_len;
+	uint8_t             rpm_ordinal;
+	uint8_t             rpm_matchlen;
+	uint8_t             rpm_minlen;
+	uint8_t             rpm_maxlen;
+	uint16_t            rpm_reserved;
+	struct in6_addr     rpm_prefix;
+};
+
+#define RPM_PCO_ADD             1
+#define RPM_PCO_CHANGE          2
+#define RPM_PCO_SETGLOBAL       3
+
+struct rr_pco_use {
+	uint8_t             rpu_uselen;
+	uint8_t             rpu_keeplen;
+	uint8_t             rpu_ramask;
+	uint8_t             rpu_raflags;
+	uint32_t            rpu_vltime;
+	uint32_t            rpu_pltime;
+	uint32_t            rpu_flags;
+	struct in6_addr     rpu_prefix;
+};
+
+#define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK  0x20
+#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO    0x10
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80000000
+#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40000000
+#else
+#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80
+#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40
+#endif
+
+struct rr_result {
+	uint16_t            rrr_flags;
+	uint8_t             rrr_ordinal;
+	uint8_t             rrr_matchedlen;
+	uint32_t            rrr_ifid;
+	struct in6_addr     rrr_prefix;
+};
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define ICMP6_RR_RESULT_FLAGS_OOB       0x0002
+#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0001
+#else
+#define ICMP6_RR_RESULT_FLAGS_OOB       0x0200
+#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0100
+#endif
+
+struct nd_opt_adv_interval {
+	uint8_t   nd_opt_adv_interval_type;
+	uint8_t   nd_opt_adv_interval_len;
+	uint16_t  nd_opt_adv_interval_reserved;
+	uint32_t  nd_opt_adv_interval_ival;
+};
+
+struct nd_opt_home_agent_info {
+	uint8_t   nd_opt_home_agent_info_type;
+	uint8_t   nd_opt_home_agent_info_len;
+	uint16_t  nd_opt_home_agent_info_reserved;
+	uint16_t  nd_opt_home_agent_info_preference;
+	uint16_t  nd_opt_home_agent_info_lifetime;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/netinet/if_ether.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/netinet/if_ether.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/netinet/if_ether.h	(revision 331)
@@ -0,0 +1,134 @@
+#ifndef _NETINET_IF_ETHER_H
+#define _NETINET_IF_ETHER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#define ETH_ALEN	6
+#define ETH_HLEN	14
+#define ETH_ZLEN	60
+#define ETH_DATA_LEN	1500
+#define ETH_FRAME_LEN	1514
+#define ETH_FCS_LEN	4
+
+#define ETH_P_LOOP	0x0060
+#define ETH_P_PUP	0x0200
+#define ETH_P_PUPAT	0x0201
+#define ETH_P_TSN	0x22F0
+#define ETH_P_IP	0x0800
+#define ETH_P_X25	0x0805
+#define ETH_P_ARP	0x0806
+#define	ETH_P_BPQ	0x08FF
+#define ETH_P_IEEEPUP	0x0a00
+#define ETH_P_IEEEPUPAT	0x0a01
+#define ETH_P_BATMAN	0x4305
+#define ETH_P_DEC       0x6000
+#define ETH_P_DNA_DL    0x6001
+#define ETH_P_DNA_RC    0x6002
+#define ETH_P_DNA_RT    0x6003
+#define ETH_P_LAT       0x6004
+#define ETH_P_DIAG      0x6005
+#define ETH_P_CUST      0x6006
+#define ETH_P_SCA       0x6007
+#define ETH_P_TEB	0x6558
+#define ETH_P_RARP      0x8035
+#define ETH_P_ATALK	0x809B
+#define ETH_P_AARP	0x80F3
+#define ETH_P_8021Q	0x8100
+#define ETH_P_IPX	0x8137
+#define ETH_P_IPV6	0x86DD
+#define ETH_P_PAUSE	0x8808
+#define ETH_P_SLOW	0x8809
+#define ETH_P_WCCP	0x883E
+#define ETH_P_MPLS_UC	0x8847
+#define ETH_P_MPLS_MC	0x8848
+#define ETH_P_ATMMPOA	0x884c
+#define ETH_P_PPP_DISC	0x8863
+#define ETH_P_PPP_SES	0x8864
+#define ETH_P_LINK_CTL	0x886c
+#define ETH_P_ATMFATE	0x8884
+#define ETH_P_PAE	0x888E
+#define ETH_P_AOE	0x88A2
+#define ETH_P_8021AD	0x88A8
+#define ETH_P_802_EX1	0x88B5
+#define ETH_P_TIPC	0x88CA
+#define ETH_P_MACSEC	0x88E5
+#define ETH_P_8021AH	0x88E7
+#define ETH_P_MVRP	0x88F5
+#define ETH_P_1588	0x88F7
+#define ETH_P_NCSI	0x88F8
+#define ETH_P_PRP	0x88FB
+#define ETH_P_FCOE	0x8906
+#define ETH_P_TDLS	0x890D
+#define ETH_P_FIP	0x8914
+#define ETH_P_80221	0x8917
+#define ETH_P_HSR	0x892F
+#define ETH_P_LOOPBACK	0x9000
+#define ETH_P_QINQ1	0x9100
+#define ETH_P_QINQ2	0x9200
+#define ETH_P_QINQ3	0x9300
+#define ETH_P_EDSA	0xDADA
+#define ETH_P_AF_IUCV	0xFBFB
+
+#define ETH_P_802_3_MIN	0x0600
+
+#define ETH_P_802_3	0x0001
+#define ETH_P_AX25	0x0002
+#define ETH_P_ALL	0x0003
+#define ETH_P_802_2	0x0004
+#define ETH_P_SNAP	0x0005
+#define ETH_P_DDCMP     0x0006
+#define ETH_P_WAN_PPP   0x0007
+#define ETH_P_PPP_MP    0x0008
+#define ETH_P_LOCALTALK 0x0009
+#define ETH_P_CAN	0x000C
+#define ETH_P_CANFD	0x000D
+#define ETH_P_PPPTALK	0x0010
+#define ETH_P_TR_802_2	0x0011
+#define ETH_P_MOBITEX	0x0015
+#define ETH_P_CONTROL	0x0016
+#define ETH_P_IRDA	0x0017
+#define ETH_P_ECONET	0x0018
+#define ETH_P_HDLC	0x0019
+#define ETH_P_ARCNET	0x001A
+#define ETH_P_DSA	0x001B
+#define ETH_P_TRAILER	0x001C
+#define ETH_P_PHONET	0x00F5
+#define ETH_P_IEEE802154 0x00F6
+#define ETH_P_CAIF	0x00F7
+#define ETH_P_XDSA	0x00F8
+
+struct ethhdr {
+	uint8_t h_dest[ETH_ALEN];
+	uint8_t h_source[ETH_ALEN];
+	uint16_t h_proto;
+};
+
+#include <net/ethernet.h>
+#include <net/if_arp.h>
+
+struct	ether_arp {
+	struct	arphdr ea_hdr;
+	uint8_t arp_sha[ETH_ALEN];
+	uint8_t arp_spa[4];
+	uint8_t arp_tha[ETH_ALEN];
+	uint8_t arp_tpa[4];
+};
+#define	arp_hrd	ea_hdr.ar_hrd
+#define	arp_pro	ea_hdr.ar_pro
+#define	arp_hln	ea_hdr.ar_hln
+#define	arp_pln	ea_hdr.ar_pln
+#define	arp_op	ea_hdr.ar_op
+
+#define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr) \
+do { \
+	(enaddr)[0] = 0x01; \
+	(enaddr)[1] = 0x00; \
+	(enaddr)[2] = 0x5e; \
+	(enaddr)[3] = ((uint8_t *)ipaddr)[1] & 0x7f; \
+	(enaddr)[4] = ((uint8_t *)ipaddr)[2]; \
+	(enaddr)[5] = ((uint8_t *)ipaddr)[3]; \
+} while(0)
+
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/netinet/igmp.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/netinet/igmp.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/netinet/igmp.h	(revision 331)
@@ -0,0 +1,45 @@
+#ifndef _NETINET_IGMP_H
+#define _NETINET_IGMP_H
+
+#include <stdint.h>
+#include <netinet/in.h>
+
+struct igmp {
+	uint8_t igmp_type;
+	uint8_t igmp_code;
+	uint16_t igmp_cksum;
+	struct in_addr igmp_group;
+};
+
+#define IGMP_MINLEN			8
+
+#define IGMP_MEMBERSHIP_QUERY   	0x11
+#define IGMP_V1_MEMBERSHIP_REPORT	0x12
+#define IGMP_V2_MEMBERSHIP_REPORT	0x16
+#define IGMP_V2_LEAVE_GROUP		0x17
+
+#define IGMP_DVMRP			0x13
+#define IGMP_PIM			0x14
+#define IGMP_TRACE			0x15
+
+#define IGMP_MTRACE_RESP		0x1e
+#define IGMP_MTRACE			0x1f
+
+#define IGMP_MAX_HOST_REPORT_DELAY	10
+#define IGMP_TIMER_SCALE		10
+
+#define IGMP_DELAYING_MEMBER	1
+#define IGMP_IDLE_MEMBER	2
+#define IGMP_LAZY_MEMBER	3
+#define IGMP_SLEEPING_MEMBER	4
+#define IGMP_AWAKENING_MEMBER	5
+
+#define IGMP_v1_ROUTER		1
+#define IGMP_v2_ROUTER		2
+
+#define IGMP_HOST_MEMBERSHIP_QUERY	IGMP_MEMBERSHIP_QUERY
+#define IGMP_HOST_MEMBERSHIP_REPORT	IGMP_V1_MEMBERSHIP_REPORT
+#define IGMP_HOST_NEW_MEMBERSHIP_REPORT	IGMP_V2_MEMBERSHIP_REPORT
+#define IGMP_HOST_LEAVE_MESSAGE		IGMP_V2_LEAVE_GROUP
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/netinet/in.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/netinet/in.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/netinet/in.h	(revision 331)
@@ -0,0 +1,409 @@
+#ifndef	_NETINET_IN_H
+#define	_NETINET_IN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <inttypes.h>
+#include <sys/socket.h>
+
+typedef uint16_t in_port_t;
+typedef uint32_t in_addr_t;
+struct in_addr { in_addr_t s_addr; };
+
+struct sockaddr_in {
+	sa_family_t sin_family;
+	in_port_t sin_port;
+	struct in_addr sin_addr;
+	uint8_t sin_zero[8];
+};
+
+struct in6_addr {
+	union {
+		uint8_t __s6_addr[16];
+		uint16_t __s6_addr16[8];
+		uint32_t __s6_addr32[4];
+	} __in6_union;
+};
+#define s6_addr __in6_union.__s6_addr
+#define s6_addr16 __in6_union.__s6_addr16
+#define s6_addr32 __in6_union.__s6_addr32
+
+struct sockaddr_in6 {
+	sa_family_t     sin6_family;
+	in_port_t       sin6_port;
+	uint32_t        sin6_flowinfo;
+	struct in6_addr sin6_addr;
+	uint32_t        sin6_scope_id;
+};
+
+struct ipv6_mreq {
+	struct in6_addr ipv6mr_multiaddr;
+	unsigned        ipv6mr_interface;
+};
+
+#define INADDR_ANY        ((in_addr_t) 0x00000000)
+#define INADDR_BROADCAST  ((in_addr_t) 0xffffffff)
+#define INADDR_NONE       ((in_addr_t) 0xffffffff)
+#define INADDR_LOOPBACK   ((in_addr_t) 0x7f000001)
+
+#define INADDR_UNSPEC_GROUP     ((in_addr_t) 0xe0000000)
+#define INADDR_ALLHOSTS_GROUP   ((in_addr_t) 0xe0000001)
+#define INADDR_ALLRTRS_GROUP    ((in_addr_t) 0xe0000002)
+#define INADDR_MAX_LOCAL_GROUP  ((in_addr_t) 0xe00000ff)
+
+#define IN6ADDR_ANY_INIT      { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
+#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
+
+extern const struct in6_addr in6addr_any, in6addr_loopback;
+
+#undef INET_ADDRSTRLEN
+#undef INET6_ADDRSTRLEN
+#define INET_ADDRSTRLEN  16
+#define INET6_ADDRSTRLEN 46
+
+uint32_t htonl(uint32_t);
+uint16_t htons(uint16_t);
+uint32_t ntohl(uint32_t);
+uint16_t ntohs(uint16_t);
+
+#define IPPORT_RESERVED 1024
+
+#define IPPROTO_IP       0
+#define IPPROTO_HOPOPTS  0
+#define IPPROTO_ICMP     1
+#define IPPROTO_IGMP     2
+#define IPPROTO_IPIP     4
+#define IPPROTO_TCP      6
+#define IPPROTO_EGP      8
+#define IPPROTO_PUP      12
+#define IPPROTO_UDP      17
+#define IPPROTO_IDP      22
+#define IPPROTO_TP       29
+#define IPPROTO_DCCP     33
+#define IPPROTO_IPV6     41
+#define IPPROTO_ROUTING  43
+#define IPPROTO_FRAGMENT 44
+#define IPPROTO_RSVP     46
+#define IPPROTO_GRE      47
+#define IPPROTO_ESP      50
+#define IPPROTO_AH       51
+#define IPPROTO_ICMPV6   58
+#define IPPROTO_NONE     59
+#define IPPROTO_DSTOPTS  60
+#define IPPROTO_MTP      92
+#define IPPROTO_BEETPH   94
+#define IPPROTO_ENCAP    98
+#define IPPROTO_PIM      103
+#define IPPROTO_COMP     108
+#define IPPROTO_SCTP     132
+#define IPPROTO_MH       135
+#define IPPROTO_UDPLITE  136
+#define IPPROTO_MPLS     137
+#define IPPROTO_RAW      255
+#define IPPROTO_MAX      256
+
+#define IN6_IS_ADDR_UNSPECIFIED(a) \
+        (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
+         ((uint32_t *) (a))[2] == 0 && ((uint32_t *) (a))[3] == 0)
+
+#define IN6_IS_ADDR_LOOPBACK(a) \
+        (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
+         ((uint32_t *) (a))[2] == 0 && \
+         ((uint8_t *) (a))[12] == 0 && ((uint8_t *) (a))[13] == 0 && \
+         ((uint8_t *) (a))[14] == 0 && ((uint8_t *) (a))[15] == 1 )
+
+#define IN6_IS_ADDR_MULTICAST(a) (((uint8_t *) (a))[0] == 0xff)
+
+#define IN6_IS_ADDR_LINKLOCAL(a) \
+        ((((uint8_t *) (a))[0]) == 0xfe && (((uint8_t *) (a))[1] & 0xc0) == 0x80)
+
+#define IN6_IS_ADDR_SITELOCAL(a) \
+        ((((uint8_t *) (a))[0]) == 0xfe && (((uint8_t *) (a))[1] & 0xc0) == 0xc0)
+
+#define IN6_IS_ADDR_V4MAPPED(a) \
+        (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
+         ((uint8_t *) (a))[8] == 0 && ((uint8_t *) (a))[9] == 0 && \
+         ((uint8_t *) (a))[10] == 0xff && ((uint8_t *) (a))[11] == 0xff)
+
+#define IN6_IS_ADDR_V4COMPAT(a) \
+        (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
+         ((uint32_t *) (a))[2] == 0 && ((uint8_t *) (a))[15] > 1)
+
+#define IN6_IS_ADDR_MC_NODELOCAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x1))
+
+#define IN6_IS_ADDR_MC_LINKLOCAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x2))
+
+#define IN6_IS_ADDR_MC_SITELOCAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x5))
+
+#define IN6_IS_ADDR_MC_ORGLOCAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x8))
+
+#define IN6_IS_ADDR_MC_GLOBAL(a) \
+        (IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0xe))
+
+#define __ARE_4_EQUAL(a,b) \
+	(!( (0[a]-0[b]) | (1[a]-1[b]) | (2[a]-2[b]) | (3[a]-3[b]) ))
+#define IN6_ARE_ADDR_EQUAL(a,b) \
+	__ARE_4_EQUAL((const uint32_t *)(a), (const uint32_t *)(b))
+
+#define	IN_CLASSA(a)		((((in_addr_t)(a)) & 0x80000000) == 0)
+#define	IN_CLASSA_NET		0xff000000
+#define	IN_CLASSA_NSHIFT	24
+#define	IN_CLASSA_HOST		(0xffffffff & ~IN_CLASSA_NET)
+#define	IN_CLASSA_MAX		128
+#define	IN_CLASSB(a)		((((in_addr_t)(a)) & 0xc0000000) == 0x80000000)
+#define	IN_CLASSB_NET		0xffff0000
+#define	IN_CLASSB_NSHIFT	16
+#define	IN_CLASSB_HOST		(0xffffffff & ~IN_CLASSB_NET)
+#define	IN_CLASSB_MAX		65536
+#define	IN_CLASSC(a)		((((in_addr_t)(a)) & 0xe0000000) == 0xc0000000)
+#define	IN_CLASSC_NET		0xffffff00
+#define	IN_CLASSC_NSHIFT	8
+#define	IN_CLASSC_HOST		(0xffffffff & ~IN_CLASSC_NET)
+#define	IN_CLASSD(a)		((((in_addr_t)(a)) & 0xf0000000) == 0xe0000000)
+#define	IN_MULTICAST(a)		IN_CLASSD(a)
+#define	IN_EXPERIMENTAL(a)	((((in_addr_t)(a)) & 0xe0000000) == 0xe0000000)
+#define	IN_BADCLASS(a)		((((in_addr_t)(a)) & 0xf0000000) == 0xf0000000)
+
+#define IN_LOOPBACKNET 127
+
+
+#define IP_TOS             1
+#define IP_TTL             2
+#define IP_HDRINCL         3
+#define IP_OPTIONS         4
+#define IP_ROUTER_ALERT    5
+#define IP_RECVOPTS        6
+#define IP_RETOPTS         7
+#define IP_PKTINFO         8
+#define IP_PKTOPTIONS      9
+#define IP_PMTUDISC        10
+#define IP_MTU_DISCOVER    10
+#define IP_RECVERR         11
+#define IP_RECVTTL         12
+#define IP_RECVTOS         13
+#define IP_MTU             14
+#define IP_FREEBIND        15
+#define IP_IPSEC_POLICY    16
+#define IP_XFRM_POLICY     17
+#define IP_PASSSEC         18
+#define IP_TRANSPARENT     19
+#define IP_ORIGDSTADDR     20
+#define IP_RECVORIGDSTADDR IP_ORIGDSTADDR
+#define IP_MINTTL          21
+#define IP_NODEFRAG        22
+#define IP_CHECKSUM        23
+#define IP_BIND_ADDRESS_NO_PORT 24
+#define IP_MULTICAST_IF    32
+#define IP_MULTICAST_TTL   33
+#define IP_MULTICAST_LOOP  34
+#define IP_ADD_MEMBERSHIP  35
+#define IP_DROP_MEMBERSHIP 36
+#define IP_UNBLOCK_SOURCE  37
+#define IP_BLOCK_SOURCE    38
+#define IP_ADD_SOURCE_MEMBERSHIP  39
+#define IP_DROP_SOURCE_MEMBERSHIP 40
+#define IP_MSFILTER        41
+#define IP_MULTICAST_ALL   49
+#define IP_UNICAST_IF      50
+
+#define IP_RECVRETOPTS IP_RETOPTS
+
+#define IP_PMTUDISC_DONT   0
+#define IP_PMTUDISC_WANT   1
+#define IP_PMTUDISC_DO     2
+#define IP_PMTUDISC_PROBE  3
+#define IP_PMTUDISC_INTERFACE 4
+#define IP_PMTUDISC_OMIT   5
+
+#define IP_DEFAULT_MULTICAST_TTL        1
+#define IP_DEFAULT_MULTICAST_LOOP       1
+#define IP_MAX_MEMBERSHIPS              20
+
+struct ip_opts {
+	struct in_addr ip_dst;
+	char ip_opts[40];
+};
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+#define MCAST_JOIN_GROUP   42
+#define MCAST_BLOCK_SOURCE 43
+#define MCAST_UNBLOCK_SOURCE      44
+#define MCAST_LEAVE_GROUP  45
+#define MCAST_JOIN_SOURCE_GROUP   46
+#define MCAST_LEAVE_SOURCE_GROUP  47
+#define MCAST_MSFILTER     48
+
+#define MCAST_EXCLUDE 0
+#define MCAST_INCLUDE 1
+
+struct ip_mreq {
+	struct in_addr imr_multiaddr;
+	struct in_addr imr_interface;
+};
+
+struct ip_mreqn {
+	struct in_addr imr_multiaddr;
+	struct in_addr imr_address;
+	int imr_ifindex;
+};
+
+struct ip_mreq_source {
+	struct in_addr imr_multiaddr;
+	struct in_addr imr_interface;
+	struct in_addr imr_sourceaddr;
+};
+
+struct ip_msfilter {
+	struct in_addr imsf_multiaddr;
+	struct in_addr imsf_interface;
+	uint32_t imsf_fmode;
+	uint32_t imsf_numsrc;
+	struct in_addr imsf_slist[1];
+};
+#define IP_MSFILTER_SIZE(numsrc) \
+	(sizeof(struct ip_msfilter) - sizeof(struct in_addr) \
+	+ (numsrc) * sizeof(struct in_addr))
+
+struct group_req {
+	uint32_t gr_interface;
+	struct sockaddr_storage gr_group;
+};
+
+struct group_source_req {
+	uint32_t gsr_interface;
+	struct sockaddr_storage gsr_group;
+	struct sockaddr_storage gsr_source;
+};
+
+struct group_filter {
+	uint32_t gf_interface;
+	struct sockaddr_storage gf_group;
+	uint32_t gf_fmode;
+	uint32_t gf_numsrc;
+	struct sockaddr_storage gf_slist[1];
+};
+#define GROUP_FILTER_SIZE(numsrc) \
+	(sizeof(struct group_filter) - sizeof(struct sockaddr_storage) \
+	+ (numsrc) * sizeof(struct sockaddr_storage))
+
+struct in_pktinfo {
+	int ipi_ifindex;
+	struct in_addr ipi_spec_dst;
+	struct in_addr ipi_addr;
+};
+
+struct in6_pktinfo {
+	struct in6_addr ipi6_addr;
+	unsigned ipi6_ifindex;
+};
+
+struct ip6_mtuinfo {
+	struct sockaddr_in6 ip6m_addr;
+	uint32_t ip6m_mtu;
+};
+#endif
+
+#define IPV6_ADDRFORM           1
+#define IPV6_2292PKTINFO        2
+#define IPV6_2292HOPOPTS        3
+#define IPV6_2292DSTOPTS        4
+#define IPV6_2292RTHDR          5
+#define IPV6_2292PKTOPTIONS     6
+#define IPV6_CHECKSUM           7
+#define IPV6_2292HOPLIMIT       8
+#define IPV6_NEXTHOP            9
+#define IPV6_AUTHHDR            10
+#define IPV6_UNICAST_HOPS       16
+#define IPV6_MULTICAST_IF       17
+#define IPV6_MULTICAST_HOPS     18
+#define IPV6_MULTICAST_LOOP     19
+#define IPV6_JOIN_GROUP         20
+#define IPV6_LEAVE_GROUP        21
+#define IPV6_ROUTER_ALERT       22
+#define IPV6_MTU_DISCOVER       23
+#define IPV6_MTU                24
+#define IPV6_RECVERR            25
+#define IPV6_V6ONLY             26
+#define IPV6_JOIN_ANYCAST       27
+#define IPV6_LEAVE_ANYCAST      28
+#define IPV6_IPSEC_POLICY       34
+#define IPV6_XFRM_POLICY        35
+#define IPV6_HDRINCL            36
+
+#define IPV6_RECVPKTINFO        49
+#define IPV6_PKTINFO            50
+#define IPV6_RECVHOPLIMIT       51
+#define IPV6_HOPLIMIT           52
+#define IPV6_RECVHOPOPTS        53
+#define IPV6_HOPOPTS            54
+#define IPV6_RTHDRDSTOPTS       55
+#define IPV6_RECVRTHDR          56
+#define IPV6_RTHDR              57
+#define IPV6_RECVDSTOPTS        58
+#define IPV6_DSTOPTS            59
+#define IPV6_RECVPATHMTU        60
+#define IPV6_PATHMTU            61
+#define IPV6_DONTFRAG           62
+#define IPV6_RECVTCLASS         66
+#define IPV6_TCLASS             67
+#define IPV6_AUTOFLOWLABEL      70
+#define IPV6_ADDR_PREFERENCES   72
+#define IPV6_MINHOPCOUNT        73
+#define IPV6_ORIGDSTADDR        74
+#define IPV6_RECVORIGDSTADDR    IPV6_ORIGDSTADDR
+#define IPV6_TRANSPARENT        75
+#define IPV6_UNICAST_IF         76
+
+#define IPV6_ADD_MEMBERSHIP     IPV6_JOIN_GROUP
+#define IPV6_DROP_MEMBERSHIP    IPV6_LEAVE_GROUP
+#define IPV6_RXHOPOPTS          IPV6_HOPOPTS
+#define IPV6_RXDSTOPTS          IPV6_DSTOPTS
+
+#define IPV6_PMTUDISC_DONT      0
+#define IPV6_PMTUDISC_WANT      1
+#define IPV6_PMTUDISC_DO        2
+#define IPV6_PMTUDISC_PROBE     3
+#define IPV6_PMTUDISC_INTERFACE 4
+#define IPV6_PMTUDISC_OMIT      5
+
+#define IPV6_PREFER_SRC_TMP            0x0001
+#define IPV6_PREFER_SRC_PUBLIC         0x0002
+#define IPV6_PREFER_SRC_PUBTMP_DEFAULT 0x0100
+#define IPV6_PREFER_SRC_COA            0x0004
+#define IPV6_PREFER_SRC_HOME           0x0400
+#define IPV6_PREFER_SRC_CGA            0x0008
+#define IPV6_PREFER_SRC_NONCGA         0x0800
+
+#define IPV6_RTHDR_LOOSE        0
+#define IPV6_RTHDR_STRICT       1
+
+#define IPV6_RTHDR_TYPE_0       0
+
+#define __UAPI_DEF_IN_ADDR      0
+#define __UAPI_DEF_IN_IPPROTO   0
+#define __UAPI_DEF_IN_PKTINFO   0
+#define __UAPI_DEF_IP_MREQ      0
+#define __UAPI_DEF_SOCKADDR_IN  0
+#define __UAPI_DEF_IN_CLASS     0
+#define __UAPI_DEF_IN6_ADDR     0
+#define __UAPI_DEF_IN6_ADDR_ALT 0
+#define __UAPI_DEF_SOCKADDR_IN6 0
+#define __UAPI_DEF_IPV6_MREQ    0
+#define __UAPI_DEF_IPPROTO_V6   0
+#define __UAPI_DEF_IPV6_OPTIONS 0
+#define __UAPI_DEF_IN6_PKTINFO  0
+#define __UAPI_DEF_IP6_MTUINFO  0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/netinet/in_systm.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/netinet/in_systm.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/netinet/in_systm.h	(revision 331)
@@ -0,0 +1,9 @@
+#ifndef _NETINET_IN_SYSTM_H
+#define _NETINET_IN_SYSTM_H
+
+#include <stdint.h>
+
+typedef uint16_t n_short;
+typedef uint32_t n_long, n_time;
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/netinet/ip.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/netinet/ip.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/netinet/ip.h	(revision 331)
@@ -0,0 +1,198 @@
+#ifndef _NETINET_IP_H
+#define _NETINET_IP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <netinet/in.h>
+#include <endian.h>
+
+struct timestamp {
+	uint8_t len;
+	uint8_t ptr;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	unsigned int flags:4;
+	unsigned int overflow:4;
+#else
+	unsigned int overflow:4;
+	unsigned int flags:4;
+#endif
+	uint32_t data[9];
+  };
+
+struct iphdr {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	unsigned int ihl:4;
+	unsigned int version:4;
+#else
+	unsigned int version:4;
+	unsigned int ihl:4;
+#endif
+	uint8_t tos;
+	uint16_t tot_len;
+	uint16_t id;
+	uint16_t frag_off;
+	uint8_t ttl;
+	uint8_t protocol;
+	uint16_t check;
+	uint32_t saddr;
+	uint32_t daddr;
+};
+
+struct ip {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	unsigned int ip_hl:4;
+	unsigned int ip_v:4;
+#else
+	unsigned int ip_v:4;
+	unsigned int ip_hl:4;
+#endif
+	uint8_t ip_tos;
+	uint16_t ip_len;
+	uint16_t ip_id;
+	uint16_t ip_off;
+	uint8_t ip_ttl;
+	uint8_t ip_p;
+	uint16_t ip_sum;
+	struct in_addr ip_src, ip_dst;
+};
+
+#define	IP_RF 0x8000
+#define	IP_DF 0x4000
+#define	IP_MF 0x2000
+#define	IP_OFFMASK 0x1fff
+
+struct ip_timestamp {
+	uint8_t ipt_code;
+	uint8_t ipt_len;
+	uint8_t ipt_ptr;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	unsigned int ipt_flg:4;
+	unsigned int ipt_oflw:4;
+#else
+	unsigned int ipt_oflw:4;
+	unsigned int ipt_flg:4;
+#endif
+	uint32_t data[9];
+};
+
+#define	IPVERSION	4
+#define	IP_MAXPACKET	65535
+
+#define	IPTOS_ECN_MASK		0x03
+#define	IPTOS_ECN(x)		((x) & IPTOS_ECN_MASK)
+#define	IPTOS_ECN_NOT_ECT	0x00
+#define	IPTOS_ECN_ECT1		0x01
+#define	IPTOS_ECN_ECT0		0x02
+#define	IPTOS_ECN_CE		0x03
+
+#define	IPTOS_DSCP_MASK		0xfc
+#define	IPTOS_DSCP(x)		((x) & IPTOS_DSCP_MASK)
+#define	IPTOS_DSCP_AF11		0x28
+#define	IPTOS_DSCP_AF12		0x30
+#define	IPTOS_DSCP_AF13		0x38
+#define	IPTOS_DSCP_AF21		0x48
+#define	IPTOS_DSCP_AF22		0x50
+#define	IPTOS_DSCP_AF23		0x58
+#define	IPTOS_DSCP_AF31		0x68
+#define	IPTOS_DSCP_AF32		0x70
+#define	IPTOS_DSCP_AF33		0x78
+#define	IPTOS_DSCP_AF41		0x88
+#define	IPTOS_DSCP_AF42		0x90
+#define	IPTOS_DSCP_AF43		0x98
+#define	IPTOS_DSCP_EF		0xb8
+
+#define	IPTOS_CLASS_MASK	0xe0
+#define	IPTOS_CLASS(x)		((x) & IPTOS_CLASS_MASK)
+#define	IPTOS_CLASS_CS0		0x00
+#define	IPTOS_CLASS_CS1		0x20
+#define	IPTOS_CLASS_CS2		0x40
+#define	IPTOS_CLASS_CS3		0x60
+#define	IPTOS_CLASS_CS4		0x80
+#define	IPTOS_CLASS_CS5		0xa0
+#define	IPTOS_CLASS_CS6		0xc0
+#define	IPTOS_CLASS_CS7		0xe0
+#define	IPTOS_CLASS_DEFAULT	IPTOS_CLASS_CS0
+
+#define	IPTOS_TOS_MASK		0x1E
+#define	IPTOS_TOS(tos)		((tos) & IPTOS_TOS_MASK)
+#define	IPTOS_LOWDELAY		0x10
+#define	IPTOS_THROUGHPUT	0x08
+#define	IPTOS_RELIABILITY	0x04
+#define	IPTOS_LOWCOST		0x02
+#define	IPTOS_MINCOST		IPTOS_LOWCOST
+
+#define	IPTOS_PREC_MASK			0xe0
+#define	IPTOS_PREC(tos)                ((tos) & IPTOS_PREC_MASK)
+#define	IPTOS_PREC_NETCONTROL		0xe0
+#define	IPTOS_PREC_INTERNETCONTROL	0xc0
+#define	IPTOS_PREC_CRITIC_ECP		0xa0
+#define	IPTOS_PREC_FLASHOVERRIDE	0x80
+#define	IPTOS_PREC_FLASH		0x60
+#define	IPTOS_PREC_IMMEDIATE		0x40
+#define	IPTOS_PREC_PRIORITY		0x20
+#define	IPTOS_PREC_ROUTINE		0x00
+
+#define	IPOPT_COPY		0x80
+#define	IPOPT_CLASS_MASK	0x60
+#define	IPOPT_NUMBER_MASK	0x1f
+
+#define	IPOPT_COPIED(o)		((o) & IPOPT_COPY)
+#define	IPOPT_CLASS(o)		((o) & IPOPT_CLASS_MASK)
+#define	IPOPT_NUMBER(o)		((o) & IPOPT_NUMBER_MASK)
+
+#define	IPOPT_CONTROL		0x00
+#define	IPOPT_RESERVED1		0x20
+#define	IPOPT_DEBMEAS		0x40
+#define	IPOPT_MEASUREMENT       IPOPT_DEBMEAS
+#define	IPOPT_RESERVED2		0x60
+
+#define	IPOPT_EOL		0
+#define	IPOPT_END		IPOPT_EOL
+#define	IPOPT_NOP		1
+#define	IPOPT_NOOP		IPOPT_NOP
+
+#define	IPOPT_RR		7
+#define	IPOPT_TS		68
+#define	IPOPT_TIMESTAMP		IPOPT_TS
+#define	IPOPT_SECURITY		130
+#define	IPOPT_SEC		IPOPT_SECURITY
+#define	IPOPT_LSRR		131
+#define	IPOPT_SATID		136
+#define	IPOPT_SID		IPOPT_SATID
+#define	IPOPT_SSRR		137
+#define	IPOPT_RA		148
+
+#define	IPOPT_OPTVAL		0
+#define	IPOPT_OLEN		1
+#define	IPOPT_OFFSET		2
+#define	IPOPT_MINOFF		4
+
+#define	MAX_IPOPTLEN		40
+
+#define	IPOPT_TS_TSONLY		0
+#define	IPOPT_TS_TSANDADDR	1
+#define	IPOPT_TS_PRESPEC	3
+
+#define	IPOPT_SECUR_UNCLASS	0x0000
+#define	IPOPT_SECUR_CONFID	0xf135
+#define	IPOPT_SECUR_EFTO	0x789a
+#define	IPOPT_SECUR_MMMM	0xbc4d
+#define	IPOPT_SECUR_RESTR	0xaf13
+#define	IPOPT_SECUR_SECRET	0xd788
+#define	IPOPT_SECUR_TOPSECRET	0x6bc5
+
+#define	MAXTTL		255
+#define	IPDEFTTL	64
+#define	IPFRAGTTL	60
+#define	IPTTLDEC	1
+
+#define	IP_MSS		576
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/netinet/ip6.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/netinet/ip6.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/netinet/ip6.h	(revision 331)
@@ -0,0 +1,142 @@
+#ifndef _NETINET_IP6_H
+#define _NETINET_IP6_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <netinet/in.h>
+#include <endian.h>
+
+struct ip6_hdr {
+	union {
+		struct ip6_hdrctl {
+			uint32_t ip6_un1_flow;
+			uint16_t ip6_un1_plen;
+			uint8_t  ip6_un1_nxt;
+			uint8_t  ip6_un1_hlim;
+		} ip6_un1;
+		uint8_t ip6_un2_vfc;
+	} ip6_ctlun;
+	struct in6_addr ip6_src;
+	struct in6_addr ip6_dst;
+};
+
+#define ip6_vfc   ip6_ctlun.ip6_un2_vfc
+#define ip6_flow  ip6_ctlun.ip6_un1.ip6_un1_flow
+#define ip6_plen  ip6_ctlun.ip6_un1.ip6_un1_plen
+#define ip6_nxt   ip6_ctlun.ip6_un1.ip6_un1_nxt
+#define ip6_hlim  ip6_ctlun.ip6_un1.ip6_un1_hlim
+#define ip6_hops  ip6_ctlun.ip6_un1.ip6_un1_hlim
+
+struct ip6_ext {
+	uint8_t  ip6e_nxt;
+	uint8_t  ip6e_len;
+};
+
+struct ip6_hbh {
+	uint8_t  ip6h_nxt;
+	uint8_t  ip6h_len;
+};
+
+struct ip6_dest {
+	uint8_t  ip6d_nxt;
+	uint8_t  ip6d_len;
+};
+
+struct ip6_rthdr {
+	uint8_t  ip6r_nxt;
+	uint8_t  ip6r_len;
+	uint8_t  ip6r_type;
+	uint8_t  ip6r_segleft;
+};
+
+struct ip6_rthdr0 {
+	uint8_t  ip6r0_nxt;
+	uint8_t  ip6r0_len;
+	uint8_t  ip6r0_type;
+	uint8_t  ip6r0_segleft;
+	uint8_t  ip6r0_reserved;
+	uint8_t  ip6r0_slmap[3];
+	struct in6_addr ip6r0_addr[];
+};
+
+struct ip6_frag {
+	uint8_t   ip6f_nxt;
+	uint8_t   ip6f_reserved;
+	uint16_t  ip6f_offlg;
+	uint32_t  ip6f_ident;
+};
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define IP6F_OFF_MASK       0xfff8
+#define IP6F_RESERVED_MASK  0x0006
+#define IP6F_MORE_FRAG      0x0001
+#else
+#define IP6F_OFF_MASK       0xf8ff
+#define IP6F_RESERVED_MASK  0x0600
+#define IP6F_MORE_FRAG      0x0100
+#endif
+
+struct ip6_opt {
+	uint8_t  ip6o_type;
+	uint8_t  ip6o_len;
+};
+
+#define IP6OPT_TYPE(o)		((o) & 0xc0)
+#define IP6OPT_TYPE_SKIP	0x00
+#define IP6OPT_TYPE_DISCARD	0x40
+#define IP6OPT_TYPE_FORCEICMP	0x80
+#define IP6OPT_TYPE_ICMP	0xc0
+#define IP6OPT_TYPE_MUTABLE	0x20
+
+#define IP6OPT_PAD1	0
+#define IP6OPT_PADN	1
+
+#define IP6OPT_JUMBO		0xc2
+#define IP6OPT_NSAP_ADDR	0xc3
+#define IP6OPT_TUNNEL_LIMIT	0x04
+#define IP6OPT_ROUTER_ALERT	0x05
+
+struct ip6_opt_jumbo {
+	uint8_t  ip6oj_type;
+	uint8_t  ip6oj_len;
+	uint8_t  ip6oj_jumbo_len[4];
+};
+#define IP6OPT_JUMBO_LEN	6
+
+struct ip6_opt_nsap {
+	uint8_t  ip6on_type;
+	uint8_t  ip6on_len;
+	uint8_t  ip6on_src_nsap_len;
+	uint8_t  ip6on_dst_nsap_len;
+};
+
+struct ip6_opt_tunnel {
+	uint8_t  ip6ot_type;
+	uint8_t  ip6ot_len;
+	uint8_t  ip6ot_encap_limit;
+};
+
+struct ip6_opt_router {
+	uint8_t  ip6or_type;
+	uint8_t  ip6or_len;
+	uint8_t  ip6or_value[2];
+};
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define IP6_ALERT_MLD	0x0000
+#define IP6_ALERT_RSVP	0x0001
+#define IP6_ALERT_AN	0x0002
+#else
+#define IP6_ALERT_MLD	0x0000
+#define IP6_ALERT_RSVP	0x0100
+#define IP6_ALERT_AN	0x0200
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/netinet/ip_icmp.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/netinet/ip_icmp.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/netinet/ip_icmp.h	(revision 331)
@@ -0,0 +1,193 @@
+#ifndef _NETINET_IP_ICMP_H
+#define _NETINET_IP_ICMP_H
+
+#include <stdint.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct icmphdr {
+	uint8_t type;
+	uint8_t code;
+	uint16_t checksum;
+	union {
+		struct {
+			uint16_t id;
+			uint16_t sequence;
+		} echo;
+		uint32_t gateway;
+		struct {
+			uint16_t __unused;
+			uint16_t mtu;
+		} frag;
+		uint8_t reserved[4];
+	} un;
+};
+
+#define ICMP_ECHOREPLY		0
+#define ICMP_DEST_UNREACH	3
+#define ICMP_SOURCE_QUENCH	4
+#define ICMP_REDIRECT		5
+#define ICMP_ECHO		8
+#define ICMP_TIME_EXCEEDED	11
+#define ICMP_PARAMETERPROB	12
+#define ICMP_TIMESTAMP		13
+#define ICMP_TIMESTAMPREPLY	14
+#define ICMP_INFO_REQUEST	15
+#define ICMP_INFO_REPLY		16
+#define ICMP_ADDRESS		17
+#define ICMP_ADDRESSREPLY	18
+#define NR_ICMP_TYPES		18
+
+
+#define ICMP_NET_UNREACH	0
+#define ICMP_HOST_UNREACH	1
+#define ICMP_PROT_UNREACH	2
+#define ICMP_PORT_UNREACH	3
+#define ICMP_FRAG_NEEDED	4
+#define ICMP_SR_FAILED		5
+#define ICMP_NET_UNKNOWN	6
+#define ICMP_HOST_UNKNOWN	7
+#define ICMP_HOST_ISOLATED	8
+#define ICMP_NET_ANO		9
+#define ICMP_HOST_ANO		10
+#define ICMP_NET_UNR_TOS	11
+#define ICMP_HOST_UNR_TOS	12
+#define ICMP_PKT_FILTERED	13
+#define ICMP_PREC_VIOLATION	14
+#define ICMP_PREC_CUTOFF	15
+#define NR_ICMP_UNREACH		15
+
+#define ICMP_REDIR_NET		0
+#define ICMP_REDIR_HOST		1
+#define ICMP_REDIR_NETTOS	2
+#define ICMP_REDIR_HOSTTOS	3
+
+#define ICMP_EXC_TTL		0
+#define ICMP_EXC_FRAGTIME	1
+
+
+struct icmp_ra_addr {
+	uint32_t ira_addr;
+	uint32_t ira_preference;
+};
+
+struct icmp {
+	uint8_t  icmp_type;
+	uint8_t  icmp_code;
+	uint16_t icmp_cksum;
+	union {
+		uint8_t ih_pptr;
+		struct in_addr ih_gwaddr;
+		struct ih_idseq {
+			uint16_t icd_id;
+			uint16_t icd_seq;
+		} ih_idseq;
+		uint32_t ih_void;
+
+		struct ih_pmtu {
+			uint16_t ipm_void;
+			uint16_t ipm_nextmtu;
+		} ih_pmtu;
+
+		struct ih_rtradv {
+			uint8_t irt_num_addrs;
+			uint8_t irt_wpa;
+			uint16_t irt_lifetime;
+		} ih_rtradv;
+	} icmp_hun;
+	union {
+		struct {
+			uint32_t its_otime;
+			uint32_t its_rtime;
+			uint32_t its_ttime;
+		} id_ts;
+		struct {
+			struct ip idi_ip;
+		} id_ip;
+		struct icmp_ra_addr id_radv;
+		uint32_t   id_mask;
+		uint8_t    id_data[1];
+	} icmp_dun;
+};
+
+#define	icmp_pptr	icmp_hun.ih_pptr
+#define	icmp_gwaddr	icmp_hun.ih_gwaddr
+#define	icmp_id		icmp_hun.ih_idseq.icd_id
+#define	icmp_seq	icmp_hun.ih_idseq.icd_seq
+#define	icmp_void	icmp_hun.ih_void
+#define	icmp_pmvoid	icmp_hun.ih_pmtu.ipm_void
+#define	icmp_nextmtu	icmp_hun.ih_pmtu.ipm_nextmtu
+#define	icmp_num_addrs	icmp_hun.ih_rtradv.irt_num_addrs
+#define	icmp_wpa	icmp_hun.ih_rtradv.irt_wpa
+#define	icmp_lifetime	icmp_hun.ih_rtradv.irt_lifetime
+#define	icmp_otime	icmp_dun.id_ts.its_otime
+#define	icmp_rtime	icmp_dun.id_ts.its_rtime
+#define	icmp_ttime	icmp_dun.id_ts.its_ttime
+#define	icmp_ip		icmp_dun.id_ip.idi_ip
+#define	icmp_radv	icmp_dun.id_radv
+#define	icmp_mask	icmp_dun.id_mask
+#define	icmp_data	icmp_dun.id_data
+
+#define	ICMP_MINLEN	8
+#define	ICMP_TSLEN	(8 + 3 * sizeof (n_time))
+#define	ICMP_MASKLEN	12
+#define	ICMP_ADVLENMIN	(8 + sizeof (struct ip) + 8)
+#define	ICMP_ADVLEN(p)	(8 + ((p)->icmp_ip.ip_hl << 2) + 8)
+
+#define	ICMP_UNREACH		3
+#define	ICMP_SOURCEQUENCH	4
+#define	ICMP_ROUTERADVERT	9
+#define	ICMP_ROUTERSOLICIT	10
+#define	ICMP_TIMXCEED		11
+#define	ICMP_PARAMPROB		12
+#define	ICMP_TSTAMP		13
+#define	ICMP_TSTAMPREPLY	14
+#define	ICMP_IREQ		15
+#define	ICMP_IREQREPLY		16
+#define	ICMP_MASKREQ		17
+#define	ICMP_MASKREPLY		18
+#define	ICMP_MAXTYPE		18
+
+#define	ICMP_UNREACH_NET	        0
+#define	ICMP_UNREACH_HOST	        1
+#define	ICMP_UNREACH_PROTOCOL	        2
+#define	ICMP_UNREACH_PORT	        3
+#define	ICMP_UNREACH_NEEDFRAG	        4
+#define	ICMP_UNREACH_SRCFAIL	        5
+#define	ICMP_UNREACH_NET_UNKNOWN        6
+#define	ICMP_UNREACH_HOST_UNKNOWN       7
+#define	ICMP_UNREACH_ISOLATED	        8
+#define	ICMP_UNREACH_NET_PROHIB	        9
+#define	ICMP_UNREACH_HOST_PROHIB        10
+#define	ICMP_UNREACH_TOSNET	        11
+#define	ICMP_UNREACH_TOSHOST	        12
+#define	ICMP_UNREACH_FILTER_PROHIB      13
+#define	ICMP_UNREACH_HOST_PRECEDENCE    14
+#define	ICMP_UNREACH_PRECEDENCE_CUTOFF  15
+
+#define	ICMP_REDIRECT_NET	0
+#define	ICMP_REDIRECT_HOST	1
+#define	ICMP_REDIRECT_TOSNET	2
+#define	ICMP_REDIRECT_TOSHOST	3
+
+#define	ICMP_TIMXCEED_INTRANS	0
+#define	ICMP_TIMXCEED_REASS	1
+
+#define	ICMP_PARAMPROB_OPTABSENT 1
+
+#define	ICMP_INFOTYPE(type) \
+	((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \
+	(type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \
+	(type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \
+	(type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \
+	(type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/netinet/tcp.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/netinet/tcp.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/netinet/tcp.h	(revision 331)
@@ -0,0 +1,215 @@
+#ifndef _NETINET_TCP_H
+#define _NETINET_TCP_H
+
+#include <features.h>
+
+#define TCP_NODELAY 1
+#define TCP_MAXSEG	 2
+#define TCP_CORK	 3
+#define TCP_KEEPIDLE	 4
+#define TCP_KEEPINTVL	 5
+#define TCP_KEEPCNT	 6
+#define TCP_SYNCNT	 7
+#define TCP_LINGER2	 8
+#define TCP_DEFER_ACCEPT 9
+#define TCP_WINDOW_CLAMP 10
+#define TCP_INFO	 11
+#define	TCP_QUICKACK	 12
+#define TCP_CONGESTION	 13
+#define TCP_MD5SIG	 14
+#define TCP_THIN_LINEAR_TIMEOUTS 16
+#define TCP_THIN_DUPACK  17
+#define TCP_USER_TIMEOUT 18
+#define TCP_REPAIR       19
+#define TCP_REPAIR_QUEUE 20
+#define TCP_QUEUE_SEQ    21
+#define TCP_REPAIR_OPTIONS 22
+#define TCP_FASTOPEN     23
+#define TCP_TIMESTAMP    24
+#define TCP_NOTSENT_LOWAT 25
+#define TCP_CC_INFO      26
+#define TCP_SAVE_SYN     27
+#define TCP_SAVED_SYN    28
+#define TCP_REPAIR_WINDOW 29
+
+#define TCP_ESTABLISHED  1
+#define TCP_SYN_SENT     2
+#define TCP_SYN_RECV     3
+#define TCP_FIN_WAIT1    4
+#define TCP_FIN_WAIT2    5
+#define TCP_TIME_WAIT    6
+#define TCP_CLOSE        7
+#define TCP_CLOSE_WAIT   8
+#define TCP_LAST_ACK     9
+#define TCP_LISTEN       10
+#define TCP_CLOSING      11
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define TCPOPT_EOL              0
+#define TCPOPT_NOP              1
+#define TCPOPT_MAXSEG           2
+#define TCPOPT_WINDOW           3
+#define TCPOPT_SACK_PERMITTED   4
+#define TCPOPT_SACK             5
+#define TCPOPT_TIMESTAMP        8
+#define TCPOLEN_SACK_PERMITTED  2
+#define TCPOLEN_WINDOW          3
+#define TCPOLEN_MAXSEG          4
+#define TCPOLEN_TIMESTAMP       10
+
+#define SOL_TCP 6
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdint.h>
+#include <endian.h>
+
+typedef uint32_t tcp_seq;
+
+#define TH_FIN 0x01
+#define TH_SYN 0x02
+#define TH_RST 0x04
+#define TH_PUSH 0x08
+#define TH_ACK 0x10
+#define TH_URG 0x20
+
+struct tcphdr {
+#ifdef _GNU_SOURCE
+#ifdef __GNUC__
+	__extension__
+#endif
+	union { struct {
+
+	uint16_t source;
+	uint16_t dest;
+	uint32_t seq;
+	uint32_t ack_seq;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	uint16_t res1:4;
+	uint16_t doff:4;
+	uint16_t fin:1;
+	uint16_t syn:1;
+	uint16_t rst:1;
+	uint16_t psh:1;
+	uint16_t ack:1;
+	uint16_t urg:1;
+	uint16_t res2:2;
+#else
+	uint16_t doff:4;
+	uint16_t res1:4;
+	uint16_t res2:2;
+	uint16_t urg:1;
+	uint16_t ack:1;
+	uint16_t psh:1;
+	uint16_t rst:1;
+	uint16_t syn:1;
+	uint16_t fin:1;
+#endif
+	uint16_t window;
+	uint16_t check;
+	uint16_t urg_ptr;
+
+	}; struct {
+#endif
+
+	uint16_t th_sport;
+	uint16_t th_dport;
+	uint32_t th_seq;
+	uint32_t th_ack;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	uint8_t th_x2:4;
+	uint8_t th_off:4;
+#else
+	uint8_t th_off:4;
+	uint8_t th_x2:4;
+#endif
+	uint8_t th_flags;
+	uint16_t th_win;
+	uint16_t th_sum;
+	uint16_t th_urp;
+
+#ifdef _GNU_SOURCE
+	}; };
+#endif
+};
+#endif
+
+#ifdef _GNU_SOURCE
+#define TCPI_OPT_TIMESTAMPS	1
+#define TCPI_OPT_SACK		2
+#define TCPI_OPT_WSCALE		4
+#define TCPI_OPT_ECN		8
+
+#define TCP_CA_Open		0
+#define TCP_CA_Disorder		1
+#define TCP_CA_CWR		2
+#define TCP_CA_Recovery		3
+#define TCP_CA_Loss		4
+
+struct tcp_info {
+	uint8_t tcpi_state;
+	uint8_t tcpi_ca_state;
+	uint8_t tcpi_retransmits;
+	uint8_t tcpi_probes;
+	uint8_t tcpi_backoff;
+	uint8_t tcpi_options;
+	uint8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
+	uint8_t tcpi_delivery_rate_app_limited : 1;
+	uint32_t tcpi_rto;
+	uint32_t tcpi_ato;
+	uint32_t tcpi_snd_mss;
+	uint32_t tcpi_rcv_mss;
+	uint32_t tcpi_unacked;
+	uint32_t tcpi_sacked;
+	uint32_t tcpi_lost;
+	uint32_t tcpi_retrans;
+	uint32_t tcpi_fackets;
+	uint32_t tcpi_last_data_sent;
+	uint32_t tcpi_last_ack_sent;
+	uint32_t tcpi_last_data_recv;
+	uint32_t tcpi_last_ack_recv;
+	uint32_t tcpi_pmtu;
+	uint32_t tcpi_rcv_ssthresh;
+	uint32_t tcpi_rtt;
+	uint32_t tcpi_rttvar;
+	uint32_t tcpi_snd_ssthresh;
+	uint32_t tcpi_snd_cwnd;
+	uint32_t tcpi_advmss;
+	uint32_t tcpi_reordering;
+	uint32_t tcpi_rcv_rtt;
+	uint32_t tcpi_rcv_space;
+	uint32_t tcpi_total_retrans;
+	uint64_t tcpi_pacing_rate;
+	uint64_t tcpi_max_pacing_rate;
+	uint64_t tcpi_bytes_acked;
+	uint64_t tcpi_bytes_received;
+	uint32_t tcpi_segs_out;
+	uint32_t tcpi_segs_in;
+	uint32_t tcpi_notsent_bytes;
+	uint32_t tcpi_min_rtt;
+	uint32_t tcpi_data_segs_in;
+	uint32_t tcpi_data_segs_out;
+	uint64_t tcpi_delivery_rate;
+};
+
+#define TCP_MD5SIG_MAXKEYLEN    80
+
+struct tcp_md5sig {
+	struct sockaddr_storage tcpm_addr;
+	uint16_t __tcpm_pad1;
+	uint16_t tcpm_keylen;
+	uint32_t __tcpm_pad2;
+	uint8_t tcpm_key[TCP_MD5SIG_MAXKEYLEN];
+};
+
+struct tcp_repair_window {
+	uint32_t snd_wl1;
+	uint32_t snd_wnd;
+	uint32_t max_window;
+	uint32_t rcv_wnd;
+	uint32_t rcv_wup;
+};
+
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/netinet/udp.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/netinet/udp.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/netinet/udp.h	(revision 331)
@@ -0,0 +1,40 @@
+#ifndef _NETINET_UDP_H
+#define _NETINET_UDP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <stdint.h>
+
+#ifdef _GNU_SOURCE
+#define uh_sport source
+#define uh_dport dest
+#define uh_ulen len
+#define uh_sum check
+#endif
+
+struct udphdr {
+	uint16_t uh_sport;
+	uint16_t uh_dport;
+	uint16_t uh_ulen;
+	uint16_t uh_sum;
+};
+
+#define UDP_CORK	1
+#define UDP_ENCAP	100
+
+#define UDP_ENCAP_ESPINUDP_NON_IKE 1
+#define UDP_ENCAP_ESPINUDP	2
+#define UDP_ENCAP_L2TPINUDP	3
+#define UDP_ENCAP_GTP0		4
+#define UDP_ENCAP_GTP1U		5
+
+#define SOL_UDP            17
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/netpacket/packet.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/netpacket/packet.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/netpacket/packet.h	(revision 331)
@@ -0,0 +1,61 @@
+#ifndef _NETPACKET_PACKET_H
+#define _NETPACKET_PACKET_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct sockaddr_ll {
+	unsigned short sll_family, sll_protocol;
+	int sll_ifindex;
+	unsigned short sll_hatype;
+	unsigned char sll_pkttype, sll_halen;
+	unsigned char sll_addr[8];
+};
+
+struct packet_mreq {
+	int mr_ifindex;
+	unsigned short int mr_type,  mr_alen;
+	unsigned char mr_address[8];
+};
+
+#define PACKET_HOST		0
+#define PACKET_BROADCAST	1
+#define PACKET_MULTICAST	2
+#define PACKET_OTHERHOST	3
+#define PACKET_OUTGOING		4
+#define PACKET_LOOPBACK		5
+#define PACKET_FASTROUTE	6
+
+#define PACKET_ADD_MEMBERSHIP		1
+#define PACKET_DROP_MEMBERSHIP		2
+#define	PACKET_RECV_OUTPUT		3
+#define	PACKET_RX_RING			5
+#define	PACKET_STATISTICS		6
+#define PACKET_COPY_THRESH		7
+#define PACKET_AUXDATA			8
+#define PACKET_ORIGDEV			9
+#define PACKET_VERSION			10
+#define PACKET_HDRLEN			11
+#define PACKET_RESERVE			12
+#define PACKET_TX_RING			13
+#define PACKET_LOSS			14
+#define PACKET_VNET_HDR			15
+#define PACKET_TX_TIMESTAMP		16
+#define PACKET_TIMESTAMP		17
+#define PACKET_FANOUT			18
+#define PACKET_TX_HAS_OFF		19
+#define PACKET_QDISC_BYPASS		20
+#define PACKET_ROLLOVER_STATS		21
+#define PACKET_FANOUT_DATA		22
+
+#define PACKET_MR_MULTICAST	0
+#define PACKET_MR_PROMISC	1
+#define PACKET_MR_ALLMULTI	2
+#define PACKET_MR_UNICAST	3
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/nl_types.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/nl_types.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/nl_types.h	(revision 331)
@@ -0,0 +1,22 @@
+#ifndef _NL_TYPES_H
+#define _NL_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NL_SETD 1
+#define NL_CAT_LOCALE 1
+
+typedef int nl_item;
+typedef void *nl_catd;
+
+nl_catd catopen (const char *, int);
+char *catgets (nl_catd, int, int, const char *);
+int catclose (nl_catd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/paths.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/paths.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/paths.h	(revision 331)
@@ -0,0 +1,31 @@
+#ifndef _PATHS_H
+#define _PATHS_H
+
+#define	_PATH_DEFPATH "/usr/local/bin:/bin:/usr/bin"
+#define	_PATH_STDPATH "/bin:/usr/bin:/sbin:/usr/sbin"
+
+#define	_PATH_BSHELL	"/bin/sh"
+#define	_PATH_CONSOLE	"/dev/console"
+#define	_PATH_DEVNULL	"/dev/null"
+#define	_PATH_KLOG	"/proc/kmsg"
+#define	_PATH_LASTLOG	"/var/log/lastlog"
+#define	_PATH_MAILDIR	"/var/mail"
+#define	_PATH_MAN	"/usr/share/man"
+#define	_PATH_MNTTAB	"/etc/fstab"
+#define	_PATH_MOUNTED	"/etc/mtab"
+#define	_PATH_NOLOGIN	"/etc/nologin"
+#define	_PATH_SENDMAIL	"/usr/sbin/sendmail"
+#define	_PATH_SHADOW	"/etc/shadow"
+#define	_PATH_SHELLS	"/etc/shells"
+#define	_PATH_TTY	"/dev/tty"
+#define _PATH_UTMP	"/dev/null/utmp"
+#define	_PATH_VI	"/usr/bin/vi"
+#define _PATH_WTMP	"/dev/null/wtmp"
+
+#define	_PATH_DEV	"/dev/"
+#define	_PATH_TMP	"/tmp/"
+#define	_PATH_VARDB	"/var/lib/misc/"
+#define	_PATH_VARRUN	"/var/run/"
+#define	_PATH_VARTMP	"/var/tmp/"
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/poll.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/poll.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/poll.h	(revision 331)
@@ -0,0 +1,51 @@
+#ifndef	_POLL_H
+#define	_POLL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/poll.h>
+
+#define POLLIN     0x001
+#define POLLPRI    0x002
+#define POLLOUT    0x004
+#define POLLERR    0x008
+#define POLLHUP    0x010
+#define POLLNVAL   0x020
+#define POLLRDNORM 0x040
+#define POLLRDBAND 0x080
+#ifndef POLLWRNORM
+#define POLLWRNORM 0x100
+#define POLLWRBAND 0x200
+#endif
+#ifndef POLLMSG
+#define POLLMSG    0x400
+#define POLLRDHUP  0x2000
+#endif
+
+typedef unsigned long nfds_t;
+
+struct pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+int poll (struct pollfd *, nfds_t, int);
+
+#ifdef _GNU_SOURCE
+#define __NEED_time_t
+#define __NEED_struct_timespec
+#define __NEED_sigset_t
+#include <bits/alltypes.h>
+int ppoll(struct pollfd *, nfds_t, const struct timespec *, const sigset_t *);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/pthread.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/pthread.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/pthread.h	(revision 331)
@@ -0,0 +1,227 @@
+#ifndef _PTHREAD_H
+#define _PTHREAD_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_time_t
+#define __NEED_clockid_t
+#define __NEED_struct_timespec
+#define __NEED_sigset_t
+#define __NEED_pthread_t
+#define __NEED_pthread_attr_t
+#define __NEED_pthread_mutexattr_t
+#define __NEED_pthread_condattr_t
+#define __NEED_pthread_rwlockattr_t
+#define __NEED_pthread_barrierattr_t
+#define __NEED_pthread_mutex_t
+#define __NEED_pthread_cond_t
+#define __NEED_pthread_rwlock_t
+#define __NEED_pthread_barrier_t
+#define __NEED_pthread_spinlock_t
+#define __NEED_pthread_key_t
+#define __NEED_pthread_once_t
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+#include <sched.h>
+#include <time.h>
+
+#define PTHREAD_CREATE_JOINABLE 0
+#define PTHREAD_CREATE_DETACHED 1
+
+#define PTHREAD_MUTEX_NORMAL 0
+#define PTHREAD_MUTEX_DEFAULT 0
+#define PTHREAD_MUTEX_RECURSIVE 1
+#define PTHREAD_MUTEX_ERRORCHECK 2
+
+#define PTHREAD_MUTEX_STALLED 0
+#define PTHREAD_MUTEX_ROBUST 1
+
+#define PTHREAD_PRIO_NONE 0
+#define PTHREAD_PRIO_INHERIT 1
+#define PTHREAD_PRIO_PROTECT 2
+
+#define PTHREAD_INHERIT_SCHED 0
+#define PTHREAD_EXPLICIT_SCHED 1
+
+#define PTHREAD_SCOPE_SYSTEM 0
+#define PTHREAD_SCOPE_PROCESS 1
+
+#define PTHREAD_PROCESS_PRIVATE 0
+#define PTHREAD_PROCESS_SHARED 1
+
+
+#define PTHREAD_MUTEX_INITIALIZER {{{0}}}
+#define PTHREAD_RWLOCK_INITIALIZER {{{0}}}
+#define PTHREAD_COND_INITIALIZER {{{0}}}
+#define PTHREAD_ONCE_INIT 0
+
+
+#define PTHREAD_CANCEL_ENABLE 0
+#define PTHREAD_CANCEL_DISABLE 1
+#define PTHREAD_CANCEL_MASKED 2
+
+#define PTHREAD_CANCEL_DEFERRED 0
+#define PTHREAD_CANCEL_ASYNCHRONOUS 1
+
+#define PTHREAD_CANCELED ((void *)-1)
+
+
+#define PTHREAD_BARRIER_SERIAL_THREAD (-1)
+
+
+int pthread_create(pthread_t *__restrict, const pthread_attr_t *__restrict, void *(*)(void *), void *__restrict);
+int pthread_detach(pthread_t);
+_Noreturn void pthread_exit(void *);
+int pthread_join(pthread_t, void **);
+
+pthread_t pthread_self(void);
+
+int pthread_equal(pthread_t, pthread_t);
+#ifndef __cplusplus
+#define pthread_equal(x,y) ((x)==(y))
+#endif
+
+int pthread_setcancelstate(int, int *);
+int pthread_setcanceltype(int, int *);
+void pthread_testcancel(void);
+int pthread_cancel(pthread_t);
+
+int pthread_getschedparam(pthread_t, int *__restrict, struct sched_param *__restrict);
+int pthread_setschedparam(pthread_t, int, const struct sched_param *);
+int pthread_setschedprio(pthread_t, int);
+
+int pthread_once(pthread_once_t *, void (*)(void));
+
+int pthread_mutex_init(pthread_mutex_t *__restrict, const pthread_mutexattr_t *__restrict);
+int pthread_mutex_lock(pthread_mutex_t *);
+int pthread_mutex_unlock(pthread_mutex_t *);
+int pthread_mutex_trylock(pthread_mutex_t *);
+int pthread_mutex_timedlock(pthread_mutex_t *__restrict, const struct timespec *__restrict);
+int pthread_mutex_destroy(pthread_mutex_t *);
+int pthread_mutex_consistent(pthread_mutex_t *);
+
+int pthread_mutex_getprioceiling(const pthread_mutex_t *__restrict, int *__restrict);
+int pthread_mutex_setprioceiling(pthread_mutex_t *__restrict, int, int *__restrict);
+
+int pthread_cond_init(pthread_cond_t *__restrict, const pthread_condattr_t *__restrict);
+int pthread_cond_destroy(pthread_cond_t *);
+int pthread_cond_wait(pthread_cond_t *__restrict, pthread_mutex_t *__restrict);
+int pthread_cond_timedwait(pthread_cond_t *__restrict, pthread_mutex_t *__restrict, const struct timespec *__restrict);
+int pthread_cond_broadcast(pthread_cond_t *);
+int pthread_cond_signal(pthread_cond_t *);
+
+int pthread_rwlock_init(pthread_rwlock_t *__restrict, const pthread_rwlockattr_t *__restrict);
+int pthread_rwlock_destroy(pthread_rwlock_t *);
+int pthread_rwlock_rdlock(pthread_rwlock_t *);
+int pthread_rwlock_tryrdlock(pthread_rwlock_t *);
+int pthread_rwlock_timedrdlock(pthread_rwlock_t *__restrict, const struct timespec *__restrict);
+int pthread_rwlock_wrlock(pthread_rwlock_t *);
+int pthread_rwlock_trywrlock(pthread_rwlock_t *);
+int pthread_rwlock_timedwrlock(pthread_rwlock_t *__restrict, const struct timespec *__restrict);
+int pthread_rwlock_unlock(pthread_rwlock_t *);
+
+int pthread_spin_init(pthread_spinlock_t *, int);
+int pthread_spin_destroy(pthread_spinlock_t *);
+int pthread_spin_lock(pthread_spinlock_t *);
+int pthread_spin_trylock(pthread_spinlock_t *);
+int pthread_spin_unlock(pthread_spinlock_t *);
+
+int pthread_barrier_init(pthread_barrier_t *__restrict, const pthread_barrierattr_t *__restrict, unsigned);
+int pthread_barrier_destroy(pthread_barrier_t *);
+int pthread_barrier_wait(pthread_barrier_t *);
+
+int pthread_key_create(pthread_key_t *, void (*)(void *));
+int pthread_key_delete(pthread_key_t);
+void *pthread_getspecific(pthread_key_t);
+int pthread_setspecific(pthread_key_t, const void *);
+
+int pthread_attr_init(pthread_attr_t *);
+int pthread_attr_destroy(pthread_attr_t *);
+
+int pthread_attr_getguardsize(const pthread_attr_t *__restrict, size_t *__restrict);
+int pthread_attr_setguardsize(pthread_attr_t *, size_t);
+int pthread_attr_getstacksize(const pthread_attr_t *__restrict, size_t *__restrict);
+int pthread_attr_setstacksize(pthread_attr_t *, size_t);
+int pthread_attr_getdetachstate(const pthread_attr_t *, int *);
+int pthread_attr_setdetachstate(pthread_attr_t *, int);
+int pthread_attr_getstack(const pthread_attr_t *__restrict, void **__restrict, size_t *__restrict);
+int pthread_attr_setstack(pthread_attr_t *, void *, size_t);
+int pthread_attr_getscope(const pthread_attr_t *__restrict, int *__restrict);
+int pthread_attr_setscope(pthread_attr_t *, int);
+int pthread_attr_getschedpolicy(const pthread_attr_t *__restrict, int *__restrict);
+int pthread_attr_setschedpolicy(pthread_attr_t *, int);
+int pthread_attr_getschedparam(const pthread_attr_t *__restrict, struct sched_param *__restrict);
+int pthread_attr_setschedparam(pthread_attr_t *__restrict, const struct sched_param *__restrict);
+int pthread_attr_getinheritsched(const pthread_attr_t *__restrict, int *__restrict);
+int pthread_attr_setinheritsched(pthread_attr_t *, int);
+
+int pthread_mutexattr_destroy(pthread_mutexattr_t *);
+int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *__restrict, int *__restrict);
+int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *__restrict, int *__restrict);
+int pthread_mutexattr_getpshared(const pthread_mutexattr_t *__restrict, int *__restrict);
+int pthread_mutexattr_getrobust(const pthread_mutexattr_t *__restrict, int *__restrict);
+int pthread_mutexattr_gettype(const pthread_mutexattr_t *__restrict, int *__restrict);
+int pthread_mutexattr_init(pthread_mutexattr_t *);
+int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *, int);
+int pthread_mutexattr_setprotocol(pthread_mutexattr_t *, int);
+int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int);
+int pthread_mutexattr_setrobust(pthread_mutexattr_t *, int);
+int pthread_mutexattr_settype(pthread_mutexattr_t *, int);
+
+int pthread_condattr_init(pthread_condattr_t *);
+int pthread_condattr_destroy(pthread_condattr_t *);
+int pthread_condattr_setclock(pthread_condattr_t *, clockid_t);
+int pthread_condattr_setpshared(pthread_condattr_t *, int);
+int pthread_condattr_getclock(const pthread_condattr_t *__restrict, clockid_t *__restrict);
+int pthread_condattr_getpshared(const pthread_condattr_t *__restrict, int *__restrict);
+
+int pthread_rwlockattr_init(pthread_rwlockattr_t *);
+int pthread_rwlockattr_destroy(pthread_rwlockattr_t *);
+int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int);
+int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *__restrict, int *__restrict);
+
+int pthread_barrierattr_destroy(pthread_barrierattr_t *);
+int pthread_barrierattr_getpshared(const pthread_barrierattr_t *__restrict, int *__restrict);
+int pthread_barrierattr_init(pthread_barrierattr_t *);
+int pthread_barrierattr_setpshared(pthread_barrierattr_t *, int);
+
+int pthread_atfork(void (*)(void), void (*)(void), void (*)(void));
+
+int pthread_getconcurrency(void);
+int pthread_setconcurrency(int);
+
+int pthread_getcpuclockid(pthread_t, clockid_t *);
+
+struct __ptcb {
+	void (*__f)(void *);
+	void *__x;
+	struct __ptcb *__next;
+};
+
+void _pthread_cleanup_push(struct __ptcb *, void (*)(void *), void *);
+void _pthread_cleanup_pop(struct __ptcb *, int);
+
+#define pthread_cleanup_push(f, x) do { struct __ptcb __cb; _pthread_cleanup_push(&__cb, f, x);
+#define pthread_cleanup_pop(r) _pthread_cleanup_pop(&__cb, (r)); } while(0)
+
+#ifdef _GNU_SOURCE
+struct cpu_set_t;
+int pthread_getaffinity_np(pthread_t, size_t, struct cpu_set_t *);
+int pthread_setaffinity_np(pthread_t, size_t, const struct cpu_set_t *);
+int pthread_getattr_np(pthread_t, pthread_attr_t *);
+int pthread_setname_np(pthread_t, const char *);
+int pthread_getattr_default_np(pthread_attr_t *);
+int pthread_setattr_default_np(const pthread_attr_t *);
+int pthread_tryjoin_np(pthread_t, void **);
+int pthread_timedjoin_np(pthread_t, void **, const struct timespec *);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/pty.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/pty.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/pty.h	(revision 331)
@@ -0,0 +1,18 @@
+#ifndef	_PTY_H
+#define	_PTY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <termios.h>
+#include <sys/ioctl.h>
+
+int openpty(int *, int *, char *, const struct termios *, const struct winsize *);
+int forkpty(int *, char *, const struct termios *, const struct winsize *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/pwd.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/pwd.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/pwd.h	(revision 331)
@@ -0,0 +1,50 @@
+#ifndef _PWD_H
+#define _PWD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_uid_t
+#define __NEED_gid_t
+
+#ifdef _GNU_SOURCE
+#define __NEED_FILE
+#endif
+
+#include <bits/alltypes.h>
+
+struct passwd {
+	char *pw_name;
+	char *pw_passwd;
+	uid_t pw_uid;
+	gid_t pw_gid;
+	char *pw_gecos;
+	char *pw_dir;
+	char *pw_shell;
+};
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+void setpwent (void);
+void endpwent (void);
+struct passwd *getpwent (void);
+#endif
+
+struct passwd *getpwuid (uid_t);
+struct passwd *getpwnam (const char *);
+int getpwuid_r (uid_t, struct passwd *, char *, size_t, struct passwd **);
+int getpwnam_r (const char *, struct passwd *, char *, size_t, struct passwd **);
+
+#ifdef _GNU_SOURCE
+struct passwd *fgetpwent(FILE *);
+int putpwent(const struct passwd *, FILE *);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/regex.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/regex.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/regex.h	(revision 331)
@@ -0,0 +1,62 @@
+#ifndef _REGEX_H
+#define _REGEX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_regoff_t
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+typedef struct re_pattern_buffer {
+	size_t re_nsub;
+	void *__opaque, *__padding[4];
+	size_t __nsub2;
+	char __padding2;
+} regex_t;
+
+typedef struct {
+	regoff_t rm_so;
+	regoff_t rm_eo;
+} regmatch_t;
+
+#define REG_EXTENDED    1
+#define REG_ICASE       2
+#define REG_NEWLINE     4
+#define REG_NOSUB       8
+
+#define REG_NOTBOL      1
+#define REG_NOTEOL      2
+
+#define REG_OK          0
+#define REG_NOMATCH     1
+#define REG_BADPAT      2
+#define REG_ECOLLATE    3
+#define REG_ECTYPE      4
+#define REG_EESCAPE     5
+#define REG_ESUBREG     6
+#define REG_EBRACK      7
+#define REG_EPAREN      8
+#define REG_EBRACE      9
+#define REG_BADBR       10
+#define REG_ERANGE      11
+#define REG_ESPACE      12
+#define REG_BADRPT      13
+
+#define REG_ENOSYS      -1
+
+int regcomp(regex_t *__restrict, const char *__restrict, int);
+int regexec(const regex_t *__restrict, const char *__restrict, size_t, regmatch_t *__restrict, int);
+void regfree(regex_t *);
+
+size_t regerror(int, const regex_t *__restrict, char *__restrict, size_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/resolv.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/resolv.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/resolv.h	(revision 331)
@@ -0,0 +1,142 @@
+#ifndef _RESOLV_H
+#define _RESOLV_H
+
+#include <stdint.h>
+#include <arpa/nameser.h>
+#include <netinet/in.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAXNS			3
+#define MAXDFLSRCH		3
+#define MAXDNSRCH		6
+#define LOCALDOMAINPARTS	2
+
+#define RES_TIMEOUT		5
+#define MAXRESOLVSORT		10
+#define RES_MAXNDOTS		15
+#define RES_MAXRETRANS		30
+#define RES_MAXRETRY		5
+#define RES_DFLRETRY		2
+#define RES_MAXTIME		65535
+
+/* unused; purely for broken apps */
+typedef struct __res_state {
+	int retrans;
+	int retry;
+	unsigned long options;
+	int nscount;
+	struct sockaddr_in nsaddr_list[MAXNS];
+# define nsaddr	nsaddr_list[0]
+	unsigned short id;
+	char *dnsrch[MAXDNSRCH+1];
+	char defdname[256];
+	unsigned long pfcode;
+	unsigned ndots:4;
+	unsigned nsort:4;
+	unsigned ipv6_unavail:1;
+	unsigned unused:23;
+	struct {
+		struct in_addr addr;
+		uint32_t mask;
+	} sort_list[MAXRESOLVSORT];
+	void *qhook;
+	void *rhook;
+	int res_h_errno;
+	int _vcsock;
+	unsigned _flags;
+	union {
+		char pad[52];
+		struct {
+			uint16_t		nscount;
+			uint16_t		nsmap[MAXNS];
+			int			nssocks[MAXNS];
+			uint16_t		nscount6;
+			uint16_t		nsinit;
+			struct sockaddr_in6	*nsaddrs[MAXNS];
+			unsigned int		_initstamp[2];
+		} _ext;
+	} _u;
+} *res_state;
+
+#define	__RES	19960801
+
+#ifndef _PATH_RESCONF
+#define _PATH_RESCONF        "/etc/resolv.conf"
+#endif
+
+struct res_sym {
+	int number;
+	char *name;
+	char *humanname;
+};
+
+#define	RES_F_VC	0x00000001
+#define	RES_F_CONN	0x00000002
+#define RES_F_EDNS0ERR	0x00000004
+
+#define	RES_EXHAUSTIVE	0x00000001
+
+#define RES_INIT	0x00000001
+#define RES_DEBUG	0x00000002
+#define RES_AAONLY	0x00000004
+#define RES_USEVC	0x00000008
+#define RES_PRIMARY	0x00000010
+#define RES_IGNTC	0x00000020
+#define RES_RECURSE	0x00000040
+#define RES_DEFNAMES	0x00000080
+#define RES_STAYOPEN	0x00000100
+#define RES_DNSRCH	0x00000200
+#define	RES_INSECURE1	0x00000400
+#define	RES_INSECURE2	0x00000800
+#define	RES_NOALIASES	0x00001000
+#define	RES_USE_INET6	0x00002000
+#define RES_ROTATE	0x00004000
+#define	RES_NOCHECKNAME	0x00008000
+#define	RES_KEEPTSIG	0x00010000
+#define	RES_BLAST	0x00020000
+#define RES_USEBSTRING	0x00040000
+#define RES_NOIP6DOTINT	0x00080000
+#define RES_USE_EDNS0	0x00100000
+#define RES_SNGLKUP	0x00200000
+#define RES_SNGLKUPREOP	0x00400000
+#define RES_USE_DNSSEC	0x00800000
+
+#define RES_DEFAULT	(RES_RECURSE|RES_DEFNAMES|RES_DNSRCH|RES_NOIP6DOTINT)
+
+#define RES_PRF_STATS	0x00000001
+#define RES_PRF_UPDATE	0x00000002
+#define RES_PRF_CLASS   0x00000004
+#define RES_PRF_CMD	0x00000008
+#define RES_PRF_QUES	0x00000010
+#define RES_PRF_ANS	0x00000020
+#define RES_PRF_AUTH	0x00000040
+#define RES_PRF_ADD	0x00000080
+#define RES_PRF_HEAD1	0x00000100
+#define RES_PRF_HEAD2	0x00000200
+#define RES_PRF_TTLID	0x00000400
+#define RES_PRF_HEADX	0x00000800
+#define RES_PRF_QUERY	0x00001000
+#define RES_PRF_REPLY	0x00002000
+#define RES_PRF_INIT	0x00004000
+
+struct __res_state *__res_state(void);
+#define _res (*__res_state())
+
+int res_init(void);
+int res_query(const char *, int, int, unsigned char *, int);
+int res_querydomain(const char *, const char *, int, int, unsigned char *, int);
+int res_search(const char *, int, int, unsigned char *, int);
+int res_mkquery(int, const char *, int, int, const unsigned char *, int, const unsigned char*, unsigned char *, int);
+int res_send(const unsigned char *, int, unsigned char *, int);
+int dn_comp(const char *, unsigned char *, int, unsigned char **, unsigned char **);
+int dn_expand(const unsigned char *, const unsigned char *, const unsigned char *, char *, int);
+int dn_skipname(const unsigned char *, const unsigned char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sched.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sched.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sched.h	(revision 331)
@@ -0,0 +1,136 @@
+#ifndef _SCHED_H
+#define _SCHED_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_struct_timespec
+#define __NEED_pid_t
+#define __NEED_time_t
+
+#ifdef _GNU_SOURCE
+#define __NEED_size_t
+#endif
+
+#include <bits/alltypes.h>
+
+struct sched_param {
+	int sched_priority;
+	int sched_ss_low_priority;
+	struct timespec sched_ss_repl_period;
+	struct timespec sched_ss_init_budget;
+	int sched_ss_max_repl;
+};
+
+int    sched_get_priority_max(int);
+int    sched_get_priority_min(int);
+int    sched_getparam(pid_t, struct sched_param *);
+int    sched_getscheduler(pid_t);
+int    sched_rr_get_interval(pid_t, struct timespec *);
+int    sched_setparam(pid_t, const struct sched_param *);
+int    sched_setscheduler(pid_t, int, const struct sched_param *);
+int     sched_yield(void);
+
+#define SCHED_OTHER 0
+#define SCHED_FIFO 1
+#define SCHED_RR 2
+#define SCHED_BATCH 3
+#define SCHED_IDLE 5
+#define SCHED_DEADLINE 6
+#define SCHED_RESET_ON_FORK 0x40000000
+
+#ifdef _GNU_SOURCE
+#define CSIGNAL		0x000000ff
+#define CLONE_VM	0x00000100
+#define CLONE_FS	0x00000200
+#define CLONE_FILES	0x00000400
+#define CLONE_SIGHAND	0x00000800
+#define CLONE_PTRACE	0x00002000
+#define CLONE_VFORK	0x00004000
+#define CLONE_PARENT	0x00008000
+#define CLONE_THREAD	0x00010000
+#define CLONE_NEWNS	0x00020000
+#define CLONE_SYSVSEM	0x00040000
+#define CLONE_SETTLS	0x00080000
+#define CLONE_PARENT_SETTID	0x00100000
+#define CLONE_CHILD_CLEARTID	0x00200000
+#define CLONE_DETACHED	0x00400000
+#define CLONE_UNTRACED	0x00800000
+#define CLONE_CHILD_SETTID	0x01000000
+#define CLONE_NEWCGROUP	0x02000000
+#define CLONE_NEWUTS	0x04000000
+#define CLONE_NEWIPC	0x08000000
+#define CLONE_NEWUSER	0x10000000
+#define CLONE_NEWPID	0x20000000
+#define CLONE_NEWNET	0x40000000
+#define CLONE_IO	0x80000000
+int clone (int (*)(void *), void *, int, void *, ...);
+int unshare(int);
+int setns(int, int);
+
+void *memcpy(void *__restrict, const void *__restrict, size_t);
+int memcmp(const void *, const void *, size_t);
+void *memset (void *, int, size_t);
+void *calloc(size_t, size_t);
+void free(void *);
+
+typedef struct cpu_set_t { unsigned long __bits[128/sizeof(long)]; } cpu_set_t;
+int __sched_cpucount(size_t, const cpu_set_t *);
+int sched_getcpu(void);
+int sched_getaffinity(pid_t, size_t, cpu_set_t *);
+int sched_setaffinity(pid_t, size_t, const cpu_set_t *);
+
+#define __CPU_op_S(i, size, set, op) ( (i)/8U >= (size) ? 0 : \
+	(((unsigned long *)(set))[(i)/8/sizeof(long)] op (1UL<<((i)%(8*sizeof(long))))) )
+
+#define CPU_SET_S(i, size, set) __CPU_op_S(i, size, set, |=)
+#define CPU_CLR_S(i, size, set) __CPU_op_S(i, size, set, &=~)
+#define CPU_ISSET_S(i, size, set) __CPU_op_S(i, size, set, &)
+
+#define __CPU_op_func_S(func, op) \
+static __inline void __CPU_##func##_S(size_t __size, cpu_set_t *__dest, \
+	const cpu_set_t *__src1, const cpu_set_t *__src2) \
+{ \
+	size_t __i; \
+	for (__i=0; __i<__size/sizeof(long); __i++) \
+		((unsigned long *)__dest)[__i] = ((unsigned long *)__src1)[__i] \
+			op ((unsigned long *)__src2)[__i] ; \
+}
+
+__CPU_op_func_S(AND, &)
+__CPU_op_func_S(OR, |)
+__CPU_op_func_S(XOR, ^)
+
+#define CPU_AND_S(a,b,c,d) __CPU_AND_S(a,b,c,d)
+#define CPU_OR_S(a,b,c,d) __CPU_OR_S(a,b,c,d)
+#define CPU_XOR_S(a,b,c,d) __CPU_XOR_S(a,b,c,d)
+
+#define CPU_COUNT_S(size,set) __sched_cpucount(size,set)
+#define CPU_ZERO_S(size,set) memset(set,0,size)
+#define CPU_EQUAL_S(size,set1,set2) (!memcmp(set1,set2,size))
+
+#define CPU_ALLOC_SIZE(n) (sizeof(long) * ( (n)/(8*sizeof(long)) \
+	+ ((n)%(8*sizeof(long)) + 8*sizeof(long)-1)/(8*sizeof(long)) ) )
+#define CPU_ALLOC(n) ((cpu_set_t *)calloc(1,CPU_ALLOC_SIZE(n)))
+#define CPU_FREE(set) free(set)
+
+#define CPU_SETSIZE 128
+
+#define CPU_SET(i, set) CPU_SET_S(i,sizeof(cpu_set_t),set)
+#define CPU_CLR(i, set) CPU_CLR_S(i,sizeof(cpu_set_t),set)
+#define CPU_ISSET(i, set) CPU_ISSET_S(i,sizeof(cpu_set_t),set)
+#define CPU_AND(d,s1,s2) CPU_AND_S(sizeof(cpu_set_t),d,s1,s2)
+#define CPU_OR(d,s1,s2) CPU_OR_S(sizeof(cpu_set_t),d,s1,s2)
+#define CPU_XOR(d,s1,s2) CPU_XOR_S(sizeof(cpu_set_t),d,s1,s2)
+#define CPU_COUNT(set) CPU_COUNT_S(sizeof(cpu_set_t),set)
+#define CPU_ZERO(set) CPU_ZERO_S(sizeof(cpu_set_t),set)
+#define CPU_EQUAL(s1,s2) CPU_EQUAL_S(sizeof(cpu_set_t),s1,s2)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/scsi/scsi.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/scsi/scsi.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/scsi/scsi.h	(revision 331)
@@ -0,0 +1,150 @@
+#ifndef _SCSI_SCSI_H
+#define _SCSI_SCSI_H
+
+#define TEST_UNIT_READY 0x00
+#define REZERO_UNIT 0x01
+#define REQUEST_SENSE 0x03
+#define FORMAT_UNIT 0x04
+#define READ_BLOCK_LIMITS 0x05
+#define REASSIGN_BLOCKS 0x07
+#define READ_6 0x08
+#define WRITE_6 0x0a
+#define SEEK_6 0x0b
+#define READ_REVERSE 0x0f
+#define WRITE_FILEMARKS 0x10
+#define SPACE 0x11
+#define INQUIRY 0x12
+#define RECOVER_BUFFERED_DATA 0x14
+#define MODE_SELECT 0x15
+#define RESERVE 0x16
+#define RELEASE 0x17
+#define COPY 0x18
+#define ERASE 0x19
+#define MODE_SENSE 0x1a
+#define START_STOP 0x1b
+#define RECEIVE_DIAGNOSTIC 0x1c
+#define SEND_DIAGNOSTIC 0x1d
+#define ALLOW_MEDIUM_REMOVAL 0x1e
+#define SET_WINDOW 0x24
+#define READ_CAPACITY 0x25
+#define READ_10 0x28
+#define WRITE_10 0x2a
+#define SEEK_10 0x2b
+#define WRITE_VERIFY 0x2e
+#define VERIFY 0x2f
+#define SEARCH_HIGH 0x30
+#define SEARCH_EQUAL 0x31
+#define SEARCH_LOW 0x32
+#define SET_LIMITS 0x33
+#define PRE_FETCH 0x34
+#define READ_POSITION 0x34
+#define SYNCHRONIZE_CACHE 0x35
+#define LOCK_UNLOCK_CACHE 0x36
+#define READ_DEFECT_DATA 0x37
+#define MEDIUM_SCAN 0x38
+#define COMPARE 0x39
+#define COPY_VERIFY 0x3a
+#define WRITE_BUFFER 0x3b
+#define READ_BUFFER 0x3c
+#define UPDATE_BLOCK 0x3d
+#define READ_LONG 0x3e
+#define WRITE_LONG 0x3f
+#define CHANGE_DEFINITION 0x40
+#define WRITE_SAME 0x41
+#define READ_TOC 0x43
+#define LOG_SELECT 0x4c
+#define LOG_SENSE 0x4d
+#define MODE_SELECT_10 0x55
+#define RESERVE_10 0x56
+#define RELEASE_10 0x57
+#define MODE_SENSE_10 0x5a
+#define PERSISTENT_RESERVE_IN 0x5e
+#define PERSISTENT_RESERVE_OUT 0x5f
+#define MOVE_MEDIUM 0xa5
+#define READ_12 0xa8
+#define WRITE_12 0xaa
+#define WRITE_VERIFY_12 0xae
+#define SEARCH_HIGH_12 0xb0
+#define SEARCH_EQUAL_12 0xb1
+#define SEARCH_LOW_12 0xb2
+#define READ_ELEMENT_STATUS 0xb8
+#define SEND_VOLUME_TAG 0xb6
+#define WRITE_LONG_2 0xea
+#define GOOD 0x00
+#define CHECK_CONDITION 0x01
+#define CONDITION_GOOD 0x02
+#define BUSY 0x04
+#define INTERMEDIATE_GOOD 0x08
+#define INTERMEDIATE_C_GOOD 0x0a
+#define RESERVATION_CONFLICT 0x0c
+#define COMMAND_TERMINATED 0x11
+#define QUEUE_FULL 0x14
+#define STATUS_MASK 0x3e
+#define NO_SENSE 0x00
+#define RECOVERED_ERROR 0x01
+#define NOT_READY 0x02
+#define MEDIUM_ERROR 0x03
+#define HARDWARE_ERROR 0x04
+#define ILLEGAL_REQUEST 0x05
+#define UNIT_ATTENTION 0x06
+#define DATA_PROTECT 0x07
+#define BLANK_CHECK 0x08
+#define COPY_ABORTED 0x0a
+#define ABORTED_COMMAND 0x0b
+#define VOLUME_OVERFLOW 0x0d
+#define MISCOMPARE 0x0e
+#define TYPE_DISK 0x00
+#define TYPE_TAPE 0x01
+#define TYPE_PROCESSOR 0x03
+#define TYPE_WORM 0x04
+#define TYPE_ROM 0x05
+#define TYPE_SCANNER 0x06
+#define TYPE_MOD 0x07
+#define TYPE_MEDIUM_CHANGER 0x08
+#define TYPE_ENCLOSURE 0x0d
+#define TYPE_NO_LUN 0x7f
+#define COMMAND_COMPLETE 0x00
+#define EXTENDED_MESSAGE 0x01
+#define EXTENDED_MODIFY_DATA_POINTER 0x00
+#define EXTENDED_SDTR 0x01
+#define EXTENDED_EXTENDED_IDENTIFY 0x02
+#define EXTENDED_WDTR 0x03
+#define SAVE_POINTERS 0x02
+#define RESTORE_POINTERS 0x03
+#define DISCONNECT 0x04
+#define INITIATOR_ERROR 0x05
+#define ABORT 0x06
+#define MESSAGE_REJECT 0x07
+#define NOP 0x08
+#define MSG_PARITY_ERROR 0x09
+#define LINKED_CMD_COMPLETE 0x0a
+#define LINKED_FLG_CMD_COMPLETE 0x0b
+#define BUS_DEVICE_RESET 0x0c
+#define INITIATE_RECOVERY 0x0f
+#define RELEASE_RECOVERY 0x10
+#define SIMPLE_QUEUE_TAG 0x20
+#define HEAD_OF_QUEUE_TAG 0x21
+#define ORDERED_QUEUE_TAG 0x22
+#define SCSI_IOCTL_GET_IDLUN 0x5382
+#define SCSI_IOCTL_TAGGED_ENABLE 0x5383
+#define SCSI_IOCTL_TAGGED_DISABLE 0x5384
+#define SCSI_IOCTL_PROBE_HOST 0x5385
+#define SCSI_IOCTL_GET_BUS_NUMBER 0x5386
+
+struct ccs_modesel_head {
+	unsigned char _r1;
+	unsigned char medium;
+	unsigned char _r2;
+	unsigned char block_desc_length;
+	unsigned char density;
+	unsigned char number_blocks_hi;
+	unsigned char number_blocks_med;
+	unsigned char number_blocks_lo;
+	unsigned char _r3;
+	unsigned char block_length_hi;
+	unsigned char block_length_med;
+	unsigned char block_length_lo;
+};
+
+#endif
+
Index: EcnlProtoTool/trunk/musl-1.1.18/include/scsi/scsi_ioctl.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/scsi/scsi_ioctl.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/scsi/scsi_ioctl.h	(revision 331)
@@ -0,0 +1,11 @@
+#ifndef _SCSI_IOCTL_H
+#define _SCSI_IOCTL_H
+#define SCSI_IOCTL_SEND_COMMAND 1
+#define SCSI_IOCTL_TEST_UNIT_READY 2
+#define SCSI_IOCTL_BENCHMARK_COMMAND 3
+#define SCSI_IOCTL_SYNC 4
+#define SCSI_IOCTL_START_UNIT 5
+#define SCSI_IOCTL_STOP_UNIT 6
+#define SCSI_IOCTL_DOORLOCK 0x5380
+#define SCSI_IOCTL_DOORUNLOCK 0x5381
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/scsi/sg.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/scsi/sg.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/scsi/sg.h	(revision 331)
@@ -0,0 +1,129 @@
+#ifndef _SCSI_SG_H
+#define _SCSI_SG_H
+
+#define SG_DXFER_NONE -1
+#define SG_DXFER_TO_DEV -2
+#define SG_DXFER_FROM_DEV -3
+#define SG_DXFER_TO_FROM_DEV -4
+#define SG_FLAG_DIRECT_IO 1
+#define SG_FLAG_LUN_INHIBIT 2
+#define SG_FLAG_NO_DXFER 0x10000
+#define SG_INFO_OK_MASK 0x1
+#define SG_INFO_OK 0x0
+#define SG_INFO_CHECK 0x1
+#define SG_INFO_DIRECT_IO_MASK 0x6
+#define SG_INFO_INDIRECT_IO 0x0
+#define SG_INFO_DIRECT_IO 0x2
+#define SG_INFO_MIXED_IO 0x4
+#define SG_EMULATED_HOST 0x2203
+#define SG_SET_TRANSFORM 0x2204
+#define SG_GET_TRANSFORM 0x2205
+#define SG_SET_RESERVED_SIZE 0x2275
+#define SG_GET_RESERVED_SIZE 0x2272
+#define SG_GET_SCSI_ID 0x2276
+#define SG_SET_FORCE_LOW_DMA 0x2279
+#define SG_GET_LOW_DMA 0x227a
+#define SG_SET_FORCE_PACK_ID 0x227b
+#define SG_GET_PACK_ID 0x227c
+#define SG_GET_NUM_WAITING 0x227d
+#define SG_GET_SG_TABLESIZE 0x227F
+#define SG_GET_VERSION_NUM 0x2282
+#define SG_SCSI_RESET 0x2284
+#define SG_SCSI_RESET_NOTHING 0
+#define SG_SCSI_RESET_DEVICE 1
+#define SG_SCSI_RESET_BUS 2
+#define SG_SCSI_RESET_HOST 3
+#define SG_IO 0x2285
+#define SG_GET_REQUEST_TABLE 0x2286
+#define SG_SET_KEEP_ORPHAN 0x2287
+#define SG_GET_KEEP_ORPHAN 0x2288
+#define SG_SCATTER_SZ (8 * 4096)
+#define SG_DEFAULT_RETRIES 1
+#define SG_DEF_FORCE_LOW_DMA 0
+#define SG_DEF_FORCE_PACK_ID 0
+#define SG_DEF_KEEP_ORPHAN 0
+#define SG_DEF_RESERVED_SIZE SG_SCATTER_SZ
+#define SG_MAX_QUEUE 16
+#define SG_BIG_BUFF SG_DEF_RESERVED_SIZE
+#define SG_MAX_SENSE 16
+#define SG_SET_TIMEOUT 0x2201
+#define SG_GET_TIMEOUT 0x2202
+#define SG_GET_COMMAND_Q 0x2270
+#define SG_SET_COMMAND_Q 0x2271
+#define SG_SET_DEBUG 0x227e
+#define SG_NEXT_CMD_LEN 0x2283
+#define SG_DEFAULT_TIMEOUT (60*100) /* 60*HZ */
+#define SG_DEF_COMMAND_Q 0
+#define SG_DEF_UNDERRUN_FLAG 0
+
+typedef struct sg_iovec {
+	void *iov_base;
+	unsigned long iov_len;
+} sg_iovec_t;
+
+typedef struct sg_io_hdr { 
+	int interface_id; 
+	int dxfer_direction; 
+	unsigned char cmd_len;
+	unsigned char mx_sb_len;
+	unsigned short iovec_count;
+	unsigned dxfer_len;
+	void *dxferp;
+	unsigned char *cmdp;
+	unsigned char *sbp;
+	unsigned timeout;
+	unsigned flags;
+	int pack_id;
+	void *usr_ptr;
+	unsigned char status;
+	unsigned char masked_status;
+	unsigned char msg_status;
+	unsigned char sb_len_wr;
+	unsigned short host_status;
+	unsigned short driver_status;
+	int resid; 
+	unsigned int duration;
+	unsigned int info;
+} sg_io_hdr_t;
+
+struct sg_scsi_id {
+	int host_no;
+	int channel;
+	int scsi_id;
+	int lun;
+	int scsi_type;
+	short h_cmd_per_lun;
+	short d_queue_depth;
+	int unused[2];
+};
+
+typedef struct sg_req_info {
+	char req_state;
+	char orphan;
+	char sg_io_owned;
+	char problem;
+	int pack_id;
+	void *usr_ptr;
+	unsigned duration; 
+	int unused; 
+} sg_req_info_t;
+
+typedef struct sg_io_hdr Sg_io_hdr;
+typedef struct sg_io_vec Sg_io_vec;
+typedef struct sg_scsi_id Sg_scsi_id;
+typedef struct sg_req_info Sg_req_info;
+
+struct sg_header {
+	int pack_len;
+	int reply_len;
+	int pack_id;
+	int result;
+	unsigned twelve_byte:1;
+	unsigned target_status:5;
+	unsigned host_status:8;
+	unsigned driver_status:8;
+	unsigned other_flags:10;
+	unsigned char sense_buffer[SG_MAX_SENSE];
+};
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/search.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/search.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/search.h	(revision 331)
@@ -0,0 +1,63 @@
+#ifndef _SEARCH_H
+#define _SEARCH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#include <bits/alltypes.h>
+
+typedef enum { FIND, ENTER } ACTION;
+typedef enum { preorder, postorder, endorder, leaf } VISIT;
+
+typedef struct entry {
+	char *key;
+	void *data;
+} ENTRY;
+
+int hcreate(size_t);
+void hdestroy(void);
+ENTRY *hsearch(ENTRY, ACTION);
+
+#ifdef _GNU_SOURCE
+struct hsearch_data {
+	struct __tab *__tab;
+	unsigned int __unused1;
+	unsigned int __unused2;
+};
+
+int hcreate_r(size_t, struct hsearch_data *);
+void hdestroy_r(struct hsearch_data *);
+int hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *);
+#endif
+
+void insque(void *, void *);
+void remque(void *);
+
+void *lsearch(const void *, void *, size_t *, size_t,
+	int (*)(const void *, const void *));
+void *lfind(const void *, const void *, size_t *, size_t,
+	int (*)(const void *, const void *));
+
+void *tdelete(const void *__restrict, void **__restrict, int(*)(const void *, const void *));
+void *tfind(const void *, void *const *, int(*)(const void *, const void *));
+void *tsearch(const void *, void **, int (*)(const void *, const void *));
+void twalk(const void *, void (*)(const void *, VISIT, int));
+
+#ifdef _GNU_SOURCE
+struct qelem {
+	struct qelem *q_forw, *q_back;
+	char q_data[1];
+};
+
+void tdestroy(void *, void (*)(void *));
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/semaphore.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/semaphore.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/semaphore.h	(revision 331)
@@ -0,0 +1,35 @@
+#ifndef _SEMAPHORE_H
+#define _SEMAPHORE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_time_t
+#define __NEED_struct_timespec
+#include <bits/alltypes.h>
+
+#include <fcntl.h>
+
+#define SEM_FAILED ((sem_t *)0)
+
+typedef struct {
+	volatile int __val[4*sizeof(long)/sizeof(int)];
+} sem_t;
+
+int    sem_close(sem_t *);
+int    sem_destroy(sem_t *);
+int    sem_getvalue(sem_t *__restrict, int *__restrict);
+int    sem_init(sem_t *, int, unsigned);
+sem_t *sem_open(const char *, int, ...);
+int    sem_post(sem_t *);
+int    sem_timedwait(sem_t *__restrict, const struct timespec *__restrict);
+int    sem_trywait(sem_t *);
+int    sem_unlink(const char *);
+int    sem_wait(sem_t *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/setjmp.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/setjmp.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/setjmp.h	(revision 331)
@@ -0,0 +1,41 @@
+#ifndef	_SETJMP_H
+#define	_SETJMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/setjmp.h>
+
+typedef struct __jmp_buf_tag {
+	__jmp_buf __jb;
+	unsigned long __fl;
+	unsigned long __ss[128/sizeof(long)];
+} jmp_buf[1];
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+typedef jmp_buf sigjmp_buf;
+int sigsetjmp (sigjmp_buf, int);
+_Noreturn void siglongjmp (sigjmp_buf, int);
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+int _setjmp (jmp_buf);
+_Noreturn void _longjmp (jmp_buf, int);
+#endif
+
+int setjmp (jmp_buf);
+_Noreturn void longjmp (jmp_buf, int);
+
+#define setjmp setjmp
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/shadow.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/shadow.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/shadow.h	(revision 331)
@@ -0,0 +1,44 @@
+#ifndef _SHADOW_H
+#define _SHADOW_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define	__NEED_FILE
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+#define	SHADOW "/etc/shadow"
+
+struct spwd {
+	char *sp_namp;
+	char *sp_pwdp;
+	long sp_lstchg;
+	long sp_min;
+	long sp_max;
+	long sp_warn;
+	long sp_inact;
+	long sp_expire;
+	unsigned long sp_flag;
+};
+
+void setspent(void);
+void endspent(void);
+struct spwd *getspent(void);
+struct spwd *fgetspent(FILE *);
+struct spwd *sgetspent(const char *);
+int putspent(const struct spwd *, FILE *);
+
+struct spwd *getspnam(const char *);
+int getspnam_r(const char *, struct spwd *, char *, size_t, struct spwd **);
+
+int lckpwdf(void);
+int ulckpwdf(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/signal.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/signal.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/signal.h	(revision 331)
@@ -0,0 +1,275 @@
+#ifndef _SIGNAL_H
+#define _SIGNAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+
+#ifdef _GNU_SOURCE
+#define __ucontext ucontext
+#endif
+
+#define __NEED_size_t
+#define __NEED_pid_t
+#define __NEED_uid_t
+#define __NEED_struct_timespec
+#define __NEED_pthread_t
+#define __NEED_pthread_attr_t
+#define __NEED_time_t
+#define __NEED_clock_t
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+#define SIG_BLOCK     0
+#define SIG_UNBLOCK   1
+#define SIG_SETMASK   2
+
+#define SI_ASYNCNL (-60)
+#define SI_TKILL (-6)
+#define SI_SIGIO (-5)
+#define SI_ASYNCIO (-4)
+#define SI_MESGQ (-3)
+#define SI_TIMER (-2)
+#define SI_QUEUE (-1)
+#define SI_USER 0
+#define SI_KERNEL 128
+
+typedef struct sigaltstack stack_t;
+
+#endif
+
+#include <bits/signal.h>
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+
+#define SIG_HOLD ((void (*)(int)) 2)
+
+#define FPE_INTDIV 1
+#define FPE_INTOVF 2
+#define FPE_FLTDIV 3
+#define FPE_FLTOVF 4
+#define FPE_FLTUND 5
+#define FPE_FLTRES 6
+#define FPE_FLTINV 7
+#define FPE_FLTSUB 8
+
+#define ILL_ILLOPC 1
+#define ILL_ILLOPN 2
+#define ILL_ILLADR 3
+#define ILL_ILLTRP 4
+#define ILL_PRVOPC 5
+#define ILL_PRVREG 6
+#define ILL_COPROC 7
+#define ILL_BADSTK 8
+
+#define SEGV_MAPERR 1
+#define SEGV_ACCERR 2
+#define SEGV_BNDERR 3
+#define SEGV_PKUERR 4
+
+#define BUS_ADRALN 1
+#define BUS_ADRERR 2
+#define BUS_OBJERR 3
+#define BUS_MCEERR_AR 4
+#define BUS_MCEERR_AO 5
+
+#define CLD_EXITED 1
+#define CLD_KILLED 2
+#define CLD_DUMPED 3
+#define CLD_TRAPPED 4
+#define CLD_STOPPED 5
+#define CLD_CONTINUED 6
+
+union sigval {
+	int sival_int;
+	void *sival_ptr;
+};
+
+typedef struct {
+#ifdef __SI_SWAP_ERRNO_CODE
+	int si_signo, si_code, si_errno;
+#else
+	int si_signo, si_errno, si_code;
+#endif
+	union {
+		char __pad[128 - 2*sizeof(int) - sizeof(long)];
+		struct {
+			union {
+				struct {
+					pid_t si_pid;
+					uid_t si_uid;
+				} __piduid;
+				struct {
+					int si_timerid;
+					int si_overrun;
+				} __timer;
+			} __first;
+			union {
+				union sigval si_value;
+				struct {
+					int si_status;
+					clock_t si_utime, si_stime;
+				} __sigchld;
+			} __second;
+		} __si_common;
+		struct {
+			void *si_addr;
+			short si_addr_lsb;
+			union {
+				struct {
+					void *si_lower;
+					void *si_upper;
+				} __addr_bnd;
+				unsigned si_pkey;
+			} __first;
+		} __sigfault;
+		struct {
+			long si_band;
+			int si_fd;
+		} __sigpoll;
+		struct {
+			void *si_call_addr;
+			int si_syscall;
+			unsigned si_arch;
+		} __sigsys;
+	} __si_fields;
+} siginfo_t;
+#define si_pid     __si_fields.__si_common.__first.__piduid.si_pid
+#define si_uid     __si_fields.__si_common.__first.__piduid.si_uid
+#define si_status  __si_fields.__si_common.__second.__sigchld.si_status
+#define si_utime   __si_fields.__si_common.__second.__sigchld.si_utime
+#define si_stime   __si_fields.__si_common.__second.__sigchld.si_stime
+#define si_value   __si_fields.__si_common.__second.si_value
+#define si_addr    __si_fields.__sigfault.si_addr
+#define si_addr_lsb __si_fields.__sigfault.si_addr_lsb
+#define si_lower   __si_fields.__sigfault.__first.__addr_bnd.si_lower
+#define si_upper   __si_fields.__sigfault.__first.__addr_bnd.si_upper
+#define si_pkey    __si_fields.__sigfault.__first.si_pkey
+#define si_band    __si_fields.__sigpoll.si_band
+#define si_fd      __si_fields.__sigpoll.si_fd
+#define si_timerid __si_fields.__si_common.__first.__timer.si_timerid
+#define si_overrun __si_fields.__si_common.__first.__timer.si_overrun
+#define si_ptr     si_value.sival_ptr
+#define si_int     si_value.sival_int
+#define si_call_addr __si_fields.__sigsys.si_call_addr
+#define si_syscall __si_fields.__sigsys.si_syscall
+#define si_arch    __si_fields.__sigsys.si_arch
+
+struct sigaction {
+	union {
+		void (*sa_handler)(int);
+		void (*sa_sigaction)(int, siginfo_t *, void *);
+	} __sa_handler;
+	sigset_t sa_mask;
+	int sa_flags;
+	void (*sa_restorer)(void);
+};
+#define sa_handler   __sa_handler.sa_handler
+#define sa_sigaction __sa_handler.sa_sigaction
+
+struct sigevent {
+	union sigval sigev_value;
+	int sigev_signo;
+	int sigev_notify;
+	void (*sigev_notify_function)(union sigval);
+	pthread_attr_t *sigev_notify_attributes;
+	char __pad[56-3*sizeof(long)];
+};
+
+#define SIGEV_SIGNAL 0
+#define SIGEV_NONE 1
+#define SIGEV_THREAD 2
+
+int __libc_current_sigrtmin(void);
+int __libc_current_sigrtmax(void);
+
+#define SIGRTMIN  (__libc_current_sigrtmin())
+#define SIGRTMAX  (__libc_current_sigrtmax())
+
+int kill(pid_t, int);
+
+int sigemptyset(sigset_t *);
+int sigfillset(sigset_t *);
+int sigaddset(sigset_t *, int);
+int sigdelset(sigset_t *, int);
+int sigismember(const sigset_t *, int);
+
+int sigprocmask(int, const sigset_t *__restrict, sigset_t *__restrict);
+int sigsuspend(const sigset_t *);
+int sigaction(int, const struct sigaction *__restrict, struct sigaction *__restrict);
+int sigpending(sigset_t *);
+int sigwait(const sigset_t *__restrict, int *__restrict);
+int sigwaitinfo(const sigset_t *__restrict, siginfo_t *__restrict);
+int sigtimedwait(const sigset_t *__restrict, siginfo_t *__restrict, const struct timespec *__restrict);
+int sigqueue(pid_t, int, const union sigval);
+
+int pthread_sigmask(int, const sigset_t *__restrict, sigset_t *__restrict);
+int pthread_kill(pthread_t, int);
+
+void psiginfo(const siginfo_t *, const char *);
+void psignal(int, const char *);
+
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+int killpg(pid_t, int);
+int sigaltstack(const stack_t *__restrict, stack_t *__restrict);
+int sighold(int);
+int sigignore(int);
+int siginterrupt(int, int);
+int sigpause(int);
+int sigrelse(int);
+void (*sigset(int, void (*)(int)))(int);
+#define TRAP_BRKPT 1
+#define TRAP_TRACE 2
+#define POLL_IN 1
+#define POLL_OUT 2
+#define POLL_MSG 3
+#define POLL_ERR 4
+#define POLL_PRI 5
+#define POLL_HUP 6
+#define SS_ONSTACK    1
+#define SS_DISABLE    2
+#define SS_AUTODISARM (1U << 31)
+#define SS_FLAG_BITS SS_AUTODISARM
+#endif
+
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#define NSIG _NSIG
+typedef void (*sig_t)(int);
+#endif
+
+#ifdef _GNU_SOURCE
+typedef void (*sighandler_t)(int);
+void (*bsd_signal(int, void (*)(int)))(int);
+int sigisemptyset(const sigset_t *);
+int sigorset (sigset_t *, const sigset_t *, const sigset_t *);
+int sigandset(sigset_t *, const sigset_t *, const sigset_t *);
+
+#define SA_NOMASK SA_NODEFER
+#define SA_ONESHOT SA_RESETHAND
+#endif
+
+#define SIG_ERR  ((void (*)(int))-1)
+#define SIG_DFL  ((void (*)(int)) 0)
+#define SIG_IGN  ((void (*)(int)) 1)
+
+typedef int sig_atomic_t;
+
+void (*signal(int, void (*)(int)))(int);
+int raise(int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/spawn.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/spawn.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/spawn.h	(revision 331)
@@ -0,0 +1,76 @@
+#ifndef _SPAWN_H
+#define _SPAWN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_mode_t
+#define __NEED_pid_t
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+struct sched_param;
+
+#define POSIX_SPAWN_RESETIDS 1
+#define POSIX_SPAWN_SETPGROUP 2
+#define POSIX_SPAWN_SETSIGDEF 4
+#define POSIX_SPAWN_SETSIGMASK 8
+#define POSIX_SPAWN_SETSCHEDPARAM 16
+#define POSIX_SPAWN_SETSCHEDULER 32
+#define POSIX_SPAWN_USEVFORK 64
+#define POSIX_SPAWN_SETSID 128
+
+typedef struct {
+	int __flags;
+	pid_t __pgrp;
+	sigset_t __def, __mask;
+	int __prio, __pol, __pad[16];
+} posix_spawnattr_t;
+
+typedef struct {
+	int __pad0[2];
+	void *__actions;
+	int __pad[16];
+} posix_spawn_file_actions_t;
+
+int posix_spawn(pid_t *__restrict, const char *__restrict, const posix_spawn_file_actions_t *,
+	const posix_spawnattr_t *__restrict, char *const *__restrict, char *const *__restrict);
+int posix_spawnp(pid_t *__restrict, const char *__restrict, const posix_spawn_file_actions_t *,
+	const posix_spawnattr_t *__restrict, char *const *__restrict, char *const *__restrict);
+
+int posix_spawnattr_init(posix_spawnattr_t *);
+int posix_spawnattr_destroy(posix_spawnattr_t *);
+
+int posix_spawnattr_setflags(posix_spawnattr_t *, short);
+int posix_spawnattr_getflags(const posix_spawnattr_t *__restrict, short *__restrict);
+
+int posix_spawnattr_setpgroup(posix_spawnattr_t *, pid_t);
+int posix_spawnattr_getpgroup(const posix_spawnattr_t *__restrict, pid_t *__restrict);
+
+int posix_spawnattr_setsigmask(posix_spawnattr_t *__restrict, const sigset_t *__restrict);
+int posix_spawnattr_getsigmask(const posix_spawnattr_t *__restrict, sigset_t *__restrict);
+
+int posix_spawnattr_setsigdefault(posix_spawnattr_t *__restrict, const sigset_t *__restrict);
+int posix_spawnattr_getsigdefault(const posix_spawnattr_t *__restrict, sigset_t *__restrict);
+
+int posix_spawnattr_setschedparam(posix_spawnattr_t *__restrict, const struct sched_param *__restrict);
+int posix_spawnattr_getschedparam(const posix_spawnattr_t *__restrict, struct sched_param *__restrict);
+int posix_spawnattr_setschedpolicy(posix_spawnattr_t *, int);
+int posix_spawnattr_getschedpolicy(const posix_spawnattr_t *__restrict, int *__restrict);
+
+int posix_spawn_file_actions_init(posix_spawn_file_actions_t *);
+int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *);
+
+int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t *__restrict, int, const char *__restrict, int, mode_t);
+int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *, int);
+int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *, int, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/stdalign.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/stdalign.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/stdalign.h	(revision 331)
@@ -0,0 +1,20 @@
+#ifndef _STDALIGN_H
+#define _STDALIGN_H
+
+#ifndef __cplusplus
+
+/* this whole header only works in C11 or with compiler extensions */
+#if __STDC_VERSION__ < 201112L && defined( __GNUC__)
+#define _Alignas(t) __attribute__((__aligned__(t)))
+#define _Alignof(t) __alignof__(t)
+#endif
+
+#define alignas _Alignas
+#define alignof _Alignof
+
+#endif
+
+#define __alignas_is_defined 1
+#define __alignof_is_defined 1
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/stdarg.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/stdarg.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/stdarg.h	(revision 331)
@@ -0,0 +1,21 @@
+#ifndef _STDARG_H
+#define _STDARG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_va_list
+
+#include <bits/alltypes.h>
+
+#define va_start(v,l)   __builtin_va_start(v,l)
+#define va_end(v)       __builtin_va_end(v)
+#define va_arg(v,l)     __builtin_va_arg(v,l)
+#define va_copy(d,s)    __builtin_va_copy(d,s)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/stdbool.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/stdbool.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/stdbool.h	(revision 331)
@@ -0,0 +1,14 @@
+#ifndef _STDBOOL_H
+#define _STDBOOL_H
+
+#ifndef __cplusplus
+
+#define true 1
+#define false 0
+#define bool _Bool
+
+#endif
+
+#define __bool_true_false_are_defined 1
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/stdc-predef.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/stdc-predef.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/stdc-predef.h	(revision 331)
@@ -0,0 +1,10 @@
+#ifndef _STDC_PREDEF_H
+#define _STDC_PREDEF_H
+
+#define __STDC_ISO_10646__ 201206L
+
+#if !defined(__GCC_IEC_559) || __GCC_IEC_559 > 0
+#define __STDC_IEC_559__ 1
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/stddef.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/stddef.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/stddef.h	(revision 331)
@@ -0,0 +1,25 @@
+#ifndef _STDDEF_H
+#define _STDDEF_H
+
+#ifdef __cplusplus
+#define NULL 0L
+#else
+#define NULL ((void*)0)
+#endif
+
+#define __NEED_ptrdiff_t
+#define __NEED_size_t
+#define __NEED_wchar_t
+#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L
+#define __NEED_max_align_t
+#endif
+
+#include <bits/alltypes.h>
+
+#if __GNUC__ > 3
+#define offsetof(type, member) __builtin_offsetof(type, member)
+#else
+#define offsetof(type, member) ((size_t)( (char *)&(((type *)0)->member) - (char *)0 ))
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/stdint.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/stdint.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/stdint.h	(revision 331)
@@ -0,0 +1,117 @@
+#ifndef _STDINT_H
+#define _STDINT_H
+
+#define __NEED_int8_t
+#define __NEED_int16_t
+#define __NEED_int32_t
+#define __NEED_int64_t
+
+#define __NEED_uint8_t
+#define __NEED_uint16_t
+#define __NEED_uint32_t
+#define __NEED_uint64_t
+
+#define __NEED_intptr_t
+#define __NEED_uintptr_t
+
+#define __NEED_intmax_t
+#define __NEED_uintmax_t
+
+#include <bits/alltypes.h>
+
+typedef int8_t int_fast8_t;
+typedef int64_t int_fast64_t;
+
+typedef int8_t  int_least8_t;
+typedef int16_t int_least16_t;
+typedef int32_t int_least32_t;
+typedef int64_t int_least64_t;
+
+typedef uint8_t uint_fast8_t;
+typedef uint64_t uint_fast64_t;
+
+typedef uint8_t  uint_least8_t;
+typedef uint16_t uint_least16_t;
+typedef uint32_t uint_least32_t;
+typedef uint64_t uint_least64_t;
+
+#define INT8_MIN   (-1-0x7f)
+#define INT16_MIN  (-1-0x7fff)
+#define INT32_MIN  (-1-0x7fffffff)
+#define INT64_MIN  (-1-0x7fffffffffffffff)
+
+#define INT8_MAX   (0x7f)
+#define INT16_MAX  (0x7fff)
+#define INT32_MAX  (0x7fffffff)
+#define INT64_MAX  (0x7fffffffffffffff)
+
+#define UINT8_MAX  (0xff)
+#define UINT16_MAX (0xffff)
+#define UINT32_MAX (0xffffffffu)
+#define UINT64_MAX (0xffffffffffffffffu)
+
+#define INT_FAST8_MIN   INT8_MIN
+#define INT_FAST64_MIN  INT64_MIN
+
+#define INT_LEAST8_MIN   INT8_MIN
+#define INT_LEAST16_MIN  INT16_MIN
+#define INT_LEAST32_MIN  INT32_MIN
+#define INT_LEAST64_MIN  INT64_MIN
+
+#define INT_FAST8_MAX   INT8_MAX
+#define INT_FAST64_MAX  INT64_MAX
+
+#define INT_LEAST8_MAX   INT8_MAX
+#define INT_LEAST16_MAX  INT16_MAX
+#define INT_LEAST32_MAX  INT32_MAX
+#define INT_LEAST64_MAX  INT64_MAX
+
+#define UINT_FAST8_MAX  UINT8_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+#define UINT_LEAST8_MAX  UINT8_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+#define INTMAX_MIN  INT64_MIN
+#define INTMAX_MAX  INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+#define WINT_MIN 0U
+#define WINT_MAX UINT32_MAX
+
+#if L'\0'-1 > 0
+#define WCHAR_MAX (0xffffffffu+L'\0')
+#define WCHAR_MIN (0+L'\0')
+#else
+#define WCHAR_MAX (0x7fffffff+L'\0')
+#define WCHAR_MIN (-1-0x7fffffff+L'\0')
+#endif
+
+#define SIG_ATOMIC_MIN  INT32_MIN
+#define SIG_ATOMIC_MAX  INT32_MAX
+
+#include <bits/stdint.h>
+
+#define INT8_C(c)  c
+#define INT16_C(c) c
+#define INT32_C(c) c
+
+#define UINT8_C(c)  c
+#define UINT16_C(c) c
+#define UINT32_C(c) c ## U
+
+#if UINTPTR_MAX == UINT64_MAX
+#define INT64_C(c) c ## L
+#define UINT64_C(c) c ## UL
+#define INTMAX_C(c)  c ## L
+#define UINTMAX_C(c) c ## UL
+#else
+#define INT64_C(c) c ## LL
+#define UINT64_C(c) c ## ULL
+#define INTMAX_C(c)  c ## LL
+#define UINTMAX_C(c) c ## ULL
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/stdio.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/stdio.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/stdio.h	(revision 331)
@@ -0,0 +1,203 @@
+#ifndef _STDIO_H
+#define _STDIO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_FILE
+#define __NEED___isoc_va_list
+#define __NEED_size_t
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+#define __NEED_ssize_t
+#define __NEED_off_t
+#define __NEED_va_list
+#endif
+
+#include <bits/alltypes.h>
+
+#ifdef __cplusplus
+#define NULL 0L
+#else
+#define NULL ((void*)0)
+#endif
+
+#undef EOF
+#define EOF (-1)
+
+#undef SEEK_SET
+#undef SEEK_CUR
+#undef SEEK_END
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+#define _IOFBF 0
+#define _IOLBF 1
+#define _IONBF 2
+
+#define BUFSIZ 1024
+#define FILENAME_MAX 4096
+#define FOPEN_MAX 1000
+#define TMP_MAX 10000
+#define L_tmpnam 20
+
+typedef union _G_fpos64_t {
+	char __opaque[16];
+	double __align;
+} fpos_t;
+
+extern FILE *const stdin;
+extern FILE *const stdout;
+extern FILE *const stderr;
+
+#define stdin  (stdin)
+#define stdout (stdout)
+#define stderr (stderr)
+
+FILE *fopen(const char *__restrict, const char *__restrict);
+FILE *freopen(const char *__restrict, const char *__restrict, FILE *__restrict);
+int fclose(FILE *);
+
+int remove(const char *);
+int rename(const char *, const char *);
+
+int feof(FILE *);
+int ferror(FILE *);
+int fflush(FILE *);
+void clearerr(FILE *);
+
+int fseek(FILE *, long, int);
+long ftell(FILE *);
+void rewind(FILE *);
+
+int fgetpos(FILE *__restrict, fpos_t *__restrict);
+int fsetpos(FILE *, const fpos_t *);
+
+size_t fread(void *__restrict, size_t, size_t, FILE *__restrict);
+size_t fwrite(const void *__restrict, size_t, size_t, FILE *__restrict);
+
+int fgetc(FILE *);
+int getc(FILE *);
+int getchar(void);
+int ungetc(int, FILE *);
+
+int fputc(int, FILE *);
+int putc(int, FILE *);
+int putchar(int);
+
+char *fgets(char *__restrict, int, FILE *__restrict);
+#if __STDC_VERSION__ < 201112L
+char *gets(char *);
+#endif
+
+int fputs(const char *__restrict, FILE *__restrict);
+int puts(const char *);
+
+int printf(const char *__restrict, ...);
+int fprintf(FILE *__restrict, const char *__restrict, ...);
+int sprintf(char *__restrict, const char *__restrict, ...);
+int snprintf(char *__restrict, size_t, const char *__restrict, ...);
+
+int vprintf(const char *__restrict, __isoc_va_list);
+int vfprintf(FILE *__restrict, const char *__restrict, __isoc_va_list);
+int vsprintf(char *__restrict, const char *__restrict, __isoc_va_list);
+int vsnprintf(char *__restrict, size_t, const char *__restrict, __isoc_va_list);
+
+int scanf(const char *__restrict, ...);
+int fscanf(FILE *__restrict, const char *__restrict, ...);
+int sscanf(const char *__restrict, const char *__restrict, ...);
+int vscanf(const char *__restrict, __isoc_va_list);
+int vfscanf(FILE *__restrict, const char *__restrict, __isoc_va_list);
+int vsscanf(const char *__restrict, const char *__restrict, __isoc_va_list);
+
+void perror(const char *);
+
+int setvbuf(FILE *__restrict, char *__restrict, int, size_t);
+void setbuf(FILE *__restrict, char *__restrict);
+
+char *tmpnam(char *);
+FILE *tmpfile(void);
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+FILE *fmemopen(void *__restrict, size_t, const char *__restrict);
+FILE *open_memstream(char **, size_t *);
+FILE *fdopen(int, const char *);
+FILE *popen(const char *, const char *);
+int pclose(FILE *);
+int fileno(FILE *);
+int fseeko(FILE *, off_t, int);
+off_t ftello(FILE *);
+int dprintf(int, const char *__restrict, ...);
+int vdprintf(int, const char *__restrict, __isoc_va_list);
+void flockfile(FILE *);
+int ftrylockfile(FILE *);
+void funlockfile(FILE *);
+int getc_unlocked(FILE *);
+int getchar_unlocked(void);
+int putc_unlocked(int, FILE *);
+int putchar_unlocked(int);
+ssize_t getdelim(char **__restrict, size_t *__restrict, int, FILE *__restrict);
+ssize_t getline(char **__restrict, size_t *__restrict, FILE *__restrict);
+int renameat(int, const char *, int, const char *);
+char *ctermid(char *);
+#define L_ctermid 20
+#endif
+
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+#define P_tmpdir "/tmp"
+char *tempnam(const char *, const char *);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define L_cuserid 20
+char *cuserid(char *);
+void setlinebuf(FILE *);
+void setbuffer(FILE *, char *, size_t);
+int fgetc_unlocked(FILE *);
+int fputc_unlocked(int, FILE *);
+int fflush_unlocked(FILE *);
+size_t fread_unlocked(void *, size_t, size_t, FILE *);
+size_t fwrite_unlocked(const void *, size_t, size_t, FILE *);
+void clearerr_unlocked(FILE *);
+int feof_unlocked(FILE *);
+int ferror_unlocked(FILE *);
+int fileno_unlocked(FILE *);
+int getw(FILE *);
+int putw(int, FILE *);
+char *fgetln(FILE *, size_t *);
+int asprintf(char **, const char *, ...);
+int vasprintf(char **, const char *, __isoc_va_list);
+#endif
+
+#ifdef _GNU_SOURCE
+char *fgets_unlocked(char *, int, FILE *);
+int fputs_unlocked(const char *, FILE *);
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define tmpfile64 tmpfile
+#define fopen64 fopen
+#define freopen64 freopen
+#define fseeko64 fseeko
+#define ftello64 ftello
+#define fgetpos64 fgetpos
+#define fsetpos64 fsetpos
+#define fpos64_t fpos_t
+#define off64_t off_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/stdio_ext.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/stdio_ext.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/stdio_ext.h	(revision 331)
@@ -0,0 +1,34 @@
+#ifndef _STDIO_EXT_H
+#define _STDIO_EXT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+
+#define FSETLOCKING_QUERY 0
+#define FSETLOCKING_INTERNAL 1
+#define FSETLOCKING_BYCALLER 2
+
+void _flushlbf(void);
+int __fsetlocking(FILE *, int);
+int __fwriting(FILE *);
+int __freading(FILE *);
+int __freadable(FILE *);
+int __fwritable(FILE *);
+int __flbf(FILE *);
+size_t __fbufsize(FILE *);
+size_t __fpending(FILE *);
+int __fpurge(FILE *);
+
+size_t __freadahead(FILE *);
+const char *__freadptr(FILE *, size_t *);
+void __freadptrinc(FILE *, size_t);
+void __fseterr(FILE *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/stdlib.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/stdlib.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/stdlib.h	(revision 331)
@@ -0,0 +1,174 @@
+#ifndef _STDLIB_H
+#define _STDLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#ifdef __cplusplus
+#define NULL 0L
+#else
+#define NULL ((void*)0)
+#endif
+
+#define __NEED_size_t
+#define __NEED_wchar_t
+
+#include <bits/alltypes.h>
+
+int atoi (const char *);
+long atol (const char *);
+long long atoll (const char *);
+double atof (const char *);
+
+float strtof (const char *__restrict, char **__restrict);
+double strtod (const char *__restrict, char **__restrict);
+long double strtold (const char *__restrict, char **__restrict);
+
+long strtol (const char *__restrict, char **__restrict, int);
+unsigned long strtoul (const char *__restrict, char **__restrict, int);
+long long strtoll (const char *__restrict, char **__restrict, int);
+unsigned long long strtoull (const char *__restrict, char **__restrict, int);
+
+int rand (void);
+void srand (unsigned);
+
+void *malloc (size_t);
+void *calloc (size_t, size_t);
+void *realloc (void *, size_t);
+void free (void *);
+void *aligned_alloc(size_t, size_t);
+
+_Noreturn void abort (void);
+int atexit (void (*) (void));
+_Noreturn void exit (int);
+_Noreturn void _Exit (int);
+int at_quick_exit (void (*) (void));
+_Noreturn void quick_exit (int);
+
+char *getenv (const char *);
+
+int system (const char *);
+
+void *bsearch (const void *, const void *, size_t, size_t, int (*)(const void *, const void *));
+void qsort (void *, size_t, size_t, int (*)(const void *, const void *));
+
+int abs (int);
+long labs (long);
+long long llabs (long long);
+
+typedef struct { int quot, rem; } div_t;
+typedef struct { long quot, rem; } ldiv_t;
+typedef struct { long long quot, rem; } lldiv_t;
+
+div_t div (int, int);
+ldiv_t ldiv (long, long);
+lldiv_t lldiv (long long, long long);
+
+int mblen (const char *, size_t);
+int mbtowc (wchar_t *__restrict, const char *__restrict, size_t);
+int wctomb (char *, wchar_t);
+size_t mbstowcs (wchar_t *__restrict, const char *__restrict, size_t);
+size_t wcstombs (char *__restrict, const wchar_t *__restrict, size_t);
+
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
+
+size_t __ctype_get_mb_cur_max(void);
+#define MB_CUR_MAX (__ctype_get_mb_cur_max())
+
+#define RAND_MAX (0x7fffffff)
+
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+
+#define WNOHANG    1
+#define WUNTRACED  2
+
+#define WEXITSTATUS(s) (((s) & 0xff00) >> 8)
+#define WTERMSIG(s) ((s) & 0x7f)
+#define WSTOPSIG(s) WEXITSTATUS(s)
+#define WIFEXITED(s) (!WTERMSIG(s))
+#define WIFSTOPPED(s) ((short)((((s)&0xffff)*0x10001)>>8) > 0x7f00)
+#define WIFSIGNALED(s) (((s)&0xffff)-1U < 0xffu)
+
+int posix_memalign (void **, size_t, size_t);
+int setenv (const char *, const char *, int);
+int unsetenv (const char *);
+int mkstemp (char *);
+int mkostemp (char *, int);
+char *mkdtemp (char *);
+int getsubopt (char **, char *const *, char **);
+int rand_r (unsigned *);
+
+#endif
+
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+char *realpath (const char *__restrict, char *__restrict);
+long int random (void);
+void srandom (unsigned int);
+char *initstate (unsigned int, char *, size_t);
+char *setstate (char *);
+int putenv (char *);
+int posix_openpt (int);
+int grantpt (int);
+int unlockpt (int);
+char *ptsname (int);
+char *l64a (long);
+long a64l (const char *);
+void setkey (const char *);
+double drand48 (void);
+double erand48 (unsigned short [3]);
+long int lrand48 (void);
+long int nrand48 (unsigned short [3]);
+long mrand48 (void);
+long jrand48 (unsigned short [3]);
+void srand48 (long);
+unsigned short *seed48 (unsigned short [3]);
+void lcong48 (unsigned short [7]);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#include <alloca.h>
+char *mktemp (char *);
+int mkstemps (char *, int);
+int mkostemps (char *, int, int);
+void *valloc (size_t);
+void *memalign(size_t, size_t);
+int getloadavg(double *, int);
+int clearenv(void);
+#define WCOREDUMP(s) ((s) & 0x80)
+#define WIFCONTINUED(s) ((s) == 0xffff)
+#endif
+
+#ifdef _GNU_SOURCE
+int ptsname_r(int, char *, size_t);
+char *ecvt(double, int, int *, int *);
+char *fcvt(double, int, int *, int *);
+char *gcvt(double, int, char *);
+struct __locale_struct;
+float strtof_l(const char *__restrict, char **__restrict, struct __locale_struct *);
+double strtod_l(const char *__restrict, char **__restrict, struct __locale_struct *);
+long double strtold_l(const char *__restrict, char **__restrict, struct __locale_struct *);
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define mkstemp64 mkstemp
+#define mkostemp64 mkostemp
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define mkstemps64 mkstemps
+#define mkostemps64 mkostemps
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/stdnoreturn.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/stdnoreturn.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/stdnoreturn.h	(revision 331)
@@ -0,0 +1,7 @@
+#ifndef _STDNORETURN_H
+#define _STDNORETURN_H
+#ifndef __cplusplus
+#include <features.h>
+#define noreturn _Noreturn
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/string.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/string.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/string.h	(revision 331)
@@ -0,0 +1,104 @@
+#ifndef	_STRING_H
+#define	_STRING_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#ifdef __cplusplus
+#define NULL 0L
+#else
+#define NULL ((void*)0)
+#endif
+
+#define __NEED_size_t
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+#define __NEED_locale_t
+#endif
+
+#include <bits/alltypes.h>
+
+void *memcpy (void *__restrict, const void *__restrict, size_t);
+void *memmove (void *, const void *, size_t);
+void *memset (void *, int, size_t);
+int memcmp (const void *, const void *, size_t);
+void *memchr (const void *, int, size_t);
+
+char *strcpy (char *__restrict, const char *__restrict);
+char *strncpy (char *__restrict, const char *__restrict, size_t);
+
+char *strcat (char *__restrict, const char *__restrict);
+char *strncat (char *__restrict, const char *__restrict, size_t);
+
+int strcmp (const char *, const char *);
+int strncmp (const char *, const char *, size_t);
+
+int strcoll (const char *, const char *);
+size_t strxfrm (char *__restrict, const char *__restrict, size_t);
+
+char *strchr (const char *, int);
+char *strrchr (const char *, int);
+
+size_t strcspn (const char *, const char *);
+size_t strspn (const char *, const char *);
+char *strpbrk (const char *, const char *);
+char *strstr (const char *, const char *);
+char *strtok (char *__restrict, const char *__restrict);
+
+size_t strlen (const char *);
+
+char *strerror (int);
+
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#include <strings.h>
+#endif
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+char *strtok_r (char *__restrict, const char *__restrict, char **__restrict);
+int strerror_r (int, char *, size_t);
+char *stpcpy(char *__restrict, const char *__restrict);
+char *stpncpy(char *__restrict, const char *__restrict, size_t);
+size_t strnlen (const char *, size_t);
+char *strdup (const char *);
+char *strndup (const char *, size_t);
+char *strsignal(int);
+char *strerror_l (int, locale_t);
+int strcoll_l (const char *, const char *, locale_t);
+size_t strxfrm_l (char *__restrict, const char *__restrict, size_t, locale_t);
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+void *memccpy (void *__restrict, const void *__restrict, int, size_t);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+char *strsep(char **, const char *);
+size_t strlcat (char *, const char *, size_t);
+size_t strlcpy (char *, const char *, size_t);
+#endif
+
+#ifdef _GNU_SOURCE
+#define	strdupa(x)	strcpy(alloca(strlen(x)+1),x)
+int strverscmp (const char *, const char *);
+char *strchrnul(const char *, int);
+char *strcasestr(const char *, const char *);
+void *memmem(const void *, size_t, const void *, size_t);
+void *memrchr(const void *, int, size_t);
+void *mempcpy(void *, const void *, size_t);
+#ifndef __cplusplus
+char *basename();
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/strings.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/strings.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/strings.h	(revision 331)
@@ -0,0 +1,39 @@
+#ifndef	_STRINGS_H
+#define	_STRINGS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define __NEED_size_t
+#define __NEED_locale_t
+#include <bits/alltypes.h>
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_POSIX_SOURCE) \
+ || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE+0 < 200809L) \
+ || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700)
+int bcmp (const void *, const void *, size_t);
+void bcopy (const void *, void *, size_t);
+void bzero (void *, size_t);
+char *index (const char *, int);
+char *rindex (const char *, int);
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE)  || defined(_BSD_SOURCE)
+int ffs (int);
+int ffsl (long);
+int ffsll (long long);
+#endif
+
+int strcasecmp (const char *, const char *);
+int strncasecmp (const char *, const char *, size_t);
+
+int strcasecmp_l (const char *, const char *, locale_t);
+int strncasecmp_l (const char *, const char *, size_t, locale_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/stropts.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/stropts.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/stropts.h	(revision 331)
@@ -0,0 +1,139 @@
+#ifndef _STROPTS_H
+#define _STROPTS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __SID		('S' << 8)
+
+#define I_NREAD		(__SID | 1)
+#define I_PUSH		(__SID | 2)
+#define I_POP		(__SID | 3)
+#define I_LOOK		(__SID | 4)
+#define I_FLUSH		(__SID | 5)
+#define I_SRDOPT	(__SID | 6)
+#define I_GRDOPT	(__SID | 7)
+#define I_STR		(__SID | 8)
+#define I_SETSIG	(__SID | 9)
+#define I_GETSIG	(__SID |10)
+#define I_FIND		(__SID |11)
+#define I_LINK		(__SID |12)
+#define I_UNLINK	(__SID |13)
+#define I_PEEK		(__SID |15)
+#define I_FDINSERT	(__SID |16)
+#define I_SENDFD	(__SID |17)
+#define I_RECVFD	(__SID |14)
+#define I_SWROPT	(__SID |19)
+#define I_GWROPT	(__SID |20)
+#define I_LIST		(__SID |21)
+#define I_PLINK		(__SID |22)
+#define I_PUNLINK	(__SID |23)
+#define I_FLUSHBAND	(__SID |28)
+#define I_CKBAND	(__SID |29)
+#define I_GETBAND	(__SID |30)
+#define I_ATMARK	(__SID |31)
+#define I_SETCLTIME	(__SID |32)
+#define I_GETCLTIME	(__SID |33)
+#define I_CANPUT	(__SID |34)
+
+#define FMNAMESZ	8
+
+#define FLUSHR		0x01
+#define FLUSHW		0x02
+#define FLUSHRW		0x03
+#define FLUSHBAND	0x04
+
+#define S_INPUT		0x0001
+#define S_HIPRI		0x0002
+#define S_OUTPUT	0x0004
+#define S_MSG		0x0008
+#define S_ERROR		0x0010
+#define S_HANGUP	0x0020
+#define S_RDNORM	0x0040
+#define S_WRNORM	S_OUTPUT
+#define S_RDBAND	0x0080
+#define S_WRBAND	0x0100
+#define S_BANDURG	0x0200
+
+#define RS_HIPRI	0x01
+
+#define RNORM		0x0000
+#define RMSGD		0x0001
+#define RMSGN		0x0002
+#define RPROTDAT	0x0004
+#define RPROTDIS	0x0008
+#define RPROTNORM	0x0010
+#define RPROTMASK	0x001C
+
+#define SNDZERO		0x001
+#define SNDPIPE		0x002
+
+#define ANYMARK		0x01
+#define LASTMARK	0x02
+
+#define MUXID_ALL	(-1)
+
+#define MSG_HIPRI	0x01
+#define MSG_ANY		0x02
+#define MSG_BAND	0x04
+
+#define MORECTL		1
+#define MOREDATA	2
+
+struct bandinfo {
+	unsigned char bi_pri;
+	int bi_flag;
+};
+
+struct strbuf {
+	int maxlen;
+	int len;
+	char *buf;
+};
+
+struct strpeek {
+	struct strbuf ctlbuf;
+	struct strbuf databuf;
+	unsigned flags;
+};
+
+struct strfdinsert {
+	struct strbuf ctlbuf;
+	struct strbuf databuf;
+	unsigned flags;
+	int fildes;
+	int offset;
+};
+
+struct strioctl {
+	int ic_cmd;
+	int ic_timout;
+	int ic_len;
+	char *ic_dp;
+};
+
+struct strrecvfd {
+	int fd;
+	int uid;
+	int gid;
+	char __fill[8];
+};
+
+struct str_mlist {
+	char l_name[FMNAMESZ + 1];
+};
+
+struct str_list {
+	int sl_nmods;
+	struct str_mlist *sl_modlist;
+};
+
+int isastream(int);
+int ioctl(int, int, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/acct.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/acct.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/acct.h	(revision 331)
@@ -0,0 +1,73 @@
+#ifndef _SYS_ACCT_H
+#define _SYS_ACCT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <endian.h>
+#include <time.h>
+#include <stdint.h>
+
+#define ACCT_COMM 16
+
+typedef uint16_t comp_t;
+
+struct acct {
+	char ac_flag;
+	uint16_t ac_uid;
+	uint16_t ac_gid;
+	uint16_t ac_tty;
+	uint32_t ac_btime;
+	comp_t ac_utime;
+	comp_t ac_stime;
+	comp_t ac_etime;
+	comp_t ac_mem;
+	comp_t ac_io;
+	comp_t ac_rw;
+	comp_t ac_minflt;
+	comp_t ac_majflt;
+	comp_t ac_swaps;
+	uint32_t ac_exitcode;
+	char ac_comm[ACCT_COMM+1];
+	char ac_pad[10];
+};
+
+
+struct acct_v3 {
+	char ac_flag;
+	char ac_version;
+	uint16_t ac_tty;
+	uint32_t ac_exitcode;
+	uint32_t ac_uid;
+	uint32_t ac_gid;
+	uint32_t ac_pid;
+	uint32_t ac_ppid;
+	uint32_t ac_btime;
+	float ac_etime;
+	comp_t ac_utime;
+	comp_t ac_stime;
+	comp_t ac_mem;
+	comp_t ac_io;
+	comp_t ac_rw;
+	comp_t ac_minflt;
+	comp_t ac_majflt;
+	comp_t ac_swaps;
+	char ac_comm[ACCT_COMM];
+};
+
+#define AFORK 1
+#define ASU 2
+#define ACORE 8
+#define AXSIG 16
+#define ACCT_BYTEORDER (128*(__BYTE_ORDER==__BIG_ENDIAN))
+#define AHZ 100
+
+int acct(const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/auxv.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/auxv.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/auxv.h	(revision 331)
@@ -0,0 +1,17 @@
+#ifndef _SYS_AUXV_H
+#define _SYS_AUXV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <elf.h>
+#include <bits/hwcap.h>
+
+unsigned long getauxval(unsigned long);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/cachectl.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/cachectl.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/cachectl.h	(revision 331)
@@ -0,0 +1,22 @@
+#ifndef _SYS_CACHECTL_H
+#define _SYS_CACHECTL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ICACHE (1<<0)
+#define DCACHE (1<<1)
+#define BCACHE (ICACHE|DCACHE)
+#define CACHEABLE 0
+#define UNCACHEABLE 1
+ 
+int cachectl(void *, int, int);
+int cacheflush(void *, int, int);
+int _flush_cache(void *, int, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/dir.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/dir.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/dir.h	(revision 331)
@@ -0,0 +1,2 @@
+#include <dirent.h>
+#define direct dirent
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/epoll.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/epoll.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/epoll.h	(revision 331)
@@ -0,0 +1,68 @@
+#ifndef	_SYS_EPOLL_H
+#define	_SYS_EPOLL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+#define EPOLL_CLOEXEC O_CLOEXEC
+#define EPOLL_NONBLOCK O_NONBLOCK
+
+enum EPOLL_EVENTS { __EPOLL_DUMMY };
+#define EPOLLIN 0x001
+#define EPOLLPRI 0x002
+#define EPOLLOUT 0x004
+#define EPOLLRDNORM 0x040
+#define EPOLLRDBAND 0x080
+#define EPOLLWRNORM 0x100
+#define EPOLLWRBAND 0x200
+#define EPOLLMSG 0x400
+#define EPOLLERR 0x008
+#define EPOLLHUP 0x010
+#define EPOLLRDHUP 0x2000
+#define EPOLLEXCLUSIVE (1U<<28)
+#define EPOLLWAKEUP (1U<<29)
+#define EPOLLONESHOT (1U<<30)
+#define EPOLLET (1U<<31)
+
+#define EPOLL_CTL_ADD 1
+#define EPOLL_CTL_DEL 2
+#define EPOLL_CTL_MOD 3
+
+typedef union epoll_data {
+	void *ptr;
+	int fd;
+	uint32_t u32;
+	uint64_t u64;
+} epoll_data_t;
+
+struct epoll_event {
+	uint32_t events;
+	epoll_data_t data;
+}
+#ifdef __x86_64__
+__attribute__ ((__packed__))
+#endif
+;
+
+
+int epoll_create(int);
+int epoll_create1(int);
+int epoll_ctl(int, int, int, struct epoll_event *);
+int epoll_wait(int, struct epoll_event *, int, int);
+int epoll_pwait(int, struct epoll_event *, int, int, const sigset_t *);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* sys/epoll.h */
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/errno.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/errno.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/errno.h	(revision 331)
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <sys/errno.h> to <errno.h>
+#include <errno.h>
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/eventfd.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/eventfd.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/eventfd.h	(revision 331)
@@ -0,0 +1,26 @@
+#ifndef _SYS_EVENTFD_H
+#define _SYS_EVENTFD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <fcntl.h>
+
+typedef uint64_t eventfd_t;
+
+#define EFD_SEMAPHORE 1
+#define EFD_CLOEXEC O_CLOEXEC
+#define EFD_NONBLOCK O_NONBLOCK
+
+int eventfd(unsigned int, int);
+int eventfd_read(int, eventfd_t *);
+int eventfd_write(int, eventfd_t);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* sys/eventfd.h */
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/fanotify.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/fanotify.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/fanotify.h	(revision 331)
@@ -0,0 +1,73 @@
+#ifndef _FANOTIFY_H
+#define _FANOTIFY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct fanotify_event_metadata {
+	unsigned event_len;
+	unsigned char vers;
+	unsigned char reserved;
+	unsigned short metadata_len;
+	unsigned long long mask
+#ifdef __GNUC__
+	__attribute__((__aligned__(8)))
+#endif
+	;
+	int fd;
+	int pid;
+};
+
+struct fanotify_response {
+	int fd;
+	unsigned response;
+};
+
+#define FAN_ACCESS 0x01
+#define FAN_MODIFY 0x02
+#define FAN_CLOSE_WRITE 0x08
+#define FAN_CLOSE_NOWRITE 0x10
+#define FAN_OPEN 0x20
+#define FAN_Q_OVERFLOW 0x4000
+#define FAN_OPEN_PERM 0x10000
+#define FAN_ACCESS_PERM 0x20000
+#define FAN_ONDIR 0x40000000
+#define FAN_EVENT_ON_CHILD 0x08000000
+#define FAN_CLOSE (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE)
+#define FAN_CLOEXEC 0x01
+#define FAN_NONBLOCK 0x02
+#define FAN_CLASS_NOTIF 0
+#define FAN_CLASS_CONTENT 0x04
+#define FAN_CLASS_PRE_CONTENT 0x08
+#define FAN_ALL_CLASS_BITS (FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | FAN_CLASS_PRE_CONTENT)
+#define FAN_UNLIMITED_QUEUE 0x10
+#define FAN_UNLIMITED_MARKS 0x20
+#define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE | FAN_UNLIMITED_MARKS)
+#define FAN_MARK_ADD 0x01
+#define FAN_MARK_REMOVE 0x02
+#define FAN_MARK_DONT_FOLLOW 0x04
+#define FAN_MARK_ONLYDIR 0x08
+#define FAN_MARK_MOUNT 0x10
+#define FAN_MARK_IGNORED_MASK 0x20
+#define FAN_MARK_IGNORED_SURV_MODIFY 0x40
+#define FAN_MARK_FLUSH 0x80
+#define FAN_ALL_MARK_FLAGS (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_DONT_FOLLOW | FAN_MARK_ONLYDIR | FAN_MARK_MOUNT | FAN_MARK_IGNORED_MASK | FAN_MARK_IGNORED_SURV_MODIFY | FAN_MARK_FLUSH)
+#define FAN_ALL_EVENTS (FAN_ACCESS | FAN_MODIFY | FAN_CLOSE | FAN_OPEN)
+#define FAN_ALL_PERM_EVENTS (FAN_OPEN_PERM | FAN_ACCESS_PERM)
+#define FAN_ALL_OUTGOING_EVENTS (FAN_ALL_EVENTS | FAN_ALL_PERM_EVENTS | FAN_Q_OVERFLOW)
+#define FANOTIFY_METADATA_VERSION 3
+#define FAN_ALLOW 0x01
+#define FAN_DENY 0x02
+#define FAN_NOFD -1
+#define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata))
+#define FAN_EVENT_NEXT(meta, len) ((len) -= (meta)->event_len, (struct fanotify_event_metadata*)(((char *)(meta)) + (meta)->event_len))
+#define FAN_EVENT_OK(meta, len) ((long)(len) >= (long)FAN_EVENT_METADATA_LEN && (long)(meta)->event_len >= (long)FAN_EVENT_METADATA_LEN && (long)(meta)->event_len <= (long)(len))
+
+int fanotify_init(unsigned, unsigned);
+int fanotify_mark(int, unsigned, unsigned long long, int, const char *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/fcntl.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/fcntl.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/fcntl.h	(revision 331)
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h>
+#include <fcntl.h>
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/file.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/file.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/file.h	(revision 331)
@@ -0,0 +1,21 @@
+#ifndef _SYS_FILE_H
+#define _SYS_FILE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LOCK_SH	1
+#define LOCK_EX	2
+#define LOCK_NB	4
+#define LOCK_UN	8
+
+#define L_SET 0
+#define L_INCR 1
+#define L_XTND 2
+
+int flock(int, int);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/fsuid.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/fsuid.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/fsuid.h	(revision 331)
@@ -0,0 +1,20 @@
+#ifndef _SYS_FSUID_H
+#define _SYS_FSUID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_uid_t
+#define __NEED_gid_t
+
+#include <bits/alltypes.h>
+
+int setfsuid(uid_t);
+int setfsgid(gid_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/inotify.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/inotify.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/inotify.h	(revision 331)
@@ -0,0 +1,57 @@
+#ifndef _SYS_INOTIFY_H
+#define _SYS_INOTIFY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <fcntl.h>
+
+struct inotify_event {
+	int wd;
+	uint32_t mask, cookie, len;
+	char name[];
+};
+
+#define IN_CLOEXEC O_CLOEXEC
+#define IN_NONBLOCK O_NONBLOCK
+
+#define IN_ACCESS        0x00000001
+#define IN_MODIFY        0x00000002
+#define IN_ATTRIB        0x00000004
+#define IN_CLOSE_WRITE   0x00000008
+#define IN_CLOSE_NOWRITE 0x00000010
+#define IN_CLOSE         (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
+#define IN_OPEN          0x00000020
+#define IN_MOVED_FROM    0x00000040
+#define IN_MOVED_TO      0x00000080
+#define IN_MOVE          (IN_MOVED_FROM | IN_MOVED_TO)
+#define IN_CREATE        0x00000100
+#define IN_DELETE        0x00000200
+#define IN_DELETE_SELF   0x00000400
+#define IN_MOVE_SELF     0x00000800
+#define IN_ALL_EVENTS    0x00000fff
+
+#define IN_UNMOUNT       0x00002000
+#define IN_Q_OVERFLOW    0x00004000
+#define IN_IGNORED       0x00008000
+
+#define IN_ONLYDIR       0x01000000
+#define IN_DONT_FOLLOW   0x02000000
+#define IN_EXCL_UNLINK   0x04000000
+#define IN_MASK_ADD      0x20000000
+
+#define IN_ISDIR         0x40000000
+#define IN_ONESHOT       0x80000000
+
+int inotify_init(void);
+int inotify_init1(int);
+int inotify_add_watch(int, const char *, uint32_t);
+int inotify_rm_watch(int, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/io.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/io.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/io.h	(revision 331)
@@ -0,0 +1,17 @@
+#ifndef	_SYS_IO_H
+#define	_SYS_IO_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <bits/io.h>
+
+int iopl(int);
+int ioperm(unsigned long, unsigned long, int);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/ioctl.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/ioctl.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/ioctl.h	(revision 331)
@@ -0,0 +1,14 @@
+#ifndef	_SYS_IOCTL_H
+#define	_SYS_IOCTL_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bits/ioctl.h>
+
+int ioctl (int, int, ...);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/ipc.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/ipc.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/ipc.h	(revision 331)
@@ -0,0 +1,42 @@
+#ifndef _SYS_IPC_H
+#define _SYS_IPC_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_uid_t
+#define __NEED_gid_t
+#define __NEED_mode_t
+#define __NEED_key_t
+
+#include <bits/alltypes.h>
+
+#define __ipc_perm_key __key
+#define __ipc_perm_seq __seq
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __key key
+#define __seq seq
+#endif
+
+#include <bits/ipc.h>
+
+#define IPC_CREAT  01000
+#define IPC_EXCL   02000
+#define IPC_NOWAIT 04000
+
+#define IPC_RMID 0
+#define IPC_SET  1
+#define IPC_STAT 2
+#define IPC_INFO 3
+
+#define IPC_PRIVATE ((key_t) 0)
+
+key_t ftok (const char *, int);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/kd.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/kd.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/kd.h	(revision 331)
@@ -0,0 +1,8 @@
+#ifndef _SYS_KD_H
+#define _SYS_KD_H
+
+#define _LINUX_TYPES_H
+#include <linux/kd.h>
+#undef _LINUX_TYPES_H
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/klog.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/klog.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/klog.h	(revision 331)
@@ -0,0 +1,14 @@
+#ifndef	_SYS_KLOG_H
+#define	_SYS_KLOG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int klogctl (int, char *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/mman.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/mman.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/mman.h	(revision 331)
@@ -0,0 +1,118 @@
+#ifndef	_SYS_MMAN_H
+#define	_SYS_MMAN_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_mode_t
+#define __NEED_size_t
+#define __NEED_off_t
+
+#if defined(_GNU_SOURCE)
+#define __NEED_ssize_t
+#endif
+
+#include <bits/alltypes.h>
+
+#define MAP_FAILED ((void *) -1)
+
+#define MAP_SHARED     0x01
+#define MAP_PRIVATE    0x02
+#define MAP_TYPE       0x0f
+#define MAP_FIXED      0x10
+#define MAP_ANON       0x20
+#define MAP_ANONYMOUS  MAP_ANON
+#define MAP_NORESERVE  0x4000
+#define MAP_GROWSDOWN  0x0100
+#define MAP_DENYWRITE  0x0800
+#define MAP_EXECUTABLE 0x1000
+#define MAP_LOCKED     0x2000
+#define MAP_POPULATE   0x8000
+#define MAP_NONBLOCK   0x10000
+#define MAP_STACK      0x20000
+#define MAP_HUGETLB    0x40000
+#define MAP_FILE       0
+
+#define PROT_NONE      0
+#define PROT_READ      1
+#define PROT_WRITE     2
+#define PROT_EXEC      4
+#define PROT_GROWSDOWN 0x01000000
+#define PROT_GROWSUP   0x02000000
+
+#define MS_ASYNC       1
+#define MS_INVALIDATE  2
+#define MS_SYNC        4
+
+#define MCL_CURRENT    1
+#define MCL_FUTURE     2
+#define MCL_ONFAULT    4
+
+#define POSIX_MADV_NORMAL     0
+#define POSIX_MADV_RANDOM     1
+#define POSIX_MADV_SEQUENTIAL 2
+#define POSIX_MADV_WILLNEED   3
+#define POSIX_MADV_DONTNEED   4
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MADV_NORMAL      0
+#define MADV_RANDOM      1
+#define MADV_SEQUENTIAL  2
+#define MADV_WILLNEED    3
+#define MADV_DONTNEED    4
+#define MADV_FREE        8
+#define MADV_REMOVE      9
+#define MADV_DONTFORK    10
+#define MADV_DOFORK      11
+#define MADV_MERGEABLE   12
+#define MADV_UNMERGEABLE 13
+#define MADV_HUGEPAGE    14
+#define MADV_NOHUGEPAGE  15
+#define MADV_DONTDUMP    16
+#define MADV_DODUMP      17
+#define MADV_HWPOISON    100
+#define MADV_SOFT_OFFLINE 101
+#endif
+
+#include <bits/mman.h>
+
+void *mmap (void *, size_t, int, int, int, off_t);
+int munmap (void *, size_t);
+
+int mprotect (void *, size_t, int);
+int msync (void *, size_t, int);
+
+int posix_madvise (void *, size_t, int);
+
+int mlock (const void *, size_t);
+int munlock (const void *, size_t);
+int mlockall (int);
+int munlockall (void);
+
+#ifdef _GNU_SOURCE
+#define MREMAP_MAYMOVE 1
+#define MREMAP_FIXED 2
+void *mremap (void *, size_t, size_t, int, ...);
+int remap_file_pages (void *, size_t, int, size_t, int);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define MLOCK_ONFAULT   0x01
+int madvise (void *, size_t, int);
+int mincore (void *, size_t, unsigned char *);
+#endif
+
+int shm_open (const char *, int, mode_t);
+int shm_unlink (const char *);
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define mmap64 mmap
+#define off64_t off_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/mount.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/mount.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/mount.h	(revision 331)
@@ -0,0 +1,74 @@
+#ifndef _SYS_MOUNT_H
+#define _SYS_MOUNT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/ioctl.h>
+
+#define BLKROSET   _IO(0x12, 93)
+#define BLKROGET   _IO(0x12, 94)
+#define BLKRRPART  _IO(0x12, 95)
+#define BLKGETSIZE _IO(0x12, 96)
+#define BLKFLSBUF  _IO(0x12, 97)
+#define BLKRASET   _IO(0x12, 98)
+#define BLKRAGET   _IO(0x12, 99)
+#define BLKFRASET  _IO(0x12,100)
+#define BLKFRAGET  _IO(0x12,101)
+#define BLKSECTSET _IO(0x12,102)
+#define BLKSECTGET _IO(0x12,103)
+#define BLKSSZGET  _IO(0x12,104)
+#define BLKBSZGET  _IOR(0x12,112,size_t)
+#define BLKBSZSET  _IOW(0x12,113,size_t)
+#define BLKGETSIZE64 _IOR(0x12,114,size_t)
+
+#define MS_RDONLY      1
+#define MS_NOSUID      2
+#define MS_NODEV       4
+#define MS_NOEXEC      8
+#define MS_SYNCHRONOUS 16
+#define MS_REMOUNT     32
+#define MS_MANDLOCK    64
+#define MS_DIRSYNC     128
+#define MS_NOATIME     1024
+#define MS_NODIRATIME  2048
+#define MS_BIND        4096
+#define MS_MOVE        8192
+#define MS_REC         16384
+#define MS_SILENT      32768
+#define MS_POSIXACL    (1<<16)
+#define MS_UNBINDABLE  (1<<17)
+#define MS_PRIVATE     (1<<18)
+#define MS_SLAVE       (1<<19)
+#define MS_SHARED      (1<<20)
+#define MS_RELATIME    (1<<21)
+#define MS_KERNMOUNT   (1<<22)
+#define MS_I_VERSION   (1<<23)
+#define MS_STRICTATIME (1<<24)
+#define MS_LAZYTIME    (1<<25)
+#define MS_NOREMOTELOCK (1<<27)
+#define MS_NOSEC       (1<<28)
+#define MS_BORN        (1<<29)
+#define MS_ACTIVE      (1<<30)
+#define MS_NOUSER      (1U<<31)
+
+#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION|MS_LAZYTIME)
+
+#define MS_MGC_VAL 0xc0ed0000
+#define MS_MGC_MSK 0xffff0000
+
+#define MNT_FORCE       1
+#define MNT_DETACH      2
+#define MNT_EXPIRE      4
+#define UMOUNT_NOFOLLOW 8
+
+int mount(const char *, const char *, const char *, unsigned long, const void *);
+int umount(const char *);
+int umount2(const char *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/msg.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/msg.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/msg.h	(revision 331)
@@ -0,0 +1,52 @@
+#ifndef _SYS_MSG_H
+#define _SYS_MSG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/ipc.h>
+
+#define __NEED_pid_t
+#define __NEED_key_t
+#define __NEED_time_t
+#define __NEED_size_t
+#define __NEED_ssize_t
+
+#include <bits/alltypes.h>
+
+typedef unsigned long msgqnum_t;
+typedef unsigned long msglen_t;
+
+#include <bits/msg.h>
+
+#define __msg_cbytes msg_cbytes
+
+#define MSG_NOERROR 010000
+#define MSG_EXCEPT  020000
+
+#define MSG_STAT 11
+#define MSG_INFO 12
+
+struct msginfo {
+	int msgpool, msgmap, msgmax, msgmnb, msgmni, msgssz, msgtql;
+	unsigned short msgseg;
+};
+
+int msgctl (int, int, struct msqid_ds *);
+int msgget (key_t, int);
+ssize_t msgrcv (int, void *, size_t, long, int);
+int msgsnd (int, const void *, size_t, int);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+struct msgbuf {
+	long mtype;
+	char mtext[1];
+};
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/mtio.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/mtio.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/mtio.h	(revision 331)
@@ -0,0 +1,188 @@
+#ifndef _SYS_MTIO_H
+#define _SYS_MTIO_H
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+struct mtop {
+	short mt_op;
+	int mt_count;
+};
+
+#define _IOT_mtop _IOT (_IOTS (short), 1, _IOTS (int), 1, 0, 0)
+#define _IOT_mtget _IOT (_IOTS (long), 7, 0, 0, 0, 0)
+#define _IOT_mtpos _IOT_SIMPLE (long)
+#define _IOT_mtconfiginfo _IOT (_IOTS (long), 2, _IOTS (short), 3, _IOTS (long), 1)
+
+
+#define MTRESET 0
+#define MTFSF	1
+#define MTBSF	2
+#define MTFSR	3
+#define MTBSR	4
+#define MTWEOF	5
+#define MTREW	6
+#define MTOFFL	7
+#define MTNOP	8
+#define MTRETEN 9
+#define MTBSFM	10
+#define MTFSFM  11
+#define MTEOM	12
+#define MTERASE 13
+#define MTRAS1  14
+#define MTRAS2	15
+#define MTRAS3  16
+#define MTSETBLK 20
+#define MTSETDENSITY 21
+#define MTSEEK	22
+#define MTTELL	23
+#define MTSETDRVBUFFER 24
+#define MTFSS	25
+#define MTBSS	26
+#define MTWSM	27
+#define MTLOCK  28
+#define MTUNLOCK 29
+#define MTLOAD  30
+#define MTUNLOAD 31
+#define MTCOMPRESSION 32
+#define MTSETPART 33
+#define MTMKPART  34
+
+struct mtget {
+	long mt_type;
+	long mt_resid;
+	long mt_dsreg;
+	long mt_gstat;
+	long mt_erreg;
+	int mt_fileno;
+	int mt_blkno;
+};
+
+#define MT_ISUNKNOWN		0x01
+#define MT_ISQIC02		0x02
+#define MT_ISWT5150		0x03
+#define MT_ISARCHIVE_5945L2	0x04
+#define MT_ISCMSJ500		0x05
+#define MT_ISTDC3610		0x06
+#define MT_ISARCHIVE_VP60I	0x07
+#define MT_ISARCHIVE_2150L	0x08
+#define MT_ISARCHIVE_2060L	0x09
+#define MT_ISARCHIVESC499	0x0A
+#define MT_ISQIC02_ALL_FEATURES	0x0F
+#define MT_ISWT5099EEN24	0x11
+#define MT_ISTEAC_MT2ST		0x12
+#define MT_ISEVEREX_FT40A	0x32
+#define MT_ISDDS1		0x51
+#define MT_ISDDS2		0x52
+#define MT_ISSCSI1		0x71
+#define MT_ISSCSI2		0x72
+#define MT_ISFTAPE_UNKNOWN	0x800000
+#define MT_ISFTAPE_FLAG		0x800000
+
+struct mt_tape_info {
+	long t_type;
+	char *t_name;
+};
+
+#define MT_TAPE_INFO \
+{									      \
+	{MT_ISUNKNOWN,		"Unknown type of tape device"},		      \
+	{MT_ISQIC02,		"Generic QIC-02 tape streamer"},	      \
+	{MT_ISWT5150,		"Wangtek 5150, QIC-150"},		      \
+	{MT_ISARCHIVE_5945L2,	"Archive 5945L-2"},			      \
+	{MT_ISCMSJ500,		"CMS Jumbo 500"},			      \
+	{MT_ISTDC3610,		"Tandberg TDC 3610, QIC-24"},		      \
+	{MT_ISARCHIVE_VP60I,	"Archive VP60i, QIC-02"},		      \
+	{MT_ISARCHIVE_2150L,	"Archive Viper 2150L"},			      \
+	{MT_ISARCHIVE_2060L,	"Archive Viper 2060L"},			      \
+	{MT_ISARCHIVESC499,	"Archive SC-499 QIC-36 controller"},	      \
+	{MT_ISQIC02_ALL_FEATURES, "Generic QIC-02 tape, all features"},	      \
+	{MT_ISWT5099EEN24,	"Wangtek 5099-een24, 60MB"},		      \
+	{MT_ISTEAC_MT2ST,	"Teac MT-2ST 155mb data cassette drive"},     \
+	{MT_ISEVEREX_FT40A,	"Everex FT40A, QIC-40"},		      \
+	{MT_ISSCSI1,		"Generic SCSI-1 tape"},			      \
+	{MT_ISSCSI2,		"Generic SCSI-2 tape"},			      \
+	{0, 0}								      \
+}
+
+struct mtpos {
+	long mt_blkno;
+};
+
+struct mtconfiginfo  {
+	long mt_type;
+	long ifc_type;
+	unsigned short irqnr;
+	unsigned short dmanr;
+	unsigned short port;
+	unsigned long debug;
+	unsigned have_dens:1;
+	unsigned have_bsf:1;
+	unsigned have_fsr:1;
+	unsigned have_bsr:1;
+	unsigned have_eod:1;
+	unsigned have_seek:1;
+	unsigned have_tell:1;
+	unsigned have_ras1:1;
+	unsigned have_ras2:1;
+	unsigned have_ras3:1;
+	unsigned have_qfa:1;
+	unsigned pad1:5;
+	char reserved[10];
+};
+
+#define	MTIOCTOP _IOW('m', 1, struct mtop)
+#define	MTIOCGET _IOR('m', 2, struct mtget)
+#define	MTIOCPOS _IOR('m', 3, struct mtpos)
+
+#define	MTIOCGETCONFIG	_IOR('m', 4, struct mtconfiginfo)
+#define	MTIOCSETCONFIG	_IOW('m', 5, struct mtconfiginfo)
+
+#define GMT_EOF(x)              ((x) & 0x80000000)
+#define GMT_BOT(x)              ((x) & 0x40000000)
+#define GMT_EOT(x)              ((x) & 0x20000000)
+#define GMT_SM(x)               ((x) & 0x10000000)
+#define GMT_EOD(x)              ((x) & 0x08000000)
+#define GMT_WR_PROT(x)          ((x) & 0x04000000)
+#define GMT_ONLINE(x)           ((x) & 0x01000000)
+#define GMT_D_6250(x)           ((x) & 0x00800000)
+#define GMT_D_1600(x)           ((x) & 0x00400000)
+#define GMT_D_800(x)            ((x) & 0x00200000)
+#define GMT_DR_OPEN(x)          ((x) & 0x00040000)
+#define GMT_IM_REP_EN(x)        ((x) & 0x00010000)
+
+#define MT_ST_BLKSIZE_SHIFT	0
+#define MT_ST_BLKSIZE_MASK	0xffffff
+#define MT_ST_DENSITY_SHIFT	24
+#define MT_ST_DENSITY_MASK	0xff000000
+#define MT_ST_SOFTERR_SHIFT	0
+#define MT_ST_SOFTERR_MASK	0xffff
+#define MT_ST_OPTIONS		0xf0000000
+#define MT_ST_BOOLEANS		0x10000000
+#define MT_ST_SETBOOLEANS	0x30000000
+#define MT_ST_CLEARBOOLEANS	0x40000000
+#define MT_ST_WRITE_THRESHOLD	0x20000000
+#define MT_ST_DEF_BLKSIZE	0x50000000
+#define MT_ST_DEF_OPTIONS	0x60000000
+#define MT_ST_BUFFER_WRITES	0x1
+#define MT_ST_ASYNC_WRITES	0x2
+#define MT_ST_READ_AHEAD	0x4
+#define MT_ST_DEBUGGING		0x8
+#define MT_ST_TWO_FM		0x10
+#define MT_ST_FAST_MTEOM	0x20
+#define MT_ST_AUTO_LOCK		0x40
+#define MT_ST_DEF_WRITES	0x80
+#define MT_ST_CAN_BSR		0x100
+#define MT_ST_NO_BLKLIMS	0x200
+#define MT_ST_CAN_PARTITIONS    0x400
+#define MT_ST_SCSI2LOGICAL      0x800
+#define MT_ST_CLEAR_DEFAULT	0xfffff
+#define MT_ST_DEF_DENSITY	(MT_ST_DEF_OPTIONS | 0x100000)
+#define MT_ST_DEF_COMPRESSION	(MT_ST_DEF_OPTIONS | 0x200000)
+#define MT_ST_DEF_DRVBUFFER	(MT_ST_DEF_OPTIONS | 0x300000)
+#define MT_ST_HPLOADER_OFFSET 10000
+#ifndef DEFTAPE
+# define DEFTAPE	"/dev/tape"
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/param.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/param.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/param.h	(revision 331)
@@ -0,0 +1,35 @@
+#ifndef _SYS_PARAM_H
+#define _SYS_PARAM_H
+
+#define MAXSYMLINKS 20
+#define MAXHOSTNAMELEN 64
+#define MAXNAMLEN 255
+#define MAXPATHLEN 4096
+#define NBBY 8
+#define NGROUPS 32
+#define CANBSIZ 255
+#define NOFILE 256
+#define NCARGS 131072
+#define DEV_BSIZE 512
+#define NOGROUP (-1)
+
+#undef MIN
+#undef MAX
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MAX(a,b) (((a)>(b))?(a):(b))
+
+#define __bitop(x,i,o) ((x)[(i)/8] o (1<<(i)%8))
+#define setbit(x,i) __bitop(x,i,|=)
+#define clrbit(x,i) __bitop(x,i,&=~)
+#define isset(x,i) __bitop(x,i,&)
+#define isclr(x,i) !isset(x,i)
+
+#define howmany(n,d) (((n)+((d)-1))/(d))
+#define roundup(n,d) (howmany(n,d)*(d))
+#define powerof2(n) !(((n)-1) & (n))
+
+#include <sys/resource.h>
+#include <endian.h>
+#include <limits.h>
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/personality.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/personality.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/personality.h	(revision 331)
@@ -0,0 +1,46 @@
+#ifndef _PERSONALITY_H
+#define _PERSONALITY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ADDR_NO_RANDOMIZE  0x0040000
+#define MMAP_PAGE_ZERO     0x0100000
+#define ADDR_COMPAT_LAYOUT 0x0200000
+#define READ_IMPLIES_EXEC  0x0400000
+#define ADDR_LIMIT_32BIT   0x0800000
+#define SHORT_INODE        0x1000000
+#define WHOLE_SECONDS      0x2000000
+#define STICKY_TIMEOUTS    0x4000000
+#define ADDR_LIMIT_3GB     0x8000000
+
+#define PER_LINUX 0
+#define PER_LINUX_32BIT ADDR_LIMIT_32BIT
+#define PER_SVR4 (1 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO)
+#define PER_SVR3 (2 | STICKY_TIMEOUTS | SHORT_INODE)
+#define PER_SCOSVR3 (3 | STICKY_TIMEOUTS | WHOLE_SECONDS | SHORT_INODE)
+#define PER_OSR5 (3 | STICKY_TIMEOUTS | WHOLE_SECONDS)
+#define PER_WYSEV386 (4 | STICKY_TIMEOUTS | SHORT_INODE)
+#define PER_ISCR4 (5 | STICKY_TIMEOUTS)
+#define PER_BSD 6
+#define PER_SUNOS (6 | STICKY_TIMEOUTS)
+#define PER_XENIX (7 | STICKY_TIMEOUTS | SHORT_INODE)
+#define PER_LINUX32 8
+#define PER_LINUX32_3GB (8 | ADDR_LIMIT_3GB)
+#define PER_IRIX32 (9 | STICKY_TIMEOUTS)
+#define PER_IRIXN32 (0xa | STICKY_TIMEOUTS)
+#define PER_IRIX64 (0x0b | STICKY_TIMEOUTS)
+#define PER_RISCOS 0xc
+#define PER_SOLARIS (0xd | STICKY_TIMEOUTS)
+#define PER_UW7 (0xe | STICKY_TIMEOUTS | MMAP_PAGE_ZERO)
+#define PER_OSF4 0xf
+#define PER_HPUX 0x10
+#define PER_MASK 0xff
+
+int personality(unsigned long);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/poll.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/poll.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/poll.h	(revision 331)
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <sys/poll.h> to <poll.h>
+#include <poll.h>
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/prctl.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/prctl.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/prctl.h	(revision 331)
@@ -0,0 +1,139 @@
+#ifndef _SYS_PRCTL_H
+#define _SYS_PRCTL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define PR_SET_PDEATHSIG  1
+#define PR_GET_PDEATHSIG  2
+#define PR_GET_DUMPABLE   3
+#define PR_SET_DUMPABLE   4
+#define PR_GET_UNALIGN   5
+#define PR_SET_UNALIGN   6
+#define PR_UNALIGN_NOPRINT 1
+#define PR_UNALIGN_SIGBUS 2
+#define PR_GET_KEEPCAPS   7
+#define PR_SET_KEEPCAPS   8
+#define PR_GET_FPEMU  9
+#define PR_SET_FPEMU 10
+#define PR_FPEMU_NOPRINT 1
+#define PR_FPEMU_SIGFPE 2
+#define PR_GET_FPEXC 11
+#define PR_SET_FPEXC 12
+#define PR_FP_EXC_SW_ENABLE 0x80
+#define PR_FP_EXC_DIV  0x010000
+#define PR_FP_EXC_OVF  0x020000
+#define PR_FP_EXC_UND  0x040000
+#define PR_FP_EXC_RES  0x080000
+#define PR_FP_EXC_INV  0x100000
+#define PR_FP_EXC_DISABLED 0
+#define PR_FP_EXC_NONRECOV 1
+#define PR_FP_EXC_ASYNC 2
+#define PR_FP_EXC_PRECISE 3
+#define PR_GET_TIMING   13
+#define PR_SET_TIMING   14
+#define PR_TIMING_STATISTICAL  0
+#define PR_TIMING_TIMESTAMP    1
+#define PR_SET_NAME    15
+#define PR_GET_NAME    16
+#define PR_GET_ENDIAN 19
+#define PR_SET_ENDIAN 20
+#define PR_ENDIAN_BIG 0
+#define PR_ENDIAN_LITTLE 1
+#define PR_ENDIAN_PPC_LITTLE 2
+#define PR_GET_SECCOMP 21
+#define PR_SET_SECCOMP 22
+#define PR_CAPBSET_READ 23
+#define PR_CAPBSET_DROP 24
+#define PR_GET_TSC 25
+#define PR_SET_TSC 26
+#define PR_TSC_ENABLE 1
+#define PR_TSC_SIGSEGV 2
+#define PR_GET_SECUREBITS 27
+#define PR_SET_SECUREBITS 28
+#define PR_SET_TIMERSLACK 29
+#define PR_GET_TIMERSLACK 30
+
+#define PR_TASK_PERF_EVENTS_DISABLE             31
+#define PR_TASK_PERF_EVENTS_ENABLE              32
+
+#define PR_MCE_KILL     33
+#define PR_MCE_KILL_CLEAR   0
+#define PR_MCE_KILL_SET     1
+#define PR_MCE_KILL_LATE    0
+#define PR_MCE_KILL_EARLY   1
+#define PR_MCE_KILL_DEFAULT 2
+#define PR_MCE_KILL_GET 34
+
+#define PR_SET_MM               35
+#define PR_SET_MM_START_CODE           1
+#define PR_SET_MM_END_CODE             2
+#define PR_SET_MM_START_DATA           3
+#define PR_SET_MM_END_DATA             4
+#define PR_SET_MM_START_STACK          5
+#define PR_SET_MM_START_BRK            6
+#define PR_SET_MM_BRK                  7
+#define PR_SET_MM_ARG_START            8
+#define PR_SET_MM_ARG_END              9
+#define PR_SET_MM_ENV_START            10
+#define PR_SET_MM_ENV_END              11
+#define PR_SET_MM_AUXV                 12
+#define PR_SET_MM_EXE_FILE             13
+#define PR_SET_MM_MAP                  14
+#define PR_SET_MM_MAP_SIZE             15
+
+struct prctl_mm_map {
+	uint64_t start_code;
+	uint64_t end_code;
+	uint64_t start_data;
+	uint64_t end_data;
+	uint64_t start_brk;
+	uint64_t brk;
+	uint64_t start_stack;
+	uint64_t arg_start;
+	uint64_t arg_end;
+	uint64_t env_start;
+	uint64_t env_end;
+	uint64_t *auxv;
+	uint32_t auxv_size;
+	uint32_t exe_fd;
+};
+
+#define PR_SET_PTRACER 0x59616d61
+#define PR_SET_PTRACER_ANY (-1UL)
+
+#define PR_SET_CHILD_SUBREAPER  36
+#define PR_GET_CHILD_SUBREAPER  37
+
+#define PR_SET_NO_NEW_PRIVS     38
+#define PR_GET_NO_NEW_PRIVS     39
+
+#define PR_GET_TID_ADDRESS      40
+
+#define PR_SET_THP_DISABLE      41
+#define PR_GET_THP_DISABLE      42
+
+#define PR_MPX_ENABLE_MANAGEMENT  43
+#define PR_MPX_DISABLE_MANAGEMENT 44
+
+#define PR_SET_FP_MODE          45
+#define PR_GET_FP_MODE          46
+#define PR_FP_MODE_FR (1 << 0)
+#define PR_FP_MODE_FRE (1 << 1)
+
+#define PR_CAP_AMBIENT          47
+#define PR_CAP_AMBIENT_IS_SET   1
+#define PR_CAP_AMBIENT_RAISE    2
+#define PR_CAP_AMBIENT_LOWER    3
+#define PR_CAP_AMBIENT_CLEAR_ALL 4
+
+int prctl (int, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/procfs.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/procfs.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/procfs.h	(revision 331)
@@ -0,0 +1,64 @@
+#ifndef _SYS_PROCFS_H
+#define _SYS_PROCFS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/user.h>
+
+struct elf_siginfo {
+	int si_signo;
+	int si_code;
+	int si_errno;
+};
+
+struct elf_prstatus {
+	struct elf_siginfo pr_info;
+	short int pr_cursig;
+	unsigned long int pr_sigpend;
+	unsigned long int pr_sighold;
+	pid_t pr_pid;
+	pid_t pr_ppid;
+	pid_t pr_pgrp;
+	pid_t pr_sid;
+	struct timeval pr_utime;
+	struct timeval pr_stime;
+	struct timeval pr_cutime;
+	struct timeval pr_cstime;
+	elf_gregset_t pr_reg;
+	int pr_fpvalid;
+};
+
+#define ELF_PRARGSZ 80
+
+struct elf_prpsinfo {
+	char pr_state;
+	char pr_sname;
+	char pr_zomb;
+	char pr_nice;
+	unsigned long int pr_flag;
+#if UINTPTR_MAX == 0xffffffff
+	unsigned short int pr_uid;
+	unsigned short int pr_gid;
+#else
+	unsigned int pr_uid;
+	unsigned int pr_gid;
+#endif
+	int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+	char pr_fname[16];
+	char pr_psargs[ELF_PRARGSZ];
+};
+
+typedef void *psaddr_t;
+typedef elf_gregset_t prgregset_t;
+typedef elf_fpregset_t prfpregset_t;
+typedef pid_t lwpid_t;
+typedef struct elf_prstatus prstatus_t;
+typedef struct elf_prpsinfo prpsinfo_t;
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/ptrace.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/ptrace.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/ptrace.h	(revision 331)
@@ -0,0 +1,100 @@
+#ifndef _SYS_PTRACE_H
+#define _SYS_PTRACE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define PTRACE_TRACEME 0
+#define PT_TRACE_ME PTRACE_TRACEME
+
+#define PTRACE_PEEKTEXT 1
+#define PTRACE_PEEKDATA 2
+#define PTRACE_PEEKUSER 3
+#define PTRACE_POKETEXT 4
+#define PTRACE_POKEDATA 5
+#define PTRACE_POKEUSER 6
+#define PTRACE_CONT 7
+#define PTRACE_KILL 8
+#define PTRACE_SINGLESTEP 9
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+#define PTRACE_ATTACH 16
+#define PTRACE_DETACH 17
+#define PTRACE_GETFPXREGS 18
+#define PTRACE_SETFPXREGS 19
+#define PTRACE_SYSCALL 24
+#define PTRACE_SETOPTIONS 0x4200
+#define PTRACE_GETEVENTMSG 0x4201
+#define PTRACE_GETSIGINFO 0x4202
+#define PTRACE_SETSIGINFO 0x4203
+#define PTRACE_GETREGSET 0x4204
+#define PTRACE_SETREGSET 0x4205
+#define PTRACE_SEIZE 0x4206
+#define PTRACE_INTERRUPT 0x4207
+#define PTRACE_LISTEN 0x4208
+#define PTRACE_PEEKSIGINFO 0x4209
+#define PTRACE_GETSIGMASK 0x420a
+#define PTRACE_SETSIGMASK 0x420b
+#define PTRACE_SECCOMP_GET_FILTER 0x420c
+
+#define PT_READ_I PTRACE_PEEKTEXT
+#define PT_READ_D PTRACE_PEEKDATA
+#define PT_READ_U PTRACE_PEEKUSER
+#define PT_WRITE_I PTRACE_POKETEXT
+#define PT_WRITE_D PTRACE_POKEDATA
+#define PT_WRITE_U PTRACE_POKEUSER
+#define PT_CONTINUE PTRACE_CONT
+#define PT_KILL PTRACE_KILL
+#define PT_STEP PTRACE_SINGLESTEP
+#define PT_GETREGS PTRACE_GETREGS
+#define PT_SETREGS PTRACE_SETREGS
+#define PT_GETFPREGS PTRACE_GETFPREGS
+#define PT_SETFPREGS PTRACE_SETFPREGS
+#define PT_ATTACH PTRACE_ATTACH
+#define PT_DETACH PTRACE_DETACH
+#define PT_GETFPXREGS PTRACE_GETFPXREGS
+#define PT_SETFPXREGS PTRACE_SETFPXREGS
+#define PT_SYSCALL PTRACE_SYSCALL
+#define PT_SETOPTIONS PTRACE_SETOPTIONS
+#define PT_GETEVENTMSG PTRACE_GETEVENTMSG
+#define PT_GETSIGINFO PTRACE_GETSIGINFO
+#define PT_SETSIGINFO PTRACE_SETSIGINFO
+
+#define PTRACE_O_TRACESYSGOOD   0x00000001
+#define PTRACE_O_TRACEFORK      0x00000002
+#define PTRACE_O_TRACEVFORK     0x00000004
+#define PTRACE_O_TRACECLONE     0x00000008
+#define PTRACE_O_TRACEEXEC      0x00000010
+#define PTRACE_O_TRACEVFORKDONE 0x00000020
+#define PTRACE_O_TRACEEXIT      0x00000040
+#define PTRACE_O_TRACESECCOMP   0x00000080
+#define PTRACE_O_EXITKILL       0x00100000
+#define PTRACE_O_SUSPEND_SECCOMP 0x00200000
+#define PTRACE_O_MASK           0x003000ff
+
+#define PTRACE_EVENT_FORK 1
+#define PTRACE_EVENT_VFORK 2
+#define PTRACE_EVENT_CLONE 3
+#define PTRACE_EVENT_EXEC 4
+#define PTRACE_EVENT_VFORK_DONE 5
+#define PTRACE_EVENT_EXIT 6
+#define PTRACE_EVENT_SECCOMP 7
+
+#define PTRACE_PEEKSIGINFO_SHARED 1
+
+struct ptrace_peeksiginfo_args {
+	uint64_t off;
+	uint32_t flags;
+	int32_t nr;
+};
+
+long ptrace(int, ...);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/quota.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/quota.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/quota.h	(revision 331)
@@ -0,0 +1,102 @@
+#ifndef _SYS_QUOTA_H
+#define _SYS_QUOTA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define _LINUX_QUOTA_VERSION 2
+
+#define dbtob(num) ((num) << 10)
+#define btodb(num) ((num) >> 10)
+#define fs_to_dq_blocks(num, blksize) (((num) * (blksize)) / 1024)
+
+#define MAX_IQ_TIME 604800
+#define MAX_DQ_TIME 604800
+
+#define MAXQUOTAS 2
+#define USRQUOTA  0
+#define GRPQUOTA  1
+
+#define INITQFNAMES { "user", "group", "undefined" };
+
+#define QUOTAFILENAME "quota"
+#define QUOTAGROUP "staff"
+
+#define NR_DQHASH 43
+#define NR_DQUOTS 256
+
+#define SUBCMDMASK       0x00ff
+#define SUBCMDSHIFT      8
+#define QCMD(cmd, type)  (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))
+
+#define Q_SYNC     0x800001
+#define Q_QUOTAON  0x800002
+#define Q_QUOTAOFF 0x800003
+#define Q_GETFMT   0x800004
+#define Q_GETINFO  0x800005
+#define Q_SETINFO  0x800006
+#define Q_GETQUOTA 0x800007
+#define Q_SETQUOTA 0x800008
+
+#define	QFMT_VFS_OLD 1
+#define	QFMT_VFS_V0 2
+#define QFMT_OCFS2 3
+#define	QFMT_VFS_V1 4
+
+#define QIF_BLIMITS	1
+#define QIF_SPACE	2
+#define QIF_ILIMITS	4
+#define QIF_INODES	8
+#define QIF_BTIME	16
+#define QIF_ITIME	32
+#define QIF_LIMITS	(QIF_BLIMITS | QIF_ILIMITS)
+#define QIF_USAGE	(QIF_SPACE | QIF_INODES)
+#define QIF_TIMES	(QIF_BTIME | QIF_ITIME)
+#define QIF_ALL		(QIF_LIMITS | QIF_USAGE | QIF_TIMES)
+
+struct dqblk {
+	uint64_t dqb_bhardlimit;
+	uint64_t dqb_bsoftlimit;
+	uint64_t dqb_curspace;
+	uint64_t dqb_ihardlimit;
+	uint64_t dqb_isoftlimit;
+	uint64_t dqb_curinodes;
+	uint64_t dqb_btime;
+	uint64_t dqb_itime;
+	uint32_t dqb_valid;
+};
+
+#define	dq_bhardlimit	dq_dqb.dqb_bhardlimit
+#define	dq_bsoftlimit	dq_dqb.dqb_bsoftlimit
+#define dq_curspace	dq_dqb.dqb_curspace
+#define dq_valid	dq_dqb.dqb_valid
+#define	dq_ihardlimit	dq_dqb.dqb_ihardlimit
+#define	dq_isoftlimit	dq_dqb.dqb_isoftlimit
+#define	dq_curinodes	dq_dqb.dqb_curinodes
+#define	dq_btime	dq_dqb.dqb_btime
+#define	dq_itime	dq_dqb.dqb_itime
+
+#define dqoff(UID)      ((long long)(UID) * sizeof (struct dqblk))
+
+#define IIF_BGRACE	1
+#define IIF_IGRACE	2
+#define IIF_FLAGS	4
+#define IIF_ALL		(IIF_BGRACE | IIF_IGRACE | IIF_FLAGS)
+
+struct dqinfo {
+	uint64_t dqi_bgrace;
+	uint64_t dqi_igrace;
+	uint32_t dqi_flags;
+	uint32_t dqi_valid;
+};
+
+int quotactl(int, const char *, int, char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/reboot.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/reboot.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/reboot.h	(revision 331)
@@ -0,0 +1,20 @@
+#ifndef _SYS_REBOOT_H
+#define _SYS_REBOOT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RB_AUTOBOOT     0x01234567
+#define RB_HALT_SYSTEM  0xcdef0123
+#define RB_ENABLE_CAD   0x89abcdef
+#define RB_DISABLE_CAD  0
+#define RB_POWER_OFF    0x4321fedc
+#define RB_SW_SUSPEND   0xd000fce2
+#define RB_KEXEC        0x45584543
+
+int reboot(int);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/reg.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/reg.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/reg.h	(revision 331)
@@ -0,0 +1,9 @@
+#ifndef _SYS_REG_H
+#define _SYS_REG_H
+
+#include <limits.h>
+#include <unistd.h>
+
+#include <bits/reg.h>
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/resource.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/resource.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/resource.h	(revision 331)
@@ -0,0 +1,111 @@
+#ifndef	_SYS_RESOURCE_H
+#define	_SYS_RESOURCE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <sys/time.h>
+
+#define __NEED_id_t
+
+#ifdef _GNU_SOURCE
+#define __NEED_pid_t
+#endif
+
+#include <bits/alltypes.h>
+#include <bits/resource.h>
+
+typedef unsigned long long rlim_t;
+
+struct rlimit {
+	rlim_t rlim_cur;
+	rlim_t rlim_max;
+};
+
+struct rusage {
+	struct timeval ru_utime;
+	struct timeval ru_stime;
+	/* linux extentions, but useful */
+	long	ru_maxrss;
+	long	ru_ixrss;
+	long	ru_idrss;
+	long	ru_isrss;
+	long	ru_minflt;
+	long	ru_majflt;
+	long	ru_nswap;
+	long	ru_inblock;
+	long	ru_oublock;
+	long	ru_msgsnd;
+	long	ru_msgrcv;
+	long	ru_nsignals;
+	long	ru_nvcsw;
+	long	ru_nivcsw;
+	/* room for more... */
+	long    __reserved[16];
+};
+
+int getrlimit (int, struct rlimit *);
+int setrlimit (int, const struct rlimit *);
+int getrusage (int, struct rusage *);
+
+int getpriority (int, id_t);
+int setpriority (int, id_t, int);
+
+#ifdef _GNU_SOURCE
+int prlimit(pid_t, int, const struct rlimit *, struct rlimit *);
+#define prlimit64 prlimit
+#endif
+
+#define PRIO_MIN (-20)
+#define PRIO_MAX 20
+
+#define PRIO_PROCESS 0
+#define PRIO_PGRP    1
+#define PRIO_USER    2
+
+#define RUSAGE_SELF     0
+#define RUSAGE_CHILDREN (-1)
+#define RUSAGE_THREAD   1
+
+#define RLIM_INFINITY (~0ULL)
+#define RLIM_SAVED_CUR RLIM_INFINITY
+#define RLIM_SAVED_MAX RLIM_INFINITY
+
+#define RLIMIT_CPU     0
+#define RLIMIT_FSIZE   1
+#define RLIMIT_DATA    2
+#define RLIMIT_STACK   3
+#define RLIMIT_CORE    4
+#ifndef RLIMIT_RSS
+#define RLIMIT_RSS     5
+#define RLIMIT_NPROC   6
+#define RLIMIT_NOFILE  7
+#define RLIMIT_MEMLOCK 8
+#define RLIMIT_AS      9
+#endif
+#define RLIMIT_LOCKS   10
+#define RLIMIT_SIGPENDING 11
+#define RLIMIT_MSGQUEUE 12
+#define RLIMIT_NICE    13
+#define RLIMIT_RTPRIO  14
+#define RLIMIT_NLIMITS 15
+
+#define RLIM_NLIMITS RLIMIT_NLIMITS
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define RLIM64_INFINITY RLIM_INFINITY
+#define RLIM64_SAVED_CUR RLIM_SAVED_CUR
+#define RLIM64_SAVED_MAX RLIM_SAVED_MAX
+#define getrlimit64 getrlimit
+#define setrlimit64 setrlimit
+#define rlimit64 rlimit
+#define rlim64_t rlim_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/select.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/select.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/select.h	(revision 331)
@@ -0,0 +1,41 @@
+#ifndef _SYS_SELECT_H
+#define _SYS_SELECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_time_t
+#define __NEED_suseconds_t
+#define __NEED_struct_timeval
+#define __NEED_struct_timespec
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+#define FD_SETSIZE 32
+
+typedef unsigned long fd_mask;
+
+typedef struct {
+	unsigned long fds_bits[FD_SETSIZE / 8 / sizeof(long)];
+} fd_set;
+
+#define FD_ZERO(s) do { int __i; unsigned long *__b=(s)->fds_bits; for(__i=sizeof (fd_set)/sizeof (long); __i; __i--) *__b++=0; } while(0)
+#define FD_SET(d, s)   ((s)->fds_bits[(d)/(8*sizeof(long))] |= (1UL<<((d)%(8*sizeof(long)))))
+#define FD_CLR(d, s)   ((s)->fds_bits[(d)/(8*sizeof(long))] &= ~(1UL<<((d)%(8*sizeof(long)))))
+#define FD_ISSET(d, s) !!((s)->fds_bits[(d)/(8*sizeof(long))] & (1UL<<((d)%(8*sizeof(long)))))
+
+int select (int, fd_set *__restrict, fd_set *__restrict, fd_set *__restrict, struct timeval *__restrict);
+int pselect (int, fd_set *__restrict, fd_set *__restrict, fd_set *__restrict, const struct timespec *__restrict, const sigset_t *__restrict);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define NFDBITS (8*(int)sizeof(long))
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/sem.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/sem.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/sem.h	(revision 331)
@@ -0,0 +1,67 @@
+#ifndef _SYS_SEM_H
+#define _SYS_SEM_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_pid_t
+#define __NEED_time_t
+#ifdef _GNU_SOURCE
+#define __NEED_struct_timespec
+#endif
+#include <bits/alltypes.h>
+
+#include <sys/ipc.h>
+
+#define SEM_UNDO	0x1000
+#define GETPID		11
+#define GETVAL		12
+#define GETALL		13
+#define GETNCNT		14
+#define GETZCNT		15
+#define SETVAL		16
+#define SETALL		17
+
+#include <endian.h>
+
+#include <bits/sem.h>
+
+#define _SEM_SEMUN_UNDEFINED 1
+
+#define SEM_STAT 18
+#define SEM_INFO 19
+
+struct  seminfo {
+	int semmap;
+	int semmni;
+	int semmns;
+	int semmnu;
+	int semmsl;
+	int semopm;
+	int semume;
+	int semusz;
+	int semvmx;
+	int semaem;
+};
+
+struct sembuf {
+	unsigned short sem_num;
+	short sem_op;
+	short sem_flg;
+};
+
+int semctl(int, int, int, ...);
+int semget(key_t, int, int);
+int semop(int, struct sembuf *, size_t);
+
+#ifdef _GNU_SOURCE
+int semtimedop(int, struct sembuf *, size_t, const struct timespec *);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/sendfile.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/sendfile.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/sendfile.h	(revision 331)
@@ -0,0 +1,22 @@
+#ifndef _SYS_SENDFILE_H
+#define _SYS_SENDFILE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+#include <unistd.h>
+
+ssize_t sendfile(int, int, off_t *, size_t);
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define sendfile64 sendfile
+#define off64_t off_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/shm.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/shm.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/shm.h	(revision 331)
@@ -0,0 +1,54 @@
+#ifndef _SYS_SHM_H
+#define _SYS_SHM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_time_t
+#define __NEED_size_t
+#define __NEED_pid_t
+
+#include <bits/alltypes.h>
+
+#include <sys/ipc.h>
+
+#ifdef _GNU_SOURCE
+#define __used_ids used_ids
+#define __swap_attempts swap_attempts
+#define __swap_successes swap_successes
+#endif
+
+#include <bits/shm.h>
+
+#define SHM_R 0400
+#define SHM_W 0200
+
+#define SHM_RDONLY 010000
+#define SHM_RND    020000
+#define SHM_REMAP  040000
+#define SHM_EXEC   0100000
+
+#define SHM_LOCK 11
+#define SHM_UNLOCK 12
+#define SHM_STAT 13
+#define SHM_INFO 14
+#define SHM_DEST 01000
+#define SHM_LOCKED 02000
+#define SHM_HUGETLB 04000
+#define SHM_NORESERVE 010000
+
+typedef unsigned long shmatt_t;
+
+void *shmat(int, const void *, int);
+int shmctl(int, int, struct shmid_ds *);
+int shmdt(const void *);
+int shmget(key_t, size_t, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/signal.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/signal.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/signal.h	(revision 331)
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <sys/signal.h> to <signal.h>
+#include <signal.h>
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/signalfd.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/signalfd.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/signalfd.h	(revision 331)
@@ -0,0 +1,45 @@
+#ifndef _SYS_SIGNALFD_H
+#define _SYS_SIGNALFD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <fcntl.h>
+
+#define __NEED_sigset_t
+
+#include <bits/alltypes.h>
+
+#define SFD_CLOEXEC O_CLOEXEC
+#define SFD_NONBLOCK O_NONBLOCK
+
+int signalfd(int, const sigset_t *, int);
+
+struct signalfd_siginfo {
+	uint32_t  ssi_signo;
+	int32_t   ssi_errno;
+	int32_t   ssi_code;
+	uint32_t  ssi_pid;
+	uint32_t  ssi_uid;
+	int32_t   ssi_fd;
+	uint32_t  ssi_tid;
+	uint32_t  ssi_band;
+	uint32_t  ssi_overrun;
+	uint32_t  ssi_trapno;
+	int32_t   ssi_status;
+	int32_t   ssi_int;
+	uint64_t  ssi_ptr;
+	uint64_t  ssi_utime;
+	uint64_t  ssi_stime;
+	uint64_t  ssi_addr;
+	uint16_t  ssi_addr_lsb;
+	uint8_t   pad[128-12*4-4*8-2];
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/socket.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/socket.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/socket.h	(revision 331)
@@ -0,0 +1,339 @@
+#ifndef	_SYS_SOCKET_H
+#define	_SYS_SOCKET_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_socklen_t
+#define __NEED_sa_family_t
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_uid_t
+#define __NEED_pid_t
+#define __NEED_gid_t
+#define __NEED_struct_iovec
+
+#include <bits/alltypes.h>
+
+#include <bits/socket.h>
+
+#ifdef _GNU_SOURCE
+struct ucred {
+	pid_t pid;
+	uid_t uid;
+	gid_t gid;
+};
+
+struct mmsghdr {
+	struct msghdr msg_hdr;
+	unsigned int  msg_len;
+};
+
+struct timespec;
+
+int sendmmsg (int, struct mmsghdr *, unsigned int, unsigned int);
+int recvmmsg (int, struct mmsghdr *, unsigned int, unsigned int, struct timespec *);
+#endif
+
+struct linger {
+	int l_onoff;
+	int l_linger;
+};
+
+#define SHUT_RD 0
+#define SHUT_WR 1
+#define SHUT_RDWR 2
+
+#ifndef SOCK_STREAM
+#define SOCK_STREAM    1
+#define SOCK_DGRAM     2
+#endif
+
+#define SOCK_RAW       3
+#define SOCK_RDM       4
+#define SOCK_SEQPACKET 5
+#define SOCK_DCCP      6
+#define SOCK_PACKET    10
+
+#ifndef SOCK_CLOEXEC
+#define SOCK_CLOEXEC   02000000
+#define SOCK_NONBLOCK  04000
+#endif
+
+#define PF_UNSPEC       0
+#define PF_LOCAL        1
+#define PF_UNIX         PF_LOCAL
+#define PF_FILE         PF_LOCAL
+#define PF_INET         2
+#define PF_AX25         3
+#define PF_IPX          4
+#define PF_APPLETALK    5
+#define PF_NETROM       6
+#define PF_BRIDGE       7
+#define PF_ATMPVC       8
+#define PF_X25          9
+#define PF_INET6        10
+#define PF_ROSE         11
+#define PF_DECnet       12
+#define PF_NETBEUI      13
+#define PF_SECURITY     14
+#define PF_KEY          15
+#define PF_NETLINK      16
+#define PF_ROUTE        PF_NETLINK
+#define PF_PACKET       17
+#define PF_ASH          18
+#define PF_ECONET       19
+#define PF_ATMSVC       20
+#define PF_RDS          21
+#define PF_SNA          22
+#define PF_IRDA         23
+#define PF_PPPOX        24
+#define PF_WANPIPE      25
+#define PF_LLC          26
+#define PF_IB           27
+#define PF_MPLS         28
+#define PF_CAN          29
+#define PF_TIPC         30
+#define PF_BLUETOOTH    31
+#define PF_IUCV         32
+#define PF_RXRPC        33
+#define PF_ISDN         34
+#define PF_PHONET       35
+#define PF_IEEE802154   36
+#define PF_CAIF         37
+#define PF_ALG          38
+#define PF_NFC          39
+#define PF_VSOCK        40
+#define PF_KCM          41
+#define PF_QIPCRTR      42
+#define PF_MAX          43
+
+#define AF_UNSPEC       PF_UNSPEC
+#define AF_LOCAL        PF_LOCAL
+#define AF_UNIX         AF_LOCAL
+#define AF_FILE         AF_LOCAL
+#define AF_INET         PF_INET
+#define AF_AX25         PF_AX25
+#define AF_IPX          PF_IPX
+#define AF_APPLETALK    PF_APPLETALK
+#define AF_NETROM       PF_NETROM
+#define AF_BRIDGE       PF_BRIDGE
+#define AF_ATMPVC       PF_ATMPVC
+#define AF_X25          PF_X25
+#define AF_INET6        PF_INET6
+#define AF_ROSE         PF_ROSE
+#define AF_DECnet       PF_DECnet
+#define AF_NETBEUI      PF_NETBEUI
+#define AF_SECURITY     PF_SECURITY
+#define AF_KEY          PF_KEY
+#define AF_NETLINK      PF_NETLINK
+#define AF_ROUTE        PF_ROUTE
+#define AF_PACKET       PF_PACKET
+#define AF_ASH          PF_ASH
+#define AF_ECONET       PF_ECONET
+#define AF_ATMSVC       PF_ATMSVC
+#define AF_RDS          PF_RDS
+#define AF_SNA          PF_SNA
+#define AF_IRDA         PF_IRDA
+#define AF_PPPOX        PF_PPPOX
+#define AF_WANPIPE      PF_WANPIPE
+#define AF_LLC          PF_LLC
+#define AF_IB           PF_IB
+#define AF_MPLS         PF_MPLS
+#define AF_CAN          PF_CAN
+#define AF_TIPC         PF_TIPC
+#define AF_BLUETOOTH    PF_BLUETOOTH
+#define AF_IUCV         PF_IUCV
+#define AF_RXRPC        PF_RXRPC
+#define AF_ISDN         PF_ISDN
+#define AF_PHONET       PF_PHONET
+#define AF_IEEE802154   PF_IEEE802154
+#define AF_CAIF         PF_CAIF
+#define AF_ALG          PF_ALG
+#define AF_NFC          PF_NFC
+#define AF_VSOCK        PF_VSOCK
+#define AF_KCM          PF_KCM
+#define AF_QIPCRTR      PF_QIPCRTR
+#define AF_MAX          PF_MAX
+
+#ifndef SO_DEBUG
+#define SO_DEBUG        1
+#define SO_REUSEADDR    2
+#define SO_TYPE         3
+#define SO_ERROR        4
+#define SO_DONTROUTE    5
+#define SO_BROADCAST    6
+#define SO_SNDBUF       7
+#define SO_RCVBUF       8
+#define SO_KEEPALIVE    9
+#define SO_OOBINLINE    10
+#define SO_NO_CHECK     11
+#define SO_PRIORITY     12
+#define SO_LINGER       13
+#define SO_BSDCOMPAT    14
+#define SO_REUSEPORT    15
+#define SO_PASSCRED     16
+#define SO_PEERCRED     17
+#define SO_RCVLOWAT     18
+#define SO_SNDLOWAT     19
+#define SO_RCVTIMEO     20
+#define SO_SNDTIMEO     21
+#define SO_ACCEPTCONN   30
+#define SO_SNDBUFFORCE  32
+#define SO_RCVBUFFORCE  33
+#define SO_PROTOCOL     38
+#define SO_DOMAIN       39
+#endif
+
+#define SO_SECURITY_AUTHENTICATION              22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT        23
+#define SO_SECURITY_ENCRYPTION_NETWORK          24
+
+#define SO_BINDTODEVICE 25
+
+#define SO_ATTACH_FILTER        26
+#define SO_DETACH_FILTER        27
+#define SO_GET_FILTER           SO_ATTACH_FILTER
+
+#define SO_PEERNAME             28
+#define SO_TIMESTAMP            29
+#define SCM_TIMESTAMP           SO_TIMESTAMP
+
+#define SO_PEERSEC              31
+#define SO_PASSSEC              34
+#define SO_TIMESTAMPNS          35
+#define SCM_TIMESTAMPNS         SO_TIMESTAMPNS
+#define SO_MARK                 36
+#define SO_TIMESTAMPING         37
+#define SCM_TIMESTAMPING        SO_TIMESTAMPING
+#define SO_RXQ_OVFL             40
+#define SO_WIFI_STATUS          41
+#define SCM_WIFI_STATUS         SO_WIFI_STATUS
+#define SO_PEEK_OFF             42
+#define SO_NOFCS                43
+#define SO_LOCK_FILTER          44
+#define SO_SELECT_ERR_QUEUE     45
+#define SO_BUSY_POLL            46
+#define SO_MAX_PACING_RATE      47
+#define SO_BPF_EXTENSIONS       48
+#define SO_INCOMING_CPU         49
+#define SO_ATTACH_BPF           50
+#define SO_DETACH_BPF           SO_DETACH_FILTER
+#define SO_ATTACH_REUSEPORT_CBPF 51
+#define SO_ATTACH_REUSEPORT_EBPF 52
+#define SO_CNX_ADVICE           53
+
+#ifndef SOL_SOCKET
+#define SOL_SOCKET      1
+#endif
+
+#define SOL_IP          0
+#define SOL_IPV6        41
+#define SOL_ICMPV6      58
+
+#define SOL_RAW         255
+#define SOL_DECNET      261
+#define SOL_X25         262
+#define SOL_PACKET      263
+#define SOL_ATM         264
+#define SOL_AAL         265
+#define SOL_IRDA        266
+#define SOL_NETBEUI     267
+#define SOL_LLC         268
+#define SOL_DCCP        269
+#define SOL_NETLINK     270
+#define SOL_TIPC        271
+#define SOL_RXRPC       272
+#define SOL_PPPOL2TP    273
+#define SOL_BLUETOOTH   274
+#define SOL_PNPIPE      275
+#define SOL_RDS         276
+#define SOL_IUCV        277
+#define SOL_CAIF        278
+#define SOL_ALG         279
+#define SOL_NFC         280
+#define SOL_KCM         281
+
+#define SOMAXCONN       128
+
+#define MSG_OOB       0x0001
+#define MSG_PEEK      0x0002
+#define MSG_DONTROUTE 0x0004
+#define MSG_CTRUNC    0x0008
+#define MSG_PROXY     0x0010
+#define MSG_TRUNC     0x0020
+#define MSG_DONTWAIT  0x0040
+#define MSG_EOR       0x0080
+#define MSG_WAITALL   0x0100
+#define MSG_FIN       0x0200
+#define MSG_SYN       0x0400
+#define MSG_CONFIRM   0x0800
+#define MSG_RST       0x1000
+#define MSG_ERRQUEUE  0x2000
+#define MSG_NOSIGNAL  0x4000
+#define MSG_MORE      0x8000
+#define MSG_WAITFORONE 0x10000
+#define MSG_BATCH     0x40000
+#define MSG_FASTOPEN  0x20000000
+#define MSG_CMSG_CLOEXEC 0x40000000
+
+#define __CMSG_LEN(cmsg) (((cmsg)->cmsg_len + sizeof(long) - 1) & ~(long)(sizeof(long) - 1))
+#define __CMSG_NEXT(cmsg) ((unsigned char *)(cmsg) + __CMSG_LEN(cmsg))
+#define __MHDR_END(mhdr) ((unsigned char *)(mhdr)->msg_control + (mhdr)->msg_controllen)
+
+#define CMSG_DATA(cmsg) ((unsigned char *) (((struct cmsghdr *)(cmsg)) + 1))
+#define CMSG_NXTHDR(mhdr, cmsg) ((cmsg)->cmsg_len < sizeof (struct cmsghdr) || \
+	__CMSG_LEN(cmsg) + sizeof(struct cmsghdr) >= __MHDR_END(mhdr) - (unsigned char *)(cmsg) \
+	? 0 : (struct cmsghdr *)__CMSG_NEXT(cmsg))
+#define CMSG_FIRSTHDR(mhdr) ((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr) ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) 0)
+
+#define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) & (size_t) ~(sizeof (size_t) - 1))
+#define CMSG_SPACE(len) (CMSG_ALIGN (len) + CMSG_ALIGN (sizeof (struct cmsghdr)))
+#define CMSG_LEN(len)   (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
+
+#define SCM_RIGHTS      0x01
+#define SCM_CREDENTIALS 0x02
+
+struct sockaddr {
+	sa_family_t sa_family;
+	char sa_data[14];
+};
+
+struct sockaddr_storage {
+	sa_family_t ss_family;
+	char __ss_padding[128-sizeof(long)-sizeof(sa_family_t)];
+	unsigned long __ss_align;
+};
+
+int socket (int, int, int);
+int socketpair (int, int, int, int [2]);
+
+int shutdown (int, int);
+
+int bind (int, const struct sockaddr *, socklen_t);
+int connect (int, const struct sockaddr *, socklen_t);
+int listen (int, int);
+int accept (int, struct sockaddr *__restrict, socklen_t *__restrict);
+int accept4(int, struct sockaddr *__restrict, socklen_t *__restrict, int);
+
+int getsockname (int, struct sockaddr *__restrict, socklen_t *__restrict);
+int getpeername (int, struct sockaddr *__restrict, socklen_t *__restrict);
+
+ssize_t send (int, const void *, size_t, int);
+ssize_t recv (int, void *, size_t, int);
+ssize_t sendto (int, const void *, size_t, int, const struct sockaddr *, socklen_t);
+ssize_t recvfrom (int, void *__restrict, size_t, int, struct sockaddr *__restrict, socklen_t *__restrict);
+ssize_t sendmsg (int, const struct msghdr *, int);
+ssize_t recvmsg (int, struct msghdr *, int);
+
+int getsockopt (int, int, int, void *__restrict, socklen_t *__restrict);
+int setsockopt (int, int, int, const void *, socklen_t);
+
+int sockatmark (int);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/soundcard.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/soundcard.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/soundcard.h	(revision 331)
@@ -0,0 +1,1 @@
+#include <linux/soundcard.h>
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/stat.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/stat.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/stat.h	(revision 331)
@@ -0,0 +1,118 @@
+#ifndef	_SYS_STAT_H
+#define	_SYS_STAT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_dev_t
+#define __NEED_ino_t
+#define __NEED_mode_t
+#define __NEED_nlink_t
+#define __NEED_uid_t
+#define __NEED_gid_t
+#define __NEED_off_t
+#define __NEED_time_t
+#define __NEED_blksize_t
+#define __NEED_blkcnt_t
+#define __NEED_struct_timespec
+
+#include <bits/alltypes.h>
+
+#include <bits/stat.h>
+
+#define st_atime st_atim.tv_sec
+#define st_mtime st_mtim.tv_sec
+#define st_ctime st_ctim.tv_sec
+
+#define S_IFMT  0170000
+
+#define S_IFDIR 0040000
+#define S_IFCHR 0020000
+#define S_IFBLK 0060000
+#define S_IFREG 0100000
+#define S_IFIFO 0010000
+#define S_IFLNK 0120000
+#define S_IFSOCK 0140000
+
+#define S_TYPEISMQ(buf)  0
+#define S_TYPEISSEM(buf) 0
+#define S_TYPEISSHM(buf) 0
+#define S_TYPEISTMO(buf) 0
+
+#define S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)
+#define S_ISCHR(mode)  (((mode) & S_IFMT) == S_IFCHR)
+#define S_ISBLK(mode)  (((mode) & S_IFMT) == S_IFBLK)
+#define S_ISREG(mode)  (((mode) & S_IFMT) == S_IFREG)
+#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
+#define S_ISLNK(mode)  (((mode) & S_IFMT) == S_IFLNK)
+#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
+
+#ifndef S_IRUSR
+#define S_ISUID 04000
+#define S_ISGID 02000
+#define S_ISVTX 01000
+#define S_IRUSR 0400
+#define S_IWUSR 0200
+#define S_IXUSR 0100
+#define S_IRWXU 0700
+#define S_IRGRP 0040
+#define S_IWGRP 0020
+#define S_IXGRP 0010
+#define S_IRWXG 0070
+#define S_IROTH 0004
+#define S_IWOTH 0002
+#define S_IXOTH 0001
+#define S_IRWXO 0007
+#endif
+
+#define UTIME_NOW  0x3fffffff
+#define UTIME_OMIT 0x3ffffffe
+
+int stat(const char *__restrict, struct stat *__restrict);
+int fstat(int, struct stat *);
+int lstat(const char *__restrict, struct stat *__restrict);
+int fstatat(int, const char *__restrict, struct stat *__restrict, int);
+int chmod(const char *, mode_t);
+int fchmod(int, mode_t);
+int fchmodat(int, const char *, mode_t, int);
+mode_t umask(mode_t);
+int mkdir(const char *, mode_t);
+int mkfifo(const char *, mode_t);
+int mkdirat(int, const char *, mode_t);
+int mkfifoat(int, const char *, mode_t);
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int mknod(const char *, mode_t, dev_t);
+int mknodat(int, const char *, mode_t, dev_t);
+#endif
+
+int futimens(int, const struct timespec [2]);
+int utimensat(int, const char *, const struct timespec [2], int);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int lchmod(const char *, mode_t);
+#define S_IREAD S_IRUSR
+#define S_IWRITE S_IWUSR
+#define S_IEXEC S_IXUSR
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define stat64 stat
+#define fstat64 fstat
+#define lstat64 lstat
+#define fstatat64 fstatat
+#define blkcnt64_t blkcnt_t
+#define fsblkcnt64_t fsblkcnt_t
+#define fsfilcnt64_t fsfilcnt_t
+#define ino64_t ino_t
+#define off64_t off_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/statfs.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/statfs.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/statfs.h	(revision 331)
@@ -0,0 +1,32 @@
+#ifndef	_SYS_STATFS_H
+#define	_SYS_STATFS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <sys/statvfs.h>
+
+typedef struct __fsid_t {
+	int __val[2];
+} fsid_t;
+
+#include <bits/statfs.h>
+
+int statfs (const char *, struct statfs *);
+int fstatfs (int, struct statfs *);
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define statfs64 statfs
+#define fstatfs64 fstatfs
+#define fsblkcnt64_t fsblkcnt_t
+#define fsfilcnt64_t fsfilcnt_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/statvfs.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/statvfs.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/statvfs.h	(revision 331)
@@ -0,0 +1,57 @@
+#ifndef	_SYS_STATVFS_H
+#define	_SYS_STATVFS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_fsblkcnt_t
+#define __NEED_fsfilcnt_t
+#include <bits/alltypes.h>
+
+#include <endian.h>
+
+struct statvfs {
+	unsigned long f_bsize, f_frsize;
+	fsblkcnt_t f_blocks, f_bfree, f_bavail;
+	fsfilcnt_t f_files, f_ffree, f_favail;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+	unsigned long f_fsid;
+	unsigned :8*(2*sizeof(int)-sizeof(long));
+#else
+	unsigned :8*(2*sizeof(int)-sizeof(long));
+	unsigned long f_fsid;
+#endif
+	unsigned long f_flag, f_namemax;
+	int __reserved[6];
+};
+
+int statvfs (const char *__restrict, struct statvfs *__restrict);
+int fstatvfs (int, struct statvfs *);
+
+#define ST_RDONLY 1
+#define ST_NOSUID 2
+#define ST_NODEV  4
+#define ST_NOEXEC 8
+#define ST_SYNCHRONOUS 16
+#define ST_MANDLOCK    64
+#define ST_WRITE       128
+#define ST_APPEND      256
+#define ST_IMMUTABLE   512
+#define ST_NOATIME     1024
+#define ST_NODIRATIME  2048
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define statvfs64 statvfs
+#define fstatvfs64 fstatvfs
+#define fsblkcnt64_t fsblkcnt_t
+#define fsfilcnt64_t fsfilcnt_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/stropts.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/stropts.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/stropts.h	(revision 331)
@@ -0,0 +1,1 @@
+#include <stropts.h>
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/swap.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/swap.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/swap.h	(revision 331)
@@ -0,0 +1,21 @@
+#ifndef _SYS_SWAP_H
+#define _SYS_SWAP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define	SWAP_FLAG_PREFER        0x8000
+#define	SWAP_FLAG_PRIO_MASK     0x7fff
+#define	SWAP_FLAG_PRIO_SHIFT    0
+#define SWAP_FLAG_DISCARD       0x10000
+
+int swapon (const char *, int);
+int swapoff (const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/syscall.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/syscall.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/syscall.h	(revision 331)
@@ -0,0 +1,6 @@
+#ifndef _SYS_SYSCALL_H
+#define _SYS_SYSCALL_H
+
+#include <bits/syscall.h>
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/sysinfo.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/sysinfo.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/sysinfo.h	(revision 331)
@@ -0,0 +1,36 @@
+#ifndef _SYS_SYSINFO_H
+#define _SYS_SYSINFO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SI_LOAD_SHIFT 16
+
+struct sysinfo {
+	unsigned long uptime;
+	unsigned long loads[3];
+	unsigned long totalram;
+	unsigned long freeram;
+	unsigned long sharedram;
+	unsigned long bufferram;
+	unsigned long totalswap;
+	unsigned long freeswap;
+	unsigned short procs, pad;
+	unsigned long totalhigh;
+	unsigned long freehigh;
+	unsigned mem_unit;
+	char __reserved[256];
+};
+
+int sysinfo (struct sysinfo *);
+int get_nprocs_conf (void);
+int get_nprocs (void);
+long get_phys_pages (void);
+long get_avphys_pages (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/syslog.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/syslog.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/syslog.h	(revision 331)
@@ -0,0 +1,1 @@
+#include <syslog.h>
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/sysmacros.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/sysmacros.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/sysmacros.h	(revision 331)
@@ -0,0 +1,15 @@
+#ifndef _SYS_SYSMACROS_H
+#define _SYS_SYSMACROS_H
+
+#define major(x) \
+	((unsigned)( (((x)>>31>>1) & 0xfffff000) | (((x)>>8) & 0x00000fff) ))
+#define minor(x) \
+	((unsigned)( (((x)>>12) & 0xffffff00) | ((x) & 0x000000ff) ))
+
+#define makedev(x,y) ( \
+        (((x)&0xfffff000ULL) << 32) | \
+	(((x)&0x00000fffULL) << 8) | \
+        (((y)&0xffffff00ULL) << 12) | \
+	(((y)&0x000000ffULL)) )
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/termios.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/termios.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/termios.h	(revision 331)
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <sys/termios.h> to <termios.h>
+#include <termios.h>
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/time.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/time.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/time.h	(revision 331)
@@ -0,0 +1,62 @@
+#ifndef _SYS_TIME_H
+#define _SYS_TIME_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <sys/select.h>
+
+int gettimeofday (struct timeval *__restrict, void *__restrict);
+
+#define ITIMER_REAL    0
+#define ITIMER_VIRTUAL 1
+#define ITIMER_PROF    2
+
+struct itimerval {
+	struct timeval it_interval;
+	struct timeval it_value;
+};
+
+int getitimer (int, struct itimerval *);
+int setitimer (int, const struct itimerval *__restrict, struct itimerval *__restrict);
+int utimes (const char *, const struct timeval [2]);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+struct timezone {
+	int tz_minuteswest;
+	int tz_dsttime;
+};
+int futimes(int, const struct timeval [2]);
+int futimesat(int, const char *, const struct timeval [2]);
+int lutimes(const char *, const struct timeval [2]);
+int settimeofday(const struct timeval *, const struct timezone *);
+int adjtime (const struct timeval *, struct timeval *);
+#define timerisset(t) ((t)->tv_sec || (t)->tv_usec)
+#define timerclear(t) ((t)->tv_sec = (t)->tv_usec = 0)
+#define timercmp(s,t,op) ((s)->tv_sec == (t)->tv_sec ? \
+	(s)->tv_usec op (t)->tv_usec : (s)->tv_sec op (t)->tv_sec)
+#define timeradd(s,t,a) (void) ( (a)->tv_sec = (s)->tv_sec + (t)->tv_sec, \
+	((a)->tv_usec = (s)->tv_usec + (t)->tv_usec) >= 1000000 && \
+	((a)->tv_usec -= 1000000, (a)->tv_sec++) )
+#define timersub(s,t,a) (void) ( (a)->tv_sec = (s)->tv_sec - (t)->tv_sec, \
+	((a)->tv_usec = (s)->tv_usec - (t)->tv_usec) < 0 && \
+	((a)->tv_usec += 1000000, (a)->tv_sec--) )
+#endif
+
+#if defined(_GNU_SOURCE)
+#define TIMEVAL_TO_TIMESPEC(tv, ts) ( \
+	(ts)->tv_sec = (tv)->tv_sec, \
+	(ts)->tv_nsec = (tv)->tv_usec * 1000, \
+	(void)0 )
+#define TIMESPEC_TO_TIMEVAL(tv, ts) ( \
+	(tv)->tv_sec = (ts)->tv_sec, \
+	(tv)->tv_usec = (ts)->tv_nsec / 1000, \
+	(void)0 )
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/timeb.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/timeb.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/timeb.h	(revision 331)
@@ -0,0 +1,22 @@
+#ifndef _SYS_TIMEB_H
+#define _SYS_TIMEB_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_time_t
+
+#include <bits/alltypes.h>
+
+struct timeb {
+	time_t time;
+	unsigned short millitm;
+	short timezone, dstflag;
+};
+
+int ftime(struct timeb *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/timerfd.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/timerfd.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/timerfd.h	(revision 331)
@@ -0,0 +1,26 @@
+#ifndef _SYS_TIMERFD_H
+#define _SYS_TIMERFD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <time.h>
+#include <fcntl.h>
+
+#define TFD_NONBLOCK O_NONBLOCK
+#define TFD_CLOEXEC O_CLOEXEC
+
+#define TFD_TIMER_ABSTIME 1
+
+struct itimerspec;
+
+int timerfd_create(int, int);
+int timerfd_settime(int, int, const struct itimerspec *, struct itimerspec *);
+int timerfd_gettime(int, struct itimerspec *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/times.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/times.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/times.h	(revision 331)
@@ -0,0 +1,25 @@
+#ifndef	_SYS_TIMES_H
+#define	_SYS_TIMES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_clock_t
+#include <bits/alltypes.h>
+
+struct tms {
+	clock_t tms_utime;
+	clock_t tms_stime;
+	clock_t tms_cutime;
+	clock_t tms_cstime;
+};
+
+clock_t times (struct tms *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/timex.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/timex.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/timex.h	(revision 331)
@@ -0,0 +1,98 @@
+#ifndef _SYS_TIMEX_H
+#define _SYS_TIMEX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_clockid_t
+
+#include <bits/alltypes.h>
+
+#include <sys/time.h>
+
+struct ntptimeval {
+	struct timeval time;
+	long maxerror, esterror;
+};
+
+struct timex {
+	unsigned modes;
+	long offset, freq, maxerror, esterror;
+	int status;
+	long constant, precision, tolerance;
+	struct timeval time;
+	long tick, ppsfreq, jitter;
+	int shift;
+	long stabil, jitcnt, calcnt, errcnt, stbcnt;
+	int tai;
+	int __padding[11];
+};
+
+#define ADJ_OFFSET		0x0001
+#define ADJ_FREQUENCY		0x0002
+#define ADJ_MAXERROR		0x0004
+#define ADJ_ESTERROR		0x0008
+#define ADJ_STATUS		0x0010
+#define ADJ_TIMECONST		0x0020
+#define ADJ_TAI			0x0080
+#define ADJ_SETOFFSET		0x0100
+#define ADJ_MICRO		0x1000
+#define ADJ_NANO		0x2000
+#define ADJ_TICK		0x4000
+#define ADJ_OFFSET_SINGLESHOT	0x8001
+#define ADJ_OFFSET_SS_READ	0xa001
+
+#define MOD_OFFSET	ADJ_OFFSET
+#define MOD_FREQUENCY	ADJ_FREQUENCY
+#define MOD_MAXERROR	ADJ_MAXERROR
+#define MOD_ESTERROR	ADJ_ESTERROR
+#define MOD_STATUS	ADJ_STATUS
+#define MOD_TIMECONST	ADJ_TIMECONST
+#define MOD_CLKB	ADJ_TICK
+#define MOD_CLKA	ADJ_OFFSET_SINGLESHOT
+#define MOD_TAI		ADJ_TAI
+#define MOD_MICRO	ADJ_MICRO
+#define MOD_NANO	ADJ_NANO
+
+#define STA_PLL		0x0001
+#define STA_PPSFREQ	0x0002
+#define STA_PPSTIME	0x0004
+#define STA_FLL		0x0008
+
+#define STA_INS		0x0010
+#define STA_DEL		0x0020
+#define STA_UNSYNC	0x0040
+#define STA_FREQHOLD	0x0080
+
+#define STA_PPSSIGNAL	0x0100
+#define STA_PPSJITTER	0x0200
+#define STA_PPSWANDER	0x0400
+#define STA_PPSERROR	0x0800
+
+#define STA_CLOCKERR	0x1000
+#define STA_NANO	0x2000
+#define STA_MODE	0x4000
+#define STA_CLK		0x8000
+
+#define STA_RONLY (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER | \
+    STA_PPSERROR | STA_CLOCKERR | STA_NANO | STA_MODE | STA_CLK)
+
+#define TIME_OK		0
+#define TIME_INS	1
+#define TIME_DEL	2
+#define TIME_OOP	3
+#define TIME_WAIT	4
+#define TIME_ERROR	5
+#define TIME_BAD	TIME_ERROR
+
+#define MAXTC		6
+
+int adjtimex(struct timex *);
+int clock_adjtime(clockid_t, struct timex *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/ttydefaults.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/ttydefaults.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/ttydefaults.h	(revision 331)
@@ -0,0 +1,39 @@
+#ifndef _SYS_TTYDEFAULTS_H
+#define _SYS_TTYDEFAULTS_H
+
+#define TTYDEF_IFLAG (BRKINT | ISTRIP | ICRNL | IMAXBEL | IXON | IXANY)
+#define TTYDEF_OFLAG (OPOST | ONLCR | XTABS)
+#define TTYDEF_LFLAG (ECHO | ICANON | ISIG | IEXTEN | ECHOE|ECHOKE|ECHOCTL)
+#define TTYDEF_CFLAG (CREAD | CS7 | PARENB | HUPCL)
+#define TTYDEF_SPEED (B9600)
+#define CTRL(x) (x&037)
+#define CEOF CTRL('d')
+
+#ifdef _POSIX_VDISABLE
+#define CEOL _POSIX_VDISABLE
+#define CSTATUS _POSIX_VDISABLE
+#else
+#define CEOL '\0'
+#define CSTATUS '\0'
+#endif
+
+#define CERASE 0177
+#define CINTR CTRL('c')
+#define CKILL CTRL('u')
+#define CMIN 1
+#define CQUIT 034
+#define CSUSP CTRL('z')
+#define CTIME 0
+#define CDSUSP CTRL('y')
+#define CSTART CTRL('q')
+#define CSTOP CTRL('s')
+#define CLNEXT CTRL('v')
+#define CDISCARD CTRL('o')
+#define CWERASE CTRL('w')
+#define CREPRINT CTRL('r')
+#define CEOT CEOF
+#define CBRK CEOL
+#define CRPRNT CREPRINT
+#define CFLUSH CDISCARD
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/types.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/types.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/types.h	(revision 331)
@@ -0,0 +1,86 @@
+#ifndef	_SYS_TYPES_H
+#define	_SYS_TYPES_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_ino_t
+#define __NEED_dev_t
+#define __NEED_uid_t
+#define __NEED_gid_t
+#define __NEED_mode_t
+#define __NEED_nlink_t
+#define __NEED_off_t
+#define __NEED_pid_t
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_time_t
+#define __NEED_timer_t
+#define __NEED_clockid_t
+
+#define __NEED_blkcnt_t
+#define __NEED_fsblkcnt_t
+#define __NEED_fsfilcnt_t
+
+#define __NEED_id_t
+#define __NEED_key_t
+#define __NEED_clock_t
+#define __NEED_suseconds_t
+#define __NEED_blksize_t
+
+#define __NEED_pthread_t
+#define __NEED_pthread_attr_t
+#define __NEED_pthread_mutexattr_t
+#define __NEED_pthread_condattr_t
+#define __NEED_pthread_rwlockattr_t
+#define __NEED_pthread_barrierattr_t
+#define __NEED_pthread_mutex_t
+#define __NEED_pthread_cond_t
+#define __NEED_pthread_rwlock_t
+#define __NEED_pthread_barrier_t
+#define __NEED_pthread_spinlock_t
+#define __NEED_pthread_key_t
+#define __NEED_pthread_once_t
+#define __NEED_useconds_t
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_int8_t
+#define __NEED_int16_t
+#define __NEED_int32_t
+#define __NEED_int64_t
+#define __NEED_u_int64_t
+#define __NEED_register_t
+#endif
+
+#include <bits/alltypes.h>
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+typedef unsigned char u_int8_t;
+typedef unsigned short u_int16_t;
+typedef unsigned u_int32_t;
+typedef char *caddr_t;
+typedef unsigned char u_char;
+typedef unsigned short u_short, ushort;
+typedef unsigned u_int, uint;
+typedef unsigned long u_long, ulong;
+typedef long long quad_t;
+typedef unsigned long long u_quad_t;
+#include <endian.h>
+#include <sys/select.h>
+#include <sys/sysmacros.h>
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define blkcnt64_t blkcnt_t
+#define fsblkcnt64_t fsblkcnt_t
+#define fsfilcnt64_t fsfilcnt_t
+#define ino64_t ino_t
+#define off64_t off_t
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/ucontext.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/ucontext.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/ucontext.h	(revision 331)
@@ -0,0 +1,1 @@
+#include <ucontext.h>
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/uio.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/uio.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/uio.h	(revision 331)
@@ -0,0 +1,48 @@
+#ifndef _SYS_UIO_H
+#define _SYS_UIO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_struct_iovec
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_off_t
+#endif
+
+#ifdef _GNU_SOURCE
+#define __NEED_pid_t
+#endif
+
+#include <bits/alltypes.h>
+
+#define UIO_MAXIOV 1024
+
+ssize_t readv (int, const struct iovec *, int);
+ssize_t writev (int, const struct iovec *, int);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+ssize_t preadv (int, const struct iovec *, int, off_t);
+ssize_t pwritev (int, const struct iovec *, int, off_t);
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define preadv64 preadv
+#define pwritev64 pwritev
+#define off64_t off_t
+#endif
+#endif
+
+#ifdef _GNU_SOURCE
+ssize_t process_vm_writev(pid_t, const struct iovec *, unsigned long, const struct iovec *, unsigned long, unsigned long);
+ssize_t process_vm_readv(pid_t, const struct iovec *, unsigned long, const struct iovec *, unsigned long, unsigned long);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/un.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/un.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/un.h	(revision 331)
@@ -0,0 +1,31 @@
+#ifndef	_SYS_UN_H
+#define	_SYS_UN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_sa_family_t
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_size_t
+#endif
+
+#include <bits/alltypes.h>
+
+struct sockaddr_un {
+	sa_family_t sun_family;
+	char sun_path[108];
+};
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+size_t strlen(const char *);
+#define SUN_LEN(s) (2+strlen((s)->sun_path))
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/user.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/user.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/user.h	(revision 331)
@@ -0,0 +1,16 @@
+#ifndef _SYS_USER_H
+#define _SYS_USER_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <limits.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include <bits/user.h>
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/utsname.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/utsname.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/utsname.h	(revision 331)
@@ -0,0 +1,29 @@
+#ifndef	_SYS_UTSNAME_H
+#define	_SYS_UTSNAME_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+struct utsname {
+	char sysname[65];
+	char nodename[65];
+	char release[65];
+	char version[65];
+	char machine[65];
+#ifdef _GNU_SOURCE
+	char domainname[65];
+#else
+	char __domainname[65];
+#endif
+};
+
+int uname (struct utsname *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/vfs.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/vfs.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/vfs.h	(revision 331)
@@ -0,0 +1,1 @@
+#include <sys/statfs.h>
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/vt.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/vt.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/vt.h	(revision 331)
@@ -0,0 +1,1 @@
+#include <linux/vt.h>
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/wait.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/wait.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/wait.h	(revision 331)
@@ -0,0 +1,59 @@
+#ifndef	_SYS_WAIT_H
+#define	_SYS_WAIT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_pid_t
+#define __NEED_id_t
+#include <bits/alltypes.h>
+
+typedef enum {
+	P_ALL = 0,
+	P_PID = 1,
+	P_PGID = 2
+} idtype_t;
+
+pid_t wait (int *);
+pid_t waitpid (pid_t, int *, int );
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+#include <signal.h>
+int waitid (idtype_t, id_t, siginfo_t *, int);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#include <sys/resource.h>
+pid_t wait3 (int *, int, struct rusage *);
+pid_t wait4 (pid_t, int *, int, struct rusage *);
+#endif
+
+#define WNOHANG    1
+#define WUNTRACED  2
+
+#define WSTOPPED   2
+#define WEXITED    4
+#define WCONTINUED 8
+#define WNOWAIT    0x1000000
+
+#define __WNOTHREAD 0x20000000
+#define __WALL      0x40000000
+#define __WCLONE    0x80000000
+
+#define WEXITSTATUS(s) (((s) & 0xff00) >> 8)
+#define WTERMSIG(s) ((s) & 0x7f)
+#define WSTOPSIG(s) WEXITSTATUS(s)
+#define WCOREDUMP(s) ((s) & 0x80)
+#define WIFEXITED(s) (!WTERMSIG(s))
+#define WIFSTOPPED(s) ((short)((((s)&0xffff)*0x10001)>>8) > 0x7f00)
+#define WIFSIGNALED(s) (((s)&0xffff)-1U < 0xffu)
+#define WIFCONTINUED(s) ((s) == 0xffff)
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sys/xattr.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sys/xattr.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sys/xattr.h	(revision 331)
@@ -0,0 +1,30 @@
+#ifndef	_SYS_XATTR_H
+#define	_SYS_XATTR_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_ssize_t
+#define __NEED_size_t
+#include <bits/alltypes.h>
+
+#define XATTR_CREATE 1
+#define XATTR_REPLACE 2
+
+ssize_t getxattr(const char *, const char *, void *, size_t);
+ssize_t lgetxattr(const char *, const char *, void *, size_t);
+ssize_t fgetxattr(int, const char *, void *, size_t);
+ssize_t listxattr(const char *, char *, size_t);
+ssize_t llistxattr(const char *, char *, size_t);
+ssize_t flistxattr(int, char *, size_t);
+int setxattr(const char *, const char *, const void *, size_t, int);
+int lsetxattr(const char *, const char *, const void *, size_t, int);
+int fsetxattr(int, const char *, const void *, size_t, int);
+int removexattr(const char *, const char *);
+int lremovexattr(const char *, const char *);
+int fremovexattr(int, const char *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/syscall.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/syscall.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/syscall.h	(revision 331)
@@ -0,0 +1,1 @@
+#include <sys/syscall.h>
Index: EcnlProtoTool/trunk/musl-1.1.18/include/sysexits.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/sysexits.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/sysexits.h	(revision 331)
@@ -0,0 +1,21 @@
+#ifndef	_SYSEXITS_H
+#define _SYSEXITS_H
+#define EX_OK 0
+#define EX__BASE 64
+#define EX_USAGE 64
+#define EX_DATAERR 65
+#define EX_NOINPUT 66
+#define EX_NOUSER 67
+#define EX_NOHOST 68
+#define EX_UNAVAILABLE 69
+#define EX_SOFTWARE 70
+#define EX_OSERR 71
+#define EX_OSFILE 72
+#define EX_CANTCREAT 73
+#define EX_IOERR 74
+#define EX_TEMPFAIL 75
+#define EX_PROTOCOL 76
+#define EX_NOPERM 77
+#define EX_CONFIG 78
+#define EX__MAX 78
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/syslog.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/syslog.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/syslog.h	(revision 331)
@@ -0,0 +1,100 @@
+#ifndef _SYSLOG_H
+#define _SYSLOG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define LOG_EMERG   0
+#define LOG_ALERT   1
+#define LOG_CRIT    2
+#define LOG_ERR     3
+#define LOG_WARNING 4
+#define LOG_NOTICE  5
+#define LOG_INFO    6
+#define LOG_DEBUG   7
+
+#define LOG_PRIMASK 7
+#define LOG_PRI(p) ((p)&LOG_PRIMASK)
+#define	LOG_MAKEPRI(f, p) (((f)<<3)|(p))
+
+#define LOG_MASK(p) (1<<(p))
+#define LOG_UPTO(p) ((1<<((p)+1))-1)
+
+#define LOG_KERN     (0<<3)
+#define LOG_USER     (1<<3)
+#define LOG_MAIL     (2<<3)
+#define LOG_DAEMON   (3<<3)
+#define LOG_AUTH     (4<<3)
+#define LOG_SYSLOG   (5<<3)
+#define LOG_LPR      (6<<3)
+#define LOG_NEWS     (7<<3)
+#define LOG_UUCP     (8<<3)
+#define LOG_CRON     (9<<3)
+#define	LOG_AUTHPRIV (10<<3)
+#define	LOG_FTP      (11<<3)
+
+#define LOG_LOCAL0   (16<<3)
+#define LOG_LOCAL1   (17<<3)
+#define LOG_LOCAL2   (18<<3)
+#define LOG_LOCAL3   (19<<3)
+#define LOG_LOCAL4   (20<<3)
+#define LOG_LOCAL5   (21<<3)
+#define LOG_LOCAL6   (22<<3)
+#define LOG_LOCAL7   (23<<3)
+
+#define LOG_NFACILITIES 24
+#define LOG_FACMASK 0x3f8
+#define LOG_FAC(p) (((p)&LOG_FACMASK)>>3)
+
+#define LOG_PID    0x01
+#define LOG_CONS   0x02
+#define LOG_ODELAY 0x04
+#define LOG_NDELAY 0x08
+#define LOG_NOWAIT 0x10
+#define LOG_PERROR 0x20
+
+void closelog (void);
+void openlog (const char *, int, int);
+int setlogmask (int);
+void syslog (int, const char *, ...);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define _PATH_LOG "/dev/log"
+#define __NEED_va_list
+#include <bits/alltypes.h>
+void vsyslog (int, const char *, va_list);
+#if defined(SYSLOG_NAMES)
+#define	INTERNAL_NOPRI 0x10
+#define	INTERNAL_MARK (LOG_NFACILITIES<<3)
+typedef struct {
+	char *c_name;
+	int c_val;
+} CODE;
+#define prioritynames ((CODE *)(const CODE []){ \
+	{ "alert", LOG_ALERT }, { "crit", LOG_CRIT }, { "debug", LOG_DEBUG }, \
+	{ "emerg", LOG_EMERG }, { "err", LOG_ERR }, { "error", LOG_ERR }, \
+	{ "info", LOG_INFO }, { "none", INTERNAL_NOPRI }, \
+	{ "notice", LOG_NOTICE }, { "panic", LOG_EMERG }, \
+	{ "warn", LOG_WARNING }, { "warning", LOG_WARNING }, { 0, -1 } })
+#define facilitynames ((CODE *)(const CODE []){ \
+	{ "auth", LOG_AUTH }, { "authpriv", LOG_AUTHPRIV }, \
+	{ "cron", LOG_CRON }, { "daemon", LOG_DAEMON }, { "ftp", LOG_FTP }, \
+	{ "kern", LOG_KERN }, { "lpr", LOG_LPR }, { "mail", LOG_MAIL }, \
+	{ "mark", INTERNAL_MARK }, { "news", LOG_NEWS }, \
+	{ "security", LOG_AUTH }, { "syslog", LOG_SYSLOG }, \
+	{ "user", LOG_USER }, { "uucp", LOG_UUCP }, \
+	{ "local0", LOG_LOCAL0 }, { "local1", LOG_LOCAL1 }, \
+	{ "local2", LOG_LOCAL2 }, { "local3", LOG_LOCAL3 }, \
+	{ "local4", LOG_LOCAL4 }, { "local5", LOG_LOCAL5 }, \
+	{ "local6", LOG_LOCAL6 }, { "local7", LOG_LOCAL7 }, { 0, -1 } })
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/tar.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/tar.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/tar.h	(revision 331)
@@ -0,0 +1,33 @@
+#ifndef	_TAR_H
+#define	_TAR_H
+
+#define TSUID   04000
+#define TSGID   02000
+#define TSVTX   01000
+#define TUREAD  00400
+#define TUWRITE 00200
+#define TUEXEC  00100
+#define TGREAD  00040
+#define TGWRITE 00020
+#define TGEXEC  00010
+#define TOREAD  00004
+#define TOWRITE 00002
+#define TOEXEC  00001
+
+#define REGTYPE  '0'
+#define AREGTYPE '\0'
+#define LNKTYPE  '1'
+#define SYMTYPE  '2'
+#define CHRTYPE  '3'
+#define BLKTYPE  '4'
+#define DIRTYPE  '5'
+#define FIFOTYPE '6'
+#define CONTTYPE '7'
+
+#define TMAGIC "ustar"
+#define TMAGLEN 6
+
+#define TVERSION "00"
+#define TVERSLEN 2
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/termios.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/termios.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/termios.h	(revision 331)
@@ -0,0 +1,46 @@
+#ifndef	_TERMIOS_H
+#define	_TERMIOS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_pid_t
+
+#include <bits/alltypes.h>
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 32
+
+#include <bits/termios.h>
+
+speed_t cfgetospeed (const struct termios *);
+speed_t cfgetispeed (const struct termios *);
+int cfsetospeed (struct termios *, speed_t);
+int cfsetispeed (struct termios *, speed_t);
+
+int tcgetattr (int, struct termios *);
+int tcsetattr (int, int, const struct termios *);
+
+int tcsendbreak (int, int);
+int tcdrain (int);
+int tcflush (int, int);
+int tcflow (int, int);
+
+pid_t tcgetsid (int);
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+void cfmakeraw(struct termios *);
+int cfsetspeed(struct termios *, speed_t);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/tgmath.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/tgmath.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/tgmath.h	(revision 331)
@@ -0,0 +1,270 @@
+#ifndef _TGMATH_H
+#define _TGMATH_H
+
+/*
+the return types are only correct with gcc (__GNUC__)
+otherwise they are long double or long double complex
+
+the long double version of a function is never chosen when
+sizeof(double) == sizeof(long double)
+(but the return type is set correctly with gcc)
+*/
+
+#include <math.h>
+#include <complex.h>
+
+#define __IS_FP(x) (sizeof((x)+1ULL) == sizeof((x)+1.0f))
+#define __IS_CX(x) (__IS_FP(x) && sizeof(x) == sizeof((x)+I))
+#define __IS_REAL(x) (__IS_FP(x) && 2*sizeof(x) == sizeof((x)+I))
+
+#define __FLT(x) (__IS_REAL(x) && sizeof(x) == sizeof(float))
+#define __LDBL(x) (__IS_REAL(x) && sizeof(x) == sizeof(long double) && sizeof(long double) != sizeof(double))
+
+#define __FLTCX(x) (__IS_CX(x) && sizeof(x) == sizeof(float complex))
+#define __DBLCX(x) (__IS_CX(x) && sizeof(x) == sizeof(double complex))
+#define __LDBLCX(x) (__IS_CX(x) && sizeof(x) == sizeof(long double complex) && sizeof(long double) != sizeof(double))
+
+/* return type */
+
+#ifdef __GNUC__
+/*
+the result must be casted to the right type
+(otherwise the result type is determined by the conversion
+rules applied to all the function return types so it is long
+double or long double complex except for integral functions)
+
+this cannot be done in c99, so the typeof gcc extension is
+used and that the type of ?: depends on wether an operand is
+a null pointer constant or not
+(in c11 _Generic can be used)
+
+the c arguments below must be integer constant expressions
+so they can be in null pointer constants
+(__IS_FP above was carefully chosen this way)
+*/
+/* if c then t else void */
+#define __type1(c,t) __typeof__(*(0?(t*)0:(void*)!(c)))
+/* if c then t1 else t2 */
+#define __type2(c,t1,t2) __typeof__(*(0?(__type1(c,t1)*)0:(__type1(!(c),t2)*)0))
+/* cast to double when x is integral, otherwise use typeof(x) */
+#define __RETCAST(x) ( \
+	__type2(__IS_FP(x), __typeof__(x), double))
+/* 2 args case, should work for complex types (cpow) */
+#define __RETCAST_2(x, y) ( \
+	__type2(__IS_FP(x) && __IS_FP(y), \
+		__typeof__((x)+(y)), \
+		__typeof__((x)+(y)+1.0)))
+/* 3 args case (fma only) */
+#define __RETCAST_3(x, y, z) ( \
+	__type2(__IS_FP(x) && __IS_FP(y) && __IS_FP(z), \
+		__typeof__((x)+(y)+(z)), \
+		__typeof__((x)+(y)+(z)+1.0)))
+/* drop complex from the type of x */
+/* TODO: wrong when sizeof(long double)==sizeof(double) */
+#define __RETCAST_REAL(x) (  \
+	__type2(__IS_FP(x) && sizeof((x)+I) == sizeof(float complex), float, \
+	__type2(sizeof((x)+1.0+I) == sizeof(double complex), double, \
+		long double)))
+/* add complex to the type of x */
+#define __RETCAST_CX(x) (__typeof__(__RETCAST(x)0+I))
+#else
+#define __RETCAST(x)
+#define __RETCAST_2(x, y)
+#define __RETCAST_3(x, y, z)
+#define __RETCAST_REAL(x)
+#define __RETCAST_CX(x)
+#endif
+
+/* function selection */
+
+#define __tg_real_nocast(fun, x) ( \
+	__FLT(x) ? fun ## f (x) : \
+	__LDBL(x) ? fun ## l (x) : \
+	fun(x) )
+
+#define __tg_real(fun, x) (__RETCAST(x)__tg_real_nocast(fun, x))
+
+#define __tg_real_2_1(fun, x, y) (__RETCAST(x)( \
+	__FLT(x) ? fun ## f (x, y) : \
+	__LDBL(x) ? fun ## l (x, y) : \
+	fun(x, y) ))
+
+#define __tg_real_2(fun, x, y) (__RETCAST_2(x, y)( \
+	__FLT(x) && __FLT(y) ? fun ## f (x, y) : \
+	__LDBL((x)+(y)) ? fun ## l (x, y) : \
+	fun(x, y) ))
+
+#define __tg_complex(fun, x) (__RETCAST_CX(x)( \
+	__FLTCX((x)+I) && __IS_FP(x) ? fun ## f (x) : \
+	__LDBLCX((x)+I) ? fun ## l (x) : \
+	fun(x) ))
+
+#define __tg_complex_retreal(fun, x) (__RETCAST_REAL(x)( \
+	__FLTCX((x)+I) && __IS_FP(x) ? fun ## f (x) : \
+	__LDBLCX((x)+I) ? fun ## l (x) : \
+	fun(x) ))
+
+#define __tg_real_complex(fun, x) (__RETCAST(x)( \
+	__FLTCX(x) ? c ## fun ## f (x) : \
+	__DBLCX(x) ? c ## fun (x) : \
+	__LDBLCX(x) ? c ## fun ## l (x) : \
+	__FLT(x) ? fun ## f (x) : \
+	__LDBL(x) ? fun ## l (x) : \
+	fun(x) ))
+
+/* special cases */
+
+#define __tg_real_remquo(x, y, z) (__RETCAST_2(x, y)( \
+	__FLT(x) && __FLT(y) ? remquof(x, y, z) : \
+	__LDBL((x)+(y)) ? remquol(x, y, z) : \
+	remquo(x, y, z) ))
+
+#define __tg_real_fma(x, y, z) (__RETCAST_3(x, y, z)( \
+	__FLT(x) && __FLT(y) && __FLT(z) ? fmaf(x, y, z) : \
+	__LDBL((x)+(y)+(z)) ? fmal(x, y, z) : \
+	fma(x, y, z) ))
+
+#define __tg_real_complex_pow(x, y) (__RETCAST_2(x, y)( \
+	__FLTCX((x)+(y)) && __IS_FP(x) && __IS_FP(y) ? cpowf(x, y) : \
+	__FLTCX((x)+(y)) ? cpow(x, y) : \
+	__DBLCX((x)+(y)) ? cpow(x, y) : \
+	__LDBLCX((x)+(y)) ? cpowl(x, y) : \
+	__FLT(x) && __FLT(y) ? powf(x, y) : \
+	__LDBL((x)+(y)) ? powl(x, y) : \
+	pow(x, y) ))
+
+#define __tg_real_complex_fabs(x) (__RETCAST_REAL(x)( \
+	__FLTCX(x) ? cabsf(x) : \
+	__DBLCX(x) ? cabs(x) : \
+	__LDBLCX(x) ? cabsl(x) : \
+	__FLT(x) ? fabsf(x) : \
+	__LDBL(x) ? fabsl(x) : \
+	fabs(x) ))
+
+/* suppress any macros in math.h or complex.h */
+
+#undef acos
+#undef acosh
+#undef asin
+#undef asinh
+#undef atan
+#undef atan2
+#undef atanh
+#undef carg
+#undef cbrt
+#undef ceil
+#undef cimag
+#undef conj
+#undef copysign
+#undef cos
+#undef cosh
+#undef cproj
+#undef creal
+#undef erf
+#undef erfc
+#undef exp
+#undef exp2
+#undef expm1
+#undef fabs
+#undef fdim
+#undef floor
+#undef fma
+#undef fmax
+#undef fmin
+#undef fmod
+#undef frexp
+#undef hypot
+#undef ilogb
+#undef ldexp
+#undef lgamma
+#undef llrint
+#undef llround
+#undef log
+#undef log10
+#undef log1p
+#undef log2
+#undef logb
+#undef lrint
+#undef lround
+#undef nearbyint
+#undef nextafter
+#undef nexttoward
+#undef pow
+#undef remainder
+#undef remquo
+#undef rint
+#undef round
+#undef scalbln
+#undef scalbn
+#undef sin
+#undef sinh
+#undef sqrt
+#undef tan
+#undef tanh
+#undef tgamma
+#undef trunc
+
+/* tg functions */
+
+#define acos(x)         __tg_real_complex(acos, (x))
+#define acosh(x)        __tg_real_complex(acosh, (x))
+#define asin(x)         __tg_real_complex(asin, (x))
+#define asinh(x)        __tg_real_complex(asinh, (x))
+#define atan(x)         __tg_real_complex(atan, (x))
+#define atan2(x,y)      __tg_real_2(atan2, (x), (y))
+#define atanh(x)        __tg_real_complex(atanh, (x))
+#define carg(x)         __tg_complex_retreal(carg, (x))
+#define cbrt(x)         __tg_real(cbrt, (x))
+#define ceil(x)         __tg_real(ceil, (x))
+#define cimag(x)        __tg_complex_retreal(cimag, (x))
+#define conj(x)         __tg_complex(conj, (x))
+#define copysign(x,y)   __tg_real_2(copysign, (x), (y))
+#define cos(x)          __tg_real_complex(cos, (x))
+#define cosh(x)         __tg_real_complex(cosh, (x))
+#define cproj(x)        __tg_complex(cproj, (x))
+#define creal(x)        __tg_complex_retreal(creal, (x))
+#define erf(x)          __tg_real(erf, (x))
+#define erfc(x)         __tg_real(erfc, (x))
+#define exp(x)          __tg_real_complex(exp, (x))
+#define exp2(x)         __tg_real(exp2, (x))
+#define expm1(x)        __tg_real(expm1, (x))
+#define fabs(x)         __tg_real_complex_fabs(x)
+#define fdim(x,y)       __tg_real_2(fdim, (x), (y))
+#define floor(x)        __tg_real(floor, (x))
+#define fma(x,y,z)      __tg_real_fma((x), (y), (z))
+#define fmax(x,y)       __tg_real_2(fmax, (x), (y))
+#define fmin(x,y)       __tg_real_2(fmin, (x), (y))
+#define fmod(x,y)       __tg_real_2(fmod, (x), (y))
+#define frexp(x,y)      __tg_real_2_1(frexp, (x), (y))
+#define hypot(x,y)      __tg_real_2(hypot, (x), (y))
+#define ilogb(x)        __tg_real_nocast(ilogb, (x))
+#define ldexp(x,y)      __tg_real_2_1(ldexp, (x), (y))
+#define lgamma(x)       __tg_real(lgamma, (x))
+#define llrint(x)       __tg_real_nocast(llrint, (x))
+#define llround(x)      __tg_real_nocast(llround, (x))
+#define log(x)          __tg_real_complex(log, (x))
+#define log10(x)        __tg_real(log10, (x))
+#define log1p(x)        __tg_real(log1p, (x))
+#define log2(x)         __tg_real(log2, (x))
+#define logb(x)         __tg_real(logb, (x))
+#define lrint(x)        __tg_real_nocast(lrint, (x))
+#define lround(x)       __tg_real_nocast(lround, (x))
+#define nearbyint(x)    __tg_real(nearbyint, (x))
+#define nextafter(x,y)  __tg_real_2(nextafter, (x), (y))
+#define nexttoward(x,y) __tg_real_2(nexttoward, (x), (y))
+#define pow(x,y)        __tg_real_complex_pow((x), (y))
+#define remainder(x,y)  __tg_real_2(remainder, (x), (y))
+#define remquo(x,y,z)   __tg_real_remquo((x), (y), (z))
+#define rint(x)         __tg_real(rint, (x))
+#define round(x)        __tg_real(round, (x))
+#define scalbln(x,y)    __tg_real_2_1(scalbln, (x), (y))
+#define scalbn(x,y)     __tg_real_2_1(scalbn, (x), (y))
+#define sin(x)          __tg_real_complex(sin, (x))
+#define sinh(x)         __tg_real_complex(sinh, (x))
+#define sqrt(x)         __tg_real_complex(sqrt, (x))
+#define tan(x)          __tg_real_complex(tan, (x))
+#define tanh(x)         __tg_real_complex(tanh, (x))
+#define tgamma(x)       __tg_real(tgamma, (x))
+#define trunc(x)        __tg_real(trunc, (x))
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/threads.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/threads.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/threads.h	(revision 331)
@@ -0,0 +1,87 @@
+#ifndef _THREADS_H
+#define _THREADS_H
+
+#include <features.h>
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+typedef unsigned long thrd_t;
+#else
+typedef struct __pthread *thrd_t;
+#define thread_local _Thread_local
+#endif
+
+typedef int once_flag;
+typedef unsigned tss_t;
+typedef int (*thrd_start_t)(void *);
+typedef void (*tss_dtor_t)(void *);
+
+#define __NEED_cnd_t
+#define __NEED_mtx_t
+
+#include <bits/alltypes.h>
+
+#define TSS_DTOR_ITERATIONS 4
+
+enum {
+	thrd_success  = 0,
+	thrd_busy     = 1,
+	thrd_error    = 2,
+	thrd_nomem    = 3,
+	thrd_timedout = 4,
+};
+
+enum {
+	mtx_plain     = 0,
+	mtx_recursive = 1,
+	mtx_timed     = 2,
+};
+
+#define ONCE_FLAG_INIT 0
+
+int thrd_create(thrd_t *, thrd_start_t, void *);
+_Noreturn void thrd_exit(int);
+
+int thrd_detach(thrd_t);
+int thrd_join(thrd_t, int *);
+
+int thrd_sleep(const struct timespec *, struct timespec *);
+void thrd_yield(void);
+
+thrd_t thrd_current(void);
+int thrd_equal(thrd_t, thrd_t);
+#ifndef __cplusplus
+#define thrd_equal(A, B) ((A) == (B))
+#endif
+
+void call_once(once_flag *, void (*)(void));
+
+int mtx_init(mtx_t *, int);
+void mtx_destroy(mtx_t *);
+
+int mtx_lock(mtx_t *);
+int mtx_timedlock(mtx_t *__restrict, const struct timespec *__restrict);
+int mtx_trylock(mtx_t *);
+int mtx_unlock(mtx_t *);
+
+int cnd_init(cnd_t *);
+void cnd_destroy(cnd_t *);
+
+int cnd_broadcast(cnd_t *);
+int cnd_signal(cnd_t *);
+
+int cnd_timedwait(cnd_t *__restrict, mtx_t *__restrict, const struct timespec *__restrict);
+int cnd_wait(cnd_t *, mtx_t *);
+
+int tss_create(tss_t *, tss_dtor_t);
+void tss_delete(tss_t);
+
+int tss_set(tss_t, void *);
+void *tss_get(tss_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/time.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/time.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/time.h	(revision 331)
@@ -0,0 +1,138 @@
+#ifndef	_TIME_H
+#define _TIME_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#ifdef __cplusplus
+#define NULL 0L
+#else
+#define NULL ((void*)0)
+#endif
+
+
+#define __NEED_size_t
+#define __NEED_time_t
+#define __NEED_clock_t
+#define __NEED_struct_timespec
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+#define __NEED_clockid_t
+#define __NEED_timer_t
+#define __NEED_pid_t
+#define __NEED_locale_t
+#endif
+
+#include <bits/alltypes.h>
+
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#define __tm_gmtoff tm_gmtoff
+#define __tm_zone tm_zone
+#endif
+
+struct tm {
+	int tm_sec;
+	int tm_min;
+	int tm_hour;
+	int tm_mday;
+	int tm_mon;
+	int tm_year;
+	int tm_wday;
+	int tm_yday;
+	int tm_isdst;
+	long __tm_gmtoff;
+	const char *__tm_zone;
+};
+
+clock_t clock (void);
+time_t time (time_t *);
+double difftime (time_t, time_t);
+time_t mktime (struct tm *);
+size_t strftime (char *__restrict, size_t, const char *__restrict, const struct tm *__restrict);
+struct tm *gmtime (const time_t *);
+struct tm *localtime (const time_t *);
+char *asctime (const struct tm *);
+char *ctime (const time_t *);
+int timespec_get(struct timespec *, int);
+
+#define CLOCKS_PER_SEC 1000000L
+
+#define TIME_UTC 1
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+
+size_t strftime_l (char *  __restrict, size_t, const char *  __restrict, const struct tm *  __restrict, locale_t);
+
+struct tm *gmtime_r (const time_t *__restrict, struct tm *__restrict);
+struct tm *localtime_r (const time_t *__restrict, struct tm *__restrict);
+char *asctime_r (const struct tm *__restrict, char *__restrict);
+char *ctime_r (const time_t *, char *);
+
+void tzset (void);
+
+struct itimerspec {
+	struct timespec it_interval;
+	struct timespec it_value;
+};
+
+#define CLOCK_REALTIME           0
+#define CLOCK_MONOTONIC          1
+#define CLOCK_PROCESS_CPUTIME_ID 2
+#define CLOCK_THREAD_CPUTIME_ID  3
+#define CLOCK_MONOTONIC_RAW      4
+#define CLOCK_REALTIME_COARSE    5
+#define CLOCK_MONOTONIC_COARSE   6
+#define CLOCK_BOOTTIME           7
+#define CLOCK_REALTIME_ALARM     8
+#define CLOCK_BOOTTIME_ALARM     9
+#define CLOCK_SGI_CYCLE         10
+#define CLOCK_TAI               11
+
+#define TIMER_ABSTIME 1
+
+int nanosleep (const struct timespec *, struct timespec *);
+int clock_getres (clockid_t, struct timespec *);
+int clock_gettime (clockid_t, struct timespec *);
+int clock_settime (clockid_t, const struct timespec *);
+int clock_nanosleep (clockid_t, int, const struct timespec *, struct timespec *);
+int clock_getcpuclockid (pid_t, clockid_t *);
+
+struct sigevent;
+int timer_create (clockid_t, struct sigevent *__restrict, timer_t *__restrict);
+int timer_delete (timer_t);
+int timer_settime (timer_t, int, const struct itimerspec *__restrict, struct itimerspec *__restrict);
+int timer_gettime (timer_t, struct itimerspec *);
+int timer_getoverrun (timer_t);
+
+extern char *tzname[2];
+
+#endif
+
+
+#if defined(_XOPEN_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+char *strptime (const char *__restrict, const char *__restrict, struct tm *__restrict);
+extern int daylight;
+extern long timezone;
+extern int getdate_err;
+struct tm *getdate (const char *);
+#endif
+
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int stime(const time_t *);
+time_t timegm(struct tm *);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/uchar.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/uchar.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/uchar.h	(revision 331)
@@ -0,0 +1,27 @@
+#ifndef _UCHAR_H
+#define _UCHAR_H
+
+#ifdef __cplusplus
+extern "C" {
+#else
+typedef unsigned short char16_t;
+typedef unsigned char32_t;
+#endif
+
+#define __NEED_mbstate_t
+#define __NEED_size_t
+
+#include <features.h>
+#include <bits/alltypes.h>
+
+size_t c16rtomb(char *__restrict, char16_t, mbstate_t *__restrict);
+size_t mbrtoc16(char16_t *__restrict, const char *__restrict, size_t, mbstate_t *__restrict);
+
+size_t c32rtomb(char *__restrict, char32_t, mbstate_t *__restrict);
+size_t mbrtoc32(char32_t *__restrict, const char *__restrict, size_t, mbstate_t *__restrict);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/ucontext.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/ucontext.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/ucontext.h	(revision 331)
@@ -0,0 +1,25 @@
+#ifndef _UCONTEXT_H
+#define _UCONTEXT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#include <signal.h>
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define NGREG (sizeof(gregset_t)/sizeof(greg_t))
+#endif
+
+struct __ucontext;
+
+int  getcontext(struct __ucontext *);
+void makecontext(struct __ucontext *, void (*)(void), int, ...);
+int  setcontext(const struct __ucontext *);
+int  swapcontext(struct __ucontext *, const struct __ucontext *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/ulimit.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/ulimit.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/ulimit.h	(revision 331)
@@ -0,0 +1,17 @@
+#ifndef _ULIMIT_H
+#define _ULIMIT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UL_GETFSIZE 1
+#define UL_SETFSIZE 2
+
+long ulimit (int, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/unistd.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/unistd.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/unistd.h	(revision 331)
@@ -0,0 +1,467 @@
+#ifndef	_UNISTD_H
+#define	_UNISTD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define STDIN_FILENO  0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+#ifdef __cplusplus
+#define NULL 0L
+#else
+#define NULL ((void*)0)
+#endif
+
+#define __NEED_size_t
+#define __NEED_ssize_t
+#define __NEED_uid_t
+#define __NEED_gid_t
+#define __NEED_off_t
+#define __NEED_pid_t
+#define __NEED_intptr_t
+#define __NEED_useconds_t
+
+#include <bits/alltypes.h>
+
+int pipe(int [2]);
+int pipe2(int [2], int);
+int close(int);
+int posix_close(int, int);
+int dup(int);
+int dup2(int, int);
+int dup3(int, int, int);
+off_t lseek(int, off_t, int);
+int fsync(int);
+int fdatasync(int);
+
+ssize_t read(int, void *, size_t);
+ssize_t write(int, const void *, size_t);
+ssize_t pread(int, void *, size_t, off_t);
+ssize_t pwrite(int, const void *, size_t, off_t);
+
+int chown(const char *, uid_t, gid_t);
+int fchown(int, uid_t, gid_t);
+int lchown(const char *, uid_t, gid_t);
+int fchownat(int, const char *, uid_t, gid_t, int);
+
+int link(const char *, const char *);
+int linkat(int, const char *, int, const char *, int);
+int symlink(const char *, const char *);
+int symlinkat(const char *, int, const char *);
+ssize_t readlink(const char *__restrict, char *__restrict, size_t);
+ssize_t readlinkat(int, const char *__restrict, char *__restrict, size_t);
+int unlink(const char *);
+int unlinkat(int, const char *, int);
+int rmdir(const char *);
+int truncate(const char *, off_t);
+int ftruncate(int, off_t);
+
+#define F_OK 0
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+
+int access(const char *, int);
+int faccessat(int, const char *, int, int);
+
+int chdir(const char *);
+int fchdir(int);
+char *getcwd(char *, size_t);
+
+unsigned alarm(unsigned);
+unsigned sleep(unsigned);
+int pause(void);
+
+pid_t fork(void);
+int execve(const char *, char *const [], char *const []);
+int execv(const char *, char *const []);
+int execle(const char *, const char *, ...);
+int execl(const char *, const char *, ...);
+int execvp(const char *, char *const []);
+int execlp(const char *, const char *, ...);
+int fexecve(int, char *const [], char *const []);
+_Noreturn void _exit(int);
+
+pid_t getpid(void);
+pid_t getppid(void);
+pid_t getpgrp(void);
+pid_t getpgid(pid_t);
+int setpgid(pid_t, pid_t);
+pid_t setsid(void);
+pid_t getsid(pid_t);
+char *ttyname(int);
+int ttyname_r(int, char *, size_t);
+int isatty(int);
+pid_t tcgetpgrp(int);
+int tcsetpgrp(int, pid_t);
+
+uid_t getuid(void);
+uid_t geteuid(void);
+gid_t getgid(void);
+gid_t getegid(void);
+int getgroups(int, gid_t []);
+int setuid(uid_t);
+int seteuid(uid_t);
+int setgid(gid_t);
+int setegid(gid_t);
+
+char *getlogin(void);
+int getlogin_r(char *, size_t);
+int gethostname(char *, size_t);
+char *ctermid(char *);
+
+int getopt(int, char * const [], const char *);
+extern char *optarg;
+extern int optind, opterr, optopt;
+
+long pathconf(const char *, int);
+long fpathconf(int, int);
+long sysconf(int);
+size_t confstr(int, char *, size_t);
+
+#define F_ULOCK 0
+#define F_LOCK  1
+#define F_TLOCK 2
+#define F_TEST  3
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int setreuid(uid_t, uid_t);
+int setregid(gid_t, gid_t);
+int lockf(int, int, off_t);
+long gethostid(void);
+int nice(int);
+void sync(void);
+pid_t setpgrp(void);
+char *crypt(const char *, const char *);
+void encrypt(char *, int);
+void swab(const void *__restrict, void *__restrict, ssize_t);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) \
+ || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700)
+int usleep(unsigned);
+unsigned ualarm(unsigned, unsigned);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define L_SET 0
+#define L_INCR 1
+#define L_XTND 2
+int brk(void *);
+void *sbrk(intptr_t);
+pid_t vfork(void);
+int vhangup(void);
+int chroot(const char *);
+int getpagesize(void);
+int getdtablesize(void);
+int sethostname(const char *, size_t);
+int getdomainname(char *, size_t);
+int setdomainname(const char *, size_t);
+int setgroups(size_t, const gid_t *);
+char *getpass(const char *);
+int daemon(int, int);
+void setusershell(void);
+void endusershell(void);
+char *getusershell(void);
+int acct(const char *);
+long syscall(long, ...);
+int execvpe(const char *, char *const [], char *const []);
+int issetugid(void);
+#endif
+
+#ifdef _GNU_SOURCE
+extern char **environ;
+int setresuid(uid_t, uid_t, uid_t);
+int setresgid(gid_t, gid_t, gid_t);
+int getresuid(uid_t *, uid_t *, uid_t *);
+int getresgid(gid_t *, gid_t *, gid_t *);
+char *get_current_dir_name(void);
+int syncfs(int);
+int euidaccess(const char *, int);
+int eaccess(const char *, int);
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+#define lseek64 lseek
+#define pread64 pread
+#define pwrite64 pwrite
+#define truncate64 truncate
+#define ftruncate64 ftruncate
+#define lockf64 lockf
+#define off64_t off_t
+#endif
+
+#define POSIX_CLOSE_RESTART     0
+
+#define _XOPEN_VERSION          700
+#define _XOPEN_UNIX             1
+#define _XOPEN_ENH_I18N         1
+
+#define _POSIX_VERSION          200809L
+#define _POSIX2_VERSION         _POSIX_VERSION
+
+#define _POSIX_ADVISORY_INFO    _POSIX_VERSION
+#define _POSIX_CHOWN_RESTRICTED 1
+#define _POSIX_IPV6             _POSIX_VERSION
+#define _POSIX_JOB_CONTROL      1
+#define _POSIX_MAPPED_FILES     _POSIX_VERSION
+#define _POSIX_MEMLOCK          _POSIX_VERSION
+#define _POSIX_MEMLOCK_RANGE    _POSIX_VERSION
+#define _POSIX_MEMORY_PROTECTION _POSIX_VERSION
+#define _POSIX_MESSAGE_PASSING  _POSIX_VERSION
+#define _POSIX_FSYNC            _POSIX_VERSION
+#define _POSIX_NO_TRUNC         1
+#define _POSIX_RAW_SOCKETS      _POSIX_VERSION
+#define _POSIX_REALTIME_SIGNALS _POSIX_VERSION
+#define _POSIX_REGEXP           1
+#define _POSIX_SAVED_IDS        1
+#define _POSIX_SHELL            1
+#define _POSIX_SPAWN            _POSIX_VERSION
+#define _POSIX_VDISABLE         0
+
+#define _POSIX_THREADS          _POSIX_VERSION
+#define _POSIX_THREAD_PROCESS_SHARED _POSIX_VERSION
+#define _POSIX_THREAD_SAFE_FUNCTIONS _POSIX_VERSION
+#define _POSIX_THREAD_ATTR_STACKADDR _POSIX_VERSION
+#define _POSIX_THREAD_ATTR_STACKSIZE _POSIX_VERSION
+#define _POSIX_THREAD_PRIORITY_SCHEDULING _POSIX_VERSION
+#define _POSIX_THREAD_CPUTIME   _POSIX_VERSION
+#define _POSIX_TIMERS           _POSIX_VERSION
+#define _POSIX_TIMEOUTS         _POSIX_VERSION
+#define _POSIX_MONOTONIC_CLOCK  _POSIX_VERSION
+#define _POSIX_CPUTIME          _POSIX_VERSION
+#define _POSIX_CLOCK_SELECTION  _POSIX_VERSION
+#define _POSIX_BARRIERS         _POSIX_VERSION
+#define _POSIX_SPIN_LOCKS       _POSIX_VERSION
+#define _POSIX_READER_WRITER_LOCKS _POSIX_VERSION
+#define _POSIX_ASYNCHRONOUS_IO  _POSIX_VERSION
+#define _POSIX_SEMAPHORES       _POSIX_VERSION
+#define _POSIX_SHARED_MEMORY_OBJECTS _POSIX_VERSION
+
+#define _POSIX2_C_BIND          _POSIX_VERSION
+
+#include <bits/posix.h>
+
+
+
+#define _PC_LINK_MAX	0
+#define _PC_MAX_CANON	1
+#define _PC_MAX_INPUT	2
+#define _PC_NAME_MAX	3
+#define _PC_PATH_MAX	4
+#define _PC_PIPE_BUF	5
+#define _PC_CHOWN_RESTRICTED	6
+#define _PC_NO_TRUNC	7
+#define _PC_VDISABLE	8
+#define _PC_SYNC_IO	9
+#define _PC_ASYNC_IO	10
+#define _PC_PRIO_IO	11
+#define _PC_SOCK_MAXBUF	12
+#define _PC_FILESIZEBITS	13
+#define _PC_REC_INCR_XFER_SIZE	14
+#define _PC_REC_MAX_XFER_SIZE	15
+#define _PC_REC_MIN_XFER_SIZE	16
+#define _PC_REC_XFER_ALIGN	17
+#define _PC_ALLOC_SIZE_MIN	18
+#define _PC_SYMLINK_MAX	19
+#define _PC_2_SYMLINKS	20
+
+#define _SC_ARG_MAX	0
+#define _SC_CHILD_MAX	1
+#define _SC_CLK_TCK	2
+#define _SC_NGROUPS_MAX	3
+#define _SC_OPEN_MAX	4
+#define _SC_STREAM_MAX	5
+#define _SC_TZNAME_MAX	6
+#define _SC_JOB_CONTROL	7
+#define _SC_SAVED_IDS	8
+#define _SC_REALTIME_SIGNALS	9
+#define _SC_PRIORITY_SCHEDULING	10
+#define _SC_TIMERS	11
+#define _SC_ASYNCHRONOUS_IO	12
+#define _SC_PRIORITIZED_IO	13
+#define _SC_SYNCHRONIZED_IO	14
+#define _SC_FSYNC	15
+#define _SC_MAPPED_FILES	16
+#define _SC_MEMLOCK	17
+#define _SC_MEMLOCK_RANGE	18
+#define _SC_MEMORY_PROTECTION	19
+#define _SC_MESSAGE_PASSING	20
+#define _SC_SEMAPHORES	21
+#define _SC_SHARED_MEMORY_OBJECTS	22
+#define _SC_AIO_LISTIO_MAX	23
+#define _SC_AIO_MAX	24
+#define _SC_AIO_PRIO_DELTA_MAX	25
+#define _SC_DELAYTIMER_MAX	26
+#define _SC_MQ_OPEN_MAX	27
+#define _SC_MQ_PRIO_MAX	28
+#define _SC_VERSION	29
+#define _SC_PAGE_SIZE	30
+#define _SC_PAGESIZE	30 /* !! */
+#define _SC_RTSIG_MAX	31
+#define _SC_SEM_NSEMS_MAX	32
+#define _SC_SEM_VALUE_MAX	33
+#define _SC_SIGQUEUE_MAX	34
+#define _SC_TIMER_MAX	35
+#define _SC_BC_BASE_MAX	36
+#define _SC_BC_DIM_MAX	37
+#define _SC_BC_SCALE_MAX	38
+#define _SC_BC_STRING_MAX	39
+#define _SC_COLL_WEIGHTS_MAX	40
+#define _SC_EXPR_NEST_MAX	42
+#define _SC_LINE_MAX	43
+#define _SC_RE_DUP_MAX	44
+#define _SC_2_VERSION	46
+#define _SC_2_C_BIND	47
+#define _SC_2_C_DEV	48
+#define _SC_2_FORT_DEV	49
+#define _SC_2_FORT_RUN	50
+#define _SC_2_SW_DEV	51
+#define _SC_2_LOCALEDEF	52
+#define _SC_UIO_MAXIOV	60 /* !! */
+#define _SC_IOV_MAX	60
+#define _SC_THREADS	67
+#define _SC_THREAD_SAFE_FUNCTIONS	68
+#define _SC_GETGR_R_SIZE_MAX	69
+#define _SC_GETPW_R_SIZE_MAX	70
+#define _SC_LOGIN_NAME_MAX	71
+#define _SC_TTY_NAME_MAX	72
+#define _SC_THREAD_DESTRUCTOR_ITERATIONS	73
+#define _SC_THREAD_KEYS_MAX	74
+#define _SC_THREAD_STACK_MIN	75
+#define _SC_THREAD_THREADS_MAX	76
+#define _SC_THREAD_ATTR_STACKADDR	77
+#define _SC_THREAD_ATTR_STACKSIZE	78
+#define _SC_THREAD_PRIORITY_SCHEDULING	79
+#define _SC_THREAD_PRIO_INHERIT	80
+#define _SC_THREAD_PRIO_PROTECT	81
+#define _SC_THREAD_PROCESS_SHARED	82
+#define _SC_NPROCESSORS_CONF	83
+#define _SC_NPROCESSORS_ONLN	84
+#define _SC_PHYS_PAGES	85
+#define _SC_AVPHYS_PAGES	86
+#define _SC_ATEXIT_MAX	87
+#define _SC_PASS_MAX	88
+#define _SC_XOPEN_VERSION	89
+#define _SC_XOPEN_XCU_VERSION	90
+#define _SC_XOPEN_UNIX	91
+#define _SC_XOPEN_CRYPT	92
+#define _SC_XOPEN_ENH_I18N	93
+#define _SC_XOPEN_SHM	94
+#define _SC_2_CHAR_TERM	95
+#define _SC_2_UPE	97
+#define _SC_XOPEN_XPG2	98
+#define _SC_XOPEN_XPG3	99
+#define _SC_XOPEN_XPG4	100
+#define _SC_NZERO	109
+#define _SC_XBS5_ILP32_OFF32	125
+#define _SC_XBS5_ILP32_OFFBIG	126
+#define _SC_XBS5_LP64_OFF64	127
+#define _SC_XBS5_LPBIG_OFFBIG	128
+#define _SC_XOPEN_LEGACY	129
+#define _SC_XOPEN_REALTIME	130
+#define _SC_XOPEN_REALTIME_THREADS	131
+#define _SC_ADVISORY_INFO	132
+#define _SC_BARRIERS	133
+#define _SC_CLOCK_SELECTION	137
+#define _SC_CPUTIME	138
+#define _SC_THREAD_CPUTIME	139
+#define _SC_MONOTONIC_CLOCK	149
+#define _SC_READER_WRITER_LOCKS	153
+#define _SC_SPIN_LOCKS	154
+#define _SC_REGEXP	155
+#define _SC_SHELL	157
+#define _SC_SPAWN	159
+#define _SC_SPORADIC_SERVER	160
+#define _SC_THREAD_SPORADIC_SERVER	161
+#define _SC_TIMEOUTS	164
+#define _SC_TYPED_MEMORY_OBJECTS	165
+#define _SC_2_PBS	168
+#define _SC_2_PBS_ACCOUNTING	169
+#define _SC_2_PBS_LOCATE	170
+#define _SC_2_PBS_MESSAGE	171
+#define _SC_2_PBS_TRACK	172
+#define _SC_SYMLOOP_MAX	173
+#define _SC_STREAMS	174
+#define _SC_2_PBS_CHECKPOINT	175
+#define _SC_V6_ILP32_OFF32	176
+#define _SC_V6_ILP32_OFFBIG	177
+#define _SC_V6_LP64_OFF64	178
+#define _SC_V6_LPBIG_OFFBIG	179
+#define _SC_HOST_NAME_MAX	180
+#define _SC_TRACE	181
+#define _SC_TRACE_EVENT_FILTER	182
+#define _SC_TRACE_INHERIT	183
+#define _SC_TRACE_LOG	184
+
+#define _SC_IPV6	235
+#define _SC_RAW_SOCKETS	236
+#define _SC_V7_ILP32_OFF32	237
+#define _SC_V7_ILP32_OFFBIG	238
+#define _SC_V7_LP64_OFF64	239
+#define _SC_V7_LPBIG_OFFBIG	240
+#define _SC_SS_REPL_MAX	241
+#define _SC_TRACE_EVENT_NAME_MAX	242
+#define _SC_TRACE_NAME_MAX	243
+#define _SC_TRACE_SYS_MAX	244
+#define _SC_TRACE_USER_EVENT_MAX	245
+#define _SC_XOPEN_STREAMS	246
+#define _SC_THREAD_ROBUST_PRIO_INHERIT	247
+#define _SC_THREAD_ROBUST_PRIO_PROTECT	248
+
+#define _CS_PATH	0
+#define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS	1
+#define _CS_GNU_LIBC_VERSION	2
+#define _CS_GNU_LIBPTHREAD_VERSION	3
+#define _CS_POSIX_V5_WIDTH_RESTRICTED_ENVS	4
+#define _CS_POSIX_V7_WIDTH_RESTRICTED_ENVS	5
+
+#define _CS_POSIX_V6_ILP32_OFF32_CFLAGS	1116
+#define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS	1117
+#define _CS_POSIX_V6_ILP32_OFF32_LIBS	1118
+#define _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS	1119
+#define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS	1120
+#define _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS	1121
+#define _CS_POSIX_V6_ILP32_OFFBIG_LIBS	1122
+#define _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS	1123
+#define _CS_POSIX_V6_LP64_OFF64_CFLAGS	1124
+#define _CS_POSIX_V6_LP64_OFF64_LDFLAGS	1125
+#define _CS_POSIX_V6_LP64_OFF64_LIBS	1126
+#define _CS_POSIX_V6_LP64_OFF64_LINTFLAGS	1127
+#define _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS	1128
+#define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS	1129
+#define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS	1130
+#define _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS	1131
+#define _CS_POSIX_V7_ILP32_OFF32_CFLAGS	1132
+#define _CS_POSIX_V7_ILP32_OFF32_LDFLAGS	1133
+#define _CS_POSIX_V7_ILP32_OFF32_LIBS	1134
+#define _CS_POSIX_V7_ILP32_OFF32_LINTFLAGS	1135
+#define _CS_POSIX_V7_ILP32_OFFBIG_CFLAGS	1136
+#define _CS_POSIX_V7_ILP32_OFFBIG_LDFLAGS	1137
+#define _CS_POSIX_V7_ILP32_OFFBIG_LIBS	1138
+#define _CS_POSIX_V7_ILP32_OFFBIG_LINTFLAGS	1139
+#define _CS_POSIX_V7_LP64_OFF64_CFLAGS	1140
+#define _CS_POSIX_V7_LP64_OFF64_LDFLAGS	1141
+#define _CS_POSIX_V7_LP64_OFF64_LIBS	1142
+#define _CS_POSIX_V7_LP64_OFF64_LINTFLAGS	1143
+#define _CS_POSIX_V7_LPBIG_OFFBIG_CFLAGS	1144
+#define _CS_POSIX_V7_LPBIG_OFFBIG_LDFLAGS	1145
+#define _CS_POSIX_V7_LPBIG_OFFBIG_LIBS	1146
+#define _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS	1147
+#define _CS_V6_ENV	1148
+#define _CS_V7_ENV	1149
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/utime.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/utime.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/utime.h	(revision 331)
@@ -0,0 +1,23 @@
+#ifndef	_UTIME_H
+#define	_UTIME_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __NEED_time_t
+
+#include <bits/alltypes.h>
+
+struct utimbuf {
+	time_t actime;
+	time_t modtime;
+};
+
+int utime (const char *, const struct utimbuf *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/utmp.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/utmp.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/utmp.h	(revision 331)
@@ -0,0 +1,52 @@
+#ifndef _UTMP_H
+#define _UTMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <utmpx.h>
+
+#define ACCOUNTING 9
+#define UT_NAMESIZE 32
+#define UT_HOSTSIZE 256
+#define UT_LINESIZE 32
+
+struct lastlog {
+	time_t ll_time;
+	char ll_line[UT_LINESIZE];
+	char ll_host[UT_HOSTSIZE];
+};
+
+#define ut_time ut_tv.tv_sec
+#define ut_name ut_user
+#define ut_addr ut_addr_v6[0]
+#define utmp utmpx
+#define e_exit __e_exit
+#define e_termination __e_termination
+
+void         endutent(void);
+struct utmp *getutent(void);
+struct utmp *getutid(const struct utmp *);
+struct utmp *getutline(const struct utmp *);
+struct utmp *pututline(const struct utmp *);
+void         setutent(void);
+
+void updwtmp(const char *, const struct utmp *);
+int utmpname(const char *);
+
+int login_tty(int);
+
+#define _PATH_UTMP "/dev/null/utmp"
+#define _PATH_WTMP "/dev/null/wtmp"
+
+#define UTMP_FILE _PATH_UTMP
+#define WTMP_FILE _PATH_WTMP
+#define UTMP_FILENAME _PATH_UTMP
+#define WTMP_FILENAME _PATH_WTMP
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/utmpx.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/utmpx.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/utmpx.h	(revision 331)
@@ -0,0 +1,62 @@
+#ifndef _UTMPX_H
+#define _UTMPX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_pid_t
+#define __NEED_time_t
+#define __NEED_suseconds_t
+#define __NEED_struct_timeval
+
+#include <bits/alltypes.h>
+
+struct utmpx {
+	short ut_type;
+	pid_t ut_pid;
+	char ut_line[32];
+	char ut_id[4];
+	char ut_user[32];
+	char ut_host[256];
+	struct {
+		short __e_termination;
+		short __e_exit;
+	} ut_exit;
+	long ut_session;
+	struct timeval ut_tv;
+	unsigned ut_addr_v6[4];
+	char __unused[20];
+};
+
+void          endutxent(void);
+struct utmpx *getutxent(void);
+struct utmpx *getutxid(const struct utmpx *);
+struct utmpx *getutxline(const struct utmpx *);
+struct utmpx *pututxline(const struct utmpx *);
+void          setutxent(void);
+
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#define e_exit __e_exit
+#define e_termination __e_termination
+void updwtmpx(const char *, const struct utmpx *);
+int utmpxname(const char *);
+#endif
+
+#define EMPTY           0
+#define RUN_LVL         1
+#define BOOT_TIME       2
+#define NEW_TIME        3
+#define OLD_TIME        4
+#define INIT_PROCESS    5
+#define LOGIN_PROCESS   6
+#define USER_PROCESS    7
+#define DEAD_PROCESS    8
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/values.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/values.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/values.h	(revision 331)
@@ -0,0 +1,39 @@
+#ifndef _VALUES_H
+#define _VALUES_H
+
+#include <limits.h>
+
+#define CHARBITS   (sizeof(char)   * 8)
+#define SHORTBITS  (sizeof(short)  * 8)
+#define INTBITS    (sizeof(int)    * 8)
+#define LONGBITS   (sizeof(long)   * 8)
+#define PTRBITS    (sizeof(char *) * 8)
+#define DOUBLEBITS (sizeof(double) * 8)
+#define FLOATBITS  (sizeof(float)  * 8)
+
+#define MINSHORT SHRT_MIN
+#define MININT   INT_MIN
+#define MINLONG  LONG_MIN
+
+#define MAXSHORT SHRT_MAX
+#define MAXINT   INT_MAX
+#define MAXLONG  LONG_MAX
+
+#define HIBITS   MINSHORT
+#define HIBITL   MINLONG
+
+#include <float.h>
+
+#define MAXDOUBLE DBL_MAX
+#undef  MAXFLOAT
+#define MAXFLOAT  FLT_MAX
+#define MINDOUBLE DBL_MIN
+#define MINFLOAT  FLT_MIN
+#define DMINEXP   DBL_MIN_EXP
+#define FMINEXP   FLT_MIN_EXP
+#define DMAXEXP   DBL_MAX_EXP
+#define FMAXEXP   FLT_MAX_EXP
+
+#define BITSPERBYTE CHAR_BIT
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/wait.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/wait.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/wait.h	(revision 331)
@@ -0,0 +1,2 @@
+#warning redirecting incorrect #include <wait.h> to <sys/wait.h>
+#include <sys/wait.h>
Index: EcnlProtoTool/trunk/musl-1.1.18/include/wchar.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/wchar.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/wchar.h	(revision 331)
@@ -0,0 +1,201 @@
+#ifndef _WCHAR_H
+#define _WCHAR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_FILE
+#define __NEED___isoc_va_list
+#define __NEED_size_t
+#define __NEED_wchar_t
+#define __NEED_wint_t
+#define __NEED_mbstate_t
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_locale_t
+#define __NEED_va_list
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_wctype_t
+#endif
+
+#include <bits/alltypes.h>
+
+#if L'\0'-1 > 0
+#define WCHAR_MAX (0xffffffffu+L'\0')
+#define WCHAR_MIN (0+L'\0')
+#else
+#define WCHAR_MAX (0x7fffffff+L'\0')
+#define WCHAR_MIN (-1-0x7fffffff+L'\0')
+#endif
+
+#ifdef __cplusplus
+#define NULL 0L
+#else
+#define NULL ((void*)0)
+#endif
+
+#undef WEOF
+#define WEOF 0xffffffffU
+
+wchar_t *wcscpy (wchar_t *__restrict, const wchar_t *__restrict);
+wchar_t *wcsncpy (wchar_t *__restrict, const wchar_t *__restrict, size_t);
+
+wchar_t *wcscat (wchar_t *__restrict, const wchar_t *__restrict);
+wchar_t *wcsncat (wchar_t *__restrict, const wchar_t *__restrict, size_t);
+
+int wcscmp (const wchar_t *, const wchar_t *);
+int wcsncmp (const wchar_t *, const wchar_t *, size_t);
+
+int wcscoll(const wchar_t *, const wchar_t *);
+size_t wcsxfrm (wchar_t *__restrict, const wchar_t *__restrict, size_t);
+
+wchar_t *wcschr (const wchar_t *, wchar_t);
+wchar_t *wcsrchr (const wchar_t *, wchar_t);
+
+size_t wcscspn (const wchar_t *, const wchar_t *);
+size_t wcsspn (const wchar_t *, const wchar_t *);
+wchar_t *wcspbrk (const wchar_t *, const wchar_t *);
+
+wchar_t *wcstok (wchar_t *__restrict, const wchar_t *__restrict, wchar_t **__restrict);
+
+size_t wcslen (const wchar_t *);
+
+wchar_t *wcsstr (const wchar_t *__restrict, const wchar_t *__restrict);
+wchar_t *wcswcs (const wchar_t *, const wchar_t *);
+
+wchar_t *wmemchr (const wchar_t *, wchar_t, size_t);
+int wmemcmp (const wchar_t *, const wchar_t *, size_t);
+wchar_t *wmemcpy (wchar_t *__restrict, const wchar_t *__restrict, size_t);
+wchar_t *wmemmove (wchar_t *, const wchar_t *, size_t);
+wchar_t *wmemset (wchar_t *, wchar_t, size_t);
+
+wint_t btowc (int);
+int wctob (wint_t);
+
+int mbsinit (const mbstate_t *);
+size_t mbrtowc (wchar_t *__restrict, const char *__restrict, size_t, mbstate_t *__restrict);
+size_t wcrtomb (char *__restrict, wchar_t, mbstate_t *__restrict);
+
+size_t mbrlen (const char *__restrict, size_t, mbstate_t *__restrict);
+
+size_t mbsrtowcs (wchar_t *__restrict, const char **__restrict, size_t, mbstate_t *__restrict);
+size_t wcsrtombs (char *__restrict, const wchar_t **__restrict, size_t, mbstate_t *__restrict);
+
+float wcstof (const wchar_t *__restrict, wchar_t **__restrict);
+double wcstod (const wchar_t *__restrict, wchar_t **__restrict);
+long double wcstold (const wchar_t *__restrict, wchar_t **__restrict);
+
+long wcstol (const wchar_t *__restrict, wchar_t **__restrict, int);
+unsigned long wcstoul (const wchar_t *__restrict, wchar_t **__restrict, int);
+
+long long wcstoll (const wchar_t *__restrict, wchar_t **__restrict, int);
+unsigned long long wcstoull (const wchar_t *__restrict, wchar_t **__restrict, int);
+
+
+
+int fwide (FILE *, int);
+
+
+int wprintf (const wchar_t *__restrict, ...);
+int fwprintf (FILE *__restrict, const wchar_t *__restrict, ...);
+int swprintf (wchar_t *__restrict, size_t, const wchar_t *__restrict, ...);
+
+int vwprintf (const wchar_t *__restrict, __isoc_va_list);
+int vfwprintf (FILE *__restrict, const wchar_t *__restrict, __isoc_va_list);
+int vswprintf (wchar_t *__restrict, size_t, const wchar_t *__restrict, __isoc_va_list);
+
+int wscanf (const wchar_t *__restrict, ...);
+int fwscanf (FILE *__restrict, const wchar_t *__restrict, ...);
+int swscanf (const wchar_t *__restrict, const wchar_t *__restrict, ...);
+
+int vwscanf (const wchar_t *__restrict, __isoc_va_list);
+int vfwscanf (FILE *__restrict, const wchar_t *__restrict, __isoc_va_list);
+int vswscanf (const wchar_t *__restrict, const wchar_t *__restrict, __isoc_va_list);
+
+wint_t fgetwc (FILE *);
+wint_t getwc (FILE *);
+wint_t getwchar (void);
+
+wint_t fputwc (wchar_t, FILE *);
+wint_t putwc (wchar_t, FILE *);
+wint_t putwchar (wchar_t);
+
+wchar_t *fgetws (wchar_t *__restrict, int, FILE *__restrict);
+int fputws (const wchar_t *__restrict, FILE *__restrict);
+
+wint_t ungetwc (wint_t, FILE *);
+
+struct tm;
+size_t wcsftime (wchar_t *__restrict, size_t, const wchar_t *__restrict, const struct tm *__restrict);
+
+#undef iswdigit
+
+#if defined(_GNU_SOURCE)
+wint_t fgetwc_unlocked (FILE *);
+wint_t getwc_unlocked (FILE *);
+wint_t getwchar_unlocked (void);
+wint_t fputwc_unlocked (wchar_t, FILE *);
+wint_t putwc_unlocked (wchar_t, FILE *);
+wint_t putwchar_unlocked (wchar_t);
+wchar_t *fgetws_unlocked (wchar_t *__restrict, int, FILE *__restrict);
+int fputws_unlocked (const wchar_t *__restrict, FILE *__restrict);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+size_t wcsftime_l (wchar_t *__restrict, size_t, const wchar_t *__restrict, const struct tm *__restrict, locale_t);
+#endif
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE)  || defined(_BSD_SOURCE)
+FILE *open_wmemstream(wchar_t **, size_t *);
+size_t mbsnrtowcs(wchar_t *__restrict, const char **__restrict, size_t, size_t, mbstate_t *__restrict);
+size_t wcsnrtombs(char *__restrict, const wchar_t **__restrict, size_t, size_t, mbstate_t *__restrict);
+wchar_t *wcsdup(const wchar_t *);
+size_t wcsnlen (const wchar_t *, size_t);
+wchar_t *wcpcpy (wchar_t *__restrict, const wchar_t *__restrict);
+wchar_t *wcpncpy (wchar_t *__restrict, const wchar_t *__restrict, size_t);
+int wcscasecmp(const wchar_t *, const wchar_t *);
+int wcscasecmp_l(const wchar_t *, const wchar_t *, locale_t);
+int wcsncasecmp(const wchar_t *, const wchar_t *, size_t);
+int wcsncasecmp_l(const wchar_t *, const wchar_t *, size_t, locale_t);
+int wcscoll_l(const wchar_t *, const wchar_t *, locale_t);
+size_t wcsxfrm_l(wchar_t *__restrict, const wchar_t *__restrict, size_t, locale_t);
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+int wcwidth (wchar_t);
+int wcswidth (const wchar_t *, size_t);
+int       iswalnum(wint_t);
+int       iswalpha(wint_t);
+int       iswblank(wint_t);
+int       iswcntrl(wint_t);
+int       iswdigit(wint_t);
+int       iswgraph(wint_t);
+int       iswlower(wint_t);
+int       iswprint(wint_t);
+int       iswpunct(wint_t);
+int       iswspace(wint_t);
+int       iswupper(wint_t);
+int       iswxdigit(wint_t);
+int       iswctype(wint_t, wctype_t);
+wint_t    towlower(wint_t);
+wint_t    towupper(wint_t);
+wctype_t  wctype(const char *);
+
+#ifndef __cplusplus
+#undef iswdigit
+#define iswdigit(a) (0 ? iswdigit(a) : ((unsigned)(a)-'0') < 10)
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/wctype.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/wctype.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/wctype.h	(revision 331)
@@ -0,0 +1,79 @@
+#ifndef _WCTYPE_H
+#define _WCTYPE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_wint_t
+#define __NEED_wctype_t
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define __NEED_locale_t
+#endif
+
+#include <bits/alltypes.h>
+
+typedef const int * wctrans_t;
+
+#undef WEOF
+#define WEOF 0xffffffffU
+
+#undef iswdigit
+
+int       iswalnum(wint_t);
+int       iswalpha(wint_t);
+int       iswblank(wint_t);
+int       iswcntrl(wint_t);
+int       iswdigit(wint_t);
+int       iswgraph(wint_t);
+int       iswlower(wint_t);
+int       iswprint(wint_t);
+int       iswpunct(wint_t);
+int       iswspace(wint_t);
+int       iswupper(wint_t);
+int       iswxdigit(wint_t);
+int       iswctype(wint_t, wctype_t);
+wint_t    towctrans(wint_t, wctrans_t);
+wint_t    towlower(wint_t);
+wint_t    towupper(wint_t);
+wctrans_t wctrans(const char *);
+wctype_t  wctype(const char *);
+
+#ifndef __cplusplus
+#undef iswdigit
+#define iswdigit(a) (0 ? iswdigit(a) : ((unsigned)(a)-'0') < 10)
+#endif
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+
+int iswalnum_l(wint_t, locale_t);
+int iswalpha_l(wint_t, locale_t);
+int iswblank_l(wint_t, locale_t);
+int iswcntrl_l(wint_t, locale_t);
+int iswdigit_l(wint_t, locale_t);
+int iswgraph_l(wint_t, locale_t);
+int iswlower_l(wint_t, locale_t);
+int iswprint_l(wint_t, locale_t);
+int iswpunct_l(wint_t, locale_t);
+int iswspace_l(wint_t, locale_t);
+int iswupper_l(wint_t, locale_t);
+int iswxdigit_l(wint_t, locale_t);
+int iswctype_l(wint_t, wctype_t, locale_t);
+wint_t towlower_l(wint_t, locale_t);
+wint_t towupper_l(wint_t, locale_t);
+wint_t towctrans_l(wint_t, wctrans_t, locale_t);
+wctrans_t wctrans_l(const char *, locale_t);
+wctype_t  wctype_l(const char *, locale_t);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/include/wordexp.h
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/include/wordexp.h	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/include/wordexp.h	(revision 331)
@@ -0,0 +1,41 @@
+#ifndef	_WORDEXP_H
+#define	_WORDEXP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#define __NEED_size_t
+
+#include <bits/alltypes.h>
+
+#define WRDE_DOOFFS  1
+#define WRDE_APPEND  2
+#define WRDE_NOCMD   4
+#define WRDE_REUSE   8
+#define WRDE_SHOWERR 16
+#define WRDE_UNDEF   32
+
+typedef struct {
+	size_t we_wordc;
+	char **we_wordv;
+	size_t we_offs;
+} wordexp_t;
+
+#define WRDE_NOSYS   -1
+#define WRDE_NOSPACE 1
+#define WRDE_BADCHAR 2
+#define WRDE_BADVAL  3
+#define WRDE_CMDSUB  4
+#define WRDE_SYNTAX  5
+
+int wordexp (const char *__restrict, wordexp_t *__restrict, int);
+void wordfree (wordexp_t *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/musl-1.1.18/src/internal/arm/syscall.s
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/src/internal/arm/syscall.s	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/src/internal/arm/syscall.s	(revision 331)
@@ -0,0 +1,15 @@
+.syntax unified
+.global __syscall
+.hidden __syscall
+.type __syscall,%function
+__syscall:
+	mov ip,sp
+	stmfd sp!,{r4,r5,r6,r7,lr}
+	mov r7,r0
+	mov r0,r1
+	mov r1,r2
+	mov r2,r3
+	ldmfd ip,{r3,r4,r5,r6}
+	svc 0
+	ldmfd sp!,{r4,r5,r6,r7,lr}
+	bx lr
Index: EcnlProtoTool/trunk/musl-1.1.18/src/network/lookup_name.c
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/src/network/lookup_name.c	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/src/network/lookup_name.c	(revision 331)
@@ -0,0 +1,399 @@
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <errno.h>
+#include "lookup.h"
+#include "stdio_impl.h"
+#include "syscall.h"
+
+static int is_valid_hostname(const char *host)
+{
+	const unsigned char *s;
+	if (strnlen(host, 255)-1 >= 254 || mbstowcs(0, host, 0) == -1) return 0;
+	for (s=(void *)host; *s>=0x80 || *s=='.' || *s=='-' || isalnum(*s); s++);
+	return !*s;
+}
+
+static int name_from_null(struct address buf[static 2], const char *name, int family, int flags)
+{
+	int cnt = 0;
+	if (name) return 0;
+	if (flags & AI_PASSIVE) {
+		if (family != AF_INET6)
+			buf[cnt++] = (struct address){ .family = AF_INET };
+		/*if (family != AF_INET)
+			buf[cnt++] = (struct address){ .family = AF_INET6 };*/
+	} else {
+		if (family != AF_INET6)
+			buf[cnt++] = (struct address){ .family = AF_INET, .addr = { 127,0,0,1 } };
+		/*if (family != AF_INET)
+			buf[cnt++] = (struct address){ .family = AF_INET6, .addr = { [15] = 1 } };*/
+	}
+	return cnt;
+}
+
+static int name_from_numeric(struct address buf[static 1], const char *name, int family)
+{
+	return __lookup_ipliteral(buf, name, family);
+}
+
+static int name_from_hosts(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family)
+{
+	char line[512];
+	size_t l = strlen(name);
+	int cnt = 0, badfam = 0;
+	unsigned char _buf[1032];
+	FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
+	if (!f) switch (errno) {
+	case ENOENT:
+	case ENOTDIR:
+	case EACCES:
+		return 0;
+	default:
+		return EAI_SYSTEM;
+	}
+	while (fgets(line, sizeof line, f) && cnt < MAXADDRS) {
+		char *p, *z;
+
+		if ((p=strchr(line, '#'))) *p++='\n', *p=0;
+		for(p=line+1; (p=strstr(p, name)) &&
+			(!isspace(p[-1]) || !isspace(p[l])); p++);
+		if (!p) continue;
+
+		/* Isolate IP address to parse */
+		for (p=line; *p && !isspace(*p); p++);
+		*p++ = 0;
+		switch (name_from_numeric(buf+cnt, line, family)) {
+		case 1:
+			cnt++;
+			break;
+		case 0:
+			continue;
+		default:
+			badfam = EAI_NONAME;
+			continue;
+		}
+
+		/* Extract first name as canonical name */
+		for (; *p && isspace(*p); p++);
+		for (z=p; *z && !isspace(*z); z++);
+		*z = 0;
+		if (is_valid_hostname(p)) memcpy(canon, p, z-p+1);
+	}
+	__fclose_ca(f);
+	return cnt ? cnt : badfam;
+}
+
+struct dpc_ctx {
+	struct address *addrs;
+	char *canon;
+	int cnt;
+};
+
+int __dns_parse(const unsigned char *, int, int (*)(void *, int, const void *, int, const void *), void *);
+int __dn_expand(const unsigned char *, const unsigned char *, const unsigned char *, char *, int);
+int __res_mkquery(int, const char *, int, int, const unsigned char *, int, const unsigned char*, unsigned char *, int);
+int __res_msend_rc(int, const unsigned char *const *, const int *, unsigned char *const *, int *, int, const struct resolvconf *);
+
+#define RR_A 1
+#define RR_CNAME 5
+#define RR_AAAA 28
+
+static int dns_parse_callback(void *c, int rr, const void *data, int len, const void *packet)
+{
+	char tmp[256];
+	struct dpc_ctx *ctx = c;
+	if (ctx->cnt >= MAXADDRS) return -1;
+	switch (rr) {
+	case RR_A:
+		if (len != 4) return -1;
+		ctx->addrs[ctx->cnt].family = AF_INET;
+		ctx->addrs[ctx->cnt].scopeid = 0;
+		memcpy(ctx->addrs[ctx->cnt++].addr, data, 4);
+		break;
+	case RR_AAAA:
+		if (len != 16) return -1;
+		ctx->addrs[ctx->cnt].family = AF_INET6;
+		ctx->addrs[ctx->cnt].scopeid = 0;
+		memcpy(ctx->addrs[ctx->cnt++].addr, data, 16);
+		break;
+	case RR_CNAME:
+		if (__dn_expand(packet, (const unsigned char *)packet + 512,
+		    data, tmp, sizeof tmp) > 0 && is_valid_hostname(tmp))
+			strcpy(ctx->canon, tmp);
+		break;
+	}
+	return 0;
+}
+
+static int name_from_dns(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, const struct resolvconf *conf)
+{
+	unsigned char qbuf[2][280], abuf[2][512];
+	const unsigned char *qp[2] = { qbuf[0], qbuf[1] };
+	unsigned char *ap[2] = { abuf[0], abuf[1] };
+	int qlens[2], alens[2];
+	int i, nq = 0;
+	struct dpc_ctx ctx = { .addrs = buf, .canon = canon };
+	static const struct { int af; int rr; } afrr[2] = {
+		{ .af = AF_INET6, .rr = RR_A },
+		{ .af = AF_INET, .rr = RR_AAAA },
+	};
+
+	for (i=0; i<2; i++) {
+		if (family != afrr[i].af) {
+			qlens[nq] = __res_mkquery(0, name, 1, afrr[i].rr,
+				0, 0, 0, qbuf[nq], sizeof *qbuf);
+			if (qlens[nq] == -1)
+				return EAI_NONAME;
+			nq++;
+		}
+	}
+
+	if (__res_msend_rc(nq, qp, qlens, ap, alens, sizeof *abuf, conf) < 0)
+		return EAI_SYSTEM;
+
+	for (i=0; i<nq; i++)
+		__dns_parse(abuf[i], alens[i], dns_parse_callback, &ctx);
+
+	if (ctx.cnt) return ctx.cnt;
+	if (alens[0] < 4 || (abuf[0][3] & 15) == 2) return EAI_AGAIN;
+	if ((abuf[0][3] & 15) == 0) return EAI_NONAME;
+	if ((abuf[0][3] & 15) == 3) return 0;
+	return EAI_FAIL;
+}
+
+static int name_from_dns_search(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family)
+{
+	char search[256];
+	struct resolvconf conf;
+	size_t l, dots;
+	char *p, *z;
+
+	if (__get_resolv_conf(&conf, search, sizeof search) < 0) return -1;
+
+	/* Count dots, suppress search when >=ndots or name ends in
+	 * a dot, which is an explicit request for global scope. */
+	for (dots=l=0; name[l]; l++) if (name[l]=='.') dots++;
+	if (dots >= conf.ndots || name[l-1]=='.') *search = 0;
+
+	/* This can never happen; the caller already checked length. */
+	if (l >= 256) return EAI_NONAME;
+
+	/* Name with search domain appended is setup in canon[]. This both
+	 * provides the desired default canonical name (if the requested
+	 * name is not a CNAME record) and serves as a buffer for passing
+	 * the full requested name to name_from_dns. */
+	memcpy(canon, name, l);
+	canon[l] = '.';
+
+	for (p=search; *p; p=z) {
+		for (; isspace(*p); p++);
+		for (z=p; *z && !isspace(*z); z++);
+		if (z==p) break;
+		if (z-p < 256 - l - 1) {
+			memcpy(canon+l+1, p, z-p);
+			canon[z-p+1+l] = 0;
+			int cnt = name_from_dns(buf, canon, canon, family, &conf);
+			if (cnt) return cnt;
+		}
+	}
+
+	canon[l] = 0;
+	return name_from_dns(buf, canon, name, family, &conf);
+}
+
+static const struct policy {
+	unsigned char addr[16];
+	unsigned char len, mask;
+	unsigned char prec, label;
+} defpolicy[] = {
+	{ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1", 15, 0xff, 50, 0 },
+	{ "\0\0\0\0\0\0\0\0\0\0\xff\xff", 11, 0xff, 35, 4 },
+	{ "\x20\2", 1, 0xff, 30, 2 },
+	{ "\x20\1", 3, 0xff, 5, 5 },
+	{ "\xfc", 0, 0xfe, 3, 13 },
+#if 0
+	/* These are deprecated and/or returned to the address
+	 * pool, so despite the RFC, treating them as special
+	 * is probably wrong. */
+	{ "", 11, 0xff, 1, 3 },
+	{ "\xfe\xc0", 1, 0xc0, 1, 11 },
+	{ "\x3f\xfe", 1, 0xff, 1, 12 },
+#endif
+	/* Last rule must match all addresses to stop loop. */
+	{ "", 0, 0, 40, 1 },
+};
+
+static const struct policy *policyof(const struct in6_addr *a)
+{
+	int i;
+	for (i=0; ; i++) {
+		if (memcmp(a->s6_addr, defpolicy[i].addr, defpolicy[i].len))
+			continue;
+		if ((a->s6_addr[defpolicy[i].len] & defpolicy[i].mask)
+		    != defpolicy[i].addr[defpolicy[i].len])
+			continue;
+		return defpolicy+i;
+	}
+}
+
+static int labelof(const struct in6_addr *a)
+{
+	return policyof(a)->label;
+}
+
+static int scopeof(const struct in6_addr *a)
+{
+	if (IN6_IS_ADDR_MULTICAST(a)) return a->s6_addr[1] & 15;
+	if (IN6_IS_ADDR_LINKLOCAL(a)) return 2;
+	if (IN6_IS_ADDR_LOOPBACK(a)) return 2;
+	if (IN6_IS_ADDR_SITELOCAL(a)) return 5;
+	return 14;
+}
+
+static int prefixmatch(const struct in6_addr *s, const struct in6_addr *d)
+{
+	/* FIXME: The common prefix length should be limited to no greater
+	 * than the nominal length of the prefix portion of the source
+	 * address. However the definition of the source prefix length is
+	 * not clear and thus this limiting is not yet implemented. */
+	unsigned i;
+	for (i=0; i<128 && !((s->s6_addr[i/8]^d->s6_addr[i/8])&(128>>(i%8))); i++);
+	return i;
+}
+
+#define DAS_USABLE              0x40000000
+#define DAS_MATCHINGSCOPE       0x20000000
+#define DAS_MATCHINGLABEL       0x10000000
+#define DAS_PREC_SHIFT          20
+#define DAS_SCOPE_SHIFT         16
+#define DAS_PREFIX_SHIFT        8
+#define DAS_ORDER_SHIFT         0
+
+static int addrcmp(const void *_a, const void *_b)
+{
+	const struct address *a = _a, *b = _b;
+	return b->sortkey - a->sortkey;
+}
+
+int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, int flags)
+{
+	int cnt = 0, i, j;
+
+	*canon = 0;
+	if (name) {
+		/* reject empty name and check len so it fits into temp bufs */
+		size_t l = strnlen(name, 255);
+		if (l-1 >= 254)
+			return EAI_NONAME;
+		memcpy(canon, name, l+1);
+	}
+
+	/* Procedurally, a request for v6 addresses with the v4-mapped
+	 * flag set is like a request for unspecified family, followed
+	 * by filtering of the results. */
+	if (flags & AI_V4MAPPED) {
+		if (family == AF_INET6) family = AF_UNSPEC;
+		else flags -= AI_V4MAPPED;
+	}
+
+	/* Try each backend until there's at least one result. */
+	cnt = name_from_null(buf, name, family, flags);
+	if (!cnt) cnt = name_from_numeric(buf, name, family);
+	if (!cnt && !(flags & AI_NUMERICHOST)) {
+		cnt = name_from_hosts(buf, canon, name, family);
+		if (!cnt) cnt = name_from_dns_search(buf, canon, name, family);
+	}
+	if (cnt<=0) return cnt ? cnt : EAI_NONAME;
+
+	/* Filter/transform results for v4-mapped lookup, if requested. */
+	if (flags & AI_V4MAPPED) {
+		if (!(flags & AI_ALL)) {
+			/* If any v6 results exist, remove v4 results. */
+			for (i=0; i<cnt && buf[i].family != AF_INET6; i++);
+			if (i<cnt) {
+				for (j=0; i<cnt; i++) {
+					if (buf[i].family == AF_INET6)
+						buf[j++] = buf[i];
+				}
+				cnt = i = j;
+			}
+		}
+		/* Translate any remaining v4 results to v6 */
+		for (i=0; i<cnt; i++) {
+			if (buf[i].family != AF_INET) continue;
+			memcpy(buf[i].addr+12, buf[i].addr, 4);
+			memcpy(buf[i].addr, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
+			buf[i].family = AF_INET6;
+		}
+	}
+
+	/* No further processing is needed if there are fewer than 2
+	 * results or if there are only IPv4 results. */
+	if (cnt<2 || family==AF_INET) return cnt;
+	for (i=0; i<cnt; i++) if (buf[i].family != AF_INET) break;
+	if (i==cnt) return cnt;
+
+	int cs;
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
+
+	/* The following implements a subset of RFC 3484/6724 destination
+	 * address selection by generating a single 31-bit sort key for
+	 * each address. Rules 3, 4, and 7 are omitted for having
+	 * excessive runtime and code size cost and dubious benefit.
+	 * So far the label/precedence table cannot be customized. */
+	for (i=0; i<cnt; i++) {
+		int key = 0;
+		struct sockaddr_in6 sa, da = {
+			.sin6_family = AF_INET6,
+			.sin6_scope_id = buf[i].scopeid,
+			.sin6_port = 65535
+		};
+		if (buf[i].family == AF_INET6) {
+			memcpy(da.sin6_addr.s6_addr, buf[i].addr, 16);
+		} else {
+			memcpy(da.sin6_addr.s6_addr,
+				"\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
+			memcpy(da.sin6_addr.s6_addr+12, buf[i].addr, 4);
+		}
+		const struct policy *dpolicy = policyof(&da.sin6_addr);
+		int dscope = scopeof(&da.sin6_addr);
+		int dlabel = dpolicy->label;
+		int dprec = dpolicy->prec;
+		int prefixlen = 0;
+		int fd = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_UDP);
+		if (fd >= 0) {
+			if (!connect(fd, (void *)&da, sizeof da)) {
+				key |= DAS_USABLE;
+				if (!getsockname(fd, (void *)&sa,
+				    &(socklen_t){sizeof sa})) {
+					if (dscope == scopeof(&sa.sin6_addr))
+						key |= DAS_MATCHINGSCOPE;
+					if (dlabel == labelof(&sa.sin6_addr))
+						key |= DAS_MATCHINGLABEL;
+					prefixlen = prefixmatch(&sa.sin6_addr,
+						&da.sin6_addr);
+				}
+			}
+			close(fd);
+		}
+		key |= dprec << DAS_PREC_SHIFT;
+		key |= (15-dscope) << DAS_SCOPE_SHIFT;
+		key |= prefixlen << DAS_PREFIX_SHIFT;
+		key |= (MAXADDRS-i) << DAS_ORDER_SHIFT;
+		buf[i].sortkey = key;
+	}
+	qsort(buf, cnt, sizeof *buf, addrcmp);
+
+	pthread_setcancelstate(cs, 0);
+
+	return cnt;
+}
Index: EcnlProtoTool/trunk/musl-1.1.18/src/thread/arm/clone.s
===================================================================
--- EcnlProtoTool/trunk/musl-1.1.18/src/thread/arm/clone.s	(revision 331)
+++ EcnlProtoTool/trunk/musl-1.1.18/src/thread/arm/clone.s	(revision 331)
@@ -0,0 +1,31 @@
+.syntax unified
+.text
+.global __clone
+.type   __clone,%function
+__clone:
+	stmfd sp!,{r4,r5,r6,r7,lr}
+	mov r7,#120
+	mov r6,r3
+	mov r5,r0
+	mov r0,r2
+	and r1,r1,#-16
+	ldr r2,[sp,#16]
+	ldr r3,[sp,#20]
+	ldr r4,[sp,#24]
+	svc 0
+	tst r0,r0
+	beq 1f
+	ldmfd sp!,{r4,r5,r6,r7,lr}
+	bx lr
+
+1:	mov r0,r6
+	tst r5,#1
+	bne 1f
+	mov lr,pc
+	mov pc,r5
+2:	mov r7,#1
+	svc 0
+
+1:	mov lr,pc
+	bx r5
+	b 2b
Index: EcnlProtoTool/trunk/ntshell/.cproject
===================================================================
--- EcnlProtoTool/trunk/ntshell/.cproject	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/.cproject	(revision 331)
@@ -85,5 +85,5 @@
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre/mbed/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre/mbed/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/TARGET_MBED_MBRZA1H}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mruby-1.2.0/include}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mruby-1.3.0/include}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ntshell/src}&quot;"/>
Index: EcnlProtoTool/trunk/ntshell/.info
===================================================================
--- EcnlProtoTool/trunk/ntshell/.info	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/.info	(revision 331)
@@ -4,4 +4,4 @@
 GCC_STRING=5.2-GNUARM-NONE_v16.01
 VERSION_IDE=
-E2STUDIO_VERSION=5.3.1.002
+E2STUDIO_VERSION=5.4.0.018
 ACTIVE_CONFIGURATION=Debug
Index: EcnlProtoTool/trunk/ntshell/Debug/Makefile
===================================================================
--- EcnlProtoTool/trunk/ntshell/Debug/Makefile	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/Debug/Makefile	(revision 331)
@@ -203,7 +203,7 @@
 ifdef USE_CXX
 	APPL_CXXOBJS := main.o
-	APPL_COBJS := fdtable.o io_stub.o socket_stub.o ffarch.o time.o tlsf.o diskio.o ff.o sdfs.o ccsbcs.o base64.o http-strings.o http_parser.o httpd.o httpd-fs.o sha1.o websocket.o websocket_fbs.o ntshell.o text_editor.o text_history.o usrcmd.o vtrecv.o vtsend.o ntstdio.o ntopt.o shellif.o
-else
-	APPL_COBJS := main.o fdtable.o io_stub.o socket_stub.o ffarch.o time.o tlsf.o diskio.o ff.o sdfs.o ccsbcs.o base64.o http-strings.o http_parser.o httpd.o httpd-fs.o sha1.o websocket.o websocket_fbs.o ntshell.o text_editor.o text_history.o usrcmd.o vtrecv.o vtsend.o ntstdio.o ntopt.o shellif.o
+	APPL_COBJS := fdtable.o io_stub.o socket_stub.o ffarch.o fftime.o tlsf.o diskio.o ff.o sdfs.o ccsbcs.o base64.o http-strings.o http_parser.o httpd.o httpd-fs.o sha1.o websocket.o websocket_fbs.o ntshell.o text_editor.o text_history.o usrcmd.o vtrecv.o vtsend.o ntlibc.o ntstdio.o ntopt.o syscall.o mbedcall.o
+else
+	APPL_COBJS := main.o fdtable.o io_stub.o socket_stub.o ffarch.o fftime.o tlsf.o diskio.o ff.o sdfs.o ccsbcs.o base64.o http-strings.o http_parser.o httpd.o httpd-fs.o sha1.o websocket.o websocket_fbs.o ntshell.o text_editor.o text_history.o usrcmd.o vtrecv.o vtsend.o ntlibc.o ntstdio.o ntopt.o syscall.o mbedcall.o
 endif
 APPL_COBJS := $(APPL_COBJS) log_output.o vasyslog.o t_perror.o strerror.o
@@ -214,36 +214,36 @@
 endif
 
-#
-#  ãããã¯ã¼ã¯ãµã¼ãã¹ã®å®ç¾©
-#
-
-NO_USE_TINET_LIBRARY = true
-
-#  ãããã¯ã¼ã¯ã¤ã³ã¿ãã§ã¼ã¹ã®é¸æãä½ããä¸ã¤é¸æããã
-
-NET_IF = ether
-
-#  ã¤ã¼ãµãããã»ãã£ãã¤ã¹ãã©ã¤ãã®é¸æ
-
-NET_DEV = if_mbed
-
-#  ãããã¯ã¼ã¯å±¤ã®é¸æ
-
-#SUPPORT_INET6 = true
-SUPPORT_INET4 = true
-
-#  API ã«çµè¾¼ãæ©è½ã®é¸æ
-
-#API_CFG_IP4MAPPED_ADDR = true
-
-#  ãã©ã³ã¹ãã¼ãå±¤ã®é¸æ
-
-SUPPORT_TCP = true
-SUPPORT_UDP = true
-
-#
-#  ã·ã¹ãã ãµã¼ãã¹ã® Makefile ã®ã¤ã³ã¯ã«ã¼ã
-#
-include $(SRCDIR)/tinet/Makefile.tinet
+TINETDIR = tinet
+ifdef TINETDIR
+	#
+	#  ãããã¯ã¼ã¯ãµã¼ãã¹ã®å®ç¾©
+	#
+	NO_USE_TINET_LIBRARY = true
+
+	#  ãããã¯ã¼ã¯ã¤ã³ã¿ãã§ã¼ã¹ã®é¸æãä½ããä¸ã¤é¸æããã
+	NET_IF = ether
+
+	#  ã¤ã¼ãµãããã»ãã£ãã¤ã¹ãã©ã¤ãã®é¸æ
+	NET_DEV = if_mbed
+
+	#  ãããã¯ã¼ã¯å±¤ã®é¸æ
+	#SUPPORT_INET6 = true
+	SUPPORT_INET4 = true
+
+	#  API ã«çµè¾¼ãæ©è½ã®é¸æ
+	#API_CFG_IP4MAPPED_ADDR = true
+
+	#  ãã©ã³ã¹ãã¼ãå±¤ã®é¸æ
+	SUPPORT_TCP = true
+	SUPPORT_UDP = true
+
+	# IGMPãæå¹ã«è¨­å®
+	SUPPORT_IGMP = true
+
+	#
+	#  ãããã¯ã¼ã¯ãµã¼ãã¹ã® Makefile ã®ã¤ã³ã¯ã«ã¼ã
+	#
+	include $(SRCDIR)/$(TINETDIR)/Makefile.tinet
+endif
 
 #
@@ -272,5 +272,4 @@
 #all: check $(OBJNAME).srec
 endif
-	ruby ../shellif.rb
 	$(OBJCOPY) -B arm -I binary -O elf32-littlearm --rename-section .data=.boot $(OBJNAME).bin $(OBJNAME)_bin.o
 
@@ -280,8 +279,15 @@
 #  ã³ã³ãã£ã®ã¥ã¬ã¼ã¿ã«é¢ããå®ç¾©
 #
-CFG_TABS := --api-table $(SRCDIR)/tinet/tcpip_api.def:tcpip \
+ifndef TINETDIR
+  CFG_TRB := -T $(TARGETDIR)/target_kernel.trb
+  CFG_TABS := --api-table $(SRCDIR)/kernel/kernel_api.def \
+			--symval-table $(SRCDIR)/kernel/kernel_sym.def $(CFG_TABS)
+else
+  CFG_TRB := -T $(TINET_ROOT)/tinet.trb:tcpip -T $(TARGETDIR)/target_kernel.trb:kernel
+  CFG_TABS := --api-table $(TINET_ROOT)/tcpip_api.def:tcpip \
 			--api-table $(SRCDIR)/kernel/kernel_api.def:kernel \
 			--symval-table $(SRCDIR)/tinet/tcpip_sym.def \
 			--symval-table $(SRCDIR)/kernel/kernel_sym.def $(CFG_TABS)
+endif
 CFG_ASMOBJS := $(CFG_ASMOBJS)
 CFG_COBJS := kernel_cfg.o $(CFG_COBJS)
@@ -353,5 +359,5 @@
 #
 KERNEL_LIB_OBJS = $(KERNEL_ASMOBJS) $(KERNEL_COBJS) $(KERNEL_LCOBJS)
-SYSSVC_OBJS = $(SYSSVC_ASMOBJS) $(SYSSVC_COBJS)
+SYSSVC_OBJS = $(SYSSVC_ASMOBJS) $(SYSSVC_COBJS) $(HIDDEN_OBJS)
 APPL_OBJS = $(APPL_ASMOBJS) $(APPL_COBJS) $(APPL_CXXOBJS) $(APPL_BINOBJS)
 ALL_OBJS = $(START_OBJS) $(APPL_OBJS) $(SYSSVC_OBJS) $(CFG_OBJS) \
@@ -395,4 +401,5 @@
 cfg1_out.c cfg1_out.db: cfg1_out.timestamp ;
 cfg1_out.timestamp: $(APPL_CFG) $(TECSGEN_TIMESTAMP)
+	echo $(CFG_TABS)
 	$(CFG) --pass 1 --kernel asp $(INCLUDES) $(CFG_TABS) \
 						-M $(DEPDIR)/cfg1_out_c.d $(TARGET_KERNEL_CFG) $<
@@ -410,5 +417,5 @@
 $(CFG2_OUT_SRCS) cfg2_out.db: kernel_cfg.timestamp ;
 kernel_cfg.timestamp: cfg1_out.db cfg1_out.syms cfg1_out.srec
-	$(CFG) --pass 2 --kernel asp $(INCLUDES) -T $(TARGET_TCPIP_TRB):tcpip -T $(TARGET_KERNEL_TRB):kernel
+	$(CFG) --pass 2 --kernel asp $(INCLUDES) $(CFG_TRB)
 
 #
@@ -483,5 +490,5 @@
 	rm -f cfg1_out.syms cfg1_out.srec $(CFG1_OUT)
 	rm -f cfg1_out.timestamp cfg1_out.c cfg1_out.db
-	rm -f $(TECSGENDIR)/*
+	rm -rf $(TECSGENDIR)
 ifndef KERNEL_LIB
 	rm -f libkernel.a
Index: EcnlProtoTool/trunk/ntshell/fatfs/ff.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/fatfs/ff.c	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/fatfs/ff.c	(revision 331)
@@ -19,5 +19,6 @@
 #include "ff.h"			/* Declarations of FatFs API */
 #include "diskio.h"		/* Declarations of disk I/O functions */
-
+#include "util/ntstdio.h"
+#include "shellif.h"
 
 /*--------------------------------------------------------------------------
@@ -3909,5 +3910,5 @@
 					if (dir[DIR_Attr] & AM_DIR) {	/* The new object is a directory */
 						temp_new_path = (TCHAR *)ff_memalloc((_MAX_LFN + 1) * sizeof(WCHAR));
-						snprintf(temp_new_path, _MAX_LFN, "%s/%s", path_new, basename((char *)path_old));
+						ntstdio_snprintf(temp_new_path, _MAX_LFN, "%s/%s", path_new, basename((char *)path_old));
 						res = follow_path(&djn, temp_new_path);
 					}
Index: EcnlProtoTool/trunk/ntshell/fatfs/ff.h
===================================================================
--- EcnlProtoTool/trunk/ntshell/fatfs/ff.h	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/fatfs/ff.h	(revision 331)
@@ -162,5 +162,4 @@
 	const TCHAR*	pat;	/* Pointer to the name matching pattern */
 #endif
-	struct dirent *dirent;
 } DIR;
 
Index: EcnlProtoTool/trunk/ntshell/fatfs/ffarch.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/fatfs/ffarch.c	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/fatfs/ffarch.c	(revision 331)
@@ -39,4 +39,5 @@
  */
 
+#include "shellif.h"
 #include <kernel.h>
 #include <stdlib.h>
@@ -50,5 +51,5 @@
 #include "ff.h"
 #include "tlsf.h"
-#include "ntstdio.h"
+#include "util/ntstdio.h"
 
 #define SIO_PORTID 1
@@ -58,6 +59,5 @@
 static pool_t sys_pool;
 
-uint32_t  __HeapBase;
-uint32_t  __HeapLimit;
+uint8_t shell_heap[64 * 1024];
 FATFS RomDisk;
 
@@ -118,9 +118,9 @@
 void sys_init(void)
 {
-	sys_tlsf = tlsf_create(&__HeapBase);
+	sys_tlsf = tlsf_create(&shell_heap);
 	if (sys_tlsf == NULL)
 		return;
 
-	sys_pool = tlsf_add_pool(sys_tlsf, ((uint8_t *)&__HeapBase) + tlsf_size(), ((size_t)&__HeapLimit - (size_t)&__HeapBase) - tlsf_size());
+	sys_pool = tlsf_add_pool(sys_tlsf, ((uint8_t *)&shell_heap) + tlsf_size(), sizeof(shell_heap) - tlsf_size());
 }
 
Index: EcnlProtoTool/trunk/ntshell/fatfs/fftime.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/fatfs/fftime.c	(revision 331)
+++ EcnlProtoTool/trunk/ntshell/fatfs/fftime.c	(revision 331)
@@ -0,0 +1,271 @@
+/* musl-1.1.12/src/time/*.c */
+/* musl as a whole is licensed under the following standard MIT license:
+*
+* ----------------------------------------------------------------------
+* Copyright (C) 2005-2014 Rich Felker, et al.
+*
+* Permission is hereby granted, free of charge, to any person obtaining
+* a copy of this software and associated documentation files (the
+* "Software"), to deal in the Software without restriction, including
+* without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to
+* permit persons to whom the Software is furnished to do so, subject to
+* the following conditions:
+*
+* The above copyright notice and this permission notice shall be
+* included in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+* ----------------------------------------------------------------------*/
+#include <string.h>
+#include <limits.h>
+#include <time.h>
+#include <errno.h>
+#include "ff.h"
+
+int shell_errno;
+
+/* 2000-03-01 (mod 400 year, immediately after feb29 */
+#define LEAPOCH (946684800LL + 86400*(31+29))
+
+#define DAYS_PER_400Y (365*400 + 97)
+#define DAYS_PER_100Y (365*100 + 24)
+#define DAYS_PER_4Y   (365*4   + 1)
+
+int __secs_to_tm(long long t, struct tm* tm)
+{
+	long long days, secs, years;
+	int remdays, remsecs, remyears;
+	int qc_cycles, c_cycles, q_cycles;
+	int months;
+	int wday, yday, leap;
+	static const char days_in_month[] = {31,30,31,30,31,31,30,31,30,31,31,29};
+
+	/* Reject time_t values whose year would overflow int */
+	if (t < INT_MIN * 31622400LL || t > INT_MAX * 31622400LL)
+		return -1;
+
+	secs = t - LEAPOCH;
+	days = secs / 86400;
+	remsecs = secs % 86400;
+	if (remsecs < 0) {
+		remsecs += 86400;
+		days--;
+	}
+
+	wday = (3 + days) % 7;
+	if (wday < 0) wday += 7;
+
+	qc_cycles = days / DAYS_PER_400Y;
+	remdays = days % DAYS_PER_400Y;
+	if (remdays < 0) {
+		remdays += DAYS_PER_400Y;
+		qc_cycles--;
+	}
+
+	c_cycles = remdays / DAYS_PER_100Y;
+	if (c_cycles == 4) c_cycles--;
+	remdays -= c_cycles * DAYS_PER_100Y;
+
+	q_cycles = remdays / DAYS_PER_4Y;
+	if (q_cycles == 25) q_cycles--;
+	remdays -= q_cycles * DAYS_PER_4Y;
+
+	remyears = remdays / 365;
+	if (remyears == 4) remyears--;
+	remdays -= remyears * 365;
+
+	leap = !remyears && (q_cycles || !c_cycles);
+	yday = remdays + 31 + 28 + leap;
+	if (yday >= 365 + leap) yday -= 365 + leap;
+
+	years = remyears + 4 * q_cycles + 100 * c_cycles + 400LL * qc_cycles;
+
+	for (months = 0; days_in_month[months] <= remdays; months++)
+		remdays -= days_in_month[months];
+
+	if (years + 100 > INT_MAX || years + 100 < INT_MIN)
+		return -1;
+
+	tm->tm_year = years + 100;
+	tm->tm_mon = months + 2;
+	if (tm->tm_mon >= 12) {
+		tm->tm_mon -= 12;
+		tm->tm_year++;
+	}
+	tm->tm_mday = remdays + 1;
+	tm->tm_wday = wday;
+	tm->tm_yday = yday;
+
+	tm->tm_hour = remsecs / 3600;
+	tm->tm_min = remsecs / 60 % 60;
+	tm->tm_sec = remsecs % 60;
+
+	return 0;
+}
+
+long long __year_to_secs(long long year, int *is_leap)
+{
+	if (year - 2ULL <= 136) {
+		int y = year;
+		int leaps = (y - 68) >> 2;
+		if (!((y - 68) & 3)) {
+			leaps--;
+			if (is_leap) *is_leap = 1;
+		}
+		else if (is_leap) *is_leap = 0;
+		return 31536000 * (y - 70) + 86400 * leaps;
+	}
+
+	int cycles, centuries, leaps, rem;
+
+	if (!is_leap) is_leap = &(int) { 0 };
+	cycles = (year - 100) / 400;
+	rem = (year - 100) % 400;
+	if (rem < 0) {
+		cycles--;
+		rem += 400;
+	}
+	if (!rem) {
+		*is_leap = 1;
+		centuries = 0;
+		leaps = 0;
+	}
+	else {
+		if (rem >= 200) {
+			if (rem >= 300) centuries = 3, rem -= 300;
+			else centuries = 2, rem -= 200;
+		}
+		else {
+			if (rem >= 100) centuries = 1, rem -= 100;
+			else centuries = 0;
+		}
+		if (!rem) {
+			*is_leap = 0;
+			leaps = 0;
+		}
+		else {
+			leaps = rem / 4U;
+			rem %= 4U;
+			*is_leap = !rem;
+		}
+	}
+
+	leaps += 97 * cycles + 24 * centuries - *is_leap;
+
+	return (year - 100) * 31536000LL + leaps * 86400LL + 946684800 + 86400;
+}
+
+int __month_to_secs(int month, int is_leap)
+{
+	static const int secs_through_month[] = {
+		0, 31 * 86400, 59 * 86400, 90 * 86400,
+		120 * 86400, 151 * 86400, 181 * 86400, 212 * 86400,
+		243 * 86400, 273 * 86400, 304 * 86400, 334 * 86400};
+	int t = secs_through_month[month];
+	if (is_leap && month >= 2) t += 86400;
+	return t;
+}
+
+long long __tm_to_secs(const struct tm *tm)
+{
+	int is_leap;
+	long long year = tm->tm_year;
+	int month = tm->tm_mon;
+	if (month >= 12 || month < 0) {
+		int adj = month / 12;
+		month %= 12;
+		if (month < 0) {
+			adj--;
+			month += 12;
+		}
+		year += adj;
+	}
+	long long t = __year_to_secs(year, &is_leap);
+	t += __month_to_secs(month, is_leap);
+	t += 86400LL * (tm->tm_mday - 1);
+	t += 3600LL * tm->tm_hour;
+	t += 60LL * tm->tm_min;
+	t += tm->tm_sec;
+	return t;
+}
+
+struct tm *localtime_r(const time_t *t, struct tm *tm)
+{
+	/* Reject time_t values whose year would overflow int because
+	* __secs_to_zone cannot safely handle them. */
+	if (*t < INT_MIN * 31622400LL || *t > INT_MAX * 31622400LL) {
+		shell_errno = EOVERFLOW;
+		return 0;
+	}
+	//TODO:__secs_to_zone(*t, 0, &tm->tm_isdst, &tm->__tm_gmtoff, 0, &tm->__tm_zone);
+	if (__secs_to_tm((long long)*t /*+ tm->__tm_gmtoff*/, tm) < 0) {
+		shell_errno = EOVERFLOW;
+		return 0;
+	}
+	return tm;
+}
+
+struct tm *localtime(const time_t *time)
+{
+	static struct tm tm;
+	return localtime_r(time, &tm);
+}
+
+struct tm *gmtime_r(const time_t *t, struct tm *tm)
+{
+	if (__secs_to_tm(*t, tm) < 0) {
+		shell_errno = EOVERFLOW;
+		return 0;
+	}
+	tm->tm_isdst = 0;
+	/*tm->__tm_gmtoff = 0;
+	tm->__tm_zone = NULL;//__gmt;*/
+	return tm;
+}
+
+/* There is no other implemented value than TIME_UTC; all other values
+ * are considered erroneous. */
+/*int timespec_get(struct timespec * ts, int base)
+{
+	if (base != TIME_UTC) return 0;
+	int ret = __clock_gettime(CLOCK_REALTIME, ts);
+	return ret < 0 ? 0 : base;
+}*/
+time_t mktime(struct tm *tm)
+{
+	struct tm new;
+	long opp;
+	long long t = __tm_to_secs(tm);
+
+	if (__secs_to_tm(t, &new) < 0) goto error;
+
+	*tm = new;
+	return t;
+
+error:
+	shell_errno = EOVERFLOW;
+	return -1;
+}
+
+DWORD get_fattime(void)
+{
+	time_t temp;
+	struct tm _tm;
+
+	temp = rtc_read();
+	gmtime_r(&temp, &_tm);
+
+	return	  ((DWORD)(_tm.tm_year - 1980) << 25)
+		| ((DWORD)_tm.tm_mon << 21)
+		| ((DWORD)_tm.tm_mday << 16)
+		| ((DWORD)_tm.tm_hour << 11)
+		| ((DWORD)_tm.tm_min << 5)
+		| ((DWORD)_tm.tm_sec >> 1);
+}
Index: EcnlProtoTool/trunk/ntshell/fatfs/sdfs.h
===================================================================
--- EcnlProtoTool/trunk/ntshell/fatfs/sdfs.h	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/fatfs/sdfs.h	(revision 331)
@@ -24,5 +24,7 @@
 
 #include <stdint.h>
-#include <time.h>
+//#include <time.h>
+#define __NEED_time_t
+#include "../musl-1.1.18/include/bits/alltypes.h"
 #include "gpio_api.h"
 #include "spi_api.h"
Index: EcnlProtoTool/trunk/ntshell/fatfs/time.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/fatfs/time.c	(revision 321)
+++ 	(revision )
@@ -1,269 +1,0 @@
-/* musl-1.1.12/src/time/*.c */
-/* musl as a whole is licensed under the following standard MIT license:
-*
-* ----------------------------------------------------------------------
-* Copyright (C) 2005-2014 Rich Felker, et al.
-*
-* Permission is hereby granted, free of charge, to any person obtaining
-* a copy of this software and associated documentation files (the
-* "Software"), to deal in the Software without restriction, including
-* without limitation the rights to use, copy, modify, merge, publish,
-* distribute, sublicense, and/or sell copies of the Software, and to
-* permit persons to whom the Software is furnished to do so, subject to
-* the following conditions:
-*
-* The above copyright notice and this permission notice shall be
-* included in all copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-* ----------------------------------------------------------------------*/
-#include <string.h>
-#include <limits.h>
-#include <time.h>
-#include <errno.h>
-#include "ff.h"
-
-/* 2000-03-01 (mod 400 year, immediately after feb29 */
-#define LEAPOCH (946684800LL + 86400*(31+29))
-
-#define DAYS_PER_400Y (365*400 + 97)
-#define DAYS_PER_100Y (365*100 + 24)
-#define DAYS_PER_4Y   (365*4   + 1)
-
-int __secs_to_tm(long long t, struct tm* tm)
-{
-	long long days, secs, years;
-	int remdays, remsecs, remyears;
-	int qc_cycles, c_cycles, q_cycles;
-	int months;
-	int wday, yday, leap;
-	static const char days_in_month[] = {31,30,31,30,31,31,30,31,30,31,31,29};
-
-	/* Reject time_t values whose year would overflow int */
-	if (t < INT_MIN * 31622400LL || t > INT_MAX * 31622400LL)
-		return -1;
-
-	secs = t - LEAPOCH;
-	days = secs / 86400;
-	remsecs = secs % 86400;
-	if (remsecs < 0) {
-		remsecs += 86400;
-		days--;
-	}
-
-	wday = (3 + days) % 7;
-	if (wday < 0) wday += 7;
-
-	qc_cycles = days / DAYS_PER_400Y;
-	remdays = days % DAYS_PER_400Y;
-	if (remdays < 0) {
-		remdays += DAYS_PER_400Y;
-		qc_cycles--;
-	}
-
-	c_cycles = remdays / DAYS_PER_100Y;
-	if (c_cycles == 4) c_cycles--;
-	remdays -= c_cycles * DAYS_PER_100Y;
-
-	q_cycles = remdays / DAYS_PER_4Y;
-	if (q_cycles == 25) q_cycles--;
-	remdays -= q_cycles * DAYS_PER_4Y;
-
-	remyears = remdays / 365;
-	if (remyears == 4) remyears--;
-	remdays -= remyears * 365;
-
-	leap = !remyears && (q_cycles || !c_cycles);
-	yday = remdays + 31 + 28 + leap;
-	if (yday >= 365 + leap) yday -= 365 + leap;
-
-	years = remyears + 4 * q_cycles + 100 * c_cycles + 400LL * qc_cycles;
-
-	for (months = 0; days_in_month[months] <= remdays; months++)
-		remdays -= days_in_month[months];
-
-	if (years + 100 > INT_MAX || years + 100 < INT_MIN)
-		return -1;
-
-	tm->tm_year = years + 100;
-	tm->tm_mon = months + 2;
-	if (tm->tm_mon >= 12) {
-		tm->tm_mon -= 12;
-		tm->tm_year++;
-	}
-	tm->tm_mday = remdays + 1;
-	tm->tm_wday = wday;
-	tm->tm_yday = yday;
-
-	tm->tm_hour = remsecs / 3600;
-	tm->tm_min = remsecs / 60 % 60;
-	tm->tm_sec = remsecs % 60;
-
-	return 0;
-}
-
-long long __year_to_secs(long long year, int *is_leap)
-{
-	if (year - 2ULL <= 136) {
-		int y = year;
-		int leaps = (y - 68) >> 2;
-		if (!((y - 68) & 3)) {
-			leaps--;
-			if (is_leap) *is_leap = 1;
-		}
-		else if (is_leap) *is_leap = 0;
-		return 31536000 * (y - 70) + 86400 * leaps;
-	}
-
-	int cycles, centuries, leaps, rem;
-
-	if (!is_leap) is_leap = &(int) { 0 };
-	cycles = (year - 100) / 400;
-	rem = (year - 100) % 400;
-	if (rem < 0) {
-		cycles--;
-		rem += 400;
-	}
-	if (!rem) {
-		*is_leap = 1;
-		centuries = 0;
-		leaps = 0;
-	}
-	else {
-		if (rem >= 200) {
-			if (rem >= 300) centuries = 3, rem -= 300;
-			else centuries = 2, rem -= 200;
-		}
-		else {
-			if (rem >= 100) centuries = 1, rem -= 100;
-			else centuries = 0;
-		}
-		if (!rem) {
-			*is_leap = 0;
-			leaps = 0;
-		}
-		else {
-			leaps = rem / 4U;
-			rem %= 4U;
-			*is_leap = !rem;
-		}
-	}
-
-	leaps += 97 * cycles + 24 * centuries - *is_leap;
-
-	return (year - 100) * 31536000LL + leaps * 86400LL + 946684800 + 86400;
-}
-
-int __month_to_secs(int month, int is_leap)
-{
-	static const int secs_through_month[] = {
-		0, 31 * 86400, 59 * 86400, 90 * 86400,
-		120 * 86400, 151 * 86400, 181 * 86400, 212 * 86400,
-		243 * 86400, 273 * 86400, 304 * 86400, 334 * 86400};
-	int t = secs_through_month[month];
-	if (is_leap && month >= 2) t += 86400;
-	return t;
-}
-
-long long __tm_to_secs(const struct tm *tm)
-{
-	int is_leap;
-	long long year = tm->tm_year;
-	int month = tm->tm_mon;
-	if (month >= 12 || month < 0) {
-		int adj = month / 12;
-		month %= 12;
-		if (month < 0) {
-			adj--;
-			month += 12;
-		}
-		year += adj;
-	}
-	long long t = __year_to_secs(year, &is_leap);
-	t += __month_to_secs(month, is_leap);
-	t += 86400LL * (tm->tm_mday - 1);
-	t += 3600LL * tm->tm_hour;
-	t += 60LL * tm->tm_min;
-	t += tm->tm_sec;
-	return t;
-}
-
-struct tm *localtime_r(const time_t *t, struct tm *tm)
-{
-	/* Reject time_t values whose year would overflow int because
-	* __secs_to_zone cannot safely handle them. */
-	if (*t < INT_MIN * 31622400LL || *t > INT_MAX * 31622400LL) {
-		errno = EOVERFLOW;
-		return 0;
-	}
-	//TODO:__secs_to_zone(*t, 0, &tm->tm_isdst, &tm->__tm_gmtoff, 0, &tm->__tm_zone);
-	if (__secs_to_tm((long long)*t /*+ tm->__tm_gmtoff*/, tm) < 0) {
-		errno = EOVERFLOW;
-		return 0;
-	}
-	return tm;
-}
-
-struct tm *localtime(const time_t *time)
-{
-	static struct tm tm;
-	return localtime_r(time, &tm);
-}
-
-struct tm *gmtime_r(const time_t *t, struct tm *tm)
-{
-	if (__secs_to_tm(*t, tm) < 0) {
-		errno = EOVERFLOW;
-		return 0;
-	}
-	tm->tm_isdst = 0;
-	/*tm->__tm_gmtoff = 0;
-	tm->__tm_zone = NULL;//__gmt;*/
-	return tm;
-}
-
-/* There is no other implemented value than TIME_UTC; all other values
- * are considered erroneous. */
-/*int timespec_get(struct timespec * ts, int base)
-{
-	if (base != TIME_UTC) return 0;
-	int ret = __clock_gettime(CLOCK_REALTIME, ts);
-	return ret < 0 ? 0 : base;
-}*/
-time_t mktime(struct tm *tm)
-{
-	struct tm new;
-	long opp;
-	long long t = __tm_to_secs(tm);
-
-	if (__secs_to_tm(t, &new) < 0) goto error;
-
-	*tm = new;
-	return t;
-
-error:
-	errno = EOVERFLOW;
-	return -1;
-}
-
-DWORD get_fattime(void)
-{
-	time_t temp;
-	struct tm _tm;
-
-	time(&temp);
-	gmtime_r(&temp, &_tm);
-
-	return	  ((DWORD)(_tm.tm_year - 1980) << 25)
-		| ((DWORD)_tm.tm_mon << 21)
-		| ((DWORD)_tm.tm_mday << 16)
-		| ((DWORD)_tm.tm_hour << 11)
-		| ((DWORD)_tm.tm_min << 5)
-		| ((DWORD)_tm.tm_sec >> 1);
-}
Index: EcnlProtoTool/trunk/ntshell/ntshell/core/ntlibc.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/ntshell/core/ntlibc.c	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/ntshell/core/ntlibc.c	(revision 331)
@@ -57,4 +57,17 @@
 }
 
+int ntlibc_strlcpy(char *des, const char *src, int n)
+{
+	char *d = des, *e = &des[n];
+	const char *s = src;
+	while (*s && d < e) {
+		*d = *s;
+		d++;
+		s++;
+	}
+	*d++ = '\0';
+	return (int)d - (int)des;
+}
+
 char *ntlibc_strcat(char *des, const char *src)
 {
@@ -71,4 +84,20 @@
 	*d = '\0';
 	return des;
+}
+
+int ntlibc_strlcat(char *des, const char *src, int n)
+{
+	char *d = des, *e = &des[n];
+	const char *s = src;
+	while (*d && d < e) {
+		d++;
+	}
+	while (*s && d < e) {
+		*d = *s;
+		d++;
+		s++;
+	}
+	*d++ = '\0';
+	return (int)d - (int)des;
 }
 
@@ -223,4 +252,49 @@
 }
 
+unsigned long ntlibc_strtoul(const char *restrict nptr, char **restrict endptr, int base)
+{
+	int cnt;
+	int num = 0;
+	int ofs = 0;
+	int sign = 0;
+	int scnt = 0;
+	char *p = (char *)nptr;
+	while (*p != '\0') {
+		if (!ntlibc_isdigit(*p)) {
+			if (*p == ' ') {
+				ofs++;
+			}
+			if (*p == '+') {
+				sign = 0;
+				ofs++;
+				if (scnt++ > 0) {
+					*endptr = p;
+					break;
+				}
+			}
+			if (*p == '-') {
+				sign = 1;
+				ofs++;
+				if (scnt++ > 0) {
+					*endptr = p;
+					break;
+				}
+			}
+			*endptr = p;
+			break;
+		}
+		p++;
+	}
+	for (cnt = ofs; (nptr[cnt] >= '0') && (nptr[cnt] <= '9'); cnt++) {
+		num = 10 * num + (nptr[cnt] - '0');
+	}
+	if (sign) {
+		return -num;
+	}
+	else {
+		return num;
+	}
+}
+
 char *ntlibc_strchr(const char *s, int c)
 {
Index: EcnlProtoTool/trunk/ntshell/ntshell/core/ntlibc.h
===================================================================
--- EcnlProtoTool/trunk/ntshell/ntshell/core/ntlibc.h	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/ntshell/core/ntlibc.h	(revision 331)
@@ -40,5 +40,7 @@
 int ntlibc_strlen(const char *s);
 char *ntlibc_strcpy(char *des, const char *src);
+int ntlibc_strlcpy(char *des, const char *src, int n);
 char *ntlibc_strcat(char *des, const char *src);
+int ntlibc_strlcat(char *des, const char *src, int n);
 int ntlibc_strcmp(const char *s1, const char *s2);
 int ntlibc_stricmp(const char *s1, const char *s2);
@@ -50,4 +52,5 @@
 int ntlibc_tolower(int c);
 int ntlibc_atoi(const char *nptr);
+unsigned long ntlibc_strtoul(const char *__restrict nptr, char **__restrict endptr, int base);
 char *ntlibc_strchr(const char *s, int c);
 char *ntlibc_utoa(unsigned int value, char *s, int radix);
Index: EcnlProtoTool/trunk/ntshell/ntshell/core/ntshell.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/ntshell/core/ntshell.c	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/ntshell/core/ntshell.c	(revision 331)
@@ -33,4 +33,5 @@
 #include <string.h>
 #include "ntshell.h"
+#include "core/ntlibc.h"
 
 int ntshell_exit;
@@ -107,5 +108,5 @@
  * @param HANDLE A pointer of the handle.
  */
-#define PROMPT_WRITE(HANDLE)            SERIAL_WRITE((HANDLE), (HANDLE)->prompt, strlen((HANDLE)->prompt))
+#define PROMPT_WRITE(HANDLE)            SERIAL_WRITE((HANDLE), (HANDLE)->prompt, ntlibc_strlen((HANDLE)->prompt))
 
 /**
@@ -114,5 +115,5 @@
  * @param HANDLE A pointer of the handle.
  */
-#define PROMPT_NEWLINE(HANDLE)          SERIAL_WRITE((HANDLE), NTSHELL_PROMPT_NEWLINE, strlen(NTSHELL_PROMPT_NEWLINE))
+#define PROMPT_NEWLINE(HANDLE)          SERIAL_WRITE((HANDLE), NTSHELL_PROMPT_NEWLINE, ntlibc_strlen(NTSHELL_PROMPT_NEWLINE))
 
 /**
@@ -399,5 +400,5 @@
 				 * Found the suggestion.
 				 */
-				int n = strlen((const char *)buf);
+				int n = ntlibc_strlen((const char *)buf);
 				VTSEND_ERASE_LINE(ntshell);
 				VTSEND_CURSOR_HEAD(ntshell);
@@ -429,5 +430,5 @@
 			 * Found the suggestion.
 			 */
-			int n = strlen((const char *)buf);
+			int n = ntlibc_strlen((const char *)buf);
 			VTSEND_ERASE_LINE(ntshell);
 			VTSEND_CURSOR_HEAD(ntshell);
@@ -441,5 +442,5 @@
 			 * Recall the previous input text string.
 			 */
-			int n = strlen(SUGGEST_SOURCE(ntshell));
+			int n = ntlibc_strlen(SUGGEST_SOURCE(ntshell));
 			VTSEND_ERASE_LINE(ntshell);
 			VTSEND_CURSOR_HEAD(ntshell);
@@ -484,5 +485,5 @@
 	UNUSED_VARIABLE(ch);
 	text_editor_get_text(GET_EDITOR(ntshell), buf, sizeof(buf));
-	len = strlen((const char *)buf);
+	len = ntlibc_strlen((const char *)buf);
 	VTSEND_CURSOR_HEAD(ntshell);
 	PROMPT_WRITE(ntshell);
@@ -606,5 +607,5 @@
 	p->func_callback = func_callback;
 	p->extobj = extobj;
-	strcpy(p->prompt, NTSHELL_PROMPT_DEFAULT);
+	ntlibc_strcpy(p->prompt, NTSHELL_PROMPT_DEFAULT);
 
 	p->vtrecv.user_data = p;
@@ -666,5 +667,5 @@
 	}
 
-	strcpy(p->prompt, prompt);
+	ntlibc_strcpy(p->prompt, prompt);
 }
 
Index: EcnlProtoTool/trunk/ntshell/ntshell/core/text_history.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/ntshell/core/text_history.c	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/ntshell/core/text_history.c	(revision 331)
@@ -33,4 +33,5 @@
 #include <string.h>
 #include "text_history.h"
+#include "core/ntlibc.h"
 
 /**
@@ -145,5 +146,5 @@
 	char *buf, const int siz)
 {
-	const int text_len = strlen((const char *)text);
+	const int text_len = ntlibc_strlen((const char *)text);
 	int found = 0;
 	int i;
@@ -151,14 +152,14 @@
 		int target = (p->rp + i) % TEXTHISTORY_DEPTH;
 		char *txtp = p->history + (TEXTHISTORY_MAXLEN * target);
-		const int target_len = strlen((const char *)txtp);
+		const int target_len = ntlibc_strlen((const char *)txtp);
 		int comp_len = (target_len < text_len) ? target_len : text_len;
-		if ((strncmp(
+		if ((ntlibc_strncmp(
 			(const char *)txtp,
 			(const char *)text, comp_len) == 0) && (comp_len > 0)) {
 			if (found == index) {
-				if (siz <= strlen(txtp)) {
+				if (siz <= ntlibc_strlen(txtp)) {
 					return -1;
 				}
-				strcpy((char *)buf, (char *)txtp);
+				ntlibc_strcpy((char *)buf, (char *)txtp);
 				return 0;
 			}
Index: EcnlProtoTool/trunk/ntshell/ntshell/usrcmd.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/ntshell/usrcmd.c	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/ntshell/usrcmd.c	(revision 331)
@@ -31,12 +31,10 @@
  */
 
+#include "shellif.h"
 #include <kernel.h>
+#include <string.h>
 #include <t_syslog.h>
 #include <t_stdlib.h>
 #include <sil.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <setjmp.h>
 #include "syssvc/syslog.h"
 #include "kernel_cfg.h"
@@ -46,9 +44,106 @@
 #include "ff.h"
 #include "usrcmd.h"
-#include "ntstdio.h"
-#include "ntshell.h"
+#include "core/ntshell.h"
+#include "core/ntlibc.h"
+#include "util/ntstdio.h"
 
 extern ntstdio_t ntstdio;
 extern int ntshell_exit;
+
+/* musl_getopt from msul */
+char *optarg;
+int /*optind=1, opterr=1, */optopt, optpos, optreset=0;
+extern int optind, opterr;
+
+static void ntstdio_write(ntstdio_t *handle, const char *str, int l)
+{
+	for (; *str && l >= 0; l--) {
+		ntstdio_putc(handle, *str++);
+	}
+}
+
+static void __getopt_msg(const char *a, const char *b, const char *c, size_t l)
+{
+	ntstdio_puts(&ntstdio, a);
+	ntstdio_write(&ntstdio, b, ntlibc_strlen(b));
+	ntstdio_write(&ntstdio, c, l);
+	ntstdio_putc(&ntstdio, '\n');
+}
+
+static int musl_getopt(int argc, char * const argv[], const char *optstring)
+{
+	int i;
+	wchar_t c, d;
+	int k, l;
+	char *optchar;
+
+	if (!optind || optreset) {
+		optreset = 0;
+		optpos = 0;
+		optind = 1;
+	}
+
+	if (optind >= argc || !argv[optind])
+		return -1;
+
+	if (argv[optind][0] != '-') {
+		if (optstring[0] == '-') {
+			optarg = argv[optind++];
+			return 1;
+		}
+		return -1;
+	}
+
+	if (!argv[optind][1])
+		return -1;
+
+	if (argv[optind][1] == '-' && !argv[optind][2])
+		return optind++, -1;
+
+	if (!optpos) optpos++;
+	if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) {
+		k = 1;
+		c = 0xfffd; /* replacement char */
+	}
+	optchar = argv[optind]+optpos;
+	optopt = c;
+	optpos += k;
+
+	if (!argv[optind][optpos]) {
+		optind++;
+		optpos = 0;
+	}
+
+	if (optstring[0] == '-' || optstring[0] == '+')
+		optstring++;
+
+	i = 0;
+	d = 0;
+	do {
+		l = mbtowc(&d, optstring+i, MB_LEN_MAX);
+		if (l>0) i+=l; else i++;
+	} while (l && d != c);
+
+	if (d != c) {
+		if (optstring[0] != ':' && opterr)
+			__getopt_msg(argv[0], ": unrecognized option: ", optchar, k);
+		return '?';
+	}
+	if (optstring[i] == ':') {
+		if (optstring[i+1] == ':') optarg = 0;
+		else if (optind >= argc) {
+			if (optstring[0] == ':') return ':';
+			if (opterr) __getopt_msg(argv[0],
+				": option requires an argument: ",
+				optchar, k);
+			return '?';
+		}
+		if (optstring[i+1] != ':' || optpos) {
+			optarg = argv[optind++] + optpos;
+			optpos = 0;
+		}
+	}
+	return c;
+}
 
 int shell_kill(int pid, int sig)
@@ -99,5 +194,5 @@
 	size_t i, j;
 	if (!s || !*s) return ".";
-	i = strlen(s) - 1;
+	i = ntlibc_strlen(s) - 1;
 	for (j = 0; j <= i; j++) if (s[j] == ':') { s = &s[j + 1]; i -= j; break; }
 	for (; i&&s[i] == '/'; i--) s[i] = 0;
@@ -111,5 +206,5 @@
 	size_t i, j;
 	if (!s || !*s) return ".";
-	i = strlen(s) - 1;
+	i = ntlibc_strlen(s) - 1;
 	for (j = 0; j <= i; j++) if (s[j] == ':') { s = &s[j + 1]; i -= j; break; }
 	for (; s[i] == '/'; i--) if (!i) return (s == _s) ? "/" : _s;
@@ -141,5 +236,5 @@
 	}
 
-	strlcat(path, "\n", sizeof(path));
+	ntlibc_strlcat(path, "\n", sizeof(path));
 	ntstdio_printf(&ntstdio, path);
 
@@ -287,29 +382,27 @@
 	char *pattern_p = NULL, *basename_p = NULL, *dirname_p = NULL;
 	char default_pattern[_MAX_LFN] = "";
-	int i;
+	int c;
 	BYTE list_option = 0;
 
-	for (i = 1; i < argc; i++) {
-		if (argv[i][0] == '-') {
-			if (argv[i][1] == 'a') {
-				list_option |= LS_ALL;
-			}
-			else if (argv[i][1] == 'l') {
-				list_option |= LS_LONG;
-			}
-			continue;
-		}
-		if (argv[i][0] != '\0') {	/* pattern matching ? */
-			pattern_p = &argv[i][0];
+	while ((c = musl_getopt(argc, argv, "al")) != -1) {
+		switch (c) {
+		case 'a':
+			list_option |= LS_ALL;
 			break;
-		}
-	}
+		case 'l':
+			list_option |= LS_LONG;
+			break;
+		default:
+			break;
+		}
+	}
+	pattern_p = *(argv + optind);
 
 	if (pattern_p != NULL)
-		strlcpy(default_pattern, pattern_p, sizeof(default_pattern));
+		ntlibc_strlcpy(default_pattern, pattern_p, sizeof(default_pattern));
 	basename_p = basename(pattern_p);
 	dirname_p = dirname(default_pattern);
 	if (((dirname_p[0] == '/') && (basename_p[0] == '/')) ||
-		(!strncmp(dirname_p, ".", strlen(dirname_p)) && !strncmp(basename_p, ".", strlen(basename_p))))
+		(!ntlibc_strncmp(dirname_p, ".", ntlibc_strlen(dirname_p)) && !ntlibc_strncmp(basename_p, ".", ntlibc_strlen(basename_p))))
 	{
 		basename_p = NULL;
@@ -499,22 +592,81 @@
 }
 
+extern WCHAR Utf8_to_Utf16(const char *, int *); /* in ff.c */
+extern void Utf16_to_Utf8(unsigned char *, int *, UINT); /* in ff.c */
+#define HEXDUMP_EXTRA_FOR_UTF8 3 /* need extra buffer size */
+#define CCOLOR_RESET	0
+#define CCOLOR_BLACK	30
+#define CCOLOR_RED		31
+#define CCOLOR_GREEN	32
+#define CCOLOR_YELLOW	33
+#define CCOLOR_BLUE		34
+#define CCOLOR_MAGENTA	35
+#define CCOLOR_CYAN		36
+#define CCOLOR_WHITE	37
+enum {
+	HEXDUMP_OPT_DEFAULT = 1 << 0,
+	HEXDUMP_OPT_UTF8 = 1 << 1,
+};
+
 int usrcmd_hexdump(int argc, char **argv)
 {
 	FRESULT res;
 	FIL fsrc;
-	unsigned char data[16 + 1];
-	unsigned char ascii[sizeof("\x1B[31m0\x1B[0m\x1B[31m1\x1B[0m\x1B[31m2\x1B[0m\x1B[31m3\x1B[0m\x1B[31m4\x1B[0m\x1B[31m5\x1B[0m\x1B[31m6\x1B[0m\x1B[31m7\x1B[0m\x1B[31m8\x1B[0m\x1B[31m9\x1B[0m\x1B[31ma\x1B[0m\x1B[31mb\x1B[0m\x1B[31mc\x1B[0m\x1B[31md\x1B[0m\x1B[31me\x1B[0m\x1B[31mf\x1B[0m")];
+	unsigned char data[16 + 1 + HEXDUMP_EXTRA_FOR_UTF8];
+	unsigned char ascii[sizeof("\x1B[31m0\x1B[0m\x1B[31m1\x1B[0m\x1B[31m2\x1B[0m\x1B[31m3\x1B[0m\x1B[31m4\x1B[0m\x1B[31m5\x1B[0m\x1B[31m6\x1B[0m\x1B[31m7\x1B[0m\x1B[31m8\x1B[0m\x1B[31m9\x1B[0m\x1B[31ma\x1B[0m\x1B[31mb\x1B[0m\x1B[31mc\x1B[0m\x1B[31md\x1B[0m\x1B[31me\x1B[0m\x1B[31mf\x1B[0m") + HEXDUMP_EXTRA_FOR_UTF8];
 	char line[sizeof("00000000: 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 : \n") + sizeof(ascii)];
-
-	if (argc != 2) {
-		ntstdio_printf(&ntstdio, "hexdump file\n");
-	}
-
-	if ((res = f_open(&fsrc, argv[1], FA_OPEN_EXISTING | FA_READ)) != FR_OK) {
+	TCHAR *filename_p = NULL;
+	int op, option_flag = HEXDUMP_OPT_DEFAULT;
+	char *option_ptr, *option_endptr, ccolor, utf8_done_flg, utf8_odd_bytes = 0;
+	unsigned int op_offset = 0, op_size = 0, op_end = 0;
+
+	while ((op = musl_getopt(argc, argv, "hduos0123456789xX")) != -1) {
+		switch (op) {
+		case 'h': /* help */
+			ntstdio_printf(&ntstdio, " hexdump [OPTION] file\n");
+			ntstdio_printf(&ntstdio, "  -h : help\n");
+			ntstdio_printf(&ntstdio, "  -d : print all byte with convert and color [in character area] (default)\n");
+			ntstdio_printf(&ntstdio, "  -u : try print UTF-8 code [in character area]\n");
+			ntstdio_printf(&ntstdio, "  -oOFFSET : print start offset address from top\n");
+			ntstdio_printf(&ntstdio, "  -sSIZE   : print size\n");
+			break;
+		case 'd': /* print one byte character [in character area] (default) */
+			option_flag |= HEXDUMP_OPT_DEFAULT;
+			break;
+		case 'u': /* try print UTF-8 code [in character area] */
+			option_flag |= HEXDUMP_OPT_UTF8;
+			break;
+		case 'o': /* print start offset address from top */
+			option_ptr = *(argv + optind);
+			op_offset = ntlibc_strtoul(&option_ptr[2], &option_endptr, 0);
+			break;
+		case 's': /* print size */
+			option_ptr = *(argv + optind);
+			op_size = ntlibc_strtoul(&option_ptr[2], &option_endptr, 0);
+			break;
+		default:
+			break;
+		}
+	}
+	filename_p = *(argv + optind);
+	if (filename_p == NULL)
+		return 0;
+
+	if ((res = f_open(&fsrc, filename_p, FA_OPEN_EXISTING | FA_READ)) != FR_OK) {
 		put_rc("f_open", res);
 		return 0;
 	}
 
-	for (int i = 0; i < fsrc.fsize; i += 16) {
+	/* position adjusting */
+	if (op_offset >= fsrc.fsize) {
+		ntstdio_printf(&ntstdio, "error : input offset is bigger than file size(0x%X).\n", fsrc.fsize);
+		return 0;
+	}
+	op_end = op_offset + op_size;
+	if ((op_size == 0) || (op_end >= fsrc.fsize))
+		op_end = fsrc.fsize;
+	f_lseek(&fsrc, op_offset);
+
+	for (int i = op_offset; i < op_end; i += 16) {
 		ascii[0] = '\0';
 		line[0] = '\0';
@@ -526,10 +678,12 @@
 
 		UINT br = 0;
-		if ((res = f_read(&fsrc, data, 16, &br)) != FR_OK) {
+		if ((res = f_read(&fsrc, data, 16 + HEXDUMP_EXTRA_FOR_UTF8, &br)) != FR_OK) {
 			put_rc("f_read", res);
 			f_close(&fsrc);
 			return 0;
 		}
-		data[16] = '\0';
+		data[br] = '\0';
+		f_lseek(&fsrc, i + 16);
+		if (br > 16) br = 16;
 
 		char *apos = ascii;
@@ -544,13 +698,71 @@
 			rst -= len;
 
+			len = 0;
+			utf8_done_flg = 0;
+			ccolor = CCOLOR_RESET;
+
 			if (c < 0x20) {
-				len = ntstdio_snprintf(apos, arst , "\x1B[31m%c\x1B[0m", c + 0x40);
-			}
-			else if (c == 0xFF) {
-				len = ntstdio_snprintf(apos, arst, "\x1B[32m%c\x1B[0m", 'E');
+				ccolor = CCOLOR_RED;
+				c = c + 0x40;
 			}
 			else {
-				len = ntstdio_snprintf(apos, arst, "%c", c);
-			}
+				if (option_flag & HEXDUMP_OPT_UTF8) { /* try UTF-8 */
+					/* check character code */
+					int bf_utf8_bytes, af_utf8_bytes;
+					unsigned char utf8_code[4];
+					WCHAR utf16_code;
+
+					utf16_code = Utf8_to_Utf16(&data[j], &bf_utf8_bytes);       /* try UTF-8 -> UTF-16 */
+					Utf16_to_Utf8(utf8_code, &af_utf8_bytes, (UINT)utf16_code); /* try UTF-16 -> UTF-8 */
+					if ((af_utf8_bytes <= 3 && bf_utf8_bytes == af_utf8_bytes) &&
+						!memcmp(&data[j], utf8_code, af_utf8_bytes)) { /* size & code match */
+						utf8_done_flg = 1;
+						for (int k = 1; k < af_utf8_bytes; k++) { /* pos */
+							if (j + k >= 16)
+								break;
+							if (j + k != 7)
+								len = ntstdio_snprintf(pos, rst, "%02X ", data[j + k]);
+							else
+								len = ntstdio_snprintf(pos, rst, "%02X-", data[j + k]);
+							pos += len;
+							rst -= len;
+						}
+						memcpy(apos, &data[j], af_utf8_bytes); /* apos */
+						apos[af_utf8_bytes] = 0;
+						len = af_utf8_bytes;
+						j += af_utf8_bytes - 1;
+						if (af_utf8_bytes > 1) {
+							utf8_odd_bytes = j < 15 ? af_utf8_bytes - 2 : af_utf8_bytes - 1;
+						}
+					}
+				}
+			}
+
+			if (utf8_odd_bytes > 0 && j < 15) {
+				apos += len;
+				arst -= len;
+				len = ntstdio_snprintf(apos, arst, "\x1B[%dm%c\x1B[0m", CCOLOR_RESET, ' ');
+				utf8_odd_bytes--;
+			}
+			else if (utf8_done_flg == 0) {
+				if (c >= 0x80 && c < 0x9F) {
+					ccolor = CCOLOR_RED;
+					c = c - 0x60;
+				}
+				else if (c >= 0xA0 && c < 0xDF) {
+					ccolor = CCOLOR_GREEN;
+					c = c - 0x60;
+				}
+				else if (c >= 0xE0 && c < 0xFF) {
+					ccolor = CCOLOR_GREEN;
+					c = c - 0xC0;
+				}
+				else if (c == 0x7F || c == 0x9F || c == 0xDF || c == 0xFF) {
+					ccolor = CCOLOR_CYAN;
+					c = '?';
+				}
+				len = ntstdio_snprintf(apos, arst, "\x1B[%dm%c\x1B[0m", ccolor, c);
+			}
+
 			apos += len;
 			arst -= len;
@@ -570,5 +782,5 @@
 		rst -= len;
 
-		ntstdio_printf(&ntstdio, line);
+		ntstdio_puts(&ntstdio, line);
 	}
 
@@ -584,9 +796,9 @@
 		return 0;
 	}
-	if (strcmp(argv[1], "sys") == 0) {
+	if (ntlibc_strcmp(argv[1], "sys") == 0) {
 		ntstdio_printf(&ntstdio, "GR-PEACH Monitor\n");
 		return 0;
 	}
-	if (strcmp(argv[1], "ver") == 0) {
+	if (ntlibc_strcmp(argv[1], "ver") == 0) {
 		int mj, mn, bd;
 		ntshell_version(&mj, &mn, &bd);
Index: EcnlProtoTool/trunk/ntshell/ntshell/usrcmd.h
===================================================================
--- EcnlProtoTool/trunk/ntshell/ntshell/usrcmd.h	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/ntshell/usrcmd.h	(revision 331)
@@ -43,20 +43,20 @@
 } cmd_table_t;
 
-extern int usrcmd_cd(int argc, char **argv);
-extern int usrcmd_ls(int argc, char **argv);
-extern int usrcmd_cp(int argc, char **argv);
-extern int usrcmd_rm(int argc, char **argv);
-extern int usrcmd_mv(int argc, char **argv);
-extern int usrcmd_mkdir(int argc, char **argv);
-extern int usrcmd_hexdump(int argc, char **argv);
+int usrcmd_cd(int argc, char **argv);
+int usrcmd_ls(int argc, char **argv);
+int usrcmd_cp(int argc, char **argv);
+int usrcmd_rm(int argc, char **argv);
+int usrcmd_mv(int argc, char **argv);
+int usrcmd_mkdir(int argc, char **argv);
+int usrcmd_hexdump(int argc, char **argv);
 
-extern int usrcmd_help(int argc, char **argv);
-extern int usrcmd_info(int argc, char **argv);
-extern int usrcmd_exit(int argc, char **argv);
+int usrcmd_help(int argc, char **argv);
+int usrcmd_info(int argc, char **argv);
+int usrcmd_exit(int argc, char **argv);
 
-extern void shell_abort();
-extern void shell_exit(int exitcd);
-extern int shell_kill(int pid, int sig);
-extern int shell_gettimeofday(struct timeval * tp, void * tzvp);
+void shell_abort();
+void shell_exit(int exitcd);
+int shell_kill(int pid, int sig);
+int shell_gettimeofday(struct timeval * tp, void * tzvp);
 
 #endif
Index: EcnlProtoTool/trunk/ntshell/ntshell/util/ntopt.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/ntshell/util/ntopt.c	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/ntshell/util/ntopt.c	(revision 331)
@@ -131,5 +131,5 @@
 	int argc;
 	char argv[NTOPT_TEXT_MAXLEN];
-	char *argvp[NTOPT_TEXT_MAXARGS];
+	char *argvp[1 + NTOPT_TEXT_MAXARGS];
 	int i;
 	int total;
@@ -146,5 +146,5 @@
 	for (i = 0; i < argc; i++) {
 		int len;
-		argvp[i] = ntopt_get_text(
+		argvp[i + 1] = ntopt_get_text(
 			str, i, p, NTOPT_TEXT_MAXLEN - total, &len);
 		if (total + len + 1 < NTOPT_TEXT_MAXLEN) {
@@ -156,5 +156,6 @@
 		}
 	}
+	argvp[0] = (char *)argc;
 
-	return func(argc, &argvp[0], extobj);
+	return func((long *)&argvp[0], extobj);
 }
Index: EcnlProtoTool/trunk/ntshell/ntshell/util/ntopt.h
===================================================================
--- EcnlProtoTool/trunk/ntshell/ntshell/util/ntopt.h	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/ntshell/util/ntopt.h	(revision 331)
@@ -55,5 +55,5 @@
  * @return A return value.
  */
-typedef int (*NTOPT_CALLBACK)(int argc, char **argv, void *extobj);
+typedef int (*NTOPT_CALLBACK)(long *args, void *extobj);
 
 #ifdef __cplusplus
Index: EcnlProtoTool/trunk/ntshell/ntshell/util/ntstdio.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/ntshell/util/ntstdio.c	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/ntshell/util/ntstdio.c	(revision 331)
@@ -241,5 +241,5 @@
 
 	if (handle->xo) {
-		handle->xo((unsigned char)c);
+		handle->xo(handle, (unsigned char)c);
 	}
 	handle->pos++;
@@ -266,5 +266,5 @@
 void ntstdio_fputs(ntstdio_t *handle, NTSTDIO_XO xo, const char *str)
 {
-	void(*pf)(unsigned char);
+	NTSTDIO_XO pf;
 
 	/* Save current output device */
@@ -314,5 +314,5 @@
 	int result;
 	va_list arp;
-	void(*pf)(unsigned char);
+	NTSTDIO_XO pf;
 
 	/* Save current output device */
@@ -334,5 +334,5 @@
 	extern void shell_exit(int cd);
 
-	int c = handle->xi();
+	int c = handle->xi(handle);
 	if (handle->option & NTSTDIO_OPTION_LF_CR) {
 		if (c == '\r')
@@ -362,5 +362,5 @@
 	for (;;) {
 		/* Get a char from the incoming stream */
-		c = handle->xi();
+		c = handle->xi(handle);
 		if (!c) {
 			/* End of stream */
@@ -398,5 +398,5 @@
 int ntstdio_fgets(ntstdio_t *handle, NTSTDIO_XI xi, char *buf, int len)
 {
-	unsigned char(*pf)(void);
+	NTSTDIO_XI pf;
 	int n;
 
Index: EcnlProtoTool/trunk/ntshell/ntshell/util/ntstdio.h
===================================================================
--- EcnlProtoTool/trunk/ntshell/ntshell/util/ntstdio.h	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/ntshell/util/ntstdio.h	(revision 331)
@@ -67,14 +67,14 @@
 #define NTSTDIO_OPTION_LF_CR        (1 << 3)
 
-typedef unsigned char (*NTSTDIO_XI)(void);
-typedef void (*NTSTDIO_XO)(unsigned char c);
+typedef unsigned char (*NTSTDIO_XI)(struct ntstdio_t *handle);
+typedef void (*NTSTDIO_XO)(struct ntstdio_t *handle, unsigned char c);
 
-typedef struct {
-    NTSTDIO_XI xi;
-    NTSTDIO_XO xo;
-    char *outptr;
+typedef struct ntstdio_t {
+	NTSTDIO_XI xi;
+	NTSTDIO_XO xo;
+	char *outptr;
 	int len;
 	int pos;
-    unsigned int option;
+	unsigned int option;
 } ntstdio_t;
 
Index: EcnlProtoTool/trunk/ntshell/shellif.rb
===================================================================
--- EcnlProtoTool/trunk/ntshell/shellif.rb	(revision 321)
+++ 	(revision )
@@ -1,57 +1,0 @@
-
-def ReadSymbolFile(symbolFileName)
-  begin
-    symbolFile = File.open(symbolFileName)
-  rescue Errno::ENOENT, Errno::EACCES => ex
-    abort(ex.message)
-  end
-
-  symbolAddress = {}
-  symbolFile.each do |line|
-    # スペース区切りで分解
-    fields = line.split(/\s+/)
-
-    # 3列になっていない行は除外
-    if fields.size == 3 && fields[2].start_with?("__exp_")
-      symbolAddress[fields[2].gsub("__exp_", "")] = fields[0].hex
-    end
-  end
-  symbolFile.close
-  return(symbolAddress)
-end
-
-symbolsInfo = ReadSymbolFile("ntshell.syms")
-
-begin
-  outFile = File.open("../ntshell/shellif.h", "w")
-rescue Errno::ENOENT, Errno::EACCES => ex
-  abort(ex.message)
-end
-
-symbolsInfo.each do |k, v|
-  outFile.printf("#define __imp_%s ((%s_t)0x%08x)\n", k, k, v)
-end
-
-outFile.close
-
-begin
-  outFile = File.open("../ntshell/shellif_stub.c", "w")
-rescue Errno::ENOENT, Errno::EACCES => ex
-  abort(ex.message)
-end
-
-symbolsInfo.each do |k, v|
-  outFile.printf("typedef int (*%s_t)(void);\n", k)
-end
-
-outFile.print("\n")
-
-symbolsInfo.each do |k, v|
-  outFile.printf("int %s(void)\n", k)
-  outFile.print("{\n")
-  outFile.printf("\treturn __imp_%s();\n", k)
-  outFile.print("}\n")
-  outFile.print("\n")
-end
-
-outFile.close
Index: EcnlProtoTool/trunk/ntshell/src/bits/alltypes.h
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/bits/alltypes.h	(revision 331)
+++ EcnlProtoTool/trunk/ntshell/src/bits/alltypes.h	(revision 331)
@@ -0,0 +1,1 @@
+#include "../musl-1.1.18/include/bits/alltypes.h"
Index: EcnlProtoTool/trunk/ntshell/src/bits/fcntl.h
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/bits/fcntl.h	(revision 331)
+++ EcnlProtoTool/trunk/ntshell/src/bits/fcntl.h	(revision 331)
@@ -0,0 +1,1 @@
+#include "../musl-1.1.18/include/bits/fcntl.h"
Index: EcnlProtoTool/trunk/ntshell/src/bits/ioctl_fix.h
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/bits/ioctl_fix.h	(revision 331)
+++ EcnlProtoTool/trunk/ntshell/src/bits/ioctl_fix.h	(revision 331)
@@ -0,0 +1,1 @@
+#include "../musl-1.1.18/include/bits/ioctl_fix.h"
Index: EcnlProtoTool/trunk/ntshell/src/bits/signal.h
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/bits/signal.h	(revision 331)
+++ EcnlProtoTool/trunk/ntshell/src/bits/signal.h	(revision 331)
@@ -0,0 +1,1 @@
+#include "../musl-1.1.18/include/bits/signal.h"
Index: EcnlProtoTool/trunk/ntshell/src/bits/socket.h
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/bits/socket.h	(revision 331)
+++ EcnlProtoTool/trunk/ntshell/src/bits/socket.h	(revision 331)
@@ -0,0 +1,1 @@
+#include "../musl-1.1.18/include/bits/socket.h"
Index: EcnlProtoTool/trunk/ntshell/src/fdtable.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/fdtable.c	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/src/fdtable.c	(revision 331)
@@ -35,17 +35,10 @@
  *  @(#) $Id$
  */
+#include "shellif.h"
 #include <stdint.h>
-#include <stdio.h>
-#include <sys/unistd.h>
-#include <limits.h>
 #include <kernel.h>
 #include <t_syslog.h>
 #include <t_stdlib.h>
 #include <sil.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <setjmp.h>
-#include "../../../musl-1.1.12/include/poll.h"
 #include "syssvc/serial.h"
 #include "syssvc/syslog.h"
@@ -61,8 +54,9 @@
 #include <net/if_var.h>
 #include <netinet/udp_var.h>
-#include <ethernet_api.h>
+//#include <ethernet_api.h>
 #include "ff.h"
 #include "socket_stub.h"
 #include "kernel_cfg.h"
+#include <string.h>
 
 #define SIO_PORTID 1
@@ -71,11 +65,12 @@
 #define IO_TYPE_SIO		1
 #define IO_TYPE_FILE	2
-#define IO_TYPE_TCP		3
-#define IO_TYPE_UDP		4
+#define IO_TYPE_DIR		3
+#define IO_TYPE_TCP		4
+#define IO_TYPE_UDP		5
 
 static struct _IO_FILE fd_table[8 * sizeof(FLGPTN)] = {
-	{ 0, IO_TYPE_SIO, 0, stdio_close, stdin_read, stdio_write },
-	{ 1, IO_TYPE_SIO, 0, stdio_close, stdio_read, stdout_write },
-	{ 2, IO_TYPE_SIO, 0, stdio_close, stdio_read, stderr_write },
+	{ 0, IO_TYPE_SIO, 0, stdio_close, stdin_read, stdio_write, sio_seek, sio_ioctl },
+	{ 1, IO_TYPE_SIO, 0, stdio_close, stdio_read, stdout_write, sio_seek, sio_ioctl },
+	{ 2, IO_TYPE_SIO, 0, stdio_close, stdio_read, stderr_write, sio_seek, sio_ioctl },
 };
 #define fd_table_count (sizeof(fd_table) / sizeof(fd_table[0]))
@@ -94,5 +89,5 @@
 	}
 
-	return -1;
+	return -ENOMEM;
 }
 
@@ -112,5 +107,5 @@
 	struct _IO_FILE *fp = id_to_fd(type, id);
 	if (fp == NULL)
-		return -1;
+		return -EBADF;
 
 	memset(fp, 0, sizeof(struct _IO_FILE));
@@ -136,4 +131,6 @@
 	fp->read = sio_read;
 	fp->write = sio_write;
+	fp->seek = sio_seek;
+	fp->ioctl = sio_ioctl;
 
 	return fp;
@@ -160,4 +157,6 @@
 	fp->read = file_read;
 	fp->write = file_write;
+	fp->seek = file_seek;
+	fp->ioctl = file_ioctl;
 
 	return fp;
@@ -172,4 +171,30 @@
 {
 	return id_to_fd(IO_TYPE_FILE, fileid);
+}
+
+struct _IO_FILE *new_dir_fd(int fileid)
+{
+	int fd = new_fd(IO_TYPE_DIR, fileid);
+	if ((fd < 0) || (fd >= fd_table_count))
+		return NULL;
+
+	struct _IO_FILE *fp = &fd_table[fd];
+	fp->close = dir_close;
+	fp->read = dir_read;
+	fp->write = dir_write;
+	fp->seek = dir_seek;
+	fp->ioctl = dir_ioctl;
+
+	return fp;
+}
+
+int delete_dir_fd(int dirid)
+{
+	return delete_fd(IO_TYPE_DIR, dirid);
+}
+
+struct _IO_FILE *dirid_to_fd(int dirid)
+{
+	return id_to_fd(IO_TYPE_DIR, dirid);
 }
 
@@ -184,4 +209,6 @@
 	fp->read = tcp_fd_read;
 	fp->write = tcp_fd_write;
+	fp->seek = tcp_fd_seek;
+	fp->ioctl = tcp_fd_ioctl;
 
 	return fp;
@@ -208,4 +235,6 @@
 	fp->read = udp_fd_read;
 	fp->write = udp_fd_write;
+	fp->seek = udp_fd_seek;
+	fp->ioctl = udp_fd_ioctl;
 
 	return fp;
@@ -220,16 +249,4 @@
 {
 	return id_to_fd(IO_TYPE_UDP, udpid);
-}
-
-int shell_isatty(int fd)
-{
-	if ((fd < 0) || (fd >= fd_table_count))
-		return 0;
-
-	struct _IO_FILE *fp = &fd_table[fd];
-	if (fp->type == IO_TYPE_SIO)
-		return 1;
-
-	return 0;
 }
 
@@ -245,5 +262,5 @@
 #define TMO_MAX INT_MAX
 
-int select(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv)
+int shell_select(int n, fd_set *__restrict rfds, fd_set *__restrict wfds, fd_set *__restrict efds, struct timeval *__restrict tv)
 {
 	ER ret;
@@ -277,8 +294,8 @@
 	}
 
-	return -1;
-}
-
-int poll(struct pollfd *fds, nfds_t nfds, int timeout)
+	return -EBADF;
+}
+
+int shell_poll(struct pollfd *fds, nfds_t nfds, int timeout)
 {
 	ER ret;
@@ -334,5 +351,5 @@
 	}
 
-	return -1;
+	return -EBADF;
 }
 
@@ -541,2 +558,11 @@
 	}
 }
+
+int shell_ioctl(int fd, int request, void *arg)
+{
+	struct _IO_FILE *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
+
+	return fp->ioctl(fp, request, arg);
+}
Index: EcnlProtoTool/trunk/ntshell/src/features.h
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/features.h	(revision 331)
+++ EcnlProtoTool/trunk/ntshell/src/features.h	(revision 331)
@@ -0,0 +1,1 @@
+#include "../musl-1.1.18/include/features.h"
Index: EcnlProtoTool/trunk/ntshell/src/io_stub.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/io_stub.c	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/src/io_stub.c	(revision 331)
@@ -35,9 +35,6 @@
  *  @(#) $Id$
  */
+#include "shellif.h"
 #include <stdint.h>
-#include <stdio.h>
-#include <sys/unistd.h>
-#include <limits.h>
-#include <fcntl.h>
 #include "ff.h"
 #include <kernel.h>
@@ -45,7 +42,5 @@
 #include <t_stdlib.h>
 #include <sil.h>
-#include <stdlib.h>
 #include <string.h>
-#include <stdio.h>
 #include <setjmp.h>
 #include "syssvc/syslog.h"
@@ -61,18 +56,59 @@
 #include <net/if_var.h>
 #include <netinet/udp_var.h>
-#include <ethernet_api.h>
-#include "ff.h"
+//#include <ethernet_api.h>
 #include "socket_stub.h"
-#include "../../../musl-1.1.12/include/_dirent.h"
-#include "../../../musl-1.1.12/include/_termios.h"
-#include "ntstdio.h"
-
-int shell_open(const char * path, int flags)
-{
-	FRESULT res;
-
-	struct _IO_FILE *fp = new_file_fd(0);
-	if (fp == NULL)
-		return -1;
+//#include <sys/stat.h>
+#include "util/ntstdio.h"
+#include "usrcmd.h"
+#include "core/ntlibc.h"
+
+int fresult2errno(FRESULT res)
+{
+	switch (res) {
+	case FR_INVALID_OBJECT:
+		return -EINVAL;
+	case FR_TOO_MANY_OPEN_FILES:
+		return -ENOMEM;
+	case FR_NO_FILE:
+	case FR_NO_PATH:
+	case FR_INVALID_DRIVE:
+	case FR_INVALID_NAME:
+		return -ENOENT;
+	case FR_DISK_ERR:
+	case FR_NO_FILESYSTEM:
+	case FR_NOT_ENABLED:
+		return -ENODEV;
+	case FR_WRITE_PROTECTED:
+	case FR_DENIED:
+		return -EACCES;
+	case FR_EXIST:
+		return -EEXIST;
+	case FR_INT_ERR:
+	default:
+		return -EIO;
+	}
+}
+
+int shell_open(const char * path, int flags, void *arg)
+{
+	FRESULT res;
+	struct _IO_FILE *fp;
+
+	if (flags & O_DIRECTORY) {
+		fp = new_dir_fd(0);
+		if (fp == NULL)
+			return -ENOMEM;
+
+		DIR *dir = &fp->dir;
+		FRESULT res;
+		if ((res = f_opendir(dir, path)) != FR_OK) {
+			return fresult2errno(res);
+		}
+		return 0;
+	}
+
+	fp = new_file_fd(0);
+	if (fp == NULL)
+		return -ENOMEM;
 
 	BYTE fmd = 0;
@@ -115,5 +151,5 @@
 	}
 
-	return -1;
+	return fresult2errno(res);
 }
 
@@ -126,5 +162,5 @@
 	}
 
-	return -1;
+	return -EINVAL;
 }
 
@@ -135,5 +171,5 @@
 
 	if ((res = f_read(&fp->file, data, len, &ret)) != FR_OK)
-		return -1;
+		return -EIO;
 
 	return ret;
@@ -146,47 +182,111 @@
 
 	if ((res = f_write(&fp->file, data, len, &ret)) != FR_OK)
-		return -1;
+		return -EIO;
 
 	return ret;
 }
 
+off_t file_seek(struct _IO_FILE *fp, off_t ptr, int dir)
+{
+	switch (dir) {
+	case SEEK_SET:
+		dir = F_SEEK_SET;
+		break;
+	case SEEK_CUR:
+		dir = F_SEEK_CUR;
+		break;
+	case SEEK_END:
+		dir = F_SEEK_END;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	FRESULT res;
+	if ((res = f_seek(&fp->file, ptr, dir)) != FR_OK)
+		return -EIO;
+
+	return fp->file.fptr;
+}
+
+int file_ioctl(struct _IO_FILE *fp, int req, void *arg)
+{
+	DRESULT res;
+
+	if ((res = disk_ioctl(fp->file.fs->drv, req, arg) != RES_OK))
+		return -EINVAL;
+
+	return 0;
+}
+
 int shell_close(int fd)
 {
 	struct _IO_FILE *fp = fd_to_fp(fd);
 	if (fp == NULL)
-		return -1;
+		return -EBADF;
 
 	return fp->close(fp);
 }
 
-int shell_read(int fd, char *data, int len)
-{
-	struct _IO_FILE *fp = fd_to_fp(fd);
-	if (fp == NULL)
-		return -1;
+ssize_t shell_read(int fd, void *data, size_t len)
+{
+	struct _IO_FILE *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
 
 	return fp->read(fp, (unsigned char *)data, len);
 }
 
-int shell_write(int fd, char *data, int len)
-{
-	struct _IO_FILE *fp = fd_to_fp(fd);
-	if (fp == NULL)
-		return -1;
+int shell_readv(int fd, const struct iovec *iov, int iovcnt)
+{
+	int result = 0;
+	struct _IO_FILE *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
+
+	const struct iovec *end = &iov[iovcnt];
+	for (; iov < end; iov++) {
+		result += fp->read(fp, (unsigned char *)iov->iov_base, iov->iov_len);
+	}
+
+	return result;
+}
+
+ssize_t shell_write(int fd, const void *data, size_t len)
+{
+	struct _IO_FILE *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
 
 	return fp->write(fp, (unsigned char *)data, len);
 }
 
-int shell_lseek(int fd, int ptr, int dir)
-{
-	struct _IO_FILE *fp = fd_to_fp(fd);
-	if (fp == NULL)
-		return -1;
-
-	FRESULT res;
-	if ((res = f_seek(&fp->file, ptr, dir)) != FR_OK)
-		return -1;
-
-	return fp->file.fptr;
+int shell_writev(int fd, const struct iovec *iov, int iovcnt)
+{
+	int result = 0;
+	struct _IO_FILE *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
+
+	const struct iovec *end = &iov[iovcnt];
+	for (; iov < end; iov++) {
+		result += fp->write(fp, (unsigned char *)iov->iov_base, iov->iov_len);
+	}
+
+	return result;
+}
+
+int shell_llseek(int fd, off_t ptr, off_t *result, int dir)
+{
+	struct _IO_FILE *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
+
+	off_t ret = fp->seek(fp, ptr, dir);
+	if (ret < 0)
+		return ret;
+
+	*result = ret;
+	return 0;
 }
 
@@ -195,5 +295,5 @@
 	struct _IO_FILE *fp = fd_to_fp(fd);
 	if (fp == NULL)
-		return -1;
+		return -EBADF;
 
 	memset(st, 0, sizeof(*st));
@@ -203,34 +303,31 @@
 }
 
-int fsync(int fd)
-{
-	struct _IO_FILE *fp = fd_to_fp(fd);
-	if (fp == NULL)
-		return -1;
-	return -1;
-}
-
-int ftruncate(int fd, off_t length)
-{
-	struct _IO_FILE *fp = fd_to_fp(fd);
-	if (fp == NULL)
-		return -1;
+int shell_fsync(int fd)
+{
+	struct _IO_FILE *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
+	return -EIO;
+}
+
+int shell_ftruncate(int fd, off_t length)
+{
+	struct _IO_FILE *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
 
 	FRESULT res;
 	if ((res = f_truncate(&fp->file)) != FR_OK)
-		return -1;
-
-	return 0;
-}
-
-int ioctl(int fd, int request, va_list ap)
-{
-	struct _IO_FILE *fp = fd_to_fp(fd);
-	if (fp == NULL)
-		return -1;
-	return -1;
-}
-
-int tcgetattr(int fd, struct termios *termios)
+		return fresult2errno(res);
+
+	return 0;
+}
+
+int shell_fcntl(int fd, int cmd, void *arg)
+{
+	return shell_ioctl(fd, cmd, arg);
+}
+
+int sio_tcgetattr(int fd, struct termios *termios)
 {
 	extern ntstdio_t ntstdio;
@@ -265,9 +362,9 @@
 		return 0;
 	}
-	abort();
-	return 0;
-}
-
-int tcsetattr(int fd, int optional_actions, const struct termios *termios)
+	shell_abort();
+	return 0;
+}
+
+int sio_tcsetattr(int fd, int optional_actions, const struct termios *termios)
 {
 	extern ntstdio_t ntstdio;
@@ -300,9 +397,9 @@
 		return 0;
 	}
-	abort();
-	return 0;
-}
-
-int shell_stat(const char *path, struct stat *st)
+	shell_abort();
+	return 0;
+}
+
+int shell_stat(const char *__restrict path, struct stat *__restrict st)
 {
 	FILINFO fi;
@@ -313,27 +410,29 @@
 	fi.lfsize = sizeof lfn;
 #endif
-	if (strcmp(path, ".") == 0) {
+	if (ntlibc_strcmp(path, ".") == 0) {
 		char cwd[_MAX_LFN];
 		if ((ret = f_getcwd(cwd, sizeof(cwd))) != FR_OK) {
-		return -1;
-		}
-		int l = strlen(cwd);
+			return fresult2errno(ret);
+		}
+		int l = ntlibc_strlen(cwd);
 		// ルートディレクトリの場合
 		if (cwd[l - 2] == ':' && cwd[l - 1] == '/') {
 			st->st_size = 0;
-			st->st_mtime = 0;
+			st->st_mtim.tv_nsec = 0;
+			st->st_mtim.tv_sec = 0;
 			st->st_mode = S_IFDIR;
 			return 0;
 		}
 		if ((ret = f_stat(cwd, &fi)) != FR_OK) {
-			return -1;
+			return fresult2errno(ret);
 		}
 	}
 	else if ((ret = f_stat(path, &fi)) != FR_OK) {
-		return -1;
+		return fresult2errno(ret);
 	}
 
 	st->st_size = fi.fsize;
-	st->st_mtime = fi.fdate + fi.ftime;
+	st->st_mtim.tv_nsec = 0;
+	st->st_mtim.tv_sec = fi.fdate + fi.ftime;
 	st->st_mode  = (S_IRUSR | S_IRGRP | S_IROTH);
 	st->st_mode |= (fi.fattrib & AM_RDO) ? 0 : (S_IWUSR | S_IWGRP | S_IWOTH);
@@ -343,7 +442,12 @@
 }
 
-int shell_link(void)
-{
-	return -1;
+int shell_lstat(const char *__restrict path, struct stat *__restrict st)
+{
+	return shell_stat(path, st);
+}
+
+int shell_link(const char *a, const char *b)
+{
+	return -EPERM;
 }
 
@@ -353,15 +457,15 @@
 
 	if ((res = f_unlink(path)) != FR_OK)
-		return -1;
-
-	return 0;
-}
-
-int rmdir(const char *path)
+		return -EIO;
+
+	return 0;
+}
+
+int shell_rmdir(const char *path)
 {
 	FRESULT res;
 
 	if ((res = f_unlink(path)) != FR_OK)
-		return -1;
+		return -EIO;
 
 	return 0;
@@ -373,14 +477,17 @@
 
 	if ((res = f_rename(oldpath, newpath)) != FR_OK)
-		return -1;
-	return 0;
-}
-
-int mkdir(const char *path, mode_t mode)
+		return fresult2errno(res);
+	return 0;
+}
+
+#define S_IREAD S_IRUSR
+#define S_IWRITE S_IWUSR
+
+int shell_mkdir(const char *path, mode_t mode)
 {
 	FRESULT res;
 
 	if ((res = f_mkdir(path)) != FR_OK)
-		return -1;
+		return fresult2errno(res);
 
 	BYTE attr = 0;
@@ -397,13 +504,13 @@
 
 	if((res = f_chmod(path, attr, mask)) != FR_OK) {
-		return -1;
-	}
-
-	return 0;
-}
-
-int chmod(const char *path, mode_t mode)
-{
-	FRESULT ret;
+		return fresult2errno(res);
+	}
+
+	return 0;
+}
+
+int shell_chmod(const char *path, mode_t mode)
+{
+	FRESULT res;
 	BYTE attr = 0;
 	BYTE mask = AM_RDO | AM_SYS; // AM_ARC, AM_HID
@@ -418,12 +525,12 @@
 	}
 
-	if((ret = f_chmod(path, attr, mask)) != FR_OK) {
-		return -1;
-	}
-
-	return 0;
-}
-
-char *getcwd(char *buf, size_t size)
+	if((res = f_chmod(path, attr, mask)) != FR_OK) {
+		return fresult2errno(res);
+	}
+
+	return 0;
+}
+
+char *shell_getcwd(char *buf, size_t size)
 {
 	FRESULT ret;
@@ -435,48 +542,39 @@
 }
 
-int chdir(const char *path)
-{
-	FRESULT ret;
-	if ((ret = f_chdir(path)) != FR_OK) {
-		return -1;
-	}
-
-	return 0;
-}
-
-int chroot(const char *path)
-{
-	abort();
-	return -1;
-}
-
-DIR *opendir(const char *path)
-{
-	DIR *dir = malloc(sizeof(DIR) + sizeof(struct dirent));
-	FRESULT ret;
-	if ((ret = f_opendir(dir, path)) != FR_OK) {
-		free(dir);
-		return NULL;
-	}
-
-	dir->dirent = &dir[1];
-	return dir;
-}
-
-int closedir(DIR *dir)
-{
-	FRESULT ret;
-	if ((ret = f_closedir(dir)) != FR_OK) {
-		free(dir);
-		return -1;
-	}
-
-	free(dir);
-	return 0;
-}
-
-struct dirent *readdir(DIR *dir)
-{
-	struct dirent *de = dir->dirent;
+int shell_chdir(const char *path)
+{
+	FRESULT res;
+	if ((res = f_chdir(path)) != FR_OK) {
+		return fresult2errno(res);
+	}
+
+	return 0;
+}
+
+int shell_chroot(const char *path)
+{
+	shell_abort();
+	return -EPERM;
+}
+
+int dir_close(struct _IO_FILE *fp)
+{
+	FRESULT res;
+	if ((res = f_closedir(&fp->dir)) != FR_OK) {
+		return fresult2errno(res);
+	}
+
+	return 0;
+}
+
+int shell_getdents(int fd, struct dirent *de, size_t len)
+{
+	if (len < sizeof(struct dirent))
+		return -EINVAL;
+
+	struct _IO_FILE *fp = fd_to_fp(fd);
+	if (fp == NULL)
+		return -EBADF;
+
 	FILINFO fno;
 #if _USE_LFN
@@ -485,40 +583,117 @@
 	fno.lfsize = sizeof lfn;
 #endif
-	FRESULT ret;
-	if ((ret = f_readdir(dir, &fno)) != FR_OK || fno.fname[0] == '\0') {
-		return NULL;
+	FRESULT res;
+	if ((res = f_readdir(&fp->dir, &fno)) != FR_OK || fno.fname[0] == '\0') {
+		return fresult2errno(res);
 	}
 
 	memset(de, 0, sizeof(*de));
 #if _USE_LFN
-	strlcpy(de->d_name, *fno.lfname ? fno.lfname : fno.fname, sizeof(de->d_name));
+	ntlibc_strlcpy(de->d_name, *fno.lfname ? fno.lfname : fno.fname, sizeof(de->d_name));
 #else
-	strlcpy(de->d_name, fno.fname, sizeof(de->d_name));
+	ntlibc_strlcpy(de->d_name, fno.fname, sizeof(de->d_name));
 #endif
 
-	return de;
-}
-
-void rewinddir(DIR *dir)
-{
-	FRESULT ret;
-	if ((ret = f_rewinddir(dir)) != FR_OK) {
-		return;
-	}
-}
-
-void seekdir(DIR *dir, long pos)
-{
-	abort();
-}
-
-long telldir(DIR *dir)
-{
-	abort();
-	return 0;
-}
-
-int shell_getpid(int n)
+	return 0;
+}
+
+size_t dir_read(struct _IO_FILE *fp, unsigned char *data, size_t len)
+{
+	return -EPERM;
+}
+
+size_t dir_write(struct _IO_FILE *fp, const unsigned char *data, size_t len)
+{
+	return -EPERM;
+}
+
+off_t dir_seek(struct _IO_FILE *fp, off_t ptr, int dir)
+{
+	FRESULT res;
+
+	if (dir != SEEK_SET)
+		return -EINVAL;
+
+	if (ptr == 0) {
+		if ((res = f_rewinddir(&fp->dir)) != FR_OK) {
+			return fresult2errno(res);
+		}
+	}
+	else {
+		FILINFO fno;
+#if _USE_LFN
+		static char lfn[_MAX_LFN + 1];   /* Buffer to store the LFN */
+		fno.lfname = lfn;
+		fno.lfsize = sizeof lfn;
+#endif
+		if ((res = f_rewinddir(&fp->dir)) != FR_OK) {
+			return fresult2errno(res);
+		}
+
+		for (int i = 0; i < ptr; i++) {
+			if ((res = f_readdir(&fp->dir, &fno)) != FR_OK || fno.fname[0] == '\0') {
+				return fresult2errno(res);
+			}
+		}
+	}
+
+	return ptr;
+}
+
+int dir_ioctl(struct _IO_FILE *fp, int req, void *arg)
+{
+	return -EINVAL;
+}
+
+pid_t shell_getpid(void)
 {
 	return 1;
 }
+
+int shell_access(const char *path, int mode)
+{
+	struct stat st;
+	int ret;
+
+	ret = shell_stat(path, &st);
+	if (ret != 0)
+		return ret;
+
+	return 0;
+}
+
+//#include "../musl-1.1.18/include/bits/limits.h"
+#define PAGE_SIZE 4096
+
+uint32_t  __CmdBase;
+uint32_t  __CmdLimit;
+
+void *shell_brk(void *addr)
+{
+	if (addr == 0) {
+		return (void *)((intptr_t)&__CmdBase + 0x20000);
+	}
+	if ((addr >= (intptr_t)&__CmdBase + 0x20000) && (addr < &__CmdLimit)) {
+		return addr;
+	}
+	return (void *)-1;
+}
+
+void *shell_mmap2(void *start, size_t length, int prot, int flags, int fd, off_t pgoffset)
+{
+	if (fd != -1)
+		return -EINVAL;
+
+	if ((length >= 0) && (length <= (intptr_t)&__CmdLimit - (intptr_t)&__CmdBase - 0x20000)) {
+		return &__CmdBase + 0x20000;
+	}
+	return (void *)-1;
+}
+
+int shell_mprotect(void *addr, size_t len, int prot)
+{
+	//if ((addr >= (intptr_t)&__CmdBase + 0x20000) && ((intptr_t)addr + len < &__CmdLimit)) {
+		return 0;
+	//}
+	//return -1;
+}
Index: EcnlProtoTool/trunk/ntshell/src/main.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/main.c	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/src/main.c	(revision 331)
@@ -40,12 +40,10 @@
  */
 
+#include "shellif.h"
 #include <kernel.h>
-#include <t_syslog.h>
 #include <t_stdlib.h>
 #include <sil.h>
-#include <stdlib.h>
+#include <setjmp.h>
 #include <string.h>
-#include <stdio.h>
-#include <setjmp.h>
 #include "syssvc/serial.h"
 #include "syssvc/syslog.h"
@@ -64,17 +62,13 @@
 #include <net/if_var.h>
 #include <netinet/udp_var.h>
-#include <ethernet_api.h>
 #include "ffarch.h"
-#include "gpio_api.h"
 #include "ff.h"
 #include "websocket_fbs.h"
-#include "ntshell.h"
-#include "ntstdio.h"
+#include "core/ntshell.h"
+#include "core/ntlibc.h"
+#include "util/ntstdio.h"
 #include "usrcmd.h"
-#include "ntopt.h"
-
-#ifndef _MSC_VER
-void strcpy_s(char *dst, int size, const char *src);
-#endif
+#include "util/ntopt.h"
+#include "socket_stub.h"
 
 ID ws_api_mailboxid = MAIN_DATAQUEUE;
@@ -86,6 +80,13 @@
 ntstdio_t ntstdio;
 
-const uint8_t mac_addr[6] = {0x00, 0x30, 0x13, 0x06, 0x62, 0xC0};
-const char host_name[] = "GR-PEACH";
+const uint8_t mac_addr[6] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC};
+const struct utsname host_name = {
+	"TOPPERS/ASP3",
+    "GR-PEACH",
+    "3.1.0",
+    "3.1.0",
+    "GR-PEACH",
+    "toppers.jp"
+};
 
 static void netif_link_callback(T_IFNET *ether);
@@ -228,5 +229,5 @@
 	char buf[1];
 	if(serial_rea_dat(SIO_PORTID, buf, 1) != 1)
-		return -1;
+		return -EIO;
 	return buf[0];
 }
@@ -305,5 +306,5 @@
 
 	if (exec) {
-		strcpy_s(command, sizeof(command), "mruby -b 1:/upload/main.mrb");
+		ntlibc_strlcpy(command, "mruby -b 1:/upload/main.mrb", sizeof(command));
 
 		execute_command(1);
@@ -371,13 +372,13 @@
 }
 
-int gethostname(char *name, size_t len)
-{
-	return strlcpy(name, host_name, len);
-}
-
-static int usrcmd_ntopt_callback(int argc, char **argv, void *extobj);
+int shell_uname(struct utsname *uts)
+{
+	return memcpy(uts, &host_name, sizeof(host_name));
+}
+
+static int usrcmd_ntopt_callback(long *args, void *extobj);
 int mruby_exit_code;
 volatile int mruby_state;
-typedef void (*PowerOn_Reset_t)(int argc, char **argv);
+typedef void (*PowerOn_Reset_t)(long *args);
 jmp_buf process_exit;
 
@@ -392,10 +393,52 @@
 }
 
-static int usrcmd_ntopt_callback(int argc, char **argv, void *extobj)
-{
+typedef struct
+{
+	const cmd_table_t *table;
+	int count;
+} cmd_table_info_t;
+
+static const cmd_table_t cmdlist[] = {
+	{"cd", "change directory", usrcmd_cd },
+	{"ls", "list files", usrcmd_ls },
+	{"cp", "copy file", usrcmd_cp },
+	{"rm", "remove file", usrcmd_rm },
+	{"mv", "move file", usrcmd_mv },
+	{"mkdir", "Make directory", usrcmd_mkdir},
+	{"hexdump", "Hex dump", usrcmd_hexdump},
+	{"info", "This is a description text string for info command.", usrcmd_info},
+	{"exit", "Exit Natural Tyny Shell", usrcmd_exit},
+};
+cmd_table_info_t cmd_table_info = { cmdlist, sizeof(cmdlist) / sizeof(cmdlist[0]) };
+
+static int usrcmd_ntopt_callback(long *args, void *extobj)
+{
+	const cmd_table_t *p = cmd_table_info.table;
+	if (ntlibc_strcmp((const char *)args[1], "help") == 0) {
+		usrcmd_help(args[0], (char **)&args[1]);
+	}
+	else for (int i = 0; i < cmd_table_info.count; i++) {
+		if (ntlibc_strcmp((const char *)args[1], p->cmd) == 0) {
+			return p->func(args[0], (char **)&args[1]);
+		}
+		p++;
+	}
 	if (setjmp(process_exit) == 0) {
-		(*((PowerOn_Reset_t *)0x18200000))(argc, argv);
+		(*((PowerOn_Reset_t *)0x18200000))(args);
 	}
 	clean_fd();
+	return 0;
+}
+
+int usrcmd_help(int argc, char **argv)
+{
+	const cmd_table_t *p = cmd_table_info.table;
+	for (int i = 0; i < cmd_table_info.count; i++) {
+		ntstdio_puts(&ntstdio, p->cmd);
+		ntstdio_puts(&ntstdio, "\t:");
+		ntstdio_puts(&ntstdio, p->desc);
+		ntstdio_puts(&ntstdio, "\n");
+		p++;
+	}
 	return 0;
 }
@@ -422,4 +465,10 @@
 
 void shell_exit(int exitcd)
+{
+	mruby_exit_code = exitcd;
+	longjmp(process_exit, 1);
+}
+
+void shell_exit_group(int exitcd)
 {
 	mruby_exit_code = exitcd;
@@ -458,5 +507,5 @@
 static int cmd_execute(const char *text, void *extobj)
 {
-	strlcpy(command, text, sizeof(command));
+	ntlibc_strlcpy(command, text, sizeof(command));
 	return execute_command(1);
 }
@@ -464,15 +513,15 @@
 int stdio_close(struct _IO_FILE *fp)
 {
-	return -1;
+	return -EPERM;
 }
 
 size_t stdio_read(struct _IO_FILE *fp, unsigned char *data, size_t len)
 {
-	return -1;
+	return -EPERM;
 }
 
 size_t stdio_write(struct _IO_FILE *fp, const unsigned char *data, size_t len)
 {
-	return -1;
+	return -EPERM;
 }
 
@@ -507,14 +556,141 @@
 int sio_close(struct _IO_FILE *fp)
 {
-	return -1;
+	return -EPERM;
 }
 
 size_t sio_read(struct _IO_FILE *fp, unsigned char *data, size_t len)
 {
-	return -1;
+	return -EPERM;
 }
 
 size_t sio_write(struct _IO_FILE *fp, const unsigned char *data, size_t len)
 {
-	return -1;
-}
+	return -EPERM;
+}
+
+off_t sio_seek(struct _IO_FILE *fp, off_t ofs, int org)
+{
+	return -EPERM;
+}
+
+int sio_ioctl(struct _IO_FILE *fp, int request, void *arg)
+{
+	switch (request) {
+	case TIOCGWINSZ:
+		return 0;
+	case TCGETS:
+		return sio_tcgetattr(fp->fd, (struct termios *)arg);
+	case TCSETS + TCSANOW:
+	case TCSETS + TCSADRAIN:
+	case TCSETS + TCSAFLUSH:
+		return sio_tcsetattr(fp->fd, request - TCSETS, (const struct termios *)arg);
+	}
+
+	return -EINVAL;
+}
+
+int shell_clock_getres(clockid_t clk_id, struct timespec *res)
+{
+	if (clk_id != CLOCK_REALTIME)
+		return -EINVAL;
+
+	memset(&res->tv_sec, 0xFF, sizeof(res->tv_sec));
+	res->tv_nsec = 0;
+
+	return 0;
+}
+
+int shell_clock_gettime(clockid_t clk_id, struct timespec *tp)
+{
+	SYSTIM now = 0;
+
+	if (clk_id != CLOCK_REALTIME)
+		return -EINVAL;
+
+	get_tim(&now);
+	tp->tv_sec = now / 1000000;
+	tp->tv_nsec = (now % 1000000) * 1000;
+
+	return 0;
+}
+
+int shell_clock_settime(clockid_t clk_id, const struct timespec *tp)
+{
+	if (clk_id != CLOCK_REALTIME)
+		return -EINVAL;
+
+	rtc_write(tp->tv_sec);
+
+	return 0;
+}
+
+sigset_t g_sigmask;
+
+int shell_sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict old)
+{
+	if (old != NULL)
+		memcpy(old, &g_sigmask, sizeof(sigset_t));
+
+	switch (how) {
+	case SIG_BLOCK:
+		for (int i = 0; i < sizeof(g_sigmask.__bits) / sizeof(g_sigmask.__bits[0]); i++) {
+			g_sigmask.__bits[i] |= set->__bits[i];
+		}
+		break;
+	case SIG_UNBLOCK:
+		for (int i = 0; i < sizeof(g_sigmask.__bits) / sizeof(g_sigmask.__bits[0]); i++) {
+			g_sigmask.__bits[i] &= ~set->__bits[i];
+		}
+		break;
+	case SIG_SETMASK:
+		memcpy(&g_sigmask, set, sizeof(sigset_t));
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+struct sigaction sigtable[6];
+
+int shell_sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
+{
+	struct sigaction *sat;
+
+	switch(sig){
+	case SIGALRM:
+		sat = &sigtable[0];
+		break;
+	case SIGFPE:
+		sat = &sigtable[1];
+		break;
+	case SIGILL:
+		sat = &sigtable[2];
+		break;
+	case SIGSEGV:
+		sat = &sigtable[3];
+		break;
+	case SIGBUS:
+		sat = &sigtable[4];
+		break;
+	case SIGABRT:
+		sat = &sigtable[5];
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (old != NULL)
+		memcpy(old, sat, sizeof(struct sigaction));
+
+	memcpy(sat, sa, sizeof(struct sigaction));
+
+	return 0;
+}
+
+int shell_madvise(void *a, size_t b, int c)
+{
+	return 0;
+}
+
Index: EcnlProtoTool/trunk/ntshell/src/main.cfg
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/main.cfg	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/src/main.cfg	(revision 331)
@@ -61,4 +61,4 @@
 CRE_SEM(SEM_FILESYSTEM, { TA_TPRI, 1, 1 });
 
-CRE_TSK(MRUBY_TASK, { TA_NULL, 0, mruby_task, MRUBY_PRIORITY, MRUBY_STACK_SIZE, (void *)0x20600000 });
+CRE_TSK(MRUBY_TASK, { TA_NULL, 0, mruby_task, MRUBY_PRIORITY, MRUBY_STACK_SIZE, (void *)0x20100000 });
 CRE_FLG(FLG_SELECT_WAIT, { TA_WMUL, 0x00 });
Index: EcnlProtoTool/trunk/ntshell/src/main.h
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/main.h	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/src/main.h	(revision 331)
@@ -56,5 +56,5 @@
 
 #define MAIN_STACK_SIZE		2048	/* メインタスクのスタック領域のサイズ */
-#define MRUBY_STACK_SIZE	0x100000	/* mruby実行タスクのスタック領域のサイズ */
+#define MRUBY_STACK_SIZE	0x00800000	/* mruby実行タスクのスタック領域のサイズ */
 
 #define NUM_MAIN_DATAQUEUE	1	/* メインタスクで待ち受けているデータキューのサイズ */
Index: EcnlProtoTool/trunk/ntshell/src/mbedcall.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/mbedcall.c	(revision 331)
+++ EcnlProtoTool/trunk/ntshell/src/mbedcall.c	(revision 331)
@@ -0,0 +1,394 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2017 Cores Co., Ltd. Japan
+ * 
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+ *  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+ *  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+ *      ã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+ *        å ±åãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+ *      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+ *      å
+è²¬ãããã¨ï¼
+ * 
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+ *  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+ *  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+ *  ã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+#include "shellif.h"
+#include <stdarg.h>
+#include "analogin_api.h"
+#include "gpio_api.h"
+#include "i2c_api.h"
+#include "pwmout_api.h"
+//#include "rtc_api.h"
+#include "serial_api.h"
+#include "us_ticker_api.h"
+#include "wait_api.h"
+#include "../../mbed_api/src/mbedcall.h"
+
+static inline long __exp_analogin_init(struct regs_t *r)
+{
+	analogin_init((analogin_t *)r->a, (PinName)r->b);
+	return 0;
+}
+
+static inline long __exp_analogin_read_u16(struct regs_t *r)
+{
+	return (long)analogin_read_u16((analogin_t *)r->a);
+}
+
+static inline long __exp_gpio_init(struct regs_t *r)
+{
+	gpio_init((gpio_t *)r->a, (PinName)r->b);
+	return 0;
+}
+
+static inline long __exp_gpio_mode(struct regs_t *r)
+{
+	gpio_mode((gpio_t *)r->a, (PinMode)r->b);
+	return 0;
+}
+
+static inline long __exp_gpio_dir(struct regs_t *r)
+{
+	gpio_dir((gpio_t *)r->a, (PinDirection)r->b);
+	return 0;
+}
+
+static inline long __exp_gpio_write(struct regs_t *r)
+{
+	gpio_write((gpio_t *)r->a, (int)r->b);
+	return 0;
+}
+
+static inline long __exp_gpio_read(struct regs_t *r)
+{
+	return (long)gpio_read((gpio_t *)r->a);
+}
+
+static inline long __exp_i2c_start(struct regs_t *r)
+{
+	return (long)i2c_start((i2c_t *)r->a);
+}
+
+static inline long __exp_i2c_stop(struct regs_t *r)
+{
+	return (long)i2c_stop((i2c_t *)r->a);
+}
+
+static inline long __exp_i2c_init(struct regs_t *r)
+{
+	i2c_init((i2c_t *)r->a, (PinName)r->b, (PinName)r->c);
+	return 0;
+}
+
+static inline long __exp_i2c_read(struct regs_t *r)
+{
+	return (long)i2c_read((i2c_t *)r->a, (int)r->b, (char *)r->c, (int)r->d, (int)r->e);
+}
+
+static inline long __exp_i2c_write(struct regs_t *r)
+{
+	return (long)i2c_write((i2c_t *)r->a, (int)r->b, (const char *)r->c, (int)r->d, (int)r->e);
+}
+
+static inline long __exp_i2c_byte_read(struct regs_t *r)
+{
+	return (long)i2c_byte_read((i2c_t *)r->a, (int)r->b);
+}
+
+static inline long __exp_i2c_byte_write(struct regs_t *r)
+{
+	return (long)i2c_byte_write((i2c_t *)r->a, (int)r->b);
+}
+
+static inline long __exp_pin_function(struct regs_t *r)
+{
+	return (long)pin_function((PinName)r->a, (int)r->b);
+}
+
+static inline long __exp_pin_mode(struct regs_t *r)
+{
+	return (long)pin_mode((PinName)r->a, (PinMode)r->b);
+}
+
+static inline long __exp_pwmout_free(struct regs_t *r)
+{
+	pwmout_free((pwmout_t *)r->a);
+	return 0;
+}
+
+static inline long __exp_pwmout_init(struct regs_t *r)
+{
+	pwmout_init((pwmout_t *)r->a, (PinName)r->b);
+	return 0;
+}
+
+static inline long __exp_pwmout_pulsewidth_us(struct regs_t *r)
+{
+	pwmout_pulsewidth_us((pwmout_t *)r->a, (int)r->b);
+	return 0;
+}
+
+static inline long __exp_rtc_init(struct regs_t *r)
+{
+	rtc_init();
+	return 0;
+}
+
+static inline long __exp_rtc_free(struct regs_t *r)
+{
+	rtc_free();
+	return 0;
+}
+
+static inline long __exp_rtc_isenabled(struct regs_t *r)
+{
+	return (long)rtc_isenabled();
+}
+
+static inline long __exp_rtc_read(struct regs_t *r)
+{
+	return (long)rtc_read();
+}
+
+static inline long __exp_rtc_write(struct regs_t *r)
+{
+	rtc_write((time_t)r->a);
+	return 0;
+}
+
+static inline long __exp_serial_baud(struct regs_t *r)
+{
+	serial_baud((serial_t *)r->a, (int)r->b);
+	return 0;
+}
+
+static inline long __exp_serial_init(struct regs_t *r)
+{
+	serial_init((serial_t *)r->a, (PinName)r->b, (PinName)r->c);
+	return 0;
+}
+
+static inline long __exp_serial_readable(struct regs_t *r)
+{
+	return (long)serial_readable((serial_t *)r->a);
+}
+
+static inline long __exp_serial_getc(struct regs_t *r)
+{
+	return (long)serial_getc((serial_t *)r->a);
+}
+
+static inline long __exp_serial_putc(struct regs_t *r)
+{
+	serial_putc((serial_t *)r->a, (int)r->b);
+	return 0;
+}
+
+static inline long __exp_us_ticker_init(struct regs_t *r)
+{
+	us_ticker_init();
+	return 0;
+}
+
+static inline long __exp_us_ticker_read(struct regs_t *r)
+{
+	return (long)us_ticker_read();
+}
+
+static inline long __exp_us_ticker_set_interrupt(struct regs_t *r)
+{
+	us_ticker_set_interrupt((timestamp_t)r->a);
+	return 0;
+}
+
+static inline long __exp_us_ticker_disable_interrupt(struct regs_t *r)
+{
+	us_ticker_disable_interrupt();
+	return 0;
+}
+
+static inline long __exp_us_ticker_clear_interrupt(struct regs_t *r)
+{
+	us_ticker_clear_interrupt();
+	return 0;
+}
+
+static inline long __exp_SD_begin(struct regs_t *r)
+{
+	return (long)SD_begin();
+}
+
+static long __mbedcall(struct regs_t *r)
+{
+	long ret = -ENOSYS;
+
+	shellif_into();
+
+	switch (r->n) {
+	case MBED_analogin_init:
+		ret = __exp_analogin_init(r);
+		break;
+	case MBED_analogin_read_u16:
+		ret = __exp_analogin_read_u16(r);
+		break;
+	case MBED_gpio_init:
+		ret = __exp_gpio_init(r);
+		break;
+	case MBED_gpio_mode:
+		ret = __exp_gpio_mode(r);
+		break;
+	case MBED_gpio_dir:
+		ret = __exp_gpio_dir(r);
+		break;
+	case MBED_gpio_write:
+		ret = __exp_gpio_write(r);
+		break;
+	case MBED_gpio_read:
+		ret = __exp_gpio_read(r);
+		break;
+	case MBED_i2c_start:
+		ret = __exp_i2c_start(r);
+		break;
+	case MBED_i2c_stop:
+		ret = __exp_i2c_stop(r);
+		break;
+	case MBED_i2c_init:
+		ret = __exp_i2c_init(r);
+		break;
+	case MBED_i2c_read:
+		ret = __exp_i2c_read(r);
+		break;
+	case MBED_i2c_write:
+		ret = __exp_i2c_write(r);
+		break;
+	case MBED_i2c_byte_read:
+		ret = __exp_i2c_byte_read(r);
+		break;
+	case MBED_i2c_byte_write:
+		ret = __exp_i2c_byte_write(r);
+		break;
+	case MBED_pin_function:
+		ret = __exp_pin_function(r);
+		break;
+	case MBED_pin_mode:
+		ret = __exp_pin_mode(r);
+		break;
+	case MBED_pwmout_free:
+		ret = __exp_pwmout_free(r);
+		break;
+	case MBED_pwmout_init:
+		ret = __exp_pwmout_init(r);
+		break;
+	case MBED_pwmout_pulsewidth_us:
+		ret = __exp_pwmout_pulsewidth_us(r);
+		break;
+	case MBED_rtc_init:
+		ret = __exp_rtc_init(r);
+		break;
+	case MBED_rtc_free:
+		ret = __exp_rtc_free(r);
+		break;
+	case MBED_rtc_isenabled:
+		ret = __exp_rtc_isenabled(r);
+		break;
+	case MBED_rtc_read:
+		ret = __exp_rtc_read(r);
+		break;
+	case MBED_rtc_write:
+		ret = __exp_rtc_write(r);
+		break;
+	case MBED_serial_baud:
+		ret = __exp_serial_baud(r);
+		break;
+	case MBED_serial_init:
+		ret = __exp_serial_init(r);
+		break;
+	case MBED_serial_readable:
+		ret = __exp_serial_readable(r);
+		break;
+	case MBED_serial_getc:
+		ret = __exp_serial_getc(r);
+		break;
+	case MBED_serial_putc:
+		ret = __exp_serial_putc(r);
+		break;
+	case MBED_us_ticker_init:
+		ret = __exp_us_ticker_init(r);
+		break;
+	case MBED_us_ticker_read:
+		ret = __exp_us_ticker_read(r);
+		break;
+	case MBED_us_ticker_set_interrupt:
+		ret = __exp_us_ticker_set_interrupt(r);
+		break;
+	case MBED_us_ticker_disable_interrupt:
+		ret = __exp_us_ticker_disable_interrupt(r);
+		break;
+	case MBED_us_ticker_clear_interrupt:
+		ret = __exp_us_ticker_clear_interrupt(r);
+		break;
+	case MBED_SD_begin:
+		ret = __exp_SD_begin(r);
+		break;
+	case MBED___enable_irq:
+		ret = 0;
+		break;
+	case MBED___disable_irq:
+		ret = 0;
+		break;
+	default:
+		asm("bkpt #0");
+		break;
+	}
+
+	shellif_outof();
+
+	return ret;
+}
+
+void __attribute__((naked)) __mbedcall_cp_asm()
+{
+	register long sp asm("sp");
+	asm("push	{r0, r1, r2, r3, r4, r5, r7, r12, lr}");
+	__mbedcall((struct regs_t *)sp);
+	asm("add	sp, sp, #4");
+	asm("pop	{r1, r2, r3, r4, r5, r7, r12, pc}");
+}
+
Index: EcnlProtoTool/trunk/ntshell/src/route_cfg.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/route_cfg.c	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/src/route_cfg.c	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2017 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -44,11 +44,23 @@
 #include <netinet/in_var.h>
 
+/* IPv6 に関する定義 */
+
+#ifdef _IP6_CFG
+
+#if NUM_IN6_ROUTE_ENTRY > 0
+
+T_IN6_RTENTRY routing6_tbl[NUM_IN6_ROUTE_ENTRY];
+
+#endif	/* of #if NUM_IN6_ROUTE_ENTRY > 0 */
+
+#endif	/* of #ifdef _IP6_CFG */
+
 /* IPv4 に関する定義 */
 
-#ifdef SUPPORT_INET4
+#ifdef _IP4_CFG
 
 #ifdef SUPPORT_LOOP
 
-T_IN4_RTENTRY routing_tbl[NUM_ROUTE_ENTRY] = {
+T_IN4_RTENTRY routing4_tbl[NUM_IN4_ROUTE_ENTRY] = {
 	{ 0, 0, 0 },
 	};
@@ -58,5 +70,5 @@
 #ifdef SUPPORT_PPP
 
-T_IN4_RTENTRY routing_tbl[NUM_ROUTE_ENTRY] = {
+T_IN4_RTENTRY routing4_tbl[NUM_IN4_ROUTE_ENTRY] = {
 	{ 0, 0, 0 },
 	};
@@ -66,5 +78,5 @@
 #ifdef SUPPORT_ETHER
 
-T_IN4_RTENTRY routing_tbl[NUM_ROUTE_ENTRY] = {
+T_IN4_RTENTRY routing4_tbl[NUM_IN4_ROUTE_ENTRY] = {
 
 	/* 異なる LAN、default gateway による間接配送	*/
@@ -82,15 +94,3 @@
 #endif	/* of #ifdef SUPPORT_ETHER */
 
-#endif	/* of #ifdef SUPPORT_INET4 */
-
-/* IPv6 に関する定義 */
-
-#ifdef SUPPORT_INET6
-
-#if NUM_ROUTE_ENTRY > 0
-
-T_IN6_RTENTRY routing_tbl[NUM_ROUTE_ENTRY] = { };
-
-#endif	/* of #if NUM_ROUTE_ENTRY > 0 */
-
-#endif	/* of #ifdef SUPPORT_INET6 */
+#endif	/* of #ifdef _IP4_CFG */
Index: EcnlProtoTool/trunk/ntshell/src/shellif.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/shellif.c	(revision 321)
+++ 	(revision )
@@ -1,825 +1,0 @@
-/*
- *  TOPPERS ECHONET Lite Communication Middleware
- * 
- *  Copyright (C) 2017 Cores Co., Ltd. Japan
- * 
- *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
- *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
- *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
- *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
- *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
- *      スコード中に含まれていること．
- *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
- *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
- *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
- *      の無保証規定を掲載すること．
- *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
- *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
- *      と．
- *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
- *        作権表示，この利用条件および下記の無保証規定を掲載すること．
- *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
- *        報告すること．
- *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
- *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
- *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
- *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
- *      免責すること．
- * 
- *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
- *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
- *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
- *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
- *  の責任を負わない．
- * 
- *  @(#) $Id$
- */
-#include <setjmp.h>
-#include <sys/time.h>
-#include <stdarg.h>
-#include "../../../musl-1.1.12/include/poll.h"
-#include "analogin_api.h"
-#include "gpio_api.h"
-#include "i2c_api.h"
-#include "pwmout_api.h"
-#include "rtc_api.h"
-#include "serial_api.h"
-#include "us_ticker_api.h"
-#include "wait_api.h"
-#include "usrcmd.h"
-#include "ff.h"
-#include <kernel.h>
-#include "socket_stub.h"
-
-void shellif_into();
-void shellif_outof();
-
-void __exp_analogin_init(analogin_t *obj, PinName pin)
-{
-	shellif_into();
-	analogin_init(obj, pin);
-	shellif_outof();
-}
-
-uint16_t __exp_analogin_read_u16(analogin_t *obj)
-{
-	uint16_t result;
-	shellif_into();
-	result = analogin_read_u16(obj);
-	shellif_outof();
-	return result;
-}
-
-void __exp_gpio_init(gpio_t *obj, PinName pin)
-{
-	shellif_into();
-	gpio_init(obj, pin);
-	shellif_outof();
-}
-
-void __exp_gpio_dir(gpio_t *obj, PinDirection direction)
-{
-	shellif_into();
-	gpio_dir(obj, direction);
-	shellif_outof();
-}
-
-int __exp_i2c_start(i2c_t *obj)
-{
-	int result;
-	shellif_into();
-	result = i2c_start(obj);
-	shellif_outof();
-	return result;
-}
-
-int __exp_i2c_stop(i2c_t *obj)
-{
-	int result;
-	shellif_into();
-	result = i2c_stop(obj);
-	shellif_outof();
-	return result;
-}
-
-void __exp_i2c_init(i2c_t *obj, PinName sda, PinName scl)
-{
-	shellif_into();
-	i2c_init(obj, sda, scl);
-	shellif_outof();
-}
-
-int __exp_i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
-{
-	int result;
-	shellif_into();
-	result = i2c_read(obj, address, data, length, stop);
-	shellif_outof();
-	return result;
-}
-
-int __exp_i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
-{
-	int result;
-	shellif_into();
-	result = i2c_write(obj, address, data, length, stop);
-	shellif_outof();
-	return result;
-}
-
-int __exp_i2c_byte_read(i2c_t *obj, int last)
-{
-	int result;
-	shellif_into();
-	result = i2c_byte_read(obj, last);
-	shellif_outof();
-	return result;
-}
-
-int __exp_i2c_byte_write(i2c_t *obj, int data)
-{
-	int result;
-	shellif_into();
-	result = i2c_byte_write(obj, data);
-	shellif_outof();
-	return result;
-}
-
-void __exp_pwmout_free(pwmout_t* obj)
-{
-	shellif_into();
-	pwmout_free(obj);
-	shellif_outof();
-}
-
-void __exp_pwmout_init(pwmout_t* obj, PinName pin)
-{
-	shellif_into();
-	pwmout_init(obj, pin);
-	shellif_outof();
-}
-
-void __exp_pwmout_pulsewidth_us(pwmout_t* obj, int us)
-{
-	shellif_into();
-	pwmout_pulsewidth_us(obj, us);
-	shellif_outof();
-}
-
-void __exp_rtc_init(void)
-{
-	shellif_into();
-	rtc_init();
-	shellif_outof();
-}
-
-void __exp_rtc_free(void)
-{
-	shellif_into();
-	rtc_free();
-	shellif_outof();
-}
-
-int __exp_rtc_isenabled(void)
-{
-	int result;
-	shellif_into();
-	result = rtc_isenabled();
-	shellif_outof();
-	return result;
-}
-
-time_t __exp_rtc_read(void)
-{
-	time_t result;
-	shellif_into();
-	result = rtc_read();
-	shellif_outof();
-	return result;
-}
-
-void __exp_rtc_write(time_t t)
-{
-	shellif_into();
-	rtc_write(t);
-	shellif_outof();
-}
-
-void __exp_serial_baud(serial_t *obj, int baudrate)
-{
-	shellif_into();
-	serial_baud(obj, baudrate);
-	shellif_outof();
-}
-
-void __exp_serial_init(serial_t *obj, PinName tx, PinName rx)
-{
-	shellif_into();
-	serial_init(obj, tx, rx);
-	shellif_outof();
-}
-
-int __exp_serial_readable(serial_t *obj)
-{
-	int result;
-	shellif_into();
-	result = serial_readable(obj);
-	shellif_outof();
-	return result;
-}
-
-int __exp_serial_getc(serial_t *obj)
-{
-	int result;
-	shellif_into();
-	result = serial_getc(obj);
-	shellif_outof();
-	return result;
-}
-
-void __exp_serial_putc(serial_t *obj, int c)
-{
-	shellif_into();
-	serial_putc(obj, c);
-	shellif_outof();
-}
-
-uint32_t __exp_us_ticker_read(void)
-{
-	int result;
-	shellif_into();
-	result = us_ticker_read();
-	shellif_outof();
-	return result;
-}
-
-void __exp_wait_ms(int ms)
-{
-	shellif_into();
-	wait_ms(ms);
-	shellif_outof();
-}
-
-bool __exp_SD_begin()
-{
-	bool result;
-	shellif_into();
-	result = SD_begin();
-	shellif_outof();
-	return result;
-}
-
-int __exp_usrcmd_cd(int argc, char **argv)
-{
-	int result;
-	shellif_into();
-	result = usrcmd_cd(argc, argv);
-	shellif_outof();
-	return result;
-}
-
-int __exp_usrcmd_ls(int argc, char **argv)
-{
-	int result;
-	shellif_into();
-	result = usrcmd_ls(argc, argv);
-	shellif_outof();
-	return result;
-}
-
-int __exp_usrcmd_cp(int argc, char **argv)
-{
-	int result;
-	shellif_into();
-	result = usrcmd_cp(argc, argv);
-	shellif_outof();
-	return result;
-}
-
-int __exp_usrcmd_rm(int argc, char **argv)
-{
-	int result;
-	shellif_into();
-	result = usrcmd_rm(argc, argv);
-	shellif_outof();
-	return result;
-}
-
-int __exp_usrcmd_mv(int argc, char **argv)
-{
-	int result;
-	shellif_into();
-	result = usrcmd_mv(argc, argv);
-	shellif_outof();
-	return result;
-}
-
-int __exp_usrcmd_mkdir(int argc, char **argv)
-{
-	int result;
-	shellif_into();
-	result = usrcmd_mkdir(argc, argv);
-	shellif_outof();
-	return result;
-}
-
-int __exp_usrcmd_hexdump(int argc, char **argv)
-{
-	int result;
-	shellif_into();
-	result = usrcmd_hexdump(argc, argv);
-	shellif_outof();
-	return result;
-}
-
-int __exp_usrcmd_info(int argc, char **argv)
-{
-	int result;
-	shellif_into();
-	result = usrcmd_info(argc, argv);
-	shellif_outof();
-	return result;
-}
-
-int __exp_usrcmd_exit(int argc, char **argv)
-{
-	int result;
-	shellif_into();
-	result = usrcmd_exit(argc, argv);
-	shellif_outof();
-	return result;
-}
-
-void __exp_shell_abort()
-{
-	shellif_into();
-	shell_abort();
-	shellif_outof();
-}
-
-void __exp_shell_exit(int exitcd)
-{
-	shellif_into();
-	shell_exit(exitcd);
-	shellif_outof();
-}
-
-int __exp_shell_kill(int pid, int sig)
-{
-	int result;
-	shellif_into();
-	result = shell_kill(pid, sig);
-	shellif_outof();
-	return result;
-}
-
-int __exp_shell_gettimeofday(struct timeval * tp, void * tzvp)
-{
-	int result;
-	shellif_into();
-	result = shell_gettimeofday(tp, tzvp);
-	shellif_outof();
-	return result;
-}
-
-void __exp_vsyslog(int priority, const char *format, va_list ap)
-{
-	shellif_into();
-	vsyslog(priority, format, ap);
-	shellif_outof();
-}
-
-int __exp_shell_open(const char * path, int flags)
-{
-	int result;
-	shellif_into();
-	result = shell_open(path, flags);
-	shellif_outof();
-	return result;
-}
-
-int __exp_shell_close(int fd)
-{
-	int result;
-	shellif_into();
-	result = shell_close(fd);
-	shellif_outof();
-	return result;
-}
-
-int __exp_shell_read(int fd, char *data, int len)
-{
-	int result;
-	shellif_into();
-	result = shell_read(fd, data, len);
-	shellif_outof();
-	return result;
-}
-
-int __exp_shell_write(int fd, char *data, int len)
-{
-	int result;
-	shellif_into();
-	result = shell_write(fd, data, len);
-	shellif_outof();
-	return result;
-}
-
-int __exp_shell_lseek(int fd, int ptr, int dir)
-{
-	int result;
-	shellif_into();
-	result = shell_lseek(fd, ptr, dir);
-	shellif_outof();
-	return result;
-}
-
-int __exp_shell_fstat(int fd, struct stat * st)
-{
-	int result;
-	shellif_into();
-	result = shell_fstat(fd, st);
-	shellif_outof();
-	return result;
-}
-
-int __exp_shell_stat(const char *fname, struct stat *st)
-{
-	int result;
-	shellif_into();
-	result = shell_stat(fname, st);
-	shellif_outof();
-	return result;
-}
-
-int __exp_shell_link(void)
-{
-	int result;
-	shellif_into();
-	result = shell_link();
-	shellif_outof();
-	return result;
-}
-
-int __exp_shell_unlink(const char *path)
-{
-	int result;
-	shellif_into();
-	result = shell_unlink(path);
-	shellif_outof();
-	return result;
-}
-
-int __exp_shell_isatty(int fd)
-{
-	int result;
-	shellif_into();
-	result = shell_isatty(fd);
-	shellif_outof();
-	return result;
-}
-
-int __exp_fsync(int fd)
-{
-	int result;
-	shellif_into();
-	result = fsync(fd);
-	shellif_outof();
-	return result;
-}
-
-int __exp_ftruncate(int fd, off_t length)
-{
-	int result;
-	shellif_into();
-	result = ftruncate(fd, length);
-	shellif_outof();
-	return result;
-}
-
-int __exp_ioctl(int fd, int request, va_list ap)
-{
-	int result;
-	shellif_into();
-	result = ioctl(fd, request, ap);
-	shellif_outof();
-	return result;
-}
-
-int __exp_tcgetattr(int fd, struct termios *termios_p)
-{
-	int result;
-	shellif_into();
-	result = tcgetattr(fd, termios_p);
-	shellif_outof();
-	return result;
-}
-
-int __exp_tcsetattr(int fd, int optional_actions, const struct termios *termios_p)
-{
-	int result;
-	shellif_into();
-	result = tcsetattr(fd, optional_actions, termios_p);
-	shellif_outof();
-	return result;
-}
-
-int __exp_shell_rename(const char *oldpath, const char *newpath)
-{
-	int result;
-	shellif_into();
-	result = shell_rename(oldpath, newpath);
-	shellif_outof();
-	return result;
-}
-
-int __exp_rmdir(const char *path)
-{
-	int result;
-	shellif_into();
-	result = rmdir(path);
-	shellif_outof();
-	return result;
-}
-
-int __exp_mkdir(const char *path, mode_t mode)
-{
-	int result;
-	shellif_into();
-	result = mkdir(path, mode);
-	shellif_outof();
-	return result;
-}
-
-int __exp_chmod(const char *path, mode_t mode)
-{
-	int result;
-	shellif_into();
-	result = chmod(path, mode);
-	shellif_outof();
-	return result;
-}
-
-char *__exp_getcwd(char *buf, size_t size)
-{
-	char *result;
-	shellif_into();
-	result = getcwd(buf, size);
-	shellif_outof();
-	return result;
-}
-
-int __exp_chdir(const char *path)
-{
-	int result;
-	shellif_into();
-	result = chdir(path);
-	shellif_outof();
-	return result;
-}
-
-int __exp_chroot(const char *path)
-{
-	int result;
-	shellif_into();
-	result = chroot(path);
-	shellif_outof();
-	return result;
-}
-
-int __exp_closedir(DIR *dir)
-{
-	int result;
-	shellif_into();
-	result = closedir(dir);
-	shellif_outof();
-	return result;
-}
-
-DIR *__exp_opendir(const char *path)
-{
-	DIR *result;
-	shellif_into();
-	result = opendir(path);
-	shellif_outof();
-	return result;
-}
-
-struct dirent *__exp_readdir(DIR *dir)
-{
-	struct dirent *result;
-	shellif_into();
-	result = readdir(dir);
-	shellif_outof();
-	return result;
-}
-
-void __exp_rewinddir(DIR *dir)
-{
-	shellif_into();
-	rewinddir(dir);
-	shellif_outof();
-}
-
-void __exp_seekdir(DIR *dir, long pos)
-{
-	shellif_into();
-	seekdir(dir, pos);
-	shellif_outof();
-}
-
-long __exp_telldir(DIR *dir)
-{
-	long result;
-	shellif_into();
-	result = telldir(dir);
-	shellif_outof();
-	return result;
-}
-
-int __exp_shell_getpid()
-{
-	int result;
-	shellif_into();
-	result = shell_getpid();
-	shellif_outof();
-	return result;
-}
-
-int __exp_socket(int family, int type, int protocol)
-{
-	int result;
-	shellif_into();
-	result = socket(family, type, protocol);
-	shellif_outof();
-	return result;
-}
-
-int __exp_bind(int fd, const struct sockaddr *addr, socklen_t len)
-{
-	int result;
-	shellif_into();
-	result = bind(fd, addr, len);
-	shellif_outof();
-	return result;
-}
-
-int __exp_listen(int fd, int backlog)
-{
-	int result;
-	shellif_into();
-	result = listen(fd, backlog);
-	shellif_outof();
-	return result;
-}
-
-int __exp_connect(int fd, const struct sockaddr *addr, socklen_t len)
-{
-	int result;
-	shellif_into();
-	result = connect(fd, addr, len);
-	shellif_outof();
-	return result;
-}
-
-int __exp_accept(int fd, struct sockaddr *addr, socklen_t *len)
-{
-	int result;
-	shellif_into();
-	result = accept(fd, addr, len);
-	shellif_outof();
-	return result;
-}
-
-ssize_t __exp_send(int fd, const void *buf, size_t len, int flags)
-{
-	ssize_t result;
-	shellif_into();
-	result = send(fd, buf, len, flags);
-	shellif_outof();
-	return result;
-}
-
-ssize_t __exp_sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t alen)
-{
-	ssize_t result;
-	shellif_into();
-	result = sendto(fd, buf, len, flags, addr, alen);
-	shellif_outof();
-	return result;
-}
-
-ssize_t __exp_recv(int fd, void *buf, size_t len, int flags)
-{
-	ssize_t result;
-	shellif_into();
-	result = recv(fd, buf, len, flags);
-	shellif_outof();
-	return result;
-}
-
-ssize_t __exp_recvfrom(int fd, void *buf, size_t len, int flags, struct sockaddr *addr, socklen_t *alen)
-{
-	ssize_t result;
-	shellif_into();
-	result = recvfrom(fd, buf, len, flags, addr, alen);
-	shellif_outof();
-	return result;
-}
-
-int __exp_shutdown(int fd, int how)
-{
-	int result;
-	shellif_into();
-	result = shutdown(fd, how);
-	shellif_outof();
-	return result;
-}
-
-int __exp_getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen)
-{
-	int result;
-	shellif_into();
-	result = getsockopt(fd, level, optname, optval, optlen);
-	shellif_outof();
-	return result;
-}
-
-int __exp_setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
-{
-	int result;
-	shellif_into();
-	result = setsockopt(fd, level, optname, optval, optlen);
-	shellif_outof();
-	return result;
-}
-
-int __exp_select(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv)
-{
-	int result;
-	shellif_into();
-	result = select(n, rfds, wfds, efds, tv);
-	shellif_outof();
-	return result;
-}
-
-int __exp_poll(struct pollfd *fds, nfds_t nfds, int timeout)
-{
-	int result;
-	shellif_into();
-	result = poll(fds, nfds, timeout);
-	shellif_outof();
-	return result;
-}
-
-int __exp_gethostname(char *name, size_t len)
-{
-	int result;
-	shellif_into();
-	result = gethostname(name, len);
-	shellif_outof();
-	return result;
-}
-
-int __exp_getnameinfo(const struct sockaddr *sa, socklen_t sl,
-	char *node, socklen_t nodelen,
-	char *serv, socklen_t servlen,
-	int flags)
-{
-	int result;
-	shellif_into();
-	shell_abort();
-	result = 0;
-	shellif_outof();
-	return result;
-}
-
-int __exp_getpeername(int fd, struct sockaddr *addr, socklen_t *len)
-{
-	int result;
-	shellif_into();
-	shell_abort();
-	result = 0;
-	shellif_outof();
-	return result;
-}
-
-int __exp_getsockname(int fd, struct sockaddr *addr, socklen_t *len)
-{
-	int result;
-	shellif_into();
-	shell_abort();
-	result = 0;
-	shellif_outof();
-	return result;
-}
-
-int __exp_socketpair(int family, int type, int protocol, int fd[2])
-{
-	int result;
-	shellif_into();
-	shell_abort();
-	result = 0;
-	shellif_outof();
-	return result;
-}
Index: EcnlProtoTool/trunk/ntshell/src/shellif.h
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/shellif.h	(revision 331)
+++ EcnlProtoTool/trunk/ntshell/src/shellif.h	(revision 331)
@@ -0,0 +1,249 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2017 Cores Co., Ltd. Japan
+ * 
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+ *  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+ *  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+ *      ã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+ *        å ±åãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+ *      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+ *      å
+è²¬ãããã¨ï¼
+ * 
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+ *  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+ *  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+ *  ã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+#ifndef SHELLIF_H
+#define SHELLIF_H
+
+#ifdef _MSC_VER
+#include <time.h>
+#endif
+
+#define __NEED_off_t
+#define __NEED_ssize_t
+#define __NEED_size_t
+#define __NEED_mode_t
+#define __NEED_dev_t
+#define __NEED_pid_t
+#define __NEED_gid_t
+#define __NEED_uid_t
+#define __NEED_socklen_t
+#define __NEED_nlink_t
+#define __NEED_blksize_t
+#define __NEED_blkcnt_t
+#define __NEED_ino_t
+#define __NEED_time_t
+#define __NEED_suseconds_t
+#define __NEED_struct_timeval
+#define __NEED_struct_timespec
+#define __NEED_struct_iovec
+#define __NEED_clockid_t
+#define __NEED_socklen_t
+#define __NEED_sa_family_t
+#define __NEED_sigset_t
+
+#include "../musl-1.1.18/include/bits/alltypes.h"
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 32
+
+#include "../musl-1.1.18/include/bits/fcntl.h"
+#include "../musl-1.1.18/include/bits/termios.h"
+#include "../musl-1.1.18/include/bits/stat.h"
+#include "../musl-1.1.18/include/sys/select.h"
+#ifndef _MSC_VER
+#include "../musl-1.1.18/include/time.h"
+#endif
+#include "../musl-1.1.18/include/signal.h"
+#include "../musl-1.1.18/include/stdio.h"
+#include "../musl-1.1.18/include/sys/utsname.h"
+#include "../musl-1.1.18/include/dirent.h"
+#include "../musl-1.1.18/include/bits/ioctl.h"
+#include "../musl-1.1.18/include/fcntl.h"
+#include "../musl-1.1.18/include/bits/errno.h"
+#include "../musl-1.1.18/include/sys/socket.h"
+
+#include <stddef.h>
+#include <stdarg.h>
+
+// time.h
+#define CLOCK_REALTIME 0
+
+// dirent.h
+typedef struct __dirstream DIR;
+
+int shell_getdents(int, struct dirent *, size_t);
+// pool.h
+typedef unsigned long nfds_t;
+
+struct pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+int shell_poll(struct pollfd *, nfds_t, int);
+
+#define POLLIN     0x001
+#define POLLOUT    0x004
+#define POLLERR    0x008
+
+// stropts.h
+int shell_ioctl(int, int, void *);
+// unistd.h
+#define STDIN_FILENO  0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+int shell_rmdir(const char *);
+int shell_ftruncate(int, off_t);
+int shell_chdir(const char *);
+char *shell_getcwd(char *, size_t);
+int shell_chroot(const char *);
+int shell_close(int);
+int shell_llseek(int, off_t, off_t *, int);
+int shell_fsync(int);
+ssize_t shell_read(int, void *, size_t);
+int shell_readv(int fd, const struct iovec *iov, int iovcnt);
+ssize_t shell_write(int, const void *, size_t);
+int shell_writev(int fd, const struct iovec *iov, int iovcnt);
+int shell_link(const char *, const char *);
+int shell_unlink(const char *);
+pid_t shell_getpid(void);
+int shell_access(const char *path, int mode);
+// signal.h
+int shell_sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict old);
+int shell_sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old);
+// socket.h
+int shell_socket(int, int, int);
+int shell_connect(int, const struct sockaddr *, socklen_t);
+ssize_t shell_send(int, const void *, size_t, int);
+ssize_t shell_sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t);
+ssize_t shell_sendmsg(int, const struct msghdr *, int);
+int shell_bind(int, const struct sockaddr *, socklen_t);
+int shell_listen(int, int);
+int shell_accept(int, struct sockaddr *__restrict, socklen_t *__restrict);
+ssize_t shell_recv(int, void *, size_t, int);
+ssize_t shell_recvfrom(int, void *__restrict, size_t, int, struct sockaddr *__restrict, socklen_t *__restrict);
+ssize_t shell_recvmsg(int, struct msghdr *, int);
+int shell_getsockopt(int, int, int, void *__restrict, socklen_t *__restrict);
+int shell_setsockopt(int, int, int, const void *, socklen_t);
+int shell_shutdown(int, int);
+// select.h
+int shell_select(int, fd_set *__restrict, fd_set *__restrict, fd_set *__restrict, struct timeval *__restrict);
+// syslog.h
+void vsyslog (int, const char *, va_list);
+// termios.h
+int sio_tcgetattr (int, struct termios *);
+int sio_tcsetattr(int, int, const struct termios *);
+// fcntl.h
+int shell_open(const char *, int, void *arg);
+int shell_fcntl(int fd, int cmd, void *arg);
+// stdio.h
+int shell_rename(const char *, const char *);
+// stat.h
+#define S_IFDIR 0040000
+#define S_IFCHR 0020000
+#define S_IFREG 0100000
+
+#define S_IRUSR 0400
+#define S_IWUSR 0200
+#define S_IRGRP 0040
+#define S_IWGRP 0020
+#define S_IROTH 0004
+#define S_IWOTH 0002
+
+int shell_chmod(const char *, mode_t);
+int shell_mkdir(const char *, mode_t);
+int shell_stat(const char *__restrict, struct stat *__restrict);
+int shell_fstat(int, struct stat *);
+int shell_lstat(const char *__restrict, struct stat *__restrict);
+
+int shell_clock_getres(clockid_t clk_id, struct timespec *res);
+int shell_clock_gettime(clockid_t clk_id, struct timespec *tp);
+int shell_clock_settime(clockid_t clk_id, const struct timespec *tp);
+int shell_gettimeofday(struct timeval *tp, void * tzvp);
+
+void shell_abort();
+void shell_exit(int exitcd);
+void shell_exit_group(int exitcd);
+int shell_kill(int pid, int sig);
+
+void *shell_brk(void *addr);
+void *shell_mmap2(void *start, size_t length, int prot, int flags, int fd, off_t pgoffset);
+// sys/mman.h
+int shell_mprotect(void *addr, size_t len, int prot);
+// TODO
+int shell_madvise(void *, size_t, int);
+int shell_uname(struct utsname *);
+// âââmusl
+
+// arduino.h
+int SD_begin();
+
+char *basename(char *);
+void shellif_into();
+void shellif_outof();
+
+struct regs_t {
+	long a;
+	long b;
+	long c;
+	long d;
+	long e;
+	long f;
+	long n;
+};
+
+void no_implement(const char *text);
+void __mbedcall_cp_asm();
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void Kernel_StartExternal(int argc, char **argv);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SHELLIF_H */
Index: EcnlProtoTool/trunk/ntshell/src/socket_stub.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/socket_stub.c	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/src/socket_stub.c	(revision 331)
@@ -35,26 +35,10 @@
  *  @(#) $Id$
  */
-#include <sys/types.h>
-#include <stdint.h>
-#if 0
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#endif
-#include <fcntl.h>
-#include "sys/unistd.h"
-#include <stddef.h>
-#include <string.h>
-#include <stdlib.h>
+#include "shellif.h"
 #include <kernel.h>
 #include <t_syslog.h>
 #include <t_stdlib.h>
+#include <string.h>
 #include <sil.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
 #include <setjmp.h>
 #include "syssvc/syslog.h"
@@ -74,5 +58,6 @@
 #include "ff.h"
 #include "socket_stub.h"
-#define SO_REUSEADDR    2
+
+#define SOCKET_TIMEOUT 2000000
 
 typedef struct id_table_t {
@@ -107,5 +92,5 @@
 }
 
-	return -1;
+	return -ENOMEM;
 }
 
@@ -120,10 +105,10 @@
 		return 0;
 	}
-	return -1;
+	return -EINVAL;
 }
 
 int delete_tcp_rep(int repid)
 {
-	delete_tcp_fd(tmax_tcp_cepid + repid);
+	return delete_tcp_fd(tmax_tcp_cepid + repid);
 }
 
@@ -145,7 +130,8 @@
 typedef struct _IO_FILE SOCKET;
 
-int socket(int family, int type, int protocol)
+int shell_socket(int family, int type, int protocol)
 {
 	SOCKET *fp;
+	unsigned int flags;
 
 	switch (family) {
@@ -154,6 +140,9 @@
 		break;
 	default:
-		return -1;
-	}
+		return -EAFNOSUPPORT;
+	}
+
+	flags = type & (SOCK_CLOEXEC|SOCK_NONBLOCK);
+	type &= ~flags;
 
 	switch (type) {
@@ -165,9 +154,9 @@
 		break;
 	default:
-		return -1;
+		return -ENOPROTOOPT;
 	}
 
 	if (fp == NULL) {
-		return -1;
+		return -ENOMEM;
 	}
 
@@ -175,18 +164,16 @@
 	fp->socket.type = type;
 	fp->socket.protocol = protocol;
+	fp->socket.flags = flags;
 
 	return fp->fd;
 }
 
-int bind(int fd, const struct sockaddr *addr, socklen_t len)
+int shell_bind(int fd, const struct sockaddr *addr, socklen_t len)
 {
 	SOCKET *fp = fd_to_fp(fd);
-	if (fp == NULL) {
-		return -1;
-	}
-
-	if (fp->socket.family != addr->sa_family) {
-		return -1;
-	}
+	if (fp == NULL)
+		return -EBADF;
+	if (fp->socket.family != addr->sa_family)
+		return -EINVAL;
 
 	ER ret;
@@ -194,5 +181,5 @@
 	case AF_INET: {
 		if (len < 8) {
-			return -1;
+			return -EINVAL;
 		}
 		struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
@@ -202,13 +189,13 @@
 			ID cepid = new_id(tcp_cepid_table, tcp_cepid_table_count);
 			if (cepid < 0)
-				return -1;
+				return -ENOMEM;
 
 			fp->socket.buf_size = 512 + 512;
 			fp->socket.buf = id_to_buff(cepid);
-			T_TCP_CCEP ccep = { 0, fp->socket.buf, 512, &fp->socket.buf[512], 512, socket_tcp_callback };
+			T_TCP_CCEP ccep = { 0, fp->socket.buf, 512, &fp->socket.buf[512], 512, (FP)socket_tcp_callback };
 			ret = tcp_cre_cep(cepid, &ccep);
 			if (ret != E_OK) {
 				delete_id(tcp_cepid_table, tcp_cepid_table_count, cepid);
-				return -1;
+				return -ENOMEM;
 			}
 			fp->handle = cepid;
@@ -219,11 +206,11 @@
 			ID cepid = new_id(udp_cepid_table, udp_cepid_table_count);
 			if (cepid < 0)
-				return -1;
-
-			T_UDP_CCEP ccep = { 0, {ntohl(addr_in->sin_addr.s_addr), ntohs(addr_in->sin_port)}, socket_udp_callback };
+				return -ENOMEM;
+
+			T_UDP_CCEP ccep = { 0, {ntohl(addr_in->sin_addr.s_addr), ntohs(addr_in->sin_port)}, (FP)socket_udp_callback };
 			ret = udp_cre_cep(cepid, &ccep);
 			if (ret != E_OK) {
 				delete_id(udp_cepid_table, udp_cepid_table_count, cepid);
-				return -1;
+				return -ENOMEM;
 			}
 			fp->handle = cepid;
@@ -232,5 +219,5 @@
 		}
 		default:
-			return -1;
+			return -ENOPROTOOPT;
 		}
 		break;
@@ -238,5 +225,5 @@
 	case AF_INET6: {
 		if (len < 20) {
-			return -1;
+			return -EINVAL;
 		}
 		memcpy(&fp->socket.laddr4, addr, len);
@@ -248,10 +235,11 @@
 }
 
-int listen(int fd, int backlog)
+int shell_listen(int fd, int backlog)
 {
 	SOCKET *fp = fd_to_fp(fd);
-	if ((fp == NULL) || (fp->socket.type != SOCK_STREAM)) {
-		return -1;
-	}
+	if (fp == NULL)
+		return -EBADF;
+	if (fp->socket.type != SOCK_STREAM)
+		return -EINVAL;
 
 	fp->socket.backlog = backlog;
@@ -262,5 +250,5 @@
 		ID repid = new_id(tcp_repid_table, tcp_repid_table_count);
 		if (repid < 0)
-			return -1;
+			return -ENOMEM;
 
 		struct sockaddr_in *laddr = &fp->socket.laddr4;
@@ -269,5 +257,5 @@
 		if (ret != E_OK) {
 			delete_id(tcp_repid_table, tcp_repid_table_count, repid);
-			return -1;
+			return -ENOMEM;
 		}
 		fp->socket.repid = repid;
@@ -282,10 +270,11 @@
 }
 
-int connect(int fd, const struct sockaddr *addr, socklen_t len)
+int shell_connect(int fd, const struct sockaddr *addr, socklen_t len)
 {
 	SOCKET *fp = fd_to_fp(fd);
-	if ((fp == NULL) || (fp->socket.type != SOCK_STREAM)) {
-		return -1;
-	}
+	if (fp == NULL)
+		return -EBADF;
+	if (fp->socket.type != SOCK_STREAM)
+		return -EINVAL;
 
 	ER ret;
@@ -293,18 +282,18 @@
 	case AF_INET: {
 		if (len < 8) {
-			return -1;
+			return -EINVAL;
 		}
 		if (fp->socket.cepid == 0) {
 			ID cepid = new_id(tcp_cepid_table, tcp_cepid_table_count);
 			if (cepid < 0)
-				return -1;
+				return -ENOMEM;
 
 			fp->socket.buf_size = 512 + 512;
 			fp->socket.buf = id_to_buff(cepid);
-			T_TCP_CCEP ccep = { 0, fp->socket.buf, 512, &fp->socket.buf[512], 512, socket_tcp_callback };
+			T_TCP_CCEP ccep = { 0, fp->socket.buf, 512, &fp->socket.buf[512], 512, (FP)socket_tcp_callback };
 			ret = tcp_cre_cep(cepid, &ccep);
 			if (ret != E_OK) {
 				delete_id(tcp_cepid_table, tcp_cepid_table_count, cepid);
-				return -1;
+				return -ENOMEM;
 			}
 			fp->handle = cepid;
@@ -317,7 +306,7 @@
 		T_IPV4EP lep = { ntohl(laddr->sin_addr.s_addr), ntohs(laddr->sin_port) };
 		T_IPV4EP rep = { ntohl(raddr->sin_addr.s_addr), ntohs(raddr->sin_port) };
-		ret = tcp_con_cep(fp->socket.cepid, &lep, &rep, TMO_FEVR);
+		ret = tcp_con_cep(fp->socket.cepid, &lep, &rep, SOCKET_TIMEOUT);
 		if (ret < 0) {
-			return -1;
+			return -EHOSTUNREACH;
 		}
 		break;
@@ -331,14 +320,15 @@
 }
 
-int accept(int fd, struct sockaddr *addr, socklen_t *len)
+int shell_accept(int fd, struct sockaddr *__restrict addr, socklen_t *__restrict len)
 {
 	SOCKET *lfp = fd_to_fp(fd);
-	if ((lfp == NULL) || (lfp->socket.type != SOCK_STREAM)) {
-		return -1;
-	}
+	if (lfp == NULL)
+		return -EBADF;
+	if (lfp->socket.type != SOCK_STREAM)
+		return -EINVAL;
 
 	SOCKET *fp = new_tcp_fd(0);
 	if (fp == NULL) {
-		return -1;
+		return -ENOMEM;
 	}
 
@@ -352,13 +342,13 @@
 			cepid = new_id(tcp_cepid_table, tcp_cepid_table_count);
 			if (cepid < 0)
-				return -1;
+				return -ENOMEM;
 
 			fp->socket.buf_size = 512 + 512;
 			fp->socket.buf = id_to_buff(cepid);
-			T_TCP_CCEP ccep = { 0, fp->socket.buf, 512, &fp->socket.buf[512], 512, socket_tcp_callback };
+			T_TCP_CCEP ccep = { 0, fp->socket.buf, 512, &fp->socket.buf[512], 512, (FP)socket_tcp_callback };
 			ret = tcp_cre_cep(cepid, &ccep);
 			if (ret != E_OK) {
 				delete_id(tcp_cepid_table, tcp_cepid_table_count, cepid);
-				return -1;
+				return -ENOMEM;
 			}
 			fp->handle = cepid;
@@ -375,5 +365,5 @@
 		ret = tcp_acp_cep(fp->socket.cepid, fp->socket.repid, &rep, TMO_FEVR);
 		if (ret < 0) {
-			return -1;
+			return -ENOMEM;
 		}
 		struct sockaddr_in *raddr = &fp->socket.raddr4;
@@ -385,5 +375,5 @@
 	}
 	case AF_INET6: {
-		break;
+		return -EAFNOSUPPORT;
 	}
 	}
@@ -392,5 +382,5 @@
 		int sz = *len;
 		if (sz < 8) {
-			return -1;
+			return -EINVAL;
 		}
 		struct sockaddr_in *raddr = &fp->socket.raddr4;
@@ -404,9 +394,9 @@
 }
 
-ssize_t send(int fd, const void *buf, size_t len, int flags)
+ssize_t shell_send(int fd, const void *buf, size_t len, int flags)
 {
 	SOCKET *fp = fd_to_fp(fd);
 	if (fp == NULL) {
-		return -1;
+		return -EBADF;
 	}
 
@@ -417,13 +407,13 @@
 		case SOCK_STREAM: {
 			if (flags & MSG_OOB) {
-				ret = tcp_snd_oob(fp->socket.cepid, (void *)buf, len, TMO_FEVR);
+				ret = tcp_snd_oob(fp->socket.cepid, (void *)buf, len, SOCKET_TIMEOUT);
 				if (ret < 0) {
-					return -1;
+					return -ECOMM;
 				}
 			}
 			else {
-				ret = tcp_snd_dat(fp->socket.cepid, (void *)buf, len, TMO_FEVR);
+				ret = tcp_snd_dat(fp->socket.cepid, (void *)buf, len, SOCKET_TIMEOUT);
 				if (ret < 0) {
-					return -1;
+					return -ECOMM;
 				}
 			}
@@ -431,11 +421,11 @@
 		}
 		case SOCK_DGRAM: {
-			return -1;
-		}
-		}
-		break;
-	}
-	case AF_INET6: {
-		break;
+			return -EINVAL;
+		}
+		}
+		break;
+	}
+	case AF_INET6: {
+		return -EAFNOSUPPORT;
 	}
 	}
@@ -444,9 +434,9 @@
 }
 
-ssize_t sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t alen)
+ssize_t shell_sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t alen)
 {
 	SOCKET *fp = fd_to_fp(fd);
 	if (fp == NULL) {
-		return -1;
+		return -EBADF;
 	}
 
@@ -457,17 +447,17 @@
 		case SOCK_STREAM: {
 			if ((addr != NULL) && (alen != 0)) {
-				return -1;
+				return -EINVAL;
 			}
 
 			if (flags & MSG_OOB) {
-				ret = tcp_snd_oob(fp->socket.cepid, (void *)buf, len, TMO_FEVR);
+				ret = tcp_snd_oob(fp->socket.cepid, (void *)buf, len, SOCKET_TIMEOUT);
 				if (ret < 0) {
-					return -1;
+					return -ECOMM;
 				}
 			}
 			else {
-				ret = tcp_snd_dat(fp->socket.cepid, (void *)buf, len, TMO_FEVR);
+				ret = tcp_snd_dat(fp->socket.cepid, (void *)buf, len, SOCKET_TIMEOUT);
 				if (ret < 0) {
-					return -1;
+					return -ECOMM;
 				}
 			}
@@ -477,5 +467,5 @@
 			int sz = alen;
 			if (sz < 8) {
-				return -1;
+				return -EINVAL;
 			}
 			struct sockaddr_in *raddr = &fp->socket.raddr4;
@@ -483,15 +473,16 @@
 			memcpy(raddr, addr, sz);
 			T_IPV4EP rep = { ntohl(raddr->sin_addr.s_addr), ntohs(raddr->sin_port) };
-			ret = udp_snd_dat(fp->socket.cepid, &rep, (void *)buf, len, TMO_FEVR);
+			ret = udp_snd_dat(fp->socket.cepid, &rep, (void *)buf, len,
+				(fp->socket.flags & O_NONBLOCK) ? 0 : SOCKET_TIMEOUT);
 			if (ret < 0) {
-				return -1;
-			}
-			break;
-		}
-		}
-		break;
-	}
-	case AF_INET6: {
-		break;
+				return -ECOMM;
+			}
+			break;
+		}
+		}
+		break;
+	}
+	case AF_INET6: {
+		return -EAFNOSUPPORT;
 	}
 	}
@@ -500,9 +491,15 @@
 }
 
-ssize_t recv(int fd, void *buf, size_t len, int flags)
+ssize_t shell_sendmsg(int fd, const struct msghdr *msg, int flags)
+{
+	no_implement("sendmsg\n");
+	return -ENOSYS;
+}
+
+ssize_t shell_recv(int fd, void *buf, size_t len, int flags)
 {
 	SOCKET *fp = fd_to_fp(fd);
 	if (fp == NULL) {
-		return -1;
+		return -EBADF;
 	}
 
@@ -515,5 +512,5 @@
 				ret = tcp_rcv_oob(fp->socket.cepid, buf, len);
 				if (ret < 0) {
-					return -1;
+					return -ECOMM;
 				}
 			}
@@ -521,5 +518,5 @@
 				ret = tcp_rcv_dat(fp->socket.cepid, buf, len, TMO_FEVR);
 				if (ret < 0) {
-					return -1;
+					return -ECOMM;
 				}
 			}
@@ -528,14 +525,14 @@
 		case SOCK_DGRAM: {
 			T_IPV4EP rep = { 0, 0 };
-			ret = udp_rcv_dat(fp->socket.cepid, &rep, buf, len, TMO_FEVR);
+			ret = udp_rcv_dat(fp->socket.cepid, &rep, buf, len, (fp->socket.flags & O_NONBLOCK) ? 0 : TMO_FEVR);
 			if (ret < 0) {
-				return -1;
-			}
-		}
-		}
-		break;
-	}
-	case AF_INET6: {
-		break;
+				return -ECOMM;
+			}
+		}
+		}
+		break;
+	}
+	case AF_INET6: {
+		return -EAFNOSUPPORT;
 	}
 	}
@@ -544,9 +541,9 @@
 }
 
-ssize_t recvfrom(int fd, void *buf, size_t len, int flags, struct sockaddr *addr, socklen_t *alen)
+ssize_t shell_recvfrom(int fd, void *buf, size_t len, int flags, struct sockaddr *__restrict addr, socklen_t *__restrict alen)
 {
 	SOCKET *fp = fd_to_fp(fd);
 	if (fp == NULL) {
-		return -1;
+		return -EBADF;
 	}
 
@@ -559,5 +556,5 @@
 				ret = tcp_rcv_oob(fp->socket.cepid, buf, len);
 				if (ret < 0) {
-					return -1;
+					return -ECOMM;
 				}
 			}
@@ -565,5 +562,5 @@
 				ret = tcp_rcv_dat(fp->socket.cepid, buf, len, TMO_FEVR);
 				if (ret < 0) {
-					return -1;
+					return -ECOMM;
 				}
 			}
@@ -574,5 +571,5 @@
 			ret = udp_rcv_dat(fp->socket.cepid, &rep, buf, len, TMO_FEVR);
 			if (ret < 0) {
-				return -1;
+				return -ECOMM;
 			}
 			int sz = *alen;
@@ -590,5 +587,5 @@
 	}
 	case AF_INET6: {
-		break;
+		return -EAFNOSUPPORT;
 	}
 	}
@@ -597,9 +594,15 @@
 }
 
-int shutdown(int fd, int how)
+ssize_t shell_recvmsg(int fd, struct msghdr *msg, int flags)
+{
+	no_implement("recvmsg\n");
+	return -ENOSYS;
+}
+
+int shell_shutdown(int fd, int how)
 {
 	SOCKET *fp = fd_to_fp(fd);
 	if (fp == NULL) {
-		return -1;
+		return -EBADF;
 	}
 
@@ -611,13 +614,13 @@
 			ret = tcp_sht_cep(fp->socket.cepid);
 			if (ret < 0) {
-				return -1;
-			}
-			break;
-		}
-		}
-		break;
-	}
-	case AF_INET6: {
-		break;
+				return -ECOMM;
+			}
+			break;
+		}
+		}
+		break;
+	}
+	case AF_INET6: {
+		return -EAFNOSUPPORT;
 	}
 	}
@@ -626,9 +629,9 @@
 }
 
-int getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen)
+int shell_getsockopt(int fd, int level, int optname, void *optval, socklen_t *__restrict optlen)
 {
 	SOCKET *fp = fd_to_fp(fd);
 	if (fp == NULL) {
-		return -1;
+		return -EBADF;
 	}
 
@@ -650,5 +653,5 @@
 				ret = tcp_get_opt(fp->socket.cepid, optname, (void *)optval, *optlen);
 				if (ret < 0) {
-					return -1;
+					return -EINVAL;
 				}
 				*optlen = ret;
@@ -660,5 +663,5 @@
 			ret = udp_get_opt(fp->socket.cepid, optname, (void *)optval, *optlen);
 			if (ret < 0) {
-				return -1;
+				return -EINVAL;
 			}
 			*optlen = ret;
@@ -669,5 +672,5 @@
 	}
 	case AF_INET6: {
-		break;
+		return -EAFNOSUPPORT;
 	}
 	}
@@ -676,9 +679,9 @@
 }
 
-int setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
+int shell_setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
 {
 	SOCKET *fp = fd_to_fp(fd);
 	if (fp == NULL) {
-		return -1;
+		return -EBADF;
 	}
 
@@ -700,5 +703,5 @@
 				ret = tcp_set_opt(fp->socket.cepid, optname, (void *)optval, optlen);
 				if (ret < 0) {
-					return -1;
+					return -EINVAL;
 				}
 				break;
@@ -709,13 +712,13 @@
 			ret = udp_set_opt(fp->socket.cepid, optname, (void *)optval, optlen);
 			if (ret < 0) {
-				return -1;
-			}
-			break;
-		}
-		}
-		break;
-	}
-	case AF_INET6: {
-		break;
+				return -EINVAL;
+			}
+			break;
+		}
+		}
+		break;
+	}
+	case AF_INET6: {
+		return -EAFNOSUPPORT;
 	}
 	}
@@ -735,5 +738,5 @@
 				//return -1;
 			}
-			ret = tcp_cls_cep(cepid, TMO_FEVR);
+			ret = tcp_cls_cep(cepid, (fp->socket.repid != 0) ? 0 : SOCKET_TIMEOUT);
 			if (ret < 0) {
 				//return -1;
@@ -743,5 +746,5 @@
 			delete_id(tcp_cepid_table, tcp_cepid_table_count, cepid);
 			if (ret < 0) {
-				return -1;
+				return -EINVAL;
 			}
 		}
@@ -752,14 +755,14 @@
 			delete_id(tcp_repid_table, tcp_repid_table_count, repid);
 			if (ret < 0) {
-				return -1;
+				return -EINVAL;
 			}
 		}
 		else {
-			return -1;
-		}
-		break;
-	}
-	case AF_INET6: {
-		break;
+			return -EINVAL;
+		}
+		break;
+	}
+	case AF_INET6: {
+		return -EAFNOSUPPORT;
 	}
 	}
@@ -770,15 +773,20 @@
 size_t tcp_fd_read(struct _IO_FILE *fp, unsigned char *dst, size_t dstsz)
 {
-	return recv(fp->fd, dst, dstsz, 0);
+	return shell_recv(fp->fd, dst, dstsz, 0);
 }
 
 size_t tcp_fd_write(struct _IO_FILE *fp, const unsigned char *src, size_t srcsz)
 {
-	return send(fp->fd, src, srcsz, 0);
+	return shell_send(fp->fd, src, srcsz, 0);
 }
 
 off_t tcp_fd_seek(struct _IO_FILE *fp, off_t ofs, int org)
 {
-	return -1;
+	return -EPERM;
+}
+
+int tcp_fd_ioctl(struct _IO_FILE *fp, int req, void *arg)
+{
+	return -EINVAL;
 }
 
@@ -794,10 +802,10 @@
 		delete_id(udp_cepid_table, udp_cepid_table_count, cepid);
 		if (ret < 0) {
-			return -1;
-		}
-		break;
-	}
-	case AF_INET6: {
-		break;
+			return -EINVAL;
+		}
+		break;
+	}
+	case AF_INET6: {
+		return -EAFNOSUPPORT;
 	}
 	}
@@ -808,15 +816,20 @@
 size_t udp_fd_read(struct _IO_FILE *fp, unsigned char *dst, size_t dstsz)
 {
-	return recv(fp->fd, dst, dstsz, 0);
+	return shell_recv(fp->fd, dst, dstsz, 0);
 }
 
 size_t udp_fd_write(struct _IO_FILE *fp, const unsigned char *src, size_t srcsz)
 {
-	return send(fp->fd, src, srcsz, 0);
+	return shell_send(fp->fd, src, srcsz, 0);
 }
 
 off_t udp_fd_seek(struct _IO_FILE *fp, off_t ofs, int org)
 {
-	return -1;
+	return -EPERM;
+}
+
+int udp_fd_ioctl(struct _IO_FILE *fp, int req, void *arg)
+{
+	return -EINVAL;
 }
 
Index: EcnlProtoTool/trunk/ntshell/src/socket_stub.h
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/socket_stub.h	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/src/socket_stub.h	(revision 331)
@@ -38,12 +38,4 @@
 #define SOCKET_STUB_H
 
-typedef unsigned socklen_t;
-typedef unsigned short sa_family_t;
-
-struct sockaddr {
-	sa_family_t sa_family;
-	char sa_data[14];
-};
-
 struct addrinfo {
 	int ai_flags;
@@ -57,10 +49,4 @@
 };
 
-#define AF_INET		2
-#define AF_INET6	10
-
-#define SOCK_STREAM	1
-#define SOCK_DGRAM	2
-
 typedef uint16_t in_port_t;
 typedef uint32_t in_addr_t;
@@ -82,7 +68,7 @@
 	} __in6_union;
 };
-#define s6_addr __in6_union.__s6_addr
-#define s6_addr16 __in6_union.__s6_addr16
-#define s6_addr32 __in6_union.__s6_addr32
+//#define s6_addr __in6_union.__s6_addr
+//#define s6_addr16 __in6_union.__s6_addr16
+//#define s6_addr32 __in6_union.__s6_addr32
 
 struct sockaddr_in6
@@ -94,6 +80,4 @@
 	uint32_t        sin6_scope_id;
 };
-
-#define MSG_OOB       0x0001
 
 typedef struct socket_t {
@@ -124,4 +108,6 @@
 	size_t (*read)(struct _IO_FILE *, unsigned char *, size_t);
 	size_t (*write)(struct _IO_FILE *, const unsigned char *, size_t);
+	off_t (*seek)(struct _IO_FILE *, off_t, int);
+	int (*ioctl)(struct _IO_FILE *, int, void *);
 	int readevt_r;
 	int readevt_w;
@@ -132,4 +118,8 @@
 	union {
 		FIL file;
+		struct {
+			DIR dir;
+			struct dirent dirent;
+		};
 		socket_t socket;
 	};
@@ -156,16 +146,30 @@
 extern size_t sio_read(struct _IO_FILE *fp, unsigned char *data, size_t len);
 extern size_t sio_write(struct _IO_FILE *fp, const unsigned char *data, size_t len);
+extern off_t sio_seek(struct _IO_FILE *fp, off_t ofs, int org);
+extern int sio_ioctl(struct _IO_FILE *fp, int req, void *arg);
 
 extern int file_close(struct _IO_FILE *fp);
 extern size_t file_read(struct _IO_FILE *fp, unsigned char *data, size_t len);
 extern size_t file_write(struct _IO_FILE *fp, const unsigned char *data, size_t len);
+extern off_t file_seek(struct _IO_FILE *fp, off_t ofs, int org);
+extern int file_ioctl(struct _IO_FILE *fp, int req, void *arg);
+
+extern int dir_close(struct _IO_FILE *fp);
+extern size_t dir_read(struct _IO_FILE *fp, unsigned char *data, size_t len);
+extern size_t dir_write(struct _IO_FILE *fp, const unsigned char *data, size_t len);
+extern off_t dir_seek(struct _IO_FILE *fp, off_t ofs, int org);
+extern int dir_ioctl(struct _IO_FILE *fp, int req, void *arg);
 
 extern int tcp_fd_close(struct _IO_FILE *fp);
 extern size_t tcp_fd_read(struct _IO_FILE *fp, unsigned char *data, size_t len);
 extern size_t tcp_fd_write(struct _IO_FILE *fp, const unsigned char *data, size_t len);
+extern off_t tcp_fd_seek(struct _IO_FILE *fp, off_t ofs, int org);
+extern int tcp_fd_ioctl(struct _IO_FILE *fp, int req, void *arg);
 
 extern int udp_fd_close(struct _IO_FILE *fp);
 extern size_t udp_fd_read(struct _IO_FILE *fp, unsigned char *data, size_t len);
 extern size_t udp_fd_write(struct _IO_FILE *fp, const unsigned char *data, size_t len);
+extern off_t udp_fd_seek(struct _IO_FILE *fp, off_t ofs, int org);
+extern int udp_fd_ioctl(struct _IO_FILE *fp, int req, void *arg);
 
 struct _IO_FILE *fd_to_fp(int fd);
@@ -179,4 +183,8 @@
 struct _IO_FILE *fileid_to_fd(int fileid);
 
+struct _IO_FILE *new_dir_fd(int dirid);
+int delete_dir_fd(int dirid);
+struct _IO_FILE *dirid_to_fd(int dirid);
+
 struct _IO_FILE *new_tcp_fd(int tcpid);
 int delete_tcp_fd(int tcpid);
Index: EcnlProtoTool/trunk/ntshell/src/syscall.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/syscall.c	(revision 331)
+++ EcnlProtoTool/trunk/ntshell/src/syscall.c	(revision 331)
@@ -0,0 +1,977 @@
+/*
+ *  TOPPERS ECHONET Lite Communication Middleware
+ * 
+ *  Copyright (C) 2017 Cores Co., Ltd. Japan
+ * 
+ *  ä¸è¨èä½æ¨©è
+ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
+ *  ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ãä½¿ç¨ã»è¤è£½ã»æ¹
+ *  å¤ã»åé
+å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
+ *  (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
+ *      æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
+ *      ã¹ã³ã¼ãä¸­ã«å«ã¾ãã¦ãããã¨ï¼
+ *  (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨
+ *      è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
+ *      ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *  (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
+ *      ç¨ã§ããªãå½¢ã§åé
+å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
+ *      ã¨ï¼
+ *    (a) åé
+å¸ã«ä¼´ããã­ã¥ã¡ã³ãï¼å©ç¨è
+ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
+ *        ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
+ *    (b) åé
+å¸ã®å½¢æ
+ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSãã­ã¸ã§ã¯ãã«
+ *        å ±åãããã¨ï¼
+ *  (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
+ *      å®³ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ããå
+è²¬ãããã¨ï¼
+ *      ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
+ *      ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
+ããã³TOPPERSãã­ã¸ã§ã¯ãã
+ *      å
+è²¬ãããã¨ï¼
+ * 
+ *  æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
+ã
+ *  ãã³TOPPERSãã­ã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
+ *  ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
+ *  ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæå®³ã«é¢ãã¦ãï¼ã
+ *  ã®è²¬ä»»ãè² ããªãï¼
+ * 
+ *  @(#) $Id$
+ */
+#define _CRT_NO_TIME_T
+#include "../../musl-1.1.18/include/bits/syscall.h"
+#include "shellif.h"
+#include <t_syslog.h>
+#include "MBRZA1H.h"
+
+void *thread_area;
+void *tid_address;
+
+// https://os.mbed.com/users/dkato/code/FlashAccess/#652a093cf264
+void flash_access_cache_control(void) {
+    unsigned int assoc;
+
+    /* ==== Cleaning and invalidation of the L1 data cache ==== */
+    __v7_all_cache(2);
+    __DSB();
+
+    /* ==== Cleaning and invalidation of the L2 cache ==== */
+    if (PL310->AUX_CNT & (1<<16)) {
+        assoc = 16;
+    } else {
+        assoc =  8;
+    }
+    PL310->INV_WAY = (1 << assoc) - 1;
+    while(PL310->INV_WAY & ((1 << assoc) - 1)); // poll invalidate
+    PL310->CACHE_SYNC = 0x0;
+
+    /* ==== Invalidate all TLB entries ==== */
+    __ca9u_inv_tlb_all();
+
+    /* ==== Invalidate the L1 instruction cache ==== */
+    __v7_inv_icache_all();
+    __DSB();
+    __ISB();
+}
+
+void no_implement(const char *text)
+{
+	syslog(LOG_ERROR, text);
+	asm("bkpt #0");
+}
+
+static long __syscall(struct regs_t *r)
+{
+	long ret = -ENOSYS;
+
+	shellif_into();
+
+	switch (r->n) {
+	case SYS__llseek:
+		return shell_llseek(r->a, (((off_t)r->b) << 32) + (off_t)r->c, (off_t *)r->d, r->e);
+	case SYS__newselect:
+		ret = shell_select(r->a, (fd_set *)r->b, (fd_set *)r->c, (fd_set *)r->d, (struct timeval *)r->e);
+		break;
+	case SYS_accept:
+		ret = shell_accept(r->a, (struct sockaddr *)r->b, (socklen_t *)r->c);
+		break;
+	case SYS_access:
+		ret = shell_access((const char *)r->a, r->b);
+		break;
+	case SYS_acct:
+		no_implement("acct\n");
+		break;
+	case SYS_adjtimex:
+		no_implement("adjtimex\n");
+		break;
+#ifdef SYS_arch_prctl
+	case SYS_arch_prctl:
+		no_implement("arch_prctl\n");
+		break;
+#endif
+	case SYS_bind:
+		ret = shell_bind(r->a, (const struct sockaddr *)r->b, (socklen_t)r->c);
+		break;
+	case SYS_brk:
+		ret = (long)shell_brk((void *)r->a);
+		break;
+#ifdef SYS_cachectl
+	case SYS_cachectl:
+		no_implement("cachectl\n");
+		break;
+#endif
+#ifdef SYS_cacheflush
+	case SYS_cacheflush:
+		no_implement("cacheflush\n");
+		break;
+#endif
+	case SYS_capget:
+		no_implement("capget\n");
+		break;
+	case SYS_capset:
+		no_implement("capset\n");
+		break;
+	case SYS_chdir:
+		ret = shell_chdir((const char *)r->a);
+		break;
+	case SYS_chmod:
+		ret = shell_chmod((const char *)r->a, (mode_t)r->b);
+		break;
+	case SYS_chown32:
+		no_implement("chown\n");
+		break;
+	case SYS_chroot:
+		ret = shell_chroot((const char *)r->a);
+		break;
+	case SYS_clock_adjtime:
+		no_implement("clock_adjtime\n");
+		break;
+	case SYS_clock_getres:
+		ret = shell_clock_getres((clockid_t)r->a, (struct timespec *)r->b);
+		break;
+	case SYS_clock_gettime:
+		ret = shell_clock_gettime((clockid_t)r->a, (struct timespec *)r->b);
+		break;
+	case SYS_clock_nanosleep:
+		no_implement("clock_nanosleep\n");
+		break;
+	case SYS_clock_settime:
+		ret = shell_clock_settime((clockid_t)r->a, (const struct timespec *)r->b);
+		break;
+	case SYS_clone:
+		no_implement("clone\n");
+		break;
+	case SYS_close:
+		ret = shell_close(r->a);
+		break;
+	case SYS_connect:
+		ret = shell_connect(r->a, (const struct sockaddr *)r->b, (socklen_t)r->c);
+		break;
+	case SYS_delete_module:
+		no_implement("delete_module\n");
+		break;
+	case SYS_dup:
+		no_implement("dup\n");
+		break;
+	case SYS_dup2:
+		no_implement("dup2\n");
+		break;
+	case SYS_dup3:
+		no_implement("dup3\n");
+		break;
+	case SYS_epoll_create:
+		no_implement("epoll_create\n");
+		break;
+	case SYS_epoll_create1:
+		no_implement("epoll_create1\n");
+		break;
+	case SYS_epoll_ctl:
+		no_implement("epoll_ctl\n");
+		break;
+	case SYS_epoll_pwait:
+		no_implement("epoll_pwait\n");
+		break;
+	case SYS_epoll_wait:
+		no_implement("epoll_wait\n");
+		break;
+	case SYS_eventfd:
+		no_implement("eventfd\n");
+		break;
+	case SYS_eventfd2:
+		no_implement("eventfd2\n");
+		break;
+	case SYS_execve:
+		no_implement("execve\n");
+		break;
+	case SYS_exit:
+		shell_exit(r->a);
+		ret = 0;
+		break;
+	case SYS_exit_group:
+		shell_exit_group(r->a);
+		ret = 0;
+		break;
+	case SYS_faccessat:
+		no_implement("faccessat\n");
+		break;
+	case SYS_fadvise64_64:
+		no_implement("fadvise64_64\n");
+		break;
+	case SYS_fallocate:
+		no_implement("fallocate\n");
+		break;
+	case SYS_fanotify_init:
+		no_implement("fanotify_init\n");
+		break;
+	case SYS_fanotify_mark:
+		no_implement("fanotify_mark\n");
+		break;
+	case SYS_fchdir:
+		no_implement("fchdir\n");
+		break;
+	case SYS_fchmod:
+		no_implement("fchmod\n");
+		break;
+	case SYS_fchmodat:
+		no_implement("fchmodat\n");
+		break;
+	case SYS_fchown32:
+		no_implement("fchown\n");
+		break;
+	case SYS_fchownat:
+		no_implement("fchownat\n");
+		break;
+	case SYS_fcntl64:
+		ret = shell_fcntl((int)r->a, (int)r->b, (void *)r->c);
+		break;
+	case SYS_fdatasync:
+		no_implement("fdatasync\n");
+		break;
+	case SYS_fgetxattr:
+		no_implement("fgetxattr\n");
+		break;
+	case SYS_flistxattr:
+		no_implement("flistxattr\n");
+		break;
+	case SYS_flock:
+		no_implement("flock\n");
+		break;
+	case SYS_fork:
+		no_implement("fork\n");
+		break;
+	case SYS_fremovexattr:
+		no_implement("fremovexattr\n");
+		break;
+	case SYS_fsetxattr:
+		no_implement("fsetxattr\n");
+		break;
+	case SYS_fstat64:
+		ret = shell_fstat((int)r->a, (struct stat *)r->b);
+		break;
+	case SYS_fstatat64:
+		no_implement("fstatat64\n");
+		break;
+	case SYS_fstatfs:
+		no_implement("fstatfs\n");
+		break;
+	case SYS_fstatfs64:
+		no_implement("fstatfs64\n");
+		break;
+	case SYS_fsync:
+		ret = shell_fsync(r->a);
+		break;
+	case SYS_ftruncate64:
+		ret = shell_ftruncate((int)r->a, (((off_t)r->b) << 32) + (off_t)r->c);
+		break;
+	case SYS_futex:
+		no_implement("futex\n");
+		break;
+	case SYS_futimesat:
+		no_implement("futimesat\n");
+		break;
+	case SYS_getcpu:
+		no_implement("getcpu\n");
+		break;
+	case SYS_getcwd:
+		ret = (long)shell_getcwd((char *)r->a, (size_t)r->b);
+		break;
+	case SYS_getdents64:
+		ret = shell_getdents((int)r->a, (struct dirent *)r->b, (size_t)r->c);	// TODO
+		break;
+	case SYS_getegid32:
+		no_implement("getegid\n");
+		break;
+	case SYS_geteuid32:
+		no_implement("geteuid\n");
+		break;
+	case SYS_getgid32:
+		no_implement("getgid\n");
+		break;
+	case SYS_getgroups32:
+		no_implement("getgroups\n");
+		break;
+	case SYS_getitimer:
+		no_implement("getitimer\n");
+		break;
+	case SYS_getpgid:
+		no_implement("getpgid\n");
+		break;
+	case SYS_getpid:
+		ret = shell_getpid();
+		break;
+	case SYS_getppid:
+		no_implement("getppid\n");
+		break;
+	case SYS_getpriority:
+		no_implement("getpriority\n");
+		break;
+	case SYS_getresgid32:
+		no_implement("getresgid\n");
+		break;
+	case SYS_getresuid32:
+		no_implement("getresuid\n");
+		break;
+#ifdef SYS_getrlimit
+	case SYS_getrlimit:
+		no_implement("getrlimit\n");
+		break;
+#endif
+	case SYS_getrusage:
+		no_implement("getrusage\n");
+		break;
+	case SYS_getsid:
+		no_implement("getsid\n");
+		break;
+	case SYS_getsockopt:
+		ret = shell_getsockopt(r->a, r->b, r->c, (void *)r->d, (socklen_t *)r->e);
+		break;
+	case SYS_gettid:
+		no_implement("gettid\n");
+		break;
+	case SYS_gettimeofday:
+		ret = shell_gettimeofday((struct timeval *)r->a, (void *)r->b);
+		break;
+	case SYS_getuid32:
+		no_implement("getuid\n");
+		break;
+	case SYS_getxattr:
+		no_implement("getxattr\n");
+		break;
+	case SYS_init_module:
+		no_implement("init_module\n");
+		break;
+	case SYS_inotify_add_watch:
+		no_implement("inotify_add_watch\n");
+		break;
+	case SYS_inotify_init:
+		no_implement("inotify_init\n");
+		break;
+	case SYS_inotify_init1:
+		no_implement("inotify_init1\n");
+		break;
+	case SYS_inotify_rm_watch:
+		no_implement("inotify_rm_watch\n");
+		break;
+	case SYS_ioctl:
+		ret = shell_ioctl((int)r->a, (int)r->b, (void *)r->c);
+		break;
+#ifdef SYS_ioperm
+	case SYS_ioperm:
+		no_implement("ioperm\n");
+		break;
+#endif
+#ifdef SYS_iopl
+	case SYS_iopl:
+		no_implement("iopl\n");
+		break;
+#endif
+#ifdef SYS_ipc
+	case SYS_ipc:
+		no_implement("ipc\n");
+		break;
+#endif
+#ifdef SYS_ipc
+	case SYS_ipc:
+		no_implement("ipc\n");
+		break;
+#endif
+	case SYS_kill:
+		ret = shell_kill(r->a, r->b);
+		break;
+	case SYS_lchown32:
+		no_implement("lchown\n");
+		break;
+	case SYS_lgetxattr:
+		no_implement("lgetxattr\n");
+		break;
+	case SYS_link:
+		ret = shell_link((const char *)r->a, (const char *)r->b);
+		break;
+	case SYS_linkat:
+		no_implement("linkat\n");
+		break;
+	case SYS_listen:
+		ret = shell_listen(r->a, r->b);
+		break;
+	case SYS_listxattr:
+		no_implement("listxattr\n");
+		break;
+	case SYS_llistxattr:
+		no_implement("llistxattr\n");
+		break;
+	case SYS_lremovexattr:
+		no_implement("lremovexattr\n");
+		break;
+	case SYS_lsetxattr:
+		no_implement("lsetxattr\n");
+		break;
+	case SYS_lstat64:
+		ret = shell_lstat((const char *__restrict)r->a, (struct stat *__restrict)r->b);
+		break;
+	case SYS_madvise:
+		ret = shell_madvise((void *)r->a, (size_t)r->b, (int)r->c);	// TODO
+		break;
+	case SYS_mincore:
+		no_implement("mincore\n");
+		break;
+	case SYS_mkdir:
+		ret = shell_mkdir((const char *)r->a, (mode_t)r->b);
+		break;
+	case SYS_mkdirat:
+		no_implement("mkdirat\n");
+		break;
+	case SYS_mknod:
+		no_implement("mknod\n");
+		break;
+	case SYS_mknodat:
+		no_implement("mknodat\n");
+		break;
+	case SYS_mlock:
+		no_implement("mlock\n");
+		break;
+	case SYS_mlockall:
+		no_implement("mlockall\n");
+		break;
+	case SYS_mmap2:
+		ret = (int)shell_mmap2((void *)r->a, (size_t)r->b, r->c, r->d, r->e, (off_t)r->f);
+		break;
+	case SYS_mount:
+		no_implement("mount\n");
+		break;
+	case SYS_mprotect:
+		return shell_mprotect((void *)r->a, (size_t)r->b, r->c);
+		break;
+	case SYS_mq_getsetattr:
+		no_implement("mq_getsetattr\n");
+		break;
+	case SYS_mq_notify:
+		no_implement("mq_notify\n");
+		break;
+	case SYS_mq_open:
+		no_implement("mq_open\n");
+		break;
+	case SYS_mq_timedreceive:
+		no_implement("mq_timedreceive\n");
+		break;
+	case SYS_mq_timedsend:
+		no_implement("mq_timedsend\n");
+		break;
+	case SYS_mq_unlink:
+		no_implement("mq_unlink\n");
+		break;
+	case SYS_mremap:
+		no_implement("mremap\n");
+		break;
+	case SYS_msgctl:
+		no_implement("msgctl\n");
+		break;
+	case SYS_msgget:
+		no_implement("msgget\n");
+		break;
+	case SYS_msgrcv:
+		no_implement("msgrcv\n");
+		break;
+	case SYS_msgsnd:
+		no_implement("msgsnd\n");
+		break;
+	case SYS_msync:
+		no_implement("msync\n");
+		break;
+	case SYS_munlock:
+		no_implement("munlock\n");
+		break;
+	case SYS_munlockall:
+		no_implement("munlockall\n");
+		break;
+	case SYS_munmap:
+		no_implement("munmap\n");
+		break;
+	case SYS_nanosleep:
+		no_implement("nanosleep\n");
+		break;
+	case SYS_nice:
+		no_implement("nice\n");
+		break;
+	case SYS_open:
+		ret = shell_open((const char *)r->a, (int)r->b, (void *)r->c);
+		break;
+	case SYS_openat:
+		no_implement("openat\n");
+		break;
+	case SYS_pause:
+		no_implement("pause\n");
+		break;
+	case SYS_personality:
+		no_implement("personality\n");
+		break;
+	case SYS_pipe:
+		no_implement("pipe\n");
+		break;
+	case SYS_pipe2:
+		no_implement("pipe2\n");
+		break;
+	case SYS_pivot_root:
+		no_implement("pivot_root\n");
+		break;
+	case SYS_poll:
+		ret = shell_poll((struct pollfd *)r->a, (nfds_t)r->b, (int)r->c);
+		break;
+	case SYS_ppoll:
+		no_implement("ppoll\n");
+		break;
+	case SYS_prctl:
+		no_implement("prctl\n");
+		break;
+	case SYS_pread64:
+		no_implement("pread64\n");
+		break;
+	case SYS_preadv:
+		no_implement("preadv\n");
+		break;
+	case SYS_prlimit64:
+		no_implement("prlimit64\n");
+		break;
+	case SYS_process_vm_readv:
+		no_implement("process_vm_readv\n");
+		break;
+	case SYS_process_vm_writev:
+		no_implement("process_vm_writev\n");
+		break;
+	case SYS_pselect6:
+		no_implement("pselect6\n");
+		break;
+	case SYS_ptrace:
+		no_implement("ptrace\n");
+		break;
+	case SYS_pwrite64:
+		no_implement("pwrite64\n");
+		break;
+	case SYS_pwritev:
+		no_implement("pwritev\n");
+		break;
+	case SYS_quotactl:
+		no_implement("quotactl\n");
+		break;
+	case SYS_read:
+		ret = shell_read((int)r->a, (void *)r->b, (size_t)r->c);
+		break;
+	case SYS_readahead:
+		no_implement("readahead\n");
+		break;
+	case SYS_readlink:
+		no_implement("readlink\n");
+		break;
+	case SYS_readlinkat:
+		no_implement("readlinkat\n");
+		break;
+	case SYS_readv:
+		ret = shell_readv((int)r->a, (const struct iovec *)r->b, (int)r->c);
+		break;
+	case SYS_recv:
+		ret = shell_recv(r->a, (void *)r->b, (size_t)r->c, r->d);
+		break;
+	case SYS_recvfrom:
+		if (r->e == 0)
+			ret = shell_recv(r->a, (void *)r->b, (size_t)r->c, r->d);
+		else
+			ret = shell_recvfrom(r->a, (void *)r->b, (size_t)r->c, r->d, (struct sockaddr *)r->e, (socklen_t *)r->f);
+		break;
+	case SYS_recvmsg:
+		ret = shell_recvmsg(r->a, (struct msghdr *)r->b, (size_t)r->c);
+		break;
+	case SYS_reboot:
+		no_implement("reboot\n");
+		break;
+	case SYS_recvmmsg:
+		no_implement("recvmmsg\n");
+		break;
+	case SYS_remap_file_pages:
+		no_implement("remap_file_pages\n");
+		break;
+	case SYS_removexattr:
+		no_implement("removexattr\n");
+		break;
+	case SYS_rename:
+		ret = shell_rename((const char *)r->a, (const char *)r->b);
+		break;
+	case SYS_renameat:
+		no_implement("renameat\n");
+		break;
+	case SYS_rmdir:
+		ret = shell_rmdir((const char *)r->a);
+		break;
+	case SYS_rt_sigaction:
+		ret = shell_sigaction(r->a, (const struct sigaction *)r->b, (struct sigaction *)r->c);
+		break;
+	case SYS_rt_sigpending:
+		no_implement("rt_sigpending\n");
+		break;
+	case SYS_rt_sigprocmask:
+		ret = shell_sigprocmask(r->a, (const sigset_t *)r->b, (sigset_t *)r->c);
+		break;
+	case SYS_rt_sigqueueinfo:
+		no_implement("rt_sigqueueinfo\n");
+		break;
+	case SYS_rt_sigsuspend:
+		no_implement("rt_sigsuspend\n");
+		break;
+	case SYS_rt_sigtimedwait:
+		no_implement("rt_sigtimedwait\n");
+		break;
+	case SYS_send:
+		ret = shell_send(r->a, (const void *)r->b, (size_t)r->c, r->d);
+		break;
+	case SYS_sendmsg:
+		ret = shell_sendmsg(r->a, (const struct msghdr *)r->b, (size_t)r->c);
+		break;
+	case SYS_sendto:
+		if (r->e == 0)
+			ret = shell_send(r->a, (const void *)r->b, (size_t)r->c, r->d);
+		else
+			ret = shell_sendto(r->a, (const void *)r->b, (size_t)r->c, r->d, (const struct sockaddr *)r->e, (socklen_t)r->f);
+		break;
+	case SYS_setsockopt:
+		ret = shell_setsockopt(r->a, r->b, r->c, (const void *)r->d, (socklen_t)r->e);
+		break;
+	case SYS_shutdown:
+		ret = shell_shutdown(r->a, r->b);
+		break;
+	case SYS_sched_get_priority_max:
+		no_implement("sched_get_priority_max\n");
+		break;
+	case SYS_sched_get_priority_min:
+		no_implement("sched_get_priority_min\n");
+		break;
+	case SYS_sched_getaffinity:
+		no_implement("sched_getaffinity\n");
+		break;
+	case SYS_sched_getparam:
+		no_implement("sched_getparam\n");
+		break;
+	case SYS_sched_getscheduler:
+		no_implement("sched_getscheduler\n");
+		break;
+	case SYS_sched_rr_get_interval:
+		no_implement("sched_rr_get_interval\n");
+		break;
+	case SYS_sched_setaffinity:
+		no_implement("sched_setaffinity\n");
+		break;
+	case SYS_sched_setparam:
+		no_implement("sched_setparam\n");
+		break;
+	case SYS_sched_setscheduler:
+		no_implement("sched_setscheduler\n");
+		break;
+	case SYS_sched_yield:
+		no_implement("sched_yield\n");
+		break;
+	case SYS_semctl:
+		no_implement("semctl\n");
+		break;
+	case SYS_semget:
+		no_implement("semget\n");
+		break;
+	case SYS_semop:
+		no_implement("semop\n");
+		break;
+	case SYS_semtimedop:
+		no_implement("semtimedop\n");
+		break;
+	case SYS_sendfile64:
+		no_implement("sendfile\n");
+		break;
+	case SYS_sendmmsg:
+		no_implement("sendmmsg\n");
+		break;
+	case SYS_set_robust_list:
+		no_implement("set_robust_list\n");
+		break;
+#ifdef SYS_set_thread_area
+	case SYS_set_thread_area:
+		thread_area = (void *)r->a;
+		__asm__ __volatile__ ( "mcr p15,0,%0,c13,c0,3" :: "r"(thread_area) );
+		ret = 0;
+		break;
+#endif
+	case SYS_set_tid_address:
+		tid_address = (void *)r->a;
+		ret = 0;
+		break;
+	case SYS_setdomainname:
+		no_implement("setdomainname\n");
+		break;
+	case SYS_setfsgid32:
+		no_implement("setfsgid\n");
+		break;
+	case SYS_setfsuid32:
+		no_implement("setfsuid\n");
+		break;
+	case SYS_setgroups32:
+		no_implement("setgroups\n");
+		break;
+	case SYS_sethostname:
+		no_implement("sethostname\n");
+		break;
+	case SYS_setitimer:
+		no_implement("setitimer\n");
+		break;
+	case SYS_setns:
+		no_implement("setns\n");
+		break;
+	case SYS_setpgid:
+		no_implement("setpgid\n");
+		break;
+	case SYS_setpriority:
+		no_implement("setpriority\n");
+		break;
+	case SYS_setrlimit:
+		no_implement("setrlimit\n");
+		break;
+	case SYS_setsid:
+		no_implement("setsid\n");
+		break;
+	case SYS_settimeofday:
+		no_implement("settimeofday\n");
+		break;
+	case SYS_setxattr:
+		no_implement("setxattr\n");
+		break;
+	case SYS_shmat:
+		no_implement("shmat\n");
+		break;
+	case SYS_shmctl:
+		no_implement("shmctl\n");
+		break;
+	case SYS_shmdt:
+		no_implement("shmdt\n");
+		break;
+	case SYS_shmget:
+		no_implement("shmget\n");
+		break;
+	case SYS_sigaltstack:
+		no_implement("sigaltstack\n");
+		break;
+	case SYS_signalfd:
+		no_implement("signalfd\n");
+		break;
+	case SYS_signalfd4:
+		no_implement("signalfd4\n");
+		break;
+	case SYS_socket:
+		ret = shell_socket(r->a, r->b, r->c);
+		break;
+	case SYS_splice:
+		no_implement("splice\n");
+		break;
+	case SYS_stat64:
+		ret = shell_stat((const char *)r->a, (struct stat *)r->b);
+		break;
+	case SYS_statfs64:
+		no_implement("statfs64\n");
+		break;
+	case SYS_swapoff:
+		no_implement("swapoff\n");
+		break;
+	case SYS_swapon:
+		no_implement("swapon\n");
+		break;
+	case SYS_symlink:
+		no_implement("symlink\n");
+		break;
+	case SYS_symlinkat:
+		no_implement("symlinkat\n");
+		break;
+	case SYS_sync:
+		no_implement("sync\n");
+		break;
+#ifdef SYS_sync_file_range
+	case SYS_sync_file_range:
+		no_implement("sync_file_range\n");
+		break;
+#endif
+	case SYS_sync_file_range2:
+		no_implement("sync_file_range2\n");
+		break;
+	case SYS_syncfs:
+		no_implement("syncfs\n");
+		break;
+	case SYS_sysinfo:
+		no_implement("sysinfo\n");
+		break;
+	case SYS_syslog:
+		no_implement("syslog\n");
+		break;
+	case SYS_tee:
+		no_implement("tee\n");
+		break;
+	case SYS_tgkill:
+		no_implement("tgkill\n");
+		break;
+	case SYS_timer_create:
+		no_implement("timer_create\n");
+		break;
+	case SYS_timer_delete:
+		no_implement("timer_delete\n");
+		break;
+	case SYS_timer_getoverrun:
+		no_implement("timer_getoverrun\n");
+		break;
+	case SYS_timer_gettime:
+		no_implement("timer_gettime\n");
+		break;
+	case SYS_timer_settime:
+		no_implement("timer_settime\n");
+		break;
+	case SYS_timerfd_create:
+		no_implement("timerfd_create\n");
+		break;
+	case SYS_timerfd_gettime:
+		no_implement("timerfd_gettime\n");
+		break;
+	case SYS_timerfd_settime:
+		no_implement("timerfd_settime\n");
+		break;
+	case SYS_times:
+		no_implement("times\n");
+		break;
+	case SYS_tkill:
+		no_implement("tkill\n");
+		break;
+	case SYS_truncate64:
+		no_implement("truncate\n");
+		break;
+	case SYS_ugetrlimit:
+		no_implement("ugetrlimit\n");
+		break;
+	case SYS_umask:
+		no_implement("umask\n");
+		break;
+	case SYS_umount2:
+		no_implement("umount2\n");
+		break;
+	case SYS_uname:
+		ret = shell_uname((struct utsname *)r->a);
+		break;
+	case SYS_unlink:
+		ret = shell_unlink((const char *)r->a);
+		break;
+	case SYS_unlinkat:
+		no_implement("unlinkat\n");
+		break;
+	case SYS_unshare:
+		no_implement("unshare\n");
+		break;
+	case SYS_utimensat:
+		no_implement("utimensat\n");
+		break;
+	case SYS_utimes:
+		no_implement("utimes\n");
+		break;
+	case SYS_vhangup:
+		no_implement("vhangup\n");
+		break;
+	case SYS_vmsplice:
+		no_implement("vmsplice\n");
+		break;
+	case SYS_wait4:
+		no_implement("wait4\n");
+		break;
+	case SYS_waitid:
+		no_implement("waitid\n");
+		break;
+	case SYS_write:
+		ret = shell_write((int)r->a, (const void *)r->b, (size_t)r->c);
+		break;
+	case SYS_writev:
+		ret = shell_writev((int)r->a, (const struct iovec *)r->b, (size_t)r->c);
+		break;
+	default:
+		switch (r->n) {
+		case 0xf0002:
+			flash_access_cache_control();
+			ret = 0;
+			break;
+		case 0xf0005:
+			// __set_thread_area
+			thread_area = (void *)r->a;
+			__asm__ __volatile__ ( "mcr p15,0,%0,c13,c0,3" :: "r"(thread_area) );
+			ret = 0;
+			break;
+		default:
+			asm("bkpt #0");
+			break;
+		}
+		break;
+	}
+
+	shellif_outof();
+
+	return ret;
+}
+
+void __attribute__((naked)) __syscall_cp_asm()
+{
+	register long sp asm("sp");
+	asm("push	{r0, r1, r2, r3, r4, r5, r7, r12, lr}");
+	__syscall((struct regs_t *)sp);
+	asm("add	sp, sp, #4");
+	asm("pop	{r1, r2, r3, r4, r5, r7, r12, pc}");
+}
+
+/*
+ *  ã¹ã¼ããã¤ã¶ã³ã¼ã«
+ */
+void __attribute__((naked)) _kernel_svc_handler(void)
+{
+	register long r0 asm("r0");
+	asm("srsfd	#0x13!");
+	asm("stmfd	sp!, {r0-r3,r12,lr}");
+	asm("mrs	r0, spsr");
+	asm("tst	r0, #0x20");
+	asm("ldrneh	r0, [lr,#-2]");
+	asm("bicne	r0, r0, #0xFF00");
+	asm("ldreq	r0, [lr,#-4]");
+	asm("biceq	r0, r0, #0xFF000000");
+	switch (r0){
+	case 0:
+		asm("str	%0, [sp,#0x18]" :: "r"(__syscall_cp_asm));
+		break;
+	case 1:
+		asm("str	%0, [sp,#0x18]" :: "r"(__mbedcall_cp_asm));
+		break;
+	}
+	asm("ldmfd	sp!, {r0-r3,r12,lr}");
+	asm("rfefd	sp!");
+}
Index: EcnlProtoTool/trunk/ntshell/src/tinet_app_config.h
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/tinet_app_config.h	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/src/tinet_app_config.h	(revision 331)
@@ -2,5 +2,5 @@
  *  TINET (TCP/IP Protocol Stack)
  * 
- *  Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
+ *  Copyright (C) 2001-2012 by Dep. of Computer Science and Engineering
  *                   Tomakomai National College of Technology, JAPAN
  *
@@ -62,12 +62,4 @@
 
 /*
- *  TCPの能動オープンのみサポートすることを指定する。
- */
-
-#ifdef UNDEF_TCP_CFG_PASSIVE_OPEN
-#undef TCP_CFG_PASSIVE_OPEN
-#endif
-
-/*
  *  TCP 通信端点の送受信ウィンドバッファの省コピー機能
  *    注意: Makefile で指定している。
@@ -98,11 +90,15 @@
 #ifdef USE_TCP_MSS_SEG
 
+#ifdef SUPPORT_INET6
+
+#define TCP_CFG_SWBUF_CSAVE_MAX_SIZE	(IF_HDR_SIZE + IPV6_MMTU)	/* 最大サイズ */
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
 #ifdef SUPPORT_INET4
 #define TCP_CFG_SWBUF_CSAVE_MAX_SIZE	(IF_HDR_SIZE + IP4_MSS)		/* 最大サイズ */
 #endif
 
-#ifdef SUPPORT_INET6
-#define TCP_CFG_SWBUF_CSAVE_MAX_SIZE	(IF_HDR_SIZE + IPV6_MMTU)	/* 最大サイズ */
-#endif
+#endif	/* of #ifdef SUPPORT_INET6 */
 
 #else	/* of #ifdef USE_TCP_MSS_SEG */
@@ -135,11 +131,15 @@
 #endif
 
+#ifdef SUPPORT_INET6
+
+#define MAX_TCP_SND_SEG			TCP6_MSS
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
 #ifdef SUPPORT_INET4
 #define MAX_TCP_SND_SEG			TCP_MSS
 #endif
 
-#ifdef SUPPORT_INET6
-#define MAX_TCP_SND_SEG			TCP6_MSS
-#endif
+#endif	/* of #ifdef SUPPORT_INET6 */
 
 #endif	/* of #ifdef USE_TCP_MSS_SEG */
@@ -155,11 +155,15 @@
 #endif
 
+#ifdef SUPPORT_INET6
+
+#define DEF_TCP_RCV_SEG			TCP6_MSS
+
+#else	/* of #ifdef SUPPORT_INET6 */
+
 #ifdef SUPPORT_INET4
 #define DEF_TCP_RCV_SEG			TCP_MSS
 #endif
 
-#ifdef SUPPORT_INET6
-#define DEF_TCP_RCV_SEG			TCP6_MSS
-#endif
+#endif	/* of #ifdef SUPPORT_INET6 */
 
 #endif	/* of #ifdef USE_TCP_MSS_SEG */
@@ -235,7 +239,28 @@
 #define UDP_CFG_EXTENTIONS
 
+/* IPv6 に関する定義 */
+
+#ifdef SUPPORT_PPP
+
+#define NUM_IN6_STATIC_ROUTE_ENTRY	0
+#define NUM_IN6_REDIRECT_ROUTE_ENTRY	0
+
+#endif	/* of #ifdef SUPPORT_PPP */
+
+#ifdef SUPPORT_LOOP
+
+#define NUM_IN6_STATIC_ROUTE_ENTRY	0
+#define NUM_IN6_REDIRECT_ROUTE_ENTRY	0
+
+#endif	/* of #ifdef SUPPORT_LOOP */
+
+#ifdef SUPPORT_ETHER
+
+#define NUM_IN6_STATIC_ROUTE_ENTRY	0
+#define NUM_IN6_REDIRECT_ROUTE_ENTRY	1
+
+#endif	/* of #ifdef SUPPORT_ETHER */
+
 /* IPv4 に関する定義 */
-
-#ifdef SUPPORT_INET4
 
 #ifdef SUPPORT_PPP
@@ -253,6 +278,6 @@
 #endif
 
-#define NUM_STATIC_ROUTE_ENTRY		1
-#define NUM_REDIRECT_ROUTE_ENTRY	0
+#define NUM_IN4_STATIC_ROUTE_ENTRY	1
+#define NUM_IN4_REDIRECT_ROUTE_ENTRY	0
 
 #endif	/* of #ifdef SUPPORT_PPP */
@@ -260,5 +285,5 @@
 #ifdef SUPPORT_ETHER
 
-#ifdef DHCP_CFG
+#ifdef DHCP4_CLI_CFG
 
 #define IPV4_ADDR_LOCAL			MAKE_IPV4_ADDR(0,0,0,0)
@@ -266,5 +291,5 @@
 #define IPV4_ADDR_DEFAULT_GW		MAKE_IPV4_ADDR(0,0,0,0)
 
-#else	/* of #ifdef DHCP_CFG */
+#else	/* of #ifdef DHCP4_CLI_CFG */
 
 #define IPV4_ADDR_LOCAL			MAKE_IPV4_ADDR(192,168,137,110)
@@ -272,8 +297,8 @@
 #define IPV4_ADDR_DEFAULT_GW		MAKE_IPV4_ADDR(192,168,137,1)
 
-#endif	/* of #ifdef DHCP_CFG */
-
-#define NUM_STATIC_ROUTE_ENTRY		3
-#define NUM_REDIRECT_ROUTE_ENTRY	1
+#endif	/* of #ifdef DHCP4_CLI_CFG */
+
+#define NUM_IN4_STATIC_ROUTE_ENTRY	3
+#define NUM_IN4_REDIRECT_ROUTE_ENTRY	1
 
 #endif	/* of #ifdef SUPPORT_ETHER */
@@ -281,37 +306,8 @@
 #ifdef SUPPORT_LOOP
 
-#define NUM_STATIC_ROUTE_ENTRY		1
-#define NUM_REDIRECT_ROUTE_ENTRY	0
+#define NUM_IN4_STATIC_ROUTE_ENTRY	1
+#define NUM_IN4_REDIRECT_ROUTE_ENTRY	0
 
 #endif	/* of #ifdef SUPPORT_LOOP */
-
-#endif	/* of #ifdef SUPPORT_INET4 */
-
-/* IPv6 に関する定義 */
-
-#ifdef SUPPORT_INET6
-
-#ifdef SUPPORT_PPP
-
-#define NUM_STATIC_ROUTE_ENTRY		0
-#define NUM_REDIRECT_ROUTE_ENTRY	0
-
-#endif	/* of #ifdef SUPPORT_PPP */
-
-#ifdef SUPPORT_LOOP
-
-#define NUM_STATIC_ROUTE_ENTRY		0
-#define NUM_REDIRECT_ROUTE_ENTRY	0
-
-#endif	/* of #ifdef SUPPORT_LOOP */
-
-#ifdef SUPPORT_ETHER
-
-#define NUM_STATIC_ROUTE_ENTRY		0
-#define NUM_REDIRECT_ROUTE_ENTRY	1
-
-#endif	/* of #ifdef SUPPORT_ETHER */
-
-#endif	/* of #ifdef SUPPORT_INET6 */
 
 /*
@@ -420,5 +416,5 @@
  *    IPv6 でのみ割り当てる。
  *
- *    RX62N Ethernet Controler のディバイスドライバ（if_rx62n）の最低割当て長は、
+ *    MBED Ethernet Controler のディバイスドライバ（if_mbed）の最低割当て長は、
  *    イーサネットフレームの最短長である 60（CRC の 4 オクテットを除き、
  *    更にアラインして 62）オクテットである。
Index: EcnlProtoTool/trunk/ntshell/src/tinet_main.cfg
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/tinet_main.cfg	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/src/tinet_main.cfg	(revision 331)
@@ -43,4 +43,6 @@
 #include "main.h"
 
+INCLUDE("netinet/ip_igmp.cfg");
+
 /* DHCP クライアント */
 /*INCLUDE("netapp/tinet_dhcp4_cli.cfg");*/
@@ -49,48 +51,26 @@
 /* ECHONET Lite UDP 通信端点 */
 
-#ifdef SUPPORT_INET4
+VRID_TCP_REP (USR_TCP_REP1);
+VRID_TCP_REP (USR_TCP_REP2);
+VRID_TCP_REP (USR_TCP_REP3);
+VRID_TCP_REP (USR_TCP_REP4);
 
-VRID_TCP4_REP (USR_TCP_REP1);
-VRID_TCP4_REP (USR_TCP_REP2);
-VRID_TCP4_REP (USR_TCP_REP3);
-VRID_TCP4_REP (USR_TCP_REP4);
+VRID_TCP_CEP (USR_TCP_CEP1);
+VRID_TCP_CEP (USR_TCP_CEP2);
+VRID_TCP_CEP (USR_TCP_CEP3);
+VRID_TCP_CEP (USR_TCP_CEP4);
+VRID_TCP_CEP (USR_TCP_CEP5);
+VRID_TCP_CEP (USR_TCP_CEP6);
+VRID_TCP_CEP (USR_TCP_CEP7);
+VRID_TCP_CEP (USR_TCP_CEP8);
 
-VRID_TCP4_CEP (USR_TCP_CEP1);
-VRID_TCP4_CEP (USR_TCP_CEP2);
-VRID_TCP4_CEP (USR_TCP_CEP3);
-VRID_TCP4_CEP (USR_TCP_CEP4);
-VRID_TCP4_CEP (USR_TCP_CEP5);
-VRID_TCP4_CEP (USR_TCP_CEP6);
-VRID_TCP4_CEP (USR_TCP_CEP7);
-VRID_TCP4_CEP (USR_TCP_CEP8);
+VRID_UDP_CEP (USR_UDP_CEP1);
+VRID_UDP_CEP (USR_UDP_CEP2);
+VRID_UDP_CEP (USR_UDP_CEP3);
+VRID_UDP_CEP (USR_UDP_CEP4);
 
-VRID_UDP4_CEP (USR_UDP_CEP1);
-VRID_UDP4_CEP (USR_UDP_CEP2);
-VRID_UDP4_CEP (USR_UDP_CEP3);
-VRID_UDP4_CEP (USR_UDP_CEP4);
+VRID_UDP6_CEP (USR_UDP6_CEP1);
+VRID_UDP6_CEP (USR_UDP6_CEP2);
+VRID_UDP6_CEP (USR_UDP6_CEP3);
+VRID_UDP6_CEP (USR_UDP6_CEP4);
 
-#endif	/* of #ifdef SUPPORT_INET4 */
-
-#ifdef SUPPORT_INET6
-
-VRID_TCP6_REP (USR_TCP_REP1);
-VRID_TCP6_REP (USR_TCP_REP2);
-VRID_TCP6_REP (USR_TCP_REP3);
-VRID_TCP6_REP (USR_TCP_REP4);
-
-VRID_TCP6_CEP (USR_TCP_CEP1);
-VRID_TCP6_CEP (USR_TCP_CEP2);
-VRID_TCP6_CEP (USR_TCP_CEP3);
-VRID_TCP6_CEP (USR_TCP_CEP4);
-VRID_TCP6_CEP (USR_TCP_CEP5);
-VRID_TCP6_CEP (USR_TCP_CEP6);
-VRID_TCP6_CEP (USR_TCP_CEP7);
-VRID_TCP6_CEP (USR_TCP_CEP8);
-
-VRID_UDP6_CEP (USR_UDP_CEP1);
-VRID_UDP6_CEP (USR_UDP_CEP2);
-VRID_UDP6_CEP (USR_UDP_CEP3);
-VRID_UDP6_CEP (USR_UDP_CEP4);
-
-#endif	/* of #ifdef SUPPORT_INET6 */
-
Index: EcnlProtoTool/trunk/ntshell/webserver/base64.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/webserver/base64.c	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/webserver/base64.c	(revision 331)
@@ -7,4 +7,5 @@
 
 #include "base64.h"
+#include "core/ntlibc.h"
 
 static const char base64_encode_chars[] =
@@ -85,5 +86,5 @@
     unsigned char *pdst;
     int i, j = 0, k = 0;
-    size_t srcsiz = strlen((const char *)src);
+    size_t srcsiz = ntlibc_strlen((const char *)src);
 
     if ((srcsiz % 4) != 0) {
Index: EcnlProtoTool/trunk/ntshell/webserver/http_parser.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/webserver/http_parser.c	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/webserver/http_parser.c	(revision 331)
@@ -29,4 +29,5 @@
 #include <string.h>
 #include <limits.h>
+#include "core/ntlibc.h"
 
 #ifndef ULLONG_MAX
@@ -2371,5 +2372,5 @@
   if (u->field_set & (1 << UF_PORT)) {
     /* Don't bother with endp; we've already validated the string */
-    unsigned long v = strtoul(buf + u->field_data[UF_PORT].off, NULL, 10);
+    unsigned long v = ntlibc_strtoul(buf + u->field_data[UF_PORT].off, NULL, 10);
 
     /* Ports have a max value of 2^16 */
Index: EcnlProtoTool/trunk/ntshell/webserver/httpd-fs.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/webserver/httpd-fs.c	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/webserver/httpd-fs.c	(revision 331)
@@ -45,9 +45,9 @@
 #include "kernel_cfg.h"
 #include "syssvc/syslog.h"
-#include "ntstdio.h"
+#include "util/ntstdio.h"
 
 #ifndef _MSC_VER
 #ifndef strcat_s
-#define strcat_s(dst, dsz, src) strcat(dst, src)
+#define strcat_s(dst, dsz, src) ntlibc_strcat(dst, src)
 #endif
 #endif
@@ -75,5 +75,5 @@
 	res = f_opendir(&dir, path);
 	if (res == FR_OK) {
-		i = strlen(path);
+		i = ntlibc_strlen(path);
 		for (;;) {
 			res = f_readdir(&dir, &fno);
Index: EcnlProtoTool/trunk/ntshell/webserver/httpd.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/webserver/httpd.c	(revision 321)
+++ EcnlProtoTool/trunk/ntshell/webserver/httpd.c	(revision 331)
@@ -43,6 +43,9 @@
 #include "syssvc/syslog.h"
 #include "http-strings.h"
+#include <tinet_defs.h>
+#include <tinet_config.h>
 #include "netinet/in.h"
 #include "netinet/in_var.h"
+#include "netinet/in_itron.h"
 #include "httpd.h"
 #include "httpd-fs.h"
@@ -50,5 +53,6 @@
 #include "base64.h"
 #include "sha1.h"
-#include "ntstdio.h"
+#include "util/ntstdio.h"
+#include "core/ntlibc.h"
 
 #define TRUE 1
@@ -82,4 +86,5 @@
 
 #ifndef _MSC_VER
+#define strnlen httpd_strnlen
 /* strnlen() is a POSIX.2008 addition. Can't rely on it being available so
  * define it ourselves.
@@ -99,5 +104,5 @@
 void strcpy_s(char *dst, int size, const char *src)
 {
-	int slen = strlen(src);
+	int slen = ntlibc_strlen(src);
 	if (slen >= size)
 		slen = size - 1;
@@ -108,6 +113,6 @@
 void strcat_s(char *dst, int size, const char *src)
 {
-	int dlen = strlen(dst);
-	int slen = strlen(src);
+	int dlen = ntlibc_strlen(dst);
+	int slen = ntlibc_strlen(src);
 	if (dlen + slen >= size)
 		slen = size - 1 - dlen;
@@ -223,26 +228,26 @@
 	struct message *m = &s->message;
 
-	if (strncmp("Referer", buf, len) == 0) {
+	if (ntlibc_strncmp("Referer", buf, len) == 0) {
 		m->num_headers = 1;
 	}
-	else if (strncmp("Host", buf, len) == 0) {
+	else if (ntlibc_strncmp("Host", buf, len) == 0) {
 		m->num_headers = 2;
 	}
-	else if (strncmp("Upgrade", buf, len) == 0) {
+	else if (ntlibc_strncmp("Upgrade", buf, len) == 0) {
 		m->num_headers = 3;
 	}
-	else if (strncmp("Connection", buf, len) == 0) {
+	else if (ntlibc_strncmp("Connection", buf, len) == 0) {
 		m->num_headers = 4;
 	}
-	else if (strncmp("Sec-WebSocket-Key", buf, len) == 0) {
+	else if (ntlibc_strncmp("Sec-WebSocket-Key", buf, len) == 0) {
 		m->num_headers = 5;
 	}
-	else if (strncmp("Origin", buf, len) == 0) {
+	else if (ntlibc_strncmp("Origin", buf, len) == 0) {
 		m->num_headers = 6;
 	}
-	else if (strncmp("Sec-WebSocket-Protocol", buf, len) == 0) {
+	else if (ntlibc_strncmp("Sec-WebSocket-Protocol", buf, len) == 0) {
 		m->num_headers = 7;
 	}
-	else if (strncmp("Sec-WebSocket-Version", buf, len) == 0) {
+	else if (ntlibc_strncmp("Sec-WebSocket-Version", buf, len) == 0) {
 		m->num_headers = 8;
 	}
@@ -329,5 +334,5 @@
 			s->in.state = IN_STATE_UPLOAD;
 		}
-		else if (strcmp(s->filename, uploding->filename) == 0) {
+		else if (ntlibc_strcmp(s->filename, uploding->filename) == 0) {
 			ntstdio_printf(&ntstdio, "collision: %s.%d %s\n", s->addr, ((T_IPV4EP *)s->dst)->portno, s->filename);
 			goto error;
@@ -559,5 +564,5 @@
 	char *ptr;
 
-	len = strlen(statushdr);
+	len = ntlibc_strlen(statushdr);
 	tcp_snd_dat(s->cepid, (void *)statushdr, len, TMO_FEVR);
 
@@ -574,9 +579,9 @@
 			tcp_snd_dat(s->cepid, "/~", len, TMO_FEVR);
 		}
-		len = strlen(s->filename);
+		len = ntlibc_strlen(s->filename);
 		tcp_snd_dat(s->cepid, s->filename, len, TMO_FEVR);
 		if (s->query != NULL) {
 			tcp_snd_dat(s->cepid, "?", 1, TMO_FEVR);
-			len = strlen(s->query);
+			len = ntlibc_strlen(s->query);
 			tcp_snd_dat(s->cepid, s->query, len, TMO_FEVR);
 		}
@@ -590,58 +595,58 @@
 		tcp_snd_dat(s->cepid, (void *)http_content_type_binary, len, TMO_FEVR);
 	}
-	else if (strncmp(http_html, ptr, sizeof(http_html) - 1) == 0 ||
-		strncmp(http_htm, ptr, sizeof(http_htm) - 1) == 0) {
+	else if (ntlibc_strncmp(http_html, ptr, sizeof(http_html) - 1) == 0 ||
+		ntlibc_strncmp(http_htm, ptr, sizeof(http_htm) - 1) == 0) {
 		len = sizeof(http_content_type_html) - 1;
 		tcp_snd_dat(s->cepid, (void *)http_content_type_html, len, TMO_FEVR);
 	}
-	else if (strncmp(http_css, ptr, sizeof(http_css) - 1) == 0) {
+	else if (ntlibc_strncmp(http_css, ptr, sizeof(http_css) - 1) == 0) {
 		len = sizeof(http_content_type_css) - 1;
 		tcp_snd_dat(s->cepid, (void *)http_content_type_css, len, TMO_FEVR);
 	}
-	else if (strncmp(http_js, ptr, sizeof(http_js) - 1) == 0) {
+	else if (ntlibc_strncmp(http_js, ptr, sizeof(http_js) - 1) == 0) {
 		len = sizeof(http_content_type_js) - 1;
 		tcp_snd_dat(s->cepid, (void *)http_content_type_js, len, TMO_FEVR);
 	}
-	else if (strncmp(http_json, ptr, sizeof(http_json) - 1) == 0) {
+	else if (ntlibc_strncmp(http_json, ptr, sizeof(http_json) - 1) == 0) {
 		len = sizeof(http_content_type_json) - 1;
 		tcp_snd_dat(s->cepid, (void *)http_content_type_json, len, TMO_FEVR);
 	}
-	else if (strncmp(http_png, ptr, sizeof(http_png) - 1) == 0) {
+	else if (ntlibc_strncmp(http_png, ptr, sizeof(http_png) - 1) == 0) {
 		len = sizeof(http_content_type_png) - 1;
 		tcp_snd_dat(s->cepid, (void *)http_content_type_png, len, TMO_FEVR);
 	}
-	else if (strncmp(http_gif, ptr, sizeof(http_gif) - 1) == 0) {
+	else if (ntlibc_strncmp(http_gif, ptr, sizeof(http_gif) - 1) == 0) {
 		len = sizeof(http_content_type_gif) - 1;
 		tcp_snd_dat(s->cepid, (void *)http_content_type_gif, len, TMO_FEVR);
 	}
-	else if (strncmp(http_jpg, ptr, sizeof(http_jpg) - 1) == 0) {
+	else if (ntlibc_strncmp(http_jpg, ptr, sizeof(http_jpg) - 1) == 0) {
 		len = sizeof(http_content_type_jpg) - 1;
 		tcp_snd_dat(s->cepid, (void *)http_content_type_jpg, len, TMO_FEVR);
 	}
-	else if (strncmp(http_svg, ptr, sizeof(http_svg) - 1) == 0) {
+	else if (ntlibc_strncmp(http_svg, ptr, sizeof(http_svg) - 1) == 0) {
 		len = sizeof(http_content_type_svg) - 1;
 		tcp_snd_dat(s->cepid, (void *)http_content_type_svg, len, TMO_FEVR);
 	}
-	else if (strncmp(http_text, ptr, sizeof(http_text) - 1) == 0) {
+	else if (ntlibc_strncmp(http_text, ptr, sizeof(http_text) - 1) == 0) {
 		len = sizeof(http_content_type_text) - 1;
 		tcp_snd_dat(s->cepid, (void *)http_content_type_text, len, TMO_FEVR);
 	}
-	else if (strncmp(http_eot, ptr, sizeof(http_eot) - 1) == 0) {
+	else if (ntlibc_strncmp(http_eot, ptr, sizeof(http_eot) - 1) == 0) {
 		len = sizeof(http_content_type_eot) - 1;
 		tcp_snd_dat(s->cepid, (void *)http_content_type_eot, len, TMO_FEVR);
 	}
-	else if (strncmp(http_ttf, ptr, sizeof(http_ttf) - 1) == 0) {
+	else if (ntlibc_strncmp(http_ttf, ptr, sizeof(http_ttf) - 1) == 0) {
 		len = sizeof(http_content_type_ttf) - 1;
 		tcp_snd_dat(s->cepid, (void *)http_content_type_ttf, len, TMO_FEVR);
 	}
-	else if (strncmp(http_woff, ptr, sizeof(http_woff) - 1) == 0) {
+	else if (ntlibc_strncmp(http_woff, ptr, sizeof(http_woff) - 1) == 0) {
 		len = sizeof(http_content_type_woff) - 1;
 		tcp_snd_dat(s->cepid, (void *)http_content_type_woff, len, TMO_FEVR);
 	}
-	else if (strncmp(http_woff2, ptr, sizeof(http_woff2) - 1) == 0) {
+	else if (ntlibc_strncmp(http_woff2, ptr, sizeof(http_woff2) - 1) == 0) {
 		len = sizeof(http_content_type_woff2) - 1;
 		tcp_snd_dat(s->cepid, (void *)http_content_type_woff2, len, TMO_FEVR);
 	}
-	else if (strncmp(http_ico, ptr, sizeof(http_ico) - 1) == 0) {
+	else if (ntlibc_strncmp(http_ico, ptr, sizeof(http_ico) - 1) == 0) {
 		len = sizeof(http_content_type_ico) - 1;
 		tcp_snd_dat(s->cepid, (void *)http_content_type_ico, len, TMO_FEVR);
@@ -656,5 +661,5 @@
 		tcp_snd_dat(s->cepid, (void *)http_content_length, len, TMO_FEVR);
 		ntstdio_snprintf(s->temp, sizeof(s->temp), "%d\r\n", s->file.len);
-		tcp_snd_dat(s->cepid, (void *)s->temp, strlen(s->temp), TMO_FEVR);
+		tcp_snd_dat(s->cepid, (void *)s->temp, ntlibc_strlen(s->temp), TMO_FEVR);
 	}
 
@@ -732,10 +737,10 @@
 	int len;
 
-	len = strlen(statushdr);
+	len = ntlibc_strlen(statushdr);
 	tcp_snd_dat(s->cepid, (void *)statushdr, len, TMO_FEVR);
 
 	len = sizeof(http_upgrade) - 1;
 	tcp_snd_dat(s->cepid, (void *)http_upgrade, len, TMO_FEVR);
-	len = strlen(s->message.upgrade);
+	len = ntlibc_strlen(s->message.upgrade);
 	tcp_snd_dat(s->cepid, s->message.upgrade, len, TMO_FEVR);
 	len = sizeof(http_crnl) - 1;
@@ -744,5 +749,5 @@
 	len = sizeof(http_connection) - 1;
 	tcp_snd_dat(s->cepid, (void *)http_connection, len, TMO_FEVR);
-	len = strlen(s->message.connection);
+	len = ntlibc_strlen(s->message.connection);
 	tcp_snd_dat(s->cepid, s->message.connection, len, TMO_FEVR);
 	len = sizeof(http_crnl) - 1;
@@ -751,5 +756,5 @@
 	len = sizeof(http_sec_websocket_accept) - 1;
 	tcp_snd_dat(s->cepid, (void *)http_sec_websocket_accept, len, TMO_FEVR);
-	len = strlen(s->message.response_key);
+	len = ntlibc_strlen(s->message.response_key);
 	tcp_snd_dat(s->cepid, s->message.response_key, len, TMO_FEVR);
 	len = sizeof(http_crnl) - 1;
@@ -758,5 +763,5 @@
 	len = sizeof(http_sec_websocket_protocol) - 1;
 	tcp_snd_dat(s->cepid, (void *)http_sec_websocket_protocol, len, TMO_FEVR);
-	len = strlen(s->message.sec_websocket_protocol);
+	len = ntlibc_strlen(s->message.sec_websocket_protocol);
 	tcp_snd_dat(s->cepid, s->message.sec_websocket_protocol, len, TMO_FEVR);
 	len = sizeof(http_crnl) - 1;
Index: EcnlProtoTool/trunk/onigmo-6.1.3/.cproject
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/.cproject	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/.cproject	(revision 331)
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.599453217">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.599453217" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactExtension="a" artifactName="onigmo" buildArtefactType="com.renesas.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=com.renesas.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf *.lst *.lis *.lpp *.map" description="" id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.599453217" name="Debug" parent="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id">
+					<folderInfo id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.599453217." name="/" resourcePath="">
+						<toolChain id="com.renesas.cdt.library.rz.debug.win32.toolchain.Id.1686505726" name="KPIT GNUARM-NONE-EABI Toolchain" superClass="com.renesas.cdt.library.rz.debug.win32.toolchain.Id">
+							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.PE" id="com.renesas.cdt.rz.libraryProject.debug.win32.targetplatform.Id.904923015" name="Target Platform" osList="win32,linux" superClass="com.renesas.cdt.rz.libraryProject.debug.win32.targetplatform.Id"/>
+							<builder buildPath="${workspace_loc:/onigmo}/Debug" id="com.renesas.cdt.rz.library.project.debug.win32.builder.Id.648387239" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.renesas.cdt.rz.library.project.debug.win32.builder.Id"/>
+							<tool id="com.renesas.cdt.rz.libraryProject.debug.win32.tool.compiler.Id.1403906573" name="Compiler" superClass="com.renesas.cdt.rz.libraryProject.debug.win32.tool.compiler.Id">
+								<option defaultValue="true" id="com.renesas.cdt.core.Compiler.option.misc2.893295126" name="æ¨æºã·ã¹ãã ã»ãã£ã¬ã¯ããªã¼ã§ãããã¼ã»ãã¡ã¤ã«ãæ¤ç´¢ããªã (-nostdinc)" superClass="com.renesas.cdt.core.Compiler.option.misc2" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.dataEndian.830168116" name="ã¨ã³ãã£ã¢ã³" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.dataEndian" value="Little-endian" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.instructionset.181932475" name="å½ä»¤ã»ãã" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.instructionset" value="ARM" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.interworking.1734700906" name="ã¤ã³ã¿ã¼ã»ã¯ã¼ã­ã³ã°" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.interworking" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.targetfpu.294263703" name="ã¿ã¼ã²ãã FPU (-mfpu)" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.targetfpu" value="vfp" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.floatingpointabi.1157903482" name="æµ®åå°æ°ç¹ ABI (-mfloat-abi=name)" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.floatingpointabi" value="Hard" valueType="enumerated"/>
+								<option id="com.renesas.cdt.core.Compiler.option.warnStackSize.1359091351" name="Warn if stack size exceeds the limit (-Wstack-usage) (H')" superClass="com.renesas.cdt.core.Compiler.option.warnStackSize" value="100" valueType="string"/>
+								<option id="com.renesas.cdt.core.Compiler.option.CPUSeries.2092668987" name="CPU ã·ãªã¼ãº" superClass="com.renesas.cdt.core.Compiler.option.CPUSeries" value="RZ/A" valueType="string"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.architecture.2113164712" name="ã¢ã¼ã­ãã¯ãã£ã¼" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.architecture" value="armv7-a" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.cpuType.1970460770" name="CPU ã¿ã¤ã" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.cpuType" value="cortex-a9" valueType="enumerated"/>
+								<option id="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal.79407894" name="Decimal representation of '-Wstack-usage'" superClass="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal" value="256" valueType="string"/>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.rz.Debug.Compiler.option.library.macroDefines.614908404" name="ãã¯ã­å®ç¾©" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.macroDefines" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="ONIG_EXTERN=extern"/>
+								</option>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.core.Compiler.option.includeFileDir.46425275" name="ã¤ã³ã¯ã«ã¼ãã»ãã¡ã¤ã«ã»ãã£ã¬ã¯ããªã¼" superClass="com.renesas.cdt.core.Compiler.option.includeFileDir" valueType="includePath">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/musl-1.1.18/include}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src/enc/unicode}&quot;"/>
+								</option>
+								<inputType id="%Base.Compiler.C.InputType.Id.884982235" name="C å
+¥å" superClass="%Base.Compiler.C.InputType.Id"/>
+								<inputType id="Base.Compiler.CPP.InputType.Id.468221844" name="C++ å
+¥å" superClass="Base.Compiler.CPP.InputType.Id"/>
+							</tool>
+							<tool id="com.renesas.cdt.library.rz.Debug.win32.tool.assembler.Id.1308609704" name="Assembler" superClass="com.renesas.cdt.library.rz.Debug.win32.tool.assembler.Id">
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.dataEndian.671886442" name="ã¨ã³ãã£ã¢ã³" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.dataEndian" value="Little-endian" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.instructionset.753533557" name="å½ä»¤ã»ãã" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.instructionset" value="ARM" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.targetfpu.816721656" name="ã¿ã¼ã²ãã FPU (-mfpu)" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.targetfpu" value="vfp" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.floatingpointabi.631007521" name="æµ®åå°æ°ç¹ ABI (-mfloat-abi=name)" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.floatingpointabi" value="Hard" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.architecture.739518456" name="ã¢ã¼ã­ãã¯ãã£ã¼" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.architecture" value="armv7-a" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.cpuType.1106302179" name="CPU ã¿ã¤ã" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.cpuType" value="cortex-a9" valueType="enumerated"/>
+								<inputType id="%Base.Assembler.inputType.Id.1061608568" name="ã¢ã»ã³ãã©ã¼å
+¥åã¿ã¤ã" superClass="%Base.Assembler.inputType.Id"/>
+							</tool>
+							<tool id="com.renesas.cdt.library.rz.debug.win32.tool.archive.Id.1640450029" name="Archive Generator" superClass="com.renesas.cdt.library.rz.debug.win32.tool.archive.Id"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="onigmo.com.renesas.cdt.rz.library.projectType.Id.158908142" name="Static Library (Renesas)" projectType="com.renesas.cdt.rz.library.projectType.Id"/>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+	<storageModule moduleId="refreshScope"/>
+</cproject>
Index: EcnlProtoTool/trunk/onigmo-6.1.3/.info
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/.info	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/.info	(revision 331)
@@ -0,0 +1,7 @@
+TOOL_CHAIN=KPIT GNUARM-NONE-EABI Toolchain
+VERSION=v16.01
+TC_INSTALL=C:\Program Files (x86)\KPIT\GNUARM-NONEv16.01-EABI\arm-none-eabi\arm-none-eabi\
+GCC_STRING=5.2-GNUARM-NONE_v16.01
+VERSION_IDE=
+E2STUDIO_VERSION=5.4.0.018
+ACTIVE_CONFIGURATION=Debug
Index: EcnlProtoTool/trunk/onigmo-6.1.3/.project
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/.project	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/.project	(revision 331)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>onigmo-6.1.3</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>com.renesas.cdt.core.genmakebuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>com.renesas.cdt.core.kpitcnature</nature>
+		<nature>com.renesas.cdt.core.kpitccnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+	</natures>
+</projectDescription>
Index: EcnlProtoTool/trunk/onigmo-6.1.3/COPYING
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/COPYING	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/COPYING	(revision 331)
@@ -0,0 +1,87 @@
+Onigmo (Oniguruma-mod) LICENSE
+------------------------------
+
+/*-
+ * Copyright (c) 2002-2009  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011-2014  K.Takata  <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+
+Oniguruma LICENSE
+-----------------
+
+/*-
+ * Copyright (c) 2002-2009  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+
+Ruby BSDL
+---------
+Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
Index: EcnlProtoTool/trunk/onigmo-6.1.3/README
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/README	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/README	(revision 331)
@@ -0,0 +1,251 @@
+README  2016/11/30
+
+Onigmo (Oniguruma-mod)  --  (C) K.Takata <kentkt AT csc DOT jp>
+
+https://github.com/k-takata/Onigmo
+
+Onigmo is a regular expressions library forked from Oniguruma.
+It focuses to support new expressions like `\K`, `\R`, `(?(cond)yes|no)`
+and etc. which are supported in Perl 5.10+.
+
+Since Onigmo is used as the default regexp library of Ruby 2.0 or later,
+many patches are backported from Ruby 2.x.
+
+See also the Wiki page:
+https://github.com/k-takata/Onigmo/wiki
+
+
+Main New features:
+  Regular Expressions (depends on the syntax):
+    \K, \R, \X, (?(cond)yes|no)
+    (?adlu), \g{name}, \g{n}, (?&name), (?n), (?R), (?0)
+    (?P<name>...), (?P=name), (?P>name)
+
+  API:
+    onig_search_gpos (for Perl-compatible \G)
+
+  Encoding:
+    CP932, CP1250, CP1251, CP1252, CP1253, CP1254, CP1257
+
+  Syntax:
+    Python
+
+
+New Source Files:
+  enc/jis/props.h               JIS character properties data.
+  enc/jis/props.kwd             JIS character properties data.
+  enc/unicode/casefold.h        Unicode case folding data.
+  enc/unicode/name2ctype.h      Unicode properties data.
+  enc/windows_*.c               CP* encoding
+
+  onigmo.py                     onigmo.dll/libonigmo.so loader.
+  testpy.py                     test program.
+
+  tool/download-ucd.sh          downloads Unicode Character Database (UCD).
+  tool/case-folding.rb          generates casefold.h from UCD.
+  tool/convert-jis-props.sh     converts props.kwd to props.h.
+  tool/convert-name2ctype.sh    converts name2ctype.kwd to name2ctypes.h.
+  tool/enc-unicode.rb           generates name2ctype.kwd from UCD.
+
+  win32/Makefile.mingw          Makefile for Win32 (MinGW)
+  win32/makedef.py              creates onigmo.def.
+  win32/onigmo.rc               resource file for onigmo.dll.
+
+
+ToDo:
+  * Reduce the size of Unicode Character Data.
+  * (?|...)
+  * Improve (?(cond)yes|no). (support look-ahead/behind assertions.)
+
+
+Oniguruma's README follows:
+======================================================================
+README  2007/05/31
+
+Oniguruma  ----   (C) K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+
+http://www.geocities.jp/kosako3/oniguruma/
+
+Oniguruma is a regular expressions library.
+The characteristics of this library is that different character encoding
+for every regular expression object can be specified.
+
+Supported character encodings:
+
+  ASCII, UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, UTF-32LE,
+  EUC-JP, EUC-TW, EUC-KR, EUC-CN,
+  Shift_JIS, Big5, GB18030, KOI8-R, CP1251,
+  ISO-8859-1, ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5,
+  ISO-8859-6, ISO-8859-7, ISO-8859-8, ISO-8859-9, ISO-8859-10,
+  ISO-8859-11, ISO-8859-13, ISO-8859-14, ISO-8859-15, ISO-8859-16
+
+* GB18030: contributed by KUBO Takehiro
+* CP1251:  contributed by Byte
+------------------------------------------------------------
+
+License
+
+   BSD license.
+
+
+Install
+
+ Case 1: Unix and Cygwin platform
+
+   1. ./configure
+   2. make
+   3. make install
+
+   * uninstall
+
+     make uninstall
+
+   * test (ASCII/EUC-JP)
+
+     make atest
+
+   * configuration check
+
+     onig-config --cflags
+     onig-config --libs
+     onig-config --prefix
+     onig-config --exec-prefix
+
+
+
+ Case 2: Win32 platform (VC++)
+
+   1. copy win32\Makefile Makefile
+   2. copy win32\config.h config.h
+   3. nmake
+
+      onig_s.lib:  static link library
+      onig.dll:    dynamic link library
+
+  * test (ASCII/Shift_JIS)
+   4. copy win32\testc.c testc.c
+   5. nmake ctest
+
+
+
+Regular Expressions
+
+  See doc/RE (or doc/RE.ja for Japanese).
+
+
+Usage
+
+  Include oniguruma.h in your program. (Oniguruma API)
+  See doc/API for Oniguruma API.
+
+  If you want to disable UChar type (== unsigned char) definition
+  in oniguruma.h, define ONIG_ESCAPE_UCHAR_COLLISION and then
+  include oniguruma.h.
+
+  If you want to disable regex_t type definition in oniguruma.h,
+  define ONIG_ESCAPE_REGEX_T_COLLISION and then include oniguruma.h.
+
+  Example of the compiling/linking command line in Unix or Cygwin,
+  (prefix == /usr/local case)
+
+    cc sample.c -L/usr/local/lib -lonig
+
+
+  If you want to use static link library(onig_s.lib) in Win32,
+  add option -DONIG_EXTERN=extern to C compiler.
+
+
+
+Sample Programs
+
+  sample/simple.c    example of the minimum (Oniguruma API)
+  sample/names.c     example of the named group callback.
+  sample/encode.c    example of some encodings.
+  sample/listcap.c   example of the capture history.
+  sample/posix.c     POSIX API sample.
+  sample/sql.c       example of the variable meta characters.
+                     (SQL-like pattern matching)
+
+Test Programs
+  sample/syntax.c    Perl, Java and ASIS syntax test.
+  sample/crnl.c      --enable-crnl-as-line-terminator test
+
+
+Source Files
+
+  oniguruma.h        Oniguruma API header file. (public)
+  onig-config.in     configuration check program template.
+
+  regenc.h           character encodings framework header file.
+  regint.h           internal definitions
+  regparse.h         internal definitions for regparse.c and regcomp.c
+  regcomp.c          compiling and optimization functions
+  regenc.c           character encodings framework.
+  regerror.c         error message function
+  regext.c           extended API functions. (deluxe version API)
+  regexec.c          search and match functions
+  regparse.c         parsing functions.
+  regsyntax.c        pattern syntax functions and built-in syntax definitions.
+  regtrav.c          capture history tree data traverse functions.
+  regversion.c       version info function.
+  st.h               hash table functions header file
+  st.c               hash table functions
+
+  oniggnu.h          GNU regex API header file. (public)
+  reggnu.c           GNU regex API functions
+
+  onigposix.h        POSIX API header file. (public)
+  regposerr.c        POSIX error message function.
+  regposix.c         POSIX API functions.
+
+  enc/mktable.c      character type table generator.
+  enc/ascii.c        ASCII encoding.
+  enc/euc_jp.c       EUC-JP encoding.
+  enc/euc_tw.c       EUC-TW encoding.
+  enc/euc_kr.c       EUC-KR, EUC-CN encoding.
+  enc/sjis.c         Shift_JIS encoding.
+  enc/big5.c         Big5      encoding.
+  enc/gb18030.c      GB18030   encoding.
+  enc/koi8.c         KOI8      encoding.
+  enc/koi8_r.c       KOI8-R    encoding.
+  enc/cp1251.c       CP1251    encoding.
+  enc/iso8859_1.c    ISO-8859-1  encoding. (Latin-1)
+  enc/iso8859_2.c    ISO-8859-2  encoding. (Latin-2)
+  enc/iso8859_3.c    ISO-8859-3  encoding. (Latin-3)
+  enc/iso8859_4.c    ISO-8859-4  encoding. (Latin-4)
+  enc/iso8859_5.c    ISO-8859-5  encoding. (Cyrillic)
+  enc/iso8859_6.c    ISO-8859-6  encoding. (Arabic)
+  enc/iso8859_7.c    ISO-8859-7  encoding. (Greek)
+  enc/iso8859_8.c    ISO-8859-8  encoding. (Hebrew)
+  enc/iso8859_9.c    ISO-8859-9  encoding. (Latin-5 or Turkish)
+  enc/iso8859_10.c   ISO-8859-10 encoding. (Latin-6 or Nordic)
+  enc/iso8859_11.c   ISO-8859-11 encoding. (Thai)
+  enc/iso8859_13.c   ISO-8859-13 encoding. (Latin-7 or Baltic Rim)
+  enc/iso8859_14.c   ISO-8859-14 encoding. (Latin-8 or Celtic)
+  enc/iso8859_15.c   ISO-8859-15 encoding. (Latin-9 or West European with Euro)
+  enc/iso8859_16.c   ISO-8859-16 encoding.
+                     (Latin-10 or South-Eastern European with Euro)
+  enc/utf8.c         UTF-8    encoding.
+  enc/utf16_be.c     UTF-16BE encoding.
+  enc/utf16_le.c     UTF-16LE encoding.
+  enc/utf32_be.c     UTF-32BE encoding.
+  enc/utf32_le.c     UTF-32LE encoding.
+  enc/unicode.c      Unicode information data.
+
+  win32/Makefile     Makefile for Win32 (VC++)
+  win32/config.h     config.h for Win32
+
+
+
+ToDo
+
+  ? case fold flag: Katakana <-> Hiragana.
+  ? add ONIG_OPTION_NOTBOS/NOTEOS. (\A, \z, \Z)
+ ?? \X (== \PM\pM*)
+ ?? implement syntax behavior ONIG_SYN_CONTEXT_INDEP_ANCHORS.
+ ?? transmission stopper. (return ONIG_STOP from match_at())
+
+and I'm thankful to Akinori MUSHA.
+
+
+Mail Address: K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/config.h
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/config.h	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/config.h	(revision 331)
@@ -0,0 +1,124 @@
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+   systems. This function is required for `alloca.c' support on those systems.
+   */
+#undef CRAY_STACKSEG_END
+
+/* Define to 1 if using `alloca.c'. */
+#undef C_ALLOCA
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#define HAVE_ALLOCA
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+   */
+#define HAVE_ALLOCA_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/times.h> header file. */
+#define HAVE_SYS_TIMES_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#undef LT_OBJDIR
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#undef NO_MINUS_C_MINUS_O
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* The size of `int', as computed by sizeof. */
+#undef SIZEOF_INT
+#define SIZEOF_INT 4
+
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+#define SIZEOF_LONG 4
+
+/* The size of `short', as computed by sizeof. */
+#undef SIZEOF_SHORT
+#define SIZEOF_SHORT 2
+
+/* The size of `void*', as computed by sizeof. */
+#undef SIZEOF_VOIDP
+#define SIZEOF_VOIDP 4
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at runtime.
+	STACK_DIRECTION > 0 => grows toward higher addresses
+	STACK_DIRECTION < 0 => grows toward lower addresses
+	STACK_DIRECTION = 0 => direction of growth unknown */
+#undef STACK_DIRECTION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define if combination explosion check */
+#undef USE_COMBINATION_EXPLOSION_CHECK
+
+/* Define if enable CR+NL as line terminator */
+#undef USE_CRNL_AS_LINE_TERMINATOR
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/enc/ascii.c
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/enc/ascii.c	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/enc/ascii.c	(revision 331)
@@ -0,0 +1,104 @@
+/**********************************************************************
+  ascii.c -  Onigmo (Oniguruma-mod) (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2006  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011       K.Takata  <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "regenc.h"
+#ifdef RUBY
+# include "encindex.h"
+#endif
+
+#ifndef ENCINDEX_ASCII
+# define ENCINDEX_ASCII 0
+#endif
+
+OnigEncodingDefine(ascii, ASCII) = {
+  onigenc_single_byte_mbc_enc_len,
+  "ASCII-8BIT",/* name */
+  1,           /* max byte length */
+  1,           /* min byte length */
+  onigenc_is_mbc_newline_0x0a,
+  onigenc_single_byte_mbc_to_code,
+  onigenc_single_byte_code_to_mbclen,
+  onigenc_single_byte_code_to_mbc,
+  onigenc_ascii_mbc_case_fold,
+  onigenc_ascii_apply_all_case_fold,
+  onigenc_ascii_get_case_fold_codes_by_str,
+  onigenc_minimum_property_name_to_ctype,
+  onigenc_ascii_is_code_ctype,
+  onigenc_not_support_get_ctype_code_range,
+  onigenc_single_byte_left_adjust_char_head,
+  onigenc_always_true_is_allowed_reverse_match,
+  onigenc_single_byte_ascii_only_case_map,
+  ENCINDEX_ASCII,
+  ONIGENC_FLAG_NONE,
+};
+ENC_ALIAS("BINARY", "ASCII-8BIT")
+ENC_REPLICATE("IBM437", "ASCII-8BIT")
+ENC_ALIAS("CP437", "IBM437")
+ENC_REPLICATE("IBM737", "ASCII-8BIT")
+ENC_ALIAS("CP737", "IBM737")
+ENC_REPLICATE("IBM775", "ASCII-8BIT")
+ENC_ALIAS("CP775", "IBM775")
+ENC_REPLICATE("CP850", "ASCII-8BIT")
+ENC_ALIAS("IBM850", "CP850")
+ENC_REPLICATE("IBM852", "ASCII-8BIT")
+ENC_REPLICATE("CP852", "IBM852")
+ENC_REPLICATE("IBM855", "ASCII-8BIT")
+ENC_REPLICATE("CP855", "IBM855")
+ENC_REPLICATE("IBM857", "ASCII-8BIT")
+ENC_ALIAS("CP857", "IBM857")
+ENC_REPLICATE("IBM860", "ASCII-8BIT")
+ENC_ALIAS("CP860", "IBM860")
+ENC_REPLICATE("IBM861", "ASCII-8BIT")
+ENC_ALIAS("CP861", "IBM861")
+ENC_REPLICATE("IBM862", "ASCII-8BIT")
+ENC_ALIAS("CP862", "IBM862")
+ENC_REPLICATE("IBM863", "ASCII-8BIT")
+ENC_ALIAS("CP863", "IBM863")
+ENC_REPLICATE("IBM864", "ASCII-8BIT")
+ENC_ALIAS("CP864", "IBM864")
+ENC_REPLICATE("IBM865", "ASCII-8BIT")
+ENC_ALIAS("CP865", "IBM865")
+ENC_REPLICATE("IBM866", "ASCII-8BIT")
+ENC_ALIAS("CP866", "IBM866")
+ENC_REPLICATE("IBM869", "ASCII-8BIT")
+ENC_ALIAS("CP869", "IBM869")
+ENC_REPLICATE("Windows-1258", "ASCII-8BIT")
+ENC_ALIAS("CP1258", "Windows-1258")
+ENC_REPLICATE("GB1988", "ASCII-8BIT")
+ENC_REPLICATE("macCentEuro", "ASCII-8BIT")
+ENC_REPLICATE("macCroatian", "ASCII-8BIT")
+ENC_REPLICATE("macCyrillic", "ASCII-8BIT")
+ENC_REPLICATE("macGreek", "ASCII-8BIT")
+ENC_REPLICATE("macIceland", "ASCII-8BIT")
+ENC_REPLICATE("macRoman", "ASCII-8BIT")
+ENC_REPLICATE("macRomania", "ASCII-8BIT")
+ENC_REPLICATE("macThai", "ASCII-8BIT")
+ENC_REPLICATE("macTurkish", "ASCII-8BIT")
+ENC_REPLICATE("macUkraine", "ASCII-8BIT")
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/enc/unicode.c
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/enc/unicode.c	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/enc/unicode.c	(revision 331)
@@ -0,0 +1,805 @@
+/**********************************************************************
+  unicode.c -  Oniguruma (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2013  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "regint.h"
+
+#define ONIGENC_IS_UNICODE_ISO_8859_1_CTYPE(code,ctype) \
+  ((EncUNICODE_ISO_8859_1_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
+#if 0
+#define ONIGENC_IS_UNICODE_ISO_8859_1_BIT_CTYPE(code,cbit) \
+  ((EncUNICODE_ISO_8859_1_CtypeTable[code] & (cbit)) != 0)
+#endif
+
+static const unsigned short EncUNICODE_ISO_8859_1_CtypeTable[256] = {
+  0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+  0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+  0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+  0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+  0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+  0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+  0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+  0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+  0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+  0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+  0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+  0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+  0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+  0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+  0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+  0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
+  0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0288, 0x0008, 0x0008,
+  0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
+  0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
+  0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
+  0x0284, 0x01a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0,
+  0x00a0, 0x00a0, 0x30e2, 0x01a0, 0x00a0, 0x00a8, 0x00a0, 0x00a0,
+  0x00a0, 0x00a0, 0x10a0, 0x10a0, 0x00a0, 0x30e2, 0x00a0, 0x01a0,
+  0x00a0, 0x10a0, 0x30e2, 0x01a0, 0x10a0, 0x10a0, 0x10a0, 0x01a0,
+  0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+  0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+  0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x00a0,
+  0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x30e2,
+  0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+  0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+  0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x00a0,
+  0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2
+};
+
+typedef struct {
+  int n;
+  OnigCodePoint code[3];
+} CodePointList3;
+
+typedef struct {
+  OnigCodePoint  from;
+  CodePointList3 to;
+} CaseFold_11_Type;
+
+typedef struct {
+  OnigCodePoint  from;
+  CodePointList3 to;
+} CaseUnfold_11_Type;
+
+typedef struct {
+  int n;
+  OnigCodePoint code[2];
+} CodePointList2;
+
+typedef struct {
+  OnigCodePoint  from[2];
+  CodePointList2 to;
+} CaseUnfold_12_Type;
+
+typedef struct {
+  OnigCodePoint  from[3];
+  CodePointList2 to;
+} CaseUnfold_13_Type;
+
+static inline int
+bits_of(const OnigCodePoint c, const int n)
+{
+  return (c >> (2 - n) * 7) & 127;
+}
+
+static inline int
+bits_at(const OnigCodePoint *c, const int n)
+{
+  return bits_of(c[n / 3], n % 3);
+}
+
+static int
+code1_equal(const OnigCodePoint x, const OnigCodePoint y)
+{
+  if (x != y) return 0;
+  return 1;
+}
+
+static int
+code2_equal(const OnigCodePoint *x, const OnigCodePoint *y)
+{
+  if (x[0] != y[0]) return 0;
+  if (x[1] != y[1]) return 0;
+  return 1;
+}
+
+static int
+code3_equal(const OnigCodePoint *x, const OnigCodePoint *y)
+{
+  if (x[0] != y[0]) return 0;
+  if (x[1] != y[1]) return 0;
+  if (x[2] != y[2]) return 0;
+  return 1;
+}
+
+/* macros related to ONIGENC_CASE flags */
+/* defined here because not used in other files */
+#define ONIGENC_CASE_SPECIALS       (ONIGENC_CASE_TITLECASE | ONIGENC_CASE_IS_TITLECASE | ONIGENC_CASE_UP_SPECIAL | ONIGENC_CASE_DOWN_SPECIAL)
+
+/* macros for length in CaseMappingSpecials array in enc/unicode/casefold.h */
+#define SpecialsLengthOffset 25  /* needs to be higher than the 22 bits used for Unicode codepoints */
+#define SpecialsLengthExtract(n)    ((n) >> SpecialsLengthOffset)
+#define SpecialsCodepointExtract(n) ((n) & ((1 << SpecialsLengthOffset) - 1))
+#define SpecialsLengthEncode(n)     ((n) << SpecialsLengthOffset)
+
+#define OnigSpecialIndexMask        (((1 << OnigSpecialIndexWidth) - 1) << OnigSpecialIndexShift)
+#define OnigSpecialIndexEncode(n)   ((n) << OnigSpecialIndexShift)
+#define OnigSpecialIndexDecode(n)   (((n) & OnigSpecialIndexMask) >> OnigSpecialIndexShift)
+
+/* macros to shorten "enc/unicode/casefold.h", undefined immediately after including the file */
+#define U ONIGENC_CASE_UPCASE
+#define D ONIGENC_CASE_DOWNCASE
+#define F ONIGENC_CASE_FOLD
+#define ST ONIGENC_CASE_TITLECASE
+#define SU ONIGENC_CASE_UP_SPECIAL
+#define SL ONIGENC_CASE_DOWN_SPECIAL
+#define IT ONIGENC_CASE_IS_TITLECASE
+#define I(n) OnigSpecialIndexEncode(n)
+#define L(n) SpecialsLengthEncode(n)
+
+#include "casefold.h"
+
+#undef U
+#undef D
+#undef F
+#undef ST
+#undef SU
+#undef SL
+#undef IT
+#undef I
+#undef L
+
+#include "name2ctype.h"
+
+#define CODE_RANGES_NUM numberof(CodeRanges)
+
+extern int
+onigenc_unicode_is_code_ctype(OnigCodePoint code, unsigned int ctype, OnigEncoding enc ARG_UNUSED)
+{
+  if (
+#ifdef USE_UNICODE_PROPERTIES
+      ctype <= ONIGENC_MAX_STD_CTYPE &&
+#endif
+      code < 256) {
+    return ONIGENC_IS_UNICODE_ISO_8859_1_CTYPE(code, ctype);
+  }
+
+  if (ctype >= CODE_RANGES_NUM) {
+    return ONIGERR_TYPE_BUG;
+  }
+
+  return onig_is_in_code_range((UChar* )CodeRanges[ctype], code);
+}
+
+
+extern int
+onigenc_unicode_ctype_code_range(int ctype, const OnigCodePoint* ranges[])
+{
+  if (ctype >= CODE_RANGES_NUM) {
+    return ONIGERR_TYPE_BUG;
+  }
+
+  *ranges = CodeRanges[ctype];
+
+  return 0;
+}
+
+extern int
+onigenc_utf16_32_get_ctype_code_range(OnigCtype ctype, OnigCodePoint* sb_out,
+                                      const OnigCodePoint* ranges[],
+				      OnigEncoding enc ARG_UNUSED)
+{
+  *sb_out = 0x00;
+  return onigenc_unicode_ctype_code_range(ctype, ranges);
+}
+
+#define PROPERTY_NAME_MAX_SIZE    (MAX_WORD_LENGTH + 1)
+
+extern int
+onigenc_unicode_property_name_to_ctype(OnigEncoding enc, const UChar* name, const UChar* end)
+{
+  int len;
+  int ctype;
+  UChar buf[PROPERTY_NAME_MAX_SIZE];
+  const UChar *p;
+  OnigCodePoint code;
+
+  len = 0;
+  for (p = name; p < end; p += enclen(enc, p, end)) {
+    code = ONIGENC_MBC_TO_CODE(enc, p, end);
+    if (code == ' ' || code == '-' || code == '_')
+      continue;
+    if (code >= 0x80)
+      return ONIGERR_INVALID_CHAR_PROPERTY_NAME;
+
+    buf[len++] = ONIGENC_ASCII_CODE_TO_LOWER_CASE(code);
+    if (len >= PROPERTY_NAME_MAX_SIZE)
+      return ONIGERR_INVALID_CHAR_PROPERTY_NAME;
+  }
+
+  buf[len] = 0;
+
+  if ((ctype = uniname2ctype(buf, len)) < 0) {
+    return ONIGERR_INVALID_CHAR_PROPERTY_NAME;
+  }
+
+  return ctype;
+}
+
+#define onigenc_unicode_fold_lookup onigenc_unicode_CaseFold_11_lookup
+#define onigenc_unicode_unfold1_lookup onigenc_unicode_CaseUnfold_11_lookup
+#define onigenc_unicode_unfold2_lookup onigenc_unicode_CaseUnfold_12_lookup
+#define onigenc_unicode_unfold3_lookup onigenc_unicode_CaseUnfold_13_lookup
+
+enum {
+  I_WITH_DOT_ABOVE = 0x0130,
+  DOTLESS_i = 0x0131,
+  DOT_ABOVE = 0x0307
+};
+
+extern int
+onigenc_unicode_mbc_case_fold(OnigEncoding enc,
+    OnigCaseFoldType flag ARG_UNUSED, const UChar** pp, const UChar* end,
+    UChar* fold)
+{
+  const CodePointList3 *to;
+  OnigCodePoint code;
+  int i, len, rlen;
+  const UChar *p = *pp;
+
+  code = ONIGENC_MBC_TO_CODE(enc, p, end);
+  len = enclen(enc, p, end);
+  *pp += len;
+
+#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
+  if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) != 0) {
+    if (code == 'I') {
+      return ONIGENC_CODE_TO_MBC(enc, DOTLESS_i, fold);
+    }
+    else if (code == I_WITH_DOT_ABOVE) {
+      return ONIGENC_CODE_TO_MBC(enc, 'i', fold);
+    }
+  }
+#endif
+
+  if ((to = onigenc_unicode_fold_lookup(code)) != 0) {
+    if (OnigCodePointCount(to->n) == 1) {
+      return ONIGENC_CODE_TO_MBC(enc, to->code[0], fold);
+    }
+#if 0
+    /* NO NEEDS TO CHECK */
+    else if ((flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0)
+#else
+    else
+#endif
+    {
+      rlen = 0;
+      for (i = 0; i < OnigCodePointCount(to->n); i++) {
+	len = ONIGENC_CODE_TO_MBC(enc, to->code[i], fold);
+	fold += len;
+	rlen += len;
+      }
+      return rlen;
+    }
+  }
+
+  for (i = 0; i < len; i++) {
+    *fold++ = *p++;
+  }
+  return len;
+}
+
+extern int
+onigenc_unicode_apply_all_case_fold(OnigCaseFoldType flag,
+				    OnigApplyAllCaseFoldFunc f, void* arg,
+				    OnigEncoding enc ARG_UNUSED)
+{
+  const CaseUnfold_11_Type* p11;
+  OnigCodePoint code;
+  int i, j, k, r;
+
+  for (i = 0; i < numberof(CaseUnfold_11); i++) {
+    p11 = &CaseUnfold_11[i];
+    for (j = 0; j < OnigCodePointCount(p11->to.n); j++) {
+      code = p11->from;
+      r = (*f)(p11->to.code[j], &code, 1, arg);
+      if (r != 0) return r;
+
+      code = p11->to.code[j];
+      r = (*f)(p11->from, &code, 1, arg);
+      if (r != 0) return r;
+
+      for (k = 0; k < j; k++) {
+	r = (*f)(p11->to.code[j], (OnigCodePoint* )(&p11->to.code[k]), 1, arg);
+	if (r != 0) return r;
+
+	r = (*f)(p11->to.code[k], (OnigCodePoint* )(&p11->to.code[j]), 1, arg);
+	if (r != 0) return r;
+      }
+    }
+  }
+
+#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
+  if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) != 0) {
+    code = DOTLESS_i;
+    r = (*f)('I', &code, 1, arg);
+    if (r != 0) return r;
+    code = 'I';
+    r = (*f)(DOTLESS_i, &code, 1, arg);
+    if (r != 0) return r;
+
+    code = I_WITH_DOT_ABOVE;
+    r = (*f)('i', &code, 1, arg);
+    if (r != 0) return r;
+    code = 'i';
+    r = (*f)(I_WITH_DOT_ABOVE, &code, 1, arg);
+    if (r != 0) return r;
+  }
+  else {
+#endif
+    for (i = 0; i < numberof(CaseUnfold_11_Locale); i++) {
+      p11 = &CaseUnfold_11_Locale[i];
+      for (j = 0; j < OnigCodePointCount(p11->to.n); j++) {
+	code = p11->from;
+	r = (*f)(p11->to.code[j], &code, 1, arg);
+	if (r != 0) return r;
+
+	code = p11->to.code[j];
+	r = (*f)(p11->from, &code, 1, arg);
+	if (r != 0) return r;
+
+	for (k = 0; k < j; k++) {
+	  r = (*f)(p11->to.code[j], (OnigCodePoint* )(&p11->to.code[k]),
+		   1, arg);
+	  if (r != 0) return r;
+
+	  r = (*f)(p11->to.code[k], (OnigCodePoint* )(&p11->to.code[j]),
+		   1, arg);
+	  if (r != 0) return r;
+	}
+      }
+    }
+#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
+  }
+#endif
+
+  if ((flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+    for (i = 0; i < numberof(CaseUnfold_12); i++) {
+      for (j = 0; j < OnigCodePointCount(CaseUnfold_12[i].to.n); j++) {
+	r = (*f)(CaseUnfold_12[i].to.code[j],
+		 (OnigCodePoint* )CaseUnfold_12[i].from, 2, arg);
+	if (r != 0) return r;
+
+	for (k = 0; k < OnigCodePointCount(CaseUnfold_12[i].to.n); k++) {
+	  if (k == j) continue;
+
+	  r = (*f)(CaseUnfold_12[i].to.code[j],
+		   (OnigCodePoint* )(&CaseUnfold_12[i].to.code[k]), 1, arg);
+	  if (r != 0) return r;
+	}
+      }
+    }
+
+#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
+    if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) == 0) {
+#endif
+      for (i = 0; i < numberof(CaseUnfold_12_Locale); i++) {
+	for (j = 0; j < OnigCodePointCount(CaseUnfold_12_Locale[i].to.n); j++) {
+	  r = (*f)(CaseUnfold_12_Locale[i].to.code[j],
+		   (OnigCodePoint* )CaseUnfold_12_Locale[i].from, 2, arg);
+	  if (r != 0) return r;
+
+	  for (k = 0; k < OnigCodePointCount(CaseUnfold_12_Locale[i].to.n); k++) {
+	    if (k == j) continue;
+
+	    r = (*f)(CaseUnfold_12_Locale[i].to.code[j],
+		     (OnigCodePoint* )(&CaseUnfold_12_Locale[i].to.code[k]),
+		     1, arg);
+	    if (r != 0) return r;
+	  }
+	}
+      }
+#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
+    }
+#endif
+
+    for (i = 0; i < numberof(CaseUnfold_13); i++) {
+      for (j = 0; j < OnigCodePointCount(CaseUnfold_13[i].to.n); j++) {
+	r = (*f)(CaseUnfold_13[i].to.code[j],
+		 (OnigCodePoint* )CaseUnfold_13[i].from, 3, arg);
+	if (r != 0) return r;
+
+	for (k = 0; k < OnigCodePointCount(CaseUnfold_13[i].to.n); k++) {
+	  if (k == j) continue;
+
+	  r = (*f)(CaseUnfold_13[i].to.code[j],
+		   (OnigCodePoint* )(&CaseUnfold_13[i].to.code[k]), 1, arg);
+	  if (r != 0) return r;
+	}
+      }
+    }
+  }
+
+  return 0;
+}
+
+#define CodePointListValidP(x) (OnigCodePointCount((x)->n) <= numberof((x)->code))
+
+extern int
+onigenc_unicode_get_case_fold_codes_by_str(OnigEncoding enc,
+    OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end,
+    OnigCaseFoldCodeItem items[])
+{
+  int n, i, j, k, len;
+  OnigCodePoint code, codes[3];
+  const CodePointList3 *to, *z3;
+  const CodePointList2 *z2;
+
+  n = 0;
+
+  code = ONIGENC_MBC_TO_CODE(enc, p, end);
+  len = enclen(enc, p, end);
+
+#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
+  if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) != 0) {
+    switch (code) {
+    case 'I':
+      items[0].byte_len = len;
+      items[0].code_len = 1;
+      items[0].code[0]  = DOTLESS_i;
+      return 1;
+    case I_WITH_DOT_ABOVE:
+      items[0].byte_len = len;
+      items[0].code_len = 1;
+      items[0].code[0]  = 'i';
+      return 1;
+    case DOTLESS_i:
+      items[0].byte_len = len;
+      items[0].code_len = 1;
+      items[0].code[0]  = 'I';
+      return 1;
+    case 'i':
+      items[0].byte_len = len;
+      items[0].code_len = 1;
+      items[0].code[0]  = I_WITH_DOT_ABOVE;
+      return 1;
+    }
+  }
+#endif
+
+  if ((to = onigenc_unicode_fold_lookup(code)) != 0) {
+    if (OnigCodePointCount(to->n) == 1) {
+      OnigCodePoint orig_code = code;
+
+      items[0].byte_len = len;
+      items[0].code_len = 1;
+      items[0].code[0]  = to->code[0];
+      n++;
+
+      code = to->code[0];
+      if ((to = onigenc_unicode_unfold1_lookup(code)) != 0 &&
+	  CodePointListValidP(to)) {
+	for (i = 0; i < OnigCodePointCount(to->n); i++) {
+	  if (to->code[i] != orig_code) {
+	    items[n].byte_len = len;
+	    items[n].code_len = 1;
+	    items[n].code[0]  = to->code[i];
+	    n++;
+	  }
+	}
+      }
+    }
+    else if ((flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+      OnigCodePoint cs[3][4];
+      int fn, ncs[3];
+
+      for (fn = 0; fn < OnigCodePointCount(to->n); fn++) {
+	cs[fn][0] = to->code[fn];
+	if ((z3 = onigenc_unicode_unfold1_lookup(cs[fn][0])) != 0) {
+	  for (i = 0; i < OnigCodePointCount(z3->n); i++) {
+	    cs[fn][i+1] = z3->code[i];
+	  }
+	  ncs[fn] = OnigCodePointCount(z3->n) + 1;
+	}
+	else
+	  ncs[fn] = 1;
+      }
+
+      if (fn == 2) {
+	for (i = 0; i < ncs[0]; i++) {
+	  for (j = 0; j < ncs[1]; j++) {
+	    items[n].byte_len = len;
+	    items[n].code_len = 2;
+	    items[n].code[0]  = cs[0][i];
+	    items[n].code[1]  = cs[1][j];
+	    n++;
+	  }
+	}
+
+	if ((z2 = onigenc_unicode_unfold2_lookup(to->code)) != 0 &&
+	    CodePointListValidP(z2)) {
+	  for (i = 0; i < OnigCodePointCount(z2->n); i++) {
+	    if (z2->code[i] == code) continue;
+
+	    items[n].byte_len = len;
+	    items[n].code_len = 1;
+	    items[n].code[0]  = z2->code[i];
+	    n++;
+	  }
+	}
+      }
+      else {
+	for (i = 0; i < ncs[0]; i++) {
+	  for (j = 0; j < ncs[1]; j++) {
+	    for (k = 0; k < ncs[2]; k++) {
+	      items[n].byte_len = len;
+	      items[n].code_len = 3;
+	      items[n].code[0]  = cs[0][i];
+	      items[n].code[1]  = cs[1][j];
+	      items[n].code[2]  = cs[2][k];
+	      n++;
+	    }
+	  }
+	}
+
+	if ((z2 = onigenc_unicode_unfold3_lookup(to->code)) != 0 &&
+	    CodePointListValidP(z2)) {
+	  for (i = 0; i < OnigCodePointCount(z2->n); i++) {
+	    if (z2->code[i] == code) continue;
+
+	    items[n].byte_len = len;
+	    items[n].code_len = 1;
+	    items[n].code[0]  = z2->code[i];
+	    n++;
+	  }
+	}
+      }
+
+      /* multi char folded code is not head of another folded multi char */
+      flag = 0; /* DISABLE_CASE_FOLD_MULTI_CHAR(flag); */
+    }
+  }
+  else {
+    if ((to = onigenc_unicode_unfold1_lookup(code)) != 0 &&
+	CodePointListValidP(to)) {
+      for (i = 0; i < OnigCodePointCount(to->n); i++) {
+	items[n].byte_len = len;
+	items[n].code_len = 1;
+	items[n].code[0]  = to->code[i];
+	n++;
+      }
+    }
+  }
+
+
+  if ((flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+    p += len;
+    if (p < end) {
+      int clen;
+
+      codes[0] = code;
+      code = ONIGENC_MBC_TO_CODE(enc, p, end);
+      if ((to = onigenc_unicode_fold_lookup(code)) != 0
+	  && OnigCodePointCount(to->n) == 1) {
+	codes[1] = to->code[0];
+      }
+      else
+	codes[1] = code;
+
+      clen = enclen(enc, p, end);
+      len += clen;
+      if ((z2 = onigenc_unicode_unfold2_lookup(codes)) != 0 &&
+	  CodePointListValidP(z2)) {
+	for (i = 0; i < OnigCodePointCount(z2->n); i++) {
+	  items[n].byte_len = len;
+	  items[n].code_len = 1;
+	  items[n].code[0]  = z2->code[i];
+	  n++;
+	}
+      }
+
+      p += clen;
+      if (p < end) {
+	code = ONIGENC_MBC_TO_CODE(enc, p, end);
+	if ((to = onigenc_unicode_fold_lookup(code)) != 0
+	    && OnigCodePointCount(to->n) == 1) {
+	  codes[2] = to->code[0];
+	}
+	else
+	  codes[2] = code;
+
+	clen = enclen(enc, p, end);
+	len += clen;
+	if ((z2 = onigenc_unicode_unfold3_lookup(codes)) != 0 &&
+	    CodePointListValidP(z2)) {
+	  for (i = 0; i < OnigCodePointCount(z2->n); i++) {
+	    items[n].byte_len = len;
+	    items[n].code_len = 1;
+	    items[n].code[0]  = z2->code[i];
+	    n++;
+	  }
+	}
+      }
+    }
+  }
+
+  return n;
+}
+
+/* length in bytes for three characters in UTF-32; e.g. needed for ffi (U+FB03) */
+#define CASE_MAPPING_SLACK 12
+#define MODIFIED (flags |= ONIGENC_CASE_MODIFIED)
+extern int
+onigenc_unicode_case_map(OnigCaseFoldType* flagP,
+    const OnigUChar** pp, const OnigUChar* end,
+    OnigUChar* to, OnigUChar* to_end,
+    const struct OnigEncodingTypeST* enc)
+{
+  OnigCodePoint code;
+  OnigUChar *to_start = to;
+  OnigCaseFoldType flags = *flagP;
+  int codepoint_length;
+
+  to_end -= CASE_MAPPING_SLACK;
+  /* copy flags ONIGENC_CASE_UPCASE     and ONIGENC_CASE_DOWNCASE over to
+   *            ONIGENC_CASE_UP_SPECIAL and ONIGENC_CASE_DOWN_SPECIAL */
+  flags |= (flags & (ONIGENC_CASE_UPCASE | ONIGENC_CASE_DOWNCASE)) << ONIGENC_CASE_SPECIAL_OFFSET;
+
+  while (*pp < end && to <= to_end) {
+    codepoint_length = ONIGENC_PRECISE_MBC_ENC_LEN(enc, *pp, end);
+    if (codepoint_length < 0)
+      return codepoint_length; /* encoding invalid */
+    code = ONIGENC_MBC_TO_CODE(enc, *pp, end);
+    *pp += codepoint_length;
+
+    if (code <= 'z') { /* ASCII comes first */
+      if (code >= 'a' && code <= 'z') {
+	if (flags & ONIGENC_CASE_UPCASE) {
+	  MODIFIED;
+	  if (flags & ONIGENC_CASE_FOLD_TURKISH_AZERI && code == 'i')
+	    code = I_WITH_DOT_ABOVE;
+	  else
+	    code += 'A' - 'a';
+	}
+      }
+      else if (code >= 'A' && code <= 'Z') {
+	if (flags & (ONIGENC_CASE_DOWNCASE | ONIGENC_CASE_FOLD)) {
+	  MODIFIED;
+	  if (flags & ONIGENC_CASE_FOLD_TURKISH_AZERI && code == 'I')
+	    code = DOTLESS_i;
+	  else
+	    code += 'a' - 'A';
+	}
+      }
+    }
+    else if (!(flags & ONIGENC_CASE_ASCII_ONLY) && code >= 0x00B5) { /* deal with non-ASCII; micron sign (U+00B5) is lowest affected */
+      const CodePointList3 *folded;
+
+      if (code == I_WITH_DOT_ABOVE) {
+	if (flags & (ONIGENC_CASE_DOWNCASE | ONIGENC_CASE_FOLD)) {
+	  MODIFIED;
+	  code = 'i';
+	  if (!(flags & ONIGENC_CASE_FOLD_TURKISH_AZERI)) { /* make dot above explicit */
+	    to += ONIGENC_CODE_TO_MBC(enc, code, to);
+	    code = DOT_ABOVE;
+	  }
+	}
+      }
+      else if (code == DOTLESS_i) { /* handle this manually, because it isn't involved in folding */
+	if (flags & ONIGENC_CASE_UPCASE) {
+	  MODIFIED;
+	  code = 'I';
+	}
+      }
+      else if ((folded = onigenc_unicode_fold_lookup(code)) != 0) { /* data about character found in CaseFold_11_Table */
+	if ((flags & ONIGENC_CASE_TITLECASE)                                 /* Titlecase needed, */
+	    && (OnigCaseFoldFlags(folded->n) & ONIGENC_CASE_IS_TITLECASE)) { /* but already Titlecase  */
+	  /* already Titlecase, no changes needed */
+	}
+	else if (flags & OnigCaseFoldFlags(folded->n)) { /* needs and data availability match */
+	  const OnigCodePoint *next;
+	  int count;
+
+	  MODIFIED;
+	  if (flags & OnigCaseFoldFlags(folded->n) & ONIGENC_CASE_SPECIALS) { /* special */
+	    const OnigCodePoint *SpecialsStart = CaseMappingSpecials + OnigSpecialIndexDecode(folded->n);
+
+	    if (OnigCaseFoldFlags(folded->n) & ONIGENC_CASE_IS_TITLECASE) { /* swapCASE available */
+	      if ((flags & (ONIGENC_CASE_UPCASE | ONIGENC_CASE_DOWNCASE))
+		  == (ONIGENC_CASE_UPCASE | ONIGENC_CASE_DOWNCASE)) /* swapCASE needed */
+		goto SpecialsCopy;
+	      else /* swapCASE not needed */
+		SpecialsStart += SpecialsLengthExtract(*SpecialsStart);
+	    }
+	    if (OnigCaseFoldFlags(folded->n) & ONIGENC_CASE_TITLECASE) { /* Titlecase available */
+	      if (flags & ONIGENC_CASE_TITLECASE) /* Titlecase needed, but not yet Titlecase */
+		goto SpecialsCopy;
+	      else /* Titlecase not needed */
+		SpecialsStart += SpecialsLengthExtract(*SpecialsStart);
+	    }
+	    if (OnigCaseFoldFlags(folded->n) & ONIGENC_CASE_DOWN_SPECIAL) {
+	      if (!(flags & ONIGENC_CASE_DOWN_SPECIAL))
+		SpecialsStart += SpecialsLengthExtract(*SpecialsStart);
+	    }
+	    /* here, we know we use ONIGENC_CASE_UP_SPECIAL, and the position is right */
+SpecialsCopy:
+	    count = SpecialsLengthExtract(*SpecialsStart);
+	    next = SpecialsStart;
+	    code = SpecialsCodepointExtract(*next++);
+	  }
+	  else { /* no specials */
+	    count = OnigCodePointCount(folded->n);
+	    next = folded->code;
+	    code = *next++;
+	  }
+	  if (count == 1)
+	    ;
+	  else if (count == 2) {
+	    to += ONIGENC_CODE_TO_MBC(enc, code, to);
+	    code = *next;
+	  }
+	  else { /* count == 3 */
+	    to += ONIGENC_CODE_TO_MBC(enc, code, to);
+	    to += ONIGENC_CODE_TO_MBC(enc, *next++, to);
+	    code = *next;
+	  }
+	}
+      }
+      else if ((folded = onigenc_unicode_unfold1_lookup(code)) != 0  /* data about character found in CaseUnfold_11_Table */
+	  && flags & OnigCaseFoldFlags(folded->n)) { /* needs and data availability match */
+	MODIFIED;
+	code = folded->code[(flags & OnigCaseFoldFlags(folded->n) & ONIGENC_CASE_TITLECASE) ? 1 : 0];
+      }
+    }
+    to += ONIGENC_CODE_TO_MBC(enc, code, to);
+    /* switch from titlecase to lowercase for capitalize */
+    if (flags & ONIGENC_CASE_TITLECASE)
+      flags ^= (ONIGENC_CASE_UPCASE | ONIGENC_CASE_DOWNCASE | ONIGENC_CASE_TITLECASE |
+	  ONIGENC_CASE_UP_SPECIAL | ONIGENC_CASE_DOWN_SPECIAL);
+  }
+  *flagP = flags;
+  return (int )(to - to_start);
+}
+
+#if 0
+const char onigenc_unicode_version_string[] =
+#ifdef ONIG_UNICODE_VERSION_STRING
+    ONIG_UNICODE_VERSION_STRING
+#endif
+    "";
+
+const int onigenc_unicode_version_number[3] = {
+#ifdef ONIG_UNICODE_VERSION_MAJOR
+    ONIG_UNICODE_VERSION_MAJOR,
+    ONIG_UNICODE_VERSION_MINOR,
+    ONIG_UNICODE_VERSION_TEENY,
+#else
+    0
+#endif
+};
+#endif
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/enc/unicode/casefold.h
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/enc/unicode/casefold.h	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/enc/unicode/casefold.h	(revision 331)
@@ -0,0 +1,7044 @@
+/* DO NOT EDIT THIS FILE. */
+/* Generated by tool/case-folding.rb */
+
+#if defined ONIG_UNICODE_VERSION_STRING && !( \
+      ONIG_UNICODE_VERSION_MAJOR == 10 && \
+      ONIG_UNICODE_VERSION_MINOR == 0 && \
+      ONIG_UNICODE_VERSION_TEENY == 0 && \
+      1)
+# error ONIG_UNICODE_VERSION_STRING mismatch
+#endif
+#define ONIG_UNICODE_VERSION_STRING "10.0.0"
+#define ONIG_UNICODE_VERSION_MAJOR 10
+#define ONIG_UNICODE_VERSION_MINOR 0
+#define ONIG_UNICODE_VERSION_TEENY 0
+
+static const CaseFold_11_Type CaseFold_11_Table[] = {
+#define CaseFold (*(CaseFold_11_Type (*)[1399])(CaseFold_11_Table+0))
+  {0x0041, {1|F|D, {0x0061}}},
+  {0x0042, {1|F|D, {0x0062}}},
+  {0x0043, {1|F|D, {0x0063}}},
+  {0x0044, {1|F|D, {0x0064}}},
+  {0x0045, {1|F|D, {0x0065}}},
+  {0x0046, {1|F|D, {0x0066}}},
+  {0x0047, {1|F|D, {0x0067}}},
+  {0x0048, {1|F|D, {0x0068}}},
+  {0x004a, {1|F|D, {0x006a}}},
+  {0x004b, {1|F|D, {0x006b}}},
+  {0x004c, {1|F|D, {0x006c}}},
+  {0x004d, {1|F|D, {0x006d}}},
+  {0x004e, {1|F|D, {0x006e}}},
+  {0x004f, {1|F|D, {0x006f}}},
+  {0x0050, {1|F|D, {0x0070}}},
+  {0x0051, {1|F|D, {0x0071}}},
+  {0x0052, {1|F|D, {0x0072}}},
+  {0x0053, {1|F|D, {0x0073}}},
+  {0x0054, {1|F|D, {0x0074}}},
+  {0x0055, {1|F|D, {0x0075}}},
+  {0x0056, {1|F|D, {0x0076}}},
+  {0x0057, {1|F|D, {0x0077}}},
+  {0x0058, {1|F|D, {0x0078}}},
+  {0x0059, {1|F|D, {0x0079}}},
+  {0x005a, {1|F|D, {0x007a}}},
+  {0x00b5, {1|F|SU|I(0), {0x03bc}}},
+  {0x00c0, {1|F|D, {0x00e0}}},
+  {0x00c1, {1|F|D, {0x00e1}}},
+  {0x00c2, {1|F|D, {0x00e2}}},
+  {0x00c3, {1|F|D, {0x00e3}}},
+  {0x00c4, {1|F|D, {0x00e4}}},
+  {0x00c5, {1|F|D, {0x00e5}}},
+  {0x00c6, {1|F|D, {0x00e6}}},
+  {0x00c7, {1|F|D, {0x00e7}}},
+  {0x00c8, {1|F|D, {0x00e8}}},
+  {0x00c9, {1|F|D, {0x00e9}}},
+  {0x00ca, {1|F|D, {0x00ea}}},
+  {0x00cb, {1|F|D, {0x00eb}}},
+  {0x00cc, {1|F|D, {0x00ec}}},
+  {0x00cd, {1|F|D, {0x00ed}}},
+  {0x00ce, {1|F|D, {0x00ee}}},
+  {0x00cf, {1|F|D, {0x00ef}}},
+  {0x00d0, {1|F|D, {0x00f0}}},
+  {0x00d1, {1|F|D, {0x00f1}}},
+  {0x00d2, {1|F|D, {0x00f2}}},
+  {0x00d3, {1|F|D, {0x00f3}}},
+  {0x00d4, {1|F|D, {0x00f4}}},
+  {0x00d5, {1|F|D, {0x00f5}}},
+  {0x00d6, {1|F|D, {0x00f6}}},
+  {0x00d8, {1|F|D, {0x00f8}}},
+  {0x00d9, {1|F|D, {0x00f9}}},
+  {0x00da, {1|F|D, {0x00fa}}},
+  {0x00db, {1|F|D, {0x00fb}}},
+  {0x00dc, {1|F|D, {0x00fc}}},
+  {0x00dd, {1|F|D, {0x00fd}}},
+  {0x00de, {1|F|D, {0x00fe}}},
+  {0x00df, {2|F|ST|SU|I(1), {0x0073, 0x0073}}},
+  {0x0100, {1|F|D, {0x0101}}},
+  {0x0102, {1|F|D, {0x0103}}},
+  {0x0104, {1|F|D, {0x0105}}},
+  {0x0106, {1|F|D, {0x0107}}},
+  {0x0108, {1|F|D, {0x0109}}},
+  {0x010a, {1|F|D, {0x010b}}},
+  {0x010c, {1|F|D, {0x010d}}},
+  {0x010e, {1|F|D, {0x010f}}},
+  {0x0110, {1|F|D, {0x0111}}},
+  {0x0112, {1|F|D, {0x0113}}},
+  {0x0114, {1|F|D, {0x0115}}},
+  {0x0116, {1|F|D, {0x0117}}},
+  {0x0118, {1|F|D, {0x0119}}},
+  {0x011a, {1|F|D, {0x011b}}},
+  {0x011c, {1|F|D, {0x011d}}},
+  {0x011e, {1|F|D, {0x011f}}},
+  {0x0120, {1|F|D, {0x0121}}},
+  {0x0122, {1|F|D, {0x0123}}},
+  {0x0124, {1|F|D, {0x0125}}},
+  {0x0126, {1|F|D, {0x0127}}},
+  {0x0128, {1|F|D, {0x0129}}},
+  {0x012a, {1|F|D, {0x012b}}},
+  {0x012c, {1|F|D, {0x012d}}},
+  {0x012e, {1|F|D, {0x012f}}},
+  {0x0132, {1|F|D, {0x0133}}},
+  {0x0134, {1|F|D, {0x0135}}},
+  {0x0136, {1|F|D, {0x0137}}},
+  {0x0139, {1|F|D, {0x013a}}},
+  {0x013b, {1|F|D, {0x013c}}},
+  {0x013d, {1|F|D, {0x013e}}},
+  {0x013f, {1|F|D, {0x0140}}},
+  {0x0141, {1|F|D, {0x0142}}},
+  {0x0143, {1|F|D, {0x0144}}},
+  {0x0145, {1|F|D, {0x0146}}},
+  {0x0147, {1|F|D, {0x0148}}},
+  {0x0149, {2|F|SU|I(5), {0x02bc, 0x006e}}},
+  {0x014a, {1|F|D, {0x014b}}},
+  {0x014c, {1|F|D, {0x014d}}},
+  {0x014e, {1|F|D, {0x014f}}},
+  {0x0150, {1|F|D, {0x0151}}},
+  {0x0152, {1|F|D, {0x0153}}},
+  {0x0154, {1|F|D, {0x0155}}},
+  {0x0156, {1|F|D, {0x0157}}},
+  {0x0158, {1|F|D, {0x0159}}},
+  {0x015a, {1|F|D, {0x015b}}},
+  {0x015c, {1|F|D, {0x015d}}},
+  {0x015e, {1|F|D, {0x015f}}},
+  {0x0160, {1|F|D, {0x0161}}},
+  {0x0162, {1|F|D, {0x0163}}},
+  {0x0164, {1|F|D, {0x0165}}},
+  {0x0166, {1|F|D, {0x0167}}},
+  {0x0168, {1|F|D, {0x0169}}},
+  {0x016a, {1|F|D, {0x016b}}},
+  {0x016c, {1|F|D, {0x016d}}},
+  {0x016e, {1|F|D, {0x016f}}},
+  {0x0170, {1|F|D, {0x0171}}},
+  {0x0172, {1|F|D, {0x0173}}},
+  {0x0174, {1|F|D, {0x0175}}},
+  {0x0176, {1|F|D, {0x0177}}},
+  {0x0178, {1|F|D, {0x00ff}}},
+  {0x0179, {1|F|D, {0x017a}}},
+  {0x017b, {1|F|D, {0x017c}}},
+  {0x017d, {1|F|D, {0x017e}}},
+  {0x017f, {1|F|SU|I(7), {0x0073}}},
+  {0x0181, {1|F|D, {0x0253}}},
+  {0x0182, {1|F|D, {0x0183}}},
+  {0x0184, {1|F|D, {0x0185}}},
+  {0x0186, {1|F|D, {0x0254}}},
+  {0x0187, {1|F|D, {0x0188}}},
+  {0x0189, {1|F|D, {0x0256}}},
+  {0x018a, {1|F|D, {0x0257}}},
+  {0x018b, {1|F|D, {0x018c}}},
+  {0x018e, {1|F|D, {0x01dd}}},
+  {0x018f, {1|F|D, {0x0259}}},
+  {0x0190, {1|F|D, {0x025b}}},
+  {0x0191, {1|F|D, {0x0192}}},
+  {0x0193, {1|F|D, {0x0260}}},
+  {0x0194, {1|F|D, {0x0263}}},
+  {0x0196, {1|F|D, {0x0269}}},
+  {0x0197, {1|F|D, {0x0268}}},
+  {0x0198, {1|F|D, {0x0199}}},
+  {0x019c, {1|F|D, {0x026f}}},
+  {0x019d, {1|F|D, {0x0272}}},
+  {0x019f, {1|F|D, {0x0275}}},
+  {0x01a0, {1|F|D, {0x01a1}}},
+  {0x01a2, {1|F|D, {0x01a3}}},
+  {0x01a4, {1|F|D, {0x01a5}}},
+  {0x01a6, {1|F|D, {0x0280}}},
+  {0x01a7, {1|F|D, {0x01a8}}},
+  {0x01a9, {1|F|D, {0x0283}}},
+  {0x01ac, {1|F|D, {0x01ad}}},
+  {0x01ae, {1|F|D, {0x0288}}},
+  {0x01af, {1|F|D, {0x01b0}}},
+  {0x01b1, {1|F|D, {0x028a}}},
+  {0x01b2, {1|F|D, {0x028b}}},
+  {0x01b3, {1|F|D, {0x01b4}}},
+  {0x01b5, {1|F|D, {0x01b6}}},
+  {0x01b7, {1|F|D, {0x0292}}},
+  {0x01b8, {1|F|D, {0x01b9}}},
+  {0x01bc, {1|F|D, {0x01bd}}},
+  {0x01c4, {1|F|D|ST|I(8), {0x01c6}}},
+  {0x01c5, {1|F|D|IT|SU|I(9), {0x01c6}}},
+  {0x01c7, {1|F|D|ST|I(12), {0x01c9}}},
+  {0x01c8, {1|F|D|IT|SU|I(13), {0x01c9}}},
+  {0x01ca, {1|F|D|ST|I(16), {0x01cc}}},
+  {0x01cb, {1|F|D|IT|SU|I(17), {0x01cc}}},
+  {0x01cd, {1|F|D, {0x01ce}}},
+  {0x01cf, {1|F|D, {0x01d0}}},
+  {0x01d1, {1|F|D, {0x01d2}}},
+  {0x01d3, {1|F|D, {0x01d4}}},
+  {0x01d5, {1|F|D, {0x01d6}}},
+  {0x01d7, {1|F|D, {0x01d8}}},
+  {0x01d9, {1|F|D, {0x01da}}},
+  {0x01db, {1|F|D, {0x01dc}}},
+  {0x01de, {1|F|D, {0x01df}}},
+  {0x01e0, {1|F|D, {0x01e1}}},
+  {0x01e2, {1|F|D, {0x01e3}}},
+  {0x01e4, {1|F|D, {0x01e5}}},
+  {0x01e6, {1|F|D, {0x01e7}}},
+  {0x01e8, {1|F|D, {0x01e9}}},
+  {0x01ea, {1|F|D, {0x01eb}}},
+  {0x01ec, {1|F|D, {0x01ed}}},
+  {0x01ee, {1|F|D, {0x01ef}}},
+  {0x01f0, {2|F|SU|I(20), {0x006a, 0x030c}}},
+  {0x01f1, {1|F|D|ST|I(22), {0x01f3}}},
+  {0x01f2, {1|F|D|IT|SU|I(23), {0x01f3}}},
+  {0x01f4, {1|F|D, {0x01f5}}},
+  {0x01f6, {1|F|D, {0x0195}}},
+  {0x01f7, {1|F|D, {0x01bf}}},
+  {0x01f8, {1|F|D, {0x01f9}}},
+  {0x01fa, {1|F|D, {0x01fb}}},
+  {0x01fc, {1|F|D, {0x01fd}}},
+  {0x01fe, {1|F|D, {0x01ff}}},
+  {0x0200, {1|F|D, {0x0201}}},
+  {0x0202, {1|F|D, {0x0203}}},
+  {0x0204, {1|F|D, {0x0205}}},
+  {0x0206, {1|F|D, {0x0207}}},
+  {0x0208, {1|F|D, {0x0209}}},
+  {0x020a, {1|F|D, {0x020b}}},
+  {0x020c, {1|F|D, {0x020d}}},
+  {0x020e, {1|F|D, {0x020f}}},
+  {0x0210, {1|F|D, {0x0211}}},
+  {0x0212, {1|F|D, {0x0213}}},
+  {0x0214, {1|F|D, {0x0215}}},
+  {0x0216, {1|F|D, {0x0217}}},
+  {0x0218, {1|F|D, {0x0219}}},
+  {0x021a, {1|F|D, {0x021b}}},
+  {0x021c, {1|F|D, {0x021d}}},
+  {0x021e, {1|F|D, {0x021f}}},
+  {0x0220, {1|F|D, {0x019e}}},
+  {0x0222, {1|F|D, {0x0223}}},
+  {0x0224, {1|F|D, {0x0225}}},
+  {0x0226, {1|F|D, {0x0227}}},
+  {0x0228, {1|F|D, {0x0229}}},
+  {0x022a, {1|F|D, {0x022b}}},
+  {0x022c, {1|F|D, {0x022d}}},
+  {0x022e, {1|F|D, {0x022f}}},
+  {0x0230, {1|F|D, {0x0231}}},
+  {0x0232, {1|F|D, {0x0233}}},
+  {0x023a, {1|F|D, {0x2c65}}},
+  {0x023b, {1|F|D, {0x023c}}},
+  {0x023d, {1|F|D, {0x019a}}},
+  {0x023e, {1|F|D, {0x2c66}}},
+  {0x0241, {1|F|D, {0x0242}}},
+  {0x0243, {1|F|D, {0x0180}}},
+  {0x0244, {1|F|D, {0x0289}}},
+  {0x0245, {1|F|D, {0x028c}}},
+  {0x0246, {1|F|D, {0x0247}}},
+  {0x0248, {1|F|D, {0x0249}}},
+  {0x024a, {1|F|D, {0x024b}}},
+  {0x024c, {1|F|D, {0x024d}}},
+  {0x024e, {1|F|D, {0x024f}}},
+  {0x0345, {1|F|SU|I(26), {0x03b9}}},
+  {0x0370, {1|F|D, {0x0371}}},
+  {0x0372, {1|F|D, {0x0373}}},
+  {0x0376, {1|F|D, {0x0377}}},
+  {0x037f, {1|F|D, {0x03f3}}},
+  {0x0386, {1|F|D, {0x03ac}}},
+  {0x0388, {1|F|D, {0x03ad}}},
+  {0x0389, {1|F|D, {0x03ae}}},
+  {0x038a, {1|F|D, {0x03af}}},
+  {0x038c, {1|F|D, {0x03cc}}},
+  {0x038e, {1|F|D, {0x03cd}}},
+  {0x038f, {1|F|D, {0x03ce}}},
+  {0x0390, {3|F|SU|I(27), {0x03b9, 0x0308, 0x0301}}},
+  {0x0391, {1|F|D, {0x03b1}}},
+  {0x0392, {1|F|D, {0x03b2}}},
+  {0x0393, {1|F|D, {0x03b3}}},
+  {0x0394, {1|F|D, {0x03b4}}},
+  {0x0395, {1|F|D, {0x03b5}}},
+  {0x0396, {1|F|D, {0x03b6}}},
+  {0x0397, {1|F|D, {0x03b7}}},
+  {0x0398, {1|F|D, {0x03b8}}},
+  {0x0399, {1|F|D, {0x03b9}}},
+  {0x039a, {1|F|D, {0x03ba}}},
+  {0x039b, {1|F|D, {0x03bb}}},
+  {0x039c, {1|F|D, {0x03bc}}},
+  {0x039d, {1|F|D, {0x03bd}}},
+  {0x039e, {1|F|D, {0x03be}}},
+  {0x039f, {1|F|D, {0x03bf}}},
+  {0x03a0, {1|F|D, {0x03c0}}},
+  {0x03a1, {1|F|D, {0x03c1}}},
+  {0x03a3, {1|F|D, {0x03c3}}},
+  {0x03a4, {1|F|D, {0x03c4}}},
+  {0x03a5, {1|F|D, {0x03c5}}},
+  {0x03a6, {1|F|D, {0x03c6}}},
+  {0x03a7, {1|F|D, {0x03c7}}},
+  {0x03a8, {1|F|D, {0x03c8}}},
+  {0x03a9, {1|F|D, {0x03c9}}},
+  {0x03aa, {1|F|D, {0x03ca}}},
+  {0x03ab, {1|F|D, {0x03cb}}},
+  {0x03b0, {3|F|SU|I(30), {0x03c5, 0x0308, 0x0301}}},
+  {0x03c2, {1|F|SU|I(33), {0x03c3}}},
+  {0x03cf, {1|F|D, {0x03d7}}},
+  {0x03d0, {1|F|SU|I(34), {0x03b2}}},
+  {0x03d1, {1|F|SU|I(35), {0x03b8}}},
+  {0x03d5, {1|F|SU|I(36), {0x03c6}}},
+  {0x03d6, {1|F|SU|I(37), {0x03c0}}},
+  {0x03d8, {1|F|D, {0x03d9}}},
+  {0x03da, {1|F|D, {0x03db}}},
+  {0x03dc, {1|F|D, {0x03dd}}},
+  {0x03de, {1|F|D, {0x03df}}},
+  {0x03e0, {1|F|D, {0x03e1}}},
+  {0x03e2, {1|F|D, {0x03e3}}},
+  {0x03e4, {1|F|D, {0x03e5}}},
+  {0x03e6, {1|F|D, {0x03e7}}},
+  {0x03e8, {1|F|D, {0x03e9}}},
+  {0x03ea, {1|F|D, {0x03eb}}},
+  {0x03ec, {1|F|D, {0x03ed}}},
+  {0x03ee, {1|F|D, {0x03ef}}},
+  {0x03f0, {1|F|SU|I(38), {0x03ba}}},
+  {0x03f1, {1|F|SU|I(39), {0x03c1}}},
+  {0x03f4, {1|F|D, {0x03b8}}},
+  {0x03f5, {1|F|SU|I(40), {0x03b5}}},
+  {0x03f7, {1|F|D, {0x03f8}}},
+  {0x03f9, {1|F|D, {0x03f2}}},
+  {0x03fa, {1|F|D, {0x03fb}}},
+  {0x03fd, {1|F|D, {0x037b}}},
+  {0x03fe, {1|F|D, {0x037c}}},
+  {0x03ff, {1|F|D, {0x037d}}},
+  {0x0400, {1|F|D, {0x0450}}},
+  {0x0401, {1|F|D, {0x0451}}},
+  {0x0402, {1|F|D, {0x0452}}},
+  {0x0403, {1|F|D, {0x0453}}},
+  {0x0404, {1|F|D, {0x0454}}},
+  {0x0405, {1|F|D, {0x0455}}},
+  {0x0406, {1|F|D, {0x0456}}},
+  {0x0407, {1|F|D, {0x0457}}},
+  {0x0408, {1|F|D, {0x0458}}},
+  {0x0409, {1|F|D, {0x0459}}},
+  {0x040a, {1|F|D, {0x045a}}},
+  {0x040b, {1|F|D, {0x045b}}},
+  {0x040c, {1|F|D, {0x045c}}},
+  {0x040d, {1|F|D, {0x045d}}},
+  {0x040e, {1|F|D, {0x045e}}},
+  {0x040f, {1|F|D, {0x045f}}},
+  {0x0410, {1|F|D, {0x0430}}},
+  {0x0411, {1|F|D, {0x0431}}},
+  {0x0412, {1|F|D, {0x0432}}},
+  {0x0413, {1|F|D, {0x0433}}},
+  {0x0414, {1|F|D, {0x0434}}},
+  {0x0415, {1|F|D, {0x0435}}},
+  {0x0416, {1|F|D, {0x0436}}},
+  {0x0417, {1|F|D, {0x0437}}},
+  {0x0418, {1|F|D, {0x0438}}},
+  {0x0419, {1|F|D, {0x0439}}},
+  {0x041a, {1|F|D, {0x043a}}},
+  {0x041b, {1|F|D, {0x043b}}},
+  {0x041c, {1|F|D, {0x043c}}},
+  {0x041d, {1|F|D, {0x043d}}},
+  {0x041e, {1|F|D, {0x043e}}},
+  {0x041f, {1|F|D, {0x043f}}},
+  {0x0420, {1|F|D, {0x0440}}},
+  {0x0421, {1|F|D, {0x0441}}},
+  {0x0422, {1|F|D, {0x0442}}},
+  {0x0423, {1|F|D, {0x0443}}},
+  {0x0424, {1|F|D, {0x0444}}},
+  {0x0425, {1|F|D, {0x0445}}},
+  {0x0426, {1|F|D, {0x0446}}},
+  {0x0427, {1|F|D, {0x0447}}},
+  {0x0428, {1|F|D, {0x0448}}},
+  {0x0429, {1|F|D, {0x0449}}},
+  {0x042a, {1|F|D, {0x044a}}},
+  {0x042b, {1|F|D, {0x044b}}},
+  {0x042c, {1|F|D, {0x044c}}},
+  {0x042d, {1|F|D, {0x044d}}},
+  {0x042e, {1|F|D, {0x044e}}},
+  {0x042f, {1|F|D, {0x044f}}},
+  {0x0460, {1|F|D, {0x0461}}},
+  {0x0462, {1|F|D, {0x0463}}},
+  {0x0464, {1|F|D, {0x0465}}},
+  {0x0466, {1|F|D, {0x0467}}},
+  {0x0468, {1|F|D, {0x0469}}},
+  {0x046a, {1|F|D, {0x046b}}},
+  {0x046c, {1|F|D, {0x046d}}},
+  {0x046e, {1|F|D, {0x046f}}},
+  {0x0470, {1|F|D, {0x0471}}},
+  {0x0472, {1|F|D, {0x0473}}},
+  {0x0474, {1|F|D, {0x0475}}},
+  {0x0476, {1|F|D, {0x0477}}},
+  {0x0478, {1|F|D, {0x0479}}},
+  {0x047a, {1|F|D, {0x047b}}},
+  {0x047c, {1|F|D, {0x047d}}},
+  {0x047e, {1|F|D, {0x047f}}},
+  {0x0480, {1|F|D, {0x0481}}},
+  {0x048a, {1|F|D, {0x048b}}},
+  {0x048c, {1|F|D, {0x048d}}},
+  {0x048e, {1|F|D, {0x048f}}},
+  {0x0490, {1|F|D, {0x0491}}},
+  {0x0492, {1|F|D, {0x0493}}},
+  {0x0494, {1|F|D, {0x0495}}},
+  {0x0496, {1|F|D, {0x0497}}},
+  {0x0498, {1|F|D, {0x0499}}},
+  {0x049a, {1|F|D, {0x049b}}},
+  {0x049c, {1|F|D, {0x049d}}},
+  {0x049e, {1|F|D, {0x049f}}},
+  {0x04a0, {1|F|D, {0x04a1}}},
+  {0x04a2, {1|F|D, {0x04a3}}},
+  {0x04a4, {1|F|D, {0x04a5}}},
+  {0x04a6, {1|F|D, {0x04a7}}},
+  {0x04a8, {1|F|D, {0x04a9}}},
+  {0x04aa, {1|F|D, {0x04ab}}},
+  {0x04ac, {1|F|D, {0x04ad}}},
+  {0x04ae, {1|F|D, {0x04af}}},
+  {0x04b0, {1|F|D, {0x04b1}}},
+  {0x04b2, {1|F|D, {0x04b3}}},
+  {0x04b4, {1|F|D, {0x04b5}}},
+  {0x04b6, {1|F|D, {0x04b7}}},
+  {0x04b8, {1|F|D, {0x04b9}}},
+  {0x04ba, {1|F|D, {0x04bb}}},
+  {0x04bc, {1|F|D, {0x04bd}}},
+  {0x04be, {1|F|D, {0x04bf}}},
+  {0x04c0, {1|F|D, {0x04cf}}},
+  {0x04c1, {1|F|D, {0x04c2}}},
+  {0x04c3, {1|F|D, {0x04c4}}},
+  {0x04c5, {1|F|D, {0x04c6}}},
+  {0x04c7, {1|F|D, {0x04c8}}},
+  {0x04c9, {1|F|D, {0x04ca}}},
+  {0x04cb, {1|F|D, {0x04cc}}},
+  {0x04cd, {1|F|D, {0x04ce}}},
+  {0x04d0, {1|F|D, {0x04d1}}},
+  {0x04d2, {1|F|D, {0x04d3}}},
+  {0x04d4, {1|F|D, {0x04d5}}},
+  {0x04d6, {1|F|D, {0x04d7}}},
+  {0x04d8, {1|F|D, {0x04d9}}},
+  {0x04da, {1|F|D, {0x04db}}},
+  {0x04dc, {1|F|D, {0x04dd}}},
+  {0x04de, {1|F|D, {0x04df}}},
+  {0x04e0, {1|F|D, {0x04e1}}},
+  {0x04e2, {1|F|D, {0x04e3}}},
+  {0x04e4, {1|F|D, {0x04e5}}},
+  {0x04e6, {1|F|D, {0x04e7}}},
+  {0x04e8, {1|F|D, {0x04e9}}},
+  {0x04ea, {1|F|D, {0x04eb}}},
+  {0x04ec, {1|F|D, {0x04ed}}},
+  {0x04ee, {1|F|D, {0x04ef}}},
+  {0x04f0, {1|F|D, {0x04f1}}},
+  {0x04f2, {1|F|D, {0x04f3}}},
+  {0x04f4, {1|F|D, {0x04f5}}},
+  {0x04f6, {1|F|D, {0x04f7}}},
+  {0x04f8, {1|F|D, {0x04f9}}},
+  {0x04fa, {1|F|D, {0x04fb}}},
+  {0x04fc, {1|F|D, {0x04fd}}},
+  {0x04fe, {1|F|D, {0x04ff}}},
+  {0x0500, {1|F|D, {0x0501}}},
+  {0x0502, {1|F|D, {0x0503}}},
+  {0x0504, {1|F|D, {0x0505}}},
+  {0x0506, {1|F|D, {0x0507}}},
+  {0x0508, {1|F|D, {0x0509}}},
+  {0x050a, {1|F|D, {0x050b}}},
+  {0x050c, {1|F|D, {0x050d}}},
+  {0x050e, {1|F|D, {0x050f}}},
+  {0x0510, {1|F|D, {0x0511}}},
+  {0x0512, {1|F|D, {0x0513}}},
+  {0x0514, {1|F|D, {0x0515}}},
+  {0x0516, {1|F|D, {0x0517}}},
+  {0x0518, {1|F|D, {0x0519}}},
+  {0x051a, {1|F|D, {0x051b}}},
+  {0x051c, {1|F|D, {0x051d}}},
+  {0x051e, {1|F|D, {0x051f}}},
+  {0x0520, {1|F|D, {0x0521}}},
+  {0x0522, {1|F|D, {0x0523}}},
+  {0x0524, {1|F|D, {0x0525}}},
+  {0x0526, {1|F|D, {0x0527}}},
+  {0x0528, {1|F|D, {0x0529}}},
+  {0x052a, {1|F|D, {0x052b}}},
+  {0x052c, {1|F|D, {0x052d}}},
+  {0x052e, {1|F|D, {0x052f}}},
+  {0x0531, {1|F|D, {0x0561}}},
+  {0x0532, {1|F|D, {0x0562}}},
+  {0x0533, {1|F|D, {0x0563}}},
+  {0x0534, {1|F|D, {0x0564}}},
+  {0x0535, {1|F|D, {0x0565}}},
+  {0x0536, {1|F|D, {0x0566}}},
+  {0x0537, {1|F|D, {0x0567}}},
+  {0x0538, {1|F|D, {0x0568}}},
+  {0x0539, {1|F|D, {0x0569}}},
+  {0x053a, {1|F|D, {0x056a}}},
+  {0x053b, {1|F|D, {0x056b}}},
+  {0x053c, {1|F|D, {0x056c}}},
+  {0x053d, {1|F|D, {0x056d}}},
+  {0x053e, {1|F|D, {0x056e}}},
+  {0x053f, {1|F|D, {0x056f}}},
+  {0x0540, {1|F|D, {0x0570}}},
+  {0x0541, {1|F|D, {0x0571}}},
+  {0x0542, {1|F|D, {0x0572}}},
+  {0x0543, {1|F|D, {0x0573}}},
+  {0x0544, {1|F|D, {0x0574}}},
+  {0x0545, {1|F|D, {0x0575}}},
+  {0x0546, {1|F|D, {0x0576}}},
+  {0x0547, {1|F|D, {0x0577}}},
+  {0x0548, {1|F|D, {0x0578}}},
+  {0x0549, {1|F|D, {0x0579}}},
+  {0x054a, {1|F|D, {0x057a}}},
+  {0x054b, {1|F|D, {0x057b}}},
+  {0x054c, {1|F|D, {0x057c}}},
+  {0x054d, {1|F|D, {0x057d}}},
+  {0x054e, {1|F|D, {0x057e}}},
+  {0x054f, {1|F|D, {0x057f}}},
+  {0x0550, {1|F|D, {0x0580}}},
+  {0x0551, {1|F|D, {0x0581}}},
+  {0x0552, {1|F|D, {0x0582}}},
+  {0x0553, {1|F|D, {0x0583}}},
+  {0x0554, {1|F|D, {0x0584}}},
+  {0x0555, {1|F|D, {0x0585}}},
+  {0x0556, {1|F|D, {0x0586}}},
+  {0x0587, {2|F|ST|SU|I(41), {0x0565, 0x0582}}},
+  {0x10a0, {1|F|D, {0x2d00}}},
+  {0x10a1, {1|F|D, {0x2d01}}},
+  {0x10a2, {1|F|D, {0x2d02}}},
+  {0x10a3, {1|F|D, {0x2d03}}},
+  {0x10a4, {1|F|D, {0x2d04}}},
+  {0x10a5, {1|F|D, {0x2d05}}},
+  {0x10a6, {1|F|D, {0x2d06}}},
+  {0x10a7, {1|F|D, {0x2d07}}},
+  {0x10a8, {1|F|D, {0x2d08}}},
+  {0x10a9, {1|F|D, {0x2d09}}},
+  {0x10aa, {1|F|D, {0x2d0a}}},
+  {0x10ab, {1|F|D, {0x2d0b}}},
+  {0x10ac, {1|F|D, {0x2d0c}}},
+  {0x10ad, {1|F|D, {0x2d0d}}},
+  {0x10ae, {1|F|D, {0x2d0e}}},
+  {0x10af, {1|F|D, {0x2d0f}}},
+  {0x10b0, {1|F|D, {0x2d10}}},
+  {0x10b1, {1|F|D, {0x2d11}}},
+  {0x10b2, {1|F|D, {0x2d12}}},
+  {0x10b3, {1|F|D, {0x2d13}}},
+  {0x10b4, {1|F|D, {0x2d14}}},
+  {0x10b5, {1|F|D, {0x2d15}}},
+  {0x10b6, {1|F|D, {0x2d16}}},
+  {0x10b7, {1|F|D, {0x2d17}}},
+  {0x10b8, {1|F|D, {0x2d18}}},
+  {0x10b9, {1|F|D, {0x2d19}}},
+  {0x10ba, {1|F|D, {0x2d1a}}},
+  {0x10bb, {1|F|D, {0x2d1b}}},
+  {0x10bc, {1|F|D, {0x2d1c}}},
+  {0x10bd, {1|F|D, {0x2d1d}}},
+  {0x10be, {1|F|D, {0x2d1e}}},
+  {0x10bf, {1|F|D, {0x2d1f}}},
+  {0x10c0, {1|F|D, {0x2d20}}},
+  {0x10c1, {1|F|D, {0x2d21}}},
+  {0x10c2, {1|F|D, {0x2d22}}},
+  {0x10c3, {1|F|D, {0x2d23}}},
+  {0x10c4, {1|F|D, {0x2d24}}},
+  {0x10c5, {1|F|D, {0x2d25}}},
+  {0x10c7, {1|F|D, {0x2d27}}},
+  {0x10cd, {1|F|D, {0x2d2d}}},
+  {0x13f8, {1|F|U, {0x13f0}}},
+  {0x13f9, {1|F|U, {0x13f1}}},
+  {0x13fa, {1|F|U, {0x13f2}}},
+  {0x13fb, {1|F|U, {0x13f3}}},
+  {0x13fc, {1|F|U, {0x13f4}}},
+  {0x13fd, {1|F|U, {0x13f5}}},
+  {0x1c80, {1|F|SU|I(45), {0x0432}}},
+  {0x1c81, {1|F|SU|I(46), {0x0434}}},
+  {0x1c82, {1|F|SU|I(47), {0x043e}}},
+  {0x1c83, {1|F|SU|I(48), {0x0441}}},
+  {0x1c84, {1|F|SU|I(49), {0x0442}}},
+  {0x1c85, {1|F|SU|I(50), {0x0442}}},
+  {0x1c86, {1|F|SU|I(51), {0x044a}}},
+  {0x1c87, {1|F|SU|I(52), {0x0463}}},
+  {0x1c88, {1|F|SU|I(53), {0xa64b}}},
+  {0x1e00, {1|F|D, {0x1e01}}},
+  {0x1e02, {1|F|D, {0x1e03}}},
+  {0x1e04, {1|F|D, {0x1e05}}},
+  {0x1e06, {1|F|D, {0x1e07}}},
+  {0x1e08, {1|F|D, {0x1e09}}},
+  {0x1e0a, {1|F|D, {0x1e0b}}},
+  {0x1e0c, {1|F|D, {0x1e0d}}},
+  {0x1e0e, {1|F|D, {0x1e0f}}},
+  {0x1e10, {1|F|D, {0x1e11}}},
+  {0x1e12, {1|F|D, {0x1e13}}},
+  {0x1e14, {1|F|D, {0x1e15}}},
+  {0x1e16, {1|F|D, {0x1e17}}},
+  {0x1e18, {1|F|D, {0x1e19}}},
+  {0x1e1a, {1|F|D, {0x1e1b}}},
+  {0x1e1c, {1|F|D, {0x1e1d}}},
+  {0x1e1e, {1|F|D, {0x1e1f}}},
+  {0x1e20, {1|F|D, {0x1e21}}},
+  {0x1e22, {1|F|D, {0x1e23}}},
+  {0x1e24, {1|F|D, {0x1e25}}},
+  {0x1e26, {1|F|D, {0x1e27}}},
+  {0x1e28, {1|F|D, {0x1e29}}},
+  {0x1e2a, {1|F|D, {0x1e2b}}},
+  {0x1e2c, {1|F|D, {0x1e2d}}},
+  {0x1e2e, {1|F|D, {0x1e2f}}},
+  {0x1e30, {1|F|D, {0x1e31}}},
+  {0x1e32, {1|F|D, {0x1e33}}},
+  {0x1e34, {1|F|D, {0x1e35}}},
+  {0x1e36, {1|F|D, {0x1e37}}},
+  {0x1e38, {1|F|D, {0x1e39}}},
+  {0x1e3a, {1|F|D, {0x1e3b}}},
+  {0x1e3c, {1|F|D, {0x1e3d}}},
+  {0x1e3e, {1|F|D, {0x1e3f}}},
+  {0x1e40, {1|F|D, {0x1e41}}},
+  {0x1e42, {1|F|D, {0x1e43}}},
+  {0x1e44, {1|F|D, {0x1e45}}},
+  {0x1e46, {1|F|D, {0x1e47}}},
+  {0x1e48, {1|F|D, {0x1e49}}},
+  {0x1e4a, {1|F|D, {0x1e4b}}},
+  {0x1e4c, {1|F|D, {0x1e4d}}},
+  {0x1e4e, {1|F|D, {0x1e4f}}},
+  {0x1e50, {1|F|D, {0x1e51}}},
+  {0x1e52, {1|F|D, {0x1e53}}},
+  {0x1e54, {1|F|D, {0x1e55}}},
+  {0x1e56, {1|F|D, {0x1e57}}},
+  {0x1e58, {1|F|D, {0x1e59}}},
+  {0x1e5a, {1|F|D, {0x1e5b}}},
+  {0x1e5c, {1|F|D, {0x1e5d}}},
+  {0x1e5e, {1|F|D, {0x1e5f}}},
+  {0x1e60, {1|F|D, {0x1e61}}},
+  {0x1e62, {1|F|D, {0x1e63}}},
+  {0x1e64, {1|F|D, {0x1e65}}},
+  {0x1e66, {1|F|D, {0x1e67}}},
+  {0x1e68, {1|F|D, {0x1e69}}},
+  {0x1e6a, {1|F|D, {0x1e6b}}},
+  {0x1e6c, {1|F|D, {0x1e6d}}},
+  {0x1e6e, {1|F|D, {0x1e6f}}},
+  {0x1e70, {1|F|D, {0x1e71}}},
+  {0x1e72, {1|F|D, {0x1e73}}},
+  {0x1e74, {1|F|D, {0x1e75}}},
+  {0x1e76, {1|F|D, {0x1e77}}},
+  {0x1e78, {1|F|D, {0x1e79}}},
+  {0x1e7a, {1|F|D, {0x1e7b}}},
+  {0x1e7c, {1|F|D, {0x1e7d}}},
+  {0x1e7e, {1|F|D, {0x1e7f}}},
+  {0x1e80, {1|F|D, {0x1e81}}},
+  {0x1e82, {1|F|D, {0x1e83}}},
+  {0x1e84, {1|F|D, {0x1e85}}},
+  {0x1e86, {1|F|D, {0x1e87}}},
+  {0x1e88, {1|F|D, {0x1e89}}},
+  {0x1e8a, {1|F|D, {0x1e8b}}},
+  {0x1e8c, {1|F|D, {0x1e8d}}},
+  {0x1e8e, {1|F|D, {0x1e8f}}},
+  {0x1e90, {1|F|D, {0x1e91}}},
+  {0x1e92, {1|F|D, {0x1e93}}},
+  {0x1e94, {1|F|D, {0x1e95}}},
+  {0x1e96, {2|F|SU|I(54), {0x0068, 0x0331}}},
+  {0x1e97, {2|F|SU|I(56), {0x0074, 0x0308}}},
+  {0x1e98, {2|F|SU|I(58), {0x0077, 0x030a}}},
+  {0x1e99, {2|F|SU|I(60), {0x0079, 0x030a}}},
+  {0x1e9a, {2|F|SU|I(62), {0x0061, 0x02be}}},
+  {0x1e9b, {1|F|SU|I(64), {0x1e61}}},
+  {0x1e9e, {2|F|SL|I(65), {0x0073, 0x0073}}},
+  {0x1ea0, {1|F|D, {0x1ea1}}},
+  {0x1ea2, {1|F|D, {0x1ea3}}},
+  {0x1ea4, {1|F|D, {0x1ea5}}},
+  {0x1ea6, {1|F|D, {0x1ea7}}},
+  {0x1ea8, {1|F|D, {0x1ea9}}},
+  {0x1eaa, {1|F|D, {0x1eab}}},
+  {0x1eac, {1|F|D, {0x1ead}}},
+  {0x1eae, {1|F|D, {0x1eaf}}},
+  {0x1eb0, {1|F|D, {0x1eb1}}},
+  {0x1eb2, {1|F|D, {0x1eb3}}},
+  {0x1eb4, {1|F|D, {0x1eb5}}},
+  {0x1eb6, {1|F|D, {0x1eb7}}},
+  {0x1eb8, {1|F|D, {0x1eb9}}},
+  {0x1eba, {1|F|D, {0x1ebb}}},
+  {0x1ebc, {1|F|D, {0x1ebd}}},
+  {0x1ebe, {1|F|D, {0x1ebf}}},
+  {0x1ec0, {1|F|D, {0x1ec1}}},
+  {0x1ec2, {1|F|D, {0x1ec3}}},
+  {0x1ec4, {1|F|D, {0x1ec5}}},
+  {0x1ec6, {1|F|D, {0x1ec7}}},
+  {0x1ec8, {1|F|D, {0x1ec9}}},
+  {0x1eca, {1|F|D, {0x1ecb}}},
+  {0x1ecc, {1|F|D, {0x1ecd}}},
+  {0x1ece, {1|F|D, {0x1ecf}}},
+  {0x1ed0, {1|F|D, {0x1ed1}}},
+  {0x1ed2, {1|F|D, {0x1ed3}}},
+  {0x1ed4, {1|F|D, {0x1ed5}}},
+  {0x1ed6, {1|F|D, {0x1ed7}}},
+  {0x1ed8, {1|F|D, {0x1ed9}}},
+  {0x1eda, {1|F|D, {0x1edb}}},
+  {0x1edc, {1|F|D, {0x1edd}}},
+  {0x1ede, {1|F|D, {0x1edf}}},
+  {0x1ee0, {1|F|D, {0x1ee1}}},
+  {0x1ee2, {1|F|D, {0x1ee3}}},
+  {0x1ee4, {1|F|D, {0x1ee5}}},
+  {0x1ee6, {1|F|D, {0x1ee7}}},
+  {0x1ee8, {1|F|D, {0x1ee9}}},
+  {0x1eea, {1|F|D, {0x1eeb}}},
+  {0x1eec, {1|F|D, {0x1eed}}},
+  {0x1eee, {1|F|D, {0x1eef}}},
+  {0x1ef0, {1|F|D, {0x1ef1}}},
+  {0x1ef2, {1|F|D, {0x1ef3}}},
+  {0x1ef4, {1|F|D, {0x1ef5}}},
+  {0x1ef6, {1|F|D, {0x1ef7}}},
+  {0x1ef8, {1|F|D, {0x1ef9}}},
+  {0x1efa, {1|F|D, {0x1efb}}},
+  {0x1efc, {1|F|D, {0x1efd}}},
+  {0x1efe, {1|F|D, {0x1eff}}},
+  {0x1f08, {1|F|D, {0x1f00}}},
+  {0x1f09, {1|F|D, {0x1f01}}},
+  {0x1f0a, {1|F|D, {0x1f02}}},
+  {0x1f0b, {1|F|D, {0x1f03}}},
+  {0x1f0c, {1|F|D, {0x1f04}}},
+  {0x1f0d, {1|F|D, {0x1f05}}},
+  {0x1f0e, {1|F|D, {0x1f06}}},
+  {0x1f0f, {1|F|D, {0x1f07}}},
+  {0x1f18, {1|F|D, {0x1f10}}},
+  {0x1f19, {1|F|D, {0x1f11}}},
+  {0x1f1a, {1|F|D, {0x1f12}}},
+  {0x1f1b, {1|F|D, {0x1f13}}},
+  {0x1f1c, {1|F|D, {0x1f14}}},
+  {0x1f1d, {1|F|D, {0x1f15}}},
+  {0x1f28, {1|F|D, {0x1f20}}},
+  {0x1f29, {1|F|D, {0x1f21}}},
+  {0x1f2a, {1|F|D, {0x1f22}}},
+  {0x1f2b, {1|F|D, {0x1f23}}},
+  {0x1f2c, {1|F|D, {0x1f24}}},
+  {0x1f2d, {1|F|D, {0x1f25}}},
+  {0x1f2e, {1|F|D, {0x1f26}}},
+  {0x1f2f, {1|F|D, {0x1f27}}},
+  {0x1f38, {1|F|D, {0x1f30}}},
+  {0x1f39, {1|F|D, {0x1f31}}},
+  {0x1f3a, {1|F|D, {0x1f32}}},
+  {0x1f3b, {1|F|D, {0x1f33}}},
+  {0x1f3c, {1|F|D, {0x1f34}}},
+  {0x1f3d, {1|F|D, {0x1f35}}},
+  {0x1f3e, {1|F|D, {0x1f36}}},
+  {0x1f3f, {1|F|D, {0x1f37}}},
+  {0x1f48, {1|F|D, {0x1f40}}},
+  {0x1f49, {1|F|D, {0x1f41}}},
+  {0x1f4a, {1|F|D, {0x1f42}}},
+  {0x1f4b, {1|F|D, {0x1f43}}},
+  {0x1f4c, {1|F|D, {0x1f44}}},
+  {0x1f4d, {1|F|D, {0x1f45}}},
+  {0x1f50, {2|F|SU|I(66), {0x03c5, 0x0313}}},
+  {0x1f52, {3|F|SU|I(68), {0x03c5, 0x0313, 0x0300}}},
+  {0x1f54, {3|F|SU|I(71), {0x03c5, 0x0313, 0x0301}}},
+  {0x1f56, {3|F|SU|I(74), {0x03c5, 0x0313, 0x0342}}},
+  {0x1f59, {1|F|D, {0x1f51}}},
+  {0x1f5b, {1|F|D, {0x1f53}}},
+  {0x1f5d, {1|F|D, {0x1f55}}},
+  {0x1f5f, {1|F|D, {0x1f57}}},
+  {0x1f68, {1|F|D, {0x1f60}}},
+  {0x1f69, {1|F|D, {0x1f61}}},
+  {0x1f6a, {1|F|D, {0x1f62}}},
+  {0x1f6b, {1|F|D, {0x1f63}}},
+  {0x1f6c, {1|F|D, {0x1f64}}},
+  {0x1f6d, {1|F|D, {0x1f65}}},
+  {0x1f6e, {1|F|D, {0x1f66}}},
+  {0x1f6f, {1|F|D, {0x1f67}}},
+  {0x1f80, {2|F|ST|SU|I(77), {0x1f00, 0x03b9}}},
+  {0x1f81, {2|F|ST|SU|I(80), {0x1f01, 0x03b9}}},
+  {0x1f82, {2|F|ST|SU|I(83), {0x1f02, 0x03b9}}},
+  {0x1f83, {2|F|ST|SU|I(86), {0x1f03, 0x03b9}}},
+  {0x1f84, {2|F|ST|SU|I(89), {0x1f04, 0x03b9}}},
+  {0x1f85, {2|F|ST|SU|I(92), {0x1f05, 0x03b9}}},
+  {0x1f86, {2|F|ST|SU|I(95), {0x1f06, 0x03b9}}},
+  {0x1f87, {2|F|ST|SU|I(98), {0x1f07, 0x03b9}}},
+  {0x1f88, {2|F|IT|SL|SU|I(101), {0x1f00, 0x03b9}}},
+  {0x1f89, {2|F|IT|SL|SU|I(106), {0x1f01, 0x03b9}}},
+  {0x1f8a, {2|F|IT|SL|SU|I(111), {0x1f02, 0x03b9}}},
+  {0x1f8b, {2|F|IT|SL|SU|I(116), {0x1f03, 0x03b9}}},
+  {0x1f8c, {2|F|IT|SL|SU|I(121), {0x1f04, 0x03b9}}},
+  {0x1f8d, {2|F|IT|SL|SU|I(126), {0x1f05, 0x03b9}}},
+  {0x1f8e, {2|F|IT|SL|SU|I(131), {0x1f06, 0x03b9}}},
+  {0x1f8f, {2|F|IT|SL|SU|I(136), {0x1f07, 0x03b9}}},
+  {0x1f90, {2|F|ST|SU|I(141), {0x1f20, 0x03b9}}},
+  {0x1f91, {2|F|ST|SU|I(144), {0x1f21, 0x03b9}}},
+  {0x1f92, {2|F|ST|SU|I(147), {0x1f22, 0x03b9}}},
+  {0x1f93, {2|F|ST|SU|I(150), {0x1f23, 0x03b9}}},
+  {0x1f94, {2|F|ST|SU|I(153), {0x1f24, 0x03b9}}},
+  {0x1f95, {2|F|ST|SU|I(156), {0x1f25, 0x03b9}}},
+  {0x1f96, {2|F|ST|SU|I(159), {0x1f26, 0x03b9}}},
+  {0x1f97, {2|F|ST|SU|I(162), {0x1f27, 0x03b9}}},
+  {0x1f98, {2|F|IT|SL|SU|I(165), {0x1f20, 0x03b9}}},
+  {0x1f99, {2|F|IT|SL|SU|I(170), {0x1f21, 0x03b9}}},
+  {0x1f9a, {2|F|IT|SL|SU|I(175), {0x1f22, 0x03b9}}},
+  {0x1f9b, {2|F|IT|SL|SU|I(180), {0x1f23, 0x03b9}}},
+  {0x1f9c, {2|F|IT|SL|SU|I(185), {0x1f24, 0x03b9}}},
+  {0x1f9d, {2|F|IT|SL|SU|I(190), {0x1f25, 0x03b9}}},
+  {0x1f9e, {2|F|IT|SL|SU|I(195), {0x1f26, 0x03b9}}},
+  {0x1f9f, {2|F|IT|SL|SU|I(200), {0x1f27, 0x03b9}}},
+  {0x1fa0, {2|F|ST|SU|I(205), {0x1f60, 0x03b9}}},
+  {0x1fa1, {2|F|ST|SU|I(208), {0x1f61, 0x03b9}}},
+  {0x1fa2, {2|F|ST|SU|I(211), {0x1f62, 0x03b9}}},
+  {0x1fa3, {2|F|ST|SU|I(214), {0x1f63, 0x03b9}}},
+  {0x1fa4, {2|F|ST|SU|I(217), {0x1f64, 0x03b9}}},
+  {0x1fa5, {2|F|ST|SU|I(220), {0x1f65, 0x03b9}}},
+  {0x1fa6, {2|F|ST|SU|I(223), {0x1f66, 0x03b9}}},
+  {0x1fa7, {2|F|ST|SU|I(226), {0x1f67, 0x03b9}}},
+  {0x1fa8, {2|F|IT|SL|SU|I(229), {0x1f60, 0x03b9}}},
+  {0x1fa9, {2|F|IT|SL|SU|I(234), {0x1f61, 0x03b9}}},
+  {0x1faa, {2|F|IT|SL|SU|I(239), {0x1f62, 0x03b9}}},
+  {0x1fab, {2|F|IT|SL|SU|I(244), {0x1f63, 0x03b9}}},
+  {0x1fac, {2|F|IT|SL|SU|I(249), {0x1f64, 0x03b9}}},
+  {0x1fad, {2|F|IT|SL|SU|I(254), {0x1f65, 0x03b9}}},
+  {0x1fae, {2|F|IT|SL|SU|I(259), {0x1f66, 0x03b9}}},
+  {0x1faf, {2|F|IT|SL|SU|I(264), {0x1f67, 0x03b9}}},
+  {0x1fb2, {2|F|ST|SU|I(269), {0x1f70, 0x03b9}}},
+  {0x1fb3, {2|F|ST|SU|I(273), {0x03b1, 0x03b9}}},
+  {0x1fb4, {2|F|ST|SU|I(276), {0x03ac, 0x03b9}}},
+  {0x1fb6, {2|F|SU|I(280), {0x03b1, 0x0342}}},
+  {0x1fb7, {3|F|ST|SU|I(282), {0x03b1, 0x0342, 0x03b9}}},
+  {0x1fb8, {1|F|D, {0x1fb0}}},
+  {0x1fb9, {1|F|D, {0x1fb1}}},
+  {0x1fba, {1|F|D, {0x1f70}}},
+  {0x1fbb, {1|F|D, {0x1f71}}},
+  {0x1fbc, {2|F|IT|SL|SU|I(288), {0x03b1, 0x03b9}}},
+  {0x1fbe, {1|F|SU|I(293), {0x03b9}}},
+  {0x1fc2, {2|F|ST|SU|I(294), {0x1f74, 0x03b9}}},
+  {0x1fc3, {2|F|ST|SU|I(298), {0x03b7, 0x03b9}}},
+  {0x1fc4, {2|F|ST|SU|I(301), {0x03ae, 0x03b9}}},
+  {0x1fc6, {2|F|SU|I(305), {0x03b7, 0x0342}}},
+  {0x1fc7, {3|F|ST|SU|I(307), {0x03b7, 0x0342, 0x03b9}}},
+  {0x1fc8, {1|F|D, {0x1f72}}},
+  {0x1fc9, {1|F|D, {0x1f73}}},
+  {0x1fca, {1|F|D, {0x1f74}}},
+  {0x1fcb, {1|F|D, {0x1f75}}},
+  {0x1fcc, {2|F|IT|SL|SU|I(313), {0x03b7, 0x03b9}}},
+  {0x1fd2, {3|F|SU|I(318), {0x03b9, 0x0308, 0x0300}}},
+  {0x1fd3, {3|F|SU|I(321), {0x03b9, 0x0308, 0x0301}}},
+  {0x1fd6, {2|F|SU|I(324), {0x03b9, 0x0342}}},
+  {0x1fd7, {3|F|SU|I(326), {0x03b9, 0x0308, 0x0342}}},
+  {0x1fd8, {1|F|D, {0x1fd0}}},
+  {0x1fd9, {1|F|D, {0x1fd1}}},
+  {0x1fda, {1|F|D, {0x1f76}}},
+  {0x1fdb, {1|F|D, {0x1f77}}},
+  {0x1fe2, {3|F|SU|I(329), {0x03c5, 0x0308, 0x0300}}},
+  {0x1fe3, {3|F|SU|I(332), {0x03c5, 0x0308, 0x0301}}},
+  {0x1fe4, {2|F|SU|I(335), {0x03c1, 0x0313}}},
+  {0x1fe6, {2|F|SU|I(337), {0x03c5, 0x0342}}},
+  {0x1fe7, {3|F|SU|I(339), {0x03c5, 0x0308, 0x0342}}},
+  {0x1fe8, {1|F|D, {0x1fe0}}},
+  {0x1fe9, {1|F|D, {0x1fe1}}},
+  {0x1fea, {1|F|D, {0x1f7a}}},
+  {0x1feb, {1|F|D, {0x1f7b}}},
+  {0x1fec, {1|F|D, {0x1fe5}}},
+  {0x1ff2, {2|F|ST|SU|I(342), {0x1f7c, 0x03b9}}},
+  {0x1ff3, {2|F|ST|SU|I(346), {0x03c9, 0x03b9}}},
+  {0x1ff4, {2|F|ST|SU|I(349), {0x03ce, 0x03b9}}},
+  {0x1ff6, {2|F|SU|I(353), {0x03c9, 0x0342}}},
+  {0x1ff7, {3|F|ST|SU|I(355), {0x03c9, 0x0342, 0x03b9}}},
+  {0x1ff8, {1|F|D, {0x1f78}}},
+  {0x1ff9, {1|F|D, {0x1f79}}},
+  {0x1ffa, {1|F|D, {0x1f7c}}},
+  {0x1ffb, {1|F|D, {0x1f7d}}},
+  {0x1ffc, {2|F|IT|SL|SU|I(361), {0x03c9, 0x03b9}}},
+  {0x2126, {1|F|D, {0x03c9}}},
+  {0x212a, {1|F|D, {0x006b}}},
+  {0x212b, {1|F|D, {0x00e5}}},
+  {0x2132, {1|F|D, {0x214e}}},
+  {0x2160, {1|F|D, {0x2170}}},
+  {0x2161, {1|F|D, {0x2171}}},
+  {0x2162, {1|F|D, {0x2172}}},
+  {0x2163, {1|F|D, {0x2173}}},
+  {0x2164, {1|F|D, {0x2174}}},
+  {0x2165, {1|F|D, {0x2175}}},
+  {0x2166, {1|F|D, {0x2176}}},
+  {0x2167, {1|F|D, {0x2177}}},
+  {0x2168, {1|F|D, {0x2178}}},
+  {0x2169, {1|F|D, {0x2179}}},
+  {0x216a, {1|F|D, {0x217a}}},
+  {0x216b, {1|F|D, {0x217b}}},
+  {0x216c, {1|F|D, {0x217c}}},
+  {0x216d, {1|F|D, {0x217d}}},
+  {0x216e, {1|F|D, {0x217e}}},
+  {0x216f, {1|F|D, {0x217f}}},
+  {0x2183, {1|F|D, {0x2184}}},
+  {0x24b6, {1|F|D, {0x24d0}}},
+  {0x24b7, {1|F|D, {0x24d1}}},
+  {0x24b8, {1|F|D, {0x24d2}}},
+  {0x24b9, {1|F|D, {0x24d3}}},
+  {0x24ba, {1|F|D, {0x24d4}}},
+  {0x24bb, {1|F|D, {0x24d5}}},
+  {0x24bc, {1|F|D, {0x24d6}}},
+  {0x24bd, {1|F|D, {0x24d7}}},
+  {0x24be, {1|F|D, {0x24d8}}},
+  {0x24bf, {1|F|D, {0x24d9}}},
+  {0x24c0, {1|F|D, {0x24da}}},
+  {0x24c1, {1|F|D, {0x24db}}},
+  {0x24c2, {1|F|D, {0x24dc}}},
+  {0x24c3, {1|F|D, {0x24dd}}},
+  {0x24c4, {1|F|D, {0x24de}}},
+  {0x24c5, {1|F|D, {0x24df}}},
+  {0x24c6, {1|F|D, {0x24e0}}},
+  {0x24c7, {1|F|D, {0x24e1}}},
+  {0x24c8, {1|F|D, {0x24e2}}},
+  {0x24c9, {1|F|D, {0x24e3}}},
+  {0x24ca, {1|F|D, {0x24e4}}},
+  {0x24cb, {1|F|D, {0x24e5}}},
+  {0x24cc, {1|F|D, {0x24e6}}},
+  {0x24cd, {1|F|D, {0x24e7}}},
+  {0x24ce, {1|F|D, {0x24e8}}},
+  {0x24cf, {1|F|D, {0x24e9}}},
+  {0x2c00, {1|F|D, {0x2c30}}},
+  {0x2c01, {1|F|D, {0x2c31}}},
+  {0x2c02, {1|F|D, {0x2c32}}},
+  {0x2c03, {1|F|D, {0x2c33}}},
+  {0x2c04, {1|F|D, {0x2c34}}},
+  {0x2c05, {1|F|D, {0x2c35}}},
+  {0x2c06, {1|F|D, {0x2c36}}},
+  {0x2c07, {1|F|D, {0x2c37}}},
+  {0x2c08, {1|F|D, {0x2c38}}},
+  {0x2c09, {1|F|D, {0x2c39}}},
+  {0x2c0a, {1|F|D, {0x2c3a}}},
+  {0x2c0b, {1|F|D, {0x2c3b}}},
+  {0x2c0c, {1|F|D, {0x2c3c}}},
+  {0x2c0d, {1|F|D, {0x2c3d}}},
+  {0x2c0e, {1|F|D, {0x2c3e}}},
+  {0x2c0f, {1|F|D, {0x2c3f}}},
+  {0x2c10, {1|F|D, {0x2c40}}},
+  {0x2c11, {1|F|D, {0x2c41}}},
+  {0x2c12, {1|F|D, {0x2c42}}},
+  {0x2c13, {1|F|D, {0x2c43}}},
+  {0x2c14, {1|F|D, {0x2c44}}},
+  {0x2c15, {1|F|D, {0x2c45}}},
+  {0x2c16, {1|F|D, {0x2c46}}},
+  {0x2c17, {1|F|D, {0x2c47}}},
+  {0x2c18, {1|F|D, {0x2c48}}},
+  {0x2c19, {1|F|D, {0x2c49}}},
+  {0x2c1a, {1|F|D, {0x2c4a}}},
+  {0x2c1b, {1|F|D, {0x2c4b}}},
+  {0x2c1c, {1|F|D, {0x2c4c}}},
+  {0x2c1d, {1|F|D, {0x2c4d}}},
+  {0x2c1e, {1|F|D, {0x2c4e}}},
+  {0x2c1f, {1|F|D, {0x2c4f}}},
+  {0x2c20, {1|F|D, {0x2c50}}},
+  {0x2c21, {1|F|D, {0x2c51}}},
+  {0x2c22, {1|F|D, {0x2c52}}},
+  {0x2c23, {1|F|D, {0x2c53}}},
+  {0x2c24, {1|F|D, {0x2c54}}},
+  {0x2c25, {1|F|D, {0x2c55}}},
+  {0x2c26, {1|F|D, {0x2c56}}},
+  {0x2c27, {1|F|D, {0x2c57}}},
+  {0x2c28, {1|F|D, {0x2c58}}},
+  {0x2c29, {1|F|D, {0x2c59}}},
+  {0x2c2a, {1|F|D, {0x2c5a}}},
+  {0x2c2b, {1|F|D, {0x2c5b}}},
+  {0x2c2c, {1|F|D, {0x2c5c}}},
+  {0x2c2d, {1|F|D, {0x2c5d}}},
+  {0x2c2e, {1|F|D, {0x2c5e}}},
+  {0x2c60, {1|F|D, {0x2c61}}},
+  {0x2c62, {1|F|D, {0x026b}}},
+  {0x2c63, {1|F|D, {0x1d7d}}},
+  {0x2c64, {1|F|D, {0x027d}}},
+  {0x2c67, {1|F|D, {0x2c68}}},
+  {0x2c69, {1|F|D, {0x2c6a}}},
+  {0x2c6b, {1|F|D, {0x2c6c}}},
+  {0x2c6d, {1|F|D, {0x0251}}},
+  {0x2c6e, {1|F|D, {0x0271}}},
+  {0x2c6f, {1|F|D, {0x0250}}},
+  {0x2c70, {1|F|D, {0x0252}}},
+  {0x2c72, {1|F|D, {0x2c73}}},
+  {0x2c75, {1|F|D, {0x2c76}}},
+  {0x2c7e, {1|F|D, {0x023f}}},
+  {0x2c7f, {1|F|D, {0x0240}}},
+  {0x2c80, {1|F|D, {0x2c81}}},
+  {0x2c82, {1|F|D, {0x2c83}}},
+  {0x2c84, {1|F|D, {0x2c85}}},
+  {0x2c86, {1|F|D, {0x2c87}}},
+  {0x2c88, {1|F|D, {0x2c89}}},
+  {0x2c8a, {1|F|D, {0x2c8b}}},
+  {0x2c8c, {1|F|D, {0x2c8d}}},
+  {0x2c8e, {1|F|D, {0x2c8f}}},
+  {0x2c90, {1|F|D, {0x2c91}}},
+  {0x2c92, {1|F|D, {0x2c93}}},
+  {0x2c94, {1|F|D, {0x2c95}}},
+  {0x2c96, {1|F|D, {0x2c97}}},
+  {0x2c98, {1|F|D, {0x2c99}}},
+  {0x2c9a, {1|F|D, {0x2c9b}}},
+  {0x2c9c, {1|F|D, {0x2c9d}}},
+  {0x2c9e, {1|F|D, {0x2c9f}}},
+  {0x2ca0, {1|F|D, {0x2ca1}}},
+  {0x2ca2, {1|F|D, {0x2ca3}}},
+  {0x2ca4, {1|F|D, {0x2ca5}}},
+  {0x2ca6, {1|F|D, {0x2ca7}}},
+  {0x2ca8, {1|F|D, {0x2ca9}}},
+  {0x2caa, {1|F|D, {0x2cab}}},
+  {0x2cac, {1|F|D, {0x2cad}}},
+  {0x2cae, {1|F|D, {0x2caf}}},
+  {0x2cb0, {1|F|D, {0x2cb1}}},
+  {0x2cb2, {1|F|D, {0x2cb3}}},
+  {0x2cb4, {1|F|D, {0x2cb5}}},
+  {0x2cb6, {1|F|D, {0x2cb7}}},
+  {0x2cb8, {1|F|D, {0x2cb9}}},
+  {0x2cba, {1|F|D, {0x2cbb}}},
+  {0x2cbc, {1|F|D, {0x2cbd}}},
+  {0x2cbe, {1|F|D, {0x2cbf}}},
+  {0x2cc0, {1|F|D, {0x2cc1}}},
+  {0x2cc2, {1|F|D, {0x2cc3}}},
+  {0x2cc4, {1|F|D, {0x2cc5}}},
+  {0x2cc6, {1|F|D, {0x2cc7}}},
+  {0x2cc8, {1|F|D, {0x2cc9}}},
+  {0x2cca, {1|F|D, {0x2ccb}}},
+  {0x2ccc, {1|F|D, {0x2ccd}}},
+  {0x2cce, {1|F|D, {0x2ccf}}},
+  {0x2cd0, {1|F|D, {0x2cd1}}},
+  {0x2cd2, {1|F|D, {0x2cd3}}},
+  {0x2cd4, {1|F|D, {0x2cd5}}},
+  {0x2cd6, {1|F|D, {0x2cd7}}},
+  {0x2cd8, {1|F|D, {0x2cd9}}},
+  {0x2cda, {1|F|D, {0x2cdb}}},
+  {0x2cdc, {1|F|D, {0x2cdd}}},
+  {0x2cde, {1|F|D, {0x2cdf}}},
+  {0x2ce0, {1|F|D, {0x2ce1}}},
+  {0x2ce2, {1|F|D, {0x2ce3}}},
+  {0x2ceb, {1|F|D, {0x2cec}}},
+  {0x2ced, {1|F|D, {0x2cee}}},
+  {0x2cf2, {1|F|D, {0x2cf3}}},
+  {0xa640, {1|F|D, {0xa641}}},
+  {0xa642, {1|F|D, {0xa643}}},
+  {0xa644, {1|F|D, {0xa645}}},
+  {0xa646, {1|F|D, {0xa647}}},
+  {0xa648, {1|F|D, {0xa649}}},
+  {0xa64a, {1|F|D, {0xa64b}}},
+  {0xa64c, {1|F|D, {0xa64d}}},
+  {0xa64e, {1|F|D, {0xa64f}}},
+  {0xa650, {1|F|D, {0xa651}}},
+  {0xa652, {1|F|D, {0xa653}}},
+  {0xa654, {1|F|D, {0xa655}}},
+  {0xa656, {1|F|D, {0xa657}}},
+  {0xa658, {1|F|D, {0xa659}}},
+  {0xa65a, {1|F|D, {0xa65b}}},
+  {0xa65c, {1|F|D, {0xa65d}}},
+  {0xa65e, {1|F|D, {0xa65f}}},
+  {0xa660, {1|F|D, {0xa661}}},
+  {0xa662, {1|F|D, {0xa663}}},
+  {0xa664, {1|F|D, {0xa665}}},
+  {0xa666, {1|F|D, {0xa667}}},
+  {0xa668, {1|F|D, {0xa669}}},
+  {0xa66a, {1|F|D, {0xa66b}}},
+  {0xa66c, {1|F|D, {0xa66d}}},
+  {0xa680, {1|F|D, {0xa681}}},
+  {0xa682, {1|F|D, {0xa683}}},
+  {0xa684, {1|F|D, {0xa685}}},
+  {0xa686, {1|F|D, {0xa687}}},
+  {0xa688, {1|F|D, {0xa689}}},
+  {0xa68a, {1|F|D, {0xa68b}}},
+  {0xa68c, {1|F|D, {0xa68d}}},
+  {0xa68e, {1|F|D, {0xa68f}}},
+  {0xa690, {1|F|D, {0xa691}}},
+  {0xa692, {1|F|D, {0xa693}}},
+  {0xa694, {1|F|D, {0xa695}}},
+  {0xa696, {1|F|D, {0xa697}}},
+  {0xa698, {1|F|D, {0xa699}}},
+  {0xa69a, {1|F|D, {0xa69b}}},
+  {0xa722, {1|F|D, {0xa723}}},
+  {0xa724, {1|F|D, {0xa725}}},
+  {0xa726, {1|F|D, {0xa727}}},
+  {0xa728, {1|F|D, {0xa729}}},
+  {0xa72a, {1|F|D, {0xa72b}}},
+  {0xa72c, {1|F|D, {0xa72d}}},
+  {0xa72e, {1|F|D, {0xa72f}}},
+  {0xa732, {1|F|D, {0xa733}}},
+  {0xa734, {1|F|D, {0xa735}}},
+  {0xa736, {1|F|D, {0xa737}}},
+  {0xa738, {1|F|D, {0xa739}}},
+  {0xa73a, {1|F|D, {0xa73b}}},
+  {0xa73c, {1|F|D, {0xa73d}}},
+  {0xa73e, {1|F|D, {0xa73f}}},
+  {0xa740, {1|F|D, {0xa741}}},
+  {0xa742, {1|F|D, {0xa743}}},
+  {0xa744, {1|F|D, {0xa745}}},
+  {0xa746, {1|F|D, {0xa747}}},
+  {0xa748, {1|F|D, {0xa749}}},
+  {0xa74a, {1|F|D, {0xa74b}}},
+  {0xa74c, {1|F|D, {0xa74d}}},
+  {0xa74e, {1|F|D, {0xa74f}}},
+  {0xa750, {1|F|D, {0xa751}}},
+  {0xa752, {1|F|D, {0xa753}}},
+  {0xa754, {1|F|D, {0xa755}}},
+  {0xa756, {1|F|D, {0xa757}}},
+  {0xa758, {1|F|D, {0xa759}}},
+  {0xa75a, {1|F|D, {0xa75b}}},
+  {0xa75c, {1|F|D, {0xa75d}}},
+  {0xa75e, {1|F|D, {0xa75f}}},
+  {0xa760, {1|F|D, {0xa761}}},
+  {0xa762, {1|F|D, {0xa763}}},
+  {0xa764, {1|F|D, {0xa765}}},
+  {0xa766, {1|F|D, {0xa767}}},
+  {0xa768, {1|F|D, {0xa769}}},
+  {0xa76a, {1|F|D, {0xa76b}}},
+  {0xa76c, {1|F|D, {0xa76d}}},
+  {0xa76e, {1|F|D, {0xa76f}}},
+  {0xa779, {1|F|D, {0xa77a}}},
+  {0xa77b, {1|F|D, {0xa77c}}},
+  {0xa77d, {1|F|D, {0x1d79}}},
+  {0xa77e, {1|F|D, {0xa77f}}},
+  {0xa780, {1|F|D, {0xa781}}},
+  {0xa782, {1|F|D, {0xa783}}},
+  {0xa784, {1|F|D, {0xa785}}},
+  {0xa786, {1|F|D, {0xa787}}},
+  {0xa78b, {1|F|D, {0xa78c}}},
+  {0xa78d, {1|F|D, {0x0265}}},
+  {0xa790, {1|F|D, {0xa791}}},
+  {0xa792, {1|F|D, {0xa793}}},
+  {0xa796, {1|F|D, {0xa797}}},
+  {0xa798, {1|F|D, {0xa799}}},
+  {0xa79a, {1|F|D, {0xa79b}}},
+  {0xa79c, {1|F|D, {0xa79d}}},
+  {0xa79e, {1|F|D, {0xa79f}}},
+  {0xa7a0, {1|F|D, {0xa7a1}}},
+  {0xa7a2, {1|F|D, {0xa7a3}}},
+  {0xa7a4, {1|F|D, {0xa7a5}}},
+  {0xa7a6, {1|F|D, {0xa7a7}}},
+  {0xa7a8, {1|F|D, {0xa7a9}}},
+  {0xa7aa, {1|F|D, {0x0266}}},
+  {0xa7ab, {1|F|D, {0x025c}}},
+  {0xa7ac, {1|F|D, {0x0261}}},
+  {0xa7ad, {1|F|D, {0x026c}}},
+  {0xa7ae, {1|F|D, {0x026a}}},
+  {0xa7b0, {1|F|D, {0x029e}}},
+  {0xa7b1, {1|F|D, {0x0287}}},
+  {0xa7b2, {1|F|D, {0x029d}}},
+  {0xa7b3, {1|F|D, {0xab53}}},
+  {0xa7b4, {1|F|D, {0xa7b5}}},
+  {0xa7b6, {1|F|D, {0xa7b7}}},
+  {0xab70, {1|F|U, {0x13a0}}},
+  {0xab71, {1|F|U, {0x13a1}}},
+  {0xab72, {1|F|U, {0x13a2}}},
+  {0xab73, {1|F|U, {0x13a3}}},
+  {0xab74, {1|F|U, {0x13a4}}},
+  {0xab75, {1|F|U, {0x13a5}}},
+  {0xab76, {1|F|U, {0x13a6}}},
+  {0xab77, {1|F|U, {0x13a7}}},
+  {0xab78, {1|F|U, {0x13a8}}},
+  {0xab79, {1|F|U, {0x13a9}}},
+  {0xab7a, {1|F|U, {0x13aa}}},
+  {0xab7b, {1|F|U, {0x13ab}}},
+  {0xab7c, {1|F|U, {0x13ac}}},
+  {0xab7d, {1|F|U, {0x13ad}}},
+  {0xab7e, {1|F|U, {0x13ae}}},
+  {0xab7f, {1|F|U, {0x13af}}},
+  {0xab80, {1|F|U, {0x13b0}}},
+  {0xab81, {1|F|U, {0x13b1}}},
+  {0xab82, {1|F|U, {0x13b2}}},
+  {0xab83, {1|F|U, {0x13b3}}},
+  {0xab84, {1|F|U, {0x13b4}}},
+  {0xab85, {1|F|U, {0x13b5}}},
+  {0xab86, {1|F|U, {0x13b6}}},
+  {0xab87, {1|F|U, {0x13b7}}},
+  {0xab88, {1|F|U, {0x13b8}}},
+  {0xab89, {1|F|U, {0x13b9}}},
+  {0xab8a, {1|F|U, {0x13ba}}},
+  {0xab8b, {1|F|U, {0x13bb}}},
+  {0xab8c, {1|F|U, {0x13bc}}},
+  {0xab8d, {1|F|U, {0x13bd}}},
+  {0xab8e, {1|F|U, {0x13be}}},
+  {0xab8f, {1|F|U, {0x13bf}}},
+  {0xab90, {1|F|U, {0x13c0}}},
+  {0xab91, {1|F|U, {0x13c1}}},
+  {0xab92, {1|F|U, {0x13c2}}},
+  {0xab93, {1|F|U, {0x13c3}}},
+  {0xab94, {1|F|U, {0x13c4}}},
+  {0xab95, {1|F|U, {0x13c5}}},
+  {0xab96, {1|F|U, {0x13c6}}},
+  {0xab97, {1|F|U, {0x13c7}}},
+  {0xab98, {1|F|U, {0x13c8}}},
+  {0xab99, {1|F|U, {0x13c9}}},
+  {0xab9a, {1|F|U, {0x13ca}}},
+  {0xab9b, {1|F|U, {0x13cb}}},
+  {0xab9c, {1|F|U, {0x13cc}}},
+  {0xab9d, {1|F|U, {0x13cd}}},
+  {0xab9e, {1|F|U, {0x13ce}}},
+  {0xab9f, {1|F|U, {0x13cf}}},
+  {0xaba0, {1|F|U, {0x13d0}}},
+  {0xaba1, {1|F|U, {0x13d1}}},
+  {0xaba2, {1|F|U, {0x13d2}}},
+  {0xaba3, {1|F|U, {0x13d3}}},
+  {0xaba4, {1|F|U, {0x13d4}}},
+  {0xaba5, {1|F|U, {0x13d5}}},
+  {0xaba6, {1|F|U, {0x13d6}}},
+  {0xaba7, {1|F|U, {0x13d7}}},
+  {0xaba8, {1|F|U, {0x13d8}}},
+  {0xaba9, {1|F|U, {0x13d9}}},
+  {0xabaa, {1|F|U, {0x13da}}},
+  {0xabab, {1|F|U, {0x13db}}},
+  {0xabac, {1|F|U, {0x13dc}}},
+  {0xabad, {1|F|U, {0x13dd}}},
+  {0xabae, {1|F|U, {0x13de}}},
+  {0xabaf, {1|F|U, {0x13df}}},
+  {0xabb0, {1|F|U, {0x13e0}}},
+  {0xabb1, {1|F|U, {0x13e1}}},
+  {0xabb2, {1|F|U, {0x13e2}}},
+  {0xabb3, {1|F|U, {0x13e3}}},
+  {0xabb4, {1|F|U, {0x13e4}}},
+  {0xabb5, {1|F|U, {0x13e5}}},
+  {0xabb6, {1|F|U, {0x13e6}}},
+  {0xabb7, {1|F|U, {0x13e7}}},
+  {0xabb8, {1|F|U, {0x13e8}}},
+  {0xabb9, {1|F|U, {0x13e9}}},
+  {0xabba, {1|F|U, {0x13ea}}},
+  {0xabbb, {1|F|U, {0x13eb}}},
+  {0xabbc, {1|F|U, {0x13ec}}},
+  {0xabbd, {1|F|U, {0x13ed}}},
+  {0xabbe, {1|F|U, {0x13ee}}},
+  {0xabbf, {1|F|U, {0x13ef}}},
+  {0xfb00, {2|F|ST|SU|I(366), {0x0066, 0x0066}}},
+  {0xfb01, {2|F|ST|SU|I(370), {0x0066, 0x0069}}},
+  {0xfb02, {2|F|ST|SU|I(374), {0x0066, 0x006c}}},
+  {0xfb03, {3|F|ST|SU|I(378), {0x0066, 0x0066, 0x0069}}},
+  {0xfb04, {3|F|ST|SU|I(384), {0x0066, 0x0066, 0x006c}}},
+  {0xfb05, {2|F|ST|SU|I(390), {0x0073, 0x0074}}},
+  {0xfb06, {2|F|ST|SU|I(394), {0x0073, 0x0074}}},
+  {0xfb13, {2|F|ST|SU|I(398), {0x0574, 0x0576}}},
+  {0xfb14, {2|F|ST|SU|I(402), {0x0574, 0x0565}}},
+  {0xfb15, {2|F|ST|SU|I(406), {0x0574, 0x056b}}},
+  {0xfb16, {2|F|ST|SU|I(410), {0x057e, 0x0576}}},
+  {0xfb17, {2|F|ST|SU|I(414), {0x0574, 0x056d}}},
+  {0xff21, {1|F|D, {0xff41}}},
+  {0xff22, {1|F|D, {0xff42}}},
+  {0xff23, {1|F|D, {0xff43}}},
+  {0xff24, {1|F|D, {0xff44}}},
+  {0xff25, {1|F|D, {0xff45}}},
+  {0xff26, {1|F|D, {0xff46}}},
+  {0xff27, {1|F|D, {0xff47}}},
+  {0xff28, {1|F|D, {0xff48}}},
+  {0xff29, {1|F|D, {0xff49}}},
+  {0xff2a, {1|F|D, {0xff4a}}},
+  {0xff2b, {1|F|D, {0xff4b}}},
+  {0xff2c, {1|F|D, {0xff4c}}},
+  {0xff2d, {1|F|D, {0xff4d}}},
+  {0xff2e, {1|F|D, {0xff4e}}},
+  {0xff2f, {1|F|D, {0xff4f}}},
+  {0xff30, {1|F|D, {0xff50}}},
+  {0xff31, {1|F|D, {0xff51}}},
+  {0xff32, {1|F|D, {0xff52}}},
+  {0xff33, {1|F|D, {0xff53}}},
+  {0xff34, {1|F|D, {0xff54}}},
+  {0xff35, {1|F|D, {0xff55}}},
+  {0xff36, {1|F|D, {0xff56}}},
+  {0xff37, {1|F|D, {0xff57}}},
+  {0xff38, {1|F|D, {0xff58}}},
+  {0xff39, {1|F|D, {0xff59}}},
+  {0xff3a, {1|F|D, {0xff5a}}},
+  {0x10400, {1|F|D, {0x10428}}},
+  {0x10401, {1|F|D, {0x10429}}},
+  {0x10402, {1|F|D, {0x1042a}}},
+  {0x10403, {1|F|D, {0x1042b}}},
+  {0x10404, {1|F|D, {0x1042c}}},
+  {0x10405, {1|F|D, {0x1042d}}},
+  {0x10406, {1|F|D, {0x1042e}}},
+  {0x10407, {1|F|D, {0x1042f}}},
+  {0x10408, {1|F|D, {0x10430}}},
+  {0x10409, {1|F|D, {0x10431}}},
+  {0x1040a, {1|F|D, {0x10432}}},
+  {0x1040b, {1|F|D, {0x10433}}},
+  {0x1040c, {1|F|D, {0x10434}}},
+  {0x1040d, {1|F|D, {0x10435}}},
+  {0x1040e, {1|F|D, {0x10436}}},
+  {0x1040f, {1|F|D, {0x10437}}},
+  {0x10410, {1|F|D, {0x10438}}},
+  {0x10411, {1|F|D, {0x10439}}},
+  {0x10412, {1|F|D, {0x1043a}}},
+  {0x10413, {1|F|D, {0x1043b}}},
+  {0x10414, {1|F|D, {0x1043c}}},
+  {0x10415, {1|F|D, {0x1043d}}},
+  {0x10416, {1|F|D, {0x1043e}}},
+  {0x10417, {1|F|D, {0x1043f}}},
+  {0x10418, {1|F|D, {0x10440}}},
+  {0x10419, {1|F|D, {0x10441}}},
+  {0x1041a, {1|F|D, {0x10442}}},
+  {0x1041b, {1|F|D, {0x10443}}},
+  {0x1041c, {1|F|D, {0x10444}}},
+  {0x1041d, {1|F|D, {0x10445}}},
+  {0x1041e, {1|F|D, {0x10446}}},
+  {0x1041f, {1|F|D, {0x10447}}},
+  {0x10420, {1|F|D, {0x10448}}},
+  {0x10421, {1|F|D, {0x10449}}},
+  {0x10422, {1|F|D, {0x1044a}}},
+  {0x10423, {1|F|D, {0x1044b}}},
+  {0x10424, {1|F|D, {0x1044c}}},
+  {0x10425, {1|F|D, {0x1044d}}},
+  {0x10426, {1|F|D, {0x1044e}}},
+  {0x10427, {1|F|D, {0x1044f}}},
+  {0x104b0, {1|F|D, {0x104d8}}},
+  {0x104b1, {1|F|D, {0x104d9}}},
+  {0x104b2, {1|F|D, {0x104da}}},
+  {0x104b3, {1|F|D, {0x104db}}},
+  {0x104b4, {1|F|D, {0x104dc}}},
+  {0x104b5, {1|F|D, {0x104dd}}},
+  {0x104b6, {1|F|D, {0x104de}}},
+  {0x104b7, {1|F|D, {0x104df}}},
+  {0x104b8, {1|F|D, {0x104e0}}},
+  {0x104b9, {1|F|D, {0x104e1}}},
+  {0x104ba, {1|F|D, {0x104e2}}},
+  {0x104bb, {1|F|D, {0x104e3}}},
+  {0x104bc, {1|F|D, {0x104e4}}},
+  {0x104bd, {1|F|D, {0x104e5}}},
+  {0x104be, {1|F|D, {0x104e6}}},
+  {0x104bf, {1|F|D, {0x104e7}}},
+  {0x104c0, {1|F|D, {0x104e8}}},
+  {0x104c1, {1|F|D, {0x104e9}}},
+  {0x104c2, {1|F|D, {0x104ea}}},
+  {0x104c3, {1|F|D, {0x104eb}}},
+  {0x104c4, {1|F|D, {0x104ec}}},
+  {0x104c5, {1|F|D, {0x104ed}}},
+  {0x104c6, {1|F|D, {0x104ee}}},
+  {0x104c7, {1|F|D, {0x104ef}}},
+  {0x104c8, {1|F|D, {0x104f0}}},
+  {0x104c9, {1|F|D, {0x104f1}}},
+  {0x104ca, {1|F|D, {0x104f2}}},
+  {0x104cb, {1|F|D, {0x104f3}}},
+  {0x104cc, {1|F|D, {0x104f4}}},
+  {0x104cd, {1|F|D, {0x104f5}}},
+  {0x104ce, {1|F|D, {0x104f6}}},
+  {0x104cf, {1|F|D, {0x104f7}}},
+  {0x104d0, {1|F|D, {0x104f8}}},
+  {0x104d1, {1|F|D, {0x104f9}}},
+  {0x104d2, {1|F|D, {0x104fa}}},
+  {0x104d3, {1|F|D, {0x104fb}}},
+  {0x10c80, {1|F|D, {0x10cc0}}},
+  {0x10c81, {1|F|D, {0x10cc1}}},
+  {0x10c82, {1|F|D, {0x10cc2}}},
+  {0x10c83, {1|F|D, {0x10cc3}}},
+  {0x10c84, {1|F|D, {0x10cc4}}},
+  {0x10c85, {1|F|D, {0x10cc5}}},
+  {0x10c86, {1|F|D, {0x10cc6}}},
+  {0x10c87, {1|F|D, {0x10cc7}}},
+  {0x10c88, {1|F|D, {0x10cc8}}},
+  {0x10c89, {1|F|D, {0x10cc9}}},
+  {0x10c8a, {1|F|D, {0x10cca}}},
+  {0x10c8b, {1|F|D, {0x10ccb}}},
+  {0x10c8c, {1|F|D, {0x10ccc}}},
+  {0x10c8d, {1|F|D, {0x10ccd}}},
+  {0x10c8e, {1|F|D, {0x10cce}}},
+  {0x10c8f, {1|F|D, {0x10ccf}}},
+  {0x10c90, {1|F|D, {0x10cd0}}},
+  {0x10c91, {1|F|D, {0x10cd1}}},
+  {0x10c92, {1|F|D, {0x10cd2}}},
+  {0x10c93, {1|F|D, {0x10cd3}}},
+  {0x10c94, {1|F|D, {0x10cd4}}},
+  {0x10c95, {1|F|D, {0x10cd5}}},
+  {0x10c96, {1|F|D, {0x10cd6}}},
+  {0x10c97, {1|F|D, {0x10cd7}}},
+  {0x10c98, {1|F|D, {0x10cd8}}},
+  {0x10c99, {1|F|D, {0x10cd9}}},
+  {0x10c9a, {1|F|D, {0x10cda}}},
+  {0x10c9b, {1|F|D, {0x10cdb}}},
+  {0x10c9c, {1|F|D, {0x10cdc}}},
+  {0x10c9d, {1|F|D, {0x10cdd}}},
+  {0x10c9e, {1|F|D, {0x10cde}}},
+  {0x10c9f, {1|F|D, {0x10cdf}}},
+  {0x10ca0, {1|F|D, {0x10ce0}}},
+  {0x10ca1, {1|F|D, {0x10ce1}}},
+  {0x10ca2, {1|F|D, {0x10ce2}}},
+  {0x10ca3, {1|F|D, {0x10ce3}}},
+  {0x10ca4, {1|F|D, {0x10ce4}}},
+  {0x10ca5, {1|F|D, {0x10ce5}}},
+  {0x10ca6, {1|F|D, {0x10ce6}}},
+  {0x10ca7, {1|F|D, {0x10ce7}}},
+  {0x10ca8, {1|F|D, {0x10ce8}}},
+  {0x10ca9, {1|F|D, {0x10ce9}}},
+  {0x10caa, {1|F|D, {0x10cea}}},
+  {0x10cab, {1|F|D, {0x10ceb}}},
+  {0x10cac, {1|F|D, {0x10cec}}},
+  {0x10cad, {1|F|D, {0x10ced}}},
+  {0x10cae, {1|F|D, {0x10cee}}},
+  {0x10caf, {1|F|D, {0x10cef}}},
+  {0x10cb0, {1|F|D, {0x10cf0}}},
+  {0x10cb1, {1|F|D, {0x10cf1}}},
+  {0x10cb2, {1|F|D, {0x10cf2}}},
+  {0x118a0, {1|F|D, {0x118c0}}},
+  {0x118a1, {1|F|D, {0x118c1}}},
+  {0x118a2, {1|F|D, {0x118c2}}},
+  {0x118a3, {1|F|D, {0x118c3}}},
+  {0x118a4, {1|F|D, {0x118c4}}},
+  {0x118a5, {1|F|D, {0x118c5}}},
+  {0x118a6, {1|F|D, {0x118c6}}},
+  {0x118a7, {1|F|D, {0x118c7}}},
+  {0x118a8, {1|F|D, {0x118c8}}},
+  {0x118a9, {1|F|D, {0x118c9}}},
+  {0x118aa, {1|F|D, {0x118ca}}},
+  {0x118ab, {1|F|D, {0x118cb}}},
+  {0x118ac, {1|F|D, {0x118cc}}},
+  {0x118ad, {1|F|D, {0x118cd}}},
+  {0x118ae, {1|F|D, {0x118ce}}},
+  {0x118af, {1|F|D, {0x118cf}}},
+  {0x118b0, {1|F|D, {0x118d0}}},
+  {0x118b1, {1|F|D, {0x118d1}}},
+  {0x118b2, {1|F|D, {0x118d2}}},
+  {0x118b3, {1|F|D, {0x118d3}}},
+  {0x118b4, {1|F|D, {0x118d4}}},
+  {0x118b5, {1|F|D, {0x118d5}}},
+  {0x118b6, {1|F|D, {0x118d6}}},
+  {0x118b7, {1|F|D, {0x118d7}}},
+  {0x118b8, {1|F|D, {0x118d8}}},
+  {0x118b9, {1|F|D, {0x118d9}}},
+  {0x118ba, {1|F|D, {0x118da}}},
+  {0x118bb, {1|F|D, {0x118db}}},
+  {0x118bc, {1|F|D, {0x118dc}}},
+  {0x118bd, {1|F|D, {0x118dd}}},
+  {0x118be, {1|F|D, {0x118de}}},
+  {0x118bf, {1|F|D, {0x118df}}},
+  {0x1e900, {1|F|D, {0x1e922}}},
+  {0x1e901, {1|F|D, {0x1e923}}},
+  {0x1e902, {1|F|D, {0x1e924}}},
+  {0x1e903, {1|F|D, {0x1e925}}},
+  {0x1e904, {1|F|D, {0x1e926}}},
+  {0x1e905, {1|F|D, {0x1e927}}},
+  {0x1e906, {1|F|D, {0x1e928}}},
+  {0x1e907, {1|F|D, {0x1e929}}},
+  {0x1e908, {1|F|D, {0x1e92a}}},
+  {0x1e909, {1|F|D, {0x1e92b}}},
+  {0x1e90a, {1|F|D, {0x1e92c}}},
+  {0x1e90b, {1|F|D, {0x1e92d}}},
+  {0x1e90c, {1|F|D, {0x1e92e}}},
+  {0x1e90d, {1|F|D, {0x1e92f}}},
+  {0x1e90e, {1|F|D, {0x1e930}}},
+  {0x1e90f, {1|F|D, {0x1e931}}},
+  {0x1e910, {1|F|D, {0x1e932}}},
+  {0x1e911, {1|F|D, {0x1e933}}},
+  {0x1e912, {1|F|D, {0x1e934}}},
+  {0x1e913, {1|F|D, {0x1e935}}},
+  {0x1e914, {1|F|D, {0x1e936}}},
+  {0x1e915, {1|F|D, {0x1e937}}},
+  {0x1e916, {1|F|D, {0x1e938}}},
+  {0x1e917, {1|F|D, {0x1e939}}},
+  {0x1e918, {1|F|D, {0x1e93a}}},
+  {0x1e919, {1|F|D, {0x1e93b}}},
+  {0x1e91a, {1|F|D, {0x1e93c}}},
+  {0x1e91b, {1|F|D, {0x1e93d}}},
+  {0x1e91c, {1|F|D, {0x1e93e}}},
+  {0x1e91d, {1|F|D, {0x1e93f}}},
+  {0x1e91e, {1|F|D, {0x1e940}}},
+  {0x1e91f, {1|F|D, {0x1e941}}},
+  {0x1e920, {1|F|D, {0x1e942}}},
+  {0x1e921, {1|F|D, {0x1e943}}},
+#define CaseFold_Locale (*(CaseFold_11_Type (*)[2])(CaseFold_11_Table+1399))
+  {0x0049, {1|F|D, {0x0069}}},
+  {0x0130, {2|F|D, {0x0069, 0x0307}}},
+};
+
+/* ANSI-C code produced by gperf version 3.1 */
+/* Command-line: gperf -7 -k1,2,3 -F,-1 -c -j1 -i1 -t -T -E -C -H onigenc_unicode_CaseFold_11_hash -N onigenc_unicode_CaseFold_11_lookup -n  */
+
+/* maximum key range = 3623, duplicates = 0 */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+/*ARGSUSED*/
+static unsigned int
+onigenc_unicode_CaseFold_11_hash(const OnigCodePoint code)
+{
+  static const unsigned short asso_values[] =
+    {
+         1, 3627,    2,   28,    3,  303,  218,    5,   21,  167,
+         2,  199,  194,    7, 3627, 3627, 3627, 3627, 3627, 3627,
+      3627, 3627, 3627, 3627, 3627, 3627, 3627,   28, 3627, 3627,
+      3627, 3627, 3627, 3627, 3627,  282, 3627, 3627, 3627, 3627,
+      3627,  113, 3627, 3627, 3627, 3627, 3627, 3627, 3627, 3627,
+      3627,  318, 3627, 3627, 3627, 3627, 3627, 3627, 3627, 1197,
+      3627, 3627,  149,   73,  513,    1, 3627, 3627,  267,   17,
+      3627, 3627, 3627, 3627, 3627,  286, 3627, 3627,  289,  617,
+       291,   28, 1163,  444,   36,  430,  954,  110, 1767,    5,
+        11,   22, 1761,  486, 1921,  250, 1746,  122, 1905,  163,
+      1716,  262, 1880,   80, 1503,   68, 1704,  157, 1681,  376,
+      1673,  209, 1822,  203, 1406,  498, 1622,  362, 1588,  316,
+       475,  599, 1228,  538, 1160,  585, 1510,  544,  331,  685,
+      1672,  603, 1536,  840, 1684,  786, 1594,  743, 1380,  700,
+       142,  839, 1302,  865, 1173, 1329, 1730, 1043, 1449,  969,
+      1437, 1108, 1360,  925, 1497,  723,  154,  810,  391, 1083,
+      1777, 1047,  436, 1051,   47, 1342,    8,  974,   98, 1318,
+       781, 1314,  148, 1403,   39, 1357,   18, 1265,   11,  928,
+        92, 1205,    2, 1295,    3, 1181,  187, 1151,  385, 1132,
+       107, 1280,    8, 1678,   41,  511,   42, 1655,   78,  294,
+       134, 1857,   17,  784,    2, 1113,   57,  496,   52
+    };
+  return asso_values[bits_of(code, 2)+81] + asso_values[bits_of(code, 1)+2] + asso_values[bits_of(code, 0)];
+}
+
+static const CodePointList3 *
+onigenc_unicode_CaseFold_11_lookup(const OnigCodePoint code)
+{
+  enum
+    {
+      MIN_CODE_VALUE = 0x41,
+      MAX_CODE_VALUE = 0x1e921,
+      TOTAL_KEYWORDS = 1401,
+      MIN_WORD_LENGTH = 3,
+      MAX_WORD_LENGTH = 3,
+      MIN_HASH_VALUE = 4,
+      MAX_HASH_VALUE = 3626
+    };
+
+  static const short wordlist[] =
+    {
+      -1, -1, -1, -1,
+      /*0x1ffb*/ 816,
+      /*0x1fe7*/ 802,
+      /*0x017b*/ 118,
+      /*0x1f88*/ 729,
+      /*0x0408*/ 305,
+      /*0x0108*/ 61,
+      /*0x10408*/ 1214,
+      /*0x0055*/ 19,
+      /*0xab88*/ 1112,
+      /*0x1f89*/ 730,
+      /*0x0409*/ 306,
+      /*0x2c67*/ 916,
+      /*0x10409*/ 1215,
+      /*0x2c08*/ 873,
+      /*0xab89*/ 1113,
+      /*0x1ff9*/ 814,
+      /*0x2c6f*/ 921,
+      /*0x0179*/ 117,
+      -1,
+      /*0x2c09*/ 874,
+      /*0x1f8a*/ 731,
+      /*0x040a*/ 307,
+      /*0x010a*/ 62,
+      /*0x1040a*/ 1216,
+      /*0x2c88*/ 931,
+      /*0xab8a*/ 1114,
+      /*0x1f80*/ 721,
+      /*0x0400*/ 297,
+      /*0x0100*/ 57,
+      /*0x10400*/ 1206,
+      /*0x2c0a*/ 875,
+      /*0xab80*/ 1104,
+      /*0x10c88*/ 1290,
+      /*0x00d5*/ 47,
+      /*0x1f83*/ 724,
+      /*0x0403*/ 300,
+      /*0x2c00*/ 865,
+      /*0x10403*/ 1209,
+      /*0x10c89*/ 1291,
+      /*0xab83*/ 1107,
+      /*0x1ff3*/ 809,
+      /*0x2c8a*/ 932,
+      /*0x1e908*/ 1373,
+      /*0x00df*/ 56,
+      /*0x2c03*/ 868,
+      /*0x1fd3*/ 791,
+      /*0x0053*/ 17,
+      /*0x2c80*/ 927,
+      /*0x1e909*/ 1374,
+      /*0x10c8a*/ 1292,
+      /*0x2183*/ 838,
+      -1,
+      /*0x017f*/ 120,
+      -1,
+      /*0xa780*/ 1059,
+      /*0x10c80*/ 1282,
+      -1,
+      /*0x017d*/ 119,
+      -1,
+      /*0x1e90a*/ 1375,
+      /*0x2c7f*/ 926,
+      -1, -1,
+      /*0x10c83*/ 1285,
+      /*0x00dd*/ 54,
+      /*0x1e900*/ 1365,
+      /*0x1f98*/ 745,
+      /*0x0418*/ 321,
+      /*0x0118*/ 69,
+      /*0x10418*/ 1230,
+      /*0x037f*/ 233,
+      /*0xab98*/ 1128,
+      /*0x00d3*/ 45,
+      /*0x1e903*/ 1368,
+      -1,
+      /*0x1e88*/ 607,
+      /*0x2c18*/ 889,
+      -1,
+      /*0x1f96*/ 743,
+      /*0x0416*/ 319,
+      /*0x0116*/ 68,
+      /*0x10416*/ 1228,
+      -1,
+      /*0xab96*/ 1126,
+      -1, -1,
+      /*0x2c75*/ 924,
+      /*0x2c98*/ 939,
+      /*0x2c16*/ 887,
+      -1,
+      /*0x1fe3*/ 799,
+      -1,
+      /*0x1e8a*/ 608,
+      -1,
+      /*0xa798*/ 1068,
+      /*0x10c98*/ 1306,
+      /*0x1fd7*/ 793,
+      /*0x0057*/ 21,
+      /*0x1e80*/ 603,
+      /*0x2c96*/ 938,
+      /*0x2c63*/ 914,
+      -1, -1, -1, -1,
+      /*0x1e918*/ 1389,
+      /*0xa796*/ 1067,
+      /*0x10c96*/ 1304,
+      /*0x1f86*/ 727,
+      /*0x0406*/ 303,
+      /*0x0106*/ 60,
+      /*0x10406*/ 1212,
+      /*0x13fb*/ 527,
+      /*0xab86*/ 1110,
+      -1,
+      /*0x2c6d*/ 919,
+      -1,
+      /*0x1e916*/ 1387,
+      /*0x2c06*/ 871,
+      -1,
+      /*0x1f90*/ 737,
+      /*0x0410*/ 313,
+      /*0x0110*/ 65,
+      /*0x10410*/ 1222,
+      -1,
+      /*0xab90*/ 1120,
+      /*0x2ced*/ 978,
+      /*0x13f9*/ 525,
+      -1,
+      /*0x2c86*/ 930,
+      /*0x2c10*/ 881,
+      -1,
+      /*0x1ff7*/ 812,
+      -1, -1, -1,
+      /*0xa786*/ 1062,
+      /*0x10c86*/ 1288,
+      /*0x1e98*/ 616,
+      -1,
+      /*0x1fbb*/ 777,
+      /*0x2c90*/ 935,
+      /*0x013b*/ 85,
+      -1, -1,
+      /*0xabbb*/ 1163,
+      /*0x1fdb*/ 797,
+      /*0x1e906*/ 1371,
+      /*0xa790*/ 1065,
+      /*0x10c90*/ 1298,
+      /*0x1e96*/ 614,
+      /*0x1e08*/ 543,
+      /*0x1fcb*/ 788,
+      /*0x004b*/ 9,
+      -1,
+      /*0x1f9a*/ 747,
+      /*0x041a*/ 323,
+      /*0x011a*/ 70,
+      /*0x1041a*/ 1232,
+      /*0x1e910*/ 1381,
+      /*0xab9a*/ 1130,
+      /*0x1f92*/ 739,
+      /*0x0412*/ 315,
+      /*0x0112*/ 66,
+      /*0x10412*/ 1224,
+      /*0x2c1a*/ 891,
+      /*0xab92*/ 1122,
+      /*0x13fd*/ 529,
+      /*0x1e0a*/ 544,
+      /*0x0388*/ 235,
+      -1,
+      /*0x2c12*/ 883,
+      /*0x03d5*/ 273,
+      /*0x00db*/ 52,
+      /*0x1e00*/ 539,
+      /*0x0389*/ 236,
+      /*0x2c9a*/ 940,
+      -1, -1,
+      /*0x00cb*/ 37,
+      /*0x1e86*/ 606,
+      /*0x03f9*/ 292,
+      /*0x2c92*/ 936,
+      /*0xa79a*/ 1069,
+      /*0x10c9a*/ 1308,
+      /*0x1fe9*/ 804,
+      /*0x038a*/ 237,
+      -1, -1,
+      /*0xa792*/ 1066,
+      /*0x10c92*/ 1300,
+      -1,
+      /*0x1e90*/ 611,
+      -1,
+      /*0x1e91a*/ 1391,
+      /*0x2c69*/ 917,
+      /*0x0508*/ 425,
+      -1, -1,
+      /*0x0555*/ 481,
+      /*0x1e912*/ 1383,
+      /*0x1fa0*/ 753,
+      /*0x0420*/ 329,
+      /*0x0120*/ 73,
+      /*0x10420*/ 1238,
+      /*0x03f1*/ 288,
+      /*0xaba0*/ 1136,
+      /*0x1f9e*/ 751,
+      /*0x041e*/ 327,
+      /*0x011e*/ 72,
+      /*0x1041e*/ 1236,
+      /*0x2c20*/ 897,
+      /*0xab9e*/ 1134,
+      /*0x050a*/ 426,
+      /*0x1e18*/ 551,
+      -1,
+      /*0x03ff*/ 296,
+      /*0x2c1e*/ 895,
+      /*0x048a*/ 362,
+      /*0x0500*/ 421,
+      /*0x0208*/ 194,
+      /*0x03fd*/ 294,
+      /*0x2ca0*/ 943,
+      -1,
+      /*0x0480*/ 361,
+      -1,
+      /*0x1e16*/ 550,
+      /*0x1e9a*/ 618,
+      /*0x2c9e*/ 942,
+      /*0xa7a0*/ 1072,
+      /*0x10ca0*/ 1314,
+      -1,
+      /*0x0398*/ 249,
+      /*0x1e92*/ 612,
+      -1,
+      /*0xa79e*/ 1071,
+      /*0x10c9e*/ 1312,
+      /*0x020a*/ 195,
+      /*0x0553*/ 479,
+      -1,
+      /*0x1e920*/ 1397,
+      -1,
+      /*0x03f5*/ 290,
+      /*0x0200*/ 190,
+      /*0x0396*/ 247,
+      /*0x104d3*/ 1281,
+      /*0x1e91e*/ 1395,
+      -1,
+      /*0x1f8e*/ 735,
+      /*0x040e*/ 311,
+      /*0x010e*/ 64,
+      /*0x1040e*/ 1220,
+      -1,
+      /*0xab8e*/ 1118,
+      -1, -1,
+      /*0x1e06*/ 542,
+      -1,
+      /*0x2c0e*/ 879,
+      /*0x0518*/ 433,
+      /*0x1f94*/ 741,
+      /*0x0414*/ 317,
+      /*0x0114*/ 67,
+      /*0x10414*/ 1226,
+      /*0x0498*/ 369,
+      /*0xab94*/ 1124,
+      /*0x2165*/ 827,
+      /*0x2167*/ 829,
+      /*0x1e10*/ 547,
+      /*0x2c8e*/ 934,
+      /*0x2c14*/ 885,
+      /*0x0516*/ 432,
+      /*0x216f*/ 837,
+      /*0x1ea0*/ 621,
+      /*0x0386*/ 234,
+      /*0x2161*/ 823,
+      /*0x0496*/ 368,
+      /*0x10c8e*/ 1296,
+      -1,
+      /*0x1e9e*/ 620,
+      -1,
+      /*0x2c94*/ 937,
+      -1,
+      /*0x0218*/ 202,
+      -1, -1,
+      /*0x0390*/ 241,
+      /*0x1e90e*/ 1379,
+      -1,
+      /*0x10c94*/ 1302,
+      -1,
+      /*0xa77b*/ 1056,
+      /*0x1ff6*/ 811,
+      /*0x0476*/ 356,
+      /*0x0176*/ 115,
+      /*0x0216*/ 201,
+      -1, -1,
+      /*0x03f7*/ 291,
+      /*0x1e914*/ 1385,
+      -1,
+      /*0x0506*/ 424,
+      -1,
+      /*0x1e1a*/ 552,
+      -1, -1,
+      /*0xa779*/ 1055,
+      -1,
+      /*0x01d5*/ 167,
+      /*0x1e12*/ 548,
+      -1,
+      /*0x0189*/ 126,
+      /*0x0376*/ 232,
+      /*0x0510*/ 429,
+      /*0x1fa6*/ 759,
+      /*0x0426*/ 335,
+      /*0x0126*/ 76,
+      /*0x10426*/ 1244,
+      /*0x0490*/ 365,
+      /*0xaba6*/ 1142,
+      /*0x1e8e*/ 610,
+      /*0x039a*/ 251,
+      /*0x018a*/ 127,
+      -1,
+      /*0x2c26*/ 903,
+      /*0x0206*/ 193,
+      -1,
+      /*0x0392*/ 243,
+      -1,
+      /*0x1faf*/ 768,
+      /*0x042f*/ 344,
+      -1,
+      /*0x1e94*/ 613,
+      /*0x053b*/ 455,
+      /*0xabaf*/ 1151,
+      /*0x2ca6*/ 946,
+      -1,
+      /*0x0210*/ 198,
+      -1, -1,
+      /*0x104bb*/ 1257,
+      /*0x01f1*/ 181,
+      /*0xa7a6*/ 1075,
+      /*0x10ca6*/ 1320,
+      -1,
+      /*0x054b*/ 471,
+      /*0xa77d*/ 1057,
+      /*0x01d3*/ 166,
+      /*0x051a*/ 434,
+      /*0x1e20*/ 555,
+      /*0x04cb*/ 395,
+      -1,
+      /*0x104cb*/ 1273,
+      /*0x049a*/ 370,
+      /*0x0512*/ 430,
+      /*0x1e1e*/ 554,
+      /*0x2163*/ 825,
+      /*0x023b*/ 217,
+      /*0x10caf*/ 1329,
+      /*0x0492*/ 366,
+      /*0x1fa4*/ 757,
+      /*0x0424*/ 333,
+      /*0x0124*/ 75,
+      /*0x10424*/ 1242,
+      /*0x1ef6*/ 664,
+      /*0xaba4*/ 1140,
+      -1,
+      /*0x03a0*/ 257,
+      /*0x0198*/ 137,
+      -1,
+      /*0x2c24*/ 901,
+      /*0x216d*/ 835,
+      /*0x021a*/ 203,
+      /*0x039e*/ 255,
+      /*0x1f9c*/ 749,
+      /*0x041c*/ 325,
+      /*0x011c*/ 71,
+      /*0x1041c*/ 1234,
+      /*0x0212*/ 199,
+      /*0xab9c*/ 1132,
+      /*0x0196*/ 135,
+      /*0x2ca4*/ 945,
+      -1,
+      /*0x1feb*/ 806,
+      /*0x2c1c*/ 893,
+      -1,
+      /*0x1ea6*/ 624,
+      -1,
+      /*0xa7a4*/ 1074,
+      /*0x10ca4*/ 1318,
+      /*0x004d*/ 11,
+      -1, -1,
+      /*0x2c6b*/ 918,
+      /*0x0520*/ 437,
+      /*0x2c9c*/ 941,
+      /*0x1e0e*/ 546,
+      -1,
+      /*0x01d7*/ 168,
+      /*0x04a0*/ 373,
+      /*0x051e*/ 436,
+      -1,
+      /*0xa79c*/ 1070,
+      /*0x10c9c*/ 1310,
+      /*0x2ceb*/ 977,
+      /*0x049e*/ 372,
+      -1, -1,
+      /*0x1e14*/ 549,
+      -1,
+      /*0x0186*/ 124,
+      -1, -1,
+      /*0x1e91c*/ 1393,
+      /*0x038e*/ 239,
+      -1,
+      /*0x00cd*/ 39,
+      -1,
+      /*0x0220*/ 206,
+      -1, -1,
+      /*0x10bb*/ 511,
+      /*0x0190*/ 131,
+      -1,
+      /*0x021e*/ 205,
+      /*0x24bb*/ 844,
+      /*0x0394*/ 245,
+      -1,
+      /*0x1f84*/ 725,
+      /*0x0404*/ 301,
+      /*0x0104*/ 59,
+      /*0x10404*/ 1210,
+      /*0x1ea4*/ 623,
+      /*0xab84*/ 1108,
+      /*0x01f7*/ 185,
+      /*0x0051*/ 15,
+      -1,
+      /*0x24cb*/ 860,
+      /*0x2c04*/ 869,
+      -1,
+      /*0x1e76*/ 598,
+      /*0x050e*/ 428,
+      /*0x1f82*/ 723,
+      /*0x0402*/ 299,
+      /*0x0102*/ 58,
+      /*0x10402*/ 1208,
+      /*0x048e*/ 364,
+      /*0xab82*/ 1106,
+      /*0x01db*/ 170,
+      /*0x2c84*/ 929,
+      -1,
+      /*0x2169*/ 831,
+      /*0x2c02*/ 867,
+      /*0x0514*/ 431,
+      /*0x01cb*/ 162,
+      -1,
+      /*0xa784*/ 1061,
+      /*0x10c84*/ 1286,
+      /*0x0494*/ 367,
+      /*0x118bb*/ 1360,
+      -1,
+      /*0x00d1*/ 43,
+      /*0x1e26*/ 558,
+      /*0x2c82*/ 928,
+      -1,
+      /*0x020e*/ 197,
+      -1,
+      /*0x1e904*/ 1369,
+      -1, -1,
+      /*0xa782*/ 1060,
+      /*0x10c82*/ 1284,
+      -1,
+      /*0x1fa7*/ 760,
+      /*0x0427*/ 336,
+      -1,
+      /*0x10427*/ 1245,
+      /*0x0214*/ 200,
+      /*0xaba7*/ 1143,
+      -1,
+      /*0x03a6*/ 262,
+      /*0x1e902*/ 1367,
+      /*0x10a0*/ 484,
+      /*0x2c27*/ 904,
+      /*0x1f8c*/ 733,
+      /*0x040c*/ 309,
+      /*0x010c*/ 63,
+      /*0x1040c*/ 1218,
+      -1,
+      /*0xab8c*/ 1116,
+      /*0x04f6*/ 416,
+      -1, -1, -1,
+      /*0x2c0c*/ 877,
+      /*0x047e*/ 360,
+      /*0x1fa2*/ 755,
+      /*0x0422*/ 331,
+      /*0x0122*/ 74,
+      /*0x10422*/ 1240,
+      /*0x1e84*/ 605,
+      /*0xaba2*/ 1138,
+      /*0x10ca7*/ 1321,
+      /*0x01a0*/ 141,
+      /*0x2c7e*/ 925,
+      /*0x2c8c*/ 933,
+      /*0x2c22*/ 899,
+      /*0x0526*/ 440,
+      /*0x1e24*/ 557,
+      /*0x1ff2*/ 808,
+      /*0x0472*/ 354,
+      /*0x0172*/ 113,
+      /*0x04a6*/ 376,
+      /*0x10c8c*/ 1294,
+      /*0x1e82*/ 604,
+      /*0x1f08*/ 669,
+      -1,
+      /*0x2ca2*/ 944,
+      /*0x1f6f*/ 720,
+      /*0x2c72*/ 923,
+      /*0x118a0*/ 1333,
+      /*0x1f09*/ 670,
+      /*0x1e1c*/ 553,
+      /*0x1e90c*/ 1377,
+      /*0xa7a2*/ 1073,
+      /*0x10ca2*/ 1316,
+      /*0x03a4*/ 260,
+      /*0xfb00*/ 1168,
+      /*0x1f5f*/ 712,
+      /*0x0372*/ 231,
+      /*0x2cf2*/ 979,
+      /*0x0226*/ 209,
+      /*0x1f0a*/ 671,
+      -1, -1,
+      /*0xfb03*/ 1171,
+      /*0x1faa*/ 763,
+      /*0x042a*/ 339,
+      /*0x012a*/ 78,
+      -1,
+      /*0x039c*/ 253,
+      /*0xabaa*/ 1146,
+      /*0x1fae*/ 767,
+      /*0x042e*/ 343,
+      /*0x012e*/ 80,
+      -1,
+      /*0x2c2a*/ 907,
+      /*0xabae*/ 1150,
+      -1,
+      /*0x1f5d*/ 711,
+      /*0x018e*/ 129,
+      -1,
+      /*0x2c2e*/ 911,
+      /*0x0524*/ 439,
+      -1, -1,
+      /*0x1e8c*/ 609,
+      /*0x2caa*/ 948,
+      /*0x04a4*/ 375,
+      -1, -1, -1,
+      /*0x0194*/ 134,
+      /*0x2cae*/ 950,
+      /*0xa7aa*/ 1077,
+      /*0x10caa*/ 1324,
+      /*0x1efe*/ 668,
+      /*0x051c*/ 435,
+      /*0x1ea2*/ 622,
+      -1,
+      /*0xa7ae*/ 1081,
+      /*0x10cae*/ 1328,
+      /*0x049c*/ 371,
+      -1, -1, -1,
+      /*0x1e04*/ 541,
+      /*0x0224*/ 208,
+      /*0x1f18*/ 677,
+      /*0xfb16*/ 1178,
+      /*0x2126*/ 818,
+      /*0x1ef2*/ 662,
+      /*0x054d*/ 473,
+      /*0x1fac*/ 765,
+      /*0x042c*/ 341,
+      /*0x012c*/ 79,
+      -1,
+      /*0x04cd*/ 396,
+      /*0xabac*/ 1148,
+      /*0x104cd*/ 1275,
+      /*0x1e02*/ 540,
+      /*0x021c*/ 204,
+      -1,
+      /*0x2c2c*/ 909,
+      /*0x01f6*/ 184,
+      /*0x10a6*/ 490,
+      -1,
+      /*0x1fa8*/ 761,
+      /*0x0428*/ 337,
+      /*0x0128*/ 77,
+      /*0x03d1*/ 272,
+      /*0x1fb2*/ 769,
+      /*0xaba8*/ 1144,
+      /*0x0132*/ 81,
+      /*0x2cac*/ 949,
+      /*0xa726*/ 1019,
+      /*0xabb2*/ 1154,
+      /*0x2c28*/ 905,
+      /*0x1eaa*/ 626,
+      /*0xfb06*/ 1174,
+      /*0x10af*/ 499,
+      /*0xa7ac*/ 1079,
+      /*0x10cac*/ 1326,
+      -1,
+      /*0x1eae*/ 628,
+      -1,
+      /*0x01a6*/ 144,
+      /*0x1f6d*/ 718,
+      /*0x2ca8*/ 947,
+      -1,
+      /*0xa688*/ 1007,
+      /*0x0504*/ 423,
+      /*0x2cb2*/ 952,
+      -1, -1,
+      /*0xa7a8*/ 1076,
+      /*0x10ca8*/ 1322,
+      /*0x0551*/ 477,
+      -1,
+      /*0xa7b2*/ 1084,
+      /*0x10cb2*/ 1332,
+      /*0x01af*/ 149,
+      /*0x1e0c*/ 545,
+      /*0x118a6*/ 1339,
+      /*0x104d1*/ 1279,
+      /*0x0502*/ 422,
+      -1,
+      /*0xa68a*/ 1008,
+      -1,
+      /*0x03a7*/ 263,
+      -1,
+      /*0x10a4*/ 488,
+      /*0x1e7e*/ 602,
+      /*0xa680*/ 1003,
+      /*0x1e22*/ 556,
+      /*0x0204*/ 192,
+      -1, -1,
+      /*0x118af*/ 1348,
+      /*0x216b*/ 833,
+      /*0x038c*/ 238,
+      /*0xa724*/ 1018,
+      /*0x1f3b*/ 694,
+      -1, -1,
+      /*0x1eac*/ 627,
+      -1,
+      /*0x1e72*/ 596,
+      /*0x1f5b*/ 710,
+      /*0x0202*/ 191,
+      /*0x03fe*/ 295,
+      -1,
+      /*0x01a4*/ 143,
+      -1,
+      /*0x1f4b*/ 702,
+      -1, -1,
+      /*0x1f1a*/ 679,
+      -1,
+      /*0x1ea8*/ 625,
+      /*0x10cd*/ 523,
+      /*0xff26*/ 1185,
+      -1,
+      /*0x1eb2*/ 630,
+      /*0x24cd*/ 862,
+      -1,
+      /*0x019c*/ 138,
+      /*0x050c*/ 427,
+      -1,
+      /*0x118a4*/ 1337,
+      -1, -1,
+      /*0x048c*/ 363,
+      /*0xa698*/ 1015,
+      /*0x1e2a*/ 560,
+      /*0x0130*/ 1400,
+      /*0xff2f*/ 1194,
+      -1,
+      /*0xabb0*/ 1152,
+      /*0x0522*/ 438,
+      /*0x1e2e*/ 562,
+      /*0x01cd*/ 163,
+      /*0x04fe*/ 420,
+      -1,
+      /*0x04a2*/ 374,
+      /*0xa696*/ 1014,
+      -1,
+      /*0x1f69*/ 714,
+      /*0x1fba*/ 776,
+      -1, -1,
+      /*0x020c*/ 196,
+      /*0x03aa*/ 266,
+      /*0xabba*/ 1162,
+      /*0x2cb0*/ 951,
+      -1, -1,
+      /*0x04f2*/ 414,
+      -1, -1, -1,
+      /*0xa7b0*/ 1082,
+      /*0x10cb0*/ 1330,
+      /*0x0222*/ 207,
+      -1, -1, -1,
+      /*0xff24*/ 1183,
+      -1,
+      /*0x2cba*/ 956,
+      -1,
+      /*0x1fca*/ 787,
+      /*0x004a*/ 8,
+      /*0x014a*/ 93,
+      -1,
+      /*0xa686*/ 1006,
+      -1, -1, -1,
+      /*0x052a*/ 442,
+      /*0x0184*/ 123,
+      /*0x1e2c*/ 561,
+      -1, -1,
+      /*0x04aa*/ 378,
+      /*0x052e*/ 444,
+      /*0x01d1*/ 165,
+      /*0xa690*/ 1011,
+      -1, -1,
+      /*0x04ae*/ 380,
+      /*0x1fb8*/ 774,
+      /*0x2cca*/ 964,
+      -1,
+      /*0x0182*/ 122,
+      /*0x1e28*/ 559,
+      /*0xabb8*/ 1160,
+      -1,
+      /*0x00ca*/ 36,
+      /*0x1e32*/ 564,
+      -1, -1, -1,
+      /*0x022a*/ 211,
+      /*0x10a7*/ 491,
+      /*0x1eb0*/ 629,
+      -1, -1, -1,
+      /*0x022e*/ 213,
+      /*0x1f0e*/ 675,
+      /*0xfb14*/ 1176,
+      /*0x2cb8*/ 955,
+      /*0x03a8*/ 264,
+      -1, -1, -1, -1, -1, -1,
+      /*0x1eba*/ 634,
+      -1,
+      /*0xa69a*/ 1016,
+      -1, -1,
+      /*0x01a7*/ 145,
+      /*0x052c*/ 443,
+      /*0x10a2*/ 486,
+      /*0xa692*/ 1012,
+      /*0x1fd9*/ 795,
+      /*0x0059*/ 23,
+      /*0x04ac*/ 379,
+      /*0x1ffa*/ 815,
+      /*0x047a*/ 358,
+      /*0x1fb6*/ 772,
+      /*0xa77e*/ 1058,
+      /*0x0136*/ 83,
+      /*0xa722*/ 1017,
+      -1,
+      /*0xabb6*/ 1158,
+      /*0x0528*/ 441,
+      -1,
+      /*0x118a7*/ 1340,
+      /*0x1eca*/ 642,
+      /*0x0532*/ 446,
+      /*0x04a8*/ 377,
+      /*0x01fe*/ 189,
+      -1,
+      /*0x01a2*/ 142,
+      /*0x04b2*/ 382,
+      /*0x022c*/ 212,
+      /*0x104b2*/ 1248,
+      /*0x212a*/ 819,
+      -1, -1,
+      /*0x2cb6*/ 954,
+      /*0x00d9*/ 50,
+      -1,
+      /*0x1fcc*/ 789,
+      /*0x004c*/ 10,
+      /*0x014c*/ 94,
+      /*0x01f2*/ 182,
+      /*0xa7b6*/ 1087,
+      /*0x1eb8*/ 633,
+      /*0x0228*/ 210,
+      /*0x118a2*/ 1335,
+      -1,
+      /*0x10aa*/ 494,
+      /*0x0232*/ 215,
+      -1, -1, -1, -1,
+      /*0x10ae*/ 498,
+      -1, -1, -1,
+      /*0xa72a*/ 1021,
+      -1,
+      /*0x2ccc*/ 965,
+      /*0xff27*/ 1186,
+      /*0x1e30*/ 563,
+      -1,
+      /*0xa72e*/ 1023,
+      -1,
+      /*0x00cc*/ 38,
+      -1,
+      /*0x1fbc*/ 778,
+      /*0x1fb4*/ 771,
+      -1,
+      /*0x0134*/ 82,
+      /*0x1f2f*/ 690,
+      /*0xabbc*/ 1164,
+      /*0xabb4*/ 1156,
+      /*0x01ae*/ 148,
+      -1,
+      /*0x1e3a*/ 568,
+      -1, -1,
+      /*0x03b0*/ 268,
+      -1, -1, -1,
+      /*0xff22*/ 1181,
+      /*0x1efa*/ 666,
+      /*0x118aa*/ 1343,
+      /*0x1eb6*/ 632,
+      -1,
+      /*0x2cbc*/ 957,
+      /*0x2cb4*/ 953,
+      -1,
+      /*0x118ae*/ 1347,
+      -1,
+      /*0x1fbe*/ 779,
+      /*0x10ac*/ 496,
+      /*0xa68e*/ 1010,
+      /*0xa7b4*/ 1086,
+      /*0x2132*/ 821,
+      /*0xabbe*/ 1166,
+      /*0x1e4a*/ 576,
+      -1, -1, -1, -1,
+      /*0xa72c*/ 1022,
+      -1, -1,
+      /*0xa694*/ 1013,
+      /*0x10a8*/ 492,
+      -1,
+      /*0x1ecc*/ 643,
+      /*0x04b0*/ 381,
+      /*0x10b2*/ 502,
+      /*0x104b0*/ 1246,
+      /*0x2cbe*/ 958,
+      /*0x01ac*/ 147,
+      /*0x1f1c*/ 681,
+      -1,
+      /*0xa728*/ 1020,
+      /*0x1e38*/ 567,
+      -1,
+      /*0x053a*/ 454,
+      /*0xa732*/ 1024,
+      /*0xff2a*/ 1189,
+      /*0x13fa*/ 526,
+      /*0x1f6b*/ 716,
+      /*0x04ba*/ 386,
+      -1,
+      /*0x104ba*/ 1256,
+      /*0xff2e*/ 1193,
+      /*0x0230*/ 214,
+      /*0x1f4d*/ 704,
+      /*0x118ac*/ 1345,
+      /*0x01b2*/ 151,
+      -1, -1, -1, -1, -1,
+      /*0x1ebc*/ 635,
+      /*0x1eb4*/ 631,
+      -1, -1, -1,
+      /*0x054a*/ 470,
+      /*0x023a*/ 216,
+      /*0x118a8*/ 1341,
+      -1, -1, -1,
+      /*0x118b2*/ 1351,
+      /*0x104ca*/ 1272,
+      -1,
+      /*0x1fc8*/ 785,
+      /*0x0048*/ 7,
+      -1,
+      /*0x1fe2*/ 798,
+      /*0x0462*/ 346,
+      /*0x0162*/ 105,
+      /*0xfb04*/ 1172,
+      /*0x1e7a*/ 600,
+      -1,
+      /*0x1e36*/ 566,
+      -1,
+      /*0x0538*/ 452,
+      /*0x1ebe*/ 636,
+      /*0x2c62*/ 913,
+      -1,
+      /*0x024a*/ 226,
+      /*0x04b8*/ 385,
+      /*0xff2c*/ 1191,
+      /*0x104b8*/ 1254,
+      -1,
+      /*0xfb02*/ 1170,
+      /*0x2cc8*/ 963,
+      -1, -1,
+      /*0x2ce2*/ 976,
+      /*0x03fa*/ 293,
+      -1,
+      /*0x00c8*/ 34,
+      -1,
+      /*0x1f85*/ 726,
+      /*0x0405*/ 302,
+      /*0xff28*/ 1187,
+      /*0x10405*/ 1211,
+      /*0x1e4c*/ 577,
+      /*0xab85*/ 1109,
+      /*0xff32*/ 1197,
+      -1, -1, -1,
+      /*0x2c05*/ 870,
+      -1,
+      /*0x10b0*/ 500,
+      -1, -1,
+      /*0x1fc4*/ 782,
+      /*0x0044*/ 3,
+      -1, -1, -1,
+      /*0x1fd6*/ 792,
+      /*0x0056*/ 20,
+      /*0x0156*/ 99,
+      -1, -1,
+      /*0x0536*/ 450,
+      -1,
+      /*0x10ba*/ 510,
+      /*0x04fa*/ 418,
+      /*0x10c85*/ 1287,
+      /*0x04b6*/ 384,
+      /*0x24ba*/ 843,
+      /*0x104b6*/ 1252,
+      /*0x1e3c*/ 569,
+      /*0x1e34*/ 565,
+      -1,
+      /*0x2cc4*/ 961,
+      /*0xa73a*/ 1028,
+      -1,
+      /*0x1e905*/ 1370,
+      -1,
+      /*0x2cd6*/ 970,
+      /*0x00c4*/ 30,
+      /*0x1ec8*/ 641,
+      /*0x1f0c*/ 673,
+      -1,
+      /*0x1ee2*/ 654,
+      /*0x00d6*/ 48,
+      -1,
+      /*0x054c*/ 472,
+      /*0x118b0*/ 1349,
+      -1, -1, -1,
+      /*0x24ca*/ 859,
+      -1,
+      /*0x104cc*/ 1274,
+      -1,
+      /*0xa64a*/ 985,
+      /*0x1e3e*/ 570,
+      /*0xa74a*/ 1036,
+      -1, -1, -1, -1,
+      /*0x118ba*/ 1359,
+      -1, -1, -1, -1,
+      /*0x10b8*/ 508,
+      /*0x01ca*/ 161,
+      -1,
+      /*0x024c*/ 227,
+      /*0x24b8*/ 841,
+      -1, -1, -1,
+      /*0x053c*/ 456,
+      /*0x0534*/ 448,
+      /*0xa738*/ 1027,
+      -1, -1,
+      /*0x04bc*/ 387,
+      /*0x04b4*/ 383,
+      /*0x104bc*/ 1258,
+      /*0x104b4*/ 1250,
+      /*0x1ec4*/ 639,
+      /*0xff30*/ 1195,
+      /*0x1fc2*/ 780,
+      /*0x0042*/ 1,
+      /*0x01b8*/ 155,
+      /*0x1ed6*/ 648,
+      /*0xa684*/ 1005,
+      /*0x0050*/ 14,
+      /*0x0150*/ 96,
+      /*0x1f2a*/ 685,
+      /*0x1fd2*/ 790,
+      /*0x0052*/ 16,
+      /*0x0152*/ 97,
+      -1, -1,
+      /*0x1f2e*/ 689,
+      /*0xff3a*/ 1205,
+      /*0x053e*/ 458,
+      -1, -1,
+      /*0xa682*/ 1004,
+      /*0x118b8*/ 1357,
+      /*0x04be*/ 388,
+      /*0x2cc2*/ 960,
+      /*0x104be*/ 1260,
+      -1,
+      /*0x10b6*/ 506,
+      /*0x2cd0*/ 967,
+      -1,
+      /*0x00c2*/ 28,
+      /*0x24b6*/ 839,
+      /*0x2cd2*/ 968,
+      /*0x1e48*/ 575,
+      /*0x00d0*/ 42,
+      -1,
+      /*0x1e62*/ 588,
+      /*0xa736*/ 1026,
+      /*0x00d2*/ 44,
+      -1, -1, -1,
+      /*0x023e*/ 219,
+      /*0x01d9*/ 169,
+      /*0x004e*/ 12,
+      /*0x014e*/ 95,
+      /*0x01fa*/ 187,
+      -1, -1, -1, -1, -1, -1,
+      -1,
+      /*0x03e2*/ 280,
+      /*0x24cc*/ 861,
+      -1,
+      /*0x1f2c*/ 687,
+      -1,
+      /*0xa64c*/ 986,
+      /*0xff38*/ 1203,
+      /*0xa74c*/ 1037,
+      -1,
+      /*0xa68c*/ 1009,
+      /*0x2cce*/ 966,
+      /*0x118b6*/ 1355,
+      -1, -1,
+      /*0x1fc6*/ 783,
+      /*0x0046*/ 5,
+      /*0x00ce*/ 40,
+      /*0x1f28*/ 683,
+      -1,
+      /*0x1ffc*/ 817,
+      /*0x047c*/ 359,
+      /*0x1ec2*/ 638,
+      -1,
+      /*0x1e44*/ 573,
+      /*0x0548*/ 468,
+      /*0x1ed0*/ 645,
+      /*0x10bc*/ 512,
+      /*0x10b4*/ 504,
+      /*0x1e56*/ 582,
+      /*0x1ed2*/ 646,
+      /*0x24bc*/ 845,
+      /*0x104c8*/ 1270,
+      /*0x04e2*/ 406,
+      -1, -1,
+      /*0x2cc6*/ 962,
+      /*0xa73c*/ 1029,
+      /*0xa734*/ 1025,
+      /*0x1fec*/ 807,
+      /*0x046c*/ 351,
+      /*0x016c*/ 110,
+      /*0x00c6*/ 32,
+      -1, -1, -1, -1,
+      /*0x03d6*/ 274,
+      /*0x01bc*/ 156,
+      /*0x0248*/ 225,
+      /*0xff36*/ 1201,
+      -1, -1,
+      /*0x10be*/ 514,
+      -1, -1, -1,
+      /*0x24be*/ 847,
+      /*0x1fea*/ 805,
+      /*0x046a*/ 350,
+      /*0x016a*/ 109,
+      -1,
+      /*0x1ece*/ 644,
+      /*0xa73e*/ 1030,
+      -1,
+      /*0x118bc*/ 1361,
+      /*0x118b4*/ 1353,
+      /*0x1fab*/ 764,
+      /*0x042b*/ 340,
+      /*0x0544*/ 464,
+      /*0x1f81*/ 722,
+      /*0x0401*/ 298,
+      /*0xabab*/ 1147,
+      /*0x10401*/ 1207,
+      /*0x0556*/ 482,
+      /*0xab81*/ 1105,
+      /*0x104c4*/ 1266,
+      /*0x2c2b*/ 908,
+      -1,
+      /*0x04d6*/ 400,
+      /*0x2c01*/ 866,
+      -1,
+      /*0x013f*/ 87,
+      -1, -1,
+      /*0xabbf*/ 1167,
+      -1,
+      /*0x1ec6*/ 640,
+      /*0x1fe8*/ 803,
+      /*0x0468*/ 349,
+      /*0x0168*/ 108,
+      /*0x118be*/ 1363,
+      /*0x1efc*/ 667,
+      /*0x0244*/ 222,
+      -1,
+      /*0xa7ab*/ 1078,
+      /*0x10cab*/ 1325,
+      -1,
+      /*0x1e42*/ 572,
+      /*0x10c81*/ 1283,
+      -1,
+      /*0x2162*/ 824,
+      /*0x1e50*/ 579,
+      -1,
+      /*0xff34*/ 1199,
+      -1,
+      /*0x1e52*/ 580,
+      -1,
+      /*0x1c88*/ 538,
+      /*0x1e901*/ 1366,
+      -1,
+      /*0x1eec*/ 659,
+      /*0x1fe4*/ 800,
+      /*0x0464*/ 347,
+      /*0x0164*/ 106,
+      -1,
+      /*0x03c2*/ 269,
+      /*0x24c8*/ 857,
+      -1,
+      /*0x1f3a*/ 693,
+      /*0x03d0*/ 271,
+      /*0xa648*/ 984,
+      /*0x2c64*/ 915,
+      /*0xa748*/ 1035,
+      /*0xa662*/ 997,
+      -1,
+      /*0xa762*/ 1048,
+      -1, -1, -1,
+      /*0x1eea*/ 658,
+      /*0x1c80*/ 530,
+      /*0x13fc*/ 528,
+      -1,
+      /*0x01c8*/ 160,
+      /*0x1fa9*/ 762,
+      /*0x0429*/ 338,
+      /*0x01e2*/ 173,
+      /*0x1e4e*/ 578,
+      /*0x1c83*/ 533,
+      /*0xaba9*/ 1145,
+      -1,
+      /*0x1f4a*/ 701,
+      /*0x0542*/ 462,
+      -1,
+      /*0x2c29*/ 906,
+      -1,
+      /*0x0550*/ 476,
+      -1, -1,
+      /*0x104c2*/ 1264,
+      /*0x0552*/ 478,
+      /*0x04d0*/ 397,
+      -1,
+      /*0x104d0*/ 1278,
+      -1,
+      /*0x04d2*/ 398,
+      /*0x10c4*/ 520,
+      /*0x104d2*/ 1280,
+      -1,
+      /*0x1ee8*/ 657,
+      /*0x24c4*/ 853,
+      /*0x1f38*/ 691,
+      /*0x1e46*/ 574,
+      /*0x10ca9*/ 1323,
+      /*0xa644*/ 982,
+      -1,
+      /*0xa744*/ 1033,
+      /*0x1e7c*/ 601,
+      -1,
+      /*0xa656*/ 991,
+      -1,
+      /*0xa756*/ 1042,
+      /*0x0460*/ 345,
+      /*0x0160*/ 104,
+      -1, -1, -1,
+      /*0x01c4*/ 157,
+      -1, -1, -1,
+      /*0x2c60*/ 912,
+      /*0x054e*/ 474,
+      /*0x1ee4*/ 655,
+      -1, -1,
+      /*0x1e6c*/ 593,
+      /*0x046e*/ 352,
+      /*0x016e*/ 111,
+      /*0x104ce*/ 1276,
+      -1, -1,
+      /*0x2ce0*/ 975,
+      -1, -1, -1,
+      /*0x2c6e*/ 920,
+      -1, -1,
+      /*0x1f59*/ 709,
+      -1,
+      /*0x1fe6*/ 801,
+      /*0x0466*/ 348,
+      /*0x0166*/ 107,
+      /*0x03ec*/ 285,
+      /*0x1e6a*/ 592,
+      /*0x024e*/ 228,
+      /*0x0546*/ 466,
+      -1, -1,
+      /*0x013d*/ 86,
+      -1,
+      /*0x1c86*/ 536,
+      /*0xabbd*/ 1165,
+      /*0x104c6*/ 1268,
+      -1, -1,
+      /*0x04fc*/ 419,
+      -1, -1,
+      /*0x1fda*/ 796,
+      /*0x005a*/ 24,
+      /*0x015a*/ 101,
+      /*0x03ea*/ 284,
+      /*0x1fd8*/ 794,
+      /*0x0058*/ 22,
+      /*0x0158*/ 100,
+      -1,
+      /*0x1f4c*/ 703,
+      -1,
+      /*0x10c2*/ 518,
+      /*0x0246*/ 224,
+      /*0x03ab*/ 267,
+      -1,
+      /*0x24c2*/ 851,
+      /*0x1e68*/ 591,
+      /*0x04ec*/ 411,
+      -1,
+      /*0xa642*/ 981,
+      -1,
+      /*0xa742*/ 1032,
+      /*0x2cda*/ 972,
+      /*0xa650*/ 988,
+      /*0x1ee0*/ 653,
+      /*0xa750*/ 1039,
+      /*0x2cd8*/ 971,
+      /*0xa652*/ 989,
+      /*0x00da*/ 51,
+      /*0xa752*/ 1040,
+      /*0x0054*/ 18,
+      /*0x0154*/ 98,
+      /*0x00d8*/ 49,
+      -1,
+      /*0x03e8*/ 283,
+      -1,
+      /*0x04ea*/ 410,
+      /*0x2cc0*/ 959,
+      /*0x1f3c*/ 695,
+      /*0x1eee*/ 660,
+      /*0x1e64*/ 589,
+      -1, -1,
+      /*0x00c0*/ 26,
+      -1, -1,
+      /*0x015e*/ 103,
+      /*0x1fc7*/ 784,
+      /*0x0047*/ 6,
+      /*0x0147*/ 91,
+      /*0x2cd4*/ 969,
+      -1, -1,
+      /*0x053f*/ 459,
+      /*0x1ee6*/ 656,
+      /*0x24ce*/ 863,
+      /*0x00d4*/ 46,
+      -1,
+      /*0x03e4*/ 281,
+      /*0xa64e*/ 987,
+      /*0x104bf*/ 1261,
+      /*0xa74e*/ 1038,
+      -1, -1,
+      /*0x1f3e*/ 697,
+      /*0x2cde*/ 974,
+      /*0x04e8*/ 409,
+      /*0x1fb9*/ 775,
+      -1,
+      /*0x0139*/ 84,
+      -1,
+      /*0x00de*/ 55,
+      /*0xabb9*/ 1161,
+      /*0x1eda*/ 650,
+      /*0x00c7*/ 33,
+      -1, -1,
+      /*0x1ed8*/ 649,
+      -1, -1,
+      /*0x24c6*/ 855,
+      /*0x03a9*/ 265,
+      -1, -1,
+      /*0xa646*/ 983,
+      /*0x216c*/ 834,
+      /*0xa746*/ 1034,
+      -1,
+      /*0x1ec0*/ 637,
+      -1,
+      /*0x04e4*/ 407,
+      -1,
+      /*0x015c*/ 102,
+      /*0x1fa1*/ 754,
+      /*0x0421*/ 330,
+      -1,
+      /*0x10421*/ 1239,
+      -1,
+      /*0xaba1*/ 1137,
+      -1,
+      /*0x1e60*/ 587,
+      /*0x1ed4*/ 647,
+      /*0x01fc*/ 188,
+      /*0x2c21*/ 898,
+      /*0x216a*/ 832,
+      -1, -1, -1,
+      /*0xa66c*/ 1002,
+      -1,
+      /*0xa76c*/ 1053,
+      /*0x2cdc*/ 973,
+      -1,
+      /*0x212b*/ 820,
+      -1,
+      /*0x1e6e*/ 594,
+      /*0x1ede*/ 652,
+      /*0x00dc*/ 53,
+      /*0x03e0*/ 279,
+      -1, -1,
+      /*0x01ec*/ 178,
+      /*0x10ca1*/ 1315,
+      -1,
+      /*0x1f48*/ 699,
+      /*0x0045*/ 4,
+      /*0x0145*/ 90,
+      /*0xa66a*/ 1001,
+      /*0x10ab*/ 495,
+      /*0xa76a*/ 1052,
+      /*0x1e66*/ 590,
+      -1,
+      /*0x1e921*/ 1398,
+      /*0x03ee*/ 286,
+      /*0x2168*/ 830,
+      -1,
+      /*0x1fc3*/ 781,
+      /*0x0043*/ 2,
+      /*0x0143*/ 89,
+      -1,
+      /*0x01ea*/ 177,
+      /*0x10bf*/ 515,
+      /*0xfb05*/ 1173,
+      -1,
+      /*0x0345*/ 229,
+      /*0x24bf*/ 848,
+      -1, -1,
+      /*0x03e6*/ 282,
+      /*0x1e5a*/ 584,
+      /*0x04e0*/ 405,
+      /*0x00c5*/ 31,
+      /*0x0181*/ 121,
+      /*0x1e58*/ 583,
+      -1, -1, -1,
+      /*0xa668*/ 1000,
+      /*0x2164*/ 826,
+      /*0xa768*/ 1051,
+      -1, -1,
+      /*0x1edc*/ 651,
+      /*0x00c3*/ 29,
+      /*0x1e40*/ 571,
+      /*0x04ee*/ 412,
+      /*0x118ab*/ 1344,
+      /*0x03da*/ 276,
+      -1, -1,
+      /*0x01e8*/ 176,
+      /*0x03d8*/ 275,
+      -1,
+      /*0x1f56*/ 708,
+      -1, -1, -1,
+      /*0x1e54*/ 581,
+      -1,
+      /*0x118bf*/ 1364,
+      /*0x04e6*/ 408,
+      /*0xa664*/ 998,
+      /*0x053d*/ 457,
+      /*0xa764*/ 1049,
+      /*0x1fc9*/ 786,
+      /*0x0049*/ 1399,
+      /*0x0149*/ 92,
+      -1, -1,
+      /*0x104bd*/ 1259,
+      /*0x1f97*/ 744,
+      /*0x0417*/ 320,
+      /*0x1e5e*/ 586,
+      /*0x10417*/ 1229,
+      /*0x01e4*/ 174,
+      /*0xab97*/ 1127,
+      /*0x10a9*/ 493,
+      /*0x1fad*/ 766,
+      /*0x042d*/ 342,
+      /*0x04da*/ 402,
+      /*0x2c17*/ 888,
+      -1,
+      /*0xabad*/ 1149,
+      /*0x04d8*/ 401,
+      /*0xff2b*/ 1190,
+      -1,
+      /*0x023d*/ 218,
+      /*0x2c2d*/ 910,
+      -1,
+      /*0x0540*/ 460,
+      /*0x03de*/ 278,
+      /*0x00c9*/ 35,
+      -1, -1,
+      /*0x04c0*/ 389,
+      -1,
+      /*0x104c0*/ 1262,
+      /*0x01a9*/ 146,
+      /*0x2160*/ 822,
+      /*0x10c97*/ 1305,
+      -1, -1,
+      /*0x0554*/ 480,
+      /*0x1fb3*/ 770,
+      -1,
+      /*0xa7ad*/ 1080,
+      /*0x10cad*/ 1327,
+      /*0x04d4*/ 399,
+      /*0xabb3*/ 1155,
+      /*0x1e917*/ 1388,
+      -1, -1, -1,
+      /*0x216e*/ 836,
+      /*0x118a9*/ 1342,
+      -1, -1, -1,
+      /*0x1e5c*/ 585,
+      -1,
+      /*0x0547*/ 467,
+      /*0xa660*/ 996,
+      /*0x04de*/ 404,
+      /*0xa760*/ 1047,
+      -1,
+      /*0x04c7*/ 393,
+      /*0x1f50*/ 705,
+      /*0x104c7*/ 1269,
+      /*0x2166*/ 828,
+      -1,
+      /*0x1f52*/ 706,
+      /*0xa7b3*/ 1085,
+      -1, -1,
+      /*0x01e0*/ 172,
+      -1,
+      /*0x03dc*/ 277,
+      -1,
+      /*0xa76e*/ 1054,
+      /*0x03a1*/ 258,
+      /*0x0539*/ 453,
+      -1,
+      /*0x1e97*/ 615,
+      -1, -1, -1, -1,
+      /*0x104b9*/ 1255,
+      -1,
+      /*0x01ee*/ 179,
+      /*0x10bd*/ 513,
+      /*0xa666*/ 999,
+      /*0xff29*/ 1188,
+      /*0xa766*/ 1050,
+      /*0x24bd*/ 846,
+      /*0x1fa5*/ 758,
+      /*0x0425*/ 334,
+      -1,
+      /*0x10425*/ 1243,
+      -1,
+      /*0xaba5*/ 1141,
+      /*0x1fb7*/ 773,
+      -1, -1,
+      /*0x01e6*/ 175,
+      /*0x2c25*/ 902,
+      /*0xabb7*/ 1159,
+      -1,
+      /*0x04dc*/ 403,
+      -1,
+      /*0xa65a*/ 993,
+      -1,
+      /*0xa75a*/ 1044,
+      -1,
+      /*0xa658*/ 992,
+      -1,
+      /*0xa758*/ 1043,
+      /*0x10c0*/ 516,
+      -1, -1, -1,
+      /*0x24c0*/ 849,
+      -1, -1,
+      /*0x10ca5*/ 1319,
+      /*0xa640*/ 980,
+      -1,
+      /*0xa740*/ 1031,
+      /*0x118bd*/ 1362,
+      /*0x1fa3*/ 756,
+      /*0x0423*/ 332,
+      -1,
+      /*0x10423*/ 1241,
+      /*0x1c84*/ 534,
+      /*0xaba3*/ 1139,
+      -1, -1,
+      /*0x0545*/ 465,
+      /*0xa654*/ 990,
+      /*0x2c23*/ 900,
+      /*0xa754*/ 1041,
+      -1,
+      /*0x04c5*/ 392,
+      -1,
+      /*0x104c5*/ 1267,
+      -1, -1,
+      /*0x1c82*/ 532,
+      /*0x10c7*/ 522,
+      /*0x0543*/ 463,
+      -1,
+      /*0x1f6c*/ 717,
+      /*0x24c7*/ 856,
+      /*0xa65e*/ 995,
+      /*0x04c3*/ 391,
+      /*0xa75e*/ 1046,
+      /*0x104c3*/ 1265,
+      -1,
+      /*0x10ca3*/ 1317,
+      -1, -1,
+      /*0x0245*/ 223,
+      /*0x1ff4*/ 810,
+      /*0x0474*/ 355,
+      /*0x0174*/ 114,
+      -1,
+      /*0x01de*/ 171,
+      -1,
+      /*0x10b9*/ 509,
+      /*0x01c7*/ 159,
+      /*0x1f6a*/ 715,
+      /*0xfb01*/ 1169,
+      /*0x24b9*/ 842,
+      /*0x0243*/ 221,
+      -1, -1,
+      /*0x0397*/ 248,
+      -1, -1,
+      /*0x1f2b*/ 686,
+      /*0x1f9d*/ 750,
+      /*0x041d*/ 326,
+      -1,
+      /*0x1041d*/ 1235,
+      /*0xabb1*/ 1153,
+      /*0xab9d*/ 1133,
+      /*0x0470*/ 353,
+      /*0x0170*/ 112,
+      /*0x1f9b*/ 748,
+      /*0x041b*/ 324,
+      /*0x2c1d*/ 894,
+      /*0x1041b*/ 1233,
+      /*0x1f3f*/ 698,
+      /*0xab9b*/ 1131,
+      /*0x10a1*/ 485,
+      /*0x2c70*/ 922,
+      /*0xabb5*/ 1157,
+      /*0x0549*/ 469,
+      /*0x2c1b*/ 892,
+      /*0xa65c*/ 994,
+      /*0x1f68*/ 713,
+      /*0xa75c*/ 1045,
+      /*0x04c9*/ 394,
+      -1,
+      /*0x104c9*/ 1271,
+      /*0x0370*/ 230,
+      /*0x118b9*/ 1358,
+      /*0xa7b1*/ 1083,
+      /*0x10cb1*/ 1331,
+      /*0x10c9d*/ 1311,
+      -1,
+      /*0x1f99*/ 746,
+      /*0x0419*/ 322,
+      -1,
+      /*0x10419*/ 1231,
+      -1,
+      /*0xab99*/ 1129,
+      /*0x10c9b*/ 1309,
+      /*0x00b5*/ 25,
+      /*0x1e91d*/ 1394,
+      -1,
+      /*0x2c19*/ 890,
+      -1,
+      /*0x1f93*/ 740,
+      /*0x0413*/ 316,
+      /*0x10c5*/ 521,
+      /*0x10413*/ 1225,
+      /*0x1e91b*/ 1392,
+      /*0xab93*/ 1123,
+      /*0x24c5*/ 854,
+      -1, -1,
+      /*0x118a1*/ 1334,
+      /*0x2c13*/ 884,
+      /*0x1ef4*/ 663,
+      -1,
+      /*0x0533*/ 447,
+      /*0x10c3*/ 519,
+      /*0x0041*/ 0,
+      /*0x0141*/ 88,
+      /*0x10c99*/ 1307,
+      /*0x24c3*/ 852,
+      -1,
+      /*0x104b3*/ 1249,
+      /*0xff39*/ 1204,
+      -1,
+      /*0x01c5*/ 158,
+      /*0x1f29*/ 684,
+      -1, -1,
+      /*0x1e919*/ 1390,
+      -1,
+      /*0x10c93*/ 1301,
+      /*0x1f8f*/ 736,
+      /*0x040f*/ 312,
+      -1,
+      /*0x1040f*/ 1221,
+      /*0x1ef0*/ 661,
+      /*0xab8f*/ 1119,
+      -1,
+      /*0x1e9b*/ 619,
+      /*0x03a5*/ 261,
+      /*0x1e913*/ 1384,
+      /*0x2c0f*/ 880,
+      /*0x00c1*/ 27,
+      -1, -1, -1,
+      /*0x1f8b*/ 732,
+      /*0x040b*/ 308,
+      /*0xff21*/ 1180,
+      /*0x1040b*/ 1217,
+      -1,
+      /*0xab8b*/ 1115,
+      /*0x1f87*/ 728,
+      /*0x0407*/ 304,
+      /*0xab7b*/ 1099,
+      /*0x10407*/ 1213,
+      /*0x2c0b*/ 876,
+      /*0xab87*/ 1111,
+      /*0x0587*/ 483,
+      -1,
+      /*0x10c8f*/ 1297,
+      /*0x1e99*/ 617,
+      /*0x2c07*/ 872,
+      /*0x004f*/ 13,
+      -1, -1, -1,
+      /*0x24c9*/ 858,
+      -1,
+      /*0xab79*/ 1097,
+      /*0x1e90f*/ 1380,
+      -1,
+      /*0x0537*/ 451,
+      /*0x03a3*/ 259,
+      /*0xa78b*/ 1063,
+      /*0x10c8b*/ 1293,
+      /*0x10ad*/ 497,
+      /*0x1f6e*/ 719,
+      -1,
+      /*0x104b7*/ 1253,
+      -1,
+      /*0x10c87*/ 1289,
+      -1, -1, -1,
+      /*0x1e90b*/ 1376,
+      -1, -1,
+      /*0x1e74*/ 597,
+      /*0x00cf*/ 41,
+      /*0x0197*/ 136,
+      /*0x1e907*/ 1372,
+      -1,
+      /*0xab71*/ 1089,
+      /*0xab73*/ 1091,
+      -1, -1, -1, -1,
+      /*0x1f3d*/ 696,
+      -1, -1,
+      /*0x10b3*/ 503,
+      -1,
+      /*0xab7f*/ 1103,
+      -1,
+      /*0x03f4*/ 289,
+      /*0x1f9f*/ 752,
+      /*0x041f*/ 328,
+      /*0xab7d*/ 1101,
+      /*0x1041f*/ 1237,
+      /*0x1e70*/ 595,
+      /*0xab9f*/ 1135,
+      -1,
+      /*0x118ad*/ 1346,
+      -1, -1,
+      /*0x2c1f*/ 896,
+      -1, -1, -1, -1, -1,
+      /*0x01b3*/ 152,
+      /*0x039d*/ 254,
+      -1, -1, -1, -1,
+      /*0x03f0*/ 287,
+      /*0xab75*/ 1093,
+      -1,
+      /*0x039b*/ 252,
+      -1, -1, -1,
+      /*0x10c9f*/ 1313,
+      -1,
+      /*0x04f4*/ 415,
+      /*0x1f54*/ 707,
+      /*0x118b3*/ 1352,
+      -1,
+      /*0x1ff8*/ 813,
+      /*0x0478*/ 357,
+      /*0x0178*/ 116,
+      -1,
+      /*0x1e91f*/ 1396,
+      -1, -1, -1,
+      /*0x0531*/ 445,
+      -1,
+      /*0xff2d*/ 1192,
+      -1,
+      /*0x10a5*/ 489,
+      /*0x0399*/ 250,
+      -1,
+      /*0x104b1*/ 1247,
+      -1, -1,
+      /*0x10b7*/ 507,
+      /*0x04f0*/ 413,
+      /*0x0535*/ 449,
+      -1,
+      /*0x24b7*/ 840,
+      /*0x1f95*/ 742,
+      /*0x0415*/ 318,
+      /*0x0393*/ 244,
+      /*0x10415*/ 1227,
+      /*0x104b5*/ 1251,
+      /*0xab95*/ 1125,
+      -1, -1, -1, -1,
+      /*0x2c15*/ 886,
+      -1,
+      /*0x1f39*/ 692,
+      /*0xff33*/ 1198,
+      -1, -1,
+      /*0x01b7*/ 154,
+      -1, -1, -1, -1,
+      /*0xab77*/ 1095,
+      -1,
+      /*0x10a3*/ 487,
+      -1,
+      /*0x1f91*/ 738,
+      /*0x0411*/ 314,
+      /*0x118a5*/ 1338,
+      /*0x10411*/ 1223,
+      /*0x10c95*/ 1303,
+      /*0xab91*/ 1121,
+      -1,
+      /*0x038f*/ 240,
+      /*0x118b7*/ 1356,
+      -1,
+      /*0x2c11*/ 882,
+      -1, -1, -1,
+      /*0x1e915*/ 1386,
+      -1,
+      /*0x1f8d*/ 734,
+      /*0x040d*/ 310,
+      /*0x0541*/ 461,
+      /*0x1040d*/ 1219,
+      -1,
+      /*0xab8d*/ 1117,
+      -1,
+      /*0x04c1*/ 390,
+      /*0x1ef8*/ 665,
+      /*0x104c1*/ 1263,
+      /*0x2c0d*/ 878,
+      -1, -1,
+      /*0x10c91*/ 1299,
+      -1, -1, -1, -1, -1, -1,
+      /*0x118a3*/ 1336,
+      -1,
+      /*0x03cf*/ 270,
+      /*0x1e911*/ 1382,
+      /*0xff25*/ 1184,
+      -1,
+      /*0x0241*/ 220,
+      -1,
+      /*0xa78d*/ 1064,
+      /*0x10c8d*/ 1295,
+      /*0xff37*/ 1202,
+      -1,
+      /*0x10b1*/ 501,
+      -1, -1, -1,
+      /*0x01f4*/ 183,
+      -1, -1,
+      /*0x1e90d*/ 1378,
+      -1, -1, -1, -1,
+      /*0x10b5*/ 505,
+      -1, -1, -1,
+      /*0x13f8*/ 524,
+      /*0x054f*/ 475,
+      -1, -1, -1,
+      /*0x01b1*/ 150,
+      /*0x019d*/ 139,
+      -1,
+      /*0x104cf*/ 1277,
+      -1,
+      /*0xff23*/ 1182,
+      /*0x01f0*/ 180,
+      -1, -1, -1, -1, -1,
+      /*0x01b5*/ 153,
+      -1,
+      /*0x039f*/ 256,
+      -1, -1,
+      /*0x118b1*/ 1350,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1,
+      /*0x118b5*/ 1354,
+      /*0xfb17*/ 1179,
+      /*0x1e78*/ 599,
+      -1, -1, -1,
+      /*0x1f49*/ 700,
+      -1,
+      /*0x10c1*/ 517,
+      -1, -1, -1,
+      /*0x24c1*/ 850,
+      -1, -1,
+      /*0x0193*/ 133,
+      -1, -1, -1,
+      /*0x1f2d*/ 688,
+      -1, -1, -1, -1, -1, -1,
+      /*0xff31*/ 1196,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1,
+      /*0xff35*/ 1200,
+      -1, -1, -1, -1,
+      /*0x0395*/ 246,
+      -1,
+      /*0x018f*/ 130,
+      -1, -1, -1, -1, -1, -1,
+      /*0x04f8*/ 417,
+      -1, -1, -1, -1, -1,
+      /*0xab76*/ 1094,
+      /*0x24cf*/ 864,
+      /*0x018b*/ 128,
+      -1, -1, -1, -1, -1,
+      /*0x0187*/ 125,
+      -1,
+      /*0x0391*/ 242,
+      -1, -1, -1, -1, -1, -1,
+      -1,
+      /*0x01cf*/ 164,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1,
+      /*0x019f*/ 140,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1,
+      /*0x1c85*/ 535,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1,
+      /*0x01f8*/ 186,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1,
+      /*0x1f1d*/ 682,
+      -1, -1, -1, -1, -1, -1,
+      -1,
+      /*0x1f1b*/ 680,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1,
+      /*0x0191*/ 132,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1,
+      /*0x1f19*/ 678,
+      /*0xfb13*/ 1175,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1,
+      /*0x1f0f*/ 676,
+      -1, -1, -1, -1,
+      /*0xab7e*/ 1102,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1,
+      /*0x1f0b*/ 672,
+      -1, -1, -1, -1,
+      /*0xab72*/ 1090,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1,
+      /*0x1c81*/ 531,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1,
+      /*0xfb15*/ 1177,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1,
+      /*0x1f0d*/ 674,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1,
+      /*0xab7a*/ 1098,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1,
+      /*0xab7c*/ 1100,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1,
+      /*0x1c87*/ 537,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1,
+      /*0xab74*/ 1092,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1,
+      /*0xab70*/ 1088,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1,
+      /*0xab78*/ 1096
+    };
+
+  if (code <= MAX_CODE_VALUE && code >= MIN_CODE_VALUE)
+    {
+      register unsigned int key = onigenc_unicode_CaseFold_11_hash(code);
+
+      if (key <= MAX_HASH_VALUE)
+        {
+          register short s = wordlist[key];
+
+          if (s >= 0 && code1_equal(code, CaseFold_11_Table[s].from))
+            return &CaseFold_11_Table[s].to;
+        }
+    }
+  return 0;
+}
+
+static const CaseUnfold_11_Type CaseUnfold_11_Table[] = {
+#define CaseUnfold_11 (*(CaseUnfold_11_Type (*)[1266])(CaseUnfold_11_Table+0))
+  {0x0061, {1|U, {0x0041}}},
+  {0x0062, {1|U, {0x0042}}},
+  {0x0063, {1|U, {0x0043}}},
+  {0x0064, {1|U, {0x0044}}},
+  {0x0065, {1|U, {0x0045}}},
+  {0x0066, {1|U, {0x0046}}},
+  {0x0067, {1|U, {0x0047}}},
+  {0x0068, {1|U, {0x0048}}},
+  {0x006a, {1|U, {0x004a}}},
+  {0x006b, {2|U, {0x004b, 0x212a}}},
+  {0x006c, {1|U, {0x004c}}},
+  {0x006d, {1|U, {0x004d}}},
+  {0x006e, {1|U, {0x004e}}},
+  {0x006f, {1|U, {0x004f}}},
+  {0x0070, {1|U, {0x0050}}},
+  {0x0071, {1|U, {0x0051}}},
+  {0x0072, {1|U, {0x0052}}},
+  {0x0073, {2|U, {0x0053, 0x017f}}},
+  {0x0074, {1|U, {0x0054}}},
+  {0x0075, {1|U, {0x0055}}},
+  {0x0076, {1|U, {0x0056}}},
+  {0x0077, {1|U, {0x0057}}},
+  {0x0078, {1|U, {0x0058}}},
+  {0x0079, {1|U, {0x0059}}},
+  {0x007a, {1|U, {0x005a}}},
+  {0x00e0, {1|U, {0x00c0}}},
+  {0x00e1, {1|U, {0x00c1}}},
+  {0x00e2, {1|U, {0x00c2}}},
+  {0x00e3, {1|U, {0x00c3}}},
+  {0x00e4, {1|U, {0x00c4}}},
+  {0x00e5, {2|U, {0x00c5, 0x212b}}},
+  {0x00e6, {1|U, {0x00c6}}},
+  {0x00e7, {1|U, {0x00c7}}},
+  {0x00e8, {1|U, {0x00c8}}},
+  {0x00e9, {1|U, {0x00c9}}},
+  {0x00ea, {1|U, {0x00ca}}},
+  {0x00eb, {1|U, {0x00cb}}},
+  {0x00ec, {1|U, {0x00cc}}},
+  {0x00ed, {1|U, {0x00cd}}},
+  {0x00ee, {1|U, {0x00ce}}},
+  {0x00ef, {1|U, {0x00cf}}},
+  {0x00f0, {1|U, {0x00d0}}},
+  {0x00f1, {1|U, {0x00d1}}},
+  {0x00f2, {1|U, {0x00d2}}},
+  {0x00f3, {1|U, {0x00d3}}},
+  {0x00f4, {1|U, {0x00d4}}},
+  {0x00f5, {1|U, {0x00d5}}},
+  {0x00f6, {1|U, {0x00d6}}},
+  {0x00f8, {1|U, {0x00d8}}},
+  {0x00f9, {1|U, {0x00d9}}},
+  {0x00fa, {1|U, {0x00da}}},
+  {0x00fb, {1|U, {0x00db}}},
+  {0x00fc, {1|U, {0x00dc}}},
+  {0x00fd, {1|U, {0x00dd}}},
+  {0x00fe, {1|U, {0x00de}}},
+  {0x00ff, {1|U, {0x0178}}},
+  {0x0101, {1|U, {0x0100}}},
+  {0x0103, {1|U, {0x0102}}},
+  {0x0105, {1|U, {0x0104}}},
+  {0x0107, {1|U, {0x0106}}},
+  {0x0109, {1|U, {0x0108}}},
+  {0x010b, {1|U, {0x010a}}},
+  {0x010d, {1|U, {0x010c}}},
+  {0x010f, {1|U, {0x010e}}},
+  {0x0111, {1|U, {0x0110}}},
+  {0x0113, {1|U, {0x0112}}},
+  {0x0115, {1|U, {0x0114}}},
+  {0x0117, {1|U, {0x0116}}},
+  {0x0119, {1|U, {0x0118}}},
+  {0x011b, {1|U, {0x011a}}},
+  {0x011d, {1|U, {0x011c}}},
+  {0x011f, {1|U, {0x011e}}},
+  {0x0121, {1|U, {0x0120}}},
+  {0x0123, {1|U, {0x0122}}},
+  {0x0125, {1|U, {0x0124}}},
+  {0x0127, {1|U, {0x0126}}},
+  {0x0129, {1|U, {0x0128}}},
+  {0x012b, {1|U, {0x012a}}},
+  {0x012d, {1|U, {0x012c}}},
+  {0x012f, {1|U, {0x012e}}},
+  {0x0133, {1|U, {0x0132}}},
+  {0x0135, {1|U, {0x0134}}},
+  {0x0137, {1|U, {0x0136}}},
+  {0x013a, {1|U, {0x0139}}},
+  {0x013c, {1|U, {0x013b}}},
+  {0x013e, {1|U, {0x013d}}},
+  {0x0140, {1|U, {0x013f}}},
+  {0x0142, {1|U, {0x0141}}},
+  {0x0144, {1|U, {0x0143}}},
+  {0x0146, {1|U, {0x0145}}},
+  {0x0148, {1|U, {0x0147}}},
+  {0x014b, {1|U, {0x014a}}},
+  {0x014d, {1|U, {0x014c}}},
+  {0x014f, {1|U, {0x014e}}},
+  {0x0151, {1|U, {0x0150}}},
+  {0x0153, {1|U, {0x0152}}},
+  {0x0155, {1|U, {0x0154}}},
+  {0x0157, {1|U, {0x0156}}},
+  {0x0159, {1|U, {0x0158}}},
+  {0x015b, {1|U, {0x015a}}},
+  {0x015d, {1|U, {0x015c}}},
+  {0x015f, {1|U, {0x015e}}},
+  {0x0161, {1|U, {0x0160}}},
+  {0x0163, {1|U, {0x0162}}},
+  {0x0165, {1|U, {0x0164}}},
+  {0x0167, {1|U, {0x0166}}},
+  {0x0169, {1|U, {0x0168}}},
+  {0x016b, {1|U, {0x016a}}},
+  {0x016d, {1|U, {0x016c}}},
+  {0x016f, {1|U, {0x016e}}},
+  {0x0171, {1|U, {0x0170}}},
+  {0x0173, {1|U, {0x0172}}},
+  {0x0175, {1|U, {0x0174}}},
+  {0x0177, {1|U, {0x0176}}},
+  {0x017a, {1|U, {0x0179}}},
+  {0x017c, {1|U, {0x017b}}},
+  {0x017e, {1|U, {0x017d}}},
+  {0x0180, {1|U, {0x0243}}},
+  {0x0183, {1|U, {0x0182}}},
+  {0x0185, {1|U, {0x0184}}},
+  {0x0188, {1|U, {0x0187}}},
+  {0x018c, {1|U, {0x018b}}},
+  {0x0192, {1|U, {0x0191}}},
+  {0x0195, {1|U, {0x01f6}}},
+  {0x0199, {1|U, {0x0198}}},
+  {0x019a, {1|U, {0x023d}}},
+  {0x019e, {1|U, {0x0220}}},
+  {0x01a1, {1|U, {0x01a0}}},
+  {0x01a3, {1|U, {0x01a2}}},
+  {0x01a5, {1|U, {0x01a4}}},
+  {0x01a8, {1|U, {0x01a7}}},
+  {0x01ad, {1|U, {0x01ac}}},
+  {0x01b0, {1|U, {0x01af}}},
+  {0x01b4, {1|U, {0x01b3}}},
+  {0x01b6, {1|U, {0x01b5}}},
+  {0x01b9, {1|U, {0x01b8}}},
+  {0x01bd, {1|U, {0x01bc}}},
+  {0x01bf, {1|U, {0x01f7}}},
+  {0x01c6, {2|U|ST, {0x01c4, 0x01c5}}},
+  {0x01c9, {2|U|ST, {0x01c7, 0x01c8}}},
+  {0x01cc, {2|U|ST, {0x01ca, 0x01cb}}},
+  {0x01ce, {1|U, {0x01cd}}},
+  {0x01d0, {1|U, {0x01cf}}},
+  {0x01d2, {1|U, {0x01d1}}},
+  {0x01d4, {1|U, {0x01d3}}},
+  {0x01d6, {1|U, {0x01d5}}},
+  {0x01d8, {1|U, {0x01d7}}},
+  {0x01da, {1|U, {0x01d9}}},
+  {0x01dc, {1|U, {0x01db}}},
+  {0x01dd, {1|U, {0x018e}}},
+  {0x01df, {1|U, {0x01de}}},
+  {0x01e1, {1|U, {0x01e0}}},
+  {0x01e3, {1|U, {0x01e2}}},
+  {0x01e5, {1|U, {0x01e4}}},
+  {0x01e7, {1|U, {0x01e6}}},
+  {0x01e9, {1|U, {0x01e8}}},
+  {0x01eb, {1|U, {0x01ea}}},
+  {0x01ed, {1|U, {0x01ec}}},
+  {0x01ef, {1|U, {0x01ee}}},
+  {0x01f3, {2|U|ST, {0x01f1, 0x01f2}}},
+  {0x01f5, {1|U, {0x01f4}}},
+  {0x01f9, {1|U, {0x01f8}}},
+  {0x01fb, {1|U, {0x01fa}}},
+  {0x01fd, {1|U, {0x01fc}}},
+  {0x01ff, {1|U, {0x01fe}}},
+  {0x0201, {1|U, {0x0200}}},
+  {0x0203, {1|U, {0x0202}}},
+  {0x0205, {1|U, {0x0204}}},
+  {0x0207, {1|U, {0x0206}}},
+  {0x0209, {1|U, {0x0208}}},
+  {0x020b, {1|U, {0x020a}}},
+  {0x020d, {1|U, {0x020c}}},
+  {0x020f, {1|U, {0x020e}}},
+  {0x0211, {1|U, {0x0210}}},
+  {0x0213, {1|U, {0x0212}}},
+  {0x0215, {1|U, {0x0214}}},
+  {0x0217, {1|U, {0x0216}}},
+  {0x0219, {1|U, {0x0218}}},
+  {0x021b, {1|U, {0x021a}}},
+  {0x021d, {1|U, {0x021c}}},
+  {0x021f, {1|U, {0x021e}}},
+  {0x0223, {1|U, {0x0222}}},
+  {0x0225, {1|U, {0x0224}}},
+  {0x0227, {1|U, {0x0226}}},
+  {0x0229, {1|U, {0x0228}}},
+  {0x022b, {1|U, {0x022a}}},
+  {0x022d, {1|U, {0x022c}}},
+  {0x022f, {1|U, {0x022e}}},
+  {0x0231, {1|U, {0x0230}}},
+  {0x0233, {1|U, {0x0232}}},
+  {0x023c, {1|U, {0x023b}}},
+  {0x023f, {1|U, {0x2c7e}}},
+  {0x0240, {1|U, {0x2c7f}}},
+  {0x0242, {1|U, {0x0241}}},
+  {0x0247, {1|U, {0x0246}}},
+  {0x0249, {1|U, {0x0248}}},
+  {0x024b, {1|U, {0x024a}}},
+  {0x024d, {1|U, {0x024c}}},
+  {0x024f, {1|U, {0x024e}}},
+  {0x0250, {1|U, {0x2c6f}}},
+  {0x0251, {1|U, {0x2c6d}}},
+  {0x0252, {1|U, {0x2c70}}},
+  {0x0253, {1|U, {0x0181}}},
+  {0x0254, {1|U, {0x0186}}},
+  {0x0256, {1|U, {0x0189}}},
+  {0x0257, {1|U, {0x018a}}},
+  {0x0259, {1|U, {0x018f}}},
+  {0x025b, {1|U, {0x0190}}},
+  {0x025c, {1|U, {0xa7ab}}},
+  {0x0260, {1|U, {0x0193}}},
+  {0x0261, {1|U, {0xa7ac}}},
+  {0x0263, {1|U, {0x0194}}},
+  {0x0265, {1|U, {0xa78d}}},
+  {0x0266, {1|U, {0xa7aa}}},
+  {0x0268, {1|U, {0x0197}}},
+  {0x0269, {1|U, {0x0196}}},
+  {0x026a, {1|U, {0xa7ae}}},
+  {0x026b, {1|U, {0x2c62}}},
+  {0x026c, {1|U, {0xa7ad}}},
+  {0x026f, {1|U, {0x019c}}},
+  {0x0271, {1|U, {0x2c6e}}},
+  {0x0272, {1|U, {0x019d}}},
+  {0x0275, {1|U, {0x019f}}},
+  {0x027d, {1|U, {0x2c64}}},
+  {0x0280, {1|U, {0x01a6}}},
+  {0x0283, {1|U, {0x01a9}}},
+  {0x0287, {1|U, {0xa7b1}}},
+  {0x0288, {1|U, {0x01ae}}},
+  {0x0289, {1|U, {0x0244}}},
+  {0x028a, {1|U, {0x01b1}}},
+  {0x028b, {1|U, {0x01b2}}},
+  {0x028c, {1|U, {0x0245}}},
+  {0x0292, {1|U, {0x01b7}}},
+  {0x029d, {1|U, {0xa7b2}}},
+  {0x029e, {1|U, {0xa7b0}}},
+  {0x0371, {1|U, {0x0370}}},
+  {0x0373, {1|U, {0x0372}}},
+  {0x0377, {1|U, {0x0376}}},
+  {0x037b, {1|U, {0x03fd}}},
+  {0x037c, {1|U, {0x03fe}}},
+  {0x037d, {1|U, {0x03ff}}},
+  {0x03ac, {1|U, {0x0386}}},
+  {0x03ad, {1|U, {0x0388}}},
+  {0x03ae, {1|U, {0x0389}}},
+  {0x03af, {1|U, {0x038a}}},
+  {0x03b1, {1|U, {0x0391}}},
+  {0x03b2, {2|U, {0x0392, 0x03d0}}},
+  {0x03b3, {1|U, {0x0393}}},
+  {0x03b4, {1|U, {0x0394}}},
+  {0x03b5, {2|U, {0x0395, 0x03f5}}},
+  {0x03b6, {1|U, {0x0396}}},
+  {0x03b7, {1|U, {0x0397}}},
+  {0x03b8, {3|U, {0x0398, 0x03d1, 0x03f4}}},
+  {0x03b9, {3|U, {0x0399, 0x0345, 0x1fbe}}},
+  {0x03ba, {2|U, {0x039a, 0x03f0}}},
+  {0x03bb, {1|U, {0x039b}}},
+  {0x03bc, {2|U, {0x039c, 0x00b5}}},
+  {0x03bd, {1|U, {0x039d}}},
+  {0x03be, {1|U, {0x039e}}},
+  {0x03bf, {1|U, {0x039f}}},
+  {0x03c0, {2|U, {0x03a0, 0x03d6}}},
+  {0x03c1, {2|U, {0x03a1, 0x03f1}}},
+  {0x03c3, {2|U, {0x03a3, 0x03c2}}},
+  {0x03c4, {1|U, {0x03a4}}},
+  {0x03c5, {1|U, {0x03a5}}},
+  {0x03c6, {2|U, {0x03a6, 0x03d5}}},
+  {0x03c7, {1|U, {0x03a7}}},
+  {0x03c8, {1|U, {0x03a8}}},
+  {0x03c9, {2|U, {0x03a9, 0x2126}}},
+  {0x03ca, {1|U, {0x03aa}}},
+  {0x03cb, {1|U, {0x03ab}}},
+  {0x03cc, {1|U, {0x038c}}},
+  {0x03cd, {1|U, {0x038e}}},
+  {0x03ce, {1|U, {0x038f}}},
+  {0x03d7, {1|U, {0x03cf}}},
+  {0x03d9, {1|U, {0x03d8}}},
+  {0x03db, {1|U, {0x03da}}},
+  {0x03dd, {1|U, {0x03dc}}},
+  {0x03df, {1|U, {0x03de}}},
+  {0x03e1, {1|U, {0x03e0}}},
+  {0x03e3, {1|U, {0x03e2}}},
+  {0x03e5, {1|U, {0x03e4}}},
+  {0x03e7, {1|U, {0x03e6}}},
+  {0x03e9, {1|U, {0x03e8}}},
+  {0x03eb, {1|U, {0x03ea}}},
+  {0x03ed, {1|U, {0x03ec}}},
+  {0x03ef, {1|U, {0x03ee}}},
+  {0x03f2, {1|U, {0x03f9}}},
+  {0x03f3, {1|U, {0x037f}}},
+  {0x03f8, {1|U, {0x03f7}}},
+  {0x03fb, {1|U, {0x03fa}}},
+  {0x0430, {1|U, {0x0410}}},
+  {0x0431, {1|U, {0x0411}}},
+  {0x0432, {2|U, {0x0412, 0x1c80}}},
+  {0x0433, {1|U, {0x0413}}},
+  {0x0434, {2|U, {0x0414, 0x1c81}}},
+  {0x0435, {1|U, {0x0415}}},
+  {0x0436, {1|U, {0x0416}}},
+  {0x0437, {1|U, {0x0417}}},
+  {0x0438, {1|U, {0x0418}}},
+  {0x0439, {1|U, {0x0419}}},
+  {0x043a, {1|U, {0x041a}}},
+  {0x043b, {1|U, {0x041b}}},
+  {0x043c, {1|U, {0x041c}}},
+  {0x043d, {1|U, {0x041d}}},
+  {0x043e, {2|U, {0x041e, 0x1c82}}},
+  {0x043f, {1|U, {0x041f}}},
+  {0x0440, {1|U, {0x0420}}},
+  {0x0441, {2|U, {0x0421, 0x1c83}}},
+  {0x0442, {3|U, {0x0422, 0x1c84, 0x1c85}}},
+  {0x0443, {1|U, {0x0423}}},
+  {0x0444, {1|U, {0x0424}}},
+  {0x0445, {1|U, {0x0425}}},
+  {0x0446, {1|U, {0x0426}}},
+  {0x0447, {1|U, {0x0427}}},
+  {0x0448, {1|U, {0x0428}}},
+  {0x0449, {1|U, {0x0429}}},
+  {0x044a, {2|U, {0x042a, 0x1c86}}},
+  {0x044b, {1|U, {0x042b}}},
+  {0x044c, {1|U, {0x042c}}},
+  {0x044d, {1|U, {0x042d}}},
+  {0x044e, {1|U, {0x042e}}},
+  {0x044f, {1|U, {0x042f}}},
+  {0x0450, {1|U, {0x0400}}},
+  {0x0451, {1|U, {0x0401}}},
+  {0x0452, {1|U, {0x0402}}},
+  {0x0453, {1|U, {0x0403}}},
+  {0x0454, {1|U, {0x0404}}},
+  {0x0455, {1|U, {0x0405}}},
+  {0x0456, {1|U, {0x0406}}},
+  {0x0457, {1|U, {0x0407}}},
+  {0x0458, {1|U, {0x0408}}},
+  {0x0459, {1|U, {0x0409}}},
+  {0x045a, {1|U, {0x040a}}},
+  {0x045b, {1|U, {0x040b}}},
+  {0x045c, {1|U, {0x040c}}},
+  {0x045d, {1|U, {0x040d}}},
+  {0x045e, {1|U, {0x040e}}},
+  {0x045f, {1|U, {0x040f}}},
+  {0x0461, {1|U, {0x0460}}},
+  {0x0463, {2|U, {0x0462, 0x1c87}}},
+  {0x0465, {1|U, {0x0464}}},
+  {0x0467, {1|U, {0x0466}}},
+  {0x0469, {1|U, {0x0468}}},
+  {0x046b, {1|U, {0x046a}}},
+  {0x046d, {1|U, {0x046c}}},
+  {0x046f, {1|U, {0x046e}}},
+  {0x0471, {1|U, {0x0470}}},
+  {0x0473, {1|U, {0x0472}}},
+  {0x0475, {1|U, {0x0474}}},
+  {0x0477, {1|U, {0x0476}}},
+  {0x0479, {1|U, {0x0478}}},
+  {0x047b, {1|U, {0x047a}}},
+  {0x047d, {1|U, {0x047c}}},
+  {0x047f, {1|U, {0x047e}}},
+  {0x0481, {1|U, {0x0480}}},
+  {0x048b, {1|U, {0x048a}}},
+  {0x048d, {1|U, {0x048c}}},
+  {0x048f, {1|U, {0x048e}}},
+  {0x0491, {1|U, {0x0490}}},
+  {0x0493, {1|U, {0x0492}}},
+  {0x0495, {1|U, {0x0494}}},
+  {0x0497, {1|U, {0x0496}}},
+  {0x0499, {1|U, {0x0498}}},
+  {0x049b, {1|U, {0x049a}}},
+  {0x049d, {1|U, {0x049c}}},
+  {0x049f, {1|U, {0x049e}}},
+  {0x04a1, {1|U, {0x04a0}}},
+  {0x04a3, {1|U, {0x04a2}}},
+  {0x04a5, {1|U, {0x04a4}}},
+  {0x04a7, {1|U, {0x04a6}}},
+  {0x04a9, {1|U, {0x04a8}}},
+  {0x04ab, {1|U, {0x04aa}}},
+  {0x04ad, {1|U, {0x04ac}}},
+  {0x04af, {1|U, {0x04ae}}},
+  {0x04b1, {1|U, {0x04b0}}},
+  {0x04b3, {1|U, {0x04b2}}},
+  {0x04b5, {1|U, {0x04b4}}},
+  {0x04b7, {1|U, {0x04b6}}},
+  {0x04b9, {1|U, {0x04b8}}},
+  {0x04bb, {1|U, {0x04ba}}},
+  {0x04bd, {1|U, {0x04bc}}},
+  {0x04bf, {1|U, {0x04be}}},
+  {0x04c2, {1|U, {0x04c1}}},
+  {0x04c4, {1|U, {0x04c3}}},
+  {0x04c6, {1|U, {0x04c5}}},
+  {0x04c8, {1|U, {0x04c7}}},
+  {0x04ca, {1|U, {0x04c9}}},
+  {0x04cc, {1|U, {0x04cb}}},
+  {0x04ce, {1|U, {0x04cd}}},
+  {0x04cf, {1|U, {0x04c0}}},
+  {0x04d1, {1|U, {0x04d0}}},
+  {0x04d3, {1|U, {0x04d2}}},
+  {0x04d5, {1|U, {0x04d4}}},
+  {0x04d7, {1|U, {0x04d6}}},
+  {0x04d9, {1|U, {0x04d8}}},
+  {0x04db, {1|U, {0x04da}}},
+  {0x04dd, {1|U, {0x04dc}}},
+  {0x04df, {1|U, {0x04de}}},
+  {0x04e1, {1|U, {0x04e0}}},
+  {0x04e3, {1|U, {0x04e2}}},
+  {0x04e5, {1|U, {0x04e4}}},
+  {0x04e7, {1|U, {0x04e6}}},
+  {0x04e9, {1|U, {0x04e8}}},
+  {0x04eb, {1|U, {0x04ea}}},
+  {0x04ed, {1|U, {0x04ec}}},
+  {0x04ef, {1|U, {0x04ee}}},
+  {0x04f1, {1|U, {0x04f0}}},
+  {0x04f3, {1|U, {0x04f2}}},
+  {0x04f5, {1|U, {0x04f4}}},
+  {0x04f7, {1|U, {0x04f6}}},
+  {0x04f9, {1|U, {0x04f8}}},
+  {0x04fb, {1|U, {0x04fa}}},
+  {0x04fd, {1|U, {0x04fc}}},
+  {0x04ff, {1|U, {0x04fe}}},
+  {0x0501, {1|U, {0x0500}}},
+  {0x0503, {1|U, {0x0502}}},
+  {0x0505, {1|U, {0x0504}}},
+  {0x0507, {1|U, {0x0506}}},
+  {0x0509, {1|U, {0x0508}}},
+  {0x050b, {1|U, {0x050a}}},
+  {0x050d, {1|U, {0x050c}}},
+  {0x050f, {1|U, {0x050e}}},
+  {0x0511, {1|U, {0x0510}}},
+  {0x0513, {1|U, {0x0512}}},
+  {0x0515, {1|U, {0x0514}}},
+  {0x0517, {1|U, {0x0516}}},
+  {0x0519, {1|U, {0x0518}}},
+  {0x051b, {1|U, {0x051a}}},
+  {0x051d, {1|U, {0x051c}}},
+  {0x051f, {1|U, {0x051e}}},
+  {0x0521, {1|U, {0x0520}}},
+  {0x0523, {1|U, {0x0522}}},
+  {0x0525, {1|U, {0x0524}}},
+  {0x0527, {1|U, {0x0526}}},
+  {0x0529, {1|U, {0x0528}}},
+  {0x052b, {1|U, {0x052a}}},
+  {0x052d, {1|U, {0x052c}}},
+  {0x052f, {1|U, {0x052e}}},
+  {0x0561, {1|U, {0x0531}}},
+  {0x0562, {1|U, {0x0532}}},
+  {0x0563, {1|U, {0x0533}}},
+  {0x0564, {1|U, {0x0534}}},
+  {0x0565, {1|U, {0x0535}}},
+  {0x0566, {1|U, {0x0536}}},
+  {0x0567, {1|U, {0x0537}}},
+  {0x0568, {1|U, {0x0538}}},
+  {0x0569, {1|U, {0x0539}}},
+  {0x056a, {1|U, {0x053a}}},
+  {0x056b, {1|U, {0x053b}}},
+  {0x056c, {1|U, {0x053c}}},
+  {0x056d, {1|U, {0x053d}}},
+  {0x056e, {1|U, {0x053e}}},
+  {0x056f, {1|U, {0x053f}}},
+  {0x0570, {1|U, {0x0540}}},
+  {0x0571, {1|U, {0x0541}}},
+  {0x0572, {1|U, {0x0542}}},
+  {0x0573, {1|U, {0x0543}}},
+  {0x0574, {1|U, {0x0544}}},
+  {0x0575, {1|U, {0x0545}}},
+  {0x0576, {1|U, {0x0546}}},
+  {0x0577, {1|U, {0x0547}}},
+  {0x0578, {1|U, {0x0548}}},
+  {0x0579, {1|U, {0x0549}}},
+  {0x057a, {1|U, {0x054a}}},
+  {0x057b, {1|U, {0x054b}}},
+  {0x057c, {1|U, {0x054c}}},
+  {0x057d, {1|U, {0x054d}}},
+  {0x057e, {1|U, {0x054e}}},
+  {0x057f, {1|U, {0x054f}}},
+  {0x0580, {1|U, {0x0550}}},
+  {0x0581, {1|U, {0x0551}}},
+  {0x0582, {1|U, {0x0552}}},
+  {0x0583, {1|U, {0x0553}}},
+  {0x0584, {1|U, {0x0554}}},
+  {0x0585, {1|U, {0x0555}}},
+  {0x0586, {1|U, {0x0556}}},
+  {0x13a0, {1|D, {0xab70}}},
+  {0x13a1, {1|D, {0xab71}}},
+  {0x13a2, {1|D, {0xab72}}},
+  {0x13a3, {1|D, {0xab73}}},
+  {0x13a4, {1|D, {0xab74}}},
+  {0x13a5, {1|D, {0xab75}}},
+  {0x13a6, {1|D, {0xab76}}},
+  {0x13a7, {1|D, {0xab77}}},
+  {0x13a8, {1|D, {0xab78}}},
+  {0x13a9, {1|D, {0xab79}}},
+  {0x13aa, {1|D, {0xab7a}}},
+  {0x13ab, {1|D, {0xab7b}}},
+  {0x13ac, {1|D, {0xab7c}}},
+  {0x13ad, {1|D, {0xab7d}}},
+  {0x13ae, {1|D, {0xab7e}}},
+  {0x13af, {1|D, {0xab7f}}},
+  {0x13b0, {1|D, {0xab80}}},
+  {0x13b1, {1|D, {0xab81}}},
+  {0x13b2, {1|D, {0xab82}}},
+  {0x13b3, {1|D, {0xab83}}},
+  {0x13b4, {1|D, {0xab84}}},
+  {0x13b5, {1|D, {0xab85}}},
+  {0x13b6, {1|D, {0xab86}}},
+  {0x13b7, {1|D, {0xab87}}},
+  {0x13b8, {1|D, {0xab88}}},
+  {0x13b9, {1|D, {0xab89}}},
+  {0x13ba, {1|D, {0xab8a}}},
+  {0x13bb, {1|D, {0xab8b}}},
+  {0x13bc, {1|D, {0xab8c}}},
+  {0x13bd, {1|D, {0xab8d}}},
+  {0x13be, {1|D, {0xab8e}}},
+  {0x13bf, {1|D, {0xab8f}}},
+  {0x13c0, {1|D, {0xab90}}},
+  {0x13c1, {1|D, {0xab91}}},
+  {0x13c2, {1|D, {0xab92}}},
+  {0x13c3, {1|D, {0xab93}}},
+  {0x13c4, {1|D, {0xab94}}},
+  {0x13c5, {1|D, {0xab95}}},
+  {0x13c6, {1|D, {0xab96}}},
+  {0x13c7, {1|D, {0xab97}}},
+  {0x13c8, {1|D, {0xab98}}},
+  {0x13c9, {1|D, {0xab99}}},
+  {0x13ca, {1|D, {0xab9a}}},
+  {0x13cb, {1|D, {0xab9b}}},
+  {0x13cc, {1|D, {0xab9c}}},
+  {0x13cd, {1|D, {0xab9d}}},
+  {0x13ce, {1|D, {0xab9e}}},
+  {0x13cf, {1|D, {0xab9f}}},
+  {0x13d0, {1|D, {0xaba0}}},
+  {0x13d1, {1|D, {0xaba1}}},
+  {0x13d2, {1|D, {0xaba2}}},
+  {0x13d3, {1|D, {0xaba3}}},
+  {0x13d4, {1|D, {0xaba4}}},
+  {0x13d5, {1|D, {0xaba5}}},
+  {0x13d6, {1|D, {0xaba6}}},
+  {0x13d7, {1|D, {0xaba7}}},
+  {0x13d8, {1|D, {0xaba8}}},
+  {0x13d9, {1|D, {0xaba9}}},
+  {0x13da, {1|D, {0xabaa}}},
+  {0x13db, {1|D, {0xabab}}},
+  {0x13dc, {1|D, {0xabac}}},
+  {0x13dd, {1|D, {0xabad}}},
+  {0x13de, {1|D, {0xabae}}},
+  {0x13df, {1|D, {0xabaf}}},
+  {0x13e0, {1|D, {0xabb0}}},
+  {0x13e1, {1|D, {0xabb1}}},
+  {0x13e2, {1|D, {0xabb2}}},
+  {0x13e3, {1|D, {0xabb3}}},
+  {0x13e4, {1|D, {0xabb4}}},
+  {0x13e5, {1|D, {0xabb5}}},
+  {0x13e6, {1|D, {0xabb6}}},
+  {0x13e7, {1|D, {0xabb7}}},
+  {0x13e8, {1|D, {0xabb8}}},
+  {0x13e9, {1|D, {0xabb9}}},
+  {0x13ea, {1|D, {0xabba}}},
+  {0x13eb, {1|D, {0xabbb}}},
+  {0x13ec, {1|D, {0xabbc}}},
+  {0x13ed, {1|D, {0xabbd}}},
+  {0x13ee, {1|D, {0xabbe}}},
+  {0x13ef, {1|D, {0xabbf}}},
+  {0x13f0, {1|D, {0x13f8}}},
+  {0x13f1, {1|D, {0x13f9}}},
+  {0x13f2, {1|D, {0x13fa}}},
+  {0x13f3, {1|D, {0x13fb}}},
+  {0x13f4, {1|D, {0x13fc}}},
+  {0x13f5, {1|D, {0x13fd}}},
+  {0x1d79, {1|U, {0xa77d}}},
+  {0x1d7d, {1|U, {0x2c63}}},
+  {0x1e01, {1|U, {0x1e00}}},
+  {0x1e03, {1|U, {0x1e02}}},
+  {0x1e05, {1|U, {0x1e04}}},
+  {0x1e07, {1|U, {0x1e06}}},
+  {0x1e09, {1|U, {0x1e08}}},
+  {0x1e0b, {1|U, {0x1e0a}}},
+  {0x1e0d, {1|U, {0x1e0c}}},
+  {0x1e0f, {1|U, {0x1e0e}}},
+  {0x1e11, {1|U, {0x1e10}}},
+  {0x1e13, {1|U, {0x1e12}}},
+  {0x1e15, {1|U, {0x1e14}}},
+  {0x1e17, {1|U, {0x1e16}}},
+  {0x1e19, {1|U, {0x1e18}}},
+  {0x1e1b, {1|U, {0x1e1a}}},
+  {0x1e1d, {1|U, {0x1e1c}}},
+  {0x1e1f, {1|U, {0x1e1e}}},
+  {0x1e21, {1|U, {0x1e20}}},
+  {0x1e23, {1|U, {0x1e22}}},
+  {0x1e25, {1|U, {0x1e24}}},
+  {0x1e27, {1|U, {0x1e26}}},
+  {0x1e29, {1|U, {0x1e28}}},
+  {0x1e2b, {1|U, {0x1e2a}}},
+  {0x1e2d, {1|U, {0x1e2c}}},
+  {0x1e2f, {1|U, {0x1e2e}}},
+  {0x1e31, {1|U, {0x1e30}}},
+  {0x1e33, {1|U, {0x1e32}}},
+  {0x1e35, {1|U, {0x1e34}}},
+  {0x1e37, {1|U, {0x1e36}}},
+  {0x1e39, {1|U, {0x1e38}}},
+  {0x1e3b, {1|U, {0x1e3a}}},
+  {0x1e3d, {1|U, {0x1e3c}}},
+  {0x1e3f, {1|U, {0x1e3e}}},
+  {0x1e41, {1|U, {0x1e40}}},
+  {0x1e43, {1|U, {0x1e42}}},
+  {0x1e45, {1|U, {0x1e44}}},
+  {0x1e47, {1|U, {0x1e46}}},
+  {0x1e49, {1|U, {0x1e48}}},
+  {0x1e4b, {1|U, {0x1e4a}}},
+  {0x1e4d, {1|U, {0x1e4c}}},
+  {0x1e4f, {1|U, {0x1e4e}}},
+  {0x1e51, {1|U, {0x1e50}}},
+  {0x1e53, {1|U, {0x1e52}}},
+  {0x1e55, {1|U, {0x1e54}}},
+  {0x1e57, {1|U, {0x1e56}}},
+  {0x1e59, {1|U, {0x1e58}}},
+  {0x1e5b, {1|U, {0x1e5a}}},
+  {0x1e5d, {1|U, {0x1e5c}}},
+  {0x1e5f, {1|U, {0x1e5e}}},
+  {0x1e61, {2|U, {0x1e60, 0x1e9b}}},
+  {0x1e63, {1|U, {0x1e62}}},
+  {0x1e65, {1|U, {0x1e64}}},
+  {0x1e67, {1|U, {0x1e66}}},
+  {0x1e69, {1|U, {0x1e68}}},
+  {0x1e6b, {1|U, {0x1e6a}}},
+  {0x1e6d, {1|U, {0x1e6c}}},
+  {0x1e6f, {1|U, {0x1e6e}}},
+  {0x1e71, {1|U, {0x1e70}}},
+  {0x1e73, {1|U, {0x1e72}}},
+  {0x1e75, {1|U, {0x1e74}}},
+  {0x1e77, {1|U, {0x1e76}}},
+  {0x1e79, {1|U, {0x1e78}}},
+  {0x1e7b, {1|U, {0x1e7a}}},
+  {0x1e7d, {1|U, {0x1e7c}}},
+  {0x1e7f, {1|U, {0x1e7e}}},
+  {0x1e81, {1|U, {0x1e80}}},
+  {0x1e83, {1|U, {0x1e82}}},
+  {0x1e85, {1|U, {0x1e84}}},
+  {0x1e87, {1|U, {0x1e86}}},
+  {0x1e89, {1|U, {0x1e88}}},
+  {0x1e8b, {1|U, {0x1e8a}}},
+  {0x1e8d, {1|U, {0x1e8c}}},
+  {0x1e8f, {1|U, {0x1e8e}}},
+  {0x1e91, {1|U, {0x1e90}}},
+  {0x1e93, {1|U, {0x1e92}}},
+  {0x1e95, {1|U, {0x1e94}}},
+  {0x1ea1, {1|U, {0x1ea0}}},
+  {0x1ea3, {1|U, {0x1ea2}}},
+  {0x1ea5, {1|U, {0x1ea4}}},
+  {0x1ea7, {1|U, {0x1ea6}}},
+  {0x1ea9, {1|U, {0x1ea8}}},
+  {0x1eab, {1|U, {0x1eaa}}},
+  {0x1ead, {1|U, {0x1eac}}},
+  {0x1eaf, {1|U, {0x1eae}}},
+  {0x1eb1, {1|U, {0x1eb0}}},
+  {0x1eb3, {1|U, {0x1eb2}}},
+  {0x1eb5, {1|U, {0x1eb4}}},
+  {0x1eb7, {1|U, {0x1eb6}}},
+  {0x1eb9, {1|U, {0x1eb8}}},
+  {0x1ebb, {1|U, {0x1eba}}},
+  {0x1ebd, {1|U, {0x1ebc}}},
+  {0x1ebf, {1|U, {0x1ebe}}},
+  {0x1ec1, {1|U, {0x1ec0}}},
+  {0x1ec3, {1|U, {0x1ec2}}},
+  {0x1ec5, {1|U, {0x1ec4}}},
+  {0x1ec7, {1|U, {0x1ec6}}},
+  {0x1ec9, {1|U, {0x1ec8}}},
+  {0x1ecb, {1|U, {0x1eca}}},
+  {0x1ecd, {1|U, {0x1ecc}}},
+  {0x1ecf, {1|U, {0x1ece}}},
+  {0x1ed1, {1|U, {0x1ed0}}},
+  {0x1ed3, {1|U, {0x1ed2}}},
+  {0x1ed5, {1|U, {0x1ed4}}},
+  {0x1ed7, {1|U, {0x1ed6}}},
+  {0x1ed9, {1|U, {0x1ed8}}},
+  {0x1edb, {1|U, {0x1eda}}},
+  {0x1edd, {1|U, {0x1edc}}},
+  {0x1edf, {1|U, {0x1ede}}},
+  {0x1ee1, {1|U, {0x1ee0}}},
+  {0x1ee3, {1|U, {0x1ee2}}},
+  {0x1ee5, {1|U, {0x1ee4}}},
+  {0x1ee7, {1|U, {0x1ee6}}},
+  {0x1ee9, {1|U, {0x1ee8}}},
+  {0x1eeb, {1|U, {0x1eea}}},
+  {0x1eed, {1|U, {0x1eec}}},
+  {0x1eef, {1|U, {0x1eee}}},
+  {0x1ef1, {1|U, {0x1ef0}}},
+  {0x1ef3, {1|U, {0x1ef2}}},
+  {0x1ef5, {1|U, {0x1ef4}}},
+  {0x1ef7, {1|U, {0x1ef6}}},
+  {0x1ef9, {1|U, {0x1ef8}}},
+  {0x1efb, {1|U, {0x1efa}}},
+  {0x1efd, {1|U, {0x1efc}}},
+  {0x1eff, {1|U, {0x1efe}}},
+  {0x1f00, {1|U, {0x1f08}}},
+  {0x1f01, {1|U, {0x1f09}}},
+  {0x1f02, {1|U, {0x1f0a}}},
+  {0x1f03, {1|U, {0x1f0b}}},
+  {0x1f04, {1|U, {0x1f0c}}},
+  {0x1f05, {1|U, {0x1f0d}}},
+  {0x1f06, {1|U, {0x1f0e}}},
+  {0x1f07, {1|U, {0x1f0f}}},
+  {0x1f10, {1|U, {0x1f18}}},
+  {0x1f11, {1|U, {0x1f19}}},
+  {0x1f12, {1|U, {0x1f1a}}},
+  {0x1f13, {1|U, {0x1f1b}}},
+  {0x1f14, {1|U, {0x1f1c}}},
+  {0x1f15, {1|U, {0x1f1d}}},
+  {0x1f20, {1|U, {0x1f28}}},
+  {0x1f21, {1|U, {0x1f29}}},
+  {0x1f22, {1|U, {0x1f2a}}},
+  {0x1f23, {1|U, {0x1f2b}}},
+  {0x1f24, {1|U, {0x1f2c}}},
+  {0x1f25, {1|U, {0x1f2d}}},
+  {0x1f26, {1|U, {0x1f2e}}},
+  {0x1f27, {1|U, {0x1f2f}}},
+  {0x1f30, {1|U, {0x1f38}}},
+  {0x1f31, {1|U, {0x1f39}}},
+  {0x1f32, {1|U, {0x1f3a}}},
+  {0x1f33, {1|U, {0x1f3b}}},
+  {0x1f34, {1|U, {0x1f3c}}},
+  {0x1f35, {1|U, {0x1f3d}}},
+  {0x1f36, {1|U, {0x1f3e}}},
+  {0x1f37, {1|U, {0x1f3f}}},
+  {0x1f40, {1|U, {0x1f48}}},
+  {0x1f41, {1|U, {0x1f49}}},
+  {0x1f42, {1|U, {0x1f4a}}},
+  {0x1f43, {1|U, {0x1f4b}}},
+  {0x1f44, {1|U, {0x1f4c}}},
+  {0x1f45, {1|U, {0x1f4d}}},
+  {0x1f51, {1|U, {0x1f59}}},
+  {0x1f53, {1|U, {0x1f5b}}},
+  {0x1f55, {1|U, {0x1f5d}}},
+  {0x1f57, {1|U, {0x1f5f}}},
+  {0x1f60, {1|U, {0x1f68}}},
+  {0x1f61, {1|U, {0x1f69}}},
+  {0x1f62, {1|U, {0x1f6a}}},
+  {0x1f63, {1|U, {0x1f6b}}},
+  {0x1f64, {1|U, {0x1f6c}}},
+  {0x1f65, {1|U, {0x1f6d}}},
+  {0x1f66, {1|U, {0x1f6e}}},
+  {0x1f67, {1|U, {0x1f6f}}},
+  {0x1f70, {1|U, {0x1fba}}},
+  {0x1f71, {1|U, {0x1fbb}}},
+  {0x1f72, {1|U, {0x1fc8}}},
+  {0x1f73, {1|U, {0x1fc9}}},
+  {0x1f74, {1|U, {0x1fca}}},
+  {0x1f75, {1|U, {0x1fcb}}},
+  {0x1f76, {1|U, {0x1fda}}},
+  {0x1f77, {1|U, {0x1fdb}}},
+  {0x1f78, {1|U, {0x1ff8}}},
+  {0x1f79, {1|U, {0x1ff9}}},
+  {0x1f7a, {1|U, {0x1fea}}},
+  {0x1f7b, {1|U, {0x1feb}}},
+  {0x1f7c, {1|U, {0x1ffa}}},
+  {0x1f7d, {1|U, {0x1ffb}}},
+  {0x1fb0, {1|U, {0x1fb8}}},
+  {0x1fb1, {1|U, {0x1fb9}}},
+  {0x1fd0, {1|U, {0x1fd8}}},
+  {0x1fd1, {1|U, {0x1fd9}}},
+  {0x1fe0, {1|U, {0x1fe8}}},
+  {0x1fe1, {1|U, {0x1fe9}}},
+  {0x1fe5, {1|U, {0x1fec}}},
+  {0x214e, {1|U, {0x2132}}},
+  {0x2170, {1|U, {0x2160}}},
+  {0x2171, {1|U, {0x2161}}},
+  {0x2172, {1|U, {0x2162}}},
+  {0x2173, {1|U, {0x2163}}},
+  {0x2174, {1|U, {0x2164}}},
+  {0x2175, {1|U, {0x2165}}},
+  {0x2176, {1|U, {0x2166}}},
+  {0x2177, {1|U, {0x2167}}},
+  {0x2178, {1|U, {0x2168}}},
+  {0x2179, {1|U, {0x2169}}},
+  {0x217a, {1|U, {0x216a}}},
+  {0x217b, {1|U, {0x216b}}},
+  {0x217c, {1|U, {0x216c}}},
+  {0x217d, {1|U, {0x216d}}},
+  {0x217e, {1|U, {0x216e}}},
+  {0x217f, {1|U, {0x216f}}},
+  {0x2184, {1|U, {0x2183}}},
+  {0x24d0, {1|U, {0x24b6}}},
+  {0x24d1, {1|U, {0x24b7}}},
+  {0x24d2, {1|U, {0x24b8}}},
+  {0x24d3, {1|U, {0x24b9}}},
+  {0x24d4, {1|U, {0x24ba}}},
+  {0x24d5, {1|U, {0x24bb}}},
+  {0x24d6, {1|U, {0x24bc}}},
+  {0x24d7, {1|U, {0x24bd}}},
+  {0x24d8, {1|U, {0x24be}}},
+  {0x24d9, {1|U, {0x24bf}}},
+  {0x24da, {1|U, {0x24c0}}},
+  {0x24db, {1|U, {0x24c1}}},
+  {0x24dc, {1|U, {0x24c2}}},
+  {0x24dd, {1|U, {0x24c3}}},
+  {0x24de, {1|U, {0x24c4}}},
+  {0x24df, {1|U, {0x24c5}}},
+  {0x24e0, {1|U, {0x24c6}}},
+  {0x24e1, {1|U, {0x24c7}}},
+  {0x24e2, {1|U, {0x24c8}}},
+  {0x24e3, {1|U, {0x24c9}}},
+  {0x24e4, {1|U, {0x24ca}}},
+  {0x24e5, {1|U, {0x24cb}}},
+  {0x24e6, {1|U, {0x24cc}}},
+  {0x24e7, {1|U, {0x24cd}}},
+  {0x24e8, {1|U, {0x24ce}}},
+  {0x24e9, {1|U, {0x24cf}}},
+  {0x2c30, {1|U, {0x2c00}}},
+  {0x2c31, {1|U, {0x2c01}}},
+  {0x2c32, {1|U, {0x2c02}}},
+  {0x2c33, {1|U, {0x2c03}}},
+  {0x2c34, {1|U, {0x2c04}}},
+  {0x2c35, {1|U, {0x2c05}}},
+  {0x2c36, {1|U, {0x2c06}}},
+  {0x2c37, {1|U, {0x2c07}}},
+  {0x2c38, {1|U, {0x2c08}}},
+  {0x2c39, {1|U, {0x2c09}}},
+  {0x2c3a, {1|U, {0x2c0a}}},
+  {0x2c3b, {1|U, {0x2c0b}}},
+  {0x2c3c, {1|U, {0x2c0c}}},
+  {0x2c3d, {1|U, {0x2c0d}}},
+  {0x2c3e, {1|U, {0x2c0e}}},
+  {0x2c3f, {1|U, {0x2c0f}}},
+  {0x2c40, {1|U, {0x2c10}}},
+  {0x2c41, {1|U, {0x2c11}}},
+  {0x2c42, {1|U, {0x2c12}}},
+  {0x2c43, {1|U, {0x2c13}}},
+  {0x2c44, {1|U, {0x2c14}}},
+  {0x2c45, {1|U, {0x2c15}}},
+  {0x2c46, {1|U, {0x2c16}}},
+  {0x2c47, {1|U, {0x2c17}}},
+  {0x2c48, {1|U, {0x2c18}}},
+  {0x2c49, {1|U, {0x2c19}}},
+  {0x2c4a, {1|U, {0x2c1a}}},
+  {0x2c4b, {1|U, {0x2c1b}}},
+  {0x2c4c, {1|U, {0x2c1c}}},
+  {0x2c4d, {1|U, {0x2c1d}}},
+  {0x2c4e, {1|U, {0x2c1e}}},
+  {0x2c4f, {1|U, {0x2c1f}}},
+  {0x2c50, {1|U, {0x2c20}}},
+  {0x2c51, {1|U, {0x2c21}}},
+  {0x2c52, {1|U, {0x2c22}}},
+  {0x2c53, {1|U, {0x2c23}}},
+  {0x2c54, {1|U, {0x2c24}}},
+  {0x2c55, {1|U, {0x2c25}}},
+  {0x2c56, {1|U, {0x2c26}}},
+  {0x2c57, {1|U, {0x2c27}}},
+  {0x2c58, {1|U, {0x2c28}}},
+  {0x2c59, {1|U, {0x2c29}}},
+  {0x2c5a, {1|U, {0x2c2a}}},
+  {0x2c5b, {1|U, {0x2c2b}}},
+  {0x2c5c, {1|U, {0x2c2c}}},
+  {0x2c5d, {1|U, {0x2c2d}}},
+  {0x2c5e, {1|U, {0x2c2e}}},
+  {0x2c61, {1|U, {0x2c60}}},
+  {0x2c65, {1|U, {0x023a}}},
+  {0x2c66, {1|U, {0x023e}}},
+  {0x2c68, {1|U, {0x2c67}}},
+  {0x2c6a, {1|U, {0x2c69}}},
+  {0x2c6c, {1|U, {0x2c6b}}},
+  {0x2c73, {1|U, {0x2c72}}},
+  {0x2c76, {1|U, {0x2c75}}},
+  {0x2c81, {1|U, {0x2c80}}},
+  {0x2c83, {1|U, {0x2c82}}},
+  {0x2c85, {1|U, {0x2c84}}},
+  {0x2c87, {1|U, {0x2c86}}},
+  {0x2c89, {1|U, {0x2c88}}},
+  {0x2c8b, {1|U, {0x2c8a}}},
+  {0x2c8d, {1|U, {0x2c8c}}},
+  {0x2c8f, {1|U, {0x2c8e}}},
+  {0x2c91, {1|U, {0x2c90}}},
+  {0x2c93, {1|U, {0x2c92}}},
+  {0x2c95, {1|U, {0x2c94}}},
+  {0x2c97, {1|U, {0x2c96}}},
+  {0x2c99, {1|U, {0x2c98}}},
+  {0x2c9b, {1|U, {0x2c9a}}},
+  {0x2c9d, {1|U, {0x2c9c}}},
+  {0x2c9f, {1|U, {0x2c9e}}},
+  {0x2ca1, {1|U, {0x2ca0}}},
+  {0x2ca3, {1|U, {0x2ca2}}},
+  {0x2ca5, {1|U, {0x2ca4}}},
+  {0x2ca7, {1|U, {0x2ca6}}},
+  {0x2ca9, {1|U, {0x2ca8}}},
+  {0x2cab, {1|U, {0x2caa}}},
+  {0x2cad, {1|U, {0x2cac}}},
+  {0x2caf, {1|U, {0x2cae}}},
+  {0x2cb1, {1|U, {0x2cb0}}},
+  {0x2cb3, {1|U, {0x2cb2}}},
+  {0x2cb5, {1|U, {0x2cb4}}},
+  {0x2cb7, {1|U, {0x2cb6}}},
+  {0x2cb9, {1|U, {0x2cb8}}},
+  {0x2cbb, {1|U, {0x2cba}}},
+  {0x2cbd, {1|U, {0x2cbc}}},
+  {0x2cbf, {1|U, {0x2cbe}}},
+  {0x2cc1, {1|U, {0x2cc0}}},
+  {0x2cc3, {1|U, {0x2cc2}}},
+  {0x2cc5, {1|U, {0x2cc4}}},
+  {0x2cc7, {1|U, {0x2cc6}}},
+  {0x2cc9, {1|U, {0x2cc8}}},
+  {0x2ccb, {1|U, {0x2cca}}},
+  {0x2ccd, {1|U, {0x2ccc}}},
+  {0x2ccf, {1|U, {0x2cce}}},
+  {0x2cd1, {1|U, {0x2cd0}}},
+  {0x2cd3, {1|U, {0x2cd2}}},
+  {0x2cd5, {1|U, {0x2cd4}}},
+  {0x2cd7, {1|U, {0x2cd6}}},
+  {0x2cd9, {1|U, {0x2cd8}}},
+  {0x2cdb, {1|U, {0x2cda}}},
+  {0x2cdd, {1|U, {0x2cdc}}},
+  {0x2cdf, {1|U, {0x2cde}}},
+  {0x2ce1, {1|U, {0x2ce0}}},
+  {0x2ce3, {1|U, {0x2ce2}}},
+  {0x2cec, {1|U, {0x2ceb}}},
+  {0x2cee, {1|U, {0x2ced}}},
+  {0x2cf3, {1|U, {0x2cf2}}},
+  {0x2d00, {1|U, {0x10a0}}},
+  {0x2d01, {1|U, {0x10a1}}},
+  {0x2d02, {1|U, {0x10a2}}},
+  {0x2d03, {1|U, {0x10a3}}},
+  {0x2d04, {1|U, {0x10a4}}},
+  {0x2d05, {1|U, {0x10a5}}},
+  {0x2d06, {1|U, {0x10a6}}},
+  {0x2d07, {1|U, {0x10a7}}},
+  {0x2d08, {1|U, {0x10a8}}},
+  {0x2d09, {1|U, {0x10a9}}},
+  {0x2d0a, {1|U, {0x10aa}}},
+  {0x2d0b, {1|U, {0x10ab}}},
+  {0x2d0c, {1|U, {0x10ac}}},
+  {0x2d0d, {1|U, {0x10ad}}},
+  {0x2d0e, {1|U, {0x10ae}}},
+  {0x2d0f, {1|U, {0x10af}}},
+  {0x2d10, {1|U, {0x10b0}}},
+  {0x2d11, {1|U, {0x10b1}}},
+  {0x2d12, {1|U, {0x10b2}}},
+  {0x2d13, {1|U, {0x10b3}}},
+  {0x2d14, {1|U, {0x10b4}}},
+  {0x2d15, {1|U, {0x10b5}}},
+  {0x2d16, {1|U, {0x10b6}}},
+  {0x2d17, {1|U, {0x10b7}}},
+  {0x2d18, {1|U, {0x10b8}}},
+  {0x2d19, {1|U, {0x10b9}}},
+  {0x2d1a, {1|U, {0x10ba}}},
+  {0x2d1b, {1|U, {0x10bb}}},
+  {0x2d1c, {1|U, {0x10bc}}},
+  {0x2d1d, {1|U, {0x10bd}}},
+  {0x2d1e, {1|U, {0x10be}}},
+  {0x2d1f, {1|U, {0x10bf}}},
+  {0x2d20, {1|U, {0x10c0}}},
+  {0x2d21, {1|U, {0x10c1}}},
+  {0x2d22, {1|U, {0x10c2}}},
+  {0x2d23, {1|U, {0x10c3}}},
+  {0x2d24, {1|U, {0x10c4}}},
+  {0x2d25, {1|U, {0x10c5}}},
+  {0x2d27, {1|U, {0x10c7}}},
+  {0x2d2d, {1|U, {0x10cd}}},
+  {0xa641, {1|U, {0xa640}}},
+  {0xa643, {1|U, {0xa642}}},
+  {0xa645, {1|U, {0xa644}}},
+  {0xa647, {1|U, {0xa646}}},
+  {0xa649, {1|U, {0xa648}}},
+  {0xa64b, {2|U, {0xa64a, 0x1c88}}},
+  {0xa64d, {1|U, {0xa64c}}},
+  {0xa64f, {1|U, {0xa64e}}},
+  {0xa651, {1|U, {0xa650}}},
+  {0xa653, {1|U, {0xa652}}},
+  {0xa655, {1|U, {0xa654}}},
+  {0xa657, {1|U, {0xa656}}},
+  {0xa659, {1|U, {0xa658}}},
+  {0xa65b, {1|U, {0xa65a}}},
+  {0xa65d, {1|U, {0xa65c}}},
+  {0xa65f, {1|U, {0xa65e}}},
+  {0xa661, {1|U, {0xa660}}},
+  {0xa663, {1|U, {0xa662}}},
+  {0xa665, {1|U, {0xa664}}},
+  {0xa667, {1|U, {0xa666}}},
+  {0xa669, {1|U, {0xa668}}},
+  {0xa66b, {1|U, {0xa66a}}},
+  {0xa66d, {1|U, {0xa66c}}},
+  {0xa681, {1|U, {0xa680}}},
+  {0xa683, {1|U, {0xa682}}},
+  {0xa685, {1|U, {0xa684}}},
+  {0xa687, {1|U, {0xa686}}},
+  {0xa689, {1|U, {0xa688}}},
+  {0xa68b, {1|U, {0xa68a}}},
+  {0xa68d, {1|U, {0xa68c}}},
+  {0xa68f, {1|U, {0xa68e}}},
+  {0xa691, {1|U, {0xa690}}},
+  {0xa693, {1|U, {0xa692}}},
+  {0xa695, {1|U, {0xa694}}},
+  {0xa697, {1|U, {0xa696}}},
+  {0xa699, {1|U, {0xa698}}},
+  {0xa69b, {1|U, {0xa69a}}},
+  {0xa723, {1|U, {0xa722}}},
+  {0xa725, {1|U, {0xa724}}},
+  {0xa727, {1|U, {0xa726}}},
+  {0xa729, {1|U, {0xa728}}},
+  {0xa72b, {1|U, {0xa72a}}},
+  {0xa72d, {1|U, {0xa72c}}},
+  {0xa72f, {1|U, {0xa72e}}},
+  {0xa733, {1|U, {0xa732}}},
+  {0xa735, {1|U, {0xa734}}},
+  {0xa737, {1|U, {0xa736}}},
+  {0xa739, {1|U, {0xa738}}},
+  {0xa73b, {1|U, {0xa73a}}},
+  {0xa73d, {1|U, {0xa73c}}},
+  {0xa73f, {1|U, {0xa73e}}},
+  {0xa741, {1|U, {0xa740}}},
+  {0xa743, {1|U, {0xa742}}},
+  {0xa745, {1|U, {0xa744}}},
+  {0xa747, {1|U, {0xa746}}},
+  {0xa749, {1|U, {0xa748}}},
+  {0xa74b, {1|U, {0xa74a}}},
+  {0xa74d, {1|U, {0xa74c}}},
+  {0xa74f, {1|U, {0xa74e}}},
+  {0xa751, {1|U, {0xa750}}},
+  {0xa753, {1|U, {0xa752}}},
+  {0xa755, {1|U, {0xa754}}},
+  {0xa757, {1|U, {0xa756}}},
+  {0xa759, {1|U, {0xa758}}},
+  {0xa75b, {1|U, {0xa75a}}},
+  {0xa75d, {1|U, {0xa75c}}},
+  {0xa75f, {1|U, {0xa75e}}},
+  {0xa761, {1|U, {0xa760}}},
+  {0xa763, {1|U, {0xa762}}},
+  {0xa765, {1|U, {0xa764}}},
+  {0xa767, {1|U, {0xa766}}},
+  {0xa769, {1|U, {0xa768}}},
+  {0xa76b, {1|U, {0xa76a}}},
+  {0xa76d, {1|U, {0xa76c}}},
+  {0xa76f, {1|U, {0xa76e}}},
+  {0xa77a, {1|U, {0xa779}}},
+  {0xa77c, {1|U, {0xa77b}}},
+  {0xa77f, {1|U, {0xa77e}}},
+  {0xa781, {1|U, {0xa780}}},
+  {0xa783, {1|U, {0xa782}}},
+  {0xa785, {1|U, {0xa784}}},
+  {0xa787, {1|U, {0xa786}}},
+  {0xa78c, {1|U, {0xa78b}}},
+  {0xa791, {1|U, {0xa790}}},
+  {0xa793, {1|U, {0xa792}}},
+  {0xa797, {1|U, {0xa796}}},
+  {0xa799, {1|U, {0xa798}}},
+  {0xa79b, {1|U, {0xa79a}}},
+  {0xa79d, {1|U, {0xa79c}}},
+  {0xa79f, {1|U, {0xa79e}}},
+  {0xa7a1, {1|U, {0xa7a0}}},
+  {0xa7a3, {1|U, {0xa7a2}}},
+  {0xa7a5, {1|U, {0xa7a4}}},
+  {0xa7a7, {1|U, {0xa7a6}}},
+  {0xa7a9, {1|U, {0xa7a8}}},
+  {0xa7b5, {1|U, {0xa7b4}}},
+  {0xa7b7, {1|U, {0xa7b6}}},
+  {0xab53, {1|U, {0xa7b3}}},
+  {0xff41, {1|U, {0xff21}}},
+  {0xff42, {1|U, {0xff22}}},
+  {0xff43, {1|U, {0xff23}}},
+  {0xff44, {1|U, {0xff24}}},
+  {0xff45, {1|U, {0xff25}}},
+  {0xff46, {1|U, {0xff26}}},
+  {0xff47, {1|U, {0xff27}}},
+  {0xff48, {1|U, {0xff28}}},
+  {0xff49, {1|U, {0xff29}}},
+  {0xff4a, {1|U, {0xff2a}}},
+  {0xff4b, {1|U, {0xff2b}}},
+  {0xff4c, {1|U, {0xff2c}}},
+  {0xff4d, {1|U, {0xff2d}}},
+  {0xff4e, {1|U, {0xff2e}}},
+  {0xff4f, {1|U, {0xff2f}}},
+  {0xff50, {1|U, {0xff30}}},
+  {0xff51, {1|U, {0xff31}}},
+  {0xff52, {1|U, {0xff32}}},
+  {0xff53, {1|U, {0xff33}}},
+  {0xff54, {1|U, {0xff34}}},
+  {0xff55, {1|U, {0xff35}}},
+  {0xff56, {1|U, {0xff36}}},
+  {0xff57, {1|U, {0xff37}}},
+  {0xff58, {1|U, {0xff38}}},
+  {0xff59, {1|U, {0xff39}}},
+  {0xff5a, {1|U, {0xff3a}}},
+  {0x10428, {1|U, {0x10400}}},
+  {0x10429, {1|U, {0x10401}}},
+  {0x1042a, {1|U, {0x10402}}},
+  {0x1042b, {1|U, {0x10403}}},
+  {0x1042c, {1|U, {0x10404}}},
+  {0x1042d, {1|U, {0x10405}}},
+  {0x1042e, {1|U, {0x10406}}},
+  {0x1042f, {1|U, {0x10407}}},
+  {0x10430, {1|U, {0x10408}}},
+  {0x10431, {1|U, {0x10409}}},
+  {0x10432, {1|U, {0x1040a}}},
+  {0x10433, {1|U, {0x1040b}}},
+  {0x10434, {1|U, {0x1040c}}},
+  {0x10435, {1|U, {0x1040d}}},
+  {0x10436, {1|U, {0x1040e}}},
+  {0x10437, {1|U, {0x1040f}}},
+  {0x10438, {1|U, {0x10410}}},
+  {0x10439, {1|U, {0x10411}}},
+  {0x1043a, {1|U, {0x10412}}},
+  {0x1043b, {1|U, {0x10413}}},
+  {0x1043c, {1|U, {0x10414}}},
+  {0x1043d, {1|U, {0x10415}}},
+  {0x1043e, {1|U, {0x10416}}},
+  {0x1043f, {1|U, {0x10417}}},
+  {0x10440, {1|U, {0x10418}}},
+  {0x10441, {1|U, {0x10419}}},
+  {0x10442, {1|U, {0x1041a}}},
+  {0x10443, {1|U, {0x1041b}}},
+  {0x10444, {1|U, {0x1041c}}},
+  {0x10445, {1|U, {0x1041d}}},
+  {0x10446, {1|U, {0x1041e}}},
+  {0x10447, {1|U, {0x1041f}}},
+  {0x10448, {1|U, {0x10420}}},
+  {0x10449, {1|U, {0x10421}}},
+  {0x1044a, {1|U, {0x10422}}},
+  {0x1044b, {1|U, {0x10423}}},
+  {0x1044c, {1|U, {0x10424}}},
+  {0x1044d, {1|U, {0x10425}}},
+  {0x1044e, {1|U, {0x10426}}},
+  {0x1044f, {1|U, {0x10427}}},
+  {0x104d8, {1|U, {0x104b0}}},
+  {0x104d9, {1|U, {0x104b1}}},
+  {0x104da, {1|U, {0x104b2}}},
+  {0x104db, {1|U, {0x104b3}}},
+  {0x104dc, {1|U, {0x104b4}}},
+  {0x104dd, {1|U, {0x104b5}}},
+  {0x104de, {1|U, {0x104b6}}},
+  {0x104df, {1|U, {0x104b7}}},
+  {0x104e0, {1|U, {0x104b8}}},
+  {0x104e1, {1|U, {0x104b9}}},
+  {0x104e2, {1|U, {0x104ba}}},
+  {0x104e3, {1|U, {0x104bb}}},
+  {0x104e4, {1|U, {0x104bc}}},
+  {0x104e5, {1|U, {0x104bd}}},
+  {0x104e6, {1|U, {0x104be}}},
+  {0x104e7, {1|U, {0x104bf}}},
+  {0x104e8, {1|U, {0x104c0}}},
+  {0x104e9, {1|U, {0x104c1}}},
+  {0x104ea, {1|U, {0x104c2}}},
+  {0x104eb, {1|U, {0x104c3}}},
+  {0x104ec, {1|U, {0x104c4}}},
+  {0x104ed, {1|U, {0x104c5}}},
+  {0x104ee, {1|U, {0x104c6}}},
+  {0x104ef, {1|U, {0x104c7}}},
+  {0x104f0, {1|U, {0x104c8}}},
+  {0x104f1, {1|U, {0x104c9}}},
+  {0x104f2, {1|U, {0x104ca}}},
+  {0x104f3, {1|U, {0x104cb}}},
+  {0x104f4, {1|U, {0x104cc}}},
+  {0x104f5, {1|U, {0x104cd}}},
+  {0x104f6, {1|U, {0x104ce}}},
+  {0x104f7, {1|U, {0x104cf}}},
+  {0x104f8, {1|U, {0x104d0}}},
+  {0x104f9, {1|U, {0x104d1}}},
+  {0x104fa, {1|U, {0x104d2}}},
+  {0x104fb, {1|U, {0x104d3}}},
+  {0x10cc0, {1|U, {0x10c80}}},
+  {0x10cc1, {1|U, {0x10c81}}},
+  {0x10cc2, {1|U, {0x10c82}}},
+  {0x10cc3, {1|U, {0x10c83}}},
+  {0x10cc4, {1|U, {0x10c84}}},
+  {0x10cc5, {1|U, {0x10c85}}},
+  {0x10cc6, {1|U, {0x10c86}}},
+  {0x10cc7, {1|U, {0x10c87}}},
+  {0x10cc8, {1|U, {0x10c88}}},
+  {0x10cc9, {1|U, {0x10c89}}},
+  {0x10cca, {1|U, {0x10c8a}}},
+  {0x10ccb, {1|U, {0x10c8b}}},
+  {0x10ccc, {1|U, {0x10c8c}}},
+  {0x10ccd, {1|U, {0x10c8d}}},
+  {0x10cce, {1|U, {0x10c8e}}},
+  {0x10ccf, {1|U, {0x10c8f}}},
+  {0x10cd0, {1|U, {0x10c90}}},
+  {0x10cd1, {1|U, {0x10c91}}},
+  {0x10cd2, {1|U, {0x10c92}}},
+  {0x10cd3, {1|U, {0x10c93}}},
+  {0x10cd4, {1|U, {0x10c94}}},
+  {0x10cd5, {1|U, {0x10c95}}},
+  {0x10cd6, {1|U, {0x10c96}}},
+  {0x10cd7, {1|U, {0x10c97}}},
+  {0x10cd8, {1|U, {0x10c98}}},
+  {0x10cd9, {1|U, {0x10c99}}},
+  {0x10cda, {1|U, {0x10c9a}}},
+  {0x10cdb, {1|U, {0x10c9b}}},
+  {0x10cdc, {1|U, {0x10c9c}}},
+  {0x10cdd, {1|U, {0x10c9d}}},
+  {0x10cde, {1|U, {0x10c9e}}},
+  {0x10cdf, {1|U, {0x10c9f}}},
+  {0x10ce0, {1|U, {0x10ca0}}},
+  {0x10ce1, {1|U, {0x10ca1}}},
+  {0x10ce2, {1|U, {0x10ca2}}},
+  {0x10ce3, {1|U, {0x10ca3}}},
+  {0x10ce4, {1|U, {0x10ca4}}},
+  {0x10ce5, {1|U, {0x10ca5}}},
+  {0x10ce6, {1|U, {0x10ca6}}},
+  {0x10ce7, {1|U, {0x10ca7}}},
+  {0x10ce8, {1|U, {0x10ca8}}},
+  {0x10ce9, {1|U, {0x10ca9}}},
+  {0x10cea, {1|U, {0x10caa}}},
+  {0x10ceb, {1|U, {0x10cab}}},
+  {0x10cec, {1|U, {0x10cac}}},
+  {0x10ced, {1|U, {0x10cad}}},
+  {0x10cee, {1|U, {0x10cae}}},
+  {0x10cef, {1|U, {0x10caf}}},
+  {0x10cf0, {1|U, {0x10cb0}}},
+  {0x10cf1, {1|U, {0x10cb1}}},
+  {0x10cf2, {1|U, {0x10cb2}}},
+  {0x118c0, {1|U, {0x118a0}}},
+  {0x118c1, {1|U, {0x118a1}}},
+  {0x118c2, {1|U, {0x118a2}}},
+  {0x118c3, {1|U, {0x118a3}}},
+  {0x118c4, {1|U, {0x118a4}}},
+  {0x118c5, {1|U, {0x118a5}}},
+  {0x118c6, {1|U, {0x118a6}}},
+  {0x118c7, {1|U, {0x118a7}}},
+  {0x118c8, {1|U, {0x118a8}}},
+  {0x118c9, {1|U, {0x118a9}}},
+  {0x118ca, {1|U, {0x118aa}}},
+  {0x118cb, {1|U, {0x118ab}}},
+  {0x118cc, {1|U, {0x118ac}}},
+  {0x118cd, {1|U, {0x118ad}}},
+  {0x118ce, {1|U, {0x118ae}}},
+  {0x118cf, {1|U, {0x118af}}},
+  {0x118d0, {1|U, {0x118b0}}},
+  {0x118d1, {1|U, {0x118b1}}},
+  {0x118d2, {1|U, {0x118b2}}},
+  {0x118d3, {1|U, {0x118b3}}},
+  {0x118d4, {1|U, {0x118b4}}},
+  {0x118d5, {1|U, {0x118b5}}},
+  {0x118d6, {1|U, {0x118b6}}},
+  {0x118d7, {1|U, {0x118b7}}},
+  {0x118d8, {1|U, {0x118b8}}},
+  {0x118d9, {1|U, {0x118b9}}},
+  {0x118da, {1|U, {0x118ba}}},
+  {0x118db, {1|U, {0x118bb}}},
+  {0x118dc, {1|U, {0x118bc}}},
+  {0x118dd, {1|U, {0x118bd}}},
+  {0x118de, {1|U, {0x118be}}},
+  {0x118df, {1|U, {0x118bf}}},
+  {0x1e922, {1|U, {0x1e900}}},
+  {0x1e923, {1|U, {0x1e901}}},
+  {0x1e924, {1|U, {0x1e902}}},
+  {0x1e925, {1|U, {0x1e903}}},
+  {0x1e926, {1|U, {0x1e904}}},
+  {0x1e927, {1|U, {0x1e905}}},
+  {0x1e928, {1|U, {0x1e906}}},
+  {0x1e929, {1|U, {0x1e907}}},
+  {0x1e92a, {1|U, {0x1e908}}},
+  {0x1e92b, {1|U, {0x1e909}}},
+  {0x1e92c, {1|U, {0x1e90a}}},
+  {0x1e92d, {1|U, {0x1e90b}}},
+  {0x1e92e, {1|U, {0x1e90c}}},
+  {0x1e92f, {1|U, {0x1e90d}}},
+  {0x1e930, {1|U, {0x1e90e}}},
+  {0x1e931, {1|U, {0x1e90f}}},
+  {0x1e932, {1|U, {0x1e910}}},
+  {0x1e933, {1|U, {0x1e911}}},
+  {0x1e934, {1|U, {0x1e912}}},
+  {0x1e935, {1|U, {0x1e913}}},
+  {0x1e936, {1|U, {0x1e914}}},
+  {0x1e937, {1|U, {0x1e915}}},
+  {0x1e938, {1|U, {0x1e916}}},
+  {0x1e939, {1|U, {0x1e917}}},
+  {0x1e93a, {1|U, {0x1e918}}},
+  {0x1e93b, {1|U, {0x1e919}}},
+  {0x1e93c, {1|U, {0x1e91a}}},
+  {0x1e93d, {1|U, {0x1e91b}}},
+  {0x1e93e, {1|U, {0x1e91c}}},
+  {0x1e93f, {1|U, {0x1e91d}}},
+  {0x1e940, {1|U, {0x1e91e}}},
+  {0x1e941, {1|U, {0x1e91f}}},
+  {0x1e942, {1|U, {0x1e920}}},
+  {0x1e943, {1|U, {0x1e921}}},
+#define CaseUnfold_11_Locale (*(CaseUnfold_11_Type (*)[1])(CaseUnfold_11_Table+1266))
+  {0x0069, {1|U, {0x0049}}},
+};
+
+/* ANSI-C code produced by gperf version 3.1 */
+/* Command-line: gperf -7 -k1,2,3 -F,-1 -c -j1 -i1 -t -T -E -C -H onigenc_unicode_CaseUnfold_11_hash -N onigenc_unicode_CaseUnfold_11_lookup -n  */
+
+/* maximum key range = 2216, duplicates = 0 */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+/*ARGSUSED*/
+static unsigned int
+onigenc_unicode_CaseUnfold_11_hash(const OnigCodePoint code)
+{
+  static const unsigned short asso_values[] =
+    {
+         1, 2219,    2,   14,    4,  807,    9,  379,   10,  179,
+        70,  161,    2,    3,  411,    4, 2219, 2219, 2219, 2219,
+      2219, 2219, 2219, 2219, 2219, 2219, 2219, 2219, 2219,   80,
+      2219, 2219, 2219, 2219, 2219, 2219, 2219, 2219, 2219, 2219,
+      2219, 2219, 2219,    1, 2219, 2219, 2219, 2219, 2219, 2219,
+      2219, 2219, 2219,  210, 2219, 2219, 2219, 2219, 2219, 2219,
+      2219, 2219,   53, 2219,    7,    8,  306,  607,  169,  844,
+       431,  722,  125, 1047,  489, 1394,   15,   16,  324, 1361,
+       140,  521,   47,  461,  221,  985,   70,  965,    9, 1085,
+        51, 1029,  223,   11,  430, 1168,  122, 1457,  344,  930,
+        91,  711,   31,  651,  157,  772,  224,  876,  262,  900,
+       254,  686,  221,  830, 1335,  755,  432,  623, 1382,  675,
+      1275,  587,   99,  821, 1530,  958,  195,  810, 1518,  739,
+       330,  361,  767,  313,  941,  400,  925,  384, 1142,  295,
+      1295,  242, 1103,  229, 1082,  206, 1066,  104, 1317,  137,
+      1249,  263, 1229,  115, 1154,   71,  135,   60, 1211,  158,
+      1472,  175, 1232,    1, 1345,   27, 1269,   38, 1111,   87,
+      1189,   49, 1256,  503, 1157,  574, 1410,  556, 1200,  787,
+       948,  486, 1316,  797, 1218, 1044, 1282, 1007, 1126,  996,
+       818, 1019,  218, 1072
+    };
+  return asso_values[bits_of(code, 2)+66] + asso_values[bits_of(code, 1)+4] + asso_values[bits_of(code, 0)];
+}
+
+static const CodePointList3 *
+onigenc_unicode_CaseUnfold_11_lookup(const OnigCodePoint code)
+{
+  enum
+    {
+      MIN_CODE_VALUE = 0x61,
+      MAX_CODE_VALUE = 0x1e943,
+      TOTAL_KEYWORDS = 1267,
+      MIN_WORD_LENGTH = 3,
+      MAX_WORD_LENGTH = 3,
+      MIN_HASH_VALUE = 3,
+      MAX_HASH_VALUE = 2218
+    };
+
+  static const short wordlist[] =
+    {
+      -1, -1, -1,
+      /*0x13e1*/ 542,
+      /*0x0461*/ 339,
+      /*0x04e1*/ 399,
+      /*0x0061*/ 0,
+      -1,
+      /*0x104e1*/ 1122,
+      /*0x1e61*/ 613,
+      /*0x1ee1*/ 672,
+      /*0x0161*/ 102,
+      /*0x0261*/ 210,
+      /*0x2ce1*/ 904,
+      -1,
+      /*0x049b*/ 364,
+      -1, -1,
+      /*0x24e1*/ 792,
+      /*0x1e1b*/ 578,
+      /*0x048b*/ 356,
+      /*0x011b*/ 69,
+      /*0x021b*/ 178,
+      /*0x2c9b*/ 869,
+      /*0x1e0b*/ 570,
+      /*0x1e8b*/ 634,
+      /*0x010b*/ 61,
+      /*0x020b*/ 170,
+      /*0x2c8b*/ 861,
+      /*0x13e3*/ 544,
+      /*0x0463*/ 340,
+      /*0x04e3*/ 400,
+      /*0x0063*/ 2,
+      /*0x13a4*/ 481,
+      /*0x104e3*/ 1124,
+      /*0x1e63*/ 614,
+      /*0x1ee3*/ 673,
+      /*0x0163*/ 103,
+      /*0x0263*/ 211,
+      /*0x2ce3*/ 905,
+      /*0x13e5*/ 546,
+      /*0x0465*/ 341,
+      /*0x04e5*/ 401,
+      /*0x0065*/ 4,
+      /*0x24e3*/ 794,
+      /*0x104e5*/ 1126,
+      /*0x1e65*/ 615,
+      /*0x1ee5*/ 674,
+      /*0x0165*/ 104,
+      /*0x0265*/ 212,
+      /*0xa761*/ 1016,
+      /*0x13e9*/ 550,
+      /*0x0469*/ 343,
+      /*0x04e9*/ 403,
+      /*0x0069*/ 1266,
+      /*0x24e5*/ 796,
+      /*0x104e9*/ 1130,
+      /*0x1e69*/ 617,
+      /*0x1ee9*/ 676,
+      /*0x0169*/ 106,
+      /*0x0269*/ 215,
+      -1,
+      /*0x13db*/ 536,
+      /*0x045b*/ 334,
+      /*0x04db*/ 396,
+      -1,
+      /*0x24e9*/ 800,
+      /*0x104db*/ 1116,
+      /*0x1e5b*/ 610,
+      /*0x1edb*/ 669,
+      /*0x015b*/ 99,
+      /*0x025b*/ 207,
+      /*0x2cdb*/ 901,
+      /*0x13d9*/ 534,
+      /*0x0459*/ 332,
+      /*0x04d9*/ 395,
+      /*0xa763*/ 1017,
+      /*0x24db*/ 786,
+      /*0x104d9*/ 1114,
+      /*0x1e59*/ 609,
+      /*0x1ed9*/ 668,
+      /*0x0159*/ 98,
+      /*0x0259*/ 206,
+      /*0x2cd9*/ 900,
+      -1,
+      /*0x10ce1*/ 1182,
+      -1,
+      /*0xa765*/ 1018,
+      /*0x24d9*/ 784,
+      /*0x13e7*/ 548,
+      /*0x0467*/ 342,
+      /*0x04e7*/ 402,
+      /*0x0067*/ 6,
+      /*0x13a2*/ 479,
+      /*0x104e7*/ 1128,
+      /*0x1e67*/ 616,
+      /*0x1ee7*/ 675,
+      /*0x0167*/ 105,
+      /*0xa769*/ 1020,
+      -1, -1,
+      /*0x13b8*/ 501,
+      /*0x0438*/ 299,
+      -1,
+      /*0x24e7*/ 798,
+      /*0x10438*/ 1089,
+      /*0x13d1*/ 526,
+      /*0x0451*/ 324,
+      /*0x04d1*/ 391,
+      /*0xa75b*/ 1013,
+      -1,
+      /*0x10ce3*/ 1184,
+      /*0x1e51*/ 605,
+      /*0x1ed1*/ 664,
+      /*0x0151*/ 94,
+      /*0x0251*/ 200,
+      /*0x2cd1*/ 896,
+      /*0x13d7*/ 532,
+      /*0x0457*/ 330,
+      /*0x04d7*/ 394,
+      /*0xa759*/ 1012,
+      /*0x24d1*/ 776,
+      /*0x10ce5*/ 1186,
+      /*0x1e57*/ 608,
+      /*0x1ed7*/ 667,
+      /*0x0157*/ 97,
+      /*0x0257*/ 205,
+      /*0x2cd7*/ 899,
+      -1, -1,
+      /*0x0586*/ 476,
+      -1,
+      /*0x24d7*/ 782,
+      /*0x10ce9*/ 1190,
+      -1, -1,
+      /*0xa767*/ 1019,
+      /*0x13da*/ 535,
+      /*0x045a*/ 333,
+      /*0x13d3*/ 528,
+      /*0x0453*/ 326,
+      /*0x04d3*/ 392,
+      /*0x104da*/ 1115,
+      /*0xa661*/ 965,
+      /*0x10cdb*/ 1176,
+      /*0x1e53*/ 606,
+      /*0x1ed3*/ 665,
+      /*0x0153*/ 95,
+      /*0x0253*/ 202,
+      /*0x2cd3*/ 897,
+      -1, -1,
+      /*0x24da*/ 785,
+      /*0xa751*/ 1008,
+      /*0x24d3*/ 778,
+      /*0x10cd9*/ 1174,
+      -1, -1, -1,
+      /*0x13a6*/ 483,
+      /*0x13dd*/ 538,
+      /*0x045d*/ 336,
+      /*0x04dd*/ 397,
+      /*0x03e1*/ 279,
+      /*0xa757*/ 1011,
+      /*0x104dd*/ 1118,
+      /*0x1e5d*/ 611,
+      /*0x1edd*/ 670,
+      /*0x015d*/ 100,
+      /*0xa663*/ 966,
+      /*0x2cdd*/ 902,
+      /*0x10ce7*/ 1188,
+      -1, -1,
+      /*0x0582*/ 472,
+      /*0x24dd*/ 788,
+      -1,
+      /*0x13df*/ 540,
+      /*0x045f*/ 338,
+      /*0x04df*/ 398,
+      /*0xa665*/ 967,
+      -1,
+      /*0x104df*/ 1120,
+      /*0x1e5f*/ 612,
+      /*0x1edf*/ 671,
+      /*0x015f*/ 101,
+      /*0xa753*/ 1009,
+      /*0x2cdf*/ 903,
+      /*0x10cd1*/ 1166,
+      /*0x03e3*/ 280,
+      /*0xab53*/ 1046,
+      /*0xa669*/ 969,
+      /*0x24df*/ 790,
+      -1, -1,
+      /*0x028a*/ 229,
+      /*0x028b*/ 230,
+      /*0x13bc*/ 505,
+      /*0x043c*/ 303,
+      /*0x10cd7*/ 1172,
+      /*0x03e5*/ 281,
+      /*0x1043c*/ 1093,
+      /*0xa65b*/ 962,
+      -1, -1,
+      /*0x013c*/ 84,
+      /*0x023c*/ 190,
+      /*0xa75d*/ 1014,
+      /*0x13cf*/ 524,
+      /*0x044f*/ 322,
+      /*0x04cf*/ 390,
+      /*0x03e9*/ 283,
+      /*0x1044f*/ 1112,
+      /*0xa659*/ 961,
+      /*0x1e4f*/ 604,
+      /*0x1ecf*/ 663,
+      /*0x014f*/ 93,
+      /*0x024f*/ 198,
+      /*0x2ccf*/ 895,
+      /*0x10cda*/ 1175,
+      -1,
+      /*0x10cd3*/ 1168,
+      /*0x03db*/ 276,
+      /*0x13ae*/ 491,
+      /*0xa75f*/ 1015,
+      /*0x2c61*/ 848,
+      /*0x13a8*/ 485,
+      /*0x1042e*/ 1079,
+      /*0x017e*/ 116,
+      /*0xa667*/ 968,
+      /*0x10428*/ 1073,
+      /*0x13cd*/ 522,
+      /*0x044d*/ 320,
+      /*0x03d9*/ 275,
+      -1,
+      /*0x1044d*/ 1110,
+      -1,
+      /*0x1e4d*/ 603,
+      /*0x1ecd*/ 662,
+      /*0x014d*/ 92,
+      /*0x024d*/ 197,
+      /*0x2ccd*/ 894,
+      /*0x10cdd*/ 1178,
+      -1,
+      /*0x13cb*/ 520,
+      /*0x044b*/ 318,
+      /*0xa651*/ 957,
+      -1,
+      /*0x1044b*/ 1108,
+      /*0x03e7*/ 282,
+      /*0x1e4b*/ 602,
+      /*0x1ecb*/ 661,
+      /*0x014b*/ 91,
+      /*0x024b*/ 196,
+      /*0x2ccb*/ 893,
+      /*0xa74f*/ 1007,
+      /*0x13ac*/ 489,
+      /*0xa657*/ 960,
+      -1,
+      /*0x10cdf*/ 1180,
+      /*0x1042c*/ 1077,
+      /*0x03b8*/ 252,
+      /*0x2c65*/ 849,
+      -1,
+      /*0x13aa*/ 487,
+      /*0x13d5*/ 530,
+      /*0x0455*/ 328,
+      /*0x04d5*/ 393,
+      /*0x1042a*/ 1075,
+      -1, -1,
+      /*0x1e55*/ 607,
+      /*0x1ed5*/ 666,
+      /*0x0155*/ 96,
+      /*0x118db*/ 1227,
+      /*0x2cd5*/ 898,
+      -1,
+      /*0x03d7*/ 274,
+      /*0xa74d*/ 1006,
+      /*0xa653*/ 958,
+      /*0x24d5*/ 780,
+      -1, -1, -1,
+      /*0x2c5b*/ 844,
+      /*0x118d9*/ 1225,
+      -1, -1, -1, -1,
+      /*0x10ccf*/ 1164,
+      /*0xa74b*/ 1005,
+      -1, -1, -1,
+      /*0x2c59*/ 842,
+      -1,
+      /*0x13c9*/ 518,
+      /*0x0449*/ 316,
+      -1,
+      /*0xa65d*/ 963,
+      /*0x10449*/ 1106,
+      /*0x029e*/ 234,
+      /*0x1e49*/ 601,
+      /*0x1ec9*/ 660,
+      -1,
+      /*0x0249*/ 195,
+      /*0x2cc9*/ 892,
+      /*0x1f61*/ 729,
+      -1, -1,
+      /*0x0580*/ 470,
+      /*0xa755*/ 1010,
+      /*0x10ccd*/ 1162,
+      -1,
+      /*0x13c3*/ 512,
+      /*0x0443*/ 310,
+      /*0xa65f*/ 964,
+      /*0x118d1*/ 1217,
+      /*0x10443*/ 1100,
+      /*0x03dd*/ 277,
+      /*0x1e43*/ 598,
+      /*0x1ec3*/ 657,
+      /*0x2c38*/ 809,
+      -1,
+      /*0x2cc3*/ 889,
+      /*0x10ccb*/ 1160,
+      -1,
+      /*0x2c51*/ 834,
+      /*0x118d7*/ 1223,
+      -1, -1,
+      /*0x13c0*/ 509,
+      /*0x0440*/ 307,
+      /*0x1f63*/ 731,
+      -1,
+      /*0x10440*/ 1097,
+      /*0x03df*/ 278,
+      /*0x1f24*/ 706,
+      /*0x2c57*/ 840,
+      /*0x0140*/ 86,
+      /*0x0240*/ 192,
+      -1, -1,
+      /*0xa749*/ 1004,
+      /*0x1f65*/ 733,
+      /*0x13a0*/ 477,
+      /*0x10cd5*/ 1170,
+      /*0xa64f*/ 956,
+      /*0x118da*/ 1226,
+      -1,
+      /*0x118d3*/ 1219,
+      -1, -1,
+      /*0x1f10*/ 696,
+      -1, -1,
+      /*0x03bc*/ 256,
+      -1,
+      /*0x2c5a*/ 843,
+      -1,
+      /*0x2c53*/ 836,
+      /*0xa743*/ 1001,
+      /*0x13c1*/ 510,
+      /*0x0441*/ 308,
+      -1, -1,
+      /*0x10441*/ 1098,
+      -1,
+      /*0x1e41*/ 597,
+      /*0x1ec1*/ 656,
+      /*0xa64d*/ 955,
+      /*0x118dd*/ 1229,
+      /*0x2cc1*/ 888,
+      -1, -1, -1,
+      /*0x1f14*/ 700,
+      -1,
+      /*0x10cc9*/ 1158,
+      -1,
+      /*0x01e1*/ 151,
+      /*0x2c5d*/ 846,
+      /*0x03ae*/ 243,
+      /*0xa64b*/ 954,
+      -1,
+      /*0x13c7*/ 516,
+      /*0x0447*/ 314,
+      -1,
+      /*0x118df*/ 1231,
+      /*0x10447*/ 1104,
+      /*0x03cd*/ 272,
+      /*0x1e47*/ 600,
+      /*0x1ec7*/ 659,
+      /*0x1f67*/ 735,
+      /*0x0247*/ 194,
+      /*0x2cc7*/ 891,
+      /*0x10cc3*/ 1152,
+      /*0x1f22*/ 704,
+      -1, -1,
+      /*0x0292*/ 232,
+      /*0x13c5*/ 514,
+      /*0x0445*/ 312,
+      /*0x03cb*/ 270,
+      /*0xa655*/ 959,
+      /*0x10445*/ 1102,
+      /*0x01e3*/ 152,
+      /*0x1e45*/ 599,
+      /*0x1ec5*/ 658,
+      /*0xa741*/ 1000,
+      /*0x1f51*/ 724,
+      /*0x2cc5*/ 890,
+      /*0x0561*/ 439,
+      /*0x10cc0*/ 1149,
+      /*0xff59*/ 1071,
+      /*0x03ac*/ 241,
+      -1,
+      /*0x01e5*/ 153,
+      /*0x2c3c*/ 813,
+      /*0x118cf*/ 1215,
+      -1,
+      /*0x1f57*/ 727,
+      /*0x051b*/ 428,
+      -1, -1, -1, -1,
+      /*0x050b*/ 420,
+      /*0x01e9*/ 155,
+      /*0x2c4f*/ 832,
+      -1,
+      /*0x1f06*/ 694,
+      /*0xa747*/ 1003,
+      /*0x13b2*/ 495,
+      /*0x0432*/ 293,
+      /*0x0584*/ 474,
+      /*0xa649*/ 953,
+      /*0x10432*/ 1083,
+      /*0x0563*/ 441,
+      /*0x2d16*/ 931,
+      -1,
+      /*0x2d1b*/ 936,
+      /*0x118cd*/ 1213,
+      /*0x1f53*/ 725,
+      /*0x10cc1*/ 1150,
+      /*0x2d0a*/ 919,
+      /*0x2d0b*/ 920,
+      /*0xff51*/ 1063,
+      /*0xa745*/ 1002,
+      /*0x0565*/ 443,
+      -1, -1,
+      /*0x2c4d*/ 830,
+      -1,
+      /*0xa643*/ 950,
+      /*0x118cb*/ 1211,
+      /*0x03c9*/ 268,
+      -1,
+      /*0xff57*/ 1069,
+      -1,
+      /*0x0569*/ 447,
+      /*0x2d24*/ 945,
+      -1,
+      /*0x1f26*/ 708,
+      /*0x0491*/ 359,
+      /*0x2c4b*/ 828,
+      /*0x01e7*/ 154,
+      /*0x10cc7*/ 1156,
+      /*0x1e11*/ 573,
+      /*0x1e91*/ 637,
+      /*0x0111*/ 64,
+      /*0x0211*/ 173,
+      /*0x2c91*/ 864,
+      /*0xa79b*/ 1036,
+      /*0x03c3*/ 262,
+      /*0x1f02*/ 690,
+      /*0x118d5*/ 1221,
+      /*0x2d10*/ 925,
+      /*0xff5a*/ 1072,
+      /*0x1e924*/ 1234,
+      /*0xff53*/ 1065,
+      /*0x2d18*/ 933,
+      -1,
+      /*0x10cc5*/ 1154,
+      -1,
+      /*0x0280*/ 224,
+      /*0x2c55*/ 838,
+      /*0x13f3*/ 560,
+      /*0x0473*/ 348,
+      /*0x04f3*/ 408,
+      /*0x0073*/ 17,
+      /*0x03c0*/ 260,
+      /*0x104f3*/ 1140,
+      /*0x1e73*/ 622,
+      /*0x1ef3*/ 681,
+      /*0x0173*/ 111,
+      -1,
+      /*0x2cf3*/ 908,
+      /*0x0567*/ 445,
+      -1,
+      /*0x2d14*/ 929,
+      /*0x019e*/ 126,
+      /*0xa641*/ 949,
+      /*0x028c*/ 231,
+      /*0x13eb*/ 552,
+      /*0x046b*/ 344,
+      /*0x04eb*/ 404,
+      /*0x006b*/ 9,
+      /*0x118c9*/ 1209,
+      /*0x104eb*/ 1132,
+      /*0x1e6b*/ 618,
+      /*0x1eeb*/ 677,
+      /*0x016b*/ 107,
+      /*0x026b*/ 217,
+      /*0x01da*/ 147,
+      -1, -1, -1,
+      /*0x2c49*/ 826,
+      -1, -1,
+      /*0x2d22*/ 943,
+      /*0x03c1*/ 261,
+      -1,
+      /*0x048f*/ 358,
+      /*0xa647*/ 952,
+      /*0x118c3*/ 1203,
+      /*0x1f12*/ 698,
+      /*0x1e0f*/ 572,
+      /*0x1e8f*/ 636,
+      /*0x010f*/ 63,
+      /*0x020f*/ 172,
+      /*0x2c8f*/ 863,
+      /*0xa69b*/ 985,
+      -1, -1,
+      /*0x2c43*/ 820,
+      /*0x01dd*/ 149,
+      /*0xa68b*/ 977,
+      /*0x1e922*/ 1232,
+      -1,
+      /*0xa645*/ 951,
+      -1,
+      /*0x118c0*/ 1200,
+      -1,
+      /*0x03c7*/ 266,
+      -1,
+      /*0x1e938*/ 1254,
+      -1,
+      /*0xff4f*/ 1061,
+      -1,
+      /*0xa76b*/ 1021,
+      /*0x2d1e*/ 939,
+      /*0x2c40*/ 817,
+      /*0x01df*/ 150,
+      /*0x2d06*/ 915,
+      /*0x0373*/ 236,
+      /*0x13ef*/ 556,
+      /*0x046f*/ 346,
+      /*0x04ef*/ 406,
+      /*0x006f*/ 13,
+      /*0x03c5*/ 264,
+      /*0x104ef*/ 1136,
+      /*0x1e6f*/ 620,
+      /*0x1eef*/ 679,
+      /*0x016f*/ 109,
+      /*0x026f*/ 219,
+      -1, -1,
+      /*0x1f55*/ 726,
+      /*0x2d0e*/ 923,
+      -1,
+      /*0xff4d*/ 1059,
+      -1,
+      /*0x118c1*/ 1201,
+      /*0x13ed*/ 554,
+      /*0x046d*/ 345,
+      /*0x04ed*/ 405,
+      /*0x006d*/ 11,
+      -1,
+      /*0x104ed*/ 1134,
+      /*0x1e6d*/ 619,
+      /*0x1eed*/ 678,
+      /*0x016d*/ 108,
+      /*0x2c41*/ 818,
+      /*0xff4b*/ 1057,
+      /*0x10ceb*/ 1192,
+      -1,
+      /*0x13b7*/ 500,
+      /*0x0437*/ 298,
+      /*0x04b7*/ 378,
+      -1,
+      /*0x10437*/ 1088,
+      /*0x03b2*/ 246,
+      /*0x1e37*/ 592,
+      /*0x1eb7*/ 651,
+      /*0x0137*/ 82,
+      /*0x118c7*/ 1207,
+      /*0x2cb7*/ 883,
+      /*0x2d02*/ 911,
+      /*0x0192*/ 122,
+      -1,
+      /*0x019a*/ 125,
+      /*0x01a8*/ 130,
+      /*0xa76f*/ 1023,
+      /*0x1e926*/ 1236,
+      /*0xff55*/ 1067,
+      /*0x2c47*/ 824,
+      /*0x1fe1*/ 755,
+      -1,
+      /*0x0481*/ 355,
+      /*0x0581*/ 471,
+      /*0x1f00*/ 688,
+      /*0x118c5*/ 1205,
+      /*0x1e01*/ 565,
+      /*0x1e81*/ 629,
+      /*0x0101*/ 56,
+      /*0x0201*/ 165,
+      /*0x2c81*/ 856,
+      /*0x1f43*/ 721,
+      -1, -1,
+      /*0xa76d*/ 1022,
+      /*0x2c45*/ 822,
+      /*0x13b3*/ 496,
+      /*0x0433*/ 294,
+      /*0x04b3*/ 376,
+      -1,
+      /*0x10433*/ 1084,
+      /*0x057e*/ 468,
+      /*0x1e33*/ 590,
+      /*0x1eb3*/ 649,
+      /*0x0133*/ 80,
+      /*0x0233*/ 189,
+      /*0x2cb3*/ 881,
+      /*0xa737*/ 995,
+      /*0x1f40*/ 718,
+      -1,
+      /*0xff49*/ 1055,
+      /*0x10cef*/ 1196,
+      -1, -1, -1,
+      /*0x1e93c*/ 1258,
+      /*0xa66b*/ 970,
+      /*0x1fe5*/ 756,
+      -1,
+      /*0x03f3*/ 288,
+      -1,
+      /*0x217e*/ 772,
+      /*0x1f20*/ 702,
+      /*0x2d12*/ 927,
+      /*0x13a5*/ 482,
+      /*0x2d1a*/ 935,
+      /*0x04a5*/ 369,
+      /*0x2c32*/ 803,
+      /*0xff43*/ 1049,
+      /*0x10ced*/ 1194,
+      /*0x1e25*/ 583,
+      /*0x1ea5*/ 642,
+      /*0x0125*/ 74,
+      /*0x0225*/ 182,
+      /*0x2ca5*/ 874,
+      -1,
+      /*0x03eb*/ 284,
+      -1, -1,
+      /*0x1f41*/ 719,
+      /*0x0288*/ 227,
+      /*0x1e92e*/ 1244,
+      -1,
+      /*0xa733*/ 993,
+      /*0x1e928*/ 1238,
+      -1,
+      /*0x01c9*/ 139,
+      -1,
+      /*0x13b5*/ 498,
+      /*0x0435*/ 296,
+      /*0x04b5*/ 377,
+      -1,
+      /*0x10435*/ 1086,
+      -1,
+      /*0x1e35*/ 591,
+      /*0x1eb5*/ 650,
+      /*0x0135*/ 81,
+      /*0x0180*/ 117,
+      /*0x2cb5*/ 882,
+      /*0x13ad*/ 490,
+      -1,
+      /*0x04ad*/ 373,
+      -1,
+      /*0x1042d*/ 1078,
+      -1,
+      /*0x1e2d*/ 587,
+      /*0x1ead*/ 646,
+      /*0x012d*/ 78,
+      /*0x022d*/ 186,
+      /*0x2cad*/ 878,
+      -1,
+      /*0xa725*/ 987,
+      -1, -1,
+      /*0x1e92c*/ 1242,
+      /*0x018c*/ 121,
+      /*0xff41*/ 1047,
+      -1,
+      /*0x1f45*/ 723,
+      -1, -1,
+      /*0x2c73*/ 854,
+      /*0x1e92a*/ 1240,
+      /*0x1fd1*/ 753,
+      /*0x13a3*/ 480,
+      -1,
+      /*0x04a3*/ 368,
+      /*0xa66d*/ 971,
+      -1,
+      /*0x03ef*/ 286,
+      /*0x1e23*/ 582,
+      /*0x1ea3*/ 641,
+      /*0x0123*/ 73,
+      /*0x0223*/ 181,
+      /*0x2ca3*/ 873,
+      /*0xa735*/ 994,
+      -1, -1,
+      /*0x0585*/ 475,
+      /*0xff47*/ 1053,
+      -1,
+      /*0x1e05*/ 567,
+      /*0x1e85*/ 631,
+      /*0x0105*/ 58,
+      /*0x0205*/ 167,
+      /*0x2c85*/ 858,
+      /*0xa72d*/ 991,
+      /*0x03ed*/ 285,
+      /*0x2d00*/ 909,
+      /*0x1f04*/ 692,
+      /*0x1f32*/ 712,
+      -1,
+      /*0x13bf*/ 508,
+      /*0x043f*/ 306,
+      /*0x04bf*/ 382,
+      /*0xff45*/ 1051,
+      /*0x1043f*/ 1096,
+      -1,
+      /*0x1e3f*/ 596,
+      /*0x1ebf*/ 655,
+      /*0x03b7*/ 251,
+      /*0x023f*/ 191,
+      /*0x2cbf*/ 887,
+      -1, -1, -1,
+      /*0x2d0c*/ 921,
+      -1,
+      /*0x13b1*/ 494,
+      /*0x0431*/ 292,
+      /*0x04b1*/ 375,
+      /*0xa723*/ 986,
+      /*0x10431*/ 1082,
+      /*0x1e943*/ 1265,
+      /*0x1e31*/ 589,
+      /*0x1eb1*/ 648,
+      -1,
+      /*0x0231*/ 188,
+      /*0x2cb1*/ 880,
+      /*0x1f11*/ 697,
+      /*0x13c2*/ 511,
+      /*0x0442*/ 309,
+      /*0x04c2*/ 383,
+      -1,
+      /*0x10442*/ 1099,
+      /*0x13a7*/ 484,
+      /*0x2d20*/ 941,
+      /*0x04a7*/ 370,
+      /*0x0142*/ 87,
+      /*0x0242*/ 193,
+      /*0x1e940*/ 1262,
+      /*0x1e27*/ 584,
+      /*0x1ea7*/ 643,
+      /*0x0127*/ 75,
+      /*0x0227*/ 183,
+      /*0x2ca7*/ 875,
+      /*0x03b3*/ 247,
+      -1,
+      /*0xa78c*/ 1031,
+      /*0xa73f*/ 999,
+      /*0x13f1*/ 558,
+      /*0x0471*/ 347,
+      /*0x04f1*/ 407,
+      /*0x0071*/ 15,
+      /*0x1f73*/ 739,
+      /*0x104f1*/ 1138,
+      /*0x1e71*/ 621,
+      /*0x1ef1*/ 680,
+      /*0x0171*/ 110,
+      /*0x0271*/ 220,
+      /*0x13f5*/ 562,
+      /*0x0475*/ 349,
+      /*0x04f5*/ 409,
+      /*0x0075*/ 19,
+      -1,
+      /*0x104f5*/ 1142,
+      /*0x1e75*/ 623,
+      /*0x1ef5*/ 682,
+      /*0x0175*/ 112,
+      /*0x0275*/ 222,
+      /*0x00e1*/ 26,
+      /*0x1e941*/ 1263,
+      /*0x2c37*/ 808,
+      /*0x13bd*/ 506,
+      /*0x043d*/ 304,
+      /*0x04bd*/ 381,
+      -1,
+      /*0x1043d*/ 1094,
+      -1,
+      /*0x1e3d*/ 595,
+      /*0x1ebd*/ 654,
+      -1,
+      /*0xa727*/ 988,
+      /*0x2cbd*/ 886,
+      /*0x13b9*/ 502,
+      /*0x0439*/ 300,
+      /*0x04b9*/ 379,
+      -1,
+      /*0x10439*/ 1090,
+      /*0x017c*/ 115,
+      /*0x1e39*/ 593,
+      /*0x1eb9*/ 652,
+      -1,
+      /*0x13af*/ 492,
+      /*0x2cb9*/ 884,
+      /*0x04af*/ 374,
+      /*0x00e3*/ 28,
+      /*0x1042f*/ 1080,
+      /*0x03b5*/ 249,
+      /*0x1e2f*/ 588,
+      /*0x1eaf*/ 647,
+      /*0x012f*/ 79,
+      /*0x022f*/ 187,
+      /*0x2caf*/ 879,
+      -1, -1, -1,
+      /*0x00e5*/ 30,
+      /*0x2c33*/ 804,
+      /*0x03ad*/ 242,
+      /*0x0583*/ 473,
+      -1,
+      /*0x10cc2*/ 1151,
+      /*0x1e03*/ 566,
+      /*0x1e83*/ 630,
+      /*0x0103*/ 57,
+      /*0x0203*/ 166,
+      /*0x2c83*/ 857,
+      /*0x00e9*/ 34,
+      /*0x0371*/ 235,
+      /*0xa73d*/ 998,
+      -1,
+      /*0x2d1c*/ 937,
+      /*0x2d04*/ 913,
+      -1, -1, -1,
+      /*0x01f3*/ 159,
+      /*0xa77c*/ 1025,
+      -1,
+      /*0x0188*/ 120,
+      /*0xa739*/ 996,
+      /*0x10cf1*/ 1198,
+      -1,
+      /*0x0511*/ 423,
+      -1, -1, -1, -1,
+      /*0x13a9*/ 486,
+      /*0xa72f*/ 992,
+      /*0x04a9*/ 371,
+      /*0x1e932*/ 1248,
+      /*0x10429*/ 1074,
+      /*0x01eb*/ 156,
+      /*0x1e29*/ 585,
+      /*0x1ea9*/ 644,
+      /*0x0129*/ 76,
+      /*0x0229*/ 184,
+      /*0x2ca9*/ 876,
+      /*0x037c*/ 239,
+      -1, -1,
+      /*0x2d11*/ 926,
+      -1,
+      /*0x1f37*/ 717,
+      /*0x00e7*/ 32,
+      -1, -1,
+      /*0x0573*/ 457,
+      /*0x2c35*/ 806,
+      -1,
+      /*0x03bf*/ 259,
+      /*0x13ab*/ 488,
+      -1,
+      /*0x04ab*/ 372,
+      -1,
+      /*0x1042b*/ 1076,
+      -1,
+      /*0x1e2b*/ 586,
+      /*0x1eab*/ 645,
+      /*0x012b*/ 77,
+      /*0x022b*/ 185,
+      /*0x2cab*/ 877,
+      -1,
+      /*0x1f01*/ 689,
+      /*0x056b*/ 449,
+      -1,
+      /*0x03b1*/ 245,
+      /*0x2173*/ 761,
+      -1,
+      /*0x2d08*/ 917,
+      -1, -1, -1,
+      /*0xa791*/ 1032,
+      /*0xa729*/ 989,
+      -1,
+      /*0x13c6*/ 515,
+      /*0x0446*/ 313,
+      /*0x04c6*/ 385,
+      /*0x1f33*/ 713,
+      /*0x10446*/ 1103,
+      /*0x13a1*/ 478,
+      /*0x050f*/ 422,
+      /*0x04a1*/ 367,
+      /*0x0146*/ 89,
+      /*0x01ef*/ 158,
+      -1,
+      /*0x1e21*/ 581,
+      /*0x1ea1*/ 640,
+      /*0x0121*/ 72,
+      -1,
+      /*0x2ca1*/ 872,
+      /*0x13c4*/ 513,
+      /*0x0444*/ 311,
+      /*0x04c4*/ 384,
+      -1,
+      /*0x10444*/ 1101,
+      -1,
+      /*0xa72b*/ 990,
+      /*0x13f2*/ 559,
+      /*0x0144*/ 88,
+      /*0x2d0f*/ 924,
+      /*0x0072*/ 16,
+      /*0x01ed*/ 157,
+      /*0x104f2*/ 1139,
+      -1, -1,
+      /*0x1f25*/ 707,
+      /*0x0272*/ 221,
+      /*0x13bb*/ 504,
+      /*0x043b*/ 302,
+      /*0x04bb*/ 380,
+      /*0x2c3f*/ 816,
+      /*0x1043b*/ 1092,
+      -1,
+      /*0x1e3b*/ 594,
+      /*0x1ebb*/ 653,
+      /*0x056f*/ 453,
+      /*0x0495*/ 361,
+      /*0x2cbb*/ 885,
+      -1,
+      /*0x03bd*/ 257,
+      /*0x1e15*/ 575,
+      /*0x1e95*/ 639,
+      /*0x0115*/ 66,
+      /*0x0215*/ 175,
+      /*0x2c95*/ 866,
+      -1,
+      /*0x2c31*/ 802,
+      -1,
+      /*0x118c2*/ 1202,
+      /*0x1f35*/ 715,
+      /*0x03b9*/ 253,
+      /*0xa691*/ 980,
+      -1,
+      /*0x056d*/ 451,
+      -1, -1,
+      /*0x0493*/ 360,
+      -1,
+      /*0x2c42*/ 819,
+      /*0x03af*/ 244,
+      /*0x1e13*/ 574,
+      /*0x1e93*/ 638,
+      /*0x0113*/ 65,
+      /*0x0213*/ 174,
+      /*0x2c93*/ 865,
+      -1,
+      /*0x047b*/ 352,
+      /*0x04fb*/ 412,
+      -1, -1,
+      /*0x104fb*/ 1148,
+      /*0x1e7b*/ 626,
+      /*0x1efb*/ 685,
+      -1,
+      /*0xa73b*/ 997,
+      -1,
+      /*0x10cc6*/ 1155,
+      /*0x0479*/ 351,
+      /*0x04f9*/ 411,
+      /*0x0079*/ 23,
+      -1,
+      /*0x104f9*/ 1146,
+      /*0x1e79*/ 625,
+      /*0x1ef9*/ 684,
+      -1,
+      /*0x1f23*/ 705,
+      /*0x0501*/ 415,
+      -1, -1,
+      /*0x047d*/ 353,
+      /*0x04fd*/ 413,
+      /*0x0283*/ 225,
+      /*0x10cc4*/ 1153,
+      /*0x00fe*/ 54,
+      /*0x1e7d*/ 627,
+      /*0x1efd*/ 686,
+      /*0x1f05*/ 693,
+      /*0x027d*/ 223,
+      /*0x01a5*/ 129,
+      /*0x10cf2*/ 1199,
+      /*0x0499*/ 363,
+      /*0x2c3d*/ 814,
+      -1,
+      /*0x1e937*/ 1253,
+      /*0x1e19*/ 577,
+      /*0x2d01*/ 910,
+      /*0x0119*/ 68,
+      /*0x0219*/ 177,
+      /*0x2c99*/ 868,
+      -1, -1,
+      /*0xa68f*/ 979,
+      /*0x2c39*/ 810,
+      -1,
+      /*0x0477*/ 350,
+      /*0x04f7*/ 410,
+      /*0x0077*/ 21,
+      /*0xa7b7*/ 1045,
+      /*0x104f7*/ 1144,
+      /*0x1e77*/ 624,
+      /*0x1ef7*/ 683,
+      /*0x0177*/ 113,
+      /*0x1e07*/ 568,
+      /*0x1e87*/ 632,
+      /*0x0107*/ 59,
+      /*0x0207*/ 168,
+      /*0x2c87*/ 859,
+      -1,
+      /*0x1d79*/ 563,
+      /*0x1f31*/ 711,
+      /*0x0525*/ 433,
+      -1, -1,
+      /*0x01ad*/ 131,
+      /*0x037b*/ 238,
+      /*0x13d0*/ 525,
+      /*0x0450*/ 323,
+      /*0xa781*/ 1027,
+      -1,
+      /*0x1e933*/ 1249,
+      /*0x1d7d*/ 564,
+      /*0x1f42*/ 720,
+      /*0x047f*/ 354,
+      /*0x04ff*/ 414,
+      /*0x0250*/ 199,
+      -1,
+      /*0x1f27*/ 709,
+      /*0x1e7f*/ 628,
+      /*0x1eff*/ 687,
+      /*0x2d25*/ 946,
+      /*0x24d0*/ 775,
+      /*0x13ce*/ 523,
+      /*0x044e*/ 321,
+      /*0x04ce*/ 389,
+      /*0x03c6*/ 265,
+      /*0x1044e*/ 1111,
+      /*0x0497*/ 362,
+      /*0x037d*/ 240,
+      /*0x01a3*/ 128,
+      -1,
+      /*0x1e17*/ 576,
+      /*0x1f71*/ 737,
+      /*0x0117*/ 67,
+      /*0x0217*/ 176,
+      /*0x2c97*/ 867,
+      /*0x052d*/ 437,
+      -1,
+      /*0x1e925*/ 1235,
+      -1,
+      /*0x0185*/ 119,
+      /*0x03c4*/ 263,
+      /*0x1f75*/ 741,
+      /*0x13cc*/ 521,
+      /*0x044c*/ 319,
+      /*0x04cc*/ 388,
+      -1,
+      /*0x1044c*/ 1109,
+      /*0x03f2*/ 287,
+      /*0xff42*/ 1048,
+      -1,
+      /*0x13e6*/ 547,
+      /*0xa7a5*/ 1041,
+      /*0x0377*/ 237,
+      /*0x0066*/ 5,
+      /*0x2d2d*/ 948,
+      /*0x104e6*/ 1127,
+      /*0x01bf*/ 137,
+      /*0x03bb*/ 255,
+      /*0xa77f*/ 1026,
+      /*0x0266*/ 213,
+      /*0x0523*/ 432,
+      /*0x1e935*/ 1251,
+      /*0x1f7c*/ 748,
+      -1, -1,
+      /*0x24e6*/ 797,
+      -1,
+      /*0xa681*/ 972,
+      /*0x007a*/ 24,
+      -1,
+      /*0x104fa*/ 1147,
+      /*0x0505*/ 417,
+      /*0x1e92d*/ 1243,
+      /*0x017a*/ 114,
+      -1,
+      /*0xa7b5*/ 1044,
+      /*0x118c6*/ 1206,
+      -1, -1,
+      /*0x2d23*/ 944,
+      -1,
+      /*0x13c8*/ 517,
+      /*0x0448*/ 315,
+      /*0x04c8*/ 386,
+      -1,
+      /*0x10448*/ 1105,
+      /*0x2c46*/ 823,
+      /*0x10cd0*/ 1165,
+      /*0x1f03*/ 691,
+      /*0x0148*/ 90,
+      /*0x2d05*/ 914,
+      /*0x2184*/ 774,
+      /*0x118c4*/ 1204,
+      /*0x13d8*/ 533,
+      /*0x0458*/ 331,
+      /*0x03fb*/ 290,
+      /*0x13ec*/ 553,
+      /*0x1e923*/ 1233,
+      /*0x104d8*/ 1113,
+      /*0x006c*/ 10,
+      -1,
+      /*0x104ec*/ 1133,
+      /*0x2c44*/ 821,
+      /*0x10cce*/ 1163,
+      -1,
+      /*0x026c*/ 218,
+      /*0x2cec*/ 906,
+      -1,
+      /*0x24d8*/ 783,
+      /*0x049d*/ 365,
+      -1,
+      /*0xa7a3*/ 1040,
+      /*0xa77a*/ 1024,
+      /*0x1e1d*/ 579,
+      /*0x01f5*/ 160,
+      /*0x011d*/ 70,
+      /*0x021d*/ 179,
+      /*0x2c9d*/ 870,
+      -1,
+      /*0x2c3b*/ 812,
+      -1,
+      /*0x0527*/ 434,
+      /*0xa785*/ 1029,
+      -1,
+      /*0x10ccc*/ 1161,
+      /*0x1e93f*/ 1261,
+      -1,
+      /*0x01bd*/ 136,
+      /*0x13e8*/ 549,
+      -1, -1,
+      /*0x0068*/ 7,
+      /*0x10ce6*/ 1187,
+      /*0x104e8*/ 1129,
+      -1, -1,
+      /*0x0571*/ 455,
+      /*0x0268*/ 214,
+      /*0x01b9*/ 135,
+      /*0x13f0*/ 557,
+      /*0x2d27*/ 947,
+      /*0x1e931*/ 1247,
+      /*0x0070*/ 14,
+      /*0x24e8*/ 799,
+      /*0x104f0*/ 1137,
+      -1,
+      /*0x0575*/ 459,
+      -1, -1, -1,
+      /*0x13dc*/ 537,
+      /*0x045c*/ 335,
+      -1,
+      /*0x1e942*/ 1264,
+      -1,
+      /*0x104dc*/ 1117,
+      /*0x2171*/ 759,
+      -1,
+      /*0x1e927*/ 1237,
+      /*0x025c*/ 208,
+      /*0x0076*/ 20,
+      /*0x0183*/ 118,
+      /*0x104f6*/ 1143,
+      /*0x10cc8*/ 1157,
+      /*0x0287*/ 226,
+      /*0x24dc*/ 787,
+      /*0x2175*/ 763,
+      /*0x057c*/ 466,
+      /*0x13d6*/ 531,
+      /*0x0456*/ 329,
+      -1,
+      /*0x13e0*/ 541,
+      /*0xa7a7*/ 1042,
+      -1,
+      /*0x1f21*/ 703,
+      /*0x10cd8*/ 1173,
+      /*0x104e0*/ 1121,
+      /*0x0256*/ 204,
+      /*0x10cec*/ 1193,
+      /*0x052f*/ 438,
+      /*0x0260*/ 209,
+      /*0x03ce*/ 273,
+      /*0xa685*/ 974,
+      /*0x24d6*/ 781,
+      -1,
+      /*0x1f44*/ 722,
+      /*0x24e0*/ 791,
+      /*0x217c*/ 770,
+      /*0x13d4*/ 529,
+      /*0x0454*/ 327,
+      -1, -1,
+      /*0x1f72*/ 738,
+      /*0x0503*/ 416,
+      -1,
+      /*0x13ea*/ 551,
+      /*0x1e93d*/ 1259,
+      /*0x0254*/ 203,
+      /*0x006a*/ 8,
+      -1,
+      /*0x104ea*/ 1131,
+      -1,
+      /*0x03cc*/ 271,
+      /*0x24d4*/ 779,
+      /*0x026a*/ 216,
+      -1,
+      /*0xff46*/ 1052,
+      /*0x1e939*/ 1255,
+      /*0x13e4*/ 545,
+      /*0x1f15*/ 701,
+      /*0x10ce8*/ 1189,
+      /*0x0064*/ 3,
+      /*0x2d03*/ 912,
+      /*0x104e4*/ 1125,
+      /*0x13b6*/ 499,
+      /*0x0436*/ 297,
+      /*0x1e92f*/ 1245,
+      /*0x118d0*/ 1216,
+      /*0x10436*/ 1087,
+      -1, -1,
+      /*0x10cf0*/ 1197,
+      /*0xff44*/ 1050,
+      /*0x24e4*/ 795,
+      /*0x0078*/ 22,
+      /*0x0529*/ 435,
+      /*0x104f8*/ 1145,
+      /*0x2c50*/ 833,
+      -1,
+      /*0x1f13*/ 699,
+      -1,
+      /*0x00f3*/ 44,
+      /*0x10cdc*/ 1177,
+      /*0x118ce*/ 1214,
+      /*0x13ca*/ 519,
+      /*0x044a*/ 317,
+      /*0x04ca*/ 387,
+      -1,
+      /*0x1044a*/ 1107,
+      -1,
+      /*0x1f7b*/ 747,
+      /*0x03c8*/ 267,
+      /*0x01c6*/ 138,
+      /*0x2c4e*/ 831,
+      /*0xa783*/ 1028,
+      -1, -1,
+      /*0x01a1*/ 127,
+      /*0x00eb*/ 36,
+      /*0x052b*/ 436,
+      /*0x10cd6*/ 1171,
+      /*0x1f79*/ 745,
+      -1,
+      /*0x10ce0*/ 1181,
+      /*0x118cc*/ 1212,
+      /*0x13f4*/ 561,
+      /*0x13d2*/ 527,
+      /*0x0452*/ 325,
+      /*0x0074*/ 18,
+      -1,
+      /*0x104f4*/ 1141,
+      -1,
+      /*0x1e929*/ 1239,
+      /*0x1f7d*/ 749,
+      /*0x2c4c*/ 829,
+      /*0x0252*/ 201,
+      -1, -1, -1, -1,
+      /*0x10cd4*/ 1169,
+      /*0x24d2*/ 777,
+      /*0x2c66*/ 850,
+      -1,
+      /*0x13b0*/ 493,
+      /*0x0430*/ 291,
+      /*0xa7a9*/ 1043,
+      /*0x10cea*/ 1191,
+      /*0x10430*/ 1081,
+      /*0x0521*/ 431,
+      -1, -1,
+      /*0x0195*/ 123,
+      -1,
+      /*0x13e2*/ 543,
+      /*0x029d*/ 233,
+      /*0x1e92b*/ 1241,
+      /*0x0062*/ 1,
+      /*0x1f77*/ 743,
+      /*0x104e2*/ 1123,
+      /*0x10ce4*/ 1185,
+      /*0x1f07*/ 695,
+      -1,
+      /*0x118c8*/ 1208,
+      -1, -1, -1,
+      /*0x0572*/ 456,
+      /*0x2d21*/ 942,
+      /*0x24e2*/ 793,
+      /*0x1fb1*/ 751,
+      /*0x00ef*/ 40,
+      /*0x048d*/ 357,
+      /*0x2c48*/ 825,
+      /*0xa683*/ 973,
+      /*0x118d8*/ 1224,
+      /*0x1e0d*/ 571,
+      /*0x1e8d*/ 635,
+      /*0x010d*/ 62,
+      /*0x020d*/ 171,
+      /*0x2c8d*/ 862,
+      -1, -1,
+      /*0x01fb*/ 162,
+      /*0x0515*/ 425,
+      /*0x2c58*/ 841,
+      /*0x10cca*/ 1159,
+      /*0x2172*/ 760,
+      /*0x2c6c*/ 853,
+      /*0x00ed*/ 38,
+      -1,
+      /*0x13b4*/ 497,
+      /*0x0434*/ 295,
+      -1,
+      /*0x01f9*/ 161,
+      /*0x10434*/ 1085,
+      -1, -1, -1, -1,
+      /*0xa7a1*/ 1039,
+      -1, -1,
+      /*0x2d15*/ 930,
+      /*0x0513*/ 424,
+      -1,
+      /*0x01fd*/ 163,
+      -1,
+      /*0x10cd2*/ 1167,
+      /*0x1e09*/ 569,
+      /*0x1e89*/ 633,
+      /*0x0109*/ 60,
+      /*0x0209*/ 169,
+      /*0x2c89*/ 860,
+      /*0x1e93b*/ 1257,
+      /*0x057b*/ 465,
+      /*0x0199*/ 124,
+      /*0xff50*/ 1062,
+      -1,
+      /*0x13ee*/ 555,
+      /*0x2c68*/ 851,
+      -1,
+      /*0x006e*/ 12,
+      /*0x2d13*/ 928,
+      /*0x104ee*/ 1135,
+      /*0x1f66*/ 734,
+      /*0x0579*/ 463,
+      -1, -1,
+      /*0x2cee*/ 907,
+      -1, -1,
+      /*0x118dc*/ 1228,
+      /*0xff4e*/ 1060,
+      -1,
+      /*0x217b*/ 769,
+      /*0x10ce2*/ 1183,
+      -1,
+      /*0x057d*/ 467,
+      -1,
+      /*0x1f7a*/ 746,
+      -1,
+      /*0x2c5c*/ 845,
+      -1,
+      /*0x03b6*/ 250,
+      -1,
+      /*0x2179*/ 767,
+      -1,
+      /*0x0519*/ 427,
+      /*0x2c76*/ 855,
+      /*0x118d6*/ 1222,
+      /*0x03f8*/ 289,
+      -1,
+      /*0x01d0*/ 142,
+      /*0xff4c*/ 1058,
+      /*0xa793*/ 1033,
+      -1, -1,
+      /*0x217d*/ 771,
+      /*0x01ff*/ 164,
+      /*0x2c56*/ 839,
+      -1, -1,
+      /*0x0577*/ 461,
+      /*0x03ca*/ 269,
+      -1,
+      /*0x0507*/ 418,
+      /*0x2d19*/ 934,
+      /*0x049f*/ 366,
+      /*0x01ce*/ 141,
+      /*0x118d4*/ 1220,
+      -1,
+      /*0x1e1f*/ 580,
+      -1,
+      /*0x011f*/ 71,
+      /*0x021f*/ 180,
+      /*0x2c9f*/ 871,
+      -1, -1, -1,
+      /*0x2c54*/ 837,
+      /*0x13de*/ 539,
+      /*0x045e*/ 337,
+      /*0x2177*/ 765,
+      -1,
+      /*0x2d07*/ 916,
+      /*0x104de*/ 1119,
+      /*0x2c6a*/ 852,
+      -1, -1,
+      /*0x01cc*/ 140,
+      /*0x057f*/ 469,
+      -1,
+      /*0xff48*/ 1054,
+      -1,
+      /*0xa695*/ 982,
+      /*0x24de*/ 789,
+      -1, -1,
+      /*0xa799*/ 1035,
+      -1,
+      /*0x10cee*/ 1195,
+      -1, -1,
+      /*0x0517*/ 426,
+      /*0xff58*/ 1070,
+      /*0x2c36*/ 807,
+      -1, -1, -1, -1,
+      /*0x217f*/ 773,
+      -1, -1,
+      /*0x1f70*/ 736,
+      /*0xa693*/ 981,
+      /*0x118ca*/ 1210,
+      /*0xa787*/ 1030,
+      -1, -1, -1,
+      /*0x214e*/ 757,
+      -1,
+      /*0x2d17*/ 932,
+      -1, -1,
+      /*0x2c4a*/ 827,
+      /*0x13be*/ 507,
+      /*0x043e*/ 305,
+      -1,
+      /*0x0566*/ 444,
+      /*0x1043e*/ 1095,
+      /*0x1f76*/ 742,
+      -1, -1,
+      /*0x013e*/ 85,
+      -1, -1,
+      /*0x118d2*/ 1218,
+      /*0x13ba*/ 503,
+      /*0x043a*/ 301,
+      /*0x01d8*/ 146,
+      -1,
+      /*0x1043a*/ 1091,
+      -1,
+      /*0x057a*/ 464,
+      /*0x1f60*/ 728,
+      /*0x013a*/ 83,
+      /*0x2c52*/ 835,
+      -1, -1,
+      /*0x03b4*/ 248,
+      -1, -1, -1,
+      /*0xa797*/ 1034,
+      -1, -1, -1,
+      /*0xa699*/ 984,
+      -1, -1, -1,
+      /*0x10cde*/ 1179,
+      -1,
+      /*0x217a*/ 768,
+      /*0x2c30*/ 801,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1,
+      /*0x056c*/ 450,
+      /*0xa687*/ 975,
+      -1, -1,
+      /*0xff56*/ 1068,
+      /*0x0289*/ 228,
+      -1,
+      /*0x1f64*/ 732,
+      -1, -1, -1,
+      /*0x051d*/ 429,
+      -1,
+      /*0x1f36*/ 716,
+      -1, -1, -1, -1, -1, -1,
+      /*0x1f78*/ 744,
+      -1,
+      /*0x01dc*/ 148,
+      -1,
+      /*0xff54*/ 1066,
+      -1,
+      /*0x00f1*/ 42,
+      -1, -1, -1,
+      /*0x2d1d*/ 938,
+      -1,
+      /*0x0568*/ 446,
+      -1, -1, -1,
+      /*0x00f5*/ 46,
+      /*0x2c34*/ 805,
+      -1,
+      /*0xa697*/ 983,
+      /*0x01d6*/ 145,
+      -1, -1,
+      /*0x0570*/ 454,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1,
+      /*0x1f74*/ 740,
+      -1, -1,
+      /*0x00fc*/ 52,
+      -1, -1,
+      /*0x01d4*/ 144,
+      /*0x0576*/ 460,
+      /*0xa79d*/ 1037,
+      /*0x2170*/ 758,
+      -1, -1, -1, -1, -1, -1,
+      /*0xff4a*/ 1056,
+      -1, -1,
+      /*0x1f30*/ 710,
+      -1, -1, -1, -1, -1, -1,
+      -1,
+      /*0x2176*/ 764,
+      -1,
+      /*0x1f62*/ 730,
+      -1, -1,
+      /*0x01b6*/ 134,
+      -1, -1, -1, -1, -1,
+      /*0xff52*/ 1064,
+      -1, -1, -1, -1, -1, -1,
+      /*0x056a*/ 448,
+      -1, -1, -1, -1, -1,
+      /*0x1fd0*/ 752,
+      -1, -1, -1, -1, -1,
+      /*0x03be*/ 258,
+      /*0x0564*/ 442,
+      -1, -1, -1, -1,
+      /*0x118de*/ 1230,
+      -1, -1,
+      /*0x1f34*/ 714,
+      -1, -1,
+      /*0x03ba*/ 254,
+      -1,
+      /*0x0578*/ 462,
+      -1,
+      /*0x2c5e*/ 847,
+      /*0x01d2*/ 143,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1,
+      /*0x2178*/ 766,
+      /*0x01b0*/ 132,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1,
+      /*0x1e936*/ 1252,
+      -1, -1, -1,
+      /*0x0574*/ 458,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1,
+      /*0x2c3e*/ 815,
+      -1, -1, -1, -1, -1,
+      /*0x2174*/ 762,
+      -1, -1, -1, -1, -1,
+      /*0x2c3a*/ 811,
+      -1,
+      /*0x00f2*/ 43,
+      /*0x0562*/ 440,
+      -1, -1, -1, -1,
+      /*0x01b4*/ 133,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1,
+      /*0x050d*/ 421,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1,
+      /*0x1e930*/ 1246,
+      -1, -1, -1, -1, -1, -1,
+      -1,
+      /*0x2d0d*/ 922,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1,
+      /*0x00fb*/ 51,
+      -1,
+      /*0x0509*/ 419,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1,
+      /*0x00f9*/ 49,
+      -1, -1, -1, -1, -1, -1,
+      /*0x056e*/ 452,
+      -1, -1,
+      /*0x2d09*/ 918,
+      -1,
+      /*0x00fd*/ 53,
+      -1, -1, -1,
+      /*0x1e934*/ 1250,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1,
+      /*0x1fe0*/ 754,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1,
+      /*0x051f*/ 430,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1,
+      /*0x00ff*/ 55,
+      -1, -1, -1,
+      /*0xa68d*/ 978,
+      -1, -1, -1,
+      /*0x2d1f*/ 940,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1,
+      /*0xa689*/ 976,
+      -1,
+      /*0x00e6*/ 31,
+      /*0xa79f*/ 1038,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1,
+      /*0x00fa*/ 50,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1,
+      /*0x1fb0*/ 750,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1,
+      /*0x00ec*/ 37,
+      -1,
+      /*0x1e93e*/ 1260,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1,
+      /*0x1e93a*/ 1256,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1,
+      /*0x00e8*/ 33,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1,
+      /*0x00f0*/ 41,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1,
+      /*0x00f6*/ 47,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1,
+      /*0x00e0*/ 25,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1,
+      /*0x00ea*/ 35,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      /*0x00e4*/ 29,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      /*0x00f8*/ 48,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1,
+      /*0x00f4*/ 45,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1,
+      /*0x00e2*/ 27,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1,
+      /*0x00ee*/ 39
+    };
+
+  if (code <= MAX_CODE_VALUE && code >= MIN_CODE_VALUE)
+    {
+      register unsigned int key = onigenc_unicode_CaseUnfold_11_hash(code);
+
+      if (key <= MAX_HASH_VALUE)
+        {
+          register short s = wordlist[key];
+
+          if (s >= 0 && code1_equal(code, CaseUnfold_11_Table[s].from))
+            return &CaseUnfold_11_Table[s].to;
+        }
+    }
+  return 0;
+}
+
+static const CaseUnfold_12_Type CaseUnfold_12_Table[] = {
+#define CaseUnfold_12 (*(CaseUnfold_12_Type (*)[58])(CaseUnfold_12_Table+0))
+  {{0x0061, 0x02be}, {1, {0x1e9a}}},
+  {{0x0066, 0x0066}, {1, {0xfb00}}},
+  {{0x0066, 0x0069}, {1, {0xfb01}}},
+  {{0x0066, 0x006c}, {1, {0xfb02}}},
+  {{0x0068, 0x0331}, {1, {0x1e96}}},
+  {{0x006a, 0x030c}, {1, {0x01f0}}},
+  {{0x0073, 0x0073}, {2, {0x00df, 0x1e9e}}},
+  {{0x0073, 0x0074}, {2, {0xfb05, 0xfb06}}},
+  {{0x0074, 0x0308}, {1, {0x1e97}}},
+  {{0x0077, 0x030a}, {1, {0x1e98}}},
+  {{0x0079, 0x030a}, {1, {0x1e99}}},
+  {{0x02bc, 0x006e}, {1, {0x0149}}},
+  {{0x03ac, 0x03b9}, {1, {0x1fb4}}},
+  {{0x03ae, 0x03b9}, {1, {0x1fc4}}},
+  {{0x03b1, 0x0342}, {1, {0x1fb6}}},
+  {{0x03b1, 0x03b9}, {2, {0x1fb3, 0x1fbc}}},
+  {{0x03b7, 0x0342}, {1, {0x1fc6}}},
+  {{0x03b7, 0x03b9}, {2, {0x1fc3, 0x1fcc}}},
+  {{0x03b9, 0x0342}, {1, {0x1fd6}}},
+  {{0x03c1, 0x0313}, {1, {0x1fe4}}},
+  {{0x03c5, 0x0313}, {1, {0x1f50}}},
+  {{0x03c5, 0x0342}, {1, {0x1fe6}}},
+  {{0x03c9, 0x0342}, {1, {0x1ff6}}},
+  {{0x03c9, 0x03b9}, {2, {0x1ff3, 0x1ffc}}},
+  {{0x03ce, 0x03b9}, {1, {0x1ff4}}},
+  {{0x0565, 0x0582}, {1, {0x0587}}},
+  {{0x0574, 0x0565}, {1, {0xfb14}}},
+  {{0x0574, 0x056b}, {1, {0xfb15}}},
+  {{0x0574, 0x056d}, {1, {0xfb17}}},
+  {{0x0574, 0x0576}, {1, {0xfb13}}},
+  {{0x057e, 0x0576}, {1, {0xfb16}}},
+  {{0x1f00, 0x03b9}, {2, {0x1f80, 0x1f88}}},
+  {{0x1f01, 0x03b9}, {2, {0x1f81, 0x1f89}}},
+  {{0x1f02, 0x03b9}, {2, {0x1f82, 0x1f8a}}},
+  {{0x1f03, 0x03b9}, {2, {0x1f83, 0x1f8b}}},
+  {{0x1f04, 0x03b9}, {2, {0x1f84, 0x1f8c}}},
+  {{0x1f05, 0x03b9}, {2, {0x1f85, 0x1f8d}}},
+  {{0x1f06, 0x03b9}, {2, {0x1f86, 0x1f8e}}},
+  {{0x1f07, 0x03b9}, {2, {0x1f87, 0x1f8f}}},
+  {{0x1f20, 0x03b9}, {2, {0x1f90, 0x1f98}}},
+  {{0x1f21, 0x03b9}, {2, {0x1f91, 0x1f99}}},
+  {{0x1f22, 0x03b9}, {2, {0x1f92, 0x1f9a}}},
+  {{0x1f23, 0x03b9}, {2, {0x1f93, 0x1f9b}}},
+  {{0x1f24, 0x03b9}, {2, {0x1f94, 0x1f9c}}},
+  {{0x1f25, 0x03b9}, {2, {0x1f95, 0x1f9d}}},
+  {{0x1f26, 0x03b9}, {2, {0x1f96, 0x1f9e}}},
+  {{0x1f27, 0x03b9}, {2, {0x1f97, 0x1f9f}}},
+  {{0x1f60, 0x03b9}, {2, {0x1fa0, 0x1fa8}}},
+  {{0x1f61, 0x03b9}, {2, {0x1fa1, 0x1fa9}}},
+  {{0x1f62, 0x03b9}, {2, {0x1fa2, 0x1faa}}},
+  {{0x1f63, 0x03b9}, {2, {0x1fa3, 0x1fab}}},
+  {{0x1f64, 0x03b9}, {2, {0x1fa4, 0x1fac}}},
+  {{0x1f65, 0x03b9}, {2, {0x1fa5, 0x1fad}}},
+  {{0x1f66, 0x03b9}, {2, {0x1fa6, 0x1fae}}},
+  {{0x1f67, 0x03b9}, {2, {0x1fa7, 0x1faf}}},
+  {{0x1f70, 0x03b9}, {1, {0x1fb2}}},
+  {{0x1f74, 0x03b9}, {1, {0x1fc2}}},
+  {{0x1f7c, 0x03b9}, {1, {0x1ff2}}},
+#define CaseUnfold_12_Locale (*(CaseUnfold_12_Type (*)[1])(CaseUnfold_12_Table+58))
+  {{0x0069, 0x0307}, {1, {0x0130}}},
+};
+
+/* ANSI-C code produced by gperf version 3.1 */
+/* Command-line: gperf -7 -k1,2,3,4,5,6 -F,-1 -c -j1 -i1 -t -T -E -C -H onigenc_unicode_CaseUnfold_12_hash -N onigenc_unicode_CaseUnfold_12_lookup -n  */
+
+/* maximum key range = 71, duplicates = 0 */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+/*ARGSUSED*/
+static unsigned int
+onigenc_unicode_CaseUnfold_12_hash(const OnigCodePoint *codes)
+{
+  static const unsigned char asso_values[] =
+    {
+       3, 58, 54, 57, 56, 16,  8,  2, 43, 82,
+       3,  1, 23, 82, 82, 82, 82, 82, 82,  4,
+      82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
+      82, 82, 52, 51, 50, 49, 48, 47, 46, 45,
+      82, 82, 82, 82, 43, 82, 42, 82, 82, 13,
+      82, 82, 82, 82, 82, 11, 82,  1, 82, 82,
+      14, 82,  1, 82, 82, 31,  3, 82, 82, 30,
+      82, 82, 82, 10, 82, 82, 82, 82, 37, 82,
+      82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
+      82, 82, 82, 82, 82, 82, 37, 15, 36, 35,
+      34, 17,  1, 33, 12,  4, 23, 23, 26, 21,
+      13, 82, 27, 82, 82,  2,  5, 82, 11, 16,
+      82, 15, 82, 82, 23, 82,  8, 82
+    };
+  return asso_values[bits_at(codes, 5)] + asso_values[bits_at(codes, 4)] + asso_values[bits_at(codes, 3)] + asso_values[bits_at(codes, 2)] + asso_values[bits_at(codes, 1)] + asso_values[bits_at(codes, 0)];
+}
+
+static const CodePointList2 *
+onigenc_unicode_CaseUnfold_12_lookup(const OnigCodePoint *codes)
+{
+  enum
+    {
+      MIN_CODE_VALUE = 0x61,
+      MAX_CODE_VALUE = 0x1f7c,
+      TOTAL_KEYWORDS = 59,
+      MIN_WORD_LENGTH = 6,
+      MAX_WORD_LENGTH = 6,
+      MIN_HASH_VALUE = 11,
+      MAX_HASH_VALUE = 81
+    };
+
+  static const short wordlist[] =
+    {
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1,
+      /*0x1f66,0x03b9*/ 53,
+      /*0x1f07,0x03b9*/ 38,
+      /*0x1f00,0x03b9*/ 31,
+      /*0x0066,0x0066*/ 1,
+      /*0x1f74,0x03b9*/ 56,
+      /*0x0073,0x0073*/ 6,
+      /*0x0066,0x0069*/ 2,
+      /*0x1f06,0x03b9*/ 37,
+      /*0x0073,0x0074*/ 7,
+      /*0x03b9,0x0342*/ 18,
+      /*0x03c9,0x03b9*/ 23,
+      /*0x03b7,0x03b9*/ 17,
+      /*0x0069,0x0307*/ 58,
+      /*0x03b1,0x03b9*/ 15,
+      /*0x1f61,0x03b9*/ 48,
+      /*0x1f05,0x03b9*/ 36,
+      /*0x1f65,0x03b9*/ 52,
+      /*0x0574,0x0576*/ 29,
+      /*0x03c9,0x0342*/ 22,
+      /*0x03b7,0x0342*/ 16,
+      /*0x057e,0x0576*/ 30,
+      /*0x03b1,0x0342*/ 14,
+      /*0x1f7c,0x03b9*/ 57,
+      /*0x0574,0x0565*/ 26,
+      /*0x0079,0x030a*/ 10,
+      /*0x0077,0x030a*/ 9,
+      /*0x1f70,0x03b9*/ 55,
+      /*0x0574,0x056d*/ 28,
+      /*0x0066,0x006c*/ 3,
+      /*0x0574,0x056b*/ 27,
+      /*0x0061,0x02be*/ 0,
+      /*0x0068,0x0331*/ 4,
+      /*0x1f67,0x03b9*/ 54,
+      /*0x1f64,0x03b9*/ 51,
+      /*0x1f63,0x03b9*/ 50,
+      /*0x1f62,0x03b9*/ 49,
+      /*0x1f60,0x03b9*/ 47,
+      /*0x03ce,0x03b9*/ 24,
+      /*0x03c5,0x0342*/ 21,
+      /*0x03c5,0x0313*/ 20,
+      /*0x03c1,0x0313*/ 19,
+      /*0x02bc,0x006e*/ 11,
+      /*0x03ae,0x03b9*/ 13,
+      /*0x03ac,0x03b9*/ 12,
+      /*0x1f27,0x03b9*/ 46,
+      /*0x1f26,0x03b9*/ 45,
+      /*0x1f25,0x03b9*/ 44,
+      /*0x1f24,0x03b9*/ 43,
+      /*0x1f23,0x03b9*/ 42,
+      /*0x1f22,0x03b9*/ 41,
+      /*0x1f21,0x03b9*/ 40,
+      /*0x1f20,0x03b9*/ 39,
+      /*0x006a,0x030c*/ 5,
+      /*0x1f02,0x03b9*/ 33,
+      /*0x0074,0x0308*/ 8,
+      /*0x1f04,0x03b9*/ 35,
+      /*0x1f03,0x03b9*/ 34,
+      /*0x1f01,0x03b9*/ 32,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      /*0x0565,0x0582*/ 25
+    };
+
+  if (codes[0] <= MAX_CODE_VALUE && codes[0] >= MIN_CODE_VALUE &&
+      codes[1] <= MAX_CODE_VALUE && codes[1] >= MIN_CODE_VALUE)
+    {
+      register unsigned int key = onigenc_unicode_CaseUnfold_12_hash(codes);
+
+      if (key <= MAX_HASH_VALUE)
+        {
+          register short s = wordlist[key];
+
+          if (s >= 0 && code2_equal(codes, CaseUnfold_12_Table[s].from))
+            return &CaseUnfold_12_Table[s].to;
+        }
+    }
+  return 0;
+}
+
+static const CaseUnfold_13_Type CaseUnfold_13_Table[] = {
+#define CaseUnfold_13 (*(CaseUnfold_13_Type (*)[14])(CaseUnfold_13_Table+0))
+  {{0x0066, 0x0066, 0x0069}, {1, {0xfb03}}},
+  {{0x0066, 0x0066, 0x006c}, {1, {0xfb04}}},
+  {{0x03b1, 0x0342, 0x03b9}, {1, {0x1fb7}}},
+  {{0x03b7, 0x0342, 0x03b9}, {1, {0x1fc7}}},
+  {{0x03b9, 0x0308, 0x0300}, {1, {0x1fd2}}},
+  {{0x03b9, 0x0308, 0x0301}, {2, {0x0390, 0x1fd3}}},
+  {{0x03b9, 0x0308, 0x0342}, {1, {0x1fd7}}},
+  {{0x03c5, 0x0308, 0x0300}, {1, {0x1fe2}}},
+  {{0x03c5, 0x0308, 0x0301}, {2, {0x03b0, 0x1fe3}}},
+  {{0x03c5, 0x0308, 0x0342}, {1, {0x1fe7}}},
+  {{0x03c5, 0x0313, 0x0300}, {1, {0x1f52}}},
+  {{0x03c5, 0x0313, 0x0301}, {1, {0x1f54}}},
+  {{0x03c5, 0x0313, 0x0342}, {1, {0x1f56}}},
+  {{0x03c9, 0x0342, 0x03b9}, {1, {0x1ff7}}},
+};
+
+/* ANSI-C code produced by gperf version 3.1 */
+/* Command-line: gperf -7 -k1,2,3,4,5,6,7,8,9 -F,-1 -c -j1 -i1 -t -T -E -C -H onigenc_unicode_CaseUnfold_13_hash -N onigenc_unicode_CaseUnfold_13_lookup -n  */
+
+/* maximum key range = 20, duplicates = 0 */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+/*ARGSUSED*/
+static unsigned int
+onigenc_unicode_CaseUnfold_13_hash(const OnigCodePoint *codes)
+{
+  static const unsigned char asso_values[] =
+    {
+       7,  4, 47, 47, 47, 47,  1,  1,  2, 47,
+      47, 47, 47, 47, 47, 47, 47, 47, 47,  1,
+      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      47, 47, 47, 47, 47, 47, 47, 47, 47, 11,
+      47, 47, 47, 47, 47, 10, 47,  2, 47, 47,
+      47, 47, 47, 47, 47, 47,  1, 47, 47,  1,
+      47, 47, 47,  9, 47, 47, 47, 47, 47, 47,
+      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      47, 47,  1, 47, 47,  2, 47, 47,  1, 47,
+      47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+      47, 47, 47, 47, 47, 47, 47, 47
+    };
+  return asso_values[bits_at(codes, 8)] + asso_values[bits_at(codes, 7)] + asso_values[bits_at(codes, 6)] + asso_values[bits_at(codes, 5)] + asso_values[bits_at(codes, 4)] + asso_values[bits_at(codes, 3)] + asso_values[bits_at(codes, 2)] + asso_values[bits_at(codes, 1)] + asso_values[bits_at(codes, 0)];
+}
+
+static const CodePointList2 *
+onigenc_unicode_CaseUnfold_13_lookup(const OnigCodePoint *codes)
+{
+  enum
+    {
+      MIN_CODE_VALUE = 0x66,
+      MAX_CODE_VALUE = 0x3c9,
+      TOTAL_KEYWORDS = 14,
+      MIN_WORD_LENGTH = 9,
+      MAX_WORD_LENGTH = 9,
+      MIN_HASH_VALUE = 27,
+      MAX_HASH_VALUE = 46
+    };
+
+  static const short wordlist[] =
+    {
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1, -1, -1, -1,
+      -1, -1, -1,
+      /*0x03c5,0x0313,0x0342*/ 12,
+      /*0x03c5,0x0308,0x0342*/ 9,
+      /*0x03b9,0x0308,0x0342*/ 6,
+      /*0x03c5,0x0313,0x0301*/ 11,
+      /*0x03c5,0x0308,0x0301*/ 8,
+      /*0x03b9,0x0308,0x0301*/ 5,
+      /*0x03c5,0x0313,0x0300*/ 10,
+      /*0x03c5,0x0308,0x0300*/ 7,
+      /*0x03b9,0x0308,0x0300*/ 4,
+      /*0x03c9,0x0342,0x03b9*/ 13,
+      /*0x03b7,0x0342,0x03b9*/ 3,
+      /*0x03b1,0x0342,0x03b9*/ 2,
+      -1, -1, -1, -1, -1, -1,
+      /*0x0066,0x0066,0x006c*/ 1,
+      /*0x0066,0x0066,0x0069*/ 0
+    };
+
+  if (codes[0] <= MAX_CODE_VALUE && codes[0] >= MIN_CODE_VALUE &&
+      codes[1] <= MAX_CODE_VALUE && codes[1] >= MIN_CODE_VALUE &&
+      codes[2] <= MAX_CODE_VALUE && codes[2] >= MIN_CODE_VALUE)
+    {
+      register unsigned int key = onigenc_unicode_CaseUnfold_13_hash(codes);
+
+      if (key <= MAX_HASH_VALUE)
+        {
+          register short s = wordlist[key];
+
+          if (s >= 0 && code3_equal(codes, CaseUnfold_13_Table[s].from))
+            return &CaseUnfold_13_Table[s].to;
+        }
+    }
+  return 0;
+}
+
+static const OnigCodePoint CaseMappingSpecials[] = {
+    L(1)|0x039C,
+    L(2)|0x0053, 0x0073, L(2)|0x0053, 0x0053,
+    L(2)|0x02BC, 0x004E,
+    L(1)|0x0053,
+    L(1)|0x01C5,
+    L(2)|0x0064, 0x017D, L(1)|0x01C4,
+    L(1)|0x01C8,
+    L(2)|0x006C, 0x004A, L(1)|0x01C7,
+    L(1)|0x01CB,
+    L(2)|0x006E, 0x004A, L(1)|0x01CA,
+    L(2)|0x004A, 0x030C,
+    L(1)|0x01F2,
+    L(2)|0x0064, 0x005A, L(1)|0x01F1,
+    L(1)|0x0399,
+    L(3)|0x0399, 0x0308, 0x0301,
+    L(3)|0x03A5, 0x0308, 0x0301,
+    L(1)|0x03A3,
+    L(1)|0x0392,
+    L(1)|0x0398,
+    L(1)|0x03A6,
+    L(1)|0x03A0,
+    L(1)|0x039A,
+    L(1)|0x03A1,
+    L(1)|0x0395,
+    L(2)|0x0535, 0x0582, L(2)|0x0535, 0x0552,
+    L(1)|0x0412,
+    L(1)|0x0414,
+    L(1)|0x041E,
+    L(1)|0x0421,
+    L(1)|0x0422,
+    L(1)|0x0422,
+    L(1)|0x042A,
+    L(1)|0x0462,
+    L(1)|0xA64A,
+    L(2)|0x0048, 0x0331,
+    L(2)|0x0054, 0x0308,
+    L(2)|0x0057, 0x030A,
+    L(2)|0x0059, 0x030A,
+    L(2)|0x0041, 0x02BE,
+    L(1)|0x1E60,
+    L(1)|0x00DF,
+    L(2)|0x03A5, 0x0313,
+    L(3)|0x03A5, 0x0313, 0x0300,
+    L(3)|0x03A5, 0x0313, 0x0301,
+    L(3)|0x03A5, 0x0313, 0x0342,
+    L(1)|0x1F88, L(2)|0x1F08, 0x0399,
+    L(1)|0x1F89, L(2)|0x1F09, 0x0399,
+    L(1)|0x1F8A, L(2)|0x1F0A, 0x0399,
+    L(1)|0x1F8B, L(2)|0x1F0B, 0x0399,
+    L(1)|0x1F8C, L(2)|0x1F0C, 0x0399,
+    L(1)|0x1F8D, L(2)|0x1F0D, 0x0399,
+    L(1)|0x1F8E, L(2)|0x1F0E, 0x0399,
+    L(1)|0x1F8F, L(2)|0x1F0F, 0x0399,
+    L(2)|0x1F00, 0x0399, L(1)|0x1F80, L(2)|0x1F08, 0x0399,
+    L(2)|0x1F01, 0x0399, L(1)|0x1F81, L(2)|0x1F09, 0x0399,
+    L(2)|0x1F02, 0x0399, L(1)|0x1F82, L(2)|0x1F0A, 0x0399,
+    L(2)|0x1F03, 0x0399, L(1)|0x1F83, L(2)|0x1F0B, 0x0399,
+    L(2)|0x1F04, 0x0399, L(1)|0x1F84, L(2)|0x1F0C, 0x0399,
+    L(2)|0x1F05, 0x0399, L(1)|0x1F85, L(2)|0x1F0D, 0x0399,
+    L(2)|0x1F06, 0x0399, L(1)|0x1F86, L(2)|0x1F0E, 0x0399,
+    L(2)|0x1F07, 0x0399, L(1)|0x1F87, L(2)|0x1F0F, 0x0399,
+    L(1)|0x1F98, L(2)|0x1F28, 0x0399,
+    L(1)|0x1F99, L(2)|0x1F29, 0x0399,
+    L(1)|0x1F9A, L(2)|0x1F2A, 0x0399,
+    L(1)|0x1F9B, L(2)|0x1F2B, 0x0399,
+    L(1)|0x1F9C, L(2)|0x1F2C, 0x0399,
+    L(1)|0x1F9D, L(2)|0x1F2D, 0x0399,
+    L(1)|0x1F9E, L(2)|0x1F2E, 0x0399,
+    L(1)|0x1F9F, L(2)|0x1F2F, 0x0399,
+    L(2)|0x1F20, 0x0399, L(1)|0x1F90, L(2)|0x1F28, 0x0399,
+    L(2)|0x1F21, 0x0399, L(1)|0x1F91, L(2)|0x1F29, 0x0399,
+    L(2)|0x1F22, 0x0399, L(1)|0x1F92, L(2)|0x1F2A, 0x0399,
+    L(2)|0x1F23, 0x0399, L(1)|0x1F93, L(2)|0x1F2B, 0x0399,
+    L(2)|0x1F24, 0x0399, L(1)|0x1F94, L(2)|0x1F2C, 0x0399,
+    L(2)|0x1F25, 0x0399, L(1)|0x1F95, L(2)|0x1F2D, 0x0399,
+    L(2)|0x1F26, 0x0399, L(1)|0x1F96, L(2)|0x1F2E, 0x0399,
+    L(2)|0x1F27, 0x0399, L(1)|0x1F97, L(2)|0x1F2F, 0x0399,
+    L(1)|0x1FA8, L(2)|0x1F68, 0x0399,
+    L(1)|0x1FA9, L(2)|0x1F69, 0x0399,
+    L(1)|0x1FAA, L(2)|0x1F6A, 0x0399,
+    L(1)|0x1FAB, L(2)|0x1F6B, 0x0399,
+    L(1)|0x1FAC, L(2)|0x1F6C, 0x0399,
+    L(1)|0x1FAD, L(2)|0x1F6D, 0x0399,
+    L(1)|0x1FAE, L(2)|0x1F6E, 0x0399,
+    L(1)|0x1FAF, L(2)|0x1F6F, 0x0399,
+    L(2)|0x1F60, 0x0399, L(1)|0x1FA0, L(2)|0x1F68, 0x0399,
+    L(2)|0x1F61, 0x0399, L(1)|0x1FA1, L(2)|0x1F69, 0x0399,
+    L(2)|0x1F62, 0x0399, L(1)|0x1FA2, L(2)|0x1F6A, 0x0399,
+    L(2)|0x1F63, 0x0399, L(1)|0x1FA3, L(2)|0x1F6B, 0x0399,
+    L(2)|0x1F64, 0x0399, L(1)|0x1FA4, L(2)|0x1F6C, 0x0399,
+    L(2)|0x1F65, 0x0399, L(1)|0x1FA5, L(2)|0x1F6D, 0x0399,
+    L(2)|0x1F66, 0x0399, L(1)|0x1FA6, L(2)|0x1F6E, 0x0399,
+    L(2)|0x1F67, 0x0399, L(1)|0x1FA7, L(2)|0x1F6F, 0x0399,
+    L(2)|0x1FBA, 0x0345, L(2)|0x1FBA, 0x0399,
+    L(1)|0x1FBC, L(2)|0x0391, 0x0399,
+    L(2)|0x0386, 0x0345, L(2)|0x0386, 0x0399,
+    L(2)|0x0391, 0x0342,
+    L(3)|0x0391, 0x0342, 0x0345, L(3)|0x0391, 0x0342, 0x0399,
+    L(2)|0x03B1, 0x0399, L(1)|0x1FB3, L(2)|0x0391, 0x0399,
+    L(1)|0x0399,
+    L(2)|0x1FCA, 0x0345, L(2)|0x1FCA, 0x0399,
+    L(1)|0x1FCC, L(2)|0x0397, 0x0399,
+    L(2)|0x0389, 0x0345, L(2)|0x0389, 0x0399,
+    L(2)|0x0397, 0x0342,
+    L(3)|0x0397, 0x0342, 0x0345, L(3)|0x0397, 0x0342, 0x0399,
+    L(2)|0x03B7, 0x0399, L(1)|0x1FC3, L(2)|0x0397, 0x0399,
+    L(3)|0x0399, 0x0308, 0x0300,
+    L(3)|0x0399, 0x0308, 0x0301,
+    L(2)|0x0399, 0x0342,
+    L(3)|0x0399, 0x0308, 0x0342,
+    L(3)|0x03A5, 0x0308, 0x0300,
+    L(3)|0x03A5, 0x0308, 0x0301,
+    L(2)|0x03A1, 0x0313,
+    L(2)|0x03A5, 0x0342,
+    L(3)|0x03A5, 0x0308, 0x0342,
+    L(2)|0x1FFA, 0x0345, L(2)|0x1FFA, 0x0399,
+    L(1)|0x1FFC, L(2)|0x03A9, 0x0399,
+    L(2)|0x038F, 0x0345, L(2)|0x038F, 0x0399,
+    L(2)|0x03A9, 0x0342,
+    L(3)|0x03A9, 0x0342, 0x0345, L(3)|0x03A9, 0x0342, 0x0399,
+    L(2)|0x03C9, 0x0399, L(1)|0x1FF3, L(2)|0x03A9, 0x0399,
+    L(2)|0x0046, 0x0066, L(2)|0x0046, 0x0046,
+    L(2)|0x0046, 0x0069, L(2)|0x0046, 0x0049,
+    L(2)|0x0046, 0x006C, L(2)|0x0046, 0x004C,
+    L(3)|0x0046, 0x0066, 0x0069, L(3)|0x0046, 0x0046, 0x0049,
+    L(3)|0x0046, 0x0066, 0x006C, L(3)|0x0046, 0x0046, 0x004C,
+    L(2)|0x0053, 0x0074, L(2)|0x0053, 0x0054,
+    L(2)|0x0053, 0x0074, L(2)|0x0053, 0x0054,
+    L(2)|0x0544, 0x0576, L(2)|0x0544, 0x0546,
+    L(2)|0x0544, 0x0565, L(2)|0x0544, 0x0535,
+    L(2)|0x0544, 0x056B, L(2)|0x0544, 0x053B,
+    L(2)|0x054E, 0x0576, L(2)|0x054E, 0x0546,
+    L(2)|0x0544, 0x056D, L(2)|0x0544, 0x053D,
+};
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/enc/unicode/name2ctype.h
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/enc/unicode/name2ctype.h	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/enc/unicode/name2ctype.h	(revision 331)
@@ -0,0 +1,38389 @@
+/* C code produced by gperf version 3.0.4 */
+/* Command-line: gperf -7 -c -j1 -i1 -t -C -P -T -H uniname2ctype_hash -Q uniname2ctype_pool -N uniname2ctype_p  */
+#ifndef USE_UNICODE_PROPERTIES
+/* Computed positions: -k'1,3' */
+#else /* USE_UNICODE_PROPERTIES */
+/* Computed positions: -k'1-3,5-6,12,16,$' */
+#endif /* USE_UNICODE_PROPERTIES */
+
+#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
+      && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
+      && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
+      && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
+      && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
+      && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
+      && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
+      && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
+      && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
+      && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
+      && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
+      && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
+      && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
+      && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
+      && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
+      && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
+      && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
+      && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
+      && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
+      && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
+      && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
+      && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
+      && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
+/* The character set is not based on ISO-646.  */
+error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
+#endif
+
+
+
+/* 'NEWLINE': [[:NEWLINE:]] */
+static const OnigCodePoint CR_NEWLINE[] = {
+	1,
+	0x000a, 0x000a,
+}; /* CR_NEWLINE */
+
+/* 'Alpha': [[:Alpha:]] */
+static const OnigCodePoint CR_Alpha[] = {
+	660,
+	0x0041, 0x005a,
+	0x0061, 0x007a,
+	0x00aa, 0x00aa,
+	0x00b5, 0x00b5,
+	0x00ba, 0x00ba,
+	0x00c0, 0x00d6,
+	0x00d8, 0x00f6,
+	0x00f8, 0x02c1,
+	0x02c6, 0x02d1,
+	0x02e0, 0x02e4,
+	0x02ec, 0x02ec,
+	0x02ee, 0x02ee,
+	0x0345, 0x0345,
+	0x0370, 0x0374,
+	0x0376, 0x0377,
+	0x037a, 0x037d,
+	0x037f, 0x037f,
+	0x0386, 0x0386,
+	0x0388, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03f5,
+	0x03f7, 0x0481,
+	0x048a, 0x052f,
+	0x0531, 0x0556,
+	0x0559, 0x0559,
+	0x0561, 0x0587,
+	0x05b0, 0x05bd,
+	0x05bf, 0x05bf,
+	0x05c1, 0x05c2,
+	0x05c4, 0x05c5,
+	0x05c7, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f2,
+	0x0610, 0x061a,
+	0x0620, 0x0657,
+	0x0659, 0x065f,
+	0x066e, 0x06d3,
+	0x06d5, 0x06dc,
+	0x06e1, 0x06e8,
+	0x06ed, 0x06ef,
+	0x06fa, 0x06fc,
+	0x06ff, 0x06ff,
+	0x0710, 0x073f,
+	0x074d, 0x07b1,
+	0x07ca, 0x07ea,
+	0x07f4, 0x07f5,
+	0x07fa, 0x07fa,
+	0x0800, 0x0817,
+	0x081a, 0x082c,
+	0x0840, 0x0858,
+	0x0860, 0x086a,
+	0x08a0, 0x08b4,
+	0x08b6, 0x08bd,
+	0x08d4, 0x08df,
+	0x08e3, 0x08e9,
+	0x08f0, 0x093b,
+	0x093d, 0x094c,
+	0x094e, 0x0950,
+	0x0955, 0x0963,
+	0x0971, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bd, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09cc,
+	0x09ce, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09f0, 0x09f1,
+	0x09fc, 0x09fc,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4c,
+	0x0a51, 0x0a51,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a70, 0x0a75,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abd, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acc,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0af9, 0x0afc,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3d, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4c,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b63,
+	0x0b71, 0x0b71,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcc,
+	0x0bd0, 0x0bd0,
+	0x0bd7, 0x0bd7,
+	0x0c00, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c39,
+	0x0c3d, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4c,
+	0x0c55, 0x0c56,
+	0x0c58, 0x0c5a,
+	0x0c60, 0x0c63,
+	0x0c80, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbd, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccc,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce3,
+	0x0cf1, 0x0cf2,
+	0x0d00, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d3a,
+	0x0d3d, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4c,
+	0x0d4e, 0x0d4e,
+	0x0d54, 0x0d57,
+	0x0d5f, 0x0d63,
+	0x0d7a, 0x0d7f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0df2, 0x0df3,
+	0x0e01, 0x0e3a,
+	0x0e40, 0x0e46,
+	0x0e4d, 0x0e4d,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ecd, 0x0ecd,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f00,
+	0x0f40, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f71, 0x0f81,
+	0x0f88, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x1000, 0x1036,
+	0x1038, 0x1038,
+	0x103b, 0x103f,
+	0x1050, 0x1062,
+	0x1065, 0x1068,
+	0x106e, 0x1086,
+	0x108e, 0x108e,
+	0x109c, 0x109d,
+	0x10a0, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x10fa,
+	0x10fc, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135f, 0x135f,
+	0x1380, 0x138f,
+	0x13a0, 0x13f5,
+	0x13f8, 0x13fd,
+	0x1401, 0x166c,
+	0x166f, 0x167f,
+	0x1681, 0x169a,
+	0x16a0, 0x16ea,
+	0x16ee, 0x16f8,
+	0x1700, 0x170c,
+	0x170e, 0x1713,
+	0x1720, 0x1733,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17b3,
+	0x17b6, 0x17c8,
+	0x17d7, 0x17d7,
+	0x17dc, 0x17dc,
+	0x1820, 0x1877,
+	0x1880, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191e,
+	0x1920, 0x192b,
+	0x1930, 0x1938,
+	0x1950, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x1a00, 0x1a1b,
+	0x1a20, 0x1a5e,
+	0x1a61, 0x1a74,
+	0x1aa7, 0x1aa7,
+	0x1b00, 0x1b33,
+	0x1b35, 0x1b43,
+	0x1b45, 0x1b4b,
+	0x1b80, 0x1ba9,
+	0x1bac, 0x1baf,
+	0x1bba, 0x1be5,
+	0x1be7, 0x1bf1,
+	0x1c00, 0x1c35,
+	0x1c4d, 0x1c4f,
+	0x1c5a, 0x1c7d,
+	0x1c80, 0x1c88,
+	0x1ce9, 0x1cec,
+	0x1cee, 0x1cf3,
+	0x1cf5, 0x1cf6,
+	0x1d00, 0x1dbf,
+	0x1de7, 0x1df4,
+	0x1e00, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fbc,
+	0x1fbe, 0x1fbe,
+	0x1fc2, 0x1fc4,
+	0x1fc6, 0x1fcc,
+	0x1fd0, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fe0, 0x1fec,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffc,
+	0x2071, 0x2071,
+	0x207f, 0x207f,
+	0x2090, 0x209c,
+	0x2102, 0x2102,
+	0x2107, 0x2107,
+	0x210a, 0x2113,
+	0x2115, 0x2115,
+	0x2119, 0x211d,
+	0x2124, 0x2124,
+	0x2126, 0x2126,
+	0x2128, 0x2128,
+	0x212a, 0x212d,
+	0x212f, 0x2139,
+	0x213c, 0x213f,
+	0x2145, 0x2149,
+	0x214e, 0x214e,
+	0x2160, 0x2188,
+	0x24b6, 0x24e9,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2ce4,
+	0x2ceb, 0x2cee,
+	0x2cf2, 0x2cf3,
+	0x2d00, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d6f,
+	0x2d80, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2de0, 0x2dff,
+	0x2e2f, 0x2e2f,
+	0x3005, 0x3007,
+	0x3021, 0x3029,
+	0x3031, 0x3035,
+	0x3038, 0x303c,
+	0x3041, 0x3096,
+	0x309d, 0x309f,
+	0x30a1, 0x30fa,
+	0x30fc, 0x30ff,
+	0x3105, 0x312e,
+	0x3131, 0x318e,
+	0x31a0, 0x31ba,
+	0x31f0, 0x31ff,
+	0x3400, 0x4db5,
+	0x4e00, 0x9fea,
+	0xa000, 0xa48c,
+	0xa4d0, 0xa4fd,
+	0xa500, 0xa60c,
+	0xa610, 0xa61f,
+	0xa62a, 0xa62b,
+	0xa640, 0xa66e,
+	0xa674, 0xa67b,
+	0xa67f, 0xa6ef,
+	0xa717, 0xa71f,
+	0xa722, 0xa788,
+	0xa78b, 0xa7ae,
+	0xa7b0, 0xa7b7,
+	0xa7f7, 0xa801,
+	0xa803, 0xa805,
+	0xa807, 0xa80a,
+	0xa80c, 0xa827,
+	0xa840, 0xa873,
+	0xa880, 0xa8c3,
+	0xa8c5, 0xa8c5,
+	0xa8f2, 0xa8f7,
+	0xa8fb, 0xa8fb,
+	0xa8fd, 0xa8fd,
+	0xa90a, 0xa92a,
+	0xa930, 0xa952,
+	0xa960, 0xa97c,
+	0xa980, 0xa9b2,
+	0xa9b4, 0xa9bf,
+	0xa9cf, 0xa9cf,
+	0xa9e0, 0xa9e4,
+	0xa9e6, 0xa9ef,
+	0xa9fa, 0xa9fe,
+	0xaa00, 0xaa36,
+	0xaa40, 0xaa4d,
+	0xaa60, 0xaa76,
+	0xaa7a, 0xaa7a,
+	0xaa7e, 0xaabe,
+	0xaac0, 0xaac0,
+	0xaac2, 0xaac2,
+	0xaadb, 0xaadd,
+	0xaae0, 0xaaef,
+	0xaaf2, 0xaaf5,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xab30, 0xab5a,
+	0xab5c, 0xab65,
+	0xab70, 0xabea,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xf900, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb28,
+	0xfb2a, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbb1,
+	0xfbd3, 0xfd3d,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdf0, 0xfdfb,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xff21, 0xff3a,
+	0xff41, 0xff5a,
+	0xff66, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0x10000, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10140, 0x10174,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x10300, 0x1031f,
+	0x1032d, 0x1034a,
+	0x10350, 0x1037a,
+	0x10380, 0x1039d,
+	0x103a0, 0x103c3,
+	0x103c8, 0x103cf,
+	0x103d1, 0x103d5,
+	0x10400, 0x1049d,
+	0x104b0, 0x104d3,
+	0x104d8, 0x104fb,
+	0x10500, 0x10527,
+	0x10530, 0x10563,
+	0x10600, 0x10736,
+	0x10740, 0x10755,
+	0x10760, 0x10767,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10860, 0x10876,
+	0x10880, 0x1089e,
+	0x108e0, 0x108f2,
+	0x108f4, 0x108f5,
+	0x10900, 0x10915,
+	0x10920, 0x10939,
+	0x10980, 0x109b7,
+	0x109be, 0x109bf,
+	0x10a00, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a60, 0x10a7c,
+	0x10a80, 0x10a9c,
+	0x10ac0, 0x10ac7,
+	0x10ac9, 0x10ae4,
+	0x10b00, 0x10b35,
+	0x10b40, 0x10b55,
+	0x10b60, 0x10b72,
+	0x10b80, 0x10b91,
+	0x10c00, 0x10c48,
+	0x10c80, 0x10cb2,
+	0x10cc0, 0x10cf2,
+	0x11000, 0x11045,
+	0x11082, 0x110b8,
+	0x110d0, 0x110e8,
+	0x11100, 0x11132,
+	0x11150, 0x11172,
+	0x11176, 0x11176,
+	0x11180, 0x111bf,
+	0x111c1, 0x111c4,
+	0x111da, 0x111da,
+	0x111dc, 0x111dc,
+	0x11200, 0x11211,
+	0x11213, 0x11234,
+	0x11237, 0x11237,
+	0x1123e, 0x1123e,
+	0x11280, 0x11286,
+	0x11288, 0x11288,
+	0x1128a, 0x1128d,
+	0x1128f, 0x1129d,
+	0x1129f, 0x112a8,
+	0x112b0, 0x112e8,
+	0x11300, 0x11303,
+	0x11305, 0x1130c,
+	0x1130f, 0x11310,
+	0x11313, 0x11328,
+	0x1132a, 0x11330,
+	0x11332, 0x11333,
+	0x11335, 0x11339,
+	0x1133d, 0x11344,
+	0x11347, 0x11348,
+	0x1134b, 0x1134c,
+	0x11350, 0x11350,
+	0x11357, 0x11357,
+	0x1135d, 0x11363,
+	0x11400, 0x11441,
+	0x11443, 0x11445,
+	0x11447, 0x1144a,
+	0x11480, 0x114c1,
+	0x114c4, 0x114c5,
+	0x114c7, 0x114c7,
+	0x11580, 0x115b5,
+	0x115b8, 0x115be,
+	0x115d8, 0x115dd,
+	0x11600, 0x1163e,
+	0x11640, 0x11640,
+	0x11644, 0x11644,
+	0x11680, 0x116b5,
+	0x11700, 0x11719,
+	0x1171d, 0x1172a,
+	0x118a0, 0x118df,
+	0x118ff, 0x118ff,
+	0x11a00, 0x11a32,
+	0x11a35, 0x11a3e,
+	0x11a50, 0x11a83,
+	0x11a86, 0x11a97,
+	0x11ac0, 0x11af8,
+	0x11c00, 0x11c08,
+	0x11c0a, 0x11c36,
+	0x11c38, 0x11c3e,
+	0x11c40, 0x11c40,
+	0x11c72, 0x11c8f,
+	0x11c92, 0x11ca7,
+	0x11ca9, 0x11cb6,
+	0x11d00, 0x11d06,
+	0x11d08, 0x11d09,
+	0x11d0b, 0x11d36,
+	0x11d3a, 0x11d3a,
+	0x11d3c, 0x11d3d,
+	0x11d3f, 0x11d41,
+	0x11d43, 0x11d43,
+	0x11d46, 0x11d47,
+	0x12000, 0x12399,
+	0x12400, 0x1246e,
+	0x12480, 0x12543,
+	0x13000, 0x1342e,
+	0x14400, 0x14646,
+	0x16800, 0x16a38,
+	0x16a40, 0x16a5e,
+	0x16ad0, 0x16aed,
+	0x16b00, 0x16b36,
+	0x16b40, 0x16b43,
+	0x16b63, 0x16b77,
+	0x16b7d, 0x16b8f,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f7e,
+	0x16f93, 0x16f9f,
+	0x16fe0, 0x16fe1,
+	0x17000, 0x187ec,
+	0x18800, 0x18af2,
+	0x1b000, 0x1b11e,
+	0x1b170, 0x1b2fb,
+	0x1bc00, 0x1bc6a,
+	0x1bc70, 0x1bc7c,
+	0x1bc80, 0x1bc88,
+	0x1bc90, 0x1bc99,
+	0x1bc9e, 0x1bc9e,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d6c0,
+	0x1d6c2, 0x1d6da,
+	0x1d6dc, 0x1d6fa,
+	0x1d6fc, 0x1d714,
+	0x1d716, 0x1d734,
+	0x1d736, 0x1d74e,
+	0x1d750, 0x1d76e,
+	0x1d770, 0x1d788,
+	0x1d78a, 0x1d7a8,
+	0x1d7aa, 0x1d7c2,
+	0x1d7c4, 0x1d7cb,
+	0x1e000, 0x1e006,
+	0x1e008, 0x1e018,
+	0x1e01b, 0x1e021,
+	0x1e023, 0x1e024,
+	0x1e026, 0x1e02a,
+	0x1e800, 0x1e8c4,
+	0x1e900, 0x1e943,
+	0x1e947, 0x1e947,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x1f130, 0x1f149,
+	0x1f150, 0x1f169,
+	0x1f170, 0x1f189,
+	0x20000, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2b820, 0x2cea1,
+	0x2ceb0, 0x2ebe0,
+	0x2f800, 0x2fa1d,
+}; /* CR_Alpha */
+
+/* 'Blank': [[:Blank:]] */
+static const OnigCodePoint CR_Blank[] = {
+	8,
+	0x0009, 0x0009,
+	0x0020, 0x0020,
+	0x00a0, 0x00a0,
+	0x1680, 0x1680,
+	0x2000, 0x200a,
+	0x202f, 0x202f,
+	0x205f, 0x205f,
+	0x3000, 0x3000,
+}; /* CR_Blank */
+
+/* 'Cntrl': [[:Cntrl:]] */
+static const OnigCodePoint CR_Cntrl[] = {
+	2,
+	0x0000, 0x001f,
+	0x007f, 0x009f,
+}; /* CR_Cntrl */
+
+/* 'Digit': [[:Digit:]] */
+static const OnigCodePoint CR_Digit[] = {
+	55,
+	0x0030, 0x0039,
+	0x0660, 0x0669,
+	0x06f0, 0x06f9,
+	0x07c0, 0x07c9,
+	0x0966, 0x096f,
+	0x09e6, 0x09ef,
+	0x0a66, 0x0a6f,
+	0x0ae6, 0x0aef,
+	0x0b66, 0x0b6f,
+	0x0be6, 0x0bef,
+	0x0c66, 0x0c6f,
+	0x0ce6, 0x0cef,
+	0x0d66, 0x0d6f,
+	0x0de6, 0x0def,
+	0x0e50, 0x0e59,
+	0x0ed0, 0x0ed9,
+	0x0f20, 0x0f29,
+	0x1040, 0x1049,
+	0x1090, 0x1099,
+	0x17e0, 0x17e9,
+	0x1810, 0x1819,
+	0x1946, 0x194f,
+	0x19d0, 0x19d9,
+	0x1a80, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1b50, 0x1b59,
+	0x1bb0, 0x1bb9,
+	0x1c40, 0x1c49,
+	0x1c50, 0x1c59,
+	0xa620, 0xa629,
+	0xa8d0, 0xa8d9,
+	0xa900, 0xa909,
+	0xa9d0, 0xa9d9,
+	0xa9f0, 0xa9f9,
+	0xaa50, 0xaa59,
+	0xabf0, 0xabf9,
+	0xff10, 0xff19,
+	0x104a0, 0x104a9,
+	0x11066, 0x1106f,
+	0x110f0, 0x110f9,
+	0x11136, 0x1113f,
+	0x111d0, 0x111d9,
+	0x112f0, 0x112f9,
+	0x11450, 0x11459,
+	0x114d0, 0x114d9,
+	0x11650, 0x11659,
+	0x116c0, 0x116c9,
+	0x11730, 0x11739,
+	0x118e0, 0x118e9,
+	0x11c50, 0x11c59,
+	0x11d50, 0x11d59,
+	0x16a60, 0x16a69,
+	0x16b50, 0x16b59,
+	0x1d7ce, 0x1d7ff,
+	0x1e950, 0x1e959,
+}; /* CR_Digit */
+
+/* 'Graph': [[:Graph:]] */
+static const OnigCodePoint CR_Graph[] = {
+	654,
+	0x0021, 0x007e,
+	0x00a1, 0x0377,
+	0x037a, 0x037f,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x052f,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x058a,
+	0x058d, 0x058f,
+	0x0591, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x0600, 0x061c,
+	0x061e, 0x070d,
+	0x070f, 0x074a,
+	0x074d, 0x07b1,
+	0x07c0, 0x07fa,
+	0x0800, 0x082d,
+	0x0830, 0x083e,
+	0x0840, 0x085b,
+	0x085e, 0x085e,
+	0x0860, 0x086a,
+	0x08a0, 0x08b4,
+	0x08b6, 0x08bd,
+	0x08d4, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fd,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a75,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0af1,
+	0x0af9, 0x0aff,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3c, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b63,
+	0x0b66, 0x0b77,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd0, 0x0bd0,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bfa,
+	0x0c00, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c39,
+	0x0c3d, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c58, 0x0c5a,
+	0x0c60, 0x0c63,
+	0x0c66, 0x0c6f,
+	0x0c78, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbc, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce3,
+	0x0ce6, 0x0cef,
+	0x0cf1, 0x0cf2,
+	0x0d00, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4f,
+	0x0d54, 0x0d63,
+	0x0d66, 0x0d7f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0de6, 0x0def,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f71, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fbe, 0x0fcc,
+	0x0fce, 0x0fda,
+	0x1000, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135d, 0x137c,
+	0x1380, 0x1399,
+	0x13a0, 0x13f5,
+	0x13f8, 0x13fd,
+	0x1400, 0x167f,
+	0x1681, 0x169c,
+	0x16a0, 0x16f8,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+	0x1720, 0x1736,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17dd,
+	0x17e0, 0x17e9,
+	0x17f0, 0x17f9,
+	0x1800, 0x180e,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191e,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1940, 0x1940,
+	0x1944, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19da,
+	0x19de, 0x1a1b,
+	0x1a1e, 0x1a5e,
+	0x1a60, 0x1a7c,
+	0x1a7f, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1aa0, 0x1aad,
+	0x1ab0, 0x1abe,
+	0x1b00, 0x1b4b,
+	0x1b50, 0x1b7c,
+	0x1b80, 0x1bf3,
+	0x1bfc, 0x1c37,
+	0x1c3b, 0x1c49,
+	0x1c4d, 0x1c88,
+	0x1cc0, 0x1cc7,
+	0x1cd0, 0x1cf9,
+	0x1d00, 0x1df9,
+	0x1dfb, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x200b, 0x2027,
+	0x202a, 0x202e,
+	0x2030, 0x205e,
+	0x2060, 0x2064,
+	0x2066, 0x2071,
+	0x2074, 0x208e,
+	0x2090, 0x209c,
+	0x20a0, 0x20bf,
+	0x20d0, 0x20f0,
+	0x2100, 0x218b,
+	0x2190, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x2b73,
+	0x2b76, 0x2b95,
+	0x2b98, 0x2bb9,
+	0x2bbd, 0x2bc8,
+	0x2bca, 0x2bd2,
+	0x2bec, 0x2bef,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2cf3,
+	0x2cf9, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d70,
+	0x2d7f, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2de0, 0x2e49,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3001, 0x303f,
+	0x3041, 0x3096,
+	0x3099, 0x30ff,
+	0x3105, 0x312e,
+	0x3131, 0x318e,
+	0x3190, 0x31ba,
+	0x31c0, 0x31e3,
+	0x31f0, 0x321e,
+	0x3220, 0x32fe,
+	0x3300, 0x4db5,
+	0x4dc0, 0x9fea,
+	0xa000, 0xa48c,
+	0xa490, 0xa4c6,
+	0xa4d0, 0xa62b,
+	0xa640, 0xa6f7,
+	0xa700, 0xa7ae,
+	0xa7b0, 0xa7b7,
+	0xa7f7, 0xa82b,
+	0xa830, 0xa839,
+	0xa840, 0xa877,
+	0xa880, 0xa8c5,
+	0xa8ce, 0xa8d9,
+	0xa8e0, 0xa8fd,
+	0xa900, 0xa953,
+	0xa95f, 0xa97c,
+	0xa980, 0xa9cd,
+	0xa9cf, 0xa9d9,
+	0xa9de, 0xa9fe,
+	0xaa00, 0xaa36,
+	0xaa40, 0xaa4d,
+	0xaa50, 0xaa59,
+	0xaa5c, 0xaac2,
+	0xaadb, 0xaaf6,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xab30, 0xab65,
+	0xab70, 0xabed,
+	0xabf0, 0xabf9,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xe000, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbc1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdf0, 0xfdfd,
+	0xfe00, 0xfe19,
+	0xfe20, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfff9, 0xfffd,
+	0x10000, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10100, 0x10102,
+	0x10107, 0x10133,
+	0x10137, 0x1018e,
+	0x10190, 0x1019b,
+	0x101a0, 0x101a0,
+	0x101d0, 0x101fd,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x102e0, 0x102fb,
+	0x10300, 0x10323,
+	0x1032d, 0x1034a,
+	0x10350, 0x1037a,
+	0x10380, 0x1039d,
+	0x1039f, 0x103c3,
+	0x103c8, 0x103d5,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x104b0, 0x104d3,
+	0x104d8, 0x104fb,
+	0x10500, 0x10527,
+	0x10530, 0x10563,
+	0x1056f, 0x1056f,
+	0x10600, 0x10736,
+	0x10740, 0x10755,
+	0x10760, 0x10767,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10857, 0x1089e,
+	0x108a7, 0x108af,
+	0x108e0, 0x108f2,
+	0x108f4, 0x108f5,
+	0x108fb, 0x1091b,
+	0x1091f, 0x10939,
+	0x1093f, 0x1093f,
+	0x10980, 0x109b7,
+	0x109bc, 0x109cf,
+	0x109d2, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a47,
+	0x10a50, 0x10a58,
+	0x10a60, 0x10a9f,
+	0x10ac0, 0x10ae6,
+	0x10aeb, 0x10af6,
+	0x10b00, 0x10b35,
+	0x10b39, 0x10b55,
+	0x10b58, 0x10b72,
+	0x10b78, 0x10b91,
+	0x10b99, 0x10b9c,
+	0x10ba9, 0x10baf,
+	0x10c00, 0x10c48,
+	0x10c80, 0x10cb2,
+	0x10cc0, 0x10cf2,
+	0x10cfa, 0x10cff,
+	0x10e60, 0x10e7e,
+	0x11000, 0x1104d,
+	0x11052, 0x1106f,
+	0x1107f, 0x110c1,
+	0x110d0, 0x110e8,
+	0x110f0, 0x110f9,
+	0x11100, 0x11134,
+	0x11136, 0x11143,
+	0x11150, 0x11176,
+	0x11180, 0x111cd,
+	0x111d0, 0x111df,
+	0x111e1, 0x111f4,
+	0x11200, 0x11211,
+	0x11213, 0x1123e,
+	0x11280, 0x11286,
+	0x11288, 0x11288,
+	0x1128a, 0x1128d,
+	0x1128f, 0x1129d,
+	0x1129f, 0x112a9,
+	0x112b0, 0x112ea,
+	0x112f0, 0x112f9,
+	0x11300, 0x11303,
+	0x11305, 0x1130c,
+	0x1130f, 0x11310,
+	0x11313, 0x11328,
+	0x1132a, 0x11330,
+	0x11332, 0x11333,
+	0x11335, 0x11339,
+	0x1133c, 0x11344,
+	0x11347, 0x11348,
+	0x1134b, 0x1134d,
+	0x11350, 0x11350,
+	0x11357, 0x11357,
+	0x1135d, 0x11363,
+	0x11366, 0x1136c,
+	0x11370, 0x11374,
+	0x11400, 0x11459,
+	0x1145b, 0x1145b,
+	0x1145d, 0x1145d,
+	0x11480, 0x114c7,
+	0x114d0, 0x114d9,
+	0x11580, 0x115b5,
+	0x115b8, 0x115dd,
+	0x11600, 0x11644,
+	0x11650, 0x11659,
+	0x11660, 0x1166c,
+	0x11680, 0x116b7,
+	0x116c0, 0x116c9,
+	0x11700, 0x11719,
+	0x1171d, 0x1172b,
+	0x11730, 0x1173f,
+	0x118a0, 0x118f2,
+	0x118ff, 0x118ff,
+	0x11a00, 0x11a47,
+	0x11a50, 0x11a83,
+	0x11a86, 0x11a9c,
+	0x11a9e, 0x11aa2,
+	0x11ac0, 0x11af8,
+	0x11c00, 0x11c08,
+	0x11c0a, 0x11c36,
+	0x11c38, 0x11c45,
+	0x11c50, 0x11c6c,
+	0x11c70, 0x11c8f,
+	0x11c92, 0x11ca7,
+	0x11ca9, 0x11cb6,
+	0x11d00, 0x11d06,
+	0x11d08, 0x11d09,
+	0x11d0b, 0x11d36,
+	0x11d3a, 0x11d3a,
+	0x11d3c, 0x11d3d,
+	0x11d3f, 0x11d47,
+	0x11d50, 0x11d59,
+	0x12000, 0x12399,
+	0x12400, 0x1246e,
+	0x12470, 0x12474,
+	0x12480, 0x12543,
+	0x13000, 0x1342e,
+	0x14400, 0x14646,
+	0x16800, 0x16a38,
+	0x16a40, 0x16a5e,
+	0x16a60, 0x16a69,
+	0x16a6e, 0x16a6f,
+	0x16ad0, 0x16aed,
+	0x16af0, 0x16af5,
+	0x16b00, 0x16b45,
+	0x16b50, 0x16b59,
+	0x16b5b, 0x16b61,
+	0x16b63, 0x16b77,
+	0x16b7d, 0x16b8f,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f7e,
+	0x16f8f, 0x16f9f,
+	0x16fe0, 0x16fe1,
+	0x17000, 0x187ec,
+	0x18800, 0x18af2,
+	0x1b000, 0x1b11e,
+	0x1b170, 0x1b2fb,
+	0x1bc00, 0x1bc6a,
+	0x1bc70, 0x1bc7c,
+	0x1bc80, 0x1bc88,
+	0x1bc90, 0x1bc99,
+	0x1bc9c, 0x1bca3,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d129, 0x1d1e8,
+	0x1d200, 0x1d245,
+	0x1d300, 0x1d356,
+	0x1d360, 0x1d371,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d7cb,
+	0x1d7ce, 0x1da8b,
+	0x1da9b, 0x1da9f,
+	0x1daa1, 0x1daaf,
+	0x1e000, 0x1e006,
+	0x1e008, 0x1e018,
+	0x1e01b, 0x1e021,
+	0x1e023, 0x1e024,
+	0x1e026, 0x1e02a,
+	0x1e800, 0x1e8c4,
+	0x1e8c7, 0x1e8d6,
+	0x1e900, 0x1e94a,
+	0x1e950, 0x1e959,
+	0x1e95e, 0x1e95f,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x1eef0, 0x1eef1,
+	0x1f000, 0x1f02b,
+	0x1f030, 0x1f093,
+	0x1f0a0, 0x1f0ae,
+	0x1f0b1, 0x1f0bf,
+	0x1f0c1, 0x1f0cf,
+	0x1f0d1, 0x1f0f5,
+	0x1f100, 0x1f10c,
+	0x1f110, 0x1f12e,
+	0x1f130, 0x1f16b,
+	0x1f170, 0x1f1ac,
+	0x1f1e6, 0x1f202,
+	0x1f210, 0x1f23b,
+	0x1f240, 0x1f248,
+	0x1f250, 0x1f251,
+	0x1f260, 0x1f265,
+	0x1f300, 0x1f6d4,
+	0x1f6e0, 0x1f6ec,
+	0x1f6f0, 0x1f6f8,
+	0x1f700, 0x1f773,
+	0x1f780, 0x1f7d4,
+	0x1f800, 0x1f80b,
+	0x1f810, 0x1f847,
+	0x1f850, 0x1f859,
+	0x1f860, 0x1f887,
+	0x1f890, 0x1f8ad,
+	0x1f900, 0x1f90b,
+	0x1f910, 0x1f93e,
+	0x1f940, 0x1f94c,
+	0x1f950, 0x1f96b,
+	0x1f980, 0x1f997,
+	0x1f9c0, 0x1f9c0,
+	0x1f9d0, 0x1f9e6,
+	0x20000, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2b820, 0x2cea1,
+	0x2ceb0, 0x2ebe0,
+	0x2f800, 0x2fa1d,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+	0xe0100, 0xe01ef,
+	0xf0000, 0xffffd,
+	0x100000, 0x10fffd,
+}; /* CR_Graph */
+
+/* 'Lower': [[:Lower:]] */
+static const OnigCodePoint CR_Lower[] = {
+	640,
+	0x0061, 0x007a,
+	0x00aa, 0x00aa,
+	0x00b5, 0x00b5,
+	0x00ba, 0x00ba,
+	0x00df, 0x00f6,
+	0x00f8, 0x00ff,
+	0x0101, 0x0101,
+	0x0103, 0x0103,
+	0x0105, 0x0105,
+	0x0107, 0x0107,
+	0x0109, 0x0109,
+	0x010b, 0x010b,
+	0x010d, 0x010d,
+	0x010f, 0x010f,
+	0x0111, 0x0111,
+	0x0113, 0x0113,
+	0x0115, 0x0115,
+	0x0117, 0x0117,
+	0x0119, 0x0119,
+	0x011b, 0x011b,
+	0x011d, 0x011d,
+	0x011f, 0x011f,
+	0x0121, 0x0121,
+	0x0123, 0x0123,
+	0x0125, 0x0125,
+	0x0127, 0x0127,
+	0x0129, 0x0129,
+	0x012b, 0x012b,
+	0x012d, 0x012d,
+	0x012f, 0x012f,
+	0x0131, 0x0131,
+	0x0133, 0x0133,
+	0x0135, 0x0135,
+	0x0137, 0x0138,
+	0x013a, 0x013a,
+	0x013c, 0x013c,
+	0x013e, 0x013e,
+	0x0140, 0x0140,
+	0x0142, 0x0142,
+	0x0144, 0x0144,
+	0x0146, 0x0146,
+	0x0148, 0x0149,
+	0x014b, 0x014b,
+	0x014d, 0x014d,
+	0x014f, 0x014f,
+	0x0151, 0x0151,
+	0x0153, 0x0153,
+	0x0155, 0x0155,
+	0x0157, 0x0157,
+	0x0159, 0x0159,
+	0x015b, 0x015b,
+	0x015d, 0x015d,
+	0x015f, 0x015f,
+	0x0161, 0x0161,
+	0x0163, 0x0163,
+	0x0165, 0x0165,
+	0x0167, 0x0167,
+	0x0169, 0x0169,
+	0x016b, 0x016b,
+	0x016d, 0x016d,
+	0x016f, 0x016f,
+	0x0171, 0x0171,
+	0x0173, 0x0173,
+	0x0175, 0x0175,
+	0x0177, 0x0177,
+	0x017a, 0x017a,
+	0x017c, 0x017c,
+	0x017e, 0x0180,
+	0x0183, 0x0183,
+	0x0185, 0x0185,
+	0x0188, 0x0188,
+	0x018c, 0x018d,
+	0x0192, 0x0192,
+	0x0195, 0x0195,
+	0x0199, 0x019b,
+	0x019e, 0x019e,
+	0x01a1, 0x01a1,
+	0x01a3, 0x01a3,
+	0x01a5, 0x01a5,
+	0x01a8, 0x01a8,
+	0x01aa, 0x01ab,
+	0x01ad, 0x01ad,
+	0x01b0, 0x01b0,
+	0x01b4, 0x01b4,
+	0x01b6, 0x01b6,
+	0x01b9, 0x01ba,
+	0x01bd, 0x01bf,
+	0x01c6, 0x01c6,
+	0x01c9, 0x01c9,
+	0x01cc, 0x01cc,
+	0x01ce, 0x01ce,
+	0x01d0, 0x01d0,
+	0x01d2, 0x01d2,
+	0x01d4, 0x01d4,
+	0x01d6, 0x01d6,
+	0x01d8, 0x01d8,
+	0x01da, 0x01da,
+	0x01dc, 0x01dd,
+	0x01df, 0x01df,
+	0x01e1, 0x01e1,
+	0x01e3, 0x01e3,
+	0x01e5, 0x01e5,
+	0x01e7, 0x01e7,
+	0x01e9, 0x01e9,
+	0x01eb, 0x01eb,
+	0x01ed, 0x01ed,
+	0x01ef, 0x01f0,
+	0x01f3, 0x01f3,
+	0x01f5, 0x01f5,
+	0x01f9, 0x01f9,
+	0x01fb, 0x01fb,
+	0x01fd, 0x01fd,
+	0x01ff, 0x01ff,
+	0x0201, 0x0201,
+	0x0203, 0x0203,
+	0x0205, 0x0205,
+	0x0207, 0x0207,
+	0x0209, 0x0209,
+	0x020b, 0x020b,
+	0x020d, 0x020d,
+	0x020f, 0x020f,
+	0x0211, 0x0211,
+	0x0213, 0x0213,
+	0x0215, 0x0215,
+	0x0217, 0x0217,
+	0x0219, 0x0219,
+	0x021b, 0x021b,
+	0x021d, 0x021d,
+	0x021f, 0x021f,
+	0x0221, 0x0221,
+	0x0223, 0x0223,
+	0x0225, 0x0225,
+	0x0227, 0x0227,
+	0x0229, 0x0229,
+	0x022b, 0x022b,
+	0x022d, 0x022d,
+	0x022f, 0x022f,
+	0x0231, 0x0231,
+	0x0233, 0x0239,
+	0x023c, 0x023c,
+	0x023f, 0x0240,
+	0x0242, 0x0242,
+	0x0247, 0x0247,
+	0x0249, 0x0249,
+	0x024b, 0x024b,
+	0x024d, 0x024d,
+	0x024f, 0x0293,
+	0x0295, 0x02b8,
+	0x02c0, 0x02c1,
+	0x02e0, 0x02e4,
+	0x0345, 0x0345,
+	0x0371, 0x0371,
+	0x0373, 0x0373,
+	0x0377, 0x0377,
+	0x037a, 0x037d,
+	0x0390, 0x0390,
+	0x03ac, 0x03ce,
+	0x03d0, 0x03d1,
+	0x03d5, 0x03d7,
+	0x03d9, 0x03d9,
+	0x03db, 0x03db,
+	0x03dd, 0x03dd,
+	0x03df, 0x03df,
+	0x03e1, 0x03e1,
+	0x03e3, 0x03e3,
+	0x03e5, 0x03e5,
+	0x03e7, 0x03e7,
+	0x03e9, 0x03e9,
+	0x03eb, 0x03eb,
+	0x03ed, 0x03ed,
+	0x03ef, 0x03f3,
+	0x03f5, 0x03f5,
+	0x03f8, 0x03f8,
+	0x03fb, 0x03fc,
+	0x0430, 0x045f,
+	0x0461, 0x0461,
+	0x0463, 0x0463,
+	0x0465, 0x0465,
+	0x0467, 0x0467,
+	0x0469, 0x0469,
+	0x046b, 0x046b,
+	0x046d, 0x046d,
+	0x046f, 0x046f,
+	0x0471, 0x0471,
+	0x0473, 0x0473,
+	0x0475, 0x0475,
+	0x0477, 0x0477,
+	0x0479, 0x0479,
+	0x047b, 0x047b,
+	0x047d, 0x047d,
+	0x047f, 0x047f,
+	0x0481, 0x0481,
+	0x048b, 0x048b,
+	0x048d, 0x048d,
+	0x048f, 0x048f,
+	0x0491, 0x0491,
+	0x0493, 0x0493,
+	0x0495, 0x0495,
+	0x0497, 0x0497,
+	0x0499, 0x0499,
+	0x049b, 0x049b,
+	0x049d, 0x049d,
+	0x049f, 0x049f,
+	0x04a1, 0x04a1,
+	0x04a3, 0x04a3,
+	0x04a5, 0x04a5,
+	0x04a7, 0x04a7,
+	0x04a9, 0x04a9,
+	0x04ab, 0x04ab,
+	0x04ad, 0x04ad,
+	0x04af, 0x04af,
+	0x04b1, 0x04b1,
+	0x04b3, 0x04b3,
+	0x04b5, 0x04b5,
+	0x04b7, 0x04b7,
+	0x04b9, 0x04b9,
+	0x04bb, 0x04bb,
+	0x04bd, 0x04bd,
+	0x04bf, 0x04bf,
+	0x04c2, 0x04c2,
+	0x04c4, 0x04c4,
+	0x04c6, 0x04c6,
+	0x04c8, 0x04c8,
+	0x04ca, 0x04ca,
+	0x04cc, 0x04cc,
+	0x04ce, 0x04cf,
+	0x04d1, 0x04d1,
+	0x04d3, 0x04d3,
+	0x04d5, 0x04d5,
+	0x04d7, 0x04d7,
+	0x04d9, 0x04d9,
+	0x04db, 0x04db,
+	0x04dd, 0x04dd,
+	0x04df, 0x04df,
+	0x04e1, 0x04e1,
+	0x04e3, 0x04e3,
+	0x04e5, 0x04e5,
+	0x04e7, 0x04e7,
+	0x04e9, 0x04e9,
+	0x04eb, 0x04eb,
+	0x04ed, 0x04ed,
+	0x04ef, 0x04ef,
+	0x04f1, 0x04f1,
+	0x04f3, 0x04f3,
+	0x04f5, 0x04f5,
+	0x04f7, 0x04f7,
+	0x04f9, 0x04f9,
+	0x04fb, 0x04fb,
+	0x04fd, 0x04fd,
+	0x04ff, 0x04ff,
+	0x0501, 0x0501,
+	0x0503, 0x0503,
+	0x0505, 0x0505,
+	0x0507, 0x0507,
+	0x0509, 0x0509,
+	0x050b, 0x050b,
+	0x050d, 0x050d,
+	0x050f, 0x050f,
+	0x0511, 0x0511,
+	0x0513, 0x0513,
+	0x0515, 0x0515,
+	0x0517, 0x0517,
+	0x0519, 0x0519,
+	0x051b, 0x051b,
+	0x051d, 0x051d,
+	0x051f, 0x051f,
+	0x0521, 0x0521,
+	0x0523, 0x0523,
+	0x0525, 0x0525,
+	0x0527, 0x0527,
+	0x0529, 0x0529,
+	0x052b, 0x052b,
+	0x052d, 0x052d,
+	0x052f, 0x052f,
+	0x0561, 0x0587,
+	0x13f8, 0x13fd,
+	0x1c80, 0x1c88,
+	0x1d00, 0x1dbf,
+	0x1e01, 0x1e01,
+	0x1e03, 0x1e03,
+	0x1e05, 0x1e05,
+	0x1e07, 0x1e07,
+	0x1e09, 0x1e09,
+	0x1e0b, 0x1e0b,
+	0x1e0d, 0x1e0d,
+	0x1e0f, 0x1e0f,
+	0x1e11, 0x1e11,
+	0x1e13, 0x1e13,
+	0x1e15, 0x1e15,
+	0x1e17, 0x1e17,
+	0x1e19, 0x1e19,
+	0x1e1b, 0x1e1b,
+	0x1e1d, 0x1e1d,
+	0x1e1f, 0x1e1f,
+	0x1e21, 0x1e21,
+	0x1e23, 0x1e23,
+	0x1e25, 0x1e25,
+	0x1e27, 0x1e27,
+	0x1e29, 0x1e29,
+	0x1e2b, 0x1e2b,
+	0x1e2d, 0x1e2d,
+	0x1e2f, 0x1e2f,
+	0x1e31, 0x1e31,
+	0x1e33, 0x1e33,
+	0x1e35, 0x1e35,
+	0x1e37, 0x1e37,
+	0x1e39, 0x1e39,
+	0x1e3b, 0x1e3b,
+	0x1e3d, 0x1e3d,
+	0x1e3f, 0x1e3f,
+	0x1e41, 0x1e41,
+	0x1e43, 0x1e43,
+	0x1e45, 0x1e45,
+	0x1e47, 0x1e47,
+	0x1e49, 0x1e49,
+	0x1e4b, 0x1e4b,
+	0x1e4d, 0x1e4d,
+	0x1e4f, 0x1e4f,
+	0x1e51, 0x1e51,
+	0x1e53, 0x1e53,
+	0x1e55, 0x1e55,
+	0x1e57, 0x1e57,
+	0x1e59, 0x1e59,
+	0x1e5b, 0x1e5b,
+	0x1e5d, 0x1e5d,
+	0x1e5f, 0x1e5f,
+	0x1e61, 0x1e61,
+	0x1e63, 0x1e63,
+	0x1e65, 0x1e65,
+	0x1e67, 0x1e67,
+	0x1e69, 0x1e69,
+	0x1e6b, 0x1e6b,
+	0x1e6d, 0x1e6d,
+	0x1e6f, 0x1e6f,
+	0x1e71, 0x1e71,
+	0x1e73, 0x1e73,
+	0x1e75, 0x1e75,
+	0x1e77, 0x1e77,
+	0x1e79, 0x1e79,
+	0x1e7b, 0x1e7b,
+	0x1e7d, 0x1e7d,
+	0x1e7f, 0x1e7f,
+	0x1e81, 0x1e81,
+	0x1e83, 0x1e83,
+	0x1e85, 0x1e85,
+	0x1e87, 0x1e87,
+	0x1e89, 0x1e89,
+	0x1e8b, 0x1e8b,
+	0x1e8d, 0x1e8d,
+	0x1e8f, 0x1e8f,
+	0x1e91, 0x1e91,
+	0x1e93, 0x1e93,
+	0x1e95, 0x1e9d,
+	0x1e9f, 0x1e9f,
+	0x1ea1, 0x1ea1,
+	0x1ea3, 0x1ea3,
+	0x1ea5, 0x1ea5,
+	0x1ea7, 0x1ea7,
+	0x1ea9, 0x1ea9,
+	0x1eab, 0x1eab,
+	0x1ead, 0x1ead,
+	0x1eaf, 0x1eaf,
+	0x1eb1, 0x1eb1,
+	0x1eb3, 0x1eb3,
+	0x1eb5, 0x1eb5,
+	0x1eb7, 0x1eb7,
+	0x1eb9, 0x1eb9,
+	0x1ebb, 0x1ebb,
+	0x1ebd, 0x1ebd,
+	0x1ebf, 0x1ebf,
+	0x1ec1, 0x1ec1,
+	0x1ec3, 0x1ec3,
+	0x1ec5, 0x1ec5,
+	0x1ec7, 0x1ec7,
+	0x1ec9, 0x1ec9,
+	0x1ecb, 0x1ecb,
+	0x1ecd, 0x1ecd,
+	0x1ecf, 0x1ecf,
+	0x1ed1, 0x1ed1,
+	0x1ed3, 0x1ed3,
+	0x1ed5, 0x1ed5,
+	0x1ed7, 0x1ed7,
+	0x1ed9, 0x1ed9,
+	0x1edb, 0x1edb,
+	0x1edd, 0x1edd,
+	0x1edf, 0x1edf,
+	0x1ee1, 0x1ee1,
+	0x1ee3, 0x1ee3,
+	0x1ee5, 0x1ee5,
+	0x1ee7, 0x1ee7,
+	0x1ee9, 0x1ee9,
+	0x1eeb, 0x1eeb,
+	0x1eed, 0x1eed,
+	0x1eef, 0x1eef,
+	0x1ef1, 0x1ef1,
+	0x1ef3, 0x1ef3,
+	0x1ef5, 0x1ef5,
+	0x1ef7, 0x1ef7,
+	0x1ef9, 0x1ef9,
+	0x1efb, 0x1efb,
+	0x1efd, 0x1efd,
+	0x1eff, 0x1f07,
+	0x1f10, 0x1f15,
+	0x1f20, 0x1f27,
+	0x1f30, 0x1f37,
+	0x1f40, 0x1f45,
+	0x1f50, 0x1f57,
+	0x1f60, 0x1f67,
+	0x1f70, 0x1f7d,
+	0x1f80, 0x1f87,
+	0x1f90, 0x1f97,
+	0x1fa0, 0x1fa7,
+	0x1fb0, 0x1fb4,
+	0x1fb6, 0x1fb7,
+	0x1fbe, 0x1fbe,
+	0x1fc2, 0x1fc4,
+	0x1fc6, 0x1fc7,
+	0x1fd0, 0x1fd3,
+	0x1fd6, 0x1fd7,
+	0x1fe0, 0x1fe7,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ff7,
+	0x2071, 0x2071,
+	0x207f, 0x207f,
+	0x2090, 0x209c,
+	0x210a, 0x210a,
+	0x210e, 0x210f,
+	0x2113, 0x2113,
+	0x212f, 0x212f,
+	0x2134, 0x2134,
+	0x2139, 0x2139,
+	0x213c, 0x213d,
+	0x2146, 0x2149,
+	0x214e, 0x214e,
+	0x2170, 0x217f,
+	0x2184, 0x2184,
+	0x24d0, 0x24e9,
+	0x2c30, 0x2c5e,
+	0x2c61, 0x2c61,
+	0x2c65, 0x2c66,
+	0x2c68, 0x2c68,
+	0x2c6a, 0x2c6a,
+	0x2c6c, 0x2c6c,
+	0x2c71, 0x2c71,
+	0x2c73, 0x2c74,
+	0x2c76, 0x2c7d,
+	0x2c81, 0x2c81,
+	0x2c83, 0x2c83,
+	0x2c85, 0x2c85,
+	0x2c87, 0x2c87,
+	0x2c89, 0x2c89,
+	0x2c8b, 0x2c8b,
+	0x2c8d, 0x2c8d,
+	0x2c8f, 0x2c8f,
+	0x2c91, 0x2c91,
+	0x2c93, 0x2c93,
+	0x2c95, 0x2c95,
+	0x2c97, 0x2c97,
+	0x2c99, 0x2c99,
+	0x2c9b, 0x2c9b,
+	0x2c9d, 0x2c9d,
+	0x2c9f, 0x2c9f,
+	0x2ca1, 0x2ca1,
+	0x2ca3, 0x2ca3,
+	0x2ca5, 0x2ca5,
+	0x2ca7, 0x2ca7,
+	0x2ca9, 0x2ca9,
+	0x2cab, 0x2cab,
+	0x2cad, 0x2cad,
+	0x2caf, 0x2caf,
+	0x2cb1, 0x2cb1,
+	0x2cb3, 0x2cb3,
+	0x2cb5, 0x2cb5,
+	0x2cb7, 0x2cb7,
+	0x2cb9, 0x2cb9,
+	0x2cbb, 0x2cbb,
+	0x2cbd, 0x2cbd,
+	0x2cbf, 0x2cbf,
+	0x2cc1, 0x2cc1,
+	0x2cc3, 0x2cc3,
+	0x2cc5, 0x2cc5,
+	0x2cc7, 0x2cc7,
+	0x2cc9, 0x2cc9,
+	0x2ccb, 0x2ccb,
+	0x2ccd, 0x2ccd,
+	0x2ccf, 0x2ccf,
+	0x2cd1, 0x2cd1,
+	0x2cd3, 0x2cd3,
+	0x2cd5, 0x2cd5,
+	0x2cd7, 0x2cd7,
+	0x2cd9, 0x2cd9,
+	0x2cdb, 0x2cdb,
+	0x2cdd, 0x2cdd,
+	0x2cdf, 0x2cdf,
+	0x2ce1, 0x2ce1,
+	0x2ce3, 0x2ce4,
+	0x2cec, 0x2cec,
+	0x2cee, 0x2cee,
+	0x2cf3, 0x2cf3,
+	0x2d00, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0xa641, 0xa641,
+	0xa643, 0xa643,
+	0xa645, 0xa645,
+	0xa647, 0xa647,
+	0xa649, 0xa649,
+	0xa64b, 0xa64b,
+	0xa64d, 0xa64d,
+	0xa64f, 0xa64f,
+	0xa651, 0xa651,
+	0xa653, 0xa653,
+	0xa655, 0xa655,
+	0xa657, 0xa657,
+	0xa659, 0xa659,
+	0xa65b, 0xa65b,
+	0xa65d, 0xa65d,
+	0xa65f, 0xa65f,
+	0xa661, 0xa661,
+	0xa663, 0xa663,
+	0xa665, 0xa665,
+	0xa667, 0xa667,
+	0xa669, 0xa669,
+	0xa66b, 0xa66b,
+	0xa66d, 0xa66d,
+	0xa681, 0xa681,
+	0xa683, 0xa683,
+	0xa685, 0xa685,
+	0xa687, 0xa687,
+	0xa689, 0xa689,
+	0xa68b, 0xa68b,
+	0xa68d, 0xa68d,
+	0xa68f, 0xa68f,
+	0xa691, 0xa691,
+	0xa693, 0xa693,
+	0xa695, 0xa695,
+	0xa697, 0xa697,
+	0xa699, 0xa699,
+	0xa69b, 0xa69d,
+	0xa723, 0xa723,
+	0xa725, 0xa725,
+	0xa727, 0xa727,
+	0xa729, 0xa729,
+	0xa72b, 0xa72b,
+	0xa72d, 0xa72d,
+	0xa72f, 0xa731,
+	0xa733, 0xa733,
+	0xa735, 0xa735,
+	0xa737, 0xa737,
+	0xa739, 0xa739,
+	0xa73b, 0xa73b,
+	0xa73d, 0xa73d,
+	0xa73f, 0xa73f,
+	0xa741, 0xa741,
+	0xa743, 0xa743,
+	0xa745, 0xa745,
+	0xa747, 0xa747,
+	0xa749, 0xa749,
+	0xa74b, 0xa74b,
+	0xa74d, 0xa74d,
+	0xa74f, 0xa74f,
+	0xa751, 0xa751,
+	0xa753, 0xa753,
+	0xa755, 0xa755,
+	0xa757, 0xa757,
+	0xa759, 0xa759,
+	0xa75b, 0xa75b,
+	0xa75d, 0xa75d,
+	0xa75f, 0xa75f,
+	0xa761, 0xa761,
+	0xa763, 0xa763,
+	0xa765, 0xa765,
+	0xa767, 0xa767,
+	0xa769, 0xa769,
+	0xa76b, 0xa76b,
+	0xa76d, 0xa76d,
+	0xa76f, 0xa778,
+	0xa77a, 0xa77a,
+	0xa77c, 0xa77c,
+	0xa77f, 0xa77f,
+	0xa781, 0xa781,
+	0xa783, 0xa783,
+	0xa785, 0xa785,
+	0xa787, 0xa787,
+	0xa78c, 0xa78c,
+	0xa78e, 0xa78e,
+	0xa791, 0xa791,
+	0xa793, 0xa795,
+	0xa797, 0xa797,
+	0xa799, 0xa799,
+	0xa79b, 0xa79b,
+	0xa79d, 0xa79d,
+	0xa79f, 0xa79f,
+	0xa7a1, 0xa7a1,
+	0xa7a3, 0xa7a3,
+	0xa7a5, 0xa7a5,
+	0xa7a7, 0xa7a7,
+	0xa7a9, 0xa7a9,
+	0xa7b5, 0xa7b5,
+	0xa7b7, 0xa7b7,
+	0xa7f8, 0xa7fa,
+	0xab30, 0xab5a,
+	0xab5c, 0xab65,
+	0xab70, 0xabbf,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xff41, 0xff5a,
+	0x10428, 0x1044f,
+	0x104d8, 0x104fb,
+	0x10cc0, 0x10cf2,
+	0x118c0, 0x118df,
+	0x1d41a, 0x1d433,
+	0x1d44e, 0x1d454,
+	0x1d456, 0x1d467,
+	0x1d482, 0x1d49b,
+	0x1d4b6, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d4cf,
+	0x1d4ea, 0x1d503,
+	0x1d51e, 0x1d537,
+	0x1d552, 0x1d56b,
+	0x1d586, 0x1d59f,
+	0x1d5ba, 0x1d5d3,
+	0x1d5ee, 0x1d607,
+	0x1d622, 0x1d63b,
+	0x1d656, 0x1d66f,
+	0x1d68a, 0x1d6a5,
+	0x1d6c2, 0x1d6da,
+	0x1d6dc, 0x1d6e1,
+	0x1d6fc, 0x1d714,
+	0x1d716, 0x1d71b,
+	0x1d736, 0x1d74e,
+	0x1d750, 0x1d755,
+	0x1d770, 0x1d788,
+	0x1d78a, 0x1d78f,
+	0x1d7aa, 0x1d7c2,
+	0x1d7c4, 0x1d7c9,
+	0x1d7cb, 0x1d7cb,
+	0x1e922, 0x1e943,
+}; /* CR_Lower */
+
+/* 'Print': [[:Print:]] */
+static const OnigCodePoint CR_Print[] = {
+	651,
+	0x0020, 0x007e,
+	0x00a0, 0x0377,
+	0x037a, 0x037f,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x052f,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x058a,
+	0x058d, 0x058f,
+	0x0591, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x0600, 0x061c,
+	0x061e, 0x070d,
+	0x070f, 0x074a,
+	0x074d, 0x07b1,
+	0x07c0, 0x07fa,
+	0x0800, 0x082d,
+	0x0830, 0x083e,
+	0x0840, 0x085b,
+	0x085e, 0x085e,
+	0x0860, 0x086a,
+	0x08a0, 0x08b4,
+	0x08b6, 0x08bd,
+	0x08d4, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fd,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a75,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0af1,
+	0x0af9, 0x0aff,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3c, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b63,
+	0x0b66, 0x0b77,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd0, 0x0bd0,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bfa,
+	0x0c00, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c39,
+	0x0c3d, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c58, 0x0c5a,
+	0x0c60, 0x0c63,
+	0x0c66, 0x0c6f,
+	0x0c78, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbc, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce3,
+	0x0ce6, 0x0cef,
+	0x0cf1, 0x0cf2,
+	0x0d00, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4f,
+	0x0d54, 0x0d63,
+	0x0d66, 0x0d7f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0de6, 0x0def,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f71, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fbe, 0x0fcc,
+	0x0fce, 0x0fda,
+	0x1000, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135d, 0x137c,
+	0x1380, 0x1399,
+	0x13a0, 0x13f5,
+	0x13f8, 0x13fd,
+	0x1400, 0x169c,
+	0x16a0, 0x16f8,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+	0x1720, 0x1736,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17dd,
+	0x17e0, 0x17e9,
+	0x17f0, 0x17f9,
+	0x1800, 0x180e,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191e,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1940, 0x1940,
+	0x1944, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19da,
+	0x19de, 0x1a1b,
+	0x1a1e, 0x1a5e,
+	0x1a60, 0x1a7c,
+	0x1a7f, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1aa0, 0x1aad,
+	0x1ab0, 0x1abe,
+	0x1b00, 0x1b4b,
+	0x1b50, 0x1b7c,
+	0x1b80, 0x1bf3,
+	0x1bfc, 0x1c37,
+	0x1c3b, 0x1c49,
+	0x1c4d, 0x1c88,
+	0x1cc0, 0x1cc7,
+	0x1cd0, 0x1cf9,
+	0x1d00, 0x1df9,
+	0x1dfb, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x2027,
+	0x202a, 0x2064,
+	0x2066, 0x2071,
+	0x2074, 0x208e,
+	0x2090, 0x209c,
+	0x20a0, 0x20bf,
+	0x20d0, 0x20f0,
+	0x2100, 0x218b,
+	0x2190, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x2b73,
+	0x2b76, 0x2b95,
+	0x2b98, 0x2bb9,
+	0x2bbd, 0x2bc8,
+	0x2bca, 0x2bd2,
+	0x2bec, 0x2bef,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2cf3,
+	0x2cf9, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d70,
+	0x2d7f, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2de0, 0x2e49,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3000, 0x303f,
+	0x3041, 0x3096,
+	0x3099, 0x30ff,
+	0x3105, 0x312e,
+	0x3131, 0x318e,
+	0x3190, 0x31ba,
+	0x31c0, 0x31e3,
+	0x31f0, 0x321e,
+	0x3220, 0x32fe,
+	0x3300, 0x4db5,
+	0x4dc0, 0x9fea,
+	0xa000, 0xa48c,
+	0xa490, 0xa4c6,
+	0xa4d0, 0xa62b,
+	0xa640, 0xa6f7,
+	0xa700, 0xa7ae,
+	0xa7b0, 0xa7b7,
+	0xa7f7, 0xa82b,
+	0xa830, 0xa839,
+	0xa840, 0xa877,
+	0xa880, 0xa8c5,
+	0xa8ce, 0xa8d9,
+	0xa8e0, 0xa8fd,
+	0xa900, 0xa953,
+	0xa95f, 0xa97c,
+	0xa980, 0xa9cd,
+	0xa9cf, 0xa9d9,
+	0xa9de, 0xa9fe,
+	0xaa00, 0xaa36,
+	0xaa40, 0xaa4d,
+	0xaa50, 0xaa59,
+	0xaa5c, 0xaac2,
+	0xaadb, 0xaaf6,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xab30, 0xab65,
+	0xab70, 0xabed,
+	0xabf0, 0xabf9,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xe000, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbc1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdf0, 0xfdfd,
+	0xfe00, 0xfe19,
+	0xfe20, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfff9, 0xfffd,
+	0x10000, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10100, 0x10102,
+	0x10107, 0x10133,
+	0x10137, 0x1018e,
+	0x10190, 0x1019b,
+	0x101a0, 0x101a0,
+	0x101d0, 0x101fd,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x102e0, 0x102fb,
+	0x10300, 0x10323,
+	0x1032d, 0x1034a,
+	0x10350, 0x1037a,
+	0x10380, 0x1039d,
+	0x1039f, 0x103c3,
+	0x103c8, 0x103d5,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x104b0, 0x104d3,
+	0x104d8, 0x104fb,
+	0x10500, 0x10527,
+	0x10530, 0x10563,
+	0x1056f, 0x1056f,
+	0x10600, 0x10736,
+	0x10740, 0x10755,
+	0x10760, 0x10767,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10857, 0x1089e,
+	0x108a7, 0x108af,
+	0x108e0, 0x108f2,
+	0x108f4, 0x108f5,
+	0x108fb, 0x1091b,
+	0x1091f, 0x10939,
+	0x1093f, 0x1093f,
+	0x10980, 0x109b7,
+	0x109bc, 0x109cf,
+	0x109d2, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a47,
+	0x10a50, 0x10a58,
+	0x10a60, 0x10a9f,
+	0x10ac0, 0x10ae6,
+	0x10aeb, 0x10af6,
+	0x10b00, 0x10b35,
+	0x10b39, 0x10b55,
+	0x10b58, 0x10b72,
+	0x10b78, 0x10b91,
+	0x10b99, 0x10b9c,
+	0x10ba9, 0x10baf,
+	0x10c00, 0x10c48,
+	0x10c80, 0x10cb2,
+	0x10cc0, 0x10cf2,
+	0x10cfa, 0x10cff,
+	0x10e60, 0x10e7e,
+	0x11000, 0x1104d,
+	0x11052, 0x1106f,
+	0x1107f, 0x110c1,
+	0x110d0, 0x110e8,
+	0x110f0, 0x110f9,
+	0x11100, 0x11134,
+	0x11136, 0x11143,
+	0x11150, 0x11176,
+	0x11180, 0x111cd,
+	0x111d0, 0x111df,
+	0x111e1, 0x111f4,
+	0x11200, 0x11211,
+	0x11213, 0x1123e,
+	0x11280, 0x11286,
+	0x11288, 0x11288,
+	0x1128a, 0x1128d,
+	0x1128f, 0x1129d,
+	0x1129f, 0x112a9,
+	0x112b0, 0x112ea,
+	0x112f0, 0x112f9,
+	0x11300, 0x11303,
+	0x11305, 0x1130c,
+	0x1130f, 0x11310,
+	0x11313, 0x11328,
+	0x1132a, 0x11330,
+	0x11332, 0x11333,
+	0x11335, 0x11339,
+	0x1133c, 0x11344,
+	0x11347, 0x11348,
+	0x1134b, 0x1134d,
+	0x11350, 0x11350,
+	0x11357, 0x11357,
+	0x1135d, 0x11363,
+	0x11366, 0x1136c,
+	0x11370, 0x11374,
+	0x11400, 0x11459,
+	0x1145b, 0x1145b,
+	0x1145d, 0x1145d,
+	0x11480, 0x114c7,
+	0x114d0, 0x114d9,
+	0x11580, 0x115b5,
+	0x115b8, 0x115dd,
+	0x11600, 0x11644,
+	0x11650, 0x11659,
+	0x11660, 0x1166c,
+	0x11680, 0x116b7,
+	0x116c0, 0x116c9,
+	0x11700, 0x11719,
+	0x1171d, 0x1172b,
+	0x11730, 0x1173f,
+	0x118a0, 0x118f2,
+	0x118ff, 0x118ff,
+	0x11a00, 0x11a47,
+	0x11a50, 0x11a83,
+	0x11a86, 0x11a9c,
+	0x11a9e, 0x11aa2,
+	0x11ac0, 0x11af8,
+	0x11c00, 0x11c08,
+	0x11c0a, 0x11c36,
+	0x11c38, 0x11c45,
+	0x11c50, 0x11c6c,
+	0x11c70, 0x11c8f,
+	0x11c92, 0x11ca7,
+	0x11ca9, 0x11cb6,
+	0x11d00, 0x11d06,
+	0x11d08, 0x11d09,
+	0x11d0b, 0x11d36,
+	0x11d3a, 0x11d3a,
+	0x11d3c, 0x11d3d,
+	0x11d3f, 0x11d47,
+	0x11d50, 0x11d59,
+	0x12000, 0x12399,
+	0x12400, 0x1246e,
+	0x12470, 0x12474,
+	0x12480, 0x12543,
+	0x13000, 0x1342e,
+	0x14400, 0x14646,
+	0x16800, 0x16a38,
+	0x16a40, 0x16a5e,
+	0x16a60, 0x16a69,
+	0x16a6e, 0x16a6f,
+	0x16ad0, 0x16aed,
+	0x16af0, 0x16af5,
+	0x16b00, 0x16b45,
+	0x16b50, 0x16b59,
+	0x16b5b, 0x16b61,
+	0x16b63, 0x16b77,
+	0x16b7d, 0x16b8f,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f7e,
+	0x16f8f, 0x16f9f,
+	0x16fe0, 0x16fe1,
+	0x17000, 0x187ec,
+	0x18800, 0x18af2,
+	0x1b000, 0x1b11e,
+	0x1b170, 0x1b2fb,
+	0x1bc00, 0x1bc6a,
+	0x1bc70, 0x1bc7c,
+	0x1bc80, 0x1bc88,
+	0x1bc90, 0x1bc99,
+	0x1bc9c, 0x1bca3,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d129, 0x1d1e8,
+	0x1d200, 0x1d245,
+	0x1d300, 0x1d356,
+	0x1d360, 0x1d371,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d7cb,
+	0x1d7ce, 0x1da8b,
+	0x1da9b, 0x1da9f,
+	0x1daa1, 0x1daaf,
+	0x1e000, 0x1e006,
+	0x1e008, 0x1e018,
+	0x1e01b, 0x1e021,
+	0x1e023, 0x1e024,
+	0x1e026, 0x1e02a,
+	0x1e800, 0x1e8c4,
+	0x1e8c7, 0x1e8d6,
+	0x1e900, 0x1e94a,
+	0x1e950, 0x1e959,
+	0x1e95e, 0x1e95f,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x1eef0, 0x1eef1,
+	0x1f000, 0x1f02b,
+	0x1f030, 0x1f093,
+	0x1f0a0, 0x1f0ae,
+	0x1f0b1, 0x1f0bf,
+	0x1f0c1, 0x1f0cf,
+	0x1f0d1, 0x1f0f5,
+	0x1f100, 0x1f10c,
+	0x1f110, 0x1f12e,
+	0x1f130, 0x1f16b,
+	0x1f170, 0x1f1ac,
+	0x1f1e6, 0x1f202,
+	0x1f210, 0x1f23b,
+	0x1f240, 0x1f248,
+	0x1f250, 0x1f251,
+	0x1f260, 0x1f265,
+	0x1f300, 0x1f6d4,
+	0x1f6e0, 0x1f6ec,
+	0x1f6f0, 0x1f6f8,
+	0x1f700, 0x1f773,
+	0x1f780, 0x1f7d4,
+	0x1f800, 0x1f80b,
+	0x1f810, 0x1f847,
+	0x1f850, 0x1f859,
+	0x1f860, 0x1f887,
+	0x1f890, 0x1f8ad,
+	0x1f900, 0x1f90b,
+	0x1f910, 0x1f93e,
+	0x1f940, 0x1f94c,
+	0x1f950, 0x1f96b,
+	0x1f980, 0x1f997,
+	0x1f9c0, 0x1f9c0,
+	0x1f9d0, 0x1f9e6,
+	0x20000, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2b820, 0x2cea1,
+	0x2ceb0, 0x2ebe0,
+	0x2f800, 0x2fa1d,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+	0xe0100, 0xe01ef,
+	0xf0000, 0xffffd,
+	0x100000, 0x10fffd,
+}; /* CR_Print */
+
+/* 'XPosixPunct': [[:Punct:]] */
+static const OnigCodePoint CR_XPosixPunct[] = {
+	167,
+	0x0021, 0x002f,
+	0x003a, 0x0040,
+	0x005b, 0x0060,
+	0x007b, 0x007e,
+	0x00a1, 0x00a1,
+	0x00a7, 0x00a7,
+	0x00ab, 0x00ab,
+	0x00b6, 0x00b7,
+	0x00bb, 0x00bb,
+	0x00bf, 0x00bf,
+	0x037e, 0x037e,
+	0x0387, 0x0387,
+	0x055a, 0x055f,
+	0x0589, 0x058a,
+	0x05be, 0x05be,
+	0x05c0, 0x05c0,
+	0x05c3, 0x05c3,
+	0x05c6, 0x05c6,
+	0x05f3, 0x05f4,
+	0x0609, 0x060a,
+	0x060c, 0x060d,
+	0x061b, 0x061b,
+	0x061e, 0x061f,
+	0x066a, 0x066d,
+	0x06d4, 0x06d4,
+	0x0700, 0x070d,
+	0x07f7, 0x07f9,
+	0x0830, 0x083e,
+	0x085e, 0x085e,
+	0x0964, 0x0965,
+	0x0970, 0x0970,
+	0x09fd, 0x09fd,
+	0x0af0, 0x0af0,
+	0x0df4, 0x0df4,
+	0x0e4f, 0x0e4f,
+	0x0e5a, 0x0e5b,
+	0x0f04, 0x0f12,
+	0x0f14, 0x0f14,
+	0x0f3a, 0x0f3d,
+	0x0f85, 0x0f85,
+	0x0fd0, 0x0fd4,
+	0x0fd9, 0x0fda,
+	0x104a, 0x104f,
+	0x10fb, 0x10fb,
+	0x1360, 0x1368,
+	0x1400, 0x1400,
+	0x166d, 0x166e,
+	0x169b, 0x169c,
+	0x16eb, 0x16ed,
+	0x1735, 0x1736,
+	0x17d4, 0x17d6,
+	0x17d8, 0x17da,
+	0x1800, 0x180a,
+	0x1944, 0x1945,
+	0x1a1e, 0x1a1f,
+	0x1aa0, 0x1aa6,
+	0x1aa8, 0x1aad,
+	0x1b5a, 0x1b60,
+	0x1bfc, 0x1bff,
+	0x1c3b, 0x1c3f,
+	0x1c7e, 0x1c7f,
+	0x1cc0, 0x1cc7,
+	0x1cd3, 0x1cd3,
+	0x2010, 0x2027,
+	0x2030, 0x2043,
+	0x2045, 0x2051,
+	0x2053, 0x205e,
+	0x207d, 0x207e,
+	0x208d, 0x208e,
+	0x2308, 0x230b,
+	0x2329, 0x232a,
+	0x2768, 0x2775,
+	0x27c5, 0x27c6,
+	0x27e6, 0x27ef,
+	0x2983, 0x2998,
+	0x29d8, 0x29db,
+	0x29fc, 0x29fd,
+	0x2cf9, 0x2cfc,
+	0x2cfe, 0x2cff,
+	0x2d70, 0x2d70,
+	0x2e00, 0x2e2e,
+	0x2e30, 0x2e49,
+	0x3001, 0x3003,
+	0x3008, 0x3011,
+	0x3014, 0x301f,
+	0x3030, 0x3030,
+	0x303d, 0x303d,
+	0x30a0, 0x30a0,
+	0x30fb, 0x30fb,
+	0xa4fe, 0xa4ff,
+	0xa60d, 0xa60f,
+	0xa673, 0xa673,
+	0xa67e, 0xa67e,
+	0xa6f2, 0xa6f7,
+	0xa874, 0xa877,
+	0xa8ce, 0xa8cf,
+	0xa8f8, 0xa8fa,
+	0xa8fc, 0xa8fc,
+	0xa92e, 0xa92f,
+	0xa95f, 0xa95f,
+	0xa9c1, 0xa9cd,
+	0xa9de, 0xa9df,
+	0xaa5c, 0xaa5f,
+	0xaade, 0xaadf,
+	0xaaf0, 0xaaf1,
+	0xabeb, 0xabeb,
+	0xfd3e, 0xfd3f,
+	0xfe10, 0xfe19,
+	0xfe30, 0xfe52,
+	0xfe54, 0xfe61,
+	0xfe63, 0xfe63,
+	0xfe68, 0xfe68,
+	0xfe6a, 0xfe6b,
+	0xff01, 0xff03,
+	0xff05, 0xff0a,
+	0xff0c, 0xff0f,
+	0xff1a, 0xff1b,
+	0xff1f, 0xff20,
+	0xff3b, 0xff3d,
+	0xff3f, 0xff3f,
+	0xff5b, 0xff5b,
+	0xff5d, 0xff5d,
+	0xff5f, 0xff65,
+	0x10100, 0x10102,
+	0x1039f, 0x1039f,
+	0x103d0, 0x103d0,
+	0x1056f, 0x1056f,
+	0x10857, 0x10857,
+	0x1091f, 0x1091f,
+	0x1093f, 0x1093f,
+	0x10a50, 0x10a58,
+	0x10a7f, 0x10a7f,
+	0x10af0, 0x10af6,
+	0x10b39, 0x10b3f,
+	0x10b99, 0x10b9c,
+	0x11047, 0x1104d,
+	0x110bb, 0x110bc,
+	0x110be, 0x110c1,
+	0x11140, 0x11143,
+	0x11174, 0x11175,
+	0x111c5, 0x111c9,
+	0x111cd, 0x111cd,
+	0x111db, 0x111db,
+	0x111dd, 0x111df,
+	0x11238, 0x1123d,
+	0x112a9, 0x112a9,
+	0x1144b, 0x1144f,
+	0x1145b, 0x1145b,
+	0x1145d, 0x1145d,
+	0x114c6, 0x114c6,
+	0x115c1, 0x115d7,
+	0x11641, 0x11643,
+	0x11660, 0x1166c,
+	0x1173c, 0x1173e,
+	0x11a3f, 0x11a46,
+	0x11a9a, 0x11a9c,
+	0x11a9e, 0x11aa2,
+	0x11c41, 0x11c45,
+	0x11c70, 0x11c71,
+	0x12470, 0x12474,
+	0x16a6e, 0x16a6f,
+	0x16af5, 0x16af5,
+	0x16b37, 0x16b3b,
+	0x16b44, 0x16b44,
+	0x1bc9f, 0x1bc9f,
+	0x1da87, 0x1da8b,
+	0x1e95e, 0x1e95f,
+}; /* CR_XPosixPunct */
+
+/* 'Space': [[:Space:]] */
+static const OnigCodePoint CR_Space[] = {
+	10,
+	0x0009, 0x000d,
+	0x0020, 0x0020,
+	0x0085, 0x0085,
+	0x00a0, 0x00a0,
+	0x1680, 0x1680,
+	0x2000, 0x200a,
+	0x2028, 0x2029,
+	0x202f, 0x202f,
+	0x205f, 0x205f,
+	0x3000, 0x3000,
+}; /* CR_Space */
+
+/* 'Upper': [[:Upper:]] */
+static const OnigCodePoint CR_Upper[] = {
+	632,
+	0x0041, 0x005a,
+	0x00c0, 0x00d6,
+	0x00d8, 0x00de,
+	0x0100, 0x0100,
+	0x0102, 0x0102,
+	0x0104, 0x0104,
+	0x0106, 0x0106,
+	0x0108, 0x0108,
+	0x010a, 0x010a,
+	0x010c, 0x010c,
+	0x010e, 0x010e,
+	0x0110, 0x0110,
+	0x0112, 0x0112,
+	0x0114, 0x0114,
+	0x0116, 0x0116,
+	0x0118, 0x0118,
+	0x011a, 0x011a,
+	0x011c, 0x011c,
+	0x011e, 0x011e,
+	0x0120, 0x0120,
+	0x0122, 0x0122,
+	0x0124, 0x0124,
+	0x0126, 0x0126,
+	0x0128, 0x0128,
+	0x012a, 0x012a,
+	0x012c, 0x012c,
+	0x012e, 0x012e,
+	0x0130, 0x0130,
+	0x0132, 0x0132,
+	0x0134, 0x0134,
+	0x0136, 0x0136,
+	0x0139, 0x0139,
+	0x013b, 0x013b,
+	0x013d, 0x013d,
+	0x013f, 0x013f,
+	0x0141, 0x0141,
+	0x0143, 0x0143,
+	0x0145, 0x0145,
+	0x0147, 0x0147,
+	0x014a, 0x014a,
+	0x014c, 0x014c,
+	0x014e, 0x014e,
+	0x0150, 0x0150,
+	0x0152, 0x0152,
+	0x0154, 0x0154,
+	0x0156, 0x0156,
+	0x0158, 0x0158,
+	0x015a, 0x015a,
+	0x015c, 0x015c,
+	0x015e, 0x015e,
+	0x0160, 0x0160,
+	0x0162, 0x0162,
+	0x0164, 0x0164,
+	0x0166, 0x0166,
+	0x0168, 0x0168,
+	0x016a, 0x016a,
+	0x016c, 0x016c,
+	0x016e, 0x016e,
+	0x0170, 0x0170,
+	0x0172, 0x0172,
+	0x0174, 0x0174,
+	0x0176, 0x0176,
+	0x0178, 0x0179,
+	0x017b, 0x017b,
+	0x017d, 0x017d,
+	0x0181, 0x0182,
+	0x0184, 0x0184,
+	0x0186, 0x0187,
+	0x0189, 0x018b,
+	0x018e, 0x0191,
+	0x0193, 0x0194,
+	0x0196, 0x0198,
+	0x019c, 0x019d,
+	0x019f, 0x01a0,
+	0x01a2, 0x01a2,
+	0x01a4, 0x01a4,
+	0x01a6, 0x01a7,
+	0x01a9, 0x01a9,
+	0x01ac, 0x01ac,
+	0x01ae, 0x01af,
+	0x01b1, 0x01b3,
+	0x01b5, 0x01b5,
+	0x01b7, 0x01b8,
+	0x01bc, 0x01bc,
+	0x01c4, 0x01c4,
+	0x01c7, 0x01c7,
+	0x01ca, 0x01ca,
+	0x01cd, 0x01cd,
+	0x01cf, 0x01cf,
+	0x01d1, 0x01d1,
+	0x01d3, 0x01d3,
+	0x01d5, 0x01d5,
+	0x01d7, 0x01d7,
+	0x01d9, 0x01d9,
+	0x01db, 0x01db,
+	0x01de, 0x01de,
+	0x01e0, 0x01e0,
+	0x01e2, 0x01e2,
+	0x01e4, 0x01e4,
+	0x01e6, 0x01e6,
+	0x01e8, 0x01e8,
+	0x01ea, 0x01ea,
+	0x01ec, 0x01ec,
+	0x01ee, 0x01ee,
+	0x01f1, 0x01f1,
+	0x01f4, 0x01f4,
+	0x01f6, 0x01f8,
+	0x01fa, 0x01fa,
+	0x01fc, 0x01fc,
+	0x01fe, 0x01fe,
+	0x0200, 0x0200,
+	0x0202, 0x0202,
+	0x0204, 0x0204,
+	0x0206, 0x0206,
+	0x0208, 0x0208,
+	0x020a, 0x020a,
+	0x020c, 0x020c,
+	0x020e, 0x020e,
+	0x0210, 0x0210,
+	0x0212, 0x0212,
+	0x0214, 0x0214,
+	0x0216, 0x0216,
+	0x0218, 0x0218,
+	0x021a, 0x021a,
+	0x021c, 0x021c,
+	0x021e, 0x021e,
+	0x0220, 0x0220,
+	0x0222, 0x0222,
+	0x0224, 0x0224,
+	0x0226, 0x0226,
+	0x0228, 0x0228,
+	0x022a, 0x022a,
+	0x022c, 0x022c,
+	0x022e, 0x022e,
+	0x0230, 0x0230,
+	0x0232, 0x0232,
+	0x023a, 0x023b,
+	0x023d, 0x023e,
+	0x0241, 0x0241,
+	0x0243, 0x0246,
+	0x0248, 0x0248,
+	0x024a, 0x024a,
+	0x024c, 0x024c,
+	0x024e, 0x024e,
+	0x0370, 0x0370,
+	0x0372, 0x0372,
+	0x0376, 0x0376,
+	0x037f, 0x037f,
+	0x0386, 0x0386,
+	0x0388, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x038f,
+	0x0391, 0x03a1,
+	0x03a3, 0x03ab,
+	0x03cf, 0x03cf,
+	0x03d2, 0x03d4,
+	0x03d8, 0x03d8,
+	0x03da, 0x03da,
+	0x03dc, 0x03dc,
+	0x03de, 0x03de,
+	0x03e0, 0x03e0,
+	0x03e2, 0x03e2,
+	0x03e4, 0x03e4,
+	0x03e6, 0x03e6,
+	0x03e8, 0x03e8,
+	0x03ea, 0x03ea,
+	0x03ec, 0x03ec,
+	0x03ee, 0x03ee,
+	0x03f4, 0x03f4,
+	0x03f7, 0x03f7,
+	0x03f9, 0x03fa,
+	0x03fd, 0x042f,
+	0x0460, 0x0460,
+	0x0462, 0x0462,
+	0x0464, 0x0464,
+	0x0466, 0x0466,
+	0x0468, 0x0468,
+	0x046a, 0x046a,
+	0x046c, 0x046c,
+	0x046e, 0x046e,
+	0x0470, 0x0470,
+	0x0472, 0x0472,
+	0x0474, 0x0474,
+	0x0476, 0x0476,
+	0x0478, 0x0478,
+	0x047a, 0x047a,
+	0x047c, 0x047c,
+	0x047e, 0x047e,
+	0x0480, 0x0480,
+	0x048a, 0x048a,
+	0x048c, 0x048c,
+	0x048e, 0x048e,
+	0x0490, 0x0490,
+	0x0492, 0x0492,
+	0x0494, 0x0494,
+	0x0496, 0x0496,
+	0x0498, 0x0498,
+	0x049a, 0x049a,
+	0x049c, 0x049c,
+	0x049e, 0x049e,
+	0x04a0, 0x04a0,
+	0x04a2, 0x04a2,
+	0x04a4, 0x04a4,
+	0x04a6, 0x04a6,
+	0x04a8, 0x04a8,
+	0x04aa, 0x04aa,
+	0x04ac, 0x04ac,
+	0x04ae, 0x04ae,
+	0x04b0, 0x04b0,
+	0x04b2, 0x04b2,
+	0x04b4, 0x04b4,
+	0x04b6, 0x04b6,
+	0x04b8, 0x04b8,
+	0x04ba, 0x04ba,
+	0x04bc, 0x04bc,
+	0x04be, 0x04be,
+	0x04c0, 0x04c1,
+	0x04c3, 0x04c3,
+	0x04c5, 0x04c5,
+	0x04c7, 0x04c7,
+	0x04c9, 0x04c9,
+	0x04cb, 0x04cb,
+	0x04cd, 0x04cd,
+	0x04d0, 0x04d0,
+	0x04d2, 0x04d2,
+	0x04d4, 0x04d4,
+	0x04d6, 0x04d6,
+	0x04d8, 0x04d8,
+	0x04da, 0x04da,
+	0x04dc, 0x04dc,
+	0x04de, 0x04de,
+	0x04e0, 0x04e0,
+	0x04e2, 0x04e2,
+	0x04e4, 0x04e4,
+	0x04e6, 0x04e6,
+	0x04e8, 0x04e8,
+	0x04ea, 0x04ea,
+	0x04ec, 0x04ec,
+	0x04ee, 0x04ee,
+	0x04f0, 0x04f0,
+	0x04f2, 0x04f2,
+	0x04f4, 0x04f4,
+	0x04f6, 0x04f6,
+	0x04f8, 0x04f8,
+	0x04fa, 0x04fa,
+	0x04fc, 0x04fc,
+	0x04fe, 0x04fe,
+	0x0500, 0x0500,
+	0x0502, 0x0502,
+	0x0504, 0x0504,
+	0x0506, 0x0506,
+	0x0508, 0x0508,
+	0x050a, 0x050a,
+	0x050c, 0x050c,
+	0x050e, 0x050e,
+	0x0510, 0x0510,
+	0x0512, 0x0512,
+	0x0514, 0x0514,
+	0x0516, 0x0516,
+	0x0518, 0x0518,
+	0x051a, 0x051a,
+	0x051c, 0x051c,
+	0x051e, 0x051e,
+	0x0520, 0x0520,
+	0x0522, 0x0522,
+	0x0524, 0x0524,
+	0x0526, 0x0526,
+	0x0528, 0x0528,
+	0x052a, 0x052a,
+	0x052c, 0x052c,
+	0x052e, 0x052e,
+	0x0531, 0x0556,
+	0x10a0, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x13a0, 0x13f5,
+	0x1e00, 0x1e00,
+	0x1e02, 0x1e02,
+	0x1e04, 0x1e04,
+	0x1e06, 0x1e06,
+	0x1e08, 0x1e08,
+	0x1e0a, 0x1e0a,
+	0x1e0c, 0x1e0c,
+	0x1e0e, 0x1e0e,
+	0x1e10, 0x1e10,
+	0x1e12, 0x1e12,
+	0x1e14, 0x1e14,
+	0x1e16, 0x1e16,
+	0x1e18, 0x1e18,
+	0x1e1a, 0x1e1a,
+	0x1e1c, 0x1e1c,
+	0x1e1e, 0x1e1e,
+	0x1e20, 0x1e20,
+	0x1e22, 0x1e22,
+	0x1e24, 0x1e24,
+	0x1e26, 0x1e26,
+	0x1e28, 0x1e28,
+	0x1e2a, 0x1e2a,
+	0x1e2c, 0x1e2c,
+	0x1e2e, 0x1e2e,
+	0x1e30, 0x1e30,
+	0x1e32, 0x1e32,
+	0x1e34, 0x1e34,
+	0x1e36, 0x1e36,
+	0x1e38, 0x1e38,
+	0x1e3a, 0x1e3a,
+	0x1e3c, 0x1e3c,
+	0x1e3e, 0x1e3e,
+	0x1e40, 0x1e40,
+	0x1e42, 0x1e42,
+	0x1e44, 0x1e44,
+	0x1e46, 0x1e46,
+	0x1e48, 0x1e48,
+	0x1e4a, 0x1e4a,
+	0x1e4c, 0x1e4c,
+	0x1e4e, 0x1e4e,
+	0x1e50, 0x1e50,
+	0x1e52, 0x1e52,
+	0x1e54, 0x1e54,
+	0x1e56, 0x1e56,
+	0x1e58, 0x1e58,
+	0x1e5a, 0x1e5a,
+	0x1e5c, 0x1e5c,
+	0x1e5e, 0x1e5e,
+	0x1e60, 0x1e60,
+	0x1e62, 0x1e62,
+	0x1e64, 0x1e64,
+	0x1e66, 0x1e66,
+	0x1e68, 0x1e68,
+	0x1e6a, 0x1e6a,
+	0x1e6c, 0x1e6c,
+	0x1e6e, 0x1e6e,
+	0x1e70, 0x1e70,
+	0x1e72, 0x1e72,
+	0x1e74, 0x1e74,
+	0x1e76, 0x1e76,
+	0x1e78, 0x1e78,
+	0x1e7a, 0x1e7a,
+	0x1e7c, 0x1e7c,
+	0x1e7e, 0x1e7e,
+	0x1e80, 0x1e80,
+	0x1e82, 0x1e82,
+	0x1e84, 0x1e84,
+	0x1e86, 0x1e86,
+	0x1e88, 0x1e88,
+	0x1e8a, 0x1e8a,
+	0x1e8c, 0x1e8c,
+	0x1e8e, 0x1e8e,
+	0x1e90, 0x1e90,
+	0x1e92, 0x1e92,
+	0x1e94, 0x1e94,
+	0x1e9e, 0x1e9e,
+	0x1ea0, 0x1ea0,
+	0x1ea2, 0x1ea2,
+	0x1ea4, 0x1ea4,
+	0x1ea6, 0x1ea6,
+	0x1ea8, 0x1ea8,
+	0x1eaa, 0x1eaa,
+	0x1eac, 0x1eac,
+	0x1eae, 0x1eae,
+	0x1eb0, 0x1eb0,
+	0x1eb2, 0x1eb2,
+	0x1eb4, 0x1eb4,
+	0x1eb6, 0x1eb6,
+	0x1eb8, 0x1eb8,
+	0x1eba, 0x1eba,
+	0x1ebc, 0x1ebc,
+	0x1ebe, 0x1ebe,
+	0x1ec0, 0x1ec0,
+	0x1ec2, 0x1ec2,
+	0x1ec4, 0x1ec4,
+	0x1ec6, 0x1ec6,
+	0x1ec8, 0x1ec8,
+	0x1eca, 0x1eca,
+	0x1ecc, 0x1ecc,
+	0x1ece, 0x1ece,
+	0x1ed0, 0x1ed0,
+	0x1ed2, 0x1ed2,
+	0x1ed4, 0x1ed4,
+	0x1ed6, 0x1ed6,
+	0x1ed8, 0x1ed8,
+	0x1eda, 0x1eda,
+	0x1edc, 0x1edc,
+	0x1ede, 0x1ede,
+	0x1ee0, 0x1ee0,
+	0x1ee2, 0x1ee2,
+	0x1ee4, 0x1ee4,
+	0x1ee6, 0x1ee6,
+	0x1ee8, 0x1ee8,
+	0x1eea, 0x1eea,
+	0x1eec, 0x1eec,
+	0x1eee, 0x1eee,
+	0x1ef0, 0x1ef0,
+	0x1ef2, 0x1ef2,
+	0x1ef4, 0x1ef4,
+	0x1ef6, 0x1ef6,
+	0x1ef8, 0x1ef8,
+	0x1efa, 0x1efa,
+	0x1efc, 0x1efc,
+	0x1efe, 0x1efe,
+	0x1f08, 0x1f0f,
+	0x1f18, 0x1f1d,
+	0x1f28, 0x1f2f,
+	0x1f38, 0x1f3f,
+	0x1f48, 0x1f4d,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f5f,
+	0x1f68, 0x1f6f,
+	0x1fb8, 0x1fbb,
+	0x1fc8, 0x1fcb,
+	0x1fd8, 0x1fdb,
+	0x1fe8, 0x1fec,
+	0x1ff8, 0x1ffb,
+	0x2102, 0x2102,
+	0x2107, 0x2107,
+	0x210b, 0x210d,
+	0x2110, 0x2112,
+	0x2115, 0x2115,
+	0x2119, 0x211d,
+	0x2124, 0x2124,
+	0x2126, 0x2126,
+	0x2128, 0x2128,
+	0x212a, 0x212d,
+	0x2130, 0x2133,
+	0x213e, 0x213f,
+	0x2145, 0x2145,
+	0x2160, 0x216f,
+	0x2183, 0x2183,
+	0x24b6, 0x24cf,
+	0x2c00, 0x2c2e,
+	0x2c60, 0x2c60,
+	0x2c62, 0x2c64,
+	0x2c67, 0x2c67,
+	0x2c69, 0x2c69,
+	0x2c6b, 0x2c6b,
+	0x2c6d, 0x2c70,
+	0x2c72, 0x2c72,
+	0x2c75, 0x2c75,
+	0x2c7e, 0x2c80,
+	0x2c82, 0x2c82,
+	0x2c84, 0x2c84,
+	0x2c86, 0x2c86,
+	0x2c88, 0x2c88,
+	0x2c8a, 0x2c8a,
+	0x2c8c, 0x2c8c,
+	0x2c8e, 0x2c8e,
+	0x2c90, 0x2c90,
+	0x2c92, 0x2c92,
+	0x2c94, 0x2c94,
+	0x2c96, 0x2c96,
+	0x2c98, 0x2c98,
+	0x2c9a, 0x2c9a,
+	0x2c9c, 0x2c9c,
+	0x2c9e, 0x2c9e,
+	0x2ca0, 0x2ca0,
+	0x2ca2, 0x2ca2,
+	0x2ca4, 0x2ca4,
+	0x2ca6, 0x2ca6,
+	0x2ca8, 0x2ca8,
+	0x2caa, 0x2caa,
+	0x2cac, 0x2cac,
+	0x2cae, 0x2cae,
+	0x2cb0, 0x2cb0,
+	0x2cb2, 0x2cb2,
+	0x2cb4, 0x2cb4,
+	0x2cb6, 0x2cb6,
+	0x2cb8, 0x2cb8,
+	0x2cba, 0x2cba,
+	0x2cbc, 0x2cbc,
+	0x2cbe, 0x2cbe,
+	0x2cc0, 0x2cc0,
+	0x2cc2, 0x2cc2,
+	0x2cc4, 0x2cc4,
+	0x2cc6, 0x2cc6,
+	0x2cc8, 0x2cc8,
+	0x2cca, 0x2cca,
+	0x2ccc, 0x2ccc,
+	0x2cce, 0x2cce,
+	0x2cd0, 0x2cd0,
+	0x2cd2, 0x2cd2,
+	0x2cd4, 0x2cd4,
+	0x2cd6, 0x2cd6,
+	0x2cd8, 0x2cd8,
+	0x2cda, 0x2cda,
+	0x2cdc, 0x2cdc,
+	0x2cde, 0x2cde,
+	0x2ce0, 0x2ce0,
+	0x2ce2, 0x2ce2,
+	0x2ceb, 0x2ceb,
+	0x2ced, 0x2ced,
+	0x2cf2, 0x2cf2,
+	0xa640, 0xa640,
+	0xa642, 0xa642,
+	0xa644, 0xa644,
+	0xa646, 0xa646,
+	0xa648, 0xa648,
+	0xa64a, 0xa64a,
+	0xa64c, 0xa64c,
+	0xa64e, 0xa64e,
+	0xa650, 0xa650,
+	0xa652, 0xa652,
+	0xa654, 0xa654,
+	0xa656, 0xa656,
+	0xa658, 0xa658,
+	0xa65a, 0xa65a,
+	0xa65c, 0xa65c,
+	0xa65e, 0xa65e,
+	0xa660, 0xa660,
+	0xa662, 0xa662,
+	0xa664, 0xa664,
+	0xa666, 0xa666,
+	0xa668, 0xa668,
+	0xa66a, 0xa66a,
+	0xa66c, 0xa66c,
+	0xa680, 0xa680,
+	0xa682, 0xa682,
+	0xa684, 0xa684,
+	0xa686, 0xa686,
+	0xa688, 0xa688,
+	0xa68a, 0xa68a,
+	0xa68c, 0xa68c,
+	0xa68e, 0xa68e,
+	0xa690, 0xa690,
+	0xa692, 0xa692,
+	0xa694, 0xa694,
+	0xa696, 0xa696,
+	0xa698, 0xa698,
+	0xa69a, 0xa69a,
+	0xa722, 0xa722,
+	0xa724, 0xa724,
+	0xa726, 0xa726,
+	0xa728, 0xa728,
+	0xa72a, 0xa72a,
+	0xa72c, 0xa72c,
+	0xa72e, 0xa72e,
+	0xa732, 0xa732,
+	0xa734, 0xa734,
+	0xa736, 0xa736,
+	0xa738, 0xa738,
+	0xa73a, 0xa73a,
+	0xa73c, 0xa73c,
+	0xa73e, 0xa73e,
+	0xa740, 0xa740,
+	0xa742, 0xa742,
+	0xa744, 0xa744,
+	0xa746, 0xa746,
+	0xa748, 0xa748,
+	0xa74a, 0xa74a,
+	0xa74c, 0xa74c,
+	0xa74e, 0xa74e,
+	0xa750, 0xa750,
+	0xa752, 0xa752,
+	0xa754, 0xa754,
+	0xa756, 0xa756,
+	0xa758, 0xa758,
+	0xa75a, 0xa75a,
+	0xa75c, 0xa75c,
+	0xa75e, 0xa75e,
+	0xa760, 0xa760,
+	0xa762, 0xa762,
+	0xa764, 0xa764,
+	0xa766, 0xa766,
+	0xa768, 0xa768,
+	0xa76a, 0xa76a,
+	0xa76c, 0xa76c,
+	0xa76e, 0xa76e,
+	0xa779, 0xa779,
+	0xa77b, 0xa77b,
+	0xa77d, 0xa77e,
+	0xa780, 0xa780,
+	0xa782, 0xa782,
+	0xa784, 0xa784,
+	0xa786, 0xa786,
+	0xa78b, 0xa78b,
+	0xa78d, 0xa78d,
+	0xa790, 0xa790,
+	0xa792, 0xa792,
+	0xa796, 0xa796,
+	0xa798, 0xa798,
+	0xa79a, 0xa79a,
+	0xa79c, 0xa79c,
+	0xa79e, 0xa79e,
+	0xa7a0, 0xa7a0,
+	0xa7a2, 0xa7a2,
+	0xa7a4, 0xa7a4,
+	0xa7a6, 0xa7a6,
+	0xa7a8, 0xa7a8,
+	0xa7aa, 0xa7ae,
+	0xa7b0, 0xa7b4,
+	0xa7b6, 0xa7b6,
+	0xff21, 0xff3a,
+	0x10400, 0x10427,
+	0x104b0, 0x104d3,
+	0x10c80, 0x10cb2,
+	0x118a0, 0x118bf,
+	0x1d400, 0x1d419,
+	0x1d434, 0x1d44d,
+	0x1d468, 0x1d481,
+	0x1d49c, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b5,
+	0x1d4d0, 0x1d4e9,
+	0x1d504, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d538, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d56c, 0x1d585,
+	0x1d5a0, 0x1d5b9,
+	0x1d5d4, 0x1d5ed,
+	0x1d608, 0x1d621,
+	0x1d63c, 0x1d655,
+	0x1d670, 0x1d689,
+	0x1d6a8, 0x1d6c0,
+	0x1d6e2, 0x1d6fa,
+	0x1d71c, 0x1d734,
+	0x1d756, 0x1d76e,
+	0x1d790, 0x1d7a8,
+	0x1d7ca, 0x1d7ca,
+	0x1e900, 0x1e921,
+	0x1f130, 0x1f149,
+	0x1f150, 0x1f169,
+	0x1f170, 0x1f189,
+}; /* CR_Upper */
+
+/* 'XDigit': [[:XDigit:]] */
+static const OnigCodePoint CR_XDigit[] = {
+	3,
+	0x0030, 0x0039,
+	0x0041, 0x0046,
+	0x0061, 0x0066,
+}; /* CR_XDigit */
+
+/* 'Word': [[:Word:]] */
+static const OnigCodePoint CR_Word[] = {
+	692,
+	0x0030, 0x0039,
+	0x0041, 0x005a,
+	0x005f, 0x005f,
+	0x0061, 0x007a,
+	0x00aa, 0x00aa,
+	0x00b5, 0x00b5,
+	0x00ba, 0x00ba,
+	0x00c0, 0x00d6,
+	0x00d8, 0x00f6,
+	0x00f8, 0x02c1,
+	0x02c6, 0x02d1,
+	0x02e0, 0x02e4,
+	0x02ec, 0x02ec,
+	0x02ee, 0x02ee,
+	0x0300, 0x0374,
+	0x0376, 0x0377,
+	0x037a, 0x037d,
+	0x037f, 0x037f,
+	0x0386, 0x0386,
+	0x0388, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03f5,
+	0x03f7, 0x0481,
+	0x0483, 0x052f,
+	0x0531, 0x0556,
+	0x0559, 0x0559,
+	0x0561, 0x0587,
+	0x0591, 0x05bd,
+	0x05bf, 0x05bf,
+	0x05c1, 0x05c2,
+	0x05c4, 0x05c5,
+	0x05c7, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f2,
+	0x0610, 0x061a,
+	0x0620, 0x0669,
+	0x066e, 0x06d3,
+	0x06d5, 0x06dc,
+	0x06df, 0x06e8,
+	0x06ea, 0x06fc,
+	0x06ff, 0x06ff,
+	0x0710, 0x074a,
+	0x074d, 0x07b1,
+	0x07c0, 0x07f5,
+	0x07fa, 0x07fa,
+	0x0800, 0x082d,
+	0x0840, 0x085b,
+	0x0860, 0x086a,
+	0x08a0, 0x08b4,
+	0x08b6, 0x08bd,
+	0x08d4, 0x08e1,
+	0x08e3, 0x0963,
+	0x0966, 0x096f,
+	0x0971, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09f1,
+	0x09fc, 0x09fc,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a75,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0aef,
+	0x0af9, 0x0aff,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3c, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b63,
+	0x0b66, 0x0b6f,
+	0x0b71, 0x0b71,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd0, 0x0bd0,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bef,
+	0x0c00, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c39,
+	0x0c3d, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c58, 0x0c5a,
+	0x0c60, 0x0c63,
+	0x0c66, 0x0c6f,
+	0x0c80, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbc, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce3,
+	0x0ce6, 0x0cef,
+	0x0cf1, 0x0cf2,
+	0x0d00, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4e,
+	0x0d54, 0x0d57,
+	0x0d5f, 0x0d63,
+	0x0d66, 0x0d6f,
+	0x0d7a, 0x0d7f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0de6, 0x0def,
+	0x0df2, 0x0df3,
+	0x0e01, 0x0e3a,
+	0x0e40, 0x0e4e,
+	0x0e50, 0x0e59,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f00,
+	0x0f18, 0x0f19,
+	0x0f20, 0x0f29,
+	0x0f35, 0x0f35,
+	0x0f37, 0x0f37,
+	0x0f39, 0x0f39,
+	0x0f3e, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f71, 0x0f84,
+	0x0f86, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fc6, 0x0fc6,
+	0x1000, 0x1049,
+	0x1050, 0x109d,
+	0x10a0, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x10fa,
+	0x10fc, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135d, 0x135f,
+	0x1380, 0x138f,
+	0x13a0, 0x13f5,
+	0x13f8, 0x13fd,
+	0x1401, 0x166c,
+	0x166f, 0x167f,
+	0x1681, 0x169a,
+	0x16a0, 0x16ea,
+	0x16ee, 0x16f8,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+	0x1720, 0x1734,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17d3,
+	0x17d7, 0x17d7,
+	0x17dc, 0x17dd,
+	0x17e0, 0x17e9,
+	0x180b, 0x180d,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191e,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1946, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19d9,
+	0x1a00, 0x1a1b,
+	0x1a20, 0x1a5e,
+	0x1a60, 0x1a7c,
+	0x1a7f, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1aa7, 0x1aa7,
+	0x1ab0, 0x1abe,
+	0x1b00, 0x1b4b,
+	0x1b50, 0x1b59,
+	0x1b6b, 0x1b73,
+	0x1b80, 0x1bf3,
+	0x1c00, 0x1c37,
+	0x1c40, 0x1c49,
+	0x1c4d, 0x1c7d,
+	0x1c80, 0x1c88,
+	0x1cd0, 0x1cd2,
+	0x1cd4, 0x1cf9,
+	0x1d00, 0x1df9,
+	0x1dfb, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fbc,
+	0x1fbe, 0x1fbe,
+	0x1fc2, 0x1fc4,
+	0x1fc6, 0x1fcc,
+	0x1fd0, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fe0, 0x1fec,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffc,
+	0x203f, 0x2040,
+	0x2054, 0x2054,
+	0x2071, 0x2071,
+	0x207f, 0x207f,
+	0x2090, 0x209c,
+	0x20d0, 0x20f0,
+	0x2102, 0x2102,
+	0x2107, 0x2107,
+	0x210a, 0x2113,
+	0x2115, 0x2115,
+	0x2119, 0x211d,
+	0x2124, 0x2124,
+	0x2126, 0x2126,
+	0x2128, 0x2128,
+	0x212a, 0x212d,
+	0x212f, 0x2139,
+	0x213c, 0x213f,
+	0x2145, 0x2149,
+	0x214e, 0x214e,
+	0x2160, 0x2188,
+	0x24b6, 0x24e9,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2ce4,
+	0x2ceb, 0x2cf3,
+	0x2d00, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d6f,
+	0x2d7f, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2de0, 0x2dff,
+	0x2e2f, 0x2e2f,
+	0x3005, 0x3007,
+	0x3021, 0x302f,
+	0x3031, 0x3035,
+	0x3038, 0x303c,
+	0x3041, 0x3096,
+	0x3099, 0x309a,
+	0x309d, 0x309f,
+	0x30a1, 0x30fa,
+	0x30fc, 0x30ff,
+	0x3105, 0x312e,
+	0x3131, 0x318e,
+	0x31a0, 0x31ba,
+	0x31f0, 0x31ff,
+	0x3400, 0x4db5,
+	0x4e00, 0x9fea,
+	0xa000, 0xa48c,
+	0xa4d0, 0xa4fd,
+	0xa500, 0xa60c,
+	0xa610, 0xa62b,
+	0xa640, 0xa672,
+	0xa674, 0xa67d,
+	0xa67f, 0xa6f1,
+	0xa717, 0xa71f,
+	0xa722, 0xa788,
+	0xa78b, 0xa7ae,
+	0xa7b0, 0xa7b7,
+	0xa7f7, 0xa827,
+	0xa840, 0xa873,
+	0xa880, 0xa8c5,
+	0xa8d0, 0xa8d9,
+	0xa8e0, 0xa8f7,
+	0xa8fb, 0xa8fb,
+	0xa8fd, 0xa8fd,
+	0xa900, 0xa92d,
+	0xa930, 0xa953,
+	0xa960, 0xa97c,
+	0xa980, 0xa9c0,
+	0xa9cf, 0xa9d9,
+	0xa9e0, 0xa9fe,
+	0xaa00, 0xaa36,
+	0xaa40, 0xaa4d,
+	0xaa50, 0xaa59,
+	0xaa60, 0xaa76,
+	0xaa7a, 0xaac2,
+	0xaadb, 0xaadd,
+	0xaae0, 0xaaef,
+	0xaaf2, 0xaaf6,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xab30, 0xab5a,
+	0xab5c, 0xab65,
+	0xab70, 0xabea,
+	0xabec, 0xabed,
+	0xabf0, 0xabf9,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xf900, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb28,
+	0xfb2a, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbb1,
+	0xfbd3, 0xfd3d,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdf0, 0xfdfb,
+	0xfe00, 0xfe0f,
+	0xfe20, 0xfe2f,
+	0xfe33, 0xfe34,
+	0xfe4d, 0xfe4f,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xff10, 0xff19,
+	0xff21, 0xff3a,
+	0xff3f, 0xff3f,
+	0xff41, 0xff5a,
+	0xff66, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0x10000, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10140, 0x10174,
+	0x101fd, 0x101fd,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x102e0, 0x102e0,
+	0x10300, 0x1031f,
+	0x1032d, 0x1034a,
+	0x10350, 0x1037a,
+	0x10380, 0x1039d,
+	0x103a0, 0x103c3,
+	0x103c8, 0x103cf,
+	0x103d1, 0x103d5,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x104b0, 0x104d3,
+	0x104d8, 0x104fb,
+	0x10500, 0x10527,
+	0x10530, 0x10563,
+	0x10600, 0x10736,
+	0x10740, 0x10755,
+	0x10760, 0x10767,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10860, 0x10876,
+	0x10880, 0x1089e,
+	0x108e0, 0x108f2,
+	0x108f4, 0x108f5,
+	0x10900, 0x10915,
+	0x10920, 0x10939,
+	0x10980, 0x109b7,
+	0x109be, 0x109bf,
+	0x10a00, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a3f,
+	0x10a60, 0x10a7c,
+	0x10a80, 0x10a9c,
+	0x10ac0, 0x10ac7,
+	0x10ac9, 0x10ae6,
+	0x10b00, 0x10b35,
+	0x10b40, 0x10b55,
+	0x10b60, 0x10b72,
+	0x10b80, 0x10b91,
+	0x10c00, 0x10c48,
+	0x10c80, 0x10cb2,
+	0x10cc0, 0x10cf2,
+	0x11000, 0x11046,
+	0x11066, 0x1106f,
+	0x1107f, 0x110ba,
+	0x110d0, 0x110e8,
+	0x110f0, 0x110f9,
+	0x11100, 0x11134,
+	0x11136, 0x1113f,
+	0x11150, 0x11173,
+	0x11176, 0x11176,
+	0x11180, 0x111c4,
+	0x111ca, 0x111cc,
+	0x111d0, 0x111da,
+	0x111dc, 0x111dc,
+	0x11200, 0x11211,
+	0x11213, 0x11237,
+	0x1123e, 0x1123e,
+	0x11280, 0x11286,
+	0x11288, 0x11288,
+	0x1128a, 0x1128d,
+	0x1128f, 0x1129d,
+	0x1129f, 0x112a8,
+	0x112b0, 0x112ea,
+	0x112f0, 0x112f9,
+	0x11300, 0x11303,
+	0x11305, 0x1130c,
+	0x1130f, 0x11310,
+	0x11313, 0x11328,
+	0x1132a, 0x11330,
+	0x11332, 0x11333,
+	0x11335, 0x11339,
+	0x1133c, 0x11344,
+	0x11347, 0x11348,
+	0x1134b, 0x1134d,
+	0x11350, 0x11350,
+	0x11357, 0x11357,
+	0x1135d, 0x11363,
+	0x11366, 0x1136c,
+	0x11370, 0x11374,
+	0x11400, 0x1144a,
+	0x11450, 0x11459,
+	0x11480, 0x114c5,
+	0x114c7, 0x114c7,
+	0x114d0, 0x114d9,
+	0x11580, 0x115b5,
+	0x115b8, 0x115c0,
+	0x115d8, 0x115dd,
+	0x11600, 0x11640,
+	0x11644, 0x11644,
+	0x11650, 0x11659,
+	0x11680, 0x116b7,
+	0x116c0, 0x116c9,
+	0x11700, 0x11719,
+	0x1171d, 0x1172b,
+	0x11730, 0x11739,
+	0x118a0, 0x118e9,
+	0x118ff, 0x118ff,
+	0x11a00, 0x11a3e,
+	0x11a47, 0x11a47,
+	0x11a50, 0x11a83,
+	0x11a86, 0x11a99,
+	0x11ac0, 0x11af8,
+	0x11c00, 0x11c08,
+	0x11c0a, 0x11c36,
+	0x11c38, 0x11c40,
+	0x11c50, 0x11c59,
+	0x11c72, 0x11c8f,
+	0x11c92, 0x11ca7,
+	0x11ca9, 0x11cb6,
+	0x11d00, 0x11d06,
+	0x11d08, 0x11d09,
+	0x11d0b, 0x11d36,
+	0x11d3a, 0x11d3a,
+	0x11d3c, 0x11d3d,
+	0x11d3f, 0x11d47,
+	0x11d50, 0x11d59,
+	0x12000, 0x12399,
+	0x12400, 0x1246e,
+	0x12480, 0x12543,
+	0x13000, 0x1342e,
+	0x14400, 0x14646,
+	0x16800, 0x16a38,
+	0x16a40, 0x16a5e,
+	0x16a60, 0x16a69,
+	0x16ad0, 0x16aed,
+	0x16af0, 0x16af4,
+	0x16b00, 0x16b36,
+	0x16b40, 0x16b43,
+	0x16b50, 0x16b59,
+	0x16b63, 0x16b77,
+	0x16b7d, 0x16b8f,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f7e,
+	0x16f8f, 0x16f9f,
+	0x16fe0, 0x16fe1,
+	0x17000, 0x187ec,
+	0x18800, 0x18af2,
+	0x1b000, 0x1b11e,
+	0x1b170, 0x1b2fb,
+	0x1bc00, 0x1bc6a,
+	0x1bc70, 0x1bc7c,
+	0x1bc80, 0x1bc88,
+	0x1bc90, 0x1bc99,
+	0x1bc9d, 0x1bc9e,
+	0x1d165, 0x1d169,
+	0x1d16d, 0x1d172,
+	0x1d17b, 0x1d182,
+	0x1d185, 0x1d18b,
+	0x1d1aa, 0x1d1ad,
+	0x1d242, 0x1d244,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d6c0,
+	0x1d6c2, 0x1d6da,
+	0x1d6dc, 0x1d6fa,
+	0x1d6fc, 0x1d714,
+	0x1d716, 0x1d734,
+	0x1d736, 0x1d74e,
+	0x1d750, 0x1d76e,
+	0x1d770, 0x1d788,
+	0x1d78a, 0x1d7a8,
+	0x1d7aa, 0x1d7c2,
+	0x1d7c4, 0x1d7cb,
+	0x1d7ce, 0x1d7ff,
+	0x1da00, 0x1da36,
+	0x1da3b, 0x1da6c,
+	0x1da75, 0x1da75,
+	0x1da84, 0x1da84,
+	0x1da9b, 0x1da9f,
+	0x1daa1, 0x1daaf,
+	0x1e000, 0x1e006,
+	0x1e008, 0x1e018,
+	0x1e01b, 0x1e021,
+	0x1e023, 0x1e024,
+	0x1e026, 0x1e02a,
+	0x1e800, 0x1e8c4,
+	0x1e8d0, 0x1e8d6,
+	0x1e900, 0x1e94a,
+	0x1e950, 0x1e959,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x1f130, 0x1f149,
+	0x1f150, 0x1f169,
+	0x1f170, 0x1f189,
+	0x20000, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2b820, 0x2cea1,
+	0x2ceb0, 0x2ebe0,
+	0x2f800, 0x2fa1d,
+	0xe0100, 0xe01ef,
+}; /* CR_Word */
+
+/* 'Alnum': [[:Alnum:]] */
+static const OnigCodePoint CR_Alnum[] = {
+	695,
+	0x0030, 0x0039,
+	0x0041, 0x005a,
+	0x0061, 0x007a,
+	0x00aa, 0x00aa,
+	0x00b5, 0x00b5,
+	0x00ba, 0x00ba,
+	0x00c0, 0x00d6,
+	0x00d8, 0x00f6,
+	0x00f8, 0x02c1,
+	0x02c6, 0x02d1,
+	0x02e0, 0x02e4,
+	0x02ec, 0x02ec,
+	0x02ee, 0x02ee,
+	0x0345, 0x0345,
+	0x0370, 0x0374,
+	0x0376, 0x0377,
+	0x037a, 0x037d,
+	0x037f, 0x037f,
+	0x0386, 0x0386,
+	0x0388, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03f5,
+	0x03f7, 0x0481,
+	0x048a, 0x052f,
+	0x0531, 0x0556,
+	0x0559, 0x0559,
+	0x0561, 0x0587,
+	0x05b0, 0x05bd,
+	0x05bf, 0x05bf,
+	0x05c1, 0x05c2,
+	0x05c4, 0x05c5,
+	0x05c7, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f2,
+	0x0610, 0x061a,
+	0x0620, 0x0657,
+	0x0659, 0x0669,
+	0x066e, 0x06d3,
+	0x06d5, 0x06dc,
+	0x06e1, 0x06e8,
+	0x06ed, 0x06fc,
+	0x06ff, 0x06ff,
+	0x0710, 0x073f,
+	0x074d, 0x07b1,
+	0x07c0, 0x07ea,
+	0x07f4, 0x07f5,
+	0x07fa, 0x07fa,
+	0x0800, 0x0817,
+	0x081a, 0x082c,
+	0x0840, 0x0858,
+	0x0860, 0x086a,
+	0x08a0, 0x08b4,
+	0x08b6, 0x08bd,
+	0x08d4, 0x08df,
+	0x08e3, 0x08e9,
+	0x08f0, 0x093b,
+	0x093d, 0x094c,
+	0x094e, 0x0950,
+	0x0955, 0x0963,
+	0x0966, 0x096f,
+	0x0971, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bd, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09cc,
+	0x09ce, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09f1,
+	0x09fc, 0x09fc,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4c,
+	0x0a51, 0x0a51,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a75,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abd, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acc,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0aef,
+	0x0af9, 0x0afc,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3d, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4c,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b63,
+	0x0b66, 0x0b6f,
+	0x0b71, 0x0b71,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcc,
+	0x0bd0, 0x0bd0,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bef,
+	0x0c00, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c39,
+	0x0c3d, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4c,
+	0x0c55, 0x0c56,
+	0x0c58, 0x0c5a,
+	0x0c60, 0x0c63,
+	0x0c66, 0x0c6f,
+	0x0c80, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbd, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccc,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce3,
+	0x0ce6, 0x0cef,
+	0x0cf1, 0x0cf2,
+	0x0d00, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d3a,
+	0x0d3d, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4c,
+	0x0d4e, 0x0d4e,
+	0x0d54, 0x0d57,
+	0x0d5f, 0x0d63,
+	0x0d66, 0x0d6f,
+	0x0d7a, 0x0d7f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0de6, 0x0def,
+	0x0df2, 0x0df3,
+	0x0e01, 0x0e3a,
+	0x0e40, 0x0e46,
+	0x0e4d, 0x0e4d,
+	0x0e50, 0x0e59,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ecd, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f00,
+	0x0f20, 0x0f29,
+	0x0f40, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f71, 0x0f81,
+	0x0f88, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x1000, 0x1036,
+	0x1038, 0x1038,
+	0x103b, 0x1049,
+	0x1050, 0x1062,
+	0x1065, 0x1068,
+	0x106e, 0x1086,
+	0x108e, 0x108e,
+	0x1090, 0x1099,
+	0x109c, 0x109d,
+	0x10a0, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x10fa,
+	0x10fc, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135f, 0x135f,
+	0x1380, 0x138f,
+	0x13a0, 0x13f5,
+	0x13f8, 0x13fd,
+	0x1401, 0x166c,
+	0x166f, 0x167f,
+	0x1681, 0x169a,
+	0x16a0, 0x16ea,
+	0x16ee, 0x16f8,
+	0x1700, 0x170c,
+	0x170e, 0x1713,
+	0x1720, 0x1733,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17b3,
+	0x17b6, 0x17c8,
+	0x17d7, 0x17d7,
+	0x17dc, 0x17dc,
+	0x17e0, 0x17e9,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191e,
+	0x1920, 0x192b,
+	0x1930, 0x1938,
+	0x1946, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19d9,
+	0x1a00, 0x1a1b,
+	0x1a20, 0x1a5e,
+	0x1a61, 0x1a74,
+	0x1a80, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1aa7, 0x1aa7,
+	0x1b00, 0x1b33,
+	0x1b35, 0x1b43,
+	0x1b45, 0x1b4b,
+	0x1b50, 0x1b59,
+	0x1b80, 0x1ba9,
+	0x1bac, 0x1be5,
+	0x1be7, 0x1bf1,
+	0x1c00, 0x1c35,
+	0x1c40, 0x1c49,
+	0x1c4d, 0x1c7d,
+	0x1c80, 0x1c88,
+	0x1ce9, 0x1cec,
+	0x1cee, 0x1cf3,
+	0x1cf5, 0x1cf6,
+	0x1d00, 0x1dbf,
+	0x1de7, 0x1df4,
+	0x1e00, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fbc,
+	0x1fbe, 0x1fbe,
+	0x1fc2, 0x1fc4,
+	0x1fc6, 0x1fcc,
+	0x1fd0, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fe0, 0x1fec,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffc,
+	0x2071, 0x2071,
+	0x207f, 0x207f,
+	0x2090, 0x209c,
+	0x2102, 0x2102,
+	0x2107, 0x2107,
+	0x210a, 0x2113,
+	0x2115, 0x2115,
+	0x2119, 0x211d,
+	0x2124, 0x2124,
+	0x2126, 0x2126,
+	0x2128, 0x2128,
+	0x212a, 0x212d,
+	0x212f, 0x2139,
+	0x213c, 0x213f,
+	0x2145, 0x2149,
+	0x214e, 0x214e,
+	0x2160, 0x2188,
+	0x24b6, 0x24e9,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2ce4,
+	0x2ceb, 0x2cee,
+	0x2cf2, 0x2cf3,
+	0x2d00, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d6f,
+	0x2d80, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2de0, 0x2dff,
+	0x2e2f, 0x2e2f,
+	0x3005, 0x3007,
+	0x3021, 0x3029,
+	0x3031, 0x3035,
+	0x3038, 0x303c,
+	0x3041, 0x3096,
+	0x309d, 0x309f,
+	0x30a1, 0x30fa,
+	0x30fc, 0x30ff,
+	0x3105, 0x312e,
+	0x3131, 0x318e,
+	0x31a0, 0x31ba,
+	0x31f0, 0x31ff,
+	0x3400, 0x4db5,
+	0x4e00, 0x9fea,
+	0xa000, 0xa48c,
+	0xa4d0, 0xa4fd,
+	0xa500, 0xa60c,
+	0xa610, 0xa62b,
+	0xa640, 0xa66e,
+	0xa674, 0xa67b,
+	0xa67f, 0xa6ef,
+	0xa717, 0xa71f,
+	0xa722, 0xa788,
+	0xa78b, 0xa7ae,
+	0xa7b0, 0xa7b7,
+	0xa7f7, 0xa801,
+	0xa803, 0xa805,
+	0xa807, 0xa80a,
+	0xa80c, 0xa827,
+	0xa840, 0xa873,
+	0xa880, 0xa8c3,
+	0xa8c5, 0xa8c5,
+	0xa8d0, 0xa8d9,
+	0xa8f2, 0xa8f7,
+	0xa8fb, 0xa8fb,
+	0xa8fd, 0xa8fd,
+	0xa900, 0xa92a,
+	0xa930, 0xa952,
+	0xa960, 0xa97c,
+	0xa980, 0xa9b2,
+	0xa9b4, 0xa9bf,
+	0xa9cf, 0xa9d9,
+	0xa9e0, 0xa9e4,
+	0xa9e6, 0xa9fe,
+	0xaa00, 0xaa36,
+	0xaa40, 0xaa4d,
+	0xaa50, 0xaa59,
+	0xaa60, 0xaa76,
+	0xaa7a, 0xaa7a,
+	0xaa7e, 0xaabe,
+	0xaac0, 0xaac0,
+	0xaac2, 0xaac2,
+	0xaadb, 0xaadd,
+	0xaae0, 0xaaef,
+	0xaaf2, 0xaaf5,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xab30, 0xab5a,
+	0xab5c, 0xab65,
+	0xab70, 0xabea,
+	0xabf0, 0xabf9,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xf900, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb28,
+	0xfb2a, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbb1,
+	0xfbd3, 0xfd3d,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdf0, 0xfdfb,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xff10, 0xff19,
+	0xff21, 0xff3a,
+	0xff41, 0xff5a,
+	0xff66, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0x10000, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10140, 0x10174,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x10300, 0x1031f,
+	0x1032d, 0x1034a,
+	0x10350, 0x1037a,
+	0x10380, 0x1039d,
+	0x103a0, 0x103c3,
+	0x103c8, 0x103cf,
+	0x103d1, 0x103d5,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x104b0, 0x104d3,
+	0x104d8, 0x104fb,
+	0x10500, 0x10527,
+	0x10530, 0x10563,
+	0x10600, 0x10736,
+	0x10740, 0x10755,
+	0x10760, 0x10767,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10860, 0x10876,
+	0x10880, 0x1089e,
+	0x108e0, 0x108f2,
+	0x108f4, 0x108f5,
+	0x10900, 0x10915,
+	0x10920, 0x10939,
+	0x10980, 0x109b7,
+	0x109be, 0x109bf,
+	0x10a00, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a60, 0x10a7c,
+	0x10a80, 0x10a9c,
+	0x10ac0, 0x10ac7,
+	0x10ac9, 0x10ae4,
+	0x10b00, 0x10b35,
+	0x10b40, 0x10b55,
+	0x10b60, 0x10b72,
+	0x10b80, 0x10b91,
+	0x10c00, 0x10c48,
+	0x10c80, 0x10cb2,
+	0x10cc0, 0x10cf2,
+	0x11000, 0x11045,
+	0x11066, 0x1106f,
+	0x11082, 0x110b8,
+	0x110d0, 0x110e8,
+	0x110f0, 0x110f9,
+	0x11100, 0x11132,
+	0x11136, 0x1113f,
+	0x11150, 0x11172,
+	0x11176, 0x11176,
+	0x11180, 0x111bf,
+	0x111c1, 0x111c4,
+	0x111d0, 0x111da,
+	0x111dc, 0x111dc,
+	0x11200, 0x11211,
+	0x11213, 0x11234,
+	0x11237, 0x11237,
+	0x1123e, 0x1123e,
+	0x11280, 0x11286,
+	0x11288, 0x11288,
+	0x1128a, 0x1128d,
+	0x1128f, 0x1129d,
+	0x1129f, 0x112a8,
+	0x112b0, 0x112e8,
+	0x112f0, 0x112f9,
+	0x11300, 0x11303,
+	0x11305, 0x1130c,
+	0x1130f, 0x11310,
+	0x11313, 0x11328,
+	0x1132a, 0x11330,
+	0x11332, 0x11333,
+	0x11335, 0x11339,
+	0x1133d, 0x11344,
+	0x11347, 0x11348,
+	0x1134b, 0x1134c,
+	0x11350, 0x11350,
+	0x11357, 0x11357,
+	0x1135d, 0x11363,
+	0x11400, 0x11441,
+	0x11443, 0x11445,
+	0x11447, 0x1144a,
+	0x11450, 0x11459,
+	0x11480, 0x114c1,
+	0x114c4, 0x114c5,
+	0x114c7, 0x114c7,
+	0x114d0, 0x114d9,
+	0x11580, 0x115b5,
+	0x115b8, 0x115be,
+	0x115d8, 0x115dd,
+	0x11600, 0x1163e,
+	0x11640, 0x11640,
+	0x11644, 0x11644,
+	0x11650, 0x11659,
+	0x11680, 0x116b5,
+	0x116c0, 0x116c9,
+	0x11700, 0x11719,
+	0x1171d, 0x1172a,
+	0x11730, 0x11739,
+	0x118a0, 0x118e9,
+	0x118ff, 0x118ff,
+	0x11a00, 0x11a32,
+	0x11a35, 0x11a3e,
+	0x11a50, 0x11a83,
+	0x11a86, 0x11a97,
+	0x11ac0, 0x11af8,
+	0x11c00, 0x11c08,
+	0x11c0a, 0x11c36,
+	0x11c38, 0x11c3e,
+	0x11c40, 0x11c40,
+	0x11c50, 0x11c59,
+	0x11c72, 0x11c8f,
+	0x11c92, 0x11ca7,
+	0x11ca9, 0x11cb6,
+	0x11d00, 0x11d06,
+	0x11d08, 0x11d09,
+	0x11d0b, 0x11d36,
+	0x11d3a, 0x11d3a,
+	0x11d3c, 0x11d3d,
+	0x11d3f, 0x11d41,
+	0x11d43, 0x11d43,
+	0x11d46, 0x11d47,
+	0x11d50, 0x11d59,
+	0x12000, 0x12399,
+	0x12400, 0x1246e,
+	0x12480, 0x12543,
+	0x13000, 0x1342e,
+	0x14400, 0x14646,
+	0x16800, 0x16a38,
+	0x16a40, 0x16a5e,
+	0x16a60, 0x16a69,
+	0x16ad0, 0x16aed,
+	0x16b00, 0x16b36,
+	0x16b40, 0x16b43,
+	0x16b50, 0x16b59,
+	0x16b63, 0x16b77,
+	0x16b7d, 0x16b8f,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f7e,
+	0x16f93, 0x16f9f,
+	0x16fe0, 0x16fe1,
+	0x17000, 0x187ec,
+	0x18800, 0x18af2,
+	0x1b000, 0x1b11e,
+	0x1b170, 0x1b2fb,
+	0x1bc00, 0x1bc6a,
+	0x1bc70, 0x1bc7c,
+	0x1bc80, 0x1bc88,
+	0x1bc90, 0x1bc99,
+	0x1bc9e, 0x1bc9e,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d6c0,
+	0x1d6c2, 0x1d6da,
+	0x1d6dc, 0x1d6fa,
+	0x1d6fc, 0x1d714,
+	0x1d716, 0x1d734,
+	0x1d736, 0x1d74e,
+	0x1d750, 0x1d76e,
+	0x1d770, 0x1d788,
+	0x1d78a, 0x1d7a8,
+	0x1d7aa, 0x1d7c2,
+	0x1d7c4, 0x1d7cb,
+	0x1d7ce, 0x1d7ff,
+	0x1e000, 0x1e006,
+	0x1e008, 0x1e018,
+	0x1e01b, 0x1e021,
+	0x1e023, 0x1e024,
+	0x1e026, 0x1e02a,
+	0x1e800, 0x1e8c4,
+	0x1e900, 0x1e943,
+	0x1e947, 0x1e947,
+	0x1e950, 0x1e959,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x1f130, 0x1f149,
+	0x1f150, 0x1f169,
+	0x1f170, 0x1f189,
+	0x20000, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2b820, 0x2cea1,
+	0x2ceb0, 0x2ebe0,
+	0x2f800, 0x2fa1d,
+}; /* CR_Alnum */
+
+/* 'ASCII': [[:ASCII:]] */
+static const OnigCodePoint CR_ASCII[] = {
+	1,
+	0x0000, 0x007f,
+}; /* CR_ASCII */
+
+/* 'Punct' */
+static const OnigCodePoint CR_Punct[] = {
+	172,
+	0x0021, 0x0023,
+	0x0025, 0x002a,
+	0x002c, 0x002f,
+	0x003a, 0x003b,
+	0x003f, 0x0040,
+	0x005b, 0x005d,
+	0x005f, 0x005f,
+	0x007b, 0x007b,
+	0x007d, 0x007d,
+	0x00a1, 0x00a1,
+	0x00a7, 0x00a7,
+	0x00ab, 0x00ab,
+	0x00b6, 0x00b7,
+	0x00bb, 0x00bb,
+	0x00bf, 0x00bf,
+	0x037e, 0x037e,
+	0x0387, 0x0387,
+	0x055a, 0x055f,
+	0x0589, 0x058a,
+	0x05be, 0x05be,
+	0x05c0, 0x05c0,
+	0x05c3, 0x05c3,
+	0x05c6, 0x05c6,
+	0x05f3, 0x05f4,
+	0x0609, 0x060a,
+	0x060c, 0x060d,
+	0x061b, 0x061b,
+	0x061e, 0x061f,
+	0x066a, 0x066d,
+	0x06d4, 0x06d4,
+	0x0700, 0x070d,
+	0x07f7, 0x07f9,
+	0x0830, 0x083e,
+	0x085e, 0x085e,
+	0x0964, 0x0965,
+	0x0970, 0x0970,
+	0x09fd, 0x09fd,
+	0x0af0, 0x0af0,
+	0x0df4, 0x0df4,
+	0x0e4f, 0x0e4f,
+	0x0e5a, 0x0e5b,
+	0x0f04, 0x0f12,
+	0x0f14, 0x0f14,
+	0x0f3a, 0x0f3d,
+	0x0f85, 0x0f85,
+	0x0fd0, 0x0fd4,
+	0x0fd9, 0x0fda,
+	0x104a, 0x104f,
+	0x10fb, 0x10fb,
+	0x1360, 0x1368,
+	0x1400, 0x1400,
+	0x166d, 0x166e,
+	0x169b, 0x169c,
+	0x16eb, 0x16ed,
+	0x1735, 0x1736,
+	0x17d4, 0x17d6,
+	0x17d8, 0x17da,
+	0x1800, 0x180a,
+	0x1944, 0x1945,
+	0x1a1e, 0x1a1f,
+	0x1aa0, 0x1aa6,
+	0x1aa8, 0x1aad,
+	0x1b5a, 0x1b60,
+	0x1bfc, 0x1bff,
+	0x1c3b, 0x1c3f,
+	0x1c7e, 0x1c7f,
+	0x1cc0, 0x1cc7,
+	0x1cd3, 0x1cd3,
+	0x2010, 0x2027,
+	0x2030, 0x2043,
+	0x2045, 0x2051,
+	0x2053, 0x205e,
+	0x207d, 0x207e,
+	0x208d, 0x208e,
+	0x2308, 0x230b,
+	0x2329, 0x232a,
+	0x2768, 0x2775,
+	0x27c5, 0x27c6,
+	0x27e6, 0x27ef,
+	0x2983, 0x2998,
+	0x29d8, 0x29db,
+	0x29fc, 0x29fd,
+	0x2cf9, 0x2cfc,
+	0x2cfe, 0x2cff,
+	0x2d70, 0x2d70,
+	0x2e00, 0x2e2e,
+	0x2e30, 0x2e49,
+	0x3001, 0x3003,
+	0x3008, 0x3011,
+	0x3014, 0x301f,
+	0x3030, 0x3030,
+	0x303d, 0x303d,
+	0x30a0, 0x30a0,
+	0x30fb, 0x30fb,
+	0xa4fe, 0xa4ff,
+	0xa60d, 0xa60f,
+	0xa673, 0xa673,
+	0xa67e, 0xa67e,
+	0xa6f2, 0xa6f7,
+	0xa874, 0xa877,
+	0xa8ce, 0xa8cf,
+	0xa8f8, 0xa8fa,
+	0xa8fc, 0xa8fc,
+	0xa92e, 0xa92f,
+	0xa95f, 0xa95f,
+	0xa9c1, 0xa9cd,
+	0xa9de, 0xa9df,
+	0xaa5c, 0xaa5f,
+	0xaade, 0xaadf,
+	0xaaf0, 0xaaf1,
+	0xabeb, 0xabeb,
+	0xfd3e, 0xfd3f,
+	0xfe10, 0xfe19,
+	0xfe30, 0xfe52,
+	0xfe54, 0xfe61,
+	0xfe63, 0xfe63,
+	0xfe68, 0xfe68,
+	0xfe6a, 0xfe6b,
+	0xff01, 0xff03,
+	0xff05, 0xff0a,
+	0xff0c, 0xff0f,
+	0xff1a, 0xff1b,
+	0xff1f, 0xff20,
+	0xff3b, 0xff3d,
+	0xff3f, 0xff3f,
+	0xff5b, 0xff5b,
+	0xff5d, 0xff5d,
+	0xff5f, 0xff65,
+	0x10100, 0x10102,
+	0x1039f, 0x1039f,
+	0x103d0, 0x103d0,
+	0x1056f, 0x1056f,
+	0x10857, 0x10857,
+	0x1091f, 0x1091f,
+	0x1093f, 0x1093f,
+	0x10a50, 0x10a58,
+	0x10a7f, 0x10a7f,
+	0x10af0, 0x10af6,
+	0x10b39, 0x10b3f,
+	0x10b99, 0x10b9c,
+	0x11047, 0x1104d,
+	0x110bb, 0x110bc,
+	0x110be, 0x110c1,
+	0x11140, 0x11143,
+	0x11174, 0x11175,
+	0x111c5, 0x111c9,
+	0x111cd, 0x111cd,
+	0x111db, 0x111db,
+	0x111dd, 0x111df,
+	0x11238, 0x1123d,
+	0x112a9, 0x112a9,
+	0x1144b, 0x1144f,
+	0x1145b, 0x1145b,
+	0x1145d, 0x1145d,
+	0x114c6, 0x114c6,
+	0x115c1, 0x115d7,
+	0x11641, 0x11643,
+	0x11660, 0x1166c,
+	0x1173c, 0x1173e,
+	0x11a3f, 0x11a46,
+	0x11a9a, 0x11a9c,
+	0x11a9e, 0x11aa2,
+	0x11c41, 0x11c45,
+	0x11c70, 0x11c71,
+	0x12470, 0x12474,
+	0x16a6e, 0x16a6f,
+	0x16af5, 0x16af5,
+	0x16b37, 0x16b3b,
+	0x16b44, 0x16b44,
+	0x1bc9f, 0x1bc9f,
+	0x1da87, 0x1da8b,
+	0x1e95e, 0x1e95f,
+}; /* CR_Punct */
+
+#ifdef USE_UNICODE_PROPERTIES
+/* 'Any': - */
+static const OnigCodePoint CR_Any[] = {
+	1,
+	0x0000, 0x10ffff,
+}; /* CR_Any */
+
+/* 'Assigned': - */
+static const OnigCodePoint CR_Assigned[] = {
+	649,
+	0x0000, 0x0377,
+	0x037a, 0x037f,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x052f,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x058a,
+	0x058d, 0x058f,
+	0x0591, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x0600, 0x061c,
+	0x061e, 0x070d,
+	0x070f, 0x074a,
+	0x074d, 0x07b1,
+	0x07c0, 0x07fa,
+	0x0800, 0x082d,
+	0x0830, 0x083e,
+	0x0840, 0x085b,
+	0x085e, 0x085e,
+	0x0860, 0x086a,
+	0x08a0, 0x08b4,
+	0x08b6, 0x08bd,
+	0x08d4, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fd,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a75,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0af1,
+	0x0af9, 0x0aff,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3c, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b63,
+	0x0b66, 0x0b77,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd0, 0x0bd0,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bfa,
+	0x0c00, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c39,
+	0x0c3d, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c58, 0x0c5a,
+	0x0c60, 0x0c63,
+	0x0c66, 0x0c6f,
+	0x0c78, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbc, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce3,
+	0x0ce6, 0x0cef,
+	0x0cf1, 0x0cf2,
+	0x0d00, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4f,
+	0x0d54, 0x0d63,
+	0x0d66, 0x0d7f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0de6, 0x0def,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f71, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fbe, 0x0fcc,
+	0x0fce, 0x0fda,
+	0x1000, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135d, 0x137c,
+	0x1380, 0x1399,
+	0x13a0, 0x13f5,
+	0x13f8, 0x13fd,
+	0x1400, 0x169c,
+	0x16a0, 0x16f8,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+	0x1720, 0x1736,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17dd,
+	0x17e0, 0x17e9,
+	0x17f0, 0x17f9,
+	0x1800, 0x180e,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191e,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1940, 0x1940,
+	0x1944, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19da,
+	0x19de, 0x1a1b,
+	0x1a1e, 0x1a5e,
+	0x1a60, 0x1a7c,
+	0x1a7f, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1aa0, 0x1aad,
+	0x1ab0, 0x1abe,
+	0x1b00, 0x1b4b,
+	0x1b50, 0x1b7c,
+	0x1b80, 0x1bf3,
+	0x1bfc, 0x1c37,
+	0x1c3b, 0x1c49,
+	0x1c4d, 0x1c88,
+	0x1cc0, 0x1cc7,
+	0x1cd0, 0x1cf9,
+	0x1d00, 0x1df9,
+	0x1dfb, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x2064,
+	0x2066, 0x2071,
+	0x2074, 0x208e,
+	0x2090, 0x209c,
+	0x20a0, 0x20bf,
+	0x20d0, 0x20f0,
+	0x2100, 0x218b,
+	0x2190, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x2b73,
+	0x2b76, 0x2b95,
+	0x2b98, 0x2bb9,
+	0x2bbd, 0x2bc8,
+	0x2bca, 0x2bd2,
+	0x2bec, 0x2bef,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2cf3,
+	0x2cf9, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d70,
+	0x2d7f, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2de0, 0x2e49,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3000, 0x303f,
+	0x3041, 0x3096,
+	0x3099, 0x30ff,
+	0x3105, 0x312e,
+	0x3131, 0x318e,
+	0x3190, 0x31ba,
+	0x31c0, 0x31e3,
+	0x31f0, 0x321e,
+	0x3220, 0x32fe,
+	0x3300, 0x4db5,
+	0x4dc0, 0x9fea,
+	0xa000, 0xa48c,
+	0xa490, 0xa4c6,
+	0xa4d0, 0xa62b,
+	0xa640, 0xa6f7,
+	0xa700, 0xa7ae,
+	0xa7b0, 0xa7b7,
+	0xa7f7, 0xa82b,
+	0xa830, 0xa839,
+	0xa840, 0xa877,
+	0xa880, 0xa8c5,
+	0xa8ce, 0xa8d9,
+	0xa8e0, 0xa8fd,
+	0xa900, 0xa953,
+	0xa95f, 0xa97c,
+	0xa980, 0xa9cd,
+	0xa9cf, 0xa9d9,
+	0xa9de, 0xa9fe,
+	0xaa00, 0xaa36,
+	0xaa40, 0xaa4d,
+	0xaa50, 0xaa59,
+	0xaa5c, 0xaac2,
+	0xaadb, 0xaaf6,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xab30, 0xab65,
+	0xab70, 0xabed,
+	0xabf0, 0xabf9,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xd800, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbc1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdf0, 0xfdfd,
+	0xfe00, 0xfe19,
+	0xfe20, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfff9, 0xfffd,
+	0x10000, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10100, 0x10102,
+	0x10107, 0x10133,
+	0x10137, 0x1018e,
+	0x10190, 0x1019b,
+	0x101a0, 0x101a0,
+	0x101d0, 0x101fd,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x102e0, 0x102fb,
+	0x10300, 0x10323,
+	0x1032d, 0x1034a,
+	0x10350, 0x1037a,
+	0x10380, 0x1039d,
+	0x1039f, 0x103c3,
+	0x103c8, 0x103d5,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x104b0, 0x104d3,
+	0x104d8, 0x104fb,
+	0x10500, 0x10527,
+	0x10530, 0x10563,
+	0x1056f, 0x1056f,
+	0x10600, 0x10736,
+	0x10740, 0x10755,
+	0x10760, 0x10767,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10857, 0x1089e,
+	0x108a7, 0x108af,
+	0x108e0, 0x108f2,
+	0x108f4, 0x108f5,
+	0x108fb, 0x1091b,
+	0x1091f, 0x10939,
+	0x1093f, 0x1093f,
+	0x10980, 0x109b7,
+	0x109bc, 0x109cf,
+	0x109d2, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a47,
+	0x10a50, 0x10a58,
+	0x10a60, 0x10a9f,
+	0x10ac0, 0x10ae6,
+	0x10aeb, 0x10af6,
+	0x10b00, 0x10b35,
+	0x10b39, 0x10b55,
+	0x10b58, 0x10b72,
+	0x10b78, 0x10b91,
+	0x10b99, 0x10b9c,
+	0x10ba9, 0x10baf,
+	0x10c00, 0x10c48,
+	0x10c80, 0x10cb2,
+	0x10cc0, 0x10cf2,
+	0x10cfa, 0x10cff,
+	0x10e60, 0x10e7e,
+	0x11000, 0x1104d,
+	0x11052, 0x1106f,
+	0x1107f, 0x110c1,
+	0x110d0, 0x110e8,
+	0x110f0, 0x110f9,
+	0x11100, 0x11134,
+	0x11136, 0x11143,
+	0x11150, 0x11176,
+	0x11180, 0x111cd,
+	0x111d0, 0x111df,
+	0x111e1, 0x111f4,
+	0x11200, 0x11211,
+	0x11213, 0x1123e,
+	0x11280, 0x11286,
+	0x11288, 0x11288,
+	0x1128a, 0x1128d,
+	0x1128f, 0x1129d,
+	0x1129f, 0x112a9,
+	0x112b0, 0x112ea,
+	0x112f0, 0x112f9,
+	0x11300, 0x11303,
+	0x11305, 0x1130c,
+	0x1130f, 0x11310,
+	0x11313, 0x11328,
+	0x1132a, 0x11330,
+	0x11332, 0x11333,
+	0x11335, 0x11339,
+	0x1133c, 0x11344,
+	0x11347, 0x11348,
+	0x1134b, 0x1134d,
+	0x11350, 0x11350,
+	0x11357, 0x11357,
+	0x1135d, 0x11363,
+	0x11366, 0x1136c,
+	0x11370, 0x11374,
+	0x11400, 0x11459,
+	0x1145b, 0x1145b,
+	0x1145d, 0x1145d,
+	0x11480, 0x114c7,
+	0x114d0, 0x114d9,
+	0x11580, 0x115b5,
+	0x115b8, 0x115dd,
+	0x11600, 0x11644,
+	0x11650, 0x11659,
+	0x11660, 0x1166c,
+	0x11680, 0x116b7,
+	0x116c0, 0x116c9,
+	0x11700, 0x11719,
+	0x1171d, 0x1172b,
+	0x11730, 0x1173f,
+	0x118a0, 0x118f2,
+	0x118ff, 0x118ff,
+	0x11a00, 0x11a47,
+	0x11a50, 0x11a83,
+	0x11a86, 0x11a9c,
+	0x11a9e, 0x11aa2,
+	0x11ac0, 0x11af8,
+	0x11c00, 0x11c08,
+	0x11c0a, 0x11c36,
+	0x11c38, 0x11c45,
+	0x11c50, 0x11c6c,
+	0x11c70, 0x11c8f,
+	0x11c92, 0x11ca7,
+	0x11ca9, 0x11cb6,
+	0x11d00, 0x11d06,
+	0x11d08, 0x11d09,
+	0x11d0b, 0x11d36,
+	0x11d3a, 0x11d3a,
+	0x11d3c, 0x11d3d,
+	0x11d3f, 0x11d47,
+	0x11d50, 0x11d59,
+	0x12000, 0x12399,
+	0x12400, 0x1246e,
+	0x12470, 0x12474,
+	0x12480, 0x12543,
+	0x13000, 0x1342e,
+	0x14400, 0x14646,
+	0x16800, 0x16a38,
+	0x16a40, 0x16a5e,
+	0x16a60, 0x16a69,
+	0x16a6e, 0x16a6f,
+	0x16ad0, 0x16aed,
+	0x16af0, 0x16af5,
+	0x16b00, 0x16b45,
+	0x16b50, 0x16b59,
+	0x16b5b, 0x16b61,
+	0x16b63, 0x16b77,
+	0x16b7d, 0x16b8f,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f7e,
+	0x16f8f, 0x16f9f,
+	0x16fe0, 0x16fe1,
+	0x17000, 0x187ec,
+	0x18800, 0x18af2,
+	0x1b000, 0x1b11e,
+	0x1b170, 0x1b2fb,
+	0x1bc00, 0x1bc6a,
+	0x1bc70, 0x1bc7c,
+	0x1bc80, 0x1bc88,
+	0x1bc90, 0x1bc99,
+	0x1bc9c, 0x1bca3,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d129, 0x1d1e8,
+	0x1d200, 0x1d245,
+	0x1d300, 0x1d356,
+	0x1d360, 0x1d371,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d7cb,
+	0x1d7ce, 0x1da8b,
+	0x1da9b, 0x1da9f,
+	0x1daa1, 0x1daaf,
+	0x1e000, 0x1e006,
+	0x1e008, 0x1e018,
+	0x1e01b, 0x1e021,
+	0x1e023, 0x1e024,
+	0x1e026, 0x1e02a,
+	0x1e800, 0x1e8c4,
+	0x1e8c7, 0x1e8d6,
+	0x1e900, 0x1e94a,
+	0x1e950, 0x1e959,
+	0x1e95e, 0x1e95f,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x1eef0, 0x1eef1,
+	0x1f000, 0x1f02b,
+	0x1f030, 0x1f093,
+	0x1f0a0, 0x1f0ae,
+	0x1f0b1, 0x1f0bf,
+	0x1f0c1, 0x1f0cf,
+	0x1f0d1, 0x1f0f5,
+	0x1f100, 0x1f10c,
+	0x1f110, 0x1f12e,
+	0x1f130, 0x1f16b,
+	0x1f170, 0x1f1ac,
+	0x1f1e6, 0x1f202,
+	0x1f210, 0x1f23b,
+	0x1f240, 0x1f248,
+	0x1f250, 0x1f251,
+	0x1f260, 0x1f265,
+	0x1f300, 0x1f6d4,
+	0x1f6e0, 0x1f6ec,
+	0x1f6f0, 0x1f6f8,
+	0x1f700, 0x1f773,
+	0x1f780, 0x1f7d4,
+	0x1f800, 0x1f80b,
+	0x1f810, 0x1f847,
+	0x1f850, 0x1f859,
+	0x1f860, 0x1f887,
+	0x1f890, 0x1f8ad,
+	0x1f900, 0x1f90b,
+	0x1f910, 0x1f93e,
+	0x1f940, 0x1f94c,
+	0x1f950, 0x1f96b,
+	0x1f980, 0x1f997,
+	0x1f9c0, 0x1f9c0,
+	0x1f9d0, 0x1f9e6,
+	0x20000, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2b820, 0x2cea1,
+	0x2ceb0, 0x2ebe0,
+	0x2f800, 0x2fa1d,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+	0xe0100, 0xe01ef,
+	0xf0000, 0xffffd,
+	0x100000, 0x10fffd,
+}; /* CR_Assigned */
+
+/* 'C': Major Category */
+static const OnigCodePoint CR_C[] = {
+	653,
+	0x0000, 0x001f,
+	0x007f, 0x009f,
+	0x00ad, 0x00ad,
+	0x0378, 0x0379,
+	0x0380, 0x0383,
+	0x038b, 0x038b,
+	0x038d, 0x038d,
+	0x03a2, 0x03a2,
+	0x0530, 0x0530,
+	0x0557, 0x0558,
+	0x0560, 0x0560,
+	0x0588, 0x0588,
+	0x058b, 0x058c,
+	0x0590, 0x0590,
+	0x05c8, 0x05cf,
+	0x05eb, 0x05ef,
+	0x05f5, 0x0605,
+	0x061c, 0x061d,
+	0x06dd, 0x06dd,
+	0x070e, 0x070f,
+	0x074b, 0x074c,
+	0x07b2, 0x07bf,
+	0x07fb, 0x07ff,
+	0x082e, 0x082f,
+	0x083f, 0x083f,
+	0x085c, 0x085d,
+	0x085f, 0x085f,
+	0x086b, 0x089f,
+	0x08b5, 0x08b5,
+	0x08be, 0x08d3,
+	0x08e2, 0x08e2,
+	0x0984, 0x0984,
+	0x098d, 0x098e,
+	0x0991, 0x0992,
+	0x09a9, 0x09a9,
+	0x09b1, 0x09b1,
+	0x09b3, 0x09b5,
+	0x09ba, 0x09bb,
+	0x09c5, 0x09c6,
+	0x09c9, 0x09ca,
+	0x09cf, 0x09d6,
+	0x09d8, 0x09db,
+	0x09de, 0x09de,
+	0x09e4, 0x09e5,
+	0x09fe, 0x0a00,
+	0x0a04, 0x0a04,
+	0x0a0b, 0x0a0e,
+	0x0a11, 0x0a12,
+	0x0a29, 0x0a29,
+	0x0a31, 0x0a31,
+	0x0a34, 0x0a34,
+	0x0a37, 0x0a37,
+	0x0a3a, 0x0a3b,
+	0x0a3d, 0x0a3d,
+	0x0a43, 0x0a46,
+	0x0a49, 0x0a4a,
+	0x0a4e, 0x0a50,
+	0x0a52, 0x0a58,
+	0x0a5d, 0x0a5d,
+	0x0a5f, 0x0a65,
+	0x0a76, 0x0a80,
+	0x0a84, 0x0a84,
+	0x0a8e, 0x0a8e,
+	0x0a92, 0x0a92,
+	0x0aa9, 0x0aa9,
+	0x0ab1, 0x0ab1,
+	0x0ab4, 0x0ab4,
+	0x0aba, 0x0abb,
+	0x0ac6, 0x0ac6,
+	0x0aca, 0x0aca,
+	0x0ace, 0x0acf,
+	0x0ad1, 0x0adf,
+	0x0ae4, 0x0ae5,
+	0x0af2, 0x0af8,
+	0x0b00, 0x0b00,
+	0x0b04, 0x0b04,
+	0x0b0d, 0x0b0e,
+	0x0b11, 0x0b12,
+	0x0b29, 0x0b29,
+	0x0b31, 0x0b31,
+	0x0b34, 0x0b34,
+	0x0b3a, 0x0b3b,
+	0x0b45, 0x0b46,
+	0x0b49, 0x0b4a,
+	0x0b4e, 0x0b55,
+	0x0b58, 0x0b5b,
+	0x0b5e, 0x0b5e,
+	0x0b64, 0x0b65,
+	0x0b78, 0x0b81,
+	0x0b84, 0x0b84,
+	0x0b8b, 0x0b8d,
+	0x0b91, 0x0b91,
+	0x0b96, 0x0b98,
+	0x0b9b, 0x0b9b,
+	0x0b9d, 0x0b9d,
+	0x0ba0, 0x0ba2,
+	0x0ba5, 0x0ba7,
+	0x0bab, 0x0bad,
+	0x0bba, 0x0bbd,
+	0x0bc3, 0x0bc5,
+	0x0bc9, 0x0bc9,
+	0x0bce, 0x0bcf,
+	0x0bd1, 0x0bd6,
+	0x0bd8, 0x0be5,
+	0x0bfb, 0x0bff,
+	0x0c04, 0x0c04,
+	0x0c0d, 0x0c0d,
+	0x0c11, 0x0c11,
+	0x0c29, 0x0c29,
+	0x0c3a, 0x0c3c,
+	0x0c45, 0x0c45,
+	0x0c49, 0x0c49,
+	0x0c4e, 0x0c54,
+	0x0c57, 0x0c57,
+	0x0c5b, 0x0c5f,
+	0x0c64, 0x0c65,
+	0x0c70, 0x0c77,
+	0x0c84, 0x0c84,
+	0x0c8d, 0x0c8d,
+	0x0c91, 0x0c91,
+	0x0ca9, 0x0ca9,
+	0x0cb4, 0x0cb4,
+	0x0cba, 0x0cbb,
+	0x0cc5, 0x0cc5,
+	0x0cc9, 0x0cc9,
+	0x0cce, 0x0cd4,
+	0x0cd7, 0x0cdd,
+	0x0cdf, 0x0cdf,
+	0x0ce4, 0x0ce5,
+	0x0cf0, 0x0cf0,
+	0x0cf3, 0x0cff,
+	0x0d04, 0x0d04,
+	0x0d0d, 0x0d0d,
+	0x0d11, 0x0d11,
+	0x0d45, 0x0d45,
+	0x0d49, 0x0d49,
+	0x0d50, 0x0d53,
+	0x0d64, 0x0d65,
+	0x0d80, 0x0d81,
+	0x0d84, 0x0d84,
+	0x0d97, 0x0d99,
+	0x0db2, 0x0db2,
+	0x0dbc, 0x0dbc,
+	0x0dbe, 0x0dbf,
+	0x0dc7, 0x0dc9,
+	0x0dcb, 0x0dce,
+	0x0dd5, 0x0dd5,
+	0x0dd7, 0x0dd7,
+	0x0de0, 0x0de5,
+	0x0df0, 0x0df1,
+	0x0df5, 0x0e00,
+	0x0e3b, 0x0e3e,
+	0x0e5c, 0x0e80,
+	0x0e83, 0x0e83,
+	0x0e85, 0x0e86,
+	0x0e89, 0x0e89,
+	0x0e8b, 0x0e8c,
+	0x0e8e, 0x0e93,
+	0x0e98, 0x0e98,
+	0x0ea0, 0x0ea0,
+	0x0ea4, 0x0ea4,
+	0x0ea6, 0x0ea6,
+	0x0ea8, 0x0ea9,
+	0x0eac, 0x0eac,
+	0x0eba, 0x0eba,
+	0x0ebe, 0x0ebf,
+	0x0ec5, 0x0ec5,
+	0x0ec7, 0x0ec7,
+	0x0ece, 0x0ecf,
+	0x0eda, 0x0edb,
+	0x0ee0, 0x0eff,
+	0x0f48, 0x0f48,
+	0x0f6d, 0x0f70,
+	0x0f98, 0x0f98,
+	0x0fbd, 0x0fbd,
+	0x0fcd, 0x0fcd,
+	0x0fdb, 0x0fff,
+	0x10c6, 0x10c6,
+	0x10c8, 0x10cc,
+	0x10ce, 0x10cf,
+	0x1249, 0x1249,
+	0x124e, 0x124f,
+	0x1257, 0x1257,
+	0x1259, 0x1259,
+	0x125e, 0x125f,
+	0x1289, 0x1289,
+	0x128e, 0x128f,
+	0x12b1, 0x12b1,
+	0x12b6, 0x12b7,
+	0x12bf, 0x12bf,
+	0x12c1, 0x12c1,
+	0x12c6, 0x12c7,
+	0x12d7, 0x12d7,
+	0x1311, 0x1311,
+	0x1316, 0x1317,
+	0x135b, 0x135c,
+	0x137d, 0x137f,
+	0x139a, 0x139f,
+	0x13f6, 0x13f7,
+	0x13fe, 0x13ff,
+	0x169d, 0x169f,
+	0x16f9, 0x16ff,
+	0x170d, 0x170d,
+	0x1715, 0x171f,
+	0x1737, 0x173f,
+	0x1754, 0x175f,
+	0x176d, 0x176d,
+	0x1771, 0x1771,
+	0x1774, 0x177f,
+	0x17de, 0x17df,
+	0x17ea, 0x17ef,
+	0x17fa, 0x17ff,
+	0x180e, 0x180f,
+	0x181a, 0x181f,
+	0x1878, 0x187f,
+	0x18ab, 0x18af,
+	0x18f6, 0x18ff,
+	0x191f, 0x191f,
+	0x192c, 0x192f,
+	0x193c, 0x193f,
+	0x1941, 0x1943,
+	0x196e, 0x196f,
+	0x1975, 0x197f,
+	0x19ac, 0x19af,
+	0x19ca, 0x19cf,
+	0x19db, 0x19dd,
+	0x1a1c, 0x1a1d,
+	0x1a5f, 0x1a5f,
+	0x1a7d, 0x1a7e,
+	0x1a8a, 0x1a8f,
+	0x1a9a, 0x1a9f,
+	0x1aae, 0x1aaf,
+	0x1abf, 0x1aff,
+	0x1b4c, 0x1b4f,
+	0x1b7d, 0x1b7f,
+	0x1bf4, 0x1bfb,
+	0x1c38, 0x1c3a,
+	0x1c4a, 0x1c4c,
+	0x1c89, 0x1cbf,
+	0x1cc8, 0x1ccf,
+	0x1cfa, 0x1cff,
+	0x1dfa, 0x1dfa,
+	0x1f16, 0x1f17,
+	0x1f1e, 0x1f1f,
+	0x1f46, 0x1f47,
+	0x1f4e, 0x1f4f,
+	0x1f58, 0x1f58,
+	0x1f5a, 0x1f5a,
+	0x1f5c, 0x1f5c,
+	0x1f5e, 0x1f5e,
+	0x1f7e, 0x1f7f,
+	0x1fb5, 0x1fb5,
+	0x1fc5, 0x1fc5,
+	0x1fd4, 0x1fd5,
+	0x1fdc, 0x1fdc,
+	0x1ff0, 0x1ff1,
+	0x1ff5, 0x1ff5,
+	0x1fff, 0x1fff,
+	0x200b, 0x200f,
+	0x202a, 0x202e,
+	0x2060, 0x206f,
+	0x2072, 0x2073,
+	0x208f, 0x208f,
+	0x209d, 0x209f,
+	0x20c0, 0x20cf,
+	0x20f1, 0x20ff,
+	0x218c, 0x218f,
+	0x2427, 0x243f,
+	0x244b, 0x245f,
+	0x2b74, 0x2b75,
+	0x2b96, 0x2b97,
+	0x2bba, 0x2bbc,
+	0x2bc9, 0x2bc9,
+	0x2bd3, 0x2beb,
+	0x2bf0, 0x2bff,
+	0x2c2f, 0x2c2f,
+	0x2c5f, 0x2c5f,
+	0x2cf4, 0x2cf8,
+	0x2d26, 0x2d26,
+	0x2d28, 0x2d2c,
+	0x2d2e, 0x2d2f,
+	0x2d68, 0x2d6e,
+	0x2d71, 0x2d7e,
+	0x2d97, 0x2d9f,
+	0x2da7, 0x2da7,
+	0x2daf, 0x2daf,
+	0x2db7, 0x2db7,
+	0x2dbf, 0x2dbf,
+	0x2dc7, 0x2dc7,
+	0x2dcf, 0x2dcf,
+	0x2dd7, 0x2dd7,
+	0x2ddf, 0x2ddf,
+	0x2e4a, 0x2e7f,
+	0x2e9a, 0x2e9a,
+	0x2ef4, 0x2eff,
+	0x2fd6, 0x2fef,
+	0x2ffc, 0x2fff,
+	0x3040, 0x3040,
+	0x3097, 0x3098,
+	0x3100, 0x3104,
+	0x312f, 0x3130,
+	0x318f, 0x318f,
+	0x31bb, 0x31bf,
+	0x31e4, 0x31ef,
+	0x321f, 0x321f,
+	0x32ff, 0x32ff,
+	0x4db6, 0x4dbf,
+	0x9feb, 0x9fff,
+	0xa48d, 0xa48f,
+	0xa4c7, 0xa4cf,
+	0xa62c, 0xa63f,
+	0xa6f8, 0xa6ff,
+	0xa7af, 0xa7af,
+	0xa7b8, 0xa7f6,
+	0xa82c, 0xa82f,
+	0xa83a, 0xa83f,
+	0xa878, 0xa87f,
+	0xa8c6, 0xa8cd,
+	0xa8da, 0xa8df,
+	0xa8fe, 0xa8ff,
+	0xa954, 0xa95e,
+	0xa97d, 0xa97f,
+	0xa9ce, 0xa9ce,
+	0xa9da, 0xa9dd,
+	0xa9ff, 0xa9ff,
+	0xaa37, 0xaa3f,
+	0xaa4e, 0xaa4f,
+	0xaa5a, 0xaa5b,
+	0xaac3, 0xaada,
+	0xaaf7, 0xab00,
+	0xab07, 0xab08,
+	0xab0f, 0xab10,
+	0xab17, 0xab1f,
+	0xab27, 0xab27,
+	0xab2f, 0xab2f,
+	0xab66, 0xab6f,
+	0xabee, 0xabef,
+	0xabfa, 0xabff,
+	0xd7a4, 0xd7af,
+	0xd7c7, 0xd7ca,
+	0xd7fc, 0xf8ff,
+	0xfa6e, 0xfa6f,
+	0xfada, 0xfaff,
+	0xfb07, 0xfb12,
+	0xfb18, 0xfb1c,
+	0xfb37, 0xfb37,
+	0xfb3d, 0xfb3d,
+	0xfb3f, 0xfb3f,
+	0xfb42, 0xfb42,
+	0xfb45, 0xfb45,
+	0xfbc2, 0xfbd2,
+	0xfd40, 0xfd4f,
+	0xfd90, 0xfd91,
+	0xfdc8, 0xfdef,
+	0xfdfe, 0xfdff,
+	0xfe1a, 0xfe1f,
+	0xfe53, 0xfe53,
+	0xfe67, 0xfe67,
+	0xfe6c, 0xfe6f,
+	0xfe75, 0xfe75,
+	0xfefd, 0xff00,
+	0xffbf, 0xffc1,
+	0xffc8, 0xffc9,
+	0xffd0, 0xffd1,
+	0xffd8, 0xffd9,
+	0xffdd, 0xffdf,
+	0xffe7, 0xffe7,
+	0xffef, 0xfffb,
+	0xfffe, 0xffff,
+	0x1000c, 0x1000c,
+	0x10027, 0x10027,
+	0x1003b, 0x1003b,
+	0x1003e, 0x1003e,
+	0x1004e, 0x1004f,
+	0x1005e, 0x1007f,
+	0x100fb, 0x100ff,
+	0x10103, 0x10106,
+	0x10134, 0x10136,
+	0x1018f, 0x1018f,
+	0x1019c, 0x1019f,
+	0x101a1, 0x101cf,
+	0x101fe, 0x1027f,
+	0x1029d, 0x1029f,
+	0x102d1, 0x102df,
+	0x102fc, 0x102ff,
+	0x10324, 0x1032c,
+	0x1034b, 0x1034f,
+	0x1037b, 0x1037f,
+	0x1039e, 0x1039e,
+	0x103c4, 0x103c7,
+	0x103d6, 0x103ff,
+	0x1049e, 0x1049f,
+	0x104aa, 0x104af,
+	0x104d4, 0x104d7,
+	0x104fc, 0x104ff,
+	0x10528, 0x1052f,
+	0x10564, 0x1056e,
+	0x10570, 0x105ff,
+	0x10737, 0x1073f,
+	0x10756, 0x1075f,
+	0x10768, 0x107ff,
+	0x10806, 0x10807,
+	0x10809, 0x10809,
+	0x10836, 0x10836,
+	0x10839, 0x1083b,
+	0x1083d, 0x1083e,
+	0x10856, 0x10856,
+	0x1089f, 0x108a6,
+	0x108b0, 0x108df,
+	0x108f3, 0x108f3,
+	0x108f6, 0x108fa,
+	0x1091c, 0x1091e,
+	0x1093a, 0x1093e,
+	0x10940, 0x1097f,
+	0x109b8, 0x109bb,
+	0x109d0, 0x109d1,
+	0x10a04, 0x10a04,
+	0x10a07, 0x10a0b,
+	0x10a14, 0x10a14,
+	0x10a18, 0x10a18,
+	0x10a34, 0x10a37,
+	0x10a3b, 0x10a3e,
+	0x10a48, 0x10a4f,
+	0x10a59, 0x10a5f,
+	0x10aa0, 0x10abf,
+	0x10ae7, 0x10aea,
+	0x10af7, 0x10aff,
+	0x10b36, 0x10b38,
+	0x10b56, 0x10b57,
+	0x10b73, 0x10b77,
+	0x10b92, 0x10b98,
+	0x10b9d, 0x10ba8,
+	0x10bb0, 0x10bff,
+	0x10c49, 0x10c7f,
+	0x10cb3, 0x10cbf,
+	0x10cf3, 0x10cf9,
+	0x10d00, 0x10e5f,
+	0x10e7f, 0x10fff,
+	0x1104e, 0x11051,
+	0x11070, 0x1107e,
+	0x110bd, 0x110bd,
+	0x110c2, 0x110cf,
+	0x110e9, 0x110ef,
+	0x110fa, 0x110ff,
+	0x11135, 0x11135,
+	0x11144, 0x1114f,
+	0x11177, 0x1117f,
+	0x111ce, 0x111cf,
+	0x111e0, 0x111e0,
+	0x111f5, 0x111ff,
+	0x11212, 0x11212,
+	0x1123f, 0x1127f,
+	0x11287, 0x11287,
+	0x11289, 0x11289,
+	0x1128e, 0x1128e,
+	0x1129e, 0x1129e,
+	0x112aa, 0x112af,
+	0x112eb, 0x112ef,
+	0x112fa, 0x112ff,
+	0x11304, 0x11304,
+	0x1130d, 0x1130e,
+	0x11311, 0x11312,
+	0x11329, 0x11329,
+	0x11331, 0x11331,
+	0x11334, 0x11334,
+	0x1133a, 0x1133b,
+	0x11345, 0x11346,
+	0x11349, 0x1134a,
+	0x1134e, 0x1134f,
+	0x11351, 0x11356,
+	0x11358, 0x1135c,
+	0x11364, 0x11365,
+	0x1136d, 0x1136f,
+	0x11375, 0x113ff,
+	0x1145a, 0x1145a,
+	0x1145c, 0x1145c,
+	0x1145e, 0x1147f,
+	0x114c8, 0x114cf,
+	0x114da, 0x1157f,
+	0x115b6, 0x115b7,
+	0x115de, 0x115ff,
+	0x11645, 0x1164f,
+	0x1165a, 0x1165f,
+	0x1166d, 0x1167f,
+	0x116b8, 0x116bf,
+	0x116ca, 0x116ff,
+	0x1171a, 0x1171c,
+	0x1172c, 0x1172f,
+	0x11740, 0x1189f,
+	0x118f3, 0x118fe,
+	0x11900, 0x119ff,
+	0x11a48, 0x11a4f,
+	0x11a84, 0x11a85,
+	0x11a9d, 0x11a9d,
+	0x11aa3, 0x11abf,
+	0x11af9, 0x11bff,
+	0x11c09, 0x11c09,
+	0x11c37, 0x11c37,
+	0x11c46, 0x11c4f,
+	0x11c6d, 0x11c6f,
+	0x11c90, 0x11c91,
+	0x11ca8, 0x11ca8,
+	0x11cb7, 0x11cff,
+	0x11d07, 0x11d07,
+	0x11d0a, 0x11d0a,
+	0x11d37, 0x11d39,
+	0x11d3b, 0x11d3b,
+	0x11d3e, 0x11d3e,
+	0x11d48, 0x11d4f,
+	0x11d5a, 0x11fff,
+	0x1239a, 0x123ff,
+	0x1246f, 0x1246f,
+	0x12475, 0x1247f,
+	0x12544, 0x12fff,
+	0x1342f, 0x143ff,
+	0x14647, 0x167ff,
+	0x16a39, 0x16a3f,
+	0x16a5f, 0x16a5f,
+	0x16a6a, 0x16a6d,
+	0x16a70, 0x16acf,
+	0x16aee, 0x16aef,
+	0x16af6, 0x16aff,
+	0x16b46, 0x16b4f,
+	0x16b5a, 0x16b5a,
+	0x16b62, 0x16b62,
+	0x16b78, 0x16b7c,
+	0x16b90, 0x16eff,
+	0x16f45, 0x16f4f,
+	0x16f7f, 0x16f8e,
+	0x16fa0, 0x16fdf,
+	0x16fe2, 0x16fff,
+	0x187ed, 0x187ff,
+	0x18af3, 0x1afff,
+	0x1b11f, 0x1b16f,
+	0x1b2fc, 0x1bbff,
+	0x1bc6b, 0x1bc6f,
+	0x1bc7d, 0x1bc7f,
+	0x1bc89, 0x1bc8f,
+	0x1bc9a, 0x1bc9b,
+	0x1bca0, 0x1cfff,
+	0x1d0f6, 0x1d0ff,
+	0x1d127, 0x1d128,
+	0x1d173, 0x1d17a,
+	0x1d1e9, 0x1d1ff,
+	0x1d246, 0x1d2ff,
+	0x1d357, 0x1d35f,
+	0x1d372, 0x1d3ff,
+	0x1d455, 0x1d455,
+	0x1d49d, 0x1d49d,
+	0x1d4a0, 0x1d4a1,
+	0x1d4a3, 0x1d4a4,
+	0x1d4a7, 0x1d4a8,
+	0x1d4ad, 0x1d4ad,
+	0x1d4ba, 0x1d4ba,
+	0x1d4bc, 0x1d4bc,
+	0x1d4c4, 0x1d4c4,
+	0x1d506, 0x1d506,
+	0x1d50b, 0x1d50c,
+	0x1d515, 0x1d515,
+	0x1d51d, 0x1d51d,
+	0x1d53a, 0x1d53a,
+	0x1d53f, 0x1d53f,
+	0x1d545, 0x1d545,
+	0x1d547, 0x1d549,
+	0x1d551, 0x1d551,
+	0x1d6a6, 0x1d6a7,
+	0x1d7cc, 0x1d7cd,
+	0x1da8c, 0x1da9a,
+	0x1daa0, 0x1daa0,
+	0x1dab0, 0x1dfff,
+	0x1e007, 0x1e007,
+	0x1e019, 0x1e01a,
+	0x1e022, 0x1e022,
+	0x1e025, 0x1e025,
+	0x1e02b, 0x1e7ff,
+	0x1e8c5, 0x1e8c6,
+	0x1e8d7, 0x1e8ff,
+	0x1e94b, 0x1e94f,
+	0x1e95a, 0x1e95d,
+	0x1e960, 0x1edff,
+	0x1ee04, 0x1ee04,
+	0x1ee20, 0x1ee20,
+	0x1ee23, 0x1ee23,
+	0x1ee25, 0x1ee26,
+	0x1ee28, 0x1ee28,
+	0x1ee33, 0x1ee33,
+	0x1ee38, 0x1ee38,
+	0x1ee3a, 0x1ee3a,
+	0x1ee3c, 0x1ee41,
+	0x1ee43, 0x1ee46,
+	0x1ee48, 0x1ee48,
+	0x1ee4a, 0x1ee4a,
+	0x1ee4c, 0x1ee4c,
+	0x1ee50, 0x1ee50,
+	0x1ee53, 0x1ee53,
+	0x1ee55, 0x1ee56,
+	0x1ee58, 0x1ee58,
+	0x1ee5a, 0x1ee5a,
+	0x1ee5c, 0x1ee5c,
+	0x1ee5e, 0x1ee5e,
+	0x1ee60, 0x1ee60,
+	0x1ee63, 0x1ee63,
+	0x1ee65, 0x1ee66,
+	0x1ee6b, 0x1ee6b,
+	0x1ee73, 0x1ee73,
+	0x1ee78, 0x1ee78,
+	0x1ee7d, 0x1ee7d,
+	0x1ee7f, 0x1ee7f,
+	0x1ee8a, 0x1ee8a,
+	0x1ee9c, 0x1eea0,
+	0x1eea4, 0x1eea4,
+	0x1eeaa, 0x1eeaa,
+	0x1eebc, 0x1eeef,
+	0x1eef2, 0x1efff,
+	0x1f02c, 0x1f02f,
+	0x1f094, 0x1f09f,
+	0x1f0af, 0x1f0b0,
+	0x1f0c0, 0x1f0c0,
+	0x1f0d0, 0x1f0d0,
+	0x1f0f6, 0x1f0ff,
+	0x1f10d, 0x1f10f,
+	0x1f12f, 0x1f12f,
+	0x1f16c, 0x1f16f,
+	0x1f1ad, 0x1f1e5,
+	0x1f203, 0x1f20f,
+	0x1f23c, 0x1f23f,
+	0x1f249, 0x1f24f,
+	0x1f252, 0x1f25f,
+	0x1f266, 0x1f2ff,
+	0x1f6d5, 0x1f6df,
+	0x1f6ed, 0x1f6ef,
+	0x1f6f9, 0x1f6ff,
+	0x1f774, 0x1f77f,
+	0x1f7d5, 0x1f7ff,
+	0x1f80c, 0x1f80f,
+	0x1f848, 0x1f84f,
+	0x1f85a, 0x1f85f,
+	0x1f888, 0x1f88f,
+	0x1f8ae, 0x1f8ff,
+	0x1f90c, 0x1f90f,
+	0x1f93f, 0x1f93f,
+	0x1f94d, 0x1f94f,
+	0x1f96c, 0x1f97f,
+	0x1f998, 0x1f9bf,
+	0x1f9c1, 0x1f9cf,
+	0x1f9e7, 0x1ffff,
+	0x2a6d7, 0x2a6ff,
+	0x2b735, 0x2b73f,
+	0x2b81e, 0x2b81f,
+	0x2cea2, 0x2ceaf,
+	0x2ebe1, 0x2f7ff,
+	0x2fa1e, 0xe00ff,
+	0xe01f0, 0x10ffff,
+}; /* CR_C */
+
+/* 'Cc': General Category */
+#define CR_Cc CR_Cntrl
+
+/* 'Cf': General Category */
+static const OnigCodePoint CR_Cf[] = {
+	18,
+	0x00ad, 0x00ad,
+	0x0600, 0x0605,
+	0x061c, 0x061c,
+	0x06dd, 0x06dd,
+	0x070f, 0x070f,
+	0x08e2, 0x08e2,
+	0x180e, 0x180e,
+	0x200b, 0x200f,
+	0x202a, 0x202e,
+	0x2060, 0x2064,
+	0x2066, 0x206f,
+	0xfeff, 0xfeff,
+	0xfff9, 0xfffb,
+	0x110bd, 0x110bd,
+	0x1bca0, 0x1bca3,
+	0x1d173, 0x1d17a,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+}; /* CR_Cf */
+
+/* 'Cn': General Category */
+static const OnigCodePoint CR_Cn[] = {
+	649,
+	0x0378, 0x0379,
+	0x0380, 0x0383,
+	0x038b, 0x038b,
+	0x038d, 0x038d,
+	0x03a2, 0x03a2,
+	0x0530, 0x0530,
+	0x0557, 0x0558,
+	0x0560, 0x0560,
+	0x0588, 0x0588,
+	0x058b, 0x058c,
+	0x0590, 0x0590,
+	0x05c8, 0x05cf,
+	0x05eb, 0x05ef,
+	0x05f5, 0x05ff,
+	0x061d, 0x061d,
+	0x070e, 0x070e,
+	0x074b, 0x074c,
+	0x07b2, 0x07bf,
+	0x07fb, 0x07ff,
+	0x082e, 0x082f,
+	0x083f, 0x083f,
+	0x085c, 0x085d,
+	0x085f, 0x085f,
+	0x086b, 0x089f,
+	0x08b5, 0x08b5,
+	0x08be, 0x08d3,
+	0x0984, 0x0984,
+	0x098d, 0x098e,
+	0x0991, 0x0992,
+	0x09a9, 0x09a9,
+	0x09b1, 0x09b1,
+	0x09b3, 0x09b5,
+	0x09ba, 0x09bb,
+	0x09c5, 0x09c6,
+	0x09c9, 0x09ca,
+	0x09cf, 0x09d6,
+	0x09d8, 0x09db,
+	0x09de, 0x09de,
+	0x09e4, 0x09e5,
+	0x09fe, 0x0a00,
+	0x0a04, 0x0a04,
+	0x0a0b, 0x0a0e,
+	0x0a11, 0x0a12,
+	0x0a29, 0x0a29,
+	0x0a31, 0x0a31,
+	0x0a34, 0x0a34,
+	0x0a37, 0x0a37,
+	0x0a3a, 0x0a3b,
+	0x0a3d, 0x0a3d,
+	0x0a43, 0x0a46,
+	0x0a49, 0x0a4a,
+	0x0a4e, 0x0a50,
+	0x0a52, 0x0a58,
+	0x0a5d, 0x0a5d,
+	0x0a5f, 0x0a65,
+	0x0a76, 0x0a80,
+	0x0a84, 0x0a84,
+	0x0a8e, 0x0a8e,
+	0x0a92, 0x0a92,
+	0x0aa9, 0x0aa9,
+	0x0ab1, 0x0ab1,
+	0x0ab4, 0x0ab4,
+	0x0aba, 0x0abb,
+	0x0ac6, 0x0ac6,
+	0x0aca, 0x0aca,
+	0x0ace, 0x0acf,
+	0x0ad1, 0x0adf,
+	0x0ae4, 0x0ae5,
+	0x0af2, 0x0af8,
+	0x0b00, 0x0b00,
+	0x0b04, 0x0b04,
+	0x0b0d, 0x0b0e,
+	0x0b11, 0x0b12,
+	0x0b29, 0x0b29,
+	0x0b31, 0x0b31,
+	0x0b34, 0x0b34,
+	0x0b3a, 0x0b3b,
+	0x0b45, 0x0b46,
+	0x0b49, 0x0b4a,
+	0x0b4e, 0x0b55,
+	0x0b58, 0x0b5b,
+	0x0b5e, 0x0b5e,
+	0x0b64, 0x0b65,
+	0x0b78, 0x0b81,
+	0x0b84, 0x0b84,
+	0x0b8b, 0x0b8d,
+	0x0b91, 0x0b91,
+	0x0b96, 0x0b98,
+	0x0b9b, 0x0b9b,
+	0x0b9d, 0x0b9d,
+	0x0ba0, 0x0ba2,
+	0x0ba5, 0x0ba7,
+	0x0bab, 0x0bad,
+	0x0bba, 0x0bbd,
+	0x0bc3, 0x0bc5,
+	0x0bc9, 0x0bc9,
+	0x0bce, 0x0bcf,
+	0x0bd1, 0x0bd6,
+	0x0bd8, 0x0be5,
+	0x0bfb, 0x0bff,
+	0x0c04, 0x0c04,
+	0x0c0d, 0x0c0d,
+	0x0c11, 0x0c11,
+	0x0c29, 0x0c29,
+	0x0c3a, 0x0c3c,
+	0x0c45, 0x0c45,
+	0x0c49, 0x0c49,
+	0x0c4e, 0x0c54,
+	0x0c57, 0x0c57,
+	0x0c5b, 0x0c5f,
+	0x0c64, 0x0c65,
+	0x0c70, 0x0c77,
+	0x0c84, 0x0c84,
+	0x0c8d, 0x0c8d,
+	0x0c91, 0x0c91,
+	0x0ca9, 0x0ca9,
+	0x0cb4, 0x0cb4,
+	0x0cba, 0x0cbb,
+	0x0cc5, 0x0cc5,
+	0x0cc9, 0x0cc9,
+	0x0cce, 0x0cd4,
+	0x0cd7, 0x0cdd,
+	0x0cdf, 0x0cdf,
+	0x0ce4, 0x0ce5,
+	0x0cf0, 0x0cf0,
+	0x0cf3, 0x0cff,
+	0x0d04, 0x0d04,
+	0x0d0d, 0x0d0d,
+	0x0d11, 0x0d11,
+	0x0d45, 0x0d45,
+	0x0d49, 0x0d49,
+	0x0d50, 0x0d53,
+	0x0d64, 0x0d65,
+	0x0d80, 0x0d81,
+	0x0d84, 0x0d84,
+	0x0d97, 0x0d99,
+	0x0db2, 0x0db2,
+	0x0dbc, 0x0dbc,
+	0x0dbe, 0x0dbf,
+	0x0dc7, 0x0dc9,
+	0x0dcb, 0x0dce,
+	0x0dd5, 0x0dd5,
+	0x0dd7, 0x0dd7,
+	0x0de0, 0x0de5,
+	0x0df0, 0x0df1,
+	0x0df5, 0x0e00,
+	0x0e3b, 0x0e3e,
+	0x0e5c, 0x0e80,
+	0x0e83, 0x0e83,
+	0x0e85, 0x0e86,
+	0x0e89, 0x0e89,
+	0x0e8b, 0x0e8c,
+	0x0e8e, 0x0e93,
+	0x0e98, 0x0e98,
+	0x0ea0, 0x0ea0,
+	0x0ea4, 0x0ea4,
+	0x0ea6, 0x0ea6,
+	0x0ea8, 0x0ea9,
+	0x0eac, 0x0eac,
+	0x0eba, 0x0eba,
+	0x0ebe, 0x0ebf,
+	0x0ec5, 0x0ec5,
+	0x0ec7, 0x0ec7,
+	0x0ece, 0x0ecf,
+	0x0eda, 0x0edb,
+	0x0ee0, 0x0eff,
+	0x0f48, 0x0f48,
+	0x0f6d, 0x0f70,
+	0x0f98, 0x0f98,
+	0x0fbd, 0x0fbd,
+	0x0fcd, 0x0fcd,
+	0x0fdb, 0x0fff,
+	0x10c6, 0x10c6,
+	0x10c8, 0x10cc,
+	0x10ce, 0x10cf,
+	0x1249, 0x1249,
+	0x124e, 0x124f,
+	0x1257, 0x1257,
+	0x1259, 0x1259,
+	0x125e, 0x125f,
+	0x1289, 0x1289,
+	0x128e, 0x128f,
+	0x12b1, 0x12b1,
+	0x12b6, 0x12b7,
+	0x12bf, 0x12bf,
+	0x12c1, 0x12c1,
+	0x12c6, 0x12c7,
+	0x12d7, 0x12d7,
+	0x1311, 0x1311,
+	0x1316, 0x1317,
+	0x135b, 0x135c,
+	0x137d, 0x137f,
+	0x139a, 0x139f,
+	0x13f6, 0x13f7,
+	0x13fe, 0x13ff,
+	0x169d, 0x169f,
+	0x16f9, 0x16ff,
+	0x170d, 0x170d,
+	0x1715, 0x171f,
+	0x1737, 0x173f,
+	0x1754, 0x175f,
+	0x176d, 0x176d,
+	0x1771, 0x1771,
+	0x1774, 0x177f,
+	0x17de, 0x17df,
+	0x17ea, 0x17ef,
+	0x17fa, 0x17ff,
+	0x180f, 0x180f,
+	0x181a, 0x181f,
+	0x1878, 0x187f,
+	0x18ab, 0x18af,
+	0x18f6, 0x18ff,
+	0x191f, 0x191f,
+	0x192c, 0x192f,
+	0x193c, 0x193f,
+	0x1941, 0x1943,
+	0x196e, 0x196f,
+	0x1975, 0x197f,
+	0x19ac, 0x19af,
+	0x19ca, 0x19cf,
+	0x19db, 0x19dd,
+	0x1a1c, 0x1a1d,
+	0x1a5f, 0x1a5f,
+	0x1a7d, 0x1a7e,
+	0x1a8a, 0x1a8f,
+	0x1a9a, 0x1a9f,
+	0x1aae, 0x1aaf,
+	0x1abf, 0x1aff,
+	0x1b4c, 0x1b4f,
+	0x1b7d, 0x1b7f,
+	0x1bf4, 0x1bfb,
+	0x1c38, 0x1c3a,
+	0x1c4a, 0x1c4c,
+	0x1c89, 0x1cbf,
+	0x1cc8, 0x1ccf,
+	0x1cfa, 0x1cff,
+	0x1dfa, 0x1dfa,
+	0x1f16, 0x1f17,
+	0x1f1e, 0x1f1f,
+	0x1f46, 0x1f47,
+	0x1f4e, 0x1f4f,
+	0x1f58, 0x1f58,
+	0x1f5a, 0x1f5a,
+	0x1f5c, 0x1f5c,
+	0x1f5e, 0x1f5e,
+	0x1f7e, 0x1f7f,
+	0x1fb5, 0x1fb5,
+	0x1fc5, 0x1fc5,
+	0x1fd4, 0x1fd5,
+	0x1fdc, 0x1fdc,
+	0x1ff0, 0x1ff1,
+	0x1ff5, 0x1ff5,
+	0x1fff, 0x1fff,
+	0x2065, 0x2065,
+	0x2072, 0x2073,
+	0x208f, 0x208f,
+	0x209d, 0x209f,
+	0x20c0, 0x20cf,
+	0x20f1, 0x20ff,
+	0x218c, 0x218f,
+	0x2427, 0x243f,
+	0x244b, 0x245f,
+	0x2b74, 0x2b75,
+	0x2b96, 0x2b97,
+	0x2bba, 0x2bbc,
+	0x2bc9, 0x2bc9,
+	0x2bd3, 0x2beb,
+	0x2bf0, 0x2bff,
+	0x2c2f, 0x2c2f,
+	0x2c5f, 0x2c5f,
+	0x2cf4, 0x2cf8,
+	0x2d26, 0x2d26,
+	0x2d28, 0x2d2c,
+	0x2d2e, 0x2d2f,
+	0x2d68, 0x2d6e,
+	0x2d71, 0x2d7e,
+	0x2d97, 0x2d9f,
+	0x2da7, 0x2da7,
+	0x2daf, 0x2daf,
+	0x2db7, 0x2db7,
+	0x2dbf, 0x2dbf,
+	0x2dc7, 0x2dc7,
+	0x2dcf, 0x2dcf,
+	0x2dd7, 0x2dd7,
+	0x2ddf, 0x2ddf,
+	0x2e4a, 0x2e7f,
+	0x2e9a, 0x2e9a,
+	0x2ef4, 0x2eff,
+	0x2fd6, 0x2fef,
+	0x2ffc, 0x2fff,
+	0x3040, 0x3040,
+	0x3097, 0x3098,
+	0x3100, 0x3104,
+	0x312f, 0x3130,
+	0x318f, 0x318f,
+	0x31bb, 0x31bf,
+	0x31e4, 0x31ef,
+	0x321f, 0x321f,
+	0x32ff, 0x32ff,
+	0x4db6, 0x4dbf,
+	0x9feb, 0x9fff,
+	0xa48d, 0xa48f,
+	0xa4c7, 0xa4cf,
+	0xa62c, 0xa63f,
+	0xa6f8, 0xa6ff,
+	0xa7af, 0xa7af,
+	0xa7b8, 0xa7f6,
+	0xa82c, 0xa82f,
+	0xa83a, 0xa83f,
+	0xa878, 0xa87f,
+	0xa8c6, 0xa8cd,
+	0xa8da, 0xa8df,
+	0xa8fe, 0xa8ff,
+	0xa954, 0xa95e,
+	0xa97d, 0xa97f,
+	0xa9ce, 0xa9ce,
+	0xa9da, 0xa9dd,
+	0xa9ff, 0xa9ff,
+	0xaa37, 0xaa3f,
+	0xaa4e, 0xaa4f,
+	0xaa5a, 0xaa5b,
+	0xaac3, 0xaada,
+	0xaaf7, 0xab00,
+	0xab07, 0xab08,
+	0xab0f, 0xab10,
+	0xab17, 0xab1f,
+	0xab27, 0xab27,
+	0xab2f, 0xab2f,
+	0xab66, 0xab6f,
+	0xabee, 0xabef,
+	0xabfa, 0xabff,
+	0xd7a4, 0xd7af,
+	0xd7c7, 0xd7ca,
+	0xd7fc, 0xd7ff,
+	0xfa6e, 0xfa6f,
+	0xfada, 0xfaff,
+	0xfb07, 0xfb12,
+	0xfb18, 0xfb1c,
+	0xfb37, 0xfb37,
+	0xfb3d, 0xfb3d,
+	0xfb3f, 0xfb3f,
+	0xfb42, 0xfb42,
+	0xfb45, 0xfb45,
+	0xfbc2, 0xfbd2,
+	0xfd40, 0xfd4f,
+	0xfd90, 0xfd91,
+	0xfdc8, 0xfdef,
+	0xfdfe, 0xfdff,
+	0xfe1a, 0xfe1f,
+	0xfe53, 0xfe53,
+	0xfe67, 0xfe67,
+	0xfe6c, 0xfe6f,
+	0xfe75, 0xfe75,
+	0xfefd, 0xfefe,
+	0xff00, 0xff00,
+	0xffbf, 0xffc1,
+	0xffc8, 0xffc9,
+	0xffd0, 0xffd1,
+	0xffd8, 0xffd9,
+	0xffdd, 0xffdf,
+	0xffe7, 0xffe7,
+	0xffef, 0xfff8,
+	0xfffe, 0xffff,
+	0x1000c, 0x1000c,
+	0x10027, 0x10027,
+	0x1003b, 0x1003b,
+	0x1003e, 0x1003e,
+	0x1004e, 0x1004f,
+	0x1005e, 0x1007f,
+	0x100fb, 0x100ff,
+	0x10103, 0x10106,
+	0x10134, 0x10136,
+	0x1018f, 0x1018f,
+	0x1019c, 0x1019f,
+	0x101a1, 0x101cf,
+	0x101fe, 0x1027f,
+	0x1029d, 0x1029f,
+	0x102d1, 0x102df,
+	0x102fc, 0x102ff,
+	0x10324, 0x1032c,
+	0x1034b, 0x1034f,
+	0x1037b, 0x1037f,
+	0x1039e, 0x1039e,
+	0x103c4, 0x103c7,
+	0x103d6, 0x103ff,
+	0x1049e, 0x1049f,
+	0x104aa, 0x104af,
+	0x104d4, 0x104d7,
+	0x104fc, 0x104ff,
+	0x10528, 0x1052f,
+	0x10564, 0x1056e,
+	0x10570, 0x105ff,
+	0x10737, 0x1073f,
+	0x10756, 0x1075f,
+	0x10768, 0x107ff,
+	0x10806, 0x10807,
+	0x10809, 0x10809,
+	0x10836, 0x10836,
+	0x10839, 0x1083b,
+	0x1083d, 0x1083e,
+	0x10856, 0x10856,
+	0x1089f, 0x108a6,
+	0x108b0, 0x108df,
+	0x108f3, 0x108f3,
+	0x108f6, 0x108fa,
+	0x1091c, 0x1091e,
+	0x1093a, 0x1093e,
+	0x10940, 0x1097f,
+	0x109b8, 0x109bb,
+	0x109d0, 0x109d1,
+	0x10a04, 0x10a04,
+	0x10a07, 0x10a0b,
+	0x10a14, 0x10a14,
+	0x10a18, 0x10a18,
+	0x10a34, 0x10a37,
+	0x10a3b, 0x10a3e,
+	0x10a48, 0x10a4f,
+	0x10a59, 0x10a5f,
+	0x10aa0, 0x10abf,
+	0x10ae7, 0x10aea,
+	0x10af7, 0x10aff,
+	0x10b36, 0x10b38,
+	0x10b56, 0x10b57,
+	0x10b73, 0x10b77,
+	0x10b92, 0x10b98,
+	0x10b9d, 0x10ba8,
+	0x10bb0, 0x10bff,
+	0x10c49, 0x10c7f,
+	0x10cb3, 0x10cbf,
+	0x10cf3, 0x10cf9,
+	0x10d00, 0x10e5f,
+	0x10e7f, 0x10fff,
+	0x1104e, 0x11051,
+	0x11070, 0x1107e,
+	0x110c2, 0x110cf,
+	0x110e9, 0x110ef,
+	0x110fa, 0x110ff,
+	0x11135, 0x11135,
+	0x11144, 0x1114f,
+	0x11177, 0x1117f,
+	0x111ce, 0x111cf,
+	0x111e0, 0x111e0,
+	0x111f5, 0x111ff,
+	0x11212, 0x11212,
+	0x1123f, 0x1127f,
+	0x11287, 0x11287,
+	0x11289, 0x11289,
+	0x1128e, 0x1128e,
+	0x1129e, 0x1129e,
+	0x112aa, 0x112af,
+	0x112eb, 0x112ef,
+	0x112fa, 0x112ff,
+	0x11304, 0x11304,
+	0x1130d, 0x1130e,
+	0x11311, 0x11312,
+	0x11329, 0x11329,
+	0x11331, 0x11331,
+	0x11334, 0x11334,
+	0x1133a, 0x1133b,
+	0x11345, 0x11346,
+	0x11349, 0x1134a,
+	0x1134e, 0x1134f,
+	0x11351, 0x11356,
+	0x11358, 0x1135c,
+	0x11364, 0x11365,
+	0x1136d, 0x1136f,
+	0x11375, 0x113ff,
+	0x1145a, 0x1145a,
+	0x1145c, 0x1145c,
+	0x1145e, 0x1147f,
+	0x114c8, 0x114cf,
+	0x114da, 0x1157f,
+	0x115b6, 0x115b7,
+	0x115de, 0x115ff,
+	0x11645, 0x1164f,
+	0x1165a, 0x1165f,
+	0x1166d, 0x1167f,
+	0x116b8, 0x116bf,
+	0x116ca, 0x116ff,
+	0x1171a, 0x1171c,
+	0x1172c, 0x1172f,
+	0x11740, 0x1189f,
+	0x118f3, 0x118fe,
+	0x11900, 0x119ff,
+	0x11a48, 0x11a4f,
+	0x11a84, 0x11a85,
+	0x11a9d, 0x11a9d,
+	0x11aa3, 0x11abf,
+	0x11af9, 0x11bff,
+	0x11c09, 0x11c09,
+	0x11c37, 0x11c37,
+	0x11c46, 0x11c4f,
+	0x11c6d, 0x11c6f,
+	0x11c90, 0x11c91,
+	0x11ca8, 0x11ca8,
+	0x11cb7, 0x11cff,
+	0x11d07, 0x11d07,
+	0x11d0a, 0x11d0a,
+	0x11d37, 0x11d39,
+	0x11d3b, 0x11d3b,
+	0x11d3e, 0x11d3e,
+	0x11d48, 0x11d4f,
+	0x11d5a, 0x11fff,
+	0x1239a, 0x123ff,
+	0x1246f, 0x1246f,
+	0x12475, 0x1247f,
+	0x12544, 0x12fff,
+	0x1342f, 0x143ff,
+	0x14647, 0x167ff,
+	0x16a39, 0x16a3f,
+	0x16a5f, 0x16a5f,
+	0x16a6a, 0x16a6d,
+	0x16a70, 0x16acf,
+	0x16aee, 0x16aef,
+	0x16af6, 0x16aff,
+	0x16b46, 0x16b4f,
+	0x16b5a, 0x16b5a,
+	0x16b62, 0x16b62,
+	0x16b78, 0x16b7c,
+	0x16b90, 0x16eff,
+	0x16f45, 0x16f4f,
+	0x16f7f, 0x16f8e,
+	0x16fa0, 0x16fdf,
+	0x16fe2, 0x16fff,
+	0x187ed, 0x187ff,
+	0x18af3, 0x1afff,
+	0x1b11f, 0x1b16f,
+	0x1b2fc, 0x1bbff,
+	0x1bc6b, 0x1bc6f,
+	0x1bc7d, 0x1bc7f,
+	0x1bc89, 0x1bc8f,
+	0x1bc9a, 0x1bc9b,
+	0x1bca4, 0x1cfff,
+	0x1d0f6, 0x1d0ff,
+	0x1d127, 0x1d128,
+	0x1d1e9, 0x1d1ff,
+	0x1d246, 0x1d2ff,
+	0x1d357, 0x1d35f,
+	0x1d372, 0x1d3ff,
+	0x1d455, 0x1d455,
+	0x1d49d, 0x1d49d,
+	0x1d4a0, 0x1d4a1,
+	0x1d4a3, 0x1d4a4,
+	0x1d4a7, 0x1d4a8,
+	0x1d4ad, 0x1d4ad,
+	0x1d4ba, 0x1d4ba,
+	0x1d4bc, 0x1d4bc,
+	0x1d4c4, 0x1d4c4,
+	0x1d506, 0x1d506,
+	0x1d50b, 0x1d50c,
+	0x1d515, 0x1d515,
+	0x1d51d, 0x1d51d,
+	0x1d53a, 0x1d53a,
+	0x1d53f, 0x1d53f,
+	0x1d545, 0x1d545,
+	0x1d547, 0x1d549,
+	0x1d551, 0x1d551,
+	0x1d6a6, 0x1d6a7,
+	0x1d7cc, 0x1d7cd,
+	0x1da8c, 0x1da9a,
+	0x1daa0, 0x1daa0,
+	0x1dab0, 0x1dfff,
+	0x1e007, 0x1e007,
+	0x1e019, 0x1e01a,
+	0x1e022, 0x1e022,
+	0x1e025, 0x1e025,
+	0x1e02b, 0x1e7ff,
+	0x1e8c5, 0x1e8c6,
+	0x1e8d7, 0x1e8ff,
+	0x1e94b, 0x1e94f,
+	0x1e95a, 0x1e95d,
+	0x1e960, 0x1edff,
+	0x1ee04, 0x1ee04,
+	0x1ee20, 0x1ee20,
+	0x1ee23, 0x1ee23,
+	0x1ee25, 0x1ee26,
+	0x1ee28, 0x1ee28,
+	0x1ee33, 0x1ee33,
+	0x1ee38, 0x1ee38,
+	0x1ee3a, 0x1ee3a,
+	0x1ee3c, 0x1ee41,
+	0x1ee43, 0x1ee46,
+	0x1ee48, 0x1ee48,
+	0x1ee4a, 0x1ee4a,
+	0x1ee4c, 0x1ee4c,
+	0x1ee50, 0x1ee50,
+	0x1ee53, 0x1ee53,
+	0x1ee55, 0x1ee56,
+	0x1ee58, 0x1ee58,
+	0x1ee5a, 0x1ee5a,
+	0x1ee5c, 0x1ee5c,
+	0x1ee5e, 0x1ee5e,
+	0x1ee60, 0x1ee60,
+	0x1ee63, 0x1ee63,
+	0x1ee65, 0x1ee66,
+	0x1ee6b, 0x1ee6b,
+	0x1ee73, 0x1ee73,
+	0x1ee78, 0x1ee78,
+	0x1ee7d, 0x1ee7d,
+	0x1ee7f, 0x1ee7f,
+	0x1ee8a, 0x1ee8a,
+	0x1ee9c, 0x1eea0,
+	0x1eea4, 0x1eea4,
+	0x1eeaa, 0x1eeaa,
+	0x1eebc, 0x1eeef,
+	0x1eef2, 0x1efff,
+	0x1f02c, 0x1f02f,
+	0x1f094, 0x1f09f,
+	0x1f0af, 0x1f0b0,
+	0x1f0c0, 0x1f0c0,
+	0x1f0d0, 0x1f0d0,
+	0x1f0f6, 0x1f0ff,
+	0x1f10d, 0x1f10f,
+	0x1f12f, 0x1f12f,
+	0x1f16c, 0x1f16f,
+	0x1f1ad, 0x1f1e5,
+	0x1f203, 0x1f20f,
+	0x1f23c, 0x1f23f,
+	0x1f249, 0x1f24f,
+	0x1f252, 0x1f25f,
+	0x1f266, 0x1f2ff,
+	0x1f6d5, 0x1f6df,
+	0x1f6ed, 0x1f6ef,
+	0x1f6f9, 0x1f6ff,
+	0x1f774, 0x1f77f,
+	0x1f7d5, 0x1f7ff,
+	0x1f80c, 0x1f80f,
+	0x1f848, 0x1f84f,
+	0x1f85a, 0x1f85f,
+	0x1f888, 0x1f88f,
+	0x1f8ae, 0x1f8ff,
+	0x1f90c, 0x1f90f,
+	0x1f93f, 0x1f93f,
+	0x1f94d, 0x1f94f,
+	0x1f96c, 0x1f97f,
+	0x1f998, 0x1f9bf,
+	0x1f9c1, 0x1f9cf,
+	0x1f9e7, 0x1ffff,
+	0x2a6d7, 0x2a6ff,
+	0x2b735, 0x2b73f,
+	0x2b81e, 0x2b81f,
+	0x2cea2, 0x2ceaf,
+	0x2ebe1, 0x2f7ff,
+	0x2fa1e, 0xe0000,
+	0xe0002, 0xe001f,
+	0xe0080, 0xe00ff,
+	0xe01f0, 0xeffff,
+	0xffffe, 0xfffff,
+	0x10fffe, 0x10ffff,
+}; /* CR_Cn */
+
+/* 'Co': General Category */
+static const OnigCodePoint CR_Co[] = {
+	3,
+	0xe000, 0xf8ff,
+	0xf0000, 0xffffd,
+	0x100000, 0x10fffd,
+}; /* CR_Co */
+
+/* 'Cs': General Category */
+static const OnigCodePoint CR_Cs[] = {
+	1,
+	0xd800, 0xdfff,
+}; /* CR_Cs */
+
+/* 'L': Major Category */
+static const OnigCodePoint CR_L[] = {
+	585,
+	0x0041, 0x005a,
+	0x0061, 0x007a,
+	0x00aa, 0x00aa,
+	0x00b5, 0x00b5,
+	0x00ba, 0x00ba,
+	0x00c0, 0x00d6,
+	0x00d8, 0x00f6,
+	0x00f8, 0x02c1,
+	0x02c6, 0x02d1,
+	0x02e0, 0x02e4,
+	0x02ec, 0x02ec,
+	0x02ee, 0x02ee,
+	0x0370, 0x0374,
+	0x0376, 0x0377,
+	0x037a, 0x037d,
+	0x037f, 0x037f,
+	0x0386, 0x0386,
+	0x0388, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03f5,
+	0x03f7, 0x0481,
+	0x048a, 0x052f,
+	0x0531, 0x0556,
+	0x0559, 0x0559,
+	0x0561, 0x0587,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f2,
+	0x0620, 0x064a,
+	0x066e, 0x066f,
+	0x0671, 0x06d3,
+	0x06d5, 0x06d5,
+	0x06e5, 0x06e6,
+	0x06ee, 0x06ef,
+	0x06fa, 0x06fc,
+	0x06ff, 0x06ff,
+	0x0710, 0x0710,
+	0x0712, 0x072f,
+	0x074d, 0x07a5,
+	0x07b1, 0x07b1,
+	0x07ca, 0x07ea,
+	0x07f4, 0x07f5,
+	0x07fa, 0x07fa,
+	0x0800, 0x0815,
+	0x081a, 0x081a,
+	0x0824, 0x0824,
+	0x0828, 0x0828,
+	0x0840, 0x0858,
+	0x0860, 0x086a,
+	0x08a0, 0x08b4,
+	0x08b6, 0x08bd,
+	0x0904, 0x0939,
+	0x093d, 0x093d,
+	0x0950, 0x0950,
+	0x0958, 0x0961,
+	0x0971, 0x0980,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bd, 0x09bd,
+	0x09ce, 0x09ce,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e1,
+	0x09f0, 0x09f1,
+	0x09fc, 0x09fc,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a72, 0x0a74,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abd, 0x0abd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae1,
+	0x0af9, 0x0af9,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3d, 0x0b3d,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b61,
+	0x0b71, 0x0b71,
+	0x0b83, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bd0, 0x0bd0,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c39,
+	0x0c3d, 0x0c3d,
+	0x0c58, 0x0c5a,
+	0x0c60, 0x0c61,
+	0x0c80, 0x0c80,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbd, 0x0cbd,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce1,
+	0x0cf1, 0x0cf2,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d3a,
+	0x0d3d, 0x0d3d,
+	0x0d4e, 0x0d4e,
+	0x0d54, 0x0d56,
+	0x0d5f, 0x0d61,
+	0x0d7a, 0x0d7f,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0e01, 0x0e30,
+	0x0e32, 0x0e33,
+	0x0e40, 0x0e46,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb0,
+	0x0eb2, 0x0eb3,
+	0x0ebd, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f00,
+	0x0f40, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f88, 0x0f8c,
+	0x1000, 0x102a,
+	0x103f, 0x103f,
+	0x1050, 0x1055,
+	0x105a, 0x105d,
+	0x1061, 0x1061,
+	0x1065, 0x1066,
+	0x106e, 0x1070,
+	0x1075, 0x1081,
+	0x108e, 0x108e,
+	0x10a0, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x10fa,
+	0x10fc, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x1380, 0x138f,
+	0x13a0, 0x13f5,
+	0x13f8, 0x13fd,
+	0x1401, 0x166c,
+	0x166f, 0x167f,
+	0x1681, 0x169a,
+	0x16a0, 0x16ea,
+	0x16f1, 0x16f8,
+	0x1700, 0x170c,
+	0x170e, 0x1711,
+	0x1720, 0x1731,
+	0x1740, 0x1751,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1780, 0x17b3,
+	0x17d7, 0x17d7,
+	0x17dc, 0x17dc,
+	0x1820, 0x1877,
+	0x1880, 0x1884,
+	0x1887, 0x18a8,
+	0x18aa, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191e,
+	0x1950, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x1a00, 0x1a16,
+	0x1a20, 0x1a54,
+	0x1aa7, 0x1aa7,
+	0x1b05, 0x1b33,
+	0x1b45, 0x1b4b,
+	0x1b83, 0x1ba0,
+	0x1bae, 0x1baf,
+	0x1bba, 0x1be5,
+	0x1c00, 0x1c23,
+	0x1c4d, 0x1c4f,
+	0x1c5a, 0x1c7d,
+	0x1c80, 0x1c88,
+	0x1ce9, 0x1cec,
+	0x1cee, 0x1cf1,
+	0x1cf5, 0x1cf6,
+	0x1d00, 0x1dbf,
+	0x1e00, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fbc,
+	0x1fbe, 0x1fbe,
+	0x1fc2, 0x1fc4,
+	0x1fc6, 0x1fcc,
+	0x1fd0, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fe0, 0x1fec,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffc,
+	0x2071, 0x2071,
+	0x207f, 0x207f,
+	0x2090, 0x209c,
+	0x2102, 0x2102,
+	0x2107, 0x2107,
+	0x210a, 0x2113,
+	0x2115, 0x2115,
+	0x2119, 0x211d,
+	0x2124, 0x2124,
+	0x2126, 0x2126,
+	0x2128, 0x2128,
+	0x212a, 0x212d,
+	0x212f, 0x2139,
+	0x213c, 0x213f,
+	0x2145, 0x2149,
+	0x214e, 0x214e,
+	0x2183, 0x2184,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2ce4,
+	0x2ceb, 0x2cee,
+	0x2cf2, 0x2cf3,
+	0x2d00, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d6f,
+	0x2d80, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2e2f, 0x2e2f,
+	0x3005, 0x3006,
+	0x3031, 0x3035,
+	0x303b, 0x303c,
+	0x3041, 0x3096,
+	0x309d, 0x309f,
+	0x30a1, 0x30fa,
+	0x30fc, 0x30ff,
+	0x3105, 0x312e,
+	0x3131, 0x318e,
+	0x31a0, 0x31ba,
+	0x31f0, 0x31ff,
+	0x3400, 0x4db5,
+	0x4e00, 0x9fea,
+	0xa000, 0xa48c,
+	0xa4d0, 0xa4fd,
+	0xa500, 0xa60c,
+	0xa610, 0xa61f,
+	0xa62a, 0xa62b,
+	0xa640, 0xa66e,
+	0xa67f, 0xa69d,
+	0xa6a0, 0xa6e5,
+	0xa717, 0xa71f,
+	0xa722, 0xa788,
+	0xa78b, 0xa7ae,
+	0xa7b0, 0xa7b7,
+	0xa7f7, 0xa801,
+	0xa803, 0xa805,
+	0xa807, 0xa80a,
+	0xa80c, 0xa822,
+	0xa840, 0xa873,
+	0xa882, 0xa8b3,
+	0xa8f2, 0xa8f7,
+	0xa8fb, 0xa8fb,
+	0xa8fd, 0xa8fd,
+	0xa90a, 0xa925,
+	0xa930, 0xa946,
+	0xa960, 0xa97c,
+	0xa984, 0xa9b2,
+	0xa9cf, 0xa9cf,
+	0xa9e0, 0xa9e4,
+	0xa9e6, 0xa9ef,
+	0xa9fa, 0xa9fe,
+	0xaa00, 0xaa28,
+	0xaa40, 0xaa42,
+	0xaa44, 0xaa4b,
+	0xaa60, 0xaa76,
+	0xaa7a, 0xaa7a,
+	0xaa7e, 0xaaaf,
+	0xaab1, 0xaab1,
+	0xaab5, 0xaab6,
+	0xaab9, 0xaabd,
+	0xaac0, 0xaac0,
+	0xaac2, 0xaac2,
+	0xaadb, 0xaadd,
+	0xaae0, 0xaaea,
+	0xaaf2, 0xaaf4,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xab30, 0xab5a,
+	0xab5c, 0xab65,
+	0xab70, 0xabe2,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xf900, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb1d,
+	0xfb1f, 0xfb28,
+	0xfb2a, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbb1,
+	0xfbd3, 0xfd3d,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdf0, 0xfdfb,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xff21, 0xff3a,
+	0xff41, 0xff5a,
+	0xff66, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0x10000, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x10300, 0x1031f,
+	0x1032d, 0x10340,
+	0x10342, 0x10349,
+	0x10350, 0x10375,
+	0x10380, 0x1039d,
+	0x103a0, 0x103c3,
+	0x103c8, 0x103cf,
+	0x10400, 0x1049d,
+	0x104b0, 0x104d3,
+	0x104d8, 0x104fb,
+	0x10500, 0x10527,
+	0x10530, 0x10563,
+	0x10600, 0x10736,
+	0x10740, 0x10755,
+	0x10760, 0x10767,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10860, 0x10876,
+	0x10880, 0x1089e,
+	0x108e0, 0x108f2,
+	0x108f4, 0x108f5,
+	0x10900, 0x10915,
+	0x10920, 0x10939,
+	0x10980, 0x109b7,
+	0x109be, 0x109bf,
+	0x10a00, 0x10a00,
+	0x10a10, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a60, 0x10a7c,
+	0x10a80, 0x10a9c,
+	0x10ac0, 0x10ac7,
+	0x10ac9, 0x10ae4,
+	0x10b00, 0x10b35,
+	0x10b40, 0x10b55,
+	0x10b60, 0x10b72,
+	0x10b80, 0x10b91,
+	0x10c00, 0x10c48,
+	0x10c80, 0x10cb2,
+	0x10cc0, 0x10cf2,
+	0x11003, 0x11037,
+	0x11083, 0x110af,
+	0x110d0, 0x110e8,
+	0x11103, 0x11126,
+	0x11150, 0x11172,
+	0x11176, 0x11176,
+	0x11183, 0x111b2,
+	0x111c1, 0x111c4,
+	0x111da, 0x111da,
+	0x111dc, 0x111dc,
+	0x11200, 0x11211,
+	0x11213, 0x1122b,
+	0x11280, 0x11286,
+	0x11288, 0x11288,
+	0x1128a, 0x1128d,
+	0x1128f, 0x1129d,
+	0x1129f, 0x112a8,
+	0x112b0, 0x112de,
+	0x11305, 0x1130c,
+	0x1130f, 0x11310,
+	0x11313, 0x11328,
+	0x1132a, 0x11330,
+	0x11332, 0x11333,
+	0x11335, 0x11339,
+	0x1133d, 0x1133d,
+	0x11350, 0x11350,
+	0x1135d, 0x11361,
+	0x11400, 0x11434,
+	0x11447, 0x1144a,
+	0x11480, 0x114af,
+	0x114c4, 0x114c5,
+	0x114c7, 0x114c7,
+	0x11580, 0x115ae,
+	0x115d8, 0x115db,
+	0x11600, 0x1162f,
+	0x11644, 0x11644,
+	0x11680, 0x116aa,
+	0x11700, 0x11719,
+	0x118a0, 0x118df,
+	0x118ff, 0x118ff,
+	0x11a00, 0x11a00,
+	0x11a0b, 0x11a32,
+	0x11a3a, 0x11a3a,
+	0x11a50, 0x11a50,
+	0x11a5c, 0x11a83,
+	0x11a86, 0x11a89,
+	0x11ac0, 0x11af8,
+	0x11c00, 0x11c08,
+	0x11c0a, 0x11c2e,
+	0x11c40, 0x11c40,
+	0x11c72, 0x11c8f,
+	0x11d00, 0x11d06,
+	0x11d08, 0x11d09,
+	0x11d0b, 0x11d30,
+	0x11d46, 0x11d46,
+	0x12000, 0x12399,
+	0x12480, 0x12543,
+	0x13000, 0x1342e,
+	0x14400, 0x14646,
+	0x16800, 0x16a38,
+	0x16a40, 0x16a5e,
+	0x16ad0, 0x16aed,
+	0x16b00, 0x16b2f,
+	0x16b40, 0x16b43,
+	0x16b63, 0x16b77,
+	0x16b7d, 0x16b8f,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f50,
+	0x16f93, 0x16f9f,
+	0x16fe0, 0x16fe1,
+	0x17000, 0x187ec,
+	0x18800, 0x18af2,
+	0x1b000, 0x1b11e,
+	0x1b170, 0x1b2fb,
+	0x1bc00, 0x1bc6a,
+	0x1bc70, 0x1bc7c,
+	0x1bc80, 0x1bc88,
+	0x1bc90, 0x1bc99,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d6c0,
+	0x1d6c2, 0x1d6da,
+	0x1d6dc, 0x1d6fa,
+	0x1d6fc, 0x1d714,
+	0x1d716, 0x1d734,
+	0x1d736, 0x1d74e,
+	0x1d750, 0x1d76e,
+	0x1d770, 0x1d788,
+	0x1d78a, 0x1d7a8,
+	0x1d7aa, 0x1d7c2,
+	0x1d7c4, 0x1d7cb,
+	0x1e800, 0x1e8c4,
+	0x1e900, 0x1e943,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x20000, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2b820, 0x2cea1,
+	0x2ceb0, 0x2ebe0,
+	0x2f800, 0x2fa1d,
+}; /* CR_L */
+
+/* 'LC': General Category */
+static const OnigCodePoint CR_LC[] = {
+	126,
+	0x0041, 0x005a,
+	0x0061, 0x007a,
+	0x00b5, 0x00b5,
+	0x00c0, 0x00d6,
+	0x00d8, 0x00f6,
+	0x00f8, 0x01ba,
+	0x01bc, 0x01bf,
+	0x01c4, 0x0293,
+	0x0295, 0x02af,
+	0x0370, 0x0373,
+	0x0376, 0x0377,
+	0x037b, 0x037d,
+	0x037f, 0x037f,
+	0x0386, 0x0386,
+	0x0388, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03f5,
+	0x03f7, 0x0481,
+	0x048a, 0x052f,
+	0x0531, 0x0556,
+	0x0561, 0x0587,
+	0x10a0, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x13a0, 0x13f5,
+	0x13f8, 0x13fd,
+	0x1c80, 0x1c88,
+	0x1d00, 0x1d2b,
+	0x1d6b, 0x1d77,
+	0x1d79, 0x1d9a,
+	0x1e00, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fbc,
+	0x1fbe, 0x1fbe,
+	0x1fc2, 0x1fc4,
+	0x1fc6, 0x1fcc,
+	0x1fd0, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fe0, 0x1fec,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffc,
+	0x2102, 0x2102,
+	0x2107, 0x2107,
+	0x210a, 0x2113,
+	0x2115, 0x2115,
+	0x2119, 0x211d,
+	0x2124, 0x2124,
+	0x2126, 0x2126,
+	0x2128, 0x2128,
+	0x212a, 0x212d,
+	0x212f, 0x2134,
+	0x2139, 0x2139,
+	0x213c, 0x213f,
+	0x2145, 0x2149,
+	0x214e, 0x214e,
+	0x2183, 0x2184,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2c7b,
+	0x2c7e, 0x2ce4,
+	0x2ceb, 0x2cee,
+	0x2cf2, 0x2cf3,
+	0x2d00, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0xa640, 0xa66d,
+	0xa680, 0xa69b,
+	0xa722, 0xa76f,
+	0xa771, 0xa787,
+	0xa78b, 0xa78e,
+	0xa790, 0xa7ae,
+	0xa7b0, 0xa7b7,
+	0xa7fa, 0xa7fa,
+	0xab30, 0xab5a,
+	0xab60, 0xab65,
+	0xab70, 0xabbf,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xff21, 0xff3a,
+	0xff41, 0xff5a,
+	0x10400, 0x1044f,
+	0x104b0, 0x104d3,
+	0x104d8, 0x104fb,
+	0x10c80, 0x10cb2,
+	0x10cc0, 0x10cf2,
+	0x118a0, 0x118df,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d6c0,
+	0x1d6c2, 0x1d6da,
+	0x1d6dc, 0x1d6fa,
+	0x1d6fc, 0x1d714,
+	0x1d716, 0x1d734,
+	0x1d736, 0x1d74e,
+	0x1d750, 0x1d76e,
+	0x1d770, 0x1d788,
+	0x1d78a, 0x1d7a8,
+	0x1d7aa, 0x1d7c2,
+	0x1d7c4, 0x1d7cb,
+	0x1e900, 0x1e943,
+}; /* CR_LC */
+
+/* 'Ll': General Category */
+static const OnigCodePoint CR_Ll[] = {
+	633,
+	0x0061, 0x007a,
+	0x00b5, 0x00b5,
+	0x00df, 0x00f6,
+	0x00f8, 0x00ff,
+	0x0101, 0x0101,
+	0x0103, 0x0103,
+	0x0105, 0x0105,
+	0x0107, 0x0107,
+	0x0109, 0x0109,
+	0x010b, 0x010b,
+	0x010d, 0x010d,
+	0x010f, 0x010f,
+	0x0111, 0x0111,
+	0x0113, 0x0113,
+	0x0115, 0x0115,
+	0x0117, 0x0117,
+	0x0119, 0x0119,
+	0x011b, 0x011b,
+	0x011d, 0x011d,
+	0x011f, 0x011f,
+	0x0121, 0x0121,
+	0x0123, 0x0123,
+	0x0125, 0x0125,
+	0x0127, 0x0127,
+	0x0129, 0x0129,
+	0x012b, 0x012b,
+	0x012d, 0x012d,
+	0x012f, 0x012f,
+	0x0131, 0x0131,
+	0x0133, 0x0133,
+	0x0135, 0x0135,
+	0x0137, 0x0138,
+	0x013a, 0x013a,
+	0x013c, 0x013c,
+	0x013e, 0x013e,
+	0x0140, 0x0140,
+	0x0142, 0x0142,
+	0x0144, 0x0144,
+	0x0146, 0x0146,
+	0x0148, 0x0149,
+	0x014b, 0x014b,
+	0x014d, 0x014d,
+	0x014f, 0x014f,
+	0x0151, 0x0151,
+	0x0153, 0x0153,
+	0x0155, 0x0155,
+	0x0157, 0x0157,
+	0x0159, 0x0159,
+	0x015b, 0x015b,
+	0x015d, 0x015d,
+	0x015f, 0x015f,
+	0x0161, 0x0161,
+	0x0163, 0x0163,
+	0x0165, 0x0165,
+	0x0167, 0x0167,
+	0x0169, 0x0169,
+	0x016b, 0x016b,
+	0x016d, 0x016d,
+	0x016f, 0x016f,
+	0x0171, 0x0171,
+	0x0173, 0x0173,
+	0x0175, 0x0175,
+	0x0177, 0x0177,
+	0x017a, 0x017a,
+	0x017c, 0x017c,
+	0x017e, 0x0180,
+	0x0183, 0x0183,
+	0x0185, 0x0185,
+	0x0188, 0x0188,
+	0x018c, 0x018d,
+	0x0192, 0x0192,
+	0x0195, 0x0195,
+	0x0199, 0x019b,
+	0x019e, 0x019e,
+	0x01a1, 0x01a1,
+	0x01a3, 0x01a3,
+	0x01a5, 0x01a5,
+	0x01a8, 0x01a8,
+	0x01aa, 0x01ab,
+	0x01ad, 0x01ad,
+	0x01b0, 0x01b0,
+	0x01b4, 0x01b4,
+	0x01b6, 0x01b6,
+	0x01b9, 0x01ba,
+	0x01bd, 0x01bf,
+	0x01c6, 0x01c6,
+	0x01c9, 0x01c9,
+	0x01cc, 0x01cc,
+	0x01ce, 0x01ce,
+	0x01d0, 0x01d0,
+	0x01d2, 0x01d2,
+	0x01d4, 0x01d4,
+	0x01d6, 0x01d6,
+	0x01d8, 0x01d8,
+	0x01da, 0x01da,
+	0x01dc, 0x01dd,
+	0x01df, 0x01df,
+	0x01e1, 0x01e1,
+	0x01e3, 0x01e3,
+	0x01e5, 0x01e5,
+	0x01e7, 0x01e7,
+	0x01e9, 0x01e9,
+	0x01eb, 0x01eb,
+	0x01ed, 0x01ed,
+	0x01ef, 0x01f0,
+	0x01f3, 0x01f3,
+	0x01f5, 0x01f5,
+	0x01f9, 0x01f9,
+	0x01fb, 0x01fb,
+	0x01fd, 0x01fd,
+	0x01ff, 0x01ff,
+	0x0201, 0x0201,
+	0x0203, 0x0203,
+	0x0205, 0x0205,
+	0x0207, 0x0207,
+	0x0209, 0x0209,
+	0x020b, 0x020b,
+	0x020d, 0x020d,
+	0x020f, 0x020f,
+	0x0211, 0x0211,
+	0x0213, 0x0213,
+	0x0215, 0x0215,
+	0x0217, 0x0217,
+	0x0219, 0x0219,
+	0x021b, 0x021b,
+	0x021d, 0x021d,
+	0x021f, 0x021f,
+	0x0221, 0x0221,
+	0x0223, 0x0223,
+	0x0225, 0x0225,
+	0x0227, 0x0227,
+	0x0229, 0x0229,
+	0x022b, 0x022b,
+	0x022d, 0x022d,
+	0x022f, 0x022f,
+	0x0231, 0x0231,
+	0x0233, 0x0239,
+	0x023c, 0x023c,
+	0x023f, 0x0240,
+	0x0242, 0x0242,
+	0x0247, 0x0247,
+	0x0249, 0x0249,
+	0x024b, 0x024b,
+	0x024d, 0x024d,
+	0x024f, 0x0293,
+	0x0295, 0x02af,
+	0x0371, 0x0371,
+	0x0373, 0x0373,
+	0x0377, 0x0377,
+	0x037b, 0x037d,
+	0x0390, 0x0390,
+	0x03ac, 0x03ce,
+	0x03d0, 0x03d1,
+	0x03d5, 0x03d7,
+	0x03d9, 0x03d9,
+	0x03db, 0x03db,
+	0x03dd, 0x03dd,
+	0x03df, 0x03df,
+	0x03e1, 0x03e1,
+	0x03e3, 0x03e3,
+	0x03e5, 0x03e5,
+	0x03e7, 0x03e7,
+	0x03e9, 0x03e9,
+	0x03eb, 0x03eb,
+	0x03ed, 0x03ed,
+	0x03ef, 0x03f3,
+	0x03f5, 0x03f5,
+	0x03f8, 0x03f8,
+	0x03fb, 0x03fc,
+	0x0430, 0x045f,
+	0x0461, 0x0461,
+	0x0463, 0x0463,
+	0x0465, 0x0465,
+	0x0467, 0x0467,
+	0x0469, 0x0469,
+	0x046b, 0x046b,
+	0x046d, 0x046d,
+	0x046f, 0x046f,
+	0x0471, 0x0471,
+	0x0473, 0x0473,
+	0x0475, 0x0475,
+	0x0477, 0x0477,
+	0x0479, 0x0479,
+	0x047b, 0x047b,
+	0x047d, 0x047d,
+	0x047f, 0x047f,
+	0x0481, 0x0481,
+	0x048b, 0x048b,
+	0x048d, 0x048d,
+	0x048f, 0x048f,
+	0x0491, 0x0491,
+	0x0493, 0x0493,
+	0x0495, 0x0495,
+	0x0497, 0x0497,
+	0x0499, 0x0499,
+	0x049b, 0x049b,
+	0x049d, 0x049d,
+	0x049f, 0x049f,
+	0x04a1, 0x04a1,
+	0x04a3, 0x04a3,
+	0x04a5, 0x04a5,
+	0x04a7, 0x04a7,
+	0x04a9, 0x04a9,
+	0x04ab, 0x04ab,
+	0x04ad, 0x04ad,
+	0x04af, 0x04af,
+	0x04b1, 0x04b1,
+	0x04b3, 0x04b3,
+	0x04b5, 0x04b5,
+	0x04b7, 0x04b7,
+	0x04b9, 0x04b9,
+	0x04bb, 0x04bb,
+	0x04bd, 0x04bd,
+	0x04bf, 0x04bf,
+	0x04c2, 0x04c2,
+	0x04c4, 0x04c4,
+	0x04c6, 0x04c6,
+	0x04c8, 0x04c8,
+	0x04ca, 0x04ca,
+	0x04cc, 0x04cc,
+	0x04ce, 0x04cf,
+	0x04d1, 0x04d1,
+	0x04d3, 0x04d3,
+	0x04d5, 0x04d5,
+	0x04d7, 0x04d7,
+	0x04d9, 0x04d9,
+	0x04db, 0x04db,
+	0x04dd, 0x04dd,
+	0x04df, 0x04df,
+	0x04e1, 0x04e1,
+	0x04e3, 0x04e3,
+	0x04e5, 0x04e5,
+	0x04e7, 0x04e7,
+	0x04e9, 0x04e9,
+	0x04eb, 0x04eb,
+	0x04ed, 0x04ed,
+	0x04ef, 0x04ef,
+	0x04f1, 0x04f1,
+	0x04f3, 0x04f3,
+	0x04f5, 0x04f5,
+	0x04f7, 0x04f7,
+	0x04f9, 0x04f9,
+	0x04fb, 0x04fb,
+	0x04fd, 0x04fd,
+	0x04ff, 0x04ff,
+	0x0501, 0x0501,
+	0x0503, 0x0503,
+	0x0505, 0x0505,
+	0x0507, 0x0507,
+	0x0509, 0x0509,
+	0x050b, 0x050b,
+	0x050d, 0x050d,
+	0x050f, 0x050f,
+	0x0511, 0x0511,
+	0x0513, 0x0513,
+	0x0515, 0x0515,
+	0x0517, 0x0517,
+	0x0519, 0x0519,
+	0x051b, 0x051b,
+	0x051d, 0x051d,
+	0x051f, 0x051f,
+	0x0521, 0x0521,
+	0x0523, 0x0523,
+	0x0525, 0x0525,
+	0x0527, 0x0527,
+	0x0529, 0x0529,
+	0x052b, 0x052b,
+	0x052d, 0x052d,
+	0x052f, 0x052f,
+	0x0561, 0x0587,
+	0x13f8, 0x13fd,
+	0x1c80, 0x1c88,
+	0x1d00, 0x1d2b,
+	0x1d6b, 0x1d77,
+	0x1d79, 0x1d9a,
+	0x1e01, 0x1e01,
+	0x1e03, 0x1e03,
+	0x1e05, 0x1e05,
+	0x1e07, 0x1e07,
+	0x1e09, 0x1e09,
+	0x1e0b, 0x1e0b,
+	0x1e0d, 0x1e0d,
+	0x1e0f, 0x1e0f,
+	0x1e11, 0x1e11,
+	0x1e13, 0x1e13,
+	0x1e15, 0x1e15,
+	0x1e17, 0x1e17,
+	0x1e19, 0x1e19,
+	0x1e1b, 0x1e1b,
+	0x1e1d, 0x1e1d,
+	0x1e1f, 0x1e1f,
+	0x1e21, 0x1e21,
+	0x1e23, 0x1e23,
+	0x1e25, 0x1e25,
+	0x1e27, 0x1e27,
+	0x1e29, 0x1e29,
+	0x1e2b, 0x1e2b,
+	0x1e2d, 0x1e2d,
+	0x1e2f, 0x1e2f,
+	0x1e31, 0x1e31,
+	0x1e33, 0x1e33,
+	0x1e35, 0x1e35,
+	0x1e37, 0x1e37,
+	0x1e39, 0x1e39,
+	0x1e3b, 0x1e3b,
+	0x1e3d, 0x1e3d,
+	0x1e3f, 0x1e3f,
+	0x1e41, 0x1e41,
+	0x1e43, 0x1e43,
+	0x1e45, 0x1e45,
+	0x1e47, 0x1e47,
+	0x1e49, 0x1e49,
+	0x1e4b, 0x1e4b,
+	0x1e4d, 0x1e4d,
+	0x1e4f, 0x1e4f,
+	0x1e51, 0x1e51,
+	0x1e53, 0x1e53,
+	0x1e55, 0x1e55,
+	0x1e57, 0x1e57,
+	0x1e59, 0x1e59,
+	0x1e5b, 0x1e5b,
+	0x1e5d, 0x1e5d,
+	0x1e5f, 0x1e5f,
+	0x1e61, 0x1e61,
+	0x1e63, 0x1e63,
+	0x1e65, 0x1e65,
+	0x1e67, 0x1e67,
+	0x1e69, 0x1e69,
+	0x1e6b, 0x1e6b,
+	0x1e6d, 0x1e6d,
+	0x1e6f, 0x1e6f,
+	0x1e71, 0x1e71,
+	0x1e73, 0x1e73,
+	0x1e75, 0x1e75,
+	0x1e77, 0x1e77,
+	0x1e79, 0x1e79,
+	0x1e7b, 0x1e7b,
+	0x1e7d, 0x1e7d,
+	0x1e7f, 0x1e7f,
+	0x1e81, 0x1e81,
+	0x1e83, 0x1e83,
+	0x1e85, 0x1e85,
+	0x1e87, 0x1e87,
+	0x1e89, 0x1e89,
+	0x1e8b, 0x1e8b,
+	0x1e8d, 0x1e8d,
+	0x1e8f, 0x1e8f,
+	0x1e91, 0x1e91,
+	0x1e93, 0x1e93,
+	0x1e95, 0x1e9d,
+	0x1e9f, 0x1e9f,
+	0x1ea1, 0x1ea1,
+	0x1ea3, 0x1ea3,
+	0x1ea5, 0x1ea5,
+	0x1ea7, 0x1ea7,
+	0x1ea9, 0x1ea9,
+	0x1eab, 0x1eab,
+	0x1ead, 0x1ead,
+	0x1eaf, 0x1eaf,
+	0x1eb1, 0x1eb1,
+	0x1eb3, 0x1eb3,
+	0x1eb5, 0x1eb5,
+	0x1eb7, 0x1eb7,
+	0x1eb9, 0x1eb9,
+	0x1ebb, 0x1ebb,
+	0x1ebd, 0x1ebd,
+	0x1ebf, 0x1ebf,
+	0x1ec1, 0x1ec1,
+	0x1ec3, 0x1ec3,
+	0x1ec5, 0x1ec5,
+	0x1ec7, 0x1ec7,
+	0x1ec9, 0x1ec9,
+	0x1ecb, 0x1ecb,
+	0x1ecd, 0x1ecd,
+	0x1ecf, 0x1ecf,
+	0x1ed1, 0x1ed1,
+	0x1ed3, 0x1ed3,
+	0x1ed5, 0x1ed5,
+	0x1ed7, 0x1ed7,
+	0x1ed9, 0x1ed9,
+	0x1edb, 0x1edb,
+	0x1edd, 0x1edd,
+	0x1edf, 0x1edf,
+	0x1ee1, 0x1ee1,
+	0x1ee3, 0x1ee3,
+	0x1ee5, 0x1ee5,
+	0x1ee7, 0x1ee7,
+	0x1ee9, 0x1ee9,
+	0x1eeb, 0x1eeb,
+	0x1eed, 0x1eed,
+	0x1eef, 0x1eef,
+	0x1ef1, 0x1ef1,
+	0x1ef3, 0x1ef3,
+	0x1ef5, 0x1ef5,
+	0x1ef7, 0x1ef7,
+	0x1ef9, 0x1ef9,
+	0x1efb, 0x1efb,
+	0x1efd, 0x1efd,
+	0x1eff, 0x1f07,
+	0x1f10, 0x1f15,
+	0x1f20, 0x1f27,
+	0x1f30, 0x1f37,
+	0x1f40, 0x1f45,
+	0x1f50, 0x1f57,
+	0x1f60, 0x1f67,
+	0x1f70, 0x1f7d,
+	0x1f80, 0x1f87,
+	0x1f90, 0x1f97,
+	0x1fa0, 0x1fa7,
+	0x1fb0, 0x1fb4,
+	0x1fb6, 0x1fb7,
+	0x1fbe, 0x1fbe,
+	0x1fc2, 0x1fc4,
+	0x1fc6, 0x1fc7,
+	0x1fd0, 0x1fd3,
+	0x1fd6, 0x1fd7,
+	0x1fe0, 0x1fe7,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ff7,
+	0x210a, 0x210a,
+	0x210e, 0x210f,
+	0x2113, 0x2113,
+	0x212f, 0x212f,
+	0x2134, 0x2134,
+	0x2139, 0x2139,
+	0x213c, 0x213d,
+	0x2146, 0x2149,
+	0x214e, 0x214e,
+	0x2184, 0x2184,
+	0x2c30, 0x2c5e,
+	0x2c61, 0x2c61,
+	0x2c65, 0x2c66,
+	0x2c68, 0x2c68,
+	0x2c6a, 0x2c6a,
+	0x2c6c, 0x2c6c,
+	0x2c71, 0x2c71,
+	0x2c73, 0x2c74,
+	0x2c76, 0x2c7b,
+	0x2c81, 0x2c81,
+	0x2c83, 0x2c83,
+	0x2c85, 0x2c85,
+	0x2c87, 0x2c87,
+	0x2c89, 0x2c89,
+	0x2c8b, 0x2c8b,
+	0x2c8d, 0x2c8d,
+	0x2c8f, 0x2c8f,
+	0x2c91, 0x2c91,
+	0x2c93, 0x2c93,
+	0x2c95, 0x2c95,
+	0x2c97, 0x2c97,
+	0x2c99, 0x2c99,
+	0x2c9b, 0x2c9b,
+	0x2c9d, 0x2c9d,
+	0x2c9f, 0x2c9f,
+	0x2ca1, 0x2ca1,
+	0x2ca3, 0x2ca3,
+	0x2ca5, 0x2ca5,
+	0x2ca7, 0x2ca7,
+	0x2ca9, 0x2ca9,
+	0x2cab, 0x2cab,
+	0x2cad, 0x2cad,
+	0x2caf, 0x2caf,
+	0x2cb1, 0x2cb1,
+	0x2cb3, 0x2cb3,
+	0x2cb5, 0x2cb5,
+	0x2cb7, 0x2cb7,
+	0x2cb9, 0x2cb9,
+	0x2cbb, 0x2cbb,
+	0x2cbd, 0x2cbd,
+	0x2cbf, 0x2cbf,
+	0x2cc1, 0x2cc1,
+	0x2cc3, 0x2cc3,
+	0x2cc5, 0x2cc5,
+	0x2cc7, 0x2cc7,
+	0x2cc9, 0x2cc9,
+	0x2ccb, 0x2ccb,
+	0x2ccd, 0x2ccd,
+	0x2ccf, 0x2ccf,
+	0x2cd1, 0x2cd1,
+	0x2cd3, 0x2cd3,
+	0x2cd5, 0x2cd5,
+	0x2cd7, 0x2cd7,
+	0x2cd9, 0x2cd9,
+	0x2cdb, 0x2cdb,
+	0x2cdd, 0x2cdd,
+	0x2cdf, 0x2cdf,
+	0x2ce1, 0x2ce1,
+	0x2ce3, 0x2ce4,
+	0x2cec, 0x2cec,
+	0x2cee, 0x2cee,
+	0x2cf3, 0x2cf3,
+	0x2d00, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0xa641, 0xa641,
+	0xa643, 0xa643,
+	0xa645, 0xa645,
+	0xa647, 0xa647,
+	0xa649, 0xa649,
+	0xa64b, 0xa64b,
+	0xa64d, 0xa64d,
+	0xa64f, 0xa64f,
+	0xa651, 0xa651,
+	0xa653, 0xa653,
+	0xa655, 0xa655,
+	0xa657, 0xa657,
+	0xa659, 0xa659,
+	0xa65b, 0xa65b,
+	0xa65d, 0xa65d,
+	0xa65f, 0xa65f,
+	0xa661, 0xa661,
+	0xa663, 0xa663,
+	0xa665, 0xa665,
+	0xa667, 0xa667,
+	0xa669, 0xa669,
+	0xa66b, 0xa66b,
+	0xa66d, 0xa66d,
+	0xa681, 0xa681,
+	0xa683, 0xa683,
+	0xa685, 0xa685,
+	0xa687, 0xa687,
+	0xa689, 0xa689,
+	0xa68b, 0xa68b,
+	0xa68d, 0xa68d,
+	0xa68f, 0xa68f,
+	0xa691, 0xa691,
+	0xa693, 0xa693,
+	0xa695, 0xa695,
+	0xa697, 0xa697,
+	0xa699, 0xa699,
+	0xa69b, 0xa69b,
+	0xa723, 0xa723,
+	0xa725, 0xa725,
+	0xa727, 0xa727,
+	0xa729, 0xa729,
+	0xa72b, 0xa72b,
+	0xa72d, 0xa72d,
+	0xa72f, 0xa731,
+	0xa733, 0xa733,
+	0xa735, 0xa735,
+	0xa737, 0xa737,
+	0xa739, 0xa739,
+	0xa73b, 0xa73b,
+	0xa73d, 0xa73d,
+	0xa73f, 0xa73f,
+	0xa741, 0xa741,
+	0xa743, 0xa743,
+	0xa745, 0xa745,
+	0xa747, 0xa747,
+	0xa749, 0xa749,
+	0xa74b, 0xa74b,
+	0xa74d, 0xa74d,
+	0xa74f, 0xa74f,
+	0xa751, 0xa751,
+	0xa753, 0xa753,
+	0xa755, 0xa755,
+	0xa757, 0xa757,
+	0xa759, 0xa759,
+	0xa75b, 0xa75b,
+	0xa75d, 0xa75d,
+	0xa75f, 0xa75f,
+	0xa761, 0xa761,
+	0xa763, 0xa763,
+	0xa765, 0xa765,
+	0xa767, 0xa767,
+	0xa769, 0xa769,
+	0xa76b, 0xa76b,
+	0xa76d, 0xa76d,
+	0xa76f, 0xa76f,
+	0xa771, 0xa778,
+	0xa77a, 0xa77a,
+	0xa77c, 0xa77c,
+	0xa77f, 0xa77f,
+	0xa781, 0xa781,
+	0xa783, 0xa783,
+	0xa785, 0xa785,
+	0xa787, 0xa787,
+	0xa78c, 0xa78c,
+	0xa78e, 0xa78e,
+	0xa791, 0xa791,
+	0xa793, 0xa795,
+	0xa797, 0xa797,
+	0xa799, 0xa799,
+	0xa79b, 0xa79b,
+	0xa79d, 0xa79d,
+	0xa79f, 0xa79f,
+	0xa7a1, 0xa7a1,
+	0xa7a3, 0xa7a3,
+	0xa7a5, 0xa7a5,
+	0xa7a7, 0xa7a7,
+	0xa7a9, 0xa7a9,
+	0xa7b5, 0xa7b5,
+	0xa7b7, 0xa7b7,
+	0xa7fa, 0xa7fa,
+	0xab30, 0xab5a,
+	0xab60, 0xab65,
+	0xab70, 0xabbf,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xff41, 0xff5a,
+	0x10428, 0x1044f,
+	0x104d8, 0x104fb,
+	0x10cc0, 0x10cf2,
+	0x118c0, 0x118df,
+	0x1d41a, 0x1d433,
+	0x1d44e, 0x1d454,
+	0x1d456, 0x1d467,
+	0x1d482, 0x1d49b,
+	0x1d4b6, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d4cf,
+	0x1d4ea, 0x1d503,
+	0x1d51e, 0x1d537,
+	0x1d552, 0x1d56b,
+	0x1d586, 0x1d59f,
+	0x1d5ba, 0x1d5d3,
+	0x1d5ee, 0x1d607,
+	0x1d622, 0x1d63b,
+	0x1d656, 0x1d66f,
+	0x1d68a, 0x1d6a5,
+	0x1d6c2, 0x1d6da,
+	0x1d6dc, 0x1d6e1,
+	0x1d6fc, 0x1d714,
+	0x1d716, 0x1d71b,
+	0x1d736, 0x1d74e,
+	0x1d750, 0x1d755,
+	0x1d770, 0x1d788,
+	0x1d78a, 0x1d78f,
+	0x1d7aa, 0x1d7c2,
+	0x1d7c4, 0x1d7c9,
+	0x1d7cb, 0x1d7cb,
+	0x1e922, 0x1e943,
+}; /* CR_Ll */
+
+/* 'Lm': General Category */
+static const OnigCodePoint CR_Lm[] = {
+	57,
+	0x02b0, 0x02c1,
+	0x02c6, 0x02d1,
+	0x02e0, 0x02e4,
+	0x02ec, 0x02ec,
+	0x02ee, 0x02ee,
+	0x0374, 0x0374,
+	0x037a, 0x037a,
+	0x0559, 0x0559,
+	0x0640, 0x0640,
+	0x06e5, 0x06e6,
+	0x07f4, 0x07f5,
+	0x07fa, 0x07fa,
+	0x081a, 0x081a,
+	0x0824, 0x0824,
+	0x0828, 0x0828,
+	0x0971, 0x0971,
+	0x0e46, 0x0e46,
+	0x0ec6, 0x0ec6,
+	0x10fc, 0x10fc,
+	0x17d7, 0x17d7,
+	0x1843, 0x1843,
+	0x1aa7, 0x1aa7,
+	0x1c78, 0x1c7d,
+	0x1d2c, 0x1d6a,
+	0x1d78, 0x1d78,
+	0x1d9b, 0x1dbf,
+	0x2071, 0x2071,
+	0x207f, 0x207f,
+	0x2090, 0x209c,
+	0x2c7c, 0x2c7d,
+	0x2d6f, 0x2d6f,
+	0x2e2f, 0x2e2f,
+	0x3005, 0x3005,
+	0x3031, 0x3035,
+	0x303b, 0x303b,
+	0x309d, 0x309e,
+	0x30fc, 0x30fe,
+	0xa015, 0xa015,
+	0xa4f8, 0xa4fd,
+	0xa60c, 0xa60c,
+	0xa67f, 0xa67f,
+	0xa69c, 0xa69d,
+	0xa717, 0xa71f,
+	0xa770, 0xa770,
+	0xa788, 0xa788,
+	0xa7f8, 0xa7f9,
+	0xa9cf, 0xa9cf,
+	0xa9e6, 0xa9e6,
+	0xaa70, 0xaa70,
+	0xaadd, 0xaadd,
+	0xaaf3, 0xaaf4,
+	0xab5c, 0xab5f,
+	0xff70, 0xff70,
+	0xff9e, 0xff9f,
+	0x16b40, 0x16b43,
+	0x16f93, 0x16f9f,
+	0x16fe0, 0x16fe1,
+}; /* CR_Lm */
+
+/* 'Lo': General Category */
+static const OnigCodePoint CR_Lo[] = {
+	459,
+	0x00aa, 0x00aa,
+	0x00ba, 0x00ba,
+	0x01bb, 0x01bb,
+	0x01c0, 0x01c3,
+	0x0294, 0x0294,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f2,
+	0x0620, 0x063f,
+	0x0641, 0x064a,
+	0x066e, 0x066f,
+	0x0671, 0x06d3,
+	0x06d5, 0x06d5,
+	0x06ee, 0x06ef,
+	0x06fa, 0x06fc,
+	0x06ff, 0x06ff,
+	0x0710, 0x0710,
+	0x0712, 0x072f,
+	0x074d, 0x07a5,
+	0x07b1, 0x07b1,
+	0x07ca, 0x07ea,
+	0x0800, 0x0815,
+	0x0840, 0x0858,
+	0x0860, 0x086a,
+	0x08a0, 0x08b4,
+	0x08b6, 0x08bd,
+	0x0904, 0x0939,
+	0x093d, 0x093d,
+	0x0950, 0x0950,
+	0x0958, 0x0961,
+	0x0972, 0x0980,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bd, 0x09bd,
+	0x09ce, 0x09ce,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e1,
+	0x09f0, 0x09f1,
+	0x09fc, 0x09fc,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a72, 0x0a74,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abd, 0x0abd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae1,
+	0x0af9, 0x0af9,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3d, 0x0b3d,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b61,
+	0x0b71, 0x0b71,
+	0x0b83, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bd0, 0x0bd0,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c39,
+	0x0c3d, 0x0c3d,
+	0x0c58, 0x0c5a,
+	0x0c60, 0x0c61,
+	0x0c80, 0x0c80,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbd, 0x0cbd,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce1,
+	0x0cf1, 0x0cf2,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d3a,
+	0x0d3d, 0x0d3d,
+	0x0d4e, 0x0d4e,
+	0x0d54, 0x0d56,
+	0x0d5f, 0x0d61,
+	0x0d7a, 0x0d7f,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0e01, 0x0e30,
+	0x0e32, 0x0e33,
+	0x0e40, 0x0e45,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb0,
+	0x0eb2, 0x0eb3,
+	0x0ebd, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f00,
+	0x0f40, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f88, 0x0f8c,
+	0x1000, 0x102a,
+	0x103f, 0x103f,
+	0x1050, 0x1055,
+	0x105a, 0x105d,
+	0x1061, 0x1061,
+	0x1065, 0x1066,
+	0x106e, 0x1070,
+	0x1075, 0x1081,
+	0x108e, 0x108e,
+	0x10d0, 0x10fa,
+	0x10fd, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x1380, 0x138f,
+	0x1401, 0x166c,
+	0x166f, 0x167f,
+	0x1681, 0x169a,
+	0x16a0, 0x16ea,
+	0x16f1, 0x16f8,
+	0x1700, 0x170c,
+	0x170e, 0x1711,
+	0x1720, 0x1731,
+	0x1740, 0x1751,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1780, 0x17b3,
+	0x17dc, 0x17dc,
+	0x1820, 0x1842,
+	0x1844, 0x1877,
+	0x1880, 0x1884,
+	0x1887, 0x18a8,
+	0x18aa, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191e,
+	0x1950, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x1a00, 0x1a16,
+	0x1a20, 0x1a54,
+	0x1b05, 0x1b33,
+	0x1b45, 0x1b4b,
+	0x1b83, 0x1ba0,
+	0x1bae, 0x1baf,
+	0x1bba, 0x1be5,
+	0x1c00, 0x1c23,
+	0x1c4d, 0x1c4f,
+	0x1c5a, 0x1c77,
+	0x1ce9, 0x1cec,
+	0x1cee, 0x1cf1,
+	0x1cf5, 0x1cf6,
+	0x2135, 0x2138,
+	0x2d30, 0x2d67,
+	0x2d80, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x3006, 0x3006,
+	0x303c, 0x303c,
+	0x3041, 0x3096,
+	0x309f, 0x309f,
+	0x30a1, 0x30fa,
+	0x30ff, 0x30ff,
+	0x3105, 0x312e,
+	0x3131, 0x318e,
+	0x31a0, 0x31ba,
+	0x31f0, 0x31ff,
+	0x3400, 0x4db5,
+	0x4e00, 0x9fea,
+	0xa000, 0xa014,
+	0xa016, 0xa48c,
+	0xa4d0, 0xa4f7,
+	0xa500, 0xa60b,
+	0xa610, 0xa61f,
+	0xa62a, 0xa62b,
+	0xa66e, 0xa66e,
+	0xa6a0, 0xa6e5,
+	0xa78f, 0xa78f,
+	0xa7f7, 0xa7f7,
+	0xa7fb, 0xa801,
+	0xa803, 0xa805,
+	0xa807, 0xa80a,
+	0xa80c, 0xa822,
+	0xa840, 0xa873,
+	0xa882, 0xa8b3,
+	0xa8f2, 0xa8f7,
+	0xa8fb, 0xa8fb,
+	0xa8fd, 0xa8fd,
+	0xa90a, 0xa925,
+	0xa930, 0xa946,
+	0xa960, 0xa97c,
+	0xa984, 0xa9b2,
+	0xa9e0, 0xa9e4,
+	0xa9e7, 0xa9ef,
+	0xa9fa, 0xa9fe,
+	0xaa00, 0xaa28,
+	0xaa40, 0xaa42,
+	0xaa44, 0xaa4b,
+	0xaa60, 0xaa6f,
+	0xaa71, 0xaa76,
+	0xaa7a, 0xaa7a,
+	0xaa7e, 0xaaaf,
+	0xaab1, 0xaab1,
+	0xaab5, 0xaab6,
+	0xaab9, 0xaabd,
+	0xaac0, 0xaac0,
+	0xaac2, 0xaac2,
+	0xaadb, 0xaadc,
+	0xaae0, 0xaaea,
+	0xaaf2, 0xaaf2,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xabc0, 0xabe2,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xf900, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb1d, 0xfb1d,
+	0xfb1f, 0xfb28,
+	0xfb2a, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbb1,
+	0xfbd3, 0xfd3d,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdf0, 0xfdfb,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xff66, 0xff6f,
+	0xff71, 0xff9d,
+	0xffa0, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0x10000, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x10300, 0x1031f,
+	0x1032d, 0x10340,
+	0x10342, 0x10349,
+	0x10350, 0x10375,
+	0x10380, 0x1039d,
+	0x103a0, 0x103c3,
+	0x103c8, 0x103cf,
+	0x10450, 0x1049d,
+	0x10500, 0x10527,
+	0x10530, 0x10563,
+	0x10600, 0x10736,
+	0x10740, 0x10755,
+	0x10760, 0x10767,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10860, 0x10876,
+	0x10880, 0x1089e,
+	0x108e0, 0x108f2,
+	0x108f4, 0x108f5,
+	0x10900, 0x10915,
+	0x10920, 0x10939,
+	0x10980, 0x109b7,
+	0x109be, 0x109bf,
+	0x10a00, 0x10a00,
+	0x10a10, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a60, 0x10a7c,
+	0x10a80, 0x10a9c,
+	0x10ac0, 0x10ac7,
+	0x10ac9, 0x10ae4,
+	0x10b00, 0x10b35,
+	0x10b40, 0x10b55,
+	0x10b60, 0x10b72,
+	0x10b80, 0x10b91,
+	0x10c00, 0x10c48,
+	0x11003, 0x11037,
+	0x11083, 0x110af,
+	0x110d0, 0x110e8,
+	0x11103, 0x11126,
+	0x11150, 0x11172,
+	0x11176, 0x11176,
+	0x11183, 0x111b2,
+	0x111c1, 0x111c4,
+	0x111da, 0x111da,
+	0x111dc, 0x111dc,
+	0x11200, 0x11211,
+	0x11213, 0x1122b,
+	0x11280, 0x11286,
+	0x11288, 0x11288,
+	0x1128a, 0x1128d,
+	0x1128f, 0x1129d,
+	0x1129f, 0x112a8,
+	0x112b0, 0x112de,
+	0x11305, 0x1130c,
+	0x1130f, 0x11310,
+	0x11313, 0x11328,
+	0x1132a, 0x11330,
+	0x11332, 0x11333,
+	0x11335, 0x11339,
+	0x1133d, 0x1133d,
+	0x11350, 0x11350,
+	0x1135d, 0x11361,
+	0x11400, 0x11434,
+	0x11447, 0x1144a,
+	0x11480, 0x114af,
+	0x114c4, 0x114c5,
+	0x114c7, 0x114c7,
+	0x11580, 0x115ae,
+	0x115d8, 0x115db,
+	0x11600, 0x1162f,
+	0x11644, 0x11644,
+	0x11680, 0x116aa,
+	0x11700, 0x11719,
+	0x118ff, 0x118ff,
+	0x11a00, 0x11a00,
+	0x11a0b, 0x11a32,
+	0x11a3a, 0x11a3a,
+	0x11a50, 0x11a50,
+	0x11a5c, 0x11a83,
+	0x11a86, 0x11a89,
+	0x11ac0, 0x11af8,
+	0x11c00, 0x11c08,
+	0x11c0a, 0x11c2e,
+	0x11c40, 0x11c40,
+	0x11c72, 0x11c8f,
+	0x11d00, 0x11d06,
+	0x11d08, 0x11d09,
+	0x11d0b, 0x11d30,
+	0x11d46, 0x11d46,
+	0x12000, 0x12399,
+	0x12480, 0x12543,
+	0x13000, 0x1342e,
+	0x14400, 0x14646,
+	0x16800, 0x16a38,
+	0x16a40, 0x16a5e,
+	0x16ad0, 0x16aed,
+	0x16b00, 0x16b2f,
+	0x16b63, 0x16b77,
+	0x16b7d, 0x16b8f,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f50,
+	0x17000, 0x187ec,
+	0x18800, 0x18af2,
+	0x1b000, 0x1b11e,
+	0x1b170, 0x1b2fb,
+	0x1bc00, 0x1bc6a,
+	0x1bc70, 0x1bc7c,
+	0x1bc80, 0x1bc88,
+	0x1bc90, 0x1bc99,
+	0x1e800, 0x1e8c4,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x20000, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2b820, 0x2cea1,
+	0x2ceb0, 0x2ebe0,
+	0x2f800, 0x2fa1d,
+}; /* CR_Lo */
+
+/* 'Lt': General Category */
+static const OnigCodePoint CR_Lt[] = {
+	10,
+	0x01c5, 0x01c5,
+	0x01c8, 0x01c8,
+	0x01cb, 0x01cb,
+	0x01f2, 0x01f2,
+	0x1f88, 0x1f8f,
+	0x1f98, 0x1f9f,
+	0x1fa8, 0x1faf,
+	0x1fbc, 0x1fbc,
+	0x1fcc, 0x1fcc,
+	0x1ffc, 0x1ffc,
+}; /* CR_Lt */
+
+/* 'Lu': General Category */
+static const OnigCodePoint CR_Lu[] = {
+	627,
+	0x0041, 0x005a,
+	0x00c0, 0x00d6,
+	0x00d8, 0x00de,
+	0x0100, 0x0100,
+	0x0102, 0x0102,
+	0x0104, 0x0104,
+	0x0106, 0x0106,
+	0x0108, 0x0108,
+	0x010a, 0x010a,
+	0x010c, 0x010c,
+	0x010e, 0x010e,
+	0x0110, 0x0110,
+	0x0112, 0x0112,
+	0x0114, 0x0114,
+	0x0116, 0x0116,
+	0x0118, 0x0118,
+	0x011a, 0x011a,
+	0x011c, 0x011c,
+	0x011e, 0x011e,
+	0x0120, 0x0120,
+	0x0122, 0x0122,
+	0x0124, 0x0124,
+	0x0126, 0x0126,
+	0x0128, 0x0128,
+	0x012a, 0x012a,
+	0x012c, 0x012c,
+	0x012e, 0x012e,
+	0x0130, 0x0130,
+	0x0132, 0x0132,
+	0x0134, 0x0134,
+	0x0136, 0x0136,
+	0x0139, 0x0139,
+	0x013b, 0x013b,
+	0x013d, 0x013d,
+	0x013f, 0x013f,
+	0x0141, 0x0141,
+	0x0143, 0x0143,
+	0x0145, 0x0145,
+	0x0147, 0x0147,
+	0x014a, 0x014a,
+	0x014c, 0x014c,
+	0x014e, 0x014e,
+	0x0150, 0x0150,
+	0x0152, 0x0152,
+	0x0154, 0x0154,
+	0x0156, 0x0156,
+	0x0158, 0x0158,
+	0x015a, 0x015a,
+	0x015c, 0x015c,
+	0x015e, 0x015e,
+	0x0160, 0x0160,
+	0x0162, 0x0162,
+	0x0164, 0x0164,
+	0x0166, 0x0166,
+	0x0168, 0x0168,
+	0x016a, 0x016a,
+	0x016c, 0x016c,
+	0x016e, 0x016e,
+	0x0170, 0x0170,
+	0x0172, 0x0172,
+	0x0174, 0x0174,
+	0x0176, 0x0176,
+	0x0178, 0x0179,
+	0x017b, 0x017b,
+	0x017d, 0x017d,
+	0x0181, 0x0182,
+	0x0184, 0x0184,
+	0x0186, 0x0187,
+	0x0189, 0x018b,
+	0x018e, 0x0191,
+	0x0193, 0x0194,
+	0x0196, 0x0198,
+	0x019c, 0x019d,
+	0x019f, 0x01a0,
+	0x01a2, 0x01a2,
+	0x01a4, 0x01a4,
+	0x01a6, 0x01a7,
+	0x01a9, 0x01a9,
+	0x01ac, 0x01ac,
+	0x01ae, 0x01af,
+	0x01b1, 0x01b3,
+	0x01b5, 0x01b5,
+	0x01b7, 0x01b8,
+	0x01bc, 0x01bc,
+	0x01c4, 0x01c4,
+	0x01c7, 0x01c7,
+	0x01ca, 0x01ca,
+	0x01cd, 0x01cd,
+	0x01cf, 0x01cf,
+	0x01d1, 0x01d1,
+	0x01d3, 0x01d3,
+	0x01d5, 0x01d5,
+	0x01d7, 0x01d7,
+	0x01d9, 0x01d9,
+	0x01db, 0x01db,
+	0x01de, 0x01de,
+	0x01e0, 0x01e0,
+	0x01e2, 0x01e2,
+	0x01e4, 0x01e4,
+	0x01e6, 0x01e6,
+	0x01e8, 0x01e8,
+	0x01ea, 0x01ea,
+	0x01ec, 0x01ec,
+	0x01ee, 0x01ee,
+	0x01f1, 0x01f1,
+	0x01f4, 0x01f4,
+	0x01f6, 0x01f8,
+	0x01fa, 0x01fa,
+	0x01fc, 0x01fc,
+	0x01fe, 0x01fe,
+	0x0200, 0x0200,
+	0x0202, 0x0202,
+	0x0204, 0x0204,
+	0x0206, 0x0206,
+	0x0208, 0x0208,
+	0x020a, 0x020a,
+	0x020c, 0x020c,
+	0x020e, 0x020e,
+	0x0210, 0x0210,
+	0x0212, 0x0212,
+	0x0214, 0x0214,
+	0x0216, 0x0216,
+	0x0218, 0x0218,
+	0x021a, 0x021a,
+	0x021c, 0x021c,
+	0x021e, 0x021e,
+	0x0220, 0x0220,
+	0x0222, 0x0222,
+	0x0224, 0x0224,
+	0x0226, 0x0226,
+	0x0228, 0x0228,
+	0x022a, 0x022a,
+	0x022c, 0x022c,
+	0x022e, 0x022e,
+	0x0230, 0x0230,
+	0x0232, 0x0232,
+	0x023a, 0x023b,
+	0x023d, 0x023e,
+	0x0241, 0x0241,
+	0x0243, 0x0246,
+	0x0248, 0x0248,
+	0x024a, 0x024a,
+	0x024c, 0x024c,
+	0x024e, 0x024e,
+	0x0370, 0x0370,
+	0x0372, 0x0372,
+	0x0376, 0x0376,
+	0x037f, 0x037f,
+	0x0386, 0x0386,
+	0x0388, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x038f,
+	0x0391, 0x03a1,
+	0x03a3, 0x03ab,
+	0x03cf, 0x03cf,
+	0x03d2, 0x03d4,
+	0x03d8, 0x03d8,
+	0x03da, 0x03da,
+	0x03dc, 0x03dc,
+	0x03de, 0x03de,
+	0x03e0, 0x03e0,
+	0x03e2, 0x03e2,
+	0x03e4, 0x03e4,
+	0x03e6, 0x03e6,
+	0x03e8, 0x03e8,
+	0x03ea, 0x03ea,
+	0x03ec, 0x03ec,
+	0x03ee, 0x03ee,
+	0x03f4, 0x03f4,
+	0x03f7, 0x03f7,
+	0x03f9, 0x03fa,
+	0x03fd, 0x042f,
+	0x0460, 0x0460,
+	0x0462, 0x0462,
+	0x0464, 0x0464,
+	0x0466, 0x0466,
+	0x0468, 0x0468,
+	0x046a, 0x046a,
+	0x046c, 0x046c,
+	0x046e, 0x046e,
+	0x0470, 0x0470,
+	0x0472, 0x0472,
+	0x0474, 0x0474,
+	0x0476, 0x0476,
+	0x0478, 0x0478,
+	0x047a, 0x047a,
+	0x047c, 0x047c,
+	0x047e, 0x047e,
+	0x0480, 0x0480,
+	0x048a, 0x048a,
+	0x048c, 0x048c,
+	0x048e, 0x048e,
+	0x0490, 0x0490,
+	0x0492, 0x0492,
+	0x0494, 0x0494,
+	0x0496, 0x0496,
+	0x0498, 0x0498,
+	0x049a, 0x049a,
+	0x049c, 0x049c,
+	0x049e, 0x049e,
+	0x04a0, 0x04a0,
+	0x04a2, 0x04a2,
+	0x04a4, 0x04a4,
+	0x04a6, 0x04a6,
+	0x04a8, 0x04a8,
+	0x04aa, 0x04aa,
+	0x04ac, 0x04ac,
+	0x04ae, 0x04ae,
+	0x04b0, 0x04b0,
+	0x04b2, 0x04b2,
+	0x04b4, 0x04b4,
+	0x04b6, 0x04b6,
+	0x04b8, 0x04b8,
+	0x04ba, 0x04ba,
+	0x04bc, 0x04bc,
+	0x04be, 0x04be,
+	0x04c0, 0x04c1,
+	0x04c3, 0x04c3,
+	0x04c5, 0x04c5,
+	0x04c7, 0x04c7,
+	0x04c9, 0x04c9,
+	0x04cb, 0x04cb,
+	0x04cd, 0x04cd,
+	0x04d0, 0x04d0,
+	0x04d2, 0x04d2,
+	0x04d4, 0x04d4,
+	0x04d6, 0x04d6,
+	0x04d8, 0x04d8,
+	0x04da, 0x04da,
+	0x04dc, 0x04dc,
+	0x04de, 0x04de,
+	0x04e0, 0x04e0,
+	0x04e2, 0x04e2,
+	0x04e4, 0x04e4,
+	0x04e6, 0x04e6,
+	0x04e8, 0x04e8,
+	0x04ea, 0x04ea,
+	0x04ec, 0x04ec,
+	0x04ee, 0x04ee,
+	0x04f0, 0x04f0,
+	0x04f2, 0x04f2,
+	0x04f4, 0x04f4,
+	0x04f6, 0x04f6,
+	0x04f8, 0x04f8,
+	0x04fa, 0x04fa,
+	0x04fc, 0x04fc,
+	0x04fe, 0x04fe,
+	0x0500, 0x0500,
+	0x0502, 0x0502,
+	0x0504, 0x0504,
+	0x0506, 0x0506,
+	0x0508, 0x0508,
+	0x050a, 0x050a,
+	0x050c, 0x050c,
+	0x050e, 0x050e,
+	0x0510, 0x0510,
+	0x0512, 0x0512,
+	0x0514, 0x0514,
+	0x0516, 0x0516,
+	0x0518, 0x0518,
+	0x051a, 0x051a,
+	0x051c, 0x051c,
+	0x051e, 0x051e,
+	0x0520, 0x0520,
+	0x0522, 0x0522,
+	0x0524, 0x0524,
+	0x0526, 0x0526,
+	0x0528, 0x0528,
+	0x052a, 0x052a,
+	0x052c, 0x052c,
+	0x052e, 0x052e,
+	0x0531, 0x0556,
+	0x10a0, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x13a0, 0x13f5,
+	0x1e00, 0x1e00,
+	0x1e02, 0x1e02,
+	0x1e04, 0x1e04,
+	0x1e06, 0x1e06,
+	0x1e08, 0x1e08,
+	0x1e0a, 0x1e0a,
+	0x1e0c, 0x1e0c,
+	0x1e0e, 0x1e0e,
+	0x1e10, 0x1e10,
+	0x1e12, 0x1e12,
+	0x1e14, 0x1e14,
+	0x1e16, 0x1e16,
+	0x1e18, 0x1e18,
+	0x1e1a, 0x1e1a,
+	0x1e1c, 0x1e1c,
+	0x1e1e, 0x1e1e,
+	0x1e20, 0x1e20,
+	0x1e22, 0x1e22,
+	0x1e24, 0x1e24,
+	0x1e26, 0x1e26,
+	0x1e28, 0x1e28,
+	0x1e2a, 0x1e2a,
+	0x1e2c, 0x1e2c,
+	0x1e2e, 0x1e2e,
+	0x1e30, 0x1e30,
+	0x1e32, 0x1e32,
+	0x1e34, 0x1e34,
+	0x1e36, 0x1e36,
+	0x1e38, 0x1e38,
+	0x1e3a, 0x1e3a,
+	0x1e3c, 0x1e3c,
+	0x1e3e, 0x1e3e,
+	0x1e40, 0x1e40,
+	0x1e42, 0x1e42,
+	0x1e44, 0x1e44,
+	0x1e46, 0x1e46,
+	0x1e48, 0x1e48,
+	0x1e4a, 0x1e4a,
+	0x1e4c, 0x1e4c,
+	0x1e4e, 0x1e4e,
+	0x1e50, 0x1e50,
+	0x1e52, 0x1e52,
+	0x1e54, 0x1e54,
+	0x1e56, 0x1e56,
+	0x1e58, 0x1e58,
+	0x1e5a, 0x1e5a,
+	0x1e5c, 0x1e5c,
+	0x1e5e, 0x1e5e,
+	0x1e60, 0x1e60,
+	0x1e62, 0x1e62,
+	0x1e64, 0x1e64,
+	0x1e66, 0x1e66,
+	0x1e68, 0x1e68,
+	0x1e6a, 0x1e6a,
+	0x1e6c, 0x1e6c,
+	0x1e6e, 0x1e6e,
+	0x1e70, 0x1e70,
+	0x1e72, 0x1e72,
+	0x1e74, 0x1e74,
+	0x1e76, 0x1e76,
+	0x1e78, 0x1e78,
+	0x1e7a, 0x1e7a,
+	0x1e7c, 0x1e7c,
+	0x1e7e, 0x1e7e,
+	0x1e80, 0x1e80,
+	0x1e82, 0x1e82,
+	0x1e84, 0x1e84,
+	0x1e86, 0x1e86,
+	0x1e88, 0x1e88,
+	0x1e8a, 0x1e8a,
+	0x1e8c, 0x1e8c,
+	0x1e8e, 0x1e8e,
+	0x1e90, 0x1e90,
+	0x1e92, 0x1e92,
+	0x1e94, 0x1e94,
+	0x1e9e, 0x1e9e,
+	0x1ea0, 0x1ea0,
+	0x1ea2, 0x1ea2,
+	0x1ea4, 0x1ea4,
+	0x1ea6, 0x1ea6,
+	0x1ea8, 0x1ea8,
+	0x1eaa, 0x1eaa,
+	0x1eac, 0x1eac,
+	0x1eae, 0x1eae,
+	0x1eb0, 0x1eb0,
+	0x1eb2, 0x1eb2,
+	0x1eb4, 0x1eb4,
+	0x1eb6, 0x1eb6,
+	0x1eb8, 0x1eb8,
+	0x1eba, 0x1eba,
+	0x1ebc, 0x1ebc,
+	0x1ebe, 0x1ebe,
+	0x1ec0, 0x1ec0,
+	0x1ec2, 0x1ec2,
+	0x1ec4, 0x1ec4,
+	0x1ec6, 0x1ec6,
+	0x1ec8, 0x1ec8,
+	0x1eca, 0x1eca,
+	0x1ecc, 0x1ecc,
+	0x1ece, 0x1ece,
+	0x1ed0, 0x1ed0,
+	0x1ed2, 0x1ed2,
+	0x1ed4, 0x1ed4,
+	0x1ed6, 0x1ed6,
+	0x1ed8, 0x1ed8,
+	0x1eda, 0x1eda,
+	0x1edc, 0x1edc,
+	0x1ede, 0x1ede,
+	0x1ee0, 0x1ee0,
+	0x1ee2, 0x1ee2,
+	0x1ee4, 0x1ee4,
+	0x1ee6, 0x1ee6,
+	0x1ee8, 0x1ee8,
+	0x1eea, 0x1eea,
+	0x1eec, 0x1eec,
+	0x1eee, 0x1eee,
+	0x1ef0, 0x1ef0,
+	0x1ef2, 0x1ef2,
+	0x1ef4, 0x1ef4,
+	0x1ef6, 0x1ef6,
+	0x1ef8, 0x1ef8,
+	0x1efa, 0x1efa,
+	0x1efc, 0x1efc,
+	0x1efe, 0x1efe,
+	0x1f08, 0x1f0f,
+	0x1f18, 0x1f1d,
+	0x1f28, 0x1f2f,
+	0x1f38, 0x1f3f,
+	0x1f48, 0x1f4d,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f5f,
+	0x1f68, 0x1f6f,
+	0x1fb8, 0x1fbb,
+	0x1fc8, 0x1fcb,
+	0x1fd8, 0x1fdb,
+	0x1fe8, 0x1fec,
+	0x1ff8, 0x1ffb,
+	0x2102, 0x2102,
+	0x2107, 0x2107,
+	0x210b, 0x210d,
+	0x2110, 0x2112,
+	0x2115, 0x2115,
+	0x2119, 0x211d,
+	0x2124, 0x2124,
+	0x2126, 0x2126,
+	0x2128, 0x2128,
+	0x212a, 0x212d,
+	0x2130, 0x2133,
+	0x213e, 0x213f,
+	0x2145, 0x2145,
+	0x2183, 0x2183,
+	0x2c00, 0x2c2e,
+	0x2c60, 0x2c60,
+	0x2c62, 0x2c64,
+	0x2c67, 0x2c67,
+	0x2c69, 0x2c69,
+	0x2c6b, 0x2c6b,
+	0x2c6d, 0x2c70,
+	0x2c72, 0x2c72,
+	0x2c75, 0x2c75,
+	0x2c7e, 0x2c80,
+	0x2c82, 0x2c82,
+	0x2c84, 0x2c84,
+	0x2c86, 0x2c86,
+	0x2c88, 0x2c88,
+	0x2c8a, 0x2c8a,
+	0x2c8c, 0x2c8c,
+	0x2c8e, 0x2c8e,
+	0x2c90, 0x2c90,
+	0x2c92, 0x2c92,
+	0x2c94, 0x2c94,
+	0x2c96, 0x2c96,
+	0x2c98, 0x2c98,
+	0x2c9a, 0x2c9a,
+	0x2c9c, 0x2c9c,
+	0x2c9e, 0x2c9e,
+	0x2ca0, 0x2ca0,
+	0x2ca2, 0x2ca2,
+	0x2ca4, 0x2ca4,
+	0x2ca6, 0x2ca6,
+	0x2ca8, 0x2ca8,
+	0x2caa, 0x2caa,
+	0x2cac, 0x2cac,
+	0x2cae, 0x2cae,
+	0x2cb0, 0x2cb0,
+	0x2cb2, 0x2cb2,
+	0x2cb4, 0x2cb4,
+	0x2cb6, 0x2cb6,
+	0x2cb8, 0x2cb8,
+	0x2cba, 0x2cba,
+	0x2cbc, 0x2cbc,
+	0x2cbe, 0x2cbe,
+	0x2cc0, 0x2cc0,
+	0x2cc2, 0x2cc2,
+	0x2cc4, 0x2cc4,
+	0x2cc6, 0x2cc6,
+	0x2cc8, 0x2cc8,
+	0x2cca, 0x2cca,
+	0x2ccc, 0x2ccc,
+	0x2cce, 0x2cce,
+	0x2cd0, 0x2cd0,
+	0x2cd2, 0x2cd2,
+	0x2cd4, 0x2cd4,
+	0x2cd6, 0x2cd6,
+	0x2cd8, 0x2cd8,
+	0x2cda, 0x2cda,
+	0x2cdc, 0x2cdc,
+	0x2cde, 0x2cde,
+	0x2ce0, 0x2ce0,
+	0x2ce2, 0x2ce2,
+	0x2ceb, 0x2ceb,
+	0x2ced, 0x2ced,
+	0x2cf2, 0x2cf2,
+	0xa640, 0xa640,
+	0xa642, 0xa642,
+	0xa644, 0xa644,
+	0xa646, 0xa646,
+	0xa648, 0xa648,
+	0xa64a, 0xa64a,
+	0xa64c, 0xa64c,
+	0xa64e, 0xa64e,
+	0xa650, 0xa650,
+	0xa652, 0xa652,
+	0xa654, 0xa654,
+	0xa656, 0xa656,
+	0xa658, 0xa658,
+	0xa65a, 0xa65a,
+	0xa65c, 0xa65c,
+	0xa65e, 0xa65e,
+	0xa660, 0xa660,
+	0xa662, 0xa662,
+	0xa664, 0xa664,
+	0xa666, 0xa666,
+	0xa668, 0xa668,
+	0xa66a, 0xa66a,
+	0xa66c, 0xa66c,
+	0xa680, 0xa680,
+	0xa682, 0xa682,
+	0xa684, 0xa684,
+	0xa686, 0xa686,
+	0xa688, 0xa688,
+	0xa68a, 0xa68a,
+	0xa68c, 0xa68c,
+	0xa68e, 0xa68e,
+	0xa690, 0xa690,
+	0xa692, 0xa692,
+	0xa694, 0xa694,
+	0xa696, 0xa696,
+	0xa698, 0xa698,
+	0xa69a, 0xa69a,
+	0xa722, 0xa722,
+	0xa724, 0xa724,
+	0xa726, 0xa726,
+	0xa728, 0xa728,
+	0xa72a, 0xa72a,
+	0xa72c, 0xa72c,
+	0xa72e, 0xa72e,
+	0xa732, 0xa732,
+	0xa734, 0xa734,
+	0xa736, 0xa736,
+	0xa738, 0xa738,
+	0xa73a, 0xa73a,
+	0xa73c, 0xa73c,
+	0xa73e, 0xa73e,
+	0xa740, 0xa740,
+	0xa742, 0xa742,
+	0xa744, 0xa744,
+	0xa746, 0xa746,
+	0xa748, 0xa748,
+	0xa74a, 0xa74a,
+	0xa74c, 0xa74c,
+	0xa74e, 0xa74e,
+	0xa750, 0xa750,
+	0xa752, 0xa752,
+	0xa754, 0xa754,
+	0xa756, 0xa756,
+	0xa758, 0xa758,
+	0xa75a, 0xa75a,
+	0xa75c, 0xa75c,
+	0xa75e, 0xa75e,
+	0xa760, 0xa760,
+	0xa762, 0xa762,
+	0xa764, 0xa764,
+	0xa766, 0xa766,
+	0xa768, 0xa768,
+	0xa76a, 0xa76a,
+	0xa76c, 0xa76c,
+	0xa76e, 0xa76e,
+	0xa779, 0xa779,
+	0xa77b, 0xa77b,
+	0xa77d, 0xa77e,
+	0xa780, 0xa780,
+	0xa782, 0xa782,
+	0xa784, 0xa784,
+	0xa786, 0xa786,
+	0xa78b, 0xa78b,
+	0xa78d, 0xa78d,
+	0xa790, 0xa790,
+	0xa792, 0xa792,
+	0xa796, 0xa796,
+	0xa798, 0xa798,
+	0xa79a, 0xa79a,
+	0xa79c, 0xa79c,
+	0xa79e, 0xa79e,
+	0xa7a0, 0xa7a0,
+	0xa7a2, 0xa7a2,
+	0xa7a4, 0xa7a4,
+	0xa7a6, 0xa7a6,
+	0xa7a8, 0xa7a8,
+	0xa7aa, 0xa7ae,
+	0xa7b0, 0xa7b4,
+	0xa7b6, 0xa7b6,
+	0xff21, 0xff3a,
+	0x10400, 0x10427,
+	0x104b0, 0x104d3,
+	0x10c80, 0x10cb2,
+	0x118a0, 0x118bf,
+	0x1d400, 0x1d419,
+	0x1d434, 0x1d44d,
+	0x1d468, 0x1d481,
+	0x1d49c, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b5,
+	0x1d4d0, 0x1d4e9,
+	0x1d504, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d538, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d56c, 0x1d585,
+	0x1d5a0, 0x1d5b9,
+	0x1d5d4, 0x1d5ed,
+	0x1d608, 0x1d621,
+	0x1d63c, 0x1d655,
+	0x1d670, 0x1d689,
+	0x1d6a8, 0x1d6c0,
+	0x1d6e2, 0x1d6fa,
+	0x1d71c, 0x1d734,
+	0x1d756, 0x1d76e,
+	0x1d790, 0x1d7a8,
+	0x1d7ca, 0x1d7ca,
+	0x1e900, 0x1e921,
+}; /* CR_Lu */
+
+/* 'M': Major Category */
+static const OnigCodePoint CR_M[] = {
+	263,
+	0x0300, 0x036f,
+	0x0483, 0x0489,
+	0x0591, 0x05bd,
+	0x05bf, 0x05bf,
+	0x05c1, 0x05c2,
+	0x05c4, 0x05c5,
+	0x05c7, 0x05c7,
+	0x0610, 0x061a,
+	0x064b, 0x065f,
+	0x0670, 0x0670,
+	0x06d6, 0x06dc,
+	0x06df, 0x06e4,
+	0x06e7, 0x06e8,
+	0x06ea, 0x06ed,
+	0x0711, 0x0711,
+	0x0730, 0x074a,
+	0x07a6, 0x07b0,
+	0x07eb, 0x07f3,
+	0x0816, 0x0819,
+	0x081b, 0x0823,
+	0x0825, 0x0827,
+	0x0829, 0x082d,
+	0x0859, 0x085b,
+	0x08d4, 0x08e1,
+	0x08e3, 0x0903,
+	0x093a, 0x093c,
+	0x093e, 0x094f,
+	0x0951, 0x0957,
+	0x0962, 0x0963,
+	0x0981, 0x0983,
+	0x09bc, 0x09bc,
+	0x09be, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09cd,
+	0x09d7, 0x09d7,
+	0x09e2, 0x09e3,
+	0x0a01, 0x0a03,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a70, 0x0a71,
+	0x0a75, 0x0a75,
+	0x0a81, 0x0a83,
+	0x0abc, 0x0abc,
+	0x0abe, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ae2, 0x0ae3,
+	0x0afa, 0x0aff,
+	0x0b01, 0x0b03,
+	0x0b3c, 0x0b3c,
+	0x0b3e, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b62, 0x0b63,
+	0x0b82, 0x0b82,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd7, 0x0bd7,
+	0x0c00, 0x0c03,
+	0x0c3e, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c62, 0x0c63,
+	0x0c81, 0x0c83,
+	0x0cbc, 0x0cbc,
+	0x0cbe, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0ce2, 0x0ce3,
+	0x0d00, 0x0d03,
+	0x0d3b, 0x0d3c,
+	0x0d3e, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4d,
+	0x0d57, 0x0d57,
+	0x0d62, 0x0d63,
+	0x0d82, 0x0d83,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0df2, 0x0df3,
+	0x0e31, 0x0e31,
+	0x0e34, 0x0e3a,
+	0x0e47, 0x0e4e,
+	0x0eb1, 0x0eb1,
+	0x0eb4, 0x0eb9,
+	0x0ebb, 0x0ebc,
+	0x0ec8, 0x0ecd,
+	0x0f18, 0x0f19,
+	0x0f35, 0x0f35,
+	0x0f37, 0x0f37,
+	0x0f39, 0x0f39,
+	0x0f3e, 0x0f3f,
+	0x0f71, 0x0f84,
+	0x0f86, 0x0f87,
+	0x0f8d, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fc6, 0x0fc6,
+	0x102b, 0x103e,
+	0x1056, 0x1059,
+	0x105e, 0x1060,
+	0x1062, 0x1064,
+	0x1067, 0x106d,
+	0x1071, 0x1074,
+	0x1082, 0x108d,
+	0x108f, 0x108f,
+	0x109a, 0x109d,
+	0x135d, 0x135f,
+	0x1712, 0x1714,
+	0x1732, 0x1734,
+	0x1752, 0x1753,
+	0x1772, 0x1773,
+	0x17b4, 0x17d3,
+	0x17dd, 0x17dd,
+	0x180b, 0x180d,
+	0x1885, 0x1886,
+	0x18a9, 0x18a9,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1a17, 0x1a1b,
+	0x1a55, 0x1a5e,
+	0x1a60, 0x1a7c,
+	0x1a7f, 0x1a7f,
+	0x1ab0, 0x1abe,
+	0x1b00, 0x1b04,
+	0x1b34, 0x1b44,
+	0x1b6b, 0x1b73,
+	0x1b80, 0x1b82,
+	0x1ba1, 0x1bad,
+	0x1be6, 0x1bf3,
+	0x1c24, 0x1c37,
+	0x1cd0, 0x1cd2,
+	0x1cd4, 0x1ce8,
+	0x1ced, 0x1ced,
+	0x1cf2, 0x1cf4,
+	0x1cf7, 0x1cf9,
+	0x1dc0, 0x1df9,
+	0x1dfb, 0x1dff,
+	0x20d0, 0x20f0,
+	0x2cef, 0x2cf1,
+	0x2d7f, 0x2d7f,
+	0x2de0, 0x2dff,
+	0x302a, 0x302f,
+	0x3099, 0x309a,
+	0xa66f, 0xa672,
+	0xa674, 0xa67d,
+	0xa69e, 0xa69f,
+	0xa6f0, 0xa6f1,
+	0xa802, 0xa802,
+	0xa806, 0xa806,
+	0xa80b, 0xa80b,
+	0xa823, 0xa827,
+	0xa880, 0xa881,
+	0xa8b4, 0xa8c5,
+	0xa8e0, 0xa8f1,
+	0xa926, 0xa92d,
+	0xa947, 0xa953,
+	0xa980, 0xa983,
+	0xa9b3, 0xa9c0,
+	0xa9e5, 0xa9e5,
+	0xaa29, 0xaa36,
+	0xaa43, 0xaa43,
+	0xaa4c, 0xaa4d,
+	0xaa7b, 0xaa7d,
+	0xaab0, 0xaab0,
+	0xaab2, 0xaab4,
+	0xaab7, 0xaab8,
+	0xaabe, 0xaabf,
+	0xaac1, 0xaac1,
+	0xaaeb, 0xaaef,
+	0xaaf5, 0xaaf6,
+	0xabe3, 0xabea,
+	0xabec, 0xabed,
+	0xfb1e, 0xfb1e,
+	0xfe00, 0xfe0f,
+	0xfe20, 0xfe2f,
+	0x101fd, 0x101fd,
+	0x102e0, 0x102e0,
+	0x10376, 0x1037a,
+	0x10a01, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a0f,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a3f,
+	0x10ae5, 0x10ae6,
+	0x11000, 0x11002,
+	0x11038, 0x11046,
+	0x1107f, 0x11082,
+	0x110b0, 0x110ba,
+	0x11100, 0x11102,
+	0x11127, 0x11134,
+	0x11173, 0x11173,
+	0x11180, 0x11182,
+	0x111b3, 0x111c0,
+	0x111ca, 0x111cc,
+	0x1122c, 0x11237,
+	0x1123e, 0x1123e,
+	0x112df, 0x112ea,
+	0x11300, 0x11303,
+	0x1133c, 0x1133c,
+	0x1133e, 0x11344,
+	0x11347, 0x11348,
+	0x1134b, 0x1134d,
+	0x11357, 0x11357,
+	0x11362, 0x11363,
+	0x11366, 0x1136c,
+	0x11370, 0x11374,
+	0x11435, 0x11446,
+	0x114b0, 0x114c3,
+	0x115af, 0x115b5,
+	0x115b8, 0x115c0,
+	0x115dc, 0x115dd,
+	0x11630, 0x11640,
+	0x116ab, 0x116b7,
+	0x1171d, 0x1172b,
+	0x11a01, 0x11a0a,
+	0x11a33, 0x11a39,
+	0x11a3b, 0x11a3e,
+	0x11a47, 0x11a47,
+	0x11a51, 0x11a5b,
+	0x11a8a, 0x11a99,
+	0x11c2f, 0x11c36,
+	0x11c38, 0x11c3f,
+	0x11c92, 0x11ca7,
+	0x11ca9, 0x11cb6,
+	0x11d31, 0x11d36,
+	0x11d3a, 0x11d3a,
+	0x11d3c, 0x11d3d,
+	0x11d3f, 0x11d45,
+	0x11d47, 0x11d47,
+	0x16af0, 0x16af4,
+	0x16b30, 0x16b36,
+	0x16f51, 0x16f7e,
+	0x16f8f, 0x16f92,
+	0x1bc9d, 0x1bc9e,
+	0x1d165, 0x1d169,
+	0x1d16d, 0x1d172,
+	0x1d17b, 0x1d182,
+	0x1d185, 0x1d18b,
+	0x1d1aa, 0x1d1ad,
+	0x1d242, 0x1d244,
+	0x1da00, 0x1da36,
+	0x1da3b, 0x1da6c,
+	0x1da75, 0x1da75,
+	0x1da84, 0x1da84,
+	0x1da9b, 0x1da9f,
+	0x1daa1, 0x1daaf,
+	0x1e000, 0x1e006,
+	0x1e008, 0x1e018,
+	0x1e01b, 0x1e021,
+	0x1e023, 0x1e024,
+	0x1e026, 0x1e02a,
+	0x1e8d0, 0x1e8d6,
+	0x1e944, 0x1e94a,
+	0xe0100, 0xe01ef,
+}; /* CR_M */
+
+/* 'Mc': General Category */
+static const OnigCodePoint CR_Mc[] = {
+	160,
+	0x0903, 0x0903,
+	0x093b, 0x093b,
+	0x093e, 0x0940,
+	0x0949, 0x094c,
+	0x094e, 0x094f,
+	0x0982, 0x0983,
+	0x09be, 0x09c0,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09cc,
+	0x09d7, 0x09d7,
+	0x0a03, 0x0a03,
+	0x0a3e, 0x0a40,
+	0x0a83, 0x0a83,
+	0x0abe, 0x0ac0,
+	0x0ac9, 0x0ac9,
+	0x0acb, 0x0acc,
+	0x0b02, 0x0b03,
+	0x0b3e, 0x0b3e,
+	0x0b40, 0x0b40,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4c,
+	0x0b57, 0x0b57,
+	0x0bbe, 0x0bbf,
+	0x0bc1, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcc,
+	0x0bd7, 0x0bd7,
+	0x0c01, 0x0c03,
+	0x0c41, 0x0c44,
+	0x0c82, 0x0c83,
+	0x0cbe, 0x0cbe,
+	0x0cc0, 0x0cc4,
+	0x0cc7, 0x0cc8,
+	0x0cca, 0x0ccb,
+	0x0cd5, 0x0cd6,
+	0x0d02, 0x0d03,
+	0x0d3e, 0x0d40,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4c,
+	0x0d57, 0x0d57,
+	0x0d82, 0x0d83,
+	0x0dcf, 0x0dd1,
+	0x0dd8, 0x0ddf,
+	0x0df2, 0x0df3,
+	0x0f3e, 0x0f3f,
+	0x0f7f, 0x0f7f,
+	0x102b, 0x102c,
+	0x1031, 0x1031,
+	0x1038, 0x1038,
+	0x103b, 0x103c,
+	0x1056, 0x1057,
+	0x1062, 0x1064,
+	0x1067, 0x106d,
+	0x1083, 0x1084,
+	0x1087, 0x108c,
+	0x108f, 0x108f,
+	0x109a, 0x109c,
+	0x17b6, 0x17b6,
+	0x17be, 0x17c5,
+	0x17c7, 0x17c8,
+	0x1923, 0x1926,
+	0x1929, 0x192b,
+	0x1930, 0x1931,
+	0x1933, 0x1938,
+	0x1a19, 0x1a1a,
+	0x1a55, 0x1a55,
+	0x1a57, 0x1a57,
+	0x1a61, 0x1a61,
+	0x1a63, 0x1a64,
+	0x1a6d, 0x1a72,
+	0x1b04, 0x1b04,
+	0x1b35, 0x1b35,
+	0x1b3b, 0x1b3b,
+	0x1b3d, 0x1b41,
+	0x1b43, 0x1b44,
+	0x1b82, 0x1b82,
+	0x1ba1, 0x1ba1,
+	0x1ba6, 0x1ba7,
+	0x1baa, 0x1baa,
+	0x1be7, 0x1be7,
+	0x1bea, 0x1bec,
+	0x1bee, 0x1bee,
+	0x1bf2, 0x1bf3,
+	0x1c24, 0x1c2b,
+	0x1c34, 0x1c35,
+	0x1ce1, 0x1ce1,
+	0x1cf2, 0x1cf3,
+	0x1cf7, 0x1cf7,
+	0x302e, 0x302f,
+	0xa823, 0xa824,
+	0xa827, 0xa827,
+	0xa880, 0xa881,
+	0xa8b4, 0xa8c3,
+	0xa952, 0xa953,
+	0xa983, 0xa983,
+	0xa9b4, 0xa9b5,
+	0xa9ba, 0xa9bb,
+	0xa9bd, 0xa9c0,
+	0xaa2f, 0xaa30,
+	0xaa33, 0xaa34,
+	0xaa4d, 0xaa4d,
+	0xaa7b, 0xaa7b,
+	0xaa7d, 0xaa7d,
+	0xaaeb, 0xaaeb,
+	0xaaee, 0xaaef,
+	0xaaf5, 0xaaf5,
+	0xabe3, 0xabe4,
+	0xabe6, 0xabe7,
+	0xabe9, 0xabea,
+	0xabec, 0xabec,
+	0x11000, 0x11000,
+	0x11002, 0x11002,
+	0x11082, 0x11082,
+	0x110b0, 0x110b2,
+	0x110b7, 0x110b8,
+	0x1112c, 0x1112c,
+	0x11182, 0x11182,
+	0x111b3, 0x111b5,
+	0x111bf, 0x111c0,
+	0x1122c, 0x1122e,
+	0x11232, 0x11233,
+	0x11235, 0x11235,
+	0x112e0, 0x112e2,
+	0x11302, 0x11303,
+	0x1133e, 0x1133f,
+	0x11341, 0x11344,
+	0x11347, 0x11348,
+	0x1134b, 0x1134d,
+	0x11357, 0x11357,
+	0x11362, 0x11363,
+	0x11435, 0x11437,
+	0x11440, 0x11441,
+	0x11445, 0x11445,
+	0x114b0, 0x114b2,
+	0x114b9, 0x114b9,
+	0x114bb, 0x114be,
+	0x114c1, 0x114c1,
+	0x115af, 0x115b1,
+	0x115b8, 0x115bb,
+	0x115be, 0x115be,
+	0x11630, 0x11632,
+	0x1163b, 0x1163c,
+	0x1163e, 0x1163e,
+	0x116ac, 0x116ac,
+	0x116ae, 0x116af,
+	0x116b6, 0x116b6,
+	0x11720, 0x11721,
+	0x11726, 0x11726,
+	0x11a07, 0x11a08,
+	0x11a39, 0x11a39,
+	0x11a57, 0x11a58,
+	0x11a97, 0x11a97,
+	0x11c2f, 0x11c2f,
+	0x11c3e, 0x11c3e,
+	0x11ca9, 0x11ca9,
+	0x11cb1, 0x11cb1,
+	0x11cb4, 0x11cb4,
+	0x16f51, 0x16f7e,
+	0x1d165, 0x1d166,
+	0x1d16d, 0x1d172,
+}; /* CR_Mc */
+
+/* 'Me': General Category */
+static const OnigCodePoint CR_Me[] = {
+	5,
+	0x0488, 0x0489,
+	0x1abe, 0x1abe,
+	0x20dd, 0x20e0,
+	0x20e2, 0x20e4,
+	0xa670, 0xa672,
+}; /* CR_Me */
+
+/* 'Mn': General Category */
+static const OnigCodePoint CR_Mn[] = {
+	301,
+	0x0300, 0x036f,
+	0x0483, 0x0487,
+	0x0591, 0x05bd,
+	0x05bf, 0x05bf,
+	0x05c1, 0x05c2,
+	0x05c4, 0x05c5,
+	0x05c7, 0x05c7,
+	0x0610, 0x061a,
+	0x064b, 0x065f,
+	0x0670, 0x0670,
+	0x06d6, 0x06dc,
+	0x06df, 0x06e4,
+	0x06e7, 0x06e8,
+	0x06ea, 0x06ed,
+	0x0711, 0x0711,
+	0x0730, 0x074a,
+	0x07a6, 0x07b0,
+	0x07eb, 0x07f3,
+	0x0816, 0x0819,
+	0x081b, 0x0823,
+	0x0825, 0x0827,
+	0x0829, 0x082d,
+	0x0859, 0x085b,
+	0x08d4, 0x08e1,
+	0x08e3, 0x0902,
+	0x093a, 0x093a,
+	0x093c, 0x093c,
+	0x0941, 0x0948,
+	0x094d, 0x094d,
+	0x0951, 0x0957,
+	0x0962, 0x0963,
+	0x0981, 0x0981,
+	0x09bc, 0x09bc,
+	0x09c1, 0x09c4,
+	0x09cd, 0x09cd,
+	0x09e2, 0x09e3,
+	0x0a01, 0x0a02,
+	0x0a3c, 0x0a3c,
+	0x0a41, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a70, 0x0a71,
+	0x0a75, 0x0a75,
+	0x0a81, 0x0a82,
+	0x0abc, 0x0abc,
+	0x0ac1, 0x0ac5,
+	0x0ac7, 0x0ac8,
+	0x0acd, 0x0acd,
+	0x0ae2, 0x0ae3,
+	0x0afa, 0x0aff,
+	0x0b01, 0x0b01,
+	0x0b3c, 0x0b3c,
+	0x0b3f, 0x0b3f,
+	0x0b41, 0x0b44,
+	0x0b4d, 0x0b4d,
+	0x0b56, 0x0b56,
+	0x0b62, 0x0b63,
+	0x0b82, 0x0b82,
+	0x0bc0, 0x0bc0,
+	0x0bcd, 0x0bcd,
+	0x0c00, 0x0c00,
+	0x0c3e, 0x0c40,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c62, 0x0c63,
+	0x0c81, 0x0c81,
+	0x0cbc, 0x0cbc,
+	0x0cbf, 0x0cbf,
+	0x0cc6, 0x0cc6,
+	0x0ccc, 0x0ccd,
+	0x0ce2, 0x0ce3,
+	0x0d00, 0x0d01,
+	0x0d3b, 0x0d3c,
+	0x0d41, 0x0d44,
+	0x0d4d, 0x0d4d,
+	0x0d62, 0x0d63,
+	0x0dca, 0x0dca,
+	0x0dd2, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0e31, 0x0e31,
+	0x0e34, 0x0e3a,
+	0x0e47, 0x0e4e,
+	0x0eb1, 0x0eb1,
+	0x0eb4, 0x0eb9,
+	0x0ebb, 0x0ebc,
+	0x0ec8, 0x0ecd,
+	0x0f18, 0x0f19,
+	0x0f35, 0x0f35,
+	0x0f37, 0x0f37,
+	0x0f39, 0x0f39,
+	0x0f71, 0x0f7e,
+	0x0f80, 0x0f84,
+	0x0f86, 0x0f87,
+	0x0f8d, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fc6, 0x0fc6,
+	0x102d, 0x1030,
+	0x1032, 0x1037,
+	0x1039, 0x103a,
+	0x103d, 0x103e,
+	0x1058, 0x1059,
+	0x105e, 0x1060,
+	0x1071, 0x1074,
+	0x1082, 0x1082,
+	0x1085, 0x1086,
+	0x108d, 0x108d,
+	0x109d, 0x109d,
+	0x135d, 0x135f,
+	0x1712, 0x1714,
+	0x1732, 0x1734,
+	0x1752, 0x1753,
+	0x1772, 0x1773,
+	0x17b4, 0x17b5,
+	0x17b7, 0x17bd,
+	0x17c6, 0x17c6,
+	0x17c9, 0x17d3,
+	0x17dd, 0x17dd,
+	0x180b, 0x180d,
+	0x1885, 0x1886,
+	0x18a9, 0x18a9,
+	0x1920, 0x1922,
+	0x1927, 0x1928,
+	0x1932, 0x1932,
+	0x1939, 0x193b,
+	0x1a17, 0x1a18,
+	0x1a1b, 0x1a1b,
+	0x1a56, 0x1a56,
+	0x1a58, 0x1a5e,
+	0x1a60, 0x1a60,
+	0x1a62, 0x1a62,
+	0x1a65, 0x1a6c,
+	0x1a73, 0x1a7c,
+	0x1a7f, 0x1a7f,
+	0x1ab0, 0x1abd,
+	0x1b00, 0x1b03,
+	0x1b34, 0x1b34,
+	0x1b36, 0x1b3a,
+	0x1b3c, 0x1b3c,
+	0x1b42, 0x1b42,
+	0x1b6b, 0x1b73,
+	0x1b80, 0x1b81,
+	0x1ba2, 0x1ba5,
+	0x1ba8, 0x1ba9,
+	0x1bab, 0x1bad,
+	0x1be6, 0x1be6,
+	0x1be8, 0x1be9,
+	0x1bed, 0x1bed,
+	0x1bef, 0x1bf1,
+	0x1c2c, 0x1c33,
+	0x1c36, 0x1c37,
+	0x1cd0, 0x1cd2,
+	0x1cd4, 0x1ce0,
+	0x1ce2, 0x1ce8,
+	0x1ced, 0x1ced,
+	0x1cf4, 0x1cf4,
+	0x1cf8, 0x1cf9,
+	0x1dc0, 0x1df9,
+	0x1dfb, 0x1dff,
+	0x20d0, 0x20dc,
+	0x20e1, 0x20e1,
+	0x20e5, 0x20f0,
+	0x2cef, 0x2cf1,
+	0x2d7f, 0x2d7f,
+	0x2de0, 0x2dff,
+	0x302a, 0x302d,
+	0x3099, 0x309a,
+	0xa66f, 0xa66f,
+	0xa674, 0xa67d,
+	0xa69e, 0xa69f,
+	0xa6f0, 0xa6f1,
+	0xa802, 0xa802,
+	0xa806, 0xa806,
+	0xa80b, 0xa80b,
+	0xa825, 0xa826,
+	0xa8c4, 0xa8c5,
+	0xa8e0, 0xa8f1,
+	0xa926, 0xa92d,
+	0xa947, 0xa951,
+	0xa980, 0xa982,
+	0xa9b3, 0xa9b3,
+	0xa9b6, 0xa9b9,
+	0xa9bc, 0xa9bc,
+	0xa9e5, 0xa9e5,
+	0xaa29, 0xaa2e,
+	0xaa31, 0xaa32,
+	0xaa35, 0xaa36,
+	0xaa43, 0xaa43,
+	0xaa4c, 0xaa4c,
+	0xaa7c, 0xaa7c,
+	0xaab0, 0xaab0,
+	0xaab2, 0xaab4,
+	0xaab7, 0xaab8,
+	0xaabe, 0xaabf,
+	0xaac1, 0xaac1,
+	0xaaec, 0xaaed,
+	0xaaf6, 0xaaf6,
+	0xabe5, 0xabe5,
+	0xabe8, 0xabe8,
+	0xabed, 0xabed,
+	0xfb1e, 0xfb1e,
+	0xfe00, 0xfe0f,
+	0xfe20, 0xfe2f,
+	0x101fd, 0x101fd,
+	0x102e0, 0x102e0,
+	0x10376, 0x1037a,
+	0x10a01, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a0f,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a3f,
+	0x10ae5, 0x10ae6,
+	0x11001, 0x11001,
+	0x11038, 0x11046,
+	0x1107f, 0x11081,
+	0x110b3, 0x110b6,
+	0x110b9, 0x110ba,
+	0x11100, 0x11102,
+	0x11127, 0x1112b,
+	0x1112d, 0x11134,
+	0x11173, 0x11173,
+	0x11180, 0x11181,
+	0x111b6, 0x111be,
+	0x111ca, 0x111cc,
+	0x1122f, 0x11231,
+	0x11234, 0x11234,
+	0x11236, 0x11237,
+	0x1123e, 0x1123e,
+	0x112df, 0x112df,
+	0x112e3, 0x112ea,
+	0x11300, 0x11301,
+	0x1133c, 0x1133c,
+	0x11340, 0x11340,
+	0x11366, 0x1136c,
+	0x11370, 0x11374,
+	0x11438, 0x1143f,
+	0x11442, 0x11444,
+	0x11446, 0x11446,
+	0x114b3, 0x114b8,
+	0x114ba, 0x114ba,
+	0x114bf, 0x114c0,
+	0x114c2, 0x114c3,
+	0x115b2, 0x115b5,
+	0x115bc, 0x115bd,
+	0x115bf, 0x115c0,
+	0x115dc, 0x115dd,
+	0x11633, 0x1163a,
+	0x1163d, 0x1163d,
+	0x1163f, 0x11640,
+	0x116ab, 0x116ab,
+	0x116ad, 0x116ad,
+	0x116b0, 0x116b5,
+	0x116b7, 0x116b7,
+	0x1171d, 0x1171f,
+	0x11722, 0x11725,
+	0x11727, 0x1172b,
+	0x11a01, 0x11a06,
+	0x11a09, 0x11a0a,
+	0x11a33, 0x11a38,
+	0x11a3b, 0x11a3e,
+	0x11a47, 0x11a47,
+	0x11a51, 0x11a56,
+	0x11a59, 0x11a5b,
+	0x11a8a, 0x11a96,
+	0x11a98, 0x11a99,
+	0x11c30, 0x11c36,
+	0x11c38, 0x11c3d,
+	0x11c3f, 0x11c3f,
+	0x11c92, 0x11ca7,
+	0x11caa, 0x11cb0,
+	0x11cb2, 0x11cb3,
+	0x11cb5, 0x11cb6,
+	0x11d31, 0x11d36,
+	0x11d3a, 0x11d3a,
+	0x11d3c, 0x11d3d,
+	0x11d3f, 0x11d45,
+	0x11d47, 0x11d47,
+	0x16af0, 0x16af4,
+	0x16b30, 0x16b36,
+	0x16f8f, 0x16f92,
+	0x1bc9d, 0x1bc9e,
+	0x1d167, 0x1d169,
+	0x1d17b, 0x1d182,
+	0x1d185, 0x1d18b,
+	0x1d1aa, 0x1d1ad,
+	0x1d242, 0x1d244,
+	0x1da00, 0x1da36,
+	0x1da3b, 0x1da6c,
+	0x1da75, 0x1da75,
+	0x1da84, 0x1da84,
+	0x1da9b, 0x1da9f,
+	0x1daa1, 0x1daaf,
+	0x1e000, 0x1e006,
+	0x1e008, 0x1e018,
+	0x1e01b, 0x1e021,
+	0x1e023, 0x1e024,
+	0x1e026, 0x1e02a,
+	0x1e8d0, 0x1e8d6,
+	0x1e944, 0x1e94a,
+	0xe0100, 0xe01ef,
+}; /* CR_Mn */
+
+/* 'N': Major Category */
+static const OnigCodePoint CR_N[] = {
+	116,
+	0x0030, 0x0039,
+	0x00b2, 0x00b3,
+	0x00b9, 0x00b9,
+	0x00bc, 0x00be,
+	0x0660, 0x0669,
+	0x06f0, 0x06f9,
+	0x07c0, 0x07c9,
+	0x0966, 0x096f,
+	0x09e6, 0x09ef,
+	0x09f4, 0x09f9,
+	0x0a66, 0x0a6f,
+	0x0ae6, 0x0aef,
+	0x0b66, 0x0b6f,
+	0x0b72, 0x0b77,
+	0x0be6, 0x0bf2,
+	0x0c66, 0x0c6f,
+	0x0c78, 0x0c7e,
+	0x0ce6, 0x0cef,
+	0x0d58, 0x0d5e,
+	0x0d66, 0x0d78,
+	0x0de6, 0x0def,
+	0x0e50, 0x0e59,
+	0x0ed0, 0x0ed9,
+	0x0f20, 0x0f33,
+	0x1040, 0x1049,
+	0x1090, 0x1099,
+	0x1369, 0x137c,
+	0x16ee, 0x16f0,
+	0x17e0, 0x17e9,
+	0x17f0, 0x17f9,
+	0x1810, 0x1819,
+	0x1946, 0x194f,
+	0x19d0, 0x19da,
+	0x1a80, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1b50, 0x1b59,
+	0x1bb0, 0x1bb9,
+	0x1c40, 0x1c49,
+	0x1c50, 0x1c59,
+	0x2070, 0x2070,
+	0x2074, 0x2079,
+	0x2080, 0x2089,
+	0x2150, 0x2182,
+	0x2185, 0x2189,
+	0x2460, 0x249b,
+	0x24ea, 0x24ff,
+	0x2776, 0x2793,
+	0x2cfd, 0x2cfd,
+	0x3007, 0x3007,
+	0x3021, 0x3029,
+	0x3038, 0x303a,
+	0x3192, 0x3195,
+	0x3220, 0x3229,
+	0x3248, 0x324f,
+	0x3251, 0x325f,
+	0x3280, 0x3289,
+	0x32b1, 0x32bf,
+	0xa620, 0xa629,
+	0xa6e6, 0xa6ef,
+	0xa830, 0xa835,
+	0xa8d0, 0xa8d9,
+	0xa900, 0xa909,
+	0xa9d0, 0xa9d9,
+	0xa9f0, 0xa9f9,
+	0xaa50, 0xaa59,
+	0xabf0, 0xabf9,
+	0xff10, 0xff19,
+	0x10107, 0x10133,
+	0x10140, 0x10178,
+	0x1018a, 0x1018b,
+	0x102e1, 0x102fb,
+	0x10320, 0x10323,
+	0x10341, 0x10341,
+	0x1034a, 0x1034a,
+	0x103d1, 0x103d5,
+	0x104a0, 0x104a9,
+	0x10858, 0x1085f,
+	0x10879, 0x1087f,
+	0x108a7, 0x108af,
+	0x108fb, 0x108ff,
+	0x10916, 0x1091b,
+	0x109bc, 0x109bd,
+	0x109c0, 0x109cf,
+	0x109d2, 0x109ff,
+	0x10a40, 0x10a47,
+	0x10a7d, 0x10a7e,
+	0x10a9d, 0x10a9f,
+	0x10aeb, 0x10aef,
+	0x10b58, 0x10b5f,
+	0x10b78, 0x10b7f,
+	0x10ba9, 0x10baf,
+	0x10cfa, 0x10cff,
+	0x10e60, 0x10e7e,
+	0x11052, 0x1106f,
+	0x110f0, 0x110f9,
+	0x11136, 0x1113f,
+	0x111d0, 0x111d9,
+	0x111e1, 0x111f4,
+	0x112f0, 0x112f9,
+	0x11450, 0x11459,
+	0x114d0, 0x114d9,
+	0x11650, 0x11659,
+	0x116c0, 0x116c9,
+	0x11730, 0x1173b,
+	0x118e0, 0x118f2,
+	0x11c50, 0x11c6c,
+	0x11d50, 0x11d59,
+	0x12400, 0x1246e,
+	0x16a60, 0x16a69,
+	0x16b50, 0x16b59,
+	0x16b5b, 0x16b61,
+	0x1d360, 0x1d371,
+	0x1d7ce, 0x1d7ff,
+	0x1e8c7, 0x1e8cf,
+	0x1e950, 0x1e959,
+	0x1f100, 0x1f10c,
+}; /* CR_N */
+
+/* 'Nd': General Category */
+#define CR_Nd CR_Digit
+
+/* 'Nl': General Category */
+static const OnigCodePoint CR_Nl[] = {
+	12,
+	0x16ee, 0x16f0,
+	0x2160, 0x2182,
+	0x2185, 0x2188,
+	0x3007, 0x3007,
+	0x3021, 0x3029,
+	0x3038, 0x303a,
+	0xa6e6, 0xa6ef,
+	0x10140, 0x10174,
+	0x10341, 0x10341,
+	0x1034a, 0x1034a,
+	0x103d1, 0x103d5,
+	0x12400, 0x1246e,
+}; /* CR_Nl */
+
+/* 'No': General Category */
+static const OnigCodePoint CR_No[] = {
+	60,
+	0x00b2, 0x00b3,
+	0x00b9, 0x00b9,
+	0x00bc, 0x00be,
+	0x09f4, 0x09f9,
+	0x0b72, 0x0b77,
+	0x0bf0, 0x0bf2,
+	0x0c78, 0x0c7e,
+	0x0d58, 0x0d5e,
+	0x0d70, 0x0d78,
+	0x0f2a, 0x0f33,
+	0x1369, 0x137c,
+	0x17f0, 0x17f9,
+	0x19da, 0x19da,
+	0x2070, 0x2070,
+	0x2074, 0x2079,
+	0x2080, 0x2089,
+	0x2150, 0x215f,
+	0x2189, 0x2189,
+	0x2460, 0x249b,
+	0x24ea, 0x24ff,
+	0x2776, 0x2793,
+	0x2cfd, 0x2cfd,
+	0x3192, 0x3195,
+	0x3220, 0x3229,
+	0x3248, 0x324f,
+	0x3251, 0x325f,
+	0x3280, 0x3289,
+	0x32b1, 0x32bf,
+	0xa830, 0xa835,
+	0x10107, 0x10133,
+	0x10175, 0x10178,
+	0x1018a, 0x1018b,
+	0x102e1, 0x102fb,
+	0x10320, 0x10323,
+	0x10858, 0x1085f,
+	0x10879, 0x1087f,
+	0x108a7, 0x108af,
+	0x108fb, 0x108ff,
+	0x10916, 0x1091b,
+	0x109bc, 0x109bd,
+	0x109c0, 0x109cf,
+	0x109d2, 0x109ff,
+	0x10a40, 0x10a47,
+	0x10a7d, 0x10a7e,
+	0x10a9d, 0x10a9f,
+	0x10aeb, 0x10aef,
+	0x10b58, 0x10b5f,
+	0x10b78, 0x10b7f,
+	0x10ba9, 0x10baf,
+	0x10cfa, 0x10cff,
+	0x10e60, 0x10e7e,
+	0x11052, 0x11065,
+	0x111e1, 0x111f4,
+	0x1173a, 0x1173b,
+	0x118ea, 0x118f2,
+	0x11c5a, 0x11c6c,
+	0x16b5b, 0x16b61,
+	0x1d360, 0x1d371,
+	0x1e8c7, 0x1e8cf,
+	0x1f100, 0x1f10c,
+}; /* CR_No */
+
+/* 'P': Major Category */
+#define CR_P CR_Punct
+
+/* 'Pc': General Category */
+static const OnigCodePoint CR_Pc[] = {
+	6,
+	0x005f, 0x005f,
+	0x203f, 0x2040,
+	0x2054, 0x2054,
+	0xfe33, 0xfe34,
+	0xfe4d, 0xfe4f,
+	0xff3f, 0xff3f,
+}; /* CR_Pc */
+
+/* 'Pd': General Category */
+static const OnigCodePoint CR_Pd[] = {
+	17,
+	0x002d, 0x002d,
+	0x058a, 0x058a,
+	0x05be, 0x05be,
+	0x1400, 0x1400,
+	0x1806, 0x1806,
+	0x2010, 0x2015,
+	0x2e17, 0x2e17,
+	0x2e1a, 0x2e1a,
+	0x2e3a, 0x2e3b,
+	0x2e40, 0x2e40,
+	0x301c, 0x301c,
+	0x3030, 0x3030,
+	0x30a0, 0x30a0,
+	0xfe31, 0xfe32,
+	0xfe58, 0xfe58,
+	0xfe63, 0xfe63,
+	0xff0d, 0xff0d,
+}; /* CR_Pd */
+
+/* 'Pe': General Category */
+static const OnigCodePoint CR_Pe[] = {
+	72,
+	0x0029, 0x0029,
+	0x005d, 0x005d,
+	0x007d, 0x007d,
+	0x0f3b, 0x0f3b,
+	0x0f3d, 0x0f3d,
+	0x169c, 0x169c,
+	0x2046, 0x2046,
+	0x207e, 0x207e,
+	0x208e, 0x208e,
+	0x2309, 0x2309,
+	0x230b, 0x230b,
+	0x232a, 0x232a,
+	0x2769, 0x2769,
+	0x276b, 0x276b,
+	0x276d, 0x276d,
+	0x276f, 0x276f,
+	0x2771, 0x2771,
+	0x2773, 0x2773,
+	0x2775, 0x2775,
+	0x27c6, 0x27c6,
+	0x27e7, 0x27e7,
+	0x27e9, 0x27e9,
+	0x27eb, 0x27eb,
+	0x27ed, 0x27ed,
+	0x27ef, 0x27ef,
+	0x2984, 0x2984,
+	0x2986, 0x2986,
+	0x2988, 0x2988,
+	0x298a, 0x298a,
+	0x298c, 0x298c,
+	0x298e, 0x298e,
+	0x2990, 0x2990,
+	0x2992, 0x2992,
+	0x2994, 0x2994,
+	0x2996, 0x2996,
+	0x2998, 0x2998,
+	0x29d9, 0x29d9,
+	0x29db, 0x29db,
+	0x29fd, 0x29fd,
+	0x2e23, 0x2e23,
+	0x2e25, 0x2e25,
+	0x2e27, 0x2e27,
+	0x2e29, 0x2e29,
+	0x3009, 0x3009,
+	0x300b, 0x300b,
+	0x300d, 0x300d,
+	0x300f, 0x300f,
+	0x3011, 0x3011,
+	0x3015, 0x3015,
+	0x3017, 0x3017,
+	0x3019, 0x3019,
+	0x301b, 0x301b,
+	0x301e, 0x301f,
+	0xfd3e, 0xfd3e,
+	0xfe18, 0xfe18,
+	0xfe36, 0xfe36,
+	0xfe38, 0xfe38,
+	0xfe3a, 0xfe3a,
+	0xfe3c, 0xfe3c,
+	0xfe3e, 0xfe3e,
+	0xfe40, 0xfe40,
+	0xfe42, 0xfe42,
+	0xfe44, 0xfe44,
+	0xfe48, 0xfe48,
+	0xfe5a, 0xfe5a,
+	0xfe5c, 0xfe5c,
+	0xfe5e, 0xfe5e,
+	0xff09, 0xff09,
+	0xff3d, 0xff3d,
+	0xff5d, 0xff5d,
+	0xff60, 0xff60,
+	0xff63, 0xff63,
+}; /* CR_Pe */
+
+/* 'Pf': General Category */
+static const OnigCodePoint CR_Pf[] = {
+	10,
+	0x00bb, 0x00bb,
+	0x2019, 0x2019,
+	0x201d, 0x201d,
+	0x203a, 0x203a,
+	0x2e03, 0x2e03,
+	0x2e05, 0x2e05,
+	0x2e0a, 0x2e0a,
+	0x2e0d, 0x2e0d,
+	0x2e1d, 0x2e1d,
+	0x2e21, 0x2e21,
+}; /* CR_Pf */
+
+/* 'Pi': General Category */
+static const OnigCodePoint CR_Pi[] = {
+	11,
+	0x00ab, 0x00ab,
+	0x2018, 0x2018,
+	0x201b, 0x201c,
+	0x201f, 0x201f,
+	0x2039, 0x2039,
+	0x2e02, 0x2e02,
+	0x2e04, 0x2e04,
+	0x2e09, 0x2e09,
+	0x2e0c, 0x2e0c,
+	0x2e1c, 0x2e1c,
+	0x2e20, 0x2e20,
+}; /* CR_Pi */
+
+/* 'Po': General Category */
+static const OnigCodePoint CR_Po[] = {
+	169,
+	0x0021, 0x0023,
+	0x0025, 0x0027,
+	0x002a, 0x002a,
+	0x002c, 0x002c,
+	0x002e, 0x002f,
+	0x003a, 0x003b,
+	0x003f, 0x0040,
+	0x005c, 0x005c,
+	0x00a1, 0x00a1,
+	0x00a7, 0x00a7,
+	0x00b6, 0x00b7,
+	0x00bf, 0x00bf,
+	0x037e, 0x037e,
+	0x0387, 0x0387,
+	0x055a, 0x055f,
+	0x0589, 0x0589,
+	0x05c0, 0x05c0,
+	0x05c3, 0x05c3,
+	0x05c6, 0x05c6,
+	0x05f3, 0x05f4,
+	0x0609, 0x060a,
+	0x060c, 0x060d,
+	0x061b, 0x061b,
+	0x061e, 0x061f,
+	0x066a, 0x066d,
+	0x06d4, 0x06d4,
+	0x0700, 0x070d,
+	0x07f7, 0x07f9,
+	0x0830, 0x083e,
+	0x085e, 0x085e,
+	0x0964, 0x0965,
+	0x0970, 0x0970,
+	0x09fd, 0x09fd,
+	0x0af0, 0x0af0,
+	0x0df4, 0x0df4,
+	0x0e4f, 0x0e4f,
+	0x0e5a, 0x0e5b,
+	0x0f04, 0x0f12,
+	0x0f14, 0x0f14,
+	0x0f85, 0x0f85,
+	0x0fd0, 0x0fd4,
+	0x0fd9, 0x0fda,
+	0x104a, 0x104f,
+	0x10fb, 0x10fb,
+	0x1360, 0x1368,
+	0x166d, 0x166e,
+	0x16eb, 0x16ed,
+	0x1735, 0x1736,
+	0x17d4, 0x17d6,
+	0x17d8, 0x17da,
+	0x1800, 0x1805,
+	0x1807, 0x180a,
+	0x1944, 0x1945,
+	0x1a1e, 0x1a1f,
+	0x1aa0, 0x1aa6,
+	0x1aa8, 0x1aad,
+	0x1b5a, 0x1b60,
+	0x1bfc, 0x1bff,
+	0x1c3b, 0x1c3f,
+	0x1c7e, 0x1c7f,
+	0x1cc0, 0x1cc7,
+	0x1cd3, 0x1cd3,
+	0x2016, 0x2017,
+	0x2020, 0x2027,
+	0x2030, 0x2038,
+	0x203b, 0x203e,
+	0x2041, 0x2043,
+	0x2047, 0x2051,
+	0x2053, 0x2053,
+	0x2055, 0x205e,
+	0x2cf9, 0x2cfc,
+	0x2cfe, 0x2cff,
+	0x2d70, 0x2d70,
+	0x2e00, 0x2e01,
+	0x2e06, 0x2e08,
+	0x2e0b, 0x2e0b,
+	0x2e0e, 0x2e16,
+	0x2e18, 0x2e19,
+	0x2e1b, 0x2e1b,
+	0x2e1e, 0x2e1f,
+	0x2e2a, 0x2e2e,
+	0x2e30, 0x2e39,
+	0x2e3c, 0x2e3f,
+	0x2e41, 0x2e41,
+	0x2e43, 0x2e49,
+	0x3001, 0x3003,
+	0x303d, 0x303d,
+	0x30fb, 0x30fb,
+	0xa4fe, 0xa4ff,
+	0xa60d, 0xa60f,
+	0xa673, 0xa673,
+	0xa67e, 0xa67e,
+	0xa6f2, 0xa6f7,
+	0xa874, 0xa877,
+	0xa8ce, 0xa8cf,
+	0xa8f8, 0xa8fa,
+	0xa8fc, 0xa8fc,
+	0xa92e, 0xa92f,
+	0xa95f, 0xa95f,
+	0xa9c1, 0xa9cd,
+	0xa9de, 0xa9df,
+	0xaa5c, 0xaa5f,
+	0xaade, 0xaadf,
+	0xaaf0, 0xaaf1,
+	0xabeb, 0xabeb,
+	0xfe10, 0xfe16,
+	0xfe19, 0xfe19,
+	0xfe30, 0xfe30,
+	0xfe45, 0xfe46,
+	0xfe49, 0xfe4c,
+	0xfe50, 0xfe52,
+	0xfe54, 0xfe57,
+	0xfe5f, 0xfe61,
+	0xfe68, 0xfe68,
+	0xfe6a, 0xfe6b,
+	0xff01, 0xff03,
+	0xff05, 0xff07,
+	0xff0a, 0xff0a,
+	0xff0c, 0xff0c,
+	0xff0e, 0xff0f,
+	0xff1a, 0xff1b,
+	0xff1f, 0xff20,
+	0xff3c, 0xff3c,
+	0xff61, 0xff61,
+	0xff64, 0xff65,
+	0x10100, 0x10102,
+	0x1039f, 0x1039f,
+	0x103d0, 0x103d0,
+	0x1056f, 0x1056f,
+	0x10857, 0x10857,
+	0x1091f, 0x1091f,
+	0x1093f, 0x1093f,
+	0x10a50, 0x10a58,
+	0x10a7f, 0x10a7f,
+	0x10af0, 0x10af6,
+	0x10b39, 0x10b3f,
+	0x10b99, 0x10b9c,
+	0x11047, 0x1104d,
+	0x110bb, 0x110bc,
+	0x110be, 0x110c1,
+	0x11140, 0x11143,
+	0x11174, 0x11175,
+	0x111c5, 0x111c9,
+	0x111cd, 0x111cd,
+	0x111db, 0x111db,
+	0x111dd, 0x111df,
+	0x11238, 0x1123d,
+	0x112a9, 0x112a9,
+	0x1144b, 0x1144f,
+	0x1145b, 0x1145b,
+	0x1145d, 0x1145d,
+	0x114c6, 0x114c6,
+	0x115c1, 0x115d7,
+	0x11641, 0x11643,
+	0x11660, 0x1166c,
+	0x1173c, 0x1173e,
+	0x11a3f, 0x11a46,
+	0x11a9a, 0x11a9c,
+	0x11a9e, 0x11aa2,
+	0x11c41, 0x11c45,
+	0x11c70, 0x11c71,
+	0x12470, 0x12474,
+	0x16a6e, 0x16a6f,
+	0x16af5, 0x16af5,
+	0x16b37, 0x16b3b,
+	0x16b44, 0x16b44,
+	0x1bc9f, 0x1bc9f,
+	0x1da87, 0x1da8b,
+	0x1e95e, 0x1e95f,
+}; /* CR_Po */
+
+/* 'Ps': General Category */
+static const OnigCodePoint CR_Ps[] = {
+	75,
+	0x0028, 0x0028,
+	0x005b, 0x005b,
+	0x007b, 0x007b,
+	0x0f3a, 0x0f3a,
+	0x0f3c, 0x0f3c,
+	0x169b, 0x169b,
+	0x201a, 0x201a,
+	0x201e, 0x201e,
+	0x2045, 0x2045,
+	0x207d, 0x207d,
+	0x208d, 0x208d,
+	0x2308, 0x2308,
+	0x230a, 0x230a,
+	0x2329, 0x2329,
+	0x2768, 0x2768,
+	0x276a, 0x276a,
+	0x276c, 0x276c,
+	0x276e, 0x276e,
+	0x2770, 0x2770,
+	0x2772, 0x2772,
+	0x2774, 0x2774,
+	0x27c5, 0x27c5,
+	0x27e6, 0x27e6,
+	0x27e8, 0x27e8,
+	0x27ea, 0x27ea,
+	0x27ec, 0x27ec,
+	0x27ee, 0x27ee,
+	0x2983, 0x2983,
+	0x2985, 0x2985,
+	0x2987, 0x2987,
+	0x2989, 0x2989,
+	0x298b, 0x298b,
+	0x298d, 0x298d,
+	0x298f, 0x298f,
+	0x2991, 0x2991,
+	0x2993, 0x2993,
+	0x2995, 0x2995,
+	0x2997, 0x2997,
+	0x29d8, 0x29d8,
+	0x29da, 0x29da,
+	0x29fc, 0x29fc,
+	0x2e22, 0x2e22,
+	0x2e24, 0x2e24,
+	0x2e26, 0x2e26,
+	0x2e28, 0x2e28,
+	0x2e42, 0x2e42,
+	0x3008, 0x3008,
+	0x300a, 0x300a,
+	0x300c, 0x300c,
+	0x300e, 0x300e,
+	0x3010, 0x3010,
+	0x3014, 0x3014,
+	0x3016, 0x3016,
+	0x3018, 0x3018,
+	0x301a, 0x301a,
+	0x301d, 0x301d,
+	0xfd3f, 0xfd3f,
+	0xfe17, 0xfe17,
+	0xfe35, 0xfe35,
+	0xfe37, 0xfe37,
+	0xfe39, 0xfe39,
+	0xfe3b, 0xfe3b,
+	0xfe3d, 0xfe3d,
+	0xfe3f, 0xfe3f,
+	0xfe41, 0xfe41,
+	0xfe43, 0xfe43,
+	0xfe47, 0xfe47,
+	0xfe59, 0xfe59,
+	0xfe5b, 0xfe5b,
+	0xfe5d, 0xfe5d,
+	0xff08, 0xff08,
+	0xff3b, 0xff3b,
+	0xff5b, 0xff5b,
+	0xff5f, 0xff5f,
+	0xff62, 0xff62,
+}; /* CR_Ps */
+
+/* 'S': Major Category */
+static const OnigCodePoint CR_S[] = {
+	217,
+	0x0024, 0x0024,
+	0x002b, 0x002b,
+	0x003c, 0x003e,
+	0x005e, 0x005e,
+	0x0060, 0x0060,
+	0x007c, 0x007c,
+	0x007e, 0x007e,
+	0x00a2, 0x00a6,
+	0x00a8, 0x00a9,
+	0x00ac, 0x00ac,
+	0x00ae, 0x00b1,
+	0x00b4, 0x00b4,
+	0x00b8, 0x00b8,
+	0x00d7, 0x00d7,
+	0x00f7, 0x00f7,
+	0x02c2, 0x02c5,
+	0x02d2, 0x02df,
+	0x02e5, 0x02eb,
+	0x02ed, 0x02ed,
+	0x02ef, 0x02ff,
+	0x0375, 0x0375,
+	0x0384, 0x0385,
+	0x03f6, 0x03f6,
+	0x0482, 0x0482,
+	0x058d, 0x058f,
+	0x0606, 0x0608,
+	0x060b, 0x060b,
+	0x060e, 0x060f,
+	0x06de, 0x06de,
+	0x06e9, 0x06e9,
+	0x06fd, 0x06fe,
+	0x07f6, 0x07f6,
+	0x09f2, 0x09f3,
+	0x09fa, 0x09fb,
+	0x0af1, 0x0af1,
+	0x0b70, 0x0b70,
+	0x0bf3, 0x0bfa,
+	0x0c7f, 0x0c7f,
+	0x0d4f, 0x0d4f,
+	0x0d79, 0x0d79,
+	0x0e3f, 0x0e3f,
+	0x0f01, 0x0f03,
+	0x0f13, 0x0f13,
+	0x0f15, 0x0f17,
+	0x0f1a, 0x0f1f,
+	0x0f34, 0x0f34,
+	0x0f36, 0x0f36,
+	0x0f38, 0x0f38,
+	0x0fbe, 0x0fc5,
+	0x0fc7, 0x0fcc,
+	0x0fce, 0x0fcf,
+	0x0fd5, 0x0fd8,
+	0x109e, 0x109f,
+	0x1390, 0x1399,
+	0x17db, 0x17db,
+	0x1940, 0x1940,
+	0x19de, 0x19ff,
+	0x1b61, 0x1b6a,
+	0x1b74, 0x1b7c,
+	0x1fbd, 0x1fbd,
+	0x1fbf, 0x1fc1,
+	0x1fcd, 0x1fcf,
+	0x1fdd, 0x1fdf,
+	0x1fed, 0x1fef,
+	0x1ffd, 0x1ffe,
+	0x2044, 0x2044,
+	0x2052, 0x2052,
+	0x207a, 0x207c,
+	0x208a, 0x208c,
+	0x20a0, 0x20bf,
+	0x2100, 0x2101,
+	0x2103, 0x2106,
+	0x2108, 0x2109,
+	0x2114, 0x2114,
+	0x2116, 0x2118,
+	0x211e, 0x2123,
+	0x2125, 0x2125,
+	0x2127, 0x2127,
+	0x2129, 0x2129,
+	0x212e, 0x212e,
+	0x213a, 0x213b,
+	0x2140, 0x2144,
+	0x214a, 0x214d,
+	0x214f, 0x214f,
+	0x218a, 0x218b,
+	0x2190, 0x2307,
+	0x230c, 0x2328,
+	0x232b, 0x2426,
+	0x2440, 0x244a,
+	0x249c, 0x24e9,
+	0x2500, 0x2767,
+	0x2794, 0x27c4,
+	0x27c7, 0x27e5,
+	0x27f0, 0x2982,
+	0x2999, 0x29d7,
+	0x29dc, 0x29fb,
+	0x29fe, 0x2b73,
+	0x2b76, 0x2b95,
+	0x2b98, 0x2bb9,
+	0x2bbd, 0x2bc8,
+	0x2bca, 0x2bd2,
+	0x2bec, 0x2bef,
+	0x2ce5, 0x2cea,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3004, 0x3004,
+	0x3012, 0x3013,
+	0x3020, 0x3020,
+	0x3036, 0x3037,
+	0x303e, 0x303f,
+	0x309b, 0x309c,
+	0x3190, 0x3191,
+	0x3196, 0x319f,
+	0x31c0, 0x31e3,
+	0x3200, 0x321e,
+	0x322a, 0x3247,
+	0x3250, 0x3250,
+	0x3260, 0x327f,
+	0x328a, 0x32b0,
+	0x32c0, 0x32fe,
+	0x3300, 0x33ff,
+	0x4dc0, 0x4dff,
+	0xa490, 0xa4c6,
+	0xa700, 0xa716,
+	0xa720, 0xa721,
+	0xa789, 0xa78a,
+	0xa828, 0xa82b,
+	0xa836, 0xa839,
+	0xaa77, 0xaa79,
+	0xab5b, 0xab5b,
+	0xfb29, 0xfb29,
+	0xfbb2, 0xfbc1,
+	0xfdfc, 0xfdfd,
+	0xfe62, 0xfe62,
+	0xfe64, 0xfe66,
+	0xfe69, 0xfe69,
+	0xff04, 0xff04,
+	0xff0b, 0xff0b,
+	0xff1c, 0xff1e,
+	0xff3e, 0xff3e,
+	0xff40, 0xff40,
+	0xff5c, 0xff5c,
+	0xff5e, 0xff5e,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfffc, 0xfffd,
+	0x10137, 0x1013f,
+	0x10179, 0x10189,
+	0x1018c, 0x1018e,
+	0x10190, 0x1019b,
+	0x101a0, 0x101a0,
+	0x101d0, 0x101fc,
+	0x10877, 0x10878,
+	0x10ac8, 0x10ac8,
+	0x1173f, 0x1173f,
+	0x16b3c, 0x16b3f,
+	0x16b45, 0x16b45,
+	0x1bc9c, 0x1bc9c,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d129, 0x1d164,
+	0x1d16a, 0x1d16c,
+	0x1d183, 0x1d184,
+	0x1d18c, 0x1d1a9,
+	0x1d1ae, 0x1d1e8,
+	0x1d200, 0x1d241,
+	0x1d245, 0x1d245,
+	0x1d300, 0x1d356,
+	0x1d6c1, 0x1d6c1,
+	0x1d6db, 0x1d6db,
+	0x1d6fb, 0x1d6fb,
+	0x1d715, 0x1d715,
+	0x1d735, 0x1d735,
+	0x1d74f, 0x1d74f,
+	0x1d76f, 0x1d76f,
+	0x1d789, 0x1d789,
+	0x1d7a9, 0x1d7a9,
+	0x1d7c3, 0x1d7c3,
+	0x1d800, 0x1d9ff,
+	0x1da37, 0x1da3a,
+	0x1da6d, 0x1da74,
+	0x1da76, 0x1da83,
+	0x1da85, 0x1da86,
+	0x1eef0, 0x1eef1,
+	0x1f000, 0x1f02b,
+	0x1f030, 0x1f093,
+	0x1f0a0, 0x1f0ae,
+	0x1f0b1, 0x1f0bf,
+	0x1f0c1, 0x1f0cf,
+	0x1f0d1, 0x1f0f5,
+	0x1f110, 0x1f12e,
+	0x1f130, 0x1f16b,
+	0x1f170, 0x1f1ac,
+	0x1f1e6, 0x1f202,
+	0x1f210, 0x1f23b,
+	0x1f240, 0x1f248,
+	0x1f250, 0x1f251,
+	0x1f260, 0x1f265,
+	0x1f300, 0x1f6d4,
+	0x1f6e0, 0x1f6ec,
+	0x1f6f0, 0x1f6f8,
+	0x1f700, 0x1f773,
+	0x1f780, 0x1f7d4,
+	0x1f800, 0x1f80b,
+	0x1f810, 0x1f847,
+	0x1f850, 0x1f859,
+	0x1f860, 0x1f887,
+	0x1f890, 0x1f8ad,
+	0x1f900, 0x1f90b,
+	0x1f910, 0x1f93e,
+	0x1f940, 0x1f94c,
+	0x1f950, 0x1f96b,
+	0x1f980, 0x1f997,
+	0x1f9c0, 0x1f9c0,
+	0x1f9d0, 0x1f9e6,
+}; /* CR_S */
+
+/* 'Sc': General Category */
+static const OnigCodePoint CR_Sc[] = {
+	17,
+	0x0024, 0x0024,
+	0x00a2, 0x00a5,
+	0x058f, 0x058f,
+	0x060b, 0x060b,
+	0x09f2, 0x09f3,
+	0x09fb, 0x09fb,
+	0x0af1, 0x0af1,
+	0x0bf9, 0x0bf9,
+	0x0e3f, 0x0e3f,
+	0x17db, 0x17db,
+	0x20a0, 0x20bf,
+	0xa838, 0xa838,
+	0xfdfc, 0xfdfc,
+	0xfe69, 0xfe69,
+	0xff04, 0xff04,
+	0xffe0, 0xffe1,
+	0xffe5, 0xffe6,
+}; /* CR_Sc */
+
+/* 'Sk': General Category */
+static const OnigCodePoint CR_Sk[] = {
+	29,
+	0x005e, 0x005e,
+	0x0060, 0x0060,
+	0x00a8, 0x00a8,
+	0x00af, 0x00af,
+	0x00b4, 0x00b4,
+	0x00b8, 0x00b8,
+	0x02c2, 0x02c5,
+	0x02d2, 0x02df,
+	0x02e5, 0x02eb,
+	0x02ed, 0x02ed,
+	0x02ef, 0x02ff,
+	0x0375, 0x0375,
+	0x0384, 0x0385,
+	0x1fbd, 0x1fbd,
+	0x1fbf, 0x1fc1,
+	0x1fcd, 0x1fcf,
+	0x1fdd, 0x1fdf,
+	0x1fed, 0x1fef,
+	0x1ffd, 0x1ffe,
+	0x309b, 0x309c,
+	0xa700, 0xa716,
+	0xa720, 0xa721,
+	0xa789, 0xa78a,
+	0xab5b, 0xab5b,
+	0xfbb2, 0xfbc1,
+	0xff3e, 0xff3e,
+	0xff40, 0xff40,
+	0xffe3, 0xffe3,
+	0x1f3fb, 0x1f3ff,
+}; /* CR_Sk */
+
+/* 'Sm': General Category */
+static const OnigCodePoint CR_Sm[] = {
+	64,
+	0x002b, 0x002b,
+	0x003c, 0x003e,
+	0x007c, 0x007c,
+	0x007e, 0x007e,
+	0x00ac, 0x00ac,
+	0x00b1, 0x00b1,
+	0x00d7, 0x00d7,
+	0x00f7, 0x00f7,
+	0x03f6, 0x03f6,
+	0x0606, 0x0608,
+	0x2044, 0x2044,
+	0x2052, 0x2052,
+	0x207a, 0x207c,
+	0x208a, 0x208c,
+	0x2118, 0x2118,
+	0x2140, 0x2144,
+	0x214b, 0x214b,
+	0x2190, 0x2194,
+	0x219a, 0x219b,
+	0x21a0, 0x21a0,
+	0x21a3, 0x21a3,
+	0x21a6, 0x21a6,
+	0x21ae, 0x21ae,
+	0x21ce, 0x21cf,
+	0x21d2, 0x21d2,
+	0x21d4, 0x21d4,
+	0x21f4, 0x22ff,
+	0x2320, 0x2321,
+	0x237c, 0x237c,
+	0x239b, 0x23b3,
+	0x23dc, 0x23e1,
+	0x25b7, 0x25b7,
+	0x25c1, 0x25c1,
+	0x25f8, 0x25ff,
+	0x266f, 0x266f,
+	0x27c0, 0x27c4,
+	0x27c7, 0x27e5,
+	0x27f0, 0x27ff,
+	0x2900, 0x2982,
+	0x2999, 0x29d7,
+	0x29dc, 0x29fb,
+	0x29fe, 0x2aff,
+	0x2b30, 0x2b44,
+	0x2b47, 0x2b4c,
+	0xfb29, 0xfb29,
+	0xfe62, 0xfe62,
+	0xfe64, 0xfe66,
+	0xff0b, 0xff0b,
+	0xff1c, 0xff1e,
+	0xff5c, 0xff5c,
+	0xff5e, 0xff5e,
+	0xffe2, 0xffe2,
+	0xffe9, 0xffec,
+	0x1d6c1, 0x1d6c1,
+	0x1d6db, 0x1d6db,
+	0x1d6fb, 0x1d6fb,
+	0x1d715, 0x1d715,
+	0x1d735, 0x1d735,
+	0x1d74f, 0x1d74f,
+	0x1d76f, 0x1d76f,
+	0x1d789, 0x1d789,
+	0x1d7a9, 0x1d7a9,
+	0x1d7c3, 0x1d7c3,
+	0x1eef0, 0x1eef1,
+}; /* CR_Sm */
+
+/* 'So': General Category */
+static const OnigCodePoint CR_So[] = {
+	173,
+	0x00a6, 0x00a6,
+	0x00a9, 0x00a9,
+	0x00ae, 0x00ae,
+	0x00b0, 0x00b0,
+	0x0482, 0x0482,
+	0x058d, 0x058e,
+	0x060e, 0x060f,
+	0x06de, 0x06de,
+	0x06e9, 0x06e9,
+	0x06fd, 0x06fe,
+	0x07f6, 0x07f6,
+	0x09fa, 0x09fa,
+	0x0b70, 0x0b70,
+	0x0bf3, 0x0bf8,
+	0x0bfa, 0x0bfa,
+	0x0c7f, 0x0c7f,
+	0x0d4f, 0x0d4f,
+	0x0d79, 0x0d79,
+	0x0f01, 0x0f03,
+	0x0f13, 0x0f13,
+	0x0f15, 0x0f17,
+	0x0f1a, 0x0f1f,
+	0x0f34, 0x0f34,
+	0x0f36, 0x0f36,
+	0x0f38, 0x0f38,
+	0x0fbe, 0x0fc5,
+	0x0fc7, 0x0fcc,
+	0x0fce, 0x0fcf,
+	0x0fd5, 0x0fd8,
+	0x109e, 0x109f,
+	0x1390, 0x1399,
+	0x1940, 0x1940,
+	0x19de, 0x19ff,
+	0x1b61, 0x1b6a,
+	0x1b74, 0x1b7c,
+	0x2100, 0x2101,
+	0x2103, 0x2106,
+	0x2108, 0x2109,
+	0x2114, 0x2114,
+	0x2116, 0x2117,
+	0x211e, 0x2123,
+	0x2125, 0x2125,
+	0x2127, 0x2127,
+	0x2129, 0x2129,
+	0x212e, 0x212e,
+	0x213a, 0x213b,
+	0x214a, 0x214a,
+	0x214c, 0x214d,
+	0x214f, 0x214f,
+	0x218a, 0x218b,
+	0x2195, 0x2199,
+	0x219c, 0x219f,
+	0x21a1, 0x21a2,
+	0x21a4, 0x21a5,
+	0x21a7, 0x21ad,
+	0x21af, 0x21cd,
+	0x21d0, 0x21d1,
+	0x21d3, 0x21d3,
+	0x21d5, 0x21f3,
+	0x2300, 0x2307,
+	0x230c, 0x231f,
+	0x2322, 0x2328,
+	0x232b, 0x237b,
+	0x237d, 0x239a,
+	0x23b4, 0x23db,
+	0x23e2, 0x2426,
+	0x2440, 0x244a,
+	0x249c, 0x24e9,
+	0x2500, 0x25b6,
+	0x25b8, 0x25c0,
+	0x25c2, 0x25f7,
+	0x2600, 0x266e,
+	0x2670, 0x2767,
+	0x2794, 0x27bf,
+	0x2800, 0x28ff,
+	0x2b00, 0x2b2f,
+	0x2b45, 0x2b46,
+	0x2b4d, 0x2b73,
+	0x2b76, 0x2b95,
+	0x2b98, 0x2bb9,
+	0x2bbd, 0x2bc8,
+	0x2bca, 0x2bd2,
+	0x2bec, 0x2bef,
+	0x2ce5, 0x2cea,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3004, 0x3004,
+	0x3012, 0x3013,
+	0x3020, 0x3020,
+	0x3036, 0x3037,
+	0x303e, 0x303f,
+	0x3190, 0x3191,
+	0x3196, 0x319f,
+	0x31c0, 0x31e3,
+	0x3200, 0x321e,
+	0x322a, 0x3247,
+	0x3250, 0x3250,
+	0x3260, 0x327f,
+	0x328a, 0x32b0,
+	0x32c0, 0x32fe,
+	0x3300, 0x33ff,
+	0x4dc0, 0x4dff,
+	0xa490, 0xa4c6,
+	0xa828, 0xa82b,
+	0xa836, 0xa837,
+	0xa839, 0xa839,
+	0xaa77, 0xaa79,
+	0xfdfd, 0xfdfd,
+	0xffe4, 0xffe4,
+	0xffe8, 0xffe8,
+	0xffed, 0xffee,
+	0xfffc, 0xfffd,
+	0x10137, 0x1013f,
+	0x10179, 0x10189,
+	0x1018c, 0x1018e,
+	0x10190, 0x1019b,
+	0x101a0, 0x101a0,
+	0x101d0, 0x101fc,
+	0x10877, 0x10878,
+	0x10ac8, 0x10ac8,
+	0x1173f, 0x1173f,
+	0x16b3c, 0x16b3f,
+	0x16b45, 0x16b45,
+	0x1bc9c, 0x1bc9c,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d129, 0x1d164,
+	0x1d16a, 0x1d16c,
+	0x1d183, 0x1d184,
+	0x1d18c, 0x1d1a9,
+	0x1d1ae, 0x1d1e8,
+	0x1d200, 0x1d241,
+	0x1d245, 0x1d245,
+	0x1d300, 0x1d356,
+	0x1d800, 0x1d9ff,
+	0x1da37, 0x1da3a,
+	0x1da6d, 0x1da74,
+	0x1da76, 0x1da83,
+	0x1da85, 0x1da86,
+	0x1f000, 0x1f02b,
+	0x1f030, 0x1f093,
+	0x1f0a0, 0x1f0ae,
+	0x1f0b1, 0x1f0bf,
+	0x1f0c1, 0x1f0cf,
+	0x1f0d1, 0x1f0f5,
+	0x1f110, 0x1f12e,
+	0x1f130, 0x1f16b,
+	0x1f170, 0x1f1ac,
+	0x1f1e6, 0x1f202,
+	0x1f210, 0x1f23b,
+	0x1f240, 0x1f248,
+	0x1f250, 0x1f251,
+	0x1f260, 0x1f265,
+	0x1f300, 0x1f3fa,
+	0x1f400, 0x1f6d4,
+	0x1f6e0, 0x1f6ec,
+	0x1f6f0, 0x1f6f8,
+	0x1f700, 0x1f773,
+	0x1f780, 0x1f7d4,
+	0x1f800, 0x1f80b,
+	0x1f810, 0x1f847,
+	0x1f850, 0x1f859,
+	0x1f860, 0x1f887,
+	0x1f890, 0x1f8ad,
+	0x1f900, 0x1f90b,
+	0x1f910, 0x1f93e,
+	0x1f940, 0x1f94c,
+	0x1f950, 0x1f96b,
+	0x1f980, 0x1f997,
+	0x1f9c0, 0x1f9c0,
+	0x1f9d0, 0x1f9e6,
+}; /* CR_So */
+
+/* 'Z': Major Category */
+static const OnigCodePoint CR_Z[] = {
+	8,
+	0x0020, 0x0020,
+	0x00a0, 0x00a0,
+	0x1680, 0x1680,
+	0x2000, 0x200a,
+	0x2028, 0x2029,
+	0x202f, 0x202f,
+	0x205f, 0x205f,
+	0x3000, 0x3000,
+}; /* CR_Z */
+
+/* 'Zl': General Category */
+static const OnigCodePoint CR_Zl[] = {
+	1,
+	0x2028, 0x2028,
+}; /* CR_Zl */
+
+/* 'Zp': General Category */
+static const OnigCodePoint CR_Zp[] = {
+	1,
+	0x2029, 0x2029,
+}; /* CR_Zp */
+
+/* 'Zs': General Category */
+static const OnigCodePoint CR_Zs[] = {
+	7,
+	0x0020, 0x0020,
+	0x00a0, 0x00a0,
+	0x1680, 0x1680,
+	0x2000, 0x200a,
+	0x202f, 0x202f,
+	0x205f, 0x205f,
+	0x3000, 0x3000,
+}; /* CR_Zs */
+
+/* 'Math': Derived Property */
+static const OnigCodePoint CR_Math[] = {
+	138,
+	0x002b, 0x002b,
+	0x003c, 0x003e,
+	0x005e, 0x005e,
+	0x007c, 0x007c,
+	0x007e, 0x007e,
+	0x00ac, 0x00ac,
+	0x00b1, 0x00b1,
+	0x00d7, 0x00d7,
+	0x00f7, 0x00f7,
+	0x03d0, 0x03d2,
+	0x03d5, 0x03d5,
+	0x03f0, 0x03f1,
+	0x03f4, 0x03f6,
+	0x0606, 0x0608,
+	0x2016, 0x2016,
+	0x2032, 0x2034,
+	0x2040, 0x2040,
+	0x2044, 0x2044,
+	0x2052, 0x2052,
+	0x2061, 0x2064,
+	0x207a, 0x207e,
+	0x208a, 0x208e,
+	0x20d0, 0x20dc,
+	0x20e1, 0x20e1,
+	0x20e5, 0x20e6,
+	0x20eb, 0x20ef,
+	0x2102, 0x2102,
+	0x2107, 0x2107,
+	0x210a, 0x2113,
+	0x2115, 0x2115,
+	0x2118, 0x211d,
+	0x2124, 0x2124,
+	0x2128, 0x2129,
+	0x212c, 0x212d,
+	0x212f, 0x2131,
+	0x2133, 0x2138,
+	0x213c, 0x2149,
+	0x214b, 0x214b,
+	0x2190, 0x21a7,
+	0x21a9, 0x21ae,
+	0x21b0, 0x21b1,
+	0x21b6, 0x21b7,
+	0x21bc, 0x21db,
+	0x21dd, 0x21dd,
+	0x21e4, 0x21e5,
+	0x21f4, 0x22ff,
+	0x2308, 0x230b,
+	0x2320, 0x2321,
+	0x237c, 0x237c,
+	0x239b, 0x23b5,
+	0x23b7, 0x23b7,
+	0x23d0, 0x23d0,
+	0x23dc, 0x23e2,
+	0x25a0, 0x25a1,
+	0x25ae, 0x25b7,
+	0x25bc, 0x25c1,
+	0x25c6, 0x25c7,
+	0x25ca, 0x25cb,
+	0x25cf, 0x25d3,
+	0x25e2, 0x25e2,
+	0x25e4, 0x25e4,
+	0x25e7, 0x25ec,
+	0x25f8, 0x25ff,
+	0x2605, 0x2606,
+	0x2640, 0x2640,
+	0x2642, 0x2642,
+	0x2660, 0x2663,
+	0x266d, 0x266f,
+	0x27c0, 0x27ff,
+	0x2900, 0x2aff,
+	0x2b30, 0x2b44,
+	0x2b47, 0x2b4c,
+	0xfb29, 0xfb29,
+	0xfe61, 0xfe66,
+	0xfe68, 0xfe68,
+	0xff0b, 0xff0b,
+	0xff1c, 0xff1e,
+	0xff3c, 0xff3c,
+	0xff3e, 0xff3e,
+	0xff5c, 0xff5c,
+	0xff5e, 0xff5e,
+	0xffe2, 0xffe2,
+	0xffe9, 0xffec,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d7cb,
+	0x1d7ce, 0x1d7ff,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x1eef0, 0x1eef1,
+}; /* CR_Math */
+
+/* 'Alphabetic': Derived Property */
+#define CR_Alphabetic CR_Alpha
+
+/* 'Lowercase': Derived Property */
+#define CR_Lowercase CR_Lower
+
+/* 'Uppercase': Derived Property */
+#define CR_Uppercase CR_Upper
+
+/* 'Cased': Derived Property */
+static const OnigCodePoint CR_Cased[] = {
+	135,
+	0x0041, 0x005a,
+	0x0061, 0x007a,
+	0x00aa, 0x00aa,
+	0x00b5, 0x00b5,
+	0x00ba, 0x00ba,
+	0x00c0, 0x00d6,
+	0x00d8, 0x00f6,
+	0x00f8, 0x01ba,
+	0x01bc, 0x01bf,
+	0x01c4, 0x0293,
+	0x0295, 0x02b8,
+	0x02c0, 0x02c1,
+	0x02e0, 0x02e4,
+	0x0345, 0x0345,
+	0x0370, 0x0373,
+	0x0376, 0x0377,
+	0x037a, 0x037d,
+	0x037f, 0x037f,
+	0x0386, 0x0386,
+	0x0388, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03f5,
+	0x03f7, 0x0481,
+	0x048a, 0x052f,
+	0x0531, 0x0556,
+	0x0561, 0x0587,
+	0x10a0, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x13a0, 0x13f5,
+	0x13f8, 0x13fd,
+	0x1c80, 0x1c88,
+	0x1d00, 0x1dbf,
+	0x1e00, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fbc,
+	0x1fbe, 0x1fbe,
+	0x1fc2, 0x1fc4,
+	0x1fc6, 0x1fcc,
+	0x1fd0, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fe0, 0x1fec,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffc,
+	0x2071, 0x2071,
+	0x207f, 0x207f,
+	0x2090, 0x209c,
+	0x2102, 0x2102,
+	0x2107, 0x2107,
+	0x210a, 0x2113,
+	0x2115, 0x2115,
+	0x2119, 0x211d,
+	0x2124, 0x2124,
+	0x2126, 0x2126,
+	0x2128, 0x2128,
+	0x212a, 0x212d,
+	0x212f, 0x2134,
+	0x2139, 0x2139,
+	0x213c, 0x213f,
+	0x2145, 0x2149,
+	0x214e, 0x214e,
+	0x2160, 0x217f,
+	0x2183, 0x2184,
+	0x24b6, 0x24e9,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2ce4,
+	0x2ceb, 0x2cee,
+	0x2cf2, 0x2cf3,
+	0x2d00, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0xa640, 0xa66d,
+	0xa680, 0xa69d,
+	0xa722, 0xa787,
+	0xa78b, 0xa78e,
+	0xa790, 0xa7ae,
+	0xa7b0, 0xa7b7,
+	0xa7f8, 0xa7fa,
+	0xab30, 0xab5a,
+	0xab5c, 0xab65,
+	0xab70, 0xabbf,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xff21, 0xff3a,
+	0xff41, 0xff5a,
+	0x10400, 0x1044f,
+	0x104b0, 0x104d3,
+	0x104d8, 0x104fb,
+	0x10c80, 0x10cb2,
+	0x10cc0, 0x10cf2,
+	0x118a0, 0x118df,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d6c0,
+	0x1d6c2, 0x1d6da,
+	0x1d6dc, 0x1d6fa,
+	0x1d6fc, 0x1d714,
+	0x1d716, 0x1d734,
+	0x1d736, 0x1d74e,
+	0x1d750, 0x1d76e,
+	0x1d770, 0x1d788,
+	0x1d78a, 0x1d7a8,
+	0x1d7aa, 0x1d7c2,
+	0x1d7c4, 0x1d7cb,
+	0x1e900, 0x1e943,
+	0x1f130, 0x1f149,
+	0x1f150, 0x1f169,
+	0x1f170, 0x1f189,
+}; /* CR_Cased */
+
+/* 'Case_Ignorable': Derived Property */
+static const OnigCodePoint CR_Case_Ignorable[] = {
+	381,
+	0x0027, 0x0027,
+	0x002e, 0x002e,
+	0x003a, 0x003a,
+	0x005e, 0x005e,
+	0x0060, 0x0060,
+	0x00a8, 0x00a8,
+	0x00ad, 0x00ad,
+	0x00af, 0x00af,
+	0x00b4, 0x00b4,
+	0x00b7, 0x00b8,
+	0x02b0, 0x036f,
+	0x0374, 0x0375,
+	0x037a, 0x037a,
+	0x0384, 0x0385,
+	0x0387, 0x0387,
+	0x0483, 0x0489,
+	0x0559, 0x0559,
+	0x0591, 0x05bd,
+	0x05bf, 0x05bf,
+	0x05c1, 0x05c2,
+	0x05c4, 0x05c5,
+	0x05c7, 0x05c7,
+	0x05f4, 0x05f4,
+	0x0600, 0x0605,
+	0x0610, 0x061a,
+	0x061c, 0x061c,
+	0x0640, 0x0640,
+	0x064b, 0x065f,
+	0x0670, 0x0670,
+	0x06d6, 0x06dd,
+	0x06df, 0x06e8,
+	0x06ea, 0x06ed,
+	0x070f, 0x070f,
+	0x0711, 0x0711,
+	0x0730, 0x074a,
+	0x07a6, 0x07b0,
+	0x07eb, 0x07f5,
+	0x07fa, 0x07fa,
+	0x0816, 0x082d,
+	0x0859, 0x085b,
+	0x08d4, 0x0902,
+	0x093a, 0x093a,
+	0x093c, 0x093c,
+	0x0941, 0x0948,
+	0x094d, 0x094d,
+	0x0951, 0x0957,
+	0x0962, 0x0963,
+	0x0971, 0x0971,
+	0x0981, 0x0981,
+	0x09bc, 0x09bc,
+	0x09c1, 0x09c4,
+	0x09cd, 0x09cd,
+	0x09e2, 0x09e3,
+	0x0a01, 0x0a02,
+	0x0a3c, 0x0a3c,
+	0x0a41, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a70, 0x0a71,
+	0x0a75, 0x0a75,
+	0x0a81, 0x0a82,
+	0x0abc, 0x0abc,
+	0x0ac1, 0x0ac5,
+	0x0ac7, 0x0ac8,
+	0x0acd, 0x0acd,
+	0x0ae2, 0x0ae3,
+	0x0afa, 0x0aff,
+	0x0b01, 0x0b01,
+	0x0b3c, 0x0b3c,
+	0x0b3f, 0x0b3f,
+	0x0b41, 0x0b44,
+	0x0b4d, 0x0b4d,
+	0x0b56, 0x0b56,
+	0x0b62, 0x0b63,
+	0x0b82, 0x0b82,
+	0x0bc0, 0x0bc0,
+	0x0bcd, 0x0bcd,
+	0x0c00, 0x0c00,
+	0x0c3e, 0x0c40,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c62, 0x0c63,
+	0x0c81, 0x0c81,
+	0x0cbc, 0x0cbc,
+	0x0cbf, 0x0cbf,
+	0x0cc6, 0x0cc6,
+	0x0ccc, 0x0ccd,
+	0x0ce2, 0x0ce3,
+	0x0d00, 0x0d01,
+	0x0d3b, 0x0d3c,
+	0x0d41, 0x0d44,
+	0x0d4d, 0x0d4d,
+	0x0d62, 0x0d63,
+	0x0dca, 0x0dca,
+	0x0dd2, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0e31, 0x0e31,
+	0x0e34, 0x0e3a,
+	0x0e46, 0x0e4e,
+	0x0eb1, 0x0eb1,
+	0x0eb4, 0x0eb9,
+	0x0ebb, 0x0ebc,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0f18, 0x0f19,
+	0x0f35, 0x0f35,
+	0x0f37, 0x0f37,
+	0x0f39, 0x0f39,
+	0x0f71, 0x0f7e,
+	0x0f80, 0x0f84,
+	0x0f86, 0x0f87,
+	0x0f8d, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fc6, 0x0fc6,
+	0x102d, 0x1030,
+	0x1032, 0x1037,
+	0x1039, 0x103a,
+	0x103d, 0x103e,
+	0x1058, 0x1059,
+	0x105e, 0x1060,
+	0x1071, 0x1074,
+	0x1082, 0x1082,
+	0x1085, 0x1086,
+	0x108d, 0x108d,
+	0x109d, 0x109d,
+	0x10fc, 0x10fc,
+	0x135d, 0x135f,
+	0x1712, 0x1714,
+	0x1732, 0x1734,
+	0x1752, 0x1753,
+	0x1772, 0x1773,
+	0x17b4, 0x17b5,
+	0x17b7, 0x17bd,
+	0x17c6, 0x17c6,
+	0x17c9, 0x17d3,
+	0x17d7, 0x17d7,
+	0x17dd, 0x17dd,
+	0x180b, 0x180e,
+	0x1843, 0x1843,
+	0x1885, 0x1886,
+	0x18a9, 0x18a9,
+	0x1920, 0x1922,
+	0x1927, 0x1928,
+	0x1932, 0x1932,
+	0x1939, 0x193b,
+	0x1a17, 0x1a18,
+	0x1a1b, 0x1a1b,
+	0x1a56, 0x1a56,
+	0x1a58, 0x1a5e,
+	0x1a60, 0x1a60,
+	0x1a62, 0x1a62,
+	0x1a65, 0x1a6c,
+	0x1a73, 0x1a7c,
+	0x1a7f, 0x1a7f,
+	0x1aa7, 0x1aa7,
+	0x1ab0, 0x1abe,
+	0x1b00, 0x1b03,
+	0x1b34, 0x1b34,
+	0x1b36, 0x1b3a,
+	0x1b3c, 0x1b3c,
+	0x1b42, 0x1b42,
+	0x1b6b, 0x1b73,
+	0x1b80, 0x1b81,
+	0x1ba2, 0x1ba5,
+	0x1ba8, 0x1ba9,
+	0x1bab, 0x1bad,
+	0x1be6, 0x1be6,
+	0x1be8, 0x1be9,
+	0x1bed, 0x1bed,
+	0x1bef, 0x1bf1,
+	0x1c2c, 0x1c33,
+	0x1c36, 0x1c37,
+	0x1c78, 0x1c7d,
+	0x1cd0, 0x1cd2,
+	0x1cd4, 0x1ce0,
+	0x1ce2, 0x1ce8,
+	0x1ced, 0x1ced,
+	0x1cf4, 0x1cf4,
+	0x1cf8, 0x1cf9,
+	0x1d2c, 0x1d6a,
+	0x1d78, 0x1d78,
+	0x1d9b, 0x1df9,
+	0x1dfb, 0x1dff,
+	0x1fbd, 0x1fbd,
+	0x1fbf, 0x1fc1,
+	0x1fcd, 0x1fcf,
+	0x1fdd, 0x1fdf,
+	0x1fed, 0x1fef,
+	0x1ffd, 0x1ffe,
+	0x200b, 0x200f,
+	0x2018, 0x2019,
+	0x2024, 0x2024,
+	0x2027, 0x2027,
+	0x202a, 0x202e,
+	0x2060, 0x2064,
+	0x2066, 0x206f,
+	0x2071, 0x2071,
+	0x207f, 0x207f,
+	0x2090, 0x209c,
+	0x20d0, 0x20f0,
+	0x2c7c, 0x2c7d,
+	0x2cef, 0x2cf1,
+	0x2d6f, 0x2d6f,
+	0x2d7f, 0x2d7f,
+	0x2de0, 0x2dff,
+	0x2e2f, 0x2e2f,
+	0x3005, 0x3005,
+	0x302a, 0x302d,
+	0x3031, 0x3035,
+	0x303b, 0x303b,
+	0x3099, 0x309e,
+	0x30fc, 0x30fe,
+	0xa015, 0xa015,
+	0xa4f8, 0xa4fd,
+	0xa60c, 0xa60c,
+	0xa66f, 0xa672,
+	0xa674, 0xa67d,
+	0xa67f, 0xa67f,
+	0xa69c, 0xa69f,
+	0xa6f0, 0xa6f1,
+	0xa700, 0xa721,
+	0xa770, 0xa770,
+	0xa788, 0xa78a,
+	0xa7f8, 0xa7f9,
+	0xa802, 0xa802,
+	0xa806, 0xa806,
+	0xa80b, 0xa80b,
+	0xa825, 0xa826,
+	0xa8c4, 0xa8c5,
+	0xa8e0, 0xa8f1,
+	0xa926, 0xa92d,
+	0xa947, 0xa951,
+	0xa980, 0xa982,
+	0xa9b3, 0xa9b3,
+	0xa9b6, 0xa9b9,
+	0xa9bc, 0xa9bc,
+	0xa9cf, 0xa9cf,
+	0xa9e5, 0xa9e6,
+	0xaa29, 0xaa2e,
+	0xaa31, 0xaa32,
+	0xaa35, 0xaa36,
+	0xaa43, 0xaa43,
+	0xaa4c, 0xaa4c,
+	0xaa70, 0xaa70,
+	0xaa7c, 0xaa7c,
+	0xaab0, 0xaab0,
+	0xaab2, 0xaab4,
+	0xaab7, 0xaab8,
+	0xaabe, 0xaabf,
+	0xaac1, 0xaac1,
+	0xaadd, 0xaadd,
+	0xaaec, 0xaaed,
+	0xaaf3, 0xaaf4,
+	0xaaf6, 0xaaf6,
+	0xab5b, 0xab5f,
+	0xabe5, 0xabe5,
+	0xabe8, 0xabe8,
+	0xabed, 0xabed,
+	0xfb1e, 0xfb1e,
+	0xfbb2, 0xfbc1,
+	0xfe00, 0xfe0f,
+	0xfe13, 0xfe13,
+	0xfe20, 0xfe2f,
+	0xfe52, 0xfe52,
+	0xfe55, 0xfe55,
+	0xfeff, 0xfeff,
+	0xff07, 0xff07,
+	0xff0e, 0xff0e,
+	0xff1a, 0xff1a,
+	0xff3e, 0xff3e,
+	0xff40, 0xff40,
+	0xff70, 0xff70,
+	0xff9e, 0xff9f,
+	0xffe3, 0xffe3,
+	0xfff9, 0xfffb,
+	0x101fd, 0x101fd,
+	0x102e0, 0x102e0,
+	0x10376, 0x1037a,
+	0x10a01, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a0f,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a3f,
+	0x10ae5, 0x10ae6,
+	0x11001, 0x11001,
+	0x11038, 0x11046,
+	0x1107f, 0x11081,
+	0x110b3, 0x110b6,
+	0x110b9, 0x110ba,
+	0x110bd, 0x110bd,
+	0x11100, 0x11102,
+	0x11127, 0x1112b,
+	0x1112d, 0x11134,
+	0x11173, 0x11173,
+	0x11180, 0x11181,
+	0x111b6, 0x111be,
+	0x111ca, 0x111cc,
+	0x1122f, 0x11231,
+	0x11234, 0x11234,
+	0x11236, 0x11237,
+	0x1123e, 0x1123e,
+	0x112df, 0x112df,
+	0x112e3, 0x112ea,
+	0x11300, 0x11301,
+	0x1133c, 0x1133c,
+	0x11340, 0x11340,
+	0x11366, 0x1136c,
+	0x11370, 0x11374,
+	0x11438, 0x1143f,
+	0x11442, 0x11444,
+	0x11446, 0x11446,
+	0x114b3, 0x114b8,
+	0x114ba, 0x114ba,
+	0x114bf, 0x114c0,
+	0x114c2, 0x114c3,
+	0x115b2, 0x115b5,
+	0x115bc, 0x115bd,
+	0x115bf, 0x115c0,
+	0x115dc, 0x115dd,
+	0x11633, 0x1163a,
+	0x1163d, 0x1163d,
+	0x1163f, 0x11640,
+	0x116ab, 0x116ab,
+	0x116ad, 0x116ad,
+	0x116b0, 0x116b5,
+	0x116b7, 0x116b7,
+	0x1171d, 0x1171f,
+	0x11722, 0x11725,
+	0x11727, 0x1172b,
+	0x11a01, 0x11a06,
+	0x11a09, 0x11a0a,
+	0x11a33, 0x11a38,
+	0x11a3b, 0x11a3e,
+	0x11a47, 0x11a47,
+	0x11a51, 0x11a56,
+	0x11a59, 0x11a5b,
+	0x11a8a, 0x11a96,
+	0x11a98, 0x11a99,
+	0x11c30, 0x11c36,
+	0x11c38, 0x11c3d,
+	0x11c3f, 0x11c3f,
+	0x11c92, 0x11ca7,
+	0x11caa, 0x11cb0,
+	0x11cb2, 0x11cb3,
+	0x11cb5, 0x11cb6,
+	0x11d31, 0x11d36,
+	0x11d3a, 0x11d3a,
+	0x11d3c, 0x11d3d,
+	0x11d3f, 0x11d45,
+	0x11d47, 0x11d47,
+	0x16af0, 0x16af4,
+	0x16b30, 0x16b36,
+	0x16b40, 0x16b43,
+	0x16f8f, 0x16f9f,
+	0x16fe0, 0x16fe1,
+	0x1bc9d, 0x1bc9e,
+	0x1bca0, 0x1bca3,
+	0x1d167, 0x1d169,
+	0x1d173, 0x1d182,
+	0x1d185, 0x1d18b,
+	0x1d1aa, 0x1d1ad,
+	0x1d242, 0x1d244,
+	0x1da00, 0x1da36,
+	0x1da3b, 0x1da6c,
+	0x1da75, 0x1da75,
+	0x1da84, 0x1da84,
+	0x1da9b, 0x1da9f,
+	0x1daa1, 0x1daaf,
+	0x1e000, 0x1e006,
+	0x1e008, 0x1e018,
+	0x1e01b, 0x1e021,
+	0x1e023, 0x1e024,
+	0x1e026, 0x1e02a,
+	0x1e8d0, 0x1e8d6,
+	0x1e944, 0x1e94a,
+	0x1f3fb, 0x1f3ff,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+	0xe0100, 0xe01ef,
+}; /* CR_Case_Ignorable */
+
+/* 'Changes_When_Lowercased': Derived Property */
+static const OnigCodePoint CR_Changes_When_Lowercased[] = {
+	590,
+	0x0041, 0x005a,
+	0x00c0, 0x00d6,
+	0x00d8, 0x00de,
+	0x0100, 0x0100,
+	0x0102, 0x0102,
+	0x0104, 0x0104,
+	0x0106, 0x0106,
+	0x0108, 0x0108,
+	0x010a, 0x010a,
+	0x010c, 0x010c,
+	0x010e, 0x010e,
+	0x0110, 0x0110,
+	0x0112, 0x0112,
+	0x0114, 0x0114,
+	0x0116, 0x0116,
+	0x0118, 0x0118,
+	0x011a, 0x011a,
+	0x011c, 0x011c,
+	0x011e, 0x011e,
+	0x0120, 0x0120,
+	0x0122, 0x0122,
+	0x0124, 0x0124,
+	0x0126, 0x0126,
+	0x0128, 0x0128,
+	0x012a, 0x012a,
+	0x012c, 0x012c,
+	0x012e, 0x012e,
+	0x0130, 0x0130,
+	0x0132, 0x0132,
+	0x0134, 0x0134,
+	0x0136, 0x0136,
+	0x0139, 0x0139,
+	0x013b, 0x013b,
+	0x013d, 0x013d,
+	0x013f, 0x013f,
+	0x0141, 0x0141,
+	0x0143, 0x0143,
+	0x0145, 0x0145,
+	0x0147, 0x0147,
+	0x014a, 0x014a,
+	0x014c, 0x014c,
+	0x014e, 0x014e,
+	0x0150, 0x0150,
+	0x0152, 0x0152,
+	0x0154, 0x0154,
+	0x0156, 0x0156,
+	0x0158, 0x0158,
+	0x015a, 0x015a,
+	0x015c, 0x015c,
+	0x015e, 0x015e,
+	0x0160, 0x0160,
+	0x0162, 0x0162,
+	0x0164, 0x0164,
+	0x0166, 0x0166,
+	0x0168, 0x0168,
+	0x016a, 0x016a,
+	0x016c, 0x016c,
+	0x016e, 0x016e,
+	0x0170, 0x0170,
+	0x0172, 0x0172,
+	0x0174, 0x0174,
+	0x0176, 0x0176,
+	0x0178, 0x0179,
+	0x017b, 0x017b,
+	0x017d, 0x017d,
+	0x0181, 0x0182,
+	0x0184, 0x0184,
+	0x0186, 0x0187,
+	0x0189, 0x018b,
+	0x018e, 0x0191,
+	0x0193, 0x0194,
+	0x0196, 0x0198,
+	0x019c, 0x019d,
+	0x019f, 0x01a0,
+	0x01a2, 0x01a2,
+	0x01a4, 0x01a4,
+	0x01a6, 0x01a7,
+	0x01a9, 0x01a9,
+	0x01ac, 0x01ac,
+	0x01ae, 0x01af,
+	0x01b1, 0x01b3,
+	0x01b5, 0x01b5,
+	0x01b7, 0x01b8,
+	0x01bc, 0x01bc,
+	0x01c4, 0x01c5,
+	0x01c7, 0x01c8,
+	0x01ca, 0x01cb,
+	0x01cd, 0x01cd,
+	0x01cf, 0x01cf,
+	0x01d1, 0x01d1,
+	0x01d3, 0x01d3,
+	0x01d5, 0x01d5,
+	0x01d7, 0x01d7,
+	0x01d9, 0x01d9,
+	0x01db, 0x01db,
+	0x01de, 0x01de,
+	0x01e0, 0x01e0,
+	0x01e2, 0x01e2,
+	0x01e4, 0x01e4,
+	0x01e6, 0x01e6,
+	0x01e8, 0x01e8,
+	0x01ea, 0x01ea,
+	0x01ec, 0x01ec,
+	0x01ee, 0x01ee,
+	0x01f1, 0x01f2,
+	0x01f4, 0x01f4,
+	0x01f6, 0x01f8,
+	0x01fa, 0x01fa,
+	0x01fc, 0x01fc,
+	0x01fe, 0x01fe,
+	0x0200, 0x0200,
+	0x0202, 0x0202,
+	0x0204, 0x0204,
+	0x0206, 0x0206,
+	0x0208, 0x0208,
+	0x020a, 0x020a,
+	0x020c, 0x020c,
+	0x020e, 0x020e,
+	0x0210, 0x0210,
+	0x0212, 0x0212,
+	0x0214, 0x0214,
+	0x0216, 0x0216,
+	0x0218, 0x0218,
+	0x021a, 0x021a,
+	0x021c, 0x021c,
+	0x021e, 0x021e,
+	0x0220, 0x0220,
+	0x0222, 0x0222,
+	0x0224, 0x0224,
+	0x0226, 0x0226,
+	0x0228, 0x0228,
+	0x022a, 0x022a,
+	0x022c, 0x022c,
+	0x022e, 0x022e,
+	0x0230, 0x0230,
+	0x0232, 0x0232,
+	0x023a, 0x023b,
+	0x023d, 0x023e,
+	0x0241, 0x0241,
+	0x0243, 0x0246,
+	0x0248, 0x0248,
+	0x024a, 0x024a,
+	0x024c, 0x024c,
+	0x024e, 0x024e,
+	0x0370, 0x0370,
+	0x0372, 0x0372,
+	0x0376, 0x0376,
+	0x037f, 0x037f,
+	0x0386, 0x0386,
+	0x0388, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x038f,
+	0x0391, 0x03a1,
+	0x03a3, 0x03ab,
+	0x03cf, 0x03cf,
+	0x03d8, 0x03d8,
+	0x03da, 0x03da,
+	0x03dc, 0x03dc,
+	0x03de, 0x03de,
+	0x03e0, 0x03e0,
+	0x03e2, 0x03e2,
+	0x03e4, 0x03e4,
+	0x03e6, 0x03e6,
+	0x03e8, 0x03e8,
+	0x03ea, 0x03ea,
+	0x03ec, 0x03ec,
+	0x03ee, 0x03ee,
+	0x03f4, 0x03f4,
+	0x03f7, 0x03f7,
+	0x03f9, 0x03fa,
+	0x03fd, 0x042f,
+	0x0460, 0x0460,
+	0x0462, 0x0462,
+	0x0464, 0x0464,
+	0x0466, 0x0466,
+	0x0468, 0x0468,
+	0x046a, 0x046a,
+	0x046c, 0x046c,
+	0x046e, 0x046e,
+	0x0470, 0x0470,
+	0x0472, 0x0472,
+	0x0474, 0x0474,
+	0x0476, 0x0476,
+	0x0478, 0x0478,
+	0x047a, 0x047a,
+	0x047c, 0x047c,
+	0x047e, 0x047e,
+	0x0480, 0x0480,
+	0x048a, 0x048a,
+	0x048c, 0x048c,
+	0x048e, 0x048e,
+	0x0490, 0x0490,
+	0x0492, 0x0492,
+	0x0494, 0x0494,
+	0x0496, 0x0496,
+	0x0498, 0x0498,
+	0x049a, 0x049a,
+	0x049c, 0x049c,
+	0x049e, 0x049e,
+	0x04a0, 0x04a0,
+	0x04a2, 0x04a2,
+	0x04a4, 0x04a4,
+	0x04a6, 0x04a6,
+	0x04a8, 0x04a8,
+	0x04aa, 0x04aa,
+	0x04ac, 0x04ac,
+	0x04ae, 0x04ae,
+	0x04b0, 0x04b0,
+	0x04b2, 0x04b2,
+	0x04b4, 0x04b4,
+	0x04b6, 0x04b6,
+	0x04b8, 0x04b8,
+	0x04ba, 0x04ba,
+	0x04bc, 0x04bc,
+	0x04be, 0x04be,
+	0x04c0, 0x04c1,
+	0x04c3, 0x04c3,
+	0x04c5, 0x04c5,
+	0x04c7, 0x04c7,
+	0x04c9, 0x04c9,
+	0x04cb, 0x04cb,
+	0x04cd, 0x04cd,
+	0x04d0, 0x04d0,
+	0x04d2, 0x04d2,
+	0x04d4, 0x04d4,
+	0x04d6, 0x04d6,
+	0x04d8, 0x04d8,
+	0x04da, 0x04da,
+	0x04dc, 0x04dc,
+	0x04de, 0x04de,
+	0x04e0, 0x04e0,
+	0x04e2, 0x04e2,
+	0x04e4, 0x04e4,
+	0x04e6, 0x04e6,
+	0x04e8, 0x04e8,
+	0x04ea, 0x04ea,
+	0x04ec, 0x04ec,
+	0x04ee, 0x04ee,
+	0x04f0, 0x04f0,
+	0x04f2, 0x04f2,
+	0x04f4, 0x04f4,
+	0x04f6, 0x04f6,
+	0x04f8, 0x04f8,
+	0x04fa, 0x04fa,
+	0x04fc, 0x04fc,
+	0x04fe, 0x04fe,
+	0x0500, 0x0500,
+	0x0502, 0x0502,
+	0x0504, 0x0504,
+	0x0506, 0x0506,
+	0x0508, 0x0508,
+	0x050a, 0x050a,
+	0x050c, 0x050c,
+	0x050e, 0x050e,
+	0x0510, 0x0510,
+	0x0512, 0x0512,
+	0x0514, 0x0514,
+	0x0516, 0x0516,
+	0x0518, 0x0518,
+	0x051a, 0x051a,
+	0x051c, 0x051c,
+	0x051e, 0x051e,
+	0x0520, 0x0520,
+	0x0522, 0x0522,
+	0x0524, 0x0524,
+	0x0526, 0x0526,
+	0x0528, 0x0528,
+	0x052a, 0x052a,
+	0x052c, 0x052c,
+	0x052e, 0x052e,
+	0x0531, 0x0556,
+	0x10a0, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x13a0, 0x13f5,
+	0x1e00, 0x1e00,
+	0x1e02, 0x1e02,
+	0x1e04, 0x1e04,
+	0x1e06, 0x1e06,
+	0x1e08, 0x1e08,
+	0x1e0a, 0x1e0a,
+	0x1e0c, 0x1e0c,
+	0x1e0e, 0x1e0e,
+	0x1e10, 0x1e10,
+	0x1e12, 0x1e12,
+	0x1e14, 0x1e14,
+	0x1e16, 0x1e16,
+	0x1e18, 0x1e18,
+	0x1e1a, 0x1e1a,
+	0x1e1c, 0x1e1c,
+	0x1e1e, 0x1e1e,
+	0x1e20, 0x1e20,
+	0x1e22, 0x1e22,
+	0x1e24, 0x1e24,
+	0x1e26, 0x1e26,
+	0x1e28, 0x1e28,
+	0x1e2a, 0x1e2a,
+	0x1e2c, 0x1e2c,
+	0x1e2e, 0x1e2e,
+	0x1e30, 0x1e30,
+	0x1e32, 0x1e32,
+	0x1e34, 0x1e34,
+	0x1e36, 0x1e36,
+	0x1e38, 0x1e38,
+	0x1e3a, 0x1e3a,
+	0x1e3c, 0x1e3c,
+	0x1e3e, 0x1e3e,
+	0x1e40, 0x1e40,
+	0x1e42, 0x1e42,
+	0x1e44, 0x1e44,
+	0x1e46, 0x1e46,
+	0x1e48, 0x1e48,
+	0x1e4a, 0x1e4a,
+	0x1e4c, 0x1e4c,
+	0x1e4e, 0x1e4e,
+	0x1e50, 0x1e50,
+	0x1e52, 0x1e52,
+	0x1e54, 0x1e54,
+	0x1e56, 0x1e56,
+	0x1e58, 0x1e58,
+	0x1e5a, 0x1e5a,
+	0x1e5c, 0x1e5c,
+	0x1e5e, 0x1e5e,
+	0x1e60, 0x1e60,
+	0x1e62, 0x1e62,
+	0x1e64, 0x1e64,
+	0x1e66, 0x1e66,
+	0x1e68, 0x1e68,
+	0x1e6a, 0x1e6a,
+	0x1e6c, 0x1e6c,
+	0x1e6e, 0x1e6e,
+	0x1e70, 0x1e70,
+	0x1e72, 0x1e72,
+	0x1e74, 0x1e74,
+	0x1e76, 0x1e76,
+	0x1e78, 0x1e78,
+	0x1e7a, 0x1e7a,
+	0x1e7c, 0x1e7c,
+	0x1e7e, 0x1e7e,
+	0x1e80, 0x1e80,
+	0x1e82, 0x1e82,
+	0x1e84, 0x1e84,
+	0x1e86, 0x1e86,
+	0x1e88, 0x1e88,
+	0x1e8a, 0x1e8a,
+	0x1e8c, 0x1e8c,
+	0x1e8e, 0x1e8e,
+	0x1e90, 0x1e90,
+	0x1e92, 0x1e92,
+	0x1e94, 0x1e94,
+	0x1e9e, 0x1e9e,
+	0x1ea0, 0x1ea0,
+	0x1ea2, 0x1ea2,
+	0x1ea4, 0x1ea4,
+	0x1ea6, 0x1ea6,
+	0x1ea8, 0x1ea8,
+	0x1eaa, 0x1eaa,
+	0x1eac, 0x1eac,
+	0x1eae, 0x1eae,
+	0x1eb0, 0x1eb0,
+	0x1eb2, 0x1eb2,
+	0x1eb4, 0x1eb4,
+	0x1eb6, 0x1eb6,
+	0x1eb8, 0x1eb8,
+	0x1eba, 0x1eba,
+	0x1ebc, 0x1ebc,
+	0x1ebe, 0x1ebe,
+	0x1ec0, 0x1ec0,
+	0x1ec2, 0x1ec2,
+	0x1ec4, 0x1ec4,
+	0x1ec6, 0x1ec6,
+	0x1ec8, 0x1ec8,
+	0x1eca, 0x1eca,
+	0x1ecc, 0x1ecc,
+	0x1ece, 0x1ece,
+	0x1ed0, 0x1ed0,
+	0x1ed2, 0x1ed2,
+	0x1ed4, 0x1ed4,
+	0x1ed6, 0x1ed6,
+	0x1ed8, 0x1ed8,
+	0x1eda, 0x1eda,
+	0x1edc, 0x1edc,
+	0x1ede, 0x1ede,
+	0x1ee0, 0x1ee0,
+	0x1ee2, 0x1ee2,
+	0x1ee4, 0x1ee4,
+	0x1ee6, 0x1ee6,
+	0x1ee8, 0x1ee8,
+	0x1eea, 0x1eea,
+	0x1eec, 0x1eec,
+	0x1eee, 0x1eee,
+	0x1ef0, 0x1ef0,
+	0x1ef2, 0x1ef2,
+	0x1ef4, 0x1ef4,
+	0x1ef6, 0x1ef6,
+	0x1ef8, 0x1ef8,
+	0x1efa, 0x1efa,
+	0x1efc, 0x1efc,
+	0x1efe, 0x1efe,
+	0x1f08, 0x1f0f,
+	0x1f18, 0x1f1d,
+	0x1f28, 0x1f2f,
+	0x1f38, 0x1f3f,
+	0x1f48, 0x1f4d,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f5f,
+	0x1f68, 0x1f6f,
+	0x1f88, 0x1f8f,
+	0x1f98, 0x1f9f,
+	0x1fa8, 0x1faf,
+	0x1fb8, 0x1fbc,
+	0x1fc8, 0x1fcc,
+	0x1fd8, 0x1fdb,
+	0x1fe8, 0x1fec,
+	0x1ff8, 0x1ffc,
+	0x2126, 0x2126,
+	0x212a, 0x212b,
+	0x2132, 0x2132,
+	0x2160, 0x216f,
+	0x2183, 0x2183,
+	0x24b6, 0x24cf,
+	0x2c00, 0x2c2e,
+	0x2c60, 0x2c60,
+	0x2c62, 0x2c64,
+	0x2c67, 0x2c67,
+	0x2c69, 0x2c69,
+	0x2c6b, 0x2c6b,
+	0x2c6d, 0x2c70,
+	0x2c72, 0x2c72,
+	0x2c75, 0x2c75,
+	0x2c7e, 0x2c80,
+	0x2c82, 0x2c82,
+	0x2c84, 0x2c84,
+	0x2c86, 0x2c86,
+	0x2c88, 0x2c88,
+	0x2c8a, 0x2c8a,
+	0x2c8c, 0x2c8c,
+	0x2c8e, 0x2c8e,
+	0x2c90, 0x2c90,
+	0x2c92, 0x2c92,
+	0x2c94, 0x2c94,
+	0x2c96, 0x2c96,
+	0x2c98, 0x2c98,
+	0x2c9a, 0x2c9a,
+	0x2c9c, 0x2c9c,
+	0x2c9e, 0x2c9e,
+	0x2ca0, 0x2ca0,
+	0x2ca2, 0x2ca2,
+	0x2ca4, 0x2ca4,
+	0x2ca6, 0x2ca6,
+	0x2ca8, 0x2ca8,
+	0x2caa, 0x2caa,
+	0x2cac, 0x2cac,
+	0x2cae, 0x2cae,
+	0x2cb0, 0x2cb0,
+	0x2cb2, 0x2cb2,
+	0x2cb4, 0x2cb4,
+	0x2cb6, 0x2cb6,
+	0x2cb8, 0x2cb8,
+	0x2cba, 0x2cba,
+	0x2cbc, 0x2cbc,
+	0x2cbe, 0x2cbe,
+	0x2cc0, 0x2cc0,
+	0x2cc2, 0x2cc2,
+	0x2cc4, 0x2cc4,
+	0x2cc6, 0x2cc6,
+	0x2cc8, 0x2cc8,
+	0x2cca, 0x2cca,
+	0x2ccc, 0x2ccc,
+	0x2cce, 0x2cce,
+	0x2cd0, 0x2cd0,
+	0x2cd2, 0x2cd2,
+	0x2cd4, 0x2cd4,
+	0x2cd6, 0x2cd6,
+	0x2cd8, 0x2cd8,
+	0x2cda, 0x2cda,
+	0x2cdc, 0x2cdc,
+	0x2cde, 0x2cde,
+	0x2ce0, 0x2ce0,
+	0x2ce2, 0x2ce2,
+	0x2ceb, 0x2ceb,
+	0x2ced, 0x2ced,
+	0x2cf2, 0x2cf2,
+	0xa640, 0xa640,
+	0xa642, 0xa642,
+	0xa644, 0xa644,
+	0xa646, 0xa646,
+	0xa648, 0xa648,
+	0xa64a, 0xa64a,
+	0xa64c, 0xa64c,
+	0xa64e, 0xa64e,
+	0xa650, 0xa650,
+	0xa652, 0xa652,
+	0xa654, 0xa654,
+	0xa656, 0xa656,
+	0xa658, 0xa658,
+	0xa65a, 0xa65a,
+	0xa65c, 0xa65c,
+	0xa65e, 0xa65e,
+	0xa660, 0xa660,
+	0xa662, 0xa662,
+	0xa664, 0xa664,
+	0xa666, 0xa666,
+	0xa668, 0xa668,
+	0xa66a, 0xa66a,
+	0xa66c, 0xa66c,
+	0xa680, 0xa680,
+	0xa682, 0xa682,
+	0xa684, 0xa684,
+	0xa686, 0xa686,
+	0xa688, 0xa688,
+	0xa68a, 0xa68a,
+	0xa68c, 0xa68c,
+	0xa68e, 0xa68e,
+	0xa690, 0xa690,
+	0xa692, 0xa692,
+	0xa694, 0xa694,
+	0xa696, 0xa696,
+	0xa698, 0xa698,
+	0xa69a, 0xa69a,
+	0xa722, 0xa722,
+	0xa724, 0xa724,
+	0xa726, 0xa726,
+	0xa728, 0xa728,
+	0xa72a, 0xa72a,
+	0xa72c, 0xa72c,
+	0xa72e, 0xa72e,
+	0xa732, 0xa732,
+	0xa734, 0xa734,
+	0xa736, 0xa736,
+	0xa738, 0xa738,
+	0xa73a, 0xa73a,
+	0xa73c, 0xa73c,
+	0xa73e, 0xa73e,
+	0xa740, 0xa740,
+	0xa742, 0xa742,
+	0xa744, 0xa744,
+	0xa746, 0xa746,
+	0xa748, 0xa748,
+	0xa74a, 0xa74a,
+	0xa74c, 0xa74c,
+	0xa74e, 0xa74e,
+	0xa750, 0xa750,
+	0xa752, 0xa752,
+	0xa754, 0xa754,
+	0xa756, 0xa756,
+	0xa758, 0xa758,
+	0xa75a, 0xa75a,
+	0xa75c, 0xa75c,
+	0xa75e, 0xa75e,
+	0xa760, 0xa760,
+	0xa762, 0xa762,
+	0xa764, 0xa764,
+	0xa766, 0xa766,
+	0xa768, 0xa768,
+	0xa76a, 0xa76a,
+	0xa76c, 0xa76c,
+	0xa76e, 0xa76e,
+	0xa779, 0xa779,
+	0xa77b, 0xa77b,
+	0xa77d, 0xa77e,
+	0xa780, 0xa780,
+	0xa782, 0xa782,
+	0xa784, 0xa784,
+	0xa786, 0xa786,
+	0xa78b, 0xa78b,
+	0xa78d, 0xa78d,
+	0xa790, 0xa790,
+	0xa792, 0xa792,
+	0xa796, 0xa796,
+	0xa798, 0xa798,
+	0xa79a, 0xa79a,
+	0xa79c, 0xa79c,
+	0xa79e, 0xa79e,
+	0xa7a0, 0xa7a0,
+	0xa7a2, 0xa7a2,
+	0xa7a4, 0xa7a4,
+	0xa7a6, 0xa7a6,
+	0xa7a8, 0xa7a8,
+	0xa7aa, 0xa7ae,
+	0xa7b0, 0xa7b4,
+	0xa7b6, 0xa7b6,
+	0xff21, 0xff3a,
+	0x10400, 0x10427,
+	0x104b0, 0x104d3,
+	0x10c80, 0x10cb2,
+	0x118a0, 0x118bf,
+	0x1e900, 0x1e921,
+}; /* CR_Changes_When_Lowercased */
+
+/* 'Changes_When_Uppercased': Derived Property */
+static const OnigCodePoint CR_Changes_When_Uppercased[] = {
+	607,
+	0x0061, 0x007a,
+	0x00b5, 0x00b5,
+	0x00df, 0x00f6,
+	0x00f8, 0x00ff,
+	0x0101, 0x0101,
+	0x0103, 0x0103,
+	0x0105, 0x0105,
+	0x0107, 0x0107,
+	0x0109, 0x0109,
+	0x010b, 0x010b,
+	0x010d, 0x010d,
+	0x010f, 0x010f,
+	0x0111, 0x0111,
+	0x0113, 0x0113,
+	0x0115, 0x0115,
+	0x0117, 0x0117,
+	0x0119, 0x0119,
+	0x011b, 0x011b,
+	0x011d, 0x011d,
+	0x011f, 0x011f,
+	0x0121, 0x0121,
+	0x0123, 0x0123,
+	0x0125, 0x0125,
+	0x0127, 0x0127,
+	0x0129, 0x0129,
+	0x012b, 0x012b,
+	0x012d, 0x012d,
+	0x012f, 0x012f,
+	0x0131, 0x0131,
+	0x0133, 0x0133,
+	0x0135, 0x0135,
+	0x0137, 0x0137,
+	0x013a, 0x013a,
+	0x013c, 0x013c,
+	0x013e, 0x013e,
+	0x0140, 0x0140,
+	0x0142, 0x0142,
+	0x0144, 0x0144,
+	0x0146, 0x0146,
+	0x0148, 0x0149,
+	0x014b, 0x014b,
+	0x014d, 0x014d,
+	0x014f, 0x014f,
+	0x0151, 0x0151,
+	0x0153, 0x0153,
+	0x0155, 0x0155,
+	0x0157, 0x0157,
+	0x0159, 0x0159,
+	0x015b, 0x015b,
+	0x015d, 0x015d,
+	0x015f, 0x015f,
+	0x0161, 0x0161,
+	0x0163, 0x0163,
+	0x0165, 0x0165,
+	0x0167, 0x0167,
+	0x0169, 0x0169,
+	0x016b, 0x016b,
+	0x016d, 0x016d,
+	0x016f, 0x016f,
+	0x0171, 0x0171,
+	0x0173, 0x0173,
+	0x0175, 0x0175,
+	0x0177, 0x0177,
+	0x017a, 0x017a,
+	0x017c, 0x017c,
+	0x017e, 0x0180,
+	0x0183, 0x0183,
+	0x0185, 0x0185,
+	0x0188, 0x0188,
+	0x018c, 0x018c,
+	0x0192, 0x0192,
+	0x0195, 0x0195,
+	0x0199, 0x019a,
+	0x019e, 0x019e,
+	0x01a1, 0x01a1,
+	0x01a3, 0x01a3,
+	0x01a5, 0x01a5,
+	0x01a8, 0x01a8,
+	0x01ad, 0x01ad,
+	0x01b0, 0x01b0,
+	0x01b4, 0x01b4,
+	0x01b6, 0x01b6,
+	0x01b9, 0x01b9,
+	0x01bd, 0x01bd,
+	0x01bf, 0x01bf,
+	0x01c5, 0x01c6,
+	0x01c8, 0x01c9,
+	0x01cb, 0x01cc,
+	0x01ce, 0x01ce,
+	0x01d0, 0x01d0,
+	0x01d2, 0x01d2,
+	0x01d4, 0x01d4,
+	0x01d6, 0x01d6,
+	0x01d8, 0x01d8,
+	0x01da, 0x01da,
+	0x01dc, 0x01dd,
+	0x01df, 0x01df,
+	0x01e1, 0x01e1,
+	0x01e3, 0x01e3,
+	0x01e5, 0x01e5,
+	0x01e7, 0x01e7,
+	0x01e9, 0x01e9,
+	0x01eb, 0x01eb,
+	0x01ed, 0x01ed,
+	0x01ef, 0x01f0,
+	0x01f2, 0x01f3,
+	0x01f5, 0x01f5,
+	0x01f9, 0x01f9,
+	0x01fb, 0x01fb,
+	0x01fd, 0x01fd,
+	0x01ff, 0x01ff,
+	0x0201, 0x0201,
+	0x0203, 0x0203,
+	0x0205, 0x0205,
+	0x0207, 0x0207,
+	0x0209, 0x0209,
+	0x020b, 0x020b,
+	0x020d, 0x020d,
+	0x020f, 0x020f,
+	0x0211, 0x0211,
+	0x0213, 0x0213,
+	0x0215, 0x0215,
+	0x0217, 0x0217,
+	0x0219, 0x0219,
+	0x021b, 0x021b,
+	0x021d, 0x021d,
+	0x021f, 0x021f,
+	0x0223, 0x0223,
+	0x0225, 0x0225,
+	0x0227, 0x0227,
+	0x0229, 0x0229,
+	0x022b, 0x022b,
+	0x022d, 0x022d,
+	0x022f, 0x022f,
+	0x0231, 0x0231,
+	0x0233, 0x0233,
+	0x023c, 0x023c,
+	0x023f, 0x0240,
+	0x0242, 0x0242,
+	0x0247, 0x0247,
+	0x0249, 0x0249,
+	0x024b, 0x024b,
+	0x024d, 0x024d,
+	0x024f, 0x0254,
+	0x0256, 0x0257,
+	0x0259, 0x0259,
+	0x025b, 0x025c,
+	0x0260, 0x0261,
+	0x0263, 0x0263,
+	0x0265, 0x0266,
+	0x0268, 0x026c,
+	0x026f, 0x026f,
+	0x0271, 0x0272,
+	0x0275, 0x0275,
+	0x027d, 0x027d,
+	0x0280, 0x0280,
+	0x0283, 0x0283,
+	0x0287, 0x028c,
+	0x0292, 0x0292,
+	0x029d, 0x029e,
+	0x0345, 0x0345,
+	0x0371, 0x0371,
+	0x0373, 0x0373,
+	0x0377, 0x0377,
+	0x037b, 0x037d,
+	0x0390, 0x0390,
+	0x03ac, 0x03ce,
+	0x03d0, 0x03d1,
+	0x03d5, 0x03d7,
+	0x03d9, 0x03d9,
+	0x03db, 0x03db,
+	0x03dd, 0x03dd,
+	0x03df, 0x03df,
+	0x03e1, 0x03e1,
+	0x03e3, 0x03e3,
+	0x03e5, 0x03e5,
+	0x03e7, 0x03e7,
+	0x03e9, 0x03e9,
+	0x03eb, 0x03eb,
+	0x03ed, 0x03ed,
+	0x03ef, 0x03f3,
+	0x03f5, 0x03f5,
+	0x03f8, 0x03f8,
+	0x03fb, 0x03fb,
+	0x0430, 0x045f,
+	0x0461, 0x0461,
+	0x0463, 0x0463,
+	0x0465, 0x0465,
+	0x0467, 0x0467,
+	0x0469, 0x0469,
+	0x046b, 0x046b,
+	0x046d, 0x046d,
+	0x046f, 0x046f,
+	0x0471, 0x0471,
+	0x0473, 0x0473,
+	0x0475, 0x0475,
+	0x0477, 0x0477,
+	0x0479, 0x0479,
+	0x047b, 0x047b,
+	0x047d, 0x047d,
+	0x047f, 0x047f,
+	0x0481, 0x0481,
+	0x048b, 0x048b,
+	0x048d, 0x048d,
+	0x048f, 0x048f,
+	0x0491, 0x0491,
+	0x0493, 0x0493,
+	0x0495, 0x0495,
+	0x0497, 0x0497,
+	0x0499, 0x0499,
+	0x049b, 0x049b,
+	0x049d, 0x049d,
+	0x049f, 0x049f,
+	0x04a1, 0x04a1,
+	0x04a3, 0x04a3,
+	0x04a5, 0x04a5,
+	0x04a7, 0x04a7,
+	0x04a9, 0x04a9,
+	0x04ab, 0x04ab,
+	0x04ad, 0x04ad,
+	0x04af, 0x04af,
+	0x04b1, 0x04b1,
+	0x04b3, 0x04b3,
+	0x04b5, 0x04b5,
+	0x04b7, 0x04b7,
+	0x04b9, 0x04b9,
+	0x04bb, 0x04bb,
+	0x04bd, 0x04bd,
+	0x04bf, 0x04bf,
+	0x04c2, 0x04c2,
+	0x04c4, 0x04c4,
+	0x04c6, 0x04c6,
+	0x04c8, 0x04c8,
+	0x04ca, 0x04ca,
+	0x04cc, 0x04cc,
+	0x04ce, 0x04cf,
+	0x04d1, 0x04d1,
+	0x04d3, 0x04d3,
+	0x04d5, 0x04d5,
+	0x04d7, 0x04d7,
+	0x04d9, 0x04d9,
+	0x04db, 0x04db,
+	0x04dd, 0x04dd,
+	0x04df, 0x04df,
+	0x04e1, 0x04e1,
+	0x04e3, 0x04e3,
+	0x04e5, 0x04e5,
+	0x04e7, 0x04e7,
+	0x04e9, 0x04e9,
+	0x04eb, 0x04eb,
+	0x04ed, 0x04ed,
+	0x04ef, 0x04ef,
+	0x04f1, 0x04f1,
+	0x04f3, 0x04f3,
+	0x04f5, 0x04f5,
+	0x04f7, 0x04f7,
+	0x04f9, 0x04f9,
+	0x04fb, 0x04fb,
+	0x04fd, 0x04fd,
+	0x04ff, 0x04ff,
+	0x0501, 0x0501,
+	0x0503, 0x0503,
+	0x0505, 0x0505,
+	0x0507, 0x0507,
+	0x0509, 0x0509,
+	0x050b, 0x050b,
+	0x050d, 0x050d,
+	0x050f, 0x050f,
+	0x0511, 0x0511,
+	0x0513, 0x0513,
+	0x0515, 0x0515,
+	0x0517, 0x0517,
+	0x0519, 0x0519,
+	0x051b, 0x051b,
+	0x051d, 0x051d,
+	0x051f, 0x051f,
+	0x0521, 0x0521,
+	0x0523, 0x0523,
+	0x0525, 0x0525,
+	0x0527, 0x0527,
+	0x0529, 0x0529,
+	0x052b, 0x052b,
+	0x052d, 0x052d,
+	0x052f, 0x052f,
+	0x0561, 0x0587,
+	0x13f8, 0x13fd,
+	0x1c80, 0x1c88,
+	0x1d79, 0x1d79,
+	0x1d7d, 0x1d7d,
+	0x1e01, 0x1e01,
+	0x1e03, 0x1e03,
+	0x1e05, 0x1e05,
+	0x1e07, 0x1e07,
+	0x1e09, 0x1e09,
+	0x1e0b, 0x1e0b,
+	0x1e0d, 0x1e0d,
+	0x1e0f, 0x1e0f,
+	0x1e11, 0x1e11,
+	0x1e13, 0x1e13,
+	0x1e15, 0x1e15,
+	0x1e17, 0x1e17,
+	0x1e19, 0x1e19,
+	0x1e1b, 0x1e1b,
+	0x1e1d, 0x1e1d,
+	0x1e1f, 0x1e1f,
+	0x1e21, 0x1e21,
+	0x1e23, 0x1e23,
+	0x1e25, 0x1e25,
+	0x1e27, 0x1e27,
+	0x1e29, 0x1e29,
+	0x1e2b, 0x1e2b,
+	0x1e2d, 0x1e2d,
+	0x1e2f, 0x1e2f,
+	0x1e31, 0x1e31,
+	0x1e33, 0x1e33,
+	0x1e35, 0x1e35,
+	0x1e37, 0x1e37,
+	0x1e39, 0x1e39,
+	0x1e3b, 0x1e3b,
+	0x1e3d, 0x1e3d,
+	0x1e3f, 0x1e3f,
+	0x1e41, 0x1e41,
+	0x1e43, 0x1e43,
+	0x1e45, 0x1e45,
+	0x1e47, 0x1e47,
+	0x1e49, 0x1e49,
+	0x1e4b, 0x1e4b,
+	0x1e4d, 0x1e4d,
+	0x1e4f, 0x1e4f,
+	0x1e51, 0x1e51,
+	0x1e53, 0x1e53,
+	0x1e55, 0x1e55,
+	0x1e57, 0x1e57,
+	0x1e59, 0x1e59,
+	0x1e5b, 0x1e5b,
+	0x1e5d, 0x1e5d,
+	0x1e5f, 0x1e5f,
+	0x1e61, 0x1e61,
+	0x1e63, 0x1e63,
+	0x1e65, 0x1e65,
+	0x1e67, 0x1e67,
+	0x1e69, 0x1e69,
+	0x1e6b, 0x1e6b,
+	0x1e6d, 0x1e6d,
+	0x1e6f, 0x1e6f,
+	0x1e71, 0x1e71,
+	0x1e73, 0x1e73,
+	0x1e75, 0x1e75,
+	0x1e77, 0x1e77,
+	0x1e79, 0x1e79,
+	0x1e7b, 0x1e7b,
+	0x1e7d, 0x1e7d,
+	0x1e7f, 0x1e7f,
+	0x1e81, 0x1e81,
+	0x1e83, 0x1e83,
+	0x1e85, 0x1e85,
+	0x1e87, 0x1e87,
+	0x1e89, 0x1e89,
+	0x1e8b, 0x1e8b,
+	0x1e8d, 0x1e8d,
+	0x1e8f, 0x1e8f,
+	0x1e91, 0x1e91,
+	0x1e93, 0x1e93,
+	0x1e95, 0x1e9b,
+	0x1ea1, 0x1ea1,
+	0x1ea3, 0x1ea3,
+	0x1ea5, 0x1ea5,
+	0x1ea7, 0x1ea7,
+	0x1ea9, 0x1ea9,
+	0x1eab, 0x1eab,
+	0x1ead, 0x1ead,
+	0x1eaf, 0x1eaf,
+	0x1eb1, 0x1eb1,
+	0x1eb3, 0x1eb3,
+	0x1eb5, 0x1eb5,
+	0x1eb7, 0x1eb7,
+	0x1eb9, 0x1eb9,
+	0x1ebb, 0x1ebb,
+	0x1ebd, 0x1ebd,
+	0x1ebf, 0x1ebf,
+	0x1ec1, 0x1ec1,
+	0x1ec3, 0x1ec3,
+	0x1ec5, 0x1ec5,
+	0x1ec7, 0x1ec7,
+	0x1ec9, 0x1ec9,
+	0x1ecb, 0x1ecb,
+	0x1ecd, 0x1ecd,
+	0x1ecf, 0x1ecf,
+	0x1ed1, 0x1ed1,
+	0x1ed3, 0x1ed3,
+	0x1ed5, 0x1ed5,
+	0x1ed7, 0x1ed7,
+	0x1ed9, 0x1ed9,
+	0x1edb, 0x1edb,
+	0x1edd, 0x1edd,
+	0x1edf, 0x1edf,
+	0x1ee1, 0x1ee1,
+	0x1ee3, 0x1ee3,
+	0x1ee5, 0x1ee5,
+	0x1ee7, 0x1ee7,
+	0x1ee9, 0x1ee9,
+	0x1eeb, 0x1eeb,
+	0x1eed, 0x1eed,
+	0x1eef, 0x1eef,
+	0x1ef1, 0x1ef1,
+	0x1ef3, 0x1ef3,
+	0x1ef5, 0x1ef5,
+	0x1ef7, 0x1ef7,
+	0x1ef9, 0x1ef9,
+	0x1efb, 0x1efb,
+	0x1efd, 0x1efd,
+	0x1eff, 0x1f07,
+	0x1f10, 0x1f15,
+	0x1f20, 0x1f27,
+	0x1f30, 0x1f37,
+	0x1f40, 0x1f45,
+	0x1f50, 0x1f57,
+	0x1f60, 0x1f67,
+	0x1f70, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fb7,
+	0x1fbc, 0x1fbc,
+	0x1fbe, 0x1fbe,
+	0x1fc2, 0x1fc4,
+	0x1fc6, 0x1fc7,
+	0x1fcc, 0x1fcc,
+	0x1fd0, 0x1fd3,
+	0x1fd6, 0x1fd7,
+	0x1fe0, 0x1fe7,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ff7,
+	0x1ffc, 0x1ffc,
+	0x214e, 0x214e,
+	0x2170, 0x217f,
+	0x2184, 0x2184,
+	0x24d0, 0x24e9,
+	0x2c30, 0x2c5e,
+	0x2c61, 0x2c61,
+	0x2c65, 0x2c66,
+	0x2c68, 0x2c68,
+	0x2c6a, 0x2c6a,
+	0x2c6c, 0x2c6c,
+	0x2c73, 0x2c73,
+	0x2c76, 0x2c76,
+	0x2c81, 0x2c81,
+	0x2c83, 0x2c83,
+	0x2c85, 0x2c85,
+	0x2c87, 0x2c87,
+	0x2c89, 0x2c89,
+	0x2c8b, 0x2c8b,
+	0x2c8d, 0x2c8d,
+	0x2c8f, 0x2c8f,
+	0x2c91, 0x2c91,
+	0x2c93, 0x2c93,
+	0x2c95, 0x2c95,
+	0x2c97, 0x2c97,
+	0x2c99, 0x2c99,
+	0x2c9b, 0x2c9b,
+	0x2c9d, 0x2c9d,
+	0x2c9f, 0x2c9f,
+	0x2ca1, 0x2ca1,
+	0x2ca3, 0x2ca3,
+	0x2ca5, 0x2ca5,
+	0x2ca7, 0x2ca7,
+	0x2ca9, 0x2ca9,
+	0x2cab, 0x2cab,
+	0x2cad, 0x2cad,
+	0x2caf, 0x2caf,
+	0x2cb1, 0x2cb1,
+	0x2cb3, 0x2cb3,
+	0x2cb5, 0x2cb5,
+	0x2cb7, 0x2cb7,
+	0x2cb9, 0x2cb9,
+	0x2cbb, 0x2cbb,
+	0x2cbd, 0x2cbd,
+	0x2cbf, 0x2cbf,
+	0x2cc1, 0x2cc1,
+	0x2cc3, 0x2cc3,
+	0x2cc5, 0x2cc5,
+	0x2cc7, 0x2cc7,
+	0x2cc9, 0x2cc9,
+	0x2ccb, 0x2ccb,
+	0x2ccd, 0x2ccd,
+	0x2ccf, 0x2ccf,
+	0x2cd1, 0x2cd1,
+	0x2cd3, 0x2cd3,
+	0x2cd5, 0x2cd5,
+	0x2cd7, 0x2cd7,
+	0x2cd9, 0x2cd9,
+	0x2cdb, 0x2cdb,
+	0x2cdd, 0x2cdd,
+	0x2cdf, 0x2cdf,
+	0x2ce1, 0x2ce1,
+	0x2ce3, 0x2ce3,
+	0x2cec, 0x2cec,
+	0x2cee, 0x2cee,
+	0x2cf3, 0x2cf3,
+	0x2d00, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0xa641, 0xa641,
+	0xa643, 0xa643,
+	0xa645, 0xa645,
+	0xa647, 0xa647,
+	0xa649, 0xa649,
+	0xa64b, 0xa64b,
+	0xa64d, 0xa64d,
+	0xa64f, 0xa64f,
+	0xa651, 0xa651,
+	0xa653, 0xa653,
+	0xa655, 0xa655,
+	0xa657, 0xa657,
+	0xa659, 0xa659,
+	0xa65b, 0xa65b,
+	0xa65d, 0xa65d,
+	0xa65f, 0xa65f,
+	0xa661, 0xa661,
+	0xa663, 0xa663,
+	0xa665, 0xa665,
+	0xa667, 0xa667,
+	0xa669, 0xa669,
+	0xa66b, 0xa66b,
+	0xa66d, 0xa66d,
+	0xa681, 0xa681,
+	0xa683, 0xa683,
+	0xa685, 0xa685,
+	0xa687, 0xa687,
+	0xa689, 0xa689,
+	0xa68b, 0xa68b,
+	0xa68d, 0xa68d,
+	0xa68f, 0xa68f,
+	0xa691, 0xa691,
+	0xa693, 0xa693,
+	0xa695, 0xa695,
+	0xa697, 0xa697,
+	0xa699, 0xa699,
+	0xa69b, 0xa69b,
+	0xa723, 0xa723,
+	0xa725, 0xa725,
+	0xa727, 0xa727,
+	0xa729, 0xa729,
+	0xa72b, 0xa72b,
+	0xa72d, 0xa72d,
+	0xa72f, 0xa72f,
+	0xa733, 0xa733,
+	0xa735, 0xa735,
+	0xa737, 0xa737,
+	0xa739, 0xa739,
+	0xa73b, 0xa73b,
+	0xa73d, 0xa73d,
+	0xa73f, 0xa73f,
+	0xa741, 0xa741,
+	0xa743, 0xa743,
+	0xa745, 0xa745,
+	0xa747, 0xa747,
+	0xa749, 0xa749,
+	0xa74b, 0xa74b,
+	0xa74d, 0xa74d,
+	0xa74f, 0xa74f,
+	0xa751, 0xa751,
+	0xa753, 0xa753,
+	0xa755, 0xa755,
+	0xa757, 0xa757,
+	0xa759, 0xa759,
+	0xa75b, 0xa75b,
+	0xa75d, 0xa75d,
+	0xa75f, 0xa75f,
+	0xa761, 0xa761,
+	0xa763, 0xa763,
+	0xa765, 0xa765,
+	0xa767, 0xa767,
+	0xa769, 0xa769,
+	0xa76b, 0xa76b,
+	0xa76d, 0xa76d,
+	0xa76f, 0xa76f,
+	0xa77a, 0xa77a,
+	0xa77c, 0xa77c,
+	0xa77f, 0xa77f,
+	0xa781, 0xa781,
+	0xa783, 0xa783,
+	0xa785, 0xa785,
+	0xa787, 0xa787,
+	0xa78c, 0xa78c,
+	0xa791, 0xa791,
+	0xa793, 0xa793,
+	0xa797, 0xa797,
+	0xa799, 0xa799,
+	0xa79b, 0xa79b,
+	0xa79d, 0xa79d,
+	0xa79f, 0xa79f,
+	0xa7a1, 0xa7a1,
+	0xa7a3, 0xa7a3,
+	0xa7a5, 0xa7a5,
+	0xa7a7, 0xa7a7,
+	0xa7a9, 0xa7a9,
+	0xa7b5, 0xa7b5,
+	0xa7b7, 0xa7b7,
+	0xab53, 0xab53,
+	0xab70, 0xabbf,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xff41, 0xff5a,
+	0x10428, 0x1044f,
+	0x104d8, 0x104fb,
+	0x10cc0, 0x10cf2,
+	0x118c0, 0x118df,
+	0x1e922, 0x1e943,
+}; /* CR_Changes_When_Uppercased */
+
+/* 'Changes_When_Titlecased': Derived Property */
+static const OnigCodePoint CR_Changes_When_Titlecased[] = {
+	608,
+	0x0061, 0x007a,
+	0x00b5, 0x00b5,
+	0x00df, 0x00f6,
+	0x00f8, 0x00ff,
+	0x0101, 0x0101,
+	0x0103, 0x0103,
+	0x0105, 0x0105,
+	0x0107, 0x0107,
+	0x0109, 0x0109,
+	0x010b, 0x010b,
+	0x010d, 0x010d,
+	0x010f, 0x010f,
+	0x0111, 0x0111,
+	0x0113, 0x0113,
+	0x0115, 0x0115,
+	0x0117, 0x0117,
+	0x0119, 0x0119,
+	0x011b, 0x011b,
+	0x011d, 0x011d,
+	0x011f, 0x011f,
+	0x0121, 0x0121,
+	0x0123, 0x0123,
+	0x0125, 0x0125,
+	0x0127, 0x0127,
+	0x0129, 0x0129,
+	0x012b, 0x012b,
+	0x012d, 0x012d,
+	0x012f, 0x012f,
+	0x0131, 0x0131,
+	0x0133, 0x0133,
+	0x0135, 0x0135,
+	0x0137, 0x0137,
+	0x013a, 0x013a,
+	0x013c, 0x013c,
+	0x013e, 0x013e,
+	0x0140, 0x0140,
+	0x0142, 0x0142,
+	0x0144, 0x0144,
+	0x0146, 0x0146,
+	0x0148, 0x0149,
+	0x014b, 0x014b,
+	0x014d, 0x014d,
+	0x014f, 0x014f,
+	0x0151, 0x0151,
+	0x0153, 0x0153,
+	0x0155, 0x0155,
+	0x0157, 0x0157,
+	0x0159, 0x0159,
+	0x015b, 0x015b,
+	0x015d, 0x015d,
+	0x015f, 0x015f,
+	0x0161, 0x0161,
+	0x0163, 0x0163,
+	0x0165, 0x0165,
+	0x0167, 0x0167,
+	0x0169, 0x0169,
+	0x016b, 0x016b,
+	0x016d, 0x016d,
+	0x016f, 0x016f,
+	0x0171, 0x0171,
+	0x0173, 0x0173,
+	0x0175, 0x0175,
+	0x0177, 0x0177,
+	0x017a, 0x017a,
+	0x017c, 0x017c,
+	0x017e, 0x0180,
+	0x0183, 0x0183,
+	0x0185, 0x0185,
+	0x0188, 0x0188,
+	0x018c, 0x018c,
+	0x0192, 0x0192,
+	0x0195, 0x0195,
+	0x0199, 0x019a,
+	0x019e, 0x019e,
+	0x01a1, 0x01a1,
+	0x01a3, 0x01a3,
+	0x01a5, 0x01a5,
+	0x01a8, 0x01a8,
+	0x01ad, 0x01ad,
+	0x01b0, 0x01b0,
+	0x01b4, 0x01b4,
+	0x01b6, 0x01b6,
+	0x01b9, 0x01b9,
+	0x01bd, 0x01bd,
+	0x01bf, 0x01bf,
+	0x01c4, 0x01c4,
+	0x01c6, 0x01c7,
+	0x01c9, 0x01ca,
+	0x01cc, 0x01cc,
+	0x01ce, 0x01ce,
+	0x01d0, 0x01d0,
+	0x01d2, 0x01d2,
+	0x01d4, 0x01d4,
+	0x01d6, 0x01d6,
+	0x01d8, 0x01d8,
+	0x01da, 0x01da,
+	0x01dc, 0x01dd,
+	0x01df, 0x01df,
+	0x01e1, 0x01e1,
+	0x01e3, 0x01e3,
+	0x01e5, 0x01e5,
+	0x01e7, 0x01e7,
+	0x01e9, 0x01e9,
+	0x01eb, 0x01eb,
+	0x01ed, 0x01ed,
+	0x01ef, 0x01f1,
+	0x01f3, 0x01f3,
+	0x01f5, 0x01f5,
+	0x01f9, 0x01f9,
+	0x01fb, 0x01fb,
+	0x01fd, 0x01fd,
+	0x01ff, 0x01ff,
+	0x0201, 0x0201,
+	0x0203, 0x0203,
+	0x0205, 0x0205,
+	0x0207, 0x0207,
+	0x0209, 0x0209,
+	0x020b, 0x020b,
+	0x020d, 0x020d,
+	0x020f, 0x020f,
+	0x0211, 0x0211,
+	0x0213, 0x0213,
+	0x0215, 0x0215,
+	0x0217, 0x0217,
+	0x0219, 0x0219,
+	0x021b, 0x021b,
+	0x021d, 0x021d,
+	0x021f, 0x021f,
+	0x0223, 0x0223,
+	0x0225, 0x0225,
+	0x0227, 0x0227,
+	0x0229, 0x0229,
+	0x022b, 0x022b,
+	0x022d, 0x022d,
+	0x022f, 0x022f,
+	0x0231, 0x0231,
+	0x0233, 0x0233,
+	0x023c, 0x023c,
+	0x023f, 0x0240,
+	0x0242, 0x0242,
+	0x0247, 0x0247,
+	0x0249, 0x0249,
+	0x024b, 0x024b,
+	0x024d, 0x024d,
+	0x024f, 0x0254,
+	0x0256, 0x0257,
+	0x0259, 0x0259,
+	0x025b, 0x025c,
+	0x0260, 0x0261,
+	0x0263, 0x0263,
+	0x0265, 0x0266,
+	0x0268, 0x026c,
+	0x026f, 0x026f,
+	0x0271, 0x0272,
+	0x0275, 0x0275,
+	0x027d, 0x027d,
+	0x0280, 0x0280,
+	0x0283, 0x0283,
+	0x0287, 0x028c,
+	0x0292, 0x0292,
+	0x029d, 0x029e,
+	0x0345, 0x0345,
+	0x0371, 0x0371,
+	0x0373, 0x0373,
+	0x0377, 0x0377,
+	0x037b, 0x037d,
+	0x0390, 0x0390,
+	0x03ac, 0x03ce,
+	0x03d0, 0x03d1,
+	0x03d5, 0x03d7,
+	0x03d9, 0x03d9,
+	0x03db, 0x03db,
+	0x03dd, 0x03dd,
+	0x03df, 0x03df,
+	0x03e1, 0x03e1,
+	0x03e3, 0x03e3,
+	0x03e5, 0x03e5,
+	0x03e7, 0x03e7,
+	0x03e9, 0x03e9,
+	0x03eb, 0x03eb,
+	0x03ed, 0x03ed,
+	0x03ef, 0x03f3,
+	0x03f5, 0x03f5,
+	0x03f8, 0x03f8,
+	0x03fb, 0x03fb,
+	0x0430, 0x045f,
+	0x0461, 0x0461,
+	0x0463, 0x0463,
+	0x0465, 0x0465,
+	0x0467, 0x0467,
+	0x0469, 0x0469,
+	0x046b, 0x046b,
+	0x046d, 0x046d,
+	0x046f, 0x046f,
+	0x0471, 0x0471,
+	0x0473, 0x0473,
+	0x0475, 0x0475,
+	0x0477, 0x0477,
+	0x0479, 0x0479,
+	0x047b, 0x047b,
+	0x047d, 0x047d,
+	0x047f, 0x047f,
+	0x0481, 0x0481,
+	0x048b, 0x048b,
+	0x048d, 0x048d,
+	0x048f, 0x048f,
+	0x0491, 0x0491,
+	0x0493, 0x0493,
+	0x0495, 0x0495,
+	0x0497, 0x0497,
+	0x0499, 0x0499,
+	0x049b, 0x049b,
+	0x049d, 0x049d,
+	0x049f, 0x049f,
+	0x04a1, 0x04a1,
+	0x04a3, 0x04a3,
+	0x04a5, 0x04a5,
+	0x04a7, 0x04a7,
+	0x04a9, 0x04a9,
+	0x04ab, 0x04ab,
+	0x04ad, 0x04ad,
+	0x04af, 0x04af,
+	0x04b1, 0x04b1,
+	0x04b3, 0x04b3,
+	0x04b5, 0x04b5,
+	0x04b7, 0x04b7,
+	0x04b9, 0x04b9,
+	0x04bb, 0x04bb,
+	0x04bd, 0x04bd,
+	0x04bf, 0x04bf,
+	0x04c2, 0x04c2,
+	0x04c4, 0x04c4,
+	0x04c6, 0x04c6,
+	0x04c8, 0x04c8,
+	0x04ca, 0x04ca,
+	0x04cc, 0x04cc,
+	0x04ce, 0x04cf,
+	0x04d1, 0x04d1,
+	0x04d3, 0x04d3,
+	0x04d5, 0x04d5,
+	0x04d7, 0x04d7,
+	0x04d9, 0x04d9,
+	0x04db, 0x04db,
+	0x04dd, 0x04dd,
+	0x04df, 0x04df,
+	0x04e1, 0x04e1,
+	0x04e3, 0x04e3,
+	0x04e5, 0x04e5,
+	0x04e7, 0x04e7,
+	0x04e9, 0x04e9,
+	0x04eb, 0x04eb,
+	0x04ed, 0x04ed,
+	0x04ef, 0x04ef,
+	0x04f1, 0x04f1,
+	0x04f3, 0x04f3,
+	0x04f5, 0x04f5,
+	0x04f7, 0x04f7,
+	0x04f9, 0x04f9,
+	0x04fb, 0x04fb,
+	0x04fd, 0x04fd,
+	0x04ff, 0x04ff,
+	0x0501, 0x0501,
+	0x0503, 0x0503,
+	0x0505, 0x0505,
+	0x0507, 0x0507,
+	0x0509, 0x0509,
+	0x050b, 0x050b,
+	0x050d, 0x050d,
+	0x050f, 0x050f,
+	0x0511, 0x0511,
+	0x0513, 0x0513,
+	0x0515, 0x0515,
+	0x0517, 0x0517,
+	0x0519, 0x0519,
+	0x051b, 0x051b,
+	0x051d, 0x051d,
+	0x051f, 0x051f,
+	0x0521, 0x0521,
+	0x0523, 0x0523,
+	0x0525, 0x0525,
+	0x0527, 0x0527,
+	0x0529, 0x0529,
+	0x052b, 0x052b,
+	0x052d, 0x052d,
+	0x052f, 0x052f,
+	0x0561, 0x0587,
+	0x13f8, 0x13fd,
+	0x1c80, 0x1c88,
+	0x1d79, 0x1d79,
+	0x1d7d, 0x1d7d,
+	0x1e01, 0x1e01,
+	0x1e03, 0x1e03,
+	0x1e05, 0x1e05,
+	0x1e07, 0x1e07,
+	0x1e09, 0x1e09,
+	0x1e0b, 0x1e0b,
+	0x1e0d, 0x1e0d,
+	0x1e0f, 0x1e0f,
+	0x1e11, 0x1e11,
+	0x1e13, 0x1e13,
+	0x1e15, 0x1e15,
+	0x1e17, 0x1e17,
+	0x1e19, 0x1e19,
+	0x1e1b, 0x1e1b,
+	0x1e1d, 0x1e1d,
+	0x1e1f, 0x1e1f,
+	0x1e21, 0x1e21,
+	0x1e23, 0x1e23,
+	0x1e25, 0x1e25,
+	0x1e27, 0x1e27,
+	0x1e29, 0x1e29,
+	0x1e2b, 0x1e2b,
+	0x1e2d, 0x1e2d,
+	0x1e2f, 0x1e2f,
+	0x1e31, 0x1e31,
+	0x1e33, 0x1e33,
+	0x1e35, 0x1e35,
+	0x1e37, 0x1e37,
+	0x1e39, 0x1e39,
+	0x1e3b, 0x1e3b,
+	0x1e3d, 0x1e3d,
+	0x1e3f, 0x1e3f,
+	0x1e41, 0x1e41,
+	0x1e43, 0x1e43,
+	0x1e45, 0x1e45,
+	0x1e47, 0x1e47,
+	0x1e49, 0x1e49,
+	0x1e4b, 0x1e4b,
+	0x1e4d, 0x1e4d,
+	0x1e4f, 0x1e4f,
+	0x1e51, 0x1e51,
+	0x1e53, 0x1e53,
+	0x1e55, 0x1e55,
+	0x1e57, 0x1e57,
+	0x1e59, 0x1e59,
+	0x1e5b, 0x1e5b,
+	0x1e5d, 0x1e5d,
+	0x1e5f, 0x1e5f,
+	0x1e61, 0x1e61,
+	0x1e63, 0x1e63,
+	0x1e65, 0x1e65,
+	0x1e67, 0x1e67,
+	0x1e69, 0x1e69,
+	0x1e6b, 0x1e6b,
+	0x1e6d, 0x1e6d,
+	0x1e6f, 0x1e6f,
+	0x1e71, 0x1e71,
+	0x1e73, 0x1e73,
+	0x1e75, 0x1e75,
+	0x1e77, 0x1e77,
+	0x1e79, 0x1e79,
+	0x1e7b, 0x1e7b,
+	0x1e7d, 0x1e7d,
+	0x1e7f, 0x1e7f,
+	0x1e81, 0x1e81,
+	0x1e83, 0x1e83,
+	0x1e85, 0x1e85,
+	0x1e87, 0x1e87,
+	0x1e89, 0x1e89,
+	0x1e8b, 0x1e8b,
+	0x1e8d, 0x1e8d,
+	0x1e8f, 0x1e8f,
+	0x1e91, 0x1e91,
+	0x1e93, 0x1e93,
+	0x1e95, 0x1e9b,
+	0x1ea1, 0x1ea1,
+	0x1ea3, 0x1ea3,
+	0x1ea5, 0x1ea5,
+	0x1ea7, 0x1ea7,
+	0x1ea9, 0x1ea9,
+	0x1eab, 0x1eab,
+	0x1ead, 0x1ead,
+	0x1eaf, 0x1eaf,
+	0x1eb1, 0x1eb1,
+	0x1eb3, 0x1eb3,
+	0x1eb5, 0x1eb5,
+	0x1eb7, 0x1eb7,
+	0x1eb9, 0x1eb9,
+	0x1ebb, 0x1ebb,
+	0x1ebd, 0x1ebd,
+	0x1ebf, 0x1ebf,
+	0x1ec1, 0x1ec1,
+	0x1ec3, 0x1ec3,
+	0x1ec5, 0x1ec5,
+	0x1ec7, 0x1ec7,
+	0x1ec9, 0x1ec9,
+	0x1ecb, 0x1ecb,
+	0x1ecd, 0x1ecd,
+	0x1ecf, 0x1ecf,
+	0x1ed1, 0x1ed1,
+	0x1ed3, 0x1ed3,
+	0x1ed5, 0x1ed5,
+	0x1ed7, 0x1ed7,
+	0x1ed9, 0x1ed9,
+	0x1edb, 0x1edb,
+	0x1edd, 0x1edd,
+	0x1edf, 0x1edf,
+	0x1ee1, 0x1ee1,
+	0x1ee3, 0x1ee3,
+	0x1ee5, 0x1ee5,
+	0x1ee7, 0x1ee7,
+	0x1ee9, 0x1ee9,
+	0x1eeb, 0x1eeb,
+	0x1eed, 0x1eed,
+	0x1eef, 0x1eef,
+	0x1ef1, 0x1ef1,
+	0x1ef3, 0x1ef3,
+	0x1ef5, 0x1ef5,
+	0x1ef7, 0x1ef7,
+	0x1ef9, 0x1ef9,
+	0x1efb, 0x1efb,
+	0x1efd, 0x1efd,
+	0x1eff, 0x1f07,
+	0x1f10, 0x1f15,
+	0x1f20, 0x1f27,
+	0x1f30, 0x1f37,
+	0x1f40, 0x1f45,
+	0x1f50, 0x1f57,
+	0x1f60, 0x1f67,
+	0x1f70, 0x1f7d,
+	0x1f80, 0x1f87,
+	0x1f90, 0x1f97,
+	0x1fa0, 0x1fa7,
+	0x1fb0, 0x1fb4,
+	0x1fb6, 0x1fb7,
+	0x1fbe, 0x1fbe,
+	0x1fc2, 0x1fc4,
+	0x1fc6, 0x1fc7,
+	0x1fd0, 0x1fd3,
+	0x1fd6, 0x1fd7,
+	0x1fe0, 0x1fe7,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ff7,
+	0x214e, 0x214e,
+	0x2170, 0x217f,
+	0x2184, 0x2184,
+	0x24d0, 0x24e9,
+	0x2c30, 0x2c5e,
+	0x2c61, 0x2c61,
+	0x2c65, 0x2c66,
+	0x2c68, 0x2c68,
+	0x2c6a, 0x2c6a,
+	0x2c6c, 0x2c6c,
+	0x2c73, 0x2c73,
+	0x2c76, 0x2c76,
+	0x2c81, 0x2c81,
+	0x2c83, 0x2c83,
+	0x2c85, 0x2c85,
+	0x2c87, 0x2c87,
+	0x2c89, 0x2c89,
+	0x2c8b, 0x2c8b,
+	0x2c8d, 0x2c8d,
+	0x2c8f, 0x2c8f,
+	0x2c91, 0x2c91,
+	0x2c93, 0x2c93,
+	0x2c95, 0x2c95,
+	0x2c97, 0x2c97,
+	0x2c99, 0x2c99,
+	0x2c9b, 0x2c9b,
+	0x2c9d, 0x2c9d,
+	0x2c9f, 0x2c9f,
+	0x2ca1, 0x2ca1,
+	0x2ca3, 0x2ca3,
+	0x2ca5, 0x2ca5,
+	0x2ca7, 0x2ca7,
+	0x2ca9, 0x2ca9,
+	0x2cab, 0x2cab,
+	0x2cad, 0x2cad,
+	0x2caf, 0x2caf,
+	0x2cb1, 0x2cb1,
+	0x2cb3, 0x2cb3,
+	0x2cb5, 0x2cb5,
+	0x2cb7, 0x2cb7,
+	0x2cb9, 0x2cb9,
+	0x2cbb, 0x2cbb,
+	0x2cbd, 0x2cbd,
+	0x2cbf, 0x2cbf,
+	0x2cc1, 0x2cc1,
+	0x2cc3, 0x2cc3,
+	0x2cc5, 0x2cc5,
+	0x2cc7, 0x2cc7,
+	0x2cc9, 0x2cc9,
+	0x2ccb, 0x2ccb,
+	0x2ccd, 0x2ccd,
+	0x2ccf, 0x2ccf,
+	0x2cd1, 0x2cd1,
+	0x2cd3, 0x2cd3,
+	0x2cd5, 0x2cd5,
+	0x2cd7, 0x2cd7,
+	0x2cd9, 0x2cd9,
+	0x2cdb, 0x2cdb,
+	0x2cdd, 0x2cdd,
+	0x2cdf, 0x2cdf,
+	0x2ce1, 0x2ce1,
+	0x2ce3, 0x2ce3,
+	0x2cec, 0x2cec,
+	0x2cee, 0x2cee,
+	0x2cf3, 0x2cf3,
+	0x2d00, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0xa641, 0xa641,
+	0xa643, 0xa643,
+	0xa645, 0xa645,
+	0xa647, 0xa647,
+	0xa649, 0xa649,
+	0xa64b, 0xa64b,
+	0xa64d, 0xa64d,
+	0xa64f, 0xa64f,
+	0xa651, 0xa651,
+	0xa653, 0xa653,
+	0xa655, 0xa655,
+	0xa657, 0xa657,
+	0xa659, 0xa659,
+	0xa65b, 0xa65b,
+	0xa65d, 0xa65d,
+	0xa65f, 0xa65f,
+	0xa661, 0xa661,
+	0xa663, 0xa663,
+	0xa665, 0xa665,
+	0xa667, 0xa667,
+	0xa669, 0xa669,
+	0xa66b, 0xa66b,
+	0xa66d, 0xa66d,
+	0xa681, 0xa681,
+	0xa683, 0xa683,
+	0xa685, 0xa685,
+	0xa687, 0xa687,
+	0xa689, 0xa689,
+	0xa68b, 0xa68b,
+	0xa68d, 0xa68d,
+	0xa68f, 0xa68f,
+	0xa691, 0xa691,
+	0xa693, 0xa693,
+	0xa695, 0xa695,
+	0xa697, 0xa697,
+	0xa699, 0xa699,
+	0xa69b, 0xa69b,
+	0xa723, 0xa723,
+	0xa725, 0xa725,
+	0xa727, 0xa727,
+	0xa729, 0xa729,
+	0xa72b, 0xa72b,
+	0xa72d, 0xa72d,
+	0xa72f, 0xa72f,
+	0xa733, 0xa733,
+	0xa735, 0xa735,
+	0xa737, 0xa737,
+	0xa739, 0xa739,
+	0xa73b, 0xa73b,
+	0xa73d, 0xa73d,
+	0xa73f, 0xa73f,
+	0xa741, 0xa741,
+	0xa743, 0xa743,
+	0xa745, 0xa745,
+	0xa747, 0xa747,
+	0xa749, 0xa749,
+	0xa74b, 0xa74b,
+	0xa74d, 0xa74d,
+	0xa74f, 0xa74f,
+	0xa751, 0xa751,
+	0xa753, 0xa753,
+	0xa755, 0xa755,
+	0xa757, 0xa757,
+	0xa759, 0xa759,
+	0xa75b, 0xa75b,
+	0xa75d, 0xa75d,
+	0xa75f, 0xa75f,
+	0xa761, 0xa761,
+	0xa763, 0xa763,
+	0xa765, 0xa765,
+	0xa767, 0xa767,
+	0xa769, 0xa769,
+	0xa76b, 0xa76b,
+	0xa76d, 0xa76d,
+	0xa76f, 0xa76f,
+	0xa77a, 0xa77a,
+	0xa77c, 0xa77c,
+	0xa77f, 0xa77f,
+	0xa781, 0xa781,
+	0xa783, 0xa783,
+	0xa785, 0xa785,
+	0xa787, 0xa787,
+	0xa78c, 0xa78c,
+	0xa791, 0xa791,
+	0xa793, 0xa793,
+	0xa797, 0xa797,
+	0xa799, 0xa799,
+	0xa79b, 0xa79b,
+	0xa79d, 0xa79d,
+	0xa79f, 0xa79f,
+	0xa7a1, 0xa7a1,
+	0xa7a3, 0xa7a3,
+	0xa7a5, 0xa7a5,
+	0xa7a7, 0xa7a7,
+	0xa7a9, 0xa7a9,
+	0xa7b5, 0xa7b5,
+	0xa7b7, 0xa7b7,
+	0xab53, 0xab53,
+	0xab70, 0xabbf,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xff41, 0xff5a,
+	0x10428, 0x1044f,
+	0x104d8, 0x104fb,
+	0x10cc0, 0x10cf2,
+	0x118c0, 0x118df,
+	0x1e922, 0x1e943,
+}; /* CR_Changes_When_Titlecased */
+
+/* 'Changes_When_Casefolded': Derived Property */
+static const OnigCodePoint CR_Changes_When_Casefolded[] = {
+	603,
+	0x0041, 0x005a,
+	0x00b5, 0x00b5,
+	0x00c0, 0x00d6,
+	0x00d8, 0x00df,
+	0x0100, 0x0100,
+	0x0102, 0x0102,
+	0x0104, 0x0104,
+	0x0106, 0x0106,
+	0x0108, 0x0108,
+	0x010a, 0x010a,
+	0x010c, 0x010c,
+	0x010e, 0x010e,
+	0x0110, 0x0110,
+	0x0112, 0x0112,
+	0x0114, 0x0114,
+	0x0116, 0x0116,
+	0x0118, 0x0118,
+	0x011a, 0x011a,
+	0x011c, 0x011c,
+	0x011e, 0x011e,
+	0x0120, 0x0120,
+	0x0122, 0x0122,
+	0x0124, 0x0124,
+	0x0126, 0x0126,
+	0x0128, 0x0128,
+	0x012a, 0x012a,
+	0x012c, 0x012c,
+	0x012e, 0x012e,
+	0x0130, 0x0130,
+	0x0132, 0x0132,
+	0x0134, 0x0134,
+	0x0136, 0x0136,
+	0x0139, 0x0139,
+	0x013b, 0x013b,
+	0x013d, 0x013d,
+	0x013f, 0x013f,
+	0x0141, 0x0141,
+	0x0143, 0x0143,
+	0x0145, 0x0145,
+	0x0147, 0x0147,
+	0x0149, 0x014a,
+	0x014c, 0x014c,
+	0x014e, 0x014e,
+	0x0150, 0x0150,
+	0x0152, 0x0152,
+	0x0154, 0x0154,
+	0x0156, 0x0156,
+	0x0158, 0x0158,
+	0x015a, 0x015a,
+	0x015c, 0x015c,
+	0x015e, 0x015e,
+	0x0160, 0x0160,
+	0x0162, 0x0162,
+	0x0164, 0x0164,
+	0x0166, 0x0166,
+	0x0168, 0x0168,
+	0x016a, 0x016a,
+	0x016c, 0x016c,
+	0x016e, 0x016e,
+	0x0170, 0x0170,
+	0x0172, 0x0172,
+	0x0174, 0x0174,
+	0x0176, 0x0176,
+	0x0178, 0x0179,
+	0x017b, 0x017b,
+	0x017d, 0x017d,
+	0x017f, 0x017f,
+	0x0181, 0x0182,
+	0x0184, 0x0184,
+	0x0186, 0x0187,
+	0x0189, 0x018b,
+	0x018e, 0x0191,
+	0x0193, 0x0194,
+	0x0196, 0x0198,
+	0x019c, 0x019d,
+	0x019f, 0x01a0,
+	0x01a2, 0x01a2,
+	0x01a4, 0x01a4,
+	0x01a6, 0x01a7,
+	0x01a9, 0x01a9,
+	0x01ac, 0x01ac,
+	0x01ae, 0x01af,
+	0x01b1, 0x01b3,
+	0x01b5, 0x01b5,
+	0x01b7, 0x01b8,
+	0x01bc, 0x01bc,
+	0x01c4, 0x01c5,
+	0x01c7, 0x01c8,
+	0x01ca, 0x01cb,
+	0x01cd, 0x01cd,
+	0x01cf, 0x01cf,
+	0x01d1, 0x01d1,
+	0x01d3, 0x01d3,
+	0x01d5, 0x01d5,
+	0x01d7, 0x01d7,
+	0x01d9, 0x01d9,
+	0x01db, 0x01db,
+	0x01de, 0x01de,
+	0x01e0, 0x01e0,
+	0x01e2, 0x01e2,
+	0x01e4, 0x01e4,
+	0x01e6, 0x01e6,
+	0x01e8, 0x01e8,
+	0x01ea, 0x01ea,
+	0x01ec, 0x01ec,
+	0x01ee, 0x01ee,
+	0x01f1, 0x01f2,
+	0x01f4, 0x01f4,
+	0x01f6, 0x01f8,
+	0x01fa, 0x01fa,
+	0x01fc, 0x01fc,
+	0x01fe, 0x01fe,
+	0x0200, 0x0200,
+	0x0202, 0x0202,
+	0x0204, 0x0204,
+	0x0206, 0x0206,
+	0x0208, 0x0208,
+	0x020a, 0x020a,
+	0x020c, 0x020c,
+	0x020e, 0x020e,
+	0x0210, 0x0210,
+	0x0212, 0x0212,
+	0x0214, 0x0214,
+	0x0216, 0x0216,
+	0x0218, 0x0218,
+	0x021a, 0x021a,
+	0x021c, 0x021c,
+	0x021e, 0x021e,
+	0x0220, 0x0220,
+	0x0222, 0x0222,
+	0x0224, 0x0224,
+	0x0226, 0x0226,
+	0x0228, 0x0228,
+	0x022a, 0x022a,
+	0x022c, 0x022c,
+	0x022e, 0x022e,
+	0x0230, 0x0230,
+	0x0232, 0x0232,
+	0x023a, 0x023b,
+	0x023d, 0x023e,
+	0x0241, 0x0241,
+	0x0243, 0x0246,
+	0x0248, 0x0248,
+	0x024a, 0x024a,
+	0x024c, 0x024c,
+	0x024e, 0x024e,
+	0x0345, 0x0345,
+	0x0370, 0x0370,
+	0x0372, 0x0372,
+	0x0376, 0x0376,
+	0x037f, 0x037f,
+	0x0386, 0x0386,
+	0x0388, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x038f,
+	0x0391, 0x03a1,
+	0x03a3, 0x03ab,
+	0x03c2, 0x03c2,
+	0x03cf, 0x03d1,
+	0x03d5, 0x03d6,
+	0x03d8, 0x03d8,
+	0x03da, 0x03da,
+	0x03dc, 0x03dc,
+	0x03de, 0x03de,
+	0x03e0, 0x03e0,
+	0x03e2, 0x03e2,
+	0x03e4, 0x03e4,
+	0x03e6, 0x03e6,
+	0x03e8, 0x03e8,
+	0x03ea, 0x03ea,
+	0x03ec, 0x03ec,
+	0x03ee, 0x03ee,
+	0x03f0, 0x03f1,
+	0x03f4, 0x03f5,
+	0x03f7, 0x03f7,
+	0x03f9, 0x03fa,
+	0x03fd, 0x042f,
+	0x0460, 0x0460,
+	0x0462, 0x0462,
+	0x0464, 0x0464,
+	0x0466, 0x0466,
+	0x0468, 0x0468,
+	0x046a, 0x046a,
+	0x046c, 0x046c,
+	0x046e, 0x046e,
+	0x0470, 0x0470,
+	0x0472, 0x0472,
+	0x0474, 0x0474,
+	0x0476, 0x0476,
+	0x0478, 0x0478,
+	0x047a, 0x047a,
+	0x047c, 0x047c,
+	0x047e, 0x047e,
+	0x0480, 0x0480,
+	0x048a, 0x048a,
+	0x048c, 0x048c,
+	0x048e, 0x048e,
+	0x0490, 0x0490,
+	0x0492, 0x0492,
+	0x0494, 0x0494,
+	0x0496, 0x0496,
+	0x0498, 0x0498,
+	0x049a, 0x049a,
+	0x049c, 0x049c,
+	0x049e, 0x049e,
+	0x04a0, 0x04a0,
+	0x04a2, 0x04a2,
+	0x04a4, 0x04a4,
+	0x04a6, 0x04a6,
+	0x04a8, 0x04a8,
+	0x04aa, 0x04aa,
+	0x04ac, 0x04ac,
+	0x04ae, 0x04ae,
+	0x04b0, 0x04b0,
+	0x04b2, 0x04b2,
+	0x04b4, 0x04b4,
+	0x04b6, 0x04b6,
+	0x04b8, 0x04b8,
+	0x04ba, 0x04ba,
+	0x04bc, 0x04bc,
+	0x04be, 0x04be,
+	0x04c0, 0x04c1,
+	0x04c3, 0x04c3,
+	0x04c5, 0x04c5,
+	0x04c7, 0x04c7,
+	0x04c9, 0x04c9,
+	0x04cb, 0x04cb,
+	0x04cd, 0x04cd,
+	0x04d0, 0x04d0,
+	0x04d2, 0x04d2,
+	0x04d4, 0x04d4,
+	0x04d6, 0x04d6,
+	0x04d8, 0x04d8,
+	0x04da, 0x04da,
+	0x04dc, 0x04dc,
+	0x04de, 0x04de,
+	0x04e0, 0x04e0,
+	0x04e2, 0x04e2,
+	0x04e4, 0x04e4,
+	0x04e6, 0x04e6,
+	0x04e8, 0x04e8,
+	0x04ea, 0x04ea,
+	0x04ec, 0x04ec,
+	0x04ee, 0x04ee,
+	0x04f0, 0x04f0,
+	0x04f2, 0x04f2,
+	0x04f4, 0x04f4,
+	0x04f6, 0x04f6,
+	0x04f8, 0x04f8,
+	0x04fa, 0x04fa,
+	0x04fc, 0x04fc,
+	0x04fe, 0x04fe,
+	0x0500, 0x0500,
+	0x0502, 0x0502,
+	0x0504, 0x0504,
+	0x0506, 0x0506,
+	0x0508, 0x0508,
+	0x050a, 0x050a,
+	0x050c, 0x050c,
+	0x050e, 0x050e,
+	0x0510, 0x0510,
+	0x0512, 0x0512,
+	0x0514, 0x0514,
+	0x0516, 0x0516,
+	0x0518, 0x0518,
+	0x051a, 0x051a,
+	0x051c, 0x051c,
+	0x051e, 0x051e,
+	0x0520, 0x0520,
+	0x0522, 0x0522,
+	0x0524, 0x0524,
+	0x0526, 0x0526,
+	0x0528, 0x0528,
+	0x052a, 0x052a,
+	0x052c, 0x052c,
+	0x052e, 0x052e,
+	0x0531, 0x0556,
+	0x0587, 0x0587,
+	0x10a0, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x13f8, 0x13fd,
+	0x1c80, 0x1c88,
+	0x1e00, 0x1e00,
+	0x1e02, 0x1e02,
+	0x1e04, 0x1e04,
+	0x1e06, 0x1e06,
+	0x1e08, 0x1e08,
+	0x1e0a, 0x1e0a,
+	0x1e0c, 0x1e0c,
+	0x1e0e, 0x1e0e,
+	0x1e10, 0x1e10,
+	0x1e12, 0x1e12,
+	0x1e14, 0x1e14,
+	0x1e16, 0x1e16,
+	0x1e18, 0x1e18,
+	0x1e1a, 0x1e1a,
+	0x1e1c, 0x1e1c,
+	0x1e1e, 0x1e1e,
+	0x1e20, 0x1e20,
+	0x1e22, 0x1e22,
+	0x1e24, 0x1e24,
+	0x1e26, 0x1e26,
+	0x1e28, 0x1e28,
+	0x1e2a, 0x1e2a,
+	0x1e2c, 0x1e2c,
+	0x1e2e, 0x1e2e,
+	0x1e30, 0x1e30,
+	0x1e32, 0x1e32,
+	0x1e34, 0x1e34,
+	0x1e36, 0x1e36,
+	0x1e38, 0x1e38,
+	0x1e3a, 0x1e3a,
+	0x1e3c, 0x1e3c,
+	0x1e3e, 0x1e3e,
+	0x1e40, 0x1e40,
+	0x1e42, 0x1e42,
+	0x1e44, 0x1e44,
+	0x1e46, 0x1e46,
+	0x1e48, 0x1e48,
+	0x1e4a, 0x1e4a,
+	0x1e4c, 0x1e4c,
+	0x1e4e, 0x1e4e,
+	0x1e50, 0x1e50,
+	0x1e52, 0x1e52,
+	0x1e54, 0x1e54,
+	0x1e56, 0x1e56,
+	0x1e58, 0x1e58,
+	0x1e5a, 0x1e5a,
+	0x1e5c, 0x1e5c,
+	0x1e5e, 0x1e5e,
+	0x1e60, 0x1e60,
+	0x1e62, 0x1e62,
+	0x1e64, 0x1e64,
+	0x1e66, 0x1e66,
+	0x1e68, 0x1e68,
+	0x1e6a, 0x1e6a,
+	0x1e6c, 0x1e6c,
+	0x1e6e, 0x1e6e,
+	0x1e70, 0x1e70,
+	0x1e72, 0x1e72,
+	0x1e74, 0x1e74,
+	0x1e76, 0x1e76,
+	0x1e78, 0x1e78,
+	0x1e7a, 0x1e7a,
+	0x1e7c, 0x1e7c,
+	0x1e7e, 0x1e7e,
+	0x1e80, 0x1e80,
+	0x1e82, 0x1e82,
+	0x1e84, 0x1e84,
+	0x1e86, 0x1e86,
+	0x1e88, 0x1e88,
+	0x1e8a, 0x1e8a,
+	0x1e8c, 0x1e8c,
+	0x1e8e, 0x1e8e,
+	0x1e90, 0x1e90,
+	0x1e92, 0x1e92,
+	0x1e94, 0x1e94,
+	0x1e9a, 0x1e9b,
+	0x1e9e, 0x1e9e,
+	0x1ea0, 0x1ea0,
+	0x1ea2, 0x1ea2,
+	0x1ea4, 0x1ea4,
+	0x1ea6, 0x1ea6,
+	0x1ea8, 0x1ea8,
+	0x1eaa, 0x1eaa,
+	0x1eac, 0x1eac,
+	0x1eae, 0x1eae,
+	0x1eb0, 0x1eb0,
+	0x1eb2, 0x1eb2,
+	0x1eb4, 0x1eb4,
+	0x1eb6, 0x1eb6,
+	0x1eb8, 0x1eb8,
+	0x1eba, 0x1eba,
+	0x1ebc, 0x1ebc,
+	0x1ebe, 0x1ebe,
+	0x1ec0, 0x1ec0,
+	0x1ec2, 0x1ec2,
+	0x1ec4, 0x1ec4,
+	0x1ec6, 0x1ec6,
+	0x1ec8, 0x1ec8,
+	0x1eca, 0x1eca,
+	0x1ecc, 0x1ecc,
+	0x1ece, 0x1ece,
+	0x1ed0, 0x1ed0,
+	0x1ed2, 0x1ed2,
+	0x1ed4, 0x1ed4,
+	0x1ed6, 0x1ed6,
+	0x1ed8, 0x1ed8,
+	0x1eda, 0x1eda,
+	0x1edc, 0x1edc,
+	0x1ede, 0x1ede,
+	0x1ee0, 0x1ee0,
+	0x1ee2, 0x1ee2,
+	0x1ee4, 0x1ee4,
+	0x1ee6, 0x1ee6,
+	0x1ee8, 0x1ee8,
+	0x1eea, 0x1eea,
+	0x1eec, 0x1eec,
+	0x1eee, 0x1eee,
+	0x1ef0, 0x1ef0,
+	0x1ef2, 0x1ef2,
+	0x1ef4, 0x1ef4,
+	0x1ef6, 0x1ef6,
+	0x1ef8, 0x1ef8,
+	0x1efa, 0x1efa,
+	0x1efc, 0x1efc,
+	0x1efe, 0x1efe,
+	0x1f08, 0x1f0f,
+	0x1f18, 0x1f1d,
+	0x1f28, 0x1f2f,
+	0x1f38, 0x1f3f,
+	0x1f48, 0x1f4d,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f5f,
+	0x1f68, 0x1f6f,
+	0x1f80, 0x1faf,
+	0x1fb2, 0x1fb4,
+	0x1fb7, 0x1fbc,
+	0x1fc2, 0x1fc4,
+	0x1fc7, 0x1fcc,
+	0x1fd8, 0x1fdb,
+	0x1fe8, 0x1fec,
+	0x1ff2, 0x1ff4,
+	0x1ff7, 0x1ffc,
+	0x2126, 0x2126,
+	0x212a, 0x212b,
+	0x2132, 0x2132,
+	0x2160, 0x216f,
+	0x2183, 0x2183,
+	0x24b6, 0x24cf,
+	0x2c00, 0x2c2e,
+	0x2c60, 0x2c60,
+	0x2c62, 0x2c64,
+	0x2c67, 0x2c67,
+	0x2c69, 0x2c69,
+	0x2c6b, 0x2c6b,
+	0x2c6d, 0x2c70,
+	0x2c72, 0x2c72,
+	0x2c75, 0x2c75,
+	0x2c7e, 0x2c80,
+	0x2c82, 0x2c82,
+	0x2c84, 0x2c84,
+	0x2c86, 0x2c86,
+	0x2c88, 0x2c88,
+	0x2c8a, 0x2c8a,
+	0x2c8c, 0x2c8c,
+	0x2c8e, 0x2c8e,
+	0x2c90, 0x2c90,
+	0x2c92, 0x2c92,
+	0x2c94, 0x2c94,
+	0x2c96, 0x2c96,
+	0x2c98, 0x2c98,
+	0x2c9a, 0x2c9a,
+	0x2c9c, 0x2c9c,
+	0x2c9e, 0x2c9e,
+	0x2ca0, 0x2ca0,
+	0x2ca2, 0x2ca2,
+	0x2ca4, 0x2ca4,
+	0x2ca6, 0x2ca6,
+	0x2ca8, 0x2ca8,
+	0x2caa, 0x2caa,
+	0x2cac, 0x2cac,
+	0x2cae, 0x2cae,
+	0x2cb0, 0x2cb0,
+	0x2cb2, 0x2cb2,
+	0x2cb4, 0x2cb4,
+	0x2cb6, 0x2cb6,
+	0x2cb8, 0x2cb8,
+	0x2cba, 0x2cba,
+	0x2cbc, 0x2cbc,
+	0x2cbe, 0x2cbe,
+	0x2cc0, 0x2cc0,
+	0x2cc2, 0x2cc2,
+	0x2cc4, 0x2cc4,
+	0x2cc6, 0x2cc6,
+	0x2cc8, 0x2cc8,
+	0x2cca, 0x2cca,
+	0x2ccc, 0x2ccc,
+	0x2cce, 0x2cce,
+	0x2cd0, 0x2cd0,
+	0x2cd2, 0x2cd2,
+	0x2cd4, 0x2cd4,
+	0x2cd6, 0x2cd6,
+	0x2cd8, 0x2cd8,
+	0x2cda, 0x2cda,
+	0x2cdc, 0x2cdc,
+	0x2cde, 0x2cde,
+	0x2ce0, 0x2ce0,
+	0x2ce2, 0x2ce2,
+	0x2ceb, 0x2ceb,
+	0x2ced, 0x2ced,
+	0x2cf2, 0x2cf2,
+	0xa640, 0xa640,
+	0xa642, 0xa642,
+	0xa644, 0xa644,
+	0xa646, 0xa646,
+	0xa648, 0xa648,
+	0xa64a, 0xa64a,
+	0xa64c, 0xa64c,
+	0xa64e, 0xa64e,
+	0xa650, 0xa650,
+	0xa652, 0xa652,
+	0xa654, 0xa654,
+	0xa656, 0xa656,
+	0xa658, 0xa658,
+	0xa65a, 0xa65a,
+	0xa65c, 0xa65c,
+	0xa65e, 0xa65e,
+	0xa660, 0xa660,
+	0xa662, 0xa662,
+	0xa664, 0xa664,
+	0xa666, 0xa666,
+	0xa668, 0xa668,
+	0xa66a, 0xa66a,
+	0xa66c, 0xa66c,
+	0xa680, 0xa680,
+	0xa682, 0xa682,
+	0xa684, 0xa684,
+	0xa686, 0xa686,
+	0xa688, 0xa688,
+	0xa68a, 0xa68a,
+	0xa68c, 0xa68c,
+	0xa68e, 0xa68e,
+	0xa690, 0xa690,
+	0xa692, 0xa692,
+	0xa694, 0xa694,
+	0xa696, 0xa696,
+	0xa698, 0xa698,
+	0xa69a, 0xa69a,
+	0xa722, 0xa722,
+	0xa724, 0xa724,
+	0xa726, 0xa726,
+	0xa728, 0xa728,
+	0xa72a, 0xa72a,
+	0xa72c, 0xa72c,
+	0xa72e, 0xa72e,
+	0xa732, 0xa732,
+	0xa734, 0xa734,
+	0xa736, 0xa736,
+	0xa738, 0xa738,
+	0xa73a, 0xa73a,
+	0xa73c, 0xa73c,
+	0xa73e, 0xa73e,
+	0xa740, 0xa740,
+	0xa742, 0xa742,
+	0xa744, 0xa744,
+	0xa746, 0xa746,
+	0xa748, 0xa748,
+	0xa74a, 0xa74a,
+	0xa74c, 0xa74c,
+	0xa74e, 0xa74e,
+	0xa750, 0xa750,
+	0xa752, 0xa752,
+	0xa754, 0xa754,
+	0xa756, 0xa756,
+	0xa758, 0xa758,
+	0xa75a, 0xa75a,
+	0xa75c, 0xa75c,
+	0xa75e, 0xa75e,
+	0xa760, 0xa760,
+	0xa762, 0xa762,
+	0xa764, 0xa764,
+	0xa766, 0xa766,
+	0xa768, 0xa768,
+	0xa76a, 0xa76a,
+	0xa76c, 0xa76c,
+	0xa76e, 0xa76e,
+	0xa779, 0xa779,
+	0xa77b, 0xa77b,
+	0xa77d, 0xa77e,
+	0xa780, 0xa780,
+	0xa782, 0xa782,
+	0xa784, 0xa784,
+	0xa786, 0xa786,
+	0xa78b, 0xa78b,
+	0xa78d, 0xa78d,
+	0xa790, 0xa790,
+	0xa792, 0xa792,
+	0xa796, 0xa796,
+	0xa798, 0xa798,
+	0xa79a, 0xa79a,
+	0xa79c, 0xa79c,
+	0xa79e, 0xa79e,
+	0xa7a0, 0xa7a0,
+	0xa7a2, 0xa7a2,
+	0xa7a4, 0xa7a4,
+	0xa7a6, 0xa7a6,
+	0xa7a8, 0xa7a8,
+	0xa7aa, 0xa7ae,
+	0xa7b0, 0xa7b4,
+	0xa7b6, 0xa7b6,
+	0xab70, 0xabbf,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xff21, 0xff3a,
+	0x10400, 0x10427,
+	0x104b0, 0x104d3,
+	0x10c80, 0x10cb2,
+	0x118a0, 0x118bf,
+	0x1e900, 0x1e921,
+}; /* CR_Changes_When_Casefolded */
+
+/* 'Changes_When_Casemapped': Derived Property */
+static const OnigCodePoint CR_Changes_When_Casemapped[] = {
+	116,
+	0x0041, 0x005a,
+	0x0061, 0x007a,
+	0x00b5, 0x00b5,
+	0x00c0, 0x00d6,
+	0x00d8, 0x00f6,
+	0x00f8, 0x0137,
+	0x0139, 0x018c,
+	0x018e, 0x019a,
+	0x019c, 0x01a9,
+	0x01ac, 0x01b9,
+	0x01bc, 0x01bd,
+	0x01bf, 0x01bf,
+	0x01c4, 0x0220,
+	0x0222, 0x0233,
+	0x023a, 0x0254,
+	0x0256, 0x0257,
+	0x0259, 0x0259,
+	0x025b, 0x025c,
+	0x0260, 0x0261,
+	0x0263, 0x0263,
+	0x0265, 0x0266,
+	0x0268, 0x026c,
+	0x026f, 0x026f,
+	0x0271, 0x0272,
+	0x0275, 0x0275,
+	0x027d, 0x027d,
+	0x0280, 0x0280,
+	0x0283, 0x0283,
+	0x0287, 0x028c,
+	0x0292, 0x0292,
+	0x029d, 0x029e,
+	0x0345, 0x0345,
+	0x0370, 0x0373,
+	0x0376, 0x0377,
+	0x037b, 0x037d,
+	0x037f, 0x037f,
+	0x0386, 0x0386,
+	0x0388, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03d1,
+	0x03d5, 0x03f5,
+	0x03f7, 0x03fb,
+	0x03fd, 0x0481,
+	0x048a, 0x052f,
+	0x0531, 0x0556,
+	0x0561, 0x0587,
+	0x10a0, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x13a0, 0x13f5,
+	0x13f8, 0x13fd,
+	0x1c80, 0x1c88,
+	0x1d79, 0x1d79,
+	0x1d7d, 0x1d7d,
+	0x1e00, 0x1e9b,
+	0x1e9e, 0x1e9e,
+	0x1ea0, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fbc,
+	0x1fbe, 0x1fbe,
+	0x1fc2, 0x1fc4,
+	0x1fc6, 0x1fcc,
+	0x1fd0, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fe0, 0x1fec,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffc,
+	0x2126, 0x2126,
+	0x212a, 0x212b,
+	0x2132, 0x2132,
+	0x214e, 0x214e,
+	0x2160, 0x217f,
+	0x2183, 0x2184,
+	0x24b6, 0x24e9,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2c70,
+	0x2c72, 0x2c73,
+	0x2c75, 0x2c76,
+	0x2c7e, 0x2ce3,
+	0x2ceb, 0x2cee,
+	0x2cf2, 0x2cf3,
+	0x2d00, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0xa640, 0xa66d,
+	0xa680, 0xa69b,
+	0xa722, 0xa72f,
+	0xa732, 0xa76f,
+	0xa779, 0xa787,
+	0xa78b, 0xa78d,
+	0xa790, 0xa793,
+	0xa796, 0xa7ae,
+	0xa7b0, 0xa7b7,
+	0xab53, 0xab53,
+	0xab70, 0xabbf,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xff21, 0xff3a,
+	0xff41, 0xff5a,
+	0x10400, 0x1044f,
+	0x104b0, 0x104d3,
+	0x104d8, 0x104fb,
+	0x10c80, 0x10cb2,
+	0x10cc0, 0x10cf2,
+	0x118a0, 0x118df,
+	0x1e900, 0x1e943,
+}; /* CR_Changes_When_Casemapped */
+
+/* 'ID_Start': Derived Property */
+static const OnigCodePoint CR_ID_Start[] = {
+	585,
+	0x0041, 0x005a,
+	0x0061, 0x007a,
+	0x00aa, 0x00aa,
+	0x00b5, 0x00b5,
+	0x00ba, 0x00ba,
+	0x00c0, 0x00d6,
+	0x00d8, 0x00f6,
+	0x00f8, 0x02c1,
+	0x02c6, 0x02d1,
+	0x02e0, 0x02e4,
+	0x02ec, 0x02ec,
+	0x02ee, 0x02ee,
+	0x0370, 0x0374,
+	0x0376, 0x0377,
+	0x037a, 0x037d,
+	0x037f, 0x037f,
+	0x0386, 0x0386,
+	0x0388, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03f5,
+	0x03f7, 0x0481,
+	0x048a, 0x052f,
+	0x0531, 0x0556,
+	0x0559, 0x0559,
+	0x0561, 0x0587,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f2,
+	0x0620, 0x064a,
+	0x066e, 0x066f,
+	0x0671, 0x06d3,
+	0x06d5, 0x06d5,
+	0x06e5, 0x06e6,
+	0x06ee, 0x06ef,
+	0x06fa, 0x06fc,
+	0x06ff, 0x06ff,
+	0x0710, 0x0710,
+	0x0712, 0x072f,
+	0x074d, 0x07a5,
+	0x07b1, 0x07b1,
+	0x07ca, 0x07ea,
+	0x07f4, 0x07f5,
+	0x07fa, 0x07fa,
+	0x0800, 0x0815,
+	0x081a, 0x081a,
+	0x0824, 0x0824,
+	0x0828, 0x0828,
+	0x0840, 0x0858,
+	0x0860, 0x086a,
+	0x08a0, 0x08b4,
+	0x08b6, 0x08bd,
+	0x0904, 0x0939,
+	0x093d, 0x093d,
+	0x0950, 0x0950,
+	0x0958, 0x0961,
+	0x0971, 0x0980,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bd, 0x09bd,
+	0x09ce, 0x09ce,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e1,
+	0x09f0, 0x09f1,
+	0x09fc, 0x09fc,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a72, 0x0a74,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abd, 0x0abd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae1,
+	0x0af9, 0x0af9,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3d, 0x0b3d,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b61,
+	0x0b71, 0x0b71,
+	0x0b83, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bd0, 0x0bd0,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c39,
+	0x0c3d, 0x0c3d,
+	0x0c58, 0x0c5a,
+	0x0c60, 0x0c61,
+	0x0c80, 0x0c80,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbd, 0x0cbd,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce1,
+	0x0cf1, 0x0cf2,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d3a,
+	0x0d3d, 0x0d3d,
+	0x0d4e, 0x0d4e,
+	0x0d54, 0x0d56,
+	0x0d5f, 0x0d61,
+	0x0d7a, 0x0d7f,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0e01, 0x0e30,
+	0x0e32, 0x0e33,
+	0x0e40, 0x0e46,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb0,
+	0x0eb2, 0x0eb3,
+	0x0ebd, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f00,
+	0x0f40, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f88, 0x0f8c,
+	0x1000, 0x102a,
+	0x103f, 0x103f,
+	0x1050, 0x1055,
+	0x105a, 0x105d,
+	0x1061, 0x1061,
+	0x1065, 0x1066,
+	0x106e, 0x1070,
+	0x1075, 0x1081,
+	0x108e, 0x108e,
+	0x10a0, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x10fa,
+	0x10fc, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x1380, 0x138f,
+	0x13a0, 0x13f5,
+	0x13f8, 0x13fd,
+	0x1401, 0x166c,
+	0x166f, 0x167f,
+	0x1681, 0x169a,
+	0x16a0, 0x16ea,
+	0x16ee, 0x16f8,
+	0x1700, 0x170c,
+	0x170e, 0x1711,
+	0x1720, 0x1731,
+	0x1740, 0x1751,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1780, 0x17b3,
+	0x17d7, 0x17d7,
+	0x17dc, 0x17dc,
+	0x1820, 0x1877,
+	0x1880, 0x18a8,
+	0x18aa, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191e,
+	0x1950, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x1a00, 0x1a16,
+	0x1a20, 0x1a54,
+	0x1aa7, 0x1aa7,
+	0x1b05, 0x1b33,
+	0x1b45, 0x1b4b,
+	0x1b83, 0x1ba0,
+	0x1bae, 0x1baf,
+	0x1bba, 0x1be5,
+	0x1c00, 0x1c23,
+	0x1c4d, 0x1c4f,
+	0x1c5a, 0x1c7d,
+	0x1c80, 0x1c88,
+	0x1ce9, 0x1cec,
+	0x1cee, 0x1cf1,
+	0x1cf5, 0x1cf6,
+	0x1d00, 0x1dbf,
+	0x1e00, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fbc,
+	0x1fbe, 0x1fbe,
+	0x1fc2, 0x1fc4,
+	0x1fc6, 0x1fcc,
+	0x1fd0, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fe0, 0x1fec,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffc,
+	0x2071, 0x2071,
+	0x207f, 0x207f,
+	0x2090, 0x209c,
+	0x2102, 0x2102,
+	0x2107, 0x2107,
+	0x210a, 0x2113,
+	0x2115, 0x2115,
+	0x2118, 0x211d,
+	0x2124, 0x2124,
+	0x2126, 0x2126,
+	0x2128, 0x2128,
+	0x212a, 0x2139,
+	0x213c, 0x213f,
+	0x2145, 0x2149,
+	0x214e, 0x214e,
+	0x2160, 0x2188,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2ce4,
+	0x2ceb, 0x2cee,
+	0x2cf2, 0x2cf3,
+	0x2d00, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d6f,
+	0x2d80, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x3005, 0x3007,
+	0x3021, 0x3029,
+	0x3031, 0x3035,
+	0x3038, 0x303c,
+	0x3041, 0x3096,
+	0x309b, 0x309f,
+	0x30a1, 0x30fa,
+	0x30fc, 0x30ff,
+	0x3105, 0x312e,
+	0x3131, 0x318e,
+	0x31a0, 0x31ba,
+	0x31f0, 0x31ff,
+	0x3400, 0x4db5,
+	0x4e00, 0x9fea,
+	0xa000, 0xa48c,
+	0xa4d0, 0xa4fd,
+	0xa500, 0xa60c,
+	0xa610, 0xa61f,
+	0xa62a, 0xa62b,
+	0xa640, 0xa66e,
+	0xa67f, 0xa69d,
+	0xa6a0, 0xa6ef,
+	0xa717, 0xa71f,
+	0xa722, 0xa788,
+	0xa78b, 0xa7ae,
+	0xa7b0, 0xa7b7,
+	0xa7f7, 0xa801,
+	0xa803, 0xa805,
+	0xa807, 0xa80a,
+	0xa80c, 0xa822,
+	0xa840, 0xa873,
+	0xa882, 0xa8b3,
+	0xa8f2, 0xa8f7,
+	0xa8fb, 0xa8fb,
+	0xa8fd, 0xa8fd,
+	0xa90a, 0xa925,
+	0xa930, 0xa946,
+	0xa960, 0xa97c,
+	0xa984, 0xa9b2,
+	0xa9cf, 0xa9cf,
+	0xa9e0, 0xa9e4,
+	0xa9e6, 0xa9ef,
+	0xa9fa, 0xa9fe,
+	0xaa00, 0xaa28,
+	0xaa40, 0xaa42,
+	0xaa44, 0xaa4b,
+	0xaa60, 0xaa76,
+	0xaa7a, 0xaa7a,
+	0xaa7e, 0xaaaf,
+	0xaab1, 0xaab1,
+	0xaab5, 0xaab6,
+	0xaab9, 0xaabd,
+	0xaac0, 0xaac0,
+	0xaac2, 0xaac2,
+	0xaadb, 0xaadd,
+	0xaae0, 0xaaea,
+	0xaaf2, 0xaaf4,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xab30, 0xab5a,
+	0xab5c, 0xab65,
+	0xab70, 0xabe2,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xf900, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb1d,
+	0xfb1f, 0xfb28,
+	0xfb2a, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbb1,
+	0xfbd3, 0xfd3d,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdf0, 0xfdfb,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xff21, 0xff3a,
+	0xff41, 0xff5a,
+	0xff66, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0x10000, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10140, 0x10174,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x10300, 0x1031f,
+	0x1032d, 0x1034a,
+	0x10350, 0x10375,
+	0x10380, 0x1039d,
+	0x103a0, 0x103c3,
+	0x103c8, 0x103cf,
+	0x103d1, 0x103d5,
+	0x10400, 0x1049d,
+	0x104b0, 0x104d3,
+	0x104d8, 0x104fb,
+	0x10500, 0x10527,
+	0x10530, 0x10563,
+	0x10600, 0x10736,
+	0x10740, 0x10755,
+	0x10760, 0x10767,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10860, 0x10876,
+	0x10880, 0x1089e,
+	0x108e0, 0x108f2,
+	0x108f4, 0x108f5,
+	0x10900, 0x10915,
+	0x10920, 0x10939,
+	0x10980, 0x109b7,
+	0x109be, 0x109bf,
+	0x10a00, 0x10a00,
+	0x10a10, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a60, 0x10a7c,
+	0x10a80, 0x10a9c,
+	0x10ac0, 0x10ac7,
+	0x10ac9, 0x10ae4,
+	0x10b00, 0x10b35,
+	0x10b40, 0x10b55,
+	0x10b60, 0x10b72,
+	0x10b80, 0x10b91,
+	0x10c00, 0x10c48,
+	0x10c80, 0x10cb2,
+	0x10cc0, 0x10cf2,
+	0x11003, 0x11037,
+	0x11083, 0x110af,
+	0x110d0, 0x110e8,
+	0x11103, 0x11126,
+	0x11150, 0x11172,
+	0x11176, 0x11176,
+	0x11183, 0x111b2,
+	0x111c1, 0x111c4,
+	0x111da, 0x111da,
+	0x111dc, 0x111dc,
+	0x11200, 0x11211,
+	0x11213, 0x1122b,
+	0x11280, 0x11286,
+	0x11288, 0x11288,
+	0x1128a, 0x1128d,
+	0x1128f, 0x1129d,
+	0x1129f, 0x112a8,
+	0x112b0, 0x112de,
+	0x11305, 0x1130c,
+	0x1130f, 0x11310,
+	0x11313, 0x11328,
+	0x1132a, 0x11330,
+	0x11332, 0x11333,
+	0x11335, 0x11339,
+	0x1133d, 0x1133d,
+	0x11350, 0x11350,
+	0x1135d, 0x11361,
+	0x11400, 0x11434,
+	0x11447, 0x1144a,
+	0x11480, 0x114af,
+	0x114c4, 0x114c5,
+	0x114c7, 0x114c7,
+	0x11580, 0x115ae,
+	0x115d8, 0x115db,
+	0x11600, 0x1162f,
+	0x11644, 0x11644,
+	0x11680, 0x116aa,
+	0x11700, 0x11719,
+	0x118a0, 0x118df,
+	0x118ff, 0x118ff,
+	0x11a00, 0x11a00,
+	0x11a0b, 0x11a32,
+	0x11a3a, 0x11a3a,
+	0x11a50, 0x11a50,
+	0x11a5c, 0x11a83,
+	0x11a86, 0x11a89,
+	0x11ac0, 0x11af8,
+	0x11c00, 0x11c08,
+	0x11c0a, 0x11c2e,
+	0x11c40, 0x11c40,
+	0x11c72, 0x11c8f,
+	0x11d00, 0x11d06,
+	0x11d08, 0x11d09,
+	0x11d0b, 0x11d30,
+	0x11d46, 0x11d46,
+	0x12000, 0x12399,
+	0x12400, 0x1246e,
+	0x12480, 0x12543,
+	0x13000, 0x1342e,
+	0x14400, 0x14646,
+	0x16800, 0x16a38,
+	0x16a40, 0x16a5e,
+	0x16ad0, 0x16aed,
+	0x16b00, 0x16b2f,
+	0x16b40, 0x16b43,
+	0x16b63, 0x16b77,
+	0x16b7d, 0x16b8f,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f50,
+	0x16f93, 0x16f9f,
+	0x16fe0, 0x16fe1,
+	0x17000, 0x187ec,
+	0x18800, 0x18af2,
+	0x1b000, 0x1b11e,
+	0x1b170, 0x1b2fb,
+	0x1bc00, 0x1bc6a,
+	0x1bc70, 0x1bc7c,
+	0x1bc80, 0x1bc88,
+	0x1bc90, 0x1bc99,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d6c0,
+	0x1d6c2, 0x1d6da,
+	0x1d6dc, 0x1d6fa,
+	0x1d6fc, 0x1d714,
+	0x1d716, 0x1d734,
+	0x1d736, 0x1d74e,
+	0x1d750, 0x1d76e,
+	0x1d770, 0x1d788,
+	0x1d78a, 0x1d7a8,
+	0x1d7aa, 0x1d7c2,
+	0x1d7c4, 0x1d7cb,
+	0x1e800, 0x1e8c4,
+	0x1e900, 0x1e943,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x20000, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2b820, 0x2cea1,
+	0x2ceb0, 0x2ebe0,
+	0x2f800, 0x2fa1d,
+}; /* CR_ID_Start */
+
+/* 'ID_Continue': Derived Property */
+static const OnigCodePoint CR_ID_Continue[] = {
+	689,
+	0x0030, 0x0039,
+	0x0041, 0x005a,
+	0x005f, 0x005f,
+	0x0061, 0x007a,
+	0x00aa, 0x00aa,
+	0x00b5, 0x00b5,
+	0x00b7, 0x00b7,
+	0x00ba, 0x00ba,
+	0x00c0, 0x00d6,
+	0x00d8, 0x00f6,
+	0x00f8, 0x02c1,
+	0x02c6, 0x02d1,
+	0x02e0, 0x02e4,
+	0x02ec, 0x02ec,
+	0x02ee, 0x02ee,
+	0x0300, 0x0374,
+	0x0376, 0x0377,
+	0x037a, 0x037d,
+	0x037f, 0x037f,
+	0x0386, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03f5,
+	0x03f7, 0x0481,
+	0x0483, 0x0487,
+	0x048a, 0x052f,
+	0x0531, 0x0556,
+	0x0559, 0x0559,
+	0x0561, 0x0587,
+	0x0591, 0x05bd,
+	0x05bf, 0x05bf,
+	0x05c1, 0x05c2,
+	0x05c4, 0x05c5,
+	0x05c7, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f2,
+	0x0610, 0x061a,
+	0x0620, 0x0669,
+	0x066e, 0x06d3,
+	0x06d5, 0x06dc,
+	0x06df, 0x06e8,
+	0x06ea, 0x06fc,
+	0x06ff, 0x06ff,
+	0x0710, 0x074a,
+	0x074d, 0x07b1,
+	0x07c0, 0x07f5,
+	0x07fa, 0x07fa,
+	0x0800, 0x082d,
+	0x0840, 0x085b,
+	0x0860, 0x086a,
+	0x08a0, 0x08b4,
+	0x08b6, 0x08bd,
+	0x08d4, 0x08e1,
+	0x08e3, 0x0963,
+	0x0966, 0x096f,
+	0x0971, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09f1,
+	0x09fc, 0x09fc,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a75,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0aef,
+	0x0af9, 0x0aff,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3c, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b63,
+	0x0b66, 0x0b6f,
+	0x0b71, 0x0b71,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd0, 0x0bd0,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bef,
+	0x0c00, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c39,
+	0x0c3d, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c58, 0x0c5a,
+	0x0c60, 0x0c63,
+	0x0c66, 0x0c6f,
+	0x0c80, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbc, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce3,
+	0x0ce6, 0x0cef,
+	0x0cf1, 0x0cf2,
+	0x0d00, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4e,
+	0x0d54, 0x0d57,
+	0x0d5f, 0x0d63,
+	0x0d66, 0x0d6f,
+	0x0d7a, 0x0d7f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0de6, 0x0def,
+	0x0df2, 0x0df3,
+	0x0e01, 0x0e3a,
+	0x0e40, 0x0e4e,
+	0x0e50, 0x0e59,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f00,
+	0x0f18, 0x0f19,
+	0x0f20, 0x0f29,
+	0x0f35, 0x0f35,
+	0x0f37, 0x0f37,
+	0x0f39, 0x0f39,
+	0x0f3e, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f71, 0x0f84,
+	0x0f86, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fc6, 0x0fc6,
+	0x1000, 0x1049,
+	0x1050, 0x109d,
+	0x10a0, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x10fa,
+	0x10fc, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135d, 0x135f,
+	0x1369, 0x1371,
+	0x1380, 0x138f,
+	0x13a0, 0x13f5,
+	0x13f8, 0x13fd,
+	0x1401, 0x166c,
+	0x166f, 0x167f,
+	0x1681, 0x169a,
+	0x16a0, 0x16ea,
+	0x16ee, 0x16f8,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+	0x1720, 0x1734,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17d3,
+	0x17d7, 0x17d7,
+	0x17dc, 0x17dd,
+	0x17e0, 0x17e9,
+	0x180b, 0x180d,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191e,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1946, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19da,
+	0x1a00, 0x1a1b,
+	0x1a20, 0x1a5e,
+	0x1a60, 0x1a7c,
+	0x1a7f, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1aa7, 0x1aa7,
+	0x1ab0, 0x1abd,
+	0x1b00, 0x1b4b,
+	0x1b50, 0x1b59,
+	0x1b6b, 0x1b73,
+	0x1b80, 0x1bf3,
+	0x1c00, 0x1c37,
+	0x1c40, 0x1c49,
+	0x1c4d, 0x1c7d,
+	0x1c80, 0x1c88,
+	0x1cd0, 0x1cd2,
+	0x1cd4, 0x1cf9,
+	0x1d00, 0x1df9,
+	0x1dfb, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fbc,
+	0x1fbe, 0x1fbe,
+	0x1fc2, 0x1fc4,
+	0x1fc6, 0x1fcc,
+	0x1fd0, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fe0, 0x1fec,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffc,
+	0x203f, 0x2040,
+	0x2054, 0x2054,
+	0x2071, 0x2071,
+	0x207f, 0x207f,
+	0x2090, 0x209c,
+	0x20d0, 0x20dc,
+	0x20e1, 0x20e1,
+	0x20e5, 0x20f0,
+	0x2102, 0x2102,
+	0x2107, 0x2107,
+	0x210a, 0x2113,
+	0x2115, 0x2115,
+	0x2118, 0x211d,
+	0x2124, 0x2124,
+	0x2126, 0x2126,
+	0x2128, 0x2128,
+	0x212a, 0x2139,
+	0x213c, 0x213f,
+	0x2145, 0x2149,
+	0x214e, 0x214e,
+	0x2160, 0x2188,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2ce4,
+	0x2ceb, 0x2cf3,
+	0x2d00, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d6f,
+	0x2d7f, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2de0, 0x2dff,
+	0x3005, 0x3007,
+	0x3021, 0x302f,
+	0x3031, 0x3035,
+	0x3038, 0x303c,
+	0x3041, 0x3096,
+	0x3099, 0x309f,
+	0x30a1, 0x30fa,
+	0x30fc, 0x30ff,
+	0x3105, 0x312e,
+	0x3131, 0x318e,
+	0x31a0, 0x31ba,
+	0x31f0, 0x31ff,
+	0x3400, 0x4db5,
+	0x4e00, 0x9fea,
+	0xa000, 0xa48c,
+	0xa4d0, 0xa4fd,
+	0xa500, 0xa60c,
+	0xa610, 0xa62b,
+	0xa640, 0xa66f,
+	0xa674, 0xa67d,
+	0xa67f, 0xa6f1,
+	0xa717, 0xa71f,
+	0xa722, 0xa788,
+	0xa78b, 0xa7ae,
+	0xa7b0, 0xa7b7,
+	0xa7f7, 0xa827,
+	0xa840, 0xa873,
+	0xa880, 0xa8c5,
+	0xa8d0, 0xa8d9,
+	0xa8e0, 0xa8f7,
+	0xa8fb, 0xa8fb,
+	0xa8fd, 0xa8fd,
+	0xa900, 0xa92d,
+	0xa930, 0xa953,
+	0xa960, 0xa97c,
+	0xa980, 0xa9c0,
+	0xa9cf, 0xa9d9,
+	0xa9e0, 0xa9fe,
+	0xaa00, 0xaa36,
+	0xaa40, 0xaa4d,
+	0xaa50, 0xaa59,
+	0xaa60, 0xaa76,
+	0xaa7a, 0xaac2,
+	0xaadb, 0xaadd,
+	0xaae0, 0xaaef,
+	0xaaf2, 0xaaf6,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xab30, 0xab5a,
+	0xab5c, 0xab65,
+	0xab70, 0xabea,
+	0xabec, 0xabed,
+	0xabf0, 0xabf9,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xf900, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb28,
+	0xfb2a, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbb1,
+	0xfbd3, 0xfd3d,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdf0, 0xfdfb,
+	0xfe00, 0xfe0f,
+	0xfe20, 0xfe2f,
+	0xfe33, 0xfe34,
+	0xfe4d, 0xfe4f,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xff10, 0xff19,
+	0xff21, 0xff3a,
+	0xff3f, 0xff3f,
+	0xff41, 0xff5a,
+	0xff66, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0x10000, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10140, 0x10174,
+	0x101fd, 0x101fd,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x102e0, 0x102e0,
+	0x10300, 0x1031f,
+	0x1032d, 0x1034a,
+	0x10350, 0x1037a,
+	0x10380, 0x1039d,
+	0x103a0, 0x103c3,
+	0x103c8, 0x103cf,
+	0x103d1, 0x103d5,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x104b0, 0x104d3,
+	0x104d8, 0x104fb,
+	0x10500, 0x10527,
+	0x10530, 0x10563,
+	0x10600, 0x10736,
+	0x10740, 0x10755,
+	0x10760, 0x10767,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10860, 0x10876,
+	0x10880, 0x1089e,
+	0x108e0, 0x108f2,
+	0x108f4, 0x108f5,
+	0x10900, 0x10915,
+	0x10920, 0x10939,
+	0x10980, 0x109b7,
+	0x109be, 0x109bf,
+	0x10a00, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a3f,
+	0x10a60, 0x10a7c,
+	0x10a80, 0x10a9c,
+	0x10ac0, 0x10ac7,
+	0x10ac9, 0x10ae6,
+	0x10b00, 0x10b35,
+	0x10b40, 0x10b55,
+	0x10b60, 0x10b72,
+	0x10b80, 0x10b91,
+	0x10c00, 0x10c48,
+	0x10c80, 0x10cb2,
+	0x10cc0, 0x10cf2,
+	0x11000, 0x11046,
+	0x11066, 0x1106f,
+	0x1107f, 0x110ba,
+	0x110d0, 0x110e8,
+	0x110f0, 0x110f9,
+	0x11100, 0x11134,
+	0x11136, 0x1113f,
+	0x11150, 0x11173,
+	0x11176, 0x11176,
+	0x11180, 0x111c4,
+	0x111ca, 0x111cc,
+	0x111d0, 0x111da,
+	0x111dc, 0x111dc,
+	0x11200, 0x11211,
+	0x11213, 0x11237,
+	0x1123e, 0x1123e,
+	0x11280, 0x11286,
+	0x11288, 0x11288,
+	0x1128a, 0x1128d,
+	0x1128f, 0x1129d,
+	0x1129f, 0x112a8,
+	0x112b0, 0x112ea,
+	0x112f0, 0x112f9,
+	0x11300, 0x11303,
+	0x11305, 0x1130c,
+	0x1130f, 0x11310,
+	0x11313, 0x11328,
+	0x1132a, 0x11330,
+	0x11332, 0x11333,
+	0x11335, 0x11339,
+	0x1133c, 0x11344,
+	0x11347, 0x11348,
+	0x1134b, 0x1134d,
+	0x11350, 0x11350,
+	0x11357, 0x11357,
+	0x1135d, 0x11363,
+	0x11366, 0x1136c,
+	0x11370, 0x11374,
+	0x11400, 0x1144a,
+	0x11450, 0x11459,
+	0x11480, 0x114c5,
+	0x114c7, 0x114c7,
+	0x114d0, 0x114d9,
+	0x11580, 0x115b5,
+	0x115b8, 0x115c0,
+	0x115d8, 0x115dd,
+	0x11600, 0x11640,
+	0x11644, 0x11644,
+	0x11650, 0x11659,
+	0x11680, 0x116b7,
+	0x116c0, 0x116c9,
+	0x11700, 0x11719,
+	0x1171d, 0x1172b,
+	0x11730, 0x11739,
+	0x118a0, 0x118e9,
+	0x118ff, 0x118ff,
+	0x11a00, 0x11a3e,
+	0x11a47, 0x11a47,
+	0x11a50, 0x11a83,
+	0x11a86, 0x11a99,
+	0x11ac0, 0x11af8,
+	0x11c00, 0x11c08,
+	0x11c0a, 0x11c36,
+	0x11c38, 0x11c40,
+	0x11c50, 0x11c59,
+	0x11c72, 0x11c8f,
+	0x11c92, 0x11ca7,
+	0x11ca9, 0x11cb6,
+	0x11d00, 0x11d06,
+	0x11d08, 0x11d09,
+	0x11d0b, 0x11d36,
+	0x11d3a, 0x11d3a,
+	0x11d3c, 0x11d3d,
+	0x11d3f, 0x11d47,
+	0x11d50, 0x11d59,
+	0x12000, 0x12399,
+	0x12400, 0x1246e,
+	0x12480, 0x12543,
+	0x13000, 0x1342e,
+	0x14400, 0x14646,
+	0x16800, 0x16a38,
+	0x16a40, 0x16a5e,
+	0x16a60, 0x16a69,
+	0x16ad0, 0x16aed,
+	0x16af0, 0x16af4,
+	0x16b00, 0x16b36,
+	0x16b40, 0x16b43,
+	0x16b50, 0x16b59,
+	0x16b63, 0x16b77,
+	0x16b7d, 0x16b8f,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f7e,
+	0x16f8f, 0x16f9f,
+	0x16fe0, 0x16fe1,
+	0x17000, 0x187ec,
+	0x18800, 0x18af2,
+	0x1b000, 0x1b11e,
+	0x1b170, 0x1b2fb,
+	0x1bc00, 0x1bc6a,
+	0x1bc70, 0x1bc7c,
+	0x1bc80, 0x1bc88,
+	0x1bc90, 0x1bc99,
+	0x1bc9d, 0x1bc9e,
+	0x1d165, 0x1d169,
+	0x1d16d, 0x1d172,
+	0x1d17b, 0x1d182,
+	0x1d185, 0x1d18b,
+	0x1d1aa, 0x1d1ad,
+	0x1d242, 0x1d244,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d6c0,
+	0x1d6c2, 0x1d6da,
+	0x1d6dc, 0x1d6fa,
+	0x1d6fc, 0x1d714,
+	0x1d716, 0x1d734,
+	0x1d736, 0x1d74e,
+	0x1d750, 0x1d76e,
+	0x1d770, 0x1d788,
+	0x1d78a, 0x1d7a8,
+	0x1d7aa, 0x1d7c2,
+	0x1d7c4, 0x1d7cb,
+	0x1d7ce, 0x1d7ff,
+	0x1da00, 0x1da36,
+	0x1da3b, 0x1da6c,
+	0x1da75, 0x1da75,
+	0x1da84, 0x1da84,
+	0x1da9b, 0x1da9f,
+	0x1daa1, 0x1daaf,
+	0x1e000, 0x1e006,
+	0x1e008, 0x1e018,
+	0x1e01b, 0x1e021,
+	0x1e023, 0x1e024,
+	0x1e026, 0x1e02a,
+	0x1e800, 0x1e8c4,
+	0x1e8d0, 0x1e8d6,
+	0x1e900, 0x1e94a,
+	0x1e950, 0x1e959,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x20000, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2b820, 0x2cea1,
+	0x2ceb0, 0x2ebe0,
+	0x2f800, 0x2fa1d,
+	0xe0100, 0xe01ef,
+}; /* CR_ID_Continue */
+
+/* 'XID_Start': Derived Property */
+static const OnigCodePoint CR_XID_Start[] = {
+	592,
+	0x0041, 0x005a,
+	0x0061, 0x007a,
+	0x00aa, 0x00aa,
+	0x00b5, 0x00b5,
+	0x00ba, 0x00ba,
+	0x00c0, 0x00d6,
+	0x00d8, 0x00f6,
+	0x00f8, 0x02c1,
+	0x02c6, 0x02d1,
+	0x02e0, 0x02e4,
+	0x02ec, 0x02ec,
+	0x02ee, 0x02ee,
+	0x0370, 0x0374,
+	0x0376, 0x0377,
+	0x037b, 0x037d,
+	0x037f, 0x037f,
+	0x0386, 0x0386,
+	0x0388, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03f5,
+	0x03f7, 0x0481,
+	0x048a, 0x052f,
+	0x0531, 0x0556,
+	0x0559, 0x0559,
+	0x0561, 0x0587,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f2,
+	0x0620, 0x064a,
+	0x066e, 0x066f,
+	0x0671, 0x06d3,
+	0x06d5, 0x06d5,
+	0x06e5, 0x06e6,
+	0x06ee, 0x06ef,
+	0x06fa, 0x06fc,
+	0x06ff, 0x06ff,
+	0x0710, 0x0710,
+	0x0712, 0x072f,
+	0x074d, 0x07a5,
+	0x07b1, 0x07b1,
+	0x07ca, 0x07ea,
+	0x07f4, 0x07f5,
+	0x07fa, 0x07fa,
+	0x0800, 0x0815,
+	0x081a, 0x081a,
+	0x0824, 0x0824,
+	0x0828, 0x0828,
+	0x0840, 0x0858,
+	0x0860, 0x086a,
+	0x08a0, 0x08b4,
+	0x08b6, 0x08bd,
+	0x0904, 0x0939,
+	0x093d, 0x093d,
+	0x0950, 0x0950,
+	0x0958, 0x0961,
+	0x0971, 0x0980,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bd, 0x09bd,
+	0x09ce, 0x09ce,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e1,
+	0x09f0, 0x09f1,
+	0x09fc, 0x09fc,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a72, 0x0a74,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abd, 0x0abd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae1,
+	0x0af9, 0x0af9,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3d, 0x0b3d,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b61,
+	0x0b71, 0x0b71,
+	0x0b83, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bd0, 0x0bd0,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c39,
+	0x0c3d, 0x0c3d,
+	0x0c58, 0x0c5a,
+	0x0c60, 0x0c61,
+	0x0c80, 0x0c80,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbd, 0x0cbd,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce1,
+	0x0cf1, 0x0cf2,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d3a,
+	0x0d3d, 0x0d3d,
+	0x0d4e, 0x0d4e,
+	0x0d54, 0x0d56,
+	0x0d5f, 0x0d61,
+	0x0d7a, 0x0d7f,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0e01, 0x0e30,
+	0x0e32, 0x0e32,
+	0x0e40, 0x0e46,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb0,
+	0x0eb2, 0x0eb2,
+	0x0ebd, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f00,
+	0x0f40, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f88, 0x0f8c,
+	0x1000, 0x102a,
+	0x103f, 0x103f,
+	0x1050, 0x1055,
+	0x105a, 0x105d,
+	0x1061, 0x1061,
+	0x1065, 0x1066,
+	0x106e, 0x1070,
+	0x1075, 0x1081,
+	0x108e, 0x108e,
+	0x10a0, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x10fa,
+	0x10fc, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x1380, 0x138f,
+	0x13a0, 0x13f5,
+	0x13f8, 0x13fd,
+	0x1401, 0x166c,
+	0x166f, 0x167f,
+	0x1681, 0x169a,
+	0x16a0, 0x16ea,
+	0x16ee, 0x16f8,
+	0x1700, 0x170c,
+	0x170e, 0x1711,
+	0x1720, 0x1731,
+	0x1740, 0x1751,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1780, 0x17b3,
+	0x17d7, 0x17d7,
+	0x17dc, 0x17dc,
+	0x1820, 0x1877,
+	0x1880, 0x18a8,
+	0x18aa, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191e,
+	0x1950, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x1a00, 0x1a16,
+	0x1a20, 0x1a54,
+	0x1aa7, 0x1aa7,
+	0x1b05, 0x1b33,
+	0x1b45, 0x1b4b,
+	0x1b83, 0x1ba0,
+	0x1bae, 0x1baf,
+	0x1bba, 0x1be5,
+	0x1c00, 0x1c23,
+	0x1c4d, 0x1c4f,
+	0x1c5a, 0x1c7d,
+	0x1c80, 0x1c88,
+	0x1ce9, 0x1cec,
+	0x1cee, 0x1cf1,
+	0x1cf5, 0x1cf6,
+	0x1d00, 0x1dbf,
+	0x1e00, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fbc,
+	0x1fbe, 0x1fbe,
+	0x1fc2, 0x1fc4,
+	0x1fc6, 0x1fcc,
+	0x1fd0, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fe0, 0x1fec,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffc,
+	0x2071, 0x2071,
+	0x207f, 0x207f,
+	0x2090, 0x209c,
+	0x2102, 0x2102,
+	0x2107, 0x2107,
+	0x210a, 0x2113,
+	0x2115, 0x2115,
+	0x2118, 0x211d,
+	0x2124, 0x2124,
+	0x2126, 0x2126,
+	0x2128, 0x2128,
+	0x212a, 0x2139,
+	0x213c, 0x213f,
+	0x2145, 0x2149,
+	0x214e, 0x214e,
+	0x2160, 0x2188,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2ce4,
+	0x2ceb, 0x2cee,
+	0x2cf2, 0x2cf3,
+	0x2d00, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d6f,
+	0x2d80, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x3005, 0x3007,
+	0x3021, 0x3029,
+	0x3031, 0x3035,
+	0x3038, 0x303c,
+	0x3041, 0x3096,
+	0x309d, 0x309f,
+	0x30a1, 0x30fa,
+	0x30fc, 0x30ff,
+	0x3105, 0x312e,
+	0x3131, 0x318e,
+	0x31a0, 0x31ba,
+	0x31f0, 0x31ff,
+	0x3400, 0x4db5,
+	0x4e00, 0x9fea,
+	0xa000, 0xa48c,
+	0xa4d0, 0xa4fd,
+	0xa500, 0xa60c,
+	0xa610, 0xa61f,
+	0xa62a, 0xa62b,
+	0xa640, 0xa66e,
+	0xa67f, 0xa69d,
+	0xa6a0, 0xa6ef,
+	0xa717, 0xa71f,
+	0xa722, 0xa788,
+	0xa78b, 0xa7ae,
+	0xa7b0, 0xa7b7,
+	0xa7f7, 0xa801,
+	0xa803, 0xa805,
+	0xa807, 0xa80a,
+	0xa80c, 0xa822,
+	0xa840, 0xa873,
+	0xa882, 0xa8b3,
+	0xa8f2, 0xa8f7,
+	0xa8fb, 0xa8fb,
+	0xa8fd, 0xa8fd,
+	0xa90a, 0xa925,
+	0xa930, 0xa946,
+	0xa960, 0xa97c,
+	0xa984, 0xa9b2,
+	0xa9cf, 0xa9cf,
+	0xa9e0, 0xa9e4,
+	0xa9e6, 0xa9ef,
+	0xa9fa, 0xa9fe,
+	0xaa00, 0xaa28,
+	0xaa40, 0xaa42,
+	0xaa44, 0xaa4b,
+	0xaa60, 0xaa76,
+	0xaa7a, 0xaa7a,
+	0xaa7e, 0xaaaf,
+	0xaab1, 0xaab1,
+	0xaab5, 0xaab6,
+	0xaab9, 0xaabd,
+	0xaac0, 0xaac0,
+	0xaac2, 0xaac2,
+	0xaadb, 0xaadd,
+	0xaae0, 0xaaea,
+	0xaaf2, 0xaaf4,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xab30, 0xab5a,
+	0xab5c, 0xab65,
+	0xab70, 0xabe2,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xf900, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb1d,
+	0xfb1f, 0xfb28,
+	0xfb2a, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbb1,
+	0xfbd3, 0xfc5d,
+	0xfc64, 0xfd3d,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdf0, 0xfdf9,
+	0xfe71, 0xfe71,
+	0xfe73, 0xfe73,
+	0xfe77, 0xfe77,
+	0xfe79, 0xfe79,
+	0xfe7b, 0xfe7b,
+	0xfe7d, 0xfe7d,
+	0xfe7f, 0xfefc,
+	0xff21, 0xff3a,
+	0xff41, 0xff5a,
+	0xff66, 0xff9d,
+	0xffa0, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0x10000, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10140, 0x10174,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x10300, 0x1031f,
+	0x1032d, 0x1034a,
+	0x10350, 0x10375,
+	0x10380, 0x1039d,
+	0x103a0, 0x103c3,
+	0x103c8, 0x103cf,
+	0x103d1, 0x103d5,
+	0x10400, 0x1049d,
+	0x104b0, 0x104d3,
+	0x104d8, 0x104fb,
+	0x10500, 0x10527,
+	0x10530, 0x10563,
+	0x10600, 0x10736,
+	0x10740, 0x10755,
+	0x10760, 0x10767,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10860, 0x10876,
+	0x10880, 0x1089e,
+	0x108e0, 0x108f2,
+	0x108f4, 0x108f5,
+	0x10900, 0x10915,
+	0x10920, 0x10939,
+	0x10980, 0x109b7,
+	0x109be, 0x109bf,
+	0x10a00, 0x10a00,
+	0x10a10, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a60, 0x10a7c,
+	0x10a80, 0x10a9c,
+	0x10ac0, 0x10ac7,
+	0x10ac9, 0x10ae4,
+	0x10b00, 0x10b35,
+	0x10b40, 0x10b55,
+	0x10b60, 0x10b72,
+	0x10b80, 0x10b91,
+	0x10c00, 0x10c48,
+	0x10c80, 0x10cb2,
+	0x10cc0, 0x10cf2,
+	0x11003, 0x11037,
+	0x11083, 0x110af,
+	0x110d0, 0x110e8,
+	0x11103, 0x11126,
+	0x11150, 0x11172,
+	0x11176, 0x11176,
+	0x11183, 0x111b2,
+	0x111c1, 0x111c4,
+	0x111da, 0x111da,
+	0x111dc, 0x111dc,
+	0x11200, 0x11211,
+	0x11213, 0x1122b,
+	0x11280, 0x11286,
+	0x11288, 0x11288,
+	0x1128a, 0x1128d,
+	0x1128f, 0x1129d,
+	0x1129f, 0x112a8,
+	0x112b0, 0x112de,
+	0x11305, 0x1130c,
+	0x1130f, 0x11310,
+	0x11313, 0x11328,
+	0x1132a, 0x11330,
+	0x11332, 0x11333,
+	0x11335, 0x11339,
+	0x1133d, 0x1133d,
+	0x11350, 0x11350,
+	0x1135d, 0x11361,
+	0x11400, 0x11434,
+	0x11447, 0x1144a,
+	0x11480, 0x114af,
+	0x114c4, 0x114c5,
+	0x114c7, 0x114c7,
+	0x11580, 0x115ae,
+	0x115d8, 0x115db,
+	0x11600, 0x1162f,
+	0x11644, 0x11644,
+	0x11680, 0x116aa,
+	0x11700, 0x11719,
+	0x118a0, 0x118df,
+	0x118ff, 0x118ff,
+	0x11a00, 0x11a00,
+	0x11a0b, 0x11a32,
+	0x11a3a, 0x11a3a,
+	0x11a50, 0x11a50,
+	0x11a5c, 0x11a83,
+	0x11a86, 0x11a89,
+	0x11ac0, 0x11af8,
+	0x11c00, 0x11c08,
+	0x11c0a, 0x11c2e,
+	0x11c40, 0x11c40,
+	0x11c72, 0x11c8f,
+	0x11d00, 0x11d06,
+	0x11d08, 0x11d09,
+	0x11d0b, 0x11d30,
+	0x11d46, 0x11d46,
+	0x12000, 0x12399,
+	0x12400, 0x1246e,
+	0x12480, 0x12543,
+	0x13000, 0x1342e,
+	0x14400, 0x14646,
+	0x16800, 0x16a38,
+	0x16a40, 0x16a5e,
+	0x16ad0, 0x16aed,
+	0x16b00, 0x16b2f,
+	0x16b40, 0x16b43,
+	0x16b63, 0x16b77,
+	0x16b7d, 0x16b8f,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f50,
+	0x16f93, 0x16f9f,
+	0x16fe0, 0x16fe1,
+	0x17000, 0x187ec,
+	0x18800, 0x18af2,
+	0x1b000, 0x1b11e,
+	0x1b170, 0x1b2fb,
+	0x1bc00, 0x1bc6a,
+	0x1bc70, 0x1bc7c,
+	0x1bc80, 0x1bc88,
+	0x1bc90, 0x1bc99,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d6c0,
+	0x1d6c2, 0x1d6da,
+	0x1d6dc, 0x1d6fa,
+	0x1d6fc, 0x1d714,
+	0x1d716, 0x1d734,
+	0x1d736, 0x1d74e,
+	0x1d750, 0x1d76e,
+	0x1d770, 0x1d788,
+	0x1d78a, 0x1d7a8,
+	0x1d7aa, 0x1d7c2,
+	0x1d7c4, 0x1d7cb,
+	0x1e800, 0x1e8c4,
+	0x1e900, 0x1e943,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x20000, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2b820, 0x2cea1,
+	0x2ceb0, 0x2ebe0,
+	0x2f800, 0x2fa1d,
+}; /* CR_XID_Start */
+
+/* 'XID_Continue': Derived Property */
+static const OnigCodePoint CR_XID_Continue[] = {
+	696,
+	0x0030, 0x0039,
+	0x0041, 0x005a,
+	0x005f, 0x005f,
+	0x0061, 0x007a,
+	0x00aa, 0x00aa,
+	0x00b5, 0x00b5,
+	0x00b7, 0x00b7,
+	0x00ba, 0x00ba,
+	0x00c0, 0x00d6,
+	0x00d8, 0x00f6,
+	0x00f8, 0x02c1,
+	0x02c6, 0x02d1,
+	0x02e0, 0x02e4,
+	0x02ec, 0x02ec,
+	0x02ee, 0x02ee,
+	0x0300, 0x0374,
+	0x0376, 0x0377,
+	0x037b, 0x037d,
+	0x037f, 0x037f,
+	0x0386, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03f5,
+	0x03f7, 0x0481,
+	0x0483, 0x0487,
+	0x048a, 0x052f,
+	0x0531, 0x0556,
+	0x0559, 0x0559,
+	0x0561, 0x0587,
+	0x0591, 0x05bd,
+	0x05bf, 0x05bf,
+	0x05c1, 0x05c2,
+	0x05c4, 0x05c5,
+	0x05c7, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f2,
+	0x0610, 0x061a,
+	0x0620, 0x0669,
+	0x066e, 0x06d3,
+	0x06d5, 0x06dc,
+	0x06df, 0x06e8,
+	0x06ea, 0x06fc,
+	0x06ff, 0x06ff,
+	0x0710, 0x074a,
+	0x074d, 0x07b1,
+	0x07c0, 0x07f5,
+	0x07fa, 0x07fa,
+	0x0800, 0x082d,
+	0x0840, 0x085b,
+	0x0860, 0x086a,
+	0x08a0, 0x08b4,
+	0x08b6, 0x08bd,
+	0x08d4, 0x08e1,
+	0x08e3, 0x0963,
+	0x0966, 0x096f,
+	0x0971, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09f1,
+	0x09fc, 0x09fc,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a75,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0aef,
+	0x0af9, 0x0aff,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3c, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b63,
+	0x0b66, 0x0b6f,
+	0x0b71, 0x0b71,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd0, 0x0bd0,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bef,
+	0x0c00, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c39,
+	0x0c3d, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c58, 0x0c5a,
+	0x0c60, 0x0c63,
+	0x0c66, 0x0c6f,
+	0x0c80, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbc, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce3,
+	0x0ce6, 0x0cef,
+	0x0cf1, 0x0cf2,
+	0x0d00, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4e,
+	0x0d54, 0x0d57,
+	0x0d5f, 0x0d63,
+	0x0d66, 0x0d6f,
+	0x0d7a, 0x0d7f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0de6, 0x0def,
+	0x0df2, 0x0df3,
+	0x0e01, 0x0e3a,
+	0x0e40, 0x0e4e,
+	0x0e50, 0x0e59,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f00,
+	0x0f18, 0x0f19,
+	0x0f20, 0x0f29,
+	0x0f35, 0x0f35,
+	0x0f37, 0x0f37,
+	0x0f39, 0x0f39,
+	0x0f3e, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f71, 0x0f84,
+	0x0f86, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fc6, 0x0fc6,
+	0x1000, 0x1049,
+	0x1050, 0x109d,
+	0x10a0, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x10fa,
+	0x10fc, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135d, 0x135f,
+	0x1369, 0x1371,
+	0x1380, 0x138f,
+	0x13a0, 0x13f5,
+	0x13f8, 0x13fd,
+	0x1401, 0x166c,
+	0x166f, 0x167f,
+	0x1681, 0x169a,
+	0x16a0, 0x16ea,
+	0x16ee, 0x16f8,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+	0x1720, 0x1734,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17d3,
+	0x17d7, 0x17d7,
+	0x17dc, 0x17dd,
+	0x17e0, 0x17e9,
+	0x180b, 0x180d,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191e,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1946, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19da,
+	0x1a00, 0x1a1b,
+	0x1a20, 0x1a5e,
+	0x1a60, 0x1a7c,
+	0x1a7f, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1aa7, 0x1aa7,
+	0x1ab0, 0x1abd,
+	0x1b00, 0x1b4b,
+	0x1b50, 0x1b59,
+	0x1b6b, 0x1b73,
+	0x1b80, 0x1bf3,
+	0x1c00, 0x1c37,
+	0x1c40, 0x1c49,
+	0x1c4d, 0x1c7d,
+	0x1c80, 0x1c88,
+	0x1cd0, 0x1cd2,
+	0x1cd4, 0x1cf9,
+	0x1d00, 0x1df9,
+	0x1dfb, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fbc,
+	0x1fbe, 0x1fbe,
+	0x1fc2, 0x1fc4,
+	0x1fc6, 0x1fcc,
+	0x1fd0, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fe0, 0x1fec,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffc,
+	0x203f, 0x2040,
+	0x2054, 0x2054,
+	0x2071, 0x2071,
+	0x207f, 0x207f,
+	0x2090, 0x209c,
+	0x20d0, 0x20dc,
+	0x20e1, 0x20e1,
+	0x20e5, 0x20f0,
+	0x2102, 0x2102,
+	0x2107, 0x2107,
+	0x210a, 0x2113,
+	0x2115, 0x2115,
+	0x2118, 0x211d,
+	0x2124, 0x2124,
+	0x2126, 0x2126,
+	0x2128, 0x2128,
+	0x212a, 0x2139,
+	0x213c, 0x213f,
+	0x2145, 0x2149,
+	0x214e, 0x214e,
+	0x2160, 0x2188,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2ce4,
+	0x2ceb, 0x2cf3,
+	0x2d00, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d6f,
+	0x2d7f, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2de0, 0x2dff,
+	0x3005, 0x3007,
+	0x3021, 0x302f,
+	0x3031, 0x3035,
+	0x3038, 0x303c,
+	0x3041, 0x3096,
+	0x3099, 0x309a,
+	0x309d, 0x309f,
+	0x30a1, 0x30fa,
+	0x30fc, 0x30ff,
+	0x3105, 0x312e,
+	0x3131, 0x318e,
+	0x31a0, 0x31ba,
+	0x31f0, 0x31ff,
+	0x3400, 0x4db5,
+	0x4e00, 0x9fea,
+	0xa000, 0xa48c,
+	0xa4d0, 0xa4fd,
+	0xa500, 0xa60c,
+	0xa610, 0xa62b,
+	0xa640, 0xa66f,
+	0xa674, 0xa67d,
+	0xa67f, 0xa6f1,
+	0xa717, 0xa71f,
+	0xa722, 0xa788,
+	0xa78b, 0xa7ae,
+	0xa7b0, 0xa7b7,
+	0xa7f7, 0xa827,
+	0xa840, 0xa873,
+	0xa880, 0xa8c5,
+	0xa8d0, 0xa8d9,
+	0xa8e0, 0xa8f7,
+	0xa8fb, 0xa8fb,
+	0xa8fd, 0xa8fd,
+	0xa900, 0xa92d,
+	0xa930, 0xa953,
+	0xa960, 0xa97c,
+	0xa980, 0xa9c0,
+	0xa9cf, 0xa9d9,
+	0xa9e0, 0xa9fe,
+	0xaa00, 0xaa36,
+	0xaa40, 0xaa4d,
+	0xaa50, 0xaa59,
+	0xaa60, 0xaa76,
+	0xaa7a, 0xaac2,
+	0xaadb, 0xaadd,
+	0xaae0, 0xaaef,
+	0xaaf2, 0xaaf6,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xab30, 0xab5a,
+	0xab5c, 0xab65,
+	0xab70, 0xabea,
+	0xabec, 0xabed,
+	0xabf0, 0xabf9,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xf900, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb28,
+	0xfb2a, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbb1,
+	0xfbd3, 0xfc5d,
+	0xfc64, 0xfd3d,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdf0, 0xfdf9,
+	0xfe00, 0xfe0f,
+	0xfe20, 0xfe2f,
+	0xfe33, 0xfe34,
+	0xfe4d, 0xfe4f,
+	0xfe71, 0xfe71,
+	0xfe73, 0xfe73,
+	0xfe77, 0xfe77,
+	0xfe79, 0xfe79,
+	0xfe7b, 0xfe7b,
+	0xfe7d, 0xfe7d,
+	0xfe7f, 0xfefc,
+	0xff10, 0xff19,
+	0xff21, 0xff3a,
+	0xff3f, 0xff3f,
+	0xff41, 0xff5a,
+	0xff66, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0x10000, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10140, 0x10174,
+	0x101fd, 0x101fd,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x102e0, 0x102e0,
+	0x10300, 0x1031f,
+	0x1032d, 0x1034a,
+	0x10350, 0x1037a,
+	0x10380, 0x1039d,
+	0x103a0, 0x103c3,
+	0x103c8, 0x103cf,
+	0x103d1, 0x103d5,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x104b0, 0x104d3,
+	0x104d8, 0x104fb,
+	0x10500, 0x10527,
+	0x10530, 0x10563,
+	0x10600, 0x10736,
+	0x10740, 0x10755,
+	0x10760, 0x10767,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10860, 0x10876,
+	0x10880, 0x1089e,
+	0x108e0, 0x108f2,
+	0x108f4, 0x108f5,
+	0x10900, 0x10915,
+	0x10920, 0x10939,
+	0x10980, 0x109b7,
+	0x109be, 0x109bf,
+	0x10a00, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a3f,
+	0x10a60, 0x10a7c,
+	0x10a80, 0x10a9c,
+	0x10ac0, 0x10ac7,
+	0x10ac9, 0x10ae6,
+	0x10b00, 0x10b35,
+	0x10b40, 0x10b55,
+	0x10b60, 0x10b72,
+	0x10b80, 0x10b91,
+	0x10c00, 0x10c48,
+	0x10c80, 0x10cb2,
+	0x10cc0, 0x10cf2,
+	0x11000, 0x11046,
+	0x11066, 0x1106f,
+	0x1107f, 0x110ba,
+	0x110d0, 0x110e8,
+	0x110f0, 0x110f9,
+	0x11100, 0x11134,
+	0x11136, 0x1113f,
+	0x11150, 0x11173,
+	0x11176, 0x11176,
+	0x11180, 0x111c4,
+	0x111ca, 0x111cc,
+	0x111d0, 0x111da,
+	0x111dc, 0x111dc,
+	0x11200, 0x11211,
+	0x11213, 0x11237,
+	0x1123e, 0x1123e,
+	0x11280, 0x11286,
+	0x11288, 0x11288,
+	0x1128a, 0x1128d,
+	0x1128f, 0x1129d,
+	0x1129f, 0x112a8,
+	0x112b0, 0x112ea,
+	0x112f0, 0x112f9,
+	0x11300, 0x11303,
+	0x11305, 0x1130c,
+	0x1130f, 0x11310,
+	0x11313, 0x11328,
+	0x1132a, 0x11330,
+	0x11332, 0x11333,
+	0x11335, 0x11339,
+	0x1133c, 0x11344,
+	0x11347, 0x11348,
+	0x1134b, 0x1134d,
+	0x11350, 0x11350,
+	0x11357, 0x11357,
+	0x1135d, 0x11363,
+	0x11366, 0x1136c,
+	0x11370, 0x11374,
+	0x11400, 0x1144a,
+	0x11450, 0x11459,
+	0x11480, 0x114c5,
+	0x114c7, 0x114c7,
+	0x114d0, 0x114d9,
+	0x11580, 0x115b5,
+	0x115b8, 0x115c0,
+	0x115d8, 0x115dd,
+	0x11600, 0x11640,
+	0x11644, 0x11644,
+	0x11650, 0x11659,
+	0x11680, 0x116b7,
+	0x116c0, 0x116c9,
+	0x11700, 0x11719,
+	0x1171d, 0x1172b,
+	0x11730, 0x11739,
+	0x118a0, 0x118e9,
+	0x118ff, 0x118ff,
+	0x11a00, 0x11a3e,
+	0x11a47, 0x11a47,
+	0x11a50, 0x11a83,
+	0x11a86, 0x11a99,
+	0x11ac0, 0x11af8,
+	0x11c00, 0x11c08,
+	0x11c0a, 0x11c36,
+	0x11c38, 0x11c40,
+	0x11c50, 0x11c59,
+	0x11c72, 0x11c8f,
+	0x11c92, 0x11ca7,
+	0x11ca9, 0x11cb6,
+	0x11d00, 0x11d06,
+	0x11d08, 0x11d09,
+	0x11d0b, 0x11d36,
+	0x11d3a, 0x11d3a,
+	0x11d3c, 0x11d3d,
+	0x11d3f, 0x11d47,
+	0x11d50, 0x11d59,
+	0x12000, 0x12399,
+	0x12400, 0x1246e,
+	0x12480, 0x12543,
+	0x13000, 0x1342e,
+	0x14400, 0x14646,
+	0x16800, 0x16a38,
+	0x16a40, 0x16a5e,
+	0x16a60, 0x16a69,
+	0x16ad0, 0x16aed,
+	0x16af0, 0x16af4,
+	0x16b00, 0x16b36,
+	0x16b40, 0x16b43,
+	0x16b50, 0x16b59,
+	0x16b63, 0x16b77,
+	0x16b7d, 0x16b8f,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f7e,
+	0x16f8f, 0x16f9f,
+	0x16fe0, 0x16fe1,
+	0x17000, 0x187ec,
+	0x18800, 0x18af2,
+	0x1b000, 0x1b11e,
+	0x1b170, 0x1b2fb,
+	0x1bc00, 0x1bc6a,
+	0x1bc70, 0x1bc7c,
+	0x1bc80, 0x1bc88,
+	0x1bc90, 0x1bc99,
+	0x1bc9d, 0x1bc9e,
+	0x1d165, 0x1d169,
+	0x1d16d, 0x1d172,
+	0x1d17b, 0x1d182,
+	0x1d185, 0x1d18b,
+	0x1d1aa, 0x1d1ad,
+	0x1d242, 0x1d244,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d6c0,
+	0x1d6c2, 0x1d6da,
+	0x1d6dc, 0x1d6fa,
+	0x1d6fc, 0x1d714,
+	0x1d716, 0x1d734,
+	0x1d736, 0x1d74e,
+	0x1d750, 0x1d76e,
+	0x1d770, 0x1d788,
+	0x1d78a, 0x1d7a8,
+	0x1d7aa, 0x1d7c2,
+	0x1d7c4, 0x1d7cb,
+	0x1d7ce, 0x1d7ff,
+	0x1da00, 0x1da36,
+	0x1da3b, 0x1da6c,
+	0x1da75, 0x1da75,
+	0x1da84, 0x1da84,
+	0x1da9b, 0x1da9f,
+	0x1daa1, 0x1daaf,
+	0x1e000, 0x1e006,
+	0x1e008, 0x1e018,
+	0x1e01b, 0x1e021,
+	0x1e023, 0x1e024,
+	0x1e026, 0x1e02a,
+	0x1e800, 0x1e8c4,
+	0x1e8d0, 0x1e8d6,
+	0x1e900, 0x1e94a,
+	0x1e950, 0x1e959,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x20000, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2b820, 0x2cea1,
+	0x2ceb0, 0x2ebe0,
+	0x2f800, 0x2fa1d,
+	0xe0100, 0xe01ef,
+}; /* CR_XID_Continue */
+
+/* 'Default_Ignorable_Code_Point': Derived Property */
+static const OnigCodePoint CR_Default_Ignorable_Code_Point[] = {
+	17,
+	0x00ad, 0x00ad,
+	0x034f, 0x034f,
+	0x061c, 0x061c,
+	0x115f, 0x1160,
+	0x17b4, 0x17b5,
+	0x180b, 0x180e,
+	0x200b, 0x200f,
+	0x202a, 0x202e,
+	0x2060, 0x206f,
+	0x3164, 0x3164,
+	0xfe00, 0xfe0f,
+	0xfeff, 0xfeff,
+	0xffa0, 0xffa0,
+	0xfff0, 0xfff8,
+	0x1bca0, 0x1bca3,
+	0x1d173, 0x1d17a,
+	0xe0000, 0xe0fff,
+}; /* CR_Default_Ignorable_Code_Point */
+
+/* 'Grapheme_Extend': Derived Property */
+static const OnigCodePoint CR_Grapheme_Extend[] = {
+	319,
+	0x0300, 0x036f,
+	0x0483, 0x0489,
+	0x0591, 0x05bd,
+	0x05bf, 0x05bf,
+	0x05c1, 0x05c2,
+	0x05c4, 0x05c5,
+	0x05c7, 0x05c7,
+	0x0610, 0x061a,
+	0x064b, 0x065f,
+	0x0670, 0x0670,
+	0x06d6, 0x06dc,
+	0x06df, 0x06e4,
+	0x06e7, 0x06e8,
+	0x06ea, 0x06ed,
+	0x0711, 0x0711,
+	0x0730, 0x074a,
+	0x07a6, 0x07b0,
+	0x07eb, 0x07f3,
+	0x0816, 0x0819,
+	0x081b, 0x0823,
+	0x0825, 0x0827,
+	0x0829, 0x082d,
+	0x0859, 0x085b,
+	0x08d4, 0x08e1,
+	0x08e3, 0x0902,
+	0x093a, 0x093a,
+	0x093c, 0x093c,
+	0x0941, 0x0948,
+	0x094d, 0x094d,
+	0x0951, 0x0957,
+	0x0962, 0x0963,
+	0x0981, 0x0981,
+	0x09bc, 0x09bc,
+	0x09be, 0x09be,
+	0x09c1, 0x09c4,
+	0x09cd, 0x09cd,
+	0x09d7, 0x09d7,
+	0x09e2, 0x09e3,
+	0x0a01, 0x0a02,
+	0x0a3c, 0x0a3c,
+	0x0a41, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a70, 0x0a71,
+	0x0a75, 0x0a75,
+	0x0a81, 0x0a82,
+	0x0abc, 0x0abc,
+	0x0ac1, 0x0ac5,
+	0x0ac7, 0x0ac8,
+	0x0acd, 0x0acd,
+	0x0ae2, 0x0ae3,
+	0x0afa, 0x0aff,
+	0x0b01, 0x0b01,
+	0x0b3c, 0x0b3c,
+	0x0b3e, 0x0b3f,
+	0x0b41, 0x0b44,
+	0x0b4d, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b62, 0x0b63,
+	0x0b82, 0x0b82,
+	0x0bbe, 0x0bbe,
+	0x0bc0, 0x0bc0,
+	0x0bcd, 0x0bcd,
+	0x0bd7, 0x0bd7,
+	0x0c00, 0x0c00,
+	0x0c3e, 0x0c40,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c62, 0x0c63,
+	0x0c81, 0x0c81,
+	0x0cbc, 0x0cbc,
+	0x0cbf, 0x0cbf,
+	0x0cc2, 0x0cc2,
+	0x0cc6, 0x0cc6,
+	0x0ccc, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0ce2, 0x0ce3,
+	0x0d00, 0x0d01,
+	0x0d3b, 0x0d3c,
+	0x0d3e, 0x0d3e,
+	0x0d41, 0x0d44,
+	0x0d4d, 0x0d4d,
+	0x0d57, 0x0d57,
+	0x0d62, 0x0d63,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dcf,
+	0x0dd2, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0ddf, 0x0ddf,
+	0x0e31, 0x0e31,
+	0x0e34, 0x0e3a,
+	0x0e47, 0x0e4e,
+	0x0eb1, 0x0eb1,
+	0x0eb4, 0x0eb9,
+	0x0ebb, 0x0ebc,
+	0x0ec8, 0x0ecd,
+	0x0f18, 0x0f19,
+	0x0f35, 0x0f35,
+	0x0f37, 0x0f37,
+	0x0f39, 0x0f39,
+	0x0f71, 0x0f7e,
+	0x0f80, 0x0f84,
+	0x0f86, 0x0f87,
+	0x0f8d, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fc6, 0x0fc6,
+	0x102d, 0x1030,
+	0x1032, 0x1037,
+	0x1039, 0x103a,
+	0x103d, 0x103e,
+	0x1058, 0x1059,
+	0x105e, 0x1060,
+	0x1071, 0x1074,
+	0x1082, 0x1082,
+	0x1085, 0x1086,
+	0x108d, 0x108d,
+	0x109d, 0x109d,
+	0x135d, 0x135f,
+	0x1712, 0x1714,
+	0x1732, 0x1734,
+	0x1752, 0x1753,
+	0x1772, 0x1773,
+	0x17b4, 0x17b5,
+	0x17b7, 0x17bd,
+	0x17c6, 0x17c6,
+	0x17c9, 0x17d3,
+	0x17dd, 0x17dd,
+	0x180b, 0x180d,
+	0x1885, 0x1886,
+	0x18a9, 0x18a9,
+	0x1920, 0x1922,
+	0x1927, 0x1928,
+	0x1932, 0x1932,
+	0x1939, 0x193b,
+	0x1a17, 0x1a18,
+	0x1a1b, 0x1a1b,
+	0x1a56, 0x1a56,
+	0x1a58, 0x1a5e,
+	0x1a60, 0x1a60,
+	0x1a62, 0x1a62,
+	0x1a65, 0x1a6c,
+	0x1a73, 0x1a7c,
+	0x1a7f, 0x1a7f,
+	0x1ab0, 0x1abe,
+	0x1b00, 0x1b03,
+	0x1b34, 0x1b34,
+	0x1b36, 0x1b3a,
+	0x1b3c, 0x1b3c,
+	0x1b42, 0x1b42,
+	0x1b6b, 0x1b73,
+	0x1b80, 0x1b81,
+	0x1ba2, 0x1ba5,
+	0x1ba8, 0x1ba9,
+	0x1bab, 0x1bad,
+	0x1be6, 0x1be6,
+	0x1be8, 0x1be9,
+	0x1bed, 0x1bed,
+	0x1bef, 0x1bf1,
+	0x1c2c, 0x1c33,
+	0x1c36, 0x1c37,
+	0x1cd0, 0x1cd2,
+	0x1cd4, 0x1ce0,
+	0x1ce2, 0x1ce8,
+	0x1ced, 0x1ced,
+	0x1cf4, 0x1cf4,
+	0x1cf8, 0x1cf9,
+	0x1dc0, 0x1df9,
+	0x1dfb, 0x1dff,
+	0x200c, 0x200c,
+	0x20d0, 0x20f0,
+	0x2cef, 0x2cf1,
+	0x2d7f, 0x2d7f,
+	0x2de0, 0x2dff,
+	0x302a, 0x302f,
+	0x3099, 0x309a,
+	0xa66f, 0xa672,
+	0xa674, 0xa67d,
+	0xa69e, 0xa69f,
+	0xa6f0, 0xa6f1,
+	0xa802, 0xa802,
+	0xa806, 0xa806,
+	0xa80b, 0xa80b,
+	0xa825, 0xa826,
+	0xa8c4, 0xa8c5,
+	0xa8e0, 0xa8f1,
+	0xa926, 0xa92d,
+	0xa947, 0xa951,
+	0xa980, 0xa982,
+	0xa9b3, 0xa9b3,
+	0xa9b6, 0xa9b9,
+	0xa9bc, 0xa9bc,
+	0xa9e5, 0xa9e5,
+	0xaa29, 0xaa2e,
+	0xaa31, 0xaa32,
+	0xaa35, 0xaa36,
+	0xaa43, 0xaa43,
+	0xaa4c, 0xaa4c,
+	0xaa7c, 0xaa7c,
+	0xaab0, 0xaab0,
+	0xaab2, 0xaab4,
+	0xaab7, 0xaab8,
+	0xaabe, 0xaabf,
+	0xaac1, 0xaac1,
+	0xaaec, 0xaaed,
+	0xaaf6, 0xaaf6,
+	0xabe5, 0xabe5,
+	0xabe8, 0xabe8,
+	0xabed, 0xabed,
+	0xfb1e, 0xfb1e,
+	0xfe00, 0xfe0f,
+	0xfe20, 0xfe2f,
+	0xff9e, 0xff9f,
+	0x101fd, 0x101fd,
+	0x102e0, 0x102e0,
+	0x10376, 0x1037a,
+	0x10a01, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a0f,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a3f,
+	0x10ae5, 0x10ae6,
+	0x11001, 0x11001,
+	0x11038, 0x11046,
+	0x1107f, 0x11081,
+	0x110b3, 0x110b6,
+	0x110b9, 0x110ba,
+	0x11100, 0x11102,
+	0x11127, 0x1112b,
+	0x1112d, 0x11134,
+	0x11173, 0x11173,
+	0x11180, 0x11181,
+	0x111b6, 0x111be,
+	0x111ca, 0x111cc,
+	0x1122f, 0x11231,
+	0x11234, 0x11234,
+	0x11236, 0x11237,
+	0x1123e, 0x1123e,
+	0x112df, 0x112df,
+	0x112e3, 0x112ea,
+	0x11300, 0x11301,
+	0x1133c, 0x1133c,
+	0x1133e, 0x1133e,
+	0x11340, 0x11340,
+	0x11357, 0x11357,
+	0x11366, 0x1136c,
+	0x11370, 0x11374,
+	0x11438, 0x1143f,
+	0x11442, 0x11444,
+	0x11446, 0x11446,
+	0x114b0, 0x114b0,
+	0x114b3, 0x114b8,
+	0x114ba, 0x114ba,
+	0x114bd, 0x114bd,
+	0x114bf, 0x114c0,
+	0x114c2, 0x114c3,
+	0x115af, 0x115af,
+	0x115b2, 0x115b5,
+	0x115bc, 0x115bd,
+	0x115bf, 0x115c0,
+	0x115dc, 0x115dd,
+	0x11633, 0x1163a,
+	0x1163d, 0x1163d,
+	0x1163f, 0x11640,
+	0x116ab, 0x116ab,
+	0x116ad, 0x116ad,
+	0x116b0, 0x116b5,
+	0x116b7, 0x116b7,
+	0x1171d, 0x1171f,
+	0x11722, 0x11725,
+	0x11727, 0x1172b,
+	0x11a01, 0x11a06,
+	0x11a09, 0x11a0a,
+	0x11a33, 0x11a38,
+	0x11a3b, 0x11a3e,
+	0x11a47, 0x11a47,
+	0x11a51, 0x11a56,
+	0x11a59, 0x11a5b,
+	0x11a8a, 0x11a96,
+	0x11a98, 0x11a99,
+	0x11c30, 0x11c36,
+	0x11c38, 0x11c3d,
+	0x11c3f, 0x11c3f,
+	0x11c92, 0x11ca7,
+	0x11caa, 0x11cb0,
+	0x11cb2, 0x11cb3,
+	0x11cb5, 0x11cb6,
+	0x11d31, 0x11d36,
+	0x11d3a, 0x11d3a,
+	0x11d3c, 0x11d3d,
+	0x11d3f, 0x11d45,
+	0x11d47, 0x11d47,
+	0x16af0, 0x16af4,
+	0x16b30, 0x16b36,
+	0x16f8f, 0x16f92,
+	0x1bc9d, 0x1bc9e,
+	0x1d165, 0x1d165,
+	0x1d167, 0x1d169,
+	0x1d16e, 0x1d172,
+	0x1d17b, 0x1d182,
+	0x1d185, 0x1d18b,
+	0x1d1aa, 0x1d1ad,
+	0x1d242, 0x1d244,
+	0x1da00, 0x1da36,
+	0x1da3b, 0x1da6c,
+	0x1da75, 0x1da75,
+	0x1da84, 0x1da84,
+	0x1da9b, 0x1da9f,
+	0x1daa1, 0x1daaf,
+	0x1e000, 0x1e006,
+	0x1e008, 0x1e018,
+	0x1e01b, 0x1e021,
+	0x1e023, 0x1e024,
+	0x1e026, 0x1e02a,
+	0x1e8d0, 0x1e8d6,
+	0x1e944, 0x1e94a,
+	0xe0020, 0xe007f,
+	0xe0100, 0xe01ef,
+}; /* CR_Grapheme_Extend */
+
+/* 'Grapheme_Base': Derived Property */
+static const OnigCodePoint CR_Grapheme_Base[] = {
+	791,
+	0x0020, 0x007e,
+	0x00a0, 0x00ac,
+	0x00ae, 0x02ff,
+	0x0370, 0x0377,
+	0x037a, 0x037f,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x0482,
+	0x048a, 0x052f,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x058a,
+	0x058d, 0x058f,
+	0x05be, 0x05be,
+	0x05c0, 0x05c0,
+	0x05c3, 0x05c3,
+	0x05c6, 0x05c6,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x0606, 0x060f,
+	0x061b, 0x061b,
+	0x061e, 0x064a,
+	0x0660, 0x066f,
+	0x0671, 0x06d5,
+	0x06de, 0x06de,
+	0x06e5, 0x06e6,
+	0x06e9, 0x06e9,
+	0x06ee, 0x070d,
+	0x0710, 0x0710,
+	0x0712, 0x072f,
+	0x074d, 0x07a5,
+	0x07b1, 0x07b1,
+	0x07c0, 0x07ea,
+	0x07f4, 0x07fa,
+	0x0800, 0x0815,
+	0x081a, 0x081a,
+	0x0824, 0x0824,
+	0x0828, 0x0828,
+	0x0830, 0x083e,
+	0x0840, 0x0858,
+	0x085e, 0x085e,
+	0x0860, 0x086a,
+	0x08a0, 0x08b4,
+	0x08b6, 0x08bd,
+	0x0903, 0x0939,
+	0x093b, 0x093b,
+	0x093d, 0x0940,
+	0x0949, 0x094c,
+	0x094e, 0x0950,
+	0x0958, 0x0961,
+	0x0964, 0x0980,
+	0x0982, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bd, 0x09bd,
+	0x09bf, 0x09c0,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09cc,
+	0x09ce, 0x09ce,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e1,
+	0x09e6, 0x09fd,
+	0x0a03, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3e, 0x0a40,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a6f,
+	0x0a72, 0x0a74,
+	0x0a83, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abd, 0x0ac0,
+	0x0ac9, 0x0ac9,
+	0x0acb, 0x0acc,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae1,
+	0x0ae6, 0x0af1,
+	0x0af9, 0x0af9,
+	0x0b02, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3d, 0x0b3d,
+	0x0b40, 0x0b40,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4c,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b61,
+	0x0b66, 0x0b77,
+	0x0b83, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbf, 0x0bbf,
+	0x0bc1, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcc,
+	0x0bd0, 0x0bd0,
+	0x0be6, 0x0bfa,
+	0x0c01, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c39,
+	0x0c3d, 0x0c3d,
+	0x0c41, 0x0c44,
+	0x0c58, 0x0c5a,
+	0x0c60, 0x0c61,
+	0x0c66, 0x0c6f,
+	0x0c78, 0x0c80,
+	0x0c82, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbd, 0x0cbe,
+	0x0cc0, 0x0cc1,
+	0x0cc3, 0x0cc4,
+	0x0cc7, 0x0cc8,
+	0x0cca, 0x0ccb,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce1,
+	0x0ce6, 0x0cef,
+	0x0cf1, 0x0cf2,
+	0x0d02, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d3a,
+	0x0d3d, 0x0d3d,
+	0x0d3f, 0x0d40,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4c,
+	0x0d4e, 0x0d4f,
+	0x0d54, 0x0d56,
+	0x0d58, 0x0d61,
+	0x0d66, 0x0d7f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dd0, 0x0dd1,
+	0x0dd8, 0x0dde,
+	0x0de6, 0x0def,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e30,
+	0x0e32, 0x0e33,
+	0x0e3f, 0x0e46,
+	0x0e4f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb0,
+	0x0eb2, 0x0eb3,
+	0x0ebd, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f17,
+	0x0f1a, 0x0f34,
+	0x0f36, 0x0f36,
+	0x0f38, 0x0f38,
+	0x0f3a, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f7f, 0x0f7f,
+	0x0f85, 0x0f85,
+	0x0f88, 0x0f8c,
+	0x0fbe, 0x0fc5,
+	0x0fc7, 0x0fcc,
+	0x0fce, 0x0fda,
+	0x1000, 0x102c,
+	0x1031, 0x1031,
+	0x1038, 0x1038,
+	0x103b, 0x103c,
+	0x103f, 0x1057,
+	0x105a, 0x105d,
+	0x1061, 0x1070,
+	0x1075, 0x1081,
+	0x1083, 0x1084,
+	0x1087, 0x108c,
+	0x108e, 0x109c,
+	0x109e, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x1360, 0x137c,
+	0x1380, 0x1399,
+	0x13a0, 0x13f5,
+	0x13f8, 0x13fd,
+	0x1400, 0x169c,
+	0x16a0, 0x16f8,
+	0x1700, 0x170c,
+	0x170e, 0x1711,
+	0x1720, 0x1731,
+	0x1735, 0x1736,
+	0x1740, 0x1751,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1780, 0x17b3,
+	0x17b6, 0x17b6,
+	0x17be, 0x17c5,
+	0x17c7, 0x17c8,
+	0x17d4, 0x17dc,
+	0x17e0, 0x17e9,
+	0x17f0, 0x17f9,
+	0x1800, 0x180a,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x1884,
+	0x1887, 0x18a8,
+	0x18aa, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191e,
+	0x1923, 0x1926,
+	0x1929, 0x192b,
+	0x1930, 0x1931,
+	0x1933, 0x1938,
+	0x1940, 0x1940,
+	0x1944, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19da,
+	0x19de, 0x1a16,
+	0x1a19, 0x1a1a,
+	0x1a1e, 0x1a55,
+	0x1a57, 0x1a57,
+	0x1a61, 0x1a61,
+	0x1a63, 0x1a64,
+	0x1a6d, 0x1a72,
+	0x1a80, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1aa0, 0x1aad,
+	0x1b04, 0x1b33,
+	0x1b35, 0x1b35,
+	0x1b3b, 0x1b3b,
+	0x1b3d, 0x1b41,
+	0x1b43, 0x1b4b,
+	0x1b50, 0x1b6a,
+	0x1b74, 0x1b7c,
+	0x1b82, 0x1ba1,
+	0x1ba6, 0x1ba7,
+	0x1baa, 0x1baa,
+	0x1bae, 0x1be5,
+	0x1be7, 0x1be7,
+	0x1bea, 0x1bec,
+	0x1bee, 0x1bee,
+	0x1bf2, 0x1bf3,
+	0x1bfc, 0x1c2b,
+	0x1c34, 0x1c35,
+	0x1c3b, 0x1c49,
+	0x1c4d, 0x1c88,
+	0x1cc0, 0x1cc7,
+	0x1cd3, 0x1cd3,
+	0x1ce1, 0x1ce1,
+	0x1ce9, 0x1cec,
+	0x1cee, 0x1cf3,
+	0x1cf5, 0x1cf7,
+	0x1d00, 0x1dbf,
+	0x1e00, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x200a,
+	0x2010, 0x2027,
+	0x202f, 0x205f,
+	0x2070, 0x2071,
+	0x2074, 0x208e,
+	0x2090, 0x209c,
+	0x20a0, 0x20bf,
+	0x2100, 0x218b,
+	0x2190, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x2b73,
+	0x2b76, 0x2b95,
+	0x2b98, 0x2bb9,
+	0x2bbd, 0x2bc8,
+	0x2bca, 0x2bd2,
+	0x2bec, 0x2bef,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2cee,
+	0x2cf2, 0x2cf3,
+	0x2cf9, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d70,
+	0x2d80, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2e00, 0x2e49,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3000, 0x3029,
+	0x3030, 0x303f,
+	0x3041, 0x3096,
+	0x309b, 0x30ff,
+	0x3105, 0x312e,
+	0x3131, 0x318e,
+	0x3190, 0x31ba,
+	0x31c0, 0x31e3,
+	0x31f0, 0x321e,
+	0x3220, 0x32fe,
+	0x3300, 0x4db5,
+	0x4dc0, 0x9fea,
+	0xa000, 0xa48c,
+	0xa490, 0xa4c6,
+	0xa4d0, 0xa62b,
+	0xa640, 0xa66e,
+	0xa673, 0xa673,
+	0xa67e, 0xa69d,
+	0xa6a0, 0xa6ef,
+	0xa6f2, 0xa6f7,
+	0xa700, 0xa7ae,
+	0xa7b0, 0xa7b7,
+	0xa7f7, 0xa801,
+	0xa803, 0xa805,
+	0xa807, 0xa80a,
+	0xa80c, 0xa824,
+	0xa827, 0xa82b,
+	0xa830, 0xa839,
+	0xa840, 0xa877,
+	0xa880, 0xa8c3,
+	0xa8ce, 0xa8d9,
+	0xa8f2, 0xa8fd,
+	0xa900, 0xa925,
+	0xa92e, 0xa946,
+	0xa952, 0xa953,
+	0xa95f, 0xa97c,
+	0xa983, 0xa9b2,
+	0xa9b4, 0xa9b5,
+	0xa9ba, 0xa9bb,
+	0xa9bd, 0xa9cd,
+	0xa9cf, 0xa9d9,
+	0xa9de, 0xa9e4,
+	0xa9e6, 0xa9fe,
+	0xaa00, 0xaa28,
+	0xaa2f, 0xaa30,
+	0xaa33, 0xaa34,
+	0xaa40, 0xaa42,
+	0xaa44, 0xaa4b,
+	0xaa4d, 0xaa4d,
+	0xaa50, 0xaa59,
+	0xaa5c, 0xaa7b,
+	0xaa7d, 0xaaaf,
+	0xaab1, 0xaab1,
+	0xaab5, 0xaab6,
+	0xaab9, 0xaabd,
+	0xaac0, 0xaac0,
+	0xaac2, 0xaac2,
+	0xaadb, 0xaaeb,
+	0xaaee, 0xaaf5,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xab30, 0xab65,
+	0xab70, 0xabe4,
+	0xabe6, 0xabe7,
+	0xabe9, 0xabec,
+	0xabf0, 0xabf9,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xf900, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb1d,
+	0xfb1f, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbc1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdf0, 0xfdfd,
+	0xfe10, 0xfe19,
+	0xfe30, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xff01, 0xff9d,
+	0xffa0, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfffc, 0xfffd,
+	0x10000, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10100, 0x10102,
+	0x10107, 0x10133,
+	0x10137, 0x1018e,
+	0x10190, 0x1019b,
+	0x101a0, 0x101a0,
+	0x101d0, 0x101fc,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x102e1, 0x102fb,
+	0x10300, 0x10323,
+	0x1032d, 0x1034a,
+	0x10350, 0x10375,
+	0x10380, 0x1039d,
+	0x1039f, 0x103c3,
+	0x103c8, 0x103d5,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x104b0, 0x104d3,
+	0x104d8, 0x104fb,
+	0x10500, 0x10527,
+	0x10530, 0x10563,
+	0x1056f, 0x1056f,
+	0x10600, 0x10736,
+	0x10740, 0x10755,
+	0x10760, 0x10767,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10857, 0x1089e,
+	0x108a7, 0x108af,
+	0x108e0, 0x108f2,
+	0x108f4, 0x108f5,
+	0x108fb, 0x1091b,
+	0x1091f, 0x10939,
+	0x1093f, 0x1093f,
+	0x10980, 0x109b7,
+	0x109bc, 0x109cf,
+	0x109d2, 0x10a00,
+	0x10a10, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a40, 0x10a47,
+	0x10a50, 0x10a58,
+	0x10a60, 0x10a9f,
+	0x10ac0, 0x10ae4,
+	0x10aeb, 0x10af6,
+	0x10b00, 0x10b35,
+	0x10b39, 0x10b55,
+	0x10b58, 0x10b72,
+	0x10b78, 0x10b91,
+	0x10b99, 0x10b9c,
+	0x10ba9, 0x10baf,
+	0x10c00, 0x10c48,
+	0x10c80, 0x10cb2,
+	0x10cc0, 0x10cf2,
+	0x10cfa, 0x10cff,
+	0x10e60, 0x10e7e,
+	0x11000, 0x11000,
+	0x11002, 0x11037,
+	0x11047, 0x1104d,
+	0x11052, 0x1106f,
+	0x11082, 0x110b2,
+	0x110b7, 0x110b8,
+	0x110bb, 0x110bc,
+	0x110be, 0x110c1,
+	0x110d0, 0x110e8,
+	0x110f0, 0x110f9,
+	0x11103, 0x11126,
+	0x1112c, 0x1112c,
+	0x11136, 0x11143,
+	0x11150, 0x11172,
+	0x11174, 0x11176,
+	0x11182, 0x111b5,
+	0x111bf, 0x111c9,
+	0x111cd, 0x111cd,
+	0x111d0, 0x111df,
+	0x111e1, 0x111f4,
+	0x11200, 0x11211,
+	0x11213, 0x1122e,
+	0x11232, 0x11233,
+	0x11235, 0x11235,
+	0x11238, 0x1123d,
+	0x11280, 0x11286,
+	0x11288, 0x11288,
+	0x1128a, 0x1128d,
+	0x1128f, 0x1129d,
+	0x1129f, 0x112a9,
+	0x112b0, 0x112de,
+	0x112e0, 0x112e2,
+	0x112f0, 0x112f9,
+	0x11302, 0x11303,
+	0x11305, 0x1130c,
+	0x1130f, 0x11310,
+	0x11313, 0x11328,
+	0x1132a, 0x11330,
+	0x11332, 0x11333,
+	0x11335, 0x11339,
+	0x1133d, 0x1133d,
+	0x1133f, 0x1133f,
+	0x11341, 0x11344,
+	0x11347, 0x11348,
+	0x1134b, 0x1134d,
+	0x11350, 0x11350,
+	0x1135d, 0x11363,
+	0x11400, 0x11437,
+	0x11440, 0x11441,
+	0x11445, 0x11445,
+	0x11447, 0x11459,
+	0x1145b, 0x1145b,
+	0x1145d, 0x1145d,
+	0x11480, 0x114af,
+	0x114b1, 0x114b2,
+	0x114b9, 0x114b9,
+	0x114bb, 0x114bc,
+	0x114be, 0x114be,
+	0x114c1, 0x114c1,
+	0x114c4, 0x114c7,
+	0x114d0, 0x114d9,
+	0x11580, 0x115ae,
+	0x115b0, 0x115b1,
+	0x115b8, 0x115bb,
+	0x115be, 0x115be,
+	0x115c1, 0x115db,
+	0x11600, 0x11632,
+	0x1163b, 0x1163c,
+	0x1163e, 0x1163e,
+	0x11641, 0x11644,
+	0x11650, 0x11659,
+	0x11660, 0x1166c,
+	0x11680, 0x116aa,
+	0x116ac, 0x116ac,
+	0x116ae, 0x116af,
+	0x116b6, 0x116b6,
+	0x116c0, 0x116c9,
+	0x11700, 0x11719,
+	0x11720, 0x11721,
+	0x11726, 0x11726,
+	0x11730, 0x1173f,
+	0x118a0, 0x118f2,
+	0x118ff, 0x118ff,
+	0x11a00, 0x11a00,
+	0x11a07, 0x11a08,
+	0x11a0b, 0x11a32,
+	0x11a39, 0x11a3a,
+	0x11a3f, 0x11a46,
+	0x11a50, 0x11a50,
+	0x11a57, 0x11a58,
+	0x11a5c, 0x11a83,
+	0x11a86, 0x11a89,
+	0x11a97, 0x11a97,
+	0x11a9a, 0x11a9c,
+	0x11a9e, 0x11aa2,
+	0x11ac0, 0x11af8,
+	0x11c00, 0x11c08,
+	0x11c0a, 0x11c2f,
+	0x11c3e, 0x11c3e,
+	0x11c40, 0x11c45,
+	0x11c50, 0x11c6c,
+	0x11c70, 0x11c8f,
+	0x11ca9, 0x11ca9,
+	0x11cb1, 0x11cb1,
+	0x11cb4, 0x11cb4,
+	0x11d00, 0x11d06,
+	0x11d08, 0x11d09,
+	0x11d0b, 0x11d30,
+	0x11d46, 0x11d46,
+	0x11d50, 0x11d59,
+	0x12000, 0x12399,
+	0x12400, 0x1246e,
+	0x12470, 0x12474,
+	0x12480, 0x12543,
+	0x13000, 0x1342e,
+	0x14400, 0x14646,
+	0x16800, 0x16a38,
+	0x16a40, 0x16a5e,
+	0x16a60, 0x16a69,
+	0x16a6e, 0x16a6f,
+	0x16ad0, 0x16aed,
+	0x16af5, 0x16af5,
+	0x16b00, 0x16b2f,
+	0x16b37, 0x16b45,
+	0x16b50, 0x16b59,
+	0x16b5b, 0x16b61,
+	0x16b63, 0x16b77,
+	0x16b7d, 0x16b8f,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f7e,
+	0x16f93, 0x16f9f,
+	0x16fe0, 0x16fe1,
+	0x17000, 0x187ec,
+	0x18800, 0x18af2,
+	0x1b000, 0x1b11e,
+	0x1b170, 0x1b2fb,
+	0x1bc00, 0x1bc6a,
+	0x1bc70, 0x1bc7c,
+	0x1bc80, 0x1bc88,
+	0x1bc90, 0x1bc99,
+	0x1bc9c, 0x1bc9c,
+	0x1bc9f, 0x1bc9f,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d129, 0x1d164,
+	0x1d166, 0x1d166,
+	0x1d16a, 0x1d16d,
+	0x1d183, 0x1d184,
+	0x1d18c, 0x1d1a9,
+	0x1d1ae, 0x1d1e8,
+	0x1d200, 0x1d241,
+	0x1d245, 0x1d245,
+	0x1d300, 0x1d356,
+	0x1d360, 0x1d371,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d7cb,
+	0x1d7ce, 0x1d9ff,
+	0x1da37, 0x1da3a,
+	0x1da6d, 0x1da74,
+	0x1da76, 0x1da83,
+	0x1da85, 0x1da8b,
+	0x1e800, 0x1e8c4,
+	0x1e8c7, 0x1e8cf,
+	0x1e900, 0x1e943,
+	0x1e950, 0x1e959,
+	0x1e95e, 0x1e95f,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x1eef0, 0x1eef1,
+	0x1f000, 0x1f02b,
+	0x1f030, 0x1f093,
+	0x1f0a0, 0x1f0ae,
+	0x1f0b1, 0x1f0bf,
+	0x1f0c1, 0x1f0cf,
+	0x1f0d1, 0x1f0f5,
+	0x1f100, 0x1f10c,
+	0x1f110, 0x1f12e,
+	0x1f130, 0x1f16b,
+	0x1f170, 0x1f1ac,
+	0x1f1e6, 0x1f202,
+	0x1f210, 0x1f23b,
+	0x1f240, 0x1f248,
+	0x1f250, 0x1f251,
+	0x1f260, 0x1f265,
+	0x1f300, 0x1f6d4,
+	0x1f6e0, 0x1f6ec,
+	0x1f6f0, 0x1f6f8,
+	0x1f700, 0x1f773,
+	0x1f780, 0x1f7d4,
+	0x1f800, 0x1f80b,
+	0x1f810, 0x1f847,
+	0x1f850, 0x1f859,
+	0x1f860, 0x1f887,
+	0x1f890, 0x1f8ad,
+	0x1f900, 0x1f90b,
+	0x1f910, 0x1f93e,
+	0x1f940, 0x1f94c,
+	0x1f950, 0x1f96b,
+	0x1f980, 0x1f997,
+	0x1f9c0, 0x1f9c0,
+	0x1f9d0, 0x1f9e6,
+	0x20000, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2b820, 0x2cea1,
+	0x2ceb0, 0x2ebe0,
+	0x2f800, 0x2fa1d,
+}; /* CR_Grapheme_Base */
+
+/* 'Grapheme_Link': Derived Property */
+static const OnigCodePoint CR_Grapheme_Link[] = {
+	48,
+	0x094d, 0x094d,
+	0x09cd, 0x09cd,
+	0x0a4d, 0x0a4d,
+	0x0acd, 0x0acd,
+	0x0b4d, 0x0b4d,
+	0x0bcd, 0x0bcd,
+	0x0c4d, 0x0c4d,
+	0x0ccd, 0x0ccd,
+	0x0d3b, 0x0d3c,
+	0x0d4d, 0x0d4d,
+	0x0dca, 0x0dca,
+	0x0e3a, 0x0e3a,
+	0x0f84, 0x0f84,
+	0x1039, 0x103a,
+	0x1714, 0x1714,
+	0x1734, 0x1734,
+	0x17d2, 0x17d2,
+	0x1a60, 0x1a60,
+	0x1b44, 0x1b44,
+	0x1baa, 0x1bab,
+	0x1bf2, 0x1bf3,
+	0x2d7f, 0x2d7f,
+	0xa806, 0xa806,
+	0xa8c4, 0xa8c4,
+	0xa953, 0xa953,
+	0xa9c0, 0xa9c0,
+	0xaaf6, 0xaaf6,
+	0xabed, 0xabed,
+	0x10a3f, 0x10a3f,
+	0x11046, 0x11046,
+	0x1107f, 0x1107f,
+	0x110b9, 0x110b9,
+	0x11133, 0x11134,
+	0x111c0, 0x111c0,
+	0x11235, 0x11235,
+	0x112ea, 0x112ea,
+	0x1134d, 0x1134d,
+	0x11442, 0x11442,
+	0x114c2, 0x114c2,
+	0x115bf, 0x115bf,
+	0x1163f, 0x1163f,
+	0x116b6, 0x116b6,
+	0x1172b, 0x1172b,
+	0x11a34, 0x11a34,
+	0x11a47, 0x11a47,
+	0x11a99, 0x11a99,
+	0x11c3f, 0x11c3f,
+	0x11d44, 0x11d45,
+}; /* CR_Grapheme_Link */
+
+/* 'Common': Script */
+static const OnigCodePoint CR_Common[] = {
+	164,
+	0x0000, 0x0040,
+	0x005b, 0x0060,
+	0x007b, 0x00a9,
+	0x00ab, 0x00b9,
+	0x00bb, 0x00bf,
+	0x00d7, 0x00d7,
+	0x00f7, 0x00f7,
+	0x02b9, 0x02df,
+	0x02e5, 0x02e9,
+	0x02ec, 0x02ff,
+	0x0374, 0x0374,
+	0x037e, 0x037e,
+	0x0385, 0x0385,
+	0x0387, 0x0387,
+	0x0589, 0x0589,
+	0x0605, 0x0605,
+	0x060c, 0x060c,
+	0x061b, 0x061b,
+	0x061f, 0x061f,
+	0x0640, 0x0640,
+	0x06dd, 0x06dd,
+	0x08e2, 0x08e2,
+	0x0964, 0x0965,
+	0x0e3f, 0x0e3f,
+	0x0fd5, 0x0fd8,
+	0x10fb, 0x10fb,
+	0x16eb, 0x16ed,
+	0x1735, 0x1736,
+	0x1802, 0x1803,
+	0x1805, 0x1805,
+	0x1cd3, 0x1cd3,
+	0x1ce1, 0x1ce1,
+	0x1ce9, 0x1cec,
+	0x1cee, 0x1cf3,
+	0x1cf5, 0x1cf7,
+	0x2000, 0x200b,
+	0x200e, 0x2064,
+	0x2066, 0x2070,
+	0x2074, 0x207e,
+	0x2080, 0x208e,
+	0x20a0, 0x20bf,
+	0x2100, 0x2125,
+	0x2127, 0x2129,
+	0x212c, 0x2131,
+	0x2133, 0x214d,
+	0x214f, 0x215f,
+	0x2189, 0x218b,
+	0x2190, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x27ff,
+	0x2900, 0x2b73,
+	0x2b76, 0x2b95,
+	0x2b98, 0x2bb9,
+	0x2bbd, 0x2bc8,
+	0x2bca, 0x2bd2,
+	0x2bec, 0x2bef,
+	0x2e00, 0x2e49,
+	0x2ff0, 0x2ffb,
+	0x3000, 0x3004,
+	0x3006, 0x3006,
+	0x3008, 0x3020,
+	0x3030, 0x3037,
+	0x303c, 0x303f,
+	0x309b, 0x309c,
+	0x30a0, 0x30a0,
+	0x30fb, 0x30fc,
+	0x3190, 0x319f,
+	0x31c0, 0x31e3,
+	0x3220, 0x325f,
+	0x327f, 0x32cf,
+	0x3358, 0x33ff,
+	0x4dc0, 0x4dff,
+	0xa700, 0xa721,
+	0xa788, 0xa78a,
+	0xa830, 0xa839,
+	0xa92e, 0xa92e,
+	0xa9cf, 0xa9cf,
+	0xab5b, 0xab5b,
+	0xfd3e, 0xfd3f,
+	0xfe10, 0xfe19,
+	0xfe30, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfeff, 0xfeff,
+	0xff01, 0xff20,
+	0xff3b, 0xff40,
+	0xff5b, 0xff65,
+	0xff70, 0xff70,
+	0xff9e, 0xff9f,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfff9, 0xfffd,
+	0x10100, 0x10102,
+	0x10107, 0x10133,
+	0x10137, 0x1013f,
+	0x10190, 0x1019b,
+	0x101d0, 0x101fc,
+	0x102e1, 0x102fb,
+	0x1bca0, 0x1bca3,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d129, 0x1d166,
+	0x1d16a, 0x1d17a,
+	0x1d183, 0x1d184,
+	0x1d18c, 0x1d1a9,
+	0x1d1ae, 0x1d1e8,
+	0x1d300, 0x1d356,
+	0x1d360, 0x1d371,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d7cb,
+	0x1d7ce, 0x1d7ff,
+	0x1f000, 0x1f02b,
+	0x1f030, 0x1f093,
+	0x1f0a0, 0x1f0ae,
+	0x1f0b1, 0x1f0bf,
+	0x1f0c1, 0x1f0cf,
+	0x1f0d1, 0x1f0f5,
+	0x1f100, 0x1f10c,
+	0x1f110, 0x1f12e,
+	0x1f130, 0x1f16b,
+	0x1f170, 0x1f1ac,
+	0x1f1e6, 0x1f1ff,
+	0x1f201, 0x1f202,
+	0x1f210, 0x1f23b,
+	0x1f240, 0x1f248,
+	0x1f250, 0x1f251,
+	0x1f260, 0x1f265,
+	0x1f300, 0x1f6d4,
+	0x1f6e0, 0x1f6ec,
+	0x1f6f0, 0x1f6f8,
+	0x1f700, 0x1f773,
+	0x1f780, 0x1f7d4,
+	0x1f800, 0x1f80b,
+	0x1f810, 0x1f847,
+	0x1f850, 0x1f859,
+	0x1f860, 0x1f887,
+	0x1f890, 0x1f8ad,
+	0x1f900, 0x1f90b,
+	0x1f910, 0x1f93e,
+	0x1f940, 0x1f94c,
+	0x1f950, 0x1f96b,
+	0x1f980, 0x1f997,
+	0x1f9c0, 0x1f9c0,
+	0x1f9d0, 0x1f9e6,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+}; /* CR_Common */
+
+/* 'Latin': Script */
+static const OnigCodePoint CR_Latin[] = {
+	31,
+	0x0041, 0x005a,
+	0x0061, 0x007a,
+	0x00aa, 0x00aa,
+	0x00ba, 0x00ba,
+	0x00c0, 0x00d6,
+	0x00d8, 0x00f6,
+	0x00f8, 0x02b8,
+	0x02e0, 0x02e4,
+	0x1d00, 0x1d25,
+	0x1d2c, 0x1d5c,
+	0x1d62, 0x1d65,
+	0x1d6b, 0x1d77,
+	0x1d79, 0x1dbe,
+	0x1e00, 0x1eff,
+	0x2071, 0x2071,
+	0x207f, 0x207f,
+	0x2090, 0x209c,
+	0x212a, 0x212b,
+	0x2132, 0x2132,
+	0x214e, 0x214e,
+	0x2160, 0x2188,
+	0x2c60, 0x2c7f,
+	0xa722, 0xa787,
+	0xa78b, 0xa7ae,
+	0xa7b0, 0xa7b7,
+	0xa7f7, 0xa7ff,
+	0xab30, 0xab5a,
+	0xab5c, 0xab64,
+	0xfb00, 0xfb06,
+	0xff21, 0xff3a,
+	0xff41, 0xff5a,
+}; /* CR_Latin */
+
+/* 'Greek': Script */
+static const OnigCodePoint CR_Greek[] = {
+	36,
+	0x0370, 0x0373,
+	0x0375, 0x0377,
+	0x037a, 0x037d,
+	0x037f, 0x037f,
+	0x0384, 0x0384,
+	0x0386, 0x0386,
+	0x0388, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03e1,
+	0x03f0, 0x03ff,
+	0x1d26, 0x1d2a,
+	0x1d5d, 0x1d61,
+	0x1d66, 0x1d6a,
+	0x1dbf, 0x1dbf,
+	0x1f00, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2126, 0x2126,
+	0xab65, 0xab65,
+	0x10140, 0x1018e,
+	0x101a0, 0x101a0,
+	0x1d200, 0x1d245,
+}; /* CR_Greek */
+
+/* 'Cyrillic': Script */
+static const OnigCodePoint CR_Cyrillic[] = {
+	8,
+	0x0400, 0x0484,
+	0x0487, 0x052f,
+	0x1c80, 0x1c88,
+	0x1d2b, 0x1d2b,
+	0x1d78, 0x1d78,
+	0x2de0, 0x2dff,
+	0xa640, 0xa69f,
+	0xfe2e, 0xfe2f,
+}; /* CR_Cyrillic */
+
+/* 'Armenian': Script */
+static const OnigCodePoint CR_Armenian[] = {
+	6,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x058a, 0x058a,
+	0x058d, 0x058f,
+	0xfb13, 0xfb17,
+}; /* CR_Armenian */
+
+/* 'Hebrew': Script */
+static const OnigCodePoint CR_Hebrew[] = {
+	9,
+	0x0591, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0xfb1d, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfb4f,
+}; /* CR_Hebrew */
+
+/* 'Arabic': Script */
+static const OnigCodePoint CR_Arabic[] = {
+	57,
+	0x0600, 0x0604,
+	0x0606, 0x060b,
+	0x060d, 0x061a,
+	0x061c, 0x061c,
+	0x061e, 0x061e,
+	0x0620, 0x063f,
+	0x0641, 0x064a,
+	0x0656, 0x066f,
+	0x0671, 0x06dc,
+	0x06de, 0x06ff,
+	0x0750, 0x077f,
+	0x08a0, 0x08b4,
+	0x08b6, 0x08bd,
+	0x08d4, 0x08e1,
+	0x08e3, 0x08ff,
+	0xfb50, 0xfbc1,
+	0xfbd3, 0xfd3d,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdf0, 0xfdfd,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0x10e60, 0x10e7e,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x1eef0, 0x1eef1,
+}; /* CR_Arabic */
+
+/* 'Syriac': Script */
+static const OnigCodePoint CR_Syriac[] = {
+	4,
+	0x0700, 0x070d,
+	0x070f, 0x074a,
+	0x074d, 0x074f,
+	0x0860, 0x086a,
+}; /* CR_Syriac */
+
+/* 'Thaana': Script */
+static const OnigCodePoint CR_Thaana[] = {
+	1,
+	0x0780, 0x07b1,
+}; /* CR_Thaana */
+
+/* 'Devanagari': Script */
+static const OnigCodePoint CR_Devanagari[] = {
+	4,
+	0x0900, 0x0950,
+	0x0953, 0x0963,
+	0x0966, 0x097f,
+	0xa8e0, 0xa8fd,
+}; /* CR_Devanagari */
+
+/* 'Bengali': Script */
+static const OnigCodePoint CR_Bengali[] = {
+	14,
+	0x0980, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fd,
+}; /* CR_Bengali */
+
+/* 'Gurmukhi': Script */
+static const OnigCodePoint CR_Gurmukhi[] = {
+	16,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a75,
+}; /* CR_Gurmukhi */
+
+/* 'Gujarati': Script */
+static const OnigCodePoint CR_Gujarati[] = {
+	14,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0af1,
+	0x0af9, 0x0aff,
+}; /* CR_Gujarati */
+
+/* 'Oriya': Script */
+static const OnigCodePoint CR_Oriya[] = {
+	14,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3c, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b63,
+	0x0b66, 0x0b77,
+}; /* CR_Oriya */
+
+/* 'Tamil': Script */
+static const OnigCodePoint CR_Tamil[] = {
+	16,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd0, 0x0bd0,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bfa,
+}; /* CR_Tamil */
+
+/* 'Telugu': Script */
+static const OnigCodePoint CR_Telugu[] = {
+	13,
+	0x0c00, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c39,
+	0x0c3d, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c58, 0x0c5a,
+	0x0c60, 0x0c63,
+	0x0c66, 0x0c6f,
+	0x0c78, 0x0c7f,
+}; /* CR_Telugu */
+
+/* 'Kannada': Script */
+static const OnigCodePoint CR_Kannada[] = {
+	14,
+	0x0c80, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbc, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce3,
+	0x0ce6, 0x0cef,
+	0x0cf1, 0x0cf2,
+}; /* CR_Kannada */
+
+/* 'Malayalam': Script */
+static const OnigCodePoint CR_Malayalam[] = {
+	8,
+	0x0d00, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4f,
+	0x0d54, 0x0d63,
+	0x0d66, 0x0d7f,
+}; /* CR_Malayalam */
+
+/* 'Sinhala': Script */
+static const OnigCodePoint CR_Sinhala[] = {
+	13,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0de6, 0x0def,
+	0x0df2, 0x0df4,
+	0x111e1, 0x111f4,
+}; /* CR_Sinhala */
+
+/* 'Thai': Script */
+static const OnigCodePoint CR_Thai[] = {
+	2,
+	0x0e01, 0x0e3a,
+	0x0e40, 0x0e5b,
+}; /* CR_Thai */
+
+/* 'Lao': Script */
+static const OnigCodePoint CR_Lao[] = {
+	18,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edf,
+}; /* CR_Lao */
+
+/* 'Tibetan': Script */
+static const OnigCodePoint CR_Tibetan[] = {
+	7,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f71, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fbe, 0x0fcc,
+	0x0fce, 0x0fd4,
+	0x0fd9, 0x0fda,
+}; /* CR_Tibetan */
+
+/* 'Myanmar': Script */
+static const OnigCodePoint CR_Myanmar[] = {
+	3,
+	0x1000, 0x109f,
+	0xa9e0, 0xa9fe,
+	0xaa60, 0xaa7f,
+}; /* CR_Myanmar */
+
+/* 'Georgian': Script */
+static const OnigCodePoint CR_Georgian[] = {
+	8,
+	0x10a0, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x10fa,
+	0x10fc, 0x10ff,
+	0x2d00, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+}; /* CR_Georgian */
+
+/* 'Hangul': Script */
+static const OnigCodePoint CR_Hangul[] = {
+	14,
+	0x1100, 0x11ff,
+	0x302e, 0x302f,
+	0x3131, 0x318e,
+	0x3200, 0x321e,
+	0x3260, 0x327e,
+	0xa960, 0xa97c,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xffa0, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+}; /* CR_Hangul */
+
+/* 'Ethiopic': Script */
+static const OnigCodePoint CR_Ethiopic[] = {
+	32,
+	0x1200, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135d, 0x137c,
+	0x1380, 0x1399,
+	0x2d80, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+}; /* CR_Ethiopic */
+
+/* 'Cherokee': Script */
+static const OnigCodePoint CR_Cherokee[] = {
+	3,
+	0x13a0, 0x13f5,
+	0x13f8, 0x13fd,
+	0xab70, 0xabbf,
+}; /* CR_Cherokee */
+
+/* 'Canadian_Aboriginal': Script */
+static const OnigCodePoint CR_Canadian_Aboriginal[] = {
+	2,
+	0x1400, 0x167f,
+	0x18b0, 0x18f5,
+}; /* CR_Canadian_Aboriginal */
+
+/* 'Ogham': Script */
+static const OnigCodePoint CR_Ogham[] = {
+	1,
+	0x1680, 0x169c,
+}; /* CR_Ogham */
+
+/* 'Runic': Script */
+static const OnigCodePoint CR_Runic[] = {
+	2,
+	0x16a0, 0x16ea,
+	0x16ee, 0x16f8,
+}; /* CR_Runic */
+
+/* 'Khmer': Script */
+static const OnigCodePoint CR_Khmer[] = {
+	4,
+	0x1780, 0x17dd,
+	0x17e0, 0x17e9,
+	0x17f0, 0x17f9,
+	0x19e0, 0x19ff,
+}; /* CR_Khmer */
+
+/* 'Mongolian': Script */
+static const OnigCodePoint CR_Mongolian[] = {
+	7,
+	0x1800, 0x1801,
+	0x1804, 0x1804,
+	0x1806, 0x180e,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18aa,
+	0x11660, 0x1166c,
+}; /* CR_Mongolian */
+
+/* 'Hiragana': Script */
+static const OnigCodePoint CR_Hiragana[] = {
+	4,
+	0x3041, 0x3096,
+	0x309d, 0x309f,
+	0x1b001, 0x1b11e,
+	0x1f200, 0x1f200,
+}; /* CR_Hiragana */
+
+/* 'Katakana': Script */
+static const OnigCodePoint CR_Katakana[] = {
+	8,
+	0x30a1, 0x30fa,
+	0x30fd, 0x30ff,
+	0x31f0, 0x31ff,
+	0x32d0, 0x32fe,
+	0x3300, 0x3357,
+	0xff66, 0xff6f,
+	0xff71, 0xff9d,
+	0x1b000, 0x1b000,
+}; /* CR_Katakana */
+
+/* 'Bopomofo': Script */
+static const OnigCodePoint CR_Bopomofo[] = {
+	3,
+	0x02ea, 0x02eb,
+	0x3105, 0x312e,
+	0x31a0, 0x31ba,
+}; /* CR_Bopomofo */
+
+/* 'Han': Script */
+static const OnigCodePoint CR_Han[] = {
+	17,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x3005, 0x3005,
+	0x3007, 0x3007,
+	0x3021, 0x3029,
+	0x3038, 0x303b,
+	0x3400, 0x4db5,
+	0x4e00, 0x9fea,
+	0xf900, 0xfa6d,
+	0xfa70, 0xfad9,
+	0x20000, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2b820, 0x2cea1,
+	0x2ceb0, 0x2ebe0,
+	0x2f800, 0x2fa1d,
+}; /* CR_Han */
+
+/* 'Yi': Script */
+static const OnigCodePoint CR_Yi[] = {
+	2,
+	0xa000, 0xa48c,
+	0xa490, 0xa4c6,
+}; /* CR_Yi */
+
+/* 'Old_Italic': Script */
+static const OnigCodePoint CR_Old_Italic[] = {
+	2,
+	0x10300, 0x10323,
+	0x1032d, 0x1032f,
+}; /* CR_Old_Italic */
+
+/* 'Gothic': Script */
+static const OnigCodePoint CR_Gothic[] = {
+	1,
+	0x10330, 0x1034a,
+}; /* CR_Gothic */
+
+/* 'Deseret': Script */
+static const OnigCodePoint CR_Deseret[] = {
+	1,
+	0x10400, 0x1044f,
+}; /* CR_Deseret */
+
+/* 'Inherited': Script */
+static const OnigCodePoint CR_Inherited[] = {
+	27,
+	0x0300, 0x036f,
+	0x0485, 0x0486,
+	0x064b, 0x0655,
+	0x0670, 0x0670,
+	0x0951, 0x0952,
+	0x1ab0, 0x1abe,
+	0x1cd0, 0x1cd2,
+	0x1cd4, 0x1ce0,
+	0x1ce2, 0x1ce8,
+	0x1ced, 0x1ced,
+	0x1cf4, 0x1cf4,
+	0x1cf8, 0x1cf9,
+	0x1dc0, 0x1df9,
+	0x1dfb, 0x1dff,
+	0x200c, 0x200d,
+	0x20d0, 0x20f0,
+	0x302a, 0x302d,
+	0x3099, 0x309a,
+	0xfe00, 0xfe0f,
+	0xfe20, 0xfe2d,
+	0x101fd, 0x101fd,
+	0x102e0, 0x102e0,
+	0x1d167, 0x1d169,
+	0x1d17b, 0x1d182,
+	0x1d185, 0x1d18b,
+	0x1d1aa, 0x1d1ad,
+	0xe0100, 0xe01ef,
+}; /* CR_Inherited */
+
+/* 'Tagalog': Script */
+static const OnigCodePoint CR_Tagalog[] = {
+	2,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+}; /* CR_Tagalog */
+
+/* 'Hanunoo': Script */
+static const OnigCodePoint CR_Hanunoo[] = {
+	1,
+	0x1720, 0x1734,
+}; /* CR_Hanunoo */
+
+/* 'Buhid': Script */
+static const OnigCodePoint CR_Buhid[] = {
+	1,
+	0x1740, 0x1753,
+}; /* CR_Buhid */
+
+/* 'Tagbanwa': Script */
+static const OnigCodePoint CR_Tagbanwa[] = {
+	3,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+}; /* CR_Tagbanwa */
+
+/* 'Limbu': Script */
+static const OnigCodePoint CR_Limbu[] = {
+	5,
+	0x1900, 0x191e,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1940, 0x1940,
+	0x1944, 0x194f,
+}; /* CR_Limbu */
+
+/* 'Tai_Le': Script */
+static const OnigCodePoint CR_Tai_Le[] = {
+	2,
+	0x1950, 0x196d,
+	0x1970, 0x1974,
+}; /* CR_Tai_Le */
+
+/* 'Linear_B': Script */
+static const OnigCodePoint CR_Linear_B[] = {
+	7,
+	0x10000, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+}; /* CR_Linear_B */
+
+/* 'Ugaritic': Script */
+static const OnigCodePoint CR_Ugaritic[] = {
+	2,
+	0x10380, 0x1039d,
+	0x1039f, 0x1039f,
+}; /* CR_Ugaritic */
+
+/* 'Shavian': Script */
+static const OnigCodePoint CR_Shavian[] = {
+	1,
+	0x10450, 0x1047f,
+}; /* CR_Shavian */
+
+/* 'Osmanya': Script */
+static const OnigCodePoint CR_Osmanya[] = {
+	2,
+	0x10480, 0x1049d,
+	0x104a0, 0x104a9,
+}; /* CR_Osmanya */
+
+/* 'Cypriot': Script */
+static const OnigCodePoint CR_Cypriot[] = {
+	6,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x1083f,
+}; /* CR_Cypriot */
+
+/* 'Braille': Script */
+static const OnigCodePoint CR_Braille[] = {
+	1,
+	0x2800, 0x28ff,
+}; /* CR_Braille */
+
+/* 'Buginese': Script */
+static const OnigCodePoint CR_Buginese[] = {
+	2,
+	0x1a00, 0x1a1b,
+	0x1a1e, 0x1a1f,
+}; /* CR_Buginese */
+
+/* 'Coptic': Script */
+static const OnigCodePoint CR_Coptic[] = {
+	3,
+	0x03e2, 0x03ef,
+	0x2c80, 0x2cf3,
+	0x2cf9, 0x2cff,
+}; /* CR_Coptic */
+
+/* 'New_Tai_Lue': Script */
+static const OnigCodePoint CR_New_Tai_Lue[] = {
+	4,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19da,
+	0x19de, 0x19df,
+}; /* CR_New_Tai_Lue */
+
+/* 'Glagolitic': Script */
+static const OnigCodePoint CR_Glagolitic[] = {
+	7,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x1e000, 0x1e006,
+	0x1e008, 0x1e018,
+	0x1e01b, 0x1e021,
+	0x1e023, 0x1e024,
+	0x1e026, 0x1e02a,
+}; /* CR_Glagolitic */
+
+/* 'Tifinagh': Script */
+static const OnigCodePoint CR_Tifinagh[] = {
+	3,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d70,
+	0x2d7f, 0x2d7f,
+}; /* CR_Tifinagh */
+
+/* 'Syloti_Nagri': Script */
+static const OnigCodePoint CR_Syloti_Nagri[] = {
+	1,
+	0xa800, 0xa82b,
+}; /* CR_Syloti_Nagri */
+
+/* 'Old_Persian': Script */
+static const OnigCodePoint CR_Old_Persian[] = {
+	2,
+	0x103a0, 0x103c3,
+	0x103c8, 0x103d5,
+}; /* CR_Old_Persian */
+
+/* 'Kharoshthi': Script */
+static const OnigCodePoint CR_Kharoshthi[] = {
+	8,
+	0x10a00, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a47,
+	0x10a50, 0x10a58,
+}; /* CR_Kharoshthi */
+
+/* 'Balinese': Script */
+static const OnigCodePoint CR_Balinese[] = {
+	2,
+	0x1b00, 0x1b4b,
+	0x1b50, 0x1b7c,
+}; /* CR_Balinese */
+
+/* 'Cuneiform': Script */
+static const OnigCodePoint CR_Cuneiform[] = {
+	4,
+	0x12000, 0x12399,
+	0x12400, 0x1246e,
+	0x12470, 0x12474,
+	0x12480, 0x12543,
+}; /* CR_Cuneiform */
+
+/* 'Phoenician': Script */
+static const OnigCodePoint CR_Phoenician[] = {
+	2,
+	0x10900, 0x1091b,
+	0x1091f, 0x1091f,
+}; /* CR_Phoenician */
+
+/* 'Phags_Pa': Script */
+static const OnigCodePoint CR_Phags_Pa[] = {
+	1,
+	0xa840, 0xa877,
+}; /* CR_Phags_Pa */
+
+/* 'Nko': Script */
+static const OnigCodePoint CR_Nko[] = {
+	1,
+	0x07c0, 0x07fa,
+}; /* CR_Nko */
+
+/* 'Sundanese': Script */
+static const OnigCodePoint CR_Sundanese[] = {
+	2,
+	0x1b80, 0x1bbf,
+	0x1cc0, 0x1cc7,
+}; /* CR_Sundanese */
+
+/* 'Lepcha': Script */
+static const OnigCodePoint CR_Lepcha[] = {
+	3,
+	0x1c00, 0x1c37,
+	0x1c3b, 0x1c49,
+	0x1c4d, 0x1c4f,
+}; /* CR_Lepcha */
+
+/* 'Ol_Chiki': Script */
+static const OnigCodePoint CR_Ol_Chiki[] = {
+	1,
+	0x1c50, 0x1c7f,
+}; /* CR_Ol_Chiki */
+
+/* 'Vai': Script */
+static const OnigCodePoint CR_Vai[] = {
+	1,
+	0xa500, 0xa62b,
+}; /* CR_Vai */
+
+/* 'Saurashtra': Script */
+static const OnigCodePoint CR_Saurashtra[] = {
+	2,
+	0xa880, 0xa8c5,
+	0xa8ce, 0xa8d9,
+}; /* CR_Saurashtra */
+
+/* 'Kayah_Li': Script */
+static const OnigCodePoint CR_Kayah_Li[] = {
+	2,
+	0xa900, 0xa92d,
+	0xa92f, 0xa92f,
+}; /* CR_Kayah_Li */
+
+/* 'Rejang': Script */
+static const OnigCodePoint CR_Rejang[] = {
+	2,
+	0xa930, 0xa953,
+	0xa95f, 0xa95f,
+}; /* CR_Rejang */
+
+/* 'Lycian': Script */
+static const OnigCodePoint CR_Lycian[] = {
+	1,
+	0x10280, 0x1029c,
+}; /* CR_Lycian */
+
+/* 'Carian': Script */
+static const OnigCodePoint CR_Carian[] = {
+	1,
+	0x102a0, 0x102d0,
+}; /* CR_Carian */
+
+/* 'Lydian': Script */
+static const OnigCodePoint CR_Lydian[] = {
+	2,
+	0x10920, 0x10939,
+	0x1093f, 0x1093f,
+}; /* CR_Lydian */
+
+/* 'Cham': Script */
+static const OnigCodePoint CR_Cham[] = {
+	4,
+	0xaa00, 0xaa36,
+	0xaa40, 0xaa4d,
+	0xaa50, 0xaa59,
+	0xaa5c, 0xaa5f,
+}; /* CR_Cham */
+
+/* 'Tai_Tham': Script */
+static const OnigCodePoint CR_Tai_Tham[] = {
+	5,
+	0x1a20, 0x1a5e,
+	0x1a60, 0x1a7c,
+	0x1a7f, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1aa0, 0x1aad,
+}; /* CR_Tai_Tham */
+
+/* 'Tai_Viet': Script */
+static const OnigCodePoint CR_Tai_Viet[] = {
+	2,
+	0xaa80, 0xaac2,
+	0xaadb, 0xaadf,
+}; /* CR_Tai_Viet */
+
+/* 'Avestan': Script */
+static const OnigCodePoint CR_Avestan[] = {
+	2,
+	0x10b00, 0x10b35,
+	0x10b39, 0x10b3f,
+}; /* CR_Avestan */
+
+/* 'Egyptian_Hieroglyphs': Script */
+static const OnigCodePoint CR_Egyptian_Hieroglyphs[] = {
+	1,
+	0x13000, 0x1342e,
+}; /* CR_Egyptian_Hieroglyphs */
+
+/* 'Samaritan': Script */
+static const OnigCodePoint CR_Samaritan[] = {
+	2,
+	0x0800, 0x082d,
+	0x0830, 0x083e,
+}; /* CR_Samaritan */
+
+/* 'Lisu': Script */
+static const OnigCodePoint CR_Lisu[] = {
+	1,
+	0xa4d0, 0xa4ff,
+}; /* CR_Lisu */
+
+/* 'Bamum': Script */
+static const OnigCodePoint CR_Bamum[] = {
+	2,
+	0xa6a0, 0xa6f7,
+	0x16800, 0x16a38,
+}; /* CR_Bamum */
+
+/* 'Javanese': Script */
+static const OnigCodePoint CR_Javanese[] = {
+	3,
+	0xa980, 0xa9cd,
+	0xa9d0, 0xa9d9,
+	0xa9de, 0xa9df,
+}; /* CR_Javanese */
+
+/* 'Meetei_Mayek': Script */
+static const OnigCodePoint CR_Meetei_Mayek[] = {
+	3,
+	0xaae0, 0xaaf6,
+	0xabc0, 0xabed,
+	0xabf0, 0xabf9,
+}; /* CR_Meetei_Mayek */
+
+/* 'Imperial_Aramaic': Script */
+static const OnigCodePoint CR_Imperial_Aramaic[] = {
+	2,
+	0x10840, 0x10855,
+	0x10857, 0x1085f,
+}; /* CR_Imperial_Aramaic */
+
+/* 'Old_South_Arabian': Script */
+static const OnigCodePoint CR_Old_South_Arabian[] = {
+	1,
+	0x10a60, 0x10a7f,
+}; /* CR_Old_South_Arabian */
+
+/* 'Inscriptional_Parthian': Script */
+static const OnigCodePoint CR_Inscriptional_Parthian[] = {
+	2,
+	0x10b40, 0x10b55,
+	0x10b58, 0x10b5f,
+}; /* CR_Inscriptional_Parthian */
+
+/* 'Inscriptional_Pahlavi': Script */
+static const OnigCodePoint CR_Inscriptional_Pahlavi[] = {
+	2,
+	0x10b60, 0x10b72,
+	0x10b78, 0x10b7f,
+}; /* CR_Inscriptional_Pahlavi */
+
+/* 'Old_Turkic': Script */
+static const OnigCodePoint CR_Old_Turkic[] = {
+	1,
+	0x10c00, 0x10c48,
+}; /* CR_Old_Turkic */
+
+/* 'Kaithi': Script */
+static const OnigCodePoint CR_Kaithi[] = {
+	1,
+	0x11080, 0x110c1,
+}; /* CR_Kaithi */
+
+/* 'Batak': Script */
+static const OnigCodePoint CR_Batak[] = {
+	2,
+	0x1bc0, 0x1bf3,
+	0x1bfc, 0x1bff,
+}; /* CR_Batak */
+
+/* 'Brahmi': Script */
+static const OnigCodePoint CR_Brahmi[] = {
+	3,
+	0x11000, 0x1104d,
+	0x11052, 0x1106f,
+	0x1107f, 0x1107f,
+}; /* CR_Brahmi */
+
+/* 'Mandaic': Script */
+static const OnigCodePoint CR_Mandaic[] = {
+	2,
+	0x0840, 0x085b,
+	0x085e, 0x085e,
+}; /* CR_Mandaic */
+
+/* 'Chakma': Script */
+static const OnigCodePoint CR_Chakma[] = {
+	2,
+	0x11100, 0x11134,
+	0x11136, 0x11143,
+}; /* CR_Chakma */
+
+/* 'Meroitic_Cursive': Script */
+static const OnigCodePoint CR_Meroitic_Cursive[] = {
+	3,
+	0x109a0, 0x109b7,
+	0x109bc, 0x109cf,
+	0x109d2, 0x109ff,
+}; /* CR_Meroitic_Cursive */
+
+/* 'Meroitic_Hieroglyphs': Script */
+static const OnigCodePoint CR_Meroitic_Hieroglyphs[] = {
+	1,
+	0x10980, 0x1099f,
+}; /* CR_Meroitic_Hieroglyphs */
+
+/* 'Miao': Script */
+static const OnigCodePoint CR_Miao[] = {
+	3,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f7e,
+	0x16f8f, 0x16f9f,
+}; /* CR_Miao */
+
+/* 'Sharada': Script */
+static const OnigCodePoint CR_Sharada[] = {
+	2,
+	0x11180, 0x111cd,
+	0x111d0, 0x111df,
+}; /* CR_Sharada */
+
+/* 'Sora_Sompeng': Script */
+static const OnigCodePoint CR_Sora_Sompeng[] = {
+	2,
+	0x110d0, 0x110e8,
+	0x110f0, 0x110f9,
+}; /* CR_Sora_Sompeng */
+
+/* 'Takri': Script */
+static const OnigCodePoint CR_Takri[] = {
+	2,
+	0x11680, 0x116b7,
+	0x116c0, 0x116c9,
+}; /* CR_Takri */
+
+/* 'Caucasian_Albanian': Script */
+static const OnigCodePoint CR_Caucasian_Albanian[] = {
+	2,
+	0x10530, 0x10563,
+	0x1056f, 0x1056f,
+}; /* CR_Caucasian_Albanian */
+
+/* 'Bassa_Vah': Script */
+static const OnigCodePoint CR_Bassa_Vah[] = {
+	2,
+	0x16ad0, 0x16aed,
+	0x16af0, 0x16af5,
+}; /* CR_Bassa_Vah */
+
+/* 'Duployan': Script */
+static const OnigCodePoint CR_Duployan[] = {
+	5,
+	0x1bc00, 0x1bc6a,
+	0x1bc70, 0x1bc7c,
+	0x1bc80, 0x1bc88,
+	0x1bc90, 0x1bc99,
+	0x1bc9c, 0x1bc9f,
+}; /* CR_Duployan */
+
+/* 'Elbasan': Script */
+static const OnigCodePoint CR_Elbasan[] = {
+	1,
+	0x10500, 0x10527,
+}; /* CR_Elbasan */
+
+/* 'Grantha': Script */
+static const OnigCodePoint CR_Grantha[] = {
+	15,
+	0x11300, 0x11303,
+	0x11305, 0x1130c,
+	0x1130f, 0x11310,
+	0x11313, 0x11328,
+	0x1132a, 0x11330,
+	0x11332, 0x11333,
+	0x11335, 0x11339,
+	0x1133c, 0x11344,
+	0x11347, 0x11348,
+	0x1134b, 0x1134d,
+	0x11350, 0x11350,
+	0x11357, 0x11357,
+	0x1135d, 0x11363,
+	0x11366, 0x1136c,
+	0x11370, 0x11374,
+}; /* CR_Grantha */
+
+/* 'Pahawh_Hmong': Script */
+static const OnigCodePoint CR_Pahawh_Hmong[] = {
+	5,
+	0x16b00, 0x16b45,
+	0x16b50, 0x16b59,
+	0x16b5b, 0x16b61,
+	0x16b63, 0x16b77,
+	0x16b7d, 0x16b8f,
+}; /* CR_Pahawh_Hmong */
+
+/* 'Khojki': Script */
+static const OnigCodePoint CR_Khojki[] = {
+	2,
+	0x11200, 0x11211,
+	0x11213, 0x1123e,
+}; /* CR_Khojki */
+
+/* 'Linear_A': Script */
+static const OnigCodePoint CR_Linear_A[] = {
+	3,
+	0x10600, 0x10736,
+	0x10740, 0x10755,
+	0x10760, 0x10767,
+}; /* CR_Linear_A */
+
+/* 'Mahajani': Script */
+static const OnigCodePoint CR_Mahajani[] = {
+	1,
+	0x11150, 0x11176,
+}; /* CR_Mahajani */
+
+/* 'Manichaean': Script */
+static const OnigCodePoint CR_Manichaean[] = {
+	2,
+	0x10ac0, 0x10ae6,
+	0x10aeb, 0x10af6,
+}; /* CR_Manichaean */
+
+/* 'Mende_Kikakui': Script */
+static const OnigCodePoint CR_Mende_Kikakui[] = {
+	2,
+	0x1e800, 0x1e8c4,
+	0x1e8c7, 0x1e8d6,
+}; /* CR_Mende_Kikakui */
+
+/* 'Modi': Script */
+static const OnigCodePoint CR_Modi[] = {
+	2,
+	0x11600, 0x11644,
+	0x11650, 0x11659,
+}; /* CR_Modi */
+
+/* 'Mro': Script */
+static const OnigCodePoint CR_Mro[] = {
+	3,
+	0x16a40, 0x16a5e,
+	0x16a60, 0x16a69,
+	0x16a6e, 0x16a6f,
+}; /* CR_Mro */
+
+/* 'Old_North_Arabian': Script */
+static const OnigCodePoint CR_Old_North_Arabian[] = {
+	1,
+	0x10a80, 0x10a9f,
+}; /* CR_Old_North_Arabian */
+
+/* 'Nabataean': Script */
+static const OnigCodePoint CR_Nabataean[] = {
+	2,
+	0x10880, 0x1089e,
+	0x108a7, 0x108af,
+}; /* CR_Nabataean */
+
+/* 'Palmyrene': Script */
+static const OnigCodePoint CR_Palmyrene[] = {
+	1,
+	0x10860, 0x1087f,
+}; /* CR_Palmyrene */
+
+/* 'Pau_Cin_Hau': Script */
+static const OnigCodePoint CR_Pau_Cin_Hau[] = {
+	1,
+	0x11ac0, 0x11af8,
+}; /* CR_Pau_Cin_Hau */
+
+/* 'Old_Permic': Script */
+static const OnigCodePoint CR_Old_Permic[] = {
+	1,
+	0x10350, 0x1037a,
+}; /* CR_Old_Permic */
+
+/* 'Psalter_Pahlavi': Script */
+static const OnigCodePoint CR_Psalter_Pahlavi[] = {
+	3,
+	0x10b80, 0x10b91,
+	0x10b99, 0x10b9c,
+	0x10ba9, 0x10baf,
+}; /* CR_Psalter_Pahlavi */
+
+/* 'Siddham': Script */
+static const OnigCodePoint CR_Siddham[] = {
+	2,
+	0x11580, 0x115b5,
+	0x115b8, 0x115dd,
+}; /* CR_Siddham */
+
+/* 'Khudawadi': Script */
+static const OnigCodePoint CR_Khudawadi[] = {
+	2,
+	0x112b0, 0x112ea,
+	0x112f0, 0x112f9,
+}; /* CR_Khudawadi */
+
+/* 'Tirhuta': Script */
+static const OnigCodePoint CR_Tirhuta[] = {
+	2,
+	0x11480, 0x114c7,
+	0x114d0, 0x114d9,
+}; /* CR_Tirhuta */
+
+/* 'Warang_Citi': Script */
+static const OnigCodePoint CR_Warang_Citi[] = {
+	2,
+	0x118a0, 0x118f2,
+	0x118ff, 0x118ff,
+}; /* CR_Warang_Citi */
+
+/* 'Ahom': Script */
+static const OnigCodePoint CR_Ahom[] = {
+	3,
+	0x11700, 0x11719,
+	0x1171d, 0x1172b,
+	0x11730, 0x1173f,
+}; /* CR_Ahom */
+
+/* 'Anatolian_Hieroglyphs': Script */
+static const OnigCodePoint CR_Anatolian_Hieroglyphs[] = {
+	1,
+	0x14400, 0x14646,
+}; /* CR_Anatolian_Hieroglyphs */
+
+/* 'Hatran': Script */
+static const OnigCodePoint CR_Hatran[] = {
+	3,
+	0x108e0, 0x108f2,
+	0x108f4, 0x108f5,
+	0x108fb, 0x108ff,
+}; /* CR_Hatran */
+
+/* 'Multani': Script */
+static const OnigCodePoint CR_Multani[] = {
+	5,
+	0x11280, 0x11286,
+	0x11288, 0x11288,
+	0x1128a, 0x1128d,
+	0x1128f, 0x1129d,
+	0x1129f, 0x112a9,
+}; /* CR_Multani */
+
+/* 'Old_Hungarian': Script */
+static const OnigCodePoint CR_Old_Hungarian[] = {
+	3,
+	0x10c80, 0x10cb2,
+	0x10cc0, 0x10cf2,
+	0x10cfa, 0x10cff,
+}; /* CR_Old_Hungarian */
+
+/* 'SignWriting': Script */
+static const OnigCodePoint CR_SignWriting[] = {
+	3,
+	0x1d800, 0x1da8b,
+	0x1da9b, 0x1da9f,
+	0x1daa1, 0x1daaf,
+}; /* CR_SignWriting */
+
+/* 'Adlam': Script */
+static const OnigCodePoint CR_Adlam[] = {
+	3,
+	0x1e900, 0x1e94a,
+	0x1e950, 0x1e959,
+	0x1e95e, 0x1e95f,
+}; /* CR_Adlam */
+
+/* 'Bhaiksuki': Script */
+static const OnigCodePoint CR_Bhaiksuki[] = {
+	4,
+	0x11c00, 0x11c08,
+	0x11c0a, 0x11c36,
+	0x11c38, 0x11c45,
+	0x11c50, 0x11c6c,
+}; /* CR_Bhaiksuki */
+
+/* 'Marchen': Script */
+static const OnigCodePoint CR_Marchen[] = {
+	3,
+	0x11c70, 0x11c8f,
+	0x11c92, 0x11ca7,
+	0x11ca9, 0x11cb6,
+}; /* CR_Marchen */
+
+/* 'Newa': Script */
+static const OnigCodePoint CR_Newa[] = {
+	3,
+	0x11400, 0x11459,
+	0x1145b, 0x1145b,
+	0x1145d, 0x1145d,
+}; /* CR_Newa */
+
+/* 'Osage': Script */
+static const OnigCodePoint CR_Osage[] = {
+	2,
+	0x104b0, 0x104d3,
+	0x104d8, 0x104fb,
+}; /* CR_Osage */
+
+/* 'Tangut': Script */
+static const OnigCodePoint CR_Tangut[] = {
+	3,
+	0x16fe0, 0x16fe0,
+	0x17000, 0x187ec,
+	0x18800, 0x18af2,
+}; /* CR_Tangut */
+
+/* 'Masaram_Gondi': Script */
+static const OnigCodePoint CR_Masaram_Gondi[] = {
+	7,
+	0x11d00, 0x11d06,
+	0x11d08, 0x11d09,
+	0x11d0b, 0x11d36,
+	0x11d3a, 0x11d3a,
+	0x11d3c, 0x11d3d,
+	0x11d3f, 0x11d47,
+	0x11d50, 0x11d59,
+}; /* CR_Masaram_Gondi */
+
+/* 'Nushu': Script */
+static const OnigCodePoint CR_Nushu[] = {
+	2,
+	0x16fe1, 0x16fe1,
+	0x1b170, 0x1b2fb,
+}; /* CR_Nushu */
+
+/* 'Soyombo': Script */
+static const OnigCodePoint CR_Soyombo[] = {
+	3,
+	0x11a50, 0x11a83,
+	0x11a86, 0x11a9c,
+	0x11a9e, 0x11aa2,
+}; /* CR_Soyombo */
+
+/* 'Zanabazar_Square': Script */
+static const OnigCodePoint CR_Zanabazar_Square[] = {
+	1,
+	0x11a00, 0x11a47,
+}; /* CR_Zanabazar_Square */
+
+/* 'White_Space': Binary Property */
+#define CR_White_Space CR_Space
+
+/* 'Bidi_Control': Binary Property */
+static const OnigCodePoint CR_Bidi_Control[] = {
+	4,
+	0x061c, 0x061c,
+	0x200e, 0x200f,
+	0x202a, 0x202e,
+	0x2066, 0x2069,
+}; /* CR_Bidi_Control */
+
+/* 'Join_Control': Binary Property */
+static const OnigCodePoint CR_Join_Control[] = {
+	1,
+	0x200c, 0x200d,
+}; /* CR_Join_Control */
+
+/* 'Dash': Binary Property */
+static const OnigCodePoint CR_Dash[] = {
+	21,
+	0x002d, 0x002d,
+	0x058a, 0x058a,
+	0x05be, 0x05be,
+	0x1400, 0x1400,
+	0x1806, 0x1806,
+	0x2010, 0x2015,
+	0x2053, 0x2053,
+	0x207b, 0x207b,
+	0x208b, 0x208b,
+	0x2212, 0x2212,
+	0x2e17, 0x2e17,
+	0x2e1a, 0x2e1a,
+	0x2e3a, 0x2e3b,
+	0x2e40, 0x2e40,
+	0x301c, 0x301c,
+	0x3030, 0x3030,
+	0x30a0, 0x30a0,
+	0xfe31, 0xfe32,
+	0xfe58, 0xfe58,
+	0xfe63, 0xfe63,
+	0xff0d, 0xff0d,
+}; /* CR_Dash */
+
+/* 'Hyphen': Binary Property */
+static const OnigCodePoint CR_Hyphen[] = {
+	10,
+	0x002d, 0x002d,
+	0x00ad, 0x00ad,
+	0x058a, 0x058a,
+	0x1806, 0x1806,
+	0x2010, 0x2011,
+	0x2e17, 0x2e17,
+	0x30fb, 0x30fb,
+	0xfe63, 0xfe63,
+	0xff0d, 0xff0d,
+	0xff65, 0xff65,
+}; /* CR_Hyphen */
+
+/* 'Quotation_Mark': Binary Property */
+static const OnigCodePoint CR_Quotation_Mark[] = {
+	13,
+	0x0022, 0x0022,
+	0x0027, 0x0027,
+	0x00ab, 0x00ab,
+	0x00bb, 0x00bb,
+	0x2018, 0x201f,
+	0x2039, 0x203a,
+	0x2e42, 0x2e42,
+	0x300c, 0x300f,
+	0x301d, 0x301f,
+	0xfe41, 0xfe44,
+	0xff02, 0xff02,
+	0xff07, 0xff07,
+	0xff62, 0xff63,
+}; /* CR_Quotation_Mark */
+
+/* 'Terminal_Punctuation': Binary Property */
+static const OnigCodePoint CR_Terminal_Punctuation[] = {
+	97,
+	0x0021, 0x0021,
+	0x002c, 0x002c,
+	0x002e, 0x002e,
+	0x003a, 0x003b,
+	0x003f, 0x003f,
+	0x037e, 0x037e,
+	0x0387, 0x0387,
+	0x0589, 0x0589,
+	0x05c3, 0x05c3,
+	0x060c, 0x060c,
+	0x061b, 0x061b,
+	0x061f, 0x061f,
+	0x06d4, 0x06d4,
+	0x0700, 0x070a,
+	0x070c, 0x070c,
+	0x07f8, 0x07f9,
+	0x0830, 0x083e,
+	0x085e, 0x085e,
+	0x0964, 0x0965,
+	0x0e5a, 0x0e5b,
+	0x0f08, 0x0f08,
+	0x0f0d, 0x0f12,
+	0x104a, 0x104b,
+	0x1361, 0x1368,
+	0x166d, 0x166e,
+	0x16eb, 0x16ed,
+	0x1735, 0x1736,
+	0x17d4, 0x17d6,
+	0x17da, 0x17da,
+	0x1802, 0x1805,
+	0x1808, 0x1809,
+	0x1944, 0x1945,
+	0x1aa8, 0x1aab,
+	0x1b5a, 0x1b5b,
+	0x1b5d, 0x1b5f,
+	0x1c3b, 0x1c3f,
+	0x1c7e, 0x1c7f,
+	0x203c, 0x203d,
+	0x2047, 0x2049,
+	0x2e2e, 0x2e2e,
+	0x2e3c, 0x2e3c,
+	0x2e41, 0x2e41,
+	0x3001, 0x3002,
+	0xa4fe, 0xa4ff,
+	0xa60d, 0xa60f,
+	0xa6f3, 0xa6f7,
+	0xa876, 0xa877,
+	0xa8ce, 0xa8cf,
+	0xa92f, 0xa92f,
+	0xa9c7, 0xa9c9,
+	0xaa5d, 0xaa5f,
+	0xaadf, 0xaadf,
+	0xaaf0, 0xaaf1,
+	0xabeb, 0xabeb,
+	0xfe50, 0xfe52,
+	0xfe54, 0xfe57,
+	0xff01, 0xff01,
+	0xff0c, 0xff0c,
+	0xff0e, 0xff0e,
+	0xff1a, 0xff1b,
+	0xff1f, 0xff1f,
+	0xff61, 0xff61,
+	0xff64, 0xff64,
+	0x1039f, 0x1039f,
+	0x103d0, 0x103d0,
+	0x10857, 0x10857,
+	0x1091f, 0x1091f,
+	0x10a56, 0x10a57,
+	0x10af0, 0x10af5,
+	0x10b3a, 0x10b3f,
+	0x10b99, 0x10b9c,
+	0x11047, 0x1104d,
+	0x110be, 0x110c1,
+	0x11141, 0x11143,
+	0x111c5, 0x111c6,
+	0x111cd, 0x111cd,
+	0x111de, 0x111df,
+	0x11238, 0x1123c,
+	0x112a9, 0x112a9,
+	0x1144b, 0x1144d,
+	0x1145b, 0x1145b,
+	0x115c2, 0x115c5,
+	0x115c9, 0x115d7,
+	0x11641, 0x11642,
+	0x1173c, 0x1173e,
+	0x11a42, 0x11a43,
+	0x11a9b, 0x11a9c,
+	0x11aa1, 0x11aa2,
+	0x11c41, 0x11c43,
+	0x11c71, 0x11c71,
+	0x12470, 0x12474,
+	0x16a6e, 0x16a6f,
+	0x16af5, 0x16af5,
+	0x16b37, 0x16b39,
+	0x16b44, 0x16b44,
+	0x1bc9f, 0x1bc9f,
+	0x1da87, 0x1da8a,
+}; /* CR_Terminal_Punctuation */
+
+/* 'Other_Math': Binary Property */
+static const OnigCodePoint CR_Other_Math[] = {
+	134,
+	0x005e, 0x005e,
+	0x03d0, 0x03d2,
+	0x03d5, 0x03d5,
+	0x03f0, 0x03f1,
+	0x03f4, 0x03f5,
+	0x2016, 0x2016,
+	0x2032, 0x2034,
+	0x2040, 0x2040,
+	0x2061, 0x2064,
+	0x207d, 0x207e,
+	0x208d, 0x208e,
+	0x20d0, 0x20dc,
+	0x20e1, 0x20e1,
+	0x20e5, 0x20e6,
+	0x20eb, 0x20ef,
+	0x2102, 0x2102,
+	0x2107, 0x2107,
+	0x210a, 0x2113,
+	0x2115, 0x2115,
+	0x2119, 0x211d,
+	0x2124, 0x2124,
+	0x2128, 0x2129,
+	0x212c, 0x212d,
+	0x212f, 0x2131,
+	0x2133, 0x2138,
+	0x213c, 0x213f,
+	0x2145, 0x2149,
+	0x2195, 0x2199,
+	0x219c, 0x219f,
+	0x21a1, 0x21a2,
+	0x21a4, 0x21a5,
+	0x21a7, 0x21a7,
+	0x21a9, 0x21ad,
+	0x21b0, 0x21b1,
+	0x21b6, 0x21b7,
+	0x21bc, 0x21cd,
+	0x21d0, 0x21d1,
+	0x21d3, 0x21d3,
+	0x21d5, 0x21db,
+	0x21dd, 0x21dd,
+	0x21e4, 0x21e5,
+	0x2308, 0x230b,
+	0x23b4, 0x23b5,
+	0x23b7, 0x23b7,
+	0x23d0, 0x23d0,
+	0x23e2, 0x23e2,
+	0x25a0, 0x25a1,
+	0x25ae, 0x25b6,
+	0x25bc, 0x25c0,
+	0x25c6, 0x25c7,
+	0x25ca, 0x25cb,
+	0x25cf, 0x25d3,
+	0x25e2, 0x25e2,
+	0x25e4, 0x25e4,
+	0x25e7, 0x25ec,
+	0x2605, 0x2606,
+	0x2640, 0x2640,
+	0x2642, 0x2642,
+	0x2660, 0x2663,
+	0x266d, 0x266e,
+	0x27c5, 0x27c6,
+	0x27e6, 0x27ef,
+	0x2983, 0x2998,
+	0x29d8, 0x29db,
+	0x29fc, 0x29fd,
+	0xfe61, 0xfe61,
+	0xfe63, 0xfe63,
+	0xfe68, 0xfe68,
+	0xff3c, 0xff3c,
+	0xff3e, 0xff3e,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d6c0,
+	0x1d6c2, 0x1d6da,
+	0x1d6dc, 0x1d6fa,
+	0x1d6fc, 0x1d714,
+	0x1d716, 0x1d734,
+	0x1d736, 0x1d74e,
+	0x1d750, 0x1d76e,
+	0x1d770, 0x1d788,
+	0x1d78a, 0x1d7a8,
+	0x1d7aa, 0x1d7c2,
+	0x1d7c4, 0x1d7cb,
+	0x1d7ce, 0x1d7ff,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+}; /* CR_Other_Math */
+
+/* 'Hex_Digit': Binary Property */
+static const OnigCodePoint CR_Hex_Digit[] = {
+	6,
+	0x0030, 0x0039,
+	0x0041, 0x0046,
+	0x0061, 0x0066,
+	0xff10, 0xff19,
+	0xff21, 0xff26,
+	0xff41, 0xff46,
+}; /* CR_Hex_Digit */
+
+/* 'ASCII_Hex_Digit': Binary Property */
+#define CR_ASCII_Hex_Digit CR_XDigit
+
+/* 'Other_Alphabetic': Binary Property */
+static const OnigCodePoint CR_Other_Alphabetic[] = {
+	206,
+	0x0345, 0x0345,
+	0x05b0, 0x05bd,
+	0x05bf, 0x05bf,
+	0x05c1, 0x05c2,
+	0x05c4, 0x05c5,
+	0x05c7, 0x05c7,
+	0x0610, 0x061a,
+	0x064b, 0x0657,
+	0x0659, 0x065f,
+	0x0670, 0x0670,
+	0x06d6, 0x06dc,
+	0x06e1, 0x06e4,
+	0x06e7, 0x06e8,
+	0x06ed, 0x06ed,
+	0x0711, 0x0711,
+	0x0730, 0x073f,
+	0x07a6, 0x07b0,
+	0x0816, 0x0817,
+	0x081b, 0x0823,
+	0x0825, 0x0827,
+	0x0829, 0x082c,
+	0x08d4, 0x08df,
+	0x08e3, 0x08e9,
+	0x08f0, 0x0903,
+	0x093a, 0x093b,
+	0x093e, 0x094c,
+	0x094e, 0x094f,
+	0x0955, 0x0957,
+	0x0962, 0x0963,
+	0x0981, 0x0983,
+	0x09be, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09cc,
+	0x09d7, 0x09d7,
+	0x09e2, 0x09e3,
+	0x0a01, 0x0a03,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4c,
+	0x0a51, 0x0a51,
+	0x0a70, 0x0a71,
+	0x0a75, 0x0a75,
+	0x0a81, 0x0a83,
+	0x0abe, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acc,
+	0x0ae2, 0x0ae3,
+	0x0afa, 0x0afc,
+	0x0b01, 0x0b03,
+	0x0b3e, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4c,
+	0x0b56, 0x0b57,
+	0x0b62, 0x0b63,
+	0x0b82, 0x0b82,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcc,
+	0x0bd7, 0x0bd7,
+	0x0c00, 0x0c03,
+	0x0c3e, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4c,
+	0x0c55, 0x0c56,
+	0x0c62, 0x0c63,
+	0x0c81, 0x0c83,
+	0x0cbe, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccc,
+	0x0cd5, 0x0cd6,
+	0x0ce2, 0x0ce3,
+	0x0d00, 0x0d03,
+	0x0d3e, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4c,
+	0x0d57, 0x0d57,
+	0x0d62, 0x0d63,
+	0x0d82, 0x0d83,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0df2, 0x0df3,
+	0x0e31, 0x0e31,
+	0x0e34, 0x0e3a,
+	0x0e4d, 0x0e4d,
+	0x0eb1, 0x0eb1,
+	0x0eb4, 0x0eb9,
+	0x0ebb, 0x0ebc,
+	0x0ecd, 0x0ecd,
+	0x0f71, 0x0f81,
+	0x0f8d, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x102b, 0x1036,
+	0x1038, 0x1038,
+	0x103b, 0x103e,
+	0x1056, 0x1059,
+	0x105e, 0x1060,
+	0x1062, 0x1062,
+	0x1067, 0x1068,
+	0x1071, 0x1074,
+	0x1082, 0x1086,
+	0x109c, 0x109d,
+	0x135f, 0x135f,
+	0x1712, 0x1713,
+	0x1732, 0x1733,
+	0x1752, 0x1753,
+	0x1772, 0x1773,
+	0x17b6, 0x17c8,
+	0x1885, 0x1886,
+	0x18a9, 0x18a9,
+	0x1920, 0x192b,
+	0x1930, 0x1938,
+	0x1a17, 0x1a1b,
+	0x1a55, 0x1a5e,
+	0x1a61, 0x1a74,
+	0x1b00, 0x1b04,
+	0x1b35, 0x1b43,
+	0x1b80, 0x1b82,
+	0x1ba1, 0x1ba9,
+	0x1bac, 0x1bad,
+	0x1be7, 0x1bf1,
+	0x1c24, 0x1c35,
+	0x1cf2, 0x1cf3,
+	0x1de7, 0x1df4,
+	0x24b6, 0x24e9,
+	0x2de0, 0x2dff,
+	0xa674, 0xa67b,
+	0xa69e, 0xa69f,
+	0xa823, 0xa827,
+	0xa880, 0xa881,
+	0xa8b4, 0xa8c3,
+	0xa8c5, 0xa8c5,
+	0xa926, 0xa92a,
+	0xa947, 0xa952,
+	0xa980, 0xa983,
+	0xa9b4, 0xa9bf,
+	0xaa29, 0xaa36,
+	0xaa43, 0xaa43,
+	0xaa4c, 0xaa4d,
+	0xaab0, 0xaab0,
+	0xaab2, 0xaab4,
+	0xaab7, 0xaab8,
+	0xaabe, 0xaabe,
+	0xaaeb, 0xaaef,
+	0xaaf5, 0xaaf5,
+	0xabe3, 0xabea,
+	0xfb1e, 0xfb1e,
+	0x10376, 0x1037a,
+	0x10a01, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a0f,
+	0x11000, 0x11002,
+	0x11038, 0x11045,
+	0x11082, 0x11082,
+	0x110b0, 0x110b8,
+	0x11100, 0x11102,
+	0x11127, 0x11132,
+	0x11180, 0x11182,
+	0x111b3, 0x111bf,
+	0x1122c, 0x11234,
+	0x11237, 0x11237,
+	0x1123e, 0x1123e,
+	0x112df, 0x112e8,
+	0x11300, 0x11303,
+	0x1133e, 0x11344,
+	0x11347, 0x11348,
+	0x1134b, 0x1134c,
+	0x11357, 0x11357,
+	0x11362, 0x11363,
+	0x11435, 0x11441,
+	0x11443, 0x11445,
+	0x114b0, 0x114c1,
+	0x115af, 0x115b5,
+	0x115b8, 0x115be,
+	0x115dc, 0x115dd,
+	0x11630, 0x1163e,
+	0x11640, 0x11640,
+	0x116ab, 0x116b5,
+	0x1171d, 0x1172a,
+	0x11a01, 0x11a0a,
+	0x11a35, 0x11a39,
+	0x11a3b, 0x11a3e,
+	0x11a51, 0x11a5b,
+	0x11a8a, 0x11a97,
+	0x11c2f, 0x11c36,
+	0x11c38, 0x11c3e,
+	0x11c92, 0x11ca7,
+	0x11ca9, 0x11cb6,
+	0x11d31, 0x11d36,
+	0x11d3a, 0x11d3a,
+	0x11d3c, 0x11d3d,
+	0x11d3f, 0x11d41,
+	0x11d43, 0x11d43,
+	0x11d47, 0x11d47,
+	0x16b30, 0x16b36,
+	0x16f51, 0x16f7e,
+	0x1bc9e, 0x1bc9e,
+	0x1e000, 0x1e006,
+	0x1e008, 0x1e018,
+	0x1e01b, 0x1e021,
+	0x1e023, 0x1e024,
+	0x1e026, 0x1e02a,
+	0x1e947, 0x1e947,
+	0x1f130, 0x1f149,
+	0x1f150, 0x1f169,
+	0x1f170, 0x1f189,
+}; /* CR_Other_Alphabetic */
+
+/* 'Ideographic': Binary Property */
+static const OnigCodePoint CR_Ideographic[] = {
+	16,
+	0x3006, 0x3007,
+	0x3021, 0x3029,
+	0x3038, 0x303a,
+	0x3400, 0x4db5,
+	0x4e00, 0x9fea,
+	0xf900, 0xfa6d,
+	0xfa70, 0xfad9,
+	0x17000, 0x187ec,
+	0x18800, 0x18af2,
+	0x1b170, 0x1b2fb,
+	0x20000, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2b820, 0x2cea1,
+	0x2ceb0, 0x2ebe0,
+	0x2f800, 0x2fa1d,
+}; /* CR_Ideographic */
+
+/* 'Diacritic': Binary Property */
+static const OnigCodePoint CR_Diacritic[] = {
+	159,
+	0x005e, 0x005e,
+	0x0060, 0x0060,
+	0x00a8, 0x00a8,
+	0x00af, 0x00af,
+	0x00b4, 0x00b4,
+	0x00b7, 0x00b8,
+	0x02b0, 0x034e,
+	0x0350, 0x0357,
+	0x035d, 0x0362,
+	0x0374, 0x0375,
+	0x037a, 0x037a,
+	0x0384, 0x0385,
+	0x0483, 0x0487,
+	0x0559, 0x0559,
+	0x0591, 0x05a1,
+	0x05a3, 0x05bd,
+	0x05bf, 0x05bf,
+	0x05c1, 0x05c2,
+	0x05c4, 0x05c4,
+	0x064b, 0x0652,
+	0x0657, 0x0658,
+	0x06df, 0x06e0,
+	0x06e5, 0x06e6,
+	0x06ea, 0x06ec,
+	0x0730, 0x074a,
+	0x07a6, 0x07b0,
+	0x07eb, 0x07f5,
+	0x0818, 0x0819,
+	0x08e3, 0x08fe,
+	0x093c, 0x093c,
+	0x094d, 0x094d,
+	0x0951, 0x0954,
+	0x0971, 0x0971,
+	0x09bc, 0x09bc,
+	0x09cd, 0x09cd,
+	0x0a3c, 0x0a3c,
+	0x0a4d, 0x0a4d,
+	0x0abc, 0x0abc,
+	0x0acd, 0x0acd,
+	0x0afd, 0x0aff,
+	0x0b3c, 0x0b3c,
+	0x0b4d, 0x0b4d,
+	0x0bcd, 0x0bcd,
+	0x0c4d, 0x0c4d,
+	0x0cbc, 0x0cbc,
+	0x0ccd, 0x0ccd,
+	0x0d3b, 0x0d3c,
+	0x0d4d, 0x0d4d,
+	0x0dca, 0x0dca,
+	0x0e47, 0x0e4c,
+	0x0e4e, 0x0e4e,
+	0x0ec8, 0x0ecc,
+	0x0f18, 0x0f19,
+	0x0f35, 0x0f35,
+	0x0f37, 0x0f37,
+	0x0f39, 0x0f39,
+	0x0f3e, 0x0f3f,
+	0x0f82, 0x0f84,
+	0x0f86, 0x0f87,
+	0x0fc6, 0x0fc6,
+	0x1037, 0x1037,
+	0x1039, 0x103a,
+	0x1087, 0x108d,
+	0x108f, 0x108f,
+	0x109a, 0x109b,
+	0x17c9, 0x17d3,
+	0x17dd, 0x17dd,
+	0x1939, 0x193b,
+	0x1a75, 0x1a7c,
+	0x1a7f, 0x1a7f,
+	0x1ab0, 0x1abd,
+	0x1b34, 0x1b34,
+	0x1b44, 0x1b44,
+	0x1b6b, 0x1b73,
+	0x1baa, 0x1bab,
+	0x1c36, 0x1c37,
+	0x1c78, 0x1c7d,
+	0x1cd0, 0x1ce8,
+	0x1ced, 0x1ced,
+	0x1cf4, 0x1cf4,
+	0x1cf7, 0x1cf9,
+	0x1d2c, 0x1d6a,
+	0x1dc4, 0x1dcf,
+	0x1df5, 0x1df9,
+	0x1dfd, 0x1dff,
+	0x1fbd, 0x1fbd,
+	0x1fbf, 0x1fc1,
+	0x1fcd, 0x1fcf,
+	0x1fdd, 0x1fdf,
+	0x1fed, 0x1fef,
+	0x1ffd, 0x1ffe,
+	0x2cef, 0x2cf1,
+	0x2e2f, 0x2e2f,
+	0x302a, 0x302f,
+	0x3099, 0x309c,
+	0x30fc, 0x30fc,
+	0xa66f, 0xa66f,
+	0xa67c, 0xa67d,
+	0xa67f, 0xa67f,
+	0xa69c, 0xa69d,
+	0xa6f0, 0xa6f1,
+	0xa717, 0xa721,
+	0xa788, 0xa788,
+	0xa7f8, 0xa7f9,
+	0xa8c4, 0xa8c4,
+	0xa8e0, 0xa8f1,
+	0xa92b, 0xa92e,
+	0xa953, 0xa953,
+	0xa9b3, 0xa9b3,
+	0xa9c0, 0xa9c0,
+	0xa9e5, 0xa9e5,
+	0xaa7b, 0xaa7d,
+	0xaabf, 0xaac2,
+	0xaaf6, 0xaaf6,
+	0xab5b, 0xab5f,
+	0xabec, 0xabed,
+	0xfb1e, 0xfb1e,
+	0xfe20, 0xfe2f,
+	0xff3e, 0xff3e,
+	0xff40, 0xff40,
+	0xff70, 0xff70,
+	0xff9e, 0xff9f,
+	0xffe3, 0xffe3,
+	0x102e0, 0x102e0,
+	0x10ae5, 0x10ae6,
+	0x110b9, 0x110ba,
+	0x11133, 0x11134,
+	0x11173, 0x11173,
+	0x111c0, 0x111c0,
+	0x111ca, 0x111cc,
+	0x11235, 0x11236,
+	0x112e9, 0x112ea,
+	0x1133c, 0x1133c,
+	0x1134d, 0x1134d,
+	0x11366, 0x1136c,
+	0x11370, 0x11374,
+	0x11442, 0x11442,
+	0x11446, 0x11446,
+	0x114c2, 0x114c3,
+	0x115bf, 0x115c0,
+	0x1163f, 0x1163f,
+	0x116b6, 0x116b7,
+	0x1172b, 0x1172b,
+	0x11a34, 0x11a34,
+	0x11a47, 0x11a47,
+	0x11a99, 0x11a99,
+	0x11c3f, 0x11c3f,
+	0x11d42, 0x11d42,
+	0x11d44, 0x11d45,
+	0x16af0, 0x16af4,
+	0x16f8f, 0x16f9f,
+	0x1d167, 0x1d169,
+	0x1d16d, 0x1d172,
+	0x1d17b, 0x1d182,
+	0x1d185, 0x1d18b,
+	0x1d1aa, 0x1d1ad,
+	0x1e8d0, 0x1e8d6,
+	0x1e944, 0x1e946,
+	0x1e948, 0x1e94a,
+}; /* CR_Diacritic */
+
+/* 'Extender': Binary Property */
+static const OnigCodePoint CR_Extender[] = {
+	29,
+	0x00b7, 0x00b7,
+	0x02d0, 0x02d1,
+	0x0640, 0x0640,
+	0x07fa, 0x07fa,
+	0x0e46, 0x0e46,
+	0x0ec6, 0x0ec6,
+	0x180a, 0x180a,
+	0x1843, 0x1843,
+	0x1aa7, 0x1aa7,
+	0x1c36, 0x1c36,
+	0x1c7b, 0x1c7b,
+	0x3005, 0x3005,
+	0x3031, 0x3035,
+	0x309d, 0x309e,
+	0x30fc, 0x30fe,
+	0xa015, 0xa015,
+	0xa60c, 0xa60c,
+	0xa9cf, 0xa9cf,
+	0xa9e6, 0xa9e6,
+	0xaa70, 0xaa70,
+	0xaadd, 0xaadd,
+	0xaaf3, 0xaaf4,
+	0xff70, 0xff70,
+	0x1135d, 0x1135d,
+	0x115c6, 0x115c8,
+	0x11a98, 0x11a98,
+	0x16b42, 0x16b43,
+	0x16fe0, 0x16fe1,
+	0x1e944, 0x1e946,
+}; /* CR_Extender */
+
+/* 'Other_Lowercase': Binary Property */
+static const OnigCodePoint CR_Other_Lowercase[] = {
+	20,
+	0x00aa, 0x00aa,
+	0x00ba, 0x00ba,
+	0x02b0, 0x02b8,
+	0x02c0, 0x02c1,
+	0x02e0, 0x02e4,
+	0x0345, 0x0345,
+	0x037a, 0x037a,
+	0x1d2c, 0x1d6a,
+	0x1d78, 0x1d78,
+	0x1d9b, 0x1dbf,
+	0x2071, 0x2071,
+	0x207f, 0x207f,
+	0x2090, 0x209c,
+	0x2170, 0x217f,
+	0x24d0, 0x24e9,
+	0x2c7c, 0x2c7d,
+	0xa69c, 0xa69d,
+	0xa770, 0xa770,
+	0xa7f8, 0xa7f9,
+	0xab5c, 0xab5f,
+}; /* CR_Other_Lowercase */
+
+/* 'Other_Uppercase': Binary Property */
+static const OnigCodePoint CR_Other_Uppercase[] = {
+	5,
+	0x2160, 0x216f,
+	0x24b6, 0x24cf,
+	0x1f130, 0x1f149,
+	0x1f150, 0x1f169,
+	0x1f170, 0x1f189,
+}; /* CR_Other_Uppercase */
+
+/* 'Noncharacter_Code_Point': Binary Property */
+static const OnigCodePoint CR_Noncharacter_Code_Point[] = {
+	18,
+	0xfdd0, 0xfdef,
+	0xfffe, 0xffff,
+	0x1fffe, 0x1ffff,
+	0x2fffe, 0x2ffff,
+	0x3fffe, 0x3ffff,
+	0x4fffe, 0x4ffff,
+	0x5fffe, 0x5ffff,
+	0x6fffe, 0x6ffff,
+	0x7fffe, 0x7ffff,
+	0x8fffe, 0x8ffff,
+	0x9fffe, 0x9ffff,
+	0xafffe, 0xaffff,
+	0xbfffe, 0xbffff,
+	0xcfffe, 0xcffff,
+	0xdfffe, 0xdffff,
+	0xefffe, 0xeffff,
+	0xffffe, 0xfffff,
+	0x10fffe, 0x10ffff,
+}; /* CR_Noncharacter_Code_Point */
+
+/* 'Other_Grapheme_Extend': Binary Property */
+static const OnigCodePoint CR_Other_Grapheme_Extend[] = {
+	23,
+	0x09be, 0x09be,
+	0x09d7, 0x09d7,
+	0x0b3e, 0x0b3e,
+	0x0b57, 0x0b57,
+	0x0bbe, 0x0bbe,
+	0x0bd7, 0x0bd7,
+	0x0cc2, 0x0cc2,
+	0x0cd5, 0x0cd6,
+	0x0d3e, 0x0d3e,
+	0x0d57, 0x0d57,
+	0x0dcf, 0x0dcf,
+	0x0ddf, 0x0ddf,
+	0x200c, 0x200c,
+	0x302e, 0x302f,
+	0xff9e, 0xff9f,
+	0x1133e, 0x1133e,
+	0x11357, 0x11357,
+	0x114b0, 0x114b0,
+	0x114bd, 0x114bd,
+	0x115af, 0x115af,
+	0x1d165, 0x1d165,
+	0x1d16e, 0x1d172,
+	0xe0020, 0xe007f,
+}; /* CR_Other_Grapheme_Extend */
+
+/* 'IDS_Binary_Operator': Binary Property */
+static const OnigCodePoint CR_IDS_Binary_Operator[] = {
+	2,
+	0x2ff0, 0x2ff1,
+	0x2ff4, 0x2ffb,
+}; /* CR_IDS_Binary_Operator */
+
+/* 'IDS_Trinary_Operator': Binary Property */
+static const OnigCodePoint CR_IDS_Trinary_Operator[] = {
+	1,
+	0x2ff2, 0x2ff3,
+}; /* CR_IDS_Trinary_Operator */
+
+/* 'Radical': Binary Property */
+static const OnigCodePoint CR_Radical[] = {
+	3,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+}; /* CR_Radical */
+
+/* 'Unified_Ideograph': Binary Property */
+static const OnigCodePoint CR_Unified_Ideograph[] = {
+	14,
+	0x3400, 0x4db5,
+	0x4e00, 0x9fea,
+	0xfa0e, 0xfa0f,
+	0xfa11, 0xfa11,
+	0xfa13, 0xfa14,
+	0xfa1f, 0xfa1f,
+	0xfa21, 0xfa21,
+	0xfa23, 0xfa24,
+	0xfa27, 0xfa29,
+	0x20000, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2b820, 0x2cea1,
+	0x2ceb0, 0x2ebe0,
+}; /* CR_Unified_Ideograph */
+
+/* 'Other_Default_Ignorable_Code_Point': Binary Property */
+static const OnigCodePoint CR_Other_Default_Ignorable_Code_Point[] = {
+	11,
+	0x034f, 0x034f,
+	0x115f, 0x1160,
+	0x17b4, 0x17b5,
+	0x2065, 0x2065,
+	0x3164, 0x3164,
+	0xffa0, 0xffa0,
+	0xfff0, 0xfff8,
+	0xe0000, 0xe0000,
+	0xe0002, 0xe001f,
+	0xe0080, 0xe00ff,
+	0xe01f0, 0xe0fff,
+}; /* CR_Other_Default_Ignorable_Code_Point */
+
+/* 'Deprecated': Binary Property */
+static const OnigCodePoint CR_Deprecated[] = {
+	8,
+	0x0149, 0x0149,
+	0x0673, 0x0673,
+	0x0f77, 0x0f77,
+	0x0f79, 0x0f79,
+	0x17a3, 0x17a4,
+	0x206a, 0x206f,
+	0x2329, 0x232a,
+	0xe0001, 0xe0001,
+}; /* CR_Deprecated */
+
+/* 'Soft_Dotted': Binary Property */
+static const OnigCodePoint CR_Soft_Dotted[] = {
+	31,
+	0x0069, 0x006a,
+	0x012f, 0x012f,
+	0x0249, 0x0249,
+	0x0268, 0x0268,
+	0x029d, 0x029d,
+	0x02b2, 0x02b2,
+	0x03f3, 0x03f3,
+	0x0456, 0x0456,
+	0x0458, 0x0458,
+	0x1d62, 0x1d62,
+	0x1d96, 0x1d96,
+	0x1da4, 0x1da4,
+	0x1da8, 0x1da8,
+	0x1e2d, 0x1e2d,
+	0x1ecb, 0x1ecb,
+	0x2071, 0x2071,
+	0x2148, 0x2149,
+	0x2c7c, 0x2c7c,
+	0x1d422, 0x1d423,
+	0x1d456, 0x1d457,
+	0x1d48a, 0x1d48b,
+	0x1d4be, 0x1d4bf,
+	0x1d4f2, 0x1d4f3,
+	0x1d526, 0x1d527,
+	0x1d55a, 0x1d55b,
+	0x1d58e, 0x1d58f,
+	0x1d5c2, 0x1d5c3,
+	0x1d5f6, 0x1d5f7,
+	0x1d62a, 0x1d62b,
+	0x1d65e, 0x1d65f,
+	0x1d692, 0x1d693,
+}; /* CR_Soft_Dotted */
+
+/* 'Logical_Order_Exception': Binary Property */
+static const OnigCodePoint CR_Logical_Order_Exception[] = {
+	7,
+	0x0e40, 0x0e44,
+	0x0ec0, 0x0ec4,
+	0x19b5, 0x19b7,
+	0x19ba, 0x19ba,
+	0xaab5, 0xaab6,
+	0xaab9, 0xaab9,
+	0xaabb, 0xaabc,
+}; /* CR_Logical_Order_Exception */
+
+/* 'Other_ID_Start': Binary Property */
+static const OnigCodePoint CR_Other_ID_Start[] = {
+	4,
+	0x1885, 0x1886,
+	0x2118, 0x2118,
+	0x212e, 0x212e,
+	0x309b, 0x309c,
+}; /* CR_Other_ID_Start */
+
+/* 'Other_ID_Continue': Binary Property */
+static const OnigCodePoint CR_Other_ID_Continue[] = {
+	4,
+	0x00b7, 0x00b7,
+	0x0387, 0x0387,
+	0x1369, 0x1371,
+	0x19da, 0x19da,
+}; /* CR_Other_ID_Continue */
+
+/* 'Sentence_Terminal': Binary Property */
+static const OnigCodePoint CR_Sentence_Terminal[] = {
+	68,
+	0x0021, 0x0021,
+	0x002e, 0x002e,
+	0x003f, 0x003f,
+	0x0589, 0x0589,
+	0x061f, 0x061f,
+	0x06d4, 0x06d4,
+	0x0700, 0x0702,
+	0x07f9, 0x07f9,
+	0x0964, 0x0965,
+	0x104a, 0x104b,
+	0x1362, 0x1362,
+	0x1367, 0x1368,
+	0x166e, 0x166e,
+	0x1735, 0x1736,
+	0x1803, 0x1803,
+	0x1809, 0x1809,
+	0x1944, 0x1945,
+	0x1aa8, 0x1aab,
+	0x1b5a, 0x1b5b,
+	0x1b5e, 0x1b5f,
+	0x1c3b, 0x1c3c,
+	0x1c7e, 0x1c7f,
+	0x203c, 0x203d,
+	0x2047, 0x2049,
+	0x2e2e, 0x2e2e,
+	0x2e3c, 0x2e3c,
+	0x3002, 0x3002,
+	0xa4ff, 0xa4ff,
+	0xa60e, 0xa60f,
+	0xa6f3, 0xa6f3,
+	0xa6f7, 0xa6f7,
+	0xa876, 0xa877,
+	0xa8ce, 0xa8cf,
+	0xa92f, 0xa92f,
+	0xa9c8, 0xa9c9,
+	0xaa5d, 0xaa5f,
+	0xaaf0, 0xaaf1,
+	0xabeb, 0xabeb,
+	0xfe52, 0xfe52,
+	0xfe56, 0xfe57,
+	0xff01, 0xff01,
+	0xff0e, 0xff0e,
+	0xff1f, 0xff1f,
+	0xff61, 0xff61,
+	0x10a56, 0x10a57,
+	0x11047, 0x11048,
+	0x110be, 0x110c1,
+	0x11141, 0x11143,
+	0x111c5, 0x111c6,
+	0x111cd, 0x111cd,
+	0x111de, 0x111df,
+	0x11238, 0x11239,
+	0x1123b, 0x1123c,
+	0x112a9, 0x112a9,
+	0x1144b, 0x1144c,
+	0x115c2, 0x115c3,
+	0x115c9, 0x115d7,
+	0x11641, 0x11642,
+	0x1173c, 0x1173e,
+	0x11a42, 0x11a43,
+	0x11a9b, 0x11a9c,
+	0x11c41, 0x11c42,
+	0x16a6e, 0x16a6f,
+	0x16af5, 0x16af5,
+	0x16b37, 0x16b38,
+	0x16b44, 0x16b44,
+	0x1bc9f, 0x1bc9f,
+	0x1da88, 0x1da88,
+}; /* CR_Sentence_Terminal */
+
+/* 'Variation_Selector': Binary Property */
+static const OnigCodePoint CR_Variation_Selector[] = {
+	3,
+	0x180b, 0x180d,
+	0xfe00, 0xfe0f,
+	0xe0100, 0xe01ef,
+}; /* CR_Variation_Selector */
+
+/* 'Pattern_White_Space': Binary Property */
+static const OnigCodePoint CR_Pattern_White_Space[] = {
+	5,
+	0x0009, 0x000d,
+	0x0020, 0x0020,
+	0x0085, 0x0085,
+	0x200e, 0x200f,
+	0x2028, 0x2029,
+}; /* CR_Pattern_White_Space */
+
+/* 'Pattern_Syntax': Binary Property */
+static const OnigCodePoint CR_Pattern_Syntax[] = {
+	28,
+	0x0021, 0x002f,
+	0x003a, 0x0040,
+	0x005b, 0x005e,
+	0x0060, 0x0060,
+	0x007b, 0x007e,
+	0x00a1, 0x00a7,
+	0x00a9, 0x00a9,
+	0x00ab, 0x00ac,
+	0x00ae, 0x00ae,
+	0x00b0, 0x00b1,
+	0x00b6, 0x00b6,
+	0x00bb, 0x00bb,
+	0x00bf, 0x00bf,
+	0x00d7, 0x00d7,
+	0x00f7, 0x00f7,
+	0x2010, 0x2027,
+	0x2030, 0x203e,
+	0x2041, 0x2053,
+	0x2055, 0x205e,
+	0x2190, 0x245f,
+	0x2500, 0x2775,
+	0x2794, 0x2bff,
+	0x2e00, 0x2e7f,
+	0x3001, 0x3003,
+	0x3008, 0x3020,
+	0x3030, 0x3030,
+	0xfd3e, 0xfd3f,
+	0xfe45, 0xfe46,
+}; /* CR_Pattern_Syntax */
+
+/* 'Prepended_Concatenation_Mark': Binary Property */
+static const OnigCodePoint CR_Prepended_Concatenation_Mark[] = {
+	5,
+	0x0600, 0x0605,
+	0x06dd, 0x06dd,
+	0x070f, 0x070f,
+	0x08e2, 0x08e2,
+	0x110bd, 0x110bd,
+}; /* CR_Prepended_Concatenation_Mark */
+
+/* 'Regional_Indicator': Binary Property */
+static const OnigCodePoint CR_Regional_Indicator[] = {
+	1,
+	0x1f1e6, 0x1f1ff,
+}; /* CR_Regional_Indicator */
+
+/* 'Emoji': Emoji */
+static const OnigCodePoint CR_Emoji[] = {
+	145,
+	0x0023, 0x0023,
+	0x002a, 0x002a,
+	0x0030, 0x0039,
+	0x00a9, 0x00a9,
+	0x00ae, 0x00ae,
+	0x203c, 0x203c,
+	0x2049, 0x2049,
+	0x2122, 0x2122,
+	0x2139, 0x2139,
+	0x2194, 0x2199,
+	0x21a9, 0x21aa,
+	0x231a, 0x231b,
+	0x2328, 0x2328,
+	0x23cf, 0x23cf,
+	0x23e9, 0x23f3,
+	0x23f8, 0x23fa,
+	0x24c2, 0x24c2,
+	0x25aa, 0x25ab,
+	0x25b6, 0x25b6,
+	0x25c0, 0x25c0,
+	0x25fb, 0x25fe,
+	0x2600, 0x2604,
+	0x260e, 0x260e,
+	0x2611, 0x2611,
+	0x2614, 0x2615,
+	0x2618, 0x2618,
+	0x261d, 0x261d,
+	0x2620, 0x2620,
+	0x2622, 0x2623,
+	0x2626, 0x2626,
+	0x262a, 0x262a,
+	0x262e, 0x262f,
+	0x2638, 0x263a,
+	0x2640, 0x2640,
+	0x2642, 0x2642,
+	0x2648, 0x2653,
+	0x2660, 0x2660,
+	0x2663, 0x2663,
+	0x2665, 0x2666,
+	0x2668, 0x2668,
+	0x267b, 0x267b,
+	0x267f, 0x267f,
+	0x2692, 0x2697,
+	0x2699, 0x2699,
+	0x269b, 0x269c,
+	0x26a0, 0x26a1,
+	0x26aa, 0x26ab,
+	0x26b0, 0x26b1,
+	0x26bd, 0x26be,
+	0x26c4, 0x26c5,
+	0x26c8, 0x26c8,
+	0x26ce, 0x26cf,
+	0x26d1, 0x26d1,
+	0x26d3, 0x26d4,
+	0x26e9, 0x26ea,
+	0x26f0, 0x26f5,
+	0x26f7, 0x26fa,
+	0x26fd, 0x26fd,
+	0x2702, 0x2702,
+	0x2705, 0x2705,
+	0x2708, 0x270d,
+	0x270f, 0x270f,
+	0x2712, 0x2712,
+	0x2714, 0x2714,
+	0x2716, 0x2716,
+	0x271d, 0x271d,
+	0x2721, 0x2721,
+	0x2728, 0x2728,
+	0x2733, 0x2734,
+	0x2744, 0x2744,
+	0x2747, 0x2747,
+	0x274c, 0x274c,
+	0x274e, 0x274e,
+	0x2753, 0x2755,
+	0x2757, 0x2757,
+	0x2763, 0x2764,
+	0x2795, 0x2797,
+	0x27a1, 0x27a1,
+	0x27b0, 0x27b0,
+	0x27bf, 0x27bf,
+	0x2934, 0x2935,
+	0x2b05, 0x2b07,
+	0x2b1b, 0x2b1c,
+	0x2b50, 0x2b50,
+	0x2b55, 0x2b55,
+	0x3030, 0x3030,
+	0x303d, 0x303d,
+	0x3297, 0x3297,
+	0x3299, 0x3299,
+	0x1f004, 0x1f004,
+	0x1f0cf, 0x1f0cf,
+	0x1f170, 0x1f171,
+	0x1f17e, 0x1f17f,
+	0x1f18e, 0x1f18e,
+	0x1f191, 0x1f19a,
+	0x1f1e6, 0x1f1ff,
+	0x1f201, 0x1f202,
+	0x1f21a, 0x1f21a,
+	0x1f22f, 0x1f22f,
+	0x1f232, 0x1f23a,
+	0x1f250, 0x1f251,
+	0x1f300, 0x1f321,
+	0x1f324, 0x1f393,
+	0x1f396, 0x1f397,
+	0x1f399, 0x1f39b,
+	0x1f39e, 0x1f3f0,
+	0x1f3f3, 0x1f3f5,
+	0x1f3f7, 0x1f4fd,
+	0x1f4ff, 0x1f53d,
+	0x1f549, 0x1f54e,
+	0x1f550, 0x1f567,
+	0x1f56f, 0x1f570,
+	0x1f573, 0x1f57a,
+	0x1f587, 0x1f587,
+	0x1f58a, 0x1f58d,
+	0x1f590, 0x1f590,
+	0x1f595, 0x1f596,
+	0x1f5a4, 0x1f5a5,
+	0x1f5a8, 0x1f5a8,
+	0x1f5b1, 0x1f5b2,
+	0x1f5bc, 0x1f5bc,
+	0x1f5c2, 0x1f5c4,
+	0x1f5d1, 0x1f5d3,
+	0x1f5dc, 0x1f5de,
+	0x1f5e1, 0x1f5e1,
+	0x1f5e3, 0x1f5e3,
+	0x1f5e8, 0x1f5e8,
+	0x1f5ef, 0x1f5ef,
+	0x1f5f3, 0x1f5f3,
+	0x1f5fa, 0x1f64f,
+	0x1f680, 0x1f6c5,
+	0x1f6cb, 0x1f6d2,
+	0x1f6e0, 0x1f6e5,
+	0x1f6e9, 0x1f6e9,
+	0x1f6eb, 0x1f6ec,
+	0x1f6f0, 0x1f6f0,
+	0x1f6f3, 0x1f6f8,
+	0x1f910, 0x1f93a,
+	0x1f93c, 0x1f93e,
+	0x1f940, 0x1f945,
+	0x1f947, 0x1f94c,
+	0x1f950, 0x1f96b,
+	0x1f980, 0x1f997,
+	0x1f9c0, 0x1f9c0,
+	0x1f9d0, 0x1f9e6,
+}; /* CR_Emoji */
+
+/* 'Emoji_Presentation': Emoji */
+static const OnigCodePoint CR_Emoji_Presentation[] = {
+	75,
+	0x231a, 0x231b,
+	0x23e9, 0x23ec,
+	0x23f0, 0x23f0,
+	0x23f3, 0x23f3,
+	0x25fd, 0x25fe,
+	0x2614, 0x2615,
+	0x2648, 0x2653,
+	0x267f, 0x267f,
+	0x2693, 0x2693,
+	0x26a1, 0x26a1,
+	0x26aa, 0x26ab,
+	0x26bd, 0x26be,
+	0x26c4, 0x26c5,
+	0x26ce, 0x26ce,
+	0x26d4, 0x26d4,
+	0x26ea, 0x26ea,
+	0x26f2, 0x26f3,
+	0x26f5, 0x26f5,
+	0x26fa, 0x26fa,
+	0x26fd, 0x26fd,
+	0x2705, 0x2705,
+	0x270a, 0x270b,
+	0x2728, 0x2728,
+	0x274c, 0x274c,
+	0x274e, 0x274e,
+	0x2753, 0x2755,
+	0x2757, 0x2757,
+	0x2795, 0x2797,
+	0x27b0, 0x27b0,
+	0x27bf, 0x27bf,
+	0x2b1b, 0x2b1c,
+	0x2b50, 0x2b50,
+	0x2b55, 0x2b55,
+	0x1f004, 0x1f004,
+	0x1f0cf, 0x1f0cf,
+	0x1f18e, 0x1f18e,
+	0x1f191, 0x1f19a,
+	0x1f1e6, 0x1f1ff,
+	0x1f201, 0x1f201,
+	0x1f21a, 0x1f21a,
+	0x1f22f, 0x1f22f,
+	0x1f232, 0x1f236,
+	0x1f238, 0x1f23a,
+	0x1f250, 0x1f251,
+	0x1f300, 0x1f320,
+	0x1f32d, 0x1f335,
+	0x1f337, 0x1f37c,
+	0x1f37e, 0x1f393,
+	0x1f3a0, 0x1f3ca,
+	0x1f3cf, 0x1f3d3,
+	0x1f3e0, 0x1f3f0,
+	0x1f3f4, 0x1f3f4,
+	0x1f3f8, 0x1f43e,
+	0x1f440, 0x1f440,
+	0x1f442, 0x1f4fc,
+	0x1f4ff, 0x1f53d,
+	0x1f54b, 0x1f54e,
+	0x1f550, 0x1f567,
+	0x1f57a, 0x1f57a,
+	0x1f595, 0x1f596,
+	0x1f5a4, 0x1f5a4,
+	0x1f5fb, 0x1f64f,
+	0x1f680, 0x1f6c5,
+	0x1f6cc, 0x1f6cc,
+	0x1f6d0, 0x1f6d2,
+	0x1f6eb, 0x1f6ec,
+	0x1f6f4, 0x1f6f8,
+	0x1f910, 0x1f93a,
+	0x1f93c, 0x1f93e,
+	0x1f940, 0x1f945,
+	0x1f947, 0x1f94c,
+	0x1f950, 0x1f96b,
+	0x1f980, 0x1f997,
+	0x1f9c0, 0x1f9c0,
+	0x1f9d0, 0x1f9e6,
+}; /* CR_Emoji_Presentation */
+
+/* 'Emoji_Modifier': Emoji */
+static const OnigCodePoint CR_Emoji_Modifier[] = {
+	1,
+	0x1f3fb, 0x1f3ff,
+}; /* CR_Emoji_Modifier */
+
+/* 'Emoji_Modifier_Base': Emoji */
+static const OnigCodePoint CR_Emoji_Modifier_Base[] = {
+	32,
+	0x261d, 0x261d,
+	0x26f9, 0x26f9,
+	0x270a, 0x270d,
+	0x1f385, 0x1f385,
+	0x1f3c2, 0x1f3c4,
+	0x1f3c7, 0x1f3c7,
+	0x1f3ca, 0x1f3cc,
+	0x1f442, 0x1f443,
+	0x1f446, 0x1f450,
+	0x1f466, 0x1f469,
+	0x1f46e, 0x1f46e,
+	0x1f470, 0x1f478,
+	0x1f47c, 0x1f47c,
+	0x1f481, 0x1f483,
+	0x1f485, 0x1f487,
+	0x1f4aa, 0x1f4aa,
+	0x1f574, 0x1f575,
+	0x1f57a, 0x1f57a,
+	0x1f590, 0x1f590,
+	0x1f595, 0x1f596,
+	0x1f645, 0x1f647,
+	0x1f64b, 0x1f64f,
+	0x1f6a3, 0x1f6a3,
+	0x1f6b4, 0x1f6b6,
+	0x1f6c0, 0x1f6c0,
+	0x1f6cc, 0x1f6cc,
+	0x1f918, 0x1f91c,
+	0x1f91e, 0x1f91f,
+	0x1f926, 0x1f926,
+	0x1f930, 0x1f939,
+	0x1f93d, 0x1f93e,
+	0x1f9d1, 0x1f9dd,
+}; /* CR_Emoji_Modifier_Base */
+
+/* 'Emoji_Component': Emoji */
+static const OnigCodePoint CR_Emoji_Component[] = {
+	5,
+	0x0023, 0x0023,
+	0x002a, 0x002a,
+	0x0030, 0x0039,
+	0x1f1e6, 0x1f1ff,
+	0x1f3fb, 0x1f3ff,
+}; /* CR_Emoji_Component */
+
+/* 'Unknown': Script */
+static const OnigCodePoint CR_Unknown[] = {
+	647,
+	0x0378, 0x0379,
+	0x0380, 0x0383,
+	0x038b, 0x038b,
+	0x038d, 0x038d,
+	0x03a2, 0x03a2,
+	0x0530, 0x0530,
+	0x0557, 0x0558,
+	0x0560, 0x0560,
+	0x0588, 0x0588,
+	0x058b, 0x058c,
+	0x0590, 0x0590,
+	0x05c8, 0x05cf,
+	0x05eb, 0x05ef,
+	0x05f5, 0x05ff,
+	0x061d, 0x061d,
+	0x070e, 0x070e,
+	0x074b, 0x074c,
+	0x07b2, 0x07bf,
+	0x07fb, 0x07ff,
+	0x082e, 0x082f,
+	0x083f, 0x083f,
+	0x085c, 0x085d,
+	0x085f, 0x085f,
+	0x086b, 0x089f,
+	0x08b5, 0x08b5,
+	0x08be, 0x08d3,
+	0x0984, 0x0984,
+	0x098d, 0x098e,
+	0x0991, 0x0992,
+	0x09a9, 0x09a9,
+	0x09b1, 0x09b1,
+	0x09b3, 0x09b5,
+	0x09ba, 0x09bb,
+	0x09c5, 0x09c6,
+	0x09c9, 0x09ca,
+	0x09cf, 0x09d6,
+	0x09d8, 0x09db,
+	0x09de, 0x09de,
+	0x09e4, 0x09e5,
+	0x09fe, 0x0a00,
+	0x0a04, 0x0a04,
+	0x0a0b, 0x0a0e,
+	0x0a11, 0x0a12,
+	0x0a29, 0x0a29,
+	0x0a31, 0x0a31,
+	0x0a34, 0x0a34,
+	0x0a37, 0x0a37,
+	0x0a3a, 0x0a3b,
+	0x0a3d, 0x0a3d,
+	0x0a43, 0x0a46,
+	0x0a49, 0x0a4a,
+	0x0a4e, 0x0a50,
+	0x0a52, 0x0a58,
+	0x0a5d, 0x0a5d,
+	0x0a5f, 0x0a65,
+	0x0a76, 0x0a80,
+	0x0a84, 0x0a84,
+	0x0a8e, 0x0a8e,
+	0x0a92, 0x0a92,
+	0x0aa9, 0x0aa9,
+	0x0ab1, 0x0ab1,
+	0x0ab4, 0x0ab4,
+	0x0aba, 0x0abb,
+	0x0ac6, 0x0ac6,
+	0x0aca, 0x0aca,
+	0x0ace, 0x0acf,
+	0x0ad1, 0x0adf,
+	0x0ae4, 0x0ae5,
+	0x0af2, 0x0af8,
+	0x0b00, 0x0b00,
+	0x0b04, 0x0b04,
+	0x0b0d, 0x0b0e,
+	0x0b11, 0x0b12,
+	0x0b29, 0x0b29,
+	0x0b31, 0x0b31,
+	0x0b34, 0x0b34,
+	0x0b3a, 0x0b3b,
+	0x0b45, 0x0b46,
+	0x0b49, 0x0b4a,
+	0x0b4e, 0x0b55,
+	0x0b58, 0x0b5b,
+	0x0b5e, 0x0b5e,
+	0x0b64, 0x0b65,
+	0x0b78, 0x0b81,
+	0x0b84, 0x0b84,
+	0x0b8b, 0x0b8d,
+	0x0b91, 0x0b91,
+	0x0b96, 0x0b98,
+	0x0b9b, 0x0b9b,
+	0x0b9d, 0x0b9d,
+	0x0ba0, 0x0ba2,
+	0x0ba5, 0x0ba7,
+	0x0bab, 0x0bad,
+	0x0bba, 0x0bbd,
+	0x0bc3, 0x0bc5,
+	0x0bc9, 0x0bc9,
+	0x0bce, 0x0bcf,
+	0x0bd1, 0x0bd6,
+	0x0bd8, 0x0be5,
+	0x0bfb, 0x0bff,
+	0x0c04, 0x0c04,
+	0x0c0d, 0x0c0d,
+	0x0c11, 0x0c11,
+	0x0c29, 0x0c29,
+	0x0c3a, 0x0c3c,
+	0x0c45, 0x0c45,
+	0x0c49, 0x0c49,
+	0x0c4e, 0x0c54,
+	0x0c57, 0x0c57,
+	0x0c5b, 0x0c5f,
+	0x0c64, 0x0c65,
+	0x0c70, 0x0c77,
+	0x0c84, 0x0c84,
+	0x0c8d, 0x0c8d,
+	0x0c91, 0x0c91,
+	0x0ca9, 0x0ca9,
+	0x0cb4, 0x0cb4,
+	0x0cba, 0x0cbb,
+	0x0cc5, 0x0cc5,
+	0x0cc9, 0x0cc9,
+	0x0cce, 0x0cd4,
+	0x0cd7, 0x0cdd,
+	0x0cdf, 0x0cdf,
+	0x0ce4, 0x0ce5,
+	0x0cf0, 0x0cf0,
+	0x0cf3, 0x0cff,
+	0x0d04, 0x0d04,
+	0x0d0d, 0x0d0d,
+	0x0d11, 0x0d11,
+	0x0d45, 0x0d45,
+	0x0d49, 0x0d49,
+	0x0d50, 0x0d53,
+	0x0d64, 0x0d65,
+	0x0d80, 0x0d81,
+	0x0d84, 0x0d84,
+	0x0d97, 0x0d99,
+	0x0db2, 0x0db2,
+	0x0dbc, 0x0dbc,
+	0x0dbe, 0x0dbf,
+	0x0dc7, 0x0dc9,
+	0x0dcb, 0x0dce,
+	0x0dd5, 0x0dd5,
+	0x0dd7, 0x0dd7,
+	0x0de0, 0x0de5,
+	0x0df0, 0x0df1,
+	0x0df5, 0x0e00,
+	0x0e3b, 0x0e3e,
+	0x0e5c, 0x0e80,
+	0x0e83, 0x0e83,
+	0x0e85, 0x0e86,
+	0x0e89, 0x0e89,
+	0x0e8b, 0x0e8c,
+	0x0e8e, 0x0e93,
+	0x0e98, 0x0e98,
+	0x0ea0, 0x0ea0,
+	0x0ea4, 0x0ea4,
+	0x0ea6, 0x0ea6,
+	0x0ea8, 0x0ea9,
+	0x0eac, 0x0eac,
+	0x0eba, 0x0eba,
+	0x0ebe, 0x0ebf,
+	0x0ec5, 0x0ec5,
+	0x0ec7, 0x0ec7,
+	0x0ece, 0x0ecf,
+	0x0eda, 0x0edb,
+	0x0ee0, 0x0eff,
+	0x0f48, 0x0f48,
+	0x0f6d, 0x0f70,
+	0x0f98, 0x0f98,
+	0x0fbd, 0x0fbd,
+	0x0fcd, 0x0fcd,
+	0x0fdb, 0x0fff,
+	0x10c6, 0x10c6,
+	0x10c8, 0x10cc,
+	0x10ce, 0x10cf,
+	0x1249, 0x1249,
+	0x124e, 0x124f,
+	0x1257, 0x1257,
+	0x1259, 0x1259,
+	0x125e, 0x125f,
+	0x1289, 0x1289,
+	0x128e, 0x128f,
+	0x12b1, 0x12b1,
+	0x12b6, 0x12b7,
+	0x12bf, 0x12bf,
+	0x12c1, 0x12c1,
+	0x12c6, 0x12c7,
+	0x12d7, 0x12d7,
+	0x1311, 0x1311,
+	0x1316, 0x1317,
+	0x135b, 0x135c,
+	0x137d, 0x137f,
+	0x139a, 0x139f,
+	0x13f6, 0x13f7,
+	0x13fe, 0x13ff,
+	0x169d, 0x169f,
+	0x16f9, 0x16ff,
+	0x170d, 0x170d,
+	0x1715, 0x171f,
+	0x1737, 0x173f,
+	0x1754, 0x175f,
+	0x176d, 0x176d,
+	0x1771, 0x1771,
+	0x1774, 0x177f,
+	0x17de, 0x17df,
+	0x17ea, 0x17ef,
+	0x17fa, 0x17ff,
+	0x180f, 0x180f,
+	0x181a, 0x181f,
+	0x1878, 0x187f,
+	0x18ab, 0x18af,
+	0x18f6, 0x18ff,
+	0x191f, 0x191f,
+	0x192c, 0x192f,
+	0x193c, 0x193f,
+	0x1941, 0x1943,
+	0x196e, 0x196f,
+	0x1975, 0x197f,
+	0x19ac, 0x19af,
+	0x19ca, 0x19cf,
+	0x19db, 0x19dd,
+	0x1a1c, 0x1a1d,
+	0x1a5f, 0x1a5f,
+	0x1a7d, 0x1a7e,
+	0x1a8a, 0x1a8f,
+	0x1a9a, 0x1a9f,
+	0x1aae, 0x1aaf,
+	0x1abf, 0x1aff,
+	0x1b4c, 0x1b4f,
+	0x1b7d, 0x1b7f,
+	0x1bf4, 0x1bfb,
+	0x1c38, 0x1c3a,
+	0x1c4a, 0x1c4c,
+	0x1c89, 0x1cbf,
+	0x1cc8, 0x1ccf,
+	0x1cfa, 0x1cff,
+	0x1dfa, 0x1dfa,
+	0x1f16, 0x1f17,
+	0x1f1e, 0x1f1f,
+	0x1f46, 0x1f47,
+	0x1f4e, 0x1f4f,
+	0x1f58, 0x1f58,
+	0x1f5a, 0x1f5a,
+	0x1f5c, 0x1f5c,
+	0x1f5e, 0x1f5e,
+	0x1f7e, 0x1f7f,
+	0x1fb5, 0x1fb5,
+	0x1fc5, 0x1fc5,
+	0x1fd4, 0x1fd5,
+	0x1fdc, 0x1fdc,
+	0x1ff0, 0x1ff1,
+	0x1ff5, 0x1ff5,
+	0x1fff, 0x1fff,
+	0x2065, 0x2065,
+	0x2072, 0x2073,
+	0x208f, 0x208f,
+	0x209d, 0x209f,
+	0x20c0, 0x20cf,
+	0x20f1, 0x20ff,
+	0x218c, 0x218f,
+	0x2427, 0x243f,
+	0x244b, 0x245f,
+	0x2b74, 0x2b75,
+	0x2b96, 0x2b97,
+	0x2bba, 0x2bbc,
+	0x2bc9, 0x2bc9,
+	0x2bd3, 0x2beb,
+	0x2bf0, 0x2bff,
+	0x2c2f, 0x2c2f,
+	0x2c5f, 0x2c5f,
+	0x2cf4, 0x2cf8,
+	0x2d26, 0x2d26,
+	0x2d28, 0x2d2c,
+	0x2d2e, 0x2d2f,
+	0x2d68, 0x2d6e,
+	0x2d71, 0x2d7e,
+	0x2d97, 0x2d9f,
+	0x2da7, 0x2da7,
+	0x2daf, 0x2daf,
+	0x2db7, 0x2db7,
+	0x2dbf, 0x2dbf,
+	0x2dc7, 0x2dc7,
+	0x2dcf, 0x2dcf,
+	0x2dd7, 0x2dd7,
+	0x2ddf, 0x2ddf,
+	0x2e4a, 0x2e7f,
+	0x2e9a, 0x2e9a,
+	0x2ef4, 0x2eff,
+	0x2fd6, 0x2fef,
+	0x2ffc, 0x2fff,
+	0x3040, 0x3040,
+	0x3097, 0x3098,
+	0x3100, 0x3104,
+	0x312f, 0x3130,
+	0x318f, 0x318f,
+	0x31bb, 0x31bf,
+	0x31e4, 0x31ef,
+	0x321f, 0x321f,
+	0x32ff, 0x32ff,
+	0x4db6, 0x4dbf,
+	0x9feb, 0x9fff,
+	0xa48d, 0xa48f,
+	0xa4c7, 0xa4cf,
+	0xa62c, 0xa63f,
+	0xa6f8, 0xa6ff,
+	0xa7af, 0xa7af,
+	0xa7b8, 0xa7f6,
+	0xa82c, 0xa82f,
+	0xa83a, 0xa83f,
+	0xa878, 0xa87f,
+	0xa8c6, 0xa8cd,
+	0xa8da, 0xa8df,
+	0xa8fe, 0xa8ff,
+	0xa954, 0xa95e,
+	0xa97d, 0xa97f,
+	0xa9ce, 0xa9ce,
+	0xa9da, 0xa9dd,
+	0xa9ff, 0xa9ff,
+	0xaa37, 0xaa3f,
+	0xaa4e, 0xaa4f,
+	0xaa5a, 0xaa5b,
+	0xaac3, 0xaada,
+	0xaaf7, 0xab00,
+	0xab07, 0xab08,
+	0xab0f, 0xab10,
+	0xab17, 0xab1f,
+	0xab27, 0xab27,
+	0xab2f, 0xab2f,
+	0xab66, 0xab6f,
+	0xabee, 0xabef,
+	0xabfa, 0xabff,
+	0xd7a4, 0xd7af,
+	0xd7c7, 0xd7ca,
+	0xd7fc, 0xf8ff,
+	0xfa6e, 0xfa6f,
+	0xfada, 0xfaff,
+	0xfb07, 0xfb12,
+	0xfb18, 0xfb1c,
+	0xfb37, 0xfb37,
+	0xfb3d, 0xfb3d,
+	0xfb3f, 0xfb3f,
+	0xfb42, 0xfb42,
+	0xfb45, 0xfb45,
+	0xfbc2, 0xfbd2,
+	0xfd40, 0xfd4f,
+	0xfd90, 0xfd91,
+	0xfdc8, 0xfdef,
+	0xfdfe, 0xfdff,
+	0xfe1a, 0xfe1f,
+	0xfe53, 0xfe53,
+	0xfe67, 0xfe67,
+	0xfe6c, 0xfe6f,
+	0xfe75, 0xfe75,
+	0xfefd, 0xfefe,
+	0xff00, 0xff00,
+	0xffbf, 0xffc1,
+	0xffc8, 0xffc9,
+	0xffd0, 0xffd1,
+	0xffd8, 0xffd9,
+	0xffdd, 0xffdf,
+	0xffe7, 0xffe7,
+	0xffef, 0xfff8,
+	0xfffe, 0xffff,
+	0x1000c, 0x1000c,
+	0x10027, 0x10027,
+	0x1003b, 0x1003b,
+	0x1003e, 0x1003e,
+	0x1004e, 0x1004f,
+	0x1005e, 0x1007f,
+	0x100fb, 0x100ff,
+	0x10103, 0x10106,
+	0x10134, 0x10136,
+	0x1018f, 0x1018f,
+	0x1019c, 0x1019f,
+	0x101a1, 0x101cf,
+	0x101fe, 0x1027f,
+	0x1029d, 0x1029f,
+	0x102d1, 0x102df,
+	0x102fc, 0x102ff,
+	0x10324, 0x1032c,
+	0x1034b, 0x1034f,
+	0x1037b, 0x1037f,
+	0x1039e, 0x1039e,
+	0x103c4, 0x103c7,
+	0x103d6, 0x103ff,
+	0x1049e, 0x1049f,
+	0x104aa, 0x104af,
+	0x104d4, 0x104d7,
+	0x104fc, 0x104ff,
+	0x10528, 0x1052f,
+	0x10564, 0x1056e,
+	0x10570, 0x105ff,
+	0x10737, 0x1073f,
+	0x10756, 0x1075f,
+	0x10768, 0x107ff,
+	0x10806, 0x10807,
+	0x10809, 0x10809,
+	0x10836, 0x10836,
+	0x10839, 0x1083b,
+	0x1083d, 0x1083e,
+	0x10856, 0x10856,
+	0x1089f, 0x108a6,
+	0x108b0, 0x108df,
+	0x108f3, 0x108f3,
+	0x108f6, 0x108fa,
+	0x1091c, 0x1091e,
+	0x1093a, 0x1093e,
+	0x10940, 0x1097f,
+	0x109b8, 0x109bb,
+	0x109d0, 0x109d1,
+	0x10a04, 0x10a04,
+	0x10a07, 0x10a0b,
+	0x10a14, 0x10a14,
+	0x10a18, 0x10a18,
+	0x10a34, 0x10a37,
+	0x10a3b, 0x10a3e,
+	0x10a48, 0x10a4f,
+	0x10a59, 0x10a5f,
+	0x10aa0, 0x10abf,
+	0x10ae7, 0x10aea,
+	0x10af7, 0x10aff,
+	0x10b36, 0x10b38,
+	0x10b56, 0x10b57,
+	0x10b73, 0x10b77,
+	0x10b92, 0x10b98,
+	0x10b9d, 0x10ba8,
+	0x10bb0, 0x10bff,
+	0x10c49, 0x10c7f,
+	0x10cb3, 0x10cbf,
+	0x10cf3, 0x10cf9,
+	0x10d00, 0x10e5f,
+	0x10e7f, 0x10fff,
+	0x1104e, 0x11051,
+	0x11070, 0x1107e,
+	0x110c2, 0x110cf,
+	0x110e9, 0x110ef,
+	0x110fa, 0x110ff,
+	0x11135, 0x11135,
+	0x11144, 0x1114f,
+	0x11177, 0x1117f,
+	0x111ce, 0x111cf,
+	0x111e0, 0x111e0,
+	0x111f5, 0x111ff,
+	0x11212, 0x11212,
+	0x1123f, 0x1127f,
+	0x11287, 0x11287,
+	0x11289, 0x11289,
+	0x1128e, 0x1128e,
+	0x1129e, 0x1129e,
+	0x112aa, 0x112af,
+	0x112eb, 0x112ef,
+	0x112fa, 0x112ff,
+	0x11304, 0x11304,
+	0x1130d, 0x1130e,
+	0x11311, 0x11312,
+	0x11329, 0x11329,
+	0x11331, 0x11331,
+	0x11334, 0x11334,
+	0x1133a, 0x1133b,
+	0x11345, 0x11346,
+	0x11349, 0x1134a,
+	0x1134e, 0x1134f,
+	0x11351, 0x11356,
+	0x11358, 0x1135c,
+	0x11364, 0x11365,
+	0x1136d, 0x1136f,
+	0x11375, 0x113ff,
+	0x1145a, 0x1145a,
+	0x1145c, 0x1145c,
+	0x1145e, 0x1147f,
+	0x114c8, 0x114cf,
+	0x114da, 0x1157f,
+	0x115b6, 0x115b7,
+	0x115de, 0x115ff,
+	0x11645, 0x1164f,
+	0x1165a, 0x1165f,
+	0x1166d, 0x1167f,
+	0x116b8, 0x116bf,
+	0x116ca, 0x116ff,
+	0x1171a, 0x1171c,
+	0x1172c, 0x1172f,
+	0x11740, 0x1189f,
+	0x118f3, 0x118fe,
+	0x11900, 0x119ff,
+	0x11a48, 0x11a4f,
+	0x11a84, 0x11a85,
+	0x11a9d, 0x11a9d,
+	0x11aa3, 0x11abf,
+	0x11af9, 0x11bff,
+	0x11c09, 0x11c09,
+	0x11c37, 0x11c37,
+	0x11c46, 0x11c4f,
+	0x11c6d, 0x11c6f,
+	0x11c90, 0x11c91,
+	0x11ca8, 0x11ca8,
+	0x11cb7, 0x11cff,
+	0x11d07, 0x11d07,
+	0x11d0a, 0x11d0a,
+	0x11d37, 0x11d39,
+	0x11d3b, 0x11d3b,
+	0x11d3e, 0x11d3e,
+	0x11d48, 0x11d4f,
+	0x11d5a, 0x11fff,
+	0x1239a, 0x123ff,
+	0x1246f, 0x1246f,
+	0x12475, 0x1247f,
+	0x12544, 0x12fff,
+	0x1342f, 0x143ff,
+	0x14647, 0x167ff,
+	0x16a39, 0x16a3f,
+	0x16a5f, 0x16a5f,
+	0x16a6a, 0x16a6d,
+	0x16a70, 0x16acf,
+	0x16aee, 0x16aef,
+	0x16af6, 0x16aff,
+	0x16b46, 0x16b4f,
+	0x16b5a, 0x16b5a,
+	0x16b62, 0x16b62,
+	0x16b78, 0x16b7c,
+	0x16b90, 0x16eff,
+	0x16f45, 0x16f4f,
+	0x16f7f, 0x16f8e,
+	0x16fa0, 0x16fdf,
+	0x16fe2, 0x16fff,
+	0x187ed, 0x187ff,
+	0x18af3, 0x1afff,
+	0x1b11f, 0x1b16f,
+	0x1b2fc, 0x1bbff,
+	0x1bc6b, 0x1bc6f,
+	0x1bc7d, 0x1bc7f,
+	0x1bc89, 0x1bc8f,
+	0x1bc9a, 0x1bc9b,
+	0x1bca4, 0x1cfff,
+	0x1d0f6, 0x1d0ff,
+	0x1d127, 0x1d128,
+	0x1d1e9, 0x1d1ff,
+	0x1d246, 0x1d2ff,
+	0x1d357, 0x1d35f,
+	0x1d372, 0x1d3ff,
+	0x1d455, 0x1d455,
+	0x1d49d, 0x1d49d,
+	0x1d4a0, 0x1d4a1,
+	0x1d4a3, 0x1d4a4,
+	0x1d4a7, 0x1d4a8,
+	0x1d4ad, 0x1d4ad,
+	0x1d4ba, 0x1d4ba,
+	0x1d4bc, 0x1d4bc,
+	0x1d4c4, 0x1d4c4,
+	0x1d506, 0x1d506,
+	0x1d50b, 0x1d50c,
+	0x1d515, 0x1d515,
+	0x1d51d, 0x1d51d,
+	0x1d53a, 0x1d53a,
+	0x1d53f, 0x1d53f,
+	0x1d545, 0x1d545,
+	0x1d547, 0x1d549,
+	0x1d551, 0x1d551,
+	0x1d6a6, 0x1d6a7,
+	0x1d7cc, 0x1d7cd,
+	0x1da8c, 0x1da9a,
+	0x1daa0, 0x1daa0,
+	0x1dab0, 0x1dfff,
+	0x1e007, 0x1e007,
+	0x1e019, 0x1e01a,
+	0x1e022, 0x1e022,
+	0x1e025, 0x1e025,
+	0x1e02b, 0x1e7ff,
+	0x1e8c5, 0x1e8c6,
+	0x1e8d7, 0x1e8ff,
+	0x1e94b, 0x1e94f,
+	0x1e95a, 0x1e95d,
+	0x1e960, 0x1edff,
+	0x1ee04, 0x1ee04,
+	0x1ee20, 0x1ee20,
+	0x1ee23, 0x1ee23,
+	0x1ee25, 0x1ee26,
+	0x1ee28, 0x1ee28,
+	0x1ee33, 0x1ee33,
+	0x1ee38, 0x1ee38,
+	0x1ee3a, 0x1ee3a,
+	0x1ee3c, 0x1ee41,
+	0x1ee43, 0x1ee46,
+	0x1ee48, 0x1ee48,
+	0x1ee4a, 0x1ee4a,
+	0x1ee4c, 0x1ee4c,
+	0x1ee50, 0x1ee50,
+	0x1ee53, 0x1ee53,
+	0x1ee55, 0x1ee56,
+	0x1ee58, 0x1ee58,
+	0x1ee5a, 0x1ee5a,
+	0x1ee5c, 0x1ee5c,
+	0x1ee5e, 0x1ee5e,
+	0x1ee60, 0x1ee60,
+	0x1ee63, 0x1ee63,
+	0x1ee65, 0x1ee66,
+	0x1ee6b, 0x1ee6b,
+	0x1ee73, 0x1ee73,
+	0x1ee78, 0x1ee78,
+	0x1ee7d, 0x1ee7d,
+	0x1ee7f, 0x1ee7f,
+	0x1ee8a, 0x1ee8a,
+	0x1ee9c, 0x1eea0,
+	0x1eea4, 0x1eea4,
+	0x1eeaa, 0x1eeaa,
+	0x1eebc, 0x1eeef,
+	0x1eef2, 0x1efff,
+	0x1f02c, 0x1f02f,
+	0x1f094, 0x1f09f,
+	0x1f0af, 0x1f0b0,
+	0x1f0c0, 0x1f0c0,
+	0x1f0d0, 0x1f0d0,
+	0x1f0f6, 0x1f0ff,
+	0x1f10d, 0x1f10f,
+	0x1f12f, 0x1f12f,
+	0x1f16c, 0x1f16f,
+	0x1f1ad, 0x1f1e5,
+	0x1f203, 0x1f20f,
+	0x1f23c, 0x1f23f,
+	0x1f249, 0x1f24f,
+	0x1f252, 0x1f25f,
+	0x1f266, 0x1f2ff,
+	0x1f6d5, 0x1f6df,
+	0x1f6ed, 0x1f6ef,
+	0x1f6f9, 0x1f6ff,
+	0x1f774, 0x1f77f,
+	0x1f7d5, 0x1f7ff,
+	0x1f80c, 0x1f80f,
+	0x1f848, 0x1f84f,
+	0x1f85a, 0x1f85f,
+	0x1f888, 0x1f88f,
+	0x1f8ae, 0x1f8ff,
+	0x1f90c, 0x1f90f,
+	0x1f93f, 0x1f93f,
+	0x1f94d, 0x1f94f,
+	0x1f96c, 0x1f97f,
+	0x1f998, 0x1f9bf,
+	0x1f9c1, 0x1f9cf,
+	0x1f9e7, 0x1ffff,
+	0x2a6d7, 0x2a6ff,
+	0x2b735, 0x2b73f,
+	0x2b81e, 0x2b81f,
+	0x2cea2, 0x2ceaf,
+	0x2ebe1, 0x2f7ff,
+	0x2fa1e, 0xe0000,
+	0xe0002, 0xe001f,
+	0xe0080, 0xe00ff,
+	0xe01f0, 0x10ffff,
+}; /* CR_Unknown */
+
+#ifdef USE_UNICODE_AGE_PROPERTIES
+/* 'Age_1_1': Derived Age 1.1 */
+static const OnigCodePoint CR_Age_1_1[] = {
+	288,
+	0x0000, 0x01f5,
+	0x01fa, 0x0217,
+	0x0250, 0x02a8,
+	0x02b0, 0x02de,
+	0x02e0, 0x02e9,
+	0x0300, 0x0345,
+	0x0360, 0x0361,
+	0x0374, 0x0375,
+	0x037a, 0x037a,
+	0x037e, 0x037e,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03ce,
+	0x03d0, 0x03d6,
+	0x03da, 0x03da,
+	0x03dc, 0x03dc,
+	0x03de, 0x03de,
+	0x03e0, 0x03e0,
+	0x03e2, 0x03f3,
+	0x0401, 0x040c,
+	0x040e, 0x044f,
+	0x0451, 0x045c,
+	0x045e, 0x0486,
+	0x0490, 0x04c4,
+	0x04c7, 0x04c8,
+	0x04cb, 0x04cc,
+	0x04d0, 0x04eb,
+	0x04ee, 0x04f5,
+	0x04f8, 0x04f9,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x0589,
+	0x05b0, 0x05b9,
+	0x05bb, 0x05c3,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x060c, 0x060c,
+	0x061b, 0x061b,
+	0x061f, 0x061f,
+	0x0621, 0x063a,
+	0x0640, 0x0652,
+	0x0660, 0x066d,
+	0x0670, 0x06b7,
+	0x06ba, 0x06be,
+	0x06c0, 0x06ce,
+	0x06d0, 0x06ed,
+	0x06f0, 0x06f9,
+	0x0901, 0x0903,
+	0x0905, 0x0939,
+	0x093c, 0x094d,
+	0x0950, 0x0954,
+	0x0958, 0x0970,
+	0x0981, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09bc,
+	0x09be, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09cd,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fa,
+	0x0a02, 0x0a02,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a74,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8b,
+	0x0a8d, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae0,
+	0x0ae6, 0x0aef,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b36, 0x0b39,
+	0x0b3c, 0x0b43,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b61,
+	0x0b66, 0x0b70,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb5,
+	0x0bb7, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd7, 0x0bd7,
+	0x0be7, 0x0bf2,
+	0x0c01, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c33,
+	0x0c35, 0x0c39,
+	0x0c3e, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c60, 0x0c61,
+	0x0c66, 0x0c6f,
+	0x0c82, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbe, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce1,
+	0x0ce6, 0x0cef,
+	0x0d02, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d28,
+	0x0d2a, 0x0d39,
+	0x0d3e, 0x0d43,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4d,
+	0x0d57, 0x0d57,
+	0x0d60, 0x0d61,
+	0x0d66, 0x0d6f,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edd,
+	0x10a0, 0x10c5,
+	0x10d0, 0x10f6,
+	0x10fb, 0x10fb,
+	0x1100, 0x1159,
+	0x115f, 0x11a2,
+	0x11a8, 0x11f9,
+	0x1e00, 0x1e9a,
+	0x1ea0, 0x1ef9,
+	0x1f00, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x202e,
+	0x2030, 0x2046,
+	0x206a, 0x2070,
+	0x2074, 0x208e,
+	0x20a0, 0x20aa,
+	0x20d0, 0x20e1,
+	0x2100, 0x2138,
+	0x2153, 0x2182,
+	0x2190, 0x21ea,
+	0x2200, 0x22f1,
+	0x2300, 0x2300,
+	0x2302, 0x237a,
+	0x2400, 0x2424,
+	0x2440, 0x244a,
+	0x2460, 0x24ea,
+	0x2500, 0x2595,
+	0x25a0, 0x25ef,
+	0x2600, 0x2613,
+	0x261a, 0x266f,
+	0x2701, 0x2704,
+	0x2706, 0x2709,
+	0x270c, 0x2727,
+	0x2729, 0x274b,
+	0x274d, 0x274d,
+	0x274f, 0x2752,
+	0x2756, 0x2756,
+	0x2758, 0x275e,
+	0x2761, 0x2767,
+	0x2776, 0x2794,
+	0x2798, 0x27af,
+	0x27b1, 0x27be,
+	0x3000, 0x3037,
+	0x303f, 0x303f,
+	0x3041, 0x3094,
+	0x3099, 0x309e,
+	0x30a1, 0x30fe,
+	0x3105, 0x312c,
+	0x3131, 0x318e,
+	0x3190, 0x319f,
+	0x3200, 0x321c,
+	0x3220, 0x3243,
+	0x3260, 0x327b,
+	0x327f, 0x32b0,
+	0x32c0, 0x32cb,
+	0x32d0, 0x32fe,
+	0x3300, 0x3376,
+	0x337b, 0x33dd,
+	0x33e0, 0x33fe,
+	0x4e00, 0x9fa5,
+	0xe000, 0xfa2d,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1e, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbb1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdf0, 0xfdfb,
+	0xfe20, 0xfe23,
+	0xfe30, 0xfe44,
+	0xfe49, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe72,
+	0xfe74, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xff5e,
+	0xff61, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfffd, 0xffff,
+}; /* CR_Age_1_1 */
+
+/* 'Age_2_0': Derived Age 2.0 */
+static const OnigCodePoint CR_Age_2_0[] = {
+	312,
+	0x0000, 0x01f5,
+	0x01fa, 0x0217,
+	0x0250, 0x02a8,
+	0x02b0, 0x02de,
+	0x02e0, 0x02e9,
+	0x0300, 0x0345,
+	0x0360, 0x0361,
+	0x0374, 0x0375,
+	0x037a, 0x037a,
+	0x037e, 0x037e,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03ce,
+	0x03d0, 0x03d6,
+	0x03da, 0x03da,
+	0x03dc, 0x03dc,
+	0x03de, 0x03de,
+	0x03e0, 0x03e0,
+	0x03e2, 0x03f3,
+	0x0401, 0x040c,
+	0x040e, 0x044f,
+	0x0451, 0x045c,
+	0x045e, 0x0486,
+	0x0490, 0x04c4,
+	0x04c7, 0x04c8,
+	0x04cb, 0x04cc,
+	0x04d0, 0x04eb,
+	0x04ee, 0x04f5,
+	0x04f8, 0x04f9,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x0589,
+	0x0591, 0x05a1,
+	0x05a3, 0x05b9,
+	0x05bb, 0x05c4,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x060c, 0x060c,
+	0x061b, 0x061b,
+	0x061f, 0x061f,
+	0x0621, 0x063a,
+	0x0640, 0x0652,
+	0x0660, 0x066d,
+	0x0670, 0x06b7,
+	0x06ba, 0x06be,
+	0x06c0, 0x06ce,
+	0x06d0, 0x06ed,
+	0x06f0, 0x06f9,
+	0x0901, 0x0903,
+	0x0905, 0x0939,
+	0x093c, 0x094d,
+	0x0950, 0x0954,
+	0x0958, 0x0970,
+	0x0981, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09bc,
+	0x09be, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09cd,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fa,
+	0x0a02, 0x0a02,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a74,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8b,
+	0x0a8d, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae0,
+	0x0ae6, 0x0aef,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b36, 0x0b39,
+	0x0b3c, 0x0b43,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b61,
+	0x0b66, 0x0b70,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb5,
+	0x0bb7, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd7, 0x0bd7,
+	0x0be7, 0x0bf2,
+	0x0c01, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c33,
+	0x0c35, 0x0c39,
+	0x0c3e, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c60, 0x0c61,
+	0x0c66, 0x0c6f,
+	0x0c82, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbe, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce1,
+	0x0ce6, 0x0cef,
+	0x0d02, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d28,
+	0x0d2a, 0x0d39,
+	0x0d3e, 0x0d43,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4d,
+	0x0d57, 0x0d57,
+	0x0d60, 0x0d61,
+	0x0d66, 0x0d6f,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edd,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f69,
+	0x0f71, 0x0f8b,
+	0x0f90, 0x0f95,
+	0x0f97, 0x0f97,
+	0x0f99, 0x0fad,
+	0x0fb1, 0x0fb7,
+	0x0fb9, 0x0fb9,
+	0x10a0, 0x10c5,
+	0x10d0, 0x10f6,
+	0x10fb, 0x10fb,
+	0x1100, 0x1159,
+	0x115f, 0x11a2,
+	0x11a8, 0x11f9,
+	0x1e00, 0x1e9b,
+	0x1ea0, 0x1ef9,
+	0x1f00, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x202e,
+	0x2030, 0x2046,
+	0x206a, 0x2070,
+	0x2074, 0x208e,
+	0x20a0, 0x20ab,
+	0x20d0, 0x20e1,
+	0x2100, 0x2138,
+	0x2153, 0x2182,
+	0x2190, 0x21ea,
+	0x2200, 0x22f1,
+	0x2300, 0x2300,
+	0x2302, 0x237a,
+	0x2400, 0x2424,
+	0x2440, 0x244a,
+	0x2460, 0x24ea,
+	0x2500, 0x2595,
+	0x25a0, 0x25ef,
+	0x2600, 0x2613,
+	0x261a, 0x266f,
+	0x2701, 0x2704,
+	0x2706, 0x2709,
+	0x270c, 0x2727,
+	0x2729, 0x274b,
+	0x274d, 0x274d,
+	0x274f, 0x2752,
+	0x2756, 0x2756,
+	0x2758, 0x275e,
+	0x2761, 0x2767,
+	0x2776, 0x2794,
+	0x2798, 0x27af,
+	0x27b1, 0x27be,
+	0x3000, 0x3037,
+	0x303f, 0x303f,
+	0x3041, 0x3094,
+	0x3099, 0x309e,
+	0x30a1, 0x30fe,
+	0x3105, 0x312c,
+	0x3131, 0x318e,
+	0x3190, 0x319f,
+	0x3200, 0x321c,
+	0x3220, 0x3243,
+	0x3260, 0x327b,
+	0x327f, 0x32b0,
+	0x32c0, 0x32cb,
+	0x32d0, 0x32fe,
+	0x3300, 0x3376,
+	0x337b, 0x33dd,
+	0x33e0, 0x33fe,
+	0x4e00, 0x9fa5,
+	0xac00, 0xd7a3,
+	0xd800, 0xfa2d,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1e, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbb1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdf0, 0xfdfb,
+	0xfe20, 0xfe23,
+	0xfe30, 0xfe44,
+	0xfe49, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe72,
+	0xfe74, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xff5e,
+	0xff61, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfffd, 0xffff,
+	0x1fffe, 0x1ffff,
+	0x2fffe, 0x2ffff,
+	0x3fffe, 0x3ffff,
+	0x4fffe, 0x4ffff,
+	0x5fffe, 0x5ffff,
+	0x6fffe, 0x6ffff,
+	0x7fffe, 0x7ffff,
+	0x8fffe, 0x8ffff,
+	0x9fffe, 0x9ffff,
+	0xafffe, 0xaffff,
+	0xbfffe, 0xbffff,
+	0xcfffe, 0xcffff,
+	0xdfffe, 0xdffff,
+	0xefffe, 0x10ffff,
+}; /* CR_Age_2_0 */
+
+/* 'Age_2_1': Derived Age 2.1 */
+static const OnigCodePoint CR_Age_2_1[] = {
+	312,
+	0x0000, 0x01f5,
+	0x01fa, 0x0217,
+	0x0250, 0x02a8,
+	0x02b0, 0x02de,
+	0x02e0, 0x02e9,
+	0x0300, 0x0345,
+	0x0360, 0x0361,
+	0x0374, 0x0375,
+	0x037a, 0x037a,
+	0x037e, 0x037e,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03ce,
+	0x03d0, 0x03d6,
+	0x03da, 0x03da,
+	0x03dc, 0x03dc,
+	0x03de, 0x03de,
+	0x03e0, 0x03e0,
+	0x03e2, 0x03f3,
+	0x0401, 0x040c,
+	0x040e, 0x044f,
+	0x0451, 0x045c,
+	0x045e, 0x0486,
+	0x0490, 0x04c4,
+	0x04c7, 0x04c8,
+	0x04cb, 0x04cc,
+	0x04d0, 0x04eb,
+	0x04ee, 0x04f5,
+	0x04f8, 0x04f9,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x0589,
+	0x0591, 0x05a1,
+	0x05a3, 0x05b9,
+	0x05bb, 0x05c4,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x060c, 0x060c,
+	0x061b, 0x061b,
+	0x061f, 0x061f,
+	0x0621, 0x063a,
+	0x0640, 0x0652,
+	0x0660, 0x066d,
+	0x0670, 0x06b7,
+	0x06ba, 0x06be,
+	0x06c0, 0x06ce,
+	0x06d0, 0x06ed,
+	0x06f0, 0x06f9,
+	0x0901, 0x0903,
+	0x0905, 0x0939,
+	0x093c, 0x094d,
+	0x0950, 0x0954,
+	0x0958, 0x0970,
+	0x0981, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09bc,
+	0x09be, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09cd,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fa,
+	0x0a02, 0x0a02,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a74,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8b,
+	0x0a8d, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae0,
+	0x0ae6, 0x0aef,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b36, 0x0b39,
+	0x0b3c, 0x0b43,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b61,
+	0x0b66, 0x0b70,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb5,
+	0x0bb7, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd7, 0x0bd7,
+	0x0be7, 0x0bf2,
+	0x0c01, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c33,
+	0x0c35, 0x0c39,
+	0x0c3e, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c60, 0x0c61,
+	0x0c66, 0x0c6f,
+	0x0c82, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbe, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce1,
+	0x0ce6, 0x0cef,
+	0x0d02, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d28,
+	0x0d2a, 0x0d39,
+	0x0d3e, 0x0d43,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4d,
+	0x0d57, 0x0d57,
+	0x0d60, 0x0d61,
+	0x0d66, 0x0d6f,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edd,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f69,
+	0x0f71, 0x0f8b,
+	0x0f90, 0x0f95,
+	0x0f97, 0x0f97,
+	0x0f99, 0x0fad,
+	0x0fb1, 0x0fb7,
+	0x0fb9, 0x0fb9,
+	0x10a0, 0x10c5,
+	0x10d0, 0x10f6,
+	0x10fb, 0x10fb,
+	0x1100, 0x1159,
+	0x115f, 0x11a2,
+	0x11a8, 0x11f9,
+	0x1e00, 0x1e9b,
+	0x1ea0, 0x1ef9,
+	0x1f00, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x202e,
+	0x2030, 0x2046,
+	0x206a, 0x2070,
+	0x2074, 0x208e,
+	0x20a0, 0x20ac,
+	0x20d0, 0x20e1,
+	0x2100, 0x2138,
+	0x2153, 0x2182,
+	0x2190, 0x21ea,
+	0x2200, 0x22f1,
+	0x2300, 0x2300,
+	0x2302, 0x237a,
+	0x2400, 0x2424,
+	0x2440, 0x244a,
+	0x2460, 0x24ea,
+	0x2500, 0x2595,
+	0x25a0, 0x25ef,
+	0x2600, 0x2613,
+	0x261a, 0x266f,
+	0x2701, 0x2704,
+	0x2706, 0x2709,
+	0x270c, 0x2727,
+	0x2729, 0x274b,
+	0x274d, 0x274d,
+	0x274f, 0x2752,
+	0x2756, 0x2756,
+	0x2758, 0x275e,
+	0x2761, 0x2767,
+	0x2776, 0x2794,
+	0x2798, 0x27af,
+	0x27b1, 0x27be,
+	0x3000, 0x3037,
+	0x303f, 0x303f,
+	0x3041, 0x3094,
+	0x3099, 0x309e,
+	0x30a1, 0x30fe,
+	0x3105, 0x312c,
+	0x3131, 0x318e,
+	0x3190, 0x319f,
+	0x3200, 0x321c,
+	0x3220, 0x3243,
+	0x3260, 0x327b,
+	0x327f, 0x32b0,
+	0x32c0, 0x32cb,
+	0x32d0, 0x32fe,
+	0x3300, 0x3376,
+	0x337b, 0x33dd,
+	0x33e0, 0x33fe,
+	0x4e00, 0x9fa5,
+	0xac00, 0xd7a3,
+	0xd800, 0xfa2d,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1e, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbb1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdf0, 0xfdfb,
+	0xfe20, 0xfe23,
+	0xfe30, 0xfe44,
+	0xfe49, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe72,
+	0xfe74, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xff5e,
+	0xff61, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfffc, 0xffff,
+	0x1fffe, 0x1ffff,
+	0x2fffe, 0x2ffff,
+	0x3fffe, 0x3ffff,
+	0x4fffe, 0x4ffff,
+	0x5fffe, 0x5ffff,
+	0x6fffe, 0x6ffff,
+	0x7fffe, 0x7ffff,
+	0x8fffe, 0x8ffff,
+	0x9fffe, 0x9ffff,
+	0xafffe, 0xaffff,
+	0xbfffe, 0xbffff,
+	0xcfffe, 0xcffff,
+	0xdfffe, 0xdffff,
+	0xefffe, 0x10ffff,
+}; /* CR_Age_2_1 */
+
+/* 'Age_3_0': Derived Age 3.0 */
+static const OnigCodePoint CR_Age_3_0[] = {
+	369,
+	0x0000, 0x021f,
+	0x0222, 0x0233,
+	0x0250, 0x02ad,
+	0x02b0, 0x02ee,
+	0x0300, 0x034e,
+	0x0360, 0x0362,
+	0x0374, 0x0375,
+	0x037a, 0x037a,
+	0x037e, 0x037e,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03ce,
+	0x03d0, 0x03d7,
+	0x03da, 0x03f3,
+	0x0400, 0x0486,
+	0x0488, 0x0489,
+	0x048c, 0x04c4,
+	0x04c7, 0x04c8,
+	0x04cb, 0x04cc,
+	0x04d0, 0x04f5,
+	0x04f8, 0x04f9,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x058a,
+	0x0591, 0x05a1,
+	0x05a3, 0x05b9,
+	0x05bb, 0x05c4,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x060c, 0x060c,
+	0x061b, 0x061b,
+	0x061f, 0x061f,
+	0x0621, 0x063a,
+	0x0640, 0x0655,
+	0x0660, 0x066d,
+	0x0670, 0x06ed,
+	0x06f0, 0x06fe,
+	0x0700, 0x070d,
+	0x070f, 0x072c,
+	0x0730, 0x074a,
+	0x0780, 0x07b0,
+	0x0901, 0x0903,
+	0x0905, 0x0939,
+	0x093c, 0x094d,
+	0x0950, 0x0954,
+	0x0958, 0x0970,
+	0x0981, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09bc,
+	0x09be, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09cd,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fa,
+	0x0a02, 0x0a02,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a74,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8b,
+	0x0a8d, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae0,
+	0x0ae6, 0x0aef,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b36, 0x0b39,
+	0x0b3c, 0x0b43,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b61,
+	0x0b66, 0x0b70,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb5,
+	0x0bb7, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd7, 0x0bd7,
+	0x0be7, 0x0bf2,
+	0x0c01, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c33,
+	0x0c35, 0x0c39,
+	0x0c3e, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c60, 0x0c61,
+	0x0c66, 0x0c6f,
+	0x0c82, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbe, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce1,
+	0x0ce6, 0x0cef,
+	0x0d02, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d28,
+	0x0d2a, 0x0d39,
+	0x0d3e, 0x0d43,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4d,
+	0x0d57, 0x0d57,
+	0x0d60, 0x0d61,
+	0x0d66, 0x0d6f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edd,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f6a,
+	0x0f71, 0x0f8b,
+	0x0f90, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fbe, 0x0fcc,
+	0x0fcf, 0x0fcf,
+	0x1000, 0x1021,
+	0x1023, 0x1027,
+	0x1029, 0x102a,
+	0x102c, 0x1032,
+	0x1036, 0x1039,
+	0x1040, 0x1059,
+	0x10a0, 0x10c5,
+	0x10d0, 0x10f6,
+	0x10fb, 0x10fb,
+	0x1100, 0x1159,
+	0x115f, 0x11a2,
+	0x11a8, 0x11f9,
+	0x1200, 0x1206,
+	0x1208, 0x1246,
+	0x1248, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1286,
+	0x1288, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12ae,
+	0x12b0, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12ce,
+	0x12d0, 0x12d6,
+	0x12d8, 0x12ee,
+	0x12f0, 0x130e,
+	0x1310, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x131e,
+	0x1320, 0x1346,
+	0x1348, 0x135a,
+	0x1361, 0x137c,
+	0x13a0, 0x13f4,
+	0x1401, 0x1676,
+	0x1680, 0x169c,
+	0x16a0, 0x16f0,
+	0x1780, 0x17dc,
+	0x17e0, 0x17e9,
+	0x1800, 0x180e,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18a9,
+	0x1e00, 0x1e9b,
+	0x1ea0, 0x1ef9,
+	0x1f00, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x2046,
+	0x2048, 0x204d,
+	0x206a, 0x2070,
+	0x2074, 0x208e,
+	0x20a0, 0x20af,
+	0x20d0, 0x20e3,
+	0x2100, 0x213a,
+	0x2153, 0x2183,
+	0x2190, 0x21f3,
+	0x2200, 0x22f1,
+	0x2300, 0x237b,
+	0x237d, 0x239a,
+	0x2400, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x24ea,
+	0x2500, 0x2595,
+	0x25a0, 0x25f7,
+	0x2600, 0x2613,
+	0x2619, 0x2671,
+	0x2701, 0x2704,
+	0x2706, 0x2709,
+	0x270c, 0x2727,
+	0x2729, 0x274b,
+	0x274d, 0x274d,
+	0x274f, 0x2752,
+	0x2756, 0x2756,
+	0x2758, 0x275e,
+	0x2761, 0x2767,
+	0x2776, 0x2794,
+	0x2798, 0x27af,
+	0x27b1, 0x27be,
+	0x2800, 0x28ff,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3000, 0x303a,
+	0x303e, 0x303f,
+	0x3041, 0x3094,
+	0x3099, 0x309e,
+	0x30a1, 0x30fe,
+	0x3105, 0x312c,
+	0x3131, 0x318e,
+	0x3190, 0x31b7,
+	0x3200, 0x321c,
+	0x3220, 0x3243,
+	0x3260, 0x327b,
+	0x327f, 0x32b0,
+	0x32c0, 0x32cb,
+	0x32d0, 0x32fe,
+	0x3300, 0x3376,
+	0x337b, 0x33dd,
+	0x33e0, 0x33fe,
+	0x3400, 0x4db5,
+	0x4e00, 0x9fa5,
+	0xa000, 0xa48c,
+	0xa490, 0xa4a1,
+	0xa4a4, 0xa4b3,
+	0xa4b5, 0xa4c0,
+	0xa4c2, 0xa4c4,
+	0xa4c6, 0xa4c6,
+	0xac00, 0xd7a3,
+	0xd800, 0xfa2d,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbb1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdf0, 0xfdfb,
+	0xfe20, 0xfe23,
+	0xfe30, 0xfe44,
+	0xfe49, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe72,
+	0xfe74, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xff5e,
+	0xff61, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfff9, 0xffff,
+	0x1fffe, 0x1ffff,
+	0x2fffe, 0x2ffff,
+	0x3fffe, 0x3ffff,
+	0x4fffe, 0x4ffff,
+	0x5fffe, 0x5ffff,
+	0x6fffe, 0x6ffff,
+	0x7fffe, 0x7ffff,
+	0x8fffe, 0x8ffff,
+	0x9fffe, 0x9ffff,
+	0xafffe, 0xaffff,
+	0xbfffe, 0xbffff,
+	0xcfffe, 0xcffff,
+	0xdfffe, 0xdffff,
+	0xefffe, 0x10ffff,
+}; /* CR_Age_3_0 */
+
+/* 'Age_3_1': Derived Age 3.1 */
+static const OnigCodePoint CR_Age_3_1[] = {
+	402,
+	0x0000, 0x021f,
+	0x0222, 0x0233,
+	0x0250, 0x02ad,
+	0x02b0, 0x02ee,
+	0x0300, 0x034e,
+	0x0360, 0x0362,
+	0x0374, 0x0375,
+	0x037a, 0x037a,
+	0x037e, 0x037e,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03ce,
+	0x03d0, 0x03d7,
+	0x03da, 0x03f5,
+	0x0400, 0x0486,
+	0x0488, 0x0489,
+	0x048c, 0x04c4,
+	0x04c7, 0x04c8,
+	0x04cb, 0x04cc,
+	0x04d0, 0x04f5,
+	0x04f8, 0x04f9,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x058a,
+	0x0591, 0x05a1,
+	0x05a3, 0x05b9,
+	0x05bb, 0x05c4,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x060c, 0x060c,
+	0x061b, 0x061b,
+	0x061f, 0x061f,
+	0x0621, 0x063a,
+	0x0640, 0x0655,
+	0x0660, 0x066d,
+	0x0670, 0x06ed,
+	0x06f0, 0x06fe,
+	0x0700, 0x070d,
+	0x070f, 0x072c,
+	0x0730, 0x074a,
+	0x0780, 0x07b0,
+	0x0901, 0x0903,
+	0x0905, 0x0939,
+	0x093c, 0x094d,
+	0x0950, 0x0954,
+	0x0958, 0x0970,
+	0x0981, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09bc,
+	0x09be, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09cd,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fa,
+	0x0a02, 0x0a02,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a74,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8b,
+	0x0a8d, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae0,
+	0x0ae6, 0x0aef,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b36, 0x0b39,
+	0x0b3c, 0x0b43,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b61,
+	0x0b66, 0x0b70,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb5,
+	0x0bb7, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd7, 0x0bd7,
+	0x0be7, 0x0bf2,
+	0x0c01, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c33,
+	0x0c35, 0x0c39,
+	0x0c3e, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c60, 0x0c61,
+	0x0c66, 0x0c6f,
+	0x0c82, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbe, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce1,
+	0x0ce6, 0x0cef,
+	0x0d02, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d28,
+	0x0d2a, 0x0d39,
+	0x0d3e, 0x0d43,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4d,
+	0x0d57, 0x0d57,
+	0x0d60, 0x0d61,
+	0x0d66, 0x0d6f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edd,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f6a,
+	0x0f71, 0x0f8b,
+	0x0f90, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fbe, 0x0fcc,
+	0x0fcf, 0x0fcf,
+	0x1000, 0x1021,
+	0x1023, 0x1027,
+	0x1029, 0x102a,
+	0x102c, 0x1032,
+	0x1036, 0x1039,
+	0x1040, 0x1059,
+	0x10a0, 0x10c5,
+	0x10d0, 0x10f6,
+	0x10fb, 0x10fb,
+	0x1100, 0x1159,
+	0x115f, 0x11a2,
+	0x11a8, 0x11f9,
+	0x1200, 0x1206,
+	0x1208, 0x1246,
+	0x1248, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1286,
+	0x1288, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12ae,
+	0x12b0, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12ce,
+	0x12d0, 0x12d6,
+	0x12d8, 0x12ee,
+	0x12f0, 0x130e,
+	0x1310, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x131e,
+	0x1320, 0x1346,
+	0x1348, 0x135a,
+	0x1361, 0x137c,
+	0x13a0, 0x13f4,
+	0x1401, 0x1676,
+	0x1680, 0x169c,
+	0x16a0, 0x16f0,
+	0x1780, 0x17dc,
+	0x17e0, 0x17e9,
+	0x1800, 0x180e,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18a9,
+	0x1e00, 0x1e9b,
+	0x1ea0, 0x1ef9,
+	0x1f00, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x2046,
+	0x2048, 0x204d,
+	0x206a, 0x2070,
+	0x2074, 0x208e,
+	0x20a0, 0x20af,
+	0x20d0, 0x20e3,
+	0x2100, 0x213a,
+	0x2153, 0x2183,
+	0x2190, 0x21f3,
+	0x2200, 0x22f1,
+	0x2300, 0x237b,
+	0x237d, 0x239a,
+	0x2400, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x24ea,
+	0x2500, 0x2595,
+	0x25a0, 0x25f7,
+	0x2600, 0x2613,
+	0x2619, 0x2671,
+	0x2701, 0x2704,
+	0x2706, 0x2709,
+	0x270c, 0x2727,
+	0x2729, 0x274b,
+	0x274d, 0x274d,
+	0x274f, 0x2752,
+	0x2756, 0x2756,
+	0x2758, 0x275e,
+	0x2761, 0x2767,
+	0x2776, 0x2794,
+	0x2798, 0x27af,
+	0x27b1, 0x27be,
+	0x2800, 0x28ff,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3000, 0x303a,
+	0x303e, 0x303f,
+	0x3041, 0x3094,
+	0x3099, 0x309e,
+	0x30a1, 0x30fe,
+	0x3105, 0x312c,
+	0x3131, 0x318e,
+	0x3190, 0x31b7,
+	0x3200, 0x321c,
+	0x3220, 0x3243,
+	0x3260, 0x327b,
+	0x327f, 0x32b0,
+	0x32c0, 0x32cb,
+	0x32d0, 0x32fe,
+	0x3300, 0x3376,
+	0x337b, 0x33dd,
+	0x33e0, 0x33fe,
+	0x3400, 0x4db5,
+	0x4e00, 0x9fa5,
+	0xa000, 0xa48c,
+	0xa490, 0xa4a1,
+	0xa4a4, 0xa4b3,
+	0xa4b5, 0xa4c0,
+	0xa4c2, 0xa4c4,
+	0xa4c6, 0xa4c6,
+	0xac00, 0xd7a3,
+	0xd800, 0xfa2d,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbb1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdd0, 0xfdfb,
+	0xfe20, 0xfe23,
+	0xfe30, 0xfe44,
+	0xfe49, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe72,
+	0xfe74, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xff5e,
+	0xff61, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfff9, 0xffff,
+	0x10300, 0x1031e,
+	0x10320, 0x10323,
+	0x10330, 0x1034a,
+	0x10400, 0x10425,
+	0x10428, 0x1044d,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d12a, 0x1d1dd,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c0,
+	0x1d4c2, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a3,
+	0x1d6a8, 0x1d7c9,
+	0x1d7ce, 0x1d7ff,
+	0x1fffe, 0x2a6d6,
+	0x2f800, 0x2fa1d,
+	0x2fffe, 0x2ffff,
+	0x3fffe, 0x3ffff,
+	0x4fffe, 0x4ffff,
+	0x5fffe, 0x5ffff,
+	0x6fffe, 0x6ffff,
+	0x7fffe, 0x7ffff,
+	0x8fffe, 0x8ffff,
+	0x9fffe, 0x9ffff,
+	0xafffe, 0xaffff,
+	0xbfffe, 0xbffff,
+	0xcfffe, 0xcffff,
+	0xdfffe, 0xdffff,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+	0xefffe, 0x10ffff,
+}; /* CR_Age_3_1 */
+
+/* 'Age_3_2': Derived Age 3.2 */
+static const OnigCodePoint CR_Age_3_2[] = {
+	397,
+	0x0000, 0x0220,
+	0x0222, 0x0233,
+	0x0250, 0x02ad,
+	0x02b0, 0x02ee,
+	0x0300, 0x034f,
+	0x0360, 0x036f,
+	0x0374, 0x0375,
+	0x037a, 0x037a,
+	0x037e, 0x037e,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03ce,
+	0x03d0, 0x03f6,
+	0x0400, 0x0486,
+	0x0488, 0x04ce,
+	0x04d0, 0x04f5,
+	0x04f8, 0x04f9,
+	0x0500, 0x050f,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x058a,
+	0x0591, 0x05a1,
+	0x05a3, 0x05b9,
+	0x05bb, 0x05c4,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x060c, 0x060c,
+	0x061b, 0x061b,
+	0x061f, 0x061f,
+	0x0621, 0x063a,
+	0x0640, 0x0655,
+	0x0660, 0x06ed,
+	0x06f0, 0x06fe,
+	0x0700, 0x070d,
+	0x070f, 0x072c,
+	0x0730, 0x074a,
+	0x0780, 0x07b1,
+	0x0901, 0x0903,
+	0x0905, 0x0939,
+	0x093c, 0x094d,
+	0x0950, 0x0954,
+	0x0958, 0x0970,
+	0x0981, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09bc,
+	0x09be, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09cd,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fa,
+	0x0a02, 0x0a02,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a74,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8b,
+	0x0a8d, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae0,
+	0x0ae6, 0x0aef,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b36, 0x0b39,
+	0x0b3c, 0x0b43,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b61,
+	0x0b66, 0x0b70,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb5,
+	0x0bb7, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd7, 0x0bd7,
+	0x0be7, 0x0bf2,
+	0x0c01, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c33,
+	0x0c35, 0x0c39,
+	0x0c3e, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c60, 0x0c61,
+	0x0c66, 0x0c6f,
+	0x0c82, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbe, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce1,
+	0x0ce6, 0x0cef,
+	0x0d02, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d28,
+	0x0d2a, 0x0d39,
+	0x0d3e, 0x0d43,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4d,
+	0x0d57, 0x0d57,
+	0x0d60, 0x0d61,
+	0x0d66, 0x0d6f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edd,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f6a,
+	0x0f71, 0x0f8b,
+	0x0f90, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fbe, 0x0fcc,
+	0x0fcf, 0x0fcf,
+	0x1000, 0x1021,
+	0x1023, 0x1027,
+	0x1029, 0x102a,
+	0x102c, 0x1032,
+	0x1036, 0x1039,
+	0x1040, 0x1059,
+	0x10a0, 0x10c5,
+	0x10d0, 0x10f8,
+	0x10fb, 0x10fb,
+	0x1100, 0x1159,
+	0x115f, 0x11a2,
+	0x11a8, 0x11f9,
+	0x1200, 0x1206,
+	0x1208, 0x1246,
+	0x1248, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1286,
+	0x1288, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12ae,
+	0x12b0, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12ce,
+	0x12d0, 0x12d6,
+	0x12d8, 0x12ee,
+	0x12f0, 0x130e,
+	0x1310, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x131e,
+	0x1320, 0x1346,
+	0x1348, 0x135a,
+	0x1361, 0x137c,
+	0x13a0, 0x13f4,
+	0x1401, 0x1676,
+	0x1680, 0x169c,
+	0x16a0, 0x16f0,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+	0x1720, 0x1736,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17dc,
+	0x17e0, 0x17e9,
+	0x1800, 0x180e,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18a9,
+	0x1e00, 0x1e9b,
+	0x1ea0, 0x1ef9,
+	0x1f00, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x2052,
+	0x2057, 0x2057,
+	0x205f, 0x2063,
+	0x206a, 0x2071,
+	0x2074, 0x208e,
+	0x20a0, 0x20b1,
+	0x20d0, 0x20ea,
+	0x2100, 0x213a,
+	0x213d, 0x214b,
+	0x2153, 0x2183,
+	0x2190, 0x23ce,
+	0x2400, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x24fe,
+	0x2500, 0x2613,
+	0x2616, 0x2617,
+	0x2619, 0x267d,
+	0x2680, 0x2689,
+	0x2701, 0x2704,
+	0x2706, 0x2709,
+	0x270c, 0x2727,
+	0x2729, 0x274b,
+	0x274d, 0x274d,
+	0x274f, 0x2752,
+	0x2756, 0x2756,
+	0x2758, 0x275e,
+	0x2761, 0x2794,
+	0x2798, 0x27af,
+	0x27b1, 0x27be,
+	0x27d0, 0x27eb,
+	0x27f0, 0x2aff,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3000, 0x303f,
+	0x3041, 0x3096,
+	0x3099, 0x30ff,
+	0x3105, 0x312c,
+	0x3131, 0x318e,
+	0x3190, 0x31b7,
+	0x31f0, 0x321c,
+	0x3220, 0x3243,
+	0x3251, 0x327b,
+	0x327f, 0x32cb,
+	0x32d0, 0x32fe,
+	0x3300, 0x3376,
+	0x337b, 0x33dd,
+	0x33e0, 0x33fe,
+	0x3400, 0x4db5,
+	0x4e00, 0x9fa5,
+	0xa000, 0xa48c,
+	0xa490, 0xa4c6,
+	0xac00, 0xd7a3,
+	0xd800, 0xfa2d,
+	0xfa30, 0xfa6a,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbb1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdd0, 0xfdfc,
+	0xfe00, 0xfe0f,
+	0xfe20, 0xfe23,
+	0xfe30, 0xfe46,
+	0xfe49, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfff9, 0xffff,
+	0x10300, 0x1031e,
+	0x10320, 0x10323,
+	0x10330, 0x1034a,
+	0x10400, 0x10425,
+	0x10428, 0x1044d,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d12a, 0x1d1dd,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c0,
+	0x1d4c2, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a3,
+	0x1d6a8, 0x1d7c9,
+	0x1d7ce, 0x1d7ff,
+	0x1fffe, 0x2a6d6,
+	0x2f800, 0x2fa1d,
+	0x2fffe, 0x2ffff,
+	0x3fffe, 0x3ffff,
+	0x4fffe, 0x4ffff,
+	0x5fffe, 0x5ffff,
+	0x6fffe, 0x6ffff,
+	0x7fffe, 0x7ffff,
+	0x8fffe, 0x8ffff,
+	0x9fffe, 0x9ffff,
+	0xafffe, 0xaffff,
+	0xbfffe, 0xbffff,
+	0xcfffe, 0xcffff,
+	0xdfffe, 0xdffff,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+	0xefffe, 0x10ffff,
+}; /* CR_Age_3_2 */
+
+/* 'Age_4_0': Derived Age 4.0 */
+static const OnigCodePoint CR_Age_4_0[] = {
+	412,
+	0x0000, 0x0236,
+	0x0250, 0x0357,
+	0x035d, 0x036f,
+	0x0374, 0x0375,
+	0x037a, 0x037a,
+	0x037e, 0x037e,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03ce,
+	0x03d0, 0x03fb,
+	0x0400, 0x0486,
+	0x0488, 0x04ce,
+	0x04d0, 0x04f5,
+	0x04f8, 0x04f9,
+	0x0500, 0x050f,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x058a,
+	0x0591, 0x05a1,
+	0x05a3, 0x05b9,
+	0x05bb, 0x05c4,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x0600, 0x0603,
+	0x060c, 0x0615,
+	0x061b, 0x061b,
+	0x061f, 0x061f,
+	0x0621, 0x063a,
+	0x0640, 0x0658,
+	0x0660, 0x070d,
+	0x070f, 0x074a,
+	0x074d, 0x074f,
+	0x0780, 0x07b1,
+	0x0901, 0x0939,
+	0x093c, 0x094d,
+	0x0950, 0x0954,
+	0x0958, 0x0970,
+	0x0981, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09cd,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fa,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a74,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0aef,
+	0x0af1, 0x0af1,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3c, 0x0b43,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b61,
+	0x0b66, 0x0b71,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb5,
+	0x0bb7, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd7, 0x0bd7,
+	0x0be7, 0x0bfa,
+	0x0c01, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c33,
+	0x0c35, 0x0c39,
+	0x0c3e, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c60, 0x0c61,
+	0x0c66, 0x0c6f,
+	0x0c82, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbc, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce1,
+	0x0ce6, 0x0cef,
+	0x0d02, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d28,
+	0x0d2a, 0x0d39,
+	0x0d3e, 0x0d43,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4d,
+	0x0d57, 0x0d57,
+	0x0d60, 0x0d61,
+	0x0d66, 0x0d6f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edd,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f6a,
+	0x0f71, 0x0f8b,
+	0x0f90, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fbe, 0x0fcc,
+	0x0fcf, 0x0fcf,
+	0x1000, 0x1021,
+	0x1023, 0x1027,
+	0x1029, 0x102a,
+	0x102c, 0x1032,
+	0x1036, 0x1039,
+	0x1040, 0x1059,
+	0x10a0, 0x10c5,
+	0x10d0, 0x10f8,
+	0x10fb, 0x10fb,
+	0x1100, 0x1159,
+	0x115f, 0x11a2,
+	0x11a8, 0x11f9,
+	0x1200, 0x1206,
+	0x1208, 0x1246,
+	0x1248, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1286,
+	0x1288, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12ae,
+	0x12b0, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12ce,
+	0x12d0, 0x12d6,
+	0x12d8, 0x12ee,
+	0x12f0, 0x130e,
+	0x1310, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x131e,
+	0x1320, 0x1346,
+	0x1348, 0x135a,
+	0x1361, 0x137c,
+	0x13a0, 0x13f4,
+	0x1401, 0x1676,
+	0x1680, 0x169c,
+	0x16a0, 0x16f0,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+	0x1720, 0x1736,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17dd,
+	0x17e0, 0x17e9,
+	0x17f0, 0x17f9,
+	0x1800, 0x180e,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18a9,
+	0x1900, 0x191c,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1940, 0x1940,
+	0x1944, 0x196d,
+	0x1970, 0x1974,
+	0x19e0, 0x19ff,
+	0x1d00, 0x1d6b,
+	0x1e00, 0x1e9b,
+	0x1ea0, 0x1ef9,
+	0x1f00, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x2054,
+	0x2057, 0x2057,
+	0x205f, 0x2063,
+	0x206a, 0x2071,
+	0x2074, 0x208e,
+	0x20a0, 0x20b1,
+	0x20d0, 0x20ea,
+	0x2100, 0x213b,
+	0x213d, 0x214b,
+	0x2153, 0x2183,
+	0x2190, 0x23d0,
+	0x2400, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x2617,
+	0x2619, 0x267d,
+	0x2680, 0x2691,
+	0x26a0, 0x26a1,
+	0x2701, 0x2704,
+	0x2706, 0x2709,
+	0x270c, 0x2727,
+	0x2729, 0x274b,
+	0x274d, 0x274d,
+	0x274f, 0x2752,
+	0x2756, 0x2756,
+	0x2758, 0x275e,
+	0x2761, 0x2794,
+	0x2798, 0x27af,
+	0x27b1, 0x27be,
+	0x27d0, 0x27eb,
+	0x27f0, 0x2b0d,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3000, 0x303f,
+	0x3041, 0x3096,
+	0x3099, 0x30ff,
+	0x3105, 0x312c,
+	0x3131, 0x318e,
+	0x3190, 0x31b7,
+	0x31f0, 0x321e,
+	0x3220, 0x3243,
+	0x3250, 0x327d,
+	0x327f, 0x32fe,
+	0x3300, 0x4db5,
+	0x4dc0, 0x9fa5,
+	0xa000, 0xa48c,
+	0xa490, 0xa4c6,
+	0xac00, 0xd7a3,
+	0xd800, 0xfa2d,
+	0xfa30, 0xfa6a,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbb1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdd0, 0xfdfd,
+	0xfe00, 0xfe0f,
+	0xfe20, 0xfe23,
+	0xfe30, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfff9, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10100, 0x10102,
+	0x10107, 0x10133,
+	0x10137, 0x1013f,
+	0x10300, 0x1031e,
+	0x10320, 0x10323,
+	0x10330, 0x1034a,
+	0x10380, 0x1039d,
+	0x1039f, 0x1039f,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x1083f,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d12a, 0x1d1dd,
+	0x1d300, 0x1d356,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a3,
+	0x1d6a8, 0x1d7c9,
+	0x1d7ce, 0x1d7ff,
+	0x1fffe, 0x2a6d6,
+	0x2f800, 0x2fa1d,
+	0x2fffe, 0x2ffff,
+	0x3fffe, 0x3ffff,
+	0x4fffe, 0x4ffff,
+	0x5fffe, 0x5ffff,
+	0x6fffe, 0x6ffff,
+	0x7fffe, 0x7ffff,
+	0x8fffe, 0x8ffff,
+	0x9fffe, 0x9ffff,
+	0xafffe, 0xaffff,
+	0xbfffe, 0xbffff,
+	0xcfffe, 0xcffff,
+	0xdfffe, 0xdffff,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+	0xe0100, 0xe01ef,
+	0xefffe, 0x10ffff,
+}; /* CR_Age_4_0 */
+
+/* 'Age_4_1': Derived Age 4.1 */
+static const OnigCodePoint CR_Age_4_1[] = {
+	430,
+	0x0000, 0x0241,
+	0x0250, 0x036f,
+	0x0374, 0x0375,
+	0x037a, 0x037a,
+	0x037e, 0x037e,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03ce,
+	0x03d0, 0x0486,
+	0x0488, 0x04ce,
+	0x04d0, 0x04f9,
+	0x0500, 0x050f,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x058a,
+	0x0591, 0x05b9,
+	0x05bb, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x0600, 0x0603,
+	0x060b, 0x0615,
+	0x061b, 0x061b,
+	0x061e, 0x061f,
+	0x0621, 0x063a,
+	0x0640, 0x065e,
+	0x0660, 0x070d,
+	0x070f, 0x074a,
+	0x074d, 0x076d,
+	0x0780, 0x07b1,
+	0x0901, 0x0939,
+	0x093c, 0x094d,
+	0x0950, 0x0954,
+	0x0958, 0x0970,
+	0x097d, 0x097d,
+	0x0981, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fa,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a74,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0aef,
+	0x0af1, 0x0af1,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3c, 0x0b43,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b61,
+	0x0b66, 0x0b71,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bfa,
+	0x0c01, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c33,
+	0x0c35, 0x0c39,
+	0x0c3e, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c60, 0x0c61,
+	0x0c66, 0x0c6f,
+	0x0c82, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbc, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce1,
+	0x0ce6, 0x0cef,
+	0x0d02, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d28,
+	0x0d2a, 0x0d39,
+	0x0d3e, 0x0d43,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4d,
+	0x0d57, 0x0d57,
+	0x0d60, 0x0d61,
+	0x0d66, 0x0d6f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edd,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f6a,
+	0x0f71, 0x0f8b,
+	0x0f90, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fbe, 0x0fcc,
+	0x0fcf, 0x0fd1,
+	0x1000, 0x1021,
+	0x1023, 0x1027,
+	0x1029, 0x102a,
+	0x102c, 0x1032,
+	0x1036, 0x1039,
+	0x1040, 0x1059,
+	0x10a0, 0x10c5,
+	0x10d0, 0x10fc,
+	0x1100, 0x1159,
+	0x115f, 0x11a2,
+	0x11a8, 0x11f9,
+	0x1200, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135f, 0x137c,
+	0x1380, 0x1399,
+	0x13a0, 0x13f4,
+	0x1401, 0x1676,
+	0x1680, 0x169c,
+	0x16a0, 0x16f0,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+	0x1720, 0x1736,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17dd,
+	0x17e0, 0x17e9,
+	0x17f0, 0x17f9,
+	0x1800, 0x180e,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18a9,
+	0x1900, 0x191c,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1940, 0x1940,
+	0x1944, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19a9,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19d9,
+	0x19de, 0x1a1b,
+	0x1a1e, 0x1a1f,
+	0x1d00, 0x1dc3,
+	0x1e00, 0x1e9b,
+	0x1ea0, 0x1ef9,
+	0x1f00, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x2063,
+	0x206a, 0x2071,
+	0x2074, 0x208e,
+	0x2090, 0x2094,
+	0x20a0, 0x20b5,
+	0x20d0, 0x20eb,
+	0x2100, 0x214c,
+	0x2153, 0x2183,
+	0x2190, 0x23db,
+	0x2400, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x269c,
+	0x26a0, 0x26b1,
+	0x2701, 0x2704,
+	0x2706, 0x2709,
+	0x270c, 0x2727,
+	0x2729, 0x274b,
+	0x274d, 0x274d,
+	0x274f, 0x2752,
+	0x2756, 0x2756,
+	0x2758, 0x275e,
+	0x2761, 0x2794,
+	0x2798, 0x27af,
+	0x27b1, 0x27be,
+	0x27c0, 0x27c6,
+	0x27d0, 0x27eb,
+	0x27f0, 0x2b13,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c80, 0x2cea,
+	0x2cf9, 0x2d25,
+	0x2d30, 0x2d65,
+	0x2d6f, 0x2d6f,
+	0x2d80, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2e00, 0x2e17,
+	0x2e1c, 0x2e1d,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3000, 0x303f,
+	0x3041, 0x3096,
+	0x3099, 0x30ff,
+	0x3105, 0x312c,
+	0x3131, 0x318e,
+	0x3190, 0x31b7,
+	0x31c0, 0x31cf,
+	0x31f0, 0x321e,
+	0x3220, 0x3243,
+	0x3250, 0x32fe,
+	0x3300, 0x4db5,
+	0x4dc0, 0x9fbb,
+	0xa000, 0xa48c,
+	0xa490, 0xa4c6,
+	0xa700, 0xa716,
+	0xa800, 0xa82b,
+	0xac00, 0xd7a3,
+	0xd800, 0xfa2d,
+	0xfa30, 0xfa6a,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbb1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdd0, 0xfdfd,
+	0xfe00, 0xfe19,
+	0xfe20, 0xfe23,
+	0xfe30, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfff9, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10100, 0x10102,
+	0x10107, 0x10133,
+	0x10137, 0x1018a,
+	0x10300, 0x1031e,
+	0x10320, 0x10323,
+	0x10330, 0x1034a,
+	0x10380, 0x1039d,
+	0x1039f, 0x103c3,
+	0x103c8, 0x103d5,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x1083f,
+	0x10a00, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a47,
+	0x10a50, 0x10a58,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d12a, 0x1d1dd,
+	0x1d200, 0x1d245,
+	0x1d300, 0x1d356,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d7c9,
+	0x1d7ce, 0x1d7ff,
+	0x1fffe, 0x2a6d6,
+	0x2f800, 0x2fa1d,
+	0x2fffe, 0x2ffff,
+	0x3fffe, 0x3ffff,
+	0x4fffe, 0x4ffff,
+	0x5fffe, 0x5ffff,
+	0x6fffe, 0x6ffff,
+	0x7fffe, 0x7ffff,
+	0x8fffe, 0x8ffff,
+	0x9fffe, 0x9ffff,
+	0xafffe, 0xaffff,
+	0xbfffe, 0xbffff,
+	0xcfffe, 0xcffff,
+	0xdfffe, 0xdffff,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+	0xe0100, 0xe01ef,
+	0xefffe, 0x10ffff,
+}; /* CR_Age_4_1 */
+
+/* 'Age_5_0': Derived Age 5.0 */
+static const OnigCodePoint CR_Age_5_0[] = {
+	440,
+	0x0000, 0x036f,
+	0x0374, 0x0375,
+	0x037a, 0x037e,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x03ce,
+	0x03d0, 0x0486,
+	0x0488, 0x0513,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x058a,
+	0x0591, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x0600, 0x0603,
+	0x060b, 0x0615,
+	0x061b, 0x061b,
+	0x061e, 0x061f,
+	0x0621, 0x063a,
+	0x0640, 0x065e,
+	0x0660, 0x070d,
+	0x070f, 0x074a,
+	0x074d, 0x076d,
+	0x0780, 0x07b1,
+	0x07c0, 0x07fa,
+	0x0901, 0x0939,
+	0x093c, 0x094d,
+	0x0950, 0x0954,
+	0x0958, 0x0970,
+	0x097b, 0x097f,
+	0x0981, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fa,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a74,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0aef,
+	0x0af1, 0x0af1,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3c, 0x0b43,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b61,
+	0x0b66, 0x0b71,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bfa,
+	0x0c01, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c33,
+	0x0c35, 0x0c39,
+	0x0c3e, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c60, 0x0c61,
+	0x0c66, 0x0c6f,
+	0x0c82, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbc, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce3,
+	0x0ce6, 0x0cef,
+	0x0cf1, 0x0cf2,
+	0x0d02, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d28,
+	0x0d2a, 0x0d39,
+	0x0d3e, 0x0d43,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4d,
+	0x0d57, 0x0d57,
+	0x0d60, 0x0d61,
+	0x0d66, 0x0d6f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edd,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f6a,
+	0x0f71, 0x0f8b,
+	0x0f90, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fbe, 0x0fcc,
+	0x0fcf, 0x0fd1,
+	0x1000, 0x1021,
+	0x1023, 0x1027,
+	0x1029, 0x102a,
+	0x102c, 0x1032,
+	0x1036, 0x1039,
+	0x1040, 0x1059,
+	0x10a0, 0x10c5,
+	0x10d0, 0x10fc,
+	0x1100, 0x1159,
+	0x115f, 0x11a2,
+	0x11a8, 0x11f9,
+	0x1200, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135f, 0x137c,
+	0x1380, 0x1399,
+	0x13a0, 0x13f4,
+	0x1401, 0x1676,
+	0x1680, 0x169c,
+	0x16a0, 0x16f0,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+	0x1720, 0x1736,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17dd,
+	0x17e0, 0x17e9,
+	0x17f0, 0x17f9,
+	0x1800, 0x180e,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18a9,
+	0x1900, 0x191c,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1940, 0x1940,
+	0x1944, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19a9,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19d9,
+	0x19de, 0x1a1b,
+	0x1a1e, 0x1a1f,
+	0x1b00, 0x1b4b,
+	0x1b50, 0x1b7c,
+	0x1d00, 0x1dca,
+	0x1dfe, 0x1e9b,
+	0x1ea0, 0x1ef9,
+	0x1f00, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x2063,
+	0x206a, 0x2071,
+	0x2074, 0x208e,
+	0x2090, 0x2094,
+	0x20a0, 0x20b5,
+	0x20d0, 0x20ef,
+	0x2100, 0x214e,
+	0x2153, 0x2184,
+	0x2190, 0x23e7,
+	0x2400, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x269c,
+	0x26a0, 0x26b2,
+	0x2701, 0x2704,
+	0x2706, 0x2709,
+	0x270c, 0x2727,
+	0x2729, 0x274b,
+	0x274d, 0x274d,
+	0x274f, 0x2752,
+	0x2756, 0x2756,
+	0x2758, 0x275e,
+	0x2761, 0x2794,
+	0x2798, 0x27af,
+	0x27b1, 0x27be,
+	0x27c0, 0x27ca,
+	0x27d0, 0x27eb,
+	0x27f0, 0x2b1a,
+	0x2b20, 0x2b23,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2c6c,
+	0x2c74, 0x2c77,
+	0x2c80, 0x2cea,
+	0x2cf9, 0x2d25,
+	0x2d30, 0x2d65,
+	0x2d6f, 0x2d6f,
+	0x2d80, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2e00, 0x2e17,
+	0x2e1c, 0x2e1d,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3000, 0x303f,
+	0x3041, 0x3096,
+	0x3099, 0x30ff,
+	0x3105, 0x312c,
+	0x3131, 0x318e,
+	0x3190, 0x31b7,
+	0x31c0, 0x31cf,
+	0x31f0, 0x321e,
+	0x3220, 0x3243,
+	0x3250, 0x32fe,
+	0x3300, 0x4db5,
+	0x4dc0, 0x9fbb,
+	0xa000, 0xa48c,
+	0xa490, 0xa4c6,
+	0xa700, 0xa71a,
+	0xa720, 0xa721,
+	0xa800, 0xa82b,
+	0xa840, 0xa877,
+	0xac00, 0xd7a3,
+	0xd800, 0xfa2d,
+	0xfa30, 0xfa6a,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbb1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdd0, 0xfdfd,
+	0xfe00, 0xfe19,
+	0xfe20, 0xfe23,
+	0xfe30, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfff9, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10100, 0x10102,
+	0x10107, 0x10133,
+	0x10137, 0x1018a,
+	0x10300, 0x1031e,
+	0x10320, 0x10323,
+	0x10330, 0x1034a,
+	0x10380, 0x1039d,
+	0x1039f, 0x103c3,
+	0x103c8, 0x103d5,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x1083f,
+	0x10900, 0x10919,
+	0x1091f, 0x1091f,
+	0x10a00, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a47,
+	0x10a50, 0x10a58,
+	0x12000, 0x1236e,
+	0x12400, 0x12462,
+	0x12470, 0x12473,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d12a, 0x1d1dd,
+	0x1d200, 0x1d245,
+	0x1d300, 0x1d356,
+	0x1d360, 0x1d371,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d7cb,
+	0x1d7ce, 0x1d7ff,
+	0x1fffe, 0x2a6d6,
+	0x2f800, 0x2fa1d,
+	0x2fffe, 0x2ffff,
+	0x3fffe, 0x3ffff,
+	0x4fffe, 0x4ffff,
+	0x5fffe, 0x5ffff,
+	0x6fffe, 0x6ffff,
+	0x7fffe, 0x7ffff,
+	0x8fffe, 0x8ffff,
+	0x9fffe, 0x9ffff,
+	0xafffe, 0xaffff,
+	0xbfffe, 0xbffff,
+	0xcfffe, 0xcffff,
+	0xdfffe, 0xdffff,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+	0xe0100, 0xe01ef,
+	0xefffe, 0x10ffff,
+}; /* CR_Age_5_0 */
+
+/* 'Age_5_1': Derived Age 5.1 */
+static const OnigCodePoint CR_Age_5_1[] = {
+	455,
+	0x0000, 0x0377,
+	0x037a, 0x037e,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x0523,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x058a,
+	0x0591, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x0600, 0x0603,
+	0x0606, 0x061b,
+	0x061e, 0x061f,
+	0x0621, 0x065e,
+	0x0660, 0x070d,
+	0x070f, 0x074a,
+	0x074d, 0x07b1,
+	0x07c0, 0x07fa,
+	0x0901, 0x0939,
+	0x093c, 0x094d,
+	0x0950, 0x0954,
+	0x0958, 0x0972,
+	0x097b, 0x097f,
+	0x0981, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fa,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a75,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0aef,
+	0x0af1, 0x0af1,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3c, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b63,
+	0x0b66, 0x0b71,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd0, 0x0bd0,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bfa,
+	0x0c01, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c33,
+	0x0c35, 0x0c39,
+	0x0c3d, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c58, 0x0c59,
+	0x0c60, 0x0c63,
+	0x0c66, 0x0c6f,
+	0x0c78, 0x0c7f,
+	0x0c82, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbc, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce3,
+	0x0ce6, 0x0cef,
+	0x0cf1, 0x0cf2,
+	0x0d02, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d28,
+	0x0d2a, 0x0d39,
+	0x0d3d, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4d,
+	0x0d57, 0x0d57,
+	0x0d60, 0x0d63,
+	0x0d66, 0x0d75,
+	0x0d79, 0x0d7f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edd,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f71, 0x0f8b,
+	0x0f90, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fbe, 0x0fcc,
+	0x0fce, 0x0fd4,
+	0x1000, 0x1099,
+	0x109e, 0x10c5,
+	0x10d0, 0x10fc,
+	0x1100, 0x1159,
+	0x115f, 0x11a2,
+	0x11a8, 0x11f9,
+	0x1200, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135f, 0x137c,
+	0x1380, 0x1399,
+	0x13a0, 0x13f4,
+	0x1401, 0x1676,
+	0x1680, 0x169c,
+	0x16a0, 0x16f0,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+	0x1720, 0x1736,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17dd,
+	0x17e0, 0x17e9,
+	0x17f0, 0x17f9,
+	0x1800, 0x180e,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18aa,
+	0x1900, 0x191c,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1940, 0x1940,
+	0x1944, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19a9,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19d9,
+	0x19de, 0x1a1b,
+	0x1a1e, 0x1a1f,
+	0x1b00, 0x1b4b,
+	0x1b50, 0x1b7c,
+	0x1b80, 0x1baa,
+	0x1bae, 0x1bb9,
+	0x1c00, 0x1c37,
+	0x1c3b, 0x1c49,
+	0x1c4d, 0x1c7f,
+	0x1d00, 0x1de6,
+	0x1dfe, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x2064,
+	0x206a, 0x2071,
+	0x2074, 0x208e,
+	0x2090, 0x2094,
+	0x20a0, 0x20b5,
+	0x20d0, 0x20f0,
+	0x2100, 0x214f,
+	0x2153, 0x2188,
+	0x2190, 0x23e7,
+	0x2400, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x269d,
+	0x26a0, 0x26bc,
+	0x26c0, 0x26c3,
+	0x2701, 0x2704,
+	0x2706, 0x2709,
+	0x270c, 0x2727,
+	0x2729, 0x274b,
+	0x274d, 0x274d,
+	0x274f, 0x2752,
+	0x2756, 0x2756,
+	0x2758, 0x275e,
+	0x2761, 0x2794,
+	0x2798, 0x27af,
+	0x27b1, 0x27be,
+	0x27c0, 0x27ca,
+	0x27cc, 0x27cc,
+	0x27d0, 0x2b4c,
+	0x2b50, 0x2b54,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2c6f,
+	0x2c71, 0x2c7d,
+	0x2c80, 0x2cea,
+	0x2cf9, 0x2d25,
+	0x2d30, 0x2d65,
+	0x2d6f, 0x2d6f,
+	0x2d80, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2de0, 0x2e30,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3000, 0x303f,
+	0x3041, 0x3096,
+	0x3099, 0x30ff,
+	0x3105, 0x312d,
+	0x3131, 0x318e,
+	0x3190, 0x31b7,
+	0x31c0, 0x31e3,
+	0x31f0, 0x321e,
+	0x3220, 0x3243,
+	0x3250, 0x32fe,
+	0x3300, 0x4db5,
+	0x4dc0, 0x9fc3,
+	0xa000, 0xa48c,
+	0xa490, 0xa4c6,
+	0xa500, 0xa62b,
+	0xa640, 0xa65f,
+	0xa662, 0xa673,
+	0xa67c, 0xa697,
+	0xa700, 0xa78c,
+	0xa7fb, 0xa82b,
+	0xa840, 0xa877,
+	0xa880, 0xa8c4,
+	0xa8ce, 0xa8d9,
+	0xa900, 0xa953,
+	0xa95f, 0xa95f,
+	0xaa00, 0xaa36,
+	0xaa40, 0xaa4d,
+	0xaa50, 0xaa59,
+	0xaa5c, 0xaa5f,
+	0xac00, 0xd7a3,
+	0xd800, 0xfa2d,
+	0xfa30, 0xfa6a,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbb1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdd0, 0xfdfd,
+	0xfe00, 0xfe19,
+	0xfe20, 0xfe26,
+	0xfe30, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfff9, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10100, 0x10102,
+	0x10107, 0x10133,
+	0x10137, 0x1018a,
+	0x10190, 0x1019b,
+	0x101d0, 0x101fd,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x10300, 0x1031e,
+	0x10320, 0x10323,
+	0x10330, 0x1034a,
+	0x10380, 0x1039d,
+	0x1039f, 0x103c3,
+	0x103c8, 0x103d5,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x1083f,
+	0x10900, 0x10919,
+	0x1091f, 0x10939,
+	0x1093f, 0x1093f,
+	0x10a00, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a47,
+	0x10a50, 0x10a58,
+	0x12000, 0x1236e,
+	0x12400, 0x12462,
+	0x12470, 0x12473,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d129, 0x1d1dd,
+	0x1d200, 0x1d245,
+	0x1d300, 0x1d356,
+	0x1d360, 0x1d371,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d7cb,
+	0x1d7ce, 0x1d7ff,
+	0x1f000, 0x1f02b,
+	0x1f030, 0x1f093,
+	0x1fffe, 0x2a6d6,
+	0x2f800, 0x2fa1d,
+	0x2fffe, 0x2ffff,
+	0x3fffe, 0x3ffff,
+	0x4fffe, 0x4ffff,
+	0x5fffe, 0x5ffff,
+	0x6fffe, 0x6ffff,
+	0x7fffe, 0x7ffff,
+	0x8fffe, 0x8ffff,
+	0x9fffe, 0x9ffff,
+	0xafffe, 0xaffff,
+	0xbfffe, 0xbffff,
+	0xcfffe, 0xcffff,
+	0xdfffe, 0xdffff,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+	0xe0100, 0xe01ef,
+	0xefffe, 0x10ffff,
+}; /* CR_Age_5_1 */
+
+/* 'Age_5_2': Derived Age 5.2 */
+static const OnigCodePoint CR_Age_5_2[] = {
+	495,
+	0x0000, 0x0377,
+	0x037a, 0x037e,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x0525,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x058a,
+	0x0591, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x0600, 0x0603,
+	0x0606, 0x061b,
+	0x061e, 0x061f,
+	0x0621, 0x065e,
+	0x0660, 0x070d,
+	0x070f, 0x074a,
+	0x074d, 0x07b1,
+	0x07c0, 0x07fa,
+	0x0800, 0x082d,
+	0x0830, 0x083e,
+	0x0900, 0x0939,
+	0x093c, 0x094e,
+	0x0950, 0x0955,
+	0x0958, 0x0972,
+	0x0979, 0x097f,
+	0x0981, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fb,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a75,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0aef,
+	0x0af1, 0x0af1,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3c, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b63,
+	0x0b66, 0x0b71,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd0, 0x0bd0,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bfa,
+	0x0c01, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c33,
+	0x0c35, 0x0c39,
+	0x0c3d, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c58, 0x0c59,
+	0x0c60, 0x0c63,
+	0x0c66, 0x0c6f,
+	0x0c78, 0x0c7f,
+	0x0c82, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbc, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce3,
+	0x0ce6, 0x0cef,
+	0x0cf1, 0x0cf2,
+	0x0d02, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d28,
+	0x0d2a, 0x0d39,
+	0x0d3d, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4d,
+	0x0d57, 0x0d57,
+	0x0d60, 0x0d63,
+	0x0d66, 0x0d75,
+	0x0d79, 0x0d7f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edd,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f71, 0x0f8b,
+	0x0f90, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fbe, 0x0fcc,
+	0x0fce, 0x0fd8,
+	0x1000, 0x10c5,
+	0x10d0, 0x10fc,
+	0x1100, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135f, 0x137c,
+	0x1380, 0x1399,
+	0x13a0, 0x13f4,
+	0x1400, 0x169c,
+	0x16a0, 0x16f0,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+	0x1720, 0x1736,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17dd,
+	0x17e0, 0x17e9,
+	0x17f0, 0x17f9,
+	0x1800, 0x180e,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191c,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1940, 0x1940,
+	0x1944, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19da,
+	0x19de, 0x1a1b,
+	0x1a1e, 0x1a5e,
+	0x1a60, 0x1a7c,
+	0x1a7f, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1aa0, 0x1aad,
+	0x1b00, 0x1b4b,
+	0x1b50, 0x1b7c,
+	0x1b80, 0x1baa,
+	0x1bae, 0x1bb9,
+	0x1c00, 0x1c37,
+	0x1c3b, 0x1c49,
+	0x1c4d, 0x1c7f,
+	0x1cd0, 0x1cf2,
+	0x1d00, 0x1de6,
+	0x1dfd, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x2064,
+	0x206a, 0x2071,
+	0x2074, 0x208e,
+	0x2090, 0x2094,
+	0x20a0, 0x20b8,
+	0x20d0, 0x20f0,
+	0x2100, 0x2189,
+	0x2190, 0x23e8,
+	0x2400, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x26cd,
+	0x26cf, 0x26e1,
+	0x26e3, 0x26e3,
+	0x26e8, 0x26ff,
+	0x2701, 0x2704,
+	0x2706, 0x2709,
+	0x270c, 0x2727,
+	0x2729, 0x274b,
+	0x274d, 0x274d,
+	0x274f, 0x2752,
+	0x2756, 0x275e,
+	0x2761, 0x2794,
+	0x2798, 0x27af,
+	0x27b1, 0x27be,
+	0x27c0, 0x27ca,
+	0x27cc, 0x27cc,
+	0x27d0, 0x2b4c,
+	0x2b50, 0x2b59,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2cf1,
+	0x2cf9, 0x2d25,
+	0x2d30, 0x2d65,
+	0x2d6f, 0x2d6f,
+	0x2d80, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2de0, 0x2e31,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3000, 0x303f,
+	0x3041, 0x3096,
+	0x3099, 0x30ff,
+	0x3105, 0x312d,
+	0x3131, 0x318e,
+	0x3190, 0x31b7,
+	0x31c0, 0x31e3,
+	0x31f0, 0x321e,
+	0x3220, 0x32fe,
+	0x3300, 0x4db5,
+	0x4dc0, 0x9fcb,
+	0xa000, 0xa48c,
+	0xa490, 0xa4c6,
+	0xa4d0, 0xa62b,
+	0xa640, 0xa65f,
+	0xa662, 0xa673,
+	0xa67c, 0xa697,
+	0xa6a0, 0xa6f7,
+	0xa700, 0xa78c,
+	0xa7fb, 0xa82b,
+	0xa830, 0xa839,
+	0xa840, 0xa877,
+	0xa880, 0xa8c4,
+	0xa8ce, 0xa8d9,
+	0xa8e0, 0xa8fb,
+	0xa900, 0xa953,
+	0xa95f, 0xa97c,
+	0xa980, 0xa9cd,
+	0xa9cf, 0xa9d9,
+	0xa9de, 0xa9df,
+	0xaa00, 0xaa36,
+	0xaa40, 0xaa4d,
+	0xaa50, 0xaa59,
+	0xaa5c, 0xaa7b,
+	0xaa80, 0xaac2,
+	0xaadb, 0xaadf,
+	0xabc0, 0xabed,
+	0xabf0, 0xabf9,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xd800, 0xfa2d,
+	0xfa30, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbb1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdd0, 0xfdfd,
+	0xfe00, 0xfe19,
+	0xfe20, 0xfe26,
+	0xfe30, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfff9, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10100, 0x10102,
+	0x10107, 0x10133,
+	0x10137, 0x1018a,
+	0x10190, 0x1019b,
+	0x101d0, 0x101fd,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x10300, 0x1031e,
+	0x10320, 0x10323,
+	0x10330, 0x1034a,
+	0x10380, 0x1039d,
+	0x1039f, 0x103c3,
+	0x103c8, 0x103d5,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10857, 0x1085f,
+	0x10900, 0x1091b,
+	0x1091f, 0x10939,
+	0x1093f, 0x1093f,
+	0x10a00, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a47,
+	0x10a50, 0x10a58,
+	0x10a60, 0x10a7f,
+	0x10b00, 0x10b35,
+	0x10b39, 0x10b55,
+	0x10b58, 0x10b72,
+	0x10b78, 0x10b7f,
+	0x10c00, 0x10c48,
+	0x10e60, 0x10e7e,
+	0x11080, 0x110c1,
+	0x12000, 0x1236e,
+	0x12400, 0x12462,
+	0x12470, 0x12473,
+	0x13000, 0x1342e,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d129, 0x1d1dd,
+	0x1d200, 0x1d245,
+	0x1d300, 0x1d356,
+	0x1d360, 0x1d371,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d7cb,
+	0x1d7ce, 0x1d7ff,
+	0x1f000, 0x1f02b,
+	0x1f030, 0x1f093,
+	0x1f100, 0x1f10a,
+	0x1f110, 0x1f12e,
+	0x1f131, 0x1f131,
+	0x1f13d, 0x1f13d,
+	0x1f13f, 0x1f13f,
+	0x1f142, 0x1f142,
+	0x1f146, 0x1f146,
+	0x1f14a, 0x1f14e,
+	0x1f157, 0x1f157,
+	0x1f15f, 0x1f15f,
+	0x1f179, 0x1f179,
+	0x1f17b, 0x1f17c,
+	0x1f17f, 0x1f17f,
+	0x1f18a, 0x1f18d,
+	0x1f190, 0x1f190,
+	0x1f200, 0x1f200,
+	0x1f210, 0x1f231,
+	0x1f240, 0x1f248,
+	0x1fffe, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2f800, 0x2fa1d,
+	0x2fffe, 0x2ffff,
+	0x3fffe, 0x3ffff,
+	0x4fffe, 0x4ffff,
+	0x5fffe, 0x5ffff,
+	0x6fffe, 0x6ffff,
+	0x7fffe, 0x7ffff,
+	0x8fffe, 0x8ffff,
+	0x9fffe, 0x9ffff,
+	0xafffe, 0xaffff,
+	0xbfffe, 0xbffff,
+	0xcfffe, 0xcffff,
+	0xdfffe, 0xdffff,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+	0xe0100, 0xe01ef,
+	0xefffe, 0x10ffff,
+}; /* CR_Age_5_2 */
+
+/* 'Age_6_0': Derived Age 6.0 */
+static const OnigCodePoint CR_Age_6_0[] = {
+	511,
+	0x0000, 0x0377,
+	0x037a, 0x037e,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x0527,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x058a,
+	0x0591, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x0600, 0x0603,
+	0x0606, 0x061b,
+	0x061e, 0x070d,
+	0x070f, 0x074a,
+	0x074d, 0x07b1,
+	0x07c0, 0x07fa,
+	0x0800, 0x082d,
+	0x0830, 0x083e,
+	0x0840, 0x085b,
+	0x085e, 0x085e,
+	0x0900, 0x0977,
+	0x0979, 0x097f,
+	0x0981, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fb,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a75,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0aef,
+	0x0af1, 0x0af1,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3c, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b63,
+	0x0b66, 0x0b77,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd0, 0x0bd0,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bfa,
+	0x0c01, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c33,
+	0x0c35, 0x0c39,
+	0x0c3d, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c58, 0x0c59,
+	0x0c60, 0x0c63,
+	0x0c66, 0x0c6f,
+	0x0c78, 0x0c7f,
+	0x0c82, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbc, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce3,
+	0x0ce6, 0x0cef,
+	0x0cf1, 0x0cf2,
+	0x0d02, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d3a,
+	0x0d3d, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4e,
+	0x0d57, 0x0d57,
+	0x0d60, 0x0d63,
+	0x0d66, 0x0d75,
+	0x0d79, 0x0d7f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edd,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f71, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fbe, 0x0fcc,
+	0x0fce, 0x0fda,
+	0x1000, 0x10c5,
+	0x10d0, 0x10fc,
+	0x1100, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135d, 0x137c,
+	0x1380, 0x1399,
+	0x13a0, 0x13f4,
+	0x1400, 0x169c,
+	0x16a0, 0x16f0,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+	0x1720, 0x1736,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17dd,
+	0x17e0, 0x17e9,
+	0x17f0, 0x17f9,
+	0x1800, 0x180e,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191c,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1940, 0x1940,
+	0x1944, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19da,
+	0x19de, 0x1a1b,
+	0x1a1e, 0x1a5e,
+	0x1a60, 0x1a7c,
+	0x1a7f, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1aa0, 0x1aad,
+	0x1b00, 0x1b4b,
+	0x1b50, 0x1b7c,
+	0x1b80, 0x1baa,
+	0x1bae, 0x1bb9,
+	0x1bc0, 0x1bf3,
+	0x1bfc, 0x1c37,
+	0x1c3b, 0x1c49,
+	0x1c4d, 0x1c7f,
+	0x1cd0, 0x1cf2,
+	0x1d00, 0x1de6,
+	0x1dfc, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x2064,
+	0x206a, 0x2071,
+	0x2074, 0x208e,
+	0x2090, 0x209c,
+	0x20a0, 0x20b9,
+	0x20d0, 0x20f0,
+	0x2100, 0x2189,
+	0x2190, 0x23f3,
+	0x2400, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x26ff,
+	0x2701, 0x27ca,
+	0x27cc, 0x27cc,
+	0x27ce, 0x2b4c,
+	0x2b50, 0x2b59,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2cf1,
+	0x2cf9, 0x2d25,
+	0x2d30, 0x2d65,
+	0x2d6f, 0x2d70,
+	0x2d7f, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2de0, 0x2e31,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3000, 0x303f,
+	0x3041, 0x3096,
+	0x3099, 0x30ff,
+	0x3105, 0x312d,
+	0x3131, 0x318e,
+	0x3190, 0x31ba,
+	0x31c0, 0x31e3,
+	0x31f0, 0x321e,
+	0x3220, 0x32fe,
+	0x3300, 0x4db5,
+	0x4dc0, 0x9fcb,
+	0xa000, 0xa48c,
+	0xa490, 0xa4c6,
+	0xa4d0, 0xa62b,
+	0xa640, 0xa673,
+	0xa67c, 0xa697,
+	0xa6a0, 0xa6f7,
+	0xa700, 0xa78e,
+	0xa790, 0xa791,
+	0xa7a0, 0xa7a9,
+	0xa7fa, 0xa82b,
+	0xa830, 0xa839,
+	0xa840, 0xa877,
+	0xa880, 0xa8c4,
+	0xa8ce, 0xa8d9,
+	0xa8e0, 0xa8fb,
+	0xa900, 0xa953,
+	0xa95f, 0xa97c,
+	0xa980, 0xa9cd,
+	0xa9cf, 0xa9d9,
+	0xa9de, 0xa9df,
+	0xaa00, 0xaa36,
+	0xaa40, 0xaa4d,
+	0xaa50, 0xaa59,
+	0xaa5c, 0xaa7b,
+	0xaa80, 0xaac2,
+	0xaadb, 0xaadf,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xabc0, 0xabed,
+	0xabf0, 0xabf9,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xd800, 0xfa2d,
+	0xfa30, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbc1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdd0, 0xfdfd,
+	0xfe00, 0xfe19,
+	0xfe20, 0xfe26,
+	0xfe30, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfff9, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10100, 0x10102,
+	0x10107, 0x10133,
+	0x10137, 0x1018a,
+	0x10190, 0x1019b,
+	0x101d0, 0x101fd,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x10300, 0x1031e,
+	0x10320, 0x10323,
+	0x10330, 0x1034a,
+	0x10380, 0x1039d,
+	0x1039f, 0x103c3,
+	0x103c8, 0x103d5,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10857, 0x1085f,
+	0x10900, 0x1091b,
+	0x1091f, 0x10939,
+	0x1093f, 0x1093f,
+	0x10a00, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a47,
+	0x10a50, 0x10a58,
+	0x10a60, 0x10a7f,
+	0x10b00, 0x10b35,
+	0x10b39, 0x10b55,
+	0x10b58, 0x10b72,
+	0x10b78, 0x10b7f,
+	0x10c00, 0x10c48,
+	0x10e60, 0x10e7e,
+	0x11000, 0x1104d,
+	0x11052, 0x1106f,
+	0x11080, 0x110c1,
+	0x12000, 0x1236e,
+	0x12400, 0x12462,
+	0x12470, 0x12473,
+	0x13000, 0x1342e,
+	0x16800, 0x16a38,
+	0x1b000, 0x1b001,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d129, 0x1d1dd,
+	0x1d200, 0x1d245,
+	0x1d300, 0x1d356,
+	0x1d360, 0x1d371,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d7cb,
+	0x1d7ce, 0x1d7ff,
+	0x1f000, 0x1f02b,
+	0x1f030, 0x1f093,
+	0x1f0a0, 0x1f0ae,
+	0x1f0b1, 0x1f0be,
+	0x1f0c1, 0x1f0cf,
+	0x1f0d1, 0x1f0df,
+	0x1f100, 0x1f10a,
+	0x1f110, 0x1f12e,
+	0x1f130, 0x1f169,
+	0x1f170, 0x1f19a,
+	0x1f1e6, 0x1f202,
+	0x1f210, 0x1f23a,
+	0x1f240, 0x1f248,
+	0x1f250, 0x1f251,
+	0x1f300, 0x1f320,
+	0x1f330, 0x1f335,
+	0x1f337, 0x1f37c,
+	0x1f380, 0x1f393,
+	0x1f3a0, 0x1f3c4,
+	0x1f3c6, 0x1f3ca,
+	0x1f3e0, 0x1f3f0,
+	0x1f400, 0x1f43e,
+	0x1f440, 0x1f440,
+	0x1f442, 0x1f4f7,
+	0x1f4f9, 0x1f4fc,
+	0x1f500, 0x1f53d,
+	0x1f550, 0x1f567,
+	0x1f5fb, 0x1f5ff,
+	0x1f601, 0x1f610,
+	0x1f612, 0x1f614,
+	0x1f616, 0x1f616,
+	0x1f618, 0x1f618,
+	0x1f61a, 0x1f61a,
+	0x1f61c, 0x1f61e,
+	0x1f620, 0x1f625,
+	0x1f628, 0x1f62b,
+	0x1f62d, 0x1f62d,
+	0x1f630, 0x1f633,
+	0x1f635, 0x1f640,
+	0x1f645, 0x1f64f,
+	0x1f680, 0x1f6c5,
+	0x1f700, 0x1f773,
+	0x1fffe, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2f800, 0x2fa1d,
+	0x2fffe, 0x2ffff,
+	0x3fffe, 0x3ffff,
+	0x4fffe, 0x4ffff,
+	0x5fffe, 0x5ffff,
+	0x6fffe, 0x6ffff,
+	0x7fffe, 0x7ffff,
+	0x8fffe, 0x8ffff,
+	0x9fffe, 0x9ffff,
+	0xafffe, 0xaffff,
+	0xbfffe, 0xbffff,
+	0xcfffe, 0xcffff,
+	0xdfffe, 0xdffff,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+	0xe0100, 0xe01ef,
+	0xefffe, 0x10ffff,
+}; /* CR_Age_6_0 */
+
+/* 'Age_6_1': Derived Age 6.1 */
+static const OnigCodePoint CR_Age_6_1[] = {
+	549,
+	0x0000, 0x0377,
+	0x037a, 0x037e,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x0527,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x058a,
+	0x058f, 0x058f,
+	0x0591, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x0600, 0x0604,
+	0x0606, 0x061b,
+	0x061e, 0x070d,
+	0x070f, 0x074a,
+	0x074d, 0x07b1,
+	0x07c0, 0x07fa,
+	0x0800, 0x082d,
+	0x0830, 0x083e,
+	0x0840, 0x085b,
+	0x085e, 0x085e,
+	0x08a0, 0x08a0,
+	0x08a2, 0x08ac,
+	0x08e4, 0x08fe,
+	0x0900, 0x0977,
+	0x0979, 0x097f,
+	0x0981, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fb,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a75,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0af1,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3c, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b63,
+	0x0b66, 0x0b77,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd0, 0x0bd0,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bfa,
+	0x0c01, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c33,
+	0x0c35, 0x0c39,
+	0x0c3d, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c58, 0x0c59,
+	0x0c60, 0x0c63,
+	0x0c66, 0x0c6f,
+	0x0c78, 0x0c7f,
+	0x0c82, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbc, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce3,
+	0x0ce6, 0x0cef,
+	0x0cf1, 0x0cf2,
+	0x0d02, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d3a,
+	0x0d3d, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4e,
+	0x0d57, 0x0d57,
+	0x0d60, 0x0d63,
+	0x0d66, 0x0d75,
+	0x0d79, 0x0d7f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f71, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fbe, 0x0fcc,
+	0x0fce, 0x0fda,
+	0x1000, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135d, 0x137c,
+	0x1380, 0x1399,
+	0x13a0, 0x13f4,
+	0x1400, 0x169c,
+	0x16a0, 0x16f0,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+	0x1720, 0x1736,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17dd,
+	0x17e0, 0x17e9,
+	0x17f0, 0x17f9,
+	0x1800, 0x180e,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191c,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1940, 0x1940,
+	0x1944, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19da,
+	0x19de, 0x1a1b,
+	0x1a1e, 0x1a5e,
+	0x1a60, 0x1a7c,
+	0x1a7f, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1aa0, 0x1aad,
+	0x1b00, 0x1b4b,
+	0x1b50, 0x1b7c,
+	0x1b80, 0x1bf3,
+	0x1bfc, 0x1c37,
+	0x1c3b, 0x1c49,
+	0x1c4d, 0x1c7f,
+	0x1cc0, 0x1cc7,
+	0x1cd0, 0x1cf6,
+	0x1d00, 0x1de6,
+	0x1dfc, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x2064,
+	0x206a, 0x2071,
+	0x2074, 0x208e,
+	0x2090, 0x209c,
+	0x20a0, 0x20b9,
+	0x20d0, 0x20f0,
+	0x2100, 0x2189,
+	0x2190, 0x23f3,
+	0x2400, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x26ff,
+	0x2701, 0x2b4c,
+	0x2b50, 0x2b59,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2cf3,
+	0x2cf9, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d70,
+	0x2d7f, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2de0, 0x2e3b,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3000, 0x303f,
+	0x3041, 0x3096,
+	0x3099, 0x30ff,
+	0x3105, 0x312d,
+	0x3131, 0x318e,
+	0x3190, 0x31ba,
+	0x31c0, 0x31e3,
+	0x31f0, 0x321e,
+	0x3220, 0x32fe,
+	0x3300, 0x4db5,
+	0x4dc0, 0x9fcc,
+	0xa000, 0xa48c,
+	0xa490, 0xa4c6,
+	0xa4d0, 0xa62b,
+	0xa640, 0xa697,
+	0xa69f, 0xa6f7,
+	0xa700, 0xa78e,
+	0xa790, 0xa793,
+	0xa7a0, 0xa7aa,
+	0xa7f8, 0xa82b,
+	0xa830, 0xa839,
+	0xa840, 0xa877,
+	0xa880, 0xa8c4,
+	0xa8ce, 0xa8d9,
+	0xa8e0, 0xa8fb,
+	0xa900, 0xa953,
+	0xa95f, 0xa97c,
+	0xa980, 0xa9cd,
+	0xa9cf, 0xa9d9,
+	0xa9de, 0xa9df,
+	0xaa00, 0xaa36,
+	0xaa40, 0xaa4d,
+	0xaa50, 0xaa59,
+	0xaa5c, 0xaa7b,
+	0xaa80, 0xaac2,
+	0xaadb, 0xaaf6,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xabc0, 0xabed,
+	0xabf0, 0xabf9,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xd800, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbc1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdd0, 0xfdfd,
+	0xfe00, 0xfe19,
+	0xfe20, 0xfe26,
+	0xfe30, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfff9, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10100, 0x10102,
+	0x10107, 0x10133,
+	0x10137, 0x1018a,
+	0x10190, 0x1019b,
+	0x101d0, 0x101fd,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x10300, 0x1031e,
+	0x10320, 0x10323,
+	0x10330, 0x1034a,
+	0x10380, 0x1039d,
+	0x1039f, 0x103c3,
+	0x103c8, 0x103d5,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10857, 0x1085f,
+	0x10900, 0x1091b,
+	0x1091f, 0x10939,
+	0x1093f, 0x1093f,
+	0x10980, 0x109b7,
+	0x109be, 0x109bf,
+	0x10a00, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a47,
+	0x10a50, 0x10a58,
+	0x10a60, 0x10a7f,
+	0x10b00, 0x10b35,
+	0x10b39, 0x10b55,
+	0x10b58, 0x10b72,
+	0x10b78, 0x10b7f,
+	0x10c00, 0x10c48,
+	0x10e60, 0x10e7e,
+	0x11000, 0x1104d,
+	0x11052, 0x1106f,
+	0x11080, 0x110c1,
+	0x110d0, 0x110e8,
+	0x110f0, 0x110f9,
+	0x11100, 0x11134,
+	0x11136, 0x11143,
+	0x11180, 0x111c8,
+	0x111d0, 0x111d9,
+	0x11680, 0x116b7,
+	0x116c0, 0x116c9,
+	0x12000, 0x1236e,
+	0x12400, 0x12462,
+	0x12470, 0x12473,
+	0x13000, 0x1342e,
+	0x16800, 0x16a38,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f7e,
+	0x16f8f, 0x16f9f,
+	0x1b000, 0x1b001,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d129, 0x1d1dd,
+	0x1d200, 0x1d245,
+	0x1d300, 0x1d356,
+	0x1d360, 0x1d371,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d7cb,
+	0x1d7ce, 0x1d7ff,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x1eef0, 0x1eef1,
+	0x1f000, 0x1f02b,
+	0x1f030, 0x1f093,
+	0x1f0a0, 0x1f0ae,
+	0x1f0b1, 0x1f0be,
+	0x1f0c1, 0x1f0cf,
+	0x1f0d1, 0x1f0df,
+	0x1f100, 0x1f10a,
+	0x1f110, 0x1f12e,
+	0x1f130, 0x1f16b,
+	0x1f170, 0x1f19a,
+	0x1f1e6, 0x1f202,
+	0x1f210, 0x1f23a,
+	0x1f240, 0x1f248,
+	0x1f250, 0x1f251,
+	0x1f300, 0x1f320,
+	0x1f330, 0x1f335,
+	0x1f337, 0x1f37c,
+	0x1f380, 0x1f393,
+	0x1f3a0, 0x1f3c4,
+	0x1f3c6, 0x1f3ca,
+	0x1f3e0, 0x1f3f0,
+	0x1f400, 0x1f43e,
+	0x1f440, 0x1f440,
+	0x1f442, 0x1f4f7,
+	0x1f4f9, 0x1f4fc,
+	0x1f500, 0x1f53d,
+	0x1f540, 0x1f543,
+	0x1f550, 0x1f567,
+	0x1f5fb, 0x1f640,
+	0x1f645, 0x1f64f,
+	0x1f680, 0x1f6c5,
+	0x1f700, 0x1f773,
+	0x1fffe, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2f800, 0x2fa1d,
+	0x2fffe, 0x2ffff,
+	0x3fffe, 0x3ffff,
+	0x4fffe, 0x4ffff,
+	0x5fffe, 0x5ffff,
+	0x6fffe, 0x6ffff,
+	0x7fffe, 0x7ffff,
+	0x8fffe, 0x8ffff,
+	0x9fffe, 0x9ffff,
+	0xafffe, 0xaffff,
+	0xbfffe, 0xbffff,
+	0xcfffe, 0xcffff,
+	0xdfffe, 0xdffff,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+	0xe0100, 0xe01ef,
+	0xefffe, 0x10ffff,
+}; /* CR_Age_6_1 */
+
+/* 'Age_6_2': Derived Age 6.2 */
+static const OnigCodePoint CR_Age_6_2[] = {
+	549,
+	0x0000, 0x0377,
+	0x037a, 0x037e,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x0527,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x058a,
+	0x058f, 0x058f,
+	0x0591, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x0600, 0x0604,
+	0x0606, 0x061b,
+	0x061e, 0x070d,
+	0x070f, 0x074a,
+	0x074d, 0x07b1,
+	0x07c0, 0x07fa,
+	0x0800, 0x082d,
+	0x0830, 0x083e,
+	0x0840, 0x085b,
+	0x085e, 0x085e,
+	0x08a0, 0x08a0,
+	0x08a2, 0x08ac,
+	0x08e4, 0x08fe,
+	0x0900, 0x0977,
+	0x0979, 0x097f,
+	0x0981, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fb,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a75,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0af1,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3c, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b63,
+	0x0b66, 0x0b77,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd0, 0x0bd0,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bfa,
+	0x0c01, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c33,
+	0x0c35, 0x0c39,
+	0x0c3d, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c58, 0x0c59,
+	0x0c60, 0x0c63,
+	0x0c66, 0x0c6f,
+	0x0c78, 0x0c7f,
+	0x0c82, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbc, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce3,
+	0x0ce6, 0x0cef,
+	0x0cf1, 0x0cf2,
+	0x0d02, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d3a,
+	0x0d3d, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4e,
+	0x0d57, 0x0d57,
+	0x0d60, 0x0d63,
+	0x0d66, 0x0d75,
+	0x0d79, 0x0d7f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f71, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fbe, 0x0fcc,
+	0x0fce, 0x0fda,
+	0x1000, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135d, 0x137c,
+	0x1380, 0x1399,
+	0x13a0, 0x13f4,
+	0x1400, 0x169c,
+	0x16a0, 0x16f0,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+	0x1720, 0x1736,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17dd,
+	0x17e0, 0x17e9,
+	0x17f0, 0x17f9,
+	0x1800, 0x180e,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191c,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1940, 0x1940,
+	0x1944, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19da,
+	0x19de, 0x1a1b,
+	0x1a1e, 0x1a5e,
+	0x1a60, 0x1a7c,
+	0x1a7f, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1aa0, 0x1aad,
+	0x1b00, 0x1b4b,
+	0x1b50, 0x1b7c,
+	0x1b80, 0x1bf3,
+	0x1bfc, 0x1c37,
+	0x1c3b, 0x1c49,
+	0x1c4d, 0x1c7f,
+	0x1cc0, 0x1cc7,
+	0x1cd0, 0x1cf6,
+	0x1d00, 0x1de6,
+	0x1dfc, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x2064,
+	0x206a, 0x2071,
+	0x2074, 0x208e,
+	0x2090, 0x209c,
+	0x20a0, 0x20ba,
+	0x20d0, 0x20f0,
+	0x2100, 0x2189,
+	0x2190, 0x23f3,
+	0x2400, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x26ff,
+	0x2701, 0x2b4c,
+	0x2b50, 0x2b59,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2cf3,
+	0x2cf9, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d70,
+	0x2d7f, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2de0, 0x2e3b,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3000, 0x303f,
+	0x3041, 0x3096,
+	0x3099, 0x30ff,
+	0x3105, 0x312d,
+	0x3131, 0x318e,
+	0x3190, 0x31ba,
+	0x31c0, 0x31e3,
+	0x31f0, 0x321e,
+	0x3220, 0x32fe,
+	0x3300, 0x4db5,
+	0x4dc0, 0x9fcc,
+	0xa000, 0xa48c,
+	0xa490, 0xa4c6,
+	0xa4d0, 0xa62b,
+	0xa640, 0xa697,
+	0xa69f, 0xa6f7,
+	0xa700, 0xa78e,
+	0xa790, 0xa793,
+	0xa7a0, 0xa7aa,
+	0xa7f8, 0xa82b,
+	0xa830, 0xa839,
+	0xa840, 0xa877,
+	0xa880, 0xa8c4,
+	0xa8ce, 0xa8d9,
+	0xa8e0, 0xa8fb,
+	0xa900, 0xa953,
+	0xa95f, 0xa97c,
+	0xa980, 0xa9cd,
+	0xa9cf, 0xa9d9,
+	0xa9de, 0xa9df,
+	0xaa00, 0xaa36,
+	0xaa40, 0xaa4d,
+	0xaa50, 0xaa59,
+	0xaa5c, 0xaa7b,
+	0xaa80, 0xaac2,
+	0xaadb, 0xaaf6,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xabc0, 0xabed,
+	0xabf0, 0xabf9,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xd800, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbc1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdd0, 0xfdfd,
+	0xfe00, 0xfe19,
+	0xfe20, 0xfe26,
+	0xfe30, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfff9, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10100, 0x10102,
+	0x10107, 0x10133,
+	0x10137, 0x1018a,
+	0x10190, 0x1019b,
+	0x101d0, 0x101fd,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x10300, 0x1031e,
+	0x10320, 0x10323,
+	0x10330, 0x1034a,
+	0x10380, 0x1039d,
+	0x1039f, 0x103c3,
+	0x103c8, 0x103d5,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10857, 0x1085f,
+	0x10900, 0x1091b,
+	0x1091f, 0x10939,
+	0x1093f, 0x1093f,
+	0x10980, 0x109b7,
+	0x109be, 0x109bf,
+	0x10a00, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a47,
+	0x10a50, 0x10a58,
+	0x10a60, 0x10a7f,
+	0x10b00, 0x10b35,
+	0x10b39, 0x10b55,
+	0x10b58, 0x10b72,
+	0x10b78, 0x10b7f,
+	0x10c00, 0x10c48,
+	0x10e60, 0x10e7e,
+	0x11000, 0x1104d,
+	0x11052, 0x1106f,
+	0x11080, 0x110c1,
+	0x110d0, 0x110e8,
+	0x110f0, 0x110f9,
+	0x11100, 0x11134,
+	0x11136, 0x11143,
+	0x11180, 0x111c8,
+	0x111d0, 0x111d9,
+	0x11680, 0x116b7,
+	0x116c0, 0x116c9,
+	0x12000, 0x1236e,
+	0x12400, 0x12462,
+	0x12470, 0x12473,
+	0x13000, 0x1342e,
+	0x16800, 0x16a38,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f7e,
+	0x16f8f, 0x16f9f,
+	0x1b000, 0x1b001,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d129, 0x1d1dd,
+	0x1d200, 0x1d245,
+	0x1d300, 0x1d356,
+	0x1d360, 0x1d371,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d7cb,
+	0x1d7ce, 0x1d7ff,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x1eef0, 0x1eef1,
+	0x1f000, 0x1f02b,
+	0x1f030, 0x1f093,
+	0x1f0a0, 0x1f0ae,
+	0x1f0b1, 0x1f0be,
+	0x1f0c1, 0x1f0cf,
+	0x1f0d1, 0x1f0df,
+	0x1f100, 0x1f10a,
+	0x1f110, 0x1f12e,
+	0x1f130, 0x1f16b,
+	0x1f170, 0x1f19a,
+	0x1f1e6, 0x1f202,
+	0x1f210, 0x1f23a,
+	0x1f240, 0x1f248,
+	0x1f250, 0x1f251,
+	0x1f300, 0x1f320,
+	0x1f330, 0x1f335,
+	0x1f337, 0x1f37c,
+	0x1f380, 0x1f393,
+	0x1f3a0, 0x1f3c4,
+	0x1f3c6, 0x1f3ca,
+	0x1f3e0, 0x1f3f0,
+	0x1f400, 0x1f43e,
+	0x1f440, 0x1f440,
+	0x1f442, 0x1f4f7,
+	0x1f4f9, 0x1f4fc,
+	0x1f500, 0x1f53d,
+	0x1f540, 0x1f543,
+	0x1f550, 0x1f567,
+	0x1f5fb, 0x1f640,
+	0x1f645, 0x1f64f,
+	0x1f680, 0x1f6c5,
+	0x1f700, 0x1f773,
+	0x1fffe, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2f800, 0x2fa1d,
+	0x2fffe, 0x2ffff,
+	0x3fffe, 0x3ffff,
+	0x4fffe, 0x4ffff,
+	0x5fffe, 0x5ffff,
+	0x6fffe, 0x6ffff,
+	0x7fffe, 0x7ffff,
+	0x8fffe, 0x8ffff,
+	0x9fffe, 0x9ffff,
+	0xafffe, 0xaffff,
+	0xbfffe, 0xbffff,
+	0xcfffe, 0xcffff,
+	0xdfffe, 0xdffff,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+	0xe0100, 0xe01ef,
+	0xefffe, 0x10ffff,
+}; /* CR_Age_6_2 */
+
+/* 'Age_6_3': Derived Age 6.3 */
+static const OnigCodePoint CR_Age_6_3[] = {
+	549,
+	0x0000, 0x0377,
+	0x037a, 0x037e,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x0527,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x058a,
+	0x058f, 0x058f,
+	0x0591, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x0600, 0x0604,
+	0x0606, 0x061c,
+	0x061e, 0x070d,
+	0x070f, 0x074a,
+	0x074d, 0x07b1,
+	0x07c0, 0x07fa,
+	0x0800, 0x082d,
+	0x0830, 0x083e,
+	0x0840, 0x085b,
+	0x085e, 0x085e,
+	0x08a0, 0x08a0,
+	0x08a2, 0x08ac,
+	0x08e4, 0x08fe,
+	0x0900, 0x0977,
+	0x0979, 0x097f,
+	0x0981, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fb,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a75,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0af1,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3c, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b63,
+	0x0b66, 0x0b77,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd0, 0x0bd0,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bfa,
+	0x0c01, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c33,
+	0x0c35, 0x0c39,
+	0x0c3d, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c58, 0x0c59,
+	0x0c60, 0x0c63,
+	0x0c66, 0x0c6f,
+	0x0c78, 0x0c7f,
+	0x0c82, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbc, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce3,
+	0x0ce6, 0x0cef,
+	0x0cf1, 0x0cf2,
+	0x0d02, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d3a,
+	0x0d3d, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4e,
+	0x0d57, 0x0d57,
+	0x0d60, 0x0d63,
+	0x0d66, 0x0d75,
+	0x0d79, 0x0d7f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f71, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fbe, 0x0fcc,
+	0x0fce, 0x0fda,
+	0x1000, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135d, 0x137c,
+	0x1380, 0x1399,
+	0x13a0, 0x13f4,
+	0x1400, 0x169c,
+	0x16a0, 0x16f0,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+	0x1720, 0x1736,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17dd,
+	0x17e0, 0x17e9,
+	0x17f0, 0x17f9,
+	0x1800, 0x180e,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191c,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1940, 0x1940,
+	0x1944, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19da,
+	0x19de, 0x1a1b,
+	0x1a1e, 0x1a5e,
+	0x1a60, 0x1a7c,
+	0x1a7f, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1aa0, 0x1aad,
+	0x1b00, 0x1b4b,
+	0x1b50, 0x1b7c,
+	0x1b80, 0x1bf3,
+	0x1bfc, 0x1c37,
+	0x1c3b, 0x1c49,
+	0x1c4d, 0x1c7f,
+	0x1cc0, 0x1cc7,
+	0x1cd0, 0x1cf6,
+	0x1d00, 0x1de6,
+	0x1dfc, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x2064,
+	0x2066, 0x2071,
+	0x2074, 0x208e,
+	0x2090, 0x209c,
+	0x20a0, 0x20ba,
+	0x20d0, 0x20f0,
+	0x2100, 0x2189,
+	0x2190, 0x23f3,
+	0x2400, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x26ff,
+	0x2701, 0x2b4c,
+	0x2b50, 0x2b59,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2cf3,
+	0x2cf9, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d70,
+	0x2d7f, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2de0, 0x2e3b,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3000, 0x303f,
+	0x3041, 0x3096,
+	0x3099, 0x30ff,
+	0x3105, 0x312d,
+	0x3131, 0x318e,
+	0x3190, 0x31ba,
+	0x31c0, 0x31e3,
+	0x31f0, 0x321e,
+	0x3220, 0x32fe,
+	0x3300, 0x4db5,
+	0x4dc0, 0x9fcc,
+	0xa000, 0xa48c,
+	0xa490, 0xa4c6,
+	0xa4d0, 0xa62b,
+	0xa640, 0xa697,
+	0xa69f, 0xa6f7,
+	0xa700, 0xa78e,
+	0xa790, 0xa793,
+	0xa7a0, 0xa7aa,
+	0xa7f8, 0xa82b,
+	0xa830, 0xa839,
+	0xa840, 0xa877,
+	0xa880, 0xa8c4,
+	0xa8ce, 0xa8d9,
+	0xa8e0, 0xa8fb,
+	0xa900, 0xa953,
+	0xa95f, 0xa97c,
+	0xa980, 0xa9cd,
+	0xa9cf, 0xa9d9,
+	0xa9de, 0xa9df,
+	0xaa00, 0xaa36,
+	0xaa40, 0xaa4d,
+	0xaa50, 0xaa59,
+	0xaa5c, 0xaa7b,
+	0xaa80, 0xaac2,
+	0xaadb, 0xaaf6,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xabc0, 0xabed,
+	0xabf0, 0xabf9,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xd800, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbc1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdd0, 0xfdfd,
+	0xfe00, 0xfe19,
+	0xfe20, 0xfe26,
+	0xfe30, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfff9, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10100, 0x10102,
+	0x10107, 0x10133,
+	0x10137, 0x1018a,
+	0x10190, 0x1019b,
+	0x101d0, 0x101fd,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x10300, 0x1031e,
+	0x10320, 0x10323,
+	0x10330, 0x1034a,
+	0x10380, 0x1039d,
+	0x1039f, 0x103c3,
+	0x103c8, 0x103d5,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10857, 0x1085f,
+	0x10900, 0x1091b,
+	0x1091f, 0x10939,
+	0x1093f, 0x1093f,
+	0x10980, 0x109b7,
+	0x109be, 0x109bf,
+	0x10a00, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a47,
+	0x10a50, 0x10a58,
+	0x10a60, 0x10a7f,
+	0x10b00, 0x10b35,
+	0x10b39, 0x10b55,
+	0x10b58, 0x10b72,
+	0x10b78, 0x10b7f,
+	0x10c00, 0x10c48,
+	0x10e60, 0x10e7e,
+	0x11000, 0x1104d,
+	0x11052, 0x1106f,
+	0x11080, 0x110c1,
+	0x110d0, 0x110e8,
+	0x110f0, 0x110f9,
+	0x11100, 0x11134,
+	0x11136, 0x11143,
+	0x11180, 0x111c8,
+	0x111d0, 0x111d9,
+	0x11680, 0x116b7,
+	0x116c0, 0x116c9,
+	0x12000, 0x1236e,
+	0x12400, 0x12462,
+	0x12470, 0x12473,
+	0x13000, 0x1342e,
+	0x16800, 0x16a38,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f7e,
+	0x16f8f, 0x16f9f,
+	0x1b000, 0x1b001,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d129, 0x1d1dd,
+	0x1d200, 0x1d245,
+	0x1d300, 0x1d356,
+	0x1d360, 0x1d371,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d7cb,
+	0x1d7ce, 0x1d7ff,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x1eef0, 0x1eef1,
+	0x1f000, 0x1f02b,
+	0x1f030, 0x1f093,
+	0x1f0a0, 0x1f0ae,
+	0x1f0b1, 0x1f0be,
+	0x1f0c1, 0x1f0cf,
+	0x1f0d1, 0x1f0df,
+	0x1f100, 0x1f10a,
+	0x1f110, 0x1f12e,
+	0x1f130, 0x1f16b,
+	0x1f170, 0x1f19a,
+	0x1f1e6, 0x1f202,
+	0x1f210, 0x1f23a,
+	0x1f240, 0x1f248,
+	0x1f250, 0x1f251,
+	0x1f300, 0x1f320,
+	0x1f330, 0x1f335,
+	0x1f337, 0x1f37c,
+	0x1f380, 0x1f393,
+	0x1f3a0, 0x1f3c4,
+	0x1f3c6, 0x1f3ca,
+	0x1f3e0, 0x1f3f0,
+	0x1f400, 0x1f43e,
+	0x1f440, 0x1f440,
+	0x1f442, 0x1f4f7,
+	0x1f4f9, 0x1f4fc,
+	0x1f500, 0x1f53d,
+	0x1f540, 0x1f543,
+	0x1f550, 0x1f567,
+	0x1f5fb, 0x1f640,
+	0x1f645, 0x1f64f,
+	0x1f680, 0x1f6c5,
+	0x1f700, 0x1f773,
+	0x1fffe, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2f800, 0x2fa1d,
+	0x2fffe, 0x2ffff,
+	0x3fffe, 0x3ffff,
+	0x4fffe, 0x4ffff,
+	0x5fffe, 0x5ffff,
+	0x6fffe, 0x6ffff,
+	0x7fffe, 0x7ffff,
+	0x8fffe, 0x8ffff,
+	0x9fffe, 0x9ffff,
+	0xafffe, 0xaffff,
+	0xbfffe, 0xbffff,
+	0xcfffe, 0xcffff,
+	0xdfffe, 0xdffff,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+	0xe0100, 0xe01ef,
+	0xefffe, 0x10ffff,
+}; /* CR_Age_6_3 */
+
+/* 'Age_7_0': Derived Age 7.0 */
+static const OnigCodePoint CR_Age_7_0[] = {
+	610,
+	0x0000, 0x0377,
+	0x037a, 0x037f,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x052f,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x058a,
+	0x058d, 0x058f,
+	0x0591, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x0600, 0x061c,
+	0x061e, 0x070d,
+	0x070f, 0x074a,
+	0x074d, 0x07b1,
+	0x07c0, 0x07fa,
+	0x0800, 0x082d,
+	0x0830, 0x083e,
+	0x0840, 0x085b,
+	0x085e, 0x085e,
+	0x08a0, 0x08b2,
+	0x08e4, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fb,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a75,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0af1,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3c, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b63,
+	0x0b66, 0x0b77,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd0, 0x0bd0,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bfa,
+	0x0c00, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c39,
+	0x0c3d, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c58, 0x0c59,
+	0x0c60, 0x0c63,
+	0x0c66, 0x0c6f,
+	0x0c78, 0x0c7f,
+	0x0c81, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbc, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce3,
+	0x0ce6, 0x0cef,
+	0x0cf1, 0x0cf2,
+	0x0d01, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d3a,
+	0x0d3d, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4e,
+	0x0d57, 0x0d57,
+	0x0d60, 0x0d63,
+	0x0d66, 0x0d75,
+	0x0d79, 0x0d7f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0de6, 0x0def,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f71, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fbe, 0x0fcc,
+	0x0fce, 0x0fda,
+	0x1000, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135d, 0x137c,
+	0x1380, 0x1399,
+	0x13a0, 0x13f4,
+	0x1400, 0x169c,
+	0x16a0, 0x16f8,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+	0x1720, 0x1736,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17dd,
+	0x17e0, 0x17e9,
+	0x17f0, 0x17f9,
+	0x1800, 0x180e,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191e,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1940, 0x1940,
+	0x1944, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19da,
+	0x19de, 0x1a1b,
+	0x1a1e, 0x1a5e,
+	0x1a60, 0x1a7c,
+	0x1a7f, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1aa0, 0x1aad,
+	0x1ab0, 0x1abe,
+	0x1b00, 0x1b4b,
+	0x1b50, 0x1b7c,
+	0x1b80, 0x1bf3,
+	0x1bfc, 0x1c37,
+	0x1c3b, 0x1c49,
+	0x1c4d, 0x1c7f,
+	0x1cc0, 0x1cc7,
+	0x1cd0, 0x1cf6,
+	0x1cf8, 0x1cf9,
+	0x1d00, 0x1df5,
+	0x1dfc, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x2064,
+	0x2066, 0x2071,
+	0x2074, 0x208e,
+	0x2090, 0x209c,
+	0x20a0, 0x20bd,
+	0x20d0, 0x20f0,
+	0x2100, 0x2189,
+	0x2190, 0x23fa,
+	0x2400, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x2b73,
+	0x2b76, 0x2b95,
+	0x2b98, 0x2bb9,
+	0x2bbd, 0x2bc8,
+	0x2bca, 0x2bd1,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2cf3,
+	0x2cf9, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d70,
+	0x2d7f, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2de0, 0x2e42,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3000, 0x303f,
+	0x3041, 0x3096,
+	0x3099, 0x30ff,
+	0x3105, 0x312d,
+	0x3131, 0x318e,
+	0x3190, 0x31ba,
+	0x31c0, 0x31e3,
+	0x31f0, 0x321e,
+	0x3220, 0x32fe,
+	0x3300, 0x4db5,
+	0x4dc0, 0x9fcc,
+	0xa000, 0xa48c,
+	0xa490, 0xa4c6,
+	0xa4d0, 0xa62b,
+	0xa640, 0xa69d,
+	0xa69f, 0xa6f7,
+	0xa700, 0xa78e,
+	0xa790, 0xa7ad,
+	0xa7b0, 0xa7b1,
+	0xa7f7, 0xa82b,
+	0xa830, 0xa839,
+	0xa840, 0xa877,
+	0xa880, 0xa8c4,
+	0xa8ce, 0xa8d9,
+	0xa8e0, 0xa8fb,
+	0xa900, 0xa953,
+	0xa95f, 0xa97c,
+	0xa980, 0xa9cd,
+	0xa9cf, 0xa9d9,
+	0xa9de, 0xa9fe,
+	0xaa00, 0xaa36,
+	0xaa40, 0xaa4d,
+	0xaa50, 0xaa59,
+	0xaa5c, 0xaac2,
+	0xaadb, 0xaaf6,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xab30, 0xab5f,
+	0xab64, 0xab65,
+	0xabc0, 0xabed,
+	0xabf0, 0xabf9,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xd800, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbc1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdd0, 0xfdfd,
+	0xfe00, 0xfe19,
+	0xfe20, 0xfe2d,
+	0xfe30, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfff9, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10100, 0x10102,
+	0x10107, 0x10133,
+	0x10137, 0x1018c,
+	0x10190, 0x1019b,
+	0x101a0, 0x101a0,
+	0x101d0, 0x101fd,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x102e0, 0x102fb,
+	0x10300, 0x10323,
+	0x10330, 0x1034a,
+	0x10350, 0x1037a,
+	0x10380, 0x1039d,
+	0x1039f, 0x103c3,
+	0x103c8, 0x103d5,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x10500, 0x10527,
+	0x10530, 0x10563,
+	0x1056f, 0x1056f,
+	0x10600, 0x10736,
+	0x10740, 0x10755,
+	0x10760, 0x10767,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10857, 0x1089e,
+	0x108a7, 0x108af,
+	0x10900, 0x1091b,
+	0x1091f, 0x10939,
+	0x1093f, 0x1093f,
+	0x10980, 0x109b7,
+	0x109be, 0x109bf,
+	0x10a00, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a47,
+	0x10a50, 0x10a58,
+	0x10a60, 0x10a9f,
+	0x10ac0, 0x10ae6,
+	0x10aeb, 0x10af6,
+	0x10b00, 0x10b35,
+	0x10b39, 0x10b55,
+	0x10b58, 0x10b72,
+	0x10b78, 0x10b91,
+	0x10b99, 0x10b9c,
+	0x10ba9, 0x10baf,
+	0x10c00, 0x10c48,
+	0x10e60, 0x10e7e,
+	0x11000, 0x1104d,
+	0x11052, 0x1106f,
+	0x1107f, 0x110c1,
+	0x110d0, 0x110e8,
+	0x110f0, 0x110f9,
+	0x11100, 0x11134,
+	0x11136, 0x11143,
+	0x11150, 0x11176,
+	0x11180, 0x111c8,
+	0x111cd, 0x111cd,
+	0x111d0, 0x111da,
+	0x111e1, 0x111f4,
+	0x11200, 0x11211,
+	0x11213, 0x1123d,
+	0x112b0, 0x112ea,
+	0x112f0, 0x112f9,
+	0x11301, 0x11303,
+	0x11305, 0x1130c,
+	0x1130f, 0x11310,
+	0x11313, 0x11328,
+	0x1132a, 0x11330,
+	0x11332, 0x11333,
+	0x11335, 0x11339,
+	0x1133c, 0x11344,
+	0x11347, 0x11348,
+	0x1134b, 0x1134d,
+	0x11357, 0x11357,
+	0x1135d, 0x11363,
+	0x11366, 0x1136c,
+	0x11370, 0x11374,
+	0x11480, 0x114c7,
+	0x114d0, 0x114d9,
+	0x11580, 0x115b5,
+	0x115b8, 0x115c9,
+	0x11600, 0x11644,
+	0x11650, 0x11659,
+	0x11680, 0x116b7,
+	0x116c0, 0x116c9,
+	0x118a0, 0x118f2,
+	0x118ff, 0x118ff,
+	0x11ac0, 0x11af8,
+	0x12000, 0x12398,
+	0x12400, 0x1246e,
+	0x12470, 0x12474,
+	0x13000, 0x1342e,
+	0x16800, 0x16a38,
+	0x16a40, 0x16a5e,
+	0x16a60, 0x16a69,
+	0x16a6e, 0x16a6f,
+	0x16ad0, 0x16aed,
+	0x16af0, 0x16af5,
+	0x16b00, 0x16b45,
+	0x16b50, 0x16b59,
+	0x16b5b, 0x16b61,
+	0x16b63, 0x16b77,
+	0x16b7d, 0x16b8f,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f7e,
+	0x16f8f, 0x16f9f,
+	0x1b000, 0x1b001,
+	0x1bc00, 0x1bc6a,
+	0x1bc70, 0x1bc7c,
+	0x1bc80, 0x1bc88,
+	0x1bc90, 0x1bc99,
+	0x1bc9c, 0x1bca3,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d129, 0x1d1dd,
+	0x1d200, 0x1d245,
+	0x1d300, 0x1d356,
+	0x1d360, 0x1d371,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d7cb,
+	0x1d7ce, 0x1d7ff,
+	0x1e800, 0x1e8c4,
+	0x1e8c7, 0x1e8d6,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x1eef0, 0x1eef1,
+	0x1f000, 0x1f02b,
+	0x1f030, 0x1f093,
+	0x1f0a0, 0x1f0ae,
+	0x1f0b1, 0x1f0bf,
+	0x1f0c1, 0x1f0cf,
+	0x1f0d1, 0x1f0f5,
+	0x1f100, 0x1f10c,
+	0x1f110, 0x1f12e,
+	0x1f130, 0x1f16b,
+	0x1f170, 0x1f19a,
+	0x1f1e6, 0x1f202,
+	0x1f210, 0x1f23a,
+	0x1f240, 0x1f248,
+	0x1f250, 0x1f251,
+	0x1f300, 0x1f32c,
+	0x1f330, 0x1f37d,
+	0x1f380, 0x1f3ce,
+	0x1f3d4, 0x1f3f7,
+	0x1f400, 0x1f4fe,
+	0x1f500, 0x1f54a,
+	0x1f550, 0x1f579,
+	0x1f57b, 0x1f5a3,
+	0x1f5a5, 0x1f642,
+	0x1f645, 0x1f6cf,
+	0x1f6e0, 0x1f6ec,
+	0x1f6f0, 0x1f6f3,
+	0x1f700, 0x1f773,
+	0x1f780, 0x1f7d4,
+	0x1f800, 0x1f80b,
+	0x1f810, 0x1f847,
+	0x1f850, 0x1f859,
+	0x1f860, 0x1f887,
+	0x1f890, 0x1f8ad,
+	0x1fffe, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2f800, 0x2fa1d,
+	0x2fffe, 0x2ffff,
+	0x3fffe, 0x3ffff,
+	0x4fffe, 0x4ffff,
+	0x5fffe, 0x5ffff,
+	0x6fffe, 0x6ffff,
+	0x7fffe, 0x7ffff,
+	0x8fffe, 0x8ffff,
+	0x9fffe, 0x9ffff,
+	0xafffe, 0xaffff,
+	0xbfffe, 0xbffff,
+	0xcfffe, 0xcffff,
+	0xdfffe, 0xdffff,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+	0xe0100, 0xe01ef,
+	0xefffe, 0x10ffff,
+}; /* CR_Age_7_0 */
+
+/* 'Age_8_0': Derived Age 8.0 */
+static const OnigCodePoint CR_Age_8_0[] = {
+	623,
+	0x0000, 0x0377,
+	0x037a, 0x037f,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x052f,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x058a,
+	0x058d, 0x058f,
+	0x0591, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x0600, 0x061c,
+	0x061e, 0x070d,
+	0x070f, 0x074a,
+	0x074d, 0x07b1,
+	0x07c0, 0x07fa,
+	0x0800, 0x082d,
+	0x0830, 0x083e,
+	0x0840, 0x085b,
+	0x085e, 0x085e,
+	0x08a0, 0x08b4,
+	0x08e3, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fb,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a75,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0af1,
+	0x0af9, 0x0af9,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3c, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b63,
+	0x0b66, 0x0b77,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd0, 0x0bd0,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bfa,
+	0x0c00, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c39,
+	0x0c3d, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c58, 0x0c5a,
+	0x0c60, 0x0c63,
+	0x0c66, 0x0c6f,
+	0x0c78, 0x0c7f,
+	0x0c81, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbc, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce3,
+	0x0ce6, 0x0cef,
+	0x0cf1, 0x0cf2,
+	0x0d01, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d3a,
+	0x0d3d, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4e,
+	0x0d57, 0x0d57,
+	0x0d5f, 0x0d63,
+	0x0d66, 0x0d75,
+	0x0d79, 0x0d7f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0de6, 0x0def,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f71, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fbe, 0x0fcc,
+	0x0fce, 0x0fda,
+	0x1000, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135d, 0x137c,
+	0x1380, 0x1399,
+	0x13a0, 0x13f5,
+	0x13f8, 0x13fd,
+	0x1400, 0x169c,
+	0x16a0, 0x16f8,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+	0x1720, 0x1736,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17dd,
+	0x17e0, 0x17e9,
+	0x17f0, 0x17f9,
+	0x1800, 0x180e,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191e,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1940, 0x1940,
+	0x1944, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19da,
+	0x19de, 0x1a1b,
+	0x1a1e, 0x1a5e,
+	0x1a60, 0x1a7c,
+	0x1a7f, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1aa0, 0x1aad,
+	0x1ab0, 0x1abe,
+	0x1b00, 0x1b4b,
+	0x1b50, 0x1b7c,
+	0x1b80, 0x1bf3,
+	0x1bfc, 0x1c37,
+	0x1c3b, 0x1c49,
+	0x1c4d, 0x1c7f,
+	0x1cc0, 0x1cc7,
+	0x1cd0, 0x1cf6,
+	0x1cf8, 0x1cf9,
+	0x1d00, 0x1df5,
+	0x1dfc, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x2064,
+	0x2066, 0x2071,
+	0x2074, 0x208e,
+	0x2090, 0x209c,
+	0x20a0, 0x20be,
+	0x20d0, 0x20f0,
+	0x2100, 0x218b,
+	0x2190, 0x23fa,
+	0x2400, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x2b73,
+	0x2b76, 0x2b95,
+	0x2b98, 0x2bb9,
+	0x2bbd, 0x2bc8,
+	0x2bca, 0x2bd1,
+	0x2bec, 0x2bef,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2cf3,
+	0x2cf9, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d70,
+	0x2d7f, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2de0, 0x2e42,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3000, 0x303f,
+	0x3041, 0x3096,
+	0x3099, 0x30ff,
+	0x3105, 0x312d,
+	0x3131, 0x318e,
+	0x3190, 0x31ba,
+	0x31c0, 0x31e3,
+	0x31f0, 0x321e,
+	0x3220, 0x32fe,
+	0x3300, 0x4db5,
+	0x4dc0, 0x9fd5,
+	0xa000, 0xa48c,
+	0xa490, 0xa4c6,
+	0xa4d0, 0xa62b,
+	0xa640, 0xa6f7,
+	0xa700, 0xa7ad,
+	0xa7b0, 0xa7b7,
+	0xa7f7, 0xa82b,
+	0xa830, 0xa839,
+	0xa840, 0xa877,
+	0xa880, 0xa8c4,
+	0xa8ce, 0xa8d9,
+	0xa8e0, 0xa8fd,
+	0xa900, 0xa953,
+	0xa95f, 0xa97c,
+	0xa980, 0xa9cd,
+	0xa9cf, 0xa9d9,
+	0xa9de, 0xa9fe,
+	0xaa00, 0xaa36,
+	0xaa40, 0xaa4d,
+	0xaa50, 0xaa59,
+	0xaa5c, 0xaac2,
+	0xaadb, 0xaaf6,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xab30, 0xab65,
+	0xab70, 0xabed,
+	0xabf0, 0xabf9,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xd800, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbc1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdd0, 0xfdfd,
+	0xfe00, 0xfe19,
+	0xfe20, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfff9, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10100, 0x10102,
+	0x10107, 0x10133,
+	0x10137, 0x1018c,
+	0x10190, 0x1019b,
+	0x101a0, 0x101a0,
+	0x101d0, 0x101fd,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x102e0, 0x102fb,
+	0x10300, 0x10323,
+	0x10330, 0x1034a,
+	0x10350, 0x1037a,
+	0x10380, 0x1039d,
+	0x1039f, 0x103c3,
+	0x103c8, 0x103d5,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x10500, 0x10527,
+	0x10530, 0x10563,
+	0x1056f, 0x1056f,
+	0x10600, 0x10736,
+	0x10740, 0x10755,
+	0x10760, 0x10767,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10857, 0x1089e,
+	0x108a7, 0x108af,
+	0x108e0, 0x108f2,
+	0x108f4, 0x108f5,
+	0x108fb, 0x1091b,
+	0x1091f, 0x10939,
+	0x1093f, 0x1093f,
+	0x10980, 0x109b7,
+	0x109bc, 0x109cf,
+	0x109d2, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a47,
+	0x10a50, 0x10a58,
+	0x10a60, 0x10a9f,
+	0x10ac0, 0x10ae6,
+	0x10aeb, 0x10af6,
+	0x10b00, 0x10b35,
+	0x10b39, 0x10b55,
+	0x10b58, 0x10b72,
+	0x10b78, 0x10b91,
+	0x10b99, 0x10b9c,
+	0x10ba9, 0x10baf,
+	0x10c00, 0x10c48,
+	0x10c80, 0x10cb2,
+	0x10cc0, 0x10cf2,
+	0x10cfa, 0x10cff,
+	0x10e60, 0x10e7e,
+	0x11000, 0x1104d,
+	0x11052, 0x1106f,
+	0x1107f, 0x110c1,
+	0x110d0, 0x110e8,
+	0x110f0, 0x110f9,
+	0x11100, 0x11134,
+	0x11136, 0x11143,
+	0x11150, 0x11176,
+	0x11180, 0x111cd,
+	0x111d0, 0x111df,
+	0x111e1, 0x111f4,
+	0x11200, 0x11211,
+	0x11213, 0x1123d,
+	0x11280, 0x11286,
+	0x11288, 0x11288,
+	0x1128a, 0x1128d,
+	0x1128f, 0x1129d,
+	0x1129f, 0x112a9,
+	0x112b0, 0x112ea,
+	0x112f0, 0x112f9,
+	0x11300, 0x11303,
+	0x11305, 0x1130c,
+	0x1130f, 0x11310,
+	0x11313, 0x11328,
+	0x1132a, 0x11330,
+	0x11332, 0x11333,
+	0x11335, 0x11339,
+	0x1133c, 0x11344,
+	0x11347, 0x11348,
+	0x1134b, 0x1134d,
+	0x11350, 0x11350,
+	0x11357, 0x11357,
+	0x1135d, 0x11363,
+	0x11366, 0x1136c,
+	0x11370, 0x11374,
+	0x11480, 0x114c7,
+	0x114d0, 0x114d9,
+	0x11580, 0x115b5,
+	0x115b8, 0x115dd,
+	0x11600, 0x11644,
+	0x11650, 0x11659,
+	0x11680, 0x116b7,
+	0x116c0, 0x116c9,
+	0x11700, 0x11719,
+	0x1171d, 0x1172b,
+	0x11730, 0x1173f,
+	0x118a0, 0x118f2,
+	0x118ff, 0x118ff,
+	0x11ac0, 0x11af8,
+	0x12000, 0x12399,
+	0x12400, 0x1246e,
+	0x12470, 0x12474,
+	0x12480, 0x12543,
+	0x13000, 0x1342e,
+	0x14400, 0x14646,
+	0x16800, 0x16a38,
+	0x16a40, 0x16a5e,
+	0x16a60, 0x16a69,
+	0x16a6e, 0x16a6f,
+	0x16ad0, 0x16aed,
+	0x16af0, 0x16af5,
+	0x16b00, 0x16b45,
+	0x16b50, 0x16b59,
+	0x16b5b, 0x16b61,
+	0x16b63, 0x16b77,
+	0x16b7d, 0x16b8f,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f7e,
+	0x16f8f, 0x16f9f,
+	0x1b000, 0x1b001,
+	0x1bc00, 0x1bc6a,
+	0x1bc70, 0x1bc7c,
+	0x1bc80, 0x1bc88,
+	0x1bc90, 0x1bc99,
+	0x1bc9c, 0x1bca3,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d129, 0x1d1e8,
+	0x1d200, 0x1d245,
+	0x1d300, 0x1d356,
+	0x1d360, 0x1d371,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d7cb,
+	0x1d7ce, 0x1da8b,
+	0x1da9b, 0x1da9f,
+	0x1daa1, 0x1daaf,
+	0x1e800, 0x1e8c4,
+	0x1e8c7, 0x1e8d6,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x1eef0, 0x1eef1,
+	0x1f000, 0x1f02b,
+	0x1f030, 0x1f093,
+	0x1f0a0, 0x1f0ae,
+	0x1f0b1, 0x1f0bf,
+	0x1f0c1, 0x1f0cf,
+	0x1f0d1, 0x1f0f5,
+	0x1f100, 0x1f10c,
+	0x1f110, 0x1f12e,
+	0x1f130, 0x1f16b,
+	0x1f170, 0x1f19a,
+	0x1f1e6, 0x1f202,
+	0x1f210, 0x1f23a,
+	0x1f240, 0x1f248,
+	0x1f250, 0x1f251,
+	0x1f300, 0x1f579,
+	0x1f57b, 0x1f5a3,
+	0x1f5a5, 0x1f6d0,
+	0x1f6e0, 0x1f6ec,
+	0x1f6f0, 0x1f6f3,
+	0x1f700, 0x1f773,
+	0x1f780, 0x1f7d4,
+	0x1f800, 0x1f80b,
+	0x1f810, 0x1f847,
+	0x1f850, 0x1f859,
+	0x1f860, 0x1f887,
+	0x1f890, 0x1f8ad,
+	0x1f910, 0x1f918,
+	0x1f980, 0x1f984,
+	0x1f9c0, 0x1f9c0,
+	0x1fffe, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2b820, 0x2cea1,
+	0x2f800, 0x2fa1d,
+	0x2fffe, 0x2ffff,
+	0x3fffe, 0x3ffff,
+	0x4fffe, 0x4ffff,
+	0x5fffe, 0x5ffff,
+	0x6fffe, 0x6ffff,
+	0x7fffe, 0x7ffff,
+	0x8fffe, 0x8ffff,
+	0x9fffe, 0x9ffff,
+	0xafffe, 0xaffff,
+	0xbfffe, 0xbffff,
+	0xcfffe, 0xcffff,
+	0xdfffe, 0xdffff,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+	0xe0100, 0xe01ef,
+	0xefffe, 0x10ffff,
+}; /* CR_Age_8_0 */
+
+/* 'Age_9_0': Derived Age 9.0 */
+static const OnigCodePoint CR_Age_9_0[] = {
+	648,
+	0x0000, 0x0377,
+	0x037a, 0x037f,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x052f,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x058a,
+	0x058d, 0x058f,
+	0x0591, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x0600, 0x061c,
+	0x061e, 0x070d,
+	0x070f, 0x074a,
+	0x074d, 0x07b1,
+	0x07c0, 0x07fa,
+	0x0800, 0x082d,
+	0x0830, 0x083e,
+	0x0840, 0x085b,
+	0x085e, 0x085e,
+	0x08a0, 0x08b4,
+	0x08b6, 0x08bd,
+	0x08d4, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fb,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a75,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0af1,
+	0x0af9, 0x0af9,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3c, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b63,
+	0x0b66, 0x0b77,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd0, 0x0bd0,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bfa,
+	0x0c00, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c39,
+	0x0c3d, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c58, 0x0c5a,
+	0x0c60, 0x0c63,
+	0x0c66, 0x0c6f,
+	0x0c78, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbc, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce3,
+	0x0ce6, 0x0cef,
+	0x0cf1, 0x0cf2,
+	0x0d01, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d3a,
+	0x0d3d, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4f,
+	0x0d54, 0x0d63,
+	0x0d66, 0x0d7f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0de6, 0x0def,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f71, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fbe, 0x0fcc,
+	0x0fce, 0x0fda,
+	0x1000, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135d, 0x137c,
+	0x1380, 0x1399,
+	0x13a0, 0x13f5,
+	0x13f8, 0x13fd,
+	0x1400, 0x169c,
+	0x16a0, 0x16f8,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+	0x1720, 0x1736,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17dd,
+	0x17e0, 0x17e9,
+	0x17f0, 0x17f9,
+	0x1800, 0x180e,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191e,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1940, 0x1940,
+	0x1944, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19da,
+	0x19de, 0x1a1b,
+	0x1a1e, 0x1a5e,
+	0x1a60, 0x1a7c,
+	0x1a7f, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1aa0, 0x1aad,
+	0x1ab0, 0x1abe,
+	0x1b00, 0x1b4b,
+	0x1b50, 0x1b7c,
+	0x1b80, 0x1bf3,
+	0x1bfc, 0x1c37,
+	0x1c3b, 0x1c49,
+	0x1c4d, 0x1c88,
+	0x1cc0, 0x1cc7,
+	0x1cd0, 0x1cf6,
+	0x1cf8, 0x1cf9,
+	0x1d00, 0x1df5,
+	0x1dfb, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x2064,
+	0x2066, 0x2071,
+	0x2074, 0x208e,
+	0x2090, 0x209c,
+	0x20a0, 0x20be,
+	0x20d0, 0x20f0,
+	0x2100, 0x218b,
+	0x2190, 0x23fe,
+	0x2400, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x2b73,
+	0x2b76, 0x2b95,
+	0x2b98, 0x2bb9,
+	0x2bbd, 0x2bc8,
+	0x2bca, 0x2bd1,
+	0x2bec, 0x2bef,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2cf3,
+	0x2cf9, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d70,
+	0x2d7f, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2de0, 0x2e44,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3000, 0x303f,
+	0x3041, 0x3096,
+	0x3099, 0x30ff,
+	0x3105, 0x312d,
+	0x3131, 0x318e,
+	0x3190, 0x31ba,
+	0x31c0, 0x31e3,
+	0x31f0, 0x321e,
+	0x3220, 0x32fe,
+	0x3300, 0x4db5,
+	0x4dc0, 0x9fd5,
+	0xa000, 0xa48c,
+	0xa490, 0xa4c6,
+	0xa4d0, 0xa62b,
+	0xa640, 0xa6f7,
+	0xa700, 0xa7ae,
+	0xa7b0, 0xa7b7,
+	0xa7f7, 0xa82b,
+	0xa830, 0xa839,
+	0xa840, 0xa877,
+	0xa880, 0xa8c5,
+	0xa8ce, 0xa8d9,
+	0xa8e0, 0xa8fd,
+	0xa900, 0xa953,
+	0xa95f, 0xa97c,
+	0xa980, 0xa9cd,
+	0xa9cf, 0xa9d9,
+	0xa9de, 0xa9fe,
+	0xaa00, 0xaa36,
+	0xaa40, 0xaa4d,
+	0xaa50, 0xaa59,
+	0xaa5c, 0xaac2,
+	0xaadb, 0xaaf6,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xab30, 0xab65,
+	0xab70, 0xabed,
+	0xabf0, 0xabf9,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xd800, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbc1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdd0, 0xfdfd,
+	0xfe00, 0xfe19,
+	0xfe20, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfff9, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10100, 0x10102,
+	0x10107, 0x10133,
+	0x10137, 0x1018e,
+	0x10190, 0x1019b,
+	0x101a0, 0x101a0,
+	0x101d0, 0x101fd,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x102e0, 0x102fb,
+	0x10300, 0x10323,
+	0x10330, 0x1034a,
+	0x10350, 0x1037a,
+	0x10380, 0x1039d,
+	0x1039f, 0x103c3,
+	0x103c8, 0x103d5,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x104b0, 0x104d3,
+	0x104d8, 0x104fb,
+	0x10500, 0x10527,
+	0x10530, 0x10563,
+	0x1056f, 0x1056f,
+	0x10600, 0x10736,
+	0x10740, 0x10755,
+	0x10760, 0x10767,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10857, 0x1089e,
+	0x108a7, 0x108af,
+	0x108e0, 0x108f2,
+	0x108f4, 0x108f5,
+	0x108fb, 0x1091b,
+	0x1091f, 0x10939,
+	0x1093f, 0x1093f,
+	0x10980, 0x109b7,
+	0x109bc, 0x109cf,
+	0x109d2, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a47,
+	0x10a50, 0x10a58,
+	0x10a60, 0x10a9f,
+	0x10ac0, 0x10ae6,
+	0x10aeb, 0x10af6,
+	0x10b00, 0x10b35,
+	0x10b39, 0x10b55,
+	0x10b58, 0x10b72,
+	0x10b78, 0x10b91,
+	0x10b99, 0x10b9c,
+	0x10ba9, 0x10baf,
+	0x10c00, 0x10c48,
+	0x10c80, 0x10cb2,
+	0x10cc0, 0x10cf2,
+	0x10cfa, 0x10cff,
+	0x10e60, 0x10e7e,
+	0x11000, 0x1104d,
+	0x11052, 0x1106f,
+	0x1107f, 0x110c1,
+	0x110d0, 0x110e8,
+	0x110f0, 0x110f9,
+	0x11100, 0x11134,
+	0x11136, 0x11143,
+	0x11150, 0x11176,
+	0x11180, 0x111cd,
+	0x111d0, 0x111df,
+	0x111e1, 0x111f4,
+	0x11200, 0x11211,
+	0x11213, 0x1123e,
+	0x11280, 0x11286,
+	0x11288, 0x11288,
+	0x1128a, 0x1128d,
+	0x1128f, 0x1129d,
+	0x1129f, 0x112a9,
+	0x112b0, 0x112ea,
+	0x112f0, 0x112f9,
+	0x11300, 0x11303,
+	0x11305, 0x1130c,
+	0x1130f, 0x11310,
+	0x11313, 0x11328,
+	0x1132a, 0x11330,
+	0x11332, 0x11333,
+	0x11335, 0x11339,
+	0x1133c, 0x11344,
+	0x11347, 0x11348,
+	0x1134b, 0x1134d,
+	0x11350, 0x11350,
+	0x11357, 0x11357,
+	0x1135d, 0x11363,
+	0x11366, 0x1136c,
+	0x11370, 0x11374,
+	0x11400, 0x11459,
+	0x1145b, 0x1145b,
+	0x1145d, 0x1145d,
+	0x11480, 0x114c7,
+	0x114d0, 0x114d9,
+	0x11580, 0x115b5,
+	0x115b8, 0x115dd,
+	0x11600, 0x11644,
+	0x11650, 0x11659,
+	0x11660, 0x1166c,
+	0x11680, 0x116b7,
+	0x116c0, 0x116c9,
+	0x11700, 0x11719,
+	0x1171d, 0x1172b,
+	0x11730, 0x1173f,
+	0x118a0, 0x118f2,
+	0x118ff, 0x118ff,
+	0x11ac0, 0x11af8,
+	0x11c00, 0x11c08,
+	0x11c0a, 0x11c36,
+	0x11c38, 0x11c45,
+	0x11c50, 0x11c6c,
+	0x11c70, 0x11c8f,
+	0x11c92, 0x11ca7,
+	0x11ca9, 0x11cb6,
+	0x12000, 0x12399,
+	0x12400, 0x1246e,
+	0x12470, 0x12474,
+	0x12480, 0x12543,
+	0x13000, 0x1342e,
+	0x14400, 0x14646,
+	0x16800, 0x16a38,
+	0x16a40, 0x16a5e,
+	0x16a60, 0x16a69,
+	0x16a6e, 0x16a6f,
+	0x16ad0, 0x16aed,
+	0x16af0, 0x16af5,
+	0x16b00, 0x16b45,
+	0x16b50, 0x16b59,
+	0x16b5b, 0x16b61,
+	0x16b63, 0x16b77,
+	0x16b7d, 0x16b8f,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f7e,
+	0x16f8f, 0x16f9f,
+	0x16fe0, 0x16fe0,
+	0x17000, 0x187ec,
+	0x18800, 0x18af2,
+	0x1b000, 0x1b001,
+	0x1bc00, 0x1bc6a,
+	0x1bc70, 0x1bc7c,
+	0x1bc80, 0x1bc88,
+	0x1bc90, 0x1bc99,
+	0x1bc9c, 0x1bca3,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d129, 0x1d1e8,
+	0x1d200, 0x1d245,
+	0x1d300, 0x1d356,
+	0x1d360, 0x1d371,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d7cb,
+	0x1d7ce, 0x1da8b,
+	0x1da9b, 0x1da9f,
+	0x1daa1, 0x1daaf,
+	0x1e000, 0x1e006,
+	0x1e008, 0x1e018,
+	0x1e01b, 0x1e021,
+	0x1e023, 0x1e024,
+	0x1e026, 0x1e02a,
+	0x1e800, 0x1e8c4,
+	0x1e8c7, 0x1e8d6,
+	0x1e900, 0x1e94a,
+	0x1e950, 0x1e959,
+	0x1e95e, 0x1e95f,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x1eef0, 0x1eef1,
+	0x1f000, 0x1f02b,
+	0x1f030, 0x1f093,
+	0x1f0a0, 0x1f0ae,
+	0x1f0b1, 0x1f0bf,
+	0x1f0c1, 0x1f0cf,
+	0x1f0d1, 0x1f0f5,
+	0x1f100, 0x1f10c,
+	0x1f110, 0x1f12e,
+	0x1f130, 0x1f16b,
+	0x1f170, 0x1f1ac,
+	0x1f1e6, 0x1f202,
+	0x1f210, 0x1f23b,
+	0x1f240, 0x1f248,
+	0x1f250, 0x1f251,
+	0x1f300, 0x1f6d2,
+	0x1f6e0, 0x1f6ec,
+	0x1f6f0, 0x1f6f6,
+	0x1f700, 0x1f773,
+	0x1f780, 0x1f7d4,
+	0x1f800, 0x1f80b,
+	0x1f810, 0x1f847,
+	0x1f850, 0x1f859,
+	0x1f860, 0x1f887,
+	0x1f890, 0x1f8ad,
+	0x1f910, 0x1f91e,
+	0x1f920, 0x1f927,
+	0x1f930, 0x1f930,
+	0x1f933, 0x1f93e,
+	0x1f940, 0x1f94b,
+	0x1f950, 0x1f95e,
+	0x1f980, 0x1f991,
+	0x1f9c0, 0x1f9c0,
+	0x1fffe, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2b820, 0x2cea1,
+	0x2f800, 0x2fa1d,
+	0x2fffe, 0x2ffff,
+	0x3fffe, 0x3ffff,
+	0x4fffe, 0x4ffff,
+	0x5fffe, 0x5ffff,
+	0x6fffe, 0x6ffff,
+	0x7fffe, 0x7ffff,
+	0x8fffe, 0x8ffff,
+	0x9fffe, 0x9ffff,
+	0xafffe, 0xaffff,
+	0xbfffe, 0xbffff,
+	0xcfffe, 0xcffff,
+	0xdfffe, 0xdffff,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+	0xe0100, 0xe01ef,
+	0xefffe, 0x10ffff,
+}; /* CR_Age_9_0 */
+
+/* 'Age_10_0': Derived Age 10.0 */
+static const OnigCodePoint CR_Age_10_0[] = {
+	659,
+	0x0000, 0x0377,
+	0x037a, 0x037f,
+	0x0384, 0x038a,
+	0x038c, 0x038c,
+	0x038e, 0x03a1,
+	0x03a3, 0x052f,
+	0x0531, 0x0556,
+	0x0559, 0x055f,
+	0x0561, 0x0587,
+	0x0589, 0x058a,
+	0x058d, 0x058f,
+	0x0591, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x0600, 0x061c,
+	0x061e, 0x070d,
+	0x070f, 0x074a,
+	0x074d, 0x07b1,
+	0x07c0, 0x07fa,
+	0x0800, 0x082d,
+	0x0830, 0x083e,
+	0x0840, 0x085b,
+	0x085e, 0x085e,
+	0x0860, 0x086a,
+	0x08a0, 0x08b4,
+	0x08b6, 0x08bd,
+	0x08d4, 0x0983,
+	0x0985, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09a8,
+	0x09aa, 0x09b0,
+	0x09b2, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09dd,
+	0x09df, 0x09e3,
+	0x09e6, 0x09fd,
+	0x0a01, 0x0a03,
+	0x0a05, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a28,
+	0x0a2a, 0x0a30,
+	0x0a32, 0x0a33,
+	0x0a35, 0x0a36,
+	0x0a38, 0x0a39,
+	0x0a3c, 0x0a3c,
+	0x0a3e, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a59, 0x0a5c,
+	0x0a5e, 0x0a5e,
+	0x0a66, 0x0a75,
+	0x0a81, 0x0a83,
+	0x0a85, 0x0a8d,
+	0x0a8f, 0x0a91,
+	0x0a93, 0x0aa8,
+	0x0aaa, 0x0ab0,
+	0x0ab2, 0x0ab3,
+	0x0ab5, 0x0ab9,
+	0x0abc, 0x0ac5,
+	0x0ac7, 0x0ac9,
+	0x0acb, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0af1,
+	0x0af9, 0x0aff,
+	0x0b01, 0x0b03,
+	0x0b05, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b28,
+	0x0b2a, 0x0b30,
+	0x0b32, 0x0b33,
+	0x0b35, 0x0b39,
+	0x0b3c, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b5d,
+	0x0b5f, 0x0b63,
+	0x0b66, 0x0b77,
+	0x0b82, 0x0b83,
+	0x0b85, 0x0b8a,
+	0x0b8e, 0x0b90,
+	0x0b92, 0x0b95,
+	0x0b99, 0x0b9a,
+	0x0b9c, 0x0b9c,
+	0x0b9e, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcd,
+	0x0bd0, 0x0bd0,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bfa,
+	0x0c00, 0x0c03,
+	0x0c05, 0x0c0c,
+	0x0c0e, 0x0c10,
+	0x0c12, 0x0c28,
+	0x0c2a, 0x0c39,
+	0x0c3d, 0x0c44,
+	0x0c46, 0x0c48,
+	0x0c4a, 0x0c4d,
+	0x0c55, 0x0c56,
+	0x0c58, 0x0c5a,
+	0x0c60, 0x0c63,
+	0x0c66, 0x0c6f,
+	0x0c78, 0x0c83,
+	0x0c85, 0x0c8c,
+	0x0c8e, 0x0c90,
+	0x0c92, 0x0ca8,
+	0x0caa, 0x0cb3,
+	0x0cb5, 0x0cb9,
+	0x0cbc, 0x0cc4,
+	0x0cc6, 0x0cc8,
+	0x0cca, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0cde,
+	0x0ce0, 0x0ce3,
+	0x0ce6, 0x0cef,
+	0x0cf1, 0x0cf2,
+	0x0d00, 0x0d03,
+	0x0d05, 0x0d0c,
+	0x0d0e, 0x0d10,
+	0x0d12, 0x0d44,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4f,
+	0x0d54, 0x0d63,
+	0x0d66, 0x0d7f,
+	0x0d82, 0x0d83,
+	0x0d85, 0x0d96,
+	0x0d9a, 0x0db1,
+	0x0db3, 0x0dbb,
+	0x0dbd, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0dd4,
+	0x0dd6, 0x0dd6,
+	0x0dd8, 0x0ddf,
+	0x0de6, 0x0def,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e82,
+	0x0e84, 0x0e84,
+	0x0e87, 0x0e88,
+	0x0e8a, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0e97,
+	0x0e99, 0x0e9f,
+	0x0ea1, 0x0ea3,
+	0x0ea5, 0x0ea5,
+	0x0ea7, 0x0ea7,
+	0x0eaa, 0x0eab,
+	0x0ead, 0x0eb9,
+	0x0ebb, 0x0ebd,
+	0x0ec0, 0x0ec4,
+	0x0ec6, 0x0ec6,
+	0x0ec8, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f47,
+	0x0f49, 0x0f6c,
+	0x0f71, 0x0f97,
+	0x0f99, 0x0fbc,
+	0x0fbe, 0x0fcc,
+	0x0fce, 0x0fda,
+	0x1000, 0x10c5,
+	0x10c7, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x1248,
+	0x124a, 0x124d,
+	0x1250, 0x1256,
+	0x1258, 0x1258,
+	0x125a, 0x125d,
+	0x1260, 0x1288,
+	0x128a, 0x128d,
+	0x1290, 0x12b0,
+	0x12b2, 0x12b5,
+	0x12b8, 0x12be,
+	0x12c0, 0x12c0,
+	0x12c2, 0x12c5,
+	0x12c8, 0x12d6,
+	0x12d8, 0x1310,
+	0x1312, 0x1315,
+	0x1318, 0x135a,
+	0x135d, 0x137c,
+	0x1380, 0x1399,
+	0x13a0, 0x13f5,
+	0x13f8, 0x13fd,
+	0x1400, 0x169c,
+	0x16a0, 0x16f8,
+	0x1700, 0x170c,
+	0x170e, 0x1714,
+	0x1720, 0x1736,
+	0x1740, 0x1753,
+	0x1760, 0x176c,
+	0x176e, 0x1770,
+	0x1772, 0x1773,
+	0x1780, 0x17dd,
+	0x17e0, 0x17e9,
+	0x17f0, 0x17f9,
+	0x1800, 0x180e,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x191e,
+	0x1920, 0x192b,
+	0x1930, 0x193b,
+	0x1940, 0x1940,
+	0x1944, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19da,
+	0x19de, 0x1a1b,
+	0x1a1e, 0x1a5e,
+	0x1a60, 0x1a7c,
+	0x1a7f, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1aa0, 0x1aad,
+	0x1ab0, 0x1abe,
+	0x1b00, 0x1b4b,
+	0x1b50, 0x1b7c,
+	0x1b80, 0x1bf3,
+	0x1bfc, 0x1c37,
+	0x1c3b, 0x1c49,
+	0x1c4d, 0x1c88,
+	0x1cc0, 0x1cc7,
+	0x1cd0, 0x1cf9,
+	0x1d00, 0x1df9,
+	0x1dfb, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f57,
+	0x1f59, 0x1f59,
+	0x1f5b, 0x1f5b,
+	0x1f5d, 0x1f5d,
+	0x1f5f, 0x1f7d,
+	0x1f80, 0x1fb4,
+	0x1fb6, 0x1fc4,
+	0x1fc6, 0x1fd3,
+	0x1fd6, 0x1fdb,
+	0x1fdd, 0x1fef,
+	0x1ff2, 0x1ff4,
+	0x1ff6, 0x1ffe,
+	0x2000, 0x2064,
+	0x2066, 0x2071,
+	0x2074, 0x208e,
+	0x2090, 0x209c,
+	0x20a0, 0x20bf,
+	0x20d0, 0x20f0,
+	0x2100, 0x218b,
+	0x2190, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x2b73,
+	0x2b76, 0x2b95,
+	0x2b98, 0x2bb9,
+	0x2bbd, 0x2bc8,
+	0x2bca, 0x2bd2,
+	0x2bec, 0x2bef,
+	0x2c00, 0x2c2e,
+	0x2c30, 0x2c5e,
+	0x2c60, 0x2cf3,
+	0x2cf9, 0x2d25,
+	0x2d27, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d70,
+	0x2d7f, 0x2d96,
+	0x2da0, 0x2da6,
+	0x2da8, 0x2dae,
+	0x2db0, 0x2db6,
+	0x2db8, 0x2dbe,
+	0x2dc0, 0x2dc6,
+	0x2dc8, 0x2dce,
+	0x2dd0, 0x2dd6,
+	0x2dd8, 0x2dde,
+	0x2de0, 0x2e49,
+	0x2e80, 0x2e99,
+	0x2e9b, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3000, 0x303f,
+	0x3041, 0x3096,
+	0x3099, 0x30ff,
+	0x3105, 0x312e,
+	0x3131, 0x318e,
+	0x3190, 0x31ba,
+	0x31c0, 0x31e3,
+	0x31f0, 0x321e,
+	0x3220, 0x32fe,
+	0x3300, 0x4db5,
+	0x4dc0, 0x9fea,
+	0xa000, 0xa48c,
+	0xa490, 0xa4c6,
+	0xa4d0, 0xa62b,
+	0xa640, 0xa6f7,
+	0xa700, 0xa7ae,
+	0xa7b0, 0xa7b7,
+	0xa7f7, 0xa82b,
+	0xa830, 0xa839,
+	0xa840, 0xa877,
+	0xa880, 0xa8c5,
+	0xa8ce, 0xa8d9,
+	0xa8e0, 0xa8fd,
+	0xa900, 0xa953,
+	0xa95f, 0xa97c,
+	0xa980, 0xa9cd,
+	0xa9cf, 0xa9d9,
+	0xa9de, 0xa9fe,
+	0xaa00, 0xaa36,
+	0xaa40, 0xaa4d,
+	0xaa50, 0xaa59,
+	0xaa5c, 0xaac2,
+	0xaadb, 0xaaf6,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab26,
+	0xab28, 0xab2e,
+	0xab30, 0xab65,
+	0xab70, 0xabed,
+	0xabf0, 0xabf9,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xd800, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfb36,
+	0xfb38, 0xfb3c,
+	0xfb3e, 0xfb3e,
+	0xfb40, 0xfb41,
+	0xfb43, 0xfb44,
+	0xfb46, 0xfbc1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdd0, 0xfdfd,
+	0xfe00, 0xfe19,
+	0xfe20, 0xfe52,
+	0xfe54, 0xfe66,
+	0xfe68, 0xfe6b,
+	0xfe70, 0xfe74,
+	0xfe76, 0xfefc,
+	0xfeff, 0xfeff,
+	0xff01, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffe6,
+	0xffe8, 0xffee,
+	0xfff9, 0x1000b,
+	0x1000d, 0x10026,
+	0x10028, 0x1003a,
+	0x1003c, 0x1003d,
+	0x1003f, 0x1004d,
+	0x10050, 0x1005d,
+	0x10080, 0x100fa,
+	0x10100, 0x10102,
+	0x10107, 0x10133,
+	0x10137, 0x1018e,
+	0x10190, 0x1019b,
+	0x101a0, 0x101a0,
+	0x101d0, 0x101fd,
+	0x10280, 0x1029c,
+	0x102a0, 0x102d0,
+	0x102e0, 0x102fb,
+	0x10300, 0x10323,
+	0x1032d, 0x1034a,
+	0x10350, 0x1037a,
+	0x10380, 0x1039d,
+	0x1039f, 0x103c3,
+	0x103c8, 0x103d5,
+	0x10400, 0x1049d,
+	0x104a0, 0x104a9,
+	0x104b0, 0x104d3,
+	0x104d8, 0x104fb,
+	0x10500, 0x10527,
+	0x10530, 0x10563,
+	0x1056f, 0x1056f,
+	0x10600, 0x10736,
+	0x10740, 0x10755,
+	0x10760, 0x10767,
+	0x10800, 0x10805,
+	0x10808, 0x10808,
+	0x1080a, 0x10835,
+	0x10837, 0x10838,
+	0x1083c, 0x1083c,
+	0x1083f, 0x10855,
+	0x10857, 0x1089e,
+	0x108a7, 0x108af,
+	0x108e0, 0x108f2,
+	0x108f4, 0x108f5,
+	0x108fb, 0x1091b,
+	0x1091f, 0x10939,
+	0x1093f, 0x1093f,
+	0x10980, 0x109b7,
+	0x109bc, 0x109cf,
+	0x109d2, 0x10a03,
+	0x10a05, 0x10a06,
+	0x10a0c, 0x10a13,
+	0x10a15, 0x10a17,
+	0x10a19, 0x10a33,
+	0x10a38, 0x10a3a,
+	0x10a3f, 0x10a47,
+	0x10a50, 0x10a58,
+	0x10a60, 0x10a9f,
+	0x10ac0, 0x10ae6,
+	0x10aeb, 0x10af6,
+	0x10b00, 0x10b35,
+	0x10b39, 0x10b55,
+	0x10b58, 0x10b72,
+	0x10b78, 0x10b91,
+	0x10b99, 0x10b9c,
+	0x10ba9, 0x10baf,
+	0x10c00, 0x10c48,
+	0x10c80, 0x10cb2,
+	0x10cc0, 0x10cf2,
+	0x10cfa, 0x10cff,
+	0x10e60, 0x10e7e,
+	0x11000, 0x1104d,
+	0x11052, 0x1106f,
+	0x1107f, 0x110c1,
+	0x110d0, 0x110e8,
+	0x110f0, 0x110f9,
+	0x11100, 0x11134,
+	0x11136, 0x11143,
+	0x11150, 0x11176,
+	0x11180, 0x111cd,
+	0x111d0, 0x111df,
+	0x111e1, 0x111f4,
+	0x11200, 0x11211,
+	0x11213, 0x1123e,
+	0x11280, 0x11286,
+	0x11288, 0x11288,
+	0x1128a, 0x1128d,
+	0x1128f, 0x1129d,
+	0x1129f, 0x112a9,
+	0x112b0, 0x112ea,
+	0x112f0, 0x112f9,
+	0x11300, 0x11303,
+	0x11305, 0x1130c,
+	0x1130f, 0x11310,
+	0x11313, 0x11328,
+	0x1132a, 0x11330,
+	0x11332, 0x11333,
+	0x11335, 0x11339,
+	0x1133c, 0x11344,
+	0x11347, 0x11348,
+	0x1134b, 0x1134d,
+	0x11350, 0x11350,
+	0x11357, 0x11357,
+	0x1135d, 0x11363,
+	0x11366, 0x1136c,
+	0x11370, 0x11374,
+	0x11400, 0x11459,
+	0x1145b, 0x1145b,
+	0x1145d, 0x1145d,
+	0x11480, 0x114c7,
+	0x114d0, 0x114d9,
+	0x11580, 0x115b5,
+	0x115b8, 0x115dd,
+	0x11600, 0x11644,
+	0x11650, 0x11659,
+	0x11660, 0x1166c,
+	0x11680, 0x116b7,
+	0x116c0, 0x116c9,
+	0x11700, 0x11719,
+	0x1171d, 0x1172b,
+	0x11730, 0x1173f,
+	0x118a0, 0x118f2,
+	0x118ff, 0x118ff,
+	0x11a00, 0x11a47,
+	0x11a50, 0x11a83,
+	0x11a86, 0x11a9c,
+	0x11a9e, 0x11aa2,
+	0x11ac0, 0x11af8,
+	0x11c00, 0x11c08,
+	0x11c0a, 0x11c36,
+	0x11c38, 0x11c45,
+	0x11c50, 0x11c6c,
+	0x11c70, 0x11c8f,
+	0x11c92, 0x11ca7,
+	0x11ca9, 0x11cb6,
+	0x11d00, 0x11d06,
+	0x11d08, 0x11d09,
+	0x11d0b, 0x11d36,
+	0x11d3a, 0x11d3a,
+	0x11d3c, 0x11d3d,
+	0x11d3f, 0x11d47,
+	0x11d50, 0x11d59,
+	0x12000, 0x12399,
+	0x12400, 0x1246e,
+	0x12470, 0x12474,
+	0x12480, 0x12543,
+	0x13000, 0x1342e,
+	0x14400, 0x14646,
+	0x16800, 0x16a38,
+	0x16a40, 0x16a5e,
+	0x16a60, 0x16a69,
+	0x16a6e, 0x16a6f,
+	0x16ad0, 0x16aed,
+	0x16af0, 0x16af5,
+	0x16b00, 0x16b45,
+	0x16b50, 0x16b59,
+	0x16b5b, 0x16b61,
+	0x16b63, 0x16b77,
+	0x16b7d, 0x16b8f,
+	0x16f00, 0x16f44,
+	0x16f50, 0x16f7e,
+	0x16f8f, 0x16f9f,
+	0x16fe0, 0x16fe1,
+	0x17000, 0x187ec,
+	0x18800, 0x18af2,
+	0x1b000, 0x1b11e,
+	0x1b170, 0x1b2fb,
+	0x1bc00, 0x1bc6a,
+	0x1bc70, 0x1bc7c,
+	0x1bc80, 0x1bc88,
+	0x1bc90, 0x1bc99,
+	0x1bc9c, 0x1bca3,
+	0x1d000, 0x1d0f5,
+	0x1d100, 0x1d126,
+	0x1d129, 0x1d1e8,
+	0x1d200, 0x1d245,
+	0x1d300, 0x1d356,
+	0x1d360, 0x1d371,
+	0x1d400, 0x1d454,
+	0x1d456, 0x1d49c,
+	0x1d49e, 0x1d49f,
+	0x1d4a2, 0x1d4a2,
+	0x1d4a5, 0x1d4a6,
+	0x1d4a9, 0x1d4ac,
+	0x1d4ae, 0x1d4b9,
+	0x1d4bb, 0x1d4bb,
+	0x1d4bd, 0x1d4c3,
+	0x1d4c5, 0x1d505,
+	0x1d507, 0x1d50a,
+	0x1d50d, 0x1d514,
+	0x1d516, 0x1d51c,
+	0x1d51e, 0x1d539,
+	0x1d53b, 0x1d53e,
+	0x1d540, 0x1d544,
+	0x1d546, 0x1d546,
+	0x1d54a, 0x1d550,
+	0x1d552, 0x1d6a5,
+	0x1d6a8, 0x1d7cb,
+	0x1d7ce, 0x1da8b,
+	0x1da9b, 0x1da9f,
+	0x1daa1, 0x1daaf,
+	0x1e000, 0x1e006,
+	0x1e008, 0x1e018,
+	0x1e01b, 0x1e021,
+	0x1e023, 0x1e024,
+	0x1e026, 0x1e02a,
+	0x1e800, 0x1e8c4,
+	0x1e8c7, 0x1e8d6,
+	0x1e900, 0x1e94a,
+	0x1e950, 0x1e959,
+	0x1e95e, 0x1e95f,
+	0x1ee00, 0x1ee03,
+	0x1ee05, 0x1ee1f,
+	0x1ee21, 0x1ee22,
+	0x1ee24, 0x1ee24,
+	0x1ee27, 0x1ee27,
+	0x1ee29, 0x1ee32,
+	0x1ee34, 0x1ee37,
+	0x1ee39, 0x1ee39,
+	0x1ee3b, 0x1ee3b,
+	0x1ee42, 0x1ee42,
+	0x1ee47, 0x1ee47,
+	0x1ee49, 0x1ee49,
+	0x1ee4b, 0x1ee4b,
+	0x1ee4d, 0x1ee4f,
+	0x1ee51, 0x1ee52,
+	0x1ee54, 0x1ee54,
+	0x1ee57, 0x1ee57,
+	0x1ee59, 0x1ee59,
+	0x1ee5b, 0x1ee5b,
+	0x1ee5d, 0x1ee5d,
+	0x1ee5f, 0x1ee5f,
+	0x1ee61, 0x1ee62,
+	0x1ee64, 0x1ee64,
+	0x1ee67, 0x1ee6a,
+	0x1ee6c, 0x1ee72,
+	0x1ee74, 0x1ee77,
+	0x1ee79, 0x1ee7c,
+	0x1ee7e, 0x1ee7e,
+	0x1ee80, 0x1ee89,
+	0x1ee8b, 0x1ee9b,
+	0x1eea1, 0x1eea3,
+	0x1eea5, 0x1eea9,
+	0x1eeab, 0x1eebb,
+	0x1eef0, 0x1eef1,
+	0x1f000, 0x1f02b,
+	0x1f030, 0x1f093,
+	0x1f0a0, 0x1f0ae,
+	0x1f0b1, 0x1f0bf,
+	0x1f0c1, 0x1f0cf,
+	0x1f0d1, 0x1f0f5,
+	0x1f100, 0x1f10c,
+	0x1f110, 0x1f12e,
+	0x1f130, 0x1f16b,
+	0x1f170, 0x1f1ac,
+	0x1f1e6, 0x1f202,
+	0x1f210, 0x1f23b,
+	0x1f240, 0x1f248,
+	0x1f250, 0x1f251,
+	0x1f260, 0x1f265,
+	0x1f300, 0x1f6d4,
+	0x1f6e0, 0x1f6ec,
+	0x1f6f0, 0x1f6f8,
+	0x1f700, 0x1f773,
+	0x1f780, 0x1f7d4,
+	0x1f800, 0x1f80b,
+	0x1f810, 0x1f847,
+	0x1f850, 0x1f859,
+	0x1f860, 0x1f887,
+	0x1f890, 0x1f8ad,
+	0x1f900, 0x1f90b,
+	0x1f910, 0x1f93e,
+	0x1f940, 0x1f94c,
+	0x1f950, 0x1f96b,
+	0x1f980, 0x1f997,
+	0x1f9c0, 0x1f9c0,
+	0x1f9d0, 0x1f9e6,
+	0x1fffe, 0x2a6d6,
+	0x2a700, 0x2b734,
+	0x2b740, 0x2b81d,
+	0x2b820, 0x2cea1,
+	0x2ceb0, 0x2ebe0,
+	0x2f800, 0x2fa1d,
+	0x2fffe, 0x2ffff,
+	0x3fffe, 0x3ffff,
+	0x4fffe, 0x4ffff,
+	0x5fffe, 0x5ffff,
+	0x6fffe, 0x6ffff,
+	0x7fffe, 0x7ffff,
+	0x8fffe, 0x8ffff,
+	0x9fffe, 0x9ffff,
+	0xafffe, 0xaffff,
+	0xbfffe, 0xbffff,
+	0xcfffe, 0xcffff,
+	0xdfffe, 0xdffff,
+	0xe0001, 0xe0001,
+	0xe0020, 0xe007f,
+	0xe0100, 0xe01ef,
+	0xefffe, 0x10ffff,
+}; /* CR_Age_10_0 */
+
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+/* 'Grapheme_Cluster_Break_Prepend': Grapheme_Cluster_Break=Prepend */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_Prepend[] = {
+	10,
+	0x0600, 0x0605,
+	0x06dd, 0x06dd,
+	0x070f, 0x070f,
+	0x08e2, 0x08e2,
+	0x0d4e, 0x0d4e,
+	0x110bd, 0x110bd,
+	0x111c2, 0x111c3,
+	0x11a3a, 0x11a3a,
+	0x11a86, 0x11a89,
+	0x11d46, 0x11d46,
+}; /* CR_Grapheme_Cluster_Break_Prepend */
+
+/* 'Grapheme_Cluster_Break_CR': Grapheme_Cluster_Break=CR */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_CR[] = {
+	1,
+	0x000d, 0x000d,
+}; /* CR_Grapheme_Cluster_Break_CR */
+
+/* 'Grapheme_Cluster_Break_LF': Grapheme_Cluster_Break=LF */
+#define CR_Grapheme_Cluster_Break_LF CR_NEWLINE
+
+/* 'Grapheme_Cluster_Break_Control': Grapheme_Cluster_Break=Control */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_Control[] = {
+	19,
+	0x0000, 0x0009,
+	0x000b, 0x000c,
+	0x000e, 0x001f,
+	0x007f, 0x009f,
+	0x00ad, 0x00ad,
+	0x061c, 0x061c,
+	0x180e, 0x180e,
+	0x200b, 0x200b,
+	0x200e, 0x200f,
+	0x2028, 0x202e,
+	0x2060, 0x206f,
+	0xd800, 0xdfff,
+	0xfeff, 0xfeff,
+	0xfff0, 0xfffb,
+	0x1bca0, 0x1bca3,
+	0x1d173, 0x1d17a,
+	0xe0000, 0xe001f,
+	0xe0080, 0xe00ff,
+	0xe01f0, 0xe0fff,
+}; /* CR_Grapheme_Cluster_Break_Control */
+
+/* 'Grapheme_Cluster_Break_Extend': Grapheme_Cluster_Break=Extend */
+#define CR_Grapheme_Cluster_Break_Extend CR_Grapheme_Extend
+
+/* 'Grapheme_Cluster_Break_Regional_Indicator': Grapheme_Cluster_Break=Regional_Indicator */
+#define CR_Grapheme_Cluster_Break_Regional_Indicator CR_Regional_Indicator
+
+/* 'Grapheme_Cluster_Break_SpacingMark': Grapheme_Cluster_Break=SpacingMark */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_SpacingMark[] = {
+	145,
+	0x0903, 0x0903,
+	0x093b, 0x093b,
+	0x093e, 0x0940,
+	0x0949, 0x094c,
+	0x094e, 0x094f,
+	0x0982, 0x0983,
+	0x09bf, 0x09c0,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09cc,
+	0x0a03, 0x0a03,
+	0x0a3e, 0x0a40,
+	0x0a83, 0x0a83,
+	0x0abe, 0x0ac0,
+	0x0ac9, 0x0ac9,
+	0x0acb, 0x0acc,
+	0x0b02, 0x0b03,
+	0x0b40, 0x0b40,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4c,
+	0x0bbf, 0x0bbf,
+	0x0bc1, 0x0bc2,
+	0x0bc6, 0x0bc8,
+	0x0bca, 0x0bcc,
+	0x0c01, 0x0c03,
+	0x0c41, 0x0c44,
+	0x0c82, 0x0c83,
+	0x0cbe, 0x0cbe,
+	0x0cc0, 0x0cc1,
+	0x0cc3, 0x0cc4,
+	0x0cc7, 0x0cc8,
+	0x0cca, 0x0ccb,
+	0x0d02, 0x0d03,
+	0x0d3f, 0x0d40,
+	0x0d46, 0x0d48,
+	0x0d4a, 0x0d4c,
+	0x0d82, 0x0d83,
+	0x0dd0, 0x0dd1,
+	0x0dd8, 0x0dde,
+	0x0df2, 0x0df3,
+	0x0e33, 0x0e33,
+	0x0eb3, 0x0eb3,
+	0x0f3e, 0x0f3f,
+	0x0f7f, 0x0f7f,
+	0x1031, 0x1031,
+	0x103b, 0x103c,
+	0x1056, 0x1057,
+	0x1084, 0x1084,
+	0x17b6, 0x17b6,
+	0x17be, 0x17c5,
+	0x17c7, 0x17c8,
+	0x1923, 0x1926,
+	0x1929, 0x192b,
+	0x1930, 0x1931,
+	0x1933, 0x1938,
+	0x1a19, 0x1a1a,
+	0x1a55, 0x1a55,
+	0x1a57, 0x1a57,
+	0x1a6d, 0x1a72,
+	0x1b04, 0x1b04,
+	0x1b35, 0x1b35,
+	0x1b3b, 0x1b3b,
+	0x1b3d, 0x1b41,
+	0x1b43, 0x1b44,
+	0x1b82, 0x1b82,
+	0x1ba1, 0x1ba1,
+	0x1ba6, 0x1ba7,
+	0x1baa, 0x1baa,
+	0x1be7, 0x1be7,
+	0x1bea, 0x1bec,
+	0x1bee, 0x1bee,
+	0x1bf2, 0x1bf3,
+	0x1c24, 0x1c2b,
+	0x1c34, 0x1c35,
+	0x1ce1, 0x1ce1,
+	0x1cf2, 0x1cf3,
+	0x1cf7, 0x1cf7,
+	0xa823, 0xa824,
+	0xa827, 0xa827,
+	0xa880, 0xa881,
+	0xa8b4, 0xa8c3,
+	0xa952, 0xa953,
+	0xa983, 0xa983,
+	0xa9b4, 0xa9b5,
+	0xa9ba, 0xa9bb,
+	0xa9bd, 0xa9c0,
+	0xaa2f, 0xaa30,
+	0xaa33, 0xaa34,
+	0xaa4d, 0xaa4d,
+	0xaaeb, 0xaaeb,
+	0xaaee, 0xaaef,
+	0xaaf5, 0xaaf5,
+	0xabe3, 0xabe4,
+	0xabe6, 0xabe7,
+	0xabe9, 0xabea,
+	0xabec, 0xabec,
+	0x11000, 0x11000,
+	0x11002, 0x11002,
+	0x11082, 0x11082,
+	0x110b0, 0x110b2,
+	0x110b7, 0x110b8,
+	0x1112c, 0x1112c,
+	0x11182, 0x11182,
+	0x111b3, 0x111b5,
+	0x111bf, 0x111c0,
+	0x1122c, 0x1122e,
+	0x11232, 0x11233,
+	0x11235, 0x11235,
+	0x112e0, 0x112e2,
+	0x11302, 0x11303,
+	0x1133f, 0x1133f,
+	0x11341, 0x11344,
+	0x11347, 0x11348,
+	0x1134b, 0x1134d,
+	0x11362, 0x11363,
+	0x11435, 0x11437,
+	0x11440, 0x11441,
+	0x11445, 0x11445,
+	0x114b1, 0x114b2,
+	0x114b9, 0x114b9,
+	0x114bb, 0x114bc,
+	0x114be, 0x114be,
+	0x114c1, 0x114c1,
+	0x115b0, 0x115b1,
+	0x115b8, 0x115bb,
+	0x115be, 0x115be,
+	0x11630, 0x11632,
+	0x1163b, 0x1163c,
+	0x1163e, 0x1163e,
+	0x116ac, 0x116ac,
+	0x116ae, 0x116af,
+	0x116b6, 0x116b6,
+	0x11720, 0x11721,
+	0x11726, 0x11726,
+	0x11a07, 0x11a08,
+	0x11a39, 0x11a39,
+	0x11a57, 0x11a58,
+	0x11a97, 0x11a97,
+	0x11c2f, 0x11c2f,
+	0x11c3e, 0x11c3e,
+	0x11ca9, 0x11ca9,
+	0x11cb1, 0x11cb1,
+	0x11cb4, 0x11cb4,
+	0x16f51, 0x16f7e,
+	0x1d166, 0x1d166,
+	0x1d16d, 0x1d16d,
+}; /* CR_Grapheme_Cluster_Break_SpacingMark */
+
+/* 'Grapheme_Cluster_Break_L': Grapheme_Cluster_Break=L */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_L[] = {
+	2,
+	0x1100, 0x115f,
+	0xa960, 0xa97c,
+}; /* CR_Grapheme_Cluster_Break_L */
+
+/* 'Grapheme_Cluster_Break_V': Grapheme_Cluster_Break=V */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_V[] = {
+	2,
+	0x1160, 0x11a7,
+	0xd7b0, 0xd7c6,
+}; /* CR_Grapheme_Cluster_Break_V */
+
+/* 'Grapheme_Cluster_Break_T': Grapheme_Cluster_Break=T */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_T[] = {
+	2,
+	0x11a8, 0x11ff,
+	0xd7cb, 0xd7fb,
+}; /* CR_Grapheme_Cluster_Break_T */
+
+/* 'Grapheme_Cluster_Break_LV': Grapheme_Cluster_Break=LV */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_LV[] = {
+	399,
+	0xac00, 0xac00,
+	0xac1c, 0xac1c,
+	0xac38, 0xac38,
+	0xac54, 0xac54,
+	0xac70, 0xac70,
+	0xac8c, 0xac8c,
+	0xaca8, 0xaca8,
+	0xacc4, 0xacc4,
+	0xace0, 0xace0,
+	0xacfc, 0xacfc,
+	0xad18, 0xad18,
+	0xad34, 0xad34,
+	0xad50, 0xad50,
+	0xad6c, 0xad6c,
+	0xad88, 0xad88,
+	0xada4, 0xada4,
+	0xadc0, 0xadc0,
+	0xaddc, 0xaddc,
+	0xadf8, 0xadf8,
+	0xae14, 0xae14,
+	0xae30, 0xae30,
+	0xae4c, 0xae4c,
+	0xae68, 0xae68,
+	0xae84, 0xae84,
+	0xaea0, 0xaea0,
+	0xaebc, 0xaebc,
+	0xaed8, 0xaed8,
+	0xaef4, 0xaef4,
+	0xaf10, 0xaf10,
+	0xaf2c, 0xaf2c,
+	0xaf48, 0xaf48,
+	0xaf64, 0xaf64,
+	0xaf80, 0xaf80,
+	0xaf9c, 0xaf9c,
+	0xafb8, 0xafb8,
+	0xafd4, 0xafd4,
+	0xaff0, 0xaff0,
+	0xb00c, 0xb00c,
+	0xb028, 0xb028,
+	0xb044, 0xb044,
+	0xb060, 0xb060,
+	0xb07c, 0xb07c,
+	0xb098, 0xb098,
+	0xb0b4, 0xb0b4,
+	0xb0d0, 0xb0d0,
+	0xb0ec, 0xb0ec,
+	0xb108, 0xb108,
+	0xb124, 0xb124,
+	0xb140, 0xb140,
+	0xb15c, 0xb15c,
+	0xb178, 0xb178,
+	0xb194, 0xb194,
+	0xb1b0, 0xb1b0,
+	0xb1cc, 0xb1cc,
+	0xb1e8, 0xb1e8,
+	0xb204, 0xb204,
+	0xb220, 0xb220,
+	0xb23c, 0xb23c,
+	0xb258, 0xb258,
+	0xb274, 0xb274,
+	0xb290, 0xb290,
+	0xb2ac, 0xb2ac,
+	0xb2c8, 0xb2c8,
+	0xb2e4, 0xb2e4,
+	0xb300, 0xb300,
+	0xb31c, 0xb31c,
+	0xb338, 0xb338,
+	0xb354, 0xb354,
+	0xb370, 0xb370,
+	0xb38c, 0xb38c,
+	0xb3a8, 0xb3a8,
+	0xb3c4, 0xb3c4,
+	0xb3e0, 0xb3e0,
+	0xb3fc, 0xb3fc,
+	0xb418, 0xb418,
+	0xb434, 0xb434,
+	0xb450, 0xb450,
+	0xb46c, 0xb46c,
+	0xb488, 0xb488,
+	0xb4a4, 0xb4a4,
+	0xb4c0, 0xb4c0,
+	0xb4dc, 0xb4dc,
+	0xb4f8, 0xb4f8,
+	0xb514, 0xb514,
+	0xb530, 0xb530,
+	0xb54c, 0xb54c,
+	0xb568, 0xb568,
+	0xb584, 0xb584,
+	0xb5a0, 0xb5a0,
+	0xb5bc, 0xb5bc,
+	0xb5d8, 0xb5d8,
+	0xb5f4, 0xb5f4,
+	0xb610, 0xb610,
+	0xb62c, 0xb62c,
+	0xb648, 0xb648,
+	0xb664, 0xb664,
+	0xb680, 0xb680,
+	0xb69c, 0xb69c,
+	0xb6b8, 0xb6b8,
+	0xb6d4, 0xb6d4,
+	0xb6f0, 0xb6f0,
+	0xb70c, 0xb70c,
+	0xb728, 0xb728,
+	0xb744, 0xb744,
+	0xb760, 0xb760,
+	0xb77c, 0xb77c,
+	0xb798, 0xb798,
+	0xb7b4, 0xb7b4,
+	0xb7d0, 0xb7d0,
+	0xb7ec, 0xb7ec,
+	0xb808, 0xb808,
+	0xb824, 0xb824,
+	0xb840, 0xb840,
+	0xb85c, 0xb85c,
+	0xb878, 0xb878,
+	0xb894, 0xb894,
+	0xb8b0, 0xb8b0,
+	0xb8cc, 0xb8cc,
+	0xb8e8, 0xb8e8,
+	0xb904, 0xb904,
+	0xb920, 0xb920,
+	0xb93c, 0xb93c,
+	0xb958, 0xb958,
+	0xb974, 0xb974,
+	0xb990, 0xb990,
+	0xb9ac, 0xb9ac,
+	0xb9c8, 0xb9c8,
+	0xb9e4, 0xb9e4,
+	0xba00, 0xba00,
+	0xba1c, 0xba1c,
+	0xba38, 0xba38,
+	0xba54, 0xba54,
+	0xba70, 0xba70,
+	0xba8c, 0xba8c,
+	0xbaa8, 0xbaa8,
+	0xbac4, 0xbac4,
+	0xbae0, 0xbae0,
+	0xbafc, 0xbafc,
+	0xbb18, 0xbb18,
+	0xbb34, 0xbb34,
+	0xbb50, 0xbb50,
+	0xbb6c, 0xbb6c,
+	0xbb88, 0xbb88,
+	0xbba4, 0xbba4,
+	0xbbc0, 0xbbc0,
+	0xbbdc, 0xbbdc,
+	0xbbf8, 0xbbf8,
+	0xbc14, 0xbc14,
+	0xbc30, 0xbc30,
+	0xbc4c, 0xbc4c,
+	0xbc68, 0xbc68,
+	0xbc84, 0xbc84,
+	0xbca0, 0xbca0,
+	0xbcbc, 0xbcbc,
+	0xbcd8, 0xbcd8,
+	0xbcf4, 0xbcf4,
+	0xbd10, 0xbd10,
+	0xbd2c, 0xbd2c,
+	0xbd48, 0xbd48,
+	0xbd64, 0xbd64,
+	0xbd80, 0xbd80,
+	0xbd9c, 0xbd9c,
+	0xbdb8, 0xbdb8,
+	0xbdd4, 0xbdd4,
+	0xbdf0, 0xbdf0,
+	0xbe0c, 0xbe0c,
+	0xbe28, 0xbe28,
+	0xbe44, 0xbe44,
+	0xbe60, 0xbe60,
+	0xbe7c, 0xbe7c,
+	0xbe98, 0xbe98,
+	0xbeb4, 0xbeb4,
+	0xbed0, 0xbed0,
+	0xbeec, 0xbeec,
+	0xbf08, 0xbf08,
+	0xbf24, 0xbf24,
+	0xbf40, 0xbf40,
+	0xbf5c, 0xbf5c,
+	0xbf78, 0xbf78,
+	0xbf94, 0xbf94,
+	0xbfb0, 0xbfb0,
+	0xbfcc, 0xbfcc,
+	0xbfe8, 0xbfe8,
+	0xc004, 0xc004,
+	0xc020, 0xc020,
+	0xc03c, 0xc03c,
+	0xc058, 0xc058,
+	0xc074, 0xc074,
+	0xc090, 0xc090,
+	0xc0ac, 0xc0ac,
+	0xc0c8, 0xc0c8,
+	0xc0e4, 0xc0e4,
+	0xc100, 0xc100,
+	0xc11c, 0xc11c,
+	0xc138, 0xc138,
+	0xc154, 0xc154,
+	0xc170, 0xc170,
+	0xc18c, 0xc18c,
+	0xc1a8, 0xc1a8,
+	0xc1c4, 0xc1c4,
+	0xc1e0, 0xc1e0,
+	0xc1fc, 0xc1fc,
+	0xc218, 0xc218,
+	0xc234, 0xc234,
+	0xc250, 0xc250,
+	0xc26c, 0xc26c,
+	0xc288, 0xc288,
+	0xc2a4, 0xc2a4,
+	0xc2c0, 0xc2c0,
+	0xc2dc, 0xc2dc,
+	0xc2f8, 0xc2f8,
+	0xc314, 0xc314,
+	0xc330, 0xc330,
+	0xc34c, 0xc34c,
+	0xc368, 0xc368,
+	0xc384, 0xc384,
+	0xc3a0, 0xc3a0,
+	0xc3bc, 0xc3bc,
+	0xc3d8, 0xc3d8,
+	0xc3f4, 0xc3f4,
+	0xc410, 0xc410,
+	0xc42c, 0xc42c,
+	0xc448, 0xc448,
+	0xc464, 0xc464,
+	0xc480, 0xc480,
+	0xc49c, 0xc49c,
+	0xc4b8, 0xc4b8,
+	0xc4d4, 0xc4d4,
+	0xc4f0, 0xc4f0,
+	0xc50c, 0xc50c,
+	0xc528, 0xc528,
+	0xc544, 0xc544,
+	0xc560, 0xc560,
+	0xc57c, 0xc57c,
+	0xc598, 0xc598,
+	0xc5b4, 0xc5b4,
+	0xc5d0, 0xc5d0,
+	0xc5ec, 0xc5ec,
+	0xc608, 0xc608,
+	0xc624, 0xc624,
+	0xc640, 0xc640,
+	0xc65c, 0xc65c,
+	0xc678, 0xc678,
+	0xc694, 0xc694,
+	0xc6b0, 0xc6b0,
+	0xc6cc, 0xc6cc,
+	0xc6e8, 0xc6e8,
+	0xc704, 0xc704,
+	0xc720, 0xc720,
+	0xc73c, 0xc73c,
+	0xc758, 0xc758,
+	0xc774, 0xc774,
+	0xc790, 0xc790,
+	0xc7ac, 0xc7ac,
+	0xc7c8, 0xc7c8,
+	0xc7e4, 0xc7e4,
+	0xc800, 0xc800,
+	0xc81c, 0xc81c,
+	0xc838, 0xc838,
+	0xc854, 0xc854,
+	0xc870, 0xc870,
+	0xc88c, 0xc88c,
+	0xc8a8, 0xc8a8,
+	0xc8c4, 0xc8c4,
+	0xc8e0, 0xc8e0,
+	0xc8fc, 0xc8fc,
+	0xc918, 0xc918,
+	0xc934, 0xc934,
+	0xc950, 0xc950,
+	0xc96c, 0xc96c,
+	0xc988, 0xc988,
+	0xc9a4, 0xc9a4,
+	0xc9c0, 0xc9c0,
+	0xc9dc, 0xc9dc,
+	0xc9f8, 0xc9f8,
+	0xca14, 0xca14,
+	0xca30, 0xca30,
+	0xca4c, 0xca4c,
+	0xca68, 0xca68,
+	0xca84, 0xca84,
+	0xcaa0, 0xcaa0,
+	0xcabc, 0xcabc,
+	0xcad8, 0xcad8,
+	0xcaf4, 0xcaf4,
+	0xcb10, 0xcb10,
+	0xcb2c, 0xcb2c,
+	0xcb48, 0xcb48,
+	0xcb64, 0xcb64,
+	0xcb80, 0xcb80,
+	0xcb9c, 0xcb9c,
+	0xcbb8, 0xcbb8,
+	0xcbd4, 0xcbd4,
+	0xcbf0, 0xcbf0,
+	0xcc0c, 0xcc0c,
+	0xcc28, 0xcc28,
+	0xcc44, 0xcc44,
+	0xcc60, 0xcc60,
+	0xcc7c, 0xcc7c,
+	0xcc98, 0xcc98,
+	0xccb4, 0xccb4,
+	0xccd0, 0xccd0,
+	0xccec, 0xccec,
+	0xcd08, 0xcd08,
+	0xcd24, 0xcd24,
+	0xcd40, 0xcd40,
+	0xcd5c, 0xcd5c,
+	0xcd78, 0xcd78,
+	0xcd94, 0xcd94,
+	0xcdb0, 0xcdb0,
+	0xcdcc, 0xcdcc,
+	0xcde8, 0xcde8,
+	0xce04, 0xce04,
+	0xce20, 0xce20,
+	0xce3c, 0xce3c,
+	0xce58, 0xce58,
+	0xce74, 0xce74,
+	0xce90, 0xce90,
+	0xceac, 0xceac,
+	0xcec8, 0xcec8,
+	0xcee4, 0xcee4,
+	0xcf00, 0xcf00,
+	0xcf1c, 0xcf1c,
+	0xcf38, 0xcf38,
+	0xcf54, 0xcf54,
+	0xcf70, 0xcf70,
+	0xcf8c, 0xcf8c,
+	0xcfa8, 0xcfa8,
+	0xcfc4, 0xcfc4,
+	0xcfe0, 0xcfe0,
+	0xcffc, 0xcffc,
+	0xd018, 0xd018,
+	0xd034, 0xd034,
+	0xd050, 0xd050,
+	0xd06c, 0xd06c,
+	0xd088, 0xd088,
+	0xd0a4, 0xd0a4,
+	0xd0c0, 0xd0c0,
+	0xd0dc, 0xd0dc,
+	0xd0f8, 0xd0f8,
+	0xd114, 0xd114,
+	0xd130, 0xd130,
+	0xd14c, 0xd14c,
+	0xd168, 0xd168,
+	0xd184, 0xd184,
+	0xd1a0, 0xd1a0,
+	0xd1bc, 0xd1bc,
+	0xd1d8, 0xd1d8,
+	0xd1f4, 0xd1f4,
+	0xd210, 0xd210,
+	0xd22c, 0xd22c,
+	0xd248, 0xd248,
+	0xd264, 0xd264,
+	0xd280, 0xd280,
+	0xd29c, 0xd29c,
+	0xd2b8, 0xd2b8,
+	0xd2d4, 0xd2d4,
+	0xd2f0, 0xd2f0,
+	0xd30c, 0xd30c,
+	0xd328, 0xd328,
+	0xd344, 0xd344,
+	0xd360, 0xd360,
+	0xd37c, 0xd37c,
+	0xd398, 0xd398,
+	0xd3b4, 0xd3b4,
+	0xd3d0, 0xd3d0,
+	0xd3ec, 0xd3ec,
+	0xd408, 0xd408,
+	0xd424, 0xd424,
+	0xd440, 0xd440,
+	0xd45c, 0xd45c,
+	0xd478, 0xd478,
+	0xd494, 0xd494,
+	0xd4b0, 0xd4b0,
+	0xd4cc, 0xd4cc,
+	0xd4e8, 0xd4e8,
+	0xd504, 0xd504,
+	0xd520, 0xd520,
+	0xd53c, 0xd53c,
+	0xd558, 0xd558,
+	0xd574, 0xd574,
+	0xd590, 0xd590,
+	0xd5ac, 0xd5ac,
+	0xd5c8, 0xd5c8,
+	0xd5e4, 0xd5e4,
+	0xd600, 0xd600,
+	0xd61c, 0xd61c,
+	0xd638, 0xd638,
+	0xd654, 0xd654,
+	0xd670, 0xd670,
+	0xd68c, 0xd68c,
+	0xd6a8, 0xd6a8,
+	0xd6c4, 0xd6c4,
+	0xd6e0, 0xd6e0,
+	0xd6fc, 0xd6fc,
+	0xd718, 0xd718,
+	0xd734, 0xd734,
+	0xd750, 0xd750,
+	0xd76c, 0xd76c,
+	0xd788, 0xd788,
+}; /* CR_Grapheme_Cluster_Break_LV */
+
+/* 'Grapheme_Cluster_Break_LVT': Grapheme_Cluster_Break=LVT */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_LVT[] = {
+	399,
+	0xac01, 0xac1b,
+	0xac1d, 0xac37,
+	0xac39, 0xac53,
+	0xac55, 0xac6f,
+	0xac71, 0xac8b,
+	0xac8d, 0xaca7,
+	0xaca9, 0xacc3,
+	0xacc5, 0xacdf,
+	0xace1, 0xacfb,
+	0xacfd, 0xad17,
+	0xad19, 0xad33,
+	0xad35, 0xad4f,
+	0xad51, 0xad6b,
+	0xad6d, 0xad87,
+	0xad89, 0xada3,
+	0xada5, 0xadbf,
+	0xadc1, 0xaddb,
+	0xaddd, 0xadf7,
+	0xadf9, 0xae13,
+	0xae15, 0xae2f,
+	0xae31, 0xae4b,
+	0xae4d, 0xae67,
+	0xae69, 0xae83,
+	0xae85, 0xae9f,
+	0xaea1, 0xaebb,
+	0xaebd, 0xaed7,
+	0xaed9, 0xaef3,
+	0xaef5, 0xaf0f,
+	0xaf11, 0xaf2b,
+	0xaf2d, 0xaf47,
+	0xaf49, 0xaf63,
+	0xaf65, 0xaf7f,
+	0xaf81, 0xaf9b,
+	0xaf9d, 0xafb7,
+	0xafb9, 0xafd3,
+	0xafd5, 0xafef,
+	0xaff1, 0xb00b,
+	0xb00d, 0xb027,
+	0xb029, 0xb043,
+	0xb045, 0xb05f,
+	0xb061, 0xb07b,
+	0xb07d, 0xb097,
+	0xb099, 0xb0b3,
+	0xb0b5, 0xb0cf,
+	0xb0d1, 0xb0eb,
+	0xb0ed, 0xb107,
+	0xb109, 0xb123,
+	0xb125, 0xb13f,
+	0xb141, 0xb15b,
+	0xb15d, 0xb177,
+	0xb179, 0xb193,
+	0xb195, 0xb1af,
+	0xb1b1, 0xb1cb,
+	0xb1cd, 0xb1e7,
+	0xb1e9, 0xb203,
+	0xb205, 0xb21f,
+	0xb221, 0xb23b,
+	0xb23d, 0xb257,
+	0xb259, 0xb273,
+	0xb275, 0xb28f,
+	0xb291, 0xb2ab,
+	0xb2ad, 0xb2c7,
+	0xb2c9, 0xb2e3,
+	0xb2e5, 0xb2ff,
+	0xb301, 0xb31b,
+	0xb31d, 0xb337,
+	0xb339, 0xb353,
+	0xb355, 0xb36f,
+	0xb371, 0xb38b,
+	0xb38d, 0xb3a7,
+	0xb3a9, 0xb3c3,
+	0xb3c5, 0xb3df,
+	0xb3e1, 0xb3fb,
+	0xb3fd, 0xb417,
+	0xb419, 0xb433,
+	0xb435, 0xb44f,
+	0xb451, 0xb46b,
+	0xb46d, 0xb487,
+	0xb489, 0xb4a3,
+	0xb4a5, 0xb4bf,
+	0xb4c1, 0xb4db,
+	0xb4dd, 0xb4f7,
+	0xb4f9, 0xb513,
+	0xb515, 0xb52f,
+	0xb531, 0xb54b,
+	0xb54d, 0xb567,
+	0xb569, 0xb583,
+	0xb585, 0xb59f,
+	0xb5a1, 0xb5bb,
+	0xb5bd, 0xb5d7,
+	0xb5d9, 0xb5f3,
+	0xb5f5, 0xb60f,
+	0xb611, 0xb62b,
+	0xb62d, 0xb647,
+	0xb649, 0xb663,
+	0xb665, 0xb67f,
+	0xb681, 0xb69b,
+	0xb69d, 0xb6b7,
+	0xb6b9, 0xb6d3,
+	0xb6d5, 0xb6ef,
+	0xb6f1, 0xb70b,
+	0xb70d, 0xb727,
+	0xb729, 0xb743,
+	0xb745, 0xb75f,
+	0xb761, 0xb77b,
+	0xb77d, 0xb797,
+	0xb799, 0xb7b3,
+	0xb7b5, 0xb7cf,
+	0xb7d1, 0xb7eb,
+	0xb7ed, 0xb807,
+	0xb809, 0xb823,
+	0xb825, 0xb83f,
+	0xb841, 0xb85b,
+	0xb85d, 0xb877,
+	0xb879, 0xb893,
+	0xb895, 0xb8af,
+	0xb8b1, 0xb8cb,
+	0xb8cd, 0xb8e7,
+	0xb8e9, 0xb903,
+	0xb905, 0xb91f,
+	0xb921, 0xb93b,
+	0xb93d, 0xb957,
+	0xb959, 0xb973,
+	0xb975, 0xb98f,
+	0xb991, 0xb9ab,
+	0xb9ad, 0xb9c7,
+	0xb9c9, 0xb9e3,
+	0xb9e5, 0xb9ff,
+	0xba01, 0xba1b,
+	0xba1d, 0xba37,
+	0xba39, 0xba53,
+	0xba55, 0xba6f,
+	0xba71, 0xba8b,
+	0xba8d, 0xbaa7,
+	0xbaa9, 0xbac3,
+	0xbac5, 0xbadf,
+	0xbae1, 0xbafb,
+	0xbafd, 0xbb17,
+	0xbb19, 0xbb33,
+	0xbb35, 0xbb4f,
+	0xbb51, 0xbb6b,
+	0xbb6d, 0xbb87,
+	0xbb89, 0xbba3,
+	0xbba5, 0xbbbf,
+	0xbbc1, 0xbbdb,
+	0xbbdd, 0xbbf7,
+	0xbbf9, 0xbc13,
+	0xbc15, 0xbc2f,
+	0xbc31, 0xbc4b,
+	0xbc4d, 0xbc67,
+	0xbc69, 0xbc83,
+	0xbc85, 0xbc9f,
+	0xbca1, 0xbcbb,
+	0xbcbd, 0xbcd7,
+	0xbcd9, 0xbcf3,
+	0xbcf5, 0xbd0f,
+	0xbd11, 0xbd2b,
+	0xbd2d, 0xbd47,
+	0xbd49, 0xbd63,
+	0xbd65, 0xbd7f,
+	0xbd81, 0xbd9b,
+	0xbd9d, 0xbdb7,
+	0xbdb9, 0xbdd3,
+	0xbdd5, 0xbdef,
+	0xbdf1, 0xbe0b,
+	0xbe0d, 0xbe27,
+	0xbe29, 0xbe43,
+	0xbe45, 0xbe5f,
+	0xbe61, 0xbe7b,
+	0xbe7d, 0xbe97,
+	0xbe99, 0xbeb3,
+	0xbeb5, 0xbecf,
+	0xbed1, 0xbeeb,
+	0xbeed, 0xbf07,
+	0xbf09, 0xbf23,
+	0xbf25, 0xbf3f,
+	0xbf41, 0xbf5b,
+	0xbf5d, 0xbf77,
+	0xbf79, 0xbf93,
+	0xbf95, 0xbfaf,
+	0xbfb1, 0xbfcb,
+	0xbfcd, 0xbfe7,
+	0xbfe9, 0xc003,
+	0xc005, 0xc01f,
+	0xc021, 0xc03b,
+	0xc03d, 0xc057,
+	0xc059, 0xc073,
+	0xc075, 0xc08f,
+	0xc091, 0xc0ab,
+	0xc0ad, 0xc0c7,
+	0xc0c9, 0xc0e3,
+	0xc0e5, 0xc0ff,
+	0xc101, 0xc11b,
+	0xc11d, 0xc137,
+	0xc139, 0xc153,
+	0xc155, 0xc16f,
+	0xc171, 0xc18b,
+	0xc18d, 0xc1a7,
+	0xc1a9, 0xc1c3,
+	0xc1c5, 0xc1df,
+	0xc1e1, 0xc1fb,
+	0xc1fd, 0xc217,
+	0xc219, 0xc233,
+	0xc235, 0xc24f,
+	0xc251, 0xc26b,
+	0xc26d, 0xc287,
+	0xc289, 0xc2a3,
+	0xc2a5, 0xc2bf,
+	0xc2c1, 0xc2db,
+	0xc2dd, 0xc2f7,
+	0xc2f9, 0xc313,
+	0xc315, 0xc32f,
+	0xc331, 0xc34b,
+	0xc34d, 0xc367,
+	0xc369, 0xc383,
+	0xc385, 0xc39f,
+	0xc3a1, 0xc3bb,
+	0xc3bd, 0xc3d7,
+	0xc3d9, 0xc3f3,
+	0xc3f5, 0xc40f,
+	0xc411, 0xc42b,
+	0xc42d, 0xc447,
+	0xc449, 0xc463,
+	0xc465, 0xc47f,
+	0xc481, 0xc49b,
+	0xc49d, 0xc4b7,
+	0xc4b9, 0xc4d3,
+	0xc4d5, 0xc4ef,
+	0xc4f1, 0xc50b,
+	0xc50d, 0xc527,
+	0xc529, 0xc543,
+	0xc545, 0xc55f,
+	0xc561, 0xc57b,
+	0xc57d, 0xc597,
+	0xc599, 0xc5b3,
+	0xc5b5, 0xc5cf,
+	0xc5d1, 0xc5eb,
+	0xc5ed, 0xc607,
+	0xc609, 0xc623,
+	0xc625, 0xc63f,
+	0xc641, 0xc65b,
+	0xc65d, 0xc677,
+	0xc679, 0xc693,
+	0xc695, 0xc6af,
+	0xc6b1, 0xc6cb,
+	0xc6cd, 0xc6e7,
+	0xc6e9, 0xc703,
+	0xc705, 0xc71f,
+	0xc721, 0xc73b,
+	0xc73d, 0xc757,
+	0xc759, 0xc773,
+	0xc775, 0xc78f,
+	0xc791, 0xc7ab,
+	0xc7ad, 0xc7c7,
+	0xc7c9, 0xc7e3,
+	0xc7e5, 0xc7ff,
+	0xc801, 0xc81b,
+	0xc81d, 0xc837,
+	0xc839, 0xc853,
+	0xc855, 0xc86f,
+	0xc871, 0xc88b,
+	0xc88d, 0xc8a7,
+	0xc8a9, 0xc8c3,
+	0xc8c5, 0xc8df,
+	0xc8e1, 0xc8fb,
+	0xc8fd, 0xc917,
+	0xc919, 0xc933,
+	0xc935, 0xc94f,
+	0xc951, 0xc96b,
+	0xc96d, 0xc987,
+	0xc989, 0xc9a3,
+	0xc9a5, 0xc9bf,
+	0xc9c1, 0xc9db,
+	0xc9dd, 0xc9f7,
+	0xc9f9, 0xca13,
+	0xca15, 0xca2f,
+	0xca31, 0xca4b,
+	0xca4d, 0xca67,
+	0xca69, 0xca83,
+	0xca85, 0xca9f,
+	0xcaa1, 0xcabb,
+	0xcabd, 0xcad7,
+	0xcad9, 0xcaf3,
+	0xcaf5, 0xcb0f,
+	0xcb11, 0xcb2b,
+	0xcb2d, 0xcb47,
+	0xcb49, 0xcb63,
+	0xcb65, 0xcb7f,
+	0xcb81, 0xcb9b,
+	0xcb9d, 0xcbb7,
+	0xcbb9, 0xcbd3,
+	0xcbd5, 0xcbef,
+	0xcbf1, 0xcc0b,
+	0xcc0d, 0xcc27,
+	0xcc29, 0xcc43,
+	0xcc45, 0xcc5f,
+	0xcc61, 0xcc7b,
+	0xcc7d, 0xcc97,
+	0xcc99, 0xccb3,
+	0xccb5, 0xcccf,
+	0xccd1, 0xcceb,
+	0xcced, 0xcd07,
+	0xcd09, 0xcd23,
+	0xcd25, 0xcd3f,
+	0xcd41, 0xcd5b,
+	0xcd5d, 0xcd77,
+	0xcd79, 0xcd93,
+	0xcd95, 0xcdaf,
+	0xcdb1, 0xcdcb,
+	0xcdcd, 0xcde7,
+	0xcde9, 0xce03,
+	0xce05, 0xce1f,
+	0xce21, 0xce3b,
+	0xce3d, 0xce57,
+	0xce59, 0xce73,
+	0xce75, 0xce8f,
+	0xce91, 0xceab,
+	0xcead, 0xcec7,
+	0xcec9, 0xcee3,
+	0xcee5, 0xceff,
+	0xcf01, 0xcf1b,
+	0xcf1d, 0xcf37,
+	0xcf39, 0xcf53,
+	0xcf55, 0xcf6f,
+	0xcf71, 0xcf8b,
+	0xcf8d, 0xcfa7,
+	0xcfa9, 0xcfc3,
+	0xcfc5, 0xcfdf,
+	0xcfe1, 0xcffb,
+	0xcffd, 0xd017,
+	0xd019, 0xd033,
+	0xd035, 0xd04f,
+	0xd051, 0xd06b,
+	0xd06d, 0xd087,
+	0xd089, 0xd0a3,
+	0xd0a5, 0xd0bf,
+	0xd0c1, 0xd0db,
+	0xd0dd, 0xd0f7,
+	0xd0f9, 0xd113,
+	0xd115, 0xd12f,
+	0xd131, 0xd14b,
+	0xd14d, 0xd167,
+	0xd169, 0xd183,
+	0xd185, 0xd19f,
+	0xd1a1, 0xd1bb,
+	0xd1bd, 0xd1d7,
+	0xd1d9, 0xd1f3,
+	0xd1f5, 0xd20f,
+	0xd211, 0xd22b,
+	0xd22d, 0xd247,
+	0xd249, 0xd263,
+	0xd265, 0xd27f,
+	0xd281, 0xd29b,
+	0xd29d, 0xd2b7,
+	0xd2b9, 0xd2d3,
+	0xd2d5, 0xd2ef,
+	0xd2f1, 0xd30b,
+	0xd30d, 0xd327,
+	0xd329, 0xd343,
+	0xd345, 0xd35f,
+	0xd361, 0xd37b,
+	0xd37d, 0xd397,
+	0xd399, 0xd3b3,
+	0xd3b5, 0xd3cf,
+	0xd3d1, 0xd3eb,
+	0xd3ed, 0xd407,
+	0xd409, 0xd423,
+	0xd425, 0xd43f,
+	0xd441, 0xd45b,
+	0xd45d, 0xd477,
+	0xd479, 0xd493,
+	0xd495, 0xd4af,
+	0xd4b1, 0xd4cb,
+	0xd4cd, 0xd4e7,
+	0xd4e9, 0xd503,
+	0xd505, 0xd51f,
+	0xd521, 0xd53b,
+	0xd53d, 0xd557,
+	0xd559, 0xd573,
+	0xd575, 0xd58f,
+	0xd591, 0xd5ab,
+	0xd5ad, 0xd5c7,
+	0xd5c9, 0xd5e3,
+	0xd5e5, 0xd5ff,
+	0xd601, 0xd61b,
+	0xd61d, 0xd637,
+	0xd639, 0xd653,
+	0xd655, 0xd66f,
+	0xd671, 0xd68b,
+	0xd68d, 0xd6a7,
+	0xd6a9, 0xd6c3,
+	0xd6c5, 0xd6df,
+	0xd6e1, 0xd6fb,
+	0xd6fd, 0xd717,
+	0xd719, 0xd733,
+	0xd735, 0xd74f,
+	0xd751, 0xd76b,
+	0xd76d, 0xd787,
+	0xd789, 0xd7a3,
+}; /* CR_Grapheme_Cluster_Break_LVT */
+
+/* 'Grapheme_Cluster_Break_E_Base': Grapheme_Cluster_Break=E_Base */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_E_Base[] = {
+	31,
+	0x261d, 0x261d,
+	0x26f9, 0x26f9,
+	0x270a, 0x270d,
+	0x1f385, 0x1f385,
+	0x1f3c2, 0x1f3c4,
+	0x1f3c7, 0x1f3c7,
+	0x1f3ca, 0x1f3cc,
+	0x1f442, 0x1f443,
+	0x1f446, 0x1f450,
+	0x1f46e, 0x1f46e,
+	0x1f470, 0x1f478,
+	0x1f47c, 0x1f47c,
+	0x1f481, 0x1f483,
+	0x1f485, 0x1f487,
+	0x1f4aa, 0x1f4aa,
+	0x1f574, 0x1f575,
+	0x1f57a, 0x1f57a,
+	0x1f590, 0x1f590,
+	0x1f595, 0x1f596,
+	0x1f645, 0x1f647,
+	0x1f64b, 0x1f64f,
+	0x1f6a3, 0x1f6a3,
+	0x1f6b4, 0x1f6b6,
+	0x1f6c0, 0x1f6c0,
+	0x1f6cc, 0x1f6cc,
+	0x1f918, 0x1f91c,
+	0x1f91e, 0x1f91f,
+	0x1f926, 0x1f926,
+	0x1f930, 0x1f939,
+	0x1f93d, 0x1f93e,
+	0x1f9d1, 0x1f9dd,
+}; /* CR_Grapheme_Cluster_Break_E_Base */
+
+/* 'Grapheme_Cluster_Break_E_Modifier': Grapheme_Cluster_Break=E_Modifier */
+#define CR_Grapheme_Cluster_Break_E_Modifier CR_Emoji_Modifier
+
+/* 'Grapheme_Cluster_Break_ZWJ': Grapheme_Cluster_Break=ZWJ */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_ZWJ[] = {
+	1,
+	0x200d, 0x200d,
+}; /* CR_Grapheme_Cluster_Break_ZWJ */
+
+/* 'Grapheme_Cluster_Break_Glue_After_Zwj': Grapheme_Cluster_Break=Glue_After_Zwj */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_Glue_After_Zwj[] = {
+	20,
+	0x2640, 0x2640,
+	0x2642, 0x2642,
+	0x2695, 0x2696,
+	0x2708, 0x2708,
+	0x2764, 0x2764,
+	0x1f308, 0x1f308,
+	0x1f33e, 0x1f33e,
+	0x1f373, 0x1f373,
+	0x1f393, 0x1f393,
+	0x1f3a4, 0x1f3a4,
+	0x1f3a8, 0x1f3a8,
+	0x1f3eb, 0x1f3eb,
+	0x1f3ed, 0x1f3ed,
+	0x1f48b, 0x1f48b,
+	0x1f4bb, 0x1f4bc,
+	0x1f527, 0x1f527,
+	0x1f52c, 0x1f52c,
+	0x1f5e8, 0x1f5e8,
+	0x1f680, 0x1f680,
+	0x1f692, 0x1f692,
+}; /* CR_Grapheme_Cluster_Break_Glue_After_Zwj */
+
+/* 'Grapheme_Cluster_Break_E_Base_GAZ': Grapheme_Cluster_Break=E_Base_GAZ */
+static const OnigCodePoint CR_Grapheme_Cluster_Break_E_Base_GAZ[] = {
+	1,
+	0x1f466, 0x1f469,
+}; /* CR_Grapheme_Cluster_Break_E_Base_GAZ */
+
+/* 'In_Basic_Latin': Block */
+#define CR_In_Basic_Latin CR_ASCII
+
+/* 'In_Latin_1_Supplement': Block */
+static const OnigCodePoint CR_In_Latin_1_Supplement[] = {
+	1,
+	0x0080, 0x00ff,
+}; /* CR_In_Latin_1_Supplement */
+
+/* 'In_Latin_Extended_A': Block */
+static const OnigCodePoint CR_In_Latin_Extended_A[] = {
+	1,
+	0x0100, 0x017f,
+}; /* CR_In_Latin_Extended_A */
+
+/* 'In_Latin_Extended_B': Block */
+static const OnigCodePoint CR_In_Latin_Extended_B[] = {
+	1,
+	0x0180, 0x024f,
+}; /* CR_In_Latin_Extended_B */
+
+/* 'In_IPA_Extensions': Block */
+static const OnigCodePoint CR_In_IPA_Extensions[] = {
+	1,
+	0x0250, 0x02af,
+}; /* CR_In_IPA_Extensions */
+
+/* 'In_Spacing_Modifier_Letters': Block */
+static const OnigCodePoint CR_In_Spacing_Modifier_Letters[] = {
+	1,
+	0x02b0, 0x02ff,
+}; /* CR_In_Spacing_Modifier_Letters */
+
+/* 'In_Combining_Diacritical_Marks': Block */
+static const OnigCodePoint CR_In_Combining_Diacritical_Marks[] = {
+	1,
+	0x0300, 0x036f,
+}; /* CR_In_Combining_Diacritical_Marks */
+
+/* 'In_Greek_and_Coptic': Block */
+static const OnigCodePoint CR_In_Greek_and_Coptic[] = {
+	1,
+	0x0370, 0x03ff,
+}; /* CR_In_Greek_and_Coptic */
+
+/* 'In_Cyrillic': Block */
+static const OnigCodePoint CR_In_Cyrillic[] = {
+	1,
+	0x0400, 0x04ff,
+}; /* CR_In_Cyrillic */
+
+/* 'In_Cyrillic_Supplement': Block */
+static const OnigCodePoint CR_In_Cyrillic_Supplement[] = {
+	1,
+	0x0500, 0x052f,
+}; /* CR_In_Cyrillic_Supplement */
+
+/* 'In_Armenian': Block */
+static const OnigCodePoint CR_In_Armenian[] = {
+	1,
+	0x0530, 0x058f,
+}; /* CR_In_Armenian */
+
+/* 'In_Hebrew': Block */
+static const OnigCodePoint CR_In_Hebrew[] = {
+	1,
+	0x0590, 0x05ff,
+}; /* CR_In_Hebrew */
+
+/* 'In_Arabic': Block */
+static const OnigCodePoint CR_In_Arabic[] = {
+	1,
+	0x0600, 0x06ff,
+}; /* CR_In_Arabic */
+
+/* 'In_Syriac': Block */
+static const OnigCodePoint CR_In_Syriac[] = {
+	1,
+	0x0700, 0x074f,
+}; /* CR_In_Syriac */
+
+/* 'In_Arabic_Supplement': Block */
+static const OnigCodePoint CR_In_Arabic_Supplement[] = {
+	1,
+	0x0750, 0x077f,
+}; /* CR_In_Arabic_Supplement */
+
+/* 'In_Thaana': Block */
+static const OnigCodePoint CR_In_Thaana[] = {
+	1,
+	0x0780, 0x07bf,
+}; /* CR_In_Thaana */
+
+/* 'In_NKo': Block */
+static const OnigCodePoint CR_In_NKo[] = {
+	1,
+	0x07c0, 0x07ff,
+}; /* CR_In_NKo */
+
+/* 'In_Samaritan': Block */
+static const OnigCodePoint CR_In_Samaritan[] = {
+	1,
+	0x0800, 0x083f,
+}; /* CR_In_Samaritan */
+
+/* 'In_Mandaic': Block */
+static const OnigCodePoint CR_In_Mandaic[] = {
+	1,
+	0x0840, 0x085f,
+}; /* CR_In_Mandaic */
+
+/* 'In_Syriac_Supplement': Block */
+static const OnigCodePoint CR_In_Syriac_Supplement[] = {
+	1,
+	0x0860, 0x086f,
+}; /* CR_In_Syriac_Supplement */
+
+/* 'In_Arabic_Extended_A': Block */
+static const OnigCodePoint CR_In_Arabic_Extended_A[] = {
+	1,
+	0x08a0, 0x08ff,
+}; /* CR_In_Arabic_Extended_A */
+
+/* 'In_Devanagari': Block */
+static const OnigCodePoint CR_In_Devanagari[] = {
+	1,
+	0x0900, 0x097f,
+}; /* CR_In_Devanagari */
+
+/* 'In_Bengali': Block */
+static const OnigCodePoint CR_In_Bengali[] = {
+	1,
+	0x0980, 0x09ff,
+}; /* CR_In_Bengali */
+
+/* 'In_Gurmukhi': Block */
+static const OnigCodePoint CR_In_Gurmukhi[] = {
+	1,
+	0x0a00, 0x0a7f,
+}; /* CR_In_Gurmukhi */
+
+/* 'In_Gujarati': Block */
+static const OnigCodePoint CR_In_Gujarati[] = {
+	1,
+	0x0a80, 0x0aff,
+}; /* CR_In_Gujarati */
+
+/* 'In_Oriya': Block */
+static const OnigCodePoint CR_In_Oriya[] = {
+	1,
+	0x0b00, 0x0b7f,
+}; /* CR_In_Oriya */
+
+/* 'In_Tamil': Block */
+static const OnigCodePoint CR_In_Tamil[] = {
+	1,
+	0x0b80, 0x0bff,
+}; /* CR_In_Tamil */
+
+/* 'In_Telugu': Block */
+static const OnigCodePoint CR_In_Telugu[] = {
+	1,
+	0x0c00, 0x0c7f,
+}; /* CR_In_Telugu */
+
+/* 'In_Kannada': Block */
+static const OnigCodePoint CR_In_Kannada[] = {
+	1,
+	0x0c80, 0x0cff,
+}; /* CR_In_Kannada */
+
+/* 'In_Malayalam': Block */
+static const OnigCodePoint CR_In_Malayalam[] = {
+	1,
+	0x0d00, 0x0d7f,
+}; /* CR_In_Malayalam */
+
+/* 'In_Sinhala': Block */
+static const OnigCodePoint CR_In_Sinhala[] = {
+	1,
+	0x0d80, 0x0dff,
+}; /* CR_In_Sinhala */
+
+/* 'In_Thai': Block */
+static const OnigCodePoint CR_In_Thai[] = {
+	1,
+	0x0e00, 0x0e7f,
+}; /* CR_In_Thai */
+
+/* 'In_Lao': Block */
+static const OnigCodePoint CR_In_Lao[] = {
+	1,
+	0x0e80, 0x0eff,
+}; /* CR_In_Lao */
+
+/* 'In_Tibetan': Block */
+static const OnigCodePoint CR_In_Tibetan[] = {
+	1,
+	0x0f00, 0x0fff,
+}; /* CR_In_Tibetan */
+
+/* 'In_Myanmar': Block */
+static const OnigCodePoint CR_In_Myanmar[] = {
+	1,
+	0x1000, 0x109f,
+}; /* CR_In_Myanmar */
+
+/* 'In_Georgian': Block */
+static const OnigCodePoint CR_In_Georgian[] = {
+	1,
+	0x10a0, 0x10ff,
+}; /* CR_In_Georgian */
+
+/* 'In_Hangul_Jamo': Block */
+static const OnigCodePoint CR_In_Hangul_Jamo[] = {
+	1,
+	0x1100, 0x11ff,
+}; /* CR_In_Hangul_Jamo */
+
+/* 'In_Ethiopic': Block */
+static const OnigCodePoint CR_In_Ethiopic[] = {
+	1,
+	0x1200, 0x137f,
+}; /* CR_In_Ethiopic */
+
+/* 'In_Ethiopic_Supplement': Block */
+static const OnigCodePoint CR_In_Ethiopic_Supplement[] = {
+	1,
+	0x1380, 0x139f,
+}; /* CR_In_Ethiopic_Supplement */
+
+/* 'In_Cherokee': Block */
+static const OnigCodePoint CR_In_Cherokee[] = {
+	1,
+	0x13a0, 0x13ff,
+}; /* CR_In_Cherokee */
+
+/* 'In_Unified_Canadian_Aboriginal_Syllabics': Block */
+static const OnigCodePoint CR_In_Unified_Canadian_Aboriginal_Syllabics[] = {
+	1,
+	0x1400, 0x167f,
+}; /* CR_In_Unified_Canadian_Aboriginal_Syllabics */
+
+/* 'In_Ogham': Block */
+static const OnigCodePoint CR_In_Ogham[] = {
+	1,
+	0x1680, 0x169f,
+}; /* CR_In_Ogham */
+
+/* 'In_Runic': Block */
+static const OnigCodePoint CR_In_Runic[] = {
+	1,
+	0x16a0, 0x16ff,
+}; /* CR_In_Runic */
+
+/* 'In_Tagalog': Block */
+static const OnigCodePoint CR_In_Tagalog[] = {
+	1,
+	0x1700, 0x171f,
+}; /* CR_In_Tagalog */
+
+/* 'In_Hanunoo': Block */
+static const OnigCodePoint CR_In_Hanunoo[] = {
+	1,
+	0x1720, 0x173f,
+}; /* CR_In_Hanunoo */
+
+/* 'In_Buhid': Block */
+static const OnigCodePoint CR_In_Buhid[] = {
+	1,
+	0x1740, 0x175f,
+}; /* CR_In_Buhid */
+
+/* 'In_Tagbanwa': Block */
+static const OnigCodePoint CR_In_Tagbanwa[] = {
+	1,
+	0x1760, 0x177f,
+}; /* CR_In_Tagbanwa */
+
+/* 'In_Khmer': Block */
+static const OnigCodePoint CR_In_Khmer[] = {
+	1,
+	0x1780, 0x17ff,
+}; /* CR_In_Khmer */
+
+/* 'In_Mongolian': Block */
+static const OnigCodePoint CR_In_Mongolian[] = {
+	1,
+	0x1800, 0x18af,
+}; /* CR_In_Mongolian */
+
+/* 'In_Unified_Canadian_Aboriginal_Syllabics_Extended': Block */
+static const OnigCodePoint CR_In_Unified_Canadian_Aboriginal_Syllabics_Extended[] = {
+	1,
+	0x18b0, 0x18ff,
+}; /* CR_In_Unified_Canadian_Aboriginal_Syllabics_Extended */
+
+/* 'In_Limbu': Block */
+static const OnigCodePoint CR_In_Limbu[] = {
+	1,
+	0x1900, 0x194f,
+}; /* CR_In_Limbu */
+
+/* 'In_Tai_Le': Block */
+static const OnigCodePoint CR_In_Tai_Le[] = {
+	1,
+	0x1950, 0x197f,
+}; /* CR_In_Tai_Le */
+
+/* 'In_New_Tai_Lue': Block */
+static const OnigCodePoint CR_In_New_Tai_Lue[] = {
+	1,
+	0x1980, 0x19df,
+}; /* CR_In_New_Tai_Lue */
+
+/* 'In_Khmer_Symbols': Block */
+static const OnigCodePoint CR_In_Khmer_Symbols[] = {
+	1,
+	0x19e0, 0x19ff,
+}; /* CR_In_Khmer_Symbols */
+
+/* 'In_Buginese': Block */
+static const OnigCodePoint CR_In_Buginese[] = {
+	1,
+	0x1a00, 0x1a1f,
+}; /* CR_In_Buginese */
+
+/* 'In_Tai_Tham': Block */
+static const OnigCodePoint CR_In_Tai_Tham[] = {
+	1,
+	0x1a20, 0x1aaf,
+}; /* CR_In_Tai_Tham */
+
+/* 'In_Combining_Diacritical_Marks_Extended': Block */
+static const OnigCodePoint CR_In_Combining_Diacritical_Marks_Extended[] = {
+	1,
+	0x1ab0, 0x1aff,
+}; /* CR_In_Combining_Diacritical_Marks_Extended */
+
+/* 'In_Balinese': Block */
+static const OnigCodePoint CR_In_Balinese[] = {
+	1,
+	0x1b00, 0x1b7f,
+}; /* CR_In_Balinese */
+
+/* 'In_Sundanese': Block */
+static const OnigCodePoint CR_In_Sundanese[] = {
+	1,
+	0x1b80, 0x1bbf,
+}; /* CR_In_Sundanese */
+
+/* 'In_Batak': Block */
+static const OnigCodePoint CR_In_Batak[] = {
+	1,
+	0x1bc0, 0x1bff,
+}; /* CR_In_Batak */
+
+/* 'In_Lepcha': Block */
+static const OnigCodePoint CR_In_Lepcha[] = {
+	1,
+	0x1c00, 0x1c4f,
+}; /* CR_In_Lepcha */
+
+/* 'In_Ol_Chiki': Block */
+#define CR_In_Ol_Chiki CR_Ol_Chiki
+
+/* 'In_Cyrillic_Extended_C': Block */
+static const OnigCodePoint CR_In_Cyrillic_Extended_C[] = {
+	1,
+	0x1c80, 0x1c8f,
+}; /* CR_In_Cyrillic_Extended_C */
+
+/* 'In_Sundanese_Supplement': Block */
+static const OnigCodePoint CR_In_Sundanese_Supplement[] = {
+	1,
+	0x1cc0, 0x1ccf,
+}; /* CR_In_Sundanese_Supplement */
+
+/* 'In_Vedic_Extensions': Block */
+static const OnigCodePoint CR_In_Vedic_Extensions[] = {
+	1,
+	0x1cd0, 0x1cff,
+}; /* CR_In_Vedic_Extensions */
+
+/* 'In_Phonetic_Extensions': Block */
+static const OnigCodePoint CR_In_Phonetic_Extensions[] = {
+	1,
+	0x1d00, 0x1d7f,
+}; /* CR_In_Phonetic_Extensions */
+
+/* 'In_Phonetic_Extensions_Supplement': Block */
+static const OnigCodePoint CR_In_Phonetic_Extensions_Supplement[] = {
+	1,
+	0x1d80, 0x1dbf,
+}; /* CR_In_Phonetic_Extensions_Supplement */
+
+/* 'In_Combining_Diacritical_Marks_Supplement': Block */
+static const OnigCodePoint CR_In_Combining_Diacritical_Marks_Supplement[] = {
+	1,
+	0x1dc0, 0x1dff,
+}; /* CR_In_Combining_Diacritical_Marks_Supplement */
+
+/* 'In_Latin_Extended_Additional': Block */
+static const OnigCodePoint CR_In_Latin_Extended_Additional[] = {
+	1,
+	0x1e00, 0x1eff,
+}; /* CR_In_Latin_Extended_Additional */
+
+/* 'In_Greek_Extended': Block */
+static const OnigCodePoint CR_In_Greek_Extended[] = {
+	1,
+	0x1f00, 0x1fff,
+}; /* CR_In_Greek_Extended */
+
+/* 'In_General_Punctuation': Block */
+static const OnigCodePoint CR_In_General_Punctuation[] = {
+	1,
+	0x2000, 0x206f,
+}; /* CR_In_General_Punctuation */
+
+/* 'In_Superscripts_and_Subscripts': Block */
+static const OnigCodePoint CR_In_Superscripts_and_Subscripts[] = {
+	1,
+	0x2070, 0x209f,
+}; /* CR_In_Superscripts_and_Subscripts */
+
+/* 'In_Currency_Symbols': Block */
+static const OnigCodePoint CR_In_Currency_Symbols[] = {
+	1,
+	0x20a0, 0x20cf,
+}; /* CR_In_Currency_Symbols */
+
+/* 'In_Combining_Diacritical_Marks_for_Symbols': Block */
+static const OnigCodePoint CR_In_Combining_Diacritical_Marks_for_Symbols[] = {
+	1,
+	0x20d0, 0x20ff,
+}; /* CR_In_Combining_Diacritical_Marks_for_Symbols */
+
+/* 'In_Letterlike_Symbols': Block */
+static const OnigCodePoint CR_In_Letterlike_Symbols[] = {
+	1,
+	0x2100, 0x214f,
+}; /* CR_In_Letterlike_Symbols */
+
+/* 'In_Number_Forms': Block */
+static const OnigCodePoint CR_In_Number_Forms[] = {
+	1,
+	0x2150, 0x218f,
+}; /* CR_In_Number_Forms */
+
+/* 'In_Arrows': Block */
+static const OnigCodePoint CR_In_Arrows[] = {
+	1,
+	0x2190, 0x21ff,
+}; /* CR_In_Arrows */
+
+/* 'In_Mathematical_Operators': Block */
+static const OnigCodePoint CR_In_Mathematical_Operators[] = {
+	1,
+	0x2200, 0x22ff,
+}; /* CR_In_Mathematical_Operators */
+
+/* 'In_Miscellaneous_Technical': Block */
+static const OnigCodePoint CR_In_Miscellaneous_Technical[] = {
+	1,
+	0x2300, 0x23ff,
+}; /* CR_In_Miscellaneous_Technical */
+
+/* 'In_Control_Pictures': Block */
+static const OnigCodePoint CR_In_Control_Pictures[] = {
+	1,
+	0x2400, 0x243f,
+}; /* CR_In_Control_Pictures */
+
+/* 'In_Optical_Character_Recognition': Block */
+static const OnigCodePoint CR_In_Optical_Character_Recognition[] = {
+	1,
+	0x2440, 0x245f,
+}; /* CR_In_Optical_Character_Recognition */
+
+/* 'In_Enclosed_Alphanumerics': Block */
+static const OnigCodePoint CR_In_Enclosed_Alphanumerics[] = {
+	1,
+	0x2460, 0x24ff,
+}; /* CR_In_Enclosed_Alphanumerics */
+
+/* 'In_Box_Drawing': Block */
+static const OnigCodePoint CR_In_Box_Drawing[] = {
+	1,
+	0x2500, 0x257f,
+}; /* CR_In_Box_Drawing */
+
+/* 'In_Block_Elements': Block */
+static const OnigCodePoint CR_In_Block_Elements[] = {
+	1,
+	0x2580, 0x259f,
+}; /* CR_In_Block_Elements */
+
+/* 'In_Geometric_Shapes': Block */
+static const OnigCodePoint CR_In_Geometric_Shapes[] = {
+	1,
+	0x25a0, 0x25ff,
+}; /* CR_In_Geometric_Shapes */
+
+/* 'In_Miscellaneous_Symbols': Block */
+static const OnigCodePoint CR_In_Miscellaneous_Symbols[] = {
+	1,
+	0x2600, 0x26ff,
+}; /* CR_In_Miscellaneous_Symbols */
+
+/* 'In_Dingbats': Block */
+static const OnigCodePoint CR_In_Dingbats[] = {
+	1,
+	0x2700, 0x27bf,
+}; /* CR_In_Dingbats */
+
+/* 'In_Miscellaneous_Mathematical_Symbols_A': Block */
+static const OnigCodePoint CR_In_Miscellaneous_Mathematical_Symbols_A[] = {
+	1,
+	0x27c0, 0x27ef,
+}; /* CR_In_Miscellaneous_Mathematical_Symbols_A */
+
+/* 'In_Supplemental_Arrows_A': Block */
+static const OnigCodePoint CR_In_Supplemental_Arrows_A[] = {
+	1,
+	0x27f0, 0x27ff,
+}; /* CR_In_Supplemental_Arrows_A */
+
+/* 'In_Braille_Patterns': Block */
+#define CR_In_Braille_Patterns CR_Braille
+
+/* 'In_Supplemental_Arrows_B': Block */
+static const OnigCodePoint CR_In_Supplemental_Arrows_B[] = {
+	1,
+	0x2900, 0x297f,
+}; /* CR_In_Supplemental_Arrows_B */
+
+/* 'In_Miscellaneous_Mathematical_Symbols_B': Block */
+static const OnigCodePoint CR_In_Miscellaneous_Mathematical_Symbols_B[] = {
+	1,
+	0x2980, 0x29ff,
+}; /* CR_In_Miscellaneous_Mathematical_Symbols_B */
+
+/* 'In_Supplemental_Mathematical_Operators': Block */
+static const OnigCodePoint CR_In_Supplemental_Mathematical_Operators[] = {
+	1,
+	0x2a00, 0x2aff,
+}; /* CR_In_Supplemental_Mathematical_Operators */
+
+/* 'In_Miscellaneous_Symbols_and_Arrows': Block */
+static const OnigCodePoint CR_In_Miscellaneous_Symbols_and_Arrows[] = {
+	1,
+	0x2b00, 0x2bff,
+}; /* CR_In_Miscellaneous_Symbols_and_Arrows */
+
+/* 'In_Glagolitic': Block */
+static const OnigCodePoint CR_In_Glagolitic[] = {
+	1,
+	0x2c00, 0x2c5f,
+}; /* CR_In_Glagolitic */
+
+/* 'In_Latin_Extended_C': Block */
+static const OnigCodePoint CR_In_Latin_Extended_C[] = {
+	1,
+	0x2c60, 0x2c7f,
+}; /* CR_In_Latin_Extended_C */
+
+/* 'In_Coptic': Block */
+static const OnigCodePoint CR_In_Coptic[] = {
+	1,
+	0x2c80, 0x2cff,
+}; /* CR_In_Coptic */
+
+/* 'In_Georgian_Supplement': Block */
+static const OnigCodePoint CR_In_Georgian_Supplement[] = {
+	1,
+	0x2d00, 0x2d2f,
+}; /* CR_In_Georgian_Supplement */
+
+/* 'In_Tifinagh': Block */
+static const OnigCodePoint CR_In_Tifinagh[] = {
+	1,
+	0x2d30, 0x2d7f,
+}; /* CR_In_Tifinagh */
+
+/* 'In_Ethiopic_Extended': Block */
+static const OnigCodePoint CR_In_Ethiopic_Extended[] = {
+	1,
+	0x2d80, 0x2ddf,
+}; /* CR_In_Ethiopic_Extended */
+
+/* 'In_Cyrillic_Extended_A': Block */
+static const OnigCodePoint CR_In_Cyrillic_Extended_A[] = {
+	1,
+	0x2de0, 0x2dff,
+}; /* CR_In_Cyrillic_Extended_A */
+
+/* 'In_Supplemental_Punctuation': Block */
+static const OnigCodePoint CR_In_Supplemental_Punctuation[] = {
+	1,
+	0x2e00, 0x2e7f,
+}; /* CR_In_Supplemental_Punctuation */
+
+/* 'In_CJK_Radicals_Supplement': Block */
+static const OnigCodePoint CR_In_CJK_Radicals_Supplement[] = {
+	1,
+	0x2e80, 0x2eff,
+}; /* CR_In_CJK_Radicals_Supplement */
+
+/* 'In_Kangxi_Radicals': Block */
+static const OnigCodePoint CR_In_Kangxi_Radicals[] = {
+	1,
+	0x2f00, 0x2fdf,
+}; /* CR_In_Kangxi_Radicals */
+
+/* 'In_Ideographic_Description_Characters': Block */
+static const OnigCodePoint CR_In_Ideographic_Description_Characters[] = {
+	1,
+	0x2ff0, 0x2fff,
+}; /* CR_In_Ideographic_Description_Characters */
+
+/* 'In_CJK_Symbols_and_Punctuation': Block */
+static const OnigCodePoint CR_In_CJK_Symbols_and_Punctuation[] = {
+	1,
+	0x3000, 0x303f,
+}; /* CR_In_CJK_Symbols_and_Punctuation */
+
+/* 'In_Hiragana': Block */
+static const OnigCodePoint CR_In_Hiragana[] = {
+	1,
+	0x3040, 0x309f,
+}; /* CR_In_Hiragana */
+
+/* 'In_Katakana': Block */
+static const OnigCodePoint CR_In_Katakana[] = {
+	1,
+	0x30a0, 0x30ff,
+}; /* CR_In_Katakana */
+
+/* 'In_Bopomofo': Block */
+static const OnigCodePoint CR_In_Bopomofo[] = {
+	1,
+	0x3100, 0x312f,
+}; /* CR_In_Bopomofo */
+
+/* 'In_Hangul_Compatibility_Jamo': Block */
+static const OnigCodePoint CR_In_Hangul_Compatibility_Jamo[] = {
+	1,
+	0x3130, 0x318f,
+}; /* CR_In_Hangul_Compatibility_Jamo */
+
+/* 'In_Kanbun': Block */
+static const OnigCodePoint CR_In_Kanbun[] = {
+	1,
+	0x3190, 0x319f,
+}; /* CR_In_Kanbun */
+
+/* 'In_Bopomofo_Extended': Block */
+static const OnigCodePoint CR_In_Bopomofo_Extended[] = {
+	1,
+	0x31a0, 0x31bf,
+}; /* CR_In_Bopomofo_Extended */
+
+/* 'In_CJK_Strokes': Block */
+static const OnigCodePoint CR_In_CJK_Strokes[] = {
+	1,
+	0x31c0, 0x31ef,
+}; /* CR_In_CJK_Strokes */
+
+/* 'In_Katakana_Phonetic_Extensions': Block */
+static const OnigCodePoint CR_In_Katakana_Phonetic_Extensions[] = {
+	1,
+	0x31f0, 0x31ff,
+}; /* CR_In_Katakana_Phonetic_Extensions */
+
+/* 'In_Enclosed_CJK_Letters_and_Months': Block */
+static const OnigCodePoint CR_In_Enclosed_CJK_Letters_and_Months[] = {
+	1,
+	0x3200, 0x32ff,
+}; /* CR_In_Enclosed_CJK_Letters_and_Months */
+
+/* 'In_CJK_Compatibility': Block */
+static const OnigCodePoint CR_In_CJK_Compatibility[] = {
+	1,
+	0x3300, 0x33ff,
+}; /* CR_In_CJK_Compatibility */
+
+/* 'In_CJK_Unified_Ideographs_Extension_A': Block */
+static const OnigCodePoint CR_In_CJK_Unified_Ideographs_Extension_A[] = {
+	1,
+	0x3400, 0x4dbf,
+}; /* CR_In_CJK_Unified_Ideographs_Extension_A */
+
+/* 'In_Yijing_Hexagram_Symbols': Block */
+static const OnigCodePoint CR_In_Yijing_Hexagram_Symbols[] = {
+	1,
+	0x4dc0, 0x4dff,
+}; /* CR_In_Yijing_Hexagram_Symbols */
+
+/* 'In_CJK_Unified_Ideographs': Block */
+static const OnigCodePoint CR_In_CJK_Unified_Ideographs[] = {
+	1,
+	0x4e00, 0x9fff,
+}; /* CR_In_CJK_Unified_Ideographs */
+
+/* 'In_Yi_Syllables': Block */
+static const OnigCodePoint CR_In_Yi_Syllables[] = {
+	1,
+	0xa000, 0xa48f,
+}; /* CR_In_Yi_Syllables */
+
+/* 'In_Yi_Radicals': Block */
+static const OnigCodePoint CR_In_Yi_Radicals[] = {
+	1,
+	0xa490, 0xa4cf,
+}; /* CR_In_Yi_Radicals */
+
+/* 'In_Lisu': Block */
+#define CR_In_Lisu CR_Lisu
+
+/* 'In_Vai': Block */
+static const OnigCodePoint CR_In_Vai[] = {
+	1,
+	0xa500, 0xa63f,
+}; /* CR_In_Vai */
+
+/* 'In_Cyrillic_Extended_B': Block */
+static const OnigCodePoint CR_In_Cyrillic_Extended_B[] = {
+	1,
+	0xa640, 0xa69f,
+}; /* CR_In_Cyrillic_Extended_B */
+
+/* 'In_Bamum': Block */
+static const OnigCodePoint CR_In_Bamum[] = {
+	1,
+	0xa6a0, 0xa6ff,
+}; /* CR_In_Bamum */
+
+/* 'In_Modifier_Tone_Letters': Block */
+static const OnigCodePoint CR_In_Modifier_Tone_Letters[] = {
+	1,
+	0xa700, 0xa71f,
+}; /* CR_In_Modifier_Tone_Letters */
+
+/* 'In_Latin_Extended_D': Block */
+static const OnigCodePoint CR_In_Latin_Extended_D[] = {
+	1,
+	0xa720, 0xa7ff,
+}; /* CR_In_Latin_Extended_D */
+
+/* 'In_Syloti_Nagri': Block */
+static const OnigCodePoint CR_In_Syloti_Nagri[] = {
+	1,
+	0xa800, 0xa82f,
+}; /* CR_In_Syloti_Nagri */
+
+/* 'In_Common_Indic_Number_Forms': Block */
+static const OnigCodePoint CR_In_Common_Indic_Number_Forms[] = {
+	1,
+	0xa830, 0xa83f,
+}; /* CR_In_Common_Indic_Number_Forms */
+
+/* 'In_Phags_pa': Block */
+static const OnigCodePoint CR_In_Phags_pa[] = {
+	1,
+	0xa840, 0xa87f,
+}; /* CR_In_Phags_pa */
+
+/* 'In_Saurashtra': Block */
+static const OnigCodePoint CR_In_Saurashtra[] = {
+	1,
+	0xa880, 0xa8df,
+}; /* CR_In_Saurashtra */
+
+/* 'In_Devanagari_Extended': Block */
+static const OnigCodePoint CR_In_Devanagari_Extended[] = {
+	1,
+	0xa8e0, 0xa8ff,
+}; /* CR_In_Devanagari_Extended */
+
+/* 'In_Kayah_Li': Block */
+static const OnigCodePoint CR_In_Kayah_Li[] = {
+	1,
+	0xa900, 0xa92f,
+}; /* CR_In_Kayah_Li */
+
+/* 'In_Rejang': Block */
+static const OnigCodePoint CR_In_Rejang[] = {
+	1,
+	0xa930, 0xa95f,
+}; /* CR_In_Rejang */
+
+/* 'In_Hangul_Jamo_Extended_A': Block */
+static const OnigCodePoint CR_In_Hangul_Jamo_Extended_A[] = {
+	1,
+	0xa960, 0xa97f,
+}; /* CR_In_Hangul_Jamo_Extended_A */
+
+/* 'In_Javanese': Block */
+static const OnigCodePoint CR_In_Javanese[] = {
+	1,
+	0xa980, 0xa9df,
+}; /* CR_In_Javanese */
+
+/* 'In_Myanmar_Extended_B': Block */
+static const OnigCodePoint CR_In_Myanmar_Extended_B[] = {
+	1,
+	0xa9e0, 0xa9ff,
+}; /* CR_In_Myanmar_Extended_B */
+
+/* 'In_Cham': Block */
+static const OnigCodePoint CR_In_Cham[] = {
+	1,
+	0xaa00, 0xaa5f,
+}; /* CR_In_Cham */
+
+/* 'In_Myanmar_Extended_A': Block */
+static const OnigCodePoint CR_In_Myanmar_Extended_A[] = {
+	1,
+	0xaa60, 0xaa7f,
+}; /* CR_In_Myanmar_Extended_A */
+
+/* 'In_Tai_Viet': Block */
+static const OnigCodePoint CR_In_Tai_Viet[] = {
+	1,
+	0xaa80, 0xaadf,
+}; /* CR_In_Tai_Viet */
+
+/* 'In_Meetei_Mayek_Extensions': Block */
+static const OnigCodePoint CR_In_Meetei_Mayek_Extensions[] = {
+	1,
+	0xaae0, 0xaaff,
+}; /* CR_In_Meetei_Mayek_Extensions */
+
+/* 'In_Ethiopic_Extended_A': Block */
+static const OnigCodePoint CR_In_Ethiopic_Extended_A[] = {
+	1,
+	0xab00, 0xab2f,
+}; /* CR_In_Ethiopic_Extended_A */
+
+/* 'In_Latin_Extended_E': Block */
+static const OnigCodePoint CR_In_Latin_Extended_E[] = {
+	1,
+	0xab30, 0xab6f,
+}; /* CR_In_Latin_Extended_E */
+
+/* 'In_Cherokee_Supplement': Block */
+static const OnigCodePoint CR_In_Cherokee_Supplement[] = {
+	1,
+	0xab70, 0xabbf,
+}; /* CR_In_Cherokee_Supplement */
+
+/* 'In_Meetei_Mayek': Block */
+static const OnigCodePoint CR_In_Meetei_Mayek[] = {
+	1,
+	0xabc0, 0xabff,
+}; /* CR_In_Meetei_Mayek */
+
+/* 'In_Hangul_Syllables': Block */
+static const OnigCodePoint CR_In_Hangul_Syllables[] = {
+	1,
+	0xac00, 0xd7af,
+}; /* CR_In_Hangul_Syllables */
+
+/* 'In_Hangul_Jamo_Extended_B': Block */
+static const OnigCodePoint CR_In_Hangul_Jamo_Extended_B[] = {
+	1,
+	0xd7b0, 0xd7ff,
+}; /* CR_In_Hangul_Jamo_Extended_B */
+
+/* 'In_High_Surrogates': Block */
+static const OnigCodePoint CR_In_High_Surrogates[] = {
+	1,
+	0xd800, 0xdb7f,
+}; /* CR_In_High_Surrogates */
+
+/* 'In_High_Private_Use_Surrogates': Block */
+static const OnigCodePoint CR_In_High_Private_Use_Surrogates[] = {
+	1,
+	0xdb80, 0xdbff,
+}; /* CR_In_High_Private_Use_Surrogates */
+
+/* 'In_Low_Surrogates': Block */
+static const OnigCodePoint CR_In_Low_Surrogates[] = {
+	1,
+	0xdc00, 0xdfff,
+}; /* CR_In_Low_Surrogates */
+
+/* 'In_Private_Use_Area': Block */
+static const OnigCodePoint CR_In_Private_Use_Area[] = {
+	1,
+	0xe000, 0xf8ff,
+}; /* CR_In_Private_Use_Area */
+
+/* 'In_CJK_Compatibility_Ideographs': Block */
+static const OnigCodePoint CR_In_CJK_Compatibility_Ideographs[] = {
+	1,
+	0xf900, 0xfaff,
+}; /* CR_In_CJK_Compatibility_Ideographs */
+
+/* 'In_Alphabetic_Presentation_Forms': Block */
+static const OnigCodePoint CR_In_Alphabetic_Presentation_Forms[] = {
+	1,
+	0xfb00, 0xfb4f,
+}; /* CR_In_Alphabetic_Presentation_Forms */
+
+/* 'In_Arabic_Presentation_Forms_A': Block */
+static const OnigCodePoint CR_In_Arabic_Presentation_Forms_A[] = {
+	1,
+	0xfb50, 0xfdff,
+}; /* CR_In_Arabic_Presentation_Forms_A */
+
+/* 'In_Variation_Selectors': Block */
+static const OnigCodePoint CR_In_Variation_Selectors[] = {
+	1,
+	0xfe00, 0xfe0f,
+}; /* CR_In_Variation_Selectors */
+
+/* 'In_Vertical_Forms': Block */
+static const OnigCodePoint CR_In_Vertical_Forms[] = {
+	1,
+	0xfe10, 0xfe1f,
+}; /* CR_In_Vertical_Forms */
+
+/* 'In_Combining_Half_Marks': Block */
+static const OnigCodePoint CR_In_Combining_Half_Marks[] = {
+	1,
+	0xfe20, 0xfe2f,
+}; /* CR_In_Combining_Half_Marks */
+
+/* 'In_CJK_Compatibility_Forms': Block */
+static const OnigCodePoint CR_In_CJK_Compatibility_Forms[] = {
+	1,
+	0xfe30, 0xfe4f,
+}; /* CR_In_CJK_Compatibility_Forms */
+
+/* 'In_Small_Form_Variants': Block */
+static const OnigCodePoint CR_In_Small_Form_Variants[] = {
+	1,
+	0xfe50, 0xfe6f,
+}; /* CR_In_Small_Form_Variants */
+
+/* 'In_Arabic_Presentation_Forms_B': Block */
+static const OnigCodePoint CR_In_Arabic_Presentation_Forms_B[] = {
+	1,
+	0xfe70, 0xfeff,
+}; /* CR_In_Arabic_Presentation_Forms_B */
+
+/* 'In_Halfwidth_and_Fullwidth_Forms': Block */
+static const OnigCodePoint CR_In_Halfwidth_and_Fullwidth_Forms[] = {
+	1,
+	0xff00, 0xffef,
+}; /* CR_In_Halfwidth_and_Fullwidth_Forms */
+
+/* 'In_Specials': Block */
+static const OnigCodePoint CR_In_Specials[] = {
+	1,
+	0xfff0, 0xffff,
+}; /* CR_In_Specials */
+
+/* 'In_Linear_B_Syllabary': Block */
+static const OnigCodePoint CR_In_Linear_B_Syllabary[] = {
+	1,
+	0x10000, 0x1007f,
+}; /* CR_In_Linear_B_Syllabary */
+
+/* 'In_Linear_B_Ideograms': Block */
+static const OnigCodePoint CR_In_Linear_B_Ideograms[] = {
+	1,
+	0x10080, 0x100ff,
+}; /* CR_In_Linear_B_Ideograms */
+
+/* 'In_Aegean_Numbers': Block */
+static const OnigCodePoint CR_In_Aegean_Numbers[] = {
+	1,
+	0x10100, 0x1013f,
+}; /* CR_In_Aegean_Numbers */
+
+/* 'In_Ancient_Greek_Numbers': Block */
+static const OnigCodePoint CR_In_Ancient_Greek_Numbers[] = {
+	1,
+	0x10140, 0x1018f,
+}; /* CR_In_Ancient_Greek_Numbers */
+
+/* 'In_Ancient_Symbols': Block */
+static const OnigCodePoint CR_In_Ancient_Symbols[] = {
+	1,
+	0x10190, 0x101cf,
+}; /* CR_In_Ancient_Symbols */
+
+/* 'In_Phaistos_Disc': Block */
+static const OnigCodePoint CR_In_Phaistos_Disc[] = {
+	1,
+	0x101d0, 0x101ff,
+}; /* CR_In_Phaistos_Disc */
+
+/* 'In_Lycian': Block */
+static const OnigCodePoint CR_In_Lycian[] = {
+	1,
+	0x10280, 0x1029f,
+}; /* CR_In_Lycian */
+
+/* 'In_Carian': Block */
+static const OnigCodePoint CR_In_Carian[] = {
+	1,
+	0x102a0, 0x102df,
+}; /* CR_In_Carian */
+
+/* 'In_Coptic_Epact_Numbers': Block */
+static const OnigCodePoint CR_In_Coptic_Epact_Numbers[] = {
+	1,
+	0x102e0, 0x102ff,
+}; /* CR_In_Coptic_Epact_Numbers */
+
+/* 'In_Old_Italic': Block */
+static const OnigCodePoint CR_In_Old_Italic[] = {
+	1,
+	0x10300, 0x1032f,
+}; /* CR_In_Old_Italic */
+
+/* 'In_Gothic': Block */
+static const OnigCodePoint CR_In_Gothic[] = {
+	1,
+	0x10330, 0x1034f,
+}; /* CR_In_Gothic */
+
+/* 'In_Old_Permic': Block */
+static const OnigCodePoint CR_In_Old_Permic[] = {
+	1,
+	0x10350, 0x1037f,
+}; /* CR_In_Old_Permic */
+
+/* 'In_Ugaritic': Block */
+static const OnigCodePoint CR_In_Ugaritic[] = {
+	1,
+	0x10380, 0x1039f,
+}; /* CR_In_Ugaritic */
+
+/* 'In_Old_Persian': Block */
+static const OnigCodePoint CR_In_Old_Persian[] = {
+	1,
+	0x103a0, 0x103df,
+}; /* CR_In_Old_Persian */
+
+/* 'In_Deseret': Block */
+#define CR_In_Deseret CR_Deseret
+
+/* 'In_Shavian': Block */
+#define CR_In_Shavian CR_Shavian
+
+/* 'In_Osmanya': Block */
+static const OnigCodePoint CR_In_Osmanya[] = {
+	1,
+	0x10480, 0x104af,
+}; /* CR_In_Osmanya */
+
+/* 'In_Osage': Block */
+static const OnigCodePoint CR_In_Osage[] = {
+	1,
+	0x104b0, 0x104ff,
+}; /* CR_In_Osage */
+
+/* 'In_Elbasan': Block */
+static const OnigCodePoint CR_In_Elbasan[] = {
+	1,
+	0x10500, 0x1052f,
+}; /* CR_In_Elbasan */
+
+/* 'In_Caucasian_Albanian': Block */
+static const OnigCodePoint CR_In_Caucasian_Albanian[] = {
+	1,
+	0x10530, 0x1056f,
+}; /* CR_In_Caucasian_Albanian */
+
+/* 'In_Linear_A': Block */
+static const OnigCodePoint CR_In_Linear_A[] = {
+	1,
+	0x10600, 0x1077f,
+}; /* CR_In_Linear_A */
+
+/* 'In_Cypriot_Syllabary': Block */
+static const OnigCodePoint CR_In_Cypriot_Syllabary[] = {
+	1,
+	0x10800, 0x1083f,
+}; /* CR_In_Cypriot_Syllabary */
+
+/* 'In_Imperial_Aramaic': Block */
+static const OnigCodePoint CR_In_Imperial_Aramaic[] = {
+	1,
+	0x10840, 0x1085f,
+}; /* CR_In_Imperial_Aramaic */
+
+/* 'In_Palmyrene': Block */
+#define CR_In_Palmyrene CR_Palmyrene
+
+/* 'In_Nabataean': Block */
+static const OnigCodePoint CR_In_Nabataean[] = {
+	1,
+	0x10880, 0x108af,
+}; /* CR_In_Nabataean */
+
+/* 'In_Hatran': Block */
+static const OnigCodePoint CR_In_Hatran[] = {
+	1,
+	0x108e0, 0x108ff,
+}; /* CR_In_Hatran */
+
+/* 'In_Phoenician': Block */
+static const OnigCodePoint CR_In_Phoenician[] = {
+	1,
+	0x10900, 0x1091f,
+}; /* CR_In_Phoenician */
+
+/* 'In_Lydian': Block */
+static const OnigCodePoint CR_In_Lydian[] = {
+	1,
+	0x10920, 0x1093f,
+}; /* CR_In_Lydian */
+
+/* 'In_Meroitic_Hieroglyphs': Block */
+#define CR_In_Meroitic_Hieroglyphs CR_Meroitic_Hieroglyphs
+
+/* 'In_Meroitic_Cursive': Block */
+static const OnigCodePoint CR_In_Meroitic_Cursive[] = {
+	1,
+	0x109a0, 0x109ff,
+}; /* CR_In_Meroitic_Cursive */
+
+/* 'In_Kharoshthi': Block */
+static const OnigCodePoint CR_In_Kharoshthi[] = {
+	1,
+	0x10a00, 0x10a5f,
+}; /* CR_In_Kharoshthi */
+
+/* 'In_Old_South_Arabian': Block */
+#define CR_In_Old_South_Arabian CR_Old_South_Arabian
+
+/* 'In_Old_North_Arabian': Block */
+#define CR_In_Old_North_Arabian CR_Old_North_Arabian
+
+/* 'In_Manichaean': Block */
+static const OnigCodePoint CR_In_Manichaean[] = {
+	1,
+	0x10ac0, 0x10aff,
+}; /* CR_In_Manichaean */
+
+/* 'In_Avestan': Block */
+static const OnigCodePoint CR_In_Avestan[] = {
+	1,
+	0x10b00, 0x10b3f,
+}; /* CR_In_Avestan */
+
+/* 'In_Inscriptional_Parthian': Block */
+static const OnigCodePoint CR_In_Inscriptional_Parthian[] = {
+	1,
+	0x10b40, 0x10b5f,
+}; /* CR_In_Inscriptional_Parthian */
+
+/* 'In_Inscriptional_Pahlavi': Block */
+static const OnigCodePoint CR_In_Inscriptional_Pahlavi[] = {
+	1,
+	0x10b60, 0x10b7f,
+}; /* CR_In_Inscriptional_Pahlavi */
+
+/* 'In_Psalter_Pahlavi': Block */
+static const OnigCodePoint CR_In_Psalter_Pahlavi[] = {
+	1,
+	0x10b80, 0x10baf,
+}; /* CR_In_Psalter_Pahlavi */
+
+/* 'In_Old_Turkic': Block */
+static const OnigCodePoint CR_In_Old_Turkic[] = {
+	1,
+	0x10c00, 0x10c4f,
+}; /* CR_In_Old_Turkic */
+
+/* 'In_Old_Hungarian': Block */
+static const OnigCodePoint CR_In_Old_Hungarian[] = {
+	1,
+	0x10c80, 0x10cff,
+}; /* CR_In_Old_Hungarian */
+
+/* 'In_Rumi_Numeral_Symbols': Block */
+static const OnigCodePoint CR_In_Rumi_Numeral_Symbols[] = {
+	1,
+	0x10e60, 0x10e7f,
+}; /* CR_In_Rumi_Numeral_Symbols */
+
+/* 'In_Brahmi': Block */
+static const OnigCodePoint CR_In_Brahmi[] = {
+	1,
+	0x11000, 0x1107f,
+}; /* CR_In_Brahmi */
+
+/* 'In_Kaithi': Block */
+static const OnigCodePoint CR_In_Kaithi[] = {
+	1,
+	0x11080, 0x110cf,
+}; /* CR_In_Kaithi */
+
+/* 'In_Sora_Sompeng': Block */
+static const OnigCodePoint CR_In_Sora_Sompeng[] = {
+	1,
+	0x110d0, 0x110ff,
+}; /* CR_In_Sora_Sompeng */
+
+/* 'In_Chakma': Block */
+static const OnigCodePoint CR_In_Chakma[] = {
+	1,
+	0x11100, 0x1114f,
+}; /* CR_In_Chakma */
+
+/* 'In_Mahajani': Block */
+static const OnigCodePoint CR_In_Mahajani[] = {
+	1,
+	0x11150, 0x1117f,
+}; /* CR_In_Mahajani */
+
+/* 'In_Sharada': Block */
+static const OnigCodePoint CR_In_Sharada[] = {
+	1,
+	0x11180, 0x111df,
+}; /* CR_In_Sharada */
+
+/* 'In_Sinhala_Archaic_Numbers': Block */
+static const OnigCodePoint CR_In_Sinhala_Archaic_Numbers[] = {
+	1,
+	0x111e0, 0x111ff,
+}; /* CR_In_Sinhala_Archaic_Numbers */
+
+/* 'In_Khojki': Block */
+static const OnigCodePoint CR_In_Khojki[] = {
+	1,
+	0x11200, 0x1124f,
+}; /* CR_In_Khojki */
+
+/* 'In_Multani': Block */
+static const OnigCodePoint CR_In_Multani[] = {
+	1,
+	0x11280, 0x112af,
+}; /* CR_In_Multani */
+
+/* 'In_Khudawadi': Block */
+static const OnigCodePoint CR_In_Khudawadi[] = {
+	1,
+	0x112b0, 0x112ff,
+}; /* CR_In_Khudawadi */
+
+/* 'In_Grantha': Block */
+static const OnigCodePoint CR_In_Grantha[] = {
+	1,
+	0x11300, 0x1137f,
+}; /* CR_In_Grantha */
+
+/* 'In_Newa': Block */
+static const OnigCodePoint CR_In_Newa[] = {
+	1,
+	0x11400, 0x1147f,
+}; /* CR_In_Newa */
+
+/* 'In_Tirhuta': Block */
+static const OnigCodePoint CR_In_Tirhuta[] = {
+	1,
+	0x11480, 0x114df,
+}; /* CR_In_Tirhuta */
+
+/* 'In_Siddham': Block */
+static const OnigCodePoint CR_In_Siddham[] = {
+	1,
+	0x11580, 0x115ff,
+}; /* CR_In_Siddham */
+
+/* 'In_Modi': Block */
+static const OnigCodePoint CR_In_Modi[] = {
+	1,
+	0x11600, 0x1165f,
+}; /* CR_In_Modi */
+
+/* 'In_Mongolian_Supplement': Block */
+static const OnigCodePoint CR_In_Mongolian_Supplement[] = {
+	1,
+	0x11660, 0x1167f,
+}; /* CR_In_Mongolian_Supplement */
+
+/* 'In_Takri': Block */
+static const OnigCodePoint CR_In_Takri[] = {
+	1,
+	0x11680, 0x116cf,
+}; /* CR_In_Takri */
+
+/* 'In_Ahom': Block */
+static const OnigCodePoint CR_In_Ahom[] = {
+	1,
+	0x11700, 0x1173f,
+}; /* CR_In_Ahom */
+
+/* 'In_Warang_Citi': Block */
+static const OnigCodePoint CR_In_Warang_Citi[] = {
+	1,
+	0x118a0, 0x118ff,
+}; /* CR_In_Warang_Citi */
+
+/* 'In_Zanabazar_Square': Block */
+static const OnigCodePoint CR_In_Zanabazar_Square[] = {
+	1,
+	0x11a00, 0x11a4f,
+}; /* CR_In_Zanabazar_Square */
+
+/* 'In_Soyombo': Block */
+static const OnigCodePoint CR_In_Soyombo[] = {
+	1,
+	0x11a50, 0x11aaf,
+}; /* CR_In_Soyombo */
+
+/* 'In_Pau_Cin_Hau': Block */
+static const OnigCodePoint CR_In_Pau_Cin_Hau[] = {
+	1,
+	0x11ac0, 0x11aff,
+}; /* CR_In_Pau_Cin_Hau */
+
+/* 'In_Bhaiksuki': Block */
+static const OnigCodePoint CR_In_Bhaiksuki[] = {
+	1,
+	0x11c00, 0x11c6f,
+}; /* CR_In_Bhaiksuki */
+
+/* 'In_Marchen': Block */
+static const OnigCodePoint CR_In_Marchen[] = {
+	1,
+	0x11c70, 0x11cbf,
+}; /* CR_In_Marchen */
+
+/* 'In_Masaram_Gondi': Block */
+static const OnigCodePoint CR_In_Masaram_Gondi[] = {
+	1,
+	0x11d00, 0x11d5f,
+}; /* CR_In_Masaram_Gondi */
+
+/* 'In_Cuneiform': Block */
+static const OnigCodePoint CR_In_Cuneiform[] = {
+	1,
+	0x12000, 0x123ff,
+}; /* CR_In_Cuneiform */
+
+/* 'In_Cuneiform_Numbers_and_Punctuation': Block */
+static const OnigCodePoint CR_In_Cuneiform_Numbers_and_Punctuation[] = {
+	1,
+	0x12400, 0x1247f,
+}; /* CR_In_Cuneiform_Numbers_and_Punctuation */
+
+/* 'In_Early_Dynastic_Cuneiform': Block */
+static const OnigCodePoint CR_In_Early_Dynastic_Cuneiform[] = {
+	1,
+	0x12480, 0x1254f,
+}; /* CR_In_Early_Dynastic_Cuneiform */
+
+/* 'In_Egyptian_Hieroglyphs': Block */
+static const OnigCodePoint CR_In_Egyptian_Hieroglyphs[] = {
+	1,
+	0x13000, 0x1342f,
+}; /* CR_In_Egyptian_Hieroglyphs */
+
+/* 'In_Anatolian_Hieroglyphs': Block */
+static const OnigCodePoint CR_In_Anatolian_Hieroglyphs[] = {
+	1,
+	0x14400, 0x1467f,
+}; /* CR_In_Anatolian_Hieroglyphs */
+
+/* 'In_Bamum_Supplement': Block */
+static const OnigCodePoint CR_In_Bamum_Supplement[] = {
+	1,
+	0x16800, 0x16a3f,
+}; /* CR_In_Bamum_Supplement */
+
+/* 'In_Mro': Block */
+static const OnigCodePoint CR_In_Mro[] = {
+	1,
+	0x16a40, 0x16a6f,
+}; /* CR_In_Mro */
+
+/* 'In_Bassa_Vah': Block */
+static const OnigCodePoint CR_In_Bassa_Vah[] = {
+	1,
+	0x16ad0, 0x16aff,
+}; /* CR_In_Bassa_Vah */
+
+/* 'In_Pahawh_Hmong': Block */
+static const OnigCodePoint CR_In_Pahawh_Hmong[] = {
+	1,
+	0x16b00, 0x16b8f,
+}; /* CR_In_Pahawh_Hmong */
+
+/* 'In_Miao': Block */
+static const OnigCodePoint CR_In_Miao[] = {
+	1,
+	0x16f00, 0x16f9f,
+}; /* CR_In_Miao */
+
+/* 'In_Ideographic_Symbols_and_Punctuation': Block */
+static const OnigCodePoint CR_In_Ideographic_Symbols_and_Punctuation[] = {
+	1,
+	0x16fe0, 0x16fff,
+}; /* CR_In_Ideographic_Symbols_and_Punctuation */
+
+/* 'In_Tangut': Block */
+static const OnigCodePoint CR_In_Tangut[] = {
+	1,
+	0x17000, 0x187ff,
+}; /* CR_In_Tangut */
+
+/* 'In_Tangut_Components': Block */
+static const OnigCodePoint CR_In_Tangut_Components[] = {
+	1,
+	0x18800, 0x18aff,
+}; /* CR_In_Tangut_Components */
+
+/* 'In_Kana_Supplement': Block */
+static const OnigCodePoint CR_In_Kana_Supplement[] = {
+	1,
+	0x1b000, 0x1b0ff,
+}; /* CR_In_Kana_Supplement */
+
+/* 'In_Kana_Extended_A': Block */
+static const OnigCodePoint CR_In_Kana_Extended_A[] = {
+	1,
+	0x1b100, 0x1b12f,
+}; /* CR_In_Kana_Extended_A */
+
+/* 'In_Nushu': Block */
+static const OnigCodePoint CR_In_Nushu[] = {
+	1,
+	0x1b170, 0x1b2ff,
+}; /* CR_In_Nushu */
+
+/* 'In_Duployan': Block */
+static const OnigCodePoint CR_In_Duployan[] = {
+	1,
+	0x1bc00, 0x1bc9f,
+}; /* CR_In_Duployan */
+
+/* 'In_Shorthand_Format_Controls': Block */
+static const OnigCodePoint CR_In_Shorthand_Format_Controls[] = {
+	1,
+	0x1bca0, 0x1bcaf,
+}; /* CR_In_Shorthand_Format_Controls */
+
+/* 'In_Byzantine_Musical_Symbols': Block */
+static const OnigCodePoint CR_In_Byzantine_Musical_Symbols[] = {
+	1,
+	0x1d000, 0x1d0ff,
+}; /* CR_In_Byzantine_Musical_Symbols */
+
+/* 'In_Musical_Symbols': Block */
+static const OnigCodePoint CR_In_Musical_Symbols[] = {
+	1,
+	0x1d100, 0x1d1ff,
+}; /* CR_In_Musical_Symbols */
+
+/* 'In_Ancient_Greek_Musical_Notation': Block */
+static const OnigCodePoint CR_In_Ancient_Greek_Musical_Notation[] = {
+	1,
+	0x1d200, 0x1d24f,
+}; /* CR_In_Ancient_Greek_Musical_Notation */
+
+/* 'In_Tai_Xuan_Jing_Symbols': Block */
+static const OnigCodePoint CR_In_Tai_Xuan_Jing_Symbols[] = {
+	1,
+	0x1d300, 0x1d35f,
+}; /* CR_In_Tai_Xuan_Jing_Symbols */
+
+/* 'In_Counting_Rod_Numerals': Block */
+static const OnigCodePoint CR_In_Counting_Rod_Numerals[] = {
+	1,
+	0x1d360, 0x1d37f,
+}; /* CR_In_Counting_Rod_Numerals */
+
+/* 'In_Mathematical_Alphanumeric_Symbols': Block */
+static const OnigCodePoint CR_In_Mathematical_Alphanumeric_Symbols[] = {
+	1,
+	0x1d400, 0x1d7ff,
+}; /* CR_In_Mathematical_Alphanumeric_Symbols */
+
+/* 'In_Sutton_SignWriting': Block */
+static const OnigCodePoint CR_In_Sutton_SignWriting[] = {
+	1,
+	0x1d800, 0x1daaf,
+}; /* CR_In_Sutton_SignWriting */
+
+/* 'In_Glagolitic_Supplement': Block */
+static const OnigCodePoint CR_In_Glagolitic_Supplement[] = {
+	1,
+	0x1e000, 0x1e02f,
+}; /* CR_In_Glagolitic_Supplement */
+
+/* 'In_Mende_Kikakui': Block */
+static const OnigCodePoint CR_In_Mende_Kikakui[] = {
+	1,
+	0x1e800, 0x1e8df,
+}; /* CR_In_Mende_Kikakui */
+
+/* 'In_Adlam': Block */
+static const OnigCodePoint CR_In_Adlam[] = {
+	1,
+	0x1e900, 0x1e95f,
+}; /* CR_In_Adlam */
+
+/* 'In_Arabic_Mathematical_Alphabetic_Symbols': Block */
+static const OnigCodePoint CR_In_Arabic_Mathematical_Alphabetic_Symbols[] = {
+	1,
+	0x1ee00, 0x1eeff,
+}; /* CR_In_Arabic_Mathematical_Alphabetic_Symbols */
+
+/* 'In_Mahjong_Tiles': Block */
+static const OnigCodePoint CR_In_Mahjong_Tiles[] = {
+	1,
+	0x1f000, 0x1f02f,
+}; /* CR_In_Mahjong_Tiles */
+
+/* 'In_Domino_Tiles': Block */
+static const OnigCodePoint CR_In_Domino_Tiles[] = {
+	1,
+	0x1f030, 0x1f09f,
+}; /* CR_In_Domino_Tiles */
+
+/* 'In_Playing_Cards': Block */
+static const OnigCodePoint CR_In_Playing_Cards[] = {
+	1,
+	0x1f0a0, 0x1f0ff,
+}; /* CR_In_Playing_Cards */
+
+/* 'In_Enclosed_Alphanumeric_Supplement': Block */
+static const OnigCodePoint CR_In_Enclosed_Alphanumeric_Supplement[] = {
+	1,
+	0x1f100, 0x1f1ff,
+}; /* CR_In_Enclosed_Alphanumeric_Supplement */
+
+/* 'In_Enclosed_Ideographic_Supplement': Block */
+static const OnigCodePoint CR_In_Enclosed_Ideographic_Supplement[] = {
+	1,
+	0x1f200, 0x1f2ff,
+}; /* CR_In_Enclosed_Ideographic_Supplement */
+
+/* 'In_Miscellaneous_Symbols_and_Pictographs': Block */
+static const OnigCodePoint CR_In_Miscellaneous_Symbols_and_Pictographs[] = {
+	1,
+	0x1f300, 0x1f5ff,
+}; /* CR_In_Miscellaneous_Symbols_and_Pictographs */
+
+/* 'In_Emoticons': Block */
+static const OnigCodePoint CR_In_Emoticons[] = {
+	1,
+	0x1f600, 0x1f64f,
+}; /* CR_In_Emoticons */
+
+/* 'In_Ornamental_Dingbats': Block */
+static const OnigCodePoint CR_In_Ornamental_Dingbats[] = {
+	1,
+	0x1f650, 0x1f67f,
+}; /* CR_In_Ornamental_Dingbats */
+
+/* 'In_Transport_and_Map_Symbols': Block */
+static const OnigCodePoint CR_In_Transport_and_Map_Symbols[] = {
+	1,
+	0x1f680, 0x1f6ff,
+}; /* CR_In_Transport_and_Map_Symbols */
+
+/* 'In_Alchemical_Symbols': Block */
+static const OnigCodePoint CR_In_Alchemical_Symbols[] = {
+	1,
+	0x1f700, 0x1f77f,
+}; /* CR_In_Alchemical_Symbols */
+
+/* 'In_Geometric_Shapes_Extended': Block */
+static const OnigCodePoint CR_In_Geometric_Shapes_Extended[] = {
+	1,
+	0x1f780, 0x1f7ff,
+}; /* CR_In_Geometric_Shapes_Extended */
+
+/* 'In_Supplemental_Arrows_C': Block */
+static const OnigCodePoint CR_In_Supplemental_Arrows_C[] = {
+	1,
+	0x1f800, 0x1f8ff,
+}; /* CR_In_Supplemental_Arrows_C */
+
+/* 'In_Supplemental_Symbols_and_Pictographs': Block */
+static const OnigCodePoint CR_In_Supplemental_Symbols_and_Pictographs[] = {
+	1,
+	0x1f900, 0x1f9ff,
+}; /* CR_In_Supplemental_Symbols_and_Pictographs */
+
+/* 'In_CJK_Unified_Ideographs_Extension_B': Block */
+static const OnigCodePoint CR_In_CJK_Unified_Ideographs_Extension_B[] = {
+	1,
+	0x20000, 0x2a6df,
+}; /* CR_In_CJK_Unified_Ideographs_Extension_B */
+
+/* 'In_CJK_Unified_Ideographs_Extension_C': Block */
+static const OnigCodePoint CR_In_CJK_Unified_Ideographs_Extension_C[] = {
+	1,
+	0x2a700, 0x2b73f,
+}; /* CR_In_CJK_Unified_Ideographs_Extension_C */
+
+/* 'In_CJK_Unified_Ideographs_Extension_D': Block */
+static const OnigCodePoint CR_In_CJK_Unified_Ideographs_Extension_D[] = {
+	1,
+	0x2b740, 0x2b81f,
+}; /* CR_In_CJK_Unified_Ideographs_Extension_D */
+
+/* 'In_CJK_Unified_Ideographs_Extension_E': Block */
+static const OnigCodePoint CR_In_CJK_Unified_Ideographs_Extension_E[] = {
+	1,
+	0x2b820, 0x2ceaf,
+}; /* CR_In_CJK_Unified_Ideographs_Extension_E */
+
+/* 'In_CJK_Unified_Ideographs_Extension_F': Block */
+static const OnigCodePoint CR_In_CJK_Unified_Ideographs_Extension_F[] = {
+	1,
+	0x2ceb0, 0x2ebef,
+}; /* CR_In_CJK_Unified_Ideographs_Extension_F */
+
+/* 'In_CJK_Compatibility_Ideographs_Supplement': Block */
+static const OnigCodePoint CR_In_CJK_Compatibility_Ideographs_Supplement[] = {
+	1,
+	0x2f800, 0x2fa1f,
+}; /* CR_In_CJK_Compatibility_Ideographs_Supplement */
+
+/* 'In_Tags': Block */
+static const OnigCodePoint CR_In_Tags[] = {
+	1,
+	0xe0000, 0xe007f,
+}; /* CR_In_Tags */
+
+/* 'In_Variation_Selectors_Supplement': Block */
+static const OnigCodePoint CR_In_Variation_Selectors_Supplement[] = {
+	1,
+	0xe0100, 0xe01ef,
+}; /* CR_In_Variation_Selectors_Supplement */
+
+/* 'In_Supplementary_Private_Use_Area_A': Block */
+static const OnigCodePoint CR_In_Supplementary_Private_Use_Area_A[] = {
+	1,
+	0xf0000, 0xfffff,
+}; /* CR_In_Supplementary_Private_Use_Area_A */
+
+/* 'In_Supplementary_Private_Use_Area_B': Block */
+static const OnigCodePoint CR_In_Supplementary_Private_Use_Area_B[] = {
+	1,
+	0x100000, 0x10ffff,
+}; /* CR_In_Supplementary_Private_Use_Area_B */
+
+/* 'In_No_Block': Block */
+static const OnigCodePoint CR_In_No_Block[] = {
+	47,
+	0x0870, 0x089f,
+	0x1c90, 0x1cbf,
+	0x2fe0, 0x2fef,
+	0x10200, 0x1027f,
+	0x103e0, 0x103ff,
+	0x10570, 0x105ff,
+	0x10780, 0x107ff,
+	0x108b0, 0x108df,
+	0x10940, 0x1097f,
+	0x10aa0, 0x10abf,
+	0x10bb0, 0x10bff,
+	0x10c50, 0x10c7f,
+	0x10d00, 0x10e5f,
+	0x10e80, 0x10fff,
+	0x11250, 0x1127f,
+	0x11380, 0x113ff,
+	0x114e0, 0x1157f,
+	0x116d0, 0x116ff,
+	0x11740, 0x1189f,
+	0x11900, 0x119ff,
+	0x11ab0, 0x11abf,
+	0x11b00, 0x11bff,
+	0x11cc0, 0x11cff,
+	0x11d60, 0x11fff,
+	0x12550, 0x12fff,
+	0x13430, 0x143ff,
+	0x14680, 0x167ff,
+	0x16a70, 0x16acf,
+	0x16b90, 0x16eff,
+	0x16fa0, 0x16fdf,
+	0x18b00, 0x1afff,
+	0x1b130, 0x1b16f,
+	0x1b300, 0x1bbff,
+	0x1bcb0, 0x1cfff,
+	0x1d250, 0x1d2ff,
+	0x1d380, 0x1d3ff,
+	0x1dab0, 0x1dfff,
+	0x1e030, 0x1e7ff,
+	0x1e8e0, 0x1e8ff,
+	0x1e960, 0x1edff,
+	0x1ef00, 0x1efff,
+	0x1fa00, 0x1ffff,
+	0x2a6e0, 0x2a6ff,
+	0x2ebf0, 0x2f7ff,
+	0x2fa20, 0xdffff,
+	0xe0080, 0xe00ff,
+	0xe01f0, 0xeffff,
+}; /* CR_In_No_Block */
+
+#endif /* USE_UNICODE_PROPERTIES */
+static const OnigCodePoint* const CodeRanges[] = {
+  CR_NEWLINE,
+  CR_Alpha,
+  CR_Blank,
+  CR_Cntrl,
+  CR_Digit,
+  CR_Graph,
+  CR_Lower,
+  CR_Print,
+  CR_XPosixPunct,
+  CR_Space,
+  CR_Upper,
+  CR_XDigit,
+  CR_Word,
+  CR_Alnum,
+  CR_ASCII,
+  CR_Punct,
+#ifdef USE_UNICODE_PROPERTIES
+  CR_Any,
+  CR_Assigned,
+  CR_C,
+  CR_Cc,
+  CR_Cf,
+  CR_Cn,
+  CR_Co,
+  CR_Cs,
+  CR_L,
+  CR_LC,
+  CR_Ll,
+  CR_Lm,
+  CR_Lo,
+  CR_Lt,
+  CR_Lu,
+  CR_M,
+  CR_Mc,
+  CR_Me,
+  CR_Mn,
+  CR_N,
+  CR_Nd,
+  CR_Nl,
+  CR_No,
+  CR_P,
+  CR_Pc,
+  CR_Pd,
+  CR_Pe,
+  CR_Pf,
+  CR_Pi,
+  CR_Po,
+  CR_Ps,
+  CR_S,
+  CR_Sc,
+  CR_Sk,
+  CR_Sm,
+  CR_So,
+  CR_Z,
+  CR_Zl,
+  CR_Zp,
+  CR_Zs,
+  CR_Math,
+  CR_Alphabetic,
+  CR_Lowercase,
+  CR_Uppercase,
+  CR_Cased,
+  CR_Case_Ignorable,
+  CR_Changes_When_Lowercased,
+  CR_Changes_When_Uppercased,
+  CR_Changes_When_Titlecased,
+  CR_Changes_When_Casefolded,
+  CR_Changes_When_Casemapped,
+  CR_ID_Start,
+  CR_ID_Continue,
+  CR_XID_Start,
+  CR_XID_Continue,
+  CR_Default_Ignorable_Code_Point,
+  CR_Grapheme_Extend,
+  CR_Grapheme_Base,
+  CR_Grapheme_Link,
+  CR_Common,
+  CR_Latin,
+  CR_Greek,
+  CR_Cyrillic,
+  CR_Armenian,
+  CR_Hebrew,
+  CR_Arabic,
+  CR_Syriac,
+  CR_Thaana,
+  CR_Devanagari,
+  CR_Bengali,
+  CR_Gurmukhi,
+  CR_Gujarati,
+  CR_Oriya,
+  CR_Tamil,
+  CR_Telugu,
+  CR_Kannada,
+  CR_Malayalam,
+  CR_Sinhala,
+  CR_Thai,
+  CR_Lao,
+  CR_Tibetan,
+  CR_Myanmar,
+  CR_Georgian,
+  CR_Hangul,
+  CR_Ethiopic,
+  CR_Cherokee,
+  CR_Canadian_Aboriginal,
+  CR_Ogham,
+  CR_Runic,
+  CR_Khmer,
+  CR_Mongolian,
+  CR_Hiragana,
+  CR_Katakana,
+  CR_Bopomofo,
+  CR_Han,
+  CR_Yi,
+  CR_Old_Italic,
+  CR_Gothic,
+  CR_Deseret,
+  CR_Inherited,
+  CR_Tagalog,
+  CR_Hanunoo,
+  CR_Buhid,
+  CR_Tagbanwa,
+  CR_Limbu,
+  CR_Tai_Le,
+  CR_Linear_B,
+  CR_Ugaritic,
+  CR_Shavian,
+  CR_Osmanya,
+  CR_Cypriot,
+  CR_Braille,
+  CR_Buginese,
+  CR_Coptic,
+  CR_New_Tai_Lue,
+  CR_Glagolitic,
+  CR_Tifinagh,
+  CR_Syloti_Nagri,
+  CR_Old_Persian,
+  CR_Kharoshthi,
+  CR_Balinese,
+  CR_Cuneiform,
+  CR_Phoenician,
+  CR_Phags_Pa,
+  CR_Nko,
+  CR_Sundanese,
+  CR_Lepcha,
+  CR_Ol_Chiki,
+  CR_Vai,
+  CR_Saurashtra,
+  CR_Kayah_Li,
+  CR_Rejang,
+  CR_Lycian,
+  CR_Carian,
+  CR_Lydian,
+  CR_Cham,
+  CR_Tai_Tham,
+  CR_Tai_Viet,
+  CR_Avestan,
+  CR_Egyptian_Hieroglyphs,
+  CR_Samaritan,
+  CR_Lisu,
+  CR_Bamum,
+  CR_Javanese,
+  CR_Meetei_Mayek,
+  CR_Imperial_Aramaic,
+  CR_Old_South_Arabian,
+  CR_Inscriptional_Parthian,
+  CR_Inscriptional_Pahlavi,
+  CR_Old_Turkic,
+  CR_Kaithi,
+  CR_Batak,
+  CR_Brahmi,
+  CR_Mandaic,
+  CR_Chakma,
+  CR_Meroitic_Cursive,
+  CR_Meroitic_Hieroglyphs,
+  CR_Miao,
+  CR_Sharada,
+  CR_Sora_Sompeng,
+  CR_Takri,
+  CR_Caucasian_Albanian,
+  CR_Bassa_Vah,
+  CR_Duployan,
+  CR_Elbasan,
+  CR_Grantha,
+  CR_Pahawh_Hmong,
+  CR_Khojki,
+  CR_Linear_A,
+  CR_Mahajani,
+  CR_Manichaean,
+  CR_Mende_Kikakui,
+  CR_Modi,
+  CR_Mro,
+  CR_Old_North_Arabian,
+  CR_Nabataean,
+  CR_Palmyrene,
+  CR_Pau_Cin_Hau,
+  CR_Old_Permic,
+  CR_Psalter_Pahlavi,
+  CR_Siddham,
+  CR_Khudawadi,
+  CR_Tirhuta,
+  CR_Warang_Citi,
+  CR_Ahom,
+  CR_Anatolian_Hieroglyphs,
+  CR_Hatran,
+  CR_Multani,
+  CR_Old_Hungarian,
+  CR_SignWriting,
+  CR_Adlam,
+  CR_Bhaiksuki,
+  CR_Marchen,
+  CR_Newa,
+  CR_Osage,
+  CR_Tangut,
+  CR_Masaram_Gondi,
+  CR_Nushu,
+  CR_Soyombo,
+  CR_Zanabazar_Square,
+  CR_White_Space,
+  CR_Bidi_Control,
+  CR_Join_Control,
+  CR_Dash,
+  CR_Hyphen,
+  CR_Quotation_Mark,
+  CR_Terminal_Punctuation,
+  CR_Other_Math,
+  CR_Hex_Digit,
+  CR_ASCII_Hex_Digit,
+  CR_Other_Alphabetic,
+  CR_Ideographic,
+  CR_Diacritic,
+  CR_Extender,
+  CR_Other_Lowercase,
+  CR_Other_Uppercase,
+  CR_Noncharacter_Code_Point,
+  CR_Other_Grapheme_Extend,
+  CR_IDS_Binary_Operator,
+  CR_IDS_Trinary_Operator,
+  CR_Radical,
+  CR_Unified_Ideograph,
+  CR_Other_Default_Ignorable_Code_Point,
+  CR_Deprecated,
+  CR_Soft_Dotted,
+  CR_Logical_Order_Exception,
+  CR_Other_ID_Start,
+  CR_Other_ID_Continue,
+  CR_Sentence_Terminal,
+  CR_Variation_Selector,
+  CR_Pattern_White_Space,
+  CR_Pattern_Syntax,
+  CR_Prepended_Concatenation_Mark,
+  CR_Regional_Indicator,
+  CR_Emoji,
+  CR_Emoji_Presentation,
+  CR_Emoji_Modifier,
+  CR_Emoji_Modifier_Base,
+  CR_Emoji_Component,
+  CR_Unknown,
+#ifdef USE_UNICODE_AGE_PROPERTIES
+  CR_Age_1_1,
+  CR_Age_2_0,
+  CR_Age_2_1,
+  CR_Age_3_0,
+  CR_Age_3_1,
+  CR_Age_3_2,
+  CR_Age_4_0,
+  CR_Age_4_1,
+  CR_Age_5_0,
+  CR_Age_5_1,
+  CR_Age_5_2,
+  CR_Age_6_0,
+  CR_Age_6_1,
+  CR_Age_6_2,
+  CR_Age_6_3,
+  CR_Age_7_0,
+  CR_Age_8_0,
+  CR_Age_9_0,
+  CR_Age_10_0,
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+  CR_Grapheme_Cluster_Break_Prepend,
+  CR_Grapheme_Cluster_Break_CR,
+  CR_Grapheme_Cluster_Break_LF,
+  CR_Grapheme_Cluster_Break_Control,
+  CR_Grapheme_Cluster_Break_Extend,
+  CR_Grapheme_Cluster_Break_Regional_Indicator,
+  CR_Grapheme_Cluster_Break_SpacingMark,
+  CR_Grapheme_Cluster_Break_L,
+  CR_Grapheme_Cluster_Break_V,
+  CR_Grapheme_Cluster_Break_T,
+  CR_Grapheme_Cluster_Break_LV,
+  CR_Grapheme_Cluster_Break_LVT,
+  CR_Grapheme_Cluster_Break_E_Base,
+  CR_Grapheme_Cluster_Break_E_Modifier,
+  CR_Grapheme_Cluster_Break_ZWJ,
+  CR_Grapheme_Cluster_Break_Glue_After_Zwj,
+  CR_Grapheme_Cluster_Break_E_Base_GAZ,
+  CR_In_Basic_Latin,
+  CR_In_Latin_1_Supplement,
+  CR_In_Latin_Extended_A,
+  CR_In_Latin_Extended_B,
+  CR_In_IPA_Extensions,
+  CR_In_Spacing_Modifier_Letters,
+  CR_In_Combining_Diacritical_Marks,
+  CR_In_Greek_and_Coptic,
+  CR_In_Cyrillic,
+  CR_In_Cyrillic_Supplement,
+  CR_In_Armenian,
+  CR_In_Hebrew,
+  CR_In_Arabic,
+  CR_In_Syriac,
+  CR_In_Arabic_Supplement,
+  CR_In_Thaana,
+  CR_In_NKo,
+  CR_In_Samaritan,
+  CR_In_Mandaic,
+  CR_In_Syriac_Supplement,
+  CR_In_Arabic_Extended_A,
+  CR_In_Devanagari,
+  CR_In_Bengali,
+  CR_In_Gurmukhi,
+  CR_In_Gujarati,
+  CR_In_Oriya,
+  CR_In_Tamil,
+  CR_In_Telugu,
+  CR_In_Kannada,
+  CR_In_Malayalam,
+  CR_In_Sinhala,
+  CR_In_Thai,
+  CR_In_Lao,
+  CR_In_Tibetan,
+  CR_In_Myanmar,
+  CR_In_Georgian,
+  CR_In_Hangul_Jamo,
+  CR_In_Ethiopic,
+  CR_In_Ethiopic_Supplement,
+  CR_In_Cherokee,
+  CR_In_Unified_Canadian_Aboriginal_Syllabics,
+  CR_In_Ogham,
+  CR_In_Runic,
+  CR_In_Tagalog,
+  CR_In_Hanunoo,
+  CR_In_Buhid,
+  CR_In_Tagbanwa,
+  CR_In_Khmer,
+  CR_In_Mongolian,
+  CR_In_Unified_Canadian_Aboriginal_Syllabics_Extended,
+  CR_In_Limbu,
+  CR_In_Tai_Le,
+  CR_In_New_Tai_Lue,
+  CR_In_Khmer_Symbols,
+  CR_In_Buginese,
+  CR_In_Tai_Tham,
+  CR_In_Combining_Diacritical_Marks_Extended,
+  CR_In_Balinese,
+  CR_In_Sundanese,
+  CR_In_Batak,
+  CR_In_Lepcha,
+  CR_In_Ol_Chiki,
+  CR_In_Cyrillic_Extended_C,
+  CR_In_Sundanese_Supplement,
+  CR_In_Vedic_Extensions,
+  CR_In_Phonetic_Extensions,
+  CR_In_Phonetic_Extensions_Supplement,
+  CR_In_Combining_Diacritical_Marks_Supplement,
+  CR_In_Latin_Extended_Additional,
+  CR_In_Greek_Extended,
+  CR_In_General_Punctuation,
+  CR_In_Superscripts_and_Subscripts,
+  CR_In_Currency_Symbols,
+  CR_In_Combining_Diacritical_Marks_for_Symbols,
+  CR_In_Letterlike_Symbols,
+  CR_In_Number_Forms,
+  CR_In_Arrows,
+  CR_In_Mathematical_Operators,
+  CR_In_Miscellaneous_Technical,
+  CR_In_Control_Pictures,
+  CR_In_Optical_Character_Recognition,
+  CR_In_Enclosed_Alphanumerics,
+  CR_In_Box_Drawing,
+  CR_In_Block_Elements,
+  CR_In_Geometric_Shapes,
+  CR_In_Miscellaneous_Symbols,
+  CR_In_Dingbats,
+  CR_In_Miscellaneous_Mathematical_Symbols_A,
+  CR_In_Supplemental_Arrows_A,
+  CR_In_Braille_Patterns,
+  CR_In_Supplemental_Arrows_B,
+  CR_In_Miscellaneous_Mathematical_Symbols_B,
+  CR_In_Supplemental_Mathematical_Operators,
+  CR_In_Miscellaneous_Symbols_and_Arrows,
+  CR_In_Glagolitic,
+  CR_In_Latin_Extended_C,
+  CR_In_Coptic,
+  CR_In_Georgian_Supplement,
+  CR_In_Tifinagh,
+  CR_In_Ethiopic_Extended,
+  CR_In_Cyrillic_Extended_A,
+  CR_In_Supplemental_Punctuation,
+  CR_In_CJK_Radicals_Supplement,
+  CR_In_Kangxi_Radicals,
+  CR_In_Ideographic_Description_Characters,
+  CR_In_CJK_Symbols_and_Punctuation,
+  CR_In_Hiragana,
+  CR_In_Katakana,
+  CR_In_Bopomofo,
+  CR_In_Hangul_Compatibility_Jamo,
+  CR_In_Kanbun,
+  CR_In_Bopomofo_Extended,
+  CR_In_CJK_Strokes,
+  CR_In_Katakana_Phonetic_Extensions,
+  CR_In_Enclosed_CJK_Letters_and_Months,
+  CR_In_CJK_Compatibility,
+  CR_In_CJK_Unified_Ideographs_Extension_A,
+  CR_In_Yijing_Hexagram_Symbols,
+  CR_In_CJK_Unified_Ideographs,
+  CR_In_Yi_Syllables,
+  CR_In_Yi_Radicals,
+  CR_In_Lisu,
+  CR_In_Vai,
+  CR_In_Cyrillic_Extended_B,
+  CR_In_Bamum,
+  CR_In_Modifier_Tone_Letters,
+  CR_In_Latin_Extended_D,
+  CR_In_Syloti_Nagri,
+  CR_In_Common_Indic_Number_Forms,
+  CR_In_Phags_pa,
+  CR_In_Saurashtra,
+  CR_In_Devanagari_Extended,
+  CR_In_Kayah_Li,
+  CR_In_Rejang,
+  CR_In_Hangul_Jamo_Extended_A,
+  CR_In_Javanese,
+  CR_In_Myanmar_Extended_B,
+  CR_In_Cham,
+  CR_In_Myanmar_Extended_A,
+  CR_In_Tai_Viet,
+  CR_In_Meetei_Mayek_Extensions,
+  CR_In_Ethiopic_Extended_A,
+  CR_In_Latin_Extended_E,
+  CR_In_Cherokee_Supplement,
+  CR_In_Meetei_Mayek,
+  CR_In_Hangul_Syllables,
+  CR_In_Hangul_Jamo_Extended_B,
+  CR_In_High_Surrogates,
+  CR_In_High_Private_Use_Surrogates,
+  CR_In_Low_Surrogates,
+  CR_In_Private_Use_Area,
+  CR_In_CJK_Compatibility_Ideographs,
+  CR_In_Alphabetic_Presentation_Forms,
+  CR_In_Arabic_Presentation_Forms_A,
+  CR_In_Variation_Selectors,
+  CR_In_Vertical_Forms,
+  CR_In_Combining_Half_Marks,
+  CR_In_CJK_Compatibility_Forms,
+  CR_In_Small_Form_Variants,
+  CR_In_Arabic_Presentation_Forms_B,
+  CR_In_Halfwidth_and_Fullwidth_Forms,
+  CR_In_Specials,
+  CR_In_Linear_B_Syllabary,
+  CR_In_Linear_B_Ideograms,
+  CR_In_Aegean_Numbers,
+  CR_In_Ancient_Greek_Numbers,
+  CR_In_Ancient_Symbols,
+  CR_In_Phaistos_Disc,
+  CR_In_Lycian,
+  CR_In_Carian,
+  CR_In_Coptic_Epact_Numbers,
+  CR_In_Old_Italic,
+  CR_In_Gothic,
+  CR_In_Old_Permic,
+  CR_In_Ugaritic,
+  CR_In_Old_Persian,
+  CR_In_Deseret,
+  CR_In_Shavian,
+  CR_In_Osmanya,
+  CR_In_Osage,
+  CR_In_Elbasan,
+  CR_In_Caucasian_Albanian,
+  CR_In_Linear_A,
+  CR_In_Cypriot_Syllabary,
+  CR_In_Imperial_Aramaic,
+  CR_In_Palmyrene,
+  CR_In_Nabataean,
+  CR_In_Hatran,
+  CR_In_Phoenician,
+  CR_In_Lydian,
+  CR_In_Meroitic_Hieroglyphs,
+  CR_In_Meroitic_Cursive,
+  CR_In_Kharoshthi,
+  CR_In_Old_South_Arabian,
+  CR_In_Old_North_Arabian,
+  CR_In_Manichaean,
+  CR_In_Avestan,
+  CR_In_Inscriptional_Parthian,
+  CR_In_Inscriptional_Pahlavi,
+  CR_In_Psalter_Pahlavi,
+  CR_In_Old_Turkic,
+  CR_In_Old_Hungarian,
+  CR_In_Rumi_Numeral_Symbols,
+  CR_In_Brahmi,
+  CR_In_Kaithi,
+  CR_In_Sora_Sompeng,
+  CR_In_Chakma,
+  CR_In_Mahajani,
+  CR_In_Sharada,
+  CR_In_Sinhala_Archaic_Numbers,
+  CR_In_Khojki,
+  CR_In_Multani,
+  CR_In_Khudawadi,
+  CR_In_Grantha,
+  CR_In_Newa,
+  CR_In_Tirhuta,
+  CR_In_Siddham,
+  CR_In_Modi,
+  CR_In_Mongolian_Supplement,
+  CR_In_Takri,
+  CR_In_Ahom,
+  CR_In_Warang_Citi,
+  CR_In_Zanabazar_Square,
+  CR_In_Soyombo,
+  CR_In_Pau_Cin_Hau,
+  CR_In_Bhaiksuki,
+  CR_In_Marchen,
+  CR_In_Masaram_Gondi,
+  CR_In_Cuneiform,
+  CR_In_Cuneiform_Numbers_and_Punctuation,
+  CR_In_Early_Dynastic_Cuneiform,
+  CR_In_Egyptian_Hieroglyphs,
+  CR_In_Anatolian_Hieroglyphs,
+  CR_In_Bamum_Supplement,
+  CR_In_Mro,
+  CR_In_Bassa_Vah,
+  CR_In_Pahawh_Hmong,
+  CR_In_Miao,
+  CR_In_Ideographic_Symbols_and_Punctuation,
+  CR_In_Tangut,
+  CR_In_Tangut_Components,
+  CR_In_Kana_Supplement,
+  CR_In_Kana_Extended_A,
+  CR_In_Nushu,
+  CR_In_Duployan,
+  CR_In_Shorthand_Format_Controls,
+  CR_In_Byzantine_Musical_Symbols,
+  CR_In_Musical_Symbols,
+  CR_In_Ancient_Greek_Musical_Notation,
+  CR_In_Tai_Xuan_Jing_Symbols,
+  CR_In_Counting_Rod_Numerals,
+  CR_In_Mathematical_Alphanumeric_Symbols,
+  CR_In_Sutton_SignWriting,
+  CR_In_Glagolitic_Supplement,
+  CR_In_Mende_Kikakui,
+  CR_In_Adlam,
+  CR_In_Arabic_Mathematical_Alphabetic_Symbols,
+  CR_In_Mahjong_Tiles,
+  CR_In_Domino_Tiles,
+  CR_In_Playing_Cards,
+  CR_In_Enclosed_Alphanumeric_Supplement,
+  CR_In_Enclosed_Ideographic_Supplement,
+  CR_In_Miscellaneous_Symbols_and_Pictographs,
+  CR_In_Emoticons,
+  CR_In_Ornamental_Dingbats,
+  CR_In_Transport_and_Map_Symbols,
+  CR_In_Alchemical_Symbols,
+  CR_In_Geometric_Shapes_Extended,
+  CR_In_Supplemental_Arrows_C,
+  CR_In_Supplemental_Symbols_and_Pictographs,
+  CR_In_CJK_Unified_Ideographs_Extension_B,
+  CR_In_CJK_Unified_Ideographs_Extension_C,
+  CR_In_CJK_Unified_Ideographs_Extension_D,
+  CR_In_CJK_Unified_Ideographs_Extension_E,
+  CR_In_CJK_Unified_Ideographs_Extension_F,
+  CR_In_CJK_Compatibility_Ideographs_Supplement,
+  CR_In_Tags,
+  CR_In_Variation_Selectors_Supplement,
+  CR_In_Supplementary_Private_Use_Area_A,
+  CR_In_Supplementary_Private_Use_Area_B,
+  CR_In_No_Block,
+#endif /* USE_UNICODE_PROPERTIES */
+};
+struct uniname2ctype_struct {
+  short name;
+  unsigned short ctype;
+};
+#define uniname2ctype_offset(str) offsetof(struct uniname2ctype_pool_t, uniname2ctype_pool_##str)
+
+static const struct uniname2ctype_struct *uniname2ctype_p(const char *, unsigned int);
+
+#ifndef USE_UNICODE_PROPERTIES
+#define TOTAL_KEYWORDS 15
+#define MIN_WORD_LENGTH 4
+#define MAX_WORD_LENGTH 11
+#define MIN_HASH_VALUE 6
+#define MAX_HASH_VALUE 20
+/* maximum key range = 15, duplicates = 0 */
+#else /* USE_UNICODE_PROPERTIES */
+#ifndef USE_UNICODE_AGE_PROPERTIES
+#define TOTAL_KEYWORDS 775
+#else /* USE_UNICODE_AGE_PROPERTIES */
+#define TOTAL_KEYWORDS 794
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+#define MIN_WORD_LENGTH 1
+#define MAX_WORD_LENGTH 44
+#define MIN_HASH_VALUE 10
+#define MAX_HASH_VALUE 6145
+/* maximum key range = 6136, duplicates = 0 */
+#endif /* USE_UNICODE_PROPERTIES */
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static unsigned int
+uniname2ctype_hash (str, len)
+     register const char *str;
+     register unsigned int len;
+{
+#ifndef USE_UNICODE_PROPERTIES
+  static const unsigned char asso_values[] =
+#else /* USE_UNICODE_PROPERTIES */
+  static const unsigned short asso_values[] =
+#endif /* USE_UNICODE_PROPERTIES */
+    {
+#ifndef USE_UNICODE_PROPERTIES
+      21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+      21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+      21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+      21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+      21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+      21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+      21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+      21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+      21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+      21, 21, 21, 21, 21, 21, 21,  3, 12,  5,
+       4, 21, 21, 10, 21,  1, 21, 21, 11, 21,
+       2,  1,  1, 21,  1,  7,  4,  6, 21,  1,
+       4, 21, 21, 21, 21, 21, 21, 21
+#else /* USE_UNICODE_PROPERTIES */
+      6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146,
+      6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146,
+      6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146,
+      6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146,
+#ifndef USE_UNICODE_AGE_PROPERTIES
+      6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146,
+      6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146,
+#else /* USE_UNICODE_AGE_PROPERTIES */
+      6146, 6146, 6146, 6146, 6146, 6146,    1, 6146,    2,    1,
+         5,   27,    2,   15,    7,   11,    9,    8, 6146, 6146,
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+      6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146,
+      6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146,
+      6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146, 6146,
+      6146, 6146, 6146, 6146, 6146, 6146, 6146,    5, 1058,  101,
+       332,    9,  777, 1271,  842,    3, 1142,   17,  491,   70,
+         1,   15,  741, 1115,   39,  174,  260,  566, 1127, 1473,
+       502, 1554,   13,    2,   12, 6146, 6146, 6146, 6146, 6146
+#endif /* USE_UNICODE_PROPERTIES */
+    };
+#ifndef USE_UNICODE_PROPERTIES
+  return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]];
+#else /* USE_UNICODE_PROPERTIES */
+  register int hval = len;
+
+  switch (hval)
+    {
+      default:
+        hval += asso_values[(unsigned char)str[15]];
+      /*FALLTHROUGH*/
+      case 15:
+      case 14:
+      case 13:
+      case 12:
+        hval += asso_values[(unsigned char)str[11]];
+      /*FALLTHROUGH*/
+      case 11:
+      case 10:
+      case 9:
+      case 8:
+      case 7:
+      case 6:
+        hval += asso_values[(unsigned char)str[5]];
+      /*FALLTHROUGH*/
+      case 5:
+        hval += asso_values[(unsigned char)str[4]];
+      /*FALLTHROUGH*/
+      case 4:
+      case 3:
+        hval += asso_values[(unsigned char)str[2]];
+      /*FALLTHROUGH*/
+      case 2:
+        hval += asso_values[(unsigned char)str[1]];
+      /*FALLTHROUGH*/
+      case 1:
+        hval += asso_values[(unsigned char)str[0]+2];
+        break;
+    }
+  return hval + asso_values[(unsigned char)str[len - 1]];
+#endif /* USE_UNICODE_PROPERTIES */
+}
+
+struct uniname2ctype_pool_t
+  {
+#ifndef USE_UNICODE_PROPERTIES
+    char uniname2ctype_pool_str6[sizeof("word")];
+    char uniname2ctype_pool_str7[sizeof("print")];
+    char uniname2ctype_pool_str8[sizeof("punct")];
+    char uniname2ctype_pool_str9[sizeof("alpha")];
+    char uniname2ctype_pool_str10[sizeof("alnum")];
+    char uniname2ctype_pool_str11[sizeof("xdigit")];
+    char uniname2ctype_pool_str12[sizeof("upper")];
+    char uniname2ctype_pool_str13[sizeof("ascii")];
+    char uniname2ctype_pool_str14[sizeof("cntrl")];
+    char uniname2ctype_pool_str15[sizeof("space")];
+    char uniname2ctype_pool_str16[sizeof("xposixpunct")];
+    char uniname2ctype_pool_str17[sizeof("lower")];
+    char uniname2ctype_pool_str18[sizeof("graph")];
+    char uniname2ctype_pool_str19[sizeof("digit")];
+    char uniname2ctype_pool_str20[sizeof("blank")];
+#else /* USE_UNICODE_PROPERTIES */
+    char uniname2ctype_pool_str10[sizeof("yi")];
+    char uniname2ctype_pool_str13[sizeof("cn")];
+    char uniname2ctype_pool_str14[sizeof("lina")];
+    char uniname2ctype_pool_str15[sizeof("yiii")];
+    char uniname2ctype_pool_str16[sizeof("lana")];
+    char uniname2ctype_pool_str17[sizeof("ci")];
+    char uniname2ctype_pool_str19[sizeof("mn")];
+    char uniname2ctype_pool_str26[sizeof("z")];
+    char uniname2ctype_pool_str28[sizeof("mani")];
+    char uniname2ctype_pool_str33[sizeof("lo")];
+    char uniname2ctype_pool_str35[sizeof("me")];
+    char uniname2ctype_pool_str37[sizeof("loe")];
+    char uniname2ctype_pool_str39[sizeof("lao")];
+    char uniname2ctype_pool_str40[sizeof("laoo")];
+    char uniname2ctype_pool_str41[sizeof("co")];
+    char uniname2ctype_pool_str42[sizeof("miao")];
+    char uniname2ctype_pool_str47[sizeof("pi")];
+    char uniname2ctype_pool_str51[sizeof("inkannada")];
+    char uniname2ctype_pool_str52[sizeof("gran")];
+    char uniname2ctype_pool_str54[sizeof("innko")];
+    char uniname2ctype_pool_str55[sizeof("zzzz")];
+    char uniname2ctype_pool_str59[sizeof("pe")];
+    char uniname2ctype_pool_str60[sizeof("cari")];
+    char uniname2ctype_pool_str61[sizeof("lineara")];
+    char uniname2ctype_pool_str66[sizeof("carian")];
+    char uniname2ctype_pool_str69[sizeof("mendekikakui")];
+    char uniname2ctype_pool_str70[sizeof("geor")];
+    char uniname2ctype_pool_str71[sizeof("po")];
+    char uniname2ctype_pool_str72[sizeof("grek")];
+    char uniname2ctype_pool_str73[sizeof("meeteimayek")];
+    char uniname2ctype_pool_str80[sizeof("mark")];
+    char uniname2ctype_pool_str82[sizeof("mero")];
+    char uniname2ctype_pool_str85[sizeof("kana")];
+    char uniname2ctype_pool_str86[sizeof("m")];
+    char uniname2ctype_pool_str87[sizeof("mro")];
+    char uniname2ctype_pool_str88[sizeof("mroo")];
+    char uniname2ctype_pool_str90[sizeof("greek")];
+    char uniname2ctype_pool_str93[sizeof("gonm")];
+    char uniname2ctype_pool_str97[sizeof("inkharoshthi")];
+    char uniname2ctype_pool_str105[sizeof("cakm")];
+    char uniname2ctype_pool_str106[sizeof("inmanichaean")];
+    char uniname2ctype_pool_str111[sizeof("c")];
+    char uniname2ctype_pool_str113[sizeof("inarmenian")];
+    char uniname2ctype_pool_str117[sizeof("common")];
+    char uniname2ctype_pool_str122[sizeof("inosmanya")];
+    char uniname2ctype_pool_str123[sizeof("inmro")];
+    char uniname2ctype_pool_str129[sizeof("inmiao")];
+    char uniname2ctype_pool_str137[sizeof("mandaic")];
+    char uniname2ctype_pool_str142[sizeof("inmyanmar")];
+    char uniname2ctype_pool_str143[sizeof("lm")];
+    char uniname2ctype_pool_str150[sizeof("prependedconcatenationmark")];
+    char uniname2ctype_pool_str153[sizeof("inideographicsymbolsandpunctuation")];
+    char uniname2ctype_pool_str154[sizeof("inchakma")];
+    char uniname2ctype_pool_str160[sizeof("inkhmer")];
+    char uniname2ctype_pool_str161[sizeof("perm")];
+    char uniname2ctype_pool_str162[sizeof("connectorpunctuation")];
+    char uniname2ctype_pool_str164[sizeof("marc")];
+    char uniname2ctype_pool_str167[sizeof("combiningmark")];
+    char uniname2ctype_pool_str168[sizeof("merc")];
+    char uniname2ctype_pool_str169[sizeof("inrunic")];
+    char uniname2ctype_pool_str170[sizeof("incarian")];
+    char uniname2ctype_pool_str172[sizeof("incuneiformnumbersandpunctuation")];
+    char uniname2ctype_pool_str184[sizeof("inahom")];
+    char uniname2ctype_pool_str186[sizeof("incherokee")];
+    char uniname2ctype_pool_str191[sizeof("qaai")];
+    char uniname2ctype_pool_str193[sizeof("cans")];
+    char uniname2ctype_pool_str205[sizeof("lc")];
+    char uniname2ctype_pool_str210[sizeof("incuneiform")];
+    char uniname2ctype_pool_str213[sizeof("cc")];
+    char uniname2ctype_pool_str215[sizeof("armn")];
+    char uniname2ctype_pool_str216[sizeof("inavestan")];
+    char uniname2ctype_pool_str217[sizeof("armi")];
+    char uniname2ctype_pool_str219[sizeof("mc")];
+    char uniname2ctype_pool_str223[sizeof("armenian")];
+    char uniname2ctype_pool_str227[sizeof("inipaextensions")];
+    char uniname2ctype_pool_str238[sizeof("inmarchen")];
+    char uniname2ctype_pool_str243[sizeof("pc")];
+    char uniname2ctype_pool_str250[sizeof("insharada")];
+    char uniname2ctype_pool_str255[sizeof("lineseparator")];
+    char uniname2ctype_pool_str256[sizeof("masaramgondi")];
+    char uniname2ctype_pool_str259[sizeof("inarrows")];
+    char uniname2ctype_pool_str268[sizeof("ri")];
+    char uniname2ctype_pool_str270[sizeof("incham")];
+    char uniname2ctype_pool_str271[sizeof("latn")];
+    char uniname2ctype_pool_str272[sizeof("incyrillic")];
+    char uniname2ctype_pool_str273[sizeof("latin")];
+    char uniname2ctype_pool_str276[sizeof("inzanabazarsquare")];
+    char uniname2ctype_pool_str279[sizeof("insamaritan")];
+    char uniname2ctype_pool_str283[sizeof("pcm")];
+    char uniname2ctype_pool_str285[sizeof("inmasaramgondi")];
+    char uniname2ctype_pool_str288[sizeof("qmark")];
+    char uniname2ctype_pool_str289[sizeof("qaac")];
+    char uniname2ctype_pool_str291[sizeof("mtei")];
+    char uniname2ctype_pool_str295[sizeof("inthai")];
+    char uniname2ctype_pool_str300[sizeof("inscriptionalparthian")];
+    char uniname2ctype_pool_str301[sizeof("inthaana")];
+    char uniname2ctype_pool_str309[sizeof("inkaithi")];
+    char uniname2ctype_pool_str311[sizeof("initialpunctuation")];
+    char uniname2ctype_pool_str315[sizeof("inkatakana")];
+    char uniname2ctype_pool_str317[sizeof("inkhmersymbols")];
+    char uniname2ctype_pool_str343[sizeof("insyriac")];
+    char uniname2ctype_pool_str344[sizeof("intakri")];
+    char uniname2ctype_pool_str345[sizeof("prti")];
+    char uniname2ctype_pool_str356[sizeof("arabic")];
+    char uniname2ctype_pool_str357[sizeof("mand")];
+    char uniname2ctype_pool_str359[sizeof("cs")];
+    char uniname2ctype_pool_str361[sizeof("mend")];
+    char uniname2ctype_pool_str362[sizeof("zs")];
+    char uniname2ctype_pool_str363[sizeof("letter")];
+    char uniname2ctype_pool_str365[sizeof("privateuse")];
+    char uniname2ctype_pool_str369[sizeof("modi")];
+    char uniname2ctype_pool_str370[sizeof("katakana")];
+    char uniname2ctype_pool_str377[sizeof("ideo")];
+    char uniname2ctype_pool_str383[sizeof("brai")];
+    char uniname2ctype_pool_str384[sizeof("xidcontinue")];
+    char uniname2ctype_pool_str386[sizeof("inmyanmarextendeda")];
+    char uniname2ctype_pool_str387[sizeof("ascii")];
+    char uniname2ctype_pool_str389[sizeof("ps")];
+    char uniname2ctype_pool_str393[sizeof("inkanaextendeda")];
+    char uniname2ctype_pool_str396[sizeof("inmeeteimayek")];
+    char uniname2ctype_pool_str399[sizeof("inruminumeralsymbols")];
+    char uniname2ctype_pool_str408[sizeof("letternumber")];
+    char uniname2ctype_pool_str412[sizeof("knda")];
+    char uniname2ctype_pool_str425[sizeof("kannada")];
+    char uniname2ctype_pool_str428[sizeof("inoldnortharabian")];
+    char uniname2ctype_pool_str430[sizeof("inideographicdescriptioncharacters")];
+    char uniname2ctype_pool_str432[sizeof("inmodi")];
+    char uniname2ctype_pool_str440[sizeof("incjkcompatibilityforms")];
+    char uniname2ctype_pool_str445[sizeof("incjkcompatibilityideographs")];
+    char uniname2ctype_pool_str453[sizeof("xidc")];
+    char uniname2ctype_pool_str455[sizeof("inmendekikakui")];
+    char uniname2ctype_pool_str458[sizeof("brahmi")];
+    char uniname2ctype_pool_str480[sizeof("inolditalic")];
+    char uniname2ctype_pool_str482[sizeof("inmiscellaneousmathematicalsymbolsa")];
+    char uniname2ctype_pool_str486[sizeof("inspecials")];
+    char uniname2ctype_pool_str487[sizeof("inemoticons")];
+    char uniname2ctype_pool_str488[sizeof("patternwhitespace")];
+    char uniname2ctype_pool_str489[sizeof("gothic")];
+    char uniname2ctype_pool_str492[sizeof("intransportandmapsymbols")];
+    char uniname2ctype_pool_str493[sizeof("l")];
+    char uniname2ctype_pool_str509[sizeof("psalterpahlavi")];
+    char uniname2ctype_pool_str516[sizeof("vai")];
+    char uniname2ctype_pool_str517[sizeof("vaii")];
+    char uniname2ctype_pool_str523[sizeof("lt")];
+    char uniname2ctype_pool_str524[sizeof("meroiticcursive")];
+    char uniname2ctype_pool_str526[sizeof("xids")];
+    char uniname2ctype_pool_str530[sizeof("incommonindicnumberforms")];
+    char uniname2ctype_pool_str531[sizeof("inmandaic")];
+    char uniname2ctype_pool_str533[sizeof("inlineara")];
+    char uniname2ctype_pool_str541[sizeof("incjkcompatibilityideographssupplement")];
+    char uniname2ctype_pool_str544[sizeof("inlao")];
+    char uniname2ctype_pool_str545[sizeof("insundanese")];
+    char uniname2ctype_pool_str547[sizeof("mongolian")];
+    char uniname2ctype_pool_str552[sizeof("bamum")];
+    char uniname2ctype_pool_str554[sizeof("idc")];
+    char uniname2ctype_pool_str561[sizeof("inancientsymbols")];
+    char uniname2ctype_pool_str573[sizeof("kali")];
+    char uniname2ctype_pool_str574[sizeof("grlink")];
+    char uniname2ctype_pool_str576[sizeof("grext")];
+    char uniname2ctype_pool_str577[sizeof("control")];
+    char uniname2ctype_pool_str586[sizeof("inkanasupplement")];
+    char uniname2ctype_pool_str591[sizeof("inopticalcharacterrecognition")];
+    char uniname2ctype_pool_str596[sizeof("inadlam")];
+    char uniname2ctype_pool_str598[sizeof("so")];
+    char uniname2ctype_pool_str601[sizeof("inoldsoutharabian")];
+    char uniname2ctype_pool_str602[sizeof("sk")];
+    char uniname2ctype_pool_str606[sizeof("print")];
+    char uniname2ctype_pool_str607[sizeof("idsbinaryoperator")];
+    char uniname2ctype_pool_str609[sizeof("palm")];
+    char uniname2ctype_pool_str618[sizeof("batk")];
+    char uniname2ctype_pool_str619[sizeof("indominotiles")];
+    char uniname2ctype_pool_str620[sizeof("intaitham")];
+    char uniname2ctype_pool_str622[sizeof("inlycian")];
+    char uniname2ctype_pool_str629[sizeof("sora")];
+    char uniname2ctype_pool_str636[sizeof("batak")];
+    char uniname2ctype_pool_str642[sizeof("inmodifiertoneletters")];
+    char uniname2ctype_pool_str657[sizeof("patws")];
+    char uniname2ctype_pool_str665[sizeof("inmalayalam")];
+    char uniname2ctype_pool_str670[sizeof("incjkstrokes")];
+    char uniname2ctype_pool_str681[sizeof("incontrolpictures")];
+    char uniname2ctype_pool_str684[sizeof("samr")];
+    char uniname2ctype_pool_str689[sizeof("bass")];
+    char uniname2ctype_pool_str693[sizeof("samaritan")];
+    char uniname2ctype_pool_str699[sizeof("inmusicalsymbols")];
+    char uniname2ctype_pool_str700[sizeof("ids")];
+    char uniname2ctype_pool_str705[sizeof("pd")];
+    char uniname2ctype_pool_str708[sizeof("sm")];
+    char uniname2ctype_pool_str715[sizeof("pauc")];
+    char uniname2ctype_pool_str716[sizeof("joinc")];
+    char uniname2ctype_pool_str725[sizeof("inlinearbideograms")];
+    char uniname2ctype_pool_str730[sizeof("idcontinue")];
+    char uniname2ctype_pool_str732[sizeof("inancientgreekmusicalnotation")];
+    char uniname2ctype_pool_str737[sizeof("inoldturkic")];
+    char uniname2ctype_pool_str738[sizeof("alnum")];
+    char uniname2ctype_pool_str739[sizeof("inugaritic")];
+    char uniname2ctype_pool_str741[sizeof("s")];
+    char uniname2ctype_pool_str742[sizeof("inmiscellaneoussymbols")];
+    char uniname2ctype_pool_str743[sizeof("n")];
+    char uniname2ctype_pool_str748[sizeof("lisu")];
+    char uniname2ctype_pool_str751[sizeof("inmiscellaneoussymbolsandarrows")];
+    char uniname2ctype_pool_str753[sizeof("insylotinagri")];
+    char uniname2ctype_pool_str756[sizeof("inmiscellaneoussymbolsandpictographs")];
+    char uniname2ctype_pool_str770[sizeof("sc")];
+    char uniname2ctype_pool_str773[sizeof("no")];
+    char uniname2ctype_pool_str777[sizeof("ital")];
+    char uniname2ctype_pool_str781[sizeof("p")];
+    char uniname2ctype_pool_str782[sizeof("xpeo")];
+    char uniname2ctype_pool_str785[sizeof("di")];
+    char uniname2ctype_pool_str787[sizeof("idst")];
+    char uniname2ctype_pool_str788[sizeof("intaile")];
+    char uniname2ctype_pool_str791[sizeof("nko")];
+    char uniname2ctype_pool_str792[sizeof("nkoo")];
+    char uniname2ctype_pool_str793[sizeof("dia")];
+    char uniname2ctype_pool_str797[sizeof("inphoenician")];
+    char uniname2ctype_pool_str799[sizeof("inlatinextendeda")];
+    char uniname2ctype_pool_str802[sizeof("indeseret")];
+    char uniname2ctype_pool_str807[sizeof("inlatinextendede")];
+    char uniname2ctype_pool_str812[sizeof("incaucasianalbanian")];
+    char uniname2ctype_pool_str819[sizeof("insaurashtra")];
+    char uniname2ctype_pool_str823[sizeof("inmeeteimayekextensions")];
+    char uniname2ctype_pool_str834[sizeof("idstart")];
+    char uniname2ctype_pool_str835[sizeof("bali")];
+    char uniname2ctype_pool_str837[sizeof("inspacingmodifierletters")];
+    char uniname2ctype_pool_str848[sizeof("bengali")];
+    char uniname2ctype_pool_str849[sizeof("intamil")];
+    char uniname2ctype_pool_str851[sizeof("inmultani")];
+    char uniname2ctype_pool_str852[sizeof("vs")];
+    char uniname2ctype_pool_str853[sizeof("inlydian")];
+    char uniname2ctype_pool_str855[sizeof("balinese")];
+    char uniname2ctype_pool_str856[sizeof("lepc")];
+    char uniname2ctype_pool_str857[sizeof("cased")];
+    char uniname2ctype_pool_str862[sizeof("zinh")];
+    char uniname2ctype_pool_str867[sizeof("blank")];
+    char uniname2ctype_pool_str870[sizeof("runr")];
+    char uniname2ctype_pool_str872[sizeof("patternsyntax")];
+    char uniname2ctype_pool_str874[sizeof("bidic")];
+    char uniname2ctype_pool_str877[sizeof("xdigit")];
+    char uniname2ctype_pool_str881[sizeof("xidstart")];
+    char uniname2ctype_pool_str885[sizeof("inphaistosdisc")];
+    char uniname2ctype_pool_str897[sizeof("inancientgreeknumbers")];
+    char uniname2ctype_pool_str899[sizeof("canadianaboriginal")];
+    char uniname2ctype_pool_str903[sizeof("cher")];
+    char uniname2ctype_pool_str905[sizeof("plrd")];
+    char uniname2ctype_pool_str906[sizeof("sind")];
+    char uniname2ctype_pool_str909[sizeof("cherokee")];
+    char uniname2ctype_pool_str911[sizeof("phoenician")];
+    char uniname2ctype_pool_str918[sizeof("marchen")];
+    char uniname2ctype_pool_str919[sizeof("inhiragana")];
+    char uniname2ctype_pool_str926[sizeof("inearlydynasticcuneiform")];
+    char uniname2ctype_pool_str928[sizeof("graphemebase")];
+    char uniname2ctype_pool_str930[sizeof("cham")];
+    char uniname2ctype_pool_str931[sizeof("inimperialaramaic")];
+    char uniname2ctype_pool_str932[sizeof("kaithi")];
+    char uniname2ctype_pool_str935[sizeof("insiddham")];
+    char uniname2ctype_pool_str937[sizeof("diacritic")];
+    char uniname2ctype_pool_str942[sizeof("chakma")];
+    char uniname2ctype_pool_str944[sizeof("graphemelink")];
+    char uniname2ctype_pool_str947[sizeof("inkhudawadi")];
+    char uniname2ctype_pool_str948[sizeof("inmahajani")];
+    char uniname2ctype_pool_str956[sizeof("khojki")];
+    char uniname2ctype_pool_str957[sizeof("inogham")];
+    char uniname2ctype_pool_str960[sizeof("khar")];
+    char uniname2ctype_pool_str966[sizeof("incountingrodnumerals")];
+    char uniname2ctype_pool_str975[sizeof("manichaean")];
+    char uniname2ctype_pool_str976[sizeof("coptic")];
+    char uniname2ctype_pool_str977[sizeof("bamu")];
+    char uniname2ctype_pool_str980[sizeof("sterm")];
+    char uniname2ctype_pool_str983[sizeof("inethiopic")];
+    char uniname2ctype_pool_str985[sizeof("ll")];
+    char uniname2ctype_pool_str988[sizeof("inolchiki")];
+    char uniname2ctype_pool_str991[sizeof("inlatinextendedc")];
+    char uniname2ctype_pool_str996[sizeof("zl")];
+    char uniname2ctype_pool_str998[sizeof("adlm")];
+    char uniname2ctype_pool_str1016[sizeof("incyrillicsupplement")];
+    char uniname2ctype_pool_str1019[sizeof("incyrillicextendeda")];
+    char uniname2ctype_pool_str1022[sizeof("incherokeesupplement")];
+    char uniname2ctype_pool_str1023[sizeof("decimalnumber")];
+    char uniname2ctype_pool_str1025[sizeof("khmr")];
+    char uniname2ctype_pool_str1029[sizeof("copt")];
+    char uniname2ctype_pool_str1032[sizeof("ahom")];
+    char uniname2ctype_pool_str1034[sizeof("runic")];
+    char uniname2ctype_pool_str1048[sizeof("intaixuanjingsymbols")];
+    char uniname2ctype_pool_str1049[sizeof("insinhala")];
+    char uniname2ctype_pool_str1053[sizeof("cprt")];
+    char uniname2ctype_pool_str1056[sizeof("imperialaramaic")];
+    char uniname2ctype_pool_str1061[sizeof("casedletter")];
+    char uniname2ctype_pool_str1065[sizeof("khmer")];
+    char uniname2ctype_pool_str1067[sizeof("linb")];
+    char uniname2ctype_pool_str1069[sizeof("adlam")];
+    char uniname2ctype_pool_str1076[sizeof("ininscriptionalparthian")];
+    char uniname2ctype_pool_str1077[sizeof("ininscriptionalpahlavi")];
+    char uniname2ctype_pool_str1078[sizeof("sinhala")];
+    char uniname2ctype_pool_str1080[sizeof("zanb")];
+    char uniname2ctype_pool_str1086[sizeof("incjkunifiedideographsextensiona")];
+    char uniname2ctype_pool_str1088[sizeof("multani")];
+    char uniname2ctype_pool_str1089[sizeof("quotationmark")];
+    char uniname2ctype_pool_str1090[sizeof("incjkunifiedideographsextensione")];
+    char uniname2ctype_pool_str1094[sizeof("innabataean")];
+    char uniname2ctype_pool_str1098[sizeof("inbhaiksuki")];
+    char uniname2ctype_pool_str1100[sizeof("inelbasan")];
+    char uniname2ctype_pool_str1103[sizeof("inkanbun")];
+    char uniname2ctype_pool_str1104[sizeof("inscriptionalpahlavi")];
+    char uniname2ctype_pool_str1107[sizeof("bopo")];
+    char uniname2ctype_pool_str1114[sizeof("linearb")];
+    char uniname2ctype_pool_str1115[sizeof("incyrillicextendedc")];
+    char uniname2ctype_pool_str1116[sizeof("glagolitic")];
+    char uniname2ctype_pool_str1119[sizeof("kharoshthi")];
+    char uniname2ctype_pool_str1120[sizeof("inoldpersian")];
+    char uniname2ctype_pool_str1124[sizeof("goth")];
+    char uniname2ctype_pool_str1126[sizeof("math")];
+    char uniname2ctype_pool_str1127[sizeof("joincontrol")];
+    char uniname2ctype_pool_str1131[sizeof("punct")];
+    char uniname2ctype_pool_str1135[sizeof("lu")];
+    char uniname2ctype_pool_str1136[sizeof("limb")];
+    char uniname2ctype_pool_str1147[sizeof("inmiscellaneoustechnical")];
+    char uniname2ctype_pool_str1152[sizeof("han")];
+    char uniname2ctype_pool_str1155[sizeof("hani")];
+    char uniname2ctype_pool_str1156[sizeof("invai")];
+    char uniname2ctype_pool_str1157[sizeof("sundanese")];
+    char uniname2ctype_pool_str1158[sizeof("taile")];
+    char uniname2ctype_pool_str1160[sizeof("takri")];
+    char uniname2ctype_pool_str1161[sizeof("grantha")];
+    char uniname2ctype_pool_str1167[sizeof("hano")];
+    char uniname2ctype_pool_str1168[sizeof("inhatran")];
+    char uniname2ctype_pool_str1172[sizeof("oriya")];
+    char uniname2ctype_pool_str1173[sizeof("intirhuta")];
+    char uniname2ctype_pool_str1178[sizeof("guru")];
+    char uniname2ctype_pool_str1179[sizeof("kthi")];
+    char uniname2ctype_pool_str1180[sizeof("saur")];
+    char uniname2ctype_pool_str1182[sizeof("incjkunifiedideographsextensionc")];
+    char uniname2ctype_pool_str1186[sizeof("hanunoo")];
+    char uniname2ctype_pool_str1189[sizeof("paucinhau")];
+    char uniname2ctype_pool_str1192[sizeof("takr")];
+    char uniname2ctype_pool_str1193[sizeof("hira")];
+    char uniname2ctype_pool_str1195[sizeof("inarabic")];
+    char uniname2ctype_pool_str1196[sizeof("bopomofo")];
+    char uniname2ctype_pool_str1201[sizeof("radical")];
+    char uniname2ctype_pool_str1202[sizeof("gurmukhi")];
+    char uniname2ctype_pool_str1203[sizeof("inkhojki")];
+    char uniname2ctype_pool_str1207[sizeof("arab")];
+    char uniname2ctype_pool_str1211[sizeof("limbu")];
+    char uniname2ctype_pool_str1218[sizeof("inoldpermic")];
+    char uniname2ctype_pool_str1222[sizeof("brah")];
+    char uniname2ctype_pool_str1225[sizeof("inoldhungarian")];
+    char uniname2ctype_pool_str1227[sizeof("inshorthandformatcontrols")];
+    char uniname2ctype_pool_str1229[sizeof("incoptic")];
+    char uniname2ctype_pool_str1232[sizeof("sd")];
+    char uniname2ctype_pool_str1237[sizeof("sidd")];
+    char uniname2ctype_pool_str1243[sizeof("inherited")];
+    char uniname2ctype_pool_str1245[sizeof("incjkunifiedideographs")];
+    char uniname2ctype_pool_str1249[sizeof("term")];
+    char uniname2ctype_pool_str1252[sizeof("incjksymbolsandpunctuation")];
+    char uniname2ctype_pool_str1253[sizeof("graphemeextend")];
+    char uniname2ctype_pool_str1254[sizeof("dsrt")];
+    char uniname2ctype_pool_str1257[sizeof("cntrl")];
+    char uniname2ctype_pool_str1259[sizeof("xsux")];
+    char uniname2ctype_pool_str1262[sizeof("insyriacsupplement")];
+    char uniname2ctype_pool_str1267[sizeof("inbasiclatin")];
+    char uniname2ctype_pool_str1275[sizeof("deseret")];
+    char uniname2ctype_pool_str1281[sizeof("inenclosedideographicsupplement")];
+    char uniname2ctype_pool_str1285[sizeof("bidicontrol")];
+    char uniname2ctype_pool_str1288[sizeof("closepunctuation")];
+    char uniname2ctype_pool_str1294[sizeof("inlatinextendedadditional")];
+    char uniname2ctype_pool_str1296[sizeof("inarabicpresentationformsa")];
+    char uniname2ctype_pool_str1298[sizeof("grbase")];
+    char uniname2ctype_pool_str1306[sizeof("mong")];
+    char uniname2ctype_pool_str1307[sizeof("anatolianhieroglyphs")];
+    char uniname2ctype_pool_str1308[sizeof("inenclosedalphanumerics")];
+    char uniname2ctype_pool_str1309[sizeof("ingrantha")];
+    char uniname2ctype_pool_str1310[sizeof("georgian")];
+    char uniname2ctype_pool_str1317[sizeof("osage")];
+    char uniname2ctype_pool_str1325[sizeof("inosage")];
+    char uniname2ctype_pool_str1326[sizeof("ingeneralpunctuation")];
+    char uniname2ctype_pool_str1331[sizeof("saurashtra")];
+    char uniname2ctype_pool_str1334[sizeof("inshavian")];
+    char uniname2ctype_pool_str1335[sizeof("space")];
+    char uniname2ctype_pool_str1336[sizeof("mult")];
+    char uniname2ctype_pool_str1340[sizeof("inpalmyrene")];
+    char uniname2ctype_pool_str1341[sizeof("inanatolianhieroglyphs")];
+    char uniname2ctype_pool_str1344[sizeof("spacingmark")];
+    char uniname2ctype_pool_str1348[sizeof("alpha")];
+    char uniname2ctype_pool_str1354[sizeof("ingeorgian")];
+    char uniname2ctype_pool_str1355[sizeof("intibetan")];
+    char uniname2ctype_pool_str1364[sizeof("inlepcha")];
+    char uniname2ctype_pool_str1365[sizeof("inbatak")];
+    char uniname2ctype_pool_str1367[sizeof("emoji")];
+    char uniname2ctype_pool_str1368[sizeof("osma")];
+    char uniname2ctype_pool_str1369[sizeof("bhks")];
+    char uniname2ctype_pool_str1372[sizeof("inmongolian")];
+    char uniname2ctype_pool_str1373[sizeof("variationselector")];
+    char uniname2ctype_pool_str1374[sizeof("braille")];
+    char uniname2ctype_pool_str1379[sizeof("phli")];
+    char uniname2ctype_pool_str1382[sizeof("bhaiksuki")];
+    char uniname2ctype_pool_str1388[sizeof("phnx")];
+    char uniname2ctype_pool_str1390[sizeof("inblockelements")];
+#ifdef USE_UNICODE_AGE_PROPERTIES
+    char uniname2ctype_pool_str1391[sizeof("age=1.1")];
+    char uniname2ctype_pool_str1392[sizeof("age=4.1")];
+    char uniname2ctype_pool_str1393[sizeof("age=4.0")];
+    char uniname2ctype_pool_str1394[sizeof("age=10.0")];
+    char uniname2ctype_pool_str1395[sizeof("age=2.1")];
+    char uniname2ctype_pool_str1396[sizeof("age=2.0")];
+    char uniname2ctype_pool_str1397[sizeof("age=6.1")];
+    char uniname2ctype_pool_str1398[sizeof("age=6.0")];
+    char uniname2ctype_pool_str1399[sizeof("age=9.0")];
+    char uniname2ctype_pool_str1400[sizeof("age=8.0")];
+    char uniname2ctype_pool_str1401[sizeof("age=6.2")];
+    char uniname2ctype_pool_str1402[sizeof("age=7.0")];
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+    char uniname2ctype_pool_str1403[sizeof("inenclosedalphanumericsupplement")];
+    char uniname2ctype_pool_str1404[sizeof("innumberforms")];
+#ifdef USE_UNICODE_AGE_PROPERTIES
+    char uniname2ctype_pool_str1405[sizeof("age=5.1")];
+    char uniname2ctype_pool_str1406[sizeof("age=5.0")];
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+    char uniname2ctype_pool_str1407[sizeof("nd")];
+    char uniname2ctype_pool_str1408[sizeof("separator")];
+#ifdef USE_UNICODE_AGE_PROPERTIES
+    char uniname2ctype_pool_str1409[sizeof("age=5.2")];
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+    char uniname2ctype_pool_str1411[sizeof("ingurmukhi")];
+    char uniname2ctype_pool_str1413[sizeof("incjkunifiedideographsextensiond")];
+    char uniname2ctype_pool_str1414[sizeof("taiviet")];
+    char uniname2ctype_pool_str1416[sizeof("sinh")];
+#ifdef USE_UNICODE_AGE_PROPERTIES
+    char uniname2ctype_pool_str1417[sizeof("age=3.1")];
+    char uniname2ctype_pool_str1418[sizeof("age=3.0")];
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+    char uniname2ctype_pool_str1420[sizeof("hatran")];
+#ifdef USE_UNICODE_AGE_PROPERTIES
+    char uniname2ctype_pool_str1421[sizeof("age=3.2")];
+    char uniname2ctype_pool_str1423[sizeof("age=6.3")];
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+    char uniname2ctype_pool_str1427[sizeof("format")];
+    char uniname2ctype_pool_str1429[sizeof("shavian")];
+    char uniname2ctype_pool_str1434[sizeof("insinhalaarchaicnumbers")];
+    char uniname2ctype_pool_str1435[sizeof("cuneiform")];
+    char uniname2ctype_pool_str1439[sizeof("inmyanmarextendedb")];
+    char uniname2ctype_pool_str1444[sizeof("punctuation")];
+    char uniname2ctype_pool_str1449[sizeof("inarabicextendeda")];
+    char uniname2ctype_pool_str1450[sizeof("hatr")];
+    char uniname2ctype_pool_str1451[sizeof("inhanunoo")];
+    char uniname2ctype_pool_str1453[sizeof("inlatinextendedd")];
+    char uniname2ctype_pool_str1455[sizeof("modifierletter")];
+    char uniname2ctype_pool_str1456[sizeof("odi")];
+    char uniname2ctype_pool_str1458[sizeof("ahex")];
+    char uniname2ctype_pool_str1463[sizeof("logicalorderexception")];
+    char uniname2ctype_pool_str1464[sizeof("inbyzantinemusicalsymbols")];
+    char uniname2ctype_pool_str1469[sizeof("sund")];
+    char uniname2ctype_pool_str1470[sizeof("number")];
+    char uniname2ctype_pool_str1471[sizeof("insundanesesupplement")];
+    char uniname2ctype_pool_str1485[sizeof("incopticepactnumbers")];
+    char uniname2ctype_pool_str1490[sizeof("emojimodifier")];
+    char uniname2ctype_pool_str1496[sizeof("zp")];
+    char uniname2ctype_pool_str1497[sizeof("asciihexdigit")];
+    char uniname2ctype_pool_str1500[sizeof("indevanagari")];
+    char uniname2ctype_pool_str1508[sizeof("innewa")];
+    char uniname2ctype_pool_str1510[sizeof("avestan")];
+    char uniname2ctype_pool_str1521[sizeof("insorasompeng")];
+    char uniname2ctype_pool_str1535[sizeof("inmiscellaneousmathematicalsymbolsb")];
+    char uniname2ctype_pool_str1536[sizeof("inbraillepatterns")];
+    char uniname2ctype_pool_str1539[sizeof("nonspacingmark")];
+    char uniname2ctype_pool_str1540[sizeof("ingreekandcoptic")];
+    char uniname2ctype_pool_str1545[sizeof("xposixpunct")];
+    char uniname2ctype_pool_str1553[sizeof("inwarangciti")];
+    char uniname2ctype_pool_str1555[sizeof("oidc")];
+    char uniname2ctype_pool_str1560[sizeof("terminalpunctuation")];
+    char uniname2ctype_pool_str1565[sizeof("cf")];
+    char uniname2ctype_pool_str1572[sizeof("lower")];
+    char uniname2ctype_pool_str1580[sizeof("inunifiedcanadianaboriginalsyllabics")];
+    char uniname2ctype_pool_str1585[sizeof("idsb")];
+    char uniname2ctype_pool_str1589[sizeof("inbalinese")];
+    char uniname2ctype_pool_str1593[sizeof("induployan")];
+    char uniname2ctype_pool_str1594[sizeof("innoblock")];
+    char uniname2ctype_pool_str1595[sizeof("pf")];
+    char uniname2ctype_pool_str1602[sizeof("inoriya")];
+    char uniname2ctype_pool_str1604[sizeof("inkatakanaphoneticextensions")];
+    char uniname2ctype_pool_str1606[sizeof("inkayahli")];
+    char uniname2ctype_pool_str1607[sizeof("wara")];
+    char uniname2ctype_pool_str1608[sizeof("innushu")];
+    char uniname2ctype_pool_str1609[sizeof("lepcha")];
+    char uniname2ctype_pool_str1611[sizeof("inmeroitichieroglyphs")];
+    char uniname2ctype_pool_str1617[sizeof("beng")];
+    char uniname2ctype_pool_str1623[sizeof("idstrinaryoperator")];
+    char uniname2ctype_pool_str1628[sizeof("oids")];
+    char uniname2ctype_pool_str1630[sizeof("regionalindicator")];
+    char uniname2ctype_pool_str1631[sizeof("enclosingmark")];
+    char uniname2ctype_pool_str1632[sizeof("java")];
+    char uniname2ctype_pool_str1636[sizeof("tale")];
+    char uniname2ctype_pool_str1638[sizeof("emojimodifierbase")];
+    char uniname2ctype_pool_str1645[sizeof("inphoneticextensions")];
+    char uniname2ctype_pool_str1647[sizeof("lowercase")];
+    char uniname2ctype_pool_str1648[sizeof("inverticalforms")];
+    char uniname2ctype_pool_str1650[sizeof("javanese")];
+    char uniname2ctype_pool_str1654[sizeof("sentenceterminal")];
+    char uniname2ctype_pool_str1655[sizeof("ingreekextended")];
+    char uniname2ctype_pool_str1656[sizeof("invariationselectors")];
+    char uniname2ctype_pool_str1657[sizeof("cwcm")];
+    char uniname2ctype_pool_str1663[sizeof("lyci")];
+    char uniname2ctype_pool_str1666[sizeof("avst")];
+    char uniname2ctype_pool_str1669[sizeof("lycian")];
+    char uniname2ctype_pool_str1671[sizeof("zanabazarsquare")];
+    char uniname2ctype_pool_str1672[sizeof("sarb")];
+    char uniname2ctype_pool_str1673[sizeof("invedicextensions")];
+    char uniname2ctype_pool_str1674[sizeof("inkangxiradicals")];
+    char uniname2ctype_pool_str1677[sizeof("intaiviet")];
+    char uniname2ctype_pool_str1682[sizeof("mymr")];
+    char uniname2ctype_pool_str1690[sizeof("incjkradicalssupplement")];
+    char uniname2ctype_pool_str1695[sizeof("myanmar")];
+    char uniname2ctype_pool_str1697[sizeof("taml")];
+    char uniname2ctype_pool_str1714[sizeof("olower")];
+    char uniname2ctype_pool_str1725[sizeof("nl")];
+    char uniname2ctype_pool_str1727[sizeof("inethiopicsupplement")];
+    char uniname2ctype_pool_str1728[sizeof("olck")];
+    char uniname2ctype_pool_str1730[sizeof("inethiopicextendeda")];
+    char uniname2ctype_pool_str1736[sizeof("graph")];
+    char uniname2ctype_pool_str1737[sizeof("olchiki")];
+    char uniname2ctype_pool_str1741[sizeof("inphoneticextensionssupplement")];
+    char uniname2ctype_pool_str1743[sizeof("emojicomponent")];
+    char uniname2ctype_pool_str1746[sizeof("inunifiedcanadianaboriginalsyllabicsextended")];
+    char uniname2ctype_pool_str1748[sizeof("ingeometricshapes")];
+    char uniname2ctype_pool_str1752[sizeof("invariationselectorssupplement")];
+    char uniname2ctype_pool_str1754[sizeof("gujr")];
+    char uniname2ctype_pool_str1762[sizeof("sharada")];
+    char uniname2ctype_pool_str1766[sizeof("gujarati")];
+    char uniname2ctype_pool_str1767[sizeof("nchar")];
+    char uniname2ctype_pool_str1772[sizeof("innewtailue")];
+    char uniname2ctype_pool_str1774[sizeof("glag")];
+    char uniname2ctype_pool_str1780[sizeof("ideographic")];
+    char uniname2ctype_pool_str1783[sizeof("shrd")];
+    char uniname2ctype_pool_str1785[sizeof("insoyombo")];
+    char uniname2ctype_pool_str1789[sizeof("inbamum")];
+    char uniname2ctype_pool_str1800[sizeof("inlatin1supplement")];
+    char uniname2ctype_pool_str1802[sizeof("dash")];
+    char uniname2ctype_pool_str1806[sizeof("indingbats")];
+    char uniname2ctype_pool_str1808[sizeof("spaceseparator")];
+    char uniname2ctype_pool_str1813[sizeof("phagspa")];
+    char uniname2ctype_pool_str1814[sizeof("titlecaseletter")];
+    char uniname2ctype_pool_str1815[sizeof("incjkcompatibility")];
+    char uniname2ctype_pool_str1818[sizeof("intangut")];
+    char uniname2ctype_pool_str1819[sizeof("incombiningdiacriticalmarks")];
+    char uniname2ctype_pool_str1821[sizeof("inlisu")];
+    char uniname2ctype_pool_str1825[sizeof("siddham")];
+    char uniname2ctype_pool_str1829[sizeof("incombiningdiacriticalmarksforsymbols")];
+    char uniname2ctype_pool_str1840[sizeof("caucasianalbanian")];
+    char uniname2ctype_pool_str1843[sizeof("uideo")];
+    char uniname2ctype_pool_str1846[sizeof("indevanagariextended")];
+    char uniname2ctype_pool_str1847[sizeof("narb")];
+    char uniname2ctype_pool_str1857[sizeof("inbopomofo")];
+    char uniname2ctype_pool_str1858[sizeof("incjkunifiedideographsextensionf")];
+    char uniname2ctype_pool_str1861[sizeof("inmeroiticcursive")];
+    char uniname2ctype_pool_str1866[sizeof("patsyn")];
+    char uniname2ctype_pool_str1885[sizeof("insuperscriptsandsubscripts")];
+    char uniname2ctype_pool_str1894[sizeof("lydi")];
+    char uniname2ctype_pool_str1900[sizeof("lydian")];
+    char uniname2ctype_pool_str1903[sizeof("intags")];
+    char uniname2ctype_pool_str1909[sizeof("intelugu")];
+    char uniname2ctype_pool_str1910[sizeof("intifinagh")];
+    char uniname2ctype_pool_str1914[sizeof("ingeometricshapesextended")];
+    char uniname2ctype_pool_str1915[sizeof("incombiningdiacriticalmarkssupplement")];
+    char uniname2ctype_pool_str1922[sizeof("deva")];
+    char uniname2ctype_pool_str1924[sizeof("inprivateusearea")];
+    char uniname2ctype_pool_str1932[sizeof("devanagari")];
+    char uniname2ctype_pool_str1933[sizeof("noncharactercodepoint")];
+    char uniname2ctype_pool_str1934[sizeof("inbrahmi")];
+    char uniname2ctype_pool_str1943[sizeof("lowercaseletter")];
+    char uniname2ctype_pool_str1944[sizeof("word")];
+    char uniname2ctype_pool_str1975[sizeof("caseignorable")];
+    char uniname2ctype_pool_str1976[sizeof("inyiradicals")];
+    char uniname2ctype_pool_str1979[sizeof("deprecated")];
+    char uniname2ctype_pool_str1981[sizeof("thai")];
+    char uniname2ctype_pool_str1983[sizeof("thaa")];
+    char uniname2ctype_pool_str1985[sizeof("incombiningdiacriticalmarksextended")];
+    char uniname2ctype_pool_str1989[sizeof("inmathematicalalphanumericsymbols")];
+    char uniname2ctype_pool_str1991[sizeof("thaana")];
+    char uniname2ctype_pool_str1995[sizeof("inornamentaldingbats")];
+    char uniname2ctype_pool_str1997[sizeof("oldpersian")];
+    char uniname2ctype_pool_str1998[sizeof("unassigned")];
+    char uniname2ctype_pool_str1999[sizeof("insupplementalarrowsa")];
+    char uniname2ctype_pool_str2003[sizeof("inpaucinhau")];
+    char uniname2ctype_pool_str2005[sizeof("cwt")];
+    char uniname2ctype_pool_str2007[sizeof("tirhuta")];
+    char uniname2ctype_pool_str2008[sizeof("mahj")];
+    char uniname2ctype_pool_str2013[sizeof("insmallformvariants")];
+    char uniname2ctype_pool_str2015[sizeof("tirh")];
+    char uniname2ctype_pool_str2017[sizeof("orkh")];
+    char uniname2ctype_pool_str2020[sizeof("mahajani")];
+    char uniname2ctype_pool_str2047[sizeof("softdotted")];
+    char uniname2ctype_pool_str2049[sizeof("inphagspa")];
+    char uniname2ctype_pool_str2056[sizeof("inethiopicextended")];
+    char uniname2ctype_pool_str2059[sizeof("taitham")];
+    char uniname2ctype_pool_str2061[sizeof("assigned")];
+    char uniname2ctype_pool_str2068[sizeof("nbat")];
+    char uniname2ctype_pool_str2072[sizeof("incyrillicextendedb")];
+    char uniname2ctype_pool_str2073[sizeof("khoj")];
+    char uniname2ctype_pool_str2076[sizeof("buhd")];
+    char uniname2ctype_pool_str2079[sizeof("nabataean")];
+    char uniname2ctype_pool_str2084[sizeof("inalphabeticpresentationforms")];
+    char uniname2ctype_pool_str2091[sizeof("sorasompeng")];
+    char uniname2ctype_pool_str2095[sizeof("insupplementalarrowsc")];
+    char uniname2ctype_pool_str2096[sizeof("oldpermic")];
+    char uniname2ctype_pool_str2097[sizeof("cyrl")];
+    char uniname2ctype_pool_str2101[sizeof("finalpunctuation")];
+    char uniname2ctype_pool_str2112[sizeof("meroitichieroglyphs")];
+    char uniname2ctype_pool_str2114[sizeof("inarabicsupplement")];
+    char uniname2ctype_pool_str2117[sizeof("phlp")];
+    char uniname2ctype_pool_str2119[sizeof("inpsalterpahlavi")];
+    char uniname2ctype_pool_str2134[sizeof("mlym")];
+    char uniname2ctype_pool_str2139[sizeof("incjkunifiedideographsextensionb")];
+    char uniname2ctype_pool_str2146[sizeof("palmyrene")];
+    char uniname2ctype_pool_str2148[sizeof("insupplementalmathematicaloperators")];
+    char uniname2ctype_pool_str2149[sizeof("malayalam")];
+    char uniname2ctype_pool_str2154[sizeof("soyo")];
+    char uniname2ctype_pool_str2158[sizeof("hex")];
+    char uniname2ctype_pool_str2161[sizeof("phag")];
+    char uniname2ctype_pool_str2165[sizeof("graphemeclusterbreak=ebase")];
+    char uniname2ctype_pool_str2172[sizeof("graphemeclusterbreak=ebasegaz")];
+    char uniname2ctype_pool_str2174[sizeof("inhanguljamo")];
+    char uniname2ctype_pool_str2176[sizeof("bugi")];
+    char uniname2ctype_pool_str2179[sizeof("graphemeclusterbreak=spacingmark")];
+    char uniname2ctype_pool_str2182[sizeof("inhanguljamoextendeda")];
+    char uniname2ctype_pool_str2187[sizeof("currencysymbol")];
+    char uniname2ctype_pool_str2189[sizeof("tamil")];
+    char uniname2ctype_pool_str2192[sizeof("graphemeclusterbreak=cr")];
+    char uniname2ctype_pool_str2193[sizeof("talu")];
+    char uniname2ctype_pool_str2196[sizeof("buginese")];
+    char uniname2ctype_pool_str2197[sizeof("telu")];
+    char uniname2ctype_pool_str2198[sizeof("ingeorgiansupplement")];
+    char uniname2ctype_pool_str2199[sizeof("graphemeclusterbreak=emodifier")];
+    char uniname2ctype_pool_str2207[sizeof("graphemeclusterbreak=regionalindicator")];
+    char uniname2ctype_pool_str2210[sizeof("inlimbu")];
+    char uniname2ctype_pool_str2224[sizeof("inenclosedcjklettersandmonths")];
+    char uniname2ctype_pool_str2225[sizeof("tangut")];
+    char uniname2ctype_pool_str2229[sizeof("inmathematicaloperators")];
+    char uniname2ctype_pool_str2232[sizeof("newa")];
+    char uniname2ctype_pool_str2249[sizeof("newtailue")];
+    char uniname2ctype_pool_str2252[sizeof("hebr")];
+    char uniname2ctype_pool_str2260[sizeof("inbuhid")];
+    char uniname2ctype_pool_str2263[sizeof("insuttonsignwriting")];
+    char uniname2ctype_pool_str2264[sizeof("syrc")];
+    char uniname2ctype_pool_str2271[sizeof("dep")];
+    char uniname2ctype_pool_str2276[sizeof("inbassavah")];
+    char uniname2ctype_pool_str2286[sizeof("otheridcontinue")];
+    char uniname2ctype_pool_str2289[sizeof("inletterlikesymbols")];
+    char uniname2ctype_pool_str2296[sizeof("ext")];
+    char uniname2ctype_pool_str2300[sizeof("other")];
+    char uniname2ctype_pool_str2306[sizeof("inmongoliansupplement")];
+    char uniname2ctype_pool_str2307[sizeof("othernumber")];
+    char uniname2ctype_pool_str2311[sizeof("injavanese")];
+    char uniname2ctype_pool_str2313[sizeof("olditalic")];
+    char uniname2ctype_pool_str2327[sizeof("nshu")];
+    char uniname2ctype_pool_str2349[sizeof("inarabicpresentationformsb")];
+    char uniname2ctype_pool_str2350[sizeof("inlowsurrogates")];
+    char uniname2ctype_pool_str2353[sizeof("incombininghalfmarks")];
+    char uniname2ctype_pool_str2360[sizeof("inbengali")];
+    char uniname2ctype_pool_str2364[sizeof("cwcf")];
+    char uniname2ctype_pool_str2369[sizeof("inbuginese")];
+    char uniname2ctype_pool_str2372[sizeof("syriac")];
+    char uniname2ctype_pool_str2380[sizeof("ethi")];
+    char uniname2ctype_pool_str2386[sizeof("otheralphabetic")];
+    char uniname2ctype_pool_str2393[sizeof("emojipresentation")];
+    char uniname2ctype_pool_str2399[sizeof("inarabicmathematicalalphabeticsymbols")];
+    char uniname2ctype_pool_str2408[sizeof("tang")];
+    char uniname2ctype_pool_str2409[sizeof("buhid")];
+    char uniname2ctype_pool_str2412[sizeof("graphemeclusterbreak=t")];
+    char uniname2ctype_pool_str2413[sizeof("extender")];
+    char uniname2ctype_pool_str2414[sizeof("graphemeclusterbreak=lvt")];
+    char uniname2ctype_pool_str2422[sizeof("tagbanwa")];
+    char uniname2ctype_pool_str2423[sizeof("hang")];
+    char uniname2ctype_pool_str2433[sizeof("incurrencysymbols")];
+    char uniname2ctype_pool_str2449[sizeof("ingujarati")];
+    char uniname2ctype_pool_str2451[sizeof("paragraphseparator")];
+    char uniname2ctype_pool_str2452[sizeof("tibt")];
+    char uniname2ctype_pool_str2461[sizeof("tibetan")];
+    char uniname2ctype_pool_str2465[sizeof("ogam")];
+    char uniname2ctype_pool_str2467[sizeof("cwl")];
+    char uniname2ctype_pool_str2469[sizeof("oalpha")];
+    char uniname2ctype_pool_str2473[sizeof("hiragana")];
+    char uniname2ctype_pool_str2475[sizeof("surrogate")];
+    char uniname2ctype_pool_str2481[sizeof("inbamumsupplement")];
+    char uniname2ctype_pool_str2483[sizeof("inrejang")];
+    char uniname2ctype_pool_str2484[sizeof("intangutcomponents")];
+    char uniname2ctype_pool_str2488[sizeof("hmng")];
+    char uniname2ctype_pool_str2489[sizeof("graphemeclusterbreak=extend")];
+    char uniname2ctype_pool_str2490[sizeof("graphemeclusterbreak=prepend")];
+    char uniname2ctype_pool_str2493[sizeof("bassavah")];
+    char uniname2ctype_pool_str2500[sizeof("ingothic")];
+    char uniname2ctype_pool_str2507[sizeof("alphabetic")];
+    char uniname2ctype_pool_str2509[sizeof("mathsymbol")];
+    char uniname2ctype_pool_str2515[sizeof("oupper")];
+    char uniname2ctype_pool_str2519[sizeof("oldhungarian")];
+    char uniname2ctype_pool_str2523[sizeof("tavt")];
+    char uniname2ctype_pool_str2526[sizeof("insupplementalpunctuation")];
+    char uniname2ctype_pool_str2539[sizeof("dashpunctuation")];
+    char uniname2ctype_pool_str2545[sizeof("inplayingcards")];
+    char uniname2ctype_pool_str2550[sizeof("inaegeannumbers")];
+    char uniname2ctype_pool_str2573[sizeof("osge")];
+    char uniname2ctype_pool_str2576[sizeof("digit")];
+    char uniname2ctype_pool_str2579[sizeof("dupl")];
+    char uniname2ctype_pool_str2587[sizeof("inlinearbsyllabary")];
+    char uniname2ctype_pool_str2589[sizeof("cypriot")];
+    char uniname2ctype_pool_str2594[sizeof("wspace")];
+    char uniname2ctype_pool_str2601[sizeof("whitespace")];
+    char uniname2ctype_pool_str2617[sizeof("cwu")];
+    char uniname2ctype_pool_str2618[sizeof("nushu")];
+    char uniname2ctype_pool_str2622[sizeof("intagbanwa")];
+    char uniname2ctype_pool_str2630[sizeof("sylo")];
+    char uniname2ctype_pool_str2643[sizeof("graphemeclusterbreak=l")];
+    char uniname2ctype_pool_str2649[sizeof("graphemeclusterbreak=control")];
+    char uniname2ctype_pool_str2653[sizeof("oldturkic")];
+    char uniname2ctype_pool_str2660[sizeof("changeswhencasemapped")];
+    char uniname2ctype_pool_str2678[sizeof("rjng")];
+    char uniname2ctype_pool_str2693[sizeof("cyrillic")];
+    char uniname2ctype_pool_str2702[sizeof("hangul")];
+    char uniname2ctype_pool_str2705[sizeof("modifiersymbol")];
+    char uniname2ctype_pool_str2708[sizeof("inalchemicalsymbols")];
+    char uniname2ctype_pool_str2710[sizeof("insupplementaryprivateuseareaa")];
+    char uniname2ctype_pool_str2717[sizeof("orya")];
+    char uniname2ctype_pool_str2751[sizeof("inmahjongtiles")];
+    char uniname2ctype_pool_str2758[sizeof("changeswhentitlecased")];
+    char uniname2ctype_pool_str2763[sizeof("tifinagh")];
+    char uniname2ctype_pool_str2775[sizeof("otherlowercase")];
+    char uniname2ctype_pool_str2779[sizeof("inglagolitic")];
+    char uniname2ctype_pool_str2791[sizeof("otheridstart")];
+    char uniname2ctype_pool_str2792[sizeof("ugar")];
+    char uniname2ctype_pool_str2797[sizeof("otherletter")];
+    char uniname2ctype_pool_str2823[sizeof("inhangulsyllables")];
+    char uniname2ctype_pool_str2829[sizeof("elba")];
+    char uniname2ctype_pool_str2834[sizeof("intagalog")];
+    char uniname2ctype_pool_str2850[sizeof("otheruppercase")];
+    char uniname2ctype_pool_str2879[sizeof("omath")];
+    char uniname2ctype_pool_str2883[sizeof("warangciti")];
+    char uniname2ctype_pool_str2888[sizeof("sylotinagri")];
+    char uniname2ctype_pool_str2890[sizeof("shaw")];
+    char uniname2ctype_pool_str2891[sizeof("inpahawhhmong")];
+    char uniname2ctype_pool_str2901[sizeof("inhalfwidthandfullwidthforms")];
+    char uniname2ctype_pool_str2905[sizeof("inlatinextendedb")];
+    char uniname2ctype_pool_str2926[sizeof("osmanya")];
+    char uniname2ctype_pool_str2930[sizeof("graphemeclusterbreak=lf")];
+    char uniname2ctype_pool_str2932[sizeof("othersymbol")];
+    char uniname2ctype_pool_str2953[sizeof("defaultignorablecodepoint")];
+    char uniname2ctype_pool_str2967[sizeof("incypriotsyllabary")];
+    char uniname2ctype_pool_str2968[sizeof("khudawadi")];
+    char uniname2ctype_pool_str2972[sizeof("kayahli")];
+    char uniname2ctype_pool_str2984[sizeof("hung")];
+    char uniname2ctype_pool_str2987[sizeof("unknown")];
+    char uniname2ctype_pool_str2989[sizeof("inyijinghexagramsymbols")];
+    char uniname2ctype_pool_str3007[sizeof("elbasan")];
+    char uniname2ctype_pool_str3016[sizeof("inbopomofoextended")];
+    char uniname2ctype_pool_str3019[sizeof("changeswhenlowercased")];
+    char uniname2ctype_pool_str3020[sizeof("otherpunctuation")];
+    char uniname2ctype_pool_str3038[sizeof("upper")];
+    char uniname2ctype_pool_str3052[sizeof("insupplementalarrowsb")];
+    char uniname2ctype_pool_str3066[sizeof("oldnortharabian")];
+    char uniname2ctype_pool_str3094[sizeof("changeswhenuppercased")];
+    char uniname2ctype_pool_str3113[sizeof("uppercase")];
+    char uniname2ctype_pool_str3121[sizeof("ugaritic")];
+    char uniname2ctype_pool_str3153[sizeof("otherdefaultignorablecodepoint")];
+    char uniname2ctype_pool_str3177[sizeof("othermath")];
+    char uniname2ctype_pool_str3180[sizeof("tfng")];
+    char uniname2ctype_pool_str3193[sizeof("symbol")];
+    char uniname2ctype_pool_str3195[sizeof("hexdigit")];
+    char uniname2ctype_pool_str3213[sizeof("any")];
+    char uniname2ctype_pool_str3235[sizeof("inhanguljamoextendedb")];
+    char uniname2ctype_pool_str3238[sizeof("ethiopic")];
+    char uniname2ctype_pool_str3276[sizeof("aghb")];
+    char uniname2ctype_pool_str3279[sizeof("graphemeclusterbreak=v")];
+    char uniname2ctype_pool_str3280[sizeof("graphemeclusterbreak=lv")];
+    char uniname2ctype_pool_str3285[sizeof("soyombo")];
+    char uniname2ctype_pool_str3296[sizeof("graphemeclusterbreak=zwj")];
+    char uniname2ctype_pool_str3305[sizeof("graphemeclusterbreak=glueafterzwj")];
+    char uniname2ctype_pool_str3315[sizeof("sgnw")];
+    char uniname2ctype_pool_str3367[sizeof("changeswhencasefolded")];
+    char uniname2ctype_pool_str3373[sizeof("ogham")];
+    char uniname2ctype_pool_str3409[sizeof("uppercaseletter")];
+    char uniname2ctype_pool_str3438[sizeof("inhebrew")];
+    char uniname2ctype_pool_str3442[sizeof("inhighprivateusesurrogates")];
+    char uniname2ctype_pool_str3448[sizeof("openpunctuation")];
+    char uniname2ctype_pool_str3453[sizeof("ogrext")];
+    char uniname2ctype_pool_str3454[sizeof("hyphen")];
+    char uniname2ctype_pool_str3465[sizeof("tagb")];
+    char uniname2ctype_pool_str3496[sizeof("inyisyllables")];
+    char uniname2ctype_pool_str3593[sizeof("oldsoutharabian")];
+    char uniname2ctype_pool_str3662[sizeof("duployan")];
+    char uniname2ctype_pool_str3676[sizeof("hluw")];
+    char uniname2ctype_pool_str3689[sizeof("inglagoliticsupplement")];
+    char uniname2ctype_pool_str3697[sizeof("insupplementalsymbolsandpictographs")];
+    char uniname2ctype_pool_str3763[sizeof("insupplementaryprivateuseareab")];
+    char uniname2ctype_pool_str3791[sizeof("inegyptianhieroglyphs")];
+    char uniname2ctype_pool_str3960[sizeof("rejang")];
+    char uniname2ctype_pool_str3971[sizeof("inhangulcompatibilityjamo")];
+    char uniname2ctype_pool_str4036[sizeof("telugu")];
+    char uniname2ctype_pool_str4164[sizeof("tglg")];
+    char uniname2ctype_pool_str4187[sizeof("tagalog")];
+    char uniname2ctype_pool_str4208[sizeof("othergraphemeextend")];
+    char uniname2ctype_pool_str4460[sizeof("unifiedideograph")];
+    char uniname2ctype_pool_str4464[sizeof("inboxdrawing")];
+    char uniname2ctype_pool_str4483[sizeof("pahawhhmong")];
+    char uniname2ctype_pool_str4608[sizeof("inhighsurrogates")];
+    char uniname2ctype_pool_str4634[sizeof("signwriting")];
+    char uniname2ctype_pool_str4678[sizeof("zyyy")];
+    char uniname2ctype_pool_str4841[sizeof("egyp")];
+    char uniname2ctype_pool_str5170[sizeof("hebrew")];
+    char uniname2ctype_pool_str6145[sizeof("egyptianhieroglyphs")];
+#endif /* USE_UNICODE_PROPERTIES */
+  };
+static const struct uniname2ctype_pool_t uniname2ctype_pool_contents =
+  {
+#ifndef USE_UNICODE_PROPERTIES
+    "word",
+#else /* USE_UNICODE_PROPERTIES */
+    "yi",
+    "cn",
+    "lina",
+    "yiii",
+    "lana",
+    "ci",
+    "mn",
+    "z",
+    "mani",
+    "lo",
+    "me",
+    "loe",
+    "lao",
+    "laoo",
+    "co",
+    "miao",
+    "pi",
+    "inkannada",
+    "gran",
+    "innko",
+    "zzzz",
+    "pe",
+    "cari",
+    "lineara",
+    "carian",
+    "mendekikakui",
+    "geor",
+    "po",
+    "grek",
+    "meeteimayek",
+    "mark",
+    "mero",
+    "kana",
+    "m",
+    "mro",
+    "mroo",
+    "greek",
+    "gonm",
+    "inkharoshthi",
+    "cakm",
+    "inmanichaean",
+    "c",
+    "inarmenian",
+    "common",
+    "inosmanya",
+    "inmro",
+    "inmiao",
+    "mandaic",
+    "inmyanmar",
+    "lm",
+    "prependedconcatenationmark",
+    "inideographicsymbolsandpunctuation",
+    "inchakma",
+    "inkhmer",
+    "perm",
+    "connectorpunctuation",
+    "marc",
+    "combiningmark",
+    "merc",
+    "inrunic",
+    "incarian",
+    "incuneiformnumbersandpunctuation",
+    "inahom",
+    "incherokee",
+    "qaai",
+    "cans",
+    "lc",
+    "incuneiform",
+    "cc",
+    "armn",
+    "inavestan",
+    "armi",
+    "mc",
+    "armenian",
+    "inipaextensions",
+    "inmarchen",
+    "pc",
+    "insharada",
+    "lineseparator",
+    "masaramgondi",
+    "inarrows",
+    "ri",
+    "incham",
+    "latn",
+    "incyrillic",
+    "latin",
+    "inzanabazarsquare",
+    "insamaritan",
+    "pcm",
+    "inmasaramgondi",
+    "qmark",
+    "qaac",
+    "mtei",
+    "inthai",
+    "inscriptionalparthian",
+    "inthaana",
+    "inkaithi",
+    "initialpunctuation",
+    "inkatakana",
+    "inkhmersymbols",
+    "insyriac",
+    "intakri",
+    "prti",
+    "arabic",
+    "mand",
+    "cs",
+    "mend",
+    "zs",
+    "letter",
+    "privateuse",
+    "modi",
+    "katakana",
+    "ideo",
+    "brai",
+    "xidcontinue",
+    "inmyanmarextendeda",
+    "ascii",
+    "ps",
+    "inkanaextendeda",
+    "inmeeteimayek",
+    "inruminumeralsymbols",
+    "letternumber",
+    "knda",
+    "kannada",
+    "inoldnortharabian",
+    "inideographicdescriptioncharacters",
+    "inmodi",
+    "incjkcompatibilityforms",
+    "incjkcompatibilityideographs",
+    "xidc",
+    "inmendekikakui",
+    "brahmi",
+    "inolditalic",
+    "inmiscellaneousmathematicalsymbolsa",
+    "inspecials",
+    "inemoticons",
+    "patternwhitespace",
+    "gothic",
+    "intransportandmapsymbols",
+    "l",
+    "psalterpahlavi",
+    "vai",
+    "vaii",
+    "lt",
+    "meroiticcursive",
+    "xids",
+    "incommonindicnumberforms",
+    "inmandaic",
+    "inlineara",
+    "incjkcompatibilityideographssupplement",
+    "inlao",
+    "insundanese",
+    "mongolian",
+    "bamum",
+    "idc",
+    "inancientsymbols",
+    "kali",
+    "grlink",
+    "grext",
+    "control",
+    "inkanasupplement",
+    "inopticalcharacterrecognition",
+    "inadlam",
+    "so",
+    "inoldsoutharabian",
+    "sk",
+#endif /* USE_UNICODE_PROPERTIES */
+    "print",
+#ifndef USE_UNICODE_PROPERTIES
+    "punct",
+    "alpha",
+#else /* USE_UNICODE_PROPERTIES */
+    "idsbinaryoperator",
+    "palm",
+    "batk",
+    "indominotiles",
+    "intaitham",
+    "inlycian",
+    "sora",
+    "batak",
+    "inmodifiertoneletters",
+    "patws",
+    "inmalayalam",
+    "incjkstrokes",
+    "incontrolpictures",
+    "samr",
+    "bass",
+    "samaritan",
+    "inmusicalsymbols",
+    "ids",
+    "pd",
+    "sm",
+    "pauc",
+    "joinc",
+    "inlinearbideograms",
+    "idcontinue",
+    "inancientgreekmusicalnotation",
+    "inoldturkic",
+#endif /* USE_UNICODE_PROPERTIES */
+    "alnum",
+#ifdef USE_UNICODE_PROPERTIES
+    "inugaritic",
+    "s",
+    "inmiscellaneoussymbols",
+    "n",
+    "lisu",
+    "inmiscellaneoussymbolsandarrows",
+    "insylotinagri",
+    "inmiscellaneoussymbolsandpictographs",
+    "sc",
+    "no",
+    "ital",
+    "p",
+    "xpeo",
+    "di",
+    "idst",
+    "intaile",
+    "nko",
+    "nkoo",
+    "dia",
+    "inphoenician",
+    "inlatinextendeda",
+    "indeseret",
+    "inlatinextendede",
+    "incaucasianalbanian",
+    "insaurashtra",
+    "inmeeteimayekextensions",
+    "idstart",
+    "bali",
+    "inspacingmodifierletters",
+    "bengali",
+    "intamil",
+    "inmultani",
+    "vs",
+    "inlydian",
+    "balinese",
+    "lepc",
+    "cased",
+    "zinh",
+    "blank",
+    "runr",
+    "patternsyntax",
+    "bidic",
+#endif /* USE_UNICODE_PROPERTIES */
+    "xdigit",
+#ifndef USE_UNICODE_PROPERTIES
+    "upper",
+    "ascii",
+#else /* USE_UNICODE_PROPERTIES */
+    "xidstart",
+    "inphaistosdisc",
+    "inancientgreeknumbers",
+    "canadianaboriginal",
+    "cher",
+    "plrd",
+    "sind",
+    "cherokee",
+    "phoenician",
+    "marchen",
+    "inhiragana",
+    "inearlydynasticcuneiform",
+    "graphemebase",
+    "cham",
+    "inimperialaramaic",
+    "kaithi",
+    "insiddham",
+    "diacritic",
+    "chakma",
+    "graphemelink",
+    "inkhudawadi",
+    "inmahajani",
+    "khojki",
+    "inogham",
+    "khar",
+    "incountingrodnumerals",
+    "manichaean",
+    "coptic",
+    "bamu",
+    "sterm",
+    "inethiopic",
+    "ll",
+    "inolchiki",
+    "inlatinextendedc",
+    "zl",
+    "adlm",
+    "incyrillicsupplement",
+    "incyrillicextendeda",
+    "incherokeesupplement",
+    "decimalnumber",
+    "khmr",
+    "copt",
+    "ahom",
+    "runic",
+    "intaixuanjingsymbols",
+    "insinhala",
+    "cprt",
+    "imperialaramaic",
+    "casedletter",
+    "khmer",
+    "linb",
+    "adlam",
+    "ininscriptionalparthian",
+    "ininscriptionalpahlavi",
+    "sinhala",
+    "zanb",
+    "incjkunifiedideographsextensiona",
+    "multani",
+    "quotationmark",
+    "incjkunifiedideographsextensione",
+    "innabataean",
+    "inbhaiksuki",
+    "inelbasan",
+    "inkanbun",
+    "inscriptionalpahlavi",
+    "bopo",
+    "linearb",
+    "incyrillicextendedc",
+    "glagolitic",
+    "kharoshthi",
+    "inoldpersian",
+    "goth",
+    "math",
+    "joincontrol",
+    "punct",
+    "lu",
+    "limb",
+    "inmiscellaneoustechnical",
+    "han",
+    "hani",
+    "invai",
+    "sundanese",
+    "taile",
+    "takri",
+    "grantha",
+    "hano",
+    "inhatran",
+    "oriya",
+    "intirhuta",
+    "guru",
+    "kthi",
+    "saur",
+    "incjkunifiedideographsextensionc",
+    "hanunoo",
+    "paucinhau",
+    "takr",
+    "hira",
+    "inarabic",
+    "bopomofo",
+    "radical",
+    "gurmukhi",
+    "inkhojki",
+    "arab",
+    "limbu",
+    "inoldpermic",
+    "brah",
+    "inoldhungarian",
+    "inshorthandformatcontrols",
+    "incoptic",
+    "sd",
+    "sidd",
+    "inherited",
+    "incjkunifiedideographs",
+    "term",
+    "incjksymbolsandpunctuation",
+    "graphemeextend",
+    "dsrt",
+#endif /* USE_UNICODE_PROPERTIES */
+    "cntrl",
+#ifdef USE_UNICODE_PROPERTIES
+    "xsux",
+    "insyriacsupplement",
+    "inbasiclatin",
+    "deseret",
+    "inenclosedideographicsupplement",
+    "bidicontrol",
+    "closepunctuation",
+    "inlatinextendedadditional",
+    "inarabicpresentationformsa",
+    "grbase",
+    "mong",
+    "anatolianhieroglyphs",
+    "inenclosedalphanumerics",
+    "ingrantha",
+    "georgian",
+    "osage",
+    "inosage",
+    "ingeneralpunctuation",
+    "saurashtra",
+    "inshavian",
+#endif /* USE_UNICODE_PROPERTIES */
+    "space",
+#ifdef USE_UNICODE_PROPERTIES
+    "mult",
+    "inpalmyrene",
+    "inanatolianhieroglyphs",
+    "spacingmark",
+    "alpha",
+    "ingeorgian",
+    "intibetan",
+    "inlepcha",
+    "inbatak",
+    "emoji",
+    "osma",
+    "bhks",
+    "inmongolian",
+    "variationselector",
+    "braille",
+    "phli",
+    "bhaiksuki",
+    "phnx",
+    "inblockelements",
+#ifdef USE_UNICODE_AGE_PROPERTIES
+    "age=1.1",
+    "age=4.1",
+    "age=4.0",
+    "age=10.0",
+    "age=2.1",
+    "age=2.0",
+    "age=6.1",
+    "age=6.0",
+    "age=9.0",
+    "age=8.0",
+    "age=6.2",
+    "age=7.0",
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+    "inenclosedalphanumericsupplement",
+    "innumberforms",
+#ifdef USE_UNICODE_AGE_PROPERTIES
+    "age=5.1",
+    "age=5.0",
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+    "nd",
+    "separator",
+#ifdef USE_UNICODE_AGE_PROPERTIES
+    "age=5.2",
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+    "ingurmukhi",
+    "incjkunifiedideographsextensiond",
+    "taiviet",
+    "sinh",
+#ifdef USE_UNICODE_AGE_PROPERTIES
+    "age=3.1",
+    "age=3.0",
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+    "hatran",
+#ifdef USE_UNICODE_AGE_PROPERTIES
+    "age=3.2",
+    "age=6.3",
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+    "format",
+    "shavian",
+    "insinhalaarchaicnumbers",
+    "cuneiform",
+    "inmyanmarextendedb",
+    "punctuation",
+    "inarabicextendeda",
+    "hatr",
+    "inhanunoo",
+    "inlatinextendedd",
+    "modifierletter",
+    "odi",
+    "ahex",
+    "logicalorderexception",
+    "inbyzantinemusicalsymbols",
+    "sund",
+    "number",
+    "insundanesesupplement",
+    "incopticepactnumbers",
+    "emojimodifier",
+    "zp",
+    "asciihexdigit",
+    "indevanagari",
+    "innewa",
+    "avestan",
+    "insorasompeng",
+    "inmiscellaneousmathematicalsymbolsb",
+    "inbraillepatterns",
+    "nonspacingmark",
+    "ingreekandcoptic",
+#endif /* USE_UNICODE_PROPERTIES */
+    "xposixpunct",
+#ifdef USE_UNICODE_PROPERTIES
+    "inwarangciti",
+    "oidc",
+    "terminalpunctuation",
+    "cf",
+#endif /* USE_UNICODE_PROPERTIES */
+    "lower",
+#ifdef USE_UNICODE_PROPERTIES
+    "inunifiedcanadianaboriginalsyllabics",
+    "idsb",
+    "inbalinese",
+    "induployan",
+    "innoblock",
+    "pf",
+    "inoriya",
+    "inkatakanaphoneticextensions",
+    "inkayahli",
+    "wara",
+    "innushu",
+    "lepcha",
+    "inmeroitichieroglyphs",
+    "beng",
+    "idstrinaryoperator",
+    "oids",
+    "regionalindicator",
+    "enclosingmark",
+    "java",
+    "tale",
+    "emojimodifierbase",
+    "inphoneticextensions",
+    "lowercase",
+    "inverticalforms",
+    "javanese",
+    "sentenceterminal",
+    "ingreekextended",
+    "invariationselectors",
+    "cwcm",
+    "lyci",
+    "avst",
+    "lycian",
+    "zanabazarsquare",
+    "sarb",
+    "invedicextensions",
+    "inkangxiradicals",
+    "intaiviet",
+    "mymr",
+    "incjkradicalssupplement",
+    "myanmar",
+    "taml",
+    "olower",
+    "nl",
+    "inethiopicsupplement",
+    "olck",
+    "inethiopicextendeda",
+#endif /* USE_UNICODE_PROPERTIES */
+    "graph",
+#ifdef USE_UNICODE_PROPERTIES
+    "olchiki",
+    "inphoneticextensionssupplement",
+    "emojicomponent",
+    "inunifiedcanadianaboriginalsyllabicsextended",
+    "ingeometricshapes",
+    "invariationselectorssupplement",
+    "gujr",
+    "sharada",
+    "gujarati",
+    "nchar",
+    "innewtailue",
+    "glag",
+    "ideographic",
+    "shrd",
+    "insoyombo",
+    "inbamum",
+    "inlatin1supplement",
+    "dash",
+    "indingbats",
+    "spaceseparator",
+    "phagspa",
+    "titlecaseletter",
+    "incjkcompatibility",
+    "intangut",
+    "incombiningdiacriticalmarks",
+    "inlisu",
+    "siddham",
+    "incombiningdiacriticalmarksforsymbols",
+    "caucasianalbanian",
+    "uideo",
+    "indevanagariextended",
+    "narb",
+    "inbopomofo",
+    "incjkunifiedideographsextensionf",
+    "inmeroiticcursive",
+    "patsyn",
+    "insuperscriptsandsubscripts",
+    "lydi",
+    "lydian",
+    "intags",
+    "intelugu",
+    "intifinagh",
+    "ingeometricshapesextended",
+    "incombiningdiacriticalmarkssupplement",
+    "deva",
+    "inprivateusearea",
+    "devanagari",
+    "noncharactercodepoint",
+    "inbrahmi",
+    "lowercaseletter",
+    "word",
+    "caseignorable",
+    "inyiradicals",
+    "deprecated",
+    "thai",
+    "thaa",
+    "incombiningdiacriticalmarksextended",
+    "inmathematicalalphanumericsymbols",
+    "thaana",
+    "inornamentaldingbats",
+    "oldpersian",
+    "unassigned",
+    "insupplementalarrowsa",
+    "inpaucinhau",
+    "cwt",
+    "tirhuta",
+    "mahj",
+    "insmallformvariants",
+    "tirh",
+    "orkh",
+    "mahajani",
+    "softdotted",
+    "inphagspa",
+    "inethiopicextended",
+    "taitham",
+    "assigned",
+    "nbat",
+    "incyrillicextendedb",
+    "khoj",
+    "buhd",
+    "nabataean",
+    "inalphabeticpresentationforms",
+    "sorasompeng",
+    "insupplementalarrowsc",
+    "oldpermic",
+    "cyrl",
+    "finalpunctuation",
+    "meroitichieroglyphs",
+    "inarabicsupplement",
+    "phlp",
+    "inpsalterpahlavi",
+    "mlym",
+    "incjkunifiedideographsextensionb",
+    "palmyrene",
+    "insupplementalmathematicaloperators",
+    "malayalam",
+    "soyo",
+    "hex",
+    "phag",
+    "graphemeclusterbreak=ebase",
+    "graphemeclusterbreak=ebasegaz",
+    "inhanguljamo",
+    "bugi",
+    "graphemeclusterbreak=spacingmark",
+    "inhanguljamoextendeda",
+    "currencysymbol",
+    "tamil",
+    "graphemeclusterbreak=cr",
+    "talu",
+    "buginese",
+    "telu",
+    "ingeorgiansupplement",
+    "graphemeclusterbreak=emodifier",
+    "graphemeclusterbreak=regionalindicator",
+    "inlimbu",
+    "inenclosedcjklettersandmonths",
+    "tangut",
+    "inmathematicaloperators",
+    "newa",
+    "newtailue",
+    "hebr",
+    "inbuhid",
+    "insuttonsignwriting",
+    "syrc",
+    "dep",
+    "inbassavah",
+    "otheridcontinue",
+    "inletterlikesymbols",
+    "ext",
+    "other",
+    "inmongoliansupplement",
+    "othernumber",
+    "injavanese",
+    "olditalic",
+    "nshu",
+    "inarabicpresentationformsb",
+    "inlowsurrogates",
+    "incombininghalfmarks",
+    "inbengali",
+    "cwcf",
+    "inbuginese",
+    "syriac",
+    "ethi",
+    "otheralphabetic",
+    "emojipresentation",
+    "inarabicmathematicalalphabeticsymbols",
+    "tang",
+    "buhid",
+    "graphemeclusterbreak=t",
+    "extender",
+    "graphemeclusterbreak=lvt",
+    "tagbanwa",
+    "hang",
+    "incurrencysymbols",
+    "ingujarati",
+    "paragraphseparator",
+    "tibt",
+    "tibetan",
+    "ogam",
+    "cwl",
+    "oalpha",
+    "hiragana",
+    "surrogate",
+    "inbamumsupplement",
+    "inrejang",
+    "intangutcomponents",
+    "hmng",
+    "graphemeclusterbreak=extend",
+    "graphemeclusterbreak=prepend",
+    "bassavah",
+    "ingothic",
+    "alphabetic",
+    "mathsymbol",
+    "oupper",
+    "oldhungarian",
+    "tavt",
+    "insupplementalpunctuation",
+    "dashpunctuation",
+    "inplayingcards",
+    "inaegeannumbers",
+    "osge",
+#endif /* USE_UNICODE_PROPERTIES */
+    "digit",
+#ifndef USE_UNICODE_PROPERTIES
+    "blank"
+#else /* USE_UNICODE_PROPERTIES */
+    "dupl",
+    "inlinearbsyllabary",
+    "cypriot",
+    "wspace",
+    "whitespace",
+    "cwu",
+    "nushu",
+    "intagbanwa",
+    "sylo",
+    "graphemeclusterbreak=l",
+    "graphemeclusterbreak=control",
+    "oldturkic",
+    "changeswhencasemapped",
+    "rjng",
+    "cyrillic",
+    "hangul",
+    "modifiersymbol",
+    "inalchemicalsymbols",
+    "insupplementaryprivateuseareaa",
+    "orya",
+    "inmahjongtiles",
+    "changeswhentitlecased",
+    "tifinagh",
+    "otherlowercase",
+    "inglagolitic",
+    "otheridstart",
+    "ugar",
+    "otherletter",
+    "inhangulsyllables",
+    "elba",
+    "intagalog",
+    "otheruppercase",
+    "omath",
+    "warangciti",
+    "sylotinagri",
+    "shaw",
+    "inpahawhhmong",
+    "inhalfwidthandfullwidthforms",
+    "inlatinextendedb",
+    "osmanya",
+    "graphemeclusterbreak=lf",
+    "othersymbol",
+    "defaultignorablecodepoint",
+    "incypriotsyllabary",
+    "khudawadi",
+    "kayahli",
+    "hung",
+    "unknown",
+    "inyijinghexagramsymbols",
+    "elbasan",
+    "inbopomofoextended",
+    "changeswhenlowercased",
+    "otherpunctuation",
+    "upper",
+    "insupplementalarrowsb",
+    "oldnortharabian",
+    "changeswhenuppercased",
+    "uppercase",
+    "ugaritic",
+    "otherdefaultignorablecodepoint",
+    "othermath",
+    "tfng",
+    "symbol",
+    "hexdigit",
+    "any",
+    "inhanguljamoextendedb",
+    "ethiopic",
+    "aghb",
+    "graphemeclusterbreak=v",
+    "graphemeclusterbreak=lv",
+    "soyombo",
+    "graphemeclusterbreak=zwj",
+    "graphemeclusterbreak=glueafterzwj",
+    "sgnw",
+    "changeswhencasefolded",
+    "ogham",
+    "uppercaseletter",
+    "inhebrew",
+    "inhighprivateusesurrogates",
+    "openpunctuation",
+    "ogrext",
+    "hyphen",
+    "tagb",
+    "inyisyllables",
+    "oldsoutharabian",
+    "duployan",
+    "hluw",
+    "inglagoliticsupplement",
+    "insupplementalsymbolsandpictographs",
+    "insupplementaryprivateuseareab",
+    "inegyptianhieroglyphs",
+    "rejang",
+    "inhangulcompatibilityjamo",
+    "telugu",
+    "tglg",
+    "tagalog",
+    "othergraphemeextend",
+    "unifiedideograph",
+    "inboxdrawing",
+    "pahawhhmong",
+    "inhighsurrogates",
+    "signwriting",
+    "zyyy",
+    "egyp",
+    "hebrew",
+    "egyptianhieroglyphs"
+#endif /* USE_UNICODE_PROPERTIES */
+  };
+#define uniname2ctype_pool ((const char *) &uniname2ctype_pool_contents)
+#ifdef __GNUC__
+__inline
+#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
+__attribute__ ((__gnu_inline__))
+#endif
+#endif
+const struct uniname2ctype_struct *
+uniname2ctype_p (str, len)
+     register const char *str;
+     register unsigned int len;
+{
+  static const struct uniname2ctype_struct wordlist[] =
+    {
+#ifdef USE_UNICODE_PROPERTIES
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1},
+      {uniname2ctype_offset(str10), 111},
+      {-1}, {-1},
+      {uniname2ctype_offset(str13), 21},
+      {uniname2ctype_offset(str14), 184},
+      {uniname2ctype_offset(str15), 111},
+      {uniname2ctype_offset(str16), 152},
+      {uniname2ctype_offset(str17), 61},
+      {-1},
+      {uniname2ctype_offset(str19), 34},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str26), 52},
+      {-1},
+      {uniname2ctype_offset(str28), 186},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str33), 28},
+      {-1},
+      {uniname2ctype_offset(str35), 33},
+      {-1},
+      {uniname2ctype_offset(str37), 241},
+      {-1},
+      {uniname2ctype_offset(str39), 95},
+      {uniname2ctype_offset(str40), 95},
+      {uniname2ctype_offset(str41), 22},
+      {uniname2ctype_offset(str42), 173},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str47), 44},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str51), 320},
+      {uniname2ctype_offset(str52), 181},
+      {-1},
+      {uniname2ctype_offset(str54), 308},
+      {uniname2ctype_offset(str55), 255},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str59), 42},
+      {uniname2ctype_offset(str60), 149},
+      {uniname2ctype_offset(str61), 184},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str66), 149},
+      {-1}, {-1},
+      {uniname2ctype_offset(str69), 187},
+      {uniname2ctype_offset(str70), 98},
+      {uniname2ctype_offset(str71), 45},
+      {uniname2ctype_offset(str72), 77},
+      {uniname2ctype_offset(str73), 160},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str80), 31},
+      {-1},
+      {uniname2ctype_offset(str82), 172},
+      {-1}, {-1},
+      {uniname2ctype_offset(str85), 108},
+      {uniname2ctype_offset(str86), 31},
+      {uniname2ctype_offset(str87), 189},
+      {uniname2ctype_offset(str88), 189},
+      {-1},
+      {uniname2ctype_offset(str90), 77},
+      {-1}, {-1},
+      {uniname2ctype_offset(str93), 212},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str97), 484},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str105), 170},
+      {uniname2ctype_offset(str106), 487},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str111), 18},
+      {-1},
+      {uniname2ctype_offset(str113), 302},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str117), 75},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str122), 470},
+      {uniname2ctype_offset(str123), 526},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str129), 529},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str137), 169},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str142), 326},
+      {uniname2ctype_offset(str143), 27},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str150), 248},
+      {-1}, {-1},
+      {uniname2ctype_offset(str153), 530},
+      {uniname2ctype_offset(str154), 498},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str160), 339},
+      {uniname2ctype_offset(str161), 194},
+      {uniname2ctype_offset(str162), 40},
+      {-1},
+      {uniname2ctype_offset(str164), 208},
+      {-1}, {-1},
+      {uniname2ctype_offset(str167), 31},
+      {uniname2ctype_offset(str168), 171},
+      {uniname2ctype_offset(str169), 334},
+      {uniname2ctype_offset(str170), 461},
+      {-1},
+      {uniname2ctype_offset(str172), 521},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1},
+      {uniname2ctype_offset(str184), 512},
+      {-1},
+      {uniname2ctype_offset(str186), 331},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str191), 115},
+      {-1},
+      {uniname2ctype_offset(str193), 102},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1},
+      {uniname2ctype_offset(str205), 25},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str210), 520},
+      {-1}, {-1},
+      {uniname2ctype_offset(str213), 19},
+      {-1},
+      {uniname2ctype_offset(str215), 79},
+      {uniname2ctype_offset(str216), 488},
+      {uniname2ctype_offset(str217), 161},
+      {-1},
+      {uniname2ctype_offset(str219), 32},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str223), 79},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str227), 296},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1},
+      {uniname2ctype_offset(str238), 518},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str243), 40},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str250), 500},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str255), 53},
+      {uniname2ctype_offset(str256), 212},
+      {-1}, {-1},
+      {uniname2ctype_offset(str259), 368},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str268), 249},
+      {-1},
+      {uniname2ctype_offset(str270), 429},
+      {uniname2ctype_offset(str271), 76},
+      {uniname2ctype_offset(str272), 300},
+      {uniname2ctype_offset(str273), 76},
+      {-1}, {-1},
+      {uniname2ctype_offset(str276), 514},
+      {-1}, {-1},
+      {uniname2ctype_offset(str279), 309},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str283), 248},
+      {-1},
+      {uniname2ctype_offset(str285), 519},
+      {-1}, {-1},
+      {uniname2ctype_offset(str288), 221},
+      {uniname2ctype_offset(str289), 129},
+      {-1},
+      {uniname2ctype_offset(str291), 160},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str295), 323},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str300), 163},
+      {uniname2ctype_offset(str301), 307},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str309), 496},
+      {-1},
+      {uniname2ctype_offset(str311), 44},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str315), 399},
+      {-1},
+      {uniname2ctype_offset(str317), 345},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str343), 305},
+      {uniname2ctype_offset(str344), 511},
+      {uniname2ctype_offset(str345), 163},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1},
+      {uniname2ctype_offset(str356), 81},
+      {uniname2ctype_offset(str357), 169},
+      {-1},
+      {uniname2ctype_offset(str359), 23},
+      {-1},
+      {uniname2ctype_offset(str361), 187},
+      {uniname2ctype_offset(str362), 55},
+      {uniname2ctype_offset(str363), 24},
+      {-1},
+      {uniname2ctype_offset(str365), 22},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str369), 188},
+      {uniname2ctype_offset(str370), 108},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str377), 227},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str383), 127},
+      {uniname2ctype_offset(str384), 70},
+      {-1},
+      {uniname2ctype_offset(str386), 430},
+      {uniname2ctype_offset(str387), 14},
+      {-1},
+      {uniname2ctype_offset(str389), 46},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str393), 534},
+      {-1}, {-1},
+      {uniname2ctype_offset(str396), 436},
+      {-1}, {-1},
+      {uniname2ctype_offset(str399), 494},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str408), 37},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str412), 91},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str425), 91},
+      {-1}, {-1},
+      {uniname2ctype_offset(str428), 486},
+      {-1},
+      {uniname2ctype_offset(str430), 396},
+      {-1},
+      {uniname2ctype_offset(str432), 509},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str440), 449},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str445), 443},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str453), 70},
+      {-1},
+      {uniname2ctype_offset(str455), 546},
+      {-1}, {-1},
+      {uniname2ctype_offset(str458), 168},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str480), 463},
+      {-1},
+      {uniname2ctype_offset(str482), 379},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str486), 453},
+      {uniname2ctype_offset(str487), 555},
+      {uniname2ctype_offset(str488), 246},
+      {uniname2ctype_offset(str489), 113},
+      {-1}, {-1},
+      {uniname2ctype_offset(str492), 557},
+      {uniname2ctype_offset(str493), 24},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str509), 195},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str516), 144},
+      {uniname2ctype_offset(str517), 144},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str523), 29},
+      {uniname2ctype_offset(str524), 171},
+      {-1},
+      {uniname2ctype_offset(str526), 69},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str530), 420},
+      {uniname2ctype_offset(str531), 310},
+      {-1},
+      {uniname2ctype_offset(str533), 474},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str541), 567},
+      {-1}, {-1},
+      {uniname2ctype_offset(str544), 324},
+      {uniname2ctype_offset(str545), 350},
+      {-1},
+      {uniname2ctype_offset(str547), 106},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str552), 158},
+      {-1},
+      {uniname2ctype_offset(str554), 68},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str561), 458},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1},
+      {uniname2ctype_offset(str573), 146},
+      {uniname2ctype_offset(str574), 74},
+      {-1},
+      {uniname2ctype_offset(str576), 72},
+      {uniname2ctype_offset(str577), 19},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str586), 533},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str591), 372},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str596), 547},
+      {-1},
+      {uniname2ctype_offset(str598), 51},
+      {-1}, {-1},
+      {uniname2ctype_offset(str601), 485},
+      {uniname2ctype_offset(str602), 49},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str606), 7},
+      {uniname2ctype_offset(str607), 234},
+      {-1},
+      {uniname2ctype_offset(str609), 192},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str618), 167},
+      {uniname2ctype_offset(str619), 550},
+      {uniname2ctype_offset(str620), 347},
+      {-1},
+      {uniname2ctype_offset(str622), 460},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str629), 175},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str636), 167},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str642), 417},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str657), 246},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str665), 321},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str670), 404},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1},
+      {uniname2ctype_offset(str681), 371},
+      {-1}, {-1},
+      {uniname2ctype_offset(str684), 156},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str689), 178},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str693), 156},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str699), 539},
+      {uniname2ctype_offset(str700), 67},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str705), 41},
+      {-1}, {-1},
+      {uniname2ctype_offset(str708), 50},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str715), 193},
+      {uniname2ctype_offset(str716), 218},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str725), 455},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str730), 68},
+      {-1},
+      {uniname2ctype_offset(str732), 540},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str737), 492},
+      {uniname2ctype_offset(str738), 13},
+      {uniname2ctype_offset(str739), 466},
+      {-1},
+      {uniname2ctype_offset(str741), 47},
+      {uniname2ctype_offset(str742), 377},
+      {uniname2ctype_offset(str743), 35},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str748), 157},
+      {-1}, {-1},
+      {uniname2ctype_offset(str751), 385},
+      {-1},
+      {uniname2ctype_offset(str753), 419},
+      {-1}, {-1},
+      {uniname2ctype_offset(str756), 554},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str770), 48},
+      {-1}, {-1},
+      {uniname2ctype_offset(str773), 38},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str777), 112},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str781), 39},
+      {uniname2ctype_offset(str782), 134},
+      {-1}, {-1},
+      {uniname2ctype_offset(str785), 71},
+      {-1},
+      {uniname2ctype_offset(str787), 235},
+      {uniname2ctype_offset(str788), 343},
+      {-1}, {-1},
+      {uniname2ctype_offset(str791), 140},
+      {uniname2ctype_offset(str792), 140},
+      {uniname2ctype_offset(str793), 228},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str797), 480},
+      {-1},
+      {uniname2ctype_offset(str799), 294},
+      {-1}, {-1},
+      {uniname2ctype_offset(str802), 468},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str807), 434},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str812), 473},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str819), 422},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str823), 432},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1},
+      {uniname2ctype_offset(str834), 67},
+      {uniname2ctype_offset(str835), 136},
+      {-1},
+      {uniname2ctype_offset(str837), 297},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1},
+      {uniname2ctype_offset(str848), 85},
+      {uniname2ctype_offset(str849), 318},
+      {-1},
+      {uniname2ctype_offset(str851), 503},
+      {uniname2ctype_offset(str852), 245},
+      {uniname2ctype_offset(str853), 481},
+      {-1},
+      {uniname2ctype_offset(str855), 136},
+      {uniname2ctype_offset(str856), 142},
+      {uniname2ctype_offset(str857), 60},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str862), 115},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str867), 2},
+      {-1}, {-1},
+      {uniname2ctype_offset(str870), 104},
+      {-1},
+      {uniname2ctype_offset(str872), 247},
+      {-1},
+      {uniname2ctype_offset(str874), 217},
+      {-1}, {-1},
+      {uniname2ctype_offset(str877), 11},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str881), 69},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str885), 459},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1},
+      {uniname2ctype_offset(str897), 457},
+      {-1},
+      {uniname2ctype_offset(str899), 102},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str903), 101},
+      {-1},
+      {uniname2ctype_offset(str905), 173},
+      {uniname2ctype_offset(str906), 197},
+      {-1}, {-1},
+      {uniname2ctype_offset(str909), 101},
+      {-1},
+      {uniname2ctype_offset(str911), 138},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str918), 208},
+      {uniname2ctype_offset(str919), 398},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str926), 522},
+      {-1},
+      {uniname2ctype_offset(str928), 73},
+      {-1},
+      {uniname2ctype_offset(str930), 151},
+      {uniname2ctype_offset(str931), 476},
+      {uniname2ctype_offset(str932), 166},
+      {-1}, {-1},
+      {uniname2ctype_offset(str935), 508},
+      {-1},
+      {uniname2ctype_offset(str937), 228},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str942), 170},
+      {-1},
+      {uniname2ctype_offset(str944), 74},
+      {-1}, {-1},
+      {uniname2ctype_offset(str947), 504},
+      {uniname2ctype_offset(str948), 499},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str956), 183},
+      {uniname2ctype_offset(str957), 333},
+      {-1}, {-1},
+      {uniname2ctype_offset(str960), 135},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str966), 542},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str975), 186},
+      {uniname2ctype_offset(str976), 129},
+      {uniname2ctype_offset(str977), 158},
+      {-1}, {-1},
+      {uniname2ctype_offset(str980), 244},
+      {-1}, {-1},
+      {uniname2ctype_offset(str983), 329},
+      {-1},
+      {uniname2ctype_offset(str985), 26},
+      {-1}, {-1},
+      {uniname2ctype_offset(str988), 353},
+      {-1}, {-1},
+      {uniname2ctype_offset(str991), 387},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str996), 53},
+      {-1},
+      {uniname2ctype_offset(str998), 206},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1016), 301},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1019), 392},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1022), 435},
+      {uniname2ctype_offset(str1023), 36},
+      {-1},
+      {uniname2ctype_offset(str1025), 105},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1029), 129},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1032), 200},
+      {-1},
+      {uniname2ctype_offset(str1034), 104},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1048), 541},
+      {uniname2ctype_offset(str1049), 322},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1053), 126},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1056), 161},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1061), 25},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1065), 105},
+      {-1},
+      {uniname2ctype_offset(str1067), 122},
+      {-1},
+      {uniname2ctype_offset(str1069), 206},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1076), 489},
+      {uniname2ctype_offset(str1077), 490},
+      {uniname2ctype_offset(str1078), 93},
+      {-1},
+      {uniname2ctype_offset(str1080), 215},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1086), 408},
+      {-1},
+      {uniname2ctype_offset(str1088), 203},
+      {uniname2ctype_offset(str1089), 221},
+      {uniname2ctype_offset(str1090), 565},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1094), 478},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1098), 517},
+      {-1},
+      {uniname2ctype_offset(str1100), 472},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1103), 402},
+      {uniname2ctype_offset(str1104), 164},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1107), 109},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1114), 122},
+      {uniname2ctype_offset(str1115), 354},
+      {uniname2ctype_offset(str1116), 131},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1119), 135},
+      {uniname2ctype_offset(str1120), 467},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1124), 113},
+      {-1},
+      {uniname2ctype_offset(str1126), 56},
+      {uniname2ctype_offset(str1127), 218},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1131), 15},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1135), 30},
+      {uniname2ctype_offset(str1136), 120},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1},
+      {uniname2ctype_offset(str1147), 370},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1152), 110},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1155), 110},
+      {uniname2ctype_offset(str1156), 414},
+      {uniname2ctype_offset(str1157), 141},
+      {uniname2ctype_offset(str1158), 121},
+      {-1},
+      {uniname2ctype_offset(str1160), 176},
+      {uniname2ctype_offset(str1161), 181},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1167), 117},
+      {uniname2ctype_offset(str1168), 479},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1172), 88},
+      {uniname2ctype_offset(str1173), 507},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1178), 86},
+      {uniname2ctype_offset(str1179), 166},
+      {uniname2ctype_offset(str1180), 145},
+      {-1},
+      {uniname2ctype_offset(str1182), 563},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1186), 117},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1189), 193},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1192), 176},
+      {uniname2ctype_offset(str1193), 107},
+      {-1},
+      {uniname2ctype_offset(str1195), 304},
+      {uniname2ctype_offset(str1196), 109},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1201), 236},
+      {uniname2ctype_offset(str1202), 86},
+      {uniname2ctype_offset(str1203), 502},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1207), 81},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1211), 120},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1218), 465},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1222), 168},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1225), 493},
+      {-1},
+      {uniname2ctype_offset(str1227), 537},
+      {-1},
+      {uniname2ctype_offset(str1229), 388},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1232), 240},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1237), 196},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1243), 115},
+      {-1},
+      {uniname2ctype_offset(str1245), 410},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1249), 222},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1252), 397},
+      {uniname2ctype_offset(str1253), 72},
+      {uniname2ctype_offset(str1254), 114},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1257), 3},
+      {-1},
+      {uniname2ctype_offset(str1259), 137},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1262), 311},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1267), 292},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1275), 114},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1281), 553},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1285), 217},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1288), 42},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1294), 360},
+      {-1},
+      {uniname2ctype_offset(str1296), 445},
+      {-1},
+      {uniname2ctype_offset(str1298), 73},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1306), 106},
+      {uniname2ctype_offset(str1307), 201},
+      {uniname2ctype_offset(str1308), 373},
+      {uniname2ctype_offset(str1309), 505},
+      {uniname2ctype_offset(str1310), 98},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1317), 210},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1325), 471},
+      {uniname2ctype_offset(str1326), 362},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1331), 145},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1334), 469},
+      {uniname2ctype_offset(str1335), 9},
+      {uniname2ctype_offset(str1336), 203},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1340), 477},
+      {uniname2ctype_offset(str1341), 524},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1344), 32},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1348), 1},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1354), 327},
+      {uniname2ctype_offset(str1355), 325},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1364), 352},
+      {uniname2ctype_offset(str1365), 351},
+      {-1},
+      {uniname2ctype_offset(str1367), 250},
+      {uniname2ctype_offset(str1368), 125},
+      {uniname2ctype_offset(str1369), 207},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1372), 340},
+      {uniname2ctype_offset(str1373), 245},
+      {uniname2ctype_offset(str1374), 127},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1379), 164},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1382), 207},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1388), 138},
+      {-1},
+      {uniname2ctype_offset(str1390), 375},
+#ifndef USE_UNICODE_AGE_PROPERTIES
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1},
+#else /* USE_UNICODE_AGE_PROPERTIES */
+      {uniname2ctype_offset(str1391), 256},
+      {uniname2ctype_offset(str1392), 263},
+      {uniname2ctype_offset(str1393), 262},
+      {uniname2ctype_offset(str1394), 274},
+      {uniname2ctype_offset(str1395), 258},
+      {uniname2ctype_offset(str1396), 257},
+      {uniname2ctype_offset(str1397), 268},
+      {uniname2ctype_offset(str1398), 267},
+      {uniname2ctype_offset(str1399), 273},
+      {uniname2ctype_offset(str1400), 272},
+      {uniname2ctype_offset(str1401), 269},
+      {uniname2ctype_offset(str1402), 271},
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+      {uniname2ctype_offset(str1403), 552},
+      {uniname2ctype_offset(str1404), 367},
+#ifndef USE_UNICODE_AGE_PROPERTIES
+      {-1}, {-1},
+#else /* USE_UNICODE_AGE_PROPERTIES */
+      {uniname2ctype_offset(str1405), 265},
+      {uniname2ctype_offset(str1406), 264},
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+      {uniname2ctype_offset(str1407), 36},
+      {uniname2ctype_offset(str1408), 52},
+#ifndef USE_UNICODE_AGE_PROPERTIES
+      {-1}, {-1},
+#else /* USE_UNICODE_AGE_PROPERTIES */
+      {uniname2ctype_offset(str1409), 266},
+      {-1},
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+      {uniname2ctype_offset(str1411), 315},
+      {-1},
+      {uniname2ctype_offset(str1413), 564},
+      {uniname2ctype_offset(str1414), 153},
+      {-1},
+      {uniname2ctype_offset(str1416), 93},
+#ifndef USE_UNICODE_AGE_PROPERTIES
+      {-1}, {-1}, {-1},
+#else /* USE_UNICODE_AGE_PROPERTIES */
+      {uniname2ctype_offset(str1417), 260},
+      {uniname2ctype_offset(str1418), 259},
+      {-1},
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+      {uniname2ctype_offset(str1420), 202},
+#ifndef USE_UNICODE_AGE_PROPERTIES
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+#else /* USE_UNICODE_AGE_PROPERTIES */
+      {uniname2ctype_offset(str1421), 261},
+      {-1},
+      {uniname2ctype_offset(str1423), 270},
+      {-1}, {-1}, {-1},
+#endif /* USE_UNICODE_AGE_PROPERTIES */
+      {uniname2ctype_offset(str1427), 20},
+      {-1},
+      {uniname2ctype_offset(str1429), 124},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1434), 501},
+      {uniname2ctype_offset(str1435), 137},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1439), 428},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1444), 39},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1449), 312},
+      {uniname2ctype_offset(str1450), 202},
+      {uniname2ctype_offset(str1451), 336},
+      {-1},
+      {uniname2ctype_offset(str1453), 418},
+      {-1},
+      {uniname2ctype_offset(str1455), 27},
+      {uniname2ctype_offset(str1456), 238},
+      {-1},
+      {uniname2ctype_offset(str1458), 225},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1463), 241},
+      {uniname2ctype_offset(str1464), 538},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1469), 141},
+      {uniname2ctype_offset(str1470), 35},
+      {uniname2ctype_offset(str1471), 355},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1485), 462},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1490), 252},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1496), 54},
+      {uniname2ctype_offset(str1497), 225},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1500), 313},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1508), 506},
+      {-1},
+      {uniname2ctype_offset(str1510), 154},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1},
+      {uniname2ctype_offset(str1521), 497},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1535), 383},
+      {uniname2ctype_offset(str1536), 381},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1539), 34},
+      {uniname2ctype_offset(str1540), 299},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1545), 8},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1553), 513},
+      {-1},
+      {uniname2ctype_offset(str1555), 243},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1560), 222},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1565), 20},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1572), 6},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1580), 332},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1585), 234},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1589), 349},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1593), 536},
+      {uniname2ctype_offset(str1594), 572},
+      {uniname2ctype_offset(str1595), 43},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1602), 317},
+      {-1},
+      {uniname2ctype_offset(str1604), 405},
+      {-1},
+      {uniname2ctype_offset(str1606), 424},
+      {uniname2ctype_offset(str1607), 199},
+      {uniname2ctype_offset(str1608), 535},
+      {uniname2ctype_offset(str1609), 142},
+      {-1},
+      {uniname2ctype_offset(str1611), 482},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1617), 85},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1623), 235},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1628), 242},
+      {-1},
+      {uniname2ctype_offset(str1630), 249},
+      {uniname2ctype_offset(str1631), 33},
+      {uniname2ctype_offset(str1632), 159},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1636), 121},
+      {-1},
+      {uniname2ctype_offset(str1638), 253},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1645), 357},
+      {-1},
+      {uniname2ctype_offset(str1647), 58},
+      {uniname2ctype_offset(str1648), 447},
+      {-1},
+      {uniname2ctype_offset(str1650), 159},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1654), 244},
+      {uniname2ctype_offset(str1655), 361},
+      {uniname2ctype_offset(str1656), 446},
+      {uniname2ctype_offset(str1657), 66},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1663), 148},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1666), 154},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1669), 148},
+      {-1},
+      {uniname2ctype_offset(str1671), 215},
+      {uniname2ctype_offset(str1672), 162},
+      {uniname2ctype_offset(str1673), 356},
+      {uniname2ctype_offset(str1674), 395},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1677), 431},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1682), 97},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1690), 394},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1695), 97},
+      {-1},
+      {uniname2ctype_offset(str1697), 89},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1714), 230},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1},
+      {uniname2ctype_offset(str1725), 37},
+      {-1},
+      {uniname2ctype_offset(str1727), 330},
+      {uniname2ctype_offset(str1728), 143},
+      {-1},
+      {uniname2ctype_offset(str1730), 433},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1736), 5},
+      {uniname2ctype_offset(str1737), 143},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1741), 358},
+      {-1},
+      {uniname2ctype_offset(str1743), 254},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1746), 341},
+      {-1},
+      {uniname2ctype_offset(str1748), 376},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1752), 569},
+      {-1},
+      {uniname2ctype_offset(str1754), 87},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1762), 174},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1766), 87},
+      {uniname2ctype_offset(str1767), 232},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1772), 344},
+      {-1},
+      {uniname2ctype_offset(str1774), 131},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1780), 227},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1783), 174},
+      {-1},
+      {uniname2ctype_offset(str1785), 515},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1789), 416},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1},
+      {uniname2ctype_offset(str1800), 293},
+      {-1},
+      {uniname2ctype_offset(str1802), 219},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1806), 378},
+      {-1},
+      {uniname2ctype_offset(str1808), 55},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1813), 139},
+      {uniname2ctype_offset(str1814), 29},
+      {uniname2ctype_offset(str1815), 407},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1818), 531},
+      {uniname2ctype_offset(str1819), 298},
+      {-1},
+      {uniname2ctype_offset(str1821), 413},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1825), 196},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1829), 365},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1},
+      {uniname2ctype_offset(str1840), 177},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1843), 237},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1846), 423},
+      {uniname2ctype_offset(str1847), 190},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1857), 400},
+      {uniname2ctype_offset(str1858), 566},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1861), 483},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1866), 247},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1885), 363},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1894), 150},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1900), 150},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1903), 568},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1909), 319},
+      {uniname2ctype_offset(str1910), 390},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1914), 559},
+      {uniname2ctype_offset(str1915), 359},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1922), 84},
+      {-1},
+      {uniname2ctype_offset(str1924), 442},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1932), 84},
+      {uniname2ctype_offset(str1933), 232},
+      {uniname2ctype_offset(str1934), 495},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1943), 26},
+      {uniname2ctype_offset(str1944), 12},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1975), 61},
+      {uniname2ctype_offset(str1976), 412},
+      {-1}, {-1},
+      {uniname2ctype_offset(str1979), 239},
+      {-1},
+      {uniname2ctype_offset(str1981), 94},
+      {-1},
+      {uniname2ctype_offset(str1983), 83},
+      {-1},
+      {uniname2ctype_offset(str1985), 348},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1989), 543},
+      {-1},
+      {uniname2ctype_offset(str1991), 83},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str1995), 556},
+      {-1},
+      {uniname2ctype_offset(str1997), 134},
+      {uniname2ctype_offset(str1998), 21},
+      {uniname2ctype_offset(str1999), 380},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2003), 516},
+      {-1},
+      {uniname2ctype_offset(str2005), 64},
+      {-1},
+      {uniname2ctype_offset(str2007), 198},
+      {uniname2ctype_offset(str2008), 185},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2013), 450},
+      {-1},
+      {uniname2ctype_offset(str2015), 198},
+      {-1},
+      {uniname2ctype_offset(str2017), 165},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2020), 185},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2047), 240},
+      {-1},
+      {uniname2ctype_offset(str2049), 421},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2056), 391},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2059), 152},
+      {-1},
+      {uniname2ctype_offset(str2061), 17},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2068), 191},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2072), 415},
+      {uniname2ctype_offset(str2073), 183},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2076), 118},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2079), 191},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2084), 444},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2091), 175},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2095), 560},
+      {uniname2ctype_offset(str2096), 194},
+      {uniname2ctype_offset(str2097), 78},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2101), 43},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1},
+      {uniname2ctype_offset(str2112), 172},
+      {-1},
+      {uniname2ctype_offset(str2114), 306},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2117), 195},
+      {-1},
+      {uniname2ctype_offset(str2119), 491},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2134), 92},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2139), 562},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2146), 192},
+      {-1},
+      {uniname2ctype_offset(str2148), 384},
+      {uniname2ctype_offset(str2149), 92},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2154), 214},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2158), 224},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2161), 139},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2165), 287},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2172), 291},
+      {-1},
+      {uniname2ctype_offset(str2174), 328},
+      {-1},
+      {uniname2ctype_offset(str2176), 128},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2179), 281},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2182), 426},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2187), 48},
+      {-1},
+      {uniname2ctype_offset(str2189), 89},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2192), 276},
+      {uniname2ctype_offset(str2193), 130},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2196), 128},
+      {uniname2ctype_offset(str2197), 90},
+      {uniname2ctype_offset(str2198), 389},
+      {uniname2ctype_offset(str2199), 288},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2207), 280},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2210), 342},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2224), 406},
+      {uniname2ctype_offset(str2225), 211},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2229), 369},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2232), 209},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2249), 130},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2252), 80},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2260), 337},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2263), 544},
+      {uniname2ctype_offset(str2264), 82},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2271), 239},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2276), 527},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2286), 243},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2289), 366},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2296), 229},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2300), 18},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2306), 510},
+      {uniname2ctype_offset(str2307), 38},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2311), 427},
+      {-1},
+      {uniname2ctype_offset(str2313), 112},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2327), 213},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2349), 451},
+      {uniname2ctype_offset(str2350), 441},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2353), 448},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2360), 314},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2364), 65},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2369), 346},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2372), 82},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2380), 100},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2386), 226},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2393), 251},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2399), 548},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2408), 211},
+      {uniname2ctype_offset(str2409), 118},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2412), 284},
+      {uniname2ctype_offset(str2413), 229},
+      {uniname2ctype_offset(str2414), 286},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2422), 119},
+      {uniname2ctype_offset(str2423), 99},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2433), 364},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2449), 316},
+      {-1},
+      {uniname2ctype_offset(str2451), 54},
+      {uniname2ctype_offset(str2452), 96},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2461), 96},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2465), 103},
+      {-1},
+      {uniname2ctype_offset(str2467), 62},
+      {-1},
+      {uniname2ctype_offset(str2469), 226},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2473), 107},
+      {-1},
+      {uniname2ctype_offset(str2475), 23},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2481), 525},
+      {-1},
+      {uniname2ctype_offset(str2483), 425},
+      {uniname2ctype_offset(str2484), 532},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2488), 182},
+      {uniname2ctype_offset(str2489), 279},
+      {uniname2ctype_offset(str2490), 275},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2493), 178},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2500), 464},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2507), 57},
+      {-1},
+      {uniname2ctype_offset(str2509), 50},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2515), 231},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2519), 204},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2523), 153},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2526), 393},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2539), 41},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2545), 551},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2550), 456},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2573), 210},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2576), 4},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2579), 179},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2587), 454},
+      {-1},
+      {uniname2ctype_offset(str2589), 126},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2594), 216},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2601), 216},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2617), 63},
+      {uniname2ctype_offset(str2618), 213},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2622), 338},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2630), 133},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2643), 282},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2649), 278},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2653), 165},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2660), 66},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2678), 147},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2693), 78},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2702), 99},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2705), 49},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2708), 558},
+      {-1},
+      {uniname2ctype_offset(str2710), 570},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2717), 88},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2751), 549},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2758), 64},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2763), 132},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2775), 230},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2779), 386},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2791), 242},
+      {uniname2ctype_offset(str2792), 123},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2797), 28},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2823), 437},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2829), 180},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2834), 335},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2850), 231},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1},
+      {uniname2ctype_offset(str2879), 223},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2883), 199},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2888), 133},
+      {-1},
+      {uniname2ctype_offset(str2890), 124},
+      {uniname2ctype_offset(str2891), 528},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2901), 452},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2905), 295},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2926), 125},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2930), 277},
+      {-1},
+      {uniname2ctype_offset(str2932), 51},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2953), 71},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2967), 475},
+      {uniname2ctype_offset(str2968), 197},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str2972), 146},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2984), 204},
+      {-1}, {-1},
+      {uniname2ctype_offset(str2987), 255},
+      {-1},
+      {uniname2ctype_offset(str2989), 409},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3007), 180},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3016), 403},
+      {-1}, {-1},
+      {uniname2ctype_offset(str3019), 62},
+      {uniname2ctype_offset(str3020), 45},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3038), 10},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3052), 382},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3066), 190},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3094), 63},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3113), 59},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3121), 123},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3153), 238},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3177), 223},
+      {-1}, {-1},
+      {uniname2ctype_offset(str3180), 132},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3193), 47},
+      {-1},
+      {uniname2ctype_offset(str3195), 224},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3213), 16},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3235), 438},
+      {-1}, {-1},
+      {uniname2ctype_offset(str3238), 100},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1},
+      {uniname2ctype_offset(str3276), 177},
+      {-1}, {-1},
+      {uniname2ctype_offset(str3279), 283},
+      {uniname2ctype_offset(str3280), 285},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3285), 214},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1},
+      {uniname2ctype_offset(str3296), 289},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3305), 290},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3315), 205},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3367), 65},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3373), 103},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3409), 30},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1},
+      {uniname2ctype_offset(str3438), 303},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3442), 440},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3448), 46},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3453), 233},
+      {uniname2ctype_offset(str3454), 220},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1},
+      {uniname2ctype_offset(str3465), 119},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3496), 411},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3593), 162},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3662), 179},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3676), 201},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3689), 545},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3697), 561},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1},
+      {uniname2ctype_offset(str3763), 571},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str3791), 523},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+#endif /* USE_UNICODE_PROPERTIES */
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+#ifndef USE_UNICODE_PROPERTIES
+      {uniname2ctype_offset(str6), 12},
+      {uniname2ctype_offset(str7), 7},
+      {uniname2ctype_offset(str8), 15},
+      {uniname2ctype_offset(str9), 1},
+      {uniname2ctype_offset(str10), 13},
+      {uniname2ctype_offset(str11), 11},
+      {uniname2ctype_offset(str12), 10},
+      {uniname2ctype_offset(str13), 14},
+      {uniname2ctype_offset(str14), 3},
+      {uniname2ctype_offset(str15), 9},
+      {uniname2ctype_offset(str16), 8},
+      {uniname2ctype_offset(str17), 6},
+      {uniname2ctype_offset(str18), 5},
+      {uniname2ctype_offset(str19), 4},
+      {uniname2ctype_offset(str20), 2}
+#else /* USE_UNICODE_PROPERTIES */
+      {uniname2ctype_offset(str3960), 147},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1},
+      {uniname2ctype_offset(str3971), 401},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1},
+      {uniname2ctype_offset(str4036), 90},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1},
+      {uniname2ctype_offset(str4164), 116},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str4187), 116},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1},
+      {uniname2ctype_offset(str4208), 233},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str4460), 237},
+      {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str4464), 374},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str4483), 182},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str4608), 439},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str4634), 205},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str4678), 75},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str4841), 155},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1},
+      {uniname2ctype_offset(str5170), 80},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1},
+      {-1}, {-1},
+      {uniname2ctype_offset(str6145), 155}
+#endif /* USE_UNICODE_PROPERTIES */
+    };
+
+  if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
+    {
+      register int key = uniname2ctype_hash (str, len);
+
+      if (key <= MAX_HASH_VALUE && key >= 0)
+        {
+          register int o = wordlist[key].name;
+          if (o >= 0)
+            {
+              register const char *s = o + uniname2ctype_pool;
+
+              if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
+                return &wordlist[key];
+            }
+        }
+    }
+  return 0;
+}
+
+static int
+uniname2ctype(const UChar *name, unsigned int len)
+{
+  const struct uniname2ctype_struct *p = uniname2ctype_p((const char *)name, len);
+  if (p) return p->ctype;
+  return -1;
+}
+#if defined ONIG_UNICODE_VERSION_STRING && !( \
+      ONIG_UNICODE_VERSION_MAJOR == 10 && \
+      ONIG_UNICODE_VERSION_MINOR == 0 && \
+      ONIG_UNICODE_VERSION_TEENY == 0 && \
+      1)
+# error ONIG_UNICODE_VERSION_STRING mismatch
+#endif
+#define ONIG_UNICODE_VERSION_STRING "10.0.0"
+#define ONIG_UNICODE_VERSION_MAJOR 10
+#define ONIG_UNICODE_VERSION_MINOR 0
+#define ONIG_UNICODE_VERSION_TEENY 0
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/enc/utf_8.c
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/enc/utf_8.c	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/enc/utf_8.c	(revision 331)
@@ -0,0 +1,449 @@
+/**********************************************************************
+  utf_8.c -  Oniguruma (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2007  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "regenc.h"
+#ifdef RUBY
+# include "encindex.h"
+#endif
+
+#ifndef ENCINDEX_UTF_8
+# define ENCINDEX_UTF_8 0
+#endif
+
+#define USE_INVALID_CODE_SCHEME
+
+#ifdef USE_INVALID_CODE_SCHEME
+/* virtual codepoint values for invalid encoding byte 0xfe and 0xff */
+# define INVALID_CODE_FE  0xfffffffe
+# define INVALID_CODE_FF  0xffffffff
+#endif
+#define VALID_CODE_LIMIT  0x0010ffff
+
+#define utf8_islead(c)     ((UChar )((c) & 0xc0) != 0x80)
+
+static const int EncLen_UTF8[] = {
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+  2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+  3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+  4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+};
+
+typedef enum {
+  FAILURE = -2,
+  ACCEPT,
+  S0, S1, S2, S3,
+  S4, S5, S6, S7
+} state_t;
+#define A ACCEPT
+#define F FAILURE
+static const signed char trans[][0x100] = {
+  { /* S0   0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f */
+    /* 0 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+    /* 1 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+    /* 2 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+    /* 3 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+    /* 4 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+    /* 5 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+    /* 6 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+    /* 7 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+    /* 8 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 9 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* a */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* b */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* c */ F, F, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    /* d */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    /* e */ 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3,
+    /* f */ 5, 6, 6, 6, 7, F, F, F, F, F, F, F, F, F, F, F
+  },
+  { /* S1   0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f */
+    /* 0 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 1 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 2 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 3 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 4 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 5 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 6 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 7 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 8 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+    /* 9 */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+    /* a */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+    /* b */ A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A,
+    /* c */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* d */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* e */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* f */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F
+  },
+  { /* S2   0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f */
+    /* 0 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 1 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 2 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 3 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 4 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 5 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 6 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 7 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 8 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 9 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* a */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    /* b */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    /* c */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* d */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* e */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* f */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F
+  },
+  { /* S3   0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f */
+    /* 0 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 1 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 2 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 3 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 4 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 5 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 6 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 7 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 8 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    /* 9 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    /* a */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    /* b */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    /* c */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* d */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* e */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* f */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F
+  },
+  { /* S4   0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f */
+    /* 0 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 1 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 2 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 3 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 4 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 5 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 6 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 7 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 8 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    /* 9 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    /* a */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* b */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* c */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* d */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* e */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* f */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F
+  },
+  { /* S5   0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f */
+    /* 0 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 1 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 2 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 3 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 4 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 5 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 6 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 7 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 8 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 9 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    /* a */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    /* b */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    /* c */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* d */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* e */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* f */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F
+  },
+  { /* S6   0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f */
+    /* 0 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 1 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 2 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 3 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 4 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 5 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 6 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 7 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 8 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    /* 9 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    /* a */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    /* b */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    /* c */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* d */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* e */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* f */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F
+  },
+  { /* S7   0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f */
+    /* 0 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 1 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 2 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 3 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 4 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 5 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 6 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 7 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* 8 */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    /* 9 */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* a */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* b */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* c */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* d */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* e */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
+    /* f */ F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F
+  },
+};
+#undef A
+#undef F
+
+static int
+mbc_enc_len(const UChar* p, const UChar* e, OnigEncoding enc ARG_UNUSED)
+{
+  int firstbyte = *p++;
+  state_t s;
+  s = trans[0][firstbyte];
+  if (s < 0) return s == ACCEPT ? ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(1) :
+                                  ONIGENC_CONSTRUCT_MBCLEN_INVALID();
+
+  if (p == e) return ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(EncLen_UTF8[firstbyte]-1);
+  s = trans[s][*p++];
+  if (s < 0) return s == ACCEPT ? ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(2) :
+                                  ONIGENC_CONSTRUCT_MBCLEN_INVALID();
+
+  if (p == e) return ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(EncLen_UTF8[firstbyte]-2);
+  s = trans[s][*p++];
+  if (s < 0) return s == ACCEPT ? ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(3) :
+                                  ONIGENC_CONSTRUCT_MBCLEN_INVALID();
+
+  if (p == e) return ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(EncLen_UTF8[firstbyte]-3);
+  s = trans[s][*p++];
+  return s == ACCEPT ? ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(4) :
+                       ONIGENC_CONSTRUCT_MBCLEN_INVALID();
+}
+
+static int
+is_mbc_newline(const UChar* p, const UChar* end, OnigEncoding enc)
+{
+  if (p < end) {
+    if (*p == 0x0a) return 1;
+
+#ifdef USE_UNICODE_ALL_LINE_TERMINATORS
+    if (*p == 0x0b || *p == 0x0c || *p == 0x0d) return 1;
+    if (p + 1 < end) {
+      if (*(p+1) == 0x85 && *p == 0xc2) /* U+0085 */
+	return 1;
+      if (p + 2 < end) {
+	if ((*(p+2) == 0xa8 || *(p+2) == 0xa9)
+	    && *(p+1) == 0x80 && *p == 0xe2)  /* U+2028, U+2029 */
+	  return 1;
+      }
+    }
+#endif
+  }
+
+  return 0;
+}
+
+static OnigCodePoint
+mbc_to_code(const UChar* p, const UChar* end, OnigEncoding enc)
+{
+  int c, len;
+  OnigCodePoint n;
+
+  len = mbc_enc_len(p, end, enc);
+  c = *p++;
+  if (len > 1) {
+    len--;
+    n = c & ((1 << (6 - len)) - 1);
+    while (len--) {
+      c = *p++;
+      n = (n << 6) | (c & ((1 << 6) - 1));
+    }
+    return n;
+  }
+  else {
+#ifdef USE_INVALID_CODE_SCHEME
+    if (c > 0xfd) {
+      return ((c == 0xfe) ? INVALID_CODE_FE : INVALID_CODE_FF);
+    }
+#endif
+    return (OnigCodePoint )c;
+  }
+}
+
+static int
+code_to_mbclen(OnigCodePoint code, OnigEncoding enc ARG_UNUSED)
+{
+  if      ((code & 0xffffff80) == 0) return 1;
+  else if ((code & 0xfffff800) == 0) return 2;
+  else if ((code & 0xffff0000) == 0) return 3;
+  else if (code <= VALID_CODE_LIMIT) return 4;
+#ifdef USE_INVALID_CODE_SCHEME
+  else if (code == INVALID_CODE_FE) return 1;
+  else if (code == INVALID_CODE_FF) return 1;
+#endif
+  else
+    return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
+}
+
+static int
+code_to_mbc(OnigCodePoint code, UChar *buf, OnigEncoding enc ARG_UNUSED)
+{
+#define UTF8_TRAILS(code, shift) (UChar )((((code) >> (shift)) & 0x3f) | 0x80)
+#define UTF8_TRAIL0(code)        (UChar )(((code) & 0x3f) | 0x80)
+
+  if ((code & 0xffffff80) == 0) {
+    *buf = (UChar )code;
+    return 1;
+  }
+  else {
+    UChar *p = buf;
+
+    if ((code & 0xfffff800) == 0) {
+      *p++ = (UChar )(((code>>6)& 0x1f) | 0xc0);
+    }
+    else if ((code & 0xffff0000) == 0) {
+      *p++ = (UChar )(((code>>12) & 0x0f) | 0xe0);
+      *p++ = UTF8_TRAILS(code, 6);
+    }
+    else if (code <= VALID_CODE_LIMIT) {
+      *p++ = (UChar )(((code>>18) & 0x07) | 0xf0);
+      *p++ = UTF8_TRAILS(code, 12);
+      *p++ = UTF8_TRAILS(code,  6);
+    }
+#ifdef USE_INVALID_CODE_SCHEME
+    else if (code == INVALID_CODE_FE) {
+      *p = 0xfe;
+      return 1;
+    }
+    else if (code == INVALID_CODE_FF) {
+      *p = 0xff;
+      return 1;
+    }
+#endif
+    else {
+      return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
+    }
+
+    *p++ = UTF8_TRAIL0(code);
+    return (int )(p - buf);
+  }
+}
+
+static int
+mbc_case_fold(OnigCaseFoldType flag, const UChar** pp,
+	      const UChar* end, UChar* fold, OnigEncoding enc)
+{
+  const UChar* p = *pp;
+
+  if (ONIGENC_IS_MBC_ASCII(p)) {
+#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
+    if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) != 0) {
+      if (*p == 0x49) {
+	*fold++ = 0xc4;
+	*fold   = 0xb1;
+	(*pp)++;
+	return 2;
+      }
+    }
+#endif
+
+    *fold = ONIGENC_ASCII_CODE_TO_LOWER_CASE(*p);
+    (*pp)++;
+    return 1; /* return byte length of converted char to lower */
+  }
+  else {
+    return onigenc_unicode_mbc_case_fold(enc, flag, pp, end, fold);
+  }
+}
+
+
+static int
+get_ctype_code_range(OnigCtype ctype, OnigCodePoint *sb_out,
+		     const OnigCodePoint* ranges[], OnigEncoding enc ARG_UNUSED)
+{
+  *sb_out = 0x80;
+  return onigenc_unicode_ctype_code_range(ctype, ranges);
+}
+
+
+static UChar*
+left_adjust_char_head(const UChar* start, const UChar* s, const UChar* end, OnigEncoding enc ARG_UNUSED)
+{
+  const UChar *p;
+
+  if (s <= start) return (UChar* )s;
+  p = s;
+
+  while (!utf8_islead(*p) && p > start) p--;
+  return (UChar* )p;
+}
+
+static int
+get_case_fold_codes_by_str(OnigCaseFoldType flag,
+    const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[],
+    OnigEncoding enc)
+{
+  return onigenc_unicode_get_case_fold_codes_by_str(enc, flag, p, end, items);
+}
+
+OnigEncodingDefine(utf_8, UTF_8) = {
+  mbc_enc_len,
+  "UTF-8",     /* name */
+  4,           /* max byte length */
+  1,           /* min byte length */
+  is_mbc_newline,
+  mbc_to_code,
+  code_to_mbclen,
+  code_to_mbc,
+  mbc_case_fold,
+  onigenc_unicode_apply_all_case_fold,
+  get_case_fold_codes_by_str,
+  onigenc_unicode_property_name_to_ctype,
+  onigenc_unicode_is_code_ctype,
+  get_ctype_code_range,
+  left_adjust_char_head,
+  onigenc_always_true_is_allowed_reverse_match,
+  onigenc_unicode_case_map,
+  ENCINDEX_UTF_8,
+  ONIGENC_FLAG_UNICODE,
+};
+ENC_ALIAS("CP65001", "UTF-8")
+
+/*
+ * Name: UTF8-MAC
+ * Link: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/BPFileSystem.html
+ * Link: http://developer.apple.com/qa/qa2001/qa1235.html
+ * Link: http://developer.apple.com/jp/qa/qa2001/qa1235.html
+ * Link: http://www.gnu.org/software/emacs/NEWS.23.2
+ */
+ENC_REPLICATE("UTF8-MAC", "UTF-8")
+ENC_ALIAS("UTF-8-MAC", "UTF8-MAC")
+ENC_ALIAS("UTF-8-HFS", "UTF8-MAC") /* Emacs 23.2 */
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/onigmo.h
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/onigmo.h	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/onigmo.h	(revision 331)
@@ -0,0 +1,935 @@
+#ifndef ONIGMO_H
+#define ONIGMO_H
+/**********************************************************************
+  onigmo.h - Onigmo (Oniguruma-mod) (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2009  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011-2017  K.Takata  <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+# if 0
+} /* satisfy cc-mode */
+# endif
+#endif
+
+#define ONIGMO_VERSION_MAJOR   6
+#define ONIGMO_VERSION_MINOR   1
+#define ONIGMO_VERSION_TEENY   3
+
+#ifndef ONIG_EXTERN
+# ifdef RUBY_EXTERN
+#  define ONIG_EXTERN   RUBY_EXTERN
+# else
+#  if defined(_WIN32) && !defined(__GNUC__)
+#   if defined(EXPORT) || defined(RUBY_EXPORT)
+#    define ONIG_EXTERN   extern __declspec(dllexport)
+#   else
+#    define ONIG_EXTERN   extern __declspec(dllimport)
+#   endif
+#  endif
+# endif
+#endif
+
+#ifndef ONIG_EXTERN
+# define ONIG_EXTERN   extern
+#endif
+
+#ifndef RUBY
+# ifndef RUBY_SYMBOL_EXPORT_BEGIN
+#  define RUBY_SYMBOL_EXPORT_BEGIN
+#  define RUBY_SYMBOL_EXPORT_END
+# endif
+#endif
+
+RUBY_SYMBOL_EXPORT_BEGIN
+
+#include <stddef.h>		/* for size_t */
+
+/* PART: character encoding */
+
+#ifndef ONIG_ESCAPE_UCHAR_COLLISION
+# define UChar OnigUChar
+#endif
+
+typedef unsigned char  OnigUChar;
+typedef unsigned int   OnigCodePoint;
+typedef unsigned int   OnigCtype;
+typedef size_t         OnigDistance;
+typedef ptrdiff_t      OnigPosition;
+
+#define ONIG_INFINITE_DISTANCE  ~((OnigDistance )0)
+
+/*
+ * Onig casefold/case mapping flags and related definitions
+ *
+ * Subfields (starting with 0 at LSB):
+ *   0-2: Code point count in casefold.h
+ *   3-12: Index into SpecialCaseMapping array in casefold.h
+ *   13-22: Case folding/mapping flags
+ */
+typedef unsigned int OnigCaseFoldType; /* case fold flag */
+
+ONIG_EXTERN OnigCaseFoldType OnigDefaultCaseFoldFlag;
+
+/* bits for actual code point count; 3 bits is more than enough, currently only 2 used */
+#define OnigCodePointMaskWidth    3
+#define OnigCodePointMask     ((1<<OnigCodePointMaskWidth)-1)
+#define OnigCodePointCount(n) ((n)&OnigCodePointMask)
+#define OnigCaseFoldFlags(n) ((n)&~OnigCodePointMask)
+
+/* #define ONIGENC_CASE_FOLD_HIRAGANA_KATAKANA  (1<<1) */ /* no longer usable with these values! */
+/* #define ONIGENC_CASE_FOLD_KATAKANA_WIDTH     (1<<2) */ /* no longer usable with these values! */
+
+/* bits for index into table with separate titlecase mappings */
+/* 10 bits provide 1024 values */
+#define OnigSpecialIndexShift 3
+#define OnigSpecialIndexWidth 10
+
+#define ONIGENC_CASE_UPCASE                     (1<<13) /* has/needs uppercase mapping */
+#define ONIGENC_CASE_DOWNCASE                   (1<<14) /* has/needs lowercase mapping */
+#define ONIGENC_CASE_TITLECASE                  (1<<15) /* has/needs (special) titlecase mapping */
+#define ONIGENC_CASE_SPECIAL_OFFSET             3       /* offset in bits from ONIGENC_CASE to ONIGENC_CASE_SPECIAL */
+#define ONIGENC_CASE_UP_SPECIAL                 (1<<16) /* has special upcase mapping */
+#define ONIGENC_CASE_DOWN_SPECIAL               (1<<17) /* has special downcase mapping */
+#define ONIGENC_CASE_MODIFIED                   (1<<18) /* data has been modified */
+#define ONIGENC_CASE_FOLD                       (1<<19) /* has/needs case folding */
+
+#define ONIGENC_CASE_FOLD_TURKISH_AZERI         (1<<20) /* needs mapping specific to Turkic languages; better not change original value! */
+
+#define ONIGENC_CASE_FOLD_LITHUANIAN            (1<<21) /* needs Lithuanian-specific mapping */
+#define ONIGENC_CASE_ASCII_ONLY                 (1<<22) /* only modify ASCII range */
+#define ONIGENC_CASE_IS_TITLECASE               (1<<23) /* character itself is already titlecase */
+
+#define INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR   (1<<30) /* better not change original value! */
+
+#define ONIGENC_CASE_FOLD_MIN      INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR
+#define ONIGENC_CASE_FOLD_DEFAULT  OnigDefaultCaseFoldFlag
+
+
+#define ONIGENC_MAX_COMP_CASE_FOLD_CODE_LEN       3
+#define ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM      13
+/* 13 => Unicode:0x1ffc */
+
+/* code range */
+#define ONIGENC_CODE_RANGE_NUM(range)     ((int )range[0])
+#define ONIGENC_CODE_RANGE_FROM(range,i)  range[((i)*2) + 1]
+#define ONIGENC_CODE_RANGE_TO(range,i)    range[((i)*2) + 2]
+
+typedef struct {
+  int byte_len;  /* argument(original) character(s) byte length */
+  int code_len;  /* number of code */
+  OnigCodePoint code[ONIGENC_MAX_COMP_CASE_FOLD_CODE_LEN];
+} OnigCaseFoldCodeItem;
+
+typedef struct {
+  OnigCodePoint esc;
+  OnigCodePoint anychar;
+  OnigCodePoint anytime;
+  OnigCodePoint zero_or_one_time;
+  OnigCodePoint one_or_more_time;
+  OnigCodePoint anychar_anytime;
+} OnigMetaCharTableType;
+
+typedef int (*OnigApplyAllCaseFoldFunc)(OnigCodePoint from, OnigCodePoint* to, int to_len, void* arg);
+
+typedef struct OnigEncodingTypeST {
+  int    (*precise_mbc_enc_len)(const OnigUChar* p,const OnigUChar* e, const struct OnigEncodingTypeST* enc);
+  const char*   name;
+  int           max_enc_len;
+  int           min_enc_len;
+  int    (*is_mbc_newline)(const OnigUChar* p, const OnigUChar* end, const struct OnigEncodingTypeST* enc);
+  OnigCodePoint (*mbc_to_code)(const OnigUChar* p, const OnigUChar* end, const struct OnigEncodingTypeST* enc);
+  int    (*code_to_mbclen)(OnigCodePoint code, const struct OnigEncodingTypeST* enc);
+  int    (*code_to_mbc)(OnigCodePoint code, OnigUChar *buf, const struct OnigEncodingTypeST* enc);
+  int    (*mbc_case_fold)(OnigCaseFoldType flag, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to, const struct OnigEncodingTypeST* enc);
+  int    (*apply_all_case_fold)(OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg, const struct OnigEncodingTypeST* enc);
+  int    (*get_case_fold_codes_by_str)(OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem acs[], const struct OnigEncodingTypeST* enc);
+  int    (*property_name_to_ctype)(const struct OnigEncodingTypeST* enc, const OnigUChar* p, const OnigUChar* end);
+  int    (*is_code_ctype)(OnigCodePoint code, OnigCtype ctype, const struct OnigEncodingTypeST* enc);
+  int    (*get_ctype_code_range)(OnigCtype ctype, OnigCodePoint* sb_out, const OnigCodePoint* ranges[], const struct OnigEncodingTypeST* enc);
+  OnigUChar* (*left_adjust_char_head)(const OnigUChar* start, const OnigUChar* p, const OnigUChar* end, const struct OnigEncodingTypeST* enc);
+  int    (*is_allowed_reverse_match)(const OnigUChar* p, const OnigUChar* end, const struct OnigEncodingTypeST* enc);
+  int    (*case_map)(OnigCaseFoldType* flagP, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to, OnigUChar* to_end, const struct OnigEncodingTypeST* enc);
+  int ruby_encoding_index;
+  unsigned int  flags;
+} OnigEncodingType;
+
+typedef const OnigEncodingType* OnigEncoding;
+
+ONIG_EXTERN const OnigEncodingType OnigEncodingASCII;
+#ifndef RUBY
+ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_1;
+ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_2;
+ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_3;
+ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_4;
+ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_5;
+ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_6;
+ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_7;
+ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_8;
+ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_9;
+ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_10;
+ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_11;
+ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_13;
+ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_14;
+ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_15;
+ONIG_EXTERN const OnigEncodingType OnigEncodingISO_8859_16;
+ONIG_EXTERN const OnigEncodingType OnigEncodingUTF_8;
+ONIG_EXTERN const OnigEncodingType OnigEncodingUTF_16BE;
+ONIG_EXTERN const OnigEncodingType OnigEncodingUTF_16LE;
+ONIG_EXTERN const OnigEncodingType OnigEncodingUTF_32BE;
+ONIG_EXTERN const OnigEncodingType OnigEncodingUTF_32LE;
+ONIG_EXTERN const OnigEncodingType OnigEncodingEUC_JP;
+ONIG_EXTERN const OnigEncodingType OnigEncodingEUC_TW;
+ONIG_EXTERN const OnigEncodingType OnigEncodingEUC_KR;
+ONIG_EXTERN const OnigEncodingType OnigEncodingEUC_CN;
+ONIG_EXTERN const OnigEncodingType OnigEncodingShift_JIS;
+ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_31J;
+/* ONIG_EXTERN const OnigEncodingType OnigEncodingKOI8; */
+ONIG_EXTERN const OnigEncodingType OnigEncodingKOI8_R;
+ONIG_EXTERN const OnigEncodingType OnigEncodingKOI8_U;
+ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_1250;
+ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_1251;
+ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_1252;
+ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_1253;
+ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_1254;
+ONIG_EXTERN const OnigEncodingType OnigEncodingWindows_1257;
+ONIG_EXTERN const OnigEncodingType OnigEncodingBIG5;
+ONIG_EXTERN const OnigEncodingType OnigEncodingGB18030;
+#endif /* RUBY */
+
+#define ONIG_ENCODING_ASCII        (&OnigEncodingASCII)
+#ifndef RUBY
+# define ONIG_ENCODING_ISO_8859_1   (&OnigEncodingISO_8859_1)
+# define ONIG_ENCODING_ISO_8859_2   (&OnigEncodingISO_8859_2)
+# define ONIG_ENCODING_ISO_8859_3   (&OnigEncodingISO_8859_3)
+# define ONIG_ENCODING_ISO_8859_4   (&OnigEncodingISO_8859_4)
+# define ONIG_ENCODING_ISO_8859_5   (&OnigEncodingISO_8859_5)
+# define ONIG_ENCODING_ISO_8859_6   (&OnigEncodingISO_8859_6)
+# define ONIG_ENCODING_ISO_8859_7   (&OnigEncodingISO_8859_7)
+# define ONIG_ENCODING_ISO_8859_8   (&OnigEncodingISO_8859_8)
+# define ONIG_ENCODING_ISO_8859_9   (&OnigEncodingISO_8859_9)
+# define ONIG_ENCODING_ISO_8859_10  (&OnigEncodingISO_8859_10)
+# define ONIG_ENCODING_ISO_8859_11  (&OnigEncodingISO_8859_11)
+# define ONIG_ENCODING_ISO_8859_13  (&OnigEncodingISO_8859_13)
+# define ONIG_ENCODING_ISO_8859_14  (&OnigEncodingISO_8859_14)
+# define ONIG_ENCODING_ISO_8859_15  (&OnigEncodingISO_8859_15)
+# define ONIG_ENCODING_ISO_8859_16  (&OnigEncodingISO_8859_16)
+# define ONIG_ENCODING_UTF_8        (&OnigEncodingUTF_8)
+# define ONIG_ENCODING_UTF_16BE     (&OnigEncodingUTF_16BE)
+# define ONIG_ENCODING_UTF_16LE     (&OnigEncodingUTF_16LE)
+# define ONIG_ENCODING_UTF_32BE     (&OnigEncodingUTF_32BE)
+# define ONIG_ENCODING_UTF_32LE     (&OnigEncodingUTF_32LE)
+# define ONIG_ENCODING_EUC_JP       (&OnigEncodingEUC_JP)
+# define ONIG_ENCODING_EUC_TW       (&OnigEncodingEUC_TW)
+# define ONIG_ENCODING_EUC_KR       (&OnigEncodingEUC_KR)
+# define ONIG_ENCODING_EUC_CN       (&OnigEncodingEUC_CN)
+# define ONIG_ENCODING_SHIFT_JIS    (&OnigEncodingShift_JIS)
+# define ONIG_ENCODING_WINDOWS_31J  (&OnigEncodingWindows_31J)
+/* # define ONIG_ENCODING_KOI8         (&OnigEncodingKOI8) */
+# define ONIG_ENCODING_KOI8_R       (&OnigEncodingKOI8_R)
+# define ONIG_ENCODING_KOI8_U       (&OnigEncodingKOI8_U)
+# define ONIG_ENCODING_WINDOWS_1250 (&OnigEncodingWindows_1250)
+# define ONIG_ENCODING_WINDOWS_1251 (&OnigEncodingWindows_1251)
+# define ONIG_ENCODING_WINDOWS_1252 (&OnigEncodingWindows_1252)
+# define ONIG_ENCODING_WINDOWS_1253 (&OnigEncodingWindows_1253)
+# define ONIG_ENCODING_WINDOWS_1254 (&OnigEncodingWindows_1254)
+# define ONIG_ENCODING_WINDOWS_1257 (&OnigEncodingWindows_1257)
+# define ONIG_ENCODING_BIG5         (&OnigEncodingBIG5)
+# define ONIG_ENCODING_GB18030      (&OnigEncodingGB18030)
+
+/* old names */
+# define ONIG_ENCODING_SJIS         ONIG_ENCODING_SHIFT_JIS
+# define ONIG_ENCODING_CP932        ONIG_ENCODING_WINDOWS_31J
+# define ONIG_ENCODING_CP1250       ONIG_ENCODING_WINDOWS_1250
+# define ONIG_ENCODING_CP1251       ONIG_ENCODING_WINDOWS_1251
+# define ONIG_ENCODING_CP1252       ONIG_ENCODING_WINDOWS_1252
+# define ONIG_ENCODING_CP1253       ONIG_ENCODING_WINDOWS_1253
+# define ONIG_ENCODING_CP1254       ONIG_ENCODING_WINDOWS_1254
+# define ONIG_ENCODING_CP1257       ONIG_ENCODING_WINDOWS_1257
+# define ONIG_ENCODING_UTF8         ONIG_ENCODING_UTF_8
+# define ONIG_ENCODING_UTF16_BE     ONIG_ENCODING_UTF_16BE
+# define ONIG_ENCODING_UTF16_LE     ONIG_ENCODING_UTF_16LE
+# define ONIG_ENCODING_UTF32_BE     ONIG_ENCODING_UTF_32BE
+# define ONIG_ENCODING_UTF32_LE     ONIG_ENCODING_UTF_32LE
+#endif /* RUBY */
+
+#define ONIG_ENCODING_UNDEF    ((OnigEncoding )0)
+
+/* this declaration needs to be here because it is used in string.c in Ruby */
+ONIG_EXTERN
+int onigenc_ascii_only_case_map(OnigCaseFoldType* flagP, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to, OnigUChar* to_end, const struct OnigEncodingTypeST* enc);
+
+
+/* work size */
+#define ONIGENC_CODE_TO_MBC_MAXLEN       7
+#define ONIGENC_MBC_CASE_FOLD_MAXLEN    18
+/* 18: 6(max-byte) * 3(case-fold chars) */
+
+/* character types */
+#define ONIGENC_CTYPE_NEWLINE   0
+#define ONIGENC_CTYPE_ALPHA     1
+#define ONIGENC_CTYPE_BLANK     2
+#define ONIGENC_CTYPE_CNTRL     3
+#define ONIGENC_CTYPE_DIGIT     4
+#define ONIGENC_CTYPE_GRAPH     5
+#define ONIGENC_CTYPE_LOWER     6
+#define ONIGENC_CTYPE_PRINT     7
+#define ONIGENC_CTYPE_PUNCT     8
+#define ONIGENC_CTYPE_SPACE     9
+#define ONIGENC_CTYPE_UPPER    10
+#define ONIGENC_CTYPE_XDIGIT   11
+#define ONIGENC_CTYPE_WORD     12
+#define ONIGENC_CTYPE_ALNUM    13  /* alpha || digit */
+#define ONIGENC_CTYPE_ASCII    14
+#define ONIGENC_MAX_STD_CTYPE  ONIGENC_CTYPE_ASCII
+
+/* flags */
+#define ONIGENC_FLAG_NONE       0U
+#define ONIGENC_FLAG_UNICODE    1U
+
+#define onig_enc_len(enc,p,e)          ONIGENC_MBC_ENC_LEN(enc, p, e)
+
+#define ONIGENC_IS_UNDEF(enc)          ((enc) == ONIG_ENCODING_UNDEF)
+#define ONIGENC_IS_SINGLEBYTE(enc)     (ONIGENC_MBC_MAXLEN(enc) == 1)
+#define ONIGENC_IS_MBC_HEAD(enc,p,e)   (ONIGENC_MBC_ENC_LEN(enc,p,e) != 1)
+#define ONIGENC_IS_MBC_ASCII(p)           (*(p)   < 128)
+#define ONIGENC_IS_CODE_ASCII(code)       ((code) < 128)
+#define ONIGENC_IS_MBC_WORD(enc,s,end) \
+   ONIGENC_IS_CODE_WORD(enc,ONIGENC_MBC_TO_CODE(enc,s,end))
+#define ONIGENC_IS_MBC_ASCII_WORD(enc,s,end) \
+   onigenc_ascii_is_code_ctype( \
+	ONIGENC_MBC_TO_CODE(enc,s,end),ONIGENC_CTYPE_WORD,enc)
+#define ONIGENC_IS_UNICODE(enc)        ((enc)->flags & ONIGENC_FLAG_UNICODE)
+
+
+#define ONIGENC_NAME(enc)                      ((enc)->name)
+
+#define ONIGENC_MBC_CASE_FOLD(enc,flag,pp,end,buf) \
+  (enc)->mbc_case_fold(flag,(const OnigUChar** )pp,end,buf,enc)
+#define ONIGENC_IS_ALLOWED_REVERSE_MATCH(enc,s,end) \
+        (enc)->is_allowed_reverse_match(s,end,enc)
+#define ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc,start,s,end) \
+        (enc)->left_adjust_char_head(start, s, end, enc)
+#define ONIGENC_APPLY_ALL_CASE_FOLD(enc,case_fold_flag,f,arg) \
+        (enc)->apply_all_case_fold(case_fold_flag,f,arg,enc)
+#define ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc,case_fold_flag,p,end,acs) \
+       (enc)->get_case_fold_codes_by_str(case_fold_flag,p,end,acs,enc)
+#define ONIGENC_STEP_BACK(enc,start,s,end,n) \
+        onigenc_step_back((enc),(start),(s),(end),(n))
+
+#define ONIGENC_CONSTRUCT_MBCLEN_CHARFOUND(n)   (n)
+#define ONIGENC_MBCLEN_CHARFOUND_P(r)           (0 < (r))
+#define ONIGENC_MBCLEN_CHARFOUND_LEN(r)         (r)
+
+#define ONIGENC_CONSTRUCT_MBCLEN_INVALID()      (-1)
+#define ONIGENC_MBCLEN_INVALID_P(r)             ((r) == -1)
+
+#define ONIGENC_CONSTRUCT_MBCLEN_NEEDMORE(n)    (-1-(n))
+#define ONIGENC_MBCLEN_NEEDMORE_P(r)            ((r) < -1)
+#define ONIGENC_MBCLEN_NEEDMORE_LEN(r)          (-1-(r))
+
+#define ONIGENC_PRECISE_MBC_ENC_LEN(enc,p,e)   (enc)->precise_mbc_enc_len(p,e,enc)
+
+ONIG_EXTERN
+int onigenc_mbclen_approximate(const OnigUChar* p,const OnigUChar* e, const struct OnigEncodingTypeST* enc);
+
+#define ONIGENC_MBC_ENC_LEN(enc,p,e)           onigenc_mbclen_approximate(p,e,enc)
+#define ONIGENC_MBC_MAXLEN(enc)               ((enc)->max_enc_len)
+#define ONIGENC_MBC_MAXLEN_DIST(enc)           ONIGENC_MBC_MAXLEN(enc)
+#define ONIGENC_MBC_MINLEN(enc)               ((enc)->min_enc_len)
+#define ONIGENC_IS_MBC_NEWLINE(enc,p,end)      (enc)->is_mbc_newline((p),(end),enc)
+#define ONIGENC_MBC_TO_CODE(enc,p,end)         (enc)->mbc_to_code((p),(end),enc)
+#define ONIGENC_CODE_TO_MBCLEN(enc,code)       (enc)->code_to_mbclen(code,enc)
+#define ONIGENC_CODE_TO_MBC(enc,code,buf)      (enc)->code_to_mbc(code,buf,enc)
+#define ONIGENC_PROPERTY_NAME_TO_CTYPE(enc,p,end) \
+  (enc)->property_name_to_ctype(enc,p,end)
+
+#define ONIGENC_IS_CODE_CTYPE(enc,code,ctype)  (enc)->is_code_ctype(code,ctype,enc)
+
+#define ONIGENC_IS_CODE_NEWLINE(enc,code) \
+        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_NEWLINE)
+#define ONIGENC_IS_CODE_GRAPH(enc,code) \
+        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_GRAPH)
+#define ONIGENC_IS_CODE_PRINT(enc,code) \
+        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_PRINT)
+#define ONIGENC_IS_CODE_ALNUM(enc,code) \
+        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_ALNUM)
+#define ONIGENC_IS_CODE_ALPHA(enc,code) \
+        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_ALPHA)
+#define ONIGENC_IS_CODE_LOWER(enc,code) \
+        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_LOWER)
+#define ONIGENC_IS_CODE_UPPER(enc,code) \
+        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_UPPER)
+#define ONIGENC_IS_CODE_CNTRL(enc,code) \
+        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_CNTRL)
+#define ONIGENC_IS_CODE_PUNCT(enc,code) \
+        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_PUNCT)
+#define ONIGENC_IS_CODE_SPACE(enc,code) \
+        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_SPACE)
+#define ONIGENC_IS_CODE_BLANK(enc,code) \
+        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_BLANK)
+#define ONIGENC_IS_CODE_DIGIT(enc,code) \
+        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_DIGIT)
+#define ONIGENC_IS_CODE_XDIGIT(enc,code) \
+        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_XDIGIT)
+#define ONIGENC_IS_CODE_WORD(enc,code) \
+        ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_WORD)
+
+#define ONIGENC_GET_CTYPE_CODE_RANGE(enc,ctype,sbout,ranges) \
+        (enc)->get_ctype_code_range(ctype,sbout,ranges,enc)
+
+ONIG_EXTERN
+OnigUChar* onigenc_step_back(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end, int n);
+
+
+/* encoding API */
+ONIG_EXTERN
+int onigenc_init(void);
+ONIG_EXTERN
+int onigenc_set_default_encoding(OnigEncoding enc);
+ONIG_EXTERN
+OnigEncoding onigenc_get_default_encoding(void);
+ONIG_EXTERN
+OnigUChar* onigenc_get_right_adjust_char_head_with_prev(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end, const OnigUChar** prev);
+ONIG_EXTERN
+OnigUChar* onigenc_get_prev_char_head(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end);
+ONIG_EXTERN
+OnigUChar* onigenc_get_left_adjust_char_head(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end);
+ONIG_EXTERN
+OnigUChar* onigenc_get_right_adjust_char_head(OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, const OnigUChar* end);
+ONIG_EXTERN
+int onigenc_strlen(OnigEncoding enc, const OnigUChar* p, const OnigUChar* end);
+ONIG_EXTERN
+int onigenc_strlen_null(OnigEncoding enc, const OnigUChar* p);
+ONIG_EXTERN
+int onigenc_str_bytelen_null(OnigEncoding enc, const OnigUChar* p);
+
+
+
+/* PART: regular expression */
+
+/* config parameters */
+#define ONIG_NREGION                          10
+#define ONIG_MAX_CAPTURE_GROUP_NUM         32767
+#define ONIG_MAX_BACKREF_NUM                1000
+#define ONIG_MAX_REPEAT_NUM               100000
+#define ONIG_MAX_MULTI_BYTE_RANGES_NUM     10000
+/* constants */
+#define ONIG_MAX_ERROR_MESSAGE_LEN            90
+
+typedef unsigned int        OnigOptionType;
+
+#define ONIG_OPTION_DEFAULT            ONIG_OPTION_NONE
+
+/* options */
+#define ONIG_OPTION_NONE                 0U
+#define ONIG_OPTION_IGNORECASE           1U
+#define ONIG_OPTION_EXTEND               (ONIG_OPTION_IGNORECASE         << 1)
+#define ONIG_OPTION_MULTILINE            (ONIG_OPTION_EXTEND             << 1)
+#define ONIG_OPTION_DOTALL                ONIG_OPTION_MULTILINE
+#define ONIG_OPTION_SINGLELINE           (ONIG_OPTION_MULTILINE          << 1)
+#define ONIG_OPTION_FIND_LONGEST         (ONIG_OPTION_SINGLELINE         << 1)
+#define ONIG_OPTION_FIND_NOT_EMPTY       (ONIG_OPTION_FIND_LONGEST       << 1)
+#define ONIG_OPTION_NEGATE_SINGLELINE    (ONIG_OPTION_FIND_NOT_EMPTY     << 1)
+#define ONIG_OPTION_DONT_CAPTURE_GROUP   (ONIG_OPTION_NEGATE_SINGLELINE  << 1)
+#define ONIG_OPTION_CAPTURE_GROUP        (ONIG_OPTION_DONT_CAPTURE_GROUP << 1)
+/* options (search time) */
+#define ONIG_OPTION_NOTBOL               (ONIG_OPTION_CAPTURE_GROUP << 1)
+#define ONIG_OPTION_NOTEOL               (ONIG_OPTION_NOTBOL << 1)
+#define ONIG_OPTION_NOTBOS               (ONIG_OPTION_NOTEOL << 1)
+#define ONIG_OPTION_NOTEOS               (ONIG_OPTION_NOTBOS << 1)
+/* options (ctype range) */
+#define ONIG_OPTION_ASCII_RANGE          (ONIG_OPTION_NOTEOS << 1)
+#define ONIG_OPTION_POSIX_BRACKET_ALL_RANGE (ONIG_OPTION_ASCII_RANGE << 1)
+#define ONIG_OPTION_WORD_BOUND_ALL_RANGE    (ONIG_OPTION_POSIX_BRACKET_ALL_RANGE << 1)
+/* options (newline) */
+#define ONIG_OPTION_NEWLINE_CRLF         (ONIG_OPTION_WORD_BOUND_ALL_RANGE << 1)
+#define ONIG_OPTION_MAXBIT               ONIG_OPTION_NEWLINE_CRLF  /* limit */
+
+#define ONIG_OPTION_ON(options,regopt)      ((options) |= (regopt))
+#define ONIG_OPTION_OFF(options,regopt)     ((options) &= ~(regopt))
+#define ONIG_IS_OPTION_ON(options,option)   ((options) & (option))
+
+/* syntax */
+typedef struct {
+  unsigned int   op;
+  unsigned int   op2;
+  unsigned int   behavior;
+  OnigOptionType options;   /* default option */
+  OnigMetaCharTableType meta_char_table;
+} OnigSyntaxType;
+
+ONIG_EXTERN const OnigSyntaxType OnigSyntaxASIS;
+ONIG_EXTERN const OnigSyntaxType OnigSyntaxPosixBasic;
+ONIG_EXTERN const OnigSyntaxType OnigSyntaxPosixExtended;
+ONIG_EXTERN const OnigSyntaxType OnigSyntaxEmacs;
+ONIG_EXTERN const OnigSyntaxType OnigSyntaxGrep;
+ONIG_EXTERN const OnigSyntaxType OnigSyntaxGnuRegex;
+ONIG_EXTERN const OnigSyntaxType OnigSyntaxJava;
+ONIG_EXTERN const OnigSyntaxType OnigSyntaxPerl58;
+ONIG_EXTERN const OnigSyntaxType OnigSyntaxPerl58_NG;
+ONIG_EXTERN const OnigSyntaxType OnigSyntaxPerl;
+ONIG_EXTERN const OnigSyntaxType OnigSyntaxRuby;
+ONIG_EXTERN const OnigSyntaxType OnigSyntaxPython;
+
+/* predefined syntaxes (see regsyntax.c) */
+#define ONIG_SYNTAX_ASIS               (&OnigSyntaxASIS)
+#define ONIG_SYNTAX_POSIX_BASIC        (&OnigSyntaxPosixBasic)
+#define ONIG_SYNTAX_POSIX_EXTENDED     (&OnigSyntaxPosixExtended)
+#define ONIG_SYNTAX_EMACS              (&OnigSyntaxEmacs)
+#define ONIG_SYNTAX_GREP               (&OnigSyntaxGrep)
+#define ONIG_SYNTAX_GNU_REGEX          (&OnigSyntaxGnuRegex)
+#define ONIG_SYNTAX_JAVA               (&OnigSyntaxJava)
+#define ONIG_SYNTAX_PERL58             (&OnigSyntaxPerl58)
+#define ONIG_SYNTAX_PERL58_NG          (&OnigSyntaxPerl58_NG)
+#define ONIG_SYNTAX_PERL               (&OnigSyntaxPerl)
+#define ONIG_SYNTAX_RUBY               (&OnigSyntaxRuby)
+#define ONIG_SYNTAX_PYTHON             (&OnigSyntaxPython)
+
+/* default syntax */
+ONIG_EXTERN const OnigSyntaxType*   OnigDefaultSyntax;
+#define ONIG_SYNTAX_DEFAULT   OnigDefaultSyntax
+
+/* syntax (operators) */
+#define ONIG_SYN_OP_VARIABLE_META_CHARACTERS    (1U<<0)
+#define ONIG_SYN_OP_DOT_ANYCHAR                 (1U<<1)   /* . */
+#define ONIG_SYN_OP_ASTERISK_ZERO_INF           (1U<<2)   /* * */
+#define ONIG_SYN_OP_ESC_ASTERISK_ZERO_INF       (1U<<3)
+#define ONIG_SYN_OP_PLUS_ONE_INF                (1U<<4)   /* + */
+#define ONIG_SYN_OP_ESC_PLUS_ONE_INF            (1U<<5)
+#define ONIG_SYN_OP_QMARK_ZERO_ONE              (1U<<6)   /* ? */
+#define ONIG_SYN_OP_ESC_QMARK_ZERO_ONE          (1U<<7)
+#define ONIG_SYN_OP_BRACE_INTERVAL              (1U<<8)   /* {lower,upper} */
+#define ONIG_SYN_OP_ESC_BRACE_INTERVAL          (1U<<9)   /* \{lower,upper\} */
+#define ONIG_SYN_OP_VBAR_ALT                    (1U<<10)   /* | */
+#define ONIG_SYN_OP_ESC_VBAR_ALT                (1U<<11)  /* \| */
+#define ONIG_SYN_OP_LPAREN_SUBEXP               (1U<<12)  /* (...)   */
+#define ONIG_SYN_OP_ESC_LPAREN_SUBEXP           (1U<<13)  /* \(...\) */
+#define ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR           (1U<<14)  /* \A, \Z, \z */
+#define ONIG_SYN_OP_ESC_CAPITAL_G_BEGIN_ANCHOR  (1U<<15)  /* \G     */
+#define ONIG_SYN_OP_DECIMAL_BACKREF             (1U<<16)  /* \num   */
+#define ONIG_SYN_OP_BRACKET_CC                  (1U<<17)  /* [...]  */
+#define ONIG_SYN_OP_ESC_W_WORD                  (1U<<18)  /* \w, \W */
+#define ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END     (1U<<19)  /* \<. \> */
+#define ONIG_SYN_OP_ESC_B_WORD_BOUND            (1U<<20)  /* \b, \B */
+#define ONIG_SYN_OP_ESC_S_WHITE_SPACE           (1U<<21)  /* \s, \S */
+#define ONIG_SYN_OP_ESC_D_DIGIT                 (1U<<22)  /* \d, \D */
+#define ONIG_SYN_OP_LINE_ANCHOR                 (1U<<23)  /* ^, $   */
+#define ONIG_SYN_OP_POSIX_BRACKET               (1U<<24)  /* [:xxxx:] */
+#define ONIG_SYN_OP_QMARK_NON_GREEDY            (1U<<25)  /* ??,*?,+?,{n,m}? */
+#define ONIG_SYN_OP_ESC_CONTROL_CHARS           (1U<<26)  /* \n,\r,\t,\a ... */
+#define ONIG_SYN_OP_ESC_C_CONTROL               (1U<<27)  /* \cx  */
+#define ONIG_SYN_OP_ESC_OCTAL3                  (1U<<28)  /* \OOO */
+#define ONIG_SYN_OP_ESC_X_HEX2                  (1U<<29)  /* \xHH */
+#define ONIG_SYN_OP_ESC_X_BRACE_HEX8            (1U<<30)  /* \x{7HHHHHHH} */
+#define ONIG_SYN_OP_ESC_O_BRACE_OCTAL           (1U<<31)  /* \o{OOO} */
+
+#define ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE        (1U<<0)  /* \Q...\E */
+#define ONIG_SYN_OP2_QMARK_GROUP_EFFECT         (1U<<1)  /* (?...) */
+#define ONIG_SYN_OP2_OPTION_PERL                (1U<<2)  /* (?imsxadlu), (?-imsx), (?^imsxalu) */
+#define ONIG_SYN_OP2_OPTION_RUBY                (1U<<3)  /* (?imxadu), (?-imx)  */
+#define ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT     (1U<<4)  /* ?+,*+,++ */
+#define ONIG_SYN_OP2_PLUS_POSSESSIVE_INTERVAL   (1U<<5)  /* {n,m}+   */
+#define ONIG_SYN_OP2_CCLASS_SET_OP              (1U<<6)  /* [...&&..[..]..] */
+#define ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP       (1U<<7)  /* (?<name>...) */
+#define ONIG_SYN_OP2_ESC_K_NAMED_BACKREF        (1U<<8)  /* \k<name> */
+#define ONIG_SYN_OP2_ESC_G_SUBEXP_CALL          (1U<<9)  /* \g<name>, \g<n> */
+#define ONIG_SYN_OP2_ATMARK_CAPTURE_HISTORY     (1U<<10) /* (?@..),(?@<x>..) */
+#define ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL  (1U<<11) /* \C-x */
+#define ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META     (1U<<12) /* \M-x */
+#define ONIG_SYN_OP2_ESC_V_VTAB                 (1U<<13) /* \v as VTAB */
+#define ONIG_SYN_OP2_ESC_U_HEX4                 (1U<<14) /* \uHHHH */
+#define ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR         (1U<<15) /* \`, \' */
+#define ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY  (1U<<16) /* \p{...}, \P{...} */
+#define ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT (1U<<17) /* \p{^..}, \P{^..} */
+/* #define ONIG_SYN_OP2_CHAR_PROPERTY_PREFIX_IS (1U<<18) */
+#define ONIG_SYN_OP2_ESC_H_XDIGIT               (1U<<19) /* \h, \H */
+#define ONIG_SYN_OP2_INEFFECTIVE_ESCAPE         (1U<<20) /* \ */
+#define ONIG_SYN_OP2_ESC_CAPITAL_R_LINEBREAK    (1U<<21) /* \R as (?>\x0D\x0A|[\x0A-\x0D\x{85}\x{2028}\x{2029}]) */
+#define ONIG_SYN_OP2_ESC_CAPITAL_X_EXTENDED_GRAPHEME_CLUSTER (1U<<22) /* \X */
+#define ONIG_SYN_OP2_ESC_V_VERTICAL_WHITESPACE   (1U<<23) /* \v, \V -- Perl */ /* NOTIMPL */
+#define ONIG_SYN_OP2_ESC_H_HORIZONTAL_WHITESPACE (1U<<24) /* \h, \H -- Perl */ /* NOTIMPL */
+#define ONIG_SYN_OP2_ESC_CAPITAL_K_KEEP         (1U<<25) /* \K */
+#define ONIG_SYN_OP2_ESC_G_BRACE_BACKREF        (1U<<26) /* \g{name}, \g{n} */
+#define ONIG_SYN_OP2_QMARK_SUBEXP_CALL          (1U<<27) /* (?&name), (?n), (?R), (?0) */
+#define ONIG_SYN_OP2_QMARK_VBAR_BRANCH_RESET    (1U<<28) /* (?|...) */         /* NOTIMPL */
+#define ONIG_SYN_OP2_QMARK_LPAREN_CONDITION     (1U<<29) /* (?(cond)yes...|no...) */
+#define ONIG_SYN_OP2_QMARK_CAPITAL_P_NAMED_GROUP (1U<<30) /* (?P<name>...), (?P=name), (?P>name) -- Python/PCRE */
+#define ONIG_SYN_OP2_QMARK_TILDE_ABSENT         (1U<<31) /* (?~...) */
+/* #define ONIG_SYN_OP2_OPTION_JAVA                (1U<<xx) */ /* (?idmsux), (?-idmsux) */ /* NOTIMPL */
+
+/* syntax (behavior) */
+#define ONIG_SYN_CONTEXT_INDEP_ANCHORS           (1U<<31) /* not implemented */
+#define ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS        (1U<<0)  /* ?, *, +, {n,m} */
+#define ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS      (1U<<1)  /* error or ignore */
+#define ONIG_SYN_ALLOW_UNMATCHED_CLOSE_SUBEXP    (1U<<2)  /* ...)... */
+#define ONIG_SYN_ALLOW_INVALID_INTERVAL          (1U<<3)  /* {??? */
+#define ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV       (1U<<4)  /* {,n} => {0,n} */
+#define ONIG_SYN_STRICT_CHECK_BACKREF            (1U<<5)  /* /(\1)/,/\1()/ ..*/
+#define ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND   (1U<<6)  /* (?<=a|bc) */
+#define ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP        (1U<<7)  /* see doc/RE */
+#define ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME (1U<<8)  /* (?<x>)(?<x>) */
+#define ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY   (1U<<9)  /* a{n}?=(?:a{n})? */
+#define ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME_CALL (1U<<10)  /* (?<x>)(?<x>)(?&x) */
+#define ONIG_SYN_USE_LEFT_MOST_NAMED_GROUP       (1U<<11) /* (?<x>)(?<x>)\k<x> */
+
+/* syntax (behavior) in char class [...] */
+#define ONIG_SYN_NOT_NEWLINE_IN_NEGATIVE_CC      (1U<<20) /* [^...] */
+#define ONIG_SYN_BACKSLASH_ESCAPE_IN_CC          (1U<<21) /* [..\w..] etc.. */
+#define ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC         (1U<<22)
+#define ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC     (1U<<23) /* [0-9-a]=[0-9\-a] */
+/* syntax (behavior) warning */
+#define ONIG_SYN_WARN_CC_OP_NOT_ESCAPED          (1U<<24) /* [,-,] */
+#define ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT    (1U<<25) /* (?:a*)+ */
+#define ONIG_SYN_WARN_CC_DUP                     (1U<<26) /* [aa] */
+
+/* meta character specifiers (onig_set_meta_char()) */
+#define ONIG_META_CHAR_ESCAPE               0
+#define ONIG_META_CHAR_ANYCHAR              1
+#define ONIG_META_CHAR_ANYTIME              2
+#define ONIG_META_CHAR_ZERO_OR_ONE_TIME     3
+#define ONIG_META_CHAR_ONE_OR_MORE_TIME     4
+#define ONIG_META_CHAR_ANYCHAR_ANYTIME      5
+
+#define ONIG_INEFFECTIVE_META_CHAR          0
+
+/* error codes */
+#define ONIG_IS_PATTERN_ERROR(ecode)   ((ecode) <= -100 && (ecode) > -1000)
+/* normal return */
+#define ONIG_NORMAL                                            0
+#define ONIG_MISMATCH                                         -1
+#define ONIG_NO_SUPPORT_CONFIG                                -2
+
+/* internal error */
+#define ONIGERR_MEMORY                                         -5
+#define ONIGERR_TYPE_BUG                                       -6
+#define ONIGERR_PARSER_BUG                                    -11
+#define ONIGERR_STACK_BUG                                     -12
+#define ONIGERR_UNDEFINED_BYTECODE                            -13
+#define ONIGERR_UNEXPECTED_BYTECODE                           -14
+#define ONIGERR_MATCH_STACK_LIMIT_OVER                        -15
+#define ONIGERR_PARSE_DEPTH_LIMIT_OVER                        -16
+#define ONIGERR_DEFAULT_ENCODING_IS_NOT_SET                   -21
+#define ONIGERR_SPECIFIED_ENCODING_CANT_CONVERT_TO_WIDE_CHAR  -22
+/* general error */
+#define ONIGERR_INVALID_ARGUMENT                              -30
+/* syntax error */
+#define ONIGERR_END_PATTERN_AT_LEFT_BRACE                    -100
+#define ONIGERR_END_PATTERN_AT_LEFT_BRACKET                  -101
+#define ONIGERR_EMPTY_CHAR_CLASS                             -102
+#define ONIGERR_PREMATURE_END_OF_CHAR_CLASS                  -103
+#define ONIGERR_END_PATTERN_AT_ESCAPE                        -104
+#define ONIGERR_END_PATTERN_AT_META                          -105
+#define ONIGERR_END_PATTERN_AT_CONTROL                       -106
+#define ONIGERR_META_CODE_SYNTAX                             -108
+#define ONIGERR_CONTROL_CODE_SYNTAX                          -109
+#define ONIGERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE             -110
+#define ONIGERR_CHAR_CLASS_VALUE_AT_START_OF_RANGE           -111
+#define ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS      -112
+#define ONIGERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED      -113
+#define ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID            -114
+#define ONIGERR_NESTED_REPEAT_OPERATOR                       -115
+#define ONIGERR_UNMATCHED_CLOSE_PARENTHESIS                  -116
+#define ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS       -117
+#define ONIGERR_END_PATTERN_IN_GROUP                         -118
+#define ONIGERR_UNDEFINED_GROUP_OPTION                       -119
+#define ONIGERR_INVALID_POSIX_BRACKET_TYPE                   -121
+#define ONIGERR_INVALID_LOOK_BEHIND_PATTERN                  -122
+#define ONIGERR_INVALID_REPEAT_RANGE_PATTERN                 -123
+#define ONIGERR_INVALID_CONDITION_PATTERN                    -124
+/* values error (syntax error) */
+#define ONIGERR_TOO_BIG_NUMBER                               -200
+#define ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE              -201
+#define ONIGERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE     -202
+#define ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS                    -203
+#define ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE          -204
+#define ONIGERR_TOO_MANY_MULTI_BYTE_RANGES                   -205
+#define ONIGERR_TOO_SHORT_MULTI_BYTE_STRING                  -206
+#define ONIGERR_TOO_BIG_BACKREF_NUMBER                       -207
+#define ONIGERR_INVALID_BACKREF                              -208
+#define ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED         -209
+#define ONIGERR_TOO_MANY_CAPTURE_GROUPS                      -210
+#define ONIGERR_TOO_SHORT_DIGITS                             -211
+#define ONIGERR_TOO_LONG_WIDE_CHAR_VALUE                     -212
+#define ONIGERR_EMPTY_GROUP_NAME                             -214
+#define ONIGERR_INVALID_GROUP_NAME                           -215
+#define ONIGERR_INVALID_CHAR_IN_GROUP_NAME                   -216
+#define ONIGERR_UNDEFINED_NAME_REFERENCE                     -217
+#define ONIGERR_UNDEFINED_GROUP_REFERENCE                    -218
+#define ONIGERR_MULTIPLEX_DEFINED_NAME                       -219
+#define ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL               -220
+#define ONIGERR_NEVER_ENDING_RECURSION                       -221
+#define ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY        -222
+#define ONIGERR_INVALID_CHAR_PROPERTY_NAME                   -223
+#define ONIGERR_INVALID_CODE_POINT_VALUE                     -400
+#define ONIGERR_INVALID_WIDE_CHAR_VALUE                      -400
+#define ONIGERR_TOO_BIG_WIDE_CHAR_VALUE                      -401
+#define ONIGERR_NOT_SUPPORTED_ENCODING_COMBINATION           -402
+#define ONIGERR_INVALID_COMBINATION_OF_OPTIONS               -403
+
+/* errors related to thread */
+/* #define ONIGERR_OVER_THREAD_PASS_LIMIT_COUNT                -1001 */
+
+
+/* must be smaller than BIT_STATUS_BITS_NUM (unsigned int * 8) */
+#define ONIG_MAX_CAPTURE_HISTORY_GROUP   31
+#define ONIG_IS_CAPTURE_HISTORY_GROUP(r, i) \
+  ((i) <= ONIG_MAX_CAPTURE_HISTORY_GROUP && (r)->list && (r)->list[i])
+
+typedef struct OnigCaptureTreeNodeStruct {
+  int group;   /* group number */
+  OnigPosition beg;
+  OnigPosition end;
+  int allocated;
+  int num_childs;
+  struct OnigCaptureTreeNodeStruct** childs;
+} OnigCaptureTreeNode;
+
+/* match result region type */
+struct re_registers {
+  int  allocated;
+  int  num_regs;
+  OnigPosition* beg;
+  OnigPosition* end;
+  /* extended */
+  OnigCaptureTreeNode* history_root;  /* capture history tree root */
+};
+
+/* capture tree traverse */
+#define ONIG_TRAVERSE_CALLBACK_AT_FIRST   1
+#define ONIG_TRAVERSE_CALLBACK_AT_LAST    2
+#define ONIG_TRAVERSE_CALLBACK_AT_BOTH \
+  ( ONIG_TRAVERSE_CALLBACK_AT_FIRST | ONIG_TRAVERSE_CALLBACK_AT_LAST )
+
+
+#define ONIG_REGION_NOTPOS            -1
+
+typedef struct re_registers   OnigRegion;
+
+typedef struct {
+  OnigEncoding enc;
+  OnigUChar* par;
+  OnigUChar* par_end;
+} OnigErrorInfo;
+
+typedef struct {
+  int lower;
+  int upper;
+} OnigRepeatRange;
+
+typedef void (*OnigWarnFunc)(const char* s);
+extern void onig_null_warn(const char* s);
+#define ONIG_NULL_WARN       onig_null_warn
+
+#define ONIG_CHAR_TABLE_SIZE   256
+
+typedef struct re_pattern_buffer {
+  /* common members of BBuf(bytes-buffer) */
+  unsigned char* p;         /* compiled pattern */
+  unsigned int used;        /* used space for p */
+  unsigned int alloc;       /* allocated space for p */
+
+  int num_mem;                   /* used memory(...) num counted from 1 */
+  int num_repeat;                /* OP_REPEAT/OP_REPEAT_NG id-counter */
+  int num_null_check;            /* OP_NULL_CHECK_START/END id counter */
+  int num_comb_exp_check;        /* combination explosion check */
+  int num_call;                  /* number of subexp call */
+  unsigned int capture_history;  /* (?@...) flag (1-31) */
+  unsigned int bt_mem_start;     /* need backtrack flag */
+  unsigned int bt_mem_end;       /* need backtrack flag */
+  int stack_pop_level;
+  int repeat_range_alloc;
+
+  OnigOptionType    options;
+
+  OnigRepeatRange* repeat_range;
+
+  OnigEncoding      enc;
+  const OnigSyntaxType* syntax;
+  void*             name_table;
+  OnigCaseFoldType  case_fold_flag;
+
+  /* optimization info (string search, char-map and anchors) */
+  int            optimize;          /* optimize flag */
+  int            threshold_len;     /* search str-length for apply optimize */
+  int            anchor;            /* BEGIN_BUF, BEGIN_POS, (SEMI_)END_BUF */
+  OnigDistance   anchor_dmin;       /* (SEMI_)END_BUF anchor distance */
+  OnigDistance   anchor_dmax;       /* (SEMI_)END_BUF anchor distance */
+  int            sub_anchor;        /* start-anchor for exact or map */
+  unsigned char *exact;
+  unsigned char *exact_end;
+  unsigned char  map[ONIG_CHAR_TABLE_SIZE]; /* used as BM skip or char-map */
+  int           *int_map;                   /* BM skip for exact_len > 255 */
+  int           *int_map_backward;          /* BM skip for backward search */
+  OnigDistance   dmin;                      /* min-distance of exact or map */
+  OnigDistance   dmax;                      /* max-distance of exact or map */
+
+  /* regex_t link chain */
+  struct re_pattern_buffer* chain;  /* escape compile-conflict */
+} OnigRegexType;
+
+typedef OnigRegexType*  OnigRegex;
+
+#ifndef ONIG_ESCAPE_REGEX_T_COLLISION
+typedef OnigRegexType  regex_t;
+#endif
+
+
+typedef struct {
+  int             num_of_elements;
+  OnigEncoding    pattern_enc;
+  OnigEncoding    target_enc;
+  const OnigSyntaxType* syntax;
+  OnigOptionType  option;
+  OnigCaseFoldType   case_fold_flag;
+} OnigCompileInfo;
+
+/* Oniguruma Native API */
+ONIG_EXTERN
+int onig_initialize(OnigEncoding encodings[], int n);
+ONIG_EXTERN
+int onig_init(void);
+ONIG_EXTERN
+int onig_error_code_to_str(OnigUChar* s, OnigPosition err_code, ...);
+ONIG_EXTERN
+void onig_set_warn_func(OnigWarnFunc f);
+ONIG_EXTERN
+void onig_set_verb_warn_func(OnigWarnFunc f);
+ONIG_EXTERN
+int onig_new(OnigRegex*, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, const OnigSyntaxType* syntax, OnigErrorInfo* einfo);
+ONIG_EXTERN
+int onig_reg_init(OnigRegex reg, OnigOptionType option, OnigCaseFoldType case_fold_flag, OnigEncoding enc, const OnigSyntaxType* syntax);
+ONIG_EXTERN
+int onig_new_without_alloc(OnigRegex, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, const OnigSyntaxType* syntax, OnigErrorInfo* einfo);
+ONIG_EXTERN
+int onig_new_deluxe(OnigRegex* reg, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigCompileInfo* ci, OnigErrorInfo* einfo);
+ONIG_EXTERN
+void onig_free(OnigRegex);
+ONIG_EXTERN
+void onig_free_body(OnigRegex);
+ONIG_EXTERN
+OnigPosition onig_scan(OnigRegex reg, const OnigUChar* str, const OnigUChar* end, OnigRegion* region, OnigOptionType option, int (*scan_callback)(OnigPosition, OnigPosition, OnigRegion*, void*), void* callback_arg);
+ONIG_EXTERN
+OnigPosition onig_search(OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* start, const OnigUChar* range, OnigRegion* region, OnigOptionType option);
+ONIG_EXTERN
+OnigPosition onig_search_gpos(OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* global_pos, const OnigUChar* start, const OnigUChar* range, OnigRegion* region, OnigOptionType option);
+ONIG_EXTERN
+OnigPosition onig_match(OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* at, OnigRegion* region, OnigOptionType option);
+ONIG_EXTERN
+OnigRegion* onig_region_new(void);
+ONIG_EXTERN
+void onig_region_init(OnigRegion* region);
+ONIG_EXTERN
+void onig_region_free(OnigRegion* region, int free_self);
+ONIG_EXTERN
+void onig_region_copy(OnigRegion* to, const OnigRegion* from);
+ONIG_EXTERN
+void onig_region_clear(OnigRegion* region);
+ONIG_EXTERN
+int onig_region_resize(OnigRegion* region, int n);
+ONIG_EXTERN
+int onig_region_set(OnigRegion* region, int at, int beg, int end);
+ONIG_EXTERN
+int onig_name_to_group_numbers(OnigRegex reg, const OnigUChar* name, const OnigUChar* name_end, int** nums);
+ONIG_EXTERN
+int onig_name_to_backref_number(OnigRegex reg, const OnigUChar* name, const OnigUChar* name_end, const OnigRegion *region);
+ONIG_EXTERN
+int onig_foreach_name(OnigRegex reg, int (*func)(const OnigUChar*, const OnigUChar*,int,int*,OnigRegex,void*), void* arg);
+ONIG_EXTERN
+int onig_number_of_names(const OnigRegexType *reg);
+ONIG_EXTERN
+int onig_number_of_captures(const OnigRegexType *reg);
+ONIG_EXTERN
+int onig_number_of_capture_histories(const OnigRegexType *reg);
+ONIG_EXTERN
+OnigCaptureTreeNode* onig_get_capture_tree(OnigRegion* region);
+ONIG_EXTERN
+int onig_capture_tree_traverse(OnigRegion* region, int at, int(*callback_func)(int,OnigPosition,OnigPosition,int,int,void*), void* arg);
+ONIG_EXTERN
+int onig_noname_group_capture_is_active(const OnigRegexType *reg);
+ONIG_EXTERN
+OnigEncoding onig_get_encoding(const OnigRegexType *reg);
+ONIG_EXTERN
+OnigOptionType onig_get_options(const OnigRegexType *reg);
+ONIG_EXTERN
+OnigCaseFoldType onig_get_case_fold_flag(const OnigRegexType *reg);
+ONIG_EXTERN
+const OnigSyntaxType* onig_get_syntax(const OnigRegexType *reg);
+ONIG_EXTERN
+int onig_set_default_syntax(const OnigSyntaxType* syntax);
+ONIG_EXTERN
+void onig_copy_syntax(OnigSyntaxType* to, const OnigSyntaxType* from);
+ONIG_EXTERN
+unsigned int onig_get_syntax_op(const OnigSyntaxType* syntax);
+ONIG_EXTERN
+unsigned int onig_get_syntax_op2(const OnigSyntaxType* syntax);
+ONIG_EXTERN
+unsigned int onig_get_syntax_behavior(const OnigSyntaxType* syntax);
+ONIG_EXTERN
+OnigOptionType onig_get_syntax_options(const OnigSyntaxType* syntax);
+ONIG_EXTERN
+void onig_set_syntax_op(OnigSyntaxType* syntax, unsigned int op);
+ONIG_EXTERN
+void onig_set_syntax_op2(OnigSyntaxType* syntax, unsigned int op2);
+ONIG_EXTERN
+void onig_set_syntax_behavior(OnigSyntaxType* syntax, unsigned int behavior);
+ONIG_EXTERN
+void onig_set_syntax_options(OnigSyntaxType* syntax, OnigOptionType options);
+ONIG_EXTERN
+int onig_set_meta_char(OnigSyntaxType* syntax, unsigned int what, OnigCodePoint code);
+ONIG_EXTERN
+void onig_copy_encoding(OnigEncodingType *to, OnigEncoding from);
+ONIG_EXTERN
+OnigCaseFoldType onig_get_default_case_fold_flag(void);
+ONIG_EXTERN
+int onig_set_default_case_fold_flag(OnigCaseFoldType case_fold_flag);
+ONIG_EXTERN
+unsigned int onig_get_match_stack_limit_size(void);
+ONIG_EXTERN
+int onig_set_match_stack_limit_size(unsigned int size);
+ONIG_EXTERN
+unsigned int onig_get_parse_depth_limit(void);
+ONIG_EXTERN
+int onig_set_parse_depth_limit(unsigned int depth);
+ONIG_EXTERN
+int onig_end(void);
+ONIG_EXTERN
+const char* onig_version(void);
+ONIG_EXTERN
+const char* onig_copyright(void);
+
+RUBY_SYMBOL_EXPORT_END
+
+#ifdef __cplusplus
+# if 0
+{ /* satisfy cc-mode */
+# endif
+}
+#endif
+
+#endif /* ONIGMO_H */
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/onigmognu.h
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/onigmognu.h	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/onigmognu.h	(revision 331)
@@ -0,0 +1,86 @@
+#ifndef ONIGMOGNU_H
+#define ONIGMOGNU_H
+/**********************************************************************
+  onigmognu.h - Onigmo (Oniguruma-mod) (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2005  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011-2016  K.Takata  <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "onigmo.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RE_MBCTYPE_ASCII         0
+#define RE_MBCTYPE_EUC           1
+#define RE_MBCTYPE_SJIS          2
+#define RE_MBCTYPE_UTF8          3
+
+/* GNU regex options */
+#ifndef RE_NREGS
+#define RE_NREGS                ONIG_NREGION
+#endif
+
+#define RE_OPTION_IGNORECASE         ONIG_OPTION_IGNORECASE
+#define RE_OPTION_EXTENDED           ONIG_OPTION_EXTEND
+#define RE_OPTION_MULTILINE          ONIG_OPTION_MULTILINE
+#define RE_OPTION_SINGLELINE         ONIG_OPTION_SINGLELINE
+#define RE_OPTION_LONGEST            ONIG_OPTION_FIND_LONGEST
+#define RE_OPTION_POSIXLINE         (RE_OPTION_MULTILINE|RE_OPTION_SINGLELINE)
+#define RE_OPTION_FIND_NOT_EMPTY     ONIG_OPTION_FIND_NOT_EMPTY
+#define RE_OPTION_NEGATE_SINGLELINE  ONIG_OPTION_NEGATE_SINGLELINE
+#define RE_OPTION_DONT_CAPTURE_GROUP ONIG_OPTION_DONT_CAPTURE_GROUP
+#define RE_OPTION_CAPTURE_GROUP      ONIG_OPTION_CAPTURE_GROUP
+
+
+ONIG_EXTERN
+void re_mbcinit(int);
+ONIG_EXTERN
+int re_compile_pattern(const char*, int, struct re_pattern_buffer*, char* err_buf);
+ONIG_EXTERN
+int re_recompile_pattern(const char*, int, struct re_pattern_buffer*, char* err_buf);
+ONIG_EXTERN
+void re_free_pattern(struct re_pattern_buffer*);
+ONIG_EXTERN
+int re_adjust_startpos(struct re_pattern_buffer*, const char*, int, int, int);
+ONIG_EXTERN
+int re_search(struct re_pattern_buffer*, const char*, int, int, int, struct re_registers*);
+ONIG_EXTERN
+int re_match(struct re_pattern_buffer*, const char *, int, int, struct re_registers*);
+ONIG_EXTERN
+void re_set_casetable(const char*);
+ONIG_EXTERN
+void re_free_registers(struct re_registers*);
+ONIG_EXTERN
+int re_alloc_pattern(struct re_pattern_buffer**);  /* added */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ONIGMOGNU_H */
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/onigmoposix.h
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/onigmoposix.h	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/onigmoposix.h	(revision 331)
@@ -0,0 +1,163 @@
+#ifndef ONIGMOPOSIX_H
+#define ONIGMOPOSIX_H
+/**********************************************************************
+  onigmoposix.h - Onigmo (Oniguruma-mod) (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2005  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011-2016  K.Takata  <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* options */
+#define REG_ICASE          (1<<0)
+#define REG_NEWLINE        (1<<1)
+#define REG_NOTBOL         (1<<2)
+#define REG_NOTEOL         (1<<3)
+#define REG_EXTENDED       (1<<4) /* if not set, Basic Onigular Expression */
+#define REG_NOSUB          (1<<5)
+
+/* POSIX error codes */
+#define REG_NOMATCH          1
+#define REG_BADPAT           2
+#define REG_ECOLLATE         3
+#define REG_ECTYPE           4
+#define REG_EESCAPE          5
+#define REG_ESUBREG          6
+#define REG_EBRACK           7
+#define REG_EPAREN           8
+#define REG_EBRACE           9
+#define REG_BADBR           10
+#define REG_ERANGE          11
+#define REG_ESPACE          12
+#define REG_BADRPT          13
+
+/* extended error codes */
+#define REG_EONIG_INTERNAL  14
+#define REG_EONIG_BADWC     15
+#define REG_EONIG_BADARG    16
+/* #define REG_EONIG_THREAD    17 */
+
+/* character encodings (for reg_set_encoding()) */
+#define REG_POSIX_ENCODING_ASCII     0
+#define REG_POSIX_ENCODING_EUC_JP    1
+#define REG_POSIX_ENCODING_SJIS      2
+#define REG_POSIX_ENCODING_UTF8      3
+#define REG_POSIX_ENCODING_UTF16_BE  4
+#define REG_POSIX_ENCODING_UTF16_LE  5
+
+
+typedef int regoff_t;
+
+typedef struct {
+  regoff_t  rm_so;
+  regoff_t  rm_eo;
+} regmatch_t;
+
+/* POSIX regex_t */
+typedef struct {
+  void*   onig;          /* Oniguruma regex_t*  */
+  size_t  re_nsub;
+  int     comp_options;
+} regex_t;
+
+
+#ifndef ONIG_EXTERN
+# if defined(_WIN32) && !defined(__GNUC__)
+#  if defined(EXPORT)
+#   define ONIG_EXTERN   extern __declspec(dllexport)
+#  else
+#   define ONIG_EXTERN   extern __declspec(dllimport)
+#  endif
+# endif
+#endif
+
+#ifndef ONIG_EXTERN
+# define ONIG_EXTERN   extern
+#endif
+
+#ifndef ONIGMO_H
+typedef unsigned int        OnigOptionType;
+
+/* syntax */
+typedef struct {
+  unsigned int op;
+  unsigned int op2;
+  unsigned int behavior;
+  OnigOptionType options;    /* default option */
+} OnigSyntaxType;
+
+ONIG_EXTERN const OnigSyntaxType OnigSyntaxPosixBasic;
+ONIG_EXTERN const OnigSyntaxType OnigSyntaxPosixExtended;
+ONIG_EXTERN const OnigSyntaxType OnigSyntaxEmacs;
+ONIG_EXTERN const OnigSyntaxType OnigSyntaxGrep;
+ONIG_EXTERN const OnigSyntaxType OnigSyntaxGnuRegex;
+ONIG_EXTERN const OnigSyntaxType OnigSyntaxJava;
+ONIG_EXTERN const OnigSyntaxType OnigSyntaxPerl;
+ONIG_EXTERN const OnigSyntaxType OnigSyntaxRuby;
+
+/* predefined syntaxes (see regsyntax.c) */
+#define ONIG_SYNTAX_POSIX_BASIC        (&OnigSyntaxPosixBasic)
+#define ONIG_SYNTAX_POSIX_EXTENDED     (&OnigSyntaxPosixExtended)
+#define ONIG_SYNTAX_EMACS              (&OnigSyntaxEmacs)
+#define ONIG_SYNTAX_GREP               (&OnigSyntaxGrep)
+#define ONIG_SYNTAX_GNU_REGEX          (&OnigSyntaxGnuRegex)
+#define ONIG_SYNTAX_JAVA               (&OnigSyntaxJava)
+#define ONIG_SYNTAX_PERL               (&OnigSyntaxPerl)
+#define ONIG_SYNTAX_RUBY               (&OnigSyntaxRuby)
+/* default syntax */
+#define ONIG_SYNTAX_DEFAULT             OnigDefaultSyntax
+
+ONIG_EXTERN const OnigSyntaxType*  OnigDefaultSyntax;
+
+ONIG_EXTERN int  onig_set_default_syntax(const OnigSyntaxType* syntax);
+ONIG_EXTERN void onig_copy_syntax(OnigSyntaxType* to, const OnigSyntaxType* from);
+ONIG_EXTERN const char* onig_version(void);
+ONIG_EXTERN const char* onig_copyright(void);
+ONIG_EXTERN int onig_end(void);
+
+#endif /* ONIGMO_H */
+
+
+ONIG_EXTERN int    regcomp(regex_t* reg, const char* pat, int options);
+ONIG_EXTERN int    regexec(regex_t* reg, const char* str, size_t nmatch, regmatch_t* matches, int options);
+ONIG_EXTERN void   regfree(regex_t* reg);
+ONIG_EXTERN size_t regerror(int code, const regex_t* reg, char* buf, size_t size);
+
+/* extended API */
+ONIG_EXTERN void reg_set_encoding(int enc);
+ONIG_EXTERN int  reg_name_to_group_numbers(regex_t* reg, const unsigned char* name, const unsigned char* name_end, int** nums);
+ONIG_EXTERN int  reg_foreach_name(regex_t* reg, int (*func)(const unsigned char*, const unsigned char*,int,int*,regex_t*,void*), void* arg);
+ONIG_EXTERN int  reg_number_of_names(regex_t* reg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ONIGMOPOSIX_H */
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/regcomp.c
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/regcomp.c	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/regcomp.c	(revision 331)
@@ -0,0 +1,6740 @@
+/**********************************************************************
+  regcomp.c -  Onigmo (Oniguruma-mod) (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2013  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011-2016  K.Takata  <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "regparse.h"
+
+OnigCaseFoldType OnigDefaultCaseFoldFlag = ONIGENC_CASE_FOLD_MIN;
+
+extern OnigCaseFoldType
+onig_get_default_case_fold_flag(void)
+{
+  return OnigDefaultCaseFoldFlag;
+}
+
+extern int
+onig_set_default_case_fold_flag(OnigCaseFoldType case_fold_flag)
+{
+  OnigDefaultCaseFoldFlag = case_fold_flag;
+  return 0;
+}
+
+
+#ifndef PLATFORM_UNALIGNED_WORD_ACCESS
+static unsigned char PadBuf[WORD_ALIGNMENT_SIZE];
+#endif
+
+#if 0
+static UChar*
+str_dup(UChar* s, UChar* end)
+{
+  ptrdiff_t len = end - s;
+
+  if (len > 0) {
+    UChar* r = (UChar* )xmalloc(len + 1);
+    CHECK_NULL_RETURN(r);
+    xmemcpy(r, s, len);
+    r[len] = (UChar )0;
+    return r;
+  }
+  else return NULL;
+}
+#endif
+
+static void
+swap_node(Node* a, Node* b)
+{
+  Node c;
+  c = *a; *a = *b; *b = c;
+
+  if (NTYPE(a) == NT_STR) {
+    StrNode* sn = NSTR(a);
+    if (sn->capa == 0) {
+      size_t len = sn->end - sn->s;
+      sn->s   = sn->buf;
+      sn->end = sn->s + len;
+    }
+  }
+
+  if (NTYPE(b) == NT_STR) {
+    StrNode* sn = NSTR(b);
+    if (sn->capa == 0) {
+      size_t len = sn->end - sn->s;
+      sn->s   = sn->buf;
+      sn->end = sn->s + len;
+    }
+  }
+}
+
+static OnigDistance
+distance_add(OnigDistance d1, OnigDistance d2)
+{
+  if (d1 == ONIG_INFINITE_DISTANCE || d2 == ONIG_INFINITE_DISTANCE)
+    return ONIG_INFINITE_DISTANCE;
+  else {
+    if (d1 <= ONIG_INFINITE_DISTANCE - d2) return d1 + d2;
+    else return ONIG_INFINITE_DISTANCE;
+  }
+}
+
+static OnigDistance
+distance_multiply(OnigDistance d, int m)
+{
+  if (m == 0) return 0;
+
+  if (d < ONIG_INFINITE_DISTANCE / m)
+    return d * m;
+  else
+    return ONIG_INFINITE_DISTANCE;
+}
+
+static int
+bitset_is_empty(BitSetRef bs)
+{
+  int i;
+  for (i = 0; i < BITSET_SIZE; i++) {
+    if (bs[i] != 0) return 0;
+  }
+  return 1;
+}
+
+#ifdef ONIG_DEBUG
+static int
+bitset_on_num(BitSetRef bs)
+{
+  int i, n;
+
+  n = 0;
+  for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
+    if (BITSET_AT(bs, i)) n++;
+  }
+  return n;
+}
+#endif
+
+extern int
+onig_bbuf_init(BBuf* buf, OnigDistance size)
+{
+  if (size <= 0) {
+    size   = 0;
+    buf->p = NULL;
+  }
+  else {
+    buf->p = (UChar* )xmalloc(size);
+    if (IS_NULL(buf->p)) return(ONIGERR_MEMORY);
+  }
+
+  buf->alloc = (unsigned int )size;
+  buf->used  = 0;
+  return 0;
+}
+
+
+#ifdef USE_SUBEXP_CALL
+
+static int
+unset_addr_list_init(UnsetAddrList* uslist, int size)
+{
+  UnsetAddr* p;
+
+  p = (UnsetAddr* )xmalloc(sizeof(UnsetAddr)* size);
+  CHECK_NULL_RETURN_MEMERR(p);
+  uslist->num   = 0;
+  uslist->alloc = size;
+  uslist->us    = p;
+  return 0;
+}
+
+static void
+unset_addr_list_end(UnsetAddrList* uslist)
+{
+  if (IS_NOT_NULL(uslist->us))
+    xfree(uslist->us);
+}
+
+static int
+unset_addr_list_add(UnsetAddrList* uslist, int offset, struct _Node* node)
+{
+  UnsetAddr* p;
+  int size;
+
+  if (uslist->num >= uslist->alloc) {
+    size = uslist->alloc * 2;
+    p = (UnsetAddr* )xrealloc(uslist->us, sizeof(UnsetAddr) * size);
+    CHECK_NULL_RETURN_MEMERR(p);
+    uslist->alloc = size;
+    uslist->us    = p;
+  }
+
+  uslist->us[uslist->num].offset = offset;
+  uslist->us[uslist->num].target = node;
+  uslist->num++;
+  return 0;
+}
+#endif /* USE_SUBEXP_CALL */
+
+
+static int
+add_opcode(regex_t* reg, int opcode)
+{
+  BBUF_ADD1(reg, opcode);
+  return 0;
+}
+
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+static int
+add_state_check_num(regex_t* reg, int num)
+{
+  StateCheckNumType n = (StateCheckNumType )num;
+
+  BBUF_ADD(reg, &n, SIZE_STATE_CHECK_NUM);
+  return 0;
+}
+#endif
+
+static int
+add_rel_addr(regex_t* reg, int addr)
+{
+  RelAddrType ra = (RelAddrType )addr;
+
+  BBUF_ADD(reg, &ra, SIZE_RELADDR);
+  return 0;
+}
+
+static int
+add_abs_addr(regex_t* reg, int addr)
+{
+  AbsAddrType ra = (AbsAddrType )addr;
+
+  BBUF_ADD(reg, &ra, SIZE_ABSADDR);
+  return 0;
+}
+
+static int
+add_length(regex_t* reg, OnigDistance len)
+{
+  LengthType l = (LengthType )len;
+
+  BBUF_ADD(reg, &l, SIZE_LENGTH);
+  return 0;
+}
+
+static int
+add_mem_num(regex_t* reg, int num)
+{
+  MemNumType n = (MemNumType )num;
+
+  BBUF_ADD(reg, &n, SIZE_MEMNUM);
+  return 0;
+}
+
+#if 0
+static int
+add_pointer(regex_t* reg, void* addr)
+{
+  PointerType ptr = (PointerType )addr;
+
+  BBUF_ADD(reg, &ptr, SIZE_POINTER);
+  return 0;
+}
+#endif
+
+static int
+add_option(regex_t* reg, OnigOptionType option)
+{
+  BBUF_ADD(reg, &option, SIZE_OPTION);
+  return 0;
+}
+
+static int
+add_opcode_rel_addr(regex_t* reg, int opcode, int addr)
+{
+  int r;
+
+  r = add_opcode(reg, opcode);
+  if (r) return r;
+  r = add_rel_addr(reg, addr);
+  return r;
+}
+
+static int
+add_bytes(regex_t* reg, UChar* bytes, OnigDistance len)
+{
+  BBUF_ADD(reg, bytes, len);
+  return 0;
+}
+
+static int
+add_bitset(regex_t* reg, BitSetRef bs)
+{
+  BBUF_ADD(reg, bs, SIZE_BITSET);
+  return 0;
+}
+
+static int
+add_opcode_option(regex_t* reg, int opcode, OnigOptionType option)
+{
+  int r;
+
+  r = add_opcode(reg, opcode);
+  if (r) return r;
+  r = add_option(reg, option);
+  return r;
+}
+
+static int compile_length_tree(Node* node, regex_t* reg);
+static int compile_tree(Node* node, regex_t* reg);
+
+
+#define IS_NEED_STR_LEN_OP_EXACT(op) \
+   ((op) == OP_EXACTN    || (op) == OP_EXACTMB2N ||\
+    (op) == OP_EXACTMB3N || (op) == OP_EXACTMBN  || (op) == OP_EXACTN_IC)
+
+static int
+select_str_opcode(int mb_len, OnigDistance byte_len, int ignore_case)
+{
+  int op;
+  OnigDistance str_len = (byte_len + mb_len - 1) / mb_len;
+
+  if (ignore_case) {
+    switch (str_len) {
+    case 1:  op = OP_EXACT1_IC; break;
+    default: op = OP_EXACTN_IC; break;
+    }
+  }
+  else {
+    switch (mb_len) {
+    case 1:
+      switch (str_len) {
+      case 1:  op = OP_EXACT1; break;
+      case 2:  op = OP_EXACT2; break;
+      case 3:  op = OP_EXACT3; break;
+      case 4:  op = OP_EXACT4; break;
+      case 5:  op = OP_EXACT5; break;
+      default: op = OP_EXACTN; break;
+      }
+      break;
+
+    case 2:
+      switch (str_len) {
+      case 1:  op = OP_EXACTMB2N1; break;
+      case 2:  op = OP_EXACTMB2N2; break;
+      case 3:  op = OP_EXACTMB2N3; break;
+      default: op = OP_EXACTMB2N;  break;
+      }
+      break;
+
+    case 3:
+      op = OP_EXACTMB3N;
+      break;
+
+    default:
+      op = OP_EXACTMBN;
+      break;
+    }
+  }
+  return op;
+}
+
+static int
+compile_tree_empty_check(Node* node, regex_t* reg, int empty_info)
+{
+  int r;
+  int saved_num_null_check = reg->num_null_check;
+
+  if (empty_info != 0) {
+    r = add_opcode(reg, OP_NULL_CHECK_START);
+    if (r) return r;
+    r = add_mem_num(reg, reg->num_null_check); /* NULL CHECK ID */
+    if (r) return r;
+    reg->num_null_check++;
+  }
+
+  r = compile_tree(node, reg);
+  if (r) return r;
+
+  if (empty_info != 0) {
+    if (empty_info == NQ_TARGET_IS_EMPTY)
+      r = add_opcode(reg, OP_NULL_CHECK_END);
+    else if (empty_info == NQ_TARGET_IS_EMPTY_MEM)
+      r = add_opcode(reg, OP_NULL_CHECK_END_MEMST);
+    else if (empty_info == NQ_TARGET_IS_EMPTY_REC)
+      r = add_opcode(reg, OP_NULL_CHECK_END_MEMST_PUSH);
+
+    if (r) return r;
+    r = add_mem_num(reg, saved_num_null_check); /* NULL CHECK ID */
+  }
+  return r;
+}
+
+#ifdef USE_SUBEXP_CALL
+static int
+compile_call(CallNode* node, regex_t* reg)
+{
+  int r;
+
+  r = add_opcode(reg, OP_CALL);
+  if (r) return r;
+  r = unset_addr_list_add(node->unset_addr_list, BBUF_GET_OFFSET_POS(reg),
+                          node->target);
+  if (r) return r;
+  r = add_abs_addr(reg, 0 /*dummy addr.*/);
+  return r;
+}
+#endif
+
+static int
+compile_tree_n_times(Node* node, int n, regex_t* reg)
+{
+  int i, r;
+
+  for (i = 0; i < n; i++) {
+    r = compile_tree(node, reg);
+    if (r) return r;
+  }
+  return 0;
+}
+
+static int
+add_compile_string_length(UChar* s ARG_UNUSED, int mb_len, OnigDistance byte_len,
+                          regex_t* reg ARG_UNUSED, int ignore_case)
+{
+  int len;
+  int op = select_str_opcode(mb_len, byte_len, ignore_case);
+
+  len = SIZE_OPCODE;
+
+  if (op == OP_EXACTMBN)  len += SIZE_LENGTH;
+  if (IS_NEED_STR_LEN_OP_EXACT(op))
+    len += SIZE_LENGTH;
+
+  len += (int )byte_len;
+  return len;
+}
+
+static int
+add_compile_string(UChar* s, int mb_len, OnigDistance byte_len,
+                   regex_t* reg, int ignore_case)
+{
+  int op = select_str_opcode(mb_len, byte_len, ignore_case);
+  add_opcode(reg, op);
+
+  if (op == OP_EXACTMBN)
+    add_length(reg, mb_len);
+
+  if (IS_NEED_STR_LEN_OP_EXACT(op)) {
+    if (op == OP_EXACTN_IC)
+      add_length(reg, byte_len);
+    else
+      add_length(reg, byte_len / mb_len);
+  }
+
+  add_bytes(reg, s, byte_len);
+  return 0;
+}
+
+
+static int
+compile_length_string_node(Node* node, regex_t* reg)
+{
+  int rlen, r, len, prev_len, blen, ambig;
+  OnigEncoding enc = reg->enc;
+  UChar *p, *prev;
+  StrNode* sn;
+
+  sn = NSTR(node);
+  if (sn->end <= sn->s)
+    return 0;
+
+  ambig = NSTRING_IS_AMBIG(node);
+
+  p = prev = sn->s;
+  prev_len = enclen(enc, p, sn->end);
+  p += prev_len;
+  blen = prev_len;
+  rlen = 0;
+
+  for (; p < sn->end; ) {
+    len = enclen(enc, p, sn->end);
+    if (len == prev_len || ambig) {
+      blen += len;
+    }
+    else {
+      r = add_compile_string_length(prev, prev_len, blen, reg, ambig);
+      rlen += r;
+      prev = p;
+      blen = len;
+      prev_len = len;
+    }
+    p += len;
+  }
+  r = add_compile_string_length(prev, prev_len, blen, reg, ambig);
+  rlen += r;
+  return rlen;
+}
+
+static int
+compile_length_string_raw_node(StrNode* sn, regex_t* reg)
+{
+  if (sn->end <= sn->s)
+    return 0;
+
+  return add_compile_string_length(sn->s, 1 /* sb */, sn->end - sn->s, reg, 0);
+}
+
+static int
+compile_string_node(Node* node, regex_t* reg)
+{
+  int r, len, prev_len, blen, ambig;
+  OnigEncoding enc = reg->enc;
+  UChar *p, *prev, *end;
+  StrNode* sn;
+
+  sn = NSTR(node);
+  if (sn->end <= sn->s)
+    return 0;
+
+  end = sn->end;
+  ambig = NSTRING_IS_AMBIG(node);
+
+  p = prev = sn->s;
+  prev_len = enclen(enc, p, end);
+  p += prev_len;
+  blen = prev_len;
+
+  for (; p < end; ) {
+    len = enclen(enc, p, end);
+    if (len == prev_len || ambig) {
+      blen += len;
+    }
+    else {
+      r = add_compile_string(prev, prev_len, blen, reg, ambig);
+      if (r) return r;
+
+      prev  = p;
+      blen  = len;
+      prev_len = len;
+    }
+
+    p += len;
+  }
+  return add_compile_string(prev, prev_len, blen, reg, ambig);
+}
+
+static int
+compile_string_raw_node(StrNode* sn, regex_t* reg)
+{
+  if (sn->end <= sn->s)
+    return 0;
+
+  return add_compile_string(sn->s, 1 /* sb */, sn->end - sn->s, reg, 0);
+}
+
+static int
+add_multi_byte_cclass(BBuf* mbuf, regex_t* reg)
+{
+#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
+  add_length(reg, mbuf->used);
+  return add_bytes(reg, mbuf->p, mbuf->used);
+#else
+  int r, pad_size;
+  UChar* p = BBUF_GET_ADD_ADDRESS(reg) + SIZE_LENGTH;
+
+  GET_ALIGNMENT_PAD_SIZE(p, pad_size);
+  add_length(reg, mbuf->used + (WORD_ALIGNMENT_SIZE - 1));
+  if (pad_size != 0) add_bytes(reg, PadBuf, pad_size);
+
+  r = add_bytes(reg, mbuf->p, mbuf->used);
+
+  /* padding for return value from compile_length_cclass_node() to be fix. */
+  pad_size = (WORD_ALIGNMENT_SIZE - 1) - pad_size;
+  if (pad_size != 0) add_bytes(reg, PadBuf, pad_size);
+  return r;
+#endif
+}
+
+static int
+compile_length_cclass_node(CClassNode* cc, regex_t* reg)
+{
+  int len;
+
+  if (IS_NULL(cc->mbuf)) {
+    len = SIZE_OPCODE + SIZE_BITSET;
+  }
+  else {
+    if (ONIGENC_MBC_MINLEN(reg->enc) > 1 || bitset_is_empty(cc->bs)) {
+      len = SIZE_OPCODE;
+    }
+    else {
+      len = SIZE_OPCODE + SIZE_BITSET;
+    }
+#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
+    len += SIZE_LENGTH + cc->mbuf->used;
+#else
+    len += SIZE_LENGTH + cc->mbuf->used + (WORD_ALIGNMENT_SIZE - 1);
+#endif
+  }
+
+  return len;
+}
+
+static int
+compile_cclass_node(CClassNode* cc, regex_t* reg)
+{
+  int r;
+
+  if (IS_NULL(cc->mbuf)) {
+    if (IS_NCCLASS_NOT(cc))
+      add_opcode(reg, OP_CCLASS_NOT);
+    else
+      add_opcode(reg, OP_CCLASS);
+
+    r = add_bitset(reg, cc->bs);
+  }
+  else {
+    if (ONIGENC_MBC_MINLEN(reg->enc) > 1 || bitset_is_empty(cc->bs)) {
+      if (IS_NCCLASS_NOT(cc))
+	add_opcode(reg, OP_CCLASS_MB_NOT);
+      else
+	add_opcode(reg, OP_CCLASS_MB);
+
+      r = add_multi_byte_cclass(cc->mbuf, reg);
+    }
+    else {
+      if (IS_NCCLASS_NOT(cc))
+	add_opcode(reg, OP_CCLASS_MIX_NOT);
+      else
+	add_opcode(reg, OP_CCLASS_MIX);
+
+      r = add_bitset(reg, cc->bs);
+      if (r) return r;
+      r = add_multi_byte_cclass(cc->mbuf, reg);
+    }
+  }
+
+  return r;
+}
+
+static int
+entry_repeat_range(regex_t* reg, int id, int lower, int upper)
+{
+#define REPEAT_RANGE_ALLOC  4
+
+  OnigRepeatRange* p;
+
+  if (reg->repeat_range_alloc == 0) {
+    p = (OnigRepeatRange* )xmalloc(sizeof(OnigRepeatRange) * REPEAT_RANGE_ALLOC);
+    CHECK_NULL_RETURN_MEMERR(p);
+    reg->repeat_range = p;
+    reg->repeat_range_alloc = REPEAT_RANGE_ALLOC;
+  }
+  else if (reg->repeat_range_alloc <= id) {
+    int n;
+    n = reg->repeat_range_alloc + REPEAT_RANGE_ALLOC;
+    p = (OnigRepeatRange* )xrealloc(reg->repeat_range,
+                                    sizeof(OnigRepeatRange) * n);
+    CHECK_NULL_RETURN_MEMERR(p);
+    reg->repeat_range = p;
+    reg->repeat_range_alloc = n;
+  }
+  else {
+    p = reg->repeat_range;
+  }
+
+  p[id].lower = lower;
+  p[id].upper = (IS_REPEAT_INFINITE(upper) ? 0x7fffffff : upper);
+  return 0;
+}
+
+static int
+compile_range_repeat_node(QtfrNode* qn, int target_len, int empty_info,
+                          regex_t* reg)
+{
+  int r;
+  int num_repeat = reg->num_repeat;
+
+  r = add_opcode(reg, qn->greedy ? OP_REPEAT : OP_REPEAT_NG);
+  if (r) return r;
+  r = add_mem_num(reg, num_repeat); /* OP_REPEAT ID */
+  reg->num_repeat++;
+  if (r) return r;
+  r = add_rel_addr(reg, target_len + SIZE_OP_REPEAT_INC);
+  if (r) return r;
+
+  r = entry_repeat_range(reg, num_repeat, qn->lower, qn->upper);
+  if (r) return r;
+
+  r = compile_tree_empty_check(qn->target, reg, empty_info);
+  if (r) return r;
+
+  if (
+#ifdef USE_SUBEXP_CALL
+      reg->num_call > 0 ||
+#endif
+      IS_QUANTIFIER_IN_REPEAT(qn)) {
+    r = add_opcode(reg, qn->greedy ? OP_REPEAT_INC_SG : OP_REPEAT_INC_NG_SG);
+  }
+  else {
+    r = add_opcode(reg, qn->greedy ? OP_REPEAT_INC : OP_REPEAT_INC_NG);
+  }
+  if (r) return r;
+  r = add_mem_num(reg, num_repeat); /* OP_REPEAT ID */
+  return r;
+}
+
+static int
+is_anychar_star_quantifier(QtfrNode* qn)
+{
+  if (qn->greedy && IS_REPEAT_INFINITE(qn->upper) &&
+      NTYPE(qn->target) == NT_CANY)
+    return 1;
+  else
+    return 0;
+}
+
+#define QUANTIFIER_EXPAND_LIMIT_SIZE   50
+#define CKN_ON   (ckn > 0)
+
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+
+static int
+compile_length_quantifier_node(QtfrNode* qn, regex_t* reg)
+{
+  int len, mod_tlen, cklen;
+  int ckn;
+  int infinite = IS_REPEAT_INFINITE(qn->upper);
+  int empty_info = qn->target_empty_info;
+  int tlen = compile_length_tree(qn->target, reg);
+
+  if (tlen < 0) return tlen;
+
+  ckn = ((reg->num_comb_exp_check > 0) ? qn->comb_exp_check_num : 0);
+
+  cklen = (CKN_ON ? SIZE_STATE_CHECK_NUM: 0);
+
+  /* anychar repeat */
+  if (NTYPE(qn->target) == NT_CANY) {
+    if (qn->greedy && infinite) {
+      if (IS_NOT_NULL(qn->next_head_exact) && !CKN_ON)
+	return SIZE_OP_ANYCHAR_STAR_PEEK_NEXT + tlen * qn->lower + cklen;
+      else
+	return SIZE_OP_ANYCHAR_STAR + tlen * qn->lower + cklen;
+    }
+  }
+
+  if (empty_info != 0)
+    mod_tlen = tlen + (SIZE_OP_NULL_CHECK_START + SIZE_OP_NULL_CHECK_END);
+  else
+    mod_tlen = tlen;
+
+  if (infinite && qn->lower <= 1) {
+    if (qn->greedy) {
+      if (qn->lower == 1)
+	len = SIZE_OP_JUMP;
+      else
+	len = 0;
+
+      len += SIZE_OP_PUSH + cklen + mod_tlen + SIZE_OP_JUMP;
+    }
+    else {
+      if (qn->lower == 0)
+	len = SIZE_OP_JUMP;
+      else
+	len = 0;
+
+      len += mod_tlen + SIZE_OP_PUSH + cklen;
+    }
+  }
+  else if (qn->upper == 0) {
+    if (qn->is_refered != 0) /* /(?<n>..){0}/ */
+      len = SIZE_OP_JUMP + tlen;
+    else
+      len = 0;
+  }
+  else if (qn->upper == 1 && qn->greedy) {
+    if (qn->lower == 0) {
+      if (CKN_ON) {
+	len = SIZE_OP_STATE_CHECK_PUSH + tlen;
+      }
+      else {
+	len = SIZE_OP_PUSH + tlen;
+      }
+    }
+    else {
+      len = tlen;
+    }
+  }
+  else if (!qn->greedy && qn->upper == 1 && qn->lower == 0) { /* '??' */
+    len = SIZE_OP_PUSH + cklen + SIZE_OP_JUMP + tlen;
+  }
+  else {
+    len = SIZE_OP_REPEAT_INC
+        + mod_tlen + SIZE_OPCODE + SIZE_RELADDR + SIZE_MEMNUM;
+    if (CKN_ON)
+      len += SIZE_OP_STATE_CHECK;
+  }
+
+  return len;
+}
+
+static int
+compile_quantifier_node(QtfrNode* qn, regex_t* reg)
+{
+  int r, mod_tlen;
+  int ckn;
+  int infinite = IS_REPEAT_INFINITE(qn->upper);
+  int empty_info = qn->target_empty_info;
+  int tlen = compile_length_tree(qn->target, reg);
+
+  if (tlen < 0) return tlen;
+
+  ckn = ((reg->num_comb_exp_check > 0) ? qn->comb_exp_check_num : 0);
+
+  if (is_anychar_star_quantifier(qn)) {
+    r = compile_tree_n_times(qn->target, qn->lower, reg);
+    if (r) return r;
+    if (IS_NOT_NULL(qn->next_head_exact) && !CKN_ON) {
+      if (IS_MULTILINE(reg->options))
+	r = add_opcode(reg, OP_ANYCHAR_ML_STAR_PEEK_NEXT);
+      else
+	r = add_opcode(reg, OP_ANYCHAR_STAR_PEEK_NEXT);
+      if (r) return r;
+      if (CKN_ON) {
+	r = add_state_check_num(reg, ckn);
+	if (r) return r;
+      }
+
+      return add_bytes(reg, NSTR(qn->next_head_exact)->s, 1);
+    }
+    else {
+      if (IS_MULTILINE(reg->options)) {
+	r = add_opcode(reg, (CKN_ON ?
+			       OP_STATE_CHECK_ANYCHAR_ML_STAR
+			     : OP_ANYCHAR_ML_STAR));
+      }
+      else {
+	r = add_opcode(reg, (CKN_ON ?
+			       OP_STATE_CHECK_ANYCHAR_STAR
+			     : OP_ANYCHAR_STAR));
+      }
+      if (r) return r;
+      if (CKN_ON)
+	r = add_state_check_num(reg, ckn);
+
+      return r;
+    }
+  }
+
+  if (empty_info != 0)
+    mod_tlen = tlen + (SIZE_OP_NULL_CHECK_START + SIZE_OP_NULL_CHECK_END);
+  else
+    mod_tlen = tlen;
+
+  if (infinite && qn->lower <= 1) {
+    if (qn->greedy) {
+      if (qn->lower == 1) {
+	r = add_opcode_rel_addr(reg, OP_JUMP,
+			(CKN_ON ? SIZE_OP_STATE_CHECK_PUSH : SIZE_OP_PUSH));
+	if (r) return r;
+      }
+
+      if (CKN_ON) {
+	r = add_opcode(reg, OP_STATE_CHECK_PUSH);
+	if (r) return r;
+	r = add_state_check_num(reg, ckn);
+	if (r) return r;
+	r = add_rel_addr(reg, mod_tlen + SIZE_OP_JUMP);
+      }
+      else {
+	r = add_opcode_rel_addr(reg, OP_PUSH, mod_tlen + SIZE_OP_JUMP);
+      }
+      if (r) return r;
+      r = compile_tree_empty_check(qn->target, reg, empty_info);
+      if (r) return r;
+      r = add_opcode_rel_addr(reg, OP_JUMP,
+	      -(mod_tlen + (int )SIZE_OP_JUMP
+		+ (int )(CKN_ON ? SIZE_OP_STATE_CHECK_PUSH : SIZE_OP_PUSH)));
+    }
+    else {
+      if (qn->lower == 0) {
+	r = add_opcode_rel_addr(reg, OP_JUMP, mod_tlen);
+	if (r) return r;
+      }
+      r = compile_tree_empty_check(qn->target, reg, empty_info);
+      if (r) return r;
+      if (CKN_ON) {
+	r = add_opcode(reg, OP_STATE_CHECK_PUSH_OR_JUMP);
+	if (r) return r;
+	r = add_state_check_num(reg, ckn);
+	if (r) return r;
+	r = add_rel_addr(reg,
+		 -(mod_tlen + (int )SIZE_OP_STATE_CHECK_PUSH_OR_JUMP));
+      }
+      else
+	r = add_opcode_rel_addr(reg, OP_PUSH, -(mod_tlen + (int )SIZE_OP_PUSH));
+    }
+  }
+  else if (qn->upper == 0) {
+    if (qn->is_refered != 0) { /* /(?<n>..){0}/ */
+      r = add_opcode_rel_addr(reg, OP_JUMP, tlen);
+      if (r) return r;
+      r = compile_tree(qn->target, reg);
+    }
+    else
+      r = 0;
+  }
+  else if (qn->upper == 1 && qn->greedy) {
+    if (qn->lower == 0) {
+      if (CKN_ON) {
+	r = add_opcode(reg, OP_STATE_CHECK_PUSH);
+	if (r) return r;
+	r = add_state_check_num(reg, ckn);
+	if (r) return r;
+	r = add_rel_addr(reg, tlen);
+      }
+      else {
+	r = add_opcode_rel_addr(reg, OP_PUSH, tlen);
+      }
+      if (r) return r;
+    }
+
+    r = compile_tree(qn->target, reg);
+  }
+  else if (!qn->greedy && qn->upper == 1 && qn->lower == 0) { /* '??' */
+    if (CKN_ON) {
+      r = add_opcode(reg, OP_STATE_CHECK_PUSH);
+      if (r) return r;
+      r = add_state_check_num(reg, ckn);
+      if (r) return r;
+      r = add_rel_addr(reg, SIZE_OP_JUMP);
+    }
+    else {
+      r = add_opcode_rel_addr(reg, OP_PUSH, SIZE_OP_JUMP);
+    }
+
+    if (r) return r;
+    r = add_opcode_rel_addr(reg, OP_JUMP, tlen);
+    if (r) return r;
+    r = compile_tree(qn->target, reg);
+  }
+  else {
+    r = compile_range_repeat_node(qn, mod_tlen, empty_info, reg);
+    if (CKN_ON) {
+      if (r) return r;
+      r = add_opcode(reg, OP_STATE_CHECK);
+      if (r) return r;
+      r = add_state_check_num(reg, ckn);
+    }
+  }
+  return r;
+}
+
+#else /* USE_COMBINATION_EXPLOSION_CHECK */
+
+static int
+compile_length_quantifier_node(QtfrNode* qn, regex_t* reg)
+{
+  int len, mod_tlen;
+  int infinite = IS_REPEAT_INFINITE(qn->upper);
+  int empty_info = qn->target_empty_info;
+  int tlen = compile_length_tree(qn->target, reg);
+
+  if (tlen < 0) return tlen;
+
+  /* anychar repeat */
+  if (NTYPE(qn->target) == NT_CANY) {
+    if (qn->greedy && infinite) {
+      if (IS_NOT_NULL(qn->next_head_exact))
+	return SIZE_OP_ANYCHAR_STAR_PEEK_NEXT + tlen * qn->lower;
+      else
+	return SIZE_OP_ANYCHAR_STAR + tlen * qn->lower;
+    }
+  }
+
+  if (empty_info != 0)
+    mod_tlen = tlen + (SIZE_OP_NULL_CHECK_START + SIZE_OP_NULL_CHECK_END);
+  else
+    mod_tlen = tlen;
+
+  if (infinite &&
+      (qn->lower <= 1 || tlen * qn->lower <= QUANTIFIER_EXPAND_LIMIT_SIZE)) {
+    if (qn->lower == 1 && tlen > QUANTIFIER_EXPAND_LIMIT_SIZE) {
+      len = SIZE_OP_JUMP;
+    }
+    else {
+      len = tlen * qn->lower;
+    }
+
+    if (qn->greedy) {
+#ifdef USE_OP_PUSH_OR_JUMP_EXACT
+      if (IS_NOT_NULL(qn->head_exact))
+	len += SIZE_OP_PUSH_OR_JUMP_EXACT1 + mod_tlen + SIZE_OP_JUMP;
+      else
+#endif
+      if (IS_NOT_NULL(qn->next_head_exact))
+	len += SIZE_OP_PUSH_IF_PEEK_NEXT + mod_tlen + SIZE_OP_JUMP;
+      else
+	len += SIZE_OP_PUSH + mod_tlen + SIZE_OP_JUMP;
+    }
+    else
+      len += SIZE_OP_JUMP + mod_tlen + SIZE_OP_PUSH;
+  }
+  else if (qn->upper == 0 && qn->is_refered != 0) { /* /(?<n>..){0}/ */
+    len = SIZE_OP_JUMP + tlen;
+  }
+  else if (!infinite && qn->greedy &&
+           (qn->upper == 1 || (tlen + SIZE_OP_PUSH) * qn->upper
+                                      <= QUANTIFIER_EXPAND_LIMIT_SIZE)) {
+    len = tlen * qn->lower;
+    len += (SIZE_OP_PUSH + tlen) * (qn->upper - qn->lower);
+  }
+  else if (!qn->greedy && qn->upper == 1 && qn->lower == 0) { /* '??' */
+    len = SIZE_OP_PUSH + SIZE_OP_JUMP + tlen;
+  }
+  else {
+    len = SIZE_OP_REPEAT_INC
+        + mod_tlen + SIZE_OPCODE + SIZE_RELADDR + SIZE_MEMNUM;
+  }
+
+  return len;
+}
+
+static int
+compile_quantifier_node(QtfrNode* qn, regex_t* reg)
+{
+  int i, r, mod_tlen;
+  int infinite = IS_REPEAT_INFINITE(qn->upper);
+  int empty_info = qn->target_empty_info;
+  int tlen = compile_length_tree(qn->target, reg);
+
+  if (tlen < 0) return tlen;
+
+  if (is_anychar_star_quantifier(qn)) {
+    r = compile_tree_n_times(qn->target, qn->lower, reg);
+    if (r) return r;
+    if (IS_NOT_NULL(qn->next_head_exact)) {
+      if (IS_MULTILINE(reg->options))
+	r = add_opcode(reg, OP_ANYCHAR_ML_STAR_PEEK_NEXT);
+      else
+	r = add_opcode(reg, OP_ANYCHAR_STAR_PEEK_NEXT);
+      if (r) return r;
+      return add_bytes(reg, NSTR(qn->next_head_exact)->s, 1);
+    }
+    else {
+      if (IS_MULTILINE(reg->options))
+	return add_opcode(reg, OP_ANYCHAR_ML_STAR);
+      else
+	return add_opcode(reg, OP_ANYCHAR_STAR);
+    }
+  }
+
+  if (empty_info != 0)
+    mod_tlen = tlen + (SIZE_OP_NULL_CHECK_START + SIZE_OP_NULL_CHECK_END);
+  else
+    mod_tlen = tlen;
+
+  if (infinite &&
+      (qn->lower <= 1 || tlen * qn->lower <= QUANTIFIER_EXPAND_LIMIT_SIZE)) {
+    if (qn->lower == 1 && tlen > QUANTIFIER_EXPAND_LIMIT_SIZE) {
+      if (qn->greedy) {
+#ifdef USE_OP_PUSH_OR_JUMP_EXACT
+	if (IS_NOT_NULL(qn->head_exact))
+	  r = add_opcode_rel_addr(reg, OP_JUMP, SIZE_OP_PUSH_OR_JUMP_EXACT1);
+	else
+#endif
+	if (IS_NOT_NULL(qn->next_head_exact))
+	  r = add_opcode_rel_addr(reg, OP_JUMP, SIZE_OP_PUSH_IF_PEEK_NEXT);
+	else
+	  r = add_opcode_rel_addr(reg, OP_JUMP, SIZE_OP_PUSH);
+      }
+      else {
+	r = add_opcode_rel_addr(reg, OP_JUMP, SIZE_OP_JUMP);
+      }
+      if (r) return r;
+    }
+    else {
+      r = compile_tree_n_times(qn->target, qn->lower, reg);
+      if (r) return r;
+    }
+
+    if (qn->greedy) {
+#ifdef USE_OP_PUSH_OR_JUMP_EXACT
+      if (IS_NOT_NULL(qn->head_exact)) {
+	r = add_opcode_rel_addr(reg, OP_PUSH_OR_JUMP_EXACT1,
+			     mod_tlen + SIZE_OP_JUMP);
+	if (r) return r;
+	add_bytes(reg, NSTR(qn->head_exact)->s, 1);
+	r = compile_tree_empty_check(qn->target, reg, empty_info);
+	if (r) return r;
+	r = add_opcode_rel_addr(reg, OP_JUMP,
+	-(mod_tlen + (int )SIZE_OP_JUMP + (int )SIZE_OP_PUSH_OR_JUMP_EXACT1));
+      }
+      else
+#endif
+      if (IS_NOT_NULL(qn->next_head_exact)) {
+	r = add_opcode_rel_addr(reg, OP_PUSH_IF_PEEK_NEXT,
+				mod_tlen + SIZE_OP_JUMP);
+	if (r) return r;
+	add_bytes(reg, NSTR(qn->next_head_exact)->s, 1);
+	r = compile_tree_empty_check(qn->target, reg, empty_info);
+	if (r) return r;
+	r = add_opcode_rel_addr(reg, OP_JUMP,
+          -(mod_tlen + (int )SIZE_OP_JUMP + (int )SIZE_OP_PUSH_IF_PEEK_NEXT));
+      }
+      else {
+	r = add_opcode_rel_addr(reg, OP_PUSH, mod_tlen + SIZE_OP_JUMP);
+	if (r) return r;
+	r = compile_tree_empty_check(qn->target, reg, empty_info);
+	if (r) return r;
+	r = add_opcode_rel_addr(reg, OP_JUMP,
+		     -(mod_tlen + (int )SIZE_OP_JUMP + (int )SIZE_OP_PUSH));
+      }
+    }
+    else {
+      r = add_opcode_rel_addr(reg, OP_JUMP, mod_tlen);
+      if (r) return r;
+      r = compile_tree_empty_check(qn->target, reg, empty_info);
+      if (r) return r;
+      r = add_opcode_rel_addr(reg, OP_PUSH, -(mod_tlen + (int )SIZE_OP_PUSH));
+    }
+  }
+  else if (qn->upper == 0 && qn->is_refered != 0) { /* /(?<n>..){0}/ */
+    r = add_opcode_rel_addr(reg, OP_JUMP, tlen);
+    if (r) return r;
+    r = compile_tree(qn->target, reg);
+  }
+  else if (!infinite && qn->greedy &&
+           (qn->upper == 1 || (tlen + SIZE_OP_PUSH) * qn->upper
+                                  <= QUANTIFIER_EXPAND_LIMIT_SIZE)) {
+    int n = qn->upper - qn->lower;
+
+    r = compile_tree_n_times(qn->target, qn->lower, reg);
+    if (r) return r;
+
+    for (i = 0; i < n; i++) {
+      r = add_opcode_rel_addr(reg, OP_PUSH,
+			   (n - i) * tlen + (n - i - 1) * SIZE_OP_PUSH);
+      if (r) return r;
+      r = compile_tree(qn->target, reg);
+      if (r) return r;
+    }
+  }
+  else if (!qn->greedy && qn->upper == 1 && qn->lower == 0) { /* '??' */
+    r = add_opcode_rel_addr(reg, OP_PUSH, SIZE_OP_JUMP);
+    if (r) return r;
+    r = add_opcode_rel_addr(reg, OP_JUMP, tlen);
+    if (r) return r;
+    r = compile_tree(qn->target, reg);
+  }
+  else {
+    r = compile_range_repeat_node(qn, mod_tlen, empty_info, reg);
+  }
+  return r;
+}
+#endif /* USE_COMBINATION_EXPLOSION_CHECK */
+
+static int
+compile_length_option_node(EncloseNode* node, regex_t* reg)
+{
+  int tlen;
+  OnigOptionType prev = reg->options;
+
+  reg->options = node->option;
+  tlen = compile_length_tree(node->target, reg);
+  reg->options = prev;
+
+  if (tlen < 0) return tlen;
+
+  if (IS_DYNAMIC_OPTION(prev ^ node->option)) {
+    return SIZE_OP_SET_OPTION_PUSH + SIZE_OP_SET_OPTION + SIZE_OP_FAIL
+           + tlen + SIZE_OP_SET_OPTION;
+  }
+  else
+    return tlen;
+}
+
+static int
+compile_option_node(EncloseNode* node, regex_t* reg)
+{
+  int r;
+  OnigOptionType prev = reg->options;
+
+  if (IS_DYNAMIC_OPTION(prev ^ node->option)) {
+    r = add_opcode_option(reg, OP_SET_OPTION_PUSH, node->option);
+    if (r) return r;
+    r = add_opcode_option(reg, OP_SET_OPTION, prev);
+    if (r) return r;
+    r = add_opcode(reg, OP_FAIL);
+    if (r) return r;
+  }
+
+  reg->options = node->option;
+  r = compile_tree(node->target, reg);
+  reg->options = prev;
+
+  if (IS_DYNAMIC_OPTION(prev ^ node->option)) {
+    if (r) return r;
+    r = add_opcode_option(reg, OP_SET_OPTION, prev);
+  }
+  return r;
+}
+
+static int
+compile_length_enclose_node(EncloseNode* node, regex_t* reg)
+{
+  int len;
+  int tlen;
+
+  if (node->type == ENCLOSE_OPTION)
+    return compile_length_option_node(node, reg);
+
+  if (node->target) {
+    tlen = compile_length_tree(node->target, reg);
+    if (tlen < 0) return tlen;
+  }
+  else
+    tlen = 0;
+
+  switch (node->type) {
+  case ENCLOSE_MEMORY:
+#ifdef USE_SUBEXP_CALL
+    if (IS_ENCLOSE_CALLED(node)) {
+      len = SIZE_OP_MEMORY_START_PUSH + tlen
+	  + SIZE_OP_CALL + SIZE_OP_JUMP + SIZE_OP_RETURN;
+      if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
+	len += (IS_ENCLOSE_RECURSION(node)
+		? SIZE_OP_MEMORY_END_PUSH_REC : SIZE_OP_MEMORY_END_PUSH);
+      else
+	len += (IS_ENCLOSE_RECURSION(node)
+		? SIZE_OP_MEMORY_END_REC : SIZE_OP_MEMORY_END);
+    }
+    else if (IS_ENCLOSE_RECURSION(node)) {
+      len = SIZE_OP_MEMORY_START_PUSH;
+      len += tlen + (BIT_STATUS_AT(reg->bt_mem_end, node->regnum)
+		     ? SIZE_OP_MEMORY_END_PUSH_REC : SIZE_OP_MEMORY_END_REC);
+    }
+    else
+#endif
+    {
+      if (BIT_STATUS_AT(reg->bt_mem_start, node->regnum))
+	len = SIZE_OP_MEMORY_START_PUSH;
+      else
+	len = SIZE_OP_MEMORY_START;
+
+      len += tlen + (BIT_STATUS_AT(reg->bt_mem_end, node->regnum)
+		     ? SIZE_OP_MEMORY_END_PUSH : SIZE_OP_MEMORY_END);
+    }
+    break;
+
+  case ENCLOSE_STOP_BACKTRACK:
+    if (IS_ENCLOSE_STOP_BT_SIMPLE_REPEAT(node)) {
+      QtfrNode* qn = NQTFR(node->target);
+      tlen = compile_length_tree(qn->target, reg);
+      if (tlen < 0) return tlen;
+
+      len = tlen * qn->lower
+	  + SIZE_OP_PUSH + tlen + SIZE_OP_POP + SIZE_OP_JUMP;
+    }
+    else {
+      len = SIZE_OP_PUSH_STOP_BT + tlen + SIZE_OP_POP_STOP_BT;
+    }
+    break;
+
+  case ENCLOSE_CONDITION:
+    len = SIZE_OP_CONDITION;
+    if (NTYPE(node->target) == NT_ALT) {
+      Node* x = node->target;
+
+      tlen = compile_length_tree(NCAR(x), reg); /* yes-node */
+      if (tlen < 0) return tlen;
+      len += tlen + SIZE_OP_JUMP;
+      if (NCDR(x) == NULL) return ONIGERR_PARSER_BUG;
+      x = NCDR(x);
+      tlen = compile_length_tree(NCAR(x), reg); /* no-node */
+      if (tlen < 0) return tlen;
+      len += tlen;
+      if (NCDR(x) != NULL) return ONIGERR_INVALID_CONDITION_PATTERN;
+    }
+    else {
+      return ONIGERR_PARSER_BUG;
+    }
+    break;
+
+  case ENCLOSE_ABSENT:
+    len = SIZE_OP_PUSH_ABSENT_POS + SIZE_OP_ABSENT + tlen + SIZE_OP_ABSENT_END;
+    break;
+
+  default:
+    return ONIGERR_TYPE_BUG;
+    break;
+  }
+
+  return len;
+}
+
+static int get_char_length_tree(Node* node, regex_t* reg, int* len);
+
+static int
+compile_enclose_node(EncloseNode* node, regex_t* reg)
+{
+  int r, len;
+
+  if (node->type == ENCLOSE_OPTION)
+    return compile_option_node(node, reg);
+
+  switch (node->type) {
+  case ENCLOSE_MEMORY:
+#ifdef USE_SUBEXP_CALL
+    if (IS_ENCLOSE_CALLED(node)) {
+      r = add_opcode(reg, OP_CALL);
+      if (r) return r;
+      node->call_addr = BBUF_GET_OFFSET_POS(reg) + SIZE_ABSADDR + SIZE_OP_JUMP;
+      node->state |= NST_ADDR_FIXED;
+      r = add_abs_addr(reg, (int )node->call_addr);
+      if (r) return r;
+      len = compile_length_tree(node->target, reg);
+      len += (SIZE_OP_MEMORY_START_PUSH + SIZE_OP_RETURN);
+      if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
+	len += (IS_ENCLOSE_RECURSION(node)
+		? SIZE_OP_MEMORY_END_PUSH_REC : SIZE_OP_MEMORY_END_PUSH);
+      else
+	len += (IS_ENCLOSE_RECURSION(node)
+		? SIZE_OP_MEMORY_END_REC : SIZE_OP_MEMORY_END);
+
+      r = add_opcode_rel_addr(reg, OP_JUMP, len);
+      if (r) return r;
+    }
+#endif
+    if (BIT_STATUS_AT(reg->bt_mem_start, node->regnum))
+      r = add_opcode(reg, OP_MEMORY_START_PUSH);
+    else
+      r = add_opcode(reg, OP_MEMORY_START);
+    if (r) return r;
+    r = add_mem_num(reg, node->regnum);
+    if (r) return r;
+    r = compile_tree(node->target, reg);
+    if (r) return r;
+#ifdef USE_SUBEXP_CALL
+    if (IS_ENCLOSE_CALLED(node)) {
+      if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
+	r = add_opcode(reg, (IS_ENCLOSE_RECURSION(node)
+			     ? OP_MEMORY_END_PUSH_REC : OP_MEMORY_END_PUSH));
+      else
+	r = add_opcode(reg, (IS_ENCLOSE_RECURSION(node)
+			     ? OP_MEMORY_END_REC : OP_MEMORY_END));
+
+      if (r) return r;
+      r = add_mem_num(reg, node->regnum);
+      if (r) return r;
+      r = add_opcode(reg, OP_RETURN);
+    }
+    else if (IS_ENCLOSE_RECURSION(node)) {
+      if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
+	r = add_opcode(reg, OP_MEMORY_END_PUSH_REC);
+      else
+	r = add_opcode(reg, OP_MEMORY_END_REC);
+      if (r) return r;
+      r = add_mem_num(reg, node->regnum);
+    }
+    else
+#endif
+    {
+      if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
+	r = add_opcode(reg, OP_MEMORY_END_PUSH);
+      else
+	r = add_opcode(reg, OP_MEMORY_END);
+      if (r) return r;
+      r = add_mem_num(reg, node->regnum);
+    }
+    break;
+
+  case ENCLOSE_STOP_BACKTRACK:
+    if (IS_ENCLOSE_STOP_BT_SIMPLE_REPEAT(node)) {
+      QtfrNode* qn = NQTFR(node->target);
+      r = compile_tree_n_times(qn->target, qn->lower, reg);
+      if (r) return r;
+
+      len = compile_length_tree(qn->target, reg);
+      if (len < 0) return len;
+
+      r = add_opcode_rel_addr(reg, OP_PUSH, len + SIZE_OP_POP + SIZE_OP_JUMP);
+      if (r) return r;
+      r = compile_tree(qn->target, reg);
+      if (r) return r;
+      r = add_opcode(reg, OP_POP);
+      if (r) return r;
+      r = add_opcode_rel_addr(reg, OP_JUMP,
+	 -((int )SIZE_OP_PUSH + len + (int )SIZE_OP_POP + (int )SIZE_OP_JUMP));
+    }
+    else {
+      r = add_opcode(reg, OP_PUSH_STOP_BT);
+      if (r) return r;
+      r = compile_tree(node->target, reg);
+      if (r) return r;
+      r = add_opcode(reg, OP_POP_STOP_BT);
+    }
+    break;
+
+  case ENCLOSE_CONDITION:
+    r = add_opcode(reg, OP_CONDITION);
+    if (r) return r;
+    r = add_mem_num(reg, node->regnum);
+    if (r) return r;
+
+    if (NTYPE(node->target) == NT_ALT) {
+      Node* x = node->target;
+      int len2;
+
+      len = compile_length_tree(NCAR(x), reg);  /* yes-node */
+      if (len < 0) return len;
+      if (NCDR(x) == NULL) return ONIGERR_PARSER_BUG;
+      x = NCDR(x);
+      len2 = compile_length_tree(NCAR(x), reg); /* no-node */
+      if (len2 < 0) return len2;
+      if (NCDR(x) != NULL) return ONIGERR_INVALID_CONDITION_PATTERN;
+
+      x = node->target;
+      r = add_rel_addr(reg, len + SIZE_OP_JUMP);
+      if (r) return r;
+      r = compile_tree(NCAR(x), reg);   /* yes-node */
+      if (r) return r;
+      r = add_opcode_rel_addr(reg, OP_JUMP, len2);
+      if (r) return r;
+      x = NCDR(x);
+      r = compile_tree(NCAR(x), reg);   /* no-node */
+    }
+    else {
+      return ONIGERR_PARSER_BUG;
+    }
+    break;
+
+  case ENCLOSE_ABSENT:
+    len = compile_length_tree(node->target, reg);
+    if (len < 0) return len;
+
+    r = add_opcode(reg, OP_PUSH_ABSENT_POS);
+    if (r) return r;
+    r = add_opcode_rel_addr(reg, OP_ABSENT, len + SIZE_OP_ABSENT_END);
+    if (r) return r;
+    r = compile_tree(node->target, reg);
+    if (r) return r;
+    r = add_opcode(reg, OP_ABSENT_END);
+    break;
+
+  default:
+    return ONIGERR_TYPE_BUG;
+    break;
+  }
+
+  return r;
+}
+
+static int
+compile_length_anchor_node(AnchorNode* node, regex_t* reg)
+{
+  int len;
+  int tlen = 0;
+
+  if (node->target) {
+    tlen = compile_length_tree(node->target, reg);
+    if (tlen < 0) return tlen;
+  }
+
+  switch (node->type) {
+  case ANCHOR_PREC_READ:
+    len = SIZE_OP_PUSH_POS + tlen + SIZE_OP_POP_POS;
+    break;
+  case ANCHOR_PREC_READ_NOT:
+    len = SIZE_OP_PUSH_POS_NOT + tlen + SIZE_OP_FAIL_POS;
+    break;
+  case ANCHOR_LOOK_BEHIND:
+    len = SIZE_OP_LOOK_BEHIND + tlen;
+    break;
+  case ANCHOR_LOOK_BEHIND_NOT:
+    len = SIZE_OP_PUSH_LOOK_BEHIND_NOT + tlen + SIZE_OP_FAIL_LOOK_BEHIND_NOT;
+    break;
+
+  default:
+    len = SIZE_OPCODE;
+    break;
+  }
+
+  return len;
+}
+
+static int
+compile_anchor_node(AnchorNode* node, regex_t* reg)
+{
+  int r, len;
+
+  switch (node->type) {
+  case ANCHOR_BEGIN_BUF:      r = add_opcode(reg, OP_BEGIN_BUF);      break;
+  case ANCHOR_END_BUF:        r = add_opcode(reg, OP_END_BUF);        break;
+  case ANCHOR_BEGIN_LINE:     r = add_opcode(reg, OP_BEGIN_LINE);     break;
+  case ANCHOR_END_LINE:       r = add_opcode(reg, OP_END_LINE);       break;
+  case ANCHOR_SEMI_END_BUF:   r = add_opcode(reg, OP_SEMI_END_BUF);   break;
+  case ANCHOR_BEGIN_POSITION: r = add_opcode(reg, OP_BEGIN_POSITION); break;
+
+  case ANCHOR_WORD_BOUND:
+    if (node->ascii_range)    r = add_opcode(reg, OP_ASCII_WORD_BOUND);
+    else                      r = add_opcode(reg, OP_WORD_BOUND);
+    break;
+  case ANCHOR_NOT_WORD_BOUND:
+    if (node->ascii_range)    r = add_opcode(reg, OP_NOT_ASCII_WORD_BOUND);
+    else                      r = add_opcode(reg, OP_NOT_WORD_BOUND);
+    break;
+#ifdef USE_WORD_BEGIN_END
+  case ANCHOR_WORD_BEGIN:
+    if (node->ascii_range)    r = add_opcode(reg, OP_ASCII_WORD_BEGIN);
+    else                      r = add_opcode(reg, OP_WORD_BEGIN);
+    break;
+  case ANCHOR_WORD_END:
+    if (node->ascii_range)    r = add_opcode(reg, OP_ASCII_WORD_END);
+    else                      r = add_opcode(reg, OP_WORD_END);
+    break;
+#endif
+  case ANCHOR_KEEP:           r = add_opcode(reg, OP_KEEP);           break;
+
+  case ANCHOR_PREC_READ:
+    r = add_opcode(reg, OP_PUSH_POS);
+    if (r) return r;
+    r = compile_tree(node->target, reg);
+    if (r) return r;
+    r = add_opcode(reg, OP_POP_POS);
+    break;
+
+  case ANCHOR_PREC_READ_NOT:
+    len = compile_length_tree(node->target, reg);
+    if (len < 0) return len;
+    r = add_opcode_rel_addr(reg, OP_PUSH_POS_NOT, len + SIZE_OP_FAIL_POS);
+    if (r) return r;
+    r = compile_tree(node->target, reg);
+    if (r) return r;
+    r = add_opcode(reg, OP_FAIL_POS);
+    break;
+
+  case ANCHOR_LOOK_BEHIND:
+    {
+      int n;
+      r = add_opcode(reg, OP_LOOK_BEHIND);
+      if (r) return r;
+      if (node->char_len < 0) {
+	r = get_char_length_tree(node->target, reg, &n);
+	if (r) return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
+      }
+      else
+	n = node->char_len;
+      r = add_length(reg, n);
+      if (r) return r;
+      r = compile_tree(node->target, reg);
+    }
+    break;
+
+  case ANCHOR_LOOK_BEHIND_NOT:
+    {
+      int n;
+      len = compile_length_tree(node->target, reg);
+      r = add_opcode_rel_addr(reg, OP_PUSH_LOOK_BEHIND_NOT,
+			   len + SIZE_OP_FAIL_LOOK_BEHIND_NOT);
+      if (r) return r;
+      if (node->char_len < 0) {
+	r = get_char_length_tree(node->target, reg, &n);
+	if (r) return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
+      }
+      else
+	n = node->char_len;
+      r = add_length(reg, n);
+      if (r) return r;
+      r = compile_tree(node->target, reg);
+      if (r) return r;
+      r = add_opcode(reg, OP_FAIL_LOOK_BEHIND_NOT);
+    }
+    break;
+
+  default:
+    return ONIGERR_TYPE_BUG;
+    break;
+  }
+
+  return r;
+}
+
+static int
+compile_length_tree(Node* node, regex_t* reg)
+{
+  int len, type, r;
+
+  type = NTYPE(node);
+  switch (type) {
+  case NT_LIST:
+    len = 0;
+    do {
+      r = compile_length_tree(NCAR(node), reg);
+      if (r < 0) return r;
+      len += r;
+    } while (IS_NOT_NULL(node = NCDR(node)));
+    r = len;
+    break;
+
+  case NT_ALT:
+    {
+      int n = 0;
+      len = 0;
+      do {
+	r = compile_length_tree(NCAR(node), reg);
+	if (r < 0) return r;
+	len += r;
+	n++;
+      } while (IS_NOT_NULL(node = NCDR(node)));
+      r = len;
+      r += (SIZE_OP_PUSH + SIZE_OP_JUMP) * (n - 1);
+    }
+    break;
+
+  case NT_STR:
+    if (NSTRING_IS_RAW(node))
+      r = compile_length_string_raw_node(NSTR(node), reg);
+    else
+      r = compile_length_string_node(node, reg);
+    break;
+
+  case NT_CCLASS:
+    r = compile_length_cclass_node(NCCLASS(node), reg);
+    break;
+
+  case NT_CTYPE:
+  case NT_CANY:
+    r = SIZE_OPCODE;
+    break;
+
+  case NT_BREF:
+    {
+      BRefNode* br = NBREF(node);
+
+#ifdef USE_BACKREF_WITH_LEVEL
+      if (IS_BACKREF_NEST_LEVEL(br)) {
+	r = SIZE_OPCODE + SIZE_OPTION + SIZE_LENGTH +
+            SIZE_LENGTH + (SIZE_MEMNUM * br->back_num);
+      }
+      else
+#endif
+      if (br->back_num == 1) {
+	r = ((!IS_IGNORECASE(reg->options) && br->back_static[0] <= 2)
+	     ? SIZE_OPCODE : (SIZE_OPCODE + SIZE_MEMNUM));
+      }
+      else {
+	r = SIZE_OPCODE + SIZE_LENGTH + (SIZE_MEMNUM * br->back_num);
+      }
+    }
+    break;
+
+#ifdef USE_SUBEXP_CALL
+  case NT_CALL:
+    r = SIZE_OP_CALL;
+    break;
+#endif
+
+  case NT_QTFR:
+    r = compile_length_quantifier_node(NQTFR(node), reg);
+    break;
+
+  case NT_ENCLOSE:
+    r = compile_length_enclose_node(NENCLOSE(node), reg);
+    break;
+
+  case NT_ANCHOR:
+    r = compile_length_anchor_node(NANCHOR(node), reg);
+    break;
+
+  default:
+    return ONIGERR_TYPE_BUG;
+    break;
+  }
+
+  return r;
+}
+
+static int
+compile_tree(Node* node, regex_t* reg)
+{
+  int n, type, len, pos, r = 0;
+
+  type = NTYPE(node);
+  switch (type) {
+  case NT_LIST:
+    do {
+      r = compile_tree(NCAR(node), reg);
+    } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
+    break;
+
+  case NT_ALT:
+    {
+      Node* x = node;
+      len = 0;
+      do {
+	len += compile_length_tree(NCAR(x), reg);
+	if (NCDR(x) != NULL) {
+	  len += SIZE_OP_PUSH + SIZE_OP_JUMP;
+	}
+      } while (IS_NOT_NULL(x = NCDR(x)));
+      pos = reg->used + len;  /* goal position */
+
+      do {
+	len = compile_length_tree(NCAR(node), reg);
+	if (IS_NOT_NULL(NCDR(node))) {
+	  r = add_opcode_rel_addr(reg, OP_PUSH, len + SIZE_OP_JUMP);
+	  if (r) break;
+	}
+	r = compile_tree(NCAR(node), reg);
+	if (r) break;
+	if (IS_NOT_NULL(NCDR(node))) {
+	  len = pos - (reg->used + SIZE_OP_JUMP);
+	  r = add_opcode_rel_addr(reg, OP_JUMP, len);
+	  if (r) break;
+	}
+      } while (IS_NOT_NULL(node = NCDR(node)));
+    }
+    break;
+
+  case NT_STR:
+    if (NSTRING_IS_RAW(node))
+      r = compile_string_raw_node(NSTR(node), reg);
+    else
+      r = compile_string_node(node, reg);
+    break;
+
+  case NT_CCLASS:
+    r = compile_cclass_node(NCCLASS(node), reg);
+    break;
+
+  case NT_CTYPE:
+    {
+      int op;
+
+      switch (NCTYPE(node)->ctype) {
+      case ONIGENC_CTYPE_WORD:
+	if (NCTYPE(node)->ascii_range != 0) {
+	  if (NCTYPE(node)->not != 0)  op = OP_NOT_ASCII_WORD;
+	  else                         op = OP_ASCII_WORD;
+	}
+	else {
+	  if (NCTYPE(node)->not != 0)  op = OP_NOT_WORD;
+	  else                         op = OP_WORD;
+	}
+	break;
+      default:
+	return ONIGERR_TYPE_BUG;
+	break;
+      }
+      r = add_opcode(reg, op);
+    }
+    break;
+
+  case NT_CANY:
+    if (IS_MULTILINE(reg->options))
+      r = add_opcode(reg, OP_ANYCHAR_ML);
+    else
+      r = add_opcode(reg, OP_ANYCHAR);
+    break;
+
+  case NT_BREF:
+    {
+      BRefNode* br = NBREF(node);
+
+#ifdef USE_BACKREF_WITH_LEVEL
+      if (IS_BACKREF_NEST_LEVEL(br)) {
+	r = add_opcode(reg, OP_BACKREF_WITH_LEVEL);
+	if (r) return r;
+	r = add_option(reg, (reg->options & ONIG_OPTION_IGNORECASE));
+	if (r) return r;
+	r = add_length(reg, br->nest_level);
+	if (r) return r;
+
+	goto add_bacref_mems;
+      }
+      else
+#endif
+      if (br->back_num == 1) {
+	n = br->back_static[0];
+	if (IS_IGNORECASE(reg->options)) {
+	  r = add_opcode(reg, OP_BACKREFN_IC);
+	  if (r) return r;
+	  r = add_mem_num(reg, n);
+	}
+	else {
+	  switch (n) {
+	  case 1:  r = add_opcode(reg, OP_BACKREF1); break;
+	  case 2:  r = add_opcode(reg, OP_BACKREF2); break;
+	  default:
+	    r = add_opcode(reg, OP_BACKREFN);
+	    if (r) return r;
+	    r = add_mem_num(reg, n);
+	    break;
+	  }
+	}
+      }
+      else {
+	int i;
+	int* p;
+
+	if (IS_IGNORECASE(reg->options)) {
+	  r = add_opcode(reg, OP_BACKREF_MULTI_IC);
+	}
+	else {
+	  r = add_opcode(reg, OP_BACKREF_MULTI);
+	}
+	if (r) return r;
+
+#ifdef USE_BACKREF_WITH_LEVEL
+      add_bacref_mems:
+#endif
+	r = add_length(reg, br->back_num);
+	if (r) return r;
+	p = BACKREFS_P(br);
+	for (i = br->back_num - 1; i >= 0; i--) {
+	  r = add_mem_num(reg, p[i]);
+	  if (r) return r;
+	}
+      }
+    }
+    break;
+
+#ifdef USE_SUBEXP_CALL
+  case NT_CALL:
+    r = compile_call(NCALL(node), reg);
+    break;
+#endif
+
+  case NT_QTFR:
+    r = compile_quantifier_node(NQTFR(node), reg);
+    break;
+
+  case NT_ENCLOSE:
+    r = compile_enclose_node(NENCLOSE(node), reg);
+    break;
+
+  case NT_ANCHOR:
+    r = compile_anchor_node(NANCHOR(node), reg);
+    break;
+
+  default:
+#ifdef ONIG_DEBUG
+    fprintf(stderr, "compile_tree: undefined node type %d\n", NTYPE(node));
+#endif
+    break;
+  }
+
+  return r;
+}
+
+#ifdef USE_NAMED_GROUP
+
+static int
+noname_disable_map(Node** plink, GroupNumRemap* map, int* counter)
+{
+  int r = 0;
+  Node* node = *plink;
+
+  switch (NTYPE(node)) {
+  case NT_LIST:
+  case NT_ALT:
+    do {
+      r = noname_disable_map(&(NCAR(node)), map, counter);
+    } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
+    break;
+
+  case NT_QTFR:
+    {
+      Node** ptarget = &(NQTFR(node)->target);
+      Node*  old = *ptarget;
+      r = noname_disable_map(ptarget, map, counter);
+      if (*ptarget != old && NTYPE(*ptarget) == NT_QTFR) {
+	onig_reduce_nested_quantifier(node, *ptarget);
+      }
+    }
+    break;
+
+  case NT_ENCLOSE:
+    {
+      EncloseNode* en = NENCLOSE(node);
+      if (en->type == ENCLOSE_MEMORY) {
+	if (IS_ENCLOSE_NAMED_GROUP(en)) {
+	  (*counter)++;
+	  map[en->regnum].new_val = *counter;
+	  en->regnum = *counter;
+	}
+	else if (en->regnum != 0) {
+	  *plink = en->target;
+	  en->target = NULL_NODE;
+	  onig_node_free(node);
+	  r = noname_disable_map(plink, map, counter);
+	  break;
+	}
+      }
+      r = noname_disable_map(&(en->target), map, counter);
+    }
+    break;
+
+  case NT_ANCHOR:
+    if (NANCHOR(node)->target)
+      r = noname_disable_map(&(NANCHOR(node)->target), map, counter);
+    break;
+
+  default:
+    break;
+  }
+
+  return r;
+}
+
+static int
+renumber_node_backref(Node* node, GroupNumRemap* map)
+{
+  int i, pos, n, old_num;
+  int *backs;
+  BRefNode* bn = NBREF(node);
+
+  if (! IS_BACKREF_NAME_REF(bn))
+    return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;
+
+  old_num = bn->back_num;
+  if (IS_NULL(bn->back_dynamic))
+    backs = bn->back_static;
+  else
+    backs = bn->back_dynamic;
+
+  for (i = 0, pos = 0; i < old_num; i++) {
+    n = map[backs[i]].new_val;
+    if (n > 0) {
+      backs[pos] = n;
+      pos++;
+    }
+  }
+
+  bn->back_num = pos;
+  return 0;
+}
+
+static int
+renumber_by_map(Node* node, GroupNumRemap* map)
+{
+  int r = 0;
+
+  switch (NTYPE(node)) {
+  case NT_LIST:
+  case NT_ALT:
+    do {
+      r = renumber_by_map(NCAR(node), map);
+    } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
+    break;
+  case NT_QTFR:
+    r = renumber_by_map(NQTFR(node)->target, map);
+    break;
+  case NT_ENCLOSE:
+    {
+      EncloseNode* en = NENCLOSE(node);
+      if (en->type == ENCLOSE_CONDITION)
+	en->regnum = map[en->regnum].new_val;
+      r = renumber_by_map(en->target, map);
+    }
+    break;
+
+  case NT_BREF:
+    r = renumber_node_backref(node, map);
+    break;
+
+  case NT_ANCHOR:
+    if (NANCHOR(node)->target)
+      r = renumber_by_map(NANCHOR(node)->target, map);
+    break;
+
+  default:
+    break;
+  }
+
+  return r;
+}
+
+static int
+numbered_ref_check(Node* node)
+{
+  int r = 0;
+
+  switch (NTYPE(node)) {
+  case NT_LIST:
+  case NT_ALT:
+    do {
+      r = numbered_ref_check(NCAR(node));
+    } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
+    break;
+  case NT_QTFR:
+    r = numbered_ref_check(NQTFR(node)->target);
+    break;
+  case NT_ENCLOSE:
+    r = numbered_ref_check(NENCLOSE(node)->target);
+    break;
+
+  case NT_BREF:
+    if (! IS_BACKREF_NAME_REF(NBREF(node)))
+      return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;
+    break;
+
+  case NT_ANCHOR:
+    if (NANCHOR(node)->target)
+      r = numbered_ref_check(NANCHOR(node)->target);
+    break;
+
+  default:
+    break;
+  }
+
+  return r;
+}
+
+static int
+disable_noname_group_capture(Node** root, regex_t* reg, ScanEnv* env)
+{
+  int r, i, pos, counter;
+  BitStatusType loc;
+  GroupNumRemap* map;
+
+  map = (GroupNumRemap* )xalloca(sizeof(GroupNumRemap) * (env->num_mem + 1));
+  CHECK_NULL_RETURN_MEMERR(map);
+  for (i = 1; i <= env->num_mem; i++) {
+    map[i].new_val = 0;
+  }
+  counter = 0;
+  r = noname_disable_map(root, map, &counter);
+  if (r != 0) return r;
+
+  r = renumber_by_map(*root, map);
+  if (r != 0) return r;
+
+  for (i = 1, pos = 1; i <= env->num_mem; i++) {
+    if (map[i].new_val > 0) {
+      SCANENV_MEM_NODES(env)[pos] = SCANENV_MEM_NODES(env)[i];
+      pos++;
+    }
+  }
+
+  loc = env->capture_history;
+  BIT_STATUS_CLEAR(env->capture_history);
+  for (i = 1; i <= ONIG_MAX_CAPTURE_HISTORY_GROUP; i++) {
+    if (BIT_STATUS_AT(loc, i)) {
+      BIT_STATUS_ON_AT_SIMPLE(env->capture_history, map[i].new_val);
+    }
+  }
+
+  env->num_mem = env->num_named;
+  reg->num_mem = env->num_named;
+
+  return onig_renumber_name_table(reg, map);
+}
+#endif /* USE_NAMED_GROUP */
+
+#ifdef USE_SUBEXP_CALL
+static int
+unset_addr_list_fix(UnsetAddrList* uslist, regex_t* reg)
+{
+  int i, offset;
+  EncloseNode* en;
+  AbsAddrType addr;
+
+  for (i = 0; i < uslist->num; i++) {
+    en = NENCLOSE(uslist->us[i].target);
+    if (! IS_ENCLOSE_ADDR_FIXED(en)) return ONIGERR_PARSER_BUG;
+    addr = en->call_addr;
+    offset = uslist->us[i].offset;
+
+    BBUF_WRITE(reg, offset, &addr, SIZE_ABSADDR);
+  }
+  return 0;
+}
+#endif
+
+#ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
+static int
+quantifiers_memory_node_info(Node* node)
+{
+  int r = 0;
+
+  switch (NTYPE(node)) {
+  case NT_LIST:
+  case NT_ALT:
+    {
+      int v;
+      do {
+	v = quantifiers_memory_node_info(NCAR(node));
+	if (v > r) r = v;
+      } while (v >= 0 && IS_NOT_NULL(node = NCDR(node)));
+    }
+    break;
+
+# ifdef USE_SUBEXP_CALL
+  case NT_CALL:
+    if (IS_CALL_RECURSION(NCALL(node))) {
+      return NQ_TARGET_IS_EMPTY_REC; /* tiny version */
+    }
+    else
+      r = quantifiers_memory_node_info(NCALL(node)->target);
+    break;
+# endif
+
+  case NT_QTFR:
+    {
+      QtfrNode* qn = NQTFR(node);
+      if (qn->upper != 0) {
+	r = quantifiers_memory_node_info(qn->target);
+      }
+    }
+    break;
+
+  case NT_ENCLOSE:
+    {
+      EncloseNode* en = NENCLOSE(node);
+      switch (en->type) {
+      case ENCLOSE_MEMORY:
+	return NQ_TARGET_IS_EMPTY_MEM;
+	break;
+
+      case ENCLOSE_OPTION:
+      case ENCLOSE_STOP_BACKTRACK:
+      case ENCLOSE_CONDITION:
+      case ENCLOSE_ABSENT:
+	r = quantifiers_memory_node_info(en->target);
+	break;
+      default:
+	break;
+      }
+    }
+    break;
+
+  case NT_BREF:
+  case NT_STR:
+  case NT_CTYPE:
+  case NT_CCLASS:
+  case NT_CANY:
+  case NT_ANCHOR:
+  default:
+    break;
+  }
+
+  return r;
+}
+#endif /* USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT */
+
+static int
+get_min_match_length(Node* node, OnigDistance *min, ScanEnv* env)
+{
+  OnigDistance tmin;
+  int r = 0;
+
+  *min = 0;
+  switch (NTYPE(node)) {
+  case NT_BREF:
+    {
+      int i;
+      int* backs;
+      Node** nodes = SCANENV_MEM_NODES(env);
+      BRefNode* br = NBREF(node);
+      if (br->state & NST_RECURSION) break;
+
+      backs = BACKREFS_P(br);
+      if (backs[0] > env->num_mem)  return ONIGERR_INVALID_BACKREF;
+      r = get_min_match_length(nodes[backs[0]], min, env);
+      if (r != 0) break;
+      for (i = 1; i < br->back_num; i++) {
+	if (backs[i] > env->num_mem)  return ONIGERR_INVALID_BACKREF;
+	r = get_min_match_length(nodes[backs[i]], &tmin, env);
+	if (r != 0) break;
+	if (*min > tmin) *min = tmin;
+      }
+    }
+    break;
+
+#ifdef USE_SUBEXP_CALL
+  case NT_CALL:
+    if (IS_CALL_RECURSION(NCALL(node))) {
+      EncloseNode* en = NENCLOSE(NCALL(node)->target);
+      if (IS_ENCLOSE_MIN_FIXED(en))
+	*min = en->min_len;
+    }
+    else
+      r = get_min_match_length(NCALL(node)->target, min, env);
+    break;
+#endif
+
+  case NT_LIST:
+    do {
+      r = get_min_match_length(NCAR(node), &tmin, env);
+      if (r == 0) *min += tmin;
+    } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
+    break;
+
+  case NT_ALT:
+    {
+      Node *x, *y;
+      y = node;
+      do {
+	x = NCAR(y);
+	r = get_min_match_length(x, &tmin, env);
+	if (r != 0) break;
+	if (y == node) *min = tmin;
+	else if (*min > tmin) *min = tmin;
+      } while (r == 0 && IS_NOT_NULL(y = NCDR(y)));
+    }
+    break;
+
+  case NT_STR:
+    {
+      StrNode* sn = NSTR(node);
+      *min = sn->end - sn->s;
+    }
+    break;
+
+  case NT_CTYPE:
+    *min = 1;
+    break;
+
+  case NT_CCLASS:
+  case NT_CANY:
+    *min = 1;
+    break;
+
+  case NT_QTFR:
+    {
+      QtfrNode* qn = NQTFR(node);
+
+      if (qn->lower > 0) {
+	r = get_min_match_length(qn->target, min, env);
+	if (r == 0)
+	  *min = distance_multiply(*min, qn->lower);
+      }
+    }
+    break;
+
+  case NT_ENCLOSE:
+    {
+      EncloseNode* en = NENCLOSE(node);
+      switch (en->type) {
+      case ENCLOSE_MEMORY:
+        if (IS_ENCLOSE_MIN_FIXED(en))
+          *min = en->min_len;
+        else {
+	  if (IS_ENCLOSE_MARK1(NENCLOSE(node)))
+	    *min = 0;  /* recursive */
+	  else {
+	    SET_ENCLOSE_STATUS(node, NST_MARK1);
+	    r = get_min_match_length(en->target, min, env);
+	    CLEAR_ENCLOSE_STATUS(node, NST_MARK1);
+	    if (r == 0) {
+	      en->min_len = *min;
+	      SET_ENCLOSE_STATUS(node, NST_MIN_FIXED);
+	    }
+	  }
+        }
+        break;
+
+      case ENCLOSE_OPTION:
+      case ENCLOSE_STOP_BACKTRACK:
+      case ENCLOSE_CONDITION:
+	r = get_min_match_length(en->target, min, env);
+	break;
+
+      case ENCLOSE_ABSENT:
+	break;
+      }
+    }
+    break;
+
+  case NT_ANCHOR:
+  default:
+    break;
+  }
+
+  return r;
+}
+
+static int
+get_max_match_length(Node* node, OnigDistance *max, ScanEnv* env)
+{
+  OnigDistance tmax;
+  int r = 0;
+
+  *max = 0;
+  switch (NTYPE(node)) {
+  case NT_LIST:
+    do {
+      r = get_max_match_length(NCAR(node), &tmax, env);
+      if (r == 0)
+	*max = distance_add(*max, tmax);
+    } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
+    break;
+
+  case NT_ALT:
+    do {
+      r = get_max_match_length(NCAR(node), &tmax, env);
+      if (r == 0 && *max < tmax) *max = tmax;
+    } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
+    break;
+
+  case NT_STR:
+    {
+      StrNode* sn = NSTR(node);
+      *max = sn->end - sn->s;
+    }
+    break;
+
+  case NT_CTYPE:
+    *max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
+    break;
+
+  case NT_CCLASS:
+  case NT_CANY:
+    *max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
+    break;
+
+  case NT_BREF:
+    {
+      int i;
+      int* backs;
+      Node** nodes = SCANENV_MEM_NODES(env);
+      BRefNode* br = NBREF(node);
+      if (br->state & NST_RECURSION) {
+	*max = ONIG_INFINITE_DISTANCE;
+	break;
+      }
+      backs = BACKREFS_P(br);
+      for (i = 0; i < br->back_num; i++) {
+	if (backs[i] > env->num_mem)  return ONIGERR_INVALID_BACKREF;
+	r = get_max_match_length(nodes[backs[i]], &tmax, env);
+	if (r != 0) break;
+	if (*max < tmax) *max = tmax;
+      }
+    }
+    break;
+
+#ifdef USE_SUBEXP_CALL
+  case NT_CALL:
+    if (! IS_CALL_RECURSION(NCALL(node)))
+      r = get_max_match_length(NCALL(node)->target, max, env);
+    else
+      *max = ONIG_INFINITE_DISTANCE;
+    break;
+#endif
+
+  case NT_QTFR:
+    {
+      QtfrNode* qn = NQTFR(node);
+
+      if (qn->upper != 0) {
+	r = get_max_match_length(qn->target, max, env);
+	if (r == 0 && *max != 0) {
+	  if (! IS_REPEAT_INFINITE(qn->upper))
+	    *max = distance_multiply(*max, qn->upper);
+	  else
+	    *max = ONIG_INFINITE_DISTANCE;
+	}
+      }
+    }
+    break;
+
+  case NT_ENCLOSE:
+    {
+      EncloseNode* en = NENCLOSE(node);
+      switch (en->type) {
+      case ENCLOSE_MEMORY:
+	if (IS_ENCLOSE_MAX_FIXED(en))
+	  *max = en->max_len;
+	else {
+	  if (IS_ENCLOSE_MARK1(NENCLOSE(node)))
+	    *max = ONIG_INFINITE_DISTANCE;
+	  else {
+	    SET_ENCLOSE_STATUS(node, NST_MARK1);
+	    r = get_max_match_length(en->target, max, env);
+	    CLEAR_ENCLOSE_STATUS(node, NST_MARK1);
+	    if (r == 0) {
+	      en->max_len = *max;
+	      SET_ENCLOSE_STATUS(node, NST_MAX_FIXED);
+	    }
+	  }
+	}
+	break;
+
+      case ENCLOSE_OPTION:
+      case ENCLOSE_STOP_BACKTRACK:
+      case ENCLOSE_CONDITION:
+	r = get_max_match_length(en->target, max, env);
+	break;
+
+      case ENCLOSE_ABSENT:
+	break;
+      }
+    }
+    break;
+
+  case NT_ANCHOR:
+  default:
+    break;
+  }
+
+  return r;
+}
+
+#define GET_CHAR_LEN_VARLEN           -1
+#define GET_CHAR_LEN_TOP_ALT_VARLEN   -2
+
+/* fixed size pattern node only */
+static int
+get_char_length_tree1(Node* node, regex_t* reg, int* len, int level)
+{
+  int tlen;
+  int r = 0;
+
+  level++;
+  *len = 0;
+  switch (NTYPE(node)) {
+  case NT_LIST:
+    do {
+      r = get_char_length_tree1(NCAR(node), reg, &tlen, level);
+      if (r == 0)
+	*len = (int )distance_add(*len, tlen);
+    } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
+    break;
+
+  case NT_ALT:
+    {
+      int tlen2;
+      int varlen = 0;
+
+      r = get_char_length_tree1(NCAR(node), reg, &tlen, level);
+      while (r == 0 && IS_NOT_NULL(node = NCDR(node))) {
+	r = get_char_length_tree1(NCAR(node), reg, &tlen2, level);
+	if (r == 0) {
+	  if (tlen != tlen2)
+	    varlen = 1;
+	}
+      }
+      if (r == 0) {
+	if (varlen != 0) {
+	  if (level == 1)
+	    r = GET_CHAR_LEN_TOP_ALT_VARLEN;
+	  else
+	    r = GET_CHAR_LEN_VARLEN;
+	}
+	else
+	  *len = tlen;
+      }
+    }
+    break;
+
+  case NT_STR:
+    {
+      StrNode* sn = NSTR(node);
+      UChar *s = sn->s;
+      while (s < sn->end) {
+	s += enclen(reg->enc, s, sn->end);
+	(*len)++;
+      }
+    }
+    break;
+
+  case NT_QTFR:
+    {
+      QtfrNode* qn = NQTFR(node);
+      if (qn->lower == qn->upper) {
+	r = get_char_length_tree1(qn->target, reg, &tlen, level);
+	if (r == 0)
+	  *len = (int )distance_multiply(tlen, qn->lower);
+      }
+      else
+	r = GET_CHAR_LEN_VARLEN;
+    }
+    break;
+
+#ifdef USE_SUBEXP_CALL
+  case NT_CALL:
+    if (! IS_CALL_RECURSION(NCALL(node)))
+      r = get_char_length_tree1(NCALL(node)->target, reg, len, level);
+    else
+      r = GET_CHAR_LEN_VARLEN;
+    break;
+#endif
+
+  case NT_CTYPE:
+    *len = 1;
+    break;
+
+  case NT_CCLASS:
+  case NT_CANY:
+    *len = 1;
+    break;
+
+  case NT_ENCLOSE:
+    {
+      EncloseNode* en = NENCLOSE(node);
+      switch (en->type) {
+      case ENCLOSE_MEMORY:
+#ifdef USE_SUBEXP_CALL
+	if (IS_ENCLOSE_CLEN_FIXED(en))
+	  *len = en->char_len;
+	else {
+	  r = get_char_length_tree1(en->target, reg, len, level);
+	  if (r == 0) {
+	    en->char_len = *len;
+	    SET_ENCLOSE_STATUS(node, NST_CLEN_FIXED);
+	  }
+	}
+	break;
+#endif
+      case ENCLOSE_OPTION:
+      case ENCLOSE_STOP_BACKTRACK:
+      case ENCLOSE_CONDITION:
+	r = get_char_length_tree1(en->target, reg, len, level);
+	break;
+      case ENCLOSE_ABSENT:
+      default:
+	break;
+      }
+    }
+    break;
+
+  case NT_ANCHOR:
+    break;
+
+  default:
+    r = GET_CHAR_LEN_VARLEN;
+    break;
+  }
+
+  return r;
+}
+
+static int
+get_char_length_tree(Node* node, regex_t* reg, int* len)
+{
+  return get_char_length_tree1(node, reg, len, 0);
+}
+
+/* x is not included y ==>  1 : 0 */
+static int
+is_not_included(Node* x, Node* y, regex_t* reg)
+{
+  int i;
+  OnigDistance len;
+  OnigCodePoint code;
+  UChar *p;
+  int ytype;
+
+ retry:
+  ytype = NTYPE(y);
+  switch (NTYPE(x)) {
+  case NT_CTYPE:
+    {
+      switch (ytype) {
+      case NT_CTYPE:
+	if (NCTYPE(y)->ctype == NCTYPE(x)->ctype &&
+	    NCTYPE(y)->not   != NCTYPE(x)->not &&
+	    NCTYPE(y)->ascii_range == NCTYPE(x)->ascii_range)
+	  return 1;
+	else
+	  return 0;
+	break;
+
+      case NT_CCLASS:
+      swap:
+	{
+	  Node* tmp;
+	  tmp = x; x = y; y = tmp;
+	  goto retry;
+	}
+	break;
+
+      case NT_STR:
+	goto swap;
+	break;
+
+      default:
+	break;
+      }
+    }
+    break;
+
+  case NT_CCLASS:
+    {
+      CClassNode* xc = NCCLASS(x);
+      switch (ytype) {
+      case NT_CTYPE:
+	switch (NCTYPE(y)->ctype) {
+	case ONIGENC_CTYPE_WORD:
+	  if (NCTYPE(y)->not == 0) {
+	    if (IS_NULL(xc->mbuf) && !IS_NCCLASS_NOT(xc)) {
+	      for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
+		if (BITSET_AT(xc->bs, i)) {
+		  if (NCTYPE(y)->ascii_range) {
+		    if (IS_CODE_SB_WORD(reg->enc, i)) return 0;
+		  }
+		  else {
+		    if (ONIGENC_IS_CODE_WORD(reg->enc, i)) return 0;
+		  }
+		}
+	      }
+	      return 1;
+	    }
+	    return 0;
+	  }
+	  else {
+	    if (IS_NOT_NULL(xc->mbuf)) return 0;
+	    for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
+	      int is_word;
+	      if (NCTYPE(y)->ascii_range)
+		is_word = IS_CODE_SB_WORD(reg->enc, i);
+	      else
+		is_word = ONIGENC_IS_CODE_WORD(reg->enc, i);
+	      if (! is_word) {
+		if (!IS_NCCLASS_NOT(xc)) {
+		  if (BITSET_AT(xc->bs, i))
+		    return 0;
+		}
+		else {
+		  if (! BITSET_AT(xc->bs, i))
+		    return 0;
+		}
+	      }
+	    }
+	    return 1;
+	  }
+	  break;
+
+	default:
+	  break;
+	}
+	break;
+
+      case NT_CCLASS:
+	{
+	  int v;
+	  CClassNode* yc = NCCLASS(y);
+
+	  for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
+	    v = BITSET_AT(xc->bs, i);
+	    if ((v != 0 && !IS_NCCLASS_NOT(xc)) ||
+		(v == 0 && IS_NCCLASS_NOT(xc))) {
+	      v = BITSET_AT(yc->bs, i);
+	      if ((v != 0 && !IS_NCCLASS_NOT(yc)) ||
+		  (v == 0 && IS_NCCLASS_NOT(yc)))
+		return 0;
+	    }
+	  }
+	  if ((IS_NULL(xc->mbuf) && !IS_NCCLASS_NOT(xc)) ||
+	      (IS_NULL(yc->mbuf) && !IS_NCCLASS_NOT(yc)))
+	    return 1;
+	  return 0;
+	}
+	break;
+
+      case NT_STR:
+	goto swap;
+	break;
+
+      default:
+	break;
+      }
+    }
+    break;
+
+  case NT_STR:
+    {
+      StrNode* xs = NSTR(x);
+      if (NSTRING_LEN(x) == 0)
+	break;
+
+      switch (ytype) {
+      case NT_CTYPE:
+	switch (NCTYPE(y)->ctype) {
+	case ONIGENC_CTYPE_WORD:
+	  if (NCTYPE(y)->ascii_range) {
+	    if (ONIGENC_IS_MBC_ASCII_WORD(reg->enc, xs->s, xs->end))
+	      return NCTYPE(y)->not;
+	    else
+	      return !(NCTYPE(y)->not);
+	  }
+	  else {
+	    if (ONIGENC_IS_MBC_WORD(reg->enc, xs->s, xs->end))
+	      return NCTYPE(y)->not;
+	    else
+	      return !(NCTYPE(y)->not);
+	  }
+	  break;
+	default:
+	  break;
+	}
+	break;
+
+      case NT_CCLASS:
+	{
+	  CClassNode* cc = NCCLASS(y);
+
+	  code = ONIGENC_MBC_TO_CODE(reg->enc, xs->s,
+				     xs->s + ONIGENC_MBC_MAXLEN(reg->enc));
+	  return (onig_is_code_in_cc(reg->enc, code, cc) != 0 ? 0 : 1);
+	}
+	break;
+
+      case NT_STR:
+	{
+	  UChar *q;
+	  StrNode* ys = NSTR(y);
+	  len = NSTRING_LEN(x);
+	  if (len > NSTRING_LEN(y)) len = NSTRING_LEN(y);
+	  if (NSTRING_IS_AMBIG(x) || NSTRING_IS_AMBIG(y)) {
+	    /* tiny version */
+	    return 0;
+	  }
+	  else {
+	    for (i = 0, p = ys->s, q = xs->s; (OnigDistance )i < len; i++, p++, q++) {
+	      if (*p != *q) return 1;
+	    }
+	  }
+	}
+	break;
+
+      default:
+	break;
+      }
+    }
+    break;
+
+  default:
+    break;
+  }
+
+  return 0;
+}
+
+static Node*
+get_head_value_node(Node* node, int exact, regex_t* reg)
+{
+  Node* n = NULL_NODE;
+
+  switch (NTYPE(node)) {
+  case NT_BREF:
+  case NT_ALT:
+  case NT_CANY:
+#ifdef USE_SUBEXP_CALL
+  case NT_CALL:
+#endif
+    break;
+
+  case NT_CTYPE:
+  case NT_CCLASS:
+    if (exact == 0) {
+      n = node;
+    }
+    break;
+
+  case NT_LIST:
+    n = get_head_value_node(NCAR(node), exact, reg);
+    break;
+
+  case NT_STR:
+    {
+      StrNode* sn = NSTR(node);
+
+      if (sn->end <= sn->s)
+	break;
+
+      if (exact != 0 &&
+	  !NSTRING_IS_RAW(node) && IS_IGNORECASE(reg->options)) {
+      }
+      else {
+	n = node;
+      }
+    }
+    break;
+
+  case NT_QTFR:
+    {
+      QtfrNode* qn = NQTFR(node);
+      if (qn->lower > 0) {
+#ifdef USE_OP_PUSH_OR_JUMP_EXACT
+	if (IS_NOT_NULL(qn->head_exact))
+	  n = qn->head_exact;
+	else
+#endif
+	  n = get_head_value_node(qn->target, exact, reg);
+      }
+    }
+    break;
+
+  case NT_ENCLOSE:
+    {
+      EncloseNode* en = NENCLOSE(node);
+      switch (en->type) {
+      case ENCLOSE_OPTION:
+	{
+	  OnigOptionType options = reg->options;
+
+	  reg->options = NENCLOSE(node)->option;
+	  n = get_head_value_node(NENCLOSE(node)->target, exact, reg);
+	  reg->options = options;
+	}
+	break;
+
+      case ENCLOSE_MEMORY:
+      case ENCLOSE_STOP_BACKTRACK:
+      case ENCLOSE_CONDITION:
+	n = get_head_value_node(en->target, exact, reg);
+	break;
+
+      case ENCLOSE_ABSENT:
+	break;
+      }
+    }
+    break;
+
+  case NT_ANCHOR:
+    if (NANCHOR(node)->type == ANCHOR_PREC_READ)
+      n = get_head_value_node(NANCHOR(node)->target, exact, reg);
+    break;
+
+  default:
+    break;
+  }
+
+  return n;
+}
+
+static int
+check_type_tree(Node* node, int type_mask, int enclose_mask, int anchor_mask)
+{
+  int type, r = 0;
+
+  type = NTYPE(node);
+  if ((NTYPE2BIT(type) & type_mask) == 0)
+    return 1;
+
+  switch (type) {
+  case NT_LIST:
+  case NT_ALT:
+    do {
+      r = check_type_tree(NCAR(node), type_mask, enclose_mask,
+			  anchor_mask);
+    } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
+    break;
+
+  case NT_QTFR:
+    r = check_type_tree(NQTFR(node)->target, type_mask, enclose_mask,
+			anchor_mask);
+    break;
+
+  case NT_ENCLOSE:
+    {
+      EncloseNode* en = NENCLOSE(node);
+      if ((en->type & enclose_mask) == 0)
+	return 1;
+
+      r = check_type_tree(en->target, type_mask, enclose_mask, anchor_mask);
+    }
+    break;
+
+  case NT_ANCHOR:
+    type = NANCHOR(node)->type;
+    if ((type & anchor_mask) == 0)
+      return 1;
+
+    if (NANCHOR(node)->target)
+      r = check_type_tree(NANCHOR(node)->target,
+			  type_mask, enclose_mask, anchor_mask);
+    break;
+
+  default:
+    break;
+  }
+  return r;
+}
+
+#ifdef USE_SUBEXP_CALL
+
+# define RECURSION_EXIST       1
+# define RECURSION_INFINITE    2
+
+static int
+subexp_inf_recursive_check(Node* node, ScanEnv* env, int head)
+{
+  int type;
+  int r = 0;
+
+  type = NTYPE(node);
+  switch (type) {
+  case NT_LIST:
+    {
+      Node *x;
+      OnigDistance min;
+      int ret;
+
+      x = node;
+      do {
+	ret = subexp_inf_recursive_check(NCAR(x), env, head);
+	if (ret < 0 || ret == RECURSION_INFINITE) return ret;
+	r |= ret;
+	if (head) {
+	  ret = get_min_match_length(NCAR(x), &min, env);
+	  if (ret != 0) return ret;
+	  if (min != 0) head = 0;
+	}
+      } while (IS_NOT_NULL(x = NCDR(x)));
+    }
+    break;
+
+  case NT_ALT:
+    {
+      int ret;
+      r = RECURSION_EXIST;
+      do {
+	ret = subexp_inf_recursive_check(NCAR(node), env, head);
+	if (ret < 0 || ret == RECURSION_INFINITE) return ret;
+	r &= ret;
+      } while (IS_NOT_NULL(node = NCDR(node)));
+    }
+    break;
+
+  case NT_QTFR:
+    r = subexp_inf_recursive_check(NQTFR(node)->target, env, head);
+    if (r == RECURSION_EXIST) {
+      if (NQTFR(node)->lower == 0) r = 0;
+    }
+    break;
+
+  case NT_ANCHOR:
+    {
+      AnchorNode* an = NANCHOR(node);
+      switch (an->type) {
+      case ANCHOR_PREC_READ:
+      case ANCHOR_PREC_READ_NOT:
+      case ANCHOR_LOOK_BEHIND:
+      case ANCHOR_LOOK_BEHIND_NOT:
+	r = subexp_inf_recursive_check(an->target, env, head);
+	break;
+      }
+    }
+    break;
+
+  case NT_CALL:
+    r = subexp_inf_recursive_check(NCALL(node)->target, env, head);
+    break;
+
+  case NT_ENCLOSE:
+    if (IS_ENCLOSE_MARK2(NENCLOSE(node)))
+      return 0;
+    else if (IS_ENCLOSE_MARK1(NENCLOSE(node)))
+      return (head == 0 ? RECURSION_EXIST : RECURSION_INFINITE);
+    else {
+      SET_ENCLOSE_STATUS(node, NST_MARK2);
+      r = subexp_inf_recursive_check(NENCLOSE(node)->target, env, head);
+      CLEAR_ENCLOSE_STATUS(node, NST_MARK2);
+    }
+    break;
+
+  default:
+    break;
+  }
+
+  return r;
+}
+
+static int
+subexp_inf_recursive_check_trav(Node* node, ScanEnv* env)
+{
+  int type;
+  int r = 0;
+
+  type = NTYPE(node);
+  switch (type) {
+  case NT_LIST:
+  case NT_ALT:
+    do {
+      r = subexp_inf_recursive_check_trav(NCAR(node), env);
+    } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
+    break;
+
+  case NT_QTFR:
+    r = subexp_inf_recursive_check_trav(NQTFR(node)->target, env);
+    break;
+
+  case NT_ANCHOR:
+    {
+      AnchorNode* an = NANCHOR(node);
+      switch (an->type) {
+      case ANCHOR_PREC_READ:
+      case ANCHOR_PREC_READ_NOT:
+      case ANCHOR_LOOK_BEHIND:
+      case ANCHOR_LOOK_BEHIND_NOT:
+	r = subexp_inf_recursive_check_trav(an->target, env);
+	break;
+      }
+    }
+    break;
+
+  case NT_ENCLOSE:
+    {
+      EncloseNode* en = NENCLOSE(node);
+
+      if (IS_ENCLOSE_RECURSION(en)) {
+	SET_ENCLOSE_STATUS(node, NST_MARK1);
+	r = subexp_inf_recursive_check(en->target, env, 1);
+	if (r > 0) return ONIGERR_NEVER_ENDING_RECURSION;
+	CLEAR_ENCLOSE_STATUS(node, NST_MARK1);
+      }
+      r = subexp_inf_recursive_check_trav(en->target, env);
+    }
+
+    break;
+
+  default:
+    break;
+  }
+
+  return r;
+}
+
+static int
+subexp_recursive_check(Node* node)
+{
+  int r = 0;
+
+  switch (NTYPE(node)) {
+  case NT_LIST:
+  case NT_ALT:
+    do {
+      r |= subexp_recursive_check(NCAR(node));
+    } while (IS_NOT_NULL(node = NCDR(node)));
+    break;
+
+  case NT_QTFR:
+    r = subexp_recursive_check(NQTFR(node)->target);
+    break;
+
+  case NT_ANCHOR:
+    {
+      AnchorNode* an = NANCHOR(node);
+      switch (an->type) {
+      case ANCHOR_PREC_READ:
+      case ANCHOR_PREC_READ_NOT:
+      case ANCHOR_LOOK_BEHIND:
+      case ANCHOR_LOOK_BEHIND_NOT:
+	r = subexp_recursive_check(an->target);
+	break;
+      }
+    }
+    break;
+
+  case NT_CALL:
+    r = subexp_recursive_check(NCALL(node)->target);
+    if (r != 0) SET_CALL_RECURSION(node);
+    break;
+
+  case NT_ENCLOSE:
+    if (IS_ENCLOSE_MARK2(NENCLOSE(node)))
+      return 0;
+    else if (IS_ENCLOSE_MARK1(NENCLOSE(node)))
+      return 1; /* recursion */
+    else {
+      SET_ENCLOSE_STATUS(node, NST_MARK2);
+      r = subexp_recursive_check(NENCLOSE(node)->target);
+      CLEAR_ENCLOSE_STATUS(node, NST_MARK2);
+    }
+    break;
+
+  default:
+    break;
+  }
+
+  return r;
+}
+
+
+static int
+subexp_recursive_check_trav(Node* node, ScanEnv* env)
+{
+# define FOUND_CALLED_NODE    1
+
+  int type;
+  int r = 0;
+
+  type = NTYPE(node);
+  switch (type) {
+  case NT_LIST:
+  case NT_ALT:
+    {
+      int ret;
+      do {
+	ret = subexp_recursive_check_trav(NCAR(node), env);
+	if (ret == FOUND_CALLED_NODE) r = FOUND_CALLED_NODE;
+	else if (ret < 0) return ret;
+      } while (IS_NOT_NULL(node = NCDR(node)));
+    }
+    break;
+
+  case NT_QTFR:
+    r = subexp_recursive_check_trav(NQTFR(node)->target, env);
+    if (NQTFR(node)->upper == 0) {
+      if (r == FOUND_CALLED_NODE)
+	NQTFR(node)->is_refered = 1;
+    }
+    break;
+
+  case NT_ANCHOR:
+    {
+      AnchorNode* an = NANCHOR(node);
+      switch (an->type) {
+      case ANCHOR_PREC_READ:
+      case ANCHOR_PREC_READ_NOT:
+      case ANCHOR_LOOK_BEHIND:
+      case ANCHOR_LOOK_BEHIND_NOT:
+	r = subexp_recursive_check_trav(an->target, env);
+	break;
+      }
+    }
+    break;
+
+  case NT_ENCLOSE:
+    {
+      EncloseNode* en = NENCLOSE(node);
+
+      if (! IS_ENCLOSE_RECURSION(en)) {
+	if (IS_ENCLOSE_CALLED(en)) {
+	  SET_ENCLOSE_STATUS(node, NST_MARK1);
+	  r = subexp_recursive_check(en->target);
+	  if (r != 0) SET_ENCLOSE_STATUS(node, NST_RECURSION);
+	  CLEAR_ENCLOSE_STATUS(node, NST_MARK1);
+	}
+      }
+      r = subexp_recursive_check_trav(en->target, env);
+      if (IS_ENCLOSE_CALLED(en))
+	r |= FOUND_CALLED_NODE;
+    }
+    break;
+
+  default:
+    break;
+  }
+
+  return r;
+}
+
+static int
+setup_subexp_call(Node* node, ScanEnv* env)
+{
+  int type;
+  int r = 0;
+
+  type = NTYPE(node);
+  switch (type) {
+  case NT_LIST:
+    do {
+      r = setup_subexp_call(NCAR(node), env);
+    } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
+    break;
+
+  case NT_ALT:
+    do {
+      r = setup_subexp_call(NCAR(node), env);
+    } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
+    break;
+
+  case NT_QTFR:
+    r = setup_subexp_call(NQTFR(node)->target, env);
+    break;
+  case NT_ENCLOSE:
+    r = setup_subexp_call(NENCLOSE(node)->target, env);
+    break;
+
+  case NT_CALL:
+    {
+      CallNode* cn = NCALL(node);
+      Node** nodes = SCANENV_MEM_NODES(env);
+
+      if (cn->group_num != 0) {
+	int gnum = cn->group_num;
+
+# ifdef USE_NAMED_GROUP
+	if (env->num_named > 0 &&
+	    IS_SYNTAX_BV(env->syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) &&
+	    !ONIG_IS_OPTION_ON(env->option, ONIG_OPTION_CAPTURE_GROUP)) {
+	  return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;
+	}
+# endif
+	if (gnum > env->num_mem) {
+	  onig_scan_env_set_error_string(env,
+		 ONIGERR_UNDEFINED_GROUP_REFERENCE, cn->name, cn->name_end);
+	  return ONIGERR_UNDEFINED_GROUP_REFERENCE;
+	}
+
+# ifdef USE_NAMED_GROUP
+      set_call_attr:
+# endif
+	cn->target = nodes[cn->group_num];
+	if (IS_NULL(cn->target)) {
+	  onig_scan_env_set_error_string(env,
+		 ONIGERR_UNDEFINED_NAME_REFERENCE, cn->name, cn->name_end);
+	  return ONIGERR_UNDEFINED_NAME_REFERENCE;
+	}
+	SET_ENCLOSE_STATUS(cn->target, NST_CALLED);
+	BIT_STATUS_ON_AT(env->bt_mem_start, cn->group_num);
+	cn->unset_addr_list = env->unset_addr_list;
+      }
+# ifdef USE_NAMED_GROUP
+#  ifdef USE_PERL_SUBEXP_CALL
+      else if (cn->name == cn->name_end) {
+	goto set_call_attr;
+      }
+#  endif
+      else {
+	int *refs;
+
+	int n = onig_name_to_group_numbers(env->reg, cn->name, cn->name_end,
+					   &refs);
+	if (n <= 0) {
+	  onig_scan_env_set_error_string(env,
+		 ONIGERR_UNDEFINED_NAME_REFERENCE, cn->name, cn->name_end);
+	  return ONIGERR_UNDEFINED_NAME_REFERENCE;
+	}
+	else if (n > 1 &&
+	    ! IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME_CALL)) {
+	  onig_scan_env_set_error_string(env,
+	    ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL, cn->name, cn->name_end);
+	  return ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL;
+	}
+	else {
+	  cn->group_num = refs[0];
+	  goto set_call_attr;
+	}
+      }
+# endif
+    }
+    break;
+
+  case NT_ANCHOR:
+    {
+      AnchorNode* an = NANCHOR(node);
+
+      switch (an->type) {
+      case ANCHOR_PREC_READ:
+      case ANCHOR_PREC_READ_NOT:
+      case ANCHOR_LOOK_BEHIND:
+      case ANCHOR_LOOK_BEHIND_NOT:
+	r = setup_subexp_call(an->target, env);
+	break;
+      }
+    }
+    break;
+
+  default:
+    break;
+  }
+
+  return r;
+}
+#endif
+
+/* divide different length alternatives in look-behind.
+  (?<=A|B) ==> (?<=A)|(?<=B)
+  (?<!A|B) ==> (?<!A)(?<!B)
+*/
+static int
+divide_look_behind_alternatives(Node* node)
+{
+  Node *head, *np, *insert_node;
+  AnchorNode* an = NANCHOR(node);
+  int anc_type = an->type;
+
+  head = an->target;
+  np = NCAR(head);
+  swap_node(node, head);
+  NCAR(node) = head;
+  NANCHOR(head)->target = np;
+
+  np = node;
+  while ((np = NCDR(np)) != NULL_NODE) {
+    insert_node = onig_node_new_anchor(anc_type);
+    CHECK_NULL_RETURN_MEMERR(insert_node);
+    NANCHOR(insert_node)->target = NCAR(np);
+    NCAR(np) = insert_node;
+  }
+
+  if (anc_type == ANCHOR_LOOK_BEHIND_NOT) {
+    np = node;
+    do {
+      SET_NTYPE(np, NT_LIST);  /* alt -> list */
+    } while ((np = NCDR(np)) != NULL_NODE);
+  }
+  return 0;
+}
+
+static int
+setup_look_behind(Node* node, regex_t* reg, ScanEnv* env)
+{
+  int r, len;
+  AnchorNode* an = NANCHOR(node);
+
+  r = get_char_length_tree(an->target, reg, &len);
+  if (r == 0)
+    an->char_len = len;
+  else if (r == GET_CHAR_LEN_VARLEN)
+    r = ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
+  else if (r == GET_CHAR_LEN_TOP_ALT_VARLEN) {
+    if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND))
+      r = divide_look_behind_alternatives(node);
+    else
+      r = ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
+  }
+
+  return r;
+}
+
+static int
+next_setup(Node* node, Node* next_node, regex_t* reg)
+{
+  int type;
+
+ retry:
+  type = NTYPE(node);
+  if (type == NT_QTFR) {
+    QtfrNode* qn = NQTFR(node);
+    if (qn->greedy && IS_REPEAT_INFINITE(qn->upper)) {
+#ifdef USE_QTFR_PEEK_NEXT
+      Node* n = get_head_value_node(next_node, 1, reg);
+      /* '\0': for UTF-16BE etc... */
+      if (IS_NOT_NULL(n) && NSTR(n)->s[0] != '\0') {
+	qn->next_head_exact = n;
+      }
+#endif
+      /* automatic possessification a*b ==> (?>a*)b */
+      if (qn->lower <= 1) {
+	int ttype = NTYPE(qn->target);
+	if (IS_NODE_TYPE_SIMPLE(ttype)) {
+	  Node *x, *y;
+	  x = get_head_value_node(qn->target, 0, reg);
+	  if (IS_NOT_NULL(x)) {
+	    y = get_head_value_node(next_node,  0, reg);
+	    if (IS_NOT_NULL(y) && is_not_included(x, y, reg)) {
+	      Node* en = onig_node_new_enclose(ENCLOSE_STOP_BACKTRACK);
+	      CHECK_NULL_RETURN_MEMERR(en);
+	      SET_ENCLOSE_STATUS(en, NST_STOP_BT_SIMPLE_REPEAT);
+	      swap_node(node, en);
+	      NENCLOSE(node)->target = en;
+	    }
+	  }
+	}
+      }
+    }
+  }
+  else if (type == NT_ENCLOSE) {
+    EncloseNode* en = NENCLOSE(node);
+    if (en->type == ENCLOSE_MEMORY) {
+      node = en->target;
+      goto retry;
+    }
+  }
+  return 0;
+}
+
+
+static int
+update_string_node_case_fold(regex_t* reg, Node *node)
+{
+  UChar *p, *end, buf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
+  UChar *sbuf, *ebuf, *sp;
+  int r, i, len;
+  OnigDistance sbuf_size;
+  StrNode* sn = NSTR(node);
+
+  end = sn->end;
+  sbuf_size = (end - sn->s) * 2;
+  sbuf = (UChar* )xmalloc(sbuf_size);
+  CHECK_NULL_RETURN_MEMERR(sbuf);
+  ebuf = sbuf + sbuf_size;
+
+  sp = sbuf;
+  p = sn->s;
+  while (p < end) {
+    len = ONIGENC_MBC_CASE_FOLD(reg->enc, reg->case_fold_flag, &p, end, buf);
+    for (i = 0; i < len; i++) {
+      if (sp >= ebuf) {
+	UChar* p = (UChar* )xrealloc(sbuf, sbuf_size * 2);
+	if (IS_NULL(p)) {
+	  xfree(sbuf);
+	  return ONIGERR_MEMORY;
+	}
+	sbuf = p;
+	sp = sbuf + sbuf_size;
+	sbuf_size *= 2;
+	ebuf = sbuf + sbuf_size;
+      }
+
+      *sp++ = buf[i];
+    }
+  }
+
+  r = onig_node_str_set(node, sbuf, sp);
+
+  xfree(sbuf);
+  return r;
+}
+
+static int
+expand_case_fold_make_rem_string(Node** rnode, UChar *s, UChar *end,
+				 regex_t* reg)
+{
+  int r;
+  Node *node;
+
+  node = onig_node_new_str(s, end);
+  if (IS_NULL(node)) return ONIGERR_MEMORY;
+
+  r = update_string_node_case_fold(reg, node);
+  if (r != 0) {
+    onig_node_free(node);
+    return r;
+  }
+
+  NSTRING_SET_AMBIG(node);
+  NSTRING_SET_DONT_GET_OPT_INFO(node);
+  *rnode = node;
+  return 0;
+}
+
+static int
+is_case_fold_variable_len(int item_num, OnigCaseFoldCodeItem items[],
+			  int slen)
+{
+  int i;
+
+  for (i = 0; i < item_num; i++) {
+    if (items[i].byte_len != slen) {
+      return 1;
+    }
+    if (items[i].code_len != 1) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+static int
+expand_case_fold_string_alt(int item_num, OnigCaseFoldCodeItem items[],
+			    UChar *p, int slen, UChar *end,
+			    regex_t* reg, Node **rnode)
+{
+  int r, i, j, len, varlen;
+  Node *anode, *var_anode, *snode, *xnode, *an;
+  UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
+
+  *rnode = var_anode = NULL_NODE;
+
+  varlen = 0;
+  for (i = 0; i < item_num; i++) {
+    if (items[i].byte_len != slen) {
+      varlen = 1;
+      break;
+    }
+  }
+
+  if (varlen != 0) {
+    *rnode = var_anode = onig_node_new_alt(NULL_NODE, NULL_NODE);
+    if (IS_NULL(var_anode)) return ONIGERR_MEMORY;
+
+    xnode = onig_node_new_list(NULL, NULL);
+    if (IS_NULL(xnode)) goto mem_err;
+    NCAR(var_anode) = xnode;
+
+    anode = onig_node_new_alt(NULL_NODE, NULL_NODE);
+    if (IS_NULL(anode)) goto mem_err;
+    NCAR(xnode) = anode;
+  }
+  else {
+    *rnode = anode = onig_node_new_alt(NULL_NODE, NULL_NODE);
+    if (IS_NULL(anode)) return ONIGERR_MEMORY;
+  }
+
+  snode = onig_node_new_str(p, p + slen);
+  if (IS_NULL(snode)) goto mem_err;
+
+  NCAR(anode) = snode;
+
+  for (i = 0; i < item_num; i++) {
+    snode = onig_node_new_str(NULL, NULL);
+    if (IS_NULL(snode)) goto mem_err;
+
+    for (j = 0; j < items[i].code_len; j++) {
+      len = ONIGENC_CODE_TO_MBC(reg->enc, items[i].code[j], buf);
+      if (len < 0) {
+	r = len;
+	goto mem_err2;
+      }
+
+      r = onig_node_str_cat(snode, buf, buf + len);
+      if (r != 0) goto mem_err2;
+    }
+
+    an = onig_node_new_alt(NULL_NODE, NULL_NODE);
+    if (IS_NULL(an)) {
+      goto mem_err2;
+    }
+
+    if (items[i].byte_len != slen) {
+      Node *rem;
+      UChar *q = p + items[i].byte_len;
+
+      if (q < end) {
+	r = expand_case_fold_make_rem_string(&rem, q, end, reg);
+	if (r != 0) {
+	  onig_node_free(an);
+	  goto mem_err2;
+	}
+
+	xnode = onig_node_list_add(NULL_NODE, snode);
+	if (IS_NULL(xnode)) {
+	  onig_node_free(an);
+	  onig_node_free(rem);
+	  goto mem_err2;
+	}
+	if (IS_NULL(onig_node_list_add(xnode, rem))) {
+	  onig_node_free(an);
+	  onig_node_free(xnode);
+	  onig_node_free(rem);
+	  goto mem_err;
+	}
+
+	NCAR(an) = xnode;
+      }
+      else {
+	NCAR(an) = snode;
+      }
+
+      NCDR(var_anode) = an;
+      var_anode = an;
+    }
+    else {
+      NCAR(an)     = snode;
+      NCDR(anode) = an;
+      anode = an;
+    }
+  }
+
+  return varlen;
+
+ mem_err2:
+  onig_node_free(snode);
+
+ mem_err:
+  onig_node_free(*rnode);
+
+  return ONIGERR_MEMORY;
+}
+
+static int
+expand_case_fold_string(Node* node, regex_t* reg)
+{
+#define THRESHOLD_CASE_FOLD_ALT_FOR_EXPANSION  8
+
+  int r, n, len, alt_num;
+  int varlen = 0;
+  UChar *start, *end, *p;
+  Node *top_root, *root, *snode, *prev_node;
+  OnigCaseFoldCodeItem items[ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM];
+  StrNode* sn = NSTR(node);
+
+  if (NSTRING_IS_AMBIG(node)) return 0;
+
+  start = sn->s;
+  end   = sn->end;
+  if (start >= end) return 0;
+
+  r = 0;
+  top_root = root = prev_node = snode = NULL_NODE;
+  alt_num = 1;
+  p = start;
+  while (p < end) {
+    n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(reg->enc, reg->case_fold_flag,
+					   p, end, items);
+    if (n < 0) {
+      r = n;
+      goto err;
+    }
+
+    len = enclen(reg->enc, p, end);
+
+    varlen = is_case_fold_variable_len(n, items, len);
+    if (n == 0 || varlen == 0) {
+      if (IS_NULL(snode)) {
+	if (IS_NULL(root) && IS_NOT_NULL(prev_node)) {
+	  top_root = root = onig_node_list_add(NULL_NODE, prev_node);
+	  if (IS_NULL(root)) {
+	    onig_node_free(prev_node);
+	    goto mem_err;
+	  }
+	}
+
+	prev_node = snode = onig_node_new_str(NULL, NULL);
+	if (IS_NULL(snode)) goto mem_err;
+	if (IS_NOT_NULL(root)) {
+	  if (IS_NULL(onig_node_list_add(root, snode))) {
+	    onig_node_free(snode);
+	    goto mem_err;
+	  }
+	}
+      }
+
+      r = onig_node_str_cat(snode, p, p + len);
+      if (r != 0) goto err;
+    }
+    else {
+      alt_num *= (n + 1);
+      if (alt_num > THRESHOLD_CASE_FOLD_ALT_FOR_EXPANSION) break;
+
+      if (IS_NOT_NULL(snode)) {
+	r = update_string_node_case_fold(reg, snode);
+	if (r == 0) {
+	  NSTRING_SET_AMBIG(snode);
+	}
+      }
+      if (IS_NULL(root) && IS_NOT_NULL(prev_node)) {
+	top_root = root = onig_node_list_add(NULL_NODE, prev_node);
+	if (IS_NULL(root)) {
+	  onig_node_free(prev_node);
+	  goto mem_err;
+	}
+      }
+
+      r = expand_case_fold_string_alt(n, items, p, len, end, reg, &prev_node);
+      if (r < 0) goto mem_err;
+      if (r == 1) {
+	if (IS_NULL(root)) {
+	  top_root = prev_node;
+	}
+	else {
+	  if (IS_NULL(onig_node_list_add(root, prev_node))) {
+	    onig_node_free(prev_node);
+	    goto mem_err;
+	  }
+	}
+
+	root = NCAR(prev_node);
+      }
+      else { /* r == 0 */
+	if (IS_NOT_NULL(root)) {
+	  if (IS_NULL(onig_node_list_add(root, prev_node))) {
+	    onig_node_free(prev_node);
+	    goto mem_err;
+	  }
+	}
+      }
+
+      snode = NULL_NODE;
+    }
+
+    p += len;
+  }
+  if (IS_NOT_NULL(snode)) {
+    r = update_string_node_case_fold(reg, snode);
+    if (r == 0) {
+      NSTRING_SET_AMBIG(snode);
+    }
+  }
+
+  if (p < end) {
+    Node *srem;
+
+    r = expand_case_fold_make_rem_string(&srem, p, end, reg);
+    if (r != 0) goto mem_err;
+
+    if (IS_NOT_NULL(prev_node) && IS_NULL(root)) {
+      top_root = root = onig_node_list_add(NULL_NODE, prev_node);
+      if (IS_NULL(root)) {
+	onig_node_free(srem);
+	onig_node_free(prev_node);
+	goto mem_err;
+      }
+    }
+
+    if (IS_NULL(root)) {
+      prev_node = srem;
+    }
+    else {
+      if (IS_NULL(onig_node_list_add(root, srem))) {
+	onig_node_free(srem);
+	goto mem_err;
+      }
+    }
+  }
+
+  /* ending */
+  top_root = (IS_NOT_NULL(top_root) ? top_root : prev_node);
+  swap_node(node, top_root);
+  onig_node_free(top_root);
+  return 0;
+
+ mem_err:
+  r = ONIGERR_MEMORY;
+
+ err:
+  onig_node_free(top_root);
+  return r;
+}
+
+
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+
+# define CEC_THRES_NUM_BIG_REPEAT         512
+# define CEC_INFINITE_NUM          0x7fffffff
+
+# define CEC_IN_INFINITE_REPEAT    (1<<0)
+# define CEC_IN_FINITE_REPEAT      (1<<1)
+# define CEC_CONT_BIG_REPEAT       (1<<2)
+
+static int
+setup_comb_exp_check(Node* node, int state, ScanEnv* env)
+{
+  int type;
+  int r = state;
+
+  type = NTYPE(node);
+  switch (type) {
+  case NT_LIST:
+    {
+      Node* prev = NULL_NODE;
+      do {
+	r = setup_comb_exp_check(NCAR(node), r, env);
+	prev = NCAR(node);
+      } while (r >= 0 && IS_NOT_NULL(node = NCDR(node)));
+    }
+    break;
+
+  case NT_ALT:
+    {
+      int ret;
+      do {
+	ret = setup_comb_exp_check(NCAR(node), state, env);
+	r |= ret;
+      } while (ret >= 0 && IS_NOT_NULL(node = NCDR(node)));
+    }
+    break;
+
+  case NT_QTFR:
+    {
+      int child_state = state;
+      int add_state = 0;
+      QtfrNode* qn = NQTFR(node);
+      Node* target = qn->target;
+      int var_num;
+
+      if (! IS_REPEAT_INFINITE(qn->upper)) {
+	if (qn->upper > 1) {
+	  /* {0,1}, {1,1} are allowed */
+	  child_state |= CEC_IN_FINITE_REPEAT;
+
+	  /* check (a*){n,m}, (a+){n,m} => (a*){n,n}, (a+){n,n} */
+	  if (env->backrefed_mem == 0) {
+	    if (NTYPE(qn->target) == NT_ENCLOSE) {
+	      EncloseNode* en = NENCLOSE(qn->target);
+	      if (en->type == ENCLOSE_MEMORY) {
+		if (NTYPE(en->target) == NT_QTFR) {
+		  QtfrNode* q = NQTFR(en->target);
+		  if (IS_REPEAT_INFINITE(q->upper)
+		      && q->greedy == qn->greedy) {
+		    qn->upper = (qn->lower == 0 ? 1 : qn->lower);
+		    if (qn->upper == 1)
+		      child_state = state;
+		  }
+		}
+	      }
+	    }
+	  }
+	}
+      }
+
+      if (state & CEC_IN_FINITE_REPEAT) {
+	qn->comb_exp_check_num = -1;
+      }
+      else {
+	if (IS_REPEAT_INFINITE(qn->upper)) {
+	  var_num = CEC_INFINITE_NUM;
+	  child_state |= CEC_IN_INFINITE_REPEAT;
+	}
+	else {
+	  var_num = qn->upper - qn->lower;
+	}
+
+	if (var_num >= CEC_THRES_NUM_BIG_REPEAT)
+	  add_state |= CEC_CONT_BIG_REPEAT;
+
+	if (((state & CEC_IN_INFINITE_REPEAT) != 0 && var_num != 0) ||
+	    ((state & CEC_CONT_BIG_REPEAT) != 0 &&
+	     var_num >= CEC_THRES_NUM_BIG_REPEAT)) {
+	  if (qn->comb_exp_check_num == 0) {
+	    env->num_comb_exp_check++;
+	    qn->comb_exp_check_num = env->num_comb_exp_check;
+	    if (env->curr_max_regnum > env->comb_exp_max_regnum)
+	      env->comb_exp_max_regnum = env->curr_max_regnum;
+	  }
+	}
+      }
+
+      r = setup_comb_exp_check(target, child_state, env);
+      r |= add_state;
+    }
+    break;
+
+  case NT_ENCLOSE:
+    {
+      EncloseNode* en = NENCLOSE(node);
+
+      switch (en->type) {
+      case ENCLOSE_MEMORY:
+	{
+	  if (env->curr_max_regnum < en->regnum)
+	    env->curr_max_regnum = en->regnum;
+
+	  r = setup_comb_exp_check(en->target, state, env);
+	}
+	break;
+
+      default:
+	r = setup_comb_exp_check(en->target, state, env);
+	break;
+      }
+    }
+    break;
+
+# ifdef USE_SUBEXP_CALL
+  case NT_CALL:
+    if (IS_CALL_RECURSION(NCALL(node)))
+      env->has_recursion = 1;
+    else
+      r = setup_comb_exp_check(NCALL(node)->target, state, env);
+    break;
+# endif
+
+  default:
+    break;
+  }
+
+  return r;
+}
+#endif
+
+#define IN_ALT        (1<<0)
+#define IN_NOT        (1<<1)
+#define IN_REPEAT     (1<<2)
+#define IN_VAR_REPEAT (1<<3)
+#define IN_CALL       (1<<4)
+#define IN_RECCALL    (1<<5)
+
+/* setup_tree does the following work.
+ 1. check empty loop. (set qn->target_empty_info)
+ 2. expand ignore-case in char class.
+ 3. set memory status bit flags. (reg->mem_stats)
+ 4. set qn->head_exact for [push, exact] -> [push_or_jump_exact1, exact].
+ 5. find invalid patterns in look-behind.
+ 6. expand repeated string.
+ */
+static int
+setup_tree(Node* node, regex_t* reg, int state, ScanEnv* env)
+{
+  int type;
+  int r = 0;
+
+restart:
+  type = NTYPE(node);
+  switch (type) {
+  case NT_LIST:
+    {
+      Node* prev = NULL_NODE;
+      do {
+	r = setup_tree(NCAR(node), reg, state, env);
+	if (IS_NOT_NULL(prev) && r == 0) {
+	  r = next_setup(prev, NCAR(node), reg);
+	}
+	prev = NCAR(node);
+      } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
+    }
+    break;
+
+  case NT_ALT:
+    do {
+      r = setup_tree(NCAR(node), reg, (state | IN_ALT), env);
+    } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
+    break;
+
+  case NT_CCLASS:
+    break;
+
+  case NT_STR:
+    if (IS_IGNORECASE(reg->options) && !NSTRING_IS_RAW(node)) {
+      r = expand_case_fold_string(node, reg);
+    }
+    break;
+
+  case NT_CTYPE:
+  case NT_CANY:
+    break;
+
+#ifdef USE_SUBEXP_CALL
+  case NT_CALL:
+    break;
+#endif
+
+  case NT_BREF:
+    {
+      int i;
+      int* p;
+      Node** nodes = SCANENV_MEM_NODES(env);
+      BRefNode* br = NBREF(node);
+      p = BACKREFS_P(br);
+      for (i = 0; i < br->back_num; i++) {
+	if (p[i] > env->num_mem)  return ONIGERR_INVALID_BACKREF;
+	BIT_STATUS_ON_AT(env->backrefed_mem, p[i]);
+	BIT_STATUS_ON_AT(env->bt_mem_start, p[i]);
+#ifdef USE_BACKREF_WITH_LEVEL
+	if (IS_BACKREF_NEST_LEVEL(br)) {
+	  BIT_STATUS_ON_AT(env->bt_mem_end, p[i]);
+	}
+#endif
+	SET_ENCLOSE_STATUS(nodes[p[i]], NST_MEM_BACKREFED);
+      }
+    }
+    break;
+
+  case NT_QTFR:
+    {
+      OnigDistance d;
+      QtfrNode* qn = NQTFR(node);
+      Node* target = qn->target;
+
+      if ((state & IN_REPEAT) != 0) {
+	qn->state |= NST_IN_REPEAT;
+      }
+
+      if (IS_REPEAT_INFINITE(qn->upper) || qn->upper >= 1) {
+	r = get_min_match_length(target, &d, env);
+	if (r) break;
+	if (d == 0) {
+	  qn->target_empty_info = NQ_TARGET_IS_EMPTY;
+#ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
+	  r = quantifiers_memory_node_info(target);
+	  if (r < 0) break;
+	  if (r > 0) {
+	    qn->target_empty_info = r;
+	  }
+#endif
+#if 0
+	  r = get_max_match_length(target, &d, env);
+	  if (r == 0 && d == 0) {
+	    /*  ()* ==> ()?, ()+ ==> ()  */
+	    qn->upper = 1;
+	    if (qn->lower > 1) qn->lower = 1;
+	    if (NTYPE(target) == NT_STR) {
+	      qn->upper = qn->lower = 0;  /* /(?:)+/ ==> // */
+	    }
+	  }
+#endif
+	}
+      }
+
+      state |= IN_REPEAT;
+      if (qn->lower != qn->upper)
+	state |= IN_VAR_REPEAT;
+      r = setup_tree(target, reg, state, env);
+      if (r) break;
+
+      /* expand string */
+#define EXPAND_STRING_MAX_LENGTH  100
+      if (NTYPE(target) == NT_STR) {
+	if (qn->lower > 1) {
+	  int i, n = qn->lower;
+	  OnigDistance len = NSTRING_LEN(target);
+	  StrNode* sn = NSTR(target);
+	  Node* np;
+
+	  np = onig_node_new_str(sn->s, sn->end);
+	  if (IS_NULL(np)) return ONIGERR_MEMORY;
+	  NSTR(np)->flag = sn->flag;
+
+	  for (i = 1; i < n && (i+1) * len <= EXPAND_STRING_MAX_LENGTH; i++) {
+	    r = onig_node_str_cat(np, sn->s, sn->end);
+	    if (r) {
+	      onig_node_free(np);
+	      return r;
+	    }
+	  }
+	  if (i < qn->upper || IS_REPEAT_INFINITE(qn->upper)) {
+	    Node *np1, *np2;
+
+	    qn->lower -= i;
+	    if (! IS_REPEAT_INFINITE(qn->upper))
+	      qn->upper -= i;
+
+	    np1 = onig_node_new_list(np, NULL);
+	    if (IS_NULL(np1)) {
+	      onig_node_free(np);
+	      return ONIGERR_MEMORY;
+	    }
+	    swap_node(np1, node);
+	    np2 = onig_node_list_add(node, np1);
+	    if (IS_NULL(np2)) {
+	      onig_node_free(np1);
+	      return ONIGERR_MEMORY;
+	    }
+	  }
+	  else {
+	    swap_node(np, node);
+	    onig_node_free(np);
+	  }
+	  break; /* break case NT_QTFR: */
+	}
+      }
+
+#ifdef USE_OP_PUSH_OR_JUMP_EXACT
+      if (qn->greedy && (qn->target_empty_info != 0)) {
+	if (NTYPE(target) == NT_QTFR) {
+	  QtfrNode* tqn = NQTFR(target);
+	  if (IS_NOT_NULL(tqn->head_exact)) {
+	    qn->head_exact  = tqn->head_exact;
+	    tqn->head_exact = NULL;
+	  }
+	}
+	else {
+	  qn->head_exact = get_head_value_node(qn->target, 1, reg);
+	}
+      }
+#endif
+    }
+    break;
+
+  case NT_ENCLOSE:
+    {
+      EncloseNode* en = NENCLOSE(node);
+
+      switch (en->type) {
+      case ENCLOSE_OPTION:
+	{
+	  OnigOptionType options = reg->options;
+	  reg->options = NENCLOSE(node)->option;
+	  r = setup_tree(NENCLOSE(node)->target, reg, state, env);
+	  reg->options = options;
+	}
+	break;
+
+      case ENCLOSE_MEMORY:
+	if ((state & (IN_ALT | IN_NOT | IN_VAR_REPEAT | IN_CALL)) != 0) {
+	  BIT_STATUS_ON_AT(env->bt_mem_start, en->regnum);
+	  /* SET_ENCLOSE_STATUS(node, NST_MEM_IN_ALT_NOT); */
+	}
+	if (IS_ENCLOSE_CALLED(en))
+	  state |= IN_CALL;
+	if (IS_ENCLOSE_RECURSION(en))
+	  state |= IN_RECCALL;
+	else if ((state & IN_RECCALL) != 0)
+	  SET_CALL_RECURSION(node);
+	r = setup_tree(en->target, reg, state, env);
+	break;
+
+      case ENCLOSE_STOP_BACKTRACK:
+	{
+	  Node* target = en->target;
+	  r = setup_tree(target, reg, state, env);
+	  if (NTYPE(target) == NT_QTFR) {
+	    QtfrNode* tqn = NQTFR(target);
+	    if (IS_REPEAT_INFINITE(tqn->upper) && tqn->lower <= 1 &&
+		tqn->greedy != 0) {  /* (?>a*), a*+ etc... */
+	      int qtype = NTYPE(tqn->target);
+	      if (IS_NODE_TYPE_SIMPLE(qtype))
+		SET_ENCLOSE_STATUS(node, NST_STOP_BT_SIMPLE_REPEAT);
+	    }
+	  }
+	}
+	break;
+
+      case ENCLOSE_CONDITION:
+#ifdef USE_NAMED_GROUP
+	if (! IS_ENCLOSE_NAME_REF(NENCLOSE(node)) &&
+	    env->num_named > 0 &&
+	    IS_SYNTAX_BV(env->syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) &&
+	    !ONIG_IS_OPTION_ON(env->option, ONIG_OPTION_CAPTURE_GROUP)) {
+	  return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;
+	}
+#endif
+	if (NENCLOSE(node)->regnum > env->num_mem)
+	  return ONIGERR_INVALID_BACKREF;
+	r = setup_tree(NENCLOSE(node)->target, reg, state, env);
+	break;
+
+      case ENCLOSE_ABSENT:
+	r = setup_tree(NENCLOSE(node)->target, reg, state, env);
+	break;
+      }
+    }
+    break;
+
+  case NT_ANCHOR:
+    {
+      AnchorNode* an = NANCHOR(node);
+
+      switch (an->type) {
+      case ANCHOR_PREC_READ:
+	r = setup_tree(an->target, reg, state, env);
+	break;
+      case ANCHOR_PREC_READ_NOT:
+	r = setup_tree(an->target, reg, (state | IN_NOT), env);
+	break;
+
+/* allowed node types in look-behind */
+#define ALLOWED_TYPE_IN_LB  \
+  ( BIT_NT_LIST | BIT_NT_ALT | BIT_NT_STR | BIT_NT_CCLASS | BIT_NT_CTYPE | \
+    BIT_NT_CANY | BIT_NT_ANCHOR | BIT_NT_ENCLOSE | BIT_NT_QTFR | BIT_NT_CALL )
+
+#define ALLOWED_ENCLOSE_IN_LB       ( ENCLOSE_MEMORY | ENCLOSE_OPTION )
+#define ALLOWED_ENCLOSE_IN_LB_NOT   ENCLOSE_OPTION
+
+#define ALLOWED_ANCHOR_IN_LB \
+( ANCHOR_LOOK_BEHIND | ANCHOR_LOOK_BEHIND_NOT | ANCHOR_BEGIN_LINE | \
+  ANCHOR_END_LINE | ANCHOR_BEGIN_BUF | ANCHOR_BEGIN_POSITION | ANCHOR_KEEP | \
+  ANCHOR_WORD_BOUND | ANCHOR_NOT_WORD_BOUND | \
+  ANCHOR_WORD_BEGIN | ANCHOR_WORD_END )
+#define ALLOWED_ANCHOR_IN_LB_NOT \
+( ANCHOR_LOOK_BEHIND | ANCHOR_LOOK_BEHIND_NOT | ANCHOR_BEGIN_LINE | \
+  ANCHOR_END_LINE | ANCHOR_BEGIN_BUF | ANCHOR_BEGIN_POSITION | ANCHOR_KEEP | \
+  ANCHOR_WORD_BOUND | ANCHOR_NOT_WORD_BOUND | \
+  ANCHOR_WORD_BEGIN | ANCHOR_WORD_END )
+
+      case ANCHOR_LOOK_BEHIND:
+	{
+	  r = check_type_tree(an->target, ALLOWED_TYPE_IN_LB,
+			      ALLOWED_ENCLOSE_IN_LB, ALLOWED_ANCHOR_IN_LB);
+	  if (r < 0) return r;
+	  if (r > 0) return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
+	  if (NTYPE(node) != NT_ANCHOR) goto restart;
+	  r = setup_tree(an->target, reg, state, env);
+	  if (r != 0) return r;
+	  r = setup_look_behind(node, reg, env);
+	}
+	break;
+
+      case ANCHOR_LOOK_BEHIND_NOT:
+	{
+	  r = check_type_tree(an->target, ALLOWED_TYPE_IN_LB,
+		      ALLOWED_ENCLOSE_IN_LB_NOT, ALLOWED_ANCHOR_IN_LB_NOT);
+	  if (r < 0) return r;
+	  if (r > 0) return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
+	  if (NTYPE(node) != NT_ANCHOR) goto restart;
+	  r = setup_tree(an->target, reg, (state | IN_NOT), env);
+	  if (r != 0) return r;
+	  r = setup_look_behind(node, reg, env);
+	}
+	break;
+      }
+    }
+    break;
+
+  default:
+    break;
+  }
+
+  return r;
+}
+
+#ifndef USE_SUNDAY_QUICK_SEARCH
+/* set skip map for Boyer-Moore search */
+static int
+set_bm_skip(UChar* s, UChar* end, regex_t* reg,
+	    UChar skip[], int** int_skip, int ignore_case)
+{
+  OnigDistance i, len;
+  int clen, flen, n, j, k;
+  UChar *p, buf[ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM][ONIGENC_MBC_CASE_FOLD_MAXLEN];
+  OnigCaseFoldCodeItem items[ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM];
+  OnigEncoding enc = reg->enc;
+
+  len = end - s;
+  if (len < ONIG_CHAR_TABLE_SIZE) {
+    for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) skip[i] = (UChar )len;
+
+    n = 0;
+    for (i = 0; i < len - 1; i += clen) {
+      p = s + i;
+      if (ignore_case)
+	n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, reg->case_fold_flag,
+					       p, end, items);
+      clen = enclen(enc, p, end);
+      if (p + clen > end)
+	clen = (int )(end - p);
+
+      for (j = 0; j < n; j++) {
+	if ((items[j].code_len != 1) || (items[j].byte_len != clen))
+	  return 1;  /* different length isn't supported. */
+	flen = ONIGENC_CODE_TO_MBC(enc, items[j].code[0], buf[j]);
+	if (flen != clen)
+	  return 1;  /* different length isn't supported. */
+      }
+      for (j = 0; j < clen; j++) {
+	skip[s[i + j]] = (UChar )(len - 1 - i - j);
+	for (k = 0; k < n; k++) {
+	  skip[buf[k][j]] = (UChar )(len - 1 - i - j);
+	}
+      }
+    }
+  }
+  else {
+# if OPT_EXACT_MAXLEN < ONIG_CHAR_TABLE_SIZE
+    /* This should not happen. */
+    return ONIGERR_TYPE_BUG;
+# else
+    if (IS_NULL(*int_skip)) {
+      *int_skip = (int* )xmalloc(sizeof(int) * ONIG_CHAR_TABLE_SIZE);
+      if (IS_NULL(*int_skip)) return ONIGERR_MEMORY;
+    }
+    for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) (*int_skip)[i] = (int )len;
+
+    n = 0;
+    for (i = 0; i < len - 1; i += clen) {
+      p = s + i;
+      if (ignore_case)
+	n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, reg->case_fold_flag,
+					       p, end, items);
+      clen = enclen(enc, p, end);
+      if (p + clen > end)
+	clen = (int )(end - p);
+
+      for (j = 0; j < n; j++) {
+	if ((items[j].code_len != 1) || (items[j].byte_len != clen))
+	  return 1;  /* different length isn't supported. */
+	flen = ONIGENC_CODE_TO_MBC(enc, items[j].code[0], buf[j]);
+	if (flen != clen)
+	  return 1;  /* different length isn't supported. */
+      }
+      for (j = 0; j < clen; j++) {
+	(*int_skip)[s[i + j]] = (int )(len - 1 - i - j);
+	for (k = 0; k < n; k++) {
+	  (*int_skip)[buf[k][j]] = (int )(len - 1 - i - j);
+	}
+      }
+    }
+# endif
+  }
+  return 0;
+}
+
+#else /* USE_SUNDAY_QUICK_SEARCH */
+
+/* set skip map for Sunday's quick search */
+static int
+set_bm_skip(UChar* s, UChar* end, regex_t* reg,
+	    UChar skip[], int** int_skip, int ignore_case)
+{
+  OnigDistance i, len;
+  int clen, flen, n, j, k;
+  UChar *p, buf[ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM][ONIGENC_MBC_CASE_FOLD_MAXLEN];
+  OnigCaseFoldCodeItem items[ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM];
+  OnigEncoding enc = reg->enc;
+
+  len = end - s;
+  if (len < ONIG_CHAR_TABLE_SIZE) {
+    for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) skip[i] = (UChar )(len + 1);
+
+    n = 0;
+    for (i = 0; i < len; i += clen) {
+      p = s + i;
+      if (ignore_case)
+	n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, reg->case_fold_flag,
+					       p, end, items);
+      clen = enclen(enc, p, end);
+      if (p + clen > end)
+	clen = (int )(end - p);
+
+      for (j = 0; j < n; j++) {
+	if ((items[j].code_len != 1) || (items[j].byte_len != clen))
+	  return 1;  /* different length isn't supported. */
+	flen = ONIGENC_CODE_TO_MBC(enc, items[j].code[0], buf[j]);
+	if (flen != clen)
+	  return 1;  /* different length isn't supported. */
+      }
+      for (j = 0; j < clen; j++) {
+	skip[s[i + j]] = (UChar )(len - i - j);
+	for (k = 0; k < n; k++) {
+	  skip[buf[k][j]] = (UChar )(len - i - j);
+	}
+      }
+    }
+  }
+  else {
+# if OPT_EXACT_MAXLEN < ONIG_CHAR_TABLE_SIZE
+    /* This should not happen. */
+    return ONIGERR_TYPE_BUG;
+# else
+    if (IS_NULL(*int_skip)) {
+      *int_skip = (int* )xmalloc(sizeof(int) * ONIG_CHAR_TABLE_SIZE);
+      if (IS_NULL(*int_skip)) return ONIGERR_MEMORY;
+    }
+    for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) (*int_skip)[i] = (int )(len + 1);
+
+    n = 0;
+    for (i = 0; i < len; i += clen) {
+      p = s + i;
+      if (ignore_case)
+	n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, reg->case_fold_flag,
+					       p, end, items);
+      clen = enclen(enc, p, end);
+      if (p + clen > end)
+	clen = (int )(end - p);
+
+      for (j = 0; j < n; j++) {
+	if ((items[j].code_len != 1) || (items[j].byte_len != clen))
+	  return 1;  /* different length isn't supported. */
+	flen = ONIGENC_CODE_TO_MBC(enc, items[j].code[0], buf[j]);
+	if (flen != clen)
+	  return 1;  /* different length isn't supported. */
+      }
+      for (j = 0; j < clen; j++) {
+	(*int_skip)[s[i + j]] = (int )(len - i - j);
+	for (k = 0; k < n; k++) {
+	  (*int_skip)[buf[k][j]] = (int )(len - i - j);
+	}
+      }
+    }
+# endif
+  }
+  return 0;
+}
+#endif /* USE_SUNDAY_QUICK_SEARCH */
+
+typedef struct {
+  OnigDistance min;  /* min byte length */
+  OnigDistance max;  /* max byte length */
+} MinMaxLen;
+
+typedef struct {
+  MinMaxLen        mmd;
+  OnigEncoding     enc;
+  OnigOptionType   options;
+  OnigCaseFoldType case_fold_flag;
+  ScanEnv*         scan_env;
+} OptEnv;
+
+typedef struct {
+  int left_anchor;
+  int right_anchor;
+} OptAncInfo;
+
+typedef struct {
+  MinMaxLen  mmd; /* info position */
+  OptAncInfo anc;
+
+  int   reach_end;
+  int   ignore_case;  /* -1: unset, 0: case sensitive, 1: ignore case */
+  int   len;
+  UChar s[OPT_EXACT_MAXLEN];
+} OptExactInfo;
+
+typedef struct {
+  MinMaxLen mmd; /* info position */
+  OptAncInfo anc;
+
+  int   value;      /* weighted value */
+  UChar map[ONIG_CHAR_TABLE_SIZE];
+} OptMapInfo;
+
+typedef struct {
+  MinMaxLen    len;
+
+  OptAncInfo   anc;
+  OptExactInfo exb;    /* boundary */
+  OptExactInfo exm;    /* middle */
+  OptExactInfo expr;   /* prec read (?=...) */
+
+  OptMapInfo   map;   /* boundary */
+} NodeOptInfo;
+
+
+static int
+map_position_value(OnigEncoding enc, int i)
+{
+  static const short int ByteValTable[] = {
+     5,  1,  1,  1,  1,  1,  1,  1,  1, 10, 10,  1,  1, 10,  1,  1,
+     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+    12,  4,  7,  4,  4,  4,  4,  4,  4,  5,  5,  5,  5,  5,  5,  5,
+     6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  5,  5,  5,  5,  5,  5,
+     5,  6,  6,  6,  6,  7,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
+     6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  5,  6,  5,  5,  5,
+     5,  6,  6,  6,  6,  7,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
+     6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  5,  5,  5,  5,  1
+  };
+
+  if (i < numberof(ByteValTable)) {
+    if (i == 0 && ONIGENC_MBC_MINLEN(enc) > 1)
+      return 20;
+    else
+      return (int )ByteValTable[i];
+  }
+  else
+    return 4;   /* Take it easy. */
+}
+
+static int
+distance_value(MinMaxLen* mm)
+{
+  /* 1000 / (min-max-dist + 1) */
+  static const short int dist_vals[] = {
+    1000,  500,  333,  250,  200,  167,  143,  125,  111,  100,
+      91,   83,   77,   71,   67,   63,   59,   56,   53,   50,
+      48,   45,   43,   42,   40,   38,   37,   36,   34,   33,
+      32,   31,   30,   29,   29,   28,   27,   26,   26,   25,
+      24,   24,   23,   23,   22,   22,   21,   21,   20,   20,
+      20,   19,   19,   19,   18,   18,   18,   17,   17,   17,
+      16,   16,   16,   16,   15,   15,   15,   15,   14,   14,
+      14,   14,   14,   14,   13,   13,   13,   13,   13,   13,
+      12,   12,   12,   12,   12,   12,   11,   11,   11,   11,
+      11,   11,   11,   11,   11,   10,   10,   10,   10,   10
+  };
+
+  OnigDistance d;
+
+  if (mm->max == ONIG_INFINITE_DISTANCE) return 0;
+
+  d = mm->max - mm->min;
+  if (d < numberof(dist_vals))
+    /* return dist_vals[d] * 16 / (mm->min + 12); */
+    return (int )dist_vals[d];
+  else
+    return 1;
+}
+
+static int
+comp_distance_value(MinMaxLen* d1, MinMaxLen* d2, int v1, int v2)
+{
+  if (v2 <= 0) return -1;
+  if (v1 <= 0) return  1;
+
+  v1 *= distance_value(d1);
+  v2 *= distance_value(d2);
+
+  if (v2 > v1) return  1;
+  if (v2 < v1) return -1;
+
+  if (d2->min < d1->min) return  1;
+  if (d2->min > d1->min) return -1;
+  return 0;
+}
+
+static int
+is_equal_mml(MinMaxLen* a, MinMaxLen* b)
+{
+  return (a->min == b->min && a->max == b->max) ? 1 : 0;
+}
+
+
+static void
+set_mml(MinMaxLen* mml, OnigDistance min, OnigDistance max)
+{
+  mml->min = min;
+  mml->max = max;
+}
+
+static void
+clear_mml(MinMaxLen* mml)
+{
+  mml->min = mml->max = 0;
+}
+
+static void
+copy_mml(MinMaxLen* to, MinMaxLen* from)
+{
+  to->min = from->min;
+  to->max = from->max;
+}
+
+static void
+add_mml(MinMaxLen* to, MinMaxLen* from)
+{
+  to->min = distance_add(to->min, from->min);
+  to->max = distance_add(to->max, from->max);
+}
+
+#if 0
+static void
+add_len_mml(MinMaxLen* to, OnigDistance len)
+{
+  to->min = distance_add(to->min, len);
+  to->max = distance_add(to->max, len);
+}
+#endif
+
+static void
+alt_merge_mml(MinMaxLen* to, MinMaxLen* from)
+{
+  if (to->min > from->min) to->min = from->min;
+  if (to->max < from->max) to->max = from->max;
+}
+
+static void
+copy_opt_env(OptEnv* to, OptEnv* from)
+{
+  *to = *from;
+}
+
+static void
+clear_opt_anc_info(OptAncInfo* anc)
+{
+  anc->left_anchor  = 0;
+  anc->right_anchor = 0;
+}
+
+static void
+copy_opt_anc_info(OptAncInfo* to, OptAncInfo* from)
+{
+  *to = *from;
+}
+
+static void
+concat_opt_anc_info(OptAncInfo* to, OptAncInfo* left, OptAncInfo* right,
+		    OnigDistance left_len, OnigDistance right_len)
+{
+  clear_opt_anc_info(to);
+
+  to->left_anchor = left->left_anchor;
+  if (left_len == 0) {
+    to->left_anchor |= right->left_anchor;
+  }
+
+  to->right_anchor = right->right_anchor;
+  if (right_len == 0) {
+    to->right_anchor |= left->right_anchor;
+  }
+  else {
+    to->right_anchor |= (left->right_anchor & ANCHOR_PREC_READ_NOT);
+  }
+}
+
+static int
+is_left_anchor(int anc)
+{
+  if (anc == ANCHOR_END_BUF || anc == ANCHOR_SEMI_END_BUF ||
+      anc == ANCHOR_END_LINE || anc == ANCHOR_PREC_READ ||
+      anc == ANCHOR_PREC_READ_NOT)
+    return 0;
+
+  return 1;
+}
+
+static int
+is_set_opt_anc_info(OptAncInfo* to, int anc)
+{
+  if ((to->left_anchor & anc) != 0) return 1;
+
+  return ((to->right_anchor & anc) != 0 ? 1 : 0);
+}
+
+static void
+add_opt_anc_info(OptAncInfo* to, int anc)
+{
+  if (is_left_anchor(anc))
+    to->left_anchor |= anc;
+  else
+    to->right_anchor |= anc;
+}
+
+static void
+remove_opt_anc_info(OptAncInfo* to, int anc)
+{
+  if (is_left_anchor(anc))
+    to->left_anchor &= ~anc;
+  else
+    to->right_anchor &= ~anc;
+}
+
+static void
+alt_merge_opt_anc_info(OptAncInfo* to, OptAncInfo* add)
+{
+  to->left_anchor  &= add->left_anchor;
+  to->right_anchor &= add->right_anchor;
+}
+
+static int
+is_full_opt_exact_info(OptExactInfo* ex)
+{
+  return (ex->len >= OPT_EXACT_MAXLEN ? 1 : 0);
+}
+
+static void
+clear_opt_exact_info(OptExactInfo* ex)
+{
+  clear_mml(&ex->mmd);
+  clear_opt_anc_info(&ex->anc);
+  ex->reach_end   = 0;
+  ex->ignore_case = -1;   /* unset */
+  ex->len         = 0;
+  ex->s[0]        = '\0';
+}
+
+static void
+copy_opt_exact_info(OptExactInfo* to, OptExactInfo* from)
+{
+  *to = *from;
+}
+
+static void
+concat_opt_exact_info(OptExactInfo* to, OptExactInfo* add, OnigEncoding enc)
+{
+  int i, j, len;
+  UChar *p, *end;
+  OptAncInfo tanc;
+
+  if (to->ignore_case < 0)
+    to->ignore_case = add->ignore_case;
+  else if (to->ignore_case != add->ignore_case)
+    return ;  /* avoid */
+
+  p = add->s;
+  end = p + add->len;
+  for (i = to->len; p < end; ) {
+    len = enclen(enc, p, end);
+    if (i + len > OPT_EXACT_MAXLEN) break;
+    for (j = 0; j < len && p < end; j++)
+      to->s[i++] = *p++;
+  }
+
+  to->len = i;
+  to->reach_end = (p == end ? add->reach_end : 0);
+
+  concat_opt_anc_info(&tanc, &to->anc, &add->anc, 1, 1);
+  if (! to->reach_end) tanc.right_anchor = 0;
+  copy_opt_anc_info(&to->anc, &tanc);
+}
+
+static void
+concat_opt_exact_info_str(OptExactInfo* to, UChar* s, UChar* end,
+			  int raw ARG_UNUSED, OnigEncoding enc)
+{
+  int i, j, len;
+  UChar *p;
+
+  for (i = to->len, p = s; p < end && i < OPT_EXACT_MAXLEN; ) {
+    len = enclen(enc, p, end);
+    if (i + len > OPT_EXACT_MAXLEN) break;
+    for (j = 0; j < len && p < end; j++)
+      to->s[i++] = *p++;
+  }
+
+  to->len = i;
+}
+
+static void
+alt_merge_opt_exact_info(OptExactInfo* to, OptExactInfo* add, OptEnv* env)
+{
+  int i, j, len;
+
+  if (add->len == 0 || to->len == 0) {
+    clear_opt_exact_info(to);
+    return ;
+  }
+
+  if (! is_equal_mml(&to->mmd, &add->mmd)) {
+    clear_opt_exact_info(to);
+    return ;
+  }
+
+  for (i = 0; i < to->len && i < add->len; ) {
+    if (to->s[i] != add->s[i]) break;
+    len = enclen(env->enc, to->s + i, to->s + to->len);
+
+    for (j = 1; j < len; j++) {
+      if (to->s[i+j] != add->s[i+j]) break;
+    }
+    if (j < len) break;
+    i += len;
+  }
+
+  if (! add->reach_end || i < add->len || i < to->len) {
+    to->reach_end = 0;
+  }
+  to->len = i;
+  if (to->ignore_case < 0)
+    to->ignore_case = add->ignore_case;
+  else if (add->ignore_case >= 0)
+    to->ignore_case |= add->ignore_case;
+
+  alt_merge_opt_anc_info(&to->anc, &add->anc);
+  if (! to->reach_end) to->anc.right_anchor = 0;
+}
+
+static void
+select_opt_exact_info(OnigEncoding enc, OptExactInfo* now, OptExactInfo* alt)
+{
+  int v1, v2;
+
+  v1 = now->len;
+  v2 = alt->len;
+
+  if (v2 == 0) {
+    return ;
+  }
+  else if (v1 == 0) {
+    copy_opt_exact_info(now, alt);
+    return ;
+  }
+  else if (v1 <= 2 && v2 <= 2) {
+    /* ByteValTable[x] is big value --> low price */
+    v2 = map_position_value(enc, now->s[0]);
+    v1 = map_position_value(enc, alt->s[0]);
+
+    if (now->len > 1) v1 += 5;
+    if (alt->len > 1) v2 += 5;
+  }
+
+  if (now->ignore_case <= 0) v1 *= 2;
+  if (alt->ignore_case <= 0) v2 *= 2;
+
+  if (comp_distance_value(&now->mmd, &alt->mmd, v1, v2) > 0)
+    copy_opt_exact_info(now, alt);
+}
+
+static void
+clear_opt_map_info(OptMapInfo* map)
+{
+  static const OptMapInfo clean_info = {
+    {0, 0}, {0, 0}, 0,
+    {
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+    }
+  };
+
+  xmemcpy(map, &clean_info, sizeof(OptMapInfo));
+}
+
+static void
+copy_opt_map_info(OptMapInfo* to, OptMapInfo* from)
+{
+  *to = *from;
+}
+
+static void
+add_char_opt_map_info(OptMapInfo* map, UChar c, OnigEncoding enc)
+{
+  if (map->map[c] == 0) {
+    map->map[c] = 1;
+    map->value += map_position_value(enc, c);
+  }
+}
+
+static int
+add_char_amb_opt_map_info(OptMapInfo* map, UChar* p, UChar* end,
+                          OnigEncoding enc, OnigCaseFoldType case_fold_flag)
+{
+  OnigCaseFoldCodeItem items[ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM];
+  UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
+  int i, n;
+
+  add_char_opt_map_info(map, p[0], enc);
+
+  case_fold_flag = DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag);
+  n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, case_fold_flag, p, end, items);
+  if (n < 0) return n;
+
+  for (i = 0; i < n; i++) {
+    ONIGENC_CODE_TO_MBC(enc, items[i].code[0], buf);
+    add_char_opt_map_info(map, buf[0], enc);
+  }
+
+  return 0;
+}
+
+static void
+select_opt_map_info(OptMapInfo* now, OptMapInfo* alt)
+{
+  const int z = 1<<15; /* 32768: something big value */
+
+  int v1, v2;
+
+  if (alt->value == 0) return ;
+  if (now->value == 0) {
+    copy_opt_map_info(now, alt);
+    return ;
+  }
+
+  v1 = z / now->value;
+  v2 = z / alt->value;
+  if (comp_distance_value(&now->mmd, &alt->mmd, v1, v2) > 0)
+    copy_opt_map_info(now, alt);
+}
+
+static int
+comp_opt_exact_or_map_info(OptExactInfo* e, OptMapInfo* m)
+{
+#define COMP_EM_BASE  20
+  int ve, vm;
+
+  if (m->value <= 0) return -1;
+
+  ve = COMP_EM_BASE * e->len * (e->ignore_case > 0 ? 1 : 2);
+  vm = COMP_EM_BASE * 5 * 2 / m->value;
+  return comp_distance_value(&e->mmd, &m->mmd, ve, vm);
+}
+
+static void
+alt_merge_opt_map_info(OnigEncoding enc, OptMapInfo* to, OptMapInfo* add)
+{
+  int i, val;
+
+  /* if (! is_equal_mml(&to->mmd, &add->mmd)) return ; */
+  if (to->value == 0) return ;
+  if (add->value == 0 || to->mmd.max < add->mmd.min) {
+    clear_opt_map_info(to);
+    return ;
+  }
+
+  alt_merge_mml(&to->mmd, &add->mmd);
+
+  val = 0;
+  for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) {
+    if (add->map[i])
+      to->map[i] = 1;
+
+    if (to->map[i])
+      val += map_position_value(enc, i);
+  }
+  to->value = val;
+
+  alt_merge_opt_anc_info(&to->anc, &add->anc);
+}
+
+static void
+set_bound_node_opt_info(NodeOptInfo* opt, MinMaxLen* mmd)
+{
+  copy_mml(&(opt->exb.mmd),  mmd);
+  copy_mml(&(opt->expr.mmd), mmd);
+  copy_mml(&(opt->map.mmd),  mmd);
+}
+
+static void
+clear_node_opt_info(NodeOptInfo* opt)
+{
+  clear_mml(&opt->len);
+  clear_opt_anc_info(&opt->anc);
+  clear_opt_exact_info(&opt->exb);
+  clear_opt_exact_info(&opt->exm);
+  clear_opt_exact_info(&opt->expr);
+  clear_opt_map_info(&opt->map);
+}
+
+static void
+copy_node_opt_info(NodeOptInfo* to, NodeOptInfo* from)
+{
+  *to = *from;
+}
+
+static void
+concat_left_node_opt_info(OnigEncoding enc, NodeOptInfo* to, NodeOptInfo* add)
+{
+  int exb_reach, exm_reach;
+  OptAncInfo tanc;
+
+  concat_opt_anc_info(&tanc, &to->anc, &add->anc, to->len.max, add->len.max);
+  copy_opt_anc_info(&to->anc, &tanc);
+
+  if (add->exb.len > 0 && to->len.max == 0) {
+    concat_opt_anc_info(&tanc, &to->anc, &add->exb.anc,
+			to->len.max, add->len.max);
+    copy_opt_anc_info(&add->exb.anc, &tanc);
+  }
+
+  if (add->map.value > 0 && to->len.max == 0) {
+    if (add->map.mmd.max == 0)
+      add->map.anc.left_anchor |= to->anc.left_anchor;
+  }
+
+  exb_reach = to->exb.reach_end;
+  exm_reach = to->exm.reach_end;
+
+  if (add->len.max != 0)
+    to->exb.reach_end = to->exm.reach_end = 0;
+
+  if (add->exb.len > 0) {
+    if (exb_reach) {
+      concat_opt_exact_info(&to->exb, &add->exb, enc);
+      clear_opt_exact_info(&add->exb);
+    }
+    else if (exm_reach) {
+      concat_opt_exact_info(&to->exm, &add->exb, enc);
+      clear_opt_exact_info(&add->exb);
+    }
+  }
+  select_opt_exact_info(enc, &to->exm, &add->exb);
+  select_opt_exact_info(enc, &to->exm, &add->exm);
+
+  if (to->expr.len > 0) {
+    if (add->len.max > 0) {
+      if (to->expr.len > (int )add->len.max)
+	to->expr.len = (int )add->len.max;
+
+      if (to->expr.mmd.max == 0)
+	select_opt_exact_info(enc, &to->exb, &to->expr);
+      else
+	select_opt_exact_info(enc, &to->exm, &to->expr);
+    }
+  }
+  else if (add->expr.len > 0) {
+    copy_opt_exact_info(&to->expr, &add->expr);
+  }
+
+  select_opt_map_info(&to->map, &add->map);
+
+  add_mml(&to->len, &add->len);
+}
+
+static void
+alt_merge_node_opt_info(NodeOptInfo* to, NodeOptInfo* add, OptEnv* env)
+{
+  alt_merge_opt_anc_info  (&to->anc,  &add->anc);
+  alt_merge_opt_exact_info(&to->exb,  &add->exb, env);
+  alt_merge_opt_exact_info(&to->exm,  &add->exm, env);
+  alt_merge_opt_exact_info(&to->expr, &add->expr, env);
+  alt_merge_opt_map_info(env->enc, &to->map,  &add->map);
+
+  alt_merge_mml(&to->len, &add->len);
+}
+
+
+#define MAX_NODE_OPT_INFO_REF_COUNT    5
+
+static int
+optimize_node_left(Node* node, NodeOptInfo* opt, OptEnv* env)
+{
+  int type;
+  int r = 0;
+
+  clear_node_opt_info(opt);
+  set_bound_node_opt_info(opt, &env->mmd);
+
+  type = NTYPE(node);
+  switch (type) {
+  case NT_LIST:
+    {
+      OptEnv nenv;
+      NodeOptInfo nopt;
+      Node* nd = node;
+
+      copy_opt_env(&nenv, env);
+      do {
+	r = optimize_node_left(NCAR(nd), &nopt, &nenv);
+	if (r == 0) {
+	  add_mml(&nenv.mmd, &nopt.len);
+	  concat_left_node_opt_info(env->enc, opt, &nopt);
+	}
+      } while (r == 0 && IS_NOT_NULL(nd = NCDR(nd)));
+    }
+    break;
+
+  case NT_ALT:
+    {
+      NodeOptInfo nopt;
+      Node* nd = node;
+
+      do {
+	r = optimize_node_left(NCAR(nd), &nopt, env);
+	if (r == 0) {
+	  if (nd == node) copy_node_opt_info(opt, &nopt);
+	  else            alt_merge_node_opt_info(opt, &nopt, env);
+	}
+      } while ((r == 0) && IS_NOT_NULL(nd = NCDR(nd)));
+    }
+    break;
+
+  case NT_STR:
+    {
+      StrNode* sn = NSTR(node);
+      OnigDistance slen = sn->end - sn->s;
+      int is_raw = NSTRING_IS_RAW(node);
+
+      if (! NSTRING_IS_AMBIG(node)) {
+	concat_opt_exact_info_str(&opt->exb, sn->s, sn->end,
+				  is_raw, env->enc);
+	opt->exb.ignore_case = 0;
+	if (slen > 0) {
+	  add_char_opt_map_info(&opt->map, *(sn->s), env->enc);
+	}
+	set_mml(&opt->len, slen, slen);
+      }
+      else {
+	OnigDistance max;
+
+	if (NSTRING_IS_DONT_GET_OPT_INFO(node)) {
+	  int n = onigenc_strlen(env->enc, sn->s, sn->end);
+	  max = ONIGENC_MBC_MAXLEN_DIST(env->enc) * n;
+	}
+	else {
+	  concat_opt_exact_info_str(&opt->exb, sn->s, sn->end,
+				    is_raw, env->enc);
+	  opt->exb.ignore_case = 1;
+
+	  if (slen > 0) {
+	    r = add_char_amb_opt_map_info(&opt->map, sn->s, sn->end,
+					  env->enc, env->case_fold_flag);
+	    if (r != 0) break;
+	  }
+
+	  max = slen;
+	}
+
+	set_mml(&opt->len, slen, max);
+      }
+
+      if ((OnigDistance )opt->exb.len == slen)
+	opt->exb.reach_end = 1;
+    }
+    break;
+
+  case NT_CCLASS:
+    {
+      int i, z;
+      CClassNode* cc = NCCLASS(node);
+
+      /* no need to check ignore case. (set in setup_tree()) */
+
+      if (IS_NOT_NULL(cc->mbuf) || IS_NCCLASS_NOT(cc)) {
+	OnigDistance min = ONIGENC_MBC_MINLEN(env->enc);
+	OnigDistance max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
+
+	set_mml(&opt->len, min, max);
+      }
+      else {
+	for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
+	  z = BITSET_AT(cc->bs, i);
+	  if ((z && !IS_NCCLASS_NOT(cc)) || (!z && IS_NCCLASS_NOT(cc))) {
+	    add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
+	  }
+	}
+	set_mml(&opt->len, 1, 1);
+      }
+    }
+    break;
+
+  case NT_CTYPE:
+    {
+      int i, min, max;
+      int maxcode;
+
+      max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
+
+      if (max == 1) {
+	min = 1;
+
+	maxcode = NCTYPE(node)->ascii_range ? 0x80 : SINGLE_BYTE_SIZE;
+	switch (NCTYPE(node)->ctype) {
+	case ONIGENC_CTYPE_WORD:
+	  if (NCTYPE(node)->not != 0) {
+	    for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
+	      if (! ONIGENC_IS_CODE_WORD(env->enc, i) || i >= maxcode) {
+		add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
+	      }
+	    }
+	  }
+	  else {
+	    for (i = 0; i < maxcode; i++) {
+	      if (ONIGENC_IS_CODE_WORD(env->enc, i)) {
+		add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
+	      }
+	    }
+	  }
+	  break;
+	}
+      }
+      else {
+	min = ONIGENC_MBC_MINLEN(env->enc);
+      }
+      set_mml(&opt->len, min, max);
+    }
+    break;
+
+  case NT_CANY:
+    {
+      OnigDistance min = ONIGENC_MBC_MINLEN(env->enc);
+      OnigDistance max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
+      set_mml(&opt->len, min, max);
+    }
+    break;
+
+  case NT_ANCHOR:
+    switch (NANCHOR(node)->type) {
+    case ANCHOR_BEGIN_BUF:
+    case ANCHOR_BEGIN_POSITION:
+    case ANCHOR_BEGIN_LINE:
+    case ANCHOR_END_BUF:
+    case ANCHOR_SEMI_END_BUF:
+    case ANCHOR_END_LINE:
+    case ANCHOR_LOOK_BEHIND:	/* just for (?<=x).* */
+    case ANCHOR_PREC_READ_NOT:	/* just for (?!x).* */
+      add_opt_anc_info(&opt->anc, NANCHOR(node)->type);
+      break;
+
+    case ANCHOR_PREC_READ:
+      {
+	NodeOptInfo nopt;
+
+	r = optimize_node_left(NANCHOR(node)->target, &nopt, env);
+	if (r == 0) {
+	  if (nopt.exb.len > 0)
+	    copy_opt_exact_info(&opt->expr, &nopt.exb);
+	  else if (nopt.exm.len > 0)
+	    copy_opt_exact_info(&opt->expr, &nopt.exm);
+
+	  opt->expr.reach_end = 0;
+
+	  if (nopt.map.value > 0)
+	    copy_opt_map_info(&opt->map, &nopt.map);
+	}
+      }
+      break;
+
+    case ANCHOR_LOOK_BEHIND_NOT:
+      break;
+    }
+    break;
+
+  case NT_BREF:
+    {
+      int i;
+      int* backs;
+      OnigDistance min, max, tmin, tmax;
+      Node** nodes = SCANENV_MEM_NODES(env->scan_env);
+      BRefNode* br = NBREF(node);
+
+      if (br->state & NST_RECURSION) {
+	set_mml(&opt->len, 0, ONIG_INFINITE_DISTANCE);
+	break;
+      }
+      backs = BACKREFS_P(br);
+      r = get_min_match_length(nodes[backs[0]], &min, env->scan_env);
+      if (r != 0) break;
+      r = get_max_match_length(nodes[backs[0]], &max, env->scan_env);
+      if (r != 0) break;
+      for (i = 1; i < br->back_num; i++) {
+	r = get_min_match_length(nodes[backs[i]], &tmin, env->scan_env);
+	if (r != 0) break;
+	r = get_max_match_length(nodes[backs[i]], &tmax, env->scan_env);
+	if (r != 0) break;
+	if (min > tmin) min = tmin;
+	if (max < tmax) max = tmax;
+      }
+      if (r == 0) set_mml(&opt->len, min, max);
+    }
+    break;
+
+#ifdef USE_SUBEXP_CALL
+  case NT_CALL:
+    if (IS_CALL_RECURSION(NCALL(node)))
+      set_mml(&opt->len, 0, ONIG_INFINITE_DISTANCE);
+    else {
+      OnigOptionType save = env->options;
+      env->options = NENCLOSE(NCALL(node)->target)->option;
+      r = optimize_node_left(NCALL(node)->target, opt, env);
+      env->options = save;
+    }
+    break;
+#endif
+
+  case NT_QTFR:
+    {
+      int i;
+      OnigDistance min, max;
+      NodeOptInfo nopt;
+      QtfrNode* qn = NQTFR(node);
+
+      r = optimize_node_left(qn->target, &nopt, env);
+      if (r) break;
+
+      if (/*qn->lower == 0 &&*/ IS_REPEAT_INFINITE(qn->upper)) {
+	if (env->mmd.max == 0 &&
+	    NTYPE(qn->target) == NT_CANY && qn->greedy) {
+	  if (IS_MULTILINE(env->options))
+	    /* implicit anchor: /.*a/ ==> /\A.*a/ */
+	    add_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR_ML);
+	  else
+	    add_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR);
+	}
+      }
+      else {
+	if (qn->lower > 0) {
+	  copy_node_opt_info(opt, &nopt);
+	  if (nopt.exb.len > 0) {
+	    if (nopt.exb.reach_end) {
+	      for (i = 2; i <= qn->lower &&
+			  ! is_full_opt_exact_info(&opt->exb); i++) {
+		concat_opt_exact_info(&opt->exb, &nopt.exb, env->enc);
+	      }
+	      if (i < qn->lower) {
+		opt->exb.reach_end = 0;
+	      }
+	    }
+	  }
+
+	  if (qn->lower != qn->upper) {
+	    opt->exb.reach_end = 0;
+	    opt->exm.reach_end = 0;
+	  }
+	  if (qn->lower > 1)
+	    opt->exm.reach_end = 0;
+	}
+      }
+
+      min = distance_multiply(nopt.len.min, qn->lower);
+      if (IS_REPEAT_INFINITE(qn->upper))
+	max = (nopt.len.max > 0 ? ONIG_INFINITE_DISTANCE : 0);
+      else
+	max = distance_multiply(nopt.len.max, qn->upper);
+
+      set_mml(&opt->len, min, max);
+    }
+    break;
+
+  case NT_ENCLOSE:
+    {
+      EncloseNode* en = NENCLOSE(node);
+
+      switch (en->type) {
+      case ENCLOSE_OPTION:
+	{
+	  OnigOptionType save = env->options;
+
+	  env->options = en->option;
+	  r = optimize_node_left(en->target, opt, env);
+	  env->options = save;
+	}
+	break;
+
+      case ENCLOSE_MEMORY:
+#ifdef USE_SUBEXP_CALL
+	en->opt_count++;
+	if (en->opt_count > MAX_NODE_OPT_INFO_REF_COUNT) {
+	  OnigDistance min, max;
+
+	  min = 0;
+	  max = ONIG_INFINITE_DISTANCE;
+	  if (IS_ENCLOSE_MIN_FIXED(en)) min = en->min_len;
+	  if (IS_ENCLOSE_MAX_FIXED(en)) max = en->max_len;
+	  set_mml(&opt->len, min, max);
+	}
+	else
+#endif
+	{
+	  r = optimize_node_left(en->target, opt, env);
+
+	  if (is_set_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR_MASK)) {
+	    if (BIT_STATUS_AT(env->scan_env->backrefed_mem, en->regnum))
+	      remove_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR_MASK);
+	  }
+	}
+	break;
+
+      case ENCLOSE_STOP_BACKTRACK:
+      case ENCLOSE_CONDITION:
+	r = optimize_node_left(en->target, opt, env);
+	break;
+
+      case ENCLOSE_ABSENT:
+	set_mml(&opt->len, 0, ONIG_INFINITE_DISTANCE);
+	break;
+      }
+    }
+    break;
+
+  default:
+#ifdef ONIG_DEBUG
+    fprintf(stderr, "optimize_node_left: undefined node type %d\n",
+	    NTYPE(node));
+#endif
+    r = ONIGERR_TYPE_BUG;
+    break;
+  }
+
+  return r;
+}
+
+static int
+set_optimize_exact_info(regex_t* reg, OptExactInfo* e)
+{
+  int r;
+  int allow_reverse;
+
+  if (e->len == 0) return 0;
+
+  reg->exact = (UChar* )xmalloc(e->len);
+  CHECK_NULL_RETURN_MEMERR(reg->exact);
+  xmemcpy(reg->exact, e->s, e->len);
+  reg->exact_end = reg->exact + e->len;
+
+  allow_reverse =
+	ONIGENC_IS_ALLOWED_REVERSE_MATCH(reg->enc, reg->exact, reg->exact_end);
+
+  if (e->ignore_case > 0) {
+    if (e->len >= 3 || (e->len >= 2 && allow_reverse)) {
+      r = set_bm_skip(reg->exact, reg->exact_end, reg,
+		      reg->map, &(reg->int_map), 1);
+      if (r == 0) {
+	reg->optimize = (allow_reverse != 0
+			 ? ONIG_OPTIMIZE_EXACT_BM_IC : ONIG_OPTIMIZE_EXACT_BM_NOT_REV_IC);
+      }
+      else {
+	reg->optimize = ONIG_OPTIMIZE_EXACT_IC;
+      }
+    }
+    else {
+      reg->optimize = ONIG_OPTIMIZE_EXACT_IC;
+    }
+  }
+  else {
+    if (e->len >= 3 || (e->len >= 2 && allow_reverse)) {
+      r = set_bm_skip(reg->exact, reg->exact_end, reg,
+		      reg->map, &(reg->int_map), 0);
+      if (r == 0) {
+	reg->optimize = (allow_reverse != 0
+		       ? ONIG_OPTIMIZE_EXACT_BM : ONIG_OPTIMIZE_EXACT_BM_NOT_REV);
+      }
+      else {
+	reg->optimize = ONIG_OPTIMIZE_EXACT;
+      }
+    }
+    else {
+      reg->optimize = ONIG_OPTIMIZE_EXACT;
+    }
+  }
+
+  reg->dmin = e->mmd.min;
+  reg->dmax = e->mmd.max;
+
+  if (reg->dmin != ONIG_INFINITE_DISTANCE) {
+    reg->threshold_len = (int )(reg->dmin + (reg->exact_end - reg->exact));
+  }
+
+  return 0;
+}
+
+static void
+set_optimize_map_info(regex_t* reg, OptMapInfo* m)
+{
+  int i;
+
+  for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
+    reg->map[i] = m->map[i];
+
+  reg->optimize   = ONIG_OPTIMIZE_MAP;
+  reg->dmin       = m->mmd.min;
+  reg->dmax       = m->mmd.max;
+
+  if (reg->dmin != ONIG_INFINITE_DISTANCE) {
+    reg->threshold_len = (int )(reg->dmin + 1);
+  }
+}
+
+static void
+set_sub_anchor(regex_t* reg, OptAncInfo* anc)
+{
+  reg->sub_anchor |= anc->left_anchor  & ANCHOR_BEGIN_LINE;
+  reg->sub_anchor |= anc->right_anchor & ANCHOR_END_LINE;
+}
+
+#if defined(ONIG_DEBUG_COMPILE) || defined(ONIG_DEBUG_MATCH)
+static void print_optimize_info(FILE* f, regex_t* reg);
+#endif
+
+static int
+set_optimize_info_from_tree(Node* node, regex_t* reg, ScanEnv* scan_env)
+{
+
+  int r;
+  NodeOptInfo opt;
+  OptEnv env;
+
+  env.enc            = reg->enc;
+  env.options        = reg->options;
+  env.case_fold_flag = reg->case_fold_flag;
+  env.scan_env   = scan_env;
+  clear_mml(&env.mmd);
+
+  r = optimize_node_left(node, &opt, &env);
+  if (r) return r;
+
+  reg->anchor = opt.anc.left_anchor & (ANCHOR_BEGIN_BUF |
+        ANCHOR_BEGIN_POSITION | ANCHOR_ANYCHAR_STAR | ANCHOR_ANYCHAR_STAR_ML |
+        ANCHOR_LOOK_BEHIND);
+
+  if ((opt.anc.left_anchor & (ANCHOR_LOOK_BEHIND | ANCHOR_PREC_READ_NOT)) != 0)
+    reg->anchor &= ~ANCHOR_ANYCHAR_STAR_ML;
+
+  reg->anchor |= opt.anc.right_anchor & (ANCHOR_END_BUF | ANCHOR_SEMI_END_BUF |
+	ANCHOR_PREC_READ_NOT);
+
+  if (reg->anchor & (ANCHOR_END_BUF | ANCHOR_SEMI_END_BUF)) {
+    reg->anchor_dmin = opt.len.min;
+    reg->anchor_dmax = opt.len.max;
+  }
+
+  if (opt.exb.len > 0 || opt.exm.len > 0) {
+    select_opt_exact_info(reg->enc, &opt.exb, &opt.exm);
+    if (opt.map.value > 0 &&
+	comp_opt_exact_or_map_info(&opt.exb, &opt.map) > 0) {
+      goto set_map;
+    }
+    else {
+      r = set_optimize_exact_info(reg, &opt.exb);
+      set_sub_anchor(reg, &opt.exb.anc);
+    }
+  }
+  else if (opt.map.value > 0) {
+  set_map:
+    set_optimize_map_info(reg, &opt.map);
+    set_sub_anchor(reg, &opt.map.anc);
+  }
+  else {
+    reg->sub_anchor |= opt.anc.left_anchor & ANCHOR_BEGIN_LINE;
+    if (opt.len.max == 0)
+      reg->sub_anchor |= opt.anc.right_anchor & ANCHOR_END_LINE;
+  }
+
+#if defined(ONIG_DEBUG_COMPILE) || defined(ONIG_DEBUG_MATCH)
+  print_optimize_info(stderr, reg);
+#endif
+  return r;
+}
+
+static void
+clear_optimize_info(regex_t* reg)
+{
+  reg->optimize      = ONIG_OPTIMIZE_NONE;
+  reg->anchor        = 0;
+  reg->anchor_dmin   = 0;
+  reg->anchor_dmax   = 0;
+  reg->sub_anchor    = 0;
+  reg->exact_end     = (UChar* )NULL;
+  reg->threshold_len = 0;
+  if (IS_NOT_NULL(reg->exact)) {
+    xfree(reg->exact);
+    reg->exact = (UChar* )NULL;
+  }
+}
+
+#ifdef ONIG_DEBUG
+
+static void print_enc_string(FILE* fp, OnigEncoding enc,
+			     const UChar *s, const UChar *end)
+{
+  fprintf(fp, "\nPATTERN: /");
+
+  if (ONIGENC_MBC_MINLEN(enc) > 1) {
+    const UChar *p;
+    OnigCodePoint code;
+
+    p = s;
+    while (p < end) {
+      code = ONIGENC_MBC_TO_CODE(enc, p, end);
+      if (code >= 0x80) {
+	fprintf(fp, " 0x%04x ", (int )code);
+      }
+      else {
+	fputc((int )code, fp);
+      }
+
+      p += enclen(enc, p, end);
+    }
+  }
+  else {
+    while (s < end) {
+      fputc((int )*s, fp);
+      s++;
+    }
+  }
+
+  fprintf(fp, "/ (%s)\n", enc->name);
+}
+#endif	/* ONIG_DEBUG */
+
+#if defined(ONIG_DEBUG_COMPILE) || defined(ONIG_DEBUG_MATCH)
+static void
+print_distance_range(FILE* f, OnigDistance a, OnigDistance b)
+{
+  if (a == ONIG_INFINITE_DISTANCE)
+    fputs("inf", f);
+  else
+    fprintf(f, "(%"PRIuPTR")", a);
+
+  fputs("-", f);
+
+  if (b == ONIG_INFINITE_DISTANCE)
+    fputs("inf", f);
+  else
+    fprintf(f, "(%"PRIuPTR")", b);
+}
+
+static void
+print_anchor(FILE* f, int anchor)
+{
+  int q = 0;
+
+  fprintf(f, "[");
+
+  if (anchor & ANCHOR_BEGIN_BUF) {
+    fprintf(f, "begin-buf");
+    q = 1;
+  }
+  if (anchor & ANCHOR_BEGIN_LINE) {
+    if (q) fprintf(f, ", ");
+    q = 1;
+    fprintf(f, "begin-line");
+  }
+  if (anchor & ANCHOR_BEGIN_POSITION) {
+    if (q) fprintf(f, ", ");
+    q = 1;
+    fprintf(f, "begin-pos");
+  }
+  if (anchor & ANCHOR_END_BUF) {
+    if (q) fprintf(f, ", ");
+    q = 1;
+    fprintf(f, "end-buf");
+  }
+  if (anchor & ANCHOR_SEMI_END_BUF) {
+    if (q) fprintf(f, ", ");
+    q = 1;
+    fprintf(f, "semi-end-buf");
+  }
+  if (anchor & ANCHOR_END_LINE) {
+    if (q) fprintf(f, ", ");
+    q = 1;
+    fprintf(f, "end-line");
+  }
+  if (anchor & ANCHOR_ANYCHAR_STAR) {
+    if (q) fprintf(f, ", ");
+    q = 1;
+    fprintf(f, "anychar-star");
+  }
+  if (anchor & ANCHOR_ANYCHAR_STAR_ML) {
+    if (q) fprintf(f, ", ");
+    fprintf(f, "anychar-star-ml");
+  }
+
+  fprintf(f, "]");
+}
+
+static void
+print_optimize_info(FILE* f, regex_t* reg)
+{
+  static const char* on[] = { "NONE", "EXACT", "EXACT_BM", "EXACT_BM_NOT_REV",
+                              "EXACT_IC", "MAP",
+                              "EXACT_BM_IC", "EXACT_BM_NOT_REV_IC" };
+
+  fprintf(f, "optimize: %s\n", on[reg->optimize]);
+  fprintf(f, "  anchor: "); print_anchor(f, reg->anchor);
+  if ((reg->anchor & ANCHOR_END_BUF_MASK) != 0)
+    print_distance_range(f, reg->anchor_dmin, reg->anchor_dmax);
+  fprintf(f, "\n");
+
+  if (reg->optimize) {
+    fprintf(f, "  sub anchor: "); print_anchor(f, reg->sub_anchor);
+    fprintf(f, "\n");
+  }
+  fprintf(f, "\n");
+
+  if (reg->exact) {
+    UChar *p;
+    fprintf(f, "exact: [");
+    for (p = reg->exact; p < reg->exact_end; p++) {
+      fputc(*p, f);
+    }
+    fprintf(f, "]: length: %"PRIdPTR"\n", (reg->exact_end - reg->exact));
+  }
+  else if (reg->optimize & ONIG_OPTIMIZE_MAP) {
+    int c, i, n = 0;
+
+    for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
+      if (reg->map[i]) n++;
+
+    fprintf(f, "map: n=%d\n", n);
+    if (n > 0) {
+      c = 0;
+      fputc('[', f);
+      for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) {
+	if (reg->map[i] != 0) {
+	  if (c > 0)  fputs(", ", f);
+	  c++;
+	  if (ONIGENC_MBC_MAXLEN(reg->enc) == 1 &&
+	      ONIGENC_IS_CODE_PRINT(reg->enc, (OnigCodePoint )i))
+	    fputc(i, f);
+	  else
+	    fprintf(f, "%d", i);
+	}
+      }
+      fprintf(f, "]\n");
+    }
+  }
+}
+#endif /* ONIG_DEBUG_COMPILE || ONIG_DEBUG_MATCH */
+
+
+extern void
+onig_free_body(regex_t* reg)
+{
+  if (IS_NOT_NULL(reg)) {
+    if (IS_NOT_NULL(reg->p))                xfree(reg->p);
+    if (IS_NOT_NULL(reg->exact))            xfree(reg->exact);
+    if (IS_NOT_NULL(reg->int_map))          xfree(reg->int_map);
+    if (IS_NOT_NULL(reg->int_map_backward)) xfree(reg->int_map_backward);
+    if (IS_NOT_NULL(reg->repeat_range))     xfree(reg->repeat_range);
+    if (IS_NOT_NULL(reg->chain))            onig_free(reg->chain);
+
+#ifdef USE_NAMED_GROUP
+    onig_names_free(reg);
+#endif
+  }
+}
+
+extern void
+onig_free(regex_t* reg)
+{
+  if (IS_NOT_NULL(reg)) {
+    onig_free_body(reg);
+    xfree(reg);
+  }
+}
+
+#ifdef RUBY
+size_t
+onig_memsize(const regex_t *reg)
+{
+    size_t size = sizeof(regex_t);
+    if (IS_NULL(reg)) return 0;
+    if (IS_NOT_NULL(reg->p))                size += reg->alloc;
+    if (IS_NOT_NULL(reg->exact))            size += reg->exact_end - reg->exact;
+    if (IS_NOT_NULL(reg->int_map))          size += sizeof(int) * ONIG_CHAR_TABLE_SIZE;
+    if (IS_NOT_NULL(reg->int_map_backward)) size += sizeof(int) * ONIG_CHAR_TABLE_SIZE;
+    if (IS_NOT_NULL(reg->repeat_range))     size += reg->repeat_range_alloc * sizeof(OnigRepeatRange);
+    if (IS_NOT_NULL(reg->chain))            size += onig_memsize(reg->chain);
+
+    return size;
+}
+
+size_t
+onig_region_memsize(const OnigRegion *regs)
+{
+    size_t size = sizeof(*regs);
+    if (IS_NULL(regs)) return 0;
+    size += regs->allocated * (sizeof(*regs->beg) + sizeof(*regs->end));
+    return size;
+}
+#endif
+
+#define REGEX_TRANSFER(to,from) do {\
+  onig_free_body(to);\
+  xmemcpy(to, from, sizeof(regex_t));\
+  xfree(from);\
+} while (0)
+
+#if 0
+extern void
+onig_transfer(regex_t* to, regex_t* from)
+{
+  REGEX_TRANSFER(to, from);
+}
+#endif
+
+#ifdef ONIG_DEBUG_COMPILE
+static void print_compiled_byte_code_list(FILE* f, regex_t* reg);
+#endif
+#ifdef ONIG_DEBUG_PARSE_TREE
+static void print_tree(FILE* f, Node* node);
+#endif
+
+#ifdef RUBY
+extern int
+onig_compile(regex_t* reg, const UChar* pattern, const UChar* pattern_end,
+	     OnigErrorInfo* einfo)
+{
+  return onig_compile_ruby(reg, pattern, pattern_end, einfo, NULL, 0);
+}
+#endif
+
+#ifdef RUBY
+extern int
+onig_compile_ruby(regex_t* reg, const UChar* pattern, const UChar* pattern_end,
+	      OnigErrorInfo* einfo, const char *sourcefile, int sourceline)
+#else
+extern int
+onig_compile(regex_t* reg, const UChar* pattern, const UChar* pattern_end,
+	     OnigErrorInfo* einfo)
+#endif
+{
+#define COMPILE_INIT_SIZE  20
+
+  int r;
+  OnigDistance init_size;
+  Node*  root;
+  ScanEnv  scan_env = {0};
+#ifdef USE_SUBEXP_CALL
+  UnsetAddrList  uslist;
+#endif
+
+  if (IS_NOT_NULL(einfo)) einfo->par = (UChar* )NULL;
+
+#ifdef RUBY
+  scan_env.sourcefile = sourcefile;
+  scan_env.sourceline = sourceline;
+#endif
+
+#ifdef ONIG_DEBUG
+  print_enc_string(stderr, reg->enc, pattern, pattern_end);
+#endif
+
+  if (reg->alloc == 0) {
+    init_size = (pattern_end - pattern) * 2;
+    if (init_size <= 0) init_size = COMPILE_INIT_SIZE;
+    r = BBUF_INIT(reg, init_size);
+    if (r != 0) goto end;
+  }
+  else
+    reg->used = 0;
+
+  reg->num_mem            = 0;
+  reg->num_repeat         = 0;
+  reg->num_null_check     = 0;
+  reg->repeat_range_alloc = 0;
+  reg->repeat_range       = (OnigRepeatRange* )NULL;
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+  reg->num_comb_exp_check = 0;
+#endif
+
+  r = onig_parse_make_tree(&root, pattern, pattern_end, reg, &scan_env);
+  if (r != 0) goto err;
+
+#ifdef ONIG_DEBUG_PARSE_TREE
+# if 0
+  fprintf(stderr, "ORIGINAL PARSE TREE:\n");
+  print_tree(stderr, root);
+# endif
+#endif
+
+#ifdef USE_NAMED_GROUP
+  /* mixed use named group and no-named group */
+  if (scan_env.num_named > 0 &&
+      IS_SYNTAX_BV(scan_env.syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) &&
+      !ONIG_IS_OPTION_ON(reg->options, ONIG_OPTION_CAPTURE_GROUP)) {
+    if (scan_env.num_named != scan_env.num_mem)
+      r = disable_noname_group_capture(&root, reg, &scan_env);
+    else
+      r = numbered_ref_check(root);
+
+    if (r != 0) goto err;
+  }
+#endif
+
+#ifdef USE_SUBEXP_CALL
+  if (scan_env.num_call > 0) {
+    r = unset_addr_list_init(&uslist, scan_env.num_call);
+    if (r != 0) goto err;
+    scan_env.unset_addr_list = &uslist;
+    r = setup_subexp_call(root, &scan_env);
+    if (r != 0) goto err_unset;
+    r = subexp_recursive_check_trav(root, &scan_env);
+    if (r  < 0) goto err_unset;
+    r = subexp_inf_recursive_check_trav(root, &scan_env);
+    if (r != 0) goto err_unset;
+
+    reg->num_call = scan_env.num_call;
+  }
+  else
+    reg->num_call = 0;
+#endif
+
+  r = setup_tree(root, reg, 0, &scan_env);
+  if (r != 0) goto err_unset;
+
+#ifdef ONIG_DEBUG_PARSE_TREE
+  print_tree(stderr, root);
+#endif
+
+  reg->capture_history  = scan_env.capture_history;
+  reg->bt_mem_start     = scan_env.bt_mem_start;
+  reg->bt_mem_start    |= reg->capture_history;
+  if (IS_FIND_CONDITION(reg->options))
+    BIT_STATUS_ON_ALL(reg->bt_mem_end);
+  else {
+    reg->bt_mem_end  = scan_env.bt_mem_end;
+    reg->bt_mem_end |= reg->capture_history;
+  }
+
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+  if (scan_env.backrefed_mem == 0
+# ifdef USE_SUBEXP_CALL
+      || scan_env.num_call == 0
+# endif
+      ) {
+    setup_comb_exp_check(root, 0, &scan_env);
+# ifdef USE_SUBEXP_CALL
+    if (scan_env.has_recursion != 0) {
+      scan_env.num_comb_exp_check = 0;
+    }
+    else
+# endif
+    if (scan_env.comb_exp_max_regnum > 0) {
+      int i;
+      for (i = 1; i <= scan_env.comb_exp_max_regnum; i++) {
+	if (BIT_STATUS_AT(scan_env.backrefed_mem, i) != 0) {
+	  scan_env.num_comb_exp_check = 0;
+	  break;
+	}
+      }
+    }
+  }
+
+  reg->num_comb_exp_check = scan_env.num_comb_exp_check;
+#endif
+
+  clear_optimize_info(reg);
+#ifndef ONIG_DONT_OPTIMIZE
+  r = set_optimize_info_from_tree(root, reg, &scan_env);
+  if (r != 0) goto err_unset;
+#endif
+
+  if (IS_NOT_NULL(scan_env.mem_nodes_dynamic)) {
+    xfree(scan_env.mem_nodes_dynamic);
+    scan_env.mem_nodes_dynamic = (Node** )NULL;
+  }
+
+  r = compile_tree(root, reg);
+  if (r == 0) {
+    r = add_opcode(reg, OP_END);
+#ifdef USE_SUBEXP_CALL
+    if (scan_env.num_call > 0) {
+      r = unset_addr_list_fix(&uslist, reg);
+      unset_addr_list_end(&uslist);
+      if (r) goto err;
+    }
+#endif
+
+    if ((reg->num_repeat != 0) || (reg->bt_mem_end != 0))
+      reg->stack_pop_level = STACK_POP_LEVEL_ALL;
+    else {
+      if (reg->bt_mem_start != 0)
+	reg->stack_pop_level = STACK_POP_LEVEL_MEM_START;
+      else
+	reg->stack_pop_level = STACK_POP_LEVEL_FREE;
+    }
+  }
+#ifdef USE_SUBEXP_CALL
+  else if (scan_env.num_call > 0) {
+    unset_addr_list_end(&uslist);
+  }
+#endif
+  onig_node_free(root);
+
+#ifdef ONIG_DEBUG_COMPILE
+# ifdef USE_NAMED_GROUP
+  onig_print_names(stderr, reg);
+# endif
+  print_compiled_byte_code_list(stderr, reg);
+#endif
+
+ end:
+  return r;
+
+ err_unset:
+#ifdef USE_SUBEXP_CALL
+  if (scan_env.num_call > 0) {
+    unset_addr_list_end(&uslist);
+  }
+#endif
+ err:
+  if (IS_NOT_NULL(scan_env.error)) {
+    if (IS_NOT_NULL(einfo)) {
+      einfo->enc     = scan_env.enc;
+      einfo->par     = scan_env.error;
+      einfo->par_end = scan_env.error_end;
+    }
+  }
+
+  onig_node_free(root);
+  if (IS_NOT_NULL(scan_env.mem_nodes_dynamic))
+      xfree(scan_env.mem_nodes_dynamic);
+  return r;
+}
+
+static int onig_inited = 0;
+
+extern int
+onig_reg_init(regex_t* reg, OnigOptionType option,
+	      OnigCaseFoldType case_fold_flag,
+	      OnigEncoding enc, const OnigSyntaxType* syntax)
+{
+  if (! onig_inited)
+    onig_init();
+
+  if (IS_NULL(reg))
+    return ONIGERR_INVALID_ARGUMENT;
+
+  if (ONIGENC_IS_UNDEF(enc))
+    return ONIGERR_DEFAULT_ENCODING_IS_NOT_SET;
+
+  if ((option & (ONIG_OPTION_DONT_CAPTURE_GROUP|ONIG_OPTION_CAPTURE_GROUP))
+      == (ONIG_OPTION_DONT_CAPTURE_GROUP|ONIG_OPTION_CAPTURE_GROUP)) {
+    return ONIGERR_INVALID_COMBINATION_OF_OPTIONS;
+  }
+
+  if ((option & ONIG_OPTION_NEGATE_SINGLELINE) != 0) {
+    option |= syntax->options;
+    option &= ~ONIG_OPTION_SINGLELINE;
+  }
+  else
+    option |= syntax->options;
+
+  (reg)->enc              = enc;
+  (reg)->options          = option;
+  (reg)->syntax           = syntax;
+  (reg)->optimize         = 0;
+  (reg)->exact            = (UChar* )NULL;
+  (reg)->int_map          = (int* )NULL;
+  (reg)->int_map_backward = (int* )NULL;
+  (reg)->chain            = (regex_t* )NULL;
+
+  (reg)->p                = (UChar* )NULL;
+  (reg)->alloc            = 0;
+  (reg)->used             = 0;
+  (reg)->name_table       = (void* )NULL;
+
+  (reg)->case_fold_flag   = case_fold_flag;
+  return 0;
+}
+
+extern int
+onig_new_without_alloc(regex_t* reg, const UChar* pattern,
+          const UChar* pattern_end, OnigOptionType option, OnigEncoding enc,
+          const OnigSyntaxType* syntax, OnigErrorInfo* einfo)
+{
+  int r;
+
+  r = onig_reg_init(reg, option, ONIGENC_CASE_FOLD_DEFAULT, enc, syntax);
+  if (r) return r;
+
+  r = onig_compile(reg, pattern, pattern_end, einfo);
+  return r;
+}
+
+extern int
+onig_new(regex_t** reg, const UChar* pattern, const UChar* pattern_end,
+	  OnigOptionType option, OnigEncoding enc, const OnigSyntaxType* syntax,
+	  OnigErrorInfo* einfo)
+{
+  int r;
+
+  *reg = (regex_t* )xmalloc(sizeof(regex_t));
+  if (IS_NULL(*reg)) return ONIGERR_MEMORY;
+
+  r = onig_reg_init(*reg, option, ONIGENC_CASE_FOLD_DEFAULT, enc, syntax);
+  if (r) goto err;
+
+  r = onig_compile(*reg, pattern, pattern_end, einfo);
+  if (r) {
+  err:
+    onig_free(*reg);
+    *reg = NULL;
+  }
+  return r;
+}
+
+extern int
+onig_initialize(OnigEncoding encodings[] ARG_UNUSED, int n ARG_UNUSED)
+{
+  return onig_init();
+}
+
+extern int
+onig_init(void)
+{
+  if (onig_inited != 0)
+    return 0;
+
+  onig_inited = 1;
+
+#if defined(ONIG_DEBUG_MEMLEAK) && defined(_MSC_VER)
+  _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+
+  onigenc_init();
+  /* onigenc_set_default_caseconv_table((UChar* )0); */
+
+#ifdef ONIG_DEBUG_STATISTICS
+  onig_statistics_init();
+#endif
+
+  return 0;
+}
+
+
+static OnigEndCallListItemType* EndCallTop;
+
+extern void onig_add_end_call(void (*func)(void))
+{
+  OnigEndCallListItemType* item;
+
+  item = (OnigEndCallListItemType* )xmalloc(sizeof(*item));
+  if (item == 0) return ;
+
+  item->next = EndCallTop;
+  item->func = func;
+
+  EndCallTop = item;
+}
+
+static void
+exec_end_call_list(void)
+{
+  OnigEndCallListItemType* prev;
+  void (*func)(void);
+
+  while (EndCallTop != 0) {
+    func = EndCallTop->func;
+    (*func)();
+
+    prev = EndCallTop;
+    EndCallTop = EndCallTop->next;
+    xfree(prev);
+  }
+}
+
+extern int
+onig_end(void)
+{
+  exec_end_call_list();
+
+#ifdef ONIG_DEBUG_STATISTICS
+  onig_print_statistics(stderr);
+#endif
+
+#if defined(ONIG_DEBUG_MEMLEAK) && defined(_MSC_VER)
+  _CrtDumpMemoryLeaks();
+#endif
+
+  onig_inited = 0;
+
+  return 0;
+}
+
+extern int
+onig_is_in_code_range(const UChar* p, OnigCodePoint code)
+{
+  OnigCodePoint n, *data;
+  OnigCodePoint low, high, x;
+
+  GET_CODE_POINT(n, p);
+  data = (OnigCodePoint* )p;
+  data++;
+
+  for (low = 0, high = n; low < high; ) {
+    x = (low + high) >> 1;
+    if (code > data[x * 2 + 1])
+      low = x + 1;
+    else
+      high = x;
+  }
+
+  return ((low < n && code >= data[low * 2]) ? 1 : 0);
+}
+
+extern int
+onig_is_code_in_cc_len(int elen, OnigCodePoint code, CClassNode* cc)
+{
+  int found;
+
+  if (elen > 1 || (code >= SINGLE_BYTE_SIZE)) {
+    if (IS_NULL(cc->mbuf)) {
+      found = 0;
+    }
+    else {
+      found = (onig_is_in_code_range(cc->mbuf->p, code) != 0 ? 1 : 0);
+    }
+  }
+  else {
+    found = (BITSET_AT(cc->bs, code) == 0 ? 0 : 1);
+  }
+
+  if (IS_NCCLASS_NOT(cc))
+    return !found;
+  else
+    return found;
+}
+
+extern int
+onig_is_code_in_cc(OnigEncoding enc, OnigCodePoint code, CClassNode* cc)
+{
+  int len;
+
+  if (ONIGENC_MBC_MINLEN(enc) > 1) {
+    len = 2;
+  }
+  else {
+    len = ONIGENC_CODE_TO_MBCLEN(enc, code);
+  }
+  return onig_is_code_in_cc_len(len, code, cc);
+}
+
+
+#ifdef ONIG_DEBUG
+
+/* arguments type */
+# define ARG_SPECIAL     -1
+# define ARG_NON          0
+# define ARG_RELADDR      1
+# define ARG_ABSADDR      2
+# define ARG_LENGTH       3
+# define ARG_MEMNUM       4
+# define ARG_OPTION       5
+# define ARG_STATE_CHECK  6
+
+OnigOpInfoType OnigOpInfo[] = {
+  { OP_FINISH,            "finish",          ARG_NON },
+  { OP_END,               "end",             ARG_NON },
+  { OP_EXACT1,            "exact1",          ARG_SPECIAL },
+  { OP_EXACT2,            "exact2",          ARG_SPECIAL },
+  { OP_EXACT3,            "exact3",          ARG_SPECIAL },
+  { OP_EXACT4,            "exact4",          ARG_SPECIAL },
+  { OP_EXACT5,            "exact5",          ARG_SPECIAL },
+  { OP_EXACTN,            "exactn",          ARG_SPECIAL },
+  { OP_EXACTMB2N1,        "exactmb2-n1",     ARG_SPECIAL },
+  { OP_EXACTMB2N2,        "exactmb2-n2",     ARG_SPECIAL },
+  { OP_EXACTMB2N3,        "exactmb2-n3",     ARG_SPECIAL },
+  { OP_EXACTMB2N,         "exactmb2-n",      ARG_SPECIAL },
+  { OP_EXACTMB3N,         "exactmb3n"  ,     ARG_SPECIAL },
+  { OP_EXACTMBN,          "exactmbn",        ARG_SPECIAL },
+  { OP_EXACT1_IC,         "exact1-ic",       ARG_SPECIAL },
+  { OP_EXACTN_IC,         "exactn-ic",       ARG_SPECIAL },
+  { OP_CCLASS,            "cclass",          ARG_SPECIAL },
+  { OP_CCLASS_MB,         "cclass-mb",       ARG_SPECIAL },
+  { OP_CCLASS_MIX,        "cclass-mix",      ARG_SPECIAL },
+  { OP_CCLASS_NOT,        "cclass-not",      ARG_SPECIAL },
+  { OP_CCLASS_MB_NOT,     "cclass-mb-not",   ARG_SPECIAL },
+  { OP_CCLASS_MIX_NOT,    "cclass-mix-not",  ARG_SPECIAL },
+  { OP_ANYCHAR,           "anychar",         ARG_NON },
+  { OP_ANYCHAR_ML,        "anychar-ml",      ARG_NON },
+  { OP_ANYCHAR_STAR,      "anychar*",        ARG_NON },
+  { OP_ANYCHAR_ML_STAR,   "anychar-ml*",     ARG_NON },
+  { OP_ANYCHAR_STAR_PEEK_NEXT, "anychar*-peek-next", ARG_SPECIAL },
+  { OP_ANYCHAR_ML_STAR_PEEK_NEXT, "anychar-ml*-peek-next", ARG_SPECIAL },
+  { OP_WORD,                "word",            ARG_NON },
+  { OP_NOT_WORD,            "not-word",        ARG_NON },
+  { OP_WORD_BOUND,          "word-bound",      ARG_NON },
+  { OP_NOT_WORD_BOUND,      "not-word-bound",  ARG_NON },
+  { OP_WORD_BEGIN,          "word-begin",      ARG_NON },
+  { OP_WORD_END,            "word-end",        ARG_NON },
+  { OP_ASCII_WORD,          "ascii-word",           ARG_NON },
+  { OP_NOT_ASCII_WORD,      "not-ascii-word",       ARG_NON },
+  { OP_ASCII_WORD_BOUND,    "ascii-word-bound",     ARG_NON },
+  { OP_NOT_ASCII_WORD_BOUND,"not-ascii-word-bound", ARG_NON },
+  { OP_ASCII_WORD_BEGIN,    "ascii-word-begin",     ARG_NON },
+  { OP_ASCII_WORD_END,      "ascii-word-end",       ARG_NON },
+  { OP_BEGIN_BUF,           "begin-buf",       ARG_NON },
+  { OP_END_BUF,             "end-buf",         ARG_NON },
+  { OP_BEGIN_LINE,          "begin-line",      ARG_NON },
+  { OP_END_LINE,            "end-line",        ARG_NON },
+  { OP_SEMI_END_BUF,        "semi-end-buf",    ARG_NON },
+  { OP_BEGIN_POSITION,      "begin-position",  ARG_NON },
+  { OP_BACKREF1,            "backref1",             ARG_NON },
+  { OP_BACKREF2,            "backref2",             ARG_NON },
+  { OP_BACKREFN,            "backrefn",             ARG_MEMNUM  },
+  { OP_BACKREFN_IC,         "backrefn-ic",          ARG_SPECIAL },
+  { OP_BACKREF_MULTI,       "backref_multi",        ARG_SPECIAL },
+  { OP_BACKREF_MULTI_IC,    "backref_multi-ic",     ARG_SPECIAL },
+  { OP_BACKREF_WITH_LEVEL,  "backref_at_level",     ARG_SPECIAL },
+  { OP_MEMORY_START_PUSH,   "mem-start-push",       ARG_MEMNUM  },
+  { OP_MEMORY_START,        "mem-start",            ARG_MEMNUM  },
+  { OP_MEMORY_END_PUSH,     "mem-end-push",         ARG_MEMNUM  },
+  { OP_MEMORY_END_PUSH_REC, "mem-end-push-rec",     ARG_MEMNUM  },
+  { OP_MEMORY_END,          "mem-end",              ARG_MEMNUM  },
+  { OP_MEMORY_END_REC,      "mem-end-rec",          ARG_MEMNUM  },
+  { OP_SET_OPTION_PUSH,     "set-option-push",      ARG_OPTION  },
+  { OP_SET_OPTION,          "set-option",           ARG_OPTION  },
+  { OP_KEEP,                "keep",                 ARG_NON },
+  { OP_FAIL,                "fail",                 ARG_NON },
+  { OP_JUMP,                "jump",                 ARG_RELADDR },
+  { OP_PUSH,                "push",                 ARG_RELADDR },
+  { OP_POP,                 "pop",                  ARG_NON },
+  { OP_PUSH_OR_JUMP_EXACT1, "push-or-jump-e1",      ARG_SPECIAL },
+  { OP_PUSH_IF_PEEK_NEXT,   "push-if-peek-next",    ARG_SPECIAL },
+  { OP_REPEAT,              "repeat",               ARG_SPECIAL },
+  { OP_REPEAT_NG,           "repeat-ng",            ARG_SPECIAL },
+  { OP_REPEAT_INC,          "repeat-inc",           ARG_MEMNUM  },
+  { OP_REPEAT_INC_NG,       "repeat-inc-ng",        ARG_MEMNUM  },
+  { OP_REPEAT_INC_SG,       "repeat-inc-sg",        ARG_MEMNUM  },
+  { OP_REPEAT_INC_NG_SG,    "repeat-inc-ng-sg",     ARG_MEMNUM  },
+  { OP_NULL_CHECK_START,    "null-check-start",     ARG_MEMNUM  },
+  { OP_NULL_CHECK_END,      "null-check-end",       ARG_MEMNUM  },
+  { OP_NULL_CHECK_END_MEMST,"null-check-end-memst", ARG_MEMNUM  },
+  { OP_NULL_CHECK_END_MEMST_PUSH,"null-check-end-memst-push", ARG_MEMNUM  },
+  { OP_PUSH_POS,             "push-pos",             ARG_NON },
+  { OP_POP_POS,              "pop-pos",              ARG_NON },
+  { OP_PUSH_POS_NOT,         "push-pos-not",         ARG_RELADDR },
+  { OP_FAIL_POS,             "fail-pos",             ARG_NON },
+  { OP_PUSH_STOP_BT,         "push-stop-bt",         ARG_NON },
+  { OP_POP_STOP_BT,          "pop-stop-bt",          ARG_NON },
+  { OP_LOOK_BEHIND,          "look-behind",          ARG_SPECIAL },
+  { OP_PUSH_LOOK_BEHIND_NOT, "push-look-behind-not", ARG_SPECIAL },
+  { OP_FAIL_LOOK_BEHIND_NOT, "fail-look-behind-not", ARG_NON },
+  { OP_PUSH_ABSENT_POS,      "push-absent-pos",      ARG_NON },
+  { OP_ABSENT,               "absent",               ARG_RELADDR },
+  { OP_ABSENT_END,           "absent-end",           ARG_NON },
+  { OP_CALL,                 "call",                 ARG_ABSADDR },
+  { OP_RETURN,               "return",               ARG_NON },
+  { OP_CONDITION,            "condition",            ARG_SPECIAL },
+  { OP_STATE_CHECK_PUSH,         "state-check-push",         ARG_SPECIAL },
+  { OP_STATE_CHECK_PUSH_OR_JUMP, "state-check-push-or-jump", ARG_SPECIAL },
+  { OP_STATE_CHECK,              "state-check",              ARG_STATE_CHECK },
+  { OP_STATE_CHECK_ANYCHAR_STAR, "state-check-anychar*",     ARG_STATE_CHECK },
+  { OP_STATE_CHECK_ANYCHAR_ML_STAR,
+    "state-check-anychar-ml*", ARG_STATE_CHECK },
+  { -1, "", ARG_NON }
+};
+
+static const char*
+op2name(int opcode)
+{
+  int i;
+
+  for (i = 0; OnigOpInfo[i].opcode >= 0; i++) {
+    if (opcode == OnigOpInfo[i].opcode)
+      return OnigOpInfo[i].name;
+  }
+  return "";
+}
+
+static int
+op2arg_type(int opcode)
+{
+  int i;
+
+  for (i = 0; OnigOpInfo[i].opcode >= 0; i++) {
+    if (opcode == OnigOpInfo[i].opcode)
+      return OnigOpInfo[i].arg_type;
+  }
+  return ARG_SPECIAL;
+}
+
+# ifdef ONIG_DEBUG_PARSE_TREE
+static void
+Indent(FILE* f, int indent)
+{
+  int i;
+  for (i = 0; i < indent; i++) putc(' ', f);
+}
+# endif /* ONIG_DEBUG_PARSE_TREE */
+
+static void
+p_string(FILE* f, ptrdiff_t len, UChar* s)
+{
+  fputs(":", f);
+  while (len-- > 0) { fputc(*s++, f); }
+}
+
+static void
+p_len_string(FILE* f, LengthType len, int mb_len, UChar* s)
+{
+  int x = len * mb_len;
+
+  fprintf(f, ":%d:", len);
+  while (x-- > 0) { fputc(*s++, f); }
+}
+
+extern void
+onig_print_compiled_byte_code(FILE* f, UChar* bp, UChar* bpend, UChar** nextp,
+                              OnigEncoding enc)
+{
+  int i, n, arg_type;
+  RelAddrType addr;
+  LengthType len;
+  MemNumType mem;
+  StateCheckNumType scn;
+  OnigCodePoint code;
+  UChar *q;
+
+  fprintf(f, "[%s", op2name(*bp));
+  arg_type = op2arg_type(*bp);
+  if (arg_type != ARG_SPECIAL) {
+    bp++;
+    switch (arg_type) {
+    case ARG_NON:
+      break;
+    case ARG_RELADDR:
+      GET_RELADDR_INC(addr, bp);
+      fprintf(f, ":(%s%d)", (addr >= 0) ? "+" : "", addr);
+      break;
+    case ARG_ABSADDR:
+      GET_ABSADDR_INC(addr, bp);
+      fprintf(f, ":(%d)", addr);
+      break;
+    case ARG_LENGTH:
+      GET_LENGTH_INC(len, bp);
+      fprintf(f, ":%d", len);
+      break;
+    case ARG_MEMNUM:
+      mem = *((MemNumType* )bp);
+      bp += SIZE_MEMNUM;
+      fprintf(f, ":%d", mem);
+      break;
+    case ARG_OPTION:
+      {
+	OnigOptionType option = *((OnigOptionType* )bp);
+	bp += SIZE_OPTION;
+	fprintf(f, ":%d", option);
+      }
+      break;
+
+    case ARG_STATE_CHECK:
+      scn = *((StateCheckNumType* )bp);
+      bp += SIZE_STATE_CHECK_NUM;
+      fprintf(f, ":%d", scn);
+      break;
+    }
+  }
+  else {
+    switch (*bp++) {
+    case OP_EXACT1:
+    case OP_ANYCHAR_STAR_PEEK_NEXT:
+    case OP_ANYCHAR_ML_STAR_PEEK_NEXT:
+      p_string(f, 1, bp++); break;
+    case OP_EXACT2:
+      p_string(f, 2, bp); bp += 2; break;
+    case OP_EXACT3:
+      p_string(f, 3, bp); bp += 3; break;
+    case OP_EXACT4:
+      p_string(f, 4, bp); bp += 4; break;
+    case OP_EXACT5:
+      p_string(f, 5, bp); bp += 5; break;
+    case OP_EXACTN:
+      GET_LENGTH_INC(len, bp);
+      p_len_string(f, len, 1, bp);
+      bp += len;
+      break;
+
+    case OP_EXACTMB2N1:
+      p_string(f, 2, bp); bp += 2; break;
+    case OP_EXACTMB2N2:
+      p_string(f, 4, bp); bp += 4; break;
+    case OP_EXACTMB2N3:
+      p_string(f, 6, bp); bp += 6; break;
+    case OP_EXACTMB2N:
+      GET_LENGTH_INC(len, bp);
+      p_len_string(f, len, 2, bp);
+      bp += len * 2;
+      break;
+    case OP_EXACTMB3N:
+      GET_LENGTH_INC(len, bp);
+      p_len_string(f, len, 3, bp);
+      bp += len * 3;
+      break;
+    case OP_EXACTMBN:
+      {
+	int mb_len;
+
+	GET_LENGTH_INC(mb_len, bp);
+	GET_LENGTH_INC(len, bp);
+	fprintf(f, ":%d:%d:", mb_len, len);
+	n = len * mb_len;
+	while (n-- > 0) { fputc(*bp++, f); }
+      }
+      break;
+
+    case OP_EXACT1_IC:
+      len = enclen(enc, bp, bpend);
+      p_string(f, len, bp);
+      bp += len;
+      break;
+    case OP_EXACTN_IC:
+      GET_LENGTH_INC(len, bp);
+      p_len_string(f, len, 1, bp);
+      bp += len;
+      break;
+
+    case OP_CCLASS:
+      n = bitset_on_num((BitSetRef )bp);
+      bp += SIZE_BITSET;
+      fprintf(f, ":%d", n);
+      break;
+
+    case OP_CCLASS_NOT:
+      n = bitset_on_num((BitSetRef )bp);
+      bp += SIZE_BITSET;
+      fprintf(f, ":%d", n);
+      break;
+
+    case OP_CCLASS_MB:
+    case OP_CCLASS_MB_NOT:
+      GET_LENGTH_INC(len, bp);
+      q = bp;
+# ifndef PLATFORM_UNALIGNED_WORD_ACCESS
+      ALIGNMENT_RIGHT(q);
+# endif
+      GET_CODE_POINT(code, q);
+      bp += len;
+      fprintf(f, ":%d:%d", (int )code, len);
+      break;
+
+    case OP_CCLASS_MIX:
+    case OP_CCLASS_MIX_NOT:
+      n = bitset_on_num((BitSetRef )bp);
+      bp += SIZE_BITSET;
+      GET_LENGTH_INC(len, bp);
+      q = bp;
+# ifndef PLATFORM_UNALIGNED_WORD_ACCESS
+      ALIGNMENT_RIGHT(q);
+# endif
+      GET_CODE_POINT(code, q);
+      bp += len;
+      fprintf(f, ":%d:%d:%d", n, (int )code, len);
+      break;
+
+    case OP_BACKREFN_IC:
+      mem = *((MemNumType* )bp);
+      bp += SIZE_MEMNUM;
+      fprintf(f, ":%d", mem);
+      break;
+
+    case OP_BACKREF_MULTI_IC:
+    case OP_BACKREF_MULTI:
+      fputs(" ", f);
+      GET_LENGTH_INC(len, bp);
+      for (i = 0; i < len; i++) {
+	GET_MEMNUM_INC(mem, bp);
+	if (i > 0) fputs(", ", f);
+	fprintf(f, "%d", mem);
+      }
+      break;
+
+    case OP_BACKREF_WITH_LEVEL:
+      {
+	OnigOptionType option;
+	LengthType level;
+
+	GET_OPTION_INC(option, bp);
+	fprintf(f, ":%d", option);
+	GET_LENGTH_INC(level, bp);
+	fprintf(f, ":%d", level);
+
+	fputs(" ", f);
+	GET_LENGTH_INC(len, bp);
+	for (i = 0; i < len; i++) {
+	  GET_MEMNUM_INC(mem, bp);
+	  if (i > 0) fputs(", ", f);
+	  fprintf(f, "%d", mem);
+	}
+      }
+      break;
+
+    case OP_REPEAT:
+    case OP_REPEAT_NG:
+      {
+	mem = *((MemNumType* )bp);
+	bp += SIZE_MEMNUM;
+	addr = *((RelAddrType* )bp);
+	bp += SIZE_RELADDR;
+	fprintf(f, ":%d:%d", mem, addr);
+      }
+      break;
+
+    case OP_PUSH_OR_JUMP_EXACT1:
+    case OP_PUSH_IF_PEEK_NEXT:
+      addr = *((RelAddrType* )bp);
+      bp += SIZE_RELADDR;
+      fprintf(f, ":(%s%d)", (addr >= 0) ? "+" : "", addr);
+      p_string(f, 1, bp);
+      bp += 1;
+      break;
+
+    case OP_LOOK_BEHIND:
+      GET_LENGTH_INC(len, bp);
+      fprintf(f, ":%d", len);
+      break;
+
+    case OP_PUSH_LOOK_BEHIND_NOT:
+      GET_RELADDR_INC(addr, bp);
+      GET_LENGTH_INC(len, bp);
+      fprintf(f, ":%d:(%s%d)", len, (addr >= 0) ? "+" : "", addr);
+      break;
+
+    case OP_STATE_CHECK_PUSH:
+    case OP_STATE_CHECK_PUSH_OR_JUMP:
+      scn = *((StateCheckNumType* )bp);
+      bp += SIZE_STATE_CHECK_NUM;
+      addr = *((RelAddrType* )bp);
+      bp += SIZE_RELADDR;
+      fprintf(f, ":%d:(%s%d)", scn, (addr >= 0) ? "+" : "", addr);
+      break;
+
+    case OP_CONDITION:
+      GET_MEMNUM_INC(mem, bp);
+      GET_RELADDR_INC(addr, bp);
+      fprintf(f, ":%d:(%s%d)", mem, (addr >= 0) ? "+" : "", addr);
+      break;
+
+    default:
+      fprintf(stderr, "onig_print_compiled_byte_code: undefined code %d\n",
+	      bp[-1]);
+    }
+  }
+  fputs("]", f);
+  if (nextp) *nextp = bp;
+}
+
+# ifdef ONIG_DEBUG_COMPILE
+static void
+print_compiled_byte_code_list(FILE* f, regex_t* reg)
+{
+  int ncode;
+  UChar* bp = reg->p;
+  UChar* end = reg->p + reg->used;
+
+  fprintf(f, "code length: %d", reg->used);
+
+  ncode = -1;
+  while (bp < end) {
+    ncode++;
+    if (ncode % 5 == 0)
+      fprintf(f, "\n%ld:", bp - reg->p);
+    else
+      fprintf(f, " %ld:", bp - reg->p);
+    onig_print_compiled_byte_code(f, bp, end, &bp, reg->enc);
+  }
+
+  fprintf(f, "\n");
+}
+# endif /* ONIG_DEBUG_COMPILE */
+
+# ifdef ONIG_DEBUG_PARSE_TREE
+static void
+print_indent_tree(FILE* f, Node* node, int indent)
+{
+  int i, type, container_p = 0;
+  int add = 3;
+  UChar* p;
+
+  Indent(f, indent);
+  if (IS_NULL(node)) {
+    fprintf(f, "ERROR: null node!!!\n");
+    exit (0);
+  }
+
+  type = NTYPE(node);
+  switch (type) {
+  case NT_LIST:
+  case NT_ALT:
+    if (NTYPE(node) == NT_LIST)
+      fprintf(f, "<list:%"PRIxPTR">\n", (intptr_t )node);
+    else
+      fprintf(f, "<alt:%"PRIxPTR">\n", (intptr_t )node);
+
+    print_indent_tree(f, NCAR(node), indent + add);
+    while (IS_NOT_NULL(node = NCDR(node))) {
+      if (NTYPE(node) != type) {
+	fprintf(f, "ERROR: list/alt right is not a cons. %d\n", NTYPE(node));
+	exit(0);
+      }
+      print_indent_tree(f, NCAR(node), indent + add);
+    }
+    break;
+
+  case NT_STR:
+    fprintf(f, "<string%s:%"PRIxPTR">",
+	    (NSTRING_IS_RAW(node) ? "-raw" : ""), (intptr_t )node);
+    for (p = NSTR(node)->s; p < NSTR(node)->end; p++) {
+      if (*p >= 0x20 && *p < 0x7f)
+	fputc(*p, f);
+      else {
+	fprintf(f, " 0x%02x", *p);
+      }
+    }
+    break;
+
+  case NT_CCLASS:
+    fprintf(f, "<cclass:%"PRIxPTR">", (intptr_t )node);
+    if (IS_NCCLASS_NOT(NCCLASS(node))) fputs("not ", f);
+    if (NCCLASS(node)->mbuf) {
+      BBuf* bbuf = NCCLASS(node)->mbuf;
+      OnigCodePoint* data = (OnigCodePoint* )bbuf->p;
+      OnigCodePoint* end = (OnigCodePoint* )(bbuf->p + bbuf->used);
+      fprintf(f, "%d", *data++);
+      for (; data < end; data+=2) {
+	fprintf(f, ",");
+	fprintf(f, "%04x-%04x", data[0], data[1]);
+      }
+    }
+    break;
+
+  case NT_CTYPE:
+    fprintf(f, "<ctype:%"PRIxPTR"> ", (intptr_t )node);
+    switch (NCTYPE(node)->ctype) {
+    case ONIGENC_CTYPE_WORD:
+      if (NCTYPE(node)->not != 0)
+	fputs("not word",       f);
+      else
+	fputs("word",           f);
+      break;
+
+    default:
+      fprintf(f, "ERROR: undefined ctype.\n");
+      exit(0);
+    }
+    break;
+
+  case NT_CANY:
+    fprintf(f, "<anychar:%"PRIxPTR">", (intptr_t )node);
+    break;
+
+  case NT_ANCHOR:
+    fprintf(f, "<anchor:%"PRIxPTR"> ", (intptr_t )node);
+    switch (NANCHOR(node)->type) {
+    case ANCHOR_BEGIN_BUF:      fputs("begin buf",      f); break;
+    case ANCHOR_END_BUF:        fputs("end buf",        f); break;
+    case ANCHOR_BEGIN_LINE:     fputs("begin line",     f); break;
+    case ANCHOR_END_LINE:       fputs("end line",       f); break;
+    case ANCHOR_SEMI_END_BUF:   fputs("semi end buf",   f); break;
+    case ANCHOR_BEGIN_POSITION: fputs("begin position", f); break;
+
+    case ANCHOR_WORD_BOUND:      fputs("word bound",     f); break;
+    case ANCHOR_NOT_WORD_BOUND:  fputs("not word bound", f); break;
+#  ifdef USE_WORD_BEGIN_END
+    case ANCHOR_WORD_BEGIN:      fputs("word begin", f);     break;
+    case ANCHOR_WORD_END:        fputs("word end", f);       break;
+#  endif
+    case ANCHOR_PREC_READ:       fputs("prec read",      f); container_p = TRUE; break;
+    case ANCHOR_PREC_READ_NOT:   fputs("prec read not",  f); container_p = TRUE; break;
+    case ANCHOR_LOOK_BEHIND:     fputs("look_behind",    f); container_p = TRUE; break;
+    case ANCHOR_LOOK_BEHIND_NOT: fputs("look_behind_not",f); container_p = TRUE; break;
+    case ANCHOR_KEEP:            fputs("keep",f);            break;
+
+    default:
+      fprintf(f, "ERROR: undefined anchor type.\n");
+      break;
+    }
+    break;
+
+  case NT_BREF:
+    {
+      int* p;
+      BRefNode* br = NBREF(node);
+      p = BACKREFS_P(br);
+      fprintf(f, "<backref:%"PRIxPTR">", (intptr_t )node);
+      for (i = 0; i < br->back_num; i++) {
+	if (i > 0) fputs(", ", f);
+	fprintf(f, "%d", p[i]);
+      }
+    }
+    break;
+
+#  ifdef USE_SUBEXP_CALL
+  case NT_CALL:
+    {
+      CallNode* cn = NCALL(node);
+      fprintf(f, "<call:%"PRIxPTR">", (intptr_t )node);
+      p_string(f, cn->name_end - cn->name, cn->name);
+    }
+    break;
+#  endif
+
+  case NT_QTFR:
+    fprintf(f, "<quantifier:%"PRIxPTR">{%d,%d}%s\n", (intptr_t )node,
+	    NQTFR(node)->lower, NQTFR(node)->upper,
+	    (NQTFR(node)->greedy ? "" : "?"));
+    print_indent_tree(f, NQTFR(node)->target, indent + add);
+    break;
+
+  case NT_ENCLOSE:
+    fprintf(f, "<enclose:%"PRIxPTR"> ", (intptr_t )node);
+    switch (NENCLOSE(node)->type) {
+    case ENCLOSE_OPTION:
+      fprintf(f, "option:%d", NENCLOSE(node)->option);
+      break;
+    case ENCLOSE_MEMORY:
+      fprintf(f, "memory:%d", NENCLOSE(node)->regnum);
+      break;
+    case ENCLOSE_STOP_BACKTRACK:
+      fprintf(f, "stop-bt");
+      break;
+    case ENCLOSE_CONDITION:
+      fprintf(f, "condition:%d", NENCLOSE(node)->regnum);
+      break;
+    case ENCLOSE_ABSENT:
+      fprintf(f, "absent");
+      break;
+
+    default:
+      break;
+    }
+    fprintf(f, "\n");
+    print_indent_tree(f, NENCLOSE(node)->target, indent + add);
+    break;
+
+  default:
+    fprintf(f, "print_indent_tree: undefined node type %d\n", NTYPE(node));
+    break;
+  }
+
+  if (type != NT_LIST && type != NT_ALT && type != NT_QTFR &&
+      type != NT_ENCLOSE)
+    fprintf(f, "\n");
+
+  if (container_p) print_indent_tree(f, NANCHOR(node)->target, indent + add);
+
+  fflush(f);
+}
+
+static void
+print_tree(FILE* f, Node* node)
+{
+  print_indent_tree(f, node, 0);
+}
+# endif /* ONIG_DEBUG_PARSE_TREE */
+#endif /* ONIG_DEBUG */
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/regenc.c
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/regenc.c	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/regenc.c	(revision 331)
@@ -0,0 +1,1012 @@
+/**********************************************************************
+  regenc.c -  Onigmo (Oniguruma-mod) (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2007  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011-2016  K.Takata  <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "regint.h"
+
+OnigEncoding OnigEncDefaultCharEncoding = ONIG_ENCODING_INIT_DEFAULT;
+
+extern int
+onigenc_init(void)
+{
+  return 0;
+}
+
+extern OnigEncoding
+onigenc_get_default_encoding(void)
+{
+  return OnigEncDefaultCharEncoding;
+}
+
+extern int
+onigenc_set_default_encoding(OnigEncoding enc)
+{
+  OnigEncDefaultCharEncoding = enc;
+  return 0;
+}
+
+extern int
+onigenc_mbclen_approximate(const OnigUChar* p,const OnigUChar* e, OnigEncoding enc)
+{
+  int ret = ONIGENC_PRECISE_MBC_ENC_LEN(enc, p, e);
+  if (ONIGENC_MBCLEN_CHARFOUND_P(ret))
+    return ONIGENC_MBCLEN_CHARFOUND_LEN(ret);
+  else if (ONIGENC_MBCLEN_NEEDMORE_P(ret))
+    return (int )(e - p) + ONIGENC_MBCLEN_NEEDMORE_LEN(ret);
+  return 1;
+}
+
+extern UChar*
+onigenc_get_right_adjust_char_head(OnigEncoding enc, const UChar* start, const UChar* s, const UChar* end)
+{
+  UChar* p = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, start, s, end);
+  if (p < s) {
+    p += enclen(enc, p, end);
+  }
+  return p;
+}
+
+extern UChar*
+onigenc_get_right_adjust_char_head_with_prev(OnigEncoding enc,
+				   const UChar* start, const UChar* s, const UChar* end, const UChar** prev)
+{
+  UChar* p = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, start, s, end);
+
+  if (p < s) {
+    if (prev) *prev = (const UChar* )p;
+    p += enclen(enc, p, end);
+  }
+  else {
+    if (prev) *prev = (const UChar* )NULL; /* Sorry */
+  }
+  return p;
+}
+
+extern UChar*
+onigenc_get_prev_char_head(OnigEncoding enc, const UChar* start, const UChar* s, const UChar* end)
+{
+  if (s <= start)
+    return (UChar* )NULL;
+
+  return ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, start, s - 1, end);
+}
+
+extern UChar*
+onigenc_step_back(OnigEncoding enc, const UChar* start, const UChar* s, const UChar* end, int n)
+{
+  while (ONIG_IS_NOT_NULL(s) && n-- > 0) {
+    if (s <= start)
+      return (UChar* )NULL;
+
+    s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, start, s - 1, end);
+  }
+  return (UChar* )s;
+}
+
+extern UChar*
+onigenc_step(OnigEncoding enc, const UChar* p, const UChar* end, int n)
+{
+  UChar* q = (UChar* )p;
+  while (n-- > 0) {
+    q += ONIGENC_MBC_ENC_LEN(enc, q, end);
+  }
+  return (q <= end ? q : NULL);
+}
+
+extern int
+onigenc_strlen(OnigEncoding enc, const UChar* p, const UChar* end)
+{
+  int n = 0;
+  UChar* q = (UChar* )p;
+
+  while (q < end) {
+    q += ONIGENC_MBC_ENC_LEN(enc, q, end);
+    n++;
+  }
+  return n;
+}
+
+extern int
+onigenc_strlen_null(OnigEncoding enc, const UChar* s)
+{
+  int n = 0;
+  UChar* p = (UChar* )s;
+  UChar* e;
+
+  while (1) {
+    if (*p == '\0') {
+      UChar* q;
+      int len = ONIGENC_MBC_MINLEN(enc);
+
+      if (len == 1) return n;
+      q = p + 1;
+      while (len > 1) {
+        if (*q != '\0') break;
+        q++;
+        len--;
+      }
+      if (len == 1) return n;
+    }
+    e = p + ONIGENC_MBC_MAXLEN(enc);
+    p += ONIGENC_MBC_ENC_LEN(enc, p, e);
+    n++;
+  }
+}
+
+extern int
+onigenc_str_bytelen_null(OnigEncoding enc, const UChar* s)
+{
+  UChar* start = (UChar* )s;
+  UChar* p = (UChar* )s;
+  UChar* e;
+
+  while (1) {
+    if (*p == '\0') {
+      UChar* q;
+      int len = ONIGENC_MBC_MINLEN(enc);
+
+      if (len == 1) return (int )(p - start);
+      q = p + 1;
+      while (len > 1) {
+        if (*q != '\0') break;
+        q++;
+        len--;
+      }
+      if (len == 1) return (int )(p - start);
+    }
+    e = p + ONIGENC_MBC_MAXLEN(enc);
+    p += ONIGENC_MBC_ENC_LEN(enc, p, e);
+  }
+}
+
+const UChar OnigEncAsciiToLowerCaseTable[] = {
+  '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+  '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+  '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+  '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+  '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
+  '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
+  '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
+  '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
+  '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+  '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+  '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+  '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
+  '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+  '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+  '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+  '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
+  '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
+  '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
+  '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
+  '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
+  '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
+  '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
+  '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
+  '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
+  '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
+  '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
+  '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
+  '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
+  '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+  '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+  '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+  '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
+};
+
+#ifdef USE_UPPER_CASE_TABLE
+const UChar OnigEncAsciiToUpperCaseTable[256] = {
+  '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+  '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+  '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+  '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+  '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
+  '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
+  '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
+  '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
+  '\100', '\101', '\102', '\103', '\104', '\105', '\106', '\107',
+  '\110', '\111', '\112', '\113', '\114', '\115', '\116', '\117',
+  '\120', '\121', '\122', '\123', '\124', '\125', '\126', '\127',
+  '\130', '\131', '\132', '\133', '\134', '\135', '\136', '\137',
+  '\140', '\101', '\102', '\103', '\104', '\105', '\106', '\107',
+  '\110', '\111', '\112', '\113', '\114', '\115', '\116', '\117',
+  '\120', '\121', '\122', '\123', '\124', '\125', '\126', '\127',
+  '\130', '\131', '\132', '\173', '\174', '\175', '\176', '\177',
+  '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
+  '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
+  '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
+  '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
+  '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
+  '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
+  '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
+  '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
+  '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
+  '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
+  '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
+  '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
+  '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+  '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+  '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+  '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
+};
+#endif
+
+const unsigned short OnigEncAsciiCtypeTable[256] = {
+  0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+  0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+  0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+  0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+  0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+  0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+  0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+  0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+  0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+  0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+  0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+  0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+  0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+  0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+  0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+  0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
+  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+const UChar OnigEncISO_8859_1_ToLowerCaseTable[256] = {
+  '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+  '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+  '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+  '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+  '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
+  '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
+  '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
+  '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
+  '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+  '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+  '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+  '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
+  '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+  '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+  '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+  '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
+  '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
+  '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
+  '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
+  '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
+  '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
+  '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
+  '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
+  '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
+  '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+  '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+  '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\327',
+  '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\337',
+  '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+  '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+  '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+  '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377'
+};
+
+#ifdef USE_UPPER_CASE_TABLE
+const UChar OnigEncISO_8859_1_ToUpperCaseTable[256] = {
+  '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+  '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+  '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+  '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+  '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
+  '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
+  '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
+  '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
+  '\100', '\101', '\102', '\103', '\104', '\105', '\106', '\107',
+  '\110', '\111', '\112', '\113', '\114', '\115', '\116', '\117',
+  '\120', '\121', '\122', '\123', '\124', '\125', '\126', '\127',
+  '\130', '\131', '\132', '\133', '\134', '\135', '\136', '\137',
+  '\140', '\101', '\102', '\103', '\104', '\105', '\106', '\107',
+  '\110', '\111', '\112', '\113', '\114', '\115', '\116', '\117',
+  '\120', '\121', '\122', '\123', '\124', '\125', '\126', '\127',
+  '\130', '\131', '\132', '\173', '\174', '\175', '\176', '\177',
+  '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
+  '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
+  '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
+  '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
+  '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
+  '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
+  '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
+  '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
+  '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
+  '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
+  '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
+  '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
+  '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
+  '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
+  '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\367',
+  '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\377',
+};
+#endif
+
+#if 0
+extern void
+onigenc_set_default_caseconv_table(const UChar* table ARG_UNUSED)
+{
+  /* nothing */
+  /* obsoleted. */
+}
+#endif
+
+extern UChar*
+onigenc_get_left_adjust_char_head(OnigEncoding enc, const UChar* start, const UChar* s, const UChar* end)
+{
+  return ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, start, s, end);
+}
+
+const OnigPairCaseFoldCodes OnigAsciiLowerMap[] = {
+  { 0x41, 0x61 },
+  { 0x42, 0x62 },
+  { 0x43, 0x63 },
+  { 0x44, 0x64 },
+  { 0x45, 0x65 },
+  { 0x46, 0x66 },
+  { 0x47, 0x67 },
+  { 0x48, 0x68 },
+  { 0x49, 0x69 },
+  { 0x4a, 0x6a },
+  { 0x4b, 0x6b },
+  { 0x4c, 0x6c },
+  { 0x4d, 0x6d },
+  { 0x4e, 0x6e },
+  { 0x4f, 0x6f },
+  { 0x50, 0x70 },
+  { 0x51, 0x71 },
+  { 0x52, 0x72 },
+  { 0x53, 0x73 },
+  { 0x54, 0x74 },
+  { 0x55, 0x75 },
+  { 0x56, 0x76 },
+  { 0x57, 0x77 },
+  { 0x58, 0x78 },
+  { 0x59, 0x79 },
+  { 0x5a, 0x7a }
+};
+
+extern int
+onigenc_ascii_apply_all_case_fold(OnigCaseFoldType flag ARG_UNUSED,
+				  OnigApplyAllCaseFoldFunc f, void* arg,
+				  OnigEncoding enc ARG_UNUSED)
+{
+  OnigCodePoint code;
+  int i, r;
+
+  for (i = 0; i < numberof(OnigAsciiLowerMap); i++) {
+    code = OnigAsciiLowerMap[i].to;
+    r = (*f)(OnigAsciiLowerMap[i].from, &code, 1, arg);
+    if (r != 0) return r;
+
+    code = OnigAsciiLowerMap[i].from;
+    r = (*f)(OnigAsciiLowerMap[i].to, &code, 1, arg);
+    if (r != 0) return r;
+  }
+
+  return 0;
+}
+
+extern int
+onigenc_ascii_get_case_fold_codes_by_str(OnigCaseFoldType flag ARG_UNUSED,
+	 const OnigUChar* p, const OnigUChar* end ARG_UNUSED,
+	 OnigCaseFoldCodeItem items[], OnigEncoding enc ARG_UNUSED)
+{
+  if (0x41 <= *p && *p <= 0x5a) {
+    items[0].byte_len = 1;
+    items[0].code_len = 1;
+    items[0].code[0] = (OnigCodePoint )(*p + 0x20);
+    return 1;
+  }
+  else if (0x61 <= *p && *p <= 0x7a) {
+    items[0].byte_len = 1;
+    items[0].code_len = 1;
+    items[0].code[0] = (OnigCodePoint )(*p - 0x20);
+    return 1;
+  }
+  else
+    return 0;
+}
+
+static int
+ss_apply_all_case_fold(OnigCaseFoldType flag ARG_UNUSED,
+		       OnigApplyAllCaseFoldFunc f, void* arg)
+{
+  OnigCodePoint ss[] = { 0x73, 0x73 };
+
+  return (*f)((OnigCodePoint )0xdf, ss, 2, arg);
+}
+
+extern int
+onigenc_apply_all_case_fold_with_map(int map_size,
+    const OnigPairCaseFoldCodes map[],
+    int ess_tsett_flag, OnigCaseFoldType flag,
+    OnigApplyAllCaseFoldFunc f, void* arg)
+{
+  OnigCodePoint code;
+  int i, r;
+
+  r = onigenc_ascii_apply_all_case_fold(flag, f, arg, 0);
+  if (r != 0) return r;
+
+  for (i = 0; i < map_size; i++) {
+    code = map[i].to;
+    r = (*f)(map[i].from, &code, 1, arg);
+    if (r != 0) return r;
+
+    code = map[i].from;
+    r = (*f)(map[i].to, &code, 1, arg);
+    if (r != 0) return r;
+  }
+
+  if (ess_tsett_flag != 0)
+    return ss_apply_all_case_fold(flag, f, arg);
+
+  return 0;
+}
+
+extern int
+onigenc_get_case_fold_codes_by_str_with_map(int map_size,
+    const OnigPairCaseFoldCodes map[],
+    int ess_tsett_flag, OnigCaseFoldType flag ARG_UNUSED,
+    const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
+{
+  if (0x41 <= *p && *p <= 0x5a) {
+    items[0].byte_len = 1;
+    items[0].code_len = 1;
+    items[0].code[0] = (OnigCodePoint )(*p + 0x20);
+    if (*p == 0x53 && ess_tsett_flag != 0 && end > p + 1
+	&& (*(p+1) == 0x53 || *(p+1) == 0x73)) {
+      /* SS */
+      items[1].byte_len = 2;
+      items[1].code_len = 1;
+      items[1].code[0] = (OnigCodePoint )0xdf;
+      return 2;
+    }
+    else
+      return 1;
+  }
+  else if (0x61 <= *p && *p <= 0x7a) {
+    items[0].byte_len = 1;
+    items[0].code_len = 1;
+    items[0].code[0] = (OnigCodePoint )(*p - 0x20);
+    if (*p == 0x73 && ess_tsett_flag != 0 && end > p + 1
+	&& (*(p+1) == 0x73 || *(p+1) == 0x53)) {
+      /* ss */
+      items[1].byte_len = 2;
+      items[1].code_len = 1;
+      items[1].code[0] = (OnigCodePoint )0xdf;
+      return 2;
+    }
+    else
+      return 1;
+  }
+  else if (*p == 0xdf && ess_tsett_flag != 0) {
+    items[0].byte_len = 1;
+    items[0].code_len = 2;
+    items[0].code[0] = (OnigCodePoint )'s';
+    items[0].code[1] = (OnigCodePoint )'s';
+
+    items[1].byte_len = 1;
+    items[1].code_len = 2;
+    items[1].code[0] = (OnigCodePoint )'S';
+    items[1].code[1] = (OnigCodePoint )'S';
+
+    items[2].byte_len = 1;
+    items[2].code_len = 2;
+    items[2].code[0] = (OnigCodePoint )'s';
+    items[2].code[1] = (OnigCodePoint )'S';
+
+    items[3].byte_len = 1;
+    items[3].code_len = 2;
+    items[3].code[0] = (OnigCodePoint )'S';
+    items[3].code[1] = (OnigCodePoint )'s';
+
+    return 4;
+  }
+  else {
+    int i;
+
+    for (i = 0; i < map_size; i++) {
+      if (*p == map[i].from) {
+	items[0].byte_len = 1;
+	items[0].code_len = 1;
+	items[0].code[0] = map[i].to;
+	return 1;
+      }
+      else if (*p == map[i].to) {
+	items[0].byte_len = 1;
+	items[0].code_len = 1;
+	items[0].code[0] = map[i].from;
+	return 1;
+      }
+    }
+  }
+
+  return 0;
+}
+
+
+extern int
+onigenc_not_support_get_ctype_code_range(OnigCtype ctype ARG_UNUSED,
+	 OnigCodePoint* sb_out ARG_UNUSED,
+	 const OnigCodePoint* ranges[] ARG_UNUSED,
+	 OnigEncoding enc)
+{
+  return ONIG_NO_SUPPORT_CONFIG;
+}
+
+extern int
+onigenc_is_mbc_newline_0x0a(const UChar* p, const UChar* end, OnigEncoding enc ARG_UNUSED)
+{
+  if (p < end) {
+    if (*p == 0x0a) return 1;
+  }
+  return 0;
+}
+
+/* for single byte encodings */
+extern int
+onigenc_ascii_mbc_case_fold(OnigCaseFoldType flag ARG_UNUSED, const UChar** p,
+			    const UChar* end, UChar* lower, OnigEncoding enc ARG_UNUSED)
+{
+  *lower = ONIGENC_ASCII_CODE_TO_LOWER_CASE(**p);
+
+  (*p)++;
+  return 1; /* return byte length of converted char to lower */
+}
+
+#if 0
+extern int
+onigenc_ascii_is_mbc_ambiguous(OnigCaseFoldType flag ARG_UNUSED,
+			       const UChar** pp, const UChar* end ARG_UNUSED)
+{
+  const UChar* p = *pp;
+
+  (*pp)++;
+  return ONIGENC_IS_ASCII_CODE_CASE_AMBIG(*p);
+}
+#endif
+
+extern int
+onigenc_single_byte_mbc_enc_len(const UChar* p ARG_UNUSED, const UChar* e ARG_UNUSED,
+				OnigEncoding enc ARG_UNUSED)
+{
+  return 1;
+}
+
+extern OnigCodePoint
+onigenc_single_byte_mbc_to_code(const UChar* p, const UChar* end ARG_UNUSED,
+				OnigEncoding enc ARG_UNUSED)
+{
+  return (OnigCodePoint )(*p);
+}
+
+extern int
+onigenc_single_byte_code_to_mbclen(OnigCodePoint code ARG_UNUSED, OnigEncoding enc ARG_UNUSED)
+{
+  return 1;
+}
+
+extern int
+onigenc_single_byte_code_to_mbc(OnigCodePoint code, UChar *buf, OnigEncoding enc ARG_UNUSED)
+{
+#ifdef RUBY
+  if (code > 0xff)
+    rb_raise(rb_eRangeError, "%u out of char range", code);
+#endif
+  *buf = (UChar )(code & 0xff);
+  return 1;
+}
+
+extern UChar*
+onigenc_single_byte_left_adjust_char_head(const UChar* start ARG_UNUSED,
+					  const UChar* s,
+					  const UChar* end ARG_UNUSED,
+					  OnigEncoding enc ARG_UNUSED)
+{
+  return (UChar* )s;
+}
+
+extern int
+onigenc_always_true_is_allowed_reverse_match(const UChar* s   ARG_UNUSED,
+					     const UChar* end ARG_UNUSED,
+					     OnigEncoding enc ARG_UNUSED)
+{
+  return TRUE;
+}
+
+extern int
+onigenc_always_false_is_allowed_reverse_match(const UChar* s   ARG_UNUSED,
+					      const UChar* end ARG_UNUSED,
+					      OnigEncoding enc ARG_UNUSED)
+{
+  return FALSE;
+}
+
+extern int
+onigenc_ascii_is_code_ctype(OnigCodePoint code, unsigned int ctype,
+                            OnigEncoding enc ARG_UNUSED)
+{
+  if (code < 128)
+    return ONIGENC_IS_ASCII_CODE_CTYPE(code, ctype);
+  else
+    return FALSE;
+}
+
+extern OnigCodePoint
+onigenc_mbn_mbc_to_code(OnigEncoding enc, const UChar* p, const UChar* end)
+{
+  int c, i, len;
+  OnigCodePoint n;
+
+  len = enclen(enc, p, end);
+  n = (OnigCodePoint )(*p++);
+  if (len == 1) return n;
+
+  for (i = 1; i < len; i++) {
+    if (p >= end) break;
+    c = *p++;
+    n <<= 8;  n += c;
+  }
+  return n;
+}
+
+extern int
+onigenc_mbn_mbc_case_fold(OnigEncoding enc, OnigCaseFoldType flag ARG_UNUSED,
+                          const UChar** pp, const UChar* end ARG_UNUSED,
+			  UChar* lower)
+{
+  int len;
+  const UChar *p = *pp;
+
+  if (ONIGENC_IS_MBC_ASCII(p)) {
+    *lower = ONIGENC_ASCII_CODE_TO_LOWER_CASE(*p);
+    (*pp)++;
+    return 1;
+  }
+  else {
+    int i;
+
+    len = enclen(enc, p, end);
+    for (i = 0; i < len; i++) {
+      *lower++ = *p++;
+    }
+    (*pp) += len;
+    return len; /* return byte length of converted to lower char */
+  }
+}
+
+#if 0
+extern int
+onigenc_mbn_is_mbc_ambiguous(OnigEncoding enc, OnigCaseFoldType flag,
+                             const UChar** pp, const UChar* end ARG_UNUSED)
+{
+  const UChar* p = *pp;
+
+  if (ONIGENC_IS_MBC_ASCII(p)) {
+    (*pp)++;
+    return ONIGENC_IS_ASCII_CODE_CASE_AMBIG(*p);
+  }
+
+  (*pp) += enclen(enc, p);
+  return FALSE;
+}
+#endif
+
+extern int
+onigenc_mb2_code_to_mbclen(OnigCodePoint code, OnigEncoding enc ARG_UNUSED)
+{
+  if (code <= 0xff) return 1;
+  if (code <= 0xffff) return 2;
+  return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
+}
+
+extern int
+onigenc_mb4_code_to_mbclen(OnigCodePoint code, OnigEncoding enc ARG_UNUSED)
+{
+       if ((code & 0xff000000) != 0) return 4;
+  else if ((code & 0xff0000) != 0) return 3;
+  else if ((code & 0xff00) != 0) return 2;
+  else return 1;
+}
+
+extern int
+onigenc_mb2_code_to_mbc(OnigEncoding enc, OnigCodePoint code, UChar *buf)
+{
+  UChar *p = buf;
+
+  if ((code & 0xff00) != 0) {
+    *p++ = (UChar )((code >>  8) & 0xff);
+  }
+  *p++ = (UChar )(code & 0xff);
+
+#if 1
+  if (enclen(enc, buf, p) != (p - buf))
+    return ONIGERR_INVALID_CODE_POINT_VALUE;
+#endif
+  return (int )(p - buf);
+}
+
+extern int
+onigenc_mb4_code_to_mbc(OnigEncoding enc, OnigCodePoint code, UChar *buf)
+{
+  UChar *p = buf;
+
+  if ((code & 0xff000000) != 0) {
+    *p++ = (UChar )((code >> 24) & 0xff);
+  }
+  if ((code & 0xff0000) != 0 || p != buf) {
+    *p++ = (UChar )((code >> 16) & 0xff);
+  }
+  if ((code & 0xff00) != 0 || p != buf) {
+    *p++ = (UChar )((code >> 8) & 0xff);
+  }
+  *p++ = (UChar )(code & 0xff);
+
+#if 1
+  if (enclen(enc, buf, p) != (p - buf))
+    return ONIGERR_INVALID_CODE_POINT_VALUE;
+#endif
+  return (int )(p - buf);
+}
+
+extern int
+onigenc_minimum_property_name_to_ctype(OnigEncoding enc, const UChar* p, const UChar* end)
+{
+  static const PosixBracketEntryType PBS[] = {
+    POSIX_BRACKET_ENTRY_INIT("Alnum",  ONIGENC_CTYPE_ALNUM),
+    POSIX_BRACKET_ENTRY_INIT("Alpha",  ONIGENC_CTYPE_ALPHA),
+    POSIX_BRACKET_ENTRY_INIT("Blank",  ONIGENC_CTYPE_BLANK),
+    POSIX_BRACKET_ENTRY_INIT("Cntrl",  ONIGENC_CTYPE_CNTRL),
+    POSIX_BRACKET_ENTRY_INIT("Digit",  ONIGENC_CTYPE_DIGIT),
+    POSIX_BRACKET_ENTRY_INIT("Graph",  ONIGENC_CTYPE_GRAPH),
+    POSIX_BRACKET_ENTRY_INIT("Lower",  ONIGENC_CTYPE_LOWER),
+    POSIX_BRACKET_ENTRY_INIT("Print",  ONIGENC_CTYPE_PRINT),
+    POSIX_BRACKET_ENTRY_INIT("Punct",  ONIGENC_CTYPE_PUNCT),
+    POSIX_BRACKET_ENTRY_INIT("Space",  ONIGENC_CTYPE_SPACE),
+    POSIX_BRACKET_ENTRY_INIT("Upper",  ONIGENC_CTYPE_UPPER),
+    POSIX_BRACKET_ENTRY_INIT("XDigit", ONIGENC_CTYPE_XDIGIT),
+    POSIX_BRACKET_ENTRY_INIT("ASCII",  ONIGENC_CTYPE_ASCII),
+    POSIX_BRACKET_ENTRY_INIT("Word",   ONIGENC_CTYPE_WORD),
+  };
+
+  const PosixBracketEntryType *pb;
+  int len;
+
+  len = onigenc_strlen(enc, p, end);
+  for (pb = PBS; pb < PBS + numberof(PBS); pb++) {
+    if (len == pb->len &&
+        onigenc_with_ascii_strnicmp(enc, p, end, pb->name, pb->len) == 0)
+      return pb->ctype;
+  }
+
+  return ONIGERR_INVALID_CHAR_PROPERTY_NAME;
+}
+
+extern int
+onigenc_mb2_is_code_ctype(OnigEncoding enc, OnigCodePoint code,
+			  unsigned int ctype)
+{
+  if (code < 128)
+    return ONIGENC_IS_ASCII_CODE_CTYPE(code, ctype);
+  else {
+    if (CTYPE_IS_WORD_GRAPH_PRINT(ctype)) {
+      return (ONIGENC_CODE_TO_MBCLEN(enc, code) > 1 ? TRUE : FALSE);
+    }
+  }
+
+  return FALSE;
+}
+
+extern int
+onigenc_mb4_is_code_ctype(OnigEncoding enc, OnigCodePoint code,
+			  unsigned int ctype)
+{
+  if (code < 128)
+    return ONIGENC_IS_ASCII_CODE_CTYPE(code, ctype);
+  else {
+    if (CTYPE_IS_WORD_GRAPH_PRINT(ctype)) {
+      return (ONIGENC_CODE_TO_MBCLEN(enc, code) > 1 ? TRUE : FALSE);
+    }
+  }
+
+  return FALSE;
+}
+
+extern int
+onigenc_with_ascii_strncmp(OnigEncoding enc, const UChar* p, const UChar* end,
+                           const UChar* sascii /* ascii */, int n)
+{
+  int x, c;
+
+  while (n-- > 0) {
+    if (p >= end) return (int )(*sascii);
+
+    c = (int )ONIGENC_MBC_TO_CODE(enc, p, end);
+    x = *sascii - c;
+    if (x) return x;
+
+    sascii++;
+    p += enclen(enc, p, end);
+  }
+  return 0;
+}
+
+extern int
+onigenc_with_ascii_strnicmp(OnigEncoding enc, const UChar* p, const UChar* end,
+                            const UChar* sascii /* ascii */, int n)
+{
+  int x, c;
+
+  while (n-- > 0) {
+    if (p >= end) return (int )(*sascii);
+
+    c = (int )ONIGENC_MBC_TO_CODE(enc, p, end);
+    if (ONIGENC_IS_ASCII_CODE(c))
+      c = ONIGENC_ASCII_CODE_TO_LOWER_CASE(c);
+    x = ONIGENC_ASCII_CODE_TO_LOWER_CASE(*sascii) - c;
+    if (x) return x;
+
+    sascii++;
+    p += enclen(enc, p, end);
+  }
+  return 0;
+}
+
+#if 0
+/* Property management */
+static int
+resize_property_list(int new_size, const OnigCodePoint*** plist, int* psize)
+{
+  size_t size;
+  const OnigCodePoint **list = *plist;
+
+  size = sizeof(OnigCodePoint*) * new_size;
+  if (IS_NULL(list)) {
+    list = (const OnigCodePoint** )xmalloc(size);
+    if (IS_NULL(list)) return ONIGERR_MEMORY;
+  }
+  else {
+    const OnigCodePoint **tmp;
+    tmp = (const OnigCodePoint** )xrealloc((void* )list, size);
+    if (IS_NULL(tmp)) return ONIGERR_MEMORY;
+    list = tmp;
+  }
+
+  *plist = list;
+  *psize = new_size;
+
+  return 0;
+}
+
+extern int
+onigenc_property_list_add_property(UChar* name, const OnigCodePoint* prop,
+     hash_table_type **table, const OnigCodePoint*** plist, int *pnum,
+     int *psize)
+{
+#define PROP_INIT_SIZE     16
+
+  int r;
+
+  if (*psize <= *pnum) {
+    int new_size = (*psize == 0 ? PROP_INIT_SIZE : *psize * 2);
+    r = resize_property_list(new_size, plist, psize);
+    if (r != 0) return r;
+  }
+
+  (*plist)[*pnum] = prop;
+
+  if (ONIG_IS_NULL(*table)) {
+    *table = onig_st_init_strend_table_with_size(PROP_INIT_SIZE);
+    if (ONIG_IS_NULL(*table)) return ONIGERR_MEMORY;
+  }
+
+  *pnum = *pnum + 1;
+  onig_st_insert_strend(*table, name, name + strlen((char* )name),
+			(hash_data_type )(*pnum + ONIGENC_MAX_STD_CTYPE));
+  return 0;
+}
+#endif
+
+extern int
+onigenc_ascii_only_case_map(OnigCaseFoldType* flagP, const OnigUChar** pp, const OnigUChar* end,
+			    OnigUChar* to, OnigUChar* to_end, const struct OnigEncodingTypeST* enc)
+{
+  OnigCodePoint code;
+  OnigUChar *to_start = to;
+  OnigCaseFoldType flags = *flagP;
+  int codepoint_length;
+
+  while (*pp < end && to < to_end) {
+    codepoint_length = ONIGENC_PRECISE_MBC_ENC_LEN(enc, *pp, end);
+    if (codepoint_length < 0)
+      return codepoint_length; /* encoding invalid */
+    code = ONIGENC_MBC_TO_CODE(enc, *pp, end);
+    *pp += codepoint_length;
+
+    if (code >= 'a' && code <= 'z' && (flags & ONIGENC_CASE_UPCASE)) {
+      flags |= ONIGENC_CASE_MODIFIED;
+      code += 'A' - 'a';
+    } else if (code >= 'A' && code <= 'Z' &&
+	(flags & (ONIGENC_CASE_DOWNCASE | ONIGENC_CASE_FOLD))) {
+      flags |= ONIGENC_CASE_MODIFIED;
+      code += 'a' - 'A';
+    }
+    to += ONIGENC_CODE_TO_MBC(enc, code, to);
+    if (flags & ONIGENC_CASE_TITLECASE)  /* switch from titlecase to lowercase for capitalize */
+      flags ^= (ONIGENC_CASE_UPCASE | ONIGENC_CASE_DOWNCASE | ONIGENC_CASE_TITLECASE);
+  }
+  *flagP = flags;
+  return (int )(to - to_start);
+}
+
+extern int
+onigenc_single_byte_ascii_only_case_map(OnigCaseFoldType* flagP, const OnigUChar** pp,
+					const OnigUChar* end, OnigUChar* to, OnigUChar* to_end,
+					const struct OnigEncodingTypeST* enc)
+{
+  OnigCodePoint code;
+  OnigUChar *to_start = to;
+  OnigCaseFoldType flags = *flagP;
+
+  while (*pp < end && to < to_end) {
+    code = *(*pp)++;
+
+    if (code >= 'a' && code <= 'z' && (flags & ONIGENC_CASE_UPCASE)) {
+      flags |= ONIGENC_CASE_MODIFIED;
+      code += 'A' - 'a';
+    } else if (code >= 'A' && code <= 'Z' &&
+	(flags & (ONIGENC_CASE_DOWNCASE | ONIGENC_CASE_FOLD))) {
+      flags |= ONIGENC_CASE_MODIFIED;
+      code += 'a' - 'A';
+    }
+    *to++ = code;
+    if (flags & ONIGENC_CASE_TITLECASE)  /* switch from titlecase to lowercase for capitalize */
+      flags ^= (ONIGENC_CASE_UPCASE | ONIGENC_CASE_DOWNCASE | ONIGENC_CASE_TITLECASE);
+  }
+  *flagP = flags;
+  return (int )(to - to_start);
+}
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/regenc.h
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/regenc.h	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/regenc.h	(revision 331)
@@ -0,0 +1,254 @@
+#ifndef ONIGMO_REGENC_H
+#define ONIGMO_REGENC_H
+/**********************************************************************
+  regenc.h -  Onigmo (Oniguruma-mod) (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2008  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011-2016  K.Takata  <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if !defined(RUBY) && (defined(RUBY_EXPORT) || defined(ONIG_ENC_REGISTER))
+# define RUBY
+#endif
+#ifdef RUBY
+# ifndef ONIGMO_REGINT_H
+#  ifndef RUBY_EXTERN
+#   include "ruby/config.h"
+#   include "ruby/defines.h"
+#  endif
+# endif
+#else /* RUBY */
+# ifndef PACKAGE
+/* PACKAGE is defined in config.h */
+#  include "config.h"
+# endif
+#endif /* RUBY */
+
+#ifdef ONIG_ESCAPE_UCHAR_COLLISION
+# undef ONIG_ESCAPE_UCHAR_COLLISION
+#endif
+
+#ifdef RUBY
+# include "ruby/onigmo.h"
+#else
+# include "onigmo.h"
+#endif
+
+RUBY_SYMBOL_EXPORT_BEGIN
+
+typedef struct {
+  OnigCodePoint from;
+  OnigCodePoint to;
+} OnigPairCaseFoldCodes;
+
+
+#ifndef NULL
+# define NULL   ((void* )0)
+#endif
+
+#ifndef TRUE
+# define TRUE    1
+#endif
+
+#ifndef FALSE
+# define FALSE   0
+#endif
+
+#ifndef ARG_UNUSED
+# if defined(__GNUC__)
+#  define ARG_UNUSED  __attribute__ ((unused))
+# else
+#  define ARG_UNUSED
+# endif
+#endif
+
+#define ONIG_IS_NULL(p)                    (((void*)(p)) == (void*)0)
+#define ONIG_IS_NOT_NULL(p)                (((void*)(p)) != (void*)0)
+#define ONIG_CHECK_NULL_RETURN(p)          if (ONIG_IS_NULL(p)) return NULL
+#define ONIG_CHECK_NULL_RETURN_VAL(p,val)  if (ONIG_IS_NULL(p)) return (val)
+
+#define enclen(enc,p,e) ((enc->max_enc_len == enc->min_enc_len) ? enc->min_enc_len : ONIGENC_MBC_ENC_LEN(enc,p,e))
+
+/* character types bit flag */
+#define BIT_CTYPE_NEWLINE  (1<< ONIGENC_CTYPE_NEWLINE)
+#define BIT_CTYPE_ALPHA    (1<< ONIGENC_CTYPE_ALPHA)
+#define BIT_CTYPE_BLANK    (1<< ONIGENC_CTYPE_BLANK)
+#define BIT_CTYPE_CNTRL    (1<< ONIGENC_CTYPE_CNTRL)
+#define BIT_CTYPE_DIGIT    (1<< ONIGENC_CTYPE_DIGIT)
+#define BIT_CTYPE_GRAPH    (1<< ONIGENC_CTYPE_GRAPH)
+#define BIT_CTYPE_LOWER    (1<< ONIGENC_CTYPE_LOWER)
+#define BIT_CTYPE_PRINT    (1<< ONIGENC_CTYPE_PRINT)
+#define BIT_CTYPE_PUNCT    (1<< ONIGENC_CTYPE_PUNCT)
+#define BIT_CTYPE_SPACE    (1<< ONIGENC_CTYPE_SPACE)
+#define BIT_CTYPE_UPPER    (1<< ONIGENC_CTYPE_UPPER)
+#define BIT_CTYPE_XDIGIT   (1<< ONIGENC_CTYPE_XDIGIT)
+#define BIT_CTYPE_WORD     (1<< ONIGENC_CTYPE_WORD)
+#define BIT_CTYPE_ALNUM    (1<< ONIGENC_CTYPE_ALNUM)
+#define BIT_CTYPE_ASCII    (1<< ONIGENC_CTYPE_ASCII)
+
+#define CTYPE_TO_BIT(ctype)  (1<<(ctype))
+#define CTYPE_IS_WORD_GRAPH_PRINT(ctype) \
+  ((ctype) == ONIGENC_CTYPE_WORD || (ctype) == ONIGENC_CTYPE_GRAPH ||\
+   (ctype) == ONIGENC_CTYPE_PRINT)
+
+
+typedef struct {
+  short int len;
+  const UChar name[6];
+  int       ctype;
+} PosixBracketEntryType;
+
+#define POSIX_BRACKET_ENTRY_INIT(name, ctype) \
+  {(short int )(sizeof(name) - 1), (name), (ctype)}
+
+#ifndef numberof
+# define numberof(array) (int )(sizeof(array) / sizeof((array)[0]))
+#endif
+
+
+#define USE_CRNL_AS_LINE_TERMINATOR
+#define USE_UNICODE_PROPERTIES
+#define USE_UNICODE_AGE_PROPERTIES
+/* #define USE_UNICODE_CASE_FOLD_TURKISH_AZERI */
+/* #define USE_UNICODE_ALL_LINE_TERMINATORS */  /* see Unicode.org UTS #18 */
+
+
+#define ONIG_ENCODING_INIT_DEFAULT           ONIG_ENCODING_ASCII
+
+/* for encoding system implementation (internal) */
+ONIG_EXTERN int onigenc_ascii_apply_all_case_fold(OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg, OnigEncoding enc);
+ONIG_EXTERN int onigenc_ascii_get_case_fold_codes_by_str(OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[], OnigEncoding enc);
+ONIG_EXTERN int onigenc_apply_all_case_fold_with_map(int map_size, const OnigPairCaseFoldCodes map[], int ess_tsett_flag, OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg);
+ONIG_EXTERN int onigenc_get_case_fold_codes_by_str_with_map(int map_size, const OnigPairCaseFoldCodes map[], int ess_tsett_flag, OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[]);
+ONIG_EXTERN int onigenc_not_support_get_ctype_code_range(OnigCtype ctype, OnigCodePoint* sb_out, const OnigCodePoint* ranges[], OnigEncoding enc);
+ONIG_EXTERN int onigenc_is_mbc_newline_0x0a(const UChar* p, const UChar* end, OnigEncoding enc);
+ONIG_EXTERN int    onigenc_single_byte_ascii_only_case_map(OnigCaseFoldType* flagP, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to, OnigUChar* to_end, const struct OnigEncodingTypeST* enc);
+
+
+/* methods for single byte encoding */
+ONIG_EXTERN int onigenc_ascii_mbc_case_fold(OnigCaseFoldType flag, const UChar** p, const UChar* end, UChar* lower, OnigEncoding enc);
+ONIG_EXTERN int onigenc_single_byte_mbc_enc_len(const UChar* p, const UChar* e, OnigEncoding enc);
+ONIG_EXTERN OnigCodePoint onigenc_single_byte_mbc_to_code(const UChar* p, const UChar* end, OnigEncoding enc);
+ONIG_EXTERN int onigenc_single_byte_code_to_mbclen(OnigCodePoint code, OnigEncoding enc);
+ONIG_EXTERN int onigenc_single_byte_code_to_mbc(OnigCodePoint code, UChar *buf, OnigEncoding enc);
+ONIG_EXTERN UChar* onigenc_single_byte_left_adjust_char_head(const UChar* start, const UChar* s, const OnigUChar* end, OnigEncoding enc);
+ONIG_EXTERN int onigenc_always_true_is_allowed_reverse_match(const UChar* s, const UChar* end, OnigEncoding enc);
+ONIG_EXTERN int onigenc_always_false_is_allowed_reverse_match(const UChar* s, const UChar* end, OnigEncoding enc);
+ONIG_EXTERN int onigenc_ascii_is_code_ctype(OnigCodePoint code, unsigned int ctype, OnigEncoding enc);
+
+/* methods for multi byte encoding */
+ONIG_EXTERN OnigCodePoint onigenc_mbn_mbc_to_code(OnigEncoding enc, const UChar* p, const UChar* end);
+ONIG_EXTERN int onigenc_mbn_mbc_case_fold(OnigEncoding enc, OnigCaseFoldType flag, const UChar** p, const UChar* end, UChar* lower);
+ONIG_EXTERN int onigenc_mb2_code_to_mbclen(OnigCodePoint code, OnigEncoding enc);
+ONIG_EXTERN int onigenc_mb2_code_to_mbc(OnigEncoding enc, OnigCodePoint code, UChar *buf);
+ONIG_EXTERN int onigenc_minimum_property_name_to_ctype(OnigEncoding enc, const UChar* p, const UChar* end);
+ONIG_EXTERN int onigenc_unicode_property_name_to_ctype(OnigEncoding enc, const UChar* p, const UChar* end);
+ONIG_EXTERN int onigenc_mb2_is_code_ctype(OnigEncoding enc, OnigCodePoint code, unsigned int ctype);
+ONIG_EXTERN int onigenc_mb4_code_to_mbclen(OnigCodePoint code, OnigEncoding enc);
+ONIG_EXTERN int onigenc_mb4_code_to_mbc(OnigEncoding enc, OnigCodePoint code, UChar *buf);
+ONIG_EXTERN int onigenc_mb4_is_code_ctype(OnigEncoding enc, OnigCodePoint code, unsigned int ctype);
+
+ONIG_EXTERN int onigenc_unicode_case_map(OnigCaseFoldType* flagP, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to, OnigUChar* to_end, const struct OnigEncodingTypeST* enc);
+
+
+/* in enc/unicode.c */
+ONIG_EXTERN int onigenc_unicode_is_code_ctype(OnigCodePoint code, unsigned int ctype, OnigEncoding enc);
+ONIG_EXTERN int onigenc_utf16_32_get_ctype_code_range(OnigCtype ctype, OnigCodePoint *sb_out, const OnigCodePoint* ranges[], OnigEncoding enc);
+ONIG_EXTERN int onigenc_unicode_ctype_code_range(int ctype, const OnigCodePoint* ranges[]);
+ONIG_EXTERN int onigenc_unicode_get_case_fold_codes_by_str(OnigEncoding enc, OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[]);
+ONIG_EXTERN int onigenc_unicode_mbc_case_fold(OnigEncoding enc, OnigCaseFoldType flag, const UChar** pp, const UChar* end, UChar* fold);
+ONIG_EXTERN int onigenc_unicode_apply_all_case_fold(OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg, OnigEncoding enc);
+
+
+#define UTF16_IS_SURROGATE_FIRST(c)    (((c) & 0xfc) == 0xd8)
+#define UTF16_IS_SURROGATE_SECOND(c)   (((c) & 0xfc) == 0xdc)
+#define UTF16_IS_SURROGATE(c)          (((c) & 0xf8) == 0xd8)
+#define UNICODE_VALID_CODEPOINT_P(c) ( \
+	((c) <= 0x10ffff) && \
+	!((c) < 0x10000 && UTF16_IS_SURROGATE((c) >> 8)))
+
+#define ONIGENC_ISO_8859_1_TO_LOWER_CASE(c) \
+  OnigEncISO_8859_1_ToLowerCaseTable[c]
+#define ONIGENC_ISO_8859_1_TO_UPPER_CASE(c) \
+  OnigEncISO_8859_1_ToUpperCaseTable[c]
+
+ONIG_EXTERN const UChar OnigEncISO_8859_1_ToLowerCaseTable[];
+ONIG_EXTERN const UChar OnigEncISO_8859_1_ToUpperCaseTable[];
+
+ONIG_EXTERN int
+onigenc_with_ascii_strncmp(OnigEncoding enc, const UChar* p, const UChar* end, const UChar* sascii /* ascii */, int n);
+ONIG_EXTERN int
+onigenc_with_ascii_strnicmp(OnigEncoding enc, const UChar* p, const UChar* end, const UChar* sascii /* ascii */, int n);
+ONIG_EXTERN UChar*
+onigenc_step(OnigEncoding enc, const UChar* p, const UChar* end, int n);
+
+/* defined in regexec.c, but used in enc/xxx.c */
+extern int  onig_is_in_code_range(const UChar* p, OnigCodePoint code);
+
+ONIG_EXTERN OnigEncoding  OnigEncDefaultCharEncoding;
+ONIG_EXTERN const UChar  OnigEncAsciiToLowerCaseTable[];
+ONIG_EXTERN const UChar  OnigEncAsciiToUpperCaseTable[];
+ONIG_EXTERN const unsigned short OnigEncAsciiCtypeTable[];
+
+#define ONIGENC_IS_ASCII_CODE(code)  ((code) < 0x80)
+#define ONIGENC_ASCII_CODE_TO_LOWER_CASE(c) OnigEncAsciiToLowerCaseTable[c]
+#define ONIGENC_ASCII_CODE_TO_UPPER_CASE(c) OnigEncAsciiToUpperCaseTable[c]
+#define ONIGENC_IS_ASCII_CODE_CTYPE(code,ctype) \
+  ((OnigEncAsciiCtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
+#define ONIGENC_IS_ASCII_CODE_CASE_AMBIG(code) \
+ (ONIGENC_IS_ASCII_CODE_CTYPE(code, ONIGENC_CTYPE_UPPER) ||\
+  ONIGENC_IS_ASCII_CODE_CTYPE(code, ONIGENC_CTYPE_LOWER))
+
+/* Check if the code is in the range. (from <= code && code <= to) */
+#define ONIGENC_IS_IN_RANGE(code, from, to) \
+  ((OnigCodePoint )((code) - (from)) <= (OnigCodePoint )((to) - (from)))
+
+
+#ifdef ONIG_ENC_REGISTER
+extern int ONIG_ENC_REGISTER(const char *, OnigEncoding);
+# define OnigEncodingName(n) encoding_##n
+# define OnigEncodingDeclare(n) static const OnigEncodingType OnigEncodingName(n)
+# define OnigEncodingDefine(f,n)			     \
+    OnigEncodingDeclare(n);			     \
+    void Init_##f(void) {			     \
+	ONIG_ENC_REGISTER(OnigEncodingName(n).name,  \
+			  &OnigEncodingName(n));     \
+    }						     \
+    OnigEncodingDeclare(n)
+#else
+# define OnigEncodingName(n) OnigEncoding##n
+# define OnigEncodingDeclare(n) const OnigEncodingType OnigEncodingName(n)
+# define OnigEncodingDefine(f,n) OnigEncodingDeclare(n)
+#endif
+
+/* macros for define replica encoding and encoding alias */
+#define ENC_REPLICATE(name, orig)
+#define ENC_ALIAS(name, orig)
+#define ENC_DUMMY(name)
+
+RUBY_SYMBOL_EXPORT_END
+
+#endif /* ONIGMO_REGENC_H */
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/regerror.c
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/regerror.c	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/regerror.c	(revision 331)
@@ -0,0 +1,386 @@
+/**********************************************************************
+  regerror.c -  Onigmo (Oniguruma-mod) (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2007  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011-2016  K.Takata  <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "regint.h"
+#include <stdio.h> /* for vsnprintf() */
+
+#include <stdarg.h>
+
+extern UChar*
+onig_error_code_to_format(OnigPosition code)
+{
+  const char *p;
+
+  if (code >= 0) return (UChar* )0;
+
+  switch (code) {
+  case ONIG_MISMATCH:
+    p = "mismatch"; break;
+  case ONIG_NO_SUPPORT_CONFIG:
+    p = "no support in this configuration"; break;
+  case ONIGERR_MEMORY:
+    p = "failed to allocate memory"; break;
+  case ONIGERR_TYPE_BUG:
+    p = "undefined type (bug)"; break;
+  case ONIGERR_PARSER_BUG:
+    p = "internal parser error (bug)"; break;
+  case ONIGERR_STACK_BUG:
+    p = "stack error (bug)"; break;
+  case ONIGERR_UNDEFINED_BYTECODE:
+    p = "undefined bytecode (bug)"; break;
+  case ONIGERR_UNEXPECTED_BYTECODE:
+    p = "unexpected bytecode (bug)"; break;
+  case ONIGERR_MATCH_STACK_LIMIT_OVER:
+    p = "match-stack limit over"; break;
+  case ONIGERR_PARSE_DEPTH_LIMIT_OVER:
+    p = "parse depth limit over"; break;
+  case ONIGERR_DEFAULT_ENCODING_IS_NOT_SET:
+    p = "default multibyte-encoding is not set"; break;
+  case ONIGERR_SPECIFIED_ENCODING_CANT_CONVERT_TO_WIDE_CHAR:
+    p = "can't convert to wide-char on specified multibyte-encoding"; break;
+  case ONIGERR_INVALID_ARGUMENT:
+    p = "invalid argument"; break;
+  case ONIGERR_END_PATTERN_AT_LEFT_BRACE:
+    p = "end pattern at left brace"; break;
+  case ONIGERR_END_PATTERN_AT_LEFT_BRACKET:
+    p = "end pattern at left bracket"; break;
+  case ONIGERR_EMPTY_CHAR_CLASS:
+    p = "empty char-class"; break;
+  case ONIGERR_PREMATURE_END_OF_CHAR_CLASS:
+    p = "premature end of char-class"; break;
+  case ONIGERR_END_PATTERN_AT_ESCAPE:
+    p = "end pattern at escape"; break;
+  case ONIGERR_END_PATTERN_AT_META:
+    p = "end pattern at meta"; break;
+  case ONIGERR_END_PATTERN_AT_CONTROL:
+    p = "end pattern at control"; break;
+  case ONIGERR_META_CODE_SYNTAX:
+    p = "invalid meta-code syntax"; break;
+  case ONIGERR_CONTROL_CODE_SYNTAX:
+    p = "invalid control-code syntax"; break;
+  case ONIGERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE:
+    p = "char-class value at end of range"; break;
+  case ONIGERR_CHAR_CLASS_VALUE_AT_START_OF_RANGE:
+    p = "char-class value at start of range"; break;
+  case ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS:
+    p = "unmatched range specifier in char-class"; break;
+  case ONIGERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED:
+    p = "target of repeat operator is not specified"; break;
+  case ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID:
+    p = "target of repeat operator is invalid"; break;
+  case ONIGERR_NESTED_REPEAT_OPERATOR:
+    p = "nested repeat operator"; break;
+  case ONIGERR_UNMATCHED_CLOSE_PARENTHESIS:
+    p = "unmatched close parenthesis"; break;
+  case ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS:
+    p = "end pattern with unmatched parenthesis"; break;
+  case ONIGERR_END_PATTERN_IN_GROUP:
+    p = "end pattern in group"; break;
+  case ONIGERR_UNDEFINED_GROUP_OPTION:
+    p = "undefined group option"; break;
+  case ONIGERR_INVALID_POSIX_BRACKET_TYPE:
+    p = "invalid POSIX bracket type"; break;
+  case ONIGERR_INVALID_LOOK_BEHIND_PATTERN:
+    p = "invalid pattern in look-behind"; break;
+  case ONIGERR_INVALID_REPEAT_RANGE_PATTERN:
+    p = "invalid repeat range {lower,upper}"; break;
+  case ONIGERR_INVALID_CONDITION_PATTERN:
+    p = "invalid conditional pattern"; break;
+  case ONIGERR_TOO_BIG_NUMBER:
+    p = "too big number"; break;
+  case ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE:
+    p = "too big number for repeat range"; break;
+  case ONIGERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE:
+    p = "upper is smaller than lower in repeat range"; break;
+  case ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS:
+    p = "empty range in char class"; break;
+  case ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE:
+    p = "mismatch multibyte code length in char-class range"; break;
+  case ONIGERR_TOO_MANY_MULTI_BYTE_RANGES:
+    p = "too many multibyte code ranges are specified"; break;
+  case ONIGERR_TOO_SHORT_MULTI_BYTE_STRING:
+    p = "too short multibyte code string"; break;
+  case ONIGERR_TOO_BIG_BACKREF_NUMBER:
+    p = "too big backref number"; break;
+  case ONIGERR_INVALID_BACKREF:
+#ifdef USE_NAMED_GROUP
+    p = "invalid backref number/name"; break;
+#else
+    p = "invalid backref number"; break;
+#endif
+  case ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED:
+    p = "numbered backref/call is not allowed. (use name)"; break;
+  case ONIGERR_TOO_SHORT_DIGITS:
+    p = "too short digits"; break;
+  case ONIGERR_TOO_LONG_WIDE_CHAR_VALUE:
+    p = "too long wide-char value"; break;
+  case ONIGERR_EMPTY_GROUP_NAME:
+    p = "group name is empty"; break;
+  case ONIGERR_INVALID_GROUP_NAME:
+    p = "invalid group name <%n>"; break;
+  case ONIGERR_INVALID_CHAR_IN_GROUP_NAME:
+#ifdef USE_NAMED_GROUP
+    p = "invalid char in group name <%n>"; break;
+#else
+    p = "invalid char in group number <%n>"; break;
+#endif
+  case ONIGERR_UNDEFINED_NAME_REFERENCE:
+    p = "undefined name <%n> reference"; break;
+  case ONIGERR_UNDEFINED_GROUP_REFERENCE:
+    p = "undefined group <%n> reference"; break;
+  case ONIGERR_MULTIPLEX_DEFINED_NAME:
+    p = "multiplex defined name <%n>"; break;
+  case ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL:
+    p = "multiplex definition name <%n> call"; break;
+  case ONIGERR_NEVER_ENDING_RECURSION:
+    p = "never ending recursion"; break;
+  case ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY:
+    p = "group number is too big for capture history"; break;
+  case ONIGERR_INVALID_CHAR_PROPERTY_NAME:
+    p = "invalid character property name {%n}"; break;
+  case ONIGERR_TOO_MANY_CAPTURE_GROUPS:
+    p = "too many capture groups are specified"; break;
+  case ONIGERR_INVALID_CODE_POINT_VALUE:
+    p = "invalid code point value"; break;
+  case ONIGERR_TOO_BIG_WIDE_CHAR_VALUE:
+    p = "too big wide-char value"; break;
+  case ONIGERR_NOT_SUPPORTED_ENCODING_COMBINATION:
+    p = "not supported encoding combination"; break;
+  case ONIGERR_INVALID_COMBINATION_OF_OPTIONS:
+    p = "invalid combination of options"; break;
+
+  default:
+    p = "undefined error code"; break;
+  }
+
+  return (UChar* )p;
+}
+
+static void sprint_byte(char* s, unsigned int v)
+{
+  xsnprintf(s, 3, "%02x", (v & 0377));
+}
+
+static void sprint_byte_with_x(char* s, unsigned int v)
+{
+  xsnprintf(s, 5, "\\x%02x", (v & 0377));
+}
+
+static int to_ascii(OnigEncoding enc, UChar *s, UChar *end,
+		    UChar buf[], int buf_size, int *is_over)
+{
+  int len;
+  UChar *p;
+  OnigCodePoint code;
+
+  if (ONIGENC_MBC_MINLEN(enc) > 1) {
+    p = s;
+    len = 0;
+    while (p < end) {
+      code = ONIGENC_MBC_TO_CODE(enc, p, end);
+      if (code >= 0x80) {
+	if (code > 0xffff && len + 10 <= buf_size) {
+	  sprint_byte_with_x((char*)(&(buf[len])), (unsigned int)(code >> 24));
+	  sprint_byte((char*)(&(buf[len+4])),      (unsigned int)(code >> 16));
+	  sprint_byte((char*)(&(buf[len+6])),      (unsigned int)(code >>  8));
+	  sprint_byte((char*)(&(buf[len+8])),      (unsigned int)code);
+	  len += 10;
+	}
+	else if (len + 6 <= buf_size) {
+	  sprint_byte_with_x((char*)(&(buf[len])), (unsigned int)(code >> 8));
+	  sprint_byte((char*)(&(buf[len+4])),      (unsigned int)code);
+	  len += 6;
+	}
+	else {
+	  break;
+	}
+      }
+      else {
+	buf[len++] = (UChar )code;
+      }
+
+      p += enclen(enc, p, end);
+      if (len >= buf_size) break;
+    }
+
+    *is_over = ((p < end) ? 1 : 0);
+  }
+  else {
+    len = (int )MIN((end - s), buf_size);
+    xmemcpy(buf, s, (size_t )len);
+    *is_over = ((buf_size < (end - s)) ? 1 : 0);
+  }
+
+  return len;
+}
+
+
+/* for ONIG_MAX_ERROR_MESSAGE_LEN */
+#define MAX_ERROR_PAR_LEN   30
+
+extern int
+onig_error_code_to_str(UChar* s, OnigPosition code, ...)
+{
+  UChar *p, *q;
+  OnigErrorInfo* einfo;
+  size_t len;
+  int is_over;
+  UChar parbuf[MAX_ERROR_PAR_LEN];
+  va_list vargs;
+
+  va_start(vargs, code);
+
+  switch (code) {
+  case ONIGERR_UNDEFINED_NAME_REFERENCE:
+  case ONIGERR_UNDEFINED_GROUP_REFERENCE:
+  case ONIGERR_MULTIPLEX_DEFINED_NAME:
+  case ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL:
+  case ONIGERR_INVALID_GROUP_NAME:
+  case ONIGERR_INVALID_CHAR_IN_GROUP_NAME:
+  case ONIGERR_INVALID_CHAR_PROPERTY_NAME:
+    einfo = va_arg(vargs, OnigErrorInfo*);
+    len = to_ascii(einfo->enc, einfo->par, einfo->par_end,
+		   parbuf, MAX_ERROR_PAR_LEN - 3, &is_over);
+    q = onig_error_code_to_format(code);
+    p = s;
+    while (*q != '\0') {
+      if (*q == '%') {
+	q++;
+	if (*q == 'n') { /* '%n': name */
+	  xmemcpy(p, parbuf, len);
+	  p += len;
+	  if (is_over != 0) {
+	    xmemcpy(p, "...", 3);
+	    p += 3;
+	  }
+	  q++;
+	}
+	else
+	  goto normal_char;
+      }
+      else {
+      normal_char:
+	*p++ = *q++;
+      }
+    }
+    *p = '\0';
+    len = p - s;
+    break;
+
+  default:
+    q = onig_error_code_to_format(code);
+    if (q) {
+      len = onigenc_str_bytelen_null(ONIG_ENCODING_ASCII, q);
+      xmemcpy(s, q, len);
+    } else {
+      len = 0;
+    }
+    s[len] = '\0';
+    break;
+  }
+
+  va_end(vargs);
+  return (int )len;
+}
+
+void
+onig_vsnprintf_with_pattern(UChar buf[], int bufsize, OnigEncoding enc,
+                           UChar* pat, UChar* pat_end, const UChar *fmt, va_list args)
+{
+  size_t need;
+  int n, len;
+  UChar *p, *s, *bp;
+  UChar bs[6];
+
+  n = xvsnprintf((char* )buf, bufsize, (const char* )fmt, args);
+
+  need = (pat_end - pat) * 4 + 4;
+
+  if (n + need < (size_t )bufsize) {
+    static const char sep[] = ": /";
+    memcpy((char* )buf + n, sep, sizeof(sep));
+    s = buf + onigenc_str_bytelen_null(ONIG_ENCODING_ASCII, buf);
+
+    p = pat;
+    while (p < pat_end) {
+      if (ONIGENC_IS_MBC_HEAD(enc, p, pat_end)) {
+        len = enclen(enc, p, pat_end);
+        if (ONIGENC_MBC_MINLEN(enc) == 1) {
+          while (len-- > 0) *s++ = *p++;
+        }
+        else { /* for UTF16/32 */
+          int blen;
+
+          while (len-- > 0) {
+            sprint_byte_with_x((char* )bs, (unsigned int )(*p++));
+            blen = onigenc_str_bytelen_null(ONIG_ENCODING_ASCII, bs);
+            bp = bs;
+            while (blen-- > 0) *s++ = *bp++;
+          }
+        }
+      }
+      else if (*p == '\\') {
+	*s++ = *p++;
+	len = enclen(enc, p, pat_end);
+	while (len-- > 0) *s++ = *p++;
+      }
+      else if (*p == '/') {
+	*s++ = (unsigned char )'\\';
+	*s++ = *p++;
+      }
+      else if (!ONIGENC_IS_CODE_PRINT(enc, *p) &&
+	       !ONIGENC_IS_CODE_SPACE(enc, *p)) {
+	sprint_byte_with_x((char* )bs, (unsigned int )(*p++));
+	len = onigenc_str_bytelen_null(ONIG_ENCODING_ASCII, bs);
+        bp = bs;
+	while (len-- > 0) *s++ = *bp++;
+      }
+      else {
+	*s++ = *p++;
+      }
+    }
+
+    *s++ = '/';
+    *s   = '\0';
+  }
+}
+
+#if 0 /* unused */
+void
+onig_snprintf_with_pattern(UChar buf[], int bufsize, OnigEncoding enc,
+                           UChar* pat, UChar* pat_end, const UChar *fmt, ...)
+{
+  va_list args;
+  va_start(args, fmt);
+  onig_vsnprintf_with_pattern(buf, bufsize, enc,
+	  pat, pat_end, fmt, args);
+  va_end(args);
+}
+#endif
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/regexec.c
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/regexec.c	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/regexec.c	(revision 331)
@@ -0,0 +1,4619 @@
+/**********************************************************************
+  regexec.c -  Onigmo (Oniguruma-mod) (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2008  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011-2016  K.Takata  <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "regint.h"
+
+#ifdef RUBY
+# undef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
+#else
+# define USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
+#endif
+
+#ifndef USE_TOKEN_THREADED_VM
+# ifdef __GNUC__
+#  define USE_TOKEN_THREADED_VM 1
+# else
+#  define USE_TOKEN_THREADED_VM 0
+# endif
+#endif
+
+#ifdef RUBY
+# define ENC_DUMMY_FLAG (1<<24)
+static inline int
+rb_enc_asciicompat(OnigEncoding enc)
+{
+  return ONIGENC_MBC_MINLEN(enc)==1 && !((enc)->ruby_encoding_index & ENC_DUMMY_FLAG);
+}
+# undef ONIGENC_IS_MBC_ASCII_WORD
+# define ONIGENC_IS_MBC_ASCII_WORD(enc,s,end) \
+    (rb_enc_asciicompat(enc) ? (ISALNUM(*s) || *s=='_') : \
+   onigenc_ascii_is_code_ctype( \
+	ONIGENC_MBC_TO_CODE(enc,s,end),ONIGENC_CTYPE_WORD,enc))
+#endif /* RUBY */
+
+#ifdef USE_CRNL_AS_LINE_TERMINATOR
+# define ONIGENC_IS_MBC_CRNL(enc,p,end) \
+  (ONIGENC_MBC_TO_CODE(enc,p,end) == 13 && \
+   ONIGENC_MBC_TO_CODE(enc,(p+enclen(enc,p,end)),end) == 10)
+# define ONIGENC_IS_MBC_NEWLINE_EX(enc,p,start,end,option,check_prev) \
+  is_mbc_newline_ex((enc),(p),(start),(end),(option),(check_prev))
+static int
+is_mbc_newline_ex(OnigEncoding enc, const UChar *p, const UChar *start,
+		  const UChar *end, OnigOptionType option, int check_prev)
+{
+  if (IS_NEWLINE_CRLF(option)) {
+    if (ONIGENC_MBC_TO_CODE(enc, p, end) == 0x0a) {
+      if (check_prev) {
+	const UChar *prev = onigenc_get_prev_char_head(enc, start, p, end);
+	if ((prev != NULL) && ONIGENC_MBC_TO_CODE(enc, prev, end) == 0x0d)
+	  return 0;
+	else
+	  return 1;
+      }
+      else
+	return 1;
+    }
+    else {
+      const UChar *pnext = p + enclen(enc, p, end);
+      if (pnext < end &&
+	  ONIGENC_MBC_TO_CODE(enc, p, end) == 0x0d &&
+	  ONIGENC_MBC_TO_CODE(enc, pnext, end) == 0x0a)
+	return 1;
+      if (ONIGENC_IS_MBC_NEWLINE(enc, p, end))
+	return 1;
+      return 0;
+    }
+  }
+  else {
+    return ONIGENC_IS_MBC_NEWLINE(enc, p, end);
+  }
+}
+#else /* USE_CRNL_AS_LINE_TERMINATOR */
+# define ONIGENC_IS_MBC_NEWLINE_EX(enc,p,start,end,option,check_prev) \
+  ONIGENC_IS_MBC_NEWLINE((enc), (p), (end))
+#endif /* USE_CRNL_AS_LINE_TERMINATOR */
+
+#ifdef USE_CAPTURE_HISTORY
+static void history_tree_free(OnigCaptureTreeNode* node);
+
+static void
+history_tree_clear(OnigCaptureTreeNode* node)
+{
+  int i;
+
+  if (IS_NOT_NULL(node)) {
+    for (i = 0; i < node->num_childs; i++) {
+      if (IS_NOT_NULL(node->childs[i])) {
+	history_tree_free(node->childs[i]);
+      }
+    }
+    for (i = 0; i < node->allocated; i++) {
+      node->childs[i] = (OnigCaptureTreeNode* )0;
+    }
+    node->num_childs = 0;
+    node->beg = ONIG_REGION_NOTPOS;
+    node->end = ONIG_REGION_NOTPOS;
+    node->group = -1;
+    xfree(node->childs);
+    node->childs = (OnigCaptureTreeNode** )0;
+  }
+}
+
+static void
+history_tree_free(OnigCaptureTreeNode* node)
+{
+  history_tree_clear(node);
+  xfree(node);
+}
+
+static void
+history_root_free(OnigRegion* r)
+{
+  if (IS_NOT_NULL(r->history_root)) {
+    history_tree_free(r->history_root);
+    r->history_root = (OnigCaptureTreeNode* )0;
+  }
+}
+
+static OnigCaptureTreeNode*
+history_node_new(void)
+{
+  OnigCaptureTreeNode* node;
+
+  node = (OnigCaptureTreeNode* )xmalloc(sizeof(OnigCaptureTreeNode));
+  CHECK_NULL_RETURN(node);
+  node->childs     = (OnigCaptureTreeNode** )0;
+  node->allocated  = 0;
+  node->num_childs = 0;
+  node->group      = -1;
+  node->beg        = ONIG_REGION_NOTPOS;
+  node->end        = ONIG_REGION_NOTPOS;
+
+  return node;
+}
+
+static int
+history_tree_add_child(OnigCaptureTreeNode* parent, OnigCaptureTreeNode* child)
+{
+# define HISTORY_TREE_INIT_ALLOC_SIZE  8
+
+  if (parent->num_childs >= parent->allocated) {
+    int n, i;
+
+    if (IS_NULL(parent->childs)) {
+      n = HISTORY_TREE_INIT_ALLOC_SIZE;
+      parent->childs =
+	(OnigCaptureTreeNode** )xmalloc(sizeof(OnigCaptureTreeNode*) * n);
+      CHECK_NULL_RETURN_MEMERR(parent->childs);
+    }
+    else {
+      OnigCaptureTreeNode** tmp;
+      n = parent->allocated * 2;
+      tmp =
+	(OnigCaptureTreeNode** )xrealloc(parent->childs,
+					 sizeof(OnigCaptureTreeNode*) * n);
+      if (tmp == 0) {
+	history_tree_clear(parent);
+	return ONIGERR_MEMORY;
+      }
+      parent->childs = tmp;
+    }
+    for (i = parent->allocated; i < n; i++) {
+      parent->childs[i] = (OnigCaptureTreeNode* )0;
+    }
+    parent->allocated = n;
+  }
+
+  parent->childs[parent->num_childs] = child;
+  parent->num_childs++;
+  return 0;
+}
+
+static OnigCaptureTreeNode*
+history_tree_clone(OnigCaptureTreeNode* node)
+{
+  int i, r;
+  OnigCaptureTreeNode *clone, *child;
+
+  clone = history_node_new();
+  CHECK_NULL_RETURN(clone);
+
+  clone->beg = node->beg;
+  clone->end = node->end;
+  for (i = 0; i < node->num_childs; i++) {
+    child = history_tree_clone(node->childs[i]);
+    if (IS_NULL(child)) {
+      history_tree_free(clone);
+      return (OnigCaptureTreeNode* )0;
+    }
+    r = history_tree_add_child(clone, child);
+    if (r != 0) {
+      history_tree_free(child);
+      history_tree_free(clone);
+      return (OnigCaptureTreeNode* )0;
+    }
+  }
+
+  return clone;
+}
+
+extern  OnigCaptureTreeNode*
+onig_get_capture_tree(OnigRegion* region)
+{
+  return region->history_root;
+}
+#endif /* USE_CAPTURE_HISTORY */
+
+extern void
+onig_region_clear(OnigRegion* region)
+{
+  int i;
+
+  for (i = 0; i < region->num_regs; i++) {
+    region->beg[i] = region->end[i] = ONIG_REGION_NOTPOS;
+  }
+#ifdef USE_CAPTURE_HISTORY
+  history_root_free(region);
+#endif
+}
+
+extern int
+onig_region_resize(OnigRegion* region, int n)
+{
+  region->num_regs = n;
+
+  if (n < ONIG_NREGION)
+    n = ONIG_NREGION;
+
+  if (region->allocated == 0) {
+    region->beg = (OnigPosition* )xmalloc(n * sizeof(OnigPosition));
+    if (region->beg == 0)
+      return ONIGERR_MEMORY;
+
+    region->end = (OnigPosition* )xmalloc(n * sizeof(OnigPosition));
+    if (region->end == 0) {
+      xfree(region->beg);
+      return ONIGERR_MEMORY;
+    }
+
+    region->allocated = n;
+  }
+  else if (region->allocated < n) {
+    OnigPosition *tmp;
+
+    region->allocated = 0;
+    tmp = (OnigPosition* )xrealloc(region->beg, n * sizeof(OnigPosition));
+    if (tmp == 0) {
+      xfree(region->beg);
+      xfree(region->end);
+      return ONIGERR_MEMORY;
+    }
+    region->beg = tmp;
+    tmp = (OnigPosition* )xrealloc(region->end, n * sizeof(OnigPosition));
+    if (tmp == 0) {
+      xfree(region->beg);
+      xfree(region->end);
+      return ONIGERR_MEMORY;
+    }
+    region->end = tmp;
+
+    region->allocated = n;
+  }
+
+  return 0;
+}
+
+static int
+onig_region_resize_clear(OnigRegion* region, int n)
+{
+  int r;
+
+  r = onig_region_resize(region, n);
+  if (r != 0) return r;
+  onig_region_clear(region);
+  return 0;
+}
+
+extern int
+onig_region_set(OnigRegion* region, int at, int beg, int end)
+{
+  if (at < 0) return ONIGERR_INVALID_ARGUMENT;
+
+  if (at >= region->allocated) {
+    int r = onig_region_resize(region, at + 1);
+    if (r < 0) return r;
+  }
+
+  region->beg[at] = beg;
+  region->end[at] = end;
+  return 0;
+}
+
+extern void
+onig_region_init(OnigRegion* region)
+{
+  region->num_regs     = 0;
+  region->allocated    = 0;
+  region->beg          = (OnigPosition* )0;
+  region->end          = (OnigPosition* )0;
+  region->history_root = (OnigCaptureTreeNode* )0;
+}
+
+extern OnigRegion*
+onig_region_new(void)
+{
+  OnigRegion* r;
+
+  r = (OnigRegion* )xmalloc(sizeof(OnigRegion));
+  if (r)
+    onig_region_init(r);
+  return r;
+}
+
+extern void
+onig_region_free(OnigRegion* r, int free_self)
+{
+  if (r) {
+    if (r->allocated > 0) {
+      if (r->beg) xfree(r->beg);
+      if (r->end) xfree(r->end);
+      r->allocated = 0;
+    }
+#ifdef USE_CAPTURE_HISTORY
+    history_root_free(r);
+#endif
+    if (free_self) xfree(r);
+  }
+}
+
+extern void
+onig_region_copy(OnigRegion* to, const OnigRegion* from)
+{
+#define RREGC_SIZE   (sizeof(int) * from->num_regs)
+  int i, r;
+
+  if (to == from) return;
+
+  r = onig_region_resize(to, from->num_regs);
+  if (r) return;
+
+  for (i = 0; i < from->num_regs; i++) {
+    to->beg[i] = from->beg[i];
+    to->end[i] = from->end[i];
+  }
+  to->num_regs = from->num_regs;
+
+#ifdef USE_CAPTURE_HISTORY
+  history_root_free(to);
+
+  if (IS_NOT_NULL(from->history_root)) {
+    to->history_root = history_tree_clone(from->history_root);
+  }
+#endif
+}
+
+
+/** stack **/
+#define INVALID_STACK_INDEX   -1
+
+/* stack type */
+/* used by normal-POP */
+#define STK_ALT                    0x0001
+#define STK_LOOK_BEHIND_NOT        0x0002
+#define STK_POS_NOT                0x0003
+/* handled by normal-POP */
+#define STK_MEM_START              0x0100
+#define STK_MEM_END                0x8200
+#define STK_REPEAT_INC             0x0300
+#define STK_STATE_CHECK_MARK       0x1000
+/* avoided by normal-POP */
+#define STK_NULL_CHECK_START       0x3000
+#define STK_NULL_CHECK_END         0x5000  /* for recursive call */
+#define STK_MEM_END_MARK           0x8400
+#define STK_POS                    0x0500  /* used when POP-POS */
+#define STK_STOP_BT                0x0600  /* mark for "(?>...)" */
+#define STK_REPEAT                 0x0700
+#define STK_CALL_FRAME             0x0800
+#define STK_RETURN                 0x0900
+#define STK_VOID                   0x0a00  /* for fill a blank */
+#define STK_ABSENT_POS             0x0b00  /* for absent */
+#define STK_ABSENT                 0x0c00  /* absent inner loop marker */
+
+/* stack type check mask */
+#define STK_MASK_POP_USED          0x00ff
+#define STK_MASK_TO_VOID_TARGET    0x10ff
+#define STK_MASK_MEM_END_OR_MARK   0x8000  /* MEM_END or MEM_END_MARK */
+
+#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
+# define MATCH_ARG_INIT(msa, arg_option, arg_region, arg_start, arg_gpos) do {\
+  (msa).stack_p  = (void* )0;\
+  (msa).options  = (arg_option);\
+  (msa).region   = (arg_region);\
+  (msa).start    = (arg_start);\
+  (msa).gpos     = (arg_gpos);\
+  (msa).best_len = ONIG_MISMATCH;\
+} while(0)
+#else
+# define MATCH_ARG_INIT(msa, arg_option, arg_region, arg_start, arg_gpos) do {\
+  (msa).stack_p  = (void* )0;\
+  (msa).options  = (arg_option);\
+  (msa).region   = (arg_region);\
+  (msa).start    = (arg_start);\
+  (msa).gpos     = (arg_gpos);\
+} while(0)
+#endif
+
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+
+# define STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE  16
+
+# define STATE_CHECK_BUFF_INIT(msa, str_len, offset, state_num) do {	\
+  if ((state_num) > 0 && str_len >= STATE_CHECK_STRING_THRESHOLD_LEN) {\
+    unsigned int size = (unsigned int )(((str_len) + 1) * (state_num) + 7) >> 3;\
+    offset = ((offset) * (state_num)) >> 3;\
+    if (size > 0 && offset < size && size < STATE_CHECK_BUFF_MAX_SIZE) {\
+      if (size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) {\
+        (msa).state_check_buff = (void* )xmalloc(size);\
+        CHECK_NULL_RETURN_MEMERR((msa).state_check_buff);\
+      }\
+      else \
+        (msa).state_check_buff = (void* )xalloca(size);\
+      xmemset(((char* )((msa).state_check_buff)+(offset)), 0, \
+              (size_t )(size - (offset))); \
+      (msa).state_check_buff_size = size;\
+    }\
+    else {\
+      (msa).state_check_buff = (void* )0;\
+      (msa).state_check_buff_size = 0;\
+    }\
+  }\
+  else {\
+    (msa).state_check_buff = (void* )0;\
+    (msa).state_check_buff_size = 0;\
+  }\
+  } while(0)
+
+# define MATCH_ARG_FREE(msa) do {\
+  if ((msa).stack_p) xfree((msa).stack_p);\
+  if ((msa).state_check_buff_size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) { \
+    if ((msa).state_check_buff) xfree((msa).state_check_buff);\
+  }\
+} while(0)
+#else /* USE_COMBINATION_EXPLOSION_CHECK */
+# define MATCH_ARG_FREE(msa)  if ((msa).stack_p) xfree((msa).stack_p)
+#endif /* USE_COMBINATION_EXPLOSION_CHECK */
+
+
+
+#define MAX_PTR_NUM 100
+
+#define STACK_INIT(alloc_addr, heap_addr, ptr_num, stack_num)  do {\
+  if (ptr_num > MAX_PTR_NUM) {\
+    alloc_addr = (char* )xmalloc(sizeof(OnigStackIndex) * (ptr_num));\
+    heap_addr  = alloc_addr;\
+    if (msa->stack_p) {\
+      stk_alloc = (OnigStackType* )(msa->stack_p);\
+      stk_base  = stk_alloc;\
+      stk       = stk_base;\
+      stk_end   = stk_base + msa->stack_n;\
+    } else {\
+      stk_alloc = (OnigStackType* )xalloca(sizeof(OnigStackType) * (stack_num));\
+      stk_base  = stk_alloc;\
+      stk       = stk_base;\
+      stk_end   = stk_base + (stack_num);\
+    }\
+  } else if (msa->stack_p) {\
+    alloc_addr = (char* )xalloca(sizeof(OnigStackIndex) * (ptr_num));\
+    heap_addr  = NULL;\
+    stk_alloc  = (OnigStackType* )(msa->stack_p);\
+    stk_base   = stk_alloc;\
+    stk        = stk_base;\
+    stk_end    = stk_base + msa->stack_n;\
+  }\
+  else {\
+    alloc_addr = (char* )xalloca(sizeof(OnigStackIndex) * (ptr_num)\
+		       + sizeof(OnigStackType) * (stack_num));\
+    heap_addr  = NULL;\
+    stk_alloc  = (OnigStackType* )(alloc_addr + sizeof(OnigStackIndex) * (ptr_num));\
+    stk_base   = stk_alloc;\
+    stk        = stk_base;\
+    stk_end    = stk_base + (stack_num);\
+  }\
+} while(0)
+
+#define STACK_SAVE do{\
+  if (stk_base != stk_alloc) {\
+    msa->stack_p = stk_base;\
+    msa->stack_n = stk_end - stk_base; /* TODO: check overflow */\
+  };\
+} while(0)
+
+static unsigned int MatchStackLimitSize = DEFAULT_MATCH_STACK_LIMIT_SIZE;
+
+extern unsigned int
+onig_get_match_stack_limit_size(void)
+{
+  return MatchStackLimitSize;
+}
+
+extern int
+onig_set_match_stack_limit_size(unsigned int size)
+{
+  MatchStackLimitSize = size;
+  return 0;
+}
+
+static int
+stack_double(OnigStackType** arg_stk_base, OnigStackType** arg_stk_end,
+	     OnigStackType** arg_stk, OnigStackType* stk_alloc, OnigMatchArg* msa)
+{
+  size_t n;
+  OnigStackType *x, *stk_base, *stk_end, *stk;
+
+  stk_base = *arg_stk_base;
+  stk_end  = *arg_stk_end;
+  stk      = *arg_stk;
+
+  n = stk_end - stk_base;
+  if (stk_base == stk_alloc && IS_NULL(msa->stack_p)) {
+    x = (OnigStackType* )xmalloc(sizeof(OnigStackType) * n * 2);
+    if (IS_NULL(x)) {
+      STACK_SAVE;
+      return ONIGERR_MEMORY;
+    }
+    xmemcpy(x, stk_base, n * sizeof(OnigStackType));
+    n *= 2;
+  }
+  else {
+    unsigned int limit_size = MatchStackLimitSize;
+    n *= 2;
+    if (limit_size != 0 && n > limit_size) {
+      if ((unsigned int )(stk_end - stk_base) == limit_size)
+	return ONIGERR_MATCH_STACK_LIMIT_OVER;
+      else
+	n = limit_size;
+    }
+    x = (OnigStackType* )xrealloc(stk_base, sizeof(OnigStackType) * n);
+    if (IS_NULL(x)) {
+      STACK_SAVE;
+      return ONIGERR_MEMORY;
+    }
+  }
+  *arg_stk      = x + (stk - stk_base);
+  *arg_stk_base = x;
+  *arg_stk_end  = x + n;
+  return 0;
+}
+
+#define STACK_ENSURE(n)	do {\
+  if (stk_end - stk < (n)) {\
+    int r = stack_double(&stk_base, &stk_end, &stk, stk_alloc, msa);\
+    if (r != 0) {\
+      STACK_SAVE;\
+      if (xmalloc_base) xfree(xmalloc_base);\
+      return r;\
+    }\
+  }\
+} while(0)
+
+#define STACK_AT(index)        (stk_base + (index))
+#define GET_STACK_INDEX(stk)   ((stk) - stk_base)
+
+#define STACK_PUSH_TYPE(stack_type) do {\
+  STACK_ENSURE(1);\
+  stk->type = (stack_type);\
+  STACK_INC;\
+} while(0)
+
+#define IS_TO_VOID_TARGET(stk) (((stk)->type & STK_MASK_TO_VOID_TARGET) != 0)
+
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+# define STATE_CHECK_POS(s,snum) \
+  (((s) - str) * num_comb_exp_check + ((snum) - 1))
+# define STATE_CHECK_VAL(v,snum) do {\
+  if (state_check_buff != NULL) {\
+    int x = STATE_CHECK_POS(s,snum);\
+    (v) = state_check_buff[x/8] & (1<<(x%8));\
+  }\
+  else (v) = 0;\
+} while(0)
+
+
+# define ELSE_IF_STATE_CHECK_MARK(stk) \
+  else if ((stk)->type == STK_STATE_CHECK_MARK) { \
+    int x = STATE_CHECK_POS(stk->u.state.pstr, stk->u.state.state_check);\
+    state_check_buff[x/8] |= (1<<(x%8));				\
+  }
+
+# define STACK_PUSH(stack_type,pat,s,sprev,keep) do {\
+  STACK_ENSURE(1);\
+  stk->type = (stack_type);\
+  stk->u.state.pcode     = (pat);\
+  stk->u.state.pstr      = (s);\
+  stk->u.state.pstr_prev = (sprev);\
+  stk->u.state.state_check = 0;\
+  stk->u.state.pkeep     = (keep);\
+  STACK_INC;\
+} while(0)
+
+# define STACK_PUSH_ENSURED(stack_type,pat) do {\
+  stk->type = (stack_type);\
+  stk->u.state.pcode = (pat);\
+  stk->u.state.state_check = 0;\
+  STACK_INC;\
+} while(0)
+
+# define STACK_PUSH_ALT_WITH_STATE_CHECK(pat,s,sprev,snum,keep) do {\
+  STACK_ENSURE(1);\
+  stk->type = STK_ALT;\
+  stk->u.state.pcode     = (pat);\
+  stk->u.state.pstr      = (s);\
+  stk->u.state.pstr_prev = (sprev);\
+  stk->u.state.state_check = ((state_check_buff != NULL) ? (snum) : 0);\
+  stk->u.state.pkeep     = (keep);\
+  STACK_INC;\
+} while(0)
+
+# define STACK_PUSH_STATE_CHECK(s,snum) do {\
+  if (state_check_buff != NULL) {\
+    STACK_ENSURE(1);\
+    stk->type = STK_STATE_CHECK_MARK;\
+    stk->u.state.pstr = (s);\
+    stk->u.state.state_check = (snum);\
+    STACK_INC;\
+  }\
+} while(0)
+
+#else /* USE_COMBINATION_EXPLOSION_CHECK */
+
+# define ELSE_IF_STATE_CHECK_MARK(stk)
+
+# define STACK_PUSH(stack_type,pat,s,sprev,keep) do {\
+  STACK_ENSURE(1);\
+  stk->type = (stack_type);\
+  stk->u.state.pcode     = (pat);\
+  stk->u.state.pstr      = (s);\
+  stk->u.state.pstr_prev = (sprev);\
+  stk->u.state.pkeep     = (keep);\
+  STACK_INC;\
+} while(0)
+
+# define STACK_PUSH_ENSURED(stack_type,pat) do {\
+  stk->type = (stack_type);\
+  stk->u.state.pcode = (pat);\
+  STACK_INC;\
+} while(0)
+#endif /* USE_COMBINATION_EXPLOSION_CHECK */
+
+#define STACK_PUSH_ALT(pat,s,sprev,keep)     STACK_PUSH(STK_ALT,pat,s,sprev,keep)
+#define STACK_PUSH_POS(s,sprev,keep)         STACK_PUSH(STK_POS,NULL_UCHARP,s,sprev,keep)
+#define STACK_PUSH_POS_NOT(pat,s,sprev,keep) STACK_PUSH(STK_POS_NOT,pat,s,sprev,keep)
+#define STACK_PUSH_ABSENT                    STACK_PUSH_TYPE(STK_ABSENT)
+#define STACK_PUSH_STOP_BT                   STACK_PUSH_TYPE(STK_STOP_BT)
+#define STACK_PUSH_LOOK_BEHIND_NOT(pat,s,sprev,keep) \
+        STACK_PUSH(STK_LOOK_BEHIND_NOT,pat,s,sprev,keep)
+
+#define STACK_PUSH_REPEAT(id, pat) do {\
+  STACK_ENSURE(1);\
+  stk->type = STK_REPEAT;\
+  stk->u.repeat.num    = (id);\
+  stk->u.repeat.pcode  = (pat);\
+  stk->u.repeat.count  = 0;\
+  STACK_INC;\
+} while(0)
+
+#define STACK_PUSH_REPEAT_INC(sindex) do {\
+  STACK_ENSURE(1);\
+  stk->type = STK_REPEAT_INC;\
+  stk->u.repeat_inc.si  = (sindex);\
+  STACK_INC;\
+} while(0)
+
+#define STACK_PUSH_MEM_START(mnum, s) do {\
+  STACK_ENSURE(1);\
+  stk->type = STK_MEM_START;\
+  stk->u.mem.num      = (mnum);\
+  stk->u.mem.pstr     = (s);\
+  stk->u.mem.start    = mem_start_stk[mnum];\
+  stk->u.mem.end      = mem_end_stk[mnum];\
+  mem_start_stk[mnum] = GET_STACK_INDEX(stk);\
+  mem_end_stk[mnum]   = INVALID_STACK_INDEX;\
+  STACK_INC;\
+} while(0)
+
+#define STACK_PUSH_MEM_END(mnum, s) do {\
+  STACK_ENSURE(1);\
+  stk->type = STK_MEM_END;\
+  stk->u.mem.num    = (mnum);\
+  stk->u.mem.pstr   = (s);\
+  stk->u.mem.start  = mem_start_stk[mnum];\
+  stk->u.mem.end    = mem_end_stk[mnum];\
+  mem_end_stk[mnum] = GET_STACK_INDEX(stk);\
+  STACK_INC;\
+} while(0)
+
+#define STACK_PUSH_MEM_END_MARK(mnum) do {\
+  STACK_ENSURE(1);\
+  stk->type = STK_MEM_END_MARK;\
+  stk->u.mem.num = (mnum);\
+  STACK_INC;\
+} while(0)
+
+#define STACK_GET_MEM_START(mnum, k) do {\
+  int level = 0;\
+  k = stk;\
+  while (k > stk_base) {\
+    k--;\
+    if ((k->type & STK_MASK_MEM_END_OR_MARK) != 0 \
+      && k->u.mem.num == (mnum)) {\
+      level++;\
+    }\
+    else if (k->type == STK_MEM_START && k->u.mem.num == (mnum)) {\
+      if (level == 0) break;\
+      level--;\
+    }\
+  }\
+} while(0)
+
+#define STACK_GET_MEM_RANGE(k, mnum, start, end) do {\
+  int level = 0;\
+  while (k < stk) {\
+    if (k->type == STK_MEM_START && k->u.mem.num == (mnum)) {\
+      if (level == 0) (start) = k->u.mem.pstr;\
+      level++;\
+    }\
+    else if (k->type == STK_MEM_END && k->u.mem.num == (mnum)) {\
+      level--;\
+      if (level == 0) {\
+        (end) = k->u.mem.pstr;\
+        break;\
+      }\
+    }\
+    k++;\
+  }\
+} while(0)
+
+#define STACK_PUSH_NULL_CHECK_START(cnum, s) do {\
+  STACK_ENSURE(1);\
+  stk->type = STK_NULL_CHECK_START;\
+  stk->u.null_check.num  = (cnum);\
+  stk->u.null_check.pstr = (s);\
+  STACK_INC;\
+} while(0)
+
+#define STACK_PUSH_NULL_CHECK_END(cnum) do {\
+  STACK_ENSURE(1);\
+  stk->type = STK_NULL_CHECK_END;\
+  stk->u.null_check.num  = (cnum);\
+  STACK_INC;\
+} while(0)
+
+#define STACK_PUSH_CALL_FRAME(pat) do {\
+  STACK_ENSURE(1);\
+  stk->type = STK_CALL_FRAME;\
+  stk->u.call_frame.ret_addr = (pat);\
+  STACK_INC;\
+} while(0)
+
+#define STACK_PUSH_RETURN do {\
+  STACK_ENSURE(1);\
+  stk->type = STK_RETURN;\
+  STACK_INC;\
+} while(0)
+
+#define STACK_PUSH_ABSENT_POS(start, end) do {\
+  STACK_ENSURE(1);\
+  stk->type = STK_ABSENT_POS;\
+  stk->u.absent_pos.abs_pstr = (start);\
+  stk->u.absent_pos.end_pstr = (end);\
+  STACK_INC;\
+} while(0)
+
+
+#ifdef ONIG_DEBUG
+# define STACK_BASE_CHECK(p, at) \
+  if ((p) < stk_base) {\
+    fprintf(stderr, "at %s\n", at);\
+    goto stack_error;\
+  }
+#else
+# define STACK_BASE_CHECK(p, at)
+#endif
+
+#define STACK_POP_ONE do {\
+  stk--;\
+  STACK_BASE_CHECK(stk, "STACK_POP_ONE"); \
+} while(0)
+
+#define STACK_POP  do {\
+  switch (pop_level) {\
+  case STACK_POP_LEVEL_FREE:\
+    while (1) {\
+      stk--;\
+      STACK_BASE_CHECK(stk, "STACK_POP"); \
+      if ((stk->type & STK_MASK_POP_USED) != 0)  break;\
+      ELSE_IF_STATE_CHECK_MARK(stk);\
+    }\
+    break;\
+  case STACK_POP_LEVEL_MEM_START:\
+    while (1) {\
+      stk--;\
+      STACK_BASE_CHECK(stk, "STACK_POP 2"); \
+      if ((stk->type & STK_MASK_POP_USED) != 0)  break;\
+      else if (stk->type == STK_MEM_START) {\
+        mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
+        mem_end_stk[stk->u.mem.num]   = stk->u.mem.end;\
+      }\
+      ELSE_IF_STATE_CHECK_MARK(stk);\
+    }\
+    break;\
+  default:\
+    while (1) {\
+      stk--;\
+      STACK_BASE_CHECK(stk, "STACK_POP 3"); \
+      if ((stk->type & STK_MASK_POP_USED) != 0)  break;\
+      else if (stk->type == STK_MEM_START) {\
+        mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
+        mem_end_stk[stk->u.mem.num]   = stk->u.mem.end;\
+      }\
+      else if (stk->type == STK_REPEAT_INC) {\
+        STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\
+      }\
+      else if (stk->type == STK_MEM_END) {\
+        mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
+        mem_end_stk[stk->u.mem.num]   = stk->u.mem.end;\
+      }\
+      ELSE_IF_STATE_CHECK_MARK(stk);\
+    }\
+    break;\
+  }\
+} while(0)
+
+#define STACK_POP_TIL_POS_NOT  do {\
+  while (1) {\
+    stk--;\
+    STACK_BASE_CHECK(stk, "STACK_POP_TIL_POS_NOT"); \
+    if (stk->type == STK_POS_NOT) break;\
+    else if (stk->type == STK_MEM_START) {\
+      mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
+      mem_end_stk[stk->u.mem.num]   = stk->u.mem.end;\
+    }\
+    else if (stk->type == STK_REPEAT_INC) {\
+      STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\
+    }\
+    else if (stk->type == STK_MEM_END) {\
+      mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
+      mem_end_stk[stk->u.mem.num]   = stk->u.mem.end;\
+    }\
+    ELSE_IF_STATE_CHECK_MARK(stk);\
+  }\
+} while(0)
+
+#define STACK_POP_TIL_LOOK_BEHIND_NOT  do {\
+  while (1) {\
+    stk--;\
+    STACK_BASE_CHECK(stk, "STACK_POP_TIL_LOOK_BEHIND_NOT"); \
+    if (stk->type == STK_LOOK_BEHIND_NOT) break;\
+    else if (stk->type == STK_MEM_START) {\
+      mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
+      mem_end_stk[stk->u.mem.num]   = stk->u.mem.end;\
+    }\
+    else if (stk->type == STK_REPEAT_INC) {\
+      STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\
+    }\
+    else if (stk->type == STK_MEM_END) {\
+      mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
+      mem_end_stk[stk->u.mem.num]   = stk->u.mem.end;\
+    }\
+    ELSE_IF_STATE_CHECK_MARK(stk);\
+  }\
+} while(0)
+
+#define STACK_POP_TIL_ABSENT  do {\
+  while (1) {\
+    stk--;\
+    STACK_BASE_CHECK(stk, "STACK_POP_TIL_ABSENT"); \
+    if (stk->type == STK_ABSENT) break;\
+    else if (stk->type == STK_MEM_START) {\
+      mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
+      mem_end_stk[stk->u.mem.num]   = stk->u.mem.end;\
+    }\
+    else if (stk->type == STK_REPEAT_INC) {\
+      STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\
+    }\
+    else if (stk->type == STK_MEM_END) {\
+      mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
+      mem_end_stk[stk->u.mem.num]   = stk->u.mem.end;\
+    }\
+    ELSE_IF_STATE_CHECK_MARK(stk);\
+  }\
+} while(0)
+
+#define STACK_POP_ABSENT_POS(start, end) do {\
+  stk--;\
+  STACK_BASE_CHECK(stk, "STACK_POP_ABSENT_POS"); \
+  (start) = stk->u.absent_pos.abs_pstr;\
+  (end) = stk->u.absent_pos.end_pstr;\
+} while(0)
+
+#define STACK_POS_END(k) do {\
+  k = stk;\
+  while (1) {\
+    k--;\
+    STACK_BASE_CHECK(k, "STACK_POS_END"); \
+    if (IS_TO_VOID_TARGET(k)) {\
+      k->type = STK_VOID;\
+    }\
+    else if (k->type == STK_POS) {\
+      k->type = STK_VOID;\
+      break;\
+    }\
+  }\
+} while(0)
+
+#define STACK_STOP_BT_END do {\
+  OnigStackType *k = stk;\
+  while (1) {\
+    k--;\
+    STACK_BASE_CHECK(k, "STACK_STOP_BT_END"); \
+    if (IS_TO_VOID_TARGET(k)) {\
+      k->type = STK_VOID;\
+    }\
+    else if (k->type == STK_STOP_BT) {\
+      k->type = STK_VOID;\
+      break;\
+    }\
+  }\
+} while(0)
+
+#define STACK_NULL_CHECK(isnull,id,s) do {\
+  OnigStackType* k = stk;\
+  while (1) {\
+    k--;\
+    STACK_BASE_CHECK(k, "STACK_NULL_CHECK"); \
+    if (k->type == STK_NULL_CHECK_START) {\
+      if (k->u.null_check.num == (id)) {\
+        (isnull) = (k->u.null_check.pstr == (s));\
+        break;\
+      }\
+    }\
+  }\
+} while(0)
+
+#define STACK_NULL_CHECK_REC(isnull,id,s) do {\
+  int level = 0;\
+  OnigStackType* k = stk;\
+  while (1) {\
+    k--;\
+    STACK_BASE_CHECK(k, "STACK_NULL_CHECK_REC"); \
+    if (k->type == STK_NULL_CHECK_START) {\
+      if (k->u.null_check.num == (id)) {\
+        if (level == 0) {\
+          (isnull) = (k->u.null_check.pstr == (s));\
+          break;\
+        }\
+        else level--;\
+      }\
+    }\
+    else if (k->type == STK_NULL_CHECK_END) {\
+      level++;\
+    }\
+  }\
+} while(0)
+
+#define STACK_NULL_CHECK_MEMST(isnull,id,s,reg) do {\
+  OnigStackType* k = stk;\
+  while (1) {\
+    k--;\
+    STACK_BASE_CHECK(k, "STACK_NULL_CHECK_MEMST"); \
+    if (k->type == STK_NULL_CHECK_START) {\
+      if (k->u.null_check.num == (id)) {\
+        if (k->u.null_check.pstr != (s)) {\
+          (isnull) = 0;\
+          break;\
+        }\
+        else {\
+          UChar* endp;\
+          (isnull) = 1;\
+          while (k < stk) {\
+            if (k->type == STK_MEM_START) {\
+              if (k->u.mem.end == INVALID_STACK_INDEX) {\
+                (isnull) = 0; break;\
+              }\
+              if (BIT_STATUS_AT(reg->bt_mem_end, k->u.mem.num))\
+                endp = STACK_AT(k->u.mem.end)->u.mem.pstr;\
+              else\
+                endp = (UChar* )k->u.mem.end;\
+              if (STACK_AT(k->u.mem.start)->u.mem.pstr != endp) {\
+                (isnull) = 0; break;\
+              }\
+              else if (endp != s) {\
+                (isnull) = -1; /* empty, but position changed */ \
+              }\
+            }\
+            k++;\
+          }\
+          break;\
+        }\
+      }\
+    }\
+  }\
+} while(0)
+
+#define STACK_NULL_CHECK_MEMST_REC(isnull,id,s,reg) do {\
+  int level = 0;\
+  OnigStackType* k = stk;\
+  while (1) {\
+    k--;\
+    STACK_BASE_CHECK(k, "STACK_NULL_CHECK_MEMST_REC"); \
+    if (k->type == STK_NULL_CHECK_START) {\
+      if (k->u.null_check.num == (id)) {\
+        if (level == 0) {\
+          if (k->u.null_check.pstr != (s)) {\
+            (isnull) = 0;\
+            break;\
+          }\
+          else {\
+            UChar* endp;\
+            (isnull) = 1;\
+            while (k < stk) {\
+              if (k->type == STK_MEM_START) {\
+                if (k->u.mem.end == INVALID_STACK_INDEX) {\
+                  (isnull) = 0; break;\
+                }\
+                if (BIT_STATUS_AT(reg->bt_mem_end, k->u.mem.num))\
+                  endp = STACK_AT(k->u.mem.end)->u.mem.pstr;\
+                else\
+                  endp = (UChar* )k->u.mem.end;\
+                if (STACK_AT(k->u.mem.start)->u.mem.pstr != endp) {\
+                  (isnull) = 0; break;\
+                }\
+                else if (endp != s) {\
+                  (isnull) = -1; /* empty, but position changed */ \
+                }\
+              }\
+              k++;\
+            }\
+            break;\
+          }\
+        }\
+        else {\
+          level--;\
+        }\
+      }\
+    }\
+    else if (k->type == STK_NULL_CHECK_END) {\
+      if (k->u.null_check.num == (id)) level++;\
+    }\
+  }\
+} while(0)
+
+#define STACK_GET_REPEAT(id, k) do {\
+  int level = 0;\
+  k = stk;\
+  while (1) {\
+    k--;\
+    STACK_BASE_CHECK(k, "STACK_GET_REPEAT"); \
+    if (k->type == STK_REPEAT) {\
+      if (level == 0) {\
+        if (k->u.repeat.num == (id)) {\
+          break;\
+        }\
+      }\
+    }\
+    else if (k->type == STK_CALL_FRAME) level--;\
+    else if (k->type == STK_RETURN)     level++;\
+  }\
+} while(0)
+
+#define STACK_RETURN(addr)  do {\
+  int level = 0;\
+  OnigStackType* k = stk;\
+  while (1) {\
+    k--;\
+    STACK_BASE_CHECK(k, "STACK_RETURN"); \
+    if (k->type == STK_CALL_FRAME) {\
+      if (level == 0) {\
+        (addr) = k->u.call_frame.ret_addr;\
+        break;\
+      }\
+      else level--;\
+    }\
+    else if (k->type == STK_RETURN)\
+      level++;\
+  }\
+} while(0)
+
+
+#define STRING_CMP(s1,s2,len) do {\
+  while (len-- > 0) {\
+    if (*s1++ != *s2++) goto fail;\
+  }\
+} while(0)
+
+#define STRING_CMP_IC(case_fold_flag,s1,ps2,len,text_end) do {\
+  if (string_cmp_ic(encode, case_fold_flag, s1, ps2, len, text_end) == 0) \
+    goto fail; \
+} while(0)
+
+static int string_cmp_ic(OnigEncoding enc, int case_fold_flag,
+			 UChar* s1, UChar** ps2, OnigDistance mblen, const UChar* text_end)
+{
+  UChar buf1[ONIGENC_MBC_CASE_FOLD_MAXLEN];
+  UChar buf2[ONIGENC_MBC_CASE_FOLD_MAXLEN];
+  UChar *p1, *p2, *end1, *s2;
+  int len1, len2;
+
+  s2   = *ps2;
+  end1 = s1 + mblen;
+  while (s1 < end1) {
+    len1 = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &s1, text_end, buf1);
+    len2 = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &s2, text_end, buf2);
+    if (len1 != len2) return 0;
+    p1 = buf1;
+    p2 = buf2;
+    while (len1-- > 0) {
+      if (*p1 != *p2) return 0;
+      p1++;
+      p2++;
+    }
+  }
+
+  *ps2 = s2;
+  return 1;
+}
+
+#define STRING_CMP_VALUE(s1,s2,len,is_fail) do {\
+  is_fail = 0;\
+  while (len-- > 0) {\
+    if (*s1++ != *s2++) {\
+      is_fail = 1; break;\
+    }\
+  }\
+} while(0)
+
+#define STRING_CMP_VALUE_IC(case_fold_flag,s1,ps2,len,text_end,is_fail) do {\
+  if (string_cmp_ic(encode, case_fold_flag, s1, ps2, len, text_end) == 0) \
+    is_fail = 1; \
+  else \
+    is_fail = 0; \
+} while(0)
+
+
+#define IS_EMPTY_STR           (str == end)
+#define ON_STR_BEGIN(s)        ((s) == str)
+#define ON_STR_END(s)          ((s) == end)
+#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
+# define DATA_ENSURE_CHECK1    (s < right_range)
+# define DATA_ENSURE_CHECK(n)  (s + (n) <= right_range)
+# define DATA_ENSURE(n)        if (s + (n) > right_range) goto fail
+# define ABSENT_END_POS        right_range
+#else
+# define DATA_ENSURE_CHECK1    (s < end)
+# define DATA_ENSURE_CHECK(n)  (s + (n) <= end)
+# define DATA_ENSURE(n)        if (s + (n) > end) goto fail
+# define ABSENT_END_POS        end
+#endif /* USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE */
+
+
+#ifdef USE_CAPTURE_HISTORY
+static int
+make_capture_history_tree(OnigCaptureTreeNode* node, OnigStackType** kp,
+                          OnigStackType* stk_top, UChar* str, regex_t* reg)
+{
+  int n, r;
+  OnigCaptureTreeNode* child;
+  OnigStackType* k = *kp;
+
+  while (k < stk_top) {
+    if (k->type == STK_MEM_START) {
+      n = k->u.mem.num;
+      if (n <= ONIG_MAX_CAPTURE_HISTORY_GROUP &&
+	  BIT_STATUS_AT(reg->capture_history, n) != 0) {
+	child = history_node_new();
+	CHECK_NULL_RETURN_MEMERR(child);
+	child->group = n;
+	child->beg = k->u.mem.pstr - str;
+	r = history_tree_add_child(node, child);
+	if (r != 0) {
+	  history_tree_free(child);
+	  return r;
+	}
+	*kp = (k + 1);
+	r = make_capture_history_tree(child, kp, stk_top, str, reg);
+	if (r != 0) return r;
+
+	k = *kp;
+	child->end = k->u.mem.pstr - str;
+      }
+    }
+    else if (k->type == STK_MEM_END) {
+      if (k->u.mem.num == node->group) {
+	node->end = k->u.mem.pstr - str;
+	*kp = k;
+	return 0;
+      }
+    }
+    k++;
+  }
+
+  return 1; /* 1: root node ending. */
+}
+#endif /* USE_CAPTURE_HISTORY */
+
+#ifdef USE_BACKREF_WITH_LEVEL
+static int mem_is_in_memp(int mem, int num, UChar* memp)
+{
+  int i;
+  MemNumType m;
+
+  for (i = 0; i < num; i++) {
+    GET_MEMNUM_INC(m, memp);
+    if (mem == (int )m) return 1;
+  }
+  return 0;
+}
+
+static int backref_match_at_nested_level(regex_t* reg,
+	 OnigStackType* top, OnigStackType* stk_base,
+	 int ignore_case, int case_fold_flag,
+	 int nest, int mem_num, UChar* memp, UChar** s, const UChar* send)
+{
+  UChar *ss, *p, *pstart, *pend = NULL_UCHARP;
+  int level;
+  OnigStackType* k;
+
+  level = 0;
+  k = top;
+  k--;
+  while (k >= stk_base) {
+    if (k->type == STK_CALL_FRAME) {
+      level--;
+    }
+    else if (k->type == STK_RETURN) {
+      level++;
+    }
+    else if (level == nest) {
+      if (k->type == STK_MEM_START) {
+	if (mem_is_in_memp(k->u.mem.num, mem_num, memp)) {
+	  pstart = k->u.mem.pstr;
+	  if (pend != NULL_UCHARP) {
+	    if (pend - pstart > send - *s) return 0; /* or goto next_mem; */
+	    p  = pstart;
+	    ss = *s;
+
+	    if (ignore_case != 0) {
+	      if (string_cmp_ic(reg->enc, case_fold_flag,
+				pstart, &ss, pend - pstart, send) == 0)
+		return 0; /* or goto next_mem; */
+	    }
+	    else {
+	      while (p < pend) {
+		if (*p++ != *ss++) return 0; /* or goto next_mem; */
+	      }
+	    }
+
+	    *s = ss;
+	    return 1;
+	  }
+	}
+      }
+      else if (k->type == STK_MEM_END) {
+	if (mem_is_in_memp(k->u.mem.num, mem_num, memp)) {
+	  pend = k->u.mem.pstr;
+	}
+      }
+    }
+    k--;
+  }
+
+  return 0;
+}
+#endif /* USE_BACKREF_WITH_LEVEL */
+
+
+#ifdef ONIG_DEBUG_STATISTICS
+
+# ifdef _WIN32
+#  include <windows.h>
+static LARGE_INTEGER ts, te, freq;
+#  define GETTIME(t)	  QueryPerformanceCounter(&(t))
+#  define TIMEDIFF(te,ts) (unsigned long )(((te).QuadPart - (ts).QuadPart) \
+			    * 1000000 / freq.QuadPart)
+# else /* _WIN32 */
+
+#  define USE_TIMEOFDAY
+
+#  ifdef USE_TIMEOFDAY
+#   ifdef HAVE_SYS_TIME_H
+#    include <sys/time.h>
+#   endif
+#   ifdef HAVE_UNISTD_H
+#    include <unistd.h>
+#   endif
+static struct timeval ts, te;
+#   define GETTIME(t)      gettimeofday(&(t), (struct timezone* )0)
+#   define TIMEDIFF(te,ts) (((te).tv_usec - (ts).tv_usec) + \
+                            (((te).tv_sec - (ts).tv_sec)*1000000))
+#  else /* USE_TIMEOFDAY */
+#   ifdef HAVE_SYS_TIMES_H
+#    include <sys/times.h>
+#   endif
+static struct tms ts, te;
+#   define GETTIME(t)       times(&(t))
+#   define TIMEDIFF(te,ts)  ((te).tms_utime - (ts).tms_utime)
+#  endif /* USE_TIMEOFDAY */
+
+# endif /* _WIN32 */
+
+static int OpCounter[256];
+static int OpPrevCounter[256];
+static unsigned long OpTime[256];
+static int OpCurr = OP_FINISH;
+static int OpPrevTarget = OP_FAIL;
+static int MaxStackDepth = 0;
+
+# define MOP_IN(opcode) do {\
+  if (opcode == OpPrevTarget) OpPrevCounter[OpCurr]++;\
+  OpCurr = opcode;\
+  OpCounter[opcode]++;\
+  GETTIME(ts);\
+} while(0)
+
+# define MOP_OUT do {\
+  GETTIME(te);\
+  OpTime[OpCurr] += TIMEDIFF(te, ts);\
+} while(0)
+
+extern void
+onig_statistics_init(void)
+{
+  int i;
+  for (i = 0; i < 256; i++) {
+    OpCounter[i] = OpPrevCounter[i] = 0; OpTime[i] = 0;
+  }
+  MaxStackDepth = 0;
+# ifdef _WIN32
+  QueryPerformanceFrequency(&freq);
+# endif
+}
+
+extern void
+onig_print_statistics(FILE* f)
+{
+  int i;
+  fprintf(f, "   count      prev        time\n");
+  for (i = 0; OnigOpInfo[i].opcode >= 0; i++) {
+    fprintf(f, "%8d: %8d: %10lu: %s\n",
+	    OpCounter[i], OpPrevCounter[i], OpTime[i], OnigOpInfo[i].name);
+  }
+  fprintf(f, "\nmax stack depth: %d\n", MaxStackDepth);
+}
+
+# define STACK_INC do {\
+  stk++;\
+  if (stk - stk_base > MaxStackDepth) \
+    MaxStackDepth = stk - stk_base;\
+} while(0)
+
+#else /* ONIG_DEBUG_STATISTICS */
+# define STACK_INC     stk++
+
+# define MOP_IN(opcode)
+# define MOP_OUT
+#endif /* ONIG_DEBUG_STATISTICS */
+
+
+#ifdef ONIG_DEBUG_MATCH
+static char *
+stack_type_str(int stack_type)
+{
+  switch (stack_type) {
+    case STK_ALT:		return "Alt   ";
+    case STK_LOOK_BEHIND_NOT:	return "LBNot ";
+    case STK_POS_NOT:		return "PosNot";
+    case STK_MEM_START:		return "MemS  ";
+    case STK_MEM_END:		return "MemE  ";
+    case STK_REPEAT_INC:	return "RepInc";
+    case STK_STATE_CHECK_MARK:	return "StChMk";
+    case STK_NULL_CHECK_START:	return "NulChS";
+    case STK_NULL_CHECK_END:	return "NulChE";
+    case STK_MEM_END_MARK:	return "MemEMk";
+    case STK_POS:		return "Pos   ";
+    case STK_STOP_BT:		return "StopBt";
+    case STK_REPEAT:		return "Rep   ";
+    case STK_CALL_FRAME:	return "Call  ";
+    case STK_RETURN:		return "Ret   ";
+    case STK_VOID:		return "Void  ";
+    case STK_ABSENT_POS:	return "AbsPos";
+    case STK_ABSENT:		return "Absent";
+    default:			return "      ";
+  }
+}
+#endif
+
+/* match data(str - end) from position (sstart). */
+/* if sstart == str then set sprev to NULL. */
+static OnigPosition
+match_at(regex_t* reg, const UChar* str, const UChar* end,
+#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
+	 const UChar* right_range,
+#endif
+	 const UChar* sstart, UChar* sprev, OnigMatchArg* msa)
+{
+  static const UChar FinishCode[] = { OP_FINISH };
+
+  int i, num_mem, pop_level;
+  ptrdiff_t n, best_len;
+  LengthType tlen, tlen2;
+  MemNumType mem;
+  RelAddrType addr;
+  OnigOptionType option = reg->options;
+  OnigEncoding encode = reg->enc;
+  OnigCaseFoldType case_fold_flag = reg->case_fold_flag;
+  UChar *s, *q, *sbegin;
+  UChar *p = reg->p;
+  UChar *pkeep;
+  char *alloca_base;
+  char *xmalloc_base = NULL;
+  OnigStackType *stk_alloc, *stk_base, *stk, *stk_end;
+  OnigStackType *stkp; /* used as any purpose. */
+  OnigStackIndex si;
+  OnigStackIndex *repeat_stk;
+  OnigStackIndex *mem_start_stk, *mem_end_stk;
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+  int scv;
+  unsigned char* state_check_buff = msa->state_check_buff;
+  int num_comb_exp_check = reg->num_comb_exp_check;
+#endif
+
+#if USE_TOKEN_THREADED_VM
+# define OP_OFFSET  1
+# define VM_LOOP JUMP;
+# define VM_LOOP_END
+# define CASE(x) L_##x: sbegin = s; OPCODE_EXEC_HOOK;
+# define DEFAULT L_DEFAULT:
+# define NEXT sprev = sbegin; JUMP
+# define JUMP goto *oplabels[*p++]
+
+  static const void *oplabels[] = {
+    &&L_OP_FINISH,               /* matching process terminator (no more alternative) */
+    &&L_OP_END,                  /* pattern code terminator (success end) */
+
+    &&L_OP_EXACT1,               /* single byte, N = 1 */
+    &&L_OP_EXACT2,               /* single byte, N = 2 */
+    &&L_OP_EXACT3,               /* single byte, N = 3 */
+    &&L_OP_EXACT4,               /* single byte, N = 4 */
+    &&L_OP_EXACT5,               /* single byte, N = 5 */
+    &&L_OP_EXACTN,               /* single byte */
+    &&L_OP_EXACTMB2N1,           /* mb-length = 2 N = 1 */
+    &&L_OP_EXACTMB2N2,           /* mb-length = 2 N = 2 */
+    &&L_OP_EXACTMB2N3,           /* mb-length = 2 N = 3 */
+    &&L_OP_EXACTMB2N,            /* mb-length = 2 */
+    &&L_OP_EXACTMB3N,            /* mb-length = 3 */
+    &&L_OP_EXACTMBN,             /* other length */
+
+    &&L_OP_EXACT1_IC,            /* single byte, N = 1, ignore case */
+    &&L_OP_EXACTN_IC,            /* single byte,        ignore case */
+
+    &&L_OP_CCLASS,
+    &&L_OP_CCLASS_MB,
+    &&L_OP_CCLASS_MIX,
+    &&L_OP_CCLASS_NOT,
+    &&L_OP_CCLASS_MB_NOT,
+    &&L_OP_CCLASS_MIX_NOT,
+
+    &&L_OP_ANYCHAR,                 /* "."  */
+    &&L_OP_ANYCHAR_ML,              /* "."  multi-line */
+    &&L_OP_ANYCHAR_STAR,            /* ".*" */
+    &&L_OP_ANYCHAR_ML_STAR,         /* ".*" multi-line */
+    &&L_OP_ANYCHAR_STAR_PEEK_NEXT,
+    &&L_OP_ANYCHAR_ML_STAR_PEEK_NEXT,
+
+    &&L_OP_WORD,
+    &&L_OP_NOT_WORD,
+    &&L_OP_WORD_BOUND,
+    &&L_OP_NOT_WORD_BOUND,
+# ifdef USE_WORD_BEGIN_END
+    &&L_OP_WORD_BEGIN,
+    &&L_OP_WORD_END,
+# else
+    &&L_DEFAULT,
+    &&L_DEFAULT,
+# endif
+    &&L_OP_ASCII_WORD,
+    &&L_OP_NOT_ASCII_WORD,
+    &&L_OP_ASCII_WORD_BOUND,
+    &&L_OP_NOT_ASCII_WORD_BOUND,
+# ifdef USE_WORD_BEGIN_END
+    &&L_OP_ASCII_WORD_BEGIN,
+    &&L_OP_ASCII_WORD_END,
+# else
+    &&L_DEFAULT,
+    &&L_DEFAULT,
+# endif
+
+    &&L_OP_BEGIN_BUF,
+    &&L_OP_END_BUF,
+    &&L_OP_BEGIN_LINE,
+    &&L_OP_END_LINE,
+    &&L_OP_SEMI_END_BUF,
+    &&L_OP_BEGIN_POSITION,
+
+    &&L_OP_BACKREF1,
+    &&L_OP_BACKREF2,
+    &&L_OP_BACKREFN,
+    &&L_OP_BACKREFN_IC,
+    &&L_OP_BACKREF_MULTI,
+    &&L_OP_BACKREF_MULTI_IC,
+# ifdef USE_BACKREF_WITH_LEVEL
+    &&L_OP_BACKREF_WITH_LEVEL,   /* \k<xxx+n>, \k<xxx-n> */
+# else
+    &&L_DEFAULT,
+# endif
+    &&L_OP_MEMORY_START,
+    &&L_OP_MEMORY_START_PUSH,    /* push back-tracker to stack */
+    &&L_OP_MEMORY_END_PUSH,      /* push back-tracker to stack */
+# ifdef USE_SUBEXP_CALL
+    &&L_OP_MEMORY_END_PUSH_REC,  /* push back-tracker to stack */
+# else
+    &&L_DEFAULT,
+# endif
+    &&L_OP_MEMORY_END,
+# ifdef USE_SUBEXP_CALL
+    &&L_OP_MEMORY_END_REC,       /* push marker to stack */
+# else
+    &&L_DEFAULT,
+# endif
+
+    &&L_OP_KEEP,
+
+    &&L_OP_FAIL,                 /* pop stack and move */
+    &&L_OP_JUMP,
+    &&L_OP_PUSH,
+    &&L_OP_POP,
+# ifdef USE_OP_PUSH_OR_JUMP_EXACT
+    &&L_OP_PUSH_OR_JUMP_EXACT1,  /* if match exact then push, else jump. */
+# else
+    &&L_DEFAULT,
+# endif
+    &&L_OP_PUSH_IF_PEEK_NEXT,    /* if match exact then push, else none. */
+    &&L_OP_REPEAT,               /* {n,m} */
+    &&L_OP_REPEAT_NG,            /* {n,m}? (non greedy) */
+    &&L_OP_REPEAT_INC,
+    &&L_OP_REPEAT_INC_NG,        /* non greedy */
+    &&L_OP_REPEAT_INC_SG,        /* search and get in stack */
+    &&L_OP_REPEAT_INC_NG_SG,     /* search and get in stack (non greedy) */
+    &&L_OP_NULL_CHECK_START,     /* null loop checker start */
+    &&L_OP_NULL_CHECK_END,       /* null loop checker end   */
+# ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
+    &&L_OP_NULL_CHECK_END_MEMST, /* null loop checker end (with capture status) */
+# else
+    &&L_DEFAULT,
+# endif
+# ifdef USE_SUBEXP_CALL
+    &&L_OP_NULL_CHECK_END_MEMST_PUSH, /* with capture status and push check-end */
+# else
+    &&L_DEFAULT,
+# endif
+
+    &&L_OP_PUSH_POS,             /* (?=...)  start */
+    &&L_OP_POP_POS,              /* (?=...)  end   */
+    &&L_OP_PUSH_POS_NOT,         /* (?!...)  start */
+    &&L_OP_FAIL_POS,             /* (?!...)  end   */
+    &&L_OP_PUSH_STOP_BT,         /* (?>...)  start */
+    &&L_OP_POP_STOP_BT,          /* (?>...)  end   */
+    &&L_OP_LOOK_BEHIND,          /* (?<=...) start (no needs end opcode) */
+    &&L_OP_PUSH_LOOK_BEHIND_NOT, /* (?<!...) start */
+    &&L_OP_FAIL_LOOK_BEHIND_NOT, /* (?<!...) end   */
+    &&L_OP_PUSH_ABSENT_POS,      /* (?~...)  start */
+    &&L_OP_ABSENT,               /* (?~...)  start of inner loop */
+    &&L_OP_ABSENT_END,           /* (?~...)  end   */
+
+# ifdef USE_SUBEXP_CALL
+    &&L_OP_CALL,                 /* \g<name> */
+    &&L_OP_RETURN,
+# else
+    &&L_DEFAULT,
+    &&L_DEFAULT,
+# endif
+    &&L_OP_CONDITION,
+
+# ifdef USE_COMBINATION_EXPLOSION_CHECK
+    &&L_OP_STATE_CHECK_PUSH,         /* combination explosion check and push */
+    &&L_OP_STATE_CHECK_PUSH_OR_JUMP, /* check ok -> push, else jump  */
+    &&L_OP_STATE_CHECK,              /* check only */
+# else
+    &&L_DEFAULT,
+    &&L_DEFAULT,
+    &&L_DEFAULT,
+# endif
+# ifdef USE_COMBINATION_EXPLOSION_CHECK
+    &&L_OP_STATE_CHECK_ANYCHAR_STAR,
+    &&L_OP_STATE_CHECK_ANYCHAR_ML_STAR,
+# else
+    &&L_DEFAULT,
+    &&L_DEFAULT,
+# endif
+    /* no need: IS_DYNAMIC_OPTION() == 0 */
+# if 0   /* no need: IS_DYNAMIC_OPTION() == 0 */
+    &&L_OP_SET_OPTION_PUSH,    /* set option and push recover option */
+    &&L_OP_SET_OPTION          /* set option */
+# else
+    &&L_DEFAULT,
+    &&L_DEFAULT
+# endif
+  };
+#else /* USE_TOKEN_THREADED_VM */
+
+# define OP_OFFSET  0
+# define VM_LOOP                                \
+  while (1) {                                   \
+  OPCODE_EXEC_HOOK;                             \
+  sbegin = s;                                   \
+  switch (*p++) {
+# define VM_LOOP_END } sprev = sbegin; }
+# define CASE(x) case x:
+# define DEFAULT default:
+# define NEXT break
+# define JUMP continue; break
+#endif /* USE_TOKEN_THREADED_VM */
+
+
+#ifdef USE_SUBEXP_CALL
+/* Stack #0 is used to store the pattern itself and used for (?R), \g<0>,
+   etc. Additional space is required. */
+# define ADD_NUMMEM 1
+#else
+/* Stack #0 not is used. */
+# define ADD_NUMMEM 0
+#endif
+
+  n = reg->num_repeat + (reg->num_mem + ADD_NUMMEM) * 2;
+
+  STACK_INIT(alloca_base, xmalloc_base, n, INIT_MATCH_STACK_SIZE);
+  pop_level = reg->stack_pop_level;
+  num_mem = reg->num_mem;
+  repeat_stk = (OnigStackIndex* )alloca_base;
+
+  mem_start_stk = (OnigStackIndex* )(repeat_stk + reg->num_repeat);
+  mem_end_stk   = mem_start_stk + (num_mem + ADD_NUMMEM);
+  {
+    OnigStackIndex *pp = mem_start_stk;
+    for (; pp < repeat_stk + n; pp += 2) {
+      pp[0] = INVALID_STACK_INDEX;
+      pp[1] = INVALID_STACK_INDEX;
+    }
+  }
+#ifndef USE_SUBEXP_CALL
+  mem_start_stk--; /* for index start from 1,
+		      mem_start_stk[1]..mem_start_stk[num_mem] */
+  mem_end_stk--;   /* for index start from 1,
+		      mem_end_stk[1]..mem_end_stk[num_mem] */
+#endif
+
+#ifdef ONIG_DEBUG_MATCH
+  fprintf(stderr, "match_at: str: %"PRIuPTR" (%p), end: %"PRIuPTR" (%p), start: %"PRIuPTR" (%p), sprev: %"PRIuPTR" (%p)\n",
+	  (uintptr_t )str, str, (uintptr_t )end, end, (uintptr_t )sstart, sstart, (uintptr_t )sprev, sprev);
+  fprintf(stderr, "size: %d, start offset: %d\n",
+	  (int )(end - str), (int )(sstart - str));
+  fprintf(stderr, "\n ofs> str                   stk:type   addr:opcode\n");
+#endif
+
+  STACK_PUSH_ENSURED(STK_ALT, (UChar* )FinishCode);  /* bottom stack */
+  best_len = ONIG_MISMATCH;
+  s = (UChar* )sstart;
+  pkeep = (UChar* )sstart;
+
+
+#ifdef ONIG_DEBUG_MATCH
+# define OPCODE_EXEC_HOOK                                               \
+    if (s) {                                                            \
+      UChar *op, *q, *bp, buf[50];                                      \
+      int len;                                                          \
+      op = p - OP_OFFSET;                                               \
+      fprintf(stderr, "%4"PRIdPTR"> \"", (*op == OP_FINISH) ? (ptrdiff_t )-1 : s - str); \
+      bp = buf;                                                         \
+      q = s;                                                            \
+      if (*op != OP_FINISH) {    /* s may not be a valid pointer if OP_FINISH. */ \
+	for (i = 0; i < 7 && q < end; i++) {                            \
+	  len = enclen(encode, q, end);                                 \
+	  while (len-- > 0) *bp++ = *q++;                               \
+	}                                                               \
+        if (q < end) { xmemcpy(bp, "...", 3); bp += 3; }                \
+      }                                                                 \
+      xmemcpy(bp, "\"", 1); bp += 1;                                    \
+      *bp = 0;                                                          \
+      fputs((char* )buf, stderr);                                       \
+      for (i = 0; i < 20 - (bp - buf); i++) fputc(' ', stderr);         \
+      fprintf(stderr, "%4"PRIdPTR":%s %4"PRIdPTR":",                    \
+	  stk - stk_base - 1,                                           \
+	  (stk > stk_base) ? stack_type_str(stk[-1].type) : "      ",   \
+	  (op == FinishCode) ? (ptrdiff_t )-1 : op - reg->p);           \
+      onig_print_compiled_byte_code(stderr, op, reg->p+reg->used, NULL, encode); \
+      fprintf(stderr, "\n");                                            \
+    }
+#else
+# define OPCODE_EXEC_HOOK ((void) 0)
+#endif
+
+
+  VM_LOOP {
+    CASE(OP_END)  MOP_IN(OP_END);
+      n = s - sstart;
+      if (n > best_len) {
+	OnigRegion* region;
+#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
+	if (IS_FIND_LONGEST(option)) {
+	  if (n > msa->best_len) {
+	    msa->best_len = n;
+	    msa->best_s   = (UChar* )sstart;
+	  }
+	  else
+	    goto end_best_len;
+	}
+#endif
+	best_len = n;
+	region = msa->region;
+	if (region) {
+	  region->beg[0] = ((pkeep > s) ? s : pkeep) - str;
+	  region->end[0] = s - str;
+	  for (i = 1; i <= num_mem; i++) {
+	    if (mem_end_stk[i] != INVALID_STACK_INDEX) {
+	      if (BIT_STATUS_AT(reg->bt_mem_start, i))
+		region->beg[i] = STACK_AT(mem_start_stk[i])->u.mem.pstr - str;
+	      else
+		region->beg[i] = (UChar* )((void* )mem_start_stk[i]) - str;
+
+	      region->end[i] = (BIT_STATUS_AT(reg->bt_mem_end, i)
+				? STACK_AT(mem_end_stk[i])->u.mem.pstr
+				: (UChar* )((void* )mem_end_stk[i])) - str;
+	    }
+	    else {
+	      region->beg[i] = region->end[i] = ONIG_REGION_NOTPOS;
+	    }
+	  }
+
+#ifdef USE_CAPTURE_HISTORY
+	  if (reg->capture_history != 0) {
+	    int r;
+	    OnigCaptureTreeNode* node;
+
+	    if (IS_NULL(region->history_root)) {
+	      region->history_root = node = history_node_new();
+	      CHECK_NULL_RETURN_MEMERR(node);
+	    }
+	    else {
+	      node = region->history_root;
+	      history_tree_clear(node);
+	    }
+
+	    node->group = 0;
+	    node->beg   = ((pkeep > s) ? s : pkeep) - str;
+	    node->end   = s - str;
+
+	    stkp = stk_base;
+	    r = make_capture_history_tree(region->history_root, &stkp,
+		stk, (UChar* )str, reg);
+	    if (r < 0) {
+	      best_len = r; /* error code */
+	      goto finish;
+	    }
+	  }
+#endif /* USE_CAPTURE_HISTORY */
+	} /* if (region) */
+      } /* n > best_len */
+
+#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
+    end_best_len:
+#endif
+      MOP_OUT;
+
+      if (IS_FIND_CONDITION(option)) {
+	if (IS_FIND_NOT_EMPTY(option) && s == sstart) {
+	  best_len = ONIG_MISMATCH;
+	  goto fail; /* for retry */
+	}
+	if (IS_FIND_LONGEST(option) && DATA_ENSURE_CHECK1) {
+	  goto fail; /* for retry */
+	}
+      }
+
+      /* default behavior: return first-matching result. */
+      goto finish;
+      NEXT;
+
+    CASE(OP_EXACT1)  MOP_IN(OP_EXACT1);
+      DATA_ENSURE(1);
+      if (*p != *s) goto fail;
+      p++; s++;
+      MOP_OUT;
+      NEXT;
+
+    CASE(OP_EXACT1_IC)  MOP_IN(OP_EXACT1_IC);
+      {
+	int len;
+	UChar *q, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
+
+	DATA_ENSURE(1);
+	len = ONIGENC_MBC_CASE_FOLD(encode,
+		    /* DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag), */
+		    case_fold_flag,
+		    &s, end, lowbuf);
+	DATA_ENSURE(0);
+	q = lowbuf;
+	while (len-- > 0) {
+	  if (*p != *q) {
+	    goto fail;
+	  }
+	  p++; q++;
+	}
+      }
+      MOP_OUT;
+      NEXT;
+
+    CASE(OP_EXACT2)  MOP_IN(OP_EXACT2);
+      DATA_ENSURE(2);
+      if (*p != *s) goto fail;
+      p++; s++;
+      if (*p != *s) goto fail;
+      sprev = s;
+      p++; s++;
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_EXACT3)  MOP_IN(OP_EXACT3);
+      DATA_ENSURE(3);
+      if (*p != *s) goto fail;
+      p++; s++;
+      if (*p != *s) goto fail;
+      p++; s++;
+      if (*p != *s) goto fail;
+      sprev = s;
+      p++; s++;
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_EXACT4)  MOP_IN(OP_EXACT4);
+      DATA_ENSURE(4);
+      if (*p != *s) goto fail;
+      p++; s++;
+      if (*p != *s) goto fail;
+      p++; s++;
+      if (*p != *s) goto fail;
+      p++; s++;
+      if (*p != *s) goto fail;
+      sprev = s;
+      p++; s++;
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_EXACT5)  MOP_IN(OP_EXACT5);
+      DATA_ENSURE(5);
+      if (*p != *s) goto fail;
+      p++; s++;
+      if (*p != *s) goto fail;
+      p++; s++;
+      if (*p != *s) goto fail;
+      p++; s++;
+      if (*p != *s) goto fail;
+      p++; s++;
+      if (*p != *s) goto fail;
+      sprev = s;
+      p++; s++;
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_EXACTN)  MOP_IN(OP_EXACTN);
+      GET_LENGTH_INC(tlen, p);
+      DATA_ENSURE(tlen);
+      while (tlen-- > 0) {
+	if (*p++ != *s++) goto fail;
+      }
+      sprev = s - 1;
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_EXACTN_IC)  MOP_IN(OP_EXACTN_IC);
+      {
+	int len;
+	UChar *q, *endp, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
+
+	GET_LENGTH_INC(tlen, p);
+	endp = p + tlen;
+
+	while (p < endp) {
+	  sprev = s;
+	  DATA_ENSURE(1);
+	  len = ONIGENC_MBC_CASE_FOLD(encode,
+		      /* DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag), */
+		      case_fold_flag,
+		      &s, end, lowbuf);
+	  DATA_ENSURE(0);
+	  q = lowbuf;
+	  while (len-- > 0) {
+	    if (*p != *q) goto fail;
+	    p++; q++;
+	  }
+	}
+      }
+
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_EXACTMB2N1)  MOP_IN(OP_EXACTMB2N1);
+      DATA_ENSURE(2);
+      if (*p != *s) goto fail;
+      p++; s++;
+      if (*p != *s) goto fail;
+      p++; s++;
+      MOP_OUT;
+      NEXT;
+
+    CASE(OP_EXACTMB2N2)  MOP_IN(OP_EXACTMB2N2);
+      DATA_ENSURE(4);
+      if (*p != *s) goto fail;
+      p++; s++;
+      if (*p != *s) goto fail;
+      p++; s++;
+      sprev = s;
+      if (*p != *s) goto fail;
+      p++; s++;
+      if (*p != *s) goto fail;
+      p++; s++;
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_EXACTMB2N3)  MOP_IN(OP_EXACTMB2N3);
+      DATA_ENSURE(6);
+      if (*p != *s) goto fail;
+      p++; s++;
+      if (*p != *s) goto fail;
+      p++; s++;
+      if (*p != *s) goto fail;
+      p++; s++;
+      if (*p != *s) goto fail;
+      p++; s++;
+      sprev = s;
+      if (*p != *s) goto fail;
+      p++; s++;
+      if (*p != *s) goto fail;
+      p++; s++;
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_EXACTMB2N)  MOP_IN(OP_EXACTMB2N);
+      GET_LENGTH_INC(tlen, p);
+      DATA_ENSURE(tlen * 2);
+      while (tlen-- > 0) {
+	if (*p != *s) goto fail;
+	p++; s++;
+	if (*p != *s) goto fail;
+	p++; s++;
+      }
+      sprev = s - 2;
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_EXACTMB3N)  MOP_IN(OP_EXACTMB3N);
+      GET_LENGTH_INC(tlen, p);
+      DATA_ENSURE(tlen * 3);
+      while (tlen-- > 0) {
+	if (*p != *s) goto fail;
+	p++; s++;
+	if (*p != *s) goto fail;
+	p++; s++;
+	if (*p != *s) goto fail;
+	p++; s++;
+      }
+      sprev = s - 3;
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_EXACTMBN)  MOP_IN(OP_EXACTMBN);
+      GET_LENGTH_INC(tlen,  p);  /* mb-len */
+      GET_LENGTH_INC(tlen2, p);  /* string len */
+      tlen2 *= tlen;
+      DATA_ENSURE(tlen2);
+      while (tlen2-- > 0) {
+	if (*p != *s) goto fail;
+	p++; s++;
+      }
+      sprev = s - tlen;
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_CCLASS)  MOP_IN(OP_CCLASS);
+      DATA_ENSURE(1);
+      if (BITSET_AT(((BitSetRef )p), *s) == 0) goto fail;
+      p += SIZE_BITSET;
+      s += enclen(encode, s, end);   /* OP_CCLASS can match mb-code. \D, \S */
+      MOP_OUT;
+      NEXT;
+
+    CASE(OP_CCLASS_MB)  MOP_IN(OP_CCLASS_MB);
+      if (! ONIGENC_IS_MBC_HEAD(encode, s, end)) goto fail;
+
+    cclass_mb:
+      GET_LENGTH_INC(tlen, p);
+      {
+	OnigCodePoint code;
+	UChar *ss;
+	int mb_len;
+
+	DATA_ENSURE(1);
+	mb_len = enclen(encode, s, end);
+	DATA_ENSURE(mb_len);
+	ss = s;
+	s += mb_len;
+	code = ONIGENC_MBC_TO_CODE(encode, ss, s);
+
+#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
+	if (! onig_is_in_code_range(p, code)) goto fail;
+#else
+	q = p;
+	ALIGNMENT_RIGHT(q);
+	if (! onig_is_in_code_range(q, code)) goto fail;
+#endif
+      }
+      p += tlen;
+      MOP_OUT;
+      NEXT;
+
+    CASE(OP_CCLASS_MIX)  MOP_IN(OP_CCLASS_MIX);
+      DATA_ENSURE(1);
+      if (ONIGENC_IS_MBC_HEAD(encode, s, end)) {
+	p += SIZE_BITSET;
+	goto cclass_mb;
+      }
+      else {
+	if (BITSET_AT(((BitSetRef )p), *s) == 0)
+	  goto fail;
+
+	p += SIZE_BITSET;
+	GET_LENGTH_INC(tlen, p);
+	p += tlen;
+	s++;
+      }
+      MOP_OUT;
+      NEXT;
+
+    CASE(OP_CCLASS_NOT)  MOP_IN(OP_CCLASS_NOT);
+      DATA_ENSURE(1);
+      if (BITSET_AT(((BitSetRef )p), *s) != 0) goto fail;
+      p += SIZE_BITSET;
+      s += enclen(encode, s, end);
+      MOP_OUT;
+      NEXT;
+
+    CASE(OP_CCLASS_MB_NOT)  MOP_IN(OP_CCLASS_MB_NOT);
+      DATA_ENSURE(1);
+      if (! ONIGENC_IS_MBC_HEAD(encode, s, end)) {
+	s++;
+	GET_LENGTH_INC(tlen, p);
+	p += tlen;
+	goto cc_mb_not_success;
+      }
+
+    cclass_mb_not:
+      GET_LENGTH_INC(tlen, p);
+      {
+	OnigCodePoint code;
+	UChar *ss;
+	int mb_len = enclen(encode, s, end);
+
+	if (! DATA_ENSURE_CHECK(mb_len)) {
+	  DATA_ENSURE(1);
+	  s = (UChar* )end;
+	  p += tlen;
+	  goto cc_mb_not_success;
+	}
+
+	ss = s;
+	s += mb_len;
+	code = ONIGENC_MBC_TO_CODE(encode, ss, s);
+
+#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
+	if (onig_is_in_code_range(p, code)) goto fail;
+#else
+	q = p;
+	ALIGNMENT_RIGHT(q);
+	if (onig_is_in_code_range(q, code)) goto fail;
+#endif
+      }
+      p += tlen;
+
+    cc_mb_not_success:
+      MOP_OUT;
+      NEXT;
+
+    CASE(OP_CCLASS_MIX_NOT)  MOP_IN(OP_CCLASS_MIX_NOT);
+      DATA_ENSURE(1);
+      if (ONIGENC_IS_MBC_HEAD(encode, s, end)) {
+	p += SIZE_BITSET;
+	goto cclass_mb_not;
+      }
+      else {
+	if (BITSET_AT(((BitSetRef )p), *s) != 0)
+	  goto fail;
+
+	p += SIZE_BITSET;
+	GET_LENGTH_INC(tlen, p);
+	p += tlen;
+	s++;
+      }
+      MOP_OUT;
+      NEXT;
+
+    CASE(OP_ANYCHAR)  MOP_IN(OP_ANYCHAR);
+      DATA_ENSURE(1);
+      n = enclen(encode, s, end);
+      DATA_ENSURE(n);
+      if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 0)) goto fail;
+      s += n;
+      MOP_OUT;
+      NEXT;
+
+    CASE(OP_ANYCHAR_ML)  MOP_IN(OP_ANYCHAR_ML);
+      DATA_ENSURE(1);
+      n = enclen(encode, s, end);
+      DATA_ENSURE(n);
+      s += n;
+      MOP_OUT;
+      NEXT;
+
+    CASE(OP_ANYCHAR_STAR)  MOP_IN(OP_ANYCHAR_STAR);
+      while (DATA_ENSURE_CHECK1) {
+	STACK_PUSH_ALT(p, s, sprev, pkeep);
+	n = enclen(encode, s, end);
+	DATA_ENSURE(n);
+	if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 0))  goto fail;
+	sprev = s;
+	s += n;
+      }
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_ANYCHAR_ML_STAR)  MOP_IN(OP_ANYCHAR_ML_STAR);
+      while (DATA_ENSURE_CHECK1) {
+	STACK_PUSH_ALT(p, s, sprev, pkeep);
+	n = enclen(encode, s, end);
+	if (n > 1) {
+	  DATA_ENSURE(n);
+	  sprev = s;
+	  s += n;
+	}
+	else {
+	  sprev = s;
+	  s++;
+	}
+      }
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_ANYCHAR_STAR_PEEK_NEXT)  MOP_IN(OP_ANYCHAR_STAR_PEEK_NEXT);
+      while (DATA_ENSURE_CHECK1) {
+	if (*p == *s) {
+	  STACK_PUSH_ALT(p + 1, s, sprev, pkeep);
+	}
+	n = enclen(encode, s, end);
+	DATA_ENSURE(n);
+	if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 0))  goto fail;
+	sprev = s;
+	s += n;
+      }
+      p++;
+      MOP_OUT;
+      NEXT;
+
+    CASE(OP_ANYCHAR_ML_STAR_PEEK_NEXT)MOP_IN(OP_ANYCHAR_ML_STAR_PEEK_NEXT);
+      while (DATA_ENSURE_CHECK1) {
+	if (*p == *s) {
+	  STACK_PUSH_ALT(p + 1, s, sprev, pkeep);
+	}
+	n = enclen(encode, s, end);
+	if (n > 1) {
+	  DATA_ENSURE(n);
+	  sprev = s;
+	  s += n;
+	}
+	else {
+	  sprev = s;
+	  s++;
+	}
+      }
+      p++;
+      MOP_OUT;
+      NEXT;
+
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+    CASE(OP_STATE_CHECK_ANYCHAR_STAR)  MOP_IN(OP_STATE_CHECK_ANYCHAR_STAR);
+      GET_STATE_CHECK_NUM_INC(mem, p);
+      while (DATA_ENSURE_CHECK1) {
+	STATE_CHECK_VAL(scv, mem);
+	if (scv) goto fail;
+
+	STACK_PUSH_ALT_WITH_STATE_CHECK(p, s, sprev, mem, pkeep);
+	n = enclen(encode, s, end);
+	DATA_ENSURE(n);
+	if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 0))  goto fail;
+	sprev = s;
+	s += n;
+      }
+      MOP_OUT;
+      NEXT;
+
+    CASE(OP_STATE_CHECK_ANYCHAR_ML_STAR)
+      MOP_IN(OP_STATE_CHECK_ANYCHAR_ML_STAR);
+
+      GET_STATE_CHECK_NUM_INC(mem, p);
+      while (DATA_ENSURE_CHECK1) {
+	STATE_CHECK_VAL(scv, mem);
+	if (scv) goto fail;
+
+	STACK_PUSH_ALT_WITH_STATE_CHECK(p, s, sprev, mem, pkeep);
+	n = enclen(encode, s, end);
+	if (n > 1) {
+	  DATA_ENSURE(n);
+	  sprev = s;
+	  s += n;
+	}
+	else {
+	  sprev = s;
+	  s++;
+	}
+      }
+      MOP_OUT;
+      NEXT;
+#endif /* USE_COMBINATION_EXPLOSION_CHECK */
+
+    CASE(OP_WORD)  MOP_IN(OP_WORD);
+      DATA_ENSURE(1);
+      if (! ONIGENC_IS_MBC_WORD(encode, s, end))
+	goto fail;
+
+      s += enclen(encode, s, end);
+      MOP_OUT;
+      NEXT;
+
+    CASE(OP_ASCII_WORD)  MOP_IN(OP_ASCII_WORD);
+      DATA_ENSURE(1);
+      if (! ONIGENC_IS_MBC_ASCII_WORD(encode, s, end))
+	goto fail;
+
+      s += enclen(encode, s, end);
+      MOP_OUT;
+      NEXT;
+
+    CASE(OP_NOT_WORD)  MOP_IN(OP_NOT_WORD);
+      DATA_ENSURE(1);
+      if (ONIGENC_IS_MBC_WORD(encode, s, end))
+	goto fail;
+
+      s += enclen(encode, s, end);
+      MOP_OUT;
+      NEXT;
+
+    CASE(OP_NOT_ASCII_WORD)  MOP_IN(OP_NOT_ASCII_WORD);
+      DATA_ENSURE(1);
+      if (ONIGENC_IS_MBC_ASCII_WORD(encode, s, end))
+	goto fail;
+
+      s += enclen(encode, s, end);
+      MOP_OUT;
+      NEXT;
+
+    CASE(OP_WORD_BOUND)  MOP_IN(OP_WORD_BOUND);
+      if (ON_STR_BEGIN(s)) {
+	DATA_ENSURE(1);
+	if (! ONIGENC_IS_MBC_WORD(encode, s, end))
+	  goto fail;
+      }
+      else if (ON_STR_END(s)) {
+	if (! ONIGENC_IS_MBC_WORD(encode, sprev, end))
+	  goto fail;
+      }
+      else {
+	if (ONIGENC_IS_MBC_WORD(encode, s, end)
+	    == ONIGENC_IS_MBC_WORD(encode, sprev, end))
+	  goto fail;
+      }
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_ASCII_WORD_BOUND)  MOP_IN(OP_ASCII_WORD_BOUND);
+      if (ON_STR_BEGIN(s)) {
+	DATA_ENSURE(1);
+	if (! ONIGENC_IS_MBC_ASCII_WORD(encode, s, end))
+	  goto fail;
+      }
+      else if (ON_STR_END(s)) {
+	if (! ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end))
+	  goto fail;
+      }
+      else {
+	if (ONIGENC_IS_MBC_ASCII_WORD(encode, s, end)
+	    == ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end))
+	  goto fail;
+      }
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_NOT_WORD_BOUND)  MOP_IN(OP_NOT_WORD_BOUND);
+      if (ON_STR_BEGIN(s)) {
+	if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_WORD(encode, s, end))
+	  goto fail;
+      }
+      else if (ON_STR_END(s)) {
+	if (ONIGENC_IS_MBC_WORD(encode, sprev, end))
+	  goto fail;
+      }
+      else {
+	if (ONIGENC_IS_MBC_WORD(encode, s, end)
+	    != ONIGENC_IS_MBC_WORD(encode, sprev, end))
+	  goto fail;
+      }
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_NOT_ASCII_WORD_BOUND)  MOP_IN(OP_NOT_ASCII_WORD_BOUND);
+      if (ON_STR_BEGIN(s)) {
+	if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_ASCII_WORD(encode, s, end))
+	  goto fail;
+      }
+      else if (ON_STR_END(s)) {
+	if (ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end))
+	  goto fail;
+      }
+      else {
+	if (ONIGENC_IS_MBC_ASCII_WORD(encode, s, end)
+	    != ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end))
+	  goto fail;
+      }
+      MOP_OUT;
+      JUMP;
+
+#ifdef USE_WORD_BEGIN_END
+    CASE(OP_WORD_BEGIN)  MOP_IN(OP_WORD_BEGIN);
+      if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_WORD(encode, s, end)) {
+	if (ON_STR_BEGIN(s) || !ONIGENC_IS_MBC_WORD(encode, sprev, end)) {
+	  MOP_OUT;
+	  JUMP;
+	}
+      }
+      goto fail;
+      NEXT;
+
+    CASE(OP_ASCII_WORD_BEGIN)  MOP_IN(OP_ASCII_WORD_BEGIN);
+      if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_ASCII_WORD(encode, s, end)) {
+	if (ON_STR_BEGIN(s) || !ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end)) {
+	  MOP_OUT;
+	  JUMP;
+	}
+      }
+      goto fail;
+      NEXT;
+
+    CASE(OP_WORD_END)  MOP_IN(OP_WORD_END);
+      if (!ON_STR_BEGIN(s) && ONIGENC_IS_MBC_WORD(encode, sprev, end)) {
+	if (ON_STR_END(s) || !ONIGENC_IS_MBC_WORD(encode, s, end)) {
+	  MOP_OUT;
+	  JUMP;
+	}
+      }
+      goto fail;
+      NEXT;
+
+    CASE(OP_ASCII_WORD_END)  MOP_IN(OP_ASCII_WORD_END);
+      if (!ON_STR_BEGIN(s) && ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end)) {
+	if (ON_STR_END(s) || !ONIGENC_IS_MBC_ASCII_WORD(encode, s, end)) {
+	  MOP_OUT;
+	  JUMP;
+	}
+      }
+      goto fail;
+      NEXT;
+#endif
+
+    CASE(OP_BEGIN_BUF)  MOP_IN(OP_BEGIN_BUF);
+      if (! ON_STR_BEGIN(s)) goto fail;
+      if (IS_NOTBOS(msa->options)) goto fail;
+
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_END_BUF)  MOP_IN(OP_END_BUF);
+      if (! ON_STR_END(s)) goto fail;
+      if (IS_NOTEOS(msa->options)) goto fail;
+
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_BEGIN_LINE)  MOP_IN(OP_BEGIN_LINE);
+      if (ON_STR_BEGIN(s)) {
+	if (IS_NOTBOL(msa->options)) goto fail;
+	MOP_OUT;
+	JUMP;
+      }
+      else if (ONIGENC_IS_MBC_NEWLINE(encode, sprev, end)
+#ifdef USE_CRNL_AS_LINE_TERMINATOR
+		&& !(IS_NEWLINE_CRLF(option)
+		     && ONIGENC_IS_MBC_CRNL(encode, sprev, end))
+#endif
+		&& !ON_STR_END(s)) {
+	MOP_OUT;
+	JUMP;
+      }
+      goto fail;
+      NEXT;
+
+    CASE(OP_END_LINE)  MOP_IN(OP_END_LINE);
+      if (ON_STR_END(s)) {
+#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
+	if (IS_EMPTY_STR || !ONIGENC_IS_MBC_NEWLINE_EX(encode, sprev, str, end, option, 1)) {
+#endif
+	  if (IS_NOTEOL(msa->options)) goto fail;
+	  MOP_OUT;
+	  JUMP;
+#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
+	}
+#endif
+      }
+      else if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 1)) {
+	MOP_OUT;
+	JUMP;
+      }
+      goto fail;
+      NEXT;
+
+    CASE(OP_SEMI_END_BUF)  MOP_IN(OP_SEMI_END_BUF);
+      if (ON_STR_END(s)) {
+#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
+	if (IS_EMPTY_STR || !ONIGENC_IS_MBC_NEWLINE_EX(encode, sprev, str, end, option, 1)) {
+#endif
+	  if (IS_NOTEOL(msa->options)) goto fail;
+	  MOP_OUT;
+	  JUMP;
+#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
+	}
+#endif
+      }
+      else if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 1)) {
+	UChar* ss = s + enclen(encode, s, end);
+	if (ON_STR_END(ss)) {
+	  MOP_OUT;
+	  JUMP;
+	}
+#ifdef USE_CRNL_AS_LINE_TERMINATOR
+	else if (IS_NEWLINE_CRLF(option)
+	    && ONIGENC_IS_MBC_CRNL(encode, s, end)) {
+	  ss += enclen(encode, ss, end);
+	  if (ON_STR_END(ss)) {
+	    MOP_OUT;
+	    JUMP;
+	  }
+	}
+#endif
+      }
+      goto fail;
+      NEXT;
+
+    CASE(OP_BEGIN_POSITION)  MOP_IN(OP_BEGIN_POSITION);
+      if (s != msa->gpos)
+	goto fail;
+
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_MEMORY_START_PUSH)  MOP_IN(OP_MEMORY_START_PUSH);
+      GET_MEMNUM_INC(mem, p);
+      STACK_PUSH_MEM_START(mem, s);
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_MEMORY_START)  MOP_IN(OP_MEMORY_START);
+      GET_MEMNUM_INC(mem, p);
+      mem_start_stk[mem] = (OnigStackIndex )((void* )s);
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_MEMORY_END_PUSH)  MOP_IN(OP_MEMORY_END_PUSH);
+      GET_MEMNUM_INC(mem, p);
+      STACK_PUSH_MEM_END(mem, s);
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_MEMORY_END)  MOP_IN(OP_MEMORY_END);
+      GET_MEMNUM_INC(mem, p);
+      mem_end_stk[mem] = (OnigStackIndex )((void* )s);
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_KEEP)  MOP_IN(OP_KEEP);
+      pkeep = s;
+      MOP_OUT;
+      JUMP;
+
+#ifdef USE_SUBEXP_CALL
+    CASE(OP_MEMORY_END_PUSH_REC)  MOP_IN(OP_MEMORY_END_PUSH_REC);
+      GET_MEMNUM_INC(mem, p);
+      STACK_GET_MEM_START(mem, stkp); /* should be before push mem-end. */
+      STACK_PUSH_MEM_END(mem, s);
+      mem_start_stk[mem] = GET_STACK_INDEX(stkp);
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_MEMORY_END_REC)  MOP_IN(OP_MEMORY_END_REC);
+      GET_MEMNUM_INC(mem, p);
+      mem_end_stk[mem] = (OnigStackIndex )((void* )s);
+      STACK_GET_MEM_START(mem, stkp);
+
+      if (BIT_STATUS_AT(reg->bt_mem_start, mem))
+	mem_start_stk[mem] = GET_STACK_INDEX(stkp);
+      else
+	mem_start_stk[mem] = (OnigStackIndex )((void* )stkp->u.mem.pstr);
+
+      STACK_PUSH_MEM_END_MARK(mem);
+      MOP_OUT;
+      JUMP;
+#endif
+
+    CASE(OP_BACKREF1)  MOP_IN(OP_BACKREF1);
+      mem = 1;
+      goto backref;
+      NEXT;
+
+    CASE(OP_BACKREF2)  MOP_IN(OP_BACKREF2);
+      mem = 2;
+      goto backref;
+      NEXT;
+
+    CASE(OP_BACKREFN)  MOP_IN(OP_BACKREFN);
+      GET_MEMNUM_INC(mem, p);
+    backref:
+      {
+	int len;
+	UChar *pstart, *pend;
+
+	/* if you want to remove following line,
+	   you should check in parse and compile time. */
+	if (mem > num_mem) goto fail;
+	if (mem_end_stk[mem]   == INVALID_STACK_INDEX) goto fail;
+	if (mem_start_stk[mem] == INVALID_STACK_INDEX) goto fail;
+
+	if (BIT_STATUS_AT(reg->bt_mem_start, mem))
+	  pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;
+	else
+	  pstart = (UChar* )((void* )mem_start_stk[mem]);
+
+	pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)
+		? STACK_AT(mem_end_stk[mem])->u.mem.pstr
+		: (UChar* )((void* )mem_end_stk[mem]));
+	n = pend - pstart;
+	DATA_ENSURE(n);
+	sprev = s;
+	STRING_CMP(pstart, s, n);
+	while (sprev + (len = enclen(encode, sprev, end)) < s)
+	  sprev += len;
+
+	MOP_OUT;
+	JUMP;
+      }
+
+    CASE(OP_BACKREFN_IC)  MOP_IN(OP_BACKREFN_IC);
+      GET_MEMNUM_INC(mem, p);
+      {
+	int len;
+	UChar *pstart, *pend;
+
+	/* if you want to remove following line,
+	   you should check in parse and compile time. */
+	if (mem > num_mem) goto fail;
+	if (mem_end_stk[mem]   == INVALID_STACK_INDEX) goto fail;
+	if (mem_start_stk[mem] == INVALID_STACK_INDEX) goto fail;
+
+	if (BIT_STATUS_AT(reg->bt_mem_start, mem))
+	  pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;
+	else
+	  pstart = (UChar* )((void* )mem_start_stk[mem]);
+
+	pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)
+		? STACK_AT(mem_end_stk[mem])->u.mem.pstr
+		: (UChar* )((void* )mem_end_stk[mem]));
+	n = pend - pstart;
+	DATA_ENSURE(n);
+	sprev = s;
+	STRING_CMP_IC(case_fold_flag, pstart, &s, (int)n, end);
+	while (sprev + (len = enclen(encode, sprev, end)) < s)
+	  sprev += len;
+
+	MOP_OUT;
+	JUMP;
+      }
+      NEXT;
+
+    CASE(OP_BACKREF_MULTI)  MOP_IN(OP_BACKREF_MULTI);
+      {
+	int len, is_fail;
+	UChar *pstart, *pend, *swork;
+
+	GET_LENGTH_INC(tlen, p);
+	for (i = 0; i < tlen; i++) {
+	  GET_MEMNUM_INC(mem, p);
+
+	  if (mem_end_stk[mem]   == INVALID_STACK_INDEX) continue;
+	  if (mem_start_stk[mem] == INVALID_STACK_INDEX) continue;
+
+	  if (BIT_STATUS_AT(reg->bt_mem_start, mem))
+	    pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;
+	  else
+	    pstart = (UChar* )((void* )mem_start_stk[mem]);
+
+	  pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)
+		  ? STACK_AT(mem_end_stk[mem])->u.mem.pstr
+		  : (UChar* )((void* )mem_end_stk[mem]));
+	  n = pend - pstart;
+	  DATA_ENSURE(n);
+	  sprev = s;
+	  swork = s;
+	  STRING_CMP_VALUE(pstart, swork, n, is_fail);
+	  if (is_fail) continue;
+	  s = swork;
+	  while (sprev + (len = enclen(encode, sprev, end)) < s)
+	    sprev += len;
+
+	  p += (SIZE_MEMNUM * (tlen - i - 1));
+	  break; /* success */
+	}
+	if (i == tlen) goto fail;
+	MOP_OUT;
+	JUMP;
+      }
+      NEXT;
+
+    CASE(OP_BACKREF_MULTI_IC)  MOP_IN(OP_BACKREF_MULTI_IC);
+      {
+	int len, is_fail;
+	UChar *pstart, *pend, *swork;
+
+	GET_LENGTH_INC(tlen, p);
+	for (i = 0; i < tlen; i++) {
+	  GET_MEMNUM_INC(mem, p);
+
+	  if (mem_end_stk[mem]   == INVALID_STACK_INDEX) continue;
+	  if (mem_start_stk[mem] == INVALID_STACK_INDEX) continue;
+
+	  if (BIT_STATUS_AT(reg->bt_mem_start, mem))
+	    pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;
+	  else
+	    pstart = (UChar* )((void* )mem_start_stk[mem]);
+
+	  pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)
+		  ? STACK_AT(mem_end_stk[mem])->u.mem.pstr
+		  : (UChar* )((void* )mem_end_stk[mem]));
+	  n = pend - pstart;
+	  DATA_ENSURE(n);
+	  sprev = s;
+	  swork = s;
+	  STRING_CMP_VALUE_IC(case_fold_flag, pstart, &swork, n, end, is_fail);
+	  if (is_fail) continue;
+	  s = swork;
+	  while (sprev + (len = enclen(encode, sprev, end)) < s)
+	    sprev += len;
+
+	  p += (SIZE_MEMNUM * (tlen - i - 1));
+	  break; /* success */
+	}
+	if (i == tlen) goto fail;
+	MOP_OUT;
+	JUMP;
+      }
+
+#ifdef USE_BACKREF_WITH_LEVEL
+    CASE(OP_BACKREF_WITH_LEVEL)
+      {
+	int len;
+	OnigOptionType ic;
+	LengthType level;
+
+	GET_OPTION_INC(ic,    p);
+	GET_LENGTH_INC(level, p);
+	GET_LENGTH_INC(tlen,  p);
+
+	sprev = s;
+	if (backref_match_at_nested_level(reg, stk, stk_base, ic,
+		  case_fold_flag, (int )level, (int )tlen, p, &s, end)) {
+	  while (sprev + (len = enclen(encode, sprev, end)) < s)
+	    sprev += len;
+
+	  p += (SIZE_MEMNUM * tlen);
+	}
+	else
+	  goto fail;
+
+	MOP_OUT;
+	JUMP;
+      }
+
+#endif
+
+#if 0   /* no need: IS_DYNAMIC_OPTION() == 0 */
+    CASE(OP_SET_OPTION_PUSH)  MOP_IN(OP_SET_OPTION_PUSH);
+      GET_OPTION_INC(option, p);
+      STACK_PUSH_ALT(p, s, sprev, pkeep);
+      p += SIZE_OP_SET_OPTION + SIZE_OP_FAIL;
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_SET_OPTION)  MOP_IN(OP_SET_OPTION);
+      GET_OPTION_INC(option, p);
+      MOP_OUT;
+      JUMP;
+#endif
+
+    CASE(OP_NULL_CHECK_START)  MOP_IN(OP_NULL_CHECK_START);
+      GET_MEMNUM_INC(mem, p);    /* mem: null check id */
+      STACK_PUSH_NULL_CHECK_START(mem, s);
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_NULL_CHECK_END)  MOP_IN(OP_NULL_CHECK_END);
+      {
+	int isnull;
+
+	GET_MEMNUM_INC(mem, p); /* mem: null check id */
+	STACK_NULL_CHECK(isnull, mem, s);
+	if (isnull) {
+#ifdef ONIG_DEBUG_MATCH
+	  fprintf(stderr, "NULL_CHECK_END: skip  id:%d, s:%"PRIuPTR" (%p)\n",
+		  (int )mem, (uintptr_t )s, s);
+#endif
+	null_check_found:
+	  /* empty loop founded, skip next instruction */
+	  switch (*p++) {
+	  case OP_JUMP:
+	  case OP_PUSH:
+	    p += SIZE_RELADDR;
+	    break;
+	  case OP_REPEAT_INC:
+	  case OP_REPEAT_INC_NG:
+	  case OP_REPEAT_INC_SG:
+	  case OP_REPEAT_INC_NG_SG:
+	    p += SIZE_MEMNUM;
+	    break;
+	  default:
+	    goto unexpected_bytecode_error;
+	    break;
+	  }
+	}
+      }
+      MOP_OUT;
+      JUMP;
+
+#ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
+    CASE(OP_NULL_CHECK_END_MEMST)  MOP_IN(OP_NULL_CHECK_END_MEMST);
+      {
+	int isnull;
+
+	GET_MEMNUM_INC(mem, p); /* mem: null check id */
+	STACK_NULL_CHECK_MEMST(isnull, mem, s, reg);
+	if (isnull) {
+# ifdef ONIG_DEBUG_MATCH
+	  fprintf(stderr, "NULL_CHECK_END_MEMST: skip  id:%d, s:%"PRIuPTR" (%p)\n",
+		  (int )mem, (uintptr_t )s, s);
+# endif
+	  if (isnull == -1) goto fail;
+	  goto null_check_found;
+	}
+      }
+      MOP_OUT;
+      JUMP;
+#endif
+
+#ifdef USE_SUBEXP_CALL
+    CASE(OP_NULL_CHECK_END_MEMST_PUSH)
+      MOP_IN(OP_NULL_CHECK_END_MEMST_PUSH);
+      {
+	int isnull;
+
+	GET_MEMNUM_INC(mem, p); /* mem: null check id */
+# ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
+	STACK_NULL_CHECK_MEMST_REC(isnull, mem, s, reg);
+# else
+	STACK_NULL_CHECK_REC(isnull, mem, s);
+# endif
+	if (isnull) {
+# ifdef ONIG_DEBUG_MATCH
+	  fprintf(stderr, "NULL_CHECK_END_MEMST_PUSH: skip  id:%d, s:%"PRIuPTR" (%p)\n",
+		  (int )mem, (uintptr_t )s, s);
+# endif
+	  if (isnull == -1) goto fail;
+	  goto null_check_found;
+	}
+	else {
+	  STACK_PUSH_NULL_CHECK_END(mem);
+	}
+      }
+      MOP_OUT;
+      JUMP;
+#endif
+
+    CASE(OP_JUMP)  MOP_IN(OP_JUMP);
+      GET_RELADDR_INC(addr, p);
+      p += addr;
+      MOP_OUT;
+      CHECK_INTERRUPT_IN_MATCH_AT;
+      JUMP;
+
+    CASE(OP_PUSH)  MOP_IN(OP_PUSH);
+      GET_RELADDR_INC(addr, p);
+      STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
+      MOP_OUT;
+      JUMP;
+
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+    CASE(OP_STATE_CHECK_PUSH)  MOP_IN(OP_STATE_CHECK_PUSH);
+      GET_STATE_CHECK_NUM_INC(mem, p);
+      STATE_CHECK_VAL(scv, mem);
+      if (scv) goto fail;
+
+      GET_RELADDR_INC(addr, p);
+      STACK_PUSH_ALT_WITH_STATE_CHECK(p + addr, s, sprev, mem, pkeep);
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_STATE_CHECK_PUSH_OR_JUMP)  MOP_IN(OP_STATE_CHECK_PUSH_OR_JUMP);
+      GET_STATE_CHECK_NUM_INC(mem, p);
+      GET_RELADDR_INC(addr, p);
+      STATE_CHECK_VAL(scv, mem);
+      if (scv) {
+	p += addr;
+      }
+      else {
+	STACK_PUSH_ALT_WITH_STATE_CHECK(p + addr, s, sprev, mem, pkeep);
+      }
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_STATE_CHECK)  MOP_IN(OP_STATE_CHECK);
+      GET_STATE_CHECK_NUM_INC(mem, p);
+      STATE_CHECK_VAL(scv, mem);
+      if (scv) goto fail;
+
+      STACK_PUSH_STATE_CHECK(s, mem);
+      MOP_OUT;
+      JUMP;
+#endif /* USE_COMBINATION_EXPLOSION_CHECK */
+
+    CASE(OP_POP)  MOP_IN(OP_POP);
+      STACK_POP_ONE;
+      MOP_OUT;
+      JUMP;
+
+#ifdef USE_OP_PUSH_OR_JUMP_EXACT
+    CASE(OP_PUSH_OR_JUMP_EXACT1)  MOP_IN(OP_PUSH_OR_JUMP_EXACT1);
+      GET_RELADDR_INC(addr, p);
+      if (*p == *s && DATA_ENSURE_CHECK1) {
+	p++;
+	STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
+	MOP_OUT;
+	JUMP;
+      }
+      p += (addr + 1);
+      MOP_OUT;
+      JUMP;
+#endif
+
+    CASE(OP_PUSH_IF_PEEK_NEXT)  MOP_IN(OP_PUSH_IF_PEEK_NEXT);
+      GET_RELADDR_INC(addr, p);
+      if (*p == *s) {
+	p++;
+	STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
+	MOP_OUT;
+	JUMP;
+      }
+      p++;
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_REPEAT)  MOP_IN(OP_REPEAT);
+      {
+	GET_MEMNUM_INC(mem, p);    /* mem: OP_REPEAT ID */
+	GET_RELADDR_INC(addr, p);
+
+	STACK_ENSURE(1);
+	repeat_stk[mem] = GET_STACK_INDEX(stk);
+	STACK_PUSH_REPEAT(mem, p);
+
+	if (reg->repeat_range[mem].lower == 0) {
+	  STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
+	}
+      }
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_REPEAT_NG)  MOP_IN(OP_REPEAT_NG);
+      {
+	GET_MEMNUM_INC(mem, p);    /* mem: OP_REPEAT ID */
+	GET_RELADDR_INC(addr, p);
+
+	STACK_ENSURE(1);
+	repeat_stk[mem] = GET_STACK_INDEX(stk);
+	STACK_PUSH_REPEAT(mem, p);
+
+	if (reg->repeat_range[mem].lower == 0) {
+	  STACK_PUSH_ALT(p, s, sprev, pkeep);
+	  p += addr;
+	}
+      }
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_REPEAT_INC)  MOP_IN(OP_REPEAT_INC);
+      GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
+      si = repeat_stk[mem];
+      stkp = STACK_AT(si);
+
+    repeat_inc:
+      stkp->u.repeat.count++;
+      if (stkp->u.repeat.count >= reg->repeat_range[mem].upper) {
+	/* end of repeat. Nothing to do. */
+      }
+      else if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) {
+	STACK_PUSH_ALT(p, s, sprev, pkeep);
+	p = STACK_AT(si)->u.repeat.pcode; /* Don't use stkp after PUSH. */
+      }
+      else {
+	p = stkp->u.repeat.pcode;
+      }
+      STACK_PUSH_REPEAT_INC(si);
+      MOP_OUT;
+      CHECK_INTERRUPT_IN_MATCH_AT;
+      JUMP;
+
+    CASE(OP_REPEAT_INC_SG)  MOP_IN(OP_REPEAT_INC_SG);
+      GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
+      STACK_GET_REPEAT(mem, stkp);
+      si = GET_STACK_INDEX(stkp);
+      goto repeat_inc;
+      NEXT;
+
+    CASE(OP_REPEAT_INC_NG)  MOP_IN(OP_REPEAT_INC_NG);
+      GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
+      si = repeat_stk[mem];
+      stkp = STACK_AT(si);
+
+    repeat_inc_ng:
+      stkp->u.repeat.count++;
+      if (stkp->u.repeat.count < reg->repeat_range[mem].upper) {
+	if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) {
+	  UChar* pcode = stkp->u.repeat.pcode;
+
+	  STACK_PUSH_REPEAT_INC(si);
+	  STACK_PUSH_ALT(pcode, s, sprev, pkeep);
+	}
+	else {
+	  p = stkp->u.repeat.pcode;
+	  STACK_PUSH_REPEAT_INC(si);
+	}
+      }
+      else if (stkp->u.repeat.count == reg->repeat_range[mem].upper) {
+	STACK_PUSH_REPEAT_INC(si);
+      }
+      MOP_OUT;
+      CHECK_INTERRUPT_IN_MATCH_AT;
+      JUMP;
+
+    CASE(OP_REPEAT_INC_NG_SG)  MOP_IN(OP_REPEAT_INC_NG_SG);
+      GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
+      STACK_GET_REPEAT(mem, stkp);
+      si = GET_STACK_INDEX(stkp);
+      goto repeat_inc_ng;
+      NEXT;
+
+    CASE(OP_PUSH_POS)  MOP_IN(OP_PUSH_POS);
+      STACK_PUSH_POS(s, sprev, pkeep);
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_POP_POS)  MOP_IN(OP_POP_POS);
+      {
+	STACK_POS_END(stkp);
+	s     = stkp->u.state.pstr;
+	sprev = stkp->u.state.pstr_prev;
+      }
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_PUSH_POS_NOT)  MOP_IN(OP_PUSH_POS_NOT);
+      GET_RELADDR_INC(addr, p);
+      STACK_PUSH_POS_NOT(p + addr, s, sprev, pkeep);
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_FAIL_POS)  MOP_IN(OP_FAIL_POS);
+      STACK_POP_TIL_POS_NOT;
+      goto fail;
+      NEXT;
+
+    CASE(OP_PUSH_STOP_BT)  MOP_IN(OP_PUSH_STOP_BT);
+      STACK_PUSH_STOP_BT;
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_POP_STOP_BT)  MOP_IN(OP_POP_STOP_BT);
+      STACK_STOP_BT_END;
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_LOOK_BEHIND)  MOP_IN(OP_LOOK_BEHIND);
+      GET_LENGTH_INC(tlen, p);
+      s = (UChar* )ONIGENC_STEP_BACK(encode, str, s, end, (int )tlen);
+      if (IS_NULL(s)) goto fail;
+      sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s, end);
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_PUSH_LOOK_BEHIND_NOT)  MOP_IN(OP_PUSH_LOOK_BEHIND_NOT);
+      GET_RELADDR_INC(addr, p);
+      GET_LENGTH_INC(tlen, p);
+      q = (UChar* )ONIGENC_STEP_BACK(encode, str, s, end, (int )tlen);
+      if (IS_NULL(q)) {
+	/* too short case -> success. ex. /(?<!XXX)a/.match("a")
+	   If you want to change to fail, replace following line. */
+	p += addr;
+	/* goto fail; */
+      }
+      else {
+	STACK_PUSH_LOOK_BEHIND_NOT(p + addr, s, sprev, pkeep);
+	s = q;
+	sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s, end);
+      }
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_FAIL_LOOK_BEHIND_NOT)  MOP_IN(OP_FAIL_LOOK_BEHIND_NOT);
+      STACK_POP_TIL_LOOK_BEHIND_NOT;
+      goto fail;
+      NEXT;
+
+    CASE(OP_PUSH_ABSENT_POS)  MOP_IN(OP_PUSH_ABSENT_POS);
+      /* Save the absent-start-pos and the original end-pos. */
+      STACK_PUSH_ABSENT_POS(s, ABSENT_END_POS);
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_ABSENT)  MOP_IN(OP_ABSENT);
+      {
+	const UChar* aend = ABSENT_END_POS;
+	UChar* absent;
+	UChar* selfp = p - 1;
+
+	STACK_POP_ABSENT_POS(absent, ABSENT_END_POS);  /* Restore end-pos. */
+	GET_RELADDR_INC(addr, p);
+#ifdef ONIG_DEBUG_MATCH
+	fprintf(stderr, "ABSENT: s:%p, end:%p, absent:%p, aend:%p\n", s, end, absent, aend);
+#endif
+	if ((absent > aend) && (s > absent)) {
+	  /* An empty match occurred in (?~...) at the start point.
+	   * Never match. */
+	  STACK_POP;
+	  goto fail;
+	}
+	else if ((s >= aend) && (s > absent)) {
+	  if (s > aend) {
+	    /* Only one (or less) character matched in the last iteration.
+	     * This is not a possible point. */
+	    goto fail;
+	  }
+	  /* All possible points were found. Try matching after (?~...). */
+	  DATA_ENSURE(0);
+	  p += addr;
+	}
+	else {
+	  STACK_PUSH_ALT(p + addr, s, sprev, pkeep); /* Push possible point. */
+	  n = enclen(encode, s, end);
+	  STACK_PUSH_ABSENT_POS(absent, ABSENT_END_POS); /* Save the original pos. */
+	  STACK_PUSH_ALT(selfp, s + n, s, pkeep); /* Next iteration. */
+	  STACK_PUSH_ABSENT;
+	  ABSENT_END_POS = aend;
+	}
+      }
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_ABSENT_END)  MOP_IN(OP_ABSENT_END);
+      /* The pattern inside (?~...) was matched.
+       * Set the end-pos temporary and go to next iteration. */
+      if (sprev < ABSENT_END_POS)
+	ABSENT_END_POS = sprev;
+#ifdef ONIG_DEBUG_MATCH
+      fprintf(stderr, "ABSENT_END: end:%p\n", ABSENT_END_POS);
+#endif
+      STACK_POP_TIL_ABSENT;
+      goto fail;
+      NEXT;
+
+#ifdef USE_SUBEXP_CALL
+    CASE(OP_CALL)  MOP_IN(OP_CALL);
+      GET_ABSADDR_INC(addr, p);
+      STACK_PUSH_CALL_FRAME(p);
+      p = reg->p + addr;
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_RETURN)  MOP_IN(OP_RETURN);
+      STACK_RETURN(p);
+      STACK_PUSH_RETURN;
+      MOP_OUT;
+      JUMP;
+#endif
+
+    CASE(OP_CONDITION)  MOP_IN(OP_CONDITION);
+      GET_MEMNUM_INC(mem, p);
+      GET_RELADDR_INC(addr, p);
+      if ((mem > num_mem) ||
+	  (mem_end_stk[mem]   == INVALID_STACK_INDEX) ||
+	  (mem_start_stk[mem] == INVALID_STACK_INDEX)) {
+	p += addr;
+      }
+      MOP_OUT;
+      JUMP;
+
+    CASE(OP_FINISH)
+      goto finish;
+      NEXT;
+
+    CASE(OP_FAIL)
+      if (0) {
+	/* fall */
+      fail:
+	MOP_OUT;
+      }
+      MOP_IN(OP_FAIL);
+      STACK_POP;
+      p     = stk->u.state.pcode;
+      s     = stk->u.state.pstr;
+      sprev = stk->u.state.pstr_prev;
+      pkeep = stk->u.state.pkeep;
+
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+      if (stk->u.state.state_check != 0) {
+	stk->type = STK_STATE_CHECK_MARK;
+	stk++;
+      }
+#endif
+
+      MOP_OUT;
+      JUMP;
+
+    DEFAULT
+      goto bytecode_error;
+  } VM_LOOP_END
+
+ finish:
+  STACK_SAVE;
+  if (xmalloc_base) xfree(xmalloc_base);
+  return best_len;
+
+#ifdef ONIG_DEBUG
+ stack_error:
+  STACK_SAVE;
+  if (xmalloc_base) xfree(xmalloc_base);
+  return ONIGERR_STACK_BUG;
+#endif
+
+ bytecode_error:
+  STACK_SAVE;
+  if (xmalloc_base) xfree(xmalloc_base);
+  return ONIGERR_UNDEFINED_BYTECODE;
+
+ unexpected_bytecode_error:
+  STACK_SAVE;
+  if (xmalloc_base) xfree(xmalloc_base);
+  return ONIGERR_UNEXPECTED_BYTECODE;
+}
+
+
+static UChar*
+slow_search(OnigEncoding enc, UChar* target, UChar* target_end,
+	    const UChar* text, const UChar* text_end, UChar* text_range)
+{
+  UChar *t, *p, *s, *end;
+
+  end = (UChar* )text_end;
+  end -= target_end - target - 1;
+  if (end > text_range)
+    end = text_range;
+
+  s = (UChar* )text;
+
+  if (enc->max_enc_len == enc->min_enc_len) {
+    int n = enc->max_enc_len;
+
+    while (s < end) {
+      if (*s == *target) {
+	p = s + 1;
+	t = target + 1;
+	if (target_end == t || memcmp(t, p, target_end - t) == 0)
+	  return s;
+      }
+      s += n;
+    }
+    return (UChar* )NULL;
+  }
+  while (s < end) {
+    if (*s == *target) {
+      p = s + 1;
+      t = target + 1;
+      if (target_end == t || memcmp(t, p, target_end - t) == 0)
+	return s;
+    }
+    s += enclen(enc, s, text_end);
+  }
+
+  return (UChar* )NULL;
+}
+
+static int
+str_lower_case_match(OnigEncoding enc, int case_fold_flag,
+		     const UChar* t, const UChar* tend,
+		     const UChar* p, const UChar* end)
+{
+  int lowlen;
+  UChar *q, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
+
+  while (t < tend) {
+    lowlen = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &p, end, lowbuf);
+    q = lowbuf;
+    while (lowlen > 0) {
+      if (*t++ != *q++)	return 0;
+      lowlen--;
+    }
+  }
+
+  return 1;
+}
+
+static UChar*
+slow_search_ic(OnigEncoding enc, int case_fold_flag,
+	       UChar* target, UChar* target_end,
+	       const UChar* text, const UChar* text_end, UChar* text_range)
+{
+  UChar *s, *end;
+
+  end = (UChar* )text_end;
+  end -= target_end - target - 1;
+  if (end > text_range)
+    end = text_range;
+
+  s = (UChar* )text;
+
+  while (s < end) {
+    if (str_lower_case_match(enc, case_fold_flag, target, target_end,
+			     s, text_end))
+      return s;
+
+    s += enclen(enc, s, text_end);
+  }
+
+  return (UChar* )NULL;
+}
+
+static UChar*
+slow_search_backward(OnigEncoding enc, UChar* target, UChar* target_end,
+		     const UChar* text, const UChar* adjust_text,
+		     const UChar* text_end, const UChar* text_start)
+{
+  UChar *t, *p, *s;
+
+  s = (UChar* )text_end;
+  s -= (target_end - target);
+  if (s > text_start)
+    s = (UChar* )text_start;
+  else
+    s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, adjust_text, s, text_end);
+
+  while (s >= text) {
+    if (*s == *target) {
+      p = s + 1;
+      t = target + 1;
+      while (t < target_end) {
+	if (*t != *p++)
+	  break;
+	t++;
+      }
+      if (t == target_end)
+	return s;
+    }
+    s = (UChar* )onigenc_get_prev_char_head(enc, adjust_text, s, text_end);
+  }
+
+  return (UChar* )NULL;
+}
+
+static UChar*
+slow_search_backward_ic(OnigEncoding enc, int case_fold_flag,
+			UChar* target, UChar* target_end,
+			const UChar* text, const UChar* adjust_text,
+			const UChar* text_end, const UChar* text_start)
+{
+  UChar *s;
+
+  s = (UChar* )text_end;
+  s -= (target_end - target);
+  if (s > text_start)
+    s = (UChar* )text_start;
+  else
+    s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, adjust_text, s, text_end);
+
+  while (s >= text) {
+    if (str_lower_case_match(enc, case_fold_flag,
+			     target, target_end, s, text_end))
+      return s;
+
+    s = (UChar* )onigenc_get_prev_char_head(enc, adjust_text, s, text_end);
+  }
+
+  return (UChar* )NULL;
+}
+
+#ifndef USE_SUNDAY_QUICK_SEARCH
+/* Boyer-Moore-Horspool search applied to a multibyte string */
+static UChar*
+bm_search_notrev(regex_t* reg, const UChar* target, const UChar* target_end,
+		 const UChar* text, const UChar* text_end,
+		 const UChar* text_range)
+{
+  const UChar *s, *se, *t, *p, *end;
+  const UChar *tail;
+  ptrdiff_t skip, tlen1;
+
+# ifdef ONIG_DEBUG_SEARCH
+  fprintf(stderr, "bm_search_notrev: text: %"PRIuPTR" (%p), text_end: %"PRIuPTR" (%p), text_range: %"PRIuPTR" (%p)\n",
+	  (uintptr_t )text, text, (uintptr_t )text_end, text_end, (uintptr_t )text_range, text_range);
+# endif
+
+  tail = target_end - 1;
+  tlen1 = tail - target;
+  end = text_range;
+  if (end + tlen1 > text_end)
+    end = text_end - tlen1;
+
+  s = text;
+
+  if (IS_NULL(reg->int_map)) {
+    while (s < end) {
+      p = se = s + tlen1;
+      t = tail;
+      while (*p == *t) {
+	if (t == target) return (UChar* )s;
+	p--; t--;
+      }
+      skip = reg->map[*se];
+      t = s;
+      do {
+	s += enclen(reg->enc, s, end);
+      } while ((s - t) < skip && s < end);
+    }
+  }
+  else {
+# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
+    while (s < end) {
+      p = se = s + tlen1;
+      t = tail;
+      while (*p == *t) {
+	if (t == target) return (UChar* )s;
+	p--; t--;
+      }
+      skip = reg->int_map[*se];
+      t = s;
+      do {
+	s += enclen(reg->enc, s, end);
+      } while ((s - t) < skip && s < end);
+    }
+# endif
+  }
+
+  return (UChar* )NULL;
+}
+
+/* Boyer-Moore-Horspool search */
+static UChar*
+bm_search(regex_t* reg, const UChar* target, const UChar* target_end,
+	  const UChar* text, const UChar* text_end, const UChar* text_range)
+{
+  const UChar *s, *t, *p, *end;
+  const UChar *tail;
+
+# ifdef ONIG_DEBUG_SEARCH
+  fprintf(stderr, "bm_search: text: %"PRIuPTR" (%p), text_end: %"PRIuPTR" (%p), text_range: %"PRIuPTR" (%p)\n",
+	  (uintptr_t )text, text, (uintptr_t )text_end, text_end, (uintptr_t )text_range, text_range);
+# endif
+
+  end = text_range + (target_end - target) - 1;
+  if (end > text_end)
+    end = text_end;
+
+  tail = target_end - 1;
+  s = text + (target_end - target) - 1;
+  if (IS_NULL(reg->int_map)) {
+    while (s < end) {
+      p = s;
+      t = tail;
+# ifdef ONIG_DEBUG_SEARCH
+      fprintf(stderr, "bm_search_loop: pos: %"PRIdPTR" %s\n",
+	  (intptr_t )(s - text), s);
+# endif
+      while (*p == *t) {
+	if (t == target) return (UChar* )p;
+	p--; t--;
+      }
+      s += reg->map[*s];
+    }
+  }
+  else { /* see int_map[] */
+# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
+    while (s < end) {
+      p = s;
+      t = tail;
+      while (*p == *t) {
+	if (t == target) return (UChar* )p;
+	p--; t--;
+      }
+      s += reg->int_map[*s];
+    }
+# endif
+  }
+  return (UChar* )NULL;
+}
+
+/* Boyer-Moore-Horspool search applied to a multibyte string (ignore case) */
+static UChar*
+bm_search_notrev_ic(regex_t* reg, const UChar* target, const UChar* target_end,
+		    const UChar* text, const UChar* text_end,
+		    const UChar* text_range)
+{
+  const UChar *s, *se, *t, *end;
+  const UChar *tail;
+  ptrdiff_t skip, tlen1;
+  OnigEncoding enc = reg->enc;
+  int case_fold_flag = reg->case_fold_flag;
+
+# ifdef ONIG_DEBUG_SEARCH
+  fprintf(stderr, "bm_search_notrev_ic: text: %d (%p), text_end: %d (%p), text_range: %d (%p)\n",
+	  (int )text, text, (int )text_end, text_end, (int )text_range, text_range);
+# endif
+
+  tail = target_end - 1;
+  tlen1 = tail - target;
+  end = text_range;
+  if (end + tlen1 > text_end)
+    end = text_end - tlen1;
+
+  s = text;
+
+  if (IS_NULL(reg->int_map)) {
+    while (s < end) {
+      se = s + tlen1;
+      if (str_lower_case_match(enc, case_fold_flag, target, target_end,
+			       s, se + 1))
+	return (UChar* )s;
+      skip = reg->map[*se];
+      t = s;
+      do {
+	s += enclen(reg->enc, s, end);
+      } while ((s - t) < skip && s < end);
+    }
+  }
+  else {
+# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
+    while (s < end) {
+      se = s + tlen1;
+      if (str_lower_case_match(enc, case_fold_flag, target, target_end,
+			       s, se + 1))
+	return (UChar* )s;
+      skip = reg->int_map[*se];
+      t = s;
+      do {
+	s += enclen(reg->enc, s, end);
+      } while ((s - t) < skip && s < end);
+    }
+# endif
+  }
+
+  return (UChar* )NULL;
+}
+
+/* Boyer-Moore-Horspool search (ignore case) */
+static UChar*
+bm_search_ic(regex_t* reg, const UChar* target, const UChar* target_end,
+	     const UChar* text, const UChar* text_end, const UChar* text_range)
+{
+  const UChar *s, *p, *end;
+  const UChar *tail;
+  OnigEncoding enc = reg->enc;
+  int case_fold_flag = reg->case_fold_flag;
+
+# ifdef ONIG_DEBUG_SEARCH
+  fprintf(stderr, "bm_search_ic: text: %d (%p), text_end: %d (%p), text_range: %d (%p)\n",
+	  (int )text, text, (int )text_end, text_end, (int )text_range, text_range);
+# endif
+
+  end = text_range + (target_end - target) - 1;
+  if (end > text_end)
+    end = text_end;
+
+  tail = target_end - 1;
+  s = text + (target_end - target) - 1;
+  if (IS_NULL(reg->int_map)) {
+    while (s < end) {
+      p = s - (target_end - target) + 1;
+      if (str_lower_case_match(enc, case_fold_flag, target, target_end,
+			       p, s + 1))
+	return (UChar* )p;
+      s += reg->map[*s];
+    }
+  }
+  else { /* see int_map[] */
+# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
+    while (s < end) {
+      p = s - (target_end - target) + 1;
+      if (str_lower_case_match(enc, case_fold_flag, target, target_end,
+			       p, s + 1))
+	return (UChar* )p;
+      s += reg->int_map[*s];
+    }
+# endif
+  }
+  return (UChar* )NULL;
+}
+
+#else /* USE_SUNDAY_QUICK_SEARCH */
+
+/* Sunday's quick search applied to a multibyte string */
+static UChar*
+bm_search_notrev(regex_t* reg, const UChar* target, const UChar* target_end,
+		 const UChar* text, const UChar* text_end,
+		 const UChar* text_range)
+{
+  const UChar *s, *se, *t, *p, *end;
+  const UChar *tail;
+  ptrdiff_t skip, tlen1;
+  OnigEncoding enc = reg->enc;
+
+# ifdef ONIG_DEBUG_SEARCH
+  fprintf(stderr, "bm_search_notrev: text: %"PRIuPTR" (%p), text_end: %"PRIuPTR" (%p), text_range: %"PRIuPTR" (%p)\n",
+	  (uintptr_t )text, text, (uintptr_t )text_end, text_end, (uintptr_t )text_range, text_range);
+# endif
+
+  tail = target_end - 1;
+  tlen1 = tail - target;
+  end = text_range;
+  if (end + tlen1 > text_end)
+    end = text_end - tlen1;
+
+  s = text;
+
+  if (IS_NULL(reg->int_map)) {
+    while (s < end) {
+      p = se = s + tlen1;
+      t = tail;
+      while (*p == *t) {
+	if (t == target) return (UChar* )s;
+	p--; t--;
+      }
+      if (s + 1 >= end) break;
+      skip = reg->map[se[1]];
+      t = s;
+      do {
+	s += enclen(enc, s, end);
+      } while ((s - t) < skip && s < end);
+    }
+  }
+  else {
+# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
+    while (s < end) {
+      p = se = s + tlen1;
+      t = tail;
+      while (*p == *t) {
+	if (t == target) return (UChar* )s;
+	p--; t--;
+      }
+      if (s + 1 >= end) break;
+      skip = reg->int_map[se[1]];
+      t = s;
+      do {
+	s += enclen(enc, s, end);
+      } while ((s - t) < skip && s < end);
+    }
+# endif
+  }
+
+  return (UChar* )NULL;
+}
+
+/* Sunday's quick search */
+static UChar*
+bm_search(regex_t* reg, const UChar* target, const UChar* target_end,
+	  const UChar* text, const UChar* text_end, const UChar* text_range)
+{
+  const UChar *s, *t, *p, *end;
+  const UChar *tail;
+  ptrdiff_t tlen1;
+
+# ifdef ONIG_DEBUG_SEARCH
+  fprintf(stderr, "bm_search: text: %"PRIuPTR" (%p), text_end: %"PRIuPTR" (%p), text_range: %"PRIuPTR" (%p)\n",
+	  (uintptr_t )text, text, (uintptr_t )text_end, text_end, (uintptr_t )text_range, text_range);
+# endif
+
+  tail = target_end - 1;
+  tlen1 = tail - target;
+  end = text_range + tlen1;
+  if (end > text_end)
+    end = text_end;
+
+  s = text + tlen1;
+  if (IS_NULL(reg->int_map)) {
+    while (s < end) {
+      p = s;
+      t = tail;
+      while (*p == *t) {
+	if (t == target) return (UChar* )p;
+	p--; t--;
+      }
+      if (s + 1 >= end) break;
+      s += reg->map[s[1]];
+    }
+  }
+  else { /* see int_map[] */
+# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
+    while (s < end) {
+      p = s;
+      t = tail;
+      while (*p == *t) {
+	if (t == target) return (UChar* )p;
+	p--; t--;
+      }
+      if (s + 1 >= end) break;
+      s += reg->int_map[s[1]];
+    }
+# endif
+  }
+  return (UChar* )NULL;
+}
+
+/* Sunday's quick search applied to a multibyte string (ignore case) */
+static UChar*
+bm_search_notrev_ic(regex_t* reg, const UChar* target, const UChar* target_end,
+		    const UChar* text, const UChar* text_end,
+		    const UChar* text_range)
+{
+  const UChar *s, *se, *t, *end;
+  const UChar *tail;
+  ptrdiff_t skip, tlen1;
+  OnigEncoding enc = reg->enc;
+  int case_fold_flag = reg->case_fold_flag;
+
+# ifdef ONIG_DEBUG_SEARCH
+  fprintf(stderr, "bm_search_notrev_ic: text: %"PRIuPTR" (%p), text_end: %"PRIuPTR" (%p), text_range: %"PRIuPTR" (%p)\n",
+	  (uintptr_t )text, text, (uintptr_t )text_end, text_end, (uintptr_t )text_range, text_range);
+# endif
+
+  tail = target_end - 1;
+  tlen1 = tail - target;
+  end = text_range;
+  if (end + tlen1 > text_end)
+    end = text_end - tlen1;
+
+  s = text;
+
+  if (IS_NULL(reg->int_map)) {
+    while (s < end) {
+      se = s + tlen1;
+      if (str_lower_case_match(enc, case_fold_flag, target, target_end,
+			       s, se + 1))
+	return (UChar* )s;
+      if (s + 1 >= end) break;
+      skip = reg->map[se[1]];
+      t = s;
+      do {
+	s += enclen(enc, s, end);
+      } while ((s - t) < skip && s < end);
+    }
+  }
+  else {
+# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
+    while (s < end) {
+      se = s + tlen1;
+      if (str_lower_case_match(enc, case_fold_flag, target, target_end,
+			       s, se + 1))
+	return (UChar* )s;
+      if (s + 1 >= end) break;
+      skip = reg->int_map[se[1]];
+      t = s;
+      do {
+	s += enclen(enc, s, end);
+      } while ((s - t) < skip && s < end);
+    }
+# endif
+  }
+
+  return (UChar* )NULL;
+}
+
+/* Sunday's quick search (ignore case) */
+static UChar*
+bm_search_ic(regex_t* reg, const UChar* target, const UChar* target_end,
+	     const UChar* text, const UChar* text_end, const UChar* text_range)
+{
+  const UChar *s, *p, *end;
+  const UChar *tail;
+  ptrdiff_t tlen1;
+  OnigEncoding enc = reg->enc;
+  int case_fold_flag = reg->case_fold_flag;
+
+# ifdef ONIG_DEBUG_SEARCH
+  fprintf(stderr, "bm_search_ic: text: %"PRIuPTR" (%p), text_end: %"PRIuPTR" (%p), text_range: %"PRIuPTR" (%p)\n",
+	  (uintptr_t )text, text, (uintptr_t )text_end, text_end, (uintptr_t )text_range, text_range);
+# endif
+
+  tail = target_end - 1;
+  tlen1 = tail - target;
+  end = text_range + tlen1;
+  if (end > text_end)
+    end = text_end;
+
+  s = text + tlen1;
+  if (IS_NULL(reg->int_map)) {
+    while (s < end) {
+      p = s - tlen1;
+      if (str_lower_case_match(enc, case_fold_flag, target, target_end,
+			       p, s + 1))
+	return (UChar* )p;
+      if (s + 1 >= end) break;
+      s += reg->map[s[1]];
+    }
+  }
+  else { /* see int_map[] */
+# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
+    while (s < end) {
+      p = s - tlen1;
+      if (str_lower_case_match(enc, case_fold_flag, target, target_end,
+			       p, s + 1))
+	return (UChar* )p;
+      if (s + 1 >= end) break;
+      s += reg->int_map[s[1]];
+    }
+# endif
+  }
+  return (UChar* )NULL;
+}
+#endif /* USE_SUNDAY_QUICK_SEARCH */
+
+#ifdef USE_INT_MAP_BACKWARD
+static int
+set_bm_backward_skip(UChar* s, UChar* end, OnigEncoding enc ARG_UNUSED,
+		     int** skip)
+{
+  int i, len;
+
+  if (IS_NULL(*skip)) {
+    *skip = (int* )xmalloc(sizeof(int) * ONIG_CHAR_TABLE_SIZE);
+    if (IS_NULL(*skip)) return ONIGERR_MEMORY;
+  }
+
+  len = (int )(end - s);
+  for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
+    (*skip)[i] = len;
+
+  for (i = len - 1; i > 0; i--)
+    (*skip)[s[i]] = i;
+
+  return 0;
+}
+
+static UChar*
+bm_search_backward(regex_t* reg, const UChar* target, const UChar* target_end,
+		   const UChar* text, const UChar* adjust_text,
+		   const UChar* text_end, const UChar* text_start)
+{
+  const UChar *s, *t, *p;
+
+  s = text_end - (target_end - target);
+  if (text_start < s)
+    s = text_start;
+  else
+    s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, adjust_text, s, text_end);
+
+  while (s >= text) {
+    p = s;
+    t = target;
+    while (t < target_end && *p == *t) {
+      p++; t++;
+    }
+    if (t == target_end)
+      return (UChar* )s;
+
+    s -= reg->int_map_backward[*s];
+    s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, adjust_text, s, text_end);
+  }
+
+  return (UChar* )NULL;
+}
+#endif
+
+static UChar*
+map_search(OnigEncoding enc, UChar map[],
+	   const UChar* text, const UChar* text_range, const UChar* text_end)
+{
+  const UChar *s = text;
+
+  while (s < text_range) {
+    if (map[*s]) return (UChar* )s;
+
+    s += enclen(enc, s, text_end);
+  }
+  return (UChar* )NULL;
+}
+
+static UChar*
+map_search_backward(OnigEncoding enc, UChar map[],
+		    const UChar* text, const UChar* adjust_text,
+		    const UChar* text_start, const UChar* text_end)
+{
+  const UChar *s = text_start;
+
+  while (s >= text) {
+    if (map[*s]) return (UChar* )s;
+
+    s = onigenc_get_prev_char_head(enc, adjust_text, s, text_end);
+  }
+  return (UChar* )NULL;
+}
+
+extern OnigPosition
+onig_match(regex_t* reg, const UChar* str, const UChar* end, const UChar* at, OnigRegion* region,
+	    OnigOptionType option)
+{
+  ptrdiff_t r;
+  UChar *prev;
+  OnigMatchArg msa;
+
+  MATCH_ARG_INIT(msa, option, region, at, at);
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+  {
+    int offset = at - str;
+    STATE_CHECK_BUFF_INIT(msa, end - str, offset, reg->num_comb_exp_check);
+  }
+#endif
+
+  if (region) {
+    r = onig_region_resize_clear(region, reg->num_mem + 1);
+  }
+  else
+    r = 0;
+
+  if (r == 0) {
+    prev = (UChar* )onigenc_get_prev_char_head(reg->enc, str, at, end);
+    r = match_at(reg, str, end,
+#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
+		 end,
+#endif
+		 at, prev, &msa);
+  }
+
+  MATCH_ARG_FREE(msa);
+  return r;
+}
+
+static int
+forward_search_range(regex_t* reg, const UChar* str, const UChar* end, UChar* s,
+		     UChar* range, UChar** low, UChar** high, UChar** low_prev)
+{
+  UChar *p, *pprev = (UChar* )NULL;
+
+#ifdef ONIG_DEBUG_SEARCH
+  fprintf(stderr, "forward_search_range: str: %"PRIuPTR" (%p), end: %"PRIuPTR" (%p), s: %"PRIuPTR" (%p), range: %"PRIuPTR" (%p)\n",
+	  (uintptr_t )str, str, (uintptr_t )end, end, (uintptr_t )s, s, (uintptr_t )range, range);
+#endif
+
+  p = s;
+  if (reg->dmin > 0) {
+    if (ONIGENC_IS_SINGLEBYTE(reg->enc)) {
+      p += reg->dmin;
+    }
+    else {
+      UChar *q = p + reg->dmin;
+
+      if (q >= end) return 0; /* fail */
+      while (p < q) p += enclen(reg->enc, p, end);
+    }
+  }
+
+ retry:
+  switch (reg->optimize) {
+  case ONIG_OPTIMIZE_EXACT:
+    p = slow_search(reg->enc, reg->exact, reg->exact_end, p, end, range);
+    break;
+  case ONIG_OPTIMIZE_EXACT_IC:
+    p = slow_search_ic(reg->enc, reg->case_fold_flag,
+		       reg->exact, reg->exact_end, p, end, range);
+    break;
+
+  case ONIG_OPTIMIZE_EXACT_BM:
+    p = bm_search(reg, reg->exact, reg->exact_end, p, end, range);
+    break;
+
+  case ONIG_OPTIMIZE_EXACT_BM_NOT_REV:
+    p = bm_search_notrev(reg, reg->exact, reg->exact_end, p, end, range);
+    break;
+
+  case ONIG_OPTIMIZE_EXACT_BM_IC:
+    p = bm_search_ic(reg, reg->exact, reg->exact_end, p, end, range);
+    break;
+
+  case ONIG_OPTIMIZE_EXACT_BM_NOT_REV_IC:
+    p = bm_search_notrev_ic(reg, reg->exact, reg->exact_end, p, end, range);
+    break;
+
+  case ONIG_OPTIMIZE_MAP:
+    p = map_search(reg->enc, reg->map, p, range, end);
+    break;
+  }
+
+  if (p && p < range) {
+    if (p - reg->dmin < s) {
+    retry_gate:
+      pprev = p;
+      p += enclen(reg->enc, p, end);
+      goto retry;
+    }
+
+    if (reg->sub_anchor) {
+      UChar* prev;
+
+      switch (reg->sub_anchor) {
+      case ANCHOR_BEGIN_LINE:
+	if (!ON_STR_BEGIN(p)) {
+	  prev = onigenc_get_prev_char_head(reg->enc,
+					    (pprev ? pprev : str), p, end);
+	  if (!ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, prev, str, end, reg->options, 0))
+	    goto retry_gate;
+	}
+	break;
+
+      case ANCHOR_END_LINE:
+	if (ON_STR_END(p)) {
+#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
+	  prev = (UChar* )onigenc_get_prev_char_head(reg->enc,
+					    (pprev ? pprev : str), p);
+	  if (prev && ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, prev, str, end, reg->options, 1))
+	    goto retry_gate;
+#endif
+	}
+	else if (! ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, p, str, end, reg->options, 1))
+	  goto retry_gate;
+	break;
+      }
+    }
+
+    if (reg->dmax == 0) {
+      *low = p;
+      if (low_prev) {
+	if (*low > s)
+	  *low_prev = onigenc_get_prev_char_head(reg->enc, s, p, end);
+	else
+	  *low_prev = onigenc_get_prev_char_head(reg->enc,
+						 (pprev ? pprev : str), p, end);
+      }
+    }
+    else {
+      if (reg->dmax != ONIG_INFINITE_DISTANCE) {
+	if (p < str + reg->dmax) {
+	  *low = (UChar* )str;
+	  if (low_prev)
+	    *low_prev = onigenc_get_prev_char_head(reg->enc, str, *low, end);
+	}
+	else {
+	  *low = p - reg->dmax;
+	  if (*low > s) {
+	    *low = onigenc_get_right_adjust_char_head_with_prev(reg->enc, s,
+								*low, end, (const UChar** )low_prev);
+	    if (low_prev && IS_NULL(*low_prev))
+	      *low_prev = onigenc_get_prev_char_head(reg->enc,
+						     (pprev ? pprev : s), *low, end);
+	  }
+	  else {
+	    if (low_prev)
+	      *low_prev = onigenc_get_prev_char_head(reg->enc,
+						 (pprev ? pprev : str), *low, end);
+	  }
+	}
+      }
+    }
+    /* no needs to adjust *high, *high is used as range check only */
+    *high = p - reg->dmin;
+
+#ifdef ONIG_DEBUG_SEARCH
+    fprintf(stderr,
+    "forward_search_range success: low: %"PRIdPTR", high: %"PRIdPTR", dmin: %"PRIdPTR", dmax: %"PRIdPTR"\n",
+	    *low - str, *high - str, reg->dmin, reg->dmax);
+#endif
+    return 1; /* success */
+  }
+
+  return 0; /* fail */
+}
+
+#define BM_BACKWARD_SEARCH_LENGTH_THRESHOLD   100
+
+static int
+backward_search_range(regex_t* reg, const UChar* str, const UChar* end,
+		      UChar* s, const UChar* range, UChar* adjrange,
+		      UChar** low, UChar** high)
+{
+  UChar *p;
+
+  range += reg->dmin;
+  p = s;
+
+ retry:
+  switch (reg->optimize) {
+  case ONIG_OPTIMIZE_EXACT:
+  exact_method:
+    p = slow_search_backward(reg->enc, reg->exact, reg->exact_end,
+			     range, adjrange, end, p);
+    break;
+
+  case ONIG_OPTIMIZE_EXACT_IC:
+  case ONIG_OPTIMIZE_EXACT_BM_IC:
+  case ONIG_OPTIMIZE_EXACT_BM_NOT_REV_IC:
+    p = slow_search_backward_ic(reg->enc, reg->case_fold_flag,
+				reg->exact, reg->exact_end,
+				range, adjrange, end, p);
+    break;
+
+  case ONIG_OPTIMIZE_EXACT_BM:
+  case ONIG_OPTIMIZE_EXACT_BM_NOT_REV:
+#ifdef USE_INT_MAP_BACKWARD
+    if (IS_NULL(reg->int_map_backward)) {
+      int r;
+      if (s - range < BM_BACKWARD_SEARCH_LENGTH_THRESHOLD)
+	goto exact_method;
+
+      r = set_bm_backward_skip(reg->exact, reg->exact_end, reg->enc,
+			       &(reg->int_map_backward));
+      if (r) return r;
+    }
+    p = bm_search_backward(reg, reg->exact, reg->exact_end, range, adjrange,
+			   end, p);
+#else
+    goto exact_method;
+#endif
+    break;
+
+  case ONIG_OPTIMIZE_MAP:
+    p = map_search_backward(reg->enc, reg->map, range, adjrange, p, end);
+    break;
+  }
+
+  if (p) {
+    if (reg->sub_anchor) {
+      UChar* prev;
+
+      switch (reg->sub_anchor) {
+      case ANCHOR_BEGIN_LINE:
+	if (!ON_STR_BEGIN(p)) {
+	  prev = onigenc_get_prev_char_head(reg->enc, str, p, end);
+	  if (!ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, prev, str, end, reg->options, 0)) {
+	    p = prev;
+	    goto retry;
+	  }
+	}
+	break;
+
+      case ANCHOR_END_LINE:
+	if (ON_STR_END(p)) {
+#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
+	  prev = onigenc_get_prev_char_head(reg->enc, adjrange, p);
+	  if (IS_NULL(prev)) goto fail;
+	  if (ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, prev, str, end, reg->options, 1)) {
+	    p = prev;
+	    goto retry;
+	  }
+#endif
+	}
+	else if (! ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, p, str, end, reg->options, 1)) {
+	  p = onigenc_get_prev_char_head(reg->enc, adjrange, p, end);
+	  if (IS_NULL(p)) goto fail;
+	  goto retry;
+	}
+	break;
+      }
+    }
+
+    /* no needs to adjust *high, *high is used as range check only */
+    if (reg->dmax != ONIG_INFINITE_DISTANCE) {
+      *low  = p - reg->dmax;
+      *high = p - reg->dmin;
+      *high = onigenc_get_right_adjust_char_head(reg->enc, adjrange, *high, end);
+    }
+
+#ifdef ONIG_DEBUG_SEARCH
+    fprintf(stderr, "backward_search_range: low: %d, high: %d\n",
+	    (int )(*low - str), (int )(*high - str));
+#endif
+    return 1; /* success */
+  }
+
+ fail:
+#ifdef ONIG_DEBUG_SEARCH
+  fprintf(stderr, "backward_search_range: fail.\n");
+#endif
+  return 0; /* fail */
+}
+
+
+extern OnigPosition
+onig_search(regex_t* reg, const UChar* str, const UChar* end,
+	    const UChar* start, const UChar* range, OnigRegion* region, OnigOptionType option)
+{
+  return onig_search_gpos(reg, str, end, start, start, range, region, option);
+}
+
+extern OnigPosition
+onig_search_gpos(regex_t* reg, const UChar* str, const UChar* end,
+	    const UChar* global_pos,
+	    const UChar* start, const UChar* range, OnigRegion* region, OnigOptionType option)
+{
+  ptrdiff_t r;
+  UChar *s, *prev;
+  OnigMatchArg msa;
+#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
+  const UChar *orig_start = start;
+  const UChar *orig_range = range;
+#endif
+
+#ifdef ONIG_DEBUG_SEARCH
+  fprintf(stderr,
+     "onig_search (entry point): str: %"PRIuPTR" (%p), end: %"PRIuPTR", start: %"PRIuPTR", range: %"PRIuPTR"\n",
+     (uintptr_t )str, str, end - str, start - str, range - str);
+#endif
+
+  if (region) {
+    r = onig_region_resize_clear(region, reg->num_mem + 1);
+    if (r) goto finish_no_msa;
+  }
+
+  if (start > end || start < str) goto mismatch_no_msa;
+
+
+#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
+# ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
+#  define MATCH_AND_RETURN_CHECK(upper_range) \
+  r = match_at(reg, str, end, (upper_range), s, prev, &msa); \
+  if (r != ONIG_MISMATCH) {\
+    if (r >= 0) {\
+      if (! IS_FIND_LONGEST(reg->options)) {\
+        goto match;\
+      }\
+    }\
+    else goto finish; /* error */ \
+  }
+# else
+#  define MATCH_AND_RETURN_CHECK(upper_range) \
+  r = match_at(reg, str, end, (upper_range), s, prev, &msa); \
+  if (r != ONIG_MISMATCH) {\
+    if (r >= 0) {\
+      goto match;\
+    }\
+    else goto finish; /* error */ \
+  }
+# endif /* USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE */
+#else
+# ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
+#  define MATCH_AND_RETURN_CHECK(none) \
+  r = match_at(reg, str, end, s, prev, &msa);\
+  if (r != ONIG_MISMATCH) {\
+    if (r >= 0) {\
+      if (! IS_FIND_LONGEST(reg->options)) {\
+        goto match;\
+      }\
+    }\
+    else goto finish; /* error */ \
+  }
+# else
+#  define MATCH_AND_RETURN_CHECK(none) \
+  r = match_at(reg, str, end, s, prev, &msa);\
+  if (r != ONIG_MISMATCH) {\
+    if (r >= 0) {\
+      goto match;\
+    }\
+    else goto finish; /* error */ \
+  }
+# endif /* USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE */
+#endif /* USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE */
+
+
+  /* anchor optimize: resume search range */
+  if (reg->anchor != 0 && str < end) {
+    UChar *min_semi_end, *max_semi_end;
+
+    if (reg->anchor & ANCHOR_BEGIN_POSITION) {
+      /* search start-position only */
+    begin_position:
+      if (range > start)
+      {
+	if (global_pos > start)
+	{
+	  if (global_pos < range)
+	    range = global_pos + 1;
+	}
+	else
+	  range = start + 1;
+      }
+      else
+	range = start;
+    }
+    else if (reg->anchor & ANCHOR_BEGIN_BUF) {
+      /* search str-position only */
+      if (range > start) {
+	if (start != str) goto mismatch_no_msa;
+	range = str + 1;
+      }
+      else {
+	if (range <= str) {
+	  start = str;
+	  range = str;
+	}
+	else
+	  goto mismatch_no_msa;
+      }
+    }
+    else if (reg->anchor & ANCHOR_END_BUF) {
+      min_semi_end = max_semi_end = (UChar* )end;
+
+    end_buf:
+      if ((OnigDistance )(max_semi_end - str) < reg->anchor_dmin)
+	goto mismatch_no_msa;
+
+      if (range > start) {
+	if ((OnigDistance )(min_semi_end - start) > reg->anchor_dmax) {
+	  start = min_semi_end - reg->anchor_dmax;
+	  if (start < end)
+	    start = onigenc_get_right_adjust_char_head(reg->enc, str, start, end);
+	}
+	if ((OnigDistance )(max_semi_end - (range - 1)) < reg->anchor_dmin) {
+	  range = max_semi_end - reg->anchor_dmin + 1;
+	}
+
+	if (start > range) goto mismatch_no_msa;
+	/* If start == range, match with empty at end.
+	   Backward search is used. */
+      }
+      else {
+	if ((OnigDistance )(min_semi_end - range) > reg->anchor_dmax) {
+	  range = min_semi_end - reg->anchor_dmax;
+	}
+	if ((OnigDistance )(max_semi_end - start) < reg->anchor_dmin) {
+	  start = max_semi_end - reg->anchor_dmin;
+	  start = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, str, start, end);
+	}
+	if (range > start) goto mismatch_no_msa;
+      }
+    }
+    else if (reg->anchor & ANCHOR_SEMI_END_BUF) {
+      UChar* pre_end = ONIGENC_STEP_BACK(reg->enc, str, end, end, 1);
+
+      max_semi_end = (UChar* )end;
+      if (ONIGENC_IS_MBC_NEWLINE(reg->enc, pre_end, end)) {
+	min_semi_end = pre_end;
+
+#ifdef USE_CRNL_AS_LINE_TERMINATOR
+	pre_end = ONIGENC_STEP_BACK(reg->enc, str, pre_end, end, 1);
+	if (IS_NOT_NULL(pre_end) &&
+	    IS_NEWLINE_CRLF(reg->options) &&
+	    ONIGENC_IS_MBC_CRNL(reg->enc, pre_end, end)) {
+	  min_semi_end = pre_end;
+	}
+#endif
+	if (min_semi_end > str && start <= min_semi_end) {
+	  goto end_buf;
+	}
+      }
+      else {
+	min_semi_end = (UChar* )end;
+	goto end_buf;
+      }
+    }
+    else if ((reg->anchor & ANCHOR_ANYCHAR_STAR_ML)) {
+      goto begin_position;
+    }
+  }
+  else if (str == end) { /* empty string */
+    static const UChar address_for_empty_string[] = "";
+
+#ifdef ONIG_DEBUG_SEARCH
+    fprintf(stderr, "onig_search: empty string.\n");
+#endif
+
+    if (reg->threshold_len == 0) {
+      start = end = str = address_for_empty_string;
+      s = (UChar* )start;
+      prev = (UChar* )NULL;
+
+      MATCH_ARG_INIT(msa, option, region, start, start);
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+      msa.state_check_buff = (void* )0;
+      msa.state_check_buff_size = 0;   /* NO NEED, for valgrind */
+#endif
+      MATCH_AND_RETURN_CHECK(end);
+      goto mismatch;
+    }
+    goto mismatch_no_msa;
+  }
+
+#ifdef ONIG_DEBUG_SEARCH
+  fprintf(stderr, "onig_search(apply anchor): end: %d, start: %d, range: %d\n",
+	  (int )(end - str), (int )(start - str), (int )(range - str));
+#endif
+
+  MATCH_ARG_INIT(msa, option, region, start, global_pos);
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+  {
+    int offset = (MIN(start, range) - str);
+    STATE_CHECK_BUFF_INIT(msa, end - str, offset, reg->num_comb_exp_check);
+  }
+#endif
+
+  s = (UChar* )start;
+  if (range > start) {   /* forward search */
+    if (s > str)
+      prev = onigenc_get_prev_char_head(reg->enc, str, s, end);
+    else
+      prev = (UChar* )NULL;
+
+    if (reg->optimize != ONIG_OPTIMIZE_NONE) {
+      UChar *sch_range, *low, *high, *low_prev;
+
+      sch_range = (UChar* )range;
+      if (reg->dmax != 0) {
+	if (reg->dmax == ONIG_INFINITE_DISTANCE)
+	  sch_range = (UChar* )end;
+	else {
+	  sch_range += reg->dmax;
+	  if (sch_range > end) sch_range = (UChar* )end;
+	}
+      }
+
+      if ((end - start) < reg->threshold_len)
+	goto mismatch;
+
+      if (reg->dmax != ONIG_INFINITE_DISTANCE) {
+	do {
+	  if (! forward_search_range(reg, str, end, s, sch_range,
+				     &low, &high, &low_prev)) goto mismatch;
+	  if (s < low) {
+	    s    = low;
+	    prev = low_prev;
+	  }
+	  while (s <= high) {
+	    MATCH_AND_RETURN_CHECK(orig_range);
+	    prev = s;
+	    s += enclen(reg->enc, s, end);
+	  }
+	} while (s < range);
+	goto mismatch;
+      }
+      else { /* check only. */
+	if (! forward_search_range(reg, str, end, s, sch_range,
+				   &low, &high, (UChar** )NULL)) goto mismatch;
+
+	if ((reg->anchor & ANCHOR_ANYCHAR_STAR) != 0) {
+	  do {
+	    MATCH_AND_RETURN_CHECK(orig_range);
+	    prev = s;
+	    s += enclen(reg->enc, s, end);
+
+	    if ((reg->anchor & (ANCHOR_LOOK_BEHIND | ANCHOR_PREC_READ_NOT)) == 0) {
+	      while (!ONIGENC_IS_MBC_NEWLINE_EX(reg->enc, prev, str, end, reg->options, 0)
+		  && s < range) {
+		prev = s;
+		s += enclen(reg->enc, s, end);
+	      }
+	    }
+	  } while (s < range);
+	  goto mismatch;
+	}
+      }
+    }
+
+    do {
+      MATCH_AND_RETURN_CHECK(orig_range);
+      prev = s;
+      s += enclen(reg->enc, s, end);
+    } while (s < range);
+
+    if (s == range) { /* because empty match with /$/. */
+      MATCH_AND_RETURN_CHECK(orig_range);
+    }
+  }
+  else {  /* backward search */
+    if (reg->optimize != ONIG_OPTIMIZE_NONE) {
+      UChar *low, *high, *adjrange, *sch_start;
+
+      if (range < end)
+	adjrange = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, str, range, end);
+      else
+	adjrange = (UChar* )end;
+
+      if (reg->dmax != ONIG_INFINITE_DISTANCE &&
+	  (end - range) >= reg->threshold_len) {
+	do {
+	  sch_start = s + reg->dmax;
+	  if (sch_start > end) sch_start = (UChar* )end;
+	  if (backward_search_range(reg, str, end, sch_start, range, adjrange,
+				    &low, &high) <= 0)
+	    goto mismatch;
+
+	  if (s > high)
+	    s = high;
+
+	  while (s >= low) {
+	    prev = onigenc_get_prev_char_head(reg->enc, str, s, end);
+	    MATCH_AND_RETURN_CHECK(orig_start);
+	    s = prev;
+	  }
+	} while (s >= range);
+	goto mismatch;
+      }
+      else { /* check only. */
+	if ((end - range) < reg->threshold_len) goto mismatch;
+
+	sch_start = s;
+	if (reg->dmax != 0) {
+	  if (reg->dmax == ONIG_INFINITE_DISTANCE)
+	    sch_start = (UChar* )end;
+	  else {
+	    sch_start += reg->dmax;
+	    if (sch_start > end) sch_start = (UChar* )end;
+	    else
+	      sch_start = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc,
+						    start, sch_start, end);
+	  }
+	}
+	if (backward_search_range(reg, str, end, sch_start, range, adjrange,
+				  &low, &high) <= 0) goto mismatch;
+      }
+    }
+
+    do {
+      prev = onigenc_get_prev_char_head(reg->enc, str, s, end);
+      MATCH_AND_RETURN_CHECK(orig_start);
+      s = prev;
+    } while (s >= range);
+  }
+
+ mismatch:
+#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
+  if (IS_FIND_LONGEST(reg->options)) {
+    if (msa.best_len >= 0) {
+      s = msa.best_s;
+      goto match;
+    }
+  }
+#endif
+  r = ONIG_MISMATCH;
+
+ finish:
+  MATCH_ARG_FREE(msa);
+
+  /* If result is mismatch and no FIND_NOT_EMPTY option,
+     then the region is not set in match_at(). */
+  if (IS_FIND_NOT_EMPTY(reg->options) && region) {
+    onig_region_clear(region);
+  }
+
+#ifdef ONIG_DEBUG
+  if (r != ONIG_MISMATCH)
+    fprintf(stderr, "onig_search: error %"PRIdPTRDIFF"\n", r);
+#endif
+  return r;
+
+ mismatch_no_msa:
+  r = ONIG_MISMATCH;
+ finish_no_msa:
+#ifdef ONIG_DEBUG
+  if (r != ONIG_MISMATCH)
+    fprintf(stderr, "onig_search: error %"PRIdPTRDIFF"\n", r);
+#endif
+  return r;
+
+ match:
+  MATCH_ARG_FREE(msa);
+  return s - str;
+}
+
+extern OnigPosition
+onig_scan(regex_t* reg, const UChar* str, const UChar* end,
+	  OnigRegion* region, OnigOptionType option,
+	  int (*scan_callback)(OnigPosition, OnigPosition, OnigRegion*, void*),
+	  void* callback_arg)
+{
+  OnigPosition r;
+  OnigPosition n;
+  int rs;
+  const UChar* start;
+
+  n = 0;
+  start = str;
+  while (1) {
+    r = onig_search(reg, str, end, start, end, region, option);
+    if (r >= 0) {
+      rs = scan_callback(n, r, region, callback_arg);
+      n++;
+      if (rs != 0)
+	return rs;
+
+      if (region->end[0] == start - str) {
+	if (start >= end) break;
+	start += enclen(reg->enc, start, end);
+      }
+      else
+	start = str + region->end[0];
+
+      if (start > end)
+	break;
+    }
+    else if (r == ONIG_MISMATCH) {
+      break;
+    }
+    else { /* error */
+      return r;
+    }
+  }
+
+  return n;
+}
+
+extern OnigEncoding
+onig_get_encoding(const regex_t* reg)
+{
+  return reg->enc;
+}
+
+extern OnigOptionType
+onig_get_options(const regex_t* reg)
+{
+  return reg->options;
+}
+
+extern  OnigCaseFoldType
+onig_get_case_fold_flag(const regex_t* reg)
+{
+  return reg->case_fold_flag;
+}
+
+extern const OnigSyntaxType*
+onig_get_syntax(const regex_t* reg)
+{
+  return reg->syntax;
+}
+
+extern int
+onig_number_of_captures(const regex_t* reg)
+{
+  return reg->num_mem;
+}
+
+extern int
+onig_number_of_capture_histories(const regex_t* reg)
+{
+#ifdef USE_CAPTURE_HISTORY
+  int i, n;
+
+  n = 0;
+  for (i = 0; i <= ONIG_MAX_CAPTURE_HISTORY_GROUP; i++) {
+    if (BIT_STATUS_AT(reg->capture_history, i) != 0)
+      n++;
+  }
+  return n;
+#else
+  return 0;
+#endif
+}
+
+extern void
+onig_copy_encoding(OnigEncodingType *to, OnigEncoding from)
+{
+  *to = *from;
+}
+
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/regext.c
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/regext.c	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/regext.c	(revision 331)
@@ -0,0 +1,203 @@
+/**********************************************************************
+  regext.c -  Onigmo (Oniguruma-mod) (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2008  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011-2016  K.Takata  <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "regint.h"
+
+static void
+conv_ext0be32(const UChar* s, const UChar* end, UChar* conv)
+{
+  while (s < end) {
+    *conv++ = '\0';
+    *conv++ = '\0';
+    *conv++ = '\0';
+    *conv++ = *s++;
+  }
+}
+
+static void
+conv_ext0le32(const UChar* s, const UChar* end, UChar* conv)
+{
+  while (s < end) {
+    *conv++ = *s++;
+    *conv++ = '\0';
+    *conv++ = '\0';
+    *conv++ = '\0';
+  }
+}
+
+static void
+conv_ext0be(const UChar* s, const UChar* end, UChar* conv)
+{
+  while (s < end) {
+    *conv++ = '\0';
+    *conv++ = *s++;
+  }
+}
+
+static void
+conv_ext0le(const UChar* s, const UChar* end, UChar* conv)
+{
+  while (s < end) {
+    *conv++ = *s++;
+    *conv++ = '\0';
+  }
+}
+
+static void
+conv_swap4bytes(const UChar* s, const UChar* end, UChar* conv)
+{
+  while (s < end) {
+    *conv++ = s[3];
+    *conv++ = s[2];
+    *conv++ = s[1];
+    *conv++ = s[0];
+    s += 4;
+  }
+}
+
+static void
+conv_swap2bytes(const UChar* s, const UChar* end, UChar* conv)
+{
+  while (s < end) {
+    *conv++ = s[1];
+    *conv++ = s[0];
+    s += 2;
+  }
+}
+
+static int
+conv_encoding(OnigEncoding from, OnigEncoding to, const UChar* s, const UChar* end,
+              UChar** conv, UChar** conv_end)
+{
+  ptrdiff_t len = end - s;
+
+  if (to == ONIG_ENCODING_UTF16_BE) {
+    if (from == ONIG_ENCODING_ASCII || from == ONIG_ENCODING_ISO_8859_1) {
+      *conv = (UChar* )xmalloc(len * 2);
+      CHECK_NULL_RETURN_MEMERR(*conv);
+      *conv_end = *conv + (len * 2);
+      conv_ext0be(s, end, *conv);
+      return 0;
+    }
+    else if (from == ONIG_ENCODING_UTF16_LE) {
+    swap16:
+      *conv = (UChar* )xmalloc(len);
+      CHECK_NULL_RETURN_MEMERR(*conv);
+      *conv_end = *conv + len;
+      conv_swap2bytes(s, end, *conv);
+      return 0;
+    }
+  }
+  else if (to == ONIG_ENCODING_UTF16_LE) {
+    if (from == ONIG_ENCODING_ASCII || from == ONIG_ENCODING_ISO_8859_1) {
+      *conv = (UChar* )xmalloc(len * 2);
+      CHECK_NULL_RETURN_MEMERR(*conv);
+      *conv_end = *conv + (len * 2);
+      conv_ext0le(s, end, *conv);
+      return 0;
+    }
+    else if (from == ONIG_ENCODING_UTF16_BE) {
+      goto swap16;
+    }
+  }
+  if (to == ONIG_ENCODING_UTF32_BE) {
+    if (from == ONIG_ENCODING_ASCII || from == ONIG_ENCODING_ISO_8859_1) {
+      *conv = (UChar* )xmalloc(len * 4);
+      CHECK_NULL_RETURN_MEMERR(*conv);
+      *conv_end = *conv + (len * 4);
+      conv_ext0be32(s, end, *conv);
+      return 0;
+    }
+    else if (from == ONIG_ENCODING_UTF32_LE) {
+    swap32:
+      *conv = (UChar* )xmalloc(len);
+      CHECK_NULL_RETURN_MEMERR(*conv);
+      *conv_end = *conv + len;
+      conv_swap4bytes(s, end, *conv);
+      return 0;
+    }
+  }
+  else if (to == ONIG_ENCODING_UTF32_LE) {
+    if (from == ONIG_ENCODING_ASCII || from == ONIG_ENCODING_ISO_8859_1) {
+      *conv = (UChar* )xmalloc(len * 4);
+      CHECK_NULL_RETURN_MEMERR(*conv);
+      *conv_end = *conv + (len * 4);
+      conv_ext0le32(s, end, *conv);
+      return 0;
+    }
+    else if (from == ONIG_ENCODING_UTF32_BE) {
+      goto swap32;
+    }
+  }
+
+  return ONIGERR_NOT_SUPPORTED_ENCODING_COMBINATION;
+}
+
+extern int
+onig_new_deluxe(regex_t** reg, const UChar* pattern, const UChar* pattern_end,
+                OnigCompileInfo* ci, OnigErrorInfo* einfo)
+{
+  int r;
+  UChar *cpat, *cpat_end;
+
+  if (IS_NOT_NULL(einfo)) einfo->par = (UChar* )NULL;
+
+  if (ci->pattern_enc != ci->target_enc) {
+    r = conv_encoding(ci->pattern_enc, ci->target_enc, pattern, pattern_end,
+                      &cpat, &cpat_end);
+    if (r) return r;
+  }
+  else {
+    cpat     = (UChar* )pattern;
+    cpat_end = (UChar* )pattern_end;
+  }
+
+  *reg = (regex_t* )xmalloc(sizeof(regex_t));
+  if (IS_NULL(*reg)) {
+    r = ONIGERR_MEMORY;
+    goto err2;
+  }
+
+  r = onig_reg_init(*reg, ci->option, ci->case_fold_flag, ci->target_enc,
+		    ci->syntax);
+  if (r) goto err;
+
+  r = onig_compile(*reg, cpat, cpat_end, einfo);
+  if (r) {
+  err:
+    onig_free(*reg);
+    *reg = NULL;
+  }
+
+ err2:
+  if (cpat != pattern) xfree(cpat);
+
+  return r;
+}
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/reggnu.c
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/reggnu.c	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/reggnu.c	(revision 331)
@@ -0,0 +1,146 @@
+/**********************************************************************
+  reggnu.c -  Onigmo (Oniguruma-mod) (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2008  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011-2016  K.Takata  <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "regint.h"
+
+#ifndef ONIGMOGNU_H
+# include "onigmognu.h"
+#endif
+
+extern void
+re_free_registers(OnigRegion* r)
+{
+  /* 0: don't free self */
+  onig_region_free(r, 0);
+}
+
+extern int
+re_adjust_startpos(regex_t* reg, const char* string, int size,
+		   int startpos, int range)
+{
+  if (startpos > 0 && ONIGENC_MBC_MAXLEN(reg->enc) != 1 && startpos < size) {
+    UChar *p;
+    UChar *s = (UChar* )string + startpos;
+    UChar *e = (UChar* )string + size;
+
+    if (range > 0) {
+      p = onigenc_get_right_adjust_char_head(reg->enc, (UChar* )string, s, e);
+    }
+    else {
+      p = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, (UChar* )string, s, e);
+    }
+    return (int )(p - (UChar* )string);
+  }
+
+  return startpos;
+}
+
+extern int
+re_match(regex_t* reg, const char* str, int size, int pos,
+	 struct re_registers* regs)
+{
+  return (int )onig_match(reg, (UChar* )str, (UChar* )(str + size),
+		    (UChar* )(str + pos), regs, ONIG_OPTION_NONE);
+}
+
+extern int
+re_search(regex_t* bufp, const char* string, int size, int startpos, int range,
+	  struct re_registers* regs)
+{
+  return (int )onig_search(bufp, (UChar* )string, (UChar* )(string + size),
+		     (UChar* )(string + startpos),
+		     (UChar* )(string + startpos + range),
+		     regs, ONIG_OPTION_NONE);
+}
+
+extern int
+re_compile_pattern(const char* pattern, int size, regex_t* reg, char* ebuf)
+{
+  int r;
+  OnigErrorInfo einfo;
+
+  r = onig_compile(reg, (UChar* )pattern, (UChar* )(pattern + size), &einfo);
+  if (r != ONIG_NORMAL) {
+    if (IS_NOT_NULL(ebuf))
+      (void )onig_error_code_to_str((UChar* )ebuf, r, &einfo);
+  }
+
+  return r;
+}
+
+extern void
+re_free_pattern(regex_t* reg)
+{
+  onig_free(reg);
+}
+
+extern int
+re_alloc_pattern(regex_t** reg)
+{
+  *reg = (regex_t* )xmalloc(sizeof(regex_t));
+  if (IS_NULL(*reg)) return ONIGERR_MEMORY;
+
+  return onig_reg_init(*reg, ONIG_OPTION_DEFAULT,
+		       ONIGENC_CASE_FOLD_DEFAULT,
+		       OnigEncDefaultCharEncoding,
+		       OnigDefaultSyntax);
+}
+
+extern void
+re_set_casetable(const char* table)
+{
+  /* onigenc_set_default_caseconv_table((UChar* )table); */
+}
+
+extern void
+re_mbcinit(int mb_code)
+{
+  OnigEncoding enc;
+
+  switch (mb_code) {
+  case RE_MBCTYPE_ASCII:
+    enc = ONIG_ENCODING_ASCII;
+    break;
+  case RE_MBCTYPE_EUC:
+    enc = ONIG_ENCODING_EUC_JP;
+    break;
+  case RE_MBCTYPE_SJIS:
+    enc = ONIG_ENCODING_SJIS;
+    break;
+  case RE_MBCTYPE_UTF8:
+    enc = ONIG_ENCODING_UTF8;
+    break;
+  default:
+    return ;
+    break;
+  }
+
+  onigenc_set_default_encoding(enc);
+}
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/regint.h
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/regint.h	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/regint.h	(revision 331)
@@ -0,0 +1,938 @@
+#ifndef ONIGMO_REGINT_H
+#define ONIGMO_REGINT_H
+/**********************************************************************
+  regint.h -  Onigmo (Oniguruma-mod) (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2013  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011-2016  K.Takata  <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* for debug */
+/* #define ONIG_DEBUG_PARSE_TREE */
+/* #define ONIG_DEBUG_COMPILE */
+/* #define ONIG_DEBUG_SEARCH */
+/* #define ONIG_DEBUG_MATCH */
+/* #define ONIG_DEBUG_MEMLEAK */
+/* #define ONIG_DONT_OPTIMIZE */
+
+/* for byte-code statistical data. */
+/* #define ONIG_DEBUG_STATISTICS */
+
+#if defined(ONIG_DEBUG_PARSE_TREE) || defined(ONIG_DEBUG_MATCH) || \
+    defined(ONIG_DEBUG_SEARCH) || defined(ONIG_DEBUG_COMPILE) || \
+    defined(ONIG_DEBUG_STATISTICS) || defined(ONIG_DEBUG_MEMLEAK)
+# ifndef ONIG_DEBUG
+#  define ONIG_DEBUG
+# endif
+#endif
+
+#ifndef UNALIGNED_WORD_ACCESS
+# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
+     defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || \
+     defined(__powerpc64__) || \
+     defined(__mc68020__)
+#  define UNALIGNED_WORD_ACCESS 1
+# else
+#  define UNALIGNED_WORD_ACCESS 0
+# endif
+#endif
+
+#if UNALIGNED_WORD_ACCESS
+# define PLATFORM_UNALIGNED_WORD_ACCESS
+#endif
+
+/* config */
+/* spec. config */
+#define USE_NAMED_GROUP
+#define USE_SUBEXP_CALL
+#define USE_PERL_SUBEXP_CALL
+#define USE_CAPITAL_P_NAMED_GROUP
+#define USE_BACKREF_WITH_LEVEL        /* \k<name+n>, \k<name-n> */
+#define USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT  /* /(?:()|())*\2/ */
+#define USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE     /* /\n$/ =~ "\n" */
+#define USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR
+/* !!! moved to regenc.h. */ /* #define USE_CRNL_AS_LINE_TERMINATOR */
+#define USE_NO_INVALID_QUANTIFIER
+
+/* internal config */
+/* #define USE_OP_PUSH_OR_JUMP_EXACT */
+#define USE_QTFR_PEEK_NEXT
+#define USE_ST_LIBRARY
+#define USE_SUNDAY_QUICK_SEARCH
+
+#define INIT_MATCH_STACK_SIZE                     160
+#define DEFAULT_MATCH_STACK_LIMIT_SIZE              0 /* unlimited */
+#define DEFAULT_PARSE_DEPTH_LIMIT                4096
+
+#define OPT_EXACT_MAXLEN   24
+
+/* check config */
+#if defined(USE_PERL_SUBEXP_CALL) || defined(USE_CAPITAL_P_NAMED_GROUP)
+# if !defined(USE_NAMED_GROUP) || !defined(USE_SUBEXP_CALL)
+#  error USE_NAMED_GROUP and USE_SUBEXP_CALL must be defined.
+# endif
+#endif
+
+#if defined(__GNUC__)
+# define ARG_UNUSED  __attribute__ ((unused))
+#else
+# define ARG_UNUSED
+#endif
+
+#if !defined(RUBY) && defined(RUBY_EXPORT)
+# define RUBY
+#endif
+#ifdef RUBY
+# ifndef RUBY_DEFINES_H
+#  include "ruby/ruby.h"
+#  undef xmalloc
+#  undef xrealloc
+#  undef xcalloc
+#  undef xfree
+# endif
+#else /* RUBY */
+# include "config.h"
+# if SIZEOF_LONG_LONG > 0
+#  define LONG_LONG long long
+# endif
+#endif /* RUBY */
+
+#include <stdarg.h>
+
+/* */
+/* escape other system UChar definition */
+#ifdef ONIG_ESCAPE_UCHAR_COLLISION
+# undef ONIG_ESCAPE_UCHAR_COLLISION
+#endif
+
+#define USE_WORD_BEGIN_END          /* "\<": word-begin, "\>": word-end */
+#ifdef RUBY
+# undef USE_CAPTURE_HISTORY
+#else
+# define USE_CAPTURE_HISTORY
+#endif
+#define USE_VARIABLE_META_CHARS
+#define USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
+/* #define USE_COMBINATION_EXPLOSION_CHECK */     /* (X*)* */
+
+
+#ifndef xmalloc
+# define xmalloc     malloc
+# define xrealloc    realloc
+# define xcalloc     calloc
+# define xfree       free
+#endif
+
+#ifdef RUBY
+
+# define CHECK_INTERRUPT_IN_MATCH_AT rb_thread_check_ints()
+# define onig_st_init_table                  st_init_table
+# define onig_st_init_table_with_size        st_init_table_with_size
+# define onig_st_init_numtable               st_init_numtable
+# define onig_st_init_numtable_with_size     st_init_numtable_with_size
+# define onig_st_init_strtable               st_init_strtable
+# define onig_st_init_strtable_with_size     st_init_strtable_with_size
+# define onig_st_delete                      st_delete
+# define onig_st_delete_safe                 st_delete_safe
+# define onig_st_insert                      st_insert
+# define onig_st_lookup                      st_lookup
+# define onig_st_foreach                     st_foreach
+# define onig_st_add_direct                  st_add_direct
+# define onig_st_free_table                  st_free_table
+# define onig_st_cleanup_safe                st_cleanup_safe
+# define onig_st_copy                        st_copy
+# define onig_st_nothing_key_clone           st_nothing_key_clone
+# define onig_st_nothing_key_free            st_nothing_key_free
+# define onig_st_is_member                   st_is_member
+
+# define USE_UPPER_CASE_TABLE
+#else /* RUBY */
+
+# define CHECK_INTERRUPT_IN_MATCH_AT
+
+# define st_init_table                  onig_st_init_table
+# define st_init_table_with_size        onig_st_init_table_with_size
+# define st_init_numtable               onig_st_init_numtable
+# define st_init_numtable_with_size     onig_st_init_numtable_with_size
+# define st_init_strtable               onig_st_init_strtable
+# define st_init_strtable_with_size     onig_st_init_strtable_with_size
+# define st_delete                      onig_st_delete
+# define st_delete_safe                 onig_st_delete_safe
+# define st_insert                      onig_st_insert
+# define st_lookup                      onig_st_lookup
+# define st_foreach                     onig_st_foreach
+# define st_add_direct                  onig_st_add_direct
+# define st_free_table                  onig_st_free_table
+# define st_cleanup_safe                onig_st_cleanup_safe
+# define st_copy                        onig_st_copy
+# define st_nothing_key_clone           onig_st_nothing_key_clone
+# define st_nothing_key_free            onig_st_nothing_key_free
+/* */
+# define onig_st_is_member              st_is_member
+
+#endif /* RUBY */
+
+#define STATE_CHECK_STRING_THRESHOLD_LEN             7
+#define STATE_CHECK_BUFF_MAX_SIZE               0x4000
+
+#define xmemset     memset
+#define xmemcpy     memcpy
+#define xmemmove    memmove
+
+#if ((defined(RUBY_MSVCRT_VERSION) && RUBY_MSVCRT_VERSION >= 90) \
+        || (!defined(RUBY_MSVCRT_VERSION) && defined(_WIN32))) \
+    && !defined(__GNUC__)
+# define xalloca     _alloca
+# define xvsnprintf(buf,size,fmt,args)  _vsnprintf_s(buf,size,_TRUNCATE,fmt,args)
+# define xsnprintf   sprintf_s
+# define xstrcat(dest,src,size)   strcat_s(dest,size,src)
+#else
+# define xalloca     alloca
+# define xvsnprintf  vsnprintf
+# define xsnprintf   snprintf
+# define xstrcat(dest,src,size)	  strcat(dest,src)
+#endif
+
+#if defined(ONIG_DEBUG_MEMLEAK) && defined(_MSC_VER)
+# define _CRTDBG_MAP_ALLOC
+# include <malloc.h>
+# include <crtdbg.h>
+#endif
+
+#include <stdlib.h>
+
+#if defined(HAVE_ALLOCA_H) && (defined(_AIX) || !defined(__GNUC__))
+# include <alloca.h>
+#endif
+
+#include <string.h>
+
+#include <ctype.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+
+#include <stddef.h>
+
+#ifdef _WIN32
+# include <malloc.h>	/* for alloca() */
+#endif
+
+#ifdef ONIG_DEBUG
+# include <stdio.h>
+#endif
+
+#ifdef _WIN32
+# if defined(_MSC_VER) && (_MSC_VER < 1300)
+#  ifndef _INTPTR_T_DEFINED
+#   define _INTPTR_T_DEFINED
+typedef int intptr_t;
+#  endif
+#  ifndef _UINTPTR_T_DEFINED
+#   define _UINTPTR_T_DEFINED
+typedef unsigned int uintptr_t;
+#  endif
+# endif
+#endif /* _WIN32 */
+
+#ifndef PRIdPTR
+# ifdef _WIN64
+#  define PRIdPTR	"I64d"
+#  define PRIuPTR	"I64u"
+#  define PRIxPTR	"I64x"
+# else
+#  define PRIdPTR	"ld"
+#  define PRIuPTR	"lu"
+#  define PRIxPTR	"lx"
+# endif
+#endif
+
+#ifndef PRIdPTRDIFF
+# define PRIdPTRDIFF PRIdPTR
+#endif
+
+#include "regenc.h"
+
+RUBY_SYMBOL_EXPORT_BEGIN
+
+#ifdef MIN
+# undef MIN
+#endif
+#ifdef MAX
+# undef MAX
+#endif
+#define MIN(a,b) (((a)>(b))?(b):(a))
+#define MAX(a,b) (((a)<(b))?(b):(a))
+
+#define IS_NULL(p)                    (((void*)(p)) == (void*)0)
+#define IS_NOT_NULL(p)                (((void*)(p)) != (void*)0)
+#define CHECK_NULL_RETURN(p)          if (IS_NULL(p)) return NULL
+#define CHECK_NULL_RETURN_MEMERR(p)   if (IS_NULL(p)) return ONIGERR_MEMORY
+#define NULL_UCHARP                   ((UChar* )0)
+
+#define ONIG_LAST_CODE_POINT    (~((OnigCodePoint )0))
+
+#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
+
+# define PLATFORM_GET_INC(val,p,type) do{\
+  val  = *(type* )p;\
+  (p) += sizeof(type);\
+} while(0)
+
+#else
+
+# define PLATFORM_GET_INC(val,p,type) do{\
+  xmemcpy(&val, (p), sizeof(type));\
+  (p) += sizeof(type);\
+} while(0)
+
+/* sizeof(OnigCodePoint) */
+# define WORD_ALIGNMENT_SIZE     SIZEOF_LONG
+
+# define GET_ALIGNMENT_PAD_SIZE(addr,pad_size) do {\
+  (pad_size) = WORD_ALIGNMENT_SIZE \
+               - ((uintptr_t )(addr) % WORD_ALIGNMENT_SIZE);\
+  if ((pad_size) == WORD_ALIGNMENT_SIZE) (pad_size) = 0;\
+} while (0)
+
+# define ALIGNMENT_RIGHT(addr) do {\
+  (addr) += (WORD_ALIGNMENT_SIZE - 1);\
+  (addr) -= ((uintptr_t )(addr) % WORD_ALIGNMENT_SIZE);\
+} while (0)
+
+#endif /* PLATFORM_UNALIGNED_WORD_ACCESS */
+
+/* stack pop level */
+#define STACK_POP_LEVEL_FREE        0
+#define STACK_POP_LEVEL_MEM_START   1
+#define STACK_POP_LEVEL_ALL         2
+
+/* optimize flags */
+#define ONIG_OPTIMIZE_NONE              0
+#define ONIG_OPTIMIZE_EXACT             1   /* Slow Search */
+#define ONIG_OPTIMIZE_EXACT_BM          2   /* Boyer Moore Search */
+#define ONIG_OPTIMIZE_EXACT_BM_NOT_REV  3   /* BM (applied to a multibyte string) */
+#define ONIG_OPTIMIZE_EXACT_IC          4   /* Slow Search (ignore case) */
+#define ONIG_OPTIMIZE_MAP               5   /* char map */
+#define ONIG_OPTIMIZE_EXACT_BM_IC         6 /* BM (ignore case) */
+#define ONIG_OPTIMIZE_EXACT_BM_NOT_REV_IC 7 /* BM (applied to a multibyte string) (ignore case) */
+
+/* bit status */
+typedef unsigned int  BitStatusType;
+
+#define BIT_STATUS_BITS_NUM          (sizeof(BitStatusType) * 8)
+#define BIT_STATUS_CLEAR(stats)      (stats) = 0
+#define BIT_STATUS_ON_ALL(stats)     (stats) = ~((BitStatusType )0)
+#define BIT_STATUS_AT(stats,n) \
+  ((n) < (int )BIT_STATUS_BITS_NUM  ?  ((stats) & ((BitStatusType )1 << n)) : ((stats) & 1))
+
+#define BIT_STATUS_ON_AT(stats,n) do {\
+  if ((n) < (int )BIT_STATUS_BITS_NUM)\
+    (stats) |= (1 << (n));\
+  else\
+    (stats) |= 1;\
+} while (0)
+
+#define BIT_STATUS_ON_AT_SIMPLE(stats,n) do {\
+  if ((n) < (int )BIT_STATUS_BITS_NUM)\
+    (stats) |= (1 << (n));\
+} while (0)
+
+
+#define INT_MAX_LIMIT           ((1UL << (SIZEOF_INT * 8 - 1)) - 1)
+
+#define DIGITVAL(code)    ((code) - '0')
+#define ODIGITVAL(code)   DIGITVAL(code)
+#define XDIGITVAL(enc,code) \
+  (ONIGENC_IS_CODE_DIGIT(enc,code) ? DIGITVAL(code) \
+   : (ONIGENC_IS_CODE_UPPER(enc,code) ? (code) - 'A' + 10 : (code) - 'a' + 10))
+
+#define IS_SINGLELINE(option)     ((option) & ONIG_OPTION_SINGLELINE)
+#define IS_MULTILINE(option)      ((option) & ONIG_OPTION_MULTILINE)
+#define IS_IGNORECASE(option)     ((option) & ONIG_OPTION_IGNORECASE)
+#define IS_EXTEND(option)         ((option) & ONIG_OPTION_EXTEND)
+#define IS_FIND_LONGEST(option)   ((option) & ONIG_OPTION_FIND_LONGEST)
+#define IS_FIND_NOT_EMPTY(option) ((option) & ONIG_OPTION_FIND_NOT_EMPTY)
+#define IS_FIND_CONDITION(option) ((option) & \
+          (ONIG_OPTION_FIND_LONGEST | ONIG_OPTION_FIND_NOT_EMPTY))
+#define IS_NOTBOL(option)         ((option) & ONIG_OPTION_NOTBOL)
+#define IS_NOTEOL(option)         ((option) & ONIG_OPTION_NOTEOL)
+#define IS_NOTBOS(option)         ((option) & ONIG_OPTION_NOTBOS)
+#define IS_NOTEOS(option)         ((option) & ONIG_OPTION_NOTEOS)
+#define IS_ASCII_RANGE(option)    ((option) & ONIG_OPTION_ASCII_RANGE)
+#define IS_POSIX_BRACKET_ALL_RANGE(option)  ((option) & ONIG_OPTION_POSIX_BRACKET_ALL_RANGE)
+#define IS_WORD_BOUND_ALL_RANGE(option)     ((option) & ONIG_OPTION_WORD_BOUND_ALL_RANGE)
+#define IS_NEWLINE_CRLF(option)   ((option) & ONIG_OPTION_NEWLINE_CRLF)
+
+/* OP_SET_OPTION is required for these options.
+#define IS_DYNAMIC_OPTION(option) \
+  (((option) & (ONIG_OPTION_MULTILINE | ONIG_OPTION_IGNORECASE)) != 0)
+*/
+/* ignore-case and multibyte status are included in compiled code. */
+#define IS_DYNAMIC_OPTION(option)  0
+
+#define DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag) \
+  ((case_fold_flag) & ~INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR)
+
+#define REPEAT_INFINITE         -1
+#define IS_REPEAT_INFINITE(n)   ((n) == REPEAT_INFINITE)
+
+/* bitset */
+#define BITS_PER_BYTE      8
+#define SINGLE_BYTE_SIZE   (1 << BITS_PER_BYTE)
+#define BITS_IN_ROOM       ((int )sizeof(Bits) * BITS_PER_BYTE)
+#define BITSET_SIZE        (SINGLE_BYTE_SIZE / BITS_IN_ROOM)
+
+#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
+typedef unsigned int   Bits;
+#else
+typedef unsigned char  Bits;
+#endif
+typedef Bits           BitSet[BITSET_SIZE];
+typedef Bits*          BitSetRef;
+
+#define SIZE_BITSET        (int )sizeof(BitSet)
+
+#define BITSET_CLEAR(bs) do {\
+  int i;\
+  for (i = 0; i < BITSET_SIZE; i++) { (bs)[i] = 0; }	\
+} while (0)
+
+#define BS_ROOM(bs,pos)            (bs)[(int )(pos) / BITS_IN_ROOM]
+#define BS_BIT(pos)                (1U << ((int )(pos) % BITS_IN_ROOM))
+
+#define BITSET_AT(bs, pos)         (BS_ROOM(bs,pos) & BS_BIT(pos))
+#define BITSET_SET_BIT(bs, pos)     BS_ROOM(bs,pos) |= BS_BIT(pos)
+#define BITSET_CLEAR_BIT(bs, pos)   BS_ROOM(bs,pos) &= ~(BS_BIT(pos))
+#define BITSET_INVERT_BIT(bs, pos)  BS_ROOM(bs,pos) ^= BS_BIT(pos)
+
+/* bytes buffer */
+typedef struct _BBuf {
+  UChar* p;
+  unsigned int used;
+  unsigned int alloc;
+} BBuf;
+
+#define BBUF_INIT(buf,size)    onig_bbuf_init((BBuf* )(buf), (size))
+
+#define BBUF_SIZE_INC(buf,inc) do{\
+  UChar *tmp;\
+  (buf)->alloc += (inc);\
+  tmp = (UChar* )xrealloc((buf)->p, (buf)->alloc);\
+  if (IS_NULL(tmp)) return(ONIGERR_MEMORY);\
+  (buf)->p = tmp;\
+} while (0)
+
+#define BBUF_EXPAND(buf,low) do{\
+  UChar *tmp;\
+  do { (buf)->alloc *= 2; } while ((buf)->alloc < (unsigned int )low);\
+  tmp = (UChar* )xrealloc((buf)->p, (buf)->alloc);\
+  if (IS_NULL(tmp)) return(ONIGERR_MEMORY);\
+  (buf)->p = tmp;\
+} while (0)
+
+#define BBUF_ENSURE_SIZE(buf,size) do{\
+  unsigned int new_alloc = (buf)->alloc;\
+  while (new_alloc < (unsigned int )(size)) { new_alloc *= 2; }\
+  if ((buf)->alloc != new_alloc) {\
+    UChar *tmp;\
+    tmp = (UChar* )xrealloc((buf)->p, new_alloc);\
+    if (IS_NULL(tmp)) return(ONIGERR_MEMORY);\
+    (buf)->p = tmp;\
+    (buf)->alloc = new_alloc;\
+  }\
+} while (0)
+
+#define BBUF_WRITE(buf,pos,bytes,n) do{\
+  int used = (pos) + (int )(n);\
+  if ((buf)->alloc < (unsigned int )used) BBUF_EXPAND((buf),used);\
+  xmemcpy((buf)->p + (pos), (bytes), (n));\
+  if ((buf)->used < (unsigned int )used) (buf)->used = used;\
+} while (0)
+
+#define BBUF_WRITE1(buf,pos,byte) do{\
+  int used = (pos) + 1;\
+  if ((buf)->alloc < (unsigned int )used) BBUF_EXPAND((buf),used);\
+  (buf)->p[(pos)] = (UChar )(byte);\
+  if ((buf)->used < (unsigned int )used) (buf)->used = used;\
+} while (0)
+
+#define BBUF_ADD(buf,bytes,n)       BBUF_WRITE((buf),(buf)->used,(bytes),(n))
+#define BBUF_ADD1(buf,byte)         BBUF_WRITE1((buf),(buf)->used,(byte))
+#define BBUF_GET_ADD_ADDRESS(buf)   ((buf)->p + (buf)->used)
+#define BBUF_GET_OFFSET_POS(buf)    ((buf)->used)
+
+/* from < to */
+#define BBUF_MOVE_RIGHT(buf,from,to,n) do {\
+  if ((unsigned int )((to)+(n)) > (buf)->alloc) BBUF_EXPAND((buf),(to) + (n));\
+  xmemmove((buf)->p + (to), (buf)->p + (from), (n));\
+  if ((unsigned int )((to)+(n)) > (buf)->used) (buf)->used = (to) + (n);\
+} while (0)
+
+/* from > to */
+#define BBUF_MOVE_LEFT(buf,from,to,n) do {\
+  xmemmove((buf)->p + (to), (buf)->p + (from), (n));\
+} while (0)
+
+/* from > to */
+#define BBUF_MOVE_LEFT_REDUCE(buf,from,to) do {\
+  xmemmove((buf)->p + (to), (buf)->p + (from), (buf)->used - (from));\
+  (buf)->used -= (from - to);\
+} while (0)
+
+#define BBUF_INSERT(buf,pos,bytes,n) do {\
+  if (pos >= (buf)->used) {\
+    BBUF_WRITE(buf,pos,bytes,n);\
+  }\
+  else {\
+    BBUF_MOVE_RIGHT((buf),(pos),(pos) + (n),((buf)->used - (pos)));\
+    xmemcpy((buf)->p + (pos), (bytes), (n));\
+  }\
+} while (0)
+
+#define BBUF_GET_BYTE(buf, pos) (buf)->p[(pos)]
+
+
+#define ANCHOR_BEGIN_BUF        (1<<0)
+#define ANCHOR_BEGIN_LINE       (1<<1)
+#define ANCHOR_BEGIN_POSITION   (1<<2)
+#define ANCHOR_END_BUF          (1<<3)
+#define ANCHOR_SEMI_END_BUF     (1<<4)
+#define ANCHOR_END_LINE         (1<<5)
+
+#define ANCHOR_WORD_BOUND       (1<<6)
+#define ANCHOR_NOT_WORD_BOUND   (1<<7)
+#define ANCHOR_WORD_BEGIN       (1<<8)
+#define ANCHOR_WORD_END         (1<<9)
+#define ANCHOR_PREC_READ        (1<<10)
+#define ANCHOR_PREC_READ_NOT    (1<<11)
+#define ANCHOR_LOOK_BEHIND      (1<<12)
+#define ANCHOR_LOOK_BEHIND_NOT  (1<<13)
+
+#define ANCHOR_ANYCHAR_STAR     (1<<14)   /* ".*" optimize info */
+#define ANCHOR_ANYCHAR_STAR_ML  (1<<15)   /* ".*" optimize info (multi-line) */
+
+#define ANCHOR_KEEP             (1<<16)
+
+/* operation code */
+enum OpCode {
+  OP_FINISH = 0,        /* matching process terminator (no more alternative) */
+  OP_END    = 1,        /* pattern code terminator (success end) */
+
+  OP_EXACT1 = 2,        /* single byte, N = 1 */
+  OP_EXACT2,            /* single byte, N = 2 */
+  OP_EXACT3,            /* single byte, N = 3 */
+  OP_EXACT4,            /* single byte, N = 4 */
+  OP_EXACT5,            /* single byte, N = 5 */
+  OP_EXACTN,            /* single byte */
+  OP_EXACTMB2N1,        /* mb-length = 2 N = 1 */
+  OP_EXACTMB2N2,        /* mb-length = 2 N = 2 */
+  OP_EXACTMB2N3,        /* mb-length = 2 N = 3 */
+  OP_EXACTMB2N,         /* mb-length = 2 */
+  OP_EXACTMB3N,         /* mb-length = 3 */
+  OP_EXACTMBN,          /* other length */
+
+  OP_EXACT1_IC,         /* single byte, N = 1, ignore case */
+  OP_EXACTN_IC,         /* single byte,        ignore case */
+
+  OP_CCLASS,
+  OP_CCLASS_MB,
+  OP_CCLASS_MIX,
+  OP_CCLASS_NOT,
+  OP_CCLASS_MB_NOT,
+  OP_CCLASS_MIX_NOT,
+
+  OP_ANYCHAR,                 /* "."  */
+  OP_ANYCHAR_ML,              /* "."  multi-line */
+  OP_ANYCHAR_STAR,            /* ".*" */
+  OP_ANYCHAR_ML_STAR,         /* ".*" multi-line */
+  OP_ANYCHAR_STAR_PEEK_NEXT,
+  OP_ANYCHAR_ML_STAR_PEEK_NEXT,
+
+  OP_WORD,
+  OP_NOT_WORD,
+  OP_WORD_BOUND,
+  OP_NOT_WORD_BOUND,
+  OP_WORD_BEGIN,
+  OP_WORD_END,
+
+  OP_ASCII_WORD,
+  OP_NOT_ASCII_WORD,
+  OP_ASCII_WORD_BOUND,
+  OP_NOT_ASCII_WORD_BOUND,
+  OP_ASCII_WORD_BEGIN,
+  OP_ASCII_WORD_END,
+
+  OP_BEGIN_BUF,
+  OP_END_BUF,
+  OP_BEGIN_LINE,
+  OP_END_LINE,
+  OP_SEMI_END_BUF,
+  OP_BEGIN_POSITION,
+
+  OP_BACKREF1,
+  OP_BACKREF2,
+  OP_BACKREFN,
+  OP_BACKREFN_IC,
+  OP_BACKREF_MULTI,
+  OP_BACKREF_MULTI_IC,
+  OP_BACKREF_WITH_LEVEL,    /* \k<xxx+n>, \k<xxx-n> */
+
+  OP_MEMORY_START,
+  OP_MEMORY_START_PUSH,   /* push back-tracker to stack */
+  OP_MEMORY_END_PUSH,     /* push back-tracker to stack */
+  OP_MEMORY_END_PUSH_REC, /* push back-tracker to stack */
+  OP_MEMORY_END,
+  OP_MEMORY_END_REC,      /* push marker to stack */
+
+  OP_KEEP,
+
+  OP_FAIL,               /* pop stack and move */
+  OP_JUMP,
+  OP_PUSH,
+  OP_POP,
+  OP_PUSH_OR_JUMP_EXACT1,  /* if match exact then push, else jump. */
+  OP_PUSH_IF_PEEK_NEXT,    /* if match exact then push, else none. */
+  OP_REPEAT,               /* {n,m} */
+  OP_REPEAT_NG,            /* {n,m}? (non greedy) */
+  OP_REPEAT_INC,
+  OP_REPEAT_INC_NG,        /* non greedy */
+  OP_REPEAT_INC_SG,        /* search and get in stack */
+  OP_REPEAT_INC_NG_SG,     /* search and get in stack (non greedy) */
+  OP_NULL_CHECK_START,     /* null loop checker start */
+  OP_NULL_CHECK_END,       /* null loop checker end   */
+  OP_NULL_CHECK_END_MEMST, /* null loop checker end (with capture status) */
+  OP_NULL_CHECK_END_MEMST_PUSH, /* with capture status and push check-end */
+
+  OP_PUSH_POS,             /* (?=...)  start */
+  OP_POP_POS,              /* (?=...)  end   */
+  OP_PUSH_POS_NOT,         /* (?!...)  start */
+  OP_FAIL_POS,             /* (?!...)  end   */
+  OP_PUSH_STOP_BT,         /* (?>...)  start */
+  OP_POP_STOP_BT,          /* (?>...)  end   */
+  OP_LOOK_BEHIND,          /* (?<=...) start (no needs end opcode) */
+  OP_PUSH_LOOK_BEHIND_NOT, /* (?<!...) start */
+  OP_FAIL_LOOK_BEHIND_NOT, /* (?<!...) end   */
+  OP_PUSH_ABSENT_POS,      /* (?~...)  start */
+  OP_ABSENT,               /* (?~...)  start of inner loop */
+  OP_ABSENT_END,           /* (?~...)  end   */
+
+  OP_CALL,                 /* \g<name> */
+  OP_RETURN,
+
+  OP_CONDITION,
+
+  OP_STATE_CHECK_PUSH,         /* combination explosion check and push */
+  OP_STATE_CHECK_PUSH_OR_JUMP, /* check ok -> push, else jump  */
+  OP_STATE_CHECK,              /* check only */
+  OP_STATE_CHECK_ANYCHAR_STAR,
+  OP_STATE_CHECK_ANYCHAR_ML_STAR,
+
+  /* no need: IS_DYNAMIC_OPTION() == 0 */
+  OP_SET_OPTION_PUSH,    /* set option and push recover option */
+  OP_SET_OPTION          /* set option */
+};
+
+typedef int RelAddrType;
+typedef int AbsAddrType;
+typedef int LengthType;
+typedef int RepeatNumType;
+typedef short int MemNumType;
+typedef short int StateCheckNumType;
+typedef void* PointerType;
+
+#define SIZE_OPCODE           1
+#define SIZE_RELADDR          (int )sizeof(RelAddrType)
+#define SIZE_ABSADDR          (int )sizeof(AbsAddrType)
+#define SIZE_LENGTH           (int )sizeof(LengthType)
+#define SIZE_MEMNUM           (int )sizeof(MemNumType)
+#define SIZE_STATE_CHECK_NUM  (int )sizeof(StateCheckNumType)
+#define SIZE_REPEATNUM        (int )sizeof(RepeatNumType)
+#define SIZE_OPTION           (int )sizeof(OnigOptionType)
+#define SIZE_CODE_POINT       (int )sizeof(OnigCodePoint)
+#define SIZE_POINTER          (int )sizeof(PointerType)
+
+
+#define GET_RELADDR_INC(addr,p)    PLATFORM_GET_INC(addr,   p, RelAddrType)
+#define GET_ABSADDR_INC(addr,p)    PLATFORM_GET_INC(addr,   p, AbsAddrType)
+#define GET_LENGTH_INC(len,p)      PLATFORM_GET_INC(len,    p, LengthType)
+#define GET_MEMNUM_INC(num,p)      PLATFORM_GET_INC(num,    p, MemNumType)
+#define GET_REPEATNUM_INC(num,p)   PLATFORM_GET_INC(num,    p, RepeatNumType)
+#define GET_OPTION_INC(option,p)   PLATFORM_GET_INC(option, p, OnigOptionType)
+#define GET_POINTER_INC(ptr,p)     PLATFORM_GET_INC(ptr,    p, PointerType)
+#define GET_STATE_CHECK_NUM_INC(num,p)  PLATFORM_GET_INC(num, p, StateCheckNumType)
+
+/* code point's address must be aligned address. */
+#define GET_CODE_POINT(code,p)   code = *((OnigCodePoint* )(p))
+#define GET_BYTE_INC(byte,p) do{\
+  byte = *(p);\
+  (p)++;\
+} while(0)
+
+
+/* op-code + arg size */
+#define SIZE_OP_ANYCHAR_STAR            SIZE_OPCODE
+#define SIZE_OP_ANYCHAR_STAR_PEEK_NEXT (SIZE_OPCODE + 1)
+#define SIZE_OP_JUMP                   (SIZE_OPCODE + SIZE_RELADDR)
+#define SIZE_OP_PUSH                   (SIZE_OPCODE + SIZE_RELADDR)
+#define SIZE_OP_POP                     SIZE_OPCODE
+#define SIZE_OP_PUSH_OR_JUMP_EXACT1    (SIZE_OPCODE + SIZE_RELADDR + 1)
+#define SIZE_OP_PUSH_IF_PEEK_NEXT      (SIZE_OPCODE + SIZE_RELADDR + 1)
+#define SIZE_OP_REPEAT_INC             (SIZE_OPCODE + SIZE_MEMNUM)
+#define SIZE_OP_REPEAT_INC_NG          (SIZE_OPCODE + SIZE_MEMNUM)
+#define SIZE_OP_PUSH_POS                SIZE_OPCODE
+#define SIZE_OP_PUSH_POS_NOT           (SIZE_OPCODE + SIZE_RELADDR)
+#define SIZE_OP_POP_POS                 SIZE_OPCODE
+#define SIZE_OP_FAIL_POS                SIZE_OPCODE
+#define SIZE_OP_SET_OPTION             (SIZE_OPCODE + SIZE_OPTION)
+#define SIZE_OP_SET_OPTION_PUSH        (SIZE_OPCODE + SIZE_OPTION)
+#define SIZE_OP_FAIL                    SIZE_OPCODE
+#define SIZE_OP_MEMORY_START           (SIZE_OPCODE + SIZE_MEMNUM)
+#define SIZE_OP_MEMORY_START_PUSH      (SIZE_OPCODE + SIZE_MEMNUM)
+#define SIZE_OP_MEMORY_END_PUSH        (SIZE_OPCODE + SIZE_MEMNUM)
+#define SIZE_OP_MEMORY_END_PUSH_REC    (SIZE_OPCODE + SIZE_MEMNUM)
+#define SIZE_OP_MEMORY_END             (SIZE_OPCODE + SIZE_MEMNUM)
+#define SIZE_OP_MEMORY_END_REC         (SIZE_OPCODE + SIZE_MEMNUM)
+#define SIZE_OP_PUSH_STOP_BT            SIZE_OPCODE
+#define SIZE_OP_POP_STOP_BT             SIZE_OPCODE
+#define SIZE_OP_NULL_CHECK_START       (SIZE_OPCODE + SIZE_MEMNUM)
+#define SIZE_OP_NULL_CHECK_END         (SIZE_OPCODE + SIZE_MEMNUM)
+#define SIZE_OP_LOOK_BEHIND            (SIZE_OPCODE + SIZE_LENGTH)
+#define SIZE_OP_PUSH_LOOK_BEHIND_NOT   (SIZE_OPCODE + SIZE_RELADDR + SIZE_LENGTH)
+#define SIZE_OP_FAIL_LOOK_BEHIND_NOT    SIZE_OPCODE
+#define SIZE_OP_CALL                   (SIZE_OPCODE + SIZE_ABSADDR)
+#define SIZE_OP_RETURN                  SIZE_OPCODE
+#define SIZE_OP_CONDITION              (SIZE_OPCODE + SIZE_MEMNUM + SIZE_RELADDR)
+#define SIZE_OP_PUSH_ABSENT_POS         SIZE_OPCODE
+#define SIZE_OP_ABSENT                 (SIZE_OPCODE + SIZE_RELADDR)
+#define SIZE_OP_ABSENT_END              SIZE_OPCODE
+
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+# define SIZE_OP_STATE_CHECK           (SIZE_OPCODE + SIZE_STATE_CHECK_NUM)
+# define SIZE_OP_STATE_CHECK_PUSH      (SIZE_OPCODE + SIZE_STATE_CHECK_NUM + SIZE_RELADDR)
+# define SIZE_OP_STATE_CHECK_PUSH_OR_JUMP (SIZE_OPCODE + SIZE_STATE_CHECK_NUM + SIZE_RELADDR)
+# define SIZE_OP_STATE_CHECK_ANYCHAR_STAR (SIZE_OPCODE + SIZE_STATE_CHECK_NUM)
+#endif
+
+#define MC_ESC(syn)               (syn)->meta_char_table.esc
+#define MC_ANYCHAR(syn)           (syn)->meta_char_table.anychar
+#define MC_ANYTIME(syn)           (syn)->meta_char_table.anytime
+#define MC_ZERO_OR_ONE_TIME(syn)  (syn)->meta_char_table.zero_or_one_time
+#define MC_ONE_OR_MORE_TIME(syn)  (syn)->meta_char_table.one_or_more_time
+#define MC_ANYCHAR_ANYTIME(syn)   (syn)->meta_char_table.anychar_anytime
+
+#define IS_MC_ESC_CODE(code, syn) \
+  ((code) == MC_ESC(syn) && \
+   !IS_SYNTAX_OP2((syn), ONIG_SYN_OP2_INEFFECTIVE_ESCAPE))
+
+
+#define SYN_POSIX_COMMON_OP \
+ ( ONIG_SYN_OP_DOT_ANYCHAR | ONIG_SYN_OP_POSIX_BRACKET | \
+   ONIG_SYN_OP_DECIMAL_BACKREF | \
+   ONIG_SYN_OP_BRACKET_CC | ONIG_SYN_OP_ASTERISK_ZERO_INF | \
+   ONIG_SYN_OP_LINE_ANCHOR | \
+   ONIG_SYN_OP_ESC_CONTROL_CHARS )
+
+#define SYN_GNU_REGEX_OP \
+  ( ONIG_SYN_OP_DOT_ANYCHAR | ONIG_SYN_OP_BRACKET_CC | \
+    ONIG_SYN_OP_POSIX_BRACKET | ONIG_SYN_OP_DECIMAL_BACKREF | \
+    ONIG_SYN_OP_BRACE_INTERVAL | ONIG_SYN_OP_LPAREN_SUBEXP | \
+    ONIG_SYN_OP_VBAR_ALT | \
+    ONIG_SYN_OP_ASTERISK_ZERO_INF | ONIG_SYN_OP_PLUS_ONE_INF | \
+    ONIG_SYN_OP_QMARK_ZERO_ONE | \
+    ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR | ONIG_SYN_OP_ESC_CAPITAL_G_BEGIN_ANCHOR | \
+    ONIG_SYN_OP_ESC_W_WORD | \
+    ONIG_SYN_OP_ESC_B_WORD_BOUND | ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END | \
+    ONIG_SYN_OP_ESC_S_WHITE_SPACE | ONIG_SYN_OP_ESC_D_DIGIT | \
+    ONIG_SYN_OP_LINE_ANCHOR )
+
+#define SYN_GNU_REGEX_BV \
+  ( ONIG_SYN_CONTEXT_INDEP_ANCHORS | ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS | \
+    ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS | ONIG_SYN_ALLOW_INVALID_INTERVAL | \
+    ONIG_SYN_BACKSLASH_ESCAPE_IN_CC | ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC )
+
+
+#define NCCLASS_FLAGS(cc)           ((cc)->flags)
+#define NCCLASS_FLAG_SET(cc,flag)    (NCCLASS_FLAGS(cc) |= (flag))
+#define NCCLASS_FLAG_CLEAR(cc,flag)  (NCCLASS_FLAGS(cc) &= ~(flag))
+#define IS_NCCLASS_FLAG_ON(cc,flag) ((NCCLASS_FLAGS(cc) & (flag)) != 0)
+
+/* cclass node */
+#define FLAG_NCCLASS_NOT           (1<<0)
+
+#define NCCLASS_SET_NOT(nd)     NCCLASS_FLAG_SET(nd, FLAG_NCCLASS_NOT)
+#define NCCLASS_CLEAR_NOT(nd)   NCCLASS_FLAG_CLEAR(nd, FLAG_NCCLASS_NOT)
+#define IS_NCCLASS_NOT(nd)      IS_NCCLASS_FLAG_ON(nd, FLAG_NCCLASS_NOT)
+
+typedef struct {
+  int type;
+  /* struct _Node* next; */
+  /* unsigned int flags; */
+} NodeBase;
+
+typedef struct {
+  NodeBase base;
+  unsigned int flags;
+  BitSet bs;
+  BBuf*  mbuf;   /* multi-byte info or NULL */
+} CClassNode;
+
+typedef intptr_t OnigStackIndex;
+
+typedef struct _OnigStackType {
+  unsigned int type;
+  union {
+    struct {
+      UChar *pcode;      /* byte code position */
+      UChar *pstr;       /* string position */
+      UChar *pstr_prev;  /* previous char position of pstr */
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+      unsigned int state_check;
+#endif
+      UChar *pkeep;      /* keep pattern position */
+    } state;
+    struct {
+      int   count;       /* for OP_REPEAT_INC, OP_REPEAT_INC_NG */
+      UChar *pcode;      /* byte code position (head of repeated target) */
+      int   num;         /* repeat id */
+    } repeat;
+    struct {
+      OnigStackIndex si;     /* index of stack */
+    } repeat_inc;
+    struct {
+      int num;           /* memory num */
+      UChar *pstr;       /* start/end position */
+      /* Following information is set, if this stack type is MEM-START */
+      OnigStackIndex start;  /* prev. info (for backtrack  "(...)*" ) */
+      OnigStackIndex end;    /* prev. info (for backtrack  "(...)*" ) */
+    } mem;
+    struct {
+      int num;           /* null check id */
+      UChar *pstr;       /* start position */
+    } null_check;
+#ifdef USE_SUBEXP_CALL
+    struct {
+      UChar *ret_addr;   /* byte code position */
+      int    num;        /* null check id */
+      UChar *pstr;       /* string position */
+    } call_frame;
+#endif
+    struct {
+      UChar *abs_pstr;        /* absent start position */
+      const UChar *end_pstr;  /* end position */
+    } absent_pos;
+  } u;
+} OnigStackType;
+
+typedef struct {
+  void* stack_p;
+  size_t stack_n;
+  OnigOptionType options;
+  OnigRegion*    region;
+  const UChar* start;   /* search start position */
+  const UChar* gpos;    /* global position (for \G: BEGIN_POSITION) */
+#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
+  OnigPosition best_len;  /* for ONIG_OPTION_FIND_LONGEST */
+  UChar* best_s;
+#endif
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+  void* state_check_buff;
+  int   state_check_buff_size;
+#endif
+} OnigMatchArg;
+
+
+#define IS_CODE_SB_WORD(enc,code) \
+  (ONIGENC_IS_CODE_ASCII(code) && ONIGENC_IS_CODE_WORD(enc,code))
+
+typedef struct OnigEndCallListItem {
+  struct OnigEndCallListItem* next;
+  void (*func)(void);
+} OnigEndCallListItemType;
+
+extern void onig_add_end_call(void (*func)(void));
+
+
+#ifdef ONIG_DEBUG
+
+typedef struct {
+  short int opcode;
+  const char* name;
+  short int arg_type;
+} OnigOpInfoType;
+
+extern OnigOpInfoType OnigOpInfo[];
+
+
+extern void onig_print_compiled_byte_code(FILE* f, UChar* bp, UChar* bpend, UChar** nextp, OnigEncoding enc);
+
+# ifdef ONIG_DEBUG_STATISTICS
+extern void onig_statistics_init(void);
+extern void onig_print_statistics(FILE* f);
+# endif
+#endif
+
+extern UChar* onig_error_code_to_format(OnigPosition code);
+extern void onig_vsnprintf_with_pattern(UChar buf[], int bufsize, OnigEncoding enc, UChar* pat, UChar* pat_end, const UChar *fmt, va_list args);
+extern void onig_snprintf_with_pattern(UChar buf[], int bufsize, OnigEncoding enc, UChar* pat, UChar* pat_end, const UChar *fmt, ...);
+extern int  onig_bbuf_init(BBuf* buf, OnigDistance size);
+extern int  onig_compile(regex_t* reg, const UChar* pattern, const UChar* pattern_end, OnigErrorInfo* einfo);
+#ifdef RUBY
+extern int  onig_compile_ruby(regex_t* reg, const UChar* pattern, const UChar* pattern_end, OnigErrorInfo* einfo, const char *sourcefile, int sourceline);
+#endif
+extern void onig_transfer(regex_t* to, regex_t* from);
+extern int  onig_is_code_in_cc(OnigEncoding enc, OnigCodePoint code, CClassNode* cc);
+extern int  onig_is_code_in_cc_len(int enclen, OnigCodePoint code, CClassNode* cc);
+
+/* strend hash */
+typedef void hash_table_type;
+#ifdef RUBY
+# include "ruby/st.h"
+#else
+# include "st.h"
+#endif
+typedef st_data_t hash_data_type;
+
+extern hash_table_type* onig_st_init_strend_table_with_size(st_index_t size);
+extern int onig_st_lookup_strend(hash_table_type* table, const UChar* str_key, const UChar* end_key, hash_data_type *value);
+extern int onig_st_insert_strend(hash_table_type* table, const UChar* str_key, const UChar* end_key, hash_data_type value);
+
+#ifdef RUBY
+extern size_t onig_memsize(const regex_t *reg);
+extern size_t onig_region_memsize(const struct re_registers *regs);
+#endif
+
+RUBY_SYMBOL_EXPORT_END
+
+#endif /* ONIGMO_REGINT_H */
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/regparse.c
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/regparse.c	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/regparse.c	(revision 331)
@@ -0,0 +1,7043 @@
+/**********************************************************************
+  regparse.c -  Onigmo (Oniguruma-mod) (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2008  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011-2016  K.Takata  <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "regparse.h"
+#include <stdarg.h>
+
+#define WARN_BUFSIZE    256
+
+#define CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
+
+
+const OnigSyntaxType OnigSyntaxRuby = {
+  (( SYN_GNU_REGEX_OP | ONIG_SYN_OP_QMARK_NON_GREEDY |
+     ONIG_SYN_OP_ESC_OCTAL3 | ONIG_SYN_OP_ESC_X_HEX2 |
+     ONIG_SYN_OP_ESC_X_BRACE_HEX8 | ONIG_SYN_OP_ESC_CONTROL_CHARS |
+     ONIG_SYN_OP_ESC_C_CONTROL )
+   & ~ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END )
+  , ( ONIG_SYN_OP2_QMARK_GROUP_EFFECT |
+      ONIG_SYN_OP2_OPTION_RUBY |
+      ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP | ONIG_SYN_OP2_ESC_K_NAMED_BACKREF |
+      ONIG_SYN_OP2_ESC_G_SUBEXP_CALL |
+      ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY  |
+      ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT |
+      ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT |
+      ONIG_SYN_OP2_CCLASS_SET_OP | ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL |
+      ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META | ONIG_SYN_OP2_ESC_V_VTAB |
+      ONIG_SYN_OP2_ESC_H_XDIGIT |
+#ifndef RUBY
+      ONIG_SYN_OP2_ESC_U_HEX4 |
+#endif
+      ONIG_SYN_OP2_ESC_CAPITAL_X_EXTENDED_GRAPHEME_CLUSTER |
+      ONIG_SYN_OP2_QMARK_LPAREN_CONDITION |
+      ONIG_SYN_OP2_ESC_CAPITAL_R_LINEBREAK |
+      ONIG_SYN_OP2_ESC_CAPITAL_K_KEEP |
+      ONIG_SYN_OP2_QMARK_TILDE_ABSENT )
+  , ( SYN_GNU_REGEX_BV |
+      ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV |
+      ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND |
+      ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP |
+      ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME |
+      ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY |
+      ONIG_SYN_WARN_CC_OP_NOT_ESCAPED |
+      ONIG_SYN_WARN_CC_DUP |
+      ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT )
+  , ( ONIG_OPTION_ASCII_RANGE | ONIG_OPTION_POSIX_BRACKET_ALL_RANGE |
+      ONIG_OPTION_WORD_BOUND_ALL_RANGE )
+  ,
+  {
+      (OnigCodePoint )'\\'                       /* esc */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+  }
+};
+
+const OnigSyntaxType*  OnigDefaultSyntax = ONIG_SYNTAX_RUBY;
+
+extern void onig_null_warn(const char* s ARG_UNUSED) { }
+
+#ifdef DEFAULT_WARN_FUNCTION
+static OnigWarnFunc onig_warn = (OnigWarnFunc )DEFAULT_WARN_FUNCTION;
+#else
+static OnigWarnFunc onig_warn = onig_null_warn;
+#endif
+
+#ifdef DEFAULT_VERB_WARN_FUNCTION
+static OnigWarnFunc onig_verb_warn = (OnigWarnFunc )DEFAULT_VERB_WARN_FUNCTION;
+#else
+static OnigWarnFunc onig_verb_warn = onig_null_warn;
+#endif
+
+extern void onig_set_warn_func(OnigWarnFunc f)
+{
+  onig_warn = f;
+}
+
+extern void onig_set_verb_warn_func(OnigWarnFunc f)
+{
+  onig_verb_warn = f;
+}
+
+static void CC_DUP_WARN(ScanEnv *env);
+
+
+static unsigned int ParseDepthLimit = DEFAULT_PARSE_DEPTH_LIMIT;
+
+extern unsigned int
+onig_get_parse_depth_limit(void)
+{
+  return ParseDepthLimit;
+}
+
+extern int
+onig_set_parse_depth_limit(unsigned int depth)
+{
+  if (depth == 0)
+    ParseDepthLimit = DEFAULT_PARSE_DEPTH_LIMIT;
+  else
+    ParseDepthLimit = depth;
+  return 0;
+}
+
+
+static void
+bbuf_free(BBuf* bbuf)
+{
+  if (IS_NOT_NULL(bbuf)) {
+    if (IS_NOT_NULL(bbuf->p)) xfree(bbuf->p);
+    xfree(bbuf);
+  }
+}
+
+static int
+bbuf_clone(BBuf** rto, BBuf* from)
+{
+  int r;
+  BBuf *to;
+
+  *rto = to = (BBuf* )xmalloc(sizeof(BBuf));
+  CHECK_NULL_RETURN_MEMERR(to);
+  r = BBUF_INIT(to, from->alloc);
+  if (r != 0) return r;
+  to->used = from->used;
+  xmemcpy(to->p, from->p, from->used);
+  return 0;
+}
+
+#define BACKREF_REL_TO_ABS(rel_no, env) \
+  ((env)->num_mem + 1 + (rel_no))
+
+#define ONOFF(v,f,negative)    (negative) ? ((v) &= ~(f)) : ((v) |= (f))
+
+#define MBCODE_START_POS(enc) \
+  (OnigCodePoint )(ONIGENC_MBC_MINLEN(enc) > 1 ? 0 : 0x80)
+
+#define SET_ALL_MULTI_BYTE_RANGE(enc, pbuf) \
+  add_code_range_to_buf(pbuf, env, MBCODE_START_POS(enc), ONIG_LAST_CODE_POINT)
+
+#define ADD_ALL_MULTI_BYTE_RANGE(enc, mbuf) do {\
+  if (! ONIGENC_IS_SINGLEBYTE(enc)) {\
+    r = SET_ALL_MULTI_BYTE_RANGE(enc, &(mbuf));\
+    if (r) return r;\
+  }\
+} while (0)
+
+
+#define BITSET_SET_BIT_CHKDUP(bs, pos) do { \
+  if (BITSET_AT(bs, pos)) CC_DUP_WARN(env); \
+  BS_ROOM(bs, pos) |= BS_BIT(pos); \
+} while (0)
+
+#define BITSET_IS_EMPTY(bs,empty) do {\
+  int i;\
+  empty = 1;\
+  for (i = 0; i < BITSET_SIZE; i++) {\
+    if ((bs)[i] != 0) {\
+      empty = 0; break;\
+    }\
+  }\
+} while (0)
+
+static void
+bitset_set_range(ScanEnv *env, BitSetRef bs, int from, int to)
+{
+  int i;
+  for (i = from; i <= to && i < SINGLE_BYTE_SIZE; i++) {
+    BITSET_SET_BIT_CHKDUP(bs, i);
+  }
+}
+
+#if 0
+static void
+bitset_set_all(BitSetRef bs)
+{
+  int i;
+  for (i = 0; i < BITSET_SIZE; i++) { bs[i] = ~((Bits )0); }
+}
+#endif
+
+static void
+bitset_invert(BitSetRef bs)
+{
+  int i;
+  for (i = 0; i < BITSET_SIZE; i++) { bs[i] = ~(bs[i]); }
+}
+
+static void
+bitset_invert_to(BitSetRef from, BitSetRef to)
+{
+  int i;
+  for (i = 0; i < BITSET_SIZE; i++) { to[i] = ~(from[i]); }
+}
+
+static void
+bitset_and(BitSetRef dest, BitSetRef bs)
+{
+  int i;
+  for (i = 0; i < BITSET_SIZE; i++) { dest[i] &= bs[i]; }
+}
+
+static void
+bitset_or(BitSetRef dest, BitSetRef bs)
+{
+  int i;
+  for (i = 0; i < BITSET_SIZE; i++) { dest[i] |= bs[i]; }
+}
+
+static void
+bitset_copy(BitSetRef dest, BitSetRef bs)
+{
+  int i;
+  for (i = 0; i < BITSET_SIZE; i++) { dest[i] = bs[i]; }
+}
+
+#if defined(USE_NAMED_GROUP) && !defined(USE_ST_LIBRARY)
+extern int
+onig_strncmp(const UChar* s1, const UChar* s2, int n)
+{
+  int x;
+
+  while (n-- > 0) {
+    x = *s2++ - *s1++;
+    if (x) return x;
+  }
+  return 0;
+}
+#endif
+
+extern void
+onig_strcpy(UChar* dest, const UChar* src, const UChar* end)
+{
+  ptrdiff_t len = end - src;
+  if (len > 0) {
+    xmemcpy(dest, src, len);
+    dest[len] = (UChar )0;
+  }
+}
+
+#ifdef USE_NAMED_GROUP
+static UChar*
+strdup_with_null(OnigEncoding enc, UChar* s, UChar* end)
+{
+  ptrdiff_t slen;
+  int term_len, i;
+  UChar *r;
+
+  slen = end - s;
+  term_len = ONIGENC_MBC_MINLEN(enc);
+
+  r = (UChar* )xmalloc(slen + term_len);
+  CHECK_NULL_RETURN(r);
+  xmemcpy(r, s, slen);
+
+  for (i = 0; i < term_len; i++)
+    r[slen + i] = (UChar )0;
+
+  return r;
+}
+#endif
+
+/* scan pattern methods */
+#define PEND_VALUE   0
+
+#ifdef __GNUC__
+/* get rid of Wunused-but-set-variable and Wuninitialized */
+# define PFETCH_READY  UChar* pfetch_prev = NULL; (void)pfetch_prev
+#else
+# define PFETCH_READY  UChar* pfetch_prev
+#endif
+#define PEND         (p < end ?  0 : 1)
+#define PUNFETCH     p = pfetch_prev
+#define PINC       do { \
+  pfetch_prev = p; \
+  p += enclen(enc, p, end); \
+} while (0)
+#define PFETCH(c)  do { \
+  c = ((enc->max_enc_len == 1) ? *p : ONIGENC_MBC_TO_CODE(enc, p, end)); \
+  pfetch_prev = p; \
+  p += enclen(enc, p, end); \
+} while (0)
+
+#define PINC_S     do { \
+  p += enclen(enc, p, end); \
+} while (0)
+#define PFETCH_S(c) do { \
+  c = ((enc->max_enc_len == 1) ? *p : ONIGENC_MBC_TO_CODE(enc, p, end)); \
+  p += enclen(enc, p, end); \
+} while (0)
+
+#define PPEEK        (p < end ? ONIGENC_MBC_TO_CODE(enc, p, end) : PEND_VALUE)
+#define PPEEK_IS(c)  (PPEEK == (OnigCodePoint )c)
+
+static UChar*
+strcat_capa(UChar* dest, UChar* dest_end, const UChar* src, const UChar* src_end,
+	      size_t capa)
+{
+  UChar* r;
+
+  if (dest)
+    r = (UChar* )xrealloc(dest, capa + 1);
+  else
+    r = (UChar* )xmalloc(capa + 1);
+
+  CHECK_NULL_RETURN(r);
+  onig_strcpy(r + (dest_end - dest), src, src_end);
+  return r;
+}
+
+/* dest on static area */
+static UChar*
+strcat_capa_from_static(UChar* dest, UChar* dest_end,
+			const UChar* src, const UChar* src_end, size_t capa)
+{
+  UChar* r;
+
+  r = (UChar* )xmalloc(capa + 1);
+  CHECK_NULL_RETURN(r);
+  onig_strcpy(r, dest, dest_end);
+  onig_strcpy(r + (dest_end - dest), src, src_end);
+  return r;
+}
+
+
+#ifdef USE_ST_LIBRARY
+
+# ifdef RUBY
+#  include "ruby/st.h"
+# else
+#  include "st.h"
+# endif
+
+typedef struct {
+  const UChar* s;
+  const UChar* end;
+} st_str_end_key;
+
+static int
+str_end_cmp(st_data_t xp, st_data_t yp)
+{
+  const st_str_end_key *x, *y;
+  const UChar *p, *q;
+  int c;
+
+  x = (const st_str_end_key *)xp;
+  y = (const st_str_end_key *)yp;
+  if ((x->end - x->s) != (y->end - y->s))
+    return 1;
+
+  p = x->s;
+  q = y->s;
+  while (p < x->end) {
+    c = (int )*p - (int )*q;
+    if (c != 0) return c;
+
+    p++; q++;
+  }
+
+  return 0;
+}
+
+static st_index_t
+str_end_hash(st_data_t xp)
+{
+  const st_str_end_key *x = (const st_str_end_key *)xp;
+  const UChar *p;
+  st_index_t val = 0;
+
+  p = x->s;
+  while (p < x->end) {
+    val = val * 997 + (int )*p++;
+  }
+
+  return val + (val >> 5);
+}
+
+extern hash_table_type*
+onig_st_init_strend_table_with_size(st_index_t size)
+{
+  static const struct st_hash_type hashType = {
+    str_end_cmp,
+    str_end_hash,
+  };
+
+  return (hash_table_type* )
+           onig_st_init_table_with_size(&hashType, size);
+}
+
+extern int
+onig_st_lookup_strend(hash_table_type* table, const UChar* str_key,
+		      const UChar* end_key, hash_data_type *value)
+{
+  st_str_end_key key;
+
+  key.s   = (UChar* )str_key;
+  key.end = (UChar* )end_key;
+
+  return onig_st_lookup(table, (st_data_t )(&key), value);
+}
+
+extern int
+onig_st_insert_strend(hash_table_type* table, const UChar* str_key,
+		      const UChar* end_key, hash_data_type value)
+{
+  st_str_end_key* key;
+  int result;
+
+  key = (st_str_end_key* )xmalloc(sizeof(st_str_end_key));
+  key->s   = (UChar* )str_key;
+  key->end = (UChar* )end_key;
+  result = onig_st_insert(table, (st_data_t )key, value);
+  if (result) {
+    xfree(key);
+  }
+  return result;
+}
+
+#endif /* USE_ST_LIBRARY */
+
+
+#ifdef USE_NAMED_GROUP
+
+# define INIT_NAME_BACKREFS_ALLOC_NUM   8
+
+typedef struct {
+  UChar* name;
+  size_t name_len;   /* byte length */
+  int    back_num;   /* number of backrefs */
+  int    back_alloc;
+  int    back_ref1;
+  int*   back_refs;
+} NameEntry;
+
+# ifdef USE_ST_LIBRARY
+
+typedef st_table  NameTable;
+typedef st_data_t HashDataType;   /* 1.6 st.h doesn't define st_data_t type */
+
+#  ifdef ONIG_DEBUG
+static int
+i_print_name_entry(UChar* key, NameEntry* e, void* arg)
+{
+  int i;
+  FILE* fp = (FILE* )arg;
+
+  fprintf(fp, "%s: ", e->name);
+  if (e->back_num == 0)
+    fputs("-", fp);
+  else if (e->back_num == 1)
+    fprintf(fp, "%d", e->back_ref1);
+  else {
+    for (i = 0; i < e->back_num; i++) {
+      if (i > 0) fprintf(fp, ", ");
+      fprintf(fp, "%d", e->back_refs[i]);
+    }
+  }
+  fputs("\n", fp);
+  return ST_CONTINUE;
+}
+
+extern int
+onig_print_names(FILE* fp, regex_t* reg)
+{
+  NameTable* t = (NameTable* )reg->name_table;
+
+  if (IS_NOT_NULL(t)) {
+    fprintf(fp, "name table\n");
+    onig_st_foreach(t, i_print_name_entry, (HashDataType )fp);
+    fputs("\n", fp);
+  }
+  return 0;
+}
+#  endif /* ONIG_DEBUG */
+
+static int
+i_free_name_entry(UChar* key, NameEntry* e, void* arg ARG_UNUSED)
+{
+  xfree(e->name);
+  if (IS_NOT_NULL(e->back_refs)) xfree(e->back_refs);
+  xfree(key);
+  xfree(e);
+  return ST_DELETE;
+}
+
+static int
+names_clear(regex_t* reg)
+{
+  NameTable* t = (NameTable* )reg->name_table;
+
+  if (IS_NOT_NULL(t)) {
+    onig_st_foreach(t, i_free_name_entry, 0);
+  }
+  return 0;
+}
+
+extern int
+onig_names_free(regex_t* reg)
+{
+  int r;
+  NameTable* t;
+
+  r = names_clear(reg);
+  if (r) return r;
+
+  t = (NameTable* )reg->name_table;
+  if (IS_NOT_NULL(t)) onig_st_free_table(t);
+  reg->name_table = (void* )NULL;
+  return 0;
+}
+
+static NameEntry*
+name_find(regex_t* reg, const UChar* name, const UChar* name_end)
+{
+  NameEntry* e;
+  NameTable* t = (NameTable* )reg->name_table;
+
+  e = (NameEntry* )NULL;
+  if (IS_NOT_NULL(t)) {
+    onig_st_lookup_strend(t, name, name_end, (HashDataType* )((void* )(&e)));
+  }
+  return e;
+}
+
+typedef struct {
+  int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*);
+  regex_t* reg;
+  void* arg;
+  int ret;
+  OnigEncoding enc;
+} INamesArg;
+
+static int
+i_names(UChar* key ARG_UNUSED, NameEntry* e, INamesArg* arg)
+{
+  int r = (*(arg->func))(e->name,
+			 e->name + e->name_len,
+			 e->back_num,
+			 (e->back_num > 1 ? e->back_refs : &(e->back_ref1)),
+			 arg->reg, arg->arg);
+  if (r != 0) {
+    arg->ret = r;
+    return ST_STOP;
+  }
+  return ST_CONTINUE;
+}
+
+extern int
+onig_foreach_name(regex_t* reg,
+  int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*), void* arg)
+{
+  INamesArg narg;
+  NameTable* t = (NameTable* )reg->name_table;
+
+  narg.ret = 0;
+  if (IS_NOT_NULL(t)) {
+    narg.func = func;
+    narg.reg  = reg;
+    narg.arg  = arg;
+    narg.enc  = reg->enc; /* should be pattern encoding. */
+    onig_st_foreach(t, i_names, (HashDataType )&narg);
+  }
+  return narg.ret;
+}
+
+static int
+i_renumber_name(UChar* key ARG_UNUSED, NameEntry* e, GroupNumRemap* map)
+{
+  int i;
+
+  if (e->back_num > 1) {
+    for (i = 0; i < e->back_num; i++) {
+      e->back_refs[i] = map[e->back_refs[i]].new_val;
+    }
+  }
+  else if (e->back_num == 1) {
+    e->back_ref1 = map[e->back_ref1].new_val;
+  }
+
+  return ST_CONTINUE;
+}
+
+extern int
+onig_renumber_name_table(regex_t* reg, GroupNumRemap* map)
+{
+  NameTable* t = (NameTable* )reg->name_table;
+
+  if (IS_NOT_NULL(t)) {
+    onig_st_foreach(t, i_renumber_name, (HashDataType )map);
+  }
+  return 0;
+}
+
+
+extern int
+onig_number_of_names(const regex_t* reg)
+{
+  NameTable* t = (NameTable* )reg->name_table;
+
+  if (IS_NOT_NULL(t))
+    return (int )t->num_entries;
+  else
+    return 0;
+}
+
+# else  /* USE_ST_LIBRARY */
+
+#  define INIT_NAMES_ALLOC_NUM    8
+
+typedef struct {
+  NameEntry* e;
+  int        num;
+  int        alloc;
+} NameTable;
+
+#  ifdef ONIG_DEBUG
+extern int
+onig_print_names(FILE* fp, regex_t* reg)
+{
+  int i, j;
+  NameEntry* e;
+  NameTable* t = (NameTable* )reg->name_table;
+
+  if (IS_NOT_NULL(t) && t->num > 0) {
+    fprintf(fp, "name table\n");
+    for (i = 0; i < t->num; i++) {
+      e = &(t->e[i]);
+      fprintf(fp, "%s: ", e->name);
+      if (e->back_num == 0) {
+	fputs("-", fp);
+      }
+      else if (e->back_num == 1) {
+	fprintf(fp, "%d", e->back_ref1);
+      }
+      else {
+	for (j = 0; j < e->back_num; j++) {
+	  if (j > 0) fprintf(fp, ", ");
+	  fprintf(fp, "%d", e->back_refs[j]);
+	}
+      }
+      fputs("\n", fp);
+    }
+    fputs("\n", fp);
+  }
+  return 0;
+}
+#  endif
+
+static int
+names_clear(regex_t* reg)
+{
+  int i;
+  NameEntry* e;
+  NameTable* t = (NameTable* )reg->name_table;
+
+  if (IS_NOT_NULL(t)) {
+    for (i = 0; i < t->num; i++) {
+      e = &(t->e[i]);
+      if (IS_NOT_NULL(e->name)) {
+	xfree(e->name);
+	e->name       = NULL;
+	e->name_len   = 0;
+	e->back_num   = 0;
+	e->back_alloc = 0;
+	if (IS_NOT_NULL(e->back_refs)) xfree(e->back_refs);
+	e->back_refs = (int* )NULL;
+      }
+    }
+    if (IS_NOT_NULL(t->e)) {
+      xfree(t->e);
+      t->e = NULL;
+    }
+    t->num = 0;
+  }
+  return 0;
+}
+
+extern int
+onig_names_free(regex_t* reg)
+{
+  int r;
+  NameTable* t;
+
+  r = names_clear(reg);
+  if (r) return r;
+
+  t = (NameTable* )reg->name_table;
+  if (IS_NOT_NULL(t)) xfree(t);
+  reg->name_table = NULL;
+  return 0;
+}
+
+static NameEntry*
+name_find(regex_t* reg, const UChar* name, const UChar* name_end)
+{
+  int i, len;
+  NameEntry* e;
+  NameTable* t = (NameTable* )reg->name_table;
+
+  if (IS_NOT_NULL(t)) {
+    len = name_end - name;
+    for (i = 0; i < t->num; i++) {
+      e = &(t->e[i]);
+      if (len == e->name_len && onig_strncmp(name, e->name, len) == 0)
+	return e;
+    }
+  }
+  return (NameEntry* )NULL;
+}
+
+extern int
+onig_foreach_name(regex_t* reg,
+  int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*), void* arg)
+{
+  int i, r;
+  NameEntry* e;
+  NameTable* t = (NameTable* )reg->name_table;
+
+  if (IS_NOT_NULL(t)) {
+    for (i = 0; i < t->num; i++) {
+      e = &(t->e[i]);
+      r = (*func)(e->name, e->name + e->name_len, e->back_num,
+		  (e->back_num > 1 ? e->back_refs : &(e->back_ref1)),
+		  reg, arg);
+      if (r != 0) return r;
+    }
+  }
+  return 0;
+}
+
+extern int
+onig_number_of_names(const regex_t* reg)
+{
+  NameTable* t = (NameTable* )reg->name_table;
+
+  if (IS_NOT_NULL(t))
+    return t->num;
+  else
+    return 0;
+}
+
+# endif /* else USE_ST_LIBRARY */
+
+static int
+name_add(regex_t* reg, UChar* name, UChar* name_end, int backref, ScanEnv* env)
+{
+  int alloc;
+  NameEntry* e;
+  NameTable* t = (NameTable* )reg->name_table;
+
+  if (name_end - name <= 0)
+    return ONIGERR_EMPTY_GROUP_NAME;
+
+  e = name_find(reg, name, name_end);
+  if (IS_NULL(e)) {
+# ifdef USE_ST_LIBRARY
+    if (IS_NULL(t)) {
+      t = onig_st_init_strend_table_with_size(5);
+      reg->name_table = (void* )t;
+    }
+    e = (NameEntry* )xmalloc(sizeof(NameEntry));
+    CHECK_NULL_RETURN_MEMERR(e);
+
+    e->name = strdup_with_null(reg->enc, name, name_end);
+    if (IS_NULL(e->name)) {
+      xfree(e);
+      return ONIGERR_MEMORY;
+    }
+    onig_st_insert_strend(t, e->name, (e->name + (name_end - name)),
+                          (HashDataType )e);
+
+    e->name_len   = name_end - name;
+    e->back_num   = 0;
+    e->back_alloc = 0;
+    e->back_refs  = (int* )NULL;
+
+# else
+
+    if (IS_NULL(t)) {
+      alloc = INIT_NAMES_ALLOC_NUM;
+      t = (NameTable* )xmalloc(sizeof(NameTable));
+      CHECK_NULL_RETURN_MEMERR(t);
+      t->e     = NULL;
+      t->alloc = 0;
+      t->num   = 0;
+
+      t->e = (NameEntry* )xmalloc(sizeof(NameEntry) * alloc);
+      if (IS_NULL(t->e)) {
+	xfree(t);
+	return ONIGERR_MEMORY;
+      }
+      t->alloc = alloc;
+      reg->name_table = t;
+      goto clear;
+    }
+    else if (t->num == t->alloc) {
+      int i;
+      NameEntry* p;
+
+      alloc = t->alloc * 2;
+      p = (NameEntry* )xrealloc(t->e, sizeof(NameEntry) * alloc);
+      CHECK_NULL_RETURN_MEMERR(p);
+      t->e = p;
+      t->alloc = alloc;
+
+    clear:
+      for (i = t->num; i < t->alloc; i++) {
+	t->e[i].name       = NULL;
+	t->e[i].name_len   = 0;
+	t->e[i].back_num   = 0;
+	t->e[i].back_alloc = 0;
+	t->e[i].back_refs  = (int* )NULL;
+      }
+    }
+    e = &(t->e[t->num]);
+    t->num++;
+    e->name = strdup_with_null(reg->enc, name, name_end);
+    if (IS_NULL(e->name)) return ONIGERR_MEMORY;
+    e->name_len = name_end - name;
+# endif
+  }
+
+  if (e->back_num >= 1 &&
+      ! IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME)) {
+    onig_scan_env_set_error_string(env, ONIGERR_MULTIPLEX_DEFINED_NAME,
+				    name, name_end);
+    return ONIGERR_MULTIPLEX_DEFINED_NAME;
+  }
+
+  e->back_num++;
+  if (e->back_num == 1) {
+    e->back_ref1 = backref;
+  }
+  else {
+    if (e->back_num == 2) {
+      alloc = INIT_NAME_BACKREFS_ALLOC_NUM;
+      e->back_refs = (int* )xmalloc(sizeof(int) * alloc);
+      CHECK_NULL_RETURN_MEMERR(e->back_refs);
+      e->back_alloc = alloc;
+      e->back_refs[0] = e->back_ref1;
+      e->back_refs[1] = backref;
+    }
+    else {
+      if (e->back_num > e->back_alloc) {
+	int* p;
+	alloc = e->back_alloc * 2;
+	p = (int* )xrealloc(e->back_refs, sizeof(int) * alloc);
+	CHECK_NULL_RETURN_MEMERR(p);
+	e->back_refs = p;
+	e->back_alloc = alloc;
+      }
+      e->back_refs[e->back_num - 1] = backref;
+    }
+  }
+
+  return 0;
+}
+
+extern int
+onig_name_to_group_numbers(regex_t* reg, const UChar* name,
+			   const UChar* name_end, int** nums)
+{
+  NameEntry* e = name_find(reg, name, name_end);
+
+  if (IS_NULL(e)) return ONIGERR_UNDEFINED_NAME_REFERENCE;
+
+  switch (e->back_num) {
+  case 0:
+    *nums = 0;
+    break;
+  case 1:
+    *nums = &(e->back_ref1);
+    break;
+  default:
+    *nums = e->back_refs;
+    break;
+  }
+  return e->back_num;
+}
+
+extern int
+onig_name_to_backref_number(regex_t* reg, const UChar* name,
+			    const UChar* name_end, const OnigRegion *region)
+{
+  int i, n, *nums;
+
+  n = onig_name_to_group_numbers(reg, name, name_end, &nums);
+  if (n < 0)
+    return n;
+  else if (n == 0)
+    return ONIGERR_PARSER_BUG;
+  else if (n == 1)
+    return nums[0];
+  else {
+    if (IS_NOT_NULL(region)) {
+      for (i = n - 1; i >= 0; i--) {
+	if (region->beg[nums[i]] != ONIG_REGION_NOTPOS)
+	  return nums[i];
+      }
+    }
+    return nums[n - 1];
+  }
+}
+
+#else /* USE_NAMED_GROUP */
+
+extern int
+onig_name_to_group_numbers(regex_t* reg, const UChar* name,
+			   const UChar* name_end, int** nums)
+{
+  return ONIG_NO_SUPPORT_CONFIG;
+}
+
+extern int
+onig_name_to_backref_number(regex_t* reg, const UChar* name,
+			    const UChar* name_end, const OnigRegion* region)
+{
+  return ONIG_NO_SUPPORT_CONFIG;
+}
+
+extern int
+onig_foreach_name(regex_t* reg,
+  int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*), void* arg)
+{
+  return ONIG_NO_SUPPORT_CONFIG;
+}
+
+extern int
+onig_number_of_names(const regex_t* reg)
+{
+  return 0;
+}
+#endif /* else USE_NAMED_GROUP */
+
+extern int
+onig_noname_group_capture_is_active(const regex_t* reg)
+{
+  if (ONIG_IS_OPTION_ON(reg->options, ONIG_OPTION_DONT_CAPTURE_GROUP))
+    return 0;
+
+#ifdef USE_NAMED_GROUP
+  if (onig_number_of_names(reg) > 0 &&
+      IS_SYNTAX_BV(reg->syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) &&
+      !ONIG_IS_OPTION_ON(reg->options, ONIG_OPTION_CAPTURE_GROUP)) {
+    return 0;
+  }
+#endif
+
+  return 1;
+}
+
+
+#define INIT_SCANENV_MEMNODES_ALLOC_SIZE   16
+
+static void
+scan_env_clear(ScanEnv* env)
+{
+  int i;
+
+  BIT_STATUS_CLEAR(env->capture_history);
+  BIT_STATUS_CLEAR(env->bt_mem_start);
+  BIT_STATUS_CLEAR(env->bt_mem_end);
+  BIT_STATUS_CLEAR(env->backrefed_mem);
+  env->error      = (UChar* )NULL;
+  env->error_end  = (UChar* )NULL;
+  env->num_call   = 0;
+  env->num_mem    = 0;
+#ifdef USE_NAMED_GROUP
+  env->num_named  = 0;
+#endif
+  env->mem_alloc         = 0;
+  env->mem_nodes_dynamic = (Node** )NULL;
+
+  for (i = 0; i < SCANENV_MEMNODES_SIZE; i++)
+    env->mem_nodes_static[i] = NULL_NODE;
+
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+  env->num_comb_exp_check  = 0;
+  env->comb_exp_max_regnum = 0;
+  env->curr_max_regnum     = 0;
+  env->has_recursion       = 0;
+#endif
+  env->parse_depth         = 0;
+  env->warnings_flag       = 0;
+}
+
+static int
+scan_env_add_mem_entry(ScanEnv* env)
+{
+  int i, need, alloc;
+  Node** p;
+
+  need = env->num_mem + 1;
+  if (need > ONIG_MAX_CAPTURE_GROUP_NUM)
+    return ONIGERR_TOO_MANY_CAPTURE_GROUPS;
+  if (need >= SCANENV_MEMNODES_SIZE) {
+    if (env->mem_alloc <= need) {
+      if (IS_NULL(env->mem_nodes_dynamic)) {
+	alloc = INIT_SCANENV_MEMNODES_ALLOC_SIZE;
+	p = (Node** )xmalloc(sizeof(Node*) * alloc);
+	CHECK_NULL_RETURN_MEMERR(p);
+	xmemcpy(p, env->mem_nodes_static,
+		sizeof(Node*) * SCANENV_MEMNODES_SIZE);
+      }
+      else {
+	alloc = env->mem_alloc * 2;
+	p = (Node** )xrealloc(env->mem_nodes_dynamic, sizeof(Node*) * alloc);
+	CHECK_NULL_RETURN_MEMERR(p);
+      }
+
+      for (i = env->num_mem + 1; i < alloc; i++)
+	p[i] = NULL_NODE;
+
+      env->mem_nodes_dynamic = p;
+      env->mem_alloc = alloc;
+    }
+  }
+
+  env->num_mem++;
+  return env->num_mem;
+}
+
+static int
+scan_env_set_mem_node(ScanEnv* env, int num, Node* node)
+{
+  if (env->num_mem >= num)
+    SCANENV_MEM_NODES(env)[num] = node;
+  else
+    return ONIGERR_PARSER_BUG;
+  return 0;
+}
+
+
+extern void
+onig_node_free(Node* node)
+{
+ start:
+  if (IS_NULL(node)) return ;
+
+  switch (NTYPE(node)) {
+  case NT_STR:
+    if (NSTR(node)->capa != 0 &&
+	IS_NOT_NULL(NSTR(node)->s) && NSTR(node)->s != NSTR(node)->buf) {
+      xfree(NSTR(node)->s);
+    }
+    break;
+
+  case NT_LIST:
+  case NT_ALT:
+    onig_node_free(NCAR(node));
+    {
+      Node* next_node = NCDR(node);
+
+      xfree(node);
+      node = next_node;
+      goto start;
+    }
+    break;
+
+  case NT_CCLASS:
+    {
+      CClassNode* cc = NCCLASS(node);
+
+      if (cc->mbuf)
+	bbuf_free(cc->mbuf);
+    }
+    break;
+
+  case NT_QTFR:
+    if (NQTFR(node)->target)
+      onig_node_free(NQTFR(node)->target);
+    break;
+
+  case NT_ENCLOSE:
+    if (NENCLOSE(node)->target)
+      onig_node_free(NENCLOSE(node)->target);
+    break;
+
+  case NT_BREF:
+    if (IS_NOT_NULL(NBREF(node)->back_dynamic))
+      xfree(NBREF(node)->back_dynamic);
+    break;
+
+  case NT_ANCHOR:
+    if (NANCHOR(node)->target)
+      onig_node_free(NANCHOR(node)->target);
+    break;
+  }
+
+  xfree(node);
+}
+
+static Node*
+node_new(void)
+{
+  Node* node;
+
+  node = (Node* )xmalloc(sizeof(Node));
+  /* xmemset(node, 0, sizeof(Node)); */
+  return node;
+}
+
+static void
+initialize_cclass(CClassNode* cc)
+{
+  BITSET_CLEAR(cc->bs);
+  /* cc->base.flags = 0; */
+  cc->flags = 0;
+  cc->mbuf  = NULL;
+}
+
+static Node*
+node_new_cclass(void)
+{
+  Node* node = node_new();
+  CHECK_NULL_RETURN(node);
+
+  SET_NTYPE(node, NT_CCLASS);
+  initialize_cclass(NCCLASS(node));
+  return node;
+}
+
+static Node*
+node_new_ctype(int type, int not, int ascii_range)
+{
+  Node* node = node_new();
+  CHECK_NULL_RETURN(node);
+
+  SET_NTYPE(node, NT_CTYPE);
+  NCTYPE(node)->ctype = type;
+  NCTYPE(node)->not   = not;
+  NCTYPE(node)->ascii_range = ascii_range;
+  return node;
+}
+
+static Node*
+node_new_anychar(void)
+{
+  Node* node = node_new();
+  CHECK_NULL_RETURN(node);
+
+  SET_NTYPE(node, NT_CANY);
+  return node;
+}
+
+static Node*
+node_new_list(Node* left, Node* right)
+{
+  Node* node = node_new();
+  CHECK_NULL_RETURN(node);
+
+  SET_NTYPE(node, NT_LIST);
+  NCAR(node)  = left;
+  NCDR(node) = right;
+  return node;
+}
+
+extern Node*
+onig_node_new_list(Node* left, Node* right)
+{
+  return node_new_list(left, right);
+}
+
+extern Node*
+onig_node_list_add(Node* list, Node* x)
+{
+  Node *n;
+
+  n = onig_node_new_list(x, NULL);
+  if (IS_NULL(n)) return NULL_NODE;
+
+  if (IS_NOT_NULL(list)) {
+    while (IS_NOT_NULL(NCDR(list)))
+      list = NCDR(list);
+
+    NCDR(list) = n;
+  }
+
+  return n;
+}
+
+extern Node*
+onig_node_new_alt(Node* left, Node* right)
+{
+  Node* node = node_new();
+  CHECK_NULL_RETURN(node);
+
+  SET_NTYPE(node, NT_ALT);
+  NCAR(node)  = left;
+  NCDR(node) = right;
+  return node;
+}
+
+extern Node*
+onig_node_new_anchor(int type)
+{
+  Node* node = node_new();
+  CHECK_NULL_RETURN(node);
+
+  SET_NTYPE(node, NT_ANCHOR);
+  NANCHOR(node)->type     = type;
+  NANCHOR(node)->target   = NULL;
+  NANCHOR(node)->char_len = -1;
+  NANCHOR(node)->ascii_range = 0;
+  return node;
+}
+
+static Node*
+node_new_backref(int back_num, int* backrefs, int by_name,
+#ifdef USE_BACKREF_WITH_LEVEL
+		 int exist_level, int nest_level,
+#endif
+		 ScanEnv* env)
+{
+  int i;
+  Node* node = node_new();
+
+  CHECK_NULL_RETURN(node);
+
+  SET_NTYPE(node, NT_BREF);
+  NBREF(node)->state    = 0;
+  NBREF(node)->back_num = back_num;
+  NBREF(node)->back_dynamic = (int* )NULL;
+  if (by_name != 0)
+    NBREF(node)->state |= NST_NAME_REF;
+
+#ifdef USE_BACKREF_WITH_LEVEL
+  if (exist_level != 0) {
+    NBREF(node)->state |= NST_NEST_LEVEL;
+    NBREF(node)->nest_level  = nest_level;
+  }
+#endif
+
+  for (i = 0; i < back_num; i++) {
+    if (backrefs[i] <= env->num_mem &&
+	IS_NULL(SCANENV_MEM_NODES(env)[backrefs[i]])) {
+      NBREF(node)->state |= NST_RECURSION;   /* /...(\1).../ */
+      break;
+    }
+  }
+
+  if (back_num <= NODE_BACKREFS_SIZE) {
+    for (i = 0; i < back_num; i++)
+      NBREF(node)->back_static[i] = backrefs[i];
+  }
+  else {
+    int* p = (int* )xmalloc(sizeof(int) * back_num);
+    if (IS_NULL(p)) {
+      onig_node_free(node);
+      return NULL;
+    }
+    NBREF(node)->back_dynamic = p;
+    for (i = 0; i < back_num; i++)
+      p[i] = backrefs[i];
+  }
+  return node;
+}
+
+#ifdef USE_SUBEXP_CALL
+static Node*
+node_new_call(UChar* name, UChar* name_end, int gnum)
+{
+  Node* node = node_new();
+  CHECK_NULL_RETURN(node);
+
+  SET_NTYPE(node, NT_CALL);
+  NCALL(node)->state     = 0;
+  NCALL(node)->target    = NULL_NODE;
+  NCALL(node)->name      = name;
+  NCALL(node)->name_end  = name_end;
+  NCALL(node)->group_num = gnum;  /* call by number if gnum != 0 */
+  return node;
+}
+#endif
+
+static Node*
+node_new_quantifier(int lower, int upper, int by_number)
+{
+  Node* node = node_new();
+  CHECK_NULL_RETURN(node);
+
+  SET_NTYPE(node, NT_QTFR);
+  NQTFR(node)->state  = 0;
+  NQTFR(node)->target = NULL;
+  NQTFR(node)->lower  = lower;
+  NQTFR(node)->upper  = upper;
+  NQTFR(node)->greedy = 1;
+  NQTFR(node)->target_empty_info = NQ_TARGET_ISNOT_EMPTY;
+  NQTFR(node)->head_exact        = NULL_NODE;
+  NQTFR(node)->next_head_exact   = NULL_NODE;
+  NQTFR(node)->is_refered        = 0;
+  if (by_number != 0)
+    NQTFR(node)->state |= NST_BY_NUMBER;
+
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+  NQTFR(node)->comb_exp_check_num = 0;
+#endif
+
+  return node;
+}
+
+static Node*
+node_new_enclose(int type)
+{
+  Node* node = node_new();
+  CHECK_NULL_RETURN(node);
+
+  SET_NTYPE(node, NT_ENCLOSE);
+  NENCLOSE(node)->type      = type;
+  NENCLOSE(node)->state     =  0;
+  NENCLOSE(node)->regnum    =  0;
+  NENCLOSE(node)->option    =  0;
+  NENCLOSE(node)->target    = NULL;
+  NENCLOSE(node)->call_addr = -1;
+  NENCLOSE(node)->opt_count =  0;
+  return node;
+}
+
+extern Node*
+onig_node_new_enclose(int type)
+{
+  return node_new_enclose(type);
+}
+
+static Node*
+node_new_enclose_memory(OnigOptionType option, int is_named)
+{
+  Node* node = node_new_enclose(ENCLOSE_MEMORY);
+  CHECK_NULL_RETURN(node);
+  if (is_named != 0)
+    SET_ENCLOSE_STATUS(node, NST_NAMED_GROUP);
+
+#ifdef USE_SUBEXP_CALL
+  NENCLOSE(node)->option = option;
+#endif
+  return node;
+}
+
+static Node*
+node_new_option(OnigOptionType option)
+{
+  Node* node = node_new_enclose(ENCLOSE_OPTION);
+  CHECK_NULL_RETURN(node);
+  NENCLOSE(node)->option = option;
+  return node;
+}
+
+extern int
+onig_node_str_cat(Node* node, const UChar* s, const UChar* end)
+{
+  ptrdiff_t addlen = end - s;
+
+  if (addlen > 0) {
+    ptrdiff_t len  = NSTR(node)->end - NSTR(node)->s;
+
+    if (NSTR(node)->capa > 0 || (len + addlen > NODE_STR_BUF_SIZE - 1)) {
+      UChar* p;
+      ptrdiff_t capa = len + addlen + NODE_STR_MARGIN;
+
+      if (capa <= NSTR(node)->capa) {
+	onig_strcpy(NSTR(node)->s + len, s, end);
+      }
+      else {
+	if (NSTR(node)->s == NSTR(node)->buf)
+	  p = strcat_capa_from_static(NSTR(node)->s, NSTR(node)->end,
+				      s, end, capa);
+	else
+	  p = strcat_capa(NSTR(node)->s, NSTR(node)->end, s, end, capa);
+
+	CHECK_NULL_RETURN_MEMERR(p);
+	NSTR(node)->s    = p;
+	NSTR(node)->capa = (int )capa;
+      }
+    }
+    else {
+      onig_strcpy(NSTR(node)->s + len, s, end);
+    }
+    NSTR(node)->end = NSTR(node)->s + len + addlen;
+  }
+
+  return 0;
+}
+
+extern int
+onig_node_str_set(Node* node, const UChar* s, const UChar* end)
+{
+  onig_node_str_clear(node);
+  return onig_node_str_cat(node, s, end);
+}
+
+static int
+node_str_cat_char(Node* node, UChar c)
+{
+  UChar s[1];
+
+  s[0] = c;
+  return onig_node_str_cat(node, s, s + 1);
+}
+
+static int
+node_str_cat_codepoint(Node* node, OnigEncoding enc, OnigCodePoint c)
+{
+  UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
+  int num = ONIGENC_CODE_TO_MBC(enc, c, buf);
+  if (num < 0) return num;
+  return onig_node_str_cat(node, buf, buf + num);
+}
+
+#if 0
+extern void
+onig_node_conv_to_str_node(Node* node, int flag)
+{
+  SET_NTYPE(node, NT_STR);
+  NSTR(node)->flag = flag;
+  NSTR(node)->capa = 0;
+  NSTR(node)->s    = NSTR(node)->buf;
+  NSTR(node)->end  = NSTR(node)->buf;
+}
+#endif
+
+extern void
+onig_node_str_clear(Node* node)
+{
+  if (NSTR(node)->capa != 0 &&
+      IS_NOT_NULL(NSTR(node)->s) && NSTR(node)->s != NSTR(node)->buf) {
+    xfree(NSTR(node)->s);
+  }
+
+  NSTR(node)->capa = 0;
+  NSTR(node)->flag = 0;
+  NSTR(node)->s    = NSTR(node)->buf;
+  NSTR(node)->end  = NSTR(node)->buf;
+}
+
+static Node*
+node_new_str(const UChar* s, const UChar* end)
+{
+  Node* node = node_new();
+  CHECK_NULL_RETURN(node);
+
+  SET_NTYPE(node, NT_STR);
+  NSTR(node)->capa = 0;
+  NSTR(node)->flag = 0;
+  NSTR(node)->s    = NSTR(node)->buf;
+  NSTR(node)->end  = NSTR(node)->buf;
+  if (onig_node_str_cat(node, s, end)) {
+    onig_node_free(node);
+    return NULL;
+  }
+  return node;
+}
+
+extern Node*
+onig_node_new_str(const UChar* s, const UChar* end)
+{
+  return node_new_str(s, end);
+}
+
+static Node*
+node_new_str_raw(UChar* s, UChar* end)
+{
+  Node* node = node_new_str(s, end);
+  if (IS_NOT_NULL(node))
+    NSTRING_SET_RAW(node);
+  return node;
+}
+
+static Node*
+node_new_empty(void)
+{
+  return node_new_str(NULL, NULL);
+}
+
+static Node*
+node_new_str_raw_char(UChar c)
+{
+  UChar p[1];
+
+  p[0] = c;
+  return node_new_str_raw(p, p + 1);
+}
+
+static Node*
+str_node_split_last_char(StrNode* sn, OnigEncoding enc)
+{
+  const UChar *p;
+  Node* n = NULL_NODE;
+
+  if (sn->end > sn->s) {
+    p = onigenc_get_prev_char_head(enc, sn->s, sn->end, sn->end);
+    if (p && p > sn->s) { /* can be split. */
+      n = node_new_str(p, sn->end);
+      if (IS_NOT_NULL(n) && (sn->flag & NSTR_RAW) != 0)
+	NSTRING_SET_RAW(n);
+      sn->end = (UChar* )p;
+    }
+  }
+  return n;
+}
+
+static int
+str_node_can_be_split(StrNode* sn, OnigEncoding enc)
+{
+  if (sn->end > sn->s) {
+    return ((enclen(enc, sn->s, sn->end) < sn->end - sn->s)  ?  1 : 0);
+  }
+  return 0;
+}
+
+#ifdef USE_PAD_TO_SHORT_BYTE_CHAR
+static int
+node_str_head_pad(StrNode* sn, int num, UChar val)
+{
+  UChar buf[NODE_STR_BUF_SIZE];
+  int i, len;
+
+  len = sn->end - sn->s;
+  onig_strcpy(buf, sn->s, sn->end);
+  onig_strcpy(&(sn->s[num]), buf, buf + len);
+  sn->end += num;
+
+  for (i = 0; i < num; i++) {
+    sn->s[i] = val;
+  }
+}
+#endif
+
+extern int
+onig_scan_unsigned_number(UChar** src, const UChar* end, OnigEncoding enc)
+{
+  unsigned int num, val;
+  OnigCodePoint c;
+  UChar* p = *src;
+  PFETCH_READY;
+
+  num = 0;
+  while (!PEND) {
+    PFETCH(c);
+    if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
+      val = (unsigned int )DIGITVAL(c);
+      if ((INT_MAX_LIMIT - val) / 10UL < num)
+	return -1;  /* overflow */
+
+      num = num * 10 + val;
+    }
+    else {
+      PUNFETCH;
+      break;
+    }
+  }
+  *src = p;
+  return num;
+}
+
+static int
+scan_unsigned_hexadecimal_number(UChar** src, UChar* end, int minlen,
+				 int maxlen, OnigEncoding enc)
+{
+  OnigCodePoint c;
+  unsigned int num, val;
+  int restlen;
+  UChar* p = *src;
+  PFETCH_READY;
+
+  restlen = maxlen - minlen;
+  num = 0;
+  while (!PEND && maxlen-- != 0) {
+    PFETCH(c);
+    if (ONIGENC_IS_CODE_XDIGIT(enc, c)) {
+      val = (unsigned int )XDIGITVAL(enc,c);
+      if ((INT_MAX_LIMIT - val) / 16UL < num)
+	return -1;  /* overflow */
+
+      num = (num << 4) + XDIGITVAL(enc,c);
+    }
+    else {
+      PUNFETCH;
+      maxlen++;
+      break;
+    }
+  }
+  if (maxlen > restlen)
+    return -2;  /* not enough digits */
+  *src = p;
+  return num;
+}
+
+static int
+scan_unsigned_octal_number(UChar** src, UChar* end, int maxlen,
+			   OnigEncoding enc)
+{
+  OnigCodePoint c;
+  unsigned int num, val;
+  UChar* p = *src;
+  PFETCH_READY;
+
+  num = 0;
+  while (!PEND && maxlen-- != 0) {
+    PFETCH(c);
+    if (ONIGENC_IS_CODE_DIGIT(enc, c) && c < '8') {
+      val = ODIGITVAL(c);
+      if ((INT_MAX_LIMIT - val) / 8UL < num)
+	return -1;  /* overflow */
+
+      num = (num << 3) + val;
+    }
+    else {
+      PUNFETCH;
+      break;
+    }
+  }
+  *src = p;
+  return num;
+}
+
+
+#define BBUF_WRITE_CODE_POINT(bbuf,pos,code) \
+    BBUF_WRITE(bbuf, pos, &(code), SIZE_CODE_POINT)
+
+/* data format:
+     [n][from-1][to-1][from-2][to-2] ... [from-n][to-n]
+     (all data size is OnigCodePoint)
+ */
+static int
+new_code_range(BBuf** pbuf)
+{
+#define INIT_MULTI_BYTE_RANGE_SIZE  (SIZE_CODE_POINT * 5)
+  int r;
+  OnigCodePoint n;
+  BBuf* bbuf;
+
+  bbuf = *pbuf = (BBuf* )xmalloc(sizeof(BBuf));
+  CHECK_NULL_RETURN_MEMERR(*pbuf);
+  r = BBUF_INIT(*pbuf, INIT_MULTI_BYTE_RANGE_SIZE);
+  if (r) return r;
+
+  n = 0;
+  BBUF_WRITE_CODE_POINT(bbuf, 0, n);
+  return 0;
+}
+
+static int
+add_code_range_to_buf0(BBuf** pbuf, ScanEnv* env, OnigCodePoint from, OnigCodePoint to,
+	int checkdup)
+{
+  int r, inc_n, pos;
+  OnigCodePoint low, high, bound, x;
+  OnigCodePoint n, *data;
+  BBuf* bbuf;
+
+  if (from > to) {
+    n = from; from = to; to = n;
+  }
+
+  if (IS_NULL(*pbuf)) {
+    r = new_code_range(pbuf);
+    if (r) return r;
+    bbuf = *pbuf;
+    n = 0;
+  }
+  else {
+    bbuf = *pbuf;
+    GET_CODE_POINT(n, bbuf->p);
+  }
+  data = (OnigCodePoint* )(bbuf->p);
+  data++;
+
+  bound = (from == 0) ? 0 : n;
+  for (low = 0; low < bound; ) {
+    x = (low + bound) >> 1;
+    if (from - 1 > data[x*2 + 1])
+      low = x + 1;
+    else
+      bound = x;
+  }
+
+  high = (to == ONIG_LAST_CODE_POINT) ? n : low;
+  for (bound = n; high < bound; ) {
+    x = (high + bound) >> 1;
+    if (to + 1 >= data[x*2])
+      high = x + 1;
+    else
+      bound = x;
+  }
+  /* data[(low-1)*2+1] << from <= data[low*2]
+   * data[(high-1)*2+1] <= to << data[high*2]
+   */
+
+  inc_n = low + 1 - high;
+  if (n + inc_n > ONIG_MAX_MULTI_BYTE_RANGES_NUM)
+    return ONIGERR_TOO_MANY_MULTI_BYTE_RANGES;
+
+  if (inc_n != 1) {
+    if (checkdup && from <= data[low*2+1]
+	&& (data[low*2] <= from || data[low*2+1] <= to))
+      CC_DUP_WARN(env);
+    if (from > data[low*2])
+      from = data[low*2];
+    if (to < data[(high - 1)*2 + 1])
+      to = data[(high - 1)*2 + 1];
+  }
+
+  if (inc_n != 0) {
+    int from_pos = SIZE_CODE_POINT * (1 + high * 2);
+    int to_pos   = SIZE_CODE_POINT * (1 + (low + 1) * 2);
+
+    if (inc_n > 0) {
+      if (high < n) {
+	int size = (n - high) * 2 * SIZE_CODE_POINT;
+	BBUF_MOVE_RIGHT(bbuf, from_pos, to_pos, size);
+      }
+    }
+    else {
+      BBUF_MOVE_LEFT_REDUCE(bbuf, from_pos, to_pos);
+    }
+  }
+
+  pos = SIZE_CODE_POINT * (1 + low * 2);
+  BBUF_ENSURE_SIZE(bbuf, pos + SIZE_CODE_POINT * 2);
+  BBUF_WRITE_CODE_POINT(bbuf, pos, from);
+  BBUF_WRITE_CODE_POINT(bbuf, pos + SIZE_CODE_POINT, to);
+  n += inc_n;
+  BBUF_WRITE_CODE_POINT(bbuf, 0, n);
+
+  return 0;
+}
+
+static int
+add_code_range_to_buf(BBuf** pbuf, ScanEnv* env, OnigCodePoint from, OnigCodePoint to)
+{
+  return add_code_range_to_buf0(pbuf, env, from, to, 1);
+}
+
+static int
+add_code_range0(BBuf** pbuf, ScanEnv* env, OnigCodePoint from, OnigCodePoint to, int checkdup)
+{
+  if (from > to) {
+    if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
+      return 0;
+    else
+      return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS;
+  }
+
+  return add_code_range_to_buf0(pbuf, env, from, to, checkdup);
+}
+
+static int
+add_code_range(BBuf** pbuf, ScanEnv* env, OnigCodePoint from, OnigCodePoint to)
+{
+  return add_code_range0(pbuf, env, from, to, 1);
+}
+
+static int
+not_code_range_buf(OnigEncoding enc, BBuf* bbuf, BBuf** pbuf, ScanEnv* env)
+{
+  int r, i, n;
+  OnigCodePoint pre, from, *data, to = 0;
+
+  *pbuf = (BBuf* )NULL;
+  if (IS_NULL(bbuf)) {
+  set_all:
+    return SET_ALL_MULTI_BYTE_RANGE(enc, pbuf);
+  }
+
+  data = (OnigCodePoint* )(bbuf->p);
+  GET_CODE_POINT(n, data);
+  data++;
+  if (n <= 0) goto set_all;
+
+  r = 0;
+  pre = MBCODE_START_POS(enc);
+  for (i = 0; i < n; i++) {
+    from = data[i*2];
+    to   = data[i*2+1];
+    if (pre <= from - 1) {
+      r = add_code_range_to_buf(pbuf, env, pre, from - 1);
+      if (r != 0) return r;
+    }
+    if (to == ONIG_LAST_CODE_POINT) break;
+    pre = to + 1;
+  }
+  if (to < ONIG_LAST_CODE_POINT) {
+    r = add_code_range_to_buf(pbuf, env, to + 1, ONIG_LAST_CODE_POINT);
+  }
+  return r;
+}
+
+#define SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2) do {\
+  BBuf *tbuf; \
+  int  tnot; \
+  tnot = not1;  not1  = not2;  not2  = tnot; \
+  tbuf = bbuf1; bbuf1 = bbuf2; bbuf2 = tbuf; \
+} while (0)
+
+static int
+or_code_range_buf(OnigEncoding enc, BBuf* bbuf1, int not1,
+                  BBuf* bbuf2, int not2, BBuf** pbuf, ScanEnv* env)
+{
+  int r;
+  OnigCodePoint i, n1, *data1;
+  OnigCodePoint from, to;
+
+  *pbuf = (BBuf* )NULL;
+  if (IS_NULL(bbuf1) && IS_NULL(bbuf2)) {
+    if (not1 != 0 || not2 != 0)
+      return SET_ALL_MULTI_BYTE_RANGE(enc, pbuf);
+    return 0;
+  }
+
+  r = 0;
+  if (IS_NULL(bbuf2))
+    SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2);
+
+  if (IS_NULL(bbuf1)) {
+    if (not1 != 0) {
+      return SET_ALL_MULTI_BYTE_RANGE(enc, pbuf);
+    }
+    else {
+      if (not2 == 0) {
+	return bbuf_clone(pbuf, bbuf2);
+      }
+      else {
+	return not_code_range_buf(enc, bbuf2, pbuf, env);
+      }
+    }
+  }
+
+  if (not1 != 0)
+    SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2);
+
+  data1 = (OnigCodePoint* )(bbuf1->p);
+  GET_CODE_POINT(n1, data1);
+  data1++;
+
+  if (not2 == 0 && not1 == 0) { /* 1 OR 2 */
+    r = bbuf_clone(pbuf, bbuf2);
+  }
+  else if (not1 == 0) { /* 1 OR (not 2) */
+    r = not_code_range_buf(enc, bbuf2, pbuf, env);
+  }
+  if (r != 0) return r;
+
+  for (i = 0; i < n1; i++) {
+    from = data1[i*2];
+    to   = data1[i*2+1];
+    r = add_code_range_to_buf(pbuf, env, from, to);
+    if (r != 0) return r;
+  }
+  return 0;
+}
+
+static int
+and_code_range1(BBuf** pbuf, ScanEnv* env, OnigCodePoint from1, OnigCodePoint to1,
+		OnigCodePoint* data, int n)
+{
+  int i, r;
+  OnigCodePoint from2, to2;
+
+  for (i = 0; i < n; i++) {
+    from2 = data[i*2];
+    to2   = data[i*2+1];
+    if (from2 < from1) {
+      if (to2 < from1) continue;
+      else {
+	from1 = to2 + 1;
+      }
+    }
+    else if (from2 <= to1) {
+      if (to2 < to1) {
+	if (from1 <= from2 - 1) {
+	  r = add_code_range_to_buf(pbuf, env, from1, from2-1);
+	  if (r != 0) return r;
+	}
+	from1 = to2 + 1;
+      }
+      else {
+	to1 = from2 - 1;
+      }
+    }
+    else {
+      from1 = from2;
+    }
+    if (from1 > to1) break;
+  }
+  if (from1 <= to1) {
+    r = add_code_range_to_buf(pbuf, env, from1, to1);
+    if (r != 0) return r;
+  }
+  return 0;
+}
+
+static int
+and_code_range_buf(BBuf* bbuf1, int not1, BBuf* bbuf2, int not2, BBuf** pbuf, ScanEnv* env)
+{
+  int r;
+  OnigCodePoint i, j, n1, n2, *data1, *data2;
+  OnigCodePoint from, to, from1, to1, from2, to2;
+
+  *pbuf = (BBuf* )NULL;
+  if (IS_NULL(bbuf1)) {
+    if (not1 != 0 && IS_NOT_NULL(bbuf2)) /* not1 != 0 -> not2 == 0 */
+      return bbuf_clone(pbuf, bbuf2);
+    return 0;
+  }
+  else if (IS_NULL(bbuf2)) {
+    if (not2 != 0)
+      return bbuf_clone(pbuf, bbuf1);
+    return 0;
+  }
+
+  if (not1 != 0)
+    SWAP_BBUF_NOT(bbuf1, not1, bbuf2, not2);
+
+  data1 = (OnigCodePoint* )(bbuf1->p);
+  data2 = (OnigCodePoint* )(bbuf2->p);
+  GET_CODE_POINT(n1, data1);
+  GET_CODE_POINT(n2, data2);
+  data1++;
+  data2++;
+
+  if (not2 == 0 && not1 == 0) { /* 1 AND 2 */
+    for (i = 0; i < n1; i++) {
+      from1 = data1[i*2];
+      to1   = data1[i*2+1];
+      for (j = 0; j < n2; j++) {
+	from2 = data2[j*2];
+	to2   = data2[j*2+1];
+	if (from2 > to1) break;
+	if (to2 < from1) continue;
+	from = MAX(from1, from2);
+	to   = MIN(to1, to2);
+	r = add_code_range_to_buf(pbuf, env, from, to);
+	if (r != 0) return r;
+      }
+    }
+  }
+  else if (not1 == 0) { /* 1 AND (not 2) */
+    for (i = 0; i < n1; i++) {
+      from1 = data1[i*2];
+      to1   = data1[i*2+1];
+      r = and_code_range1(pbuf, env, from1, to1, data2, n2);
+      if (r != 0) return r;
+    }
+  }
+
+  return 0;
+}
+
+static int
+and_cclass(CClassNode* dest, CClassNode* cc, ScanEnv* env)
+{
+  OnigEncoding enc = env->enc;
+  int r, not1, not2;
+  BBuf *buf1, *buf2, *pbuf = 0;
+  BitSetRef bsr1, bsr2;
+  BitSet bs1, bs2;
+
+  not1 = IS_NCCLASS_NOT(dest);
+  bsr1 = dest->bs;
+  buf1 = dest->mbuf;
+  not2 = IS_NCCLASS_NOT(cc);
+  bsr2 = cc->bs;
+  buf2 = cc->mbuf;
+
+  if (not1 != 0) {
+    bitset_invert_to(bsr1, bs1);
+    bsr1 = bs1;
+  }
+  if (not2 != 0) {
+    bitset_invert_to(bsr2, bs2);
+    bsr2 = bs2;
+  }
+  bitset_and(bsr1, bsr2);
+  if (bsr1 != dest->bs) {
+    bitset_copy(dest->bs, bsr1);
+    bsr1 = dest->bs;
+  }
+  if (not1 != 0) {
+    bitset_invert(dest->bs);
+  }
+
+  if (! ONIGENC_IS_SINGLEBYTE(enc)) {
+    if (not1 != 0 && not2 != 0) {
+      r = or_code_range_buf(enc, buf1, 0, buf2, 0, &pbuf, env);
+    }
+    else {
+      r = and_code_range_buf(buf1, not1, buf2, not2, &pbuf, env);
+      if (r == 0 && not1 != 0) {
+	BBuf *tbuf = 0;
+	r = not_code_range_buf(enc, pbuf, &tbuf, env);
+	bbuf_free(pbuf);
+	pbuf = tbuf;
+      }
+    }
+    if (r != 0) {
+      bbuf_free(pbuf);
+      return r;
+    }
+
+    dest->mbuf = pbuf;
+    bbuf_free(buf1);
+    return r;
+  }
+  return 0;
+}
+
+static int
+or_cclass(CClassNode* dest, CClassNode* cc, ScanEnv* env)
+{
+  OnigEncoding enc = env->enc;
+  int r, not1, not2;
+  BBuf *buf1, *buf2, *pbuf = 0;
+  BitSetRef bsr1, bsr2;
+  BitSet bs1, bs2;
+
+  not1 = IS_NCCLASS_NOT(dest);
+  bsr1 = dest->bs;
+  buf1 = dest->mbuf;
+  not2 = IS_NCCLASS_NOT(cc);
+  bsr2 = cc->bs;
+  buf2 = cc->mbuf;
+
+  if (not1 != 0) {
+    bitset_invert_to(bsr1, bs1);
+    bsr1 = bs1;
+  }
+  if (not2 != 0) {
+    bitset_invert_to(bsr2, bs2);
+    bsr2 = bs2;
+  }
+  bitset_or(bsr1, bsr2);
+  if (bsr1 != dest->bs) {
+    bitset_copy(dest->bs, bsr1);
+    bsr1 = dest->bs;
+  }
+  if (not1 != 0) {
+    bitset_invert(dest->bs);
+  }
+
+  if (! ONIGENC_IS_SINGLEBYTE(enc)) {
+    if (not1 != 0 && not2 != 0) {
+      r = and_code_range_buf(buf1, 0, buf2, 0, &pbuf, env);
+    }
+    else {
+      r = or_code_range_buf(enc, buf1, not1, buf2, not2, &pbuf, env);
+      if (r == 0 && not1 != 0) {
+	BBuf *tbuf = 0;
+	r = not_code_range_buf(enc, pbuf, &tbuf, env);
+	bbuf_free(pbuf);
+	pbuf = tbuf;
+      }
+    }
+    if (r != 0) {
+      bbuf_free(pbuf);
+      return r;
+    }
+
+    dest->mbuf = pbuf;
+    bbuf_free(buf1);
+    return r;
+  }
+  else
+    return 0;
+}
+
+static void UNKNOWN_ESC_WARN(ScanEnv *env, int c);
+
+static OnigCodePoint
+conv_backslash_value(OnigCodePoint c, ScanEnv* env)
+{
+  if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_CONTROL_CHARS)) {
+    switch (c) {
+    case 'n': return '\n';
+    case 't': return '\t';
+    case 'r': return '\r';
+    case 'f': return '\f';
+    case 'a': return '\007';
+    case 'b': return '\010';
+    case 'e': return '\033';
+    case 'v':
+      if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ESC_V_VTAB))
+	return '\v';
+      break;
+
+    default:
+      if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))
+	  UNKNOWN_ESC_WARN(env, c);
+      break;
+    }
+  }
+  return c;
+}
+
+#ifdef USE_NO_INVALID_QUANTIFIER
+# define is_invalid_quantifier_target(node) 0
+#else
+static int
+is_invalid_quantifier_target(Node* node)
+{
+  switch (NTYPE(node)) {
+  case NT_ANCHOR:
+    return 1;
+    break;
+
+  case NT_ENCLOSE:
+    /* allow enclosed elements */
+    /* return is_invalid_quantifier_target(NENCLOSE(node)->target); */
+    break;
+
+  case NT_LIST:
+    do {
+      if (! is_invalid_quantifier_target(NCAR(node))) return 0;
+    } while (IS_NOT_NULL(node = NCDR(node)));
+    return 0;
+    break;
+
+  case NT_ALT:
+    do {
+      if (is_invalid_quantifier_target(NCAR(node))) return 1;
+    } while (IS_NOT_NULL(node = NCDR(node)));
+    break;
+
+  default:
+    break;
+  }
+  return 0;
+}
+#endif
+
+/* ?:0, *:1, +:2, ??:3, *?:4, +?:5 */
+static int
+popular_quantifier_num(QtfrNode* q)
+{
+  if (q->greedy) {
+    if (q->lower == 0) {
+      if (q->upper == 1) return 0;
+      else if (IS_REPEAT_INFINITE(q->upper)) return 1;
+    }
+    else if (q->lower == 1) {
+      if (IS_REPEAT_INFINITE(q->upper)) return 2;
+    }
+  }
+  else {
+    if (q->lower == 0) {
+      if (q->upper == 1) return 3;
+      else if (IS_REPEAT_INFINITE(q->upper)) return 4;
+    }
+    else if (q->lower == 1) {
+      if (IS_REPEAT_INFINITE(q->upper)) return 5;
+    }
+  }
+  return -1;
+}
+
+
+enum ReduceType {
+  RQ_ASIS = 0, /* as is */
+  RQ_DEL  = 1, /* delete parent */
+  RQ_A,        /* to '*'    */
+  RQ_AQ,       /* to '*?'   */
+  RQ_QQ,       /* to '??'   */
+  RQ_P_QQ,     /* to '+)??' */
+  RQ_PQ_Q      /* to '+?)?' */
+};
+
+static enum ReduceType const ReduceTypeTable[6][6] = {
+/* '?',     '*',     '+',    '??',    '*?',    '+?'      p / c   */
+  {RQ_DEL,  RQ_A,    RQ_A,   RQ_QQ,   RQ_AQ,   RQ_ASIS}, /* '?'  */
+  {RQ_DEL,  RQ_DEL,  RQ_DEL, RQ_P_QQ, RQ_P_QQ, RQ_DEL},  /* '*'  */
+  {RQ_A,    RQ_A,    RQ_DEL, RQ_ASIS, RQ_P_QQ, RQ_DEL},  /* '+'  */
+  {RQ_DEL,  RQ_AQ,   RQ_AQ,  RQ_DEL,  RQ_AQ,   RQ_AQ},   /* '??' */
+  {RQ_DEL,  RQ_DEL,  RQ_DEL, RQ_DEL,  RQ_DEL,  RQ_DEL},  /* '*?' */
+  {RQ_ASIS, RQ_PQ_Q, RQ_DEL, RQ_AQ,   RQ_AQ,   RQ_DEL}   /* '+?' */
+};
+
+extern void
+onig_reduce_nested_quantifier(Node* pnode, Node* cnode)
+{
+  int pnum, cnum;
+  QtfrNode *p, *c;
+
+  p = NQTFR(pnode);
+  c = NQTFR(cnode);
+  pnum = popular_quantifier_num(p);
+  cnum = popular_quantifier_num(c);
+  if (pnum < 0 || cnum < 0) return ;
+
+  switch (ReduceTypeTable[cnum][pnum]) {
+  case RQ_DEL:
+    *pnode = *cnode;
+    break;
+  case RQ_A:
+    p->target = c->target;
+    p->lower  = 0;  p->upper = REPEAT_INFINITE;  p->greedy = 1;
+    break;
+  case RQ_AQ:
+    p->target = c->target;
+    p->lower  = 0;  p->upper = REPEAT_INFINITE;  p->greedy = 0;
+    break;
+  case RQ_QQ:
+    p->target = c->target;
+    p->lower  = 0;  p->upper = 1;  p->greedy = 0;
+    break;
+  case RQ_P_QQ:
+    p->target = cnode;
+    p->lower  = 0;  p->upper = 1;  p->greedy = 0;
+    c->lower  = 1;  c->upper = REPEAT_INFINITE;  c->greedy = 1;
+    return ;
+    break;
+  case RQ_PQ_Q:
+    p->target = cnode;
+    p->lower  = 0;  p->upper = 1;  p->greedy = 1;
+    c->lower  = 1;  c->upper = REPEAT_INFINITE;  c->greedy = 0;
+    return ;
+    break;
+  case RQ_ASIS:
+    p->target = cnode;
+    return ;
+    break;
+  }
+
+  c->target = NULL_NODE;
+  onig_node_free(cnode);
+}
+
+
+enum TokenSyms {
+  TK_EOT      = 0,   /* end of token */
+  TK_RAW_BYTE = 1,
+  TK_CHAR,
+  TK_STRING,
+  TK_CODE_POINT,
+  TK_ANYCHAR,
+  TK_CHAR_TYPE,
+  TK_BACKREF,
+  TK_CALL,
+  TK_ANCHOR,
+  TK_OP_REPEAT,
+  TK_INTERVAL,
+  TK_ANYCHAR_ANYTIME,  /* SQL '%' == .* */
+  TK_ALT,
+  TK_SUBEXP_OPEN,
+  TK_SUBEXP_CLOSE,
+  TK_CC_OPEN,
+  TK_QUOTE_OPEN,
+  TK_CHAR_PROPERTY,    /* \p{...}, \P{...} */
+  TK_LINEBREAK,
+  TK_EXTENDED_GRAPHEME_CLUSTER,
+  TK_KEEP,
+  /* in cc */
+  TK_CC_CLOSE,
+  TK_CC_RANGE,
+  TK_POSIX_BRACKET_OPEN,
+  TK_CC_AND,             /* && */
+  TK_CC_CC_OPEN          /* [ */
+};
+
+typedef struct {
+  enum TokenSyms type;
+  int escaped;
+  int base;   /* is number: 8, 16 (used in [....]) */
+  UChar* backp;
+  union {
+    UChar* s;
+    int   c;
+    OnigCodePoint code;
+    struct {
+      int subtype;
+      int ascii_range;
+    } anchor;
+    struct {
+      int lower;
+      int upper;
+      int greedy;
+      int possessive;
+    } repeat;
+    struct {
+      int  num;
+      int  ref1;
+      int* refs;
+      int  by_name;
+#ifdef USE_BACKREF_WITH_LEVEL
+      int  exist_level;
+      int  level;   /* \k<name+n> */
+#endif
+    } backref;
+    struct {
+      UChar* name;
+      UChar* name_end;
+      int    gnum;
+      int    rel;
+    } call;
+    struct {
+      int ctype;
+      int not;
+    } prop;
+  } u;
+} OnigToken;
+
+
+static int
+fetch_range_quantifier(UChar** src, UChar* end, OnigToken* tok, ScanEnv* env)
+{
+  int low, up, syn_allow, non_low = 0;
+  int r = 0;
+  OnigCodePoint c;
+  OnigEncoding enc = env->enc;
+  UChar* p = *src;
+  PFETCH_READY;
+
+  syn_allow = IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_INVALID_INTERVAL);
+
+  if (PEND) {
+    if (syn_allow)
+      return 1;  /* "....{" : OK! */
+    else
+      return ONIGERR_END_PATTERN_AT_LEFT_BRACE;  /* "....{" syntax error */
+  }
+
+  if (! syn_allow) {
+    c = PPEEK;
+    if (c == ')' || c == '(' || c == '|') {
+      return ONIGERR_END_PATTERN_AT_LEFT_BRACE;
+    }
+  }
+
+  low = onig_scan_unsigned_number(&p, end, env->enc);
+  if (low < 0) return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE;
+  if (low > ONIG_MAX_REPEAT_NUM)
+    return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE;
+
+  if (p == *src) { /* can't read low */
+    if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV)) {
+      /* allow {,n} as {0,n} */
+      low = 0;
+      non_low = 1;
+    }
+    else
+      goto invalid;
+  }
+
+  if (PEND) goto invalid;
+  PFETCH(c);
+  if (c == ',') {
+    UChar* prev = p;
+    up = onig_scan_unsigned_number(&p, end, env->enc);
+    if (up < 0) return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE;
+    if (up > ONIG_MAX_REPEAT_NUM)
+      return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE;
+
+    if (p == prev) {
+      if (non_low != 0)
+	goto invalid;
+      up = REPEAT_INFINITE;  /* {n,} : {n,infinite} */
+    }
+  }
+  else {
+    if (non_low != 0)
+      goto invalid;
+
+    PUNFETCH;
+    up = low;  /* {n} : exact n times */
+    r = 2;     /* fixed */
+  }
+
+  if (PEND) goto invalid;
+  PFETCH(c);
+  if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_BRACE_INTERVAL)) {
+    if (c != MC_ESC(env->syntax)) goto invalid;
+    if (PEND) goto invalid;
+    PFETCH(c);
+  }
+  if (c != '}') goto invalid;
+
+  if (!IS_REPEAT_INFINITE(up) && low > up) {
+    return ONIGERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE;
+  }
+
+  tok->type = TK_INTERVAL;
+  tok->u.repeat.lower = low;
+  tok->u.repeat.upper = up;
+  *src = p;
+  return r; /* 0: normal {n,m}, 2: fixed {n} */
+
+ invalid:
+  if (syn_allow)
+    return 1;  /* OK */
+  else
+    return ONIGERR_INVALID_REPEAT_RANGE_PATTERN;
+}
+
+/* \M-, \C-, \c, or \... */
+static int
+fetch_escaped_value(UChar** src, UChar* end, ScanEnv* env, OnigCodePoint* val)
+{
+  int v;
+  OnigCodePoint c;
+  OnigEncoding enc = env->enc;
+  UChar* p = *src;
+
+  if (PEND) return ONIGERR_END_PATTERN_AT_ESCAPE;
+
+  PFETCH_S(c);
+  switch (c) {
+  case 'M':
+    if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META)) {
+      if (PEND) return ONIGERR_END_PATTERN_AT_META;
+      PFETCH_S(c);
+      if (c != '-') return ONIGERR_META_CODE_SYNTAX;
+      if (PEND) return ONIGERR_END_PATTERN_AT_META;
+      PFETCH_S(c);
+      if (c == MC_ESC(env->syntax)) {
+	v = fetch_escaped_value(&p, end, env, &c);
+	if (v < 0) return v;
+      }
+      c = ((c & 0xff) | 0x80);
+    }
+    else
+      goto backslash;
+    break;
+
+  case 'C':
+    if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL)) {
+      if (PEND) return ONIGERR_END_PATTERN_AT_CONTROL;
+      PFETCH_S(c);
+      if (c != '-') return ONIGERR_CONTROL_CODE_SYNTAX;
+      goto control;
+    }
+    else
+      goto backslash;
+
+  case 'c':
+    if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_C_CONTROL)) {
+    control:
+      if (PEND) return ONIGERR_END_PATTERN_AT_CONTROL;
+      PFETCH_S(c);
+      if (c == '?') {
+	c = 0177;
+      }
+      else {
+	if (c == MC_ESC(env->syntax)) {
+	  v = fetch_escaped_value(&p, end, env, &c);
+	  if (v < 0) return v;
+	}
+	c &= 0x9f;
+      }
+      break;
+    }
+    /* fall through */
+
+  default:
+    {
+    backslash:
+      c = conv_backslash_value(c, env);
+    }
+    break;
+  }
+
+  *src = p;
+  *val = c;
+  return 0;
+}
+
+static int fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env);
+
+static OnigCodePoint
+get_name_end_code_point(OnigCodePoint start)
+{
+  switch (start) {
+  case '<':  return (OnigCodePoint )'>'; break;
+  case '\'': return (OnigCodePoint )'\''; break;
+  case '(':  return (OnigCodePoint )')'; break;
+  case '{':  return (OnigCodePoint )'}'; break;
+  default:
+    break;
+  }
+
+  return (OnigCodePoint )0;
+}
+
+#ifdef USE_NAMED_GROUP
+# ifdef RUBY
+#  define ONIGENC_IS_CODE_NAME(enc, c)  TRUE
+# else
+#  define ONIGENC_IS_CODE_NAME(enc, c)  ONIGENC_IS_CODE_WORD(enc, c)
+# endif
+
+# ifdef USE_BACKREF_WITH_LEVEL
+/*
+   \k<name+n>, \k<name-n>
+   \k<num+n>,  \k<num-n>
+   \k<-num+n>, \k<-num-n>
+*/
+static int
+fetch_name_with_level(OnigCodePoint start_code, UChar** src, UChar* end,
+		      UChar** rname_end, ScanEnv* env,
+		      int* rback_num, int* rlevel)
+{
+  int r, sign, is_num, exist_level;
+  OnigCodePoint end_code;
+  OnigCodePoint c = 0;
+  OnigEncoding enc = env->enc;
+  UChar *name_end;
+  UChar *pnum_head;
+  UChar *p = *src;
+  PFETCH_READY;
+
+  *rback_num = 0;
+  is_num = exist_level = 0;
+  sign = 1;
+  pnum_head = *src;
+
+  end_code = get_name_end_code_point(start_code);
+
+  name_end = end;
+  r = 0;
+  if (PEND) {
+    return ONIGERR_EMPTY_GROUP_NAME;
+  }
+  else {
+    PFETCH(c);
+    if (c == end_code)
+      return ONIGERR_EMPTY_GROUP_NAME;
+
+    if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
+      is_num = 1;
+    }
+    else if (c == '-') {
+      is_num = 2;
+      sign = -1;
+      pnum_head = p;
+    }
+    else if (!ONIGENC_IS_CODE_NAME(enc, c)) {
+      r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
+    }
+  }
+
+  while (!PEND) {
+    name_end = p;
+    PFETCH(c);
+    if (c == end_code || c == ')' || c == '+' || c == '-') {
+      if (is_num == 2) r = ONIGERR_INVALID_GROUP_NAME;
+      break;
+    }
+
+    if (is_num != 0) {
+      if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
+	is_num = 1;
+      }
+      else {
+	r = ONIGERR_INVALID_GROUP_NAME;
+	is_num = 0;
+      }
+    }
+    else if (!ONIGENC_IS_CODE_NAME(enc, c)) {
+      r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
+    }
+  }
+
+  if (r == 0 && c != end_code) {
+    if (c == '+' || c == '-') {
+      int level;
+      int flag = (c == '-' ? -1 : 1);
+
+      if (PEND) {
+	r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
+	goto end;
+      }
+      PFETCH(c);
+      if (! ONIGENC_IS_CODE_DIGIT(enc, c)) goto err;
+      PUNFETCH;
+      level = onig_scan_unsigned_number(&p, end, enc);
+      if (level < 0) return ONIGERR_TOO_BIG_NUMBER;
+      *rlevel = (level * flag);
+      exist_level = 1;
+
+      if (!PEND) {
+	PFETCH(c);
+	if (c == end_code)
+	  goto end;
+      }
+    }
+
+  err:
+    r = ONIGERR_INVALID_GROUP_NAME;
+    name_end = end;
+  }
+
+ end:
+  if (r == 0) {
+    if (is_num != 0) {
+      *rback_num = onig_scan_unsigned_number(&pnum_head, name_end, enc);
+      if (*rback_num < 0) return ONIGERR_TOO_BIG_NUMBER;
+      else if (*rback_num == 0) goto err;
+
+      *rback_num *= sign;
+    }
+
+    *rname_end = name_end;
+    *src = p;
+    return (exist_level ? 1 : 0);
+  }
+  else {
+    onig_scan_env_set_error_string(env, r, *src, name_end);
+    return r;
+  }
+}
+# endif /* USE_BACKREF_WITH_LEVEL */
+
+/*
+  ref: 0 -> define name    (don't allow number name)
+       1 -> reference name (allow number name)
+*/
+static int
+fetch_name(OnigCodePoint start_code, UChar** src, UChar* end,
+	   UChar** rname_end, ScanEnv* env, int* rback_num, int ref)
+{
+  int r, is_num, sign;
+  OnigCodePoint end_code;
+  OnigCodePoint c = 0;
+  OnigEncoding enc = env->enc;
+  UChar *name_end;
+  UChar *pnum_head;
+  UChar *p = *src;
+
+  *rback_num = 0;
+
+  end_code = get_name_end_code_point(start_code);
+
+  name_end = end;
+  pnum_head = *src;
+  r = 0;
+  is_num = 0;
+  sign = 1;
+  if (PEND) {
+    return ONIGERR_EMPTY_GROUP_NAME;
+  }
+  else {
+    PFETCH_S(c);
+    if (c == end_code)
+      return ONIGERR_EMPTY_GROUP_NAME;
+
+    if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
+      if (ref == 1)
+	is_num = 1;
+      else {
+	r = ONIGERR_INVALID_GROUP_NAME;
+	is_num = 0;
+      }
+    }
+    else if (c == '-') {
+      if (ref == 1) {
+	is_num = 2;
+	sign = -1;
+	pnum_head = p;
+      }
+      else {
+	r = ONIGERR_INVALID_GROUP_NAME;
+	is_num = 0;
+      }
+    }
+    else if (!ONIGENC_IS_CODE_NAME(enc, c)) {
+      r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
+    }
+  }
+
+  if (r == 0) {
+    while (!PEND) {
+      name_end = p;
+      PFETCH_S(c);
+      if (c == end_code || c == ')') {
+	if (is_num == 2) {
+	  r = ONIGERR_INVALID_GROUP_NAME;
+	  goto teardown;
+	}
+	break;
+      }
+
+      if (is_num != 0) {
+	if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
+	  is_num = 1;
+	}
+	else {
+	  if (!ONIGENC_IS_CODE_WORD(enc, c))
+	    r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
+	  else
+	    r = ONIGERR_INVALID_GROUP_NAME;
+	  goto teardown;
+	}
+      }
+      else {
+	if (!ONIGENC_IS_CODE_NAME(enc, c)) {
+	  r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
+	  goto teardown;
+	}
+      }
+    }
+
+    if (c != end_code) {
+      r = ONIGERR_INVALID_GROUP_NAME;
+      name_end = end;
+      goto err;
+    }
+
+    if (is_num != 0) {
+      *rback_num = onig_scan_unsigned_number(&pnum_head, name_end, enc);
+      if (*rback_num < 0) return ONIGERR_TOO_BIG_NUMBER;
+      else if (*rback_num == 0) {
+	r = ONIGERR_INVALID_GROUP_NAME;
+	goto err;
+      }
+
+      *rback_num *= sign;
+    }
+
+    *rname_end = name_end;
+    *src = p;
+    return 0;
+  }
+  else {
+teardown:
+    while (!PEND) {
+      name_end = p;
+      PFETCH_S(c);
+      if (c == end_code || c == ')')
+	break;
+    }
+    if (PEND)
+      name_end = end;
+
+  err:
+    onig_scan_env_set_error_string(env, r, *src, name_end);
+    return r;
+  }
+}
+#else
+static int
+fetch_name(OnigCodePoint start_code, UChar** src, UChar* end,
+	   UChar** rname_end, ScanEnv* env, int* rback_num, int ref)
+{
+  int r, is_num, sign;
+  OnigCodePoint end_code;
+  OnigCodePoint c = 0;
+  UChar *name_end;
+  OnigEncoding enc = env->enc;
+  UChar *pnum_head;
+  UChar *p = *src;
+  PFETCH_READY;
+
+  *rback_num = 0;
+
+  end_code = get_name_end_code_point(start_code);
+
+  *rname_end = name_end = end;
+  r = 0;
+  pnum_head = *src;
+  is_num = 0;
+  sign = 1;
+
+  if (PEND) {
+    return ONIGERR_EMPTY_GROUP_NAME;
+  }
+  else {
+    PFETCH(c);
+    if (c == end_code)
+      return ONIGERR_EMPTY_GROUP_NAME;
+
+    if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
+      is_num = 1;
+    }
+    else if (c == '-') {
+      is_num = 2;
+      sign = -1;
+      pnum_head = p;
+    }
+    else {
+      r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
+    }
+  }
+
+  while (!PEND) {
+    name_end = p;
+
+    PFETCH(c);
+    if (c == end_code || c == ')') break;
+    if (! ONIGENC_IS_CODE_DIGIT(enc, c))
+      r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
+  }
+  if (r == 0 && c != end_code) {
+    r = ONIGERR_INVALID_GROUP_NAME;
+    name_end = end;
+  }
+
+  if (r == 0) {
+    *rback_num = onig_scan_unsigned_number(&pnum_head, name_end, enc);
+    if (*rback_num < 0) return ONIGERR_TOO_BIG_NUMBER;
+    else if (*rback_num == 0) {
+      r = ONIGERR_INVALID_GROUP_NAME;
+      goto err;
+    }
+    *rback_num *= sign;
+
+    *rname_end = name_end;
+    *src = p;
+    return 0;
+  }
+  else {
+  err:
+    onig_scan_env_set_error_string(env, r, *src, name_end);
+    return r;
+  }
+}
+#endif /* USE_NAMED_GROUP */
+
+
+static void
+onig_syntax_warn(ScanEnv *env, const char *fmt, ...)
+{
+    va_list args;
+    UChar buf[WARN_BUFSIZE];
+    va_start(args, fmt);
+    onig_vsnprintf_with_pattern(buf, WARN_BUFSIZE, env->enc,
+		env->pattern, env->pattern_end,
+		(const UChar *)fmt, args);
+    va_end(args);
+#ifdef RUBY
+    if (env->sourcefile == NULL)
+      rb_warn("%s", (char *)buf);
+    else
+      rb_compile_warn(env->sourcefile, env->sourceline, "%s", (char *)buf);
+#else
+    (*onig_warn)((char* )buf);
+#endif
+}
+
+static void
+CC_ESC_WARN(ScanEnv *env, UChar *c)
+{
+  if (onig_warn == onig_null_warn) return ;
+
+  if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_WARN_CC_OP_NOT_ESCAPED) &&
+      IS_SYNTAX_BV(env->syntax, ONIG_SYN_BACKSLASH_ESCAPE_IN_CC)) {
+    onig_syntax_warn(env, "character class has '%s' without escape", c);
+  }
+}
+
+static void
+CLOSE_BRACKET_WITHOUT_ESC_WARN(ScanEnv* env, UChar* c)
+{
+  if (onig_warn == onig_null_warn) return ;
+
+  if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_WARN_CC_OP_NOT_ESCAPED)) {
+    onig_syntax_warn(env, "regular expression has '%s' without escape", c);
+  }
+}
+
+#ifndef RTEST
+# define RTEST(v)  1
+#endif
+
+static void
+CC_DUP_WARN(ScanEnv *env)
+{
+  if (onig_warn == onig_null_warn || !RTEST(ruby_verbose)) return ;
+
+  if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_WARN_CC_DUP) &&
+      !(env->warnings_flag & ONIG_SYN_WARN_CC_DUP)) {
+    env->warnings_flag |= ONIG_SYN_WARN_CC_DUP;
+    onig_syntax_warn(env, "character class has duplicated range");
+  }
+}
+
+static void
+UNKNOWN_ESC_WARN(ScanEnv *env, int c)
+{
+  if (onig_warn == onig_null_warn || !RTEST(ruby_verbose)) return ;
+  onig_syntax_warn(env, "Unknown escape \\%c is ignored", c);
+}
+
+static UChar*
+find_str_position(OnigCodePoint s[], int n, UChar* from, UChar* to,
+		  UChar **next, OnigEncoding enc)
+{
+  int i;
+  OnigCodePoint x;
+  UChar *q;
+  UChar *p = from;
+
+  while (p < to) {
+    x = ONIGENC_MBC_TO_CODE(enc, p, to);
+    q = p + enclen(enc, p, to);
+    if (x == s[0]) {
+      for (i = 1; i < n && q < to; i++) {
+	x = ONIGENC_MBC_TO_CODE(enc, q, to);
+	if (x != s[i]) break;
+	q += enclen(enc, q, to);
+      }
+      if (i >= n) {
+	if (IS_NOT_NULL(next))
+	  *next = q;
+	return p;
+      }
+    }
+    p = q;
+  }
+  return NULL_UCHARP;
+}
+
+static int
+str_exist_check_with_esc(OnigCodePoint s[], int n, UChar* from, UChar* to,
+		 OnigCodePoint bad, OnigEncoding enc, const OnigSyntaxType* syn)
+{
+  int i, in_esc;
+  OnigCodePoint x;
+  UChar *q;
+  UChar *p = from;
+
+  in_esc = 0;
+  while (p < to) {
+    if (in_esc) {
+      in_esc = 0;
+      p += enclen(enc, p, to);
+    }
+    else {
+      x = ONIGENC_MBC_TO_CODE(enc, p, to);
+      q = p + enclen(enc, p, to);
+      if (x == s[0]) {
+	for (i = 1; i < n && q < to; i++) {
+	  x = ONIGENC_MBC_TO_CODE(enc, q, to);
+	  if (x != s[i]) break;
+	  q += enclen(enc, q, to);
+	}
+	if (i >= n) return 1;
+	p += enclen(enc, p, to);
+      }
+      else {
+	x = ONIGENC_MBC_TO_CODE(enc, p, to);
+	if (x == bad) return 0;
+	else if (x == MC_ESC(syn)) in_esc = 1;
+	p = q;
+      }
+    }
+  }
+  return 0;
+}
+
+static int
+fetch_token_in_cc(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
+{
+  int num;
+  OnigCodePoint c, c2;
+  const OnigSyntaxType* syn = env->syntax;
+  OnigEncoding enc = env->enc;
+  UChar* prev;
+  UChar* p = *src;
+  PFETCH_READY;
+
+  if (PEND) {
+    tok->type = TK_EOT;
+    return tok->type;
+  }
+
+  PFETCH(c);
+  tok->type = TK_CHAR;
+  tok->base = 0;
+  tok->u.c  = c;
+  tok->escaped = 0;
+
+  if (c == ']') {
+    tok->type = TK_CC_CLOSE;
+  }
+  else if (c == '-') {
+    tok->type = TK_CC_RANGE;
+  }
+  else if (c == MC_ESC(syn)) {
+    if (! IS_SYNTAX_BV(syn, ONIG_SYN_BACKSLASH_ESCAPE_IN_CC))
+      goto end;
+
+    if (PEND) return ONIGERR_END_PATTERN_AT_ESCAPE;
+
+    PFETCH(c);
+    tok->escaped = 1;
+    tok->u.c = c;
+    switch (c) {
+    case 'w':
+      tok->type = TK_CHAR_TYPE;
+      tok->u.prop.ctype = ONIGENC_CTYPE_WORD;
+      tok->u.prop.not   = 0;
+      break;
+    case 'W':
+      tok->type = TK_CHAR_TYPE;
+      tok->u.prop.ctype = ONIGENC_CTYPE_WORD;
+      tok->u.prop.not   = 1;
+      break;
+    case 'd':
+      tok->type = TK_CHAR_TYPE;
+      tok->u.prop.ctype = ONIGENC_CTYPE_DIGIT;
+      tok->u.prop.not   = 0;
+      break;
+    case 'D':
+      tok->type = TK_CHAR_TYPE;
+      tok->u.prop.ctype = ONIGENC_CTYPE_DIGIT;
+      tok->u.prop.not   = 1;
+      break;
+    case 's':
+      tok->type = TK_CHAR_TYPE;
+      tok->u.prop.ctype = ONIGENC_CTYPE_SPACE;
+      tok->u.prop.not   = 0;
+      break;
+    case 'S':
+      tok->type = TK_CHAR_TYPE;
+      tok->u.prop.ctype = ONIGENC_CTYPE_SPACE;
+      tok->u.prop.not   = 1;
+      break;
+    case 'h':
+      if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
+      tok->type = TK_CHAR_TYPE;
+      tok->u.prop.ctype = ONIGENC_CTYPE_XDIGIT;
+      tok->u.prop.not   = 0;
+      break;
+    case 'H':
+      if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
+      tok->type = TK_CHAR_TYPE;
+      tok->u.prop.ctype = ONIGENC_CTYPE_XDIGIT;
+      tok->u.prop.not   = 1;
+      break;
+
+    case 'p':
+    case 'P':
+      if (PEND) break;
+
+      c2 = PPEEK;
+      if (c2 == '{' &&
+	  IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY)) {
+	PINC;
+	tok->type = TK_CHAR_PROPERTY;
+	tok->u.prop.not = (c == 'P' ? 1 : 0);
+
+	if (!PEND && IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT)) {
+	  PFETCH(c2);
+	  if (c2 == '^') {
+	    tok->u.prop.not = (tok->u.prop.not == 0 ? 1 : 0);
+	  }
+	  else
+	    PUNFETCH;
+	}
+      }
+      else {
+	onig_syntax_warn(env, "invalid Unicode Property \\%c", c);
+      }
+      break;
+
+    case 'x':
+      if (PEND) break;
+
+      prev = p;
+      if (PPEEK_IS('{') && IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_BRACE_HEX8)) {
+	PINC;
+	num = scan_unsigned_hexadecimal_number(&p, end, 0, 8, enc);
+	if (num < 0) return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
+	if (!PEND) {
+	  c2 = PPEEK;
+	  if (ONIGENC_IS_CODE_XDIGIT(enc, c2))
+	    return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE;
+	}
+
+	if (p > prev + enclen(enc, prev, end) && !PEND && (PPEEK_IS('}'))) {
+	  PINC;
+	  tok->type   = TK_CODE_POINT;
+	  tok->base   = 16;
+	  tok->u.code = (OnigCodePoint )num;
+	}
+	else {
+	  /* can't read nothing or invalid format */
+	  p = prev;
+	}
+      }
+      else if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_HEX2)) {
+	num = scan_unsigned_hexadecimal_number(&p, end, 0, 2, enc);
+	if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
+	if (p == prev) {  /* can't read nothing. */
+	  num = 0; /* but, it's not error */
+	}
+	tok->type = TK_RAW_BYTE;
+	tok->base = 16;
+	tok->u.c  = num;
+      }
+      break;
+
+    case 'u':
+      if (PEND) break;
+
+      prev = p;
+      if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_U_HEX4)) {
+	num = scan_unsigned_hexadecimal_number(&p, end, 4, 4, enc);
+	if (num < -1) return ONIGERR_TOO_SHORT_DIGITS;
+	else if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
+	if (p == prev) {  /* can't read nothing. */
+	  num = 0; /* but, it's not error */
+	}
+	tok->type   = TK_CODE_POINT;
+	tok->base   = 16;
+	tok->u.code = (OnigCodePoint )num;
+      }
+      break;
+
+    case 'o':
+      if (PEND) break;
+
+      prev = p;
+      if (PPEEK_IS('{') && IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_O_BRACE_OCTAL)) {
+	PINC;
+	num = scan_unsigned_octal_number(&p, end, 11, enc);
+	if (num < 0) return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
+	if (!PEND) {
+	  c2 = PPEEK;
+	  if (ONIGENC_IS_CODE_DIGIT(enc, c2) && c2 < '8')
+	    return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE;
+	}
+
+	if (p > prev + enclen(enc, prev, end) && !PEND && (PPEEK_IS('}'))) {
+	  PINC;
+	  tok->type   = TK_CODE_POINT;
+	  tok->base   = 8;
+	  tok->u.code = (OnigCodePoint )num;
+	}
+	else {
+	  /* can't read nothing or invalid format */
+	  p = prev;
+	}
+      }
+      break;
+
+    case '0':
+    case '1': case '2': case '3': case '4': case '5': case '6': case '7':
+      if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_OCTAL3)) {
+	PUNFETCH;
+	prev = p;
+	num = scan_unsigned_octal_number(&p, end, 3, enc);
+	if (num < 0 || 0xff < num) return ONIGERR_TOO_BIG_NUMBER;
+	if (p == prev) {  /* can't read nothing. */
+	  num = 0; /* but, it's not error */
+	}
+	tok->type = TK_RAW_BYTE;
+	tok->base = 8;
+	tok->u.c  = num;
+      }
+      break;
+
+    default:
+      PUNFETCH;
+      num = fetch_escaped_value(&p, end, env, &c2);
+      if (num < 0) return num;
+      if ((OnigCodePoint )tok->u.c != c2) {
+	tok->u.code = (OnigCodePoint )c2;
+	tok->type   = TK_CODE_POINT;
+      }
+      break;
+    }
+  }
+  else if (c == '[') {
+    if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_POSIX_BRACKET) && (PPEEK_IS(':'))) {
+      OnigCodePoint send[] = { (OnigCodePoint )':', (OnigCodePoint )']' };
+      tok->backp = p; /* point at '[' is read */
+      PINC;
+      if (str_exist_check_with_esc(send, 2, p, end,
+                                   (OnigCodePoint )']', enc, syn)) {
+	tok->type = TK_POSIX_BRACKET_OPEN;
+      }
+      else {
+	PUNFETCH;
+	goto cc_in_cc;
+      }
+    }
+    else {
+    cc_in_cc:
+      if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_CCLASS_SET_OP)) {
+	tok->type = TK_CC_CC_OPEN;
+      }
+      else {
+	CC_ESC_WARN(env, (UChar* )"[");
+      }
+    }
+  }
+  else if (c == '&') {
+    if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_CCLASS_SET_OP) &&
+	!PEND && (PPEEK_IS('&'))) {
+      PINC;
+      tok->type = TK_CC_AND;
+    }
+  }
+
+ end:
+  *src = p;
+  return tok->type;
+}
+
+#ifdef USE_NAMED_GROUP
+static int
+fetch_named_backref_token(OnigCodePoint c, OnigToken* tok, UChar** src,
+			  UChar* end, ScanEnv* env)
+{
+  int r, num;
+  const OnigSyntaxType* syn = env->syntax;
+  UChar* prev;
+  UChar* p = *src;
+  UChar* name_end;
+  int* backs;
+  int back_num;
+
+  prev = p;
+
+# ifdef USE_BACKREF_WITH_LEVEL
+  name_end = NULL_UCHARP; /* no need. escape gcc warning. */
+  r = fetch_name_with_level(c, &p, end, &name_end,
+			    env, &back_num, &tok->u.backref.level);
+  if (r == 1) tok->u.backref.exist_level = 1;
+  else        tok->u.backref.exist_level = 0;
+# else
+  r = fetch_name(&p, end, &name_end, env, &back_num, 1);
+# endif
+  if (r < 0) return r;
+
+  if (back_num != 0) {
+    if (back_num < 0) {
+      back_num = BACKREF_REL_TO_ABS(back_num, env);
+      if (back_num <= 0)
+	return ONIGERR_INVALID_BACKREF;
+    }
+
+    if (IS_SYNTAX_BV(syn, ONIG_SYN_STRICT_CHECK_BACKREF)) {
+      if (back_num > env->num_mem ||
+	  IS_NULL(SCANENV_MEM_NODES(env)[back_num]))
+	return ONIGERR_INVALID_BACKREF;
+    }
+    tok->type = TK_BACKREF;
+    tok->u.backref.by_name = 0;
+    tok->u.backref.num  = 1;
+    tok->u.backref.ref1 = back_num;
+  }
+  else {
+    num = onig_name_to_group_numbers(env->reg, prev, name_end, &backs);
+    if (num <= 0) {
+      onig_scan_env_set_error_string(env,
+		     ONIGERR_UNDEFINED_NAME_REFERENCE, prev, name_end);
+      return ONIGERR_UNDEFINED_NAME_REFERENCE;
+    }
+    if (IS_SYNTAX_BV(syn, ONIG_SYN_STRICT_CHECK_BACKREF)) {
+      int i;
+      for (i = 0; i < num; i++) {
+	if (backs[i] > env->num_mem ||
+	    IS_NULL(SCANENV_MEM_NODES(env)[backs[i]]))
+	  return ONIGERR_INVALID_BACKREF;
+      }
+    }
+
+    tok->type = TK_BACKREF;
+    tok->u.backref.by_name = 1;
+    if (num == 1 || IS_SYNTAX_BV(syn, ONIG_SYN_USE_LEFT_MOST_NAMED_GROUP)) {
+      tok->u.backref.num  = 1;
+      tok->u.backref.ref1 = backs[0];
+    }
+    else {
+      tok->u.backref.num  = num;
+      tok->u.backref.refs = backs;
+    }
+  }
+  *src = p;
+  return 0;
+}
+#endif
+
+static int
+fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
+{
+  int r, num;
+  OnigCodePoint c;
+  OnigEncoding enc = env->enc;
+  const OnigSyntaxType* syn = env->syntax;
+  UChar* prev;
+  UChar* p = *src;
+  PFETCH_READY;
+
+ start:
+  if (PEND) {
+    tok->type = TK_EOT;
+    return tok->type;
+  }
+
+  tok->type  = TK_STRING;
+  tok->base  = 0;
+  tok->backp = p;
+
+  PFETCH(c);
+  if (IS_MC_ESC_CODE(c, syn)) {
+    if (PEND) return ONIGERR_END_PATTERN_AT_ESCAPE;
+
+    tok->backp = p;
+    PFETCH(c);
+
+    tok->u.c = c;
+    tok->escaped = 1;
+    switch (c) {
+    case '*':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_ASTERISK_ZERO_INF)) break;
+      tok->type = TK_OP_REPEAT;
+      tok->u.repeat.lower = 0;
+      tok->u.repeat.upper = REPEAT_INFINITE;
+      goto greedy_check;
+      break;
+
+    case '+':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_PLUS_ONE_INF)) break;
+      tok->type = TK_OP_REPEAT;
+      tok->u.repeat.lower = 1;
+      tok->u.repeat.upper = REPEAT_INFINITE;
+      goto greedy_check;
+      break;
+
+    case '?':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_QMARK_ZERO_ONE)) break;
+      tok->type = TK_OP_REPEAT;
+      tok->u.repeat.lower = 0;
+      tok->u.repeat.upper = 1;
+    greedy_check:
+      if (!PEND && PPEEK_IS('?') &&
+	  IS_SYNTAX_OP(syn, ONIG_SYN_OP_QMARK_NON_GREEDY)) {
+	PFETCH(c);
+	tok->u.repeat.greedy     = 0;
+	tok->u.repeat.possessive = 0;
+      }
+      else {
+      possessive_check:
+	if (!PEND && PPEEK_IS('+') &&
+	    ((IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT) &&
+	      tok->type != TK_INTERVAL)  ||
+	     (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_PLUS_POSSESSIVE_INTERVAL) &&
+	      tok->type == TK_INTERVAL))) {
+	  PFETCH(c);
+	  tok->u.repeat.greedy     = 1;
+	  tok->u.repeat.possessive = 1;
+	}
+	else {
+	  tok->u.repeat.greedy     = 1;
+	  tok->u.repeat.possessive = 0;
+	}
+      }
+      break;
+
+    case '{':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_BRACE_INTERVAL)) break;
+      r = fetch_range_quantifier(&p, end, tok, env);
+      if (r < 0) return r;  /* error */
+      if (r == 0) goto greedy_check;
+      else if (r == 2) { /* {n} */
+	if (IS_SYNTAX_BV(syn, ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY))
+	  goto possessive_check;
+
+	goto greedy_check;
+      }
+      /* r == 1 : normal char */
+      break;
+
+    case '|':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_VBAR_ALT)) break;
+      tok->type = TK_ALT;
+      break;
+
+    case '(':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LPAREN_SUBEXP)) break;
+      tok->type = TK_SUBEXP_OPEN;
+      break;
+
+    case ')':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LPAREN_SUBEXP)) break;
+      tok->type = TK_SUBEXP_CLOSE;
+      break;
+
+    case 'w':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_W_WORD)) break;
+      tok->type = TK_CHAR_TYPE;
+      tok->u.prop.ctype = ONIGENC_CTYPE_WORD;
+      tok->u.prop.not   = 0;
+      break;
+
+    case 'W':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_W_WORD)) break;
+      tok->type = TK_CHAR_TYPE;
+      tok->u.prop.ctype = ONIGENC_CTYPE_WORD;
+      tok->u.prop.not   = 1;
+      break;
+
+    case 'b':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_B_WORD_BOUND)) break;
+      tok->type = TK_ANCHOR;
+      tok->u.anchor.subtype = ANCHOR_WORD_BOUND;
+      tok->u.anchor.ascii_range = IS_ASCII_RANGE(env->option)
+		&& ! IS_WORD_BOUND_ALL_RANGE(env->option);
+      break;
+
+    case 'B':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_B_WORD_BOUND)) break;
+      tok->type = TK_ANCHOR;
+      tok->u.anchor.subtype = ANCHOR_NOT_WORD_BOUND;
+      tok->u.anchor.ascii_range = IS_ASCII_RANGE(env->option)
+		&& ! IS_WORD_BOUND_ALL_RANGE(env->option);
+      break;
+
+#ifdef USE_WORD_BEGIN_END
+    case '<':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END)) break;
+      tok->type = TK_ANCHOR;
+      tok->u.anchor.subtype = ANCHOR_WORD_BEGIN;
+      tok->u.anchor.ascii_range = IS_ASCII_RANGE(env->option);
+      break;
+
+    case '>':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END)) break;
+      tok->type = TK_ANCHOR;
+      tok->u.anchor.subtype = ANCHOR_WORD_END;
+      tok->u.anchor.ascii_range = IS_ASCII_RANGE(env->option);
+      break;
+#endif
+
+    case 's':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_S_WHITE_SPACE)) break;
+      tok->type = TK_CHAR_TYPE;
+      tok->u.prop.ctype = ONIGENC_CTYPE_SPACE;
+      tok->u.prop.not   = 0;
+      break;
+
+    case 'S':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_S_WHITE_SPACE)) break;
+      tok->type = TK_CHAR_TYPE;
+      tok->u.prop.ctype = ONIGENC_CTYPE_SPACE;
+      tok->u.prop.not   = 1;
+      break;
+
+    case 'd':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_D_DIGIT)) break;
+      tok->type = TK_CHAR_TYPE;
+      tok->u.prop.ctype = ONIGENC_CTYPE_DIGIT;
+      tok->u.prop.not   = 0;
+      break;
+
+    case 'D':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_D_DIGIT)) break;
+      tok->type = TK_CHAR_TYPE;
+      tok->u.prop.ctype = ONIGENC_CTYPE_DIGIT;
+      tok->u.prop.not   = 1;
+      break;
+
+    case 'h':
+      if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
+      tok->type = TK_CHAR_TYPE;
+      tok->u.prop.ctype = ONIGENC_CTYPE_XDIGIT;
+      tok->u.prop.not   = 0;
+      break;
+
+    case 'H':
+      if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
+      tok->type = TK_CHAR_TYPE;
+      tok->u.prop.ctype = ONIGENC_CTYPE_XDIGIT;
+      tok->u.prop.not   = 1;
+      break;
+
+    case 'A':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR)) break;
+    begin_buf:
+      tok->type = TK_ANCHOR;
+      tok->u.anchor.subtype = ANCHOR_BEGIN_BUF;
+      break;
+
+    case 'Z':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR)) break;
+      tok->type = TK_ANCHOR;
+      tok->u.anchor.subtype = ANCHOR_SEMI_END_BUF;
+      break;
+
+    case 'z':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR)) break;
+    end_buf:
+      tok->type = TK_ANCHOR;
+      tok->u.anchor.subtype = ANCHOR_END_BUF;
+      break;
+
+    case 'G':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_CAPITAL_G_BEGIN_ANCHOR)) break;
+      tok->type = TK_ANCHOR;
+      tok->u.anchor.subtype = ANCHOR_BEGIN_POSITION;
+      break;
+
+    case '`':
+      if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR)) break;
+      goto begin_buf;
+      break;
+
+    case '\'':
+      if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR)) break;
+      goto end_buf;
+      break;
+
+    case 'x':
+      if (PEND) break;
+
+      prev = p;
+      if (PPEEK_IS('{') && IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_BRACE_HEX8)) {
+	PINC;
+	num = scan_unsigned_hexadecimal_number(&p, end, 0, 8, enc);
+	if (num < 0) return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
+	if (!PEND) {
+	  if (ONIGENC_IS_CODE_XDIGIT(enc, PPEEK))
+	    return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE;
+	}
+
+	if ((p > prev + enclen(enc, prev, end)) && !PEND && PPEEK_IS('}')) {
+	  PINC;
+	  tok->type   = TK_CODE_POINT;
+	  tok->u.code = (OnigCodePoint )num;
+	}
+	else {
+	  /* can't read nothing or invalid format */
+	  p = prev;
+	}
+      }
+      else if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_HEX2)) {
+	num = scan_unsigned_hexadecimal_number(&p, end, 0, 2, enc);
+	if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
+	if (p == prev) {  /* can't read nothing. */
+	  num = 0; /* but, it's not error */
+	}
+	tok->type = TK_RAW_BYTE;
+	tok->base = 16;
+	tok->u.c  = num;
+      }
+      break;
+
+    case 'u':
+      if (PEND) break;
+
+      prev = p;
+      if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_U_HEX4)) {
+	num = scan_unsigned_hexadecimal_number(&p, end, 4, 4, enc);
+	if (num < -1) return ONIGERR_TOO_SHORT_DIGITS;
+	else if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
+	if (p == prev) {  /* can't read nothing. */
+	  num = 0; /* but, it's not error */
+	}
+	tok->type   = TK_CODE_POINT;
+	tok->base   = 16;
+	tok->u.code = (OnigCodePoint )num;
+      }
+      break;
+
+    case 'o':
+      if (PEND) break;
+
+      prev = p;
+      if (PPEEK_IS('{') && IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_O_BRACE_OCTAL)) {
+	PINC;
+	num = scan_unsigned_octal_number(&p, end, 11, enc);
+	if (num < 0) return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
+	if (!PEND) {
+	  OnigCodePoint c = PPEEK;
+	  if (ONIGENC_IS_CODE_DIGIT(enc, c) && c < '8')
+	    return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE;
+	}
+
+	if ((p > prev + enclen(enc, prev, end)) && !PEND && PPEEK_IS('}')) {
+	  PINC;
+	  tok->type   = TK_CODE_POINT;
+	  tok->u.code = (OnigCodePoint )num;
+	}
+	else {
+	  /* can't read nothing or invalid format */
+	  p = prev;
+	}
+      }
+      break;
+
+    case '1': case '2': case '3': case '4':
+    case '5': case '6': case '7': case '8': case '9':
+      PUNFETCH;
+      prev = p;
+      num = onig_scan_unsigned_number(&p, end, enc);
+      if (num < 0 || num > ONIG_MAX_BACKREF_NUM) {
+	goto skip_backref;
+      }
+
+      if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_DECIMAL_BACKREF) &&
+	  (num <= env->num_mem || num <= 9)) { /* This spec. from GNU regex */
+	if (IS_SYNTAX_BV(syn, ONIG_SYN_STRICT_CHECK_BACKREF)) {
+	  if (num > env->num_mem || IS_NULL(SCANENV_MEM_NODES(env)[num]))
+	    return ONIGERR_INVALID_BACKREF;
+	}
+
+	tok->type = TK_BACKREF;
+	tok->u.backref.num     = 1;
+	tok->u.backref.ref1    = num;
+	tok->u.backref.by_name = 0;
+#ifdef USE_BACKREF_WITH_LEVEL
+	tok->u.backref.exist_level = 0;
+#endif
+	break;
+      }
+
+    skip_backref:
+      if (c == '8' || c == '9') {
+	/* normal char */
+	p = prev; PINC;
+	break;
+      }
+
+      p = prev;
+      /* fall through */
+    case '0':
+      if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_OCTAL3)) {
+	prev = p;
+	num = scan_unsigned_octal_number(&p, end, (c == '0' ? 2:3), enc);
+	if (num < 0 || 0xff < num) return ONIGERR_TOO_BIG_NUMBER;
+	if (p == prev) {  /* can't read nothing. */
+	  num = 0; /* but, it's not error */
+	}
+	tok->type = TK_RAW_BYTE;
+	tok->base = 8;
+	tok->u.c  = num;
+      }
+      else if (c != '0') {
+	PINC;
+      }
+      break;
+
+#ifdef USE_NAMED_GROUP
+    case 'k':
+      if (!PEND && IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_K_NAMED_BACKREF)) {
+	PFETCH(c);
+	if (c == '<' || c == '\'') {
+	  r = fetch_named_backref_token(c, tok, &p, end, env);
+	  if (r < 0) return r;
+	}
+	else {
+	  PUNFETCH;
+	  onig_syntax_warn(env, "invalid back reference");
+	}
+      }
+      break;
+#endif
+
+#if defined(USE_SUBEXP_CALL) || defined(USE_NAMED_GROUP)
+    case 'g':
+# ifdef USE_NAMED_GROUP
+      if (!PEND && IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_G_BRACE_BACKREF)) {
+	PFETCH(c);
+	if (c == '{') {
+	  r = fetch_named_backref_token(c, tok, &p, end, env);
+	  if (r < 0) return r;
+	}
+	else
+	  PUNFETCH;
+      }
+# endif
+# ifdef USE_SUBEXP_CALL
+      if (!PEND && IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_G_SUBEXP_CALL)) {
+	PFETCH(c);
+	if (c == '<' || c == '\'') {
+	  int gnum = -1, rel = 0;
+	  UChar* name_end;
+	  OnigCodePoint cnext;
+
+	  cnext = PPEEK;
+	  if (cnext == '0') {
+	    PINC;
+	    if (PPEEK_IS(get_name_end_code_point(c))) {  /* \g<0>, \g'0' */
+	      PINC;
+	      name_end = p;
+	      gnum = 0;
+	    }
+	  }
+	  else if (cnext == '+') {
+	    PINC;
+	    rel = 1;
+	  }
+	  prev = p;
+	  if (gnum < 0) {
+	    r = fetch_name((OnigCodePoint )c, &p, end, &name_end, env, &gnum, 1);
+	    if (r < 0) return r;
+	  }
+
+	  tok->type = TK_CALL;
+	  tok->u.call.name     = prev;
+	  tok->u.call.name_end = name_end;
+	  tok->u.call.gnum     = gnum;
+	  tok->u.call.rel      = rel;
+	}
+	else {
+	  onig_syntax_warn(env, "invalid subexp call");
+	  PUNFETCH;
+	}
+      }
+# endif
+      break;
+#endif
+
+    case 'Q':
+      if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE)) {
+	tok->type = TK_QUOTE_OPEN;
+      }
+      break;
+
+    case 'p':
+    case 'P':
+      if (PPEEK_IS('{') &&
+	  IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY)) {
+	PINC;
+	tok->type = TK_CHAR_PROPERTY;
+	tok->u.prop.not = (c == 'P' ? 1 : 0);
+
+	if (!PEND && IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT)) {
+	  PFETCH(c);
+	  if (c == '^') {
+	    tok->u.prop.not = (tok->u.prop.not == 0 ? 1 : 0);
+	  }
+	  else
+	    PUNFETCH;
+	}
+      }
+      else {
+	onig_syntax_warn(env, "invalid Unicode Property \\%c", c);
+      }
+      break;
+
+    case 'R':
+      if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_CAPITAL_R_LINEBREAK)) {
+	tok->type = TK_LINEBREAK;
+      }
+      break;
+
+    case 'X':
+      if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_CAPITAL_X_EXTENDED_GRAPHEME_CLUSTER)) {
+	tok->type = TK_EXTENDED_GRAPHEME_CLUSTER;
+      }
+      break;
+
+    case 'K':
+      if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_CAPITAL_K_KEEP)) {
+	tok->type = TK_KEEP;
+      }
+      break;
+
+    default:
+      {
+	OnigCodePoint c2;
+
+	PUNFETCH;
+	num = fetch_escaped_value(&p, end, env, &c2);
+	if (num < 0) return num;
+	/* set_raw: */
+	if ((OnigCodePoint )tok->u.c != c2) {
+	  tok->type = TK_CODE_POINT;
+	  tok->u.code = (OnigCodePoint )c2;
+	}
+	else { /* string */
+	  p = tok->backp + enclen(enc, tok->backp, end);
+	}
+      }
+      break;
+    }
+  }
+  else {
+    tok->u.c = c;
+    tok->escaped = 0;
+
+#ifdef USE_VARIABLE_META_CHARS
+    if ((c != ONIG_INEFFECTIVE_META_CHAR) &&
+	IS_SYNTAX_OP(syn, ONIG_SYN_OP_VARIABLE_META_CHARACTERS)) {
+      if (c == MC_ANYCHAR(syn))
+	goto any_char;
+      else if (c == MC_ANYTIME(syn))
+	goto anytime;
+      else if (c == MC_ZERO_OR_ONE_TIME(syn))
+	goto zero_or_one_time;
+      else if (c == MC_ONE_OR_MORE_TIME(syn))
+	goto one_or_more_time;
+      else if (c == MC_ANYCHAR_ANYTIME(syn)) {
+	tok->type = TK_ANYCHAR_ANYTIME;
+	goto out;
+      }
+    }
+#endif
+
+    switch (c) {
+    case '.':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_DOT_ANYCHAR)) break;
+#ifdef USE_VARIABLE_META_CHARS
+    any_char:
+#endif
+      tok->type = TK_ANYCHAR;
+      break;
+
+    case '*':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ASTERISK_ZERO_INF)) break;
+#ifdef USE_VARIABLE_META_CHARS
+    anytime:
+#endif
+      tok->type = TK_OP_REPEAT;
+      tok->u.repeat.lower = 0;
+      tok->u.repeat.upper = REPEAT_INFINITE;
+      goto greedy_check;
+      break;
+
+    case '+':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_PLUS_ONE_INF)) break;
+#ifdef USE_VARIABLE_META_CHARS
+    one_or_more_time:
+#endif
+      tok->type = TK_OP_REPEAT;
+      tok->u.repeat.lower = 1;
+      tok->u.repeat.upper = REPEAT_INFINITE;
+      goto greedy_check;
+      break;
+
+    case '?':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_QMARK_ZERO_ONE)) break;
+#ifdef USE_VARIABLE_META_CHARS
+    zero_or_one_time:
+#endif
+      tok->type = TK_OP_REPEAT;
+      tok->u.repeat.lower = 0;
+      tok->u.repeat.upper = 1;
+      goto greedy_check;
+      break;
+
+    case '{':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_BRACE_INTERVAL)) break;
+      r = fetch_range_quantifier(&p, end, tok, env);
+      if (r < 0) return r;  /* error */
+      if (r == 0) goto greedy_check;
+      else if (r == 2) { /* {n} */
+	if (IS_SYNTAX_BV(syn, ONIG_SYN_FIXED_INTERVAL_IS_GREEDY_ONLY))
+	  goto possessive_check;
+
+	goto greedy_check;
+      }
+      /* r == 1 : normal char */
+      break;
+
+    case '|':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_VBAR_ALT)) break;
+      tok->type = TK_ALT;
+      break;
+
+    case '(':
+      if (PPEEK_IS('?') &&
+	  IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_QMARK_GROUP_EFFECT)) {
+	PINC;
+	if (PPEEK_IS('#')) {
+	  PFETCH(c);
+	  while (1) {
+	    if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
+	    PFETCH(c);
+	    if (c == MC_ESC(syn)) {
+	      if (!PEND) PFETCH(c);
+	    }
+	    else {
+	      if (c == ')') break;
+	    }
+	  }
+	  goto start;
+	}
+#ifdef USE_PERL_SUBEXP_CALL
+	/* (?&name), (?n), (?R), (?0), (?+n), (?-n) */
+	c = PPEEK;
+	if ((c == '&' || c == 'R' || ONIGENC_IS_CODE_DIGIT(enc, c)) &&
+	    IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_SUBEXP_CALL)) {
+	  /* (?&name), (?n), (?R), (?0) */
+	  int gnum;
+	  UChar *name;
+	  UChar *name_end;
+
+	  if (c == 'R' || c == '0') {
+	    PINC;   /* skip 'R' / '0' */
+	    if (!PPEEK_IS(')')) return ONIGERR_INVALID_GROUP_NAME;
+	    PINC;   /* skip ')' */
+	    name_end = name = p;
+	    gnum = 0;
+	  }
+	  else {
+	    int numref = 1;
+	    if (c == '&') {     /* (?&name) */
+	      PINC;
+	      numref = 0;       /* don't allow number name */
+	    }
+	    name = p;
+	    r = fetch_name((OnigCodePoint )'(', &p, end, &name_end, env, &gnum, numref);
+	    if (r < 0) return r;
+	  }
+
+	  tok->type = TK_CALL;
+	  tok->u.call.name     = name;
+	  tok->u.call.name_end = name_end;
+	  tok->u.call.gnum     = gnum;
+	  tok->u.call.rel      = 0;
+	  break;
+	}
+	else if ((c == '-' || c == '+') &&
+	    IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_SUBEXP_CALL)) {
+	  /* (?+n), (?-n) */
+	  int gnum;
+	  UChar *name;
+	  UChar *name_end;
+	  OnigCodePoint cnext;
+	  PFETCH_READY;
+
+	  PINC;     /* skip '-' / '+' */
+	  cnext = PPEEK;
+	  if (ONIGENC_IS_CODE_DIGIT(enc, cnext)) {
+	    if (c == '-') PUNFETCH;
+	    name = p;
+	    r = fetch_name((OnigCodePoint )'(', &p, end, &name_end, env, &gnum, 1);
+	    if (r < 0) return r;
+
+	    tok->type = TK_CALL;
+	    tok->u.call.name     = name;
+	    tok->u.call.name_end = name_end;
+	    tok->u.call.gnum     = gnum;
+	    tok->u.call.rel      = 1;
+	    break;
+	  }
+	}
+#endif /* USE_PERL_SUBEXP_CALL */
+#ifdef USE_CAPITAL_P_NAMED_GROUP
+	if (PPEEK_IS('P') &&
+	    IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_CAPITAL_P_NAMED_GROUP)) {
+	  int gnum;
+	  UChar *name;
+	  UChar *name_end;
+	  PFETCH_READY;
+
+	  PINC;     /* skip 'P' */
+	  if (PEND) return ONIGERR_UNDEFINED_GROUP_OPTION;
+	  PFETCH(c);
+	  if (c == '=') {       /* (?P=name): backref */
+	    r = fetch_named_backref_token((OnigCodePoint )'(', tok, &p, end, env);
+	    if (r < 0) return r;
+	    break;
+	  }
+	  else if (c == '>') {  /* (?P>name): subexp call */
+	    name = p;
+	    r = fetch_name((OnigCodePoint )'(', &p, end, &name_end, env, &gnum, 0);
+	    if (r < 0) return r;
+
+	    tok->type = TK_CALL;
+	    tok->u.call.name     = name;
+	    tok->u.call.name_end = name_end;
+	    tok->u.call.gnum     = gnum;
+	    tok->u.call.rel      = 0;
+	    break;
+	  }
+	}
+#endif /* USE_CAPITAL_P_NAMED_GROUP */
+	PUNFETCH;
+      }
+
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LPAREN_SUBEXP)) break;
+      tok->type = TK_SUBEXP_OPEN;
+      break;
+
+    case ')':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LPAREN_SUBEXP)) break;
+      tok->type = TK_SUBEXP_CLOSE;
+      break;
+
+    case '^':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LINE_ANCHOR)) break;
+      tok->type = TK_ANCHOR;
+      tok->u.anchor.subtype = (IS_SINGLELINE(env->option)
+			       ? ANCHOR_BEGIN_BUF : ANCHOR_BEGIN_LINE);
+      break;
+
+    case '$':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LINE_ANCHOR)) break;
+      tok->type = TK_ANCHOR;
+      tok->u.anchor.subtype = (IS_SINGLELINE(env->option)
+			       ? ANCHOR_SEMI_END_BUF : ANCHOR_END_LINE);
+      break;
+
+    case '[':
+      if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_BRACKET_CC)) break;
+      tok->type = TK_CC_OPEN;
+      break;
+
+    case ']':
+      if (*src > env->pattern)   /* /].../ is allowed. */
+	CLOSE_BRACKET_WITHOUT_ESC_WARN(env, (UChar* )"]");
+      break;
+
+    case '#':
+      if (IS_EXTEND(env->option)) {
+	while (!PEND) {
+	  PFETCH(c);
+	  if (ONIGENC_IS_CODE_NEWLINE(enc, c))
+	    break;
+	}
+	goto start;
+	break;
+      }
+      break;
+
+    case ' ': case '\t': case '\n': case '\r': case '\f':
+      if (IS_EXTEND(env->option))
+	goto start;
+      break;
+
+    default:
+      /* string */
+      break;
+    }
+  }
+
+#ifdef USE_VARIABLE_META_CHARS
+ out:
+#endif
+  *src = p;
+  return tok->type;
+}
+
+static int
+add_ctype_to_cc_by_range(CClassNode* cc, int ctype ARG_UNUSED, int not,
+                         ScanEnv* env,
+                         OnigCodePoint sb_out, const OnigCodePoint mbr[])
+{
+  int i, r;
+  OnigCodePoint j;
+
+  int n = ONIGENC_CODE_RANGE_NUM(mbr);
+
+  if (not == 0) {
+    for (i = 0; i < n; i++) {
+      for (j = ONIGENC_CODE_RANGE_FROM(mbr, i);
+	  j <= ONIGENC_CODE_RANGE_TO(mbr, i); j++) {
+	if (j >= sb_out) {
+	  if (j > ONIGENC_CODE_RANGE_FROM(mbr, i)) {
+	    r = add_code_range_to_buf(&(cc->mbuf), env, j,
+				      ONIGENC_CODE_RANGE_TO(mbr, i));
+	    if (r != 0) return r;
+	    i++;
+	  }
+
+	  goto sb_end;
+	}
+	BITSET_SET_BIT_CHKDUP(cc->bs, j);
+      }
+    }
+
+  sb_end:
+    for ( ; i < n; i++) {
+      r = add_code_range_to_buf(&(cc->mbuf), env,
+                                ONIGENC_CODE_RANGE_FROM(mbr, i),
+                                ONIGENC_CODE_RANGE_TO(mbr, i));
+      if (r != 0) return r;
+    }
+  }
+  else {
+    OnigCodePoint prev = 0;
+
+    for (i = 0; i < n; i++) {
+      for (j = prev;
+	   j < ONIGENC_CODE_RANGE_FROM(mbr, i); j++) {
+	if (j >= sb_out) {
+	  goto sb_end2;
+	}
+	BITSET_SET_BIT_CHKDUP(cc->bs, j);
+      }
+      prev = ONIGENC_CODE_RANGE_TO(mbr, i) + 1;
+    }
+    for (j = prev; j < sb_out; j++) {
+      BITSET_SET_BIT_CHKDUP(cc->bs, j);
+    }
+
+  sb_end2:
+    prev = sb_out;
+
+    for (i = 0; i < n; i++) {
+      if (prev < ONIGENC_CODE_RANGE_FROM(mbr, i)) {
+	r = add_code_range_to_buf(&(cc->mbuf), env, prev,
+                                  ONIGENC_CODE_RANGE_FROM(mbr, i) - 1);
+	if (r != 0) return r;
+      }
+      prev = ONIGENC_CODE_RANGE_TO(mbr, i) + 1;
+    }
+    if (prev < 0x7fffffff) {
+      r = add_code_range_to_buf(&(cc->mbuf), env, prev, 0x7fffffff);
+      if (r != 0) return r;
+    }
+  }
+
+  return 0;
+}
+
+static int
+add_ctype_to_cc(CClassNode* cc, int ctype, int not, int ascii_range, ScanEnv* env)
+{
+  int maxcode;
+  int c, r;
+  const OnigCodePoint *ranges;
+  OnigCodePoint sb_out;
+  OnigEncoding enc = env->enc;
+
+  r = ONIGENC_GET_CTYPE_CODE_RANGE(enc, ctype, &sb_out, &ranges);
+  if (r == 0) {
+    if (ascii_range) {
+      CClassNode ccwork;
+      initialize_cclass(&ccwork);
+      r = add_ctype_to_cc_by_range(&ccwork, ctype, not, env, sb_out,
+				   ranges);
+      if (r == 0) {
+	if (not) {
+	  r = add_code_range_to_buf0(&(ccwork.mbuf), env, 0x80, ONIG_LAST_CODE_POINT, FALSE);
+	}
+	else {
+	  CClassNode ccascii;
+	  initialize_cclass(&ccascii);
+	  if (ONIGENC_MBC_MINLEN(env->enc) > 1) {
+	    r = add_code_range(&(ccascii.mbuf), env, 0x00, 0x7F);
+	  }
+	  else {
+	    bitset_set_range(env, ccascii.bs, 0x00, 0x7F);
+	    r = 0;
+	  }
+	  if (r == 0) {
+	    r = and_cclass(&ccwork, &ccascii, env);
+	  }
+	  if (IS_NOT_NULL(ccascii.mbuf)) bbuf_free(ccascii.mbuf);
+	}
+	if (r == 0) {
+	  r = or_cclass(cc, &ccwork, env);
+	}
+	if (IS_NOT_NULL(ccwork.mbuf)) bbuf_free(ccwork.mbuf);
+      }
+    }
+    else {
+      r = add_ctype_to_cc_by_range(cc, ctype, not, env, sb_out, ranges);
+    }
+    return r;
+  }
+  else if (r != ONIG_NO_SUPPORT_CONFIG) {
+    return r;
+  }
+
+  maxcode = ascii_range ? 0x80 : SINGLE_BYTE_SIZE;
+  r = 0;
+  switch (ctype) {
+  case ONIGENC_CTYPE_ALPHA:
+  case ONIGENC_CTYPE_BLANK:
+  case ONIGENC_CTYPE_CNTRL:
+  case ONIGENC_CTYPE_DIGIT:
+  case ONIGENC_CTYPE_LOWER:
+  case ONIGENC_CTYPE_PUNCT:
+  case ONIGENC_CTYPE_SPACE:
+  case ONIGENC_CTYPE_UPPER:
+  case ONIGENC_CTYPE_XDIGIT:
+  case ONIGENC_CTYPE_ASCII:
+  case ONIGENC_CTYPE_ALNUM:
+    if (not != 0) {
+      for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
+	if (! ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
+	  BITSET_SET_BIT_CHKDUP(cc->bs, c);
+      }
+      ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
+    }
+    else {
+      for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
+	if (ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
+	  BITSET_SET_BIT_CHKDUP(cc->bs, c);
+      }
+    }
+    break;
+
+  case ONIGENC_CTYPE_GRAPH:
+  case ONIGENC_CTYPE_PRINT:
+    if (not != 0) {
+      for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
+	if (! ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype)
+	    || c >= maxcode)
+	  BITSET_SET_BIT_CHKDUP(cc->bs, c);
+      }
+      if (ascii_range)
+	ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
+    }
+    else {
+      for (c = 0; c < maxcode; c++) {
+	if (ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
+	  BITSET_SET_BIT_CHKDUP(cc->bs, c);
+      }
+      if (! ascii_range)
+	ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
+    }
+    break;
+
+  case ONIGENC_CTYPE_WORD:
+    if (not == 0) {
+      for (c = 0; c < maxcode; c++) {
+	if (ONIGENC_IS_CODE_WORD(enc, c)) BITSET_SET_BIT_CHKDUP(cc->bs, c);
+      }
+      if (! ascii_range)
+	ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
+    }
+    else {
+      for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
+	if ((ONIGENC_CODE_TO_MBCLEN(enc, c) > 0) /* check invalid code point */
+	    && (! ONIGENC_IS_CODE_WORD(enc, c) || c >= maxcode))
+	  BITSET_SET_BIT_CHKDUP(cc->bs, c);
+      }
+      if (ascii_range)
+	ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
+    }
+    break;
+
+  default:
+    return ONIGERR_PARSER_BUG;
+    break;
+  }
+
+  return r;
+}
+
+static int
+parse_posix_bracket(CClassNode* cc, CClassNode* asc_cc,
+		    UChar** src, UChar* end, ScanEnv* env)
+{
+#define POSIX_BRACKET_CHECK_LIMIT_LENGTH  20
+#define POSIX_BRACKET_NAME_MIN_LEN         4
+
+  static const PosixBracketEntryType PBS[] = {
+    POSIX_BRACKET_ENTRY_INIT("alnum",  ONIGENC_CTYPE_ALNUM),
+    POSIX_BRACKET_ENTRY_INIT("alpha",  ONIGENC_CTYPE_ALPHA),
+    POSIX_BRACKET_ENTRY_INIT("blank",  ONIGENC_CTYPE_BLANK),
+    POSIX_BRACKET_ENTRY_INIT("cntrl",  ONIGENC_CTYPE_CNTRL),
+    POSIX_BRACKET_ENTRY_INIT("digit",  ONIGENC_CTYPE_DIGIT),
+    POSIX_BRACKET_ENTRY_INIT("graph",  ONIGENC_CTYPE_GRAPH),
+    POSIX_BRACKET_ENTRY_INIT("lower",  ONIGENC_CTYPE_LOWER),
+    POSIX_BRACKET_ENTRY_INIT("print",  ONIGENC_CTYPE_PRINT),
+    POSIX_BRACKET_ENTRY_INIT("punct",  ONIGENC_CTYPE_PUNCT),
+    POSIX_BRACKET_ENTRY_INIT("space",  ONIGENC_CTYPE_SPACE),
+    POSIX_BRACKET_ENTRY_INIT("upper",  ONIGENC_CTYPE_UPPER),
+    POSIX_BRACKET_ENTRY_INIT("xdigit", ONIGENC_CTYPE_XDIGIT),
+    POSIX_BRACKET_ENTRY_INIT("ascii",  ONIGENC_CTYPE_ASCII),
+    POSIX_BRACKET_ENTRY_INIT("word",   ONIGENC_CTYPE_WORD),
+  };
+
+  const PosixBracketEntryType *pb;
+  int not, i, r;
+  int ascii_range;
+  OnigCodePoint c;
+  OnigEncoding enc = env->enc;
+  UChar *p = *src;
+
+  if (PPEEK_IS('^')) {
+    PINC_S;
+    not = 1;
+  }
+  else
+    not = 0;
+
+  if (onigenc_strlen(enc, p, end) < POSIX_BRACKET_NAME_MIN_LEN + 3)
+    goto not_posix_bracket;
+
+  ascii_range = IS_ASCII_RANGE(env->option) &&
+		  ! IS_POSIX_BRACKET_ALL_RANGE(env->option);
+  for (pb = PBS; pb < PBS + numberof(PBS); pb++) {
+    if (onigenc_with_ascii_strncmp(enc, p, end, pb->name, pb->len) == 0) {
+      p = (UChar* )onigenc_step(enc, p, end, pb->len);
+      if (onigenc_with_ascii_strncmp(enc, p, end, (UChar* )":]", 2) != 0)
+	return ONIGERR_INVALID_POSIX_BRACKET_TYPE;
+
+      r = add_ctype_to_cc(cc, pb->ctype, not, ascii_range, env);
+      if (r != 0) return r;
+
+      if (IS_NOT_NULL(asc_cc)) {
+	if (pb->ctype != ONIGENC_CTYPE_WORD &&
+	    pb->ctype != ONIGENC_CTYPE_ASCII &&
+	    !ascii_range)
+	  r = add_ctype_to_cc(asc_cc, pb->ctype, not, ascii_range, env);
+	if (r != 0) return r;
+      }
+
+      PINC_S; PINC_S;
+      *src = p;
+      return 0;
+    }
+  }
+
+ not_posix_bracket:
+  c = 0;
+  i = 0;
+  while (!PEND && ((c = PPEEK) != ':') && c != ']') {
+    PINC_S;
+    if (++i > POSIX_BRACKET_CHECK_LIMIT_LENGTH) break;
+  }
+  if (c == ':' && ! PEND) {
+    PINC_S;
+    if (! PEND) {
+      PFETCH_S(c);
+      if (c == ']')
+	return ONIGERR_INVALID_POSIX_BRACKET_TYPE;
+    }
+  }
+
+  return 1;  /* 1: is not POSIX bracket, but no error. */
+}
+
+static int
+fetch_char_property_to_ctype(UChar** src, UChar* end, ScanEnv* env)
+{
+  int r;
+  OnigCodePoint c;
+  OnigEncoding enc = env->enc;
+  UChar *prev, *start, *p = *src;
+
+  r = 0;
+  start = prev = p;
+
+  while (!PEND) {
+    prev = p;
+    PFETCH_S(c);
+    if (c == '}') {
+      r = ONIGENC_PROPERTY_NAME_TO_CTYPE(enc, start, prev);
+      if (r < 0) break;
+
+      *src = p;
+      return r;
+    }
+    else if (c == '(' || c == ')' || c == '{' || c == '|') {
+      r = ONIGERR_INVALID_CHAR_PROPERTY_NAME;
+      break;
+    }
+  }
+
+  onig_scan_env_set_error_string(env, r, *src, prev);
+  return r;
+}
+
+static int cclass_case_fold(Node** np, CClassNode* cc, CClassNode* asc_cc, ScanEnv* env);
+
+static int
+parse_char_property(Node** np, OnigToken* tok, UChar** src, UChar* end,
+		    ScanEnv* env)
+{
+  int r, ctype;
+  CClassNode* cc;
+
+  ctype = fetch_char_property_to_ctype(src, end, env);
+  if (ctype < 0) return ctype;
+
+  *np = node_new_cclass();
+  CHECK_NULL_RETURN_MEMERR(*np);
+  cc = NCCLASS(*np);
+  r = add_ctype_to_cc(cc, ctype, 0, 0, env);
+  if (r != 0) return r;
+  if (tok->u.prop.not != 0) NCCLASS_SET_NOT(cc);
+
+  if (IS_IGNORECASE(env->option)) {
+    if (ctype != ONIGENC_CTYPE_ASCII)
+      r = cclass_case_fold(np, cc, cc, env);
+  }
+  return r;
+}
+
+
+enum CCSTATE {
+  CCS_VALUE,
+  CCS_RANGE,
+  CCS_COMPLETE,
+  CCS_START
+};
+
+enum CCVALTYPE {
+  CCV_SB,
+  CCV_CODE_POINT,
+  CCV_CLASS
+};
+
+static int
+next_state_class(CClassNode* cc, CClassNode* asc_cc,
+		 OnigCodePoint* vs, enum CCVALTYPE* type,
+		 enum CCSTATE* state, ScanEnv* env)
+{
+  int r;
+
+  if (*state == CCS_RANGE)
+    return ONIGERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE;
+
+  if (*state == CCS_VALUE && *type != CCV_CLASS) {
+    if (*type == CCV_SB) {
+      BITSET_SET_BIT_CHKDUP(cc->bs, (int )(*vs));
+      if (IS_NOT_NULL(asc_cc))
+	BITSET_SET_BIT(asc_cc->bs, (int )(*vs));
+    }
+    else if (*type == CCV_CODE_POINT) {
+      r = add_code_range(&(cc->mbuf), env, *vs, *vs);
+      if (r < 0) return r;
+      if (IS_NOT_NULL(asc_cc)) {
+	r = add_code_range0(&(asc_cc->mbuf), env, *vs, *vs, 0);
+	if (r < 0) return r;
+      }
+    }
+  }
+
+  *state = CCS_VALUE;
+  *type  = CCV_CLASS;
+  return 0;
+}
+
+static int
+next_state_val(CClassNode* cc, CClassNode* asc_cc,
+	       OnigCodePoint *from, OnigCodePoint to,
+	       int* from_israw, int to_israw,
+	       enum CCVALTYPE intype, enum CCVALTYPE* type,
+	       enum CCSTATE* state, ScanEnv* env)
+{
+  int r;
+
+  switch (*state) {
+  case CCS_VALUE:
+    if (*type == CCV_SB) {
+      BITSET_SET_BIT_CHKDUP(cc->bs, (int )(*from));
+      if (IS_NOT_NULL(asc_cc))
+	BITSET_SET_BIT(asc_cc->bs, (int )(*from));
+    }
+    else if (*type == CCV_CODE_POINT) {
+      r = add_code_range(&(cc->mbuf), env, *from, *from);
+      if (r < 0) return r;
+      if (IS_NOT_NULL(asc_cc)) {
+	r = add_code_range0(&(asc_cc->mbuf), env, *from, *from, 0);
+	if (r < 0) return r;
+      }
+    }
+    break;
+
+  case CCS_RANGE:
+    if (intype == *type) {
+      if (intype == CCV_SB) {
+	if (*from > 0xff || to > 0xff)
+	  return ONIGERR_INVALID_CODE_POINT_VALUE;
+
+	if (*from > to) {
+	  if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
+	    goto ccs_range_end;
+	  else
+	    return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS;
+	}
+	bitset_set_range(env, cc->bs, (int )*from, (int )to);
+	if (IS_NOT_NULL(asc_cc))
+	  bitset_set_range(env, asc_cc->bs, (int )*from, (int )to);
+      }
+      else {
+	r = add_code_range(&(cc->mbuf), env, *from, to);
+	if (r < 0) return r;
+	if (IS_NOT_NULL(asc_cc)) {
+	  r = add_code_range0(&(asc_cc->mbuf), env, *from, to, 0);
+	  if (r < 0) return r;
+	}
+      }
+    }
+    else {
+      if (*from > to) {
+	if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
+	  goto ccs_range_end;
+	else
+	  return ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS;
+      }
+      bitset_set_range(env, cc->bs, (int )*from, (int )(to < 0xff ? to : 0xff));
+      r = add_code_range(&(cc->mbuf), env, (OnigCodePoint )*from, to);
+      if (r < 0) return r;
+      if (IS_NOT_NULL(asc_cc)) {
+	bitset_set_range(env, asc_cc->bs, (int )*from, (int )(to < 0xff ? to : 0xff));
+	r = add_code_range0(&(asc_cc->mbuf), env, (OnigCodePoint )*from, to, 0);
+	if (r < 0) return r;
+      }
+    }
+  ccs_range_end:
+    *state = CCS_COMPLETE;
+    break;
+
+  case CCS_COMPLETE:
+  case CCS_START:
+    *state = CCS_VALUE;
+    break;
+
+  default:
+    break;
+  }
+
+  *from_israw = to_israw;
+  *from       = to;
+  *type       = intype;
+  return 0;
+}
+
+static int
+code_exist_check(OnigCodePoint c, UChar* from, UChar* end, int ignore_escaped,
+		 ScanEnv* env)
+{
+  int in_esc;
+  OnigCodePoint code;
+  OnigEncoding enc = env->enc;
+  UChar* p = from;
+
+  in_esc = 0;
+  while (! PEND) {
+    if (ignore_escaped && in_esc) {
+      in_esc = 0;
+    }
+    else {
+      PFETCH_S(code);
+      if (code == c) return 1;
+      if (code == MC_ESC(env->syntax)) in_esc = 1;
+    }
+  }
+  return 0;
+}
+
+static int
+parse_char_class(Node** np, Node** asc_np, OnigToken* tok, UChar** src, UChar* end,
+		 ScanEnv* env)
+{
+  int r, neg, len, fetched, and_start;
+  OnigCodePoint v, vs;
+  UChar *p;
+  Node* node;
+  Node* asc_node;
+  CClassNode *cc, *prev_cc;
+  CClassNode *asc_cc, *asc_prev_cc;
+  CClassNode work_cc, asc_work_cc;
+
+  enum CCSTATE state;
+  enum CCVALTYPE val_type, in_type;
+  int val_israw, in_israw;
+
+  *np = *asc_np = NULL_NODE;
+  env->parse_depth++;
+  if (env->parse_depth > ParseDepthLimit)
+    return ONIGERR_PARSE_DEPTH_LIMIT_OVER;
+  prev_cc = asc_prev_cc = (CClassNode* )NULL;
+  r = fetch_token_in_cc(tok, src, end, env);
+  if (r == TK_CHAR && tok->u.c == '^' && tok->escaped == 0) {
+    neg = 1;
+    r = fetch_token_in_cc(tok, src, end, env);
+  }
+  else {
+    neg = 0;
+  }
+
+  if (r < 0) return r;
+  if (r == TK_CC_CLOSE) {
+    if (! code_exist_check((OnigCodePoint )']',
+                           *src, env->pattern_end, 1, env))
+      return ONIGERR_EMPTY_CHAR_CLASS;
+
+    CC_ESC_WARN(env, (UChar* )"]");
+    r = tok->type = TK_CHAR;  /* allow []...] */
+  }
+
+  *np = node = node_new_cclass();
+  CHECK_NULL_RETURN_MEMERR(node);
+  cc = NCCLASS(node);
+
+  if (IS_IGNORECASE(env->option)) {
+    *asc_np = asc_node = node_new_cclass();
+    CHECK_NULL_RETURN_MEMERR(asc_node);
+    asc_cc = NCCLASS(asc_node);
+  }
+  else {
+    asc_node = NULL_NODE;
+    asc_cc = NULL;
+  }
+
+  and_start = 0;
+  state = CCS_START;
+  p = *src;
+  while (r != TK_CC_CLOSE) {
+    fetched = 0;
+    switch (r) {
+    case TK_CHAR:
+      if ((tok->u.code >= SINGLE_BYTE_SIZE) ||
+	  (len = ONIGENC_CODE_TO_MBCLEN(env->enc, tok->u.c)) > 1) {
+	in_type = CCV_CODE_POINT;
+      }
+      else if (len < 0) {
+	r = len;
+	goto err;
+      }
+      else {
+      sb_char:
+	in_type = CCV_SB;
+      }
+      v = (OnigCodePoint )tok->u.c;
+      in_israw = 0;
+      goto val_entry2;
+      break;
+
+    case TK_RAW_BYTE:
+      /* tok->base != 0 : octal or hexadec. */
+      if (! ONIGENC_IS_SINGLEBYTE(env->enc) && tok->base != 0) {
+	UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
+	UChar* bufe = buf + ONIGENC_CODE_TO_MBC_MAXLEN;
+	UChar* psave = p;
+	int i, base = tok->base;
+
+	buf[0] = (UChar )tok->u.c;
+	for (i = 1; i < ONIGENC_MBC_MAXLEN(env->enc); i++) {
+	  r = fetch_token_in_cc(tok, &p, end, env);
+	  if (r < 0) goto err;
+	  if (r != TK_RAW_BYTE || tok->base != base) {
+	    fetched = 1;
+	    break;
+	  }
+	  buf[i] = (UChar )tok->u.c;
+	}
+
+	if (i < ONIGENC_MBC_MINLEN(env->enc)) {
+	  r = ONIGERR_TOO_SHORT_MULTI_BYTE_STRING;
+	  goto err;
+	}
+
+	len = enclen(env->enc, buf, buf + i);
+	if (i < len) {
+	  r = ONIGERR_TOO_SHORT_MULTI_BYTE_STRING;
+	  goto err;
+	}
+	else if (i > len) { /* fetch back */
+	  p = psave;
+	  for (i = 1; i < len; i++) {
+	    (void)fetch_token_in_cc(tok, &p, end, env);
+	    /* no need to check the retun value (already checked above) */
+	  }
+	  fetched = 0;
+	}
+
+	if (i == 1) {
+	  v = (OnigCodePoint )buf[0];
+	  goto raw_single;
+	}
+	else {
+	  v = ONIGENC_MBC_TO_CODE(env->enc, buf, bufe);
+	  in_type = CCV_CODE_POINT;
+	}
+      }
+      else {
+	v = (OnigCodePoint )tok->u.c;
+      raw_single:
+	in_type = CCV_SB;
+      }
+      in_israw = 1;
+      goto val_entry2;
+      break;
+
+    case TK_CODE_POINT:
+      v = tok->u.code;
+      in_israw = 1;
+    val_entry:
+      len = ONIGENC_CODE_TO_MBCLEN(env->enc, v);
+      if (len < 0) {
+	r = len;
+	goto err;
+      }
+      in_type = (len == 1 ? CCV_SB : CCV_CODE_POINT);
+    val_entry2:
+      r = next_state_val(cc, asc_cc, &vs, v, &val_israw, in_israw, in_type, &val_type,
+			 &state, env);
+      if (r != 0) goto err;
+      break;
+
+    case TK_POSIX_BRACKET_OPEN:
+      r = parse_posix_bracket(cc, asc_cc, &p, end, env);
+      if (r < 0) goto err;
+      if (r == 1) {  /* is not POSIX bracket */
+	CC_ESC_WARN(env, (UChar* )"[");
+	p = tok->backp;
+	v = (OnigCodePoint )tok->u.c;
+	in_israw = 0;
+	goto val_entry;
+      }
+      goto next_class;
+      break;
+
+    case TK_CHAR_TYPE:
+      r = add_ctype_to_cc(cc, tok->u.prop.ctype, tok->u.prop.not,
+			  IS_ASCII_RANGE(env->option), env);
+      if (r != 0) return r;
+      if (IS_NOT_NULL(asc_cc)) {
+	if (tok->u.prop.ctype != ONIGENC_CTYPE_WORD)
+	  r = add_ctype_to_cc(asc_cc, tok->u.prop.ctype, tok->u.prop.not,
+			      IS_ASCII_RANGE(env->option), env);
+	if (r != 0) return r;
+      }
+
+    next_class:
+      r = next_state_class(cc, asc_cc, &vs, &val_type, &state, env);
+      if (r != 0) goto err;
+      break;
+
+    case TK_CHAR_PROPERTY:
+      {
+	int ctype;
+
+	ctype = fetch_char_property_to_ctype(&p, end, env);
+	if (ctype < 0) return ctype;
+	r = add_ctype_to_cc(cc, ctype, tok->u.prop.not, 0, env);
+	if (r != 0) return r;
+	if (IS_NOT_NULL(asc_cc)) {
+	  if (ctype != ONIGENC_CTYPE_ASCII)
+	    r = add_ctype_to_cc(asc_cc, ctype, tok->u.prop.not, 0, env);
+	  if (r != 0) return r;
+	}
+	goto next_class;
+      }
+      break;
+
+    case TK_CC_RANGE:
+      if (state == CCS_VALUE) {
+	r = fetch_token_in_cc(tok, &p, end, env);
+	if (r < 0) goto err;
+	fetched = 1;
+	if (r == TK_CC_CLOSE) { /* allow [x-] */
+	range_end_val:
+	  v = (OnigCodePoint )'-';
+	  in_israw = 0;
+	  goto val_entry;
+	}
+	else if (r == TK_CC_AND) {
+	  CC_ESC_WARN(env, (UChar* )"-");
+	  goto range_end_val;
+	}
+
+	if (val_type == CCV_CLASS) {
+	  r = ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS;
+	  goto err;
+	}
+
+	state = CCS_RANGE;
+      }
+      else if (state == CCS_START) {
+	/* [-xa] is allowed */
+	v = (OnigCodePoint )tok->u.c;
+	in_israw = 0;
+
+	r = fetch_token_in_cc(tok, &p, end, env);
+	if (r < 0) goto err;
+	fetched = 1;
+	/* [--x] or [a&&-x] is warned. */
+	if (r == TK_CC_RANGE || and_start != 0)
+	  CC_ESC_WARN(env, (UChar* )"-");
+
+	goto val_entry;
+      }
+      else if (state == CCS_RANGE) {
+	CC_ESC_WARN(env, (UChar* )"-");
+	goto sb_char;  /* [!--x] is allowed */
+      }
+      else { /* CCS_COMPLETE */
+	r = fetch_token_in_cc(tok, &p, end, env);
+	if (r < 0) goto err;
+	fetched = 1;
+	if (r == TK_CC_CLOSE) goto range_end_val; /* allow [a-b-] */
+	else if (r == TK_CC_AND) {
+	  CC_ESC_WARN(env, (UChar* )"-");
+	  goto range_end_val;
+	}
+
+	if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC)) {
+	  CC_ESC_WARN(env, (UChar* )"-");
+	  goto range_end_val;   /* [0-9-a] is allowed as [0-9\-a] */
+	}
+	r = ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS;
+	goto err;
+      }
+      break;
+
+    case TK_CC_CC_OPEN: /* [ */
+      {
+	Node *anode, *aasc_node;
+	CClassNode* acc;
+
+	r = parse_char_class(&anode, &aasc_node, tok, &p, end, env);
+	if (r == 0) {
+	  acc = NCCLASS(anode);
+	  r = or_cclass(cc, acc, env);
+	}
+	if (r == 0 && IS_NOT_NULL(aasc_node)) {
+	  acc = NCCLASS(aasc_node);
+	  r = or_cclass(asc_cc, acc, env);
+	}
+	onig_node_free(anode);
+	onig_node_free(aasc_node);
+	if (r != 0) goto err;
+      }
+      break;
+
+    case TK_CC_AND: /* && */
+      {
+	if (state == CCS_VALUE) {
+	  r = next_state_val(cc, asc_cc, &vs, 0, &val_israw, 0, val_type,
+			     &val_type, &state, env);
+	  if (r != 0) goto err;
+	}
+	/* initialize local variables */
+	and_start = 1;
+	state = CCS_START;
+
+	if (IS_NOT_NULL(prev_cc)) {
+	  r = and_cclass(prev_cc, cc, env);
+	  if (r != 0) goto err;
+	  bbuf_free(cc->mbuf);
+	  if (IS_NOT_NULL(asc_cc)) {
+	    r = and_cclass(asc_prev_cc, asc_cc, env);
+	    if (r != 0) goto err;
+	    bbuf_free(asc_cc->mbuf);
+	  }
+	}
+	else {
+	  prev_cc = cc;
+	  cc = &work_cc;
+	  if (IS_NOT_NULL(asc_cc)) {
+	    asc_prev_cc = asc_cc;
+	    asc_cc = &asc_work_cc;
+	  }
+	}
+	initialize_cclass(cc);
+	if (IS_NOT_NULL(asc_cc))
+	  initialize_cclass(asc_cc);
+      }
+      break;
+
+    case TK_EOT:
+      r = ONIGERR_PREMATURE_END_OF_CHAR_CLASS;
+      goto err;
+      break;
+    default:
+      r = ONIGERR_PARSER_BUG;
+      goto err;
+      break;
+    }
+
+    if (fetched)
+      r = tok->type;
+    else {
+      r = fetch_token_in_cc(tok, &p, end, env);
+      if (r < 0) goto err;
+    }
+  }
+
+  if (state == CCS_VALUE) {
+    r = next_state_val(cc, asc_cc, &vs, 0, &val_israw, 0, val_type,
+		       &val_type, &state, env);
+    if (r != 0) goto err;
+  }
+
+  if (IS_NOT_NULL(prev_cc)) {
+    r = and_cclass(prev_cc, cc, env);
+    if (r != 0) goto err;
+    bbuf_free(cc->mbuf);
+    cc = prev_cc;
+    if (IS_NOT_NULL(asc_cc)) {
+      r = and_cclass(asc_prev_cc, asc_cc, env);
+      if (r != 0) goto err;
+      bbuf_free(asc_cc->mbuf);
+      asc_cc = asc_prev_cc;
+    }
+  }
+
+  if (neg != 0) {
+    NCCLASS_SET_NOT(cc);
+    if (IS_NOT_NULL(asc_cc))
+      NCCLASS_SET_NOT(asc_cc);
+  }
+  else {
+    NCCLASS_CLEAR_NOT(cc);
+    if (IS_NOT_NULL(asc_cc))
+      NCCLASS_CLEAR_NOT(asc_cc);
+  }
+  if (IS_NCCLASS_NOT(cc) &&
+      IS_SYNTAX_BV(env->syntax, ONIG_SYN_NOT_NEWLINE_IN_NEGATIVE_CC)) {
+    int is_empty;
+
+    is_empty = (IS_NULL(cc->mbuf) ? 1 : 0);
+    if (is_empty != 0)
+      BITSET_IS_EMPTY(cc->bs, is_empty);
+
+    if (is_empty == 0) {
+#define NEWLINE_CODE    0x0a
+
+      if (ONIGENC_IS_CODE_NEWLINE(env->enc, NEWLINE_CODE)) {
+	if (ONIGENC_CODE_TO_MBCLEN(env->enc, NEWLINE_CODE) == 1)
+	  BITSET_SET_BIT_CHKDUP(cc->bs, NEWLINE_CODE);
+	else {
+	  r = add_code_range(&(cc->mbuf), env, NEWLINE_CODE, NEWLINE_CODE);
+	  if (r < 0) goto err;
+	}
+      }
+    }
+  }
+  *src = p;
+  env->parse_depth--;
+  return 0;
+
+ err:
+  if (cc != NCCLASS(*np))
+    bbuf_free(cc->mbuf);
+  if (IS_NOT_NULL(asc_cc) && (asc_cc != NCCLASS(*asc_np)))
+    bbuf_free(asc_cc->mbuf);
+  return r;
+}
+
+static int parse_subexp(Node** top, OnigToken* tok, int term,
+			UChar** src, UChar* end, ScanEnv* env);
+
+static int
+parse_enclose(Node** np, OnigToken* tok, int term, UChar** src, UChar* end,
+	      ScanEnv* env)
+{
+  int r = 0, num;
+  Node *target, *work1 = NULL, *work2 = NULL;
+  OnigOptionType option;
+  OnigCodePoint c;
+  OnigEncoding enc = env->enc;
+
+#ifdef USE_NAMED_GROUP
+  int list_capture;
+#endif
+
+  UChar* p = *src;
+  PFETCH_READY;
+
+  *np = NULL;
+  if (PEND) return ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS;
+
+  option = env->option;
+  if (PPEEK_IS('?') &&
+      IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_GROUP_EFFECT)) {
+    PINC;
+    if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
+
+    PFETCH(c);
+    switch (c) {
+    case ':':   /* (?:...) grouping only */
+    group:
+      r = fetch_token(tok, &p, end, env);
+      if (r < 0) return r;
+      r = parse_subexp(np, tok, term, &p, end, env);
+      if (r < 0) return r;
+      *src = p;
+      return 1; /* group */
+      break;
+
+    case '=':
+      *np = onig_node_new_anchor(ANCHOR_PREC_READ);
+      break;
+    case '!':   /* preceding read */
+      *np = onig_node_new_anchor(ANCHOR_PREC_READ_NOT);
+      break;
+    case '>':   /* (?>...) stop backtrack */
+      *np = node_new_enclose(ENCLOSE_STOP_BACKTRACK);
+      break;
+    case '~':   /* (?~...) absent operator */
+      if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_TILDE_ABSENT)) {
+	*np = node_new_enclose(ENCLOSE_ABSENT);
+      }
+      else {
+	return ONIGERR_UNDEFINED_GROUP_OPTION;
+      }
+      break;
+
+#ifdef USE_NAMED_GROUP
+    case '\'':
+      if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
+	goto named_group1;
+      }
+      else
+	return ONIGERR_UNDEFINED_GROUP_OPTION;
+      break;
+
+# ifdef USE_CAPITAL_P_NAMED_GROUP
+    case 'P':   /* (?P<name>...) */
+      if (!PEND &&
+	  IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_CAPITAL_P_NAMED_GROUP)) {
+	PFETCH(c);
+	if (c == '<') goto named_group1;
+      }
+      return ONIGERR_UNDEFINED_GROUP_OPTION;
+      break;
+# endif
+#endif
+
+    case '<':   /* look behind (?<=...), (?<!...) */
+      if (PEND) return ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS;
+      PFETCH(c);
+      if (c == '=')
+	*np = onig_node_new_anchor(ANCHOR_LOOK_BEHIND);
+      else if (c == '!')
+	*np = onig_node_new_anchor(ANCHOR_LOOK_BEHIND_NOT);
+#ifdef USE_NAMED_GROUP
+      else {    /* (?<name>...) */
+	if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
+	  UChar *name;
+	  UChar *name_end;
+
+	  PUNFETCH;
+	  c = '<';
+
+	named_group1:
+	  list_capture = 0;
+
+# ifdef USE_CAPTURE_HISTORY
+	named_group2:
+# endif
+	  name = p;
+	  r = fetch_name((OnigCodePoint )c, &p, end, &name_end, env, &num, 0);
+	  if (r < 0) return r;
+
+	  num = scan_env_add_mem_entry(env);
+	  if (num < 0) return num;
+	  if (list_capture != 0 && num >= (int )BIT_STATUS_BITS_NUM)
+	    return ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY;
+
+	  r = name_add(env->reg, name, name_end, num, env);
+	  if (r != 0) return r;
+	  *np = node_new_enclose_memory(env->option, 1);
+	  CHECK_NULL_RETURN_MEMERR(*np);
+	  NENCLOSE(*np)->regnum = num;
+	  if (list_capture != 0)
+	    BIT_STATUS_ON_AT_SIMPLE(env->capture_history, num);
+	  env->num_named++;
+	}
+	else {
+	  return ONIGERR_UNDEFINED_GROUP_OPTION;
+	}
+      }
+#else
+      else {
+	return ONIGERR_UNDEFINED_GROUP_OPTION;
+      }
+#endif
+      break;
+
+#ifdef USE_CAPTURE_HISTORY
+    case '@':
+      if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ATMARK_CAPTURE_HISTORY)) {
+# ifdef USE_NAMED_GROUP
+	if (!PEND &&
+	    IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
+	  PFETCH(c);
+	  if (c == '<' || c == '\'') {
+	    list_capture = 1;
+	    goto named_group2; /* (?@<name>...) */
+	  }
+	  PUNFETCH;
+	}
+# endif
+	*np = node_new_enclose_memory(env->option, 0);
+	CHECK_NULL_RETURN_MEMERR(*np);
+	num = scan_env_add_mem_entry(env);
+	if (num < 0) return num;
+	if (num >= (int )BIT_STATUS_BITS_NUM)
+	  return ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY;
+
+	NENCLOSE(*np)->regnum = num;
+	BIT_STATUS_ON_AT_SIMPLE(env->capture_history, num);
+      }
+      else {
+	return ONIGERR_UNDEFINED_GROUP_OPTION;
+      }
+      break;
+#endif /* USE_CAPTURE_HISTORY */
+
+    case '(':   /* conditional expression: (?(cond)yes), (?(cond)yes|no) */
+      if (!PEND &&
+	  IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LPAREN_CONDITION)) {
+	UChar *name = NULL;
+	UChar *name_end;
+	PFETCH(c);
+	if (ONIGENC_IS_CODE_DIGIT(enc, c)) {     /* (n) */
+	  PUNFETCH;
+	  r = fetch_name((OnigCodePoint )'(', &p, end, &name_end, env, &num, 1);
+	  if (r < 0) return r;
+#if 0
+	  /* Relative number is not currently supported. (same as Perl) */
+	  if (num < 0) {
+	    num = BACKREF_REL_TO_ABS(num, env);
+	    if (num <= 0)
+	      return ONIGERR_INVALID_BACKREF;
+	  }
+#endif
+	  if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_STRICT_CHECK_BACKREF)) {
+	    if (num > env->num_mem ||
+		IS_NULL(SCANENV_MEM_NODES(env)[num]))
+	    return ONIGERR_INVALID_BACKREF;
+	  }
+	}
+#ifdef USE_NAMED_GROUP
+	else if (c == '<' || c == '\'') {    /* (<name>), ('name') */
+	  name = p;
+	  r = fetch_named_backref_token(c, tok, &p, end, env);
+	  if (r < 0) return r;
+	  if (!PPEEK_IS(')')) return ONIGERR_UNDEFINED_GROUP_OPTION;
+	  PINC;
+
+	  if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_USE_LEFT_MOST_NAMED_GROUP)) {
+	    num = tok->u.backref.ref1;
+	  }
+	  else {
+	    /* FIXME:
+	     * Use left most named group for now. This is the same as Perl.
+	     * However this should use the same strategy as normal back-
+	     * references on Ruby syntax; search right to left. */
+	    int len = tok->u.backref.num;
+	    num = len > 1 ? tok->u.backref.refs[0] : tok->u.backref.ref1;
+	  }
+	}
+#endif
+	else
+	  return ONIGERR_INVALID_CONDITION_PATTERN;
+	*np = node_new_enclose(ENCLOSE_CONDITION);
+	CHECK_NULL_RETURN_MEMERR(*np);
+	NENCLOSE(*np)->regnum = num;
+	if (IS_NOT_NULL(name)) NENCLOSE(*np)->state |= NST_NAME_REF;
+      }
+      else
+	return ONIGERR_UNDEFINED_GROUP_OPTION;
+      break;
+
+#if 0
+    case '|':   /* branch reset: (?|...) */
+      if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_VBAR_BRANCH_RESET)) {
+	/* TODO */
+      }
+      else
+	return ONIGERR_UNDEFINED_GROUP_OPTION;
+      break;
+#endif
+
+    case '^':   /* loads default options */
+      if (!PEND && IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL)) {
+	/* d-imsx */
+	ONOFF(option, ONIG_OPTION_ASCII_RANGE, 1);
+	ONOFF(option, ONIG_OPTION_IGNORECASE, 1);
+	ONOFF(option, ONIG_OPTION_SINGLELINE, 0);
+	ONOFF(option, ONIG_OPTION_MULTILINE,  1);
+	ONOFF(option, ONIG_OPTION_EXTEND, 1);
+	PFETCH(c);
+      }
+#if 0
+      else if (!PEND && IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) {
+	/* d-imx */
+	ONOFF(option, ONIG_OPTION_ASCII_RANGE, 0);
+	ONOFF(option, ONIG_OPTION_POSIX_BRACKET_ALL_RANGE, 0);
+	ONOFF(option, ONIG_OPTION_WORD_BOUND_ALL_RANGE, 0);
+	ONOFF(option, ONIG_OPTION_IGNORECASE, 1);
+	ONOFF(option, ONIG_OPTION_MULTILINE,  1);
+	ONOFF(option, ONIG_OPTION_EXTEND, 1);
+	PFETCH(c);
+      }
+#endif
+      else {
+	return ONIGERR_UNDEFINED_GROUP_OPTION;
+      }
+      /* fall through */
+#ifdef USE_POSIXLINE_OPTION
+    case 'p':
+#endif
+    case '-': case 'i': case 'm': case 's': case 'x':
+    case 'a': case 'd': case 'l': case 'u':
+      {
+	int neg = 0;
+
+	while (1) {
+	  switch (c) {
+	  case ':':
+	  case ')':
+	  break;
+
+	  case '-':  neg = 1; break;
+	  case 'x':  ONOFF(option, ONIG_OPTION_EXTEND,     neg); break;
+	  case 'i':  ONOFF(option, ONIG_OPTION_IGNORECASE, neg); break;
+	  case 's':
+	    if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL)) {
+	      ONOFF(option, ONIG_OPTION_MULTILINE,  neg);
+	    }
+	    else
+	      return ONIGERR_UNDEFINED_GROUP_OPTION;
+	    break;
+
+	  case 'm':
+	    if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL)) {
+	      ONOFF(option, ONIG_OPTION_SINGLELINE, (neg == 0 ? 1 : 0));
+	    }
+	    else if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) {
+	      ONOFF(option, ONIG_OPTION_MULTILINE,  neg);
+	    }
+	    else
+	      return ONIGERR_UNDEFINED_GROUP_OPTION;
+	    break;
+#ifdef USE_POSIXLINE_OPTION
+	  case 'p':
+	    ONOFF(option, ONIG_OPTION_MULTILINE|ONIG_OPTION_SINGLELINE, neg);
+	    break;
+#endif
+
+	  case 'a':     /* limits \d, \s, \w and POSIX brackets to ASCII range */
+	    if ((IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL) ||
+		 IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) &&
+		(neg == 0)) {
+	      ONOFF(option, ONIG_OPTION_ASCII_RANGE, 0);
+	      ONOFF(option, ONIG_OPTION_POSIX_BRACKET_ALL_RANGE, 1);
+	      ONOFF(option, ONIG_OPTION_WORD_BOUND_ALL_RANGE, 1);
+	    }
+	    else
+	      return ONIGERR_UNDEFINED_GROUP_OPTION;
+	    break;
+
+	  case 'u':
+	    if ((IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL) ||
+		 IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) &&
+		(neg == 0)) {
+	      ONOFF(option, ONIG_OPTION_ASCII_RANGE, 1);
+	      ONOFF(option, ONIG_OPTION_POSIX_BRACKET_ALL_RANGE, 1);
+	      ONOFF(option, ONIG_OPTION_WORD_BOUND_ALL_RANGE, 1);
+	    }
+	    else
+	      return ONIGERR_UNDEFINED_GROUP_OPTION;
+	    break;
+
+	  case 'd':
+	    if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL) &&
+		(neg == 0)) {
+	      ONOFF(option, ONIG_OPTION_ASCII_RANGE, 1);
+	    }
+	    else if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY) &&
+		(neg == 0)) {
+	      ONOFF(option, ONIG_OPTION_ASCII_RANGE, 0);
+	      ONOFF(option, ONIG_OPTION_POSIX_BRACKET_ALL_RANGE, 0);
+	      ONOFF(option, ONIG_OPTION_WORD_BOUND_ALL_RANGE, 0);
+	    }
+	    else
+	      return ONIGERR_UNDEFINED_GROUP_OPTION;
+	    break;
+
+	  case 'l':
+	    if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL) && (neg == 0)) {
+	      ONOFF(option, ONIG_OPTION_ASCII_RANGE, 1);
+	    }
+	    else
+	      return ONIGERR_UNDEFINED_GROUP_OPTION;
+	    break;
+
+	  default:
+	    return ONIGERR_UNDEFINED_GROUP_OPTION;
+	  }
+
+	  if (c == ')') {
+	    *np = node_new_option(option);
+	    CHECK_NULL_RETURN_MEMERR(*np);
+	    *src = p;
+	    return 2; /* option only */
+	  }
+	  else if (c == ':') {
+	    OnigOptionType prev = env->option;
+
+	    env->option = option;
+	    r = fetch_token(tok, &p, end, env);
+	    if (r < 0) {
+	      env->option = prev;
+	      return r;
+	    }
+	    r = parse_subexp(&target, tok, term, &p, end, env);
+	    env->option = prev;
+	    if (r < 0) return r;
+	    *np = node_new_option(option);
+	    CHECK_NULL_RETURN_MEMERR(*np);
+	    NENCLOSE(*np)->target = target;
+	    *src = p;
+	    return 0;
+	  }
+
+	  if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
+	  PFETCH(c);
+	}
+      }
+      break;
+
+    default:
+      return ONIGERR_UNDEFINED_GROUP_OPTION;
+    }
+  }
+  else {
+    if (ONIG_IS_OPTION_ON(env->option, ONIG_OPTION_DONT_CAPTURE_GROUP))
+      goto group;
+
+    *np = node_new_enclose_memory(env->option, 0);
+    CHECK_NULL_RETURN_MEMERR(*np);
+    num = scan_env_add_mem_entry(env);
+    if (num < 0) return num;
+    NENCLOSE(*np)->regnum = num;
+  }
+
+  CHECK_NULL_RETURN_MEMERR(*np);
+  r = fetch_token(tok, &p, end, env);
+  if (r < 0) return r;
+  r = parse_subexp(&target, tok, term, &p, end, env);
+  if (r < 0) {
+    onig_node_free(target);
+    return r;
+  }
+
+  if (NTYPE(*np) == NT_ANCHOR)
+    NANCHOR(*np)->target = target;
+  else {
+    NENCLOSE(*np)->target = target;
+    if (NENCLOSE(*np)->type == ENCLOSE_MEMORY) {
+      /* Don't move this to previous of parse_subexp() */
+      r = scan_env_set_mem_node(env, NENCLOSE(*np)->regnum, *np);
+      if (r != 0) return r;
+    }
+    else if (NENCLOSE(*np)->type == ENCLOSE_CONDITION) {
+      if (NTYPE(target) != NT_ALT) {
+	/* convert (?(cond)yes) to (?(cond)yes|empty) */
+	work1 = node_new_empty();
+	if (IS_NULL(work1)) goto err;
+	work2 = onig_node_new_alt(work1, NULL_NODE);
+	if (IS_NULL(work2)) goto err;
+	work1 = onig_node_new_alt(target, work2);
+	if (IS_NULL(work1)) goto err;
+	NENCLOSE(*np)->target = work1;
+      }
+    }
+  }
+
+  *src = p;
+  return 0;
+
+ err:
+  onig_node_free(work1);
+  onig_node_free(work2);
+  onig_node_free(*np);
+  *np = NULL;
+  return ONIGERR_MEMORY;
+}
+
+static const char* const PopularQStr[] = {
+  "?", "*", "+", "??", "*?", "+?"
+};
+
+static const char* const ReduceQStr[] = {
+  "", "", "*", "*?", "??", "+ and ??", "+? and ?"
+};
+
+static int
+set_quantifier(Node* qnode, Node* target, int group, ScanEnv* env)
+{
+  QtfrNode* qn;
+
+  qn = NQTFR(qnode);
+  if (qn->lower == 1 && qn->upper == 1) {
+    return 1;
+  }
+
+  switch (NTYPE(target)) {
+  case NT_STR:
+    if (! group) {
+      StrNode* sn = NSTR(target);
+      if (str_node_can_be_split(sn, env->enc)) {
+	Node* n = str_node_split_last_char(sn, env->enc);
+	if (IS_NOT_NULL(n)) {
+	  qn->target = n;
+	  return 2;
+	}
+      }
+    }
+    break;
+
+  case NT_QTFR:
+    { /* check redundant double repeat. */
+      /* verbose warn (?:.?)? etc... but not warn (.?)? etc... */
+      QtfrNode* qnt   = NQTFR(target);
+      int nestq_num   = popular_quantifier_num(qn);
+      int targetq_num = popular_quantifier_num(qnt);
+
+#ifdef USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR
+      if (nestq_num >= 0 && targetq_num >= 0 &&
+	  IS_SYNTAX_BV(env->syntax, ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT)) {
+	switch (ReduceTypeTable[targetq_num][nestq_num]) {
+	case RQ_ASIS:
+	  break;
+
+	case RQ_DEL:
+	  if (onig_warn != onig_null_warn) {
+	    onig_syntax_warn(env, "regular expression has redundant nested repeat operator '%s'",
+		PopularQStr[targetq_num]);
+	  }
+	  goto warn_exit;
+	  break;
+
+	default:
+	  if (onig_warn != onig_null_warn) {
+	    onig_syntax_warn(env, "nested repeat operator '%s' and '%s' was replaced with '%s' in regular expression",
+		PopularQStr[targetq_num], PopularQStr[nestq_num],
+		ReduceQStr[ReduceTypeTable[targetq_num][nestq_num]]);
+	  }
+	  goto warn_exit;
+	  break;
+	}
+      }
+
+    warn_exit:
+#endif
+      if (targetq_num >= 0) {
+	if (nestq_num >= 0) {
+	  onig_reduce_nested_quantifier(qnode, target);
+	  goto q_exit;
+	}
+	else if (targetq_num == 1 || targetq_num == 2) { /* * or + */
+	  /* (?:a*){n,m}, (?:a+){n,m} => (?:a*){n,n}, (?:a+){n,n} */
+	  if (! IS_REPEAT_INFINITE(qn->upper) && qn->upper > 1 && qn->greedy) {
+	    qn->upper = (qn->lower == 0 ? 1 : qn->lower);
+	  }
+	}
+      }
+    }
+    break;
+
+  default:
+    break;
+  }
+
+  qn->target = target;
+ q_exit:
+  return 0;
+}
+
+
+#ifndef CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
+static int
+clear_not_flag_cclass(CClassNode* cc, OnigEncoding enc)
+{
+  BBuf *tbuf;
+  int r;
+
+  if (IS_NCCLASS_NOT(cc)) {
+    bitset_invert(cc->bs);
+
+    if (! ONIGENC_IS_SINGLEBYTE(enc)) {
+      r = not_code_range_buf(enc, cc->mbuf, &tbuf);
+      if (r != 0) return r;
+
+      bbuf_free(cc->mbuf);
+      cc->mbuf = tbuf;
+    }
+
+    NCCLASS_CLEAR_NOT(cc);
+  }
+
+  return 0;
+}
+#endif /* CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS */
+
+typedef struct {
+  ScanEnv*    env;
+  CClassNode* cc;
+  CClassNode* asc_cc;
+  Node*       alt_root;
+  Node**      ptail;
+} IApplyCaseFoldArg;
+
+static int
+i_apply_case_fold(OnigCodePoint from, OnigCodePoint to[],
+		  int to_len, void* arg)
+{
+  IApplyCaseFoldArg* iarg;
+  ScanEnv* env;
+  CClassNode* cc;
+  CClassNode* asc_cc;
+  BitSetRef bs;
+  int add_flag, r;
+
+  iarg = (IApplyCaseFoldArg* )arg;
+  env = iarg->env;
+  cc  = iarg->cc;
+  asc_cc = iarg->asc_cc;
+  bs = cc->bs;
+
+  if (IS_NULL(asc_cc)) {
+    add_flag = 0;
+  }
+  else if (ONIGENC_IS_ASCII_CODE(from) == ONIGENC_IS_ASCII_CODE(*to)) {
+    add_flag = 1;
+  }
+  else {
+    add_flag = onig_is_code_in_cc(env->enc, from, asc_cc);
+    if (IS_NCCLASS_NOT(asc_cc))
+      add_flag = !add_flag;
+  }
+
+  if (to_len == 1) {
+    int is_in = onig_is_code_in_cc(env->enc, from, cc);
+#ifdef CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
+    if ((is_in != 0 && !IS_NCCLASS_NOT(cc)) ||
+	(is_in == 0 &&  IS_NCCLASS_NOT(cc))) {
+      if (add_flag) {
+	if (ONIGENC_MBC_MINLEN(env->enc) > 1 || *to >= SINGLE_BYTE_SIZE) {
+	  r = add_code_range0(&(cc->mbuf), env, *to, *to, 0);
+	  if (r < 0) return r;
+	}
+	else {
+	  BITSET_SET_BIT(bs, *to);
+	}
+      }
+    }
+#else
+    if (is_in != 0) {
+      if (add_flag) {
+	if (ONIGENC_MBC_MINLEN(env->enc) > 1 || *to >= SINGLE_BYTE_SIZE) {
+	  if (IS_NCCLASS_NOT(cc)) clear_not_flag_cclass(cc, env->enc);
+	  r = add_code_range0(&(cc->mbuf), env, *to, *to, 0);
+	  if (r < 0) return r;
+	}
+	else {
+	  if (IS_NCCLASS_NOT(cc)) {
+	    BITSET_CLEAR_BIT(bs, *to);
+	  }
+	  else {
+	    BITSET_SET_BIT(bs, *to);
+	  }
+	}
+      }
+    }
+#endif /* CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS */
+  }
+  else {
+    int r, i, len;
+    UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
+    Node *snode = NULL_NODE;
+
+    if (onig_is_code_in_cc(env->enc, from, cc)
+#ifdef CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
+	&& !IS_NCCLASS_NOT(cc)
+#endif
+	) {
+      for (i = 0; i < to_len; i++) {
+	len = ONIGENC_CODE_TO_MBC(env->enc, to[i], buf);
+	if (i == 0) {
+	  snode = onig_node_new_str(buf, buf + len);
+	  CHECK_NULL_RETURN_MEMERR(snode);
+
+	  /* char-class expanded multi-char only
+	     compare with string folded at match time. */
+	  NSTRING_SET_AMBIG(snode);
+	}
+	else {
+	  r = onig_node_str_cat(snode, buf, buf + len);
+	  if (r < 0) {
+	    onig_node_free(snode);
+	    return r;
+	  }
+	}
+      }
+
+      *(iarg->ptail) = onig_node_new_alt(snode, NULL_NODE);
+      CHECK_NULL_RETURN_MEMERR(*(iarg->ptail));
+      iarg->ptail = &(NCDR((*(iarg->ptail))));
+    }
+  }
+
+  return 0;
+}
+
+static int
+cclass_case_fold(Node** np, CClassNode* cc, CClassNode* asc_cc, ScanEnv* env)
+{
+  int r;
+  IApplyCaseFoldArg iarg;
+
+  iarg.env         = env;
+  iarg.cc          = cc;
+  iarg.asc_cc      = asc_cc;
+  iarg.alt_root    = NULL_NODE;
+  iarg.ptail       = &(iarg.alt_root);
+
+  r = ONIGENC_APPLY_ALL_CASE_FOLD(env->enc, env->case_fold_flag,
+				  i_apply_case_fold, &iarg);
+  if (r != 0) {
+    onig_node_free(iarg.alt_root);
+    return r;
+  }
+  if (IS_NOT_NULL(iarg.alt_root)) {
+    Node* work = onig_node_new_alt(*np, iarg.alt_root);
+    if (IS_NULL(work)) {
+      onig_node_free(iarg.alt_root);
+      return ONIGERR_MEMORY;
+    }
+    *np = work;
+  }
+  return r;
+}
+
+static int
+node_linebreak(Node** np, ScanEnv* env)
+{
+  /* same as (?>\x0D\x0A|[\x0A-\x0D\x{85}\x{2028}\x{2029}]) */
+  Node* left = NULL;
+  Node* right = NULL;
+  Node* target1 = NULL;
+  Node* target2 = NULL;
+  CClassNode* cc;
+  int num1, num2, r;
+  UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN * 2];
+
+  /* \x0D\x0A */
+  num1 = ONIGENC_CODE_TO_MBC(env->enc, 0x0D, buf);
+  if (num1 < 0) return num1;
+  num2 = ONIGENC_CODE_TO_MBC(env->enc, 0x0A, buf + num1);
+  if (num2 < 0) return num2;
+  left = node_new_str_raw(buf, buf + num1 + num2);
+  if (IS_NULL(left)) goto err;
+
+  /* [\x0A-\x0D] or [\x0A-\x0D\x{85}\x{2028}\x{2029}] */
+  right = node_new_cclass();
+  if (IS_NULL(right)) goto err;
+  cc = NCCLASS(right);
+  if (ONIGENC_MBC_MINLEN(env->enc) > 1) {
+    r = add_code_range(&(cc->mbuf), env, 0x0A, 0x0D);
+    if (r != 0) goto err;
+  }
+  else {
+    bitset_set_range(env, cc->bs, 0x0A, 0x0D);
+  }
+
+  /* TODO: move this block to enc/unicode.c */
+  if (ONIGENC_IS_UNICODE(env->enc)) {
+    /* UTF-8, UTF-16BE/LE, UTF-32BE/LE */
+    r = add_code_range(&(cc->mbuf), env, 0x85, 0x85);
+    if (r != 0) goto err;
+    r = add_code_range(&(cc->mbuf), env, 0x2028, 0x2029);
+    if (r != 0) goto err;
+  }
+
+  /* ...|... */
+  target1 = onig_node_new_alt(right, NULL_NODE);
+  if (IS_NULL(target1)) goto err;
+  right = NULL;
+  target2 = onig_node_new_alt(left, target1);
+  if (IS_NULL(target2)) goto err;
+  left = NULL;
+  target1 = NULL;
+
+  /* (?>...) */
+  *np = node_new_enclose(ENCLOSE_STOP_BACKTRACK);
+  if (IS_NULL(*np)) goto err;
+  NENCLOSE(*np)->target = target2;
+  return ONIG_NORMAL;
+
+ err:
+  onig_node_free(left);
+  onig_node_free(right);
+  onig_node_free(target1);
+  onig_node_free(target2);
+  return ONIGERR_MEMORY;
+}
+
+static int
+propname2ctype(ScanEnv* env, const char* propname)
+{
+  UChar* name = (UChar* )propname;
+  int ctype = env->enc->property_name_to_ctype(ONIG_ENCODING_ASCII,
+      name, name + strlen(propname));
+  return ctype;
+}
+
+static int
+node_extended_grapheme_cluster(Node** np, ScanEnv* env)
+{
+  Node* tmp = NULL;
+  Node* np1 = NULL;
+  Node* list = NULL;
+  Node* list2 = NULL;
+  Node* alt = NULL;
+  Node* alt2 = NULL;
+  BBuf *pbuf1 = NULL;
+  int r = 0;
+  int num1;
+  UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN * 2];
+  OnigOptionType option;
+
+#ifdef USE_UNICODE_PROPERTIES
+  if (ONIGENC_IS_UNICODE(env->enc)) {
+    /* UTF-8, UTF-16BE/LE, UTF-32BE/LE */
+    CClassNode* cc;
+    OnigCodePoint sb_out = (ONIGENC_MBC_MINLEN(env->enc) > 1) ? 0x00 : 0x80;
+    int extend = propname2ctype(env, "Grapheme_Cluster_Break=Extend");
+
+    /* Prepend*
+     * ( RI-sequence | Hangul-Syllable | !Control )
+     * ( Grapheme_Extend | SpacingMark )* */
+
+    /* ( Grapheme_Extend | SpacingMark )* */
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, extend, 0, 0, env);
+    if (r != 0) goto err;
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=SpacingMark"), 0, 0, env);
+    if (r != 0) goto err;
+    r = add_code_range(&(cc->mbuf), env, 0x200D, 0x200D);
+    if (r != 0) goto err;
+
+    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = node_new_list(np1, NULL_NODE);
+    if (IS_NULL(tmp)) goto err;
+    list = tmp;
+    np1 = NULL;
+
+    /* ( RI-sequence | Hangul-Syllable | !Control ) */
+    /* !Control */
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=Control"), 1, 0, env);
+    if (r != 0) goto err;
+    if (ONIGENC_MBC_MINLEN(env->enc) > 1) {
+      BBuf *pbuf2 = NULL;
+      r = add_code_range(&pbuf1, env, 0x0a, 0x0a);
+      if (r != 0) goto err;
+      r = add_code_range(&pbuf1, env, 0x0d, 0x0d);
+      if (r != 0) goto err;
+      r = and_code_range_buf(cc->mbuf, 0, pbuf1, 1, &pbuf2, env);
+      if (r != 0) {
+	bbuf_free(pbuf2);
+	goto err;
+      }
+      bbuf_free(pbuf1);
+      pbuf1 = NULL;
+      bbuf_free(cc->mbuf);
+      cc->mbuf = pbuf2;
+    }
+    else {
+      BITSET_CLEAR_BIT(cc->bs, 0x0a);
+      BITSET_CLEAR_BIT(cc->bs, 0x0d);
+    }
+
+    tmp = onig_node_new_alt(np1, NULL_NODE);
+    if (IS_NULL(tmp)) goto err;
+    alt = tmp;
+    np1 = NULL;
+
+    /* Hangul-Syllable
+     *  := L* V+ T*
+     *  | L* LV V* T*
+     *  | L* LVT T*
+     *  | L+
+     *  | T+ */
+
+    /* T+ */
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=T"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_quantifier(1, REPEAT_INFINITE, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = onig_node_new_alt(np1, alt);
+    if (IS_NULL(tmp)) goto err;
+    alt = tmp;
+    np1 = NULL;
+
+    /* L+ */
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=L"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_quantifier(1, REPEAT_INFINITE, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = onig_node_new_alt(np1, alt);
+    if (IS_NULL(tmp)) goto err;
+    alt = tmp;
+    np1 = NULL;
+
+    /* L* LVT T* */
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=T"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = node_new_list(np1, NULL_NODE);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=LVT"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_list(np1, list2);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=L"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = node_new_list(np1, list2);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    tmp = onig_node_new_alt(list2, alt);
+    if (IS_NULL(tmp)) goto err;
+    alt = tmp;
+    list2 = NULL;
+
+    /* L* LV V* T* */
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=T"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = node_new_list(np1, NULL_NODE);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=V"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = node_new_list(np1, list2);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=LV"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_list(np1, list2);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=L"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = node_new_list(np1, list2);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    tmp = onig_node_new_alt(list2, alt);
+    if (IS_NULL(tmp)) goto err;
+    alt = tmp;
+    list2 = NULL;
+
+    /* L* V+ T* */
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=T"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = node_new_list(np1, NULL_NODE);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=V"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_quantifier(1, REPEAT_INFINITE, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = node_new_list(np1, list2);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=L"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = node_new_list(np1, list2);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    tmp = onig_node_new_alt(list2, alt);
+    if (IS_NULL(tmp)) goto err;
+    alt = tmp;
+    list2 = NULL;
+
+    /* Emoji sequence := (E_Base | EBG) Extend* E_Modifier?
+     *                   (ZWJ (Glue_After_Zwj | EBG Extend* E_Modifier?) )* */
+
+    /* ZWJ (Glue_After_Zwj | E_Base_GAZ Extend* E_Modifier?) */
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Modifier"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_quantifier(0, 1, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = node_new_list(np1, NULL_NODE);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, extend, 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = node_new_list(np1, list2);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Base_GAZ"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_list(np1, list2);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    tmp = onig_node_new_alt(list2, NULL_NODE);
+    if (IS_NULL(tmp)) goto err;
+    alt2 = tmp;
+    list2 = NULL;
+
+    /* Glue_After_Zwj */
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, extend, 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = node_new_list(np1, NULL_NODE);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    {
+      static const OnigCodePoint ranges[] = {
+	13,
+	0x1F308, 0x1F308,
+	0x1F33E, 0x1F33E,
+	0x1F373, 0x1F373,
+	0x1F393, 0x1F393,
+	0x1F3A4, 0x1F3A4,
+	0x1F3A8, 0x1F3A8,
+	0x1F3EB, 0x1F3EB,
+	0x1F3ED, 0x1F3ED,
+	0x1F4BB, 0x1F4BC,
+	0x1F527, 0x1F527,
+	0x1F52C, 0x1F52C,
+	0x1F680, 0x1F680,
+	0x1F692, 0x1F692,
+      };
+      r = add_ctype_to_cc_by_range(cc, -1, 0, env, sb_out, ranges);
+      if (r != 0) goto err;
+    }
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=Glue_After_Zwj"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_list(np1, list2);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    tmp = onig_node_new_alt(list2, alt2);
+    if (IS_NULL(tmp)) goto err;
+    alt2 = tmp;
+    list2 = NULL;
+
+    /* Emoji variation sequence
+     * http://unicode.org/Public/emoji/4.0/emoji-zwj-sequences.txt
+     */
+    r = ONIGENC_CODE_TO_MBC(env->enc, 0xfe0f, buf);
+    if (r < 0) goto err;
+    np1 = node_new_str_raw(buf, buf + r);
+    if (IS_NULL(np1)) goto err;
+
+    tmp = node_new_quantifier(0, 1, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = node_new_list(np1, NULL_NODE);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    {
+      static const OnigCodePoint ranges[] = {
+	4,
+	0x2640, 0x2640,
+	0x2642, 0x2642,
+	0x2695, 0x2696,
+	0x2708, 0x2708,
+      };
+      r = add_ctype_to_cc_by_range(cc, -1, 0, env, sb_out, ranges);
+      if (r != 0) goto err;
+    }
+
+    tmp = node_new_list(np1, list2);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    tmp = onig_node_new_alt(list2, alt2);
+    if (IS_NULL(tmp)) goto err;
+    alt2 = tmp;
+    list2 = NULL;
+
+    tmp = node_new_list(alt2, NULL_NODE);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    alt2 = NULL;
+
+    /* ZWJ */
+    r = ONIGENC_CODE_TO_MBC(env->enc, 0x200D, buf);
+    if (r < 0) goto err;
+    np1 = node_new_str_raw(buf, buf + r);
+    if (IS_NULL(np1)) goto err;
+
+    tmp = node_new_list(np1, list2);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = list2;
+    np1 = tmp;
+    list2 = NULL;
+
+    tmp = node_new_list(np1, NULL_NODE);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    /* E_Modifier? */
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Modifier"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_quantifier(0, 1, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = node_new_list(np1, list2);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    /* Extend* */
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, extend, 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = node_new_list(np1, list2);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    /* (E_Base | EBG) */
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    {
+      static const OnigCodePoint ranges[] = {
+	8,
+	0x1F3C2, 0x1F3C2,
+	0x1F3C7, 0x1F3C7,
+	0x1F3CC, 0x1F3CC,
+	0x1F3F3, 0x1F3F3,
+	0x1F441, 0x1F441,
+	0x1F46F, 0x1F46F,
+	0x1F574, 0x1F574,
+	0x1F6CC, 0x1F6CC,
+      };
+      r = add_ctype_to_cc_by_range(cc, -1, 0, env, sb_out, ranges);
+      if (r != 0) goto err;
+    }
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Base"), 0, 0, env);
+    if (r != 0) goto err;
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Base_GAZ"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_list(np1, list2);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    tmp = onig_node_new_alt(list2, alt);
+    if (IS_NULL(tmp)) goto err;
+    alt = tmp;
+    list2 = NULL;
+
+    /* ZWJ (E_Base_GAZ | Glue_After_Zwj) E_Modifier? */
+    /* a sequence starting with ZWJ seems artificial, but GraphemeBreakTest
+     * has such examples.
+     * http://www.unicode.org/Public/9.0.0/ucd/auxiliary/GraphemeBreakTest.html
+     */
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Modifier"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_quantifier(0, 1, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = node_new_list(np1, NULL_NODE);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=Glue_After_Zwj"), 0, 0, env);
+    if (r != 0) goto err;
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Base_GAZ"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_list(np1, list2);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    r = ONIGENC_CODE_TO_MBC(env->enc, 0x200D, buf);
+    if (r < 0) goto err;
+    np1 = node_new_str_raw(buf, buf + r);
+    if (IS_NULL(np1)) goto err;
+
+    tmp = node_new_list(np1, list2);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    tmp = onig_node_new_alt(list2, alt);
+    if (IS_NULL(tmp)) goto err;
+    alt = tmp;
+    list2 = NULL;
+
+    /* RI-Sequence := Regional_Indicator{2} */
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_code_range(&(cc->mbuf), env, 0x1F1E6, 0x1F1FF);
+    if (r != 0) goto err;
+
+    tmp = node_new_quantifier(2, 2, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = node_new_list(np1, list2);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    tmp = onig_node_new_alt(list2, alt);
+    if (IS_NULL(tmp)) goto err;
+    alt = tmp;
+    list2 = NULL;
+
+    tmp = node_new_list(alt, list);
+    if (IS_NULL(tmp)) goto err;
+    list = tmp;
+    alt = NULL;
+
+    /* Prepend* */
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=Prepend"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = node_new_list(np1, list);
+    if (IS_NULL(tmp)) goto err;
+    list = tmp;
+    np1 = NULL;
+
+    /* PerlSyntax: (?s:.), RubySyntax: (?m:.) */
+    np1 = node_new_anychar();
+    if (IS_NULL(np1)) goto err;
+
+    option = env->option;
+    ONOFF(option, ONIG_OPTION_MULTILINE, 0);
+    tmp = node_new_option(option);
+    if (IS_NULL(tmp)) goto err;
+    NENCLOSE(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = onig_node_new_alt(np1, NULL_NODE);
+    if (IS_NULL(tmp)) goto err;
+    alt = tmp;
+    np1 = NULL;
+
+    /* Prepend+ */
+    r = ONIGENC_CODE_TO_MBC(env->enc, 0x200D, buf);
+    if (r < 0) goto err;
+    np1 = node_new_str_raw(buf, buf + r);
+    if (IS_NULL(np1)) goto err;
+
+    tmp = node_new_quantifier(0, 1, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = node_new_list(np1, NULL_NODE);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    np1 = node_new_cclass();
+    if (IS_NULL(np1)) goto err;
+    cc = NCCLASS(np1);
+    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=Prepend"), 0, 0, env);
+    if (r != 0) goto err;
+
+    tmp = node_new_quantifier(1, REPEAT_INFINITE, 0);
+    if (IS_NULL(tmp)) goto err;
+    NQTFR(tmp)->target = np1;
+    np1 = tmp;
+
+    tmp = node_new_list(np1, list2);
+    if (IS_NULL(tmp)) goto err;
+    list2 = tmp;
+    np1 = NULL;
+
+    tmp = onig_node_new_alt(list2, alt);
+    if (IS_NULL(tmp)) goto err;
+    alt = tmp;
+    list2 = NULL;
+
+    tmp = onig_node_new_alt(list, alt);
+    if (IS_NULL(tmp)) goto err;
+    alt = tmp;
+    list = NULL;
+  }
+  else
+#endif /* USE_UNICODE_PROPERTIES */
+  {
+    /* PerlSyntax: (?s:.), RubySyntax: (?m:.) */
+    np1 = node_new_anychar();
+    if (IS_NULL(np1)) goto err;
+
+    option = env->option;
+    ONOFF(option, ONIG_OPTION_MULTILINE, 0);
+    tmp = node_new_option(option);
+    if (IS_NULL(tmp)) goto err;
+    NENCLOSE(tmp)->target = np1;
+    np1 = tmp;
+
+    alt = onig_node_new_alt(np1, NULL_NODE);
+    if (IS_NULL(alt)) goto err;
+    np1 = NULL;
+  }
+
+  /* \x0D\x0A */
+  r = ONIGENC_CODE_TO_MBC(env->enc, 0x0D, buf);
+  if (r < 0) goto err;
+  num1 = r;
+  r = ONIGENC_CODE_TO_MBC(env->enc, 0x0A, buf + num1);
+  if (r < 0) goto err;
+  np1 = node_new_str_raw(buf, buf + num1 + r);
+  if (IS_NULL(np1)) goto err;
+
+  tmp = onig_node_new_alt(np1, alt);
+  if (IS_NULL(tmp)) goto err;
+  alt = tmp;
+  np1 = NULL;
+
+  /* (?>\x0D\x0A|...) */
+  tmp = node_new_enclose(ENCLOSE_STOP_BACKTRACK);
+  if (IS_NULL(tmp)) goto err;
+  NENCLOSE(tmp)->target = alt;
+  np1 = tmp;
+
+#ifdef USE_UNICODE_PROPERTIES
+  if (ONIGENC_IS_UNICODE(env->enc)) {
+    /* Don't ignore case. */
+    option = env->option;
+    ONOFF(option, ONIG_OPTION_IGNORECASE, 1);
+    *np = node_new_option(option);
+    if (IS_NULL(*np)) goto err;
+    NENCLOSE(*np)->target = np1;
+  }
+  else
+#endif
+  {
+    *np = np1;
+  }
+  return ONIG_NORMAL;
+
+ err:
+  onig_node_free(np1);
+  onig_node_free(list);
+  onig_node_free(list2);
+  onig_node_free(alt);
+  onig_node_free(alt2);
+  bbuf_free(pbuf1);
+  return (r == 0) ? ONIGERR_MEMORY : r;
+}
+
+static int
+countbits(unsigned int bits)
+{
+  bits = (bits & 0x55555555) + ((bits >> 1) & 0x55555555);
+  bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333);
+  bits = (bits & 0x0f0f0f0f) + ((bits >> 4) & 0x0f0f0f0f);
+  bits = (bits & 0x00ff00ff) + ((bits >> 8) & 0x00ff00ff);
+  return (bits & 0x0000ffff) + ((bits >>16) & 0x0000ffff);
+}
+
+static int
+is_onechar_cclass(CClassNode* cc, OnigCodePoint* code)
+{
+  const OnigCodePoint not_found = ONIG_LAST_CODE_POINT;
+  OnigCodePoint c = not_found;
+  int i;
+  BBuf *bbuf = cc->mbuf;
+
+  if (IS_NCCLASS_NOT(cc)) return 0;
+
+  /* check bbuf */
+  if (IS_NOT_NULL(bbuf)) {
+    OnigCodePoint n, *data;
+    GET_CODE_POINT(n, bbuf->p);
+    data = (OnigCodePoint* )(bbuf->p) + 1;
+    if ((n == 1) && (data[0] == data[1])) {
+      /* only one char found in the bbuf, save the code point. */
+      c = data[0];
+      if (((c < SINGLE_BYTE_SIZE) && BITSET_AT(cc->bs, c))) {
+	/* skip if c is included in the bitset */
+	c = not_found;
+      }
+    }
+    else {
+      return 0;  /* the bbuf contains multiple chars */
+    }
+  }
+
+  /* check bitset */
+  for (i = 0; i < BITSET_SIZE; i++) {
+    Bits b1 = cc->bs[i];
+    if (b1 != 0) {
+      if (((b1 & (b1 - 1)) == 0) && (c == not_found)) {
+	c = BITS_IN_ROOM * i + countbits(b1 - 1);
+      } else {
+	return 0;  /* the character class contains multiple chars */
+      }
+    }
+  }
+
+  if (c != not_found) {
+    *code = c;
+    return 1;
+  }
+
+  /* the character class contains no char. */
+  return 0;
+}
+
+
+static int
+parse_exp(Node** np, OnigToken* tok, int term,
+	  UChar** src, UChar* end, ScanEnv* env)
+{
+  int r, len, group = 0;
+  Node* qn;
+  Node** targetp;
+
+  *np = NULL;
+  if (tok->type == (enum TokenSyms )term)
+    goto end_of_token;
+
+  switch (tok->type) {
+  case TK_ALT:
+  case TK_EOT:
+  end_of_token:
+    *np = node_new_empty();
+    return tok->type;
+    break;
+
+  case TK_SUBEXP_OPEN:
+    r = parse_enclose(np, tok, TK_SUBEXP_CLOSE, src, end, env);
+    if (r < 0) return r;
+    if (r == 1) group = 1;
+    else if (r == 2) { /* option only */
+      Node* target;
+      OnigOptionType prev = env->option;
+
+      env->option = NENCLOSE(*np)->option;
+      r = fetch_token(tok, src, end, env);
+      if (r < 0) {
+	env->option = prev;
+	return r;
+      }
+      r = parse_subexp(&target, tok, term, src, end, env);
+      env->option = prev;
+      if (r < 0) {
+	onig_node_free(target);
+	return r;
+      }
+      NENCLOSE(*np)->target = target;
+      return tok->type;
+    }
+    break;
+
+  case TK_SUBEXP_CLOSE:
+    if (! IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_UNMATCHED_CLOSE_SUBEXP))
+      return ONIGERR_UNMATCHED_CLOSE_PARENTHESIS;
+
+    if (tok->escaped) goto tk_raw_byte;
+    else goto tk_byte;
+    break;
+
+  case TK_LINEBREAK:
+    r = node_linebreak(np, env);
+    if (r < 0) return r;
+    break;
+
+  case TK_EXTENDED_GRAPHEME_CLUSTER:
+    r = node_extended_grapheme_cluster(np, env);
+    if (r < 0) return r;
+    break;
+
+  case TK_KEEP:
+    *np = onig_node_new_anchor(ANCHOR_KEEP);
+    CHECK_NULL_RETURN_MEMERR(*np);
+    break;
+
+  case TK_STRING:
+  tk_byte:
+    {
+      *np = node_new_str(tok->backp, *src);
+      CHECK_NULL_RETURN_MEMERR(*np);
+
+    string_loop:
+      while (1) {
+	r = fetch_token(tok, src, end, env);
+	if (r < 0) return r;
+	if (r == TK_STRING) {
+	  r = onig_node_str_cat(*np, tok->backp, *src);
+	}
+#ifndef NUMBERED_CHAR_IS_NOT_CASE_AMBIG
+	else if (r == TK_CODE_POINT) {
+	  r = node_str_cat_codepoint(*np, env->enc, tok->u.code);
+	}
+#endif
+	else {
+	  break;
+	}
+	if (r < 0) return r;
+      }
+
+    string_end:
+      targetp = np;
+      goto repeat;
+    }
+    break;
+
+  case TK_RAW_BYTE:
+  tk_raw_byte:
+    {
+      *np = node_new_str_raw_char((UChar )tok->u.c);
+      CHECK_NULL_RETURN_MEMERR(*np);
+      len = 1;
+      while (1) {
+	if (len >= ONIGENC_MBC_MINLEN(env->enc)) {
+	  if (len == enclen(env->enc, NSTR(*np)->s, NSTR(*np)->end)) {
+	    r = fetch_token(tok, src, end, env);
+	    NSTRING_CLEAR_RAW(*np);
+	    goto string_end;
+	  }
+	}
+
+	r = fetch_token(tok, src, end, env);
+	if (r < 0) return r;
+	if (r != TK_RAW_BYTE) {
+	  /* Don't use this, it is wrong for little endian encodings. */
+#ifdef USE_PAD_TO_SHORT_BYTE_CHAR
+	  int rem;
+	  if (len < ONIGENC_MBC_MINLEN(env->enc)) {
+	    rem = ONIGENC_MBC_MINLEN(env->enc) - len;
+	    (void )node_str_head_pad(NSTR(*np), rem, (UChar )0);
+	    if (len + rem == enclen(env->enc, NSTR(*np)->s)) {
+	      NSTRING_CLEAR_RAW(*np);
+	      goto string_end;
+	    }
+	  }
+#endif
+	  return ONIGERR_TOO_SHORT_MULTI_BYTE_STRING;
+	}
+
+	r = node_str_cat_char(*np, (UChar )tok->u.c);
+	if (r < 0) return r;
+
+	len++;
+      }
+    }
+    break;
+
+  case TK_CODE_POINT:
+    {
+      *np = node_new_empty();
+      CHECK_NULL_RETURN_MEMERR(*np);
+      r = node_str_cat_codepoint(*np, env->enc, tok->u.code);
+      if (r != 0) return r;
+#ifdef NUMBERED_CHAR_IS_NOT_CASE_AMBIG
+      NSTRING_SET_RAW(*np);
+#else
+      goto string_loop;
+#endif
+    }
+    break;
+
+  case TK_QUOTE_OPEN:
+    {
+      OnigCodePoint end_op[2];
+      UChar *qstart, *qend, *nextp;
+
+      end_op[0] = (OnigCodePoint )MC_ESC(env->syntax);
+      end_op[1] = (OnigCodePoint )'E';
+      qstart = *src;
+      qend = find_str_position(end_op, 2, qstart, end, &nextp, env->enc);
+      if (IS_NULL(qend)) {
+	nextp = qend = end;
+      }
+      *np = node_new_str(qstart, qend);
+      CHECK_NULL_RETURN_MEMERR(*np);
+      *src = nextp;
+    }
+    break;
+
+  case TK_CHAR_TYPE:
+    {
+      switch (tok->u.prop.ctype) {
+      case ONIGENC_CTYPE_WORD:
+	*np = node_new_ctype(tok->u.prop.ctype, tok->u.prop.not,
+			     IS_ASCII_RANGE(env->option));
+	CHECK_NULL_RETURN_MEMERR(*np);
+	break;
+
+      case ONIGENC_CTYPE_SPACE:
+      case ONIGENC_CTYPE_DIGIT:
+      case ONIGENC_CTYPE_XDIGIT:
+	{
+	  CClassNode* cc;
+
+	  *np = node_new_cclass();
+	  CHECK_NULL_RETURN_MEMERR(*np);
+	  cc = NCCLASS(*np);
+	  r = add_ctype_to_cc(cc, tok->u.prop.ctype, 0,
+	      IS_ASCII_RANGE(env->option), env);
+	  if (r != 0) return r;
+	  if (tok->u.prop.not != 0) NCCLASS_SET_NOT(cc);
+	}
+	break;
+
+      default:
+	return ONIGERR_PARSER_BUG;
+	break;
+      }
+    }
+    break;
+
+  case TK_CHAR_PROPERTY:
+    r = parse_char_property(np, tok, src, end, env);
+    if (r != 0) return r;
+    break;
+
+  case TK_CC_OPEN:
+    {
+      Node *asc_node;
+      CClassNode* cc;
+      OnigCodePoint code;
+
+      r = parse_char_class(np, &asc_node, tok, src, end, env);
+      if (r != 0) {
+	onig_node_free(asc_node);
+	return r;
+      }
+
+      cc = NCCLASS(*np);
+      if (is_onechar_cclass(cc, &code)) {
+	onig_node_free(*np);
+	onig_node_free(asc_node);
+	*np = node_new_empty();
+	CHECK_NULL_RETURN_MEMERR(*np);
+	r = node_str_cat_codepoint(*np, env->enc, code);
+	if (r != 0) return r;
+	goto string_loop;
+      }
+      if (IS_IGNORECASE(env->option)) {
+	r = cclass_case_fold(np, cc, NCCLASS(asc_node), env);
+	if (r != 0) {
+	  onig_node_free(asc_node);
+	  return r;
+	}
+      }
+      onig_node_free(asc_node);
+    }
+    break;
+
+  case TK_ANYCHAR:
+    *np = node_new_anychar();
+    CHECK_NULL_RETURN_MEMERR(*np);
+    break;
+
+  case TK_ANYCHAR_ANYTIME:
+    *np = node_new_anychar();
+    CHECK_NULL_RETURN_MEMERR(*np);
+    qn = node_new_quantifier(0, REPEAT_INFINITE, 0);
+    CHECK_NULL_RETURN_MEMERR(qn);
+    NQTFR(qn)->target = *np;
+    *np = qn;
+    break;
+
+  case TK_BACKREF:
+    len = tok->u.backref.num;
+    *np = node_new_backref(len,
+		   (len > 1 ? tok->u.backref.refs : &(tok->u.backref.ref1)),
+			   tok->u.backref.by_name,
+#ifdef USE_BACKREF_WITH_LEVEL
+			   tok->u.backref.exist_level,
+			   tok->u.backref.level,
+#endif
+			   env);
+    CHECK_NULL_RETURN_MEMERR(*np);
+    break;
+
+#ifdef USE_SUBEXP_CALL
+  case TK_CALL:
+    {
+      int gnum = tok->u.call.gnum;
+
+      if (gnum < 0 || tok->u.call.rel != 0) {
+	if (gnum > 0) gnum--;
+	gnum = BACKREF_REL_TO_ABS(gnum, env);
+	if (gnum <= 0)
+	  return ONIGERR_INVALID_BACKREF;
+      }
+      *np = node_new_call(tok->u.call.name, tok->u.call.name_end, gnum);
+      CHECK_NULL_RETURN_MEMERR(*np);
+      env->num_call++;
+    }
+    break;
+#endif
+
+  case TK_ANCHOR:
+    *np = onig_node_new_anchor(tok->u.anchor.subtype);
+    CHECK_NULL_RETURN_MEMERR(*np);
+    NANCHOR(*np)->ascii_range = tok->u.anchor.ascii_range;
+    break;
+
+  case TK_OP_REPEAT:
+  case TK_INTERVAL:
+    if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS)) {
+      if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS))
+	return ONIGERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED;
+      else
+	*np = node_new_empty();
+    }
+    else {
+      goto tk_byte;
+    }
+    break;
+
+  default:
+    return ONIGERR_PARSER_BUG;
+    break;
+  }
+
+  {
+    targetp = np;
+
+  re_entry:
+    r = fetch_token(tok, src, end, env);
+    if (r < 0) return r;
+
+  repeat:
+    if (r == TK_OP_REPEAT || r == TK_INTERVAL) {
+      if (is_invalid_quantifier_target(*targetp))
+	return ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID;
+
+      qn = node_new_quantifier(tok->u.repeat.lower, tok->u.repeat.upper,
+			       (r == TK_INTERVAL ? 1 : 0));
+      CHECK_NULL_RETURN_MEMERR(qn);
+      NQTFR(qn)->greedy = tok->u.repeat.greedy;
+      r = set_quantifier(qn, *targetp, group, env);
+      if (r < 0) {
+	onig_node_free(qn);
+	return r;
+      }
+
+      if (tok->u.repeat.possessive != 0) {
+	Node* en;
+	en = node_new_enclose(ENCLOSE_STOP_BACKTRACK);
+	if (IS_NULL(en)) {
+	  onig_node_free(qn);
+	  return ONIGERR_MEMORY;
+	}
+	NENCLOSE(en)->target = qn;
+	qn = en;
+      }
+
+      if (r == 0) {
+	*targetp = qn;
+      }
+      else if (r == 1) {
+	onig_node_free(qn);
+      }
+      else if (r == 2) { /* split case: /abc+/ */
+	Node *tmp;
+
+	*targetp = node_new_list(*targetp, NULL);
+	if (IS_NULL(*targetp)) {
+	  onig_node_free(qn);
+	  return ONIGERR_MEMORY;
+	}
+	tmp = NCDR(*targetp) = node_new_list(qn, NULL);
+	if (IS_NULL(tmp)) {
+	  onig_node_free(qn);
+	  return ONIGERR_MEMORY;
+	}
+	targetp = &(NCAR(tmp));
+      }
+      goto re_entry;
+    }
+  }
+
+  return r;
+}
+
+static int
+parse_branch(Node** top, OnigToken* tok, int term,
+	     UChar** src, UChar* end, ScanEnv* env)
+{
+  int r;
+  Node *node, **headp;
+
+  *top = NULL;
+  r = parse_exp(&node, tok, term, src, end, env);
+  if (r < 0) {
+    onig_node_free(node);
+    return r;
+  }
+
+  if (r == TK_EOT || r == term || r == TK_ALT) {
+    *top = node;
+  }
+  else {
+    *top  = node_new_list(node, NULL);
+    headp = &(NCDR(*top));
+    while (r != TK_EOT && r != term && r != TK_ALT) {
+      r = parse_exp(&node, tok, term, src, end, env);
+      if (r < 0) {
+	onig_node_free(node);
+	return r;
+      }
+
+      if (NTYPE(node) == NT_LIST) {
+	*headp = node;
+	while (IS_NOT_NULL(NCDR(node))) node = NCDR(node);
+	headp = &(NCDR(node));
+      }
+      else {
+	*headp = node_new_list(node, NULL);
+	headp = &(NCDR(*headp));
+      }
+    }
+  }
+
+  return r;
+}
+
+/* term_tok: TK_EOT or TK_SUBEXP_CLOSE */
+static int
+parse_subexp(Node** top, OnigToken* tok, int term,
+	     UChar** src, UChar* end, ScanEnv* env)
+{
+  int r;
+  Node *node, **headp;
+
+  *top = NULL;
+  env->parse_depth++;
+  if (env->parse_depth > ParseDepthLimit)
+    return ONIGERR_PARSE_DEPTH_LIMIT_OVER;
+  r = parse_branch(&node, tok, term, src, end, env);
+  if (r < 0) {
+    onig_node_free(node);
+    return r;
+  }
+
+  if (r == term) {
+    *top = node;
+  }
+  else if (r == TK_ALT) {
+    *top  = onig_node_new_alt(node, NULL);
+    headp = &(NCDR(*top));
+    while (r == TK_ALT) {
+      r = fetch_token(tok, src, end, env);
+      if (r < 0) return r;
+      r = parse_branch(&node, tok, term, src, end, env);
+      if (r < 0) {
+	onig_node_free(node);
+	return r;
+      }
+
+      *headp = onig_node_new_alt(node, NULL);
+      headp = &(NCDR(*headp));
+    }
+
+    if (tok->type != (enum TokenSyms )term)
+      goto err;
+  }
+  else {
+    onig_node_free(node);
+  err:
+    if (term == TK_SUBEXP_CLOSE)
+      return ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS;
+    else
+      return ONIGERR_PARSER_BUG;
+  }
+
+  env->parse_depth--;
+  return r;
+}
+
+static int
+parse_regexp(Node** top, UChar** src, UChar* end, ScanEnv* env)
+{
+  int r;
+  OnigToken tok;
+
+  r = fetch_token(&tok, src, end, env);
+  if (r < 0) return r;
+  r = parse_subexp(top, &tok, TK_EOT, src, end, env);
+  if (r < 0) return r;
+
+#ifdef USE_SUBEXP_CALL
+  if (env->num_call > 0) {
+    /* Capture the pattern itself. It is used for (?R), (?0) and \g<0>. */
+    const int num = 0;
+    Node* np;
+    np = node_new_enclose_memory(env->option, 0);
+    CHECK_NULL_RETURN_MEMERR(np);
+    NENCLOSE(np)->regnum = num;
+    NENCLOSE(np)->target = *top;
+    r = scan_env_set_mem_node(env, num, np);
+    if (r != 0) {
+	onig_node_free(np);
+	return r;
+    }
+    *top = np;
+  }
+#endif
+  return 0;
+}
+
+extern int
+onig_parse_make_tree(Node** root, const UChar* pattern, const UChar* end,
+		     regex_t* reg, ScanEnv* env)
+{
+  int r;
+  UChar* p;
+
+#ifdef USE_NAMED_GROUP
+  names_clear(reg);
+#endif
+
+  scan_env_clear(env);
+  env->option         = reg->options;
+  env->case_fold_flag = reg->case_fold_flag;
+  env->enc            = reg->enc;
+  env->syntax         = reg->syntax;
+  env->pattern        = (UChar* )pattern;
+  env->pattern_end    = (UChar* )end;
+  env->reg            = reg;
+
+  *root = NULL;
+  p = (UChar* )pattern;
+  r = parse_regexp(root, &p, (UChar* )end, env);
+  reg->num_mem = env->num_mem;
+  return r;
+}
+
+extern void
+onig_scan_env_set_error_string(ScanEnv* env, int ecode ARG_UNUSED,
+				UChar* arg, UChar* arg_end)
+{
+  env->error     = arg;
+  env->error_end = arg_end;
+}
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/regparse.h
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/regparse.h	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/regparse.h	(revision 331)
@@ -0,0 +1,370 @@
+#ifndef ONIGMO_REGPARSE_H
+#define ONIGMO_REGPARSE_H
+/**********************************************************************
+  regparse.h -  Onigmo (Oniguruma-mod) (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2007  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011-2016  K.Takata  <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "regint.h"
+
+RUBY_SYMBOL_EXPORT_BEGIN
+
+/* node type */
+#define NT_STR         0
+#define NT_CCLASS      1
+#define NT_CTYPE       2
+#define NT_CANY        3
+#define NT_BREF        4
+#define NT_QTFR        5
+#define NT_ENCLOSE     6
+#define NT_ANCHOR      7
+#define NT_LIST        8
+#define NT_ALT         9
+#define NT_CALL       10
+
+/* node type bit */
+#define NTYPE2BIT(type)      (1<<(type))
+
+#define BIT_NT_STR        NTYPE2BIT(NT_STR)
+#define BIT_NT_CCLASS     NTYPE2BIT(NT_CCLASS)
+#define BIT_NT_CTYPE      NTYPE2BIT(NT_CTYPE)
+#define BIT_NT_CANY       NTYPE2BIT(NT_CANY)
+#define BIT_NT_BREF       NTYPE2BIT(NT_BREF)
+#define BIT_NT_QTFR       NTYPE2BIT(NT_QTFR)
+#define BIT_NT_ENCLOSE    NTYPE2BIT(NT_ENCLOSE)
+#define BIT_NT_ANCHOR     NTYPE2BIT(NT_ANCHOR)
+#define BIT_NT_LIST       NTYPE2BIT(NT_LIST)
+#define BIT_NT_ALT        NTYPE2BIT(NT_ALT)
+#define BIT_NT_CALL       NTYPE2BIT(NT_CALL)
+
+#define IS_NODE_TYPE_SIMPLE(type) \
+  ((NTYPE2BIT(type) & (BIT_NT_STR | BIT_NT_CCLASS | BIT_NT_CTYPE |\
+                       BIT_NT_CANY | BIT_NT_BREF)) != 0)
+
+#define NTYPE(node)             ((node)->u.base.type)
+#define SET_NTYPE(node, ntype) \
+    do { \
+	int value = ntype; \
+	memcpy(&((node)->u.base.type), &value, sizeof(int)); \
+    } while (0)
+
+#define NSTR(node)         (&((node)->u.str))
+#define NCCLASS(node)      (&((node)->u.cclass))
+#define NCTYPE(node)       (&((node)->u.ctype))
+#define NBREF(node)        (&((node)->u.bref))
+#define NQTFR(node)        (&((node)->u.qtfr))
+#define NENCLOSE(node)     (&((node)->u.enclose))
+#define NANCHOR(node)      (&((node)->u.anchor))
+#define NCONS(node)        (&((node)->u.cons))
+#define NCALL(node)        (&((node)->u.call))
+
+#define NCAR(node)         (NCONS(node)->car)
+#define NCDR(node)         (NCONS(node)->cdr)
+
+
+
+#define ANCHOR_ANYCHAR_STAR_MASK (ANCHOR_ANYCHAR_STAR | ANCHOR_ANYCHAR_STAR_ML)
+#define ANCHOR_END_BUF_MASK      (ANCHOR_END_BUF | ANCHOR_SEMI_END_BUF)
+
+#define ENCLOSE_MEMORY           (1<<0)
+#define ENCLOSE_OPTION           (1<<1)
+#define ENCLOSE_STOP_BACKTRACK   (1<<2)
+#define ENCLOSE_CONDITION        (1<<3)
+#define ENCLOSE_ABSENT           (1<<4)
+
+#define NODE_STR_MARGIN         16
+#define NODE_STR_BUF_SIZE       24  /* sizeof(CClassNode) - sizeof(int)*4 */
+#define NODE_BACKREFS_SIZE       6
+
+#define NSTR_RAW                (1<<0) /* by backslashed number */
+#define NSTR_AMBIG              (1<<1)
+#define NSTR_DONT_GET_OPT_INFO  (1<<2)
+
+#define NSTRING_LEN(node) (OnigDistance )((node)->u.str.end - (node)->u.str.s)
+#define NSTRING_SET_RAW(node)          (node)->u.str.flag |= NSTR_RAW
+#define NSTRING_CLEAR_RAW(node)        (node)->u.str.flag &= ~NSTR_RAW
+#define NSTRING_SET_AMBIG(node)        (node)->u.str.flag |= NSTR_AMBIG
+#define NSTRING_SET_DONT_GET_OPT_INFO(node) \
+  (node)->u.str.flag |= NSTR_DONT_GET_OPT_INFO
+#define NSTRING_IS_RAW(node)          (((node)->u.str.flag & NSTR_RAW)   != 0)
+#define NSTRING_IS_AMBIG(node)        (((node)->u.str.flag & NSTR_AMBIG) != 0)
+#define NSTRING_IS_DONT_GET_OPT_INFO(node) \
+  (((node)->u.str.flag & NSTR_DONT_GET_OPT_INFO) != 0)
+
+#define BACKREFS_P(br) \
+  (IS_NOT_NULL((br)->back_dynamic) ? (br)->back_dynamic : (br)->back_static);
+
+#define NQ_TARGET_ISNOT_EMPTY     0
+#define NQ_TARGET_IS_EMPTY        1
+#define NQ_TARGET_IS_EMPTY_MEM    2
+#define NQ_TARGET_IS_EMPTY_REC    3
+
+/* status bits */
+#define NST_MIN_FIXED             (1<<0)
+#define NST_MAX_FIXED             (1<<1)
+#define NST_CLEN_FIXED            (1<<2)
+#define NST_MARK1                 (1<<3)
+#define NST_MARK2                 (1<<4)
+#define NST_MEM_BACKREFED         (1<<5)
+#define NST_STOP_BT_SIMPLE_REPEAT (1<<6)
+#define NST_RECURSION             (1<<7)
+#define NST_CALLED                (1<<8)
+#define NST_ADDR_FIXED            (1<<9)
+#define NST_NAMED_GROUP           (1<<10)
+#define NST_NAME_REF              (1<<11)
+#define NST_IN_REPEAT             (1<<12) /* STK_REPEAT is nested in stack. */
+#define NST_NEST_LEVEL            (1<<13)
+#define NST_BY_NUMBER             (1<<14) /* {n,m} */
+
+#define SET_ENCLOSE_STATUS(node,f)      (node)->u.enclose.state |=  (f)
+#define CLEAR_ENCLOSE_STATUS(node,f)    (node)->u.enclose.state &= ~(f)
+
+#define IS_ENCLOSE_CALLED(en)          (((en)->state & NST_CALLED)        != 0)
+#define IS_ENCLOSE_ADDR_FIXED(en)      (((en)->state & NST_ADDR_FIXED)    != 0)
+#define IS_ENCLOSE_RECURSION(en)       (((en)->state & NST_RECURSION)     != 0)
+#define IS_ENCLOSE_MARK1(en)           (((en)->state & NST_MARK1)         != 0)
+#define IS_ENCLOSE_MARK2(en)           (((en)->state & NST_MARK2)         != 0)
+#define IS_ENCLOSE_MIN_FIXED(en)       (((en)->state & NST_MIN_FIXED)     != 0)
+#define IS_ENCLOSE_MAX_FIXED(en)       (((en)->state & NST_MAX_FIXED)     != 0)
+#define IS_ENCLOSE_CLEN_FIXED(en)      (((en)->state & NST_CLEN_FIXED)    != 0)
+#define IS_ENCLOSE_STOP_BT_SIMPLE_REPEAT(en) \
+    (((en)->state & NST_STOP_BT_SIMPLE_REPEAT) != 0)
+#define IS_ENCLOSE_NAMED_GROUP(en)     (((en)->state & NST_NAMED_GROUP)   != 0)
+#define IS_ENCLOSE_NAME_REF(en)        (((en)->state & NST_NAME_REF)      != 0)
+
+#define SET_CALL_RECURSION(node)       (node)->u.call.state |= NST_RECURSION
+#define IS_CALL_RECURSION(cn)          (((cn)->state & NST_RECURSION)  != 0)
+#define IS_CALL_NAME_REF(cn)           (((cn)->state & NST_NAME_REF)   != 0)
+#define IS_BACKREF_NAME_REF(bn)        (((bn)->state & NST_NAME_REF)   != 0)
+#define IS_BACKREF_NEST_LEVEL(bn)      (((bn)->state & NST_NEST_LEVEL) != 0)
+#define IS_QUANTIFIER_IN_REPEAT(qn)    (((qn)->state & NST_IN_REPEAT)  != 0)
+#define IS_QUANTIFIER_BY_NUMBER(qn)    (((qn)->state & NST_BY_NUMBER)  != 0)
+
+#define CALLNODE_REFNUM_UNDEF  -1
+
+typedef struct {
+  NodeBase base;
+  UChar* s;
+  UChar* end;
+  unsigned int flag;
+  int    capa;    /* (allocated size - 1) or 0: use buf[] */
+  UChar  buf[NODE_STR_BUF_SIZE];
+} StrNode;
+
+typedef struct {
+  NodeBase base;
+  int state;
+  struct _Node* target;
+  int lower;
+  int upper;
+  int greedy;
+  int target_empty_info;
+  struct _Node* head_exact;
+  struct _Node* next_head_exact;
+  int is_refered;     /* include called node. don't eliminate even if {0} */
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+  int comb_exp_check_num;  /* 1,2,3...: check,  0: no check  */
+#endif
+} QtfrNode;
+
+typedef struct {
+  NodeBase base;
+  int state;
+  int type;
+  int regnum;
+  OnigOptionType option;
+  AbsAddrType    call_addr;
+  struct _Node*  target;
+  /* for multiple call reference */
+  OnigDistance min_len; /* min length (byte) */
+  OnigDistance max_len; /* max length (byte) */
+  int char_len;         /* character length  */
+  int opt_count;        /* referenced count in optimize_node_left() */
+} EncloseNode;
+
+#ifdef USE_SUBEXP_CALL
+
+typedef struct {
+  int           offset;
+  struct _Node* target;
+} UnsetAddr;
+
+typedef struct {
+  int        num;
+  int        alloc;
+  UnsetAddr* us;
+} UnsetAddrList;
+
+typedef struct {
+  NodeBase base;
+  int     state;
+  int     group_num;
+  UChar*  name;
+  UChar*  name_end;
+  struct _Node*  target;  /* EncloseNode : ENCLOSE_MEMORY */
+  UnsetAddrList* unset_addr_list;
+} CallNode;
+
+#endif
+
+typedef struct {
+  NodeBase base;
+  int  state;
+  int  back_num;
+  int  back_static[NODE_BACKREFS_SIZE];
+  int* back_dynamic;
+  int  nest_level;
+} BRefNode;
+
+typedef struct {
+  NodeBase base;
+  int type;
+  struct _Node* target;
+  int char_len;
+  int ascii_range;
+} AnchorNode;
+
+typedef struct {
+  NodeBase base;
+  struct _Node* car;
+  struct _Node* cdr;
+} ConsAltNode;
+
+typedef struct {
+  NodeBase base;
+  int ctype;
+  int not;
+  int ascii_range;
+} CtypeNode;
+
+typedef struct _Node {
+  union {
+    NodeBase     base;
+    StrNode      str;
+    CClassNode   cclass;
+    QtfrNode     qtfr;
+    EncloseNode  enclose;
+    BRefNode     bref;
+    AnchorNode   anchor;
+    ConsAltNode  cons;
+    CtypeNode    ctype;
+#ifdef USE_SUBEXP_CALL
+    CallNode     call;
+#endif
+  } u;
+} Node;
+
+
+#define NULL_NODE  ((Node* )0)
+
+#define SCANENV_MEMNODES_SIZE               8
+#define SCANENV_MEM_NODES(senv)   \
+ (IS_NOT_NULL((senv)->mem_nodes_dynamic) ? \
+    (senv)->mem_nodes_dynamic : (senv)->mem_nodes_static)
+
+typedef struct {
+  OnigOptionType   option;
+  OnigCaseFoldType case_fold_flag;
+  OnigEncoding     enc;
+  const OnigSyntaxType* syntax;
+  BitStatusType    capture_history;
+  BitStatusType    bt_mem_start;
+  BitStatusType    bt_mem_end;
+  BitStatusType    backrefed_mem;
+  UChar*           pattern;
+  UChar*           pattern_end;
+  UChar*           error;
+  UChar*           error_end;
+  regex_t*         reg;       /* for reg->names only */
+#ifdef USE_SUBEXP_CALL
+  UnsetAddrList*   unset_addr_list;
+#endif
+  int              num_call;
+  int              num_mem;
+#ifdef USE_NAMED_GROUP
+  int              num_named;
+#endif
+  int              mem_alloc;
+  Node*            mem_nodes_static[SCANENV_MEMNODES_SIZE];
+  Node**           mem_nodes_dynamic;
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+  int num_comb_exp_check;
+  int comb_exp_max_regnum;
+  int curr_max_regnum;
+  int has_recursion;
+#endif
+  unsigned int parse_depth;
+  int warnings_flag;
+#ifdef RUBY
+  const char* sourcefile;
+  int sourceline;
+#endif
+} ScanEnv;
+
+
+#define IS_SYNTAX_OP(syn, opm)    (((syn)->op  & (opm)) != 0)
+#define IS_SYNTAX_OP2(syn, opm)   (((syn)->op2 & (opm)) != 0)
+#define IS_SYNTAX_BV(syn, bvm)    (((syn)->behavior & (bvm)) != 0)
+
+#ifdef USE_NAMED_GROUP
+typedef struct {
+  int new_val;
+} GroupNumRemap;
+
+extern int    onig_renumber_name_table(regex_t* reg, GroupNumRemap* map);
+#endif
+
+extern int    onig_strncmp(const UChar* s1, const UChar* s2, int n);
+extern void   onig_strcpy(UChar* dest, const UChar* src, const UChar* end);
+extern void   onig_scan_env_set_error_string(ScanEnv* env, int ecode, UChar* arg, UChar* arg_end);
+extern int    onig_scan_unsigned_number(UChar** src, const UChar* end, OnigEncoding enc);
+extern void   onig_reduce_nested_quantifier(Node* pnode, Node* cnode);
+extern void   onig_node_conv_to_str_node(Node* node, int raw);
+extern int    onig_node_str_cat(Node* node, const UChar* s, const UChar* end);
+extern int    onig_node_str_set(Node* node, const UChar* s, const UChar* end);
+extern void   onig_node_free(Node* node);
+extern Node*  onig_node_new_enclose(int type);
+extern Node*  onig_node_new_anchor(int type);
+extern Node*  onig_node_new_str(const UChar* s, const UChar* end);
+extern Node*  onig_node_new_list(Node* left, Node* right);
+extern Node*  onig_node_list_add(Node* list, Node* x);
+extern Node*  onig_node_new_alt(Node* left, Node* right);
+extern void   onig_node_str_clear(Node* node);
+extern int    onig_names_free(regex_t* reg);
+extern int    onig_parse_make_tree(Node** root, const UChar* pattern, const UChar* end, regex_t* reg, ScanEnv* env);
+extern int    onig_free_shared_cclass_table(void);
+
+#ifdef ONIG_DEBUG
+# ifdef USE_NAMED_GROUP
+extern int onig_print_names(FILE*, regex_t*);
+# endif
+#endif
+
+RUBY_SYMBOL_EXPORT_END
+
+#endif /* ONIGMO_REGPARSE_H */
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/regposerr.c
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/regposerr.c	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/regposerr.c	(revision 331)
@@ -0,0 +1,103 @@
+/**********************************************************************
+  regposerr.c - Onigmo (Oniguruma-mod) (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2007  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011-2016  K.Takata  <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "onigmoposix.h"
+#include <string.h>
+
+#if defined(__GNUC__)
+# define ARG_UNUSED  __attribute__ ((unused))
+#else
+# define ARG_UNUSED
+#endif
+
+#if defined(_WIN32) && !defined(__GNUC__)
+# define xsnprintf   sprintf_s
+# define xstrncpy(dest,src,size)   strncpy_s(dest,size,src,_TRUNCATE)
+#else
+# define xsnprintf   snprintf
+# define xstrncpy    strncpy
+#endif
+
+#define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
+
+static const char* ESTRING[] = {
+  NULL,
+  "failed to match",                         /* REG_NOMATCH    */
+  "Invalid regular expression",              /* REG_BADPAT     */
+  "invalid collating element referenced",    /* REG_ECOLLATE   */
+  "invalid character class type referenced", /* REG_ECTYPE     */
+  "bad backslash-escape sequence",           /* REG_EESCAPE    */
+  "invalid back reference number",           /* REG_ESUBREG    */
+  "imbalanced [ and ]",                      /* REG_EBRACK     */
+  "imbalanced ( and )",                      /* REG_EPAREN     */
+  "imbalanced { and }",                      /* REG_EBRACE     */
+  "invalid repeat range {n,m}",              /* REG_BADBR      */
+  "invalid range",                           /* REG_ERANGE     */
+  "Out of memory",                           /* REG_ESPACE     */
+  "? * + not preceded by valid regular expression", /* REG_BADRPT   */
+
+  /* Extended errors */
+  "internal error",                          /* REG_EONIG_INTERNAL */
+  "invalid wide char value",                 /* REG_EONIG_BADWC    */
+  "invalid argument",                        /* REG_EONIG_BADARG   */
+};
+
+#include <stdio.h>
+
+
+extern size_t
+regerror(int posix_ecode, const regex_t* reg ARG_UNUSED, char* buf,
+	 size_t size)
+{
+  const char* s;
+  char tbuf[35];
+  size_t len;
+
+  if (posix_ecode > 0
+      && posix_ecode < numberof(ESTRING)) {
+    s = ESTRING[posix_ecode];
+  }
+  else if (posix_ecode == 0) {
+    s = "";
+  }
+  else {
+    xsnprintf(tbuf, sizeof(tbuf), "undefined error code (%d)", posix_ecode);
+    s = tbuf;
+  }
+
+  len = strlen(s) + 1; /* use strlen() because s is ascii encoding. */
+
+  if (buf != NULL && size > 0) {
+    xstrncpy(buf, s, size - 1);
+    buf[size - 1] = '\0';
+  }
+  return len;
+}
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/regposix.c
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/regposix.c	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/regposix.c	(revision 331)
@@ -0,0 +1,299 @@
+/**********************************************************************
+  regposix.c - Onigmo (Oniguruma-mod) (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2008  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011-2016  K.Takata  <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define regex_t   onig_regex_t
+#include "regint.h"
+#undef regex_t
+#include "onigmoposix.h"
+
+#define ONIG_C(reg)    ((onig_regex_t* )((reg)->onig))
+#define PONIG_C(reg)   ((onig_regex_t** )(&(reg)->onig))
+
+/* #define ENC_STRING_LEN(enc,s,len)    len = strlen(s) */
+#define ENC_STRING_LEN(enc,s,len) do { \
+  if (ONIGENC_MBC_MINLEN(enc) == 1) { \
+    UChar* tmps = (UChar* )(s); \
+    while (*tmps != 0) tmps++; \
+    len = (int )(tmps - (UChar* )(s)); \
+  } \
+  else { \
+    len = onigenc_str_bytelen_null(enc, (UChar* )s); \
+  } \
+} while(0)
+
+typedef struct {
+  int onig_err;
+  int posix_err;
+} O2PERR;
+
+static int
+onig2posix_error_code(int code)
+{
+  static const O2PERR o2p[] = {
+    { ONIG_MISMATCH,                                      REG_NOMATCH },
+    { ONIG_NO_SUPPORT_CONFIG,                             REG_EONIG_INTERNAL },
+    { ONIGERR_MEMORY,                                     REG_ESPACE  },
+    { ONIGERR_MATCH_STACK_LIMIT_OVER,                     REG_EONIG_INTERNAL },
+    { ONIGERR_TYPE_BUG,                                   REG_EONIG_INTERNAL },
+    { ONIGERR_PARSER_BUG,                                 REG_EONIG_INTERNAL },
+    { ONIGERR_STACK_BUG,                                  REG_EONIG_INTERNAL },
+    { ONIGERR_UNDEFINED_BYTECODE,                         REG_EONIG_INTERNAL },
+    { ONIGERR_UNEXPECTED_BYTECODE,                        REG_EONIG_INTERNAL },
+    { ONIGERR_DEFAULT_ENCODING_IS_NOT_SET,                REG_EONIG_BADARG },
+    { ONIGERR_SPECIFIED_ENCODING_CANT_CONVERT_TO_WIDE_CHAR, REG_EONIG_BADARG },
+    { ONIGERR_INVALID_ARGUMENT,                           REG_EONIG_BADARG },
+    { ONIGERR_END_PATTERN_AT_LEFT_BRACE,                  REG_EBRACE  },
+    { ONIGERR_END_PATTERN_AT_LEFT_BRACKET,                REG_EBRACK  },
+    { ONIGERR_EMPTY_CHAR_CLASS,                           REG_ECTYPE  },
+    { ONIGERR_PREMATURE_END_OF_CHAR_CLASS,                REG_ECTYPE  },
+    { ONIGERR_END_PATTERN_AT_ESCAPE,                      REG_EESCAPE },
+    { ONIGERR_END_PATTERN_AT_META,                        REG_EESCAPE },
+    { ONIGERR_END_PATTERN_AT_CONTROL,                     REG_EESCAPE },
+    { ONIGERR_META_CODE_SYNTAX,                           REG_BADPAT  },
+    { ONIGERR_CONTROL_CODE_SYNTAX,                        REG_BADPAT  },
+    { ONIGERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE,           REG_ECTYPE  },
+    { ONIGERR_CHAR_CLASS_VALUE_AT_START_OF_RANGE,         REG_ECTYPE  },
+    { ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS,    REG_ECTYPE  },
+    { ONIGERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED,    REG_BADRPT  },
+    { ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID,          REG_BADRPT  },
+    { ONIGERR_NESTED_REPEAT_OPERATOR,                     REG_BADRPT  },
+    { ONIGERR_UNMATCHED_CLOSE_PARENTHESIS,                REG_EPAREN  },
+    { ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS,     REG_EPAREN  },
+    { ONIGERR_END_PATTERN_IN_GROUP,                       REG_BADPAT  },
+    { ONIGERR_UNDEFINED_GROUP_OPTION,                     REG_BADPAT  },
+    { ONIGERR_INVALID_POSIX_BRACKET_TYPE,                 REG_BADPAT  },
+    { ONIGERR_INVALID_LOOK_BEHIND_PATTERN,                REG_BADPAT  },
+    { ONIGERR_INVALID_REPEAT_RANGE_PATTERN,               REG_BADPAT  },
+    { ONIGERR_TOO_BIG_NUMBER,                             REG_BADPAT  },
+    { ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE,            REG_BADBR   },
+    { ONIGERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE,   REG_BADBR   },
+    { ONIGERR_EMPTY_RANGE_IN_CHAR_CLASS,                  REG_ECTYPE  },
+    { ONIGERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE,        REG_ECTYPE  },
+    { ONIGERR_TOO_MANY_MULTI_BYTE_RANGES,                 REG_ECTYPE  },
+    { ONIGERR_TOO_SHORT_MULTI_BYTE_STRING,                REG_BADPAT  },
+    { ONIGERR_TOO_BIG_BACKREF_NUMBER,                     REG_ESUBREG },
+    { ONIGERR_INVALID_BACKREF,                            REG_ESUBREG },
+    { ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED,       REG_BADPAT  },
+    { ONIGERR_TOO_BIG_WIDE_CHAR_VALUE,                    REG_EONIG_BADWC },
+    { ONIGERR_TOO_LONG_WIDE_CHAR_VALUE,                   REG_EONIG_BADWC },
+    { ONIGERR_INVALID_CODE_POINT_VALUE,                   REG_EONIG_BADWC },
+    { ONIGERR_EMPTY_GROUP_NAME,                           REG_BADPAT },
+    { ONIGERR_INVALID_GROUP_NAME,                         REG_BADPAT },
+    { ONIGERR_INVALID_CHAR_IN_GROUP_NAME,                 REG_BADPAT },
+    { ONIGERR_UNDEFINED_NAME_REFERENCE,                   REG_BADPAT },
+    { ONIGERR_UNDEFINED_GROUP_REFERENCE,                  REG_BADPAT },
+    { ONIGERR_MULTIPLEX_DEFINED_NAME,                     REG_BADPAT },
+    { ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL,             REG_BADPAT },
+    { ONIGERR_NEVER_ENDING_RECURSION,                     REG_BADPAT },
+    { ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY,      REG_BADPAT },
+    { ONIGERR_INVALID_CHAR_PROPERTY_NAME,                 REG_BADPAT },
+    { ONIGERR_NOT_SUPPORTED_ENCODING_COMBINATION,         REG_EONIG_BADARG },
+
+  };
+
+  int i;
+
+  if (code >= 0) return 0;
+
+  for (i = 0; i < numberof(o2p); i++) {
+    if (code == o2p[i].onig_err)
+      return o2p[i].posix_err;
+  }
+
+  return REG_EONIG_INTERNAL;  /* but, unknown error code */
+}
+
+extern int
+regcomp(regex_t* reg, const char* pattern, int posix_options)
+{
+  int r, len;
+  const OnigSyntaxType* syntax = OnigDefaultSyntax;
+  OnigOptionType options;
+
+  if ((posix_options & REG_EXTENDED) == 0)
+    syntax = ONIG_SYNTAX_POSIX_BASIC;
+
+  options = syntax->options;
+  if ((posix_options & REG_ICASE)   != 0)
+    ONIG_OPTION_ON(options, ONIG_OPTION_IGNORECASE);
+  if ((posix_options & REG_NEWLINE) != 0) {
+    ONIG_OPTION_ON( options, ONIG_OPTION_NEGATE_SINGLELINE);
+    ONIG_OPTION_OFF(options, ONIG_OPTION_SINGLELINE);
+  }
+
+  reg->comp_options = posix_options;
+
+  ENC_STRING_LEN(OnigEncDefaultCharEncoding, pattern, len);
+  r = onig_new(PONIG_C(reg), (UChar* )pattern, (UChar* )(pattern + len),
+	       options, OnigEncDefaultCharEncoding, syntax,
+	       (OnigErrorInfo* )NULL);
+  if (r != ONIG_NORMAL) {
+    return onig2posix_error_code(r);
+  }
+
+  reg->re_nsub = ONIG_C(reg)->num_mem;
+  return 0;
+}
+
+extern int
+regexec(regex_t* reg, const char* str, size_t nmatch,
+	regmatch_t pmatch[], int posix_options)
+{
+  int r, i, len;
+  UChar* end;
+  OnigRegion* region = NULL;
+  OnigOptionType options;
+
+  options = ONIG_OPTION_NONE;
+  if ((posix_options & REG_NOTBOL) != 0) options |= ONIG_OPTION_NOTBOL;
+  if ((posix_options & REG_NOTEOL) != 0) options |= ONIG_OPTION_NOTEOL;
+
+  if ((reg->comp_options & REG_NOSUB) != 0) {
+    nmatch = 0;
+  }
+  else if (nmatch != 0) {
+    region = onig_region_new();
+    if (region == NULL)
+      return REG_ESPACE;
+  }
+
+  ENC_STRING_LEN(ONIG_C(reg)->enc, str, len);
+  end = (UChar* )(str + len);
+  r = (int )onig_search(ONIG_C(reg), (UChar* )str, end, (UChar* )str, end,
+		  region, options);
+
+  if (r >= 0) {
+    r = 0; /* Match */
+    for (i = 0; i < (int )nmatch; i++) {
+      pmatch[i].rm_so = (regoff_t )region->beg[i];
+      pmatch[i].rm_eo = (regoff_t )region->end[i];
+    }
+  }
+  else if (r == ONIG_MISMATCH) {
+    r = REG_NOMATCH;
+    for (i = 0; i < (int )nmatch; i++)
+      pmatch[i].rm_so = pmatch[i].rm_eo = ONIG_REGION_NOTPOS;
+  }
+  else {
+    r = onig2posix_error_code(r);
+  }
+
+  if (region != NULL)
+    onig_region_free(region, 1);
+
+#if 0
+  if (reg->re_nsub > nmatch - 1)
+    reg->re_nsub = (nmatch <= 1 ? 0 : nmatch - 1);
+#endif
+
+  return r;
+}
+
+extern void
+regfree(regex_t* reg)
+{
+  onig_free(ONIG_C(reg));
+}
+
+
+extern void
+reg_set_encoding(int mb_code)
+{
+  OnigEncoding enc;
+
+  switch (mb_code) {
+  case REG_POSIX_ENCODING_ASCII:
+    enc = ONIG_ENCODING_ASCII;
+    break;
+  case REG_POSIX_ENCODING_EUC_JP:
+    enc = ONIG_ENCODING_EUC_JP;
+    break;
+  case REG_POSIX_ENCODING_SJIS:
+    enc = ONIG_ENCODING_SJIS;
+    break;
+  case REG_POSIX_ENCODING_UTF8:
+    enc = ONIG_ENCODING_UTF8;
+    break;
+  case REG_POSIX_ENCODING_UTF16_BE:
+    enc = ONIG_ENCODING_UTF16_BE;
+    break;
+  case REG_POSIX_ENCODING_UTF16_LE:
+    enc = ONIG_ENCODING_UTF16_LE;
+    break;
+
+  default:
+    return ;
+    break;
+  }
+
+  onigenc_set_default_encoding(enc);
+}
+
+extern int
+reg_name_to_group_numbers(regex_t* reg,
+  const unsigned char* name, const unsigned char* name_end, int** nums)
+{
+  return onig_name_to_group_numbers(ONIG_C(reg), name, name_end, nums);
+}
+
+typedef struct {
+  int (*func)(const unsigned char*, const unsigned char*,int,int*,regex_t*,void*);
+  regex_t* reg;
+  void* arg;
+} i_wrap;
+
+static int
+i_wrapper(const UChar* name, const UChar* name_end, int ng, int* gs,
+	  onig_regex_t* reg ARG_UNUSED, void* arg)
+{
+  i_wrap* warg = (i_wrap* )arg;
+
+  return (*warg->func)(name, name_end, ng, gs, warg->reg, warg->arg);
+}
+
+extern int
+reg_foreach_name(regex_t* reg,
+ int (*func)(const unsigned char*, const unsigned char*,int,int*,regex_t*,void*),
+ void* arg)
+{
+  i_wrap warg;
+
+  warg.func = func;
+  warg.reg  = reg;
+  warg.arg  = arg;
+
+  return onig_foreach_name(ONIG_C(reg), i_wrapper, &warg);
+}
+
+extern int
+reg_number_of_names(regex_t* reg)
+{
+  return onig_number_of_names(ONIG_C(reg));
+}
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/regsyntax.c
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/regsyntax.c	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/regsyntax.c	(revision 331)
@@ -0,0 +1,388 @@
+/**********************************************************************
+  regsyntax.c -  Onigmo (Oniguruma-mod) (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2006  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011-2016  K.Takata  <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "regint.h"
+
+const OnigSyntaxType OnigSyntaxASIS = {
+    0
+  , ONIG_SYN_OP2_INEFFECTIVE_ESCAPE
+  , 0
+  , ONIG_OPTION_NONE
+  ,
+  {
+      (OnigCodePoint )'\\'                       /* esc */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+  }
+};
+
+const OnigSyntaxType OnigSyntaxPosixBasic = {
+  ( SYN_POSIX_COMMON_OP | ONIG_SYN_OP_ESC_LPAREN_SUBEXP |
+    ONIG_SYN_OP_ESC_BRACE_INTERVAL )
+  , 0
+  , 0
+  , ( ONIG_OPTION_SINGLELINE | ONIG_OPTION_MULTILINE )
+  ,
+  {
+      (OnigCodePoint )'\\'                       /* esc */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+  }
+};
+
+const OnigSyntaxType OnigSyntaxPosixExtended = {
+  ( SYN_POSIX_COMMON_OP | ONIG_SYN_OP_LPAREN_SUBEXP |
+    ONIG_SYN_OP_BRACE_INTERVAL |
+    ONIG_SYN_OP_PLUS_ONE_INF | ONIG_SYN_OP_QMARK_ZERO_ONE | ONIG_SYN_OP_VBAR_ALT )
+  , 0
+  , ( ONIG_SYN_CONTEXT_INDEP_ANCHORS |
+      ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS | ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS |
+      ONIG_SYN_ALLOW_UNMATCHED_CLOSE_SUBEXP |
+      ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC )
+  , ( ONIG_OPTION_SINGLELINE | ONIG_OPTION_MULTILINE )
+  ,
+  {
+      (OnigCodePoint )'\\'                       /* esc */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+  }
+};
+
+const OnigSyntaxType OnigSyntaxEmacs = {
+  ( ONIG_SYN_OP_DOT_ANYCHAR | ONIG_SYN_OP_BRACKET_CC |
+    ONIG_SYN_OP_ESC_BRACE_INTERVAL |
+    ONIG_SYN_OP_ESC_LPAREN_SUBEXP | ONIG_SYN_OP_ESC_VBAR_ALT |
+    ONIG_SYN_OP_ASTERISK_ZERO_INF | ONIG_SYN_OP_PLUS_ONE_INF |
+    ONIG_SYN_OP_QMARK_ZERO_ONE | ONIG_SYN_OP_DECIMAL_BACKREF |
+    ONIG_SYN_OP_LINE_ANCHOR | ONIG_SYN_OP_ESC_CONTROL_CHARS )
+  , ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR
+  , ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC
+  , ONIG_OPTION_NONE
+  ,
+  {
+      (OnigCodePoint )'\\'                       /* esc */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+  }
+};
+
+const OnigSyntaxType OnigSyntaxGrep = {
+  ( ONIG_SYN_OP_DOT_ANYCHAR | ONIG_SYN_OP_BRACKET_CC | ONIG_SYN_OP_POSIX_BRACKET |
+    ONIG_SYN_OP_ESC_BRACE_INTERVAL | ONIG_SYN_OP_ESC_LPAREN_SUBEXP |
+    ONIG_SYN_OP_ESC_VBAR_ALT |
+    ONIG_SYN_OP_ASTERISK_ZERO_INF | ONIG_SYN_OP_ESC_PLUS_ONE_INF |
+    ONIG_SYN_OP_ESC_QMARK_ZERO_ONE | ONIG_SYN_OP_LINE_ANCHOR |
+    ONIG_SYN_OP_ESC_W_WORD | ONIG_SYN_OP_ESC_B_WORD_BOUND |
+    ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END | ONIG_SYN_OP_DECIMAL_BACKREF )
+  , 0
+  , ( ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC | ONIG_SYN_NOT_NEWLINE_IN_NEGATIVE_CC )
+  , ONIG_OPTION_NONE
+  ,
+  {
+      (OnigCodePoint )'\\'                       /* esc */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+  }
+};
+
+const OnigSyntaxType OnigSyntaxGnuRegex = {
+  SYN_GNU_REGEX_OP
+  , 0
+  , SYN_GNU_REGEX_BV
+  , ONIG_OPTION_NONE
+  ,
+  {
+      (OnigCodePoint )'\\'                       /* esc */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+  }
+};
+
+const OnigSyntaxType OnigSyntaxJava = {
+  (( SYN_GNU_REGEX_OP | ONIG_SYN_OP_QMARK_NON_GREEDY |
+     ONIG_SYN_OP_ESC_CONTROL_CHARS | ONIG_SYN_OP_ESC_C_CONTROL |
+     ONIG_SYN_OP_ESC_OCTAL3 | ONIG_SYN_OP_ESC_X_HEX2 )
+   & ~ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END )
+  , ( ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE | ONIG_SYN_OP2_QMARK_GROUP_EFFECT |
+      ONIG_SYN_OP2_OPTION_PERL | ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT |
+      ONIG_SYN_OP2_PLUS_POSSESSIVE_INTERVAL | ONIG_SYN_OP2_CCLASS_SET_OP |
+      ONIG_SYN_OP2_ESC_V_VTAB | ONIG_SYN_OP2_ESC_U_HEX4 |
+      ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY )
+  , ( SYN_GNU_REGEX_BV | ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND )
+  , ( ONIG_OPTION_SINGLELINE | ONIG_OPTION_ASCII_RANGE |
+      ONIG_OPTION_WORD_BOUND_ALL_RANGE )
+  ,
+  {
+      (OnigCodePoint )'\\'                       /* esc */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+  }
+};
+
+/* Perl 5.8 */
+const OnigSyntaxType OnigSyntaxPerl58 = {
+  (( SYN_GNU_REGEX_OP | ONIG_SYN_OP_QMARK_NON_GREEDY |
+     ONIG_SYN_OP_ESC_OCTAL3 | ONIG_SYN_OP_ESC_X_HEX2 |
+     ONIG_SYN_OP_ESC_X_BRACE_HEX8 | ONIG_SYN_OP_ESC_CONTROL_CHARS |
+     ONIG_SYN_OP_ESC_C_CONTROL )
+   & ~ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END )
+  , ( ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE |
+      ONIG_SYN_OP2_QMARK_GROUP_EFFECT | ONIG_SYN_OP2_OPTION_PERL |
+      ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY |
+      ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT |
+      ONIG_SYN_OP2_ESC_CAPITAL_X_EXTENDED_GRAPHEME_CLUSTER |
+      ONIG_SYN_OP2_QMARK_LPAREN_CONDITION)
+  , SYN_GNU_REGEX_BV
+  , ONIG_OPTION_SINGLELINE
+  ,
+  {
+      (OnigCodePoint )'\\'                       /* esc */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+  }
+};
+
+/* Perl 5.8 + named group */
+const OnigSyntaxType OnigSyntaxPerl58_NG = {
+  (( SYN_GNU_REGEX_OP | ONIG_SYN_OP_QMARK_NON_GREEDY |
+     ONIG_SYN_OP_ESC_OCTAL3 | ONIG_SYN_OP_ESC_X_HEX2 |
+     ONIG_SYN_OP_ESC_X_BRACE_HEX8 | ONIG_SYN_OP_ESC_CONTROL_CHARS |
+     ONIG_SYN_OP_ESC_C_CONTROL )
+   & ~ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END )
+  , ( ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE |
+      ONIG_SYN_OP2_QMARK_GROUP_EFFECT | ONIG_SYN_OP2_OPTION_PERL |
+      ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY  |
+      ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT |
+      ONIG_SYN_OP2_ESC_CAPITAL_X_EXTENDED_GRAPHEME_CLUSTER |
+      ONIG_SYN_OP2_QMARK_LPAREN_CONDITION     |
+      ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP       |
+      ONIG_SYN_OP2_ESC_K_NAMED_BACKREF        |
+      ONIG_SYN_OP2_ESC_G_SUBEXP_CALL )
+  , ( SYN_GNU_REGEX_BV |
+      ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP |
+      ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME )
+  , ONIG_OPTION_SINGLELINE
+  ,
+  {
+      (OnigCodePoint )'\\'                       /* esc */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+  }
+};
+
+/* Perl 5.10+ */
+const OnigSyntaxType OnigSyntaxPerl = {
+  (( SYN_GNU_REGEX_OP | ONIG_SYN_OP_QMARK_NON_GREEDY |
+     ONIG_SYN_OP_ESC_OCTAL3 | ONIG_SYN_OP_ESC_X_HEX2 |
+     ONIG_SYN_OP_ESC_X_BRACE_HEX8 | ONIG_SYN_OP_ESC_CONTROL_CHARS |
+     ONIG_SYN_OP_ESC_O_BRACE_OCTAL | ONIG_SYN_OP_ESC_C_CONTROL )
+   & ~ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END )
+  , ( ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE |
+      ONIG_SYN_OP2_QMARK_GROUP_EFFECT | ONIG_SYN_OP2_OPTION_PERL |
+      ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY  |
+      ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT |
+      ONIG_SYN_OP2_ESC_CAPITAL_X_EXTENDED_GRAPHEME_CLUSTER |
+      ONIG_SYN_OP2_QMARK_LPAREN_CONDITION |
+      ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT |
+      ONIG_SYN_OP2_PLUS_POSSESSIVE_INTERVAL |
+      ONIG_SYN_OP2_ESC_CAPITAL_R_LINEBREAK |
+      ONIG_SYN_OP2_ESC_CAPITAL_K_KEEP |
+      ONIG_SYN_OP2_QMARK_SUBEXP_CALL |
+      ONIG_SYN_OP2_ESC_G_BRACE_BACKREF |
+      ONIG_SYN_OP2_QMARK_CAPITAL_P_NAMED_GROUP |
+      ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP |
+      ONIG_SYN_OP2_ESC_K_NAMED_BACKREF )
+  , ( SYN_GNU_REGEX_BV |
+      ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME |
+      ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME_CALL |
+      ONIG_SYN_USE_LEFT_MOST_NAMED_GROUP )
+  , ( ONIG_OPTION_SINGLELINE | ONIG_OPTION_CAPTURE_GROUP )
+  ,
+  {
+      (OnigCodePoint )'\\'                       /* esc */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+  }
+};
+
+const OnigSyntaxType OnigSyntaxPython = {
+  (( SYN_GNU_REGEX_OP | ONIG_SYN_OP_QMARK_NON_GREEDY |
+     ONIG_SYN_OP_ESC_OCTAL3 | ONIG_SYN_OP_ESC_X_HEX2 |
+     ONIG_SYN_OP_ESC_X_BRACE_HEX8 | ONIG_SYN_OP_ESC_CONTROL_CHARS |
+     ONIG_SYN_OP_ESC_C_CONTROL )
+   & ~ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END )
+  , ( ONIG_SYN_OP2_QMARK_GROUP_EFFECT | ONIG_SYN_OP2_OPTION_PERL |
+      ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY  |
+      ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT |
+      ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT |
+      ONIG_SYN_OP2_ESC_V_VTAB |
+      ONIG_SYN_OP2_ESC_U_HEX4 |
+      ONIG_SYN_OP2_QMARK_LPAREN_CONDITION |
+      ONIG_SYN_OP2_QMARK_CAPITAL_P_NAMED_GROUP )
+  , ( SYN_GNU_REGEX_BV |
+      ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV )
+  , ( ONIG_OPTION_SINGLELINE | ONIG_OPTION_ASCII_RANGE )
+  ,
+  {
+      (OnigCodePoint )'\\'                       /* esc */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*'  */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+    , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+  }
+};
+
+
+
+extern int
+onig_set_default_syntax(const OnigSyntaxType* syntax)
+{
+  if (IS_NULL(syntax))
+    syntax = ONIG_SYNTAX_RUBY;
+
+  OnigDefaultSyntax = syntax;
+  return 0;
+}
+
+extern void
+onig_copy_syntax(OnigSyntaxType* to, const OnigSyntaxType* from)
+{
+  *to = *from;
+}
+
+extern void
+onig_set_syntax_op(OnigSyntaxType* syntax, unsigned int op)
+{
+  syntax->op = op;
+}
+
+extern void
+onig_set_syntax_op2(OnigSyntaxType* syntax, unsigned int op2)
+{
+  syntax->op2 = op2;
+}
+
+extern void
+onig_set_syntax_behavior(OnigSyntaxType* syntax, unsigned int behavior)
+{
+  syntax->behavior = behavior;
+}
+
+extern void
+onig_set_syntax_options(OnigSyntaxType* syntax, OnigOptionType options)
+{
+  syntax->options = options;
+}
+
+extern unsigned int
+onig_get_syntax_op(const OnigSyntaxType* syntax)
+{
+  return syntax->op;
+}
+
+extern unsigned int
+onig_get_syntax_op2(const OnigSyntaxType* syntax)
+{
+  return syntax->op2;
+}
+
+extern unsigned int
+onig_get_syntax_behavior(const OnigSyntaxType* syntax)
+{
+  return syntax->behavior;
+}
+
+extern OnigOptionType
+onig_get_syntax_options(const OnigSyntaxType* syntax)
+{
+  return syntax->options;
+}
+
+#ifdef USE_VARIABLE_META_CHARS
+extern int onig_set_meta_char(OnigSyntaxType* enc,
+                              unsigned int what, OnigCodePoint code)
+{
+  switch (what) {
+  case ONIG_META_CHAR_ESCAPE:
+    enc->meta_char_table.esc = code;
+    break;
+  case ONIG_META_CHAR_ANYCHAR:
+    enc->meta_char_table.anychar = code;
+    break;
+  case ONIG_META_CHAR_ANYTIME:
+    enc->meta_char_table.anytime = code;
+    break;
+  case ONIG_META_CHAR_ZERO_OR_ONE_TIME:
+    enc->meta_char_table.zero_or_one_time = code;
+    break;
+  case ONIG_META_CHAR_ONE_OR_MORE_TIME:
+    enc->meta_char_table.one_or_more_time = code;
+    break;
+  case ONIG_META_CHAR_ANYCHAR_ANYTIME:
+    enc->meta_char_table.anychar_anytime = code;
+    break;
+  default:
+    return ONIGERR_INVALID_ARGUMENT;
+    break;
+  }
+  return 0;
+}
+#endif /* USE_VARIABLE_META_CHARS */
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/regtrav.c
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/regtrav.c	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/regtrav.c	(revision 331)
@@ -0,0 +1,78 @@
+/**********************************************************************
+  regtrav.c -  Onigmo (Oniguruma-mod) (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2004  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011       K.Takata  <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "regint.h"
+
+#ifdef USE_CAPTURE_HISTORY
+
+static int
+capture_tree_traverse(OnigCaptureTreeNode* node, int at,
+              int(*callback_func)(int,OnigPosition,OnigPosition,int,int,void*),
+              int level, void* arg)
+{
+  int r, i;
+
+  if (node == (OnigCaptureTreeNode* )0)
+    return 0;
+
+  if ((at & ONIG_TRAVERSE_CALLBACK_AT_FIRST) != 0) {
+    r = (*callback_func)(node->group, node->beg, node->end,
+                         level, ONIG_TRAVERSE_CALLBACK_AT_FIRST, arg);
+    if (r != 0) return r;
+  }
+
+  for (i = 0; i < node->num_childs; i++) {
+    r = capture_tree_traverse(node->childs[i], at,
+                              callback_func, level + 1, arg);
+    if (r != 0) return r;
+  }
+
+  if ((at & ONIG_TRAVERSE_CALLBACK_AT_LAST) != 0) {
+    r = (*callback_func)(node->group, node->beg, node->end,
+                         level, ONIG_TRAVERSE_CALLBACK_AT_LAST, arg);
+    if (r != 0) return r;
+  }
+
+  return 0;
+}
+#endif /* USE_CAPTURE_HISTORY */
+
+extern int
+onig_capture_tree_traverse(OnigRegion* region, int at,
+              int(*callback_func)(int,OnigPosition,OnigPosition,int,int,void*),
+              void* arg)
+{
+#ifdef USE_CAPTURE_HISTORY
+  return capture_tree_traverse(region->history_root, at,
+                               callback_func, 0, arg);
+#else
+  return ONIG_NO_SUPPORT_CONFIG;
+#endif
+}
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/regversion.c
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/regversion.c	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/regversion.c	(revision 331)
@@ -0,0 +1,55 @@
+/**********************************************************************
+  regversion.c -  Onigmo (Oniguruma-mod) (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2002-2016  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2011-2017  K.Takata  <kentkt AT csc DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "onigmo.h"
+
+#define TOSTR_(a)	#a
+#define ONIG_VERSION_TOSTR_(a,b,c)	\
+	TOSTR_(a) "." TOSTR_(b) "." TOSTR_(c)
+#define ONIG_VERSION_STRING	\
+	ONIG_VERSION_TOSTR_(ONIGMO_VERSION_MAJOR, ONIGMO_VERSION_MINOR, ONIGMO_VERSION_TEENY)
+
+extern const char*
+onig_version(void)
+{
+  const char *s = ONIG_VERSION_STRING;
+
+  return s;
+}
+
+extern const char*
+onig_copyright(void)
+{
+  const char *s =
+    "Onigmo " ONIG_VERSION_STRING " : Copyright (C) 2002-2016 K.Kosako, "
+    "2011-2017 K.Takata";
+
+  return s;
+}
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/st.c
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/st.c	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/st.c	(revision 331)
@@ -0,0 +1,2000 @@
+/* This is a public domain general purpose hash table package
+   originally written by Peter Moore @ UCB.
+
+   The hash table data structures were redesigned and the package was
+   rewritten by Vladimir Makarov <vmakarov@redhat.com>.  */
+
+/* The original package implemented classic bucket-based hash tables
+   with entries doubly linked for an access by their insertion order.
+   To decrease pointer chasing and as a consequence to improve a data
+   locality the current implementation is based on storing entries in
+   an array and using hash tables with open addressing.  The current
+   entries are more compact in comparison with the original ones and
+   this also improves the data locality.
+
+   The hash table has two arrays called *bins* and *entries*.
+
+     bins:
+    -------
+   |       |                  entries array:
+   |-------|            --------------------------------
+   | index |           |      | entry:  |        |      |
+   |-------|           |      |         |        |      |
+   | ...   |           | ...  | hash    |  ...   | ...  |
+   |-------|           |      | key     |        |      |
+   | empty |           |      | record  |        |      |
+   |-------|            --------------------------------
+   | ...   |                   ^                  ^
+   |-------|                   |_ entries start   |_ entries bound
+   |deleted|
+    -------
+
+   o The entry array contains table entries in the same order as they
+     were inserted.
+
+     When the first entry is deleted, a variable containing index of
+     the current first entry (*entries start*) is changed.  In all
+     other cases of the deletion, we just mark the entry as deleted by
+     using a reserved hash value.
+
+     Such organization of the entry storage makes operations of the
+     table shift and the entries traversal very fast.
+
+   o The bins provide access to the entries by their keys.  The
+     key hash is mapped to a bin containing *index* of the
+     corresponding entry in the entry array.
+
+     The bin array size is always power of two, it makes mapping very
+     fast by using the corresponding lower bits of the hash.
+     Generally it is not a good idea to ignore some part of the hash.
+     But alternative approach is worse.  For example, we could use a
+     modulo operation for mapping and a prime number for the size of
+     the bin array.  Unfortunately, the modulo operation for big
+     64-bit numbers are extremely slow (it takes more than 100 cycles
+     on modern Intel CPUs).
+
+     Still other bits of the hash value are used when the mapping
+     results in a collision.  In this case we use a secondary hash
+     value which is a result of a function of the collision bin
+     index and the original hash value.  The function choice
+     guarantees that we can traverse all bins and finally find the
+     corresponding bin as after several iterations the function
+     becomes a full cycle linear congruential generator because it
+     satisfies requirements of the Hull-Dobell theorem.
+
+     When an entry is removed from the table besides marking the
+     hash in the corresponding entry described above, we also mark
+     the bin by a special value in order to find entries which had
+     a collision with the removed entries.
+
+     There are two reserved values for the bins.  One denotes an
+     empty bin, another one denotes a bin for a deleted entry.
+
+   o The length of the bin array is at least two times more than the
+     entry array length.  This keeps the table load factor healthy.
+     The trigger of rebuilding the table is always a case when we can
+     not insert an entry anymore at the entries bound.  We could
+     change the entries bound too in case of deletion but than we need
+     a special code to count bins with corresponding deleted entries
+     and reset the bin values when there are too many bins
+     corresponding deleted entries
+
+     Table rebuilding is done by creation of a new entry array and
+     bins of an appropriate size.  We also try to reuse the arrays
+     in some cases by compacting the array and removing deleted
+     entries.
+
+   o To save memory very small tables have no allocated arrays
+     bins.  We use a linear search for an access by a key.
+
+   o To save more memory we use 8-, 16-, 32- and 64- bit indexes in
+     bins depending on the current hash table size.
+
+   This implementation speeds up the Ruby hash table benchmarks in
+   average by more 40% on Intel Haswell CPU.
+
+*/
+
+#ifdef RUBY
+#include "internal.h"
+#else
+#include "regint.h"
+#include "st.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#ifdef __GNUC__
+#define PREFETCH(addr, write_p) __builtin_prefetch(addr, write_p)
+#define EXPECT(expr, val) __builtin_expect(expr, val)
+#define ATTRIBUTE_UNUSED  __attribute__((unused))
+#else
+#define PREFETCH(addr, write_p)
+#define EXPECT(expr, val) (expr)
+#define ATTRIBUTE_UNUSED
+#endif
+
+#ifdef ST_DEBUG
+#define st_assert(cond) assert(cond)
+#else
+#define st_assert(cond) ((void)(0 && (cond)))
+#endif
+
+/* The type of hashes.  */
+typedef st_index_t st_hash_t;
+
+struct st_table_entry {
+    st_hash_t hash;
+    st_data_t key;
+    st_data_t record;
+};
+
+#ifdef RUBY
+#define type_numhash st_hashtype_num
+const struct st_hash_type st_hashtype_num = {
+    st_numcmp,
+    st_numhash,
+};
+
+/* extern int strcmp(const char *, const char *); */
+static st_index_t strhash(st_data_t);
+static const struct st_hash_type type_strhash = {
+    strcmp,
+    strhash,
+};
+
+static st_index_t strcasehash(st_data_t);
+static const struct st_hash_type type_strcasehash = {
+    st_locale_insensitive_strcasecmp,
+    strcasehash,
+};
+#endif /* RUBY */
+
+/* Value used to catch uninitialized entries/bins during debugging.
+   There is a possibility for a false alarm, but its probability is
+   extremely small.  */
+#define ST_INIT_VAL 0xafafafafafafafaf
+#define ST_INIT_VAL_BYTE 0xafa
+
+#ifdef RUBY
+#undef malloc
+#undef realloc
+#undef calloc
+#undef free
+#define malloc ruby_xmalloc
+#define calloc ruby_xcalloc
+#define realloc ruby_xrealloc
+#define free ruby_xfree
+#else /* RUBY */
+#define MEMCPY(p1,p2,type,n)  memcpy((p1), (p2), sizeof(type)*(n))
+#endif /* RUBY */
+
+#define EQUAL(tab,x,y) ((x) == (y) || (*(tab)->type->compare)((x),(y)) == 0)
+#define PTR_EQUAL(tab, ptr, hash_val, key_) \
+    ((ptr)->hash == (hash_val) && EQUAL((tab), (key_), (ptr)->key))
+
+/* Features of a table.  */
+struct st_features {
+    /* Power of 2 used for number of allocated entries.  */
+    unsigned char entry_power;
+    /* Power of 2 used for number of allocated bins.  Depending on the
+       table size, the number of bins is 2-4 times more than the
+       number of entries.  */
+    unsigned char bin_power;
+    /* Enumeration of sizes of bins (8-bit, 16-bit etc).  */
+    unsigned char size_ind;
+    /* Bins are packed in words of type st_index_t.  The following is
+       a size of bins counted by words.  */
+    st_index_t bins_words;
+};
+
+/* Features of all possible size tables.  */
+#if SIZEOF_ST_INDEX_T == 8
+#define MAX_POWER2 62
+static const struct st_features features[] = {
+    {0, 1, 0, 0x0},
+    {1, 2, 0, 0x1},
+    {2, 3, 0, 0x1},
+    {3, 4, 0, 0x2},
+    {4, 5, 0, 0x4},
+    {5, 6, 0, 0x8},
+    {6, 7, 0, 0x10},
+    {7, 8, 0, 0x20},
+    {8, 9, 1, 0x80},
+    {9, 10, 1, 0x100},
+    {10, 11, 1, 0x200},
+    {11, 12, 1, 0x400},
+    {12, 13, 1, 0x800},
+    {13, 14, 1, 0x1000},
+    {14, 15, 1, 0x2000},
+    {15, 16, 1, 0x4000},
+    {16, 17, 2, 0x10000},
+    {17, 18, 2, 0x20000},
+    {18, 19, 2, 0x40000},
+    {19, 20, 2, 0x80000},
+    {20, 21, 2, 0x100000},
+    {21, 22, 2, 0x200000},
+    {22, 23, 2, 0x400000},
+    {23, 24, 2, 0x800000},
+    {24, 25, 2, 0x1000000},
+    {25, 26, 2, 0x2000000},
+    {26, 27, 2, 0x4000000},
+    {27, 28, 2, 0x8000000},
+    {28, 29, 2, 0x10000000},
+    {29, 30, 2, 0x20000000},
+    {30, 31, 2, 0x40000000},
+    {31, 32, 2, 0x80000000},
+    {32, 33, 3, 0x200000000},
+    {33, 34, 3, 0x400000000},
+    {34, 35, 3, 0x800000000},
+    {35, 36, 3, 0x1000000000},
+    {36, 37, 3, 0x2000000000},
+    {37, 38, 3, 0x4000000000},
+    {38, 39, 3, 0x8000000000},
+    {39, 40, 3, 0x10000000000},
+    {40, 41, 3, 0x20000000000},
+    {41, 42, 3, 0x40000000000},
+    {42, 43, 3, 0x80000000000},
+    {43, 44, 3, 0x100000000000},
+    {44, 45, 3, 0x200000000000},
+    {45, 46, 3, 0x400000000000},
+    {46, 47, 3, 0x800000000000},
+    {47, 48, 3, 0x1000000000000},
+    {48, 49, 3, 0x2000000000000},
+    {49, 50, 3, 0x4000000000000},
+    {50, 51, 3, 0x8000000000000},
+    {51, 52, 3, 0x10000000000000},
+    {52, 53, 3, 0x20000000000000},
+    {53, 54, 3, 0x40000000000000},
+    {54, 55, 3, 0x80000000000000},
+    {55, 56, 3, 0x100000000000000},
+    {56, 57, 3, 0x200000000000000},
+    {57, 58, 3, 0x400000000000000},
+    {58, 59, 3, 0x800000000000000},
+    {59, 60, 3, 0x1000000000000000},
+    {60, 61, 3, 0x2000000000000000},
+    {61, 62, 3, 0x4000000000000000},
+    {62, 63, 3, 0x8000000000000000},
+};
+
+#else
+#define MAX_POWER2 30
+
+static const struct st_features features[] = {
+    {0, 1, 0, 0x1},
+    {1, 2, 0, 0x1},
+    {2, 3, 0, 0x2},
+    {3, 4, 0, 0x4},
+    {4, 5, 0, 0x8},
+    {5, 6, 0, 0x10},
+    {6, 7, 0, 0x20},
+    {7, 8, 0, 0x40},
+    {8, 9, 1, 0x100},
+    {9, 10, 1, 0x200},
+    {10, 11, 1, 0x400},
+    {11, 12, 1, 0x800},
+    {12, 13, 1, 0x1000},
+    {13, 14, 1, 0x2000},
+    {14, 15, 1, 0x4000},
+    {15, 16, 1, 0x8000},
+    {16, 17, 2, 0x20000},
+    {17, 18, 2, 0x40000},
+    {18, 19, 2, 0x80000},
+    {19, 20, 2, 0x100000},
+    {20, 21, 2, 0x200000},
+    {21, 22, 2, 0x400000},
+    {22, 23, 2, 0x800000},
+    {23, 24, 2, 0x1000000},
+    {24, 25, 2, 0x2000000},
+    {25, 26, 2, 0x4000000},
+    {26, 27, 2, 0x8000000},
+    {27, 28, 2, 0x10000000},
+    {28, 29, 2, 0x20000000},
+    {29, 30, 2, 0x40000000},
+    {30, 31, 2, 0x80000000},
+};
+
+#endif
+
+/* The reserved hash value and its substitution.  */
+#define RESERVED_HASH_VAL (~(st_hash_t) 0)
+#define RESERVED_HASH_SUBSTITUTION_VAL ((st_hash_t) 0)
+
+/* Return hash value of KEY for table TAB.  */
+static inline st_hash_t
+do_hash(st_data_t key, st_table *tab)
+{
+    st_hash_t hash = (st_hash_t)(tab->type->hash)(key);
+
+    /* RESERVED_HASH_VAL is used for a deleted entry.  Map it into
+       another value.  Such mapping should be extremely rare.  */
+    return hash == RESERVED_HASH_VAL ? RESERVED_HASH_SUBSTITUTION_VAL : hash;
+}
+
+/* Power of 2 defining the minimal number of allocated entries.  */
+#define MINIMAL_POWER2 2
+
+#if MINIMAL_POWER2 < 2
+#error "MINIMAL_POWER2 should be >= 2"
+#endif
+
+/* If the power2 of the allocated `entries` is less than the following
+   value, don't allocate bins and use a linear search.  */
+#define MAX_POWER2_FOR_TABLES_WITHOUT_BINS 4
+
+/* Return smallest n >= MINIMAL_POWER2 such 2^n > SIZE.  */
+static int
+get_power2(st_index_t size)
+{
+    unsigned int n;
+
+    for (n = 0; size != 0; n++)
+        size >>= 1;
+    if (n <= MAX_POWER2)
+        return n < MINIMAL_POWER2 ? MINIMAL_POWER2 : n;
+#ifdef RUBY
+    /* Ran out of the table entries */
+    rb_raise(rb_eRuntimeError, "st_table too big");
+#endif
+    /* should raise exception */
+    return -1;
+}
+
+/* Return value of N-th bin in array BINS of table with bins size
+   index S.  */
+static inline st_index_t
+get_bin(st_index_t *bins, int s, st_index_t n)
+{
+  return (s == 0 ? ((unsigned char *) bins)[n]
+	  : s == 1 ? ((unsigned short *) bins)[n]
+	  : s == 2 ? ((unsigned int *) bins)[n]
+	  : ((st_index_t *) bins)[n]);
+}
+
+/* Set up N-th bin in array BINS of table with bins size index S to
+   value V.  */
+static inline void
+set_bin(st_index_t *bins, int s, st_index_t n, st_index_t v)
+{
+    if (s == 0) ((unsigned char *) bins)[n] = (unsigned char) v;
+    else if (s == 1) ((unsigned short *) bins)[n] = (unsigned short) v;
+    else if (s == 2) ((unsigned int *) bins)[n] = (unsigned int) v;
+    else ((st_index_t *) bins)[n] = v;
+}
+
+/* These macros define reserved values for empty table bin and table
+   bin which contains a deleted entry.  We will never use such values
+   for an entry index in bins.  */
+#define EMPTY_BIN    0
+#define DELETED_BIN  1
+/* Base of a real entry index in the bins.  */
+#define ENTRY_BASE 2
+
+/* Mark I-th bin of table TAB as empty, in other words not
+   corresponding to any entry.  */
+#define MARK_BIN_EMPTY(tab, i) (set_bin((tab)->bins, get_size_ind(tab), i, EMPTY_BIN))
+
+/* Values used for not found entry and bin with given
+   characteristics.  */
+#define UNDEFINED_ENTRY_IND (~(st_index_t) 0)
+#define UNDEFINED_BIN_IND (~(st_index_t) 0)
+
+/* Mark I-th bin of table TAB as corresponding to a deleted table
+   entry.  Update number of entries in the table and number of bins
+   corresponding to deleted entries. */
+#define MARK_BIN_DELETED(tab, i)				\
+    do {                                                        \
+        st_assert(i != UNDEFINED_BIN_IND);			\
+	st_assert(! IND_EMPTY_OR_DELETED_BIN_P(tab, i)); 	\
+        set_bin((tab)->bins, get_size_ind(tab), i, DELETED_BIN); \
+    } while (0)
+
+/* Macros to check that value B is used empty bins and bins
+   corresponding deleted entries.  */
+#define EMPTY_BIN_P(b) ((b) == EMPTY_BIN)
+#define DELETED_BIN_P(b) ((b) == DELETED_BIN)
+#define EMPTY_OR_DELETED_BIN_P(b) ((b) <= DELETED_BIN)
+
+/* Macros to check empty bins and bins corresponding to deleted
+   entries.  Bins are given by their index I in table TAB.  */
+#define IND_EMPTY_BIN_P(tab, i) (EMPTY_BIN_P(get_bin((tab)->bins, get_size_ind(tab), i)))
+#define IND_DELETED_BIN_P(tab, i) (DELETED_BIN_P(get_bin((tab)->bins, get_size_ind(tab), i)))
+#define IND_EMPTY_OR_DELETED_BIN_P(tab, i) (EMPTY_OR_DELETED_BIN_P(get_bin((tab)->bins, get_size_ind(tab), i)))
+
+/* Macros for marking and checking deleted entries given by their
+   pointer E_PTR.  */
+#define MARK_ENTRY_DELETED(e_ptr) ((e_ptr)->hash = RESERVED_HASH_VAL)
+#define DELETED_ENTRY_P(e_ptr) ((e_ptr)->hash == RESERVED_HASH_VAL)
+
+/* Return bin size index of table TAB.  */
+static inline unsigned int
+get_size_ind(const st_table *tab)
+{
+    return tab->size_ind;
+}
+
+/* Return the number of allocated bins of table TAB.  */
+static inline st_index_t
+get_bins_num(const st_table *tab)
+{
+    return ((st_index_t) 1)<<tab->bin_power;
+}
+
+/* Return mask for a bin index in table TAB.  */
+static inline st_index_t
+bins_mask(const st_table *tab)
+{
+    return get_bins_num(tab) - 1;
+}
+
+/* Return the index of table TAB bin corresponding to
+   HASH_VALUE.  */
+static inline st_index_t
+hash_bin(st_hash_t hash_value, st_table *tab)
+{
+    return hash_value & bins_mask(tab);
+}
+
+/* Return the number of allocated entries of table TAB.  */
+static inline st_index_t
+get_allocated_entries(const st_table *tab)
+{
+    return ((st_index_t) 1)<<tab->entry_power;
+}
+
+/* Return size of the allocated bins of table TAB.  */
+static inline st_index_t
+bins_size(const st_table *tab)
+{
+    return features[tab->entry_power].bins_words * sizeof (st_index_t);
+}
+
+/* Mark all bins of table TAB as empty.  */
+static void
+initialize_bins(st_table *tab)
+{
+    memset(tab->bins, 0, bins_size(tab));
+}
+
+/* Make table TAB empty.  */
+static void
+make_tab_empty(st_table *tab)
+{
+    tab->num_entries = 0;
+    tab->entries_start = tab->entries_bound = 0;
+    if (tab->bins != NULL)
+        initialize_bins(tab);
+}
+
+#ifdef ST_DEBUG
+/* Check the table T consistency.  It can be extremely slow.  So use
+   it only for debugging.  */
+static void
+st_check(st_table *tab)
+{
+    st_index_t d, e, i, n, p;
+
+    for (p = get_allocated_entries(tab), i = 0; p > 1; i++, p>>=1)
+        ;
+    p = i;
+    assert(p >= MINIMAL_POWER2);
+    assert(tab->entries_bound <= get_allocated_entries(tab)
+	   && tab->entries_start <= tab->entries_bound);
+    n = 0;
+    return;
+    if (tab->entries_bound != 0)
+        for (i = tab->entries_start; i < tab->entries_bound; i++) {
+	    assert(tab->entries[i].hash != (st_hash_t) ST_INIT_VAL
+		   && tab->entries[i].key != ST_INIT_VAL
+		   && tab->entries[i].record != ST_INIT_VAL);
+	    if (! DELETED_ENTRY_P(&tab->entries[i]))
+	        n++;
+	}
+    assert(n == tab->num_entries);
+    if (tab->bins == NULL)
+        assert(p <= MAX_POWER2_FOR_TABLES_WITHOUT_BINS);
+    else {
+        assert(p > MAX_POWER2_FOR_TABLES_WITHOUT_BINS);
+	for (n = d = i = 0; i < get_bins_num(tab); i++) {
+	    assert(get_bin(tab->bins, tab->size_ind, i) != ST_INIT_VAL);
+	    if (IND_DELETED_BIN_P(tab, i)) {
+	        d++;
+		continue;
+	    }
+	    else if (IND_EMPTY_BIN_P(tab, i))
+	        continue;
+	    n++;
+	    e = get_bin(tab->bins, tab->size_ind, i) - ENTRY_BASE;
+	    assert(tab->entries_start <= e && e < tab->entries_bound);
+	    assert(! DELETED_ENTRY_P(&tab->entries[e]));
+	    assert(tab->entries[e].hash != (st_hash_t) ST_INIT_VAL
+		   && tab->entries[e].key != ST_INIT_VAL
+		   && tab->entries[e].record != ST_INIT_VAL);
+	}
+	assert(n == tab->num_entries);
+	assert(n + d < get_bins_num(tab));
+    }
+}
+#endif
+
+#ifdef HASH_LOG
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+static struct {
+    int all, total, num, str, strcase;
+}  collision;
+
+/* Flag switching off output of package statistics at the end of
+   program.  */
+static int init_st = 0;
+
+/* Output overall number of table searches and collisions into a
+   temporary file.  */
+static void
+stat_col(void)
+{
+    char fname[10+sizeof(long)*3];
+    FILE *f;
+    if (!collision.total) return;
+    f = fopen((snprintf(fname, sizeof(fname), "/tmp/col%ld", (long)getpid()), fname), "w");
+    if (f == 0) return ;
+
+    fprintf(f, "collision: %d / %d (%6.2f)\n", collision.all, collision.total,
+            ((double)collision.all / (collision.total)) * 100);
+    fprintf(f, "num: %d, str: %d, strcase: %d\n", collision.num, collision.str, collision.strcase);
+    fclose(f);
+}
+#endif
+
+/* Create and return table with TYPE which can hold at least SIZE
+   entries.  The real number of entries which the table can hold is
+   the nearest power of two for SIZE.  */
+st_table *
+st_init_table_with_size(const struct st_hash_type *type, st_index_t size)
+{
+    st_table *tab;
+    int n;
+
+#ifdef HASH_LOG
+#if HASH_LOG+0 < 0
+    {
+        const char *e = getenv("ST_HASH_LOG");
+        if (!e || !*e) init_st = 1;
+    }
+#endif
+    if (init_st == 0) {
+        init_st = 1;
+        atexit(stat_col);
+    }
+#endif
+
+    n = get_power2(size);
+#ifndef RUBY
+    if (n < 0)
+	return NULL;
+#endif
+    tab = (st_table *) malloc(sizeof (st_table));
+    if (tab == NULL)
+	return NULL;
+    tab->type = type;
+    tab->entry_power = n;
+    tab->bin_power = features[n].bin_power;
+    tab->size_ind = features[n].size_ind;
+    if (n <= MAX_POWER2_FOR_TABLES_WITHOUT_BINS)
+        tab->bins = NULL;
+    else {
+        tab->bins = (st_index_t *) malloc(bins_size(tab));
+	if (tab->bins == NULL) {
+	    free(tab);
+	    return NULL;
+	}
+    }
+    tab->entries = (st_table_entry *) malloc(get_allocated_entries(tab)
+					     * sizeof(st_table_entry));
+    if (tab->entries == NULL) {
+	st_free_table(tab);
+	return NULL;
+    }
+#ifdef ST_DEBUG
+    memset(tab->entries, ST_INIT_VAL_BYTE,
+	   get_allocated_entries(tab) * sizeof(st_table_entry));
+    if (tab->bins != NULL)
+        memset(tab->bins, ST_INIT_VAL_BYTE, bins_size(tab));
+#endif
+    make_tab_empty(tab);
+    tab->rebuilds_num = 0;
+#ifdef ST_DEBUG
+    st_check(tab);
+#endif
+    return tab;
+}
+
+#ifdef RUBY
+/* Create and return table with TYPE which can hold a minimal number
+   of entries (see comments for get_power2).  */
+st_table *
+st_init_table(const struct st_hash_type *type)
+{
+    return st_init_table_with_size(type, 0);
+}
+
+/* Create and return table which can hold a minimal number of
+   numbers.  */
+st_table *
+st_init_numtable(void)
+{
+    return st_init_table(&type_numhash);
+}
+
+/* Create and return table which can hold SIZE numbers.  */
+st_table *
+st_init_numtable_with_size(st_index_t size)
+{
+    return st_init_table_with_size(&type_numhash, size);
+}
+
+/* Create and return table which can hold a minimal number of
+   strings.  */
+st_table *
+st_init_strtable(void)
+{
+    return st_init_table(&type_strhash);
+}
+
+/* Create and return table which can hold SIZE strings.  */
+st_table *
+st_init_strtable_with_size(st_index_t size)
+{
+    return st_init_table_with_size(&type_strhash, size);
+}
+
+/* Create and return table which can hold a minimal number of strings
+   whose character case is ignored.  */
+st_table *
+st_init_strcasetable(void)
+{
+    return st_init_table(&type_strcasehash);
+}
+
+/* Create and return table which can hold SIZE strings whose character
+   case is ignored.  */
+st_table *
+st_init_strcasetable_with_size(st_index_t size)
+{
+    return st_init_table_with_size(&type_strcasehash, size);
+}
+
+/* Make table TAB empty.  */
+void
+st_clear(st_table *tab)
+{
+    make_tab_empty(tab);
+    tab->rebuilds_num++;
+#ifdef ST_DEBUG
+    st_check(tab);
+#endif
+}
+#endif /* RUBY */
+
+/* Free table TAB space.  */
+void
+st_free_table(st_table *tab)
+{
+    if (tab->bins != NULL)
+        free(tab->bins);
+    free(tab->entries);
+    free(tab);
+}
+
+#ifdef RUBY
+/* Return byte size of memory allocted for table TAB.  */
+size_t
+st_memsize(const st_table *tab)
+{
+    return(sizeof(st_table)
+           + (tab->bins == NULL ? 0 : bins_size(tab))
+           + get_allocated_entries(tab) * sizeof(st_table_entry));
+}
+#endif /* RUBY */
+
+static st_index_t
+find_table_entry_ind(st_table *tab, st_hash_t hash_value, st_data_t key);
+
+static st_index_t
+find_table_bin_ind(st_table *tab, st_hash_t hash_value, st_data_t key);
+
+static st_index_t
+find_table_bin_ind_direct(st_table *table, st_hash_t hash_value, st_data_t key);
+
+static st_index_t
+find_table_bin_ptr_and_reserve(st_table *tab, st_hash_t *hash_value,
+			       st_data_t key, st_index_t *bin_ind);
+
+#ifdef HASH_LOG
+static void
+count_collision(const struct st_hash_type *type)
+{
+    collision.all++;
+    if (type == &type_numhash) {
+        collision.num++;
+    }
+    else if (type == &type_strhash) {
+        collision.strcase++;
+    }
+    else if (type == &type_strcasehash) {
+        collision.str++;
+    }
+}
+
+#define COLLISION (collision_check ? count_collision(tab->type) : (void)0)
+#define FOUND_BIN (collision_check ? collision.total++ : (void)0)
+#define collision_check 0
+#else
+#define COLLISION
+#define FOUND_BIN
+#endif
+
+/* If the number of entries in the table is at least REBUILD_THRESHOLD
+   times less than the entry array length, decrease the table
+   size.  */
+#define REBUILD_THRESHOLD 4
+
+#if REBUILD_THRESHOLD < 2
+#error "REBUILD_THRESHOLD should be >= 2"
+#endif
+
+/* Rebuild table TAB.  Rebuilding removes all deleted bins and entries
+   and can change size of the table entries and bins arrays.
+   Rebuilding is implemented by creation of a new table or by
+   compaction of the existing one.  */
+static void
+rebuild_table(st_table *tab)
+{
+    st_index_t i, ni, bound;
+    unsigned int size_ind;
+    st_table *new_tab;
+    st_table_entry *entries, *new_entries;
+    st_table_entry *curr_entry_ptr;
+    st_index_t *bins;
+    st_index_t bin_ind;
+
+    st_assert(tab != NULL);
+    bound = tab->entries_bound;
+    entries = tab->entries;
+    if ((2 * tab->num_entries <= get_allocated_entries(tab)
+	 && REBUILD_THRESHOLD * tab->num_entries > get_allocated_entries(tab))
+	|| tab->num_entries < (1 << MINIMAL_POWER2)) {
+        /* Compaction: */
+        tab->num_entries = 0;
+	if (tab->bins != NULL)
+	    initialize_bins(tab);
+	new_tab = tab;
+	new_entries = entries;
+    }
+    else {
+        new_tab = st_init_table_with_size(tab->type,
+					  2 * tab->num_entries - 1);
+	new_entries = new_tab->entries;
+    }
+    ni = 0;
+    bins = new_tab->bins;
+    size_ind = get_size_ind(new_tab);
+    for (i = tab->entries_start; i < bound; i++) {
+        curr_entry_ptr = &entries[i];
+	PREFETCH(entries + i + 1, 0);
+	if (EXPECT(DELETED_ENTRY_P(curr_entry_ptr), 0))
+	    continue;
+	if (&new_entries[ni] != curr_entry_ptr)
+	    new_entries[ni] = *curr_entry_ptr;
+	if (EXPECT(bins != NULL, 1)) {
+	    bin_ind = find_table_bin_ind_direct(new_tab, curr_entry_ptr->hash,
+						curr_entry_ptr->key);
+	    st_assert(bin_ind != UNDEFINED_BIN_IND
+		      && (tab == new_tab || new_tab->rebuilds_num == 0)
+		      && IND_EMPTY_BIN_P(new_tab, bin_ind));
+	    set_bin(bins, size_ind, bin_ind, ni + ENTRY_BASE);
+	}
+	new_tab->num_entries++;
+	ni++;
+    }
+    if (new_tab != tab) {
+        tab->entry_power = new_tab->entry_power;
+	tab->bin_power = new_tab->bin_power;
+	tab->size_ind = new_tab->size_ind;
+	st_assert (tab->num_entries == ni && new_tab->num_entries == ni);
+	if (tab->bins != NULL)
+	    free(tab->bins);
+	tab->bins = new_tab->bins;
+	free(tab->entries);
+	tab->entries = new_tab->entries;
+	free(new_tab);
+    }
+    tab->entries_start = 0;
+    tab->entries_bound = tab->num_entries;
+    tab->rebuilds_num++;
+#ifdef ST_DEBUG
+    st_check(tab);
+#endif
+}
+
+/* Return the next secondary hash index for table TAB using previous
+   index IND and PERTERB.  Finally modulo of the function becomes a
+   full *cycle linear congruential generator*, in other words it
+   guarantees traversing all table bins in extreme case.
+
+   According the Hull-Dobell theorem a generator
+   "Xnext = (a*Xprev + c) mod m" is a full cycle generator iff
+     o m and c are relatively prime
+     o a-1 is divisible by all prime factors of m
+     o a-1 is divisible by 4 if m is divisible by 4.
+
+   For our case a is 5, c is 1, and m is a power of two.  */
+static inline st_index_t
+secondary_hash(st_index_t ind, st_table *tab, st_index_t *perterb)
+{
+    *perterb >>= 11;
+    ind = (ind << 2) + ind + *perterb + 1;
+    return hash_bin(ind, tab);
+}
+
+/* Find an entry with HASH_VALUE and KEY in TABLE using a linear
+   search.  Return the index of the found entry in array `entries`.
+   If it is not found, return UNDEFINED_ENTRY_IND.  */
+static inline st_index_t
+find_entry(st_table *tab, st_hash_t hash_value, st_data_t key)
+{
+    st_index_t i, bound;
+    st_table_entry *entries;
+
+    bound = tab->entries_bound;
+    entries = tab->entries;
+    for (i = tab->entries_start; i < bound; i++) {
+	if (PTR_EQUAL(tab, &entries[i], hash_value, key))
+	    return i;
+    }
+    return UNDEFINED_ENTRY_IND;
+}
+
+/* Use the quadratic probing.  The method has a better data locality
+   but more collisions than the current approach.  In average it
+   results in a bit slower search.  */
+/*#define QUADRATIC_PROBE*/
+
+/* Return index of entry with HASH_VALUE and KEY in table TAB.  If
+   there is no such entry, return UNDEFINED_ENTRY_IND.  */
+static st_index_t
+find_table_entry_ind(st_table *tab, st_hash_t hash_value, st_data_t key)
+{
+    st_index_t ind;
+#ifdef QUADRATIC_PROBE
+    st_index_t d;
+#else
+    st_index_t peterb;
+#endif
+    st_index_t bin;
+    st_table_entry *entries = tab->entries;
+
+    st_assert(tab != NULL && tab->bins != NULL);
+    ind = hash_bin(hash_value, tab);
+#ifdef QUADRATIC_PROBE
+    d = 1;
+#else
+    peterb = hash_value;
+#endif
+    FOUND_BIN;
+    for (;;) {
+        bin = get_bin(tab->bins, get_size_ind(tab), ind);
+        if (! EMPTY_OR_DELETED_BIN_P(bin)
+            && PTR_EQUAL(tab, &entries[bin - ENTRY_BASE], hash_value, key))
+            break;
+        else if (EMPTY_BIN_P(bin))
+            return UNDEFINED_ENTRY_IND;
+#ifdef QUADRATIC_PROBE
+	ind = hash_bin(ind + d, tab);
+	d++;
+#else
+        ind = secondary_hash(ind, tab, &peterb);
+#endif
+        COLLISION;
+    }
+    return bin;
+}
+
+/* Find and return index of table TAB bin corresponding to an entry
+   with HASH_VALUE and KEY.  If there is no such bin, return
+   UNDEFINED_BIN_IND.  */
+static st_index_t
+find_table_bin_ind(st_table *tab, st_hash_t hash_value, st_data_t key)
+{
+    st_index_t ind;
+#ifdef QUADRATIC_PROBE
+    st_index_t d;
+#else
+    st_index_t peterb;
+#endif
+    st_index_t bin;
+    st_table_entry *entries = tab->entries;
+
+    st_assert(tab != NULL && tab->bins != NULL);
+    ind = hash_bin(hash_value, tab);
+#ifdef QUADRATIC_PROBE
+    d = 1;
+#else
+    peterb = hash_value;
+#endif
+    FOUND_BIN;
+    for (;;) {
+        bin = get_bin(tab->bins, get_size_ind(tab), ind);
+        if (! EMPTY_OR_DELETED_BIN_P(bin)
+            && PTR_EQUAL(tab, &entries[bin - ENTRY_BASE], hash_value, key))
+            break;
+        else if (EMPTY_BIN_P(bin))
+            return UNDEFINED_BIN_IND;
+#ifdef QUADRATIC_PROBE
+	ind = hash_bin(ind + d, tab);
+	d++;
+#else
+        ind = secondary_hash(ind, tab, &peterb);
+#endif
+        COLLISION;
+    }
+    return ind;
+}
+
+/* Find and return index of table TAB bin corresponding to an entry
+   with HASH_VALUE and KEY.  The entry should be in the table
+   already.  */
+static st_index_t
+find_table_bin_ind_direct(st_table *tab, st_hash_t hash_value, st_data_t key)
+{
+    st_index_t ind;
+#ifdef QUADRATIC_PROBE
+    st_index_t d;
+#else
+    st_index_t peterb;
+#endif
+    st_index_t bin;
+    st_table_entry *entries = tab->entries;
+
+    st_assert(tab != NULL && tab->bins != NULL);
+    ind = hash_bin(hash_value, tab);
+#ifdef QUADRATIC_PROBE
+    d = 1;
+#else
+    peterb = hash_value;
+#endif
+    FOUND_BIN;
+    for (;;) {
+        bin = get_bin(tab->bins, get_size_ind(tab), ind);
+        if (EMPTY_OR_DELETED_BIN_P(bin))
+	    return ind;
+	st_assert (! PTR_EQUAL(tab, &entries[bin - ENTRY_BASE], hash_value, key));
+#ifdef QUADRATIC_PROBE
+	ind = hash_bin(ind + d, tab);
+	d++;
+#else
+        ind = secondary_hash(ind, tab, &peterb);
+#endif
+        COLLISION;
+    }
+}
+
+/* Return index of table TAB bin for HASH_VALUE and KEY through
+   BIN_IND and the pointed value as the function result.  Reserve the
+   bin for inclusion of the corresponding entry into the table if it
+   is not there yet.  We always find such bin as bins array length is
+   bigger entries array.  Although we can reuse a deleted bin, the
+   result bin value is always empty if the table has no entry with
+   KEY.  Return the entries array index of the found entry or
+   UNDEFINED_ENTRY_IND if it is not found.  */
+static st_index_t
+find_table_bin_ptr_and_reserve(st_table *tab, st_hash_t *hash_value,
+			       st_data_t key, st_index_t *bin_ind) {
+    st_index_t ind;
+    st_hash_t curr_hash_value = *hash_value;
+#ifdef QUADRATIC_PROBE
+    st_index_t d;
+#else
+    st_index_t peterb;
+#endif
+    st_index_t entry_index;
+    st_index_t first_deleted_bin_ind;
+    st_table_entry *entries;
+
+    st_assert(tab != NULL && tab->bins != NULL
+	      && tab->entries_bound <= get_allocated_entries(tab)
+	      && tab->entries_start <= tab->entries_bound);
+    ind = hash_bin(curr_hash_value, tab);
+#ifdef QUADRATIC_PROBE
+    d = 1;
+#else
+    peterb = curr_hash_value;
+#endif
+    FOUND_BIN;
+    first_deleted_bin_ind = UNDEFINED_BIN_IND;
+    entries = tab->entries;
+    for (;;) {
+        entry_index = get_bin(tab->bins, get_size_ind(tab), ind);
+        if (EMPTY_BIN_P(entry_index)) {
+            tab->num_entries++;
+	    entry_index = UNDEFINED_ENTRY_IND;
+            if (first_deleted_bin_ind != UNDEFINED_BIN_IND) {
+                /* We can reuse bin of a deleted entry.  */
+                ind = first_deleted_bin_ind;
+                MARK_BIN_EMPTY(tab, ind);
+            }
+            break;
+        } else if (! DELETED_BIN_P(entry_index)) {
+            if (PTR_EQUAL(tab, &entries[entry_index - ENTRY_BASE], curr_hash_value, key))
+                break;
+        } else if (first_deleted_bin_ind == UNDEFINED_BIN_IND)
+            first_deleted_bin_ind = ind;
+#ifdef QUADRATIC_PROBE
+	ind = hash_bin(ind + d, tab);
+	d++;
+#else
+        ind = secondary_hash(ind, tab, &peterb);
+#endif
+        COLLISION;
+    }
+    *bin_ind = ind;
+    return entry_index;
+}
+
+/* Find an entry with KEY in table TAB.  Return non-zero if we found
+   it.  Set up *RECORD to the found entry record.  */
+int
+st_lookup(st_table *tab, st_data_t key, st_data_t *value)
+{
+    st_index_t bin;
+    st_hash_t hash = do_hash(key, tab);
+
+    if (tab->bins == NULL) {
+        bin = find_entry(tab, hash, key);
+	if (bin == UNDEFINED_ENTRY_IND)
+	    return 0;
+    } else {
+        bin = find_table_entry_ind(tab, hash, key);
+	if (bin == UNDEFINED_ENTRY_IND)
+	    return 0;
+	bin -= ENTRY_BASE;
+    }
+    if (value != 0)
+        *value = tab->entries[bin].record;
+    return 1;
+}
+
+#ifdef RUBY
+/* Find an entry with KEY in table TAB.  Return non-zero if we found
+   it.  Set up *RESULT to the found table entry key.  */
+int
+st_get_key(st_table *tab, st_data_t key, st_data_t *result)
+{
+    st_index_t bin;
+    st_hash_t hash = do_hash(key, tab);
+
+    if (tab->bins == NULL) {
+        bin = find_entry(tab, hash, key);
+	if (bin == UNDEFINED_ENTRY_IND)
+	    return 0;
+    } else {
+        bin = find_table_entry_ind(tab, hash, key);
+	if (bin == UNDEFINED_ENTRY_IND)
+	    return 0;
+	bin -= ENTRY_BASE;
+    }
+    if (result != 0)
+        *result = tab->entries[bin].key;
+    return 1;
+}
+#endif /* RUBY */
+
+/* Check the table and rebuild it if it is necessary.  */
+static inline void
+rebuild_table_if_necessary (st_table *tab)
+{
+    st_index_t bound = tab->entries_bound;
+
+    if (bound == get_allocated_entries(tab))
+        rebuild_table(tab);
+    st_assert(tab->entries_bound < get_allocated_entries(tab));
+}
+
+/* Insert (KEY, VALUE) into table TAB and return zero.  If there is
+   already entry with KEY in the table, return nonzero and and update
+   the value of the found entry.  */
+int
+st_insert(st_table *tab, st_data_t key, st_data_t value)
+{
+    st_table_entry *entry;
+    st_index_t bin;
+    st_index_t ind;
+    st_hash_t hash_value;
+    st_index_t bin_ind;
+    int new_p;
+
+    rebuild_table_if_necessary(tab);
+    hash_value = do_hash(key, tab);
+    if (tab->bins == NULL) {
+        bin = find_entry(tab, hash_value, key);
+	new_p = bin == UNDEFINED_ENTRY_IND;
+	if (new_p)
+	    tab->num_entries++;
+	bin_ind = UNDEFINED_BIN_IND;
+    } else {
+        bin = find_table_bin_ptr_and_reserve(tab, &hash_value,
+					     key, &bin_ind);
+	new_p = bin == UNDEFINED_ENTRY_IND;
+	bin -= ENTRY_BASE;
+    }
+    if (new_p) {
+        st_assert(tab->entries_bound < get_allocated_entries(tab));
+	ind = tab->entries_bound++;
+        entry = &tab->entries[ind];
+        entry->hash = hash_value;
+        entry->key = key;
+        entry->record = value;
+	if (bin_ind != UNDEFINED_BIN_IND)
+	    set_bin(tab->bins, get_size_ind(tab), bin_ind, ind + ENTRY_BASE);
+#ifdef ST_DEBUG
+	st_check(tab);
+#endif
+        return 0;
+    }
+    tab->entries[bin].record = value;
+#ifdef ST_DEBUG
+    st_check(tab);
+#endif
+    return 1;
+}
+
+#ifdef RUBY
+/* Insert (KEY, VALUE, HASH) into table TAB.  The table should not have
+   entry with KEY before the insertion.  */
+static inline void
+st_add_direct_with_hash(st_table *tab,
+			st_data_t key, st_data_t value, st_hash_t hash) {
+    st_table_entry *entry;
+    st_index_t ind;
+    st_index_t bin_ind;
+
+    rebuild_table_if_necessary(tab);
+    ind = tab->entries_bound++;
+    entry = &tab->entries[ind];
+    entry->hash = hash;
+    entry->key = key;
+    entry->record = value;
+    tab->num_entries++;
+    if (tab->bins != NULL) {
+        bin_ind = find_table_bin_ind_direct(tab, hash, key);
+	st_assert (bin_ind != UNDEFINED_BIN_IND);
+	set_bin(tab->bins, get_size_ind(tab), bin_ind, ind + ENTRY_BASE);
+    }
+#ifdef ST_DEBUG
+    st_check(tab);
+#endif
+}
+
+/* Insert (KEY, VALUE) into table TAB.  The table should not have
+   entry with KEY before the insertion.  */
+void
+st_add_direct(st_table *tab, st_data_t key, st_data_t value)
+{
+    st_hash_t hash_value;
+
+    hash_value = do_hash(key, tab);
+    st_add_direct_with_hash(tab, key, value, hash_value);
+}
+
+/* Insert (FUNC(KEY), VALUE) into table TAB and return zero.  If
+   there is already entry with KEY in the table, return nonzero and
+   and update the value of the found entry.  */
+int
+st_insert2(st_table *tab, st_data_t key, st_data_t value,
+           st_data_t (*func)(st_data_t)) {
+    st_table_entry *entry;
+    st_index_t bin;
+    st_index_t ind, check;
+    st_hash_t hash_value;
+    st_index_t bin_ind;
+    int new_p;
+
+    rebuild_table_if_necessary (tab);
+    hash_value = do_hash(key, tab);
+    if (tab->bins == NULL) {
+        bin = find_entry(tab, hash_value, key);
+	new_p = bin == UNDEFINED_ENTRY_IND;
+	bin_ind = UNDEFINED_BIN_IND;
+    } else {
+        bin = find_table_bin_ptr_and_reserve(tab, &hash_value,
+					     key, &bin_ind);
+	new_p = bin == UNDEFINED_ENTRY_IND;
+	bin -= ENTRY_BASE;
+    }
+    if (new_p) {
+        st_assert(tab->entries_bound < get_allocated_entries(tab));
+        check = tab->rebuilds_num;
+        key = (*func)(key);
+        st_assert(check == tab->rebuilds_num
+                  && do_hash(key, tab) == hash_value);
+        ind = tab->entries_bound++;
+        entry = &tab->entries[ind];
+        entry->hash = hash_value;
+        entry->key = key;
+        entry->record = value;
+	if (bin_ind != UNDEFINED_BIN_IND)
+	    set_bin(tab->bins, get_size_ind(tab), bin_ind, ind + ENTRY_BASE);
+#ifdef ST_DEBUG
+	st_check(tab);
+#endif
+        return 0;
+    }
+    tab->entries[bin].record = value;
+#ifdef ST_DEBUG
+    st_check(tab);
+#endif
+    return 1;
+}
+
+/* Create and return a copy of table OLD_TAB.  */
+st_table *
+st_copy(st_table *old_tab)
+{
+    st_table *new_tab;
+
+    new_tab = (st_table *) malloc(sizeof(st_table));
+    if (new_tab == NULL)
+	return NULL;
+    *new_tab = *old_tab;
+    if (old_tab->bins == NULL)
+        new_tab->bins = NULL;
+    else {
+        new_tab->bins = (st_index_t *) malloc(bins_size(old_tab));
+	if (new_tab->bins == NULL) {
+	    free(new_tab);
+	    return NULL;
+	}
+    }
+    new_tab->entries = (st_table_entry *) malloc(get_allocated_entries(old_tab)
+						 * sizeof(st_table_entry));
+    if (new_tab->entries == NULL) {
+	st_free_table(new_tab);
+	return NULL;
+    }
+    MEMCPY(new_tab->entries, old_tab->entries, st_table_entry,
+	   get_allocated_entries(old_tab));
+    if (old_tab->bins != NULL)
+        MEMCPY(new_tab->bins, old_tab->bins, char, bins_size(old_tab));
+#ifdef ST_DEBUG
+    st_check(new_tab);
+#endif
+    return new_tab;
+}
+#endif /* RUBY */
+
+/* Update the entries start of table TAB after removing an entry
+   with index N in the array entries.  */
+static inline void
+update_range_for_deleted(st_table *tab, st_index_t n)
+{
+    /* Do not update entries_bound here.  Otherwise, we can fill all
+       bins by deleted entry value before rebuilding the table.  */
+    if (tab->entries_start == n)
+        tab->entries_start = n + 1;
+}
+
+#ifdef RUBY
+/* Delete entry with KEY from table TAB, set up *VALUE (unless
+   VALUE is zero) from deleted table entry, and return non-zero.  If
+   there is no entry with KEY in the table, clear *VALUE (unless VALUE
+   is zero), and return zero.  */
+static int
+st_general_delete(st_table *tab, st_data_t *key, st_data_t *value)
+{
+    st_table_entry *entry;
+    st_index_t bin;
+    st_index_t bin_ind;
+    st_hash_t hash;
+
+    st_assert(tab != NULL);
+    hash = do_hash(*key, tab);
+    if (tab->bins == NULL) {
+        bin = find_entry(tab, hash, *key);
+	if (bin == UNDEFINED_ENTRY_IND) {
+	    if (value != 0) *value = 0;
+	    return 0;
+	}
+    } else {
+        bin_ind = find_table_bin_ind(tab, hash, *key);
+	if (bin_ind == UNDEFINED_BIN_IND) {
+	    if (value != 0) *value = 0;
+	    return 0;
+	}
+	bin = get_bin(tab->bins, get_size_ind(tab), bin_ind) - ENTRY_BASE;
+	MARK_BIN_DELETED(tab, bin_ind);
+    }
+    entry = &tab->entries[bin];
+    *key = entry->key;
+    if (value != 0) *value = entry->record;
+    MARK_ENTRY_DELETED(entry);
+    tab->num_entries--;
+    update_range_for_deleted(tab, bin);
+#ifdef ST_DEBUG
+    st_check(tab);
+#endif
+    return 1;
+}
+
+int
+st_delete(st_table *tab, st_data_t *key, st_data_t *value)
+{
+    return st_general_delete(tab, key, value);
+}
+
+/* The function and other functions with suffix '_safe' or '_check'
+   are originated from the previous implementation of the hash tables.
+   It was necessary for correct deleting entries during traversing
+   tables.  The current implementation permits deletion during
+   traversing without a specific way to do this.  */
+int
+st_delete_safe(st_table *tab, st_data_t *key, st_data_t *value,
+               st_data_t never ATTRIBUTE_UNUSED) {
+    return st_general_delete(tab, key, value);
+}
+
+/* If table TAB is empty, clear *VALUE (unless VALUE is zero), and
+   return zero.  Otherwise, remove the first entry in the table.
+   Return its key through KEY and its record through VALUE (unless
+   VALUE is zero).  */
+int
+st_shift(st_table *tab, st_data_t *key, st_data_t *value)
+{
+    st_index_t i, bound;
+    st_index_t bin;
+    st_table_entry *entries, *curr_entry_ptr;
+    st_index_t bin_ind;
+
+    entries = tab->entries;
+    bound = tab->entries_bound;
+    for (i = tab->entries_start; i < bound; i++) {
+        curr_entry_ptr = &entries[i];
+	if (! DELETED_ENTRY_P(curr_entry_ptr)) {
+	    if (value != 0) *value = curr_entry_ptr->record;
+	    *key = curr_entry_ptr->key;
+	    if (tab->bins == NULL) {
+	        bin = find_entry(tab, curr_entry_ptr->hash, curr_entry_ptr->key);
+		st_assert(bin != UNDEFINED_ENTRY_IND
+			  && &entries[bin] == curr_entry_ptr);
+	    } else {
+	        bin_ind = find_table_bin_ind(tab, curr_entry_ptr->hash,
+					     curr_entry_ptr->key);
+		st_assert(bin_ind != UNDEFINED_BIN_IND
+			  && &entries[get_bin(tab->bins, get_size_ind(tab), bin_ind)
+				      - ENTRY_BASE] == curr_entry_ptr);
+		MARK_BIN_DELETED(tab, bin_ind);
+	    }
+	    MARK_ENTRY_DELETED(curr_entry_ptr);
+	    tab->num_entries--;
+	    update_range_for_deleted(tab, i);
+#ifdef ST_DEBUG
+	    st_check(tab);
+#endif
+	    return 1;
+	}
+    }
+    st_assert(tab->num_entries == 0);
+    tab->entries_start = tab->entries_bound = 0;
+    if (value != 0) *value = 0;
+    return 0;
+}
+
+/* See comments for function st_delete_safe.  */
+void
+st_cleanup_safe(st_table *tab ATTRIBUTE_UNUSED,
+                st_data_t never ATTRIBUTE_UNUSED) {
+}
+
+/* Find entry with KEY in table TAB, call FUNC with the key and the
+   value of the found entry, and non-zero as the 3rd argument.  If the
+   entry is not found, call FUNC with KEY, and 2 zero arguments.  If
+   the call returns ST_CONTINUE, the table will have an entry with key
+   and value returned by FUNC through the 1st and 2nd parameters.  If
+   the call of FUNC returns ST_DELETE, the table will not have entry
+   with KEY.  The function returns flag of that the entry with KEY was
+   in the table before the call.  */
+int
+st_update(st_table *tab, st_data_t key,
+	  st_update_callback_func *func, st_data_t arg) {
+    st_table_entry *entry = NULL; /* to avoid uninitialized value warning */
+    st_index_t bin = 0; /* Ditto */
+    st_table_entry *entries;
+    st_index_t bin_ind;
+    st_data_t value = 0, old_key;
+    st_index_t check;
+    int retval, existing;
+    st_hash_t hash = do_hash(key, tab);
+
+    entries = tab->entries;
+    if (tab->bins == NULL) {
+        bin = find_entry(tab, hash, key);
+	existing = bin != UNDEFINED_ENTRY_IND;
+	entry = &entries[bin];
+	bin_ind = UNDEFINED_BIN_IND;
+    } else {
+        bin_ind = find_table_bin_ind(tab, hash, key);
+	existing = bin_ind != UNDEFINED_BIN_IND;
+	if (existing) {
+	    bin = get_bin(tab->bins, get_size_ind(tab), bin_ind) - ENTRY_BASE;
+	    entry = &entries[bin];
+	}
+    }
+    if (existing) {
+        key = entry->key;
+        value = entry->record;
+    }
+    old_key = key;
+    check = tab->rebuilds_num;
+    retval = (*func)(&key, &value, arg, existing);
+    st_assert(check == tab->rebuilds_num);
+    switch (retval) {
+    case ST_CONTINUE:
+        if (! existing) {
+	    st_add_direct_with_hash(tab, key, value, hash);
+            break;
+        }
+        if (old_key != key) {
+            entry->key = key;
+        }
+        entry->record = value;
+        break;
+    case ST_DELETE:
+        if (existing) {
+	    if (bin_ind != UNDEFINED_BIN_IND)
+	        MARK_BIN_DELETED(tab, bin_ind);
+            MARK_ENTRY_DELETED(entry);
+	    tab->num_entries--;
+	    update_range_for_deleted(tab, bin);
+#ifdef ST_DEBUG
+	    st_check(tab);
+#endif
+        }
+        break;
+    }
+#ifdef ST_DEBUG
+    st_check(tab);
+#endif
+    return existing;
+}
+#endif /* RUBY */
+
+/* Traverse all entries in table TAB calling FUNC with current entry
+   key and value and zero.  If the call returns ST_STOP, stop
+   traversing.  If the call returns ST_DELETE, delete the current
+   entry from the table.  In case of ST_CHECK or ST_CONTINUE, continue
+   traversing.  The function returns zero unless an error is found.
+   CHECK_P is flag of st_foreach_check call.  The behavior is a bit
+   different for ST_CHECK and when the current element is removed
+   during traversing.  */
+static inline int
+st_general_foreach(st_table *tab, int (*func)(ANYARGS), st_data_t arg,
+		   int check_p) {
+    st_index_t bin;
+    st_index_t bin_ind;
+    st_table_entry *entries, *curr_entry_ptr;
+    enum st_retval retval;
+    st_index_t i, rebuilds_num;
+    st_hash_t hash;
+    st_data_t key;
+    int error_p, packed_p = tab->bins == NULL;
+
+    st_assert(tab->entries_start <= tab->entries_bound);
+    entries = tab->entries;
+    /* The bound can change inside the loop even without rebuilding
+       the table, e.g. by an entry inesrtion.  */
+    for (i = tab->entries_start; i < tab->entries_bound; i++) {
+        curr_entry_ptr = &entries[i];
+	if (EXPECT(DELETED_ENTRY_P(curr_entry_ptr), 0))
+	    continue;
+	key = curr_entry_ptr->key;
+	rebuilds_num = tab->rebuilds_num;
+	hash = curr_entry_ptr->hash;
+	retval = (*func)(key, curr_entry_ptr->record, arg, 0);
+	if (rebuilds_num != tab->rebuilds_num) {
+	    entries = tab->entries;
+	    packed_p = tab->bins == NULL;
+	    if (packed_p) {
+	        i = find_entry(tab, hash, key);
+		error_p = i == UNDEFINED_ENTRY_IND;
+	    } else {
+	        i = find_table_entry_ind(tab, hash, key);
+		error_p = i == UNDEFINED_ENTRY_IND;
+		i -= ENTRY_BASE;
+	    }
+	    if (error_p && check_p) {
+	        /* call func with error notice */
+	        retval = (*func)(0, 0, arg, 1);
+#ifdef ST_DEBUG
+		st_check(tab);
+#endif
+		return 1;
+	    }
+	    curr_entry_ptr = &entries[i];
+	}
+	switch (retval) {
+	case ST_CONTINUE:
+	    break;
+	case ST_CHECK:
+	    if (check_p)
+		break;
+	case ST_STOP:
+#ifdef ST_DEBUG
+	    st_check(tab);
+#endif
+	    return 0;
+	case ST_DELETE:
+	    if (packed_p) {
+	        bin = find_entry(tab, hash, curr_entry_ptr->key);
+		if (bin == UNDEFINED_ENTRY_IND)
+		    break;
+	    } else {
+	        bin_ind = find_table_bin_ind(tab, hash, curr_entry_ptr->key);
+		if (bin_ind == UNDEFINED_BIN_IND)
+		    break;
+		bin = get_bin(tab->bins, get_size_ind(tab), bin_ind) - ENTRY_BASE;
+		MARK_BIN_DELETED(tab, bin_ind);
+	    }
+	    st_assert(&entries[bin] == curr_entry_ptr);
+	    MARK_ENTRY_DELETED(curr_entry_ptr);
+	    tab->num_entries--;
+	    update_range_for_deleted(tab, bin);
+#ifdef ST_DEBUG
+	    st_check(tab);
+#endif
+	    break;
+	}
+    }
+#ifdef ST_DEBUG
+    st_check(tab);
+#endif
+    return 0;
+}
+
+int
+st_foreach(st_table *tab, int (*func)(ANYARGS), st_data_t arg)
+{
+  return st_general_foreach(tab, func, arg, FALSE);
+}
+
+#ifdef RUBY
+/* See comments for function st_delete_safe.  */
+int
+st_foreach_check(st_table *tab, int (*func)(ANYARGS), st_data_t arg,
+                 st_data_t never ATTRIBUTE_UNUSED) {
+  return st_general_foreach(tab, func, arg, TRUE);
+}
+
+/* Set up array KEYS by at most SIZE keys of head table TAB entries.
+   Return the number of keys set up in array KEYS.  */
+static inline st_index_t
+st_general_keys(st_table *tab, st_data_t *keys, st_index_t size)
+{
+    st_index_t i, bound;
+    st_data_t key, *keys_start, *keys_end;
+    st_table_entry *curr_entry_ptr, *entries = tab->entries;
+
+    bound = tab->entries_bound;
+    keys_start = keys;
+    keys_end = keys + size;
+    for (i = tab->entries_start; i < bound; i++) {
+	if (keys == keys_end)
+	    break;
+	curr_entry_ptr = &entries[i];
+	key = curr_entry_ptr->key;
+        if (! DELETED_ENTRY_P(curr_entry_ptr))
+	    *keys++ = key;
+    }
+
+    return keys - keys_start;
+}
+
+st_index_t
+st_keys(st_table *tab, st_data_t *keys, st_index_t size)
+{
+    return st_general_keys(tab, keys, size);
+}
+
+/* See comments for function st_delete_safe.  */
+st_index_t
+st_keys_check(st_table *tab, st_data_t *keys, st_index_t size,
+              st_data_t never ATTRIBUTE_UNUSED) {
+    return st_general_keys(tab, keys, size);
+}
+
+/* Set up array VALUES by at most SIZE values of head table TAB
+   entries.  Return the number of values set up in array VALUES.  */
+static inline st_index_t
+st_general_values(st_table *tab, st_data_t *values, st_index_t size)
+{
+    st_index_t i, bound;
+    st_data_t *values_start, *values_end;
+    st_table_entry *curr_entry_ptr, *entries = tab->entries;
+
+    values_start = values;
+    values_end = values + size;
+    bound = tab->entries_bound;
+    st_assert(bound != 0);
+    for (i = tab->entries_start; i < bound; i++) {
+	if (values == values_end)
+	    break;
+        curr_entry_ptr = &entries[i];
+        if (! DELETED_ENTRY_P(curr_entry_ptr))
+	    *values++ = curr_entry_ptr->record;
+    }
+
+    return values - values_start;
+}
+
+st_index_t
+st_values(st_table *tab, st_data_t *values, st_index_t size)
+{
+    return st_general_values(tab, values, size);
+}
+
+/* See comments for function st_delete_safe.  */
+st_index_t
+st_values_check(st_table *tab, st_data_t *values, st_index_t size,
+		st_data_t never ATTRIBUTE_UNUSED) {
+    return st_general_values(tab, values, size);
+}
+#endif /* RUBY */
+
+#ifdef RUBY
+#define FNV1_32A_INIT 0x811c9dc5
+
+/*
+ * 32 bit magic FNV-1a prime
+ */
+#define FNV_32_PRIME 0x01000193
+
+#ifndef UNALIGNED_WORD_ACCESS
+# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
+     defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || \
+     defined(__powerpc64__) || \
+     defined(__mc68020__)
+#   define UNALIGNED_WORD_ACCESS 1
+# endif
+#endif
+#ifndef UNALIGNED_WORD_ACCESS
+# define UNALIGNED_WORD_ACCESS 0
+#endif
+
+/* This hash function is quite simplified MurmurHash3
+ * Simplification is legal, cause most of magic still happens in finalizator.
+ * And finalizator is almost the same as in MurmurHash3 */
+#define BIG_CONSTANT(x,y) ((st_index_t)(x)<<32|(st_index_t)(y))
+#define ROTL(x,n) ((x)<<(n)|(x)>>(SIZEOF_ST_INDEX_T*CHAR_BIT-(n)))
+
+#if ST_INDEX_BITS <= 32
+#define C1 (st_index_t)0xcc9e2d51
+#define C2 (st_index_t)0x1b873593
+#else
+#define C1 BIG_CONSTANT(0x87c37b91,0x114253d5);
+#define C2 BIG_CONSTANT(0x4cf5ad43,0x2745937f);
+#endif
+static inline st_index_t
+murmur_step(st_index_t h, st_index_t k)
+{
+#if ST_INDEX_BITS <= 32
+#define r1 (17)
+#define r2 (11)
+#else
+#define r1 (33)
+#define r2 (24)
+#endif
+    k *= C1;
+    h ^= ROTL(k, r1);
+    h *= C2;
+    h = ROTL(h, r2);
+    return h;
+}
+#undef r1
+#undef r2
+
+static inline st_index_t
+murmur_finish(st_index_t h)
+{
+#if ST_INDEX_BITS <= 32
+#define r1 (16)
+#define r2 (13)
+#define r3 (16)
+    const st_index_t c1 = 0x85ebca6b;
+    const st_index_t c2 = 0xc2b2ae35;
+#else
+/* values are taken from Mix13 on http://zimbry.blogspot.ru/2011/09/better-bit-mixing-improving-on.html */
+#define r1 (30)
+#define r2 (27)
+#define r3 (31)
+    const st_index_t c1 = BIG_CONSTANT(0xbf58476d,0x1ce4e5b9);
+    const st_index_t c2 = BIG_CONSTANT(0x94d049bb,0x133111eb);
+#endif
+#if ST_INDEX_BITS > 64
+    h ^= h >> 64;
+    h *= c2;
+    h ^= h >> 65;
+#endif
+    h ^= h >> r1;
+    h *= c1;
+    h ^= h >> r2;
+    h *= c2;
+    h ^= h >> r3;
+    return h;
+}
+#undef r1
+#undef r2
+#undef r3
+
+st_index_t
+st_hash(const void *ptr, size_t len, st_index_t h)
+{
+    const char *data = ptr;
+    st_index_t t = 0;
+    size_t l = len;
+
+#define data_at(n) (st_index_t)((unsigned char)data[(n)])
+#define UNALIGNED_ADD_4 UNALIGNED_ADD(2); UNALIGNED_ADD(1); UNALIGNED_ADD(0)
+#if SIZEOF_ST_INDEX_T > 4
+#define UNALIGNED_ADD_8 UNALIGNED_ADD(6); UNALIGNED_ADD(5); UNALIGNED_ADD(4); UNALIGNED_ADD(3); UNALIGNED_ADD_4
+#if SIZEOF_ST_INDEX_T > 8
+#define UNALIGNED_ADD_16 UNALIGNED_ADD(14); UNALIGNED_ADD(13); UNALIGNED_ADD(12); UNALIGNED_ADD(11); \
+    UNALIGNED_ADD(10); UNALIGNED_ADD(9); UNALIGNED_ADD(8); UNALIGNED_ADD(7); UNALIGNED_ADD_8
+#define UNALIGNED_ADD_ALL UNALIGNED_ADD_16
+#endif
+#define UNALIGNED_ADD_ALL UNALIGNED_ADD_8
+#else
+#define UNALIGNED_ADD_ALL UNALIGNED_ADD_4
+#endif
+#undef SKIP_TAIL
+    if (len >= sizeof(st_index_t)) {
+#if !UNALIGNED_WORD_ACCESS
+	int align = (int)((st_data_t)data % sizeof(st_index_t));
+	if (align) {
+	    st_index_t d = 0;
+	    int sl, sr, pack;
+
+	    switch (align) {
+#ifdef WORDS_BIGENDIAN
+# define UNALIGNED_ADD(n) case SIZEOF_ST_INDEX_T - (n) - 1: \
+		t |= data_at(n) << CHAR_BIT*(SIZEOF_ST_INDEX_T - (n) - 2)
+#else
+# define UNALIGNED_ADD(n) case SIZEOF_ST_INDEX_T - (n) - 1:	\
+		t |= data_at(n) << CHAR_BIT*(n)
+#endif
+		UNALIGNED_ADD_ALL;
+#undef UNALIGNED_ADD
+	    }
+
+#ifdef WORDS_BIGENDIAN
+	    t >>= (CHAR_BIT * align) - CHAR_BIT;
+#else
+	    t <<= (CHAR_BIT * align);
+#endif
+
+	    data += sizeof(st_index_t)-align;
+	    len -= sizeof(st_index_t)-align;
+
+	    sl = CHAR_BIT * (SIZEOF_ST_INDEX_T-align);
+	    sr = CHAR_BIT * align;
+
+	    while (len >= sizeof(st_index_t)) {
+		d = *(st_index_t *)data;
+#ifdef WORDS_BIGENDIAN
+		t = (t << sr) | (d >> sl);
+#else
+		t = (t >> sr) | (d << sl);
+#endif
+		h = murmur_step(h, t);
+		t = d;
+		data += sizeof(st_index_t);
+		len -= sizeof(st_index_t);
+	    }
+
+	    pack = len < (size_t)align ? (int)len : align;
+	    d = 0;
+	    switch (pack) {
+#ifdef WORDS_BIGENDIAN
+# define UNALIGNED_ADD(n) case (n) + 1: \
+		d |= data_at(n) << CHAR_BIT*(SIZEOF_ST_INDEX_T - (n) - 1)
+#else
+# define UNALIGNED_ADD(n) case (n) + 1: \
+		d |= data_at(n) << CHAR_BIT*(n)
+#endif
+		UNALIGNED_ADD_ALL;
+#undef UNALIGNED_ADD
+	    }
+#ifdef WORDS_BIGENDIAN
+	    t = (t << sr) | (d >> sl);
+#else
+	    t = (t >> sr) | (d << sl);
+#endif
+
+	    if (len < (size_t)align) goto skip_tail;
+# define SKIP_TAIL 1
+	    h = murmur_step(h, t);
+	    data += pack;
+	    len -= pack;
+	}
+	else
+#endif
+	{
+	    do {
+		h = murmur_step(h, *(st_index_t *)data);
+		data += sizeof(st_index_t);
+		len -= sizeof(st_index_t);
+	    } while (len >= sizeof(st_index_t));
+	}
+    }
+
+    t = 0;
+    switch (len) {
+#if UNALIGNED_WORD_ACCESS && SIZEOF_ST_INDEX_T <= 8 && CHAR_BIT == 8
+    /* in this case byteorder doesn't really matter */
+#if SIZEOF_ST_INDEX_T > 4
+	case 7: t |= data_at(6) << 48;
+	case 6: t |= data_at(5) << 40;
+	case 5: t |= data_at(4) << 32;
+	case 4:
+	    t |= (st_index_t)*(uint32_t*)data;
+	    goto skip_tail;
+# define SKIP_TAIL 1
+#endif
+	case 3: t |= data_at(2) << 16;
+	case 2: t |= data_at(1) << 8;
+	case 1: t |= data_at(0);
+#else
+#ifdef WORDS_BIGENDIAN
+# define UNALIGNED_ADD(n) case (n) + 1: \
+	t |= data_at(n) << CHAR_BIT*(SIZEOF_ST_INDEX_T - (n) - 1)
+#else
+# define UNALIGNED_ADD(n) case (n) + 1: \
+	t |= data_at(n) << CHAR_BIT*(n)
+#endif
+	UNALIGNED_ADD_ALL;
+#undef UNALIGNED_ADD
+#endif
+#ifdef SKIP_TAIL
+      skip_tail:
+#endif
+	h ^= t; h -= ROTL(t, 7);
+	h *= C2;
+    }
+    h ^= l;
+
+    return murmur_finish(h);
+}
+
+st_index_t
+st_hash_uint32(st_index_t h, uint32_t i)
+{
+    return murmur_step(h, i);
+}
+
+st_index_t
+st_hash_uint(st_index_t h, st_index_t i)
+{
+    i += h;
+/* no matter if it is BigEndian or LittleEndian,
+ * we hash just integers */
+#if SIZEOF_ST_INDEX_T*CHAR_BIT > 8*8
+    h = murmur_step(h, i >> 8*8);
+#endif
+    h = murmur_step(h, i);
+    return h;
+}
+
+st_index_t
+st_hash_end(st_index_t h)
+{
+    h = murmur_finish(h);
+    return h;
+}
+
+#undef st_hash_start
+st_index_t
+st_hash_start(st_index_t h)
+{
+    return h;
+}
+
+static st_index_t
+strhash(st_data_t arg)
+{
+    register const char *string = (const char *)arg;
+    return st_hash(string, strlen(string), FNV1_32A_INIT);
+}
+
+int
+st_locale_insensitive_strcasecmp(const char *s1, const char *s2)
+{
+    unsigned int c1, c2;
+
+    while (1) {
+        c1 = (unsigned char)*s1++;
+        c2 = (unsigned char)*s2++;
+        if (c1 == '\0' || c2 == '\0') {
+            if (c1 != '\0') return 1;
+            if (c2 != '\0') return -1;
+            return 0;
+        }
+        if ((unsigned int)(c1 - 'A') <= ('Z' - 'A')) c1 += 'a' - 'A';
+        if ((unsigned int)(c2 - 'A') <= ('Z' - 'A')) c2 += 'a' - 'A';
+        if (c1 != c2) {
+            if (c1 > c2)
+                return 1;
+            else
+                return -1;
+        }
+    }
+}
+
+int
+st_locale_insensitive_strncasecmp(const char *s1, const char *s2, size_t n)
+{
+    unsigned int c1, c2;
+
+    while (n--) {
+        c1 = (unsigned char)*s1++;
+        c2 = (unsigned char)*s2++;
+        if (c1 == '\0' || c2 == '\0') {
+            if (c1 != '\0') return 1;
+            if (c2 != '\0') return -1;
+            return 0;
+        }
+        if ((unsigned int)(c1 - 'A') <= ('Z' - 'A')) c1 += 'a' - 'A';
+        if ((unsigned int)(c2 - 'A') <= ('Z' - 'A')) c2 += 'a' - 'A';
+        if (c1 != c2) {
+            if (c1 > c2)
+                return 1;
+            else
+                return -1;
+        }
+    }
+    return 0;
+}
+
+static st_index_t
+strcasehash(st_data_t arg)
+{
+    register const char *string = (const char *)arg;
+    register st_index_t hval = FNV1_32A_INIT;
+
+    /*
+     * FNV-1a hash each octet in the buffer
+     */
+    while (*string) {
+	unsigned int c = (unsigned char)*string++;
+	if ((unsigned int)(c - 'A') <= ('Z' - 'A')) c += 'a' - 'A';
+	hval ^= c;
+
+	/* multiply by the 32 bit FNV magic prime mod 2^32 */
+	hval *= FNV_32_PRIME;
+    }
+    return hval;
+}
+
+int
+st_numcmp(st_data_t x, st_data_t y)
+{
+    return x != y;
+}
+
+st_index_t
+st_numhash(st_data_t n)
+{
+    enum {s1 = 11, s2 = 3};
+    return (st_index_t)((n>>s1|(n<<s2)) ^ (n>>s2));
+}
+#endif /* RUBY */
Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/st.h
===================================================================
--- EcnlProtoTool/trunk/onigmo-6.1.3/src/st.h	(revision 331)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/st.h	(revision 331)
@@ -0,0 +1,162 @@
+/* This is a public domain general purpose hash table package
+   originally written by Peter Moore @ UCB.
+
+   The hash table data strutures were redesigned and the package was
+   rewritten by Vladimir Makarov <vmakarov@redhat.com>.  */
+
+#ifndef RUBY_ST_H
+#define RUBY_ST_H 1
+
+#if defined(__cplusplus)
+extern "C" {
+#if 0
+} /* satisfy cc-mode */
+#endif
+#endif
+
+#ifdef RUBY
+#include "ruby/defines.h"
+#else /* RUBY */
+#ifndef RUBY_SYMBOL_EXPORT_BEGIN
+#define RUBY_SYMBOL_EXPORT_BEGIN
+#define RUBY_SYMBOL_EXPORT_END
+#endif
+#endif /* RUBY */
+
+RUBY_SYMBOL_EXPORT_BEGIN
+
+#if SIZEOF_LONG == SIZEOF_VOIDP
+typedef unsigned long st_data_t;
+#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
+typedef unsigned LONG_LONG st_data_t;
+#else
+# error ---->> st.c requires sizeof(void*) == sizeof(long) or sizeof(LONG_LONG) to be compiled. <<----
+#endif
+#define ST_DATA_T_DEFINED
+
+#ifndef CHAR_BIT
+# ifdef HAVE_LIMITS_H
+#  include <limits.h>
+# else
+#  define CHAR_BIT 8
+# endif
+#endif
+#ifndef _
+# define _(args) args
+#endif
+#ifndef ANYARGS
+# ifdef __cplusplus
+#   define ANYARGS ...
+# else
+#   define ANYARGS
+# endif
+#endif
+
+typedef struct st_table st_table;
+
+typedef st_data_t st_index_t;
+
+/* Maximal value of unsigned integer type st_index_t.  */
+#define MAX_ST_INDEX_VAL (~(st_index_t) 0)
+
+typedef int st_compare_func(st_data_t, st_data_t);
+typedef st_index_t st_hash_func(st_data_t);
+
+typedef char st_check_for_sizeof_st_index_t[SIZEOF_VOIDP == (int)sizeof(st_index_t) ? 1 : -1];
+#define SIZEOF_ST_INDEX_T SIZEOF_VOIDP
+
+struct st_hash_type {
+    int (*compare)(ANYARGS /*st_data_t, st_data_t*/); /* st_compare_func* */
+    st_index_t (*hash)(ANYARGS /*st_data_t*/);        /* st_hash_func* */
+};
+
+#define ST_INDEX_BITS (SIZEOF_ST_INDEX_T * CHAR_BIT)
+
+#if defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR) && defined(HAVE_BUILTIN___BUILTIN_TYPES_COMPATIBLE_P)
+# define ST_DATA_COMPATIBLE_P(type) \
+   __builtin_choose_expr(__builtin_types_compatible_p(type, st_data_t), 1, 0)
+#else
+# define ST_DATA_COMPATIBLE_P(type) 0
+#endif
+
+typedef struct st_table_entry st_table_entry;
+
+struct st_table_entry; /* defined in st.c */
+
+struct st_table {
+    /* Cached features of the table -- see st.c for more details.  */
+    unsigned char entry_power, bin_power, size_ind;
+    /* How many times the table was rebuilt.  */
+    unsigned int rebuilds_num;
+    const struct st_hash_type *type;
+    /* Number of entries currently in the table.  */
+    st_index_t num_entries;
+    /* Array of bins used for access by keys.  */
+    st_index_t *bins;
+    /* Start and bound index of entries in array entries.
+       entries_starts and entries_bound are in interval
+       [0,allocated_entries].  */
+    st_index_t entries_start, entries_bound;
+    /* Array of size 2^entry_power.  */
+    st_table_entry *entries;
+};
+
+#define st_is_member(table,key) st_lookup((table),(key),(st_data_t *)0)
+
+enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK};
+
+st_table *st_init_table(const struct st_hash_type *);
+st_table *st_init_table_with_size(const struct st_hash_type *, st_index_t);
+st_table *st_init_numtable(void);
+st_table *st_init_numtable_with_size(st_index_t);
+st_table *st_init_strtable(void);
+st_table *st_init_strtable_with_size(st_index_t);
+st_table *st_init_strcasetable(void);
+st_table *st_init_strcasetable_with_size(st_index_t);
+int st_delete(st_table *, st_data_t *, st_data_t *); /* returns 0:notfound 1:deleted */
+int st_delete_safe(st_table *, st_data_t *, st_data_t *, st_data_t);
+int st_shift(st_table *, st_data_t *, st_data_t *); /* returns 0:notfound 1:deleted */
+int st_insert(st_table *, st_data_t, st_data_t);
+int st_insert2(st_table *, st_data_t, st_data_t, st_data_t (*)(st_data_t));
+int st_lookup(st_table *, st_data_t, st_data_t *);
+int st_get_key(st_table *, st_data_t, st_data_t *);
+typedef int st_update_callback_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing);
+/* *key may be altered, but must equal to the old key, i.e., the
+ * results of hash() are same and compare() returns 0, otherwise the
+ * behavior is undefined */
+int st_update(st_table *table, st_data_t key, st_update_callback_func *func, st_data_t arg);
+int st_foreach(st_table *, int (*)(ANYARGS), st_data_t);
+int st_foreach_check(st_table *, int (*)(ANYARGS), st_data_t, st_data_t);
+st_index_t st_keys(st_table *table, st_data_t *keys, st_index_t size);
+st_index_t st_keys_check(st_table *table, st_data_t *keys, st_index_t size, st_data_t never);
+st_index_t st_values(st_table *table, st_data_t *values, st_index_t size);
+st_index_t st_values_check(st_table *table, st_data_t *values, st_index_t size, st_data_t never);
+void st_add_direct(st_table *, st_data_t, st_data_t);
+void st_free_table(st_table *);
+void st_cleanup_safe(st_table *, st_data_t);
+void st_clear(st_table *);
+st_table *st_copy(st_table *);
+int st_numcmp(st_data_t, st_data_t);
+st_index_t st_numhash(st_data_t);
+int st_locale_insensitive_strcasecmp(const char *s1, const char *s2);
+int st_locale_insensitive_strncasecmp(const char *s1, const char *s2, size_t n);
+#define st_strcasecmp st_locale_insensitive_strcasecmp
+#define st_strncasecmp st_locale_insensitive_strncasecmp
+size_t st_memsize(const st_table *);
+st_index_t st_hash(const void *ptr, size_t len, st_index_t h);
+st_index_t st_hash_uint32(st_index_t h, uint32_t i);
+st_index_t st_hash_uint(st_index_t h, st_index_t i);
+st_index_t st_hash_end(st_index_t h);
+st_index_t st_hash_start(st_index_t h);
+#define st_hash_start(h) ((st_index_t)(h))
+
+RUBY_SYMBOL_EXPORT_END
+
+#if defined(__cplusplus)
+#if 0
+{ /* satisfy cc-mode */
+#endif
+}  /* extern "C" { */
+#endif
+
+#endif /* RUBY_ST_H */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/.cproject
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/.cproject	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/.cproject	(revision 331)
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.1903012754">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.1903012754" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactExtension="a" artifactName="openssl" buildArtefactType="com.renesas.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=com.renesas.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf *.lst *.lis *.lpp *.map" description="" id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.1903012754" name="Debug" parent="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id">
+					<folderInfo id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.1903012754." name="/" resourcePath="">
+						<toolChain id="com.renesas.cdt.library.rz.debug.win32.toolchain.Id.540253432" name="KPIT GNUARM-NONE-EABI Toolchain" superClass="com.renesas.cdt.library.rz.debug.win32.toolchain.Id">
+							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.PE" id="com.renesas.cdt.rz.libraryProject.debug.win32.targetplatform.Id.1297347820" name="Target Platform" osList="win32,linux" superClass="com.renesas.cdt.rz.libraryProject.debug.win32.targetplatform.Id"/>
+							<builder buildPath="${workspace_loc:/openssl-1.1.0e}/" id="com.renesas.cdt.rz.library.project.debug.win32.builder.Id.620328335" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Builder" parallelBuildOn="true" parallelizationNumber="optimal" stopOnErr="false" superClass="com.renesas.cdt.rz.library.project.debug.win32.builder.Id"/>
+							<tool id="com.renesas.cdt.rz.libraryProject.debug.win32.tool.compiler.Id.1981970595" name="Compiler" superClass="com.renesas.cdt.rz.libraryProject.debug.win32.tool.compiler.Id">
+								<option defaultValue="true" id="com.renesas.cdt.core.Compiler.option.misc2.1789506130" name="æ¨æºã·ã¹ãã ã»ãã£ã¬ã¯ããªã¼ã§ãããã¼ã»ãã¡ã¤ã«ãæ¤ç´¢ããªã (-nostdinc)" superClass="com.renesas.cdt.core.Compiler.option.misc2" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.dataEndian.1689785149" name="ã¨ã³ãã£ã¢ã³" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.dataEndian" value="Little-endian" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.instructionset.576267093" name="å½ä»¤ã»ãã" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.instructionset" value="ARM" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.interworking.567214817" name="ã¤ã³ã¿ã¼ã»ã¯ã¼ã­ã³ã°" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.interworking" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.targetfpu.478287503" name="ã¿ã¼ã²ãã FPU (-mfpu)" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.targetfpu" value="vfp" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.floatingpointabi.1251458450" name="æµ®åå°æ°ç¹ ABI (-mfloat-abi=name)" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.floatingpointabi" value="Hard" valueType="enumerated"/>
+								<option id="com.renesas.cdt.core.Compiler.option.warnStackSize.1509465119" name="Warn if stack size exceeds the limit (-Wstack-usage) (H')" superClass="com.renesas.cdt.core.Compiler.option.warnStackSize" value="100" valueType="string"/>
+								<option id="com.renesas.cdt.core.Compiler.option.CPUSeries.122202256" name="CPU ã·ãªã¼ãº" superClass="com.renesas.cdt.core.Compiler.option.CPUSeries" value="RZ/A" valueType="string"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.architecture.206571745" name="ã¢ã¼ã­ãã¯ãã£ã¼" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.architecture" value="armv7-a" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.cpuType.919313389" name="CPU ã¿ã¤ã" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.cpuType" value="cortex-a9" valueType="enumerated"/>
+								<option id="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal.2136745540" name="Decimal representation of '-Wstack-usage'" superClass="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal" value="256" valueType="string"/>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.core.Compiler.option.includeFileDir.1522159594" name="ã¤ã³ã¯ã«ã¼ãã»ãã¡ã¤ã«ã»ãã£ã¬ã¯ããªã¼" superClass="com.renesas.cdt.core.Compiler.option.includeFileDir" valueType="includePath">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/musl-1.1.18/include}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/zlib-1.2.11}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/include}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/crypto/include}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;"/>
+								</option>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.rz.Debug.Compiler.option.library.macroDefines.432902018" name="ãã¯ã­å®ç¾©" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.macroDefines" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="OPENSSL_NO_DYNAMIC_ENGINE"/>
+									<listOptionValue builtIn="false" value="OPENSSLDIR="/>
+									<listOptionValue builtIn="false" value="ENGINESDIR="/>
+									<listOptionValue builtIn="false" value="SSIZE_MAX=LONG_MAX"/>
+									<listOptionValue builtIn="false" value="ZLIB"/>
+									<listOptionValue builtIn="false" value="__unix"/>
+								</option>
+								<option id="com.renesas.cdt.core.Compiler.option.misc19.1425751965" name="åé¢æ°ããåºåãã¡ã¤ã«å
+ã®å¯¾å¿ããã»ã¯ã·ã§ã³ã«é
+ç½®ãã (-ffunction-sections)" superClass="com.renesas.cdt.core.Compiler.option.misc19" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.core.Compiler.option.misc53.7356670" name="åãã¼ã¿é 
+ç®ããåºåãã¡ã¤ã«å
+ã®å¯¾å¿ããã»ã¯ã·ã§ã³ã«é
+ç½®ãã(-fdata-sections)" superClass="com.renesas.cdt.core.Compiler.option.misc53" value="true" valueType="boolean"/>
+								<option command="-Wa,-adlhn=&quot;$(basename $(notdir $&lt;)).lst&quot;" id="com.renesas.cdt.core.Compiler.option.generateListFile.1830349899" name="ãªã¹ããã¡ã¤ã«ãçæãã (-Wa,-a)" superClass="com.renesas.cdt.core.Compiler.option.generateListFile" value="false" valueType="boolean"/>
+								<option id="com.renesas.cdt.core.Compiler.option.device.1575912854" name="Device" superClass="com.renesas.cdt.core.Compiler.option.device" value="R7S721001" valueType="string"/>
+								<option id="com.renesas.cdt.core.Compiler.option.deviceShortName.273773844" name="DeviceShortName" superClass="com.renesas.cdt.core.Compiler.option.deviceShortName" value="R7S721001" valueType="string"/>
+								<inputType id="%Base.Compiler.C.InputType.Id.356694362" name="C å
+¥å" superClass="%Base.Compiler.C.InputType.Id"/>
+								<inputType id="Base.Compiler.CPP.InputType.Id.927630817" name="C++ å
+¥å" superClass="Base.Compiler.CPP.InputType.Id"/>
+							</tool>
+							<tool id="com.renesas.cdt.library.rz.Debug.win32.tool.assembler.Id.1100102428" name="Assembler" superClass="com.renesas.cdt.library.rz.Debug.win32.tool.assembler.Id">
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.dataEndian.707286256" name="ã¨ã³ãã£ã¢ã³" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.dataEndian" value="Little-endian" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.instructionset.834259922" name="å½ä»¤ã»ãã" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.instructionset" value="ARM" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.targetfpu.596117943" name="ã¿ã¼ã²ãã FPU (-mfpu)" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.targetfpu" value="vfp" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.floatingpointabi.1786953502" name="æµ®åå°æ°ç¹ ABI (-mfloat-abi=name)" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.floatingpointabi" value="Hard" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.architecture.1312656656" name="ã¢ã¼ã­ãã¯ãã£ã¼" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.architecture" value="armv7-a" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.cpuType.1666771622" name="CPU ã¿ã¤ã" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.cpuType" value="cortex-a9" valueType="enumerated"/>
+								<inputType id="%Base.Assembler.inputType.Id.1787228755" name="ã¢ã»ã³ãã©ã¼å
+¥åã¿ã¤ã" superClass="%Base.Assembler.inputType.Id"/>
+							</tool>
+							<tool id="com.renesas.cdt.library.rz.debug.win32.tool.archive.Id.94214024" name="Archive Generator" superClass="com.renesas.cdt.library.rz.debug.win32.tool.archive.Id"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry excluding="crypto/LPdir_unix.c" flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="openssl.com.renesas.cdt.rz.library.projectType.Id.1194203901" name="Static Library (Renesas)" projectType="com.renesas.cdt.rz.library.projectType.Id"/>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+	<storageModule moduleId="refreshScope" versionNumber="2">
+		<configuration configurationName="Debug">
+			<resource resourceType="PROJECT" workspacePath="/openssl"/>
+		</configuration>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
+</cproject>
Index: EcnlProtoTool/trunk/openssl-1.1.0e/.info
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/.info	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/.info	(revision 331)
@@ -0,0 +1,7 @@
+TOOL_CHAIN=KPIT GNUARM-NONE-EABI Toolchain
+VERSION=v16.01
+TC_INSTALL=C:\Program Files (x86)\KPIT\GNUARM-NONEv16.01-EABI\arm-none-eabi\arm-none-eabi\
+GCC_STRING=5.2-GNUARM-NONE_v16.01
+VERSION_IDE=
+E2STUDIO_VERSION=5.4.0.018
+ACTIVE_CONFIGURATION=Debug
Index: EcnlProtoTool/trunk/openssl-1.1.0e/.project
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/.project	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/.project	(revision 331)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>openssl</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>com.renesas.cdt.core.genmakebuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>com.renesas.cdt.core.kpitcnature</nature>
+		<nature>com.renesas.cdt.core.kpitccnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+	</natures>
+</projectDescription>
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ACKNOWLEDGEMENTS
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ACKNOWLEDGEMENTS	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ACKNOWLEDGEMENTS	(revision 331)
@@ -0,0 +1,2 @@
+Please https://www.openssl.org/community/thanks.html for the current
+acknowledgements.
Index: EcnlProtoTool/trunk/openssl-1.1.0e/AUTHORS
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/AUTHORS	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/AUTHORS	(revision 331)
@@ -0,0 +1,21 @@
+    Andy Polyakov
+    Ben Laurie
+    Bodo Möller
+    Emilia Käsper
+    Eric Young
+    Geoff Thorpe
+    Holger Reif
+    Kurt Roeckx
+    Lutz Jänicke
+    Mark J. Cox
+    Matt Caswell
+    Nils Larsch
+    Paul C. Sutton
+    Ralf S. Engelschall
+    Rich Salz
+    Richard Levitte
+    Stephen Henson
+    Steve Marquess
+    Tim Hudson
+    Ulf Möller
+    Viktor Dukhovni
Index: EcnlProtoTool/trunk/openssl-1.1.0e/CHANGES
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/CHANGES	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/CHANGES	(revision 331)
@@ -0,0 +1,12454 @@
+
+ OpenSSL CHANGES
+ _______________
+
+ Changes between 1.1.0d and 1.1.0e [16 Feb 2017]
+
+  *) Encrypt-Then-Mac renegotiation crash
+
+     During a renegotiation handshake if the Encrypt-Then-Mac extension is
+     negotiated where it was not in the original handshake (or vice-versa) then
+     this can cause OpenSSL to crash (dependant on ciphersuite). Both clients
+     and servers are affected.
+
+     This issue was reported to OpenSSL by Joe Orton (Red Hat).
+     (CVE-2017-3733)
+     [Matt Caswell]
+
+ Changes between 1.1.0c and 1.1.0d [26 Jan 2017]
+
+  *) Truncated packet could crash via OOB read
+
+     If one side of an SSL/TLS path is running on a 32-bit host and a specific
+     cipher is being used, then a truncated packet can cause that host to
+     perform an out-of-bounds read, usually resulting in a crash.
+
+     This issue was reported to OpenSSL by Robert ÅwiÄcki of Google.
+     (CVE-2017-3731)
+     [Andy Polyakov]
+
+  *) Bad (EC)DHE parameters cause a client crash
+
+     If a malicious server supplies bad parameters for a DHE or ECDHE key
+     exchange then this can result in the client attempting to dereference a
+     NULL pointer leading to a client crash. This could be exploited in a Denial
+     of Service attack.
+
+     This issue was reported to OpenSSL by Guido Vranken.
+     (CVE-2017-3730)
+     [Matt Caswell]
+
+  *) BN_mod_exp may produce incorrect results on x86_64
+
+     There is a carry propagating bug in the x86_64 Montgomery squaring
+     procedure. No EC algorithms are affected. Analysis suggests that attacks
+     against RSA and DSA as a result of this defect would be very difficult to
+     perform and are not believed likely. Attacks against DH are considered just
+     feasible (although very difficult) because most of the work necessary to
+     deduce information about a private key may be performed offline. The amount
+     of resources required for such an attack would be very significant and
+     likely only accessible to a limited number of attackers. An attacker would
+     additionally need online access to an unpatched system using the target
+     private key in a scenario with persistent DH parameters and a private
+     key that is shared between multiple clients. For example this can occur by
+     default in OpenSSL DHE based SSL/TLS ciphersuites. Note: This issue is very
+     similar to CVE-2015-3193 but must be treated as a separate problem.
+
+     This issue was reported to OpenSSL by the OSS-Fuzz project.
+     (CVE-2017-3732)
+     [Andy Polyakov]
+
+ Changes between 1.1.0b and 1.1.0c [10 Nov 2016]
+
+  *) ChaCha20/Poly1305 heap-buffer-overflow
+
+     TLS connections using *-CHACHA20-POLY1305 ciphersuites are susceptible to
+     a DoS attack by corrupting larger payloads. This can result in an OpenSSL
+     crash. This issue is not considered to be exploitable beyond a DoS.
+
+     This issue was reported to OpenSSL by Robert ÅwiÄcki (Google Security Team)
+     (CVE-2016-7054)
+     [Richard Levitte]
+
+  *) CMS Null dereference
+
+     Applications parsing invalid CMS structures can crash with a NULL pointer
+     dereference. This is caused by a bug in the handling of the ASN.1 CHOICE
+     type in OpenSSL 1.1.0 which can result in a NULL value being passed to the
+     structure callback if an attempt is made to free certain invalid encodings.
+     Only CHOICE structures using a callback which do not handle NULL value are
+     affected.
+
+     This issue was reported to OpenSSL by Tyler Nighswander of ForAllSecure.
+     (CVE-2016-7053)
+     [Stephen Henson]
+
+  *) Montgomery multiplication may produce incorrect results
+
+     There is a carry propagating bug in the Broadwell-specific Montgomery
+     multiplication procedure that handles input lengths divisible by, but
+     longer than 256 bits. Analysis suggests that attacks against RSA, DSA
+     and DH private keys are impossible. This is because the subroutine in
+     question is not used in operations with the private key itself and an input
+     of the attacker's direct choice. Otherwise the bug can manifest itself as
+     transient authentication and key negotiation failures or reproducible
+     erroneous outcome of public-key operations with specially crafted input.
+     Among EC algorithms only Brainpool P-512 curves are affected and one
+     presumably can attack ECDH key negotiation. Impact was not analyzed in
+     detail, because pre-requisites for attack are considered unlikely. Namely
+     multiple clients have to choose the curve in question and the server has to
+     share the private key among them, neither of which is default behaviour.
+     Even then only clients that chose the curve will be affected.
+
+     This issue was publicly reported as transient failures and was not
+     initially recognized as a security issue. Thanks to Richard Morgan for
+     providing reproducible case.
+     (CVE-2016-7055)
+     [Andy Polyakov]
+
+  *) OpenSSL now fails if it receives an unrecognised record type in TLS1.0
+     or TLS1.1. Previously this only happened in SSLv3 and TLS1.2. This is to
+     prevent issues where no progress is being made and the peer continually
+     sends unrecognised record types, using up resources processing them.
+     [Matt Caswell]
+
+  *) Removed automatic addition of RPATH in shared libraries and executables,
+     as this was a remainder from OpenSSL 1.0.x and isn't needed any more.
+     [Richard Levitte]
+
+ Changes between 1.1.0a and 1.1.0b [26 Sep 2016]
+
+  *) Fix Use After Free for large message sizes
+
+     The patch applied to address CVE-2016-6307 resulted in an issue where if a
+     message larger than approx 16k is received then the underlying buffer to
+     store the incoming message is reallocated and moved. Unfortunately a
+     dangling pointer to the old location is left which results in an attempt to
+     write to the previously freed location. This is likely to result in a
+     crash, however it could potentially lead to execution of arbitrary code.
+
+     This issue only affects OpenSSL 1.1.0a.
+
+     This issue was reported to OpenSSL by Robert ÅwiÄcki.
+     (CVE-2016-6309)
+     [Matt Caswell]
+
+ Changes between 1.1.0 and 1.1.0a [22 Sep 2016]
+
+  *) OCSP Status Request extension unbounded memory growth
+
+     A malicious client can send an excessively large OCSP Status Request
+     extension. If that client continually requests renegotiation, sending a
+     large OCSP Status Request extension each time, then there will be unbounded
+     memory growth on the server. This will eventually lead to a Denial Of
+     Service attack through memory exhaustion. Servers with a default
+     configuration are vulnerable even if they do not support OCSP. Builds using
+     the "no-ocsp" build time option are not affected.
+
+     This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.)
+     (CVE-2016-6304)
+     [Matt Caswell]
+
+  *) SSL_peek() hang on empty record
+
+     OpenSSL 1.1.0 SSL/TLS will hang during a call to SSL_peek() if the peer
+     sends an empty record. This could be exploited by a malicious peer in a
+     Denial Of Service attack.
+
+     This issue was reported to OpenSSL by Alex Gaynor.
+     (CVE-2016-6305)
+     [Matt Caswell]
+
+  *) Excessive allocation of memory in tls_get_message_header() and
+     dtls1_preprocess_fragment()
+
+     A (D)TLS message includes 3 bytes for its length in the header for the
+     message. This would allow for messages up to 16Mb in length. Messages of
+     this length are excessive and OpenSSL includes a check to ensure that a
+     peer is sending reasonably sized messages in order to avoid too much memory
+     being consumed to service a connection. A flaw in the logic of version
+     1.1.0 means that memory for the message is allocated too early, prior to
+     the excessive message length check. Due to way memory is allocated in
+     OpenSSL this could mean an attacker could force up to 21Mb to be allocated
+     to service a connection. This could lead to a Denial of Service through
+     memory exhaustion. However, the excessive message length check still takes
+     place, and this would cause the connection to immediately fail. Assuming
+     that the application calls SSL_free() on the failed conneciton in a timely
+     manner then the 21Mb of allocated memory will then be immediately freed
+     again. Therefore the excessive memory allocation will be transitory in
+     nature. This then means that there is only a security impact if:
+
+     1) The application does not call SSL_free() in a timely manner in the event
+     that the connection fails
+     or
+     2) The application is working in a constrained environment where there is
+     very little free memory
+     or
+     3) The attacker initiates multiple connection attempts such that there are
+     multiple connections in a state where memory has been allocated for the
+     connection; SSL_free() has not yet been called; and there is insufficient
+     memory to service the multiple requests.
+
+     Except in the instance of (1) above any Denial Of Service is likely to be
+     transitory because as soon as the connection fails the memory is
+     subsequently freed again in the SSL_free() call. However there is an
+     increased risk during this period of application crashes due to the lack of
+     memory - which would then mean a more serious Denial of Service.
+
+     This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.)
+     (CVE-2016-6307 and CVE-2016-6308)
+     [Matt Caswell]
+
+  *) solaris-x86-cc, i.e. 32-bit configuration with vendor compiler,
+     had to be removed. Primary reason is that vendor assembler can't
+     assemble our modules with -KPIC flag. As result it, assembly
+     support, was not even available as option. But its lack means
+     lack of side-channel resistant code, which is incompatible with
+     security by todays standards. Fortunately gcc is readily available
+     prepackaged option, which we firmly point at...
+     [Andy Polyakov]
+
+ Changes between 1.0.2h and 1.1.0  [25 Aug 2016]
+
+  *) Windows command-line tool supports UTF-8 opt-in option for arguments
+     and console input. Setting OPENSSL_WIN32_UTF8 environment variable
+     (to any value) allows Windows user to access PKCS#12 file generated
+     with Windows CryptoAPI and protected with non-ASCII password, as well
+     as files generated under UTF-8 locale on Linux also protected with
+     non-ASCII password.
+     [Andy Polyakov]
+
+  *) To mitigate the SWEET32 attack (CVE-2016-2183), 3DES cipher suites
+     have been disabled by default and removed from DEFAULT, just like RC4.
+     See the RC4 item below to re-enable both.
+     [Rich Salz]
+
+  *) The method for finding the storage location for the Windows RAND seed file
+     has changed. First we check %RANDFILE%. If that is not set then we check
+     the directories %HOME%, %USERPROFILE% and %SYSTEMROOT% in that order. If
+     all else fails we fall back to C:\.
+     [Matt Caswell]
+
+  *) The EVP_EncryptUpdate() function has had its return type changed from void
+     to int. A return of 0 indicates and error while a return of 1 indicates
+     success.
+     [Matt Caswell]
+
+  *) The flags RSA_FLAG_NO_CONSTTIME, DSA_FLAG_NO_EXP_CONSTTIME and
+     DH_FLAG_NO_EXP_CONSTTIME which previously provided the ability to switch
+     off the constant time implementation for RSA, DSA and DH have been made
+     no-ops and deprecated.
+     [Matt Caswell]
+
+  *) Windows RAND implementation was simplified to only get entropy by
+     calling CryptGenRandom(). Various other RAND-related tickets
+     were also closed.
+     [Joseph Wylie Yandle, Rich Salz]
+
+  *) The stack and lhash API's were renamed to start with OPENSSL_SK_
+     and OPENSSL_LH_, respectively.  The old names are available
+     with API compatibility.  They new names are now completely documented.
+     [Rich Salz]
+
+  *) Unify TYPE_up_ref(obj) methods signature.
+     SSL_CTX_up_ref(), SSL_up_ref(), X509_up_ref(), EVP_PKEY_up_ref(),
+     X509_CRL_up_ref(), X509_OBJECT_up_ref_count() methods are now returning an
+     int (instead of void) like all others TYPE_up_ref() methods.
+     So now these methods also check the return value of CRYPTO_atomic_add(),
+     and the validity of object reference counter.
+     [fdasilvayy@gmail.com]
+
+  *) With Windows Visual Studio builds, the .pdb files are installed
+     alongside the installed libraries and executables.  For a static
+     library installation, ossl_static.pdb is the associate compiler
+     generated .pdb file to be used when linking programs.
+     [Richard Levitte]
+
+  *) Remove openssl.spec.  Packaging files belong with the packagers.
+     [Richard Levitte]
+
+  *) Automatic Darwin/OSX configuration has had a refresh, it will now
+     recognise x86_64 architectures automatically.  You can still decide
+     to build for a different bitness with the environment variable
+     KERNEL_BITS (can be 32 or 64), for example:
+
+         KERNEL_BITS=32 ./config
+
+     [Richard Levitte]
+
+  *) Change default algorithms in pkcs8 utility to use PKCS#5 v2.0,
+     256 bit AES and HMAC with SHA256.
+     [Steve Henson]
+
+  *) Remove support for MIPS o32 ABI on IRIX (and IRIX only).
+     [Andy Polyakov]
+
+  *) Triple-DES ciphers have been moved from HIGH to MEDIUM.
+     [Rich Salz]
+
+  *) To enable users to have their own config files and build file templates,
+     Configure looks in the directory indicated by the environment variable
+     OPENSSL_LOCAL_CONFIG_DIR as well as the in-source Configurations/
+     directory.  On VMS, OPENSSL_LOCAL_CONFIG_DIR is expected to be a logical
+     name and is used as is.
+     [Richard Levitte]
+
+  *) The following datatypes were made opaque: X509_OBJECT, X509_STORE_CTX,
+     X509_STORE, X509_LOOKUP, and X509_LOOKUP_METHOD.  The unused type
+     X509_CERT_FILE_CTX was removed.
+     [Rich Salz]
+
+  *) "shared" builds are now the default. To create only static libraries use
+     the "no-shared" Configure option.
+     [Matt Caswell]
+
+  *) Remove the no-aes, no-hmac, no-rsa, no-sha and no-md5 Configure options.
+     All of these option have not worked for some while and are fundamental
+     algorithms.
+     [Matt Caswell]
+
+  *) Make various cleanup routines no-ops and mark them as deprecated. Most
+     global cleanup functions are no longer required because they are handled
+     via auto-deinit (see OPENSSL_init_crypto and OPENSSL_init_ssl man pages).
+     Explicitly de-initing can cause problems (e.g. where a library that uses
+     OpenSSL de-inits, but an application is still using it). The affected
+     functions are CONF_modules_free(), ENGINE_cleanup(), OBJ_cleanup(),
+     EVP_cleanup(), BIO_sock_cleanup(), CRYPTO_cleanup_all_ex_data(),
+     RAND_cleanup(), SSL_COMP_free_compression_methods(), ERR_free_strings() and
+     COMP_zlib_cleanup().
+     [Matt Caswell]
+
+  *) --strict-warnings no longer enables runtime debugging options
+     such as REF_DEBUG. Instead, debug options are automatically
+     enabled with '--debug' builds.
+     [Andy Polyakov, Emilia KÃ¤sper]
+
+  *) Made DH and DH_METHOD opaque. The structures for managing DH objects
+     have been moved out of the public header files. New functions for managing
+     these have been added.
+     [Matt Caswell]
+
+  *) Made RSA and RSA_METHOD opaque. The structures for managing RSA
+     objects have been moved out of the public header files. New
+     functions for managing these have been added.
+     [Richard Levitte]
+
+  *) Made DSA and DSA_METHOD opaque. The structures for managing DSA objects
+     have been moved out of the public header files. New functions for managing
+     these have been added.
+     [Matt Caswell]
+
+  *) Made BIO and BIO_METHOD opaque. The structures for managing BIOs have been
+     moved out of the public header files. New functions for managing these
+     have been added.
+     [Matt Caswell]
+
+  *) Removed no-rijndael as a config option. Rijndael is an old name for AES.
+     [Matt Caswell]
+
+  *) Removed the mk1mf build scripts.
+     [Richard Levitte]
+
+  *) Headers are now wrapped, if necessary, with OPENSSL_NO_xxx, so
+     it is always safe to #include a header now.
+     [Rich Salz]
+
+  *) Removed the aged BC-32 config and all its supporting scripts
+     [Richard Levitte]
+
+  *) Removed support for Ultrix, Netware, and OS/2.
+     [Rich Salz]
+
+  *) Add support for HKDF.
+     [Alessandro Ghedini]
+
+  *) Add support for blake2b and blake2s
+     [Bill Cox]
+
+  *) Added support for "pipelining". Ciphers that have the
+     EVP_CIPH_FLAG_PIPELINE flag set have a capability to process multiple
+     encryptions/decryptions simultaneously. There are currently no built-in
+     ciphers with this property but the expectation is that engines will be able
+     to offer it to significantly improve throughput. Support has been extended
+     into libssl so that multiple records for a single connection can be
+     processed in one go (for >=TLS 1.1).
+     [Matt Caswell]
+
+  *) Added the AFALG engine. This is an async capable engine which is able to
+     offload work to the Linux kernel. In this initial version it only supports
+     AES128-CBC. The kernel must be version 4.1.0 or greater.
+     [Catriona Lucey]
+
+  *) OpenSSL now uses a new threading API. It is no longer necessary to
+     set locking callbacks to use OpenSSL in a multi-threaded environment. There
+     are two supported threading models: pthreads and windows threads. It is
+     also possible to configure OpenSSL at compile time for "no-threads". The
+     old threading API should no longer be used. The functions have been
+     replaced with "no-op" compatibility macros.
+     [Alessandro Ghedini, Matt Caswell]
+
+  *) Modify behavior of ALPN to invoke callback after SNI/servername
+     callback, such that updates to the SSL_CTX affect ALPN.
+     [Todd Short]
+
+  *) Add SSL_CIPHER queries for authentication and key-exchange.
+     [Todd Short]
+
+  *) Changes to the DEFAULT cipherlist:
+       - Prefer (EC)DHE handshakes over plain RSA.
+       - Prefer AEAD ciphers over legacy ciphers.
+       - Prefer ECDSA over RSA when both certificates are available.
+       - Prefer TLSv1.2 ciphers/PRF.
+       - Remove DSS, SEED, IDEA, CAMELLIA, and AES-CCM from the
+         default cipherlist.
+     [Emilia KÃ¤sper]
+
+  *) Change the ECC default curve list to be this, in order: x25519,
+     secp256r1, secp521r1, secp384r1.
+     [Rich Salz]
+
+  *) RC4 based libssl ciphersuites are now classed as "weak" ciphers and are
+     disabled by default. They can be re-enabled using the
+     enable-weak-ssl-ciphers option to Configure.
+     [Matt Caswell]
+
+  *) If the server has ALPN configured, but supports no protocols that the
+     client advertises, send a fatal "no_application_protocol" alert.
+     This behaviour is SHALL in RFC 7301, though it isn't universally
+     implemented by other servers.
+     [Emilia KÃ¤sper]
+
+  *) Add X25519 support.
+     Add ASN.1 and EVP_PKEY methods for X25519. This includes support
+     for public and private key encoding using the format documented in
+     draft-ietf-curdle-pkix-02. The coresponding EVP_PKEY method supports
+     key generation and key derivation.
+
+     TLS support complies with draft-ietf-tls-rfc4492bis-08 and uses
+     X25519(29).
+     [Steve Henson]
+
+  *) Deprecate SRP_VBASE_get_by_user.
+     SRP_VBASE_get_by_user had inconsistent memory management behaviour.
+     In order to fix an unavoidable memory leak (CVE-2016-0798),
+     SRP_VBASE_get_by_user was changed to ignore the "fake user" SRP
+     seed, even if the seed is configured.
+
+     Users should use SRP_VBASE_get1_by_user instead. Note that in
+     SRP_VBASE_get1_by_user, caller must free the returned value. Note
+     also that even though configuring the SRP seed attempts to hide
+     invalid usernames by continuing the handshake with fake
+     credentials, this behaviour is not constant time and no strong
+     guarantees are made that the handshake is indistinguishable from
+     that of a valid user.
+     [Emilia KÃ¤sper]
+
+  *) Configuration change; it's now possible to build dynamic engines
+     without having to build shared libraries and vice versa.  This
+     only applies to the engines in engines/, those in crypto/engine/
+     will always be built into libcrypto (i.e. "static").
+
+     Building dynamic engines is enabled by default; to disable, use
+     the configuration option "disable-dynamic-engine".
+
+     The only requirements for building dynamic engines are the
+     presence of the DSO module and building with position independent
+     code, so they will also automatically be disabled if configuring
+     with "disable-dso" or "disable-pic".
+
+     The macros OPENSSL_NO_STATIC_ENGINE and OPENSSL_NO_DYNAMIC_ENGINE
+     are also taken away from openssl/opensslconf.h, as they are
+     irrelevant.
+     [Richard Levitte]
+
+  *) Configuration change; if there is a known flag to compile
+     position independent code, it will always be applied on the
+     libcrypto and libssl object files, and never on the application
+     object files.  This means other libraries that use routines from
+     libcrypto / libssl can be made into shared libraries regardless
+     of how OpenSSL was configured.
+
+     If this isn't desirable, the configuration options "disable-pic"
+     or "no-pic" can be used to disable the use of PIC.  This will
+     also disable building shared libraries and dynamic engines.
+     [Richard Levitte]
+
+  *) Removed JPAKE code.  It was experimental and has no wide use.
+     [Rich Salz]
+
+  *) The INSTALL_PREFIX Makefile variable has been renamed to
+     DESTDIR.  That makes for less confusion on what this variable
+     is for.  Also, the configuration option --install_prefix is
+     removed.
+     [Richard Levitte]
+
+  *) Heartbeat for TLS has been removed and is disabled by default
+     for DTLS; configure with enable-heartbeats.  Code that uses the
+     old #define's might need to be updated.
+     [Emilia KÃ¤sper, Rich Salz]
+
+  *) Rename REF_CHECK to REF_DEBUG.
+     [Rich Salz]
+
+  *) New "unified" build system
+
+     The "unified" build system is aimed to be a common system for all
+     platforms we support.  With it comes new support for VMS.
+
+     This system builds supports building in a different directory tree
+     than the source tree.  It produces one Makefile (for unix family
+     or lookalikes), or one descrip.mms (for VMS).
+
+     The source of information to make the Makefile / descrip.mms is
+     small files called 'build.info', holding the necessary
+     information for each directory with source to compile, and a
+     template in Configurations, like unix-Makefile.tmpl or
+     descrip.mms.tmpl.
+
+     With this change, the library names were also renamed on Windows
+     and on VMS.  They now have names that are closer to the standard
+     on Unix, and include the major version number, and in certain
+     cases, the architecture they are built for.  See "Notes on shared
+     libraries" in INSTALL.
+
+     We rely heavily on the perl module Text::Template.
+     [Richard Levitte]
+
+  *) Added support for auto-initialisation and de-initialisation of the library.
+     OpenSSL no longer requires explicit init or deinit routines to be called,
+     except in certain circumstances. See the OPENSSL_init_crypto() and
+     OPENSSL_init_ssl() man pages for further information.
+     [Matt Caswell]
+
+  *) The arguments to the DTLSv1_listen function have changed. Specifically the
+     "peer" argument is now expected to be a BIO_ADDR object.
+
+  *) Rewrite of BIO networking library. The BIO library lacked consistent
+     support of IPv6, and adding it required some more extensive
+     modifications.  This introduces the BIO_ADDR and BIO_ADDRINFO types,
+     which hold all types of addresses and chains of address information.
+     It also introduces a new API, with functions like BIO_socket,
+     BIO_connect, BIO_listen, BIO_lookup and a rewrite of BIO_accept.
+     The source/sink BIOs BIO_s_connect, BIO_s_accept and BIO_s_datagram
+     have been adapted accordingly.
+     [Richard Levitte]
+
+  *) RSA_padding_check_PKCS1_type_1 now accepts inputs with and without
+     the leading 0-byte.
+     [Emilia KÃ¤sper]
+
+  *) CRIME protection: disable compression by default, even if OpenSSL is
+     compiled with zlib enabled. Applications can still enable compression
+     by calling SSL_CTX_clear_options(ctx, SSL_OP_NO_COMPRESSION), or by
+     using the SSL_CONF library to configure compression.
+     [Emilia KÃ¤sper]
+
+  *) The signature of the session callback configured with
+     SSL_CTX_sess_set_get_cb was changed. The read-only input buffer
+     was explicitly marked as 'const unsigned char*' instead of
+     'unsigned char*'.
+     [Emilia KÃ¤sper]
+
+  *) Always DPURIFY. Remove the use of uninitialized memory in the
+     RNG, and other conditional uses of DPURIFY. This makes -DPURIFY a no-op.
+     [Emilia KÃ¤sper]
+
+  *) Removed many obsolete configuration items, including
+        DES_PTR, DES_RISC1, DES_RISC2, DES_INT
+        MD2_CHAR, MD2_INT, MD2_LONG
+        BF_PTR, BF_PTR2
+        IDEA_SHORT, IDEA_LONG
+        RC2_SHORT, RC2_LONG, RC4_LONG, RC4_CHUNK, RC4_INDEX
+     [Rich Salz, with advice from Andy Polyakov]
+
+  *) Many BN internals have been moved to an internal header file.
+     [Rich Salz with help from Andy Polyakov]
+
+  *) Configuration and writing out the results from it has changed.
+     Files such as Makefile include/openssl/opensslconf.h and are now
+     produced through general templates, such as Makefile.in and
+     crypto/opensslconf.h.in and some help from the perl module
+     Text::Template.
+
+     Also, the center of configuration information is no longer
+     Makefile.  Instead, Configure produces a perl module in
+     configdata.pm which holds most of the config data (in the hash
+     table %config), the target data that comes from the target
+     configuration in one of the Configurations/*.conf files (in
+     %target).
+     [Richard Levitte]
+
+  *) To clarify their intended purposes, the Configure options
+     --prefix and --openssldir change their semantics, and become more
+     straightforward and less interdependent.
+
+     --prefix shall be used exclusively to give the location INSTALLTOP
+     where programs, scripts, libraries, include files and manuals are
+     going to be installed.  The default is now /usr/local.
+
+     --openssldir shall be used exclusively to give the default
+     location OPENSSLDIR where certificates, private keys, CRLs are
+     managed.  This is also where the default openssl.cnf gets
+     installed.
+     If the directory given with this option is a relative path, the
+     values of both the --prefix value and the --openssldir value will
+     be combined to become OPENSSLDIR.
+     The default for --openssldir is INSTALLTOP/ssl.
+
+     Anyone who uses --openssldir to specify where OpenSSL is to be
+     installed MUST change to use --prefix instead.
+     [Richard Levitte]
+
+  *) The GOST engine was out of date and therefore it has been removed. An up
+     to date GOST engine is now being maintained in an external repository.
+     See: https://wiki.openssl.org/index.php/Binaries. Libssl still retains
+     support for GOST ciphersuites (these are only activated if a GOST engine
+     is present).
+     [Matt Caswell]
+
+  *) EGD is no longer supported by default; use enable-egd when
+     configuring.
+     [Ben Kaduk and Rich Salz]
+
+  *) The distribution now has Makefile.in files, which are used to
+     create Makefile's when Configure is run.  *Configure must be run
+     before trying to build now.*
+     [Rich Salz]
+
+  *) The return value for SSL_CIPHER_description() for error conditions
+     has changed.
+     [Rich Salz]
+
+  *) Support for RFC6698/RFC7671 DANE TLSA peer authentication.
+
+     Obtaining and performing DNSSEC validation of TLSA records is
+     the application's responsibility.  The application provides
+     the TLSA records of its choice to OpenSSL, and these are then
+     used to authenticate the peer.
+
+     The TLSA records need not even come from DNS.  They can, for
+     example, be used to implement local end-entity certificate or
+     trust-anchor "pinning", where the "pin" data takes the form
+     of TLSA records, which can augment or replace verification
+     based on the usual WebPKI public certification authorities.
+     [Viktor Dukhovni]
+
+  *) Revert default OPENSSL_NO_DEPRECATED setting.  Instead OpenSSL
+     continues to support deprecated interfaces in default builds.
+     However, applications are strongly advised to compile their
+     source files with -DOPENSSL_API_COMPAT=0x10100000L, which hides
+     the declarations of all interfaces deprecated in 0.9.8, 1.0.0
+     or the 1.1.0 releases.
+
+     In environments in which all applications have been ported to
+     not use any deprecated interfaces OpenSSL's Configure script
+     should be used with the --api=1.1.0 option to entirely remove
+     support for the deprecated features from the library and
+     unconditionally disable them in the installed headers.
+     Essentially the same effect can be achieved with the "no-deprecated"
+     argument to Configure, except that this will always restrict
+     the build to just the latest API, rather than a fixed API
+     version.
+
+     As applications are ported to future revisions of the API,
+     they should update their compile-time OPENSSL_API_COMPAT define
+     accordingly, but in most cases should be able to continue to
+     compile with later releases.
+
+     The OPENSSL_API_COMPAT versions for 1.0.0, and 0.9.8 are
+     0x10000000L and 0x00908000L, respectively.  However those
+     versions did not support the OPENSSL_API_COMPAT feature, and
+     so applications are not typically tested for explicit support
+     of just the undeprecated features of either release.
+     [Viktor Dukhovni]
+
+  *) Add support for setting the minimum and maximum supported protocol.
+     It can bet set via the SSL_set_min_proto_version() and
+     SSL_set_max_proto_version(), or via the SSL_CONF's MinProtocol and
+     MaxProtcol.  It's recommended to use the new APIs to disable
+     protocols instead of disabling individual protocols using
+     SSL_set_options() or SSL_CONF's Protocol.  This change also
+     removes support for disabling TLS 1.2 in the OpenSSL TLS
+     client at compile time by defining OPENSSL_NO_TLS1_2_CLIENT.
+     [Kurt Roeckx]
+
+  *) Support for ChaCha20 and Poly1305 added to libcrypto and libssl.
+     [Andy Polyakov]
+
+  *) New EC_KEY_METHOD, this replaces the older ECDSA_METHOD and ECDH_METHOD
+     and integrates ECDSA and ECDH functionality into EC. Implementations can
+     now redirect key generation and no longer need to convert to or from
+     ECDSA_SIG format.
+
+     Note: the ecdsa.h and ecdh.h headers are now no longer needed and just
+     include the ec.h header file instead.
+     [Steve Henson]
+
+  *) Remove support for all 40 and 56 bit ciphers.  This includes all the export
+     ciphers who are no longer supported and drops support the ephemeral RSA key
+     exchange. The LOW ciphers currently doesn't have any ciphers in it.
+     [Kurt Roeckx]
+
+  *) Made EVP_MD_CTX, EVP_MD, EVP_CIPHER_CTX, EVP_CIPHER and HMAC_CTX
+     opaque.  For HMAC_CTX, the following constructors and destructors
+     were added:
+
+        HMAC_CTX *HMAC_CTX_new(void);
+        void HMAC_CTX_free(HMAC_CTX *ctx);
+
+     For EVP_MD and EVP_CIPHER, complete APIs to create, fill and
+     destroy such methods has been added.  See EVP_MD_meth_new(3) and
+     EVP_CIPHER_meth_new(3) for documentation.
+
+     Additional changes:
+     1) EVP_MD_CTX_cleanup(), EVP_CIPHER_CTX_cleanup() and
+        HMAC_CTX_cleanup() were removed.  HMAC_CTX_reset() and
+        EVP_MD_CTX_reset() should be called instead to reinitialise
+        an already created structure.
+     2) For consistency with the majority of our object creators and
+        destructors, EVP_MD_CTX_(create|destroy) were renamed to
+        EVP_MD_CTX_(new|free).  The old names are retained as macros
+        for deprecated builds.
+     [Richard Levitte]
+
+  *) Added ASYNC support. Libcrypto now includes the async sub-library to enable
+     cryptographic operations to be performed asynchronously as long as an
+     asynchronous capable engine is used. See the ASYNC_start_job() man page for
+     further details. Libssl has also had this capability integrated with the
+     introduction of the new mode SSL_MODE_ASYNC and associated error
+     SSL_ERROR_WANT_ASYNC. See the SSL_CTX_set_mode() and SSL_get_error() man
+     pages. This work was developed in partnership with Intel Corp.
+     [Matt Caswell]
+
+  *) SSL_{CTX_}set_ecdh_auto() has been removed and ECDH is support is
+     always enabled now.  If you want to disable the support you should
+     exclude it using the list of supported ciphers. This also means that the
+     "-no_ecdhe" option has been removed from s_server.
+     [Kurt Roeckx]
+
+  *) SSL_{CTX}_set_tmp_ecdh() which can set 1 EC curve now internally calls
+     SSL_{CTX_}set1_curves() which can set a list.
+     [Kurt Roeckx]
+
+  *) Remove support for SSL_{CTX_}set_tmp_ecdh_callback().  You should set the
+     curve you want to support using SSL_{CTX_}set1_curves().
+     [Kurt Roeckx]
+
+  *) State machine rewrite. The state machine code has been significantly
+     refactored in order to remove much duplication of code and solve issues
+     with the old code (see ssl/statem/README for further details). This change
+     does have some associated API changes. Notably the SSL_state() function
+     has been removed and replaced by SSL_get_state which now returns an
+     "OSSL_HANDSHAKE_STATE" instead of an int. SSL_set_state() has been removed
+     altogether. The previous handshake states defined in ssl.h and ssl3.h have
+     also been removed.
+     [Matt Caswell]
+
+  *) All instances of the string "ssleay" in the public API were replaced
+     with OpenSSL (case-matching; e.g., OPENSSL_VERSION for #define's)
+     Some error codes related to internal RSA_eay API's were renamed.
+     [Rich Salz]
+
+  *) The demo files in crypto/threads were moved to demo/threads.
+     [Rich Salz]
+
+  *) Removed obsolete engines: 4758cca, aep, atalla, cswift, nuron, gmp,
+     sureware and ubsec.
+     [Matt Caswell, Rich Salz]
+
+  *) New ASN.1 embed macro.
+
+     New ASN.1 macro ASN1_EMBED. This is the same as ASN1_SIMPLE except the
+     structure is not allocated: it is part of the parent. That is instead of
+
+     FOO *x;
+
+     it must be:
+
+     FOO x;
+
+     This reduces memory fragmentation and make it impossible to accidentally
+     set a mandatory field to NULL.
+
+     This currently only works for some fields specifically a SEQUENCE, CHOICE,
+     or ASN1_STRING type which is part of a parent SEQUENCE. Since it is
+     equivalent to ASN1_SIMPLE it cannot be tagged, OPTIONAL, SET OF or
+     SEQUENCE OF.
+     [Steve Henson]
+
+  *) Remove EVP_CHECK_DES_KEY, a compile-time option that never compiled.
+     [Emilia KÃ¤sper]
+
+  *) Removed DES and RC4 ciphersuites from DEFAULT. Also removed RC2 although
+     in 1.0.2 EXPORT was already removed and the only RC2 ciphersuite is also
+     an EXPORT one. COMPLEMENTOFDEFAULT has been updated accordingly to add
+     DES and RC4 ciphersuites.
+     [Matt Caswell]
+
+  *) Rewrite EVP_DecodeUpdate (base64 decoding) to fix several bugs.
+     This changes the decoding behaviour for some invalid messages,
+     though the change is mostly in the more lenient direction, and
+     legacy behaviour is preserved as much as possible.
+     [Emilia KÃ¤sper]
+
+  *) Fix no-stdio build.
+    [ David Woodhouse <David.Woodhouse@intel.com> and also
+      Ivan Nestlerode <ivan.nestlerode@sonos.com> ]
+
+  *) New testing framework
+     The testing framework has been largely rewritten and is now using
+     perl and the perl modules Test::Harness and an extended variant of
+     Test::More called OpenSSL::Test to do its work.  All test scripts in
+     test/ have been rewritten into test recipes, and all direct calls to
+     executables in test/Makefile have become individual recipes using the
+     simplified testing OpenSSL::Test::Simple.
+
+     For documentation on our testing modules, do:
+
+        perldoc test/testlib/OpenSSL/Test/Simple.pm
+        perldoc test/testlib/OpenSSL/Test.pm
+
+     [Richard Levitte]
+
+  *) Revamped memory debug; only -DCRYPTO_MDEBUG and -DCRYPTO_MDEBUG_ABORT
+     are used; the latter aborts on memory leaks (usually checked on exit).
+     Some undocumented "set malloc, etc., hooks" functions were removed
+     and others were changed.  All are now documented.
+     [Rich Salz]
+
+  *) In DSA_generate_parameters_ex, if the provided seed is too short,
+     return an error
+     [Rich Salz and Ismo Puustinen <ismo.puustinen@intel.com>]
+
+  *) Rewrite PSK to support ECDHE_PSK, DHE_PSK and RSA_PSK. Add ciphersuites
+     from RFC4279, RFC4785, RFC5487, RFC5489.
+
+     Thanks to Christian J. Dietrich and Giuseppe D'Angelo for the
+     original RSA_PSK patch.
+     [Steve Henson]
+
+  *) Dropped support for the SSL3_FLAGS_DELAY_CLIENT_FINISHED flag. This SSLeay
+     era flag was never set throughout the codebase (only read). Also removed
+     SSL3_FLAGS_POP_BUFFER which was only used if
+     SSL3_FLAGS_DELAY_CLIENT_FINISHED was also set.
+     [Matt Caswell]
+
+  *) Changed the default name options in the "ca", "crl", "req" and "x509"
+     to be "oneline" instead of "compat".
+     [Richard Levitte]
+
+  *) Remove SSL_OP_TLS_BLOCK_PADDING_BUG. This is SSLeay legacy, we're
+     not aware of clients that still exhibit this bug, and the workaround
+     hasn't been working properly for a while.
+     [Emilia KÃ¤sper]
+
+  *) The return type of BIO_number_read() and BIO_number_written() as well as
+     the corresponding num_read and num_write members in the BIO structure has
+     changed from unsigned long to uint64_t. On platforms where an unsigned
+     long is 32 bits (e.g. Windows) these counters could overflow if >4Gb is
+     transferred.
+     [Matt Caswell]
+
+  *) Given the pervasive nature of TLS extensions it is inadvisable to run
+     OpenSSL without support for them. It also means that maintaining
+     the OPENSSL_NO_TLSEXT option within the code is very invasive (and probably
+     not well tested). Therefore the OPENSSL_NO_TLSEXT option has been removed.
+     [Matt Caswell]
+
+  *) Removed support for the two export grade static DH ciphersuites
+     EXP-DH-RSA-DES-CBC-SHA and EXP-DH-DSS-DES-CBC-SHA. These two ciphersuites
+     were newly added (along with a number of other static DH ciphersuites) to
+     1.0.2. However the two export ones have *never* worked since they were
+     introduced. It seems strange in any case to be adding new export
+     ciphersuites, and given "logjam" it also does not seem correct to fix them.
+     [Matt Caswell]
+
+  *) Version negotiation has been rewritten. In particular SSLv23_method(),
+     SSLv23_client_method() and SSLv23_server_method() have been deprecated,
+     and turned into macros which simply call the new preferred function names
+     TLS_method(), TLS_client_method() and TLS_server_method(). All new code
+     should use the new names instead. Also as part of this change the ssl23.h
+     header file has been removed.
+     [Matt Caswell]
+
+  *) Support for Kerberos ciphersuites in TLS (RFC2712) has been removed. This
+     code and the associated standard is no longer considered fit-for-purpose.
+     [Matt Caswell]
+
+  *) RT2547 was closed.  When generating a private key, try to make the
+     output file readable only by the owner.  This behavior change might
+     be noticeable when interacting with other software.
+
+  *) Documented all exdata functions.  Added CRYPTO_free_ex_index.
+     Added a test.
+     [Rich Salz]
+
+  *) Added HTTP GET support to the ocsp command.
+     [Rich Salz]
+
+  *) Changed default digest for the dgst and enc commands from MD5 to
+     sha256
+     [Rich Salz]
+
+  *) RAND_pseudo_bytes has been deprecated. Users should use RAND_bytes instead.
+     [Matt Caswell]
+
+  *) Added support for TLS extended master secret from
+     draft-ietf-tls-session-hash-03.txt. Thanks for Alfredo Pironti for an
+     initial patch which was a great help during development.
+     [Steve Henson]
+
+  *) All libssl internal structures have been removed from the public header
+     files, and the OPENSSL_NO_SSL_INTERN option has been removed (since it is
+     now redundant). Users should not attempt to access internal structures
+     directly. Instead they should use the provided API functions.
+     [Matt Caswell]
+
+  *) config has been changed so that by default OPENSSL_NO_DEPRECATED is used.
+     Access to deprecated functions can be re-enabled by running config with
+     "enable-deprecated". In addition applications wishing to use deprecated
+     functions must define OPENSSL_USE_DEPRECATED. Note that this new behaviour
+     will, by default, disable some transitive includes that previously existed
+     in the header files (e.g. ec.h will no longer, by default, include bn.h)
+     [Matt Caswell]
+
+  *) Added support for OCB mode. OpenSSL has been granted a patent license
+     compatible with the OpenSSL license for use of OCB. Details are available
+     at https://www.openssl.org/source/OCB-patent-grant-OpenSSL.pdf. Support
+     for OCB can be removed by calling config with no-ocb.
+     [Matt Caswell]
+
+  *) SSLv2 support has been removed.  It still supports receiving a SSLv2
+     compatible client hello.
+     [Kurt Roeckx]
+
+  *) Increased the minimal RSA keysize from 256 to 512 bits [Rich Salz],
+     done while fixing the error code for the key-too-small case.
+     [Annie Yousar <a.yousar@informatik.hu-berlin.de>]
+
+  *) CA.sh has been removmed; use CA.pl instead.
+     [Rich Salz]
+
+  *) Removed old DES API.
+     [Rich Salz]
+
+  *) Remove various unsupported platforms:
+        Sony NEWS4
+        BEOS and BEOS_R5
+        NeXT
+        SUNOS
+        MPE/iX
+        Sinix/ReliantUNIX RM400
+        DGUX
+        NCR
+        Tandem
+        Cray
+        16-bit platforms such as WIN16
+     [Rich Salz]
+
+  *) Clean up OPENSSL_NO_xxx #define's
+        Use setbuf() and remove OPENSSL_NO_SETVBUF_IONBF
+        Rename OPENSSL_SYSNAME_xxx to OPENSSL_SYS_xxx
+        OPENSSL_NO_EC{DH,DSA} merged into OPENSSL_NO_EC
+        OPENSSL_NO_RIPEMD160, OPENSSL_NO_RIPEMD merged into OPENSSL_NO_RMD160
+        OPENSSL_NO_FP_API merged into OPENSSL_NO_STDIO
+        Remove OPENSSL_NO_BIO OPENSSL_NO_BUFFER OPENSSL_NO_CHAIN_VERIFY
+        OPENSSL_NO_EVP OPENSSL_NO_FIPS_ERR OPENSSL_NO_HASH_COMP
+        OPENSSL_NO_LHASH OPENSSL_NO_OBJECT OPENSSL_NO_SPEED OPENSSL_NO_STACK
+        OPENSSL_NO_X509 OPENSSL_NO_X509_VERIFY
+        Remove MS_STATIC; it's a relic from platforms <32 bits.
+     [Rich Salz]
+
+  *) Cleaned up dead code
+        Remove all but one '#ifdef undef' which is to be looked at.
+     [Rich Salz]
+
+  *) Clean up calling of xxx_free routines.
+        Just like free(), fix most of the xxx_free routines to accept
+        NULL.  Remove the non-null checks from callers.  Save much code.
+     [Rich Salz]
+
+  *) Add secure heap for storage of private keys (when possible).
+     Add BIO_s_secmem(), CBIGNUM, etc.
+     Contributed by Akamai Technologies under our Corporate CLA.
+     [Rich Salz]
+
+  *) Experimental support for a new, fast, unbiased prime candidate generator,
+     bn_probable_prime_dh_coprime(). Not currently used by any prime generator.
+     [Felix Laurie von Massenbach <felix@erbridge.co.uk>]
+
+  *) New output format NSS in the sess_id command line tool. This allows
+     exporting the session id and the master key in NSS keylog format.
+     [Martin Kaiser <martin@kaiser.cx>]
+
+  *) Harmonize version and its documentation. -f flag is used to display
+     compilation flags.
+     [mancha <mancha1@zoho.com>]
+
+  *) Fix eckey_priv_encode so it immediately returns an error upon a failure
+     in i2d_ECPrivateKey.  Thanks to Ted Unangst for feedback on this issue.
+     [mancha <mancha1@zoho.com>]
+
+  *) Fix some double frees. These are not thought to be exploitable.
+     [mancha <mancha1@zoho.com>]
+
+  *) A missing bounds check in the handling of the TLS heartbeat extension
+     can be used to reveal up to 64k of memory to a connected client or
+     server.
+
+     Thanks for Neel Mehta of Google Security for discovering this bug and to
+     Adam Langley <agl@chromium.org> and Bodo Moeller <bmoeller@acm.org> for
+     preparing the fix (CVE-2014-0160)
+     [Adam Langley, Bodo Moeller]
+
+  *) Fix for the attack described in the paper "Recovering OpenSSL
+     ECDSA Nonces Using the FLUSH+RELOAD Cache Side-channel Attack"
+     by Yuval Yarom and Naomi Benger. Details can be obtained from:
+     http://eprint.iacr.org/2014/140
+
+     Thanks to Yuval Yarom and Naomi Benger for discovering this
+     flaw and to Yuval Yarom for supplying a fix (CVE-2014-0076)
+     [Yuval Yarom and Naomi Benger]
+
+  *) Use algorithm specific chains in SSL_CTX_use_certificate_chain_file():
+     this fixes a limitation in previous versions of OpenSSL.
+     [Steve Henson]
+
+  *) Experimental encrypt-then-mac support.
+    
+     Experimental support for encrypt then mac from
+     draft-gutmann-tls-encrypt-then-mac-02.txt
+
+     To enable it set the appropriate extension number (0x42 for the test
+     server) using e.g. -DTLSEXT_TYPE_encrypt_then_mac=0x42
+ 
+     For non-compliant peers (i.e. just about everything) this should have no
+     effect.
+
+     WARNING: EXPERIMENTAL, SUBJECT TO CHANGE.
+
+     [Steve Henson]
+
+  *) Add EVP support for key wrapping algorithms, to avoid problems with
+     existing code the flag EVP_CIPHER_CTX_WRAP_ALLOW has to be set in
+     the EVP_CIPHER_CTX or an error is returned. Add AES and DES3 wrap
+     algorithms and include tests cases.
+     [Steve Henson]
+
+  *) Extend CMS code to support RSA-PSS signatures and RSA-OAEP for
+     enveloped data.
+     [Steve Henson]
+
+  *) Extended RSA OAEP support via EVP_PKEY API. Options to specify digest,
+     MGF1 digest and OAEP label.
+     [Steve Henson]
+
+  *) Make openssl verify return errors.
+     [Chris Palmer <palmer@google.com> and Ben Laurie]
+
+  *) New function ASN1_TIME_diff to calculate the difference between two
+     ASN1_TIME structures or one structure and the current time.
+     [Steve Henson]
+
+  *) Update fips_test_suite to support multiple command line options. New
+     test to induce all self test errors in sequence and check expected
+     failures.
+     [Steve Henson]
+
+  *) Add FIPS_{rsa,dsa,ecdsa}_{sign,verify} functions which digest and
+     sign or verify all in one operation.
+     [Steve Henson]
+
+  *) Add fips_algvs: a multicall fips utility incorporating all the algorithm
+     test programs and fips_test_suite. Includes functionality to parse
+     the minimal script output of fipsalgest.pl directly.
+     [Steve Henson]
+
+  *) Add authorisation parameter to FIPS_module_mode_set().
+     [Steve Henson]
+
+  *) Add FIPS selftest for ECDH algorithm using P-224 and B-233 curves.
+     [Steve Henson]
+
+  *) Use separate DRBG fields for internal and external flags. New function
+     FIPS_drbg_health_check() to perform on demand health checking. Add
+     generation tests to fips_test_suite with reduced health check interval to 
+     demonstrate periodic health checking. Add "nodh" option to
+     fips_test_suite to skip very slow DH test.
+     [Steve Henson]
+
+  *) New function FIPS_get_cipherbynid() to lookup FIPS supported ciphers
+     based on NID.
+     [Steve Henson]
+
+  *) More extensive health check for DRBG checking many more failure modes.
+     New function FIPS_selftest_drbg_all() to handle every possible DRBG
+     combination: call this in fips_test_suite.
+     [Steve Henson]
+
+  *) Add support for canonical generation of DSA parameter 'g'. See 
+     FIPS 186-3 A.2.3.
+
+  *) Add support for HMAC DRBG from SP800-90. Update DRBG algorithm test and
+     POST to handle HMAC cases.
+     [Steve Henson]
+
+  *) Add functions FIPS_module_version() and FIPS_module_version_text()
+     to return numerical and string versions of the FIPS module number.
+     [Steve Henson]
+
+  *) Rename FIPS_mode_set and FIPS_mode to FIPS_module_mode_set and
+     FIPS_module_mode. FIPS_mode and FIPS_mode_set will be implemented
+     outside the validated module in the FIPS capable OpenSSL.
+     [Steve Henson]
+
+  *) Minor change to DRBG entropy callback semantics. In some cases
+     there is no multiple of the block length between min_len and
+     max_len. Allow the callback to return more than max_len bytes
+     of entropy but discard any extra: it is the callback's responsibility
+     to ensure that the extra data discarded does not impact the
+     requested amount of entropy.
+     [Steve Henson]
+
+  *) Add PRNG security strength checks to RSA, DSA and ECDSA using 
+     information in FIPS186-3, SP800-57 and SP800-131A.
+     [Steve Henson]
+
+  *) CCM support via EVP. Interface is very similar to GCM case except we
+     must supply all data in one chunk (i.e. no update, final) and the
+     message length must be supplied if AAD is used. Add algorithm test
+     support.
+     [Steve Henson]
+
+  *) Initial version of POST overhaul. Add POST callback to allow the status
+     of POST to be monitored and/or failures induced. Modify fips_test_suite
+     to use callback. Always run all selftests even if one fails.
+     [Steve Henson]
+
+  *) XTS support including algorithm test driver in the fips_gcmtest program.
+     Note: this does increase the maximum key length from 32 to 64 bytes but
+     there should be no binary compatibility issues as existing applications
+     will never use XTS mode.
+     [Steve Henson]
+
+  *) Extensive reorganisation of FIPS PRNG behaviour. Remove all dependencies
+     to OpenSSL RAND code and replace with a tiny FIPS RAND API which also
+     performs algorithm blocking for unapproved PRNG types. Also do not
+     set PRNG type in FIPS_mode_set(): leave this to the application.
+     Add default OpenSSL DRBG handling: sets up FIPS PRNG and seeds with
+     the standard OpenSSL PRNG: set additional data to a date time vector.
+     [Steve Henson]
+
+  *) Rename old X9.31 PRNG functions of the form FIPS_rand* to FIPS_x931*.
+     This shouldn't present any incompatibility problems because applications
+     shouldn't be using these directly and any that are will need to rethink
+     anyway as the X9.31 PRNG is now deprecated by FIPS 140-2
+     [Steve Henson]
+
+  *) Extensive self tests and health checking required by SP800-90 DRBG.
+     Remove strength parameter from FIPS_drbg_instantiate and always
+     instantiate at maximum supported strength.
+     [Steve Henson]
+
+  *) Add ECDH code to fips module and fips_ecdhvs for primitives only testing.
+     [Steve Henson]
+
+  *) New algorithm test program fips_dhvs to handle DH primitives only testing.
+     [Steve Henson]
+
+  *) New function DH_compute_key_padded() to compute a DH key and pad with
+     leading zeroes if needed: this complies with SP800-56A et al.
+     [Steve Henson]
+
+  *) Initial implementation of SP800-90 DRBGs for Hash and CTR. Not used by
+     anything, incomplete, subject to change and largely untested at present.
+     [Steve Henson]
+
+  *) Modify fipscanisteronly build option to only build the necessary object
+     files by filtering FIPS_EX_OBJ through a perl script in crypto/Makefile.
+     [Steve Henson]
+
+  *) Add experimental option FIPSSYMS to give all symbols in
+     fipscanister.o and FIPS or fips prefix. This will avoid
+     conflicts with future versions of OpenSSL. Add perl script
+     util/fipsas.pl to preprocess assembly language source files
+     and rename any affected symbols.
+     [Steve Henson]
+
+  *) Add selftest checks and algorithm block of non-fips algorithms in
+     FIPS mode. Remove DES2 from selftests.
+     [Steve Henson]
+
+  *) Add ECDSA code to fips module. Add tiny fips_ecdsa_check to just
+     return internal method without any ENGINE dependencies. Add new
+     tiny fips sign and verify functions.
+     [Steve Henson]
+
+  *) New build option no-ec2m to disable characteristic 2 code.
+     [Steve Henson]
+
+  *) New build option "fipscanisteronly". This only builds fipscanister.o
+     and (currently) associated fips utilities. Uses the file Makefile.fips
+     instead of Makefile.org as the prototype.
+     [Steve Henson]
+
+  *) Add some FIPS mode restrictions to GCM. Add internal IV generator.
+     Update fips_gcmtest to use IV generator.
+     [Steve Henson]
+
+  *) Initial, experimental EVP support for AES-GCM. AAD can be input by
+     setting output buffer to NULL. The *Final function must be
+     called although it will not retrieve any additional data. The tag
+     can be set or retrieved with a ctrl. The IV length is by default 12
+     bytes (96 bits) but can be set to an alternative value. If the IV
+     length exceeds the maximum IV length (currently 16 bytes) it cannot be
+     set before the key. 
+     [Steve Henson]
+
+  *) New flag in ciphers: EVP_CIPH_FLAG_CUSTOM_CIPHER. This means the
+     underlying do_cipher function handles all cipher semantics itself
+     including padding and finalisation. This is useful if (for example)
+     an ENGINE cipher handles block padding itself. The behaviour of
+     do_cipher is subtly changed if this flag is set: the return value
+     is the number of characters written to the output buffer (zero is
+     no longer an error code) or a negative error code. Also if the
+     input buffer is NULL and length 0 finalisation should be performed.
+     [Steve Henson]
+
+  *) If a candidate issuer certificate is already part of the constructed
+     path ignore it: new debug notification X509_V_ERR_PATH_LOOP for this case.
+     [Steve Henson]
+
+  *) Improve forward-security support: add functions
+
+       void SSL_CTX_set_not_resumable_session_callback(SSL_CTX *ctx, int (*cb)(SSL *ssl, int is_forward_secure))
+       void SSL_set_not_resumable_session_callback(SSL *ssl, int (*cb)(SSL *ssl, int is_forward_secure))
+
+     for use by SSL/TLS servers; the callback function will be called whenever a
+     new session is created, and gets to decide whether the session may be
+     cached to make it resumable (return 0) or not (return 1).  (As by the
+     SSL/TLS protocol specifications, the session_id sent by the server will be
+     empty to indicate that the session is not resumable; also, the server will
+     not generate RFC 4507 (RFC 5077) session tickets.)
+
+     A simple reasonable callback implementation is to return is_forward_secure.
+     This parameter will be set to 1 or 0 depending on the ciphersuite selected
+     by the SSL/TLS server library, indicating whether it can provide forward
+     security.
+     [Emilia KÃ¤sper <emilia.kasper@esat.kuleuven.be> (Google)]
+
+  *) New -verify_name option in command line utilities to set verification
+     parameters by name.
+     [Steve Henson]
+
+  *) Initial CMAC implementation. WARNING: EXPERIMENTAL, API MAY CHANGE.
+     Add CMAC pkey methods.
+     [Steve Henson]
+
+  *) Experimental renegotiation in s_server -www mode. If the client 
+     browses /reneg connection is renegotiated. If /renegcert it is
+     renegotiated requesting a certificate.
+     [Steve Henson]
+
+  *) Add an "external" session cache for debugging purposes to s_server. This
+     should help trace issues which normally are only apparent in deployed
+     multi-process servers.
+     [Steve Henson]
+
+  *) Extensive audit of libcrypto with DEBUG_UNUSED. Fix many cases where
+     return value is ignored. NB. The functions RAND_add(), RAND_seed(),
+     BIO_set_cipher() and some obscure PEM functions were changed so they
+     can now return an error. The RAND changes required a change to the
+     RAND_METHOD structure.
+     [Steve Henson]
+
+  *) New macro __owur for "OpenSSL Warn Unused Result". This makes use of
+     a gcc attribute to warn if the result of a function is ignored. This
+     is enable if DEBUG_UNUSED is set. Add to several functions in evp.h
+     whose return value is often ignored. 
+     [Steve Henson]
+
+  *) New -noct, -requestct, -requirect and -ctlogfile options for s_client.
+     These allow SCTs (signed certificate timestamps) to be requested and
+     validated when establishing a connection.
+     [Rob Percival <robpercival@google.com>]
+
+ Changes between 1.0.2g and 1.0.2h [3 May 2016]
+
+  *) Prevent padding oracle in AES-NI CBC MAC check
+
+     A MITM attacker can use a padding oracle attack to decrypt traffic
+     when the connection uses an AES CBC cipher and the server support
+     AES-NI.
+
+     This issue was introduced as part of the fix for Lucky 13 padding
+     attack (CVE-2013-0169). The padding check was rewritten to be in
+     constant time by making sure that always the same bytes are read and
+     compared against either the MAC or padding bytes. But it no longer
+     checked that there was enough data to have both the MAC and padding
+     bytes.
+
+     This issue was reported by Juraj Somorovsky using TLS-Attacker.
+     (CVE-2016-2107)
+     [Kurt Roeckx]
+
+  *) Fix EVP_EncodeUpdate overflow
+
+     An overflow can occur in the EVP_EncodeUpdate() function which is used for
+     Base64 encoding of binary data. If an attacker is able to supply very large
+     amounts of input data then a length check can overflow resulting in a heap
+     corruption.
+
+     Internally to OpenSSL the EVP_EncodeUpdate() function is primarily used by
+     the PEM_write_bio* family of functions. These are mainly used within the
+     OpenSSL command line applications, so any application which processes data
+     from an untrusted source and outputs it as a PEM file should be considered
+     vulnerable to this issue. User applications that call these APIs directly
+     with large amounts of untrusted data may also be vulnerable.
+
+     This issue was reported by Guido Vranken.
+     (CVE-2016-2105)
+     [Matt Caswell]
+
+  *) Fix EVP_EncryptUpdate overflow
+
+     An overflow can occur in the EVP_EncryptUpdate() function. If an attacker
+     is able to supply very large amounts of input data after a previous call to
+     EVP_EncryptUpdate() with a partial block then a length check can overflow
+     resulting in a heap corruption. Following an analysis of all OpenSSL
+     internal usage of the EVP_EncryptUpdate() function all usage is one of two
+     forms. The first form is where the EVP_EncryptUpdate() call is known to be
+     the first called function after an EVP_EncryptInit(), and therefore that
+     specific call must be safe. The second form is where the length passed to
+     EVP_EncryptUpdate() can be seen from the code to be some small value and
+     therefore there is no possibility of an overflow. Since all instances are
+     one of these two forms, it is believed that there can be no overflows in
+     internal code due to this problem. It should be noted that
+     EVP_DecryptUpdate() can call EVP_EncryptUpdate() in certain code paths.
+     Also EVP_CipherUpdate() is a synonym for EVP_EncryptUpdate(). All instances
+     of these calls have also been analysed too and it is believed there are no
+     instances in internal usage where an overflow could occur.
+
+     This issue was reported by Guido Vranken.
+     (CVE-2016-2106)
+     [Matt Caswell]
+
+  *) Prevent ASN.1 BIO excessive memory allocation
+
+     When ASN.1 data is read from a BIO using functions such as d2i_CMS_bio()
+     a short invalid encoding can cause allocation of large amounts of memory
+     potentially consuming excessive resources or exhausting memory.
+
+     Any application parsing untrusted data through d2i BIO functions is
+     affected. The memory based functions such as d2i_X509() are *not* affected.
+     Since the memory based functions are used by the TLS library, TLS
+     applications are not affected.
+
+     This issue was reported by Brian Carpenter.
+     (CVE-2016-2109)
+     [Stephen Henson]
+
+  *) EBCDIC overread
+
+     ASN1 Strings that are over 1024 bytes can cause an overread in applications
+     using the X509_NAME_oneline() function on EBCDIC systems. This could result
+     in arbitrary stack data being returned in the buffer.
+
+     This issue was reported by Guido Vranken.
+     (CVE-2016-2176)
+     [Matt Caswell]
+
+  *) Modify behavior of ALPN to invoke callback after SNI/servername
+     callback, such that updates to the SSL_CTX affect ALPN.
+     [Todd Short]
+
+  *) Remove LOW from the DEFAULT cipher list.  This removes singles DES from the
+     default.
+     [Kurt Roeckx]
+
+  *) Only remove the SSLv2 methods with the no-ssl2-method option. When the
+     methods are enabled and ssl2 is disabled the methods return NULL.
+     [Kurt Roeckx]
+
+ Changes between 1.0.2f and 1.0.2g [1 Mar 2016]
+
+  * Disable weak ciphers in SSLv3 and up in default builds of OpenSSL.
+    Builds that are not configured with "enable-weak-ssl-ciphers" will not
+    provide any "EXPORT" or "LOW" strength ciphers.
+    [Viktor Dukhovni]
+
+  * Disable SSLv2 default build, default negotiation and weak ciphers.  SSLv2
+    is by default disabled at build-time.  Builds that are not configured with
+    "enable-ssl2" will not support SSLv2.  Even if "enable-ssl2" is used,
+    users who want to negotiate SSLv2 via the version-flexible SSLv23_method()
+    will need to explicitly call either of:
+
+        SSL_CTX_clear_options(ctx, SSL_OP_NO_SSLv2);
+    or
+        SSL_clear_options(ssl, SSL_OP_NO_SSLv2);
+
+    as appropriate.  Even if either of those is used, or the application
+    explicitly uses the version-specific SSLv2_method() or its client and
+    server variants, SSLv2 ciphers vulnerable to exhaustive search key
+    recovery have been removed.  Specifically, the SSLv2 40-bit EXPORT
+    ciphers, and SSLv2 56-bit DES are no longer available.
+    (CVE-2016-0800)
+    [Viktor Dukhovni]
+
+  *) Fix a double-free in DSA code
+
+     A double free bug was discovered when OpenSSL parses malformed DSA private
+     keys and could lead to a DoS attack or memory corruption for applications
+     that receive DSA private keys from untrusted sources.  This scenario is
+     considered rare.
+
+     This issue was reported to OpenSSL by Adam Langley(Google/BoringSSL) using
+     libFuzzer.
+     (CVE-2016-0705)
+     [Stephen Henson]
+
+  *) Disable SRP fake user seed to address a server memory leak.
+
+     Add a new method SRP_VBASE_get1_by_user that handles the seed properly.
+
+     SRP_VBASE_get_by_user had inconsistent memory management behaviour.
+     In order to fix an unavoidable memory leak, SRP_VBASE_get_by_user
+     was changed to ignore the "fake user" SRP seed, even if the seed
+     is configured.
+
+     Users should use SRP_VBASE_get1_by_user instead. Note that in
+     SRP_VBASE_get1_by_user, caller must free the returned value. Note
+     also that even though configuring the SRP seed attempts to hide
+     invalid usernames by continuing the handshake with fake
+     credentials, this behaviour is not constant time and no strong
+     guarantees are made that the handshake is indistinguishable from
+     that of a valid user.
+     (CVE-2016-0798)
+     [Emilia KÃ¤sper]
+
+  *) Fix BN_hex2bn/BN_dec2bn NULL pointer deref/heap corruption
+
+     In the BN_hex2bn function the number of hex digits is calculated using an
+     int value |i|. Later |bn_expand| is called with a value of |i * 4|. For
+     large values of |i| this can result in |bn_expand| not allocating any
+     memory because |i * 4| is negative. This can leave the internal BIGNUM data
+     field as NULL leading to a subsequent NULL ptr deref. For very large values
+     of |i|, the calculation |i * 4| could be a positive value smaller than |i|.
+     In this case memory is allocated to the internal BIGNUM data field, but it
+     is insufficiently sized leading to heap corruption. A similar issue exists
+     in BN_dec2bn. This could have security consequences if BN_hex2bn/BN_dec2bn
+     is ever called by user applications with very large untrusted hex/dec data.
+     This is anticipated to be a rare occurrence.
+
+     All OpenSSL internal usage of these functions use data that is not expected
+     to be untrusted, e.g. config file data or application command line
+     arguments. If user developed applications generate config file data based
+     on untrusted data then it is possible that this could also lead to security
+     consequences. This is also anticipated to be rare.
+
+     This issue was reported to OpenSSL by Guido Vranken.
+     (CVE-2016-0797)
+     [Matt Caswell]
+
+  *) Fix memory issues in BIO_*printf functions
+
+     The internal |fmtstr| function used in processing a "%s" format string in
+     the BIO_*printf functions could overflow while calculating the length of a
+     string and cause an OOB read when printing very long strings.
+
+     Additionally the internal |doapr_outch| function can attempt to write to an
+     OOB memory location (at an offset from the NULL pointer) in the event of a
+     memory allocation failure. In 1.0.2 and below this could be caused where
+     the size of a buffer to be allocated is greater than INT_MAX. E.g. this
+     could be in processing a very long "%s" format string. Memory leaks can
+     also occur.
+
+     The first issue may mask the second issue dependent on compiler behaviour.
+     These problems could enable attacks where large amounts of untrusted data
+     is passed to the BIO_*printf functions. If applications use these functions
+     in this way then they could be vulnerable. OpenSSL itself uses these
+     functions when printing out human-readable dumps of ASN.1 data. Therefore
+     applications that print this data could be vulnerable if the data is from
+     untrusted sources. OpenSSL command line applications could also be
+     vulnerable where they print out ASN.1 data, or if untrusted data is passed
+     as command line arguments.
+
+     Libssl is not considered directly vulnerable. Additionally certificates etc
+     received via remote connections via libssl are also unlikely to be able to
+     trigger these issues because of message size limits enforced within libssl.
+
+     This issue was reported to OpenSSL Guido Vranken.
+     (CVE-2016-0799)
+     [Matt Caswell]
+
+  *) Side channel attack on modular exponentiation
+
+     A side-channel attack was found which makes use of cache-bank conflicts on
+     the Intel Sandy-Bridge microarchitecture which could lead to the recovery
+     of RSA keys.  The ability to exploit this issue is limited as it relies on
+     an attacker who has control of code in a thread running on the same
+     hyper-threaded core as the victim thread which is performing decryptions.
+
+     This issue was reported to OpenSSL by Yuval Yarom, The University of
+     Adelaide and NICTA, Daniel Genkin, Technion and Tel Aviv University, and
+     Nadia Heninger, University of Pennsylvania with more information at
+     http://cachebleed.info.
+     (CVE-2016-0702)
+     [Andy Polyakov]
+
+  *) Change the req app to generate a 2048-bit RSA/DSA key by default,
+     if no keysize is specified with default_bits. This fixes an
+     omission in an earlier change that changed all RSA/DSA key generation
+     apps to use 2048 bits by default.
+     [Emilia KÃ¤sper]
+
+ Changes between 1.0.2e and 1.0.2f [28 Jan 2016]
+  *) DH small subgroups
+
+     Historically OpenSSL only ever generated DH parameters based on "safe"
+     primes. More recently (in version 1.0.2) support was provided for
+     generating X9.42 style parameter files such as those required for RFC 5114
+     support. The primes used in such files may not be "safe". Where an
+     application is using DH configured with parameters based on primes that are
+     not "safe" then an attacker could use this fact to find a peer's private
+     DH exponent. This attack requires that the attacker complete multiple
+     handshakes in which the peer uses the same private DH exponent. For example
+     this could be used to discover a TLS server's private DH exponent if it's
+     reusing the private DH exponent or it's using a static DH ciphersuite.
+
+     OpenSSL provides the option SSL_OP_SINGLE_DH_USE for ephemeral DH (DHE) in
+     TLS. It is not on by default. If the option is not set then the server
+     reuses the same private DH exponent for the life of the server process and
+     would be vulnerable to this attack. It is believed that many popular
+     applications do set this option and would therefore not be at risk.
+
+     The fix for this issue adds an additional check where a "q" parameter is
+     available (as is the case in X9.42 based parameters). This detects the
+     only known attack, and is the only possible defense for static DH
+     ciphersuites. This could have some performance impact.
+
+     Additionally the SSL_OP_SINGLE_DH_USE option has been switched on by
+     default and cannot be disabled. This could have some performance impact.
+
+     This issue was reported to OpenSSL by Antonio Sanso (Adobe).
+     (CVE-2016-0701)
+     [Matt Caswell]
+
+  *) SSLv2 doesn't block disabled ciphers
+
+     A malicious client can negotiate SSLv2 ciphers that have been disabled on
+     the server and complete SSLv2 handshakes even if all SSLv2 ciphers have
+     been disabled, provided that the SSLv2 protocol was not also disabled via
+     SSL_OP_NO_SSLv2.
+
+     This issue was reported to OpenSSL on 26th December 2015 by Nimrod Aviram
+     and Sebastian Schinzel.
+     (CVE-2015-3197)
+     [Viktor Dukhovni]
+
+ Changes between 1.0.2d and 1.0.2e [3 Dec 2015]
+
+  *) BN_mod_exp may produce incorrect results on x86_64
+
+     There is a carry propagating bug in the x86_64 Montgomery squaring
+     procedure. No EC algorithms are affected. Analysis suggests that attacks
+     against RSA and DSA as a result of this defect would be very difficult to
+     perform and are not believed likely. Attacks against DH are considered just
+     feasible (although very difficult) because most of the work necessary to
+     deduce information about a private key may be performed offline. The amount
+     of resources required for such an attack would be very significant and
+     likely only accessible to a limited number of attackers. An attacker would
+     additionally need online access to an unpatched system using the target
+     private key in a scenario with persistent DH parameters and a private
+     key that is shared between multiple clients. For example this can occur by
+     default in OpenSSL DHE based SSL/TLS ciphersuites.
+
+     This issue was reported to OpenSSL by Hanno BÃ¶ck.
+     (CVE-2015-3193)
+     [Andy Polyakov]
+
+  *) Certificate verify crash with missing PSS parameter
+
+     The signature verification routines will crash with a NULL pointer
+     dereference if presented with an ASN.1 signature using the RSA PSS
+     algorithm and absent mask generation function parameter. Since these
+     routines are used to verify certificate signature algorithms this can be
+     used to crash any certificate verification operation and exploited in a
+     DoS attack. Any application which performs certificate verification is
+     vulnerable including OpenSSL clients and servers which enable client
+     authentication.
+
+     This issue was reported to OpenSSL by LoÃ¯c Jonas Etienne (Qnective AG).
+     (CVE-2015-3194)
+     [Stephen Henson]
+
+  *) X509_ATTRIBUTE memory leak
+
+     When presented with a malformed X509_ATTRIBUTE structure OpenSSL will leak
+     memory. This structure is used by the PKCS#7 and CMS routines so any
+     application which reads PKCS#7 or CMS data from untrusted sources is
+     affected. SSL/TLS is not affected.
+
+     This issue was reported to OpenSSL by Adam Langley (Google/BoringSSL) using
+     libFuzzer.
+     (CVE-2015-3195)
+     [Stephen Henson]
+
+  *) Rewrite EVP_DecodeUpdate (base64 decoding) to fix several bugs.
+     This changes the decoding behaviour for some invalid messages,
+     though the change is mostly in the more lenient direction, and
+     legacy behaviour is preserved as much as possible.
+     [Emilia KÃ¤sper]
+
+  *) In DSA_generate_parameters_ex, if the provided seed is too short,
+     return an error
+     [Rich Salz and Ismo Puustinen <ismo.puustinen@intel.com>]
+
+ Changes between 1.0.2c and 1.0.2d [9 Jul 2015]
+
+  *) Alternate chains certificate forgery
+
+     During certificate verification, OpenSSL will attempt to find an
+     alternative certificate chain if the first attempt to build such a chain
+     fails. An error in the implementation of this logic can mean that an
+     attacker could cause certain checks on untrusted certificates to be
+     bypassed, such as the CA flag, enabling them to use a valid leaf
+     certificate to act as a CA and "issue" an invalid certificate.
+
+     This issue was reported to OpenSSL by Adam Langley/David Benjamin
+     (Google/BoringSSL).
+     [Matt Caswell]
+
+ Changes between 1.0.2b and 1.0.2c [12 Jun 2015]
+
+  *) Fix HMAC ABI incompatibility. The previous version introduced an ABI
+     incompatibility in the handling of HMAC. The previous ABI has now been
+     restored.
+     [Matt Caswell]
+
+ Changes between 1.0.2a and 1.0.2b [11 Jun 2015]
+
+  *) Malformed ECParameters causes infinite loop
+
+     When processing an ECParameters structure OpenSSL enters an infinite loop
+     if the curve specified is over a specially malformed binary polynomial
+     field.
+
+     This can be used to perform denial of service against any
+     system which processes public keys, certificate requests or
+     certificates.  This includes TLS clients and TLS servers with
+     client authentication enabled.
+
+     This issue was reported to OpenSSL by Joseph Barr-Pixton.
+     (CVE-2015-1788)
+     [Andy Polyakov]
+
+  *) Exploitable out-of-bounds read in X509_cmp_time
+
+     X509_cmp_time does not properly check the length of the ASN1_TIME
+     string and can read a few bytes out of bounds. In addition,
+     X509_cmp_time accepts an arbitrary number of fractional seconds in the
+     time string.
+
+     An attacker can use this to craft malformed certificates and CRLs of
+     various sizes and potentially cause a segmentation fault, resulting in
+     a DoS on applications that verify certificates or CRLs. TLS clients
+     that verify CRLs are affected. TLS clients and servers with client
+     authentication enabled may be affected if they use custom verification
+     callbacks.
+
+     This issue was reported to OpenSSL by Robert Swiecki (Google), and
+     independently by Hanno BÃ¶ck.
+     (CVE-2015-1789)
+     [Emilia KÃ¤sper]
+
+  *) PKCS7 crash with missing EnvelopedContent
+
+     The PKCS#7 parsing code does not handle missing inner EncryptedContent
+     correctly. An attacker can craft malformed ASN.1-encoded PKCS#7 blobs
+     with missing content and trigger a NULL pointer dereference on parsing.
+
+     Applications that decrypt PKCS#7 data or otherwise parse PKCS#7
+     structures from untrusted sources are affected. OpenSSL clients and
+     servers are not affected.
+
+     This issue was reported to OpenSSL by Michal Zalewski (Google).
+     (CVE-2015-1790)
+     [Emilia KÃ¤sper]
+
+  *) CMS verify infinite loop with unknown hash function
+
+     When verifying a signedData message the CMS code can enter an infinite loop
+     if presented with an unknown hash function OID. This can be used to perform
+     denial of service against any system which verifies signedData messages using
+     the CMS code.
+     This issue was reported to OpenSSL by Johannes Bauer.
+     (CVE-2015-1792)
+     [Stephen Henson]
+
+  *) Race condition handling NewSessionTicket
+
+     If a NewSessionTicket is received by a multi-threaded client when attempting to
+     reuse a previous ticket then a race condition can occur potentially leading to
+     a double free of the ticket data.
+     (CVE-2015-1791)
+     [Matt Caswell]
+
+  *) Only support 256-bit or stronger elliptic curves with the
+     'ecdh_auto' setting (server) or by default (client). Of supported
+     curves, prefer P-256 (both).
+     [Emilia Kasper]
+
+ Changes between 1.0.2 and 1.0.2a [19 Mar 2015]
+
+  *) ClientHello sigalgs DoS fix
+
+     If a client connects to an OpenSSL 1.0.2 server and renegotiates with an
+     invalid signature algorithms extension a NULL pointer dereference will
+     occur. This can be exploited in a DoS attack against the server.
+
+     This issue was was reported to OpenSSL by David Ramos of Stanford
+     University.
+     (CVE-2015-0291)
+     [Stephen Henson and Matt Caswell]
+
+  *) Multiblock corrupted pointer fix
+
+     OpenSSL 1.0.2 introduced the "multiblock" performance improvement. This
+     feature only applies on 64 bit x86 architecture platforms that support AES
+     NI instructions. A defect in the implementation of "multiblock" can cause
+     OpenSSL's internal write buffer to become incorrectly set to NULL when
+     using non-blocking IO. Typically, when the user application is using a
+     socket BIO for writing, this will only result in a failed connection.
+     However if some other BIO is used then it is likely that a segmentation
+     fault will be triggered, thus enabling a potential DoS attack.
+
+     This issue was reported to OpenSSL by Daniel Danner and Rainer Mueller.
+     (CVE-2015-0290)
+     [Matt Caswell]
+
+  *) Segmentation fault in DTLSv1_listen fix
+
+     The DTLSv1_listen function is intended to be stateless and processes the
+     initial ClientHello from many peers. It is common for user code to loop
+     over the call to DTLSv1_listen until a valid ClientHello is received with
+     an associated cookie. A defect in the implementation of DTLSv1_listen means
+     that state is preserved in the SSL object from one invocation to the next
+     that can lead to a segmentation fault. Errors processing the initial
+     ClientHello can trigger this scenario. An example of such an error could be
+     that a DTLS1.0 only client is attempting to connect to a DTLS1.2 only
+     server.
+
+     This issue was reported to OpenSSL by Per Allansson.
+     (CVE-2015-0207)
+     [Matt Caswell]
+
+  *) Segmentation fault in ASN1_TYPE_cmp fix
+
+     The function ASN1_TYPE_cmp will crash with an invalid read if an attempt is
+     made to compare ASN.1 boolean types. Since ASN1_TYPE_cmp is used to check
+     certificate signature algorithm consistency this can be used to crash any
+     certificate verification operation and exploited in a DoS attack. Any
+     application which performs certificate verification is vulnerable including
+     OpenSSL clients and servers which enable client authentication.
+     (CVE-2015-0286)
+     [Stephen Henson]
+
+  *) Segmentation fault for invalid PSS parameters fix
+
+     The signature verification routines will crash with a NULL pointer
+     dereference if presented with an ASN.1 signature using the RSA PSS
+     algorithm and invalid parameters. Since these routines are used to verify
+     certificate signature algorithms this can be used to crash any
+     certificate verification operation and exploited in a DoS attack. Any
+     application which performs certificate verification is vulnerable including
+     OpenSSL clients and servers which enable client authentication.
+
+     This issue was was reported to OpenSSL by Brian Carpenter.
+     (CVE-2015-0208)
+     [Stephen Henson]
+
+  *) ASN.1 structure reuse memory corruption fix
+
+     Reusing a structure in ASN.1 parsing may allow an attacker to cause
+     memory corruption via an invalid write. Such reuse is and has been
+     strongly discouraged and is believed to be rare.
+
+     Applications that parse structures containing CHOICE or ANY DEFINED BY
+     components may be affected. Certificate parsing (d2i_X509 and related
+     functions) are however not affected. OpenSSL clients and servers are
+     not affected.
+     (CVE-2015-0287)
+     [Stephen Henson]
+
+  *) PKCS7 NULL pointer dereferences fix
+
+     The PKCS#7 parsing code does not handle missing outer ContentInfo
+     correctly. An attacker can craft malformed ASN.1-encoded PKCS#7 blobs with
+     missing content and trigger a NULL pointer dereference on parsing.
+
+     Applications that verify PKCS#7 signatures, decrypt PKCS#7 data or
+     otherwise parse PKCS#7 structures from untrusted sources are
+     affected. OpenSSL clients and servers are not affected.
+
+     This issue was reported to OpenSSL by Michal Zalewski (Google).
+     (CVE-2015-0289)
+     [Emilia KÃ¤sper]
+
+  *) DoS via reachable assert in SSLv2 servers fix
+
+     A malicious client can trigger an OPENSSL_assert (i.e., an abort) in
+     servers that both support SSLv2 and enable export cipher suites by sending
+     a specially crafted SSLv2 CLIENT-MASTER-KEY message.
+
+     This issue was discovered by Sean Burford (Google) and Emilia KÃ¤sper
+     (OpenSSL development team).
+     (CVE-2015-0293)
+     [Emilia KÃ¤sper]
+
+  *) Empty CKE with client auth and DHE fix
+
+     If client auth is used then a server can seg fault in the event of a DHE
+     ciphersuite being selected and a zero length ClientKeyExchange message
+     being sent by the client. This could be exploited in a DoS attack.
+     (CVE-2015-1787)
+     [Matt Caswell]
+
+  *) Handshake with unseeded PRNG fix
+
+     Under certain conditions an OpenSSL 1.0.2 client can complete a handshake
+     with an unseeded PRNG. The conditions are:
+     - The client is on a platform where the PRNG has not been seeded
+     automatically, and the user has not seeded manually
+     - A protocol specific client method version has been used (i.e. not
+     SSL_client_methodv23)
+     - A ciphersuite is used that does not require additional random data from
+     the PRNG beyond the initial ClientHello client random (e.g. PSK-RC4-SHA).
+
+     If the handshake succeeds then the client random that has been used will
+     have been generated from a PRNG with insufficient entropy and therefore the
+     output may be predictable.
+
+     For example using the following command with an unseeded openssl will
+     succeed on an unpatched platform:
+
+     openssl s_client -psk 1a2b3c4d -tls1_2 -cipher PSK-RC4-SHA
+     (CVE-2015-0285)
+     [Matt Caswell]
+
+  *) Use After Free following d2i_ECPrivatekey error fix
+
+     A malformed EC private key file consumed via the d2i_ECPrivateKey function
+     could cause a use after free condition. This, in turn, could cause a double
+     free in several private key parsing functions (such as d2i_PrivateKey
+     or EVP_PKCS82PKEY) and could lead to a DoS attack or memory corruption
+     for applications that receive EC private keys from untrusted
+     sources. This scenario is considered rare.
+
+     This issue was discovered by the BoringSSL project and fixed in their
+     commit 517073cd4b.
+     (CVE-2015-0209)
+     [Matt Caswell]
+
+  *) X509_to_X509_REQ NULL pointer deref fix
+
+     The function X509_to_X509_REQ will crash with a NULL pointer dereference if
+     the certificate key is invalid. This function is rarely used in practice.
+
+     This issue was discovered by Brian Carpenter.
+     (CVE-2015-0288)
+     [Stephen Henson]
+
+  *) Removed the export ciphers from the DEFAULT ciphers
+     [Kurt Roeckx]
+
+ Changes between 1.0.1l and 1.0.2 [22 Jan 2015]
+
+  *) Facilitate "universal" ARM builds targeting range of ARM ISAs, e.g.
+     ARMv5 through ARMv8, as opposite to "locking" it to single one.
+     So far those who have to target multiple platforms would compromise
+     and argue that binary targeting say ARMv5 would still execute on
+     ARMv8. "Universal" build resolves this compromise by providing
+     near-optimal performance even on newer platforms.
+     [Andy Polyakov]
+
+  *) Accelerated NIST P-256 elliptic curve implementation for x86_64
+     (other platforms pending).
+     [Shay Gueron & Vlad Krasnov (Intel Corp), Andy Polyakov]
+
+  *) Add support for the SignedCertificateTimestampList certificate and
+     OCSP response extensions from RFC6962.
+     [Rob Stradling]
+
+  *) Fix ec_GFp_simple_points_make_affine (thus, EC_POINTs_mul etc.)
+     for corner cases. (Certain input points at infinity could lead to
+     bogus results, with non-infinity inputs mapped to infinity too.)
+     [Bodo Moeller]
+
+  *) Initial support for PowerISA 2.0.7, first implemented in POWER8.
+     This covers AES, SHA256/512 and GHASH. "Initial" means that most
+     common cases are optimized and there still is room for further
+     improvements. Vector Permutation AES for Altivec is also added.
+     [Andy Polyakov]
+
+  *) Add support for little-endian ppc64 Linux target.
+     [Marcelo Cerri (IBM)]
+
+  *) Initial support for AMRv8 ISA crypto extensions. This covers AES,
+     SHA1, SHA256 and GHASH. "Initial" means that most common cases
+     are optimized and there still is room for further improvements.
+     Both 32- and 64-bit modes are supported.
+     [Andy Polyakov, Ard Biesheuvel (Linaro)]
+
+  *) Improved ARMv7 NEON support.
+     [Andy Polyakov]
+
+  *) Support for SPARC Architecture 2011 crypto extensions, first
+     implemented in SPARC T4. This covers AES, DES, Camellia, SHA1,
+     SHA256/512, MD5, GHASH and modular exponentiation.
+     [Andy Polyakov, David Miller]
+
+  *) Accelerated modular exponentiation for Intel processors, a.k.a.
+     RSAZ.
+     [Shay Gueron & Vlad Krasnov (Intel Corp)]
+
+  *) Support for new and upcoming Intel processors, including AVX2,
+     BMI and SHA ISA extensions. This includes additional "stitched"
+     implementations, AESNI-SHA256 and GCM, and multi-buffer support
+     for TLS encrypt.
+
+     This work was sponsored by Intel Corp.
+     [Andy Polyakov]
+
+  *) Support for DTLS 1.2. This adds two sets of DTLS methods: DTLS_*_method()
+     supports both DTLS 1.2 and 1.0 and should use whatever version the peer
+     supports and DTLSv1_2_*_method() which supports DTLS 1.2 only.
+     [Steve Henson]
+
+  *) Use algorithm specific chains in SSL_CTX_use_certificate_chain_file():
+     this fixes a limitation in previous versions of OpenSSL.
+     [Steve Henson]
+
+  *) Extended RSA OAEP support via EVP_PKEY API. Options to specify digest,
+     MGF1 digest and OAEP label.
+     [Steve Henson]
+
+  *) Add EVP support for key wrapping algorithms, to avoid problems with
+     existing code the flag EVP_CIPHER_CTX_WRAP_ALLOW has to be set in
+     the EVP_CIPHER_CTX or an error is returned. Add AES and DES3 wrap
+     algorithms and include tests cases.
+     [Steve Henson]
+
+  *) Add functions to allocate and set the fields of an ECDSA_METHOD
+     structure.
+     [Douglas E. Engert, Steve Henson]
+
+  *) New functions OPENSSL_gmtime_diff and ASN1_TIME_diff to find the
+     difference in days and seconds between two tm or ASN1_TIME structures.
+     [Steve Henson]
+
+  *) Add -rev test option to s_server to just reverse order of characters
+     received by client and send back to server. Also prints an abbreviated
+     summary of the connection parameters.
+     [Steve Henson]
+
+  *) New option -brief for s_client and s_server to print out a brief summary
+     of connection parameters.
+     [Steve Henson]
+
+  *) Add callbacks for arbitrary TLS extensions.
+     [Trevor Perrin <trevp@trevp.net> and Ben Laurie]
+
+  *) New option -crl_download in several openssl utilities to download CRLs
+     from CRLDP extension in certificates.
+     [Steve Henson]
+
+  *) New options -CRL and -CRLform for s_client and s_server for CRLs.
+     [Steve Henson]
+
+  *) New function X509_CRL_diff to generate a delta CRL from the difference
+     of two full CRLs. Add support to "crl" utility.
+     [Steve Henson]
+
+  *) New functions to set lookup_crls function and to retrieve
+     X509_STORE from X509_STORE_CTX.
+     [Steve Henson]
+
+  *) Print out deprecated issuer and subject unique ID fields in
+     certificates.
+     [Steve Henson]
+
+  *) Extend OCSP I/O functions so they can be used for simple general purpose
+     HTTP as well as OCSP. New wrapper function which can be used to download
+     CRLs using the OCSP API.
+     [Steve Henson]
+
+  *) Delegate command line handling in s_client/s_server to SSL_CONF APIs.
+     [Steve Henson]
+
+  *) SSL_CONF* functions. These provide a common framework for application
+     configuration using configuration files or command lines.
+     [Steve Henson]
+
+  *) SSL/TLS tracing code. This parses out SSL/TLS records using the
+     message callback and prints the results. Needs compile time option
+     "enable-ssl-trace". New options to s_client and s_server to enable
+     tracing.
+     [Steve Henson]
+
+  *) New ctrl and macro to retrieve supported points extensions.
+     Print out extension in s_server and s_client.
+     [Steve Henson]
+
+  *) New functions to retrieve certificate signature and signature
+     OID NID.
+     [Steve Henson]
+
+  *) Add functions to retrieve and manipulate the raw cipherlist sent by a
+     client to OpenSSL.
+     [Steve Henson]
+
+  *) New Suite B modes for TLS code. These use and enforce the requirements
+     of RFC6460: restrict ciphersuites, only permit Suite B algorithms and
+     only use Suite B curves. The Suite B modes can be set by using the
+     strings "SUITEB128", "SUITEB192" or "SUITEB128ONLY" for the cipherstring.
+     [Steve Henson]
+
+  *) New chain verification flags for Suite B levels of security. Check
+     algorithms are acceptable when flags are set in X509_verify_cert.
+     [Steve Henson]
+
+  *) Make tls1_check_chain return a set of flags indicating checks passed
+     by a certificate chain. Add additional tests to handle client
+     certificates: checks for matching certificate type and issuer name
+     comparison.
+     [Steve Henson]
+
+  *) If an attempt is made to use a signature algorithm not in the peer
+     preference list abort the handshake. If client has no suitable
+     signature algorithms in response to a certificate request do not
+     use the certificate.
+     [Steve Henson]
+
+  *) If server EC tmp key is not in client preference list abort handshake.
+     [Steve Henson]
+
+  *) Add support for certificate stores in CERT structure. This makes it
+     possible to have different stores per SSL structure or one store in
+     the parent SSL_CTX. Include distinct stores for certificate chain
+     verification and chain building. New ctrl SSL_CTRL_BUILD_CERT_CHAIN
+     to build and store a certificate chain in CERT structure: returning
+     an error if the chain cannot be built: this will allow applications
+     to test if a chain is correctly configured.
+
+     Note: if the CERT based stores are not set then the parent SSL_CTX
+     store is used to retain compatibility with existing behaviour.
+
+     [Steve Henson]
+
+  *) New function ssl_set_client_disabled to set a ciphersuite disabled
+     mask based on the current session, check mask when sending client
+     hello and checking the requested ciphersuite.
+     [Steve Henson]
+
+  *) New ctrls to retrieve and set certificate types in a certificate
+     request message. Print out received values in s_client. If certificate
+     types is not set with custom values set sensible values based on
+     supported signature algorithms.
+     [Steve Henson]
+
+  *) Support for distinct client and server supported signature algorithms.
+     [Steve Henson]
+
+  *) Add certificate callback. If set this is called whenever a certificate
+     is required by client or server. An application can decide which
+     certificate chain to present based on arbitrary criteria: for example
+     supported signature algorithms. Add very simple example to s_server.
+     This fixes many of the problems and restrictions of the existing client
+     certificate callback: for example you can now clear an existing
+     certificate and specify the whole chain.
+     [Steve Henson]
+
+  *) Add new "valid_flags" field to CERT_PKEY structure which determines what
+     the certificate can be used for (if anything). Set valid_flags field 
+     in new tls1_check_chain function. Simplify ssl_set_cert_masks which used
+     to have similar checks in it.
+
+     Add new "cert_flags" field to CERT structure and include a "strict mode".
+     This enforces some TLS certificate requirements (such as only permitting
+     certificate signature algorithms contained in the supported algorithms
+     extension) which some implementations ignore: this option should be used
+     with caution as it could cause interoperability issues.
+     [Steve Henson]
+
+  *) Update and tidy signature algorithm extension processing. Work out
+     shared signature algorithms based on preferences and peer algorithms
+     and print them out in s_client and s_server. Abort handshake if no
+     shared signature algorithms.
+     [Steve Henson]
+
+  *) Add new functions to allow customised supported signature algorithms
+     for SSL and SSL_CTX structures. Add options to s_client and s_server
+     to support them.
+     [Steve Henson]
+
+  *) New function SSL_certs_clear() to delete all references to certificates
+     from an SSL structure. Before this once a certificate had been added
+     it couldn't be removed.
+     [Steve Henson]
+
+  *) Integrate hostname, email address and IP address checking with certificate
+     verification. New verify options supporting checking in openssl utility.
+     [Steve Henson]
+
+  *) Fixes and wildcard matching support to hostname and email checking
+     functions. Add manual page.
+     [Florian Weimer (Red Hat Product Security Team)]
+
+  *) New functions to check a hostname email or IP address against a
+     certificate. Add options x509 utility to print results of checks against
+     a certificate.
+     [Steve Henson]
+
+  *) Fix OCSP checking.
+     [Rob Stradling <rob.stradling@comodo.com> and Ben Laurie]
+
+  *) Initial experimental support for explicitly trusted non-root CAs. 
+     OpenSSL still tries to build a complete chain to a root but if an
+     intermediate CA has a trust setting included that is used. The first
+     setting is used: whether to trust (e.g., -addtrust option to the x509
+     utility) or reject.
+     [Steve Henson]
+
+  *) Add -trusted_first option which attempts to find certificates in the
+     trusted store even if an untrusted chain is also supplied.
+     [Steve Henson]
+
+  *) MIPS assembly pack updates: support for MIPS32r2 and SmartMIPS ASE,
+     platform support for Linux and Android.
+     [Andy Polyakov]
+
+  *) Support for linux-x32, ILP32 environment in x86_64 framework.
+     [Andy Polyakov]
+
+  *) Experimental multi-implementation support for FIPS capable OpenSSL.
+     When in FIPS mode the approved implementations are used as normal,
+     when not in FIPS mode the internal unapproved versions are used instead.
+     This means that the FIPS capable OpenSSL isn't forced to use the
+     (often lower performance) FIPS implementations outside FIPS mode.
+     [Steve Henson]
+
+  *) Transparently support X9.42 DH parameters when calling
+     PEM_read_bio_DHparameters. This means existing applications can handle
+     the new parameter format automatically.
+     [Steve Henson]
+
+  *) Initial experimental support for X9.42 DH parameter format: mainly
+     to support use of 'q' parameter for RFC5114 parameters.
+     [Steve Henson]
+
+  *) Add DH parameters from RFC5114 including test data to dhtest.
+     [Steve Henson]
+
+  *) Support for automatic EC temporary key parameter selection. If enabled
+     the most preferred EC parameters are automatically used instead of
+     hardcoded fixed parameters. Now a server just has to call:
+     SSL_CTX_set_ecdh_auto(ctx, 1) and the server will automatically
+     support ECDH and use the most appropriate parameters.
+     [Steve Henson]
+
+  *) Enhance and tidy EC curve and point format TLS extension code. Use
+     static structures instead of allocation if default values are used.
+     New ctrls to set curves we wish to support and to retrieve shared curves.
+     Print out shared curves in s_server. New options to s_server and s_client
+     to set list of supported curves.
+     [Steve Henson]
+
+  *) New ctrls to retrieve supported signature algorithms and 
+     supported curve values as an array of NIDs. Extend openssl utility
+     to print out received values.
+     [Steve Henson]
+
+  *) Add new APIs EC_curve_nist2nid and EC_curve_nid2nist which convert
+     between NIDs and the more common NIST names such as "P-256". Enhance
+     ecparam utility and ECC method to recognise the NIST names for curves.
+     [Steve Henson]
+
+  *) Enhance SSL/TLS certificate chain handling to support different
+     chains for each certificate instead of one chain in the parent SSL_CTX.
+     [Steve Henson]
+
+  *) Support for fixed DH ciphersuite client authentication: where both
+     server and client use DH certificates with common parameters.
+     [Steve Henson]
+
+  *) Support for fixed DH ciphersuites: those requiring DH server
+     certificates.
+     [Steve Henson]
+
+  *) New function i2d_re_X509_tbs for re-encoding the TBS portion of
+     the certificate.
+     Note: Related 1.0.2-beta specific macros X509_get_cert_info,
+     X509_CINF_set_modified, X509_CINF_get_issuer, X509_CINF_get_extensions and
+     X509_CINF_get_signature were reverted post internal team review.
+
+ Changes between 1.0.1k and 1.0.1l [15 Jan 2015]
+
+  *) Build fixes for the Windows and OpenVMS platforms
+     [Matt Caswell and Richard Levitte]
+
+ Changes between 1.0.1j and 1.0.1k [8 Jan 2015]
+
+  *) Fix DTLS segmentation fault in dtls1_get_record. A carefully crafted DTLS
+     message can cause a segmentation fault in OpenSSL due to a NULL pointer
+     dereference. This could lead to a Denial Of Service attack. Thanks to
+     Markus Stenberg of Cisco Systems, Inc. for reporting this issue.
+     (CVE-2014-3571)
+     [Steve Henson]
+
+  *) Fix DTLS memory leak in dtls1_buffer_record. A memory leak can occur in the
+     dtls1_buffer_record function under certain conditions. In particular this
+     could occur if an attacker sent repeated DTLS records with the same
+     sequence number but for the next epoch. The memory leak could be exploited
+     by an attacker in a Denial of Service attack through memory exhaustion.
+     Thanks to Chris Mueller for reporting this issue.
+     (CVE-2015-0206)
+     [Matt Caswell]
+
+  *) Fix issue where no-ssl3 configuration sets method to NULL. When openssl is
+     built with the no-ssl3 option and a SSL v3 ClientHello is received the ssl
+     method would be set to NULL which could later result in a NULL pointer
+     dereference. Thanks to Frank Schmirler for reporting this issue.
+     (CVE-2014-3569)
+     [Kurt Roeckx]
+
+  *) Abort handshake if server key exchange message is omitted for ephemeral
+     ECDH ciphersuites.
+
+     Thanks to Karthikeyan Bhargavan of the PROSECCO team at INRIA for
+     reporting this issue.
+     (CVE-2014-3572)
+     [Steve Henson]
+
+  *) Remove non-export ephemeral RSA code on client and server. This code
+     violated the TLS standard by allowing the use of temporary RSA keys in
+     non-export ciphersuites and could be used by a server to effectively
+     downgrade the RSA key length used to a value smaller than the server
+     certificate. Thanks for Karthikeyan Bhargavan of the PROSECCO team at
+     INRIA or reporting this issue.
+     (CVE-2015-0204)
+     [Steve Henson]
+
+  *) Fixed issue where DH client certificates are accepted without verification.
+     An OpenSSL server will accept a DH certificate for client authentication
+     without the certificate verify message. This effectively allows a client to
+     authenticate without the use of a private key. This only affects servers
+     which trust a client certificate authority which issues certificates
+     containing DH keys: these are extremely rare and hardly ever encountered.
+     Thanks for Karthikeyan Bhargavan of the PROSECCO team at INRIA or reporting
+     this issue.
+     (CVE-2015-0205)
+     [Steve Henson]
+
+  *) Ensure that the session ID context of an SSL is updated when its
+     SSL_CTX is updated via SSL_set_SSL_CTX.
+
+     The session ID context is typically set from the parent SSL_CTX,
+     and can vary with the CTX.
+     [Adam Langley]
+
+  *) Fix various certificate fingerprint issues.
+
+     By using non-DER or invalid encodings outside the signed portion of a
+     certificate the fingerprint can be changed without breaking the signature.
+     Although no details of the signed portion of the certificate can be changed
+     this can cause problems with some applications: e.g. those using the
+     certificate fingerprint for blacklists.
+
+     1. Reject signatures with non zero unused bits.
+
+     If the BIT STRING containing the signature has non zero unused bits reject
+     the signature. All current signature algorithms require zero unused bits.
+
+     2. Check certificate algorithm consistency.
+
+     Check the AlgorithmIdentifier inside TBS matches the one in the
+     certificate signature. NB: this will result in signature failure
+     errors for some broken certificates.
+
+     Thanks to Konrad Kraszewski from Google for reporting this issue.
+
+     3. Check DSA/ECDSA signatures use DER.
+
+     Re-encode DSA/ECDSA signatures and compare with the original received
+     signature. Return an error if there is a mismatch.
+
+     This will reject various cases including garbage after signature
+     (thanks to Antti Karjalainen and Tuomo Untinen from the Codenomicon CROSS
+     program for discovering this case) and use of BER or invalid ASN.1 INTEGERs
+     (negative or with leading zeroes).
+
+     Further analysis was conducted and fixes were developed by Stephen Henson
+     of the OpenSSL core team.
+
+     (CVE-2014-8275)
+     [Steve Henson]
+
+   *) Correct Bignum squaring. Bignum squaring (BN_sqr) may produce incorrect
+      results on some platforms, including x86_64. This bug occurs at random
+      with a very low probability, and is not known to be exploitable in any
+      way, though its exact impact is difficult to determine. Thanks to Pieter
+      Wuille (Blockstream) who reported this issue and also suggested an initial
+      fix. Further analysis was conducted by the OpenSSL development team and
+      Adam Langley of Google. The final fix was developed by Andy Polyakov of
+      the OpenSSL core team.
+      (CVE-2014-3570)
+      [Andy Polyakov]
+
+   *) Do not resume sessions on the server if the negotiated protocol
+      version does not match the session's version. Resuming with a different
+      version, while not strictly forbidden by the RFC, is of questionable
+      sanity and breaks all known clients.
+      [David Benjamin, Emilia KÃ¤sper]
+
+   *) Tighten handling of the ChangeCipherSpec (CCS) message: reject
+      early CCS messages during renegotiation. (Note that because
+      renegotiation is encrypted, this early CCS was not exploitable.)
+      [Emilia KÃ¤sper]
+
+   *) Tighten client-side session ticket handling during renegotiation:
+      ensure that the client only accepts a session ticket if the server sends
+      the extension anew in the ServerHello. Previously, a TLS client would
+      reuse the old extension state and thus accept a session ticket if one was
+      announced in the initial ServerHello.
+
+      Similarly, ensure that the client requires a session ticket if one
+      was advertised in the ServerHello. Previously, a TLS client would
+      ignore a missing NewSessionTicket message.
+      [Emilia KÃ¤sper]
+
+ Changes between 1.0.1i and 1.0.1j [15 Oct 2014]
+
+  *) SRTP Memory Leak.
+
+     A flaw in the DTLS SRTP extension parsing code allows an attacker, who
+     sends a carefully crafted handshake message, to cause OpenSSL to fail
+     to free up to 64k of memory causing a memory leak. This could be
+     exploited in a Denial Of Service attack. This issue affects OpenSSL
+     1.0.1 server implementations for both SSL/TLS and DTLS regardless of
+     whether SRTP is used or configured. Implementations of OpenSSL that
+     have been compiled with OPENSSL_NO_SRTP defined are not affected.
+
+     The fix was developed by the OpenSSL team.
+     (CVE-2014-3513)
+     [OpenSSL team]
+
+  *) Session Ticket Memory Leak.
+
+     When an OpenSSL SSL/TLS/DTLS server receives a session ticket the
+     integrity of that ticket is first verified. In the event of a session
+     ticket integrity check failing, OpenSSL will fail to free memory
+     causing a memory leak. By sending a large number of invalid session
+     tickets an attacker could exploit this issue in a Denial Of Service
+     attack.
+     (CVE-2014-3567)
+     [Steve Henson]
+
+  *) Build option no-ssl3 is incomplete.
+
+     When OpenSSL is configured with "no-ssl3" as a build option, servers
+     could accept and complete a SSL 3.0 handshake, and clients could be
+     configured to send them.
+     (CVE-2014-3568)
+     [Akamai and the OpenSSL team]
+
+  *) Add support for TLS_FALLBACK_SCSV.
+     Client applications doing fallback retries should call
+     SSL_set_mode(s, SSL_MODE_SEND_FALLBACK_SCSV).
+     (CVE-2014-3566)
+     [Adam Langley, Bodo Moeller]
+
+  *) Add additional DigestInfo checks.
+ 
+     Re-encode DigestInto in DER and check against the original when
+     verifying RSA signature: this will reject any improperly encoded
+     DigestInfo structures.
+
+     Note: this is a precautionary measure and no attacks are currently known.
+
+     [Steve Henson]
+
+ Changes between 1.0.1h and 1.0.1i [6 Aug 2014]
+
+  *) Fix SRP buffer overrun vulnerability. Invalid parameters passed to the
+     SRP code can be overrun an internal buffer. Add sanity check that
+     g, A, B < N to SRP code.
+
+     Thanks to Sean Devlin and Watson Ladd of Cryptography Services, NCC
+     Group for discovering this issue.
+     (CVE-2014-3512)
+     [Steve Henson]
+
+  *) A flaw in the OpenSSL SSL/TLS server code causes the server to negotiate
+     TLS 1.0 instead of higher protocol versions when the ClientHello message
+     is badly fragmented. This allows a man-in-the-middle attacker to force a
+     downgrade to TLS 1.0 even if both the server and the client support a
+     higher protocol version, by modifying the client's TLS records.
+
+     Thanks to David Benjamin and Adam Langley (Google) for discovering and
+     researching this issue.
+     (CVE-2014-3511)
+     [David Benjamin]
+
+  *) OpenSSL DTLS clients enabling anonymous (EC)DH ciphersuites are subject
+     to a denial of service attack. A malicious server can crash the client
+     with a null pointer dereference (read) by specifying an anonymous (EC)DH
+     ciphersuite and sending carefully crafted handshake messages.
+
+     Thanks to Felix GrÃ¶bert (Google) for discovering and researching this
+     issue.
+     (CVE-2014-3510)
+     [Emilia KÃ¤sper]
+
+  *) By sending carefully crafted DTLS packets an attacker could cause openssl
+     to leak memory. This can be exploited through a Denial of Service attack.
+     Thanks to Adam Langley for discovering and researching this issue.
+     (CVE-2014-3507)
+     [Adam Langley]
+
+  *) An attacker can force openssl to consume large amounts of memory whilst
+     processing DTLS handshake messages. This can be exploited through a
+     Denial of Service attack.
+     Thanks to Adam Langley for discovering and researching this issue.
+     (CVE-2014-3506)
+     [Adam Langley]
+
+  *) An attacker can force an error condition which causes openssl to crash
+     whilst processing DTLS packets due to memory being freed twice. This
+     can be exploited through a Denial of Service attack.
+     Thanks to Adam Langley and Wan-Teh Chang for discovering and researching
+     this issue.
+     (CVE-2014-3505)
+     [Adam Langley]
+
+  *) If a multithreaded client connects to a malicious server using a resumed
+     session and the server sends an ec point format extension it could write
+     up to 255 bytes to freed memory.
+
+     Thanks to Gabor Tyukasz (LogMeIn Inc) for discovering and researching this
+     issue.
+     (CVE-2014-3509)
+     [Gabor Tyukasz]
+
+  *) A malicious server can crash an OpenSSL client with a null pointer
+     dereference (read) by specifying an SRP ciphersuite even though it was not
+     properly negotiated with the client. This can be exploited through a
+     Denial of Service attack.
+
+     Thanks to Joonas Kuorilehto and Riku HietamÃ¤ki (Codenomicon) for
+     discovering and researching this issue.
+     (CVE-2014-5139)
+     [Steve Henson]
+
+  *) A flaw in OBJ_obj2txt may cause pretty printing functions such as
+     X509_name_oneline, X509_name_print_ex et al. to leak some information
+     from the stack. Applications may be affected if they echo pretty printing
+     output to the attacker.
+
+     Thanks to Ivan Fratric (Google) for discovering this issue.
+     (CVE-2014-3508)
+     [Emilia KÃ¤sper, and Steve Henson]
+
+  *) Fix ec_GFp_simple_points_make_affine (thus, EC_POINTs_mul etc.)
+     for corner cases. (Certain input points at infinity could lead to
+     bogus results, with non-infinity inputs mapped to infinity too.)
+     [Bodo Moeller]
+
+ Changes between 1.0.1g and 1.0.1h [5 Jun 2014]
+
+  *) Fix for SSL/TLS MITM flaw. An attacker using a carefully crafted
+     handshake can force the use of weak keying material in OpenSSL
+     SSL/TLS clients and servers.
+
+     Thanks to KIKUCHI Masashi (Lepidum Co. Ltd.) for discovering and
+     researching this issue. (CVE-2014-0224)
+     [KIKUCHI Masashi, Steve Henson]
+
+  *) Fix DTLS recursion flaw. By sending an invalid DTLS handshake to an
+     OpenSSL DTLS client the code can be made to recurse eventually crashing
+     in a DoS attack.
+
+     Thanks to Imre Rad (Search-Lab Ltd.) for discovering this issue.
+     (CVE-2014-0221)
+     [Imre Rad, Steve Henson]
+
+  *) Fix DTLS invalid fragment vulnerability. A buffer overrun attack can
+     be triggered by sending invalid DTLS fragments to an OpenSSL DTLS
+     client or server. This is potentially exploitable to run arbitrary
+     code on a vulnerable client or server.
+
+     Thanks to JÃ¼ri Aedla for reporting this issue. (CVE-2014-0195)
+     [JÃ¼ri Aedla, Steve Henson]
+
+  *) Fix bug in TLS code where clients enable anonymous ECDH ciphersuites
+     are subject to a denial of service attack.
+
+     Thanks to Felix GrÃ¶bert and Ivan Fratric at Google for discovering
+     this issue. (CVE-2014-3470)
+     [Felix GrÃ¶bert, Ivan Fratric, Steve Henson]
+
+  *) Harmonize version and its documentation. -f flag is used to display
+     compilation flags.
+     [mancha <mancha1@zoho.com>]
+
+  *) Fix eckey_priv_encode so it immediately returns an error upon a failure
+     in i2d_ECPrivateKey.
+     [mancha <mancha1@zoho.com>]
+
+  *) Fix some double frees. These are not thought to be exploitable.
+     [mancha <mancha1@zoho.com>]
+
+ Changes between 1.0.1f and 1.0.1g [7 Apr 2014]
+
+  *) A missing bounds check in the handling of the TLS heartbeat extension
+     can be used to reveal up to 64k of memory to a connected client or
+     server.
+
+     Thanks for Neel Mehta of Google Security for discovering this bug and to
+     Adam Langley <agl@chromium.org> and Bodo Moeller <bmoeller@acm.org> for
+     preparing the fix (CVE-2014-0160)
+     [Adam Langley, Bodo Moeller]
+
+  *) Fix for the attack described in the paper "Recovering OpenSSL
+     ECDSA Nonces Using the FLUSH+RELOAD Cache Side-channel Attack"
+     by Yuval Yarom and Naomi Benger. Details can be obtained from:
+     http://eprint.iacr.org/2014/140
+
+     Thanks to Yuval Yarom and Naomi Benger for discovering this
+     flaw and to Yuval Yarom for supplying a fix (CVE-2014-0076)
+     [Yuval Yarom and Naomi Benger]
+
+  *) TLS pad extension: draft-agl-tls-padding-03
+
+     Workaround for the "TLS hang bug" (see FAQ and PR#2771): if the
+     TLS client Hello record length value would otherwise be > 255 and
+     less that 512 pad with a dummy extension containing zeroes so it
+     is at least 512 bytes long.
+
+     [Adam Langley, Steve Henson]
+
+ Changes between 1.0.1e and 1.0.1f [6 Jan 2014]
+
+  *) Fix for TLS record tampering bug. A carefully crafted invalid 
+     handshake could crash OpenSSL with a NULL pointer exception.
+     Thanks to Anton Johansson for reporting this issues.
+     (CVE-2013-4353)
+
+  *) Keep original DTLS digest and encryption contexts in retransmission
+     structures so we can use the previous session parameters if they need
+     to be resent. (CVE-2013-6450)
+     [Steve Henson]
+
+  *) Add option SSL_OP_SAFARI_ECDHE_ECDSA_BUG (part of SSL_OP_ALL) which
+     avoids preferring ECDHE-ECDSA ciphers when the client appears to be
+     Safari on OS X.  Safari on OS X 10.8..10.8.3 advertises support for
+     several ECDHE-ECDSA ciphers, but fails to negotiate them.  The bug
+     is fixed in OS X 10.8.4, but Apple have ruled out both hot fixing
+     10.8..10.8.3 and forcing users to upgrade to 10.8.4 or newer.
+     [Rob Stradling, Adam Langley]
+
+ Changes between 1.0.1d and 1.0.1e [11 Feb 2013]
+
+  *) Correct fix for CVE-2013-0169. The original didn't work on AES-NI
+     supporting platforms or when small records were transferred.
+     [Andy Polyakov, Steve Henson]
+
+ Changes between 1.0.1c and 1.0.1d [5 Feb 2013]
+
+  *) Make the decoding of SSLv3, TLS and DTLS CBC records constant time.
+
+     This addresses the flaw in CBC record processing discovered by 
+     Nadhem Alfardan and Kenny Paterson. Details of this attack can be found
+     at: http://www.isg.rhul.ac.uk/tls/     
+
+     Thanks go to Nadhem Alfardan and Kenny Paterson of the Information
+     Security Group at Royal Holloway, University of London
+     (www.isg.rhul.ac.uk) for discovering this flaw and Adam Langley and
+     Emilia KÃ¤sper for the initial patch.
+     (CVE-2013-0169)
+     [Emilia KÃ¤sper, Adam Langley, Ben Laurie, Andy Polyakov, Steve Henson]
+
+  *) Fix flaw in AESNI handling of TLS 1.2 and 1.1 records for CBC mode
+     ciphersuites which can be exploited in a denial of service attack.
+     Thanks go to and to Adam Langley <agl@chromium.org> for discovering
+     and detecting this bug and to Wolfgang Ettlinger
+     <wolfgang.ettlinger@gmail.com> for independently discovering this issue.
+     (CVE-2012-2686)
+     [Adam Langley]
+
+  *) Return an error when checking OCSP signatures when key is NULL.
+     This fixes a DoS attack. (CVE-2013-0166)
+     [Steve Henson]
+
+  *) Make openssl verify return errors.
+     [Chris Palmer <palmer@google.com> and Ben Laurie]
+
+  *) Call OCSP Stapling callback after ciphersuite has been chosen, so
+     the right response is stapled. Also change SSL_get_certificate()
+     so it returns the certificate actually sent.
+     See http://rt.openssl.org/Ticket/Display.html?id=2836.
+     [Rob Stradling <rob.stradling@comodo.com>]
+
+  *) Fix possible deadlock when decoding public keys.
+     [Steve Henson]
+
+  *) Don't use TLS 1.0 record version number in initial client hello
+     if renegotiating.
+     [Steve Henson]
+
+ Changes between 1.0.1b and 1.0.1c [10 May 2012]
+
+  *) Sanity check record length before skipping explicit IV in TLS
+     1.2, 1.1 and DTLS to fix DoS attack.
+
+     Thanks to Codenomicon for discovering this issue using Fuzz-o-Matic
+     fuzzing as a service testing platform.
+     (CVE-2012-2333)
+     [Steve Henson]
+
+  *) Initialise tkeylen properly when encrypting CMS messages.
+     Thanks to Solar Designer of Openwall for reporting this issue.
+     [Steve Henson]
+
+  *) In FIPS mode don't try to use composite ciphers as they are not
+     approved.
+     [Steve Henson]
+
+ Changes between 1.0.1a and 1.0.1b [26 Apr 2012]
+
+  *) OpenSSL 1.0.0 sets SSL_OP_ALL to 0x80000FFFL and OpenSSL 1.0.1 and
+     1.0.1a set SSL_OP_NO_TLSv1_1 to 0x00000400L which would unfortunately
+     mean any application compiled against OpenSSL 1.0.0 headers setting
+     SSL_OP_ALL would also set SSL_OP_NO_TLSv1_1, unintentionally disablng
+     TLS 1.1 also. Fix this by changing the value of SSL_OP_NO_TLSv1_1 to
+     0x10000000L Any application which was previously compiled against
+     OpenSSL 1.0.1 or 1.0.1a headers and which cares about SSL_OP_NO_TLSv1_1
+     will need to be recompiled as a result. Letting be results in
+     inability to disable specifically TLS 1.1 and in client context,
+     in unlike event, limit maximum offered version to TLS 1.0 [see below].
+     [Steve Henson]
+
+  *) In order to ensure interoperabilty SSL_OP_NO_protocolX does not
+     disable just protocol X, but all protocols above X *if* there are
+     protocols *below* X still enabled. In more practical terms it means
+     that if application wants to disable TLS1.0 in favor of TLS1.1 and
+     above, it's not sufficient to pass SSL_OP_NO_TLSv1, one has to pass
+     SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2. This applies to
+     client side.
+     [Andy Polyakov]
+
+ Changes between 1.0.1 and 1.0.1a [19 Apr 2012]
+
+  *) Check for potentially exploitable overflows in asn1_d2i_read_bio
+     BUF_mem_grow and BUF_mem_grow_clean. Refuse attempts to shrink buffer
+     in CRYPTO_realloc_clean.
+
+     Thanks to Tavis Ormandy, Google Security Team, for discovering this
+     issue and to Adam Langley <agl@chromium.org> for fixing it.
+     (CVE-2012-2110)
+     [Adam Langley (Google), Tavis Ormandy, Google Security Team]
+
+  *) Don't allow TLS 1.2 SHA-256 ciphersuites in TLS 1.0, 1.1 connections.
+     [Adam Langley]
+
+  *) Workarounds for some broken servers that "hang" if a client hello
+     record length exceeds 255 bytes.
+
+     1. Do not use record version number > TLS 1.0 in initial client
+        hello: some (but not all) hanging servers will now work.
+     2. If we set OPENSSL_MAX_TLS1_2_CIPHER_LENGTH this will truncate
+	the number of ciphers sent in the client hello. This should be
+        set to an even number, such as 50, for example by passing:
+        -DOPENSSL_MAX_TLS1_2_CIPHER_LENGTH=50 to config or Configure.
+        Most broken servers should now work.
+     3. If all else fails setting OPENSSL_NO_TLS1_2_CLIENT will disable
+	TLS 1.2 client support entirely.
+     [Steve Henson]
+
+  *) Fix SEGV in Vector Permutation AES module observed in OpenSSH.
+     [Andy Polyakov]
+
+ Changes between 1.0.0h and 1.0.1  [14 Mar 2012]
+
+  *) Add compatibility with old MDC2 signatures which use an ASN1 OCTET
+     STRING form instead of a DigestInfo.
+     [Steve Henson]
+
+  *) The format used for MDC2 RSA signatures is inconsistent between EVP
+     and the RSA_sign/RSA_verify functions. This was made more apparent when
+     OpenSSL used RSA_sign/RSA_verify for some RSA signatures in particular
+     those which went through EVP_PKEY_METHOD in 1.0.0 and later. Detect 
+     the correct format in RSA_verify so both forms transparently work.
+     [Steve Henson]
+
+  *) Some servers which support TLS 1.0 can choke if we initially indicate
+     support for TLS 1.2 and later renegotiate using TLS 1.0 in the RSA
+     encrypted premaster secret. As a workaround use the maximum permitted
+     client version in client hello, this should keep such servers happy
+     and still work with previous versions of OpenSSL.
+     [Steve Henson]
+
+  *) Add support for TLS/DTLS heartbeats.
+     [Robin Seggelmann <seggelmann@fh-muenster.de>]
+
+  *) Add support for SCTP.
+     [Robin Seggelmann <seggelmann@fh-muenster.de>]
+
+  *) Improved PRNG seeding for VOS.
+     [Paul Green <Paul.Green@stratus.com>]
+
+  *) Extensive assembler packs updates, most notably:
+
+	- x86[_64]:     AES-NI, PCLMULQDQ, RDRAND support;
+	- x86[_64]:     SSSE3 support (SHA1, vector-permutation AES);
+	- x86_64:       bit-sliced AES implementation;
+	- ARM:          NEON support, contemporary platforms optimizations;
+	- s390x:        z196 support;
+	- *:            GHASH and GF(2^m) multiplication implementations;
+
+     [Andy Polyakov]
+
+  *) Make TLS-SRP code conformant with RFC 5054 API cleanup
+     (removal of unnecessary code)
+     [Peter Sylvester <peter.sylvester@edelweb.fr>]
+
+  *) Add TLS key material exporter from RFC 5705.
+     [Eric Rescorla]
+
+  *) Add DTLS-SRTP negotiation from RFC 5764.
+     [Eric Rescorla]
+
+  *) Add Next Protocol Negotiation,
+     http://tools.ietf.org/html/draft-agl-tls-nextprotoneg-00. Can be
+     disabled with a no-npn flag to config or Configure. Code donated
+     by Google.
+     [Adam Langley <agl@google.com> and Ben Laurie]
+
+  *) Add optional 64-bit optimized implementations of elliptic curves NIST-P224,
+     NIST-P256, NIST-P521, with constant-time single point multiplication on
+     typical inputs. Compiler support for the nonstandard type __uint128_t is
+     required to use this (present in gcc 4.4 and later, for 64-bit builds).
+     Code made available under Apache License version 2.0.
+
+     Specify "enable-ec_nistp_64_gcc_128" on the Configure (or config) command
+     line to include this in your build of OpenSSL, and run "make depend" (or
+     "make update"). This enables the following EC_METHODs:
+
+         EC_GFp_nistp224_method()
+         EC_GFp_nistp256_method()
+         EC_GFp_nistp521_method()
+
+     EC_GROUP_new_by_curve_name() will automatically use these (while
+     EC_GROUP_new_curve_GFp() currently prefers the more flexible
+     implementations).
+     [Emilia KÃ¤sper, Adam Langley, Bodo Moeller (Google)]
+
+  *) Use type ossl_ssize_t instad of ssize_t which isn't available on
+     all platforms. Move ssize_t definition from e_os.h to the public
+     header file e_os2.h as it now appears in public header file cms.h
+     [Steve Henson]
+
+  *) New -sigopt option to the ca, req and x509 utilities. Additional
+     signature parameters can be passed using this option and in
+     particular PSS. 
+     [Steve Henson]
+
+  *) Add RSA PSS signing function. This will generate and set the
+     appropriate AlgorithmIdentifiers for PSS based on those in the
+     corresponding EVP_MD_CTX structure. No application support yet.
+     [Steve Henson]
+
+  *) Support for companion algorithm specific ASN1 signing routines.
+     New function ASN1_item_sign_ctx() signs a pre-initialised
+     EVP_MD_CTX structure and sets AlgorithmIdentifiers based on
+     the appropriate parameters.
+     [Steve Henson]
+
+  *) Add new algorithm specific ASN1 verification initialisation function
+     to EVP_PKEY_ASN1_METHOD: this is not in EVP_PKEY_METHOD since the ASN1
+     handling will be the same no matter what EVP_PKEY_METHOD is used.
+     Add a PSS handler to support verification of PSS signatures: checked
+     against a number of sample certificates.
+     [Steve Henson]
+
+  *) Add signature printing for PSS. Add PSS OIDs.
+     [Steve Henson, Martin Kaiser <lists@kaiser.cx>]
+
+  *) Add algorithm specific signature printing. An individual ASN1 method
+     can now print out signatures instead of the standard hex dump. 
+
+     More complex signatures (e.g. PSS) can print out more meaningful
+     information. Include DSA version that prints out the signature
+     parameters r, s.
+     [Steve Henson]
+
+  *) Password based recipient info support for CMS library: implementing
+     RFC3211.
+     [Steve Henson]
+
+  *) Split password based encryption into PBES2 and PBKDF2 functions. This
+     neatly separates the code into cipher and PBE sections and is required
+     for some algorithms that split PBES2 into separate pieces (such as
+     password based CMS).
+     [Steve Henson]
+
+  *) Session-handling fixes:
+     - Fix handling of connections that are resuming with a session ID,
+       but also support Session Tickets.
+     - Fix a bug that suppressed issuing of a new ticket if the client
+       presented a ticket with an expired session.
+     - Try to set the ticket lifetime hint to something reasonable.
+     - Make tickets shorter by excluding irrelevant information.
+     - On the client side, don't ignore renewed tickets.
+     [Adam Langley, Bodo Moeller (Google)]
+
+  *) Fix PSK session representation.
+     [Bodo Moeller]
+
+  *) Add RC4-MD5 and AESNI-SHA1 "stitched" implementations.
+
+     This work was sponsored by Intel.
+     [Andy Polyakov]
+
+  *) Add GCM support to TLS library. Some custom code is needed to split
+     the IV between the fixed (from PRF) and explicit (from TLS record)
+     portions. This adds all GCM ciphersuites supported by RFC5288 and 
+     RFC5289. Generalise some AES* cipherstrings to include GCM and
+     add a special AESGCM string for GCM only.
+     [Steve Henson]
+
+  *) Expand range of ctrls for AES GCM. Permit setting invocation
+     field on decrypt and retrieval of invocation field only on encrypt.
+     [Steve Henson]
+
+  *) Add HMAC ECC ciphersuites from RFC5289. Include SHA384 PRF support.
+     As required by RFC5289 these ciphersuites cannot be used if for
+     versions of TLS earlier than 1.2.
+     [Steve Henson]
+
+  *) For FIPS capable OpenSSL interpret a NULL default public key method
+     as unset and return the appropriate default but do *not* set the default.
+     This means we can return the appropriate method in applications that
+     switch between FIPS and non-FIPS modes.
+     [Steve Henson]
+
+  *) Redirect HMAC and CMAC operations to FIPS module in FIPS mode. If an
+     ENGINE is used then we cannot handle that in the FIPS module so we
+     keep original code iff non-FIPS operations are allowed.
+     [Steve Henson]
+
+  *) Add -attime option to openssl utilities.
+     [Peter Eckersley <pde@eff.org>, Ben Laurie and Steve Henson]
+
+  *) Redirect DSA and DH operations to FIPS module in FIPS mode.
+     [Steve Henson]
+
+  *) Redirect ECDSA and ECDH operations to FIPS module in FIPS mode. Also use
+     FIPS EC methods unconditionally for now.
+     [Steve Henson]
+
+  *) New build option no-ec2m to disable characteristic 2 code.
+     [Steve Henson]
+
+  *) Backport libcrypto audit of return value checking from 1.1.0-dev; not
+     all cases can be covered as some introduce binary incompatibilities.
+     [Steve Henson]
+
+  *) Redirect RSA operations to FIPS module including keygen,
+     encrypt, decrypt, sign and verify. Block use of non FIPS RSA methods.
+     [Steve Henson]
+
+  *) Add similar low level API blocking to ciphers.
+     [Steve Henson]
+
+  *) Low level digest APIs are not approved in FIPS mode: any attempt
+     to use these will cause a fatal error. Applications that *really* want
+     to use them can use the private_* version instead.
+     [Steve Henson]
+
+  *) Redirect cipher operations to FIPS module for FIPS builds. 
+     [Steve Henson]
+
+  *) Redirect digest operations to FIPS module for FIPS builds. 
+     [Steve Henson]
+
+  *) Update build system to add "fips" flag which will link in fipscanister.o
+     for static and shared library builds embedding a signature if needed.
+     [Steve Henson]
+
+  *) Output TLS supported curves in preference order instead of numerical
+     order. This is currently hardcoded for the highest order curves first.
+     This should be configurable so applications can judge speed vs strength.
+     [Steve Henson]
+
+  *) Add TLS v1.2 server support for client authentication. 
+     [Steve Henson]
+
+  *) Add support for FIPS mode in ssl library: disable SSLv3, non-FIPS ciphers
+     and enable MD5.
+     [Steve Henson]
+
+  *) Functions FIPS_mode_set() and FIPS_mode() which call the underlying
+     FIPS modules versions.
+     [Steve Henson]
+
+  *) Add TLS v1.2 client side support for client authentication. Keep cache
+     of handshake records longer as we don't know the hash algorithm to use
+     until after the certificate request message is received.
+     [Steve Henson]
+
+  *) Initial TLS v1.2 client support. Add a default signature algorithms
+     extension including all the algorithms we support. Parse new signature
+     format in client key exchange. Relax some ECC signing restrictions for
+     TLS v1.2 as indicated in RFC5246.
+     [Steve Henson]
+
+  *) Add server support for TLS v1.2 signature algorithms extension. Switch
+     to new signature format when needed using client digest preference.
+     All server ciphersuites should now work correctly in TLS v1.2. No client
+     support yet and no support for client certificates.
+     [Steve Henson]
+
+  *) Initial TLS v1.2 support. Add new SHA256 digest to ssl code, switch
+     to SHA256 for PRF when using TLS v1.2 and later. Add new SHA256 based
+     ciphersuites. At present only RSA key exchange ciphersuites work with
+     TLS v1.2. Add new option for TLS v1.2 replacing the old and obsolete
+     SSL_OP_PKCS1_CHECK flags with SSL_OP_NO_TLSv1_2. New TLSv1.2 methods
+     and version checking.
+     [Steve Henson]
+
+  *) New option OPENSSL_NO_SSL_INTERN. If an application can be compiled
+     with this defined it will not be affected by any changes to ssl internal
+     structures. Add several utility functions to allow openssl application
+     to work with OPENSSL_NO_SSL_INTERN defined.
+     [Steve Henson]
+
+  *) Add SRP support.
+     [Tom Wu <tjw@cs.stanford.edu> and Ben Laurie]
+
+  *) Add functions to copy EVP_PKEY_METHOD and retrieve flags and id.
+     [Steve Henson]
+
+  *) Permit abbreviated handshakes when renegotiating using the function
+     SSL_renegotiate_abbreviated().
+     [Robin Seggelmann <seggelmann@fh-muenster.de>]
+
+  *) Add call to ENGINE_register_all_complete() to
+     ENGINE_load_builtin_engines(), so some implementations get used
+     automatically instead of needing explicit application support.
+     [Steve Henson]
+
+  *) Add support for TLS key exporter as described in RFC5705.
+     [Robin Seggelmann <seggelmann@fh-muenster.de>, Steve Henson]
+
+  *) Initial TLSv1.1 support. Since TLSv1.1 is very similar to TLS v1.0 only
+     a few changes are required:
+
+       Add SSL_OP_NO_TLSv1_1 flag.
+       Add TLSv1_1 methods.
+       Update version checking logic to handle version 1.1.
+       Add explicit IV handling (ported from DTLS code).
+       Add command line options to s_client/s_server.
+     [Steve Henson]
+
+ Changes between 1.0.0g and 1.0.0h [12 Mar 2012]
+
+  *) Fix MMA (Bleichenbacher's attack on PKCS #1 v1.5 RSA padding) weakness
+     in CMS and PKCS7 code. When RSA decryption fails use a random key for
+     content decryption and always return the same error. Note: this attack
+     needs on average 2^20 messages so it only affects automated senders. The
+     old behaviour can be re-enabled in the CMS code by setting the
+     CMS_DEBUG_DECRYPT flag: this is useful for debugging and testing where
+     an MMA defence is not necessary.
+     Thanks to Ivan Nestlerode <inestlerode@us.ibm.com> for discovering
+     this issue. (CVE-2012-0884)
+     [Steve Henson]
+
+  *) Fix CVE-2011-4619: make sure we really are receiving a 
+     client hello before rejecting multiple SGC restarts. Thanks to
+     Ivan Nestlerode <inestlerode@us.ibm.com> for discovering this bug.
+     [Steve Henson]
+
+ Changes between 1.0.0f and 1.0.0g [18 Jan 2012]
+
+  *) Fix for DTLS DoS issue introduced by fix for CVE-2011-4109.
+     Thanks to Antonio Martin, Enterprise Secure Access Research and
+     Development, Cisco Systems, Inc. for discovering this bug and
+     preparing a fix. (CVE-2012-0050)
+     [Antonio Martin]
+
+ Changes between 1.0.0e and 1.0.0f [4 Jan 2012]
+
+  *) Nadhem Alfardan and Kenny Paterson have discovered an extension
+     of the Vaudenay padding oracle attack on CBC mode encryption
+     which enables an efficient plaintext recovery attack against
+     the OpenSSL implementation of DTLS. Their attack exploits timing
+     differences arising during decryption processing. A research
+     paper describing this attack can be found at:
+                  http://www.isg.rhul.ac.uk/~kp/dtls.pdf
+     Thanks go to Nadhem Alfardan and Kenny Paterson of the Information
+     Security Group at Royal Holloway, University of London
+     (www.isg.rhul.ac.uk) for discovering this flaw and to Robin Seggelmann
+     <seggelmann@fh-muenster.de> and Michael Tuexen <tuexen@fh-muenster.de>
+     for preparing the fix. (CVE-2011-4108)
+     [Robin Seggelmann, Michael Tuexen]
+
+  *) Clear bytes used for block padding of SSL 3.0 records.
+     (CVE-2011-4576)
+     [Adam Langley (Google)]
+
+  *) Only allow one SGC handshake restart for SSL/TLS. Thanks to George
+     Kadianakis <desnacked@gmail.com> for discovering this issue and
+     Adam Langley for preparing the fix. (CVE-2011-4619)
+     [Adam Langley (Google)]
+
+  *) Check parameters are not NULL in GOST ENGINE. (CVE-2012-0027)
+     [Andrey Kulikov <amdeich@gmail.com>]
+
+  *) Prevent malformed RFC3779 data triggering an assertion failure.
+     Thanks to Andrew Chi, BBN Technologies, for discovering the flaw
+     and Rob Austein <sra@hactrn.net> for fixing it. (CVE-2011-4577)
+     [Rob Austein <sra@hactrn.net>]
+
+  *) Improved PRNG seeding for VOS.
+     [Paul Green <Paul.Green@stratus.com>]
+
+  *) Fix ssl_ciph.c set-up race.
+     [Adam Langley (Google)]
+
+  *) Fix spurious failures in ecdsatest.c.
+     [Emilia KÃ¤sper (Google)]
+
+  *) Fix the BIO_f_buffer() implementation (which was mixing different
+     interpretations of the '..._len' fields).
+     [Adam Langley (Google)]
+
+  *) Fix handling of BN_BLINDING: now BN_BLINDING_invert_ex (rather than
+     BN_BLINDING_invert_ex) calls BN_BLINDING_update, ensuring that concurrent
+     threads won't reuse the same blinding coefficients.
+
+     This also avoids the need to obtain the CRYPTO_LOCK_RSA_BLINDING
+     lock to call BN_BLINDING_invert_ex, and avoids one use of
+     BN_BLINDING_update for each BN_BLINDING structure (previously,
+     the last update always remained unused).
+     [Emilia KÃ¤sper (Google)]
+
+  *) In ssl3_clear, preserve s3->init_extra along with s3->rbuf.
+     [Bob Buckholz (Google)]
+
+ Changes between 1.0.0d and 1.0.0e [6 Sep 2011]
+
+  *) Fix bug where CRLs with nextUpdate in the past are sometimes accepted
+     by initialising X509_STORE_CTX properly. (CVE-2011-3207)
+     [Kaspar Brand <ossl@velox.ch>]
+
+  *) Fix SSL memory handling for (EC)DH ciphersuites, in particular
+     for multi-threaded use of ECDH. (CVE-2011-3210)
+     [Adam Langley (Google)]
+
+  *) Fix x509_name_ex_d2i memory leak on bad inputs.
+     [Bodo Moeller]
+
+  *) Remove hard coded ecdsaWithSHA1 signature tests in ssl code and check
+     signature public key algorithm by using OID xref utilities instead.
+     Before this you could only use some ECC ciphersuites with SHA1 only.
+     [Steve Henson]
+
+  *) Add protection against ECDSA timing attacks as mentioned in the paper
+     by Billy Bob Brumley and Nicola Tuveri, see:
+
+	http://eprint.iacr.org/2011/232.pdf
+
+     [Billy Bob Brumley and Nicola Tuveri]
+
+ Changes between 1.0.0c and 1.0.0d [8 Feb 2011]
+
+  *) Fix parsing of OCSP stapling ClientHello extension. CVE-2011-0014
+     [Neel Mehta, Adam Langley, Bodo Moeller (Google)]
+
+  *) Fix bug in string printing code: if *any* escaping is enabled we must
+     escape the escape character (backslash) or the resulting string is
+     ambiguous.
+     [Steve Henson]
+
+ Changes between 1.0.0b and 1.0.0c  [2 Dec 2010]
+
+  *) Disable code workaround for ancient and obsolete Netscape browsers
+     and servers: an attacker can use it in a ciphersuite downgrade attack.
+     Thanks to Martin Rex for discovering this bug. CVE-2010-4180
+     [Steve Henson]
+
+  *) Fixed J-PAKE implementation error, originally discovered by
+     Sebastien Martini, further info and confirmation from Stefan
+     Arentz and Feng Hao. Note that this fix is a security fix. CVE-2010-4252
+     [Ben Laurie]
+
+ Changes between 1.0.0a and 1.0.0b  [16 Nov 2010]
+
+  *) Fix extension code to avoid race conditions which can result in a buffer
+     overrun vulnerability: resumed sessions must not be modified as they can
+     be shared by multiple threads. CVE-2010-3864
+     [Steve Henson]
+
+  *) Fix WIN32 build system to correctly link an ENGINE directory into
+     a DLL. 
+     [Steve Henson]
+
+ Changes between 1.0.0 and 1.0.0a  [01 Jun 2010]
+
+  *) Check return value of int_rsa_verify in pkey_rsa_verifyrecover 
+     (CVE-2010-1633)
+     [Steve Henson, Peter-Michael Hager <hager@dortmund.net>]
+
+ Changes between 0.9.8n and 1.0.0  [29 Mar 2010]
+
+  *) Add "missing" function EVP_CIPHER_CTX_copy(). This copies a cipher
+     context. The operation can be customised via the ctrl mechanism in
+     case ENGINEs want to include additional functionality.
+     [Steve Henson]
+
+  *) Tolerate yet another broken PKCS#8 key format: private key value negative.
+     [Steve Henson]
+
+  *) Add new -subject_hash_old and -issuer_hash_old options to x509 utility to
+     output hashes compatible with older versions of OpenSSL.
+     [Willy Weisz <weisz@vcpc.univie.ac.at>]
+
+  *) Fix compression algorithm handling: if resuming a session use the
+     compression algorithm of the resumed session instead of determining
+     it from client hello again. Don't allow server to change algorithm.
+     [Steve Henson]
+
+  *) Add load_crls() function to apps tidying load_certs() too. Add option
+     to verify utility to allow additional CRLs to be included.
+     [Steve Henson]
+
+  *) Update OCSP request code to permit adding custom headers to the request:
+     some responders need this.
+     [Steve Henson]
+
+  *) The function EVP_PKEY_sign() returns <=0 on error: check return code
+     correctly.
+     [Julia Lawall <julia@diku.dk>]
+
+  *) Update verify callback code in apps/s_cb.c and apps/verify.c, it
+     needlessly dereferenced structures, used obsolete functions and
+     didn't handle all updated verify codes correctly.
+     [Steve Henson]
+
+  *) Disable MD2 in the default configuration.
+     [Steve Henson]
+
+  *) In BIO_pop() and BIO_push() use the ctrl argument (which was NULL) to
+     indicate the initial BIO being pushed or popped. This makes it possible
+     to determine whether the BIO is the one explicitly called or as a result
+     of the ctrl being passed down the chain. Fix BIO_pop() and SSL BIOs so
+     it handles reference counts correctly and doesn't zero out the I/O bio
+     when it is not being explicitly popped. WARNING: applications which
+     included workarounds for the old buggy behaviour will need to be modified
+     or they could free up already freed BIOs.
+     [Steve Henson]
+
+  *) Extend the uni2asc/asc2uni => OPENSSL_uni2asc/OPENSSL_asc2uni
+     renaming to all platforms (within the 0.9.8 branch, this was
+     done conditionally on Netware platforms to avoid a name clash).
+     [Guenter <lists@gknw.net>]
+
+  *) Add ECDHE and PSK support to DTLS.
+     [Michael Tuexen <tuexen@fh-muenster.de>]
+
+  *) Add CHECKED_STACK_OF macro to safestack.h, otherwise safestack can't
+     be used on C++.
+     [Steve Henson]
+
+  *) Add "missing" function EVP_MD_flags() (without this the only way to
+     retrieve a digest flags is by accessing the structure directly. Update
+     EVP_MD_do_all*() and EVP_CIPHER_do_all*() to include the name a digest
+     or cipher is registered as in the "from" argument. Print out all
+     registered digests in the dgst usage message instead of manually 
+     attempting to work them out.
+     [Steve Henson]
+
+  *) If no SSLv2 ciphers are used don't use an SSLv2 compatible client hello:
+     this allows the use of compression and extensions. Change default cipher
+     string to remove SSLv2 ciphersuites. This effectively avoids ancient SSLv2
+     by default unless an application cipher string requests it.
+     [Steve Henson]
+
+  *) Alter match criteria in PKCS12_parse(). It used to try to use local
+     key ids to find matching certificates and keys but some PKCS#12 files
+     don't follow the (somewhat unwritten) rules and this strategy fails.
+     Now just gather all certificates together and the first private key
+     then look for the first certificate that matches the key.
+     [Steve Henson]
+
+  *) Support use of registered digest and cipher names for dgst and cipher
+     commands instead of having to add each one as a special case. So now
+     you can do:
+
+        openssl sha256 foo
+
+     as well as:
+
+        openssl dgst -sha256 foo
+
+     and this works for ENGINE based algorithms too.
+
+     [Steve Henson]
+
+  *) Update Gost ENGINE to support parameter files.
+     [Victor B. Wagner <vitus@cryptocom.ru>]
+
+  *) Support GeneralizedTime in ca utility. 
+     [Oliver Martin <oliver@volatilevoid.net>, Steve Henson]
+
+  *) Enhance the hash format used for certificate directory links. The new
+     form uses the canonical encoding (meaning equivalent names will work
+     even if they aren't identical) and uses SHA1 instead of MD5. This form
+     is incompatible with the older format and as a result c_rehash should
+     be used to rebuild symbolic links.
+     [Steve Henson]
+
+  *) Make PKCS#8 the default write format for private keys, replacing the
+     traditional format. This form is standardised, more secure and doesn't
+     include an implicit MD5 dependency.
+     [Steve Henson]
+
+  *) Add a $gcc_devteam_warn option to Configure. The idea is that any code
+     committed to OpenSSL should pass this lot as a minimum.
+     [Steve Henson]
+
+  *) Add session ticket override functionality for use by EAP-FAST.
+     [Jouni Malinen <j@w1.fi>]
+
+  *) Modify HMAC functions to return a value. Since these can be implemented
+     in an ENGINE errors can occur.
+     [Steve Henson]
+
+  *) Type-checked OBJ_bsearch_ex.
+     [Ben Laurie]
+
+  *) Type-checked OBJ_bsearch. Also some constification necessitated
+     by type-checking.  Still to come: TXT_DB, bsearch(?),
+     OBJ_bsearch_ex, qsort, CRYPTO_EX_DATA, ASN1_VALUE, ASN1_STRING,
+     CONF_VALUE.
+     [Ben Laurie]
+
+  *) New function OPENSSL_gmtime_adj() to add a specific number of days and
+     seconds to a tm structure directly, instead of going through OS
+     specific date routines. This avoids any issues with OS routines such
+     as the year 2038 bug. New *_adj() functions for ASN1 time structures
+     and X509_time_adj_ex() to cover the extended range. The existing
+     X509_time_adj() is still usable and will no longer have any date issues.
+     [Steve Henson]
+
+  *) Delta CRL support. New use deltas option which will attempt to locate
+     and search any appropriate delta CRLs available.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Support for CRLs partitioned by reason code. Reorganise CRL processing
+     code and add additional score elements. Validate alternate CRL paths
+     as part of the CRL checking and indicate a new error "CRL path validation
+     error" in this case. Applications wanting additional details can use
+     the verify callback and check the new "parent" field. If this is not
+     NULL CRL path validation is taking place. Existing applications won't
+     see this because it requires extended CRL support which is off by
+     default.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Support for freshest CRL extension.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Initial indirect CRL support. Currently only supported in the CRLs
+     passed directly and not via lookup. Process certificate issuer
+     CRL entry extension and lookup CRL entries by bother issuer name
+     and serial number. Check and process CRL issuer entry in IDP extension.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Add support for distinct certificate and CRL paths. The CRL issuer
+     certificate is validated separately in this case. Only enabled if
+     an extended CRL support flag is set: this flag will enable additional
+     CRL functionality in future.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Add support for policy mappings extension.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Fixes to pathlength constraint, self issued certificate handling,
+     policy processing to align with RFC3280 and PKITS tests.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Support for name constraints certificate extension. DN, email, DNS
+     and URI types are currently supported.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) To cater for systems that provide a pointer-based thread ID rather
+     than numeric, deprecate the current numeric thread ID mechanism and
+     replace it with a structure and associated callback type. This
+     mechanism allows a numeric "hash" to be extracted from a thread ID in
+     either case, and on platforms where pointers are larger than 'long',
+     mixing is done to help ensure the numeric 'hash' is usable even if it
+     can't be guaranteed unique. The default mechanism is to use "&errno"
+     as a pointer-based thread ID to distinguish between threads.
+
+     Applications that want to provide their own thread IDs should now use
+     CRYPTO_THREADID_set_callback() to register a callback that will call
+     either CRYPTO_THREADID_set_numeric() or CRYPTO_THREADID_set_pointer().
+
+     Note that ERR_remove_state() is now deprecated, because it is tied
+     to the assumption that thread IDs are numeric.  ERR_remove_state(0)
+     to free the current thread's error state should be replaced by
+     ERR_remove_thread_state(NULL).
+
+     (This new approach replaces the functions CRYPTO_set_idptr_callback(),
+     CRYPTO_get_idptr_callback(), and CRYPTO_thread_idptr() that existed in
+     OpenSSL 0.9.9-dev between June 2006 and August 2008. Also, if an
+     application was previously providing a numeric thread callback that
+     was inappropriate for distinguishing threads, then uniqueness might
+     have been obtained with &errno that happened immediately in the
+     intermediate development versions of OpenSSL; this is no longer the
+     case, the numeric thread callback will now override the automatic use
+     of &errno.)
+     [Geoff Thorpe, with help from Bodo Moeller]
+
+  *) Initial support for different CRL issuing certificates. This covers a
+     simple case where the self issued certificates in the chain exist and
+     the real CRL issuer is higher in the existing chain.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Removed effectively defunct crypto/store from the build.
+     [Ben Laurie]
+
+  *) Revamp of STACK to provide stronger type-checking. Still to come:
+     TXT_DB, bsearch(?), OBJ_bsearch, qsort, CRYPTO_EX_DATA, ASN1_VALUE,
+     ASN1_STRING, CONF_VALUE.
+     [Ben Laurie]
+
+  *) Add a new SSL_MODE_RELEASE_BUFFERS mode flag to release unused buffer
+     RAM on SSL connections.  This option can save about 34k per idle SSL.
+     [Nick Mathewson]
+
+  *) Revamp of LHASH to provide stronger type-checking. Still to come:
+     STACK, TXT_DB, bsearch, qsort.
+     [Ben Laurie]
+
+  *) Initial support for Cryptographic Message Syntax (aka CMS) based
+     on RFC3850, RFC3851 and RFC3852. New cms directory and cms utility,
+     support for data, signedData, compressedData, digestedData and
+     encryptedData, envelopedData types included. Scripts to check against
+     RFC4134 examples draft and interop and consistency checks of many
+     content types and variants.
+     [Steve Henson]
+
+  *) Add options to enc utility to support use of zlib compression BIO.
+     [Steve Henson]
+
+  *) Extend mk1mf to support importing of options and assembly language
+     files from Configure script, currently only included in VC-WIN32.
+     The assembly language rules can now optionally generate the source
+     files from the associated perl scripts.
+     [Steve Henson]
+
+  *) Implement remaining functionality needed to support GOST ciphersuites.
+     Interop testing has been performed using CryptoPro implementations.
+     [Victor B. Wagner <vitus@cryptocom.ru>]
+
+  *) s390x assembler pack.
+     [Andy Polyakov]
+
+  *) ARMv4 assembler pack. ARMv4 refers to v4 and later ISA, not CPU
+     "family."
+     [Andy Polyakov]
+
+  *) Implement Opaque PRF Input TLS extension as specified in
+     draft-rescorla-tls-opaque-prf-input-00.txt.  Since this is not an
+     official specification yet and no extension type assignment by
+     IANA exists, this extension (for now) will have to be explicitly
+     enabled when building OpenSSL by providing the extension number
+     to use.  For example, specify an option
+
+         -DTLSEXT_TYPE_opaque_prf_input=0x9527
+
+     to the "config" or "Configure" script to enable the extension,
+     assuming extension number 0x9527 (which is a completely arbitrary
+     and unofficial assignment based on the MD5 hash of the Internet
+     Draft).  Note that by doing so, you potentially lose
+     interoperability with other TLS implementations since these might
+     be using the same extension number for other purposes.
+
+     SSL_set_tlsext_opaque_prf_input(ssl, src, len) is used to set the
+     opaque PRF input value to use in the handshake.  This will create
+     an interal copy of the length-'len' string at 'src', and will
+     return non-zero for success.
+
+     To get more control and flexibility, provide a callback function
+     by using
+
+          SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb)
+          SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg)
+
+     where
+
+          int (*cb)(SSL *, void *peerinput, size_t len, void *arg);
+          void *arg;
+
+     Callback function 'cb' will be called in handshakes, and is
+     expected to use SSL_set_tlsext_opaque_prf_input() as appropriate.
+     Argument 'arg' is for application purposes (the value as given to
+     SSL_CTX_set_tlsext_opaque_prf_input_callback_arg() will directly
+     be provided to the callback function).  The callback function
+     has to return non-zero to report success: usually 1 to use opaque
+     PRF input just if possible, or 2 to enforce use of the opaque PRF
+     input.  In the latter case, the library will abort the handshake
+     if opaque PRF input is not successfully negotiated.
+
+     Arguments 'peerinput' and 'len' given to the callback function
+     will always be NULL and 0 in the case of a client.  A server will
+     see the client's opaque PRF input through these variables if
+     available (NULL and 0 otherwise).  Note that if the server
+     provides an opaque PRF input, the length must be the same as the
+     length of the client's opaque PRF input.
+
+     Note that the callback function will only be called when creating
+     a new session (session resumption can resume whatever was
+     previously negotiated), and will not be called in SSL 2.0
+     handshakes; thus, SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) or
+     SSL_set_options(ssl, SSL_OP_NO_SSLv2) is especially recommended
+     for applications that need to enforce opaque PRF input.
+
+     [Bodo Moeller]
+
+  *) Update ssl code to support digests other than SHA1+MD5 for handshake
+     MAC. 
+
+     [Victor B. Wagner <vitus@cryptocom.ru>]
+
+  *) Add RFC4507 support to OpenSSL. This includes the corrections in
+     RFC4507bis. The encrypted ticket format is an encrypted encoded
+     SSL_SESSION structure, that way new session features are automatically
+     supported.
+
+     If a client application caches session in an SSL_SESSION structure
+     support is transparent because tickets are now stored in the encoded
+     SSL_SESSION.
+     
+     The SSL_CTX structure automatically generates keys for ticket
+     protection in servers so again support should be possible
+     with no application modification.
+
+     If a client or server wishes to disable RFC4507 support then the option
+     SSL_OP_NO_TICKET can be set.
+
+     Add a TLS extension debugging callback to allow the contents of any client
+     or server extensions to be examined.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Final changes to avoid use of pointer pointer casts in OpenSSL.
+     OpenSSL should now compile cleanly on gcc 4.2
+     [Peter Hartley <pdh@utter.chaos.org.uk>, Steve Henson]
+
+  *) Update SSL library to use new EVP_PKEY MAC API. Include generic MAC
+     support including streaming MAC support: this is required for GOST
+     ciphersuite support.
+     [Victor B. Wagner <vitus@cryptocom.ru>, Steve Henson]
+
+  *) Add option -stream to use PKCS#7 streaming in smime utility. New
+     function i2d_PKCS7_bio_stream() and PEM_write_PKCS7_bio_stream()
+     to output in BER and PEM format.
+     [Steve Henson]
+
+  *) Experimental support for use of HMAC via EVP_PKEY interface. This
+     allows HMAC to be handled via the EVP_DigestSign*() interface. The
+     EVP_PKEY "key" in this case is the HMAC key, potentially allowing
+     ENGINE support for HMAC keys which are unextractable. New -mac and
+     -macopt options to dgst utility.
+     [Steve Henson]
+
+  *) New option -sigopt to dgst utility. Update dgst to use
+     EVP_Digest{Sign,Verify}*. These two changes make it possible to use
+     alternative signing parameters such as X9.31 or PSS in the dgst 
+     utility.
+     [Steve Henson]
+
+  *) Change ssl_cipher_apply_rule(), the internal function that does
+     the work each time a ciphersuite string requests enabling
+     ("foo+bar"), moving ("+foo+bar"), disabling ("-foo+bar", or
+     removing ("!foo+bar") a class of ciphersuites: Now it maintains
+     the order of disabled ciphersuites such that those ciphersuites
+     that most recently went from enabled to disabled not only stay
+     in order with respect to each other, but also have higher priority
+     than other disabled ciphersuites the next time ciphersuites are
+     enabled again.
+
+     This means that you can now say, e.g., "PSK:-PSK:HIGH" to enable
+     the same ciphersuites as with "HIGH" alone, but in a specific
+     order where the PSK ciphersuites come first (since they are the
+     most recently disabled ciphersuites when "HIGH" is parsed).
+
+     Also, change ssl_create_cipher_list() (using this new
+     funcionality) such that between otherwise identical
+     cihpersuites, ephemeral ECDH is preferred over ephemeral DH in
+     the default order.
+     [Bodo Moeller]
+
+  *) Change ssl_create_cipher_list() so that it automatically
+     arranges the ciphersuites in reasonable order before starting
+     to process the rule string.  Thus, the definition for "DEFAULT"
+     (SSL_DEFAULT_CIPHER_LIST) now is just "ALL:!aNULL:!eNULL", but
+     remains equivalent to "AES:ALL:!aNULL:!eNULL:+aECDH:+kRSA:+RC4:@STRENGTH".
+     This makes it much easier to arrive at a reasonable default order
+     in applications for which anonymous ciphers are OK (meaning
+     that you can't actually use DEFAULT).
+     [Bodo Moeller; suggested by Victor Duchovni]
+
+  *) Split the SSL/TLS algorithm mask (as used for ciphersuite string
+     processing) into multiple integers instead of setting
+     "SSL_MKEY_MASK" bits, "SSL_AUTH_MASK" bits, "SSL_ENC_MASK",
+     "SSL_MAC_MASK", and "SSL_SSL_MASK" bits all in a single integer.
+     (These masks as well as the individual bit definitions are hidden
+     away into the non-exported interface ssl/ssl_locl.h, so this
+     change to the definition of the SSL_CIPHER structure shouldn't
+     affect applications.)  This give us more bits for each of these
+     categories, so there is no longer a need to coagulate AES128 and
+     AES256 into a single algorithm bit, and to coagulate Camellia128
+     and Camellia256 into a single algorithm bit, which has led to all
+     kinds of kludges.
+
+     Thus, among other things, the kludge introduced in 0.9.7m and
+     0.9.8e for masking out AES256 independently of AES128 or masking
+     out Camellia256 independently of AES256 is not needed here in 0.9.9.
+
+     With the change, we also introduce new ciphersuite aliases that
+     so far were missing: "AES128", "AES256", "CAMELLIA128", and
+     "CAMELLIA256".
+     [Bodo Moeller]
+
+  *) Add support for dsa-with-SHA224 and dsa-with-SHA256.
+     Use the leftmost N bytes of the signature input if the input is
+     larger than the prime q (with N being the size in bytes of q).
+     [Nils Larsch]
+
+  *) Very *very* experimental PKCS#7 streaming encoder support. Nothing uses
+     it yet and it is largely untested.
+     [Steve Henson]
+
+  *) Add support for the ecdsa-with-SHA224/256/384/512 signature types.
+     [Nils Larsch]
+
+  *) Initial incomplete changes to avoid need for function casts in OpenSSL
+     some compilers (gcc 4.2 and later) reject their use. Safestack is
+     reimplemented.  Update ASN1 to avoid use of legacy functions. 
+     [Steve Henson]
+
+  *) Win32/64 targets are linked with Winsock2.
+     [Andy Polyakov]
+
+  *) Add an X509_CRL_METHOD structure to allow CRL processing to be redirected
+     to external functions. This can be used to increase CRL handling 
+     efficiency especially when CRLs are very large by (for example) storing
+     the CRL revoked certificates in a database.
+     [Steve Henson]
+
+  *) Overhaul of by_dir code. Add support for dynamic loading of CRLs so
+     new CRLs added to a directory can be used. New command line option
+     -verify_return_error to s_client and s_server. This causes real errors
+     to be returned by the verify callback instead of carrying on no matter
+     what. This reflects the way a "real world" verify callback would behave.
+     [Steve Henson]
+
+  *) GOST engine, supporting several GOST algorithms and public key formats.
+     Kindly donated by Cryptocom.
+     [Cryptocom]
+
+  *) Partial support for Issuing Distribution Point CRL extension. CRLs
+     partitioned by DP are handled but no indirect CRL or reason partitioning
+     (yet). Complete overhaul of CRL handling: now the most suitable CRL is
+     selected via a scoring technique which handles IDP and AKID in CRLs.
+     [Steve Henson]
+
+  *) New X509_STORE_CTX callbacks lookup_crls() and lookup_certs() which
+     will ultimately be used for all verify operations: this will remove the
+     X509_STORE dependency on certificate verification and allow alternative
+     lookup methods.  X509_STORE based implementations of these two callbacks.
+     [Steve Henson]
+
+  *) Allow multiple CRLs to exist in an X509_STORE with matching issuer names.
+     Modify get_crl() to find a valid (unexpired) CRL if possible.
+     [Steve Henson]
+
+  *) New function X509_CRL_match() to check if two CRLs are identical. Normally
+     this would be called X509_CRL_cmp() but that name is already used by
+     a function that just compares CRL issuer names. Cache several CRL 
+     extensions in X509_CRL structure and cache CRLDP in X509.
+     [Steve Henson]
+
+  *) Store a "canonical" representation of X509_NAME structure (ASN1 Name)
+     this maps equivalent X509_NAME structures into a consistent structure.
+     Name comparison can then be performed rapidly using memcmp().
+     [Steve Henson]
+
+  *) Non-blocking OCSP request processing. Add -timeout option to ocsp 
+     utility.
+     [Steve Henson]
+
+  *) Allow digests to supply their own micalg string for S/MIME type using
+     the ctrl EVP_MD_CTRL_MICALG.
+     [Steve Henson]
+
+  *) During PKCS7 signing pass the PKCS7 SignerInfo structure to the
+     EVP_PKEY_METHOD before and after signing via the EVP_PKEY_CTRL_PKCS7_SIGN
+     ctrl. It can then customise the structure before and/or after signing
+     if necessary.
+     [Steve Henson]
+
+  *) New function OBJ_add_sigid() to allow application defined signature OIDs
+     to be added to OpenSSLs internal tables. New function OBJ_sigid_free()
+     to free up any added signature OIDs.
+     [Steve Henson]
+
+  *) New functions EVP_CIPHER_do_all(), EVP_CIPHER_do_all_sorted(),
+     EVP_MD_do_all() and EVP_MD_do_all_sorted() to enumerate internal
+     digest and cipher tables. New options added to openssl utility:
+     list-message-digest-algorithms and list-cipher-algorithms.
+     [Steve Henson]
+
+  *) Change the array representation of binary polynomials: the list
+     of degrees of non-zero coefficients is now terminated with -1.
+     Previously it was terminated with 0, which was also part of the
+     value; thus, the array representation was not applicable to
+     polynomials where t^0 has coefficient zero.  This change makes
+     the array representation useful in a more general context.
+     [Douglas Stebila]
+
+  *) Various modifications and fixes to SSL/TLS cipher string
+     handling.  For ECC, the code now distinguishes between fixed ECDH
+     with RSA certificates on the one hand and with ECDSA certificates
+     on the other hand, since these are separate ciphersuites.  The
+     unused code for Fortezza ciphersuites has been removed.
+
+     For consistency with EDH, ephemeral ECDH is now called "EECDH"
+     (not "ECDHE").  For consistency with the code for DH
+     certificates, use of ECDH certificates is now considered ECDH
+     authentication, not RSA or ECDSA authentication (the latter is
+     merely the CA's signing algorithm and not actively used in the
+     protocol).
+
+     The temporary ciphersuite alias "ECCdraft" is no longer
+     available, and ECC ciphersuites are no longer excluded from "ALL"
+     and "DEFAULT".  The following aliases now exist for RFC 4492
+     ciphersuites, most of these by analogy with the DH case:
+
+         kECDHr   - ECDH cert, signed with RSA
+         kECDHe   - ECDH cert, signed with ECDSA
+         kECDH    - ECDH cert (signed with either RSA or ECDSA)
+         kEECDH   - ephemeral ECDH
+         ECDH     - ECDH cert or ephemeral ECDH
+
+         aECDH    - ECDH cert
+         aECDSA   - ECDSA cert
+         ECDSA    - ECDSA cert
+
+         AECDH    - anonymous ECDH
+         EECDH    - non-anonymous ephemeral ECDH (equivalent to "kEECDH:-AECDH")
+
+     [Bodo Moeller]
+
+  *) Add additional S/MIME capabilities for AES and GOST ciphers if supported.
+     Use correct micalg parameters depending on digest(s) in signed message.
+     [Steve Henson]
+
+  *) Add engine support for EVP_PKEY_ASN1_METHOD. Add functions to process
+     an ENGINE asn1 method. Support ENGINE lookups in the ASN1 code.
+     [Steve Henson]
+
+  *) Initial engine support for EVP_PKEY_METHOD. New functions to permit
+     an engine to register a method. Add ENGINE lookups for methods and
+     functional reference processing.
+     [Steve Henson]
+
+  *) New functions EVP_Digest{Sign,Verify)*. These are enchance versions of
+     EVP_{Sign,Verify}* which allow an application to customise the signature
+     process.
+     [Steve Henson]
+
+  *) New -resign option to smime utility. This adds one or more signers
+     to an existing PKCS#7 signedData structure. Also -md option to use an
+     alternative message digest algorithm for signing.
+     [Steve Henson]
+
+  *) Tidy up PKCS#7 routines and add new functions to make it easier to
+     create PKCS7 structures containing multiple signers. Update smime
+     application to support multiple signers.
+     [Steve Henson]
+
+  *) New -macalg option to pkcs12 utility to allow setting of an alternative
+     digest MAC.
+     [Steve Henson]
+
+  *) Initial support for PKCS#5 v2.0 PRFs other than default SHA1 HMAC.
+     Reorganize PBE internals to lookup from a static table using NIDs,
+     add support for HMAC PBE OID translation. Add a EVP_CIPHER ctrl:
+     EVP_CTRL_PBE_PRF_NID this allows a cipher to specify an alternative
+     PRF which will be automatically used with PBES2.
+     [Steve Henson]
+
+  *) Replace the algorithm specific calls to generate keys in "req" with the
+     new API.
+     [Steve Henson]
+
+  *) Update PKCS#7 enveloped data routines to use new API. This is now
+     supported by any public key method supporting the encrypt operation. A
+     ctrl is added to allow the public key algorithm to examine or modify
+     the PKCS#7 RecipientInfo structure if it needs to: for RSA this is
+     a no op.
+     [Steve Henson]
+
+  *) Add a ctrl to asn1 method to allow a public key algorithm to express
+     a default digest type to use. In most cases this will be SHA1 but some
+     algorithms (such as GOST) need to specify an alternative digest. The
+     return value indicates how strong the preference is 1 means optional and
+     2 is mandatory (that is it is the only supported type). Modify
+     ASN1_item_sign() to accept a NULL digest argument to indicate it should
+     use the default md. Update openssl utilities to use the default digest
+     type for signing if it is not explicitly indicated.
+     [Steve Henson]
+
+  *) Use OID cross reference table in ASN1_sign() and ASN1_verify(). New 
+     EVP_MD flag EVP_MD_FLAG_PKEY_METHOD_SIGNATURE. This uses the relevant
+     signing method from the key type. This effectively removes the link
+     between digests and public key types.
+     [Steve Henson]
+
+  *) Add an OID cross reference table and utility functions. Its purpose is to
+     translate between signature OIDs such as SHA1WithrsaEncryption and SHA1,
+     rsaEncryption. This will allow some of the algorithm specific hackery
+     needed to use the correct OID to be removed. 
+     [Steve Henson]
+
+  *) Remove algorithm specific dependencies when setting PKCS7_SIGNER_INFO
+     structures for PKCS7_sign(). They are now set up by the relevant public
+     key ASN1 method.
+     [Steve Henson]
+
+  *) Add provisional EC pkey method with support for ECDSA and ECDH.
+     [Steve Henson]
+
+  *) Add support for key derivation (agreement) in the API, DH method and
+     pkeyutl.
+     [Steve Henson]
+
+  *) Add DSA pkey method and DH pkey methods, extend DH ASN1 method to support
+     public and private key formats. As a side effect these add additional 
+     command line functionality not previously available: DSA signatures can be
+     generated and verified using pkeyutl and DH key support and generation in
+     pkey, genpkey.
+     [Steve Henson]
+
+  *) BeOS support.
+     [Oliver Tappe <zooey@hirschkaefer.de>]
+
+  *) New make target "install_html_docs" installs HTML renditions of the
+     manual pages.
+     [Oliver Tappe <zooey@hirschkaefer.de>]
+
+  *) New utility "genpkey" this is analogous to "genrsa" etc except it can
+     generate keys for any algorithm. Extend and update EVP_PKEY_METHOD to
+     support key and parameter generation and add initial key generation
+     functionality for RSA.
+     [Steve Henson]
+
+  *) Add functions for main EVP_PKEY_method operations. The undocumented
+     functions EVP_PKEY_{encrypt,decrypt} have been renamed to
+     EVP_PKEY_{encrypt,decrypt}_old. 
+     [Steve Henson]
+
+  *) Initial definitions for EVP_PKEY_METHOD. This will be a high level public
+     key API, doesn't do much yet.
+     [Steve Henson]
+
+  *) New function EVP_PKEY_asn1_get0_info() to retrieve information about
+     public key algorithms. New option to openssl utility:
+     "list-public-key-algorithms" to print out info.
+     [Steve Henson]
+
+  *) Implement the Supported Elliptic Curves Extension for
+     ECC ciphersuites from draft-ietf-tls-ecc-12.txt.
+     [Douglas Stebila]
+
+  *) Don't free up OIDs in OBJ_cleanup() if they are in use by EVP_MD or
+     EVP_CIPHER structures to avoid later problems in EVP_cleanup().
+     [Steve Henson]
+
+  *) New utilities pkey and pkeyparam. These are similar to algorithm specific
+     utilities such as rsa, dsa, dsaparam etc except they process any key
+     type.
+     [Steve Henson]
+
+  *) Transfer public key printing routines to EVP_PKEY_ASN1_METHOD. New 
+     functions EVP_PKEY_print_public(), EVP_PKEY_print_private(),
+     EVP_PKEY_print_param() to print public key data from an EVP_PKEY
+     structure.
+     [Steve Henson]
+
+  *) Initial support for pluggable public key ASN1.
+     De-spaghettify the public key ASN1 handling. Move public and private
+     key ASN1 handling to a new EVP_PKEY_ASN1_METHOD structure. Relocate
+     algorithm specific handling to a single module within the relevant
+     algorithm directory. Add functions to allow (near) opaque processing
+     of public and private key structures.
+     [Steve Henson]
+
+  *) Implement the Supported Point Formats Extension for
+     ECC ciphersuites from draft-ietf-tls-ecc-12.txt.
+     [Douglas Stebila]
+
+  *) Add initial support for RFC 4279 PSK TLS ciphersuites. Add members
+     for the psk identity [hint] and the psk callback functions to the
+     SSL_SESSION, SSL and SSL_CTX structure.
+     
+     New ciphersuites:
+         PSK-RC4-SHA, PSK-3DES-EDE-CBC-SHA, PSK-AES128-CBC-SHA,
+         PSK-AES256-CBC-SHA
+ 
+     New functions:
+         SSL_CTX_use_psk_identity_hint
+         SSL_get_psk_identity_hint
+         SSL_get_psk_identity
+         SSL_use_psk_identity_hint
+
+     [Mika Kousa and Pasi Eronen of Nokia Corporation]
+
+  *) Add RFC 3161 compliant time stamp request creation, response generation
+     and response verification functionality.
+     [ZoltÃ¡n GlÃ³zik <zglozik@opentsa.org>, The OpenTSA Project]
+
+  *) Add initial support for TLS extensions, specifically for the server_name
+     extension so far.  The SSL_SESSION, SSL_CTX, and SSL data structures now
+     have new members for a host name.  The SSL data structure has an
+     additional member SSL_CTX *initial_ctx so that new sessions can be
+     stored in that context to allow for session resumption, even after the
+     SSL has been switched to a new SSL_CTX in reaction to a client's
+     server_name extension.
+
+     New functions (subject to change):
+
+         SSL_get_servername()
+         SSL_get_servername_type()
+         SSL_set_SSL_CTX()
+
+     New CTRL codes and macros (subject to change):
+
+         SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
+                                 - SSL_CTX_set_tlsext_servername_callback()
+         SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG
+                                      - SSL_CTX_set_tlsext_servername_arg()
+         SSL_CTRL_SET_TLSEXT_HOSTNAME           - SSL_set_tlsext_host_name()
+
+     openssl s_client has a new '-servername ...' option.
+
+     openssl s_server has new options '-servername_host ...', '-cert2 ...',
+     '-key2 ...', '-servername_fatal' (subject to change).  This allows
+     testing the HostName extension for a specific single host name ('-cert'
+     and '-key' remain fallbacks for handshakes without HostName
+     negotiation).  If the unrecognized_name alert has to be sent, this by
+     default is a warning; it becomes fatal with the '-servername_fatal'
+     option.
+
+     [Peter Sylvester,  Remy Allais, Christophe Renou]
+
+  *) Whirlpool hash implementation is added.
+     [Andy Polyakov]
+
+  *) BIGNUM code on 64-bit SPARCv9 targets is switched from bn(64,64) to
+     bn(64,32). Because of instruction set limitations it doesn't have
+     any negative impact on performance. This was done mostly in order
+     to make it possible to share assembler modules, such as bn_mul_mont
+     implementations, between 32- and 64-bit builds without hassle.
+     [Andy Polyakov]
+
+  *) Move code previously exiled into file crypto/ec/ec2_smpt.c
+     to ec2_smpl.c, and no longer require the OPENSSL_EC_BIN_PT_COMP
+     macro.
+     [Bodo Moeller]
+
+  *) New candidate for BIGNUM assembler implementation, bn_mul_mont,
+     dedicated Montgomery multiplication procedure, is introduced.
+     BN_MONT_CTX is modified to allow bn_mul_mont to reach for higher
+     "64-bit" performance on certain 32-bit targets.
+     [Andy Polyakov]
+
+  *) New option SSL_OP_NO_COMP to disable use of compression selectively
+     in SSL structures. New SSL ctrl to set maximum send fragment size. 
+     Save memory by seeting the I/O buffer sizes dynamically instead of
+     using the maximum available value.
+     [Steve Henson]
+
+  *) New option -V for 'openssl ciphers'. This prints the ciphersuite code
+     in addition to the text details.
+     [Bodo Moeller]
+
+  *) Very, very preliminary EXPERIMENTAL support for printing of general
+     ASN1 structures. This currently produces rather ugly output and doesn't
+     handle several customised structures at all.
+     [Steve Henson]
+
+  *) Integrated support for PVK file format and some related formats such
+     as MS PUBLICKEYBLOB and PRIVATEKEYBLOB. Command line switches to support
+     these in the 'rsa' and 'dsa' utilities.
+     [Steve Henson]
+
+  *) Support for PKCS#1 RSAPublicKey format on rsa utility command line.
+     [Steve Henson]
+
+  *) Remove the ancient ASN1_METHOD code. This was only ever used in one
+     place for the (very old) "NETSCAPE" format certificates which are now
+     handled using new ASN1 code equivalents.
+     [Steve Henson]
+
+  *) Let the TLSv1_method() etc. functions return a 'const' SSL_METHOD
+     pointer and make the SSL_METHOD parameter in SSL_CTX_new,
+     SSL_CTX_set_ssl_version and SSL_set_ssl_method 'const'.
+     [Nils Larsch]
+
+  *) Modify CRL distribution points extension code to print out previously
+     unsupported fields. Enhance extension setting code to allow setting of
+     all fields.
+     [Steve Henson]
+
+  *) Add print and set support for Issuing Distribution Point CRL extension.
+     [Steve Henson]
+
+  *) Change 'Configure' script to enable Camellia by default.
+     [NTT]
+
+ Changes between 0.9.8m and 0.9.8n [24 Mar 2010]
+
+  *) When rejecting SSL/TLS records due to an incorrect version number, never
+     update s->server with a new major version number.  As of
+     - OpenSSL 0.9.8m if 'short' is a 16-bit type,
+     - OpenSSL 0.9.8f if 'short' is longer than 16 bits,
+     the previous behavior could result in a read attempt at NULL when
+     receiving specific incorrect SSL/TLS records once record payload
+     protection is active.  (CVE-2010-0740)
+     [Bodo Moeller, Adam Langley <agl@chromium.org>]
+
+  *) Fix for CVE-2010-0433 where some kerberos enabled versions of OpenSSL 
+     could be crashed if the relevant tables were not present (e.g. chrooted).
+     [Tomas Hoger <thoger@redhat.com>]
+
+ Changes between 0.9.8l and 0.9.8m [25 Feb 2010]
+
+  *) Always check bn_wexpend() return values for failure.  (CVE-2009-3245)
+     [Martin Olsson, Neel Mehta]
+
+  *) Fix X509_STORE locking: Every 'objs' access requires a lock (to
+     accommodate for stack sorting, always a write lock!).
+     [Bodo Moeller]
+
+  *) On some versions of WIN32 Heap32Next is very slow. This can cause
+     excessive delays in the RAND_poll(): over a minute. As a workaround
+     include a time check in the inner Heap32Next loop too.
+     [Steve Henson]
+
+  *) The code that handled flushing of data in SSL/TLS originally used the
+     BIO_CTRL_INFO ctrl to see if any data was pending first. This caused
+     the problem outlined in PR#1949. The fix suggested there however can
+     trigger problems with buggy BIO_CTRL_WPENDING (e.g. some versions
+     of Apache). So instead simplify the code to flush unconditionally.
+     This should be fine since flushing with no data to flush is a no op.
+     [Steve Henson]
+
+  *) Handle TLS versions 2.0 and later properly and correctly use the
+     highest version of TLS/SSL supported. Although TLS >= 2.0 is some way
+     off ancient servers have a habit of sticking around for a while...
+     [Steve Henson]
+
+  *) Modify compression code so it frees up structures without using the
+     ex_data callbacks. This works around a problem where some applications
+     call CRYPTO_cleanup_all_ex_data() before application exit (e.g. when
+     restarting) then use compression (e.g. SSL with compression) later.
+     This results in significant per-connection memory leaks and
+     has caused some security issues including CVE-2008-1678 and
+     CVE-2009-4355.
+     [Steve Henson]
+
+  *) Constify crypto/cast (i.e., <openssl/cast.h>): a CAST_KEY doesn't
+     change when encrypting or decrypting.
+     [Bodo Moeller]
+
+  *) Add option SSL_OP_LEGACY_SERVER_CONNECT which will allow clients to
+     connect and renegotiate with servers which do not support RI.
+     Until RI is more widely deployed this option is enabled by default.
+     [Steve Henson]
+
+  *) Add "missing" ssl ctrls to clear options and mode.
+     [Steve Henson]
+
+  *) If client attempts to renegotiate and doesn't support RI respond with
+     a no_renegotiation alert as required by RFC5746.  Some renegotiating
+     TLS clients will continue a connection gracefully when they receive
+     the alert. Unfortunately OpenSSL mishandled this alert and would hang
+     waiting for a server hello which it will never receive. Now we treat a
+     received no_renegotiation alert as a fatal error. This is because
+     applications requesting a renegotiation might well expect it to succeed
+     and would have no code in place to handle the server denying it so the
+     only safe thing to do is to terminate the connection.
+     [Steve Henson]
+
+  *) Add ctrl macro SSL_get_secure_renegotiation_support() which returns 1 if
+     peer supports secure renegotiation and 0 otherwise. Print out peer
+     renegotiation support in s_client/s_server.
+     [Steve Henson]
+
+  *) Replace the highly broken and deprecated SPKAC certification method with
+     the updated NID creation version. This should correctly handle UTF8.
+     [Steve Henson]
+
+  *) Implement RFC5746. Re-enable renegotiation but require the extension
+     as needed. Unfortunately, SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
+     turns out to be a bad idea. It has been replaced by
+     SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION which can be set with
+     SSL_CTX_set_options(). This is really not recommended unless you
+     know what you are doing.
+     [Eric Rescorla <ekr@networkresonance.com>, Ben Laurie, Steve Henson]
+
+  *) Fixes to stateless session resumption handling. Use initial_ctx when
+     issuing and attempting to decrypt tickets in case it has changed during
+     servername handling. Use a non-zero length session ID when attempting
+     stateless session resumption: this makes it possible to determine if
+     a resumption has occurred immediately after receiving server hello
+     (several places in OpenSSL subtly assume this) instead of later in
+     the handshake.
+     [Steve Henson]
+
+  *) The functions ENGINE_ctrl(), OPENSSL_isservice(),
+     CMS_get1_RecipientRequest() and RAND_bytes() can return <=0 on error
+     fixes for a few places where the return code is not checked
+     correctly.
+     [Julia Lawall <julia@diku.dk>]
+
+  *) Add --strict-warnings option to Configure script to include devteam
+     warnings in other configurations.
+     [Steve Henson]
+
+  *) Add support for --libdir option and LIBDIR variable in makefiles. This
+     makes it possible to install openssl libraries in locations which
+     have names other than "lib", for example "/usr/lib64" which some
+     systems need.
+     [Steve Henson, based on patch from Jeremy Utley]
+
+  *) Don't allow the use of leading 0x80 in OIDs. This is a violation of
+     X690 8.9.12 and can produce some misleading textual output of OIDs.
+     [Steve Henson, reported by Dan Kaminsky]
+
+  *) Delete MD2 from algorithm tables. This follows the recommendation in
+     several standards that it is not used in new applications due to
+     several cryptographic weaknesses. For binary compatibility reasons
+     the MD2 API is still compiled in by default.
+     [Steve Henson]
+
+  *) Add compression id to {d2i,i2d}_SSL_SESSION so it is correctly saved
+     and restored.
+     [Steve Henson]
+
+  *) Rename uni2asc and asc2uni functions to OPENSSL_uni2asc and
+     OPENSSL_asc2uni conditionally on Netware platforms to avoid a name
+     clash.
+     [Guenter <lists@gknw.net>]
+
+  *) Fix the server certificate chain building code to use X509_verify_cert(),
+     it used to have an ad-hoc builder which was unable to cope with anything
+     other than a simple chain.
+     [David Woodhouse <dwmw2@infradead.org>, Steve Henson]
+
+  *) Don't check self signed certificate signatures in X509_verify_cert()
+     by default (a flag can override this): it just wastes time without
+     adding any security. As a useful side effect self signed root CAs
+     with non-FIPS digests are now usable in FIPS mode.
+     [Steve Henson]
+
+  *) In dtls1_process_out_of_seq_message() the check if the current message
+     is already buffered was missing. For every new message was memory
+     allocated, allowing an attacker to perform an denial of service attack
+     with sending out of seq handshake messages until there is no memory
+     left. Additionally every future messege was buffered, even if the
+     sequence number made no sense and would be part of another handshake.
+     So only messages with sequence numbers less than 10 in advance will be
+     buffered.  (CVE-2009-1378)
+     [Robin Seggelmann, discovered by Daniel Mentz] 	
+
+  *) Records are buffered if they arrive with a future epoch to be
+     processed after finishing the corresponding handshake. There is
+     currently no limitation to this buffer allowing an attacker to perform
+     a DOS attack with sending records with future epochs until there is no
+     memory left. This patch adds the pqueue_size() function to determine
+     the size of a buffer and limits the record buffer to 100 entries.
+     (CVE-2009-1377)
+     [Robin Seggelmann, discovered by Daniel Mentz] 	
+
+  *) Keep a copy of frag->msg_header.frag_len so it can be used after the
+     parent structure is freed.  (CVE-2009-1379)
+     [Daniel Mentz] 	
+
+  *) Handle non-blocking I/O properly in SSL_shutdown() call.
+     [Darryl Miles <darryl-mailinglists@netbauds.net>]
+
+  *) Add 2.5.4.* OIDs
+     [Ilya O. <vrghost@gmail.com>]
+
+ Changes between 0.9.8k and 0.9.8l  [5 Nov 2009]
+
+  *) Disable renegotiation completely - this fixes a severe security
+     problem (CVE-2009-3555) at the cost of breaking all
+     renegotiation. Renegotiation can be re-enabled by setting
+     SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION in s3->flags at
+     run-time. This is really not recommended unless you know what
+     you're doing.
+     [Ben Laurie]
+
+ Changes between 0.9.8j and 0.9.8k  [25 Mar 2009]
+
+  *) Don't set val to NULL when freeing up structures, it is freed up by
+     underlying code. If sizeof(void *) > sizeof(long) this can result in
+     zeroing past the valid field. (CVE-2009-0789)
+     [Paolo Ganci <Paolo.Ganci@AdNovum.CH>]
+
+  *) Fix bug where return value of CMS_SignerInfo_verify_content() was not
+     checked correctly. This would allow some invalid signed attributes to
+     appear to verify correctly. (CVE-2009-0591)
+     [Ivan Nestlerode <inestlerode@us.ibm.com>]
+
+  *) Reject UniversalString and BMPString types with invalid lengths. This
+     prevents a crash in ASN1_STRING_print_ex() which assumes the strings have
+     a legal length. (CVE-2009-0590)
+     [Steve Henson]
+
+  *) Set S/MIME signing as the default purpose rather than setting it 
+     unconditionally. This allows applications to override it at the store
+     level.
+     [Steve Henson]
+
+  *) Permit restricted recursion of ASN1 strings. This is needed in practice
+     to handle some structures.
+     [Steve Henson]
+
+  *) Improve efficiency of mem_gets: don't search whole buffer each time
+     for a '\n'
+     [Jeremy Shapiro <jnshapir@us.ibm.com>]
+
+  *) New -hex option for openssl rand.
+     [Matthieu Herrb]
+
+  *) Print out UTF8String and NumericString when parsing ASN1.
+     [Steve Henson]
+
+  *) Support NumericString type for name components.
+     [Steve Henson]
+
+  *) Allow CC in the environment to override the automatically chosen
+     compiler. Note that nothing is done to ensure flags work with the
+     chosen compiler.
+     [Ben Laurie]
+
+ Changes between 0.9.8i and 0.9.8j  [07 Jan 2009]
+
+  *) Properly check EVP_VerifyFinal() and similar return values
+     (CVE-2008-5077).
+     [Ben Laurie, Bodo Moeller, Google Security Team]
+
+  *) Enable TLS extensions by default.
+     [Ben Laurie]
+
+  *) Allow the CHIL engine to be loaded, whether the application is
+     multithreaded or not. (This does not release the developer from the
+     obligation to set up the dynamic locking callbacks.)
+     [Sander Temme <sander@temme.net>]
+
+  *) Use correct exit code if there is an error in dgst command.
+     [Steve Henson; problem pointed out by Roland Dirlewanger]
+
+  *) Tweak Configure so that you need to say "experimental-jpake" to enable
+     JPAKE, and need to use -DOPENSSL_EXPERIMENTAL_JPAKE in applications.
+     [Bodo Moeller]
+
+  *) Add experimental JPAKE support, including demo authentication in
+     s_client and s_server.
+     [Ben Laurie]
+
+  *) Set the comparison function in v3_addr_canonize().
+     [Rob Austein <sra@hactrn.net>]
+
+  *) Add support for XMPP STARTTLS in s_client.
+     [Philip Paeps <philip@freebsd.org>]
+
+  *) Change the server-side SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG behavior
+     to ensure that even with this option, only ciphersuites in the
+     server's preference list will be accepted.  (Note that the option
+     applies only when resuming a session, so the earlier behavior was
+     just about the algorithm choice for symmetric cryptography.)
+     [Bodo Moeller]
+
+ Changes between 0.9.8h and 0.9.8i  [15 Sep 2008]
+
+  *) Fix NULL pointer dereference if a DTLS server received
+     ChangeCipherSpec as first record (CVE-2009-1386).
+     [PR #1679]
+
+  *) Fix a state transition in s3_srvr.c and d1_srvr.c
+     (was using SSL3_ST_CW_CLNT_HELLO_B, should be ..._ST_SW_SRVR_...).
+     [Nagendra Modadugu]
+
+  *) The fix in 0.9.8c that supposedly got rid of unsafe
+     double-checked locking was incomplete for RSA blinding,
+     addressing just one layer of what turns out to have been
+     doubly unsafe triple-checked locking.
+
+     So now fix this for real by retiring the MONT_HELPER macro
+     in crypto/rsa/rsa_eay.c.
+
+     [Bodo Moeller; problem pointed out by Marius Schilder]
+
+  *) Various precautionary measures:
+
+     - Avoid size_t integer overflow in HASH_UPDATE (md32_common.h).
+
+     - Avoid a buffer overflow in d2i_SSL_SESSION() (ssl_asn1.c).
+       (NB: This would require knowledge of the secret session ticket key
+       to exploit, in which case you'd be SOL either way.)
+
+     - Change bn_nist.c so that it will properly handle input BIGNUMs
+       outside the expected range.
+
+     - Enforce the 'num' check in BN_div() (bn_div.c) for non-BN_DEBUG
+       builds.
+
+     [Neel Mehta, Bodo Moeller]
+
+  *) Allow engines to be "soft loaded" - i.e. optionally don't die if
+     the load fails. Useful for distros.
+     [Ben Laurie and the FreeBSD team]
+
+  *) Add support for Local Machine Keyset attribute in PKCS#12 files.
+     [Steve Henson]
+
+  *) Fix BN_GF2m_mod_arr() top-bit cleanup code.
+     [Huang Ying]
+
+  *) Expand ENGINE to support engine supplied SSL client certificate functions.
+
+     This work was sponsored by Logica.
+     [Steve Henson]
+
+  *) Add CryptoAPI ENGINE to support use of RSA and DSA keys held in Windows
+     keystores. Support for SSL/TLS client authentication too.
+     Not compiled unless enable-capieng specified to Configure.
+
+     This work was sponsored by Logica.
+     [Steve Henson]
+
+  *) Fix bug in X509_ATTRIBUTE creation: don't set attribute using
+     ASN1_TYPE_set1 if MBSTRING flag set. This bug would crash certain
+     attribute creation routines such as certificate requests and PKCS#12
+     files.
+     [Steve Henson]
+
+ Changes between 0.9.8g and 0.9.8h  [28 May 2008]
+
+  *) Fix flaw if 'Server Key exchange message' is omitted from a TLS
+     handshake which could lead to a cilent crash as found using the
+     Codenomicon TLS test suite (CVE-2008-1672) 
+     [Steve Henson, Mark Cox]
+
+  *) Fix double free in TLS server name extensions which could lead to
+     a remote crash found by Codenomicon TLS test suite (CVE-2008-0891) 
+     [Joe Orton]
+
+  *) Clear error queue in SSL_CTX_use_certificate_chain_file()
+
+     Clear the error queue to ensure that error entries left from
+     older function calls do not interfere with the correct operation.
+     [Lutz Jaenicke, Erik de Castro Lopo]
+
+  *) Remove root CA certificates of commercial CAs:
+
+     The OpenSSL project does not recommend any specific CA and does not
+     have any policy with respect to including or excluding any CA.
+     Therefore it does not make any sense to ship an arbitrary selection
+     of root CA certificates with the OpenSSL software.
+     [Lutz Jaenicke]
+
+  *) RSA OAEP patches to fix two separate invalid memory reads.
+     The first one involves inputs when 'lzero' is greater than
+     'SHA_DIGEST_LENGTH' (it would read about SHA_DIGEST_LENGTH bytes
+     before the beginning of from). The second one involves inputs where
+     the 'db' section contains nothing but zeroes (there is a one-byte
+     invalid read after the end of 'db').
+     [Ivan Nestlerode <inestlerode@us.ibm.com>]
+
+  *) Partial backport from 0.9.9-dev:
+
+     Introduce bn_mul_mont (dedicated Montgomery multiplication
+     procedure) as a candidate for BIGNUM assembler implementation.
+     While 0.9.9-dev uses assembler for various architectures, only
+     x86_64 is available by default here in the 0.9.8 branch, and
+     32-bit x86 is available through a compile-time setting.
+
+     To try the 32-bit x86 assembler implementation, use Configure
+     option "enable-montasm" (which exists only for this backport).
+
+     As "enable-montasm" for 32-bit x86 disclaims code stability
+     anyway, in this constellation we activate additional code
+     backported from 0.9.9-dev for further performance improvements,
+     namely BN_from_montgomery_word.  (To enable this otherwise,
+     e.g. x86_64, try "-DMONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD".)
+
+     [Andy Polyakov (backport partially by Bodo Moeller)]
+
+  *) Add TLS session ticket callback. This allows an application to set
+     TLS ticket cipher and HMAC keys rather than relying on hardcoded fixed
+     values. This is useful for key rollover for example where several key
+     sets may exist with different names.
+     [Steve Henson]
+
+  *) Reverse ENGINE-internal logic for caching default ENGINE handles.
+     This was broken until now in 0.9.8 releases, such that the only way
+     a registered ENGINE could be used (assuming it initialises
+     successfully on the host) was to explicitly set it as the default
+     for the relevant algorithms. This is in contradiction with 0.9.7
+     behaviour and the documentation. With this fix, when an ENGINE is
+     registered into a given algorithm's table of implementations, the
+     'uptodate' flag is reset so that auto-discovery will be used next
+     time a new context for that algorithm attempts to select an
+     implementation.
+     [Ian Lister (tweaked by Geoff Thorpe)]
+
+  *) Backport of CMS code to OpenSSL 0.9.8. This differs from the 0.9.9
+     implementation in the following ways:
+
+     Lack of EVP_PKEY_ASN1_METHOD means algorithm parameters have to be
+     hard coded.
+
+     Lack of BER streaming support means one pass streaming processing is
+     only supported if data is detached: setting the streaming flag is
+     ignored for embedded content.
+
+     CMS support is disabled by default and must be explicitly enabled
+     with the enable-cms configuration option.
+     [Steve Henson]
+
+  *) Update the GMP engine glue to do direct copies between BIGNUM and
+     mpz_t when openssl and GMP use the same limb size. Otherwise the
+     existing "conversion via a text string export" trick is still used.
+     [Paul Sheer <paulsheer@gmail.com>]
+
+  *) Zlib compression BIO. This is a filter BIO which compressed and
+     uncompresses any data passed through it.
+     [Steve Henson]
+
+  *) Add AES_wrap_key() and AES_unwrap_key() functions to implement
+     RFC3394 compatible AES key wrapping.
+     [Steve Henson]
+
+  *) Add utility functions to handle ASN1 structures. ASN1_STRING_set0():
+     sets string data without copying. X509_ALGOR_set0() and
+     X509_ALGOR_get0(): set and retrieve X509_ALGOR (AlgorithmIdentifier)
+     data. Attribute function X509at_get0_data_by_OBJ(): retrieves data
+     from an X509_ATTRIBUTE structure optionally checking it occurs only
+     once. ASN1_TYPE_set1(): set and ASN1_TYPE structure copying supplied
+     data.
+     [Steve Henson]
+
+  *) Fix BN flag handling in RSA_eay_mod_exp() and BN_MONT_CTX_set()
+     to get the expected BN_FLG_CONSTTIME behavior.
+     [Bodo Moeller (Google)]
+  
+  *) Netware support:
+
+     - fixed wrong usage of ioctlsocket() when build for LIBC BSD sockets
+     - fixed do_tests.pl to run the test suite with CLIB builds too (CLIB_OPT)
+     - added some more tests to do_tests.pl
+     - fixed RunningProcess usage so that it works with newer LIBC NDKs too
+     - removed usage of BN_LLONG for CLIB builds to avoid runtime dependency
+     - added new Configure targets netware-clib-bsdsock, netware-clib-gcc,
+       netware-clib-bsdsock-gcc, netware-libc-bsdsock-gcc
+     - various changes to netware.pl to enable gcc-cross builds on Win32
+       platform
+     - changed crypto/bio/b_sock.c to work with macro functions (CLIB BSD)
+     - various changes to fix missing prototype warnings
+     - fixed x86nasm.pl to create correct asm files for NASM COFF output
+     - added AES, WHIRLPOOL and CPUID assembler code to build files
+     - added missing AES assembler make rules to mk1mf.pl
+     - fixed order of includes in apps/ocsp.c so that e_os.h settings apply
+     [Guenter Knauf <eflash@gmx.net>]
+
+  *) Implement certificate status request TLS extension defined in RFC3546.
+     A client can set the appropriate parameters and receive the encoded
+     OCSP response via a callback. A server can query the supplied parameters
+     and set the encoded OCSP response in the callback. Add simplified examples
+     to s_client and s_server.
+     [Steve Henson]
+
+ Changes between 0.9.8f and 0.9.8g  [19 Oct 2007]
+
+  *) Fix various bugs:
+     + Binary incompatibility of ssl_ctx_st structure
+     + DTLS interoperation with non-compliant servers
+     + Don't call get_session_cb() without proposed session
+     + Fix ia64 assembler code
+     [Andy Polyakov, Steve Henson]
+
+ Changes between 0.9.8e and 0.9.8f  [11 Oct 2007]
+
+  *) DTLS Handshake overhaul. There were longstanding issues with
+     OpenSSL DTLS implementation, which were making it impossible for
+     RFC 4347 compliant client to communicate with OpenSSL server.
+     Unfortunately just fixing these incompatibilities would "cut off"
+     pre-0.9.8f clients. To allow for hassle free upgrade post-0.9.8e
+     server keeps tolerating non RFC compliant syntax. The opposite is
+     not true, 0.9.8f client can not communicate with earlier server.
+     This update even addresses CVE-2007-4995.
+     [Andy Polyakov]
+
+  *) Changes to avoid need for function casts in OpenSSL: some compilers
+     (gcc 4.2 and later) reject their use.
+     [Kurt Roeckx <kurt@roeckx.be>, Peter Hartley <pdh@utter.chaos.org.uk>,
+      Steve Henson]
+  
+  *) Add RFC4507 support to OpenSSL. This includes the corrections in
+     RFC4507bis. The encrypted ticket format is an encrypted encoded
+     SSL_SESSION structure, that way new session features are automatically
+     supported.
+
+     If a client application caches session in an SSL_SESSION structure
+     support is transparent because tickets are now stored in the encoded
+     SSL_SESSION.
+     
+     The SSL_CTX structure automatically generates keys for ticket
+     protection in servers so again support should be possible
+     with no application modification.
+
+     If a client or server wishes to disable RFC4507 support then the option
+     SSL_OP_NO_TICKET can be set.
+
+     Add a TLS extension debugging callback to allow the contents of any client
+     or server extensions to be examined.
+
+     This work was sponsored by Google.
+     [Steve Henson]
+
+  *) Add initial support for TLS extensions, specifically for the server_name
+     extension so far.  The SSL_SESSION, SSL_CTX, and SSL data structures now
+     have new members for a host name.  The SSL data structure has an
+     additional member SSL_CTX *initial_ctx so that new sessions can be
+     stored in that context to allow for session resumption, even after the
+     SSL has been switched to a new SSL_CTX in reaction to a client's
+     server_name extension.
+
+     New functions (subject to change):
+
+         SSL_get_servername()
+         SSL_get_servername_type()
+         SSL_set_SSL_CTX()
+
+     New CTRL codes and macros (subject to change):
+
+         SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
+                                 - SSL_CTX_set_tlsext_servername_callback()
+         SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG
+                                      - SSL_CTX_set_tlsext_servername_arg()
+         SSL_CTRL_SET_TLSEXT_HOSTNAME           - SSL_set_tlsext_host_name()
+
+     openssl s_client has a new '-servername ...' option.
+
+     openssl s_server has new options '-servername_host ...', '-cert2 ...',
+     '-key2 ...', '-servername_fatal' (subject to change).  This allows
+     testing the HostName extension for a specific single host name ('-cert'
+     and '-key' remain fallbacks for handshakes without HostName
+     negotiation).  If the unrecognized_name alert has to be sent, this by
+     default is a warning; it becomes fatal with the '-servername_fatal'
+     option.
+
+     [Peter Sylvester,  Remy Allais, Christophe Renou, Steve Henson]
+
+  *) Add AES and SSE2 assembly language support to VC++ build.
+     [Steve Henson]
+
+  *) Mitigate attack on final subtraction in Montgomery reduction.
+     [Andy Polyakov]
+
+  *) Fix crypto/ec/ec_mult.c to work properly with scalars of value 0
+     (which previously caused an internal error).
+     [Bodo Moeller]
+
+  *) Squeeze another 10% out of IGE mode when in != out.
+     [Ben Laurie]
+
+  *) AES IGE mode speedup.
+     [Dean Gaudet (Google)]
+
+  *) Add the Korean symmetric 128-bit cipher SEED (see
+     http://www.kisa.or.kr/kisa/seed/jsp/seed_eng.jsp) and
+     add SEED ciphersuites from RFC 4162:
+
+        TLS_RSA_WITH_SEED_CBC_SHA      =  "SEED-SHA"
+        TLS_DHE_DSS_WITH_SEED_CBC_SHA  =  "DHE-DSS-SEED-SHA"
+        TLS_DHE_RSA_WITH_SEED_CBC_SHA  =  "DHE-RSA-SEED-SHA"
+        TLS_DH_anon_WITH_SEED_CBC_SHA  =  "ADH-SEED-SHA"
+
+     To minimize changes between patchlevels in the OpenSSL 0.9.8
+     series, SEED remains excluded from compilation unless OpenSSL
+     is configured with 'enable-seed'.
+     [KISA, Bodo Moeller]
+
+  *) Mitigate branch prediction attacks, which can be practical if a
+     single processor is shared, allowing a spy process to extract
+     information.  For detailed background information, see
+     http://eprint.iacr.org/2007/039 (O. Aciicmez, S. Gueron,
+     J.-P. Seifert, "New Branch Prediction Vulnerabilities in OpenSSL
+     and Necessary Software Countermeasures").  The core of the change
+     are new versions BN_div_no_branch() and
+     BN_mod_inverse_no_branch() of BN_div() and BN_mod_inverse(),
+     respectively, which are slower, but avoid the security-relevant
+     conditional branches.  These are automatically called by BN_div()
+     and BN_mod_inverse() if the flag BN_FLG_CONSTTIME is set for one
+     of the input BIGNUMs.  Also, BN_is_bit_set() has been changed to
+     remove a conditional branch.
+
+     BN_FLG_CONSTTIME is the new name for the previous
+     BN_FLG_EXP_CONSTTIME flag, since it now affects more than just
+     modular exponentiation.  (Since OpenSSL 0.9.7h, setting this flag
+     in the exponent causes BN_mod_exp_mont() to use the alternative
+     implementation in BN_mod_exp_mont_consttime().)  The old name
+     remains as a deprecated alias.
+
+     Similarly, RSA_FLAG_NO_EXP_CONSTTIME is replaced by a more general
+     RSA_FLAG_NO_CONSTTIME flag since the RSA implementation now uses
+     constant-time implementations for more than just exponentiation.
+     Here too the old name is kept as a deprecated alias.
+
+     BN_BLINDING_new() will now use BN_dup() for the modulus so that
+     the BN_BLINDING structure gets an independent copy of the
+     modulus.  This means that the previous "BIGNUM *m" argument to
+     BN_BLINDING_new() and to BN_BLINDING_create_param() now
+     essentially becomes "const BIGNUM *m", although we can't actually
+     change this in the header file before 0.9.9.  It allows
+     RSA_setup_blinding() to use BN_with_flags() on the modulus to
+     enable BN_FLG_CONSTTIME.
+
+     [Matthew D Wood (Intel Corp)]
+
+  *) In the SSL/TLS server implementation, be strict about session ID
+     context matching (which matters if an application uses a single
+     external cache for different purposes).  Previously,
+     out-of-context reuse was forbidden only if SSL_VERIFY_PEER was
+     set.  This did ensure strict client verification, but meant that,
+     with applications using a single external cache for quite
+     different requirements, clients could circumvent ciphersuite
+     restrictions for a given session ID context by starting a session
+     in a different context.
+     [Bodo Moeller]
+
+  *) Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that
+     a ciphersuite string such as "DEFAULT:RSA" cannot enable
+     authentication-only ciphersuites.
+     [Bodo Moeller]
+
+  *) Update the SSL_get_shared_ciphers() fix CVE-2006-3738 which was
+     not complete and could lead to a possible single byte overflow
+     (CVE-2007-5135) [Ben Laurie]
+
+ Changes between 0.9.8d and 0.9.8e  [23 Feb 2007]
+
+  *) Since AES128 and AES256 (and similarly Camellia128 and
+     Camellia256) share a single mask bit in the logic of
+     ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a
+     kludge to work properly if AES128 is available and AES256 isn't
+     (or if Camellia128 is available and Camellia256 isn't).
+     [Victor Duchovni]
+
+  *) Fix the BIT STRING encoding generated by crypto/ec/ec_asn1.c
+     (within i2d_ECPrivateKey, i2d_ECPKParameters, i2d_ECParameters):
+     When a point or a seed is encoded in a BIT STRING, we need to
+     prevent the removal of trailing zero bits to get the proper DER
+     encoding.  (By default, crypto/asn1/a_bitstr.c assumes the case
+     of a NamedBitList, for which trailing 0 bits need to be removed.)
+     [Bodo Moeller]
+
+  *) Have SSL/TLS server implementation tolerate "mismatched" record
+     protocol version while receiving ClientHello even if the
+     ClientHello is fragmented.  (The server can't insist on the
+     particular protocol version it has chosen before the ServerHello
+     message has informed the client about his choice.)
+     [Bodo Moeller]
+
+  *) Add RFC 3779 support.
+     [Rob Austein for ARIN, Ben Laurie]
+
+  *) Load error codes if they are not already present instead of using a
+     static variable. This allows them to be cleanly unloaded and reloaded.
+     Improve header file function name parsing.
+     [Steve Henson]
+
+  *) extend SMTP and IMAP protocol emulation in s_client to use EHLO
+     or CAPABILITY handshake as required by RFCs.
+     [Goetz Babin-Ebell]
+
+ Changes between 0.9.8c and 0.9.8d  [28 Sep 2006]
+
+  *) Introduce limits to prevent malicious keys being able to
+     cause a denial of service.  (CVE-2006-2940)
+     [Steve Henson, Bodo Moeller]
+
+  *) Fix ASN.1 parsing of certain invalid structures that can result
+     in a denial of service.  (CVE-2006-2937)  [Steve Henson]
+
+  *) Fix buffer overflow in SSL_get_shared_ciphers() function. 
+     (CVE-2006-3738) [Tavis Ormandy and Will Drewry, Google Security Team]
+
+  *) Fix SSL client code which could crash if connecting to a
+     malicious SSLv2 server.  (CVE-2006-4343)
+     [Tavis Ormandy and Will Drewry, Google Security Team]
+
+  *) Since 0.9.8b, ciphersuite strings naming explicit ciphersuites
+     match only those.  Before that, "AES256-SHA" would be interpreted
+     as a pattern and match "AES128-SHA" too (since AES128-SHA got
+     the same strength classification in 0.9.7h) as we currently only
+     have a single AES bit in the ciphersuite description bitmap.
+     That change, however, also applied to ciphersuite strings such as
+     "RC4-MD5" that intentionally matched multiple ciphersuites --
+     namely, SSL 2.0 ciphersuites in addition to the more common ones
+     from SSL 3.0/TLS 1.0.
+
+     So we change the selection algorithm again: Naming an explicit
+     ciphersuite selects this one ciphersuite, and any other similar
+     ciphersuite (same bitmap) from *other* protocol versions.
+     Thus, "RC4-MD5" again will properly select both the SSL 2.0
+     ciphersuite and the SSL 3.0/TLS 1.0 ciphersuite.
+
+     Since SSL 2.0 does not have any ciphersuites for which the
+     128/256 bit distinction would be relevant, this works for now.
+     The proper fix will be to use different bits for AES128 and
+     AES256, which would have avoided the problems from the beginning;
+     however, bits are scarce, so we can only do this in a new release
+     (not just a patchlevel) when we can change the SSL_CIPHER
+     definition to split the single 'unsigned long mask' bitmap into
+     multiple values to extend the available space.
+
+     [Bodo Moeller]
+
+ Changes between 0.9.8b and 0.9.8c  [05 Sep 2006]
+
+  *) Avoid PKCS #1 v1.5 signature attack discovered by Daniel Bleichenbacher
+     (CVE-2006-4339)  [Ben Laurie and Google Security Team]
+
+  *) Add AES IGE and biIGE modes.
+     [Ben Laurie]
+
+  *) Change the Unix randomness entropy gathering to use poll() when
+     possible instead of select(), since the latter has some
+     undesirable limitations.
+     [Darryl Miles via Richard Levitte and Bodo Moeller]
+
+  *) Disable "ECCdraft" ciphersuites more thoroughly.  Now special
+     treatment in ssl/ssl_ciph.s makes sure that these ciphersuites
+     cannot be implicitly activated as part of, e.g., the "AES" alias.
+     However, please upgrade to OpenSSL 0.9.9[-dev] for
+     non-experimental use of the ECC ciphersuites to get TLS extension
+     support, which is required for curve and point format negotiation
+     to avoid potential handshake problems.
+     [Bodo Moeller]
+
+  *) Disable rogue ciphersuites:
+
+      - SSLv2 0x08 0x00 0x80 ("RC4-64-MD5")
+      - SSLv3/TLSv1 0x00 0x61 ("EXP1024-RC2-CBC-MD5")
+      - SSLv3/TLSv1 0x00 0x60 ("EXP1024-RC4-MD5")
+
+     The latter two were purportedly from
+     draft-ietf-tls-56-bit-ciphersuites-0[01].txt, but do not really
+     appear there.
+
+     Also deactivate the remaining ciphersuites from
+     draft-ietf-tls-56-bit-ciphersuites-01.txt.  These are just as
+     unofficial, and the ID has long expired.
+     [Bodo Moeller]
+
+  *) Fix RSA blinding Heisenbug (problems sometimes occurred on
+     dual-core machines) and other potential thread-safety issues.
+     [Bodo Moeller]
+
+  *) Add the symmetric cipher Camellia (128-bit, 192-bit, 256-bit key
+     versions), which is now available for royalty-free use
+     (see http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html).
+     Also, add Camellia TLS ciphersuites from RFC 4132.
+
+     To minimize changes between patchlevels in the OpenSSL 0.9.8
+     series, Camellia remains excluded from compilation unless OpenSSL
+     is configured with 'enable-camellia'.
+     [NTT]
+
+  *) Disable the padding bug check when compression is in use. The padding
+     bug check assumes the first packet is of even length, this is not
+     necessarily true if compresssion is enabled and can result in false
+     positives causing handshake failure. The actual bug test is ancient
+     code so it is hoped that implementations will either have fixed it by
+     now or any which still have the bug do not support compression.
+     [Steve Henson]
+
+ Changes between 0.9.8a and 0.9.8b  [04 May 2006]
+
+  *) When applying a cipher rule check to see if string match is an explicit
+     cipher suite and only match that one cipher suite if it is.
+     [Steve Henson]
+
+  *) Link in manifests for VC++ if needed.
+     [Austin Ziegler <halostatue@gmail.com>]
+
+  *) Update support for ECC-based TLS ciphersuites according to
+     draft-ietf-tls-ecc-12.txt with proposed changes (but without
+     TLS extensions, which are supported starting with the 0.9.9
+     branch, not in the OpenSSL 0.9.8 branch).
+     [Douglas Stebila]
+
+  *) New functions EVP_CIPHER_CTX_new() and EVP_CIPHER_CTX_free() to support
+     opaque EVP_CIPHER_CTX handling.
+     [Steve Henson]
+
+  *) Fixes and enhancements to zlib compression code. We now only use
+     "zlib1.dll" and use the default __cdecl calling convention on Win32
+     to conform with the standards mentioned here:
+           http://www.zlib.net/DLL_FAQ.txt
+     Static zlib linking now works on Windows and the new --with-zlib-include
+     --with-zlib-lib options to Configure can be used to supply the location
+     of the headers and library. Gracefully handle case where zlib library
+     can't be loaded.
+     [Steve Henson]
+
+  *) Several fixes and enhancements to the OID generation code. The old code
+     sometimes allowed invalid OIDs (1.X for X >= 40 for example), couldn't
+     handle numbers larger than ULONG_MAX, truncated printing and had a
+     non standard OBJ_obj2txt() behaviour.
+     [Steve Henson]
+
+  *) Add support for building of engines under engine/ as shared libraries
+     under VC++ build system.
+     [Steve Henson]
+
+  *) Corrected the numerous bugs in the Win32 path splitter in DSO.
+     Hopefully, we will not see any false combination of paths any more.
+     [Richard Levitte]
+
+ Changes between 0.9.8 and 0.9.8a  [11 Oct 2005]
+
+  *) Remove the functionality of SSL_OP_MSIE_SSLV2_RSA_PADDING
+     (part of SSL_OP_ALL).  This option used to disable the
+     countermeasure against man-in-the-middle protocol-version
+     rollback in the SSL 2.0 server implementation, which is a bad
+     idea.  (CVE-2005-2969)
+
+     [Bodo Moeller; problem pointed out by Yutaka Oiwa (Research Center
+     for Information Security, National Institute of Advanced Industrial
+     Science and Technology [AIST], Japan)]
+
+  *) Add two function to clear and return the verify parameter flags.
+     [Steve Henson]
+
+  *) Keep cipherlists sorted in the source instead of sorting them at
+     runtime, thus removing the need for a lock.
+     [Nils Larsch]
+
+  *) Avoid some small subgroup attacks in Diffie-Hellman.
+     [Nick Mathewson and Ben Laurie]
+
+  *) Add functions for well-known primes.
+     [Nick Mathewson]
+
+  *) Extended Windows CE support.
+     [Satoshi Nakamura and Andy Polyakov]
+
+  *) Initialize SSL_METHOD structures at compile time instead of during
+     runtime, thus removing the need for a lock.
+     [Steve Henson]
+
+  *) Make PKCS7_decrypt() work even if no certificate is supplied by
+     attempting to decrypt each encrypted key in turn. Add support to
+     smime utility.
+     [Steve Henson]
+
+ Changes between 0.9.7h and 0.9.8  [05 Jul 2005]
+
+  [NB: OpenSSL 0.9.7i and later 0.9.7 patch levels were released after
+  OpenSSL 0.9.8.]
+
+  *) Add libcrypto.pc and libssl.pc for those who feel they need them.
+     [Richard Levitte]
+
+  *) Change CA.sh and CA.pl so they don't bundle the CSR and the private
+     key into the same file any more.
+     [Richard Levitte]
+
+  *) Add initial support for Win64, both IA64 and AMD64/x64 flavors.
+     [Andy Polyakov]
+
+  *) Add -utf8 command line and config file option to 'ca'.
+     [Stefan <stf@udoma.org]
+
+  *) Removed the macro des_crypt(), as it seems to conflict with some
+     libraries.  Use DES_crypt().
+     [Richard Levitte]
+
+  *) Correct naming of the 'chil' and '4758cca' ENGINEs. This
+     involves renaming the source and generated shared-libs for
+     both. The engines will accept the corrected or legacy ids
+     ('ncipher' and '4758_cca' respectively) when binding. NB,
+     this only applies when building 'shared'.
+     [Corinna Vinschen <vinschen@redhat.com> and Geoff Thorpe]
+
+  *) Add attribute functions to EVP_PKEY structure. Modify
+     PKCS12_create() to recognize a CSP name attribute and
+     use it. Make -CSP option work again in pkcs12 utility.
+     [Steve Henson]
+
+  *) Add new functionality to the bn blinding code:
+     - automatic re-creation of the BN_BLINDING parameters after
+       a fixed number of uses (currently 32)
+     - add new function for parameter creation
+     - introduce flags to control the update behaviour of the
+       BN_BLINDING parameters
+     - hide BN_BLINDING structure
+     Add a second BN_BLINDING slot to the RSA structure to improve
+     performance when a single RSA object is shared among several
+     threads.
+     [Nils Larsch]
+
+  *) Add support for DTLS.
+     [Nagendra Modadugu <nagendra@cs.stanford.edu> and Ben Laurie]
+
+  *) Add support for DER encoded private keys (SSL_FILETYPE_ASN1)
+     to SSL_CTX_use_PrivateKey_file() and SSL_use_PrivateKey_file()
+     [Walter Goulet]
+
+  *) Remove buggy and incomplete DH cert support from
+     ssl/ssl_rsa.c and ssl/s3_both.c
+     [Nils Larsch]
+
+  *) Use SHA-1 instead of MD5 as the default digest algorithm for
+     the apps/openssl applications.
+     [Nils Larsch]
+
+  *) Compile clean with "-Wall -Wmissing-prototypes
+     -Wstrict-prototypes -Wmissing-declarations -Werror". Currently
+     DEBUG_SAFESTACK must also be set.
+     [Ben Laurie]
+
+  *) Change ./Configure so that certain algorithms can be disabled by default.
+     The new counterpiece to "no-xxx" is "enable-xxx".
+
+     The patented RC5 and MDC2 algorithms will now be disabled unless
+     "enable-rc5" and "enable-mdc2", respectively, are specified.
+
+     (IDEA remains enabled despite being patented.  This is because IDEA
+     is frequently required for interoperability, and there is no license
+     fee for non-commercial use.  As before, "no-idea" can be used to
+     avoid this algorithm.)
+
+     [Bodo Moeller]
+
+  *) Add processing of proxy certificates (see RFC 3820).  This work was
+     sponsored by KTH (The Royal Institute of Technology in Stockholm) and
+     EGEE (Enabling Grids for E-science in Europe).
+     [Richard Levitte]
+
+  *) RC4 performance overhaul on modern architectures/implementations, such
+     as Intel P4, IA-64 and AMD64.
+     [Andy Polyakov]
+
+  *) New utility extract-section.pl. This can be used specify an alternative
+     section number in a pod file instead of having to treat each file as
+     a separate case in Makefile. This can be done by adding two lines to the
+     pod file:
+
+     =for comment openssl_section:XXX
+
+     The blank line is mandatory.
+
+     [Steve Henson]
+
+  *) New arguments -certform, -keyform and -pass for s_client and s_server
+     to allow alternative format key and certificate files and passphrase
+     sources.
+     [Steve Henson]
+
+  *) New structure X509_VERIFY_PARAM which combines current verify parameters,
+     update associated structures and add various utility functions.
+
+     Add new policy related verify parameters, include policy checking in 
+     standard verify code. Enhance 'smime' application with extra parameters
+     to support policy checking and print out.
+     [Steve Henson]
+
+  *) Add a new engine to support VIA PadLock ACE extensions in the VIA C3
+     Nehemiah processors. These extensions support AES encryption in hardware
+     as well as RNG (though RNG support is currently disabled).
+     [Michal Ludvig <michal@logix.cz>, with help from Andy Polyakov]
+
+  *) Deprecate BN_[get|set]_params() functions (they were ignored internally).
+     [Geoff Thorpe]
+
+  *) New FIPS 180-2 algorithms, SHA-224/-256/-384/-512 are implemented.
+     [Andy Polyakov and a number of other people]
+
+  *) Improved PowerPC platform support. Most notably BIGNUM assembler
+     implementation contributed by IBM.
+     [Suresh Chari, Peter Waltenberg, Andy Polyakov]
+
+  *) The new 'RSA_generate_key_ex' function now takes a BIGNUM for the public
+     exponent rather than 'unsigned long'. There is a corresponding change to
+     the new 'rsa_keygen' element of the RSA_METHOD structure.
+     [Jelte Jansen, Geoff Thorpe]
+
+  *) Functionality for creating the initial serial number file is now
+     moved from CA.pl to the 'ca' utility with a new option -create_serial.
+
+     (Before OpenSSL 0.9.7e, CA.pl used to initialize the serial
+     number file to 1, which is bound to cause problems.  To avoid
+     the problems while respecting compatibility between different 0.9.7
+     patchlevels, 0.9.7e  employed 'openssl x509 -next_serial' in
+     CA.pl for serial number initialization.  With the new release 0.9.8,
+     we can fix the problem directly in the 'ca' utility.)
+     [Steve Henson]
+
+  *) Reduced header interdepencies by declaring more opaque objects in
+     ossl_typ.h. As a consequence, including some headers (eg. engine.h) will
+     give fewer recursive includes, which could break lazy source code - so
+     this change is covered by the OPENSSL_NO_DEPRECATED symbol. As always,
+     developers should define this symbol when building and using openssl to
+     ensure they track the recommended behaviour, interfaces, [etc], but
+     backwards-compatible behaviour prevails when this isn't defined.
+     [Geoff Thorpe]
+
+  *) New function X509_POLICY_NODE_print() which prints out policy nodes.
+     [Steve Henson]
+
+  *) Add new EVP function EVP_CIPHER_CTX_rand_key and associated functionality.
+     This will generate a random key of the appropriate length based on the 
+     cipher context. The EVP_CIPHER can provide its own random key generation
+     routine to support keys of a specific form. This is used in the des and 
+     3des routines to generate a key of the correct parity. Update S/MIME
+     code to use new functions and hence generate correct parity DES keys.
+     Add EVP_CHECK_DES_KEY #define to return an error if the key is not 
+     valid (weak or incorrect parity).
+     [Steve Henson]
+
+  *) Add a local set of CRLs that can be used by X509_verify_cert() as well
+     as looking them up. This is useful when the verified structure may contain
+     CRLs, for example PKCS#7 signedData. Modify PKCS7_verify() to use any CRLs
+     present unless the new PKCS7_NO_CRL flag is asserted.
+     [Steve Henson]
+
+  *) Extend ASN1 oid configuration module. It now additionally accepts the
+     syntax:
+
+     shortName = some long name, 1.2.3.4
+     [Steve Henson]
+
+  *) Reimplemented the BN_CTX implementation. There is now no more static
+     limitation on the number of variables it can handle nor the depth of the
+     "stack" handling for BN_CTX_start()/BN_CTX_end() pairs. The stack
+     information can now expand as required, and rather than having a single
+     static array of bignums, BN_CTX now uses a linked-list of such arrays
+     allowing it to expand on demand whilst maintaining the usefulness of
+     BN_CTX's "bundling".
+     [Geoff Thorpe]
+
+  *) Add a missing BN_CTX parameter to the 'rsa_mod_exp' callback in RSA_METHOD
+     to allow all RSA operations to function using a single BN_CTX.
+     [Geoff Thorpe]
+
+  *) Preliminary support for certificate policy evaluation and checking. This
+     is initially intended to pass the tests outlined in "Conformance Testing
+     of Relying Party Client Certificate Path Processing Logic" v1.07.
+     [Steve Henson]
+
+  *) bn_dup_expand() has been deprecated, it was introduced in 0.9.7 and
+     remained unused and not that useful. A variety of other little bignum
+     tweaks and fixes have also been made continuing on from the audit (see
+     below).
+     [Geoff Thorpe]
+
+  *) Constify all or almost all d2i, c2i, s2i and r2i functions, along with
+     associated ASN1, EVP and SSL functions and old ASN1 macros.
+     [Richard Levitte]
+
+  *) BN_zero() only needs to set 'top' and 'neg' to zero for correct results,
+     and this should never fail. So the return value from the use of
+     BN_set_word() (which can fail due to needless expansion) is now deprecated;
+     if OPENSSL_NO_DEPRECATED is defined, BN_zero() is a void macro.
+     [Geoff Thorpe]
+
+  *) BN_CTX_get() should return zero-valued bignums, providing the same
+     initialised value as BN_new().
+     [Geoff Thorpe, suggested by Ulf MÃ¶ller]
+
+  *) Support for inhibitAnyPolicy certificate extension.
+     [Steve Henson]
+
+  *) An audit of the BIGNUM code is underway, for which debugging code is
+     enabled when BN_DEBUG is defined. This makes stricter enforcements on what
+     is considered valid when processing BIGNUMs, and causes execution to
+     assert() when a problem is discovered. If BN_DEBUG_RAND is defined,
+     further steps are taken to deliberately pollute unused data in BIGNUM
+     structures to try and expose faulty code further on. For now, openssl will
+     (in its default mode of operation) continue to tolerate the inconsistent
+     forms that it has tolerated in the past, but authors and packagers should
+     consider trying openssl and their own applications when compiled with
+     these debugging symbols defined. It will help highlight potential bugs in
+     their own code, and will improve the test coverage for OpenSSL itself. At
+     some point, these tighter rules will become openssl's default to improve
+     maintainability, though the assert()s and other overheads will remain only
+     in debugging configurations. See bn.h for more details.
+     [Geoff Thorpe, Nils Larsch, Ulf MÃ¶ller]
+
+  *) BN_CTX_init() has been deprecated, as BN_CTX is an opaque structure
+     that can only be obtained through BN_CTX_new() (which implicitly
+     initialises it). The presence of this function only made it possible
+     to overwrite an existing structure (and cause memory leaks).
+     [Geoff Thorpe]
+
+  *) Because of the callback-based approach for implementing LHASH as a
+     template type, lh_insert() adds opaque objects to hash-tables and
+     lh_doall() or lh_doall_arg() are typically used with a destructor callback
+     to clean up those corresponding objects before destroying the hash table
+     (and losing the object pointers). So some over-zealous constifications in
+     LHASH have been relaxed so that lh_insert() does not take (nor store) the
+     objects as "const" and the lh_doall[_arg] callback wrappers are not
+     prototyped to have "const" restrictions on the object pointers they are
+     given (and so aren't required to cast them away any more).
+     [Geoff Thorpe]
+
+  *) The tmdiff.h API was so ugly and minimal that our own timing utility
+     (speed) prefers to use its own implementation. The two implementations
+     haven't been consolidated as yet (volunteers?) but the tmdiff API has had
+     its object type properly exposed (MS_TM) instead of casting to/from "char
+     *". This may still change yet if someone realises MS_TM and "ms_time_***"
+     aren't necessarily the greatest nomenclatures - but this is what was used
+     internally to the implementation so I've used that for now.
+     [Geoff Thorpe]
+
+  *) Ensure that deprecated functions do not get compiled when
+     OPENSSL_NO_DEPRECATED is defined. Some "openssl" subcommands and a few of
+     the self-tests were still using deprecated key-generation functions so
+     these have been updated also.
+     [Geoff Thorpe]
+
+  *) Reorganise PKCS#7 code to separate the digest location functionality
+     into PKCS7_find_digest(), digest addition into PKCS7_bio_add_digest().
+     New function PKCS7_set_digest() to set the digest type for PKCS#7
+     digestedData type. Add additional code to correctly generate the
+     digestedData type and add support for this type in PKCS7 initialization
+     functions.
+     [Steve Henson]
+
+  *) New function PKCS7_set0_type_other() this initializes a PKCS7 
+     structure of type "other".
+     [Steve Henson]
+
+  *) Fix prime generation loop in crypto/bn/bn_prime.pl by making
+     sure the loop does correctly stop and breaking ("division by zero")
+     modulus operations are not performed. The (pre-generated) prime
+     table crypto/bn/bn_prime.h was already correct, but it could not be
+     re-generated on some platforms because of the "division by zero"
+     situation in the script.
+     [Ralf S. Engelschall]
+
+  *) Update support for ECC-based TLS ciphersuites according to
+     draft-ietf-tls-ecc-03.txt: the KDF1 key derivation function with
+     SHA-1 now is only used for "small" curves (where the
+     representation of a field element takes up to 24 bytes); for
+     larger curves, the field element resulting from ECDH is directly
+     used as premaster secret.
+     [Douglas Stebila (Sun Microsystems Laboratories)]
+
+  *) Add code for kP+lQ timings to crypto/ec/ectest.c, and add SEC2
+     curve secp160r1 to the tests.
+     [Douglas Stebila (Sun Microsystems Laboratories)]
+
+  *) Add the possibility to load symbols globally with DSO.
+     [GÃ¶tz Babin-Ebell <babin-ebell@trustcenter.de> via Richard Levitte]
+
+  *) Add the functions ERR_set_mark() and ERR_pop_to_mark() for better
+     control of the error stack.
+     [Richard Levitte]
+
+  *) Add support for STORE in ENGINE.
+     [Richard Levitte]
+
+  *) Add the STORE type.  The intention is to provide a common interface
+     to certificate and key stores, be they simple file-based stores, or
+     HSM-type store, or LDAP stores, or...
+     NOTE: The code is currently UNTESTED and isn't really used anywhere.
+     [Richard Levitte]
+
+  *) Add a generic structure called OPENSSL_ITEM.  This can be used to
+     pass a list of arguments to any function as well as provide a way
+     for a function to pass data back to the caller.
+     [Richard Levitte]
+
+  *) Add the functions BUF_strndup() and BUF_memdup().  BUF_strndup()
+     works like BUF_strdup() but can be used to duplicate a portion of
+     a string.  The copy gets NUL-terminated.  BUF_memdup() duplicates
+     a memory area.
+     [Richard Levitte]
+
+  *) Add the function sk_find_ex() which works like sk_find(), but will
+     return an index to an element even if an exact match couldn't be
+     found.  The index is guaranteed to point at the element where the
+     searched-for key would be inserted to preserve sorting order.
+     [Richard Levitte]
+
+  *) Add the function OBJ_bsearch_ex() which works like OBJ_bsearch() but
+     takes an extra flags argument for optional functionality.  Currently,
+     the following flags are defined:
+
+	OBJ_BSEARCH_VALUE_ON_NOMATCH
+	This one gets OBJ_bsearch_ex() to return a pointer to the first
+	element where the comparing function returns a negative or zero
+	number.
+
+	OBJ_BSEARCH_FIRST_VALUE_ON_MATCH
+	This one gets OBJ_bsearch_ex() to return a pointer to the first
+	element where the comparing function returns zero.  This is useful
+	if there are more than one element where the comparing function
+	returns zero.
+     [Richard Levitte]
+
+  *) Make it possible to create self-signed certificates with 'openssl ca'
+     in such a way that the self-signed certificate becomes part of the
+     CA database and uses the same mechanisms for serial number generation
+     as all other certificate signing.  The new flag '-selfsign' enables
+     this functionality.  Adapt CA.sh and CA.pl.in.
+     [Richard Levitte]
+
+  *) Add functionality to check the public key of a certificate request
+     against a given private.  This is useful to check that a certificate
+     request can be signed by that key (self-signing).
+     [Richard Levitte]
+
+  *) Make it possible to have multiple active certificates with the same
+     subject in the CA index file.  This is done only if the keyword
+     'unique_subject' is set to 'no' in the main CA section (default
+     if 'CA_default') of the configuration file.  The value is saved
+     with the database itself in a separate index attribute file,
+     named like the index file with '.attr' appended to the name.
+     [Richard Levitte]
+
+  *) Generate muti valued AVAs using '+' notation in config files for
+     req and dirName.
+     [Steve Henson]
+
+  *) Support for nameConstraints certificate extension.
+     [Steve Henson]
+
+  *) Support for policyConstraints certificate extension.
+     [Steve Henson]
+
+  *) Support for policyMappings certificate extension.
+     [Steve Henson]
+
+  *) Make sure the default DSA_METHOD implementation only uses its
+     dsa_mod_exp() and/or bn_mod_exp() handlers if they are non-NULL,
+     and change its own handlers to be NULL so as to remove unnecessary
+     indirection. This lets alternative implementations fallback to the
+     default implementation more easily.
+     [Geoff Thorpe]
+
+  *) Support for directoryName in GeneralName related extensions
+     in config files.
+     [Steve Henson]
+
+  *) Make it possible to link applications using Makefile.shared.
+     Make that possible even when linking against static libraries!
+     [Richard Levitte]
+
+  *) Support for single pass processing for S/MIME signing. This now
+     means that S/MIME signing can be done from a pipe, in addition
+     cleartext signing (multipart/signed type) is effectively streaming
+     and the signed data does not need to be all held in memory.
+
+     This is done with a new flag PKCS7_STREAM. When this flag is set
+     PKCS7_sign() only initializes the PKCS7 structure and the actual signing
+     is done after the data is output (and digests calculated) in
+     SMIME_write_PKCS7().
+     [Steve Henson]
+
+  *) Add full support for -rpath/-R, both in shared libraries and
+     applications, at least on the platforms where it's known how
+     to do it.
+     [Richard Levitte]
+
+  *) In crypto/ec/ec_mult.c, implement fast point multiplication with
+     precomputation, based on wNAF splitting: EC_GROUP_precompute_mult()
+     will now compute a table of multiples of the generator that
+     makes subsequent invocations of EC_POINTs_mul() or EC_POINT_mul()
+     faster (notably in the case of a single point multiplication,
+     scalar * generator).
+     [Nils Larsch, Bodo Moeller]
+
+  *) IPv6 support for certificate extensions. The various extensions
+     which use the IP:a.b.c.d can now take IPv6 addresses using the
+     formats of RFC1884 2.2 . IPv6 addresses are now also displayed
+     correctly.
+     [Steve Henson]
+
+  *) Added an ENGINE that implements RSA by performing private key
+     exponentiations with the GMP library. The conversions to and from
+     GMP's mpz_t format aren't optimised nor are any montgomery forms
+     cached, and on x86 it appears OpenSSL's own performance has caught up.
+     However there are likely to be other architectures where GMP could
+     provide a boost. This ENGINE is not built in by default, but it can be
+     specified at Configure time and should be accompanied by the necessary
+     linker additions, eg;
+         ./config -DOPENSSL_USE_GMP -lgmp
+     [Geoff Thorpe]
+
+  *) "openssl engine" will not display ENGINE/DSO load failure errors when
+     testing availability of engines with "-t" - the old behaviour is
+     produced by increasing the feature's verbosity with "-tt".
+     [Geoff Thorpe]
+
+  *) ECDSA routines: under certain error conditions uninitialized BN objects
+     could be freed. Solution: make sure initialization is performed early
+     enough. (Reported and fix supplied by Nils Larsch <nla@trustcenter.de>
+     via PR#459)
+     [Lutz Jaenicke]
+
+  *) Key-generation can now be implemented in RSA_METHOD, DSA_METHOD
+     and DH_METHOD (eg. by ENGINE implementations) to override the normal
+     software implementations. For DSA and DH, parameter generation can
+     also be overridden by providing the appropriate method callbacks.
+     [Geoff Thorpe]
+
+  *) Change the "progress" mechanism used in key-generation and
+     primality testing to functions that take a new BN_GENCB pointer in
+     place of callback/argument pairs. The new API functions have "_ex"
+     postfixes and the older functions are reimplemented as wrappers for
+     the new ones. The OPENSSL_NO_DEPRECATED symbol can be used to hide
+     declarations of the old functions to help (graceful) attempts to
+     migrate to the new functions. Also, the new key-generation API
+     functions operate on a caller-supplied key-structure and return
+     success/failure rather than returning a key or NULL - this is to
+     help make "keygen" another member function of RSA_METHOD etc.
+
+     Example for using the new callback interface:
+
+          int (*my_callback)(int a, int b, BN_GENCB *cb) = ...;
+          void *my_arg = ...;
+          BN_GENCB my_cb;
+
+          BN_GENCB_set(&my_cb, my_callback, my_arg);
+
+          return BN_is_prime_ex(some_bignum, BN_prime_checks, NULL, &cb);
+          /* For the meaning of a, b in calls to my_callback(), see the
+           * documentation of the function that calls the callback.
+           * cb will point to my_cb; my_arg can be retrieved as cb->arg.
+           * my_callback should return 1 if it wants BN_is_prime_ex()
+           * to continue, or 0 to stop.
+           */
+
+     [Geoff Thorpe]
+
+  *) Change the ZLIB compression method to be stateful, and make it
+     available to TLS with the number defined in 
+     draft-ietf-tls-compression-04.txt.
+     [Richard Levitte]
+
+  *) Add the ASN.1 structures and functions for CertificatePair, which
+     is defined as follows (according to X.509_4thEditionDraftV6.pdf):
+
+     CertificatePair ::= SEQUENCE {
+        forward		[0]	Certificate OPTIONAL,
+        reverse		[1]	Certificate OPTIONAL,
+        -- at least one of the pair shall be present -- }
+
+     Also implement the PEM functions to read and write certificate
+     pairs, and defined the PEM tag as "CERTIFICATE PAIR".
+
+     This needed to be defined, mostly for the sake of the LDAP
+     attribute crossCertificatePair, but may prove useful elsewhere as
+     well.
+     [Richard Levitte]
+
+  *) Make it possible to inhibit symlinking of shared libraries in
+     Makefile.shared, for Cygwin's sake.
+     [Richard Levitte]
+
+  *) Extend the BIGNUM API by creating a function 
+          void BN_set_negative(BIGNUM *a, int neg);
+     and a macro that behave like
+          int  BN_is_negative(const BIGNUM *a);
+
+     to avoid the need to access 'a->neg' directly in applications.
+     [Nils Larsch]
+
+  *) Implement fast modular reduction for pseudo-Mersenne primes
+     used in NIST curves (crypto/bn/bn_nist.c, crypto/ec/ecp_nist.c).
+     EC_GROUP_new_curve_GFp() will now automatically use this
+     if applicable.
+     [Nils Larsch <nla@trustcenter.de>]
+
+  *) Add new lock type (CRYPTO_LOCK_BN).
+     [Bodo Moeller]
+
+  *) Change the ENGINE framework to automatically load engines
+     dynamically from specific directories unless they could be
+     found to already be built in or loaded.  Move all the
+     current engines except for the cryptodev one to a new
+     directory engines/.
+     The engines in engines/ are built as shared libraries if
+     the "shared" options was given to ./Configure or ./config.
+     Otherwise, they are inserted in libcrypto.a.
+     /usr/local/ssl/engines is the default directory for dynamic
+     engines, but that can be overridden at configure time through
+     the usual use of --prefix and/or --openssldir, and at run
+     time with the environment variable OPENSSL_ENGINES.
+     [Geoff Thorpe and Richard Levitte]
+
+  *) Add Makefile.shared, a helper makefile to build shared
+     libraries.  Adapt Makefile.org.
+     [Richard Levitte]
+
+  *) Add version info to Win32 DLLs.
+     [Peter 'Luna' Runestig" <peter@runestig.com>]
+
+  *) Add new 'medium level' PKCS#12 API. Certificates and keys
+     can be added using this API to created arbitrary PKCS#12
+     files while avoiding the low level API.
+
+     New options to PKCS12_create(), key or cert can be NULL and
+     will then be omitted from the output file. The encryption
+     algorithm NIDs can be set to -1 for no encryption, the mac
+     iteration count can be set to 0 to omit the mac.
+
+     Enhance pkcs12 utility by making the -nokeys and -nocerts
+     options work when creating a PKCS#12 file. New option -nomac
+     to omit the mac, NONE can be set for an encryption algorithm.
+     New code is modified to use the enhanced PKCS12_create()
+     instead of the low level API.
+     [Steve Henson]
+
+  *) Extend ASN1 encoder to support indefinite length constructed
+     encoding. This can output sequences tags and octet strings in
+     this form. Modify pk7_asn1.c to support indefinite length
+     encoding. This is experimental and needs additional code to
+     be useful, such as an ASN1 bio and some enhanced streaming
+     PKCS#7 code.
+
+     Extend template encode functionality so that tagging is passed
+     down to the template encoder.
+     [Steve Henson]
+
+  *) Let 'openssl req' fail if an argument to '-newkey' is not
+     recognized instead of using RSA as a default.
+     [Bodo Moeller]
+
+  *) Add support for ECC-based ciphersuites from draft-ietf-tls-ecc-01.txt.
+     As these are not official, they are not included in "ALL";
+     the "ECCdraft" ciphersuite group alias can be used to select them.
+     [Vipul Gupta and Sumit Gupta (Sun Microsystems Laboratories)]
+
+  *) Add ECDH engine support.
+     [Nils Gura and Douglas Stebila (Sun Microsystems Laboratories)]
+
+  *) Add ECDH in new directory crypto/ecdh/.
+     [Douglas Stebila (Sun Microsystems Laboratories)]
+
+  *) Let BN_rand_range() abort with an error after 100 iterations
+     without success (which indicates a broken PRNG).
+     [Bodo Moeller]
+
+  *) Change BN_mod_sqrt() so that it verifies that the input value
+     is really the square of the return value.  (Previously,
+     BN_mod_sqrt would show GIGO behaviour.)
+     [Bodo Moeller]
+
+  *) Add named elliptic curves over binary fields from X9.62, SECG,
+     and WAP/WTLS; add OIDs that were still missing.
+
+     [Sheueling Chang Shantz and Douglas Stebila
+     (Sun Microsystems Laboratories)]
+
+  *) Extend the EC library for elliptic curves over binary fields
+     (new files ec2_smpl.c, ec2_smpt.c, ec2_mult.c in crypto/ec/).
+     New EC_METHOD:
+
+          EC_GF2m_simple_method
+
+     New API functions:
+
+          EC_GROUP_new_curve_GF2m
+          EC_GROUP_set_curve_GF2m
+          EC_GROUP_get_curve_GF2m
+          EC_POINT_set_affine_coordinates_GF2m
+          EC_POINT_get_affine_coordinates_GF2m
+          EC_POINT_set_compressed_coordinates_GF2m
+
+     Point compression for binary fields is disabled by default for
+     patent reasons (compile with OPENSSL_EC_BIN_PT_COMP defined to
+     enable it).
+
+     As binary polynomials are represented as BIGNUMs, various members
+     of the EC_GROUP and EC_POINT data structures can be shared
+     between the implementations for prime fields and binary fields;
+     the above ..._GF2m functions (except for EX_GROUP_new_curve_GF2m)
+     are essentially identical to their ..._GFp counterparts.
+     (For simplicity, the '..._GFp' prefix has been dropped from
+     various internal method names.)
+
+     An internal 'field_div' method (similar to 'field_mul' and
+     'field_sqr') has been added; this is used only for binary fields.
+
+     [Sheueling Chang Shantz and Douglas Stebila
+     (Sun Microsystems Laboratories)]
+
+  *) Optionally dispatch EC_POINT_mul(), EC_POINT_precompute_mult()
+     through methods ('mul', 'precompute_mult').
+
+     The generic implementations (now internally called 'ec_wNAF_mul'
+     and 'ec_wNAF_precomputed_mult') remain the default if these
+     methods are undefined.
+
+     [Sheueling Chang Shantz and Douglas Stebila
+     (Sun Microsystems Laboratories)]
+
+  *) New function EC_GROUP_get_degree, which is defined through
+     EC_METHOD.  For curves over prime fields, this returns the bit
+     length of the modulus.
+
+     [Sheueling Chang Shantz and Douglas Stebila
+     (Sun Microsystems Laboratories)]
+
+  *) New functions EC_GROUP_dup, EC_POINT_dup.
+     (These simply call ..._new  and ..._copy).
+
+     [Sheueling Chang Shantz and Douglas Stebila
+     (Sun Microsystems Laboratories)]
+
+  *) Add binary polynomial arithmetic software in crypto/bn/bn_gf2m.c.
+     Polynomials are represented as BIGNUMs (where the sign bit is not
+     used) in the following functions [macros]:  
+
+          BN_GF2m_add
+          BN_GF2m_sub             [= BN_GF2m_add]
+          BN_GF2m_mod             [wrapper for BN_GF2m_mod_arr]
+          BN_GF2m_mod_mul         [wrapper for BN_GF2m_mod_mul_arr]
+          BN_GF2m_mod_sqr         [wrapper for BN_GF2m_mod_sqr_arr]
+          BN_GF2m_mod_inv
+          BN_GF2m_mod_exp         [wrapper for BN_GF2m_mod_exp_arr]
+          BN_GF2m_mod_sqrt        [wrapper for BN_GF2m_mod_sqrt_arr]
+          BN_GF2m_mod_solve_quad  [wrapper for BN_GF2m_mod_solve_quad_arr]
+          BN_GF2m_cmp             [= BN_ucmp]
+
+     (Note that only the 'mod' functions are actually for fields GF(2^m).
+     BN_GF2m_add() is misnomer, but this is for the sake of consistency.)
+
+     For some functions, an the irreducible polynomial defining a
+     field can be given as an 'unsigned int[]' with strictly
+     decreasing elements giving the indices of those bits that are set;
+     i.e., p[] represents the polynomial
+          f(t) = t^p[0] + t^p[1] + ... + t^p[k]
+     where
+          p[0] > p[1] > ... > p[k] = 0.
+     This applies to the following functions:
+
+          BN_GF2m_mod_arr
+          BN_GF2m_mod_mul_arr
+          BN_GF2m_mod_sqr_arr
+          BN_GF2m_mod_inv_arr        [wrapper for BN_GF2m_mod_inv]
+          BN_GF2m_mod_div_arr        [wrapper for BN_GF2m_mod_div]
+          BN_GF2m_mod_exp_arr
+          BN_GF2m_mod_sqrt_arr
+          BN_GF2m_mod_solve_quad_arr
+          BN_GF2m_poly2arr
+          BN_GF2m_arr2poly
+
+     Conversion can be performed by the following functions:
+
+          BN_GF2m_poly2arr
+          BN_GF2m_arr2poly
+
+     bntest.c has additional tests for binary polynomial arithmetic.
+
+     Two implementations for BN_GF2m_mod_div() are available.
+     The default algorithm simply uses BN_GF2m_mod_inv() and
+     BN_GF2m_mod_mul().  The alternative algorithm is compiled in only
+     if OPENSSL_SUN_GF2M_DIV is defined (patent pending; read the
+     copyright notice in crypto/bn/bn_gf2m.c before enabling it).
+
+     [Sheueling Chang Shantz and Douglas Stebila
+     (Sun Microsystems Laboratories)]
+
+  *) Add new error code 'ERR_R_DISABLED' that can be used when some
+     functionality is disabled at compile-time.
+     [Douglas Stebila <douglas.stebila@sun.com>]
+
+  *) Change default behaviour of 'openssl asn1parse' so that more
+     information is visible when viewing, e.g., a certificate:
+
+     Modify asn1_parse2 (crypto/asn1/asn1_par.c) so that in non-'dump'
+     mode the content of non-printable OCTET STRINGs is output in a
+     style similar to INTEGERs, but with '[HEX DUMP]' prepended to
+     avoid the appearance of a printable string.
+     [Nils Larsch <nla@trustcenter.de>]
+
+  *) Add 'asn1_flag' and 'asn1_form' member to EC_GROUP with access
+     functions
+          EC_GROUP_set_asn1_flag()
+          EC_GROUP_get_asn1_flag()
+          EC_GROUP_set_point_conversion_form()
+          EC_GROUP_get_point_conversion_form()
+     These control ASN1 encoding details:
+     - Curves (i.e., groups) are encoded explicitly unless asn1_flag
+       has been set to OPENSSL_EC_NAMED_CURVE.
+     - Points are encoded in uncompressed form by default; options for
+       asn1_for are as for point2oct, namely
+          POINT_CONVERSION_COMPRESSED
+          POINT_CONVERSION_UNCOMPRESSED
+          POINT_CONVERSION_HYBRID
+
+     Also add 'seed' and 'seed_len' members to EC_GROUP with access
+     functions
+          EC_GROUP_set_seed()
+          EC_GROUP_get0_seed()
+          EC_GROUP_get_seed_len()
+     This is used only for ASN1 purposes (so far).
+     [Nils Larsch <nla@trustcenter.de>]
+
+  *) Add 'field_type' member to EC_METHOD, which holds the NID
+     of the appropriate field type OID.  The new function
+     EC_METHOD_get_field_type() returns this value.
+     [Nils Larsch <nla@trustcenter.de>]
+
+  *) Add functions 
+          EC_POINT_point2bn()
+          EC_POINT_bn2point()
+          EC_POINT_point2hex()
+          EC_POINT_hex2point()
+     providing useful interfaces to EC_POINT_point2oct() and
+     EC_POINT_oct2point().
+     [Nils Larsch <nla@trustcenter.de>]
+
+  *) Change internals of the EC library so that the functions
+          EC_GROUP_set_generator()
+          EC_GROUP_get_generator()
+          EC_GROUP_get_order()
+          EC_GROUP_get_cofactor()
+     are implemented directly in crypto/ec/ec_lib.c and not dispatched
+     to methods, which would lead to unnecessary code duplication when
+     adding different types of curves.
+     [Nils Larsch <nla@trustcenter.de> with input by Bodo Moeller]
+
+  *) Implement compute_wNAF (crypto/ec/ec_mult.c) without BIGNUM
+     arithmetic, and such that modified wNAFs are generated
+     (which avoid length expansion in many cases).
+     [Bodo Moeller]
+
+  *) Add a function EC_GROUP_check_discriminant() (defined via
+     EC_METHOD) that verifies that the curve discriminant is non-zero.
+
+     Add a function EC_GROUP_check() that makes some sanity tests
+     on a EC_GROUP, its generator and order.  This includes
+     EC_GROUP_check_discriminant().
+     [Nils Larsch <nla@trustcenter.de>]
+
+  *) Add ECDSA in new directory crypto/ecdsa/.
+
+     Add applications 'openssl ecparam' and 'openssl ecdsa'
+     (these are based on 'openssl dsaparam' and 'openssl dsa').
+
+     ECDSA support is also included in various other files across the
+     library.  Most notably,
+     - 'openssl req' now has a '-newkey ecdsa:file' option;
+     - EVP_PKCS82PKEY (crypto/evp/evp_pkey.c) now can handle ECDSA;
+     - X509_PUBKEY_get (crypto/asn1/x_pubkey.c) and
+       d2i_PublicKey (crypto/asn1/d2i_pu.c) have been modified to make
+       them suitable for ECDSA where domain parameters must be
+       extracted before the specific public key;
+     - ECDSA engine support has been added.
+     [Nils Larsch <nla@trustcenter.de>]
+
+  *) Include some named elliptic curves, and add OIDs from X9.62,
+     SECG, and WAP/WTLS.  Each curve can be obtained from the new
+     function
+          EC_GROUP_new_by_curve_name(),
+     and the list of available named curves can be obtained with
+          EC_get_builtin_curves().
+     Also add a 'curve_name' member to EC_GROUP objects, which can be
+     accessed via
+         EC_GROUP_set_curve_name()
+         EC_GROUP_get_curve_name()
+     [Nils Larsch <larsch@trustcenter.de, Bodo Moeller]
+ 
+  *) Remove a few calls to bn_wexpand() in BN_sqr() (the one in there
+     was actually never needed) and in BN_mul().  The removal in BN_mul()
+     required a small change in bn_mul_part_recursive() and the addition
+     of the functions bn_cmp_part_words(), bn_sub_part_words() and
+     bn_add_part_words(), which do the same thing as bn_cmp_words(),
+     bn_sub_words() and bn_add_words() except they take arrays with
+     differing sizes.
+     [Richard Levitte]
+
+ Changes between 0.9.7l and 0.9.7m  [23 Feb 2007]
+
+  *) Cleanse PEM buffers before freeing them since they may contain 
+     sensitive data.
+     [Benjamin Bennett <ben@psc.edu>]
+
+  *) Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that
+     a ciphersuite string such as "DEFAULT:RSA" cannot enable
+     authentication-only ciphersuites.
+     [Bodo Moeller]
+
+  *) Since AES128 and AES256 share a single mask bit in the logic of
+     ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a
+     kludge to work properly if AES128 is available and AES256 isn't.
+     [Victor Duchovni]
+
+  *) Expand security boundary to match 1.1.1 module.
+     [Steve Henson]
+
+  *) Remove redundant features: hash file source, editing of test vectors
+     modify fipsld to use external fips_premain.c signature.
+     [Steve Henson]
+
+  *) New perl script mkfipsscr.pl to create shell scripts or batch files to
+     run algorithm test programs.
+     [Steve Henson]
+
+  *) Make algorithm test programs more tolerant of whitespace.
+     [Steve Henson]
+
+  *) Have SSL/TLS server implementation tolerate "mismatched" record
+     protocol version while receiving ClientHello even if the
+     ClientHello is fragmented.  (The server can't insist on the
+     particular protocol version it has chosen before the ServerHello
+     message has informed the client about his choice.)
+     [Bodo Moeller]
+
+  *) Load error codes if they are not already present instead of using a
+     static variable. This allows them to be cleanly unloaded and reloaded.
+     [Steve Henson]
+
+ Changes between 0.9.7k and 0.9.7l  [28 Sep 2006]
+
+  *) Introduce limits to prevent malicious keys being able to
+     cause a denial of service.  (CVE-2006-2940)
+     [Steve Henson, Bodo Moeller]
+
+  *) Fix ASN.1 parsing of certain invalid structures that can result
+     in a denial of service.  (CVE-2006-2937)  [Steve Henson]
+
+  *) Fix buffer overflow in SSL_get_shared_ciphers() function. 
+     (CVE-2006-3738) [Tavis Ormandy and Will Drewry, Google Security Team]
+
+  *) Fix SSL client code which could crash if connecting to a
+     malicious SSLv2 server.  (CVE-2006-4343)
+     [Tavis Ormandy and Will Drewry, Google Security Team]
+
+  *) Change ciphersuite string processing so that an explicit
+     ciphersuite selects this one ciphersuite (so that "AES256-SHA"
+     will no longer include "AES128-SHA"), and any other similar
+     ciphersuite (same bitmap) from *other* protocol versions (so that
+     "RC4-MD5" will still include both the SSL 2.0 ciphersuite and the
+     SSL 3.0/TLS 1.0 ciphersuite).  This is a backport combining
+     changes from 0.9.8b and 0.9.8d.
+     [Bodo Moeller]
+
+ Changes between 0.9.7j and 0.9.7k  [05 Sep 2006]
+
+  *) Avoid PKCS #1 v1.5 signature attack discovered by Daniel Bleichenbacher
+     (CVE-2006-4339)  [Ben Laurie and Google Security Team]
+
+  *) Change the Unix randomness entropy gathering to use poll() when
+     possible instead of select(), since the latter has some
+     undesirable limitations.
+     [Darryl Miles via Richard Levitte and Bodo Moeller]
+
+  *) Disable rogue ciphersuites:
+
+      - SSLv2 0x08 0x00 0x80 ("RC4-64-MD5")
+      - SSLv3/TLSv1 0x00 0x61 ("EXP1024-RC2-CBC-MD5")
+      - SSLv3/TLSv1 0x00 0x60 ("EXP1024-RC4-MD5")
+
+     The latter two were purportedly from
+     draft-ietf-tls-56-bit-ciphersuites-0[01].txt, but do not really
+     appear there.
+
+     Also deactive the remaining ciphersuites from
+     draft-ietf-tls-56-bit-ciphersuites-01.txt.  These are just as
+     unofficial, and the ID has long expired.
+     [Bodo Moeller]
+
+  *) Fix RSA blinding Heisenbug (problems sometimes occurred on
+     dual-core machines) and other potential thread-safety issues.
+     [Bodo Moeller]
+
+ Changes between 0.9.7i and 0.9.7j  [04 May 2006]
+
+  *) Adapt fipsld and the build system to link against the validated FIPS
+     module in FIPS mode.
+     [Steve Henson]
+
+  *) Fixes for VC++ 2005 build under Windows.
+     [Steve Henson]
+
+  *) Add new Windows build target VC-32-GMAKE for VC++. This uses GNU make 
+     from a Windows bash shell such as MSYS. It is autodetected from the
+     "config" script when run from a VC++ environment. Modify standard VC++
+     build to use fipscanister.o from the GNU make build. 
+     [Steve Henson]
+
+ Changes between 0.9.7h and 0.9.7i  [14 Oct 2005]
+
+  *) Wrapped the definition of EVP_MAX_MD_SIZE in a #ifdef OPENSSL_FIPS.
+     The value now differs depending on if you build for FIPS or not.
+     BEWARE!  A program linked with a shared FIPSed libcrypto can't be
+     safely run with a non-FIPSed libcrypto, as it may crash because of
+     the difference induced by this change.
+     [Andy Polyakov]
+
+ Changes between 0.9.7g and 0.9.7h  [11 Oct 2005]
+
+  *) Remove the functionality of SSL_OP_MSIE_SSLV2_RSA_PADDING
+     (part of SSL_OP_ALL).  This option used to disable the
+     countermeasure against man-in-the-middle protocol-version
+     rollback in the SSL 2.0 server implementation, which is a bad
+     idea.  (CVE-2005-2969)
+
+     [Bodo Moeller; problem pointed out by Yutaka Oiwa (Research Center
+     for Information Security, National Institute of Advanced Industrial
+     Science and Technology [AIST], Japan)]
+
+  *) Minimal support for X9.31 signatures and PSS padding modes. This is
+     mainly for FIPS compliance and not fully integrated at this stage.
+     [Steve Henson]
+
+  *) For DSA signing, unless DSA_FLAG_NO_EXP_CONSTTIME is set, perform
+     the exponentiation using a fixed-length exponent.  (Otherwise,
+     the information leaked through timing could expose the secret key
+     after many signatures; cf. Bleichenbacher's attack on DSA with
+     biased k.)
+     [Bodo Moeller]
+
+  *) Make a new fixed-window mod_exp implementation the default for
+     RSA, DSA, and DH private-key operations so that the sequence of
+     squares and multiplies and the memory access pattern are
+     independent of the particular secret key.  This will mitigate
+     cache-timing and potential related attacks.
+
+     BN_mod_exp_mont_consttime() is the new exponentiation implementation,
+     and this is automatically used by BN_mod_exp_mont() if the new flag
+     BN_FLG_EXP_CONSTTIME is set for the exponent.  RSA, DSA, and DH
+     will use this BN flag for private exponents unless the flag
+     RSA_FLAG_NO_EXP_CONSTTIME, DSA_FLAG_NO_EXP_CONSTTIME, or
+     DH_FLAG_NO_EXP_CONSTTIME, respectively, is set.
+
+     [Matthew D Wood (Intel Corp), with some changes by Bodo Moeller]
+
+  *) Change the client implementation for SSLv23_method() and
+     SSLv23_client_method() so that is uses the SSL 3.0/TLS 1.0
+     Client Hello message format if the SSL_OP_NO_SSLv2 option is set.
+     (Previously, the SSL 2.0 backwards compatible Client Hello
+     message format would be used even with SSL_OP_NO_SSLv2.)
+     [Bodo Moeller]
+
+  *) Add support for smime-type MIME parameter in S/MIME messages which some
+     clients need.
+     [Steve Henson]
+
+  *) New function BN_MONT_CTX_set_locked() to set montgomery parameters in
+     a threadsafe manner. Modify rsa code to use new function and add calls
+     to dsa and dh code (which had race conditions before).
+     [Steve Henson]
+
+  *) Include the fixed error library code in the C error file definitions
+     instead of fixing them up at runtime. This keeps the error code
+     structures constant.
+     [Steve Henson]
+
+ Changes between 0.9.7f and 0.9.7g  [11 Apr 2005]
+
+  [NB: OpenSSL 0.9.7h and later 0.9.7 patch levels were released after
+  OpenSSL 0.9.8.]
+
+  *) Fixes for newer kerberos headers. NB: the casts are needed because
+     the 'length' field is signed on one version and unsigned on another
+     with no (?) obvious way to tell the difference, without these VC++
+     complains. Also the "definition" of FAR (blank) is no longer included
+     nor is the error ENOMEM. KRB5_PRIVATE has to be set to 1 to pick up
+     some needed definitions.
+     [Steve Henson]
+
+  *) Undo Cygwin change.
+     [Ulf MÃ¶ller]
+
+  *) Added support for proxy certificates according to RFC 3820.
+     Because they may be a security thread to unaware applications,
+     they must be explicitly allowed in run-time.  See
+     docs/HOWTO/proxy_certificates.txt for further information.
+     [Richard Levitte]
+
+ Changes between 0.9.7e and 0.9.7f  [22 Mar 2005]
+
+  *) Use (SSL_RANDOM_VALUE - 4) bytes of pseudo random data when generating
+     server and client random values. Previously
+     (SSL_RANDOM_VALUE - sizeof(time_t)) would be used which would result in
+     less random data when sizeof(time_t) > 4 (some 64 bit platforms).
+
+     This change has negligible security impact because:
+
+     1. Server and client random values still have 24 bytes of pseudo random
+        data.
+
+     2. Server and client random values are sent in the clear in the initial
+        handshake.
+
+     3. The master secret is derived using the premaster secret (48 bytes in
+        size for static RSA ciphersuites) as well as client server and random
+        values.
+
+     The OpenSSL team would like to thank the UK NISCC for bringing this issue
+     to our attention. 
+
+     [Stephen Henson, reported by UK NISCC]
+
+  *) Use Windows randomness collection on Cygwin.
+     [Ulf MÃ¶ller]
+
+  *) Fix hang in EGD/PRNGD query when communication socket is closed
+     prematurely by EGD/PRNGD.
+     [Darren Tucker <dtucker@zip.com.au> via Lutz JÃ¤nicke, resolves #1014]
+
+  *) Prompt for pass phrases when appropriate for PKCS12 input format.
+     [Steve Henson]
+
+  *) Back-port of selected performance improvements from development
+     branch, as well as improved support for PowerPC platforms.
+     [Andy Polyakov]
+
+  *) Add lots of checks for memory allocation failure, error codes to indicate
+     failure and freeing up memory if a failure occurs.
+     [Nauticus Networks SSL Team <openssl@nauticusnet.com>, Steve Henson]
+
+  *) Add new -passin argument to dgst.
+     [Steve Henson]
+
+  *) Perform some character comparisons of different types in X509_NAME_cmp:
+     this is needed for some certificates that re-encode DNs into UTF8Strings
+     (in violation of RFC3280) and can't or won't issue name rollover
+     certificates.
+     [Steve Henson]
+
+  *) Make an explicit check during certificate validation to see that
+     the CA setting in each certificate on the chain is correct.  As a
+     side effect always do the following basic checks on extensions,
+     not just when there's an associated purpose to the check:
+
+      - if there is an unhandled critical extension (unless the user
+        has chosen to ignore this fault)
+      - if the path length has been exceeded (if one is set at all)
+      - that certain extensions fit the associated purpose (if one has
+        been given)
+     [Richard Levitte]
+
+ Changes between 0.9.7d and 0.9.7e  [25 Oct 2004]
+
+  *) Avoid a race condition when CRLs are checked in a multi threaded 
+     environment. This would happen due to the reordering of the revoked
+     entries during signature checking and serial number lookup. Now the
+     encoding is cached and the serial number sort performed under a lock.
+     Add new STACK function sk_is_sorted().
+     [Steve Henson]
+
+  *) Add Delta CRL to the extension code.
+     [Steve Henson]
+
+  *) Various fixes to s3_pkt.c so alerts are sent properly.
+     [David Holmes <d.holmes@f5.com>]
+
+  *) Reduce the chances of duplicate issuer name and serial numbers (in
+     violation of RFC3280) using the OpenSSL certificate creation utilities.
+     This is done by creating a random 64 bit value for the initial serial
+     number when a serial number file is created or when a self signed
+     certificate is created using 'openssl req -x509'. The initial serial
+     number file is created using 'openssl x509 -next_serial' in CA.pl
+     rather than being initialized to 1.
+     [Steve Henson]
+
+ Changes between 0.9.7c and 0.9.7d  [17 Mar 2004]
+
+  *) Fix null-pointer assignment in do_change_cipher_spec() revealed           
+     by using the Codenomicon TLS Test Tool (CVE-2004-0079)                    
+     [Joe Orton, Steve Henson]   
+
+  *) Fix flaw in SSL/TLS handshaking when using Kerberos ciphersuites
+     (CVE-2004-0112)
+     [Joe Orton, Steve Henson]   
+
+  *) Make it possible to have multiple active certificates with the same
+     subject in the CA index file.  This is done only if the keyword
+     'unique_subject' is set to 'no' in the main CA section (default
+     if 'CA_default') of the configuration file.  The value is saved
+     with the database itself in a separate index attribute file,
+     named like the index file with '.attr' appended to the name.
+     [Richard Levitte]
+
+  *) X509 verify fixes. Disable broken certificate workarounds when 
+     X509_V_FLAGS_X509_STRICT is set. Check CRL issuer has cRLSign set if
+     keyUsage extension present. Don't accept CRLs with unhandled critical
+     extensions: since verify currently doesn't process CRL extensions this
+     rejects a CRL with *any* critical extensions. Add new verify error codes
+     for these cases.
+     [Steve Henson]
+
+  *) When creating an OCSP nonce use an OCTET STRING inside the extnValue.
+     A clarification of RFC2560 will require the use of OCTET STRINGs and 
+     some implementations cannot handle the current raw format. Since OpenSSL
+     copies and compares OCSP nonces as opaque blobs without any attempt at
+     parsing them this should not create any compatibility issues.
+     [Steve Henson]
+
+  *) New md flag EVP_MD_CTX_FLAG_REUSE this allows md_data to be reused when
+     calling EVP_MD_CTX_copy_ex() to avoid calling OPENSSL_malloc(). Without
+     this HMAC (and other) operations are several times slower than OpenSSL
+     < 0.9.7.
+     [Steve Henson]
+
+  *) Print out GeneralizedTime and UTCTime in ASN1_STRING_print_ex().
+     [Peter Sylvester <Peter.Sylvester@EdelWeb.fr>]
+
+  *) Use the correct content when signing type "other".
+     [Steve Henson]
+
+ Changes between 0.9.7b and 0.9.7c  [30 Sep 2003]
+
+  *) Fix various bugs revealed by running the NISCC test suite:
+
+     Stop out of bounds reads in the ASN1 code when presented with
+     invalid tags (CVE-2003-0543 and CVE-2003-0544).
+     
+     Free up ASN1_TYPE correctly if ANY type is invalid (CVE-2003-0545).
+
+     If verify callback ignores invalid public key errors don't try to check
+     certificate signature with the NULL public key.
+
+     [Steve Henson]
+
+  *) New -ignore_err option in ocsp application to stop the server
+     exiting on the first error in a request.
+     [Steve Henson]
+
+  *) In ssl3_accept() (ssl/s3_srvr.c) only accept a client certificate
+     if the server requested one: as stated in TLS 1.0 and SSL 3.0
+     specifications.
+     [Steve Henson]
+
+  *) In ssl3_get_client_hello() (ssl/s3_srvr.c), tolerate additional
+     extra data after the compression methods not only for TLS 1.0
+     but also for SSL 3.0 (as required by the specification).
+     [Bodo Moeller; problem pointed out by Matthias Loepfe]
+
+  *) Change X509_certificate_type() to mark the key as exported/exportable
+     when it's 512 *bits* long, not 512 bytes.
+     [Richard Levitte]
+
+  *) Change AES_cbc_encrypt() so it outputs exact multiple of
+     blocks during encryption.
+     [Richard Levitte]
+
+  *) Various fixes to base64 BIO and non blocking I/O. On write 
+     flushes were not handled properly if the BIO retried. On read
+     data was not being buffered properly and had various logic bugs.
+     This also affects blocking I/O when the data being decoded is a
+     certain size.
+     [Steve Henson]
+
+  *) Various S/MIME bugfixes and compatibility changes:
+     output correct application/pkcs7 MIME type if
+     PKCS7_NOOLDMIMETYPE is set. Tolerate some broken signatures.
+     Output CR+LF for EOL if PKCS7_CRLFEOL is set (this makes opening
+     of files as .eml work). Correctly handle very long lines in MIME
+     parser.
+     [Steve Henson]
+
+ Changes between 0.9.7a and 0.9.7b  [10 Apr 2003]
+
+  *) Countermeasure against the Klima-Pokorny-Rosa extension of
+     Bleichbacher's attack on PKCS #1 v1.5 padding: treat
+     a protocol version number mismatch like a decryption error
+     in ssl3_get_client_key_exchange (ssl/s3_srvr.c).
+     [Bodo Moeller]
+
+  *) Turn on RSA blinding by default in the default implementation
+     to avoid a timing attack. Applications that don't want it can call
+     RSA_blinding_off() or use the new flag RSA_FLAG_NO_BLINDING.
+     They would be ill-advised to do so in most cases.
+     [Ben Laurie, Steve Henson, Geoff Thorpe, Bodo Moeller]
+
+  *) Change RSA blinding code so that it works when the PRNG is not
+     seeded (in this case, the secret RSA exponent is abused as
+     an unpredictable seed -- if it is not unpredictable, there
+     is no point in blinding anyway).  Make RSA blinding thread-safe
+     by remembering the creator's thread ID in rsa->blinding and
+     having all other threads use local one-time blinding factors
+     (this requires more computation than sharing rsa->blinding, but
+     avoids excessive locking; and if an RSA object is not shared
+     between threads, blinding will still be very fast).
+     [Bodo Moeller]
+
+  *) Fixed a typo bug that would cause ENGINE_set_default() to set an
+     ENGINE as defaults for all supported algorithms irrespective of
+     the 'flags' parameter. 'flags' is now honoured, so applications
+     should make sure they are passing it correctly.
+     [Geoff Thorpe]
+
+  *) Target "mingw" now allows native Windows code to be generated in
+     the Cygwin environment as well as with the MinGW compiler.
+     [Ulf Moeller] 
+
+ Changes between 0.9.7 and 0.9.7a  [19 Feb 2003]
+
+  *) In ssl3_get_record (ssl/s3_pkt.c), minimize information leaked
+     via timing by performing a MAC computation even if incorrect
+     block cipher padding has been found.  This is a countermeasure
+     against active attacks where the attacker has to distinguish
+     between bad padding and a MAC verification error. (CVE-2003-0078)
+
+     [Bodo Moeller; problem pointed out by Brice Canvel (EPFL),
+     Alain Hiltgen (UBS), Serge Vaudenay (EPFL), and
+     Martin Vuagnoux (EPFL, Ilion)]
+
+  *) Make the no-err option work as intended.  The intention with no-err
+     is not to have the whole error stack handling routines removed from
+     libcrypto, it's only intended to remove all the function name and
+     reason texts, thereby removing some of the footprint that may not
+     be interesting if those errors aren't displayed anyway.
+
+     NOTE: it's still possible for any application or module to have it's
+     own set of error texts inserted.  The routines are there, just not
+     used by default when no-err is given.
+     [Richard Levitte]
+
+  *) Add support for FreeBSD on IA64.
+     [dirk.meyer@dinoex.sub.org via Richard Levitte, resolves #454]
+
+  *) Adjust DES_cbc_cksum() so it returns the same value as the MIT
+     Kerberos function mit_des_cbc_cksum().  Before this change,
+     the value returned by DES_cbc_cksum() was like the one from
+     mit_des_cbc_cksum(), except the bytes were swapped.
+     [Kevin Greaney <Kevin.Greaney@hp.com> and Richard Levitte]
+
+  *) Allow an application to disable the automatic SSL chain building.
+     Before this a rather primitive chain build was always performed in
+     ssl3_output_cert_chain(): an application had no way to send the 
+     correct chain if the automatic operation produced an incorrect result.
+
+     Now the chain builder is disabled if either:
+
+     1. Extra certificates are added via SSL_CTX_add_extra_chain_cert().
+
+     2. The mode flag SSL_MODE_NO_AUTO_CHAIN is set.
+
+     The reasoning behind this is that an application would not want the
+     auto chain building to take place if extra chain certificates are
+     present and it might also want a means of sending no additional
+     certificates (for example the chain has two certificates and the
+     root is omitted).
+     [Steve Henson]
+
+  *) Add the possibility to build without the ENGINE framework.
+     [Steven Reddie <smr@essemer.com.au> via Richard Levitte]
+
+  *) Under Win32 gmtime() can return NULL: check return value in
+     OPENSSL_gmtime(). Add error code for case where gmtime() fails.
+     [Steve Henson]
+
+  *) DSA routines: under certain error conditions uninitialized BN objects
+     could be freed. Solution: make sure initialization is performed early
+     enough. (Reported and fix supplied by Ivan D Nestlerode <nestler@MIT.EDU>,
+     Nils Larsch <nla@trustcenter.de> via PR#459)
+     [Lutz Jaenicke]
+
+  *) Another fix for SSLv2 session ID handling: the session ID was incorrectly
+     checked on reconnect on the client side, therefore session resumption
+     could still fail with a "ssl session id is different" error. This
+     behaviour is masked when SSL_OP_ALL is used due to
+     SSL_OP_MICROSOFT_SESS_ID_BUG being set.
+     Behaviour observed by Crispin Flowerday <crispin@flowerday.cx> as
+     followup to PR #377.
+     [Lutz Jaenicke]
+
+  *) IA-32 assembler support enhancements: unified ELF targets, support
+     for SCO/Caldera platforms, fix for Cygwin shared build.
+     [Andy Polyakov]
+
+  *) Add support for FreeBSD on sparc64.  As a consequence, support for
+     FreeBSD on non-x86 processors is separate from x86 processors on
+     the config script, much like the NetBSD support.
+     [Richard Levitte & Kris Kennaway <kris@obsecurity.org>]
+
+ Changes between 0.9.6h and 0.9.7  [31 Dec 2002]
+
+  [NB: OpenSSL 0.9.6i and later 0.9.6 patch levels were released after
+  OpenSSL 0.9.7.]
+
+  *) Fix session ID handling in SSLv2 client code: the SERVER FINISHED
+     code (06) was taken as the first octet of the session ID and the last
+     octet was ignored consequently. As a result SSLv2 client side session
+     caching could not have worked due to the session ID mismatch between
+     client and server.
+     Behaviour observed by Crispin Flowerday <crispin@flowerday.cx> as
+     PR #377.
+     [Lutz Jaenicke]
+
+  *) Change the declaration of needed Kerberos libraries to use EX_LIBS
+     instead of the special (and badly supported) LIBKRB5.  LIBKRB5 is
+     removed entirely.
+     [Richard Levitte]
+
+  *) The hw_ncipher.c engine requires dynamic locks.  Unfortunately, it
+     seems that in spite of existing for more than a year, many application
+     author have done nothing to provide the necessary callbacks, which
+     means that this particular engine will not work properly anywhere.
+     This is a very unfortunate situation which forces us, in the name
+     of usability, to give the hw_ncipher.c a static lock, which is part
+     of libcrypto.
+     NOTE: This is for the 0.9.7 series ONLY.  This hack will never
+     appear in 0.9.8 or later.  We EXPECT application authors to have
+     dealt properly with this when 0.9.8 is released (unless we actually
+     make such changes in the libcrypto locking code that changes will
+     have to be made anyway).
+     [Richard Levitte]
+
+  *) In asn1_d2i_read_bio() repeatedly call BIO_read() until all content
+     octets have been read, EOF or an error occurs. Without this change
+     some truncated ASN1 structures will not produce an error.
+     [Steve Henson]
+
+  *) Disable Heimdal support, since it hasn't been fully implemented.
+     Still give the possibility to force the use of Heimdal, but with
+     warnings and a request that patches get sent to openssl-dev.
+     [Richard Levitte]
+
+  *) Add the VC-CE target, introduce the WINCE sysname, and add
+     INSTALL.WCE and appropriate conditionals to make it build.
+     [Steven Reddie <smr@essemer.com.au> via Richard Levitte]
+
+  *) Change the DLL names for Cygwin to cygcrypto-x.y.z.dll and
+     cygssl-x.y.z.dll, where x, y and z are the major, minor and
+     edit numbers of the version.
+     [Corinna Vinschen <vinschen@redhat.com> and Richard Levitte]
+
+  *) Introduce safe string copy and catenation functions
+     (BUF_strlcpy() and BUF_strlcat()).
+     [Ben Laurie (CHATS) and Richard Levitte]
+
+  *) Avoid using fixed-size buffers for one-line DNs.
+     [Ben Laurie (CHATS)]
+
+  *) Add BUF_MEM_grow_clean() to avoid information leakage when
+     resizing buffers containing secrets, and use where appropriate.
+     [Ben Laurie (CHATS)]
+
+  *) Avoid using fixed size buffers for configuration file location.
+     [Ben Laurie (CHATS)]
+
+  *) Avoid filename truncation for various CA files.
+     [Ben Laurie (CHATS)]
+
+  *) Use sizeof in preference to magic numbers.
+     [Ben Laurie (CHATS)]
+
+  *) Avoid filename truncation in cert requests.
+     [Ben Laurie (CHATS)]
+
+  *) Add assertions to check for (supposedly impossible) buffer
+     overflows.
+     [Ben Laurie (CHATS)]
+
+  *) Don't cache truncated DNS entries in the local cache (this could
+     potentially lead to a spoofing attack).
+     [Ben Laurie (CHATS)]
+
+  *) Fix various buffers to be large enough for hex/decimal
+     representations in a platform independent manner.
+     [Ben Laurie (CHATS)]
+
+  *) Add CRYPTO_realloc_clean() to avoid information leakage when
+     resizing buffers containing secrets, and use where appropriate.
+     [Ben Laurie (CHATS)]
+
+  *) Add BIO_indent() to avoid much slightly worrying code to do
+     indents.
+     [Ben Laurie (CHATS)]
+
+  *) Convert sprintf()/BIO_puts() to BIO_printf().
+     [Ben Laurie (CHATS)]
+
+  *) buffer_gets() could terminate with the buffer only half
+     full. Fixed.
+     [Ben Laurie (CHATS)]
+
+  *) Add assertions to prevent user-supplied crypto functions from
+     overflowing internal buffers by having large block sizes, etc.
+     [Ben Laurie (CHATS)]
+
+  *) New OPENSSL_assert() macro (similar to assert(), but enabled
+     unconditionally).
+     [Ben Laurie (CHATS)]
+
+  *) Eliminate unused copy of key in RC4.
+     [Ben Laurie (CHATS)]
+
+  *) Eliminate unused and incorrectly sized buffers for IV in pem.h.
+     [Ben Laurie (CHATS)]
+
+  *) Fix off-by-one error in EGD path.
+     [Ben Laurie (CHATS)]
+
+  *) If RANDFILE path is too long, ignore instead of truncating.
+     [Ben Laurie (CHATS)]
+
+  *) Eliminate unused and incorrectly sized X.509 structure
+     CBCParameter.
+     [Ben Laurie (CHATS)]
+
+  *) Eliminate unused and dangerous function knumber().
+     [Ben Laurie (CHATS)]
+
+  *) Eliminate unused and dangerous structure, KSSL_ERR.
+     [Ben Laurie (CHATS)]
+
+  *) Protect against overlong session ID context length in an encoded
+     session object. Since these are local, this does not appear to be
+     exploitable.
+     [Ben Laurie (CHATS)]
+
+  *) Change from security patch (see 0.9.6e below) that did not affect
+     the 0.9.6 release series:
+
+     Remote buffer overflow in SSL3 protocol - an attacker could
+     supply an oversized master key in Kerberos-enabled versions.
+     (CVE-2002-0657)
+     [Ben Laurie (CHATS)]
+
+  *) Change the SSL kerb5 codes to match RFC 2712.
+     [Richard Levitte]
+
+  *) Make -nameopt work fully for req and add -reqopt switch.
+     [Michael Bell <michael.bell@rz.hu-berlin.de>, Steve Henson]
+
+  *) The "block size" for block ciphers in CFB and OFB mode should be 1.
+     [Steve Henson, reported by Yngve Nysaeter Pettersen <yngve@opera.com>]
+
+  *) Make sure tests can be performed even if the corresponding algorithms
+     have been removed entirely.  This was also the last step to make
+     OpenSSL compilable with DJGPP under all reasonable conditions.
+     [Richard Levitte, Doug Kaufman <dkaufman@rahul.net>]
+
+  *) Add cipher selection rules COMPLEMENTOFALL and COMPLEMENTOFDEFAULT
+     to allow version independent disabling of normally unselected ciphers,
+     which may be activated as a side-effect of selecting a single cipher.
+
+     (E.g., cipher list string "RSA" enables ciphersuites that are left
+     out of "ALL" because they do not provide symmetric encryption.
+     "RSA:!COMPLEMEMENTOFALL" avoids these unsafe ciphersuites.)
+     [Lutz Jaenicke, Bodo Moeller]
+
+  *) Add appropriate support for separate platform-dependent build
+     directories.  The recommended way to make a platform-dependent
+     build directory is the following (tested on Linux), maybe with
+     some local tweaks:
+
+	# Place yourself outside of the OpenSSL source tree.  In
+	# this example, the environment variable OPENSSL_SOURCE
+	# is assumed to contain the absolute OpenSSL source directory.
+	mkdir -p objtree/"`uname -s`-`uname -r`-`uname -m`"
+	cd objtree/"`uname -s`-`uname -r`-`uname -m`"
+	(cd $OPENSSL_SOURCE; find . -type f) | while read F; do
+		mkdir -p `dirname $F`
+		ln -s $OPENSSL_SOURCE/$F $F
+	done
+
+     To be absolutely sure not to disturb the source tree, a "make clean"
+     is a good thing.  If it isn't successful, don't worry about it,
+     it probably means the source directory is very clean.
+     [Richard Levitte]
+
+  *) Make sure any ENGINE control commands make local copies of string
+     pointers passed to them whenever necessary. Otherwise it is possible
+     the caller may have overwritten (or deallocated) the original string
+     data when a later ENGINE operation tries to use the stored values.
+     [GÃ¶tz Babin-Ebell <babinebell@trustcenter.de>]
+
+  *) Improve diagnostics in file reading and command-line digests.
+     [Ben Laurie aided and abetted by Solar Designer <solar@openwall.com>]
+
+  *) Add AES modes CFB and OFB to the object database.  Correct an
+     error in AES-CFB decryption.
+     [Richard Levitte]
+
+  *) Remove most calls to EVP_CIPHER_CTX_cleanup() in evp_enc.c, this 
+     allows existing EVP_CIPHER_CTX structures to be reused after
+     calling EVP_*Final(). This behaviour is used by encryption
+     BIOs and some applications. This has the side effect that
+     applications must explicitly clean up cipher contexts with
+     EVP_CIPHER_CTX_cleanup() or they will leak memory.
+     [Steve Henson]
+
+  *) Check the values of dna and dnb in bn_mul_recursive before calling
+     bn_mul_comba (a non zero value means the a or b arrays do not contain
+     n2 elements) and fallback to bn_mul_normal if either is not zero.
+     [Steve Henson]
+
+  *) Fix escaping of non-ASCII characters when using the -subj option
+     of the "openssl req" command line tool. (Robert Joop <joop@fokus.gmd.de>)
+     [Lutz Jaenicke]
+
+  *) Make object definitions compliant to LDAP (RFC2256): SN is the short
+     form for "surname", serialNumber has no short form.
+     Use "mail" as the short name for "rfc822Mailbox" according to RFC2798;
+     therefore remove "mail" short name for "internet 7".
+     The OID for unique identifiers in X509 certificates is
+     x500UniqueIdentifier, not uniqueIdentifier.
+     Some more OID additions. (Michael Bell <michael.bell@rz.hu-berlin.de>)
+     [Lutz Jaenicke]
+
+  *) Add an "init" command to the ENGINE config module and auto initialize
+     ENGINEs. Without any "init" command the ENGINE will be initialized 
+     after all ctrl commands have been executed on it. If init=1 the 
+     ENGINE is initailized at that point (ctrls before that point are run
+     on the uninitialized ENGINE and after on the initialized one). If
+     init=0 then the ENGINE will not be iniatialized at all.
+     [Steve Henson]
+
+  *) Fix the 'app_verify_callback' interface so that the user-defined
+     argument is actually passed to the callback: In the
+     SSL_CTX_set_cert_verify_callback() prototype, the callback
+     declaration has been changed from
+          int (*cb)()
+     into
+          int (*cb)(X509_STORE_CTX *,void *);
+     in ssl_verify_cert_chain (ssl/ssl_cert.c), the call
+          i=s->ctx->app_verify_callback(&ctx)
+     has been changed into
+          i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg).
+
+     To update applications using SSL_CTX_set_cert_verify_callback(),
+     a dummy argument can be added to their callback functions.
+     [D. K. Smetters <smetters@parc.xerox.com>]
+
+  *) Added the '4758cca' ENGINE to support IBM 4758 cards.
+     [Maurice Gittens <maurice@gittens.nl>, touchups by Geoff Thorpe]
+
+  *) Add and OPENSSL_LOAD_CONF define which will cause
+     OpenSSL_add_all_algorithms() to load the openssl.cnf config file.
+     This allows older applications to transparently support certain
+     OpenSSL features: such as crypto acceleration and dynamic ENGINE loading.
+     Two new functions OPENSSL_add_all_algorithms_noconf() which will never
+     load the config file and OPENSSL_add_all_algorithms_conf() which will
+     always load it have also been added.
+     [Steve Henson]
+
+  *) Add the OFB, CFB and CTR (all with 128 bit feedback) to AES.
+     Adjust NIDs and EVP layer.
+     [Stephen Sprunk <stephen@sprunk.org> and Richard Levitte]
+
+  *) Config modules support in openssl utility.
+
+     Most commands now load modules from the config file,
+     though in a few (such as version) this isn't done 
+     because it couldn't be used for anything.
+
+     In the case of ca and req the config file used is
+     the same as the utility itself: that is the -config
+     command line option can be used to specify an
+     alternative file.
+     [Steve Henson]
+
+  *) Move default behaviour from OPENSSL_config(). If appname is NULL
+     use "openssl_conf" if filename is NULL use default openssl config file.
+     [Steve Henson]
+
+  *) Add an argument to OPENSSL_config() to allow the use of an alternative
+     config section name. Add a new flag to tolerate a missing config file
+     and move code to CONF_modules_load_file().
+     [Steve Henson]
+
+  *) Support for crypto accelerator cards from Accelerated Encryption
+     Processing, www.aep.ie.  (Use engine 'aep')
+     The support was copied from 0.9.6c [engine] and adapted/corrected
+     to work with the new engine framework.
+     [AEP Inc. and Richard Levitte]
+
+  *) Support for SureWare crypto accelerator cards from Baltimore
+     Technologies.  (Use engine 'sureware')
+     The support was copied from 0.9.6c [engine] and adapted
+     to work with the new engine framework.
+     [Richard Levitte]
+
+  *) Have the CHIL engine fork-safe (as defined by nCipher) and actually
+     make the newer ENGINE framework commands for the CHIL engine work.
+     [Toomas Kiisk <vix@cyber.ee> and Richard Levitte]
+
+  *) Make it possible to produce shared libraries on ReliantUNIX.
+     [Robert Dahlem <Robert.Dahlem@ffm2.siemens.de> via Richard Levitte]
+
+  *) Add the configuration target debug-linux-ppro.
+     Make 'openssl rsa' use the general key loading routines
+     implemented in apps.c, and make those routines able to
+     handle the key format FORMAT_NETSCAPE and the variant
+     FORMAT_IISSGC.
+     [Toomas Kiisk <vix@cyber.ee> via Richard Levitte]
+
+ *) Fix a crashbug and a logic bug in hwcrhk_load_pubkey().
+     [Toomas Kiisk <vix@cyber.ee> via Richard Levitte]
+
+  *) Add -keyform to rsautl, and document -engine.
+     [Richard Levitte, inspired by Toomas Kiisk <vix@cyber.ee>]
+
+  *) Change BIO_new_file (crypto/bio/bss_file.c) to use new
+     BIO_R_NO_SUCH_FILE error code rather than the generic
+     ERR_R_SYS_LIB error code if fopen() fails with ENOENT.
+     [Ben Laurie]
+
+  *) Add new functions
+          ERR_peek_last_error
+          ERR_peek_last_error_line
+          ERR_peek_last_error_line_data.
+     These are similar to
+          ERR_peek_error
+          ERR_peek_error_line
+          ERR_peek_error_line_data,
+     but report on the latest error recorded rather than the first one
+     still in the error queue.
+     [Ben Laurie, Bodo Moeller]
+        
+  *) default_algorithms option in ENGINE config module. This allows things
+     like:
+     default_algorithms = ALL
+     default_algorithms = RSA, DSA, RAND, CIPHERS, DIGESTS
+     [Steve Henson]
+
+  *) Preliminary ENGINE config module.
+     [Steve Henson]
+
+  *) New experimental application configuration code.
+     [Steve Henson]
+
+  *) Change the AES code to follow the same name structure as all other
+     symmetric ciphers, and behave the same way.  Move everything to
+     the directory crypto/aes, thereby obsoleting crypto/rijndael.
+     [Stephen Sprunk <stephen@sprunk.org> and Richard Levitte]
+
+  *) SECURITY: remove unsafe setjmp/signal interaction from ui_openssl.c.
+     [Ben Laurie and Theo de Raadt]
+
+  *) Add option to output public keys in req command.
+     [Massimiliano Pala madwolf@openca.org]
+
+  *) Use wNAFs in EC_POINTs_mul() for improved efficiency
+     (up to about 10% better than before for P-192 and P-224).
+     [Bodo Moeller]
+
+  *) New functions/macros
+
+          SSL_CTX_set_msg_callback(ctx, cb)
+          SSL_CTX_set_msg_callback_arg(ctx, arg)
+          SSL_set_msg_callback(ssl, cb)
+          SSL_set_msg_callback_arg(ssl, arg)
+
+     to request calling a callback function
+
+          void cb(int write_p, int version, int content_type,
+                  const void *buf, size_t len, SSL *ssl, void *arg)
+
+     whenever a protocol message has been completely received
+     (write_p == 0) or sent (write_p == 1).  Here 'version' is the
+     protocol version  according to which the SSL library interprets
+     the current protocol message (SSL2_VERSION, SSL3_VERSION, or
+     TLS1_VERSION).  'content_type' is 0 in the case of SSL 2.0, or
+     the content type as defined in the SSL 3.0/TLS 1.0 protocol
+     specification (change_cipher_spec(20), alert(21), handshake(22)).
+     'buf' and 'len' point to the actual message, 'ssl' to the
+     SSL object, and 'arg' is the application-defined value set by
+     SSL[_CTX]_set_msg_callback_arg().
+
+     'openssl s_client' and 'openssl s_server' have new '-msg' options
+     to enable a callback that displays all protocol messages.
+     [Bodo Moeller]
+
+  *) Change the shared library support so shared libraries are built as
+     soon as the corresponding static library is finished, and thereby get
+     openssl and the test programs linked against the shared library.
+     This still only happens when the keyword "shard" has been given to
+     the configuration scripts.
+
+     NOTE: shared library support is still an experimental thing, and
+     backward binary compatibility is still not guaranteed.
+     ["Maciej W. Rozycki" <macro@ds2.pg.gda.pl> and Richard Levitte]
+
+  *) Add support for Subject Information Access extension.
+     [Peter Sylvester <Peter.Sylvester@EdelWeb.fr>]
+
+  *) Make BUF_MEM_grow() behaviour more consistent: Initialise to zero
+     additional bytes when new memory had to be allocated, not just
+     when reusing an existing buffer.
+     [Bodo Moeller]
+
+  *) New command line and configuration option 'utf8' for the req command.
+     This allows field values to be specified as UTF8 strings.
+     [Steve Henson]
+
+  *) Add -multi and -mr options to "openssl speed" - giving multiple parallel
+     runs for the former and machine-readable output for the latter.
+     [Ben Laurie]
+
+  *) Add '-noemailDN' option to 'openssl ca'.  This prevents inclusion
+     of the e-mail address in the DN (i.e., it will go into a certificate
+     extension only).  The new configuration file option 'email_in_dn = no'
+     has the same effect.
+     [Massimiliano Pala madwolf@openca.org]
+
+  *) Change all functions with names starting with des_ to be starting
+     with DES_ instead.  Add wrappers that are compatible with libdes,
+     but are named _ossl_old_des_*.  Finally, add macros that map the
+     des_* symbols to the corresponding _ossl_old_des_* if libdes
+     compatibility is desired.  If OpenSSL 0.9.6c compatibility is
+     desired, the des_* symbols will be mapped to DES_*, with one
+     exception.
+
+     Since we provide two compatibility mappings, the user needs to
+     define the macro OPENSSL_DES_LIBDES_COMPATIBILITY if libdes
+     compatibility is desired.  The default (i.e., when that macro
+     isn't defined) is OpenSSL 0.9.6c compatibility.
+
+     There are also macros that enable and disable the support of old
+     des functions altogether.  Those are OPENSSL_ENABLE_OLD_DES_SUPPORT
+     and OPENSSL_DISABLE_OLD_DES_SUPPORT.  If none or both of those
+     are defined, the default will apply: to support the old des routines.
+
+     In either case, one must include openssl/des.h to get the correct
+     definitions.  Do not try to just include openssl/des_old.h, that
+     won't work.
+
+     NOTE: This is a major break of an old API into a new one.  Software
+     authors are encouraged to switch to the DES_ style functions.  Some
+     time in the future, des_old.h and the libdes compatibility functions
+     will be disable (i.e. OPENSSL_DISABLE_OLD_DES_SUPPORT will be the
+     default), and then completely removed.
+     [Richard Levitte]
+
+  *) Test for certificates which contain unsupported critical extensions.
+     If such a certificate is found during a verify operation it is 
+     rejected by default: this behaviour can be overridden by either
+     handling the new error X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION or
+     by setting the verify flag X509_V_FLAG_IGNORE_CRITICAL. A new function
+     X509_supported_extension() has also been added which returns 1 if a
+     particular extension is supported.
+     [Steve Henson]
+
+  *) Modify the behaviour of EVP cipher functions in similar way to digests
+     to retain compatibility with existing code.
+     [Steve Henson]
+
+  *) Modify the behaviour of EVP_DigestInit() and EVP_DigestFinal() to retain
+     compatibility with existing code. In particular the 'ctx' parameter does
+     not have to be to be initialized before the call to EVP_DigestInit() and
+     it is tidied up after a call to EVP_DigestFinal(). New function
+     EVP_DigestFinal_ex() which does not tidy up the ctx. Similarly function
+     EVP_MD_CTX_copy() changed to not require the destination to be
+     initialized valid and new function EVP_MD_CTX_copy_ex() added which
+     requires the destination to be valid.
+
+     Modify all the OpenSSL digest calls to use EVP_DigestInit_ex(),
+     EVP_DigestFinal_ex() and EVP_MD_CTX_copy_ex().
+     [Steve Henson]
+
+  *) Change ssl3_get_message (ssl/s3_both.c) and the functions using it
+     so that complete 'Handshake' protocol structures are kept in memory
+     instead of overwriting 'msg_type' and 'length' with 'body' data.
+     [Bodo Moeller]
+
+  *) Add an implementation of SSL_add_dir_cert_subjects_to_stack for Win32.
+     [Massimo Santin via Richard Levitte]
+
+  *) Major restructuring to the underlying ENGINE code. This includes
+     reduction of linker bloat, separation of pure "ENGINE" manipulation
+     (initialisation, etc) from functionality dealing with implementations
+     of specific crypto iterfaces. This change also introduces integrated
+     support for symmetric ciphers and digest implementations - so ENGINEs
+     can now accelerate these by providing EVP_CIPHER and EVP_MD
+     implementations of their own. This is detailed in crypto/engine/README
+     as it couldn't be adequately described here. However, there are a few
+     API changes worth noting - some RSA, DSA, DH, and RAND functions that
+     were changed in the original introduction of ENGINE code have now
+     reverted back - the hooking from this code to ENGINE is now a good
+     deal more passive and at run-time, operations deal directly with
+     RSA_METHODs, DSA_METHODs (etc) as they did before, rather than
+     dereferencing through an ENGINE pointer any more. Also, the ENGINE
+     functions dealing with BN_MOD_EXP[_CRT] handlers have been removed -
+     they were not being used by the framework as there is no concept of a
+     BIGNUM_METHOD and they could not be generalised to the new
+     'ENGINE_TABLE' mechanism that underlies the new code. Similarly,
+     ENGINE_cpy() has been removed as it cannot be consistently defined in
+     the new code.
+     [Geoff Thorpe]
+
+  *) Change ASN1_GENERALIZEDTIME_check() to allow fractional seconds.
+     [Steve Henson]
+
+  *) Change mkdef.pl to sort symbols that get the same entry number,
+     and make sure the automatically generated functions ERR_load_*
+     become part of libeay.num as well.
+     [Richard Levitte]
+
+  *) New function SSL_renegotiate_pending().  This returns true once
+     renegotiation has been requested (either SSL_renegotiate() call
+     or HelloRequest/ClientHello received from the peer) and becomes
+     false once a handshake has been completed.
+     (For servers, SSL_renegotiate() followed by SSL_do_handshake()
+     sends a HelloRequest, but does not ensure that a handshake takes
+     place.  SSL_renegotiate_pending() is useful for checking if the
+     client has followed the request.)
+     [Bodo Moeller]
+
+  *) New SSL option SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION.
+     By default, clients may request session resumption even during
+     renegotiation (if session ID contexts permit); with this option,
+     session resumption is possible only in the first handshake.
+
+     SSL_OP_ALL is now 0x00000FFFL instead of 0x000FFFFFL.  This makes
+     more bits available for options that should not be part of
+     SSL_OP_ALL (such as SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION).
+     [Bodo Moeller]
+
+  *) Add some demos for certificate and certificate request creation.
+     [Steve Henson]
+
+  *) Make maximum certificate chain size accepted from the peer application
+     settable (SSL*_get/set_max_cert_list()), as proposed by
+     "Douglas E. Engert" <deengert@anl.gov>.
+     [Lutz Jaenicke]
+
+  *) Add support for shared libraries for Unixware-7
+     (Boyd Lynn Gerber <gerberb@zenez.com>).
+     [Lutz Jaenicke]
+
+  *) Add a "destroy" handler to ENGINEs that allows structural cleanup to
+     be done prior to destruction. Use this to unload error strings from
+     ENGINEs that load their own error strings. NB: This adds two new API
+     functions to "get" and "set" this destroy handler in an ENGINE.
+     [Geoff Thorpe]
+
+  *) Alter all existing ENGINE implementations (except "openssl" and
+     "openbsd") to dynamically instantiate their own error strings. This
+     makes them more flexible to be built both as statically-linked ENGINEs
+     and self-contained shared-libraries loadable via the "dynamic" ENGINE.
+     Also, add stub code to each that makes building them as self-contained
+     shared-libraries easier (see README.ENGINE).
+     [Geoff Thorpe]
+
+  *) Add a "dynamic" ENGINE that provides a mechanism for binding ENGINE
+     implementations into applications that are completely implemented in
+     self-contained shared-libraries. The "dynamic" ENGINE exposes control
+     commands that can be used to configure what shared-library to load and
+     to control aspects of the way it is handled. Also, made an update to
+     the README.ENGINE file that brings its information up-to-date and
+     provides some information and instructions on the "dynamic" ENGINE
+     (ie. how to use it, how to build "dynamic"-loadable ENGINEs, etc).
+     [Geoff Thorpe]
+
+  *) Make it possible to unload ranges of ERR strings with a new
+     "ERR_unload_strings" function.
+     [Geoff Thorpe]
+
+  *) Add a copy() function to EVP_MD.
+     [Ben Laurie]
+
+  *) Make EVP_MD routines take a context pointer instead of just the
+     md_data void pointer.
+     [Ben Laurie]
+
+  *) Add flags to EVP_MD and EVP_MD_CTX. EVP_MD_FLAG_ONESHOT indicates
+     that the digest can only process a single chunk of data
+     (typically because it is provided by a piece of
+     hardware). EVP_MD_CTX_FLAG_ONESHOT indicates that the application
+     is only going to provide a single chunk of data, and hence the
+     framework needn't accumulate the data for oneshot drivers.
+     [Ben Laurie]
+
+  *) As with "ERR", make it possible to replace the underlying "ex_data"
+     functions. This change also alters the storage and management of global
+     ex_data state - it's now all inside ex_data.c and all "class" code (eg.
+     RSA, BIO, SSL_CTX, etc) no longer stores its own STACKS and per-class
+     index counters. The API functions that use this state have been changed
+     to take a "class_index" rather than pointers to the class's local STACK
+     and counter, and there is now an API function to dynamically create new
+     classes. This centralisation allows us to (a) plug a lot of the
+     thread-safety problems that existed, and (b) makes it possible to clean
+     up all allocated state using "CRYPTO_cleanup_all_ex_data()". W.r.t. (b)
+     such data would previously have always leaked in application code and
+     workarounds were in place to make the memory debugging turn a blind eye
+     to it. Application code that doesn't use this new function will still
+     leak as before, but their memory debugging output will announce it now
+     rather than letting it slide.
+
+     Besides the addition of CRYPTO_cleanup_all_ex_data(), another API change
+     induced by the "ex_data" overhaul is that X509_STORE_CTX_init() now
+     has a return value to indicate success or failure.
+     [Geoff Thorpe]
+
+  *) Make it possible to replace the underlying "ERR" functions such that the
+     global state (2 LHASH tables and 2 locks) is only used by the "default"
+     implementation. This change also adds two functions to "get" and "set"
+     the implementation prior to it being automatically set the first time
+     any other ERR function takes place. Ie. an application can call "get",
+     pass the return value to a module it has just loaded, and that module
+     can call its own "set" function using that value. This means the
+     module's "ERR" operations will use (and modify) the error state in the
+     application and not in its own statically linked copy of OpenSSL code.
+     [Geoff Thorpe]
+
+  *) Give DH, DSA, and RSA types their own "**_up_ref()" function to increment
+     reference counts. This performs normal REF_PRINT/REF_CHECK macros on
+     the operation, and provides a more encapsulated way for external code
+     (crypto/evp/ and ssl/) to do this. Also changed the evp and ssl code
+     to use these functions rather than manually incrementing the counts.
+
+     Also rename "DSO_up()" function to more descriptive "DSO_up_ref()".
+     [Geoff Thorpe]
+
+  *) Add EVP test program.
+     [Ben Laurie]
+
+  *) Add symmetric cipher support to ENGINE. Expect the API to change!
+     [Ben Laurie]
+
+  *) New CRL functions: X509_CRL_set_version(), X509_CRL_set_issuer_name()
+     X509_CRL_set_lastUpdate(), X509_CRL_set_nextUpdate(), X509_CRL_sort(),
+     X509_REVOKED_set_serialNumber(), and X509_REVOKED_set_revocationDate().
+     These allow a CRL to be built without having to access X509_CRL fields
+     directly. Modify 'ca' application to use new functions.
+     [Steve Henson]
+
+  *) Move SSL_OP_TLS_ROLLBACK_BUG out of the SSL_OP_ALL list of recommended
+     bug workarounds. Rollback attack detection is a security feature.
+     The problem will only arise on OpenSSL servers when TLSv1 is not
+     available (sslv3_server_method() or SSL_OP_NO_TLSv1).
+     Software authors not wanting to support TLSv1 will have special reasons
+     for their choice and can explicitly enable this option.
+     [Bodo Moeller, Lutz Jaenicke]
+
+  *) Rationalise EVP so it can be extended: don't include a union of
+     cipher/digest structures, add init/cleanup functions for EVP_MD_CTX
+     (similar to those existing for EVP_CIPHER_CTX).
+     Usage example:
+
+         EVP_MD_CTX md;
+
+         EVP_MD_CTX_init(&md);             /* new function call */
+         EVP_DigestInit(&md, EVP_sha1());
+         EVP_DigestUpdate(&md, in, len);
+         EVP_DigestFinal(&md, out, NULL);
+         EVP_MD_CTX_cleanup(&md);          /* new function call */
+
+     [Ben Laurie]
+
+  *) Make DES key schedule conform to the usual scheme, as well as
+     correcting its structure. This means that calls to DES functions
+     now have to pass a pointer to a des_key_schedule instead of a
+     plain des_key_schedule (which was actually always a pointer
+     anyway): E.g.,
+
+         des_key_schedule ks;
+
+	 des_set_key_checked(..., &ks);
+	 des_ncbc_encrypt(..., &ks, ...);
+
+     (Note that a later change renames 'des_...' into 'DES_...'.)
+     [Ben Laurie]
+
+  *) Initial reduction of linker bloat: the use of some functions, such as
+     PEM causes large amounts of unused functions to be linked in due to
+     poor organisation. For example pem_all.c contains every PEM function
+     which has a knock on effect of linking in large amounts of (unused)
+     ASN1 code. Grouping together similar functions and splitting unrelated
+     functions prevents this.
+     [Steve Henson]
+
+  *) Cleanup of EVP macros.
+     [Ben Laurie]
+
+  *) Change historical references to {NID,SN,LN}_des_ede and ede3 to add the
+     correct _ecb suffix.
+     [Ben Laurie]
+
+  *) Add initial OCSP responder support to ocsp application. The
+     revocation information is handled using the text based index
+     use by the ca application. The responder can either handle
+     requests generated internally, supplied in files (for example
+     via a CGI script) or using an internal minimal server.
+     [Steve Henson]
+
+  *) Add configuration choices to get zlib compression for TLS.
+     [Richard Levitte]
+
+  *) Changes to Kerberos SSL for RFC 2712 compliance:
+     1.  Implemented real KerberosWrapper, instead of just using
+         KRB5 AP_REQ message.  [Thanks to Simon Wilkinson <sxw@sxw.org.uk>]
+     2.  Implemented optional authenticator field of KerberosWrapper.
+
+     Added openssl-style ASN.1 macros for Kerberos ticket, ap_req,
+     and authenticator structs; see crypto/krb5/.
+
+     Generalized Kerberos calls to support multiple Kerberos libraries.
+     [Vern Staats <staatsvr@asc.hpc.mil>,
+      Jeffrey Altman <jaltman@columbia.edu>
+      via Richard Levitte]
+
+  *) Cause 'openssl speed' to use fully hard-coded DSA keys as it
+     already does with RSA. testdsa.h now has 'priv_key/pub_key'
+     values for each of the key sizes rather than having just
+     parameters (and 'speed' generating keys each time).
+     [Geoff Thorpe]
+
+  *) Speed up EVP routines.
+     Before:
+encrypt
+type              8 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
+des-cbc           4408.85k     5560.51k     5778.46k     5862.20k     5825.16k
+des-cbc           4389.55k     5571.17k     5792.23k     5846.91k     5832.11k
+des-cbc           4394.32k     5575.92k     5807.44k     5848.37k     5841.30k
+decrypt
+des-cbc           3482.66k     5069.49k     5496.39k     5614.16k     5639.28k
+des-cbc           3480.74k     5068.76k     5510.34k     5609.87k     5635.52k
+des-cbc           3483.72k     5067.62k     5504.60k     5708.01k     5724.80k
+     After:
+encrypt
+des-cbc           4660.16k     5650.19k     5807.19k     5827.13k     5783.32k
+decrypt
+des-cbc           3624.96k     5258.21k     5530.91k     5624.30k     5628.26k
+     [Ben Laurie]
+
+  *) Added the OS2-EMX target.
+     ["Brian Havard" <brianh@kheldar.apana.org.au> and Richard Levitte]
+
+  *) Rewrite apps to use NCONF routines instead of the old CONF. New functions
+     to support NCONF routines in extension code. New function CONF_set_nconf()
+     to allow functions which take an NCONF to also handle the old LHASH
+     structure: this means that the old CONF compatible routines can be
+     retained (in particular wrt extensions) without having to duplicate the
+     code. New function X509V3_add_ext_nconf_sk to add extensions to a stack.
+     [Steve Henson]
+
+  *) Enhance the general user interface with mechanisms for inner control
+     and with possibilities to have yes/no kind of prompts.
+     [Richard Levitte]
+
+  *) Change all calls to low level digest routines in the library and
+     applications to use EVP. Add missing calls to HMAC_cleanup() and
+     don't assume HMAC_CTX can be copied using memcpy().
+     [Verdon Walker <VWalker@novell.com>, Steve Henson]
+
+  *) Add the possibility to control engines through control names but with
+     arbitrary arguments instead of just a string.
+     Change the key loaders to take a UI_METHOD instead of a callback
+     function pointer.  NOTE: this breaks binary compatibility with earlier
+     versions of OpenSSL [engine].
+     Adapt the nCipher code for these new conditions and add a card insertion
+     callback.
+     [Richard Levitte]
+
+  *) Enhance the general user interface with mechanisms to better support
+     dialog box interfaces, application-defined prompts, the possibility
+     to use defaults (for example default passwords from somewhere else)
+     and interrupts/cancellations.
+     [Richard Levitte]
+
+  *) Tidy up PKCS#12 attribute handling. Add support for the CSP name
+     attribute in PKCS#12 files, add new -CSP option to pkcs12 utility.
+     [Steve Henson]
+
+  *) Fix a memory leak in 'sk_dup()' in the case reallocation fails. (Also
+     tidy up some unnecessarily weird code in 'sk_new()').
+     [Geoff, reported by Diego Tartara <dtartara@novamens.com>]
+
+  *) Change the key loading routines for ENGINEs to use the same kind
+     callback (pem_password_cb) as all other routines that need this
+     kind of callback.
+     [Richard Levitte]
+
+  *) Increase ENTROPY_NEEDED to 32 bytes, as Rijndael can operate with
+     256 bit (=32 byte) keys. Of course seeding with more entropy bytes
+     than this minimum value is recommended.
+     [Lutz Jaenicke]
+
+  *) New random seeder for OpenVMS, using the system process statistics
+     that are easily reachable.
+     [Richard Levitte]
+
+  *) Windows apparently can't transparently handle global
+     variables defined in DLLs. Initialisations such as:
+
+        const ASN1_ITEM *it = &ASN1_INTEGER_it;
+
+     won't compile. This is used by the any applications that need to
+     declare their own ASN1 modules. This was fixed by adding the option
+     EXPORT_VAR_AS_FN to all Win32 platforms, although this isn't strictly
+     needed for static libraries under Win32.
+     [Steve Henson]
+
+  *) New functions X509_PURPOSE_set() and X509_TRUST_set() to handle
+     setting of purpose and trust fields. New X509_STORE trust and
+     purpose functions and tidy up setting in other SSL functions.
+     [Steve Henson]
+
+  *) Add copies of X509_STORE_CTX fields and callbacks to X509_STORE
+     structure. These are inherited by X509_STORE_CTX when it is 
+     initialised. This allows various defaults to be set in the
+     X509_STORE structure (such as flags for CRL checking and custom
+     purpose or trust settings) for functions which only use X509_STORE_CTX
+     internally such as S/MIME.
+
+     Modify X509_STORE_CTX_purpose_inherit() so it only sets purposes and
+     trust settings if they are not set in X509_STORE. This allows X509_STORE
+     purposes and trust (in S/MIME for example) to override any set by default.
+
+     Add command line options for CRL checking to smime, s_client and s_server
+     applications.
+     [Steve Henson]
+
+  *) Initial CRL based revocation checking. If the CRL checking flag(s)
+     are set then the CRL is looked up in the X509_STORE structure and
+     its validity and signature checked, then if the certificate is found
+     in the CRL the verify fails with a revoked error.
+
+     Various new CRL related callbacks added to X509_STORE_CTX structure.
+
+     Command line options added to 'verify' application to support this.
+
+     This needs some additional work, such as being able to handle multiple
+     CRLs with different times, extension based lookup (rather than just
+     by subject name) and ultimately more complete V2 CRL extension
+     handling.
+     [Steve Henson]
+
+  *) Add a general user interface API (crypto/ui/).  This is designed
+     to replace things like des_read_password and friends (backward
+     compatibility functions using this new API are provided).
+     The purpose is to remove prompting functions from the DES code
+     section as well as provide for prompting through dialog boxes in
+     a window system and the like.
+     [Richard Levitte]
+
+  *) Add "ex_data" support to ENGINE so implementations can add state at a
+     per-structure level rather than having to store it globally.
+     [Geoff]
+
+  *) Make it possible for ENGINE structures to be copied when retrieved by
+     ENGINE_by_id() if the ENGINE specifies a new flag: ENGINE_FLAGS_BY_ID_COPY.
+     This causes the "original" ENGINE structure to act like a template,
+     analogous to the RSA vs. RSA_METHOD type of separation. Because of this
+     operational state can be localised to each ENGINE structure, despite the
+     fact they all share the same "methods". New ENGINE structures returned in
+     this case have no functional references and the return value is the single
+     structural reference. This matches the single structural reference returned
+     by ENGINE_by_id() normally, when it is incremented on the pre-existing
+     ENGINE structure.
+     [Geoff]
+
+  *) Fix ASN1 decoder when decoding type ANY and V_ASN1_OTHER: since this
+     needs to match any other type at all we need to manually clear the
+     tag cache.
+     [Steve Henson]
+
+  *) Changes to the "openssl engine" utility to include;
+     - verbosity levels ('-v', '-vv', and '-vvv') that provide information
+       about an ENGINE's available control commands.
+     - executing control commands from command line arguments using the
+       '-pre' and '-post' switches. '-post' is only used if '-t' is
+       specified and the ENGINE is successfully initialised. The syntax for
+       the individual commands are colon-separated, for example;
+	 openssl engine chil -pre FORK_CHECK:0 -pre SO_PATH:/lib/test.so
+     [Geoff]
+
+  *) New dynamic control command support for ENGINEs. ENGINEs can now
+     declare their own commands (numbers), names (strings), descriptions,
+     and input types for run-time discovery by calling applications. A
+     subset of these commands are implicitly classed as "executable"
+     depending on their input type, and only these can be invoked through
+     the new string-based API function ENGINE_ctrl_cmd_string(). (Eg. this
+     can be based on user input, config files, etc). The distinction is
+     that "executable" commands cannot return anything other than a boolean
+     result and can only support numeric or string input, whereas some
+     discoverable commands may only be for direct use through
+     ENGINE_ctrl(), eg. supporting the exchange of binary data, function
+     pointers, or other custom uses. The "executable" commands are to
+     support parameterisations of ENGINE behaviour that can be
+     unambiguously defined by ENGINEs and used consistently across any
+     OpenSSL-based application. Commands have been added to all the
+     existing hardware-supporting ENGINEs, noticeably "SO_PATH" to allow
+     control over shared-library paths without source code alterations.
+     [Geoff]
+
+  *) Changed all ENGINE implementations to dynamically allocate their
+     ENGINEs rather than declaring them statically. Apart from this being
+     necessary with the removal of the ENGINE_FLAGS_MALLOCED distinction,
+     this also allows the implementations to compile without using the
+     internal engine_int.h header.
+     [Geoff]
+
+  *) Minor adjustment to "rand" code. RAND_get_rand_method() now returns a
+     'const' value. Any code that should be able to modify a RAND_METHOD
+     should already have non-const pointers to it (ie. they should only
+     modify their own ones).
+     [Geoff]
+
+  *) Made a variety of little tweaks to the ENGINE code.
+     - "atalla" and "ubsec" string definitions were moved from header files
+       to C code. "nuron" string definitions were placed in variables
+       rather than hard-coded - allowing parameterisation of these values
+       later on via ctrl() commands.
+     - Removed unused "#if 0"'d code.
+     - Fixed engine list iteration code so it uses ENGINE_free() to release
+       structural references.
+     - Constified the RAND_METHOD element of ENGINE structures.
+     - Constified various get/set functions as appropriate and added
+       missing functions (including a catch-all ENGINE_cpy that duplicates
+       all ENGINE values onto a new ENGINE except reference counts/state).
+     - Removed NULL parameter checks in get/set functions. Setting a method
+       or function to NULL is a way of cancelling out a previously set
+       value.  Passing a NULL ENGINE parameter is just plain stupid anyway
+       and doesn't justify the extra error symbols and code.
+     - Deprecate the ENGINE_FLAGS_MALLOCED define and move the area for
+       flags from engine_int.h to engine.h.
+     - Changed prototypes for ENGINE handler functions (init(), finish(),
+       ctrl(), key-load functions, etc) to take an (ENGINE*) parameter.
+     [Geoff]
+
+  *) Implement binary inversion algorithm for BN_mod_inverse in addition
+     to the algorithm using long division.  The binary algorithm can be
+     used only if the modulus is odd.  On 32-bit systems, it is faster
+     only for relatively small moduli (roughly 20-30% for 128-bit moduli,
+     roughly 5-15% for 256-bit moduli), so we use it only for moduli
+     up to 450 bits.  In 64-bit environments, the binary algorithm
+     appears to be advantageous for much longer moduli; here we use it
+     for moduli up to 2048 bits.
+     [Bodo Moeller]
+
+  *) Rewrite CHOICE field setting in ASN1_item_ex_d2i(). The old code
+     could not support the combine flag in choice fields.
+     [Steve Henson]
+
+  *) Add a 'copy_extensions' option to the 'ca' utility. This copies
+     extensions from a certificate request to the certificate.
+     [Steve Henson]
+
+  *) Allow multiple 'certopt' and 'nameopt' options to be separated
+     by commas. Add 'namopt' and 'certopt' options to the 'ca' config
+     file: this allows the display of the certificate about to be
+     signed to be customised, to allow certain fields to be included
+     or excluded and extension details. The old system didn't display
+     multicharacter strings properly, omitted fields not in the policy
+     and couldn't display additional details such as extensions.
+     [Steve Henson]
+
+  *) Function EC_POINTs_mul for multiple scalar multiplication
+     of an arbitrary number of elliptic curve points
+          \sum scalars[i]*points[i],
+     optionally including the generator defined for the EC_GROUP:
+          scalar*generator +  \sum scalars[i]*points[i].
+
+     EC_POINT_mul is a simple wrapper function for the typical case
+     that the point list has just one item (besides the optional
+     generator).
+     [Bodo Moeller]
+
+  *) First EC_METHODs for curves over GF(p):
+
+     EC_GFp_simple_method() uses the basic BN_mod_mul and BN_mod_sqr
+     operations and provides various method functions that can also
+     operate with faster implementations of modular arithmetic.     
+
+     EC_GFp_mont_method() reuses most functions that are part of
+     EC_GFp_simple_method, but uses Montgomery arithmetic.
+
+     [Bodo Moeller; point addition and point doubling
+     implementation directly derived from source code provided by
+     Lenka Fibikova <fibikova@exp-math.uni-essen.de>]
+
+  *) Framework for elliptic curves (crypto/ec/ec.h, crypto/ec/ec_lcl.h,
+     crypto/ec/ec_lib.c):
+
+     Curves are EC_GROUP objects (with an optional group generator)
+     based on EC_METHODs that are built into the library.
+
+     Points are EC_POINT objects based on EC_GROUP objects.
+
+     Most of the framework would be able to handle curves over arbitrary
+     finite fields, but as there are no obvious types for fields other
+     than GF(p), some functions are limited to that for now.
+     [Bodo Moeller]
+
+  *) Add the -HTTP option to s_server.  It is similar to -WWW, but requires
+     that the file contains a complete HTTP response.
+     [Richard Levitte]
+
+  *) Add the ec directory to mkdef.pl and mkfiles.pl. In mkdef.pl
+     change the def and num file printf format specifier from "%-40sXXX"
+     to "%-39s XXX". The latter will always guarantee a space after the
+     field while the former will cause them to run together if the field
+     is 40 of more characters long.
+     [Steve Henson]
+
+  *) Constify the cipher and digest 'method' functions and structures
+     and modify related functions to take constant EVP_MD and EVP_CIPHER
+     pointers.
+     [Steve Henson]
+
+  *) Hide BN_CTX structure details in bn_lcl.h instead of publishing them
+     in <openssl/bn.h>.  Also further increase BN_CTX_NUM to 32.
+     [Bodo Moeller]
+
+  *) Modify EVP_Digest*() routines so they now return values. Although the
+     internal software routines can never fail additional hardware versions
+     might.
+     [Steve Henson]
+
+  *) Clean up crypto/err/err.h and change some error codes to avoid conflicts:
+
+     Previously ERR_R_FATAL was too small and coincided with ERR_LIB_PKCS7
+     (= ERR_R_PKCS7_LIB); it is now 64 instead of 32.
+
+     ASN1 error codes
+          ERR_R_NESTED_ASN1_ERROR
+          ...
+          ERR_R_MISSING_ASN1_EOS
+     were 4 .. 9, conflicting with
+          ERR_LIB_RSA (= ERR_R_RSA_LIB)
+          ...
+          ERR_LIB_PEM (= ERR_R_PEM_LIB).
+     They are now 58 .. 63 (i.e., just below ERR_R_FATAL).
+
+     Add new error code 'ERR_R_INTERNAL_ERROR'.
+     [Bodo Moeller]
+
+  *) Don't overuse locks in crypto/err/err.c: For data retrieval, CRYPTO_r_lock
+     suffices.
+     [Bodo Moeller]
+
+  *) New option '-subj arg' for 'openssl req' and 'openssl ca'.  This
+     sets the subject name for a new request or supersedes the
+     subject name in a given request. Formats that can be parsed are
+          'CN=Some Name, OU=myOU, C=IT'
+     and
+          'CN=Some Name/OU=myOU/C=IT'.
+
+     Add options '-batch' and '-verbose' to 'openssl req'.
+     [Massimiliano Pala <madwolf@hackmasters.net>]
+
+  *) Introduce the possibility to access global variables through
+     functions on platform were that's the best way to handle exporting
+     global variables in shared libraries.  To enable this functionality,
+     one must configure with "EXPORT_VAR_AS_FN" or defined the C macro
+     "OPENSSL_EXPORT_VAR_AS_FUNCTION" in crypto/opensslconf.h (the latter
+     is normally done by Configure or something similar).
+
+     To implement a global variable, use the macro OPENSSL_IMPLEMENT_GLOBAL
+     in the source file (foo.c) like this:
+
+	OPENSSL_IMPLEMENT_GLOBAL(int,foo)=1;
+	OPENSSL_IMPLEMENT_GLOBAL(double,bar);
+
+     To declare a global variable, use the macros OPENSSL_DECLARE_GLOBAL
+     and OPENSSL_GLOBAL_REF in the header file (foo.h) like this:
+
+	OPENSSL_DECLARE_GLOBAL(int,foo);
+	#define foo OPENSSL_GLOBAL_REF(foo)
+	OPENSSL_DECLARE_GLOBAL(double,bar);
+	#define bar OPENSSL_GLOBAL_REF(bar)
+
+     The #defines are very important, and therefore so is including the
+     header file everywhere where the defined globals are used.
+
+     The macro OPENSSL_EXPORT_VAR_AS_FUNCTION also affects the definition
+     of ASN.1 items, but that structure is a bit different.
+
+     The largest change is in util/mkdef.pl which has been enhanced with
+     better and easier to understand logic to choose which symbols should
+     go into the Windows .def files as well as a number of fixes and code
+     cleanup (among others, algorithm keywords are now sorted
+     lexicographically to avoid constant rewrites).
+     [Richard Levitte]
+
+  *) In BN_div() keep a copy of the sign of 'num' before writing the
+     result to 'rm' because if rm==num the value will be overwritten
+     and produce the wrong result if 'num' is negative: this caused
+     problems with BN_mod() and BN_nnmod().
+     [Steve Henson]
+
+  *) Function OCSP_request_verify(). This checks the signature on an
+     OCSP request and verifies the signer certificate. The signer
+     certificate is just checked for a generic purpose and OCSP request
+     trust settings.
+     [Steve Henson]
+
+  *) Add OCSP_check_validity() function to check the validity of OCSP
+     responses. OCSP responses are prepared in real time and may only
+     be a few seconds old. Simply checking that the current time lies
+     between thisUpdate and nextUpdate max reject otherwise valid responses
+     caused by either OCSP responder or client clock inaccuracy. Instead
+     we allow thisUpdate and nextUpdate to fall within a certain period of
+     the current time. The age of the response can also optionally be
+     checked. Two new options -validity_period and -status_age added to
+     ocsp utility.
+     [Steve Henson]
+
+  *) If signature or public key algorithm is unrecognized print out its
+     OID rather that just UNKNOWN.
+     [Steve Henson]
+
+  *) Change OCSP_cert_to_id() to tolerate a NULL subject certificate and
+     OCSP_cert_id_new() a NULL serialNumber. This allows a partial certificate
+     ID to be generated from the issuer certificate alone which can then be
+     passed to OCSP_id_issuer_cmp().
+     [Steve Henson]
+
+  *) New compilation option ASN1_ITEM_FUNCTIONS. This causes the new
+     ASN1 modules to export functions returning ASN1_ITEM pointers
+     instead of the ASN1_ITEM structures themselves. This adds several
+     new macros which allow the underlying ASN1 function/structure to
+     be accessed transparently. As a result code should not use ASN1_ITEM
+     references directly (such as &X509_it) but instead use the relevant
+     macros (such as ASN1_ITEM_rptr(X509)). This option is to allow
+     use of the new ASN1 code on platforms where exporting structures
+     is problematical (for example in shared libraries) but exporting
+     functions returning pointers to structures is not.
+     [Steve Henson]
+
+  *) Add support for overriding the generation of SSL/TLS session IDs.
+     These callbacks can be registered either in an SSL_CTX or per SSL.
+     The purpose of this is to allow applications to control, if they wish,
+     the arbitrary values chosen for use as session IDs, particularly as it
+     can be useful for session caching in multiple-server environments. A
+     command-line switch for testing this (and any client code that wishes
+     to use such a feature) has been added to "s_server".
+     [Geoff Thorpe, Lutz Jaenicke]
+
+  *) Modify mkdef.pl to recognise and parse preprocessor conditionals
+     of the form '#if defined(...) || defined(...) || ...' and
+     '#if !defined(...) && !defined(...) && ...'.  This also avoids
+     the growing number of special cases it was previously handling.
+     [Richard Levitte]
+
+  *) Make all configuration macros available for application by making
+     sure they are available in opensslconf.h, by giving them names starting
+     with "OPENSSL_" to avoid conflicts with other packages and by making
+     sure e_os2.h will cover all platform-specific cases together with
+     opensslconf.h.
+     Additionally, it is now possible to define configuration/platform-
+     specific names (called "system identities").  In the C code, these
+     are prefixed with "OPENSSL_SYSNAME_".  e_os2.h will create another
+     macro with the name beginning with "OPENSSL_SYS_", which is determined
+     from "OPENSSL_SYSNAME_*" or compiler-specific macros depending on
+     what is available.
+     [Richard Levitte]
+
+  *) New option -set_serial to 'req' and 'x509' this allows the serial
+     number to use to be specified on the command line. Previously self
+     signed certificates were hard coded with serial number 0 and the 
+     CA options of 'x509' had to use a serial number in a file which was
+     auto incremented.
+     [Steve Henson]
+
+  *) New options to 'ca' utility to support V2 CRL entry extensions.
+     Currently CRL reason, invalidity date and hold instruction are
+     supported. Add new CRL extensions to V3 code and some new objects.
+     [Steve Henson]
+
+  *) New function EVP_CIPHER_CTX_set_padding() this is used to
+     disable standard block padding (aka PKCS#5 padding) in the EVP
+     API, which was previously mandatory. This means that the data is
+     not padded in any way and so the total length much be a multiple
+     of the block size, otherwise an error occurs.
+     [Steve Henson]
+
+  *) Initial (incomplete) OCSP SSL support.
+     [Steve Henson]
+
+  *) New function OCSP_parse_url(). This splits up a URL into its host,
+     port and path components: primarily to parse OCSP URLs. New -url
+     option to ocsp utility.
+     [Steve Henson]
+
+  *) New nonce behavior. The return value of OCSP_check_nonce() now 
+     reflects the various checks performed. Applications can decide
+     whether to tolerate certain situations such as an absent nonce
+     in a response when one was present in a request: the ocsp application
+     just prints out a warning. New function OCSP_add1_basic_nonce()
+     this is to allow responders to include a nonce in a response even if
+     the request is nonce-less.
+     [Steve Henson]
+
+  *) Disable stdin buffering in load_cert (apps/apps.c) so that no certs are
+     skipped when using openssl x509 multiple times on a single input file,
+     e.g. "(openssl x509 -out cert1; openssl x509 -out cert2) <certs".
+     [Bodo Moeller]
+
+  *) Make ASN1_UTCTIME_set_string() and ASN1_GENERALIZEDTIME_set_string()
+     set string type: to handle setting ASN1_TIME structures. Fix ca
+     utility to correctly initialize revocation date of CRLs.
+     [Steve Henson]
+
+  *) New option SSL_OP_CIPHER_SERVER_PREFERENCE allows the server to override
+     the clients preferred ciphersuites and rather use its own preferences.
+     Should help to work around M$ SGC (Server Gated Cryptography) bug in
+     Internet Explorer by ensuring unchanged hash method during stepup.
+     (Also replaces the broken/deactivated SSL_OP_NON_EXPORT_FIRST option.)
+     [Lutz Jaenicke]
+
+  *) Make mkdef.pl recognise all DECLARE_ASN1 macros, change rijndael
+     to aes and add a new 'exist' option to print out symbols that don't
+     appear to exist.
+     [Steve Henson]
+
+  *) Additional options to ocsp utility to allow flags to be set and
+     additional certificates supplied.
+     [Steve Henson]
+
+  *) Add the option -VAfile to 'openssl ocsp', so the user can give the
+     OCSP client a number of certificate to only verify the response
+     signature against.
+     [Richard Levitte]
+
+  *) Update Rijndael code to version 3.0 and change EVP AES ciphers to
+     handle the new API. Currently only ECB, CBC modes supported. Add new
+     AES OIDs.
+
+     Add TLS AES ciphersuites as described in RFC3268, "Advanced
+     Encryption Standard (AES) Ciphersuites for Transport Layer
+     Security (TLS)".  (In beta versions of OpenSSL 0.9.7, these were
+     not enabled by default and were not part of the "ALL" ciphersuite
+     alias because they were not yet official; they could be
+     explicitly requested by specifying the "AESdraft" ciphersuite
+     group alias.  In the final release of OpenSSL 0.9.7, the group
+     alias is called "AES" and is part of "ALL".)
+     [Ben Laurie, Steve  Henson, Bodo Moeller]
+
+  *) New function OCSP_copy_nonce() to copy nonce value (if present) from
+     request to response.
+     [Steve Henson]
+
+  *) Functions for OCSP responders. OCSP_request_onereq_count(),
+     OCSP_request_onereq_get0(), OCSP_onereq_get0_id() and OCSP_id_get0_info()
+     extract information from a certificate request. OCSP_response_create()
+     creates a response and optionally adds a basic response structure.
+     OCSP_basic_add1_status() adds a complete single response to a basic
+     response and returns the OCSP_SINGLERESP structure just added (to allow
+     extensions to be included for example). OCSP_basic_add1_cert() adds a
+     certificate to a basic response and OCSP_basic_sign() signs a basic
+     response with various flags. New helper functions ASN1_TIME_check()
+     (checks validity of ASN1_TIME structure) and ASN1_TIME_to_generalizedtime()
+     (converts ASN1_TIME to GeneralizedTime).
+     [Steve Henson]
+
+  *) Various new functions. EVP_Digest() combines EVP_Digest{Init,Update,Final}()
+     in a single operation. X509_get0_pubkey_bitstr() extracts the public_key
+     structure from a certificate. X509_pubkey_digest() digests the public_key
+     contents: this is used in various key identifiers. 
+     [Steve Henson]
+
+  *) Make sk_sort() tolerate a NULL argument.
+     [Steve Henson reported by Massimiliano Pala <madwolf@comune.modena.it>]
+
+  *) New OCSP verify flag OCSP_TRUSTOTHER. When set the "other" certificates
+     passed by the function are trusted implicitly. If any of them signed the
+     response then it is assumed to be valid and is not verified.
+     [Steve Henson]
+
+  *) In PKCS7_set_type() initialise content_type in PKCS7_ENC_CONTENT
+     to data. This was previously part of the PKCS7 ASN1 code. This
+     was causing problems with OpenSSL created PKCS#12 and PKCS#7 structures.
+     [Steve Henson, reported by Kenneth R. Robinette
+				<support@securenetterm.com>]
+
+  *) Add CRYPTO_push_info() and CRYPTO_pop_info() calls to new ASN1
+     routines: without these tracing memory leaks is very painful.
+     Fix leaks in PKCS12 and PKCS7 routines.
+     [Steve Henson]
+
+  *) Make X509_time_adj() cope with the new behaviour of ASN1_TIME_new().
+     Previously it initialised the 'type' argument to V_ASN1_UTCTIME which
+     effectively meant GeneralizedTime would never be used. Now it
+     is initialised to -1 but X509_time_adj() now has to check the value
+     and use ASN1_TIME_set() if the value is not V_ASN1_UTCTIME or
+     V_ASN1_GENERALIZEDTIME, without this it always uses GeneralizedTime.
+     [Steve Henson, reported by Kenneth R. Robinette
+				<support@securenetterm.com>]
+
+  *) Fixes to BN_to_ASN1_INTEGER when bn is zero. This would previously
+     result in a zero length in the ASN1_INTEGER structure which was
+     not consistent with the structure when d2i_ASN1_INTEGER() was used
+     and would cause ASN1_INTEGER_cmp() to fail. Enhance s2i_ASN1_INTEGER()
+     to cope with hex and negative integers. Fix bug in i2a_ASN1_INTEGER()
+     where it did not print out a minus for negative ASN1_INTEGER.
+     [Steve Henson]
+
+  *) Add summary printout to ocsp utility. The various functions which
+     convert status values to strings have been renamed to:
+     OCSP_response_status_str(), OCSP_cert_status_str() and
+     OCSP_crl_reason_str() and are no longer static. New options
+     to verify nonce values and to disable verification. OCSP response
+     printout format cleaned up.
+     [Steve Henson]
+
+  *) Add additional OCSP certificate checks. These are those specified
+     in RFC2560. This consists of two separate checks: the CA of the
+     certificate being checked must either be the OCSP signer certificate
+     or the issuer of the OCSP signer certificate. In the latter case the
+     OCSP signer certificate must contain the OCSP signing extended key
+     usage. This check is performed by attempting to match the OCSP
+     signer or the OCSP signer CA to the issuerNameHash and issuerKeyHash
+     in the OCSP_CERTID structures of the response.
+     [Steve Henson]
+
+  *) Initial OCSP certificate verification added to OCSP_basic_verify()
+     and related routines. This uses the standard OpenSSL certificate
+     verify routines to perform initial checks (just CA validity) and
+     to obtain the certificate chain. Then additional checks will be
+     performed on the chain. Currently the root CA is checked to see
+     if it is explicitly trusted for OCSP signing. This is used to set
+     a root CA as a global signing root: that is any certificate that
+     chains to that CA is an acceptable OCSP signing certificate.
+     [Steve Henson]
+
+  *) New '-extfile ...' option to 'openssl ca' for reading X.509v3
+     extensions from a separate configuration file.
+     As when reading extensions from the main configuration file,
+     the '-extensions ...' option may be used for specifying the
+     section to use.
+     [Massimiliano Pala <madwolf@comune.modena.it>]
+
+  *) New OCSP utility. Allows OCSP requests to be generated or
+     read. The request can be sent to a responder and the output
+     parsed, outputed or printed in text form. Not complete yet:
+     still needs to check the OCSP response validity.
+     [Steve Henson]
+
+  *) New subcommands for 'openssl ca':
+     'openssl ca -status <serial>' prints the status of the cert with
+     the given serial number (according to the index file).
+     'openssl ca -updatedb' updates the expiry status of certificates
+     in the index file.
+     [Massimiliano Pala <madwolf@comune.modena.it>]
+
+  *) New '-newreq-nodes' command option to CA.pl.  This is like
+     '-newreq', but calls 'openssl req' with the '-nodes' option
+     so that the resulting key is not encrypted.
+     [Damien Miller <djm@mindrot.org>]
+
+  *) New configuration for the GNU Hurd.
+     [Jonathan Bartlett <johnnyb@wolfram.com> via Richard Levitte]
+
+  *) Initial code to implement OCSP basic response verify. This
+     is currently incomplete. Currently just finds the signer's
+     certificate and verifies the signature on the response.
+     [Steve Henson]
+
+  *) New SSLeay_version code SSLEAY_DIR to determine the compiled-in
+     value of OPENSSLDIR.  This is available via the new '-d' option
+     to 'openssl version', and is also included in 'openssl version -a'.
+     [Bodo Moeller]
+
+  *) Allowing defining memory allocation callbacks that will be given
+     file name and line number information in additional arguments
+     (a const char* and an int).  The basic functionality remains, as
+     well as the original possibility to just replace malloc(),
+     realloc() and free() by functions that do not know about these
+     additional arguments.  To register and find out the current
+     settings for extended allocation functions, the following
+     functions are provided:
+
+	CRYPTO_set_mem_ex_functions
+	CRYPTO_set_locked_mem_ex_functions
+	CRYPTO_get_mem_ex_functions
+	CRYPTO_get_locked_mem_ex_functions
+
+     These work the same way as CRYPTO_set_mem_functions and friends.
+     CRYPTO_get_[locked_]mem_functions now writes 0 where such an
+     extended allocation function is enabled.
+     Similarly, CRYPTO_get_[locked_]mem_ex_functions writes 0 where
+     a conventional allocation function is enabled.
+     [Richard Levitte, Bodo Moeller]
+
+  *) Finish off removing the remaining LHASH function pointer casts.
+     There should no longer be any prototype-casting required when using
+     the LHASH abstraction, and any casts that remain are "bugs". See
+     the callback types and macros at the head of lhash.h for details
+     (and "OBJ_cleanup" in crypto/objects/obj_dat.c as an example).
+     [Geoff Thorpe]
+
+  *) Add automatic query of EGD sockets in RAND_poll() for the unix variant.
+     If /dev/[u]random devices are not available or do not return enough
+     entropy, EGD style sockets (served by EGD or PRNGD) will automatically
+     be queried.
+     The locations /var/run/egd-pool, /dev/egd-pool, /etc/egd-pool, and
+     /etc/entropy will be queried once each in this sequence, querying stops
+     when enough entropy was collected without querying more sockets.
+     [Lutz Jaenicke]
+
+  *) Change the Unix RAND_poll() variant to be able to poll several
+     random devices, as specified by DEVRANDOM, until a sufficient amount
+     of data has been collected.   We spend at most 10 ms on each file
+     (select timeout) and read in non-blocking mode.  DEVRANDOM now
+     defaults to the list "/dev/urandom", "/dev/random", "/dev/srandom"
+     (previously it was just the string "/dev/urandom"), so on typical
+     platforms the 10 ms delay will never occur.
+     Also separate out the Unix variant to its own file, rand_unix.c.
+     For VMS, there's a currently-empty rand_vms.c.
+     [Richard Levitte]
+
+  *) Move OCSP client related routines to ocsp_cl.c. These
+     provide utility functions which an application needing
+     to issue a request to an OCSP responder and analyse the
+     response will typically need: as opposed to those which an
+     OCSP responder itself would need which will be added later.
+
+     OCSP_request_sign() signs an OCSP request with an API similar
+     to PKCS7_sign(). OCSP_response_status() returns status of OCSP
+     response. OCSP_response_get1_basic() extracts basic response
+     from response. OCSP_resp_find_status(): finds and extracts status
+     information from an OCSP_CERTID structure (which will be created
+     when the request structure is built). These are built from lower
+     level functions which work on OCSP_SINGLERESP structures but
+     won't normally be used unless the application wishes to examine
+     extensions in the OCSP response for example.
+
+     Replace nonce routines with a pair of functions.
+     OCSP_request_add1_nonce() adds a nonce value and optionally
+     generates a random value. OCSP_check_nonce() checks the
+     validity of the nonce in an OCSP response.
+     [Steve Henson]
+
+  *) Change function OCSP_request_add() to OCSP_request_add0_id().
+     This doesn't copy the supplied OCSP_CERTID and avoids the
+     need to free up the newly created id. Change return type
+     to OCSP_ONEREQ to return the internal OCSP_ONEREQ structure.
+     This can then be used to add extensions to the request.
+     Deleted OCSP_request_new(), since most of its functionality
+     is now in OCSP_REQUEST_new() (and the case insensitive name
+     clash) apart from the ability to set the request name which
+     will be added elsewhere.
+     [Steve Henson]
+
+  *) Update OCSP API. Remove obsolete extensions argument from
+     various functions. Extensions are now handled using the new
+     OCSP extension code. New simple OCSP HTTP function which 
+     can be used to send requests and parse the response.
+     [Steve Henson]
+
+  *) Fix the PKCS#7 (S/MIME) code to work with new ASN1. Two new
+     ASN1_ITEM structures help with sign and verify. PKCS7_ATTR_SIGN
+     uses the special reorder version of SET OF to sort the attributes
+     and reorder them to match the encoded order. This resolves a long
+     standing problem: a verify on a PKCS7 structure just after signing
+     it used to fail because the attribute order did not match the
+     encoded order. PKCS7_ATTR_VERIFY does not reorder the attributes:
+     it uses the received order. This is necessary to tolerate some broken
+     software that does not order SET OF. This is handled by encoding
+     as a SEQUENCE OF but using implicit tagging (with UNIVERSAL class)
+     to produce the required SET OF.
+     [Steve Henson]
+
+  *) Have mk1mf.pl generate the macros OPENSSL_BUILD_SHLIBCRYPTO and
+     OPENSSL_BUILD_SHLIBSSL and use them appropriately in the header
+     files to get correct declarations of the ASN.1 item variables.
+     [Richard Levitte]
+
+  *) Rewrite of PKCS#12 code to use new ASN1 functionality. Replace many
+     PKCS#12 macros with real functions. Fix two unrelated ASN1 bugs:
+     asn1_check_tlen() would sometimes attempt to use 'ctx' when it was
+     NULL and ASN1_TYPE was not dereferenced properly in asn1_ex_c2i().
+     New ASN1 macro: DECLARE_ASN1_ITEM() which just declares the relevant
+     ASN1_ITEM and no wrapper functions.
+     [Steve Henson]
+
+  *) New functions or ASN1_item_d2i_fp() and ASN1_item_d2i_bio(). These
+     replace the old function pointer based I/O routines. Change most of
+     the *_d2i_bio() and *_d2i_fp() functions to use these.
+     [Steve Henson]
+
+  *) Enhance mkdef.pl to be more accepting about spacing in C preprocessor
+     lines, recognice more "algorithms" that can be deselected, and make
+     it complain about algorithm deselection that isn't recognised.
+     [Richard Levitte]
+
+  *) New ASN1 functions to handle dup, sign, verify, digest, pack and
+     unpack operations in terms of ASN1_ITEM. Modify existing wrappers
+     to use new functions. Add NO_ASN1_OLD which can be set to remove
+     some old style ASN1 functions: this can be used to determine if old
+     code will still work when these eventually go away.
+     [Steve Henson]
+
+  *) New extension functions for OCSP structures, these follow the
+     same conventions as certificates and CRLs.
+     [Steve Henson]
+
+  *) New function X509V3_add1_i2d(). This automatically encodes and
+     adds an extension. Its behaviour can be customised with various
+     flags to append, replace or delete. Various wrappers added for
+     certificates and CRLs.
+     [Steve Henson]
+
+  *) Fix to avoid calling the underlying ASN1 print routine when
+     an extension cannot be parsed. Correct a typo in the
+     OCSP_SERVICELOC extension. Tidy up print OCSP format.
+     [Steve Henson]
+
+  *) Make mkdef.pl parse some of the ASN1 macros and add appropriate
+     entries for variables.
+     [Steve Henson]
+
+  *) Add functionality to apps/openssl.c for detecting locking
+     problems: As the program is single-threaded, all we have
+     to do is register a locking callback using an array for
+     storing which locks are currently held by the program.
+     [Bodo Moeller]
+
+  *) Use a lock around the call to CRYPTO_get_ex_new_index() in
+     SSL_get_ex_data_X509_STORE_idx(), which is used in
+     ssl_verify_cert_chain() and thus can be called at any time
+     during TLS/SSL handshakes so that thread-safety is essential.
+     Unfortunately, the ex_data design is not at all suited
+     for multi-threaded use, so it probably should be abolished.
+     [Bodo Moeller]
+
+  *) Added Broadcom "ubsec" ENGINE to OpenSSL.
+     [Broadcom, tweaked and integrated by Geoff Thorpe]
+
+  *) Move common extension printing code to new function
+     X509V3_print_extensions(). Reorganise OCSP print routines and
+     implement some needed OCSP ASN1 functions. Add OCSP extensions.
+     [Steve Henson]
+
+  *) New function X509_signature_print() to remove duplication in some
+     print routines.
+     [Steve Henson]
+
+  *) Add a special meaning when SET OF and SEQUENCE OF flags are both
+     set (this was treated exactly the same as SET OF previously). This
+     is used to reorder the STACK representing the structure to match the
+     encoding. This will be used to get round a problem where a PKCS7
+     structure which was signed could not be verified because the STACK
+     order did not reflect the encoded order.
+     [Steve Henson]
+
+  *) Reimplement the OCSP ASN1 module using the new code.
+     [Steve Henson]
+
+  *) Update the X509V3 code to permit the use of an ASN1_ITEM structure
+     for its ASN1 operations. The old style function pointers still exist
+     for now but they will eventually go away.
+     [Steve Henson]
+
+  *) Merge in replacement ASN1 code from the ASN1 branch. This almost
+     completely replaces the old ASN1 functionality with a table driven
+     encoder and decoder which interprets an ASN1_ITEM structure describing
+     the ASN1 module. Compatibility with the existing ASN1 API (i2d,d2i) is
+     largely maintained. Almost all of the old asn1_mac.h macro based ASN1
+     has also been converted to the new form.
+     [Steve Henson]
+
+  *) Change BN_mod_exp_recp so that negative moduli are tolerated
+     (the sign is ignored).  Similarly, ignore the sign in BN_MONT_CTX_set
+     so that BN_mod_exp_mont and BN_mod_exp_mont_word work
+     for negative moduli.
+     [Bodo Moeller]
+
+  *) Fix BN_uadd and BN_usub: Always return non-negative results instead
+     of not touching the result's sign bit.
+     [Bodo Moeller]
+
+  *) BN_div bugfix: If the result is 0, the sign (res->neg) must not be
+     set.
+     [Bodo Moeller]
+
+  *) Changed the LHASH code to use prototypes for callbacks, and created
+     macros to declare and implement thin (optionally static) functions
+     that provide type-safety and avoid function pointer casting for the
+     type-specific callbacks.
+     [Geoff Thorpe]
+
+  *) Added Kerberos Cipher Suites to be used with TLS, as written in
+     RFC 2712.
+     [Veers Staats <staatsvr@asc.hpc.mil>,
+      Jeffrey Altman <jaltman@columbia.edu>, via Richard Levitte]
+
+  *) Reformat the FAQ so the different questions and answers can be divided
+     in sections depending on the subject.
+     [Richard Levitte]
+
+  *) Have the zlib compression code load ZLIB.DLL dynamically under
+     Windows.
+     [Richard Levitte]
+
+  *) New function BN_mod_sqrt for computing square roots modulo a prime
+     (using the probabilistic Tonelli-Shanks algorithm unless
+     p == 3 (mod 4)  or  p == 5 (mod 8),  which are cases that can
+     be handled deterministically).
+     [Lenka Fibikova <fibikova@exp-math.uni-essen.de>, Bodo Moeller]
+
+  *) Make BN_mod_inverse faster by explicitly handling small quotients
+     in the Euclid loop. (Speed gain about 20% for small moduli [256 or
+     512 bits], about 30% for larger ones [1024 or 2048 bits].)
+     [Bodo Moeller]
+
+  *) New function BN_kronecker.
+     [Bodo Moeller]
+
+  *) Fix BN_gcd so that it works on negative inputs; the result is
+     positive unless both parameters are zero.
+     Previously something reasonably close to an infinite loop was
+     possible because numbers could be growing instead of shrinking
+     in the implementation of Euclid's algorithm.
+     [Bodo Moeller]
+
+  *) Fix BN_is_word() and BN_is_one() macros to take into account the
+     sign of the number in question.
+
+     Fix BN_is_word(a,w) to work correctly for w == 0.
+
+     The old BN_is_word(a,w) macro is now called BN_abs_is_word(a,w)
+     because its test if the absolute value of 'a' equals 'w'.
+     Note that BN_abs_is_word does *not* handle w == 0 reliably;
+     it exists mostly for use in the implementations of BN_is_zero(),
+     BN_is_one(), and BN_is_word().
+     [Bodo Moeller]
+
+  *) New function BN_swap.
+     [Bodo Moeller]
+
+  *) Use BN_nnmod instead of BN_mod in crypto/bn/bn_exp.c so that
+     the exponentiation functions are more likely to produce reasonable
+     results on negative inputs.
+     [Bodo Moeller]
+
+  *) Change BN_mod_mul so that the result is always non-negative.
+     Previously, it could be negative if one of the factors was negative;
+     I don't think anyone really wanted that behaviour.
+     [Bodo Moeller]
+
+  *) Move BN_mod_... functions into new file crypto/bn/bn_mod.c
+     (except for exponentiation, which stays in crypto/bn/bn_exp.c,
+     and BN_mod_mul_reciprocal, which stays in crypto/bn/bn_recp.c)
+     and add new functions:
+
+          BN_nnmod
+          BN_mod_sqr
+          BN_mod_add
+          BN_mod_add_quick
+          BN_mod_sub
+          BN_mod_sub_quick
+          BN_mod_lshift1
+          BN_mod_lshift1_quick
+          BN_mod_lshift
+          BN_mod_lshift_quick
+
+     These functions always generate non-negative results.
+
+     BN_nnmod otherwise is like BN_mod (if BN_mod computes a remainder  r
+     such that  |m| < r < 0,  BN_nnmod will output  rem + |m|  instead).
+
+     BN_mod_XXX_quick(r, a, [b,] m) generates the same result as
+     BN_mod_XXX(r, a, [b,] m, ctx), but requires that  a  [and  b]
+     be reduced modulo  m.
+     [Lenka Fibikova <fibikova@exp-math.uni-essen.de>, Bodo Moeller]
+
+#if 0
+     The following entry accidentally appeared in the CHANGES file
+     distributed with OpenSSL 0.9.7.  The modifications described in
+     it do *not* apply to OpenSSL 0.9.7.
+
+  *) Remove a few calls to bn_wexpand() in BN_sqr() (the one in there
+     was actually never needed) and in BN_mul().  The removal in BN_mul()
+     required a small change in bn_mul_part_recursive() and the addition
+     of the functions bn_cmp_part_words(), bn_sub_part_words() and
+     bn_add_part_words(), which do the same thing as bn_cmp_words(),
+     bn_sub_words() and bn_add_words() except they take arrays with
+     differing sizes.
+     [Richard Levitte]
+#endif
+
+  *) In 'openssl passwd', verify passwords read from the terminal
+     unless the '-salt' option is used (which usually means that
+     verification would just waste user's time since the resulting
+     hash is going to be compared with some given password hash)
+     or the new '-noverify' option is used.
+
+     This is an incompatible change, but it does not affect
+     non-interactive use of 'openssl passwd' (passwords on the command
+     line, '-stdin' option, '-in ...' option) and thus should not
+     cause any problems.
+     [Bodo Moeller]
+
+  *) Remove all references to RSAref, since there's no more need for it.
+     [Richard Levitte]
+
+  *) Make DSO load along a path given through an environment variable
+     (SHLIB_PATH) with shl_load().
+     [Richard Levitte]
+
+  *) Constify the ENGINE code as a result of BIGNUM constification.
+     Also constify the RSA code and most things related to it.  In a
+     few places, most notable in the depth of the ASN.1 code, ugly
+     casts back to non-const were required (to be solved at a later
+     time)
+     [Richard Levitte]
+
+  *) Make it so the openssl application has all engines loaded by default.
+     [Richard Levitte]
+
+  *) Constify the BIGNUM routines a little more.
+     [Richard Levitte]
+
+  *) Add the following functions:
+
+	ENGINE_load_cswift()
+	ENGINE_load_chil()
+	ENGINE_load_atalla()
+	ENGINE_load_nuron()
+	ENGINE_load_builtin_engines()
+
+     That way, an application can itself choose if external engines that
+     are built-in in OpenSSL shall ever be used or not.  The benefit is
+     that applications won't have to be linked with libdl or other dso
+     libraries unless it's really needed.
+
+     Changed 'openssl engine' to load all engines on demand.
+     Changed the engine header files to avoid the duplication of some
+     declarations (they differed!).
+     [Richard Levitte]
+
+  *) 'openssl engine' can now list capabilities.
+     [Richard Levitte]
+
+  *) Better error reporting in 'openssl engine'.
+     [Richard Levitte]
+
+  *) Never call load_dh_param(NULL) in s_server.
+     [Bodo Moeller]
+
+  *) Add engine application.  It can currently list engines by name and
+     identity, and test if they are actually available.
+     [Richard Levitte]
+
+  *) Improve RPM specification file by forcing symbolic linking and making
+     sure the installed documentation is also owned by root.root.
+     [Damien Miller <djm@mindrot.org>]
+
+  *) Give the OpenSSL applications more possibilities to make use of
+     keys (public as well as private) handled by engines.
+     [Richard Levitte]
+
+  *) Add OCSP code that comes from CertCo.
+     [Richard Levitte]
+
+  *) Add VMS support for the Rijndael code.
+     [Richard Levitte]
+
+  *) Added untested support for Nuron crypto accelerator.
+     [Ben Laurie]
+
+  *) Add support for external cryptographic devices.  This code was
+     previously distributed separately as the "engine" branch.
+     [Geoff Thorpe, Richard Levitte]
+
+  *) Rework the filename-translation in the DSO code. It is now possible to
+     have far greater control over how a "name" is turned into a filename
+     depending on the operating environment and any oddities about the
+     different shared library filenames on each system.
+     [Geoff Thorpe]
+
+  *) Support threads on FreeBSD-elf in Configure.
+     [Richard Levitte]
+
+  *) Fix for SHA1 assembly problem with MASM: it produces
+     warnings about corrupt line number information when assembling
+     with debugging information. This is caused by the overlapping
+     of two sections.
+     [Bernd Matthes <mainbug@celocom.de>, Steve Henson]
+
+  *) NCONF changes.
+     NCONF_get_number() has no error checking at all.  As a replacement,
+     NCONF_get_number_e() is defined (_e for "error checking") and is
+     promoted strongly.  The old NCONF_get_number is kept around for
+     binary backward compatibility.
+     Make it possible for methods to load from something other than a BIO,
+     by providing a function pointer that is given a name instead of a BIO.
+     For example, this could be used to load configuration data from an
+     LDAP server.
+     [Richard Levitte]
+
+  *) Fix for non blocking accept BIOs. Added new I/O special reason
+     BIO_RR_ACCEPT to cover this case. Previously use of accept BIOs
+     with non blocking I/O was not possible because no retry code was
+     implemented. Also added new SSL code SSL_WANT_ACCEPT to cover
+     this case.
+     [Steve Henson]
+
+  *) Added the beginnings of Rijndael support.
+     [Ben Laurie]
+
+  *) Fix for bug in DirectoryString mask setting. Add support for
+     X509_NAME_print_ex() in 'req' and X509_print_ex() function
+     to allow certificate printing to more controllable, additional
+     'certopt' option to 'x509' to allow new printing options to be
+     set.
+     [Steve Henson]
+
+  *) Clean old EAY MD5 hack from e_os.h.
+     [Richard Levitte]
+
+ Changes between 0.9.6l and 0.9.6m  [17 Mar 2004]
+
+  *) Fix null-pointer assignment in do_change_cipher_spec() revealed
+     by using the Codenomicon TLS Test Tool (CVE-2004-0079)
+     [Joe Orton, Steve Henson]
+
+ Changes between 0.9.6k and 0.9.6l  [04 Nov 2003]
+
+  *) Fix additional bug revealed by the NISCC test suite:
+
+     Stop bug triggering large recursion when presented with
+     certain ASN.1 tags (CVE-2003-0851)
+     [Steve Henson]
+
+ Changes between 0.9.6j and 0.9.6k  [30 Sep 2003]
+
+  *) Fix various bugs revealed by running the NISCC test suite:
+
+     Stop out of bounds reads in the ASN1 code when presented with
+     invalid tags (CVE-2003-0543 and CVE-2003-0544).
+     
+     If verify callback ignores invalid public key errors don't try to check
+     certificate signature with the NULL public key.
+
+     [Steve Henson]
+
+  *) In ssl3_accept() (ssl/s3_srvr.c) only accept a client certificate
+     if the server requested one: as stated in TLS 1.0 and SSL 3.0
+     specifications.
+     [Steve Henson]
+
+  *) In ssl3_get_client_hello() (ssl/s3_srvr.c), tolerate additional
+     extra data after the compression methods not only for TLS 1.0
+     but also for SSL 3.0 (as required by the specification).
+     [Bodo Moeller; problem pointed out by Matthias Loepfe]
+
+  *) Change X509_certificate_type() to mark the key as exported/exportable
+     when it's 512 *bits* long, not 512 bytes.
+     [Richard Levitte]
+
+ Changes between 0.9.6i and 0.9.6j  [10 Apr 2003]
+
+  *) Countermeasure against the Klima-Pokorny-Rosa extension of
+     Bleichbacher's attack on PKCS #1 v1.5 padding: treat
+     a protocol version number mismatch like a decryption error
+     in ssl3_get_client_key_exchange (ssl/s3_srvr.c).
+     [Bodo Moeller]
+
+  *) Turn on RSA blinding by default in the default implementation
+     to avoid a timing attack. Applications that don't want it can call
+     RSA_blinding_off() or use the new flag RSA_FLAG_NO_BLINDING.
+     They would be ill-advised to do so in most cases.
+     [Ben Laurie, Steve Henson, Geoff Thorpe, Bodo Moeller]
+
+  *) Change RSA blinding code so that it works when the PRNG is not
+     seeded (in this case, the secret RSA exponent is abused as
+     an unpredictable seed -- if it is not unpredictable, there
+     is no point in blinding anyway).  Make RSA blinding thread-safe
+     by remembering the creator's thread ID in rsa->blinding and
+     having all other threads use local one-time blinding factors
+     (this requires more computation than sharing rsa->blinding, but
+     avoids excessive locking; and if an RSA object is not shared
+     between threads, blinding will still be very fast).
+     [Bodo Moeller]
+
+ Changes between 0.9.6h and 0.9.6i  [19 Feb 2003]
+
+  *) In ssl3_get_record (ssl/s3_pkt.c), minimize information leaked
+     via timing by performing a MAC computation even if incorrrect
+     block cipher padding has been found.  This is a countermeasure
+     against active attacks where the attacker has to distinguish
+     between bad padding and a MAC verification error. (CVE-2003-0078)
+
+     [Bodo Moeller; problem pointed out by Brice Canvel (EPFL),
+     Alain Hiltgen (UBS), Serge Vaudenay (EPFL), and
+     Martin Vuagnoux (EPFL, Ilion)]
+
+ Changes between 0.9.6g and 0.9.6h  [5 Dec 2002]
+
+  *) New function OPENSSL_cleanse(), which is used to cleanse a section of
+     memory from it's contents.  This is done with a counter that will
+     place alternating values in each byte.  This can be used to solve
+     two issues: 1) the removal of calls to memset() by highly optimizing
+     compilers, and 2) cleansing with other values than 0, since those can
+     be read through on certain media, for example a swap space on disk.
+     [Geoff Thorpe]
+
+  *) Bugfix: client side session caching did not work with external caching,
+     because the session->cipher setting was not restored when reloading
+     from the external cache. This problem was masked, when
+     SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG (part of SSL_OP_ALL) was set.
+     (Found by Steve Haslam <steve@araqnid.ddts.net>.)
+     [Lutz Jaenicke]
+
+  *) Fix client_certificate (ssl/s2_clnt.c): The permissible total
+     length of the REQUEST-CERTIFICATE message is 18 .. 34, not 17 .. 33.
+     [Zeev Lieber <zeev-l@yahoo.com>]
+
+  *) Undo an undocumented change introduced in 0.9.6e which caused
+     repeated calls to OpenSSL_add_all_ciphers() and 
+     OpenSSL_add_all_digests() to be ignored, even after calling
+     EVP_cleanup().
+     [Richard Levitte]
+
+  *) Change the default configuration reader to deal with last line not
+     being properly terminated.
+     [Richard Levitte]
+
+  *) Change X509_NAME_cmp() so it applies the special rules on handling
+     DN values that are of type PrintableString, as well as RDNs of type
+     emailAddress where the value has the type ia5String.
+     [stefank@valicert.com via Richard Levitte]
+
+  *) Add a SSL_SESS_CACHE_NO_INTERNAL_STORE flag to take over half
+     the job SSL_SESS_CACHE_NO_INTERNAL_LOOKUP was inconsistently
+     doing, define a new flag (SSL_SESS_CACHE_NO_INTERNAL) to be
+     the bitwise-OR of the two for use by the majority of applications
+     wanting this behaviour, and update the docs. The documented
+     behaviour and actual behaviour were inconsistent and had been
+     changing anyway, so this is more a bug-fix than a behavioural
+     change.
+     [Geoff Thorpe, diagnosed by Nadav Har'El]
+
+  *) Don't impose a 16-byte length minimum on session IDs in ssl/s3_clnt.c
+     (the SSL 3.0 and TLS 1.0 specifications allow any length up to 32 bytes).
+     [Bodo Moeller]
+
+  *) Fix initialization code race conditions in
+        SSLv23_method(),  SSLv23_client_method(),   SSLv23_server_method(),
+        SSLv2_method(),   SSLv2_client_method(),    SSLv2_server_method(),
+        SSLv3_method(),   SSLv3_client_method(),    SSLv3_server_method(),
+        TLSv1_method(),   TLSv1_client_method(),    TLSv1_server_method(),
+        ssl2_get_cipher_by_char(),
+        ssl3_get_cipher_by_char().
+     [Patrick McCormick <patrick@tellme.com>, Bodo Moeller]
+
+  *) Reorder cleanup sequence in SSL_CTX_free(): only remove the ex_data after
+     the cached sessions are flushed, as the remove_cb() might use ex_data
+     contents. Bug found by Sam Varshavchik <mrsam@courier-mta.com>
+     (see [openssl.org #212]).
+     [Geoff Thorpe, Lutz Jaenicke]
+
+  *) Fix typo in OBJ_txt2obj which incorrectly passed the content
+     length, instead of the encoding length to d2i_ASN1_OBJECT.
+     [Steve Henson]
+
+ Changes between 0.9.6f and 0.9.6g  [9 Aug 2002]
+
+  *) [In 0.9.6g-engine release:]
+     Fix crypto/engine/vendor_defns/cswift.h for WIN32 (use '_stdcall').
+     [Lynn Gazis <lgazis@rainbow.com>]
+
+ Changes between 0.9.6e and 0.9.6f  [8 Aug 2002]
+
+  *) Fix ASN1 checks. Check for overflow by comparing with LONG_MAX
+     and get fix the header length calculation.
+     [Florian Weimer <Weimer@CERT.Uni-Stuttgart.DE>,
+	Alon Kantor <alonk@checkpoint.com> (and others),
+	Steve Henson]
+
+  *) Use proper error handling instead of 'assertions' in buffer
+     overflow checks added in 0.9.6e.  This prevents DoS (the
+     assertions could call abort()).
+     [Arne Ansper <arne@ats.cyber.ee>, Bodo Moeller]
+
+ Changes between 0.9.6d and 0.9.6e  [30 Jul 2002]
+
+  *) Add various sanity checks to asn1_get_length() to reject
+     the ASN1 length bytes if they exceed sizeof(long), will appear
+     negative or the content length exceeds the length of the
+     supplied buffer.
+     [Steve Henson, Adi Stav <stav@mercury.co.il>, James Yonan <jim@ntlp.com>]
+
+  *) Fix cipher selection routines: ciphers without encryption had no flags
+     for the cipher strength set and where therefore not handled correctly
+     by the selection routines (PR #130).
+     [Lutz Jaenicke]
+
+  *) Fix EVP_dsa_sha macro.
+     [Nils Larsch]
+
+  *) New option
+          SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
+     for disabling the SSL 3.0/TLS 1.0 CBC vulnerability countermeasure
+     that was added in OpenSSL 0.9.6d.
+
+     As the countermeasure turned out to be incompatible with some
+     broken SSL implementations, the new option is part of SSL_OP_ALL.
+     SSL_OP_ALL is usually employed when compatibility with weird SSL
+     implementations is desired (e.g. '-bugs' option to 's_client' and
+     's_server'), so the new option is automatically set in many
+     applications.
+     [Bodo Moeller]
+
+  *) Changes in security patch:
+
+     Changes marked "(CHATS)" were sponsored by the Defense Advanced
+     Research Projects Agency (DARPA) and Air Force Research Laboratory,
+     Air Force Materiel Command, USAF, under agreement number
+     F30602-01-2-0537.
+
+  *) Add various sanity checks to asn1_get_length() to reject
+     the ASN1 length bytes if they exceed sizeof(long), will appear
+     negative or the content length exceeds the length of the
+     supplied buffer. (CVE-2002-0659)
+     [Steve Henson, Adi Stav <stav@mercury.co.il>, James Yonan <jim@ntlp.com>]
+
+  *) Assertions for various potential buffer overflows, not known to
+     happen in practice.
+     [Ben Laurie (CHATS)]
+
+  *) Various temporary buffers to hold ASCII versions of integers were
+     too small for 64 bit platforms. (CVE-2002-0655)
+     [Matthew Byng-Maddick <mbm@aldigital.co.uk> and Ben Laurie (CHATS)>
+
+  *) Remote buffer overflow in SSL3 protocol - an attacker could
+     supply an oversized session ID to a client. (CVE-2002-0656)
+     [Ben Laurie (CHATS)]
+
+  *) Remote buffer overflow in SSL2 protocol - an attacker could
+     supply an oversized client master key. (CVE-2002-0656)
+     [Ben Laurie (CHATS)]
+
+ Changes between 0.9.6c and 0.9.6d  [9 May 2002]
+
+  *) Fix crypto/asn1/a_sign.c so that 'parameters' is omitted (not
+     encoded as NULL) with id-dsa-with-sha1.
+     [Nils Larsch <nla@trustcenter.de>; problem pointed out by Bodo Moeller]
+
+  *) Check various X509_...() return values in apps/req.c.
+     [Nils Larsch <nla@trustcenter.de>]
+
+  *) Fix BASE64 decode (EVP_DecodeUpdate) for data with CR/LF ended lines:
+     an end-of-file condition would erroneously be flagged, when the CRLF
+     was just at the end of a processed block. The bug was discovered when
+     processing data through a buffering memory BIO handing the data to a
+     BASE64-decoding BIO. Bug fund and patch submitted by Pavel Tsekov
+     <ptsekov@syntrex.com> and Nedelcho Stanev.
+     [Lutz Jaenicke]
+
+  *) Implement a countermeasure against a vulnerability recently found
+     in CBC ciphersuites in SSL 3.0/TLS 1.0: Send an empty fragment
+     before application data chunks to avoid the use of known IVs
+     with data potentially chosen by the attacker.
+     [Bodo Moeller]
+
+  *) Fix length checks in ssl3_get_client_hello().
+     [Bodo Moeller]
+
+  *) TLS/SSL library bugfix: use s->s3->in_read_app_data differently
+     to prevent ssl3_read_internal() from incorrectly assuming that
+     ssl3_read_bytes() found application data while handshake
+     processing was enabled when in fact s->s3->in_read_app_data was
+     merely automatically cleared during the initial handshake.
+     [Bodo Moeller; problem pointed out by Arne Ansper <arne@ats.cyber.ee>]
+
+  *) Fix object definitions for Private and Enterprise: they were not
+     recognized in their shortname (=lowercase) representation. Extend
+     obj_dat.pl to issue an error when using undefined keywords instead
+     of silently ignoring the problem (Svenning Sorensen
+     <sss@sss.dnsalias.net>).
+     [Lutz Jaenicke]
+
+  *) Fix DH_generate_parameters() so that it works for 'non-standard'
+     generators, i.e. generators other than 2 and 5.  (Previously, the
+     code did not properly initialise the 'add' and 'rem' values to
+     BN_generate_prime().)
+
+     In the new general case, we do not insist that 'generator' is
+     actually a primitive root: This requirement is rather pointless;
+     a generator of the order-q subgroup is just as good, if not
+     better.
+     [Bodo Moeller]
+ 
+  *) Map new X509 verification errors to alerts. Discovered and submitted by
+     Tom Wu <tom@arcot.com>.
+     [Lutz Jaenicke]
+
+  *) Fix ssl3_pending() (ssl/s3_lib.c) to prevent SSL_pending() from
+     returning non-zero before the data has been completely received
+     when using non-blocking I/O.
+     [Bodo Moeller; problem pointed out by John Hughes]
+
+  *) Some of the ciphers missed the strength entry (SSL_LOW etc).
+     [Ben Laurie, Lutz Jaenicke]
+
+  *) Fix bug in SSL_clear(): bad sessions were not removed (found by
+     Yoram Zahavi <YoramZ@gilian.com>).
+     [Lutz Jaenicke]
+
+  *) Add information about CygWin 1.3 and on, and preserve proper
+     configuration for the versions before that.
+     [Corinna Vinschen <vinschen@redhat.com> and Richard Levitte]
+
+  *) Make removal from session cache (SSL_CTX_remove_session()) more robust:
+     check whether we deal with a copy of a session and do not delete from
+     the cache in this case. Problem reported by "Izhar Shoshani Levi"
+     <izhar@checkpoint.com>.
+     [Lutz Jaenicke]
+
+  *) Do not store session data into the internal session cache, if it
+     is never intended to be looked up (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
+     flag is set). Proposed by Aslam <aslam@funk.com>.
+     [Lutz Jaenicke]
+
+  *) Have ASN1_BIT_STRING_set_bit() really clear a bit when the requested
+     value is 0.
+     [Richard Levitte]
+
+  *) [In 0.9.6d-engine release:]
+     Fix a crashbug and a logic bug in hwcrhk_load_pubkey().
+     [Toomas Kiisk <vix@cyber.ee> via Richard Levitte]
+
+  *) Add the configuration target linux-s390x.
+     [Neale Ferguson <Neale.Ferguson@SoftwareAG-USA.com> via Richard Levitte]
+
+  *) The earlier bugfix for the SSL3_ST_SW_HELLO_REQ_C case of
+     ssl3_accept (ssl/s3_srvr.c) incorrectly used a local flag
+     variable as an indication that a ClientHello message has been
+     received.  As the flag value will be lost between multiple
+     invocations of ssl3_accept when using non-blocking I/O, the
+     function may not be aware that a handshake has actually taken
+     place, thus preventing a new session from being added to the
+     session cache.
+
+     To avoid this problem, we now set s->new_session to 2 instead of
+     using a local variable.
+     [Lutz Jaenicke, Bodo Moeller]
+
+  *) Bugfix: Return -1 from ssl3_get_server_done (ssl3/s3_clnt.c)
+     if the SSL_R_LENGTH_MISMATCH error is detected.
+     [Geoff Thorpe, Bodo Moeller]
+
+  *) New 'shared_ldflag' column in Configure platform table.
+     [Richard Levitte]
+
+  *) Fix EVP_CIPHER_mode macro.
+     ["Dan S. Camper" <dan@bti.net>]
+
+  *) Fix ssl3_read_bytes (ssl/s3_pkt.c): To ignore messages of unknown
+     type, we must throw them away by setting rr->length to 0.
+     [D P Chang <dpc@qualys.com>]
+
+ Changes between 0.9.6b and 0.9.6c  [21 dec 2001]
+
+  *) Fix BN_rand_range bug pointed out by Dominikus Scherkl
+     <Dominikus.Scherkl@biodata.com>.  (The previous implementation
+     worked incorrectly for those cases where  range = 10..._2  and
+     3*range  is two bits longer than  range.)
+     [Bodo Moeller]
+
+  *) Only add signing time to PKCS7 structures if it is not already
+     present.
+     [Steve Henson]
+
+  *) Fix crypto/objects/objects.h: "ld-ce" should be "id-ce",
+     OBJ_ld_ce should be OBJ_id_ce.
+     Also some ip-pda OIDs in crypto/objects/objects.txt were
+     incorrect (cf. RFC 3039).
+     [Matt Cooper, Frederic Giudicelli, Bodo Moeller]
+
+  *) Release CRYPTO_LOCK_DYNLOCK when CRYPTO_destroy_dynlockid()
+     returns early because it has nothing to do.
+     [Andy Schneider <andy.schneider@bjss.co.uk>]
+
+  *) [In 0.9.6c-engine release:]
+     Fix mutex callback return values in crypto/engine/hw_ncipher.c.
+     [Andy Schneider <andy.schneider@bjss.co.uk>]
+
+  *) [In 0.9.6c-engine release:]
+     Add support for Cryptographic Appliance's keyserver technology.
+     (Use engine 'keyclient')
+     [Cryptographic Appliances and Geoff Thorpe]
+
+  *) Add a configuration entry for OS/390 Unix.  The C compiler 'c89'
+     is called via tools/c89.sh because arguments have to be
+     rearranged (all '-L' options must appear before the first object
+     modules).
+     [Richard Shapiro <rshapiro@abinitio.com>]
+
+  *) [In 0.9.6c-engine release:]
+     Add support for Broadcom crypto accelerator cards, backported
+     from 0.9.7.
+     [Broadcom, Nalin Dahyabhai <nalin@redhat.com>, Mark Cox]
+
+  *) [In 0.9.6c-engine release:]
+     Add support for SureWare crypto accelerator cards from 
+     Baltimore Technologies.  (Use engine 'sureware')
+     [Baltimore Technologies and Mark Cox]
+
+  *) [In 0.9.6c-engine release:]
+     Add support for crypto accelerator cards from Accelerated
+     Encryption Processing, www.aep.ie.  (Use engine 'aep')
+     [AEP Inc. and Mark Cox]
+
+  *) Add a configuration entry for gcc on UnixWare.
+     [Gary Benson <gbenson@redhat.com>]
+
+  *) Change ssl/s2_clnt.c and ssl/s2_srvr.c so that received handshake
+     messages are stored in a single piece (fixed-length part and
+     variable-length part combined) and fix various bugs found on the way.
+     [Bodo Moeller]
+
+  *) Disable caching in BIO_gethostbyname(), directly use gethostbyname()
+     instead.  BIO_gethostbyname() does not know what timeouts are
+     appropriate, so entries would stay in cache even when they have
+     become invalid.
+     [Bodo Moeller; problem pointed out by Rich Salz <rsalz@zolera.com>
+
+  *) Change ssl23_get_client_hello (ssl/s23_srvr.c) behaviour when
+     faced with a pathologically small ClientHello fragment that does
+     not contain client_version: Instead of aborting with an error,
+     simply choose the highest available protocol version (i.e.,
+     TLS 1.0 unless it is disabled).  In practice, ClientHello
+     messages are never sent like this, but this change gives us
+     strictly correct behaviour at least for TLS.
+     [Bodo Moeller]
+
+  *) Fix SSL handshake functions and SSL_clear() such that SSL_clear()
+     never resets s->method to s->ctx->method when called from within
+     one of the SSL handshake functions.
+     [Bodo Moeller; problem pointed out by Niko Baric]
+
+  *) In ssl3_get_client_hello (ssl/s3_srvr.c), generate a fatal alert
+     (sent using the client's version number) if client_version is
+     smaller than the protocol version in use.  Also change
+     ssl23_get_client_hello (ssl/s23_srvr.c) to select TLS 1.0 if
+     the client demanded SSL 3.0 but only TLS 1.0 is enabled; then
+     the client will at least see that alert.
+     [Bodo Moeller]
+
+  *) Fix ssl3_get_message (ssl/s3_both.c) to handle message fragmentation
+     correctly.
+     [Bodo Moeller]
+
+  *) Avoid infinite loop in ssl3_get_message (ssl/s3_both.c) if a
+     client receives HelloRequest while in a handshake.
+     [Bodo Moeller; bug noticed by Andy Schneider <andy.schneider@bjss.co.uk>]
+
+  *) Bugfix in ssl3_accept (ssl/s3_srvr.c): Case SSL3_ST_SW_HELLO_REQ_C
+     should end in 'break', not 'goto end' which circumvents various
+     cleanups done in state SSL_ST_OK.   But session related stuff
+     must be disabled for SSL_ST_OK in the case that we just sent a
+     HelloRequest.
+
+     Also avoid some overhead by not calling ssl_init_wbio_buffer()
+     before just sending a HelloRequest.
+     [Bodo Moeller, Eric Rescorla <ekr@rtfm.com>]
+
+  *) Fix ssl/s3_enc.c, ssl/t1_enc.c and ssl/s3_pkt.c so that we don't
+     reveal whether illegal block cipher padding was found or a MAC
+     verification error occurred.  (Neither SSLerr() codes nor alerts
+     are directly visible to potential attackers, but the information
+     may leak via logfiles.)
+
+     Similar changes are not required for the SSL 2.0 implementation
+     because the number of padding bytes is sent in clear for SSL 2.0,
+     and the extra bytes are just ignored.  However ssl/s2_pkt.c
+     failed to verify that the purported number of padding bytes is in
+     the legal range.
+     [Bodo Moeller]
+
+  *) Add OpenUNIX-8 support including shared libraries
+     (Boyd Lynn Gerber <gerberb@zenez.com>).
+     [Lutz Jaenicke]
+
+  *) Improve RSA_padding_check_PKCS1_OAEP() check again to avoid
+     'wristwatch attack' using huge encoding parameters (cf.
+     James H. Manger's CRYPTO 2001 paper).  Note that the
+     RSA_PKCS1_OAEP_PADDING case of RSA_private_decrypt() does not use
+     encoding parameters and hence was not vulnerable.
+     [Bodo Moeller]
+
+  *) BN_sqr() bug fix.
+     [Ulf MÃ¶ller, reported by Jim Ellis <jim.ellis@cavium.com>]
+
+  *) Rabin-Miller test analyses assume uniformly distributed witnesses,
+     so use BN_pseudo_rand_range() instead of using BN_pseudo_rand()
+     followed by modular reduction.
+     [Bodo Moeller; pointed out by Adam Young <AYoung1@NCSUS.JNJ.COM>]
+
+  *) Add BN_pseudo_rand_range() with obvious functionality: BN_rand_range()
+     equivalent based on BN_pseudo_rand() instead of BN_rand().
+     [Bodo Moeller]
+
+  *) s3_srvr.c: allow sending of large client certificate lists (> 16 kB).
+     This function was broken, as the check for a new client hello message
+     to handle SGC did not allow these large messages.
+     (Tracked down by "Douglas E. Engert" <deengert@anl.gov>.)
+     [Lutz Jaenicke]
+
+  *) Add alert descriptions for TLSv1 to SSL_alert_desc_string[_long]().
+     [Lutz Jaenicke]
+
+  *) Fix buggy behaviour of BIO_get_num_renegotiates() and BIO_ctrl()
+     for BIO_C_GET_WRITE_BUF_SIZE ("Stephen Hinton" <shinton@netopia.com>).
+     [Lutz Jaenicke]
+
+  *) Rework the configuration and shared library support for Tru64 Unix.
+     The configuration part makes use of modern compiler features and
+     still retains old compiler behavior for those that run older versions
+     of the OS.  The shared library support part includes a variant that
+     uses the RPATH feature, and is available through the special
+     configuration target "alpha-cc-rpath", which will never be selected
+     automatically.
+     [Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu> via Richard Levitte]
+
+  *) In ssl3_get_key_exchange (ssl/s3_clnt.c), call ssl3_get_message()
+     with the same message size as in ssl3_get_certificate_request().
+     Otherwise, if no ServerKeyExchange message occurs, CertificateRequest
+     messages might inadvertently be reject as too long.
+     [Petr Lampa <lampa@fee.vutbr.cz>]
+
+  *) Enhanced support for IA-64 Unix platforms (well, Linux and HP-UX).
+     [Andy Polyakov]
+
+  *) Modified SSL library such that the verify_callback that has been set
+     specificly for an SSL object with SSL_set_verify() is actually being
+     used. Before the change, a verify_callback set with this function was
+     ignored and the verify_callback() set in the SSL_CTX at the time of
+     the call was used. New function X509_STORE_CTX_set_verify_cb() introduced
+     to allow the necessary settings.
+     [Lutz Jaenicke]
+
+  *) Initialize static variable in crypto/dsa/dsa_lib.c and crypto/dh/dh_lib.c
+     explicitly to NULL, as at least on Solaris 8 this seems not always to be
+     done automatically (in contradiction to the requirements of the C
+     standard). This made problems when used from OpenSSH.
+     [Lutz Jaenicke]
+
+  *) In OpenSSL 0.9.6a and 0.9.6b, crypto/dh/dh_key.c ignored
+     dh->length and always used
+
+          BN_rand_range(priv_key, dh->p).
+
+     BN_rand_range() is not necessary for Diffie-Hellman, and this
+     specific range makes Diffie-Hellman unnecessarily inefficient if
+     dh->length (recommended exponent length) is much smaller than the
+     length of dh->p.  We could use BN_rand_range() if the order of
+     the subgroup was stored in the DH structure, but we only have
+     dh->length.
+
+     So switch back to
+
+          BN_rand(priv_key, l, ...)
+
+     where 'l' is dh->length if this is defined, or BN_num_bits(dh->p)-1
+     otherwise.
+     [Bodo Moeller]
+
+  *) In
+
+          RSA_eay_public_encrypt
+          RSA_eay_private_decrypt
+          RSA_eay_private_encrypt (signing)
+          RSA_eay_public_decrypt (signature verification)
+
+     (default implementations for RSA_public_encrypt,
+     RSA_private_decrypt, RSA_private_encrypt, RSA_public_decrypt),
+     always reject numbers >= n.
+     [Bodo Moeller]
+
+  *) In crypto/rand/md_rand.c, use a new short-time lock CRYPTO_LOCK_RAND2
+     to synchronize access to 'locking_thread'.  This is necessary on
+     systems where access to 'locking_thread' (an 'unsigned long'
+     variable) is not atomic.
+     [Bodo Moeller]
+
+  *) In crypto/rand/md_rand.c, set 'locking_thread' to current thread's ID
+     *before* setting the 'crypto_lock_rand' flag.  The previous code had
+     a race condition if 0 is a valid thread ID.
+     [Travis Vitek <vitek@roguewave.com>]
+
+  *) Add support for shared libraries under Irix.
+     [Albert Chin-A-Young <china@thewrittenword.com>]
+
+  *) Add configuration option to build on Linux on both big-endian and
+     little-endian MIPS.
+     [Ralf Baechle <ralf@uni-koblenz.de>]
+
+  *) Add the possibility to create shared libraries on HP-UX.
+     [Richard Levitte]
+
+ Changes between 0.9.6a and 0.9.6b  [9 Jul 2001]
+
+  *) Change ssleay_rand_bytes (crypto/rand/md_rand.c)
+     to avoid a SSLeay/OpenSSL PRNG weakness pointed out by
+     Markku-Juhani O. Saarinen <markku-juhani.saarinen@nokia.com>:
+     PRNG state recovery was possible based on the output of
+     one PRNG request appropriately sized to gain knowledge on
+     'md' followed by enough consecutive 1-byte PRNG requests
+     to traverse all of 'state'.
+
+     1. When updating 'md_local' (the current thread's copy of 'md')
+        during PRNG output generation, hash all of the previous
+        'md_local' value, not just the half used for PRNG output.
+
+     2. Make the number of bytes from 'state' included into the hash
+        independent from the number of PRNG bytes requested.
+
+     The first measure alone would be sufficient to avoid
+     Markku-Juhani's attack.  (Actually it had never occurred
+     to me that the half of 'md_local' used for chaining was the
+     half from which PRNG output bytes were taken -- I had always
+     assumed that the secret half would be used.)  The second
+     measure makes sure that additional data from 'state' is never
+     mixed into 'md_local' in small portions; this heuristically
+     further strengthens the PRNG.
+     [Bodo Moeller]
+
+  *) Fix crypto/bn/asm/mips3.s.
+     [Andy Polyakov]
+
+  *) When only the key is given to "enc", the IV is undefined. Print out
+     an error message in this case.
+     [Lutz Jaenicke]
+
+  *) Handle special case when X509_NAME is empty in X509 printing routines.
+     [Steve Henson]
+
+  *) In dsa_do_verify (crypto/dsa/dsa_ossl.c), verify that r and s are
+     positive and less than q.
+     [Bodo Moeller]
+
+  *) Don't change *pointer in CRYPTO_add_lock() is add_lock_callback is
+     used: it isn't thread safe and the add_lock_callback should handle
+     that itself.
+     [Paul Rose <Paul.Rose@bridge.com>]
+
+  *) Verify that incoming data obeys the block size in
+     ssl3_enc (ssl/s3_enc.c) and tls1_enc (ssl/t1_enc.c).
+     [Bodo Moeller]
+
+  *) Fix OAEP check.
+     [Ulf MÃ¶ller, Bodo MÃ¶ller]
+
+  *) The countermeasure against Bleichbacher's attack on PKCS #1 v1.5
+     RSA encryption was accidentally removed in s3_srvr.c in OpenSSL 0.9.5
+     when fixing the server behaviour for backwards-compatible 'client
+     hello' messages.  (Note that the attack is impractical against
+     SSL 3.0 and TLS 1.0 anyway because length and version checking
+     means that the probability of guessing a valid ciphertext is
+     around 2^-40; see section 5 in Bleichenbacher's CRYPTO '98
+     paper.)
+
+     Before 0.9.5, the countermeasure (hide the error by generating a
+     random 'decryption result') did not work properly because
+     ERR_clear_error() was missing, meaning that SSL_get_error() would
+     detect the supposedly ignored error.
+
+     Both problems are now fixed.
+     [Bodo Moeller]
+
+  *) In crypto/bio/bf_buff.c, increase DEFAULT_BUFFER_SIZE to 4096
+     (previously it was 1024).
+     [Bodo Moeller]
+
+  *) Fix for compatibility mode trust settings: ignore trust settings
+     unless some valid trust or reject settings are present.
+     [Steve Henson]
+
+  *) Fix for blowfish EVP: its a variable length cipher.
+     [Steve Henson]
+
+  *) Fix various bugs related to DSA S/MIME verification. Handle missing
+     parameters in DSA public key structures and return an error in the
+     DSA routines if parameters are absent.
+     [Steve Henson]
+
+  *) In versions up to 0.9.6, RAND_file_name() resorted to file ".rnd"
+     in the current directory if neither $RANDFILE nor $HOME was set.
+     RAND_file_name() in 0.9.6a returned NULL in this case.  This has
+     caused some confusion to Windows users who haven't defined $HOME.
+     Thus RAND_file_name() is changed again: e_os.h can define a
+     DEFAULT_HOME, which will be used if $HOME is not set.
+     For Windows, we use "C:"; on other platforms, we still require
+     environment variables.
+
+  *) Move 'if (!initialized) RAND_poll()' into regions protected by
+     CRYPTO_LOCK_RAND.  This is not strictly necessary, but avoids
+     having multiple threads call RAND_poll() concurrently.
+     [Bodo Moeller]
+
+  *) In crypto/rand/md_rand.c, replace 'add_do_not_lock' flag by a
+     combination of a flag and a thread ID variable.
+     Otherwise while one thread is in ssleay_rand_bytes (which sets the
+     flag), *other* threads can enter ssleay_add_bytes without obeying
+     the CRYPTO_LOCK_RAND lock (and may even illegally release the lock
+     that they do not hold after the first thread unsets add_do_not_lock).
+     [Bodo Moeller]
+
+  *) Change bctest again: '-x' expressions are not available in all
+     versions of 'test'.
+     [Bodo Moeller]
+
+ Changes between 0.9.6 and 0.9.6a  [5 Apr 2001]
+
+  *) Fix a couple of memory leaks in PKCS7_dataDecode()
+     [Steve Henson, reported by Heyun Zheng <hzheng@atdsprint.com>]
+
+  *) Change Configure and Makefiles to provide EXE_EXT, which will contain
+     the default extension for executables, if any.  Also, make the perl
+     scripts that use symlink() to test if it really exists and use "cp"
+     if it doesn't.  All this made OpenSSL compilable and installable in
+     CygWin.
+     [Richard Levitte]
+
+  *) Fix for asn1_GetSequence() for indefinite length constructed data.
+     If SEQUENCE is length is indefinite just set c->slen to the total
+     amount of data available.
+     [Steve Henson, reported by shige@FreeBSD.org]
+     [This change does not apply to 0.9.7.]
+
+  *) Change bctest to avoid here-documents inside command substitution
+     (workaround for FreeBSD /bin/sh bug).
+     For compatibility with Ultrix, avoid shell functions (introduced
+     in the bctest version that searches along $PATH).
+     [Bodo Moeller]
+
+  *) Rename 'des_encrypt' to 'des_encrypt1'.  This avoids the clashes
+     with des_encrypt() defined on some operating systems, like Solaris
+     and UnixWare.
+     [Richard Levitte]
+
+  *) Check the result of RSA-CRT (see D. Boneh, R. DeMillo, R. Lipton:
+     On the Importance of Eliminating Errors in Cryptographic
+     Computations, J. Cryptology 14 (2001) 2, 101-119,
+     http://theory.stanford.edu/~dabo/papers/faults.ps.gz).
+     [Ulf Moeller]
+  
+  *) MIPS assembler BIGNUM division bug fix. 
+     [Andy Polyakov]
+
+  *) Disabled incorrect Alpha assembler code.
+     [Richard Levitte]
+
+  *) Fix PKCS#7 decode routines so they correctly update the length
+     after reading an EOC for the EXPLICIT tag.
+     [Steve Henson]
+     [This change does not apply to 0.9.7.]
+
+  *) Fix bug in PKCS#12 key generation routines. This was triggered
+     if a 3DES key was generated with a 0 initial byte. Include
+     PKCS12_BROKEN_KEYGEN compilation option to retain the old
+     (but broken) behaviour.
+     [Steve Henson]
+
+  *) Enhance bctest to search for a working bc along $PATH and print
+     it when found.
+     [Tim Rice <tim@multitalents.net> via Richard Levitte]
+
+  *) Fix memory leaks in err.c: free err_data string if necessary;
+     don't write to the wrong index in ERR_set_error_data.
+     [Bodo Moeller]
+
+  *) Implement ssl23_peek (analogous to ssl23_read), which previously
+     did not exist.
+     [Bodo Moeller]
+
+  *) Replace rdtsc with _emit statements for VC++ version 5.
+     [Jeremy Cooper <jeremy@baymoo.org>]
+
+  *) Make it possible to reuse SSLv2 sessions.
+     [Richard Levitte]
+
+  *) In copy_email() check for >= 0 as a return value for
+     X509_NAME_get_index_by_NID() since 0 is a valid index.
+     [Steve Henson reported by Massimiliano Pala <madwolf@opensca.org>]
+
+  *) Avoid coredump with unsupported or invalid public keys by checking if
+     X509_get_pubkey() fails in PKCS7_verify(). Fix memory leak when
+     PKCS7_verify() fails with non detached data.
+     [Steve Henson]
+
+  *) Don't use getenv in library functions when run as setuid/setgid.
+     New function OPENSSL_issetugid().
+     [Ulf Moeller]
+
+  *) Avoid false positives in memory leak detection code (crypto/mem_dbg.c)
+     due to incorrect handling of multi-threading:
+
+     1. Fix timing glitch in the MemCheck_off() portion of CRYPTO_mem_ctrl().
+
+     2. Fix logical glitch in is_MemCheck_on() aka CRYPTO_is_mem_check_on().
+
+     3. Count how many times MemCheck_off() has been called so that
+        nested use can be treated correctly.  This also avoids 
+        inband-signalling in the previous code (which relied on the
+        assumption that thread ID 0 is impossible).
+     [Bodo Moeller]
+
+  *) Add "-rand" option also to s_client and s_server.
+     [Lutz Jaenicke]
+
+  *) Fix CPU detection on Irix 6.x.
+     [Kurt Hockenbury <khockenb@stevens-tech.edu> and
+      "Bruce W. Forsberg" <bruce.forsberg@baesystems.com>]
+
+  *) Fix X509_NAME bug which produced incorrect encoding if X509_NAME
+     was empty.
+     [Steve Henson]
+     [This change does not apply to 0.9.7.]
+
+  *) Use the cached encoding of an X509_NAME structure rather than
+     copying it. This is apparently the reason for the libsafe "errors"
+     but the code is actually correct.
+     [Steve Henson]
+
+  *) Add new function BN_rand_range(), and fix DSA_sign_setup() to prevent
+     Bleichenbacher's DSA attack.
+     Extend BN_[pseudo_]rand: As before, top=1 forces the highest two bits
+     to be set and top=0 forces the highest bit to be set; top=-1 is new
+     and leaves the highest bit random.
+     [Ulf Moeller, Bodo Moeller]
+
+  *) In the NCONF_...-based implementations for CONF_... queries
+     (crypto/conf/conf_lib.c), if the input LHASH is NULL, avoid using
+     a temporary CONF structure with the data component set to NULL
+     (which gives segmentation faults in lh_retrieve).
+     Instead, use NULL for the CONF pointer in CONF_get_string and
+     CONF_get_number (which may use environment variables) and directly
+     return NULL from CONF_get_section.
+     [Bodo Moeller]
+
+  *) Fix potential buffer overrun for EBCDIC.
+     [Ulf Moeller]
+
+  *) Tolerate nonRepudiation as being valid for S/MIME signing and certSign
+     keyUsage if basicConstraints absent for a CA.
+     [Steve Henson]
+
+  *) Make SMIME_write_PKCS7() write mail header values with a format that
+     is more generally accepted (no spaces before the semicolon), since
+     some programs can't parse those values properly otherwise.  Also make
+     sure BIO's that break lines after each write do not create invalid
+     headers.
+     [Richard Levitte]
+
+  *) Make the CRL encoding routines work with empty SEQUENCE OF. The
+     macros previously used would not encode an empty SEQUENCE OF
+     and break the signature.
+     [Steve Henson]
+     [This change does not apply to 0.9.7.]
+
+  *) Zero the premaster secret after deriving the master secret in
+     DH ciphersuites.
+     [Steve Henson]
+
+  *) Add some EVP_add_digest_alias registrations (as found in
+     OpenSSL_add_all_digests()) to SSL_library_init()
+     aka OpenSSL_add_ssl_algorithms().  This provides improved
+     compatibility with peers using X.509 certificates
+     with unconventional AlgorithmIdentifier OIDs.
+     [Bodo Moeller]
+
+  *) Fix for Irix with NO_ASM.
+     ["Bruce W. Forsberg" <bruce.forsberg@baesystems.com>]
+
+  *) ./config script fixes.
+     [Ulf Moeller, Richard Levitte]
+
+  *) Fix 'openssl passwd -1'.
+     [Bodo Moeller]
+
+  *) Change PKCS12_key_gen_asc() so it can cope with non null
+     terminated strings whose length is passed in the passlen
+     parameter, for example from PEM callbacks. This was done
+     by adding an extra length parameter to asc2uni().
+     [Steve Henson, reported by <oddissey@samsung.co.kr>]
+
+  *) Fix C code generated by 'openssl dsaparam -C': If a BN_bin2bn
+     call failed, free the DSA structure.
+     [Bodo Moeller]
+
+  *) Fix to uni2asc() to cope with zero length Unicode strings.
+     These are present in some PKCS#12 files.
+     [Steve Henson]
+
+  *) Increase s2->wbuf allocation by one byte in ssl2_new (ssl/s2_lib.c).
+     Otherwise do_ssl_write (ssl/s2_pkt.c) will write beyond buffer limits
+     when writing a 32767 byte record.
+     [Bodo Moeller; problem reported by Eric Day <eday@concentric.net>]
+
+  *) In RSA_eay_public_{en,ed}crypt and RSA_eay_mod_exp (rsa_eay.c),
+     obtain lock CRYPTO_LOCK_RSA before setting rsa->_method_mod_{n,p,q}.
+
+     (RSA objects have a reference count access to which is protected
+     by CRYPTO_LOCK_RSA [see rsa_lib.c, s3_srvr.c, ssl_cert.c, ssl_rsa.c],
+     so they are meant to be shared between threads.)
+     [Bodo Moeller, Geoff Thorpe; original patch submitted by
+     "Reddie, Steven" <Steven.Reddie@ca.com>]
+
+  *) Fix a deadlock in CRYPTO_mem_leaks().
+     [Bodo Moeller]
+
+  *) Use better test patterns in bntest.
+     [Ulf MÃ¶ller]
+
+  *) rand_win.c fix for Borland C.
+     [Ulf MÃ¶ller]
+ 
+  *) BN_rshift bugfix for n == 0.
+     [Bodo Moeller]
+
+  *) Add a 'bctest' script that checks for some known 'bc' bugs
+     so that 'make test' does not abort just because 'bc' is broken.
+     [Bodo Moeller]
+
+  *) Store verify_result within SSL_SESSION also for client side to
+     avoid potential security hole. (Re-used sessions on the client side
+     always resulted in verify_result==X509_V_OK, not using the original
+     result of the server certificate verification.)
+     [Lutz Jaenicke]
+
+  *) Fix ssl3_pending: If the record in s->s3->rrec is not of type
+     SSL3_RT_APPLICATION_DATA, return 0.
+     Similarly, change ssl2_pending to return 0 if SSL_in_init(s) is true.
+     [Bodo Moeller]
+
+  *) Fix SSL_peek:
+     Both ssl2_peek and ssl3_peek, which were totally broken in earlier
+     releases, have been re-implemented by renaming the previous
+     implementations of ssl2_read and ssl3_read to ssl2_read_internal
+     and ssl3_read_internal, respectively, and adding 'peek' parameters
+     to them.  The new ssl[23]_{read,peek} functions are calls to
+     ssl[23]_read_internal with the 'peek' flag set appropriately.
+     A 'peek' parameter has also been added to ssl3_read_bytes, which
+     does the actual work for ssl3_read_internal.
+     [Bodo Moeller]
+
+  *) Initialise "ex_data" member of RSA/DSA/DH structures prior to calling
+     the method-specific "init()" handler. Also clean up ex_data after
+     calling the method-specific "finish()" handler. Previously, this was
+     happening the other way round.
+     [Geoff Thorpe]
+
+  *) Increase BN_CTX_NUM (the number of BIGNUMs in a BN_CTX) to 16.
+     The previous value, 12, was not always sufficient for BN_mod_exp().
+     [Bodo Moeller]
+
+  *) Make sure that shared libraries get the internal name engine with
+     the full version number and not just 0.  This should mark the
+     shared libraries as not backward compatible.  Of course, this should
+     be changed again when we can guarantee backward binary compatibility.
+     [Richard Levitte]
+
+  *) Fix typo in get_cert_by_subject() in by_dir.c
+     [Jean-Marc Desperrier <jean-marc.desperrier@certplus.com>]
+
+  *) Rework the system to generate shared libraries:
+
+     - Make note of the expected extension for the shared libraries and
+       if there is a need for symbolic links from for example libcrypto.so.0
+       to libcrypto.so.0.9.7.  There is extended info in Configure for
+       that.
+
+     - Make as few rebuilds of the shared libraries as possible.
+
+     - Still avoid linking the OpenSSL programs with the shared libraries.
+
+     - When installing, install the shared libraries separately from the
+       static ones.
+     [Richard Levitte]
+
+  *) Fix SSL_CTX_set_read_ahead macro to actually use its argument.
+
+     Copy SSL_CTX's read_ahead flag to SSL object directly in SSL_new
+     and not in SSL_clear because the latter is also used by the
+     accept/connect functions; previously, the settings made by
+     SSL_set_read_ahead would be lost during the handshake.
+     [Bodo Moeller; problems reported by Anders Gertz <gertz@epact.se>]     
+
+  *) Correct util/mkdef.pl to be selective about disabled algorithms.
+     Previously, it would create entries for disabled algorithms no
+     matter what.
+     [Richard Levitte]
+
+  *) Added several new manual pages for SSL_* function.
+     [Lutz Jaenicke]
+
+ Changes between 0.9.5a and 0.9.6  [24 Sep 2000]
+
+  *) In ssl23_get_client_hello, generate an error message when faced
+     with an initial SSL 3.0/TLS record that is too small to contain the
+     first two bytes of the ClientHello message, i.e. client_version.
+     (Note that this is a pathologic case that probably has never happened
+     in real life.)  The previous approach was to use the version number
+     from the record header as a substitute; but our protocol choice
+     should not depend on that one because it is not authenticated
+     by the Finished messages.
+     [Bodo Moeller]
+
+  *) More robust randomness gathering functions for Windows.
+     [Jeffrey Altman <jaltman@columbia.edu>]
+
+  *) For compatibility reasons if the flag X509_V_FLAG_ISSUER_CHECK is
+     not set then we don't setup the error code for issuer check errors
+     to avoid possibly overwriting other errors which the callback does
+     handle. If an application does set the flag then we assume it knows
+     what it is doing and can handle the new informational codes
+     appropriately.
+     [Steve Henson]
+
+  *) Fix for a nasty bug in ASN1_TYPE handling. ASN1_TYPE is used for
+     a general "ANY" type, as such it should be able to decode anything
+     including tagged types. However it didn't check the class so it would
+     wrongly interpret tagged types in the same way as their universal
+     counterpart and unknown types were just rejected. Changed so that the
+     tagged and unknown types are handled in the same way as a SEQUENCE:
+     that is the encoding is stored intact. There is also a new type
+     "V_ASN1_OTHER" which is used when the class is not universal, in this
+     case we have no idea what the actual type is so we just lump them all
+     together.
+     [Steve Henson]
+
+  *) On VMS, stdout may very well lead to a file that is written to
+     in a record-oriented fashion.  That means that every write() will
+     write a separate record, which will be read separately by the
+     programs trying to read from it.  This can be very confusing.
+
+     The solution is to put a BIO filter in the way that will buffer
+     text until a linefeed is reached, and then write everything a
+     line at a time, so every record written will be an actual line,
+     not chunks of lines and not (usually doesn't happen, but I've
+     seen it once) several lines in one record.  BIO_f_linebuffer() is
+     the answer.
+
+     Currently, it's a VMS-only method, because that's where it has
+     been tested well enough.
+     [Richard Levitte]
+
+  *) Remove 'optimized' squaring variant in BN_mod_mul_montgomery,
+     it can return incorrect results.
+     (Note: The buggy variant was not enabled in OpenSSL 0.9.5a,
+     but it was in 0.9.6-beta[12].)
+     [Bodo Moeller]
+
+  *) Disable the check for content being present when verifying detached
+     signatures in pk7_smime.c. Some versions of Netscape (wrongly)
+     include zero length content when signing messages.
+     [Steve Henson]
+
+  *) New BIO_shutdown_wr macro, which invokes the BIO_C_SHUTDOWN_WR
+     BIO_ctrl (for BIO pairs).
+     [Bodo MÃ¶ller]
+
+  *) Add DSO method for VMS.
+     [Richard Levitte]
+
+  *) Bug fix: Montgomery multiplication could produce results with the
+     wrong sign.
+     [Ulf MÃ¶ller]
+
+  *) Add RPM specification openssl.spec and modify it to build three
+     packages.  The default package contains applications, application
+     documentation and run-time libraries.  The devel package contains
+     include files, static libraries and function documentation.  The
+     doc package contains the contents of the doc directory.  The original
+     openssl.spec was provided by Damien Miller <djm@mindrot.org>.
+     [Richard Levitte]
+     
+  *) Add a large number of documentation files for many SSL routines.
+     [Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE>]
+
+  *) Add a configuration entry for Sony News 4.
+     [NAKAJI Hiroyuki <nakaji@tutrp.tut.ac.jp>]
+
+  *) Don't set the two most significant bits to one when generating a
+     random number < q in the DSA library.
+     [Ulf MÃ¶ller]
+
+  *) New SSL API mode 'SSL_MODE_AUTO_RETRY'.  This disables the default
+     behaviour that SSL_read may result in SSL_ERROR_WANT_READ (even if
+     the underlying transport is blocking) if a handshake took place.
+     (The default behaviour is needed by applications such as s_client
+     and s_server that use select() to determine when to use SSL_read;
+     but for applications that know in advance when to expect data, it
+     just makes things more complicated.)
+     [Bodo Moeller]
+
+  *) Add RAND_egd_bytes(), which gives control over the number of bytes read
+     from EGD.
+     [Ben Laurie]
+
+  *) Add a few more EBCDIC conditionals that make `req' and `x509'
+     work better on such systems.
+     [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>]
+
+  *) Add two demo programs for PKCS12_parse() and PKCS12_create().
+     Update PKCS12_parse() so it copies the friendlyName and the
+     keyid to the certificates aux info.
+     [Steve Henson]
+
+  *) Fix bug in PKCS7_verify() which caused an infinite loop
+     if there was more than one signature.
+     [Sven Uszpelkat <su@celocom.de>]
+
+  *) Major change in util/mkdef.pl to include extra information
+     about each symbol, as well as presenting variables as well
+     as functions.  This change means that there's n more need
+     to rebuild the .num files when some algorithms are excluded.
+     [Richard Levitte]
+
+  *) Allow the verify time to be set by an application,
+     rather than always using the current time.
+     [Steve Henson]
+  
+  *) Phase 2 verify code reorganisation. The certificate
+     verify code now looks up an issuer certificate by a
+     number of criteria: subject name, authority key id
+     and key usage. It also verifies self signed certificates
+     by the same criteria. The main comparison function is
+     X509_check_issued() which performs these checks.
+ 
+     Lot of changes were necessary in order to support this
+     without completely rewriting the lookup code.
+ 
+     Authority and subject key identifier are now cached.
+ 
+     The LHASH 'certs' is X509_STORE has now been replaced
+     by a STACK_OF(X509_OBJECT). This is mainly because an
+     LHASH can't store or retrieve multiple objects with
+     the same hash value.
+
+     As a result various functions (which were all internal
+     use only) have changed to handle the new X509_STORE
+     structure. This will break anything that messed round
+     with X509_STORE internally.
+ 
+     The functions X509_STORE_add_cert() now checks for an
+     exact match, rather than just subject name.
+ 
+     The X509_STORE API doesn't directly support the retrieval
+     of multiple certificates matching a given criteria, however
+     this can be worked round by performing a lookup first
+     (which will fill the cache with candidate certificates)
+     and then examining the cache for matches. This is probably
+     the best we can do without throwing out X509_LOOKUP
+     entirely (maybe later...).
+ 
+     The X509_VERIFY_CTX structure has been enhanced considerably.
+ 
+     All certificate lookup operations now go via a get_issuer()
+     callback. Although this currently uses an X509_STORE it
+     can be replaced by custom lookups. This is a simple way
+     to bypass the X509_STORE hackery necessary to make this
+     work and makes it possible to use more efficient techniques
+     in future. A very simple version which uses a simple
+     STACK for its trusted certificate store is also provided
+     using X509_STORE_CTX_trusted_stack().
+ 
+     The verify_cb() and verify() callbacks now have equivalents
+     in the X509_STORE_CTX structure.
+ 
+     X509_STORE_CTX also has a 'flags' field which can be used
+     to customise the verify behaviour.
+     [Steve Henson]
+ 
+  *) Add new PKCS#7 signing option PKCS7_NOSMIMECAP which 
+     excludes S/MIME capabilities.
+     [Steve Henson]
+
+  *) When a certificate request is read in keep a copy of the
+     original encoding of the signed data and use it when outputting
+     again. Signatures then use the original encoding rather than
+     a decoded, encoded version which may cause problems if the
+     request is improperly encoded.
+     [Steve Henson]
+
+  *) For consistency with other BIO_puts implementations, call
+     buffer_write(b, ...) directly in buffer_puts instead of calling
+     BIO_write(b, ...).
+
+     In BIO_puts, increment b->num_write as in BIO_write.
+     [Peter.Sylvester@EdelWeb.fr]
+
+  *) Fix BN_mul_word for the case where the word is 0. (We have to use
+     BN_zero, we may not return a BIGNUM with an array consisting of
+     words set to zero.)
+     [Bodo Moeller]
+
+  *) Avoid calling abort() from within the library when problems are
+     detected, except if preprocessor symbols have been defined
+     (such as REF_CHECK, BN_DEBUG etc.).
+     [Bodo Moeller]
+
+  *) New openssl application 'rsautl'. This utility can be
+     used for low level RSA operations. DER public key
+     BIO/fp routines also added.
+     [Steve Henson]
+
+  *) New Configure entry and patches for compiling on QNX 4.
+     [Andreas Schneider <andreas@ds3.etech.fh-hamburg.de>]
+
+  *) A demo state-machine implementation was sponsored by
+     Nuron (http://www.nuron.com/) and is now available in
+     demos/state_machine.
+     [Ben Laurie]
+
+  *) New options added to the 'dgst' utility for signature
+     generation and verification.
+     [Steve Henson]
+
+  *) Unrecognized PKCS#7 content types are now handled via a
+     catch all ASN1_TYPE structure. This allows unsupported
+     types to be stored as a "blob" and an application can
+     encode and decode it manually.
+     [Steve Henson]
+
+  *) Fix various signed/unsigned issues to make a_strex.c
+     compile under VC++.
+     [Oscar Jacobsson <oscar.jacobsson@celocom.com>]
+
+  *) ASN1 fixes. i2d_ASN1_OBJECT was not returning the correct
+     length if passed a buffer. ASN1_INTEGER_to_BN failed
+     if passed a NULL BN and its argument was negative.
+     [Steve Henson, pointed out by Sven Heiberg <sven@tartu.cyber.ee>]
+
+  *) Modification to PKCS#7 encoding routines to output definite
+     length encoding. Since currently the whole structures are in
+     memory there's not real point in using indefinite length 
+     constructed encoding. However if OpenSSL is compiled with
+     the flag PKCS7_INDEFINITE_ENCODING the old form is used.
+     [Steve Henson]
+
+  *) Added BIO_vprintf() and BIO_vsnprintf().
+     [Richard Levitte]
+
+  *) Added more prefixes to parse for in the the strings written
+     through a logging bio, to cover all the levels that are available
+     through syslog.  The prefixes are now:
+
+	PANIC, EMERG, EMR	=>	LOG_EMERG
+	ALERT, ALR		=>	LOG_ALERT
+	CRIT, CRI		=>	LOG_CRIT
+	ERROR, ERR		=>	LOG_ERR
+	WARNING, WARN, WAR	=>	LOG_WARNING
+	NOTICE, NOTE, NOT	=>	LOG_NOTICE
+	INFO, INF		=>	LOG_INFO
+	DEBUG, DBG		=>	LOG_DEBUG
+
+     and as before, if none of those prefixes are present at the
+     beginning of the string, LOG_ERR is chosen.
+
+     On Win32, the LOG_* levels are mapped according to this:
+
+	LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR	=> EVENTLOG_ERROR_TYPE
+	LOG_WARNING				=> EVENTLOG_WARNING_TYPE
+	LOG_NOTICE, LOG_INFO, LOG_DEBUG		=> EVENTLOG_INFORMATION_TYPE
+
+     [Richard Levitte]
+
+  *) Made it possible to reconfigure with just the configuration
+     argument "reconf" or "reconfigure".  The command line arguments
+     are stored in Makefile.ssl in the variable CONFIGURE_ARGS,
+     and are retrieved from there when reconfiguring.
+     [Richard Levitte]
+
+  *) MD4 implemented.
+     [Assar Westerlund <assar@sics.se>, Richard Levitte]
+
+  *) Add the arguments -CAfile and -CApath to the pkcs12 utility.
+     [Richard Levitte]
+
+  *) The obj_dat.pl script was messing up the sorting of object
+     names. The reason was that it compared the quoted version
+     of strings as a result "OCSP" > "OCSP Signing" because
+     " > SPACE. Changed script to store unquoted versions of
+     names and add quotes on output. It was also omitting some
+     names from the lookup table if they were given a default
+     value (that is if SN is missing it is given the same
+     value as LN and vice versa), these are now added on the
+     grounds that if an object has a name we should be able to
+     look it up. Finally added warning output when duplicate
+     short or long names are found.
+     [Steve Henson]
+
+  *) Changes needed for Tandem NSK.
+     [Scott Uroff <scott@xypro.com>]
+
+  *) Fix SSL 2.0 rollback checking: Due to an off-by-one error in
+     RSA_padding_check_SSLv23(), special padding was never detected
+     and thus the SSL 3.0/TLS 1.0 countermeasure against protocol
+     version rollback attacks was not effective.
+
+     In s23_clnt.c, don't use special rollback-attack detection padding
+     (RSA_SSLV23_PADDING) if SSL 2.0 is the only protocol enabled in the
+     client; similarly, in s23_srvr.c, don't do the rollback check if
+     SSL 2.0 is the only protocol enabled in the server.
+     [Bodo Moeller]
+
+  *) Make it possible to get hexdumps of unprintable data with 'openssl
+     asn1parse'.  By implication, the functions ASN1_parse_dump() and
+     BIO_dump_indent() are added.
+     [Richard Levitte]
+
+  *) New functions ASN1_STRING_print_ex() and X509_NAME_print_ex()
+     these print out strings and name structures based on various
+     flags including RFC2253 support and proper handling of
+     multibyte characters. Added options to the 'x509' utility 
+     to allow the various flags to be set.
+     [Steve Henson]
+
+  *) Various fixes to use ASN1_TIME instead of ASN1_UTCTIME.
+     Also change the functions X509_cmp_current_time() and
+     X509_gmtime_adj() work with an ASN1_TIME structure,
+     this will enable certificates using GeneralizedTime in validity
+     dates to be checked.
+     [Steve Henson]
+
+  *) Make the NEG_PUBKEY_BUG code (which tolerates invalid
+     negative public key encodings) on by default,
+     NO_NEG_PUBKEY_BUG can be set to disable it.
+     [Steve Henson]
+
+  *) New function c2i_ASN1_OBJECT() which acts on ASN1_OBJECT
+     content octets. An i2c_ASN1_OBJECT is unnecessary because
+     the encoding can be trivially obtained from the structure.
+     [Steve Henson]
+
+  *) crypto/err.c locking bugfix: Use write locks (CRYPTO_w_[un]lock),
+     not read locks (CRYPTO_r_[un]lock).
+     [Bodo Moeller]
+
+  *) A first attempt at creating official support for shared
+     libraries through configuration.  I've kept it so the
+     default is static libraries only, and the OpenSSL programs
+     are always statically linked for now, but there are
+     preparations for dynamic linking in place.
+     This has been tested on Linux and Tru64.
+     [Richard Levitte]
+
+  *) Randomness polling function for Win9x, as described in:
+     Peter Gutmann, Software Generation of Practically Strong
+     Random Numbers.
+     [Ulf MÃ¶ller]
+
+  *) Fix so PRNG is seeded in req if using an already existing
+     DSA key.
+     [Steve Henson]
+
+  *) New options to smime application. -inform and -outform
+     allow alternative formats for the S/MIME message including
+     PEM and DER. The -content option allows the content to be
+     specified separately. This should allow things like Netscape
+     form signing output easier to verify.
+     [Steve Henson]
+
+  *) Fix the ASN1 encoding of tags using the 'long form'.
+     [Steve Henson]
+
+  *) New ASN1 functions, i2c_* and c2i_* for INTEGER and BIT
+     STRING types. These convert content octets to and from the
+     underlying type. The actual tag and length octets are
+     already assumed to have been read in and checked. These
+     are needed because all other string types have virtually
+     identical handling apart from the tag. By having versions
+     of the ASN1 functions that just operate on content octets
+     IMPLICIT tagging can be handled properly. It also allows
+     the ASN1_ENUMERATED code to be cut down because ASN1_ENUMERATED
+     and ASN1_INTEGER are identical apart from the tag.
+     [Steve Henson]
+
+  *) Change the handling of OID objects as follows:
+
+     - New object identifiers are inserted in objects.txt, following
+       the syntax given in objects.README.
+     - objects.pl is used to process obj_mac.num and create a new
+       obj_mac.h.
+     - obj_dat.pl is used to create a new obj_dat.h, using the data in
+       obj_mac.h.
+
+     This is currently kind of a hack, and the perl code in objects.pl
+     isn't very elegant, but it works as I intended.  The simplest way
+     to check that it worked correctly is to look in obj_dat.h and
+     check the array nid_objs and make sure the objects haven't moved
+     around (this is important!).  Additions are OK, as well as
+     consistent name changes. 
+     [Richard Levitte]
+
+  *) Add BSD-style MD5-based passwords to 'openssl passwd' (option '-1').
+     [Bodo Moeller]
+
+  *) Addition of the command line parameter '-rand file' to 'openssl req'.
+     The given file adds to whatever has already been seeded into the
+     random pool through the RANDFILE configuration file option or
+     environment variable, or the default random state file.
+     [Richard Levitte]
+
+  *) mkstack.pl now sorts each macro group into lexical order.
+     Previously the output order depended on the order the files
+     appeared in the directory, resulting in needless rewriting
+     of safestack.h .
+     [Steve Henson]
+
+  *) Patches to make OpenSSL compile under Win32 again. Mostly
+     work arounds for the VC++ problem that it treats func() as
+     func(void). Also stripped out the parts of mkdef.pl that
+     added extra typesafe functions: these no longer exist.
+     [Steve Henson]
+
+  *) Reorganisation of the stack code. The macros are now all 
+     collected in safestack.h . Each macro is defined in terms of
+     a "stack macro" of the form SKM_<name>(type, a, b). The 
+     DEBUG_SAFESTACK is now handled in terms of function casts,
+     this has the advantage of retaining type safety without the
+     use of additional functions. If DEBUG_SAFESTACK is not defined
+     then the non typesafe macros are used instead. Also modified the
+     mkstack.pl script to handle the new form. Needs testing to see
+     if which (if any) compilers it chokes and maybe make DEBUG_SAFESTACK
+     the default if no major problems. Similar behaviour for ASN1_SET_OF
+     and PKCS12_STACK_OF.
+     [Steve Henson]
+
+  *) When some versions of IIS use the 'NET' form of private key the
+     key derivation algorithm is different. Normally MD5(password) is
+     used as a 128 bit RC4 key. In the modified case
+     MD5(MD5(password) + "SGCKEYSALT")  is used instead. Added some
+     new functions i2d_RSA_NET(), d2i_RSA_NET() etc which are the same
+     as the old Netscape_RSA functions except they have an additional
+     'sgckey' parameter which uses the modified algorithm. Also added
+     an -sgckey command line option to the rsa utility. Thanks to 
+     Adrian Peck <bertie@ncipher.com> for posting details of the modified
+     algorithm to openssl-dev.
+     [Steve Henson]
+
+  *) The evp_local.h macros were using 'c.##kname' which resulted in
+     invalid expansion on some systems (SCO 5.0.5 for example).
+     Corrected to 'c.kname'.
+     [Phillip Porch <root@theporch.com>]
+
+  *) New X509_get1_email() and X509_REQ_get1_email() functions that return
+     a STACK of email addresses from a certificate or request, these look
+     in the subject name and the subject alternative name extensions and 
+     omit any duplicate addresses.
+     [Steve Henson]
+
+  *) Re-implement BN_mod_exp2_mont using independent (and larger) windows.
+     This makes DSA verification about 2 % faster.
+     [Bodo Moeller]
+
+  *) Increase maximum window size in BN_mod_exp_... to 6 bits instead of 5
+     (meaning that now 2^5 values will be precomputed, which is only 4 KB
+     plus overhead for 1024 bit moduli).
+     This makes exponentiations about 0.5 % faster for 1024 bit
+     exponents (as measured by "openssl speed rsa2048").
+     [Bodo Moeller]
+
+  *) Rename memory handling macros to avoid conflicts with other
+     software:
+          Malloc         =>  OPENSSL_malloc
+          Malloc_locked  =>  OPENSSL_malloc_locked
+          Realloc        =>  OPENSSL_realloc
+          Free           =>  OPENSSL_free
+     [Richard Levitte]
+
+  *) New function BN_mod_exp_mont_word for small bases (roughly 15%
+     faster than BN_mod_exp_mont, i.e. 7% for a full DH exchange).
+     [Bodo Moeller]
+
+  *) CygWin32 support.
+     [John Jarvie <jjarvie@newsguy.com>]
+
+  *) The type-safe stack code has been rejigged. It is now only compiled
+     in when OpenSSL is configured with the DEBUG_SAFESTACK option and
+     by default all type-specific stack functions are "#define"d back to
+     standard stack functions. This results in more streamlined output
+     but retains the type-safety checking possibilities of the original
+     approach.
+     [Geoff Thorpe]
+
+  *) The STACK code has been cleaned up, and certain type declarations
+     that didn't make a lot of sense have been brought in line. This has
+     also involved a cleanup of sorts in safestack.h to more correctly
+     map type-safe stack functions onto their plain stack counterparts.
+     This work has also resulted in a variety of "const"ifications of
+     lots of the code, especially "_cmp" operations which should normally
+     be prototyped with "const" parameters anyway.
+     [Geoff Thorpe]
+
+  *) When generating bytes for the first time in md_rand.c, 'stir the pool'
+     by seeding with STATE_SIZE dummy bytes (with zero entropy count).
+     (The PRNG state consists of two parts, the large pool 'state' and 'md',
+     where all of 'md' is used each time the PRNG is used, but 'state'
+     is used only indexed by a cyclic counter. As entropy may not be
+     well distributed from the beginning, 'md' is important as a
+     chaining variable. However, the output function chains only half
+     of 'md', i.e. 80 bits.  ssleay_rand_add, on the other hand, chains
+     all of 'md', and seeding with STATE_SIZE dummy bytes will result
+     in all of 'state' being rewritten, with the new values depending
+     on virtually all of 'md'.  This overcomes the 80 bit limitation.)
+     [Bodo Moeller]
+
+  *) In ssl/s2_clnt.c and ssl/s3_clnt.c, call ERR_clear_error() when
+     the handshake is continued after ssl_verify_cert_chain();
+     otherwise, if SSL_VERIFY_NONE is set, remaining error codes
+     can lead to 'unexplainable' connection aborts later.
+     [Bodo Moeller; problem tracked down by Lutz Jaenicke]
+
+  *) Major EVP API cipher revision.
+     Add hooks for extra EVP features. This allows various cipher
+     parameters to be set in the EVP interface. Support added for variable
+     key length ciphers via the EVP_CIPHER_CTX_set_key_length() function and
+     setting of RC2 and RC5 parameters.
+
+     Modify EVP_OpenInit() and EVP_SealInit() to cope with variable key length
+     ciphers.
+
+     Remove lots of duplicated code from the EVP library. For example *every*
+     cipher init() function handles the 'iv' in the same way according to the
+     cipher mode. They also all do nothing if the 'key' parameter is NULL and
+     for CFB and OFB modes they zero ctx->num.
+
+     New functionality allows removal of S/MIME code RC2 hack.
+
+     Most of the routines have the same form and so can be declared in terms
+     of macros.
+
+     By shifting this to the top level EVP_CipherInit() it can be removed from
+     all individual ciphers. If the cipher wants to handle IVs or keys
+     differently it can set the EVP_CIPH_CUSTOM_IV or EVP_CIPH_ALWAYS_CALL_INIT
+     flags.
+
+     Change lots of functions like EVP_EncryptUpdate() to now return a
+     value: although software versions of the algorithms cannot fail
+     any installed hardware versions can.
+     [Steve Henson]
+
+  *) Implement SSL_OP_TLS_ROLLBACK_BUG: In ssl3_get_client_key_exchange, if
+     this option is set, tolerate broken clients that send the negotiated
+     protocol version number instead of the requested protocol version
+     number.
+     [Bodo Moeller]
+
+  *) Call dh_tmp_cb (set by ..._TMP_DH_CB) with correct 'is_export' flag;
+     i.e. non-zero for export ciphersuites, zero otherwise.
+     Previous versions had this flag inverted, inconsistent with
+     rsa_tmp_cb (..._TMP_RSA_CB).
+     [Bodo Moeller; problem reported by Amit Chopra]
+
+  *) Add missing DSA library text string. Work around for some IIS
+     key files with invalid SEQUENCE encoding.
+     [Steve Henson]
+
+  *) Add a document (doc/standards.txt) that list all kinds of standards
+     and so on that are implemented in OpenSSL.
+     [Richard Levitte]
+
+  *) Enhance c_rehash script. Old version would mishandle certificates
+     with the same subject name hash and wouldn't handle CRLs at all.
+     Added -fingerprint option to crl utility, to support new c_rehash
+     features.
+     [Steve Henson]
+
+  *) Eliminate non-ANSI declarations in crypto.h and stack.h.
+     [Ulf MÃ¶ller]
+
+  *) Fix for SSL server purpose checking. Server checking was
+     rejecting certificates which had extended key usage present
+     but no ssl client purpose.
+     [Steve Henson, reported by Rene Grosser <grosser@hisolutions.com>]
+
+  *) Make PKCS#12 code work with no password. The PKCS#12 spec
+     is a little unclear about how a blank password is handled.
+     Since the password in encoded as a BMPString with terminating
+     double NULL a zero length password would end up as just the
+     double NULL. However no password at all is different and is
+     handled differently in the PKCS#12 key generation code. NS
+     treats a blank password as zero length. MSIE treats it as no
+     password on export: but it will try both on import. We now do
+     the same: PKCS12_parse() tries zero length and no password if
+     the password is set to "" or NULL (NULL is now a valid password:
+     it wasn't before) as does the pkcs12 application.
+     [Steve Henson]
+
+  *) Bugfixes in apps/x509.c: Avoid a memory leak; and don't use
+     perror when PEM_read_bio_X509_REQ fails, the error message must
+     be obtained from the error queue.
+     [Bodo Moeller]
+
+  *) Avoid 'thread_hash' memory leak in crypto/err/err.c by freeing
+     it in ERR_remove_state if appropriate, and change ERR_get_state
+     accordingly to avoid race conditions (this is necessary because
+     thread_hash is no longer constant once set).
+     [Bodo Moeller]
+
+  *) Bugfix for linux-elf makefile.one.
+     [Ulf MÃ¶ller]
+
+  *) RSA_get_default_method() will now cause a default
+     RSA_METHOD to be chosen if one doesn't exist already.
+     Previously this was only set during a call to RSA_new()
+     or RSA_new_method(NULL) meaning it was possible for
+     RSA_get_default_method() to return NULL.
+     [Geoff Thorpe]
+
+  *) Added native name translation to the existing DSO code
+     that will convert (if the flag to do so is set) filenames
+     that are sufficiently small and have no path information
+     into a canonical native form. Eg. "blah" converted to
+     "libblah.so" or "blah.dll" etc.
+     [Geoff Thorpe]
+
+  *) New function ERR_error_string_n(e, buf, len) which is like
+     ERR_error_string(e, buf), but writes at most 'len' bytes
+     including the 0 terminator.  For ERR_error_string_n, 'buf'
+     may not be NULL.
+     [Damien Miller <djm@mindrot.org>, Bodo Moeller]
+
+  *) CONF library reworked to become more general.  A new CONF
+     configuration file reader "class" is implemented as well as a
+     new functions (NCONF_*, for "New CONF") to handle it.  The now
+     old CONF_* functions are still there, but are reimplemented to
+     work in terms of the new functions.  Also, a set of functions
+     to handle the internal storage of the configuration data is
+     provided to make it easier to write new configuration file
+     reader "classes" (I can definitely see something reading a
+     configuration file in XML format, for example), called _CONF_*,
+     or "the configuration storage API"...
+
+     The new configuration file reading functions are:
+
+        NCONF_new, NCONF_free, NCONF_load, NCONF_load_fp, NCONF_load_bio,
+        NCONF_get_section, NCONF_get_string, NCONF_get_numbre
+
+        NCONF_default, NCONF_WIN32
+
+        NCONF_dump_fp, NCONF_dump_bio
+
+     NCONF_default and NCONF_WIN32 are method (or "class") choosers,
+     NCONF_new creates a new CONF object.  This works in the same way
+     as other interfaces in OpenSSL, like the BIO interface.
+     NCONF_dump_* dump the internal storage of the configuration file,
+     which is useful for debugging.  All other functions take the same
+     arguments as the old CONF_* functions wth the exception of the
+     first that must be a `CONF *' instead of a `LHASH *'.
+
+     To make it easer to use the new classes with the old CONF_* functions,
+     the function CONF_set_default_method is provided.
+     [Richard Levitte]
+
+  *) Add '-tls1' option to 'openssl ciphers', which was already
+     mentioned in the documentation but had not been implemented.
+     (This option is not yet really useful because even the additional
+     experimental TLS 1.0 ciphers are currently treated as SSL 3.0 ciphers.)
+     [Bodo Moeller]
+
+  *) Initial DSO code added into libcrypto for letting OpenSSL (and
+     OpenSSL-based applications) load shared libraries and bind to
+     them in a portable way.
+     [Geoff Thorpe, with contributions from Richard Levitte]
+
+ Changes between 0.9.5 and 0.9.5a  [1 Apr 2000]
+
+  *) Make sure _lrotl and _lrotr are only used with MSVC.
+
+  *) Use lock CRYPTO_LOCK_RAND correctly in ssleay_rand_status
+     (the default implementation of RAND_status).
+
+  *) Rename openssl x509 option '-crlext', which was added in 0.9.5,
+     to '-clrext' (= clear extensions), as intended and documented.
+     [Bodo Moeller; inconsistency pointed out by Michael Attili
+     <attili@amaxo.com>]
+
+  *) Fix for HMAC. It wasn't zeroing the rest of the block if the key length
+     was larger than the MD block size.      
+     [Steve Henson, pointed out by Yost William <YostW@tce.com>]
+
+  *) Modernise PKCS12_parse() so it uses STACK_OF(X509) for its ca argument
+     fix a leak when the ca argument was passed as NULL. Stop X509_PUBKEY_set()
+     using the passed key: if the passed key was a private key the result
+     of X509_print(), for example, would be to print out all the private key
+     components.
+     [Steve Henson]
+
+  *) des_quad_cksum() byte order bug fix.
+     [Ulf MÃ¶ller, using the problem description in krb4-0.9.7, where
+      the solution is attributed to Derrick J Brashear <shadow@DEMENTIA.ORG>]
+
+  *) Fix so V_ASN1_APP_CHOOSE works again: however its use is strongly
+     discouraged.
+     [Steve Henson, pointed out by Brian Korver <briank@cs.stanford.edu>]
+
+  *) For easily testing in shell scripts whether some command
+     'openssl XXX' exists, the new pseudo-command 'openssl no-XXX'
+     returns with exit code 0 iff no command of the given name is available.
+     'no-XXX' is printed in this case, 'XXX' otherwise.  In both cases,
+     the output goes to stdout and nothing is printed to stderr.
+     Additional arguments are always ignored.
+
+     Since for each cipher there is a command of the same name,
+     the 'no-cipher' compilation switches can be tested this way.
+
+     ('openssl no-XXX' is not able to detect pseudo-commands such
+     as 'quit', 'list-XXX-commands', or 'no-XXX' itself.)
+     [Bodo Moeller]
+
+  *) Update test suite so that 'make test' succeeds in 'no-rsa' configuration.
+     [Bodo Moeller]
+
+  *) For SSL_[CTX_]set_tmp_dh, don't create a DH key if SSL_OP_SINGLE_DH_USE
+     is set; it will be thrown away anyway because each handshake creates
+     its own key.
+     ssl_cert_dup, which is used by SSL_new, now copies DH keys in addition
+     to parameters -- in previous versions (since OpenSSL 0.9.3) the
+     'default key' from SSL_CTX_set_tmp_dh would always be lost, meaning
+     you effectivly got SSL_OP_SINGLE_DH_USE when using this macro.
+     [Bodo Moeller]
+
+  *) New s_client option -ign_eof: EOF at stdin is ignored, and
+     'Q' and 'R' lose their special meanings (quit/renegotiate).
+     This is part of what -quiet does; unlike -quiet, -ign_eof
+     does not suppress any output.
+     [Richard Levitte]
+
+  *) Add compatibility options to the purpose and trust code. The
+     purpose X509_PURPOSE_ANY is "any purpose" which automatically
+     accepts a certificate or CA, this was the previous behaviour,
+     with all the associated security issues.
+
+     X509_TRUST_COMPAT is the old trust behaviour: only and
+     automatically trust self signed roots in certificate store. A
+     new trust setting X509_TRUST_DEFAULT is used to specify that
+     a purpose has no associated trust setting and it should instead
+     use the value in the default purpose.
+     [Steve Henson]
+
+  *) Fix the PKCS#8 DSA private key code so it decodes keys again
+     and fix a memory leak.
+     [Steve Henson]
+
+  *) In util/mkerr.pl (which implements 'make errors'), preserve
+     reason strings from the previous version of the .c file, as
+     the default to have only downcase letters (and digits) in
+     automatically generated reasons codes is not always appropriate.
+     [Bodo Moeller]
+
+  *) In ERR_load_ERR_strings(), build an ERR_LIB_SYS error reason table
+     using strerror.  Previously, ERR_reason_error_string() returned
+     library names as reason strings for SYSerr; but SYSerr is a special
+     case where small numbers are errno values, not library numbers.
+     [Bodo Moeller]
+
+  *) Add '-dsaparam' option to 'openssl dhparam' application.  This
+     converts DSA parameters into DH parameters. (When creating parameters,
+     DSA_generate_parameters is used.)
+     [Bodo Moeller]
+
+  *) Include 'length' (recommended exponent length) in C code generated
+     by 'openssl dhparam -C'.
+     [Bodo Moeller]
+
+  *) The second argument to set_label in perlasm was already being used
+     so couldn't be used as a "file scope" flag. Moved to third argument
+     which was free.
+     [Steve Henson]
+
+  *) In PEM_ASN1_write_bio and some other functions, use RAND_pseudo_bytes
+     instead of RAND_bytes for encryption IVs and salts.
+     [Bodo Moeller]
+
+  *) Include RAND_status() into RAND_METHOD instead of implementing
+     it only for md_rand.c  Otherwise replacing the PRNG by calling
+     RAND_set_rand_method would be impossible.
+     [Bodo Moeller]
+
+  *) Don't let DSA_generate_key() enter an infinite loop if the random
+     number generation fails.
+     [Bodo Moeller]
+
+  *) New 'rand' application for creating pseudo-random output.
+     [Bodo Moeller]
+
+  *) Added configuration support for Linux/IA64
+     [Rolf Haberrecker <rolf@suse.de>]
+
+  *) Assembler module support for Mingw32.
+     [Ulf MÃ¶ller]
+
+  *) Shared library support for HPUX (in shlib/).
+     [Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE> and Anonymous]
+
+  *) Shared library support for Solaris gcc.
+     [Lutz Behnke <behnke@trustcenter.de>]
+
+ Changes between 0.9.4 and 0.9.5  [28 Feb 2000]
+
+  *) PKCS7_encrypt() was adding text MIME headers twice because they
+     were added manually and by SMIME_crlf_copy().
+     [Steve Henson]
+
+  *) In bntest.c don't call BN_rand with zero bits argument.
+     [Steve Henson, pointed out by Andrew W. Gray <agray@iconsinc.com>]
+
+  *) BN_mul bugfix: In bn_mul_part_recursion() only the a>a[n] && b>b[n]
+     case was implemented. This caused BN_div_recp() to fail occasionally.
+     [Ulf MÃ¶ller]
+
+  *) Add an optional second argument to the set_label() in the perl
+     assembly language builder. If this argument exists and is set
+     to 1 it signals that the assembler should use a symbol whose 
+     scope is the entire file, not just the current function. This
+     is needed with MASM which uses the format label:: for this scope.
+     [Steve Henson, pointed out by Peter Runestig <peter@runestig.com>]
+
+  *) Change the ASN1 types so they are typedefs by default. Before
+     almost all types were #define'd to ASN1_STRING which was causing
+     STACK_OF() problems: you couldn't declare STACK_OF(ASN1_UTF8STRING)
+     for example.
+     [Steve Henson]
+
+  *) Change names of new functions to the new get1/get0 naming
+     convention: After 'get1', the caller owns a reference count
+     and has to call ..._free; 'get0' returns a pointer to some
+     data structure without incrementing reference counters.
+     (Some of the existing 'get' functions increment a reference
+     counter, some don't.)
+     Similarly, 'set1' and 'add1' functions increase reference
+     counters or duplicate objects.
+     [Steve Henson]
+
+  *) Allow for the possibility of temp RSA key generation failure:
+     the code used to assume it always worked and crashed on failure.
+     [Steve Henson]
+
+  *) Fix potential buffer overrun problem in BIO_printf().
+     [Ulf MÃ¶ller, using public domain code by Patrick Powell; problem
+      pointed out by David Sacerdote <das33@cornell.edu>]
+
+  *) Support EGD <http://www.lothar.com/tech/crypto/>.  New functions
+     RAND_egd() and RAND_status().  In the command line application,
+     the EGD socket can be specified like a seed file using RANDFILE
+     or -rand.
+     [Ulf MÃ¶ller]
+
+  *) Allow the string CERTIFICATE to be tolerated in PKCS#7 structures.
+     Some CAs (e.g. Verisign) distribute certificates in this form.
+     [Steve Henson]
+
+  *) Remove the SSL_ALLOW_ADH compile option and set the default cipher
+     list to exclude them. This means that no special compilation option
+     is needed to use anonymous DH: it just needs to be included in the
+     cipher list.
+     [Steve Henson]
+
+  *) Change the EVP_MD_CTX_type macro so its meaning consistent with
+     EVP_MD_type. The old functionality is available in a new macro called
+     EVP_MD_md(). Change code that uses it and update docs.
+     [Steve Henson]
+
+  *) ..._ctrl functions now have corresponding ..._callback_ctrl functions
+     where the 'void *' argument is replaced by a function pointer argument.
+     Previously 'void *' was abused to point to functions, which works on
+     many platforms, but is not correct.  As these functions are usually
+     called by macros defined in OpenSSL header files, most source code
+     should work without changes.
+     [Richard Levitte]
+
+  *) <openssl/opensslconf.h> (which is created by Configure) now contains
+     sections with information on -D... compiler switches used for
+     compiling the library so that applications can see them.  To enable
+     one of these sections, a pre-processor symbol OPENSSL_..._DEFINES
+     must be defined.  E.g.,
+        #define OPENSSL_ALGORITHM_DEFINES
+        #include <openssl/opensslconf.h>
+     defines all pertinent NO_<algo> symbols, such as NO_IDEA, NO_RSA, etc.
+     [Richard Levitte, Ulf and Bodo MÃ¶ller]
+
+  *) Bugfix: Tolerate fragmentation and interleaving in the SSL 3/TLS
+     record layer.
+     [Bodo Moeller]
+
+  *) Change the 'other' type in certificate aux info to a STACK_OF
+     X509_ALGOR. Although not an AlgorithmIdentifier as such it has
+     the required ASN1 format: arbitrary types determined by an OID.
+     [Steve Henson]
+
+  *) Add some PEM_write_X509_REQ_NEW() functions and a command line
+     argument to 'req'. This is not because the function is newer or
+     better than others it just uses the work 'NEW' in the certificate
+     request header lines. Some software needs this.
+     [Steve Henson]
+
+  *) Reorganise password command line arguments: now passwords can be
+     obtained from various sources. Delete the PEM_cb function and make
+     it the default behaviour: i.e. if the callback is NULL and the
+     usrdata argument is not NULL interpret it as a null terminated pass
+     phrase. If usrdata and the callback are NULL then the pass phrase
+     is prompted for as usual.
+     [Steve Henson]
+
+  *) Add support for the Compaq Atalla crypto accelerator. If it is installed,
+     the support is automatically enabled. The resulting binaries will
+     autodetect the card and use it if present.
+     [Ben Laurie and Compaq Inc.]
+
+  *) Work around for Netscape hang bug. This sends certificate request
+     and server done in one record. Since this is perfectly legal in the
+     SSL/TLS protocol it isn't a "bug" option and is on by default. See
+     the bugs/SSLv3 entry for more info.
+     [Steve Henson]
+
+  *) HP-UX tune-up: new unified configs, HP C compiler bug workaround.
+     [Andy Polyakov]
+
+  *) Add -rand argument to smime and pkcs12 applications and read/write
+     of seed file.
+     [Steve Henson]
+
+  *) New 'passwd' tool for crypt(3) and apr1 password hashes.
+     [Bodo Moeller]
+
+  *) Add command line password options to the remaining applications.
+     [Steve Henson]
+
+  *) Bug fix for BN_div_recp() for numerators with an even number of
+     bits.
+     [Ulf MÃ¶ller]
+
+  *) More tests in bntest.c, and changed test_bn output.
+     [Ulf MÃ¶ller]
+
+  *) ./config recognizes MacOS X now.
+     [Andy Polyakov]
+
+  *) Bug fix for BN_div() when the first words of num and divsor are
+     equal (it gave wrong results if (rem=(n1-q*d0)&BN_MASK2) < d0).
+     [Ulf MÃ¶ller]
+
+  *) Add support for various broken PKCS#8 formats, and command line
+     options to produce them.
+     [Steve Henson]
+
+  *) New functions BN_CTX_start(), BN_CTX_get() and BT_CTX_end() to
+     get temporary BIGNUMs from a BN_CTX.
+     [Ulf MÃ¶ller]
+
+  *) Correct return values in BN_mod_exp_mont() and BN_mod_exp2_mont()
+     for p == 0.
+     [Ulf MÃ¶ller]
+
+  *) Change the SSLeay_add_all_*() functions to OpenSSL_add_all_*() and
+     include a #define from the old name to the new. The original intent
+     was that statically linked binaries could for example just call
+     SSLeay_add_all_ciphers() to just add ciphers to the table and not
+     link with digests. This never worked because SSLeay_add_all_digests()
+     and SSLeay_add_all_ciphers() were in the same source file so calling
+     one would link with the other. They are now in separate source files.
+     [Steve Henson]
+
+  *) Add a new -notext option to 'ca' and a -pubkey option to 'spkac'.
+     [Steve Henson]
+
+  *) Use a less unusual form of the Miller-Rabin primality test (it used
+     a binary algorithm for exponentiation integrated into the Miller-Rabin
+     loop, our standard modexp algorithms are faster).
+     [Bodo Moeller]
+
+  *) Support for the EBCDIC character set completed.
+     [Martin Kraemer <Martin.Kraemer@Mch.SNI.De>]
+
+  *) Source code cleanups: use const where appropriate, eliminate casts,
+     use void * instead of char * in lhash.
+     [Ulf MÃ¶ller] 
+
+  *) Bugfix: ssl3_send_server_key_exchange was not restartable
+     (the state was not changed to SSL3_ST_SW_KEY_EXCH_B, and because of
+     this the server could overwrite ephemeral keys that the client
+     has already seen).
+     [Bodo Moeller]
+
+  *) Turn DSA_is_prime into a macro that calls BN_is_prime,
+     using 50 iterations of the Rabin-Miller test.
+
+     DSA_generate_parameters now uses BN_is_prime_fasttest (with 50
+     iterations of the Rabin-Miller test as required by the appendix
+     to FIPS PUB 186[-1]) instead of DSA_is_prime.
+     As BN_is_prime_fasttest includes trial division, DSA parameter
+     generation becomes much faster.
+
+     This implies a change for the callback functions in DSA_is_prime
+     and DSA_generate_parameters: The callback function is called once
+     for each positive witness in the Rabin-Miller test, not just
+     occasionally in the inner loop; and the parameters to the
+     callback function now provide an iteration count for the outer
+     loop rather than for the current invocation of the inner loop.
+     DSA_generate_parameters additionally can call the callback
+     function with an 'iteration count' of -1, meaning that a
+     candidate has passed the trial division test (when q is generated 
+     from an application-provided seed, trial division is skipped).
+     [Bodo Moeller]
+
+  *) New function BN_is_prime_fasttest that optionally does trial
+     division before starting the Rabin-Miller test and has
+     an additional BN_CTX * argument (whereas BN_is_prime always
+     has to allocate at least one BN_CTX).
+     'callback(1, -1, cb_arg)' is called when a number has passed the
+     trial division stage.
+     [Bodo Moeller]
+
+  *) Fix for bug in CRL encoding. The validity dates weren't being handled
+     as ASN1_TIME.
+     [Steve Henson]
+
+  *) New -pkcs12 option to CA.pl script to write out a PKCS#12 file.
+     [Steve Henson]
+
+  *) New function BN_pseudo_rand().
+     [Ulf MÃ¶ller]
+
+  *) Clean up BN_mod_mul_montgomery(): replace the broken (and unreadable)
+     bignum version of BN_from_montgomery() with the working code from
+     SSLeay 0.9.0 (the word based version is faster anyway), and clean up
+     the comments.
+     [Ulf MÃ¶ller]
+
+  *) Avoid a race condition in s2_clnt.c (function get_server_hello) that
+     made it impossible to use the same SSL_SESSION data structure in
+     SSL2 clients in multiple threads.
+     [Bodo Moeller]
+
+  *) The return value of RAND_load_file() no longer counts bytes obtained
+     by stat().  RAND_load_file(..., -1) is new and uses the complete file
+     to seed the PRNG (previously an explicit byte count was required).
+     [Ulf MÃ¶ller, Bodo MÃ¶ller]
+
+  *) Clean up CRYPTO_EX_DATA functions, some of these didn't have prototypes
+     used (char *) instead of (void *) and had casts all over the place.
+     [Steve Henson]
+
+  *) Make BN_generate_prime() return NULL on error if ret!=NULL.
+     [Ulf MÃ¶ller]
+
+  *) Retain source code compatibility for BN_prime_checks macro:
+     BN_is_prime(..., BN_prime_checks, ...) now uses
+     BN_prime_checks_for_size to determine the appropriate number of
+     Rabin-Miller iterations.
+     [Ulf MÃ¶ller]
+
+  *) Diffie-Hellman uses "safe" primes: DH_check() return code renamed to
+     DH_CHECK_P_NOT_SAFE_PRIME.
+     (Check if this is true? OpenPGP calls them "strong".)
+     [Ulf MÃ¶ller]
+
+  *) Merge the functionality of "dh" and "gendh" programs into a new program
+     "dhparam". The old programs are retained for now but will handle DH keys
+     (instead of parameters) in future.
+     [Steve Henson]
+
+  *) Make the ciphers, s_server and s_client programs check the return values
+     when a new cipher list is set.
+     [Steve Henson]
+
+  *) Enhance the SSL/TLS cipher mechanism to correctly handle the TLS 56bit
+     ciphers. Before when the 56bit ciphers were enabled the sorting was
+     wrong.
+
+     The syntax for the cipher sorting has been extended to support sorting by
+     cipher-strength (using the strength_bits hard coded in the tables).
+     The new command is "@STRENGTH" (see also doc/apps/ciphers.pod).
+
+     Fix a bug in the cipher-command parser: when supplying a cipher command
+     string with an "undefined" symbol (neither command nor alphanumeric
+     [A-Za-z0-9], ssl_set_cipher_list used to hang in an endless loop. Now
+     an error is flagged.
+
+     Due to the strength-sorting extension, the code of the
+     ssl_create_cipher_list() function was completely rearranged. I hope that
+     the readability was also increased :-)
+     [Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE>]
+
+  *) Minor change to 'x509' utility. The -CAcreateserial option now uses 1
+     for the first serial number and places 2 in the serial number file. This
+     avoids problems when the root CA is created with serial number zero and
+     the first user certificate has the same issuer name and serial number
+     as the root CA.
+     [Steve Henson]
+
+  *) Fixes to X509_ATTRIBUTE utilities, change the 'req' program so it uses
+     the new code. Add documentation for this stuff.
+     [Steve Henson]
+
+  *) Changes to X509_ATTRIBUTE utilities. These have been renamed from
+     X509_*() to X509at_*() on the grounds that they don't handle X509
+     structures and behave in an analogous way to the X509v3 functions:
+     they shouldn't be called directly but wrapper functions should be used
+     instead.
+
+     So we also now have some wrapper functions that call the X509at functions
+     when passed certificate requests. (TO DO: similar things can be done with
+     PKCS#7 signed and unsigned attributes, PKCS#12 attributes and a few other
+     things. Some of these need some d2i or i2d and print functionality
+     because they handle more complex structures.)
+     [Steve Henson]
+
+  *) Add missing #ifndefs that caused missing symbols when building libssl
+     as a shared library without RSA.  Use #ifndef NO_SSL2 instead of
+     NO_RSA in ssl/s2*.c. 
+     [Kris Kennaway <kris@hub.freebsd.org>, modified by Ulf MÃ¶ller]
+
+  *) Precautions against using the PRNG uninitialized: RAND_bytes() now
+     has a return value which indicates the quality of the random data
+     (1 = ok, 0 = not seeded).  Also an error is recorded on the thread's
+     error queue. New function RAND_pseudo_bytes() generates output that is
+     guaranteed to be unique but not unpredictable. RAND_add is like
+     RAND_seed, but takes an extra argument for an entropy estimate
+     (RAND_seed always assumes full entropy).
+     [Ulf MÃ¶ller]
+
+  *) Do more iterations of Rabin-Miller probable prime test (specifically,
+     3 for 1024-bit primes, 6 for 512-bit primes, 12 for 256-bit primes
+     instead of only 2 for all lengths; see BN_prime_checks_for_size definition
+     in crypto/bn/bn_prime.c for the complete table).  This guarantees a
+     false-positive rate of at most 2^-80 for random input.
+     [Bodo Moeller]
+
+  *) Rewrite ssl3_read_n (ssl/s3_pkt.c) avoiding a couple of bugs.
+     [Bodo Moeller]
+
+  *) New function X509_CTX_rget_chain() (renamed to X509_CTX_get1_chain
+     in the 0.9.5 release), this returns the chain
+     from an X509_CTX structure with a dup of the stack and all
+     the X509 reference counts upped: so the stack will exist
+     after X509_CTX_cleanup() has been called. Modify pkcs12.c
+     to use this.
+
+     Also make SSL_SESSION_print() print out the verify return
+     code.
+     [Steve Henson]
+
+  *) Add manpage for the pkcs12 command. Also change the default
+     behaviour so MAC iteration counts are used unless the new
+     -nomaciter option is used. This improves file security and
+     only older versions of MSIE (4.0 for example) need it.
+     [Steve Henson]
+
+  *) Honor the no-xxx Configure options when creating .DEF files.
+     [Ulf MÃ¶ller]
+
+  *) Add PKCS#10 attributes to field table: challengePassword, 
+     unstructuredName and unstructuredAddress. These are taken from
+     draft PKCS#9 v2.0 but are compatible with v1.2 provided no 
+     international characters are used.
+
+     More changes to X509_ATTRIBUTE code: allow the setting of types
+     based on strings. Remove the 'loc' parameter when adding
+     attributes because these will be a SET OF encoding which is sorted
+     in ASN1 order.
+     [Steve Henson]
+
+  *) Initial changes to the 'req' utility to allow request generation
+     automation. This will allow an application to just generate a template
+     file containing all the field values and have req construct the
+     request.
+
+     Initial support for X509_ATTRIBUTE handling. Stacks of these are
+     used all over the place including certificate requests and PKCS#7
+     structures. They are currently handled manually where necessary with
+     some primitive wrappers for PKCS#7. The new functions behave in a
+     manner analogous to the X509 extension functions: they allow
+     attributes to be looked up by NID and added.
+
+     Later something similar to the X509V3 code would be desirable to
+     automatically handle the encoding, decoding and printing of the
+     more complex types. The string types like challengePassword can
+     be handled by the string table functions.
+
+     Also modified the multi byte string table handling. Now there is
+     a 'global mask' which masks out certain types. The table itself
+     can use the flag STABLE_NO_MASK to ignore the mask setting: this
+     is useful when for example there is only one permissible type
+     (as in countryName) and using the mask might result in no valid
+     types at all.
+     [Steve Henson]
+
+  *) Clean up 'Finished' handling, and add functions SSL_get_finished and
+     SSL_get_peer_finished to allow applications to obtain the latest
+     Finished messages sent to the peer or expected from the peer,
+     respectively.  (SSL_get_peer_finished is usually the Finished message
+     actually received from the peer, otherwise the protocol will be aborted.)
+
+     As the Finished message are message digests of the complete handshake
+     (with a total of 192 bits for TLS 1.0 and more for SSL 3.0), they can
+     be used for external authentication procedures when the authentication
+     provided by SSL/TLS is not desired or is not enough.
+     [Bodo Moeller]
+
+  *) Enhanced support for Alpha Linux is added. Now ./config checks if
+     the host supports BWX extension and if Compaq C is present on the
+     $PATH. Just exploiting of the BWX extension results in 20-30%
+     performance kick for some algorithms, e.g. DES and RC4 to mention
+     a couple. Compaq C in turn generates ~20% faster code for MD5 and
+     SHA1.
+     [Andy Polyakov]
+
+  *) Add support for MS "fast SGC". This is arguably a violation of the
+     SSL3/TLS protocol. Netscape SGC does two handshakes: the first with
+     weak crypto and after checking the certificate is SGC a second one
+     with strong crypto. MS SGC stops the first handshake after receiving
+     the server certificate message and sends a second client hello. Since
+     a server will typically do all the time consuming operations before
+     expecting any further messages from the client (server key exchange
+     is the most expensive) there is little difference between the two.
+
+     To get OpenSSL to support MS SGC we have to permit a second client
+     hello message after we have sent server done. In addition we have to
+     reset the MAC if we do get this second client hello.
+     [Steve Henson]
+
+  *) Add a function 'd2i_AutoPrivateKey()' this will automatically decide
+     if a DER encoded private key is RSA or DSA traditional format. Changed
+     d2i_PrivateKey_bio() to use it. This is only needed for the "traditional"
+     format DER encoded private key. Newer code should use PKCS#8 format which
+     has the key type encoded in the ASN1 structure. Added DER private key
+     support to pkcs8 application.
+     [Steve Henson]
+
+  *) SSL 3/TLS 1 servers now don't request certificates when an anonymous
+     ciphersuites has been selected (as required by the SSL 3/TLS 1
+     specifications).  Exception: When SSL_VERIFY_FAIL_IF_NO_PEER_CERT
+     is set, we interpret this as a request to violate the specification
+     (the worst that can happen is a handshake failure, and 'correct'
+     behaviour would result in a handshake failure anyway).
+     [Bodo Moeller]
+
+  *) In SSL_CTX_add_session, take into account that there might be multiple
+     SSL_SESSION structures with the same session ID (e.g. when two threads
+     concurrently obtain them from an external cache).
+     The internal cache can handle only one SSL_SESSION with a given ID,
+     so if there's a conflict, we now throw out the old one to achieve
+     consistency.
+     [Bodo Moeller]
+
+  *) Add OIDs for idea and blowfish in CBC mode. This will allow both
+     to be used in PKCS#5 v2.0 and S/MIME.  Also add checking to
+     some routines that use cipher OIDs: some ciphers do not have OIDs
+     defined and so they cannot be used for S/MIME and PKCS#5 v2.0 for
+     example.
+     [Steve Henson]
+
+  *) Simplify the trust setting structure and code. Now we just have
+     two sequences of OIDs for trusted and rejected settings. These will
+     typically have values the same as the extended key usage extension
+     and any application specific purposes.
+
+     The trust checking code now has a default behaviour: it will just
+     check for an object with the same NID as the passed id. Functions can
+     be provided to override either the default behaviour or the behaviour
+     for a given id. SSL client, server and email already have functions
+     in place for compatibility: they check the NID and also return "trusted"
+     if the certificate is self signed.
+     [Steve Henson]
+
+  *) Add d2i,i2d bio/fp functions for PrivateKey: these convert the
+     traditional format into an EVP_PKEY structure.
+     [Steve Henson]
+
+  *) Add a password callback function PEM_cb() which either prompts for
+     a password if usr_data is NULL or otherwise assumes it is a null
+     terminated password. Allow passwords to be passed on command line
+     environment or config files in a few more utilities.
+     [Steve Henson]
+
+  *) Add a bunch of DER and PEM functions to handle PKCS#8 format private
+     keys. Add some short names for PKCS#8 PBE algorithms and allow them
+     to be specified on the command line for the pkcs8 and pkcs12 utilities.
+     Update documentation.
+     [Steve Henson]
+
+  *) Support for ASN1 "NULL" type. This could be handled before by using
+     ASN1_TYPE but there wasn't any function that would try to read a NULL
+     and produce an error if it couldn't. For compatibility we also have
+     ASN1_NULL_new() and ASN1_NULL_free() functions but these are faked and
+     don't allocate anything because they don't need to.
+     [Steve Henson]
+
+  *) Initial support for MacOS is now provided. Examine INSTALL.MacOS
+     for details.
+     [Andy Polyakov, Roy Woods <roy@centicsystems.ca>]
+
+  *) Rebuild of the memory allocation routines used by OpenSSL code and
+     possibly others as well.  The purpose is to make an interface that
+     provide hooks so anyone can build a separate set of allocation and
+     deallocation routines to be used by OpenSSL, for example memory
+     pool implementations, or something else, which was previously hard
+     since Malloc(), Realloc() and Free() were defined as macros having
+     the values malloc, realloc and free, respectively (except for Win32
+     compilations).  The same is provided for memory debugging code.
+     OpenSSL already comes with functionality to find memory leaks, but
+     this gives people a chance to debug other memory problems.
+
+     With these changes, a new set of functions and macros have appeared:
+
+       CRYPTO_set_mem_debug_functions()	        [F]
+       CRYPTO_get_mem_debug_functions()         [F]
+       CRYPTO_dbg_set_options()	                [F]
+       CRYPTO_dbg_get_options()                 [F]
+       CRYPTO_malloc_debug_init()               [M]
+
+     The memory debug functions are NULL by default, unless the library
+     is compiled with CRYPTO_MDEBUG or friends is defined.  If someone
+     wants to debug memory anyway, CRYPTO_malloc_debug_init() (which
+     gives the standard debugging functions that come with OpenSSL) or
+     CRYPTO_set_mem_debug_functions() (tells OpenSSL to use functions
+     provided by the library user) must be used.  When the standard
+     debugging functions are used, CRYPTO_dbg_set_options can be used to
+     request additional information:
+     CRYPTO_dbg_set_options(V_CYRPTO_MDEBUG_xxx) corresponds to setting
+     the CRYPTO_MDEBUG_xxx macro when compiling the library.   
+
+     Also, things like CRYPTO_set_mem_functions will always give the
+     expected result (the new set of functions is used for allocation
+     and deallocation) at all times, regardless of platform and compiler
+     options.
+
+     To finish it up, some functions that were never use in any other
+     way than through macros have a new API and new semantic:
+
+       CRYPTO_dbg_malloc()
+       CRYPTO_dbg_realloc()
+       CRYPTO_dbg_free()
+
+     All macros of value have retained their old syntax.
+     [Richard Levitte and Bodo Moeller]
+
+  *) Some S/MIME fixes. The OID for SMIMECapabilities was wrong, the
+     ordering of SMIMECapabilities wasn't in "strength order" and there
+     was a missing NULL in the AlgorithmIdentifier for the SHA1 signature
+     algorithm.
+     [Steve Henson]
+
+  *) Some ASN1 types with illegal zero length encoding (INTEGER,
+     ENUMERATED and OBJECT IDENTIFIER) choked the ASN1 routines.
+     [Frans Heymans <fheymans@isaserver.be>, modified by Steve Henson]
+
+  *) Merge in my S/MIME library for OpenSSL. This provides a simple
+     S/MIME API on top of the PKCS#7 code, a MIME parser (with enough
+     functionality to handle multipart/signed properly) and a utility
+     called 'smime' to call all this stuff. This is based on code I
+     originally wrote for Celo who have kindly allowed it to be
+     included in OpenSSL.
+     [Steve Henson]
+
+  *) Add variants des_set_key_checked and des_set_key_unchecked of
+     des_set_key (aka des_key_sched).  Global variable des_check_key
+     decides which of these is called by des_set_key; this way
+     des_check_key behaves as it always did, but applications and
+     the library itself, which was buggy for des_check_key == 1,
+     have a cleaner way to pick the version they need.
+     [Bodo Moeller]
+
+  *) New function PKCS12_newpass() which changes the password of a
+     PKCS12 structure.
+     [Steve Henson]
+
+  *) Modify X509_TRUST and X509_PURPOSE so it also uses a static and
+     dynamic mix. In both cases the ids can be used as an index into the
+     table. Also modified the X509_TRUST_add() and X509_PURPOSE_add()
+     functions so they accept a list of the field values and the
+     application doesn't need to directly manipulate the X509_TRUST
+     structure.
+     [Steve Henson]
+
+  *) Modify the ASN1_STRING_TABLE stuff so it also uses bsearch and doesn't
+     need initialising.
+     [Steve Henson]
+
+  *) Modify the way the V3 extension code looks up extensions. This now
+     works in a similar way to the object code: we have some "standard"
+     extensions in a static table which is searched with OBJ_bsearch()
+     and the application can add dynamic ones if needed. The file
+     crypto/x509v3/ext_dat.h now has the info: this file needs to be
+     updated whenever a new extension is added to the core code and kept
+     in ext_nid order. There is a simple program 'tabtest.c' which checks
+     this. New extensions are not added too often so this file can readily
+     be maintained manually.
+
+     There are two big advantages in doing things this way. The extensions
+     can be looked up immediately and no longer need to be "added" using
+     X509V3_add_standard_extensions(): this function now does nothing.
+     [Side note: I get *lots* of email saying the extension code doesn't
+      work because people forget to call this function]
+     Also no dynamic allocation is done unless new extensions are added:
+     so if we don't add custom extensions there is no need to call
+     X509V3_EXT_cleanup().
+     [Steve Henson]
+
+  *) Modify enc utility's salting as follows: make salting the default. Add a
+     magic header, so unsalted files fail gracefully instead of just decrypting
+     to garbage. This is because not salting is a big security hole, so people
+     should be discouraged from doing it.
+     [Ben Laurie]
+
+  *) Fixes and enhancements to the 'x509' utility. It allowed a message
+     digest to be passed on the command line but it only used this
+     parameter when signing a certificate. Modified so all relevant
+     operations are affected by the digest parameter including the
+     -fingerprint and -x509toreq options. Also -x509toreq choked if a
+     DSA key was used because it didn't fix the digest.
+     [Steve Henson]
+
+  *) Initial certificate chain verify code. Currently tests the untrusted
+     certificates for consistency with the verify purpose (which is set
+     when the X509_STORE_CTX structure is set up) and checks the pathlength.
+
+     There is a NO_CHAIN_VERIFY compilation option to keep the old behaviour:
+     this is because it will reject chains with invalid extensions whereas
+     every previous version of OpenSSL and SSLeay made no checks at all.
+
+     Trust code: checks the root CA for the relevant trust settings. Trust
+     settings have an initial value consistent with the verify purpose: e.g.
+     if the verify purpose is for SSL client use it expects the CA to be
+     trusted for SSL client use. However the default value can be changed to
+     permit custom trust settings: one example of this would be to only trust
+     certificates from a specific "secure" set of CAs.
+
+     Also added X509_STORE_CTX_new() and X509_STORE_CTX_free() functions
+     which should be used for version portability: especially since the
+     verify structure is likely to change more often now.
+
+     SSL integration. Add purpose and trust to SSL_CTX and SSL and functions
+     to set them. If not set then assume SSL clients will verify SSL servers
+     and vice versa.
+
+     Two new options to the verify program: -untrusted allows a set of
+     untrusted certificates to be passed in and -purpose which sets the
+     intended purpose of the certificate. If a purpose is set then the
+     new chain verify code is used to check extension consistency.
+     [Steve Henson]
+
+  *) Support for the authority information access extension.
+     [Steve Henson]
+
+  *) Modify RSA and DSA PEM read routines to transparently handle
+     PKCS#8 format private keys. New *_PUBKEY_* functions that handle
+     public keys in a format compatible with certificate
+     SubjectPublicKeyInfo structures. Unfortunately there were already
+     functions called *_PublicKey_* which used various odd formats so
+     these are retained for compatibility: however the DSA variants were
+     never in a public release so they have been deleted. Changed dsa/rsa
+     utilities to handle the new format: note no releases ever handled public
+     keys so we should be OK.
+
+     The primary motivation for this change is to avoid the same fiasco
+     that dogs private keys: there are several incompatible private key
+     formats some of which are standard and some OpenSSL specific and
+     require various evil hacks to allow partial transparent handling and
+     even then it doesn't work with DER formats. Given the option anything
+     other than PKCS#8 should be dumped: but the other formats have to
+     stay in the name of compatibility.
+
+     With public keys and the benefit of hindsight one standard format 
+     is used which works with EVP_PKEY, RSA or DSA structures: though
+     it clearly returns an error if you try to read the wrong kind of key.
+
+     Added a -pubkey option to the 'x509' utility to output the public key.
+     Also rename the EVP_PKEY_get_*() to EVP_PKEY_rget_*()
+     (renamed to EVP_PKEY_get1_*() in the OpenSSL 0.9.5 release) and add
+     EVP_PKEY_rset_*() functions (renamed to EVP_PKEY_set1_*())
+     that do the same as the EVP_PKEY_assign_*() except they up the
+     reference count of the added key (they don't "swallow" the
+     supplied key).
+     [Steve Henson]
+
+  *) Fixes to crypto/x509/by_file.c the code to read in certificates and
+     CRLs would fail if the file contained no certificates or no CRLs:
+     added a new function to read in both types and return the number
+     read: this means that if none are read it will be an error. The
+     DER versions of the certificate and CRL reader would always fail
+     because it isn't possible to mix certificates and CRLs in DER format
+     without choking one or the other routine. Changed this to just read
+     a certificate: this is the best we can do. Also modified the code
+     in apps/verify.c to take notice of return codes: it was previously
+     attempting to read in certificates from NULL pointers and ignoring
+     any errors: this is one reason why the cert and CRL reader seemed
+     to work. It doesn't check return codes from the default certificate
+     routines: these may well fail if the certificates aren't installed.
+     [Steve Henson]
+
+  *) Code to support otherName option in GeneralName.
+     [Steve Henson]
+
+  *) First update to verify code. Change the verify utility
+     so it warns if it is passed a self signed certificate:
+     for consistency with the normal behaviour. X509_verify
+     has been modified to it will now verify a self signed
+     certificate if *exactly* the same certificate appears
+     in the store: it was previously impossible to trust a
+     single self signed certificate. This means that:
+     openssl verify ss.pem
+     now gives a warning about a self signed certificate but
+     openssl verify -CAfile ss.pem ss.pem
+     is OK.
+     [Steve Henson]
+
+  *) For servers, store verify_result in SSL_SESSION data structure
+     (and add it to external session representation).
+     This is needed when client certificate verifications fails,
+     but an application-provided verification callback (set by
+     SSL_CTX_set_cert_verify_callback) allows accepting the session
+     anyway (i.e. leaves x509_store_ctx->error != X509_V_OK
+     but returns 1): When the session is reused, we have to set
+     ssl->verify_result to the appropriate error code to avoid
+     security holes.
+     [Bodo Moeller, problem pointed out by Lutz Jaenicke]
+
+  *) Fix a bug in the new PKCS#7 code: it didn't consider the
+     case in PKCS7_dataInit() where the signed PKCS7 structure
+     didn't contain any existing data because it was being created.
+     [Po-Cheng Chen <pocheng@nst.com.tw>, slightly modified by Steve Henson]
+
+  *) Add a salt to the key derivation routines in enc.c. This
+     forms the first 8 bytes of the encrypted file. Also add a
+     -S option to allow a salt to be input on the command line.
+     [Steve Henson]
+
+  *) New function X509_cmp(). Oddly enough there wasn't a function
+     to compare two certificates. We do this by working out the SHA1
+     hash and comparing that. X509_cmp() will be needed by the trust
+     code.
+     [Steve Henson]
+
+  *) SSL_get1_session() is like SSL_get_session(), but increments
+     the reference count in the SSL_SESSION returned.
+     [Geoff Thorpe <geoff@eu.c2.net>]
+
+  *) Fix for 'req': it was adding a null to request attributes.
+     Also change the X509_LOOKUP and X509_INFO code to handle
+     certificate auxiliary information.
+     [Steve Henson]
+
+  *) Add support for 40 and 64 bit RC2 and RC4 algorithms: document
+     the 'enc' command.
+     [Steve Henson]
+
+  *) Add the possibility to add extra information to the memory leak
+     detecting output, to form tracebacks, showing from where each
+     allocation was originated: CRYPTO_push_info("constant string") adds
+     the string plus current file name and line number to a per-thread
+     stack, CRYPTO_pop_info() does the obvious, CRYPTO_remove_all_info()
+     is like calling CYRPTO_pop_info() until the stack is empty.
+     Also updated memory leak detection code to be multi-thread-safe.
+     [Richard Levitte]
+
+  *) Add options -text and -noout to pkcs7 utility and delete the
+     encryption options which never did anything. Update docs.
+     [Steve Henson]
+
+  *) Add options to some of the utilities to allow the pass phrase
+     to be included on either the command line (not recommended on
+     OSes like Unix) or read from the environment. Update the
+     manpages and fix a few bugs.
+     [Steve Henson]
+
+  *) Add a few manpages for some of the openssl commands.
+     [Steve Henson]
+
+  *) Fix the -revoke option in ca. It was freeing up memory twice,
+     leaking and not finding already revoked certificates.
+     [Steve Henson]
+
+  *) Extensive changes to support certificate auxiliary information.
+     This involves the use of X509_CERT_AUX structure and X509_AUX
+     functions. An X509_AUX function such as PEM_read_X509_AUX()
+     can still read in a certificate file in the usual way but it
+     will also read in any additional "auxiliary information". By
+     doing things this way a fair degree of compatibility can be
+     retained: existing certificates can have this information added
+     using the new 'x509' options. 
+
+     Current auxiliary information includes an "alias" and some trust
+     settings. The trust settings will ultimately be used in enhanced
+     certificate chain verification routines: currently a certificate
+     can only be trusted if it is self signed and then it is trusted
+     for all purposes.
+     [Steve Henson]
+
+  *) Fix assembler for Alpha (tested only on DEC OSF not Linux or *BSD).
+     The problem was that one of the replacement routines had not been working
+     since SSLeay releases.  For now the offending routine has been replaced
+     with non-optimised assembler.  Even so, this now gives around 95%
+     performance improvement for 1024 bit RSA signs.
+     [Mark Cox]
+
+  *) Hack to fix PKCS#7 decryption when used with some unorthodox RC2 
+     handling. Most clients have the effective key size in bits equal to
+     the key length in bits: so a 40 bit RC2 key uses a 40 bit (5 byte) key.
+     A few however don't do this and instead use the size of the decrypted key
+     to determine the RC2 key length and the AlgorithmIdentifier to determine
+     the effective key length. In this case the effective key length can still
+     be 40 bits but the key length can be 168 bits for example. This is fixed
+     by manually forcing an RC2 key into the EVP_PKEY structure because the
+     EVP code can't currently handle unusual RC2 key sizes: it always assumes
+     the key length and effective key length are equal.
+     [Steve Henson]
+
+  *) Add a bunch of functions that should simplify the creation of 
+     X509_NAME structures. Now you should be able to do:
+     X509_NAME_add_entry_by_txt(nm, "CN", MBSTRING_ASC, "Steve", -1, -1, 0);
+     and have it automatically work out the correct field type and fill in
+     the structures. The more adventurous can try:
+     X509_NAME_add_entry_by_txt(nm, field, MBSTRING_UTF8, str, -1, -1, 0);
+     and it will (hopefully) work out the correct multibyte encoding.
+     [Steve Henson]
+
+  *) Change the 'req' utility to use the new field handling and multibyte
+     copy routines. Before the DN field creation was handled in an ad hoc
+     way in req, ca, and x509 which was rather broken and didn't support
+     BMPStrings or UTF8Strings. Since some software doesn't implement
+     BMPStrings or UTF8Strings yet, they can be enabled using the config file
+     using the dirstring_type option. See the new comment in the default
+     openssl.cnf for more info.
+     [Steve Henson]
+
+  *) Make crypto/rand/md_rand.c more robust:
+     - Assure unique random numbers after fork().
+     - Make sure that concurrent threads access the global counter and
+       md serializably so that we never lose entropy in them
+       or use exactly the same state in multiple threads.
+       Access to the large state is not always serializable because
+       the additional locking could be a performance killer, and
+       md should be large enough anyway.
+     [Bodo Moeller]
+
+  *) New file apps/app_rand.c with commonly needed functionality
+     for handling the random seed file.
+
+     Use the random seed file in some applications that previously did not:
+          ca,
+          dsaparam -genkey (which also ignored its '-rand' option), 
+          s_client,
+          s_server,
+          x509 (when signing).
+     Except on systems with /dev/urandom, it is crucial to have a random
+     seed file at least for key creation, DSA signing, and for DH exchanges;
+     for RSA signatures we could do without one.
+
+     gendh and gendsa (unlike genrsa) used to read only the first byte
+     of each file listed in the '-rand' option.  The function as previously
+     found in genrsa is now in app_rand.c and is used by all programs
+     that support '-rand'.
+     [Bodo Moeller]
+
+  *) In RAND_write_file, use mode 0600 for creating files;
+     don't just chmod when it may be too late.
+     [Bodo Moeller]
+
+  *) Report an error from X509_STORE_load_locations
+     when X509_LOOKUP_load_file or X509_LOOKUP_add_dir failed.
+     [Bill Perry]
+
+  *) New function ASN1_mbstring_copy() this copies a string in either
+     ASCII, Unicode, Universal (4 bytes per character) or UTF8 format
+     into an ASN1_STRING type. A mask of permissible types is passed
+     and it chooses the "minimal" type to use or an error if not type
+     is suitable.
+     [Steve Henson]
+
+  *) Add function equivalents to the various macros in asn1.h. The old
+     macros are retained with an M_ prefix. Code inside the library can
+     use the M_ macros. External code (including the openssl utility)
+     should *NOT* in order to be "shared library friendly".
+     [Steve Henson]
+
+  *) Add various functions that can check a certificate's extensions
+     to see if it usable for various purposes such as SSL client,
+     server or S/MIME and CAs of these types. This is currently 
+     VERY EXPERIMENTAL but will ultimately be used for certificate chain
+     verification. Also added a -purpose flag to x509 utility to
+     print out all the purposes.
+     [Steve Henson]
+
+  *) Add a CRYPTO_EX_DATA to X509 certificate structure and associated
+     functions.
+     [Steve Henson]
+
+  *) New X509V3_{X509,CRL,REVOKED}_get_d2i() functions. These will search
+     for, obtain and decode and extension and obtain its critical flag.
+     This allows all the necessary extension code to be handled in a
+     single function call.
+     [Steve Henson]
+
+  *) RC4 tune-up featuring 30-40% performance improvement on most RISC
+     platforms. See crypto/rc4/rc4_enc.c for further details.
+     [Andy Polyakov]
+
+  *) New -noout option to asn1parse. This causes no output to be produced
+     its main use is when combined with -strparse and -out to extract data
+     from a file (which may not be in ASN.1 format).
+     [Steve Henson]
+
+  *) Fix for pkcs12 program. It was hashing an invalid certificate pointer
+     when producing the local key id.
+     [Richard Levitte <levitte@stacken.kth.se>]
+
+  *) New option -dhparam in s_server. This allows a DH parameter file to be
+     stated explicitly. If it is not stated then it tries the first server
+     certificate file. The previous behaviour hard coded the filename
+     "server.pem".
+     [Steve Henson]
+
+  *) Add -pubin and -pubout options to the rsa and dsa commands. These allow
+     a public key to be input or output. For example:
+     openssl rsa -in key.pem -pubout -out pubkey.pem
+     Also added necessary DSA public key functions to handle this.
+     [Steve Henson]
+
+  *) Fix so PKCS7_dataVerify() doesn't crash if no certificates are contained
+     in the message. This was handled by allowing
+     X509_find_by_issuer_and_serial() to tolerate a NULL passed to it.
+     [Steve Henson, reported by Sampo Kellomaki <sampo@mail.neuronio.pt>]
+
+  *) Fix for bug in d2i_ASN1_bytes(): other ASN1 functions add an extra null
+     to the end of the strings whereas this didn't. This would cause problems
+     if strings read with d2i_ASN1_bytes() were later modified.
+     [Steve Henson, reported by Arne Ansper <arne@ats.cyber.ee>]
+
+  *) Fix for base64 decode bug. When a base64 bio reads only one line of
+     data and it contains EOF it will end up returning an error. This is
+     caused by input 46 bytes long. The cause is due to the way base64
+     BIOs find the start of base64 encoded data. They do this by trying a
+     trial decode on each line until they find one that works. When they
+     do a flag is set and it starts again knowing it can pass all the
+     data directly through the decoder. Unfortunately it doesn't reset
+     the context it uses. This means that if EOF is reached an attempt
+     is made to pass two EOFs through the context and this causes the
+     resulting error. This can also cause other problems as well. As is
+     usual with these problems it takes *ages* to find and the fix is
+     trivial: move one line.
+     [Steve Henson, reported by ian@uns.ns.ac.yu (Ivan Nejgebauer) ]
+
+  *) Ugly workaround to get s_client and s_server working under Windows. The
+     old code wouldn't work because it needed to select() on sockets and the
+     tty (for keypresses and to see if data could be written). Win32 only
+     supports select() on sockets so we select() with a 1s timeout on the
+     sockets and then see if any characters are waiting to be read, if none
+     are present then we retry, we also assume we can always write data to
+     the tty. This isn't nice because the code then blocks until we've
+     received a complete line of data and it is effectively polling the
+     keyboard at 1s intervals: however it's quite a bit better than not
+     working at all :-) A dedicated Windows application might handle this
+     with an event loop for example.
+     [Steve Henson]
+
+  *) Enhance RSA_METHOD structure. Now there are two extra methods, rsa_sign
+     and rsa_verify. When the RSA_FLAGS_SIGN_VER option is set these functions
+     will be called when RSA_sign() and RSA_verify() are used. This is useful
+     if rsa_pub_dec() and rsa_priv_enc() equivalents are not available.
+     For this to work properly RSA_public_decrypt() and RSA_private_encrypt()
+     should *not* be used: RSA_sign() and RSA_verify() must be used instead.
+     This necessitated the support of an extra signature type NID_md5_sha1
+     for SSL signatures and modifications to the SSL library to use it instead
+     of calling RSA_public_decrypt() and RSA_private_encrypt().
+     [Steve Henson]
+
+  *) Add new -verify -CAfile and -CApath options to the crl program, these
+     will lookup a CRL issuers certificate and verify the signature in a
+     similar way to the verify program. Tidy up the crl program so it
+     no longer accesses structures directly. Make the ASN1 CRL parsing a bit
+     less strict. It will now permit CRL extensions even if it is not
+     a V2 CRL: this will allow it to tolerate some broken CRLs.
+     [Steve Henson]
+
+  *) Initialize all non-automatic variables each time one of the openssl
+     sub-programs is started (this is necessary as they may be started
+     multiple times from the "OpenSSL>" prompt).
+     [Lennart Bang, Bodo Moeller]
+
+  *) Preliminary compilation option RSA_NULL which disables RSA crypto without
+     removing all other RSA functionality (this is what NO_RSA does). This
+     is so (for example) those in the US can disable those operations covered
+     by the RSA patent while allowing storage and parsing of RSA keys and RSA
+     key generation.
+     [Steve Henson]
+
+  *) Non-copying interface to BIO pairs.
+     (still largely untested)
+     [Bodo Moeller]
+
+  *) New function ANS1_tag2str() to convert an ASN1 tag to a descriptive
+     ASCII string. This was handled independently in various places before.
+     [Steve Henson]
+
+  *) New functions UTF8_getc() and UTF8_putc() that parse and generate
+     UTF8 strings a character at a time.
+     [Steve Henson]
+
+  *) Use client_version from client hello to select the protocol
+     (s23_srvr.c) and for RSA client key exchange verification
+     (s3_srvr.c), as required by the SSL 3.0/TLS 1.0 specifications.
+     [Bodo Moeller]
+
+  *) Add various utility functions to handle SPKACs, these were previously
+     handled by poking round in the structure internals. Added new function
+     NETSCAPE_SPKI_print() to print out SPKAC and a new utility 'spkac' to
+     print, verify and generate SPKACs. Based on an original idea from
+     Massimiliano Pala <madwolf@comune.modena.it> but extensively modified.
+     [Steve Henson]
+
+  *) RIPEMD160 is operational on all platforms and is back in 'make test'.
+     [Andy Polyakov]
+
+  *) Allow the config file extension section to be overwritten on the
+     command line. Based on an original idea from Massimiliano Pala
+     <madwolf@comune.modena.it>. The new option is called -extensions
+     and can be applied to ca, req and x509. Also -reqexts to override
+     the request extensions in req and -crlexts to override the crl extensions
+     in ca.
+     [Steve Henson]
+
+  *) Add new feature to the SPKAC handling in ca.  Now you can include
+     the same field multiple times by preceding it by "XXXX." for example:
+     1.OU="Unit name 1"
+     2.OU="Unit name 2"
+     this is the same syntax as used in the req config file.
+     [Steve Henson]
+
+  *) Allow certificate extensions to be added to certificate requests. These
+     are specified in a 'req_extensions' option of the req section of the
+     config file. They can be printed out with the -text option to req but
+     are otherwise ignored at present.
+     [Steve Henson]
+
+  *) Fix a horrible bug in enc_read() in crypto/evp/bio_enc.c: if the first
+     data read consists of only the final block it would not decrypted because
+     EVP_CipherUpdate() would correctly report zero bytes had been decrypted.
+     A misplaced 'break' also meant the decrypted final block might not be
+     copied until the next read.
+     [Steve Henson]
+
+  *) Initial support for DH_METHOD. Again based on RSA_METHOD. Also added
+     a few extra parameters to the DH structure: these will be useful if
+     for example we want the value of 'q' or implement X9.42 DH.
+     [Steve Henson]
+
+  *) Initial support for DSA_METHOD. This is based on the RSA_METHOD and
+     provides hooks that allow the default DSA functions or functions on a
+     "per key" basis to be replaced. This allows hardware acceleration and
+     hardware key storage to be handled without major modification to the
+     library. Also added low level modexp hooks and CRYPTO_EX structure and 
+     associated functions.
+     [Steve Henson]
+
+  *) Add a new flag to memory BIOs, BIO_FLAG_MEM_RDONLY. This marks the BIO
+     as "read only": it can't be written to and the buffer it points to will
+     not be freed. Reading from a read only BIO is much more efficient than
+     a normal memory BIO. This was added because there are several times when
+     an area of memory needs to be read from a BIO. The previous method was
+     to create a memory BIO and write the data to it, this results in two
+     copies of the data and an O(n^2) reading algorithm. There is a new
+     function BIO_new_mem_buf() which creates a read only memory BIO from
+     an area of memory. Also modified the PKCS#7 routines to use read only
+     memory BIOs.
+     [Steve Henson]
+
+  *) Bugfix: ssl23_get_client_hello did not work properly when called in
+     state SSL23_ST_SR_CLNT_HELLO_B, i.e. when the first 7 bytes of
+     a SSLv2-compatible client hello for SSLv3 or TLSv1 could be read,
+     but a retry condition occurred while trying to read the rest.
+     [Bodo Moeller]
+
+  *) The PKCS7_ENC_CONTENT_new() function was setting the content type as
+     NID_pkcs7_encrypted by default: this was wrong since this should almost
+     always be NID_pkcs7_data. Also modified the PKCS7_set_type() to handle
+     the encrypted data type: this is a more sensible place to put it and it
+     allows the PKCS#12 code to be tidied up that duplicated this
+     functionality.
+     [Steve Henson]
+
+  *) Changed obj_dat.pl script so it takes its input and output files on
+     the command line. This should avoid shell escape redirection problems
+     under Win32.
+     [Steve Henson]
+
+  *) Initial support for certificate extension requests, these are included
+     in things like Xenroll certificate requests. Included functions to allow
+     extensions to be obtained and added.
+     [Steve Henson]
+
+  *) -crlf option to s_client and s_server for sending newlines as
+     CRLF (as required by many protocols).
+     [Bodo Moeller]
+
+ Changes between 0.9.3a and 0.9.4  [09 Aug 1999]
+  
+  *) Install libRSAglue.a when OpenSSL is built with RSAref.
+     [Ralf S. Engelschall]
+
+  *) A few more ``#ifndef NO_FP_API / #endif'' pairs for consistency.
+     [Andrija Antonijevic <TheAntony2@bigfoot.com>]
+
+  *) Fix -startdate and -enddate (which was missing) arguments to 'ca'
+     program.
+     [Steve Henson]
+
+  *) New function DSA_dup_DH, which duplicates DSA parameters/keys as
+     DH parameters/keys (q is lost during that conversion, but the resulting
+     DH parameters contain its length).
+
+     For 1024-bit p, DSA_generate_parameters followed by DSA_dup_DH is
+     much faster than DH_generate_parameters (which creates parameters
+     where p = 2*q + 1), and also the smaller q makes DH computations
+     much more efficient (160-bit exponentiation instead of 1024-bit
+     exponentiation); so this provides a convenient way to support DHE
+     ciphersuites in SSL/TLS servers (see ssl/ssltest.c).  It is of
+     utter importance to use
+         SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE);
+     or
+         SSL_set_options(s_ctx, SSL_OP_SINGLE_DH_USE);
+     when such DH parameters are used, because otherwise small subgroup
+     attacks may become possible!
+     [Bodo Moeller]
+
+  *) Avoid memory leak in i2d_DHparams.
+     [Bodo Moeller]
+
+  *) Allow the -k option to be used more than once in the enc program:
+     this allows the same encrypted message to be read by multiple recipients.
+     [Steve Henson]
+
+  *) New function OBJ_obj2txt(buf, buf_len, a, no_name), this converts
+     an ASN1_OBJECT to a text string. If the "no_name" parameter is set then
+     it will always use the numerical form of the OID, even if it has a short
+     or long name.
+     [Steve Henson]
+
+  *) Added an extra RSA flag: RSA_FLAG_EXT_PKEY. Previously the rsa_mod_exp
+     method only got called if p,q,dmp1,dmq1,iqmp components were present,
+     otherwise bn_mod_exp was called. In the case of hardware keys for example
+     no private key components need be present and it might store extra data
+     in the RSA structure, which cannot be accessed from bn_mod_exp.
+     By setting RSA_FLAG_EXT_PKEY rsa_mod_exp will always be called for
+     private key operations.
+     [Steve Henson]
+
+  *) Added support for SPARC Linux.
+     [Andy Polyakov]
+
+  *) pem_password_cb function type incompatibly changed from
+          typedef int pem_password_cb(char *buf, int size, int rwflag);
+     to
+          ....(char *buf, int size, int rwflag, void *userdata);
+     so that applications can pass data to their callbacks:
+     The PEM[_ASN1]_{read,write}... functions and macros now take an
+     additional void * argument, which is just handed through whenever
+     the password callback is called.
+     [Damien Miller <dmiller@ilogic.com.au>; tiny changes by Bodo Moeller]
+
+     New function SSL_CTX_set_default_passwd_cb_userdata.
+
+     Compatibility note: As many C implementations push function arguments
+     onto the stack in reverse order, the new library version is likely to
+     interoperate with programs that have been compiled with the old
+     pem_password_cb definition (PEM_whatever takes some data that
+     happens to be on the stack as its last argument, and the callback
+     just ignores this garbage); but there is no guarantee whatsoever that
+     this will work.
+
+  *) The -DPLATFORM="\"$(PLATFORM)\"" definition and the similar -DCFLAGS=...
+     (both in crypto/Makefile.ssl for use by crypto/cversion.c) caused
+     problems not only on Windows, but also on some Unix platforms.
+     To avoid problematic command lines, these definitions are now in an
+     auto-generated file crypto/buildinf.h (created by crypto/Makefile.ssl
+     for standard "make" builds, by util/mk1mf.pl for "mk1mf" builds).
+     [Bodo Moeller]
+
+  *) MIPS III/IV assembler module is reimplemented.
+     [Andy Polyakov]
+
+  *) More DES library cleanups: remove references to srand/rand and
+     delete an unused file.
+     [Ulf MÃ¶ller]
+
+  *) Add support for the the free Netwide assembler (NASM) under Win32,
+     since not many people have MASM (ml) and it can be hard to obtain.
+     This is currently experimental but it seems to work OK and pass all
+     the tests. Check out INSTALL.W32 for info.
+     [Steve Henson]
+
+  *) Fix memory leaks in s3_clnt.c: All non-anonymous SSL3/TLS1 connections
+     without temporary keys kept an extra copy of the server key,
+     and connections with temporary keys did not free everything in case
+     of an error.
+     [Bodo Moeller]
+
+  *) New function RSA_check_key and new openssl rsa option -check
+     for verifying the consistency of RSA keys.
+     [Ulf Moeller, Bodo Moeller]
+
+  *) Various changes to make Win32 compile work: 
+     1. Casts to avoid "loss of data" warnings in p5_crpt2.c
+     2. Change unsigned int to int in b_dump.c to avoid "signed/unsigned
+        comparison" warnings.
+     3. Add sk_<TYPE>_sort to DEF file generator and do make update.
+     [Steve Henson]
+
+  *) Add a debugging option to PKCS#5 v2 key generation function: when
+     you #define DEBUG_PKCS5V2 passwords, salts, iteration counts and
+     derived keys are printed to stderr.
+     [Steve Henson]
+
+  *) Copy the flags in ASN1_STRING_dup().
+     [Roman E. Pavlov <pre@mo.msk.ru>]
+
+  *) The x509 application mishandled signing requests containing DSA
+     keys when the signing key was also DSA and the parameters didn't match.
+
+     It was supposed to omit the parameters when they matched the signing key:
+     the verifying software was then supposed to automatically use the CA's
+     parameters if they were absent from the end user certificate.
+
+     Omitting parameters is no longer recommended. The test was also
+     the wrong way round! This was probably due to unusual behaviour in
+     EVP_cmp_parameters() which returns 1 if the parameters match. 
+     This meant that parameters were omitted when they *didn't* match and
+     the certificate was useless. Certificates signed with 'ca' didn't have
+     this bug.
+     [Steve Henson, reported by Doug Erickson <Doug.Erickson@Part.NET>]
+
+  *) Memory leak checking (-DCRYPTO_MDEBUG) had some problems.
+     The interface is as follows:
+     Applications can use
+         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) aka MemCheck_start(),
+         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF) aka MemCheck_stop();
+     "off" is now the default.
+     The library internally uses
+         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE) aka MemCheck_off(),
+         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE) aka MemCheck_on()
+     to disable memory-checking temporarily.
+
+     Some inconsistent states that previously were possible (and were
+     even the default) are now avoided.
+
+     -DCRYPTO_MDEBUG_TIME is new and additionally stores the current time
+     with each memory chunk allocated; this is occasionally more helpful
+     than just having a counter.
+
+     -DCRYPTO_MDEBUG_THREAD is also new and adds the thread ID.
+
+     -DCRYPTO_MDEBUG_ALL enables all of the above, plus any future
+     extensions.
+     [Bodo Moeller]
+
+  *) Introduce "mode" for SSL structures (with defaults in SSL_CTX),
+     which largely parallels "options", but is for changing API behaviour,
+     whereas "options" are about protocol behaviour.
+     Initial "mode" flags are:
+
+     SSL_MODE_ENABLE_PARTIAL_WRITE   Allow SSL_write to report success when
+                                     a single record has been written.
+     SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER  Don't insist that SSL_write
+                                     retries use the same buffer location.
+                                     (But all of the contents must be
+                                     copied!)
+     [Bodo Moeller]
+
+  *) Bugfix: SSL_set_options ignored its parameter, only SSL_CTX_set_options
+     worked.
+
+  *) Fix problems with no-hmac etc.
+     [Ulf MÃ¶ller, pointed out by Brian Wellington <bwelling@tislabs.com>]
+
+  *) New functions RSA_get_default_method(), RSA_set_method() and
+     RSA_get_method(). These allows replacement of RSA_METHODs without having
+     to mess around with the internals of an RSA structure.
+     [Steve Henson]
+
+  *) Fix memory leaks in DSA_do_sign and DSA_is_prime.
+     Also really enable memory leak checks in openssl.c and in some
+     test programs.
+     [Chad C. Mulligan, Bodo Moeller]
+
+  *) Fix a bug in d2i_ASN1_INTEGER() and i2d_ASN1_INTEGER() which can mess
+     up the length of negative integers. This has now been simplified to just
+     store the length when it is first determined and use it later, rather
+     than trying to keep track of where data is copied and updating it to
+     point to the end.
+     [Steve Henson, reported by Brien Wheeler
+      <bwheeler@authentica-security.com>]
+
+  *) Add a new function PKCS7_signatureVerify. This allows the verification
+     of a PKCS#7 signature but with the signing certificate passed to the
+     function itself. This contrasts with PKCS7_dataVerify which assumes the
+     certificate is present in the PKCS#7 structure. This isn't always the
+     case: certificates can be omitted from a PKCS#7 structure and be
+     distributed by "out of band" means (such as a certificate database).
+     [Steve Henson]
+
+  *) Complete the PEM_* macros with DECLARE_PEM versions to replace the
+     function prototypes in pem.h, also change util/mkdef.pl to add the
+     necessary function names. 
+     [Steve Henson]
+
+  *) mk1mf.pl (used by Windows builds) did not properly read the
+     options set by Configure in the top level Makefile, and Configure
+     was not even able to write more than one option correctly.
+     Fixed, now "no-idea no-rc5 -DCRYPTO_MDEBUG" etc. works as intended.
+     [Bodo Moeller]
+
+  *) New functions CONF_load_bio() and CONF_load_fp() to allow a config
+     file to be loaded from a BIO or FILE pointer. The BIO version will
+     for example allow memory BIOs to contain config info.
+     [Steve Henson]
+
+  *) New function "CRYPTO_num_locks" that returns CRYPTO_NUM_LOCKS.
+     Whoever hopes to achieve shared-library compatibility across versions
+     must use this, not the compile-time macro.
+     (Exercise 0.9.4: Which is the minimum library version required by
+     such programs?)
+     Note: All this applies only to multi-threaded programs, others don't
+     need locks.
+     [Bodo Moeller]
+
+  *) Add missing case to s3_clnt.c state machine -- one of the new SSL tests
+     through a BIO pair triggered the default case, i.e.
+     SSLerr(...,SSL_R_UNKNOWN_STATE).
+     [Bodo Moeller]
+
+  *) New "BIO pair" concept (crypto/bio/bss_bio.c) so that applications
+     can use the SSL library even if none of the specific BIOs is
+     appropriate.
+     [Bodo Moeller]
+
+  *) Fix a bug in i2d_DSAPublicKey() which meant it returned the wrong value
+     for the encoded length.
+     [Jeon KyoungHo <khjeon@sds.samsung.co.kr>]
+
+  *) Add initial documentation of the X509V3 functions.
+     [Steve Henson]
+
+  *) Add a new pair of functions PEM_write_PKCS8PrivateKey() and 
+     PEM_write_bio_PKCS8PrivateKey() that are equivalent to
+     PEM_write_PrivateKey() and PEM_write_bio_PrivateKey() but use the more
+     secure PKCS#8 private key format with a high iteration count.
+     [Steve Henson]
+
+  *) Fix determination of Perl interpreter: A perl or perl5
+     _directory_ in $PATH was also accepted as the interpreter.
+     [Ralf S. Engelschall]
+
+  *) Fix demos/sign/sign.c: well there wasn't anything strictly speaking
+     wrong with it but it was very old and did things like calling
+     PEM_ASN1_read() directly and used MD5 for the hash not to mention some
+     unusual formatting.
+     [Steve Henson]
+
+  *) Fix demos/selfsign.c: it used obsolete and deleted functions, changed
+     to use the new extension code.
+     [Steve Henson]
+
+  *) Implement the PEM_read/PEM_write functions in crypto/pem/pem_all.c
+     with macros. This should make it easier to change their form, add extra
+     arguments etc. Fix a few PEM prototypes which didn't have cipher as a
+     constant.
+     [Steve Henson]
+
+  *) Add to configuration table a new entry that can specify an alternative
+     name for unistd.h (for pre-POSIX systems); we need this for NeXTstep,
+     according to Mark Crispin <MRC@Panda.COM>.
+     [Bodo Moeller]
+
+#if 0
+  *) DES CBC did not update the IV. Weird.
+     [Ben Laurie]
+#else
+     des_cbc_encrypt does not update the IV, but des_ncbc_encrypt does.
+     Changing the behaviour of the former might break existing programs --
+     where IV updating is needed, des_ncbc_encrypt can be used.
+#endif
+
+  *) When bntest is run from "make test" it drives bc to check its
+     calculations, as well as internally checking them. If an internal check
+     fails, it needs to cause bc to give a non-zero result or make test carries
+     on without noticing the failure. Fixed.
+     [Ben Laurie]
+
+  *) DES library cleanups.
+     [Ulf MÃ¶ller]
+
+  *) Add support for PKCS#5 v2.0 PBE algorithms. This will permit PKCS#8 to be
+     used with any cipher unlike PKCS#5 v1.5 which can at most handle 64 bit
+     ciphers. NOTE: although the key derivation function has been verified
+     against some published test vectors it has not been extensively tested
+     yet. Added a -v2 "cipher" option to pkcs8 application to allow the use
+     of v2.0.
+     [Steve Henson]
+
+  *) Instead of "mkdir -p", which is not fully portable, use new
+     Perl script "util/mkdir-p.pl".
+     [Bodo Moeller]
+
+  *) Rewrite the way password based encryption (PBE) is handled. It used to
+     assume that the ASN1 AlgorithmIdentifier parameter was a PBEParameter
+     structure. This was true for the PKCS#5 v1.5 and PKCS#12 PBE algorithms
+     but doesn't apply to PKCS#5 v2.0 where it can be something else. Now
+     the 'parameter' field of the AlgorithmIdentifier is passed to the
+     underlying key generation function so it must do its own ASN1 parsing.
+     This has also changed the EVP_PBE_CipherInit() function which now has a
+     'parameter' argument instead of literal salt and iteration count values
+     and the function EVP_PBE_ALGOR_CipherInit() has been deleted.
+     [Steve Henson]
+
+  *) Support for PKCS#5 v1.5 compatible password based encryption algorithms
+     and PKCS#8 functionality. New 'pkcs8' application linked to openssl.
+     Needed to change the PEM_STRING_EVP_PKEY value which was just "PRIVATE
+     KEY" because this clashed with PKCS#8 unencrypted string. Since this
+     value was just used as a "magic string" and not used directly its
+     value doesn't matter.
+     [Steve Henson]
+
+  *) Introduce some semblance of const correctness to BN. Shame C doesn't
+     support mutable.
+     [Ben Laurie]
+
+  *) "linux-sparc64" configuration (ultrapenguin).
+     [Ray Miller <ray.miller@oucs.ox.ac.uk>]
+     "linux-sparc" configuration.
+     [Christian Forster <fo@hawo.stw.uni-erlangen.de>]
+
+  *) config now generates no-xxx options for missing ciphers.
+     [Ulf MÃ¶ller]
+
+  *) Support the EBCDIC character set (work in progress).
+     File ebcdic.c not yet included because it has a different license.
+     [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>]
+
+  *) Support BS2000/OSD-POSIX.
+     [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>]
+
+  *) Make callbacks for key generation use void * instead of char *.
+     [Ben Laurie]
+
+  *) Make S/MIME samples compile (not yet tested).
+     [Ben Laurie]
+
+  *) Additional typesafe stacks.
+     [Ben Laurie]
+
+  *) New configuration variants "bsdi-elf-gcc" (BSD/OS 4.x).
+     [Bodo Moeller]
+
+
+ Changes between 0.9.3 and 0.9.3a  [29 May 1999]
+
+  *) New configuration variant "sco5-gcc".
+
+  *) Updated some demos.
+     [Sean O Riordain, Wade Scholine]
+
+  *) Add missing BIO_free at exit of pkcs12 application.
+     [Wu Zhigang]
+
+  *) Fix memory leak in conf.c.
+     [Steve Henson]
+
+  *) Updates for Win32 to assembler version of MD5.
+     [Steve Henson]
+
+  *) Set #! path to perl in apps/der_chop to where we found it
+     instead of using a fixed path.
+     [Bodo Moeller]
+
+  *) SHA library changes for irix64-mips4-cc.
+     [Andy Polyakov]
+
+  *) Improvements for VMS support.
+     [Richard Levitte]
+
+
+ Changes between 0.9.2b and 0.9.3  [24 May 1999]
+
+  *) Bignum library bug fix. IRIX 6 passes "make test" now!
+     This also avoids the problems with SC4.2 and unpatched SC5.  
+     [Andy Polyakov <appro@fy.chalmers.se>]
+
+  *) New functions sk_num, sk_value and sk_set to replace the previous macros.
+     These are required because of the typesafe stack would otherwise break 
+     existing code. If old code used a structure member which used to be STACK
+     and is now STACK_OF (for example cert in a PKCS7_SIGNED structure) with
+     sk_num or sk_value it would produce an error because the num, data members
+     are not present in STACK_OF. Now it just produces a warning. sk_set
+     replaces the old method of assigning a value to sk_value
+     (e.g. sk_value(x, i) = y) which the library used in a few cases. Any code
+     that does this will no longer work (and should use sk_set instead) but
+     this could be regarded as a "questionable" behaviour anyway.
+     [Steve Henson]
+
+  *) Fix most of the other PKCS#7 bugs. The "experimental" code can now
+     correctly handle encrypted S/MIME data.
+     [Steve Henson]
+
+  *) Change type of various DES function arguments from des_cblock
+     (which means, in function argument declarations, pointer to char)
+     to des_cblock * (meaning pointer to array with 8 char elements),
+     which allows the compiler to do more typechecking; it was like
+     that back in SSLeay, but with lots of ugly casts.
+
+     Introduce new type const_des_cblock.
+     [Bodo Moeller]
+
+  *) Reorganise the PKCS#7 library and get rid of some of the more obvious
+     problems: find RecipientInfo structure that matches recipient certificate
+     and initialise the ASN1 structures properly based on passed cipher.
+     [Steve Henson]
+
+  *) Belatedly make the BN tests actually check the results.
+     [Ben Laurie]
+
+  *) Fix the encoding and decoding of negative ASN1 INTEGERS and conversion
+     to and from BNs: it was completely broken. New compilation option
+     NEG_PUBKEY_BUG to allow for some broken certificates that encode public
+     key elements as negative integers.
+     [Steve Henson]
+
+  *) Reorganize and speed up MD5.
+     [Andy Polyakov <appro@fy.chalmers.se>]
+
+  *) VMS support.
+     [Richard Levitte <richard@levitte.org>]
+
+  *) New option -out to asn1parse to allow the parsed structure to be
+     output to a file. This is most useful when combined with the -strparse
+     option to examine the output of things like OCTET STRINGS.
+     [Steve Henson]
+
+  *) Make SSL library a little more fool-proof by not requiring any longer
+     that SSL_set_{accept,connect}_state be called before
+     SSL_{accept,connect} may be used (SSL_set_..._state is omitted
+     in many applications because usually everything *appeared* to work as
+     intended anyway -- now it really works as intended).
+     [Bodo Moeller]
+
+  *) Move openssl.cnf out of lib/.
+     [Ulf MÃ¶ller]
+
+  *) Fix various things to let OpenSSL even pass ``egcc -pipe -O2 -Wall
+     -Wshadow -Wpointer-arith -Wcast-align -Wmissing-prototypes
+     -Wmissing-declarations -Wnested-externs -Winline'' with EGCS 1.1.2+ 
+     [Ralf S. Engelschall]
+
+  *) Various fixes to the EVP and PKCS#7 code. It may now be able to
+     handle PKCS#7 enveloped data properly.
+     [Sebastian Akerman <sak@parallelconsulting.com>, modified by Steve]
+
+  *) Create a duplicate of the SSL_CTX's CERT in SSL_new instead of
+     copying pointers.  The cert_st handling is changed by this in
+     various ways (and thus what used to be known as ctx->default_cert
+     is now called ctx->cert, since we don't resort to s->ctx->[default_]cert
+     any longer when s->cert does not give us what we need).
+     ssl_cert_instantiate becomes obsolete by this change.
+     As soon as we've got the new code right (possibly it already is?),
+     we have solved a couple of bugs of the earlier code where s->cert
+     was used as if it could not have been shared with other SSL structures.
+
+     Note that using the SSL API in certain dirty ways now will result
+     in different behaviour than observed with earlier library versions:
+     Changing settings for an SSL_CTX *ctx after having done s = SSL_new(ctx)
+     does not influence s as it used to.
+     
+     In order to clean up things more thoroughly, inside SSL_SESSION
+     we don't use CERT any longer, but a new structure SESS_CERT
+     that holds per-session data (if available); currently, this is
+     the peer's certificate chain and, for clients, the server's certificate
+     and temporary key.  CERT holds only those values that can have
+     meaningful defaults in an SSL_CTX.
+     [Bodo Moeller]
+
+  *) New function X509V3_EXT_i2d() to create an X509_EXTENSION structure
+     from the internal representation. Various PKCS#7 fixes: remove some
+     evil casts and set the enc_dig_alg field properly based on the signing
+     key type.
+     [Steve Henson]
+
+  *) Allow PKCS#12 password to be set from the command line or the
+     environment. Let 'ca' get its config file name from the environment
+     variables "OPENSSL_CONF" or "SSLEAY_CONF" (for consistency with 'req'
+     and 'x509').
+     [Steve Henson]
+
+  *) Allow certificate policies extension to use an IA5STRING for the
+     organization field. This is contrary to the PKIX definition but
+     VeriSign uses it and IE5 only recognises this form. Document 'x509'
+     extension option.
+     [Steve Henson]
+
+  *) Add PEDANTIC compiler flag to allow compilation with gcc -pedantic,
+     without disallowing inline assembler and the like for non-pedantic builds.
+     [Ben Laurie]
+
+  *) Support Borland C++ builder.
+     [Janez Jere <jj@void.si>, modified by Ulf MÃ¶ller]
+
+  *) Support Mingw32.
+     [Ulf MÃ¶ller]
+
+  *) SHA-1 cleanups and performance enhancements.
+     [Andy Polyakov <appro@fy.chalmers.se>]
+
+  *) Sparc v8plus assembler for the bignum library.
+     [Andy Polyakov <appro@fy.chalmers.se>]
+
+  *) Accept any -xxx and +xxx compiler options in Configure.
+     [Ulf MÃ¶ller]
+
+  *) Update HPUX configuration.
+     [Anonymous]
+  
+  *) Add missing sk_<type>_unshift() function to safestack.h
+     [Ralf S. Engelschall]
+
+  *) New function SSL_CTX_use_certificate_chain_file that sets the
+     "extra_cert"s in addition to the certificate.  (This makes sense
+     only for "PEM" format files, as chains as a whole are not
+     DER-encoded.)
+     [Bodo Moeller]
+
+  *) Support verify_depth from the SSL API.
+     x509_vfy.c had what can be considered an off-by-one-error:
+     Its depth (which was not part of the external interface)
+     was actually counting the number of certificates in a chain;
+     now it really counts the depth.
+     [Bodo Moeller]
+
+  *) Bugfix in crypto/x509/x509_cmp.c: The SSLerr macro was used
+     instead of X509err, which often resulted in confusing error
+     messages since the error codes are not globally unique
+     (e.g. an alleged error in ssl3_accept when a certificate
+     didn't match the private key).
+
+  *) New function SSL_CTX_set_session_id_context that allows to set a default
+     value (so that you don't need SSL_set_session_id_context for each
+     connection using the SSL_CTX).
+     [Bodo Moeller]
+
+  *) OAEP decoding bug fix.
+     [Ulf MÃ¶ller]
+
+  *) Support INSTALL_PREFIX for package builders, as proposed by
+     David Harris.
+     [Bodo Moeller]
+
+  *) New Configure options "threads" and "no-threads".  For systems
+     where the proper compiler options are known (currently Solaris
+     and Linux), "threads" is the default.
+     [Bodo Moeller]
+
+  *) New script util/mklink.pl as a faster substitute for util/mklink.sh.
+     [Bodo Moeller]
+
+  *) Install various scripts to $(OPENSSLDIR)/misc, not to
+     $(INSTALLTOP)/bin -- they shouldn't clutter directories
+     such as /usr/local/bin.
+     [Bodo Moeller]
+
+  *) "make linux-shared" to build shared libraries.
+     [Niels Poppe <niels@netbox.org>]
+
+  *) New Configure option no-<cipher> (rsa, idea, rc5, ...).
+     [Ulf MÃ¶ller]
+
+  *) Add the PKCS#12 API documentation to openssl.txt. Preliminary support for
+     extension adding in x509 utility.
+     [Steve Henson]
+
+  *) Remove NOPROTO sections and error code comments.
+     [Ulf MÃ¶ller]
+
+  *) Partial rewrite of the DEF file generator to now parse the ANSI
+     prototypes.
+     [Steve Henson]
+
+  *) New Configure options --prefix=DIR and --openssldir=DIR.
+     [Ulf MÃ¶ller]
+
+  *) Complete rewrite of the error code script(s). It is all now handled
+     by one script at the top level which handles error code gathering,
+     header rewriting and C source file generation. It should be much better
+     than the old method: it now uses a modified version of Ulf's parser to
+     read the ANSI prototypes in all header files (thus the old K&R definitions
+     aren't needed for error creation any more) and do a better job of
+     translating function codes into names. The old 'ASN1 error code imbedded
+     in a comment' is no longer necessary and it doesn't use .err files which
+     have now been deleted. Also the error code call doesn't have to appear all
+     on one line (which resulted in some large lines...).
+     [Steve Henson]
+
+  *) Change #include filenames from <foo.h> to <openssl/foo.h>.
+     [Bodo Moeller]
+
+  *) Change behaviour of ssl2_read when facing length-0 packets: Don't return
+     0 (which usually indicates a closed connection), but continue reading.
+     [Bodo Moeller]
+
+  *) Fix some race conditions.
+     [Bodo Moeller]
+
+  *) Add support for CRL distribution points extension. Add Certificate
+     Policies and CRL distribution points documentation.
+     [Steve Henson]
+
+  *) Move the autogenerated header file parts to crypto/opensslconf.h.
+     [Ulf MÃ¶ller]
+
+  *) Fix new 56-bit DES export ciphersuites: they were using 7 bytes instead of
+     8 of keying material. Merlin has also confirmed interop with this fix
+     between OpenSSL and Baltimore C/SSL 2.0 and J/SSL 2.0.
+     [Merlin Hughes <merlin@baltimore.ie>]
+
+  *) Fix lots of warnings.
+     [Richard Levitte <levitte@stacken.kth.se>]
+ 
+  *) In add_cert_dir() in crypto/x509/by_dir.c, break out of the loop if
+     the directory spec didn't end with a LIST_SEPARATOR_CHAR.
+     [Richard Levitte <levitte@stacken.kth.se>]
+ 
+  *) Fix problems with sizeof(long) == 8.
+     [Andy Polyakov <appro@fy.chalmers.se>]
+
+  *) Change functions to ANSI C.
+     [Ulf MÃ¶ller]
+
+  *) Fix typos in error codes.
+     [Martin Kraemer <Martin.Kraemer@MchP.Siemens.De>, Ulf MÃ¶ller]
+
+  *) Remove defunct assembler files from Configure.
+     [Ulf MÃ¶ller]
+
+  *) SPARC v8 assembler BIGNUM implementation.
+     [Andy Polyakov <appro@fy.chalmers.se>]
+
+  *) Support for Certificate Policies extension: both print and set.
+     Various additions to support the r2i method this uses.
+     [Steve Henson]
+
+  *) A lot of constification, and fix a bug in X509_NAME_oneline() that could
+     return a const string when you are expecting an allocated buffer.
+     [Ben Laurie]
+
+  *) Add support for ASN1 types UTF8String and VISIBLESTRING, also the CHOICE
+     types DirectoryString and DisplayText.
+     [Steve Henson]
+
+  *) Add code to allow r2i extensions to access the configuration database,
+     add an LHASH database driver and add several ctx helper functions.
+     [Steve Henson]
+
+  *) Fix an evil bug in bn_expand2() which caused various BN functions to
+     fail when they extended the size of a BIGNUM.
+     [Steve Henson]
+
+  *) Various utility functions to handle SXNet extension. Modify mkdef.pl to
+     support typesafe stack.
+     [Steve Henson]
+
+  *) Fix typo in SSL_[gs]et_options().
+     [Nils Frostberg <nils@medcom.se>]
+
+  *) Delete various functions and files that belonged to the (now obsolete)
+     old X509V3 handling code.
+     [Steve Henson]
+
+  *) New Configure option "rsaref".
+     [Ulf MÃ¶ller]
+
+  *) Don't auto-generate pem.h.
+     [Bodo Moeller]
+
+  *) Introduce type-safe ASN.1 SETs.
+     [Ben Laurie]
+
+  *) Convert various additional casted stacks to type-safe STACK_OF() variants.
+     [Ben Laurie, Ralf S. Engelschall, Steve Henson]
+
+  *) Introduce type-safe STACKs. This will almost certainly break lots of code
+     that links with OpenSSL (well at least cause lots of warnings), but fear
+     not: the conversion is trivial, and it eliminates loads of evil casts. A
+     few STACKed things have been converted already. Feel free to convert more.
+     In the fullness of time, I'll do away with the STACK type altogether.
+     [Ben Laurie]
+
+  *) Add `openssl ca -revoke <certfile>' facility which revokes a certificate
+     specified in <certfile> by updating the entry in the index.txt file.
+     This way one no longer has to edit the index.txt file manually for
+     revoking a certificate. The -revoke option does the gory details now.
+     [Massimiliano Pala <madwolf@openca.org>, Ralf S. Engelschall]
+
+  *) Fix `openssl crl -noout -text' combination where `-noout' killed the
+     `-text' option at all and this way the `-noout -text' combination was
+     inconsistent in `openssl crl' with the friends in `openssl x509|rsa|dsa'.
+     [Ralf S. Engelschall]
+
+  *) Make sure a corresponding plain text error message exists for the
+     X509_V_ERR_CERT_REVOKED/23 error number which can occur when a
+     verify callback function determined that a certificate was revoked.
+     [Ralf S. Engelschall]
+
+  *) Bugfix: In test/testenc, don't test "openssl <cipher>" for
+     ciphers that were excluded, e.g. by -DNO_IDEA.  Also, test
+     all available cipers including rc5, which was forgotten until now.
+     In order to let the testing shell script know which algorithms
+     are available, a new (up to now undocumented) command
+     "openssl list-cipher-commands" is used.
+     [Bodo Moeller]
+
+  *) Bugfix: s_client occasionally would sleep in select() when
+     it should have checked SSL_pending() first.
+     [Bodo Moeller]
+
+  *) New functions DSA_do_sign and DSA_do_verify to provide access to
+     the raw DSA values prior to ASN.1 encoding.
+     [Ulf MÃ¶ller]
+
+  *) Tweaks to Configure
+     [Niels Poppe <niels@netbox.org>]
+
+  *) Add support for PKCS#5 v2.0 ASN1 PBES2 structures. No other support,
+     yet...
+     [Steve Henson]
+
+  *) New variables $(RANLIB) and $(PERL) in the Makefiles.
+     [Ulf MÃ¶ller]
+
+  *) New config option to avoid instructions that are illegal on the 80386.
+     The default code is faster, but requires at least a 486.
+     [Ulf MÃ¶ller]
+  
+  *) Got rid of old SSL2_CLIENT_VERSION (inconsistently used) and
+     SSL2_SERVER_VERSION (not used at all) macros, which are now the
+     same as SSL2_VERSION anyway.
+     [Bodo Moeller]
+
+  *) New "-showcerts" option for s_client.
+     [Bodo Moeller]
+
+  *) Still more PKCS#12 integration. Add pkcs12 application to openssl
+     application. Various cleanups and fixes.
+     [Steve Henson]
+
+  *) More PKCS#12 integration. Add new pkcs12 directory with Makefile.ssl and
+     modify error routines to work internally. Add error codes and PBE init
+     to library startup routines.
+     [Steve Henson]
+
+  *) Further PKCS#12 integration. Added password based encryption, PKCS#8 and
+     packing functions to asn1 and evp. Changed function names and error
+     codes along the way.
+     [Steve Henson]
+
+  *) PKCS12 integration: and so it begins... First of several patches to
+     slowly integrate PKCS#12 functionality into OpenSSL. Add PKCS#12
+     objects to objects.h
+     [Steve Henson]
+
+  *) Add a new 'indent' option to some X509V3 extension code. Initial ASN1
+     and display support for Thawte strong extranet extension.
+     [Steve Henson]
+
+  *) Add LinuxPPC support.
+     [Jeff Dubrule <igor@pobox.org>]
+
+  *) Get rid of redundant BN file bn_mulw.c, and rename bn_div64 to
+     bn_div_words in alpha.s.
+     [Hannes Reinecke <H.Reinecke@hw.ac.uk> and Ben Laurie]
+
+  *) Make sure the RSA OAEP test is skipped under -DRSAref because
+     OAEP isn't supported when OpenSSL is built with RSAref.
+     [Ulf Moeller <ulf@fitug.de>]
+
+  *) Move definitions of IS_SET/IS_SEQUENCE inside crypto/asn1/asn1.h 
+     so they no longer are missing under -DNOPROTO. 
+     [Soren S. Jorvang <soren@t.dk>]
+
+
+ Changes between 0.9.1c and 0.9.2b  [22 Mar 1999]
+
+  *) Make SSL_get_peer_cert_chain() work in servers. Unfortunately, it still
+     doesn't work when the session is reused. Coming soon!
+     [Ben Laurie]
+
+  *) Fix a security hole, that allows sessions to be reused in the wrong
+     context thus bypassing client cert protection! All software that uses
+     client certs and session caches in multiple contexts NEEDS PATCHING to
+     allow session reuse! A fuller solution is in the works.
+     [Ben Laurie, problem pointed out by Holger Reif, Bodo Moeller (and ???)]
+
+  *) Some more source tree cleanups (removed obsolete files
+     crypto/bf/asm/bf586.pl, test/test.txt and crypto/sha/asm/f.s; changed
+     permission on "config" script to be executable) and a fix for the INSTALL
+     document.
+     [Ulf Moeller <ulf@fitug.de>]
+
+  *) Remove some legacy and erroneous uses of malloc, free instead of
+     Malloc, Free.
+     [Lennart Bang <lob@netstream.se>, with minor changes by Steve]
+
+  *) Make rsa_oaep_test return non-zero on error.
+     [Ulf Moeller <ulf@fitug.de>]
+
+  *) Add support for native Solaris shared libraries. Configure
+     solaris-sparc-sc4-pic, make, then run shlib/solaris-sc4.sh. It'd be nice
+     if someone would make that last step automatic.
+     [Matthias Loepfe <Matthias.Loepfe@AdNovum.CH>]
+
+  *) ctx_size was not built with the right compiler during "make links". Fixed.
+     [Ben Laurie]
+
+  *) Change the meaning of 'ALL' in the cipher list. It now means "everything
+     except NULL ciphers". This means the default cipher list will no longer
+     enable NULL ciphers. They need to be specifically enabled e.g. with
+     the string "DEFAULT:eNULL".
+     [Steve Henson]
+
+  *) Fix to RSA private encryption routines: if p < q then it would
+     occasionally produce an invalid result. This will only happen with
+     externally generated keys because OpenSSL (and SSLeay) ensure p > q.
+     [Steve Henson]
+
+  *) Be less restrictive and allow also `perl util/perlpath.pl
+     /path/to/bin/perl' in addition to `perl util/perlpath.pl /path/to/bin',
+     because this way one can also use an interpreter named `perl5' (which is
+     usually the name of Perl 5.xxx on platforms where an Perl 4.x is still
+     installed as `perl').
+     [Matthias Loepfe <Matthias.Loepfe@adnovum.ch>]
+
+  *) Let util/clean-depend.pl work also with older Perl 5.00x versions.
+     [Matthias Loepfe <Matthias.Loepfe@adnovum.ch>]
+
+  *) Fix Makefile.org so CC,CFLAG etc are passed to 'make links' add
+     advapi32.lib to Win32 build and change the pem test comparison
+     to fc.exe (thanks to Ulrich Kroener <kroneru@yahoo.com> for the
+     suggestion). Fix misplaced ASNI prototypes and declarations in evp.h
+     and crypto/des/ede_cbcm_enc.c.
+     [Steve Henson]
+
+  *) DES quad checksum was broken on big-endian architectures. Fixed.
+     [Ben Laurie]
+
+  *) Comment out two functions in bio.h that aren't implemented. Fix up the
+     Win32 test batch file so it (might) work again. The Win32 test batch file
+     is horrible: I feel ill....
+     [Steve Henson]
+
+  *) Move various #ifdefs around so NO_SYSLOG, NO_DIRENT etc are now selected
+     in e_os.h. Audit of header files to check ANSI and non ANSI
+     sections: 10 functions were absent from non ANSI section and not exported
+     from Windows DLLs. Fixed up libeay.num for new functions.
+     [Steve Henson]
+
+  *) Make `openssl version' output lines consistent.
+     [Ralf S. Engelschall]
+
+  *) Fix Win32 symbol export lists for BIO functions: Added
+     BIO_get_ex_new_index, BIO_get_ex_num, BIO_get_ex_data and BIO_set_ex_data
+     to ms/libeay{16,32}.def.
+     [Ralf S. Engelschall]
+
+  *) Second round of fixing the OpenSSL perl/ stuff. It now at least compiled
+     fine under Unix and passes some trivial tests I've now added. But the
+     whole stuff is horribly incomplete, so a README.1ST with a disclaimer was
+     added to make sure no one expects that this stuff really works in the
+     OpenSSL 0.9.2 release.  Additionally I've started to clean the XS sources
+     up and fixed a few little bugs and inconsistencies in OpenSSL.{pm,xs} and
+     openssl_bio.xs.
+     [Ralf S. Engelschall]
+
+  *) Fix the generation of two part addresses in perl.
+     [Kenji Miyake <kenji@miyake.org>, integrated by Ben Laurie]
+
+  *) Add config entry for Linux on MIPS.
+     [John Tobey <jtobey@channel1.com>]
+
+  *) Make links whenever Configure is run, unless we are on Windoze.
+     [Ben Laurie]
+
+  *) Permit extensions to be added to CRLs using crl_section in openssl.cnf.
+     Currently only issuerAltName and AuthorityKeyIdentifier make any sense
+     in CRLs.
+     [Steve Henson]
+
+  *) Add a useful kludge to allow package maintainers to specify compiler and
+     other platforms details on the command line without having to patch the
+     Configure script everytime: One now can use ``perl Configure
+     <id>:<details>'', i.e. platform ids are allowed to have details appended
+     to them (separated by colons). This is treated as there would be a static
+     pre-configured entry in Configure's %table under key <id> with value
+     <details> and ``perl Configure <id>'' is called.  So, when you want to
+     perform a quick test-compile under FreeBSD 3.1 with pgcc and without
+     assembler stuff you can use ``perl Configure "FreeBSD-elf:pgcc:-O6:::"''
+     now, which overrides the FreeBSD-elf entry on-the-fly.
+     [Ralf S. Engelschall]
+
+  *) Disable new TLS1 ciphersuites by default: they aren't official yet.
+     [Ben Laurie]
+
+  *) Allow DSO flags like -fpic, -fPIC, -KPIC etc. to be specified
+     on the `perl Configure ...' command line. This way one can compile
+     OpenSSL libraries with Position Independent Code (PIC) which is needed
+     for linking it into DSOs.
+     [Ralf S. Engelschall]
+
+  *) Remarkably, export ciphers were totally broken and no-one had noticed!
+     Fixed.
+     [Ben Laurie]
+
+  *) Cleaned up the LICENSE document: The official contact for any license
+     questions now is the OpenSSL core team under openssl-core@openssl.org.
+     And add a paragraph about the dual-license situation to make sure people
+     recognize that _BOTH_ the OpenSSL license _AND_ the SSLeay license apply
+     to the OpenSSL toolkit.
+     [Ralf S. Engelschall]
+
+  *) General source tree makefile cleanups: Made `making xxx in yyy...'
+     display consistent in the source tree and replaced `/bin/rm' by `rm'.
+     Additionally cleaned up the `make links' target: Remove unnecessary
+     semicolons, subsequent redundant removes, inline point.sh into mklink.sh
+     to speed processing and no longer clutter the display with confusing
+     stuff. Instead only the actually done links are displayed.
+     [Ralf S. Engelschall]
+
+  *) Permit null encryption ciphersuites, used for authentication only. It used
+     to be necessary to set the preprocessor define SSL_ALLOW_ENULL to do this.
+     It is now necessary to set SSL_FORBID_ENULL to prevent the use of null
+     encryption.
+     [Ben Laurie]
+
+  *) Add a bunch of fixes to the PKCS#7 stuff. It used to sometimes reorder
+     signed attributes when verifying signatures (this would break them), 
+     the detached data encoding was wrong and public keys obtained using
+     X509_get_pubkey() weren't freed.
+     [Steve Henson]
+
+  *) Add text documentation for the BUFFER functions. Also added a work around
+     to a Win95 console bug. This was triggered by the password read stuff: the
+     last character typed gets carried over to the next fread(). If you were 
+     generating a new cert request using 'req' for example then the last
+     character of the passphrase would be CR which would then enter the first
+     field as blank.
+     [Steve Henson]
+
+  *) Added the new `Includes OpenSSL Cryptography Software' button as
+     doc/openssl_button.{gif,html} which is similar in style to the old SSLeay
+     button and can be used by applications based on OpenSSL to show the
+     relationship to the OpenSSL project.  
+     [Ralf S. Engelschall]
+
+  *) Remove confusing variables in function signatures in files
+     ssl/ssl_lib.c and ssl/ssl.h.
+     [Lennart Bong <lob@kulthea.stacken.kth.se>]
+
+  *) Don't install bss_file.c under PREFIX/include/
+     [Lennart Bong <lob@kulthea.stacken.kth.se>]
+
+  *) Get the Win32 compile working again. Modify mkdef.pl so it can handle
+     functions that return function pointers and has support for NT specific
+     stuff. Fix mk1mf.pl and VC-32.pl to support NT differences also. Various
+     #ifdef WIN32 and WINNTs sprinkled about the place and some changes from
+     unsigned to signed types: this was killing the Win32 compile.
+     [Steve Henson]
+
+  *) Add new certificate file to stack functions,
+     SSL_add_dir_cert_subjects_to_stack() and
+     SSL_add_file_cert_subjects_to_stack().  These largely supplant
+     SSL_load_client_CA_file(), and can be used to add multiple certs easily
+     to a stack (usually this is then handed to SSL_CTX_set_client_CA_list()).
+     This means that Apache-SSL and similar packages don't have to mess around
+     to add as many CAs as they want to the preferred list.
+     [Ben Laurie]
+
+  *) Experiment with doxygen documentation. Currently only partially applied to
+     ssl/ssl_lib.c.
+     See http://www.stack.nl/~dimitri/doxygen/index.html, and run doxygen with
+     openssl.doxy as the configuration file.
+     [Ben Laurie]
+  
+  *) Get rid of remaining C++-style comments which strict C compilers hate.
+     [Ralf S. Engelschall, pointed out by Carlos Amengual]
+
+  *) Changed BN_RECURSION in bn_mont.c to BN_RECURSION_MONT so it is not
+     compiled in by default: it has problems with large keys.
+     [Steve Henson]
+
+  *) Add a bunch of SSL_xxx() functions for configuring the temporary RSA and
+     DH private keys and/or callback functions which directly correspond to
+     their SSL_CTX_xxx() counterparts but work on a per-connection basis. This
+     is needed for applications which have to configure certificates on a
+     per-connection basis (e.g. Apache+mod_ssl) instead of a per-context basis
+     (e.g. s_server). 
+        For the RSA certificate situation is makes no difference, but
+     for the DSA certificate situation this fixes the "no shared cipher"
+     problem where the OpenSSL cipher selection procedure failed because the
+     temporary keys were not overtaken from the context and the API provided
+     no way to reconfigure them. 
+        The new functions now let applications reconfigure the stuff and they
+     are in detail: SSL_need_tmp_RSA, SSL_set_tmp_rsa, SSL_set_tmp_dh,
+     SSL_set_tmp_rsa_callback and SSL_set_tmp_dh_callback.  Additionally a new
+     non-public-API function ssl_cert_instantiate() is used as a helper
+     function and also to reduce code redundancy inside ssl_rsa.c.
+     [Ralf S. Engelschall]
+
+  *) Move s_server -dcert and -dkey options out of the undocumented feature
+     area because they are useful for the DSA situation and should be
+     recognized by the users.
+     [Ralf S. Engelschall]
+
+  *) Fix the cipher decision scheme for export ciphers: the export bits are
+     *not* within SSL_MKEY_MASK or SSL_AUTH_MASK, they are within
+     SSL_EXP_MASK.  So, the original variable has to be used instead of the
+     already masked variable.
+     [Richard Levitte <levitte@stacken.kth.se>]
+
+  *) Fix 'port' variable from `int' to `unsigned int' in crypto/bio/b_sock.c
+     [Richard Levitte <levitte@stacken.kth.se>]
+
+  *) Change type of another md_len variable in pk7_doit.c:PKCS7_dataFinal()
+     from `int' to `unsigned int' because it's a length and initialized by
+     EVP_DigestFinal() which expects an `unsigned int *'.
+     [Richard Levitte <levitte@stacken.kth.se>]
+
+  *) Don't hard-code path to Perl interpreter on shebang line of Configure
+     script. Instead use the usual Shell->Perl transition trick.
+     [Ralf S. Engelschall]
+
+  *) Make `openssl x509 -noout -modulus' functional also for DSA certificates
+     (in addition to RSA certificates) to match the behaviour of `openssl dsa
+     -noout -modulus' as it's already the case for `openssl rsa -noout
+     -modulus'.  For RSA the -modulus is the real "modulus" while for DSA
+     currently the public key is printed (a decision which was already done by
+     `openssl dsa -modulus' in the past) which serves a similar purpose.
+     Additionally the NO_RSA no longer completely removes the whole -modulus
+     option; it now only avoids using the RSA stuff. Same applies to NO_DSA
+     now, too.
+     [Ralf S.  Engelschall]
+
+  *) Add Arne Ansper's reliable BIO - this is an encrypted, block-digested
+     BIO. See the source (crypto/evp/bio_ok.c) for more info.
+     [Arne Ansper <arne@ats.cyber.ee>]
+
+  *) Dump the old yucky req code that tried (and failed) to allow raw OIDs
+     to be added. Now both 'req' and 'ca' can use new objects defined in the
+     config file.
+     [Steve Henson]
+
+  *) Add cool BIO that does syslog (or event log on NT).
+     [Arne Ansper <arne@ats.cyber.ee>, integrated by Ben Laurie]
+
+  *) Add support for new TLS ciphersuites, TLS_RSA_EXPORT56_WITH_RC4_56_MD5,
+     TLS_RSA_EXPORT56_WITH_RC2_CBC_56_MD5 and
+     TLS_RSA_EXPORT56_WITH_DES_CBC_SHA, as specified in "56-bit Export Cipher
+     Suites For TLS", draft-ietf-tls-56-bit-ciphersuites-00.txt.
+     [Ben Laurie]
+
+  *) Add preliminary config info for new extension code.
+     [Steve Henson]
+
+  *) Make RSA_NO_PADDING really use no padding.
+     [Ulf Moeller <ulf@fitug.de>]
+
+  *) Generate errors when private/public key check is done.
+     [Ben Laurie]
+
+  *) Overhaul for 'crl' utility. New function X509_CRL_print. Partial support
+     for some CRL extensions and new objects added.
+     [Steve Henson]
+
+  *) Really fix the ASN1 IMPLICIT bug this time... Partial support for private
+     key usage extension and fuller support for authority key id.
+     [Steve Henson]
+
+  *) Add OAEP encryption for the OpenSSL crypto library. OAEP is the improved
+     padding method for RSA, which is recommended for new applications in PKCS
+     #1 v2.0 (RFC 2437, October 1998).
+     OAEP (Optimal Asymmetric Encryption Padding) has better theoretical
+     foundations than the ad-hoc padding used in PKCS #1 v1.5. It is secure
+     against Bleichbacher's attack on RSA.
+     [Ulf Moeller <ulf@fitug.de>, reformatted, corrected and integrated by
+      Ben Laurie]
+
+  *) Updates to the new SSL compression code
+     [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)]
+
+  *) Fix so that the version number in the master secret, when passed
+     via RSA, checks that if TLS was proposed, but we roll back to SSLv3
+     (because the server will not accept higher), that the version number
+     is 0x03,0x01, not 0x03,0x00
+     [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)]
+
+  *) Run extensive memory leak checks on SSL apps. Fixed *lots* of memory
+     leaks in ssl/ relating to new X509_get_pubkey() behaviour. Also fixes
+     in apps/ and an unrelated leak in crypto/dsa/dsa_vrf.c
+     [Steve Henson]
+
+  *) Support for RAW extensions where an arbitrary extension can be
+     created by including its DER encoding. See apps/openssl.cnf for
+     an example.
+     [Steve Henson]
+
+  *) Make sure latest Perl versions don't interpret some generated C array
+     code as Perl array code in the crypto/err/err_genc.pl script.
+     [Lars Weber <3weber@informatik.uni-hamburg.de>]
+
+  *) Modify ms/do_ms.bat to not generate assembly language makefiles since
+     not many people have the assembler. Various Win32 compilation fixes and
+     update to the INSTALL.W32 file with (hopefully) more accurate Win32
+     build instructions.
+     [Steve Henson]
+
+  *) Modify configure script 'Configure' to automatically create crypto/date.h
+     file under Win32 and also build pem.h from pem.org. New script
+     util/mkfiles.pl to create the MINFO file on environments that can't do a
+     'make files': perl util/mkfiles.pl >MINFO should work.
+     [Steve Henson]
+
+  *) Major rework of DES function declarations, in the pursuit of correctness
+     and purity. As a result, many evil casts evaporated, and some weirdness,
+     too. You may find this causes warnings in your code. Zapping your evil
+     casts will probably fix them. Mostly.
+     [Ben Laurie]
+
+  *) Fix for a typo in asn1.h. Bug fix to object creation script
+     obj_dat.pl. It considered a zero in an object definition to mean
+     "end of object": none of the objects in objects.h have any zeros
+     so it wasn't spotted.
+     [Steve Henson, reported by Erwann ABALEA <eabalea@certplus.com>]
+
+  *) Add support for Triple DES Cipher Block Chaining with Output Feedback
+     Masking (CBCM). In the absence of test vectors, the best I have been able
+     to do is check that the decrypt undoes the encrypt, so far. Send me test
+     vectors if you have them.
+     [Ben Laurie]
+
+  *) Correct calculation of key length for export ciphers (too much space was
+     allocated for null ciphers). This has not been tested!
+     [Ben Laurie]
+
+  *) Modifications to the mkdef.pl for Win32 DEF file creation. The usage
+     message is now correct (it understands "crypto" and "ssl" on its
+     command line). There is also now an "update" option. This will update
+     the util/ssleay.num and util/libeay.num files with any new functions.
+     If you do a: 
+     perl util/mkdef.pl crypto ssl update
+     it will update them.
+     [Steve Henson]
+
+  *) Overhauled the Perl interface (perl/*):
+     - ported BN stuff to OpenSSL's different BN library
+     - made the perl/ source tree CVS-aware
+     - renamed the package from SSLeay to OpenSSL (the files still contain
+       their history because I've copied them in the repository)
+     - removed obsolete files (the test scripts will be replaced
+       by better Test::Harness variants in the future)
+     [Ralf S. Engelschall]
+
+  *) First cut for a very conservative source tree cleanup:
+     1. merge various obsolete readme texts into doc/ssleay.txt
+     where we collect the old documents and readme texts.
+     2. remove the first part of files where I'm already sure that we no
+     longer need them because of three reasons: either they are just temporary
+     files which were left by Eric or they are preserved original files where
+     I've verified that the diff is also available in the CVS via "cvs diff
+     -rSSLeay_0_8_1b" or they were renamed (as it was definitely the case for
+     the crypto/md/ stuff).
+     [Ralf S. Engelschall]
+
+  *) More extension code. Incomplete support for subject and issuer alt
+     name, issuer and authority key id. Change the i2v function parameters
+     and add an extra 'crl' parameter in the X509V3_CTX structure: guess
+     what that's for :-) Fix to ASN1 macro which messed up
+     IMPLICIT tag and add f_enum.c which adds a2i, i2a for ENUMERATED.
+     [Steve Henson]
+
+  *) Preliminary support for ENUMERATED type. This is largely copied from the
+     INTEGER code.
+     [Steve Henson]
+
+  *) Add new function, EVP_MD_CTX_copy() to replace frequent use of memcpy.
+     [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)]
+
+  *) Make sure `make rehash' target really finds the `openssl' program.
+     [Ralf S. Engelschall, Matthias Loepfe <Matthias.Loepfe@adnovum.ch>]
+
+  *) Squeeze another 7% of speed out of MD5 assembler, at least on a P2. I'd
+     like to hear about it if this slows down other processors.
+     [Ben Laurie]
+
+  *) Add CygWin32 platform information to Configure script.
+     [Alan Batie <batie@aahz.jf.intel.com>]
+
+  *) Fixed ms/32all.bat script: `no_asm' -> `no-asm'
+     [Rainer W. Gerling <gerling@mpg-gv.mpg.de>]
+  
+  *) New program nseq to manipulate netscape certificate sequences
+     [Steve Henson]
+
+  *) Modify crl2pkcs7 so it supports multiple -certfile arguments. Fix a
+     few typos.
+     [Steve Henson]
+
+  *) Fixes to BN code.  Previously the default was to define BN_RECURSION
+     but the BN code had some problems that would cause failures when
+     doing certificate verification and some other functions.
+     [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)]
+
+  *) Add ASN1 and PEM code to support netscape certificate sequences.
+     [Steve Henson]
+
+  *) Add ASN1 and PEM code to support netscape certificate sequences.
+     [Steve Henson]
+
+  *) Add several PKIX and private extended key usage OIDs.
+     [Steve Henson]
+
+  *) Modify the 'ca' program to handle the new extension code. Modify
+     openssl.cnf for new extension format, add comments.
+     [Steve Henson]
+
+  *) More X509 V3 changes. Fix typo in v3_bitstr.c. Add support to 'req'
+     and add a sample to openssl.cnf so req -x509 now adds appropriate
+     CA extensions.
+     [Steve Henson]
+
+  *) Continued X509 V3 changes. Add to other makefiles, integrate with the
+     error code, add initial support to X509_print() and x509 application.
+     [Steve Henson]
+
+  *) Takes a deep breath and start adding X509 V3 extension support code. Add
+     files in crypto/x509v3. Move original stuff to crypto/x509v3/old. All this
+     stuff is currently isolated and isn't even compiled yet.
+     [Steve Henson]
+
+  *) Continuing patches for GeneralizedTime. Fix up certificate and CRL
+     ASN1 to use ASN1_TIME and modify print routines to use ASN1_TIME_print.
+     Removed the versions check from X509 routines when loading extensions:
+     this allows certain broken certificates that don't set the version
+     properly to be processed.
+     [Steve Henson]
+
+  *) Deal with irritating shit to do with dependencies, in YAAHW (Yet Another
+     Ad Hoc Way) - Makefile.ssls now all contain local dependencies, which
+     can still be regenerated with "make depend".
+     [Ben Laurie]
+
+  *) Spelling mistake in C version of CAST-128.
+     [Ben Laurie, reported by Jeremy Hylton <jeremy@cnri.reston.va.us>]
+
+  *) Changes to the error generation code. The perl script err-code.pl 
+     now reads in the old error codes and retains the old numbers, only
+     adding new ones if necessary. It also only changes the .err files if new
+     codes are added. The makefiles have been modified to only insert errors
+     when needed (to avoid needlessly modifying header files). This is done
+     by only inserting errors if the .err file is newer than the auto generated
+     C file. To rebuild all the error codes from scratch (the old behaviour)
+     either modify crypto/Makefile.ssl to pass the -regen flag to err_code.pl
+     or delete all the .err files.
+     [Steve Henson]
+
+  *) CAST-128 was incorrectly implemented for short keys. The C version has
+     been fixed, but is untested. The assembler versions are also fixed, but
+     new assembler HAS NOT BEEN GENERATED FOR WIN32 - the Makefile needs fixing
+     to regenerate it if needed.
+     [Ben Laurie, reported (with fix for C version) by Jun-ichiro itojun
+      Hagino <itojun@kame.net>]
+
+  *) File was opened incorrectly in randfile.c.
+     [Ulf MÃ¶ller <ulf@fitug.de>]
+
+  *) Beginning of support for GeneralizedTime. d2i, i2d, check and print
+     functions. Also ASN1_TIME suite which is a CHOICE of UTCTime or
+     GeneralizedTime. ASN1_TIME is the proper type used in certificates et
+     al: it's just almost always a UTCTime. Note this patch adds new error
+     codes so do a "make errors" if there are problems.
+     [Steve Henson]
+
+  *) Correct Linux 1 recognition in config.
+     [Ulf MÃ¶ller <ulf@fitug.de>]
+
+  *) Remove pointless MD5 hash when using DSA keys in ca.
+     [Anonymous <nobody@replay.com>]
+
+  *) Generate an error if given an empty string as a cert directory. Also
+     generate an error if handed NULL (previously returned 0 to indicate an
+     error, but didn't set one).
+     [Ben Laurie, reported by Anonymous <nobody@replay.com>]
+
+  *) Add prototypes to SSL methods. Make SSL_write's buffer const, at last.
+     [Ben Laurie]
+
+  *) Fix the dummy function BN_ref_mod_exp() in rsaref.c to have the correct
+     parameters. This was causing a warning which killed off the Win32 compile.
+     [Steve Henson]
+
+  *) Remove C++ style comments from crypto/bn/bn_local.h.
+     [Neil Costigan <neil.costigan@celocom.com>]
+
+  *) The function OBJ_txt2nid was broken. It was supposed to return a nid
+     based on a text string, looking up short and long names and finally
+     "dot" format. The "dot" format stuff didn't work. Added new function
+     OBJ_txt2obj to do the same but return an ASN1_OBJECT and rewrote 
+     OBJ_txt2nid to use it. OBJ_txt2obj can also return objects even if the
+     OID is not part of the table.
+     [Steve Henson]
+
+  *) Add prototypes to X509 lookup/verify methods, fixing a bug in
+     X509_LOOKUP_by_alias().
+     [Ben Laurie]
+
+  *) Sort openssl functions by name.
+     [Ben Laurie]
+
+  *) Get the gendsa program working (hopefully) and add it to app list. Remove
+     encryption from sample DSA keys (in case anyone is interested the password
+     was "1234").
+     [Steve Henson]
+
+  *) Make _all_ *_free functions accept a NULL pointer.
+     [Frans Heymans <fheymans@isaserver.be>]
+
+  *) If a DH key is generated in s3_srvr.c, don't blow it by trying to use
+     NULL pointers.
+     [Anonymous <nobody@replay.com>]
+
+  *) s_server should send the CAfile as acceptable CAs, not its own cert.
+     [Bodo Moeller <3moeller@informatik.uni-hamburg.de>]
+
+  *) Don't blow it for numeric -newkey arguments to apps/req.
+     [Bodo Moeller <3moeller@informatik.uni-hamburg.de>]
+
+  *) Temp key "for export" tests were wrong in s3_srvr.c.
+     [Anonymous <nobody@replay.com>]
+
+  *) Add prototype for temp key callback functions
+     SSL_CTX_set_tmp_{rsa,dh}_callback().
+     [Ben Laurie]
+
+  *) Make DH_free() tolerate being passed a NULL pointer (like RSA_free() and
+     DSA_free()). Make X509_PUBKEY_set() check for errors in d2i_PublicKey().
+     [Steve Henson]
+
+  *) X509_name_add_entry() freed the wrong thing after an error.
+     [Arne Ansper <arne@ats.cyber.ee>]
+
+  *) rsa_eay.c would attempt to free a NULL context.
+     [Arne Ansper <arne@ats.cyber.ee>]
+
+  *) BIO_s_socket() had a broken should_retry() on Windoze.
+     [Arne Ansper <arne@ats.cyber.ee>]
+
+  *) BIO_f_buffer() didn't pass on BIO_CTRL_FLUSH.
+     [Arne Ansper <arne@ats.cyber.ee>]
+
+  *) Make sure the already existing X509_STORE->depth variable is initialized
+     in X509_STORE_new(), but document the fact that this variable is still
+     unused in the certificate verification process.
+     [Ralf S. Engelschall]
+
+  *) Fix the various library and apps files to free up pkeys obtained from
+     X509_PUBKEY_get() et al. Also allow x509.c to handle netscape extensions.
+     [Steve Henson]
+
+  *) Fix reference counting in X509_PUBKEY_get(). This makes
+     demos/maurice/example2.c work, amongst others, probably.
+     [Steve Henson and Ben Laurie]
+
+  *) First cut of a cleanup for apps/. First the `ssleay' program is now named
+     `openssl' and second, the shortcut symlinks for the `openssl <command>'
+     are no longer created. This way we have a single and consistent command
+     line interface `openssl <command>', similar to `cvs <command>'.
+     [Ralf S. Engelschall, Paul Sutton and Ben Laurie]
+
+  *) ca.c: move test for DSA keys inside #ifndef NO_DSA. Make pubkey
+     BIT STRING wrapper always have zero unused bits.
+     [Steve Henson]
+
+  *) Add CA.pl, perl version of CA.sh, add extended key usage OID.
+     [Steve Henson]
+
+  *) Make the top-level INSTALL documentation easier to understand.
+     [Paul Sutton]
+
+  *) Makefiles updated to exit if an error occurs in a sub-directory
+     make (including if user presses ^C) [Paul Sutton]
+
+  *) Make Montgomery context stuff explicit in RSA data structure.
+     [Ben Laurie]
+
+  *) Fix build order of pem and err to allow for generated pem.h.
+     [Ben Laurie]
+
+  *) Fix renumbering bug in X509_NAME_delete_entry().
+     [Ben Laurie]
+
+  *) Enhanced the err-ins.pl script so it makes the error library number 
+     global and can add a library name. This is needed for external ASN1 and
+     other error libraries.
+     [Steve Henson]
+
+  *) Fixed sk_insert which never worked properly.
+     [Steve Henson]
+
+  *) Fix ASN1 macros so they can handle indefinite length constructed 
+     EXPLICIT tags. Some non standard certificates use these: they can now
+     be read in.
+     [Steve Henson]
+
+  *) Merged the various old/obsolete SSLeay documentation files (doc/xxx.doc)
+     into a single doc/ssleay.txt bundle. This way the information is still
+     preserved but no longer messes up this directory. Now it's new room for
+     the new set of documentation files.
+     [Ralf S. Engelschall]
+
+  *) SETs were incorrectly DER encoded. This was a major pain, because they
+     shared code with SEQUENCEs, which aren't coded the same. This means that
+     almost everything to do with SETs or SEQUENCEs has either changed name or
+     number of arguments.
+     [Ben Laurie, based on a partial fix by GP Jayan <gp@nsj.co.jp>]
+
+  *) Fix test data to work with the above.
+     [Ben Laurie]
+
+  *) Fix the RSA header declarations that hid a bug I fixed in 0.9.0b but
+     was already fixed by Eric for 0.9.1 it seems.
+     [Ben Laurie - pointed out by Ulf MÃ¶ller <ulf@fitug.de>]
+
+  *) Autodetect FreeBSD3.
+     [Ben Laurie]
+
+  *) Fix various bugs in Configure. This affects the following platforms:
+     nextstep
+     ncr-scde
+     unixware-2.0
+     unixware-2.0-pentium
+     sco5-cc.
+     [Ben Laurie]
+
+  *) Eliminate generated files from CVS. Reorder tests to regenerate files
+     before they are needed.
+     [Ben Laurie]
+
+  *) Generate Makefile.ssl from Makefile.org (to keep CVS happy).
+     [Ben Laurie]
+
+
+ Changes between 0.9.1b and 0.9.1c  [23-Dec-1998]
+
+  *) Added OPENSSL_VERSION_NUMBER to crypto/crypto.h and 
+     changed SSLeay to OpenSSL in version strings.
+     [Ralf S. Engelschall]
+  
+  *) Some fixups to the top-level documents.
+     [Paul Sutton]
+
+  *) Fixed the nasty bug where rsaref.h was not found under compile-time
+     because the symlink to include/ was missing.
+     [Ralf S. Engelschall]
+
+  *) Incorporated the popular no-RSA/DSA-only patches 
+     which allow to compile a RSA-free SSLeay.
+     [Andrew Cooke / Interrader Ldt., Ralf S. Engelschall]
+
+  *) Fixed nasty rehash problem under `make -f Makefile.ssl links'
+     when "ssleay" is still not found.
+     [Ralf S. Engelschall]
+
+  *) Added more platforms to Configure: Cray T3E, HPUX 11, 
+     [Ralf S. Engelschall, Beckmann <beckman@acl.lanl.gov>]
+
+  *) Updated the README file.
+     [Ralf S. Engelschall]
+
+  *) Added various .cvsignore files in the CVS repository subdirs
+     to make a "cvs update" really silent.
+     [Ralf S. Engelschall]
+
+  *) Recompiled the error-definition header files and added
+     missing symbols to the Win32 linker tables.
+     [Ralf S. Engelschall]
+
+  *) Cleaned up the top-level documents;
+     o new files: CHANGES and LICENSE
+     o merged VERSION, HISTORY* and README* files a CHANGES.SSLeay 
+     o merged COPYRIGHT into LICENSE
+     o removed obsolete TODO file
+     o renamed MICROSOFT to INSTALL.W32
+     [Ralf S. Engelschall]
+
+  *) Removed dummy files from the 0.9.1b source tree: 
+     crypto/asn1/x crypto/bio/cd crypto/bio/fg crypto/bio/grep crypto/bio/vi
+     crypto/bn/asm/......add.c crypto/bn/asm/a.out crypto/dsa/f crypto/md5/f
+     crypto/pem/gmon.out crypto/perlasm/f crypto/pkcs7/build crypto/rsa/f
+     crypto/sha/asm/f crypto/threads/f ms/zzz ssl/f ssl/f.mak test/f
+     util/f.mak util/pl/f util/pl/f.mak crypto/bf/bf_locl.old apps/f
+     [Ralf S. Engelschall]
+
+  *) Added various platform portability fixes.
+     [Mark J. Cox]
+
+  *) The Genesis of the OpenSSL rpject:
+     We start with the latest (unreleased) SSLeay version 0.9.1b which Eric A.
+     Young and Tim J. Hudson created while they were working for C2Net until
+     summer 1998.
+     [The OpenSSL Project]
+ 
+
+ Changes between 0.9.0b and 0.9.1b  [not released]
+
+  *) Updated a few CA certificates under certs/
+     [Eric A. Young]
+
+  *) Changed some BIGNUM api stuff.
+     [Eric A. Young]
+
+  *) Various platform ports: OpenBSD, Ultrix, IRIX 64bit, NetBSD, 
+     DGUX x86, Linux Alpha, etc.
+     [Eric A. Young]
+
+  *) New COMP library [crypto/comp/] for SSL Record Layer Compression: 
+     RLE (dummy implemented) and ZLIB (really implemented when ZLIB is
+     available).
+     [Eric A. Young]
+
+  *) Add -strparse option to asn1pars program which parses nested 
+     binary structures 
+     [Dr Stephen Henson <shenson@bigfoot.com>]
+
+  *) Added "oid_file" to ssleay.cnf for "ca" and "req" programs.
+     [Eric A. Young]
+
+  *) DSA fix for "ca" program.
+     [Eric A. Young]
+
+  *) Added "-genkey" option to "dsaparam" program.
+     [Eric A. Young]
+
+  *) Added RIPE MD160 (rmd160) message digest.
+     [Eric A. Young]
+
+  *) Added -a (all) option to "ssleay version" command.
+     [Eric A. Young]
+
+  *) Added PLATFORM define which is the id given to Configure.
+     [Eric A. Young]
+
+  *) Added MemCheck_XXXX functions to crypto/mem.c for memory checking.
+     [Eric A. Young]
+
+  *) Extended the ASN.1 parser routines.
+     [Eric A. Young]
+
+  *) Extended BIO routines to support REUSEADDR, seek, tell, etc.
+     [Eric A. Young]
+
+  *) Added a BN_CTX to the BN library.
+     [Eric A. Young]
+
+  *) Fixed the weak key values in DES library
+     [Eric A. Young]
+
+  *) Changed API in EVP library for cipher aliases.
+     [Eric A. Young]
+
+  *) Added support for RC2/64bit cipher.
+     [Eric A. Young]
+
+  *) Converted the lhash library to the crypto/mem.c functions.
+     [Eric A. Young]
+
+  *) Added more recognized ASN.1 object ids.
+     [Eric A. Young]
+
+  *) Added more RSA padding checks for SSL/TLS.
+     [Eric A. Young]
+
+  *) Added BIO proxy/filter functionality.
+     [Eric A. Young]
+
+  *) Added extra_certs to SSL_CTX which can be used
+     send extra CA certificates to the client in the CA cert chain sending
+     process. It can be configured with SSL_CTX_add_extra_chain_cert().
+     [Eric A. Young]
+
+  *) Now Fortezza is denied in the authentication phase because
+     this is key exchange mechanism is not supported by SSLeay at all.
+     [Eric A. Young]
+
+  *) Additional PKCS1 checks.
+     [Eric A. Young]
+
+  *) Support the string "TLSv1" for all TLS v1 ciphers.
+     [Eric A. Young]
+
+  *) Added function SSL_get_ex_data_X509_STORE_CTX_idx() which gives the
+     ex_data index of the SSL context in the X509_STORE_CTX ex_data.
+     [Eric A. Young]
+
+  *) Fixed a few memory leaks.
+     [Eric A. Young]
+
+  *) Fixed various code and comment typos.
+     [Eric A. Young]
+
+  *) A minor bug in ssl/s3_clnt.c where there would always be 4 0 
+     bytes sent in the client random.
+     [Edward Bishop <ebishop@spyglass.com>]
+
Index: EcnlProtoTool/trunk/openssl-1.1.0e/CONTRIBUTING
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/CONTRIBUTING	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/CONTRIBUTING	(revision 331)
@@ -0,0 +1,54 @@
+HOW TO CONTRIBUTE PATCHES TO OpenSSL
+------------------------------------
+
+(Please visit https://www.openssl.org/community/getting-started.html for
+other ideas about how to contribute.)
+
+Development is coordinated on the openssl-dev mailing list (see the
+above link or https://mta.openssl.org for information on subscribing).
+If you are unsure as to whether a feature will be useful for the general
+OpenSSL community you might want to discuss it on the openssl-dev mailing
+list first.  Someone may be already working on the same thing or there
+may be a good reason as to why that feature isn't implemented.
+
+To submit a patch, make a pull request on GitHub.  If you think the patch
+could use feedback from the community, please start a thread on openssl-dev
+to discuss it.
+
+Having addressed the following items before the PR will help make the
+acceptance and review process faster:
+
+    1. Anything other than trivial contributions will require a contributor
+    licensing agreement, giving us permission to use your code. See
+    https://www.openssl.org/policies/cla.html for details.
+
+    2.  All source files should start with the following text (with
+    appropriate comment characters at the start of each line and the
+    year(s) updated):
+
+        Copyright 20xx-20yy 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
+
+    3.  Patches should be as current as possible; expect to have to rebase
+    often. We do not accept merge commits; You will be asked to remove
+    them before a patch is considered acceptable.
+
+    4.  Patches should follow our coding style (see
+    https://www.openssl.org/policies/codingstyle.html) and compile without
+    warnings. Where gcc or clang is available you should use the
+    --strict-warnings Configure option.  OpenSSL compiles on many varied
+    platforms: try to ensure you only use portable features.
+    Clean builds via Travis and AppVeyor are expected, and done whenever
+    a PR is created or updated.
+
+    5.  When at all possible, patches should include tests. These can
+    either be added to an existing test, or completely new.  Please see
+    test/README for information on the test framework.
+
+    6.  New features or changed functionality must include
+    documentation. Please look at the "pod" files in doc/apps, doc/crypto
+    and doc/ssl for examples of our style.
Index: EcnlProtoTool/trunk/openssl-1.1.0e/FAQ
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/FAQ	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/FAQ	(revision 331)
@@ -0,0 +1,2 @@
+The FAQ is now maintained on the web:
+        https://www.openssl.org/docs/faq.html
Index: EcnlProtoTool/trunk/openssl-1.1.0e/INSTALL
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/INSTALL	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/INSTALL	(revision 331)
@@ -0,0 +1,951 @@
+
+ OPENSSL INSTALLATION
+ --------------------
+
+ This document describes installation on all supported operating
+ systems (the Linux/Unix family, OpenVMS and Windows)
+
+ To install OpenSSL, you will need:
+
+  * A make implementation
+  * Perl 5 with core modules (please read NOTES.PERL)
+  * The perl module Text::Template (please read NOTES.PERL)
+  * an ANSI C compiler
+  * a development environment in the form of development libraries and C
+    header files
+  * a supported operating system
+
+ For additional platform specific requirements, solutions to specific
+ issues and other details, please read one of these:
+
+  * NOTES.VMS (OpenVMS)
+  * NOTES.WIN (any supported Windows)
+  * NOTES.DJGPP (DOS platform with DJGPP)
+
+ Notational conventions in this document
+ ---------------------------------------
+
+ Throughout this document, we use the following conventions in command
+ examples:
+
+ $ command                      Any line starting with a dollar sign
+                                ($) is a command line.
+
+ { word1 | word2 | word3 }      This denotes a mandatory choice, to be
+                                replaced with one of the given words.
+                                A simple example would be this:
+
+                                $ echo { FOO | BAR | COOKIE }
+
+                                which is to be understood as one of
+                                these:
+
+                                $ echo FOO
+                                - or -
+                                $ echo BAR
+                                - or -
+                                $ echo COOKIE
+
+ [ word1 | word2 | word3 ]      Similar to { word1 | word2 | word3 }
+                                except it's optional to give any of
+                                those.  In addition to the examples
+                                above, this would also be valid:
+
+                                $ echo
+
+ {{ target }}                   This denotes a mandatory word or
+                                sequence of words of some sort.  A
+                                simple example would be this:
+
+                                $ type {{ filename }}
+
+                                which is to be understood to use the
+                                command 'type' on some file name
+                                determined by the user.
+
+ [[ options ]]                  Similar to {{ target }}, but is
+                                optional.
+
+ Note that the notation assumes spaces around {, }, [, ], {{, }} and
+ [[, ]].  This is to differentiate from OpenVMS directory
+ specifications, which also use [ and ], but without spaces.
+
+ Quick Start
+ -----------
+
+ If you want to just get on with it, do:
+
+  on Unix:
+
+    $ ./config
+    $ make
+    $ make test
+    $ make install
+
+  on OpenVMS:
+
+    $ @config
+    $ mms
+    $ mms test
+    $ mms install
+
+  on Windows (only pick one of the targets for configuration):
+
+    $ perl Configure { VC-WIN32 | VC-WIN64A | VC-WIN64I | VC-CE }
+    $ nmake
+    $ nmake test
+    $ nmake install
+
+ If any of these steps fails, see section Installation in Detail below.
+
+ This will build and install OpenSSL in the default location, which is:
+
+  Unix:    normal installation directories under /usr/local
+  OpenVMS: SYS$COMMON:[OPENSSL-'version'...], where 'version' is the
+           OpenSSL version number with underscores instead of periods.
+  Windows: C:\Program Files\OpenSSL or C:\Program Files (x86)\OpenSSL
+
+ If you want to install it anywhere else, run config like this:
+
+  On Unix:
+
+    $ ./config --prefix=/opt/openssl --openssldir=/usr/local/ssl
+
+  On OpenVMS:
+
+    $ @config --prefix=PROGRAM:[INSTALLS] --openssldir=SYS$MANAGER:[OPENSSL]
+
+
+ Configuration Options
+ ---------------------
+
+ There are several options to ./config (or ./Configure) to customize
+ the build (note that for Windows, the defaults for --prefix and
+ --openssldir depend in what configuration is used and what Windows
+ implementation OpenSSL is built on.  More notes on this in NOTES.WIN):
+
+  --api=x.y.z
+                   Don't build with support for deprecated APIs below the
+                   specified version number. For example "--api=1.1.0" will
+                   remove support for all APIS that were deprecated in OpenSSL
+                   version 1.1.0 or below.
+
+  --cross-compile-prefix=PREFIX
+                   The PREFIX to include in front of commands for your
+                   toolchain. It's likely to have to end with dash, e.g.
+                   a-b-c- would invoke GNU compiler as a-b-c-gcc, etc.
+                   Unfortunately cross-compiling is too case-specific to
+                   put together one-size-fits-all instructions. You might
+                   have to pass more flags or set up environment variables
+                   to actually make it work. Android and iOS cases are
+                   discussed in corresponding Configurations/10-main.cf
+                   sections. But there are cases when this option alone is
+                   sufficient. For example to build the mingw64 target on
+                   Linux "--cross-compile-prefix=x86_64-w64-mingw32-"
+                   works. Naturally provided that mingw packages are
+                   installed. Today Debian and Ubuntu users have option to
+                   install a number of prepackaged cross-compilers along
+                   with corresponding run-time and development packages for
+                   "alien" hardware. To give another example
+                   "--cross-compile-prefix=mipsel-linux-gnu-" suffices
+                   in such case. Needless to mention that you have to
+                   invoke ./Configure, not ./config, and pass your target
+                   name explicitly.
+
+  --debug
+                   Build OpenSSL with debugging symbols.
+
+  --libdir=DIR
+                   The name of the directory under the top of the installation
+                   directory tree (see the --prefix option) where libraries will
+                   be installed. By default this is "lib". Note that on Windows
+                   only ".lib" files will be stored in this location. dll files
+                   will always be installed to the "bin" directory.
+
+  --openssldir=DIR
+                   Directory for OpenSSL configuration files, and also the
+                   default certificate and key store.  Defaults are:
+
+                   Unix:           /usr/local/ssl
+                   Windows:        C:\Program Files\Common Files\SSL
+                                or C:\Program Files (x86)\Common Files\SSL
+                   OpenVMS:        SYS$COMMON:[OPENSSL-COMMON]
+
+  --prefix=DIR
+                   The top of the installation directory tree.  Defaults are:
+
+                   Unix:           /usr/local
+                   Windows:        C:\Program Files\OpenSSL
+                                or C:\Program Files (x86)\OpenSSL
+                   OpenVMS:        SYS$COMMON:[OPENSSL-'version']
+
+  --release
+                   Build OpenSSL without debugging symbols. This is the default.
+
+  --strict-warnings
+                   This is a developer flag that switches on various compiler
+                   options recommended for OpenSSL development. It only works
+                   when using gcc or clang as the compiler. If you are
+                   developing a patch for OpenSSL then it is recommended that
+                   you use this option where possible.
+
+  --with-zlib-include=DIR
+                   The directory for the location of the zlib include file. This
+                   option is only necessary if enable-zlib (see below) is used
+                   and the include file is not already on the system include
+                   path.
+
+  --with-zlib-lib=LIB
+                   On Unix: this is the directory containing the zlib library.
+                   If not provided the system library path will be used.
+                   On Windows: this is the filename of the zlib library (with or
+                   without a path). This flag must be provided if the
+                   zlib-dynamic option is not also used. If zlib-dynamic is used
+                   then this flag is optional and a default value ("ZLIB1") is
+                   used if not provided. 
+                   On VMS: this is the filename of the zlib library (with or
+                   without a path). This flag is optional and if not provided
+                   then "GNV$LIBZSHR", "GNV$LIBZSHR32" or "GNV$LIBZSHR64" is
+                   used by default depending on the pointer size chosen.
+
+  no-afalgeng
+                   Don't build the AFALG engine. This option will be forced if
+                   on a platform that does not support AFALG.
+
+  enable-asan
+                   Build with the Address sanitiser. This is a developer option
+                   only. It may not work on all platforms and should never be
+                   used in production environments. It will only work when used
+                   with gcc or clang and should be used in conjunction with the
+                   no-shared option.
+
+  no-asm
+                   Do not use assembler code. On some platforms a small amount
+                   of assembler code may still be used.
+
+  no-async
+                   Do not build support for async operations.
+
+  no-autoalginit
+                   Don't automatically load all supported ciphers and digests.
+                   Typically OpenSSL will make available all of its supported
+                   ciphers and digests. For a statically linked application this
+                   may be undesirable if small executable size is an objective.
+                   This only affects libcrypto. Ciphers and digests will have to
+                   be loaded manually using EVP_add_cipher() and
+                   EVP_add_digest() if this option is used. This option will
+                   force a non-shared build.
+
+  no-autoerrinit
+                   Don't automatically load all libcrypto/libssl error strings.
+                   Typically OpenSSL will automatically load human readable
+                   error strings. For a statically linked application this may
+                   be undesirable if small executable size is an objective.
+
+
+  no-capieng
+                   Don't build the CAPI engine. This option will be forced if
+                   on a platform that does not support CAPI.
+
+  no-cms
+                   Don't build support for CMS features
+
+  no-comp
+                   Don't build support for SSL/TLS compression. If this option
+                   is left enabled (the default), then compression will only
+                   work if the zlib or zlib-dynamic options are also chosen.
+
+  enable-crypto-mdebug
+                   Build support for debugging memory allocated via
+                   OPENSSL_malloc() or OPENSSL_zalloc().
+
+  enable-crypto-mdebug-backtrace
+                   As for crypto-mdebug, but additionally provide backtrace
+                   information for allocated memory.
+                   TO BE USED WITH CARE: this uses GNU C functionality, and
+                   is therefore not usable for non-GNU config targets.  If
+                   your build complains about the use of '-rdynamic' or the
+                   lack of header file execinfo.h, this option is not for you.
+                   ALSO NOTE that even though execinfo.h is available on your
+                   system (through Gnulib), the functions might just be stubs
+                   that do nothing.
+
+  no-ct
+                   Don't build support for Certificate Transparency.
+
+  no-deprecated
+                   Don't build with support for any deprecated APIs. This is the
+                   same as using "--api" and supplying the latest version
+                   number.
+
+  no-dgram
+                   Don't build support for datagram based BIOs. Selecting this
+                   option will also force the disabling of DTLS.
+
+  no-dso
+                   Don't build support for loading Dynamic Shared Objects.
+
+  no-dynamic-engine
+                   Don't build the dynamically loaded engines. This only has an
+                   effect in a "shared" build
+
+  no-ec
+                   Don't build support for Elliptic Curves.
+
+  no-ec2m
+                   Don't build support for binary Elliptic Curves
+
+  enable-ec_nistp_64_gcc_128
+                   Enable support for optimised implementations of some commonly
+                   used NIST elliptic curves. This is only supported on some
+                   platforms.
+
+  enable-egd
+                   Build support for gathering entropy from EGD (Entropy
+                   Gathering Daemon).
+
+  no-engine
+                   Don't build support for loading engines.
+
+  no-err
+                   Don't compile in any error strings.
+
+  no-filenames
+                   Don't compile in filename and line number information (e.g.
+                   for errors and memory allocation).
+
+  enable-fuzz-libfuzzer, enable-fuzz-afl
+                   Build with support for fuzzing using either libfuzzer or AFL.
+                   These are developer options only. They may not work on all
+                   platforms and should never be used in production environments.
+                   See the file fuzz/README.md for further details.
+
+  no-gost
+                   Don't build support for GOST based ciphersuites. Note that
+                   if this feature is enabled then GOST ciphersuites are only
+                   available if the GOST algorithms are also available through
+                   loading an externally supplied engine.
+
+  enable-heartbeats
+                   Build support for DTLS heartbeats.
+
+  no-hw-padlock
+                   Don't build the padlock engine.
+
+  no-makedepend
+                   Don't generate dependencies.
+
+  no-multiblock
+                   Don't build support for writing multiple records in one
+                   go in libssl (Note: this is a different capability to the
+                   pipelining functionality).
+
+  no-nextprotoneg
+                   Don't build support for the NPN TLS extension.
+
+  no-ocsp
+                   Don't build support for OCSP.
+
+  no-pic
+                   Don't build with support for Position Independent Code.
+
+  no-posix-io
+                   Don't use POSIX IO capabilities.
+
+  no-psk
+                   Don't build support for Pre-Shared Key based ciphersuites.
+
+  no-rdrand
+                   Don't use hardware RDRAND capabilities.
+
+  no-rfc3779
+                   Don't build support for RFC3779 ("X.509 Extensions for IP
+                   Addresses and AS Identifiers")
+
+  sctp
+                   Build support for SCTP
+
+  no-shared
+                   Do not create shared libraries, only static ones.  See "Note
+                   on shared libraries" below.
+
+  no-sock
+                   Don't build support for socket BIOs
+
+  no-srp
+                   Don't build support for SRP or SRP based ciphersuites.
+
+  no-srtp
+                   Don't build SRTP support
+
+  no-sse2
+                   Exclude SSE2 code paths from 32-bit x86 assembly modules.
+                   Normally SSE2 extension is detected at run-time, but the
+                   decision whether or not the machine code will be executed
+                   is taken solely on CPU capability vector. This means that
+                   if you happen to run OS kernel which does not support SSE2
+                   extension on Intel P4 processor, then your application
+                   might be exposed to "illegal instruction" exception.
+                   There might be a way to enable support in kernel, e.g.
+                   FreeBSD kernel can  be compiled with CPU_ENABLE_SSE, and
+                   there is a way to disengage SSE2 code paths upon application
+                   start-up, but if you aim for wider "audience" running
+                   such kernel, consider no-sse2. Both the 386 and
+                   no-asm options imply no-sse2.
+
+  enable-ssl-trace
+                   Build with the SSL Trace capabilities (adds the "-trace"
+                   option to s_client and s_server).
+
+  no-static-engine
+                   Don't build the statically linked engines. This only
+                   has an impact when not built "shared".
+
+  no-stdio
+                   Don't use any C "stdio" features. Only libcrypto and libssl
+                   can be built in this way. Using this option will suppress
+                   building the command line applications. Additionally since
+                   the OpenSSL tests also use the command line applications the
+                   tests will also be skipped.
+
+  no-threads
+                   Don't try to build with support for multi-threaded
+                   applications.
+
+  threads
+                   Build with support for multi-threaded applications. Most
+                   platforms will enable this by default. However if on a
+                   platform where this is not the case then this will usually
+                   require additional system-dependent options! See "Note on
+                   multi-threading" below.
+
+  no-ts
+                   Don't build Time Stamping Authority support.
+
+  enable-ubsan
+                   Build with the Undefined Behaviour sanitiser. This is a
+                   developer option only. It may not work on all platforms and
+                   should never be used in production environments. It will only
+                   work when used with gcc or clang and should be used in
+                   conjunction with the "-DPEDANTIC" option (or the
+                   --strict-warnings option).
+
+  no-ui
+                   Don't build with the "UI" capability (i.e. the set of
+                   features enabling text based prompts).
+
+  enable-unit-test
+                   Enable additional unit test APIs. This should not typically
+                   be used in production deployments.
+
+  enable-weak-ssl-ciphers
+                   Build support for SSL/TLS ciphers that are considered "weak"
+                   (e.g. RC4 based ciphersuites).
+
+  zlib
+                   Build with support for zlib compression/decompression.
+
+  zlib-dynamic
+                   Like "zlib", but has OpenSSL load the zlib library
+                   dynamically when needed.  This is only supported on systems
+                   where loading of shared libraries is supported.
+
+  386
+                   In 32-bit x86 builds, when generating assembly modules,
+                   use the 80386 instruction set only (the default x86 code
+                   is more efficient, but requires at least a 486). Note:
+                   This doesn't affect code generated by compiler, you're
+                   likely to complement configuration command line with
+                   suitable compiler-specific option.
+
+  no-<prot>
+                   Don't build support for negotiating the specified SSL/TLS
+                   protocol (one of ssl, ssl3, tls, tls1, tls1_1, tls1_2, dtls,
+                   dtls1 or dtls1_2). If "no-tls" is selected then all of tls1,
+                   tls1_1 and tls1_2 are disabled. Similarly "no-dtls" will
+                   disable dtls1 and dtls1_2. The "no-ssl" option is synonymous
+                   with "no-ssl3". Note this only affects version negotiation.
+                   OpenSSL will still provide the methods for applications to
+                   explicitly select the individual protocol versions.
+
+  no-<prot>-method
+                   As for no-<prot> but in addition do not build the methods for
+                   applications to explicitly select individual protocol
+                   versions.
+
+  enable-<alg>
+                   Build with support for the specified algorithm, where <alg>
+                   is one of: md2 or rc5.
+
+  no-<alg>
+                   Build without support for the specified algorithm, where
+                   <alg> is one of: bf, blake2, camellia, cast, chacha, cmac,
+                   des, dh, dsa, ecdh, ecdsa, idea, md4, mdc2, ocb, poly1305,
+                   rc2, rc4, rmd160, scrypt, seed or whirlpool. The "ripemd"
+                   algorithm is deprecated and if used is synonymous with rmd160.
+
+  -Dxxx, -lxxx, -Lxxx, -fxxx, -mXXX, -Kxxx
+                   These system specific options will be passed through to the
+                   compiler to allow you to define preprocessor symbols, specify
+                   additional libraries, library directories or other compiler
+                   options. It might be worth noting that some compilers
+                   generate code specifically for processor the compiler
+                   currently executes on. This is not necessarily what you might
+                   have in mind, since it might be unsuitable for execution on
+                   other, typically older, processor. Consult your compiler
+                   documentation.
+
+
+ Installation in Detail
+ ----------------------
+
+ 1a. Configure OpenSSL for your operation system automatically:
+
+     NOTE: This is not available on Windows.
+
+       $ ./config [[ options ]]                         # Unix
+
+       or
+
+       $ @config [[ options ]]                          ! OpenVMS
+
+     For the remainder of this text, the Unix form will be used in all
+     examples, please use the appropriate form for your platform.
+
+     This guesses at your operating system (and compiler, if necessary) and
+     configures OpenSSL based on this guess. Run ./config -t to see
+     if it guessed correctly. If you want to use a different compiler, you
+     are cross-compiling for another platform, or the ./config guess was
+     wrong for other reasons, go to step 1b. Otherwise go to step 2.
+
+     On some systems, you can include debugging information as follows:
+
+       $ ./config -d [[ options ]]
+
+ 1b. Configure OpenSSL for your operating system manually
+
+     OpenSSL knows about a range of different operating system, hardware and
+     compiler combinations. To see the ones it knows about, run
+
+       $ ./Configure                                    # Unix
+
+       or
+
+       $ perl Configure                                 # All other platforms
+
+     For the remainder of this text, the Unix form will be used in all
+     examples, please use the appropriate form for your platform.
+
+     Pick a suitable name from the list that matches your system. For most
+     operating systems there is a choice between using "cc" or "gcc".  When
+     you have identified your system (and if necessary compiler) use this name
+     as the argument to Configure. For example, a "linux-elf" user would
+     run:
+
+       $ ./Configure linux-elf [[ options ]]
+
+     If your system isn't listed, you will have to create a configuration
+     file named Configurations/{{ something }}.conf and add the correct
+     configuration for your system. See the available configs as examples
+     and read Configurations/README and Configurations/README.design for
+     more information.
+
+     The generic configurations "cc" or "gcc" should usually work on 32 bit
+     Unix-like systems.
+
+     Configure creates a build file ("Makefile" on Unix, "makefile" on Windows
+     and "descrip.mms" on OpenVMS) from a suitable template in Configurations,
+     and defines various macros in include/openssl/opensslconf.h (generated from
+     include/openssl/opensslconf.h.in).
+
+ 1c. Configure OpenSSL for building outside of the source tree.
+
+     OpenSSL can be configured to build in a build directory separate from
+     the directory with the source code.  It's done by placing yourself in
+     some other directory and invoking the configuration commands from
+     there.
+
+     Unix example:
+
+       $ mkdir /var/tmp/openssl-build
+       $ cd /var/tmp/openssl-build
+       $ /PATH/TO/OPENSSL/SOURCE/config [[ options ]]
+
+       or
+
+       $ /PATH/TO/OPENSSL/SOURCE/Configure {{ target }} [[ options ]]
+
+     OpenVMS example:
+
+       $ set default sys$login:
+       $ create/dir [.tmp.openssl-build]
+       $ set default [.tmp.openssl-build]
+       $ @[PATH.TO.OPENSSL.SOURCE]config [[ options ]]
+
+       or
+
+       $ @[PATH.TO.OPENSSL.SOURCE]Configure {{ target }} [[ options ]]
+
+     Windows example:
+
+       $ C:
+       $ mkdir \temp-openssl
+       $ cd \temp-openssl
+       $ perl d:\PATH\TO\OPENSSL\SOURCE\Configure {{ target }} [[ options ]]
+
+     Paths can be relative just as well as absolute.  Configure will
+     do its best to translate them to relative paths whenever possible.
+
+  2. Build OpenSSL by running:
+
+       $ make                                           # Unix
+       $ mms                                            ! (or mmk) OpenVMS
+       $ nmake                                          # Windows
+
+     This will build the OpenSSL libraries (libcrypto.a and libssl.a on
+     Unix, corresponding on other platforms) and the OpenSSL binary
+     ("openssl"). The libraries will be built in the top-level directory,
+     and the binary will be in the "apps" subdirectory.
+
+     If the build fails, look at the output.  There may be reasons
+     for the failure that aren't problems in OpenSSL itself (like
+     missing standard headers).  If you are having problems you can
+     get help by sending an email to the openssl-users email list (see
+     https://www.openssl.org/community/mailinglists.html for details). If
+     it is a bug with OpenSSL itself, please open an issue on GitHub, at
+     https://github.com/openssl/openssl/issues. Please review the existing
+     ones first; maybe the bug was already reported or has already been
+     fixed.
+
+     (If you encounter assembler error messages, try the "no-asm"
+     configuration option as an immediate fix.)
+
+     Compiling parts of OpenSSL with gcc and others with the system
+     compiler will result in unresolved symbols on some systems.
+
+  3. After a successful build, the libraries should be tested. Run:
+
+       $ make test                                      # Unix
+       $ mms test                                       ! OpenVMS
+       $ nmake test                                     # Windows
+
+     NOTE: you MUST run the tests from an unprivileged account (or
+     disable your privileges temporarily if your platform allows it).
+
+     If some tests fail, look at the output.  There may be reasons for
+     the failure that isn't a problem in OpenSSL itself (like a
+     malfunction with Perl).  You may want increased verbosity, that
+     can be accomplished like this:
+
+       $ make VERBOSE=1 test                            # Unix
+
+       $ mms /macro=(VERBOSE=1) test                    ! OpenVMS
+
+       $ nmake VERBOSE=1 test                           # Windows
+
+     If you want to run just one or a few specific tests, you can use
+     the make variable TESTS to specify them, like this:
+
+       $ make TESTS='test_rsa test_dsa' test            # Unix
+       $ mms/macro="TESTS=test_rsa test_dsa" test       ! OpenVMS
+       $ nmake TESTS='test_rsa test_dsa' test           # Windows
+
+     And of course, you can combine (Unix example shown):
+       
+       $ make VERBOSE=1 TESTS='test_rsa test_dsa' test
+
+     You can find the list of available tests like this:
+
+       $ make list-tests                                # Unix
+       $ mms list-tests                                 ! OpenVMS
+       $ nmake list-tests                               # Windows
+
+     Have a look at the manual for the perl module Test::Harness to
+     see what other HARNESS_* variables there are.
+
+     If you find a problem with OpenSSL itself, try removing any
+     compiler optimization flags from the CFLAGS line in Makefile and
+     run "make clean; make" or corresponding.
+
+     Please send bug reports to <rt@openssl.org>.
+
+  4. If everything tests ok, install OpenSSL with
+
+       $ make install                                   # Unix
+       $ mms install                                    ! OpenVMS
+       $ nmake install                                  # Windows
+
+     This will install all the software components in this directory
+     tree under PREFIX (the directory given with --prefix or its
+     default):
+
+       Unix:
+
+         bin/           Contains the openssl binary and a few other
+                        utility scripts.
+         include/openssl
+                        Contains the header files needed if you want
+                        to build your own programs that use libcrypto
+                        or libssl.
+         lib            Contains the OpenSSL library files.
+         lib/engines    Contains the OpenSSL dynamically loadable engines.
+
+         share/man/man1 Contains the OpenSSL command line man-pages.
+         share/man/man3 Contains the OpenSSL library calls man-pages.
+         share/man/man5 Contains the OpenSSL configuration format man-pages.
+         share/man/man7 Contains the OpenSSL other misc man-pages.
+
+         share/doc/openssl/html/man1
+         share/doc/openssl/html/man3
+         share/doc/openssl/html/man5
+         share/doc/openssl/html/man7
+                        Contains the HTML rendition of the man-pages.
+
+       OpenVMS ('arch' is replaced with the architecture name, "Alpha"
+       or "ia64", 'sover' is replaced with the shared library version
+       (0101 for 1.1), and 'pz' is replaced with the pointer size
+       OpenSSL was built with):
+
+         [.EXE.'arch']  Contains the openssl binary.
+         [.EXE]         Contains a few utility scripts.
+         [.include.openssl]
+                        Contains the header files needed if you want
+                        to build your own programs that use libcrypto
+                        or libssl.
+         [.LIB.'arch']  Contains the OpenSSL library files.
+         [.ENGINES'sover''pz'.'arch']
+                        Contains the OpenSSL dynamically loadable engines.
+         [.SYS$STARTUP] Contains startup, login and shutdown scripts.
+                        These define appropriate logical names and
+                        command symbols.
+         [.SYSTEST]     Contains the installation verification procedure.
+         [.HTML]        Contains the HTML rendition of the manual pages.
+                        
+
+     Additionally, install will add the following directories under
+     OPENSSLDIR (the directory given with --openssldir or its default)
+     for you convenience:
+
+         certs          Initially empty, this is the default location
+                        for certificate files.
+         private        Initially empty, this is the default location
+                        for private key files.
+         misc           Various scripts.
+
+     Package builders who want to configure the library for standard
+     locations, but have the package installed somewhere else so that
+     it can easily be packaged, can use
+
+       $ make DESTDIR=/tmp/package-root install         # Unix
+       $ mms/macro="DESTDIR=TMP:[PACKAGE-ROOT]" install ! OpenVMS
+
+     The specified destination directory will be prepended to all
+     installation target paths.
+
+  Compatibility issues with previous OpenSSL versions:
+
+  *  COMPILING existing applications
+
+     OpenSSL 1.1.0 hides a number of structures that were previously
+     open.  This includes all internal libssl structures and a number
+     of EVP types.  Accessor functions have been added to allow
+     controlled access to the structures' data.
+
+     This means that some software needs to be rewritten to adapt to
+     the new ways of doing things.  This often amounts to allocating
+     an instance of a structure explicitly where you could previously
+     allocate them on the stack as automatic variables, and using the
+     provided accessor functions where you would previously access a
+     structure's field directly.
+
+     Some APIs have changed as well.  However, older APIs have been
+     preserved when possible.
+
+ Environment Variables
+ ---------------------
+
+ A number of environment variables can be used to provide additional control
+ over the build process. Typically these should be defined prior to running
+ config or Configure. Not all environment variables are relevant to all
+ platforms.
+
+ AR
+                The name of the ar executable to use.
+
+ BUILDFILE
+                Use a different build file name than the platform default
+                ("Makefile" on Unixly platforms, "makefile" on native Windows,
+                "descrip.mms" on OpenVMS).  This requires that there is a
+                corresponding build file template.  See Configurations/README
+                for further information.
+
+ CC
+                The compiler to use. Configure will attempt to pick a default
+                compiler for your platform but this choice can be overridden
+                using this variable. Set it to the compiler executable you wish
+                to use, e.g. "gcc" or "clang".
+
+ CROSS_COMPILE
+                This environment variable has the same meaning as for the
+                "--cross-compile-prefix" Configure flag described above. If both
+                are set then the Configure flag takes precedence.
+
+ NM
+                The name of the nm executable to use.
+
+ OPENSSL_LOCAL_CONFIG_DIR
+                OpenSSL comes with a database of information about how it
+                should be built on different platforms as well as build file
+                templates for those platforms. The database is comprised of
+                ".conf" files in the Configurations directory.  The build
+                file templates reside there as well as ".tmpl" files. See the
+                file Configurations/README for further information about the
+                format of ".conf" files as well as information on the ".tmpl"
+                files.
+                In addition to the standard ".conf" and ".tmpl" files, it is
+                possible to create your own ".conf" and ".tmpl" files and store
+                them locally, outside the OpenSSL source tree. This environment
+                variable can be set to the directory where these files are held
+                and will have Configure to consider them in addition to the
+                standard ones.
+
+ PERL
+                The name of the Perl executable to use when building OpenSSL.
+
+ HASHBANGPERL
+                The command string for the Perl executable to insert in the
+                #! line of perl scripts that will be publically installed.
+                Default: /usr/bin/env perl
+                Note: the value of this variable is added to the same scripts
+                on all platforms, but it's only relevant on Unix-like platforms.
+
+ RC
+                The name of the rc executable to use. The default will be as
+                defined for the target platform in the ".conf" file. If not
+                defined then "windres" will be used. The WINDRES environment
+                variable is synonymous to this. If both are defined then RC
+                takes precedence.
+
+ RANLIB
+                The name of the ranlib executable to use.
+
+ WINDRES
+                See RC.
+
+ Makefile targets
+ ----------------
+
+ The Configure script generates a Makefile in a format relevant to the specific
+ platform. The Makefiles provide a number of targets that can be used. Not all
+ targets may be available on all platforms. Only the most common targets are
+ described here. Examine the Makefiles themselves for the full list.
+
+ all
+                The default target to build all the software components.
+
+ clean
+                Remove all build artefacts and return the directory to a "clean"
+                state.
+
+ depend
+                Rebuild the dependencies in the Makefiles. This is a legacy
+                option that no longer needs to be used in OpenSSL 1.1.0.
+
+ install
+                Install all OpenSSL components.
+
+ install_sw
+                Only install the OpenSSL software components.
+
+ install_docs
+                Only install the OpenSSL documentation components.
+
+ install_man_docs
+                Only install the OpenSSL man pages (Unix only).
+
+ install_html_docs
+                Only install the OpenSSL html documentation.
+
+ list-tests
+                Prints a list of all the self test names.
+
+ test
+                Build and run the OpenSSL self tests.
+
+ uninstall
+                Uninstall all OpenSSL components.
+
+ update
+                This is a developer option. If you are developing a patch for
+                OpenSSL you may need to use this if you want to update
+                automatically generated files; add new error codes or add new
+                (or change the visibility of) public API functions. (Unix only).
+
+ Note on multi-threading
+ -----------------------
+
+ For some systems, the OpenSSL Configure script knows what compiler options
+ are needed to generate a library that is suitable for multi-threaded
+ applications.  On these systems, support for multi-threading is enabled
+ by default; use the "no-threads" option to disable (this should never be
+ necessary).
+
+ On other systems, to enable support for multi-threading, you will have
+ to specify at least two options: "threads", and a system-dependent option.
+ (The latter is "-D_REENTRANT" on various systems.)  The default in this
+ case, obviously, is not to include support for multi-threading (but
+ you can still use "no-threads" to suppress an annoying warning message
+ from the Configure script.)
+
+ OpenSSL provides built-in support for two threading models: pthreads (found on
+ most UNIX/Linux systems), and Windows threads. No other threading models are
+ supported. If your platform does not provide pthreads or Windows threads then
+ you should Configure with the "no-threads" option.
+
+ Notes on shared libraries
+ -------------------------
+
+ For most systems the OpenSSL Configure script knows what is needed to
+ build shared libraries for libcrypto and libssl. On these systems
+ the shared libraries will be created by default. This can be suppressed and
+ only static libraries created by using the "no-shared" option. On systems
+ where OpenSSL does not know how to build shared libraries the "no-shared"
+ option will be forced and only static libraries will be created.
+
+ Shared libraries are named a little differently on different platforms.
+ One way or another, they all have the major OpenSSL version number as
+ part of the file name, i.e. for OpenSSL 1.1.x, 1.1 is somehow part of
+ the name.
+
+ On most POSIXly platforms, shared libraries are named libcrypto.so.1.1
+ and libssl.so.1.1.
+
+ on Cygwin, shared libraries are named cygcrypto-1.1.dll and cygssl-1.1.dll
+ with import libraries libcrypto.dll.a and libssl.dll.a.
+
+ On Windows build with MSVC or using MingW, shared libraries are named
+ libcrypto-1_1.dll and libssl-1_1.dll for 32-bit Windows, libcrypto-1_1-x64.dll
+ and libssl-1_1-x64.dll for 64-bit x86_64 Windows, and libcrypto-1_1-ia64.dll
+ and libssl-1_1-ia64.dll for IA64 Windows.  With MSVC, the import libraries
+ are named libcrypto.lib and libssl.lib, while with MingW, they are named
+ libcrypto.dll.a and libssl.dll.a.
+
+ On VMS, shareable images (VMS speak for shared libraries) are named
+ ossl$libcrypto0101_shr.exe and ossl$libssl0101_shr.exe.  However, when
+ OpenSSL is specifically built for 32-bit pointers, the shareable images
+ are named ossl$libcrypto0101_shr32.exe and ossl$libssl0101_shr32.exe
+ instead, and when built for 64-bit pointers, they are named
+ ossl$libcrypto0101_shr64.exe and ossl$libssl0101_shr64.exe.
+
+ Note on random number generation
+ --------------------------------
+
+ Availability of cryptographically secure random numbers is required for
+ secret key generation. OpenSSL provides several options to seed the
+ internal PRNG. If not properly seeded, the internal PRNG will refuse
+ to deliver random bytes and a "PRNG not seeded error" will occur.
+ On systems without /dev/urandom (or similar) device, it may be necessary
+ to install additional support software to obtain a random seed.
+ Please check out the manual pages for RAND_add(), RAND_bytes(), RAND_egd(),
+ and the FAQ for more information.
+
Index: EcnlProtoTool/trunk/openssl-1.1.0e/LICENSE
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/LICENSE	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/LICENSE	(revision 331)
@@ -0,0 +1,125 @@
+
+  LICENSE ISSUES
+  ==============
+
+  The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
+  the OpenSSL License and the original SSLeay license apply to the toolkit.
+  See below for the actual license texts.
+
+  OpenSSL License
+  ---------------
+
+/* ====================================================================
+ * Copyright (c) 1998-2016 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+ Original SSLeay License
+ -----------------------
+
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
Index: EcnlProtoTool/trunk/openssl-1.1.0e/Makefile
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/Makefile	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/Makefile	(revision 331)
@@ -0,0 +1,19053 @@
+##
+## Makefile for OpenSSL
+##
+## WARNING: do not edit!
+## Generated by Configure from Configurations/unix-Makefile.tmpl, Configurations/common.tmpl
+
+PLATFORM=linux-armv4
+OPTIONS=--cross-compile-prefix=arm-none-eabi- enable-zlib enable-weak-ssl-ciphers -static -nostdinc -I../musl-1.1.18/include -I../zlib-1.2.11 -L../musl-1.1.18/lib -L../zlib-1.2.11 -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing -DSSIZE_MAX=LONG_MAX -D__unix no-asan no-asm no-crypto-mdebug no-crypto-mdebug-backtrace no-dso no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-fuzz-afl no-fuzz-libfuzzer no-heartbeats no-md2 no-msan no-pic no-rc5 no-sctp no-shared no-ssl-trace no-ssl3 no-ssl3-method no-threads no-ubsan no-ui no-unit-test no-zlib-dynamic
+CONFIGURE_ARGS=("--cross-compile-prefix=arm-none-eabi-", "no-threads", "zlib", "no-shared", "no-dso", "no-asm", "no-ui", "no-pic", "enable-weak-ssl-ciphers", "-static", "linux-armv4", "-nostdinc", "-I../musl-1.1.18/include", "-I../zlib-1.2.11", "-L../musl-1.1.18/lib", "-L../zlib-1.2.11", "-mlittle-endian", "-mcpu=cortex-a9", "-mthumb", "-mthumb-interwork", "-marm", "-march=armv7-a", "-mfpu=vfpv3", "-mfloat-abi=hard", "-mno-unaligned-access", "-fno-strict-aliasing", "-DSSIZE_MAX=LONG_MAX", "-D__unix")
+SRCDIR=.
+BLDDIR=.
+
+VERSION=1.1.0e
+MAJOR=1
+MINOR=1.0
+SHLIB_VERSION_NUMBER=1.1
+SHLIB_VERSION_HISTORY=
+SHLIB_MAJOR=1
+SHLIB_MINOR=1
+SHLIB_TARGET=linux-shared
+
+LIBS=libcrypto.a libssl.a
+SHLIBS=
+SHLIB_INFO=";" ";"
+ENGINES=
+PROGRAMS=apps/openssl fuzz/asn1-test fuzz/asn1parse-test fuzz/bignum-test fuzz/bndiv-test fuzz/cms-test fuzz/conf-test fuzz/crl-test fuzz/ct-test fuzz/server-test fuzz/x509-test test/aborttest test/afalgtest test/asynciotest test/asynctest test/bad_dtls_test test/bftest test/bio_enc_test test/bioprinttest test/bntest test/buildtest_aes test/buildtest_asn1 test/buildtest_asn1t test/buildtest_async test/buildtest_bio test/buildtest_blowfish test/buildtest_bn test/buildtest_buffer test/buildtest_camellia test/buildtest_cast test/buildtest_cmac test/buildtest_cms test/buildtest_comp test/buildtest_conf test/buildtest_conf_api test/buildtest_crypto test/buildtest_ct test/buildtest_des test/buildtest_dh test/buildtest_dsa test/buildtest_dtls1 test/buildtest_e_os2 test/buildtest_ebcdic test/buildtest_ec test/buildtest_ecdh test/buildtest_ecdsa test/buildtest_engine test/buildtest_err test/buildtest_evp test/buildtest_hmac test/buildtest_idea test/buildtest_kdf test/buildtest_lhash test/buildtest_md4 test/buildtest_md5 test/buildtest_mdc2 test/buildtest_modes test/buildtest_obj_mac test/buildtest_objects test/buildtest_ocsp test/buildtest_opensslconf test/buildtest_opensslv test/buildtest_ossl_typ test/buildtest_pem test/buildtest_pem2 test/buildtest_pkcs12 test/buildtest_pkcs7 test/buildtest_rand test/buildtest_rc2 test/buildtest_rc4 test/buildtest_ripemd test/buildtest_rsa test/buildtest_safestack test/buildtest_seed test/buildtest_sha test/buildtest_srp test/buildtest_srtp test/buildtest_ssl test/buildtest_ssl2 test/buildtest_stack test/buildtest_symhacks test/buildtest_tls1 test/buildtest_ts test/buildtest_txt_db test/buildtest_whrlpool test/buildtest_x509 test/buildtest_x509_vfy test/buildtest_x509v3 test/casttest test/cipherlist_test test/clienthellotest test/constant_time_test test/crltest test/ct_test test/d2i_test test/danetest test/destest test/dhtest test/dsatest test/dtlstest test/dtlsv1listentest test/ecdhtest test/ecdsatest test/ectest test/enginetest test/evp_extra_test test/evp_test test/exptest test/gmdifftest test/heartbeat_test test/hmactest test/ideatest test/igetest test/md2test test/md4test test/md5test test/mdc2test test/memleaktest test/p5_crpt2_test test/packettest test/pbelutest test/randtest test/rc2test test/rc4test test/rc5test test/rmdtest test/rsa_test test/sanitytest test/secmemtest test/sha1test test/sha256t test/sha512t test/srptest test/ssl_test test/ssl_test_ctx_test test/sslapitest test/sslcorrupttest test/ssltest_old test/threadstest test/v3ext test/v3nametest test/verify_extra_test test/wp_test test/x509aux
+SCRIPTS=apps/CA.pl apps/tsget tools/c_rehash util/shlib_wrap.sh
+
+DEPS=crypto/aes/aes_core.d crypto/kdf/hkdf.d test/v3ext.d ssl/statem/statem_lib.d crypto/cms/cms_dd.d crypto/evp/e_rc2.d crypto/x509/x509_att.d crypto/pem/pem_sign.d test/bntest.d crypto/aes/aes_ofb.d test/heartbeat_test.d ssl/ssl_err.d crypto/aes/aes_ige.d crypto/rand/rand_vms.d ssl/statem/statem.d crypto/ocsp/ocsp_err.d crypto/bn/bn_div.d crypto/evp/e_camellia.d crypto/asn1/d2i_pu.d apps/crl.d apps/gendsa.d crypto/ts/ts_rsp_print.d crypto/asn1/tasn_utl.d crypto/x509/x_pubkey.d fuzz/ct.d crypto/init.d apps/pkey.d crypto/ec/ec_err.d crypto/seed/seed_ofb.d crypto/engine/eng_all.d crypto/cast/c_cfb64.d test/sha512t.d crypto/sha/sha1dgst.d crypto/asn1/x_sig.d crypto/asn1/p5_pbev2.d crypto/pkcs12/p12_init.d crypto/engine/eng_init.d crypto/modes/xts128.d crypto/o_str.d ssl/statem/statem_dtls.d crypto/lhash/lh_stats.d crypto/dso/dso_win32.d crypto/x509v3/v3_akey.d crypto/evp/e_bf.d crypto/md5/md5_one.d test/rc2test.d test/threadstest.d crypto/bn/bn_shift.d crypto/des/cbc_enc.d crypto/rsa/rsa_asn1.d crypto/aes/aes_cfb.d crypto/des/des_enc.d crypto/evp/bio_enc.d test/bad_dtls_test.d test/buildtest_aes.d crypto/objects/obj_lib.d test/buildtest_conf_api.d test/buildtest_bn.d crypto/async/async_wait.d crypto/mdc2/mdc2_one.d test/handshake_helper.d crypto/seed/seed_ecb.d crypto/x509/x_attrib.d crypto/pem/pem_x509.d test/p5_crpt2_test.d crypto/threads_none.d crypto/ec/ecdh_kdf.d crypto/rsa/rsa_ssl.d crypto/x509/x509_vfy.d test/verify_extra_test.d crypto/pkcs7/pk7_mime.d crypto/asn1/tasn_enc.d crypto/pkcs7/pk7_doit.d fuzz/bignum.d crypto/dsa/dsa_ossl.d crypto/pkcs12/p12_key.d crypto/bio/b_sock2.d crypto/asn1/a_utf8.d crypto/bn/bn_recp.d test/buildtest_tls1.d test/cipherlist_test.d crypto/engine/tb_eckey.d crypto/uid.d test/buildtest_ts.d crypto/asn1/tasn_prn.d crypto/o_init.d crypto/asn1/a_bitstr.d ssl/record/ssl3_buffer.d crypto/des/fcrypt.d crypto/rsa/rsa_prn.d test/v3nametest.d crypto/des/ofb64ede.d crypto/bn/bn_mont.d crypto/dh/dh_lib.d crypto/evp/evp_enc.d crypto/ct/ct_sct_ctx.d crypto/ocsp/v3_ocsp.d crypto/ec/ecp_nistp256.d crypto/asn1/asn1_gen.d test/ecdhtest.d crypto/ec/ec_check.d crypto/cast/c_enc.d crypto/asn1/a_d2i_fp.d crypto/md4/md4_dgst.d crypto/o_fopen.d crypto/dh/dh_meth.d crypto/bn/bn_x931p.d test/buildtest_des.d crypto/threads_win.d crypto/dso/dso_err.d crypto/ct/ct_err.d crypto/evp/bio_md.d ssl/d1_lib.d crypto/ec/curve25519.d fuzz/crl.d crypto/camellia/cmll_ctr.d crypto/x509/x509_obj.d crypto/async/arch/async_null.d crypto/pkcs12/pk12err.d crypto/asn1/bio_ndef.d apps/engine.d crypto/cms/cms_kari.d test/secmemtest.d crypto/ec/ec_oct.d apps/errstr.d crypto/ec/ec_cvt.d crypto/dsa/dsa_pmeth.d crypto/asn1/i2d_pr.d test/constant_time_test.d crypto/dso/dso_vms.d crypto/pkcs12/p12_decr.d crypto/ct/ct_vfy.d crypto/evp/bio_b64.d crypto/ocsp/ocsp_lib.d test/buildtest_seed.d crypto/engine/eng_cnf.d test/asynctest.d test/x509aux.d test/buildtest_ossl_typ.d crypto/rand/randfile.d apps/openssl.d test/sanitytest.d crypto/pem/pem_lib.d apps/spkac.d crypto/asn1/p8_pkey.d apps/s_server.d crypto/idea/i_cfb64.d crypto/x509v3/pcy_map.d crypto/rand/rand_lib.d ssl/s3_msg.d crypto/des/cfb64enc.d crypto/ec/ecp_mont.d test/buildtest_e_os2.d ssl/t1_trce.d apps/ciphers.d ssl/ssl_utst.d crypto/x509/x509_v3.d crypto/bio/bss_sock.d test/buildtest_comp.d test/rmdtest.d crypto/rsa/rsa_chk.d test/md4test.d crypto/modes/ctr128.d crypto/des/str2key.d crypto/x509v3/v3_sxnet.d crypto/asn1/a_time.d crypto/conf/conf_api.d crypto/sha/sha256.d crypto/rsa/rsa_x931.d crypto/hmac/hmac.d apps/asn1pars.d crypto/mem_sec.d test/buildtest_crypto.d test/buildtest_err.d test/buildtest_async.d crypto/evp/p_sign.d apps/nseq.d test/testutil.d crypto/objects/obj_dat.d crypto/dsa/dsa_ameth.d crypto/ocsp/ocsp_vfy.d crypto/ec/ecp_nistp521.d test/evp_test.d crypto/ts/ts_rsp_verify.d crypto/rsa/rsa_depr.d crypto/asn1/a_utctm.d crypto/idea/i_ecb.d crypto/dsa/dsa_err.d crypto/asn1/a_verify.d test/buildtest_x509.d crypto/rand/rand_unix.d test/dtlsv1listentest.d crypto/x509/x509_r2x.d crypto/asn1/x_pkey.d crypto/x509v3/v3_pcons.d crypto/asn1/a_object.d ssl/statem/statem_clnt.d crypto/mem.d crypto/evp/c_allc.d crypto/cms/cms_sd.d crypto/rsa/rsa_none.d crypto/bf/bf_ofb64.d crypto/des/xcbc_enc.d test/bioprinttest.d crypto/x509/x_exten.d crypto/modes/gcm128.d crypto/x509/x509_err.d crypto/asn1/a_mbstr.d crypto/bn/bn_exp2.d crypto/x509v3/v3_akeya.d crypto/asn1/asn_mime.d test/buildtest_kdf.d crypto/x509v3/v3_int.d crypto/pkcs12/p12_attr.d crypto/bn/bn_rand.d ssl/ssl_cert.d crypto/asn1/t_spki.d crypto/asn1/a_type.d crypto/ocsp/ocsp_prn.d crypto/rc2/rc2_skey.d crypto/dsa/dsa_prn.d test/ssltestlib.d crypto/blake2/blake2b.d crypto/ec/ec2_mult.d crypto/camellia/cmll_ofb.d ssl/pqueue.d ssl/ssl_sess.d crypto/aes/aes_cbc.d crypto/ec/ec2_oct.d crypto/dh/dh_depr.d crypto/conf/conf_sap.d crypto/ts/ts_err.d crypto/engine/eng_pkey.d test/buildtest_txt_db.d test/buildtest_ecdsa.d crypto/ex_data.d crypto/x509v3/v3_extku.d crypto/x509/x_req.d crypto/asn1/a_print.d test/wp_test.d crypto/x509/x_x509a.d crypto/bio/bio_lib.d crypto/bn/bn_kron.d crypto/bn/bn_exp.d crypto/bio/b_print.d crypto/engine/eng_list.d test/d2i_test.d ssl/methods.d crypto/x509v3/v3_conf.d crypto/bf/bf_enc.d crypto/bn/bn_gcd.d test/buildtest_ebcdic.d test/sslapitest.d test/pbelutest.d crypto/pem/pem_pkey.d crypto/asn1/p5_scrypt.d crypto/rsa/rsa_gen.d apps/enc.d crypto/dh/dh_gen.d crypto/bf/bf_cfb64.d crypto/x509v3/v3_prn.d crypto/ct/ct_oct.d crypto/evp/c_alld.d test/rc4test.d apps/pkcs7.d crypto/o_dir.d test/buildtest_obj_mac.d crypto/x509v3/v3_bitst.d crypto/evp/m_ripemd.d crypto/asn1/a_strex.d crypto/asn1/x_spki.d crypto/engine/eng_cryptodev.d ssl/ssl_stat.d apps/srp.d crypto/cryptlib.d ssl/ssl_lib.d crypto/evp/e_cast.d ssl/s3_enc.d crypto/dsa/dsa_vrf.d crypto/asn1/x_info.d crypto/md4/md4_one.d crypto/idea/i_ofb64.d crypto/des/cbc_cksm.d crypto/bio/bss_acpt.d crypto/rc2/rc2cfb64.d crypto/asn1/tasn_new.d crypto/pkcs12/p12_kiss.d crypto/bio/b_sock.d crypto/camellia/cmll_misc.d crypto/conf/conf_lib.d crypto/bio/bss_conn.d crypto/evp/digest.d crypto/x509v3/v3_pcia.d crypto/x509/x509rset.d crypto/evp/scrypt.d crypto/evp/pmeth_gn.d crypto/asn1/evp_asn1.d crypto/asn1/a_digest.d crypto/ec/ec_pmeth.d crypto/x509/t_crl.d crypto/engine/eng_table.d apps/verify.d crypto/cms/cms_smime.d test/asynciotest.d crypto/x509v3/v3_bcons.d crypto/dh/dh_kdf.d crypto/x509/x509_ext.d test/buildtest_x509_vfy.d test/ectest.d crypto/dso/dso_dlfcn.d test/enginetest.d crypto/x509v3/v3_tlsf.d crypto/dso/dso_dl.d test/buildtest_md4.d crypto/bn/bn_asm.d test/buildtest_ocsp.d crypto/asn1/asn1_err.d crypto/x509v3/v3_lib.d test/dhtest.d crypto/ocsp/ocsp_ext.d crypto/ts/ts_rsp_sign.d test/dsatest.d test/buildtest_hmac.d crypto/md5/md5_dgst.d crypto/evp/p5_crpt.d test/buildtest_rc4.d crypto/camellia/camellia.d crypto/cms/cms_att.d test/buildtest_pem.d crypto/evp/e_idea.d crypto/pkcs7/pk7_asn1.d test/aborttest.d crypto/evp/e_old.d crypto/evp/p_lib.d crypto/modes/wrap128.d crypto/pem/pem_xaux.d crypto/kdf/kdf_err.d fuzz/asn1parse.d ssl/ssl_init.d ssl/ssl_asn1.d crypto/evp/m_md5_sha1.d crypto/ec/ec_lib.d crypto/x509/by_dir.d crypto/bio/bss_null.d crypto/evp/m_sha1.d crypto/bn/bn_gf2m.d crypto/asn1/a_gentm.d crypto/rsa/rsa_ameth.d crypto/conf/conf_mall.d crypto/evp/p_dec.d crypto/dso/dso_lib.d crypto/bn/bn_err.d crypto/evp/names.d ssl/d1_srtp.d crypto/asn1/f_string.d crypto/ct/ct_policy.d crypto/pkcs12/p12_add.d crypto/ec/ecdh_ossl.d crypto/rsa/rsa_pk1.d crypto/pkcs12/p12_p8d.d crypto/ebcdic.d crypto/evp/e_rc4_hmac_md5.d ssl/ssl_rsa.d apps/x509.d crypto/modes/ofb128.d apps/crl2p7.d crypto/des/cfb_enc.d crypto/async/async_err.d ssl/t1_lib.d crypto/threads_pthread.d crypto/des/rpc_enc.d apps/genpkey.d crypto/asn1/asn1_par.d test/bio_enc_test.d crypto/des/qud_cksm.d crypto/dh/dh_check.d test/buildtest_pem2.d crypto/x509/x509_cmp.d crypto/asn1/x_algor.d crypto/asn1/tasn_fre.d crypto/engine/eng_err.d crypto/cms/cms_asn1.d test/buildtest_whrlpool.d crypto/modes/cts128.d crypto/ocsp/ocsp_asn.d apps/genrsa.d crypto/pkcs12/p12_mutl.d crypto/x509/t_req.d crypto/rsa/rsa_lib.d apps/apps.d crypto/des/set_key.d test/dtlstest.d crypto/pkcs7/pkcs7err.d crypto/modes/cfb128.d crypto/x509v3/v3_info.d test/buildtest_pkcs7.d crypto/rsa/rsa_oaep.d test/ideatest.d ssl/s3_lib.d crypto/evp/p5_crpt2.d crypto/asn1/x_bignum.d crypto/evp/e_des3.d crypto/stack/stack.d apps/req.d crypto/ec/ecdsa_ossl.d apps/speed.d crypto/evp/evp_key.d crypto/asn1/tasn_scn.d crypto/asn1/x_val.d test/destest.d crypto/dsa/dsa_key.d crypto/objects/o_names.d crypto/bn/bn_depr.d crypto/bio/bss_fd.d crypto/dsa/dsa_meth.d test/buildtest_evp.d crypto/pkcs12/p12_npas.d crypto/evp/e_rc4.d crypto/evp/m_sigver.d fuzz/test-corpus.d crypto/asn1/a_i2d_fp.d crypto/txt_db/txt_db.d crypto/x509/x509_req.d crypto/comp/c_zlib.d crypto/aes/aes_misc.d crypto/engine/tb_asnmth.d crypto/pem/pem_err.d crypto/asn1/bio_asn1.d crypto/asn1/asn_pack.d crypto/rsa/rsa_pss.d ssl/statem/statem_srvr.d crypto/ec/ec_kmeth.d test/buildtest_stack.d ssl/ssl_txt.d test/buildtest_buffer.d apps/dsa.d crypto/ec/ecp_nistp224.d ssl/ssl_mcnf.d crypto/des/ofb_enc.d crypto/engine/tb_dsa.d crypto/buffer/buf_err.d crypto/kdf/tls1_prf.d apps/pkeyparam.d crypto/bn/bn_dh.d crypto/async/async.d crypto/camellia/cmll_cbc.d test/buildtest_symhacks.d crypto/conf/conf_def.d test/packettest.d crypto/ocsp/ocsp_srv.d crypto/bio/bio_err.d crypto/asn1/a_strnid.d crypto/cmac/cm_pmeth.d crypto/err/err_prn.d crypto/dsa/dsa_lib.d crypto/des/cfb64ede.d apps/dhparam.d test/buildtest_md5.d crypto/seed/seed_cfb.d test/gmdifftest.d test/buildtest_dtls1.d crypto/evp/evp_pkey.d apps/pkcs8.d ssl/record/rec_layer_s3.d crypto/x509v3/v3_pmaps.d test/mdc2test.d crypto/ec/ec_curve.d crypto/ct/ct_prn.d crypto/evp/m_md4.d crypto/bn/bn_word.d crypto/seed/seed_cbc.d test/rc5test.d crypto/x509v3/pcy_node.d fuzz/x509.d test/buildtest_opensslv.d crypto/asn1/p5_pbe.d crypto/aes/aes_ecb.d test/buildtest_dh.d crypto/engine/eng_rdrand.d test/ssltest_old.d crypto/des/rand_key.d crypto/rand/md_rand.d crypto/mdc2/mdc2dgst.d crypto/engine/tb_digest.d crypto/bn/bn_sqr.d crypto/pkcs12/p12_p8e.d crypto/bn/bn_add.d crypto/evp/bio_ok.d test/buildtest_camellia.d test/ssl_test_ctx_test.d crypto/bf/bf_skey.d crypto/err/err.d crypto/comp/comp_lib.d crypto/asn1/tasn_typ.d crypto/rc2/rc2_ecb.d crypto/dh/dh_prn.d test/srptest.d crypto/x509v3/v3_genn.d crypto/x509v3/v3_addr.d apps/passwd.d crypto/cms/cms_env.d crypto/cms/cms_ess.d crypto/cast/c_ofb64.d crypto/bio/bf_nbio.d fuzz/bndiv.d crypto/dsa/dsa_gen.d crypto/bn/bn_nist.d test/buildtest_mdc2.d apps/pkeyutl.d crypto/chacha/chacha_enc.d crypto/x509/x509_def.d crypto/engine/tb_cipher.d crypto/evp/m_md2.d test/buildtest_blowfish.d crypto/x509/x509type.d crypto/cms/cms_cd.d crypto/x509v3/v3_ia5.d crypto/engine/eng_dyn.d crypto/asn1/a_dup.d crypto/evp/e_des.d crypto/cmac/cmac.d test/ecdsatest.d crypto/bn/bn_mod.d crypto/rsa/rsa_sign.d crypto/des/ecb3_enc.d test/buildtest_ct.d crypto/blake2/m_blake2b.d apps/version.d crypto/o_fips.d test/hmactest.d test/buildtest_cms.d crypto/bio/b_addr.d apps/dsaparam.d fuzz/asn1.d crypto/rsa/rsa_ossl.d test/buildtest_ec.d crypto/rsa/rsa_err.d crypto/ec/ec2_smpl.d crypto/ocsp/ocsp_ht.d crypto/engine/eng_lib.d test/exptest.d crypto/modes/cbc128.d crypto/rsa/rsa_saos.d ssl/bio_ssl.d fuzz/conf.d crypto/bn/bn_blind.d crypto/pkcs12/p12_crt.d crypto/x509v3/v3_purp.d crypto/x509/x_crl.d test/buildtest_x509v3.d crypto/whrlpool/wp_dgst.d crypto/cpt_err.d crypto/bio/bss_mem.d crypto/x509v3/v3_cpols.d crypto/bn/bn_intern.d crypto/rand/rand_win.d test/buildtest_opensslconf.d crypto/x509/x_x509.d crypto/idea/i_cbc.d test/rsa_test.d crypto/x509/x_name.d crypto/bn/bn_ctx.d crypto/bio/bio_cb.d apps/pkcs12.d crypto/asn1/t_pkey.d crypto/bio/bf_null.d crypto/cast/c_ecb.d crypto/pkcs12/p12_sbag.d test/ssl_test_ctx.d crypto/bio/bss_bio.d test/casttest.d crypto/ec/ec_mult.d test/buildtest_conf.d crypto/evp/e_null.d crypto/x509/x509name.d crypto/ts/ts_req_utils.d crypto/pkcs7/bio_pk7.d ssl/record/dtls1_bitmap.d crypto/engine/tb_rand.d crypto/pem/pem_info.d crypto/whrlpool/wp_block.d test/buildtest_rc2.d apps/ec.d crypto/dso/dso_openssl.d crypto/async/arch/async_posix.d fuzz/cms.d crypto/conf/conf_mod.d crypto/x509v3/v3_crld.d crypto/err/err_all.d test/buildtest_bio.d crypto/dsa/dsa_sign.d crypto/des/ofb64enc.d test/sha1test.d crypto/x509v3/v3_enum.d crypto/pkcs12/p12_utl.d crypto/ct/ct_x509v3.d ssl/ssl_conf.d crypto/modes/ccm128.d crypto/evp/pmeth_fn.d ssl/t1_reneg.d apps/sess_id.d crypto/x509v3/v3_ncons.d crypto/evp/evp_err.d crypto/asn1/i2d_pu.d crypto/asn1/a_sign.d test/ssl_test.d ssl/t1_enc.d crypto/srp/srp_vfy.d crypto/engine/tb_rsa.d crypto/modes/ocb128.d crypto/x509v3/v3_pci.d crypto/x509v3/v3_skey.d test/buildtest_ecdh.d crypto/buffer/buffer.d crypto/ct/ct_log.d crypto/rand/rand_err.d apps/s_cb.d crypto/bn/bn_prime.d crypto/ts/ts_verify_ctx.d crypto/evp/p_enc.d ssl/t1_ext.d crypto/hmac/hm_ameth.d crypto/comp/comp_err.d crypto/evp/m_md5.d crypto/bio/bss_file.d crypto/cms/cms_lib.d crypto/cms/cms_enc.d crypto/x509v3/v3_utl.d crypto/engine/tb_pkmeth.d crypto/evp/p_verify.d crypto/rc4/rc4_skey.d crypto/async/arch/async_win.d ssl/tls_srp.d crypto/o_time.d crypto/asn1/ameth_lib.d apps/dgst.d crypto/blake2/blake2s.d test/buildtest_pkcs12.d crypto/evp/p_seal.d engines/e_padlock.d crypto/rc2/rc2_cbc.d test/buildtest_rsa.d crypto/bio/b_dump.d crypto/evp/m_wp.d crypto/bn/bn_mpi.d crypto/engine/eng_openssl.d test/md2test.d crypto/objects/obj_err.d crypto/dsa/dsa_asn1.d crypto/evp/pmeth_lib.d crypto/asn1/t_bitst.d crypto/conf/conf_err.d crypto/bio/bss_dgram.d crypto/evp/e_chacha20_poly1305.d crypto/ec/ecp_nistputil.d test/clienthellotest.d crypto/ripemd/rmd_one.d crypto/evp/e_seed.d crypto/x509v3/pcy_data.d crypto/cms/cms_pwri.d crypto/x509/x509_vpm.d crypto/cast/c_skey.d crypto/dh/dh_asn1.d test/danetest.d apps/ts.d crypto/rsa/rsa_null.d crypto/ec/ec_print.d test/buildtest_dsa.d crypto/evp/cmeth_lib.d crypto/bn/bn_print.d crypto/dh/dh_rfc5114.d crypto/camellia/cmll_ecb.d ssl/record/ssl3_record.d crypto/camellia/cmll_cfb.d crypto/asn1/x_long.d test/crltest.d crypto/x509/x509spki.d test/buildtest_lhash.d crypto/x509/x509_lu.d crypto/ts/ts_conf.d test/buildtest_cmac.d crypto/pem/pem_oth.d apps/s_time.d crypto/bn/bn_mul.d crypto/x509/x509_set.d crypto/evp/evp_cnf.d test/buildtest_asn1t.d crypto/x509/t_x509.d crypto/bn/bn_sqrt.d apps/rehash.d crypto/ocsp/ocsp_cl.d crypto/rand/rand_egd.d crypto/asn1/n_pkey.d crypto/rsa/rsa_x931g.d crypto/asn1/asn_mstbl.d test/ct_test.d crypto/engine/tb_dh.d crypto/sha/sha1_one.d ssl/record/rec_layer_d1.d test/buildtest_safestack.d crypto/evp/p_open.d crypto/aes/aes_wrap.d crypto/evp/e_rc5.d crypto/ec/eck_prn.d test/buildtest_ripemd.d apps/ca.d apps/opt.d crypto/bn/bn_const.d crypto/poly1305/poly1305.d crypto/x509v3/pcy_cache.d crypto/x509/x509_trs.d test/buildtest_objects.d crypto/evp/e_xcbc_d.d test/igetest.d crypto/evp/e_aes.d crypto/ec/ec_asn1.d ssl/d1_msg.d crypto/x509/x509_d2.d crypto/ec/ecx_meth.d test/buildtest_ssl.d test/afalgtest.d crypto/pem/pem_all.d crypto/dh/dh_ameth.d crypto/pkcs12/p12_crpt.d apps/rsa.d crypto/ec/ec_ameth.d test/sslcorrupttest.d crypto/dsa/dsa_depr.d crypto/asn1/a_octet.d apps/app_rand.d crypto/asn1/f_int.d test/buildtest_srp.d test/buildtest_cast.d crypto/rsa/rsa_crpt.d test/buildtest_idea.d test/md5test.d crypto/evp/evp_pbe.d crypto/ct/ct_b64.d crypto/blake2/m_blake2s.d crypto/evp/m_null.d crypto/x509/x509_txt.d crypto/ripemd/rmd_dgst.d crypto/asn1/nsseq.d apps/ocsp.d apps/prime.d crypto/pem/pem_pk8.d crypto/pkcs7/pk7_attr.d crypto/asn1/asn1_lib.d test/randtest.d crypto/ec/ecp_oct.d crypto/bn/bn_lib.d crypto/dh/dh_pmeth.d crypto/x509v3/pcy_tree.d apps/s_client.d crypto/mem_dbg.d crypto/rc2/rc2ofb64.d crypto/bio/bss_log.d crypto/cversion.d crypto/cms/cms_io.d crypto/ec/ecdsa_sign.d test/buildtest_modes.d crypto/ct/ct_sct.d test/buildtest_srtp.d crypto/des/fcrypt_b.d apps/rand.d crypto/x509v3/v3err.d ssl/s3_cbc.d crypto/des/pcbc_enc.d crypto/lhash/lhash.d engines/e_capi.d crypto/rsa/rsa_meth.d crypto/ec/ecp_nist.d crypto/ts/ts_lib.d crypto/ec/ecp_smpl.d crypto/bio/bio_meth.d test/sha256t.d crypto/pem/pvkfmt.d crypto/ec/ec_key.d crypto/x509/by_file.d crypto/asn1/tasn_dec.d crypto/evp/encode.d crypto/idea/i_skey.d crypto/evp/evp_lib.d crypto/cmac/cm_ameth.d crypto/srp/srp_lib.d apps/rsautl.d crypto/engine/eng_ctrl.d crypto/pkcs7/pk7_lib.d apps/s_socket.d crypto/des/ecb_enc.d crypto/objects/obj_xref.d crypto/x509/x_all.d crypto/evp/e_aes_cbc_hmac_sha1.d test/bftest.d crypto/mem_clr.d crypto/ts/ts_req_print.d crypto/engine/eng_fat.d crypto/seed/seed.d crypto/evp/e_aes_cbc_hmac_sha256.d crypto/pkcs12/p12_asn.d crypto/bf/bf_ecb.d test/buildtest_sha.d test/evp_extra_test.d crypto/cms/cms_err.d crypto/dh/dh_key.d apps/smime.d crypto/x509v3/v3_asid.d crypto/ec/ecdsa_vrf.d crypto/evp/m_mdc2.d crypto/asn1/a_int.d ssl/ssl_ciph.d crypto/asn1/asn_moid.d crypto/dh/dh_err.d crypto/rsa/rsa_pmeth.d crypto/asn1/d2i_pr.d crypto/bio/bf_buff.d test/buildtest_engine.d crypto/x509/x509cset.d crypto/hmac/hm_pmeth.d crypto/x509v3/pcy_lib.d test/buildtest_asn1.d crypto/bio/bf_lbuf.d crypto/x509v3/v3_pku.d crypto/bn/bn_srp.d crypto/pkcs7/pk7_smime.d crypto/x509v3/v3_alt.d crypto/sha/sha512.d test/buildtest_ssl2.d crypto/ts/ts_rsp_utils.d apps/ecparam.d test/memleaktest.d apps/cms.d test/buildtest_rand.d fuzz/server.d crypto/rc4/rc4_enc.d crypto/ts/ts_asn1.d
+
+GENERATED_MANDATORY=crypto/include/internal/bn_conf.h crypto/include/internal/dso_conf.h include/openssl/opensslconf.h
+GENERATED=test/buildtest_aes.c test/buildtest_conf_api.c test/buildtest_bn.c test/buildtest_tls1.c test/buildtest_ts.c test/buildtest_des.c test/buildtest_seed.c test/buildtest_ossl_typ.c test/buildtest_e_os2.c test/buildtest_comp.c test/buildtest_crypto.c test/buildtest_err.c test/buildtest_async.c test/buildtest_x509.c test/buildtest_kdf.c test/buildtest_txt_db.c test/buildtest_ecdsa.c test/buildtest_ebcdic.c test/buildtest_obj_mac.c test/buildtest_x509_vfy.c test/buildtest_md4.c test/buildtest_ocsp.c test/buildtest_hmac.c test/buildtest_rc4.c test/buildtest_pem.c test/buildtest_pem2.c test/buildtest_whrlpool.c test/buildtest_pkcs7.c test/buildtest_evp.c test/buildtest_stack.c test/buildtest_buffer.c test/buildtest_symhacks.c test/buildtest_md5.c test/buildtest_dtls1.c test/buildtest_opensslv.c test/buildtest_dh.c test/buildtest_camellia.c test/buildtest_mdc2.c test/buildtest_blowfish.c test/buildtest_ct.c test/buildtest_cms.c test/buildtest_ec.c test/buildtest_x509v3.c test/buildtest_opensslconf.c test/buildtest_conf.c test/buildtest_rc2.c test/buildtest_bio.c test/buildtest_ecdh.c test/buildtest_pkcs12.c test/buildtest_rsa.c test/buildtest_dsa.c test/buildtest_lhash.c test/buildtest_cmac.c test/buildtest_asn1t.c test/buildtest_safestack.c test/buildtest_ripemd.c test/buildtest_objects.c test/buildtest_ssl.c test/buildtest_srp.c test/buildtest_cast.c test/buildtest_idea.c test/buildtest_modes.c test/buildtest_srtp.c test/buildtest_sha.c test/buildtest_engine.c test/buildtest_asn1.c test/buildtest_ssl2.c test/buildtest_rand.c crypto/include/internal/dso_conf.h crypto/include/internal/bn_conf.h crypto/buildinf.h include/openssl/opensslconf.h
+
+INSTALL_LIBS=libcrypto.a libssl.a
+INSTALL_SHLIBS=
+INSTALL_SHLIB_INFO=";" ";"
+INSTALL_ENGINES=
+INSTALL_PROGRAMS=apps/openssl
+
+BIN_SCRIPTS=$(BLDDIR)/tools/c_rehash
+MISC_SCRIPTS=$(BLDDIR)/apps/CA.pl $(BLDDIR)/apps/tsget
+
+
+# DESTDIR is for package builders so that they can configure for, say,
+# /usr/ and yet have everything installed to /tmp/somedir/usr/.
+# Normally it is left empty.
+DESTDIR=
+
+# Do not edit these manually. Use Configure with --prefix or --openssldir
+# to change this!  Short explanation in the top comment in Configure
+INSTALLTOP=/usr/local
+OPENSSLDIR=/usr/local/ssl
+LIBDIR=lib
+ENGINESDIR=/usr/local/lib/engines-1.1
+
+# Convenience variable for those who want to set the rpath in shared
+# libraries and applications
+LIBRPATH=$(INSTALLTOP)/$(LIBDIR)
+
+MANDIR=$(INSTALLTOP)/share/man
+DOCDIR=$(INSTALLTOP)/share/doc/$(BASENAME)
+HTMLDIR=$(DOCDIR)/html
+
+# MANSUFFIX is for the benefit of anyone who may want to have a suffix
+# appended after the manpage file section number.  "ssl" is popular,
+# resulting in files such as config.5ssl rather than config.5.
+MANSUFFIX=
+HTMLSUFFIX=html
+
+
+
+CROSS_COMPILE= arm-none-eabi-
+CC= $(CROSS_COMPILE)gcc
+CFLAGS=-DZLIB -DNDEBUG -DOPENSSL_NO_DYNAMIC_ENGINE -DSSIZE_MAX=LONG_MAX -D__unix -DOPENSSLDIR="\"$(OPENSSLDIR)\"" -DENGINESDIR="\"$(ENGINESDIR)\"" -Wall -O3  -nostdinc -I../musl-1.1.18/include -I../zlib-1.2.11 -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing
+CFLAGS_Q=-DZLIB -DNDEBUG -DOPENSSL_NO_DYNAMIC_ENGINE -DSSIZE_MAX=LONG_MAX -D__unix -DOPENSSLDIR=\"\\\"$(OPENSSLDIR)\\\"\" -DENGINESDIR=\"\\\"$(ENGINESDIR)\\\"\"  -nostdinc -I../musl-1.1.18/include -I../zlib-1.2.11 -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing
+LDFLAGS= 
+PLIB_LDFLAGS= 
+EX_LIBS= -lz -ldl -static -L../musl-1.1.18/lib -L../zlib-1.2.11 
+LIB_CFLAGS=
+LIB_LDFLAGS= 
+DSO_CFLAGS=
+DSO_LDFLAGS=$(LIB_LDFLAGS)
+BIN_CFLAGS=
+
+PERL=/usr/bin/perl
+
+ARFLAGS= 
+AR=$(CROSS_COMPILE)ar $(ARFLAGS) r
+RANLIB= $(CROSS_COMPILE)ranlib
+NM= $(CROSS_COMPILE)nm
+RCFLAGS=
+RC= $(CROSS_COMPILE)windres
+RM= rm -f
+RMDIR= rmdir
+TAR= tar
+TARFLAGS= 
+MAKEDEPEND=arm-none-eabi-gcc
+
+BASENAME=       openssl
+NAME=           $(BASENAME)-$(VERSION)
+TARFILE=        ../$(NAME).tar
+
+# We let the C compiler driver to take care of .s files. This is done in
+# order to be excused from maintaining a separate set of architecture
+# dependent assembler flags. E.g. if you throw -mcpu=ultrasparc at SPARC
+# gcc, then the driver will automatically translate it to -xarch=v8plus
+# and pass it down to assembler.
+AS=$(CC) -c
+ASFLAG=$(CFLAGS)
+PERLASM_SCHEME= linux32
+
+# For x86 assembler: Set PROCESSOR to 386 if you want to support
+# the 80386.
+PROCESSOR= 
+
+# We want error [and other] messages in English. Trouble is that make(1)
+# doesn't pass macros down as environment variables unless there already
+# was corresponding variable originally set. In other words we can only
+# reassign environment variables, but not set new ones, not in portable
+# manner that is. That's why we reassign several, just to be sure...
+LC_ALL=C
+LC_MESSAGES=C
+LANG=C
+
+# The main targets ###################################################
+
+all: build_generated
+	$(MAKE) depend && $(MAKE) _all
+_all: build_libs_nodep build_engines_nodep build_programs_nodep link-utils
+build_libs: build_generated
+	$(MAKE) depend && $(MAKE) _build_libs
+_build_libs: build_libs_nodep
+build_engines: build_generated
+	$(MAKE) depend && $(MAKE) _build_engines
+_build_engines: build_engines_nodep
+build_programs: build_generated
+	$(MAKE) depend && $(MAKE) _build_programs
+_build_programs: build_programs_nodep
+
+build_generated: $(GENERATED_MANDATORY)
+build_libs_nodep: libcrypto.pc libssl.pc openssl.pc
+build_engines_nodep: $(ENGINES)
+build_programs_nodep: $(PROGRAMS) $(SCRIPTS)
+
+# Kept around for backward compatibility
+build_apps build_tests: build_programs
+
+test: tests
+tests: build_generated
+	$(MAKE) depend && $(MAKE) _tests
+_tests: build_programs_nodep build_engines_nodep link-utils
+	@ : 
+	( cd test; \
+	  SRCTOP=../$(SRCDIR) \
+	  BLDTOP=../$(BLDDIR) \
+	  PERL="$(PERL)" \
+	  EXE_EXT= \
+	  OPENSSL_ENGINES=../$(BLDDIR)/engines \
+	  OPENSSL_DEBUG_MEMORY=on \
+	    $(PERL) ../$(SRCDIR)/test/run_tests.pl $(TESTS) )
+	@ : 
+
+list-tests:
+	@ : 
+	@SRCTOP="$(SRCDIR)" \
+	 $(PERL) $(SRCDIR)/test/run_tests.pl list
+	@ : 
+
+install: install_sw install_ssldirs install_docs
+
+uninstall: uninstall_docs uninstall_sw
+
+libclean:
+	@set -e; for s in $(SHLIB_INFO); do \
+		s1=`echo "$$s" | cut -f1 -d";"`; \
+		s2=`echo "$$s" | cut -f2 -d";"`; \
+		echo $(RM) $$s1; \
+		$(RM) $$s1; \
+		if [ "$$s1" != "$$s2" ]; then \
+			echo $(RM) $$s2; \
+			$(RM) $$s2; \
+		fi; \
+	done
+	$(RM) $(LIBS)
+	$(RM) *.map
+
+clean: libclean
+	$(RM) $(PROGRAMS) $(TESTPROGS) $(ENGINES) $(SCRIPTS)
+	$(RM) $(GENERATED)
+	-$(RM) `find . -name '*.d' -a \! -path "./.git/*"`
+	-$(RM) `find . -name '*.o' -a \! -path "./.git/*"`
+	$(RM) core
+	$(RM) tags TAGS
+	$(RM) test/.rnd
+	$(RM) openssl.pc libcrypto.pc libssl.pc
+	-$(RM) `find . -type l -a \! -path "./.git/*"`
+	$(RM) $(TARFILE)
+
+distclean: clean
+	$(RM) configdata.pm
+	$(RM) Makefile
+
+# We check if any depfile is newer than Makefile and decide to
+# concatenate only if that is true.
+depend:
+	@: 
+	@if egrep "^# DO NOT DELETE THIS LINE" Makefile >/dev/null && [ -z "`find $(DEPS) -newer Makefile 2>/dev/null; exit 0`" ]; then :; else \
+	  ( $(PERL) -pe 'exit 0 if /^# DO NOT DELETE THIS LINE.*/' < Makefile; \
+	    echo '# DO NOT DELETE THIS LINE -- make depend depends on it.'; \
+	    echo; \
+	    for f in $(DEPS); do \
+	      if [ -f $$f ]; then cat $$f; fi; \
+	    done ) > Makefile.new; \
+	  if cmp Makefile.new Makefile >/dev/null 2>&1; then \
+	    rm -f Makefile.new; \
+	  else \
+	    mv -f Makefile.new Makefile; \
+	  fi; \
+	fi
+	@: 
+
+# Install helper targets #############################################
+
+install_sw: all install_dev install_engines install_runtime
+
+uninstall_sw: uninstall_runtime uninstall_engines uninstall_dev
+
+install_docs: install_man_docs install_html_docs
+
+uninstall_docs: uninstall_man_docs uninstall_html_docs
+	$(RM) -r -v $(DESTDIR)$(DOCDIR)
+
+install_ssldirs:
+	@$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(OPENSSLDIR)/certs
+	@$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(OPENSSLDIR)/private
+	@$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(OPENSSLDIR)/misc
+	@set -e; for x in dummy $(MISC_SCRIPTS); do \
+		if [ "$$x" = "dummy" ]; then continue; fi; \
+		fn=`basename $$x`; \
+		echo "install $$x -> $(DESTDIR)$(OPENSSLDIR)/misc/$$fn"; \
+		cp $$x $(DESTDIR)$(OPENSSLDIR)/misc/$$fn.new; \
+		chmod 755 $(DESTDIR)$(OPENSSLDIR)/misc/$$fn.new; \
+		mv -f $(DESTDIR)$(OPENSSLDIR)/misc/$$fn.new \
+		      $(DESTDIR)$(OPENSSLDIR)/misc/$$fn; \
+	done
+	@echo "install $(SRCDIR)/apps/openssl.cnf -> $(DESTDIR)$(OPENSSLDIR)/openssl.cnf.dist"
+	@cp $(SRCDIR)/apps/openssl.cnf $(DESTDIR)$(OPENSSLDIR)/openssl.cnf.new
+	@chmod 644 $(DESTDIR)$(OPENSSLDIR)/openssl.cnf.new
+	@mv -f  $(DESTDIR)$(OPENSSLDIR)/openssl.cnf.new $(DESTDIR)$(OPENSSLDIR)/openssl.cnf.dist
+	@if ! [ -f "$(DESTDIR)$(OPENSSLDIR)/openssl.cnf" ]; then \
+		echo "install $(SRCDIR)/apps/openssl.cnf -> $(DESTDIR)$(OPENSSLDIR)/openssl.cnf"; \
+		cp $(SRCDIR)/apps/openssl.cnf $(DESTDIR)$(OPENSSLDIR)/openssl.cnf; \
+		chmod 644 $(DESTDIR)$(OPENSSLDIR)/openssl.cnf; \
+	fi
+
+install_dev:
+	@[ -n "$(INSTALLTOP)" ] || (echo INSTALLTOP should not be empty; exit 1)
+	@echo "*** Installing development files"
+	@$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(INSTALLTOP)/include/openssl
+	@ : 
+	@set -e; for i in $(SRCDIR)/include/openssl/*.h \
+			  $(BLDDIR)/include/openssl/*.h; do \
+		fn=`basename $$i`; \
+		echo "install $$i -> $(DESTDIR)$(INSTALLTOP)/include/openssl/$$fn"; \
+		cp $$i $(DESTDIR)$(INSTALLTOP)/include/openssl/$$fn; \
+		chmod 644 $(DESTDIR)$(INSTALLTOP)/include/openssl/$$fn; \
+	done
+	@$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)
+	@set -e; for l in $(INSTALL_LIBS); do \
+		fn=`basename $$l`; \
+		echo "install $$l -> $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn"; \
+		cp $$l $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn.new; \
+		$(RANLIB) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn.new; \
+		chmod 644 $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn.new; \
+		mv -f $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn.new \
+		      $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn; \
+	done
+	@ : 
+	@$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
+	@echo "install libcrypto.pc -> $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libcrypto.pc"
+	@cp libcrypto.pc $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
+	@chmod 644 $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libcrypto.pc
+	@echo "install libssl.pc -> $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libssl.pc"
+	@cp libssl.pc $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
+	@chmod 644 $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libssl.pc
+	@echo "install openssl.pc -> $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/openssl.pc"
+	@cp openssl.pc $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
+	@chmod 644 $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/openssl.pc
+
+uninstall_dev:
+	@echo "*** Uninstalling development files"
+	@ : 
+	@set -e; for i in $(SRCDIR)/include/openssl/*.h \
+			  $(BLDDIR)/include/openssl/*.h; do \
+		fn=`basename $$i`; \
+		echo "$(RM) $(DESTDIR)$(INSTALLTOP)/include/openssl/$$fn"; \
+		$(RM) $(DESTDIR)$(INSTALLTOP)/include/openssl/$$fn; \
+	done
+	-$(RMDIR) $(DESTDIR)$(INSTALLTOP)/include/openssl
+	-$(RMDIR) $(DESTDIR)$(INSTALLTOP)/include
+	@set -e; for l in $(INSTALL_LIBS); do \
+		fn=`basename $$l`; \
+		echo "$(RM) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn"; \
+		$(RM) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn; \
+	done
+	@ : 
+	$(RM) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libcrypto.pc
+	$(RM) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libssl.pc
+	$(RM) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/openssl.pc
+	-$(RMDIR) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
+	-$(RMDIR) $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)
+
+install_engines:
+	@[ -n "$(INSTALLTOP)" ] || (echo INSTALLTOP should not be empty; exit 1)
+	@$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(ENGINESDIR)/
+	@echo "*** Installing engines"
+	@set -e; for e in dummy $(INSTALL_ENGINES); do \
+		if [ "$$e" = "dummy" ]; then continue; fi; \
+		fn=`basename $$e`; \
+		echo "install $$e -> $(DESTDIR)$(ENGINESDIR)/$$fn"; \
+		cp $$e $(DESTDIR)$(ENGINESDIR)/$$fn.new; \
+		chmod 755 $(DESTDIR)$(ENGINESDIR)/$$fn.new; \
+		mv -f $(DESTDIR)$(ENGINESDIR)/$$fn.new \
+		      $(DESTDIR)$(ENGINESDIR)/$$fn; \
+	done
+
+uninstall_engines:
+	@echo "*** Uninstalling engines"
+	@set -e; for e in dummy $(INSTALL_ENGINES); do \
+		if [ "$$e" = "dummy" ]; then continue; fi; \
+		fn=`basename $$e`; \
+		if [ "$$fn" = 'ossltest.so' ]; then \
+			continue; \
+		fi; \
+		echo "$(RM) $(DESTDIR)$(ENGINESDIR)/$$fn"; \
+		$(RM) $(DESTDIR)$(ENGINESDIR)/$$fn; \
+	done
+	-$(RMDIR) $(DESTDIR)$(ENGINESDIR)
+
+install_runtime:
+	@[ -n "$(INSTALLTOP)" ] || (echo INSTALLTOP should not be empty; exit 1)
+	@$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(INSTALLTOP)/bin
+	@ : 
+	@$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)
+	@ : 
+	@echo "*** Installing runtime files"
+	@set -e; for s in dummy $(INSTALL_SHLIBS); do \
+		if [ "$$s" = "dummy" ]; then continue; fi; \
+		fn=`basename $$s`; \
+		: ; \
+		echo "install $$s -> $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn"; \
+		cp $$s $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn.new; \
+		chmod 755 $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn.new; \
+		mv -f $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn.new \
+		      $(DESTDIR)$(INSTALLTOP)/$(LIBDIR)/$$fn; \
+		: ; \
+	done
+	@set -e; for x in dummy $(INSTALL_PROGRAMS); do \
+		if [ "$$x" = "dummy" ]; then continue; fi; \
+		fn=`basename $$x`; \
+		echo "install $$x -> $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
+		cp $$x $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new; \
+		chmod 755 $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new; \
+		mv -f $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new \
+		      $(DESTDIR)$(INSTALLTOP)/bin/$$fn; \
+	done
+	@set -e; for x in dummy $(BIN_SCRIPTS); do \
+		if [ "$$x" = "dummy" ]; then continue; fi; \
+		fn=`basename $$x`; \
+		echo "install $$x -> $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
+		cp $$x $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new; \
+		chmod 755 $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new; \
+		mv -f $(DESTDIR)$(INSTALLTOP)/bin/$$fn.new \
+		      $(DESTDIR)$(INSTALLTOP)/bin/$$fn; \
+	done
+
+uninstall_runtime:
+	@echo "*** Uninstalling runtime files"
+	@set -e; for x in dummy $(INSTALL_PROGRAMS); \
+	do  \
+		if [ "$$x" = "dummy" ]; then continue; fi; \
+		fn=`basename $$x`; \
+		echo "$(RM) $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
+		$(RM) $(DESTDIR)$(INSTALLTOP)/bin/$$fn; \
+	done;
+	@set -e; for x in dummy $(BIN_SCRIPTS); \
+	do  \
+		if [ "$$x" = "dummy" ]; then continue; fi; \
+		fn=`basename $$x`; \
+		echo "$(RM) $(DESTDIR)$(INSTALLTOP)/bin/$$fn"; \
+		$(RM) $(DESTDIR)$(INSTALLTOP)/bin/$$fn; \
+	done
+	@ : 
+	-$(RMDIR) $(DESTDIR)$(INSTALLTOP)/bin
+
+# A method to extract all names from a .pod file
+# The first sed extracts everything between "=head1 NAME" and the next =head1
+# The perl command joins all the lines into one
+# The second sed removes the description and turns all commas into spaces
+# VoilÃ , you have a space separated list of names!
+EXTRACT_NAMES=sed -e '1,/^=head1  *NAME *$$/d;/^=head1/,$$d' | \
+              $(PERL) -p -0 -e 's/\n/ /g; END {print "\n"}' | \
+              sed -e 's/ - .*$$//;s/,/ /g'
+PROCESS_PODS=\
+	set -e; \
+	here=`cd $(SRCDIR); pwd`; \
+	point=$$here/util/point.sh; \
+	for ds in apps:1 crypto:3 ssl:3; do \
+	    defdir=`echo $$ds | cut -f1 -d:`; \
+	    defsec=`echo $$ds | cut -f2 -d:`; \
+	    for p in $(SRCDIR)/doc/$$defdir/*.pod; do \
+		SEC=`sed -ne 's/^=for  *comment  *openssl_manual_section: *\([0-9]\) *$$/\1/p' $$p`; \
+		[ -z "$$SEC" ] && SEC=$$defsec; \
+		fn=`basename $$p .pod`; \
+		Name=$$fn; \
+		NAME=`echo $$fn | tr '[a-z]' '[A-Z]'`; \
+		suf=`eval "echo $$OUTSUFFIX"`; \
+		top=`eval "echo $$OUTTOP"`; \
+		$(PERL) $(SRCDIR)/util/mkdir-p.pl $$top/man$$SEC; \
+		echo "install $$p -> $$top/man$$SEC/$$fn$$suf"; \
+		cat $$p | eval "$$GENERATE" \
+			>  $$top/man$$SEC/$$fn$$suf; \
+		names=`cat $$p | $(EXTRACT_NAMES)`; \
+		( cd $$top/man$$SEC; \
+		  for n in $$names; do \
+		      comp_n="$$n"; \
+		      comp_fn="$$fn"; \
+		      case "$(PLATFORM)" in DJGPP|Cygwin*|mingw*|darwin*-*-cc) \
+			  comp_n=`echo "$$n" | tr '[A-Z]' '[a-z]'`; \
+			  comp_fn=`echo "$$fn" | tr '[A-Z]' '[a-z]'`; \
+			  ;; \
+		      esac; \
+		      if [ "$$comp_n" != "$$comp_fn" ]; then \
+			  echo "link $$top/man$$SEC/$$n$$suf -> $$top/man$$SEC/$$fn$$suf"; \
+			  PLATFORM=$(PLATFORM) $$point $$fn$$suf $$n$$suf; \
+		      fi; \
+		  done ); \
+	    done; \
+	done
+UNINSTALL_DOCS=\
+	set -e; \
+	here=`cd $(SRCDIR); pwd`; \
+	for ds in apps:1 crypto:3 ssl:3; do \
+	    defdir=`echo $$ds | cut -f1 -d:`; \
+	    defsec=`echo $$ds | cut -f2 -d:`; \
+	    for p in $(SRCDIR)/doc/$$defdir/*.pod; do \
+		SEC=`sed -ne 's/^=for  *comment  *openssl_manual_section: *\([0-9]\) *$$/\1/p' $$p`; \
+		[ -z "$$SEC" ] && SEC=$$defsec; \
+		fn=`basename $$p .pod`; \
+		suf=`eval "echo $$OUTSUFFIX"`; \
+		top=`eval "echo $$OUTTOP"`; \
+		echo "$(RM) $$top/man$$SEC/$$fn$$suf"; \
+	        $(RM) $$top/man$$SEC/$$fn$$suf; \
+		names=`cat $$p | $(EXTRACT_NAMES)`; \
+		for n in $$names; do \
+		    comp_n="$$n"; \
+		    comp_fn="$$fn"; \
+		    case "$(PLATFORM)" in DJGPP|Cygwin*|mingw*|darwin*-*-cc) \
+			comp_n=`echo "$$n" | tr '[A-Z]' '[a-z]'`; \
+			comp_fn=`echo "$$fn" | tr '[A-Z]' '[a-z]'`; \
+			;; \
+		    esac; \
+		    if [ "$$comp_n" != "$$comp_fn" ]; then \
+			echo "$(RM) $$top/man$$SEC/$$n$$suf"; \
+			$(RM) $$top/man$$SEC/$$n$$suf; \
+		    fi; \
+		done; \
+		( $(RMDIR) $$top/man$$SEC 2>/dev/null || exit 0 ); \
+	    done; \
+	done
+
+install_man_docs:
+	@[ -n "$(INSTALLTOP)" ] || (echo INSTALLTOP should not be empty; exit 1)
+	@echo "*** Installing manpages"
+	@\
+	OUTSUFFIX='.$${SEC}$(MANSUFFIX)'; \
+	OUTTOP="$(DESTDIR)$(MANDIR)"; \
+	GENERATE='pod2man --name=$$NAME --section=$$SEC --center=OpenSSL --release=$(VERSION)'; \
+	$(PROCESS_PODS)
+
+uninstall_man_docs:
+	@echo "*** Uninstalling manpages"
+	@\
+	OUTSUFFIX='.$${SEC}$(MANSUFFIX)'; \
+	OUTTOP="$(DESTDIR)$(MANDIR)"; \
+	$(UNINSTALL_DOCS)
+
+install_html_docs:
+	@[ -n "$(INSTALLTOP)" ] || (echo INSTALLTOP should not be empty; exit 1)
+	@echo "*** Installing HTML manpages"
+	@\
+	OUTSUFFIX='.$(HTMLSUFFIX)'; \
+	OUTTOP="$(DESTDIR)$(HTMLDIR)"; \
+	GENERATE="pod2html --podroot=$(SRCDIR)/doc --htmldir=.. \
+			   --podpath=apps:crypto:ssl --title=\$$Name \
+		  | perl -pe 's|href=\"http://man.he.net/man|href=\"../man|g; s|href=\"(.*/man.*)(?<!\.html)\">|href=\"\$$1.html\">|g;'"; \
+	$(PROCESS_PODS)
+
+uninstall_html_docs:
+	@echo "*** Uninstalling manpages"
+	@\
+	OUTSUFFIX='.$(HTMLSUFFIX)'; \
+	OUTTOP="$(DESTDIR)$(HTMLDIR)"; \
+	$(UNINSTALL_DOCS)
+
+
+# Developer targets (note: these are only available on Unix) #########
+
+update: generate errors ordinals
+
+generate: generate_apps generate_crypto_bn generate_crypto_objects \
+          generate_crypto_conf generate_crypto_asn1
+
+# Test coverage is a good idea for the future
+#coverage: $(PROGRAMS) $(TESTPROGRAMS)
+#	...
+
+lint:
+	lint -DLINT $(INCLUDES) $(SRCS)
+
+
+generate_apps:
+	( cd $(SRCDIR); $(PERL) VMS/VMSify-conf.pl \
+				< apps/openssl.cnf > apps/openssl-vms.cnf )
+	( b=`pwd`; cd $(SRCDIR); $(PERL) -I$$b apps/progs.pl \
+					apps/app_rand.c apps/apps.c apps/asn1pars.c apps/ca.c apps/ciphers.c apps/cms.c apps/crl.c apps/crl2p7.c apps/dgst.c apps/dhparam.c apps/dsa.c apps/dsaparam.c apps/ec.c apps/ecparam.c apps/enc.c apps/engine.c apps/errstr.c apps/gendsa.c apps/genpkey.c apps/genrsa.c apps/nseq.c apps/ocsp.c apps/openssl.c apps/opt.c apps/passwd.c apps/pkcs12.c apps/pkcs7.c apps/pkcs8.c apps/pkey.c apps/pkeyparam.c apps/pkeyutl.c apps/prime.c apps/rand.c apps/rehash.c apps/req.c apps/rsa.c apps/rsautl.c apps/s_cb.c apps/s_client.c apps/s_server.c apps/s_socket.c apps/s_time.c apps/sess_id.c apps/smime.c apps/speed.c apps/spkac.c apps/srp.c apps/ts.c apps/verify.c apps/version.c apps/x509.c \
+					> apps/progs.h )
+
+generate_crypto_bn:
+	( cd $(SRCDIR); $(PERL) crypto/bn/bn_prime.pl > crypto/bn/bn_prime.h )
+
+generate_crypto_objects:
+	( cd $(SRCDIR); $(PERL) crypto/objects/objects.pl \
+				crypto/objects/objects.txt \
+				crypto/objects/obj_mac.num \
+				include/openssl/obj_mac.h )
+	( cd $(SRCDIR); $(PERL) crypto/objects/obj_dat.pl \
+				include/openssl/obj_mac.h \
+				crypto/objects/obj_dat.h )
+	( cd $(SRCDIR); $(PERL) crypto/objects/objxref.pl \
+				crypto/objects/obj_mac.num \
+				crypto/objects/obj_xref.txt \
+				> crypto/objects/obj_xref.h )
+
+generate_crypto_conf:
+	( cd $(SRCDIR); $(PERL) crypto/conf/keysets.pl \
+			        > crypto/conf/conf_def.h )
+
+generate_crypto_asn1:
+	( cd $(SRCDIR); $(PERL) crypto/asn1/charmap.pl \
+			        > crypto/asn1/charmap.h )
+
+errors:
+	( cd $(SRCDIR); $(PERL) util/ck_errf.pl -strict */*.c */*/*.c )
+	( cd $(SRCDIR); $(PERL) util/mkerr.pl -recurse -write )
+	( cd $(SRCDIR)/engines; \
+	  for e in *.ec; do \
+	      $(PERL) ../util/mkerr.pl -conf $$e \
+		      -nostatic -staticloader -write *.c; \
+	  done )
+
+ordinals:
+	( b=`pwd`; cd $(SRCDIR); $(PERL) -I$$b util/mkdef.pl crypto update )
+	( b=`pwd`; cd $(SRCDIR); $(PERL) -I$$b util/mkdef.pl ssl update )
+
+test_ordinals:
+	( cd test; \
+	  SRCTOP=../$(SRCDIR) \
+	  BLDTOP=../$(BLDDIR) \
+	    $(PERL) ../$(SRCDIR)/test/run_tests.pl test_ordinals )
+
+tags TAGS: FORCE
+	rm -f TAGS tags
+	-ctags -R .
+	-etags `find . -name '*.[ch]' -o -name '*.pm'`
+
+# Release targets (note: only available on Unix) #####################
+
+TAR_COMMAND=$(TAR) $(TARFLAGS) --owner 0 --group 0 -cvf -
+PREPARE_CMD=:
+tar:
+	TMPDIR=/var/tmp/openssl-copy.$$$$; \
+	DISTDIR=$(NAME); \
+	mkdir -p $$TMPDIR/$$DISTDIR; \
+	(cd $(SRCDIR); \
+	 git ls-tree -r --name-only --full-tree HEAD \
+         | grep -v '^fuzz/corpora' \
+	 | while read F; do \
+	       mkdir -p $$TMPDIR/$$DISTDIR/`dirname $$F`; \
+	       cp $$F $$TMPDIR/$$DISTDIR/$$F; \
+	   done); \
+	(cd $$TMPDIR; \
+	 $(PREPARE_CMD); \
+	 find $$TMPDIR/$$DISTDIR -type d -print | xargs chmod 755; \
+	 find $$TMPDIR/$$DISTDIR -type f -print | xargs chmod a+r; \
+	 find $$TMPDIR/$$DISTDIR -type f -perm -0100 -print | xargs chmod a+x; \
+	 $(TAR_COMMAND) $$DISTDIR) \
+	| (cd $(SRCDIR); gzip --best > $(TARFILE).gz); \
+	rm -rf $$TMPDIR
+	cd $(SRCDIR); ls -l $(TARFILE).gz
+
+dist:
+	@$(MAKE) PREPARE_CMD='$(PERL) ./Configure dist' tar
+
+# Helper targets #####################################################
+
+link-utils: $(BLDDIR)/util/opensslwrap.sh
+
+$(BLDDIR)/util/opensslwrap.sh: configdata.pm
+	@if [ "$(SRCDIR)" != "$(BLDDIR)" ]; then \
+	    mkdir -p "$(BLDDIR)/util"; \
+	    ln -sf "../$(SRCDIR)/util/opensslwrap.sh" "$(BLDDIR)/util"; \
+	fi
+
+FORCE:
+
+# Building targets ###################################################
+
+libcrypto.pc libssl.pc openssl.pc: configdata.pm $(LIBS) 
+libcrypto.pc:
+	@ ( echo 'prefix=$(INSTALLTOP)'; \
+	    echo 'exec_prefix=$${prefix}'; \
+	    echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
+	    echo 'includedir=$${prefix}/include'; \
+	    echo 'enginesdir=$${libdir}/engines-1.1'; \
+	    echo ''; \
+	    echo 'Name: OpenSSL-libcrypto'; \
+	    echo 'Description: OpenSSL cryptography library'; \
+	    echo 'Version: '$(VERSION); \
+	    echo 'Libs: -L$${libdir} -lcrypto'; \
+	    echo 'Libs.private: $(EX_LIBS)'; \
+	    echo 'Cflags: -I$${includedir}' ) > libcrypto.pc
+
+libssl.pc:
+	@ ( echo 'prefix=$(INSTALLTOP)'; \
+	    echo 'exec_prefix=$${prefix}'; \
+	    echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
+	    echo 'includedir=$${prefix}/include'; \
+	    echo ''; \
+	    echo 'Name: OpenSSL-libssl'; \
+	    echo 'Description: Secure Sockets Layer and cryptography libraries'; \
+	    echo 'Version: '$(VERSION); \
+	    echo 'Requires.private: libcrypto'; \
+	    echo 'Libs: -L$${libdir} -lssl'; \
+	    echo 'Libs.private: $(EX_LIBS)'; \
+	    echo 'Cflags: -I$${includedir}' ) > libssl.pc
+
+openssl.pc:
+	@ ( echo 'prefix=$(INSTALLTOP)'; \
+	    echo 'exec_prefix=$${prefix}'; \
+	    echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
+	    echo 'includedir=$${prefix}/include'; \
+	    echo ''; \
+	    echo 'Name: OpenSSL'; \
+	    echo 'Description: Secure Sockets Layer and cryptography libraries and tools'; \
+	    echo 'Version: '$(VERSION); \
+	    echo 'Requires: libssl libcrypto' ) > openssl.pc
+
+configdata.pm: $(SRCDIR)/Configure $(SRCDIR)/config Configurations/unix-Makefile.tmpl Configurations/common.tmpl ./build.info crypto/build.info ssl/build.info engines/build.info apps/build.info test/build.info util/build.info tools/build.info fuzz/build.info crypto/objects/build.info crypto/md4/build.info crypto/md5/build.info crypto/sha/build.info crypto/mdc2/build.info crypto/hmac/build.info crypto/ripemd/build.info crypto/whrlpool/build.info crypto/poly1305/build.info crypto/blake2/build.info crypto/des/build.info crypto/aes/build.info crypto/rc2/build.info crypto/rc4/build.info crypto/idea/build.info crypto/bf/build.info crypto/cast/build.info crypto/camellia/build.info crypto/seed/build.info crypto/chacha/build.info crypto/modes/build.info crypto/bn/build.info crypto/ec/build.info crypto/rsa/build.info crypto/dsa/build.info crypto/dh/build.info crypto/dso/build.info crypto/engine/build.info crypto/buffer/build.info crypto/bio/build.info crypto/stack/build.info crypto/lhash/build.info crypto/rand/build.info crypto/err/build.info crypto/evp/build.info crypto/asn1/build.info crypto/pem/build.info crypto/x509/build.info crypto/x509v3/build.info crypto/conf/build.info crypto/txt_db/build.info crypto/pkcs7/build.info crypto/pkcs12/build.info crypto/comp/build.info crypto/ocsp/build.info crypto/cms/build.info crypto/ts/build.info crypto/srp/build.info crypto/cmac/build.info crypto/ct/build.info crypto/async/build.info crypto/kdf/build.info Configurations/00-base-templates.conf Configurations/10-main.conf
+	@echo "Detected changed: $?"
+	@echo "Reconfiguring..."
+	$(PERL) $(SRCDIR)/Configure reconf
+	@echo "**************************************************"
+	@echo "***                                            ***"
+	@echo "***   Please run the same make command again   ***"
+	@echo "***                                            ***"
+	@echo "**************************************************"
+	@false
+
+
+crypto/include/internal/bn_conf.h: crypto/include/internal/bn_conf.h.in configdata.pm
+	$(PERL) "-I$(BLDDIR)" -Mconfigdata "util/dofile.pl" \
+	    "-oMakefile" crypto/include/internal/bn_conf.h.in > $@
+crypto/include/internal/dso_conf.h: crypto/include/internal/dso_conf.h.in configdata.pm
+	$(PERL) "-I$(BLDDIR)" -Mconfigdata "util/dofile.pl" \
+	    "-oMakefile" crypto/include/internal/dso_conf.h.in > $@
+include/openssl/opensslconf.h: include/openssl/opensslconf.h.in configdata.pm
+	$(PERL) "-I$(BLDDIR)" -Mconfigdata "util/dofile.pl" \
+	    "-oMakefile" include/openssl/opensslconf.h.in > $@
+libcrypto.a: crypto/aes/aes_cbc.o crypto/aes/aes_cfb.o crypto/aes/aes_core.o crypto/aes/aes_ecb.o crypto/aes/aes_ige.o crypto/aes/aes_misc.o crypto/aes/aes_ofb.o crypto/aes/aes_wrap.o crypto/asn1/a_bitstr.o crypto/asn1/a_d2i_fp.o crypto/asn1/a_digest.o crypto/asn1/a_dup.o crypto/asn1/a_gentm.o crypto/asn1/a_i2d_fp.o crypto/asn1/a_int.o crypto/asn1/a_mbstr.o crypto/asn1/a_object.o crypto/asn1/a_octet.o crypto/asn1/a_print.o crypto/asn1/a_sign.o crypto/asn1/a_strex.o crypto/asn1/a_strnid.o crypto/asn1/a_time.o crypto/asn1/a_type.o crypto/asn1/a_utctm.o crypto/asn1/a_utf8.o crypto/asn1/a_verify.o crypto/asn1/ameth_lib.o crypto/asn1/asn1_err.o crypto/asn1/asn1_gen.o crypto/asn1/asn1_lib.o crypto/asn1/asn1_par.o crypto/asn1/asn_mime.o crypto/asn1/asn_moid.o crypto/asn1/asn_mstbl.o crypto/asn1/asn_pack.o crypto/asn1/bio_asn1.o crypto/asn1/bio_ndef.o crypto/asn1/d2i_pr.o crypto/asn1/d2i_pu.o crypto/asn1/evp_asn1.o crypto/asn1/f_int.o crypto/asn1/f_string.o crypto/asn1/i2d_pr.o crypto/asn1/i2d_pu.o crypto/asn1/n_pkey.o crypto/asn1/nsseq.o crypto/asn1/p5_pbe.o crypto/asn1/p5_pbev2.o crypto/asn1/p5_scrypt.o crypto/asn1/p8_pkey.o crypto/asn1/t_bitst.o crypto/asn1/t_pkey.o crypto/asn1/t_spki.o crypto/asn1/tasn_dec.o crypto/asn1/tasn_enc.o crypto/asn1/tasn_fre.o crypto/asn1/tasn_new.o crypto/asn1/tasn_prn.o crypto/asn1/tasn_scn.o crypto/asn1/tasn_typ.o crypto/asn1/tasn_utl.o crypto/asn1/x_algor.o crypto/asn1/x_bignum.o crypto/asn1/x_info.o crypto/asn1/x_long.o crypto/asn1/x_pkey.o crypto/asn1/x_sig.o crypto/asn1/x_spki.o crypto/asn1/x_val.o crypto/async/arch/async_null.o crypto/async/arch/async_posix.o crypto/async/arch/async_win.o crypto/async/async.o crypto/async/async_err.o crypto/async/async_wait.o crypto/bf/bf_cfb64.o crypto/bf/bf_ecb.o crypto/bf/bf_enc.o crypto/bf/bf_ofb64.o crypto/bf/bf_skey.o crypto/bio/b_addr.o crypto/bio/b_dump.o crypto/bio/b_print.o crypto/bio/b_sock.o crypto/bio/b_sock2.o crypto/bio/bf_buff.o crypto/bio/bf_lbuf.o crypto/bio/bf_nbio.o crypto/bio/bf_null.o crypto/bio/bio_cb.o crypto/bio/bio_err.o crypto/bio/bio_lib.o crypto/bio/bio_meth.o crypto/bio/bss_acpt.o crypto/bio/bss_bio.o crypto/bio/bss_conn.o crypto/bio/bss_dgram.o crypto/bio/bss_fd.o crypto/bio/bss_file.o crypto/bio/bss_log.o crypto/bio/bss_mem.o crypto/bio/bss_null.o crypto/bio/bss_sock.o crypto/blake2/blake2b.o crypto/blake2/blake2s.o crypto/blake2/m_blake2b.o crypto/blake2/m_blake2s.o crypto/bn/bn_add.o crypto/bn/bn_asm.o crypto/bn/bn_blind.o crypto/bn/bn_const.o crypto/bn/bn_ctx.o crypto/bn/bn_depr.o crypto/bn/bn_dh.o crypto/bn/bn_div.o crypto/bn/bn_err.o crypto/bn/bn_exp.o crypto/bn/bn_exp2.o crypto/bn/bn_gcd.o crypto/bn/bn_gf2m.o crypto/bn/bn_intern.o crypto/bn/bn_kron.o crypto/bn/bn_lib.o crypto/bn/bn_mod.o crypto/bn/bn_mont.o crypto/bn/bn_mpi.o crypto/bn/bn_mul.o crypto/bn/bn_nist.o crypto/bn/bn_prime.o crypto/bn/bn_print.o crypto/bn/bn_rand.o crypto/bn/bn_recp.o crypto/bn/bn_shift.o crypto/bn/bn_sqr.o crypto/bn/bn_sqrt.o crypto/bn/bn_srp.o crypto/bn/bn_word.o crypto/bn/bn_x931p.o crypto/buffer/buf_err.o crypto/buffer/buffer.o crypto/camellia/camellia.o crypto/camellia/cmll_cbc.o crypto/camellia/cmll_cfb.o crypto/camellia/cmll_ctr.o crypto/camellia/cmll_ecb.o crypto/camellia/cmll_misc.o crypto/camellia/cmll_ofb.o crypto/cast/c_cfb64.o crypto/cast/c_ecb.o crypto/cast/c_enc.o crypto/cast/c_ofb64.o crypto/cast/c_skey.o crypto/chacha/chacha_enc.o crypto/cmac/cm_ameth.o crypto/cmac/cm_pmeth.o crypto/cmac/cmac.o crypto/cms/cms_asn1.o crypto/cms/cms_att.o crypto/cms/cms_cd.o crypto/cms/cms_dd.o crypto/cms/cms_enc.o crypto/cms/cms_env.o crypto/cms/cms_err.o crypto/cms/cms_ess.o crypto/cms/cms_io.o crypto/cms/cms_kari.o crypto/cms/cms_lib.o crypto/cms/cms_pwri.o crypto/cms/cms_sd.o crypto/cms/cms_smime.o crypto/comp/c_zlib.o crypto/comp/comp_err.o crypto/comp/comp_lib.o crypto/conf/conf_api.o crypto/conf/conf_def.o crypto/conf/conf_err.o crypto/conf/conf_lib.o crypto/conf/conf_mall.o crypto/conf/conf_mod.o crypto/conf/conf_sap.o crypto/cpt_err.o crypto/cryptlib.o crypto/ct/ct_b64.o crypto/ct/ct_err.o crypto/ct/ct_log.o crypto/ct/ct_oct.o crypto/ct/ct_policy.o crypto/ct/ct_prn.o crypto/ct/ct_sct.o crypto/ct/ct_sct_ctx.o crypto/ct/ct_vfy.o crypto/ct/ct_x509v3.o crypto/cversion.o crypto/des/cbc_cksm.o crypto/des/cbc_enc.o crypto/des/cfb64ede.o crypto/des/cfb64enc.o crypto/des/cfb_enc.o crypto/des/des_enc.o crypto/des/ecb3_enc.o crypto/des/ecb_enc.o crypto/des/fcrypt.o crypto/des/fcrypt_b.o crypto/des/ofb64ede.o crypto/des/ofb64enc.o crypto/des/ofb_enc.o crypto/des/pcbc_enc.o crypto/des/qud_cksm.o crypto/des/rand_key.o crypto/des/rpc_enc.o crypto/des/set_key.o crypto/des/str2key.o crypto/des/xcbc_enc.o crypto/dh/dh_ameth.o crypto/dh/dh_asn1.o crypto/dh/dh_check.o crypto/dh/dh_depr.o crypto/dh/dh_err.o crypto/dh/dh_gen.o crypto/dh/dh_kdf.o crypto/dh/dh_key.o crypto/dh/dh_lib.o crypto/dh/dh_meth.o crypto/dh/dh_pmeth.o crypto/dh/dh_prn.o crypto/dh/dh_rfc5114.o crypto/dsa/dsa_ameth.o crypto/dsa/dsa_asn1.o crypto/dsa/dsa_depr.o crypto/dsa/dsa_err.o crypto/dsa/dsa_gen.o crypto/dsa/dsa_key.o crypto/dsa/dsa_lib.o crypto/dsa/dsa_meth.o crypto/dsa/dsa_ossl.o crypto/dsa/dsa_pmeth.o crypto/dsa/dsa_prn.o crypto/dsa/dsa_sign.o crypto/dsa/dsa_vrf.o crypto/dso/dso_dl.o crypto/dso/dso_dlfcn.o crypto/dso/dso_err.o crypto/dso/dso_lib.o crypto/dso/dso_openssl.o crypto/dso/dso_vms.o crypto/dso/dso_win32.o crypto/ebcdic.o crypto/ec/curve25519.o crypto/ec/ec2_mult.o crypto/ec/ec2_oct.o crypto/ec/ec2_smpl.o crypto/ec/ec_ameth.o crypto/ec/ec_asn1.o crypto/ec/ec_check.o crypto/ec/ec_curve.o crypto/ec/ec_cvt.o crypto/ec/ec_err.o crypto/ec/ec_key.o crypto/ec/ec_kmeth.o crypto/ec/ec_lib.o crypto/ec/ec_mult.o crypto/ec/ec_oct.o crypto/ec/ec_pmeth.o crypto/ec/ec_print.o crypto/ec/ecdh_kdf.o crypto/ec/ecdh_ossl.o crypto/ec/ecdsa_ossl.o crypto/ec/ecdsa_sign.o crypto/ec/ecdsa_vrf.o crypto/ec/eck_prn.o crypto/ec/ecp_mont.o crypto/ec/ecp_nist.o crypto/ec/ecp_nistp224.o crypto/ec/ecp_nistp256.o crypto/ec/ecp_nistp521.o crypto/ec/ecp_nistputil.o crypto/ec/ecp_oct.o crypto/ec/ecp_smpl.o crypto/ec/ecx_meth.o crypto/engine/eng_all.o crypto/engine/eng_cnf.o crypto/engine/eng_cryptodev.o crypto/engine/eng_ctrl.o crypto/engine/eng_dyn.o crypto/engine/eng_err.o crypto/engine/eng_fat.o crypto/engine/eng_init.o crypto/engine/eng_lib.o crypto/engine/eng_list.o crypto/engine/eng_openssl.o crypto/engine/eng_pkey.o crypto/engine/eng_rdrand.o crypto/engine/eng_table.o crypto/engine/tb_asnmth.o crypto/engine/tb_cipher.o crypto/engine/tb_dh.o crypto/engine/tb_digest.o crypto/engine/tb_dsa.o crypto/engine/tb_eckey.o crypto/engine/tb_pkmeth.o crypto/engine/tb_rand.o crypto/engine/tb_rsa.o crypto/err/err.o crypto/err/err_all.o crypto/err/err_prn.o crypto/evp/bio_b64.o crypto/evp/bio_enc.o crypto/evp/bio_md.o crypto/evp/bio_ok.o crypto/evp/c_allc.o crypto/evp/c_alld.o crypto/evp/cmeth_lib.o crypto/evp/digest.o crypto/evp/e_aes.o crypto/evp/e_aes_cbc_hmac_sha1.o crypto/evp/e_aes_cbc_hmac_sha256.o crypto/evp/e_bf.o crypto/evp/e_camellia.o crypto/evp/e_cast.o crypto/evp/e_chacha20_poly1305.o crypto/evp/e_des.o crypto/evp/e_des3.o crypto/evp/e_idea.o crypto/evp/e_null.o crypto/evp/e_old.o crypto/evp/e_rc2.o crypto/evp/e_rc4.o crypto/evp/e_rc4_hmac_md5.o crypto/evp/e_rc5.o crypto/evp/e_seed.o crypto/evp/e_xcbc_d.o crypto/evp/encode.o crypto/evp/evp_cnf.o crypto/evp/evp_enc.o crypto/evp/evp_err.o crypto/evp/evp_key.o crypto/evp/evp_lib.o crypto/evp/evp_pbe.o crypto/evp/evp_pkey.o crypto/evp/m_md2.o crypto/evp/m_md4.o crypto/evp/m_md5.o crypto/evp/m_md5_sha1.o crypto/evp/m_mdc2.o crypto/evp/m_null.o crypto/evp/m_ripemd.o crypto/evp/m_sha1.o crypto/evp/m_sigver.o crypto/evp/m_wp.o crypto/evp/names.o crypto/evp/p5_crpt.o crypto/evp/p5_crpt2.o crypto/evp/p_dec.o crypto/evp/p_enc.o crypto/evp/p_lib.o crypto/evp/p_open.o crypto/evp/p_seal.o crypto/evp/p_sign.o crypto/evp/p_verify.o crypto/evp/pmeth_fn.o crypto/evp/pmeth_gn.o crypto/evp/pmeth_lib.o crypto/evp/scrypt.o crypto/ex_data.o crypto/hmac/hm_ameth.o crypto/hmac/hm_pmeth.o crypto/hmac/hmac.o crypto/idea/i_cbc.o crypto/idea/i_cfb64.o crypto/idea/i_ecb.o crypto/idea/i_ofb64.o crypto/idea/i_skey.o crypto/init.o crypto/kdf/hkdf.o crypto/kdf/kdf_err.o crypto/kdf/tls1_prf.o crypto/lhash/lh_stats.o crypto/lhash/lhash.o crypto/md4/md4_dgst.o crypto/md4/md4_one.o crypto/md5/md5_dgst.o crypto/md5/md5_one.o crypto/mdc2/mdc2_one.o crypto/mdc2/mdc2dgst.o crypto/mem.o crypto/mem_clr.o crypto/mem_dbg.o crypto/mem_sec.o crypto/modes/cbc128.o crypto/modes/ccm128.o crypto/modes/cfb128.o crypto/modes/ctr128.o crypto/modes/cts128.o crypto/modes/gcm128.o crypto/modes/ocb128.o crypto/modes/ofb128.o crypto/modes/wrap128.o crypto/modes/xts128.o crypto/o_dir.o crypto/o_fips.o crypto/o_fopen.o crypto/o_init.o crypto/o_str.o crypto/o_time.o crypto/objects/o_names.o crypto/objects/obj_dat.o crypto/objects/obj_err.o crypto/objects/obj_lib.o crypto/objects/obj_xref.o crypto/ocsp/ocsp_asn.o crypto/ocsp/ocsp_cl.o crypto/ocsp/ocsp_err.o crypto/ocsp/ocsp_ext.o crypto/ocsp/ocsp_ht.o crypto/ocsp/ocsp_lib.o crypto/ocsp/ocsp_prn.o crypto/ocsp/ocsp_srv.o crypto/ocsp/ocsp_vfy.o crypto/ocsp/v3_ocsp.o crypto/pem/pem_all.o crypto/pem/pem_err.o crypto/pem/pem_info.o crypto/pem/pem_lib.o crypto/pem/pem_oth.o crypto/pem/pem_pk8.o crypto/pem/pem_pkey.o crypto/pem/pem_sign.o crypto/pem/pem_x509.o crypto/pem/pem_xaux.o crypto/pem/pvkfmt.o crypto/pkcs12/p12_add.o crypto/pkcs12/p12_asn.o crypto/pkcs12/p12_attr.o crypto/pkcs12/p12_crpt.o crypto/pkcs12/p12_crt.o crypto/pkcs12/p12_decr.o crypto/pkcs12/p12_init.o crypto/pkcs12/p12_key.o crypto/pkcs12/p12_kiss.o crypto/pkcs12/p12_mutl.o crypto/pkcs12/p12_npas.o crypto/pkcs12/p12_p8d.o crypto/pkcs12/p12_p8e.o crypto/pkcs12/p12_sbag.o crypto/pkcs12/p12_utl.o crypto/pkcs12/pk12err.o crypto/pkcs7/bio_pk7.o crypto/pkcs7/pk7_asn1.o crypto/pkcs7/pk7_attr.o crypto/pkcs7/pk7_doit.o crypto/pkcs7/pk7_lib.o crypto/pkcs7/pk7_mime.o crypto/pkcs7/pk7_smime.o crypto/pkcs7/pkcs7err.o crypto/poly1305/poly1305.o crypto/rand/md_rand.o crypto/rand/rand_egd.o crypto/rand/rand_err.o crypto/rand/rand_lib.o crypto/rand/rand_unix.o crypto/rand/rand_vms.o crypto/rand/rand_win.o crypto/rand/randfile.o crypto/rc2/rc2_cbc.o crypto/rc2/rc2_ecb.o crypto/rc2/rc2_skey.o crypto/rc2/rc2cfb64.o crypto/rc2/rc2ofb64.o crypto/rc4/rc4_enc.o crypto/rc4/rc4_skey.o crypto/ripemd/rmd_dgst.o crypto/ripemd/rmd_one.o crypto/rsa/rsa_ameth.o crypto/rsa/rsa_asn1.o crypto/rsa/rsa_chk.o crypto/rsa/rsa_crpt.o crypto/rsa/rsa_depr.o crypto/rsa/rsa_err.o crypto/rsa/rsa_gen.o crypto/rsa/rsa_lib.o crypto/rsa/rsa_meth.o crypto/rsa/rsa_none.o crypto/rsa/rsa_null.o crypto/rsa/rsa_oaep.o crypto/rsa/rsa_ossl.o crypto/rsa/rsa_pk1.o crypto/rsa/rsa_pmeth.o crypto/rsa/rsa_prn.o crypto/rsa/rsa_pss.o crypto/rsa/rsa_saos.o crypto/rsa/rsa_sign.o crypto/rsa/rsa_ssl.o crypto/rsa/rsa_x931.o crypto/rsa/rsa_x931g.o crypto/seed/seed.o crypto/seed/seed_cbc.o crypto/seed/seed_cfb.o crypto/seed/seed_ecb.o crypto/seed/seed_ofb.o crypto/sha/sha1_one.o crypto/sha/sha1dgst.o crypto/sha/sha256.o crypto/sha/sha512.o crypto/srp/srp_lib.o crypto/srp/srp_vfy.o crypto/stack/stack.o crypto/threads_none.o crypto/threads_pthread.o crypto/threads_win.o crypto/ts/ts_asn1.o crypto/ts/ts_conf.o crypto/ts/ts_err.o crypto/ts/ts_lib.o crypto/ts/ts_req_print.o crypto/ts/ts_req_utils.o crypto/ts/ts_rsp_print.o crypto/ts/ts_rsp_sign.o crypto/ts/ts_rsp_utils.o crypto/ts/ts_rsp_verify.o crypto/ts/ts_verify_ctx.o crypto/txt_db/txt_db.o crypto/uid.o crypto/whrlpool/wp_block.o crypto/whrlpool/wp_dgst.o crypto/x509/by_dir.o crypto/x509/by_file.o crypto/x509/t_crl.o crypto/x509/t_req.o crypto/x509/t_x509.o crypto/x509/x509_att.o crypto/x509/x509_cmp.o crypto/x509/x509_d2.o crypto/x509/x509_def.o crypto/x509/x509_err.o crypto/x509/x509_ext.o crypto/x509/x509_lu.o crypto/x509/x509_obj.o crypto/x509/x509_r2x.o crypto/x509/x509_req.o crypto/x509/x509_set.o crypto/x509/x509_trs.o crypto/x509/x509_txt.o crypto/x509/x509_v3.o crypto/x509/x509_vfy.o crypto/x509/x509_vpm.o crypto/x509/x509cset.o crypto/x509/x509name.o crypto/x509/x509rset.o crypto/x509/x509spki.o crypto/x509/x509type.o crypto/x509/x_all.o crypto/x509/x_attrib.o crypto/x509/x_crl.o crypto/x509/x_exten.o crypto/x509/x_name.o crypto/x509/x_pubkey.o crypto/x509/x_req.o crypto/x509/x_x509.o crypto/x509/x_x509a.o crypto/x509v3/pcy_cache.o crypto/x509v3/pcy_data.o crypto/x509v3/pcy_lib.o crypto/x509v3/pcy_map.o crypto/x509v3/pcy_node.o crypto/x509v3/pcy_tree.o crypto/x509v3/v3_addr.o crypto/x509v3/v3_akey.o crypto/x509v3/v3_akeya.o crypto/x509v3/v3_alt.o crypto/x509v3/v3_asid.o crypto/x509v3/v3_bcons.o crypto/x509v3/v3_bitst.o crypto/x509v3/v3_conf.o crypto/x509v3/v3_cpols.o crypto/x509v3/v3_crld.o crypto/x509v3/v3_enum.o crypto/x509v3/v3_extku.o crypto/x509v3/v3_genn.o crypto/x509v3/v3_ia5.o crypto/x509v3/v3_info.o crypto/x509v3/v3_int.o crypto/x509v3/v3_lib.o crypto/x509v3/v3_ncons.o crypto/x509v3/v3_pci.o crypto/x509v3/v3_pcia.o crypto/x509v3/v3_pcons.o crypto/x509v3/v3_pku.o crypto/x509v3/v3_pmaps.o crypto/x509v3/v3_prn.o crypto/x509v3/v3_purp.o crypto/x509v3/v3_skey.o crypto/x509v3/v3_sxnet.o crypto/x509v3/v3_tlsf.o crypto/x509v3/v3_utl.o crypto/x509v3/v3err.o engines/e_capi.o engines/e_padlock.o
+	$(AR) $@ $?
+	$(RANLIB) $@ || echo Never mind.
+crypto/aes/aes_cbc.o: crypto/aes/aes_cbc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/aes/aes_cbc.d.tmp -MT $@ -c -o $@ crypto/aes/aes_cbc.c
+	@touch crypto/aes/aes_cbc.d.tmp
+	@if cmp crypto/aes/aes_cbc.d.tmp crypto/aes/aes_cbc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/aes/aes_cbc.d.tmp; \
+	else \
+		mv crypto/aes/aes_cbc.d.tmp crypto/aes/aes_cbc.d; \
+	fi
+crypto/aes/aes_cfb.o: crypto/aes/aes_cfb.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/aes/aes_cfb.d.tmp -MT $@ -c -o $@ crypto/aes/aes_cfb.c
+	@touch crypto/aes/aes_cfb.d.tmp
+	@if cmp crypto/aes/aes_cfb.d.tmp crypto/aes/aes_cfb.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/aes/aes_cfb.d.tmp; \
+	else \
+		mv crypto/aes/aes_cfb.d.tmp crypto/aes/aes_cfb.d; \
+	fi
+crypto/aes/aes_core.o: crypto/aes/aes_core.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/aes/aes_core.d.tmp -MT $@ -c -o $@ crypto/aes/aes_core.c
+	@touch crypto/aes/aes_core.d.tmp
+	@if cmp crypto/aes/aes_core.d.tmp crypto/aes/aes_core.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/aes/aes_core.d.tmp; \
+	else \
+		mv crypto/aes/aes_core.d.tmp crypto/aes/aes_core.d; \
+	fi
+crypto/aes/aes_ecb.o: crypto/aes/aes_ecb.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/aes/aes_ecb.d.tmp -MT $@ -c -o $@ crypto/aes/aes_ecb.c
+	@touch crypto/aes/aes_ecb.d.tmp
+	@if cmp crypto/aes/aes_ecb.d.tmp crypto/aes/aes_ecb.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/aes/aes_ecb.d.tmp; \
+	else \
+		mv crypto/aes/aes_ecb.d.tmp crypto/aes/aes_ecb.d; \
+	fi
+crypto/aes/aes_ige.o: crypto/aes/aes_ige.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/aes/aes_ige.d.tmp -MT $@ -c -o $@ crypto/aes/aes_ige.c
+	@touch crypto/aes/aes_ige.d.tmp
+	@if cmp crypto/aes/aes_ige.d.tmp crypto/aes/aes_ige.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/aes/aes_ige.d.tmp; \
+	else \
+		mv crypto/aes/aes_ige.d.tmp crypto/aes/aes_ige.d; \
+	fi
+crypto/aes/aes_misc.o: crypto/aes/aes_misc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/aes/aes_misc.d.tmp -MT $@ -c -o $@ crypto/aes/aes_misc.c
+	@touch crypto/aes/aes_misc.d.tmp
+	@if cmp crypto/aes/aes_misc.d.tmp crypto/aes/aes_misc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/aes/aes_misc.d.tmp; \
+	else \
+		mv crypto/aes/aes_misc.d.tmp crypto/aes/aes_misc.d; \
+	fi
+crypto/aes/aes_ofb.o: crypto/aes/aes_ofb.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/aes/aes_ofb.d.tmp -MT $@ -c -o $@ crypto/aes/aes_ofb.c
+	@touch crypto/aes/aes_ofb.d.tmp
+	@if cmp crypto/aes/aes_ofb.d.tmp crypto/aes/aes_ofb.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/aes/aes_ofb.d.tmp; \
+	else \
+		mv crypto/aes/aes_ofb.d.tmp crypto/aes/aes_ofb.d; \
+	fi
+crypto/aes/aes_wrap.o: crypto/aes/aes_wrap.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/aes/aes_wrap.d.tmp -MT $@ -c -o $@ crypto/aes/aes_wrap.c
+	@touch crypto/aes/aes_wrap.d.tmp
+	@if cmp crypto/aes/aes_wrap.d.tmp crypto/aes/aes_wrap.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/aes/aes_wrap.d.tmp; \
+	else \
+		mv crypto/aes/aes_wrap.d.tmp crypto/aes/aes_wrap.d; \
+	fi
+crypto/asn1/a_bitstr.o: crypto/asn1/a_bitstr.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/a_bitstr.d.tmp -MT $@ -c -o $@ crypto/asn1/a_bitstr.c
+	@touch crypto/asn1/a_bitstr.d.tmp
+	@if cmp crypto/asn1/a_bitstr.d.tmp crypto/asn1/a_bitstr.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/a_bitstr.d.tmp; \
+	else \
+		mv crypto/asn1/a_bitstr.d.tmp crypto/asn1/a_bitstr.d; \
+	fi
+crypto/asn1/a_d2i_fp.o: crypto/asn1/a_d2i_fp.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/a_d2i_fp.d.tmp -MT $@ -c -o $@ crypto/asn1/a_d2i_fp.c
+	@touch crypto/asn1/a_d2i_fp.d.tmp
+	@if cmp crypto/asn1/a_d2i_fp.d.tmp crypto/asn1/a_d2i_fp.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/a_d2i_fp.d.tmp; \
+	else \
+		mv crypto/asn1/a_d2i_fp.d.tmp crypto/asn1/a_d2i_fp.d; \
+	fi
+crypto/asn1/a_digest.o: crypto/asn1/a_digest.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/a_digest.d.tmp -MT $@ -c -o $@ crypto/asn1/a_digest.c
+	@touch crypto/asn1/a_digest.d.tmp
+	@if cmp crypto/asn1/a_digest.d.tmp crypto/asn1/a_digest.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/a_digest.d.tmp; \
+	else \
+		mv crypto/asn1/a_digest.d.tmp crypto/asn1/a_digest.d; \
+	fi
+crypto/asn1/a_dup.o: crypto/asn1/a_dup.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/a_dup.d.tmp -MT $@ -c -o $@ crypto/asn1/a_dup.c
+	@touch crypto/asn1/a_dup.d.tmp
+	@if cmp crypto/asn1/a_dup.d.tmp crypto/asn1/a_dup.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/a_dup.d.tmp; \
+	else \
+		mv crypto/asn1/a_dup.d.tmp crypto/asn1/a_dup.d; \
+	fi
+crypto/asn1/a_gentm.o: crypto/asn1/a_gentm.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/a_gentm.d.tmp -MT $@ -c -o $@ crypto/asn1/a_gentm.c
+	@touch crypto/asn1/a_gentm.d.tmp
+	@if cmp crypto/asn1/a_gentm.d.tmp crypto/asn1/a_gentm.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/a_gentm.d.tmp; \
+	else \
+		mv crypto/asn1/a_gentm.d.tmp crypto/asn1/a_gentm.d; \
+	fi
+crypto/asn1/a_i2d_fp.o: crypto/asn1/a_i2d_fp.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/a_i2d_fp.d.tmp -MT $@ -c -o $@ crypto/asn1/a_i2d_fp.c
+	@touch crypto/asn1/a_i2d_fp.d.tmp
+	@if cmp crypto/asn1/a_i2d_fp.d.tmp crypto/asn1/a_i2d_fp.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/a_i2d_fp.d.tmp; \
+	else \
+		mv crypto/asn1/a_i2d_fp.d.tmp crypto/asn1/a_i2d_fp.d; \
+	fi
+crypto/asn1/a_int.o: crypto/asn1/a_int.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/a_int.d.tmp -MT $@ -c -o $@ crypto/asn1/a_int.c
+	@touch crypto/asn1/a_int.d.tmp
+	@if cmp crypto/asn1/a_int.d.tmp crypto/asn1/a_int.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/a_int.d.tmp; \
+	else \
+		mv crypto/asn1/a_int.d.tmp crypto/asn1/a_int.d; \
+	fi
+crypto/asn1/a_mbstr.o: crypto/asn1/a_mbstr.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/a_mbstr.d.tmp -MT $@ -c -o $@ crypto/asn1/a_mbstr.c
+	@touch crypto/asn1/a_mbstr.d.tmp
+	@if cmp crypto/asn1/a_mbstr.d.tmp crypto/asn1/a_mbstr.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/a_mbstr.d.tmp; \
+	else \
+		mv crypto/asn1/a_mbstr.d.tmp crypto/asn1/a_mbstr.d; \
+	fi
+crypto/asn1/a_object.o: crypto/asn1/a_object.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/a_object.d.tmp -MT $@ -c -o $@ crypto/asn1/a_object.c
+	@touch crypto/asn1/a_object.d.tmp
+	@if cmp crypto/asn1/a_object.d.tmp crypto/asn1/a_object.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/a_object.d.tmp; \
+	else \
+		mv crypto/asn1/a_object.d.tmp crypto/asn1/a_object.d; \
+	fi
+crypto/asn1/a_octet.o: crypto/asn1/a_octet.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/a_octet.d.tmp -MT $@ -c -o $@ crypto/asn1/a_octet.c
+	@touch crypto/asn1/a_octet.d.tmp
+	@if cmp crypto/asn1/a_octet.d.tmp crypto/asn1/a_octet.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/a_octet.d.tmp; \
+	else \
+		mv crypto/asn1/a_octet.d.tmp crypto/asn1/a_octet.d; \
+	fi
+crypto/asn1/a_print.o: crypto/asn1/a_print.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/a_print.d.tmp -MT $@ -c -o $@ crypto/asn1/a_print.c
+	@touch crypto/asn1/a_print.d.tmp
+	@if cmp crypto/asn1/a_print.d.tmp crypto/asn1/a_print.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/a_print.d.tmp; \
+	else \
+		mv crypto/asn1/a_print.d.tmp crypto/asn1/a_print.d; \
+	fi
+crypto/asn1/a_sign.o: crypto/asn1/a_sign.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/a_sign.d.tmp -MT $@ -c -o $@ crypto/asn1/a_sign.c
+	@touch crypto/asn1/a_sign.d.tmp
+	@if cmp crypto/asn1/a_sign.d.tmp crypto/asn1/a_sign.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/a_sign.d.tmp; \
+	else \
+		mv crypto/asn1/a_sign.d.tmp crypto/asn1/a_sign.d; \
+	fi
+crypto/asn1/a_strex.o: crypto/asn1/a_strex.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/a_strex.d.tmp -MT $@ -c -o $@ crypto/asn1/a_strex.c
+	@touch crypto/asn1/a_strex.d.tmp
+	@if cmp crypto/asn1/a_strex.d.tmp crypto/asn1/a_strex.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/a_strex.d.tmp; \
+	else \
+		mv crypto/asn1/a_strex.d.tmp crypto/asn1/a_strex.d; \
+	fi
+crypto/asn1/a_strnid.o: crypto/asn1/a_strnid.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/a_strnid.d.tmp -MT $@ -c -o $@ crypto/asn1/a_strnid.c
+	@touch crypto/asn1/a_strnid.d.tmp
+	@if cmp crypto/asn1/a_strnid.d.tmp crypto/asn1/a_strnid.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/a_strnid.d.tmp; \
+	else \
+		mv crypto/asn1/a_strnid.d.tmp crypto/asn1/a_strnid.d; \
+	fi
+crypto/asn1/a_time.o: crypto/asn1/a_time.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/a_time.d.tmp -MT $@ -c -o $@ crypto/asn1/a_time.c
+	@touch crypto/asn1/a_time.d.tmp
+	@if cmp crypto/asn1/a_time.d.tmp crypto/asn1/a_time.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/a_time.d.tmp; \
+	else \
+		mv crypto/asn1/a_time.d.tmp crypto/asn1/a_time.d; \
+	fi
+crypto/asn1/a_type.o: crypto/asn1/a_type.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/a_type.d.tmp -MT $@ -c -o $@ crypto/asn1/a_type.c
+	@touch crypto/asn1/a_type.d.tmp
+	@if cmp crypto/asn1/a_type.d.tmp crypto/asn1/a_type.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/a_type.d.tmp; \
+	else \
+		mv crypto/asn1/a_type.d.tmp crypto/asn1/a_type.d; \
+	fi
+crypto/asn1/a_utctm.o: crypto/asn1/a_utctm.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/a_utctm.d.tmp -MT $@ -c -o $@ crypto/asn1/a_utctm.c
+	@touch crypto/asn1/a_utctm.d.tmp
+	@if cmp crypto/asn1/a_utctm.d.tmp crypto/asn1/a_utctm.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/a_utctm.d.tmp; \
+	else \
+		mv crypto/asn1/a_utctm.d.tmp crypto/asn1/a_utctm.d; \
+	fi
+crypto/asn1/a_utf8.o: crypto/asn1/a_utf8.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/a_utf8.d.tmp -MT $@ -c -o $@ crypto/asn1/a_utf8.c
+	@touch crypto/asn1/a_utf8.d.tmp
+	@if cmp crypto/asn1/a_utf8.d.tmp crypto/asn1/a_utf8.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/a_utf8.d.tmp; \
+	else \
+		mv crypto/asn1/a_utf8.d.tmp crypto/asn1/a_utf8.d; \
+	fi
+crypto/asn1/a_verify.o: crypto/asn1/a_verify.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/a_verify.d.tmp -MT $@ -c -o $@ crypto/asn1/a_verify.c
+	@touch crypto/asn1/a_verify.d.tmp
+	@if cmp crypto/asn1/a_verify.d.tmp crypto/asn1/a_verify.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/a_verify.d.tmp; \
+	else \
+		mv crypto/asn1/a_verify.d.tmp crypto/asn1/a_verify.d; \
+	fi
+crypto/asn1/ameth_lib.o: crypto/asn1/ameth_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/ameth_lib.d.tmp -MT $@ -c -o $@ crypto/asn1/ameth_lib.c
+	@touch crypto/asn1/ameth_lib.d.tmp
+	@if cmp crypto/asn1/ameth_lib.d.tmp crypto/asn1/ameth_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/ameth_lib.d.tmp; \
+	else \
+		mv crypto/asn1/ameth_lib.d.tmp crypto/asn1/ameth_lib.d; \
+	fi
+crypto/asn1/asn1_err.o: crypto/asn1/asn1_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/asn1_err.d.tmp -MT $@ -c -o $@ crypto/asn1/asn1_err.c
+	@touch crypto/asn1/asn1_err.d.tmp
+	@if cmp crypto/asn1/asn1_err.d.tmp crypto/asn1/asn1_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/asn1_err.d.tmp; \
+	else \
+		mv crypto/asn1/asn1_err.d.tmp crypto/asn1/asn1_err.d; \
+	fi
+crypto/asn1/asn1_gen.o: crypto/asn1/asn1_gen.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/asn1_gen.d.tmp -MT $@ -c -o $@ crypto/asn1/asn1_gen.c
+	@touch crypto/asn1/asn1_gen.d.tmp
+	@if cmp crypto/asn1/asn1_gen.d.tmp crypto/asn1/asn1_gen.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/asn1_gen.d.tmp; \
+	else \
+		mv crypto/asn1/asn1_gen.d.tmp crypto/asn1/asn1_gen.d; \
+	fi
+crypto/asn1/asn1_lib.o: crypto/asn1/asn1_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/asn1_lib.d.tmp -MT $@ -c -o $@ crypto/asn1/asn1_lib.c
+	@touch crypto/asn1/asn1_lib.d.tmp
+	@if cmp crypto/asn1/asn1_lib.d.tmp crypto/asn1/asn1_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/asn1_lib.d.tmp; \
+	else \
+		mv crypto/asn1/asn1_lib.d.tmp crypto/asn1/asn1_lib.d; \
+	fi
+crypto/asn1/asn1_par.o: crypto/asn1/asn1_par.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/asn1_par.d.tmp -MT $@ -c -o $@ crypto/asn1/asn1_par.c
+	@touch crypto/asn1/asn1_par.d.tmp
+	@if cmp crypto/asn1/asn1_par.d.tmp crypto/asn1/asn1_par.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/asn1_par.d.tmp; \
+	else \
+		mv crypto/asn1/asn1_par.d.tmp crypto/asn1/asn1_par.d; \
+	fi
+crypto/asn1/asn_mime.o: crypto/asn1/asn_mime.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/asn_mime.d.tmp -MT $@ -c -o $@ crypto/asn1/asn_mime.c
+	@touch crypto/asn1/asn_mime.d.tmp
+	@if cmp crypto/asn1/asn_mime.d.tmp crypto/asn1/asn_mime.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/asn_mime.d.tmp; \
+	else \
+		mv crypto/asn1/asn_mime.d.tmp crypto/asn1/asn_mime.d; \
+	fi
+crypto/asn1/asn_moid.o: crypto/asn1/asn_moid.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/asn_moid.d.tmp -MT $@ -c -o $@ crypto/asn1/asn_moid.c
+	@touch crypto/asn1/asn_moid.d.tmp
+	@if cmp crypto/asn1/asn_moid.d.tmp crypto/asn1/asn_moid.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/asn_moid.d.tmp; \
+	else \
+		mv crypto/asn1/asn_moid.d.tmp crypto/asn1/asn_moid.d; \
+	fi
+crypto/asn1/asn_mstbl.o: crypto/asn1/asn_mstbl.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/asn_mstbl.d.tmp -MT $@ -c -o $@ crypto/asn1/asn_mstbl.c
+	@touch crypto/asn1/asn_mstbl.d.tmp
+	@if cmp crypto/asn1/asn_mstbl.d.tmp crypto/asn1/asn_mstbl.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/asn_mstbl.d.tmp; \
+	else \
+		mv crypto/asn1/asn_mstbl.d.tmp crypto/asn1/asn_mstbl.d; \
+	fi
+crypto/asn1/asn_pack.o: crypto/asn1/asn_pack.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/asn_pack.d.tmp -MT $@ -c -o $@ crypto/asn1/asn_pack.c
+	@touch crypto/asn1/asn_pack.d.tmp
+	@if cmp crypto/asn1/asn_pack.d.tmp crypto/asn1/asn_pack.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/asn_pack.d.tmp; \
+	else \
+		mv crypto/asn1/asn_pack.d.tmp crypto/asn1/asn_pack.d; \
+	fi
+crypto/asn1/bio_asn1.o: crypto/asn1/bio_asn1.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/bio_asn1.d.tmp -MT $@ -c -o $@ crypto/asn1/bio_asn1.c
+	@touch crypto/asn1/bio_asn1.d.tmp
+	@if cmp crypto/asn1/bio_asn1.d.tmp crypto/asn1/bio_asn1.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/bio_asn1.d.tmp; \
+	else \
+		mv crypto/asn1/bio_asn1.d.tmp crypto/asn1/bio_asn1.d; \
+	fi
+crypto/asn1/bio_ndef.o: crypto/asn1/bio_ndef.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/bio_ndef.d.tmp -MT $@ -c -o $@ crypto/asn1/bio_ndef.c
+	@touch crypto/asn1/bio_ndef.d.tmp
+	@if cmp crypto/asn1/bio_ndef.d.tmp crypto/asn1/bio_ndef.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/bio_ndef.d.tmp; \
+	else \
+		mv crypto/asn1/bio_ndef.d.tmp crypto/asn1/bio_ndef.d; \
+	fi
+crypto/asn1/d2i_pr.o: crypto/asn1/d2i_pr.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/d2i_pr.d.tmp -MT $@ -c -o $@ crypto/asn1/d2i_pr.c
+	@touch crypto/asn1/d2i_pr.d.tmp
+	@if cmp crypto/asn1/d2i_pr.d.tmp crypto/asn1/d2i_pr.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/d2i_pr.d.tmp; \
+	else \
+		mv crypto/asn1/d2i_pr.d.tmp crypto/asn1/d2i_pr.d; \
+	fi
+crypto/asn1/d2i_pu.o: crypto/asn1/d2i_pu.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/d2i_pu.d.tmp -MT $@ -c -o $@ crypto/asn1/d2i_pu.c
+	@touch crypto/asn1/d2i_pu.d.tmp
+	@if cmp crypto/asn1/d2i_pu.d.tmp crypto/asn1/d2i_pu.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/d2i_pu.d.tmp; \
+	else \
+		mv crypto/asn1/d2i_pu.d.tmp crypto/asn1/d2i_pu.d; \
+	fi
+crypto/asn1/evp_asn1.o: crypto/asn1/evp_asn1.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/evp_asn1.d.tmp -MT $@ -c -o $@ crypto/asn1/evp_asn1.c
+	@touch crypto/asn1/evp_asn1.d.tmp
+	@if cmp crypto/asn1/evp_asn1.d.tmp crypto/asn1/evp_asn1.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/evp_asn1.d.tmp; \
+	else \
+		mv crypto/asn1/evp_asn1.d.tmp crypto/asn1/evp_asn1.d; \
+	fi
+crypto/asn1/f_int.o: crypto/asn1/f_int.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/f_int.d.tmp -MT $@ -c -o $@ crypto/asn1/f_int.c
+	@touch crypto/asn1/f_int.d.tmp
+	@if cmp crypto/asn1/f_int.d.tmp crypto/asn1/f_int.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/f_int.d.tmp; \
+	else \
+		mv crypto/asn1/f_int.d.tmp crypto/asn1/f_int.d; \
+	fi
+crypto/asn1/f_string.o: crypto/asn1/f_string.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/f_string.d.tmp -MT $@ -c -o $@ crypto/asn1/f_string.c
+	@touch crypto/asn1/f_string.d.tmp
+	@if cmp crypto/asn1/f_string.d.tmp crypto/asn1/f_string.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/f_string.d.tmp; \
+	else \
+		mv crypto/asn1/f_string.d.tmp crypto/asn1/f_string.d; \
+	fi
+crypto/asn1/i2d_pr.o: crypto/asn1/i2d_pr.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/i2d_pr.d.tmp -MT $@ -c -o $@ crypto/asn1/i2d_pr.c
+	@touch crypto/asn1/i2d_pr.d.tmp
+	@if cmp crypto/asn1/i2d_pr.d.tmp crypto/asn1/i2d_pr.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/i2d_pr.d.tmp; \
+	else \
+		mv crypto/asn1/i2d_pr.d.tmp crypto/asn1/i2d_pr.d; \
+	fi
+crypto/asn1/i2d_pu.o: crypto/asn1/i2d_pu.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/i2d_pu.d.tmp -MT $@ -c -o $@ crypto/asn1/i2d_pu.c
+	@touch crypto/asn1/i2d_pu.d.tmp
+	@if cmp crypto/asn1/i2d_pu.d.tmp crypto/asn1/i2d_pu.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/i2d_pu.d.tmp; \
+	else \
+		mv crypto/asn1/i2d_pu.d.tmp crypto/asn1/i2d_pu.d; \
+	fi
+crypto/asn1/n_pkey.o: crypto/asn1/n_pkey.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/n_pkey.d.tmp -MT $@ -c -o $@ crypto/asn1/n_pkey.c
+	@touch crypto/asn1/n_pkey.d.tmp
+	@if cmp crypto/asn1/n_pkey.d.tmp crypto/asn1/n_pkey.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/n_pkey.d.tmp; \
+	else \
+		mv crypto/asn1/n_pkey.d.tmp crypto/asn1/n_pkey.d; \
+	fi
+crypto/asn1/nsseq.o: crypto/asn1/nsseq.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/nsseq.d.tmp -MT $@ -c -o $@ crypto/asn1/nsseq.c
+	@touch crypto/asn1/nsseq.d.tmp
+	@if cmp crypto/asn1/nsseq.d.tmp crypto/asn1/nsseq.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/nsseq.d.tmp; \
+	else \
+		mv crypto/asn1/nsseq.d.tmp crypto/asn1/nsseq.d; \
+	fi
+crypto/asn1/p5_pbe.o: crypto/asn1/p5_pbe.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/p5_pbe.d.tmp -MT $@ -c -o $@ crypto/asn1/p5_pbe.c
+	@touch crypto/asn1/p5_pbe.d.tmp
+	@if cmp crypto/asn1/p5_pbe.d.tmp crypto/asn1/p5_pbe.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/p5_pbe.d.tmp; \
+	else \
+		mv crypto/asn1/p5_pbe.d.tmp crypto/asn1/p5_pbe.d; \
+	fi
+crypto/asn1/p5_pbev2.o: crypto/asn1/p5_pbev2.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/p5_pbev2.d.tmp -MT $@ -c -o $@ crypto/asn1/p5_pbev2.c
+	@touch crypto/asn1/p5_pbev2.d.tmp
+	@if cmp crypto/asn1/p5_pbev2.d.tmp crypto/asn1/p5_pbev2.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/p5_pbev2.d.tmp; \
+	else \
+		mv crypto/asn1/p5_pbev2.d.tmp crypto/asn1/p5_pbev2.d; \
+	fi
+crypto/asn1/p5_scrypt.o: crypto/asn1/p5_scrypt.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/p5_scrypt.d.tmp -MT $@ -c -o $@ crypto/asn1/p5_scrypt.c
+	@touch crypto/asn1/p5_scrypt.d.tmp
+	@if cmp crypto/asn1/p5_scrypt.d.tmp crypto/asn1/p5_scrypt.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/p5_scrypt.d.tmp; \
+	else \
+		mv crypto/asn1/p5_scrypt.d.tmp crypto/asn1/p5_scrypt.d; \
+	fi
+crypto/asn1/p8_pkey.o: crypto/asn1/p8_pkey.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/p8_pkey.d.tmp -MT $@ -c -o $@ crypto/asn1/p8_pkey.c
+	@touch crypto/asn1/p8_pkey.d.tmp
+	@if cmp crypto/asn1/p8_pkey.d.tmp crypto/asn1/p8_pkey.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/p8_pkey.d.tmp; \
+	else \
+		mv crypto/asn1/p8_pkey.d.tmp crypto/asn1/p8_pkey.d; \
+	fi
+crypto/asn1/t_bitst.o: crypto/asn1/t_bitst.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/t_bitst.d.tmp -MT $@ -c -o $@ crypto/asn1/t_bitst.c
+	@touch crypto/asn1/t_bitst.d.tmp
+	@if cmp crypto/asn1/t_bitst.d.tmp crypto/asn1/t_bitst.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/t_bitst.d.tmp; \
+	else \
+		mv crypto/asn1/t_bitst.d.tmp crypto/asn1/t_bitst.d; \
+	fi
+crypto/asn1/t_pkey.o: crypto/asn1/t_pkey.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/t_pkey.d.tmp -MT $@ -c -o $@ crypto/asn1/t_pkey.c
+	@touch crypto/asn1/t_pkey.d.tmp
+	@if cmp crypto/asn1/t_pkey.d.tmp crypto/asn1/t_pkey.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/t_pkey.d.tmp; \
+	else \
+		mv crypto/asn1/t_pkey.d.tmp crypto/asn1/t_pkey.d; \
+	fi
+crypto/asn1/t_spki.o: crypto/asn1/t_spki.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/t_spki.d.tmp -MT $@ -c -o $@ crypto/asn1/t_spki.c
+	@touch crypto/asn1/t_spki.d.tmp
+	@if cmp crypto/asn1/t_spki.d.tmp crypto/asn1/t_spki.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/t_spki.d.tmp; \
+	else \
+		mv crypto/asn1/t_spki.d.tmp crypto/asn1/t_spki.d; \
+	fi
+crypto/asn1/tasn_dec.o: crypto/asn1/tasn_dec.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/tasn_dec.d.tmp -MT $@ -c -o $@ crypto/asn1/tasn_dec.c
+	@touch crypto/asn1/tasn_dec.d.tmp
+	@if cmp crypto/asn1/tasn_dec.d.tmp crypto/asn1/tasn_dec.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/tasn_dec.d.tmp; \
+	else \
+		mv crypto/asn1/tasn_dec.d.tmp crypto/asn1/tasn_dec.d; \
+	fi
+crypto/asn1/tasn_enc.o: crypto/asn1/tasn_enc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/tasn_enc.d.tmp -MT $@ -c -o $@ crypto/asn1/tasn_enc.c
+	@touch crypto/asn1/tasn_enc.d.tmp
+	@if cmp crypto/asn1/tasn_enc.d.tmp crypto/asn1/tasn_enc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/tasn_enc.d.tmp; \
+	else \
+		mv crypto/asn1/tasn_enc.d.tmp crypto/asn1/tasn_enc.d; \
+	fi
+crypto/asn1/tasn_fre.o: crypto/asn1/tasn_fre.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/tasn_fre.d.tmp -MT $@ -c -o $@ crypto/asn1/tasn_fre.c
+	@touch crypto/asn1/tasn_fre.d.tmp
+	@if cmp crypto/asn1/tasn_fre.d.tmp crypto/asn1/tasn_fre.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/tasn_fre.d.tmp; \
+	else \
+		mv crypto/asn1/tasn_fre.d.tmp crypto/asn1/tasn_fre.d; \
+	fi
+crypto/asn1/tasn_new.o: crypto/asn1/tasn_new.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/tasn_new.d.tmp -MT $@ -c -o $@ crypto/asn1/tasn_new.c
+	@touch crypto/asn1/tasn_new.d.tmp
+	@if cmp crypto/asn1/tasn_new.d.tmp crypto/asn1/tasn_new.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/tasn_new.d.tmp; \
+	else \
+		mv crypto/asn1/tasn_new.d.tmp crypto/asn1/tasn_new.d; \
+	fi
+crypto/asn1/tasn_prn.o: crypto/asn1/tasn_prn.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/tasn_prn.d.tmp -MT $@ -c -o $@ crypto/asn1/tasn_prn.c
+	@touch crypto/asn1/tasn_prn.d.tmp
+	@if cmp crypto/asn1/tasn_prn.d.tmp crypto/asn1/tasn_prn.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/tasn_prn.d.tmp; \
+	else \
+		mv crypto/asn1/tasn_prn.d.tmp crypto/asn1/tasn_prn.d; \
+	fi
+crypto/asn1/tasn_scn.o: crypto/asn1/tasn_scn.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/tasn_scn.d.tmp -MT $@ -c -o $@ crypto/asn1/tasn_scn.c
+	@touch crypto/asn1/tasn_scn.d.tmp
+	@if cmp crypto/asn1/tasn_scn.d.tmp crypto/asn1/tasn_scn.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/tasn_scn.d.tmp; \
+	else \
+		mv crypto/asn1/tasn_scn.d.tmp crypto/asn1/tasn_scn.d; \
+	fi
+crypto/asn1/tasn_typ.o: crypto/asn1/tasn_typ.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/tasn_typ.d.tmp -MT $@ -c -o $@ crypto/asn1/tasn_typ.c
+	@touch crypto/asn1/tasn_typ.d.tmp
+	@if cmp crypto/asn1/tasn_typ.d.tmp crypto/asn1/tasn_typ.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/tasn_typ.d.tmp; \
+	else \
+		mv crypto/asn1/tasn_typ.d.tmp crypto/asn1/tasn_typ.d; \
+	fi
+crypto/asn1/tasn_utl.o: crypto/asn1/tasn_utl.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/tasn_utl.d.tmp -MT $@ -c -o $@ crypto/asn1/tasn_utl.c
+	@touch crypto/asn1/tasn_utl.d.tmp
+	@if cmp crypto/asn1/tasn_utl.d.tmp crypto/asn1/tasn_utl.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/tasn_utl.d.tmp; \
+	else \
+		mv crypto/asn1/tasn_utl.d.tmp crypto/asn1/tasn_utl.d; \
+	fi
+crypto/asn1/x_algor.o: crypto/asn1/x_algor.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/x_algor.d.tmp -MT $@ -c -o $@ crypto/asn1/x_algor.c
+	@touch crypto/asn1/x_algor.d.tmp
+	@if cmp crypto/asn1/x_algor.d.tmp crypto/asn1/x_algor.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/x_algor.d.tmp; \
+	else \
+		mv crypto/asn1/x_algor.d.tmp crypto/asn1/x_algor.d; \
+	fi
+crypto/asn1/x_bignum.o: crypto/asn1/x_bignum.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/x_bignum.d.tmp -MT $@ -c -o $@ crypto/asn1/x_bignum.c
+	@touch crypto/asn1/x_bignum.d.tmp
+	@if cmp crypto/asn1/x_bignum.d.tmp crypto/asn1/x_bignum.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/x_bignum.d.tmp; \
+	else \
+		mv crypto/asn1/x_bignum.d.tmp crypto/asn1/x_bignum.d; \
+	fi
+crypto/asn1/x_info.o: crypto/asn1/x_info.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/x_info.d.tmp -MT $@ -c -o $@ crypto/asn1/x_info.c
+	@touch crypto/asn1/x_info.d.tmp
+	@if cmp crypto/asn1/x_info.d.tmp crypto/asn1/x_info.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/x_info.d.tmp; \
+	else \
+		mv crypto/asn1/x_info.d.tmp crypto/asn1/x_info.d; \
+	fi
+crypto/asn1/x_long.o: crypto/asn1/x_long.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/x_long.d.tmp -MT $@ -c -o $@ crypto/asn1/x_long.c
+	@touch crypto/asn1/x_long.d.tmp
+	@if cmp crypto/asn1/x_long.d.tmp crypto/asn1/x_long.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/x_long.d.tmp; \
+	else \
+		mv crypto/asn1/x_long.d.tmp crypto/asn1/x_long.d; \
+	fi
+crypto/asn1/x_pkey.o: crypto/asn1/x_pkey.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/x_pkey.d.tmp -MT $@ -c -o $@ crypto/asn1/x_pkey.c
+	@touch crypto/asn1/x_pkey.d.tmp
+	@if cmp crypto/asn1/x_pkey.d.tmp crypto/asn1/x_pkey.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/x_pkey.d.tmp; \
+	else \
+		mv crypto/asn1/x_pkey.d.tmp crypto/asn1/x_pkey.d; \
+	fi
+crypto/asn1/x_sig.o: crypto/asn1/x_sig.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/x_sig.d.tmp -MT $@ -c -o $@ crypto/asn1/x_sig.c
+	@touch crypto/asn1/x_sig.d.tmp
+	@if cmp crypto/asn1/x_sig.d.tmp crypto/asn1/x_sig.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/x_sig.d.tmp; \
+	else \
+		mv crypto/asn1/x_sig.d.tmp crypto/asn1/x_sig.d; \
+	fi
+crypto/asn1/x_spki.o: crypto/asn1/x_spki.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/x_spki.d.tmp -MT $@ -c -o $@ crypto/asn1/x_spki.c
+	@touch crypto/asn1/x_spki.d.tmp
+	@if cmp crypto/asn1/x_spki.d.tmp crypto/asn1/x_spki.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/x_spki.d.tmp; \
+	else \
+		mv crypto/asn1/x_spki.d.tmp crypto/asn1/x_spki.d; \
+	fi
+crypto/asn1/x_val.o: crypto/asn1/x_val.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/asn1/x_val.d.tmp -MT $@ -c -o $@ crypto/asn1/x_val.c
+	@touch crypto/asn1/x_val.d.tmp
+	@if cmp crypto/asn1/x_val.d.tmp crypto/asn1/x_val.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/asn1/x_val.d.tmp; \
+	else \
+		mv crypto/asn1/x_val.d.tmp crypto/asn1/x_val.d; \
+	fi
+crypto/async/arch/async_null.o: crypto/async/arch/async_null.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/async/arch/async_null.d.tmp -MT $@ -c -o $@ crypto/async/arch/async_null.c
+	@touch crypto/async/arch/async_null.d.tmp
+	@if cmp crypto/async/arch/async_null.d.tmp crypto/async/arch/async_null.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/async/arch/async_null.d.tmp; \
+	else \
+		mv crypto/async/arch/async_null.d.tmp crypto/async/arch/async_null.d; \
+	fi
+crypto/async/arch/async_posix.o: crypto/async/arch/async_posix.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/async/arch/async_posix.d.tmp -MT $@ -c -o $@ crypto/async/arch/async_posix.c
+	@touch crypto/async/arch/async_posix.d.tmp
+	@if cmp crypto/async/arch/async_posix.d.tmp crypto/async/arch/async_posix.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/async/arch/async_posix.d.tmp; \
+	else \
+		mv crypto/async/arch/async_posix.d.tmp crypto/async/arch/async_posix.d; \
+	fi
+crypto/async/arch/async_win.o: crypto/async/arch/async_win.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/async/arch/async_win.d.tmp -MT $@ -c -o $@ crypto/async/arch/async_win.c
+	@touch crypto/async/arch/async_win.d.tmp
+	@if cmp crypto/async/arch/async_win.d.tmp crypto/async/arch/async_win.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/async/arch/async_win.d.tmp; \
+	else \
+		mv crypto/async/arch/async_win.d.tmp crypto/async/arch/async_win.d; \
+	fi
+crypto/async/async.o: crypto/async/async.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/async/async.d.tmp -MT $@ -c -o $@ crypto/async/async.c
+	@touch crypto/async/async.d.tmp
+	@if cmp crypto/async/async.d.tmp crypto/async/async.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/async/async.d.tmp; \
+	else \
+		mv crypto/async/async.d.tmp crypto/async/async.d; \
+	fi
+crypto/async/async_err.o: crypto/async/async_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/async/async_err.d.tmp -MT $@ -c -o $@ crypto/async/async_err.c
+	@touch crypto/async/async_err.d.tmp
+	@if cmp crypto/async/async_err.d.tmp crypto/async/async_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/async/async_err.d.tmp; \
+	else \
+		mv crypto/async/async_err.d.tmp crypto/async/async_err.d; \
+	fi
+crypto/async/async_wait.o: crypto/async/async_wait.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/async/async_wait.d.tmp -MT $@ -c -o $@ crypto/async/async_wait.c
+	@touch crypto/async/async_wait.d.tmp
+	@if cmp crypto/async/async_wait.d.tmp crypto/async/async_wait.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/async/async_wait.d.tmp; \
+	else \
+		mv crypto/async/async_wait.d.tmp crypto/async/async_wait.d; \
+	fi
+crypto/bf/bf_cfb64.o: crypto/bf/bf_cfb64.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bf/bf_cfb64.d.tmp -MT $@ -c -o $@ crypto/bf/bf_cfb64.c
+	@touch crypto/bf/bf_cfb64.d.tmp
+	@if cmp crypto/bf/bf_cfb64.d.tmp crypto/bf/bf_cfb64.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bf/bf_cfb64.d.tmp; \
+	else \
+		mv crypto/bf/bf_cfb64.d.tmp crypto/bf/bf_cfb64.d; \
+	fi
+crypto/bf/bf_ecb.o: crypto/bf/bf_ecb.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bf/bf_ecb.d.tmp -MT $@ -c -o $@ crypto/bf/bf_ecb.c
+	@touch crypto/bf/bf_ecb.d.tmp
+	@if cmp crypto/bf/bf_ecb.d.tmp crypto/bf/bf_ecb.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bf/bf_ecb.d.tmp; \
+	else \
+		mv crypto/bf/bf_ecb.d.tmp crypto/bf/bf_ecb.d; \
+	fi
+crypto/bf/bf_enc.o: crypto/bf/bf_enc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bf/bf_enc.d.tmp -MT $@ -c -o $@ crypto/bf/bf_enc.c
+	@touch crypto/bf/bf_enc.d.tmp
+	@if cmp crypto/bf/bf_enc.d.tmp crypto/bf/bf_enc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bf/bf_enc.d.tmp; \
+	else \
+		mv crypto/bf/bf_enc.d.tmp crypto/bf/bf_enc.d; \
+	fi
+crypto/bf/bf_ofb64.o: crypto/bf/bf_ofb64.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bf/bf_ofb64.d.tmp -MT $@ -c -o $@ crypto/bf/bf_ofb64.c
+	@touch crypto/bf/bf_ofb64.d.tmp
+	@if cmp crypto/bf/bf_ofb64.d.tmp crypto/bf/bf_ofb64.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bf/bf_ofb64.d.tmp; \
+	else \
+		mv crypto/bf/bf_ofb64.d.tmp crypto/bf/bf_ofb64.d; \
+	fi
+crypto/bf/bf_skey.o: crypto/bf/bf_skey.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bf/bf_skey.d.tmp -MT $@ -c -o $@ crypto/bf/bf_skey.c
+	@touch crypto/bf/bf_skey.d.tmp
+	@if cmp crypto/bf/bf_skey.d.tmp crypto/bf/bf_skey.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bf/bf_skey.d.tmp; \
+	else \
+		mv crypto/bf/bf_skey.d.tmp crypto/bf/bf_skey.d; \
+	fi
+crypto/bio/b_addr.o: crypto/bio/b_addr.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/b_addr.d.tmp -MT $@ -c -o $@ crypto/bio/b_addr.c
+	@touch crypto/bio/b_addr.d.tmp
+	@if cmp crypto/bio/b_addr.d.tmp crypto/bio/b_addr.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/b_addr.d.tmp; \
+	else \
+		mv crypto/bio/b_addr.d.tmp crypto/bio/b_addr.d; \
+	fi
+crypto/bio/b_dump.o: crypto/bio/b_dump.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/b_dump.d.tmp -MT $@ -c -o $@ crypto/bio/b_dump.c
+	@touch crypto/bio/b_dump.d.tmp
+	@if cmp crypto/bio/b_dump.d.tmp crypto/bio/b_dump.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/b_dump.d.tmp; \
+	else \
+		mv crypto/bio/b_dump.d.tmp crypto/bio/b_dump.d; \
+	fi
+crypto/bio/b_print.o: crypto/bio/b_print.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/b_print.d.tmp -MT $@ -c -o $@ crypto/bio/b_print.c
+	@touch crypto/bio/b_print.d.tmp
+	@if cmp crypto/bio/b_print.d.tmp crypto/bio/b_print.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/b_print.d.tmp; \
+	else \
+		mv crypto/bio/b_print.d.tmp crypto/bio/b_print.d; \
+	fi
+crypto/bio/b_sock.o: crypto/bio/b_sock.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/b_sock.d.tmp -MT $@ -c -o $@ crypto/bio/b_sock.c
+	@touch crypto/bio/b_sock.d.tmp
+	@if cmp crypto/bio/b_sock.d.tmp crypto/bio/b_sock.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/b_sock.d.tmp; \
+	else \
+		mv crypto/bio/b_sock.d.tmp crypto/bio/b_sock.d; \
+	fi
+crypto/bio/b_sock2.o: crypto/bio/b_sock2.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/b_sock2.d.tmp -MT $@ -c -o $@ crypto/bio/b_sock2.c
+	@touch crypto/bio/b_sock2.d.tmp
+	@if cmp crypto/bio/b_sock2.d.tmp crypto/bio/b_sock2.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/b_sock2.d.tmp; \
+	else \
+		mv crypto/bio/b_sock2.d.tmp crypto/bio/b_sock2.d; \
+	fi
+crypto/bio/bf_buff.o: crypto/bio/bf_buff.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/bf_buff.d.tmp -MT $@ -c -o $@ crypto/bio/bf_buff.c
+	@touch crypto/bio/bf_buff.d.tmp
+	@if cmp crypto/bio/bf_buff.d.tmp crypto/bio/bf_buff.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/bf_buff.d.tmp; \
+	else \
+		mv crypto/bio/bf_buff.d.tmp crypto/bio/bf_buff.d; \
+	fi
+crypto/bio/bf_lbuf.o: crypto/bio/bf_lbuf.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/bf_lbuf.d.tmp -MT $@ -c -o $@ crypto/bio/bf_lbuf.c
+	@touch crypto/bio/bf_lbuf.d.tmp
+	@if cmp crypto/bio/bf_lbuf.d.tmp crypto/bio/bf_lbuf.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/bf_lbuf.d.tmp; \
+	else \
+		mv crypto/bio/bf_lbuf.d.tmp crypto/bio/bf_lbuf.d; \
+	fi
+crypto/bio/bf_nbio.o: crypto/bio/bf_nbio.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/bf_nbio.d.tmp -MT $@ -c -o $@ crypto/bio/bf_nbio.c
+	@touch crypto/bio/bf_nbio.d.tmp
+	@if cmp crypto/bio/bf_nbio.d.tmp crypto/bio/bf_nbio.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/bf_nbio.d.tmp; \
+	else \
+		mv crypto/bio/bf_nbio.d.tmp crypto/bio/bf_nbio.d; \
+	fi
+crypto/bio/bf_null.o: crypto/bio/bf_null.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/bf_null.d.tmp -MT $@ -c -o $@ crypto/bio/bf_null.c
+	@touch crypto/bio/bf_null.d.tmp
+	@if cmp crypto/bio/bf_null.d.tmp crypto/bio/bf_null.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/bf_null.d.tmp; \
+	else \
+		mv crypto/bio/bf_null.d.tmp crypto/bio/bf_null.d; \
+	fi
+crypto/bio/bio_cb.o: crypto/bio/bio_cb.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/bio_cb.d.tmp -MT $@ -c -o $@ crypto/bio/bio_cb.c
+	@touch crypto/bio/bio_cb.d.tmp
+	@if cmp crypto/bio/bio_cb.d.tmp crypto/bio/bio_cb.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/bio_cb.d.tmp; \
+	else \
+		mv crypto/bio/bio_cb.d.tmp crypto/bio/bio_cb.d; \
+	fi
+crypto/bio/bio_err.o: crypto/bio/bio_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/bio_err.d.tmp -MT $@ -c -o $@ crypto/bio/bio_err.c
+	@touch crypto/bio/bio_err.d.tmp
+	@if cmp crypto/bio/bio_err.d.tmp crypto/bio/bio_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/bio_err.d.tmp; \
+	else \
+		mv crypto/bio/bio_err.d.tmp crypto/bio/bio_err.d; \
+	fi
+crypto/bio/bio_lib.o: crypto/bio/bio_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/bio_lib.d.tmp -MT $@ -c -o $@ crypto/bio/bio_lib.c
+	@touch crypto/bio/bio_lib.d.tmp
+	@if cmp crypto/bio/bio_lib.d.tmp crypto/bio/bio_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/bio_lib.d.tmp; \
+	else \
+		mv crypto/bio/bio_lib.d.tmp crypto/bio/bio_lib.d; \
+	fi
+crypto/bio/bio_meth.o: crypto/bio/bio_meth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/bio_meth.d.tmp -MT $@ -c -o $@ crypto/bio/bio_meth.c
+	@touch crypto/bio/bio_meth.d.tmp
+	@if cmp crypto/bio/bio_meth.d.tmp crypto/bio/bio_meth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/bio_meth.d.tmp; \
+	else \
+		mv crypto/bio/bio_meth.d.tmp crypto/bio/bio_meth.d; \
+	fi
+crypto/bio/bss_acpt.o: crypto/bio/bss_acpt.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/bss_acpt.d.tmp -MT $@ -c -o $@ crypto/bio/bss_acpt.c
+	@touch crypto/bio/bss_acpt.d.tmp
+	@if cmp crypto/bio/bss_acpt.d.tmp crypto/bio/bss_acpt.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/bss_acpt.d.tmp; \
+	else \
+		mv crypto/bio/bss_acpt.d.tmp crypto/bio/bss_acpt.d; \
+	fi
+crypto/bio/bss_bio.o: crypto/bio/bss_bio.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/bss_bio.d.tmp -MT $@ -c -o $@ crypto/bio/bss_bio.c
+	@touch crypto/bio/bss_bio.d.tmp
+	@if cmp crypto/bio/bss_bio.d.tmp crypto/bio/bss_bio.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/bss_bio.d.tmp; \
+	else \
+		mv crypto/bio/bss_bio.d.tmp crypto/bio/bss_bio.d; \
+	fi
+crypto/bio/bss_conn.o: crypto/bio/bss_conn.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/bss_conn.d.tmp -MT $@ -c -o $@ crypto/bio/bss_conn.c
+	@touch crypto/bio/bss_conn.d.tmp
+	@if cmp crypto/bio/bss_conn.d.tmp crypto/bio/bss_conn.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/bss_conn.d.tmp; \
+	else \
+		mv crypto/bio/bss_conn.d.tmp crypto/bio/bss_conn.d; \
+	fi
+crypto/bio/bss_dgram.o: crypto/bio/bss_dgram.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/bss_dgram.d.tmp -MT $@ -c -o $@ crypto/bio/bss_dgram.c
+	@touch crypto/bio/bss_dgram.d.tmp
+	@if cmp crypto/bio/bss_dgram.d.tmp crypto/bio/bss_dgram.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/bss_dgram.d.tmp; \
+	else \
+		mv crypto/bio/bss_dgram.d.tmp crypto/bio/bss_dgram.d; \
+	fi
+crypto/bio/bss_fd.o: crypto/bio/bss_fd.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/bss_fd.d.tmp -MT $@ -c -o $@ crypto/bio/bss_fd.c
+	@touch crypto/bio/bss_fd.d.tmp
+	@if cmp crypto/bio/bss_fd.d.tmp crypto/bio/bss_fd.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/bss_fd.d.tmp; \
+	else \
+		mv crypto/bio/bss_fd.d.tmp crypto/bio/bss_fd.d; \
+	fi
+crypto/bio/bss_file.o: crypto/bio/bss_file.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/bss_file.d.tmp -MT $@ -c -o $@ crypto/bio/bss_file.c
+	@touch crypto/bio/bss_file.d.tmp
+	@if cmp crypto/bio/bss_file.d.tmp crypto/bio/bss_file.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/bss_file.d.tmp; \
+	else \
+		mv crypto/bio/bss_file.d.tmp crypto/bio/bss_file.d; \
+	fi
+crypto/bio/bss_log.o: crypto/bio/bss_log.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/bss_log.d.tmp -MT $@ -c -o $@ crypto/bio/bss_log.c
+	@touch crypto/bio/bss_log.d.tmp
+	@if cmp crypto/bio/bss_log.d.tmp crypto/bio/bss_log.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/bss_log.d.tmp; \
+	else \
+		mv crypto/bio/bss_log.d.tmp crypto/bio/bss_log.d; \
+	fi
+crypto/bio/bss_mem.o: crypto/bio/bss_mem.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/bss_mem.d.tmp -MT $@ -c -o $@ crypto/bio/bss_mem.c
+	@touch crypto/bio/bss_mem.d.tmp
+	@if cmp crypto/bio/bss_mem.d.tmp crypto/bio/bss_mem.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/bss_mem.d.tmp; \
+	else \
+		mv crypto/bio/bss_mem.d.tmp crypto/bio/bss_mem.d; \
+	fi
+crypto/bio/bss_null.o: crypto/bio/bss_null.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/bss_null.d.tmp -MT $@ -c -o $@ crypto/bio/bss_null.c
+	@touch crypto/bio/bss_null.d.tmp
+	@if cmp crypto/bio/bss_null.d.tmp crypto/bio/bss_null.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/bss_null.d.tmp; \
+	else \
+		mv crypto/bio/bss_null.d.tmp crypto/bio/bss_null.d; \
+	fi
+crypto/bio/bss_sock.o: crypto/bio/bss_sock.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bio/bss_sock.d.tmp -MT $@ -c -o $@ crypto/bio/bss_sock.c
+	@touch crypto/bio/bss_sock.d.tmp
+	@if cmp crypto/bio/bss_sock.d.tmp crypto/bio/bss_sock.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bio/bss_sock.d.tmp; \
+	else \
+		mv crypto/bio/bss_sock.d.tmp crypto/bio/bss_sock.d; \
+	fi
+crypto/blake2/blake2b.o: crypto/blake2/blake2b.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/blake2/blake2b.d.tmp -MT $@ -c -o $@ crypto/blake2/blake2b.c
+	@touch crypto/blake2/blake2b.d.tmp
+	@if cmp crypto/blake2/blake2b.d.tmp crypto/blake2/blake2b.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/blake2/blake2b.d.tmp; \
+	else \
+		mv crypto/blake2/blake2b.d.tmp crypto/blake2/blake2b.d; \
+	fi
+crypto/blake2/blake2s.o: crypto/blake2/blake2s.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/blake2/blake2s.d.tmp -MT $@ -c -o $@ crypto/blake2/blake2s.c
+	@touch crypto/blake2/blake2s.d.tmp
+	@if cmp crypto/blake2/blake2s.d.tmp crypto/blake2/blake2s.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/blake2/blake2s.d.tmp; \
+	else \
+		mv crypto/blake2/blake2s.d.tmp crypto/blake2/blake2s.d; \
+	fi
+crypto/blake2/m_blake2b.o: crypto/blake2/m_blake2b.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/blake2/m_blake2b.d.tmp -MT $@ -c -o $@ crypto/blake2/m_blake2b.c
+	@touch crypto/blake2/m_blake2b.d.tmp
+	@if cmp crypto/blake2/m_blake2b.d.tmp crypto/blake2/m_blake2b.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/blake2/m_blake2b.d.tmp; \
+	else \
+		mv crypto/blake2/m_blake2b.d.tmp crypto/blake2/m_blake2b.d; \
+	fi
+crypto/blake2/m_blake2s.o: crypto/blake2/m_blake2s.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/blake2/m_blake2s.d.tmp -MT $@ -c -o $@ crypto/blake2/m_blake2s.c
+	@touch crypto/blake2/m_blake2s.d.tmp
+	@if cmp crypto/blake2/m_blake2s.d.tmp crypto/blake2/m_blake2s.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/blake2/m_blake2s.d.tmp; \
+	else \
+		mv crypto/blake2/m_blake2s.d.tmp crypto/blake2/m_blake2s.d; \
+	fi
+crypto/bn/bn_add.o: crypto/bn/bn_add.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_add.d.tmp -MT $@ -c -o $@ crypto/bn/bn_add.c
+	@touch crypto/bn/bn_add.d.tmp
+	@if cmp crypto/bn/bn_add.d.tmp crypto/bn/bn_add.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_add.d.tmp; \
+	else \
+		mv crypto/bn/bn_add.d.tmp crypto/bn/bn_add.d; \
+	fi
+crypto/bn/bn_asm.o: crypto/bn/bn_asm.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_asm.d.tmp -MT $@ -c -o $@ crypto/bn/bn_asm.c
+	@touch crypto/bn/bn_asm.d.tmp
+	@if cmp crypto/bn/bn_asm.d.tmp crypto/bn/bn_asm.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_asm.d.tmp; \
+	else \
+		mv crypto/bn/bn_asm.d.tmp crypto/bn/bn_asm.d; \
+	fi
+crypto/bn/bn_blind.o: crypto/bn/bn_blind.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_blind.d.tmp -MT $@ -c -o $@ crypto/bn/bn_blind.c
+	@touch crypto/bn/bn_blind.d.tmp
+	@if cmp crypto/bn/bn_blind.d.tmp crypto/bn/bn_blind.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_blind.d.tmp; \
+	else \
+		mv crypto/bn/bn_blind.d.tmp crypto/bn/bn_blind.d; \
+	fi
+crypto/bn/bn_const.o: crypto/bn/bn_const.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_const.d.tmp -MT $@ -c -o $@ crypto/bn/bn_const.c
+	@touch crypto/bn/bn_const.d.tmp
+	@if cmp crypto/bn/bn_const.d.tmp crypto/bn/bn_const.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_const.d.tmp; \
+	else \
+		mv crypto/bn/bn_const.d.tmp crypto/bn/bn_const.d; \
+	fi
+crypto/bn/bn_ctx.o: crypto/bn/bn_ctx.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_ctx.d.tmp -MT $@ -c -o $@ crypto/bn/bn_ctx.c
+	@touch crypto/bn/bn_ctx.d.tmp
+	@if cmp crypto/bn/bn_ctx.d.tmp crypto/bn/bn_ctx.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_ctx.d.tmp; \
+	else \
+		mv crypto/bn/bn_ctx.d.tmp crypto/bn/bn_ctx.d; \
+	fi
+crypto/bn/bn_depr.o: crypto/bn/bn_depr.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_depr.d.tmp -MT $@ -c -o $@ crypto/bn/bn_depr.c
+	@touch crypto/bn/bn_depr.d.tmp
+	@if cmp crypto/bn/bn_depr.d.tmp crypto/bn/bn_depr.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_depr.d.tmp; \
+	else \
+		mv crypto/bn/bn_depr.d.tmp crypto/bn/bn_depr.d; \
+	fi
+crypto/bn/bn_dh.o: crypto/bn/bn_dh.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_dh.d.tmp -MT $@ -c -o $@ crypto/bn/bn_dh.c
+	@touch crypto/bn/bn_dh.d.tmp
+	@if cmp crypto/bn/bn_dh.d.tmp crypto/bn/bn_dh.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_dh.d.tmp; \
+	else \
+		mv crypto/bn/bn_dh.d.tmp crypto/bn/bn_dh.d; \
+	fi
+crypto/bn/bn_div.o: crypto/bn/bn_div.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_div.d.tmp -MT $@ -c -o $@ crypto/bn/bn_div.c
+	@touch crypto/bn/bn_div.d.tmp
+	@if cmp crypto/bn/bn_div.d.tmp crypto/bn/bn_div.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_div.d.tmp; \
+	else \
+		mv crypto/bn/bn_div.d.tmp crypto/bn/bn_div.d; \
+	fi
+crypto/bn/bn_err.o: crypto/bn/bn_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_err.d.tmp -MT $@ -c -o $@ crypto/bn/bn_err.c
+	@touch crypto/bn/bn_err.d.tmp
+	@if cmp crypto/bn/bn_err.d.tmp crypto/bn/bn_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_err.d.tmp; \
+	else \
+		mv crypto/bn/bn_err.d.tmp crypto/bn/bn_err.d; \
+	fi
+crypto/bn/bn_exp.o: crypto/bn/bn_exp.c
+	$(CC)  -I. -Icrypto/include -Iinclude -Icrypto $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_exp.d.tmp -MT $@ -c -o $@ crypto/bn/bn_exp.c
+	@touch crypto/bn/bn_exp.d.tmp
+	@if cmp crypto/bn/bn_exp.d.tmp crypto/bn/bn_exp.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_exp.d.tmp; \
+	else \
+		mv crypto/bn/bn_exp.d.tmp crypto/bn/bn_exp.d; \
+	fi
+crypto/bn/bn_exp2.o: crypto/bn/bn_exp2.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_exp2.d.tmp -MT $@ -c -o $@ crypto/bn/bn_exp2.c
+	@touch crypto/bn/bn_exp2.d.tmp
+	@if cmp crypto/bn/bn_exp2.d.tmp crypto/bn/bn_exp2.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_exp2.d.tmp; \
+	else \
+		mv crypto/bn/bn_exp2.d.tmp crypto/bn/bn_exp2.d; \
+	fi
+crypto/bn/bn_gcd.o: crypto/bn/bn_gcd.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_gcd.d.tmp -MT $@ -c -o $@ crypto/bn/bn_gcd.c
+	@touch crypto/bn/bn_gcd.d.tmp
+	@if cmp crypto/bn/bn_gcd.d.tmp crypto/bn/bn_gcd.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_gcd.d.tmp; \
+	else \
+		mv crypto/bn/bn_gcd.d.tmp crypto/bn/bn_gcd.d; \
+	fi
+crypto/bn/bn_gf2m.o: crypto/bn/bn_gf2m.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_gf2m.d.tmp -MT $@ -c -o $@ crypto/bn/bn_gf2m.c
+	@touch crypto/bn/bn_gf2m.d.tmp
+	@if cmp crypto/bn/bn_gf2m.d.tmp crypto/bn/bn_gf2m.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_gf2m.d.tmp; \
+	else \
+		mv crypto/bn/bn_gf2m.d.tmp crypto/bn/bn_gf2m.d; \
+	fi
+crypto/bn/bn_intern.o: crypto/bn/bn_intern.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_intern.d.tmp -MT $@ -c -o $@ crypto/bn/bn_intern.c
+	@touch crypto/bn/bn_intern.d.tmp
+	@if cmp crypto/bn/bn_intern.d.tmp crypto/bn/bn_intern.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_intern.d.tmp; \
+	else \
+		mv crypto/bn/bn_intern.d.tmp crypto/bn/bn_intern.d; \
+	fi
+crypto/bn/bn_kron.o: crypto/bn/bn_kron.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_kron.d.tmp -MT $@ -c -o $@ crypto/bn/bn_kron.c
+	@touch crypto/bn/bn_kron.d.tmp
+	@if cmp crypto/bn/bn_kron.d.tmp crypto/bn/bn_kron.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_kron.d.tmp; \
+	else \
+		mv crypto/bn/bn_kron.d.tmp crypto/bn/bn_kron.d; \
+	fi
+crypto/bn/bn_lib.o: crypto/bn/bn_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_lib.d.tmp -MT $@ -c -o $@ crypto/bn/bn_lib.c
+	@touch crypto/bn/bn_lib.d.tmp
+	@if cmp crypto/bn/bn_lib.d.tmp crypto/bn/bn_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_lib.d.tmp; \
+	else \
+		mv crypto/bn/bn_lib.d.tmp crypto/bn/bn_lib.d; \
+	fi
+crypto/bn/bn_mod.o: crypto/bn/bn_mod.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_mod.d.tmp -MT $@ -c -o $@ crypto/bn/bn_mod.c
+	@touch crypto/bn/bn_mod.d.tmp
+	@if cmp crypto/bn/bn_mod.d.tmp crypto/bn/bn_mod.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_mod.d.tmp; \
+	else \
+		mv crypto/bn/bn_mod.d.tmp crypto/bn/bn_mod.d; \
+	fi
+crypto/bn/bn_mont.o: crypto/bn/bn_mont.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_mont.d.tmp -MT $@ -c -o $@ crypto/bn/bn_mont.c
+	@touch crypto/bn/bn_mont.d.tmp
+	@if cmp crypto/bn/bn_mont.d.tmp crypto/bn/bn_mont.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_mont.d.tmp; \
+	else \
+		mv crypto/bn/bn_mont.d.tmp crypto/bn/bn_mont.d; \
+	fi
+crypto/bn/bn_mpi.o: crypto/bn/bn_mpi.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_mpi.d.tmp -MT $@ -c -o $@ crypto/bn/bn_mpi.c
+	@touch crypto/bn/bn_mpi.d.tmp
+	@if cmp crypto/bn/bn_mpi.d.tmp crypto/bn/bn_mpi.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_mpi.d.tmp; \
+	else \
+		mv crypto/bn/bn_mpi.d.tmp crypto/bn/bn_mpi.d; \
+	fi
+crypto/bn/bn_mul.o: crypto/bn/bn_mul.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_mul.d.tmp -MT $@ -c -o $@ crypto/bn/bn_mul.c
+	@touch crypto/bn/bn_mul.d.tmp
+	@if cmp crypto/bn/bn_mul.d.tmp crypto/bn/bn_mul.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_mul.d.tmp; \
+	else \
+		mv crypto/bn/bn_mul.d.tmp crypto/bn/bn_mul.d; \
+	fi
+crypto/bn/bn_nist.o: crypto/bn/bn_nist.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_nist.d.tmp -MT $@ -c -o $@ crypto/bn/bn_nist.c
+	@touch crypto/bn/bn_nist.d.tmp
+	@if cmp crypto/bn/bn_nist.d.tmp crypto/bn/bn_nist.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_nist.d.tmp; \
+	else \
+		mv crypto/bn/bn_nist.d.tmp crypto/bn/bn_nist.d; \
+	fi
+crypto/bn/bn_prime.o: crypto/bn/bn_prime.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_prime.d.tmp -MT $@ -c -o $@ crypto/bn/bn_prime.c
+	@touch crypto/bn/bn_prime.d.tmp
+	@if cmp crypto/bn/bn_prime.d.tmp crypto/bn/bn_prime.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_prime.d.tmp; \
+	else \
+		mv crypto/bn/bn_prime.d.tmp crypto/bn/bn_prime.d; \
+	fi
+crypto/bn/bn_print.o: crypto/bn/bn_print.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_print.d.tmp -MT $@ -c -o $@ crypto/bn/bn_print.c
+	@touch crypto/bn/bn_print.d.tmp
+	@if cmp crypto/bn/bn_print.d.tmp crypto/bn/bn_print.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_print.d.tmp; \
+	else \
+		mv crypto/bn/bn_print.d.tmp crypto/bn/bn_print.d; \
+	fi
+crypto/bn/bn_rand.o: crypto/bn/bn_rand.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_rand.d.tmp -MT $@ -c -o $@ crypto/bn/bn_rand.c
+	@touch crypto/bn/bn_rand.d.tmp
+	@if cmp crypto/bn/bn_rand.d.tmp crypto/bn/bn_rand.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_rand.d.tmp; \
+	else \
+		mv crypto/bn/bn_rand.d.tmp crypto/bn/bn_rand.d; \
+	fi
+crypto/bn/bn_recp.o: crypto/bn/bn_recp.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_recp.d.tmp -MT $@ -c -o $@ crypto/bn/bn_recp.c
+	@touch crypto/bn/bn_recp.d.tmp
+	@if cmp crypto/bn/bn_recp.d.tmp crypto/bn/bn_recp.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_recp.d.tmp; \
+	else \
+		mv crypto/bn/bn_recp.d.tmp crypto/bn/bn_recp.d; \
+	fi
+crypto/bn/bn_shift.o: crypto/bn/bn_shift.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_shift.d.tmp -MT $@ -c -o $@ crypto/bn/bn_shift.c
+	@touch crypto/bn/bn_shift.d.tmp
+	@if cmp crypto/bn/bn_shift.d.tmp crypto/bn/bn_shift.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_shift.d.tmp; \
+	else \
+		mv crypto/bn/bn_shift.d.tmp crypto/bn/bn_shift.d; \
+	fi
+crypto/bn/bn_sqr.o: crypto/bn/bn_sqr.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_sqr.d.tmp -MT $@ -c -o $@ crypto/bn/bn_sqr.c
+	@touch crypto/bn/bn_sqr.d.tmp
+	@if cmp crypto/bn/bn_sqr.d.tmp crypto/bn/bn_sqr.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_sqr.d.tmp; \
+	else \
+		mv crypto/bn/bn_sqr.d.tmp crypto/bn/bn_sqr.d; \
+	fi
+crypto/bn/bn_sqrt.o: crypto/bn/bn_sqrt.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_sqrt.d.tmp -MT $@ -c -o $@ crypto/bn/bn_sqrt.c
+	@touch crypto/bn/bn_sqrt.d.tmp
+	@if cmp crypto/bn/bn_sqrt.d.tmp crypto/bn/bn_sqrt.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_sqrt.d.tmp; \
+	else \
+		mv crypto/bn/bn_sqrt.d.tmp crypto/bn/bn_sqrt.d; \
+	fi
+crypto/bn/bn_srp.o: crypto/bn/bn_srp.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_srp.d.tmp -MT $@ -c -o $@ crypto/bn/bn_srp.c
+	@touch crypto/bn/bn_srp.d.tmp
+	@if cmp crypto/bn/bn_srp.d.tmp crypto/bn/bn_srp.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_srp.d.tmp; \
+	else \
+		mv crypto/bn/bn_srp.d.tmp crypto/bn/bn_srp.d; \
+	fi
+crypto/bn/bn_word.o: crypto/bn/bn_word.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_word.d.tmp -MT $@ -c -o $@ crypto/bn/bn_word.c
+	@touch crypto/bn/bn_word.d.tmp
+	@if cmp crypto/bn/bn_word.d.tmp crypto/bn/bn_word.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_word.d.tmp; \
+	else \
+		mv crypto/bn/bn_word.d.tmp crypto/bn/bn_word.d; \
+	fi
+crypto/bn/bn_x931p.o: crypto/bn/bn_x931p.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/bn/bn_x931p.d.tmp -MT $@ -c -o $@ crypto/bn/bn_x931p.c
+	@touch crypto/bn/bn_x931p.d.tmp
+	@if cmp crypto/bn/bn_x931p.d.tmp crypto/bn/bn_x931p.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/bn/bn_x931p.d.tmp; \
+	else \
+		mv crypto/bn/bn_x931p.d.tmp crypto/bn/bn_x931p.d; \
+	fi
+crypto/buffer/buf_err.o: crypto/buffer/buf_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/buffer/buf_err.d.tmp -MT $@ -c -o $@ crypto/buffer/buf_err.c
+	@touch crypto/buffer/buf_err.d.tmp
+	@if cmp crypto/buffer/buf_err.d.tmp crypto/buffer/buf_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/buffer/buf_err.d.tmp; \
+	else \
+		mv crypto/buffer/buf_err.d.tmp crypto/buffer/buf_err.d; \
+	fi
+crypto/buffer/buffer.o: crypto/buffer/buffer.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/buffer/buffer.d.tmp -MT $@ -c -o $@ crypto/buffer/buffer.c
+	@touch crypto/buffer/buffer.d.tmp
+	@if cmp crypto/buffer/buffer.d.tmp crypto/buffer/buffer.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/buffer/buffer.d.tmp; \
+	else \
+		mv crypto/buffer/buffer.d.tmp crypto/buffer/buffer.d; \
+	fi
+crypto/camellia/camellia.o: crypto/camellia/camellia.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/camellia/camellia.d.tmp -MT $@ -c -o $@ crypto/camellia/camellia.c
+	@touch crypto/camellia/camellia.d.tmp
+	@if cmp crypto/camellia/camellia.d.tmp crypto/camellia/camellia.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/camellia/camellia.d.tmp; \
+	else \
+		mv crypto/camellia/camellia.d.tmp crypto/camellia/camellia.d; \
+	fi
+crypto/camellia/cmll_cbc.o: crypto/camellia/cmll_cbc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/camellia/cmll_cbc.d.tmp -MT $@ -c -o $@ crypto/camellia/cmll_cbc.c
+	@touch crypto/camellia/cmll_cbc.d.tmp
+	@if cmp crypto/camellia/cmll_cbc.d.tmp crypto/camellia/cmll_cbc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/camellia/cmll_cbc.d.tmp; \
+	else \
+		mv crypto/camellia/cmll_cbc.d.tmp crypto/camellia/cmll_cbc.d; \
+	fi
+crypto/camellia/cmll_cfb.o: crypto/camellia/cmll_cfb.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/camellia/cmll_cfb.d.tmp -MT $@ -c -o $@ crypto/camellia/cmll_cfb.c
+	@touch crypto/camellia/cmll_cfb.d.tmp
+	@if cmp crypto/camellia/cmll_cfb.d.tmp crypto/camellia/cmll_cfb.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/camellia/cmll_cfb.d.tmp; \
+	else \
+		mv crypto/camellia/cmll_cfb.d.tmp crypto/camellia/cmll_cfb.d; \
+	fi
+crypto/camellia/cmll_ctr.o: crypto/camellia/cmll_ctr.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/camellia/cmll_ctr.d.tmp -MT $@ -c -o $@ crypto/camellia/cmll_ctr.c
+	@touch crypto/camellia/cmll_ctr.d.tmp
+	@if cmp crypto/camellia/cmll_ctr.d.tmp crypto/camellia/cmll_ctr.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/camellia/cmll_ctr.d.tmp; \
+	else \
+		mv crypto/camellia/cmll_ctr.d.tmp crypto/camellia/cmll_ctr.d; \
+	fi
+crypto/camellia/cmll_ecb.o: crypto/camellia/cmll_ecb.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/camellia/cmll_ecb.d.tmp -MT $@ -c -o $@ crypto/camellia/cmll_ecb.c
+	@touch crypto/camellia/cmll_ecb.d.tmp
+	@if cmp crypto/camellia/cmll_ecb.d.tmp crypto/camellia/cmll_ecb.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/camellia/cmll_ecb.d.tmp; \
+	else \
+		mv crypto/camellia/cmll_ecb.d.tmp crypto/camellia/cmll_ecb.d; \
+	fi
+crypto/camellia/cmll_misc.o: crypto/camellia/cmll_misc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/camellia/cmll_misc.d.tmp -MT $@ -c -o $@ crypto/camellia/cmll_misc.c
+	@touch crypto/camellia/cmll_misc.d.tmp
+	@if cmp crypto/camellia/cmll_misc.d.tmp crypto/camellia/cmll_misc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/camellia/cmll_misc.d.tmp; \
+	else \
+		mv crypto/camellia/cmll_misc.d.tmp crypto/camellia/cmll_misc.d; \
+	fi
+crypto/camellia/cmll_ofb.o: crypto/camellia/cmll_ofb.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/camellia/cmll_ofb.d.tmp -MT $@ -c -o $@ crypto/camellia/cmll_ofb.c
+	@touch crypto/camellia/cmll_ofb.d.tmp
+	@if cmp crypto/camellia/cmll_ofb.d.tmp crypto/camellia/cmll_ofb.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/camellia/cmll_ofb.d.tmp; \
+	else \
+		mv crypto/camellia/cmll_ofb.d.tmp crypto/camellia/cmll_ofb.d; \
+	fi
+crypto/cast/c_cfb64.o: crypto/cast/c_cfb64.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cast/c_cfb64.d.tmp -MT $@ -c -o $@ crypto/cast/c_cfb64.c
+	@touch crypto/cast/c_cfb64.d.tmp
+	@if cmp crypto/cast/c_cfb64.d.tmp crypto/cast/c_cfb64.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cast/c_cfb64.d.tmp; \
+	else \
+		mv crypto/cast/c_cfb64.d.tmp crypto/cast/c_cfb64.d; \
+	fi
+crypto/cast/c_ecb.o: crypto/cast/c_ecb.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cast/c_ecb.d.tmp -MT $@ -c -o $@ crypto/cast/c_ecb.c
+	@touch crypto/cast/c_ecb.d.tmp
+	@if cmp crypto/cast/c_ecb.d.tmp crypto/cast/c_ecb.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cast/c_ecb.d.tmp; \
+	else \
+		mv crypto/cast/c_ecb.d.tmp crypto/cast/c_ecb.d; \
+	fi
+crypto/cast/c_enc.o: crypto/cast/c_enc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cast/c_enc.d.tmp -MT $@ -c -o $@ crypto/cast/c_enc.c
+	@touch crypto/cast/c_enc.d.tmp
+	@if cmp crypto/cast/c_enc.d.tmp crypto/cast/c_enc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cast/c_enc.d.tmp; \
+	else \
+		mv crypto/cast/c_enc.d.tmp crypto/cast/c_enc.d; \
+	fi
+crypto/cast/c_ofb64.o: crypto/cast/c_ofb64.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cast/c_ofb64.d.tmp -MT $@ -c -o $@ crypto/cast/c_ofb64.c
+	@touch crypto/cast/c_ofb64.d.tmp
+	@if cmp crypto/cast/c_ofb64.d.tmp crypto/cast/c_ofb64.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cast/c_ofb64.d.tmp; \
+	else \
+		mv crypto/cast/c_ofb64.d.tmp crypto/cast/c_ofb64.d; \
+	fi
+crypto/cast/c_skey.o: crypto/cast/c_skey.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cast/c_skey.d.tmp -MT $@ -c -o $@ crypto/cast/c_skey.c
+	@touch crypto/cast/c_skey.d.tmp
+	@if cmp crypto/cast/c_skey.d.tmp crypto/cast/c_skey.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cast/c_skey.d.tmp; \
+	else \
+		mv crypto/cast/c_skey.d.tmp crypto/cast/c_skey.d; \
+	fi
+crypto/chacha/chacha_enc.o: crypto/chacha/chacha_enc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/chacha/chacha_enc.d.tmp -MT $@ -c -o $@ crypto/chacha/chacha_enc.c
+	@touch crypto/chacha/chacha_enc.d.tmp
+	@if cmp crypto/chacha/chacha_enc.d.tmp crypto/chacha/chacha_enc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/chacha/chacha_enc.d.tmp; \
+	else \
+		mv crypto/chacha/chacha_enc.d.tmp crypto/chacha/chacha_enc.d; \
+	fi
+crypto/cmac/cm_ameth.o: crypto/cmac/cm_ameth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cmac/cm_ameth.d.tmp -MT $@ -c -o $@ crypto/cmac/cm_ameth.c
+	@touch crypto/cmac/cm_ameth.d.tmp
+	@if cmp crypto/cmac/cm_ameth.d.tmp crypto/cmac/cm_ameth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cmac/cm_ameth.d.tmp; \
+	else \
+		mv crypto/cmac/cm_ameth.d.tmp crypto/cmac/cm_ameth.d; \
+	fi
+crypto/cmac/cm_pmeth.o: crypto/cmac/cm_pmeth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cmac/cm_pmeth.d.tmp -MT $@ -c -o $@ crypto/cmac/cm_pmeth.c
+	@touch crypto/cmac/cm_pmeth.d.tmp
+	@if cmp crypto/cmac/cm_pmeth.d.tmp crypto/cmac/cm_pmeth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cmac/cm_pmeth.d.tmp; \
+	else \
+		mv crypto/cmac/cm_pmeth.d.tmp crypto/cmac/cm_pmeth.d; \
+	fi
+crypto/cmac/cmac.o: crypto/cmac/cmac.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cmac/cmac.d.tmp -MT $@ -c -o $@ crypto/cmac/cmac.c
+	@touch crypto/cmac/cmac.d.tmp
+	@if cmp crypto/cmac/cmac.d.tmp crypto/cmac/cmac.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cmac/cmac.d.tmp; \
+	else \
+		mv crypto/cmac/cmac.d.tmp crypto/cmac/cmac.d; \
+	fi
+crypto/cms/cms_asn1.o: crypto/cms/cms_asn1.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cms/cms_asn1.d.tmp -MT $@ -c -o $@ crypto/cms/cms_asn1.c
+	@touch crypto/cms/cms_asn1.d.tmp
+	@if cmp crypto/cms/cms_asn1.d.tmp crypto/cms/cms_asn1.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cms/cms_asn1.d.tmp; \
+	else \
+		mv crypto/cms/cms_asn1.d.tmp crypto/cms/cms_asn1.d; \
+	fi
+crypto/cms/cms_att.o: crypto/cms/cms_att.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cms/cms_att.d.tmp -MT $@ -c -o $@ crypto/cms/cms_att.c
+	@touch crypto/cms/cms_att.d.tmp
+	@if cmp crypto/cms/cms_att.d.tmp crypto/cms/cms_att.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cms/cms_att.d.tmp; \
+	else \
+		mv crypto/cms/cms_att.d.tmp crypto/cms/cms_att.d; \
+	fi
+crypto/cms/cms_cd.o: crypto/cms/cms_cd.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cms/cms_cd.d.tmp -MT $@ -c -o $@ crypto/cms/cms_cd.c
+	@touch crypto/cms/cms_cd.d.tmp
+	@if cmp crypto/cms/cms_cd.d.tmp crypto/cms/cms_cd.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cms/cms_cd.d.tmp; \
+	else \
+		mv crypto/cms/cms_cd.d.tmp crypto/cms/cms_cd.d; \
+	fi
+crypto/cms/cms_dd.o: crypto/cms/cms_dd.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cms/cms_dd.d.tmp -MT $@ -c -o $@ crypto/cms/cms_dd.c
+	@touch crypto/cms/cms_dd.d.tmp
+	@if cmp crypto/cms/cms_dd.d.tmp crypto/cms/cms_dd.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cms/cms_dd.d.tmp; \
+	else \
+		mv crypto/cms/cms_dd.d.tmp crypto/cms/cms_dd.d; \
+	fi
+crypto/cms/cms_enc.o: crypto/cms/cms_enc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cms/cms_enc.d.tmp -MT $@ -c -o $@ crypto/cms/cms_enc.c
+	@touch crypto/cms/cms_enc.d.tmp
+	@if cmp crypto/cms/cms_enc.d.tmp crypto/cms/cms_enc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cms/cms_enc.d.tmp; \
+	else \
+		mv crypto/cms/cms_enc.d.tmp crypto/cms/cms_enc.d; \
+	fi
+crypto/cms/cms_env.o: crypto/cms/cms_env.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cms/cms_env.d.tmp -MT $@ -c -o $@ crypto/cms/cms_env.c
+	@touch crypto/cms/cms_env.d.tmp
+	@if cmp crypto/cms/cms_env.d.tmp crypto/cms/cms_env.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cms/cms_env.d.tmp; \
+	else \
+		mv crypto/cms/cms_env.d.tmp crypto/cms/cms_env.d; \
+	fi
+crypto/cms/cms_err.o: crypto/cms/cms_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cms/cms_err.d.tmp -MT $@ -c -o $@ crypto/cms/cms_err.c
+	@touch crypto/cms/cms_err.d.tmp
+	@if cmp crypto/cms/cms_err.d.tmp crypto/cms/cms_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cms/cms_err.d.tmp; \
+	else \
+		mv crypto/cms/cms_err.d.tmp crypto/cms/cms_err.d; \
+	fi
+crypto/cms/cms_ess.o: crypto/cms/cms_ess.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cms/cms_ess.d.tmp -MT $@ -c -o $@ crypto/cms/cms_ess.c
+	@touch crypto/cms/cms_ess.d.tmp
+	@if cmp crypto/cms/cms_ess.d.tmp crypto/cms/cms_ess.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cms/cms_ess.d.tmp; \
+	else \
+		mv crypto/cms/cms_ess.d.tmp crypto/cms/cms_ess.d; \
+	fi
+crypto/cms/cms_io.o: crypto/cms/cms_io.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cms/cms_io.d.tmp -MT $@ -c -o $@ crypto/cms/cms_io.c
+	@touch crypto/cms/cms_io.d.tmp
+	@if cmp crypto/cms/cms_io.d.tmp crypto/cms/cms_io.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cms/cms_io.d.tmp; \
+	else \
+		mv crypto/cms/cms_io.d.tmp crypto/cms/cms_io.d; \
+	fi
+crypto/cms/cms_kari.o: crypto/cms/cms_kari.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cms/cms_kari.d.tmp -MT $@ -c -o $@ crypto/cms/cms_kari.c
+	@touch crypto/cms/cms_kari.d.tmp
+	@if cmp crypto/cms/cms_kari.d.tmp crypto/cms/cms_kari.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cms/cms_kari.d.tmp; \
+	else \
+		mv crypto/cms/cms_kari.d.tmp crypto/cms/cms_kari.d; \
+	fi
+crypto/cms/cms_lib.o: crypto/cms/cms_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cms/cms_lib.d.tmp -MT $@ -c -o $@ crypto/cms/cms_lib.c
+	@touch crypto/cms/cms_lib.d.tmp
+	@if cmp crypto/cms/cms_lib.d.tmp crypto/cms/cms_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cms/cms_lib.d.tmp; \
+	else \
+		mv crypto/cms/cms_lib.d.tmp crypto/cms/cms_lib.d; \
+	fi
+crypto/cms/cms_pwri.o: crypto/cms/cms_pwri.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cms/cms_pwri.d.tmp -MT $@ -c -o $@ crypto/cms/cms_pwri.c
+	@touch crypto/cms/cms_pwri.d.tmp
+	@if cmp crypto/cms/cms_pwri.d.tmp crypto/cms/cms_pwri.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cms/cms_pwri.d.tmp; \
+	else \
+		mv crypto/cms/cms_pwri.d.tmp crypto/cms/cms_pwri.d; \
+	fi
+crypto/cms/cms_sd.o: crypto/cms/cms_sd.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cms/cms_sd.d.tmp -MT $@ -c -o $@ crypto/cms/cms_sd.c
+	@touch crypto/cms/cms_sd.d.tmp
+	@if cmp crypto/cms/cms_sd.d.tmp crypto/cms/cms_sd.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cms/cms_sd.d.tmp; \
+	else \
+		mv crypto/cms/cms_sd.d.tmp crypto/cms/cms_sd.d; \
+	fi
+crypto/cms/cms_smime.o: crypto/cms/cms_smime.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cms/cms_smime.d.tmp -MT $@ -c -o $@ crypto/cms/cms_smime.c
+	@touch crypto/cms/cms_smime.d.tmp
+	@if cmp crypto/cms/cms_smime.d.tmp crypto/cms/cms_smime.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cms/cms_smime.d.tmp; \
+	else \
+		mv crypto/cms/cms_smime.d.tmp crypto/cms/cms_smime.d; \
+	fi
+crypto/comp/c_zlib.o: crypto/comp/c_zlib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/comp/c_zlib.d.tmp -MT $@ -c -o $@ crypto/comp/c_zlib.c
+	@touch crypto/comp/c_zlib.d.tmp
+	@if cmp crypto/comp/c_zlib.d.tmp crypto/comp/c_zlib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/comp/c_zlib.d.tmp; \
+	else \
+		mv crypto/comp/c_zlib.d.tmp crypto/comp/c_zlib.d; \
+	fi
+crypto/comp/comp_err.o: crypto/comp/comp_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/comp/comp_err.d.tmp -MT $@ -c -o $@ crypto/comp/comp_err.c
+	@touch crypto/comp/comp_err.d.tmp
+	@if cmp crypto/comp/comp_err.d.tmp crypto/comp/comp_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/comp/comp_err.d.tmp; \
+	else \
+		mv crypto/comp/comp_err.d.tmp crypto/comp/comp_err.d; \
+	fi
+crypto/comp/comp_lib.o: crypto/comp/comp_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/comp/comp_lib.d.tmp -MT $@ -c -o $@ crypto/comp/comp_lib.c
+	@touch crypto/comp/comp_lib.d.tmp
+	@if cmp crypto/comp/comp_lib.d.tmp crypto/comp/comp_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/comp/comp_lib.d.tmp; \
+	else \
+		mv crypto/comp/comp_lib.d.tmp crypto/comp/comp_lib.d; \
+	fi
+crypto/conf/conf_api.o: crypto/conf/conf_api.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/conf/conf_api.d.tmp -MT $@ -c -o $@ crypto/conf/conf_api.c
+	@touch crypto/conf/conf_api.d.tmp
+	@if cmp crypto/conf/conf_api.d.tmp crypto/conf/conf_api.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/conf/conf_api.d.tmp; \
+	else \
+		mv crypto/conf/conf_api.d.tmp crypto/conf/conf_api.d; \
+	fi
+crypto/conf/conf_def.o: crypto/conf/conf_def.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/conf/conf_def.d.tmp -MT $@ -c -o $@ crypto/conf/conf_def.c
+	@touch crypto/conf/conf_def.d.tmp
+	@if cmp crypto/conf/conf_def.d.tmp crypto/conf/conf_def.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/conf/conf_def.d.tmp; \
+	else \
+		mv crypto/conf/conf_def.d.tmp crypto/conf/conf_def.d; \
+	fi
+crypto/conf/conf_err.o: crypto/conf/conf_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/conf/conf_err.d.tmp -MT $@ -c -o $@ crypto/conf/conf_err.c
+	@touch crypto/conf/conf_err.d.tmp
+	@if cmp crypto/conf/conf_err.d.tmp crypto/conf/conf_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/conf/conf_err.d.tmp; \
+	else \
+		mv crypto/conf/conf_err.d.tmp crypto/conf/conf_err.d; \
+	fi
+crypto/conf/conf_lib.o: crypto/conf/conf_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/conf/conf_lib.d.tmp -MT $@ -c -o $@ crypto/conf/conf_lib.c
+	@touch crypto/conf/conf_lib.d.tmp
+	@if cmp crypto/conf/conf_lib.d.tmp crypto/conf/conf_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/conf/conf_lib.d.tmp; \
+	else \
+		mv crypto/conf/conf_lib.d.tmp crypto/conf/conf_lib.d; \
+	fi
+crypto/conf/conf_mall.o: crypto/conf/conf_mall.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/conf/conf_mall.d.tmp -MT $@ -c -o $@ crypto/conf/conf_mall.c
+	@touch crypto/conf/conf_mall.d.tmp
+	@if cmp crypto/conf/conf_mall.d.tmp crypto/conf/conf_mall.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/conf/conf_mall.d.tmp; \
+	else \
+		mv crypto/conf/conf_mall.d.tmp crypto/conf/conf_mall.d; \
+	fi
+crypto/conf/conf_mod.o: crypto/conf/conf_mod.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/conf/conf_mod.d.tmp -MT $@ -c -o $@ crypto/conf/conf_mod.c
+	@touch crypto/conf/conf_mod.d.tmp
+	@if cmp crypto/conf/conf_mod.d.tmp crypto/conf/conf_mod.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/conf/conf_mod.d.tmp; \
+	else \
+		mv crypto/conf/conf_mod.d.tmp crypto/conf/conf_mod.d; \
+	fi
+crypto/conf/conf_sap.o: crypto/conf/conf_sap.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/conf/conf_sap.d.tmp -MT $@ -c -o $@ crypto/conf/conf_sap.c
+	@touch crypto/conf/conf_sap.d.tmp
+	@if cmp crypto/conf/conf_sap.d.tmp crypto/conf/conf_sap.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/conf/conf_sap.d.tmp; \
+	else \
+		mv crypto/conf/conf_sap.d.tmp crypto/conf/conf_sap.d; \
+	fi
+crypto/cpt_err.o: crypto/cpt_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cpt_err.d.tmp -MT $@ -c -o $@ crypto/cpt_err.c
+	@touch crypto/cpt_err.d.tmp
+	@if cmp crypto/cpt_err.d.tmp crypto/cpt_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cpt_err.d.tmp; \
+	else \
+		mv crypto/cpt_err.d.tmp crypto/cpt_err.d; \
+	fi
+crypto/cryptlib.o: crypto/cryptlib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cryptlib.d.tmp -MT $@ -c -o $@ crypto/cryptlib.c
+	@touch crypto/cryptlib.d.tmp
+	@if cmp crypto/cryptlib.d.tmp crypto/cryptlib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cryptlib.d.tmp; \
+	else \
+		mv crypto/cryptlib.d.tmp crypto/cryptlib.d; \
+	fi
+crypto/ct/ct_b64.o: crypto/ct/ct_b64.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ct/ct_b64.d.tmp -MT $@ -c -o $@ crypto/ct/ct_b64.c
+	@touch crypto/ct/ct_b64.d.tmp
+	@if cmp crypto/ct/ct_b64.d.tmp crypto/ct/ct_b64.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ct/ct_b64.d.tmp; \
+	else \
+		mv crypto/ct/ct_b64.d.tmp crypto/ct/ct_b64.d; \
+	fi
+crypto/ct/ct_err.o: crypto/ct/ct_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ct/ct_err.d.tmp -MT $@ -c -o $@ crypto/ct/ct_err.c
+	@touch crypto/ct/ct_err.d.tmp
+	@if cmp crypto/ct/ct_err.d.tmp crypto/ct/ct_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ct/ct_err.d.tmp; \
+	else \
+		mv crypto/ct/ct_err.d.tmp crypto/ct/ct_err.d; \
+	fi
+crypto/ct/ct_log.o: crypto/ct/ct_log.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ct/ct_log.d.tmp -MT $@ -c -o $@ crypto/ct/ct_log.c
+	@touch crypto/ct/ct_log.d.tmp
+	@if cmp crypto/ct/ct_log.d.tmp crypto/ct/ct_log.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ct/ct_log.d.tmp; \
+	else \
+		mv crypto/ct/ct_log.d.tmp crypto/ct/ct_log.d; \
+	fi
+crypto/ct/ct_oct.o: crypto/ct/ct_oct.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ct/ct_oct.d.tmp -MT $@ -c -o $@ crypto/ct/ct_oct.c
+	@touch crypto/ct/ct_oct.d.tmp
+	@if cmp crypto/ct/ct_oct.d.tmp crypto/ct/ct_oct.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ct/ct_oct.d.tmp; \
+	else \
+		mv crypto/ct/ct_oct.d.tmp crypto/ct/ct_oct.d; \
+	fi
+crypto/ct/ct_policy.o: crypto/ct/ct_policy.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ct/ct_policy.d.tmp -MT $@ -c -o $@ crypto/ct/ct_policy.c
+	@touch crypto/ct/ct_policy.d.tmp
+	@if cmp crypto/ct/ct_policy.d.tmp crypto/ct/ct_policy.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ct/ct_policy.d.tmp; \
+	else \
+		mv crypto/ct/ct_policy.d.tmp crypto/ct/ct_policy.d; \
+	fi
+crypto/ct/ct_prn.o: crypto/ct/ct_prn.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ct/ct_prn.d.tmp -MT $@ -c -o $@ crypto/ct/ct_prn.c
+	@touch crypto/ct/ct_prn.d.tmp
+	@if cmp crypto/ct/ct_prn.d.tmp crypto/ct/ct_prn.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ct/ct_prn.d.tmp; \
+	else \
+		mv crypto/ct/ct_prn.d.tmp crypto/ct/ct_prn.d; \
+	fi
+crypto/ct/ct_sct.o: crypto/ct/ct_sct.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ct/ct_sct.d.tmp -MT $@ -c -o $@ crypto/ct/ct_sct.c
+	@touch crypto/ct/ct_sct.d.tmp
+	@if cmp crypto/ct/ct_sct.d.tmp crypto/ct/ct_sct.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ct/ct_sct.d.tmp; \
+	else \
+		mv crypto/ct/ct_sct.d.tmp crypto/ct/ct_sct.d; \
+	fi
+crypto/ct/ct_sct_ctx.o: crypto/ct/ct_sct_ctx.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ct/ct_sct_ctx.d.tmp -MT $@ -c -o $@ crypto/ct/ct_sct_ctx.c
+	@touch crypto/ct/ct_sct_ctx.d.tmp
+	@if cmp crypto/ct/ct_sct_ctx.d.tmp crypto/ct/ct_sct_ctx.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ct/ct_sct_ctx.d.tmp; \
+	else \
+		mv crypto/ct/ct_sct_ctx.d.tmp crypto/ct/ct_sct_ctx.d; \
+	fi
+crypto/ct/ct_vfy.o: crypto/ct/ct_vfy.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ct/ct_vfy.d.tmp -MT $@ -c -o $@ crypto/ct/ct_vfy.c
+	@touch crypto/ct/ct_vfy.d.tmp
+	@if cmp crypto/ct/ct_vfy.d.tmp crypto/ct/ct_vfy.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ct/ct_vfy.d.tmp; \
+	else \
+		mv crypto/ct/ct_vfy.d.tmp crypto/ct/ct_vfy.d; \
+	fi
+crypto/ct/ct_x509v3.o: crypto/ct/ct_x509v3.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ct/ct_x509v3.d.tmp -MT $@ -c -o $@ crypto/ct/ct_x509v3.c
+	@touch crypto/ct/ct_x509v3.d.tmp
+	@if cmp crypto/ct/ct_x509v3.d.tmp crypto/ct/ct_x509v3.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ct/ct_x509v3.d.tmp; \
+	else \
+		mv crypto/ct/ct_x509v3.d.tmp crypto/ct/ct_x509v3.d; \
+	fi
+crypto/cversion.o: crypto/cversion.c crypto/buildinf.h
+	$(CC)  -I. -Icrypto/include -Iinclude -Icrypto $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/cversion.d.tmp -MT $@ -c -o $@ crypto/cversion.c
+	@touch crypto/cversion.d.tmp
+	@if cmp crypto/cversion.d.tmp crypto/cversion.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/cversion.d.tmp; \
+	else \
+		mv crypto/cversion.d.tmp crypto/cversion.d; \
+	fi
+crypto/buildinf.h: util/mkbuildinf.pl configdata.pm
+	$(PERL) util/mkbuildinf.pl "$(CC) $(CFLAGS_Q)" "$(PLATFORM)" > $@
+crypto/des/cbc_cksm.o: crypto/des/cbc_cksm.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/des/cbc_cksm.d.tmp -MT $@ -c -o $@ crypto/des/cbc_cksm.c
+	@touch crypto/des/cbc_cksm.d.tmp
+	@if cmp crypto/des/cbc_cksm.d.tmp crypto/des/cbc_cksm.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/des/cbc_cksm.d.tmp; \
+	else \
+		mv crypto/des/cbc_cksm.d.tmp crypto/des/cbc_cksm.d; \
+	fi
+crypto/des/cbc_enc.o: crypto/des/cbc_enc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/des/cbc_enc.d.tmp -MT $@ -c -o $@ crypto/des/cbc_enc.c
+	@touch crypto/des/cbc_enc.d.tmp
+	@if cmp crypto/des/cbc_enc.d.tmp crypto/des/cbc_enc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/des/cbc_enc.d.tmp; \
+	else \
+		mv crypto/des/cbc_enc.d.tmp crypto/des/cbc_enc.d; \
+	fi
+crypto/des/cfb64ede.o: crypto/des/cfb64ede.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/des/cfb64ede.d.tmp -MT $@ -c -o $@ crypto/des/cfb64ede.c
+	@touch crypto/des/cfb64ede.d.tmp
+	@if cmp crypto/des/cfb64ede.d.tmp crypto/des/cfb64ede.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/des/cfb64ede.d.tmp; \
+	else \
+		mv crypto/des/cfb64ede.d.tmp crypto/des/cfb64ede.d; \
+	fi
+crypto/des/cfb64enc.o: crypto/des/cfb64enc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/des/cfb64enc.d.tmp -MT $@ -c -o $@ crypto/des/cfb64enc.c
+	@touch crypto/des/cfb64enc.d.tmp
+	@if cmp crypto/des/cfb64enc.d.tmp crypto/des/cfb64enc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/des/cfb64enc.d.tmp; \
+	else \
+		mv crypto/des/cfb64enc.d.tmp crypto/des/cfb64enc.d; \
+	fi
+crypto/des/cfb_enc.o: crypto/des/cfb_enc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/des/cfb_enc.d.tmp -MT $@ -c -o $@ crypto/des/cfb_enc.c
+	@touch crypto/des/cfb_enc.d.tmp
+	@if cmp crypto/des/cfb_enc.d.tmp crypto/des/cfb_enc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/des/cfb_enc.d.tmp; \
+	else \
+		mv crypto/des/cfb_enc.d.tmp crypto/des/cfb_enc.d; \
+	fi
+crypto/des/des_enc.o: crypto/des/des_enc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/des/des_enc.d.tmp -MT $@ -c -o $@ crypto/des/des_enc.c
+	@touch crypto/des/des_enc.d.tmp
+	@if cmp crypto/des/des_enc.d.tmp crypto/des/des_enc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/des/des_enc.d.tmp; \
+	else \
+		mv crypto/des/des_enc.d.tmp crypto/des/des_enc.d; \
+	fi
+crypto/des/ecb3_enc.o: crypto/des/ecb3_enc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/des/ecb3_enc.d.tmp -MT $@ -c -o $@ crypto/des/ecb3_enc.c
+	@touch crypto/des/ecb3_enc.d.tmp
+	@if cmp crypto/des/ecb3_enc.d.tmp crypto/des/ecb3_enc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/des/ecb3_enc.d.tmp; \
+	else \
+		mv crypto/des/ecb3_enc.d.tmp crypto/des/ecb3_enc.d; \
+	fi
+crypto/des/ecb_enc.o: crypto/des/ecb_enc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/des/ecb_enc.d.tmp -MT $@ -c -o $@ crypto/des/ecb_enc.c
+	@touch crypto/des/ecb_enc.d.tmp
+	@if cmp crypto/des/ecb_enc.d.tmp crypto/des/ecb_enc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/des/ecb_enc.d.tmp; \
+	else \
+		mv crypto/des/ecb_enc.d.tmp crypto/des/ecb_enc.d; \
+	fi
+crypto/des/fcrypt.o: crypto/des/fcrypt.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/des/fcrypt.d.tmp -MT $@ -c -o $@ crypto/des/fcrypt.c
+	@touch crypto/des/fcrypt.d.tmp
+	@if cmp crypto/des/fcrypt.d.tmp crypto/des/fcrypt.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/des/fcrypt.d.tmp; \
+	else \
+		mv crypto/des/fcrypt.d.tmp crypto/des/fcrypt.d; \
+	fi
+crypto/des/fcrypt_b.o: crypto/des/fcrypt_b.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/des/fcrypt_b.d.tmp -MT $@ -c -o $@ crypto/des/fcrypt_b.c
+	@touch crypto/des/fcrypt_b.d.tmp
+	@if cmp crypto/des/fcrypt_b.d.tmp crypto/des/fcrypt_b.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/des/fcrypt_b.d.tmp; \
+	else \
+		mv crypto/des/fcrypt_b.d.tmp crypto/des/fcrypt_b.d; \
+	fi
+crypto/des/ofb64ede.o: crypto/des/ofb64ede.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/des/ofb64ede.d.tmp -MT $@ -c -o $@ crypto/des/ofb64ede.c
+	@touch crypto/des/ofb64ede.d.tmp
+	@if cmp crypto/des/ofb64ede.d.tmp crypto/des/ofb64ede.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/des/ofb64ede.d.tmp; \
+	else \
+		mv crypto/des/ofb64ede.d.tmp crypto/des/ofb64ede.d; \
+	fi
+crypto/des/ofb64enc.o: crypto/des/ofb64enc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/des/ofb64enc.d.tmp -MT $@ -c -o $@ crypto/des/ofb64enc.c
+	@touch crypto/des/ofb64enc.d.tmp
+	@if cmp crypto/des/ofb64enc.d.tmp crypto/des/ofb64enc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/des/ofb64enc.d.tmp; \
+	else \
+		mv crypto/des/ofb64enc.d.tmp crypto/des/ofb64enc.d; \
+	fi
+crypto/des/ofb_enc.o: crypto/des/ofb_enc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/des/ofb_enc.d.tmp -MT $@ -c -o $@ crypto/des/ofb_enc.c
+	@touch crypto/des/ofb_enc.d.tmp
+	@if cmp crypto/des/ofb_enc.d.tmp crypto/des/ofb_enc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/des/ofb_enc.d.tmp; \
+	else \
+		mv crypto/des/ofb_enc.d.tmp crypto/des/ofb_enc.d; \
+	fi
+crypto/des/pcbc_enc.o: crypto/des/pcbc_enc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/des/pcbc_enc.d.tmp -MT $@ -c -o $@ crypto/des/pcbc_enc.c
+	@touch crypto/des/pcbc_enc.d.tmp
+	@if cmp crypto/des/pcbc_enc.d.tmp crypto/des/pcbc_enc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/des/pcbc_enc.d.tmp; \
+	else \
+		mv crypto/des/pcbc_enc.d.tmp crypto/des/pcbc_enc.d; \
+	fi
+crypto/des/qud_cksm.o: crypto/des/qud_cksm.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/des/qud_cksm.d.tmp -MT $@ -c -o $@ crypto/des/qud_cksm.c
+	@touch crypto/des/qud_cksm.d.tmp
+	@if cmp crypto/des/qud_cksm.d.tmp crypto/des/qud_cksm.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/des/qud_cksm.d.tmp; \
+	else \
+		mv crypto/des/qud_cksm.d.tmp crypto/des/qud_cksm.d; \
+	fi
+crypto/des/rand_key.o: crypto/des/rand_key.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/des/rand_key.d.tmp -MT $@ -c -o $@ crypto/des/rand_key.c
+	@touch crypto/des/rand_key.d.tmp
+	@if cmp crypto/des/rand_key.d.tmp crypto/des/rand_key.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/des/rand_key.d.tmp; \
+	else \
+		mv crypto/des/rand_key.d.tmp crypto/des/rand_key.d; \
+	fi
+crypto/des/rpc_enc.o: crypto/des/rpc_enc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/des/rpc_enc.d.tmp -MT $@ -c -o $@ crypto/des/rpc_enc.c
+	@touch crypto/des/rpc_enc.d.tmp
+	@if cmp crypto/des/rpc_enc.d.tmp crypto/des/rpc_enc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/des/rpc_enc.d.tmp; \
+	else \
+		mv crypto/des/rpc_enc.d.tmp crypto/des/rpc_enc.d; \
+	fi
+crypto/des/set_key.o: crypto/des/set_key.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/des/set_key.d.tmp -MT $@ -c -o $@ crypto/des/set_key.c
+	@touch crypto/des/set_key.d.tmp
+	@if cmp crypto/des/set_key.d.tmp crypto/des/set_key.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/des/set_key.d.tmp; \
+	else \
+		mv crypto/des/set_key.d.tmp crypto/des/set_key.d; \
+	fi
+crypto/des/str2key.o: crypto/des/str2key.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/des/str2key.d.tmp -MT $@ -c -o $@ crypto/des/str2key.c
+	@touch crypto/des/str2key.d.tmp
+	@if cmp crypto/des/str2key.d.tmp crypto/des/str2key.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/des/str2key.d.tmp; \
+	else \
+		mv crypto/des/str2key.d.tmp crypto/des/str2key.d; \
+	fi
+crypto/des/xcbc_enc.o: crypto/des/xcbc_enc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/des/xcbc_enc.d.tmp -MT $@ -c -o $@ crypto/des/xcbc_enc.c
+	@touch crypto/des/xcbc_enc.d.tmp
+	@if cmp crypto/des/xcbc_enc.d.tmp crypto/des/xcbc_enc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/des/xcbc_enc.d.tmp; \
+	else \
+		mv crypto/des/xcbc_enc.d.tmp crypto/des/xcbc_enc.d; \
+	fi
+crypto/dh/dh_ameth.o: crypto/dh/dh_ameth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dh/dh_ameth.d.tmp -MT $@ -c -o $@ crypto/dh/dh_ameth.c
+	@touch crypto/dh/dh_ameth.d.tmp
+	@if cmp crypto/dh/dh_ameth.d.tmp crypto/dh/dh_ameth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dh/dh_ameth.d.tmp; \
+	else \
+		mv crypto/dh/dh_ameth.d.tmp crypto/dh/dh_ameth.d; \
+	fi
+crypto/dh/dh_asn1.o: crypto/dh/dh_asn1.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dh/dh_asn1.d.tmp -MT $@ -c -o $@ crypto/dh/dh_asn1.c
+	@touch crypto/dh/dh_asn1.d.tmp
+	@if cmp crypto/dh/dh_asn1.d.tmp crypto/dh/dh_asn1.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dh/dh_asn1.d.tmp; \
+	else \
+		mv crypto/dh/dh_asn1.d.tmp crypto/dh/dh_asn1.d; \
+	fi
+crypto/dh/dh_check.o: crypto/dh/dh_check.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dh/dh_check.d.tmp -MT $@ -c -o $@ crypto/dh/dh_check.c
+	@touch crypto/dh/dh_check.d.tmp
+	@if cmp crypto/dh/dh_check.d.tmp crypto/dh/dh_check.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dh/dh_check.d.tmp; \
+	else \
+		mv crypto/dh/dh_check.d.tmp crypto/dh/dh_check.d; \
+	fi
+crypto/dh/dh_depr.o: crypto/dh/dh_depr.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dh/dh_depr.d.tmp -MT $@ -c -o $@ crypto/dh/dh_depr.c
+	@touch crypto/dh/dh_depr.d.tmp
+	@if cmp crypto/dh/dh_depr.d.tmp crypto/dh/dh_depr.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dh/dh_depr.d.tmp; \
+	else \
+		mv crypto/dh/dh_depr.d.tmp crypto/dh/dh_depr.d; \
+	fi
+crypto/dh/dh_err.o: crypto/dh/dh_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dh/dh_err.d.tmp -MT $@ -c -o $@ crypto/dh/dh_err.c
+	@touch crypto/dh/dh_err.d.tmp
+	@if cmp crypto/dh/dh_err.d.tmp crypto/dh/dh_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dh/dh_err.d.tmp; \
+	else \
+		mv crypto/dh/dh_err.d.tmp crypto/dh/dh_err.d; \
+	fi
+crypto/dh/dh_gen.o: crypto/dh/dh_gen.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dh/dh_gen.d.tmp -MT $@ -c -o $@ crypto/dh/dh_gen.c
+	@touch crypto/dh/dh_gen.d.tmp
+	@if cmp crypto/dh/dh_gen.d.tmp crypto/dh/dh_gen.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dh/dh_gen.d.tmp; \
+	else \
+		mv crypto/dh/dh_gen.d.tmp crypto/dh/dh_gen.d; \
+	fi
+crypto/dh/dh_kdf.o: crypto/dh/dh_kdf.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dh/dh_kdf.d.tmp -MT $@ -c -o $@ crypto/dh/dh_kdf.c
+	@touch crypto/dh/dh_kdf.d.tmp
+	@if cmp crypto/dh/dh_kdf.d.tmp crypto/dh/dh_kdf.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dh/dh_kdf.d.tmp; \
+	else \
+		mv crypto/dh/dh_kdf.d.tmp crypto/dh/dh_kdf.d; \
+	fi
+crypto/dh/dh_key.o: crypto/dh/dh_key.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dh/dh_key.d.tmp -MT $@ -c -o $@ crypto/dh/dh_key.c
+	@touch crypto/dh/dh_key.d.tmp
+	@if cmp crypto/dh/dh_key.d.tmp crypto/dh/dh_key.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dh/dh_key.d.tmp; \
+	else \
+		mv crypto/dh/dh_key.d.tmp crypto/dh/dh_key.d; \
+	fi
+crypto/dh/dh_lib.o: crypto/dh/dh_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dh/dh_lib.d.tmp -MT $@ -c -o $@ crypto/dh/dh_lib.c
+	@touch crypto/dh/dh_lib.d.tmp
+	@if cmp crypto/dh/dh_lib.d.tmp crypto/dh/dh_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dh/dh_lib.d.tmp; \
+	else \
+		mv crypto/dh/dh_lib.d.tmp crypto/dh/dh_lib.d; \
+	fi
+crypto/dh/dh_meth.o: crypto/dh/dh_meth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dh/dh_meth.d.tmp -MT $@ -c -o $@ crypto/dh/dh_meth.c
+	@touch crypto/dh/dh_meth.d.tmp
+	@if cmp crypto/dh/dh_meth.d.tmp crypto/dh/dh_meth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dh/dh_meth.d.tmp; \
+	else \
+		mv crypto/dh/dh_meth.d.tmp crypto/dh/dh_meth.d; \
+	fi
+crypto/dh/dh_pmeth.o: crypto/dh/dh_pmeth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dh/dh_pmeth.d.tmp -MT $@ -c -o $@ crypto/dh/dh_pmeth.c
+	@touch crypto/dh/dh_pmeth.d.tmp
+	@if cmp crypto/dh/dh_pmeth.d.tmp crypto/dh/dh_pmeth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dh/dh_pmeth.d.tmp; \
+	else \
+		mv crypto/dh/dh_pmeth.d.tmp crypto/dh/dh_pmeth.d; \
+	fi
+crypto/dh/dh_prn.o: crypto/dh/dh_prn.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dh/dh_prn.d.tmp -MT $@ -c -o $@ crypto/dh/dh_prn.c
+	@touch crypto/dh/dh_prn.d.tmp
+	@if cmp crypto/dh/dh_prn.d.tmp crypto/dh/dh_prn.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dh/dh_prn.d.tmp; \
+	else \
+		mv crypto/dh/dh_prn.d.tmp crypto/dh/dh_prn.d; \
+	fi
+crypto/dh/dh_rfc5114.o: crypto/dh/dh_rfc5114.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dh/dh_rfc5114.d.tmp -MT $@ -c -o $@ crypto/dh/dh_rfc5114.c
+	@touch crypto/dh/dh_rfc5114.d.tmp
+	@if cmp crypto/dh/dh_rfc5114.d.tmp crypto/dh/dh_rfc5114.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dh/dh_rfc5114.d.tmp; \
+	else \
+		mv crypto/dh/dh_rfc5114.d.tmp crypto/dh/dh_rfc5114.d; \
+	fi
+crypto/dsa/dsa_ameth.o: crypto/dsa/dsa_ameth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dsa/dsa_ameth.d.tmp -MT $@ -c -o $@ crypto/dsa/dsa_ameth.c
+	@touch crypto/dsa/dsa_ameth.d.tmp
+	@if cmp crypto/dsa/dsa_ameth.d.tmp crypto/dsa/dsa_ameth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dsa/dsa_ameth.d.tmp; \
+	else \
+		mv crypto/dsa/dsa_ameth.d.tmp crypto/dsa/dsa_ameth.d; \
+	fi
+crypto/dsa/dsa_asn1.o: crypto/dsa/dsa_asn1.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dsa/dsa_asn1.d.tmp -MT $@ -c -o $@ crypto/dsa/dsa_asn1.c
+	@touch crypto/dsa/dsa_asn1.d.tmp
+	@if cmp crypto/dsa/dsa_asn1.d.tmp crypto/dsa/dsa_asn1.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dsa/dsa_asn1.d.tmp; \
+	else \
+		mv crypto/dsa/dsa_asn1.d.tmp crypto/dsa/dsa_asn1.d; \
+	fi
+crypto/dsa/dsa_depr.o: crypto/dsa/dsa_depr.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dsa/dsa_depr.d.tmp -MT $@ -c -o $@ crypto/dsa/dsa_depr.c
+	@touch crypto/dsa/dsa_depr.d.tmp
+	@if cmp crypto/dsa/dsa_depr.d.tmp crypto/dsa/dsa_depr.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dsa/dsa_depr.d.tmp; \
+	else \
+		mv crypto/dsa/dsa_depr.d.tmp crypto/dsa/dsa_depr.d; \
+	fi
+crypto/dsa/dsa_err.o: crypto/dsa/dsa_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dsa/dsa_err.d.tmp -MT $@ -c -o $@ crypto/dsa/dsa_err.c
+	@touch crypto/dsa/dsa_err.d.tmp
+	@if cmp crypto/dsa/dsa_err.d.tmp crypto/dsa/dsa_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dsa/dsa_err.d.tmp; \
+	else \
+		mv crypto/dsa/dsa_err.d.tmp crypto/dsa/dsa_err.d; \
+	fi
+crypto/dsa/dsa_gen.o: crypto/dsa/dsa_gen.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dsa/dsa_gen.d.tmp -MT $@ -c -o $@ crypto/dsa/dsa_gen.c
+	@touch crypto/dsa/dsa_gen.d.tmp
+	@if cmp crypto/dsa/dsa_gen.d.tmp crypto/dsa/dsa_gen.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dsa/dsa_gen.d.tmp; \
+	else \
+		mv crypto/dsa/dsa_gen.d.tmp crypto/dsa/dsa_gen.d; \
+	fi
+crypto/dsa/dsa_key.o: crypto/dsa/dsa_key.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dsa/dsa_key.d.tmp -MT $@ -c -o $@ crypto/dsa/dsa_key.c
+	@touch crypto/dsa/dsa_key.d.tmp
+	@if cmp crypto/dsa/dsa_key.d.tmp crypto/dsa/dsa_key.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dsa/dsa_key.d.tmp; \
+	else \
+		mv crypto/dsa/dsa_key.d.tmp crypto/dsa/dsa_key.d; \
+	fi
+crypto/dsa/dsa_lib.o: crypto/dsa/dsa_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dsa/dsa_lib.d.tmp -MT $@ -c -o $@ crypto/dsa/dsa_lib.c
+	@touch crypto/dsa/dsa_lib.d.tmp
+	@if cmp crypto/dsa/dsa_lib.d.tmp crypto/dsa/dsa_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dsa/dsa_lib.d.tmp; \
+	else \
+		mv crypto/dsa/dsa_lib.d.tmp crypto/dsa/dsa_lib.d; \
+	fi
+crypto/dsa/dsa_meth.o: crypto/dsa/dsa_meth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dsa/dsa_meth.d.tmp -MT $@ -c -o $@ crypto/dsa/dsa_meth.c
+	@touch crypto/dsa/dsa_meth.d.tmp
+	@if cmp crypto/dsa/dsa_meth.d.tmp crypto/dsa/dsa_meth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dsa/dsa_meth.d.tmp; \
+	else \
+		mv crypto/dsa/dsa_meth.d.tmp crypto/dsa/dsa_meth.d; \
+	fi
+crypto/dsa/dsa_ossl.o: crypto/dsa/dsa_ossl.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dsa/dsa_ossl.d.tmp -MT $@ -c -o $@ crypto/dsa/dsa_ossl.c
+	@touch crypto/dsa/dsa_ossl.d.tmp
+	@if cmp crypto/dsa/dsa_ossl.d.tmp crypto/dsa/dsa_ossl.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dsa/dsa_ossl.d.tmp; \
+	else \
+		mv crypto/dsa/dsa_ossl.d.tmp crypto/dsa/dsa_ossl.d; \
+	fi
+crypto/dsa/dsa_pmeth.o: crypto/dsa/dsa_pmeth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dsa/dsa_pmeth.d.tmp -MT $@ -c -o $@ crypto/dsa/dsa_pmeth.c
+	@touch crypto/dsa/dsa_pmeth.d.tmp
+	@if cmp crypto/dsa/dsa_pmeth.d.tmp crypto/dsa/dsa_pmeth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dsa/dsa_pmeth.d.tmp; \
+	else \
+		mv crypto/dsa/dsa_pmeth.d.tmp crypto/dsa/dsa_pmeth.d; \
+	fi
+crypto/dsa/dsa_prn.o: crypto/dsa/dsa_prn.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dsa/dsa_prn.d.tmp -MT $@ -c -o $@ crypto/dsa/dsa_prn.c
+	@touch crypto/dsa/dsa_prn.d.tmp
+	@if cmp crypto/dsa/dsa_prn.d.tmp crypto/dsa/dsa_prn.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dsa/dsa_prn.d.tmp; \
+	else \
+		mv crypto/dsa/dsa_prn.d.tmp crypto/dsa/dsa_prn.d; \
+	fi
+crypto/dsa/dsa_sign.o: crypto/dsa/dsa_sign.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dsa/dsa_sign.d.tmp -MT $@ -c -o $@ crypto/dsa/dsa_sign.c
+	@touch crypto/dsa/dsa_sign.d.tmp
+	@if cmp crypto/dsa/dsa_sign.d.tmp crypto/dsa/dsa_sign.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dsa/dsa_sign.d.tmp; \
+	else \
+		mv crypto/dsa/dsa_sign.d.tmp crypto/dsa/dsa_sign.d; \
+	fi
+crypto/dsa/dsa_vrf.o: crypto/dsa/dsa_vrf.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dsa/dsa_vrf.d.tmp -MT $@ -c -o $@ crypto/dsa/dsa_vrf.c
+	@touch crypto/dsa/dsa_vrf.d.tmp
+	@if cmp crypto/dsa/dsa_vrf.d.tmp crypto/dsa/dsa_vrf.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dsa/dsa_vrf.d.tmp; \
+	else \
+		mv crypto/dsa/dsa_vrf.d.tmp crypto/dsa/dsa_vrf.d; \
+	fi
+crypto/dso/dso_dl.o: crypto/dso/dso_dl.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dso/dso_dl.d.tmp -MT $@ -c -o $@ crypto/dso/dso_dl.c
+	@touch crypto/dso/dso_dl.d.tmp
+	@if cmp crypto/dso/dso_dl.d.tmp crypto/dso/dso_dl.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dso/dso_dl.d.tmp; \
+	else \
+		mv crypto/dso/dso_dl.d.tmp crypto/dso/dso_dl.d; \
+	fi
+crypto/dso/dso_dlfcn.o: crypto/dso/dso_dlfcn.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dso/dso_dlfcn.d.tmp -MT $@ -c -o $@ crypto/dso/dso_dlfcn.c
+	@touch crypto/dso/dso_dlfcn.d.tmp
+	@if cmp crypto/dso/dso_dlfcn.d.tmp crypto/dso/dso_dlfcn.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dso/dso_dlfcn.d.tmp; \
+	else \
+		mv crypto/dso/dso_dlfcn.d.tmp crypto/dso/dso_dlfcn.d; \
+	fi
+crypto/dso/dso_err.o: crypto/dso/dso_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dso/dso_err.d.tmp -MT $@ -c -o $@ crypto/dso/dso_err.c
+	@touch crypto/dso/dso_err.d.tmp
+	@if cmp crypto/dso/dso_err.d.tmp crypto/dso/dso_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dso/dso_err.d.tmp; \
+	else \
+		mv crypto/dso/dso_err.d.tmp crypto/dso/dso_err.d; \
+	fi
+crypto/dso/dso_lib.o: crypto/dso/dso_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dso/dso_lib.d.tmp -MT $@ -c -o $@ crypto/dso/dso_lib.c
+	@touch crypto/dso/dso_lib.d.tmp
+	@if cmp crypto/dso/dso_lib.d.tmp crypto/dso/dso_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dso/dso_lib.d.tmp; \
+	else \
+		mv crypto/dso/dso_lib.d.tmp crypto/dso/dso_lib.d; \
+	fi
+crypto/dso/dso_openssl.o: crypto/dso/dso_openssl.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dso/dso_openssl.d.tmp -MT $@ -c -o $@ crypto/dso/dso_openssl.c
+	@touch crypto/dso/dso_openssl.d.tmp
+	@if cmp crypto/dso/dso_openssl.d.tmp crypto/dso/dso_openssl.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dso/dso_openssl.d.tmp; \
+	else \
+		mv crypto/dso/dso_openssl.d.tmp crypto/dso/dso_openssl.d; \
+	fi
+crypto/dso/dso_vms.o: crypto/dso/dso_vms.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dso/dso_vms.d.tmp -MT $@ -c -o $@ crypto/dso/dso_vms.c
+	@touch crypto/dso/dso_vms.d.tmp
+	@if cmp crypto/dso/dso_vms.d.tmp crypto/dso/dso_vms.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dso/dso_vms.d.tmp; \
+	else \
+		mv crypto/dso/dso_vms.d.tmp crypto/dso/dso_vms.d; \
+	fi
+crypto/dso/dso_win32.o: crypto/dso/dso_win32.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/dso/dso_win32.d.tmp -MT $@ -c -o $@ crypto/dso/dso_win32.c
+	@touch crypto/dso/dso_win32.d.tmp
+	@if cmp crypto/dso/dso_win32.d.tmp crypto/dso/dso_win32.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/dso/dso_win32.d.tmp; \
+	else \
+		mv crypto/dso/dso_win32.d.tmp crypto/dso/dso_win32.d; \
+	fi
+crypto/ebcdic.o: crypto/ebcdic.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ebcdic.d.tmp -MT $@ -c -o $@ crypto/ebcdic.c
+	@touch crypto/ebcdic.d.tmp
+	@if cmp crypto/ebcdic.d.tmp crypto/ebcdic.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ebcdic.d.tmp; \
+	else \
+		mv crypto/ebcdic.d.tmp crypto/ebcdic.d; \
+	fi
+crypto/ec/curve25519.o: crypto/ec/curve25519.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/curve25519.d.tmp -MT $@ -c -o $@ crypto/ec/curve25519.c
+	@touch crypto/ec/curve25519.d.tmp
+	@if cmp crypto/ec/curve25519.d.tmp crypto/ec/curve25519.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/curve25519.d.tmp; \
+	else \
+		mv crypto/ec/curve25519.d.tmp crypto/ec/curve25519.d; \
+	fi
+crypto/ec/ec2_mult.o: crypto/ec/ec2_mult.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ec2_mult.d.tmp -MT $@ -c -o $@ crypto/ec/ec2_mult.c
+	@touch crypto/ec/ec2_mult.d.tmp
+	@if cmp crypto/ec/ec2_mult.d.tmp crypto/ec/ec2_mult.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ec2_mult.d.tmp; \
+	else \
+		mv crypto/ec/ec2_mult.d.tmp crypto/ec/ec2_mult.d; \
+	fi
+crypto/ec/ec2_oct.o: crypto/ec/ec2_oct.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ec2_oct.d.tmp -MT $@ -c -o $@ crypto/ec/ec2_oct.c
+	@touch crypto/ec/ec2_oct.d.tmp
+	@if cmp crypto/ec/ec2_oct.d.tmp crypto/ec/ec2_oct.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ec2_oct.d.tmp; \
+	else \
+		mv crypto/ec/ec2_oct.d.tmp crypto/ec/ec2_oct.d; \
+	fi
+crypto/ec/ec2_smpl.o: crypto/ec/ec2_smpl.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ec2_smpl.d.tmp -MT $@ -c -o $@ crypto/ec/ec2_smpl.c
+	@touch crypto/ec/ec2_smpl.d.tmp
+	@if cmp crypto/ec/ec2_smpl.d.tmp crypto/ec/ec2_smpl.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ec2_smpl.d.tmp; \
+	else \
+		mv crypto/ec/ec2_smpl.d.tmp crypto/ec/ec2_smpl.d; \
+	fi
+crypto/ec/ec_ameth.o: crypto/ec/ec_ameth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ec_ameth.d.tmp -MT $@ -c -o $@ crypto/ec/ec_ameth.c
+	@touch crypto/ec/ec_ameth.d.tmp
+	@if cmp crypto/ec/ec_ameth.d.tmp crypto/ec/ec_ameth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ec_ameth.d.tmp; \
+	else \
+		mv crypto/ec/ec_ameth.d.tmp crypto/ec/ec_ameth.d; \
+	fi
+crypto/ec/ec_asn1.o: crypto/ec/ec_asn1.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ec_asn1.d.tmp -MT $@ -c -o $@ crypto/ec/ec_asn1.c
+	@touch crypto/ec/ec_asn1.d.tmp
+	@if cmp crypto/ec/ec_asn1.d.tmp crypto/ec/ec_asn1.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ec_asn1.d.tmp; \
+	else \
+		mv crypto/ec/ec_asn1.d.tmp crypto/ec/ec_asn1.d; \
+	fi
+crypto/ec/ec_check.o: crypto/ec/ec_check.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ec_check.d.tmp -MT $@ -c -o $@ crypto/ec/ec_check.c
+	@touch crypto/ec/ec_check.d.tmp
+	@if cmp crypto/ec/ec_check.d.tmp crypto/ec/ec_check.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ec_check.d.tmp; \
+	else \
+		mv crypto/ec/ec_check.d.tmp crypto/ec/ec_check.d; \
+	fi
+crypto/ec/ec_curve.o: crypto/ec/ec_curve.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ec_curve.d.tmp -MT $@ -c -o $@ crypto/ec/ec_curve.c
+	@touch crypto/ec/ec_curve.d.tmp
+	@if cmp crypto/ec/ec_curve.d.tmp crypto/ec/ec_curve.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ec_curve.d.tmp; \
+	else \
+		mv crypto/ec/ec_curve.d.tmp crypto/ec/ec_curve.d; \
+	fi
+crypto/ec/ec_cvt.o: crypto/ec/ec_cvt.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ec_cvt.d.tmp -MT $@ -c -o $@ crypto/ec/ec_cvt.c
+	@touch crypto/ec/ec_cvt.d.tmp
+	@if cmp crypto/ec/ec_cvt.d.tmp crypto/ec/ec_cvt.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ec_cvt.d.tmp; \
+	else \
+		mv crypto/ec/ec_cvt.d.tmp crypto/ec/ec_cvt.d; \
+	fi
+crypto/ec/ec_err.o: crypto/ec/ec_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ec_err.d.tmp -MT $@ -c -o $@ crypto/ec/ec_err.c
+	@touch crypto/ec/ec_err.d.tmp
+	@if cmp crypto/ec/ec_err.d.tmp crypto/ec/ec_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ec_err.d.tmp; \
+	else \
+		mv crypto/ec/ec_err.d.tmp crypto/ec/ec_err.d; \
+	fi
+crypto/ec/ec_key.o: crypto/ec/ec_key.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ec_key.d.tmp -MT $@ -c -o $@ crypto/ec/ec_key.c
+	@touch crypto/ec/ec_key.d.tmp
+	@if cmp crypto/ec/ec_key.d.tmp crypto/ec/ec_key.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ec_key.d.tmp; \
+	else \
+		mv crypto/ec/ec_key.d.tmp crypto/ec/ec_key.d; \
+	fi
+crypto/ec/ec_kmeth.o: crypto/ec/ec_kmeth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ec_kmeth.d.tmp -MT $@ -c -o $@ crypto/ec/ec_kmeth.c
+	@touch crypto/ec/ec_kmeth.d.tmp
+	@if cmp crypto/ec/ec_kmeth.d.tmp crypto/ec/ec_kmeth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ec_kmeth.d.tmp; \
+	else \
+		mv crypto/ec/ec_kmeth.d.tmp crypto/ec/ec_kmeth.d; \
+	fi
+crypto/ec/ec_lib.o: crypto/ec/ec_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ec_lib.d.tmp -MT $@ -c -o $@ crypto/ec/ec_lib.c
+	@touch crypto/ec/ec_lib.d.tmp
+	@if cmp crypto/ec/ec_lib.d.tmp crypto/ec/ec_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ec_lib.d.tmp; \
+	else \
+		mv crypto/ec/ec_lib.d.tmp crypto/ec/ec_lib.d; \
+	fi
+crypto/ec/ec_mult.o: crypto/ec/ec_mult.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ec_mult.d.tmp -MT $@ -c -o $@ crypto/ec/ec_mult.c
+	@touch crypto/ec/ec_mult.d.tmp
+	@if cmp crypto/ec/ec_mult.d.tmp crypto/ec/ec_mult.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ec_mult.d.tmp; \
+	else \
+		mv crypto/ec/ec_mult.d.tmp crypto/ec/ec_mult.d; \
+	fi
+crypto/ec/ec_oct.o: crypto/ec/ec_oct.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ec_oct.d.tmp -MT $@ -c -o $@ crypto/ec/ec_oct.c
+	@touch crypto/ec/ec_oct.d.tmp
+	@if cmp crypto/ec/ec_oct.d.tmp crypto/ec/ec_oct.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ec_oct.d.tmp; \
+	else \
+		mv crypto/ec/ec_oct.d.tmp crypto/ec/ec_oct.d; \
+	fi
+crypto/ec/ec_pmeth.o: crypto/ec/ec_pmeth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ec_pmeth.d.tmp -MT $@ -c -o $@ crypto/ec/ec_pmeth.c
+	@touch crypto/ec/ec_pmeth.d.tmp
+	@if cmp crypto/ec/ec_pmeth.d.tmp crypto/ec/ec_pmeth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ec_pmeth.d.tmp; \
+	else \
+		mv crypto/ec/ec_pmeth.d.tmp crypto/ec/ec_pmeth.d; \
+	fi
+crypto/ec/ec_print.o: crypto/ec/ec_print.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ec_print.d.tmp -MT $@ -c -o $@ crypto/ec/ec_print.c
+	@touch crypto/ec/ec_print.d.tmp
+	@if cmp crypto/ec/ec_print.d.tmp crypto/ec/ec_print.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ec_print.d.tmp; \
+	else \
+		mv crypto/ec/ec_print.d.tmp crypto/ec/ec_print.d; \
+	fi
+crypto/ec/ecdh_kdf.o: crypto/ec/ecdh_kdf.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ecdh_kdf.d.tmp -MT $@ -c -o $@ crypto/ec/ecdh_kdf.c
+	@touch crypto/ec/ecdh_kdf.d.tmp
+	@if cmp crypto/ec/ecdh_kdf.d.tmp crypto/ec/ecdh_kdf.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ecdh_kdf.d.tmp; \
+	else \
+		mv crypto/ec/ecdh_kdf.d.tmp crypto/ec/ecdh_kdf.d; \
+	fi
+crypto/ec/ecdh_ossl.o: crypto/ec/ecdh_ossl.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ecdh_ossl.d.tmp -MT $@ -c -o $@ crypto/ec/ecdh_ossl.c
+	@touch crypto/ec/ecdh_ossl.d.tmp
+	@if cmp crypto/ec/ecdh_ossl.d.tmp crypto/ec/ecdh_ossl.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ecdh_ossl.d.tmp; \
+	else \
+		mv crypto/ec/ecdh_ossl.d.tmp crypto/ec/ecdh_ossl.d; \
+	fi
+crypto/ec/ecdsa_ossl.o: crypto/ec/ecdsa_ossl.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ecdsa_ossl.d.tmp -MT $@ -c -o $@ crypto/ec/ecdsa_ossl.c
+	@touch crypto/ec/ecdsa_ossl.d.tmp
+	@if cmp crypto/ec/ecdsa_ossl.d.tmp crypto/ec/ecdsa_ossl.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ecdsa_ossl.d.tmp; \
+	else \
+		mv crypto/ec/ecdsa_ossl.d.tmp crypto/ec/ecdsa_ossl.d; \
+	fi
+crypto/ec/ecdsa_sign.o: crypto/ec/ecdsa_sign.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ecdsa_sign.d.tmp -MT $@ -c -o $@ crypto/ec/ecdsa_sign.c
+	@touch crypto/ec/ecdsa_sign.d.tmp
+	@if cmp crypto/ec/ecdsa_sign.d.tmp crypto/ec/ecdsa_sign.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ecdsa_sign.d.tmp; \
+	else \
+		mv crypto/ec/ecdsa_sign.d.tmp crypto/ec/ecdsa_sign.d; \
+	fi
+crypto/ec/ecdsa_vrf.o: crypto/ec/ecdsa_vrf.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ecdsa_vrf.d.tmp -MT $@ -c -o $@ crypto/ec/ecdsa_vrf.c
+	@touch crypto/ec/ecdsa_vrf.d.tmp
+	@if cmp crypto/ec/ecdsa_vrf.d.tmp crypto/ec/ecdsa_vrf.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ecdsa_vrf.d.tmp; \
+	else \
+		mv crypto/ec/ecdsa_vrf.d.tmp crypto/ec/ecdsa_vrf.d; \
+	fi
+crypto/ec/eck_prn.o: crypto/ec/eck_prn.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/eck_prn.d.tmp -MT $@ -c -o $@ crypto/ec/eck_prn.c
+	@touch crypto/ec/eck_prn.d.tmp
+	@if cmp crypto/ec/eck_prn.d.tmp crypto/ec/eck_prn.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/eck_prn.d.tmp; \
+	else \
+		mv crypto/ec/eck_prn.d.tmp crypto/ec/eck_prn.d; \
+	fi
+crypto/ec/ecp_mont.o: crypto/ec/ecp_mont.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ecp_mont.d.tmp -MT $@ -c -o $@ crypto/ec/ecp_mont.c
+	@touch crypto/ec/ecp_mont.d.tmp
+	@if cmp crypto/ec/ecp_mont.d.tmp crypto/ec/ecp_mont.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ecp_mont.d.tmp; \
+	else \
+		mv crypto/ec/ecp_mont.d.tmp crypto/ec/ecp_mont.d; \
+	fi
+crypto/ec/ecp_nist.o: crypto/ec/ecp_nist.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ecp_nist.d.tmp -MT $@ -c -o $@ crypto/ec/ecp_nist.c
+	@touch crypto/ec/ecp_nist.d.tmp
+	@if cmp crypto/ec/ecp_nist.d.tmp crypto/ec/ecp_nist.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ecp_nist.d.tmp; \
+	else \
+		mv crypto/ec/ecp_nist.d.tmp crypto/ec/ecp_nist.d; \
+	fi
+crypto/ec/ecp_nistp224.o: crypto/ec/ecp_nistp224.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ecp_nistp224.d.tmp -MT $@ -c -o $@ crypto/ec/ecp_nistp224.c
+	@touch crypto/ec/ecp_nistp224.d.tmp
+	@if cmp crypto/ec/ecp_nistp224.d.tmp crypto/ec/ecp_nistp224.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ecp_nistp224.d.tmp; \
+	else \
+		mv crypto/ec/ecp_nistp224.d.tmp crypto/ec/ecp_nistp224.d; \
+	fi
+crypto/ec/ecp_nistp256.o: crypto/ec/ecp_nistp256.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ecp_nistp256.d.tmp -MT $@ -c -o $@ crypto/ec/ecp_nistp256.c
+	@touch crypto/ec/ecp_nistp256.d.tmp
+	@if cmp crypto/ec/ecp_nistp256.d.tmp crypto/ec/ecp_nistp256.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ecp_nistp256.d.tmp; \
+	else \
+		mv crypto/ec/ecp_nistp256.d.tmp crypto/ec/ecp_nistp256.d; \
+	fi
+crypto/ec/ecp_nistp521.o: crypto/ec/ecp_nistp521.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ecp_nistp521.d.tmp -MT $@ -c -o $@ crypto/ec/ecp_nistp521.c
+	@touch crypto/ec/ecp_nistp521.d.tmp
+	@if cmp crypto/ec/ecp_nistp521.d.tmp crypto/ec/ecp_nistp521.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ecp_nistp521.d.tmp; \
+	else \
+		mv crypto/ec/ecp_nistp521.d.tmp crypto/ec/ecp_nistp521.d; \
+	fi
+crypto/ec/ecp_nistputil.o: crypto/ec/ecp_nistputil.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ecp_nistputil.d.tmp -MT $@ -c -o $@ crypto/ec/ecp_nistputil.c
+	@touch crypto/ec/ecp_nistputil.d.tmp
+	@if cmp crypto/ec/ecp_nistputil.d.tmp crypto/ec/ecp_nistputil.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ecp_nistputil.d.tmp; \
+	else \
+		mv crypto/ec/ecp_nistputil.d.tmp crypto/ec/ecp_nistputil.d; \
+	fi
+crypto/ec/ecp_oct.o: crypto/ec/ecp_oct.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ecp_oct.d.tmp -MT $@ -c -o $@ crypto/ec/ecp_oct.c
+	@touch crypto/ec/ecp_oct.d.tmp
+	@if cmp crypto/ec/ecp_oct.d.tmp crypto/ec/ecp_oct.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ecp_oct.d.tmp; \
+	else \
+		mv crypto/ec/ecp_oct.d.tmp crypto/ec/ecp_oct.d; \
+	fi
+crypto/ec/ecp_smpl.o: crypto/ec/ecp_smpl.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ecp_smpl.d.tmp -MT $@ -c -o $@ crypto/ec/ecp_smpl.c
+	@touch crypto/ec/ecp_smpl.d.tmp
+	@if cmp crypto/ec/ecp_smpl.d.tmp crypto/ec/ecp_smpl.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ecp_smpl.d.tmp; \
+	else \
+		mv crypto/ec/ecp_smpl.d.tmp crypto/ec/ecp_smpl.d; \
+	fi
+crypto/ec/ecx_meth.o: crypto/ec/ecx_meth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ec/ecx_meth.d.tmp -MT $@ -c -o $@ crypto/ec/ecx_meth.c
+	@touch crypto/ec/ecx_meth.d.tmp
+	@if cmp crypto/ec/ecx_meth.d.tmp crypto/ec/ecx_meth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ec/ecx_meth.d.tmp; \
+	else \
+		mv crypto/ec/ecx_meth.d.tmp crypto/ec/ecx_meth.d; \
+	fi
+crypto/engine/eng_all.o: crypto/engine/eng_all.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/eng_all.d.tmp -MT $@ -c -o $@ crypto/engine/eng_all.c
+	@touch crypto/engine/eng_all.d.tmp
+	@if cmp crypto/engine/eng_all.d.tmp crypto/engine/eng_all.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/eng_all.d.tmp; \
+	else \
+		mv crypto/engine/eng_all.d.tmp crypto/engine/eng_all.d; \
+	fi
+crypto/engine/eng_cnf.o: crypto/engine/eng_cnf.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/eng_cnf.d.tmp -MT $@ -c -o $@ crypto/engine/eng_cnf.c
+	@touch crypto/engine/eng_cnf.d.tmp
+	@if cmp crypto/engine/eng_cnf.d.tmp crypto/engine/eng_cnf.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/eng_cnf.d.tmp; \
+	else \
+		mv crypto/engine/eng_cnf.d.tmp crypto/engine/eng_cnf.d; \
+	fi
+crypto/engine/eng_cryptodev.o: crypto/engine/eng_cryptodev.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/eng_cryptodev.d.tmp -MT $@ -c -o $@ crypto/engine/eng_cryptodev.c
+	@touch crypto/engine/eng_cryptodev.d.tmp
+	@if cmp crypto/engine/eng_cryptodev.d.tmp crypto/engine/eng_cryptodev.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/eng_cryptodev.d.tmp; \
+	else \
+		mv crypto/engine/eng_cryptodev.d.tmp crypto/engine/eng_cryptodev.d; \
+	fi
+crypto/engine/eng_ctrl.o: crypto/engine/eng_ctrl.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/eng_ctrl.d.tmp -MT $@ -c -o $@ crypto/engine/eng_ctrl.c
+	@touch crypto/engine/eng_ctrl.d.tmp
+	@if cmp crypto/engine/eng_ctrl.d.tmp crypto/engine/eng_ctrl.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/eng_ctrl.d.tmp; \
+	else \
+		mv crypto/engine/eng_ctrl.d.tmp crypto/engine/eng_ctrl.d; \
+	fi
+crypto/engine/eng_dyn.o: crypto/engine/eng_dyn.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/eng_dyn.d.tmp -MT $@ -c -o $@ crypto/engine/eng_dyn.c
+	@touch crypto/engine/eng_dyn.d.tmp
+	@if cmp crypto/engine/eng_dyn.d.tmp crypto/engine/eng_dyn.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/eng_dyn.d.tmp; \
+	else \
+		mv crypto/engine/eng_dyn.d.tmp crypto/engine/eng_dyn.d; \
+	fi
+crypto/engine/eng_err.o: crypto/engine/eng_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/eng_err.d.tmp -MT $@ -c -o $@ crypto/engine/eng_err.c
+	@touch crypto/engine/eng_err.d.tmp
+	@if cmp crypto/engine/eng_err.d.tmp crypto/engine/eng_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/eng_err.d.tmp; \
+	else \
+		mv crypto/engine/eng_err.d.tmp crypto/engine/eng_err.d; \
+	fi
+crypto/engine/eng_fat.o: crypto/engine/eng_fat.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/eng_fat.d.tmp -MT $@ -c -o $@ crypto/engine/eng_fat.c
+	@touch crypto/engine/eng_fat.d.tmp
+	@if cmp crypto/engine/eng_fat.d.tmp crypto/engine/eng_fat.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/eng_fat.d.tmp; \
+	else \
+		mv crypto/engine/eng_fat.d.tmp crypto/engine/eng_fat.d; \
+	fi
+crypto/engine/eng_init.o: crypto/engine/eng_init.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/eng_init.d.tmp -MT $@ -c -o $@ crypto/engine/eng_init.c
+	@touch crypto/engine/eng_init.d.tmp
+	@if cmp crypto/engine/eng_init.d.tmp crypto/engine/eng_init.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/eng_init.d.tmp; \
+	else \
+		mv crypto/engine/eng_init.d.tmp crypto/engine/eng_init.d; \
+	fi
+crypto/engine/eng_lib.o: crypto/engine/eng_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/eng_lib.d.tmp -MT $@ -c -o $@ crypto/engine/eng_lib.c
+	@touch crypto/engine/eng_lib.d.tmp
+	@if cmp crypto/engine/eng_lib.d.tmp crypto/engine/eng_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/eng_lib.d.tmp; \
+	else \
+		mv crypto/engine/eng_lib.d.tmp crypto/engine/eng_lib.d; \
+	fi
+crypto/engine/eng_list.o: crypto/engine/eng_list.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/eng_list.d.tmp -MT $@ -c -o $@ crypto/engine/eng_list.c
+	@touch crypto/engine/eng_list.d.tmp
+	@if cmp crypto/engine/eng_list.d.tmp crypto/engine/eng_list.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/eng_list.d.tmp; \
+	else \
+		mv crypto/engine/eng_list.d.tmp crypto/engine/eng_list.d; \
+	fi
+crypto/engine/eng_openssl.o: crypto/engine/eng_openssl.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/eng_openssl.d.tmp -MT $@ -c -o $@ crypto/engine/eng_openssl.c
+	@touch crypto/engine/eng_openssl.d.tmp
+	@if cmp crypto/engine/eng_openssl.d.tmp crypto/engine/eng_openssl.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/eng_openssl.d.tmp; \
+	else \
+		mv crypto/engine/eng_openssl.d.tmp crypto/engine/eng_openssl.d; \
+	fi
+crypto/engine/eng_pkey.o: crypto/engine/eng_pkey.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/eng_pkey.d.tmp -MT $@ -c -o $@ crypto/engine/eng_pkey.c
+	@touch crypto/engine/eng_pkey.d.tmp
+	@if cmp crypto/engine/eng_pkey.d.tmp crypto/engine/eng_pkey.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/eng_pkey.d.tmp; \
+	else \
+		mv crypto/engine/eng_pkey.d.tmp crypto/engine/eng_pkey.d; \
+	fi
+crypto/engine/eng_rdrand.o: crypto/engine/eng_rdrand.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/eng_rdrand.d.tmp -MT $@ -c -o $@ crypto/engine/eng_rdrand.c
+	@touch crypto/engine/eng_rdrand.d.tmp
+	@if cmp crypto/engine/eng_rdrand.d.tmp crypto/engine/eng_rdrand.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/eng_rdrand.d.tmp; \
+	else \
+		mv crypto/engine/eng_rdrand.d.tmp crypto/engine/eng_rdrand.d; \
+	fi
+crypto/engine/eng_table.o: crypto/engine/eng_table.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/eng_table.d.tmp -MT $@ -c -o $@ crypto/engine/eng_table.c
+	@touch crypto/engine/eng_table.d.tmp
+	@if cmp crypto/engine/eng_table.d.tmp crypto/engine/eng_table.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/eng_table.d.tmp; \
+	else \
+		mv crypto/engine/eng_table.d.tmp crypto/engine/eng_table.d; \
+	fi
+crypto/engine/tb_asnmth.o: crypto/engine/tb_asnmth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/tb_asnmth.d.tmp -MT $@ -c -o $@ crypto/engine/tb_asnmth.c
+	@touch crypto/engine/tb_asnmth.d.tmp
+	@if cmp crypto/engine/tb_asnmth.d.tmp crypto/engine/tb_asnmth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/tb_asnmth.d.tmp; \
+	else \
+		mv crypto/engine/tb_asnmth.d.tmp crypto/engine/tb_asnmth.d; \
+	fi
+crypto/engine/tb_cipher.o: crypto/engine/tb_cipher.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/tb_cipher.d.tmp -MT $@ -c -o $@ crypto/engine/tb_cipher.c
+	@touch crypto/engine/tb_cipher.d.tmp
+	@if cmp crypto/engine/tb_cipher.d.tmp crypto/engine/tb_cipher.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/tb_cipher.d.tmp; \
+	else \
+		mv crypto/engine/tb_cipher.d.tmp crypto/engine/tb_cipher.d; \
+	fi
+crypto/engine/tb_dh.o: crypto/engine/tb_dh.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/tb_dh.d.tmp -MT $@ -c -o $@ crypto/engine/tb_dh.c
+	@touch crypto/engine/tb_dh.d.tmp
+	@if cmp crypto/engine/tb_dh.d.tmp crypto/engine/tb_dh.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/tb_dh.d.tmp; \
+	else \
+		mv crypto/engine/tb_dh.d.tmp crypto/engine/tb_dh.d; \
+	fi
+crypto/engine/tb_digest.o: crypto/engine/tb_digest.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/tb_digest.d.tmp -MT $@ -c -o $@ crypto/engine/tb_digest.c
+	@touch crypto/engine/tb_digest.d.tmp
+	@if cmp crypto/engine/tb_digest.d.tmp crypto/engine/tb_digest.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/tb_digest.d.tmp; \
+	else \
+		mv crypto/engine/tb_digest.d.tmp crypto/engine/tb_digest.d; \
+	fi
+crypto/engine/tb_dsa.o: crypto/engine/tb_dsa.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/tb_dsa.d.tmp -MT $@ -c -o $@ crypto/engine/tb_dsa.c
+	@touch crypto/engine/tb_dsa.d.tmp
+	@if cmp crypto/engine/tb_dsa.d.tmp crypto/engine/tb_dsa.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/tb_dsa.d.tmp; \
+	else \
+		mv crypto/engine/tb_dsa.d.tmp crypto/engine/tb_dsa.d; \
+	fi
+crypto/engine/tb_eckey.o: crypto/engine/tb_eckey.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/tb_eckey.d.tmp -MT $@ -c -o $@ crypto/engine/tb_eckey.c
+	@touch crypto/engine/tb_eckey.d.tmp
+	@if cmp crypto/engine/tb_eckey.d.tmp crypto/engine/tb_eckey.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/tb_eckey.d.tmp; \
+	else \
+		mv crypto/engine/tb_eckey.d.tmp crypto/engine/tb_eckey.d; \
+	fi
+crypto/engine/tb_pkmeth.o: crypto/engine/tb_pkmeth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/tb_pkmeth.d.tmp -MT $@ -c -o $@ crypto/engine/tb_pkmeth.c
+	@touch crypto/engine/tb_pkmeth.d.tmp
+	@if cmp crypto/engine/tb_pkmeth.d.tmp crypto/engine/tb_pkmeth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/tb_pkmeth.d.tmp; \
+	else \
+		mv crypto/engine/tb_pkmeth.d.tmp crypto/engine/tb_pkmeth.d; \
+	fi
+crypto/engine/tb_rand.o: crypto/engine/tb_rand.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/tb_rand.d.tmp -MT $@ -c -o $@ crypto/engine/tb_rand.c
+	@touch crypto/engine/tb_rand.d.tmp
+	@if cmp crypto/engine/tb_rand.d.tmp crypto/engine/tb_rand.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/tb_rand.d.tmp; \
+	else \
+		mv crypto/engine/tb_rand.d.tmp crypto/engine/tb_rand.d; \
+	fi
+crypto/engine/tb_rsa.o: crypto/engine/tb_rsa.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/engine/tb_rsa.d.tmp -MT $@ -c -o $@ crypto/engine/tb_rsa.c
+	@touch crypto/engine/tb_rsa.d.tmp
+	@if cmp crypto/engine/tb_rsa.d.tmp crypto/engine/tb_rsa.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/engine/tb_rsa.d.tmp; \
+	else \
+		mv crypto/engine/tb_rsa.d.tmp crypto/engine/tb_rsa.d; \
+	fi
+crypto/err/err.o: crypto/err/err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/err/err.d.tmp -MT $@ -c -o $@ crypto/err/err.c
+	@touch crypto/err/err.d.tmp
+	@if cmp crypto/err/err.d.tmp crypto/err/err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/err/err.d.tmp; \
+	else \
+		mv crypto/err/err.d.tmp crypto/err/err.d; \
+	fi
+crypto/err/err_all.o: crypto/err/err_all.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/err/err_all.d.tmp -MT $@ -c -o $@ crypto/err/err_all.c
+	@touch crypto/err/err_all.d.tmp
+	@if cmp crypto/err/err_all.d.tmp crypto/err/err_all.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/err/err_all.d.tmp; \
+	else \
+		mv crypto/err/err_all.d.tmp crypto/err/err_all.d; \
+	fi
+crypto/err/err_prn.o: crypto/err/err_prn.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/err/err_prn.d.tmp -MT $@ -c -o $@ crypto/err/err_prn.c
+	@touch crypto/err/err_prn.d.tmp
+	@if cmp crypto/err/err_prn.d.tmp crypto/err/err_prn.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/err/err_prn.d.tmp; \
+	else \
+		mv crypto/err/err_prn.d.tmp crypto/err/err_prn.d; \
+	fi
+crypto/evp/bio_b64.o: crypto/evp/bio_b64.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/bio_b64.d.tmp -MT $@ -c -o $@ crypto/evp/bio_b64.c
+	@touch crypto/evp/bio_b64.d.tmp
+	@if cmp crypto/evp/bio_b64.d.tmp crypto/evp/bio_b64.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/bio_b64.d.tmp; \
+	else \
+		mv crypto/evp/bio_b64.d.tmp crypto/evp/bio_b64.d; \
+	fi
+crypto/evp/bio_enc.o: crypto/evp/bio_enc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/bio_enc.d.tmp -MT $@ -c -o $@ crypto/evp/bio_enc.c
+	@touch crypto/evp/bio_enc.d.tmp
+	@if cmp crypto/evp/bio_enc.d.tmp crypto/evp/bio_enc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/bio_enc.d.tmp; \
+	else \
+		mv crypto/evp/bio_enc.d.tmp crypto/evp/bio_enc.d; \
+	fi
+crypto/evp/bio_md.o: crypto/evp/bio_md.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/bio_md.d.tmp -MT $@ -c -o $@ crypto/evp/bio_md.c
+	@touch crypto/evp/bio_md.d.tmp
+	@if cmp crypto/evp/bio_md.d.tmp crypto/evp/bio_md.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/bio_md.d.tmp; \
+	else \
+		mv crypto/evp/bio_md.d.tmp crypto/evp/bio_md.d; \
+	fi
+crypto/evp/bio_ok.o: crypto/evp/bio_ok.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/bio_ok.d.tmp -MT $@ -c -o $@ crypto/evp/bio_ok.c
+	@touch crypto/evp/bio_ok.d.tmp
+	@if cmp crypto/evp/bio_ok.d.tmp crypto/evp/bio_ok.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/bio_ok.d.tmp; \
+	else \
+		mv crypto/evp/bio_ok.d.tmp crypto/evp/bio_ok.d; \
+	fi
+crypto/evp/c_allc.o: crypto/evp/c_allc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/c_allc.d.tmp -MT $@ -c -o $@ crypto/evp/c_allc.c
+	@touch crypto/evp/c_allc.d.tmp
+	@if cmp crypto/evp/c_allc.d.tmp crypto/evp/c_allc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/c_allc.d.tmp; \
+	else \
+		mv crypto/evp/c_allc.d.tmp crypto/evp/c_allc.d; \
+	fi
+crypto/evp/c_alld.o: crypto/evp/c_alld.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/c_alld.d.tmp -MT $@ -c -o $@ crypto/evp/c_alld.c
+	@touch crypto/evp/c_alld.d.tmp
+	@if cmp crypto/evp/c_alld.d.tmp crypto/evp/c_alld.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/c_alld.d.tmp; \
+	else \
+		mv crypto/evp/c_alld.d.tmp crypto/evp/c_alld.d; \
+	fi
+crypto/evp/cmeth_lib.o: crypto/evp/cmeth_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/cmeth_lib.d.tmp -MT $@ -c -o $@ crypto/evp/cmeth_lib.c
+	@touch crypto/evp/cmeth_lib.d.tmp
+	@if cmp crypto/evp/cmeth_lib.d.tmp crypto/evp/cmeth_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/cmeth_lib.d.tmp; \
+	else \
+		mv crypto/evp/cmeth_lib.d.tmp crypto/evp/cmeth_lib.d; \
+	fi
+crypto/evp/digest.o: crypto/evp/digest.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/digest.d.tmp -MT $@ -c -o $@ crypto/evp/digest.c
+	@touch crypto/evp/digest.d.tmp
+	@if cmp crypto/evp/digest.d.tmp crypto/evp/digest.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/digest.d.tmp; \
+	else \
+		mv crypto/evp/digest.d.tmp crypto/evp/digest.d; \
+	fi
+crypto/evp/e_aes.o: crypto/evp/e_aes.c
+	$(CC)  -I. -Icrypto/include -Iinclude -Icrypto -Icrypto/modes $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/e_aes.d.tmp -MT $@ -c -o $@ crypto/evp/e_aes.c
+	@touch crypto/evp/e_aes.d.tmp
+	@if cmp crypto/evp/e_aes.d.tmp crypto/evp/e_aes.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/e_aes.d.tmp; \
+	else \
+		mv crypto/evp/e_aes.d.tmp crypto/evp/e_aes.d; \
+	fi
+crypto/evp/e_aes_cbc_hmac_sha1.o: crypto/evp/e_aes_cbc_hmac_sha1.c
+	$(CC)  -I. -Icrypto/include -Iinclude -Icrypto/modes $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/e_aes_cbc_hmac_sha1.d.tmp -MT $@ -c -o $@ crypto/evp/e_aes_cbc_hmac_sha1.c
+	@touch crypto/evp/e_aes_cbc_hmac_sha1.d.tmp
+	@if cmp crypto/evp/e_aes_cbc_hmac_sha1.d.tmp crypto/evp/e_aes_cbc_hmac_sha1.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/e_aes_cbc_hmac_sha1.d.tmp; \
+	else \
+		mv crypto/evp/e_aes_cbc_hmac_sha1.d.tmp crypto/evp/e_aes_cbc_hmac_sha1.d; \
+	fi
+crypto/evp/e_aes_cbc_hmac_sha256.o: crypto/evp/e_aes_cbc_hmac_sha256.c
+	$(CC)  -I. -Icrypto/include -Iinclude -Icrypto/modes $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/e_aes_cbc_hmac_sha256.d.tmp -MT $@ -c -o $@ crypto/evp/e_aes_cbc_hmac_sha256.c
+	@touch crypto/evp/e_aes_cbc_hmac_sha256.d.tmp
+	@if cmp crypto/evp/e_aes_cbc_hmac_sha256.d.tmp crypto/evp/e_aes_cbc_hmac_sha256.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/e_aes_cbc_hmac_sha256.d.tmp; \
+	else \
+		mv crypto/evp/e_aes_cbc_hmac_sha256.d.tmp crypto/evp/e_aes_cbc_hmac_sha256.d; \
+	fi
+crypto/evp/e_bf.o: crypto/evp/e_bf.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/e_bf.d.tmp -MT $@ -c -o $@ crypto/evp/e_bf.c
+	@touch crypto/evp/e_bf.d.tmp
+	@if cmp crypto/evp/e_bf.d.tmp crypto/evp/e_bf.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/e_bf.d.tmp; \
+	else \
+		mv crypto/evp/e_bf.d.tmp crypto/evp/e_bf.d; \
+	fi
+crypto/evp/e_camellia.o: crypto/evp/e_camellia.c
+	$(CC)  -I. -Icrypto/include -Iinclude -Icrypto -Icrypto/modes $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/e_camellia.d.tmp -MT $@ -c -o $@ crypto/evp/e_camellia.c
+	@touch crypto/evp/e_camellia.d.tmp
+	@if cmp crypto/evp/e_camellia.d.tmp crypto/evp/e_camellia.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/e_camellia.d.tmp; \
+	else \
+		mv crypto/evp/e_camellia.d.tmp crypto/evp/e_camellia.d; \
+	fi
+crypto/evp/e_cast.o: crypto/evp/e_cast.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/e_cast.d.tmp -MT $@ -c -o $@ crypto/evp/e_cast.c
+	@touch crypto/evp/e_cast.d.tmp
+	@if cmp crypto/evp/e_cast.d.tmp crypto/evp/e_cast.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/e_cast.d.tmp; \
+	else \
+		mv crypto/evp/e_cast.d.tmp crypto/evp/e_cast.d; \
+	fi
+crypto/evp/e_chacha20_poly1305.o: crypto/evp/e_chacha20_poly1305.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/e_chacha20_poly1305.d.tmp -MT $@ -c -o $@ crypto/evp/e_chacha20_poly1305.c
+	@touch crypto/evp/e_chacha20_poly1305.d.tmp
+	@if cmp crypto/evp/e_chacha20_poly1305.d.tmp crypto/evp/e_chacha20_poly1305.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/e_chacha20_poly1305.d.tmp; \
+	else \
+		mv crypto/evp/e_chacha20_poly1305.d.tmp crypto/evp/e_chacha20_poly1305.d; \
+	fi
+crypto/evp/e_des.o: crypto/evp/e_des.c
+	$(CC)  -I. -Icrypto/include -Iinclude -Icrypto $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/e_des.d.tmp -MT $@ -c -o $@ crypto/evp/e_des.c
+	@touch crypto/evp/e_des.d.tmp
+	@if cmp crypto/evp/e_des.d.tmp crypto/evp/e_des.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/e_des.d.tmp; \
+	else \
+		mv crypto/evp/e_des.d.tmp crypto/evp/e_des.d; \
+	fi
+crypto/evp/e_des3.o: crypto/evp/e_des3.c
+	$(CC)  -I. -Icrypto/include -Iinclude -Icrypto $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/e_des3.d.tmp -MT $@ -c -o $@ crypto/evp/e_des3.c
+	@touch crypto/evp/e_des3.d.tmp
+	@if cmp crypto/evp/e_des3.d.tmp crypto/evp/e_des3.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/e_des3.d.tmp; \
+	else \
+		mv crypto/evp/e_des3.d.tmp crypto/evp/e_des3.d; \
+	fi
+crypto/evp/e_idea.o: crypto/evp/e_idea.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/e_idea.d.tmp -MT $@ -c -o $@ crypto/evp/e_idea.c
+	@touch crypto/evp/e_idea.d.tmp
+	@if cmp crypto/evp/e_idea.d.tmp crypto/evp/e_idea.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/e_idea.d.tmp; \
+	else \
+		mv crypto/evp/e_idea.d.tmp crypto/evp/e_idea.d; \
+	fi
+crypto/evp/e_null.o: crypto/evp/e_null.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/e_null.d.tmp -MT $@ -c -o $@ crypto/evp/e_null.c
+	@touch crypto/evp/e_null.d.tmp
+	@if cmp crypto/evp/e_null.d.tmp crypto/evp/e_null.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/e_null.d.tmp; \
+	else \
+		mv crypto/evp/e_null.d.tmp crypto/evp/e_null.d; \
+	fi
+crypto/evp/e_old.o: crypto/evp/e_old.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/e_old.d.tmp -MT $@ -c -o $@ crypto/evp/e_old.c
+	@touch crypto/evp/e_old.d.tmp
+	@if cmp crypto/evp/e_old.d.tmp crypto/evp/e_old.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/e_old.d.tmp; \
+	else \
+		mv crypto/evp/e_old.d.tmp crypto/evp/e_old.d; \
+	fi
+crypto/evp/e_rc2.o: crypto/evp/e_rc2.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/e_rc2.d.tmp -MT $@ -c -o $@ crypto/evp/e_rc2.c
+	@touch crypto/evp/e_rc2.d.tmp
+	@if cmp crypto/evp/e_rc2.d.tmp crypto/evp/e_rc2.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/e_rc2.d.tmp; \
+	else \
+		mv crypto/evp/e_rc2.d.tmp crypto/evp/e_rc2.d; \
+	fi
+crypto/evp/e_rc4.o: crypto/evp/e_rc4.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/e_rc4.d.tmp -MT $@ -c -o $@ crypto/evp/e_rc4.c
+	@touch crypto/evp/e_rc4.d.tmp
+	@if cmp crypto/evp/e_rc4.d.tmp crypto/evp/e_rc4.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/e_rc4.d.tmp; \
+	else \
+		mv crypto/evp/e_rc4.d.tmp crypto/evp/e_rc4.d; \
+	fi
+crypto/evp/e_rc4_hmac_md5.o: crypto/evp/e_rc4_hmac_md5.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/e_rc4_hmac_md5.d.tmp -MT $@ -c -o $@ crypto/evp/e_rc4_hmac_md5.c
+	@touch crypto/evp/e_rc4_hmac_md5.d.tmp
+	@if cmp crypto/evp/e_rc4_hmac_md5.d.tmp crypto/evp/e_rc4_hmac_md5.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/e_rc4_hmac_md5.d.tmp; \
+	else \
+		mv crypto/evp/e_rc4_hmac_md5.d.tmp crypto/evp/e_rc4_hmac_md5.d; \
+	fi
+crypto/evp/e_rc5.o: crypto/evp/e_rc5.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/e_rc5.d.tmp -MT $@ -c -o $@ crypto/evp/e_rc5.c
+	@touch crypto/evp/e_rc5.d.tmp
+	@if cmp crypto/evp/e_rc5.d.tmp crypto/evp/e_rc5.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/e_rc5.d.tmp; \
+	else \
+		mv crypto/evp/e_rc5.d.tmp crypto/evp/e_rc5.d; \
+	fi
+crypto/evp/e_seed.o: crypto/evp/e_seed.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/e_seed.d.tmp -MT $@ -c -o $@ crypto/evp/e_seed.c
+	@touch crypto/evp/e_seed.d.tmp
+	@if cmp crypto/evp/e_seed.d.tmp crypto/evp/e_seed.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/e_seed.d.tmp; \
+	else \
+		mv crypto/evp/e_seed.d.tmp crypto/evp/e_seed.d; \
+	fi
+crypto/evp/e_xcbc_d.o: crypto/evp/e_xcbc_d.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/e_xcbc_d.d.tmp -MT $@ -c -o $@ crypto/evp/e_xcbc_d.c
+	@touch crypto/evp/e_xcbc_d.d.tmp
+	@if cmp crypto/evp/e_xcbc_d.d.tmp crypto/evp/e_xcbc_d.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/e_xcbc_d.d.tmp; \
+	else \
+		mv crypto/evp/e_xcbc_d.d.tmp crypto/evp/e_xcbc_d.d; \
+	fi
+crypto/evp/encode.o: crypto/evp/encode.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/encode.d.tmp -MT $@ -c -o $@ crypto/evp/encode.c
+	@touch crypto/evp/encode.d.tmp
+	@if cmp crypto/evp/encode.d.tmp crypto/evp/encode.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/encode.d.tmp; \
+	else \
+		mv crypto/evp/encode.d.tmp crypto/evp/encode.d; \
+	fi
+crypto/evp/evp_cnf.o: crypto/evp/evp_cnf.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/evp_cnf.d.tmp -MT $@ -c -o $@ crypto/evp/evp_cnf.c
+	@touch crypto/evp/evp_cnf.d.tmp
+	@if cmp crypto/evp/evp_cnf.d.tmp crypto/evp/evp_cnf.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/evp_cnf.d.tmp; \
+	else \
+		mv crypto/evp/evp_cnf.d.tmp crypto/evp/evp_cnf.d; \
+	fi
+crypto/evp/evp_enc.o: crypto/evp/evp_enc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/evp_enc.d.tmp -MT $@ -c -o $@ crypto/evp/evp_enc.c
+	@touch crypto/evp/evp_enc.d.tmp
+	@if cmp crypto/evp/evp_enc.d.tmp crypto/evp/evp_enc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/evp_enc.d.tmp; \
+	else \
+		mv crypto/evp/evp_enc.d.tmp crypto/evp/evp_enc.d; \
+	fi
+crypto/evp/evp_err.o: crypto/evp/evp_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/evp_err.d.tmp -MT $@ -c -o $@ crypto/evp/evp_err.c
+	@touch crypto/evp/evp_err.d.tmp
+	@if cmp crypto/evp/evp_err.d.tmp crypto/evp/evp_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/evp_err.d.tmp; \
+	else \
+		mv crypto/evp/evp_err.d.tmp crypto/evp/evp_err.d; \
+	fi
+crypto/evp/evp_key.o: crypto/evp/evp_key.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/evp_key.d.tmp -MT $@ -c -o $@ crypto/evp/evp_key.c
+	@touch crypto/evp/evp_key.d.tmp
+	@if cmp crypto/evp/evp_key.d.tmp crypto/evp/evp_key.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/evp_key.d.tmp; \
+	else \
+		mv crypto/evp/evp_key.d.tmp crypto/evp/evp_key.d; \
+	fi
+crypto/evp/evp_lib.o: crypto/evp/evp_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/evp_lib.d.tmp -MT $@ -c -o $@ crypto/evp/evp_lib.c
+	@touch crypto/evp/evp_lib.d.tmp
+	@if cmp crypto/evp/evp_lib.d.tmp crypto/evp/evp_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/evp_lib.d.tmp; \
+	else \
+		mv crypto/evp/evp_lib.d.tmp crypto/evp/evp_lib.d; \
+	fi
+crypto/evp/evp_pbe.o: crypto/evp/evp_pbe.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/evp_pbe.d.tmp -MT $@ -c -o $@ crypto/evp/evp_pbe.c
+	@touch crypto/evp/evp_pbe.d.tmp
+	@if cmp crypto/evp/evp_pbe.d.tmp crypto/evp/evp_pbe.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/evp_pbe.d.tmp; \
+	else \
+		mv crypto/evp/evp_pbe.d.tmp crypto/evp/evp_pbe.d; \
+	fi
+crypto/evp/evp_pkey.o: crypto/evp/evp_pkey.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/evp_pkey.d.tmp -MT $@ -c -o $@ crypto/evp/evp_pkey.c
+	@touch crypto/evp/evp_pkey.d.tmp
+	@if cmp crypto/evp/evp_pkey.d.tmp crypto/evp/evp_pkey.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/evp_pkey.d.tmp; \
+	else \
+		mv crypto/evp/evp_pkey.d.tmp crypto/evp/evp_pkey.d; \
+	fi
+crypto/evp/m_md2.o: crypto/evp/m_md2.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/m_md2.d.tmp -MT $@ -c -o $@ crypto/evp/m_md2.c
+	@touch crypto/evp/m_md2.d.tmp
+	@if cmp crypto/evp/m_md2.d.tmp crypto/evp/m_md2.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/m_md2.d.tmp; \
+	else \
+		mv crypto/evp/m_md2.d.tmp crypto/evp/m_md2.d; \
+	fi
+crypto/evp/m_md4.o: crypto/evp/m_md4.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/m_md4.d.tmp -MT $@ -c -o $@ crypto/evp/m_md4.c
+	@touch crypto/evp/m_md4.d.tmp
+	@if cmp crypto/evp/m_md4.d.tmp crypto/evp/m_md4.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/m_md4.d.tmp; \
+	else \
+		mv crypto/evp/m_md4.d.tmp crypto/evp/m_md4.d; \
+	fi
+crypto/evp/m_md5.o: crypto/evp/m_md5.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/m_md5.d.tmp -MT $@ -c -o $@ crypto/evp/m_md5.c
+	@touch crypto/evp/m_md5.d.tmp
+	@if cmp crypto/evp/m_md5.d.tmp crypto/evp/m_md5.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/m_md5.d.tmp; \
+	else \
+		mv crypto/evp/m_md5.d.tmp crypto/evp/m_md5.d; \
+	fi
+crypto/evp/m_md5_sha1.o: crypto/evp/m_md5_sha1.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/m_md5_sha1.d.tmp -MT $@ -c -o $@ crypto/evp/m_md5_sha1.c
+	@touch crypto/evp/m_md5_sha1.d.tmp
+	@if cmp crypto/evp/m_md5_sha1.d.tmp crypto/evp/m_md5_sha1.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/m_md5_sha1.d.tmp; \
+	else \
+		mv crypto/evp/m_md5_sha1.d.tmp crypto/evp/m_md5_sha1.d; \
+	fi
+crypto/evp/m_mdc2.o: crypto/evp/m_mdc2.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/m_mdc2.d.tmp -MT $@ -c -o $@ crypto/evp/m_mdc2.c
+	@touch crypto/evp/m_mdc2.d.tmp
+	@if cmp crypto/evp/m_mdc2.d.tmp crypto/evp/m_mdc2.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/m_mdc2.d.tmp; \
+	else \
+		mv crypto/evp/m_mdc2.d.tmp crypto/evp/m_mdc2.d; \
+	fi
+crypto/evp/m_null.o: crypto/evp/m_null.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/m_null.d.tmp -MT $@ -c -o $@ crypto/evp/m_null.c
+	@touch crypto/evp/m_null.d.tmp
+	@if cmp crypto/evp/m_null.d.tmp crypto/evp/m_null.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/m_null.d.tmp; \
+	else \
+		mv crypto/evp/m_null.d.tmp crypto/evp/m_null.d; \
+	fi
+crypto/evp/m_ripemd.o: crypto/evp/m_ripemd.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/m_ripemd.d.tmp -MT $@ -c -o $@ crypto/evp/m_ripemd.c
+	@touch crypto/evp/m_ripemd.d.tmp
+	@if cmp crypto/evp/m_ripemd.d.tmp crypto/evp/m_ripemd.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/m_ripemd.d.tmp; \
+	else \
+		mv crypto/evp/m_ripemd.d.tmp crypto/evp/m_ripemd.d; \
+	fi
+crypto/evp/m_sha1.o: crypto/evp/m_sha1.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/m_sha1.d.tmp -MT $@ -c -o $@ crypto/evp/m_sha1.c
+	@touch crypto/evp/m_sha1.d.tmp
+	@if cmp crypto/evp/m_sha1.d.tmp crypto/evp/m_sha1.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/m_sha1.d.tmp; \
+	else \
+		mv crypto/evp/m_sha1.d.tmp crypto/evp/m_sha1.d; \
+	fi
+crypto/evp/m_sigver.o: crypto/evp/m_sigver.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/m_sigver.d.tmp -MT $@ -c -o $@ crypto/evp/m_sigver.c
+	@touch crypto/evp/m_sigver.d.tmp
+	@if cmp crypto/evp/m_sigver.d.tmp crypto/evp/m_sigver.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/m_sigver.d.tmp; \
+	else \
+		mv crypto/evp/m_sigver.d.tmp crypto/evp/m_sigver.d; \
+	fi
+crypto/evp/m_wp.o: crypto/evp/m_wp.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/m_wp.d.tmp -MT $@ -c -o $@ crypto/evp/m_wp.c
+	@touch crypto/evp/m_wp.d.tmp
+	@if cmp crypto/evp/m_wp.d.tmp crypto/evp/m_wp.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/m_wp.d.tmp; \
+	else \
+		mv crypto/evp/m_wp.d.tmp crypto/evp/m_wp.d; \
+	fi
+crypto/evp/names.o: crypto/evp/names.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/names.d.tmp -MT $@ -c -o $@ crypto/evp/names.c
+	@touch crypto/evp/names.d.tmp
+	@if cmp crypto/evp/names.d.tmp crypto/evp/names.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/names.d.tmp; \
+	else \
+		mv crypto/evp/names.d.tmp crypto/evp/names.d; \
+	fi
+crypto/evp/p5_crpt.o: crypto/evp/p5_crpt.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/p5_crpt.d.tmp -MT $@ -c -o $@ crypto/evp/p5_crpt.c
+	@touch crypto/evp/p5_crpt.d.tmp
+	@if cmp crypto/evp/p5_crpt.d.tmp crypto/evp/p5_crpt.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/p5_crpt.d.tmp; \
+	else \
+		mv crypto/evp/p5_crpt.d.tmp crypto/evp/p5_crpt.d; \
+	fi
+crypto/evp/p5_crpt2.o: crypto/evp/p5_crpt2.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/p5_crpt2.d.tmp -MT $@ -c -o $@ crypto/evp/p5_crpt2.c
+	@touch crypto/evp/p5_crpt2.d.tmp
+	@if cmp crypto/evp/p5_crpt2.d.tmp crypto/evp/p5_crpt2.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/p5_crpt2.d.tmp; \
+	else \
+		mv crypto/evp/p5_crpt2.d.tmp crypto/evp/p5_crpt2.d; \
+	fi
+crypto/evp/p_dec.o: crypto/evp/p_dec.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/p_dec.d.tmp -MT $@ -c -o $@ crypto/evp/p_dec.c
+	@touch crypto/evp/p_dec.d.tmp
+	@if cmp crypto/evp/p_dec.d.tmp crypto/evp/p_dec.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/p_dec.d.tmp; \
+	else \
+		mv crypto/evp/p_dec.d.tmp crypto/evp/p_dec.d; \
+	fi
+crypto/evp/p_enc.o: crypto/evp/p_enc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/p_enc.d.tmp -MT $@ -c -o $@ crypto/evp/p_enc.c
+	@touch crypto/evp/p_enc.d.tmp
+	@if cmp crypto/evp/p_enc.d.tmp crypto/evp/p_enc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/p_enc.d.tmp; \
+	else \
+		mv crypto/evp/p_enc.d.tmp crypto/evp/p_enc.d; \
+	fi
+crypto/evp/p_lib.o: crypto/evp/p_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/p_lib.d.tmp -MT $@ -c -o $@ crypto/evp/p_lib.c
+	@touch crypto/evp/p_lib.d.tmp
+	@if cmp crypto/evp/p_lib.d.tmp crypto/evp/p_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/p_lib.d.tmp; \
+	else \
+		mv crypto/evp/p_lib.d.tmp crypto/evp/p_lib.d; \
+	fi
+crypto/evp/p_open.o: crypto/evp/p_open.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/p_open.d.tmp -MT $@ -c -o $@ crypto/evp/p_open.c
+	@touch crypto/evp/p_open.d.tmp
+	@if cmp crypto/evp/p_open.d.tmp crypto/evp/p_open.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/p_open.d.tmp; \
+	else \
+		mv crypto/evp/p_open.d.tmp crypto/evp/p_open.d; \
+	fi
+crypto/evp/p_seal.o: crypto/evp/p_seal.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/p_seal.d.tmp -MT $@ -c -o $@ crypto/evp/p_seal.c
+	@touch crypto/evp/p_seal.d.tmp
+	@if cmp crypto/evp/p_seal.d.tmp crypto/evp/p_seal.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/p_seal.d.tmp; \
+	else \
+		mv crypto/evp/p_seal.d.tmp crypto/evp/p_seal.d; \
+	fi
+crypto/evp/p_sign.o: crypto/evp/p_sign.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/p_sign.d.tmp -MT $@ -c -o $@ crypto/evp/p_sign.c
+	@touch crypto/evp/p_sign.d.tmp
+	@if cmp crypto/evp/p_sign.d.tmp crypto/evp/p_sign.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/p_sign.d.tmp; \
+	else \
+		mv crypto/evp/p_sign.d.tmp crypto/evp/p_sign.d; \
+	fi
+crypto/evp/p_verify.o: crypto/evp/p_verify.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/p_verify.d.tmp -MT $@ -c -o $@ crypto/evp/p_verify.c
+	@touch crypto/evp/p_verify.d.tmp
+	@if cmp crypto/evp/p_verify.d.tmp crypto/evp/p_verify.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/p_verify.d.tmp; \
+	else \
+		mv crypto/evp/p_verify.d.tmp crypto/evp/p_verify.d; \
+	fi
+crypto/evp/pmeth_fn.o: crypto/evp/pmeth_fn.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/pmeth_fn.d.tmp -MT $@ -c -o $@ crypto/evp/pmeth_fn.c
+	@touch crypto/evp/pmeth_fn.d.tmp
+	@if cmp crypto/evp/pmeth_fn.d.tmp crypto/evp/pmeth_fn.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/pmeth_fn.d.tmp; \
+	else \
+		mv crypto/evp/pmeth_fn.d.tmp crypto/evp/pmeth_fn.d; \
+	fi
+crypto/evp/pmeth_gn.o: crypto/evp/pmeth_gn.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/pmeth_gn.d.tmp -MT $@ -c -o $@ crypto/evp/pmeth_gn.c
+	@touch crypto/evp/pmeth_gn.d.tmp
+	@if cmp crypto/evp/pmeth_gn.d.tmp crypto/evp/pmeth_gn.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/pmeth_gn.d.tmp; \
+	else \
+		mv crypto/evp/pmeth_gn.d.tmp crypto/evp/pmeth_gn.d; \
+	fi
+crypto/evp/pmeth_lib.o: crypto/evp/pmeth_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/pmeth_lib.d.tmp -MT $@ -c -o $@ crypto/evp/pmeth_lib.c
+	@touch crypto/evp/pmeth_lib.d.tmp
+	@if cmp crypto/evp/pmeth_lib.d.tmp crypto/evp/pmeth_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/pmeth_lib.d.tmp; \
+	else \
+		mv crypto/evp/pmeth_lib.d.tmp crypto/evp/pmeth_lib.d; \
+	fi
+crypto/evp/scrypt.o: crypto/evp/scrypt.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/evp/scrypt.d.tmp -MT $@ -c -o $@ crypto/evp/scrypt.c
+	@touch crypto/evp/scrypt.d.tmp
+	@if cmp crypto/evp/scrypt.d.tmp crypto/evp/scrypt.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/evp/scrypt.d.tmp; \
+	else \
+		mv crypto/evp/scrypt.d.tmp crypto/evp/scrypt.d; \
+	fi
+crypto/ex_data.o: crypto/ex_data.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ex_data.d.tmp -MT $@ -c -o $@ crypto/ex_data.c
+	@touch crypto/ex_data.d.tmp
+	@if cmp crypto/ex_data.d.tmp crypto/ex_data.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ex_data.d.tmp; \
+	else \
+		mv crypto/ex_data.d.tmp crypto/ex_data.d; \
+	fi
+crypto/hmac/hm_ameth.o: crypto/hmac/hm_ameth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/hmac/hm_ameth.d.tmp -MT $@ -c -o $@ crypto/hmac/hm_ameth.c
+	@touch crypto/hmac/hm_ameth.d.tmp
+	@if cmp crypto/hmac/hm_ameth.d.tmp crypto/hmac/hm_ameth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/hmac/hm_ameth.d.tmp; \
+	else \
+		mv crypto/hmac/hm_ameth.d.tmp crypto/hmac/hm_ameth.d; \
+	fi
+crypto/hmac/hm_pmeth.o: crypto/hmac/hm_pmeth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/hmac/hm_pmeth.d.tmp -MT $@ -c -o $@ crypto/hmac/hm_pmeth.c
+	@touch crypto/hmac/hm_pmeth.d.tmp
+	@if cmp crypto/hmac/hm_pmeth.d.tmp crypto/hmac/hm_pmeth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/hmac/hm_pmeth.d.tmp; \
+	else \
+		mv crypto/hmac/hm_pmeth.d.tmp crypto/hmac/hm_pmeth.d; \
+	fi
+crypto/hmac/hmac.o: crypto/hmac/hmac.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/hmac/hmac.d.tmp -MT $@ -c -o $@ crypto/hmac/hmac.c
+	@touch crypto/hmac/hmac.d.tmp
+	@if cmp crypto/hmac/hmac.d.tmp crypto/hmac/hmac.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/hmac/hmac.d.tmp; \
+	else \
+		mv crypto/hmac/hmac.d.tmp crypto/hmac/hmac.d; \
+	fi
+crypto/idea/i_cbc.o: crypto/idea/i_cbc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/idea/i_cbc.d.tmp -MT $@ -c -o $@ crypto/idea/i_cbc.c
+	@touch crypto/idea/i_cbc.d.tmp
+	@if cmp crypto/idea/i_cbc.d.tmp crypto/idea/i_cbc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/idea/i_cbc.d.tmp; \
+	else \
+		mv crypto/idea/i_cbc.d.tmp crypto/idea/i_cbc.d; \
+	fi
+crypto/idea/i_cfb64.o: crypto/idea/i_cfb64.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/idea/i_cfb64.d.tmp -MT $@ -c -o $@ crypto/idea/i_cfb64.c
+	@touch crypto/idea/i_cfb64.d.tmp
+	@if cmp crypto/idea/i_cfb64.d.tmp crypto/idea/i_cfb64.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/idea/i_cfb64.d.tmp; \
+	else \
+		mv crypto/idea/i_cfb64.d.tmp crypto/idea/i_cfb64.d; \
+	fi
+crypto/idea/i_ecb.o: crypto/idea/i_ecb.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/idea/i_ecb.d.tmp -MT $@ -c -o $@ crypto/idea/i_ecb.c
+	@touch crypto/idea/i_ecb.d.tmp
+	@if cmp crypto/idea/i_ecb.d.tmp crypto/idea/i_ecb.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/idea/i_ecb.d.tmp; \
+	else \
+		mv crypto/idea/i_ecb.d.tmp crypto/idea/i_ecb.d; \
+	fi
+crypto/idea/i_ofb64.o: crypto/idea/i_ofb64.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/idea/i_ofb64.d.tmp -MT $@ -c -o $@ crypto/idea/i_ofb64.c
+	@touch crypto/idea/i_ofb64.d.tmp
+	@if cmp crypto/idea/i_ofb64.d.tmp crypto/idea/i_ofb64.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/idea/i_ofb64.d.tmp; \
+	else \
+		mv crypto/idea/i_ofb64.d.tmp crypto/idea/i_ofb64.d; \
+	fi
+crypto/idea/i_skey.o: crypto/idea/i_skey.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/idea/i_skey.d.tmp -MT $@ -c -o $@ crypto/idea/i_skey.c
+	@touch crypto/idea/i_skey.d.tmp
+	@if cmp crypto/idea/i_skey.d.tmp crypto/idea/i_skey.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/idea/i_skey.d.tmp; \
+	else \
+		mv crypto/idea/i_skey.d.tmp crypto/idea/i_skey.d; \
+	fi
+crypto/init.o: crypto/init.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/init.d.tmp -MT $@ -c -o $@ crypto/init.c
+	@touch crypto/init.d.tmp
+	@if cmp crypto/init.d.tmp crypto/init.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/init.d.tmp; \
+	else \
+		mv crypto/init.d.tmp crypto/init.d; \
+	fi
+crypto/kdf/hkdf.o: crypto/kdf/hkdf.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/kdf/hkdf.d.tmp -MT $@ -c -o $@ crypto/kdf/hkdf.c
+	@touch crypto/kdf/hkdf.d.tmp
+	@if cmp crypto/kdf/hkdf.d.tmp crypto/kdf/hkdf.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/kdf/hkdf.d.tmp; \
+	else \
+		mv crypto/kdf/hkdf.d.tmp crypto/kdf/hkdf.d; \
+	fi
+crypto/kdf/kdf_err.o: crypto/kdf/kdf_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/kdf/kdf_err.d.tmp -MT $@ -c -o $@ crypto/kdf/kdf_err.c
+	@touch crypto/kdf/kdf_err.d.tmp
+	@if cmp crypto/kdf/kdf_err.d.tmp crypto/kdf/kdf_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/kdf/kdf_err.d.tmp; \
+	else \
+		mv crypto/kdf/kdf_err.d.tmp crypto/kdf/kdf_err.d; \
+	fi
+crypto/kdf/tls1_prf.o: crypto/kdf/tls1_prf.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/kdf/tls1_prf.d.tmp -MT $@ -c -o $@ crypto/kdf/tls1_prf.c
+	@touch crypto/kdf/tls1_prf.d.tmp
+	@if cmp crypto/kdf/tls1_prf.d.tmp crypto/kdf/tls1_prf.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/kdf/tls1_prf.d.tmp; \
+	else \
+		mv crypto/kdf/tls1_prf.d.tmp crypto/kdf/tls1_prf.d; \
+	fi
+crypto/lhash/lh_stats.o: crypto/lhash/lh_stats.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/lhash/lh_stats.d.tmp -MT $@ -c -o $@ crypto/lhash/lh_stats.c
+	@touch crypto/lhash/lh_stats.d.tmp
+	@if cmp crypto/lhash/lh_stats.d.tmp crypto/lhash/lh_stats.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/lhash/lh_stats.d.tmp; \
+	else \
+		mv crypto/lhash/lh_stats.d.tmp crypto/lhash/lh_stats.d; \
+	fi
+crypto/lhash/lhash.o: crypto/lhash/lhash.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/lhash/lhash.d.tmp -MT $@ -c -o $@ crypto/lhash/lhash.c
+	@touch crypto/lhash/lhash.d.tmp
+	@if cmp crypto/lhash/lhash.d.tmp crypto/lhash/lhash.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/lhash/lhash.d.tmp; \
+	else \
+		mv crypto/lhash/lhash.d.tmp crypto/lhash/lhash.d; \
+	fi
+crypto/md4/md4_dgst.o: crypto/md4/md4_dgst.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/md4/md4_dgst.d.tmp -MT $@ -c -o $@ crypto/md4/md4_dgst.c
+	@touch crypto/md4/md4_dgst.d.tmp
+	@if cmp crypto/md4/md4_dgst.d.tmp crypto/md4/md4_dgst.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/md4/md4_dgst.d.tmp; \
+	else \
+		mv crypto/md4/md4_dgst.d.tmp crypto/md4/md4_dgst.d; \
+	fi
+crypto/md4/md4_one.o: crypto/md4/md4_one.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/md4/md4_one.d.tmp -MT $@ -c -o $@ crypto/md4/md4_one.c
+	@touch crypto/md4/md4_one.d.tmp
+	@if cmp crypto/md4/md4_one.d.tmp crypto/md4/md4_one.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/md4/md4_one.d.tmp; \
+	else \
+		mv crypto/md4/md4_one.d.tmp crypto/md4/md4_one.d; \
+	fi
+crypto/md5/md5_dgst.o: crypto/md5/md5_dgst.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/md5/md5_dgst.d.tmp -MT $@ -c -o $@ crypto/md5/md5_dgst.c
+	@touch crypto/md5/md5_dgst.d.tmp
+	@if cmp crypto/md5/md5_dgst.d.tmp crypto/md5/md5_dgst.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/md5/md5_dgst.d.tmp; \
+	else \
+		mv crypto/md5/md5_dgst.d.tmp crypto/md5/md5_dgst.d; \
+	fi
+crypto/md5/md5_one.o: crypto/md5/md5_one.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/md5/md5_one.d.tmp -MT $@ -c -o $@ crypto/md5/md5_one.c
+	@touch crypto/md5/md5_one.d.tmp
+	@if cmp crypto/md5/md5_one.d.tmp crypto/md5/md5_one.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/md5/md5_one.d.tmp; \
+	else \
+		mv crypto/md5/md5_one.d.tmp crypto/md5/md5_one.d; \
+	fi
+crypto/mdc2/mdc2_one.o: crypto/mdc2/mdc2_one.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/mdc2/mdc2_one.d.tmp -MT $@ -c -o $@ crypto/mdc2/mdc2_one.c
+	@touch crypto/mdc2/mdc2_one.d.tmp
+	@if cmp crypto/mdc2/mdc2_one.d.tmp crypto/mdc2/mdc2_one.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/mdc2/mdc2_one.d.tmp; \
+	else \
+		mv crypto/mdc2/mdc2_one.d.tmp crypto/mdc2/mdc2_one.d; \
+	fi
+crypto/mdc2/mdc2dgst.o: crypto/mdc2/mdc2dgst.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/mdc2/mdc2dgst.d.tmp -MT $@ -c -o $@ crypto/mdc2/mdc2dgst.c
+	@touch crypto/mdc2/mdc2dgst.d.tmp
+	@if cmp crypto/mdc2/mdc2dgst.d.tmp crypto/mdc2/mdc2dgst.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/mdc2/mdc2dgst.d.tmp; \
+	else \
+		mv crypto/mdc2/mdc2dgst.d.tmp crypto/mdc2/mdc2dgst.d; \
+	fi
+crypto/mem.o: crypto/mem.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/mem.d.tmp -MT $@ -c -o $@ crypto/mem.c
+	@touch crypto/mem.d.tmp
+	@if cmp crypto/mem.d.tmp crypto/mem.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/mem.d.tmp; \
+	else \
+		mv crypto/mem.d.tmp crypto/mem.d; \
+	fi
+crypto/mem_clr.o: crypto/mem_clr.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/mem_clr.d.tmp -MT $@ -c -o $@ crypto/mem_clr.c
+	@touch crypto/mem_clr.d.tmp
+	@if cmp crypto/mem_clr.d.tmp crypto/mem_clr.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/mem_clr.d.tmp; \
+	else \
+		mv crypto/mem_clr.d.tmp crypto/mem_clr.d; \
+	fi
+crypto/mem_dbg.o: crypto/mem_dbg.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/mem_dbg.d.tmp -MT $@ -c -o $@ crypto/mem_dbg.c
+	@touch crypto/mem_dbg.d.tmp
+	@if cmp crypto/mem_dbg.d.tmp crypto/mem_dbg.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/mem_dbg.d.tmp; \
+	else \
+		mv crypto/mem_dbg.d.tmp crypto/mem_dbg.d; \
+	fi
+crypto/mem_sec.o: crypto/mem_sec.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/mem_sec.d.tmp -MT $@ -c -o $@ crypto/mem_sec.c
+	@touch crypto/mem_sec.d.tmp
+	@if cmp crypto/mem_sec.d.tmp crypto/mem_sec.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/mem_sec.d.tmp; \
+	else \
+		mv crypto/mem_sec.d.tmp crypto/mem_sec.d; \
+	fi
+crypto/modes/cbc128.o: crypto/modes/cbc128.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/modes/cbc128.d.tmp -MT $@ -c -o $@ crypto/modes/cbc128.c
+	@touch crypto/modes/cbc128.d.tmp
+	@if cmp crypto/modes/cbc128.d.tmp crypto/modes/cbc128.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/modes/cbc128.d.tmp; \
+	else \
+		mv crypto/modes/cbc128.d.tmp crypto/modes/cbc128.d; \
+	fi
+crypto/modes/ccm128.o: crypto/modes/ccm128.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/modes/ccm128.d.tmp -MT $@ -c -o $@ crypto/modes/ccm128.c
+	@touch crypto/modes/ccm128.d.tmp
+	@if cmp crypto/modes/ccm128.d.tmp crypto/modes/ccm128.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/modes/ccm128.d.tmp; \
+	else \
+		mv crypto/modes/ccm128.d.tmp crypto/modes/ccm128.d; \
+	fi
+crypto/modes/cfb128.o: crypto/modes/cfb128.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/modes/cfb128.d.tmp -MT $@ -c -o $@ crypto/modes/cfb128.c
+	@touch crypto/modes/cfb128.d.tmp
+	@if cmp crypto/modes/cfb128.d.tmp crypto/modes/cfb128.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/modes/cfb128.d.tmp; \
+	else \
+		mv crypto/modes/cfb128.d.tmp crypto/modes/cfb128.d; \
+	fi
+crypto/modes/ctr128.o: crypto/modes/ctr128.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/modes/ctr128.d.tmp -MT $@ -c -o $@ crypto/modes/ctr128.c
+	@touch crypto/modes/ctr128.d.tmp
+	@if cmp crypto/modes/ctr128.d.tmp crypto/modes/ctr128.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/modes/ctr128.d.tmp; \
+	else \
+		mv crypto/modes/ctr128.d.tmp crypto/modes/ctr128.d; \
+	fi
+crypto/modes/cts128.o: crypto/modes/cts128.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/modes/cts128.d.tmp -MT $@ -c -o $@ crypto/modes/cts128.c
+	@touch crypto/modes/cts128.d.tmp
+	@if cmp crypto/modes/cts128.d.tmp crypto/modes/cts128.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/modes/cts128.d.tmp; \
+	else \
+		mv crypto/modes/cts128.d.tmp crypto/modes/cts128.d; \
+	fi
+crypto/modes/gcm128.o: crypto/modes/gcm128.c
+	$(CC)  -I. -Icrypto/include -Iinclude -Icrypto $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/modes/gcm128.d.tmp -MT $@ -c -o $@ crypto/modes/gcm128.c
+	@touch crypto/modes/gcm128.d.tmp
+	@if cmp crypto/modes/gcm128.d.tmp crypto/modes/gcm128.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/modes/gcm128.d.tmp; \
+	else \
+		mv crypto/modes/gcm128.d.tmp crypto/modes/gcm128.d; \
+	fi
+crypto/modes/ocb128.o: crypto/modes/ocb128.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/modes/ocb128.d.tmp -MT $@ -c -o $@ crypto/modes/ocb128.c
+	@touch crypto/modes/ocb128.d.tmp
+	@if cmp crypto/modes/ocb128.d.tmp crypto/modes/ocb128.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/modes/ocb128.d.tmp; \
+	else \
+		mv crypto/modes/ocb128.d.tmp crypto/modes/ocb128.d; \
+	fi
+crypto/modes/ofb128.o: crypto/modes/ofb128.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/modes/ofb128.d.tmp -MT $@ -c -o $@ crypto/modes/ofb128.c
+	@touch crypto/modes/ofb128.d.tmp
+	@if cmp crypto/modes/ofb128.d.tmp crypto/modes/ofb128.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/modes/ofb128.d.tmp; \
+	else \
+		mv crypto/modes/ofb128.d.tmp crypto/modes/ofb128.d; \
+	fi
+crypto/modes/wrap128.o: crypto/modes/wrap128.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/modes/wrap128.d.tmp -MT $@ -c -o $@ crypto/modes/wrap128.c
+	@touch crypto/modes/wrap128.d.tmp
+	@if cmp crypto/modes/wrap128.d.tmp crypto/modes/wrap128.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/modes/wrap128.d.tmp; \
+	else \
+		mv crypto/modes/wrap128.d.tmp crypto/modes/wrap128.d; \
+	fi
+crypto/modes/xts128.o: crypto/modes/xts128.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/modes/xts128.d.tmp -MT $@ -c -o $@ crypto/modes/xts128.c
+	@touch crypto/modes/xts128.d.tmp
+	@if cmp crypto/modes/xts128.d.tmp crypto/modes/xts128.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/modes/xts128.d.tmp; \
+	else \
+		mv crypto/modes/xts128.d.tmp crypto/modes/xts128.d; \
+	fi
+crypto/o_dir.o: crypto/o_dir.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/o_dir.d.tmp -MT $@ -c -o $@ crypto/o_dir.c
+	@touch crypto/o_dir.d.tmp
+	@if cmp crypto/o_dir.d.tmp crypto/o_dir.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/o_dir.d.tmp; \
+	else \
+		mv crypto/o_dir.d.tmp crypto/o_dir.d; \
+	fi
+crypto/o_fips.o: crypto/o_fips.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/o_fips.d.tmp -MT $@ -c -o $@ crypto/o_fips.c
+	@touch crypto/o_fips.d.tmp
+	@if cmp crypto/o_fips.d.tmp crypto/o_fips.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/o_fips.d.tmp; \
+	else \
+		mv crypto/o_fips.d.tmp crypto/o_fips.d; \
+	fi
+crypto/o_fopen.o: crypto/o_fopen.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/o_fopen.d.tmp -MT $@ -c -o $@ crypto/o_fopen.c
+	@touch crypto/o_fopen.d.tmp
+	@if cmp crypto/o_fopen.d.tmp crypto/o_fopen.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/o_fopen.d.tmp; \
+	else \
+		mv crypto/o_fopen.d.tmp crypto/o_fopen.d; \
+	fi
+crypto/o_init.o: crypto/o_init.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/o_init.d.tmp -MT $@ -c -o $@ crypto/o_init.c
+	@touch crypto/o_init.d.tmp
+	@if cmp crypto/o_init.d.tmp crypto/o_init.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/o_init.d.tmp; \
+	else \
+		mv crypto/o_init.d.tmp crypto/o_init.d; \
+	fi
+crypto/o_str.o: crypto/o_str.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/o_str.d.tmp -MT $@ -c -o $@ crypto/o_str.c
+	@touch crypto/o_str.d.tmp
+	@if cmp crypto/o_str.d.tmp crypto/o_str.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/o_str.d.tmp; \
+	else \
+		mv crypto/o_str.d.tmp crypto/o_str.d; \
+	fi
+crypto/o_time.o: crypto/o_time.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/o_time.d.tmp -MT $@ -c -o $@ crypto/o_time.c
+	@touch crypto/o_time.d.tmp
+	@if cmp crypto/o_time.d.tmp crypto/o_time.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/o_time.d.tmp; \
+	else \
+		mv crypto/o_time.d.tmp crypto/o_time.d; \
+	fi
+crypto/objects/o_names.o: crypto/objects/o_names.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/objects/o_names.d.tmp -MT $@ -c -o $@ crypto/objects/o_names.c
+	@touch crypto/objects/o_names.d.tmp
+	@if cmp crypto/objects/o_names.d.tmp crypto/objects/o_names.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/objects/o_names.d.tmp; \
+	else \
+		mv crypto/objects/o_names.d.tmp crypto/objects/o_names.d; \
+	fi
+crypto/objects/obj_dat.o: crypto/objects/obj_dat.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/objects/obj_dat.d.tmp -MT $@ -c -o $@ crypto/objects/obj_dat.c
+	@touch crypto/objects/obj_dat.d.tmp
+	@if cmp crypto/objects/obj_dat.d.tmp crypto/objects/obj_dat.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/objects/obj_dat.d.tmp; \
+	else \
+		mv crypto/objects/obj_dat.d.tmp crypto/objects/obj_dat.d; \
+	fi
+crypto/objects/obj_err.o: crypto/objects/obj_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/objects/obj_err.d.tmp -MT $@ -c -o $@ crypto/objects/obj_err.c
+	@touch crypto/objects/obj_err.d.tmp
+	@if cmp crypto/objects/obj_err.d.tmp crypto/objects/obj_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/objects/obj_err.d.tmp; \
+	else \
+		mv crypto/objects/obj_err.d.tmp crypto/objects/obj_err.d; \
+	fi
+crypto/objects/obj_lib.o: crypto/objects/obj_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/objects/obj_lib.d.tmp -MT $@ -c -o $@ crypto/objects/obj_lib.c
+	@touch crypto/objects/obj_lib.d.tmp
+	@if cmp crypto/objects/obj_lib.d.tmp crypto/objects/obj_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/objects/obj_lib.d.tmp; \
+	else \
+		mv crypto/objects/obj_lib.d.tmp crypto/objects/obj_lib.d; \
+	fi
+crypto/objects/obj_xref.o: crypto/objects/obj_xref.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/objects/obj_xref.d.tmp -MT $@ -c -o $@ crypto/objects/obj_xref.c
+	@touch crypto/objects/obj_xref.d.tmp
+	@if cmp crypto/objects/obj_xref.d.tmp crypto/objects/obj_xref.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/objects/obj_xref.d.tmp; \
+	else \
+		mv crypto/objects/obj_xref.d.tmp crypto/objects/obj_xref.d; \
+	fi
+crypto/ocsp/ocsp_asn.o: crypto/ocsp/ocsp_asn.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ocsp/ocsp_asn.d.tmp -MT $@ -c -o $@ crypto/ocsp/ocsp_asn.c
+	@touch crypto/ocsp/ocsp_asn.d.tmp
+	@if cmp crypto/ocsp/ocsp_asn.d.tmp crypto/ocsp/ocsp_asn.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ocsp/ocsp_asn.d.tmp; \
+	else \
+		mv crypto/ocsp/ocsp_asn.d.tmp crypto/ocsp/ocsp_asn.d; \
+	fi
+crypto/ocsp/ocsp_cl.o: crypto/ocsp/ocsp_cl.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ocsp/ocsp_cl.d.tmp -MT $@ -c -o $@ crypto/ocsp/ocsp_cl.c
+	@touch crypto/ocsp/ocsp_cl.d.tmp
+	@if cmp crypto/ocsp/ocsp_cl.d.tmp crypto/ocsp/ocsp_cl.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ocsp/ocsp_cl.d.tmp; \
+	else \
+		mv crypto/ocsp/ocsp_cl.d.tmp crypto/ocsp/ocsp_cl.d; \
+	fi
+crypto/ocsp/ocsp_err.o: crypto/ocsp/ocsp_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ocsp/ocsp_err.d.tmp -MT $@ -c -o $@ crypto/ocsp/ocsp_err.c
+	@touch crypto/ocsp/ocsp_err.d.tmp
+	@if cmp crypto/ocsp/ocsp_err.d.tmp crypto/ocsp/ocsp_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ocsp/ocsp_err.d.tmp; \
+	else \
+		mv crypto/ocsp/ocsp_err.d.tmp crypto/ocsp/ocsp_err.d; \
+	fi
+crypto/ocsp/ocsp_ext.o: crypto/ocsp/ocsp_ext.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ocsp/ocsp_ext.d.tmp -MT $@ -c -o $@ crypto/ocsp/ocsp_ext.c
+	@touch crypto/ocsp/ocsp_ext.d.tmp
+	@if cmp crypto/ocsp/ocsp_ext.d.tmp crypto/ocsp/ocsp_ext.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ocsp/ocsp_ext.d.tmp; \
+	else \
+		mv crypto/ocsp/ocsp_ext.d.tmp crypto/ocsp/ocsp_ext.d; \
+	fi
+crypto/ocsp/ocsp_ht.o: crypto/ocsp/ocsp_ht.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ocsp/ocsp_ht.d.tmp -MT $@ -c -o $@ crypto/ocsp/ocsp_ht.c
+	@touch crypto/ocsp/ocsp_ht.d.tmp
+	@if cmp crypto/ocsp/ocsp_ht.d.tmp crypto/ocsp/ocsp_ht.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ocsp/ocsp_ht.d.tmp; \
+	else \
+		mv crypto/ocsp/ocsp_ht.d.tmp crypto/ocsp/ocsp_ht.d; \
+	fi
+crypto/ocsp/ocsp_lib.o: crypto/ocsp/ocsp_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ocsp/ocsp_lib.d.tmp -MT $@ -c -o $@ crypto/ocsp/ocsp_lib.c
+	@touch crypto/ocsp/ocsp_lib.d.tmp
+	@if cmp crypto/ocsp/ocsp_lib.d.tmp crypto/ocsp/ocsp_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ocsp/ocsp_lib.d.tmp; \
+	else \
+		mv crypto/ocsp/ocsp_lib.d.tmp crypto/ocsp/ocsp_lib.d; \
+	fi
+crypto/ocsp/ocsp_prn.o: crypto/ocsp/ocsp_prn.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ocsp/ocsp_prn.d.tmp -MT $@ -c -o $@ crypto/ocsp/ocsp_prn.c
+	@touch crypto/ocsp/ocsp_prn.d.tmp
+	@if cmp crypto/ocsp/ocsp_prn.d.tmp crypto/ocsp/ocsp_prn.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ocsp/ocsp_prn.d.tmp; \
+	else \
+		mv crypto/ocsp/ocsp_prn.d.tmp crypto/ocsp/ocsp_prn.d; \
+	fi
+crypto/ocsp/ocsp_srv.o: crypto/ocsp/ocsp_srv.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ocsp/ocsp_srv.d.tmp -MT $@ -c -o $@ crypto/ocsp/ocsp_srv.c
+	@touch crypto/ocsp/ocsp_srv.d.tmp
+	@if cmp crypto/ocsp/ocsp_srv.d.tmp crypto/ocsp/ocsp_srv.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ocsp/ocsp_srv.d.tmp; \
+	else \
+		mv crypto/ocsp/ocsp_srv.d.tmp crypto/ocsp/ocsp_srv.d; \
+	fi
+crypto/ocsp/ocsp_vfy.o: crypto/ocsp/ocsp_vfy.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ocsp/ocsp_vfy.d.tmp -MT $@ -c -o $@ crypto/ocsp/ocsp_vfy.c
+	@touch crypto/ocsp/ocsp_vfy.d.tmp
+	@if cmp crypto/ocsp/ocsp_vfy.d.tmp crypto/ocsp/ocsp_vfy.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ocsp/ocsp_vfy.d.tmp; \
+	else \
+		mv crypto/ocsp/ocsp_vfy.d.tmp crypto/ocsp/ocsp_vfy.d; \
+	fi
+crypto/ocsp/v3_ocsp.o: crypto/ocsp/v3_ocsp.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ocsp/v3_ocsp.d.tmp -MT $@ -c -o $@ crypto/ocsp/v3_ocsp.c
+	@touch crypto/ocsp/v3_ocsp.d.tmp
+	@if cmp crypto/ocsp/v3_ocsp.d.tmp crypto/ocsp/v3_ocsp.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ocsp/v3_ocsp.d.tmp; \
+	else \
+		mv crypto/ocsp/v3_ocsp.d.tmp crypto/ocsp/v3_ocsp.d; \
+	fi
+crypto/pem/pem_all.o: crypto/pem/pem_all.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pem/pem_all.d.tmp -MT $@ -c -o $@ crypto/pem/pem_all.c
+	@touch crypto/pem/pem_all.d.tmp
+	@if cmp crypto/pem/pem_all.d.tmp crypto/pem/pem_all.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pem/pem_all.d.tmp; \
+	else \
+		mv crypto/pem/pem_all.d.tmp crypto/pem/pem_all.d; \
+	fi
+crypto/pem/pem_err.o: crypto/pem/pem_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pem/pem_err.d.tmp -MT $@ -c -o $@ crypto/pem/pem_err.c
+	@touch crypto/pem/pem_err.d.tmp
+	@if cmp crypto/pem/pem_err.d.tmp crypto/pem/pem_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pem/pem_err.d.tmp; \
+	else \
+		mv crypto/pem/pem_err.d.tmp crypto/pem/pem_err.d; \
+	fi
+crypto/pem/pem_info.o: crypto/pem/pem_info.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pem/pem_info.d.tmp -MT $@ -c -o $@ crypto/pem/pem_info.c
+	@touch crypto/pem/pem_info.d.tmp
+	@if cmp crypto/pem/pem_info.d.tmp crypto/pem/pem_info.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pem/pem_info.d.tmp; \
+	else \
+		mv crypto/pem/pem_info.d.tmp crypto/pem/pem_info.d; \
+	fi
+crypto/pem/pem_lib.o: crypto/pem/pem_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pem/pem_lib.d.tmp -MT $@ -c -o $@ crypto/pem/pem_lib.c
+	@touch crypto/pem/pem_lib.d.tmp
+	@if cmp crypto/pem/pem_lib.d.tmp crypto/pem/pem_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pem/pem_lib.d.tmp; \
+	else \
+		mv crypto/pem/pem_lib.d.tmp crypto/pem/pem_lib.d; \
+	fi
+crypto/pem/pem_oth.o: crypto/pem/pem_oth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pem/pem_oth.d.tmp -MT $@ -c -o $@ crypto/pem/pem_oth.c
+	@touch crypto/pem/pem_oth.d.tmp
+	@if cmp crypto/pem/pem_oth.d.tmp crypto/pem/pem_oth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pem/pem_oth.d.tmp; \
+	else \
+		mv crypto/pem/pem_oth.d.tmp crypto/pem/pem_oth.d; \
+	fi
+crypto/pem/pem_pk8.o: crypto/pem/pem_pk8.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pem/pem_pk8.d.tmp -MT $@ -c -o $@ crypto/pem/pem_pk8.c
+	@touch crypto/pem/pem_pk8.d.tmp
+	@if cmp crypto/pem/pem_pk8.d.tmp crypto/pem/pem_pk8.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pem/pem_pk8.d.tmp; \
+	else \
+		mv crypto/pem/pem_pk8.d.tmp crypto/pem/pem_pk8.d; \
+	fi
+crypto/pem/pem_pkey.o: crypto/pem/pem_pkey.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pem/pem_pkey.d.tmp -MT $@ -c -o $@ crypto/pem/pem_pkey.c
+	@touch crypto/pem/pem_pkey.d.tmp
+	@if cmp crypto/pem/pem_pkey.d.tmp crypto/pem/pem_pkey.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pem/pem_pkey.d.tmp; \
+	else \
+		mv crypto/pem/pem_pkey.d.tmp crypto/pem/pem_pkey.d; \
+	fi
+crypto/pem/pem_sign.o: crypto/pem/pem_sign.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pem/pem_sign.d.tmp -MT $@ -c -o $@ crypto/pem/pem_sign.c
+	@touch crypto/pem/pem_sign.d.tmp
+	@if cmp crypto/pem/pem_sign.d.tmp crypto/pem/pem_sign.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pem/pem_sign.d.tmp; \
+	else \
+		mv crypto/pem/pem_sign.d.tmp crypto/pem/pem_sign.d; \
+	fi
+crypto/pem/pem_x509.o: crypto/pem/pem_x509.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pem/pem_x509.d.tmp -MT $@ -c -o $@ crypto/pem/pem_x509.c
+	@touch crypto/pem/pem_x509.d.tmp
+	@if cmp crypto/pem/pem_x509.d.tmp crypto/pem/pem_x509.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pem/pem_x509.d.tmp; \
+	else \
+		mv crypto/pem/pem_x509.d.tmp crypto/pem/pem_x509.d; \
+	fi
+crypto/pem/pem_xaux.o: crypto/pem/pem_xaux.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pem/pem_xaux.d.tmp -MT $@ -c -o $@ crypto/pem/pem_xaux.c
+	@touch crypto/pem/pem_xaux.d.tmp
+	@if cmp crypto/pem/pem_xaux.d.tmp crypto/pem/pem_xaux.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pem/pem_xaux.d.tmp; \
+	else \
+		mv crypto/pem/pem_xaux.d.tmp crypto/pem/pem_xaux.d; \
+	fi
+crypto/pem/pvkfmt.o: crypto/pem/pvkfmt.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pem/pvkfmt.d.tmp -MT $@ -c -o $@ crypto/pem/pvkfmt.c
+	@touch crypto/pem/pvkfmt.d.tmp
+	@if cmp crypto/pem/pvkfmt.d.tmp crypto/pem/pvkfmt.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pem/pvkfmt.d.tmp; \
+	else \
+		mv crypto/pem/pvkfmt.d.tmp crypto/pem/pvkfmt.d; \
+	fi
+crypto/pkcs12/p12_add.o: crypto/pkcs12/p12_add.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs12/p12_add.d.tmp -MT $@ -c -o $@ crypto/pkcs12/p12_add.c
+	@touch crypto/pkcs12/p12_add.d.tmp
+	@if cmp crypto/pkcs12/p12_add.d.tmp crypto/pkcs12/p12_add.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs12/p12_add.d.tmp; \
+	else \
+		mv crypto/pkcs12/p12_add.d.tmp crypto/pkcs12/p12_add.d; \
+	fi
+crypto/pkcs12/p12_asn.o: crypto/pkcs12/p12_asn.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs12/p12_asn.d.tmp -MT $@ -c -o $@ crypto/pkcs12/p12_asn.c
+	@touch crypto/pkcs12/p12_asn.d.tmp
+	@if cmp crypto/pkcs12/p12_asn.d.tmp crypto/pkcs12/p12_asn.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs12/p12_asn.d.tmp; \
+	else \
+		mv crypto/pkcs12/p12_asn.d.tmp crypto/pkcs12/p12_asn.d; \
+	fi
+crypto/pkcs12/p12_attr.o: crypto/pkcs12/p12_attr.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs12/p12_attr.d.tmp -MT $@ -c -o $@ crypto/pkcs12/p12_attr.c
+	@touch crypto/pkcs12/p12_attr.d.tmp
+	@if cmp crypto/pkcs12/p12_attr.d.tmp crypto/pkcs12/p12_attr.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs12/p12_attr.d.tmp; \
+	else \
+		mv crypto/pkcs12/p12_attr.d.tmp crypto/pkcs12/p12_attr.d; \
+	fi
+crypto/pkcs12/p12_crpt.o: crypto/pkcs12/p12_crpt.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs12/p12_crpt.d.tmp -MT $@ -c -o $@ crypto/pkcs12/p12_crpt.c
+	@touch crypto/pkcs12/p12_crpt.d.tmp
+	@if cmp crypto/pkcs12/p12_crpt.d.tmp crypto/pkcs12/p12_crpt.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs12/p12_crpt.d.tmp; \
+	else \
+		mv crypto/pkcs12/p12_crpt.d.tmp crypto/pkcs12/p12_crpt.d; \
+	fi
+crypto/pkcs12/p12_crt.o: crypto/pkcs12/p12_crt.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs12/p12_crt.d.tmp -MT $@ -c -o $@ crypto/pkcs12/p12_crt.c
+	@touch crypto/pkcs12/p12_crt.d.tmp
+	@if cmp crypto/pkcs12/p12_crt.d.tmp crypto/pkcs12/p12_crt.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs12/p12_crt.d.tmp; \
+	else \
+		mv crypto/pkcs12/p12_crt.d.tmp crypto/pkcs12/p12_crt.d; \
+	fi
+crypto/pkcs12/p12_decr.o: crypto/pkcs12/p12_decr.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs12/p12_decr.d.tmp -MT $@ -c -o $@ crypto/pkcs12/p12_decr.c
+	@touch crypto/pkcs12/p12_decr.d.tmp
+	@if cmp crypto/pkcs12/p12_decr.d.tmp crypto/pkcs12/p12_decr.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs12/p12_decr.d.tmp; \
+	else \
+		mv crypto/pkcs12/p12_decr.d.tmp crypto/pkcs12/p12_decr.d; \
+	fi
+crypto/pkcs12/p12_init.o: crypto/pkcs12/p12_init.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs12/p12_init.d.tmp -MT $@ -c -o $@ crypto/pkcs12/p12_init.c
+	@touch crypto/pkcs12/p12_init.d.tmp
+	@if cmp crypto/pkcs12/p12_init.d.tmp crypto/pkcs12/p12_init.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs12/p12_init.d.tmp; \
+	else \
+		mv crypto/pkcs12/p12_init.d.tmp crypto/pkcs12/p12_init.d; \
+	fi
+crypto/pkcs12/p12_key.o: crypto/pkcs12/p12_key.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs12/p12_key.d.tmp -MT $@ -c -o $@ crypto/pkcs12/p12_key.c
+	@touch crypto/pkcs12/p12_key.d.tmp
+	@if cmp crypto/pkcs12/p12_key.d.tmp crypto/pkcs12/p12_key.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs12/p12_key.d.tmp; \
+	else \
+		mv crypto/pkcs12/p12_key.d.tmp crypto/pkcs12/p12_key.d; \
+	fi
+crypto/pkcs12/p12_kiss.o: crypto/pkcs12/p12_kiss.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs12/p12_kiss.d.tmp -MT $@ -c -o $@ crypto/pkcs12/p12_kiss.c
+	@touch crypto/pkcs12/p12_kiss.d.tmp
+	@if cmp crypto/pkcs12/p12_kiss.d.tmp crypto/pkcs12/p12_kiss.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs12/p12_kiss.d.tmp; \
+	else \
+		mv crypto/pkcs12/p12_kiss.d.tmp crypto/pkcs12/p12_kiss.d; \
+	fi
+crypto/pkcs12/p12_mutl.o: crypto/pkcs12/p12_mutl.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs12/p12_mutl.d.tmp -MT $@ -c -o $@ crypto/pkcs12/p12_mutl.c
+	@touch crypto/pkcs12/p12_mutl.d.tmp
+	@if cmp crypto/pkcs12/p12_mutl.d.tmp crypto/pkcs12/p12_mutl.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs12/p12_mutl.d.tmp; \
+	else \
+		mv crypto/pkcs12/p12_mutl.d.tmp crypto/pkcs12/p12_mutl.d; \
+	fi
+crypto/pkcs12/p12_npas.o: crypto/pkcs12/p12_npas.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs12/p12_npas.d.tmp -MT $@ -c -o $@ crypto/pkcs12/p12_npas.c
+	@touch crypto/pkcs12/p12_npas.d.tmp
+	@if cmp crypto/pkcs12/p12_npas.d.tmp crypto/pkcs12/p12_npas.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs12/p12_npas.d.tmp; \
+	else \
+		mv crypto/pkcs12/p12_npas.d.tmp crypto/pkcs12/p12_npas.d; \
+	fi
+crypto/pkcs12/p12_p8d.o: crypto/pkcs12/p12_p8d.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs12/p12_p8d.d.tmp -MT $@ -c -o $@ crypto/pkcs12/p12_p8d.c
+	@touch crypto/pkcs12/p12_p8d.d.tmp
+	@if cmp crypto/pkcs12/p12_p8d.d.tmp crypto/pkcs12/p12_p8d.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs12/p12_p8d.d.tmp; \
+	else \
+		mv crypto/pkcs12/p12_p8d.d.tmp crypto/pkcs12/p12_p8d.d; \
+	fi
+crypto/pkcs12/p12_p8e.o: crypto/pkcs12/p12_p8e.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs12/p12_p8e.d.tmp -MT $@ -c -o $@ crypto/pkcs12/p12_p8e.c
+	@touch crypto/pkcs12/p12_p8e.d.tmp
+	@if cmp crypto/pkcs12/p12_p8e.d.tmp crypto/pkcs12/p12_p8e.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs12/p12_p8e.d.tmp; \
+	else \
+		mv crypto/pkcs12/p12_p8e.d.tmp crypto/pkcs12/p12_p8e.d; \
+	fi
+crypto/pkcs12/p12_sbag.o: crypto/pkcs12/p12_sbag.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs12/p12_sbag.d.tmp -MT $@ -c -o $@ crypto/pkcs12/p12_sbag.c
+	@touch crypto/pkcs12/p12_sbag.d.tmp
+	@if cmp crypto/pkcs12/p12_sbag.d.tmp crypto/pkcs12/p12_sbag.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs12/p12_sbag.d.tmp; \
+	else \
+		mv crypto/pkcs12/p12_sbag.d.tmp crypto/pkcs12/p12_sbag.d; \
+	fi
+crypto/pkcs12/p12_utl.o: crypto/pkcs12/p12_utl.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs12/p12_utl.d.tmp -MT $@ -c -o $@ crypto/pkcs12/p12_utl.c
+	@touch crypto/pkcs12/p12_utl.d.tmp
+	@if cmp crypto/pkcs12/p12_utl.d.tmp crypto/pkcs12/p12_utl.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs12/p12_utl.d.tmp; \
+	else \
+		mv crypto/pkcs12/p12_utl.d.tmp crypto/pkcs12/p12_utl.d; \
+	fi
+crypto/pkcs12/pk12err.o: crypto/pkcs12/pk12err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs12/pk12err.d.tmp -MT $@ -c -o $@ crypto/pkcs12/pk12err.c
+	@touch crypto/pkcs12/pk12err.d.tmp
+	@if cmp crypto/pkcs12/pk12err.d.tmp crypto/pkcs12/pk12err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs12/pk12err.d.tmp; \
+	else \
+		mv crypto/pkcs12/pk12err.d.tmp crypto/pkcs12/pk12err.d; \
+	fi
+crypto/pkcs7/bio_pk7.o: crypto/pkcs7/bio_pk7.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs7/bio_pk7.d.tmp -MT $@ -c -o $@ crypto/pkcs7/bio_pk7.c
+	@touch crypto/pkcs7/bio_pk7.d.tmp
+	@if cmp crypto/pkcs7/bio_pk7.d.tmp crypto/pkcs7/bio_pk7.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs7/bio_pk7.d.tmp; \
+	else \
+		mv crypto/pkcs7/bio_pk7.d.tmp crypto/pkcs7/bio_pk7.d; \
+	fi
+crypto/pkcs7/pk7_asn1.o: crypto/pkcs7/pk7_asn1.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs7/pk7_asn1.d.tmp -MT $@ -c -o $@ crypto/pkcs7/pk7_asn1.c
+	@touch crypto/pkcs7/pk7_asn1.d.tmp
+	@if cmp crypto/pkcs7/pk7_asn1.d.tmp crypto/pkcs7/pk7_asn1.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs7/pk7_asn1.d.tmp; \
+	else \
+		mv crypto/pkcs7/pk7_asn1.d.tmp crypto/pkcs7/pk7_asn1.d; \
+	fi
+crypto/pkcs7/pk7_attr.o: crypto/pkcs7/pk7_attr.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs7/pk7_attr.d.tmp -MT $@ -c -o $@ crypto/pkcs7/pk7_attr.c
+	@touch crypto/pkcs7/pk7_attr.d.tmp
+	@if cmp crypto/pkcs7/pk7_attr.d.tmp crypto/pkcs7/pk7_attr.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs7/pk7_attr.d.tmp; \
+	else \
+		mv crypto/pkcs7/pk7_attr.d.tmp crypto/pkcs7/pk7_attr.d; \
+	fi
+crypto/pkcs7/pk7_doit.o: crypto/pkcs7/pk7_doit.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs7/pk7_doit.d.tmp -MT $@ -c -o $@ crypto/pkcs7/pk7_doit.c
+	@touch crypto/pkcs7/pk7_doit.d.tmp
+	@if cmp crypto/pkcs7/pk7_doit.d.tmp crypto/pkcs7/pk7_doit.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs7/pk7_doit.d.tmp; \
+	else \
+		mv crypto/pkcs7/pk7_doit.d.tmp crypto/pkcs7/pk7_doit.d; \
+	fi
+crypto/pkcs7/pk7_lib.o: crypto/pkcs7/pk7_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs7/pk7_lib.d.tmp -MT $@ -c -o $@ crypto/pkcs7/pk7_lib.c
+	@touch crypto/pkcs7/pk7_lib.d.tmp
+	@if cmp crypto/pkcs7/pk7_lib.d.tmp crypto/pkcs7/pk7_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs7/pk7_lib.d.tmp; \
+	else \
+		mv crypto/pkcs7/pk7_lib.d.tmp crypto/pkcs7/pk7_lib.d; \
+	fi
+crypto/pkcs7/pk7_mime.o: crypto/pkcs7/pk7_mime.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs7/pk7_mime.d.tmp -MT $@ -c -o $@ crypto/pkcs7/pk7_mime.c
+	@touch crypto/pkcs7/pk7_mime.d.tmp
+	@if cmp crypto/pkcs7/pk7_mime.d.tmp crypto/pkcs7/pk7_mime.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs7/pk7_mime.d.tmp; \
+	else \
+		mv crypto/pkcs7/pk7_mime.d.tmp crypto/pkcs7/pk7_mime.d; \
+	fi
+crypto/pkcs7/pk7_smime.o: crypto/pkcs7/pk7_smime.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs7/pk7_smime.d.tmp -MT $@ -c -o $@ crypto/pkcs7/pk7_smime.c
+	@touch crypto/pkcs7/pk7_smime.d.tmp
+	@if cmp crypto/pkcs7/pk7_smime.d.tmp crypto/pkcs7/pk7_smime.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs7/pk7_smime.d.tmp; \
+	else \
+		mv crypto/pkcs7/pk7_smime.d.tmp crypto/pkcs7/pk7_smime.d; \
+	fi
+crypto/pkcs7/pkcs7err.o: crypto/pkcs7/pkcs7err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/pkcs7/pkcs7err.d.tmp -MT $@ -c -o $@ crypto/pkcs7/pkcs7err.c
+	@touch crypto/pkcs7/pkcs7err.d.tmp
+	@if cmp crypto/pkcs7/pkcs7err.d.tmp crypto/pkcs7/pkcs7err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/pkcs7/pkcs7err.d.tmp; \
+	else \
+		mv crypto/pkcs7/pkcs7err.d.tmp crypto/pkcs7/pkcs7err.d; \
+	fi
+crypto/poly1305/poly1305.o: crypto/poly1305/poly1305.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/poly1305/poly1305.d.tmp -MT $@ -c -o $@ crypto/poly1305/poly1305.c
+	@touch crypto/poly1305/poly1305.d.tmp
+	@if cmp crypto/poly1305/poly1305.d.tmp crypto/poly1305/poly1305.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/poly1305/poly1305.d.tmp; \
+	else \
+		mv crypto/poly1305/poly1305.d.tmp crypto/poly1305/poly1305.d; \
+	fi
+crypto/rand/md_rand.o: crypto/rand/md_rand.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rand/md_rand.d.tmp -MT $@ -c -o $@ crypto/rand/md_rand.c
+	@touch crypto/rand/md_rand.d.tmp
+	@if cmp crypto/rand/md_rand.d.tmp crypto/rand/md_rand.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rand/md_rand.d.tmp; \
+	else \
+		mv crypto/rand/md_rand.d.tmp crypto/rand/md_rand.d; \
+	fi
+crypto/rand/rand_egd.o: crypto/rand/rand_egd.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rand/rand_egd.d.tmp -MT $@ -c -o $@ crypto/rand/rand_egd.c
+	@touch crypto/rand/rand_egd.d.tmp
+	@if cmp crypto/rand/rand_egd.d.tmp crypto/rand/rand_egd.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rand/rand_egd.d.tmp; \
+	else \
+		mv crypto/rand/rand_egd.d.tmp crypto/rand/rand_egd.d; \
+	fi
+crypto/rand/rand_err.o: crypto/rand/rand_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rand/rand_err.d.tmp -MT $@ -c -o $@ crypto/rand/rand_err.c
+	@touch crypto/rand/rand_err.d.tmp
+	@if cmp crypto/rand/rand_err.d.tmp crypto/rand/rand_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rand/rand_err.d.tmp; \
+	else \
+		mv crypto/rand/rand_err.d.tmp crypto/rand/rand_err.d; \
+	fi
+crypto/rand/rand_lib.o: crypto/rand/rand_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rand/rand_lib.d.tmp -MT $@ -c -o $@ crypto/rand/rand_lib.c
+	@touch crypto/rand/rand_lib.d.tmp
+	@if cmp crypto/rand/rand_lib.d.tmp crypto/rand/rand_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rand/rand_lib.d.tmp; \
+	else \
+		mv crypto/rand/rand_lib.d.tmp crypto/rand/rand_lib.d; \
+	fi
+crypto/rand/rand_unix.o: crypto/rand/rand_unix.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rand/rand_unix.d.tmp -MT $@ -c -o $@ crypto/rand/rand_unix.c
+	@touch crypto/rand/rand_unix.d.tmp
+	@if cmp crypto/rand/rand_unix.d.tmp crypto/rand/rand_unix.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rand/rand_unix.d.tmp; \
+	else \
+		mv crypto/rand/rand_unix.d.tmp crypto/rand/rand_unix.d; \
+	fi
+crypto/rand/rand_vms.o: crypto/rand/rand_vms.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rand/rand_vms.d.tmp -MT $@ -c -o $@ crypto/rand/rand_vms.c
+	@touch crypto/rand/rand_vms.d.tmp
+	@if cmp crypto/rand/rand_vms.d.tmp crypto/rand/rand_vms.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rand/rand_vms.d.tmp; \
+	else \
+		mv crypto/rand/rand_vms.d.tmp crypto/rand/rand_vms.d; \
+	fi
+crypto/rand/rand_win.o: crypto/rand/rand_win.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rand/rand_win.d.tmp -MT $@ -c -o $@ crypto/rand/rand_win.c
+	@touch crypto/rand/rand_win.d.tmp
+	@if cmp crypto/rand/rand_win.d.tmp crypto/rand/rand_win.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rand/rand_win.d.tmp; \
+	else \
+		mv crypto/rand/rand_win.d.tmp crypto/rand/rand_win.d; \
+	fi
+crypto/rand/randfile.o: crypto/rand/randfile.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rand/randfile.d.tmp -MT $@ -c -o $@ crypto/rand/randfile.c
+	@touch crypto/rand/randfile.d.tmp
+	@if cmp crypto/rand/randfile.d.tmp crypto/rand/randfile.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rand/randfile.d.tmp; \
+	else \
+		mv crypto/rand/randfile.d.tmp crypto/rand/randfile.d; \
+	fi
+crypto/rc2/rc2_cbc.o: crypto/rc2/rc2_cbc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rc2/rc2_cbc.d.tmp -MT $@ -c -o $@ crypto/rc2/rc2_cbc.c
+	@touch crypto/rc2/rc2_cbc.d.tmp
+	@if cmp crypto/rc2/rc2_cbc.d.tmp crypto/rc2/rc2_cbc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rc2/rc2_cbc.d.tmp; \
+	else \
+		mv crypto/rc2/rc2_cbc.d.tmp crypto/rc2/rc2_cbc.d; \
+	fi
+crypto/rc2/rc2_ecb.o: crypto/rc2/rc2_ecb.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rc2/rc2_ecb.d.tmp -MT $@ -c -o $@ crypto/rc2/rc2_ecb.c
+	@touch crypto/rc2/rc2_ecb.d.tmp
+	@if cmp crypto/rc2/rc2_ecb.d.tmp crypto/rc2/rc2_ecb.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rc2/rc2_ecb.d.tmp; \
+	else \
+		mv crypto/rc2/rc2_ecb.d.tmp crypto/rc2/rc2_ecb.d; \
+	fi
+crypto/rc2/rc2_skey.o: crypto/rc2/rc2_skey.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rc2/rc2_skey.d.tmp -MT $@ -c -o $@ crypto/rc2/rc2_skey.c
+	@touch crypto/rc2/rc2_skey.d.tmp
+	@if cmp crypto/rc2/rc2_skey.d.tmp crypto/rc2/rc2_skey.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rc2/rc2_skey.d.tmp; \
+	else \
+		mv crypto/rc2/rc2_skey.d.tmp crypto/rc2/rc2_skey.d; \
+	fi
+crypto/rc2/rc2cfb64.o: crypto/rc2/rc2cfb64.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rc2/rc2cfb64.d.tmp -MT $@ -c -o $@ crypto/rc2/rc2cfb64.c
+	@touch crypto/rc2/rc2cfb64.d.tmp
+	@if cmp crypto/rc2/rc2cfb64.d.tmp crypto/rc2/rc2cfb64.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rc2/rc2cfb64.d.tmp; \
+	else \
+		mv crypto/rc2/rc2cfb64.d.tmp crypto/rc2/rc2cfb64.d; \
+	fi
+crypto/rc2/rc2ofb64.o: crypto/rc2/rc2ofb64.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rc2/rc2ofb64.d.tmp -MT $@ -c -o $@ crypto/rc2/rc2ofb64.c
+	@touch crypto/rc2/rc2ofb64.d.tmp
+	@if cmp crypto/rc2/rc2ofb64.d.tmp crypto/rc2/rc2ofb64.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rc2/rc2ofb64.d.tmp; \
+	else \
+		mv crypto/rc2/rc2ofb64.d.tmp crypto/rc2/rc2ofb64.d; \
+	fi
+crypto/rc4/rc4_enc.o: crypto/rc4/rc4_enc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rc4/rc4_enc.d.tmp -MT $@ -c -o $@ crypto/rc4/rc4_enc.c
+	@touch crypto/rc4/rc4_enc.d.tmp
+	@if cmp crypto/rc4/rc4_enc.d.tmp crypto/rc4/rc4_enc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rc4/rc4_enc.d.tmp; \
+	else \
+		mv crypto/rc4/rc4_enc.d.tmp crypto/rc4/rc4_enc.d; \
+	fi
+crypto/rc4/rc4_skey.o: crypto/rc4/rc4_skey.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rc4/rc4_skey.d.tmp -MT $@ -c -o $@ crypto/rc4/rc4_skey.c
+	@touch crypto/rc4/rc4_skey.d.tmp
+	@if cmp crypto/rc4/rc4_skey.d.tmp crypto/rc4/rc4_skey.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rc4/rc4_skey.d.tmp; \
+	else \
+		mv crypto/rc4/rc4_skey.d.tmp crypto/rc4/rc4_skey.d; \
+	fi
+crypto/ripemd/rmd_dgst.o: crypto/ripemd/rmd_dgst.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ripemd/rmd_dgst.d.tmp -MT $@ -c -o $@ crypto/ripemd/rmd_dgst.c
+	@touch crypto/ripemd/rmd_dgst.d.tmp
+	@if cmp crypto/ripemd/rmd_dgst.d.tmp crypto/ripemd/rmd_dgst.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ripemd/rmd_dgst.d.tmp; \
+	else \
+		mv crypto/ripemd/rmd_dgst.d.tmp crypto/ripemd/rmd_dgst.d; \
+	fi
+crypto/ripemd/rmd_one.o: crypto/ripemd/rmd_one.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ripemd/rmd_one.d.tmp -MT $@ -c -o $@ crypto/ripemd/rmd_one.c
+	@touch crypto/ripemd/rmd_one.d.tmp
+	@if cmp crypto/ripemd/rmd_one.d.tmp crypto/ripemd/rmd_one.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ripemd/rmd_one.d.tmp; \
+	else \
+		mv crypto/ripemd/rmd_one.d.tmp crypto/ripemd/rmd_one.d; \
+	fi
+crypto/rsa/rsa_ameth.o: crypto/rsa/rsa_ameth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_ameth.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_ameth.c
+	@touch crypto/rsa/rsa_ameth.d.tmp
+	@if cmp crypto/rsa/rsa_ameth.d.tmp crypto/rsa/rsa_ameth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_ameth.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_ameth.d.tmp crypto/rsa/rsa_ameth.d; \
+	fi
+crypto/rsa/rsa_asn1.o: crypto/rsa/rsa_asn1.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_asn1.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_asn1.c
+	@touch crypto/rsa/rsa_asn1.d.tmp
+	@if cmp crypto/rsa/rsa_asn1.d.tmp crypto/rsa/rsa_asn1.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_asn1.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_asn1.d.tmp crypto/rsa/rsa_asn1.d; \
+	fi
+crypto/rsa/rsa_chk.o: crypto/rsa/rsa_chk.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_chk.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_chk.c
+	@touch crypto/rsa/rsa_chk.d.tmp
+	@if cmp crypto/rsa/rsa_chk.d.tmp crypto/rsa/rsa_chk.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_chk.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_chk.d.tmp crypto/rsa/rsa_chk.d; \
+	fi
+crypto/rsa/rsa_crpt.o: crypto/rsa/rsa_crpt.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_crpt.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_crpt.c
+	@touch crypto/rsa/rsa_crpt.d.tmp
+	@if cmp crypto/rsa/rsa_crpt.d.tmp crypto/rsa/rsa_crpt.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_crpt.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_crpt.d.tmp crypto/rsa/rsa_crpt.d; \
+	fi
+crypto/rsa/rsa_depr.o: crypto/rsa/rsa_depr.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_depr.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_depr.c
+	@touch crypto/rsa/rsa_depr.d.tmp
+	@if cmp crypto/rsa/rsa_depr.d.tmp crypto/rsa/rsa_depr.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_depr.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_depr.d.tmp crypto/rsa/rsa_depr.d; \
+	fi
+crypto/rsa/rsa_err.o: crypto/rsa/rsa_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_err.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_err.c
+	@touch crypto/rsa/rsa_err.d.tmp
+	@if cmp crypto/rsa/rsa_err.d.tmp crypto/rsa/rsa_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_err.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_err.d.tmp crypto/rsa/rsa_err.d; \
+	fi
+crypto/rsa/rsa_gen.o: crypto/rsa/rsa_gen.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_gen.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_gen.c
+	@touch crypto/rsa/rsa_gen.d.tmp
+	@if cmp crypto/rsa/rsa_gen.d.tmp crypto/rsa/rsa_gen.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_gen.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_gen.d.tmp crypto/rsa/rsa_gen.d; \
+	fi
+crypto/rsa/rsa_lib.o: crypto/rsa/rsa_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_lib.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_lib.c
+	@touch crypto/rsa/rsa_lib.d.tmp
+	@if cmp crypto/rsa/rsa_lib.d.tmp crypto/rsa/rsa_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_lib.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_lib.d.tmp crypto/rsa/rsa_lib.d; \
+	fi
+crypto/rsa/rsa_meth.o: crypto/rsa/rsa_meth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_meth.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_meth.c
+	@touch crypto/rsa/rsa_meth.d.tmp
+	@if cmp crypto/rsa/rsa_meth.d.tmp crypto/rsa/rsa_meth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_meth.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_meth.d.tmp crypto/rsa/rsa_meth.d; \
+	fi
+crypto/rsa/rsa_none.o: crypto/rsa/rsa_none.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_none.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_none.c
+	@touch crypto/rsa/rsa_none.d.tmp
+	@if cmp crypto/rsa/rsa_none.d.tmp crypto/rsa/rsa_none.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_none.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_none.d.tmp crypto/rsa/rsa_none.d; \
+	fi
+crypto/rsa/rsa_null.o: crypto/rsa/rsa_null.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_null.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_null.c
+	@touch crypto/rsa/rsa_null.d.tmp
+	@if cmp crypto/rsa/rsa_null.d.tmp crypto/rsa/rsa_null.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_null.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_null.d.tmp crypto/rsa/rsa_null.d; \
+	fi
+crypto/rsa/rsa_oaep.o: crypto/rsa/rsa_oaep.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_oaep.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_oaep.c
+	@touch crypto/rsa/rsa_oaep.d.tmp
+	@if cmp crypto/rsa/rsa_oaep.d.tmp crypto/rsa/rsa_oaep.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_oaep.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_oaep.d.tmp crypto/rsa/rsa_oaep.d; \
+	fi
+crypto/rsa/rsa_ossl.o: crypto/rsa/rsa_ossl.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_ossl.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_ossl.c
+	@touch crypto/rsa/rsa_ossl.d.tmp
+	@if cmp crypto/rsa/rsa_ossl.d.tmp crypto/rsa/rsa_ossl.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_ossl.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_ossl.d.tmp crypto/rsa/rsa_ossl.d; \
+	fi
+crypto/rsa/rsa_pk1.o: crypto/rsa/rsa_pk1.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_pk1.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_pk1.c
+	@touch crypto/rsa/rsa_pk1.d.tmp
+	@if cmp crypto/rsa/rsa_pk1.d.tmp crypto/rsa/rsa_pk1.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_pk1.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_pk1.d.tmp crypto/rsa/rsa_pk1.d; \
+	fi
+crypto/rsa/rsa_pmeth.o: crypto/rsa/rsa_pmeth.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_pmeth.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_pmeth.c
+	@touch crypto/rsa/rsa_pmeth.d.tmp
+	@if cmp crypto/rsa/rsa_pmeth.d.tmp crypto/rsa/rsa_pmeth.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_pmeth.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_pmeth.d.tmp crypto/rsa/rsa_pmeth.d; \
+	fi
+crypto/rsa/rsa_prn.o: crypto/rsa/rsa_prn.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_prn.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_prn.c
+	@touch crypto/rsa/rsa_prn.d.tmp
+	@if cmp crypto/rsa/rsa_prn.d.tmp crypto/rsa/rsa_prn.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_prn.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_prn.d.tmp crypto/rsa/rsa_prn.d; \
+	fi
+crypto/rsa/rsa_pss.o: crypto/rsa/rsa_pss.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_pss.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_pss.c
+	@touch crypto/rsa/rsa_pss.d.tmp
+	@if cmp crypto/rsa/rsa_pss.d.tmp crypto/rsa/rsa_pss.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_pss.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_pss.d.tmp crypto/rsa/rsa_pss.d; \
+	fi
+crypto/rsa/rsa_saos.o: crypto/rsa/rsa_saos.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_saos.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_saos.c
+	@touch crypto/rsa/rsa_saos.d.tmp
+	@if cmp crypto/rsa/rsa_saos.d.tmp crypto/rsa/rsa_saos.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_saos.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_saos.d.tmp crypto/rsa/rsa_saos.d; \
+	fi
+crypto/rsa/rsa_sign.o: crypto/rsa/rsa_sign.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_sign.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_sign.c
+	@touch crypto/rsa/rsa_sign.d.tmp
+	@if cmp crypto/rsa/rsa_sign.d.tmp crypto/rsa/rsa_sign.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_sign.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_sign.d.tmp crypto/rsa/rsa_sign.d; \
+	fi
+crypto/rsa/rsa_ssl.o: crypto/rsa/rsa_ssl.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_ssl.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_ssl.c
+	@touch crypto/rsa/rsa_ssl.d.tmp
+	@if cmp crypto/rsa/rsa_ssl.d.tmp crypto/rsa/rsa_ssl.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_ssl.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_ssl.d.tmp crypto/rsa/rsa_ssl.d; \
+	fi
+crypto/rsa/rsa_x931.o: crypto/rsa/rsa_x931.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_x931.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_x931.c
+	@touch crypto/rsa/rsa_x931.d.tmp
+	@if cmp crypto/rsa/rsa_x931.d.tmp crypto/rsa/rsa_x931.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_x931.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_x931.d.tmp crypto/rsa/rsa_x931.d; \
+	fi
+crypto/rsa/rsa_x931g.o: crypto/rsa/rsa_x931g.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/rsa/rsa_x931g.d.tmp -MT $@ -c -o $@ crypto/rsa/rsa_x931g.c
+	@touch crypto/rsa/rsa_x931g.d.tmp
+	@if cmp crypto/rsa/rsa_x931g.d.tmp crypto/rsa/rsa_x931g.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/rsa/rsa_x931g.d.tmp; \
+	else \
+		mv crypto/rsa/rsa_x931g.d.tmp crypto/rsa/rsa_x931g.d; \
+	fi
+crypto/seed/seed.o: crypto/seed/seed.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/seed/seed.d.tmp -MT $@ -c -o $@ crypto/seed/seed.c
+	@touch crypto/seed/seed.d.tmp
+	@if cmp crypto/seed/seed.d.tmp crypto/seed/seed.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/seed/seed.d.tmp; \
+	else \
+		mv crypto/seed/seed.d.tmp crypto/seed/seed.d; \
+	fi
+crypto/seed/seed_cbc.o: crypto/seed/seed_cbc.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/seed/seed_cbc.d.tmp -MT $@ -c -o $@ crypto/seed/seed_cbc.c
+	@touch crypto/seed/seed_cbc.d.tmp
+	@if cmp crypto/seed/seed_cbc.d.tmp crypto/seed/seed_cbc.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/seed/seed_cbc.d.tmp; \
+	else \
+		mv crypto/seed/seed_cbc.d.tmp crypto/seed/seed_cbc.d; \
+	fi
+crypto/seed/seed_cfb.o: crypto/seed/seed_cfb.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/seed/seed_cfb.d.tmp -MT $@ -c -o $@ crypto/seed/seed_cfb.c
+	@touch crypto/seed/seed_cfb.d.tmp
+	@if cmp crypto/seed/seed_cfb.d.tmp crypto/seed/seed_cfb.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/seed/seed_cfb.d.tmp; \
+	else \
+		mv crypto/seed/seed_cfb.d.tmp crypto/seed/seed_cfb.d; \
+	fi
+crypto/seed/seed_ecb.o: crypto/seed/seed_ecb.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/seed/seed_ecb.d.tmp -MT $@ -c -o $@ crypto/seed/seed_ecb.c
+	@touch crypto/seed/seed_ecb.d.tmp
+	@if cmp crypto/seed/seed_ecb.d.tmp crypto/seed/seed_ecb.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/seed/seed_ecb.d.tmp; \
+	else \
+		mv crypto/seed/seed_ecb.d.tmp crypto/seed/seed_ecb.d; \
+	fi
+crypto/seed/seed_ofb.o: crypto/seed/seed_ofb.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/seed/seed_ofb.d.tmp -MT $@ -c -o $@ crypto/seed/seed_ofb.c
+	@touch crypto/seed/seed_ofb.d.tmp
+	@if cmp crypto/seed/seed_ofb.d.tmp crypto/seed/seed_ofb.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/seed/seed_ofb.d.tmp; \
+	else \
+		mv crypto/seed/seed_ofb.d.tmp crypto/seed/seed_ofb.d; \
+	fi
+crypto/sha/sha1_one.o: crypto/sha/sha1_one.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/sha/sha1_one.d.tmp -MT $@ -c -o $@ crypto/sha/sha1_one.c
+	@touch crypto/sha/sha1_one.d.tmp
+	@if cmp crypto/sha/sha1_one.d.tmp crypto/sha/sha1_one.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/sha/sha1_one.d.tmp; \
+	else \
+		mv crypto/sha/sha1_one.d.tmp crypto/sha/sha1_one.d; \
+	fi
+crypto/sha/sha1dgst.o: crypto/sha/sha1dgst.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/sha/sha1dgst.d.tmp -MT $@ -c -o $@ crypto/sha/sha1dgst.c
+	@touch crypto/sha/sha1dgst.d.tmp
+	@if cmp crypto/sha/sha1dgst.d.tmp crypto/sha/sha1dgst.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/sha/sha1dgst.d.tmp; \
+	else \
+		mv crypto/sha/sha1dgst.d.tmp crypto/sha/sha1dgst.d; \
+	fi
+crypto/sha/sha256.o: crypto/sha/sha256.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/sha/sha256.d.tmp -MT $@ -c -o $@ crypto/sha/sha256.c
+	@touch crypto/sha/sha256.d.tmp
+	@if cmp crypto/sha/sha256.d.tmp crypto/sha/sha256.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/sha/sha256.d.tmp; \
+	else \
+		mv crypto/sha/sha256.d.tmp crypto/sha/sha256.d; \
+	fi
+crypto/sha/sha512.o: crypto/sha/sha512.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/sha/sha512.d.tmp -MT $@ -c -o $@ crypto/sha/sha512.c
+	@touch crypto/sha/sha512.d.tmp
+	@if cmp crypto/sha/sha512.d.tmp crypto/sha/sha512.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/sha/sha512.d.tmp; \
+	else \
+		mv crypto/sha/sha512.d.tmp crypto/sha/sha512.d; \
+	fi
+crypto/srp/srp_lib.o: crypto/srp/srp_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/srp/srp_lib.d.tmp -MT $@ -c -o $@ crypto/srp/srp_lib.c
+	@touch crypto/srp/srp_lib.d.tmp
+	@if cmp crypto/srp/srp_lib.d.tmp crypto/srp/srp_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/srp/srp_lib.d.tmp; \
+	else \
+		mv crypto/srp/srp_lib.d.tmp crypto/srp/srp_lib.d; \
+	fi
+crypto/srp/srp_vfy.o: crypto/srp/srp_vfy.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/srp/srp_vfy.d.tmp -MT $@ -c -o $@ crypto/srp/srp_vfy.c
+	@touch crypto/srp/srp_vfy.d.tmp
+	@if cmp crypto/srp/srp_vfy.d.tmp crypto/srp/srp_vfy.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/srp/srp_vfy.d.tmp; \
+	else \
+		mv crypto/srp/srp_vfy.d.tmp crypto/srp/srp_vfy.d; \
+	fi
+crypto/stack/stack.o: crypto/stack/stack.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/stack/stack.d.tmp -MT $@ -c -o $@ crypto/stack/stack.c
+	@touch crypto/stack/stack.d.tmp
+	@if cmp crypto/stack/stack.d.tmp crypto/stack/stack.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/stack/stack.d.tmp; \
+	else \
+		mv crypto/stack/stack.d.tmp crypto/stack/stack.d; \
+	fi
+crypto/threads_none.o: crypto/threads_none.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/threads_none.d.tmp -MT $@ -c -o $@ crypto/threads_none.c
+	@touch crypto/threads_none.d.tmp
+	@if cmp crypto/threads_none.d.tmp crypto/threads_none.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/threads_none.d.tmp; \
+	else \
+		mv crypto/threads_none.d.tmp crypto/threads_none.d; \
+	fi
+crypto/threads_pthread.o: crypto/threads_pthread.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/threads_pthread.d.tmp -MT $@ -c -o $@ crypto/threads_pthread.c
+	@touch crypto/threads_pthread.d.tmp
+	@if cmp crypto/threads_pthread.d.tmp crypto/threads_pthread.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/threads_pthread.d.tmp; \
+	else \
+		mv crypto/threads_pthread.d.tmp crypto/threads_pthread.d; \
+	fi
+crypto/threads_win.o: crypto/threads_win.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/threads_win.d.tmp -MT $@ -c -o $@ crypto/threads_win.c
+	@touch crypto/threads_win.d.tmp
+	@if cmp crypto/threads_win.d.tmp crypto/threads_win.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/threads_win.d.tmp; \
+	else \
+		mv crypto/threads_win.d.tmp crypto/threads_win.d; \
+	fi
+crypto/ts/ts_asn1.o: crypto/ts/ts_asn1.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ts/ts_asn1.d.tmp -MT $@ -c -o $@ crypto/ts/ts_asn1.c
+	@touch crypto/ts/ts_asn1.d.tmp
+	@if cmp crypto/ts/ts_asn1.d.tmp crypto/ts/ts_asn1.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ts/ts_asn1.d.tmp; \
+	else \
+		mv crypto/ts/ts_asn1.d.tmp crypto/ts/ts_asn1.d; \
+	fi
+crypto/ts/ts_conf.o: crypto/ts/ts_conf.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ts/ts_conf.d.tmp -MT $@ -c -o $@ crypto/ts/ts_conf.c
+	@touch crypto/ts/ts_conf.d.tmp
+	@if cmp crypto/ts/ts_conf.d.tmp crypto/ts/ts_conf.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ts/ts_conf.d.tmp; \
+	else \
+		mv crypto/ts/ts_conf.d.tmp crypto/ts/ts_conf.d; \
+	fi
+crypto/ts/ts_err.o: crypto/ts/ts_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ts/ts_err.d.tmp -MT $@ -c -o $@ crypto/ts/ts_err.c
+	@touch crypto/ts/ts_err.d.tmp
+	@if cmp crypto/ts/ts_err.d.tmp crypto/ts/ts_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ts/ts_err.d.tmp; \
+	else \
+		mv crypto/ts/ts_err.d.tmp crypto/ts/ts_err.d; \
+	fi
+crypto/ts/ts_lib.o: crypto/ts/ts_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ts/ts_lib.d.tmp -MT $@ -c -o $@ crypto/ts/ts_lib.c
+	@touch crypto/ts/ts_lib.d.tmp
+	@if cmp crypto/ts/ts_lib.d.tmp crypto/ts/ts_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ts/ts_lib.d.tmp; \
+	else \
+		mv crypto/ts/ts_lib.d.tmp crypto/ts/ts_lib.d; \
+	fi
+crypto/ts/ts_req_print.o: crypto/ts/ts_req_print.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ts/ts_req_print.d.tmp -MT $@ -c -o $@ crypto/ts/ts_req_print.c
+	@touch crypto/ts/ts_req_print.d.tmp
+	@if cmp crypto/ts/ts_req_print.d.tmp crypto/ts/ts_req_print.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ts/ts_req_print.d.tmp; \
+	else \
+		mv crypto/ts/ts_req_print.d.tmp crypto/ts/ts_req_print.d; \
+	fi
+crypto/ts/ts_req_utils.o: crypto/ts/ts_req_utils.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ts/ts_req_utils.d.tmp -MT $@ -c -o $@ crypto/ts/ts_req_utils.c
+	@touch crypto/ts/ts_req_utils.d.tmp
+	@if cmp crypto/ts/ts_req_utils.d.tmp crypto/ts/ts_req_utils.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ts/ts_req_utils.d.tmp; \
+	else \
+		mv crypto/ts/ts_req_utils.d.tmp crypto/ts/ts_req_utils.d; \
+	fi
+crypto/ts/ts_rsp_print.o: crypto/ts/ts_rsp_print.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ts/ts_rsp_print.d.tmp -MT $@ -c -o $@ crypto/ts/ts_rsp_print.c
+	@touch crypto/ts/ts_rsp_print.d.tmp
+	@if cmp crypto/ts/ts_rsp_print.d.tmp crypto/ts/ts_rsp_print.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ts/ts_rsp_print.d.tmp; \
+	else \
+		mv crypto/ts/ts_rsp_print.d.tmp crypto/ts/ts_rsp_print.d; \
+	fi
+crypto/ts/ts_rsp_sign.o: crypto/ts/ts_rsp_sign.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ts/ts_rsp_sign.d.tmp -MT $@ -c -o $@ crypto/ts/ts_rsp_sign.c
+	@touch crypto/ts/ts_rsp_sign.d.tmp
+	@if cmp crypto/ts/ts_rsp_sign.d.tmp crypto/ts/ts_rsp_sign.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ts/ts_rsp_sign.d.tmp; \
+	else \
+		mv crypto/ts/ts_rsp_sign.d.tmp crypto/ts/ts_rsp_sign.d; \
+	fi
+crypto/ts/ts_rsp_utils.o: crypto/ts/ts_rsp_utils.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ts/ts_rsp_utils.d.tmp -MT $@ -c -o $@ crypto/ts/ts_rsp_utils.c
+	@touch crypto/ts/ts_rsp_utils.d.tmp
+	@if cmp crypto/ts/ts_rsp_utils.d.tmp crypto/ts/ts_rsp_utils.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ts/ts_rsp_utils.d.tmp; \
+	else \
+		mv crypto/ts/ts_rsp_utils.d.tmp crypto/ts/ts_rsp_utils.d; \
+	fi
+crypto/ts/ts_rsp_verify.o: crypto/ts/ts_rsp_verify.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ts/ts_rsp_verify.d.tmp -MT $@ -c -o $@ crypto/ts/ts_rsp_verify.c
+	@touch crypto/ts/ts_rsp_verify.d.tmp
+	@if cmp crypto/ts/ts_rsp_verify.d.tmp crypto/ts/ts_rsp_verify.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ts/ts_rsp_verify.d.tmp; \
+	else \
+		mv crypto/ts/ts_rsp_verify.d.tmp crypto/ts/ts_rsp_verify.d; \
+	fi
+crypto/ts/ts_verify_ctx.o: crypto/ts/ts_verify_ctx.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/ts/ts_verify_ctx.d.tmp -MT $@ -c -o $@ crypto/ts/ts_verify_ctx.c
+	@touch crypto/ts/ts_verify_ctx.d.tmp
+	@if cmp crypto/ts/ts_verify_ctx.d.tmp crypto/ts/ts_verify_ctx.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/ts/ts_verify_ctx.d.tmp; \
+	else \
+		mv crypto/ts/ts_verify_ctx.d.tmp crypto/ts/ts_verify_ctx.d; \
+	fi
+crypto/txt_db/txt_db.o: crypto/txt_db/txt_db.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/txt_db/txt_db.d.tmp -MT $@ -c -o $@ crypto/txt_db/txt_db.c
+	@touch crypto/txt_db/txt_db.d.tmp
+	@if cmp crypto/txt_db/txt_db.d.tmp crypto/txt_db/txt_db.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/txt_db/txt_db.d.tmp; \
+	else \
+		mv crypto/txt_db/txt_db.d.tmp crypto/txt_db/txt_db.d; \
+	fi
+crypto/uid.o: crypto/uid.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/uid.d.tmp -MT $@ -c -o $@ crypto/uid.c
+	@touch crypto/uid.d.tmp
+	@if cmp crypto/uid.d.tmp crypto/uid.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/uid.d.tmp; \
+	else \
+		mv crypto/uid.d.tmp crypto/uid.d; \
+	fi
+crypto/whrlpool/wp_block.o: crypto/whrlpool/wp_block.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/whrlpool/wp_block.d.tmp -MT $@ -c -o $@ crypto/whrlpool/wp_block.c
+	@touch crypto/whrlpool/wp_block.d.tmp
+	@if cmp crypto/whrlpool/wp_block.d.tmp crypto/whrlpool/wp_block.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/whrlpool/wp_block.d.tmp; \
+	else \
+		mv crypto/whrlpool/wp_block.d.tmp crypto/whrlpool/wp_block.d; \
+	fi
+crypto/whrlpool/wp_dgst.o: crypto/whrlpool/wp_dgst.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/whrlpool/wp_dgst.d.tmp -MT $@ -c -o $@ crypto/whrlpool/wp_dgst.c
+	@touch crypto/whrlpool/wp_dgst.d.tmp
+	@if cmp crypto/whrlpool/wp_dgst.d.tmp crypto/whrlpool/wp_dgst.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/whrlpool/wp_dgst.d.tmp; \
+	else \
+		mv crypto/whrlpool/wp_dgst.d.tmp crypto/whrlpool/wp_dgst.d; \
+	fi
+crypto/x509/by_dir.o: crypto/x509/by_dir.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/by_dir.d.tmp -MT $@ -c -o $@ crypto/x509/by_dir.c
+	@touch crypto/x509/by_dir.d.tmp
+	@if cmp crypto/x509/by_dir.d.tmp crypto/x509/by_dir.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/by_dir.d.tmp; \
+	else \
+		mv crypto/x509/by_dir.d.tmp crypto/x509/by_dir.d; \
+	fi
+crypto/x509/by_file.o: crypto/x509/by_file.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/by_file.d.tmp -MT $@ -c -o $@ crypto/x509/by_file.c
+	@touch crypto/x509/by_file.d.tmp
+	@if cmp crypto/x509/by_file.d.tmp crypto/x509/by_file.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/by_file.d.tmp; \
+	else \
+		mv crypto/x509/by_file.d.tmp crypto/x509/by_file.d; \
+	fi
+crypto/x509/t_crl.o: crypto/x509/t_crl.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/t_crl.d.tmp -MT $@ -c -o $@ crypto/x509/t_crl.c
+	@touch crypto/x509/t_crl.d.tmp
+	@if cmp crypto/x509/t_crl.d.tmp crypto/x509/t_crl.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/t_crl.d.tmp; \
+	else \
+		mv crypto/x509/t_crl.d.tmp crypto/x509/t_crl.d; \
+	fi
+crypto/x509/t_req.o: crypto/x509/t_req.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/t_req.d.tmp -MT $@ -c -o $@ crypto/x509/t_req.c
+	@touch crypto/x509/t_req.d.tmp
+	@if cmp crypto/x509/t_req.d.tmp crypto/x509/t_req.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/t_req.d.tmp; \
+	else \
+		mv crypto/x509/t_req.d.tmp crypto/x509/t_req.d; \
+	fi
+crypto/x509/t_x509.o: crypto/x509/t_x509.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/t_x509.d.tmp -MT $@ -c -o $@ crypto/x509/t_x509.c
+	@touch crypto/x509/t_x509.d.tmp
+	@if cmp crypto/x509/t_x509.d.tmp crypto/x509/t_x509.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/t_x509.d.tmp; \
+	else \
+		mv crypto/x509/t_x509.d.tmp crypto/x509/t_x509.d; \
+	fi
+crypto/x509/x509_att.o: crypto/x509/x509_att.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509_att.d.tmp -MT $@ -c -o $@ crypto/x509/x509_att.c
+	@touch crypto/x509/x509_att.d.tmp
+	@if cmp crypto/x509/x509_att.d.tmp crypto/x509/x509_att.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509_att.d.tmp; \
+	else \
+		mv crypto/x509/x509_att.d.tmp crypto/x509/x509_att.d; \
+	fi
+crypto/x509/x509_cmp.o: crypto/x509/x509_cmp.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509_cmp.d.tmp -MT $@ -c -o $@ crypto/x509/x509_cmp.c
+	@touch crypto/x509/x509_cmp.d.tmp
+	@if cmp crypto/x509/x509_cmp.d.tmp crypto/x509/x509_cmp.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509_cmp.d.tmp; \
+	else \
+		mv crypto/x509/x509_cmp.d.tmp crypto/x509/x509_cmp.d; \
+	fi
+crypto/x509/x509_d2.o: crypto/x509/x509_d2.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509_d2.d.tmp -MT $@ -c -o $@ crypto/x509/x509_d2.c
+	@touch crypto/x509/x509_d2.d.tmp
+	@if cmp crypto/x509/x509_d2.d.tmp crypto/x509/x509_d2.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509_d2.d.tmp; \
+	else \
+		mv crypto/x509/x509_d2.d.tmp crypto/x509/x509_d2.d; \
+	fi
+crypto/x509/x509_def.o: crypto/x509/x509_def.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509_def.d.tmp -MT $@ -c -o $@ crypto/x509/x509_def.c
+	@touch crypto/x509/x509_def.d.tmp
+	@if cmp crypto/x509/x509_def.d.tmp crypto/x509/x509_def.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509_def.d.tmp; \
+	else \
+		mv crypto/x509/x509_def.d.tmp crypto/x509/x509_def.d; \
+	fi
+crypto/x509/x509_err.o: crypto/x509/x509_err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509_err.d.tmp -MT $@ -c -o $@ crypto/x509/x509_err.c
+	@touch crypto/x509/x509_err.d.tmp
+	@if cmp crypto/x509/x509_err.d.tmp crypto/x509/x509_err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509_err.d.tmp; \
+	else \
+		mv crypto/x509/x509_err.d.tmp crypto/x509/x509_err.d; \
+	fi
+crypto/x509/x509_ext.o: crypto/x509/x509_ext.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509_ext.d.tmp -MT $@ -c -o $@ crypto/x509/x509_ext.c
+	@touch crypto/x509/x509_ext.d.tmp
+	@if cmp crypto/x509/x509_ext.d.tmp crypto/x509/x509_ext.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509_ext.d.tmp; \
+	else \
+		mv crypto/x509/x509_ext.d.tmp crypto/x509/x509_ext.d; \
+	fi
+crypto/x509/x509_lu.o: crypto/x509/x509_lu.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509_lu.d.tmp -MT $@ -c -o $@ crypto/x509/x509_lu.c
+	@touch crypto/x509/x509_lu.d.tmp
+	@if cmp crypto/x509/x509_lu.d.tmp crypto/x509/x509_lu.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509_lu.d.tmp; \
+	else \
+		mv crypto/x509/x509_lu.d.tmp crypto/x509/x509_lu.d; \
+	fi
+crypto/x509/x509_obj.o: crypto/x509/x509_obj.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509_obj.d.tmp -MT $@ -c -o $@ crypto/x509/x509_obj.c
+	@touch crypto/x509/x509_obj.d.tmp
+	@if cmp crypto/x509/x509_obj.d.tmp crypto/x509/x509_obj.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509_obj.d.tmp; \
+	else \
+		mv crypto/x509/x509_obj.d.tmp crypto/x509/x509_obj.d; \
+	fi
+crypto/x509/x509_r2x.o: crypto/x509/x509_r2x.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509_r2x.d.tmp -MT $@ -c -o $@ crypto/x509/x509_r2x.c
+	@touch crypto/x509/x509_r2x.d.tmp
+	@if cmp crypto/x509/x509_r2x.d.tmp crypto/x509/x509_r2x.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509_r2x.d.tmp; \
+	else \
+		mv crypto/x509/x509_r2x.d.tmp crypto/x509/x509_r2x.d; \
+	fi
+crypto/x509/x509_req.o: crypto/x509/x509_req.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509_req.d.tmp -MT $@ -c -o $@ crypto/x509/x509_req.c
+	@touch crypto/x509/x509_req.d.tmp
+	@if cmp crypto/x509/x509_req.d.tmp crypto/x509/x509_req.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509_req.d.tmp; \
+	else \
+		mv crypto/x509/x509_req.d.tmp crypto/x509/x509_req.d; \
+	fi
+crypto/x509/x509_set.o: crypto/x509/x509_set.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509_set.d.tmp -MT $@ -c -o $@ crypto/x509/x509_set.c
+	@touch crypto/x509/x509_set.d.tmp
+	@if cmp crypto/x509/x509_set.d.tmp crypto/x509/x509_set.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509_set.d.tmp; \
+	else \
+		mv crypto/x509/x509_set.d.tmp crypto/x509/x509_set.d; \
+	fi
+crypto/x509/x509_trs.o: crypto/x509/x509_trs.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509_trs.d.tmp -MT $@ -c -o $@ crypto/x509/x509_trs.c
+	@touch crypto/x509/x509_trs.d.tmp
+	@if cmp crypto/x509/x509_trs.d.tmp crypto/x509/x509_trs.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509_trs.d.tmp; \
+	else \
+		mv crypto/x509/x509_trs.d.tmp crypto/x509/x509_trs.d; \
+	fi
+crypto/x509/x509_txt.o: crypto/x509/x509_txt.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509_txt.d.tmp -MT $@ -c -o $@ crypto/x509/x509_txt.c
+	@touch crypto/x509/x509_txt.d.tmp
+	@if cmp crypto/x509/x509_txt.d.tmp crypto/x509/x509_txt.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509_txt.d.tmp; \
+	else \
+		mv crypto/x509/x509_txt.d.tmp crypto/x509/x509_txt.d; \
+	fi
+crypto/x509/x509_v3.o: crypto/x509/x509_v3.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509_v3.d.tmp -MT $@ -c -o $@ crypto/x509/x509_v3.c
+	@touch crypto/x509/x509_v3.d.tmp
+	@if cmp crypto/x509/x509_v3.d.tmp crypto/x509/x509_v3.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509_v3.d.tmp; \
+	else \
+		mv crypto/x509/x509_v3.d.tmp crypto/x509/x509_v3.d; \
+	fi
+crypto/x509/x509_vfy.o: crypto/x509/x509_vfy.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509_vfy.d.tmp -MT $@ -c -o $@ crypto/x509/x509_vfy.c
+	@touch crypto/x509/x509_vfy.d.tmp
+	@if cmp crypto/x509/x509_vfy.d.tmp crypto/x509/x509_vfy.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509_vfy.d.tmp; \
+	else \
+		mv crypto/x509/x509_vfy.d.tmp crypto/x509/x509_vfy.d; \
+	fi
+crypto/x509/x509_vpm.o: crypto/x509/x509_vpm.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509_vpm.d.tmp -MT $@ -c -o $@ crypto/x509/x509_vpm.c
+	@touch crypto/x509/x509_vpm.d.tmp
+	@if cmp crypto/x509/x509_vpm.d.tmp crypto/x509/x509_vpm.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509_vpm.d.tmp; \
+	else \
+		mv crypto/x509/x509_vpm.d.tmp crypto/x509/x509_vpm.d; \
+	fi
+crypto/x509/x509cset.o: crypto/x509/x509cset.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509cset.d.tmp -MT $@ -c -o $@ crypto/x509/x509cset.c
+	@touch crypto/x509/x509cset.d.tmp
+	@if cmp crypto/x509/x509cset.d.tmp crypto/x509/x509cset.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509cset.d.tmp; \
+	else \
+		mv crypto/x509/x509cset.d.tmp crypto/x509/x509cset.d; \
+	fi
+crypto/x509/x509name.o: crypto/x509/x509name.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509name.d.tmp -MT $@ -c -o $@ crypto/x509/x509name.c
+	@touch crypto/x509/x509name.d.tmp
+	@if cmp crypto/x509/x509name.d.tmp crypto/x509/x509name.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509name.d.tmp; \
+	else \
+		mv crypto/x509/x509name.d.tmp crypto/x509/x509name.d; \
+	fi
+crypto/x509/x509rset.o: crypto/x509/x509rset.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509rset.d.tmp -MT $@ -c -o $@ crypto/x509/x509rset.c
+	@touch crypto/x509/x509rset.d.tmp
+	@if cmp crypto/x509/x509rset.d.tmp crypto/x509/x509rset.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509rset.d.tmp; \
+	else \
+		mv crypto/x509/x509rset.d.tmp crypto/x509/x509rset.d; \
+	fi
+crypto/x509/x509spki.o: crypto/x509/x509spki.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509spki.d.tmp -MT $@ -c -o $@ crypto/x509/x509spki.c
+	@touch crypto/x509/x509spki.d.tmp
+	@if cmp crypto/x509/x509spki.d.tmp crypto/x509/x509spki.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509spki.d.tmp; \
+	else \
+		mv crypto/x509/x509spki.d.tmp crypto/x509/x509spki.d; \
+	fi
+crypto/x509/x509type.o: crypto/x509/x509type.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x509type.d.tmp -MT $@ -c -o $@ crypto/x509/x509type.c
+	@touch crypto/x509/x509type.d.tmp
+	@if cmp crypto/x509/x509type.d.tmp crypto/x509/x509type.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x509type.d.tmp; \
+	else \
+		mv crypto/x509/x509type.d.tmp crypto/x509/x509type.d; \
+	fi
+crypto/x509/x_all.o: crypto/x509/x_all.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x_all.d.tmp -MT $@ -c -o $@ crypto/x509/x_all.c
+	@touch crypto/x509/x_all.d.tmp
+	@if cmp crypto/x509/x_all.d.tmp crypto/x509/x_all.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x_all.d.tmp; \
+	else \
+		mv crypto/x509/x_all.d.tmp crypto/x509/x_all.d; \
+	fi
+crypto/x509/x_attrib.o: crypto/x509/x_attrib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x_attrib.d.tmp -MT $@ -c -o $@ crypto/x509/x_attrib.c
+	@touch crypto/x509/x_attrib.d.tmp
+	@if cmp crypto/x509/x_attrib.d.tmp crypto/x509/x_attrib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x_attrib.d.tmp; \
+	else \
+		mv crypto/x509/x_attrib.d.tmp crypto/x509/x_attrib.d; \
+	fi
+crypto/x509/x_crl.o: crypto/x509/x_crl.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x_crl.d.tmp -MT $@ -c -o $@ crypto/x509/x_crl.c
+	@touch crypto/x509/x_crl.d.tmp
+	@if cmp crypto/x509/x_crl.d.tmp crypto/x509/x_crl.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x_crl.d.tmp; \
+	else \
+		mv crypto/x509/x_crl.d.tmp crypto/x509/x_crl.d; \
+	fi
+crypto/x509/x_exten.o: crypto/x509/x_exten.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x_exten.d.tmp -MT $@ -c -o $@ crypto/x509/x_exten.c
+	@touch crypto/x509/x_exten.d.tmp
+	@if cmp crypto/x509/x_exten.d.tmp crypto/x509/x_exten.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x_exten.d.tmp; \
+	else \
+		mv crypto/x509/x_exten.d.tmp crypto/x509/x_exten.d; \
+	fi
+crypto/x509/x_name.o: crypto/x509/x_name.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x_name.d.tmp -MT $@ -c -o $@ crypto/x509/x_name.c
+	@touch crypto/x509/x_name.d.tmp
+	@if cmp crypto/x509/x_name.d.tmp crypto/x509/x_name.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x_name.d.tmp; \
+	else \
+		mv crypto/x509/x_name.d.tmp crypto/x509/x_name.d; \
+	fi
+crypto/x509/x_pubkey.o: crypto/x509/x_pubkey.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x_pubkey.d.tmp -MT $@ -c -o $@ crypto/x509/x_pubkey.c
+	@touch crypto/x509/x_pubkey.d.tmp
+	@if cmp crypto/x509/x_pubkey.d.tmp crypto/x509/x_pubkey.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x_pubkey.d.tmp; \
+	else \
+		mv crypto/x509/x_pubkey.d.tmp crypto/x509/x_pubkey.d; \
+	fi
+crypto/x509/x_req.o: crypto/x509/x_req.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x_req.d.tmp -MT $@ -c -o $@ crypto/x509/x_req.c
+	@touch crypto/x509/x_req.d.tmp
+	@if cmp crypto/x509/x_req.d.tmp crypto/x509/x_req.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x_req.d.tmp; \
+	else \
+		mv crypto/x509/x_req.d.tmp crypto/x509/x_req.d; \
+	fi
+crypto/x509/x_x509.o: crypto/x509/x_x509.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x_x509.d.tmp -MT $@ -c -o $@ crypto/x509/x_x509.c
+	@touch crypto/x509/x_x509.d.tmp
+	@if cmp crypto/x509/x_x509.d.tmp crypto/x509/x_x509.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x_x509.d.tmp; \
+	else \
+		mv crypto/x509/x_x509.d.tmp crypto/x509/x_x509.d; \
+	fi
+crypto/x509/x_x509a.o: crypto/x509/x_x509a.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509/x_x509a.d.tmp -MT $@ -c -o $@ crypto/x509/x_x509a.c
+	@touch crypto/x509/x_x509a.d.tmp
+	@if cmp crypto/x509/x_x509a.d.tmp crypto/x509/x_x509a.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509/x_x509a.d.tmp; \
+	else \
+		mv crypto/x509/x_x509a.d.tmp crypto/x509/x_x509a.d; \
+	fi
+crypto/x509v3/pcy_cache.o: crypto/x509v3/pcy_cache.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/pcy_cache.d.tmp -MT $@ -c -o $@ crypto/x509v3/pcy_cache.c
+	@touch crypto/x509v3/pcy_cache.d.tmp
+	@if cmp crypto/x509v3/pcy_cache.d.tmp crypto/x509v3/pcy_cache.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/pcy_cache.d.tmp; \
+	else \
+		mv crypto/x509v3/pcy_cache.d.tmp crypto/x509v3/pcy_cache.d; \
+	fi
+crypto/x509v3/pcy_data.o: crypto/x509v3/pcy_data.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/pcy_data.d.tmp -MT $@ -c -o $@ crypto/x509v3/pcy_data.c
+	@touch crypto/x509v3/pcy_data.d.tmp
+	@if cmp crypto/x509v3/pcy_data.d.tmp crypto/x509v3/pcy_data.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/pcy_data.d.tmp; \
+	else \
+		mv crypto/x509v3/pcy_data.d.tmp crypto/x509v3/pcy_data.d; \
+	fi
+crypto/x509v3/pcy_lib.o: crypto/x509v3/pcy_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/pcy_lib.d.tmp -MT $@ -c -o $@ crypto/x509v3/pcy_lib.c
+	@touch crypto/x509v3/pcy_lib.d.tmp
+	@if cmp crypto/x509v3/pcy_lib.d.tmp crypto/x509v3/pcy_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/pcy_lib.d.tmp; \
+	else \
+		mv crypto/x509v3/pcy_lib.d.tmp crypto/x509v3/pcy_lib.d; \
+	fi
+crypto/x509v3/pcy_map.o: crypto/x509v3/pcy_map.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/pcy_map.d.tmp -MT $@ -c -o $@ crypto/x509v3/pcy_map.c
+	@touch crypto/x509v3/pcy_map.d.tmp
+	@if cmp crypto/x509v3/pcy_map.d.tmp crypto/x509v3/pcy_map.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/pcy_map.d.tmp; \
+	else \
+		mv crypto/x509v3/pcy_map.d.tmp crypto/x509v3/pcy_map.d; \
+	fi
+crypto/x509v3/pcy_node.o: crypto/x509v3/pcy_node.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/pcy_node.d.tmp -MT $@ -c -o $@ crypto/x509v3/pcy_node.c
+	@touch crypto/x509v3/pcy_node.d.tmp
+	@if cmp crypto/x509v3/pcy_node.d.tmp crypto/x509v3/pcy_node.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/pcy_node.d.tmp; \
+	else \
+		mv crypto/x509v3/pcy_node.d.tmp crypto/x509v3/pcy_node.d; \
+	fi
+crypto/x509v3/pcy_tree.o: crypto/x509v3/pcy_tree.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/pcy_tree.d.tmp -MT $@ -c -o $@ crypto/x509v3/pcy_tree.c
+	@touch crypto/x509v3/pcy_tree.d.tmp
+	@if cmp crypto/x509v3/pcy_tree.d.tmp crypto/x509v3/pcy_tree.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/pcy_tree.d.tmp; \
+	else \
+		mv crypto/x509v3/pcy_tree.d.tmp crypto/x509v3/pcy_tree.d; \
+	fi
+crypto/x509v3/v3_addr.o: crypto/x509v3/v3_addr.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_addr.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_addr.c
+	@touch crypto/x509v3/v3_addr.d.tmp
+	@if cmp crypto/x509v3/v3_addr.d.tmp crypto/x509v3/v3_addr.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_addr.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_addr.d.tmp crypto/x509v3/v3_addr.d; \
+	fi
+crypto/x509v3/v3_akey.o: crypto/x509v3/v3_akey.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_akey.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_akey.c
+	@touch crypto/x509v3/v3_akey.d.tmp
+	@if cmp crypto/x509v3/v3_akey.d.tmp crypto/x509v3/v3_akey.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_akey.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_akey.d.tmp crypto/x509v3/v3_akey.d; \
+	fi
+crypto/x509v3/v3_akeya.o: crypto/x509v3/v3_akeya.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_akeya.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_akeya.c
+	@touch crypto/x509v3/v3_akeya.d.tmp
+	@if cmp crypto/x509v3/v3_akeya.d.tmp crypto/x509v3/v3_akeya.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_akeya.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_akeya.d.tmp crypto/x509v3/v3_akeya.d; \
+	fi
+crypto/x509v3/v3_alt.o: crypto/x509v3/v3_alt.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_alt.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_alt.c
+	@touch crypto/x509v3/v3_alt.d.tmp
+	@if cmp crypto/x509v3/v3_alt.d.tmp crypto/x509v3/v3_alt.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_alt.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_alt.d.tmp crypto/x509v3/v3_alt.d; \
+	fi
+crypto/x509v3/v3_asid.o: crypto/x509v3/v3_asid.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_asid.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_asid.c
+	@touch crypto/x509v3/v3_asid.d.tmp
+	@if cmp crypto/x509v3/v3_asid.d.tmp crypto/x509v3/v3_asid.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_asid.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_asid.d.tmp crypto/x509v3/v3_asid.d; \
+	fi
+crypto/x509v3/v3_bcons.o: crypto/x509v3/v3_bcons.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_bcons.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_bcons.c
+	@touch crypto/x509v3/v3_bcons.d.tmp
+	@if cmp crypto/x509v3/v3_bcons.d.tmp crypto/x509v3/v3_bcons.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_bcons.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_bcons.d.tmp crypto/x509v3/v3_bcons.d; \
+	fi
+crypto/x509v3/v3_bitst.o: crypto/x509v3/v3_bitst.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_bitst.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_bitst.c
+	@touch crypto/x509v3/v3_bitst.d.tmp
+	@if cmp crypto/x509v3/v3_bitst.d.tmp crypto/x509v3/v3_bitst.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_bitst.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_bitst.d.tmp crypto/x509v3/v3_bitst.d; \
+	fi
+crypto/x509v3/v3_conf.o: crypto/x509v3/v3_conf.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_conf.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_conf.c
+	@touch crypto/x509v3/v3_conf.d.tmp
+	@if cmp crypto/x509v3/v3_conf.d.tmp crypto/x509v3/v3_conf.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_conf.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_conf.d.tmp crypto/x509v3/v3_conf.d; \
+	fi
+crypto/x509v3/v3_cpols.o: crypto/x509v3/v3_cpols.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_cpols.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_cpols.c
+	@touch crypto/x509v3/v3_cpols.d.tmp
+	@if cmp crypto/x509v3/v3_cpols.d.tmp crypto/x509v3/v3_cpols.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_cpols.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_cpols.d.tmp crypto/x509v3/v3_cpols.d; \
+	fi
+crypto/x509v3/v3_crld.o: crypto/x509v3/v3_crld.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_crld.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_crld.c
+	@touch crypto/x509v3/v3_crld.d.tmp
+	@if cmp crypto/x509v3/v3_crld.d.tmp crypto/x509v3/v3_crld.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_crld.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_crld.d.tmp crypto/x509v3/v3_crld.d; \
+	fi
+crypto/x509v3/v3_enum.o: crypto/x509v3/v3_enum.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_enum.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_enum.c
+	@touch crypto/x509v3/v3_enum.d.tmp
+	@if cmp crypto/x509v3/v3_enum.d.tmp crypto/x509v3/v3_enum.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_enum.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_enum.d.tmp crypto/x509v3/v3_enum.d; \
+	fi
+crypto/x509v3/v3_extku.o: crypto/x509v3/v3_extku.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_extku.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_extku.c
+	@touch crypto/x509v3/v3_extku.d.tmp
+	@if cmp crypto/x509v3/v3_extku.d.tmp crypto/x509v3/v3_extku.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_extku.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_extku.d.tmp crypto/x509v3/v3_extku.d; \
+	fi
+crypto/x509v3/v3_genn.o: crypto/x509v3/v3_genn.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_genn.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_genn.c
+	@touch crypto/x509v3/v3_genn.d.tmp
+	@if cmp crypto/x509v3/v3_genn.d.tmp crypto/x509v3/v3_genn.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_genn.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_genn.d.tmp crypto/x509v3/v3_genn.d; \
+	fi
+crypto/x509v3/v3_ia5.o: crypto/x509v3/v3_ia5.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_ia5.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_ia5.c
+	@touch crypto/x509v3/v3_ia5.d.tmp
+	@if cmp crypto/x509v3/v3_ia5.d.tmp crypto/x509v3/v3_ia5.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_ia5.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_ia5.d.tmp crypto/x509v3/v3_ia5.d; \
+	fi
+crypto/x509v3/v3_info.o: crypto/x509v3/v3_info.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_info.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_info.c
+	@touch crypto/x509v3/v3_info.d.tmp
+	@if cmp crypto/x509v3/v3_info.d.tmp crypto/x509v3/v3_info.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_info.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_info.d.tmp crypto/x509v3/v3_info.d; \
+	fi
+crypto/x509v3/v3_int.o: crypto/x509v3/v3_int.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_int.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_int.c
+	@touch crypto/x509v3/v3_int.d.tmp
+	@if cmp crypto/x509v3/v3_int.d.tmp crypto/x509v3/v3_int.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_int.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_int.d.tmp crypto/x509v3/v3_int.d; \
+	fi
+crypto/x509v3/v3_lib.o: crypto/x509v3/v3_lib.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_lib.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_lib.c
+	@touch crypto/x509v3/v3_lib.d.tmp
+	@if cmp crypto/x509v3/v3_lib.d.tmp crypto/x509v3/v3_lib.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_lib.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_lib.d.tmp crypto/x509v3/v3_lib.d; \
+	fi
+crypto/x509v3/v3_ncons.o: crypto/x509v3/v3_ncons.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_ncons.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_ncons.c
+	@touch crypto/x509v3/v3_ncons.d.tmp
+	@if cmp crypto/x509v3/v3_ncons.d.tmp crypto/x509v3/v3_ncons.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_ncons.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_ncons.d.tmp crypto/x509v3/v3_ncons.d; \
+	fi
+crypto/x509v3/v3_pci.o: crypto/x509v3/v3_pci.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_pci.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_pci.c
+	@touch crypto/x509v3/v3_pci.d.tmp
+	@if cmp crypto/x509v3/v3_pci.d.tmp crypto/x509v3/v3_pci.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_pci.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_pci.d.tmp crypto/x509v3/v3_pci.d; \
+	fi
+crypto/x509v3/v3_pcia.o: crypto/x509v3/v3_pcia.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_pcia.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_pcia.c
+	@touch crypto/x509v3/v3_pcia.d.tmp
+	@if cmp crypto/x509v3/v3_pcia.d.tmp crypto/x509v3/v3_pcia.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_pcia.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_pcia.d.tmp crypto/x509v3/v3_pcia.d; \
+	fi
+crypto/x509v3/v3_pcons.o: crypto/x509v3/v3_pcons.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_pcons.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_pcons.c
+	@touch crypto/x509v3/v3_pcons.d.tmp
+	@if cmp crypto/x509v3/v3_pcons.d.tmp crypto/x509v3/v3_pcons.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_pcons.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_pcons.d.tmp crypto/x509v3/v3_pcons.d; \
+	fi
+crypto/x509v3/v3_pku.o: crypto/x509v3/v3_pku.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_pku.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_pku.c
+	@touch crypto/x509v3/v3_pku.d.tmp
+	@if cmp crypto/x509v3/v3_pku.d.tmp crypto/x509v3/v3_pku.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_pku.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_pku.d.tmp crypto/x509v3/v3_pku.d; \
+	fi
+crypto/x509v3/v3_pmaps.o: crypto/x509v3/v3_pmaps.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_pmaps.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_pmaps.c
+	@touch crypto/x509v3/v3_pmaps.d.tmp
+	@if cmp crypto/x509v3/v3_pmaps.d.tmp crypto/x509v3/v3_pmaps.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_pmaps.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_pmaps.d.tmp crypto/x509v3/v3_pmaps.d; \
+	fi
+crypto/x509v3/v3_prn.o: crypto/x509v3/v3_prn.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_prn.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_prn.c
+	@touch crypto/x509v3/v3_prn.d.tmp
+	@if cmp crypto/x509v3/v3_prn.d.tmp crypto/x509v3/v3_prn.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_prn.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_prn.d.tmp crypto/x509v3/v3_prn.d; \
+	fi
+crypto/x509v3/v3_purp.o: crypto/x509v3/v3_purp.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_purp.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_purp.c
+	@touch crypto/x509v3/v3_purp.d.tmp
+	@if cmp crypto/x509v3/v3_purp.d.tmp crypto/x509v3/v3_purp.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_purp.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_purp.d.tmp crypto/x509v3/v3_purp.d; \
+	fi
+crypto/x509v3/v3_skey.o: crypto/x509v3/v3_skey.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_skey.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_skey.c
+	@touch crypto/x509v3/v3_skey.d.tmp
+	@if cmp crypto/x509v3/v3_skey.d.tmp crypto/x509v3/v3_skey.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_skey.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_skey.d.tmp crypto/x509v3/v3_skey.d; \
+	fi
+crypto/x509v3/v3_sxnet.o: crypto/x509v3/v3_sxnet.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_sxnet.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_sxnet.c
+	@touch crypto/x509v3/v3_sxnet.d.tmp
+	@if cmp crypto/x509v3/v3_sxnet.d.tmp crypto/x509v3/v3_sxnet.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_sxnet.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_sxnet.d.tmp crypto/x509v3/v3_sxnet.d; \
+	fi
+crypto/x509v3/v3_tlsf.o: crypto/x509v3/v3_tlsf.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_tlsf.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_tlsf.c
+	@touch crypto/x509v3/v3_tlsf.d.tmp
+	@if cmp crypto/x509v3/v3_tlsf.d.tmp crypto/x509v3/v3_tlsf.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_tlsf.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_tlsf.d.tmp crypto/x509v3/v3_tlsf.d; \
+	fi
+crypto/x509v3/v3_utl.o: crypto/x509v3/v3_utl.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3_utl.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3_utl.c
+	@touch crypto/x509v3/v3_utl.d.tmp
+	@if cmp crypto/x509v3/v3_utl.d.tmp crypto/x509v3/v3_utl.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3_utl.d.tmp; \
+	else \
+		mv crypto/x509v3/v3_utl.d.tmp crypto/x509v3/v3_utl.d; \
+	fi
+crypto/x509v3/v3err.o: crypto/x509v3/v3err.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF crypto/x509v3/v3err.d.tmp -MT $@ -c -o $@ crypto/x509v3/v3err.c
+	@touch crypto/x509v3/v3err.d.tmp
+	@if cmp crypto/x509v3/v3err.d.tmp crypto/x509v3/v3err.d > /dev/null 2> /dev/null; then \
+		rm -f crypto/x509v3/v3err.d.tmp; \
+	else \
+		mv crypto/x509v3/v3err.d.tmp crypto/x509v3/v3err.d; \
+	fi
+engines/e_capi.o: engines/e_capi.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF engines/e_capi.d.tmp -MT $@ -c -o $@ engines/e_capi.c
+	@touch engines/e_capi.d.tmp
+	@if cmp engines/e_capi.d.tmp engines/e_capi.d > /dev/null 2> /dev/null; then \
+		rm -f engines/e_capi.d.tmp; \
+	else \
+		mv engines/e_capi.d.tmp engines/e_capi.d; \
+	fi
+engines/e_padlock.o: engines/e_padlock.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF engines/e_padlock.d.tmp -MT $@ -c -o $@ engines/e_padlock.c
+	@touch engines/e_padlock.d.tmp
+	@if cmp engines/e_padlock.d.tmp engines/e_padlock.d > /dev/null 2> /dev/null; then \
+		rm -f engines/e_padlock.d.tmp; \
+	else \
+		mv engines/e_padlock.d.tmp engines/e_padlock.d; \
+	fi
+libssl.a: ssl/bio_ssl.o ssl/d1_lib.o ssl/d1_msg.o ssl/d1_srtp.o ssl/methods.o ssl/pqueue.o ssl/record/dtls1_bitmap.o ssl/record/rec_layer_d1.o ssl/record/rec_layer_s3.o ssl/record/ssl3_buffer.o ssl/record/ssl3_record.o ssl/s3_cbc.o ssl/s3_enc.o ssl/s3_lib.o ssl/s3_msg.o ssl/ssl_asn1.o ssl/ssl_cert.o ssl/ssl_ciph.o ssl/ssl_conf.o ssl/ssl_err.o ssl/ssl_init.o ssl/ssl_lib.o ssl/ssl_mcnf.o ssl/ssl_rsa.o ssl/ssl_sess.o ssl/ssl_stat.o ssl/ssl_txt.o ssl/ssl_utst.o ssl/statem/statem.o ssl/statem/statem_clnt.o ssl/statem/statem_dtls.o ssl/statem/statem_lib.o ssl/statem/statem_srvr.o ssl/t1_enc.o ssl/t1_ext.o ssl/t1_lib.o ssl/t1_reneg.o ssl/t1_trce.o ssl/tls_srp.o
+	$(AR) $@ $?
+	$(RANLIB) $@ || echo Never mind.
+ssl/bio_ssl.o: ssl/bio_ssl.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/bio_ssl.d.tmp -MT $@ -c -o $@ ssl/bio_ssl.c
+	@touch ssl/bio_ssl.d.tmp
+	@if cmp ssl/bio_ssl.d.tmp ssl/bio_ssl.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/bio_ssl.d.tmp; \
+	else \
+		mv ssl/bio_ssl.d.tmp ssl/bio_ssl.d; \
+	fi
+ssl/d1_lib.o: ssl/d1_lib.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/d1_lib.d.tmp -MT $@ -c -o $@ ssl/d1_lib.c
+	@touch ssl/d1_lib.d.tmp
+	@if cmp ssl/d1_lib.d.tmp ssl/d1_lib.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/d1_lib.d.tmp; \
+	else \
+		mv ssl/d1_lib.d.tmp ssl/d1_lib.d; \
+	fi
+ssl/d1_msg.o: ssl/d1_msg.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/d1_msg.d.tmp -MT $@ -c -o $@ ssl/d1_msg.c
+	@touch ssl/d1_msg.d.tmp
+	@if cmp ssl/d1_msg.d.tmp ssl/d1_msg.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/d1_msg.d.tmp; \
+	else \
+		mv ssl/d1_msg.d.tmp ssl/d1_msg.d; \
+	fi
+ssl/d1_srtp.o: ssl/d1_srtp.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/d1_srtp.d.tmp -MT $@ -c -o $@ ssl/d1_srtp.c
+	@touch ssl/d1_srtp.d.tmp
+	@if cmp ssl/d1_srtp.d.tmp ssl/d1_srtp.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/d1_srtp.d.tmp; \
+	else \
+		mv ssl/d1_srtp.d.tmp ssl/d1_srtp.d; \
+	fi
+ssl/methods.o: ssl/methods.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/methods.d.tmp -MT $@ -c -o $@ ssl/methods.c
+	@touch ssl/methods.d.tmp
+	@if cmp ssl/methods.d.tmp ssl/methods.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/methods.d.tmp; \
+	else \
+		mv ssl/methods.d.tmp ssl/methods.d; \
+	fi
+ssl/pqueue.o: ssl/pqueue.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/pqueue.d.tmp -MT $@ -c -o $@ ssl/pqueue.c
+	@touch ssl/pqueue.d.tmp
+	@if cmp ssl/pqueue.d.tmp ssl/pqueue.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/pqueue.d.tmp; \
+	else \
+		mv ssl/pqueue.d.tmp ssl/pqueue.d; \
+	fi
+ssl/record/dtls1_bitmap.o: ssl/record/dtls1_bitmap.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/record/dtls1_bitmap.d.tmp -MT $@ -c -o $@ ssl/record/dtls1_bitmap.c
+	@touch ssl/record/dtls1_bitmap.d.tmp
+	@if cmp ssl/record/dtls1_bitmap.d.tmp ssl/record/dtls1_bitmap.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/record/dtls1_bitmap.d.tmp; \
+	else \
+		mv ssl/record/dtls1_bitmap.d.tmp ssl/record/dtls1_bitmap.d; \
+	fi
+ssl/record/rec_layer_d1.o: ssl/record/rec_layer_d1.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/record/rec_layer_d1.d.tmp -MT $@ -c -o $@ ssl/record/rec_layer_d1.c
+	@touch ssl/record/rec_layer_d1.d.tmp
+	@if cmp ssl/record/rec_layer_d1.d.tmp ssl/record/rec_layer_d1.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/record/rec_layer_d1.d.tmp; \
+	else \
+		mv ssl/record/rec_layer_d1.d.tmp ssl/record/rec_layer_d1.d; \
+	fi
+ssl/record/rec_layer_s3.o: ssl/record/rec_layer_s3.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/record/rec_layer_s3.d.tmp -MT $@ -c -o $@ ssl/record/rec_layer_s3.c
+	@touch ssl/record/rec_layer_s3.d.tmp
+	@if cmp ssl/record/rec_layer_s3.d.tmp ssl/record/rec_layer_s3.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/record/rec_layer_s3.d.tmp; \
+	else \
+		mv ssl/record/rec_layer_s3.d.tmp ssl/record/rec_layer_s3.d; \
+	fi
+ssl/record/ssl3_buffer.o: ssl/record/ssl3_buffer.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/record/ssl3_buffer.d.tmp -MT $@ -c -o $@ ssl/record/ssl3_buffer.c
+	@touch ssl/record/ssl3_buffer.d.tmp
+	@if cmp ssl/record/ssl3_buffer.d.tmp ssl/record/ssl3_buffer.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/record/ssl3_buffer.d.tmp; \
+	else \
+		mv ssl/record/ssl3_buffer.d.tmp ssl/record/ssl3_buffer.d; \
+	fi
+ssl/record/ssl3_record.o: ssl/record/ssl3_record.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/record/ssl3_record.d.tmp -MT $@ -c -o $@ ssl/record/ssl3_record.c
+	@touch ssl/record/ssl3_record.d.tmp
+	@if cmp ssl/record/ssl3_record.d.tmp ssl/record/ssl3_record.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/record/ssl3_record.d.tmp; \
+	else \
+		mv ssl/record/ssl3_record.d.tmp ssl/record/ssl3_record.d; \
+	fi
+ssl/s3_cbc.o: ssl/s3_cbc.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/s3_cbc.d.tmp -MT $@ -c -o $@ ssl/s3_cbc.c
+	@touch ssl/s3_cbc.d.tmp
+	@if cmp ssl/s3_cbc.d.tmp ssl/s3_cbc.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/s3_cbc.d.tmp; \
+	else \
+		mv ssl/s3_cbc.d.tmp ssl/s3_cbc.d; \
+	fi
+ssl/s3_enc.o: ssl/s3_enc.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/s3_enc.d.tmp -MT $@ -c -o $@ ssl/s3_enc.c
+	@touch ssl/s3_enc.d.tmp
+	@if cmp ssl/s3_enc.d.tmp ssl/s3_enc.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/s3_enc.d.tmp; \
+	else \
+		mv ssl/s3_enc.d.tmp ssl/s3_enc.d; \
+	fi
+ssl/s3_lib.o: ssl/s3_lib.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/s3_lib.d.tmp -MT $@ -c -o $@ ssl/s3_lib.c
+	@touch ssl/s3_lib.d.tmp
+	@if cmp ssl/s3_lib.d.tmp ssl/s3_lib.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/s3_lib.d.tmp; \
+	else \
+		mv ssl/s3_lib.d.tmp ssl/s3_lib.d; \
+	fi
+ssl/s3_msg.o: ssl/s3_msg.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/s3_msg.d.tmp -MT $@ -c -o $@ ssl/s3_msg.c
+	@touch ssl/s3_msg.d.tmp
+	@if cmp ssl/s3_msg.d.tmp ssl/s3_msg.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/s3_msg.d.tmp; \
+	else \
+		mv ssl/s3_msg.d.tmp ssl/s3_msg.d; \
+	fi
+ssl/ssl_asn1.o: ssl/ssl_asn1.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/ssl_asn1.d.tmp -MT $@ -c -o $@ ssl/ssl_asn1.c
+	@touch ssl/ssl_asn1.d.tmp
+	@if cmp ssl/ssl_asn1.d.tmp ssl/ssl_asn1.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/ssl_asn1.d.tmp; \
+	else \
+		mv ssl/ssl_asn1.d.tmp ssl/ssl_asn1.d; \
+	fi
+ssl/ssl_cert.o: ssl/ssl_cert.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/ssl_cert.d.tmp -MT $@ -c -o $@ ssl/ssl_cert.c
+	@touch ssl/ssl_cert.d.tmp
+	@if cmp ssl/ssl_cert.d.tmp ssl/ssl_cert.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/ssl_cert.d.tmp; \
+	else \
+		mv ssl/ssl_cert.d.tmp ssl/ssl_cert.d; \
+	fi
+ssl/ssl_ciph.o: ssl/ssl_ciph.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/ssl_ciph.d.tmp -MT $@ -c -o $@ ssl/ssl_ciph.c
+	@touch ssl/ssl_ciph.d.tmp
+	@if cmp ssl/ssl_ciph.d.tmp ssl/ssl_ciph.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/ssl_ciph.d.tmp; \
+	else \
+		mv ssl/ssl_ciph.d.tmp ssl/ssl_ciph.d; \
+	fi
+ssl/ssl_conf.o: ssl/ssl_conf.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/ssl_conf.d.tmp -MT $@ -c -o $@ ssl/ssl_conf.c
+	@touch ssl/ssl_conf.d.tmp
+	@if cmp ssl/ssl_conf.d.tmp ssl/ssl_conf.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/ssl_conf.d.tmp; \
+	else \
+		mv ssl/ssl_conf.d.tmp ssl/ssl_conf.d; \
+	fi
+ssl/ssl_err.o: ssl/ssl_err.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/ssl_err.d.tmp -MT $@ -c -o $@ ssl/ssl_err.c
+	@touch ssl/ssl_err.d.tmp
+	@if cmp ssl/ssl_err.d.tmp ssl/ssl_err.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/ssl_err.d.tmp; \
+	else \
+		mv ssl/ssl_err.d.tmp ssl/ssl_err.d; \
+	fi
+ssl/ssl_init.o: ssl/ssl_init.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/ssl_init.d.tmp -MT $@ -c -o $@ ssl/ssl_init.c
+	@touch ssl/ssl_init.d.tmp
+	@if cmp ssl/ssl_init.d.tmp ssl/ssl_init.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/ssl_init.d.tmp; \
+	else \
+		mv ssl/ssl_init.d.tmp ssl/ssl_init.d; \
+	fi
+ssl/ssl_lib.o: ssl/ssl_lib.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/ssl_lib.d.tmp -MT $@ -c -o $@ ssl/ssl_lib.c
+	@touch ssl/ssl_lib.d.tmp
+	@if cmp ssl/ssl_lib.d.tmp ssl/ssl_lib.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/ssl_lib.d.tmp; \
+	else \
+		mv ssl/ssl_lib.d.tmp ssl/ssl_lib.d; \
+	fi
+ssl/ssl_mcnf.o: ssl/ssl_mcnf.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/ssl_mcnf.d.tmp -MT $@ -c -o $@ ssl/ssl_mcnf.c
+	@touch ssl/ssl_mcnf.d.tmp
+	@if cmp ssl/ssl_mcnf.d.tmp ssl/ssl_mcnf.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/ssl_mcnf.d.tmp; \
+	else \
+		mv ssl/ssl_mcnf.d.tmp ssl/ssl_mcnf.d; \
+	fi
+ssl/ssl_rsa.o: ssl/ssl_rsa.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/ssl_rsa.d.tmp -MT $@ -c -o $@ ssl/ssl_rsa.c
+	@touch ssl/ssl_rsa.d.tmp
+	@if cmp ssl/ssl_rsa.d.tmp ssl/ssl_rsa.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/ssl_rsa.d.tmp; \
+	else \
+		mv ssl/ssl_rsa.d.tmp ssl/ssl_rsa.d; \
+	fi
+ssl/ssl_sess.o: ssl/ssl_sess.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/ssl_sess.d.tmp -MT $@ -c -o $@ ssl/ssl_sess.c
+	@touch ssl/ssl_sess.d.tmp
+	@if cmp ssl/ssl_sess.d.tmp ssl/ssl_sess.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/ssl_sess.d.tmp; \
+	else \
+		mv ssl/ssl_sess.d.tmp ssl/ssl_sess.d; \
+	fi
+ssl/ssl_stat.o: ssl/ssl_stat.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/ssl_stat.d.tmp -MT $@ -c -o $@ ssl/ssl_stat.c
+	@touch ssl/ssl_stat.d.tmp
+	@if cmp ssl/ssl_stat.d.tmp ssl/ssl_stat.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/ssl_stat.d.tmp; \
+	else \
+		mv ssl/ssl_stat.d.tmp ssl/ssl_stat.d; \
+	fi
+ssl/ssl_txt.o: ssl/ssl_txt.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/ssl_txt.d.tmp -MT $@ -c -o $@ ssl/ssl_txt.c
+	@touch ssl/ssl_txt.d.tmp
+	@if cmp ssl/ssl_txt.d.tmp ssl/ssl_txt.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/ssl_txt.d.tmp; \
+	else \
+		mv ssl/ssl_txt.d.tmp ssl/ssl_txt.d; \
+	fi
+ssl/ssl_utst.o: ssl/ssl_utst.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/ssl_utst.d.tmp -MT $@ -c -o $@ ssl/ssl_utst.c
+	@touch ssl/ssl_utst.d.tmp
+	@if cmp ssl/ssl_utst.d.tmp ssl/ssl_utst.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/ssl_utst.d.tmp; \
+	else \
+		mv ssl/ssl_utst.d.tmp ssl/ssl_utst.d; \
+	fi
+ssl/statem/statem.o: ssl/statem/statem.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/statem/statem.d.tmp -MT $@ -c -o $@ ssl/statem/statem.c
+	@touch ssl/statem/statem.d.tmp
+	@if cmp ssl/statem/statem.d.tmp ssl/statem/statem.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/statem/statem.d.tmp; \
+	else \
+		mv ssl/statem/statem.d.tmp ssl/statem/statem.d; \
+	fi
+ssl/statem/statem_clnt.o: ssl/statem/statem_clnt.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/statem/statem_clnt.d.tmp -MT $@ -c -o $@ ssl/statem/statem_clnt.c
+	@touch ssl/statem/statem_clnt.d.tmp
+	@if cmp ssl/statem/statem_clnt.d.tmp ssl/statem/statem_clnt.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/statem/statem_clnt.d.tmp; \
+	else \
+		mv ssl/statem/statem_clnt.d.tmp ssl/statem/statem_clnt.d; \
+	fi
+ssl/statem/statem_dtls.o: ssl/statem/statem_dtls.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/statem/statem_dtls.d.tmp -MT $@ -c -o $@ ssl/statem/statem_dtls.c
+	@touch ssl/statem/statem_dtls.d.tmp
+	@if cmp ssl/statem/statem_dtls.d.tmp ssl/statem/statem_dtls.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/statem/statem_dtls.d.tmp; \
+	else \
+		mv ssl/statem/statem_dtls.d.tmp ssl/statem/statem_dtls.d; \
+	fi
+ssl/statem/statem_lib.o: ssl/statem/statem_lib.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/statem/statem_lib.d.tmp -MT $@ -c -o $@ ssl/statem/statem_lib.c
+	@touch ssl/statem/statem_lib.d.tmp
+	@if cmp ssl/statem/statem_lib.d.tmp ssl/statem/statem_lib.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/statem/statem_lib.d.tmp; \
+	else \
+		mv ssl/statem/statem_lib.d.tmp ssl/statem/statem_lib.d; \
+	fi
+ssl/statem/statem_srvr.o: ssl/statem/statem_srvr.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/statem/statem_srvr.d.tmp -MT $@ -c -o $@ ssl/statem/statem_srvr.c
+	@touch ssl/statem/statem_srvr.d.tmp
+	@if cmp ssl/statem/statem_srvr.d.tmp ssl/statem/statem_srvr.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/statem/statem_srvr.d.tmp; \
+	else \
+		mv ssl/statem/statem_srvr.d.tmp ssl/statem/statem_srvr.d; \
+	fi
+ssl/t1_enc.o: ssl/t1_enc.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/t1_enc.d.tmp -MT $@ -c -o $@ ssl/t1_enc.c
+	@touch ssl/t1_enc.d.tmp
+	@if cmp ssl/t1_enc.d.tmp ssl/t1_enc.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/t1_enc.d.tmp; \
+	else \
+		mv ssl/t1_enc.d.tmp ssl/t1_enc.d; \
+	fi
+ssl/t1_ext.o: ssl/t1_ext.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/t1_ext.d.tmp -MT $@ -c -o $@ ssl/t1_ext.c
+	@touch ssl/t1_ext.d.tmp
+	@if cmp ssl/t1_ext.d.tmp ssl/t1_ext.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/t1_ext.d.tmp; \
+	else \
+		mv ssl/t1_ext.d.tmp ssl/t1_ext.d; \
+	fi
+ssl/t1_lib.o: ssl/t1_lib.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/t1_lib.d.tmp -MT $@ -c -o $@ ssl/t1_lib.c
+	@touch ssl/t1_lib.d.tmp
+	@if cmp ssl/t1_lib.d.tmp ssl/t1_lib.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/t1_lib.d.tmp; \
+	else \
+		mv ssl/t1_lib.d.tmp ssl/t1_lib.d; \
+	fi
+ssl/t1_reneg.o: ssl/t1_reneg.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/t1_reneg.d.tmp -MT $@ -c -o $@ ssl/t1_reneg.c
+	@touch ssl/t1_reneg.d.tmp
+	@if cmp ssl/t1_reneg.d.tmp ssl/t1_reneg.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/t1_reneg.d.tmp; \
+	else \
+		mv ssl/t1_reneg.d.tmp ssl/t1_reneg.d; \
+	fi
+ssl/t1_trce.o: ssl/t1_trce.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/t1_trce.d.tmp -MT $@ -c -o $@ ssl/t1_trce.c
+	@touch ssl/t1_trce.d.tmp
+	@if cmp ssl/t1_trce.d.tmp ssl/t1_trce.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/t1_trce.d.tmp; \
+	else \
+		mv ssl/t1_trce.d.tmp ssl/t1_trce.d; \
+	fi
+ssl/tls_srp.o: ssl/tls_srp.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(LIB_CFLAGS) -MMD -MF ssl/tls_srp.d.tmp -MT $@ -c -o $@ ssl/tls_srp.c
+	@touch ssl/tls_srp.d.tmp
+	@if cmp ssl/tls_srp.d.tmp ssl/tls_srp.d > /dev/null 2> /dev/null; then \
+		rm -f ssl/tls_srp.d.tmp; \
+	else \
+		mv ssl/tls_srp.d.tmp ssl/tls_srp.d; \
+	fi
+apps/openssl: apps/app_rand.o apps/apps.o apps/asn1pars.o apps/ca.o apps/ciphers.o apps/cms.o apps/crl.o apps/crl2p7.o apps/dgst.o apps/dhparam.o apps/dsa.o apps/dsaparam.o apps/ec.o apps/ecparam.o apps/enc.o apps/engine.o apps/errstr.o apps/gendsa.o apps/genpkey.o apps/genrsa.o apps/nseq.o apps/ocsp.o apps/openssl.o apps/opt.o apps/passwd.o apps/pkcs12.o apps/pkcs7.o apps/pkcs8.o apps/pkey.o apps/pkeyparam.o apps/pkeyutl.o apps/prime.o apps/rand.o apps/rehash.o apps/req.o apps/rsa.o apps/rsautl.o apps/s_cb.o apps/s_client.o apps/s_server.o apps/s_socket.o apps/s_time.o apps/sess_id.o apps/smime.o apps/speed.o apps/spkac.o apps/srp.o apps/ts.o apps/verify.o apps/version.o apps/x509.o libssl.a libcrypto.a
+	$(RM) apps/openssl
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=apps/openssl OBJECTS="apps/app_rand.o apps/apps.o apps/asn1pars.o apps/ca.o apps/ciphers.o apps/cms.o apps/crl.o apps/crl2p7.o apps/dgst.o apps/dhparam.o apps/dsa.o apps/dsaparam.o apps/ec.o apps/ecparam.o apps/enc.o apps/engine.o apps/errstr.o apps/gendsa.o apps/genpkey.o apps/genrsa.o apps/nseq.o apps/ocsp.o apps/openssl.o apps/opt.o apps/passwd.o apps/pkcs12.o apps/pkcs7.o apps/pkcs8.o apps/pkey.o apps/pkeyparam.o apps/pkeyutl.o apps/prime.o apps/rand.o apps/rehash.o apps/req.o apps/rsa.o apps/rsautl.o apps/s_cb.o apps/s_client.o apps/s_server.o apps/s_socket.o apps/s_time.o apps/sess_id.o apps/smime.o apps/speed.o apps/spkac.o apps/srp.o apps/ts.o apps/verify.o apps/version.o apps/x509.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+apps/app_rand.o: apps/app_rand.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/app_rand.d.tmp -MT $@ -c -o $@ apps/app_rand.c
+	@touch apps/app_rand.d.tmp
+	@if cmp apps/app_rand.d.tmp apps/app_rand.d > /dev/null 2> /dev/null; then \
+		rm -f apps/app_rand.d.tmp; \
+	else \
+		mv apps/app_rand.d.tmp apps/app_rand.d; \
+	fi
+apps/apps.o: apps/apps.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/apps.d.tmp -MT $@ -c -o $@ apps/apps.c
+	@touch apps/apps.d.tmp
+	@if cmp apps/apps.d.tmp apps/apps.d > /dev/null 2> /dev/null; then \
+		rm -f apps/apps.d.tmp; \
+	else \
+		mv apps/apps.d.tmp apps/apps.d; \
+	fi
+apps/asn1pars.o: apps/asn1pars.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/asn1pars.d.tmp -MT $@ -c -o $@ apps/asn1pars.c
+	@touch apps/asn1pars.d.tmp
+	@if cmp apps/asn1pars.d.tmp apps/asn1pars.d > /dev/null 2> /dev/null; then \
+		rm -f apps/asn1pars.d.tmp; \
+	else \
+		mv apps/asn1pars.d.tmp apps/asn1pars.d; \
+	fi
+apps/ca.o: apps/ca.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/ca.d.tmp -MT $@ -c -o $@ apps/ca.c
+	@touch apps/ca.d.tmp
+	@if cmp apps/ca.d.tmp apps/ca.d > /dev/null 2> /dev/null; then \
+		rm -f apps/ca.d.tmp; \
+	else \
+		mv apps/ca.d.tmp apps/ca.d; \
+	fi
+apps/ciphers.o: apps/ciphers.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/ciphers.d.tmp -MT $@ -c -o $@ apps/ciphers.c
+	@touch apps/ciphers.d.tmp
+	@if cmp apps/ciphers.d.tmp apps/ciphers.d > /dev/null 2> /dev/null; then \
+		rm -f apps/ciphers.d.tmp; \
+	else \
+		mv apps/ciphers.d.tmp apps/ciphers.d; \
+	fi
+apps/cms.o: apps/cms.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/cms.d.tmp -MT $@ -c -o $@ apps/cms.c
+	@touch apps/cms.d.tmp
+	@if cmp apps/cms.d.tmp apps/cms.d > /dev/null 2> /dev/null; then \
+		rm -f apps/cms.d.tmp; \
+	else \
+		mv apps/cms.d.tmp apps/cms.d; \
+	fi
+apps/crl.o: apps/crl.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/crl.d.tmp -MT $@ -c -o $@ apps/crl.c
+	@touch apps/crl.d.tmp
+	@if cmp apps/crl.d.tmp apps/crl.d > /dev/null 2> /dev/null; then \
+		rm -f apps/crl.d.tmp; \
+	else \
+		mv apps/crl.d.tmp apps/crl.d; \
+	fi
+apps/crl2p7.o: apps/crl2p7.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/crl2p7.d.tmp -MT $@ -c -o $@ apps/crl2p7.c
+	@touch apps/crl2p7.d.tmp
+	@if cmp apps/crl2p7.d.tmp apps/crl2p7.d > /dev/null 2> /dev/null; then \
+		rm -f apps/crl2p7.d.tmp; \
+	else \
+		mv apps/crl2p7.d.tmp apps/crl2p7.d; \
+	fi
+apps/dgst.o: apps/dgst.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/dgst.d.tmp -MT $@ -c -o $@ apps/dgst.c
+	@touch apps/dgst.d.tmp
+	@if cmp apps/dgst.d.tmp apps/dgst.d > /dev/null 2> /dev/null; then \
+		rm -f apps/dgst.d.tmp; \
+	else \
+		mv apps/dgst.d.tmp apps/dgst.d; \
+	fi
+apps/dhparam.o: apps/dhparam.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/dhparam.d.tmp -MT $@ -c -o $@ apps/dhparam.c
+	@touch apps/dhparam.d.tmp
+	@if cmp apps/dhparam.d.tmp apps/dhparam.d > /dev/null 2> /dev/null; then \
+		rm -f apps/dhparam.d.tmp; \
+	else \
+		mv apps/dhparam.d.tmp apps/dhparam.d; \
+	fi
+apps/dsa.o: apps/dsa.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/dsa.d.tmp -MT $@ -c -o $@ apps/dsa.c
+	@touch apps/dsa.d.tmp
+	@if cmp apps/dsa.d.tmp apps/dsa.d > /dev/null 2> /dev/null; then \
+		rm -f apps/dsa.d.tmp; \
+	else \
+		mv apps/dsa.d.tmp apps/dsa.d; \
+	fi
+apps/dsaparam.o: apps/dsaparam.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/dsaparam.d.tmp -MT $@ -c -o $@ apps/dsaparam.c
+	@touch apps/dsaparam.d.tmp
+	@if cmp apps/dsaparam.d.tmp apps/dsaparam.d > /dev/null 2> /dev/null; then \
+		rm -f apps/dsaparam.d.tmp; \
+	else \
+		mv apps/dsaparam.d.tmp apps/dsaparam.d; \
+	fi
+apps/ec.o: apps/ec.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/ec.d.tmp -MT $@ -c -o $@ apps/ec.c
+	@touch apps/ec.d.tmp
+	@if cmp apps/ec.d.tmp apps/ec.d > /dev/null 2> /dev/null; then \
+		rm -f apps/ec.d.tmp; \
+	else \
+		mv apps/ec.d.tmp apps/ec.d; \
+	fi
+apps/ecparam.o: apps/ecparam.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/ecparam.d.tmp -MT $@ -c -o $@ apps/ecparam.c
+	@touch apps/ecparam.d.tmp
+	@if cmp apps/ecparam.d.tmp apps/ecparam.d > /dev/null 2> /dev/null; then \
+		rm -f apps/ecparam.d.tmp; \
+	else \
+		mv apps/ecparam.d.tmp apps/ecparam.d; \
+	fi
+apps/enc.o: apps/enc.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/enc.d.tmp -MT $@ -c -o $@ apps/enc.c
+	@touch apps/enc.d.tmp
+	@if cmp apps/enc.d.tmp apps/enc.d > /dev/null 2> /dev/null; then \
+		rm -f apps/enc.d.tmp; \
+	else \
+		mv apps/enc.d.tmp apps/enc.d; \
+	fi
+apps/engine.o: apps/engine.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/engine.d.tmp -MT $@ -c -o $@ apps/engine.c
+	@touch apps/engine.d.tmp
+	@if cmp apps/engine.d.tmp apps/engine.d > /dev/null 2> /dev/null; then \
+		rm -f apps/engine.d.tmp; \
+	else \
+		mv apps/engine.d.tmp apps/engine.d; \
+	fi
+apps/errstr.o: apps/errstr.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/errstr.d.tmp -MT $@ -c -o $@ apps/errstr.c
+	@touch apps/errstr.d.tmp
+	@if cmp apps/errstr.d.tmp apps/errstr.d > /dev/null 2> /dev/null; then \
+		rm -f apps/errstr.d.tmp; \
+	else \
+		mv apps/errstr.d.tmp apps/errstr.d; \
+	fi
+apps/gendsa.o: apps/gendsa.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/gendsa.d.tmp -MT $@ -c -o $@ apps/gendsa.c
+	@touch apps/gendsa.d.tmp
+	@if cmp apps/gendsa.d.tmp apps/gendsa.d > /dev/null 2> /dev/null; then \
+		rm -f apps/gendsa.d.tmp; \
+	else \
+		mv apps/gendsa.d.tmp apps/gendsa.d; \
+	fi
+apps/genpkey.o: apps/genpkey.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/genpkey.d.tmp -MT $@ -c -o $@ apps/genpkey.c
+	@touch apps/genpkey.d.tmp
+	@if cmp apps/genpkey.d.tmp apps/genpkey.d > /dev/null 2> /dev/null; then \
+		rm -f apps/genpkey.d.tmp; \
+	else \
+		mv apps/genpkey.d.tmp apps/genpkey.d; \
+	fi
+apps/genrsa.o: apps/genrsa.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/genrsa.d.tmp -MT $@ -c -o $@ apps/genrsa.c
+	@touch apps/genrsa.d.tmp
+	@if cmp apps/genrsa.d.tmp apps/genrsa.d > /dev/null 2> /dev/null; then \
+		rm -f apps/genrsa.d.tmp; \
+	else \
+		mv apps/genrsa.d.tmp apps/genrsa.d; \
+	fi
+apps/nseq.o: apps/nseq.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/nseq.d.tmp -MT $@ -c -o $@ apps/nseq.c
+	@touch apps/nseq.d.tmp
+	@if cmp apps/nseq.d.tmp apps/nseq.d > /dev/null 2> /dev/null; then \
+		rm -f apps/nseq.d.tmp; \
+	else \
+		mv apps/nseq.d.tmp apps/nseq.d; \
+	fi
+apps/ocsp.o: apps/ocsp.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/ocsp.d.tmp -MT $@ -c -o $@ apps/ocsp.c
+	@touch apps/ocsp.d.tmp
+	@if cmp apps/ocsp.d.tmp apps/ocsp.d > /dev/null 2> /dev/null; then \
+		rm -f apps/ocsp.d.tmp; \
+	else \
+		mv apps/ocsp.d.tmp apps/ocsp.d; \
+	fi
+apps/openssl.o: apps/openssl.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/openssl.d.tmp -MT $@ -c -o $@ apps/openssl.c
+	@touch apps/openssl.d.tmp
+	@if cmp apps/openssl.d.tmp apps/openssl.d > /dev/null 2> /dev/null; then \
+		rm -f apps/openssl.d.tmp; \
+	else \
+		mv apps/openssl.d.tmp apps/openssl.d; \
+	fi
+apps/opt.o: apps/opt.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/opt.d.tmp -MT $@ -c -o $@ apps/opt.c
+	@touch apps/opt.d.tmp
+	@if cmp apps/opt.d.tmp apps/opt.d > /dev/null 2> /dev/null; then \
+		rm -f apps/opt.d.tmp; \
+	else \
+		mv apps/opt.d.tmp apps/opt.d; \
+	fi
+apps/passwd.o: apps/passwd.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/passwd.d.tmp -MT $@ -c -o $@ apps/passwd.c
+	@touch apps/passwd.d.tmp
+	@if cmp apps/passwd.d.tmp apps/passwd.d > /dev/null 2> /dev/null; then \
+		rm -f apps/passwd.d.tmp; \
+	else \
+		mv apps/passwd.d.tmp apps/passwd.d; \
+	fi
+apps/pkcs12.o: apps/pkcs12.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/pkcs12.d.tmp -MT $@ -c -o $@ apps/pkcs12.c
+	@touch apps/pkcs12.d.tmp
+	@if cmp apps/pkcs12.d.tmp apps/pkcs12.d > /dev/null 2> /dev/null; then \
+		rm -f apps/pkcs12.d.tmp; \
+	else \
+		mv apps/pkcs12.d.tmp apps/pkcs12.d; \
+	fi
+apps/pkcs7.o: apps/pkcs7.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/pkcs7.d.tmp -MT $@ -c -o $@ apps/pkcs7.c
+	@touch apps/pkcs7.d.tmp
+	@if cmp apps/pkcs7.d.tmp apps/pkcs7.d > /dev/null 2> /dev/null; then \
+		rm -f apps/pkcs7.d.tmp; \
+	else \
+		mv apps/pkcs7.d.tmp apps/pkcs7.d; \
+	fi
+apps/pkcs8.o: apps/pkcs8.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/pkcs8.d.tmp -MT $@ -c -o $@ apps/pkcs8.c
+	@touch apps/pkcs8.d.tmp
+	@if cmp apps/pkcs8.d.tmp apps/pkcs8.d > /dev/null 2> /dev/null; then \
+		rm -f apps/pkcs8.d.tmp; \
+	else \
+		mv apps/pkcs8.d.tmp apps/pkcs8.d; \
+	fi
+apps/pkey.o: apps/pkey.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/pkey.d.tmp -MT $@ -c -o $@ apps/pkey.c
+	@touch apps/pkey.d.tmp
+	@if cmp apps/pkey.d.tmp apps/pkey.d > /dev/null 2> /dev/null; then \
+		rm -f apps/pkey.d.tmp; \
+	else \
+		mv apps/pkey.d.tmp apps/pkey.d; \
+	fi
+apps/pkeyparam.o: apps/pkeyparam.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/pkeyparam.d.tmp -MT $@ -c -o $@ apps/pkeyparam.c
+	@touch apps/pkeyparam.d.tmp
+	@if cmp apps/pkeyparam.d.tmp apps/pkeyparam.d > /dev/null 2> /dev/null; then \
+		rm -f apps/pkeyparam.d.tmp; \
+	else \
+		mv apps/pkeyparam.d.tmp apps/pkeyparam.d; \
+	fi
+apps/pkeyutl.o: apps/pkeyutl.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/pkeyutl.d.tmp -MT $@ -c -o $@ apps/pkeyutl.c
+	@touch apps/pkeyutl.d.tmp
+	@if cmp apps/pkeyutl.d.tmp apps/pkeyutl.d > /dev/null 2> /dev/null; then \
+		rm -f apps/pkeyutl.d.tmp; \
+	else \
+		mv apps/pkeyutl.d.tmp apps/pkeyutl.d; \
+	fi
+apps/prime.o: apps/prime.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/prime.d.tmp -MT $@ -c -o $@ apps/prime.c
+	@touch apps/prime.d.tmp
+	@if cmp apps/prime.d.tmp apps/prime.d > /dev/null 2> /dev/null; then \
+		rm -f apps/prime.d.tmp; \
+	else \
+		mv apps/prime.d.tmp apps/prime.d; \
+	fi
+apps/rand.o: apps/rand.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/rand.d.tmp -MT $@ -c -o $@ apps/rand.c
+	@touch apps/rand.d.tmp
+	@if cmp apps/rand.d.tmp apps/rand.d > /dev/null 2> /dev/null; then \
+		rm -f apps/rand.d.tmp; \
+	else \
+		mv apps/rand.d.tmp apps/rand.d; \
+	fi
+apps/rehash.o: apps/rehash.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/rehash.d.tmp -MT $@ -c -o $@ apps/rehash.c
+	@touch apps/rehash.d.tmp
+	@if cmp apps/rehash.d.tmp apps/rehash.d > /dev/null 2> /dev/null; then \
+		rm -f apps/rehash.d.tmp; \
+	else \
+		mv apps/rehash.d.tmp apps/rehash.d; \
+	fi
+apps/req.o: apps/req.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/req.d.tmp -MT $@ -c -o $@ apps/req.c
+	@touch apps/req.d.tmp
+	@if cmp apps/req.d.tmp apps/req.d > /dev/null 2> /dev/null; then \
+		rm -f apps/req.d.tmp; \
+	else \
+		mv apps/req.d.tmp apps/req.d; \
+	fi
+apps/rsa.o: apps/rsa.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/rsa.d.tmp -MT $@ -c -o $@ apps/rsa.c
+	@touch apps/rsa.d.tmp
+	@if cmp apps/rsa.d.tmp apps/rsa.d > /dev/null 2> /dev/null; then \
+		rm -f apps/rsa.d.tmp; \
+	else \
+		mv apps/rsa.d.tmp apps/rsa.d; \
+	fi
+apps/rsautl.o: apps/rsautl.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/rsautl.d.tmp -MT $@ -c -o $@ apps/rsautl.c
+	@touch apps/rsautl.d.tmp
+	@if cmp apps/rsautl.d.tmp apps/rsautl.d > /dev/null 2> /dev/null; then \
+		rm -f apps/rsautl.d.tmp; \
+	else \
+		mv apps/rsautl.d.tmp apps/rsautl.d; \
+	fi
+apps/s_cb.o: apps/s_cb.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/s_cb.d.tmp -MT $@ -c -o $@ apps/s_cb.c
+	@touch apps/s_cb.d.tmp
+	@if cmp apps/s_cb.d.tmp apps/s_cb.d > /dev/null 2> /dev/null; then \
+		rm -f apps/s_cb.d.tmp; \
+	else \
+		mv apps/s_cb.d.tmp apps/s_cb.d; \
+	fi
+apps/s_client.o: apps/s_client.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/s_client.d.tmp -MT $@ -c -o $@ apps/s_client.c
+	@touch apps/s_client.d.tmp
+	@if cmp apps/s_client.d.tmp apps/s_client.d > /dev/null 2> /dev/null; then \
+		rm -f apps/s_client.d.tmp; \
+	else \
+		mv apps/s_client.d.tmp apps/s_client.d; \
+	fi
+apps/s_server.o: apps/s_server.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/s_server.d.tmp -MT $@ -c -o $@ apps/s_server.c
+	@touch apps/s_server.d.tmp
+	@if cmp apps/s_server.d.tmp apps/s_server.d > /dev/null 2> /dev/null; then \
+		rm -f apps/s_server.d.tmp; \
+	else \
+		mv apps/s_server.d.tmp apps/s_server.d; \
+	fi
+apps/s_socket.o: apps/s_socket.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/s_socket.d.tmp -MT $@ -c -o $@ apps/s_socket.c
+	@touch apps/s_socket.d.tmp
+	@if cmp apps/s_socket.d.tmp apps/s_socket.d > /dev/null 2> /dev/null; then \
+		rm -f apps/s_socket.d.tmp; \
+	else \
+		mv apps/s_socket.d.tmp apps/s_socket.d; \
+	fi
+apps/s_time.o: apps/s_time.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/s_time.d.tmp -MT $@ -c -o $@ apps/s_time.c
+	@touch apps/s_time.d.tmp
+	@if cmp apps/s_time.d.tmp apps/s_time.d > /dev/null 2> /dev/null; then \
+		rm -f apps/s_time.d.tmp; \
+	else \
+		mv apps/s_time.d.tmp apps/s_time.d; \
+	fi
+apps/sess_id.o: apps/sess_id.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/sess_id.d.tmp -MT $@ -c -o $@ apps/sess_id.c
+	@touch apps/sess_id.d.tmp
+	@if cmp apps/sess_id.d.tmp apps/sess_id.d > /dev/null 2> /dev/null; then \
+		rm -f apps/sess_id.d.tmp; \
+	else \
+		mv apps/sess_id.d.tmp apps/sess_id.d; \
+	fi
+apps/smime.o: apps/smime.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/smime.d.tmp -MT $@ -c -o $@ apps/smime.c
+	@touch apps/smime.d.tmp
+	@if cmp apps/smime.d.tmp apps/smime.d > /dev/null 2> /dev/null; then \
+		rm -f apps/smime.d.tmp; \
+	else \
+		mv apps/smime.d.tmp apps/smime.d; \
+	fi
+apps/speed.o: apps/speed.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/speed.d.tmp -MT $@ -c -o $@ apps/speed.c
+	@touch apps/speed.d.tmp
+	@if cmp apps/speed.d.tmp apps/speed.d > /dev/null 2> /dev/null; then \
+		rm -f apps/speed.d.tmp; \
+	else \
+		mv apps/speed.d.tmp apps/speed.d; \
+	fi
+apps/spkac.o: apps/spkac.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/spkac.d.tmp -MT $@ -c -o $@ apps/spkac.c
+	@touch apps/spkac.d.tmp
+	@if cmp apps/spkac.d.tmp apps/spkac.d > /dev/null 2> /dev/null; then \
+		rm -f apps/spkac.d.tmp; \
+	else \
+		mv apps/spkac.d.tmp apps/spkac.d; \
+	fi
+apps/srp.o: apps/srp.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/srp.d.tmp -MT $@ -c -o $@ apps/srp.c
+	@touch apps/srp.d.tmp
+	@if cmp apps/srp.d.tmp apps/srp.d > /dev/null 2> /dev/null; then \
+		rm -f apps/srp.d.tmp; \
+	else \
+		mv apps/srp.d.tmp apps/srp.d; \
+	fi
+apps/ts.o: apps/ts.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/ts.d.tmp -MT $@ -c -o $@ apps/ts.c
+	@touch apps/ts.d.tmp
+	@if cmp apps/ts.d.tmp apps/ts.d > /dev/null 2> /dev/null; then \
+		rm -f apps/ts.d.tmp; \
+	else \
+		mv apps/ts.d.tmp apps/ts.d; \
+	fi
+apps/verify.o: apps/verify.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/verify.d.tmp -MT $@ -c -o $@ apps/verify.c
+	@touch apps/verify.d.tmp
+	@if cmp apps/verify.d.tmp apps/verify.d > /dev/null 2> /dev/null; then \
+		rm -f apps/verify.d.tmp; \
+	else \
+		mv apps/verify.d.tmp apps/verify.d; \
+	fi
+apps/version.o: apps/version.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/version.d.tmp -MT $@ -c -o $@ apps/version.c
+	@touch apps/version.d.tmp
+	@if cmp apps/version.d.tmp apps/version.d > /dev/null 2> /dev/null; then \
+		rm -f apps/version.d.tmp; \
+	else \
+		mv apps/version.d.tmp apps/version.d; \
+	fi
+apps/x509.o: apps/x509.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF apps/x509.d.tmp -MT $@ -c -o $@ apps/x509.c
+	@touch apps/x509.d.tmp
+	@if cmp apps/x509.d.tmp apps/x509.d > /dev/null 2> /dev/null; then \
+		rm -f apps/x509.d.tmp; \
+	else \
+		mv apps/x509.d.tmp apps/x509.d; \
+	fi
+fuzz/asn1-test: fuzz/asn1.o fuzz/test-corpus.o libcrypto.a
+	$(RM) fuzz/asn1-test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=fuzz/asn1-test OBJECTS="fuzz/asn1.o fuzz/test-corpus.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+fuzz/asn1.o: fuzz/asn1.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF fuzz/asn1.d.tmp -MT $@ -c -o $@ fuzz/asn1.c
+	@touch fuzz/asn1.d.tmp
+	@if cmp fuzz/asn1.d.tmp fuzz/asn1.d > /dev/null 2> /dev/null; then \
+		rm -f fuzz/asn1.d.tmp; \
+	else \
+		mv fuzz/asn1.d.tmp fuzz/asn1.d; \
+	fi
+fuzz/test-corpus.o: fuzz/test-corpus.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF fuzz/test-corpus.d.tmp -MT $@ -c -o $@ fuzz/test-corpus.c
+	@touch fuzz/test-corpus.d.tmp
+	@if cmp fuzz/test-corpus.d.tmp fuzz/test-corpus.d > /dev/null 2> /dev/null; then \
+		rm -f fuzz/test-corpus.d.tmp; \
+	else \
+		mv fuzz/test-corpus.d.tmp fuzz/test-corpus.d; \
+	fi
+fuzz/asn1parse-test: fuzz/asn1parse.o fuzz/test-corpus.o libcrypto.a
+	$(RM) fuzz/asn1parse-test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=fuzz/asn1parse-test OBJECTS="fuzz/asn1parse.o fuzz/test-corpus.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+fuzz/asn1parse.o: fuzz/asn1parse.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF fuzz/asn1parse.d.tmp -MT $@ -c -o $@ fuzz/asn1parse.c
+	@touch fuzz/asn1parse.d.tmp
+	@if cmp fuzz/asn1parse.d.tmp fuzz/asn1parse.d > /dev/null 2> /dev/null; then \
+		rm -f fuzz/asn1parse.d.tmp; \
+	else \
+		mv fuzz/asn1parse.d.tmp fuzz/asn1parse.d; \
+	fi
+fuzz/bignum-test: fuzz/bignum.o fuzz/test-corpus.o libcrypto.a
+	$(RM) fuzz/bignum-test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=fuzz/bignum-test OBJECTS="fuzz/bignum.o fuzz/test-corpus.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+fuzz/bignum.o: fuzz/bignum.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF fuzz/bignum.d.tmp -MT $@ -c -o $@ fuzz/bignum.c
+	@touch fuzz/bignum.d.tmp
+	@if cmp fuzz/bignum.d.tmp fuzz/bignum.d > /dev/null 2> /dev/null; then \
+		rm -f fuzz/bignum.d.tmp; \
+	else \
+		mv fuzz/bignum.d.tmp fuzz/bignum.d; \
+	fi
+fuzz/bndiv-test: fuzz/bndiv.o fuzz/test-corpus.o libcrypto.a
+	$(RM) fuzz/bndiv-test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=fuzz/bndiv-test OBJECTS="fuzz/bndiv.o fuzz/test-corpus.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+fuzz/bndiv.o: fuzz/bndiv.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF fuzz/bndiv.d.tmp -MT $@ -c -o $@ fuzz/bndiv.c
+	@touch fuzz/bndiv.d.tmp
+	@if cmp fuzz/bndiv.d.tmp fuzz/bndiv.d > /dev/null 2> /dev/null; then \
+		rm -f fuzz/bndiv.d.tmp; \
+	else \
+		mv fuzz/bndiv.d.tmp fuzz/bndiv.d; \
+	fi
+fuzz/cms-test: fuzz/cms.o fuzz/test-corpus.o libcrypto.a
+	$(RM) fuzz/cms-test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=fuzz/cms-test OBJECTS="fuzz/cms.o fuzz/test-corpus.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+fuzz/cms.o: fuzz/cms.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF fuzz/cms.d.tmp -MT $@ -c -o $@ fuzz/cms.c
+	@touch fuzz/cms.d.tmp
+	@if cmp fuzz/cms.d.tmp fuzz/cms.d > /dev/null 2> /dev/null; then \
+		rm -f fuzz/cms.d.tmp; \
+	else \
+		mv fuzz/cms.d.tmp fuzz/cms.d; \
+	fi
+fuzz/conf-test: fuzz/conf.o fuzz/test-corpus.o libcrypto.a
+	$(RM) fuzz/conf-test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=fuzz/conf-test OBJECTS="fuzz/conf.o fuzz/test-corpus.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+fuzz/conf.o: fuzz/conf.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF fuzz/conf.d.tmp -MT $@ -c -o $@ fuzz/conf.c
+	@touch fuzz/conf.d.tmp
+	@if cmp fuzz/conf.d.tmp fuzz/conf.d > /dev/null 2> /dev/null; then \
+		rm -f fuzz/conf.d.tmp; \
+	else \
+		mv fuzz/conf.d.tmp fuzz/conf.d; \
+	fi
+fuzz/crl-test: fuzz/crl.o fuzz/test-corpus.o libcrypto.a
+	$(RM) fuzz/crl-test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=fuzz/crl-test OBJECTS="fuzz/crl.o fuzz/test-corpus.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+fuzz/crl.o: fuzz/crl.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF fuzz/crl.d.tmp -MT $@ -c -o $@ fuzz/crl.c
+	@touch fuzz/crl.d.tmp
+	@if cmp fuzz/crl.d.tmp fuzz/crl.d > /dev/null 2> /dev/null; then \
+		rm -f fuzz/crl.d.tmp; \
+	else \
+		mv fuzz/crl.d.tmp fuzz/crl.d; \
+	fi
+fuzz/ct-test: fuzz/ct.o fuzz/test-corpus.o libcrypto.a
+	$(RM) fuzz/ct-test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=fuzz/ct-test OBJECTS="fuzz/ct.o fuzz/test-corpus.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+fuzz/ct.o: fuzz/ct.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF fuzz/ct.d.tmp -MT $@ -c -o $@ fuzz/ct.c
+	@touch fuzz/ct.d.tmp
+	@if cmp fuzz/ct.d.tmp fuzz/ct.d > /dev/null 2> /dev/null; then \
+		rm -f fuzz/ct.d.tmp; \
+	else \
+		mv fuzz/ct.d.tmp fuzz/ct.d; \
+	fi
+fuzz/server-test: fuzz/server.o fuzz/test-corpus.o libssl.a libcrypto.a
+	$(RM) fuzz/server-test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=fuzz/server-test OBJECTS="fuzz/server.o fuzz/test-corpus.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+fuzz/server.o: fuzz/server.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF fuzz/server.d.tmp -MT $@ -c -o $@ fuzz/server.c
+	@touch fuzz/server.d.tmp
+	@if cmp fuzz/server.d.tmp fuzz/server.d > /dev/null 2> /dev/null; then \
+		rm -f fuzz/server.d.tmp; \
+	else \
+		mv fuzz/server.d.tmp fuzz/server.d; \
+	fi
+fuzz/x509-test: fuzz/test-corpus.o fuzz/x509.o libcrypto.a
+	$(RM) fuzz/x509-test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=fuzz/x509-test OBJECTS="fuzz/test-corpus.o fuzz/x509.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+fuzz/x509.o: fuzz/x509.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF fuzz/x509.d.tmp -MT $@ -c -o $@ fuzz/x509.c
+	@touch fuzz/x509.d.tmp
+	@if cmp fuzz/x509.d.tmp fuzz/x509.d > /dev/null 2> /dev/null; then \
+		rm -f fuzz/x509.d.tmp; \
+	else \
+		mv fuzz/x509.d.tmp fuzz/x509.d; \
+	fi
+test/aborttest: test/aborttest.o libcrypto.a
+	$(RM) test/aborttest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/aborttest OBJECTS="test/aborttest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/aborttest.o: test/aborttest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/aborttest.d.tmp -MT $@ -c -o $@ test/aborttest.c
+	@touch test/aborttest.d.tmp
+	@if cmp test/aborttest.d.tmp test/aborttest.d > /dev/null 2> /dev/null; then \
+		rm -f test/aborttest.d.tmp; \
+	else \
+		mv test/aborttest.d.tmp test/aborttest.d; \
+	fi
+test/afalgtest: test/afalgtest.o libcrypto.a
+	$(RM) test/afalgtest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/afalgtest OBJECTS="test/afalgtest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/afalgtest.o: test/afalgtest.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/afalgtest.d.tmp -MT $@ -c -o $@ test/afalgtest.c
+	@touch test/afalgtest.d.tmp
+	@if cmp test/afalgtest.d.tmp test/afalgtest.d > /dev/null 2> /dev/null; then \
+		rm -f test/afalgtest.d.tmp; \
+	else \
+		mv test/afalgtest.d.tmp test/afalgtest.d; \
+	fi
+test/asynciotest: test/asynciotest.o test/ssltestlib.o libssl.a libcrypto.a
+	$(RM) test/asynciotest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/asynciotest OBJECTS="test/asynciotest.o test/ssltestlib.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/asynciotest.o: test/asynciotest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/asynciotest.d.tmp -MT $@ -c -o $@ test/asynciotest.c
+	@touch test/asynciotest.d.tmp
+	@if cmp test/asynciotest.d.tmp test/asynciotest.d > /dev/null 2> /dev/null; then \
+		rm -f test/asynciotest.d.tmp; \
+	else \
+		mv test/asynciotest.d.tmp test/asynciotest.d; \
+	fi
+test/ssltestlib.o: test/ssltestlib.c
+	$(CC)  -Iinclude -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/ssltestlib.d.tmp -MT $@ -c -o $@ test/ssltestlib.c
+	@touch test/ssltestlib.d.tmp
+	@if cmp test/ssltestlib.d.tmp test/ssltestlib.d > /dev/null 2> /dev/null; then \
+		rm -f test/ssltestlib.d.tmp; \
+	else \
+		mv test/ssltestlib.d.tmp test/ssltestlib.d; \
+	fi
+test/asynctest: test/asynctest.o libcrypto.a
+	$(RM) test/asynctest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/asynctest OBJECTS="test/asynctest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/asynctest.o: test/asynctest.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/asynctest.d.tmp -MT $@ -c -o $@ test/asynctest.c
+	@touch test/asynctest.d.tmp
+	@if cmp test/asynctest.d.tmp test/asynctest.d > /dev/null 2> /dev/null; then \
+		rm -f test/asynctest.d.tmp; \
+	else \
+		mv test/asynctest.d.tmp test/asynctest.d; \
+	fi
+test/bad_dtls_test: test/bad_dtls_test.o libssl.a libcrypto.a
+	$(RM) test/bad_dtls_test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/bad_dtls_test OBJECTS="test/bad_dtls_test.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/bad_dtls_test.o: test/bad_dtls_test.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/bad_dtls_test.d.tmp -MT $@ -c -o $@ test/bad_dtls_test.c
+	@touch test/bad_dtls_test.d.tmp
+	@if cmp test/bad_dtls_test.d.tmp test/bad_dtls_test.d > /dev/null 2> /dev/null; then \
+		rm -f test/bad_dtls_test.d.tmp; \
+	else \
+		mv test/bad_dtls_test.d.tmp test/bad_dtls_test.d; \
+	fi
+test/bftest: test/bftest.o libcrypto.a
+	$(RM) test/bftest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/bftest OBJECTS="test/bftest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/bftest.o: test/bftest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/bftest.d.tmp -MT $@ -c -o $@ test/bftest.c
+	@touch test/bftest.d.tmp
+	@if cmp test/bftest.d.tmp test/bftest.d > /dev/null 2> /dev/null; then \
+		rm -f test/bftest.d.tmp; \
+	else \
+		mv test/bftest.d.tmp test/bftest.d; \
+	fi
+test/bio_enc_test: test/bio_enc_test.o libcrypto.a
+	$(RM) test/bio_enc_test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/bio_enc_test OBJECTS="test/bio_enc_test.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/bio_enc_test.o: test/bio_enc_test.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/bio_enc_test.d.tmp -MT $@ -c -o $@ test/bio_enc_test.c
+	@touch test/bio_enc_test.d.tmp
+	@if cmp test/bio_enc_test.d.tmp test/bio_enc_test.d > /dev/null 2> /dev/null; then \
+		rm -f test/bio_enc_test.d.tmp; \
+	else \
+		mv test/bio_enc_test.d.tmp test/bio_enc_test.d; \
+	fi
+test/bioprinttest: test/bioprinttest.o libcrypto.a
+	$(RM) test/bioprinttest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/bioprinttest OBJECTS="test/bioprinttest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/bioprinttest.o: test/bioprinttest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/bioprinttest.d.tmp -MT $@ -c -o $@ test/bioprinttest.c
+	@touch test/bioprinttest.d.tmp
+	@if cmp test/bioprinttest.d.tmp test/bioprinttest.d > /dev/null 2> /dev/null; then \
+		rm -f test/bioprinttest.d.tmp; \
+	else \
+		mv test/bioprinttest.d.tmp test/bioprinttest.d; \
+	fi
+test/bntest: test/bntest.o libcrypto.a
+	$(RM) test/bntest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/bntest OBJECTS="test/bntest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/bntest.o: test/bntest.c
+	$(CC)  -I. -Icrypto/include -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/bntest.d.tmp -MT $@ -c -o $@ test/bntest.c
+	@touch test/bntest.d.tmp
+	@if cmp test/bntest.d.tmp test/bntest.d > /dev/null 2> /dev/null; then \
+		rm -f test/bntest.d.tmp; \
+	else \
+		mv test/bntest.d.tmp test/bntest.d; \
+	fi
+test/buildtest_aes: test/buildtest_aes.o libssl.a libcrypto.a
+	$(RM) test/buildtest_aes
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_aes OBJECTS="test/buildtest_aes.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_aes.o: test/buildtest_aes.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_aes.d.tmp -MT $@ -c -o $@ test/buildtest_aes.c
+	@touch test/buildtest_aes.d.tmp
+	@if cmp test/buildtest_aes.d.tmp test/buildtest_aes.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_aes.d.tmp; \
+	else \
+		mv test/buildtest_aes.d.tmp test/buildtest_aes.d; \
+	fi
+test/buildtest_aes.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl aes > $@
+test/buildtest_asn1: test/buildtest_asn1.o libssl.a libcrypto.a
+	$(RM) test/buildtest_asn1
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_asn1 OBJECTS="test/buildtest_asn1.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_asn1.o: test/buildtest_asn1.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_asn1.d.tmp -MT $@ -c -o $@ test/buildtest_asn1.c
+	@touch test/buildtest_asn1.d.tmp
+	@if cmp test/buildtest_asn1.d.tmp test/buildtest_asn1.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_asn1.d.tmp; \
+	else \
+		mv test/buildtest_asn1.d.tmp test/buildtest_asn1.d; \
+	fi
+test/buildtest_asn1.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl asn1 > $@
+test/buildtest_asn1t: test/buildtest_asn1t.o libssl.a libcrypto.a
+	$(RM) test/buildtest_asn1t
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_asn1t OBJECTS="test/buildtest_asn1t.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_asn1t.o: test/buildtest_asn1t.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_asn1t.d.tmp -MT $@ -c -o $@ test/buildtest_asn1t.c
+	@touch test/buildtest_asn1t.d.tmp
+	@if cmp test/buildtest_asn1t.d.tmp test/buildtest_asn1t.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_asn1t.d.tmp; \
+	else \
+		mv test/buildtest_asn1t.d.tmp test/buildtest_asn1t.d; \
+	fi
+test/buildtest_asn1t.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl asn1t > $@
+test/buildtest_async: test/buildtest_async.o libssl.a libcrypto.a
+	$(RM) test/buildtest_async
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_async OBJECTS="test/buildtest_async.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_async.o: test/buildtest_async.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_async.d.tmp -MT $@ -c -o $@ test/buildtest_async.c
+	@touch test/buildtest_async.d.tmp
+	@if cmp test/buildtest_async.d.tmp test/buildtest_async.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_async.d.tmp; \
+	else \
+		mv test/buildtest_async.d.tmp test/buildtest_async.d; \
+	fi
+test/buildtest_async.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl async > $@
+test/buildtest_bio: test/buildtest_bio.o libssl.a libcrypto.a
+	$(RM) test/buildtest_bio
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_bio OBJECTS="test/buildtest_bio.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_bio.o: test/buildtest_bio.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_bio.d.tmp -MT $@ -c -o $@ test/buildtest_bio.c
+	@touch test/buildtest_bio.d.tmp
+	@if cmp test/buildtest_bio.d.tmp test/buildtest_bio.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_bio.d.tmp; \
+	else \
+		mv test/buildtest_bio.d.tmp test/buildtest_bio.d; \
+	fi
+test/buildtest_bio.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl bio > $@
+test/buildtest_blowfish: test/buildtest_blowfish.o libssl.a libcrypto.a
+	$(RM) test/buildtest_blowfish
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_blowfish OBJECTS="test/buildtest_blowfish.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_blowfish.o: test/buildtest_blowfish.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_blowfish.d.tmp -MT $@ -c -o $@ test/buildtest_blowfish.c
+	@touch test/buildtest_blowfish.d.tmp
+	@if cmp test/buildtest_blowfish.d.tmp test/buildtest_blowfish.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_blowfish.d.tmp; \
+	else \
+		mv test/buildtest_blowfish.d.tmp test/buildtest_blowfish.d; \
+	fi
+test/buildtest_blowfish.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl blowfish > $@
+test/buildtest_bn: test/buildtest_bn.o libssl.a libcrypto.a
+	$(RM) test/buildtest_bn
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_bn OBJECTS="test/buildtest_bn.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_bn.o: test/buildtest_bn.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_bn.d.tmp -MT $@ -c -o $@ test/buildtest_bn.c
+	@touch test/buildtest_bn.d.tmp
+	@if cmp test/buildtest_bn.d.tmp test/buildtest_bn.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_bn.d.tmp; \
+	else \
+		mv test/buildtest_bn.d.tmp test/buildtest_bn.d; \
+	fi
+test/buildtest_bn.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl bn > $@
+test/buildtest_buffer: test/buildtest_buffer.o libssl.a libcrypto.a
+	$(RM) test/buildtest_buffer
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_buffer OBJECTS="test/buildtest_buffer.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_buffer.o: test/buildtest_buffer.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_buffer.d.tmp -MT $@ -c -o $@ test/buildtest_buffer.c
+	@touch test/buildtest_buffer.d.tmp
+	@if cmp test/buildtest_buffer.d.tmp test/buildtest_buffer.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_buffer.d.tmp; \
+	else \
+		mv test/buildtest_buffer.d.tmp test/buildtest_buffer.d; \
+	fi
+test/buildtest_buffer.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl buffer > $@
+test/buildtest_camellia: test/buildtest_camellia.o libssl.a libcrypto.a
+	$(RM) test/buildtest_camellia
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_camellia OBJECTS="test/buildtest_camellia.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_camellia.o: test/buildtest_camellia.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_camellia.d.tmp -MT $@ -c -o $@ test/buildtest_camellia.c
+	@touch test/buildtest_camellia.d.tmp
+	@if cmp test/buildtest_camellia.d.tmp test/buildtest_camellia.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_camellia.d.tmp; \
+	else \
+		mv test/buildtest_camellia.d.tmp test/buildtest_camellia.d; \
+	fi
+test/buildtest_camellia.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl camellia > $@
+test/buildtest_cast: test/buildtest_cast.o libssl.a libcrypto.a
+	$(RM) test/buildtest_cast
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_cast OBJECTS="test/buildtest_cast.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_cast.o: test/buildtest_cast.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_cast.d.tmp -MT $@ -c -o $@ test/buildtest_cast.c
+	@touch test/buildtest_cast.d.tmp
+	@if cmp test/buildtest_cast.d.tmp test/buildtest_cast.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_cast.d.tmp; \
+	else \
+		mv test/buildtest_cast.d.tmp test/buildtest_cast.d; \
+	fi
+test/buildtest_cast.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl cast > $@
+test/buildtest_cmac: test/buildtest_cmac.o libssl.a libcrypto.a
+	$(RM) test/buildtest_cmac
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_cmac OBJECTS="test/buildtest_cmac.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_cmac.o: test/buildtest_cmac.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_cmac.d.tmp -MT $@ -c -o $@ test/buildtest_cmac.c
+	@touch test/buildtest_cmac.d.tmp
+	@if cmp test/buildtest_cmac.d.tmp test/buildtest_cmac.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_cmac.d.tmp; \
+	else \
+		mv test/buildtest_cmac.d.tmp test/buildtest_cmac.d; \
+	fi
+test/buildtest_cmac.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl cmac > $@
+test/buildtest_cms: test/buildtest_cms.o libssl.a libcrypto.a
+	$(RM) test/buildtest_cms
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_cms OBJECTS="test/buildtest_cms.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_cms.o: test/buildtest_cms.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_cms.d.tmp -MT $@ -c -o $@ test/buildtest_cms.c
+	@touch test/buildtest_cms.d.tmp
+	@if cmp test/buildtest_cms.d.tmp test/buildtest_cms.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_cms.d.tmp; \
+	else \
+		mv test/buildtest_cms.d.tmp test/buildtest_cms.d; \
+	fi
+test/buildtest_cms.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl cms > $@
+test/buildtest_comp: test/buildtest_comp.o libssl.a libcrypto.a
+	$(RM) test/buildtest_comp
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_comp OBJECTS="test/buildtest_comp.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_comp.o: test/buildtest_comp.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_comp.d.tmp -MT $@ -c -o $@ test/buildtest_comp.c
+	@touch test/buildtest_comp.d.tmp
+	@if cmp test/buildtest_comp.d.tmp test/buildtest_comp.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_comp.d.tmp; \
+	else \
+		mv test/buildtest_comp.d.tmp test/buildtest_comp.d; \
+	fi
+test/buildtest_comp.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl comp > $@
+test/buildtest_conf: test/buildtest_conf.o libssl.a libcrypto.a
+	$(RM) test/buildtest_conf
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_conf OBJECTS="test/buildtest_conf.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_conf.o: test/buildtest_conf.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_conf.d.tmp -MT $@ -c -o $@ test/buildtest_conf.c
+	@touch test/buildtest_conf.d.tmp
+	@if cmp test/buildtest_conf.d.tmp test/buildtest_conf.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_conf.d.tmp; \
+	else \
+		mv test/buildtest_conf.d.tmp test/buildtest_conf.d; \
+	fi
+test/buildtest_conf.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl conf > $@
+test/buildtest_conf_api: test/buildtest_conf_api.o libssl.a libcrypto.a
+	$(RM) test/buildtest_conf_api
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_conf_api OBJECTS="test/buildtest_conf_api.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_conf_api.o: test/buildtest_conf_api.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_conf_api.d.tmp -MT $@ -c -o $@ test/buildtest_conf_api.c
+	@touch test/buildtest_conf_api.d.tmp
+	@if cmp test/buildtest_conf_api.d.tmp test/buildtest_conf_api.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_conf_api.d.tmp; \
+	else \
+		mv test/buildtest_conf_api.d.tmp test/buildtest_conf_api.d; \
+	fi
+test/buildtest_conf_api.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl conf_api > $@
+test/buildtest_crypto: test/buildtest_crypto.o libssl.a libcrypto.a
+	$(RM) test/buildtest_crypto
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_crypto OBJECTS="test/buildtest_crypto.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_crypto.o: test/buildtest_crypto.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_crypto.d.tmp -MT $@ -c -o $@ test/buildtest_crypto.c
+	@touch test/buildtest_crypto.d.tmp
+	@if cmp test/buildtest_crypto.d.tmp test/buildtest_crypto.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_crypto.d.tmp; \
+	else \
+		mv test/buildtest_crypto.d.tmp test/buildtest_crypto.d; \
+	fi
+test/buildtest_crypto.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl crypto > $@
+test/buildtest_ct: test/buildtest_ct.o libssl.a libcrypto.a
+	$(RM) test/buildtest_ct
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_ct OBJECTS="test/buildtest_ct.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_ct.o: test/buildtest_ct.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_ct.d.tmp -MT $@ -c -o $@ test/buildtest_ct.c
+	@touch test/buildtest_ct.d.tmp
+	@if cmp test/buildtest_ct.d.tmp test/buildtest_ct.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_ct.d.tmp; \
+	else \
+		mv test/buildtest_ct.d.tmp test/buildtest_ct.d; \
+	fi
+test/buildtest_ct.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl ct > $@
+test/buildtest_des: test/buildtest_des.o libssl.a libcrypto.a
+	$(RM) test/buildtest_des
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_des OBJECTS="test/buildtest_des.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_des.o: test/buildtest_des.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_des.d.tmp -MT $@ -c -o $@ test/buildtest_des.c
+	@touch test/buildtest_des.d.tmp
+	@if cmp test/buildtest_des.d.tmp test/buildtest_des.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_des.d.tmp; \
+	else \
+		mv test/buildtest_des.d.tmp test/buildtest_des.d; \
+	fi
+test/buildtest_des.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl des > $@
+test/buildtest_dh: test/buildtest_dh.o libssl.a libcrypto.a
+	$(RM) test/buildtest_dh
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_dh OBJECTS="test/buildtest_dh.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_dh.o: test/buildtest_dh.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_dh.d.tmp -MT $@ -c -o $@ test/buildtest_dh.c
+	@touch test/buildtest_dh.d.tmp
+	@if cmp test/buildtest_dh.d.tmp test/buildtest_dh.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_dh.d.tmp; \
+	else \
+		mv test/buildtest_dh.d.tmp test/buildtest_dh.d; \
+	fi
+test/buildtest_dh.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl dh > $@
+test/buildtest_dsa: test/buildtest_dsa.o libssl.a libcrypto.a
+	$(RM) test/buildtest_dsa
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_dsa OBJECTS="test/buildtest_dsa.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_dsa.o: test/buildtest_dsa.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_dsa.d.tmp -MT $@ -c -o $@ test/buildtest_dsa.c
+	@touch test/buildtest_dsa.d.tmp
+	@if cmp test/buildtest_dsa.d.tmp test/buildtest_dsa.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_dsa.d.tmp; \
+	else \
+		mv test/buildtest_dsa.d.tmp test/buildtest_dsa.d; \
+	fi
+test/buildtest_dsa.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl dsa > $@
+test/buildtest_dtls1: test/buildtest_dtls1.o libssl.a libcrypto.a
+	$(RM) test/buildtest_dtls1
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_dtls1 OBJECTS="test/buildtest_dtls1.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_dtls1.o: test/buildtest_dtls1.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_dtls1.d.tmp -MT $@ -c -o $@ test/buildtest_dtls1.c
+	@touch test/buildtest_dtls1.d.tmp
+	@if cmp test/buildtest_dtls1.d.tmp test/buildtest_dtls1.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_dtls1.d.tmp; \
+	else \
+		mv test/buildtest_dtls1.d.tmp test/buildtest_dtls1.d; \
+	fi
+test/buildtest_dtls1.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl dtls1 > $@
+test/buildtest_e_os2: test/buildtest_e_os2.o libssl.a libcrypto.a
+	$(RM) test/buildtest_e_os2
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_e_os2 OBJECTS="test/buildtest_e_os2.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_e_os2.o: test/buildtest_e_os2.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_e_os2.d.tmp -MT $@ -c -o $@ test/buildtest_e_os2.c
+	@touch test/buildtest_e_os2.d.tmp
+	@if cmp test/buildtest_e_os2.d.tmp test/buildtest_e_os2.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_e_os2.d.tmp; \
+	else \
+		mv test/buildtest_e_os2.d.tmp test/buildtest_e_os2.d; \
+	fi
+test/buildtest_e_os2.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl e_os2 > $@
+test/buildtest_ebcdic: test/buildtest_ebcdic.o libssl.a libcrypto.a
+	$(RM) test/buildtest_ebcdic
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_ebcdic OBJECTS="test/buildtest_ebcdic.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_ebcdic.o: test/buildtest_ebcdic.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_ebcdic.d.tmp -MT $@ -c -o $@ test/buildtest_ebcdic.c
+	@touch test/buildtest_ebcdic.d.tmp
+	@if cmp test/buildtest_ebcdic.d.tmp test/buildtest_ebcdic.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_ebcdic.d.tmp; \
+	else \
+		mv test/buildtest_ebcdic.d.tmp test/buildtest_ebcdic.d; \
+	fi
+test/buildtest_ebcdic.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl ebcdic > $@
+test/buildtest_ec: test/buildtest_ec.o libssl.a libcrypto.a
+	$(RM) test/buildtest_ec
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_ec OBJECTS="test/buildtest_ec.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_ec.o: test/buildtest_ec.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_ec.d.tmp -MT $@ -c -o $@ test/buildtest_ec.c
+	@touch test/buildtest_ec.d.tmp
+	@if cmp test/buildtest_ec.d.tmp test/buildtest_ec.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_ec.d.tmp; \
+	else \
+		mv test/buildtest_ec.d.tmp test/buildtest_ec.d; \
+	fi
+test/buildtest_ec.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl ec > $@
+test/buildtest_ecdh: test/buildtest_ecdh.o libssl.a libcrypto.a
+	$(RM) test/buildtest_ecdh
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_ecdh OBJECTS="test/buildtest_ecdh.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_ecdh.o: test/buildtest_ecdh.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_ecdh.d.tmp -MT $@ -c -o $@ test/buildtest_ecdh.c
+	@touch test/buildtest_ecdh.d.tmp
+	@if cmp test/buildtest_ecdh.d.tmp test/buildtest_ecdh.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_ecdh.d.tmp; \
+	else \
+		mv test/buildtest_ecdh.d.tmp test/buildtest_ecdh.d; \
+	fi
+test/buildtest_ecdh.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl ecdh > $@
+test/buildtest_ecdsa: test/buildtest_ecdsa.o libssl.a libcrypto.a
+	$(RM) test/buildtest_ecdsa
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_ecdsa OBJECTS="test/buildtest_ecdsa.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_ecdsa.o: test/buildtest_ecdsa.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_ecdsa.d.tmp -MT $@ -c -o $@ test/buildtest_ecdsa.c
+	@touch test/buildtest_ecdsa.d.tmp
+	@if cmp test/buildtest_ecdsa.d.tmp test/buildtest_ecdsa.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_ecdsa.d.tmp; \
+	else \
+		mv test/buildtest_ecdsa.d.tmp test/buildtest_ecdsa.d; \
+	fi
+test/buildtest_ecdsa.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl ecdsa > $@
+test/buildtest_engine: test/buildtest_engine.o libssl.a libcrypto.a
+	$(RM) test/buildtest_engine
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_engine OBJECTS="test/buildtest_engine.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_engine.o: test/buildtest_engine.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_engine.d.tmp -MT $@ -c -o $@ test/buildtest_engine.c
+	@touch test/buildtest_engine.d.tmp
+	@if cmp test/buildtest_engine.d.tmp test/buildtest_engine.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_engine.d.tmp; \
+	else \
+		mv test/buildtest_engine.d.tmp test/buildtest_engine.d; \
+	fi
+test/buildtest_engine.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl engine > $@
+test/buildtest_err: test/buildtest_err.o libssl.a libcrypto.a
+	$(RM) test/buildtest_err
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_err OBJECTS="test/buildtest_err.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_err.o: test/buildtest_err.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_err.d.tmp -MT $@ -c -o $@ test/buildtest_err.c
+	@touch test/buildtest_err.d.tmp
+	@if cmp test/buildtest_err.d.tmp test/buildtest_err.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_err.d.tmp; \
+	else \
+		mv test/buildtest_err.d.tmp test/buildtest_err.d; \
+	fi
+test/buildtest_err.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl err > $@
+test/buildtest_evp: test/buildtest_evp.o libssl.a libcrypto.a
+	$(RM) test/buildtest_evp
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_evp OBJECTS="test/buildtest_evp.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_evp.o: test/buildtest_evp.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_evp.d.tmp -MT $@ -c -o $@ test/buildtest_evp.c
+	@touch test/buildtest_evp.d.tmp
+	@if cmp test/buildtest_evp.d.tmp test/buildtest_evp.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_evp.d.tmp; \
+	else \
+		mv test/buildtest_evp.d.tmp test/buildtest_evp.d; \
+	fi
+test/buildtest_evp.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl evp > $@
+test/buildtest_hmac: test/buildtest_hmac.o libssl.a libcrypto.a
+	$(RM) test/buildtest_hmac
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_hmac OBJECTS="test/buildtest_hmac.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_hmac.o: test/buildtest_hmac.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_hmac.d.tmp -MT $@ -c -o $@ test/buildtest_hmac.c
+	@touch test/buildtest_hmac.d.tmp
+	@if cmp test/buildtest_hmac.d.tmp test/buildtest_hmac.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_hmac.d.tmp; \
+	else \
+		mv test/buildtest_hmac.d.tmp test/buildtest_hmac.d; \
+	fi
+test/buildtest_hmac.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl hmac > $@
+test/buildtest_idea: test/buildtest_idea.o libssl.a libcrypto.a
+	$(RM) test/buildtest_idea
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_idea OBJECTS="test/buildtest_idea.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_idea.o: test/buildtest_idea.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_idea.d.tmp -MT $@ -c -o $@ test/buildtest_idea.c
+	@touch test/buildtest_idea.d.tmp
+	@if cmp test/buildtest_idea.d.tmp test/buildtest_idea.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_idea.d.tmp; \
+	else \
+		mv test/buildtest_idea.d.tmp test/buildtest_idea.d; \
+	fi
+test/buildtest_idea.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl idea > $@
+test/buildtest_kdf: test/buildtest_kdf.o libssl.a libcrypto.a
+	$(RM) test/buildtest_kdf
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_kdf OBJECTS="test/buildtest_kdf.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_kdf.o: test/buildtest_kdf.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_kdf.d.tmp -MT $@ -c -o $@ test/buildtest_kdf.c
+	@touch test/buildtest_kdf.d.tmp
+	@if cmp test/buildtest_kdf.d.tmp test/buildtest_kdf.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_kdf.d.tmp; \
+	else \
+		mv test/buildtest_kdf.d.tmp test/buildtest_kdf.d; \
+	fi
+test/buildtest_kdf.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl kdf > $@
+test/buildtest_lhash: test/buildtest_lhash.o libssl.a libcrypto.a
+	$(RM) test/buildtest_lhash
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_lhash OBJECTS="test/buildtest_lhash.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_lhash.o: test/buildtest_lhash.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_lhash.d.tmp -MT $@ -c -o $@ test/buildtest_lhash.c
+	@touch test/buildtest_lhash.d.tmp
+	@if cmp test/buildtest_lhash.d.tmp test/buildtest_lhash.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_lhash.d.tmp; \
+	else \
+		mv test/buildtest_lhash.d.tmp test/buildtest_lhash.d; \
+	fi
+test/buildtest_lhash.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl lhash > $@
+test/buildtest_md4: test/buildtest_md4.o libssl.a libcrypto.a
+	$(RM) test/buildtest_md4
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_md4 OBJECTS="test/buildtest_md4.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_md4.o: test/buildtest_md4.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_md4.d.tmp -MT $@ -c -o $@ test/buildtest_md4.c
+	@touch test/buildtest_md4.d.tmp
+	@if cmp test/buildtest_md4.d.tmp test/buildtest_md4.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_md4.d.tmp; \
+	else \
+		mv test/buildtest_md4.d.tmp test/buildtest_md4.d; \
+	fi
+test/buildtest_md4.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl md4 > $@
+test/buildtest_md5: test/buildtest_md5.o libssl.a libcrypto.a
+	$(RM) test/buildtest_md5
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_md5 OBJECTS="test/buildtest_md5.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_md5.o: test/buildtest_md5.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_md5.d.tmp -MT $@ -c -o $@ test/buildtest_md5.c
+	@touch test/buildtest_md5.d.tmp
+	@if cmp test/buildtest_md5.d.tmp test/buildtest_md5.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_md5.d.tmp; \
+	else \
+		mv test/buildtest_md5.d.tmp test/buildtest_md5.d; \
+	fi
+test/buildtest_md5.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl md5 > $@
+test/buildtest_mdc2: test/buildtest_mdc2.o libssl.a libcrypto.a
+	$(RM) test/buildtest_mdc2
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_mdc2 OBJECTS="test/buildtest_mdc2.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_mdc2.o: test/buildtest_mdc2.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_mdc2.d.tmp -MT $@ -c -o $@ test/buildtest_mdc2.c
+	@touch test/buildtest_mdc2.d.tmp
+	@if cmp test/buildtest_mdc2.d.tmp test/buildtest_mdc2.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_mdc2.d.tmp; \
+	else \
+		mv test/buildtest_mdc2.d.tmp test/buildtest_mdc2.d; \
+	fi
+test/buildtest_mdc2.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl mdc2 > $@
+test/buildtest_modes: test/buildtest_modes.o libssl.a libcrypto.a
+	$(RM) test/buildtest_modes
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_modes OBJECTS="test/buildtest_modes.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_modes.o: test/buildtest_modes.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_modes.d.tmp -MT $@ -c -o $@ test/buildtest_modes.c
+	@touch test/buildtest_modes.d.tmp
+	@if cmp test/buildtest_modes.d.tmp test/buildtest_modes.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_modes.d.tmp; \
+	else \
+		mv test/buildtest_modes.d.tmp test/buildtest_modes.d; \
+	fi
+test/buildtest_modes.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl modes > $@
+test/buildtest_obj_mac: test/buildtest_obj_mac.o libssl.a libcrypto.a
+	$(RM) test/buildtest_obj_mac
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_obj_mac OBJECTS="test/buildtest_obj_mac.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_obj_mac.o: test/buildtest_obj_mac.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_obj_mac.d.tmp -MT $@ -c -o $@ test/buildtest_obj_mac.c
+	@touch test/buildtest_obj_mac.d.tmp
+	@if cmp test/buildtest_obj_mac.d.tmp test/buildtest_obj_mac.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_obj_mac.d.tmp; \
+	else \
+		mv test/buildtest_obj_mac.d.tmp test/buildtest_obj_mac.d; \
+	fi
+test/buildtest_obj_mac.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl obj_mac > $@
+test/buildtest_objects: test/buildtest_objects.o libssl.a libcrypto.a
+	$(RM) test/buildtest_objects
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_objects OBJECTS="test/buildtest_objects.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_objects.o: test/buildtest_objects.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_objects.d.tmp -MT $@ -c -o $@ test/buildtest_objects.c
+	@touch test/buildtest_objects.d.tmp
+	@if cmp test/buildtest_objects.d.tmp test/buildtest_objects.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_objects.d.tmp; \
+	else \
+		mv test/buildtest_objects.d.tmp test/buildtest_objects.d; \
+	fi
+test/buildtest_objects.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl objects > $@
+test/buildtest_ocsp: test/buildtest_ocsp.o libssl.a libcrypto.a
+	$(RM) test/buildtest_ocsp
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_ocsp OBJECTS="test/buildtest_ocsp.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_ocsp.o: test/buildtest_ocsp.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_ocsp.d.tmp -MT $@ -c -o $@ test/buildtest_ocsp.c
+	@touch test/buildtest_ocsp.d.tmp
+	@if cmp test/buildtest_ocsp.d.tmp test/buildtest_ocsp.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_ocsp.d.tmp; \
+	else \
+		mv test/buildtest_ocsp.d.tmp test/buildtest_ocsp.d; \
+	fi
+test/buildtest_ocsp.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl ocsp > $@
+test/buildtest_opensslconf: test/buildtest_opensslconf.o libssl.a libcrypto.a
+	$(RM) test/buildtest_opensslconf
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_opensslconf OBJECTS="test/buildtest_opensslconf.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_opensslconf.o: test/buildtest_opensslconf.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_opensslconf.d.tmp -MT $@ -c -o $@ test/buildtest_opensslconf.c
+	@touch test/buildtest_opensslconf.d.tmp
+	@if cmp test/buildtest_opensslconf.d.tmp test/buildtest_opensslconf.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_opensslconf.d.tmp; \
+	else \
+		mv test/buildtest_opensslconf.d.tmp test/buildtest_opensslconf.d; \
+	fi
+test/buildtest_opensslconf.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl opensslconf > $@
+test/buildtest_opensslv: test/buildtest_opensslv.o libssl.a libcrypto.a
+	$(RM) test/buildtest_opensslv
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_opensslv OBJECTS="test/buildtest_opensslv.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_opensslv.o: test/buildtest_opensslv.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_opensslv.d.tmp -MT $@ -c -o $@ test/buildtest_opensslv.c
+	@touch test/buildtest_opensslv.d.tmp
+	@if cmp test/buildtest_opensslv.d.tmp test/buildtest_opensslv.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_opensslv.d.tmp; \
+	else \
+		mv test/buildtest_opensslv.d.tmp test/buildtest_opensslv.d; \
+	fi
+test/buildtest_opensslv.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl opensslv > $@
+test/buildtest_ossl_typ: test/buildtest_ossl_typ.o libssl.a libcrypto.a
+	$(RM) test/buildtest_ossl_typ
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_ossl_typ OBJECTS="test/buildtest_ossl_typ.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_ossl_typ.o: test/buildtest_ossl_typ.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_ossl_typ.d.tmp -MT $@ -c -o $@ test/buildtest_ossl_typ.c
+	@touch test/buildtest_ossl_typ.d.tmp
+	@if cmp test/buildtest_ossl_typ.d.tmp test/buildtest_ossl_typ.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_ossl_typ.d.tmp; \
+	else \
+		mv test/buildtest_ossl_typ.d.tmp test/buildtest_ossl_typ.d; \
+	fi
+test/buildtest_ossl_typ.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl ossl_typ > $@
+test/buildtest_pem: test/buildtest_pem.o libssl.a libcrypto.a
+	$(RM) test/buildtest_pem
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_pem OBJECTS="test/buildtest_pem.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_pem.o: test/buildtest_pem.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_pem.d.tmp -MT $@ -c -o $@ test/buildtest_pem.c
+	@touch test/buildtest_pem.d.tmp
+	@if cmp test/buildtest_pem.d.tmp test/buildtest_pem.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_pem.d.tmp; \
+	else \
+		mv test/buildtest_pem.d.tmp test/buildtest_pem.d; \
+	fi
+test/buildtest_pem.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl pem > $@
+test/buildtest_pem2: test/buildtest_pem2.o libssl.a libcrypto.a
+	$(RM) test/buildtest_pem2
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_pem2 OBJECTS="test/buildtest_pem2.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_pem2.o: test/buildtest_pem2.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_pem2.d.tmp -MT $@ -c -o $@ test/buildtest_pem2.c
+	@touch test/buildtest_pem2.d.tmp
+	@if cmp test/buildtest_pem2.d.tmp test/buildtest_pem2.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_pem2.d.tmp; \
+	else \
+		mv test/buildtest_pem2.d.tmp test/buildtest_pem2.d; \
+	fi
+test/buildtest_pem2.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl pem2 > $@
+test/buildtest_pkcs12: test/buildtest_pkcs12.o libssl.a libcrypto.a
+	$(RM) test/buildtest_pkcs12
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_pkcs12 OBJECTS="test/buildtest_pkcs12.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_pkcs12.o: test/buildtest_pkcs12.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_pkcs12.d.tmp -MT $@ -c -o $@ test/buildtest_pkcs12.c
+	@touch test/buildtest_pkcs12.d.tmp
+	@if cmp test/buildtest_pkcs12.d.tmp test/buildtest_pkcs12.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_pkcs12.d.tmp; \
+	else \
+		mv test/buildtest_pkcs12.d.tmp test/buildtest_pkcs12.d; \
+	fi
+test/buildtest_pkcs12.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl pkcs12 > $@
+test/buildtest_pkcs7: test/buildtest_pkcs7.o libssl.a libcrypto.a
+	$(RM) test/buildtest_pkcs7
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_pkcs7 OBJECTS="test/buildtest_pkcs7.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_pkcs7.o: test/buildtest_pkcs7.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_pkcs7.d.tmp -MT $@ -c -o $@ test/buildtest_pkcs7.c
+	@touch test/buildtest_pkcs7.d.tmp
+	@if cmp test/buildtest_pkcs7.d.tmp test/buildtest_pkcs7.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_pkcs7.d.tmp; \
+	else \
+		mv test/buildtest_pkcs7.d.tmp test/buildtest_pkcs7.d; \
+	fi
+test/buildtest_pkcs7.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl pkcs7 > $@
+test/buildtest_rand: test/buildtest_rand.o libssl.a libcrypto.a
+	$(RM) test/buildtest_rand
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_rand OBJECTS="test/buildtest_rand.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_rand.o: test/buildtest_rand.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_rand.d.tmp -MT $@ -c -o $@ test/buildtest_rand.c
+	@touch test/buildtest_rand.d.tmp
+	@if cmp test/buildtest_rand.d.tmp test/buildtest_rand.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_rand.d.tmp; \
+	else \
+		mv test/buildtest_rand.d.tmp test/buildtest_rand.d; \
+	fi
+test/buildtest_rand.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl rand > $@
+test/buildtest_rc2: test/buildtest_rc2.o libssl.a libcrypto.a
+	$(RM) test/buildtest_rc2
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_rc2 OBJECTS="test/buildtest_rc2.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_rc2.o: test/buildtest_rc2.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_rc2.d.tmp -MT $@ -c -o $@ test/buildtest_rc2.c
+	@touch test/buildtest_rc2.d.tmp
+	@if cmp test/buildtest_rc2.d.tmp test/buildtest_rc2.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_rc2.d.tmp; \
+	else \
+		mv test/buildtest_rc2.d.tmp test/buildtest_rc2.d; \
+	fi
+test/buildtest_rc2.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl rc2 > $@
+test/buildtest_rc4: test/buildtest_rc4.o libssl.a libcrypto.a
+	$(RM) test/buildtest_rc4
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_rc4 OBJECTS="test/buildtest_rc4.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_rc4.o: test/buildtest_rc4.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_rc4.d.tmp -MT $@ -c -o $@ test/buildtest_rc4.c
+	@touch test/buildtest_rc4.d.tmp
+	@if cmp test/buildtest_rc4.d.tmp test/buildtest_rc4.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_rc4.d.tmp; \
+	else \
+		mv test/buildtest_rc4.d.tmp test/buildtest_rc4.d; \
+	fi
+test/buildtest_rc4.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl rc4 > $@
+test/buildtest_ripemd: test/buildtest_ripemd.o libssl.a libcrypto.a
+	$(RM) test/buildtest_ripemd
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_ripemd OBJECTS="test/buildtest_ripemd.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_ripemd.o: test/buildtest_ripemd.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_ripemd.d.tmp -MT $@ -c -o $@ test/buildtest_ripemd.c
+	@touch test/buildtest_ripemd.d.tmp
+	@if cmp test/buildtest_ripemd.d.tmp test/buildtest_ripemd.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_ripemd.d.tmp; \
+	else \
+		mv test/buildtest_ripemd.d.tmp test/buildtest_ripemd.d; \
+	fi
+test/buildtest_ripemd.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl ripemd > $@
+test/buildtest_rsa: test/buildtest_rsa.o libssl.a libcrypto.a
+	$(RM) test/buildtest_rsa
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_rsa OBJECTS="test/buildtest_rsa.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_rsa.o: test/buildtest_rsa.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_rsa.d.tmp -MT $@ -c -o $@ test/buildtest_rsa.c
+	@touch test/buildtest_rsa.d.tmp
+	@if cmp test/buildtest_rsa.d.tmp test/buildtest_rsa.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_rsa.d.tmp; \
+	else \
+		mv test/buildtest_rsa.d.tmp test/buildtest_rsa.d; \
+	fi
+test/buildtest_rsa.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl rsa > $@
+test/buildtest_safestack: test/buildtest_safestack.o libssl.a libcrypto.a
+	$(RM) test/buildtest_safestack
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_safestack OBJECTS="test/buildtest_safestack.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_safestack.o: test/buildtest_safestack.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_safestack.d.tmp -MT $@ -c -o $@ test/buildtest_safestack.c
+	@touch test/buildtest_safestack.d.tmp
+	@if cmp test/buildtest_safestack.d.tmp test/buildtest_safestack.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_safestack.d.tmp; \
+	else \
+		mv test/buildtest_safestack.d.tmp test/buildtest_safestack.d; \
+	fi
+test/buildtest_safestack.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl safestack > $@
+test/buildtest_seed: test/buildtest_seed.o libssl.a libcrypto.a
+	$(RM) test/buildtest_seed
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_seed OBJECTS="test/buildtest_seed.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_seed.o: test/buildtest_seed.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_seed.d.tmp -MT $@ -c -o $@ test/buildtest_seed.c
+	@touch test/buildtest_seed.d.tmp
+	@if cmp test/buildtest_seed.d.tmp test/buildtest_seed.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_seed.d.tmp; \
+	else \
+		mv test/buildtest_seed.d.tmp test/buildtest_seed.d; \
+	fi
+test/buildtest_seed.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl seed > $@
+test/buildtest_sha: test/buildtest_sha.o libssl.a libcrypto.a
+	$(RM) test/buildtest_sha
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_sha OBJECTS="test/buildtest_sha.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_sha.o: test/buildtest_sha.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_sha.d.tmp -MT $@ -c -o $@ test/buildtest_sha.c
+	@touch test/buildtest_sha.d.tmp
+	@if cmp test/buildtest_sha.d.tmp test/buildtest_sha.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_sha.d.tmp; \
+	else \
+		mv test/buildtest_sha.d.tmp test/buildtest_sha.d; \
+	fi
+test/buildtest_sha.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl sha > $@
+test/buildtest_srp: test/buildtest_srp.o libssl.a libcrypto.a
+	$(RM) test/buildtest_srp
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_srp OBJECTS="test/buildtest_srp.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_srp.o: test/buildtest_srp.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_srp.d.tmp -MT $@ -c -o $@ test/buildtest_srp.c
+	@touch test/buildtest_srp.d.tmp
+	@if cmp test/buildtest_srp.d.tmp test/buildtest_srp.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_srp.d.tmp; \
+	else \
+		mv test/buildtest_srp.d.tmp test/buildtest_srp.d; \
+	fi
+test/buildtest_srp.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl srp > $@
+test/buildtest_srtp: test/buildtest_srtp.o libssl.a libcrypto.a
+	$(RM) test/buildtest_srtp
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_srtp OBJECTS="test/buildtest_srtp.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_srtp.o: test/buildtest_srtp.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_srtp.d.tmp -MT $@ -c -o $@ test/buildtest_srtp.c
+	@touch test/buildtest_srtp.d.tmp
+	@if cmp test/buildtest_srtp.d.tmp test/buildtest_srtp.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_srtp.d.tmp; \
+	else \
+		mv test/buildtest_srtp.d.tmp test/buildtest_srtp.d; \
+	fi
+test/buildtest_srtp.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl srtp > $@
+test/buildtest_ssl: test/buildtest_ssl.o libssl.a libcrypto.a
+	$(RM) test/buildtest_ssl
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_ssl OBJECTS="test/buildtest_ssl.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_ssl.o: test/buildtest_ssl.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_ssl.d.tmp -MT $@ -c -o $@ test/buildtest_ssl.c
+	@touch test/buildtest_ssl.d.tmp
+	@if cmp test/buildtest_ssl.d.tmp test/buildtest_ssl.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_ssl.d.tmp; \
+	else \
+		mv test/buildtest_ssl.d.tmp test/buildtest_ssl.d; \
+	fi
+test/buildtest_ssl.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl ssl > $@
+test/buildtest_ssl2: test/buildtest_ssl2.o libssl.a libcrypto.a
+	$(RM) test/buildtest_ssl2
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_ssl2 OBJECTS="test/buildtest_ssl2.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_ssl2.o: test/buildtest_ssl2.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_ssl2.d.tmp -MT $@ -c -o $@ test/buildtest_ssl2.c
+	@touch test/buildtest_ssl2.d.tmp
+	@if cmp test/buildtest_ssl2.d.tmp test/buildtest_ssl2.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_ssl2.d.tmp; \
+	else \
+		mv test/buildtest_ssl2.d.tmp test/buildtest_ssl2.d; \
+	fi
+test/buildtest_ssl2.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl ssl2 > $@
+test/buildtest_stack: test/buildtest_stack.o libssl.a libcrypto.a
+	$(RM) test/buildtest_stack
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_stack OBJECTS="test/buildtest_stack.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_stack.o: test/buildtest_stack.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_stack.d.tmp -MT $@ -c -o $@ test/buildtest_stack.c
+	@touch test/buildtest_stack.d.tmp
+	@if cmp test/buildtest_stack.d.tmp test/buildtest_stack.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_stack.d.tmp; \
+	else \
+		mv test/buildtest_stack.d.tmp test/buildtest_stack.d; \
+	fi
+test/buildtest_stack.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl stack > $@
+test/buildtest_symhacks: test/buildtest_symhacks.o libssl.a libcrypto.a
+	$(RM) test/buildtest_symhacks
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_symhacks OBJECTS="test/buildtest_symhacks.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_symhacks.o: test/buildtest_symhacks.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_symhacks.d.tmp -MT $@ -c -o $@ test/buildtest_symhacks.c
+	@touch test/buildtest_symhacks.d.tmp
+	@if cmp test/buildtest_symhacks.d.tmp test/buildtest_symhacks.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_symhacks.d.tmp; \
+	else \
+		mv test/buildtest_symhacks.d.tmp test/buildtest_symhacks.d; \
+	fi
+test/buildtest_symhacks.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl symhacks > $@
+test/buildtest_tls1: test/buildtest_tls1.o libssl.a libcrypto.a
+	$(RM) test/buildtest_tls1
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_tls1 OBJECTS="test/buildtest_tls1.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_tls1.o: test/buildtest_tls1.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_tls1.d.tmp -MT $@ -c -o $@ test/buildtest_tls1.c
+	@touch test/buildtest_tls1.d.tmp
+	@if cmp test/buildtest_tls1.d.tmp test/buildtest_tls1.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_tls1.d.tmp; \
+	else \
+		mv test/buildtest_tls1.d.tmp test/buildtest_tls1.d; \
+	fi
+test/buildtest_tls1.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl tls1 > $@
+test/buildtest_ts: test/buildtest_ts.o libssl.a libcrypto.a
+	$(RM) test/buildtest_ts
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_ts OBJECTS="test/buildtest_ts.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_ts.o: test/buildtest_ts.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_ts.d.tmp -MT $@ -c -o $@ test/buildtest_ts.c
+	@touch test/buildtest_ts.d.tmp
+	@if cmp test/buildtest_ts.d.tmp test/buildtest_ts.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_ts.d.tmp; \
+	else \
+		mv test/buildtest_ts.d.tmp test/buildtest_ts.d; \
+	fi
+test/buildtest_ts.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl ts > $@
+test/buildtest_txt_db: test/buildtest_txt_db.o libssl.a libcrypto.a
+	$(RM) test/buildtest_txt_db
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_txt_db OBJECTS="test/buildtest_txt_db.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_txt_db.o: test/buildtest_txt_db.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_txt_db.d.tmp -MT $@ -c -o $@ test/buildtest_txt_db.c
+	@touch test/buildtest_txt_db.d.tmp
+	@if cmp test/buildtest_txt_db.d.tmp test/buildtest_txt_db.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_txt_db.d.tmp; \
+	else \
+		mv test/buildtest_txt_db.d.tmp test/buildtest_txt_db.d; \
+	fi
+test/buildtest_txt_db.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl txt_db > $@
+test/buildtest_whrlpool: test/buildtest_whrlpool.o libssl.a libcrypto.a
+	$(RM) test/buildtest_whrlpool
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_whrlpool OBJECTS="test/buildtest_whrlpool.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_whrlpool.o: test/buildtest_whrlpool.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_whrlpool.d.tmp -MT $@ -c -o $@ test/buildtest_whrlpool.c
+	@touch test/buildtest_whrlpool.d.tmp
+	@if cmp test/buildtest_whrlpool.d.tmp test/buildtest_whrlpool.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_whrlpool.d.tmp; \
+	else \
+		mv test/buildtest_whrlpool.d.tmp test/buildtest_whrlpool.d; \
+	fi
+test/buildtest_whrlpool.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl whrlpool > $@
+test/buildtest_x509: test/buildtest_x509.o libssl.a libcrypto.a
+	$(RM) test/buildtest_x509
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_x509 OBJECTS="test/buildtest_x509.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_x509.o: test/buildtest_x509.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_x509.d.tmp -MT $@ -c -o $@ test/buildtest_x509.c
+	@touch test/buildtest_x509.d.tmp
+	@if cmp test/buildtest_x509.d.tmp test/buildtest_x509.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_x509.d.tmp; \
+	else \
+		mv test/buildtest_x509.d.tmp test/buildtest_x509.d; \
+	fi
+test/buildtest_x509.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl x509 > $@
+test/buildtest_x509_vfy: test/buildtest_x509_vfy.o libssl.a libcrypto.a
+	$(RM) test/buildtest_x509_vfy
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_x509_vfy OBJECTS="test/buildtest_x509_vfy.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_x509_vfy.o: test/buildtest_x509_vfy.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_x509_vfy.d.tmp -MT $@ -c -o $@ test/buildtest_x509_vfy.c
+	@touch test/buildtest_x509_vfy.d.tmp
+	@if cmp test/buildtest_x509_vfy.d.tmp test/buildtest_x509_vfy.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_x509_vfy.d.tmp; \
+	else \
+		mv test/buildtest_x509_vfy.d.tmp test/buildtest_x509_vfy.d; \
+	fi
+test/buildtest_x509_vfy.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl x509_vfy > $@
+test/buildtest_x509v3: test/buildtest_x509v3.o libssl.a libcrypto.a
+	$(RM) test/buildtest_x509v3
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/buildtest_x509v3 OBJECTS="test/buildtest_x509v3.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/buildtest_x509v3.o: test/buildtest_x509v3.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/buildtest_x509v3.d.tmp -MT $@ -c -o $@ test/buildtest_x509v3.c
+	@touch test/buildtest_x509v3.d.tmp
+	@if cmp test/buildtest_x509v3.d.tmp test/buildtest_x509v3.d > /dev/null 2> /dev/null; then \
+		rm -f test/buildtest_x509v3.d.tmp; \
+	else \
+		mv test/buildtest_x509v3.d.tmp test/buildtest_x509v3.d; \
+	fi
+test/buildtest_x509v3.c: test/generate_buildtest.pl 
+	$(PERL) test/generate_buildtest.pl x509v3 > $@
+test/casttest: test/casttest.o libcrypto.a
+	$(RM) test/casttest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/casttest OBJECTS="test/casttest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/casttest.o: test/casttest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/casttest.d.tmp -MT $@ -c -o $@ test/casttest.c
+	@touch test/casttest.d.tmp
+	@if cmp test/casttest.d.tmp test/casttest.d > /dev/null 2> /dev/null; then \
+		rm -f test/casttest.d.tmp; \
+	else \
+		mv test/casttest.d.tmp test/casttest.d; \
+	fi
+test/cipherlist_test: test/cipherlist_test.o test/testutil.o libssl.a libcrypto.a
+	$(RM) test/cipherlist_test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/cipherlist_test OBJECTS="test/cipherlist_test.o test/testutil.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/cipherlist_test.o: test/cipherlist_test.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/cipherlist_test.d.tmp -MT $@ -c -o $@ test/cipherlist_test.c
+	@touch test/cipherlist_test.d.tmp
+	@if cmp test/cipherlist_test.d.tmp test/cipherlist_test.d > /dev/null 2> /dev/null; then \
+		rm -f test/cipherlist_test.d.tmp; \
+	else \
+		mv test/cipherlist_test.d.tmp test/cipherlist_test.d; \
+	fi
+test/testutil.o: test/testutil.c
+	$(CC)  -I. -Iinclude -I. $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/testutil.d.tmp -MT $@ -c -o $@ test/testutil.c
+	@touch test/testutil.d.tmp
+	@if cmp test/testutil.d.tmp test/testutil.d > /dev/null 2> /dev/null; then \
+		rm -f test/testutil.d.tmp; \
+	else \
+		mv test/testutil.d.tmp test/testutil.d; \
+	fi
+test/clienthellotest: test/clienthellotest.o libssl.a libcrypto.a
+	$(RM) test/clienthellotest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/clienthellotest OBJECTS="test/clienthellotest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/clienthellotest.o: test/clienthellotest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/clienthellotest.d.tmp -MT $@ -c -o $@ test/clienthellotest.c
+	@touch test/clienthellotest.d.tmp
+	@if cmp test/clienthellotest.d.tmp test/clienthellotest.d > /dev/null 2> /dev/null; then \
+		rm -f test/clienthellotest.d.tmp; \
+	else \
+		mv test/clienthellotest.d.tmp test/clienthellotest.d; \
+	fi
+test/constant_time_test: test/constant_time_test.o libcrypto.a
+	$(RM) test/constant_time_test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/constant_time_test OBJECTS="test/constant_time_test.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/constant_time_test.o: test/constant_time_test.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/constant_time_test.d.tmp -MT $@ -c -o $@ test/constant_time_test.c
+	@touch test/constant_time_test.d.tmp
+	@if cmp test/constant_time_test.d.tmp test/constant_time_test.d > /dev/null 2> /dev/null; then \
+		rm -f test/constant_time_test.d.tmp; \
+	else \
+		mv test/constant_time_test.d.tmp test/constant_time_test.d; \
+	fi
+test/crltest: test/crltest.o test/testutil.o libcrypto.a
+	$(RM) test/crltest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/crltest OBJECTS="test/crltest.o test/testutil.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/crltest.o: test/crltest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/crltest.d.tmp -MT $@ -c -o $@ test/crltest.c
+	@touch test/crltest.d.tmp
+	@if cmp test/crltest.d.tmp test/crltest.d > /dev/null 2> /dev/null; then \
+		rm -f test/crltest.d.tmp; \
+	else \
+		mv test/crltest.d.tmp test/crltest.d; \
+	fi
+test/ct_test: test/ct_test.o test/testutil.o libcrypto.a
+	$(RM) test/ct_test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/ct_test OBJECTS="test/ct_test.o test/testutil.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/ct_test.o: test/ct_test.c
+	$(CC)  -Icrypto/include -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/ct_test.d.tmp -MT $@ -c -o $@ test/ct_test.c
+	@touch test/ct_test.d.tmp
+	@if cmp test/ct_test.d.tmp test/ct_test.d > /dev/null 2> /dev/null; then \
+		rm -f test/ct_test.d.tmp; \
+	else \
+		mv test/ct_test.d.tmp test/ct_test.d; \
+	fi
+test/d2i_test: test/d2i_test.o test/testutil.o libcrypto.a
+	$(RM) test/d2i_test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/d2i_test OBJECTS="test/d2i_test.o test/testutil.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/d2i_test.o: test/d2i_test.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/d2i_test.d.tmp -MT $@ -c -o $@ test/d2i_test.c
+	@touch test/d2i_test.d.tmp
+	@if cmp test/d2i_test.d.tmp test/d2i_test.d > /dev/null 2> /dev/null; then \
+		rm -f test/d2i_test.d.tmp; \
+	else \
+		mv test/d2i_test.d.tmp test/d2i_test.d; \
+	fi
+test/danetest: test/danetest.o libssl.a libcrypto.a
+	$(RM) test/danetest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/danetest OBJECTS="test/danetest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/danetest.o: test/danetest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/danetest.d.tmp -MT $@ -c -o $@ test/danetest.c
+	@touch test/danetest.d.tmp
+	@if cmp test/danetest.d.tmp test/danetest.d > /dev/null 2> /dev/null; then \
+		rm -f test/danetest.d.tmp; \
+	else \
+		mv test/danetest.d.tmp test/danetest.d; \
+	fi
+test/destest: test/destest.o libcrypto.a
+	$(RM) test/destest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/destest OBJECTS="test/destest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/destest.o: test/destest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/destest.d.tmp -MT $@ -c -o $@ test/destest.c
+	@touch test/destest.d.tmp
+	@if cmp test/destest.d.tmp test/destest.d > /dev/null 2> /dev/null; then \
+		rm -f test/destest.d.tmp; \
+	else \
+		mv test/destest.d.tmp test/destest.d; \
+	fi
+test/dhtest: test/dhtest.o libcrypto.a
+	$(RM) test/dhtest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/dhtest OBJECTS="test/dhtest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/dhtest.o: test/dhtest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/dhtest.d.tmp -MT $@ -c -o $@ test/dhtest.c
+	@touch test/dhtest.d.tmp
+	@if cmp test/dhtest.d.tmp test/dhtest.d > /dev/null 2> /dev/null; then \
+		rm -f test/dhtest.d.tmp; \
+	else \
+		mv test/dhtest.d.tmp test/dhtest.d; \
+	fi
+test/dsatest: test/dsatest.o libcrypto.a
+	$(RM) test/dsatest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/dsatest OBJECTS="test/dsatest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/dsatest.o: test/dsatest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/dsatest.d.tmp -MT $@ -c -o $@ test/dsatest.c
+	@touch test/dsatest.d.tmp
+	@if cmp test/dsatest.d.tmp test/dsatest.d > /dev/null 2> /dev/null; then \
+		rm -f test/dsatest.d.tmp; \
+	else \
+		mv test/dsatest.d.tmp test/dsatest.d; \
+	fi
+test/dtlstest: test/dtlstest.o test/ssltestlib.o test/testutil.o libssl.a libcrypto.a
+	$(RM) test/dtlstest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/dtlstest OBJECTS="test/dtlstest.o test/ssltestlib.o test/testutil.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/dtlstest.o: test/dtlstest.c
+	$(CC)  -Iinclude -Itest $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/dtlstest.d.tmp -MT $@ -c -o $@ test/dtlstest.c
+	@touch test/dtlstest.d.tmp
+	@if cmp test/dtlstest.d.tmp test/dtlstest.d > /dev/null 2> /dev/null; then \
+		rm -f test/dtlstest.d.tmp; \
+	else \
+		mv test/dtlstest.d.tmp test/dtlstest.d; \
+	fi
+test/dtlsv1listentest: test/dtlsv1listentest.o libssl.a libcrypto.a
+	$(RM) test/dtlsv1listentest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/dtlsv1listentest OBJECTS="test/dtlsv1listentest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/dtlsv1listentest.o: test/dtlsv1listentest.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/dtlsv1listentest.d.tmp -MT $@ -c -o $@ test/dtlsv1listentest.c
+	@touch test/dtlsv1listentest.d.tmp
+	@if cmp test/dtlsv1listentest.d.tmp test/dtlsv1listentest.d > /dev/null 2> /dev/null; then \
+		rm -f test/dtlsv1listentest.d.tmp; \
+	else \
+		mv test/dtlsv1listentest.d.tmp test/dtlsv1listentest.d; \
+	fi
+test/ecdhtest: test/ecdhtest.o libcrypto.a
+	$(RM) test/ecdhtest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/ecdhtest OBJECTS="test/ecdhtest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/ecdhtest.o: test/ecdhtest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/ecdhtest.d.tmp -MT $@ -c -o $@ test/ecdhtest.c
+	@touch test/ecdhtest.d.tmp
+	@if cmp test/ecdhtest.d.tmp test/ecdhtest.d > /dev/null 2> /dev/null; then \
+		rm -f test/ecdhtest.d.tmp; \
+	else \
+		mv test/ecdhtest.d.tmp test/ecdhtest.d; \
+	fi
+test/ecdsatest: test/ecdsatest.o libcrypto.a
+	$(RM) test/ecdsatest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/ecdsatest OBJECTS="test/ecdsatest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/ecdsatest.o: test/ecdsatest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/ecdsatest.d.tmp -MT $@ -c -o $@ test/ecdsatest.c
+	@touch test/ecdsatest.d.tmp
+	@if cmp test/ecdsatest.d.tmp test/ecdsatest.d > /dev/null 2> /dev/null; then \
+		rm -f test/ecdsatest.d.tmp; \
+	else \
+		mv test/ecdsatest.d.tmp test/ecdsatest.d; \
+	fi
+test/ectest: test/ectest.o libcrypto.a
+	$(RM) test/ectest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/ectest OBJECTS="test/ectest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/ectest.o: test/ectest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/ectest.d.tmp -MT $@ -c -o $@ test/ectest.c
+	@touch test/ectest.d.tmp
+	@if cmp test/ectest.d.tmp test/ectest.d > /dev/null 2> /dev/null; then \
+		rm -f test/ectest.d.tmp; \
+	else \
+		mv test/ectest.d.tmp test/ectest.d; \
+	fi
+test/enginetest: test/enginetest.o libcrypto.a
+	$(RM) test/enginetest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/enginetest OBJECTS="test/enginetest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/enginetest.o: test/enginetest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/enginetest.d.tmp -MT $@ -c -o $@ test/enginetest.c
+	@touch test/enginetest.d.tmp
+	@if cmp test/enginetest.d.tmp test/enginetest.d > /dev/null 2> /dev/null; then \
+		rm -f test/enginetest.d.tmp; \
+	else \
+		mv test/enginetest.d.tmp test/enginetest.d; \
+	fi
+test/evp_extra_test: test/evp_extra_test.o libcrypto.a
+	$(RM) test/evp_extra_test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/evp_extra_test OBJECTS="test/evp_extra_test.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/evp_extra_test.o: test/evp_extra_test.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/evp_extra_test.d.tmp -MT $@ -c -o $@ test/evp_extra_test.c
+	@touch test/evp_extra_test.d.tmp
+	@if cmp test/evp_extra_test.d.tmp test/evp_extra_test.d > /dev/null 2> /dev/null; then \
+		rm -f test/evp_extra_test.d.tmp; \
+	else \
+		mv test/evp_extra_test.d.tmp test/evp_extra_test.d; \
+	fi
+test/evp_test: test/evp_test.o libcrypto.a
+	$(RM) test/evp_test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/evp_test OBJECTS="test/evp_test.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/evp_test.o: test/evp_test.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/evp_test.d.tmp -MT $@ -c -o $@ test/evp_test.c
+	@touch test/evp_test.d.tmp
+	@if cmp test/evp_test.d.tmp test/evp_test.d > /dev/null 2> /dev/null; then \
+		rm -f test/evp_test.d.tmp; \
+	else \
+		mv test/evp_test.d.tmp test/evp_test.d; \
+	fi
+test/exptest: test/exptest.o libcrypto.a
+	$(RM) test/exptest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/exptest OBJECTS="test/exptest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/exptest.o: test/exptest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/exptest.d.tmp -MT $@ -c -o $@ test/exptest.c
+	@touch test/exptest.d.tmp
+	@if cmp test/exptest.d.tmp test/exptest.d > /dev/null 2> /dev/null; then \
+		rm -f test/exptest.d.tmp; \
+	else \
+		mv test/exptest.d.tmp test/exptest.d; \
+	fi
+test/gmdifftest: test/gmdifftest.o libcrypto.a
+	$(RM) test/gmdifftest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/gmdifftest OBJECTS="test/gmdifftest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/gmdifftest.o: test/gmdifftest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/gmdifftest.d.tmp -MT $@ -c -o $@ test/gmdifftest.c
+	@touch test/gmdifftest.d.tmp
+	@if cmp test/gmdifftest.d.tmp test/gmdifftest.d > /dev/null 2> /dev/null; then \
+		rm -f test/gmdifftest.d.tmp; \
+	else \
+		mv test/gmdifftest.d.tmp test/gmdifftest.d; \
+	fi
+test/heartbeat_test: test/heartbeat_test.o test/testutil.o libssl.a libcrypto.a
+	$(RM) test/heartbeat_test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/heartbeat_test OBJECTS="test/heartbeat_test.o test/testutil.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/heartbeat_test.o: test/heartbeat_test.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/heartbeat_test.d.tmp -MT $@ -c -o $@ test/heartbeat_test.c
+	@touch test/heartbeat_test.d.tmp
+	@if cmp test/heartbeat_test.d.tmp test/heartbeat_test.d > /dev/null 2> /dev/null; then \
+		rm -f test/heartbeat_test.d.tmp; \
+	else \
+		mv test/heartbeat_test.d.tmp test/heartbeat_test.d; \
+	fi
+test/hmactest: test/hmactest.o libcrypto.a
+	$(RM) test/hmactest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/hmactest OBJECTS="test/hmactest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/hmactest.o: test/hmactest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/hmactest.d.tmp -MT $@ -c -o $@ test/hmactest.c
+	@touch test/hmactest.d.tmp
+	@if cmp test/hmactest.d.tmp test/hmactest.d > /dev/null 2> /dev/null; then \
+		rm -f test/hmactest.d.tmp; \
+	else \
+		mv test/hmactest.d.tmp test/hmactest.d; \
+	fi
+test/ideatest: test/ideatest.o libcrypto.a
+	$(RM) test/ideatest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/ideatest OBJECTS="test/ideatest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/ideatest.o: test/ideatest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/ideatest.d.tmp -MT $@ -c -o $@ test/ideatest.c
+	@touch test/ideatest.d.tmp
+	@if cmp test/ideatest.d.tmp test/ideatest.d > /dev/null 2> /dev/null; then \
+		rm -f test/ideatest.d.tmp; \
+	else \
+		mv test/ideatest.d.tmp test/ideatest.d; \
+	fi
+test/igetest: test/igetest.o libcrypto.a
+	$(RM) test/igetest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/igetest OBJECTS="test/igetest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/igetest.o: test/igetest.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/igetest.d.tmp -MT $@ -c -o $@ test/igetest.c
+	@touch test/igetest.d.tmp
+	@if cmp test/igetest.d.tmp test/igetest.d > /dev/null 2> /dev/null; then \
+		rm -f test/igetest.d.tmp; \
+	else \
+		mv test/igetest.d.tmp test/igetest.d; \
+	fi
+test/md2test: test/md2test.o libcrypto.a
+	$(RM) test/md2test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/md2test OBJECTS="test/md2test.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/md2test.o: test/md2test.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/md2test.d.tmp -MT $@ -c -o $@ test/md2test.c
+	@touch test/md2test.d.tmp
+	@if cmp test/md2test.d.tmp test/md2test.d > /dev/null 2> /dev/null; then \
+		rm -f test/md2test.d.tmp; \
+	else \
+		mv test/md2test.d.tmp test/md2test.d; \
+	fi
+test/md4test: test/md4test.o libcrypto.a
+	$(RM) test/md4test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/md4test OBJECTS="test/md4test.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/md4test.o: test/md4test.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/md4test.d.tmp -MT $@ -c -o $@ test/md4test.c
+	@touch test/md4test.d.tmp
+	@if cmp test/md4test.d.tmp test/md4test.d > /dev/null 2> /dev/null; then \
+		rm -f test/md4test.d.tmp; \
+	else \
+		mv test/md4test.d.tmp test/md4test.d; \
+	fi
+test/md5test: test/md5test.o libcrypto.a
+	$(RM) test/md5test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/md5test OBJECTS="test/md5test.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/md5test.o: test/md5test.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/md5test.d.tmp -MT $@ -c -o $@ test/md5test.c
+	@touch test/md5test.d.tmp
+	@if cmp test/md5test.d.tmp test/md5test.d > /dev/null 2> /dev/null; then \
+		rm -f test/md5test.d.tmp; \
+	else \
+		mv test/md5test.d.tmp test/md5test.d; \
+	fi
+test/mdc2test: test/mdc2test.o libcrypto.a
+	$(RM) test/mdc2test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/mdc2test OBJECTS="test/mdc2test.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/mdc2test.o: test/mdc2test.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/mdc2test.d.tmp -MT $@ -c -o $@ test/mdc2test.c
+	@touch test/mdc2test.d.tmp
+	@if cmp test/mdc2test.d.tmp test/mdc2test.d > /dev/null 2> /dev/null; then \
+		rm -f test/mdc2test.d.tmp; \
+	else \
+		mv test/mdc2test.d.tmp test/mdc2test.d; \
+	fi
+test/memleaktest: test/memleaktest.o libcrypto.a
+	$(RM) test/memleaktest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/memleaktest OBJECTS="test/memleaktest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/memleaktest.o: test/memleaktest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/memleaktest.d.tmp -MT $@ -c -o $@ test/memleaktest.c
+	@touch test/memleaktest.d.tmp
+	@if cmp test/memleaktest.d.tmp test/memleaktest.d > /dev/null 2> /dev/null; then \
+		rm -f test/memleaktest.d.tmp; \
+	else \
+		mv test/memleaktest.d.tmp test/memleaktest.d; \
+	fi
+test/p5_crpt2_test: test/p5_crpt2_test.o libcrypto.a
+	$(RM) test/p5_crpt2_test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/p5_crpt2_test OBJECTS="test/p5_crpt2_test.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/p5_crpt2_test.o: test/p5_crpt2_test.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/p5_crpt2_test.d.tmp -MT $@ -c -o $@ test/p5_crpt2_test.c
+	@touch test/p5_crpt2_test.d.tmp
+	@if cmp test/p5_crpt2_test.d.tmp test/p5_crpt2_test.d > /dev/null 2> /dev/null; then \
+		rm -f test/p5_crpt2_test.d.tmp; \
+	else \
+		mv test/p5_crpt2_test.d.tmp test/p5_crpt2_test.d; \
+	fi
+test/packettest: test/packettest.o libcrypto.a
+	$(RM) test/packettest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/packettest OBJECTS="test/packettest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/packettest.o: test/packettest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/packettest.d.tmp -MT $@ -c -o $@ test/packettest.c
+	@touch test/packettest.d.tmp
+	@if cmp test/packettest.d.tmp test/packettest.d > /dev/null 2> /dev/null; then \
+		rm -f test/packettest.d.tmp; \
+	else \
+		mv test/packettest.d.tmp test/packettest.d; \
+	fi
+test/pbelutest: test/pbelutest.o libcrypto.a
+	$(RM) test/pbelutest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/pbelutest OBJECTS="test/pbelutest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/pbelutest.o: test/pbelutest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/pbelutest.d.tmp -MT $@ -c -o $@ test/pbelutest.c
+	@touch test/pbelutest.d.tmp
+	@if cmp test/pbelutest.d.tmp test/pbelutest.d > /dev/null 2> /dev/null; then \
+		rm -f test/pbelutest.d.tmp; \
+	else \
+		mv test/pbelutest.d.tmp test/pbelutest.d; \
+	fi
+test/randtest: test/randtest.o libcrypto.a
+	$(RM) test/randtest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/randtest OBJECTS="test/randtest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/randtest.o: test/randtest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/randtest.d.tmp -MT $@ -c -o $@ test/randtest.c
+	@touch test/randtest.d.tmp
+	@if cmp test/randtest.d.tmp test/randtest.d > /dev/null 2> /dev/null; then \
+		rm -f test/randtest.d.tmp; \
+	else \
+		mv test/randtest.d.tmp test/randtest.d; \
+	fi
+test/rc2test: test/rc2test.o libcrypto.a
+	$(RM) test/rc2test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/rc2test OBJECTS="test/rc2test.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/rc2test.o: test/rc2test.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/rc2test.d.tmp -MT $@ -c -o $@ test/rc2test.c
+	@touch test/rc2test.d.tmp
+	@if cmp test/rc2test.d.tmp test/rc2test.d > /dev/null 2> /dev/null; then \
+		rm -f test/rc2test.d.tmp; \
+	else \
+		mv test/rc2test.d.tmp test/rc2test.d; \
+	fi
+test/rc4test: test/rc4test.o libcrypto.a
+	$(RM) test/rc4test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/rc4test OBJECTS="test/rc4test.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/rc4test.o: test/rc4test.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/rc4test.d.tmp -MT $@ -c -o $@ test/rc4test.c
+	@touch test/rc4test.d.tmp
+	@if cmp test/rc4test.d.tmp test/rc4test.d > /dev/null 2> /dev/null; then \
+		rm -f test/rc4test.d.tmp; \
+	else \
+		mv test/rc4test.d.tmp test/rc4test.d; \
+	fi
+test/rc5test: test/rc5test.o libcrypto.a
+	$(RM) test/rc5test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/rc5test OBJECTS="test/rc5test.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/rc5test.o: test/rc5test.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/rc5test.d.tmp -MT $@ -c -o $@ test/rc5test.c
+	@touch test/rc5test.d.tmp
+	@if cmp test/rc5test.d.tmp test/rc5test.d > /dev/null 2> /dev/null; then \
+		rm -f test/rc5test.d.tmp; \
+	else \
+		mv test/rc5test.d.tmp test/rc5test.d; \
+	fi
+test/rmdtest: test/rmdtest.o libcrypto.a
+	$(RM) test/rmdtest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/rmdtest OBJECTS="test/rmdtest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/rmdtest.o: test/rmdtest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/rmdtest.d.tmp -MT $@ -c -o $@ test/rmdtest.c
+	@touch test/rmdtest.d.tmp
+	@if cmp test/rmdtest.d.tmp test/rmdtest.d > /dev/null 2> /dev/null; then \
+		rm -f test/rmdtest.d.tmp; \
+	else \
+		mv test/rmdtest.d.tmp test/rmdtest.d; \
+	fi
+test/rsa_test: test/rsa_test.o libcrypto.a
+	$(RM) test/rsa_test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/rsa_test OBJECTS="test/rsa_test.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/rsa_test.o: test/rsa_test.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/rsa_test.d.tmp -MT $@ -c -o $@ test/rsa_test.c
+	@touch test/rsa_test.d.tmp
+	@if cmp test/rsa_test.d.tmp test/rsa_test.d > /dev/null 2> /dev/null; then \
+		rm -f test/rsa_test.d.tmp; \
+	else \
+		mv test/rsa_test.d.tmp test/rsa_test.d; \
+	fi
+test/sanitytest: test/sanitytest.o libcrypto.a
+	$(RM) test/sanitytest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/sanitytest OBJECTS="test/sanitytest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/sanitytest.o: test/sanitytest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/sanitytest.d.tmp -MT $@ -c -o $@ test/sanitytest.c
+	@touch test/sanitytest.d.tmp
+	@if cmp test/sanitytest.d.tmp test/sanitytest.d > /dev/null 2> /dev/null; then \
+		rm -f test/sanitytest.d.tmp; \
+	else \
+		mv test/sanitytest.d.tmp test/sanitytest.d; \
+	fi
+test/secmemtest: test/secmemtest.o libcrypto.a
+	$(RM) test/secmemtest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/secmemtest OBJECTS="test/secmemtest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/secmemtest.o: test/secmemtest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/secmemtest.d.tmp -MT $@ -c -o $@ test/secmemtest.c
+	@touch test/secmemtest.d.tmp
+	@if cmp test/secmemtest.d.tmp test/secmemtest.d > /dev/null 2> /dev/null; then \
+		rm -f test/secmemtest.d.tmp; \
+	else \
+		mv test/secmemtest.d.tmp test/secmemtest.d; \
+	fi
+test/sha1test: test/sha1test.o libcrypto.a
+	$(RM) test/sha1test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/sha1test OBJECTS="test/sha1test.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/sha1test.o: test/sha1test.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/sha1test.d.tmp -MT $@ -c -o $@ test/sha1test.c
+	@touch test/sha1test.d.tmp
+	@if cmp test/sha1test.d.tmp test/sha1test.d > /dev/null 2> /dev/null; then \
+		rm -f test/sha1test.d.tmp; \
+	else \
+		mv test/sha1test.d.tmp test/sha1test.d; \
+	fi
+test/sha256t: test/sha256t.o libcrypto.a
+	$(RM) test/sha256t
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/sha256t OBJECTS="test/sha256t.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/sha256t.o: test/sha256t.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/sha256t.d.tmp -MT $@ -c -o $@ test/sha256t.c
+	@touch test/sha256t.d.tmp
+	@if cmp test/sha256t.d.tmp test/sha256t.d > /dev/null 2> /dev/null; then \
+		rm -f test/sha256t.d.tmp; \
+	else \
+		mv test/sha256t.d.tmp test/sha256t.d; \
+	fi
+test/sha512t: test/sha512t.o libcrypto.a
+	$(RM) test/sha512t
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/sha512t OBJECTS="test/sha512t.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/sha512t.o: test/sha512t.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/sha512t.d.tmp -MT $@ -c -o $@ test/sha512t.c
+	@touch test/sha512t.d.tmp
+	@if cmp test/sha512t.d.tmp test/sha512t.d > /dev/null 2> /dev/null; then \
+		rm -f test/sha512t.d.tmp; \
+	else \
+		mv test/sha512t.d.tmp test/sha512t.d; \
+	fi
+test/srptest: test/srptest.o libcrypto.a
+	$(RM) test/srptest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/srptest OBJECTS="test/srptest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/srptest.o: test/srptest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/srptest.d.tmp -MT $@ -c -o $@ test/srptest.c
+	@touch test/srptest.d.tmp
+	@if cmp test/srptest.d.tmp test/srptest.d > /dev/null 2> /dev/null; then \
+		rm -f test/srptest.d.tmp; \
+	else \
+		mv test/srptest.d.tmp test/srptest.d; \
+	fi
+test/ssl_test: test/handshake_helper.o test/ssl_test.o test/ssl_test_ctx.o test/testutil.o libssl.a libcrypto.a
+	$(RM) test/ssl_test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/ssl_test OBJECTS="test/handshake_helper.o test/ssl_test.o test/ssl_test_ctx.o test/testutil.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/handshake_helper.o: test/handshake_helper.c
+	$(CC)  -I. -Iinclude -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/handshake_helper.d.tmp -MT $@ -c -o $@ test/handshake_helper.c
+	@touch test/handshake_helper.d.tmp
+	@if cmp test/handshake_helper.d.tmp test/handshake_helper.d > /dev/null 2> /dev/null; then \
+		rm -f test/handshake_helper.d.tmp; \
+	else \
+		mv test/handshake_helper.d.tmp test/handshake_helper.d; \
+	fi
+test/ssl_test.o: test/ssl_test.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/ssl_test.d.tmp -MT $@ -c -o $@ test/ssl_test.c
+	@touch test/ssl_test.d.tmp
+	@if cmp test/ssl_test.d.tmp test/ssl_test.d > /dev/null 2> /dev/null; then \
+		rm -f test/ssl_test.d.tmp; \
+	else \
+		mv test/ssl_test.d.tmp test/ssl_test.d; \
+	fi
+test/ssl_test_ctx.o: test/ssl_test_ctx.c
+	$(CC)  -I. -Iinclude -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/ssl_test_ctx.d.tmp -MT $@ -c -o $@ test/ssl_test_ctx.c
+	@touch test/ssl_test_ctx.d.tmp
+	@if cmp test/ssl_test_ctx.d.tmp test/ssl_test_ctx.d > /dev/null 2> /dev/null; then \
+		rm -f test/ssl_test_ctx.d.tmp; \
+	else \
+		mv test/ssl_test_ctx.d.tmp test/ssl_test_ctx.d; \
+	fi
+test/ssl_test_ctx_test: test/ssl_test_ctx.o test/ssl_test_ctx_test.o test/testutil.o libcrypto.a
+	$(RM) test/ssl_test_ctx_test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/ssl_test_ctx_test OBJECTS="test/ssl_test_ctx.o test/ssl_test_ctx_test.o test/testutil.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/ssl_test_ctx_test.o: test/ssl_test_ctx_test.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/ssl_test_ctx_test.d.tmp -MT $@ -c -o $@ test/ssl_test_ctx_test.c
+	@touch test/ssl_test_ctx_test.d.tmp
+	@if cmp test/ssl_test_ctx_test.d.tmp test/ssl_test_ctx_test.d > /dev/null 2> /dev/null; then \
+		rm -f test/ssl_test_ctx_test.d.tmp; \
+	else \
+		mv test/ssl_test_ctx_test.d.tmp test/ssl_test_ctx_test.d; \
+	fi
+test/sslapitest: test/sslapitest.o test/ssltestlib.o test/testutil.o libssl.a libcrypto.a
+	$(RM) test/sslapitest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/sslapitest OBJECTS="test/sslapitest.o test/ssltestlib.o test/testutil.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/sslapitest.o: test/sslapitest.c
+	$(CC)  -Iinclude -I. $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/sslapitest.d.tmp -MT $@ -c -o $@ test/sslapitest.c
+	@touch test/sslapitest.d.tmp
+	@if cmp test/sslapitest.d.tmp test/sslapitest.d > /dev/null 2> /dev/null; then \
+		rm -f test/sslapitest.d.tmp; \
+	else \
+		mv test/sslapitest.d.tmp test/sslapitest.d; \
+	fi
+test/sslcorrupttest: test/sslcorrupttest.o test/ssltestlib.o test/testutil.o libssl.a libcrypto.a
+	$(RM) test/sslcorrupttest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/sslcorrupttest OBJECTS="test/sslcorrupttest.o test/ssltestlib.o test/testutil.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/sslcorrupttest.o: test/sslcorrupttest.c
+	$(CC)  -Iinclude -Itest $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/sslcorrupttest.d.tmp -MT $@ -c -o $@ test/sslcorrupttest.c
+	@touch test/sslcorrupttest.d.tmp
+	@if cmp test/sslcorrupttest.d.tmp test/sslcorrupttest.d > /dev/null 2> /dev/null; then \
+		rm -f test/sslcorrupttest.d.tmp; \
+	else \
+		mv test/sslcorrupttest.d.tmp test/sslcorrupttest.d; \
+	fi
+test/ssltest_old: test/ssltest_old.o libssl.a libcrypto.a
+	$(RM) test/ssltest_old
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/ssltest_old OBJECTS="test/ssltest_old.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lssl -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/ssltest_old.o: test/ssltest_old.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/ssltest_old.d.tmp -MT $@ -c -o $@ test/ssltest_old.c
+	@touch test/ssltest_old.d.tmp
+	@if cmp test/ssltest_old.d.tmp test/ssltest_old.d > /dev/null 2> /dev/null; then \
+		rm -f test/ssltest_old.d.tmp; \
+	else \
+		mv test/ssltest_old.d.tmp test/ssltest_old.d; \
+	fi
+test/threadstest: test/threadstest.o libcrypto.a
+	$(RM) test/threadstest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/threadstest OBJECTS="test/threadstest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/threadstest.o: test/threadstest.c
+	$(CC)  -I. -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/threadstest.d.tmp -MT $@ -c -o $@ test/threadstest.c
+	@touch test/threadstest.d.tmp
+	@if cmp test/threadstest.d.tmp test/threadstest.d > /dev/null 2> /dev/null; then \
+		rm -f test/threadstest.d.tmp; \
+	else \
+		mv test/threadstest.d.tmp test/threadstest.d; \
+	fi
+test/v3ext: test/v3ext.o libcrypto.a
+	$(RM) test/v3ext
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/v3ext OBJECTS="test/v3ext.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/v3ext.o: test/v3ext.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/v3ext.d.tmp -MT $@ -c -o $@ test/v3ext.c
+	@touch test/v3ext.d.tmp
+	@if cmp test/v3ext.d.tmp test/v3ext.d > /dev/null 2> /dev/null; then \
+		rm -f test/v3ext.d.tmp; \
+	else \
+		mv test/v3ext.d.tmp test/v3ext.d; \
+	fi
+test/v3nametest: test/v3nametest.o libcrypto.a
+	$(RM) test/v3nametest
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/v3nametest OBJECTS="test/v3nametest.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/v3nametest.o: test/v3nametest.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/v3nametest.d.tmp -MT $@ -c -o $@ test/v3nametest.c
+	@touch test/v3nametest.d.tmp
+	@if cmp test/v3nametest.d.tmp test/v3nametest.d > /dev/null 2> /dev/null; then \
+		rm -f test/v3nametest.d.tmp; \
+	else \
+		mv test/v3nametest.d.tmp test/v3nametest.d; \
+	fi
+test/verify_extra_test: test/verify_extra_test.o libcrypto.a
+	$(RM) test/verify_extra_test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/verify_extra_test OBJECTS="test/verify_extra_test.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/verify_extra_test.o: test/verify_extra_test.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/verify_extra_test.d.tmp -MT $@ -c -o $@ test/verify_extra_test.c
+	@touch test/verify_extra_test.d.tmp
+	@if cmp test/verify_extra_test.d.tmp test/verify_extra_test.d > /dev/null 2> /dev/null; then \
+		rm -f test/verify_extra_test.d.tmp; \
+	else \
+		mv test/verify_extra_test.d.tmp test/verify_extra_test.d; \
+	fi
+test/wp_test: test/wp_test.o libcrypto.a
+	$(RM) test/wp_test
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/wp_test OBJECTS="test/wp_test.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/wp_test.o: test/wp_test.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/wp_test.d.tmp -MT $@ -c -o $@ test/wp_test.c
+	@touch test/wp_test.d.tmp
+	@if cmp test/wp_test.d.tmp test/wp_test.d > /dev/null 2> /dev/null; then \
+		rm -f test/wp_test.d.tmp; \
+	else \
+		mv test/wp_test.d.tmp test/wp_test.d; \
+	fi
+test/x509aux: test/x509aux.o libcrypto.a
+	$(RM) test/x509aux
+	$(MAKE) -f $(SRCDIR)/Makefile.shared -e \
+		PERL="$(PERL)" SRCDIR=$(SRCDIR) \
+		APPNAME=test/x509aux OBJECTS="test/x509aux.o" \
+		LIBDEPS='$(PLIB_LDFLAGS) '" -L. -lcrypto"' $(EX_LIBS)' \
+		CC='$(CC)' CFLAGS='$(CFLAGS) $(BIN_CFLAGS)' \
+		LDFLAGS='$(LDFLAGS)' \
+		link_app.
+test/x509aux.o: test/x509aux.c
+	$(CC)  -Iinclude $(CFLAGS) $(BIN_CFLAGS) -MMD -MF test/x509aux.d.tmp -MT $@ -c -o $@ test/x509aux.c
+	@touch test/x509aux.d.tmp
+	@if cmp test/x509aux.d.tmp test/x509aux.d > /dev/null 2> /dev/null; then \
+		rm -f test/x509aux.d.tmp; \
+	else \
+		mv test/x509aux.d.tmp test/x509aux.d; \
+	fi
+apps/CA.pl: apps/CA.pl.in
+	$(PERL) "-I$(BLDDIR)" -Mconfigdata "util/dofile.pl" \
+	    "-oMakefile" apps/CA.pl.in > "apps/CA.pl"
+	chmod a+x apps/CA.pl
+apps/tsget: apps/tsget.in
+	$(PERL) "-I$(BLDDIR)" -Mconfigdata "util/dofile.pl" \
+	    "-oMakefile" apps/tsget.in > "apps/tsget"
+	chmod a+x apps/tsget
+tools/c_rehash: tools/c_rehash.in
+	$(PERL) "-I$(BLDDIR)" -Mconfigdata "util/dofile.pl" \
+	    "-oMakefile" tools/c_rehash.in > "tools/c_rehash"
+	chmod a+x tools/c_rehash
+util/shlib_wrap.sh: util/shlib_wrap.sh.in
+	$(PERL) "-I$(BLDDIR)" -Mconfigdata "util/dofile.pl" \
+	    "-oMakefile" util/shlib_wrap.sh.in > "util/shlib_wrap.sh"
+	chmod a+x util/shlib_wrap.sh
+apps apps/: apps/openssl apps/CA.pl apps/tsget
+crypto crypto/: crypto/cpt_err.o crypto/cryptlib.o crypto/cversion.o crypto/ebcdic.o crypto/ex_data.o crypto/init.o crypto/mem.o crypto/mem_clr.o crypto/mem_dbg.o crypto/mem_sec.o crypto/o_dir.o crypto/o_fips.o crypto/o_fopen.o crypto/o_init.o crypto/o_str.o crypto/o_time.o crypto/threads_none.o crypto/threads_pthread.o crypto/threads_win.o crypto/uid.o
+crypto/aes crypto/aes/: crypto/aes/aes_cbc.o crypto/aes/aes_cfb.o crypto/aes/aes_core.o crypto/aes/aes_ecb.o crypto/aes/aes_ige.o crypto/aes/aes_misc.o crypto/aes/aes_ofb.o crypto/aes/aes_wrap.o
+crypto/asn1 crypto/asn1/: crypto/asn1/a_bitstr.o crypto/asn1/a_d2i_fp.o crypto/asn1/a_digest.o crypto/asn1/a_dup.o crypto/asn1/a_gentm.o crypto/asn1/a_i2d_fp.o crypto/asn1/a_int.o crypto/asn1/a_mbstr.o crypto/asn1/a_object.o crypto/asn1/a_octet.o crypto/asn1/a_print.o crypto/asn1/a_sign.o crypto/asn1/a_strex.o crypto/asn1/a_strnid.o crypto/asn1/a_time.o crypto/asn1/a_type.o crypto/asn1/a_utctm.o crypto/asn1/a_utf8.o crypto/asn1/a_verify.o crypto/asn1/ameth_lib.o crypto/asn1/asn1_err.o crypto/asn1/asn1_gen.o crypto/asn1/asn1_lib.o crypto/asn1/asn1_par.o crypto/asn1/asn_mime.o crypto/asn1/asn_moid.o crypto/asn1/asn_mstbl.o crypto/asn1/asn_pack.o crypto/asn1/bio_asn1.o crypto/asn1/bio_ndef.o crypto/asn1/d2i_pr.o crypto/asn1/d2i_pu.o crypto/asn1/evp_asn1.o crypto/asn1/f_int.o crypto/asn1/f_string.o crypto/asn1/i2d_pr.o crypto/asn1/i2d_pu.o crypto/asn1/n_pkey.o crypto/asn1/nsseq.o crypto/asn1/p5_pbe.o crypto/asn1/p5_pbev2.o crypto/asn1/p5_scrypt.o crypto/asn1/p8_pkey.o crypto/asn1/t_bitst.o crypto/asn1/t_pkey.o crypto/asn1/t_spki.o crypto/asn1/tasn_dec.o crypto/asn1/tasn_enc.o crypto/asn1/tasn_fre.o crypto/asn1/tasn_new.o crypto/asn1/tasn_prn.o crypto/asn1/tasn_scn.o crypto/asn1/tasn_typ.o crypto/asn1/tasn_utl.o crypto/asn1/x_algor.o crypto/asn1/x_bignum.o crypto/asn1/x_info.o crypto/asn1/x_long.o crypto/asn1/x_pkey.o crypto/asn1/x_sig.o crypto/asn1/x_spki.o crypto/asn1/x_val.o
+crypto/async crypto/async/: crypto/async/async.o crypto/async/async_err.o crypto/async/async_wait.o
+crypto/async/arch crypto/async/arch/: crypto/async/arch/async_null.o crypto/async/arch/async_posix.o crypto/async/arch/async_win.o
+crypto/bf crypto/bf/: crypto/bf/bf_cfb64.o crypto/bf/bf_ecb.o crypto/bf/bf_enc.o crypto/bf/bf_ofb64.o crypto/bf/bf_skey.o
+crypto/bio crypto/bio/: crypto/bio/b_addr.o crypto/bio/b_dump.o crypto/bio/b_print.o crypto/bio/b_sock.o crypto/bio/b_sock2.o crypto/bio/bf_buff.o crypto/bio/bf_lbuf.o crypto/bio/bf_nbio.o crypto/bio/bf_null.o crypto/bio/bio_cb.o crypto/bio/bio_err.o crypto/bio/bio_lib.o crypto/bio/bio_meth.o crypto/bio/bss_acpt.o crypto/bio/bss_bio.o crypto/bio/bss_conn.o crypto/bio/bss_dgram.o crypto/bio/bss_fd.o crypto/bio/bss_file.o crypto/bio/bss_log.o crypto/bio/bss_mem.o crypto/bio/bss_null.o crypto/bio/bss_sock.o
+crypto/blake2 crypto/blake2/: crypto/blake2/blake2b.o crypto/blake2/blake2s.o crypto/blake2/m_blake2b.o crypto/blake2/m_blake2s.o
+crypto/bn crypto/bn/: crypto/bn/bn_add.o crypto/bn/bn_asm.o crypto/bn/bn_blind.o crypto/bn/bn_const.o crypto/bn/bn_ctx.o crypto/bn/bn_depr.o crypto/bn/bn_dh.o crypto/bn/bn_div.o crypto/bn/bn_err.o crypto/bn/bn_exp.o crypto/bn/bn_exp2.o crypto/bn/bn_gcd.o crypto/bn/bn_gf2m.o crypto/bn/bn_intern.o crypto/bn/bn_kron.o crypto/bn/bn_lib.o crypto/bn/bn_mod.o crypto/bn/bn_mont.o crypto/bn/bn_mpi.o crypto/bn/bn_mul.o crypto/bn/bn_nist.o crypto/bn/bn_prime.o crypto/bn/bn_print.o crypto/bn/bn_rand.o crypto/bn/bn_recp.o crypto/bn/bn_shift.o crypto/bn/bn_sqr.o crypto/bn/bn_sqrt.o crypto/bn/bn_srp.o crypto/bn/bn_word.o crypto/bn/bn_x931p.o
+crypto/buffer crypto/buffer/: crypto/buffer/buf_err.o crypto/buffer/buffer.o
+crypto/camellia crypto/camellia/: crypto/camellia/camellia.o crypto/camellia/cmll_cbc.o crypto/camellia/cmll_cfb.o crypto/camellia/cmll_ctr.o crypto/camellia/cmll_ecb.o crypto/camellia/cmll_misc.o crypto/camellia/cmll_ofb.o
+crypto/cast crypto/cast/: crypto/cast/c_cfb64.o crypto/cast/c_ecb.o crypto/cast/c_enc.o crypto/cast/c_ofb64.o crypto/cast/c_skey.o
+crypto/chacha crypto/chacha/: crypto/chacha/chacha_enc.o
+crypto/cmac crypto/cmac/: crypto/cmac/cm_ameth.o crypto/cmac/cm_pmeth.o crypto/cmac/cmac.o
+crypto/cms crypto/cms/: crypto/cms/cms_asn1.o crypto/cms/cms_att.o crypto/cms/cms_cd.o crypto/cms/cms_dd.o crypto/cms/cms_enc.o crypto/cms/cms_env.o crypto/cms/cms_err.o crypto/cms/cms_ess.o crypto/cms/cms_io.o crypto/cms/cms_kari.o crypto/cms/cms_lib.o crypto/cms/cms_pwri.o crypto/cms/cms_sd.o crypto/cms/cms_smime.o
+crypto/comp crypto/comp/: crypto/comp/c_zlib.o crypto/comp/comp_err.o crypto/comp/comp_lib.o
+crypto/conf crypto/conf/: crypto/conf/conf_api.o crypto/conf/conf_def.o crypto/conf/conf_err.o crypto/conf/conf_lib.o crypto/conf/conf_mall.o crypto/conf/conf_mod.o crypto/conf/conf_sap.o
+crypto/ct crypto/ct/: crypto/ct/ct_b64.o crypto/ct/ct_err.o crypto/ct/ct_log.o crypto/ct/ct_oct.o crypto/ct/ct_policy.o crypto/ct/ct_prn.o crypto/ct/ct_sct.o crypto/ct/ct_sct_ctx.o crypto/ct/ct_vfy.o crypto/ct/ct_x509v3.o
+crypto/des crypto/des/: crypto/des/cbc_cksm.o crypto/des/cbc_enc.o crypto/des/cfb64ede.o crypto/des/cfb64enc.o crypto/des/cfb_enc.o crypto/des/des_enc.o crypto/des/ecb3_enc.o crypto/des/ecb_enc.o crypto/des/fcrypt.o crypto/des/fcrypt_b.o crypto/des/ofb64ede.o crypto/des/ofb64enc.o crypto/des/ofb_enc.o crypto/des/pcbc_enc.o crypto/des/qud_cksm.o crypto/des/rand_key.o crypto/des/rpc_enc.o crypto/des/set_key.o crypto/des/str2key.o crypto/des/xcbc_enc.o
+crypto/dh crypto/dh/: crypto/dh/dh_ameth.o crypto/dh/dh_asn1.o crypto/dh/dh_check.o crypto/dh/dh_depr.o crypto/dh/dh_err.o crypto/dh/dh_gen.o crypto/dh/dh_kdf.o crypto/dh/dh_key.o crypto/dh/dh_lib.o crypto/dh/dh_meth.o crypto/dh/dh_pmeth.o crypto/dh/dh_prn.o crypto/dh/dh_rfc5114.o
+crypto/dsa crypto/dsa/: crypto/dsa/dsa_ameth.o crypto/dsa/dsa_asn1.o crypto/dsa/dsa_depr.o crypto/dsa/dsa_err.o crypto/dsa/dsa_gen.o crypto/dsa/dsa_key.o crypto/dsa/dsa_lib.o crypto/dsa/dsa_meth.o crypto/dsa/dsa_ossl.o crypto/dsa/dsa_pmeth.o crypto/dsa/dsa_prn.o crypto/dsa/dsa_sign.o crypto/dsa/dsa_vrf.o
+crypto/dso crypto/dso/: crypto/dso/dso_dl.o crypto/dso/dso_dlfcn.o crypto/dso/dso_err.o crypto/dso/dso_lib.o crypto/dso/dso_openssl.o crypto/dso/dso_vms.o crypto/dso/dso_win32.o
+crypto/ec crypto/ec/: crypto/ec/curve25519.o crypto/ec/ec2_mult.o crypto/ec/ec2_oct.o crypto/ec/ec2_smpl.o crypto/ec/ec_ameth.o crypto/ec/ec_asn1.o crypto/ec/ec_check.o crypto/ec/ec_curve.o crypto/ec/ec_cvt.o crypto/ec/ec_err.o crypto/ec/ec_key.o crypto/ec/ec_kmeth.o crypto/ec/ec_lib.o crypto/ec/ec_mult.o crypto/ec/ec_oct.o crypto/ec/ec_pmeth.o crypto/ec/ec_print.o crypto/ec/ecdh_kdf.o crypto/ec/ecdh_ossl.o crypto/ec/ecdsa_ossl.o crypto/ec/ecdsa_sign.o crypto/ec/ecdsa_vrf.o crypto/ec/eck_prn.o crypto/ec/ecp_mont.o crypto/ec/ecp_nist.o crypto/ec/ecp_nistp224.o crypto/ec/ecp_nistp256.o crypto/ec/ecp_nistp521.o crypto/ec/ecp_nistputil.o crypto/ec/ecp_oct.o crypto/ec/ecp_smpl.o crypto/ec/ecx_meth.o
+crypto/engine crypto/engine/: crypto/engine/eng_all.o crypto/engine/eng_cnf.o crypto/engine/eng_cryptodev.o crypto/engine/eng_ctrl.o crypto/engine/eng_dyn.o crypto/engine/eng_err.o crypto/engine/eng_fat.o crypto/engine/eng_init.o crypto/engine/eng_lib.o crypto/engine/eng_list.o crypto/engine/eng_openssl.o crypto/engine/eng_pkey.o crypto/engine/eng_rdrand.o crypto/engine/eng_table.o crypto/engine/tb_asnmth.o crypto/engine/tb_cipher.o crypto/engine/tb_dh.o crypto/engine/tb_digest.o crypto/engine/tb_dsa.o crypto/engine/tb_eckey.o crypto/engine/tb_pkmeth.o crypto/engine/tb_rand.o crypto/engine/tb_rsa.o
+crypto/err crypto/err/: crypto/err/err.o crypto/err/err_all.o crypto/err/err_prn.o
+crypto/evp crypto/evp/: crypto/evp/bio_b64.o crypto/evp/bio_enc.o crypto/evp/bio_md.o crypto/evp/bio_ok.o crypto/evp/c_allc.o crypto/evp/c_alld.o crypto/evp/cmeth_lib.o crypto/evp/digest.o crypto/evp/e_aes.o crypto/evp/e_aes_cbc_hmac_sha1.o crypto/evp/e_aes_cbc_hmac_sha256.o crypto/evp/e_bf.o crypto/evp/e_camellia.o crypto/evp/e_cast.o crypto/evp/e_chacha20_poly1305.o crypto/evp/e_des.o crypto/evp/e_des3.o crypto/evp/e_idea.o crypto/evp/e_null.o crypto/evp/e_old.o crypto/evp/e_rc2.o crypto/evp/e_rc4.o crypto/evp/e_rc4_hmac_md5.o crypto/evp/e_rc5.o crypto/evp/e_seed.o crypto/evp/e_xcbc_d.o crypto/evp/encode.o crypto/evp/evp_cnf.o crypto/evp/evp_enc.o crypto/evp/evp_err.o crypto/evp/evp_key.o crypto/evp/evp_lib.o crypto/evp/evp_pbe.o crypto/evp/evp_pkey.o crypto/evp/m_md2.o crypto/evp/m_md4.o crypto/evp/m_md5.o crypto/evp/m_md5_sha1.o crypto/evp/m_mdc2.o crypto/evp/m_null.o crypto/evp/m_ripemd.o crypto/evp/m_sha1.o crypto/evp/m_sigver.o crypto/evp/m_wp.o crypto/evp/names.o crypto/evp/p5_crpt.o crypto/evp/p5_crpt2.o crypto/evp/p_dec.o crypto/evp/p_enc.o crypto/evp/p_lib.o crypto/evp/p_open.o crypto/evp/p_seal.o crypto/evp/p_sign.o crypto/evp/p_verify.o crypto/evp/pmeth_fn.o crypto/evp/pmeth_gn.o crypto/evp/pmeth_lib.o crypto/evp/scrypt.o
+crypto/hmac crypto/hmac/: crypto/hmac/hm_ameth.o crypto/hmac/hm_pmeth.o crypto/hmac/hmac.o
+crypto/idea crypto/idea/: crypto/idea/i_cbc.o crypto/idea/i_cfb64.o crypto/idea/i_ecb.o crypto/idea/i_ofb64.o crypto/idea/i_skey.o
+crypto/kdf crypto/kdf/: crypto/kdf/hkdf.o crypto/kdf/kdf_err.o crypto/kdf/tls1_prf.o
+crypto/lhash crypto/lhash/: crypto/lhash/lh_stats.o crypto/lhash/lhash.o
+crypto/md4 crypto/md4/: crypto/md4/md4_dgst.o crypto/md4/md4_one.o
+crypto/md5 crypto/md5/: crypto/md5/md5_dgst.o crypto/md5/md5_one.o
+crypto/mdc2 crypto/mdc2/: crypto/mdc2/mdc2_one.o crypto/mdc2/mdc2dgst.o
+crypto/modes crypto/modes/: crypto/modes/cbc128.o crypto/modes/ccm128.o crypto/modes/cfb128.o crypto/modes/ctr128.o crypto/modes/cts128.o crypto/modes/gcm128.o crypto/modes/ocb128.o crypto/modes/ofb128.o crypto/modes/wrap128.o crypto/modes/xts128.o
+crypto/objects crypto/objects/: crypto/objects/o_names.o crypto/objects/obj_dat.o crypto/objects/obj_err.o crypto/objects/obj_lib.o crypto/objects/obj_xref.o
+crypto/ocsp crypto/ocsp/: crypto/ocsp/ocsp_asn.o crypto/ocsp/ocsp_cl.o crypto/ocsp/ocsp_err.o crypto/ocsp/ocsp_ext.o crypto/ocsp/ocsp_ht.o crypto/ocsp/ocsp_lib.o crypto/ocsp/ocsp_prn.o crypto/ocsp/ocsp_srv.o crypto/ocsp/ocsp_vfy.o crypto/ocsp/v3_ocsp.o
+crypto/pem crypto/pem/: crypto/pem/pem_all.o crypto/pem/pem_err.o crypto/pem/pem_info.o crypto/pem/pem_lib.o crypto/pem/pem_oth.o crypto/pem/pem_pk8.o crypto/pem/pem_pkey.o crypto/pem/pem_sign.o crypto/pem/pem_x509.o crypto/pem/pem_xaux.o crypto/pem/pvkfmt.o
+crypto/pkcs12 crypto/pkcs12/: crypto/pkcs12/p12_add.o crypto/pkcs12/p12_asn.o crypto/pkcs12/p12_attr.o crypto/pkcs12/p12_crpt.o crypto/pkcs12/p12_crt.o crypto/pkcs12/p12_decr.o crypto/pkcs12/p12_init.o crypto/pkcs12/p12_key.o crypto/pkcs12/p12_kiss.o crypto/pkcs12/p12_mutl.o crypto/pkcs12/p12_npas.o crypto/pkcs12/p12_p8d.o crypto/pkcs12/p12_p8e.o crypto/pkcs12/p12_sbag.o crypto/pkcs12/p12_utl.o crypto/pkcs12/pk12err.o
+crypto/pkcs7 crypto/pkcs7/: crypto/pkcs7/bio_pk7.o crypto/pkcs7/pk7_asn1.o crypto/pkcs7/pk7_attr.o crypto/pkcs7/pk7_doit.o crypto/pkcs7/pk7_lib.o crypto/pkcs7/pk7_mime.o crypto/pkcs7/pk7_smime.o crypto/pkcs7/pkcs7err.o
+crypto/poly1305 crypto/poly1305/: crypto/poly1305/poly1305.o
+crypto/rand crypto/rand/: crypto/rand/md_rand.o crypto/rand/rand_egd.o crypto/rand/rand_err.o crypto/rand/rand_lib.o crypto/rand/rand_unix.o crypto/rand/rand_vms.o crypto/rand/rand_win.o crypto/rand/randfile.o
+crypto/rc2 crypto/rc2/: crypto/rc2/rc2_cbc.o crypto/rc2/rc2_ecb.o crypto/rc2/rc2_skey.o crypto/rc2/rc2cfb64.o crypto/rc2/rc2ofb64.o
+crypto/rc4 crypto/rc4/: crypto/rc4/rc4_enc.o crypto/rc4/rc4_skey.o
+crypto/ripemd crypto/ripemd/: crypto/ripemd/rmd_dgst.o crypto/ripemd/rmd_one.o
+crypto/rsa crypto/rsa/: crypto/rsa/rsa_ameth.o crypto/rsa/rsa_asn1.o crypto/rsa/rsa_chk.o crypto/rsa/rsa_crpt.o crypto/rsa/rsa_depr.o crypto/rsa/rsa_err.o crypto/rsa/rsa_gen.o crypto/rsa/rsa_lib.o crypto/rsa/rsa_meth.o crypto/rsa/rsa_none.o crypto/rsa/rsa_null.o crypto/rsa/rsa_oaep.o crypto/rsa/rsa_ossl.o crypto/rsa/rsa_pk1.o crypto/rsa/rsa_pmeth.o crypto/rsa/rsa_prn.o crypto/rsa/rsa_pss.o crypto/rsa/rsa_saos.o crypto/rsa/rsa_sign.o crypto/rsa/rsa_ssl.o crypto/rsa/rsa_x931.o crypto/rsa/rsa_x931g.o
+crypto/seed crypto/seed/: crypto/seed/seed.o crypto/seed/seed_cbc.o crypto/seed/seed_cfb.o crypto/seed/seed_ecb.o crypto/seed/seed_ofb.o
+crypto/sha crypto/sha/: crypto/sha/sha1_one.o crypto/sha/sha1dgst.o crypto/sha/sha256.o crypto/sha/sha512.o
+crypto/srp crypto/srp/: crypto/srp/srp_lib.o crypto/srp/srp_vfy.o
+crypto/stack crypto/stack/: crypto/stack/stack.o
+crypto/ts crypto/ts/: crypto/ts/ts_asn1.o crypto/ts/ts_conf.o crypto/ts/ts_err.o crypto/ts/ts_lib.o crypto/ts/ts_req_print.o crypto/ts/ts_req_utils.o crypto/ts/ts_rsp_print.o crypto/ts/ts_rsp_sign.o crypto/ts/ts_rsp_utils.o crypto/ts/ts_rsp_verify.o crypto/ts/ts_verify_ctx.o
+crypto/txt_db crypto/txt_db/: crypto/txt_db/txt_db.o
+crypto/whrlpool crypto/whrlpool/: crypto/whrlpool/wp_block.o crypto/whrlpool/wp_dgst.o
+crypto/x509 crypto/x509/: crypto/x509/by_dir.o crypto/x509/by_file.o crypto/x509/t_crl.o crypto/x509/t_req.o crypto/x509/t_x509.o crypto/x509/x509_att.o crypto/x509/x509_cmp.o crypto/x509/x509_d2.o crypto/x509/x509_def.o crypto/x509/x509_err.o crypto/x509/x509_ext.o crypto/x509/x509_lu.o crypto/x509/x509_obj.o crypto/x509/x509_r2x.o crypto/x509/x509_req.o crypto/x509/x509_set.o crypto/x509/x509_trs.o crypto/x509/x509_txt.o crypto/x509/x509_v3.o crypto/x509/x509_vfy.o crypto/x509/x509_vpm.o crypto/x509/x509cset.o crypto/x509/x509name.o crypto/x509/x509rset.o crypto/x509/x509spki.o crypto/x509/x509type.o crypto/x509/x_all.o crypto/x509/x_attrib.o crypto/x509/x_crl.o crypto/x509/x_exten.o crypto/x509/x_name.o crypto/x509/x_pubkey.o crypto/x509/x_req.o crypto/x509/x_x509.o crypto/x509/x_x509a.o
+crypto/x509v3 crypto/x509v3/: crypto/x509v3/pcy_cache.o crypto/x509v3/pcy_data.o crypto/x509v3/pcy_lib.o crypto/x509v3/pcy_map.o crypto/x509v3/pcy_node.o crypto/x509v3/pcy_tree.o crypto/x509v3/v3_addr.o crypto/x509v3/v3_akey.o crypto/x509v3/v3_akeya.o crypto/x509v3/v3_alt.o crypto/x509v3/v3_asid.o crypto/x509v3/v3_bcons.o crypto/x509v3/v3_bitst.o crypto/x509v3/v3_conf.o crypto/x509v3/v3_cpols.o crypto/x509v3/v3_crld.o crypto/x509v3/v3_enum.o crypto/x509v3/v3_extku.o crypto/x509v3/v3_genn.o crypto/x509v3/v3_ia5.o crypto/x509v3/v3_info.o crypto/x509v3/v3_int.o crypto/x509v3/v3_lib.o crypto/x509v3/v3_ncons.o crypto/x509v3/v3_pci.o crypto/x509v3/v3_pcia.o crypto/x509v3/v3_pcons.o crypto/x509v3/v3_pku.o crypto/x509v3/v3_pmaps.o crypto/x509v3/v3_prn.o crypto/x509v3/v3_purp.o crypto/x509v3/v3_skey.o crypto/x509v3/v3_sxnet.o crypto/x509v3/v3_tlsf.o crypto/x509v3/v3_utl.o crypto/x509v3/v3err.o
+engines engines/: engines/e_capi.o engines/e_padlock.o
+fuzz fuzz/: fuzz/asn1-test fuzz/asn1parse-test fuzz/bignum-test fuzz/bndiv-test fuzz/cms-test fuzz/conf-test fuzz/crl-test fuzz/ct-test fuzz/server-test fuzz/x509-test
+ssl ssl/: ssl/bio_ssl.o ssl/d1_lib.o ssl/d1_msg.o ssl/d1_srtp.o ssl/methods.o ssl/pqueue.o ssl/s3_cbc.o ssl/s3_enc.o ssl/s3_lib.o ssl/s3_msg.o ssl/ssl_asn1.o ssl/ssl_cert.o ssl/ssl_ciph.o ssl/ssl_conf.o ssl/ssl_err.o ssl/ssl_init.o ssl/ssl_lib.o ssl/ssl_mcnf.o ssl/ssl_rsa.o ssl/ssl_sess.o ssl/ssl_stat.o ssl/ssl_txt.o ssl/ssl_utst.o ssl/t1_enc.o ssl/t1_ext.o ssl/t1_lib.o ssl/t1_reneg.o ssl/t1_trce.o ssl/tls_srp.o
+ssl/record ssl/record/: ssl/record/dtls1_bitmap.o ssl/record/rec_layer_d1.o ssl/record/rec_layer_s3.o ssl/record/ssl3_buffer.o ssl/record/ssl3_record.o
+ssl/statem ssl/statem/: ssl/statem/statem.o ssl/statem/statem_clnt.o ssl/statem/statem_dtls.o ssl/statem/statem_lib.o ssl/statem/statem_srvr.o
+tools tools/: tools/c_rehash
+util util/: util/shlib_wrap.sh
+crypto/md5/md5-ia64.s: crypto/md5/asm/md5-ia64.S
+	$(CC) $(CFLAGS) -E crypto/md5/asm/md5-ia64.S | 	$(PERL) -ne 's/;\s+/;\n/g; print;' > $@
+
+##### SHA assembler implementations
+
+# GNU make "catch all"
+crypto/sha/sha1-%.S:	crypto/sha/asm/sha1-%.pl
+	CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
+crypto/sha/sha256-%.S:	crypto/sha/asm/sha512-%.pl
+	CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
+crypto/sha/sha512-%.S:	crypto/sha/asm/sha512-%.pl
+	CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
+crypto/poly1305/poly1305-%.S:	crypto/poly1305/asm/poly1305-%.pl
+	CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
+##### AES assembler implementations
+
+# GNU make "catch all"
+crypto/aes/aes-%.S:	crypto/aes/asm/aes-%.pl
+	CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
+crypto/aes/bsaes-%.S:	crypto/aes/asm/bsaes-%.pl
+	CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
+
+crypto/rc4/rc4-ia64.s: crypto/rc4/asm/rc4-ia64.pl
+	@(trap "rm $@.*" INT 0; 	  $(PERL) $< $(CFLAGS) $(LIB_CFLAGS) $@.S; 	  case `awk '/^#define RC4_INT/{print$$NF}' $(BLDDIR)/include/openssl/opensslconf.h` in 	  int)	set -x; $(CC) $(CFLAGS) $(LIB_CFLAGS) -DSZ=4 -E $@.S > $@.i && mv -f $@.i $@;; 	  char)	set -x; $(CC) $(CFLAGS) $(LIB_CFLAGS) -DSZ=1 -E $@.S > $@.i && mv -f $@.i $@;; 	  *)	exit 1 ;; 	  esac )
+
+# GNU make "catch all"
+crypto/rc4/rc4-%.s:	crypto/rc4/asm/rc4-%.pl
+	CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
+##### CHACHA assembler implementations
+
+crypto/chacha/chacha-%.S:	crypto/chacha/asm/chacha-%.pl
+	CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
+# GNU make "catch all"
+crypto/modes/ghash-%.S:	crypto/modes/asm/ghash-%.pl
+	CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
+##### BN assembler implementations
+
+crypto/bn/bn-mips3.o:	crypto/bn/asm/mips3.s
+	@if [ "$(CC)" = "gcc" ]; then 		ABI=`expr "$(CFLAGS)" : ".*-mabi=\([n3264]*\)"` && 		as -$$ABI -O -o $@ crypto/bn/asm/mips3.s; 	else	$(CC) -c $(CFLAGS) $(LIB_CFLAGS) -o $@ crypto/bn/asm/mips3.s; fi
+
+# GNU assembler fails to compile PA-RISC2 modules, insist on calling
+# vendor assembler...
+crypto/bn/pa-risc2W.o: crypto/bn/asm/pa-risc2W.s
+	CC="$(CC)" $(PERL) $(SRCDIR)/util/fipsas.pl $(SRCDIR) $< /usr/ccs/bin/as -o pa-risc2W.o crypto/bn/asm/pa-risc2W.s
+crypto/bn/pa-risc2.o: crypto/bn/asm/pa-risc2.s
+	CC="$(CC)" $(PERL) $(SRCDIR)/util/fipsas.pl $(SRCDIR) $< /usr/ccs/bin/as -o pa-risc2.o crypto/bn/asm/pa-risc2.s
+
+crypto/ec/ecp_nistz256-%.S:	crypto/ec/asm/ecp_nistz256-%.pl
+	CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+crypto/aes/aes_core.o: crypto/aes/aes_core.c \
+ ../musl-1.1.18/include/assert.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/aes.h \
+ ../musl-1.1.18/include/stddef.h crypto/aes/aes_locl.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h
+crypto/kdf/hkdf.o: crypto/kdf/hkdf.c ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/hmac.h \
+ include/openssl/opensslconf.h include/openssl/evp.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/symhacks.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/kdf.h crypto/include/internal/cryptlib.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/evp_int.h
+crypto/cms/cms_dd.o: crypto/cms/cms_dd.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/asn1t.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/pem.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/x509.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/pem2.h include/openssl/x509v3.h include/openssl/conf.h \
+ include/openssl/cms.h crypto/cms/cms_lcl.h
+crypto/evp/e_rc2.o: crypto/evp/e_rc2.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/evp_int.h include/openssl/rc2.h
+crypto/pem/pem_sign.o: crypto/pem/pem_sign.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h include/openssl/pem.h \
+ include/openssl/pem2.h
+crypto/aes/aes_ofb.o: crypto/aes/aes_ofb.c include/openssl/aes.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/modes.h
+crypto/aes/aes_ige.o: crypto/aes/aes_ige.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/aes.h \
+ crypto/aes/aes_locl.h
+crypto/rand/rand_vms.o: crypto/rand/rand_vms.c include/openssl/rand.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h crypto/rand/rand_lcl.h \
+ include/openssl/evp.h include/openssl/symhacks.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/sha.h ../musl-1.1.18/include/stddef.h
+crypto/ocsp/ocsp_err.o: crypto/ocsp/ocsp_err.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/symhacks.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/ocsp.h include/openssl/x509.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/x509v3.h include/openssl/conf.h
+crypto/bn/bn_div.o: crypto/bn/bn_div.c include/openssl/bn.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h
+crypto/evp/e_camellia.o: crypto/evp/e_camellia.c \
+ include/openssl/opensslconf.h include/openssl/evp.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/symhacks.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h ../musl-1.1.18/include/assert.h \
+ include/openssl/camellia.h ../musl-1.1.18/include/stddef.h \
+ crypto/include/internal/evp_int.h crypto/modes/modes_lcl.h \
+ include/openssl/modes.h
+crypto/asn1/d2i_pu.o: crypto/asn1/d2i_pu.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/ec.h \
+ crypto/include/internal/evp_int.h
+crypto/ts/ts_rsp_print.o: crypto/ts/ts_rsp_print.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/x509v3.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/conf.h include/openssl/ts.h crypto/ts/ts_lcl.h
+crypto/asn1/tasn_utl.o: crypto/asn1/tasn_utl.c \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/strings.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/asn1t.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ crypto/asn1/asn1_locl.h
+crypto/init.o: crypto/init.c crypto/include/internal/cryptlib_int.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/rand.h \
+ include/openssl/rand.h include/internal/bio.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/evp_int.h include/internal/conf.h \
+ include/openssl/conf.h crypto/include/internal/async.h \
+ include/openssl/async.h crypto/include/internal/engine.h \
+ include/openssl/engine.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/ec.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h include/internal/comp.h include/openssl/comp.h \
+ include/internal/err.h crypto/include/internal/err_int.h \
+ crypto/include/internal/objects.h ../musl-1.1.18/include/assert.h \
+ include/internal/thread_once.h include/internal/dso.h
+crypto/ec/ec_err.o: crypto/ec/ec_err.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/err.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/ec.h \
+ include/openssl/asn1.h include/openssl/bn.h
+crypto/seed/seed_ofb.o: crypto/seed/seed_ofb.c include/openssl/seed.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ ../musl-1.1.18/include/stdio.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/modes.h \
+ ../musl-1.1.18/include/stddef.h
+crypto/engine/eng_all.o: crypto/engine/eng_all.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/engine/eng_int.h \
+ crypto/include/internal/engine.h include/openssl/engine.h \
+ include/openssl/bn.h include/openssl/rsa.h include/openssl/asn1.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/ec.h \
+ include/openssl/rand.h include/openssl/ui.h include/openssl/x509.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/internal/thread_once.h
+crypto/cast/c_cfb64.o: crypto/cast/c_cfb64.c include/openssl/cast.h \
+ include/openssl/opensslconf.h crypto/cast/cast_lcl.h e_os.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h
+crypto/sha/sha1dgst.o: crypto/sha/sha1dgst.c include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/sha/sha_locl.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/sha.h ../musl-1.1.18/include/stddef.h \
+ crypto/include/internal/md32_common.h
+crypto/asn1/x_sig.o: crypto/asn1/x_sig.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1t.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/include/internal/x509_int.h
+crypto/asn1/p5_pbev2.o: crypto/asn1/p5_pbev2.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1t.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/rand.h
+crypto/pkcs12/p12_init.o: crypto/pkcs12/p12_init.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/pkcs12.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/pkcs12/p12_lcl.h
+crypto/engine/eng_init.o: crypto/engine/eng_init.c \
+ crypto/engine/eng_int.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/engine.h \
+ include/openssl/engine.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/internal/thread_once.h
+crypto/modes/xts128.o: crypto/modes/xts128.c include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/modes/modes_lcl.h \
+ include/openssl/modes.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h
+crypto/o_str.o: crypto/o_str.c ../musl-1.1.18/include/ctype.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ e_os.h include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ ../musl-1.1.18/include/stdio.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h include/openssl/symhacks.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/string.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/internal/o_str.h
+crypto/lhash/lh_stats.o: crypto/lhash/lh_stats.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h crypto/include/internal/cryptlib.h \
+ e_os.h include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/lhash/lhash_lcl.h
+crypto/dso/dso_win32.o: crypto/dso/dso_win32.c crypto/dso/dso_locl.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/internal/dso.h crypto/include/internal/dso_conf.h
+crypto/evp/e_bf.o: crypto/evp/e_bf.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/evp_int.h include/openssl/blowfish.h
+crypto/md5/md5_one.o: crypto/md5/md5_one.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/md5.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h
+crypto/bn/bn_shift.o: crypto/bn/bn_shift.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h
+crypto/des/cbc_enc.o: crypto/des/cbc_enc.c crypto/des/ncbc_enc.c \
+ crypto/des/des_locl.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/des.h
+crypto/rsa/rsa_asn1.o: crypto/rsa/rsa_asn1.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/asn1t.h crypto/rsa/rsa_locl.h
+crypto/aes/aes_cfb.o: crypto/aes/aes_cfb.c include/openssl/aes.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/modes.h
+crypto/des/des_enc.o: crypto/des/des_enc.c include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/des/des_locl.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/des.h crypto/des/spr.h crypto/des/ncbc_enc.c
+crypto/evp/bio_enc.o: crypto/evp/bio_enc.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/internal/bio.h
+crypto/objects/obj_lib.o: crypto/objects/obj_lib.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/asn1_int.h
+crypto/async/async_wait.o: crypto/async/async_wait.c \
+ crypto/async/async_locl.h crypto/include/internal/async.h \
+ include/openssl/async.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/async/arch/async_win.h \
+ crypto/async/arch/async_posix.h crypto/async/arch/async_null.h \
+ include/openssl/err.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h
+crypto/mdc2/mdc2_one.o: crypto/mdc2/mdc2_one.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/mdc2.h include/openssl/des.h
+crypto/seed/seed_ecb.o: crypto/seed/seed_ecb.c include/openssl/seed.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ ../musl-1.1.18/include/stdio.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h
+crypto/pem/pem_x509.o: crypto/pem/pem_x509.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h include/openssl/pem.h \
+ include/openssl/pem2.h
+crypto/threads_none.o: crypto/threads_none.c include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h
+crypto/ec/ecdh_kdf.o: crypto/ec/ecdh_kdf.c \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/strings.h \
+ include/openssl/ec.h include/openssl/opensslconf.h \
+ include/openssl/asn1.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/bn.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h
+crypto/rsa/rsa_ssl.o: crypto/rsa/rsa_ssl.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h include/openssl/rsa.h include/openssl/asn1.h \
+ include/openssl/rand.h
+crypto/pkcs7/pk7_mime.o: crypto/pkcs7/pk7_mime.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/ctype.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h
+crypto/asn1/tasn_enc.o: crypto/asn1/tasn_enc.c \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/strings.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/asn1t.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ crypto/include/internal/asn1_int.h crypto/asn1/asn1_locl.h
+crypto/pkcs7/pk7_doit.o: crypto/pkcs7/pk7_doit.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/rand.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/x509v3.h include/openssl/conf.h
+crypto/dsa/dsa_ossl.o: crypto/dsa/dsa_ossl.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h include/openssl/sha.h crypto/dsa/dsa_locl.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/asn1.h
+crypto/pkcs12/p12_key.o: crypto/pkcs12/p12_key.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/pkcs12.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/bio/b_sock2.o: crypto/bio/b_sock2.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/bio/bio_lcl.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/string.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h include/internal/bio.h
+crypto/asn1/a_utf8.o: crypto/asn1/a_utf8.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1.h include/openssl/bn.h
+crypto/bn/bn_recp.o: crypto/bn/bn_recp.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h
+crypto/engine/tb_eckey.o: crypto/engine/tb_eckey.c \
+ crypto/engine/eng_int.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/engine.h \
+ include/openssl/engine.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/internal/thread_once.h
+crypto/asn1/tasn_prn.o: crypto/asn1/tasn_prn.c \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/asn1t.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/x509v3.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h include/openssl/conf.h \
+ crypto/include/internal/asn1_int.h crypto/asn1/asn1_locl.h
+crypto/o_init.o: crypto/o_init.c e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h \
+ include/openssl/err.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/symhacks.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h
+crypto/asn1/a_bitstr.o: crypto/asn1/a_bitstr.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1.h include/openssl/bn.h crypto/asn1/asn1_locl.h
+crypto/des/fcrypt.o: crypto/des/fcrypt.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/des/des_locl.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/des.h
+crypto/rsa/rsa_prn.o: crypto/rsa/rsa_prn.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/rsa.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h
+crypto/des/ofb64ede.o: crypto/des/ofb64ede.c crypto/des/des_locl.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/des.h
+crypto/bn/bn_mont.o: crypto/bn/bn_mont.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h
+crypto/dh/dh_lib.o: crypto/dh/dh_lib.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h crypto/dh/dh_locl.h include/openssl/dh.h \
+ include/openssl/asn1.h include/openssl/engine.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/ec.h include/openssl/rand.h \
+ include/openssl/ui.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/evp/evp_enc.o: crypto/evp/evp_enc.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/assert.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/rand.h include/openssl/engine.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/ec.h \
+ include/openssl/ui.h include/openssl/x509.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/include/internal/evp_int.h crypto/evp/evp_locl.h
+crypto/ct/ct_sct_ctx.o: crypto/ct/ct_sct_ctx.c \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/strings.h include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/obj_mac.h \
+ include/openssl/x509.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h crypto/ct/ct_locl.h include/openssl/ct.h \
+ include/openssl/x509v3.h include/openssl/conf.h
+crypto/ocsp/v3_ocsp.o: crypto/ocsp/v3_ocsp.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/conf.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ocsp.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/x509v3.h crypto/ocsp/ocsp_lcl.h \
+ crypto/ocsp/../x509v3/ext_dat.h
+crypto/ec/ecp_nistp256.o: crypto/ec/ecp_nistp256.c \
+ include/openssl/opensslconf.h
+crypto/asn1/asn1_gen.o: crypto/asn1/asn1_gen.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/asn1.h \
+ include/openssl/bn.h include/openssl/x509v3.h include/openssl/x509.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/conf.h
+crypto/ec/ec_check.o: crypto/ec/ec_check.c crypto/ec/ec_lcl.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/obj_mac.h include/openssl/ec.h \
+ include/openssl/opensslconf.h include/openssl/asn1.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/bn.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h
+crypto/cast/c_enc.o: crypto/cast/c_enc.c include/openssl/cast.h \
+ include/openssl/opensslconf.h crypto/cast/cast_lcl.h e_os.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h
+crypto/asn1/a_d2i_fp.o: crypto/asn1/a_d2i_fp.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/internal/numbers.h include/openssl/asn1.h include/openssl/bn.h
+crypto/md4/md4_dgst.o: crypto/md4/md4_dgst.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/opensslv.h \
+ crypto/md4/md4_locl.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/opensslconf.h \
+ include/openssl/md4.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stddef.h crypto/include/internal/md32_common.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h
+crypto/o_fopen.o: crypto/o_fopen.c crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h
+crypto/dh/dh_meth.o: crypto/dh/dh_meth.c crypto/dh/dh_locl.h \
+ include/openssl/dh.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/asn1.h include/openssl/bn.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h
+crypto/bn/bn_x931p.o: crypto/bn/bn_x931p.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/bn.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h
+crypto/threads_win.o: crypto/threads_win.c include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h
+crypto/dso/dso_err.o: crypto/dso/dso_err.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/err.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/internal/dso.h
+crypto/ct/ct_err.o: crypto/ct/ct_err.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/err.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/ct.h \
+ include/openssl/x509.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/evp/bio_md.o: crypto/evp/bio_md.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/evp_int.h crypto/evp/evp_locl.h \
+ include/internal/bio.h
+crypto/ec/curve25519.o: crypto/ec/curve25519.c \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/strings.h \
+ crypto/ec/ec_lcl.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/obj_mac.h \
+ include/openssl/ec.h include/openssl/opensslconf.h \
+ include/openssl/asn1.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/bn.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h
+crypto/camellia/cmll_ctr.o: crypto/camellia/cmll_ctr.c \
+ include/openssl/camellia.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/modes.h
+crypto/async/arch/async_null.o: crypto/async/arch/async_null.c \
+ crypto/async/arch/../async_locl.h crypto/include/internal/async.h \
+ include/openssl/async.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/async/arch/../arch/async_win.h \
+ crypto/async/arch/../arch/async_posix.h \
+ crypto/async/arch/../arch/async_null.h
+crypto/pkcs12/pk12err.o: crypto/pkcs12/pk12err.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/symhacks.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/pkcs12.h include/openssl/x509.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/asn1/bio_ndef.o: crypto/asn1/bio_ndef.c include/openssl/asn1.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/bn.h include/openssl/asn1t.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h
+crypto/cms/cms_kari.o: crypto/cms/cms_kari.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/asn1t.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/pem.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/x509.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/pem2.h include/openssl/x509v3.h include/openssl/conf.h \
+ include/openssl/cms.h include/openssl/aes.h crypto/cms/cms_lcl.h \
+ crypto/include/internal/asn1_int.h
+crypto/ec/ec_oct.o: crypto/ec/ec_oct.c ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/strings.h include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/ec/ec_lcl.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/asn1.h \
+ include/openssl/bn.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h
+crypto/ec/ec_cvt.o: crypto/ec/ec_cvt.c include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/ec/ec_lcl.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/asn1.h \
+ include/openssl/bn.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h
+crypto/dsa/dsa_pmeth.o: crypto/dsa/dsa_pmeth.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1t.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/include/internal/evp_int.h crypto/dsa/dsa_locl.h
+crypto/asn1/i2d_pr.o: crypto/asn1/i2d_pr.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/include/internal/asn1_int.h crypto/include/internal/evp_int.h
+crypto/dso/dso_vms.o: crypto/dso/dso_vms.c crypto/dso/dso_locl.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/internal/dso.h crypto/include/internal/dso_conf.h
+crypto/pkcs12/p12_decr.o: crypto/pkcs12/p12_decr.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/pkcs12.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/ct/ct_vfy.o: crypto/ct/ct_vfy.c ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/strings.h include/openssl/ct.h \
+ include/openssl/opensslconf.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/safestack.h \
+ include/openssl/stack.h include/openssl/x509.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ ../musl-1.1.18/include/stdio.h include/openssl/opensslv.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h include/openssl/err.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/ct/ct_locl.h include/openssl/x509v3.h include/openssl/conf.h
+crypto/evp/bio_b64.o: crypto/evp/bio_b64.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/internal/bio.h
+crypto/ocsp/ocsp_lib.o: crypto/ocsp/ocsp_lib.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/x509.h \
+ include/openssl/evp.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h include/openssl/pem.h \
+ include/openssl/pem2.h include/openssl/x509v3.h include/openssl/conf.h \
+ include/openssl/ocsp.h crypto/ocsp/ocsp_lcl.h include/openssl/asn1t.h
+crypto/engine/eng_cnf.o: crypto/engine/eng_cnf.c crypto/engine/eng_int.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/engine.h \
+ include/openssl/engine.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/internal/thread_once.h include/openssl/conf.h
+crypto/rand/randfile.o: crypto/rand/randfile.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/rand.h \
+ ../musl-1.1.18/include/sys/stat.h ../musl-1.1.18/include/bits/stat.h \
+ ../musl-1.1.18/include/fcntl.h ../musl-1.1.18/include/bits/fcntl.h
+crypto/pem/pem_lib.o: crypto/pem/pem_lib.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/ctype.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/evp.h \
+ include/openssl/rand.h include/openssl/x509.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/pem.h include/openssl/pem2.h include/openssl/pkcs12.h \
+ crypto/include/internal/asn1_int.h include/openssl/des.h \
+ include/openssl/engine.h include/openssl/ui.h
+crypto/asn1/p8_pkey.o: crypto/asn1/p8_pkey.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1t.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/include/internal/x509_int.h
+crypto/idea/i_cfb64.o: crypto/idea/i_cfb64.c include/openssl/idea.h \
+ include/openssl/opensslconf.h crypto/idea/idea_lcl.h
+crypto/rand/rand_lib.o: crypto/rand/rand_lib.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/time.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/rand.h \
+ include/openssl/rand.h include/openssl/engine.h include/openssl/bn.h \
+ include/openssl/rsa.h include/openssl/asn1.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/ec.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/des/cfb64enc.o: crypto/des/cfb64enc.c crypto/des/des_locl.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/des.h
+crypto/ec/ecp_mont.o: crypto/ec/ecp_mont.c include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/ec/ec_lcl.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/asn1.h \
+ include/openssl/bn.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h
+crypto/bio/bss_sock.o: crypto/bio/bss_sock.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bio/bio_lcl.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h include/internal/bio.h
+crypto/rsa/rsa_chk.o: crypto/rsa/rsa_chk.c include/openssl/bn.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/err.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/rsa/rsa_locl.h include/openssl/rsa.h include/openssl/asn1.h
+crypto/modes/ctr128.o: crypto/modes/ctr128.c include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/modes/modes_lcl.h \
+ include/openssl/modes.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h
+crypto/des/str2key.o: crypto/des/str2key.c include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/des/des_locl.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/des.h
+crypto/asn1/a_time.o: crypto/asn1/a_time.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/time.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/asn1t.h \
+ include/openssl/asn1.h include/openssl/bn.h crypto/asn1/asn1_locl.h
+crypto/conf/conf_api.o: crypto/conf/conf_api.c \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/conf.h include/openssl/bio.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/lhash.h include/openssl/conf_api.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h
+crypto/sha/sha256.o: crypto/sha/sha256.c include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/sha.h \
+ ../musl-1.1.18/include/stddef.h crypto/include/internal/md32_common.h
+crypto/rsa/rsa_x931.o: crypto/rsa/rsa_x931.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h include/openssl/rsa.h include/openssl/asn1.h \
+ include/openssl/objects.h include/openssl/obj_mac.h
+crypto/hmac/hmac.o: crypto/hmac/hmac.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/hmac.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/hmac/hmac_lcl.h
+crypto/mem_sec.o: crypto/mem_sec.c include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/assert.h \
+ ../musl-1.1.18/include/sys/mman.h ../musl-1.1.18/include/bits/mman.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/sys/stat.h ../musl-1.1.18/include/bits/stat.h \
+ ../musl-1.1.18/include/fcntl.h ../musl-1.1.18/include/bits/fcntl.h
+crypto/evp/p_sign.o: crypto/evp/p_sign.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/include/internal/evp_int.h
+crypto/objects/obj_dat.o: crypto/objects/obj_dat.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/ctype.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/objects.h include/openssl/objects.h \
+ include/openssl/obj_mac.h crypto/include/internal/asn1_int.h \
+ crypto/objects/obj_lcl.h crypto/objects/obj_dat.h
+crypto/dsa/dsa_ameth.o: crypto/dsa/dsa_ameth.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h crypto/dsa/dsa_locl.h include/openssl/cms.h \
+ include/openssl/x509v3.h include/openssl/conf.h \
+ crypto/include/internal/asn1_int.h crypto/include/internal/evp_int.h
+crypto/ocsp/ocsp_vfy.o: crypto/ocsp/ocsp_vfy.c include/openssl/ocsp.h \
+ include/openssl/opensslconf.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/x509.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ ../musl-1.1.18/include/stdio.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h include/openssl/x509v3.h include/openssl/conf.h \
+ crypto/ocsp/ocsp_lcl.h include/openssl/err.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h
+crypto/ec/ecp_nistp521.o: crypto/ec/ecp_nistp521.c \
+ include/openssl/opensslconf.h
+crypto/rsa/rsa_depr.o: crypto/rsa/rsa_depr.c \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/time.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/bn.h \
+ include/openssl/rsa.h include/openssl/asn1.h
+crypto/asn1/a_utctm.o: crypto/asn1/a_utctm.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/time.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/asn1.h \
+ include/openssl/bn.h crypto/asn1/asn1_locl.h
+crypto/idea/i_ecb.o: crypto/idea/i_ecb.c include/openssl/idea.h \
+ include/openssl/opensslconf.h crypto/idea/idea_lcl.h \
+ include/openssl/opensslv.h
+crypto/dsa/dsa_err.o: crypto/dsa/dsa_err.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/err.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/dsa.h \
+ include/openssl/bn.h include/openssl/dh.h include/openssl/asn1.h
+crypto/asn1/a_verify.o: crypto/asn1/a_verify.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/time.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/include/internal/asn1_int.h crypto/include/internal/evp_int.h
+crypto/rand/rand_unix.o: crypto/rand/rand_unix.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/rand.h \
+ crypto/rand/rand_lcl.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/sha.h ../musl-1.1.18/include/sys/times.h \
+ ../musl-1.1.18/include/sys/stat.h ../musl-1.1.18/include/bits/stat.h \
+ ../musl-1.1.18/include/fcntl.h ../musl-1.1.18/include/bits/fcntl.h
+crypto/asn1/x_pkey.o: crypto/asn1/x_pkey.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/asn1/a_object.o: crypto/asn1/a_object.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/objects.h \
+ include/openssl/obj_mac.h crypto/include/internal/asn1_int.h \
+ crypto/asn1/asn1_locl.h
+crypto/mem.o: crypto/mem.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h
+crypto/evp/c_allc.o: crypto/evp/c_allc.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/evp_int.h include/openssl/pkcs12.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/cms/cms_sd.o: crypto/cms/cms_sd.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/asn1t.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/pem.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/x509.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/pem2.h include/openssl/x509v3.h include/openssl/conf.h \
+ include/openssl/cms.h crypto/cms/cms_lcl.h \
+ crypto/include/internal/asn1_int.h crypto/include/internal/evp_int.h
+crypto/rsa/rsa_none.o: crypto/rsa/rsa_none.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/bn.h \
+ include/openssl/rsa.h include/openssl/asn1.h
+crypto/bf/bf_ofb64.o: crypto/bf/bf_ofb64.c include/openssl/blowfish.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h crypto/bf/bf_locl.h
+crypto/des/xcbc_enc.o: crypto/des/xcbc_enc.c crypto/des/des_locl.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/des.h
+crypto/modes/gcm128.o: crypto/modes/gcm128.c include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/modes/modes_lcl.h \
+ include/openssl/modes.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h
+crypto/asn1/a_mbstr.o: crypto/asn1/a_mbstr.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/ctype.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1.h include/openssl/bn.h
+crypto/bn/bn_exp2.o: crypto/bn/bn_exp2.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/bn/bn_lcl.h crypto/include/internal/bn_conf.h \
+ crypto/include/internal/bn_int.h include/openssl/bn.h
+crypto/asn1/asn_mime.o: crypto/asn1/asn_mime.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/ctype.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/rand.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/asn1t.h crypto/include/internal/evp_int.h \
+ include/internal/bio.h crypto/asn1/asn1_locl.h
+crypto/pkcs12/p12_attr.o: crypto/pkcs12/p12_attr.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/pkcs12.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/pkcs12/p12_lcl.h
+crypto/bn/bn_rand.o: crypto/bn/bn_rand.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/time.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h include/openssl/rand.h include/openssl/sha.h
+crypto/asn1/t_spki.o: crypto/asn1/t_spki.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h
+crypto/asn1/a_type.o: crypto/asn1/a_type.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1t.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ crypto/asn1/asn1_locl.h
+crypto/ocsp/ocsp_prn.o: crypto/ocsp/ocsp_prn.c include/openssl/bio.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/ocsp.h include/openssl/x509.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/x509v3.h include/openssl/conf.h crypto/ocsp/ocsp_lcl.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h include/openssl/pem.h \
+ include/openssl/pem2.h
+crypto/rc2/rc2_skey.o: crypto/rc2/rc2_skey.c include/openssl/rc2.h \
+ include/openssl/opensslconf.h crypto/rc2/rc2_locl.h
+crypto/dsa/dsa_prn.o: crypto/dsa/dsa_prn.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/dsa.h include/openssl/dh.h
+crypto/blake2/blake2b.o: crypto/blake2/blake2b.c \
+ ../musl-1.1.18/include/assert.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/strings.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h crypto/blake2/blake2_locl.h \
+ ../musl-1.1.18/include/stddef.h crypto/blake2/blake2_impl.h
+crypto/ec/ec2_mult.o: crypto/ec/ec2_mult.c include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h crypto/ec/ec_lcl.h include/openssl/obj_mac.h \
+ include/openssl/ec.h include/openssl/asn1.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h
+crypto/camellia/cmll_ofb.o: crypto/camellia/cmll_ofb.c \
+ include/openssl/camellia.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/modes.h
+crypto/aes/aes_cbc.o: crypto/aes/aes_cbc.c include/openssl/aes.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/modes.h
+crypto/ec/ec2_oct.o: crypto/ec/ec2_oct.c include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/ec/ec_lcl.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/asn1.h \
+ include/openssl/bn.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h
+crypto/dh/dh_depr.o: crypto/dh/dh_depr.c include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h include/openssl/dh.h include/openssl/asn1.h
+crypto/conf/conf_sap.o: crypto/conf/conf_sap.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/internal/conf.h \
+ include/openssl/conf.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/engine.h include/openssl/rand.h include/openssl/ui.h
+crypto/ts/ts_err.o: crypto/ts/ts_err.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/err.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/ts.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/x509.h \
+ include/openssl/ec.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h include/openssl/x509v3.h include/openssl/conf.h
+crypto/engine/eng_pkey.o: crypto/engine/eng_pkey.c \
+ crypto/engine/eng_int.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/engine.h \
+ include/openssl/engine.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/internal/thread_once.h
+crypto/ex_data.o: crypto/ex_data.c crypto/include/internal/cryptlib_int.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/internal/thread_once.h
+crypto/asn1/a_print.o: crypto/asn1/a_print.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/ctype.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1.h include/openssl/bn.h
+crypto/bio/bio_lib.o: crypto/bio/bio_lib.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/bio/bio_lcl.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/string.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h include/internal/bio.h
+crypto/bn/bn_kron.o: crypto/bn/bn_kron.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h
+crypto/bn/bn_exp.o: crypto/bn/bn_exp.c crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h \
+ include/internal/constant_time_locl.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h crypto/bn/rsaz_exp.h
+crypto/bio/b_print.o: crypto/bio/b_print.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ ../musl-1.1.18/include/ctype.h include/internal/numbers.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h
+crypto/engine/eng_list.o: crypto/engine/eng_list.c \
+ crypto/engine/eng_int.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/engine.h \
+ include/openssl/engine.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/internal/thread_once.h
+crypto/bf/bf_enc.o: crypto/bf/bf_enc.c include/openssl/blowfish.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h crypto/bf/bf_locl.h
+crypto/bn/bn_gcd.o: crypto/bn/bn_gcd.c crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h
+crypto/pem/pem_pkey.o: crypto/pem/pem_pkey.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/evp.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/pkcs12.h include/openssl/pem.h include/openssl/pem2.h \
+ include/openssl/engine.h include/openssl/rand.h include/openssl/ui.h \
+ crypto/include/internal/asn1_int.h crypto/include/internal/evp_int.h
+crypto/asn1/p5_scrypt.o: crypto/asn1/p5_scrypt.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1t.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/x509.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/rand.h
+crypto/rsa/rsa_gen.o: crypto/rsa/rsa_gen.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/time.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/bn.h \
+ crypto/rsa/rsa_locl.h include/openssl/rsa.h include/openssl/asn1.h
+crypto/dh/dh_gen.o: crypto/dh/dh_gen.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h crypto/dh/dh_locl.h include/openssl/dh.h \
+ include/openssl/asn1.h
+crypto/bf/bf_cfb64.o: crypto/bf/bf_cfb64.c include/openssl/blowfish.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h crypto/bf/bf_locl.h
+crypto/ct/ct_oct.o: crypto/ct/ct_oct.c ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/strings.h include/openssl/asn1.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h include/openssl/symhacks.h \
+ include/openssl/bn.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/ct.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h include/openssl/err.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/ct/ct_locl.h include/openssl/x509v3.h include/openssl/conf.h
+crypto/evp/c_alld.o: crypto/evp/c_alld.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/evp_int.h include/openssl/pkcs12.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/o_dir.o: crypto/o_dir.c ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/errno.h \
+ e_os.h include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h \
+ include/internal/o_dir.h crypto/LPdir_unix.c \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/dirent.h
+crypto/evp/m_ripemd.o: crypto/evp/m_ripemd.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/ripemd.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/include/internal/evp_int.h
+crypto/asn1/a_strex.o: crypto/asn1/a_strex.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/include/internal/asn1_int.h include/openssl/x509.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h crypto/asn1/charmap.h
+crypto/asn1/x_spki.o: crypto/asn1/x_spki.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h include/openssl/asn1t.h
+crypto/engine/eng_cryptodev.o: crypto/engine/eng_cryptodev.c \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/bio.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/engine.h include/openssl/engine.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/x509.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/cryptlib.o: crypto/cryptlib.c \
+ crypto/include/internal/cryptlib_int.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h
+crypto/evp/e_cast.o: crypto/evp/e_cast.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/evp_int.h include/openssl/cast.h
+crypto/dsa/dsa_vrf.o: crypto/dsa/dsa_vrf.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/dsa/dsa_locl.h \
+ include/openssl/dsa.h include/openssl/bn.h include/openssl/dh.h \
+ include/openssl/asn1.h
+crypto/asn1/x_info.o: crypto/asn1/x_info.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/md4/md4_one.o: crypto/md4/md4_one.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/md4.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h
+crypto/idea/i_ofb64.o: crypto/idea/i_ofb64.c include/openssl/idea.h \
+ include/openssl/opensslconf.h crypto/idea/idea_lcl.h
+crypto/des/cbc_cksm.o: crypto/des/cbc_cksm.c crypto/des/des_locl.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/des.h
+crypto/bio/bss_acpt.o: crypto/bio/bss_acpt.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bio/bio_lcl.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h include/internal/bio.h
+crypto/rc2/rc2cfb64.o: crypto/rc2/rc2cfb64.c include/openssl/rc2.h \
+ include/openssl/opensslconf.h crypto/rc2/rc2_locl.h
+crypto/asn1/tasn_new.o: crypto/asn1/tasn_new.c \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/asn1.h ../musl-1.1.18/include/time.h \
+ ../musl-1.1.18/include/features.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/bn.h include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1t.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h crypto/asn1/asn1_locl.h
+crypto/pkcs12/p12_kiss.o: crypto/pkcs12/p12_kiss.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/pkcs12.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/bio/b_sock.o: crypto/bio/b_sock.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/bio/bio_lcl.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/string.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h include/internal/bio.h
+crypto/camellia/cmll_misc.o: crypto/camellia/cmll_misc.c \
+ include/openssl/opensslv.h include/openssl/camellia.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/bits/alltypes.h crypto/camellia/cmll_locl.h
+crypto/conf/conf_lib.o: crypto/conf/conf_lib.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/internal/conf.h \
+ include/openssl/conf.h include/openssl/bio.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/lhash.h include/openssl/err.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/conf_api.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h
+crypto/bio/bss_conn.o: crypto/bio/bss_conn.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bio/bio_lcl.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h include/internal/bio.h
+crypto/evp/digest.o: crypto/evp/digest.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/evp.h \
+ include/openssl/engine.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/ec.h include/openssl/rand.h \
+ include/openssl/ui.h include/openssl/x509.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/include/internal/evp_int.h crypto/evp/evp_locl.h
+crypto/evp/scrypt.o: crypto/evp/scrypt.c ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/evp.h \
+ include/openssl/opensslconf.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/symhacks.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/internal/numbers.h
+crypto/evp/pmeth_gn.o: crypto/evp/pmeth_gn.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/evp.h \
+ crypto/include/internal/bn_int.h crypto/include/internal/evp_int.h
+crypto/asn1/evp_asn1.o: crypto/asn1/evp_asn1.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/asn1t.h
+crypto/asn1/a_digest.o: crypto/asn1/a_digest.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/time.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/x509.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h
+crypto/ec/ec_pmeth.o: crypto/ec/ec_pmeth.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1t.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h crypto/ec/ec_lcl.h \
+ crypto/include/internal/evp_int.h
+crypto/engine/eng_table.o: crypto/engine/eng_table.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h crypto/engine/eng_int.h \
+ crypto/include/internal/engine.h include/openssl/engine.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h include/internal/thread_once.h
+crypto/cms/cms_smime.o: crypto/cms/cms_smime.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/asn1t.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/x509.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/x509v3.h include/openssl/conf.h include/openssl/cms.h \
+ crypto/cms/cms_lcl.h crypto/include/internal/asn1_int.h
+crypto/dh/dh_kdf.o: crypto/dh/dh_kdf.c e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h \
+ ../musl-1.1.18/include/string.h include/openssl/dh.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/cms.h include/openssl/x509.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h include/openssl/x509v3.h include/openssl/conf.h
+crypto/dso/dso_dlfcn.o: crypto/dso/dso_dlfcn.c crypto/dso/dso_locl.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/internal/dso.h crypto/include/internal/dso_conf.h
+crypto/dso/dso_dl.o: crypto/dso/dso_dl.c crypto/dso/dso_locl.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/internal/dso.h crypto/include/internal/dso_conf.h
+crypto/bn/bn_asm.o: crypto/bn/bn_asm.c ../musl-1.1.18/include/assert.h \
+ ../musl-1.1.18/include/features.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdio.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h
+crypto/asn1/asn1_err.o: crypto/asn1/asn1_err.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/symhacks.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1.h include/openssl/bn.h
+crypto/ocsp/ocsp_ext.o: crypto/ocsp/ocsp_ext.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/x509.h \
+ include/openssl/evp.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/ocsp.h include/openssl/x509v3.h include/openssl/conf.h \
+ crypto/ocsp/ocsp_lcl.h include/openssl/rand.h
+crypto/ts/ts_rsp_sign.o: crypto/ts/ts_rsp_sign.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h ../musl-1.1.18/include/sys/time.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ts.h \
+ include/openssl/evp.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/x509.h include/openssl/ec.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/x509v3.h include/openssl/conf.h crypto/ts/ts_lcl.h
+crypto/md5/md5_dgst.o: crypto/md5/md5_dgst.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h crypto/md5/md5_locl.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/md5.h ../musl-1.1.18/include/stddef.h \
+ crypto/include/internal/md32_common.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h
+crypto/evp/p5_crpt.o: crypto/evp/p5_crpt.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h
+crypto/camellia/camellia.o: crypto/camellia/camellia.c \
+ include/openssl/camellia.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/camellia/cmll_locl.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/strings.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h
+crypto/cms/cms_att.o: crypto/cms/cms_att.c include/openssl/asn1t.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/asn1.h ../musl-1.1.18/include/time.h \
+ ../musl-1.1.18/include/features.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/bn.h include/openssl/pem.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/x509.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h include/openssl/pem2.h include/openssl/x509v3.h \
+ include/openssl/conf.h include/openssl/err.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/cms.h crypto/cms/cms_lcl.h
+crypto/evp/e_idea.o: crypto/evp/e_idea.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/evp_int.h include/openssl/idea.h
+crypto/pkcs7/pk7_asn1.o: crypto/pkcs7/pk7_asn1.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1t.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/pkcs7.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h
+crypto/evp/e_old.o: crypto/evp/e_old.c include/openssl/opensslconf.h \
+ include/openssl/evp.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/symhacks.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h
+crypto/evp/p_lib.o: crypto/evp/p_lib.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/evp.h include/openssl/x509.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h include/openssl/engine.h include/openssl/rand.h \
+ include/openssl/ui.h crypto/include/internal/asn1_int.h \
+ crypto/include/internal/evp_int.h
+crypto/modes/wrap128.o: crypto/modes/wrap128.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/modes.h
+crypto/pem/pem_xaux.o: crypto/pem/pem_xaux.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h include/openssl/pem.h \
+ include/openssl/pem2.h
+crypto/kdf/kdf_err.o: crypto/kdf/kdf_err.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/err.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/kdf.h
+crypto/evp/m_md5_sha1.o: crypto/evp/m_md5_sha1.c include/openssl/evp.h \
+ include/openssl/opensslconf.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/symhacks.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/x509.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h include/openssl/md5.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h include/openssl/err.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/include/internal/evp_int.h
+crypto/ec/ec_lib.o: crypto/ec/ec_lib.c ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/strings.h include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/ec/ec_lcl.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/asn1.h \
+ include/openssl/bn.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h
+crypto/bio/bss_null.o: crypto/bio/bss_null.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bio/bio_lcl.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h include/internal/bio.h
+crypto/evp/m_sha1.o: crypto/evp/m_sha1.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/sha.h include/openssl/rsa.h \
+ crypto/include/internal/evp_int.h
+crypto/bn/bn_gf2m.o: crypto/bn/bn_gf2m.c ../musl-1.1.18/include/assert.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/bn/bn_lcl.h crypto/include/internal/bn_conf.h \
+ crypto/include/internal/bn_int.h include/openssl/bn.h
+crypto/asn1/a_gentm.o: crypto/asn1/a_gentm.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/time.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/asn1.h \
+ include/openssl/bn.h crypto/asn1/asn1_locl.h
+crypto/rsa/rsa_ameth.o: crypto/rsa/rsa_ameth.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1t.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h include/openssl/cms.h \
+ include/openssl/x509v3.h include/openssl/conf.h \
+ crypto/include/internal/asn1_int.h crypto/include/internal/evp_int.h \
+ crypto/rsa/rsa_locl.h
+crypto/conf/conf_mall.o: crypto/conf/conf_mall.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/conf.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h include/openssl/engine.h include/openssl/rand.h \
+ include/openssl/ui.h
+crypto/evp/p_dec.o: crypto/evp/p_dec.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/rsa.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/x509.h include/openssl/ec.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/dso/dso_lib.o: crypto/dso/dso_lib.c crypto/dso/dso_locl.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/internal/dso.h crypto/include/internal/dso_conf.h
+crypto/bn/bn_err.o: crypto/bn/bn_err.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/err.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/bn.h
+crypto/evp/names.o: crypto/evp/names.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/objects.h include/openssl/x509.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h crypto/include/internal/evp_int.h
+crypto/asn1/f_string.o: crypto/asn1/f_string.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/ctype.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1.h include/openssl/bn.h
+crypto/ct/ct_policy.o: crypto/ct/ct_policy.c include/openssl/ct.h \
+ include/openssl/opensslconf.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/safestack.h \
+ include/openssl/stack.h include/openssl/x509.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ ../musl-1.1.18/include/stdio.h include/openssl/opensslv.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h include/openssl/err.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/ct/ct_locl.h include/openssl/x509v3.h include/openssl/conf.h
+crypto/pkcs12/p12_add.o: crypto/pkcs12/p12_add.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/pkcs12.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/pkcs12/p12_lcl.h
+crypto/ec/ecdh_ossl.o: crypto/ec/ecdh_ossl.c \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/strings.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/bn.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/ec.h crypto/ec/ec_lcl.h
+crypto/rsa/rsa_pk1.o: crypto/rsa/rsa_pk1.c \
+ include/internal/constant_time_locl.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h include/openssl/rsa.h include/openssl/asn1.h \
+ include/openssl/rand.h
+crypto/pkcs12/p12_p8d.o: crypto/pkcs12/p12_p8d.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/pkcs12.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/ebcdic.o: crypto/ebcdic.c include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h
+crypto/evp/e_rc4_hmac_md5.o: crypto/evp/e_rc4_hmac_md5.c \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/evp.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/rc4.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/md5.h crypto/include/internal/evp_int.h
+crypto/modes/ofb128.o: crypto/modes/ofb128.c include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/modes/modes_lcl.h \
+ include/openssl/modes.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h
+crypto/des/cfb_enc.o: crypto/des/cfb_enc.c e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h \
+ crypto/des/des_locl.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h include/openssl/des.h \
+ ../musl-1.1.18/include/assert.h
+crypto/async/async_err.o: crypto/async/async_err.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/symhacks.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/async.h
+crypto/threads_pthread.o: crypto/threads_pthread.c \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdio.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h
+crypto/des/rpc_enc.o: crypto/des/rpc_enc.c crypto/des/rpc_des.h \
+ crypto/des/des_locl.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/des.h
+crypto/asn1/asn1_par.o: crypto/asn1/asn1_par.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h
+crypto/des/qud_cksm.o: crypto/des/qud_cksm.c crypto/des/des_locl.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/des.h
+crypto/dh/dh_check.o: crypto/dh/dh_check.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h crypto/dh/dh_locl.h include/openssl/dh.h \
+ include/openssl/asn1.h
+crypto/asn1/x_algor.o: crypto/asn1/x_algor.c \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/x509.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h include/openssl/asn1t.h \
+ crypto/include/internal/evp_int.h
+crypto/asn1/tasn_fre.o: crypto/asn1/tasn_fre.c \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/asn1.h ../musl-1.1.18/include/time.h \
+ ../musl-1.1.18/include/features.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/bn.h include/openssl/asn1t.h include/openssl/objects.h \
+ include/openssl/obj_mac.h crypto/asn1/asn1_locl.h
+crypto/engine/eng_err.o: crypto/engine/eng_err.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/symhacks.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/engine.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/cms/cms_asn1.o: crypto/cms/cms_asn1.c include/openssl/asn1t.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/asn1.h ../musl-1.1.18/include/time.h \
+ ../musl-1.1.18/include/features.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/bn.h include/openssl/pem.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/x509.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h include/openssl/pem2.h include/openssl/x509v3.h \
+ include/openssl/conf.h include/openssl/cms.h crypto/cms/cms_lcl.h
+crypto/modes/cts128.o: crypto/modes/cts128.c include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/modes/modes_lcl.h \
+ include/openssl/modes.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h
+crypto/ocsp/ocsp_asn.o: crypto/ocsp/ocsp_asn.c include/openssl/asn1.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/bn.h include/openssl/asn1t.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/ocsp.h \
+ include/openssl/x509.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h include/openssl/x509v3.h include/openssl/conf.h \
+ crypto/ocsp/ocsp_lcl.h
+crypto/pkcs12/p12_mutl.o: crypto/pkcs12/p12_mutl.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/hmac.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/rand.h include/openssl/pkcs12.h include/openssl/x509.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h crypto/pkcs12/p12_lcl.h
+crypto/rsa/rsa_lib.o: crypto/rsa/rsa_lib.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h include/openssl/engine.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h crypto/rsa/rsa_locl.h
+crypto/des/set_key.o: crypto/des/set_key.c include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/des/des_locl.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/des.h
+crypto/pkcs7/pkcs7err.o: crypto/pkcs7/pkcs7err.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/symhacks.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/pkcs7.h include/openssl/asn1.h include/openssl/bn.h
+crypto/modes/cfb128.o: crypto/modes/cfb128.c include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/modes/modes_lcl.h \
+ include/openssl/modes.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h
+crypto/rsa/rsa_oaep.o: crypto/rsa/rsa_oaep.c \
+ include/internal/constant_time_locl.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/rand.h \
+ include/openssl/sha.h crypto/rsa/rsa_locl.h include/openssl/rsa.h
+crypto/evp/p5_crpt2.o: crypto/evp/p5_crpt2.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h include/openssl/hmac.h crypto/evp/evp_locl.h
+crypto/asn1/x_bignum.o: crypto/asn1/x_bignum.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1t.h include/openssl/asn1.h include/openssl/bn.h
+crypto/evp/e_des3.o: crypto/evp/e_des3.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/evp_int.h include/openssl/des.h \
+ include/openssl/rand.h crypto/evp/evp_locl.h include/openssl/sha.h
+crypto/stack/stack.o: crypto/stack/stack.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/internal/numbers.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h
+crypto/ec/ecdsa_ossl.o: crypto/ec/ecdsa_ossl.c \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/strings.h \
+ include/openssl/err.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/symhacks.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/obj_mac.h include/openssl/bn.h include/openssl/rand.h \
+ include/openssl/ec.h include/openssl/asn1.h crypto/ec/ec_lcl.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h
+crypto/evp/evp_key.o: crypto/evp/evp_key.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h include/openssl/ui.h
+crypto/asn1/tasn_scn.o: crypto/asn1/tasn_scn.c \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/asn1t.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/x509v3.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h include/openssl/conf.h crypto/asn1/asn1_locl.h
+crypto/asn1/x_val.o: crypto/asn1/x_val.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1t.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/dsa/dsa_key.o: crypto/dsa/dsa_key.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/time.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/bn.h \
+ crypto/dsa/dsa_locl.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/asn1.h
+crypto/objects/o_names.o: crypto/objects/o_names.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/symhacks.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h crypto/objects/obj_lcl.h
+crypto/bn/bn_depr.o: crypto/bn/bn_depr.c include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/time.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h
+crypto/bio/bss_fd.o: crypto/bio/bss_fd.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/bio/bio_lcl.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h include/internal/bio.h
+crypto/dsa/dsa_meth.o: crypto/dsa/dsa_meth.c crypto/dsa/dsa_locl.h \
+ include/openssl/dsa.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/bn.h include/openssl/dh.h include/openssl/asn1.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h
+crypto/pkcs12/p12_npas.o: crypto/pkcs12/p12_npas.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/pem.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/x509.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h include/openssl/pem2.h include/openssl/err.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/pkcs12.h crypto/pkcs12/p12_lcl.h
+crypto/evp/e_rc4.o: crypto/evp/e_rc4.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/rc4.h crypto/include/internal/evp_int.h
+crypto/evp/m_sigver.o: crypto/evp/m_sigver.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/include/internal/evp_int.h crypto/evp/evp_locl.h
+crypto/asn1/a_i2d_fp.o: crypto/asn1/a_i2d_fp.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1.h include/openssl/bn.h
+crypto/comp/c_zlib.o: crypto/comp/c_zlib.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/bio.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/asn1.h include/openssl/bn.h \
+ include/internal/comp.h include/openssl/comp.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h \
+ crypto/include/internal/cryptlib_int.h \
+ crypto/include/internal/cryptlib.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/internal/bio.h \
+ crypto/comp/comp_lcl.h ../zlib-1.2.11/zlib.h ../zlib-1.2.11/zconf.h
+crypto/aes/aes_misc.o: crypto/aes/aes_misc.c include/openssl/opensslv.h \
+ include/openssl/aes.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/aes/aes_locl.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h
+crypto/engine/tb_asnmth.o: crypto/engine/tb_asnmth.c \
+ crypto/engine/eng_int.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/engine.h \
+ include/openssl/engine.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/internal/thread_once.h crypto/include/internal/asn1_int.h
+crypto/pem/pem_err.o: crypto/pem/pem_err.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/err.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/pem.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/pem2.h
+crypto/asn1/bio_asn1.o: crypto/asn1/bio_asn1.c \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/strings.h \
+ include/internal/bio.h include/openssl/bio.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/asn1.h include/openssl/bn.h
+crypto/asn1/asn_pack.o: crypto/asn1/asn_pack.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1.h include/openssl/bn.h
+crypto/rsa/rsa_pss.o: crypto/rsa/rsa_pss.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h include/openssl/rsa.h include/openssl/asn1.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/rand.h include/openssl/sha.h \
+ crypto/rsa/rsa_locl.h
+crypto/ec/ec_kmeth.o: crypto/ec/ec_kmeth.c \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/strings.h \
+ include/openssl/ec.h include/openssl/opensslconf.h \
+ include/openssl/asn1.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/bn.h include/openssl/engine.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/rand.h \
+ include/openssl/ui.h include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/x509.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/ec/ec_lcl.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h
+crypto/ec/ecp_nistp224.o: crypto/ec/ecp_nistp224.c \
+ include/openssl/opensslconf.h
+crypto/des/ofb_enc.o: crypto/des/ofb_enc.c crypto/des/des_locl.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/des.h
+crypto/engine/tb_dsa.o: crypto/engine/tb_dsa.c crypto/engine/eng_int.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/engine.h \
+ include/openssl/engine.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/internal/thread_once.h
+crypto/buffer/buf_err.o: crypto/buffer/buf_err.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/symhacks.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h
+crypto/kdf/tls1_prf.o: crypto/kdf/tls1_prf.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/kdf.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/evp_int.h
+crypto/bn/bn_dh.o: crypto/bn/bn_dh.c crypto/bn/bn_lcl.h \
+ include/openssl/opensslconf.h crypto/include/internal/bn_conf.h \
+ crypto/include/internal/bn_int.h include/openssl/bn.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h \
+ include/openssl/dh.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/asn1.h \
+ crypto/include/internal/bn_dh.h
+crypto/async/async.o: crypto/async/async.c crypto/async/async_locl.h \
+ crypto/include/internal/async.h include/openssl/async.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdio.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ crypto/async/arch/async_win.h crypto/async/arch/async_posix.h \
+ crypto/async/arch/async_null.h include/openssl/err.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h \
+ crypto/include/internal/cryptlib_int.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h
+crypto/camellia/cmll_cbc.o: crypto/camellia/cmll_cbc.c \
+ include/openssl/camellia.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/modes.h
+crypto/conf/conf_def.o: crypto/conf/conf_def.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/conf.h include/openssl/conf_api.h crypto/conf/conf_def.h
+crypto/ocsp/ocsp_srv.o: crypto/ocsp/ocsp_srv.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/x509.h \
+ include/openssl/evp.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h include/openssl/pem.h \
+ include/openssl/pem2.h include/openssl/x509v3.h include/openssl/conf.h \
+ include/openssl/ocsp.h crypto/ocsp/ocsp_lcl.h
+crypto/bio/bio_err.o: crypto/bio/bio_err.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/err.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h
+crypto/asn1/a_strnid.o: crypto/asn1/a_strnid.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/ctype.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/objects.h \
+ include/openssl/obj_mac.h
+crypto/cmac/cm_pmeth.o: crypto/cmac/cm_pmeth.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h include/openssl/x509v3.h include/openssl/conf.h \
+ include/openssl/cmac.h crypto/include/internal/evp_int.h
+crypto/err/err_prn.o: crypto/err/err_prn.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h
+crypto/dsa/dsa_lib.o: crypto/dsa/dsa_lib.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h crypto/dsa/dsa_locl.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/asn1.h include/openssl/engine.h \
+ include/openssl/rsa.h include/openssl/ec.h include/openssl/rand.h \
+ include/openssl/ui.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/des/cfb64ede.o: crypto/des/cfb64ede.c crypto/des/des_locl.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/des.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h
+crypto/seed/seed_cfb.o: crypto/seed/seed_cfb.c include/openssl/seed.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ ../musl-1.1.18/include/stdio.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/modes.h \
+ ../musl-1.1.18/include/stddef.h
+crypto/evp/evp_pkey.o: crypto/evp/evp_pkey.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h include/openssl/rand.h \
+ crypto/include/internal/asn1_int.h crypto/include/internal/evp_int.h \
+ crypto/include/internal/x509_int.h
+crypto/ec/ec_curve.o: crypto/ec/ec_curve.c \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/strings.h \
+ crypto/ec/ec_lcl.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/obj_mac.h \
+ include/openssl/ec.h include/openssl/opensslconf.h \
+ include/openssl/asn1.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/bn.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h
+crypto/ct/ct_prn.o: crypto/ct/ct_prn.c include/openssl/asn1.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/bn.h crypto/ct/ct_locl.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/ct.h include/openssl/x509.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h include/openssl/x509v3.h include/openssl/conf.h
+crypto/evp/m_md4.o: crypto/evp/m_md4.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h include/openssl/md4.h \
+ crypto/include/internal/evp_int.h
+crypto/bn/bn_word.o: crypto/bn/bn_word.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h
+crypto/seed/seed_cbc.o: crypto/seed/seed_cbc.c include/openssl/seed.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ ../musl-1.1.18/include/stdio.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/modes.h \
+ ../musl-1.1.18/include/stddef.h
+crypto/asn1/p5_pbe.o: crypto/asn1/p5_pbe.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1t.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/rand.h
+crypto/aes/aes_ecb.o: crypto/aes/aes_ecb.c \
+ ../musl-1.1.18/include/assert.h ../musl-1.1.18/include/features.h \
+ include/openssl/aes.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/aes/aes_locl.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h
+crypto/engine/eng_rdrand.o: crypto/engine/eng_rdrand.c \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/engine.h include/openssl/engine.h \
+ include/openssl/bn.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/symhacks.h include/openssl/rsa.h include/openssl/asn1.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/ec.h \
+ include/openssl/rand.h include/openssl/ui.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/x509.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/des/rand_key.o: crypto/des/rand_key.c include/openssl/des.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/rand.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h
+crypto/rand/md_rand.o: crypto/rand/md_rand.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/sys/time.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/rand.h \
+ include/openssl/async.h crypto/rand/rand_lcl.h include/openssl/evp.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/sha.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/internal/thread_once.h
+crypto/mdc2/mdc2dgst.o: crypto/mdc2/mdc2dgst.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/des.h include/openssl/mdc2.h
+crypto/engine/tb_digest.o: crypto/engine/tb_digest.c \
+ crypto/engine/eng_int.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/engine.h \
+ include/openssl/engine.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/internal/thread_once.h
+crypto/bn/bn_sqr.o: crypto/bn/bn_sqr.c crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h
+crypto/pkcs12/p12_p8e.o: crypto/pkcs12/p12_p8e.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/pkcs12.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/include/internal/x509_int.h
+crypto/bn/bn_add.o: crypto/bn/bn_add.c crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h
+crypto/evp/bio_ok.o: crypto/evp/bio_ok.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ ../musl-1.1.18/include/assert.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h include/internal/bio.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/rand.h crypto/include/internal/evp_int.h
+crypto/bf/bf_skey.o: crypto/bf/bf_skey.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/blowfish.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h crypto/bf/bf_locl.h \
+ crypto/bf/bf_pi.h
+crypto/err/err.o: crypto/err/err.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/stdarg.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h crypto/include/internal/cryptlib_int.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/internal/err.h crypto/include/internal/err_int.h \
+ include/internal/thread_once.h
+crypto/comp/comp_lib.o: crypto/comp/comp_lib.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/bio.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/comp.h crypto/comp/comp_lcl.h
+crypto/asn1/tasn_typ.o: crypto/asn1/tasn_typ.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/asn1.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/bn.h include/openssl/asn1t.h \
+ ../musl-1.1.18/include/stddef.h
+crypto/rc2/rc2_ecb.o: crypto/rc2/rc2_ecb.c include/openssl/rc2.h \
+ include/openssl/opensslconf.h crypto/rc2/rc2_locl.h \
+ include/openssl/opensslv.h
+crypto/dh/dh_prn.o: crypto/dh/dh_prn.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/dh.h
+crypto/cms/cms_env.o: crypto/cms/cms_env.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/asn1t.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/pem.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/x509.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/pem2.h include/openssl/x509v3.h include/openssl/conf.h \
+ include/openssl/cms.h include/openssl/aes.h crypto/cms/cms_lcl.h \
+ crypto/include/internal/asn1_int.h crypto/include/internal/evp_int.h
+crypto/cms/cms_ess.o: crypto/cms/cms_ess.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/asn1t.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/pem.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/x509.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/pem2.h include/openssl/rand.h include/openssl/x509v3.h \
+ include/openssl/conf.h include/openssl/cms.h crypto/cms/cms_lcl.h
+crypto/cast/c_ofb64.o: crypto/cast/c_ofb64.c include/openssl/cast.h \
+ include/openssl/opensslconf.h crypto/cast/cast_lcl.h e_os.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h
+crypto/bio/bf_nbio.o: crypto/bio/bf_nbio.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/bio/bio_lcl.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h include/internal/bio.h include/openssl/rand.h
+crypto/dsa/dsa_gen.o: crypto/dsa/dsa_gen.c include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/rand.h include/openssl/sha.h crypto/dsa/dsa_locl.h \
+ include/openssl/dsa.h include/openssl/dh.h
+crypto/bn/bn_nist.o: crypto/bn/bn_nist.c crypto/bn/bn_lcl.h \
+ include/openssl/opensslconf.h crypto/include/internal/bn_conf.h \
+ crypto/include/internal/bn_int.h include/openssl/bn.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h
+crypto/chacha/chacha_enc.o: crypto/chacha/chacha_enc.c \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/chacha.h ../musl-1.1.18/include/stddef.h
+crypto/engine/tb_cipher.o: crypto/engine/tb_cipher.c \
+ crypto/engine/eng_int.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/engine.h \
+ include/openssl/engine.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/internal/thread_once.h
+crypto/evp/m_md2.o: crypto/evp/m_md2.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h
+crypto/cms/cms_cd.o: crypto/cms/cms_cd.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/asn1t.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/pem.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/x509.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/pem2.h include/openssl/x509v3.h include/openssl/conf.h \
+ include/openssl/cms.h include/openssl/comp.h crypto/cms/cms_lcl.h
+crypto/engine/eng_dyn.o: crypto/engine/eng_dyn.c crypto/engine/eng_int.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/engine.h \
+ include/openssl/engine.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/internal/thread_once.h include/internal/dso.h
+crypto/asn1/a_dup.o: crypto/asn1/a_dup.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1.h include/openssl/bn.h
+crypto/evp/e_des.o: crypto/evp/e_des.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/evp_int.h include/openssl/des.h \
+ include/openssl/rand.h
+crypto/cmac/cmac.o: crypto/cmac/cmac.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/cmac.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h
+crypto/bn/bn_mod.o: crypto/bn/bn_mod.c crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h
+crypto/rsa/rsa_sign.o: crypto/rsa/rsa_sign.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h include/openssl/rsa.h include/openssl/asn1.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/ec.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/include/internal/x509_int.h crypto/rsa/rsa_locl.h
+crypto/des/ecb3_enc.o: crypto/des/ecb3_enc.c crypto/des/des_locl.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/des.h
+crypto/blake2/m_blake2b.o: crypto/blake2/m_blake2b.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h crypto/blake2/blake2_locl.h \
+ crypto/include/internal/evp_int.h
+crypto/o_fips.o: crypto/o_fips.c crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h
+crypto/bio/b_addr.o: crypto/bio/b_addr.c ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/strings.h crypto/bio/bio_lcl.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/internal/bio.h \
+ include/internal/thread_once.h ../musl-1.1.18/include/ctype.h
+crypto/rsa/rsa_ossl.o: crypto/rsa/rsa_ossl.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h crypto/rsa/rsa_locl.h include/openssl/rsa.h \
+ include/openssl/asn1.h
+crypto/rsa/rsa_err.o: crypto/rsa/rsa_err.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/err.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/bn.h
+crypto/ec/ec2_smpl.o: crypto/ec/ec2_smpl.c include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h crypto/ec/ec_lcl.h include/openssl/obj_mac.h \
+ include/openssl/ec.h include/openssl/asn1.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h
+crypto/ocsp/ocsp_ht.o: crypto/ocsp/ocsp_ht.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/ctype.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/asn1.h \
+ ../musl-1.1.18/include/time.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/bn.h include/openssl/ocsp.h \
+ include/openssl/x509.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h include/openssl/x509v3.h include/openssl/conf.h \
+ include/openssl/err.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h
+crypto/engine/eng_lib.o: crypto/engine/eng_lib.c crypto/engine/eng_int.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/engine.h \
+ include/openssl/engine.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/internal/thread_once.h
+crypto/modes/cbc128.o: crypto/modes/cbc128.c include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/modes/modes_lcl.h \
+ include/openssl/modes.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h
+crypto/rsa/rsa_saos.o: crypto/rsa/rsa_saos.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h include/openssl/rsa.h include/openssl/asn1.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/ec.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/bn/bn_blind.o: crypto/bn/bn_blind.c include/openssl/opensslconf.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h
+crypto/pkcs12/p12_crt.o: crypto/pkcs12/p12_crt.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/pkcs12.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/pkcs12/p12_lcl.h
+crypto/cpt_err.o: crypto/cpt_err.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/err.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h
+crypto/bio/bss_mem.o: crypto/bio/bss_mem.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/bio/bio_lcl.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h include/internal/bio.h
+crypto/bn/bn_intern.o: crypto/bn/bn_intern.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h
+crypto/rand/rand_win.o: crypto/rand/rand_win.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/rand.h \
+ crypto/rand/rand_lcl.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/sha.h
+crypto/idea/i_cbc.o: crypto/idea/i_cbc.c include/openssl/idea.h \
+ include/openssl/opensslconf.h crypto/idea/idea_lcl.h
+crypto/bn/bn_ctx.o: crypto/bn/bn_ctx.c crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h
+crypto/bio/bio_cb.o: crypto/bio/bio_cb.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ crypto/bio/bio_lcl.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h \
+ crypto/include/internal/cryptlib.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/internal/bio.h
+crypto/asn1/t_pkey.o: crypto/asn1/t_pkey.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/bn_int.h
+crypto/bio/bf_null.o: crypto/bio/bf_null.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/bio/bio_lcl.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h include/internal/bio.h
+crypto/cast/c_ecb.o: crypto/cast/c_ecb.c include/openssl/cast.h \
+ include/openssl/opensslconf.h crypto/cast/cast_lcl.h e_os.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h \
+ include/openssl/opensslv.h
+crypto/pkcs12/p12_sbag.o: crypto/pkcs12/p12_sbag.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/pkcs12.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/pkcs12/p12_lcl.h
+crypto/bio/bss_bio.o: crypto/bio/bss_bio.c \
+ ../musl-1.1.18/include/assert.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h crypto/bio/bio_lcl.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h \
+ crypto/include/internal/cryptlib.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/internal/bio.h
+crypto/ec/ec_mult.o: crypto/ec/ec_mult.c ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/strings.h include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/cryptlib.h \
+ e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h crypto/ec/ec_lcl.h include/openssl/obj_mac.h \
+ include/openssl/ec.h include/openssl/asn1.h
+crypto/evp/e_null.o: crypto/evp/e_null.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/evp_int.h
+crypto/ts/ts_req_utils.o: crypto/ts/ts_req_utils.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/x509v3.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/conf.h include/openssl/ts.h crypto/ts/ts_lcl.h
+crypto/pkcs7/bio_pk7.o: crypto/pkcs7/bio_pk7.c include/openssl/asn1.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/bn.h include/openssl/pkcs7.h \
+ ../musl-1.1.18/include/memory.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h
+crypto/engine/tb_rand.o: crypto/engine/tb_rand.c crypto/engine/eng_int.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/engine.h \
+ include/openssl/engine.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/internal/thread_once.h
+crypto/pem/pem_info.o: crypto/pem/pem_info.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/evp.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h include/openssl/pem.h \
+ include/openssl/pem2.h
+crypto/dso/dso_openssl.o: crypto/dso/dso_openssl.c crypto/dso/dso_locl.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/internal/dso.h crypto/include/internal/dso_conf.h
+crypto/async/arch/async_posix.o: crypto/async/arch/async_posix.c \
+ crypto/async/arch/../async_locl.h crypto/include/internal/async.h \
+ include/openssl/async.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/async/arch/../arch/async_win.h \
+ crypto/async/arch/../arch/async_posix.h \
+ crypto/async/arch/../arch/async_null.h
+crypto/conf/conf_mod.o: crypto/conf/conf_mod.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/ctype.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/internal/conf.h \
+ include/openssl/conf.h include/internal/dso.h include/openssl/x509.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h
+crypto/err/err_all.o: crypto/err/err_all.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/err_int.h include/openssl/asn1.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/comp.h \
+ include/openssl/rsa.h include/openssl/dh.h include/openssl/dsa.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/pem2.h include/openssl/x509.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h include/openssl/x509v3.h include/openssl/conf.h \
+ include/openssl/pkcs12.h include/openssl/rand.h include/internal/dso.h \
+ include/openssl/engine.h include/openssl/ui.h include/openssl/err.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/ocsp.h include/openssl/ts.h include/openssl/cms.h \
+ include/openssl/ct.h include/openssl/async.h include/openssl/kdf.h
+crypto/dsa/dsa_sign.o: crypto/dsa/dsa_sign.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/dsa/dsa_locl.h \
+ include/openssl/dsa.h include/openssl/bn.h include/openssl/dh.h \
+ include/openssl/asn1.h
+crypto/des/ofb64enc.o: crypto/des/ofb64enc.c crypto/des/des_locl.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/des.h
+crypto/pkcs12/p12_utl.o: crypto/pkcs12/p12_utl.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/pkcs12.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/ct/ct_x509v3.o: crypto/ct/ct_x509v3.c crypto/ct/ct_locl.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/ct.h include/openssl/opensslconf.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/safestack.h \
+ include/openssl/stack.h include/openssl/x509.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ ../musl-1.1.18/include/stdio.h include/openssl/opensslv.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h include/openssl/x509v3.h include/openssl/conf.h
+crypto/modes/ccm128.o: crypto/modes/ccm128.c include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/modes/modes_lcl.h \
+ include/openssl/modes.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h
+crypto/evp/pmeth_fn.o: crypto/evp/pmeth_fn.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/evp.h \
+ crypto/include/internal/evp_int.h
+crypto/evp/evp_err.o: crypto/evp/evp_err.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/err.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h
+crypto/asn1/i2d_pu.o: crypto/asn1/i2d_pu.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/ec.h
+crypto/asn1/a_sign.o: crypto/asn1/a_sign.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/time.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/bn.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/x509.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h crypto/include/internal/asn1_int.h \
+ crypto/include/internal/evp_int.h
+crypto/srp/srp_vfy.o: crypto/srp/srp_vfy.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/sha.h \
+ include/openssl/srp.h include/openssl/bn.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/rand.h include/openssl/txt_db.h
+crypto/engine/tb_rsa.o: crypto/engine/tb_rsa.c crypto/engine/eng_int.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/engine.h \
+ include/openssl/engine.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/internal/thread_once.h
+crypto/modes/ocb128.o: crypto/modes/ocb128.c \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/strings.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdio.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ crypto/modes/modes_lcl.h include/openssl/modes.h \
+ ../musl-1.1.18/include/stddef.h
+crypto/buffer/buffer.o: crypto/buffer/buffer.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h
+crypto/ct/ct_log.o: crypto/ct/ct_log.c ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/conf.h \
+ include/openssl/bio.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/lhash.h include/openssl/ct.h include/openssl/x509.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/err.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/cryptlib.h \
+ e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h
+crypto/rand/rand_err.o: crypto/rand/rand_err.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/symhacks.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/rand.h
+crypto/bn/bn_prime.o: crypto/bn/bn_prime.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/time.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h crypto/bn/bn_prime.h
+crypto/evp/p_enc.o: crypto/evp/p_enc.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/rsa.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/x509.h include/openssl/ec.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/hmac/hm_ameth.o: crypto/hmac/hm_ameth.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/asn1_int.h
+crypto/comp/comp_err.o: crypto/comp/comp_err.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/symhacks.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/comp.h
+crypto/evp/m_md5.o: crypto/evp/m_md5.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h include/openssl/md5.h \
+ crypto/include/internal/evp_int.h
+crypto/bio/bss_file.o: crypto/bio/bss_file.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bio/bio_lcl.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h include/internal/bio.h
+crypto/cms/cms_lib.o: crypto/cms/cms_lib.c include/openssl/asn1t.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/asn1.h ../musl-1.1.18/include/time.h \
+ ../musl-1.1.18/include/features.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/bn.h include/openssl/x509v3.h include/openssl/x509.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h include/openssl/conf.h include/openssl/err.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/pem.h include/openssl/pem2.h include/openssl/cms.h \
+ crypto/cms/cms_lcl.h
+crypto/cms/cms_enc.o: crypto/cms/cms_enc.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/asn1t.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/pem.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/x509.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/pem2.h include/openssl/x509v3.h include/openssl/conf.h \
+ include/openssl/cms.h include/openssl/rand.h crypto/cms/cms_lcl.h
+crypto/engine/tb_pkmeth.o: crypto/engine/tb_pkmeth.c \
+ crypto/engine/eng_int.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/engine.h \
+ include/openssl/engine.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/internal/thread_once.h
+crypto/evp/p_verify.o: crypto/evp/p_verify.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/include/internal/evp_int.h
+crypto/rc4/rc4_skey.o: crypto/rc4/rc4_skey.c include/openssl/rc4.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/bits/alltypes.h crypto/rc4/rc4_locl.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h
+crypto/async/arch/async_win.o: crypto/async/arch/async_win.c \
+ crypto/async/arch/../async_locl.h crypto/include/internal/async.h \
+ include/openssl/async.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/async/arch/../arch/async_win.h \
+ crypto/async/arch/../arch/async_posix.h \
+ crypto/async/arch/../arch/async_null.h
+crypto/o_time.o: crypto/o_time.c include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/strings.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ ../musl-1.1.18/include/stdio.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h
+crypto/asn1/ameth_lib.o: crypto/asn1/ameth_lib.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1t.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/engine.h include/openssl/rand.h include/openssl/ui.h \
+ crypto/include/internal/asn1_int.h crypto/include/internal/evp_int.h
+crypto/blake2/blake2s.o: crypto/blake2/blake2s.c \
+ ../musl-1.1.18/include/assert.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/strings.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h crypto/blake2/blake2_locl.h \
+ ../musl-1.1.18/include/stddef.h crypto/blake2/blake2_impl.h
+crypto/evp/p_seal.o: crypto/evp/p_seal.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/rand.h include/openssl/rsa.h include/openssl/asn1.h \
+ include/openssl/bn.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/x509.h include/openssl/ec.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/rc2/rc2_cbc.o: crypto/rc2/rc2_cbc.c include/openssl/rc2.h \
+ include/openssl/opensslconf.h crypto/rc2/rc2_locl.h
+crypto/bio/b_dump.o: crypto/bio/b_dump.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/bio/bio_lcl.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/internal/bio.h
+crypto/evp/m_wp.o: crypto/evp/m_wp.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/whrlpool.h crypto/include/internal/evp_int.h
+crypto/bn/bn_mpi.o: crypto/bn/bn_mpi.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/bn/bn_lcl.h crypto/include/internal/bn_conf.h \
+ crypto/include/internal/bn_int.h include/openssl/bn.h
+crypto/engine/eng_openssl.o: crypto/engine/eng_openssl.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/engine.h \
+ include/openssl/engine.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h include/openssl/pem.h \
+ include/openssl/pem2.h include/openssl/hmac.h include/openssl/x509v3.h \
+ include/openssl/conf.h include/openssl/rc4.h
+crypto/objects/obj_err.o: crypto/objects/obj_err.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/symhacks.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h
+crypto/dsa/dsa_asn1.o: crypto/dsa/dsa_asn1.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/dsa/dsa_locl.h include/openssl/dsa.h include/openssl/bn.h \
+ include/openssl/dh.h include/openssl/asn1.h include/openssl/asn1t.h \
+ include/openssl/rand.h
+crypto/evp/pmeth_lib.o: crypto/evp/pmeth_lib.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/engine.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/x509v3.h include/openssl/conf.h \
+ crypto/include/internal/asn1_int.h crypto/include/internal/evp_int.h \
+ include/internal/numbers.h
+crypto/asn1/t_bitst.o: crypto/asn1/t_bitst.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/conf.h include/openssl/x509v3.h include/openssl/x509.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h
+crypto/conf/conf_err.o: crypto/conf/conf_err.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/symhacks.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/conf.h
+crypto/bio/bss_dgram.o: crypto/bio/bss_dgram.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bio/bio_lcl.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h include/internal/bio.h
+crypto/evp/e_chacha20_poly1305.o: crypto/evp/e_chacha20_poly1305.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/evp/evp_locl.h crypto/include/internal/evp_int.h \
+ crypto/include/internal/chacha.h crypto/include/internal/poly1305.h
+crypto/ec/ecp_nistputil.o: crypto/ec/ecp_nistputil.c \
+ include/openssl/opensslconf.h
+crypto/ripemd/rmd_one.o: crypto/ripemd/rmd_one.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/ripemd.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h
+crypto/evp/e_seed.o: crypto/evp/e_seed.c include/openssl/opensslconf.h \
+ include/openssl/evp.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/symhacks.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h ../musl-1.1.18/include/assert.h \
+ include/openssl/seed.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h crypto/include/internal/evp_int.h
+crypto/cms/cms_pwri.o: crypto/cms/cms_pwri.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/asn1t.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/pem.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/x509.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/pem2.h include/openssl/x509v3.h include/openssl/conf.h \
+ include/openssl/cms.h include/openssl/rand.h include/openssl/aes.h \
+ crypto/cms/cms_lcl.h crypto/include/internal/asn1_int.h
+crypto/cast/c_skey.o: crypto/cast/c_skey.c include/openssl/cast.h \
+ include/openssl/opensslconf.h crypto/cast/cast_lcl.h e_os.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h \
+ crypto/cast/cast_s.h
+crypto/dh/dh_asn1.o: crypto/dh/dh_asn1.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h crypto/dh/dh_locl.h include/openssl/dh.h \
+ include/openssl/asn1.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1t.h
+crypto/rsa/rsa_null.o: crypto/rsa/rsa_null.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h crypto/rsa/rsa_locl.h include/openssl/rsa.h \
+ include/openssl/asn1.h
+crypto/ec/ec_print.o: crypto/ec/ec_print.c include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/ec/ec_lcl.h include/openssl/obj_mac.h \
+ include/openssl/ec.h include/openssl/asn1.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/bn.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h
+crypto/evp/cmeth_lib.o: crypto/evp/cmeth_lib.c \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/strings.h \
+ include/openssl/evp.h include/openssl/opensslconf.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/symhacks.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/evp_int.h crypto/evp/evp_locl.h
+crypto/bn/bn_print.o: crypto/bn/bn_print.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/ctype.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/bn/bn_lcl.h crypto/include/internal/bn_conf.h \
+ crypto/include/internal/bn_int.h include/openssl/bn.h
+crypto/dh/dh_rfc5114.o: crypto/dh/dh_rfc5114.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/dh/dh_locl.h include/openssl/dh.h include/openssl/asn1.h \
+ include/openssl/bn.h crypto/include/internal/bn_dh.h
+crypto/camellia/cmll_ecb.o: crypto/camellia/cmll_ecb.c \
+ include/openssl/camellia.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/camellia/cmll_locl.h
+crypto/camellia/cmll_cfb.o: crypto/camellia/cmll_cfb.c \
+ include/openssl/camellia.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/modes.h
+crypto/asn1/x_long.o: crypto/asn1/x_long.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1t.h include/openssl/asn1.h include/openssl/bn.h
+crypto/ts/ts_conf.o: crypto/ts/ts_conf.c ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/strings.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/include/internal/cryptlib.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/pem.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/pem2.h include/openssl/engine.h include/openssl/rand.h \
+ include/openssl/ui.h include/openssl/ts.h include/openssl/x509v3.h \
+ include/openssl/conf.h
+crypto/pem/pem_oth.o: crypto/pem/pem_oth.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/evp.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h include/openssl/pem.h \
+ include/openssl/pem2.h
+crypto/bn/bn_mul.o: crypto/bn/bn_mul.c ../musl-1.1.18/include/assert.h \
+ ../musl-1.1.18/include/features.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h
+crypto/evp/evp_cnf.o: crypto/evp/evp_cnf.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/ctype.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/conf.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h include/openssl/x509v3.h
+crypto/bn/bn_sqrt.o: crypto/bn/bn_sqrt.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h
+crypto/ocsp/ocsp_cl.o: crypto/ocsp/ocsp_cl.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/time.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/pem.h include/openssl/pem2.h include/openssl/x509v3.h \
+ include/openssl/conf.h include/openssl/ocsp.h crypto/ocsp/ocsp_lcl.h
+crypto/rand/rand_egd.o: crypto/rand/rand_egd.c \
+ include/openssl/opensslconf.h
+crypto/asn1/n_pkey.o: crypto/asn1/n_pkey.c include/openssl/opensslconf.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1t.h include/openssl/evp.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h
+crypto/rsa/rsa_x931g.o: crypto/rsa/rsa_x931g.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h ../musl-1.1.18/include/time.h \
+ include/openssl/err.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/symhacks.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h crypto/rsa/rsa_locl.h include/openssl/rsa.h \
+ include/openssl/asn1.h
+crypto/asn1/asn_mstbl.o: crypto/asn1/asn_mstbl.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/ctype.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/conf.h \
+ include/openssl/x509v3.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/engine/tb_dh.o: crypto/engine/tb_dh.c crypto/engine/eng_int.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/engine.h \
+ include/openssl/engine.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/internal/thread_once.h
+crypto/sha/sha1_one.o: crypto/sha/sha1_one.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/sha.h ../musl-1.1.18/include/stddef.h
+crypto/evp/p_open.o: crypto/evp/p_open.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/x509.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h
+crypto/aes/aes_wrap.o: crypto/aes/aes_wrap.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/aes.h \
+ include/openssl/modes.h
+crypto/evp/e_rc5.o: crypto/evp/e_rc5.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h
+crypto/ec/eck_prn.o: crypto/ec/eck_prn.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h
+crypto/bn/bn_const.o: crypto/bn/bn_const.c include/openssl/bn.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h
+crypto/poly1305/poly1305.o: crypto/poly1305/poly1305.c \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdio.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ crypto/include/internal/poly1305.h ../musl-1.1.18/include/stddef.h
+crypto/evp/e_xcbc_d.o: crypto/evp/e_xcbc_d.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/evp_int.h include/openssl/des.h
+crypto/evp/e_aes.o: crypto/evp/e_aes.c include/openssl/opensslconf.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/evp.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ ../musl-1.1.18/include/assert.h include/openssl/aes.h \
+ ../musl-1.1.18/include/stddef.h crypto/include/internal/evp_int.h \
+ crypto/modes/modes_lcl.h include/openssl/modes.h include/openssl/rand.h \
+ crypto/evp/evp_locl.h
+crypto/ec/ec_asn1.o: crypto/ec/ec_asn1.c ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/strings.h crypto/ec/ec_lcl.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/obj_mac.h include/openssl/ec.h \
+ include/openssl/opensslconf.h include/openssl/asn1.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/bn.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/asn1t.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/objects.h
+crypto/ec/ecx_meth.o: crypto/ec/ecx_meth.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h include/openssl/rand.h \
+ crypto/include/internal/asn1_int.h crypto/include/internal/evp_int.h \
+ crypto/ec/ec_lcl.h
+crypto/pem/pem_all.o: crypto/pem/pem_all.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h include/openssl/pem.h \
+ include/openssl/pem2.h
+crypto/dh/dh_ameth.o: crypto/dh/dh_ameth.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h crypto/dh/dh_locl.h \
+ crypto/include/internal/asn1_int.h crypto/include/internal/evp_int.h \
+ include/openssl/cms.h include/openssl/x509v3.h include/openssl/conf.h
+crypto/pkcs12/p12_crpt.o: crypto/pkcs12/p12_crpt.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/pkcs12.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/ec/ec_ameth.o: crypto/ec/ec_ameth.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h include/openssl/cms.h include/openssl/x509v3.h \
+ include/openssl/conf.h include/openssl/asn1t.h \
+ crypto/include/internal/asn1_int.h crypto/include/internal/evp_int.h \
+ crypto/ec/ec_lcl.h
+crypto/dsa/dsa_depr.o: crypto/dsa/dsa_depr.c \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/time.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h
+crypto/asn1/a_octet.o: crypto/asn1/a_octet.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1.h include/openssl/bn.h
+crypto/asn1/f_int.o: crypto/asn1/f_int.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/ctype.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1.h include/openssl/bn.h
+crypto/rsa/rsa_crpt.o: crypto/rsa/rsa_crpt.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h include/openssl/rand.h crypto/rsa/rsa_locl.h \
+ include/openssl/rsa.h include/openssl/asn1.h
+crypto/evp/evp_pbe.o: crypto/evp/evp_pbe.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/pkcs12.h include/openssl/x509.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/evp/evp_locl.h
+crypto/ct/ct_b64.o: crypto/ct/ct_b64.c ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/strings.h include/openssl/ct.h \
+ include/openssl/opensslconf.h include/openssl/ossl_typ.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/safestack.h \
+ include/openssl/stack.h include/openssl/x509.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ ../musl-1.1.18/include/stdio.h include/openssl/opensslv.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h include/openssl/err.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/ct/ct_locl.h include/openssl/x509v3.h include/openssl/conf.h
+crypto/blake2/m_blake2s.o: crypto/blake2/m_blake2s.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h crypto/blake2/blake2_locl.h \
+ crypto/include/internal/evp_int.h
+crypto/evp/m_null.o: crypto/evp/m_null.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/include/internal/evp_int.h
+crypto/ripemd/rmd_dgst.o: crypto/ripemd/rmd_dgst.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h crypto/ripemd/rmd_locl.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/opensslconf.h include/openssl/ripemd.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stddef.h \
+ crypto/include/internal/md32_common.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ crypto/ripemd/rmdconst.h
+crypto/asn1/nsseq.o: crypto/asn1/nsseq.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/asn1t.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/asn1.h ../musl-1.1.18/include/time.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/bn.h include/openssl/x509.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h
+crypto/pem/pem_pk8.o: crypto/pem/pem_pk8.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/evp.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/pkcs12.h include/openssl/pem.h include/openssl/pem2.h
+crypto/pkcs7/pk7_attr.o: crypto/pkcs7/pk7_attr.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/bio.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/asn1t.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/pem.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/x509.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h include/openssl/pem2.h include/openssl/err.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h
+crypto/asn1/asn1_lib.o: crypto/asn1/asn1_lib.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1.h include/openssl/bn.h crypto/asn1/asn1_locl.h
+crypto/ec/ecp_oct.o: crypto/ec/ecp_oct.c include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/ec/ec_lcl.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/asn1.h \
+ include/openssl/bn.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h
+crypto/bn/bn_lib.o: crypto/bn/bn_lib.c ../musl-1.1.18/include/assert.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/bn/bn_lcl.h \
+ crypto/include/internal/bn_conf.h crypto/include/internal/bn_int.h \
+ include/openssl/bn.h
+crypto/dh/dh_pmeth.o: crypto/dh/dh_pmeth.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1t.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h crypto/dh/dh_locl.h \
+ crypto/include/internal/evp_int.h
+crypto/mem_dbg.o: crypto/mem_dbg.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/internal/thread_once.h \
+ include/internal/bio.h
+crypto/rc2/rc2ofb64.o: crypto/rc2/rc2ofb64.c include/openssl/rc2.h \
+ include/openssl/opensslconf.h crypto/rc2/rc2_locl.h
+crypto/bio/bss_log.o: crypto/bio/bss_log.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/bio/bio_lcl.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h include/internal/bio.h \
+ ../musl-1.1.18/include/syslog.h
+crypto/cversion.o: crypto/cversion.c crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/buildinf.h
+crypto/cms/cms_io.o: crypto/cms/cms_io.c include/openssl/asn1t.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/asn1.h ../musl-1.1.18/include/time.h \
+ ../musl-1.1.18/include/features.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/bn.h include/openssl/x509.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h include/openssl/err.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/pem.h include/openssl/pem2.h include/openssl/cms.h \
+ include/openssl/x509v3.h include/openssl/conf.h crypto/cms/cms_lcl.h
+crypto/ec/ecdsa_sign.o: crypto/ec/ecdsa_sign.c include/openssl/ec.h \
+ include/openssl/opensslconf.h include/openssl/asn1.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/bn.h crypto/ec/ec_lcl.h \
+ include/openssl/obj_mac.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h
+crypto/ct/ct_sct.o: crypto/ct/ct_sct.c include/openssl/ct.h \
+ include/openssl/opensslconf.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/safestack.h \
+ include/openssl/stack.h include/openssl/x509.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ ../musl-1.1.18/include/stdio.h include/openssl/opensslv.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/lhash.h \
+ include/openssl/pkcs7.h include/openssl/err.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/tls1.h crypto/ct/ct_locl.h include/openssl/x509v3.h \
+ include/openssl/conf.h
+crypto/des/fcrypt_b.o: crypto/des/fcrypt_b.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h crypto/des/des_locl.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/des.h
+crypto/des/pcbc_enc.o: crypto/des/pcbc_enc.c crypto/des/des_locl.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/des.h
+crypto/lhash/lhash.o: crypto/lhash/lhash.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/lhash.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h crypto/lhash/lhash_lcl.h
+crypto/rsa/rsa_meth.o: crypto/rsa/rsa_meth.c \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/strings.h \
+ crypto/rsa/rsa_locl.h include/openssl/rsa.h \
+ include/openssl/opensslconf.h include/openssl/asn1.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/bn.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h
+crypto/ec/ecp_nist.o: crypto/ec/ecp_nist.c \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/ossl_typ.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/symhacks.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/obj_mac.h crypto/ec/ec_lcl.h include/openssl/ec.h \
+ include/openssl/asn1.h include/openssl/bn.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h
+crypto/ts/ts_lib.o: crypto/ts/ts_lib.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/x509.h \
+ include/openssl/evp.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/x509v3.h include/openssl/conf.h include/openssl/ts.h \
+ crypto/ts/ts_lcl.h
+crypto/ec/ecp_smpl.o: crypto/ec/ecp_smpl.c include/openssl/err.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/ec/ec_lcl.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/asn1.h \
+ include/openssl/bn.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h
+crypto/bio/bio_meth.o: crypto/bio/bio_meth.c crypto/bio/bio_lcl.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ ../musl-1.1.18/include/stdio.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/internal/bio.h include/internal/thread_once.h
+crypto/pem/pvkfmt.o: crypto/pem/pvkfmt.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/pem.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/pem2.h include/openssl/rand.h
+crypto/ec/ec_key.o: crypto/ec/ec_key.c crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/ec/ec_lcl.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/asn1.h \
+ include/openssl/bn.h include/openssl/engine.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/rand.h \
+ include/openssl/ui.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h
+crypto/asn1/tasn_dec.o: crypto/asn1/tasn_dec.c \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/strings.h include/openssl/asn1.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/bn.h include/openssl/asn1t.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/internal/numbers.h \
+ crypto/asn1/asn1_locl.h
+crypto/evp/encode.o: crypto/evp/encode.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/evp/evp_locl.h
+crypto/idea/i_skey.o: crypto/idea/i_skey.c include/openssl/idea.h \
+ include/openssl/opensslconf.h crypto/idea/idea_lcl.h
+crypto/evp/evp_lib.o: crypto/evp/evp_lib.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/include/internal/evp_int.h crypto/evp/evp_locl.h
+crypto/cmac/cm_ameth.o: crypto/cmac/cm_ameth.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/cmac.h crypto/include/internal/asn1_int.h
+crypto/srp/srp_lib.o: crypto/srp/srp_lib.c \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/sha.h \
+ include/openssl/srp.h include/openssl/bn.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h crypto/include/internal/bn_srp.h
+crypto/engine/eng_ctrl.o: crypto/engine/eng_ctrl.c \
+ crypto/engine/eng_int.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/engine.h \
+ include/openssl/engine.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/internal/thread_once.h
+crypto/pkcs7/pk7_lib.o: crypto/pkcs7/pk7_lib.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/x509.h \
+ include/openssl/evp.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/include/internal/asn1_int.h crypto/include/internal/evp_int.h
+crypto/des/ecb_enc.o: crypto/des/ecb_enc.c crypto/des/des_locl.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h include/openssl/des.h \
+ include/openssl/opensslv.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h
+crypto/objects/obj_xref.o: crypto/objects/obj_xref.c \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/bio.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/objects/obj_xref.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h
+crypto/evp/e_aes_cbc_hmac_sha1.o: crypto/evp/e_aes_cbc_hmac_sha1.c \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/evp.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/symhacks.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/aes.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/sha.h include/openssl/rand.h crypto/modes/modes_lcl.h \
+ include/openssl/modes.h crypto/include/internal/evp_int.h \
+ include/internal/constant_time_locl.h
+crypto/mem_clr.o: crypto/mem_clr.c ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/strings.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/time.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h
+crypto/ts/ts_req_print.o: crypto/ts/ts_req_print.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/x509v3.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/conf.h include/openssl/ts.h crypto/ts/ts_lcl.h
+crypto/engine/eng_fat.o: crypto/engine/eng_fat.c crypto/engine/eng_int.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h crypto/include/internal/engine.h \
+ include/openssl/engine.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/asn1.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/ec.h include/openssl/rand.h include/openssl/ui.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/internal/thread_once.h include/openssl/conf.h
+crypto/seed/seed.o: crypto/seed/seed.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/seed.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h crypto/seed/seed_locl.h
+crypto/evp/e_aes_cbc_hmac_sha256.o: crypto/evp/e_aes_cbc_hmac_sha256.c \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/evp.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/symhacks.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/aes.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/sha.h include/openssl/rand.h crypto/modes/modes_lcl.h \
+ include/openssl/modes.h include/internal/constant_time_locl.h \
+ crypto/include/internal/evp_int.h
+crypto/pkcs12/p12_asn.o: crypto/pkcs12/p12_asn.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1t.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/pkcs12.h include/openssl/x509.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/pkcs12/p12_lcl.h
+crypto/bf/bf_ecb.o: crypto/bf/bf_ecb.c include/openssl/blowfish.h \
+ include/openssl/opensslconf.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h crypto/bf/bf_locl.h \
+ include/openssl/opensslv.h
+crypto/cms/cms_err.o: crypto/cms/cms_err.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/err.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/cms.h \
+ include/openssl/x509.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ec.h \
+ include/openssl/rsa.h include/openssl/dsa.h include/openssl/dh.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/x509v3.h include/openssl/conf.h
+crypto/dh/dh_key.o: crypto/dh/dh_key.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/dh/dh_locl.h include/openssl/dh.h include/openssl/asn1.h \
+ include/openssl/bn.h crypto/include/internal/bn_int.h
+crypto/ec/ecdsa_vrf.o: crypto/ec/ecdsa_vrf.c include/openssl/ec.h \
+ include/openssl/opensslconf.h include/openssl/asn1.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h include/openssl/e_os2.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/alloca.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/bn.h crypto/ec/ec_lcl.h \
+ include/openssl/obj_mac.h e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h
+crypto/evp/m_mdc2.o: crypto/evp/m_mdc2.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/mdc2.h include/openssl/des.h \
+ crypto/include/internal/evp_int.h
+crypto/asn1/a_int.o: crypto/asn1/a_int.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/internal/numbers.h include/openssl/asn1.h include/openssl/bn.h \
+ crypto/asn1/asn1_locl.h
+crypto/asn1/asn_moid.o: crypto/asn1/asn_moid.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/ctype.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdint.h ../musl-1.1.18/include/bits/stdint.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h crypto/include/internal/cryptlib.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/conf.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h crypto/include/internal/asn1_int.h \
+ crypto/include/internal/objects.h
+crypto/dh/dh_err.o: crypto/dh/dh_err.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ include/openssl/err.h include/openssl/e_os2.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h \
+ include/openssl/lhash.h ../musl-1.1.18/include/errno.h \
+ ../musl-1.1.18/include/bits/errno.h include/openssl/dh.h \
+ include/openssl/asn1.h include/openssl/bn.h
+crypto/rsa/rsa_pmeth.o: crypto/rsa/rsa_pmeth.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1t.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/ec.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/x509v3.h include/openssl/conf.h include/openssl/cms.h \
+ crypto/include/internal/evp_int.h crypto/rsa/rsa_locl.h
+crypto/asn1/d2i_pr.o: crypto/asn1/d2i_pr.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/bn.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h \
+ include/openssl/engine.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/ec.h include/openssl/rand.h \
+ include/openssl/ui.h include/openssl/x509.h include/openssl/sha.h \
+ include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ crypto/include/internal/asn1_int.h crypto/include/internal/evp_int.h
+crypto/bio/bf_buff.o: crypto/bio/bf_buff.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/bio/bio_lcl.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h include/internal/bio.h
+crypto/hmac/hm_pmeth.o: crypto/hmac/hm_pmeth.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h include/openssl/x509v3.h include/openssl/conf.h \
+ include/openssl/hmac.h crypto/include/internal/evp_int.h
+crypto/bio/bf_lbuf.o: crypto/bio/bf_lbuf.c ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ crypto/bio/bio_lcl.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h \
+ ../musl-1.1.18/include/sys/param.h ../musl-1.1.18/include/sys/resource.h \
+ ../musl-1.1.18/include/sys/time.h ../musl-1.1.18/include/bits/resource.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ ../musl-1.1.18/include/netdb.h ../musl-1.1.18/include/netinet/in.h \
+ ../musl-1.1.18/include/inttypes.h ../musl-1.1.18/include/sys/socket.h \
+ ../musl-1.1.18/include/bits/socket.h ../musl-1.1.18/include/sys/un.h \
+ ../musl-1.1.18/include/arpa/inet.h ../musl-1.1.18/include/netinet/tcp.h \
+ ../musl-1.1.18/include/sys/ioctl.h ../musl-1.1.18/include/bits/ioctl.h \
+ ../musl-1.1.18/include/bits/ioctl_fix.h ../musl-1.1.18/include/strings.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ ../musl-1.1.18/include/stddef.h include/openssl/bio.h \
+ ../musl-1.1.18/include/stdarg.h include/openssl/err.h \
+ include/openssl/lhash.h include/internal/bio.h include/openssl/evp.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h
+crypto/bn/bn_srp.o: crypto/bn/bn_srp.c crypto/bn/bn_lcl.h \
+ include/openssl/opensslconf.h crypto/include/internal/bn_conf.h \
+ crypto/include/internal/bn_int.h include/openssl/bn.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ ../musl-1.1.18/include/features.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/symhacks.h e_os.h \
+ ../musl-1.1.18/include/unistd.h ../musl-1.1.18/include/bits/posix.h \
+ ../musl-1.1.18/include/sys/types.h ../musl-1.1.18/include/endian.h \
+ ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h ../musl-1.1.18/include/strings.h \
+ include/openssl/srp.h ../musl-1.1.18/include/string.h \
+ crypto/include/internal/bn_srp.h
+crypto/pkcs7/pk7_smime.o: crypto/pkcs7/pk7_smime.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/x509.h include/openssl/evp.h include/openssl/objects.h \
+ include/openssl/obj_mac.h include/openssl/asn1.h include/openssl/bn.h \
+ include/openssl/ec.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/pkcs7.h include/openssl/x509v3.h include/openssl/conf.h
+crypto/sha/sha512.o: crypto/sha/sha512.c include/openssl/opensslconf.h \
+ ../musl-1.1.18/include/stdlib.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/time.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/sha.h \
+ ../musl-1.1.18/include/stddef.h crypto/include/internal/cryptlib.h \
+ e_os.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/buffer.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h
+crypto/ts/ts_rsp_utils.o: crypto/ts/ts_rsp_utils.c \
+ ../musl-1.1.18/include/stdio.h ../musl-1.1.18/include/features.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/string.h \
+ ../musl-1.1.18/include/strings.h e_os.h include/openssl/opensslconf.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/bits/limits.h include/openssl/symhacks.h \
+ include/openssl/buffer.h ../musl-1.1.18/include/stddef.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/ts.h \
+ include/openssl/evp.h include/openssl/rsa.h include/openssl/dsa.h \
+ include/openssl/dh.h include/openssl/x509.h include/openssl/ec.h \
+ include/openssl/sha.h include/openssl/x509_vfy.h include/openssl/pkcs7.h \
+ include/openssl/x509v3.h include/openssl/conf.h crypto/ts/ts_lcl.h
+crypto/rc4/rc4_enc.o: crypto/rc4/rc4_enc.c include/openssl/rc4.h \
+ include/openssl/opensslconf.h ../musl-1.1.18/include/stddef.h \
+ ../musl-1.1.18/include/bits/alltypes.h crypto/rc4/rc4_locl.h \
+ crypto/include/internal/cryptlib.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/alloca.h \
+ ../musl-1.1.18/include/string.h ../musl-1.1.18/include/strings.h e_os.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/stdint.h ../musl-1.1.18/include/unistd.h \
+ ../musl-1.1.18/include/bits/posix.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/crypto.h \
+ ../musl-1.1.18/include/time.h ../musl-1.1.18/include/stdio.h \
+ include/openssl/stack.h include/openssl/safestack.h \
+ include/openssl/opensslv.h include/openssl/ossl_typ.h \
+ ../musl-1.1.18/include/limits.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/symhacks.h include/openssl/buffer.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/err.h include/openssl/lhash.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h
+crypto/ts/ts_asn1.o: crypto/ts/ts_asn1.c include/openssl/ts.h \
+ include/openssl/opensslconf.h include/openssl/symhacks.h \
+ include/openssl/e_os2.h ../musl-1.1.18/include/stdint.h \
+ ../musl-1.1.18/include/bits/alltypes.h \
+ ../musl-1.1.18/include/bits/stdint.h include/openssl/buffer.h \
+ include/openssl/ossl_typ.h ../musl-1.1.18/include/limits.h \
+ ../musl-1.1.18/include/features.h ../musl-1.1.18/include/bits/limits.h \
+ include/openssl/crypto.h ../musl-1.1.18/include/stdlib.h \
+ ../musl-1.1.18/include/alloca.h ../musl-1.1.18/include/time.h \
+ ../musl-1.1.18/include/stdio.h include/openssl/stack.h \
+ include/openssl/safestack.h include/openssl/opensslv.h \
+ ../musl-1.1.18/include/stddef.h ../musl-1.1.18/include/sys/types.h \
+ ../musl-1.1.18/include/endian.h ../musl-1.1.18/include/sys/select.h \
+ ../musl-1.1.18/include/sys/sysmacros.h include/openssl/evp.h \
+ include/openssl/bio.h ../musl-1.1.18/include/stdarg.h \
+ include/openssl/objects.h include/openssl/obj_mac.h \
+ include/openssl/asn1.h include/openssl/bn.h include/openssl/rsa.h \
+ include/openssl/dsa.h include/openssl/dh.h include/openssl/x509.h \
+ include/openssl/ec.h include/openssl/sha.h include/openssl/x509_vfy.h \
+ include/openssl/lhash.h include/openssl/pkcs7.h include/openssl/x509v3.h \
+ include/openssl/conf.h include/openssl/err.h \
+ ../musl-1.1.18/include/errno.h ../musl-1.1.18/include/bits/errno.h \
+ include/openssl/asn1t.h crypto/ts/ts_lcl.h
Index: EcnlProtoTool/trunk/openssl-1.1.0e/NEWS
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/NEWS	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/NEWS	(revision 331)
@@ -0,0 +1,852 @@
+
+  NEWS
+  ====
+
+  This file gives a brief overview of the major changes between each OpenSSL
+  release. For more details please read the CHANGES file.
+
+  Major changes between OpenSSL 1.1.0d and OpenSSL 1.1.0e [16 Feb 2017]
+
+      o Encrypt-Then-Mac renegotiation crash (CVE-2017-3733)
+
+  Major changes between OpenSSL 1.1.0c and OpenSSL 1.1.0d [26 Jan 2017]
+
+      o Truncated packet could crash via OOB read (CVE-2017-3731)
+      o Bad (EC)DHE parameters cause a client crash (CVE-2017-3730)
+      o BN_mod_exp may produce incorrect results on x86_64 (CVE-2017-3732)
+
+  Major changes between OpenSSL 1.1.0b and OpenSSL 1.1.0c [10 Nov 2016]
+
+      o ChaCha20/Poly1305 heap-buffer-overflow (CVE-2016-7054)
+      o CMS Null dereference (CVE-2016-7053)
+      o Montgomery multiplication may produce incorrect results (CVE-2016-7055)
+
+  Major changes between OpenSSL 1.1.0a and OpenSSL 1.1.0b [26 Sep 2016]
+
+      o Fix Use After Free for large message sizes (CVE-2016-6309)
+
+  Major changes between OpenSSL 1.1.0 and OpenSSL 1.1.0a [22 Sep 2016]
+
+      o OCSP Status Request extension unbounded memory growth (CVE-2016-6304)
+      o SSL_peek() hang on empty record (CVE-2016-6305)
+      o Excessive allocation of memory in tls_get_message_header()
+       (CVE-2016-6307)
+      o Excessive allocation of memory in dtls1_preprocess_fragment()
+       (CVE-2016-6308)
+
+  Major changes between OpenSSL 1.0.2h and OpenSSL 1.1.0 [25 Aug 2016]
+
+      o Copyright text was shrunk to a boilerplate that points to the license
+      o "shared" builds are now the default when possible
+      o Added support for "pipelining"
+      o Added the AFALG engine
+      o New threading API implemented
+      o Support for ChaCha20 and Poly1305 added to libcrypto and libssl
+      o Support for extended master secret
+      o CCM ciphersuites
+      o Reworked test suite, now based on perl, Test::Harness and Test::More
+      o *Most* libcrypto and libssl public structures were made opaque,
+        including:
+        BIGNUM and associated types, EC_KEY and EC_KEY_METHOD,
+        DH and DH_METHOD, DSA and DSA_METHOD, RSA and RSA_METHOD,
+        BIO and BIO_METHOD, EVP_MD_CTX, EVP_MD, EVP_CIPHER_CTX,
+        EVP_CIPHER, EVP_PKEY and associated types, HMAC_CTX,
+        X509, X509_CRL, X509_OBJECT, X509_STORE_CTX, X509_STORE,
+        X509_LOOKUP, X509_LOOKUP_METHOD
+      o libssl internal structures made opaque
+      o SSLv2 support removed
+      o Kerberos ciphersuite support removed
+      o RC4 removed from DEFAULT ciphersuites in libssl
+      o 40 and 56 bit cipher support removed from libssl
+      o All public header files moved to include/openssl, no more symlinking
+      o SSL/TLS state machine, version negotiation and record layer rewritten
+      o EC revision: now operations use new EC_KEY_METHOD.
+      o Support for OCB mode added to libcrypto
+      o Support for asynchronous crypto operations added to libcrypto and libssl
+      o Deprecated interfaces can now be disabled at build time either
+        relative to the latest release via the "no-deprecated" Configure
+        argument, or via the "--api=1.1.0|1.0.0|0.9.8" option.
+      o Application software can be compiled with -DOPENSSL_API_COMPAT=version
+        to ensure that features deprecated in that version are not exposed.
+      o Support for RFC6698/RFC7671 DANE TLSA peer authentication
+      o Change of Configure to use --prefix as the main installation
+        directory location rather than --openssldir.  The latter becomes
+        the directory for certs, private key and openssl.cnf exclusively.
+      o Reworked BIO networking library, with full support for IPv6.
+      o New "unified" build system
+      o New security levels
+      o Support for scrypt algorithm
+      o Support for X25519
+      o Extended SSL_CONF support using configuration files
+      o KDF algorithm support. Implement TLS PRF as a KDF.
+      o Support for Certificate Transparency
+      o HKDF support.
+
+  Major changes between OpenSSL 1.0.2g and OpenSSL 1.0.2h [3 May 2016]
+
+      o Prevent padding oracle in AES-NI CBC MAC check (CVE-2016-2107)
+      o Fix EVP_EncodeUpdate overflow (CVE-2016-2105)
+      o Fix EVP_EncryptUpdate overflow (CVE-2016-2106)
+      o Prevent ASN.1 BIO excessive memory allocation (CVE-2016-2109)
+      o EBCDIC overread (CVE-2016-2176)
+      o Modify behavior of ALPN to invoke callback after SNI/servername
+        callback, such that updates to the SSL_CTX affect ALPN.
+      o Remove LOW from the DEFAULT cipher list.  This removes singles DES from
+        the default.
+      o Only remove the SSLv2 methods with the no-ssl2-method option.
+
+  Major changes between OpenSSL 1.0.2f and OpenSSL 1.0.2g [1 Mar 2016]
+
+      o Disable weak ciphers in SSLv3 and up in default builds of OpenSSL.
+      o Disable SSLv2 default build, default negotiation and weak ciphers
+        (CVE-2016-0800)
+      o Fix a double-free in DSA code (CVE-2016-0705)
+      o Disable SRP fake user seed to address a server memory leak
+        (CVE-2016-0798)
+      o Fix BN_hex2bn/BN_dec2bn NULL pointer deref/heap corruption
+        (CVE-2016-0797)
+      o Fix memory issues in BIO_*printf functions (CVE-2016-0799)
+      o Fix side channel attack on modular exponentiation (CVE-2016-0702)
+
+  Major changes between OpenSSL 1.0.2e and OpenSSL 1.0.2f [28 Jan 2016]
+
+      o DH small subgroups (CVE-2016-0701)
+      o SSLv2 doesn't block disabled ciphers (CVE-2015-3197)
+
+  Major changes between OpenSSL 1.0.2d and OpenSSL 1.0.2e [3 Dec 2015]
+
+      o BN_mod_exp may produce incorrect results on x86_64 (CVE-2015-3193)
+      o Certificate verify crash with missing PSS parameter (CVE-2015-3194)
+      o X509_ATTRIBUTE memory leak (CVE-2015-3195)
+      o Rewrite EVP_DecodeUpdate (base64 decoding) to fix several bugs
+      o In DSA_generate_parameters_ex, if the provided seed is too short,
+        return an error
+
+  Major changes between OpenSSL 1.0.2c and OpenSSL 1.0.2d [9 Jul 2015]
+
+      o Alternate chains certificate forgery (CVE-2015-1793)
+      o Race condition handling PSK identify hint (CVE-2015-3196)
+
+  Major changes between OpenSSL 1.0.2b and OpenSSL 1.0.2c [12 Jun 2015]
+
+      o Fix HMAC ABI incompatibility
+
+  Major changes between OpenSSL 1.0.2a and OpenSSL 1.0.2b [11 Jun 2015]
+
+      o Malformed ECParameters causes infinite loop (CVE-2015-1788)
+      o Exploitable out-of-bounds read in X509_cmp_time (CVE-2015-1789)
+      o PKCS7 crash with missing EnvelopedContent (CVE-2015-1790)
+      o CMS verify infinite loop with unknown hash function (CVE-2015-1792)
+      o Race condition handling NewSessionTicket (CVE-2015-1791)
+
+  Major changes between OpenSSL 1.0.2 and OpenSSL 1.0.2a [19 Mar 2015]
+
+      o OpenSSL 1.0.2 ClientHello sigalgs DoS fix (CVE-2015-0291)
+      o Multiblock corrupted pointer fix (CVE-2015-0290)
+      o Segmentation fault in DTLSv1_listen fix (CVE-2015-0207)
+      o Segmentation fault in ASN1_TYPE_cmp fix (CVE-2015-0286)
+      o Segmentation fault for invalid PSS parameters fix (CVE-2015-0208)
+      o ASN.1 structure reuse memory corruption fix (CVE-2015-0287)
+      o PKCS7 NULL pointer dereferences fix (CVE-2015-0289)
+      o DoS via reachable assert in SSLv2 servers fix (CVE-2015-0293)
+      o Empty CKE with client auth and DHE fix (CVE-2015-1787)
+      o Handshake with unseeded PRNG fix (CVE-2015-0285)
+      o Use After Free following d2i_ECPrivatekey error fix (CVE-2015-0209)
+      o X509_to_X509_REQ NULL pointer deref fix (CVE-2015-0288)
+      o Removed the export ciphers from the DEFAULT ciphers
+
+  Major changes between OpenSSL 1.0.1l and OpenSSL 1.0.2 [22 Jan 2015]:
+
+      o Suite B support for TLS 1.2 and DTLS 1.2
+      o Support for DTLS 1.2
+      o TLS automatic EC curve selection.
+      o API to set TLS supported signature algorithms and curves
+      o SSL_CONF configuration API.
+      o TLS Brainpool support.
+      o ALPN support.
+      o CMS support for RSA-PSS, RSA-OAEP, ECDH and X9.42 DH.
+
+  Major changes between OpenSSL 1.0.1k and OpenSSL 1.0.1l [15 Jan 2015]
+
+      o Build fixes for the Windows and OpenVMS platforms
+
+  Major changes between OpenSSL 1.0.1j and OpenSSL 1.0.1k [8 Jan 2015]
+
+      o Fix for CVE-2014-3571
+      o Fix for CVE-2015-0206
+      o Fix for CVE-2014-3569
+      o Fix for CVE-2014-3572
+      o Fix for CVE-2015-0204
+      o Fix for CVE-2015-0205
+      o Fix for CVE-2014-8275
+      o Fix for CVE-2014-3570
+
+  Major changes between OpenSSL 1.0.1i and OpenSSL 1.0.1j [15 Oct 2014]
+
+      o Fix for CVE-2014-3513
+      o Fix for CVE-2014-3567
+      o Mitigation for CVE-2014-3566 (SSL protocol vulnerability)
+      o Fix for CVE-2014-3568
+
+  Major changes between OpenSSL 1.0.1h and OpenSSL 1.0.1i [6 Aug 2014]
+
+      o Fix for CVE-2014-3512
+      o Fix for CVE-2014-3511
+      o Fix for CVE-2014-3510
+      o Fix for CVE-2014-3507
+      o Fix for CVE-2014-3506
+      o Fix for CVE-2014-3505
+      o Fix for CVE-2014-3509
+      o Fix for CVE-2014-5139
+      o Fix for CVE-2014-3508
+
+  Major changes between OpenSSL 1.0.1g and OpenSSL 1.0.1h [5 Jun 2014]
+
+      o Fix for CVE-2014-0224
+      o Fix for CVE-2014-0221
+      o Fix for CVE-2014-0198
+      o Fix for CVE-2014-0195
+      o Fix for CVE-2014-3470
+      o Fix for CVE-2010-5298
+
+  Major changes between OpenSSL 1.0.1f and OpenSSL 1.0.1g [7 Apr 2014]
+
+      o Fix for CVE-2014-0160
+      o Add TLS padding extension workaround for broken servers.
+      o Fix for CVE-2014-0076
+
+  Major changes between OpenSSL 1.0.1e and OpenSSL 1.0.1f [6 Jan 2014]
+
+      o Don't include gmt_unix_time in TLS server and client random values
+      o Fix for TLS record tampering bug CVE-2013-4353
+      o Fix for TLS version checking bug CVE-2013-6449
+      o Fix for DTLS retransmission bug CVE-2013-6450
+
+  Major changes between OpenSSL 1.0.1d and OpenSSL 1.0.1e [11 Feb 2013]:
+
+      o Corrected fix for CVE-2013-0169
+
+  Major changes between OpenSSL 1.0.1c and OpenSSL 1.0.1d [4 Feb 2013]:
+
+      o Fix renegotiation in TLS 1.1, 1.2 by using the correct TLS version.
+      o Include the fips configuration module.
+      o Fix OCSP bad key DoS attack CVE-2013-0166
+      o Fix for SSL/TLS/DTLS CBC plaintext recovery attack CVE-2013-0169
+      o Fix for TLS AESNI record handling flaw CVE-2012-2686
+
+  Major changes between OpenSSL 1.0.1b and OpenSSL 1.0.1c [10 May 2012]:
+
+      o Fix TLS/DTLS record length checking bug CVE-2012-2333
+      o Don't attempt to use non-FIPS composite ciphers in FIPS mode.
+
+  Major changes between OpenSSL 1.0.1a and OpenSSL 1.0.1b [26 Apr 2012]:
+
+      o Fix compilation error on non-x86 platforms.
+      o Make FIPS capable OpenSSL ciphers work in non-FIPS mode.
+      o Fix SSL_OP_NO_TLSv1_1 clash with SSL_OP_ALL in OpenSSL 1.0.0
+
+  Major changes between OpenSSL 1.0.1 and OpenSSL 1.0.1a [19 Apr 2012]:
+
+      o Fix for ASN1 overflow bug CVE-2012-2110
+      o Workarounds for some servers that hang on long client hellos.
+      o Fix SEGV in AES code.
+
+  Major changes between OpenSSL 1.0.0h and OpenSSL 1.0.1 [14 Mar 2012]:
+
+      o TLS/DTLS heartbeat support.
+      o SCTP support.
+      o RFC 5705 TLS key material exporter.
+      o RFC 5764 DTLS-SRTP negotiation.
+      o Next Protocol Negotiation.
+      o PSS signatures in certificates, requests and CRLs.
+      o Support for password based recipient info for CMS.
+      o Support TLS v1.2 and TLS v1.1.
+      o Preliminary FIPS capability for unvalidated 2.0 FIPS module.
+      o SRP support.
+
+  Major changes between OpenSSL 1.0.0g and OpenSSL 1.0.0h [12 Mar 2012]:
+
+      o Fix for CMS/PKCS#7 MMA CVE-2012-0884
+      o Corrected fix for CVE-2011-4619
+      o Various DTLS fixes.
+
+  Major changes between OpenSSL 1.0.0f and OpenSSL 1.0.0g [18 Jan 2012]:
+
+      o Fix for DTLS DoS issue CVE-2012-0050
+
+  Major changes between OpenSSL 1.0.0e and OpenSSL 1.0.0f [4 Jan 2012]:
+
+      o Fix for DTLS plaintext recovery attack CVE-2011-4108
+      o Clear block padding bytes of SSL 3.0 records CVE-2011-4576
+      o Only allow one SGC handshake restart for SSL/TLS CVE-2011-4619
+      o Check parameters are not NULL in GOST ENGINE CVE-2012-0027
+      o Check for malformed RFC3779 data CVE-2011-4577
+
+  Major changes between OpenSSL 1.0.0d and OpenSSL 1.0.0e [6 Sep 2011]:
+
+      o Fix for CRL vulnerability issue CVE-2011-3207
+      o Fix for ECDH crashes CVE-2011-3210
+      o Protection against EC timing attacks.
+      o Support ECDH ciphersuites for certificates using SHA2 algorithms.
+      o Various DTLS fixes.
+
+  Major changes between OpenSSL 1.0.0c and OpenSSL 1.0.0d [8 Feb 2011]:
+
+      o Fix for security issue CVE-2011-0014
+
+  Major changes between OpenSSL 1.0.0b and OpenSSL 1.0.0c [2 Dec 2010]:
+
+      o Fix for security issue CVE-2010-4180
+      o Fix for CVE-2010-4252
+      o Fix mishandling of absent EC point format extension.
+      o Fix various platform compilation issues.
+      o Corrected fix for security issue CVE-2010-3864.
+
+  Major changes between OpenSSL 1.0.0a and OpenSSL 1.0.0b [16 Nov 2010]:
+
+      o Fix for security issue CVE-2010-3864.
+      o Fix for CVE-2010-2939
+      o Fix WIN32 build system for GOST ENGINE.
+
+  Major changes between OpenSSL 1.0.0 and OpenSSL 1.0.0a [1 Jun 2010]:
+
+      o Fix for security issue CVE-2010-1633.
+      o GOST MAC and CFB fixes.
+
+  Major changes between OpenSSL 0.9.8n and OpenSSL 1.0.0 [29 Mar 2010]:
+
+      o RFC3280 path validation: sufficient to process PKITS tests.
+      o Integrated support for PVK files and keyblobs.
+      o Change default private key format to PKCS#8.
+      o CMS support: able to process all examples in RFC4134
+      o Streaming ASN1 encode support for PKCS#7 and CMS.
+      o Multiple signer and signer add support for PKCS#7 and CMS.
+      o ASN1 printing support.
+      o Whirlpool hash algorithm added.
+      o RFC3161 time stamp support.
+      o New generalised public key API supporting ENGINE based algorithms.
+      o New generalised public key API utilities.
+      o New ENGINE supporting GOST algorithms.
+      o SSL/TLS GOST ciphersuite support.
+      o PKCS#7 and CMS GOST support.
+      o RFC4279 PSK ciphersuite support.
+      o Supported points format extension for ECC ciphersuites.
+      o ecdsa-with-SHA224/256/384/512 signature types.
+      o dsa-with-SHA224 and dsa-with-SHA256 signature types.
+      o Opaque PRF Input TLS extension support.
+      o Updated time routines to avoid OS limitations.
+
+  Major changes between OpenSSL 0.9.8m and OpenSSL 0.9.8n [24 Mar 2010]:
+
+      o CFB cipher definition fixes.
+      o Fix security issues CVE-2010-0740 and CVE-2010-0433.
+
+  Major changes between OpenSSL 0.9.8l and OpenSSL 0.9.8m [25 Feb 2010]:
+
+      o Cipher definition fixes.
+      o Workaround for slow RAND_poll() on some WIN32 versions.
+      o Remove MD2 from algorithm tables.
+      o SPKAC handling fixes.
+      o Support for RFC5746 TLS renegotiation extension.
+      o Compression memory leak fixed.
+      o Compression session resumption fixed.
+      o Ticket and SNI coexistence fixes.
+      o Many fixes to DTLS handling. 
+
+  Major changes between OpenSSL 0.9.8k and OpenSSL 0.9.8l [5 Nov 2009]:
+
+      o Temporary work around for CVE-2009-3555: disable renegotiation.
+
+  Major changes between OpenSSL 0.9.8j and OpenSSL 0.9.8k [25 Mar 2009]:
+
+      o Fix various build issues.
+      o Fix security issues (CVE-2009-0590, CVE-2009-0591, CVE-2009-0789)
+
+  Major changes between OpenSSL 0.9.8i and OpenSSL 0.9.8j [7 Jan 2009]:
+
+      o Fix security issue (CVE-2008-5077)
+      o Merge FIPS 140-2 branch code.
+
+  Major changes between OpenSSL 0.9.8g and OpenSSL 0.9.8h [28 May 2008]:
+
+      o CryptoAPI ENGINE support.
+      o Various precautionary measures.
+      o Fix for bugs affecting certificate request creation.
+      o Support for local machine keyset attribute in PKCS#12 files.
+
+  Major changes between OpenSSL 0.9.8f and OpenSSL 0.9.8g [19 Oct 2007]:
+
+      o Backport of CMS functionality to 0.9.8.
+      o Fixes for bugs introduced with 0.9.8f.
+
+  Major changes between OpenSSL 0.9.8e and OpenSSL 0.9.8f [11 Oct 2007]:
+
+      o Add gcc 4.2 support.
+      o Add support for AES and SSE2 assembly language optimization
+        for VC++ build.
+      o Support for RFC4507bis and server name extensions if explicitly 
+        selected at compile time.
+      o DTLS improvements.
+      o RFC4507bis support.
+      o TLS Extensions support.
+
+  Major changes between OpenSSL 0.9.8d and OpenSSL 0.9.8e [23 Feb 2007]:
+
+      o Various ciphersuite selection fixes.
+      o RFC3779 support.
+
+  Major changes between OpenSSL 0.9.8c and OpenSSL 0.9.8d [28 Sep 2006]:
+
+      o Introduce limits to prevent malicious key DoS  (CVE-2006-2940)
+      o Fix security issues (CVE-2006-2937, CVE-2006-3737, CVE-2006-4343)
+      o Changes to ciphersuite selection algorithm
+
+  Major changes between OpenSSL 0.9.8b and OpenSSL 0.9.8c [5 Sep 2006]:
+
+      o Fix Daniel Bleichenbacher forged signature attack, CVE-2006-4339
+      o New cipher Camellia
+
+  Major changes between OpenSSL 0.9.8a and OpenSSL 0.9.8b [4 May 2006]:
+
+      o Cipher string fixes.
+      o Fixes for VC++ 2005.
+      o Updated ECC cipher suite support.
+      o New functions EVP_CIPHER_CTX_new() and EVP_CIPHER_CTX_free().
+      o Zlib compression usage fixes.
+      o Built in dynamic engine compilation support on Win32.
+      o Fixes auto dynamic engine loading in Win32.
+
+  Major changes between OpenSSL 0.9.8 and OpenSSL 0.9.8a [11 Oct 2005]:
+
+      o Fix potential SSL 2.0 rollback, CVE-2005-2969
+      o Extended Windows CE support
+
+  Major changes between OpenSSL 0.9.7g and OpenSSL 0.9.8 [5 Jul 2005]:
+
+      o Major work on the BIGNUM library for higher efficiency and to
+        make operations more streamlined and less contradictory.  This
+        is the result of a major audit of the BIGNUM library.
+      o Addition of BIGNUM functions for fields GF(2^m) and NIST
+        curves, to support the Elliptic Crypto functions.
+      o Major work on Elliptic Crypto; ECDH and ECDSA added, including
+        the use through EVP, X509 and ENGINE.
+      o New ASN.1 mini-compiler that's usable through the OpenSSL
+        configuration file.
+      o Added support for ASN.1 indefinite length constructed encoding.
+      o New PKCS#12 'medium level' API to manipulate PKCS#12 files.
+      o Complete rework of shared library construction and linking
+        programs with shared or static libraries, through a separate
+        Makefile.shared.
+      o Rework of the passing of parameters from one Makefile to another.
+      o Changed ENGINE framework to load dynamic engine modules
+        automatically from specifically given directories.
+      o New structure and ASN.1 functions for CertificatePair.
+      o Changed the ZLIB compression method to be stateful.
+      o Changed the key-generation and primality testing "progress"
+        mechanism to take a structure that contains the ticker
+        function and an argument.
+      o New engine module: GMP (performs private key exponentiation).
+      o New engine module: VIA PadLOck ACE extension in VIA C3
+        Nehemiah processors.
+      o Added support for IPv6 addresses in certificate extensions.
+        See RFC 1884, section 2.2.
+      o Added support for certificate policy mappings, policy
+        constraints and name constraints.
+      o Added support for multi-valued AVAs in the OpenSSL
+        configuration file.
+      o Added support for multiple certificates with the same subject
+        in the 'openssl ca' index file.
+      o Make it possible to create self-signed certificates using
+        'openssl ca -selfsign'.
+      o Make it possible to generate a serial number file with
+        'openssl ca -create_serial'.
+      o New binary search functions with extended functionality.
+      o New BUF functions.
+      o New STORE structure and library to provide an interface to all
+        sorts of data repositories.  Supports storage of public and
+        private keys, certificates, CRLs, numbers and arbitrary blobs.
+        This library is unfortunately unfinished and unused within
+        OpenSSL.
+      o New control functions for the error stack.
+      o Changed the PKCS#7 library to support one-pass S/MIME
+        processing.
+      o Added the possibility to compile without old deprecated
+        functionality with the OPENSSL_NO_DEPRECATED macro or the
+        'no-deprecated' argument to the config and Configure scripts.
+      o Constification of all ASN.1 conversion functions, and other
+        affected functions.
+      o Improved platform support for PowerPC.
+      o New FIPS 180-2 algorithms (SHA-224, -256, -384 and -512).
+      o New X509_VERIFY_PARAM structure to support parametrisation
+        of X.509 path validation.
+      o Major overhaul of RC4 performance on Intel P4, IA-64 and
+        AMD64.
+      o Changed the Configure script to have some algorithms disabled
+        by default.  Those can be explicitly enabled with the new
+        argument form 'enable-xxx'.
+      o Change the default digest in 'openssl' commands from MD5 to
+        SHA-1.
+      o Added support for DTLS.
+      o New BIGNUM blinding.
+      o Added support for the RSA-PSS encryption scheme
+      o Added support for the RSA X.931 padding.
+      o Added support for BSD sockets on NetWare.
+      o Added support for files larger than 2GB.
+      o Added initial support for Win64.
+      o Added alternate pkg-config files.
+
+  Major changes between OpenSSL 0.9.7l and OpenSSL 0.9.7m [23 Feb 2007]:
+
+      o FIPS 1.1.1 module linking.
+      o Various ciphersuite selection fixes.
+
+  Major changes between OpenSSL 0.9.7k and OpenSSL 0.9.7l [28 Sep 2006]:
+
+      o Introduce limits to prevent malicious key DoS  (CVE-2006-2940)
+      o Fix security issues (CVE-2006-2937, CVE-2006-3737, CVE-2006-4343)
+
+  Major changes between OpenSSL 0.9.7j and OpenSSL 0.9.7k [5 Sep 2006]:
+
+      o Fix Daniel Bleichenbacher forged signature attack, CVE-2006-4339
+
+  Major changes between OpenSSL 0.9.7i and OpenSSL 0.9.7j [4 May 2006]:
+
+      o Visual C++ 2005 fixes.
+      o Update Windows build system for FIPS.
+
+  Major changes between OpenSSL 0.9.7h and OpenSSL 0.9.7i [14 Oct 2005]:
+
+      o Give EVP_MAX_MD_SIZE it's old value, except for a FIPS build.
+
+  Major changes between OpenSSL 0.9.7g and OpenSSL 0.9.7h [11 Oct 2005]:
+
+      o Fix SSL 2.0 Rollback, CVE-2005-2969
+      o Allow use of fixed-length exponent on DSA signing
+      o Default fixed-window RSA, DSA, DH private-key operations
+
+  Major changes between OpenSSL 0.9.7f and OpenSSL 0.9.7g [11 Apr 2005]:
+
+      o More compilation issues fixed.
+      o Adaptation to more modern Kerberos API.
+      o Enhanced or corrected configuration for Solaris64, Mingw and Cygwin.
+      o Enhanced x86_64 assembler BIGNUM module.
+      o More constification.
+      o Added processing of proxy certificates (RFC 3820).
+
+  Major changes between OpenSSL 0.9.7e and OpenSSL 0.9.7f [22 Mar 2005]:
+
+      o Several compilation issues fixed.
+      o Many memory allocation failure checks added.
+      o Improved comparison of X509 Name type.
+      o Mandatory basic checks on certificates.
+      o Performance improvements.
+
+  Major changes between OpenSSL 0.9.7d and OpenSSL 0.9.7e [25 Oct 2004]:
+
+      o Fix race condition in CRL checking code.
+      o Fixes to PKCS#7 (S/MIME) code.
+
+  Major changes between OpenSSL 0.9.7c and OpenSSL 0.9.7d [17 Mar 2004]:
+
+      o Security: Fix Kerberos ciphersuite SSL/TLS handshaking bug
+      o Security: Fix null-pointer assignment in do_change_cipher_spec()
+      o Allow multiple active certificates with same subject in CA index
+      o Multiple X509 verification fixes
+      o Speed up HMAC and other operations
+
+  Major changes between OpenSSL 0.9.7b and OpenSSL 0.9.7c [30 Sep 2003]:
+
+      o Security: fix various ASN1 parsing bugs.
+      o New -ignore_err option to OCSP utility.
+      o Various interop and bug fixes in S/MIME code.
+      o SSL/TLS protocol fix for unrequested client certificates.
+
+  Major changes between OpenSSL 0.9.7a and OpenSSL 0.9.7b [10 Apr 2003]:
+
+      o Security: counter the Klima-Pokorny-Rosa extension of
+        Bleichbacher's attack 
+      o Security: make RSA blinding default.
+      o Configuration: Irix fixes, AIX fixes, better mingw support.
+      o Support for new platforms: linux-ia64-ecc.
+      o Build: shared library support fixes.
+      o ASN.1: treat domainComponent correctly.
+      o Documentation: fixes and additions.
+
+  Major changes between OpenSSL 0.9.7 and OpenSSL 0.9.7a [19 Feb 2003]:
+
+      o Security: Important security related bugfixes.
+      o Enhanced compatibility with MIT Kerberos.
+      o Can be built without the ENGINE framework.
+      o IA32 assembler enhancements.
+      o Support for new platforms: FreeBSD/IA64 and FreeBSD/Sparc64.
+      o Configuration: the no-err option now works properly.
+      o SSL/TLS: now handles manual certificate chain building.
+      o SSL/TLS: certain session ID malfunctions corrected.
+
+  Major changes between OpenSSL 0.9.6 and OpenSSL 0.9.7 [30 Dec 2002]:
+
+      o New library section OCSP.
+      o Complete rewrite of ASN1 code.
+      o CRL checking in verify code and openssl utility.
+      o Extension copying in 'ca' utility.
+      o Flexible display options in 'ca' utility.
+      o Provisional support for international characters with UTF8.
+      o Support for external crypto devices ('engine') is no longer
+        a separate distribution.
+      o New elliptic curve library section.
+      o New AES (Rijndael) library section.
+      o Support for new platforms: Windows CE, Tandem OSS, A/UX, AIX 64-bit,
+        Linux x86_64, Linux 64-bit on Sparc v9
+      o Extended support for some platforms: VxWorks
+      o Enhanced support for shared libraries.
+      o Now only builds PIC code when shared library support is requested.
+      o Support for pkg-config.
+      o Lots of new manuals.
+      o Makes symbolic links to or copies of manuals to cover all described
+        functions.
+      o Change DES API to clean up the namespace (some applications link also
+        against libdes providing similar functions having the same name).
+        Provide macros for backward compatibility (will be removed in the
+        future).
+      o Unify handling of cryptographic algorithms (software and engine)
+        to be available via EVP routines for asymmetric and symmetric ciphers.
+      o NCONF: new configuration handling routines.
+      o Change API to use more 'const' modifiers to improve error checking
+        and help optimizers.
+      o Finally remove references to RSAref.
+      o Reworked parts of the BIGNUM code.
+      o Support for new engines: Broadcom ubsec, Accelerated Encryption
+        Processing, IBM 4758.
+      o A few new engines added in the demos area.
+      o Extended and corrected OID (object identifier) table.
+      o PRNG: query at more locations for a random device, automatic query for
+        EGD style random sources at several locations.
+      o SSL/TLS: allow optional cipher choice according to server's preference.
+      o SSL/TLS: allow server to explicitly set new session ids.
+      o SSL/TLS: support Kerberos cipher suites (RFC2712).
+	Only supports MIT Kerberos for now.
+      o SSL/TLS: allow more precise control of renegotiations and sessions.
+      o SSL/TLS: add callback to retrieve SSL/TLS messages.
+      o SSL/TLS: support AES cipher suites (RFC3268).
+
+  Major changes between OpenSSL 0.9.6j and OpenSSL 0.9.6k [30 Sep 2003]:
+
+      o Security: fix various ASN1 parsing bugs.
+      o SSL/TLS protocol fix for unrequested client certificates.
+
+  Major changes between OpenSSL 0.9.6i and OpenSSL 0.9.6j [10 Apr 2003]:
+
+      o Security: counter the Klima-Pokorny-Rosa extension of
+        Bleichbacher's attack 
+      o Security: make RSA blinding default.
+      o Build: shared library support fixes.
+
+  Major changes between OpenSSL 0.9.6h and OpenSSL 0.9.6i [19 Feb 2003]:
+
+      o Important security related bugfixes.
+
+  Major changes between OpenSSL 0.9.6g and OpenSSL 0.9.6h [5 Dec 2002]:
+
+      o New configuration targets for Tandem OSS and A/UX.
+      o New OIDs for Microsoft attributes.
+      o Better handling of SSL session caching.
+      o Better comparison of distinguished names.
+      o Better handling of shared libraries in a mixed GNU/non-GNU environment.
+      o Support assembler code with Borland C.
+      o Fixes for length problems.
+      o Fixes for uninitialised variables.
+      o Fixes for memory leaks, some unusual crashes and some race conditions.
+      o Fixes for smaller building problems.
+      o Updates of manuals, FAQ and other instructive documents.
+
+  Major changes between OpenSSL 0.9.6f and OpenSSL 0.9.6g [9 Aug 2002]:
+
+      o Important building fixes on Unix.
+
+  Major changes between OpenSSL 0.9.6e and OpenSSL 0.9.6f [8 Aug 2002]:
+
+      o Various important bugfixes.
+
+  Major changes between OpenSSL 0.9.6d and OpenSSL 0.9.6e [30 Jul 2002]:
+
+      o Important security related bugfixes.
+      o Various SSL/TLS library bugfixes.
+
+  Major changes between OpenSSL 0.9.6c and OpenSSL 0.9.6d [9 May 2002]:
+
+      o Various SSL/TLS library bugfixes.
+      o Fix DH parameter generation for 'non-standard' generators.
+
+  Major changes between OpenSSL 0.9.6b and OpenSSL 0.9.6c [21 Dec 2001]:
+
+      o Various SSL/TLS library bugfixes.
+      o BIGNUM library fixes.
+      o RSA OAEP and random number generation fixes.
+      o Object identifiers corrected and added.
+      o Add assembler BN routines for IA64.
+      o Add support for OS/390 Unix, UnixWare with gcc, OpenUNIX 8,
+        MIPS Linux; shared library support for Irix, HP-UX.
+      o Add crypto accelerator support for AEP, Baltimore SureWare,
+        Broadcom and Cryptographic Appliance's keyserver
+        [in 0.9.6c-engine release].
+
+  Major changes between OpenSSL 0.9.6a and OpenSSL 0.9.6b [9 Jul 2001]:
+
+      o Security fix: PRNG improvements.
+      o Security fix: RSA OAEP check.
+      o Security fix: Reinsert and fix countermeasure to Bleichbacher's
+        attack.
+      o MIPS bug fix in BIGNUM.
+      o Bug fix in "openssl enc".
+      o Bug fix in X.509 printing routine.
+      o Bug fix in DSA verification routine and DSA S/MIME verification.
+      o Bug fix to make PRNG thread-safe.
+      o Bug fix in RAND_file_name().
+      o Bug fix in compatibility mode trust settings.
+      o Bug fix in blowfish EVP.
+      o Increase default size for BIO buffering filter.
+      o Compatibility fixes in some scripts.
+
+  Major changes between OpenSSL 0.9.6 and OpenSSL 0.9.6a [5 Apr 2001]:
+
+      o Security fix: change behavior of OpenSSL to avoid using
+        environment variables when running as root.
+      o Security fix: check the result of RSA-CRT to reduce the
+        possibility of deducing the private key from an incorrectly
+        calculated signature.
+      o Security fix: prevent Bleichenbacher's DSA attack.
+      o Security fix: Zero the premaster secret after deriving the
+        master secret in DH ciphersuites.
+      o Reimplement SSL_peek(), which had various problems.
+      o Compatibility fix: the function des_encrypt() renamed to
+        des_encrypt1() to avoid clashes with some Unixen libc.
+      o Bug fixes for Win32, HP/UX and Irix.
+      o Bug fixes in BIGNUM, SSL, PKCS#7, PKCS#12, X.509, CONF and
+        memory checking routines.
+      o Bug fixes for RSA operations in threaded environments.
+      o Bug fixes in misc. openssl applications.
+      o Remove a few potential memory leaks.
+      o Add tighter checks of BIGNUM routines.
+      o Shared library support has been reworked for generality.
+      o More documentation.
+      o New function BN_rand_range().
+      o Add "-rand" option to openssl s_client and s_server.
+
+  Major changes between OpenSSL 0.9.5a and OpenSSL 0.9.6 [10 Oct 2000]:
+
+      o Some documentation for BIO and SSL libraries.
+      o Enhanced chain verification using key identifiers.
+      o New sign and verify options to 'dgst' application.
+      o Support for DER and PEM encoded messages in 'smime' application.
+      o New 'rsautl' application, low level RSA utility.
+      o MD4 now included.
+      o Bugfix for SSL rollback padding check.
+      o Support for external crypto devices [1].
+      o Enhanced EVP interface.
+
+    [1] The support for external crypto devices is currently a separate
+        distribution.  See the file README.ENGINE.
+
+  Major changes between OpenSSL 0.9.5 and OpenSSL 0.9.5a [1 Apr 2000]:
+
+      o Bug fixes for Win32, SuSE Linux, NeXTSTEP and FreeBSD 2.2.8 
+      o Shared library support for HPUX and Solaris-gcc
+      o Support of Linux/IA64
+      o Assembler support for Mingw32
+      o New 'rand' application
+      o New way to check for existence of algorithms from scripts
+
+  Major changes between OpenSSL 0.9.4 and OpenSSL 0.9.5 [25 May 2000]:
+
+      o S/MIME support in new 'smime' command
+      o Documentation for the OpenSSL command line application
+      o Automation of 'req' application
+      o Fixes to make s_client, s_server work under Windows
+      o Support for multiple fieldnames in SPKACs
+      o New SPKAC command line utilty and associated library functions
+      o Options to allow passwords to be obtained from various sources
+      o New public key PEM format and options to handle it
+      o Many other fixes and enhancements to command line utilities
+      o Usable certificate chain verification
+      o Certificate purpose checking
+      o Certificate trust settings
+      o Support of authority information access extension
+      o Extensions in certificate requests
+      o Simplified X509 name and attribute routines
+      o Initial (incomplete) support for international character sets
+      o New DH_METHOD, DSA_METHOD and enhanced RSA_METHOD
+      o Read only memory BIOs and simplified creation function
+      o TLS/SSL protocol bugfixes: Accept TLS 'client hello' in SSL 3.0
+        record; allow fragmentation and interleaving of handshake and other
+        data
+      o TLS/SSL code now "tolerates" MS SGC
+      o Work around for Netscape client certificate hang bug
+      o RSA_NULL option that removes RSA patent code but keeps other
+        RSA functionality
+      o Memory leak detection now allows applications to add extra information
+        via a per-thread stack
+      o PRNG robustness improved
+      o EGD support
+      o BIGNUM library bug fixes
+      o Faster DSA parameter generation
+      o Enhanced support for Alpha Linux
+      o Experimental MacOS support
+
+  Major changes between OpenSSL 0.9.3 and OpenSSL 0.9.4 [9 Aug 1999]:
+
+      o Transparent support for PKCS#8 format private keys: these are used
+        by several software packages and are more secure than the standard
+        form
+      o PKCS#5 v2.0 implementation
+      o Password callbacks have a new void * argument for application data
+      o Avoid various memory leaks
+      o New pipe-like BIO that allows using the SSL library when actual I/O
+        must be handled by the application (BIO pair)
+
+  Major changes between OpenSSL 0.9.2b and OpenSSL 0.9.3 [24 May 1999]:
+      o Lots of enhancements and cleanups to the Configuration mechanism
+      o RSA OEAP related fixes
+      o Added `openssl ca -revoke' option for revoking a certificate
+      o Source cleanups: const correctness, type-safe stacks and ASN.1 SETs
+      o Source tree cleanups: removed lots of obsolete files
+      o Thawte SXNet, certificate policies and CRL distribution points
+        extension support
+      o Preliminary (experimental) S/MIME support
+      o Support for ASN.1 UTF8String and VisibleString
+      o Full integration of PKCS#12 code
+      o Sparc assembler bignum implementation, optimized hash functions
+      o Option to disable selected ciphers
+
+  Major changes between OpenSSL 0.9.1c and OpenSSL 0.9.2b [22 Mar 1999]:
+      o Fixed a security hole related to session resumption
+      o Fixed RSA encryption routines for the p < q case
+      o "ALL" in cipher lists now means "everything except NULL ciphers"
+      o Support for Triple-DES CBCM cipher
+      o Support of Optimal Asymmetric Encryption Padding (OAEP) for RSA
+      o First support for new TLSv1 ciphers
+      o Added a few new BIOs (syslog BIO, reliable BIO)
+      o Extended support for DSA certificate/keys.
+      o Extended support for Certificate Signing Requests (CSR)
+      o Initial support for X.509v3 extensions
+      o Extended support for compression inside the SSL record layer
+      o Overhauled Win32 builds
+      o Cleanups and fixes to the Big Number (BN) library
+      o Support for ASN.1 GeneralizedTime
+      o Splitted ASN.1 SETs from SEQUENCEs
+      o ASN1 and PEM support for Netscape Certificate Sequences
+      o Overhauled Perl interface
+      o Lots of source tree cleanups.
+      o Lots of memory leak fixes.
+      o Lots of bug fixes.
+
+  Major changes between SSLeay 0.9.0b and OpenSSL 0.9.1c [23 Dec 1998]:
+      o Integration of the popular NO_RSA/NO_DSA patches
+      o Initial support for compression inside the SSL record layer
+      o Added BIO proxy and filtering functionality
+      o Extended Big Number (BN) library
+      o Added RIPE MD160 message digest
+      o Addeed support for RC2/64bit cipher
+      o Extended ASN.1 parser routines
+      o Adjustations of the source tree for CVS
+      o Support for various new platforms
+
Index: EcnlProtoTool/trunk/openssl-1.1.0e/NOTES.DJGPP
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/NOTES.DJGPP	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/NOTES.DJGPP	(revision 331)
@@ -0,0 +1,48 @@
+
+ 
+ INSTALLATION ON THE DOS PLATFORM WITH DJGPP
+ -------------------------------------------
+
+ OpenSSL has been ported to DJGPP, a Unix look-alike 32-bit run-time
+ environment for 16-bit DOS, but only with long filename support.
+ If you wish to compile on native DOS with 8+3 filenames, you will
+ have to tweak the installation yourself, including renaming files
+ with illegal or duplicate names.
+
+ You should have a full DJGPP environment installed, including the
+ latest versions of DJGPP, GCC, BINUTILS, BASH, etc. This package
+ requires that PERL and the PERL module Text::Template also be
+ installed (see NOTES.PERL).
+
+ All of these can be obtained from the usual DJGPP mirror sites or
+ directly at "http://www.delorie.com/pub/djgpp". For help on which
+ files to download, see the DJGPP "ZIP PICKER" page at
+ "http://www.delorie.com/djgpp/zip-picker.html". You also need to have
+ the WATT-32 networking package installed before you try to compile
+ OpenSSL. This can be obtained from "http://www.watt-32.net/".
+ The Makefile assumes that the WATT-32 code is in the directory
+ specified by the environment variable WATT_ROOT. If you have watt-32
+ in directory "watt32" under your main DJGPP directory, specify
+ WATT_ROOT="/dev/env/DJDIR/watt32".
+
+ To compile OpenSSL, start your BASH shell, then configure for DJGPP by
+ running "./Configure" with appropriate arguments:
+
+	./Configure no-threads --prefix=/dev/env/DJDIR DJGPP
+ 
+ And finally fire up "make". You may run out of DPMI selectors when
+ running in a DOS box under Windows. If so, just close the BASH
+ shell, go back to Windows, and restart BASH. Then run "make" again.
+
+ RUN-TIME CAVEAT LECTOR
+ --------------
+
+ Quoting FAQ:
+
+  "Cryptographic software needs a source of unpredictable data to work
+   correctly.  Many open source operating systems provide a "randomness
+   device" (/dev/urandom or /dev/random) that serves this purpose."
+
+ As of version 0.9.7f DJGPP port checks upon /dev/urandom$ for a 3rd
+ party "randomness" DOS driver. One such driver, NOISE.SYS, can be
+ obtained from "http://www.rahul.net/dkaufman/index.html".
Index: EcnlProtoTool/trunk/openssl-1.1.0e/NOTES.PERL
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/NOTES.PERL	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/NOTES.PERL	(revision 331)
@@ -0,0 +1,119 @@
+ TOC
+ ===
+
+ - Notes on Perl
+ - Notes on Perl on Windows
+ - Notes on Perl modules we use
+ - Notes on installing a perl module
+
+ Notes on Perl
+ -------------
+
+ For our scripts, we rely quite a bit on Perl, and increasingly on
+ some core Perl modules.  These Perl modules are part of the Perl
+ source, so if you build Perl on your own, you should be set.
+
+ However, if you install Perl as binary packages, the outcome might
+ differ, and you may have to check that you do get the core modules
+ installed properly.  We do not claim to know them all, but experience
+ has told us the following:
+
+ - on Linux distributions based on Debian, the package 'perl' will
+   install the core Perl modules as well, so you will be fine.
+ - on Linux distributions based on RPMs, you will need to install
+   'perl-core' rather than just 'perl'.
+
+ You MUST have at least Perl version 5.10.0 installed.  This minimum
+ requirement is due to our use of regexp backslash sequence \R among
+ other features that didn't exist in core Perl before that version.
+
+ Notes on Perl on Windows
+ ------------------------
+
+ There are a number of build targets that can be viewed as "Windows".
+ Indeed, there are VC-* configs targeting VisualStudio C, as well as
+ MinGW and Cygwin. The key recommendation is to use "matching" Perl,
+ one that matches build environment. For example, if you will build
+ on Cygwin be sure to use the Cygwin package manager to install Perl.
+ For MSYS builds use the MSYS provided Perl. For VC-* builds we
+ recommend ActiveState Perl, available from
+ http://www.activestate.com/ActivePerl.
+
+ Notes on Perl on VMS
+ --------------------
+
+ You will need to install Perl separately.  One way to do so is to
+ download the source from http://perl.org/, unpacking it, reading
+ README.vms and follow the instructions.  Another way is to download a
+ .PCSI file from http://www.vmsperl.com/ and install it using the
+ POLYCENTER install tool.
+
+ Notes on Perl modules we use
+ ----------------------------
+
+ We make increasing use of Perl modules, and do our best to limit
+ ourselves to core Perl modules to keep the requirements down.  There
+ are just a few exceptions:
+
+ Test::More         We require the minimum version to be 0.96, which
+                    appeared in Perl 5.13.4, because that version was
+                    the first to have all the features we're using.
+                    This module is required for testing only!  If you
+                    don't plan on running the tests, you don't need to
+                    bother with this one.
+
+ Text::Template     This module is not part of the core Perl modules.
+                    As a matter of fact, the core Perl modules do not
+                    include any templating module to date.
+                    This module is absolutely needed, configuration
+                    depends on it.
+
+ To avoid unnecessary initial hurdles, we have bundled a copy of the
+ following modules in our source.  They will work as fallbacks if
+ these modules aren't already installed on the system.
+
+    Text::Template
+
+ Notes on installing a perl module
+ ---------------------------------
+
+ There are a number of ways to install a perl module.  In all
+ descriptions below, Text::Template will server as an example.
+
+ 1. for Linux users, the easiest is to install with the use of your
+    favorite package manager.  Usually, all you need to do is search
+    for the module name and to install the package that comes up.
+
+    On Debian based Linux distributions, it would go like this:
+
+        $ apt-cache search Text::Template
+        ...
+        libtext-template-perl - perl module to process text templates
+        $ sudo apt-get install libtext-template-perl
+
+    Perl modules in Debian based distributions use package names like
+    the name of the module in question, with "lib" prepended and
+    "-perl" appended.
+
+ 2. Install using CPAN.  This is very easy, but usually requires root
+    access:
+
+        $ cpan -i Text::Template
+
+    Note that this runs all the tests that the module to be installed
+    comes with.  This is usually a smooth operation, but there are
+    platforms where a failure is indicated even though the actual tests
+    were successful.  Should that happen, you can force an
+    installation regardless (that should be safe since you've already
+    seen the tests succeed!):
+
+        $ cpan -f -i Text::Template
+
+    Note: on VMS, you must quote any argument that contains upper case
+    characters, so the lines above would be:
+
+        $ cpan -i "Text::Template"
+
+    and:
+
+        $ cpan -f -i "Text::Template"
Index: EcnlProtoTool/trunk/openssl-1.1.0e/NOTES.VMS
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/NOTES.VMS	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/NOTES.VMS	(revision 331)
@@ -0,0 +1,81 @@
+
+ NOTES FOR THE OPENVMS PLATFORM
+ ==============================
+
+ Requirement details
+ -------------------
+
+ In addition to the requirements and instructions listed in INSTALL,
+ this are required as well:
+
+  * At least ODS-5 disk organization for source and build.
+    Installation can be done on any existing disk organization.
+
+
+ About ANSI C compiler
+ ---------------------
+
+ An ANSI C compiled is needed among other things.  This means that
+ VAX C is not and will not be supported.
+
+ We have only tested with DEC C (a.k.a HP VMS C / VSI C) and require
+ version 7.1 or later.  Compiling with a different ANSI C compiler may
+ require some work.
+
+ Please avoid using C RTL feature logical names DECC$* when building
+ and testing OpenSSL.  Most of all, they can be disruptive when
+ running the tests, as they affect the Perl interpreter.
+
+
+ About ODS-5 directory names and Perl
+ ------------------------------------
+
+ It seems that the perl function canonpath() in the File::Spec module
+ doesn't treat file specifications where the last directory name
+ contains periods very well.  Unfortunately, some versions of VMS tar
+ will keep the periods in the OpenSSL source directory instead of
+ converting them to underscore, thereby leaving your source in
+ something like [.openssl-1^.1^.0].  This will lead to issues when
+ configuring and building OpenSSL.
+
+ We have no replacement for Perl's canonpath(), so the best workaround
+ for now is to rename the OpenSSL source directory, as follows (please
+ adjust for the actual source directory name you have):
+
+    $ rename openssl-1^.1^.0.DIR openssl-1_1_0.DIR 
+
+
+ About MMS and DCL
+ -----------------
+
+ MMS has certain limitations when it comes to line length, and DCL has
+ certain limitations when it comes to total command length.  We do
+ what we can to mitigate, but there is the possibility that it's not
+ enough.  Should you run into issues, a very simple solution is to set
+ yourself up a few logical names for the directory trees you're going
+ to use.
+
+
+ Checking the distribution
+ -------------------------
+
+ There have been reports of places where the distribution didn't quite
+ get through, for example if you've copied the tree from a NFS-mounted
+ Unix mount point.
+
+ The easiest way to check if everything got through as it should is to
+ check for one of the following files:
+
+   [.crypto]opensslconf^.h.in
+
+ The best way to get a correct distribution is to download the gzipped
+ tar file from ftp://ftp.openssl.org/source/, use GZIP -d to uncompress
+ it and VMSTAR to unpack the resulting tar file.
+
+ Gzip and VMSTAR are available here:
+
+   http://antinode.info/dec/index.html#Software
+
+ Should you need it, you can find UnZip for VMS here:
+
+   http://www.info-zip.org/UnZip.html
Index: EcnlProtoTool/trunk/openssl-1.1.0e/NOTES.WIN
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/NOTES.WIN	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/NOTES.WIN	(revision 331)
@@ -0,0 +1,138 @@
+
+ NOTES FOR THE WINDOWS PLATFORMS
+ ===============================
+
+ Requirement details for native (Visual C++) builds
+ --------------------------------------------------
+
+ In addition to the requirements and instructions listed in INSTALL,
+ this are required as well:
+
+ - You need Perl.  We recommend ActiveState Perl, available from
+   https://www.activestate.com/ActivePerl.
+   You also need the perl module Text::Template, available on CPAN.
+   Please read NOTES.PERL for more information.
+
+ - You need a C compiler.  OpenSSL has been tested to build with these:
+
+   * Visual C++
+
+ - Netwide Assembler, a.k.a. NASM, available from http://www.nasm.us,
+   is required if you intend to utilize assembler modules. Note that NASM
+   is the only supported assembler. The Microsoft provided assembler is NOT
+   supported.
+
+
+ Visual C++ (native Windows)
+ ---------------------------
+
+ Installation directories
+
+ The default installation directories are derived from environment
+ variables.
+
+ For VC-WIN32, the following defaults are use:
+
+     PREFIX:      %ProgramFiles(86)%\OpenSSL
+     OPENSSLDIR:  %CommonProgramFiles(86)%\SSL
+
+ For VC-WIN64, the following defaults are use:
+
+     PREFIX:      %ProgramW6432%\OpenSSL
+     OPENSSLDIR:  %CommonProgramW6432%\SSL
+
+ Should those environment variables not exist (on a pure Win32
+ installation for examples), these fallbacks are used:
+
+     PREFIX:      %ProgramFiles%\OpenSSL
+     OPENSSLDIR:  %CommonProgramFiles%\SSL
+
+ ALSO NOTE that those directories are usually write protected, even if
+ your account is in the Administrators group.  To work around that,
+ start the command prompt by right-clicking on it and choosing "Run as
+ Administrator" before running 'nmake install'.  The other solution
+ is, of course, to choose a different set of directories by using
+ --prefix and --openssldir when configuring.
+
+ GNU C (Cygwin)
+ --------------
+
+ Cygwin implements a Posix/Unix runtime system (cygwin1.dll) on top of the
+ Windows subsystem and provides a bash shell and GNU tools environment.
+ Consequently, a make of OpenSSL with Cygwin is virtually identical to the
+ Unix procedure.
+
+ To build OpenSSL using Cygwin, you need to:
+
+ * Install Cygwin (see https://cygwin.com/)
+
+ * Install Cygwin Perl and ensure it is in the path. Recall that
+   as least 5.10.0 is required.
+
+ * Run the Cygwin bash shell
+
+ Apart from that, follow the Unix instructions in INSTALL.
+
+ NOTE: "make test" and normal file operations may fail in directories
+ mounted as text (i.e. mount -t c:\somewhere /home) due to Cygwin
+ stripping of carriage returns. To avoid this ensure that a binary
+ mount is used, e.g. mount -b c:\somewhere /home.
+
+ It is also possible to create "conventional" Windows binaries that use
+ the Microsoft C runtime system (msvcrt.dll or crtdll.dll) using MinGW
+ development add-on for Cygwin. MinGW is supported even as a standalone
+ setup as described in the following section. In the context you should
+ recognize that binaries targeting Cygwin itself are not interchangeable
+ with "conventional" Windows binaries you generate with/for MinGW.
+
+
+ GNU C (MinGW/MSYS)
+ ------------------
+
+ * Compiler and shell environment installation:
+
+   MinGW and MSYS are available from http://www.mingw.org/, both are
+   required. Run the installers and do whatever magic they say it takes
+   to start MSYS bash shell with GNU tools and matching Perl on its PATH.
+   "Matching Perl" refers to chosen "shell environment", i.e. if built
+   under MSYS, then Perl compiled for MSYS must be used.
+
+   Alternatively, one can use MSYS2 from https://msys2.github.io/,
+   which includes MingW (32-bit and 64-bit).
+
+ * It is also possible to cross-compile it on Linux by configuring
+   with './Configure --cross-compile-prefix=i386-mingw32- mingw ...'.
+   Other possible cross compile prefixes include x86_64-w64-mingw32-
+   and i686-w64-mingw32-.
+
+
+ Linking your application
+ ------------------------
+
+ This section applies to non-Cygwin builds.
+
+ If you link with static OpenSSL libraries then you're expected to
+ additionally link your application with WS2_32.LIB, GDI32.LIB,
+ ADVAPI32.LIB, CRYPT32.LIB and USER32.LIB. Those developing
+ non-interactive service applications might feel concerned about
+ linking with GDI32.LIB and USER32.LIB, as they are justly associated
+ with interactive desktop, which is not available to service
+ processes. The toolkit is designed to detect in which context it's
+ currently executed, GUI, console app or service, and act accordingly,
+ namely whether or not to actually make GUI calls. Additionally those
+ who wish to /DELAYLOAD:GDI32.DLL and /DELAYLOAD:USER32.DLL and
+ actually keep them off service process should consider implementing
+ and exporting from .exe image in question own _OPENSSL_isservice not
+ relying on USER32.DLL. E.g., on Windows Vista and later you could:
+
+	__declspec(dllexport) __cdecl BOOL _OPENSSL_isservice(void)
+	{   DWORD sess;
+	    if (ProcessIdToSessionId(GetCurrentProcessId(),&sess))
+	        return sess==0;
+	    return FALSE;
+	}
+
+ If you link with OpenSSL .DLLs, then you're expected to include into
+ your application code small "shim" snippet, which provides glue between
+ OpenSSL BIO layer and your compiler run-time. See the OPENSSL_Applink
+ manual page for further details.
Index: EcnlProtoTool/trunk/openssl-1.1.0e/README
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/README	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/README	(revision 331)
@@ -0,0 +1,94 @@
+
+ OpenSSL 1.1.0e 16 Feb 2017
+
+ Copyright (c) 1998-2016 The OpenSSL Project
+ Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
+ All rights reserved.
+
+ DESCRIPTION
+ -----------
+
+ The OpenSSL Project is a collaborative effort to develop a robust,
+ commercial-grade, fully featured, and Open Source toolkit implementing the
+ Transport Layer Security (TLS) protocols (including SSLv3) as well as a
+ full-strength general purpose cryptographic library.
+
+ OpenSSL is descended from the SSLeay library developed by Eric A. Young
+ and Tim J. Hudson.  The OpenSSL toolkit is licensed under a dual-license (the
+ OpenSSL license plus the SSLeay license), which means that you are free to
+ get and use it for commercial and non-commercial purposes as long as you
+ fulfill the conditions of both licenses.
+
+ OVERVIEW
+ --------
+
+ The OpenSSL toolkit includes:
+
+ libssl (with platform specific naming):
+     Provides the client and server-side implementations for SSLv3 and TLS.
+
+ libcrypto (with platform specific naming):
+     Provides general cryptographic and X.509 support needed by SSL/TLS but
+     not logically part of it.
+
+ openssl:
+     A command line tool that can be used for:
+        Creation of key parameters
+        Creation of X.509 certificates, CSRs and CRLs
+        Calculation of message digests
+        Encryption and decryption
+        SSL/TLS client and server tests
+        Handling of S/MIME signed or encrypted mail
+        And more...
+
+ INSTALLATION
+ ------------
+
+ See the appropriate file:
+        INSTALL         Linux, Unix, Windows, OpenVMS, ...
+        NOTES.*         INSTALL addendums for different platforms
+
+ SUPPORT
+ -------
+
+ See the OpenSSL website www.openssl.org for details on how to obtain
+ commercial technical support. Free community support is available through the
+ openssl-users email list (see
+ https://www.openssl.org/community/mailinglists.html for further details).
+
+ If you have any problems with OpenSSL then please take the following steps
+ first:
+
+    - Download the latest version from the repository
+      to see if the problem has already been addressed
+    - Configure with no-asm
+    - Remove compiler optimisation flags
+
+ If you wish to report a bug then please include the following information
+ and create an issue on GitHub:
+
+    - OpenSSL version: output of 'openssl version -a'
+    - Any "Configure" options that you selected during compilation of the
+      library if applicable (see INSTALL)
+    - OS Name, Version, Hardware platform
+    - Compiler Details (name, version)
+    - Application Details (name, version)
+    - Problem Description (steps that will reproduce the problem, if known)
+    - Stack Traceback (if the application dumps core)
+
+ Just because something doesn't work the way you expect does not mean it
+ is necessarily a bug in OpenSSL. Use the openssl-users email list for this type
+ of query.
+
+ HOW TO CONTRIBUTE TO OpenSSL
+ ----------------------------
+
+ See CONTRIBUTING
+
+ LEGALITIES
+ ----------
+
+ A number of nations restrict the use or export of cryptography. If you
+ are potentially subject to such restrictions you should seek competent
+ professional legal advice before attempting to develop or distribute
+ cryptographic code.
Index: EcnlProtoTool/trunk/openssl-1.1.0e/README.ECC
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/README.ECC	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/README.ECC	(revision 331)
@@ -0,0 +1,61 @@
+NOTE: The OpenSSL Software Foundation has executed a sublicense agreement
+entitled "Elliptic Curve Cryptography Patent License Agreement" with the
+National Security Agency/ Central Security Service Commercial Solutions
+Center (NCSC) dated 2010-11-04. That agreement permits implementation and
+distribution of software containing features covered by any or all of the
+following patents:
+
+1.) U.S. Pat. No. 5,761,305 entitled "Key Agreement and Transport Protocol 
+    with Implicit Signatures" issued on June 2, 1998;
+2.) Can. Pat. Appl. Ser. No. 2176972 entitled "Key Agreement and Transport 
+    Protocol with Implicit Signature and Reduced Bandwidth" filed on May 
+    16, 1996;
+3.) U.S. Pat. No. 5,889,865 entitled "Key Agreement and Transport Protocol 
+    with Implicit Signatures" issued on March 30, 1999;
+4.) U.S. Pat. No. 5,896,455 entitled "Key Agreement and Transport Protocol 
+    with Implicit Signatures" issued on April 20, 1999;
+5.) U.S. Pat. No. 5,933,504 entitled "Strengthened Public Key Protocol" 
+    issued on August 3, 1999;
+6.) Can. Pat. Appl. Ser. No. 2176866 entitled "Strengthened Public Key 
+    Protocol" filed on May 17, 1996;
+7.) E.P. Pat. Appl. Ser. No. 96201322.3 entitled "Strengthened Public Key 
+    Protocol" filed on May 17, 1996;
+8.) U.S. Pat. No. 5,999,626 entitled "Digital Signatures on a Smartcard" 
+    issued on December 7, 1999;
+9.) Can. Pat. Appl. Ser. No. 2202566 entitled "Digital Signatures on a 
+    Smartcard" filed on April 14, 1997;
+10.) E.P. Pat. Appl. No. 97106114.8 entitled "Digital Signatures on a 
+     Smartcard" filed on April 15, 1997;
+11.) U.S Pat. No. 6,122,736 entitled "Key Agreement and Transport Protocol 
+     with Implicit Signatures" issued on September 19, 2000;
+12.) Can. Pat. Appl. Ser. No. 2174261 entitled "Key Agreement and Transport 
+     Protocol with Implicit Signatures" filed on April 16, 1996;
+13.) E.P. Pat. Appl. Ser. No. 96105920.1 entitled "Key Agreement and 
+     Transport Protocol with Implicit Signatures" filed on April 16, 1996;
+14.) U.S. Pat. No. 6,141,420 entitled "Elliptic Curve Encryption Systems" 
+     issued on October 31, 2000;
+15.) Can. Pat. Appl. Ser. No. 2155038 entitled "Elliptic Curve Encryption 
+     Systems" filed on July 31, 1995;
+16.) E.P. Pat. Appl. Ser. No. 95926348.4 entitled "Elliptic Curve Encryption 
+     Systems" filed on July 31, 1995;
+17.) U.S. Pat. No. 6,336,188 entitled "Authenticated Key Agreement" issued 
+     on January 1, 2002;
+18.) U.S. Pat. No. 6,487,661 entitled "Key Agreement and Transport Protocol" 
+     issued on November 26, 2002;
+19.) Can. Pat. Appl. Ser. No. 2174260 entitled "Key Agreement and Transport 
+     Protocol" filed on April 16, 1996;
+20.) E.P. Pat. Appl. Ser. No. 96105921.9 entitled "Key Agreement and 
+     Transport Protocol" filed on April 21, 1996;
+21.) U.S. Pat. No. 6,563,928 entitled "Strengthened Public Key Protocol" 
+     issued on May 13, 2003;
+22.) U.S. Pat. No. 6,618,483 entitled "Elliptic Curve Encryption Systems" 
+     issued September 9, 2003;
+23.) U.S. Pat. Appl. Ser. No. 09/434,247 entitled "Digital Signatures on a 
+     Smartcard" filed on November 5, 1999;
+24.) U.S. Pat. Appl. Ser. No. 09/558,256 entitled "Key Agreement and 
+     Transport Protocol with Implicit Signatures" filed on April 25, 2000;
+25.) U.S. Pat. Appl. Ser. No. 09/942,492 entitled "Digital Signatures on a 
+     Smartcard" filed on August 29, 2001 and published on July 18, 2002; and,
+26.) U.S. Pat. Appl. Ser. No. 10/185,735 entitled "Strengthened Public Key 
+     Protocol" filed on July 1, 2000.
+
Index: EcnlProtoTool/trunk/openssl-1.1.0e/README.ENGINE
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/README.ENGINE	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/README.ENGINE	(revision 331)
@@ -0,0 +1,288 @@
+  ENGINE
+  ======
+
+  With OpenSSL 0.9.6, a new component was added to support alternative
+  cryptography implementations, most commonly for interfacing with external
+  crypto devices (eg. accelerator cards). This component is called ENGINE,
+  and its presence in OpenSSL 0.9.6 (and subsequent bug-fix releases)
+  caused a little confusion as 0.9.6** releases were rolled in two
+  versions, a "standard" and an "engine" version. In development for 0.9.7,
+  the ENGINE code has been merged into the main branch and will be present
+  in the standard releases from 0.9.7 forwards.
+
+  There are currently built-in ENGINE implementations for the following
+  crypto devices:
+
+      o Cryptodev
+      o Microsoft CryptoAPI
+      o VIA Padlock
+      o nCipher CHIL
+
+  In addition, dynamic binding to external ENGINE implementations is now
+  provided by a special ENGINE called "dynamic". See the "DYNAMIC ENGINE"
+  section below for details.
+
+  At this stage, a number of things are still needed and are being worked on:
+
+      1 Integration of EVP support.
+      2 Configuration support.
+      3 Documentation!
+
+1 With respect to EVP, this relates to support for ciphers and digests in
+  the ENGINE model so that alternative implementations of existing
+  algorithms/modes (or previously unimplemented ones) can be provided by
+  ENGINE implementations.
+
+2 Configuration support currently exists in the ENGINE API itself, in the
+  form of "control commands". These allow an application to expose to the
+  user/admin the set of commands and parameter types a given ENGINE
+  implementation supports, and for an application to directly feed string
+  based input to those ENGINEs, in the form of name-value pairs. This is an
+  extensible way for ENGINEs to define their own "configuration" mechanisms
+  that are specific to a given ENGINE (eg. for a particular hardware
+  device) but that should be consistent across *all* OpenSSL-based
+  applications when they use that ENGINE. Work is in progress (or at least
+  in planning) for supporting these control commands from the CONF (or
+  NCONF) code so that applications using OpenSSL's existing configuration
+  file format can have ENGINE settings specified in much the same way.
+  Presently however, applications must use the ENGINE API itself to provide
+  such functionality. To see first hand the types of commands available
+  with the various compiled-in ENGINEs (see further down for dynamic
+  ENGINEs), use the "engine" openssl utility with full verbosity, ie;
+       openssl engine -vvvv
+
+3 Documentation? Volunteers welcome! The source code is reasonably well
+  self-documenting, but some summaries and usage instructions are needed -
+  moreover, they are needed in the same POD format the existing OpenSSL
+  documentation is provided in. Any complete or incomplete contributions
+  would help make this happen.
+
+  STABILITY & BUG-REPORTS
+  =======================
+
+  What already exists is fairly stable as far as it has been tested, but
+  the test base has been a bit small most of the time. For the most part,
+  the vendors of the devices these ENGINEs support have contributed to the
+  development and/or testing of the implementations, and *usually* (with no
+  guarantees) have experience in using the ENGINE support to drive their
+  devices from common OpenSSL-based applications. Bugs and/or inexplicable
+  behaviour in using a specific ENGINE implementation should be sent to the
+  author of that implementation (if it is mentioned in the corresponding C
+  file), and in the case of implementations for commercial hardware
+  devices, also through whatever vendor support channels are available.  If
+  none of this is possible, or the problem seems to be something about the
+  ENGINE API itself (ie. not necessarily specific to a particular ENGINE
+  implementation) then you should mail complete details to the relevant
+  OpenSSL mailing list. For a definition of "complete details", refer to
+  the OpenSSL "README" file. As for which list to send it to;
+
+     openssl-users: if you are *using* the ENGINE abstraction, either in an
+          pre-compiled application or in your own application code.
+
+     openssl-dev: if you are discussing problems with OpenSSL source code.
+
+  USAGE
+  =====
+
+  The default "openssl" ENGINE is always chosen when performing crypto
+  operations unless you specify otherwise. You must actively tell the
+  openssl utility commands to use anything else through a new command line
+  switch called "-engine". Also, if you want to use the ENGINE support in
+  your own code to do something similar, you must likewise explicitly
+  select the ENGINE implementation you want.
+
+  Depending on the type of hardware, system, and configuration, "settings"
+  may need to be applied to an ENGINE for it to function as expected/hoped.
+  The recommended way of doing this is for the application to support
+  ENGINE "control commands" so that each ENGINE implementation can provide
+  whatever configuration primitives it might require and the application
+  can allow the user/admin (and thus the hardware vendor's support desk
+  also) to provide any such input directly to the ENGINE implementation.
+  This way, applications do not need to know anything specific to any
+  device, they only need to provide the means to carry such user/admin
+  input through to the ENGINE in question. Ie. this connects *you* (and
+  your helpdesk) to the specific ENGINE implementation (and device), and
+  allows application authors to not get buried in hassle supporting
+  arbitrary devices they know (and care) nothing about.
+
+  A new "openssl" utility, "openssl engine", has been added in that allows
+  for testing and examination of ENGINE implementations. Basic usage
+  instructions are available by specifying the "-?" command line switch.
+
+  DYNAMIC ENGINES
+  ===============
+
+  The new "dynamic" ENGINE provides a low-overhead way to support ENGINE
+  implementations that aren't pre-compiled and linked into OpenSSL-based
+  applications. This could be because existing compiled-in implementations
+  have known problems and you wish to use a newer version with an existing
+  application. It could equally be because the application (or OpenSSL
+  library) you are using simply doesn't have support for the ENGINE you
+  wish to use, and the ENGINE provider (eg. hardware vendor) is providing
+  you with a self-contained implementation in the form of a shared-library.
+  The other use-case for "dynamic" is with applications that wish to
+  maintain the smallest foot-print possible and so do not link in various
+  ENGINE implementations from OpenSSL, but instead leaves you to provide
+  them, if you want them, in the form of "dynamic"-loadable
+  shared-libraries. It should be possible for hardware vendors to provide
+  their own shared-libraries to support arbitrary hardware to work with
+  applications based on OpenSSL 0.9.7 or later. If you're using an
+  application based on 0.9.7 (or later) and the support you desire is only
+  announced for versions later than the one you need, ask the vendor to
+  backport their ENGINE to the version you need.
+
+  How does "dynamic" work?
+  ------------------------
+    The dynamic ENGINE has a special flag in its implementation such that
+    every time application code asks for the 'dynamic' ENGINE, it in fact
+    gets its own copy of it. As such, multi-threaded code (or code that
+    multiplexes multiple uses of 'dynamic' in a single application in any
+    way at all) does not get confused by 'dynamic' being used to do many
+    independent things. Other ENGINEs typically don't do this so there is
+    only ever 1 ENGINE structure of its type (and reference counts are used
+    to keep order). The dynamic ENGINE itself provides absolutely no
+    cryptographic functionality, and any attempt to "initialise" the ENGINE
+    automatically fails. All it does provide are a few "control commands"
+    that can be used to control how it will load an external ENGINE
+    implementation from a shared-library. To see these control commands,
+    use the command-line;
+
+       openssl engine -vvvv dynamic
+
+    The "SO_PATH" control command should be used to identify the
+    shared-library that contains the ENGINE implementation, and "NO_VCHECK"
+    might possibly be useful if there is a minor version conflict and you
+    (or a vendor helpdesk) is convinced you can safely ignore it.
+    "ID" is probably only needed if a shared-library implements
+    multiple ENGINEs, but if you know the engine id you expect to be using,
+    it doesn't hurt to specify it (and this provides a sanity check if
+    nothing else). "LIST_ADD" is only required if you actually wish the
+    loaded ENGINE to be discoverable by application code later on using the
+    ENGINE's "id". For most applications, this isn't necessary - but some
+    application authors may have nifty reasons for using it. The "LOAD"
+    command is the only one that takes no parameters and is the command
+    that uses the settings from any previous commands to actually *load*
+    the shared-library ENGINE implementation. If this command succeeds, the
+    (copy of the) 'dynamic' ENGINE will magically morph into the ENGINE
+    that has been loaded from the shared-library. As such, any control
+    commands supported by the loaded ENGINE could then be executed as per
+    normal. Eg. if ENGINE "foo" is implemented in the shared-library
+    "libfoo.so" and it supports some special control command "CMD_FOO", the
+    following code would load and use it (NB: obviously this code has no
+    error checking);
+
+       ENGINE *e = ENGINE_by_id("dynamic");
+       ENGINE_ctrl_cmd_string(e, "SO_PATH", "/lib/libfoo.so", 0);
+       ENGINE_ctrl_cmd_string(e, "ID", "foo", 0);
+       ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0);
+       ENGINE_ctrl_cmd_string(e, "CMD_FOO", "some input data", 0);
+
+    For testing, the "openssl engine" utility can be useful for this sort
+    of thing. For example the above code excerpt would achieve much the
+    same result as;
+
+       openssl engine dynamic \
+                 -pre SO_PATH:/lib/libfoo.so \
+                 -pre ID:foo \
+                 -pre LOAD \
+                 -pre "CMD_FOO:some input data"
+
+    Or to simply see the list of commands supported by the "foo" ENGINE;
+
+       openssl engine -vvvv dynamic \
+                 -pre SO_PATH:/lib/libfoo.so \
+                 -pre ID:foo \
+                 -pre LOAD
+
+    Applications that support the ENGINE API and more specifically, the
+    "control commands" mechanism, will provide some way for you to pass
+    such commands through to ENGINEs. As such, you would select "dynamic"
+    as the ENGINE to use, and the parameters/commands you pass would
+    control the *actual* ENGINE used. Each command is actually a name-value
+    pair and the value can sometimes be omitted (eg. the "LOAD" command).
+    Whilst the syntax demonstrated in "openssl engine" uses a colon to
+    separate the command name from the value, applications may provide
+    their own syntax for making that separation (eg. a win32 registry
+    key-value pair may be used by some applications). The reason for the
+    "-pre" syntax in the "openssl engine" utility is that some commands
+    might be issued to an ENGINE *after* it has been initialised for use.
+    Eg. if an ENGINE implementation requires a smart-card to be inserted
+    during initialisation (or a PIN to be typed, or whatever), there may be
+    a control command you can issue afterwards to "forget" the smart-card
+    so that additional initialisation is no longer possible. In
+    applications such as web-servers, where potentially volatile code may
+    run on the same host system, this may provide some arguable security
+    value. In such a case, the command would be passed to the ENGINE after
+    it has been initialised for use, and so the "-post" switch would be
+    used instead. Applications may provide a different syntax for
+    supporting this distinction, and some may simply not provide it at all
+    ("-pre" is almost always what you're after, in reality).
+
+  How do I build a "dynamic" ENGINE?
+  ----------------------------------
+    This question is trickier - currently OpenSSL bundles various ENGINE
+    implementations that are statically built in, and any application that
+    calls the "ENGINE_load_builtin_engines()" function will automatically
+    have all such ENGINEs available (and occupying memory). Applications
+    that don't call that function have no ENGINEs available like that and
+    would have to use "dynamic" to load any such ENGINE - but on the other
+    hand such applications would only have the memory footprint of any
+    ENGINEs explicitly loaded using user/admin provided control commands.
+    The main advantage of not statically linking ENGINEs and only using
+    "dynamic" for hardware support is that any installation using no
+    "external" ENGINE suffers no unnecessary memory footprint from unused
+    ENGINEs. Likewise, installations that do require an ENGINE incur the
+    overheads from only *that* ENGINE once it has been loaded.
+
+    Sounds good? Maybe, but currently building an ENGINE implementation as
+    a shared-library that can be loaded by "dynamic" isn't automated in
+    OpenSSL's build process. It can be done manually quite easily however.
+    Such a shared-library can either be built with any OpenSSL code it
+    needs statically linked in, or it can link dynamically against OpenSSL
+    if OpenSSL itself is built as a shared library. The instructions are
+    the same in each case, but in the former (statically linked any
+    dependencies on OpenSSL) you must ensure OpenSSL is built with
+    position-independent code ("PIC"). The default OpenSSL compilation may
+    already specify the relevant flags to do this, but you should consult
+    with your compiler documentation if you are in any doubt.
+
+    This example will show building the "atalla" ENGINE in the
+    crypto/engine/ directory as a shared-library for use via the "dynamic"
+    ENGINE.
+    1) "cd" to the crypto/engine/ directory of a pre-compiled OpenSSL
+       source tree.
+    2) Recompile at least one source file so you can see all the compiler
+       flags (and syntax) being used to build normally. Eg;
+           touch hw_atalla.c ; make
+       will rebuild "hw_atalla.o" using all such flags.
+    3) Manually enter the same compilation line to compile the
+       "hw_atalla.c" file but with the following two changes;
+         (a) add "-DENGINE_DYNAMIC_SUPPORT" to the command line switches,
+	 (b) change the output file from "hw_atalla.o" to something new,
+             eg. "tmp_atalla.o"
+    4) Link "tmp_atalla.o" into a shared-library using the top-level
+       OpenSSL libraries to resolve any dependencies. The syntax for doing
+       this depends heavily on your system/compiler and is a nightmare
+       known well to anyone who has worked with shared-library portability
+       before. 'gcc' on Linux, for example, would use the following syntax;
+          gcc -shared -o dyn_atalla.so tmp_atalla.o -L../.. -lcrypto
+    5) Test your shared library using "openssl engine" as explained in the
+       previous section. Eg. from the top-level directory, you might try;
+          apps/openssl engine -vvvv dynamic \
+              -pre SO_PATH:./crypto/engine/dyn_atalla.so -pre LOAD
+       If the shared-library loads successfully, you will see both "-pre"
+       commands marked as "SUCCESS" and the list of control commands
+       displayed (because of "-vvvv") will be the control commands for the
+       *atalla* ENGINE (ie. *not* the 'dynamic' ENGINE). You can also add
+       the "-t" switch to the utility if you want it to try and initialise
+       the atalla ENGINE for use to test any possible hardware/driver
+       issues.
+
+  PROBLEMS
+  ========
+
+  It seems like the ENGINE part doesn't work too well with CryptoSwift on Win32.
+  A quick test done right before the release showed that trying "openssl speed
+  -engine cswift" generated errors. If the DSO gets enabled, an attempt is made
+  to write at memory address 0x00000002.
+
Index: EcnlProtoTool/trunk/openssl-1.1.0e/README.FIPS
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/README.FIPS	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/README.FIPS	(revision 331)
@@ -0,0 +1,1 @@
+This release does not support a FIPS 140-2 validated module.
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/app_rand.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/app_rand.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/app_rand.c	(revision 331)
@@ -0,0 +1,115 @@
+/*
+ * Copyright 1995-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 "apps.h"
+#include <openssl/bio.h>
+#include <openssl/rand.h>
+
+static int seeded = 0;
+static int egdsocket = 0;
+
+int app_RAND_load_file(const char *file, int dont_warn)
+{
+    int consider_randfile = (file == NULL);
+    char buffer[200];
+
+    if (file == NULL)
+        file = RAND_file_name(buffer, sizeof buffer);
+#ifndef OPENSSL_NO_EGD
+    else if (RAND_egd(file) > 0) {
+        /*
+         * we try if the given filename is an EGD socket. if it is, we don't
+         * write anything back to the file.
+         */
+        egdsocket = 1;
+        return 1;
+    }
+#endif
+    if (file == NULL || !RAND_load_file(file, -1)) {
+        if (RAND_status() == 0) {
+            if (!dont_warn) {
+                BIO_printf(bio_err, "unable to load 'random state'\n");
+                BIO_printf(bio_err,
+                           "This means that the random number generator has not been seeded\n");
+                BIO_printf(bio_err, "with much random data.\n");
+                if (consider_randfile) { /* explanation does not apply when a
+                                          * file is explicitly named */
+                    BIO_printf(bio_err,
+                               "Consider setting the RANDFILE environment variable to point at a file that\n");
+                    BIO_printf(bio_err,
+                               "'random' data can be kept in (the file will be overwritten).\n");
+                }
+            }
+            return 0;
+        }
+    }
+    seeded = 1;
+    return 1;
+}
+
+long app_RAND_load_files(char *name)
+{
+    char *p, *n;
+    int last;
+    long tot = 0;
+#ifndef OPENSSL_NO_EGD
+    int egd;
+#endif
+
+    for (;;) {
+        last = 0;
+        for (p = name; ((*p != '\0') && (*p != LIST_SEPARATOR_CHAR)); p++) ;
+        if (*p == '\0')
+            last = 1;
+        *p = '\0';
+        n = name;
+        name = p + 1;
+        if (*n == '\0')
+            break;
+
+#ifndef OPENSSL_NO_EGD
+        egd = RAND_egd(n);
+        if (egd > 0)
+            tot += egd;
+        else
+#endif
+            tot += RAND_load_file(n, -1);
+        if (last)
+            break;
+    }
+    if (tot > 512)
+        app_RAND_allow_write_file();
+    return (tot);
+}
+
+int app_RAND_write_file(const char *file)
+{
+    char buffer[200];
+
+    if (egdsocket || !seeded)
+        /*
+         * If we did not manage to read the seed file, we should not write a
+         * low-entropy seed file back -- it would suppress a crucial warning
+         * the next time we want to use it.
+         */
+        return 0;
+
+    if (file == NULL)
+        file = RAND_file_name(buffer, sizeof buffer);
+    if (file == NULL || !RAND_write_file(file)) {
+        BIO_printf(bio_err, "unable to write 'random state'\n");
+        return 0;
+    }
+    return 1;
+}
+
+void app_RAND_allow_write_file(void)
+{
+    seeded = 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/apps.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/apps.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/apps.c	(revision 331)
@@ -0,0 +1,2653 @@
+/*
+ * Copyright 1995-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
+ */
+
+#if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
+/*
+ * On VMS, you need to define this to get the declaration of fileno().  The
+ * value 2 is to make sure no function defined in POSIX-2 is left undefined.
+ */
+# define _POSIX_C_SOURCE 2
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifndef OPENSSL_NO_POSIX_IO
+# include <sys/stat.h>
+# include <fcntl.h>
+#endif
+#include <ctype.h>
+#include <errno.h>
+#include <openssl/err.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/pem.h>
+#include <openssl/pkcs12.h>
+#include <openssl/ui.h>
+#include <openssl/safestack.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#include <openssl/bn.h>
+#include <openssl/ssl.h>
+#include "s_apps.h"
+#include "apps.h"
+
+#ifdef _WIN32
+static int WIN32_rename(const char *from, const char *to);
+# define rename(from,to) WIN32_rename((from),(to))
+#endif
+
+typedef struct {
+    const char *name;
+    unsigned long flag;
+    unsigned long mask;
+} NAME_EX_TBL;
+
+#if !defined(OPENSSL_NO_UI) || !defined(OPENSSL_NO_ENGINE)
+static UI_METHOD *ui_method = NULL;
+#endif
+
+static int set_table_opts(unsigned long *flags, const char *arg,
+                          const NAME_EX_TBL * in_tbl);
+static int set_multi_opts(unsigned long *flags, const char *arg,
+                          const NAME_EX_TBL * in_tbl);
+
+int app_init(long mesgwin);
+
+int chopup_args(ARGS *arg, char *buf)
+{
+    int quoted;
+    char c = '\0', *p = NULL;
+
+    arg->argc = 0;
+    if (arg->size == 0) {
+        arg->size = 20;
+        arg->argv = app_malloc(sizeof(*arg->argv) * arg->size, "argv space");
+    }
+
+    for (p = buf;;) {
+        /* Skip whitespace. */
+        while (*p && isspace(_UC(*p)))
+            p++;
+        if (!*p)
+            break;
+
+        /* The start of something good :-) */
+        if (arg->argc >= arg->size) {
+            char **tmp;
+            arg->size += 20;
+            tmp = OPENSSL_realloc(arg->argv, sizeof(*arg->argv) * arg->size);
+            if (tmp == NULL)
+                return 0;
+            arg->argv = tmp;
+        }
+        quoted = *p == '\'' || *p == '"';
+        if (quoted)
+            c = *p++;
+        arg->argv[arg->argc++] = p;
+
+        /* now look for the end of this */
+        if (quoted) {
+            while (*p && *p != c)
+                p++;
+            *p++ = '\0';
+        } else {
+            while (*p && !isspace(_UC(*p)))
+                p++;
+            if (*p)
+                *p++ = '\0';
+        }
+    }
+    arg->argv[arg->argc] = NULL;
+    return (1);
+}
+
+#ifndef APP_INIT
+int app_init(long mesgwin)
+{
+    return (1);
+}
+#endif
+
+int ctx_set_verify_locations(SSL_CTX *ctx, const char *CAfile,
+                             const char *CApath, int noCAfile, int noCApath)
+{
+    if (CAfile == NULL && CApath == NULL) {
+        if (!noCAfile && SSL_CTX_set_default_verify_file(ctx) <= 0)
+            return 0;
+        if (!noCApath && SSL_CTX_set_default_verify_dir(ctx) <= 0)
+            return 0;
+
+        return 1;
+    }
+    return SSL_CTX_load_verify_locations(ctx, CAfile, CApath);
+}
+
+#ifndef OPENSSL_NO_CT
+
+int ctx_set_ctlog_list_file(SSL_CTX *ctx, const char *path)
+{
+    if (path == NULL) {
+        return SSL_CTX_set_default_ctlog_list_file(ctx);
+    }
+
+    return SSL_CTX_set_ctlog_list_file(ctx, path);
+}
+
+#endif
+
+int dump_cert_text(BIO *out, X509 *x)
+{
+    char *p;
+
+    p = X509_NAME_oneline(X509_get_subject_name(x), NULL, 0);
+    BIO_puts(out, "subject=");
+    BIO_puts(out, p);
+    OPENSSL_free(p);
+
+    p = X509_NAME_oneline(X509_get_issuer_name(x), NULL, 0);
+    BIO_puts(out, "\nissuer=");
+    BIO_puts(out, p);
+    BIO_puts(out, "\n");
+    OPENSSL_free(p);
+
+    return 0;
+}
+
+#ifndef OPENSSL_NO_UI
+static int ui_open(UI *ui)
+{
+    return UI_method_get_opener(UI_OpenSSL())(ui);
+}
+
+static int ui_read(UI *ui, UI_STRING *uis)
+{
+    if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
+        && UI_get0_user_data(ui)) {
+        switch (UI_get_string_type(uis)) {
+        case UIT_PROMPT:
+        case UIT_VERIFY:
+            {
+                const char *password =
+                    ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
+                if (password && password[0] != '\0') {
+                    UI_set_result(ui, uis, password);
+                    return 1;
+                }
+            }
+        default:
+            break;
+        }
+    }
+    return UI_method_get_reader(UI_OpenSSL())(ui, uis);
+}
+
+static int ui_write(UI *ui, UI_STRING *uis)
+{
+    if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
+        && UI_get0_user_data(ui)) {
+        switch (UI_get_string_type(uis)) {
+        case UIT_PROMPT:
+        case UIT_VERIFY:
+            {
+                const char *password =
+                    ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
+                if (password && password[0] != '\0')
+                    return 1;
+            }
+        default:
+            break;
+        }
+    }
+    return UI_method_get_writer(UI_OpenSSL())(ui, uis);
+}
+
+static int ui_close(UI *ui)
+{
+    return UI_method_get_closer(UI_OpenSSL())(ui);
+}
+
+int setup_ui_method(void)
+{
+    ui_method = UI_create_method("OpenSSL application user interface");
+    UI_method_set_opener(ui_method, ui_open);
+    UI_method_set_reader(ui_method, ui_read);
+    UI_method_set_writer(ui_method, ui_write);
+    UI_method_set_closer(ui_method, ui_close);
+    return 0;
+}
+
+void destroy_ui_method(void)
+{
+    if (ui_method) {
+        UI_destroy_method(ui_method);
+        ui_method = NULL;
+    }
+}
+#endif
+
+int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp)
+{
+    int res = 0;
+#ifndef OPENSSL_NO_UI
+    UI *ui = NULL;
+#endif
+    PW_CB_DATA *cb_data = (PW_CB_DATA *)cb_tmp;
+
+#ifdef OPENSSL_NO_UI
+    if (cb_data != NULL && cb_data->password != NULL) {
+        res = strlen(cb_data->password);
+        if (res > bufsiz)
+            res = bufsiz;
+        memcpy(buf, cb_data->password, res);
+    }
+#else
+    ui = UI_new_method(ui_method);
+    if (ui) {
+        int ok = 0;
+        char *buff = NULL;
+        int ui_flags = 0;
+        const char *prompt_info = NULL;
+        char *prompt;
+
+        if (cb_data != NULL && cb_data->prompt_info != NULL)
+            prompt_info = cb_data->prompt_info;
+        prompt = UI_construct_prompt(ui, "pass phrase", prompt_info);
+        if (!prompt) {
+            BIO_printf(bio_err, "Out of memory\n");
+            UI_free(ui);
+            return 0;
+        }
+
+        ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
+        UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
+
+        /* We know that there is no previous user data to return to us */
+        (void)UI_add_user_data(ui, cb_data);
+
+        if (ok >= 0)
+            ok = UI_add_input_string(ui, prompt, ui_flags, buf,
+                                     PW_MIN_LENGTH, bufsiz - 1);
+        if (ok >= 0 && verify) {
+            buff = app_malloc(bufsiz, "password buffer");
+            ok = UI_add_verify_string(ui, prompt, ui_flags, buff,
+                                      PW_MIN_LENGTH, bufsiz - 1, buf);
+        }
+        if (ok >= 0)
+            do {
+                ok = UI_process(ui);
+            }
+            while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
+
+        OPENSSL_clear_free(buff, (unsigned int)bufsiz);
+
+        if (ok >= 0)
+            res = strlen(buf);
+        if (ok == -1) {
+            BIO_printf(bio_err, "User interface error\n");
+            ERR_print_errors(bio_err);
+            OPENSSL_cleanse(buf, (unsigned int)bufsiz);
+            res = 0;
+        }
+        if (ok == -2) {
+            BIO_printf(bio_err, "aborted!\n");
+            OPENSSL_cleanse(buf, (unsigned int)bufsiz);
+            res = 0;
+        }
+        UI_free(ui);
+        OPENSSL_free(prompt);
+    }
+#endif
+    return res;
+}
+
+static char *app_get_pass(const char *arg, int keepbio);
+
+int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2)
+{
+    int same;
+    if (!arg2 || !arg1 || strcmp(arg1, arg2))
+        same = 0;
+    else
+        same = 1;
+    if (arg1) {
+        *pass1 = app_get_pass(arg1, same);
+        if (!*pass1)
+            return 0;
+    } else if (pass1)
+        *pass1 = NULL;
+    if (arg2) {
+        *pass2 = app_get_pass(arg2, same ? 2 : 0);
+        if (!*pass2)
+            return 0;
+    } else if (pass2)
+        *pass2 = NULL;
+    return 1;
+}
+
+static char *app_get_pass(const char *arg, int keepbio)
+{
+    char *tmp, tpass[APP_PASS_LEN];
+    static BIO *pwdbio = NULL;
+    int i;
+
+    if (strncmp(arg, "pass:", 5) == 0)
+        return OPENSSL_strdup(arg + 5);
+    if (strncmp(arg, "env:", 4) == 0) {
+        tmp = getenv(arg + 4);
+        if (!tmp) {
+            BIO_printf(bio_err, "Can't read environment variable %s\n", arg + 4);
+            return NULL;
+        }
+        return OPENSSL_strdup(tmp);
+    }
+    if (!keepbio || !pwdbio) {
+        if (strncmp(arg, "file:", 5) == 0) {
+            pwdbio = BIO_new_file(arg + 5, "r");
+            if (!pwdbio) {
+                BIO_printf(bio_err, "Can't open file %s\n", arg + 5);
+                return NULL;
+            }
+#if !defined(_WIN32)
+            /*
+             * Under _WIN32, which covers even Win64 and CE, file
+             * descriptors referenced by BIO_s_fd are not inherited
+             * by child process and therefore below is not an option.
+             * It could have been an option if bss_fd.c was operating
+             * on real Windows descriptors, such as those obtained
+             * with CreateFile.
+             */
+        } else if (strncmp(arg, "fd:", 3) == 0) {
+            BIO *btmp;
+            i = atoi(arg + 3);
+            if (i >= 0)
+                pwdbio = BIO_new_fd(i, BIO_NOCLOSE);
+            if ((i < 0) || !pwdbio) {
+                BIO_printf(bio_err, "Can't access file descriptor %s\n", arg + 3);
+                return NULL;
+            }
+            /*
+             * Can't do BIO_gets on an fd BIO so add a buffering BIO
+             */
+            btmp = BIO_new(BIO_f_buffer());
+            pwdbio = BIO_push(btmp, pwdbio);
+#endif
+        } else if (strcmp(arg, "stdin") == 0) {
+            pwdbio = dup_bio_in(FORMAT_TEXT);
+            if (!pwdbio) {
+                BIO_printf(bio_err, "Can't open BIO for stdin\n");
+                return NULL;
+            }
+        } else {
+            BIO_printf(bio_err, "Invalid password argument \"%s\"\n", arg);
+            return NULL;
+        }
+    }
+    i = BIO_gets(pwdbio, tpass, APP_PASS_LEN);
+    if (keepbio != 1) {
+        BIO_free_all(pwdbio);
+        pwdbio = NULL;
+    }
+    if (i <= 0) {
+        BIO_printf(bio_err, "Error reading password from BIO\n");
+        return NULL;
+    }
+    tmp = strchr(tpass, '\n');
+    if (tmp)
+        *tmp = 0;
+    return OPENSSL_strdup(tpass);
+}
+
+static CONF *app_load_config_(BIO *in, const char *filename)
+{
+    long errorline = -1;
+    CONF *conf;
+    int i;
+
+    conf = NCONF_new(NULL);
+    i = NCONF_load_bio(conf, in, &errorline);
+    if (i > 0)
+        return conf;
+
+    if (errorline <= 0)
+        BIO_printf(bio_err, "%s: Can't load config file \"%s\"\n",
+                   opt_getprog(), filename);
+    else
+        BIO_printf(bio_err, "%s: Error on line %ld of config file \"%s\"\n",
+                   opt_getprog(), errorline, filename);
+    NCONF_free(conf);
+    return NULL;
+}
+CONF *app_load_config(const char *filename)
+{
+    BIO *in;
+    CONF *conf;
+
+    in = bio_open_default(filename, 'r', FORMAT_TEXT);
+    if (in == NULL)
+        return NULL;
+
+    conf = app_load_config_(in, filename);
+    BIO_free(in);
+    return conf;
+}
+CONF *app_load_config_quiet(const char *filename)
+{
+    BIO *in;
+    CONF *conf;
+
+    in = bio_open_default_quiet(filename, 'r', FORMAT_TEXT);
+    if (in == NULL)
+        return NULL;
+
+    conf = app_load_config_(in, filename);
+    BIO_free(in);
+    return conf;
+}
+
+int app_load_modules(const CONF *config)
+{
+    CONF *to_free = NULL;
+
+    if (config == NULL)
+        config = to_free = app_load_config_quiet(default_config_file);
+    if (config == NULL)
+        return 1;
+
+    if (CONF_modules_load(config, NULL, 0) <= 0) {
+        BIO_printf(bio_err, "Error configuring OpenSSL modules\n");
+        ERR_print_errors(bio_err);
+        NCONF_free(to_free);
+        return 0;
+    }
+    NCONF_free(to_free);
+    return 1;
+}
+
+int add_oid_section(CONF *conf)
+{
+    char *p;
+    STACK_OF(CONF_VALUE) *sktmp;
+    CONF_VALUE *cnf;
+    int i;
+
+    if ((p = NCONF_get_string(conf, NULL, "oid_section")) == NULL) {
+        ERR_clear_error();
+        return 1;
+    }
+    if ((sktmp = NCONF_get_section(conf, p)) == NULL) {
+        BIO_printf(bio_err, "problem loading oid section %s\n", p);
+        return 0;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
+        cnf = sk_CONF_VALUE_value(sktmp, i);
+        if (OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
+            BIO_printf(bio_err, "problem creating object %s=%s\n",
+                       cnf->name, cnf->value);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+static int load_pkcs12(BIO *in, const char *desc,
+                       pem_password_cb *pem_cb, void *cb_data,
+                       EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
+{
+    const char *pass;
+    char tpass[PEM_BUFSIZE];
+    int len, ret = 0;
+    PKCS12 *p12;
+    p12 = d2i_PKCS12_bio(in, NULL);
+    if (p12 == NULL) {
+        BIO_printf(bio_err, "Error loading PKCS12 file for %s\n", desc);
+        goto die;
+    }
+    /* See if an empty password will do */
+    if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0))
+        pass = "";
+    else {
+        if (!pem_cb)
+            pem_cb = (pem_password_cb *)password_callback;
+        len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data);
+        if (len < 0) {
+            BIO_printf(bio_err, "Passphrase callback error for %s\n", desc);
+            goto die;
+        }
+        if (len < PEM_BUFSIZE)
+            tpass[len] = 0;
+        if (!PKCS12_verify_mac(p12, tpass, len)) {
+            BIO_printf(bio_err,
+                       "Mac verify error (wrong password?) in PKCS12 file for %s\n",
+                       desc);
+            goto die;
+        }
+        pass = tpass;
+    }
+    ret = PKCS12_parse(p12, pass, pkey, cert, ca);
+ die:
+    PKCS12_free(p12);
+    return ret;
+}
+
+#if !defined(OPENSSL_NO_OCSP) && !defined(OPENSSL_NO_SOCK)
+static int load_cert_crl_http(const char *url, X509 **pcert, X509_CRL **pcrl)
+{
+    char *host = NULL, *port = NULL, *path = NULL;
+    BIO *bio = NULL;
+    OCSP_REQ_CTX *rctx = NULL;
+    int use_ssl, rv = 0;
+    if (!OCSP_parse_url(url, &host, &port, &path, &use_ssl))
+        goto err;
+    if (use_ssl) {
+        BIO_puts(bio_err, "https not supported\n");
+        goto err;
+    }
+    bio = BIO_new_connect(host);
+    if (!bio || !BIO_set_conn_port(bio, port))
+        goto err;
+    rctx = OCSP_REQ_CTX_new(bio, 1024);
+    if (rctx == NULL)
+        goto err;
+    if (!OCSP_REQ_CTX_http(rctx, "GET", path))
+        goto err;
+    if (!OCSP_REQ_CTX_add1_header(rctx, "Host", host))
+        goto err;
+    if (pcert) {
+        do {
+            rv = X509_http_nbio(rctx, pcert);
+        } while (rv == -1);
+    } else {
+        do {
+            rv = X509_CRL_http_nbio(rctx, pcrl);
+        } while (rv == -1);
+    }
+
+ err:
+    OPENSSL_free(host);
+    OPENSSL_free(path);
+    OPENSSL_free(port);
+    if (bio)
+        BIO_free_all(bio);
+    OCSP_REQ_CTX_free(rctx);
+    if (rv != 1) {
+        BIO_printf(bio_err, "Error loading %s from %s\n",
+                   pcert ? "certificate" : "CRL", url);
+        ERR_print_errors(bio_err);
+    }
+    return rv;
+}
+#endif
+
+X509 *load_cert(const char *file, int format, const char *cert_descrip)
+{
+    X509 *x = NULL;
+    BIO *cert;
+
+    if (format == FORMAT_HTTP) {
+#if !defined(OPENSSL_NO_OCSP) && !defined(OPENSSL_NO_SOCK)
+        load_cert_crl_http(file, &x, NULL);
+#endif
+        return x;
+    }
+
+    if (file == NULL) {
+        unbuffer(stdin);
+        cert = dup_bio_in(format);
+    } else
+        cert = bio_open_default(file, 'r', format);
+    if (cert == NULL)
+        goto end;
+
+    if (format == FORMAT_ASN1)
+        x = d2i_X509_bio(cert, NULL);
+    else if (format == FORMAT_PEM)
+        x = PEM_read_bio_X509_AUX(cert, NULL,
+                                  (pem_password_cb *)password_callback, NULL);
+    else if (format == FORMAT_PKCS12) {
+        if (!load_pkcs12(cert, cert_descrip, NULL, NULL, NULL, &x, NULL))
+            goto end;
+    } else {
+        BIO_printf(bio_err, "bad input format specified for %s\n", cert_descrip);
+        goto end;
+    }
+ end:
+    if (x == NULL) {
+        BIO_printf(bio_err, "unable to load certificate\n");
+        ERR_print_errors(bio_err);
+    }
+    BIO_free(cert);
+    return (x);
+}
+
+X509_CRL *load_crl(const char *infile, int format)
+{
+    X509_CRL *x = NULL;
+    BIO *in = NULL;
+
+    if (format == FORMAT_HTTP) {
+#if !defined(OPENSSL_NO_OCSP) && !defined(OPENSSL_NO_SOCK)
+        load_cert_crl_http(infile, NULL, &x);
+#endif
+        return x;
+    }
+
+    in = bio_open_default(infile, 'r', format);
+    if (in == NULL)
+        goto end;
+    if (format == FORMAT_ASN1)
+        x = d2i_X509_CRL_bio(in, NULL);
+    else if (format == FORMAT_PEM)
+        x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
+    else {
+        BIO_printf(bio_err, "bad input format specified for input crl\n");
+        goto end;
+    }
+    if (x == NULL) {
+        BIO_printf(bio_err, "unable to load CRL\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+ end:
+    BIO_free(in);
+    return (x);
+}
+
+EVP_PKEY *load_key(const char *file, int format, int maybe_stdin,
+                   const char *pass, ENGINE *e, const char *key_descrip)
+{
+    BIO *key = NULL;
+    EVP_PKEY *pkey = NULL;
+    PW_CB_DATA cb_data;
+
+    cb_data.password = pass;
+    cb_data.prompt_info = file;
+
+    if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) {
+        BIO_printf(bio_err, "no keyfile specified\n");
+        goto end;
+    }
+    if (format == FORMAT_ENGINE) {
+        if (e == NULL)
+            BIO_printf(bio_err, "no engine specified\n");
+        else {
+#ifndef OPENSSL_NO_ENGINE
+            if (ENGINE_init(e)) {
+                pkey = ENGINE_load_private_key(e, file, ui_method, &cb_data);
+                ENGINE_finish(e);
+            }
+            if (pkey == NULL) {
+                BIO_printf(bio_err, "cannot load %s from engine\n", key_descrip);
+                ERR_print_errors(bio_err);
+            }
+#else
+            BIO_printf(bio_err, "engines not supported\n");
+#endif
+        }
+        goto end;
+    }
+    if (file == NULL && maybe_stdin) {
+        unbuffer(stdin);
+        key = dup_bio_in(format);
+    } else
+        key = bio_open_default(file, 'r', format);
+    if (key == NULL)
+        goto end;
+    if (format == FORMAT_ASN1) {
+        pkey = d2i_PrivateKey_bio(key, NULL);
+    } else if (format == FORMAT_PEM) {
+        pkey = PEM_read_bio_PrivateKey(key, NULL,
+                                       (pem_password_cb *)password_callback,
+                                       &cb_data);
+    }
+    else if (format == FORMAT_PKCS12) {
+        if (!load_pkcs12(key, key_descrip,
+                         (pem_password_cb *)password_callback, &cb_data,
+                         &pkey, NULL, NULL))
+            goto end;
+    }
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4)
+    else if (format == FORMAT_MSBLOB)
+        pkey = b2i_PrivateKey_bio(key);
+    else if (format == FORMAT_PVK)
+        pkey = b2i_PVK_bio(key, (pem_password_cb *)password_callback,
+                           &cb_data);
+#endif
+    else {
+        BIO_printf(bio_err, "bad input format specified for key file\n");
+        goto end;
+    }
+ end:
+    BIO_free(key);
+    if (pkey == NULL) {
+        BIO_printf(bio_err, "unable to load %s\n", key_descrip);
+        ERR_print_errors(bio_err);
+    }
+    return (pkey);
+}
+
+EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin,
+                      const char *pass, ENGINE *e, const char *key_descrip)
+{
+    BIO *key = NULL;
+    EVP_PKEY *pkey = NULL;
+    PW_CB_DATA cb_data;
+
+    cb_data.password = pass;
+    cb_data.prompt_info = file;
+
+    if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) {
+        BIO_printf(bio_err, "no keyfile specified\n");
+        goto end;
+    }
+    if (format == FORMAT_ENGINE) {
+        if (e == NULL)
+            BIO_printf(bio_err, "no engine specified\n");
+        else {
+#ifndef OPENSSL_NO_ENGINE
+            pkey = ENGINE_load_public_key(e, file, ui_method, &cb_data);
+            if (pkey == NULL) {
+                BIO_printf(bio_err, "cannot load %s from engine\n", key_descrip);
+                ERR_print_errors(bio_err);
+            }
+#else
+            BIO_printf(bio_err, "engines not supported\n");
+#endif
+        }
+        goto end;
+    }
+    if (file == NULL && maybe_stdin) {
+        unbuffer(stdin);
+        key = dup_bio_in(format);
+    } else
+        key = bio_open_default(file, 'r', format);
+    if (key == NULL)
+        goto end;
+    if (format == FORMAT_ASN1) {
+        pkey = d2i_PUBKEY_bio(key, NULL);
+    }
+    else if (format == FORMAT_ASN1RSA) {
+#ifndef OPENSSL_NO_RSA
+        RSA *rsa;
+        rsa = d2i_RSAPublicKey_bio(key, NULL);
+        if (rsa) {
+            pkey = EVP_PKEY_new();
+            if (pkey != NULL)
+                EVP_PKEY_set1_RSA(pkey, rsa);
+            RSA_free(rsa);
+        } else
+#else
+        BIO_printf(bio_err, "RSA keys not supported\n");
+#endif
+            pkey = NULL;
+    } else if (format == FORMAT_PEMRSA) {
+#ifndef OPENSSL_NO_RSA
+        RSA *rsa;
+        rsa = PEM_read_bio_RSAPublicKey(key, NULL,
+                                        (pem_password_cb *)password_callback,
+                                        &cb_data);
+        if (rsa != NULL) {
+            pkey = EVP_PKEY_new();
+            if (pkey != NULL)
+                EVP_PKEY_set1_RSA(pkey, rsa);
+            RSA_free(rsa);
+        } else
+#else
+        BIO_printf(bio_err, "RSA keys not supported\n");
+#endif
+            pkey = NULL;
+    }
+    else if (format == FORMAT_PEM) {
+        pkey = PEM_read_bio_PUBKEY(key, NULL,
+                                   (pem_password_cb *)password_callback,
+                                   &cb_data);
+    }
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
+    else if (format == FORMAT_MSBLOB)
+        pkey = b2i_PublicKey_bio(key);
+#endif
+ end:
+    BIO_free(key);
+    if (pkey == NULL)
+        BIO_printf(bio_err, "unable to load %s\n", key_descrip);
+    return (pkey);
+}
+
+static int load_certs_crls(const char *file, int format,
+                           const char *pass, const char *desc,
+                           STACK_OF(X509) **pcerts,
+                           STACK_OF(X509_CRL) **pcrls)
+{
+    int i;
+    BIO *bio;
+    STACK_OF(X509_INFO) *xis = NULL;
+    X509_INFO *xi;
+    PW_CB_DATA cb_data;
+    int rv = 0;
+
+    cb_data.password = pass;
+    cb_data.prompt_info = file;
+
+    if (format != FORMAT_PEM) {
+        BIO_printf(bio_err, "bad input format specified for %s\n", desc);
+        return 0;
+    }
+
+    bio = bio_open_default(file, 'r', FORMAT_PEM);
+    if (bio == NULL)
+        return 0;
+
+    xis = PEM_X509_INFO_read_bio(bio, NULL,
+                                 (pem_password_cb *)password_callback,
+                                 &cb_data);
+
+    BIO_free(bio);
+
+    if (pcerts && *pcerts == NULL) {
+        *pcerts = sk_X509_new_null();
+        if (!*pcerts)
+            goto end;
+    }
+
+    if (pcrls && *pcrls == NULL) {
+        *pcrls = sk_X509_CRL_new_null();
+        if (!*pcrls)
+            goto end;
+    }
+
+    for (i = 0; i < sk_X509_INFO_num(xis); i++) {
+        xi = sk_X509_INFO_value(xis, i);
+        if (xi->x509 && pcerts) {
+            if (!sk_X509_push(*pcerts, xi->x509))
+                goto end;
+            xi->x509 = NULL;
+        }
+        if (xi->crl && pcrls) {
+            if (!sk_X509_CRL_push(*pcrls, xi->crl))
+                goto end;
+            xi->crl = NULL;
+        }
+    }
+
+    if (pcerts && sk_X509_num(*pcerts) > 0)
+        rv = 1;
+
+    if (pcrls && sk_X509_CRL_num(*pcrls) > 0)
+        rv = 1;
+
+ end:
+
+    sk_X509_INFO_pop_free(xis, X509_INFO_free);
+
+    if (rv == 0) {
+        if (pcerts) {
+            sk_X509_pop_free(*pcerts, X509_free);
+            *pcerts = NULL;
+        }
+        if (pcrls) {
+            sk_X509_CRL_pop_free(*pcrls, X509_CRL_free);
+            *pcrls = NULL;
+        }
+        BIO_printf(bio_err, "unable to load %s\n",
+                   pcerts ? "certificates" : "CRLs");
+        ERR_print_errors(bio_err);
+    }
+    return rv;
+}
+
+void* app_malloc(int sz, const char *what)
+{
+    void *vp = OPENSSL_malloc(sz);
+
+    if (vp == NULL) {
+        BIO_printf(bio_err, "%s: Could not allocate %d bytes for %s\n",
+                opt_getprog(), sz, what);
+        ERR_print_errors(bio_err);
+        exit(1);
+    }
+    return vp;
+}
+
+/*
+ * Initialize or extend, if *certs != NULL, a certificate stack.
+ */
+int load_certs(const char *file, STACK_OF(X509) **certs, int format,
+               const char *pass, const char *desc)
+{
+    return load_certs_crls(file, format, pass, desc, certs, NULL);
+}
+
+/*
+ * Initialize or extend, if *crls != NULL, a certificate stack.
+ */
+int load_crls(const char *file, STACK_OF(X509_CRL) **crls, int format,
+              const char *pass, const char *desc)
+{
+    return load_certs_crls(file, format, pass, desc, NULL, crls);
+}
+
+#define X509V3_EXT_UNKNOWN_MASK         (0xfL << 16)
+/* Return error for unknown extensions */
+#define X509V3_EXT_DEFAULT              0
+/* Print error for unknown extensions */
+#define X509V3_EXT_ERROR_UNKNOWN        (1L << 16)
+/* ASN1 parse unknown extensions */
+#define X509V3_EXT_PARSE_UNKNOWN        (2L << 16)
+/* BIO_dump unknown extensions */
+#define X509V3_EXT_DUMP_UNKNOWN         (3L << 16)
+
+#define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \
+                         X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION)
+
+int set_cert_ex(unsigned long *flags, const char *arg)
+{
+    static const NAME_EX_TBL cert_tbl[] = {
+        {"compatible", X509_FLAG_COMPAT, 0xffffffffl},
+        {"ca_default", X509_FLAG_CA, 0xffffffffl},
+        {"no_header", X509_FLAG_NO_HEADER, 0},
+        {"no_version", X509_FLAG_NO_VERSION, 0},
+        {"no_serial", X509_FLAG_NO_SERIAL, 0},
+        {"no_signame", X509_FLAG_NO_SIGNAME, 0},
+        {"no_validity", X509_FLAG_NO_VALIDITY, 0},
+        {"no_subject", X509_FLAG_NO_SUBJECT, 0},
+        {"no_issuer", X509_FLAG_NO_ISSUER, 0},
+        {"no_pubkey", X509_FLAG_NO_PUBKEY, 0},
+        {"no_extensions", X509_FLAG_NO_EXTENSIONS, 0},
+        {"no_sigdump", X509_FLAG_NO_SIGDUMP, 0},
+        {"no_aux", X509_FLAG_NO_AUX, 0},
+        {"no_attributes", X509_FLAG_NO_ATTRIBUTES, 0},
+        {"ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK},
+        {"ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
+        {"ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
+        {"ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
+        {NULL, 0, 0}
+    };
+    return set_multi_opts(flags, arg, cert_tbl);
+}
+
+int set_name_ex(unsigned long *flags, const char *arg)
+{
+    static const NAME_EX_TBL ex_tbl[] = {
+        {"esc_2253", ASN1_STRFLGS_ESC_2253, 0},
+        {"esc_2254", ASN1_STRFLGS_ESC_2254, 0},
+        {"esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0},
+        {"esc_msb", ASN1_STRFLGS_ESC_MSB, 0},
+        {"use_quote", ASN1_STRFLGS_ESC_QUOTE, 0},
+        {"utf8", ASN1_STRFLGS_UTF8_CONVERT, 0},
+        {"ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0},
+        {"show_type", ASN1_STRFLGS_SHOW_TYPE, 0},
+        {"dump_all", ASN1_STRFLGS_DUMP_ALL, 0},
+        {"dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0},
+        {"dump_der", ASN1_STRFLGS_DUMP_DER, 0},
+        {"compat", XN_FLAG_COMPAT, 0xffffffffL},
+        {"sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK},
+        {"sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK},
+        {"sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK},
+        {"sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK},
+        {"dn_rev", XN_FLAG_DN_REV, 0},
+        {"nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK},
+        {"sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK},
+        {"lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK},
+        {"align", XN_FLAG_FN_ALIGN, 0},
+        {"oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK},
+        {"space_eq", XN_FLAG_SPC_EQ, 0},
+        {"dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0},
+        {"RFC2253", XN_FLAG_RFC2253, 0xffffffffL},
+        {"oneline", XN_FLAG_ONELINE, 0xffffffffL},
+        {"multiline", XN_FLAG_MULTILINE, 0xffffffffL},
+        {"ca_default", XN_FLAG_MULTILINE, 0xffffffffL},
+        {NULL, 0, 0}
+    };
+    if (set_multi_opts(flags, arg, ex_tbl) == 0)
+        return 0;
+    if ((*flags & XN_FLAG_SEP_MASK) == 0)
+        *flags |= XN_FLAG_SEP_CPLUS_SPC;
+    return 1;
+}
+
+int set_ext_copy(int *copy_type, const char *arg)
+{
+    if (strcasecmp(arg, "none") == 0)
+        *copy_type = EXT_COPY_NONE;
+    else if (strcasecmp(arg, "copy") == 0)
+        *copy_type = EXT_COPY_ADD;
+    else if (strcasecmp(arg, "copyall") == 0)
+        *copy_type = EXT_COPY_ALL;
+    else
+        return 0;
+    return 1;
+}
+
+int copy_extensions(X509 *x, X509_REQ *req, int copy_type)
+{
+    STACK_OF(X509_EXTENSION) *exts = NULL;
+    X509_EXTENSION *ext, *tmpext;
+    ASN1_OBJECT *obj;
+    int i, idx, ret = 0;
+    if (!x || !req || (copy_type == EXT_COPY_NONE))
+        return 1;
+    exts = X509_REQ_get_extensions(req);
+
+    for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
+        ext = sk_X509_EXTENSION_value(exts, i);
+        obj = X509_EXTENSION_get_object(ext);
+        idx = X509_get_ext_by_OBJ(x, obj, -1);
+        /* Does extension exist? */
+        if (idx != -1) {
+            /* If normal copy don't override existing extension */
+            if (copy_type == EXT_COPY_ADD)
+                continue;
+            /* Delete all extensions of same type */
+            do {
+                tmpext = X509_get_ext(x, idx);
+                X509_delete_ext(x, idx);
+                X509_EXTENSION_free(tmpext);
+                idx = X509_get_ext_by_OBJ(x, obj, -1);
+            } while (idx != -1);
+        }
+        if (!X509_add_ext(x, ext, -1))
+            goto end;
+    }
+
+    ret = 1;
+
+ end:
+
+    sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+
+    return ret;
+}
+
+static int set_multi_opts(unsigned long *flags, const char *arg,
+                          const NAME_EX_TBL * in_tbl)
+{
+    STACK_OF(CONF_VALUE) *vals;
+    CONF_VALUE *val;
+    int i, ret = 1;
+    if (!arg)
+        return 0;
+    vals = X509V3_parse_list(arg);
+    for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
+        val = sk_CONF_VALUE_value(vals, i);
+        if (!set_table_opts(flags, val->name, in_tbl))
+            ret = 0;
+    }
+    sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
+    return ret;
+}
+
+static int set_table_opts(unsigned long *flags, const char *arg,
+                          const NAME_EX_TBL * in_tbl)
+{
+    char c;
+    const NAME_EX_TBL *ptbl;
+    c = arg[0];
+
+    if (c == '-') {
+        c = 0;
+        arg++;
+    } else if (c == '+') {
+        c = 1;
+        arg++;
+    } else
+        c = 1;
+
+    for (ptbl = in_tbl; ptbl->name; ptbl++) {
+        if (strcasecmp(arg, ptbl->name) == 0) {
+            *flags &= ~ptbl->mask;
+            if (c)
+                *flags |= ptbl->flag;
+            else
+                *flags &= ~ptbl->flag;
+            return 1;
+        }
+    }
+    return 0;
+}
+
+void print_name(BIO *out, const char *title, X509_NAME *nm,
+                unsigned long lflags)
+{
+    char *buf;
+    char mline = 0;
+    int indent = 0;
+
+    if (title)
+        BIO_puts(out, title);
+    if ((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
+        mline = 1;
+        indent = 4;
+    }
+    if (lflags == XN_FLAG_COMPAT) {
+        buf = X509_NAME_oneline(nm, 0, 0);
+        BIO_puts(out, buf);
+        BIO_puts(out, "\n");
+        OPENSSL_free(buf);
+    } else {
+        if (mline)
+            BIO_puts(out, "\n");
+        X509_NAME_print_ex(out, nm, indent, lflags);
+        BIO_puts(out, "\n");
+    }
+}
+
+void print_bignum_var(BIO *out, const BIGNUM *in, const char *var,
+                      int len, unsigned char *buffer)
+{
+    BIO_printf(out, "    static unsigned char %s_%d[] = {", var, len);
+    if (BN_is_zero(in))
+        BIO_printf(out, "\n\t0x00");
+    else {
+        int i, l;
+
+        l = BN_bn2bin(in, buffer);
+        for (i = 0; i < l; i++) {
+            if ((i % 10) == 0)
+                BIO_printf(out, "\n\t");
+            if (i < l - 1)
+                BIO_printf(out, "0x%02X, ", buffer[i]);
+            else
+                BIO_printf(out, "0x%02X", buffer[i]);
+        }
+    }
+    BIO_printf(out, "\n    };\n");
+}
+void print_array(BIO *out, const char* title, int len, const unsigned char* d)
+{
+    int i;
+
+    BIO_printf(out, "unsigned char %s[%d] = {", title, len);
+    for (i = 0; i < len; i++) {
+        if ((i % 10) == 0)
+            BIO_printf(out, "\n    ");
+        if (i < len - 1)
+            BIO_printf(out, "0x%02X, ", d[i]);
+        else
+            BIO_printf(out, "0x%02X", d[i]);
+    }
+    BIO_printf(out, "\n};\n");
+}
+
+X509_STORE *setup_verify(const char *CAfile, const char *CApath, int noCAfile, int noCApath)
+{
+    X509_STORE *store = X509_STORE_new();
+    X509_LOOKUP *lookup;
+
+    if (store == NULL)
+        goto end;
+
+    if (CAfile != NULL || !noCAfile) {
+        lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
+        if (lookup == NULL)
+            goto end;
+        if (CAfile) {
+            if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) {
+                BIO_printf(bio_err, "Error loading file %s\n", CAfile);
+                goto end;
+            }
+        } else
+            X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
+    }
+
+    if (CApath != NULL || !noCApath) {
+        lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
+        if (lookup == NULL)
+            goto end;
+        if (CApath) {
+            if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) {
+                BIO_printf(bio_err, "Error loading directory %s\n", CApath);
+                goto end;
+            }
+        } else
+            X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
+    }
+
+    ERR_clear_error();
+    return store;
+ end:
+    X509_STORE_free(store);
+    return NULL;
+}
+
+#ifndef OPENSSL_NO_ENGINE
+/* Try to load an engine in a shareable library */
+static ENGINE *try_load_engine(const char *engine)
+{
+    ENGINE *e = ENGINE_by_id("dynamic");
+    if (e) {
+        if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0)
+            || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) {
+            ENGINE_free(e);
+            e = NULL;
+        }
+    }
+    return e;
+}
+#endif
+
+ENGINE *setup_engine(const char *engine, int debug)
+{
+    ENGINE *e = NULL;
+
+#ifndef OPENSSL_NO_ENGINE
+    if (engine) {
+        if (strcmp(engine, "auto") == 0) {
+            BIO_printf(bio_err, "enabling auto ENGINE support\n");
+            ENGINE_register_all_complete();
+            return NULL;
+        }
+        if ((e = ENGINE_by_id(engine)) == NULL
+            && (e = try_load_engine(engine)) == NULL) {
+            BIO_printf(bio_err, "invalid engine \"%s\"\n", engine);
+            ERR_print_errors(bio_err);
+            return NULL;
+        }
+        if (debug) {
+            ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, bio_err, 0);
+        }
+        ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1);
+        if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
+            BIO_printf(bio_err, "can't use that engine\n");
+            ERR_print_errors(bio_err);
+            ENGINE_free(e);
+            return NULL;
+        }
+
+        BIO_printf(bio_err, "engine \"%s\" set.\n", ENGINE_get_id(e));
+    }
+#endif
+    return e;
+}
+
+void release_engine(ENGINE *e)
+{
+#ifndef OPENSSL_NO_ENGINE
+    if (e != NULL)
+        /* Free our "structural" reference. */
+        ENGINE_free(e);
+#endif
+}
+
+static unsigned long index_serial_hash(const OPENSSL_CSTRING *a)
+{
+    const char *n;
+
+    n = a[DB_serial];
+    while (*n == '0')
+        n++;
+    return OPENSSL_LH_strhash(n);
+}
+
+static int index_serial_cmp(const OPENSSL_CSTRING *a,
+                            const OPENSSL_CSTRING *b)
+{
+    const char *aa, *bb;
+
+    for (aa = a[DB_serial]; *aa == '0'; aa++) ;
+    for (bb = b[DB_serial]; *bb == '0'; bb++) ;
+    return (strcmp(aa, bb));
+}
+
+static int index_name_qual(char **a)
+{
+    return (a[0][0] == 'V');
+}
+
+static unsigned long index_name_hash(const OPENSSL_CSTRING *a)
+{
+    return OPENSSL_LH_strhash(a[DB_name]);
+}
+
+int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
+{
+    return (strcmp(a[DB_name], b[DB_name]));
+}
+
+static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING)
+static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING)
+static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING)
+static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING)
+#undef BSIZE
+#define BSIZE 256
+BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai)
+{
+    BIO *in = NULL;
+    BIGNUM *ret = NULL;
+    char buf[1024];
+    ASN1_INTEGER *ai = NULL;
+
+    ai = ASN1_INTEGER_new();
+    if (ai == NULL)
+        goto err;
+
+    in = BIO_new_file(serialfile, "r");
+    if (in == NULL) {
+        if (!create) {
+            perror(serialfile);
+            goto err;
+        }
+        ERR_clear_error();
+        ret = BN_new();
+        if (ret == NULL || !rand_serial(ret, ai))
+            BIO_printf(bio_err, "Out of memory\n");
+    } else {
+        if (!a2i_ASN1_INTEGER(in, ai, buf, 1024)) {
+            BIO_printf(bio_err, "unable to load number from %s\n",
+                       serialfile);
+            goto err;
+        }
+        ret = ASN1_INTEGER_to_BN(ai, NULL);
+        if (ret == NULL) {
+            BIO_printf(bio_err,
+                       "error converting number from bin to BIGNUM\n");
+            goto err;
+        }
+    }
+
+    if (ret && retai) {
+        *retai = ai;
+        ai = NULL;
+    }
+ err:
+    BIO_free(in);
+    ASN1_INTEGER_free(ai);
+    return (ret);
+}
+
+int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial,
+                ASN1_INTEGER **retai)
+{
+    char buf[1][BSIZE];
+    BIO *out = NULL;
+    int ret = 0;
+    ASN1_INTEGER *ai = NULL;
+    int j;
+
+    if (suffix == NULL)
+        j = strlen(serialfile);
+    else
+        j = strlen(serialfile) + strlen(suffix) + 1;
+    if (j >= BSIZE) {
+        BIO_printf(bio_err, "file name too long\n");
+        goto err;
+    }
+
+    if (suffix == NULL)
+        OPENSSL_strlcpy(buf[0], serialfile, BSIZE);
+    else {
+#ifndef OPENSSL_SYS_VMS
+        j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, suffix);
+#else
+        j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, suffix);
+#endif
+    }
+    out = BIO_new_file(buf[0], "w");
+    if (out == NULL) {
+        ERR_print_errors(bio_err);
+        goto err;
+    }
+
+    if ((ai = BN_to_ASN1_INTEGER(serial, NULL)) == NULL) {
+        BIO_printf(bio_err, "error converting serial to ASN.1 format\n");
+        goto err;
+    }
+    i2a_ASN1_INTEGER(out, ai);
+    BIO_puts(out, "\n");
+    ret = 1;
+    if (retai) {
+        *retai = ai;
+        ai = NULL;
+    }
+ err:
+    BIO_free_all(out);
+    ASN1_INTEGER_free(ai);
+    return (ret);
+}
+
+int rotate_serial(const char *serialfile, const char *new_suffix,
+                  const char *old_suffix)
+{
+    char buf[2][BSIZE];
+    int i, j;
+
+    i = strlen(serialfile) + strlen(old_suffix);
+    j = strlen(serialfile) + strlen(new_suffix);
+    if (i > j)
+        j = i;
+    if (j + 1 >= BSIZE) {
+        BIO_printf(bio_err, "file name too long\n");
+        goto err;
+    }
+#ifndef OPENSSL_SYS_VMS
+    j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, new_suffix);
+    j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", serialfile, old_suffix);
+#else
+    j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, new_suffix);
+    j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", serialfile, old_suffix);
+#endif
+    if (rename(serialfile, buf[1]) < 0 && errno != ENOENT
+#ifdef ENOTDIR
+        && errno != ENOTDIR
+#endif
+        ) {
+        BIO_printf(bio_err,
+                   "unable to rename %s to %s\n", serialfile, buf[1]);
+        perror("reason");
+        goto err;
+    }
+    if (rename(buf[0], serialfile) < 0) {
+        BIO_printf(bio_err,
+                   "unable to rename %s to %s\n", buf[0], serialfile);
+        perror("reason");
+        rename(buf[1], serialfile);
+        goto err;
+    }
+    return 1;
+ err:
+    return 0;
+}
+
+int rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
+{
+    BIGNUM *btmp;
+    int ret = 0;
+
+    if (b)
+        btmp = b;
+    else
+        btmp = BN_new();
+
+    if (btmp == NULL)
+        return 0;
+
+    if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
+        goto error;
+    if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
+        goto error;
+
+    ret = 1;
+
+ error:
+
+    if (btmp != b)
+        BN_free(btmp);
+
+    return ret;
+}
+
+CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr)
+{
+    CA_DB *retdb = NULL;
+    TXT_DB *tmpdb = NULL;
+    BIO *in;
+    CONF *dbattr_conf = NULL;
+    char buf[BSIZE];
+
+    in = BIO_new_file(dbfile, "r");
+    if (in == NULL) {
+        ERR_print_errors(bio_err);
+        goto err;
+    }
+    if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL)
+        goto err;
+
+#ifndef OPENSSL_SYS_VMS
+    BIO_snprintf(buf, sizeof buf, "%s.attr", dbfile);
+#else
+    BIO_snprintf(buf, sizeof buf, "%s-attr", dbfile);
+#endif
+    dbattr_conf = app_load_config(buf);
+
+    retdb = app_malloc(sizeof(*retdb), "new DB");
+    retdb->db = tmpdb;
+    tmpdb = NULL;
+    if (db_attr)
+        retdb->attributes = *db_attr;
+    else {
+        retdb->attributes.unique_subject = 1;
+    }
+
+    if (dbattr_conf) {
+        char *p = NCONF_get_string(dbattr_conf, NULL, "unique_subject");
+        if (p) {
+            retdb->attributes.unique_subject = parse_yesno(p, 1);
+        }
+    }
+
+ err:
+    NCONF_free(dbattr_conf);
+    TXT_DB_free(tmpdb);
+    BIO_free_all(in);
+    return retdb;
+}
+
+int index_index(CA_DB *db)
+{
+    if (!TXT_DB_create_index(db->db, DB_serial, NULL,
+                             LHASH_HASH_FN(index_serial),
+                             LHASH_COMP_FN(index_serial))) {
+        BIO_printf(bio_err,
+                   "error creating serial number index:(%ld,%ld,%ld)\n",
+                   db->db->error, db->db->arg1, db->db->arg2);
+        return 0;
+    }
+
+    if (db->attributes.unique_subject
+        && !TXT_DB_create_index(db->db, DB_name, index_name_qual,
+                                LHASH_HASH_FN(index_name),
+                                LHASH_COMP_FN(index_name))) {
+        BIO_printf(bio_err, "error creating name index:(%ld,%ld,%ld)\n",
+                   db->db->error, db->db->arg1, db->db->arg2);
+        return 0;
+    }
+    return 1;
+}
+
+int save_index(const char *dbfile, const char *suffix, CA_DB *db)
+{
+    char buf[3][BSIZE];
+    BIO *out;
+    int j;
+
+    j = strlen(dbfile) + strlen(suffix);
+    if (j + 6 >= BSIZE) {
+        BIO_printf(bio_err, "file name too long\n");
+        goto err;
+    }
+#ifndef OPENSSL_SYS_VMS
+    j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr", dbfile);
+    j = BIO_snprintf(buf[1], sizeof buf[1], "%s.attr.%s", dbfile, suffix);
+    j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, suffix);
+#else
+    j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr", dbfile);
+    j = BIO_snprintf(buf[1], sizeof buf[1], "%s-attr-%s", dbfile, suffix);
+    j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, suffix);
+#endif
+    out = BIO_new_file(buf[0], "w");
+    if (out == NULL) {
+        perror(dbfile);
+        BIO_printf(bio_err, "unable to open '%s'\n", dbfile);
+        goto err;
+    }
+    j = TXT_DB_write(out, db->db);
+    BIO_free(out);
+    if (j <= 0)
+        goto err;
+
+    out = BIO_new_file(buf[1], "w");
+    if (out == NULL) {
+        perror(buf[2]);
+        BIO_printf(bio_err, "unable to open '%s'\n", buf[2]);
+        goto err;
+    }
+    BIO_printf(out, "unique_subject = %s\n",
+               db->attributes.unique_subject ? "yes" : "no");
+    BIO_free(out);
+
+    return 1;
+ err:
+    return 0;
+}
+
+int rotate_index(const char *dbfile, const char *new_suffix,
+                 const char *old_suffix)
+{
+    char buf[5][BSIZE];
+    int i, j;
+
+    i = strlen(dbfile) + strlen(old_suffix);
+    j = strlen(dbfile) + strlen(new_suffix);
+    if (i > j)
+        j = i;
+    if (j + 6 >= BSIZE) {
+        BIO_printf(bio_err, "file name too long\n");
+        goto err;
+    }
+#ifndef OPENSSL_SYS_VMS
+    j = BIO_snprintf(buf[4], sizeof buf[4], "%s.attr", dbfile);
+    j = BIO_snprintf(buf[3], sizeof buf[3], "%s.attr.%s", dbfile, old_suffix);
+    j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr.%s", dbfile, new_suffix);
+    j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", dbfile, old_suffix);
+    j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, new_suffix);
+#else
+    j = BIO_snprintf(buf[4], sizeof buf[4], "%s-attr", dbfile);
+    j = BIO_snprintf(buf[3], sizeof buf[3], "%s-attr-%s", dbfile, old_suffix);
+    j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr-%s", dbfile, new_suffix);
+    j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", dbfile, old_suffix);
+    j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, new_suffix);
+#endif
+    if (rename(dbfile, buf[1]) < 0 && errno != ENOENT
+#ifdef ENOTDIR
+        && errno != ENOTDIR
+#endif
+        ) {
+        BIO_printf(bio_err, "unable to rename %s to %s\n", dbfile, buf[1]);
+        perror("reason");
+        goto err;
+    }
+    if (rename(buf[0], dbfile) < 0) {
+        BIO_printf(bio_err, "unable to rename %s to %s\n", buf[0], dbfile);
+        perror("reason");
+        rename(buf[1], dbfile);
+        goto err;
+    }
+    if (rename(buf[4], buf[3]) < 0 && errno != ENOENT
+#ifdef ENOTDIR
+        && errno != ENOTDIR
+#endif
+        ) {
+        BIO_printf(bio_err, "unable to rename %s to %s\n", buf[4], buf[3]);
+        perror("reason");
+        rename(dbfile, buf[0]);
+        rename(buf[1], dbfile);
+        goto err;
+    }
+    if (rename(buf[2], buf[4]) < 0) {
+        BIO_printf(bio_err, "unable to rename %s to %s\n", buf[2], buf[4]);
+        perror("reason");
+        rename(buf[3], buf[4]);
+        rename(dbfile, buf[0]);
+        rename(buf[1], dbfile);
+        goto err;
+    }
+    return 1;
+ err:
+    return 0;
+}
+
+void free_index(CA_DB *db)
+{
+    if (db) {
+        TXT_DB_free(db->db);
+        OPENSSL_free(db);
+    }
+}
+
+int parse_yesno(const char *str, int def)
+{
+    if (str) {
+        switch (*str) {
+        case 'f':              /* false */
+        case 'F':              /* FALSE */
+        case 'n':              /* no */
+        case 'N':              /* NO */
+        case '0':              /* 0 */
+            return 0;
+        case 't':              /* true */
+        case 'T':              /* TRUE */
+        case 'y':              /* yes */
+        case 'Y':              /* YES */
+        case '1':              /* 1 */
+            return 1;
+        }
+    }
+    return def;
+}
+
+/*
+ * name is expected to be in the format /type0=value0/type1=value1/type2=...
+ * where characters may be escaped by \
+ */
+X509_NAME *parse_name(const char *cp, long chtype, int canmulti)
+{
+    int nextismulti = 0;
+    char *work;
+    X509_NAME *n;
+
+    if (*cp++ != '/')
+        return NULL;
+
+    n = X509_NAME_new();
+    if (n == NULL)
+        return NULL;
+    work = OPENSSL_strdup(cp);
+    if (work == NULL)
+        goto err;
+
+    while (*cp) {
+        char *bp = work;
+        char *typestr = bp;
+        unsigned char *valstr;
+        int nid;
+        int ismulti = nextismulti;
+        nextismulti = 0;
+
+        /* Collect the type */
+        while (*cp && *cp != '=')
+            *bp++ = *cp++;
+        if (*cp == '\0') {
+            BIO_printf(bio_err,
+                    "%s: Hit end of string before finding the equals.\n",
+                    opt_getprog());
+            goto err;
+        }
+        *bp++ = '\0';
+        ++cp;
+
+        /* Collect the value. */
+        valstr = (unsigned char *)bp;
+        for (; *cp && *cp != '/'; *bp++ = *cp++) {
+            if (canmulti && *cp == '+') {
+                nextismulti = 1;
+                break;
+            }
+            if (*cp == '\\' && *++cp == '\0') {
+                BIO_printf(bio_err,
+                        "%s: escape character at end of string\n",
+                        opt_getprog());
+                goto err;
+            }
+        }
+        *bp++ = '\0';
+
+        /* If not at EOS (must be + or /), move forward. */
+        if (*cp)
+            ++cp;
+
+        /* Parse */
+        nid = OBJ_txt2nid(typestr);
+        if (nid == NID_undef) {
+            BIO_printf(bio_err, "%s: Skipping unknown attribute \"%s\"\n",
+                      opt_getprog(), typestr);
+            continue;
+        }
+        if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
+                                        valstr, strlen((char *)valstr),
+                                        -1, ismulti ? -1 : 0))
+            goto err;
+    }
+
+    OPENSSL_free(work);
+    return n;
+
+ err:
+    X509_NAME_free(n);
+    OPENSSL_free(work);
+    return NULL;
+}
+
+/*
+ * Read whole contents of a BIO into an allocated memory buffer and return
+ * it.
+ */
+
+int bio_to_mem(unsigned char **out, int maxlen, BIO *in)
+{
+    BIO *mem;
+    int len, ret;
+    unsigned char tbuf[1024];
+
+    mem = BIO_new(BIO_s_mem());
+    if (mem == NULL)
+        return -1;
+    for (;;) {
+        if ((maxlen != -1) && maxlen < 1024)
+            len = maxlen;
+        else
+            len = 1024;
+        len = BIO_read(in, tbuf, len);
+        if (len < 0) {
+            BIO_free(mem);
+            return -1;
+        }
+        if (len == 0)
+            break;
+        if (BIO_write(mem, tbuf, len) != len) {
+            BIO_free(mem);
+            return -1;
+        }
+        maxlen -= len;
+
+        if (maxlen == 0)
+            break;
+    }
+    ret = BIO_get_mem_data(mem, (char **)out);
+    BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY);
+    BIO_free(mem);
+    return ret;
+}
+
+int pkey_ctrl_string(EVP_PKEY_CTX *ctx, const char *value)
+{
+    int rv;
+    char *stmp, *vtmp = NULL;
+    stmp = OPENSSL_strdup(value);
+    if (!stmp)
+        return -1;
+    vtmp = strchr(stmp, ':');
+    if (vtmp) {
+        *vtmp = 0;
+        vtmp++;
+    }
+    rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp);
+    OPENSSL_free(stmp);
+    return rv;
+}
+
+static void nodes_print(const char *name, STACK_OF(X509_POLICY_NODE) *nodes)
+{
+    X509_POLICY_NODE *node;
+    int i;
+
+    BIO_printf(bio_err, "%s Policies:", name);
+    if (nodes) {
+        BIO_puts(bio_err, "\n");
+        for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) {
+            node = sk_X509_POLICY_NODE_value(nodes, i);
+            X509_POLICY_NODE_print(bio_err, node, 2);
+        }
+    } else
+        BIO_puts(bio_err, " <empty>\n");
+}
+
+void policies_print(X509_STORE_CTX *ctx)
+{
+    X509_POLICY_TREE *tree;
+    int explicit_policy;
+    tree = X509_STORE_CTX_get0_policy_tree(ctx);
+    explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx);
+
+    BIO_printf(bio_err, "Require explicit Policy: %s\n",
+               explicit_policy ? "True" : "False");
+
+    nodes_print("Authority", X509_policy_tree_get0_policies(tree));
+    nodes_print("User", X509_policy_tree_get0_user_policies(tree));
+}
+
+/*-
+ * next_protos_parse parses a comma separated list of strings into a string
+ * in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
+ *   outlen: (output) set to the length of the resulting buffer on success.
+ *   err: (maybe NULL) on failure, an error message line is written to this BIO.
+ *   in: a NUL terminated string like "abc,def,ghi"
+ *
+ *   returns: a malloc'd buffer or NULL on failure.
+ */
+unsigned char *next_protos_parse(size_t *outlen, const char *in)
+{
+    size_t len;
+    unsigned char *out;
+    size_t i, start = 0;
+
+    len = strlen(in);
+    if (len >= 65535)
+        return NULL;
+
+    out = app_malloc(strlen(in) + 1, "NPN buffer");
+    for (i = 0; i <= len; ++i) {
+        if (i == len || in[i] == ',') {
+            if (i - start > 255) {
+                OPENSSL_free(out);
+                return NULL;
+            }
+            out[start] = i - start;
+            start = i + 1;
+        } else
+            out[i + 1] = in[i];
+    }
+
+    *outlen = len + 1;
+    return out;
+}
+
+void print_cert_checks(BIO *bio, X509 *x,
+                       const char *checkhost,
+                       const char *checkemail, const char *checkip)
+{
+    if (x == NULL)
+        return;
+    if (checkhost) {
+        BIO_printf(bio, "Hostname %s does%s match certificate\n",
+                   checkhost,
+                   X509_check_host(x, checkhost, 0, 0, NULL) == 1
+                       ? "" : " NOT");
+    }
+
+    if (checkemail) {
+        BIO_printf(bio, "Email %s does%s match certificate\n",
+                   checkemail, X509_check_email(x, checkemail, 0, 0)
+                   ? "" : " NOT");
+    }
+
+    if (checkip) {
+        BIO_printf(bio, "IP %s does%s match certificate\n",
+                   checkip, X509_check_ip_asc(x, checkip, 0) ? "" : " NOT");
+    }
+}
+
+/* Get first http URL from a DIST_POINT structure */
+
+static const char *get_dp_url(DIST_POINT *dp)
+{
+    GENERAL_NAMES *gens;
+    GENERAL_NAME *gen;
+    int i, gtype;
+    ASN1_STRING *uri;
+    if (!dp->distpoint || dp->distpoint->type != 0)
+        return NULL;
+    gens = dp->distpoint->name.fullname;
+    for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+        gen = sk_GENERAL_NAME_value(gens, i);
+        uri = GENERAL_NAME_get0_value(gen, &gtype);
+        if (gtype == GEN_URI && ASN1_STRING_length(uri) > 6) {
+            const char *uptr = (const char *)ASN1_STRING_get0_data(uri);
+            if (strncmp(uptr, "http://", 7) == 0)
+                return uptr;
+        }
+    }
+    return NULL;
+}
+
+/*
+ * Look through a CRLDP structure and attempt to find an http URL to
+ * downloads a CRL from.
+ */
+
+static X509_CRL *load_crl_crldp(STACK_OF(DIST_POINT) *crldp)
+{
+    int i;
+    const char *urlptr = NULL;
+    for (i = 0; i < sk_DIST_POINT_num(crldp); i++) {
+        DIST_POINT *dp = sk_DIST_POINT_value(crldp, i);
+        urlptr = get_dp_url(dp);
+        if (urlptr)
+            return load_crl(urlptr, FORMAT_HTTP);
+    }
+    return NULL;
+}
+
+/*
+ * Example of downloading CRLs from CRLDP: not usable for real world as it
+ * always downloads, doesn't support non-blocking I/O and doesn't cache
+ * anything.
+ */
+
+static STACK_OF(X509_CRL) *crls_http_cb(X509_STORE_CTX *ctx, X509_NAME *nm)
+{
+    X509 *x;
+    STACK_OF(X509_CRL) *crls = NULL;
+    X509_CRL *crl;
+    STACK_OF(DIST_POINT) *crldp;
+
+    crls = sk_X509_CRL_new_null();
+    if (!crls)
+        return NULL;
+    x = X509_STORE_CTX_get_current_cert(ctx);
+    crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
+    crl = load_crl_crldp(crldp);
+    sk_DIST_POINT_pop_free(crldp, DIST_POINT_free);
+    if (!crl) {
+        sk_X509_CRL_free(crls);
+        return NULL;
+    }
+    sk_X509_CRL_push(crls, crl);
+    /* Try to download delta CRL */
+    crldp = X509_get_ext_d2i(x, NID_freshest_crl, NULL, NULL);
+    crl = load_crl_crldp(crldp);
+    sk_DIST_POINT_pop_free(crldp, DIST_POINT_free);
+    if (crl)
+        sk_X509_CRL_push(crls, crl);
+    return crls;
+}
+
+void store_setup_crl_download(X509_STORE *st)
+{
+    X509_STORE_set_lookup_crls_cb(st, crls_http_cb);
+}
+
+/*
+ * Platform-specific sections
+ */
+#if defined(_WIN32)
+# ifdef fileno
+#  undef fileno
+#  define fileno(a) (int)_fileno(a)
+# endif
+
+# include <windows.h>
+# include <tchar.h>
+
+static int WIN32_rename(const char *from, const char *to)
+{
+    TCHAR *tfrom = NULL, *tto;
+    DWORD err;
+    int ret = 0;
+
+    if (sizeof(TCHAR) == 1) {
+        tfrom = (TCHAR *)from;
+        tto = (TCHAR *)to;
+    } else {                    /* UNICODE path */
+
+        size_t i, flen = strlen(from) + 1, tlen = strlen(to) + 1;
+        tfrom = malloc(sizeof(*tfrom) * (flen + tlen));
+        if (tfrom == NULL)
+            goto err;
+        tto = tfrom + flen;
+# if !defined(_WIN32_WCE) || _WIN32_WCE>=101
+        if (!MultiByteToWideChar(CP_ACP, 0, from, flen, (WCHAR *)tfrom, flen))
+# endif
+            for (i = 0; i < flen; i++)
+                tfrom[i] = (TCHAR)from[i];
+# if !defined(_WIN32_WCE) || _WIN32_WCE>=101
+        if (!MultiByteToWideChar(CP_ACP, 0, to, tlen, (WCHAR *)tto, tlen))
+# endif
+            for (i = 0; i < tlen; i++)
+                tto[i] = (TCHAR)to[i];
+    }
+
+    if (MoveFile(tfrom, tto))
+        goto ok;
+    err = GetLastError();
+    if (err == ERROR_ALREADY_EXISTS || err == ERROR_FILE_EXISTS) {
+        if (DeleteFile(tto) && MoveFile(tfrom, tto))
+            goto ok;
+        err = GetLastError();
+    }
+    if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND)
+        errno = ENOENT;
+    else if (err == ERROR_ACCESS_DENIED)
+        errno = EACCES;
+    else
+        errno = EINVAL;         /* we could map more codes... */
+ err:
+    ret = -1;
+ ok:
+    if (tfrom != NULL && tfrom != (TCHAR *)from)
+        free(tfrom);
+    return ret;
+}
+#endif
+
+/* app_tminterval section */
+#if defined(_WIN32)
+double app_tminterval(int stop, int usertime)
+{
+    FILETIME now;
+    double ret = 0;
+    static ULARGE_INTEGER tmstart;
+    static int warning = 1;
+# ifdef _WIN32_WINNT
+    static HANDLE proc = NULL;
+
+    if (proc == NULL) {
+        if (check_winnt())
+            proc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
+                               GetCurrentProcessId());
+        if (proc == NULL)
+            proc = (HANDLE) - 1;
+    }
+
+    if (usertime && proc != (HANDLE) - 1) {
+        FILETIME junk;
+        GetProcessTimes(proc, &junk, &junk, &junk, &now);
+    } else
+# endif
+    {
+        SYSTEMTIME systime;
+
+        if (usertime && warning) {
+            BIO_printf(bio_err, "To get meaningful results, run "
+                       "this program on idle system.\n");
+            warning = 0;
+        }
+        GetSystemTime(&systime);
+        SystemTimeToFileTime(&systime, &now);
+    }
+
+    if (stop == TM_START) {
+        tmstart.u.LowPart = now.dwLowDateTime;
+        tmstart.u.HighPart = now.dwHighDateTime;
+    } else {
+        ULARGE_INTEGER tmstop;
+
+        tmstop.u.LowPart = now.dwLowDateTime;
+        tmstop.u.HighPart = now.dwHighDateTime;
+
+        ret = (__int64)(tmstop.QuadPart - tmstart.QuadPart) * 1e-7;
+    }
+
+    return (ret);
+}
+#elif defined(OPENSSL_SYSTEM_VXWORKS)
+# include <time.h>
+
+double app_tminterval(int stop, int usertime)
+{
+    double ret = 0;
+# ifdef CLOCK_REALTIME
+    static struct timespec tmstart;
+    struct timespec now;
+# else
+    static unsigned long tmstart;
+    unsigned long now;
+# endif
+    static int warning = 1;
+
+    if (usertime && warning) {
+        BIO_printf(bio_err, "To get meaningful results, run "
+                   "this program on idle system.\n");
+        warning = 0;
+    }
+# ifdef CLOCK_REALTIME
+    clock_gettime(CLOCK_REALTIME, &now);
+    if (stop == TM_START)
+        tmstart = now;
+    else
+        ret = ((now.tv_sec + now.tv_nsec * 1e-9)
+               - (tmstart.tv_sec + tmstart.tv_nsec * 1e-9));
+# else
+    now = tickGet();
+    if (stop == TM_START)
+        tmstart = now;
+    else
+        ret = (now - tmstart) / (double)sysClkRateGet();
+# endif
+    return (ret);
+}
+
+#elif defined(OPENSSL_SYSTEM_VMS)
+# include <time.h>
+# include <times.h>
+
+double app_tminterval(int stop, int usertime)
+{
+    static clock_t tmstart;
+    double ret = 0;
+    clock_t now;
+# ifdef __TMS
+    struct tms rus;
+
+    now = times(&rus);
+    if (usertime)
+        now = rus.tms_utime;
+# else
+    if (usertime)
+        now = clock();          /* sum of user and kernel times */
+    else {
+        struct timeval tv;
+        gettimeofday(&tv, NULL);
+        now = (clock_t)((unsigned long long)tv.tv_sec * CLK_TCK +
+                        (unsigned long long)tv.tv_usec * (1000000 / CLK_TCK)
+            );
+    }
+# endif
+    if (stop == TM_START)
+        tmstart = now;
+    else
+        ret = (now - tmstart) / (double)(CLK_TCK);
+
+    return (ret);
+}
+
+#elif defined(_SC_CLK_TCK)      /* by means of unistd.h */
+# include <sys/times.h>
+
+double app_tminterval(int stop, int usertime)
+{
+    double ret = 0;
+    struct tms rus;
+    clock_t now = times(&rus);
+    static clock_t tmstart;
+
+    if (usertime)
+        now = rus.tms_utime;
+
+    if (stop == TM_START)
+        tmstart = now;
+    else {
+        long int tck = sysconf(_SC_CLK_TCK);
+        ret = (now - tmstart) / (double)tck;
+    }
+
+    return (ret);
+}
+
+#else
+# include <sys/time.h>
+# include <sys/resource.h>
+
+double app_tminterval(int stop, int usertime)
+{
+    double ret = 0;
+    struct rusage rus;
+    struct timeval now;
+    static struct timeval tmstart;
+
+    if (usertime)
+        getrusage(RUSAGE_SELF, &rus), now = rus.ru_utime;
+    else
+        gettimeofday(&now, NULL);
+
+    if (stop == TM_START)
+        tmstart = now;
+    else
+        ret = ((now.tv_sec + now.tv_usec * 1e-6)
+               - (tmstart.tv_sec + tmstart.tv_usec * 1e-6));
+
+    return ret;
+}
+#endif
+
+int app_access(const char* name, int flag)
+{
+#ifdef _WIN32
+    return _access(name, flag);
+#else
+    return access(name, flag);
+#endif
+}
+
+/* app_isdir section */
+#ifdef _WIN32
+int app_isdir(const char *name)
+{
+    HANDLE hList;
+    WIN32_FIND_DATA FileData;
+# if defined(UNICODE) || defined(_UNICODE)
+    size_t i, len_0 = strlen(name) + 1;
+
+    if (len_0 > OSSL_NELEM(FileData.cFileName))
+        return -1;
+
+#  if !defined(_WIN32_WCE) || _WIN32_WCE>=101
+    if (!MultiByteToWideChar
+        (CP_ACP, 0, name, len_0, FileData.cFileName, len_0))
+#  endif
+        for (i = 0; i < len_0; i++)
+            FileData.cFileName[i] = (WCHAR)name[i];
+
+    hList = FindFirstFile(FileData.cFileName, &FileData);
+# else
+    hList = FindFirstFile(name, &FileData);
+# endif
+    if (hList == INVALID_HANDLE_VALUE)
+        return -1;
+    FindClose(hList);
+    return ((FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
+}
+#else
+# include <sys/stat.h>
+# ifndef S_ISDIR
+#  if defined(_S_IFMT) && defined(_S_IFDIR)
+#   define S_ISDIR(a)   (((a) & _S_IFMT) == _S_IFDIR)
+#  else
+#   define S_ISDIR(a)   (((a) & S_IFMT) == S_IFDIR)
+#  endif
+# endif
+
+int app_isdir(const char *name)
+{
+# if defined(S_ISDIR)
+    struct stat st;
+
+    if (stat(name, &st) == 0)
+        return S_ISDIR(st.st_mode);
+    else
+        return -1;
+# else
+    return -1;
+# endif
+}
+#endif
+
+/* raw_read|write section */
+#if defined(__VMS)
+# include "vms_term_sock.h"
+static int stdin_sock = -1;
+
+static void close_stdin_sock(void)
+{
+    TerminalSocket (TERM_SOCK_DELETE, &stdin_sock);
+}
+
+int fileno_stdin(void)
+{
+    if (stdin_sock == -1) {
+        TerminalSocket(TERM_SOCK_CREATE, &stdin_sock);
+        atexit(close_stdin_sock);
+    }
+
+    return stdin_sock;
+}
+#else
+int fileno_stdin(void)
+{
+    return fileno(stdin);
+}
+#endif
+
+int fileno_stdout(void)
+{
+    return fileno(stdout);
+}
+
+#if defined(_WIN32) && defined(STD_INPUT_HANDLE)
+int raw_read_stdin(void *buf, int siz)
+{
+    DWORD n;
+    if (ReadFile(GetStdHandle(STD_INPUT_HANDLE), buf, siz, &n, NULL))
+        return (n);
+    else
+        return (-1);
+}
+#elif defined(__VMS)
+#include <sys/socket.h>
+
+int raw_read_stdin(void *buf, int siz)
+{
+    return recv(fileno_stdin(), buf, siz, 0);
+}
+#else
+int raw_read_stdin(void *buf, int siz)
+{
+    return read(fileno_stdin(), buf, siz);
+}
+#endif
+
+#if defined(_WIN32) && defined(STD_OUTPUT_HANDLE)
+int raw_write_stdout(const void *buf, int siz)
+{
+    DWORD n;
+    if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, siz, &n, NULL))
+        return (n);
+    else
+        return (-1);
+}
+#else
+int raw_write_stdout(const void *buf, int siz)
+{
+    return write(fileno_stdout(), buf, siz);
+}
+#endif
+
+/*
+ * Centralized handling if input and output files with format specification
+ * The format is meant to show what the input and output is supposed to be,
+ * and is therefore a show of intent more than anything else.  However, it
+ * does impact behavior on some platform, such as differentiating between
+ * text and binary input/output on non-Unix platforms
+ */
+static int istext(int format)
+{
+    return (format & B_FORMAT_TEXT) == B_FORMAT_TEXT;
+}
+
+BIO *dup_bio_in(int format)
+{
+    return BIO_new_fp(stdin,
+                      BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0));
+}
+
+BIO *dup_bio_out(int format)
+{
+    BIO *b = BIO_new_fp(stdout,
+                        BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0));
+#ifdef OPENSSL_SYS_VMS
+    if (istext(format))
+        b = BIO_push(BIO_new(BIO_f_linebuffer()), b);
+#endif
+    return b;
+}
+
+BIO *dup_bio_err(int format)
+{
+    BIO *b = BIO_new_fp(stderr,
+                        BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0));
+#ifdef OPENSSL_SYS_VMS
+    if (istext(format))
+        b = BIO_push(BIO_new(BIO_f_linebuffer()), b);
+#endif
+    return b;
+}
+
+void unbuffer(FILE *fp)
+{
+/*
+ * On VMS, setbuf() will only take 32-bit pointers, and a compilation
+ * with /POINTER_SIZE=64 will give off a MAYLOSEDATA2 warning here.
+ * However, we trust that the C RTL will never give us a FILE pointer
+ * above the first 4 GB of memory, so we simply turn off the warning
+ * temporarily.
+ */
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+# pragma environment save
+# pragma message disable maylosedata2
+#endif
+    setbuf(fp, NULL);
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+# pragma environment restore
+#endif
+}
+
+static const char *modestr(char mode, int format)
+{
+    OPENSSL_assert(mode == 'a' || mode == 'r' || mode == 'w');
+
+    switch (mode) {
+    case 'a':
+        return istext(format) ? "a" : "ab";
+    case 'r':
+        return istext(format) ? "r" : "rb";
+    case 'w':
+        return istext(format) ? "w" : "wb";
+    }
+    /* The assert above should make sure we never reach this point */
+    return NULL;
+}
+
+static const char *modeverb(char mode)
+{
+    switch (mode) {
+    case 'a':
+        return "appending";
+    case 'r':
+        return "reading";
+    case 'w':
+        return "writing";
+    }
+    return "(doing something)";
+}
+
+/*
+ * Open a file for writing, owner-read-only.
+ */
+BIO *bio_open_owner(const char *filename, int format, int private)
+{
+    FILE *fp = NULL;
+    BIO *b = NULL;
+    int fd = -1, bflags, mode, textmode;
+
+    if (!private || filename == NULL || strcmp(filename, "-") == 0)
+        return bio_open_default(filename, 'w', format);
+
+    mode = O_WRONLY;
+#ifdef O_CREAT
+    mode |= O_CREAT;
+#endif
+#ifdef O_TRUNC
+    mode |= O_TRUNC;
+#endif
+    textmode = istext(format);
+    if (!textmode) {
+#ifdef O_BINARY
+        mode |= O_BINARY;
+#elif defined(_O_BINARY)
+        mode |= _O_BINARY;
+#endif
+    }
+
+#ifdef OPENSSL_SYS_VMS
+    /* VMS doesn't have O_BINARY, it just doesn't make sense.  But,
+     * it still needs to know that we're going binary, or fdopen()
+     * will fail with "invalid argument"...  so we tell VMS what the
+     * context is.
+     */
+    if (!textmode)
+        fd = open(filename, mode, 0600, "ctx=bin");
+    else
+#endif
+        fd = open(filename, mode, 0600);
+    if (fd < 0)
+        goto err;
+    fp = fdopen(fd, modestr('w', format));
+    if (fp == NULL)
+        goto err;
+    bflags = BIO_CLOSE;
+    if (textmode)
+        bflags |= BIO_FP_TEXT;
+    b = BIO_new_fp(fp, bflags);
+    if (b)
+        return b;
+
+ err:
+    BIO_printf(bio_err, "%s: Can't open \"%s\" for writing, %s\n",
+               opt_getprog(), filename, strerror(errno));
+    ERR_print_errors(bio_err);
+    /* If we have fp, then fdopen took over fd, so don't close both. */
+    if (fp)
+        fclose(fp);
+    else if (fd >= 0)
+        close(fd);
+    return NULL;
+}
+
+static BIO *bio_open_default_(const char *filename, char mode, int format,
+                              int quiet)
+{
+    BIO *ret;
+
+    if (filename == NULL || strcmp(filename, "-") == 0) {
+        ret = mode == 'r' ? dup_bio_in(format) : dup_bio_out(format);
+        if (quiet) {
+            ERR_clear_error();
+            return ret;
+        }
+        if (ret != NULL)
+            return ret;
+        BIO_printf(bio_err,
+                   "Can't open %s, %s\n",
+                   mode == 'r' ? "stdin" : "stdout", strerror(errno));
+    } else {
+        ret = BIO_new_file(filename, modestr(mode, format));
+        if (quiet) {
+            ERR_clear_error();
+            return ret;
+        }
+        if (ret != NULL)
+            return ret;
+        BIO_printf(bio_err,
+                   "Can't open %s for %s, %s\n",
+                   filename, modeverb(mode), strerror(errno));
+    }
+    ERR_print_errors(bio_err);
+    return NULL;
+}
+
+BIO *bio_open_default(const char *filename, char mode, int format)
+{
+    return bio_open_default_(filename, mode, format, 0);
+}
+
+BIO *bio_open_default_quiet(const char *filename, char mode, int format)
+{
+    return bio_open_default_(filename, mode, format, 1);
+}
+
+void wait_for_async(SSL *s)
+{
+    /* On Windows select only works for sockets, so we simply don't wait  */
+#ifndef OPENSSL_SYS_WINDOWS
+    int width = 0;
+    fd_set asyncfds;
+    OSSL_ASYNC_FD *fds;
+    size_t numfds;
+
+    if (!SSL_get_all_async_fds(s, NULL, &numfds))
+        return;
+    if (numfds == 0)
+        return;
+    fds = app_malloc(sizeof(OSSL_ASYNC_FD) * numfds, "allocate async fds");
+    if (!SSL_get_all_async_fds(s, fds, &numfds)) {
+        OPENSSL_free(fds);
+    }
+
+    FD_ZERO(&asyncfds);
+    while (numfds > 0) {
+        if (width <= (int)*fds)
+            width = (int)*fds + 1;
+        openssl_fdset((int)*fds, &asyncfds);
+        numfds--;
+        fds++;
+    }
+    select(width, (void *)&asyncfds, NULL, NULL, NULL);
+#endif
+}
+
+/* if OPENSSL_SYS_WINDOWS is defined then so is OPENSSL_SYS_MSDOS */
+#if defined(OPENSSL_SYS_MSDOS)
+int has_stdin_waiting(void)
+{
+# if defined(OPENSSL_SYS_WINDOWS)
+    HANDLE inhand = GetStdHandle(STD_INPUT_HANDLE);
+    DWORD events = 0;
+    INPUT_RECORD inputrec;
+    DWORD insize = 1;
+    BOOL peeked;
+
+    if (inhand == INVALID_HANDLE_VALUE) {
+        return 0;
+    }
+
+    peeked = PeekConsoleInput(inhand, &inputrec, insize, &events);
+    if (!peeked) {
+        /* Probably redirected input? _kbhit() does not work in this case */
+        if (!feof(stdin)) {
+            return 1;
+        }
+        return 0;
+    }
+# endif
+    return _kbhit();
+}
+#endif
+
+/* Corrupt a signature by modifying final byte */
+void corrupt_signature(const ASN1_STRING *signature)
+{
+        unsigned char *s = signature->data;
+        s[signature->length - 1] ^= 0x1;
+}
+
+int set_cert_times(X509 *x, const char *startdate, const char *enddate,
+                   int days)
+{
+    if (startdate == NULL || strcmp(startdate, "today") == 0) {
+        if (X509_gmtime_adj(X509_getm_notBefore(x), 0) == NULL)
+            return 0;
+    } else {
+        if (!ASN1_TIME_set_string(X509_getm_notBefore(x), startdate))
+            return 0;
+    }
+    if (enddate == NULL) {
+        if (X509_time_adj_ex(X509_getm_notAfter(x), days, 0, NULL)
+            == NULL)
+            return 0;
+    } else if (!ASN1_TIME_set_string(X509_getm_notAfter(x), enddate)) {
+        return 0;
+    }
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/apps.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/apps.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/apps.h	(revision 331)
@@ -0,0 +1,569 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_APPS_H
+# define HEADER_APPS_H
+
+# include "e_os.h"
+# if defined(__unix) || defined(__unix__)
+#  include <sys/time.h> /* struct timeval for DTLS */
+# endif
+# include <assert.h>
+
+# include <openssl/e_os2.h>
+# include <openssl/ossl_typ.h>
+# include <openssl/bio.h>
+# include <openssl/x509.h>
+# include <openssl/lhash.h>
+# include <openssl/conf.h>
+# include <openssl/txt_db.h>
+# include <openssl/engine.h>
+# include <openssl/ocsp.h>
+# include <signal.h>
+
+# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WINCE)
+#  define openssl_fdset(a,b) FD_SET((unsigned int)a, b)
+# else
+#  define openssl_fdset(a,b) FD_SET(a, b)
+# endif
+
+/*
+ * quick macro when you need to pass an unsigned char instead of a char.
+ * this is true for some implementations of the is*() functions, for
+ * example.
+ */
+#define _UC(c) ((unsigned char)(c))
+
+int app_RAND_load_file(const char *file, int dont_warn);
+int app_RAND_write_file(const char *file);
+/*
+ * When `file' is NULL, use defaults. `bio_e' is for error messages.
+ */
+void app_RAND_allow_write_file(void);
+long app_RAND_load_files(char *file); /* `file' is a list of files to read,
+                                       * separated by LIST_SEPARATOR_CHAR
+                                       * (see e_os.h).  The string is
+                                       * destroyed! */
+
+extern char *default_config_file;
+extern BIO *bio_in;
+extern BIO *bio_out;
+extern BIO *bio_err;
+BIO *dup_bio_in(int format);
+BIO *dup_bio_out(int format);
+BIO *dup_bio_err(int format);
+BIO *bio_open_owner(const char *filename, int format, int private);
+BIO *bio_open_default(const char *filename, char mode, int format);
+BIO *bio_open_default_quiet(const char *filename, char mode, int format);
+CONF *app_load_config(const char *filename);
+CONF *app_load_config_quiet(const char *filename);
+int app_load_modules(const CONF *config);
+void unbuffer(FILE *fp);
+void wait_for_async(SSL *s);
+# if defined(OPENSSL_SYS_MSDOS)
+int has_stdin_waiting(void);
+# endif
+
+void corrupt_signature(const ASN1_STRING *signature);
+int set_cert_times(X509 *x, const char *startdate, const char *enddate,
+                   int days);
+
+/*
+ * Common verification options.
+ */
+# define OPT_V_ENUM \
+        OPT_V__FIRST=2000, \
+        OPT_V_POLICY, OPT_V_PURPOSE, OPT_V_VERIFY_NAME, OPT_V_VERIFY_DEPTH, \
+        OPT_V_ATTIME, OPT_V_VERIFY_HOSTNAME, OPT_V_VERIFY_EMAIL, \
+        OPT_V_VERIFY_IP, OPT_V_IGNORE_CRITICAL, OPT_V_ISSUER_CHECKS, \
+        OPT_V_CRL_CHECK, OPT_V_CRL_CHECK_ALL, OPT_V_POLICY_CHECK, \
+        OPT_V_EXPLICIT_POLICY, OPT_V_INHIBIT_ANY, OPT_V_INHIBIT_MAP, \
+        OPT_V_X509_STRICT, OPT_V_EXTENDED_CRL, OPT_V_USE_DELTAS, \
+        OPT_V_POLICY_PRINT, OPT_V_CHECK_SS_SIG, OPT_V_TRUSTED_FIRST, \
+        OPT_V_SUITEB_128_ONLY, OPT_V_SUITEB_128, OPT_V_SUITEB_192, \
+        OPT_V_PARTIAL_CHAIN, OPT_V_NO_ALT_CHAINS, OPT_V_NO_CHECK_TIME, \
+        OPT_V_VERIFY_AUTH_LEVEL, OPT_V_ALLOW_PROXY_CERTS, \
+        OPT_V__LAST
+
+# define OPT_V_OPTIONS \
+        { "policy", OPT_V_POLICY, 's', "adds policy to the acceptable policy set"}, \
+        { "purpose", OPT_V_PURPOSE, 's', \
+            "certificate chain purpose"}, \
+        { "verify_name", OPT_V_VERIFY_NAME, 's', "verification policy name"}, \
+        { "verify_depth", OPT_V_VERIFY_DEPTH, 'n', \
+            "chain depth limit" }, \
+        { "auth_level", OPT_V_VERIFY_AUTH_LEVEL, 'n', \
+            "chain authentication security level" }, \
+        { "attime", OPT_V_ATTIME, 'M', "verification epoch time" }, \
+        { "verify_hostname", OPT_V_VERIFY_HOSTNAME, 's', \
+            "expected peer hostname" }, \
+        { "verify_email", OPT_V_VERIFY_EMAIL, 's', \
+            "expected peer email" }, \
+        { "verify_ip", OPT_V_VERIFY_IP, 's', \
+            "expected peer IP address" }, \
+        { "ignore_critical", OPT_V_IGNORE_CRITICAL, '-', \
+            "permit unhandled critical extensions"}, \
+        { "issuer_checks", OPT_V_ISSUER_CHECKS, '-', "(deprecated)"}, \
+        { "crl_check", OPT_V_CRL_CHECK, '-', "check leaf certificate revocation" }, \
+        { "crl_check_all", OPT_V_CRL_CHECK_ALL, '-', "check full chain revocation" }, \
+        { "policy_check", OPT_V_POLICY_CHECK, '-', "perform rfc5280 policy checks"}, \
+        { "explicit_policy", OPT_V_EXPLICIT_POLICY, '-', \
+            "set policy variable require-explicit-policy"}, \
+        { "inhibit_any", OPT_V_INHIBIT_ANY, '-', \
+            "set policy variable inhibit-any-policy"}, \
+        { "inhibit_map", OPT_V_INHIBIT_MAP, '-', \
+            "set policy variable inhibit-policy-mapping"}, \
+        { "x509_strict", OPT_V_X509_STRICT, '-', \
+            "disable certificate compatibility work-arounds"}, \
+        { "extended_crl", OPT_V_EXTENDED_CRL, '-', \
+            "enable extended CRL features"}, \
+        { "use_deltas", OPT_V_USE_DELTAS, '-', \
+            "use delta CRLs"}, \
+        { "policy_print", OPT_V_POLICY_PRINT, '-', \
+            "print policy processing diagnostics"}, \
+        { "check_ss_sig", OPT_V_CHECK_SS_SIG, '-', \
+            "check root CA self-signatures"}, \
+        { "trusted_first", OPT_V_TRUSTED_FIRST, '-', \
+            "search trust store first (default)" }, \
+        { "suiteB_128_only", OPT_V_SUITEB_128_ONLY, '-', "Suite B 128-bit-only mode"}, \
+        { "suiteB_128", OPT_V_SUITEB_128, '-', \
+            "Suite B 128-bit mode allowing 192-bit algorithms"}, \
+        { "suiteB_192", OPT_V_SUITEB_192, '-', "Suite B 192-bit-only mode" }, \
+        { "partial_chain", OPT_V_PARTIAL_CHAIN, '-', \
+            "accept chains anchored by intermediate trust-store CAs"}, \
+        { "no_alt_chains", OPT_V_NO_ALT_CHAINS, '-', "(deprecated)" }, \
+        { "no_check_time", OPT_V_NO_CHECK_TIME, '-', "ignore certificate validity time" }, \
+        { "allow_proxy_certs", OPT_V_ALLOW_PROXY_CERTS, '-', "allow the use of proxy certificates" }
+
+# define OPT_V_CASES \
+        OPT_V__FIRST: case OPT_V__LAST: break; \
+        case OPT_V_POLICY: \
+        case OPT_V_PURPOSE: \
+        case OPT_V_VERIFY_NAME: \
+        case OPT_V_VERIFY_DEPTH: \
+        case OPT_V_VERIFY_AUTH_LEVEL: \
+        case OPT_V_ATTIME: \
+        case OPT_V_VERIFY_HOSTNAME: \
+        case OPT_V_VERIFY_EMAIL: \
+        case OPT_V_VERIFY_IP: \
+        case OPT_V_IGNORE_CRITICAL: \
+        case OPT_V_ISSUER_CHECKS: \
+        case OPT_V_CRL_CHECK: \
+        case OPT_V_CRL_CHECK_ALL: \
+        case OPT_V_POLICY_CHECK: \
+        case OPT_V_EXPLICIT_POLICY: \
+        case OPT_V_INHIBIT_ANY: \
+        case OPT_V_INHIBIT_MAP: \
+        case OPT_V_X509_STRICT: \
+        case OPT_V_EXTENDED_CRL: \
+        case OPT_V_USE_DELTAS: \
+        case OPT_V_POLICY_PRINT: \
+        case OPT_V_CHECK_SS_SIG: \
+        case OPT_V_TRUSTED_FIRST: \
+        case OPT_V_SUITEB_128_ONLY: \
+        case OPT_V_SUITEB_128: \
+        case OPT_V_SUITEB_192: \
+        case OPT_V_PARTIAL_CHAIN: \
+        case OPT_V_NO_ALT_CHAINS: \
+        case OPT_V_NO_CHECK_TIME: \
+        case OPT_V_ALLOW_PROXY_CERTS
+
+/*
+ * Common "extended"? options.
+ */
+# define OPT_X_ENUM \
+        OPT_X__FIRST=1000, \
+        OPT_X_KEY, OPT_X_CERT, OPT_X_CHAIN, OPT_X_CHAIN_BUILD, \
+        OPT_X_CERTFORM, OPT_X_KEYFORM, \
+        OPT_X__LAST
+
+# define OPT_X_OPTIONS \
+        { "xkey", OPT_X_KEY, '<', "key for Extended certificates"}, \
+        { "xcert", OPT_X_CERT, '<', "cert for Extended certificates"}, \
+        { "xchain", OPT_X_CHAIN, '<', "chain for Extended certificates"}, \
+        { "xchain_build", OPT_X_CHAIN_BUILD, '-', \
+            "build certificate chain for the extended certificates"}, \
+        { "xcertform", OPT_X_CERTFORM, 'F', \
+            "format of Extended certificate (PEM or DER) PEM default " }, \
+        { "xkeyform", OPT_X_KEYFORM, 'F', \
+            "format of Extended certificate's key (PEM or DER) PEM default"}
+
+# define OPT_X_CASES \
+        OPT_X__FIRST: case OPT_X__LAST: break; \
+        case OPT_X_KEY: \
+        case OPT_X_CERT: \
+        case OPT_X_CHAIN: \
+        case OPT_X_CHAIN_BUILD: \
+        case OPT_X_CERTFORM: \
+        case OPT_X_KEYFORM
+
+/*
+ * Common SSL options.
+ * Any changes here must be coordinated with ../ssl/ssl_conf.c
+ */
+# define OPT_S_ENUM \
+        OPT_S__FIRST=3000, \
+        OPT_S_NOSSL3, OPT_S_NOTLS1, OPT_S_NOTLS1_1, OPT_S_NOTLS1_2, \
+        OPT_S_BUGS, OPT_S_NO_COMP, OPT_S_NOTICKET, \
+        OPT_S_SERVERPREF, OPT_S_LEGACYRENEG, OPT_S_LEGACYCONN, \
+        OPT_S_ONRESUMP, OPT_S_NOLEGACYCONN, OPT_S_STRICT, OPT_S_SIGALGS, \
+        OPT_S_CLIENTSIGALGS, OPT_S_CURVES, OPT_S_NAMEDCURVE, OPT_S_CIPHER, \
+        OPT_S_DHPARAM, OPT_S_DEBUGBROKE, OPT_S_COMP, \
+        OPT_S__LAST
+
+# define OPT_S_OPTIONS \
+        {"no_ssl3", OPT_S_NOSSL3, '-',"Just disable SSLv3" }, \
+        {"no_tls1", OPT_S_NOTLS1, '-', "Just disable TLSv1"}, \
+        {"no_tls1_1", OPT_S_NOTLS1_1, '-', "Just disable TLSv1.1" }, \
+        {"no_tls1_2", OPT_S_NOTLS1_2, '-', "Just disable TLSv1.2"}, \
+        {"bugs", OPT_S_BUGS, '-', "Turn on SSL bug compatibility"}, \
+        {"no_comp", OPT_S_NO_COMP, '-', "Disable SSL/TLS compression (default)" }, \
+        {"comp", OPT_S_COMP, '-', "Use SSL/TLS-level compression" }, \
+        {"no_ticket", OPT_S_NOTICKET, '-', \
+            "Disable use of TLS session tickets"}, \
+        {"serverpref", OPT_S_SERVERPREF, '-', "Use server's cipher preferences"}, \
+        {"legacy_renegotiation", OPT_S_LEGACYRENEG, '-', \
+            "Enable use of legacy renegotiation (dangerous)"}, \
+        {"legacy_server_connect", OPT_S_LEGACYCONN, '-', \
+            "Allow initial connection to servers that don't support RI"}, \
+        {"no_resumption_on_reneg", OPT_S_ONRESUMP, '-', \
+            "Disallow session resumption on renegotiation"}, \
+        {"no_legacy_server_connect", OPT_S_NOLEGACYCONN, '-', \
+            "Disallow initial connection to servers that don't support RI"}, \
+        {"strict", OPT_S_STRICT, '-', \
+            "Enforce strict certificate checks as per TLS standard"}, \
+        {"sigalgs", OPT_S_SIGALGS, 's', \
+            "Signature algorithms to support (colon-separated list)" }, \
+        {"client_sigalgs", OPT_S_CLIENTSIGALGS, 's', \
+            "Signature algorithms to support for client certificate" \
+            " authentication (colon-separated list)" }, \
+        {"curves", OPT_S_CURVES, 's', \
+            "Elliptic curves to advertise (colon-separated list)" }, \
+        {"named_curve", OPT_S_NAMEDCURVE, 's', \
+            "Elliptic curve used for ECDHE (server-side only)" }, \
+        {"cipher", OPT_S_CIPHER, 's', "Specify cipher list to be used"}, \
+        {"dhparam", OPT_S_DHPARAM, '<', \
+            "DH parameter file to use, in cert file if not specified"}, \
+        {"debug_broken_protocol", OPT_S_DEBUGBROKE, '-', \
+            "Perform all sorts of protocol violations for testing purposes"}
+
+# define OPT_S_CASES \
+        OPT_S__FIRST: case OPT_S__LAST: break; \
+        case OPT_S_NOSSL3: \
+        case OPT_S_NOTLS1: \
+        case OPT_S_NOTLS1_1: \
+        case OPT_S_NOTLS1_2: \
+        case OPT_S_BUGS: \
+        case OPT_S_NO_COMP: \
+        case OPT_S_COMP: \
+        case OPT_S_NOTICKET: \
+        case OPT_S_SERVERPREF: \
+        case OPT_S_LEGACYRENEG: \
+        case OPT_S_LEGACYCONN: \
+        case OPT_S_ONRESUMP: \
+        case OPT_S_NOLEGACYCONN: \
+        case OPT_S_STRICT: \
+        case OPT_S_SIGALGS: \
+        case OPT_S_CLIENTSIGALGS: \
+        case OPT_S_CURVES: \
+        case OPT_S_NAMEDCURVE: \
+        case OPT_S_CIPHER: \
+        case OPT_S_DHPARAM: \
+        case OPT_S_DEBUGBROKE
+
+#define IS_NO_PROT_FLAG(o) \
+ (o == OPT_S_NOSSL3 || o == OPT_S_NOTLS1 || o == OPT_S_NOTLS1_1 \
+  || o == OPT_S_NOTLS1_2)
+
+/*
+ * Option parsing.
+ */
+extern const char OPT_HELP_STR[];
+extern const char OPT_MORE_STR[];
+typedef struct options_st {
+    const char *name;
+    int retval;
+    /*
+     * value type: - no value (also the value zero), n number, p positive
+     * number, u unsigned, l long, s string, < input file, > output file,
+     * f any format, F der/pem format , E der/pem/engine format identifier.
+     * l, n and u include zero; p does not.
+     */
+    int valtype;
+    const char *helpstr;
+} OPTIONS;
+
+/*
+ * A string/int pairing; widely use for option value lookup, hence the
+ * name OPT_PAIR. But that name is misleading in s_cb.c, so we also use
+ * the "generic" name STRINT_PAIR.
+ */
+typedef struct string_int_pair_st {
+    const char *name;
+    int retval;
+} OPT_PAIR, STRINT_PAIR;
+
+/* Flags to pass into opt_format; see FORMAT_xxx, below. */
+# define OPT_FMT_PEMDER          (1L <<  1)
+# define OPT_FMT_PKCS12          (1L <<  2)
+# define OPT_FMT_SMIME           (1L <<  3)
+# define OPT_FMT_ENGINE          (1L <<  4)
+# define OPT_FMT_MSBLOB          (1L <<  5)
+# define OPT_FMT_NETSCAPE        (1L <<  6)
+# define OPT_FMT_NSS             (1L <<  7)
+# define OPT_FMT_TEXT            (1L <<  8)
+# define OPT_FMT_HTTP            (1L <<  9)
+# define OPT_FMT_PVK             (1L << 10)
+# define OPT_FMT_PDE     (OPT_FMT_PEMDER | OPT_FMT_ENGINE)
+# define OPT_FMT_PDS     (OPT_FMT_PEMDER | OPT_FMT_SMIME)
+# define OPT_FMT_ANY     ( \
+        OPT_FMT_PEMDER | OPT_FMT_PKCS12 | OPT_FMT_SMIME | \
+        OPT_FMT_ENGINE | OPT_FMT_MSBLOB | OPT_FMT_NETSCAPE | \
+        OPT_FMT_NSS | OPT_FMT_TEXT | OPT_FMT_HTTP | OPT_FMT_PVK)
+
+char *opt_progname(const char *argv0);
+char *opt_getprog(void);
+char *opt_init(int ac, char **av, const OPTIONS * o);
+int opt_next(void);
+int opt_format(const char *s, unsigned long flags, int *result);
+int opt_int(const char *arg, int *result);
+int opt_ulong(const char *arg, unsigned long *result);
+int opt_long(const char *arg, long *result);
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && \
+    defined(INTMAX_MAX) && defined(UINTMAX_MAX)
+int opt_imax(const char *arg, intmax_t *result);
+int opt_umax(const char *arg, uintmax_t *result);
+#else
+# define opt_imax opt_long
+# define opt_umax opt_ulong
+# define intmax_t long
+# define uintmax_t unsigned long
+#endif
+int opt_pair(const char *arg, const OPT_PAIR * pairs, int *result);
+int opt_cipher(const char *name, const EVP_CIPHER **cipherp);
+int opt_md(const char *name, const EVP_MD **mdp);
+char *opt_arg(void);
+char *opt_flag(void);
+char *opt_unknown(void);
+char *opt_reset(void);
+char **opt_rest(void);
+int opt_num_rest(void);
+int opt_verify(int i, X509_VERIFY_PARAM *vpm);
+void opt_help(const OPTIONS * list);
+int opt_format_error(const char *s, unsigned long flags);
+
+typedef struct args_st {
+    int size;
+    int argc;
+    char **argv;
+} ARGS;
+
+/*
+ * VMS C only for now, implemented in vms_decc_init.c
+ * If other C compilers forget to terminate argv with NULL, this function
+ * can be re-used.
+ */
+char **copy_argv(int *argc, char *argv[]);
+/*
+ * Win32-specific argv initialization that splits OS-supplied UNICODE
+ * command line string to array of UTF8-encoded strings.
+ */
+void win32_utf8argv(int *argc, char **argv[]);
+
+
+# define PW_MIN_LENGTH 4
+typedef struct pw_cb_data {
+    const void *password;
+    const char *prompt_info;
+} PW_CB_DATA;
+
+int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_data);
+
+int setup_ui_method(void);
+void destroy_ui_method(void);
+
+int chopup_args(ARGS *arg, char *buf);
+# ifdef HEADER_X509_H
+int dump_cert_text(BIO *out, X509 *x);
+void print_name(BIO *out, const char *title, X509_NAME *nm,
+                unsigned long lflags);
+# endif
+void print_bignum_var(BIO *, const BIGNUM *, const char*,
+                      int, unsigned char *);
+void print_array(BIO *, const char *, int, const unsigned char *);
+int set_cert_ex(unsigned long *flags, const char *arg);
+int set_name_ex(unsigned long *flags, const char *arg);
+int set_ext_copy(int *copy_type, const char *arg);
+int copy_extensions(X509 *x, X509_REQ *req, int copy_type);
+int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2);
+int add_oid_section(CONF *conf);
+X509 *load_cert(const char *file, int format, const char *cert_descrip);
+X509_CRL *load_crl(const char *infile, int format);
+EVP_PKEY *load_key(const char *file, int format, int maybe_stdin,
+                   const char *pass, ENGINE *e, const char *key_descrip);
+EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin,
+                      const char *pass, ENGINE *e, const char *key_descrip);
+int load_certs(const char *file, STACK_OF(X509) **certs, int format,
+               const char *pass, const char *cert_descrip);
+int load_crls(const char *file, STACK_OF(X509_CRL) **crls, int format,
+              const char *pass, const char *cert_descrip);
+X509_STORE *setup_verify(const char *CAfile, const char *CApath,
+                         int noCAfile, int noCApath);
+__owur int ctx_set_verify_locations(SSL_CTX *ctx, const char *CAfile,
+                                    const char *CApath, int noCAfile,
+                                    int noCApath);
+
+#ifndef OPENSSL_NO_CT
+
+/*
+ * Sets the file to load the Certificate Transparency log list from.
+ * If path is NULL, loads from the default file path.
+ * Returns 1 on success, 0 otherwise.
+ */
+__owur int ctx_set_ctlog_list_file(SSL_CTX *ctx, const char *path);
+
+#endif
+
+ENGINE *setup_engine(const char *engine, int debug);
+void release_engine(ENGINE *e);
+
+# ifndef OPENSSL_NO_OCSP
+OCSP_RESPONSE *process_responder(OCSP_REQUEST *req,
+                                 const char *host, const char *path,
+                                 const char *port, int use_ssl,
+                                 STACK_OF(CONF_VALUE) *headers,
+                                 int req_timeout);
+# endif
+
+/* Functions defined in ca.c and also used in ocsp.c */
+int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
+                   ASN1_GENERALIZEDTIME **pinvtm, const char *str);
+
+# define DB_type         0
+# define DB_exp_date     1
+# define DB_rev_date     2
+# define DB_serial       3      /* index - unique */
+# define DB_file         4
+# define DB_name         5      /* index - unique when active and not
+                                 * disabled */
+# define DB_NUMBER       6
+
+# define DB_TYPE_REV     'R'
+# define DB_TYPE_EXP     'E'
+# define DB_TYPE_VAL     'V'
+
+typedef struct db_attr_st {
+    int unique_subject;
+} DB_ATTR;
+typedef struct ca_db_st {
+    DB_ATTR attributes;
+    TXT_DB *db;
+} CA_DB;
+
+void* app_malloc(int sz, const char *what);
+BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai);
+int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial,
+                ASN1_INTEGER **retai);
+int rotate_serial(const char *serialfile, const char *new_suffix,
+                  const char *old_suffix);
+int rand_serial(BIGNUM *b, ASN1_INTEGER *ai);
+CA_DB *load_index(const char *dbfile, DB_ATTR *dbattr);
+int index_index(CA_DB *db);
+int save_index(const char *dbfile, const char *suffix, CA_DB *db);
+int rotate_index(const char *dbfile, const char *new_suffix,
+                 const char *old_suffix);
+void free_index(CA_DB *db);
+# define index_name_cmp_noconst(a, b) \
+        index_name_cmp((const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, a), \
+        (const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, b))
+int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b);
+int parse_yesno(const char *str, int def);
+
+X509_NAME *parse_name(const char *str, long chtype, int multirdn);
+int args_verify(char ***pargs, int *pargc,
+                int *badarg, X509_VERIFY_PARAM **pm);
+void policies_print(X509_STORE_CTX *ctx);
+int bio_to_mem(unsigned char **out, int maxlen, BIO *in);
+int pkey_ctrl_string(EVP_PKEY_CTX *ctx, const char *value);
+int init_gen_str(EVP_PKEY_CTX **pctx,
+                 const char *algname, ENGINE *e, int do_param);
+int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
+                 STACK_OF(OPENSSL_STRING) *sigopts);
+int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
+                     STACK_OF(OPENSSL_STRING) *sigopts);
+int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
+                     STACK_OF(OPENSSL_STRING) *sigopts);
+# ifndef OPENSSL_NO_PSK
+extern char *psk_key;
+# endif
+
+unsigned char *next_protos_parse(size_t *outlen, const char *in);
+
+void print_cert_checks(BIO *bio, X509 *x,
+                       const char *checkhost,
+                       const char *checkemail, const char *checkip);
+
+void store_setup_crl_download(X509_STORE *st);
+
+/* See OPT_FMT_xxx, above. */
+/* On some platforms, it's important to distinguish between text and binary
+ * files.  On some, there might even be specific file formats for different
+ * contents.  The FORMAT_xxx macros are meant to express an intent with the
+ * file being read or created.
+ */
+# define B_FORMAT_TEXT   0x8000
+# define FORMAT_UNDEF    0
+# define FORMAT_TEXT    (1 | B_FORMAT_TEXT)     /* Generic text */
+# define FORMAT_BINARY   2                      /* Generic binary */
+# define FORMAT_BASE64  (3 | B_FORMAT_TEXT)     /* Base64 */
+# define FORMAT_ASN1     4                      /* ASN.1/DER */
+# define FORMAT_PEM     (5 | B_FORMAT_TEXT)
+# define FORMAT_PKCS12   6
+# define FORMAT_SMIME   (7 | B_FORMAT_TEXT)
+# define FORMAT_ENGINE   8                      /* Not really a file format */
+# define FORMAT_PEMRSA  (9 | B_FORMAT_TEXT)     /* PEM RSAPubicKey format */
+# define FORMAT_ASN1RSA  10                     /* DER RSAPubicKey format */
+# define FORMAT_MSBLOB   11                     /* MS Key blob format */
+# define FORMAT_PVK      12                     /* MS PVK file format */
+# define FORMAT_HTTP     13                     /* Download using HTTP */
+# define FORMAT_NSS      14                     /* NSS keylog format */
+
+# define EXT_COPY_NONE   0
+# define EXT_COPY_ADD    1
+# define EXT_COPY_ALL    2
+
+# define NETSCAPE_CERT_HDR       "certificate"
+
+# define APP_PASS_LEN    1024
+
+# define SERIAL_RAND_BITS        64
+
+int app_isdir(const char *);
+int app_access(const char *, int flag);
+int fileno_stdin(void);
+int fileno_stdout(void);
+int raw_read_stdin(void *, int);
+int raw_write_stdout(const void *, int);
+
+# define TM_START        0
+# define TM_STOP         1
+double app_tminterval(int stop, int usertime);
+
+typedef struct verify_options_st {
+    int depth;
+    int quiet;
+    int error;
+    int return_error;
+} VERIFY_CB_ARGS;
+
+extern VERIFY_CB_ARGS verify_args;
+
+# include "progs.h"
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/asn1pars.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/asn1pars.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/asn1pars.c	(revision 331)
@@ -0,0 +1,330 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*
+ * A nice addition from Dr Stephen Henson <steve@openssl.org> to add the
+ * -strparse option which parses nested binary structures
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_INFORM, OPT_IN, OPT_OUT, OPT_INDENT, OPT_NOOUT,
+    OPT_OID, OPT_OFFSET, OPT_LENGTH, OPT_DUMP, OPT_DLIMIT,
+    OPT_STRPARSE, OPT_GENSTR, OPT_GENCONF, OPT_STRICTPEM
+} OPTION_CHOICE;
+
+OPTIONS asn1parse_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"inform", OPT_INFORM, 'F', "input format - one of DER PEM"},
+    {"in", OPT_IN, '<', "input file"},
+    {"out", OPT_OUT, '>', "output file (output format is always DER)"},
+    {"i", OPT_INDENT, 0, "indents the output"},
+    {"noout", OPT_NOOUT, 0, "do not produce any output"},
+    {"offset", OPT_OFFSET, 'p', "offset into file"},
+    {"length", OPT_LENGTH, 'p', "length of section in file"},
+    {"oid", OPT_OID, '<', "file of extra oid definitions"},
+    {"dump", OPT_DUMP, 0, "unknown data in hex form"},
+    {"dlimit", OPT_DLIMIT, 'p',
+     "dump the first arg bytes of unknown data in hex form"},
+    {"strparse", OPT_STRPARSE, 's',
+     "offset; a series of these can be used to 'dig'"},
+    {OPT_MORE_STR, 0, 0, "into multiple ASN1 blob wrappings"},
+    {"genstr", OPT_GENSTR, 's', "string to generate ASN1 structure from"},
+    {"genconf", OPT_GENCONF, 's', "file to generate ASN1 structure from"},
+    {OPT_MORE_STR, 0, 0, "(-inform  will be ignored)"},
+    {"strictpem", OPT_STRICTPEM, 0,
+     "do not attempt base64 decode outside PEM markers"},
+    {NULL}
+};
+
+static int do_generate(char *genstr, const char *genconf, BUF_MEM *buf);
+
+int asn1parse_main(int argc, char **argv)
+{
+    ASN1_TYPE *at = NULL;
+    BIO *in = NULL, *b64 = NULL, *derout = NULL;
+    BUF_MEM *buf = NULL;
+    STACK_OF(OPENSSL_STRING) *osk = NULL;
+    char *genstr = NULL, *genconf = NULL;
+    char *infile = NULL, *oidfile = NULL, *derfile = NULL;
+    unsigned char *str = NULL;
+    char *name = NULL, *header = NULL, *prog;
+    const unsigned char *ctmpbuf;
+    int indent = 0, noout = 0, dump = 0, strictpem = 0, informat = FORMAT_PEM;
+    int offset = 0, ret = 1, i, j;
+    long num, tmplen;
+    unsigned char *tmpbuf;
+    unsigned int length = 0;
+    OPTION_CHOICE o;
+
+    prog = opt_init(argc, argv, asn1parse_options);
+
+    if ((osk = sk_OPENSSL_STRING_new_null()) == NULL) {
+        BIO_printf(bio_err, "%s: Memory allocation failure\n", prog);
+        goto end;
+    }
+
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(asn1parse_options);
+            ret = 0;
+            goto end;
+        case OPT_INFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
+                goto opthelp;
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUT:
+            derfile = opt_arg();
+            break;
+        case OPT_INDENT:
+            indent = 1;
+            break;
+        case OPT_NOOUT:
+            noout = 1;
+            break;
+        case OPT_OID:
+            oidfile = opt_arg();
+            break;
+        case OPT_OFFSET:
+            offset = strtol(opt_arg(), NULL, 0);
+            break;
+        case OPT_LENGTH:
+            length = atoi(opt_arg());
+            break;
+        case OPT_DUMP:
+            dump = -1;
+            break;
+        case OPT_DLIMIT:
+            dump = atoi(opt_arg());
+            break;
+        case OPT_STRPARSE:
+            sk_OPENSSL_STRING_push(osk, opt_arg());
+            break;
+        case OPT_GENSTR:
+            genstr = opt_arg();
+            break;
+        case OPT_GENCONF:
+            genconf = opt_arg();
+            break;
+        case OPT_STRICTPEM:
+            strictpem = 1;
+            informat = FORMAT_PEM;
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    if (oidfile != NULL) {
+        in = bio_open_default(oidfile, 'r', FORMAT_TEXT);
+        if (in == NULL)
+            goto end;
+        OBJ_create_objects(in);
+        BIO_free(in);
+    }
+
+    if ((in = bio_open_default(infile, 'r', informat)) == NULL)
+        goto end;
+
+    if (derfile && (derout = bio_open_default(derfile, 'w', FORMAT_ASN1)) == NULL)
+        goto end;
+
+    if (strictpem) {
+        if (PEM_read_bio(in, &name, &header, &str, &num) !=
+            1) {
+            BIO_printf(bio_err, "Error reading PEM file\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    } else {
+
+        if ((buf = BUF_MEM_new()) == NULL)
+            goto end;
+        if (!BUF_MEM_grow(buf, BUFSIZ * 8))
+            goto end;           /* Pre-allocate :-) */
+
+        if (genstr || genconf) {
+            num = do_generate(genstr, genconf, buf);
+            if (num < 0) {
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+        }
+
+        else {
+
+            if (informat == FORMAT_PEM) {
+                BIO *tmp;
+
+                if ((b64 = BIO_new(BIO_f_base64())) == NULL)
+                    goto end;
+                BIO_push(b64, in);
+                tmp = in;
+                in = b64;
+                b64 = tmp;
+            }
+
+            num = 0;
+            for (;;) {
+                if (!BUF_MEM_grow(buf, (int)num + BUFSIZ))
+                    goto end;
+                i = BIO_read(in, &(buf->data[num]), BUFSIZ);
+                if (i <= 0)
+                    break;
+                num += i;
+            }
+        }
+        str = (unsigned char *)buf->data;
+
+    }
+
+    /* If any structs to parse go through in sequence */
+
+    if (sk_OPENSSL_STRING_num(osk)) {
+        tmpbuf = str;
+        tmplen = num;
+        for (i = 0; i < sk_OPENSSL_STRING_num(osk); i++) {
+            ASN1_TYPE *atmp;
+            int typ;
+            j = atoi(sk_OPENSSL_STRING_value(osk, i));
+            if (j == 0) {
+                BIO_printf(bio_err, "'%s' is an invalid number\n",
+                           sk_OPENSSL_STRING_value(osk, i));
+                continue;
+            }
+            tmpbuf += j;
+            tmplen -= j;
+            atmp = at;
+            ctmpbuf = tmpbuf;
+            at = d2i_ASN1_TYPE(NULL, &ctmpbuf, tmplen);
+            ASN1_TYPE_free(atmp);
+            if (!at) {
+                BIO_printf(bio_err, "Error parsing structure\n");
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+            typ = ASN1_TYPE_get(at);
+            if ((typ == V_ASN1_OBJECT)
+                || (typ == V_ASN1_BOOLEAN)
+                || (typ == V_ASN1_NULL)) {
+                BIO_printf(bio_err, "Can't parse %s type\n", ASN1_tag2str(typ));
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+            /* hmm... this is a little evil but it works */
+            tmpbuf = at->value.asn1_string->data;
+            tmplen = at->value.asn1_string->length;
+        }
+        str = tmpbuf;
+        num = tmplen;
+    }
+
+    if (offset >= num) {
+        BIO_printf(bio_err, "Error: offset too large\n");
+        goto end;
+    }
+
+    num -= offset;
+
+    if ((length == 0) || ((long)length > num))
+        length = (unsigned int)num;
+    if (derout) {
+        if (BIO_write(derout, str + offset, length) != (int)length) {
+            BIO_printf(bio_err, "Error writing output\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+    if (!noout &&
+        !ASN1_parse_dump(bio_out, &(str[offset]), length,
+                         indent, dump)) {
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+    ret = 0;
+ end:
+    BIO_free(derout);
+    BIO_free(in);
+    BIO_free(b64);
+    if (ret != 0)
+        ERR_print_errors(bio_err);
+    BUF_MEM_free(buf);
+    OPENSSL_free(name);
+    OPENSSL_free(header);
+    if (strictpem)
+        OPENSSL_free(str);
+    ASN1_TYPE_free(at);
+    sk_OPENSSL_STRING_free(osk);
+    return (ret);
+}
+
+static int do_generate(char *genstr, const char *genconf, BUF_MEM *buf)
+{
+    CONF *cnf = NULL;
+    int len;
+    unsigned char *p;
+    ASN1_TYPE *atyp = NULL;
+
+    if (genconf) {
+        if ((cnf = app_load_config(genconf)) == NULL)
+            goto err;
+        if (!genstr)
+            genstr = NCONF_get_string(cnf, "default", "asn1");
+        if (!genstr) {
+            BIO_printf(bio_err, "Can't find 'asn1' in '%s'\n", genconf);
+            goto err;
+        }
+    }
+
+    atyp = ASN1_generate_nconf(genstr, cnf);
+    NCONF_free(cnf);
+    cnf = NULL;
+
+    if (!atyp)
+        return -1;
+
+    len = i2d_ASN1_TYPE(atyp, NULL);
+
+    if (len <= 0)
+        goto err;
+
+    if (!BUF_MEM_grow(buf, len))
+        goto err;
+
+    p = (unsigned char *)buf->data;
+
+    i2d_ASN1_TYPE(atyp, &p);
+
+    ASN1_TYPE_free(atyp);
+    return len;
+
+ err:
+    NCONF_free(cnf);
+    ASN1_TYPE_free(atyp);
+    return -1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/ca.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/ca.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/ca.c	(revision 331)
@@ -0,0 +1,2565 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* The PPKI stuff has been donated by Jeff Barber <jeffb@issl.atl.hp.com> */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <openssl/conf.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/txt_db.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/objects.h>
+#include <openssl/ocsp.h>
+#include <openssl/pem.h>
+
+#ifndef W_OK
+# ifdef OPENSSL_SYS_VMS
+#  if defined(__DECC)
+#   include <unistd.h>
+#  else
+#   include <unixlib.h>
+#  endif
+# elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS)
+#  include <sys/file.h>
+# endif
+#endif
+
+#include "apps.h"
+
+#ifndef W_OK
+# define F_OK 0
+# define X_OK 1
+# define W_OK 2
+# define R_OK 4
+#endif
+
+#undef BSIZE
+#define BSIZE 256
+
+#define BASE_SECTION            "ca"
+
+#define ENV_DEFAULT_CA          "default_ca"
+
+#define STRING_MASK             "string_mask"
+#define UTF8_IN                 "utf8"
+
+#define ENV_NEW_CERTS_DIR       "new_certs_dir"
+#define ENV_CERTIFICATE         "certificate"
+#define ENV_SERIAL              "serial"
+#define ENV_CRLNUMBER           "crlnumber"
+#define ENV_PRIVATE_KEY         "private_key"
+#define ENV_DEFAULT_DAYS        "default_days"
+#define ENV_DEFAULT_STARTDATE   "default_startdate"
+#define ENV_DEFAULT_ENDDATE     "default_enddate"
+#define ENV_DEFAULT_CRL_DAYS    "default_crl_days"
+#define ENV_DEFAULT_CRL_HOURS   "default_crl_hours"
+#define ENV_DEFAULT_MD          "default_md"
+#define ENV_DEFAULT_EMAIL_DN    "email_in_dn"
+#define ENV_PRESERVE            "preserve"
+#define ENV_POLICY              "policy"
+#define ENV_EXTENSIONS          "x509_extensions"
+#define ENV_CRLEXT              "crl_extensions"
+#define ENV_MSIE_HACK           "msie_hack"
+#define ENV_NAMEOPT             "name_opt"
+#define ENV_CERTOPT             "cert_opt"
+#define ENV_EXTCOPY             "copy_extensions"
+#define ENV_UNIQUE_SUBJECT      "unique_subject"
+
+#define ENV_DATABASE            "database"
+
+/* Additional revocation information types */
+
+#define REV_NONE                0 /* No additional information */
+#define REV_CRL_REASON          1 /* Value is CRL reason code */
+#define REV_HOLD                2 /* Value is hold instruction */
+#define REV_KEY_COMPROMISE      3 /* Value is cert key compromise time */
+#define REV_CA_COMPROMISE       4 /* Value is CA key compromise time */
+
+static char *lookup_conf(const CONF *conf, const char *group, const char *tag);
+
+static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
+                   const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
+                   STACK_OF(CONF_VALUE) *policy, CA_DB *db,
+                   BIGNUM *serial, const char *subj, unsigned long chtype,
+                   int multirdn, int email_dn, const char *startdate,
+                   const char *enddate,
+                   long days, int batch, const char *ext_sect, CONF *conf,
+                   int verbose, unsigned long certopt, unsigned long nameopt,
+                   int default_op, int ext_copy, int selfsign);
+static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
+                        const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
+                        STACK_OF(CONF_VALUE) *policy, CA_DB *db,
+                        BIGNUM *serial, const char *subj, unsigned long chtype,
+                        int multirdn, int email_dn, const char *startdate,
+                        const char *enddate, long days, int batch, const char *ext_sect,
+                        CONF *conf, int verbose, unsigned long certopt,
+                        unsigned long nameopt, int default_op, int ext_copy);
+static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey,
+                         X509 *x509, const EVP_MD *dgst,
+                         STACK_OF(OPENSSL_STRING) *sigopts,
+                         STACK_OF(CONF_VALUE) *policy, CA_DB *db,
+                         BIGNUM *serial, const char *subj, unsigned long chtype,
+                         int multirdn, int email_dn, const char *startdate,
+                         const char *enddate, long days, const char *ext_sect, CONF *conf,
+                         int verbose, unsigned long certopt,
+                         unsigned long nameopt, int default_op, int ext_copy);
+static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
+static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
+                   const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
+                   STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,
+                   const char *subj, unsigned long chtype, int multirdn,
+                   int email_dn, const char *startdate, const char *enddate, long days,
+                   int batch, int verbose, X509_REQ *req, const char *ext_sect,
+                   CONF *conf, unsigned long certopt, unsigned long nameopt,
+                   int default_op, int ext_copy, int selfsign);
+static int do_revoke(X509 *x509, CA_DB *db, int ext, char *extval);
+static int get_certificate_status(const char *ser_status, CA_DB *db);
+static int do_updatedb(CA_DB *db);
+static int check_time_format(const char *str);
+char *make_revocation_str(int rev_type, char *rev_arg);
+int make_revoked(X509_REVOKED *rev, const char *str);
+static int old_entry_print(const ASN1_OBJECT *obj, const ASN1_STRING *str);
+
+static CONF *extconf = NULL;
+static int preserve = 0;
+static int msie_hack = 0;
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_ENGINE, OPT_VERBOSE, OPT_CONFIG, OPT_NAME, OPT_SUBJ, OPT_UTF8,
+    OPT_CREATE_SERIAL, OPT_MULTIVALUE_RDN, OPT_STARTDATE, OPT_ENDDATE,
+    OPT_DAYS, OPT_MD, OPT_POLICY, OPT_KEYFILE, OPT_KEYFORM, OPT_PASSIN,
+    OPT_KEY, OPT_CERT, OPT_SELFSIGN, OPT_IN, OPT_OUT, OPT_OUTDIR,
+    OPT_SIGOPT, OPT_NOTEXT, OPT_BATCH, OPT_PRESERVEDN, OPT_NOEMAILDN,
+    OPT_GENCRL, OPT_MSIE_HACK, OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC,
+    OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID,
+    OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS,
+    OPT_CRL_REASON, OPT_CRL_HOLD, OPT_CRL_COMPROMISE,
+    OPT_CRL_CA_COMPROMISE
+} OPTION_CHOICE;
+
+OPTIONS ca_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"verbose", OPT_VERBOSE, '-', "Verbose output during processing"},
+    {"config", OPT_CONFIG, 's', "A config file"},
+    {"name", OPT_NAME, 's', "The particular CA definition to use"},
+    {"subj", OPT_SUBJ, 's', "Use arg instead of request's subject"},
+    {"utf8", OPT_UTF8, '-', "Input characters are UTF8 (default ASCII)"},
+    {"create_serial", OPT_CREATE_SERIAL, '-',
+     "If reading serial fails, create a new random serial"},
+    {"multivalue-rdn", OPT_MULTIVALUE_RDN, '-',
+     "Enable support for multivalued RDNs"},
+    {"startdate", OPT_STARTDATE, 's', "Cert notBefore, YYMMDDHHMMSSZ"},
+    {"enddate", OPT_ENDDATE, 's',
+     "YYMMDDHHMMSSZ cert notAfter (overrides -days)"},
+    {"days", OPT_DAYS, 'p', "Number of days to certify the cert for"},
+    {"md", OPT_MD, 's', "md to use; one of md2, md5, sha or sha1"},
+    {"policy", OPT_POLICY, 's', "The CA 'policy' to support"},
+    {"keyfile", OPT_KEYFILE, 's', "Private key"},
+    {"keyform", OPT_KEYFORM, 'f', "Private key file format (PEM or ENGINE)"},
+    {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
+    {"key", OPT_KEY, 's', "Key to decode the private key if it is encrypted"},
+    {"cert", OPT_CERT, '<', "The CA cert"},
+    {"selfsign", OPT_SELFSIGN, '-',
+     "Sign a cert with the key associated with it"},
+    {"in", OPT_IN, '<', "The input PEM encoded cert request(s)"},
+    {"out", OPT_OUT, '>', "Where to put the output file(s)"},
+    {"outdir", OPT_OUTDIR, '/', "Where to put output cert"},
+    {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"},
+    {"notext", OPT_NOTEXT, '-', "Do not print the generated certificate"},
+    {"batch", OPT_BATCH, '-', "Don't ask questions"},
+    {"preserveDN", OPT_PRESERVEDN, '-', "Don't re-order the DN"},
+    {"noemailDN", OPT_NOEMAILDN, '-', "Don't add the EMAIL field to the DN"},
+    {"gencrl", OPT_GENCRL, '-', "Generate a new CRL"},
+    {"msie_hack", OPT_MSIE_HACK, '-',
+     "msie modifications to handle all those universal strings"},
+    {"crldays", OPT_CRLDAYS, 'p', "Days until the next CRL is due"},
+    {"crlhours", OPT_CRLHOURS, 'p', "Hours until the next CRL is due"},
+    {"crlsec", OPT_CRLSEC, 'p', "Seconds until the next CRL is due"},
+    {"infiles", OPT_INFILES, '-', "The last argument, requests to process"},
+    {"ss_cert", OPT_SS_CERT, '<', "File contains a self signed cert to sign"},
+    {"spkac", OPT_SPKAC, '<',
+     "File contains DN and signed public key and challenge"},
+    {"revoke", OPT_REVOKE, '<', "Revoke a cert (given in file)"},
+    {"valid", OPT_VALID, 's',
+     "Add a Valid(not-revoked) DB entry about a cert (given in file)"},
+    {"extensions", OPT_EXTENSIONS, 's',
+     "Extension section (override value in config file)"},
+    {"extfile", OPT_EXTFILE, '<',
+     "Configuration file with X509v3 extensions to add"},
+    {"status", OPT_STATUS, 's', "Shows cert status given the serial number"},
+    {"updatedb", OPT_UPDATEDB, '-', "Updates db for expired cert"},
+    {"crlexts", OPT_CRLEXTS, 's',
+     "CRL extension section (override value in config file)"},
+    {"crl_reason", OPT_CRL_REASON, 's', "revocation reason"},
+    {"crl_hold", OPT_CRL_HOLD, 's',
+     "the hold instruction, an OID. Sets revocation reason to certificateHold"},
+    {"crl_compromise", OPT_CRL_COMPROMISE, 's',
+     "sets compromise time to val and the revocation reason to keyCompromise"},
+    {"crl_CA_compromise", OPT_CRL_CA_COMPROMISE, 's',
+     "sets compromise time to val and the revocation reason to CACompromise"},
+#ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+#endif
+    {NULL}
+};
+
+int ca_main(int argc, char **argv)
+{
+    CONF *conf = NULL;
+    ENGINE *e = NULL;
+    BIGNUM *crlnumber = NULL, *serial = NULL;
+    EVP_PKEY *pkey = NULL;
+    BIO *in = NULL, *out = NULL, *Sout = NULL;
+    ASN1_INTEGER *tmpser;
+    ASN1_TIME *tmptm;
+    CA_DB *db = NULL;
+    DB_ATTR db_attr;
+    STACK_OF(CONF_VALUE) *attribs = NULL;
+    STACK_OF(OPENSSL_STRING) *sigopts = NULL;
+    STACK_OF(X509) *cert_sk = NULL;
+    X509_CRL *crl = NULL;
+    const EVP_MD *dgst = NULL;
+    char *configfile = default_config_file, *section = NULL;
+    char *md = NULL, *policy = NULL, *keyfile = NULL;
+    char *certfile = NULL, *crl_ext = NULL, *crlnumberfile = NULL, *key = NULL;
+    const char *infile = NULL, *spkac_file = NULL, *ss_cert_file = NULL;
+    const char *extensions = NULL, *extfile = NULL, *passinarg = NULL;
+    char *outdir = NULL, *outfile = NULL, *rev_arg = NULL, *ser_status = NULL;
+    const char *serialfile = NULL, *subj = NULL;
+    char *prog, *startdate = NULL, *enddate = NULL;
+    char *dbfile = NULL, *f, *randfile = NULL;
+    char buf[3][BSIZE];
+    char *const *pp;
+    const char *p;
+    int create_ser = 0, free_key = 0, total = 0, total_done = 0;
+    int batch = 0, default_op = 1, doupdatedb = 0, ext_copy = EXT_COPY_NONE;
+    int keyformat = FORMAT_PEM, multirdn = 0, notext = 0, output_der = 0;
+    int ret = 1, email_dn = 1, req = 0, verbose = 0, gencrl = 0, dorevoke = 0;
+    int i, j, rev_type = REV_NONE, selfsign = 0;
+    long crldays = 0, crlhours = 0, crlsec = 0, days = 0;
+    unsigned long chtype = MBSTRING_ASC, nameopt = 0, certopt = 0;
+    X509 *x509 = NULL, *x509p = NULL, *x = NULL;
+    X509_REVOKED *r = NULL;
+    OPTION_CHOICE o;
+
+    prog = opt_init(argc, argv, ca_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(ca_options);
+            ret = 0;
+            goto end;
+        case OPT_IN:
+            req = 1;
+            infile = opt_arg();
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_VERBOSE:
+            verbose = 1;
+            break;
+        case OPT_CONFIG:
+            configfile = opt_arg();
+            break;
+        case OPT_NAME:
+            section = opt_arg();
+            break;
+        case OPT_SUBJ:
+            subj = opt_arg();
+            /* preserve=1; */
+            break;
+        case OPT_UTF8:
+            chtype = MBSTRING_UTF8;
+            break;
+        case OPT_CREATE_SERIAL:
+            create_ser = 1;
+            break;
+        case OPT_MULTIVALUE_RDN:
+            multirdn = 1;
+            break;
+        case OPT_STARTDATE:
+            startdate = opt_arg();
+            break;
+        case OPT_ENDDATE:
+            enddate = opt_arg();
+            break;
+        case OPT_DAYS:
+            days = atoi(opt_arg());
+            break;
+        case OPT_MD:
+            md = opt_arg();
+            break;
+        case OPT_POLICY:
+            policy = opt_arg();
+            break;
+        case OPT_KEYFILE:
+            keyfile = opt_arg();
+            break;
+        case OPT_KEYFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyformat))
+                goto opthelp;
+            break;
+        case OPT_PASSIN:
+            passinarg = opt_arg();
+            break;
+        case OPT_KEY:
+            key = opt_arg();
+            break;
+        case OPT_CERT:
+            certfile = opt_arg();
+            break;
+        case OPT_SELFSIGN:
+            selfsign = 1;
+            break;
+        case OPT_OUTDIR:
+            outdir = opt_arg();
+            break;
+        case OPT_SIGOPT:
+            if (sigopts == NULL)
+                sigopts = sk_OPENSSL_STRING_new_null();
+            if (sigopts == NULL
+                || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
+                goto end;
+            break;
+        case OPT_NOTEXT:
+            notext = 1;
+            break;
+        case OPT_BATCH:
+            batch = 1;
+            break;
+        case OPT_PRESERVEDN:
+            preserve = 1;
+            break;
+        case OPT_NOEMAILDN:
+            email_dn = 0;
+            break;
+        case OPT_GENCRL:
+            gencrl = 1;
+            break;
+        case OPT_MSIE_HACK:
+            msie_hack = 1;
+            break;
+        case OPT_CRLDAYS:
+            crldays = atol(opt_arg());
+            break;
+        case OPT_CRLHOURS:
+            crlhours = atol(opt_arg());
+            break;
+        case OPT_CRLSEC:
+            crlsec = atol(opt_arg());
+            break;
+        case OPT_INFILES:
+            req = 1;
+            goto end_of_options;
+        case OPT_SS_CERT:
+            ss_cert_file = opt_arg();
+            req = 1;
+            break;
+        case OPT_SPKAC:
+            spkac_file = opt_arg();
+            req = 1;
+            break;
+        case OPT_REVOKE:
+            infile = opt_arg();
+            dorevoke = 1;
+            break;
+        case OPT_VALID:
+            infile = opt_arg();
+            dorevoke = 2;
+            break;
+        case OPT_EXTENSIONS:
+            extensions = opt_arg();
+            break;
+        case OPT_EXTFILE:
+            extfile = opt_arg();
+            break;
+        case OPT_STATUS:
+            ser_status = opt_arg();
+            break;
+        case OPT_UPDATEDB:
+            doupdatedb = 1;
+            break;
+        case OPT_CRLEXTS:
+            crl_ext = opt_arg();
+            break;
+        case OPT_CRL_REASON:
+            rev_arg = opt_arg();
+            rev_type = REV_CRL_REASON;
+            break;
+        case OPT_CRL_HOLD:
+            rev_arg = opt_arg();
+            rev_type = REV_HOLD;
+            break;
+        case OPT_CRL_COMPROMISE:
+            rev_arg = opt_arg();
+            rev_type = REV_KEY_COMPROMISE;
+            break;
+        case OPT_CRL_CA_COMPROMISE:
+            rev_arg = opt_arg();
+            rev_type = REV_CA_COMPROMISE;
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        }
+    }
+end_of_options:
+    argc = opt_num_rest();
+    argv = opt_rest();
+
+    BIO_printf(bio_err, "Using configuration from %s\n", configfile);
+
+    if ((conf = app_load_config(configfile)) == NULL)
+        goto end;
+    if (configfile != default_config_file && !app_load_modules(conf))
+        goto end;
+
+    /* Lets get the config section we are using */
+    if (section == NULL
+        && (section = lookup_conf(conf, BASE_SECTION, ENV_DEFAULT_CA)) == NULL)
+        goto end;
+
+    if (conf != NULL) {
+        p = NCONF_get_string(conf, NULL, "oid_file");
+        if (p == NULL)
+            ERR_clear_error();
+        if (p != NULL) {
+            BIO *oid_bio;
+
+            oid_bio = BIO_new_file(p, "r");
+            if (oid_bio == NULL) {
+                /*-
+                BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
+                ERR_print_errors(bio_err);
+                */
+                ERR_clear_error();
+            } else {
+                OBJ_create_objects(oid_bio);
+                BIO_free(oid_bio);
+            }
+        }
+        if (!add_oid_section(conf)) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
+    if (randfile == NULL)
+        ERR_clear_error();
+    app_RAND_load_file(randfile, 0);
+
+    f = NCONF_get_string(conf, section, STRING_MASK);
+    if (!f)
+        ERR_clear_error();
+
+    if (f && !ASN1_STRING_set_default_mask_asc(f)) {
+        BIO_printf(bio_err, "Invalid global string mask setting %s\n", f);
+        goto end;
+    }
+
+    if (chtype != MBSTRING_UTF8) {
+        f = NCONF_get_string(conf, section, UTF8_IN);
+        if (!f)
+            ERR_clear_error();
+        else if (strcmp(f, "yes") == 0)
+            chtype = MBSTRING_UTF8;
+    }
+
+    db_attr.unique_subject = 1;
+    p = NCONF_get_string(conf, section, ENV_UNIQUE_SUBJECT);
+    if (p) {
+        db_attr.unique_subject = parse_yesno(p, 1);
+    } else
+        ERR_clear_error();
+
+    /*****************************************************************/
+    /* report status of cert with serial number given on command line */
+    if (ser_status) {
+        dbfile = lookup_conf(conf, section, ENV_DATABASE);
+        if (dbfile == NULL)
+            goto end;
+
+        db = load_index(dbfile, &db_attr);
+        if (db == NULL)
+            goto end;
+
+        if (!index_index(db))
+            goto end;
+
+        if (get_certificate_status(ser_status, db) != 1)
+            BIO_printf(bio_err, "Error verifying serial %s!\n", ser_status);
+        goto end;
+    }
+
+    /*****************************************************************/
+    /* we definitely need a private key, so let's get it */
+
+    if (keyfile == NULL
+        && (keyfile = lookup_conf(conf, section, ENV_PRIVATE_KEY)) == NULL)
+        goto end;
+
+    if (!key) {
+        free_key = 1;
+        if (!app_passwd(passinarg, NULL, &key, NULL)) {
+            BIO_printf(bio_err, "Error getting password\n");
+            goto end;
+        }
+    }
+    pkey = load_key(keyfile, keyformat, 0, key, e, "CA private key");
+    if (key)
+        OPENSSL_cleanse(key, strlen(key));
+    if (pkey == NULL) {
+        /* load_key() has already printed an appropriate message */
+        goto end;
+    }
+
+    /*****************************************************************/
+    /* we need a certificate */
+    if (!selfsign || spkac_file || ss_cert_file || gencrl) {
+        if (certfile == NULL
+            && (certfile = lookup_conf(conf, section, ENV_CERTIFICATE)) == NULL)
+            goto end;
+
+        x509 = load_cert(certfile, FORMAT_PEM, "CA certificate");
+        if (x509 == NULL)
+            goto end;
+
+        if (!X509_check_private_key(x509, pkey)) {
+            BIO_printf(bio_err,
+                       "CA certificate and CA private key do not match\n");
+            goto end;
+        }
+    }
+    if (!selfsign)
+        x509p = x509;
+
+    f = NCONF_get_string(conf, BASE_SECTION, ENV_PRESERVE);
+    if (f == NULL)
+        ERR_clear_error();
+    if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
+        preserve = 1;
+    f = NCONF_get_string(conf, BASE_SECTION, ENV_MSIE_HACK);
+    if (f == NULL)
+        ERR_clear_error();
+    if ((f != NULL) && ((*f == 'y') || (*f == 'Y')))
+        msie_hack = 1;
+
+    f = NCONF_get_string(conf, section, ENV_NAMEOPT);
+
+    if (f) {
+        if (!set_name_ex(&nameopt, f)) {
+            BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
+            goto end;
+        }
+        default_op = 0;
+    } else {
+        nameopt = XN_FLAG_ONELINE;
+        ERR_clear_error();
+    }
+
+    f = NCONF_get_string(conf, section, ENV_CERTOPT);
+
+    if (f) {
+        if (!set_cert_ex(&certopt, f)) {
+            BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
+            goto end;
+        }
+        default_op = 0;
+    } else
+        ERR_clear_error();
+
+    f = NCONF_get_string(conf, section, ENV_EXTCOPY);
+
+    if (f) {
+        if (!set_ext_copy(&ext_copy, f)) {
+            BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
+            goto end;
+        }
+    } else
+        ERR_clear_error();
+
+    /*****************************************************************/
+    /* lookup where to write new certificates */
+    if ((outdir == NULL) && (req)) {
+
+        outdir = NCONF_get_string(conf, section, ENV_NEW_CERTS_DIR);
+        if (outdir == NULL) {
+            BIO_printf(bio_err,
+                       "there needs to be defined a directory for new certificate to be placed in\n");
+            goto end;
+        }
+#ifndef OPENSSL_SYS_VMS
+        /*
+         * outdir is a directory spec, but access() for VMS demands a
+         * filename.  We could use the DEC C routine to convert the
+         * directory syntax to Unixly, and give that to app_isdir,
+         * but for now the fopen will catch the error if it's not a
+         * directory
+         */
+        if (app_isdir(outdir) <= 0) {
+            BIO_printf(bio_err, "%s: %s is not a directory\n", prog, outdir);
+            perror(outdir);
+            goto end;
+        }
+#endif
+    }
+
+    /*****************************************************************/
+    /* we need to load the database file */
+    dbfile = lookup_conf(conf, section, ENV_DATABASE);
+    if (dbfile == NULL)
+        goto end;
+
+    db = load_index(dbfile, &db_attr);
+    if (db == NULL)
+        goto end;
+
+    /* Lets check some fields */
+    for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
+        pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
+        if ((pp[DB_type][0] != DB_TYPE_REV) && (pp[DB_rev_date][0] != '\0')) {
+            BIO_printf(bio_err,
+                       "entry %d: not revoked yet, but has a revocation date\n",
+                       i + 1);
+            goto end;
+        }
+        if ((pp[DB_type][0] == DB_TYPE_REV) &&
+            !make_revoked(NULL, pp[DB_rev_date])) {
+            BIO_printf(bio_err, " in entry %d\n", i + 1);
+            goto end;
+        }
+        if (!check_time_format((char *)pp[DB_exp_date])) {
+            BIO_printf(bio_err, "entry %d: invalid expiry date\n", i + 1);
+            goto end;
+        }
+        p = pp[DB_serial];
+        j = strlen(p);
+        if (*p == '-') {
+            p++;
+            j--;
+        }
+        if ((j & 1) || (j < 2)) {
+            BIO_printf(bio_err, "entry %d: bad serial number length (%d)\n",
+                       i + 1, j);
+            goto end;
+        }
+        for ( ; *p; p++) {
+            if (!isxdigit(_UC(*p))) {
+                BIO_printf(bio_err,
+                           "entry %d: bad char 0%o '%c' in serial number\n",
+                           i + 1, *p, *p);
+                goto end;
+            }
+        }
+    }
+    if (verbose) {
+        TXT_DB_write(bio_out, db->db);
+        BIO_printf(bio_err, "%d entries loaded from the database\n",
+                   sk_OPENSSL_PSTRING_num(db->db->data));
+        BIO_printf(bio_err, "generating index\n");
+    }
+
+    if (!index_index(db))
+        goto end;
+
+    /*****************************************************************/
+    /* Update the db file for expired certificates */
+    if (doupdatedb) {
+        if (verbose)
+            BIO_printf(bio_err, "Updating %s ...\n", dbfile);
+
+        i = do_updatedb(db);
+        if (i == -1) {
+            BIO_printf(bio_err, "Malloc failure\n");
+            goto end;
+        } else if (i == 0) {
+            if (verbose)
+                BIO_printf(bio_err, "No entries found to mark expired\n");
+        } else {
+            if (!save_index(dbfile, "new", db))
+                goto end;
+
+            if (!rotate_index(dbfile, "new", "old"))
+                goto end;
+
+            if (verbose)
+                BIO_printf(bio_err,
+                           "Done. %d entries marked as expired\n", i);
+        }
+    }
+
+    /*****************************************************************/
+    /* Read extensions config file                                   */
+    if (extfile) {
+        if ((extconf = app_load_config(extfile)) == NULL) {
+            ret = 1;
+            goto end;
+        }
+
+        if (verbose)
+            BIO_printf(bio_err, "Successfully loaded extensions file %s\n",
+                       extfile);
+
+        /* We can have sections in the ext file */
+        if (extensions == NULL) {
+            extensions = NCONF_get_string(extconf, "default", "extensions");
+            if (extensions == NULL)
+                extensions = "default";
+        }
+    }
+
+    /*****************************************************************/
+    if (req || gencrl) {
+        /* FIXME: Is it really always text? */
+        Sout = bio_open_default(outfile, 'w', FORMAT_TEXT);
+        if (Sout == NULL)
+            goto end;
+    }
+
+    if (md == NULL
+        && (md = lookup_conf(conf, section, ENV_DEFAULT_MD)) == NULL)
+        goto end;
+
+    if (strcmp(md, "default") == 0) {
+        int def_nid;
+        if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0) {
+            BIO_puts(bio_err, "no default digest\n");
+            goto end;
+        }
+        md = (char *)OBJ_nid2sn(def_nid);
+    }
+
+    if (!opt_md(md, &dgst)) {
+        goto end;
+    }
+
+    if (req) {
+        if (email_dn == 1) {
+            char *tmp_email_dn = NULL;
+
+            tmp_email_dn = NCONF_get_string(conf, section, ENV_DEFAULT_EMAIL_DN);
+            if (tmp_email_dn != NULL && strcmp(tmp_email_dn, "no") == 0)
+                email_dn = 0;
+        }
+        if (verbose)
+            BIO_printf(bio_err, "message digest is %s\n",
+                       OBJ_nid2ln(EVP_MD_type(dgst)));
+        if (policy == NULL
+            && (policy = lookup_conf(conf, section, ENV_POLICY)) == NULL)
+            goto end;
+
+        if (verbose)
+            BIO_printf(bio_err, "policy is %s\n", policy);
+
+        serialfile = lookup_conf(conf, section, ENV_SERIAL);
+        if (serialfile == NULL)
+            goto end;
+
+        if (!extconf) {
+            /*
+             * no '-extfile' option, so we look for extensions in the main
+             * configuration file
+             */
+            if (!extensions) {
+                extensions = NCONF_get_string(conf, section, ENV_EXTENSIONS);
+                if (!extensions)
+                    ERR_clear_error();
+            }
+            if (extensions) {
+                /* Check syntax of file */
+                X509V3_CTX ctx;
+                X509V3_set_ctx_test(&ctx);
+                X509V3_set_nconf(&ctx, conf);
+                if (!X509V3_EXT_add_nconf(conf, &ctx, extensions, NULL)) {
+                    BIO_printf(bio_err,
+                               "Error Loading extension section %s\n",
+                               extensions);
+                    ret = 1;
+                    goto end;
+                }
+            }
+        }
+
+        if (startdate == NULL) {
+            startdate = NCONF_get_string(conf, section,
+                                         ENV_DEFAULT_STARTDATE);
+            if (startdate == NULL)
+                ERR_clear_error();
+        }
+        if (startdate && !ASN1_TIME_set_string(NULL, startdate)) {
+            BIO_printf(bio_err,
+                       "start date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
+            goto end;
+        }
+        if (startdate == NULL)
+            startdate = "today";
+
+        if (enddate == NULL) {
+            enddate = NCONF_get_string(conf, section, ENV_DEFAULT_ENDDATE);
+            if (enddate == NULL)
+                ERR_clear_error();
+        }
+        if (enddate && !ASN1_TIME_set_string(NULL, enddate)) {
+            BIO_printf(bio_err,
+                       "end date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
+            goto end;
+        }
+
+        if (days == 0) {
+            if (!NCONF_get_number(conf, section, ENV_DEFAULT_DAYS, &days))
+                days = 0;
+        }
+        if (!enddate && (days == 0)) {
+            BIO_printf(bio_err,
+                       "cannot lookup how many days to certify for\n");
+            goto end;
+        }
+
+        if ((serial = load_serial(serialfile, create_ser, NULL)) == NULL) {
+            BIO_printf(bio_err, "error while loading serial number\n");
+            goto end;
+        }
+        if (verbose) {
+            if (BN_is_zero(serial))
+                BIO_printf(bio_err, "next serial number is 00\n");
+            else {
+                if ((f = BN_bn2hex(serial)) == NULL)
+                    goto end;
+                BIO_printf(bio_err, "next serial number is %s\n", f);
+                OPENSSL_free(f);
+            }
+        }
+
+        if ((attribs = NCONF_get_section(conf, policy)) == NULL) {
+            BIO_printf(bio_err, "unable to find 'section' for %s\n", policy);
+            goto end;
+        }
+
+        if ((cert_sk = sk_X509_new_null()) == NULL) {
+            BIO_printf(bio_err, "Memory allocation failure\n");
+            goto end;
+        }
+        if (spkac_file != NULL) {
+            total++;
+            j = certify_spkac(&x, spkac_file, pkey, x509, dgst, sigopts,
+                              attribs, db, serial, subj, chtype, multirdn,
+                              email_dn, startdate, enddate, days, extensions,
+                              conf, verbose, certopt, nameopt, default_op,
+                              ext_copy);
+            if (j < 0)
+                goto end;
+            if (j > 0) {
+                total_done++;
+                BIO_printf(bio_err, "\n");
+                if (!BN_add_word(serial, 1))
+                    goto end;
+                if (!sk_X509_push(cert_sk, x)) {
+                    BIO_printf(bio_err, "Memory allocation failure\n");
+                    goto end;
+                }
+                if (outfile) {
+                    output_der = 1;
+                    batch = 1;
+                }
+            }
+        }
+        if (ss_cert_file != NULL) {
+            total++;
+            j = certify_cert(&x, ss_cert_file, pkey, x509, dgst, sigopts,
+                             attribs,
+                             db, serial, subj, chtype, multirdn, email_dn,
+                             startdate, enddate, days, batch, extensions,
+                             conf, verbose, certopt, nameopt, default_op,
+                             ext_copy);
+            if (j < 0)
+                goto end;
+            if (j > 0) {
+                total_done++;
+                BIO_printf(bio_err, "\n");
+                if (!BN_add_word(serial, 1))
+                    goto end;
+                if (!sk_X509_push(cert_sk, x)) {
+                    BIO_printf(bio_err, "Memory allocation failure\n");
+                    goto end;
+                }
+            }
+        }
+        if (infile != NULL) {
+            total++;
+            j = certify(&x, infile, pkey, x509p, dgst, sigopts, attribs, db,
+                        serial, subj, chtype, multirdn, email_dn, startdate,
+                        enddate, days, batch, extensions, conf, verbose,
+                        certopt, nameopt, default_op, ext_copy, selfsign);
+            if (j < 0)
+                goto end;
+            if (j > 0) {
+                total_done++;
+                BIO_printf(bio_err, "\n");
+                if (!BN_add_word(serial, 1))
+                    goto end;
+                if (!sk_X509_push(cert_sk, x)) {
+                    BIO_printf(bio_err, "Memory allocation failure\n");
+                    goto end;
+                }
+            }
+        }
+        for (i = 0; i < argc; i++) {
+            total++;
+            j = certify(&x, argv[i], pkey, x509p, dgst, sigopts, attribs, db,
+                        serial, subj, chtype, multirdn, email_dn, startdate,
+                        enddate, days, batch, extensions, conf, verbose,
+                        certopt, nameopt, default_op, ext_copy, selfsign);
+            if (j < 0)
+                goto end;
+            if (j > 0) {
+                total_done++;
+                BIO_printf(bio_err, "\n");
+                if (!BN_add_word(serial, 1))
+                    goto end;
+                if (!sk_X509_push(cert_sk, x)) {
+                    BIO_printf(bio_err, "Memory allocation failure\n");
+                    goto end;
+                }
+            }
+        }
+        /*
+         * we have a stack of newly certified certificates and a data base
+         * and serial number that need updating
+         */
+
+        if (sk_X509_num(cert_sk) > 0) {
+            if (!batch) {
+                BIO_printf(bio_err,
+                           "\n%d out of %d certificate requests certified, commit? [y/n]",
+                           total_done, total);
+                (void)BIO_flush(bio_err);
+                buf[0][0] = '\0';
+                if (!fgets(buf[0], 10, stdin)) {
+                    BIO_printf(bio_err,
+                               "CERTIFICATION CANCELED: I/O error\n");
+                    ret = 0;
+                    goto end;
+                }
+                if ((buf[0][0] != 'y') && (buf[0][0] != 'Y')) {
+                    BIO_printf(bio_err, "CERTIFICATION CANCELED\n");
+                    ret = 0;
+                    goto end;
+                }
+            }
+
+            BIO_printf(bio_err, "Write out database with %d new entries\n",
+                       sk_X509_num(cert_sk));
+
+            if (!save_serial(serialfile, "new", serial, NULL))
+                goto end;
+
+            if (!save_index(dbfile, "new", db))
+                goto end;
+        }
+
+        if (verbose)
+            BIO_printf(bio_err, "writing new certificates\n");
+        for (i = 0; i < sk_X509_num(cert_sk); i++) {
+            BIO *Cout = NULL;
+            X509 *xi = sk_X509_value(cert_sk, i);
+            ASN1_INTEGER *serialNumber = X509_get_serialNumber(xi);
+            int k;
+            char *n;
+
+            j = ASN1_STRING_length(serialNumber);
+            p = (const char *)ASN1_STRING_get0_data(serialNumber);
+
+            if (strlen(outdir) >= (size_t)(j ? BSIZE - j * 2 - 6 : BSIZE - 8)) {
+                BIO_printf(bio_err, "certificate file name too long\n");
+                goto end;
+            }
+
+            strcpy(buf[2], outdir);
+
+#ifndef OPENSSL_SYS_VMS
+            OPENSSL_strlcat(buf[2], "/", sizeof(buf[2]));
+#endif
+
+            n = (char *)&(buf[2][strlen(buf[2])]);
+            if (j > 0) {
+                for (k = 0; k < j; k++) {
+                    if (n >= &(buf[2][sizeof(buf[2])]))
+                        break;
+                    BIO_snprintf(n,
+                                 &buf[2][0] + sizeof(buf[2]) - n,
+                                 "%02X", (unsigned char)*(p++));
+                    n += 2;
+                }
+            } else {
+                *(n++) = '0';
+                *(n++) = '0';
+            }
+            *(n++) = '.';
+            *(n++) = 'p';
+            *(n++) = 'e';
+            *(n++) = 'm';
+            *n = '\0';
+            if (verbose)
+                BIO_printf(bio_err, "writing %s\n", buf[2]);
+
+            Cout = BIO_new_file(buf[2], "w");
+            if (Cout == NULL) {
+                perror(buf[2]);
+                goto end;
+            }
+            write_new_certificate(Cout, xi, 0, notext);
+            write_new_certificate(Sout, xi, output_der, notext);
+            BIO_free_all(Cout);
+        }
+
+        if (sk_X509_num(cert_sk)) {
+            /* Rename the database and the serial file */
+            if (!rotate_serial(serialfile, "new", "old"))
+                goto end;
+
+            if (!rotate_index(dbfile, "new", "old"))
+                goto end;
+
+            BIO_printf(bio_err, "Data Base Updated\n");
+        }
+    }
+
+    /*****************************************************************/
+    if (gencrl) {
+        int crl_v2 = 0;
+        if (!crl_ext) {
+            crl_ext = NCONF_get_string(conf, section, ENV_CRLEXT);
+            if (!crl_ext)
+                ERR_clear_error();
+        }
+        if (crl_ext) {
+            /* Check syntax of file */
+            X509V3_CTX ctx;
+            X509V3_set_ctx_test(&ctx);
+            X509V3_set_nconf(&ctx, conf);
+            if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL)) {
+                BIO_printf(bio_err,
+                           "Error Loading CRL extension section %s\n",
+                           crl_ext);
+                ret = 1;
+                goto end;
+            }
+        }
+
+        if ((crlnumberfile = NCONF_get_string(conf, section, ENV_CRLNUMBER))
+            != NULL)
+            if ((crlnumber = load_serial(crlnumberfile, 0, NULL)) == NULL) {
+                BIO_printf(bio_err, "error while loading CRL number\n");
+                goto end;
+            }
+
+        if (!crldays && !crlhours && !crlsec) {
+            if (!NCONF_get_number(conf, section,
+                                  ENV_DEFAULT_CRL_DAYS, &crldays))
+                crldays = 0;
+            if (!NCONF_get_number(conf, section,
+                                  ENV_DEFAULT_CRL_HOURS, &crlhours))
+                crlhours = 0;
+            ERR_clear_error();
+        }
+        if ((crldays == 0) && (crlhours == 0) && (crlsec == 0)) {
+            BIO_printf(bio_err,
+                       "cannot lookup how long until the next CRL is issued\n");
+            goto end;
+        }
+
+        if (verbose)
+            BIO_printf(bio_err, "making CRL\n");
+        if ((crl = X509_CRL_new()) == NULL)
+            goto end;
+        if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(x509)))
+            goto end;
+
+        tmptm = ASN1_TIME_new();
+        if (tmptm == NULL)
+            goto end;
+        X509_gmtime_adj(tmptm, 0);
+        X509_CRL_set1_lastUpdate(crl, tmptm);
+        if (!X509_time_adj_ex(tmptm, crldays, crlhours * 60 * 60 + crlsec,
+                              NULL)) {
+            BIO_puts(bio_err, "error setting CRL nextUpdate\n");
+            goto end;
+        }
+        X509_CRL_set1_nextUpdate(crl, tmptm);
+
+        ASN1_TIME_free(tmptm);
+
+        for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
+            pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
+            if (pp[DB_type][0] == DB_TYPE_REV) {
+                if ((r = X509_REVOKED_new()) == NULL)
+                    goto end;
+                j = make_revoked(r, pp[DB_rev_date]);
+                if (!j)
+                    goto end;
+                if (j == 2)
+                    crl_v2 = 1;
+                if (!BN_hex2bn(&serial, pp[DB_serial]))
+                    goto end;
+                tmpser = BN_to_ASN1_INTEGER(serial, NULL);
+                BN_free(serial);
+                serial = NULL;
+                if (!tmpser)
+                    goto end;
+                X509_REVOKED_set_serialNumber(r, tmpser);
+                ASN1_INTEGER_free(tmpser);
+                X509_CRL_add0_revoked(crl, r);
+            }
+        }
+
+        /*
+         * sort the data so it will be written in serial number order
+         */
+        X509_CRL_sort(crl);
+
+        /* we now have a CRL */
+        if (verbose)
+            BIO_printf(bio_err, "signing CRL\n");
+
+        /* Add any extensions asked for */
+
+        if (crl_ext || crlnumberfile != NULL) {
+            X509V3_CTX crlctx;
+            X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
+            X509V3_set_nconf(&crlctx, conf);
+
+            if (crl_ext)
+                if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx, crl_ext, crl))
+                    goto end;
+            if (crlnumberfile != NULL) {
+                tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL);
+                if (!tmpser)
+                    goto end;
+                X509_CRL_add1_ext_i2d(crl, NID_crl_number, tmpser, 0, 0);
+                ASN1_INTEGER_free(tmpser);
+                crl_v2 = 1;
+                if (!BN_add_word(crlnumber, 1))
+                    goto end;
+            }
+        }
+        if (crl_ext || crl_v2) {
+            if (!X509_CRL_set_version(crl, 1))
+                goto end;       /* version 2 CRL */
+        }
+
+        /* we have a CRL number that need updating */
+        if (crlnumberfile != NULL)
+            if (!save_serial(crlnumberfile, "new", crlnumber, NULL))
+                goto end;
+
+        BN_free(crlnumber);
+        crlnumber = NULL;
+
+        if (!do_X509_CRL_sign(crl, pkey, dgst, sigopts))
+            goto end;
+
+        PEM_write_bio_X509_CRL(Sout, crl);
+
+        if (crlnumberfile != NULL) /* Rename the crlnumber file */
+            if (!rotate_serial(crlnumberfile, "new", "old"))
+                goto end;
+
+    }
+    /*****************************************************************/
+    if (dorevoke) {
+        if (infile == NULL) {
+            BIO_printf(bio_err, "no input files\n");
+            goto end;
+        } else {
+            X509 *revcert;
+            revcert = load_cert(infile, FORMAT_PEM, infile);
+            if (revcert == NULL)
+                goto end;
+            if (dorevoke == 2)
+                rev_type = -1;
+            j = do_revoke(revcert, db, rev_type, rev_arg);
+            if (j <= 0)
+                goto end;
+            X509_free(revcert);
+
+            if (!save_index(dbfile, "new", db))
+                goto end;
+
+            if (!rotate_index(dbfile, "new", "old"))
+                goto end;
+
+            BIO_printf(bio_err, "Data Base Updated\n");
+        }
+    }
+    /*****************************************************************/
+    ret = 0;
+ end:
+    BIO_free_all(Sout);
+    BIO_free_all(out);
+    BIO_free_all(in);
+    sk_X509_pop_free(cert_sk, X509_free);
+
+    if (ret)
+        ERR_print_errors(bio_err);
+    app_RAND_write_file(randfile);
+    if (free_key)
+        OPENSSL_free(key);
+    BN_free(serial);
+    BN_free(crlnumber);
+    free_index(db);
+    sk_OPENSSL_STRING_free(sigopts);
+    EVP_PKEY_free(pkey);
+    X509_free(x509);
+    X509_CRL_free(crl);
+    NCONF_free(conf);
+    NCONF_free(extconf);
+    release_engine(e);
+    return (ret);
+}
+
+static char *lookup_conf(const CONF *conf, const char *section, const char *tag)
+{
+    char *entry = NCONF_get_string(conf, section, tag);
+    if (entry == NULL)
+        BIO_printf(bio_err, "variable lookup failed for %s::%s\n", section, tag);
+    return entry;
+}
+
+static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
+                   const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
+                   STACK_OF(CONF_VALUE) *policy, CA_DB *db,
+                   BIGNUM *serial, const char *subj, unsigned long chtype,
+                   int multirdn, int email_dn, const char *startdate,
+                   const char *enddate,
+                   long days, int batch, const char *ext_sect, CONF *lconf,
+                   int verbose, unsigned long certopt, unsigned long nameopt,
+                   int default_op, int ext_copy, int selfsign)
+{
+    X509_REQ *req = NULL;
+    BIO *in = NULL;
+    EVP_PKEY *pktmp = NULL;
+    int ok = -1, i;
+
+    in = BIO_new_file(infile, "r");
+    if (in == NULL) {
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+    if ((req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL)) == NULL) {
+        BIO_printf(bio_err, "Error reading certificate request in %s\n",
+                   infile);
+        goto end;
+    }
+    if (verbose)
+        X509_REQ_print(bio_err, req);
+
+    BIO_printf(bio_err, "Check that the request matches the signature\n");
+
+    if (selfsign && !X509_REQ_check_private_key(req, pkey)) {
+        BIO_printf(bio_err,
+                   "Certificate request and CA private key do not match\n");
+        ok = 0;
+        goto end;
+    }
+    if ((pktmp = X509_REQ_get0_pubkey(req)) == NULL) {
+        BIO_printf(bio_err, "error unpacking public key\n");
+        goto end;
+    }
+    i = X509_REQ_verify(req, pktmp);
+    pktmp = NULL;
+    if (i < 0) {
+        ok = 0;
+        BIO_printf(bio_err, "Signature verification problems....\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+    if (i == 0) {
+        ok = 0;
+        BIO_printf(bio_err,
+                   "Signature did not match the certificate request\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    } else
+        BIO_printf(bio_err, "Signature ok\n");
+
+    ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj,
+                 chtype, multirdn, email_dn, startdate, enddate, days, batch,
+                 verbose, req, ext_sect, lconf, certopt, nameopt, default_op,
+                 ext_copy, selfsign);
+
+ end:
+    X509_REQ_free(req);
+    BIO_free(in);
+    return (ok);
+}
+
+static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
+                        const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
+                        STACK_OF(CONF_VALUE) *policy, CA_DB *db,
+                        BIGNUM *serial, const char *subj, unsigned long chtype,
+                        int multirdn, int email_dn, const char *startdate,
+                        const char *enddate, long days, int batch, const char *ext_sect,
+                        CONF *lconf, int verbose, unsigned long certopt,
+                        unsigned long nameopt, int default_op, int ext_copy)
+{
+    X509 *req = NULL;
+    X509_REQ *rreq = NULL;
+    EVP_PKEY *pktmp = NULL;
+    int ok = -1, i;
+
+    if ((req = load_cert(infile, FORMAT_PEM, infile)) == NULL)
+        goto end;
+    if (verbose)
+        X509_print(bio_err, req);
+
+    BIO_printf(bio_err, "Check that the request matches the signature\n");
+
+    if ((pktmp = X509_get0_pubkey(req)) == NULL) {
+        BIO_printf(bio_err, "error unpacking public key\n");
+        goto end;
+    }
+    i = X509_verify(req, pktmp);
+    if (i < 0) {
+        ok = 0;
+        BIO_printf(bio_err, "Signature verification problems....\n");
+        goto end;
+    }
+    if (i == 0) {
+        ok = 0;
+        BIO_printf(bio_err, "Signature did not match the certificate\n");
+        goto end;
+    } else
+        BIO_printf(bio_err, "Signature ok\n");
+
+    if ((rreq = X509_to_X509_REQ(req, NULL, NULL)) == NULL)
+        goto end;
+
+    ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj,
+                 chtype, multirdn, email_dn, startdate, enddate, days, batch,
+                 verbose, rreq, ext_sect, lconf, certopt, nameopt, default_op,
+                 ext_copy, 0);
+
+ end:
+    X509_REQ_free(rreq);
+    X509_free(req);
+    return (ok);
+}
+
+static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
+                   const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
+                   STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,
+                   const char *subj, unsigned long chtype, int multirdn,
+                   int email_dn, const char *startdate, const char *enddate, long days,
+                   int batch, int verbose, X509_REQ *req, const char *ext_sect,
+                   CONF *lconf, unsigned long certopt, unsigned long nameopt,
+                   int default_op, int ext_copy, int selfsign)
+{
+    X509_NAME *name = NULL, *CAname = NULL, *subject = NULL, *dn_subject =
+        NULL;
+    const ASN1_TIME *tm;
+    ASN1_STRING *str, *str2;
+    ASN1_OBJECT *obj;
+    X509 *ret = NULL;
+    X509_NAME_ENTRY *ne;
+    X509_NAME_ENTRY *tne, *push;
+    EVP_PKEY *pktmp;
+    int ok = -1, i, j, last, nid;
+    const char *p;
+    CONF_VALUE *cv;
+    OPENSSL_STRING row[DB_NUMBER];
+    OPENSSL_STRING *irow = NULL;
+    OPENSSL_STRING *rrow = NULL;
+    char buf[25];
+
+    for (i = 0; i < DB_NUMBER; i++)
+        row[i] = NULL;
+
+    if (subj) {
+        X509_NAME *n = parse_name(subj, chtype, multirdn);
+
+        if (!n) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        X509_REQ_set_subject_name(req, n);
+        X509_NAME_free(n);
+    }
+
+    if (default_op)
+        BIO_printf(bio_err,
+                   "The Subject's Distinguished Name is as follows\n");
+
+    name = X509_REQ_get_subject_name(req);
+    for (i = 0; i < X509_NAME_entry_count(name); i++) {
+        ne = X509_NAME_get_entry(name, i);
+        str = X509_NAME_ENTRY_get_data(ne);
+        obj = X509_NAME_ENTRY_get_object(ne);
+
+        if (msie_hack) {
+            /* assume all type should be strings */
+            nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(ne));
+
+            if (str->type == V_ASN1_UNIVERSALSTRING)
+                ASN1_UNIVERSALSTRING_to_string(str);
+
+            if ((str->type == V_ASN1_IA5STRING) &&
+                (nid != NID_pkcs9_emailAddress))
+                str->type = V_ASN1_T61STRING;
+
+            if ((nid == NID_pkcs9_emailAddress) &&
+                (str->type == V_ASN1_PRINTABLESTRING))
+                str->type = V_ASN1_IA5STRING;
+        }
+
+        /* If no EMAIL is wanted in the subject */
+        if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
+            continue;
+
+        /* check some things */
+        if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
+            (str->type != V_ASN1_IA5STRING)) {
+            BIO_printf(bio_err,
+                       "\nemailAddress type needs to be of type IA5STRING\n");
+            goto end;
+        }
+        if ((str->type != V_ASN1_BMPSTRING)
+            && (str->type != V_ASN1_UTF8STRING)) {
+            j = ASN1_PRINTABLE_type(str->data, str->length);
+            if (((j == V_ASN1_T61STRING) &&
+                 (str->type != V_ASN1_T61STRING)) ||
+                ((j == V_ASN1_IA5STRING) &&
+                 (str->type == V_ASN1_PRINTABLESTRING))) {
+                BIO_printf(bio_err,
+                           "\nThe string contains characters that are illegal for the ASN.1 type\n");
+                goto end;
+            }
+        }
+
+        if (default_op)
+            old_entry_print(obj, str);
+    }
+
+    /* Ok, now we check the 'policy' stuff. */
+    if ((subject = X509_NAME_new()) == NULL) {
+        BIO_printf(bio_err, "Memory allocation failure\n");
+        goto end;
+    }
+
+    /* take a copy of the issuer name before we mess with it. */
+    if (selfsign)
+        CAname = X509_NAME_dup(name);
+    else
+        CAname = X509_NAME_dup(X509_get_subject_name(x509));
+    if (CAname == NULL)
+        goto end;
+    str = str2 = NULL;
+
+    for (i = 0; i < sk_CONF_VALUE_num(policy); i++) {
+        cv = sk_CONF_VALUE_value(policy, i); /* get the object id */
+        if ((j = OBJ_txt2nid(cv->name)) == NID_undef) {
+            BIO_printf(bio_err,
+                       "%s:unknown object type in 'policy' configuration\n",
+                       cv->name);
+            goto end;
+        }
+        obj = OBJ_nid2obj(j);
+
+        last = -1;
+        for (;;) {
+            /* lookup the object in the supplied name list */
+            j = X509_NAME_get_index_by_OBJ(name, obj, last);
+            if (j < 0) {
+                if (last != -1)
+                    break;
+                tne = NULL;
+            } else {
+                tne = X509_NAME_get_entry(name, j);
+            }
+            last = j;
+
+            /* depending on the 'policy', decide what to do. */
+            push = NULL;
+            if (strcmp(cv->value, "optional") == 0) {
+                if (tne != NULL)
+                    push = tne;
+            } else if (strcmp(cv->value, "supplied") == 0) {
+                if (tne == NULL) {
+                    BIO_printf(bio_err,
+                               "The %s field needed to be supplied and was missing\n",
+                               cv->name);
+                    goto end;
+                } else
+                    push = tne;
+            } else if (strcmp(cv->value, "match") == 0) {
+                int last2;
+
+                if (tne == NULL) {
+                    BIO_printf(bio_err,
+                               "The mandatory %s field was missing\n",
+                               cv->name);
+                    goto end;
+                }
+
+                last2 = -1;
+
+ again2:
+                j = X509_NAME_get_index_by_OBJ(CAname, obj, last2);
+                if ((j < 0) && (last2 == -1)) {
+                    BIO_printf(bio_err,
+                               "The %s field does not exist in the CA certificate,\n"
+                               "the 'policy' is misconfigured\n",
+                               cv->name);
+                    goto end;
+                }
+                if (j >= 0) {
+                    push = X509_NAME_get_entry(CAname, j);
+                    str = X509_NAME_ENTRY_get_data(tne);
+                    str2 = X509_NAME_ENTRY_get_data(push);
+                    last2 = j;
+                    if (ASN1_STRING_cmp(str, str2) != 0)
+                        goto again2;
+                }
+                if (j < 0) {
+                    BIO_printf(bio_err,
+                               "The %s field is different between\n"
+                               "CA certificate (%s) and the request (%s)\n",
+                               cv->name,
+                               ((str2 == NULL) ? "NULL" : (char *)str2->data),
+                               ((str == NULL) ? "NULL" : (char *)str->data));
+                    goto end;
+                }
+            } else {
+                BIO_printf(bio_err,
+                           "%s:invalid type in 'policy' configuration\n",
+                           cv->value);
+                goto end;
+            }
+
+            if (push != NULL) {
+                if (!X509_NAME_add_entry(subject, push, -1, 0)) {
+                    X509_NAME_ENTRY_free(push);
+                    BIO_printf(bio_err, "Memory allocation failure\n");
+                    goto end;
+                }
+            }
+            if (j < 0)
+                break;
+        }
+    }
+
+    if (preserve) {
+        X509_NAME_free(subject);
+        /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
+        subject = X509_NAME_dup(name);
+        if (subject == NULL)
+            goto end;
+    }
+
+    if (verbose)
+        BIO_printf(bio_err,
+                   "The subject name appears to be ok, checking data base for clashes\n");
+
+    /* Build the correct Subject if no e-mail is wanted in the subject */
+    /*
+     * and add it later on because of the method extensions are added
+     * (altName)
+     */
+
+    if (email_dn)
+        dn_subject = subject;
+    else {
+        X509_NAME_ENTRY *tmpne;
+        /*
+         * Its best to dup the subject DN and then delete any email addresses
+         * because this retains its structure.
+         */
+        if ((dn_subject = X509_NAME_dup(subject)) == NULL) {
+            BIO_printf(bio_err, "Memory allocation failure\n");
+            goto end;
+        }
+        while ((i = X509_NAME_get_index_by_NID(dn_subject,
+                                               NID_pkcs9_emailAddress,
+                                               -1)) >= 0) {
+            tmpne = X509_NAME_get_entry(dn_subject, i);
+            X509_NAME_delete_entry(dn_subject, i);
+            X509_NAME_ENTRY_free(tmpne);
+        }
+    }
+
+    if (BN_is_zero(serial))
+        row[DB_serial] = OPENSSL_strdup("00");
+    else
+        row[DB_serial] = BN_bn2hex(serial);
+    if (row[DB_serial] == NULL) {
+        BIO_printf(bio_err, "Memory allocation failure\n");
+        goto end;
+    }
+
+    if (db->attributes.unique_subject) {
+        OPENSSL_STRING *crow = row;
+
+        rrow = TXT_DB_get_by_index(db->db, DB_name, crow);
+        if (rrow != NULL) {
+            BIO_printf(bio_err,
+                       "ERROR:There is already a certificate for %s\n",
+                       row[DB_name]);
+        }
+    }
+    if (rrow == NULL) {
+        rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
+        if (rrow != NULL) {
+            BIO_printf(bio_err,
+                       "ERROR:Serial number %s has already been issued,\n",
+                       row[DB_serial]);
+            BIO_printf(bio_err,
+                       "      check the database/serial_file for corruption\n");
+        }
+    }
+
+    if (rrow != NULL) {
+        BIO_printf(bio_err, "The matching entry has the following details\n");
+        if (rrow[DB_type][0] == 'E')
+            p = "Expired";
+        else if (rrow[DB_type][0] == 'R')
+            p = "Revoked";
+        else if (rrow[DB_type][0] == 'V')
+            p = "Valid";
+        else
+            p = "\ninvalid type, Data base error\n";
+        BIO_printf(bio_err, "Type          :%s\n", p);;
+        if (rrow[DB_type][0] == 'R') {
+            p = rrow[DB_exp_date];
+            if (p == NULL)
+                p = "undef";
+            BIO_printf(bio_err, "Was revoked on:%s\n", p);
+        }
+        p = rrow[DB_exp_date];
+        if (p == NULL)
+            p = "undef";
+        BIO_printf(bio_err, "Expires on    :%s\n", p);
+        p = rrow[DB_serial];
+        if (p == NULL)
+            p = "undef";
+        BIO_printf(bio_err, "Serial Number :%s\n", p);
+        p = rrow[DB_file];
+        if (p == NULL)
+            p = "undef";
+        BIO_printf(bio_err, "File name     :%s\n", p);
+        p = rrow[DB_name];
+        if (p == NULL)
+            p = "undef";
+        BIO_printf(bio_err, "Subject Name  :%s\n", p);
+        ok = -1;                /* This is now a 'bad' error. */
+        goto end;
+    }
+
+    /* We are now totally happy, lets make and sign the certificate */
+    if (verbose)
+        BIO_printf(bio_err,
+                   "Everything appears to be ok, creating and signing the certificate\n");
+
+    if ((ret = X509_new()) == NULL)
+        goto end;
+
+#ifdef X509_V3
+    /* Make it an X509 v3 certificate. */
+    if (!X509_set_version(ret, 2))
+        goto end;
+#endif
+
+    if (BN_to_ASN1_INTEGER(serial, X509_get_serialNumber(ret)) == NULL)
+        goto end;
+    if (selfsign) {
+        if (!X509_set_issuer_name(ret, subject))
+            goto end;
+    } else {
+        if (!X509_set_issuer_name(ret, X509_get_subject_name(x509)))
+            goto end;
+    }
+
+    if (!set_cert_times(ret, startdate, enddate, days))
+        goto end;
+
+    if (enddate != NULL) {
+        int tdays;
+        ASN1_TIME_diff(&tdays, NULL, NULL, X509_get0_notAfter(ret));
+        days = tdays;
+    }
+
+    if (!X509_set_subject_name(ret, subject))
+        goto end;
+
+    pktmp = X509_REQ_get0_pubkey(req);
+    i = X509_set_pubkey(ret, pktmp);
+    if (!i)
+        goto end;
+
+    /* Lets add the extensions, if there are any */
+    if (ext_sect) {
+        X509V3_CTX ctx;
+        X509_set_version(ret, 2);
+
+        /* Initialize the context structure */
+        if (selfsign)
+            X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);
+        else
+            X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
+
+        if (extconf) {
+            if (verbose)
+                BIO_printf(bio_err, "Extra configuration file found\n");
+
+            /* Use the extconf configuration db LHASH */
+            X509V3_set_nconf(&ctx, extconf);
+
+            /* Test the structure (needed?) */
+            /* X509V3_set_ctx_test(&ctx); */
+
+            /* Adds exts contained in the configuration file */
+            if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect, ret)) {
+                BIO_printf(bio_err,
+                           "ERROR: adding extensions in section %s\n",
+                           ext_sect);
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+            if (verbose)
+                BIO_printf(bio_err,
+                           "Successfully added extensions from file.\n");
+        } else if (ext_sect) {
+            /* We found extensions to be set from config file */
+            X509V3_set_nconf(&ctx, lconf);
+
+            if (!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret)) {
+                BIO_printf(bio_err,
+                           "ERROR: adding extensions in section %s\n",
+                           ext_sect);
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+
+            if (verbose)
+                BIO_printf(bio_err,
+                           "Successfully added extensions from config\n");
+        }
+    }
+
+    /* Copy extensions from request (if any) */
+
+    if (!copy_extensions(ret, req, ext_copy)) {
+        BIO_printf(bio_err, "ERROR: adding extensions from request\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    /* Set the right value for the noemailDN option */
+    if (email_dn == 0) {
+        if (!X509_set_subject_name(ret, dn_subject))
+            goto end;
+    }
+
+    if (!default_op) {
+        BIO_printf(bio_err, "Certificate Details:\n");
+        /*
+         * Never print signature details because signature not present
+         */
+        certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME;
+        X509_print_ex(bio_err, ret, nameopt, certopt);
+    }
+
+    BIO_printf(bio_err, "Certificate is to be certified until ");
+    ASN1_TIME_print(bio_err, X509_get0_notAfter(ret));
+    if (days)
+        BIO_printf(bio_err, " (%ld days)", days);
+    BIO_printf(bio_err, "\n");
+
+    if (!batch) {
+
+        BIO_printf(bio_err, "Sign the certificate? [y/n]:");
+        (void)BIO_flush(bio_err);
+        buf[0] = '\0';
+        if (!fgets(buf, sizeof(buf) - 1, stdin)) {
+            BIO_printf(bio_err,
+                       "CERTIFICATE WILL NOT BE CERTIFIED: I/O error\n");
+            ok = 0;
+            goto end;
+        }
+        if (!((buf[0] == 'y') || (buf[0] == 'Y'))) {
+            BIO_printf(bio_err, "CERTIFICATE WILL NOT BE CERTIFIED\n");
+            ok = 0;
+            goto end;
+        }
+    }
+
+    pktmp = X509_get0_pubkey(ret);
+    if (EVP_PKEY_missing_parameters(pktmp) &&
+        !EVP_PKEY_missing_parameters(pkey))
+        EVP_PKEY_copy_parameters(pktmp, pkey);
+
+    if (!do_X509_sign(ret, pkey, dgst, sigopts))
+        goto end;
+
+    /* We now just add it to the database */
+    row[DB_type] = OPENSSL_strdup("V");
+    tm = X509_get0_notAfter(ret);
+    row[DB_exp_date] = app_malloc(tm->length + 1, "row expdate");
+    memcpy(row[DB_exp_date], tm->data, tm->length);
+    row[DB_exp_date][tm->length] = '\0';
+    row[DB_rev_date] = NULL;
+    row[DB_file] = OPENSSL_strdup("unknown");
+    row[DB_name] = X509_NAME_oneline(X509_get_subject_name(ret), NULL, 0);
+
+    if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
+        (row[DB_file] == NULL) || (row[DB_name] == NULL)) {
+        BIO_printf(bio_err, "Memory allocation failure\n");
+        goto end;
+    }
+
+    irow = app_malloc(sizeof(*irow) * (DB_NUMBER + 1), "row space");
+    for (i = 0; i < DB_NUMBER; i++) {
+        irow[i] = row[i];
+        row[i] = NULL;
+    }
+    irow[DB_NUMBER] = NULL;
+
+    if (!TXT_DB_insert(db->db, irow)) {
+        BIO_printf(bio_err, "failed to update database\n");
+        BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error);
+        goto end;
+    }
+    ok = 1;
+ end:
+    for (i = 0; i < DB_NUMBER; i++)
+        OPENSSL_free(row[i]);
+
+    X509_NAME_free(CAname);
+    X509_NAME_free(subject);
+    if (dn_subject != subject)
+        X509_NAME_free(dn_subject);
+    if (ok <= 0)
+        X509_free(ret);
+    else
+        *xret = ret;
+    return (ok);
+}
+
+static void write_new_certificate(BIO *bp, X509 *x, int output_der,
+                                  int notext)
+{
+
+    if (output_der) {
+        (void)i2d_X509_bio(bp, x);
+        return;
+    }
+    if (!notext)
+        X509_print(bp, x);
+    PEM_write_bio_X509(bp, x);
+}
+
+static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey,
+                         X509 *x509, const EVP_MD *dgst,
+                         STACK_OF(OPENSSL_STRING) *sigopts,
+                         STACK_OF(CONF_VALUE) *policy, CA_DB *db,
+                         BIGNUM *serial, const char *subj, unsigned long chtype,
+                         int multirdn, int email_dn, const char *startdate,
+                         const char *enddate, long days, const char *ext_sect,
+                         CONF *lconf, int verbose, unsigned long certopt,
+                         unsigned long nameopt, int default_op, int ext_copy)
+{
+    STACK_OF(CONF_VALUE) *sk = NULL;
+    LHASH_OF(CONF_VALUE) *parms = NULL;
+    X509_REQ *req = NULL;
+    CONF_VALUE *cv = NULL;
+    NETSCAPE_SPKI *spki = NULL;
+    char *type, *buf;
+    EVP_PKEY *pktmp = NULL;
+    X509_NAME *n = NULL;
+    X509_NAME_ENTRY *ne = NULL;
+    int ok = -1, i, j;
+    long errline;
+    int nid;
+
+    /*
+     * Load input file into a hash table.  (This is just an easy
+     * way to read and parse the file, then put it into a convenient
+     * STACK format).
+     */
+    parms = CONF_load(NULL, infile, &errline);
+    if (parms == NULL) {
+        BIO_printf(bio_err, "error on line %ld of %s\n", errline, infile);
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    sk = CONF_get_section(parms, "default");
+    if (sk_CONF_VALUE_num(sk) == 0) {
+        BIO_printf(bio_err, "no name/value pairs found in %s\n", infile);
+        goto end;
+    }
+
+    /*
+     * Now create a dummy X509 request structure.  We don't actually
+     * have an X509 request, but we have many of the components
+     * (a public key, various DN components).  The idea is that we
+     * put these components into the right X509 request structure
+     * and we can use the same code as if you had a real X509 request.
+     */
+    req = X509_REQ_new();
+    if (req == NULL) {
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    /*
+     * Build up the subject name set.
+     */
+    n = X509_REQ_get_subject_name(req);
+
+    for (i = 0;; i++) {
+        if (sk_CONF_VALUE_num(sk) <= i)
+            break;
+
+        cv = sk_CONF_VALUE_value(sk, i);
+        type = cv->name;
+        /*
+         * Skip past any leading X. X: X, etc to allow for multiple instances
+         */
+        for (buf = cv->name; *buf; buf++)
+            if ((*buf == ':') || (*buf == ',') || (*buf == '.')) {
+                buf++;
+                if (*buf)
+                    type = buf;
+                break;
+            }
+
+        buf = cv->value;
+        if ((nid = OBJ_txt2nid(type)) == NID_undef) {
+            if (strcmp(type, "SPKAC") == 0) {
+                spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
+                if (spki == NULL) {
+                    BIO_printf(bio_err,
+                               "unable to load Netscape SPKAC structure\n");
+                    ERR_print_errors(bio_err);
+                    goto end;
+                }
+            }
+            continue;
+        }
+
+        if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
+                                        (unsigned char *)buf, -1, -1, 0))
+            goto end;
+    }
+    if (spki == NULL) {
+        BIO_printf(bio_err, "Netscape SPKAC structure not found in %s\n",
+                   infile);
+        goto end;
+    }
+
+    /*
+     * Now extract the key from the SPKI structure.
+     */
+
+    BIO_printf(bio_err,
+               "Check that the SPKAC request matches the signature\n");
+
+    if ((pktmp = NETSCAPE_SPKI_get_pubkey(spki)) == NULL) {
+        BIO_printf(bio_err, "error unpacking SPKAC public key\n");
+        goto end;
+    }
+
+    j = NETSCAPE_SPKI_verify(spki, pktmp);
+    if (j <= 0) {
+        EVP_PKEY_free(pktmp);
+        BIO_printf(bio_err,
+                   "signature verification failed on SPKAC public key\n");
+        goto end;
+    }
+    BIO_printf(bio_err, "Signature ok\n");
+
+    X509_REQ_set_pubkey(req, pktmp);
+    EVP_PKEY_free(pktmp);
+    ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj,
+                 chtype, multirdn, email_dn, startdate, enddate, days, 1,
+                 verbose, req, ext_sect, lconf, certopt, nameopt, default_op,
+                 ext_copy, 0);
+ end:
+    X509_REQ_free(req);
+    CONF_free(parms);
+    NETSCAPE_SPKI_free(spki);
+    X509_NAME_ENTRY_free(ne);
+
+    return (ok);
+}
+
+static int check_time_format(const char *str)
+{
+    return ASN1_TIME_set_string(NULL, str);
+}
+
+static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
+{
+    const ASN1_TIME *tm = NULL;
+    char *row[DB_NUMBER], **rrow, **irow;
+    char *rev_str = NULL;
+    BIGNUM *bn = NULL;
+    int ok = -1, i;
+
+    for (i = 0; i < DB_NUMBER; i++)
+        row[i] = NULL;
+    row[DB_name] = X509_NAME_oneline(X509_get_subject_name(x509), NULL, 0);
+    bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509), NULL);
+    if (!bn)
+        goto end;
+    if (BN_is_zero(bn))
+        row[DB_serial] = OPENSSL_strdup("00");
+    else
+        row[DB_serial] = BN_bn2hex(bn);
+    BN_free(bn);
+    if ((row[DB_name] == NULL) || (row[DB_serial] == NULL)) {
+        BIO_printf(bio_err, "Memory allocation failure\n");
+        goto end;
+    }
+    /*
+     * We have to lookup by serial number because name lookup skips revoked
+     * certs
+     */
+    rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
+    if (rrow == NULL) {
+        BIO_printf(bio_err,
+                   "Adding Entry with serial number %s to DB for %s\n",
+                   row[DB_serial], row[DB_name]);
+
+        /* We now just add it to the database */
+        row[DB_type] = OPENSSL_strdup("V");
+        tm = X509_get0_notAfter(x509);
+        row[DB_exp_date] = app_malloc(tm->length + 1, "row exp_data");
+        memcpy(row[DB_exp_date], tm->data, tm->length);
+        row[DB_exp_date][tm->length] = '\0';
+        row[DB_rev_date] = NULL;
+        row[DB_file] = OPENSSL_strdup("unknown");
+
+        irow = app_malloc(sizeof(*irow) * (DB_NUMBER + 1), "row ptr");
+        for (i = 0; i < DB_NUMBER; i++) {
+            irow[i] = row[i];
+            row[i] = NULL;
+        }
+        irow[DB_NUMBER] = NULL;
+
+        if (!TXT_DB_insert(db->db, irow)) {
+            BIO_printf(bio_err, "failed to update database\n");
+            BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error);
+            goto end;
+        }
+
+        /* Revoke Certificate */
+        if (type == -1)
+            ok = 1;
+        else
+            ok = do_revoke(x509, db, type, value);
+
+        goto end;
+
+    } else if (index_name_cmp_noconst(row, rrow)) {
+        BIO_printf(bio_err, "ERROR:name does not match %s\n", row[DB_name]);
+        goto end;
+    } else if (type == -1) {
+        BIO_printf(bio_err, "ERROR:Already present, serial number %s\n",
+                   row[DB_serial]);
+        goto end;
+    } else if (rrow[DB_type][0] == 'R') {
+        BIO_printf(bio_err, "ERROR:Already revoked, serial number %s\n",
+                   row[DB_serial]);
+        goto end;
+    } else {
+        BIO_printf(bio_err, "Revoking Certificate %s.\n", rrow[DB_serial]);
+        rev_str = make_revocation_str(type, value);
+        if (!rev_str) {
+            BIO_printf(bio_err, "Error in revocation arguments\n");
+            goto end;
+        }
+        rrow[DB_type][0] = 'R';
+        rrow[DB_type][1] = '\0';
+        rrow[DB_rev_date] = rev_str;
+    }
+    ok = 1;
+ end:
+    for (i = 0; i < DB_NUMBER; i++) {
+        OPENSSL_free(row[i]);
+    }
+    return (ok);
+}
+
+static int get_certificate_status(const char *serial, CA_DB *db)
+{
+    char *row[DB_NUMBER], **rrow;
+    int ok = -1, i;
+    size_t serial_len = strlen(serial);
+
+    /* Free Resources */
+    for (i = 0; i < DB_NUMBER; i++)
+        row[i] = NULL;
+
+    /* Malloc needed char spaces */
+    row[DB_serial] = app_malloc(serial_len + 2, "row serial#");
+
+    if (serial_len % 2) {
+        /*
+         * Set the first char to 0
+         */ ;
+        row[DB_serial][0] = '0';
+
+        /* Copy String from serial to row[DB_serial] */
+        memcpy(row[DB_serial] + 1, serial, serial_len);
+        row[DB_serial][serial_len + 1] = '\0';
+    } else {
+        /* Copy String from serial to row[DB_serial] */
+        memcpy(row[DB_serial], serial, serial_len);
+        row[DB_serial][serial_len] = '\0';
+    }
+
+    /* Make it Upper Case */
+    for (i = 0; row[DB_serial][i] != '\0'; i++)
+        row[DB_serial][i] = toupper((unsigned char)row[DB_serial][i]);
+
+    ok = 1;
+
+    /* Search for the certificate */
+    rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
+    if (rrow == NULL) {
+        BIO_printf(bio_err, "Serial %s not present in db.\n", row[DB_serial]);
+        ok = -1;
+        goto end;
+    } else if (rrow[DB_type][0] == 'V') {
+        BIO_printf(bio_err, "%s=Valid (%c)\n",
+                   row[DB_serial], rrow[DB_type][0]);
+        goto end;
+    } else if (rrow[DB_type][0] == 'R') {
+        BIO_printf(bio_err, "%s=Revoked (%c)\n",
+                   row[DB_serial], rrow[DB_type][0]);
+        goto end;
+    } else if (rrow[DB_type][0] == 'E') {
+        BIO_printf(bio_err, "%s=Expired (%c)\n",
+                   row[DB_serial], rrow[DB_type][0]);
+        goto end;
+    } else if (rrow[DB_type][0] == 'S') {
+        BIO_printf(bio_err, "%s=Suspended (%c)\n",
+                   row[DB_serial], rrow[DB_type][0]);
+        goto end;
+    } else {
+        BIO_printf(bio_err, "%s=Unknown (%c).\n",
+                   row[DB_serial], rrow[DB_type][0]);
+        ok = -1;
+    }
+ end:
+    for (i = 0; i < DB_NUMBER; i++) {
+        OPENSSL_free(row[i]);
+    }
+    return (ok);
+}
+
+static int do_updatedb(CA_DB *db)
+{
+    ASN1_UTCTIME *a_tm = NULL;
+    int i, cnt = 0;
+    int db_y2k, a_y2k;          /* flags = 1 if y >= 2000 */
+    char **rrow, *a_tm_s;
+
+    a_tm = ASN1_UTCTIME_new();
+    if (a_tm == NULL)
+        return -1;
+
+    /* get actual time and make a string */
+    a_tm = X509_gmtime_adj(a_tm, 0);
+    a_tm_s = app_malloc(a_tm->length + 1, "time string");
+
+    memcpy(a_tm_s, a_tm->data, a_tm->length);
+    a_tm_s[a_tm->length] = '\0';
+
+    if (strncmp(a_tm_s, "49", 2) <= 0)
+        a_y2k = 1;
+    else
+        a_y2k = 0;
+
+    for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
+        rrow = sk_OPENSSL_PSTRING_value(db->db->data, i);
+
+        if (rrow[DB_type][0] == 'V') {
+            /* ignore entries that are not valid */
+            if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
+                db_y2k = 1;
+            else
+                db_y2k = 0;
+
+            if (db_y2k == a_y2k) {
+                /* all on the same y2k side */
+                if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0) {
+                    rrow[DB_type][0] = 'E';
+                    rrow[DB_type][1] = '\0';
+                    cnt++;
+
+                    BIO_printf(bio_err, "%s=Expired\n", rrow[DB_serial]);
+                }
+            } else if (db_y2k < a_y2k) {
+                rrow[DB_type][0] = 'E';
+                rrow[DB_type][1] = '\0';
+                cnt++;
+
+                BIO_printf(bio_err, "%s=Expired\n", rrow[DB_serial]);
+            }
+
+        }
+    }
+
+    ASN1_UTCTIME_free(a_tm);
+    OPENSSL_free(a_tm_s);
+    return (cnt);
+}
+
+static const char *crl_reasons[] = {
+    /* CRL reason strings */
+    "unspecified",
+    "keyCompromise",
+    "CACompromise",
+    "affiliationChanged",
+    "superseded",
+    "cessationOfOperation",
+    "certificateHold",
+    "removeFromCRL",
+    /* Additional pseudo reasons */
+    "holdInstruction",
+    "keyTime",
+    "CAkeyTime"
+};
+
+#define NUM_REASONS OSSL_NELEM(crl_reasons)
+
+/*
+ * Given revocation information convert to a DB string. The format of the
+ * string is: revtime[,reason,extra]. Where 'revtime' is the revocation time
+ * (the current time). 'reason' is the optional CRL reason and 'extra' is any
+ * additional argument
+ */
+
+char *make_revocation_str(int rev_type, char *rev_arg)
+{
+    char *str;
+    const char *other = NULL;
+    const char *reason = NULL;
+    ASN1_OBJECT *otmp;
+    ASN1_UTCTIME *revtm = NULL;
+    int i;
+    switch (rev_type) {
+    case REV_NONE:
+        break;
+
+    case REV_CRL_REASON:
+        for (i = 0; i < 8; i++) {
+            if (strcasecmp(rev_arg, crl_reasons[i]) == 0) {
+                reason = crl_reasons[i];
+                break;
+            }
+        }
+        if (reason == NULL) {
+            BIO_printf(bio_err, "Unknown CRL reason %s\n", rev_arg);
+            return NULL;
+        }
+        break;
+
+    case REV_HOLD:
+        /* Argument is an OID */
+
+        otmp = OBJ_txt2obj(rev_arg, 0);
+        ASN1_OBJECT_free(otmp);
+
+        if (otmp == NULL) {
+            BIO_printf(bio_err, "Invalid object identifier %s\n", rev_arg);
+            return NULL;
+        }
+
+        reason = "holdInstruction";
+        other = rev_arg;
+        break;
+
+    case REV_KEY_COMPROMISE:
+    case REV_CA_COMPROMISE:
+
+        /* Argument is the key compromise time  */
+        if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg)) {
+            BIO_printf(bio_err,
+                       "Invalid time format %s. Need YYYYMMDDHHMMSSZ\n",
+                       rev_arg);
+            return NULL;
+        }
+        other = rev_arg;
+        if (rev_type == REV_KEY_COMPROMISE)
+            reason = "keyTime";
+        else
+            reason = "CAkeyTime";
+
+        break;
+
+    }
+
+    revtm = X509_gmtime_adj(NULL, 0);
+
+    if (!revtm)
+        return NULL;
+
+    i = revtm->length + 1;
+
+    if (reason)
+        i += strlen(reason) + 1;
+    if (other)
+        i += strlen(other) + 1;
+
+    str = app_malloc(i, "revocation reason");
+    OPENSSL_strlcpy(str, (char *)revtm->data, i);
+    if (reason) {
+        OPENSSL_strlcat(str, ",", i);
+        OPENSSL_strlcat(str, reason, i);
+    }
+    if (other) {
+        OPENSSL_strlcat(str, ",", i);
+        OPENSSL_strlcat(str, other, i);
+    }
+    ASN1_UTCTIME_free(revtm);
+    return str;
+}
+
+/*-
+ * Convert revocation field to X509_REVOKED entry
+ * return code:
+ * 0 error
+ * 1 OK
+ * 2 OK and some extensions added (i.e. V2 CRL)
+ */
+
+int make_revoked(X509_REVOKED *rev, const char *str)
+{
+    char *tmp = NULL;
+    int reason_code = -1;
+    int i, ret = 0;
+    ASN1_OBJECT *hold = NULL;
+    ASN1_GENERALIZEDTIME *comp_time = NULL;
+    ASN1_ENUMERATED *rtmp = NULL;
+
+    ASN1_TIME *revDate = NULL;
+
+    i = unpack_revinfo(&revDate, &reason_code, &hold, &comp_time, str);
+
+    if (i == 0)
+        goto end;
+
+    if (rev && !X509_REVOKED_set_revocationDate(rev, revDate))
+        goto end;
+
+    if (rev && (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)) {
+        rtmp = ASN1_ENUMERATED_new();
+        if (rtmp == NULL || !ASN1_ENUMERATED_set(rtmp, reason_code))
+            goto end;
+        if (!X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, rtmp, 0, 0))
+            goto end;
+    }
+
+    if (rev && comp_time) {
+        if (!X509_REVOKED_add1_ext_i2d
+            (rev, NID_invalidity_date, comp_time, 0, 0))
+            goto end;
+    }
+    if (rev && hold) {
+        if (!X509_REVOKED_add1_ext_i2d
+            (rev, NID_hold_instruction_code, hold, 0, 0))
+            goto end;
+    }
+
+    if (reason_code != OCSP_REVOKED_STATUS_NOSTATUS)
+        ret = 2;
+    else
+        ret = 1;
+
+ end:
+
+    OPENSSL_free(tmp);
+    ASN1_OBJECT_free(hold);
+    ASN1_GENERALIZEDTIME_free(comp_time);
+    ASN1_ENUMERATED_free(rtmp);
+    ASN1_TIME_free(revDate);
+
+    return ret;
+}
+
+static int old_entry_print(const ASN1_OBJECT *obj, const ASN1_STRING *str)
+{
+    char buf[25], *pbuf;
+    const char *p;
+    int j;
+
+    j = i2a_ASN1_OBJECT(bio_err, obj);
+    pbuf = buf;
+    for (j = 22 - j; j > 0; j--)
+        *(pbuf++) = ' ';
+    *(pbuf++) = ':';
+    *(pbuf++) = '\0';
+    BIO_puts(bio_err, buf);
+
+    if (str->type == V_ASN1_PRINTABLESTRING)
+        BIO_printf(bio_err, "PRINTABLE:'");
+    else if (str->type == V_ASN1_T61STRING)
+        BIO_printf(bio_err, "T61STRING:'");
+    else if (str->type == V_ASN1_IA5STRING)
+        BIO_printf(bio_err, "IA5STRING:'");
+    else if (str->type == V_ASN1_UNIVERSALSTRING)
+        BIO_printf(bio_err, "UNIVERSALSTRING:'");
+    else
+        BIO_printf(bio_err, "ASN.1 %2d:'", str->type);
+
+    p = (const char *)str->data;
+    for (j = str->length; j > 0; j--) {
+        if ((*p >= ' ') && (*p <= '~'))
+            BIO_printf(bio_err, "%c", *p);
+        else if (*p & 0x80)
+            BIO_printf(bio_err, "\\0x%02X", *p);
+        else if ((unsigned char)*p == 0xf7)
+            BIO_printf(bio_err, "^?");
+        else
+            BIO_printf(bio_err, "^%c", *p + '@');
+        p++;
+    }
+    BIO_printf(bio_err, "'\n");
+    return 1;
+}
+
+int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
+                   ASN1_GENERALIZEDTIME **pinvtm, const char *str)
+{
+    char *tmp;
+    char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
+    int reason_code = -1;
+    int ret = 0;
+    unsigned int i;
+    ASN1_OBJECT *hold = NULL;
+    ASN1_GENERALIZEDTIME *comp_time = NULL;
+
+    tmp = OPENSSL_strdup(str);
+    if (!tmp) {
+        BIO_printf(bio_err, "memory allocation failure\n");
+        goto end;
+    }
+
+    p = strchr(tmp, ',');
+
+    rtime_str = tmp;
+
+    if (p) {
+        *p = '\0';
+        p++;
+        reason_str = p;
+        p = strchr(p, ',');
+        if (p) {
+            *p = '\0';
+            arg_str = p + 1;
+        }
+    }
+
+    if (prevtm) {
+        *prevtm = ASN1_UTCTIME_new();
+        if (*prevtm == NULL) {
+            BIO_printf(bio_err, "memory allocation failure\n");
+            goto end;
+        }
+        if (!ASN1_UTCTIME_set_string(*prevtm, rtime_str)) {
+            BIO_printf(bio_err, "invalid revocation date %s\n", rtime_str);
+            goto end;
+        }
+    }
+    if (reason_str) {
+        for (i = 0; i < NUM_REASONS; i++) {
+            if (strcasecmp(reason_str, crl_reasons[i]) == 0) {
+                reason_code = i;
+                break;
+            }
+        }
+        if (reason_code == OCSP_REVOKED_STATUS_NOSTATUS) {
+            BIO_printf(bio_err, "invalid reason code %s\n", reason_str);
+            goto end;
+        }
+
+        if (reason_code == 7)
+            reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
+        else if (reason_code == 8) { /* Hold instruction */
+            if (!arg_str) {
+                BIO_printf(bio_err, "missing hold instruction\n");
+                goto end;
+            }
+            reason_code = OCSP_REVOKED_STATUS_CERTIFICATEHOLD;
+            hold = OBJ_txt2obj(arg_str, 0);
+
+            if (!hold) {
+                BIO_printf(bio_err, "invalid object identifier %s\n",
+                           arg_str);
+                goto end;
+            }
+            if (phold)
+                *phold = hold;
+            else
+                ASN1_OBJECT_free(hold);
+        } else if ((reason_code == 9) || (reason_code == 10)) {
+            if (!arg_str) {
+                BIO_printf(bio_err, "missing compromised time\n");
+                goto end;
+            }
+            comp_time = ASN1_GENERALIZEDTIME_new();
+            if (comp_time == NULL) {
+                BIO_printf(bio_err, "memory allocation failure\n");
+                goto end;
+            }
+            if (!ASN1_GENERALIZEDTIME_set_string(comp_time, arg_str)) {
+                BIO_printf(bio_err, "invalid compromised time %s\n", arg_str);
+                goto end;
+            }
+            if (reason_code == 9)
+                reason_code = OCSP_REVOKED_STATUS_KEYCOMPROMISE;
+            else
+                reason_code = OCSP_REVOKED_STATUS_CACOMPROMISE;
+        }
+    }
+
+    if (preason)
+        *preason = reason_code;
+    if (pinvtm) {
+        *pinvtm = comp_time;
+        comp_time = NULL;
+    }
+
+    ret = 1;
+
+ end:
+
+    OPENSSL_free(tmp);
+    ASN1_GENERALIZEDTIME_free(comp_time);
+
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/ciphers.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/ciphers.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/ciphers.c	(revision 331)
@@ -0,0 +1,242 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_STDNAME,
+    OPT_SSL3,
+    OPT_TLS1,
+    OPT_TLS1_1,
+    OPT_TLS1_2,
+    OPT_PSK,
+    OPT_SRP,
+    OPT_V, OPT_UPPER_V, OPT_S
+} OPTION_CHOICE;
+
+OPTIONS ciphers_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"v", OPT_V, '-', "Verbose listing of the SSL/TLS ciphers"},
+    {"V", OPT_UPPER_V, '-', "Even more verbose"},
+    {"s", OPT_S, '-', "Only supported ciphers"},
+#ifndef OPENSSL_NO_SSL3
+    {"ssl3", OPT_SSL3, '-', "SSL3 mode"},
+#endif
+#ifndef OPENSSL_NO_TLS1
+    {"tls1", OPT_TLS1, '-', "TLS1 mode"},
+#endif
+#ifndef OPENSSL_NO_TLS1_1
+    {"tls1_1", OPT_TLS1_1, '-', "TLS1.1 mode"},
+#endif
+#ifndef OPENSSL_NO_TLS1_2
+    {"tls1_2", OPT_TLS1_2, '-', "TLS1.2 mode"},
+#endif
+#ifndef OPENSSL_NO_SSL_TRACE
+    {"stdname", OPT_STDNAME, '-', "Show standard cipher names"},
+#endif
+#ifndef OPENSSL_NO_PSK
+    {"psk", OPT_PSK, '-', "include ciphersuites requiring PSK"},
+#endif
+#ifndef OPENSSL_NO_SRP
+    {"srp", OPT_SRP, '-', "include ciphersuites requiring SRP"},
+#endif
+    {NULL}
+};
+
+#ifndef OPENSSL_NO_PSK
+static unsigned int dummy_psk(SSL *ssl, const char *hint, char *identity,
+                              unsigned int max_identity_len,
+                              unsigned char *psk,
+                              unsigned int max_psk_len)
+{
+    return 0;
+}
+#endif
+#ifndef OPENSSL_NO_SRP
+static char *dummy_srp(SSL *ssl, void *arg)
+{
+    return "";
+}
+#endif
+
+int ciphers_main(int argc, char **argv)
+{
+    SSL_CTX *ctx = NULL;
+    SSL *ssl = NULL;
+    STACK_OF(SSL_CIPHER) *sk = NULL;
+    const SSL_METHOD *meth = TLS_server_method();
+    int ret = 1, i, verbose = 0, Verbose = 0, use_supported = 0;
+#ifndef OPENSSL_NO_SSL_TRACE
+    int stdname = 0;
+#endif
+#ifndef OPENSSL_NO_PSK
+    int psk = 0;
+#endif
+#ifndef OPENSSL_NO_SRP
+    int srp = 0;
+#endif
+    const char *p;
+    char *ciphers = NULL, *prog;
+    char buf[512];
+    OPTION_CHOICE o;
+    int min_version = 0, max_version = 0;
+
+    prog = opt_init(argc, argv, ciphers_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(ciphers_options);
+            ret = 0;
+            goto end;
+        case OPT_V:
+            verbose = 1;
+            break;
+        case OPT_UPPER_V:
+            verbose = Verbose = 1;
+            break;
+        case OPT_S:
+            use_supported = 1;
+            break;
+        case OPT_STDNAME:
+#ifndef OPENSSL_NO_SSL_TRACE
+            stdname = verbose = 1;
+#endif
+            break;
+        case OPT_SSL3:
+            min_version = SSL3_VERSION;
+            max_version = SSL3_VERSION;
+            break;
+        case OPT_TLS1:
+            min_version = TLS1_VERSION;
+            max_version = TLS1_VERSION;
+            break;
+        case OPT_TLS1_1:
+            min_version = TLS1_1_VERSION;
+            max_version = TLS1_1_VERSION;
+            break;
+        case OPT_TLS1_2:
+            min_version = TLS1_2_VERSION;
+            max_version = TLS1_2_VERSION;
+            break;
+        case OPT_PSK:
+#ifndef OPENSSL_NO_PSK
+            psk = 1;
+#endif
+            break;
+        case OPT_SRP:
+#ifndef OPENSSL_NO_SRP
+            srp = 1;
+#endif
+            break;
+        }
+    }
+    argv = opt_rest();
+    argc = opt_num_rest();
+
+    if (argc == 1)
+        ciphers = *argv;
+    else if (argc != 0)
+        goto opthelp;
+
+    ctx = SSL_CTX_new(meth);
+    if (ctx == NULL)
+        goto err;
+    if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0)
+        goto err;
+    if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
+        goto err;
+
+#ifndef OPENSSL_NO_PSK
+    if (psk)
+        SSL_CTX_set_psk_client_callback(ctx, dummy_psk);
+#endif
+#ifndef OPENSSL_NO_SRP
+    if (srp)
+        SSL_CTX_set_srp_client_pwd_callback(ctx, dummy_srp);
+#endif
+    if (ciphers != NULL) {
+        if (!SSL_CTX_set_cipher_list(ctx, ciphers)) {
+            BIO_printf(bio_err, "Error in cipher list\n");
+            goto err;
+        }
+    }
+    ssl = SSL_new(ctx);
+    if (ssl == NULL)
+        goto err;
+
+    if (use_supported)
+        sk = SSL_get1_supported_ciphers(ssl);
+    else
+        sk = SSL_get_ciphers(ssl);
+
+    if (!verbose) {
+        for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
+            const SSL_CIPHER *c = sk_SSL_CIPHER_value(sk, i);
+            p = SSL_CIPHER_get_name(c);
+            if (p == NULL)
+                break;
+            if (i != 0)
+                BIO_printf(bio_out, ":");
+            BIO_printf(bio_out, "%s", p);
+        }
+        BIO_printf(bio_out, "\n");
+    } else {
+
+        for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
+            const SSL_CIPHER *c;
+
+            c = sk_SSL_CIPHER_value(sk, i);
+
+            if (Verbose) {
+                unsigned long id = SSL_CIPHER_get_id(c);
+                int id0 = (int)(id >> 24);
+                int id1 = (int)((id >> 16) & 0xffL);
+                int id2 = (int)((id >> 8) & 0xffL);
+                int id3 = (int)(id & 0xffL);
+
+                if ((id & 0xff000000L) == 0x03000000L)
+                    BIO_printf(bio_out, "          0x%02X,0x%02X - ", id2, id3); /* SSL3
+                                                                                  * cipher */
+                else
+                    BIO_printf(bio_out, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0, id1, id2, id3); /* whatever */
+            }
+#ifndef OPENSSL_NO_SSL_TRACE
+            if (stdname) {
+                const char *nm = SSL_CIPHER_standard_name(c);
+                if (nm == NULL)
+                    nm = "UNKNOWN";
+                BIO_printf(bio_out, "%s - ", nm);
+            }
+#endif
+            BIO_puts(bio_out, SSL_CIPHER_description(c, buf, sizeof buf));
+        }
+    }
+
+    ret = 0;
+    goto end;
+ err:
+    ERR_print_errors(bio_err);
+ end:
+    if (use_supported)
+        sk_SSL_CIPHER_free(sk);
+    SSL_CTX_free(ctx);
+    SSL_free(ssl);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/cms.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/cms.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/cms.c	(revision 331)
@@ -0,0 +1,1294 @@
+/*
+ * Copyright 2008-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
+ */
+
+/* CMS utility function */
+
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+
+#ifndef OPENSSL_NO_CMS
+
+# include <openssl/crypto.h>
+# include <openssl/pem.h>
+# include <openssl/err.h>
+# include <openssl/x509_vfy.h>
+# include <openssl/x509v3.h>
+# include <openssl/cms.h>
+
+static int save_certs(char *signerfile, STACK_OF(X509) *signers);
+static int cms_cb(int ok, X509_STORE_CTX *ctx);
+static void receipt_request_print(CMS_ContentInfo *cms);
+static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING)
+                                                *rr_to, int rr_allorfirst, STACK_OF(OPENSSL_STRING)
+                                                *rr_from);
+static int cms_set_pkey_param(EVP_PKEY_CTX *pctx,
+                              STACK_OF(OPENSSL_STRING) *param);
+
+# define SMIME_OP        0x10
+# define SMIME_IP        0x20
+# define SMIME_SIGNERS   0x40
+# define SMIME_ENCRYPT           (1 | SMIME_OP)
+# define SMIME_DECRYPT           (2 | SMIME_IP)
+# define SMIME_SIGN              (3 | SMIME_OP | SMIME_SIGNERS)
+# define SMIME_VERIFY            (4 | SMIME_IP)
+# define SMIME_CMSOUT            (5 | SMIME_IP | SMIME_OP)
+# define SMIME_RESIGN            (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
+# define SMIME_DATAOUT           (7 | SMIME_IP)
+# define SMIME_DATA_CREATE       (8 | SMIME_OP)
+# define SMIME_DIGEST_VERIFY     (9 | SMIME_IP)
+# define SMIME_DIGEST_CREATE     (10 | SMIME_OP)
+# define SMIME_UNCOMPRESS        (11 | SMIME_IP)
+# define SMIME_COMPRESS          (12 | SMIME_OP)
+# define SMIME_ENCRYPTED_DECRYPT (13 | SMIME_IP)
+# define SMIME_ENCRYPTED_ENCRYPT (14 | SMIME_OP)
+# define SMIME_SIGN_RECEIPT      (15 | SMIME_IP | SMIME_OP)
+# define SMIME_VERIFY_RECEIPT    (16 | SMIME_IP)
+
+static int verify_err = 0;
+
+typedef struct cms_key_param_st cms_key_param;
+
+struct cms_key_param_st {
+    int idx;
+    STACK_OF(OPENSSL_STRING) *param;
+    cms_key_param *next;
+};
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_ENCRYPT,
+    OPT_DECRYPT, OPT_SIGN, OPT_SIGN_RECEIPT, OPT_RESIGN,
+    OPT_VERIFY, OPT_VERIFY_RETCODE, OPT_VERIFY_RECEIPT,
+    OPT_CMSOUT, OPT_DATA_OUT, OPT_DATA_CREATE, OPT_DIGEST_VERIFY,
+    OPT_DIGEST_CREATE, OPT_COMPRESS, OPT_UNCOMPRESS,
+    OPT_ED_DECRYPT, OPT_ED_ENCRYPT, OPT_DEBUG_DECRYPT, OPT_TEXT,
+    OPT_ASCIICRLF, OPT_NOINTERN, OPT_NOVERIFY, OPT_NOCERTS,
+    OPT_NOATTR, OPT_NODETACH, OPT_NOSMIMECAP, OPT_BINARY, OPT_KEYID,
+    OPT_NOSIGS, OPT_NO_CONTENT_VERIFY, OPT_NO_ATTR_VERIFY, OPT_INDEF,
+    OPT_NOINDEF, OPT_CRLFEOL, OPT_NOOUT, OPT_RR_PRINT,
+    OPT_RR_ALL, OPT_RR_FIRST, OPT_RCTFORM, OPT_CERTFILE, OPT_CAFILE,
+    OPT_CAPATH, OPT_NOCAPATH, OPT_NOCAFILE,OPT_CONTENT, OPT_PRINT,
+    OPT_SECRETKEY, OPT_SECRETKEYID, OPT_PWRI_PASSWORD, OPT_ECONTENT_TYPE,
+    OPT_RAND, OPT_PASSIN, OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP,
+    OPT_CERTSOUT, OPT_MD, OPT_INKEY, OPT_KEYFORM, OPT_KEYOPT, OPT_RR_FROM,
+    OPT_RR_TO, OPT_AES128_WRAP, OPT_AES192_WRAP, OPT_AES256_WRAP,
+    OPT_3DES_WRAP, OPT_ENGINE,
+    OPT_V_ENUM,
+    OPT_CIPHER
+} OPTION_CHOICE;
+
+OPTIONS cms_options[] = {
+    {OPT_HELP_STR, 1, '-', "Usage: %s [options] cert.pem...\n"},
+    {OPT_HELP_STR, 1, '-',
+        "  cert.pem... recipient certs for encryption\n"},
+    {OPT_HELP_STR, 1, '-', "Valid options are:\n"},
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"inform", OPT_INFORM, 'c', "Input format SMIME (default), PEM or DER"},
+    {"outform", OPT_OUTFORM, 'c',
+     "Output format SMIME (default), PEM or DER"},
+    {"in", OPT_IN, '<', "Input file"},
+    {"out", OPT_OUT, '>', "Output file"},
+    {"encrypt", OPT_ENCRYPT, '-', "Encrypt message"},
+    {"decrypt", OPT_DECRYPT, '-', "Decrypt encrypted message"},
+    {"sign", OPT_SIGN, '-', "Sign message"},
+    {"sign_receipt", OPT_SIGN_RECEIPT, '-', "Generate a signed receipt for the message"},
+    {"resign", OPT_RESIGN, '-', "Resign a signed message"},
+    {"verify", OPT_VERIFY, '-', "Verify signed message"},
+    {"verify_retcode", OPT_VERIFY_RETCODE, '-'},
+    {"verify_receipt", OPT_VERIFY_RECEIPT, '<'},
+    {"cmsout", OPT_CMSOUT, '-', "Output CMS structure"},
+    {"data_out", OPT_DATA_OUT, '-'},
+    {"data_create", OPT_DATA_CREATE, '-'},
+    {"digest_verify", OPT_DIGEST_VERIFY, '-'},
+    {"digest_create", OPT_DIGEST_CREATE, '-'},
+    {"compress", OPT_COMPRESS, '-'},
+    {"uncompress", OPT_UNCOMPRESS, '-'},
+    {"EncryptedData_decrypt", OPT_ED_DECRYPT, '-'},
+    {"EncryptedData_encrypt", OPT_ED_ENCRYPT, '-'},
+    {"debug_decrypt", OPT_DEBUG_DECRYPT, '-'},
+    {"text", OPT_TEXT, '-', "Include or delete text MIME headers"},
+    {"asciicrlf", OPT_ASCIICRLF, '-'},
+    {"nointern", OPT_NOINTERN, '-',
+     "Don't search certificates in message for signer"},
+    {"noverify", OPT_NOVERIFY, '-', "Don't verify signers certificate"},
+    {"nocerts", OPT_NOCERTS, '-',
+     "Don't include signers certificate when signing"},
+    {"noattr", OPT_NOATTR, '-', "Don't include any signed attributes"},
+    {"nodetach", OPT_NODETACH, '-', "Use opaque signing"},
+    {"nosmimecap", OPT_NOSMIMECAP, '-', "Omit the SMIMECapabilities attribute"},
+    {"binary", OPT_BINARY, '-', "Don't translate message to text"},
+    {"keyid", OPT_KEYID, '-', "Use subject key identifier"},
+    {"nosigs", OPT_NOSIGS, '-', "Don't verify message signature"},
+    {"no_content_verify", OPT_NO_CONTENT_VERIFY, '-'},
+    {"no_attr_verify", OPT_NO_ATTR_VERIFY, '-'},
+    {"stream", OPT_INDEF, '-', "Enable CMS streaming"},
+    {"indef", OPT_INDEF, '-', "Same as -stream"},
+    {"noindef", OPT_NOINDEF, '-', "Disable CMS streaming"},
+    {"crlfeol", OPT_CRLFEOL, '-', "Use CRLF as EOL termination instead of CR only" },
+    {"noout", OPT_NOOUT, '-', "For the -cmsout operation do not output the parsed CMS structure"},
+    {"receipt_request_print", OPT_RR_PRINT, '-', "Print CMS Receipt Request" },
+    {"receipt_request_all", OPT_RR_ALL, '-'},
+    {"receipt_request_first", OPT_RR_FIRST, '-'},
+    {"rctform", OPT_RCTFORM, 'F', "Receipt file format"},
+    {"certfile", OPT_CERTFILE, '<', "Other certificates file"},
+    {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"},
+    {"CApath", OPT_CAPATH, '/', "trusted certificates directory"},
+    {"no-CAfile", OPT_NOCAFILE, '-',
+     "Do not load the default certificates file"},
+    {"no-CApath", OPT_NOCAPATH, '-',
+     "Do not load certificates from the default certificates directory"},
+    {"content", OPT_CONTENT, '<',
+     "Supply or override content for detached signature"},
+    {"print", OPT_PRINT, '-', 
+     "For the -cmsout operation print out all fields of the CMS structure"},
+    {"secretkey", OPT_SECRETKEY, 's'},
+    {"secretkeyid", OPT_SECRETKEYID, 's'},
+    {"pwri_password", OPT_PWRI_PASSWORD, 's'},
+    {"econtent_type", OPT_ECONTENT_TYPE, 's'},
+    {"rand", OPT_RAND, 's',
+     "Load the file(s) into the random number generator"},
+    {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
+    {"to", OPT_TO, 's', "To address"},
+    {"from", OPT_FROM, 's', "From address"},
+    {"subject", OPT_SUBJECT, 's', "Subject"},
+    {"signer", OPT_SIGNER, 's', "Signer certificate file"},
+    {"recip", OPT_RECIP, '<', "Recipient cert file for decryption"},
+    {"certsout", OPT_CERTSOUT, '>', "Certificate output file"},
+    {"md", OPT_MD, 's', "Digest algorithm to use when signing or resigning"},
+    {"inkey", OPT_INKEY, 's',
+     "Input private key (if not signer or recipient)"},
+    {"keyform", OPT_KEYFORM, 'f', "Input private key format (PEM or ENGINE)"},
+    {"keyopt", OPT_KEYOPT, 's', "Set public key parameters as n:v pairs"},
+    {"receipt_request_from", OPT_RR_FROM, 's'},
+    {"receipt_request_to", OPT_RR_TO, 's'},
+    {"", OPT_CIPHER, '-', "Any supported cipher"},
+    OPT_V_OPTIONS,
+    {"aes128-wrap", OPT_AES128_WRAP, '-', "Use AES128 to wrap key"},
+    {"aes192-wrap", OPT_AES192_WRAP, '-', "Use AES192 to wrap key"},
+    {"aes256-wrap", OPT_AES256_WRAP, '-', "Use AES256 to wrap key"},
+# ifndef OPENSSL_NO_DES
+    {"des3-wrap", OPT_3DES_WRAP, '-', "Use 3DES-EDE to wrap key"},
+# endif
+# ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
+# endif
+    {NULL}
+};
+
+int cms_main(int argc, char **argv)
+{
+    ASN1_OBJECT *econtent_type = NULL;
+    BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL;
+    CMS_ContentInfo *cms = NULL, *rcms = NULL;
+    CMS_ReceiptRequest *rr = NULL;
+    ENGINE *e = NULL;
+    EVP_PKEY *key = NULL;
+    const EVP_CIPHER *cipher = NULL, *wrap_cipher = NULL;
+    const EVP_MD *sign_md = NULL;
+    STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL;
+    STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL;
+    STACK_OF(X509) *encerts = NULL, *other = NULL;
+    X509 *cert = NULL, *recip = NULL, *signer = NULL;
+    X509_STORE *store = NULL;
+    X509_VERIFY_PARAM *vpm = NULL;
+    char *certfile = NULL, *keyfile = NULL, *contfile = NULL;
+    const char *CAfile = NULL, *CApath = NULL;
+    char *certsoutfile = NULL;
+    int noCAfile = 0, noCApath = 0;
+    char *infile = NULL, *outfile = NULL, *rctfile = NULL, *inrand = NULL;
+    char *passinarg = NULL, *passin = NULL, *signerfile = NULL, *recipfile =
+        NULL;
+    char *to = NULL, *from = NULL, *subject = NULL, *prog;
+    cms_key_param *key_first = NULL, *key_param = NULL;
+    int flags = CMS_DETACHED, noout = 0, print = 0, keyidx = -1, vpmtouched =
+        0;
+    int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
+    int need_rand = 0, operation = 0, ret = 1, rr_print = 0, rr_allorfirst =
+        -1;
+    int verify_retcode = 0, rctformat = FORMAT_SMIME, keyform = FORMAT_PEM;
+    size_t secret_keylen = 0, secret_keyidlen = 0;
+    unsigned char *pwri_pass = NULL, *pwri_tmp = NULL;
+    unsigned char *secret_key = NULL, *secret_keyid = NULL;
+    long ltmp;
+    const char *mime_eol = "\n";
+    OPTION_CHOICE o;
+
+    if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
+        return 1;
+
+    prog = opt_init(argc, argv, cms_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(cms_options);
+            ret = 0;
+            goto end;
+        case OPT_INFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PDS, &informat))
+                goto opthelp;
+            break;
+        case OPT_OUTFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PDS, &outformat))
+                goto opthelp;
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_ENCRYPT:
+            operation = SMIME_ENCRYPT;
+            break;
+        case OPT_DECRYPT:
+            operation = SMIME_DECRYPT;
+            break;
+        case OPT_SIGN:
+            operation = SMIME_SIGN;
+            break;
+        case OPT_SIGN_RECEIPT:
+            operation = SMIME_SIGN_RECEIPT;
+            break;
+        case OPT_RESIGN:
+            operation = SMIME_RESIGN;
+            break;
+        case OPT_VERIFY:
+            operation = SMIME_VERIFY;
+            break;
+        case OPT_VERIFY_RETCODE:
+            verify_retcode = 1;
+            break;
+        case OPT_VERIFY_RECEIPT:
+            operation = SMIME_VERIFY_RECEIPT;
+            rctfile = opt_arg();
+            break;
+        case OPT_CMSOUT:
+            operation = SMIME_CMSOUT;
+            break;
+        case OPT_DATA_OUT:
+            operation = SMIME_DATAOUT;
+            break;
+        case OPT_DATA_CREATE:
+            operation = SMIME_DATA_CREATE;
+            break;
+        case OPT_DIGEST_VERIFY:
+            operation = SMIME_DIGEST_VERIFY;
+            break;
+        case OPT_DIGEST_CREATE:
+            operation = SMIME_DIGEST_CREATE;
+            break;
+        case OPT_COMPRESS:
+            operation = SMIME_COMPRESS;
+            break;
+        case OPT_UNCOMPRESS:
+            operation = SMIME_UNCOMPRESS;
+            break;
+        case OPT_ED_DECRYPT:
+            operation = SMIME_ENCRYPTED_DECRYPT;
+            break;
+        case OPT_ED_ENCRYPT:
+            operation = SMIME_ENCRYPTED_ENCRYPT;
+            break;
+        case OPT_DEBUG_DECRYPT:
+            flags |= CMS_DEBUG_DECRYPT;
+            break;
+        case OPT_TEXT:
+            flags |= CMS_TEXT;
+            break;
+        case OPT_ASCIICRLF:
+            flags |= CMS_ASCIICRLF;
+            break;
+        case OPT_NOINTERN:
+            flags |= CMS_NOINTERN;
+            break;
+        case OPT_NOVERIFY:
+            flags |= CMS_NO_SIGNER_CERT_VERIFY;
+            break;
+        case OPT_NOCERTS:
+            flags |= CMS_NOCERTS;
+            break;
+        case OPT_NOATTR:
+            flags |= CMS_NOATTR;
+            break;
+        case OPT_NODETACH:
+            flags &= ~CMS_DETACHED;
+            break;
+        case OPT_NOSMIMECAP:
+            flags |= CMS_NOSMIMECAP;
+            break;
+        case OPT_BINARY:
+            flags |= CMS_BINARY;
+            break;
+        case OPT_KEYID:
+            flags |= CMS_USE_KEYID;
+            break;
+        case OPT_NOSIGS:
+            flags |= CMS_NOSIGS;
+            break;
+        case OPT_NO_CONTENT_VERIFY:
+            flags |= CMS_NO_CONTENT_VERIFY;
+            break;
+        case OPT_NO_ATTR_VERIFY:
+            flags |= CMS_NO_ATTR_VERIFY;
+            break;
+        case OPT_INDEF:
+            flags |= CMS_STREAM;
+            break;
+        case OPT_NOINDEF:
+            flags &= ~CMS_STREAM;
+            break;
+        case OPT_CRLFEOL:
+            mime_eol = "\r\n";
+            flags |= CMS_CRLFEOL;
+            break;
+        case OPT_NOOUT:
+            noout = 1;
+            break;
+        case OPT_RR_PRINT:
+            rr_print = 1;
+            break;
+        case OPT_RR_ALL:
+            rr_allorfirst = 0;
+            break;
+        case OPT_RR_FIRST:
+            rr_allorfirst = 1;
+            break;
+        case OPT_RCTFORM:
+            if (rctformat == FORMAT_SMIME)
+                rcms = SMIME_read_CMS(rctin, NULL);
+            else if (rctformat == FORMAT_PEM)
+                rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL);
+            else if (rctformat == FORMAT_ASN1)
+                if (!opt_format(opt_arg(),
+                                OPT_FMT_PEMDER | OPT_FMT_SMIME, &rctformat))
+                    goto opthelp;
+            break;
+        case OPT_CERTFILE:
+            certfile = opt_arg();
+            break;
+        case OPT_CAFILE:
+            CAfile = opt_arg();
+            break;
+        case OPT_CAPATH:
+            CApath = opt_arg();
+            break;
+        case OPT_NOCAFILE:
+            noCAfile = 1;
+            break;
+        case OPT_NOCAPATH:
+            noCApath = 1;
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_CONTENT:
+            contfile = opt_arg();
+            break;
+        case OPT_RR_FROM:
+            if (rr_from == NULL
+                && (rr_from = sk_OPENSSL_STRING_new_null()) == NULL)
+                goto end;
+            sk_OPENSSL_STRING_push(rr_from, opt_arg());
+            break;
+        case OPT_RR_TO:
+            if (rr_to == NULL
+                && (rr_to = sk_OPENSSL_STRING_new_null()) == NULL)
+                goto end;
+            sk_OPENSSL_STRING_push(rr_to, opt_arg());
+            break;
+        case OPT_PRINT:
+            noout = print = 1;
+            break;
+        case OPT_SECRETKEY:
+            if (secret_key != NULL) {
+                BIO_printf(bio_err, "Invalid key (supplied twice) %s\n",
+                           opt_arg());
+                goto opthelp;
+            }
+            secret_key = OPENSSL_hexstr2buf(opt_arg(), &ltmp);
+            if (secret_key == NULL) {
+                BIO_printf(bio_err, "Invalid key %s\n", opt_arg());
+                goto end;
+            }
+            secret_keylen = (size_t)ltmp;
+            break;
+        case OPT_SECRETKEYID:
+            if (secret_keyid != NULL) {
+                BIO_printf(bio_err, "Invalid id (supplied twice) %s\n",
+                           opt_arg());
+                goto opthelp;
+            }
+            secret_keyid = OPENSSL_hexstr2buf(opt_arg(), &ltmp);
+            if (secret_keyid == NULL) {
+                BIO_printf(bio_err, "Invalid id %s\n", opt_arg());
+                goto opthelp;
+            }
+            secret_keyidlen = (size_t)ltmp;
+            break;
+        case OPT_PWRI_PASSWORD:
+            pwri_pass = (unsigned char *)opt_arg();
+            break;
+        case OPT_ECONTENT_TYPE:
+            if (econtent_type != NULL) {
+                BIO_printf(bio_err, "Invalid OID (supplied twice) %s\n",
+                           opt_arg());
+                goto opthelp;
+            }
+            econtent_type = OBJ_txt2obj(opt_arg(), 0);
+            if (econtent_type == NULL) {
+                BIO_printf(bio_err, "Invalid OID %s\n", opt_arg());
+                goto opthelp;
+            }
+            break;
+        case OPT_RAND:
+            inrand = opt_arg();
+            need_rand = 1;
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        case OPT_PASSIN:
+            passinarg = opt_arg();
+            break;
+        case OPT_TO:
+            to = opt_arg();
+            break;
+        case OPT_FROM:
+            from = opt_arg();
+            break;
+        case OPT_SUBJECT:
+            subject = opt_arg();
+            break;
+        case OPT_CERTSOUT:
+            certsoutfile = opt_arg();
+            break;
+        case OPT_MD:
+            if (!opt_md(opt_arg(), &sign_md))
+                goto end;
+            break;
+        case OPT_SIGNER:
+            /* If previous -signer argument add signer to list */
+            if (signerfile) {
+                if (sksigners == NULL
+                    && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
+                    goto end;
+                sk_OPENSSL_STRING_push(sksigners, signerfile);
+                if (keyfile == NULL)
+                    keyfile = signerfile;
+                if (skkeys == NULL
+                    && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
+                    goto end;
+                sk_OPENSSL_STRING_push(skkeys, keyfile);
+                keyfile = NULL;
+            }
+            signerfile = opt_arg();
+            break;
+        case OPT_INKEY:
+            /* If previous -inkey argument add signer to list */
+            if (keyfile) {
+                if (signerfile == NULL) {
+                    BIO_puts(bio_err, "Illegal -inkey without -signer\n");
+                    goto end;
+                }
+                if (sksigners == NULL
+                    && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
+                    goto end;
+                sk_OPENSSL_STRING_push(sksigners, signerfile);
+                signerfile = NULL;
+                if (skkeys == NULL
+                    && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
+                    goto end;
+                sk_OPENSSL_STRING_push(skkeys, keyfile);
+            }
+            keyfile = opt_arg();
+            break;
+        case OPT_KEYFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform))
+                goto opthelp;
+            break;
+        case OPT_RECIP:
+            if (operation == SMIME_ENCRYPT) {
+                if (encerts == NULL && (encerts = sk_X509_new_null()) == NULL)
+                    goto end;
+                cert = load_cert(opt_arg(), FORMAT_PEM,
+                                 "recipient certificate file");
+                if (cert == NULL)
+                    goto end;
+                sk_X509_push(encerts, cert);
+                cert = NULL;
+            } else
+                recipfile = opt_arg();
+            break;
+        case OPT_CIPHER:
+            if (!opt_cipher(opt_unknown(), &cipher))
+                goto end;
+            break;
+        case OPT_KEYOPT:
+            keyidx = -1;
+            if (operation == SMIME_ENCRYPT) {
+                if (encerts)
+                    keyidx += sk_X509_num(encerts);
+            } else {
+                if (keyfile || signerfile)
+                    keyidx++;
+                if (skkeys)
+                    keyidx += sk_OPENSSL_STRING_num(skkeys);
+            }
+            if (keyidx < 0) {
+                BIO_printf(bio_err, "No key specified\n");
+                goto opthelp;
+            }
+            if (key_param == NULL || key_param->idx != keyidx) {
+                cms_key_param *nparam;
+                nparam = app_malloc(sizeof(*nparam), "key param buffer");
+                nparam->idx = keyidx;
+                if ((nparam->param = sk_OPENSSL_STRING_new_null()) == NULL)
+                    goto end;
+                nparam->next = NULL;
+                if (key_first == NULL)
+                    key_first = nparam;
+                else
+                    key_param->next = nparam;
+                key_param = nparam;
+            }
+            sk_OPENSSL_STRING_push(key_param->param, opt_arg());
+            break;
+        case OPT_V_CASES:
+            if (!opt_verify(o, vpm))
+                goto end;
+            vpmtouched++;
+            break;
+        case OPT_3DES_WRAP:
+# ifndef OPENSSL_NO_DES
+            wrap_cipher = EVP_des_ede3_wrap();
+# endif
+            break;
+        case OPT_AES128_WRAP:
+            wrap_cipher = EVP_aes_128_wrap();
+            break;
+        case OPT_AES192_WRAP:
+            wrap_cipher = EVP_aes_192_wrap();
+            break;
+        case OPT_AES256_WRAP:
+            wrap_cipher = EVP_aes_256_wrap();
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    argv = opt_rest();
+
+    if (((rr_allorfirst != -1) || rr_from) && !rr_to) {
+        BIO_puts(bio_err, "No Signed Receipts Recipients\n");
+        goto opthelp;
+    }
+
+    if (!(operation & SMIME_SIGNERS) && (rr_to || rr_from)) {
+        BIO_puts(bio_err, "Signed receipts only allowed with -sign\n");
+        goto opthelp;
+    }
+    if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) {
+        BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
+        goto opthelp;
+    }
+
+    if (operation & SMIME_SIGNERS) {
+        if (keyfile && !signerfile) {
+            BIO_puts(bio_err, "Illegal -inkey without -signer\n");
+            goto opthelp;
+        }
+        /* Check to see if any final signer needs to be appended */
+        if (signerfile) {
+            if (!sksigners
+                && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
+                goto end;
+            sk_OPENSSL_STRING_push(sksigners, signerfile);
+            if (!skkeys && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
+                goto end;
+            if (!keyfile)
+                keyfile = signerfile;
+            sk_OPENSSL_STRING_push(skkeys, keyfile);
+        }
+        if (!sksigners) {
+            BIO_printf(bio_err, "No signer certificate specified\n");
+            goto opthelp;
+        }
+        signerfile = NULL;
+        keyfile = NULL;
+        need_rand = 1;
+    }
+
+    else if (operation == SMIME_DECRYPT) {
+        if (!recipfile && !keyfile && !secret_key && !pwri_pass) {
+            BIO_printf(bio_err,
+                       "No recipient certificate or key specified\n");
+            goto opthelp;
+        }
+    } else if (operation == SMIME_ENCRYPT) {
+        if (*argv == NULL && !secret_key && !pwri_pass && !encerts) {
+            BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
+            goto opthelp;
+        }
+        need_rand = 1;
+    } else if (!operation)
+        goto opthelp;
+
+    if (!app_passwd(passinarg, NULL, &passin, NULL)) {
+        BIO_printf(bio_err, "Error getting password\n");
+        goto end;
+    }
+
+    if (need_rand) {
+        app_RAND_load_file(NULL, (inrand != NULL));
+        if (inrand != NULL)
+            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
+                       app_RAND_load_files(inrand));
+    }
+
+    ret = 2;
+
+    if (!(operation & SMIME_SIGNERS))
+        flags &= ~CMS_DETACHED;
+
+    if (!(operation & SMIME_OP)) {
+        if (flags & CMS_BINARY)
+            outformat = FORMAT_BINARY;
+    }
+
+    if (!(operation & SMIME_IP)) {
+        if (flags & CMS_BINARY)
+            informat = FORMAT_BINARY;
+    }
+
+    if (operation == SMIME_ENCRYPT) {
+        if (!cipher) {
+# ifndef OPENSSL_NO_DES
+            cipher = EVP_des_ede3_cbc();
+# else
+            BIO_printf(bio_err, "No cipher selected\n");
+            goto end;
+# endif
+        }
+
+        if (secret_key && !secret_keyid) {
+            BIO_printf(bio_err, "No secret key id\n");
+            goto end;
+        }
+
+        if (*argv && !encerts)
+            if ((encerts = sk_X509_new_null()) == NULL)
+                goto end;
+        while (*argv) {
+            if ((cert = load_cert(*argv, FORMAT_PEM,
+                                  "recipient certificate file")) == NULL)
+                goto end;
+            sk_X509_push(encerts, cert);
+            cert = NULL;
+            argv++;
+        }
+    }
+
+    if (certfile) {
+        if (!load_certs(certfile, &other, FORMAT_PEM, NULL,
+                        "certificate file")) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    if (recipfile && (operation == SMIME_DECRYPT)) {
+        if ((recip = load_cert(recipfile, FORMAT_PEM,
+                               "recipient certificate file")) == NULL) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    if (operation == SMIME_SIGN_RECEIPT) {
+        if ((signer = load_cert(signerfile, FORMAT_PEM,
+                                "receipt signer certificate file")) == NULL) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    if (operation == SMIME_DECRYPT) {
+        if (!keyfile)
+            keyfile = recipfile;
+    } else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT)) {
+        if (!keyfile)
+            keyfile = signerfile;
+    } else
+        keyfile = NULL;
+
+    if (keyfile) {
+        key = load_key(keyfile, keyform, 0, passin, e, "signing key file");
+        if (!key)
+            goto end;
+    }
+
+    in = bio_open_default(infile, 'r', informat);
+    if (in == NULL)
+        goto end;
+
+    if (operation & SMIME_IP) {
+        if (informat == FORMAT_SMIME)
+            cms = SMIME_read_CMS(in, &indata);
+        else if (informat == FORMAT_PEM)
+            cms = PEM_read_bio_CMS(in, NULL, NULL, NULL);
+        else if (informat == FORMAT_ASN1)
+            cms = d2i_CMS_bio(in, NULL);
+        else {
+            BIO_printf(bio_err, "Bad input format for CMS file\n");
+            goto end;
+        }
+
+        if (!cms) {
+            BIO_printf(bio_err, "Error reading S/MIME message\n");
+            goto end;
+        }
+        if (contfile) {
+            BIO_free(indata);
+            if ((indata = BIO_new_file(contfile, "rb")) == NULL) {
+                BIO_printf(bio_err, "Can't read content file %s\n", contfile);
+                goto end;
+            }
+        }
+        if (certsoutfile) {
+            STACK_OF(X509) *allcerts;
+            allcerts = CMS_get1_certs(cms);
+            if (!save_certs(certsoutfile, allcerts)) {
+                BIO_printf(bio_err,
+                           "Error writing certs to %s\n", certsoutfile);
+                ret = 5;
+                goto end;
+            }
+            sk_X509_pop_free(allcerts, X509_free);
+        }
+    }
+
+    if (rctfile) {
+        char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r";
+        if ((rctin = BIO_new_file(rctfile, rctmode)) == NULL) {
+            BIO_printf(bio_err, "Can't open receipt file %s\n", rctfile);
+            goto end;
+        }
+
+        if (rctformat == FORMAT_SMIME)
+            rcms = SMIME_read_CMS(rctin, NULL);
+        else if (rctformat == FORMAT_PEM)
+            rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL);
+        else if (rctformat == FORMAT_ASN1)
+            rcms = d2i_CMS_bio(rctin, NULL);
+        else {
+            BIO_printf(bio_err, "Bad input format for receipt\n");
+            goto end;
+        }
+
+        if (!rcms) {
+            BIO_printf(bio_err, "Error reading receipt\n");
+            goto end;
+        }
+    }
+
+    out = bio_open_default(outfile, 'w', outformat);
+    if (out == NULL)
+        goto end;
+
+    if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT)) {
+        if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL)
+            goto end;
+        X509_STORE_set_verify_cb(store, cms_cb);
+        if (vpmtouched)
+            X509_STORE_set1_param(store, vpm);
+    }
+
+    ret = 3;
+
+    if (operation == SMIME_DATA_CREATE) {
+        cms = CMS_data_create(in, flags);
+    } else if (operation == SMIME_DIGEST_CREATE) {
+        cms = CMS_digest_create(in, sign_md, flags);
+    } else if (operation == SMIME_COMPRESS) {
+        cms = CMS_compress(in, -1, flags);
+    } else if (operation == SMIME_ENCRYPT) {
+        int i;
+        flags |= CMS_PARTIAL;
+        cms = CMS_encrypt(NULL, in, cipher, flags);
+        if (!cms)
+            goto end;
+        for (i = 0; i < sk_X509_num(encerts); i++) {
+            CMS_RecipientInfo *ri;
+            cms_key_param *kparam;
+            int tflags = flags;
+            X509 *x = sk_X509_value(encerts, i);
+            for (kparam = key_first; kparam; kparam = kparam->next) {
+                if (kparam->idx == i) {
+                    tflags |= CMS_KEY_PARAM;
+                    break;
+                }
+            }
+            ri = CMS_add1_recipient_cert(cms, x, tflags);
+            if (!ri)
+                goto end;
+            if (kparam) {
+                EVP_PKEY_CTX *pctx;
+                pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+                if (!cms_set_pkey_param(pctx, kparam->param))
+                    goto end;
+            }
+            if (CMS_RecipientInfo_type(ri) == CMS_RECIPINFO_AGREE
+                && wrap_cipher) {
+                EVP_CIPHER_CTX *wctx;
+                wctx = CMS_RecipientInfo_kari_get0_ctx(ri);
+                EVP_EncryptInit_ex(wctx, wrap_cipher, NULL, NULL, NULL);
+            }
+        }
+
+        if (secret_key) {
+            if (!CMS_add0_recipient_key(cms, NID_undef,
+                                        secret_key, secret_keylen,
+                                        secret_keyid, secret_keyidlen,
+                                        NULL, NULL, NULL))
+                goto end;
+            /* NULL these because call absorbs them */
+            secret_key = NULL;
+            secret_keyid = NULL;
+        }
+        if (pwri_pass) {
+            pwri_tmp = (unsigned char *)OPENSSL_strdup((char *)pwri_pass);
+            if (!pwri_tmp)
+                goto end;
+            if (!CMS_add0_recipient_password(cms,
+                                             -1, NID_undef, NID_undef,
+                                             pwri_tmp, -1, NULL))
+                goto end;
+            pwri_tmp = NULL;
+        }
+        if (!(flags & CMS_STREAM)) {
+            if (!CMS_final(cms, in, NULL, flags))
+                goto end;
+        }
+    } else if (operation == SMIME_ENCRYPTED_ENCRYPT) {
+        cms = CMS_EncryptedData_encrypt(in, cipher,
+                                        secret_key, secret_keylen, flags);
+
+    } else if (operation == SMIME_SIGN_RECEIPT) {
+        CMS_ContentInfo *srcms = NULL;
+        STACK_OF(CMS_SignerInfo) *sis;
+        CMS_SignerInfo *si;
+        sis = CMS_get0_SignerInfos(cms);
+        if (!sis)
+            goto end;
+        si = sk_CMS_SignerInfo_value(sis, 0);
+        srcms = CMS_sign_receipt(si, signer, key, other, flags);
+        if (!srcms)
+            goto end;
+        CMS_ContentInfo_free(cms);
+        cms = srcms;
+    } else if (operation & SMIME_SIGNERS) {
+        int i;
+        /*
+         * If detached data content we enable streaming if S/MIME output
+         * format.
+         */
+        if (operation == SMIME_SIGN) {
+
+            if (flags & CMS_DETACHED) {
+                if (outformat == FORMAT_SMIME)
+                    flags |= CMS_STREAM;
+            }
+            flags |= CMS_PARTIAL;
+            cms = CMS_sign(NULL, NULL, other, in, flags);
+            if (!cms)
+                goto end;
+            if (econtent_type)
+                CMS_set1_eContentType(cms, econtent_type);
+
+            if (rr_to) {
+                rr = make_receipt_request(rr_to, rr_allorfirst, rr_from);
+                if (!rr) {
+                    BIO_puts(bio_err,
+                             "Signed Receipt Request Creation Error\n");
+                    goto end;
+                }
+            }
+        } else
+            flags |= CMS_REUSE_DIGEST;
+        for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) {
+            CMS_SignerInfo *si;
+            cms_key_param *kparam;
+            int tflags = flags;
+            signerfile = sk_OPENSSL_STRING_value(sksigners, i);
+            keyfile = sk_OPENSSL_STRING_value(skkeys, i);
+
+            signer = load_cert(signerfile, FORMAT_PEM, "signer certificate");
+            if (!signer)
+                goto end;
+            key = load_key(keyfile, keyform, 0, passin, e, "signing key file");
+            if (!key)
+                goto end;
+            for (kparam = key_first; kparam; kparam = kparam->next) {
+                if (kparam->idx == i) {
+                    tflags |= CMS_KEY_PARAM;
+                    break;
+                }
+            }
+            si = CMS_add1_signer(cms, signer, key, sign_md, tflags);
+            if (!si)
+                goto end;
+            if (kparam) {
+                EVP_PKEY_CTX *pctx;
+                pctx = CMS_SignerInfo_get0_pkey_ctx(si);
+                if (!cms_set_pkey_param(pctx, kparam->param))
+                    goto end;
+            }
+            if (rr && !CMS_add1_ReceiptRequest(si, rr))
+                goto end;
+            X509_free(signer);
+            signer = NULL;
+            EVP_PKEY_free(key);
+            key = NULL;
+        }
+        /* If not streaming or resigning finalize structure */
+        if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM)) {
+            if (!CMS_final(cms, in, NULL, flags))
+                goto end;
+        }
+    }
+
+    if (!cms) {
+        BIO_printf(bio_err, "Error creating CMS structure\n");
+        goto end;
+    }
+
+    ret = 4;
+    if (operation == SMIME_DECRYPT) {
+        if (flags & CMS_DEBUG_DECRYPT)
+            CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags);
+
+        if (secret_key) {
+            if (!CMS_decrypt_set1_key(cms,
+                                      secret_key, secret_keylen,
+                                      secret_keyid, secret_keyidlen)) {
+                BIO_puts(bio_err, "Error decrypting CMS using secret key\n");
+                goto end;
+            }
+        }
+
+        if (key) {
+            if (!CMS_decrypt_set1_pkey(cms, key, recip)) {
+                BIO_puts(bio_err, "Error decrypting CMS using private key\n");
+                goto end;
+            }
+        }
+
+        if (pwri_pass) {
+            if (!CMS_decrypt_set1_password(cms, pwri_pass, -1)) {
+                BIO_puts(bio_err, "Error decrypting CMS using password\n");
+                goto end;
+            }
+        }
+
+        if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags)) {
+            BIO_printf(bio_err, "Error decrypting CMS structure\n");
+            goto end;
+        }
+    } else if (operation == SMIME_DATAOUT) {
+        if (!CMS_data(cms, out, flags))
+            goto end;
+    } else if (operation == SMIME_UNCOMPRESS) {
+        if (!CMS_uncompress(cms, indata, out, flags))
+            goto end;
+    } else if (operation == SMIME_DIGEST_VERIFY) {
+        if (CMS_digest_verify(cms, indata, out, flags) > 0)
+            BIO_printf(bio_err, "Verification successful\n");
+        else {
+            BIO_printf(bio_err, "Verification failure\n");
+            goto end;
+        }
+    } else if (operation == SMIME_ENCRYPTED_DECRYPT) {
+        if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen,
+                                       indata, out, flags))
+            goto end;
+    } else if (operation == SMIME_VERIFY) {
+        if (CMS_verify(cms, other, store, indata, out, flags) > 0)
+            BIO_printf(bio_err, "Verification successful\n");
+        else {
+            BIO_printf(bio_err, "Verification failure\n");
+            if (verify_retcode)
+                ret = verify_err + 32;
+            goto end;
+        }
+        if (signerfile) {
+            STACK_OF(X509) *signers;
+            signers = CMS_get0_signers(cms);
+            if (!save_certs(signerfile, signers)) {
+                BIO_printf(bio_err,
+                           "Error writing signers to %s\n", signerfile);
+                ret = 5;
+                goto end;
+            }
+            sk_X509_free(signers);
+        }
+        if (rr_print)
+            receipt_request_print(cms);
+
+    } else if (operation == SMIME_VERIFY_RECEIPT) {
+        if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0)
+            BIO_printf(bio_err, "Verification successful\n");
+        else {
+            BIO_printf(bio_err, "Verification failure\n");
+            goto end;
+        }
+    } else {
+        if (noout) {
+            if (print)
+                CMS_ContentInfo_print_ctx(out, cms, 0, NULL);
+        } else if (outformat == FORMAT_SMIME) {
+            if (to)
+                BIO_printf(out, "To: %s%s", to, mime_eol);
+            if (from)
+                BIO_printf(out, "From: %s%s", from, mime_eol);
+            if (subject)
+                BIO_printf(out, "Subject: %s%s", subject, mime_eol);
+            if (operation == SMIME_RESIGN)
+                ret = SMIME_write_CMS(out, cms, indata, flags);
+            else
+                ret = SMIME_write_CMS(out, cms, in, flags);
+        } else if (outformat == FORMAT_PEM)
+            ret = PEM_write_bio_CMS_stream(out, cms, in, flags);
+        else if (outformat == FORMAT_ASN1)
+            ret = i2d_CMS_bio_stream(out, cms, in, flags);
+        else {
+            BIO_printf(bio_err, "Bad output format for CMS file\n");
+            goto end;
+        }
+        if (ret <= 0) {
+            ret = 6;
+            goto end;
+        }
+    }
+    ret = 0;
+ end:
+    if (ret)
+        ERR_print_errors(bio_err);
+    if (need_rand)
+        app_RAND_write_file(NULL);
+    sk_X509_pop_free(encerts, X509_free);
+    sk_X509_pop_free(other, X509_free);
+    X509_VERIFY_PARAM_free(vpm);
+    sk_OPENSSL_STRING_free(sksigners);
+    sk_OPENSSL_STRING_free(skkeys);
+    OPENSSL_free(secret_key);
+    OPENSSL_free(secret_keyid);
+    OPENSSL_free(pwri_tmp);
+    ASN1_OBJECT_free(econtent_type);
+    CMS_ReceiptRequest_free(rr);
+    sk_OPENSSL_STRING_free(rr_to);
+    sk_OPENSSL_STRING_free(rr_from);
+    for (key_param = key_first; key_param;) {
+        cms_key_param *tparam;
+        sk_OPENSSL_STRING_free(key_param->param);
+        tparam = key_param->next;
+        OPENSSL_free(key_param);
+        key_param = tparam;
+    }
+    X509_STORE_free(store);
+    X509_free(cert);
+    X509_free(recip);
+    X509_free(signer);
+    EVP_PKEY_free(key);
+    CMS_ContentInfo_free(cms);
+    CMS_ContentInfo_free(rcms);
+    release_engine(e);
+    BIO_free(rctin);
+    BIO_free(in);
+    BIO_free(indata);
+    BIO_free_all(out);
+    OPENSSL_free(passin);
+    return (ret);
+}
+
+static int save_certs(char *signerfile, STACK_OF(X509) *signers)
+{
+    int i;
+    BIO *tmp;
+    if (!signerfile)
+        return 1;
+    tmp = BIO_new_file(signerfile, "w");
+    if (!tmp)
+        return 0;
+    for (i = 0; i < sk_X509_num(signers); i++)
+        PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
+    BIO_free(tmp);
+    return 1;
+}
+
+/* Minimal callback just to output policy info (if any) */
+
+static int cms_cb(int ok, X509_STORE_CTX *ctx)
+{
+    int error;
+
+    error = X509_STORE_CTX_get_error(ctx);
+
+    verify_err = error;
+
+    if ((error != X509_V_ERR_NO_EXPLICIT_POLICY)
+        && ((error != X509_V_OK) || (ok != 2)))
+        return ok;
+
+    policies_print(ctx);
+
+    return ok;
+
+}
+
+static void gnames_stack_print(STACK_OF(GENERAL_NAMES) *gns)
+{
+    STACK_OF(GENERAL_NAME) *gens;
+    GENERAL_NAME *gen;
+    int i, j;
+
+    for (i = 0; i < sk_GENERAL_NAMES_num(gns); i++) {
+        gens = sk_GENERAL_NAMES_value(gns, i);
+        for (j = 0; j < sk_GENERAL_NAME_num(gens); j++) {
+            gen = sk_GENERAL_NAME_value(gens, j);
+            BIO_puts(bio_err, "    ");
+            GENERAL_NAME_print(bio_err, gen);
+            BIO_puts(bio_err, "\n");
+        }
+    }
+    return;
+}
+
+static void receipt_request_print(CMS_ContentInfo *cms)
+{
+    STACK_OF(CMS_SignerInfo) *sis;
+    CMS_SignerInfo *si;
+    CMS_ReceiptRequest *rr;
+    int allorfirst;
+    STACK_OF(GENERAL_NAMES) *rto, *rlist;
+    ASN1_STRING *scid;
+    int i, rv;
+    sis = CMS_get0_SignerInfos(cms);
+    for (i = 0; i < sk_CMS_SignerInfo_num(sis); i++) {
+        si = sk_CMS_SignerInfo_value(sis, i);
+        rv = CMS_get1_ReceiptRequest(si, &rr);
+        BIO_printf(bio_err, "Signer %d:\n", i + 1);
+        if (rv == 0)
+            BIO_puts(bio_err, "  No Receipt Request\n");
+        else if (rv < 0) {
+            BIO_puts(bio_err, "  Receipt Request Parse Error\n");
+            ERR_print_errors(bio_err);
+        } else {
+            const char *id;
+            int idlen;
+            CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst,
+                                           &rlist, &rto);
+            BIO_puts(bio_err, "  Signed Content ID:\n");
+            idlen = ASN1_STRING_length(scid);
+            id = (const char *)ASN1_STRING_get0_data(scid);
+            BIO_dump_indent(bio_err, id, idlen, 4);
+            BIO_puts(bio_err, "  Receipts From");
+            if (rlist) {
+                BIO_puts(bio_err, " List:\n");
+                gnames_stack_print(rlist);
+            } else if (allorfirst == 1)
+                BIO_puts(bio_err, ": First Tier\n");
+            else if (allorfirst == 0)
+                BIO_puts(bio_err, ": All\n");
+            else
+                BIO_printf(bio_err, " Unknown (%d)\n", allorfirst);
+            BIO_puts(bio_err, "  Receipts To:\n");
+            gnames_stack_print(rto);
+        }
+        CMS_ReceiptRequest_free(rr);
+    }
+}
+
+static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK_OF(OPENSSL_STRING) *ns)
+{
+    int i;
+    STACK_OF(GENERAL_NAMES) *ret;
+    GENERAL_NAMES *gens = NULL;
+    GENERAL_NAME *gen = NULL;
+    ret = sk_GENERAL_NAMES_new_null();
+    if (!ret)
+        goto err;
+    for (i = 0; i < sk_OPENSSL_STRING_num(ns); i++) {
+        char *str = sk_OPENSSL_STRING_value(ns, i);
+        gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0);
+        if (!gen)
+            goto err;
+        gens = GENERAL_NAMES_new();
+        if (gens == NULL)
+            goto err;
+        if (!sk_GENERAL_NAME_push(gens, gen))
+            goto err;
+        gen = NULL;
+        if (!sk_GENERAL_NAMES_push(ret, gens))
+            goto err;
+        gens = NULL;
+    }
+
+    return ret;
+
+ err:
+    sk_GENERAL_NAMES_pop_free(ret, GENERAL_NAMES_free);
+    GENERAL_NAMES_free(gens);
+    GENERAL_NAME_free(gen);
+    return NULL;
+}
+
+static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING)
+                                                *rr_to, int rr_allorfirst, STACK_OF(OPENSSL_STRING)
+                                                *rr_from)
+{
+    STACK_OF(GENERAL_NAMES) *rct_to = NULL, *rct_from = NULL;
+    CMS_ReceiptRequest *rr;
+    rct_to = make_names_stack(rr_to);
+    if (!rct_to)
+        goto err;
+    if (rr_from) {
+        rct_from = make_names_stack(rr_from);
+        if (!rct_from)
+            goto err;
+    } else
+        rct_from = NULL;
+    rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from,
+                                    rct_to);
+    return rr;
+ err:
+    sk_GENERAL_NAMES_pop_free(rct_to, GENERAL_NAMES_free);
+    return NULL;
+}
+
+static int cms_set_pkey_param(EVP_PKEY_CTX *pctx,
+                              STACK_OF(OPENSSL_STRING) *param)
+{
+    char *keyopt;
+    int i;
+    if (sk_OPENSSL_STRING_num(param) <= 0)
+        return 1;
+    for (i = 0; i < sk_OPENSSL_STRING_num(param); i++) {
+        keyopt = sk_OPENSSL_STRING_value(param, i);
+        if (pkey_ctrl_string(pctx, keyopt) <= 0) {
+            BIO_printf(bio_err, "parameter error \"%s\"\n", keyopt);
+            ERR_print_errors(bio_err);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/crl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/crl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/crl.c	(revision 331)
@@ -0,0 +1,347 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/pem.h>
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_INFORM, OPT_IN, OPT_OUTFORM, OPT_OUT, OPT_KEYFORM, OPT_KEY,
+    OPT_ISSUER, OPT_LASTUPDATE, OPT_NEXTUPDATE, OPT_FINGERPRINT,
+    OPT_CRLNUMBER, OPT_BADSIG, OPT_GENDELTA, OPT_CAPATH, OPT_CAFILE,
+    OPT_NOCAPATH, OPT_NOCAFILE, OPT_VERIFY, OPT_TEXT, OPT_HASH, OPT_HASH_OLD,
+    OPT_NOOUT, OPT_NAMEOPT, OPT_MD
+} OPTION_CHOICE;
+
+OPTIONS crl_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"inform", OPT_INFORM, 'F', "Input format; default PEM"},
+    {"in", OPT_IN, '<', "Input file - default stdin"},
+    {"outform", OPT_OUTFORM, 'F', "Output format - default PEM"},
+    {"out", OPT_OUT, '>', "output file - default stdout"},
+    {"keyform", OPT_KEYFORM, 'F', "Private key file format (PEM or ENGINE)"},
+    {"key", OPT_KEY, '<', "CRL signing Private key to use"},
+    {"issuer", OPT_ISSUER, '-', "Print issuer DN"},
+    {"lastupdate", OPT_LASTUPDATE, '-', "Set lastUpdate field"},
+    {"nextupdate", OPT_NEXTUPDATE, '-', "Set nextUpdate field"},
+    {"noout", OPT_NOOUT, '-', "No CRL output"},
+    {"fingerprint", OPT_FINGERPRINT, '-', "Print the crl fingerprint"},
+    {"crlnumber", OPT_CRLNUMBER, '-', "Print CRL number"},
+    {"badsig", OPT_BADSIG, '-', "Corrupt last byte of loaded CRL signature (for test)" },
+    {"gendelta", OPT_GENDELTA, '<', "Other CRL to compare/diff to the Input one"},
+    {"CApath", OPT_CAPATH, '/', "Verify CRL using certificates in dir"},
+    {"CAfile", OPT_CAFILE, '<', "Verify CRL using certificates in file name"},
+    {"no-CAfile", OPT_NOCAFILE, '-',
+     "Do not load the default certificates file"},
+    {"no-CApath", OPT_NOCAPATH, '-',
+     "Do not load certificates from the default certificates directory"},
+    {"verify", OPT_VERIFY, '-', "Verify CRL signature"},
+    {"text", OPT_TEXT, '-', "Print out a text format version"},
+    {"hash", OPT_HASH, '-', "Print hash value"},
+    {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"},
+    {"", OPT_MD, '-', "Any supported digest"},
+#ifndef OPENSSL_NO_MD5
+    {"hash_old", OPT_HASH_OLD, '-', "Print old-style (MD5) hash value"},
+#endif
+    {NULL}
+};
+
+int crl_main(int argc, char **argv)
+{
+    X509_CRL *x = NULL;
+    BIO *out = NULL;
+    X509_STORE *store = NULL;
+    X509_STORE_CTX *ctx = NULL;
+    X509_LOOKUP *lookup = NULL;
+    X509_OBJECT *xobj = NULL;
+    EVP_PKEY *pkey;
+    const EVP_MD *digest = EVP_sha1();
+    unsigned long nmflag = 0;
+    char nmflag_set = 0;
+    char *infile = NULL, *outfile = NULL, *crldiff = NULL, *keyfile = NULL;
+    const char *CAfile = NULL, *CApath = NULL, *prog;
+    OPTION_CHOICE o;
+    int hash = 0, issuer = 0, lastupdate = 0, nextupdate = 0, noout = 0;
+    int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM;
+    int ret = 1, num = 0, badsig = 0, fingerprint = 0, crlnumber = 0;
+    int text = 0, do_ver = 0, noCAfile = 0, noCApath = 0;
+    int i;
+#ifndef OPENSSL_NO_MD5
+    int hash_old = 0;
+#endif
+
+    prog = opt_init(argc, argv, crl_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(crl_options);
+            ret = 0;
+            goto end;
+        case OPT_INFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
+                goto opthelp;
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUTFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
+                goto opthelp;
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_KEYFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat))
+                goto opthelp;
+            break;
+        case OPT_KEY:
+            keyfile = opt_arg();
+            break;
+        case OPT_GENDELTA:
+            crldiff = opt_arg();
+            break;
+        case OPT_CAPATH:
+            CApath = opt_arg();
+            do_ver = 1;
+            break;
+        case OPT_CAFILE:
+            CAfile = opt_arg();
+            do_ver = 1;
+            break;
+        case OPT_NOCAPATH:
+            noCApath =  1;
+            break;
+        case OPT_NOCAFILE:
+            noCAfile =  1;
+            break;
+        case OPT_HASH_OLD:
+#ifndef OPENSSL_NO_MD5
+            hash_old = ++num;
+#endif
+            break;
+        case OPT_VERIFY:
+            do_ver = 1;
+            break;
+        case OPT_TEXT:
+            text = 1;
+            break;
+        case OPT_HASH:
+            hash = ++num;
+            break;
+        case OPT_ISSUER:
+            issuer = ++num;
+            break;
+        case OPT_LASTUPDATE:
+            lastupdate = ++num;
+            break;
+        case OPT_NEXTUPDATE:
+            nextupdate = ++num;
+            break;
+        case OPT_NOOUT:
+            noout = ++num;
+            break;
+        case OPT_FINGERPRINT:
+            fingerprint = ++num;
+            break;
+        case OPT_CRLNUMBER:
+            crlnumber = ++num;
+            break;
+        case OPT_BADSIG:
+            badsig = 1;
+            break;
+        case OPT_NAMEOPT:
+            nmflag_set = 1;
+            if (!set_name_ex(&nmflag, opt_arg()))
+                goto opthelp;
+            break;
+        case OPT_MD:
+            if (!opt_md(opt_unknown(), &digest))
+                goto opthelp;
+        }
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    if (!nmflag_set)
+        nmflag = XN_FLAG_ONELINE;
+
+    x = load_crl(infile, informat);
+    if (x == NULL)
+        goto end;
+
+    if (do_ver) {
+        if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL)
+            goto end;
+        lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
+        if (lookup == NULL)
+            goto end;
+        ctx = X509_STORE_CTX_new();
+        if (ctx == NULL || !X509_STORE_CTX_init(ctx, store, NULL, NULL)) {
+            BIO_printf(bio_err, "Error initialising X509 store\n");
+            goto end;
+        }
+
+        xobj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509,
+                                                 X509_CRL_get_issuer(x));
+        if (xobj == NULL) {
+            BIO_printf(bio_err, "Error getting CRL issuer certificate\n");
+            goto end;
+        }
+        pkey = X509_get_pubkey(X509_OBJECT_get0_X509(xobj));
+        X509_OBJECT_free(xobj);
+        if (!pkey) {
+            BIO_printf(bio_err, "Error getting CRL issuer public key\n");
+            goto end;
+        }
+        i = X509_CRL_verify(x, pkey);
+        EVP_PKEY_free(pkey);
+        if (i < 0)
+            goto end;
+        if (i == 0)
+            BIO_printf(bio_err, "verify failure\n");
+        else
+            BIO_printf(bio_err, "verify OK\n");
+    }
+
+    if (crldiff) {
+        X509_CRL *newcrl, *delta;
+        if (!keyfile) {
+            BIO_puts(bio_err, "Missing CRL signing key\n");
+            goto end;
+        }
+        newcrl = load_crl(crldiff, informat);
+        if (!newcrl)
+            goto end;
+        pkey = load_key(keyfile, keyformat, 0, NULL, NULL, "CRL signing key");
+        if (!pkey) {
+            X509_CRL_free(newcrl);
+            goto end;
+        }
+        delta = X509_CRL_diff(x, newcrl, pkey, digest, 0);
+        X509_CRL_free(newcrl);
+        EVP_PKEY_free(pkey);
+        if (delta) {
+            X509_CRL_free(x);
+            x = delta;
+        } else {
+            BIO_puts(bio_err, "Error creating delta CRL\n");
+            goto end;
+        }
+    }
+
+    if (badsig) {
+        const ASN1_BIT_STRING *sig;
+
+        X509_CRL_get0_signature(x, &sig, NULL);
+        corrupt_signature(sig);
+    }
+
+    if (num) {
+        for (i = 1; i <= num; i++) {
+            if (issuer == i) {
+                print_name(bio_out, "issuer=", X509_CRL_get_issuer(x),
+                           nmflag);
+            }
+            if (crlnumber == i) {
+                ASN1_INTEGER *crlnum;
+                crlnum = X509_CRL_get_ext_d2i(x, NID_crl_number, NULL, NULL);
+                BIO_printf(bio_out, "crlNumber=");
+                if (crlnum) {
+                    i2a_ASN1_INTEGER(bio_out, crlnum);
+                    ASN1_INTEGER_free(crlnum);
+                } else
+                    BIO_puts(bio_out, "<NONE>");
+                BIO_printf(bio_out, "\n");
+            }
+            if (hash == i) {
+                BIO_printf(bio_out, "%08lx\n",
+                           X509_NAME_hash(X509_CRL_get_issuer(x)));
+            }
+#ifndef OPENSSL_NO_MD5
+            if (hash_old == i) {
+                BIO_printf(bio_out, "%08lx\n",
+                           X509_NAME_hash_old(X509_CRL_get_issuer(x)));
+            }
+#endif
+            if (lastupdate == i) {
+                BIO_printf(bio_out, "lastUpdate=");
+                ASN1_TIME_print(bio_out, X509_CRL_get0_lastUpdate(x));
+                BIO_printf(bio_out, "\n");
+            }
+            if (nextupdate == i) {
+                BIO_printf(bio_out, "nextUpdate=");
+                if (X509_CRL_get0_nextUpdate(x))
+                    ASN1_TIME_print(bio_out, X509_CRL_get0_nextUpdate(x));
+                else
+                    BIO_printf(bio_out, "NONE");
+                BIO_printf(bio_out, "\n");
+            }
+            if (fingerprint == i) {
+                int j;
+                unsigned int n;
+                unsigned char md[EVP_MAX_MD_SIZE];
+
+                if (!X509_CRL_digest(x, digest, md, &n)) {
+                    BIO_printf(bio_err, "out of memory\n");
+                    goto end;
+                }
+                BIO_printf(bio_out, "%s Fingerprint=",
+                           OBJ_nid2sn(EVP_MD_type(digest)));
+                for (j = 0; j < (int)n; j++) {
+                    BIO_printf(bio_out, "%02X%c", md[j], (j + 1 == (int)n)
+                               ? '\n' : ':');
+                }
+            }
+        }
+    }
+    out = bio_open_default(outfile, 'w', outformat);
+    if (out == NULL)
+        goto end;
+
+    if (text)
+        X509_CRL_print(out, x);
+
+    if (noout) {
+        ret = 0;
+        goto end;
+    }
+
+    if (outformat == FORMAT_ASN1)
+        i = (int)i2d_X509_CRL_bio(out, x);
+    else
+        i = PEM_write_bio_X509_CRL(out, x);
+    if (!i) {
+        BIO_printf(bio_err, "unable to write CRL\n");
+        goto end;
+    }
+    ret = 0;
+
+ end:
+    if (ret != 0)
+        ERR_print_errors(bio_err);
+    BIO_free_all(out);
+    X509_CRL_free(x);
+    X509_STORE_CTX_free(ctx);
+    X509_STORE_free(store);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/crl2p7.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/crl2p7.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/crl2p7.c	(revision 331)
@@ -0,0 +1,216 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include "apps.h"
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pem.h>
+#include <openssl/objects.h>
+
+static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile);
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_NOCRL, OPT_CERTFILE
+} OPTION_CHOICE;
+
+OPTIONS crl2pkcs7_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"},
+    {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"},
+    {"in", OPT_IN, '<', "Input file"},
+    {"out", OPT_OUT, '>', "Output file"},
+    {"nocrl", OPT_NOCRL, '-', "No crl to load, just certs from '-certfile'"},
+    {"certfile", OPT_CERTFILE, '<',
+     "File of chain of certs to a trusted CA; can be repeated"},
+    {NULL}
+};
+
+int crl2pkcs7_main(int argc, char **argv)
+{
+    BIO *in = NULL, *out = NULL;
+    PKCS7 *p7 = NULL;
+    PKCS7_SIGNED *p7s = NULL;
+    STACK_OF(OPENSSL_STRING) *certflst = NULL;
+    STACK_OF(X509) *cert_stack = NULL;
+    STACK_OF(X509_CRL) *crl_stack = NULL;
+    X509_CRL *crl = NULL;
+    char *infile = NULL, *outfile = NULL, *prog, *certfile;
+    int i = 0, informat = FORMAT_PEM, outformat = FORMAT_PEM, ret = 1, nocrl =
+        0;
+    OPTION_CHOICE o;
+
+    prog = opt_init(argc, argv, crl2pkcs7_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(crl2pkcs7_options);
+            ret = 0;
+            goto end;
+        case OPT_INFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
+                goto opthelp;
+            break;
+        case OPT_OUTFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
+                goto opthelp;
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_NOCRL:
+            nocrl = 1;
+            break;
+        case OPT_CERTFILE:
+            if ((certflst == NULL)
+                && (certflst = sk_OPENSSL_STRING_new_null()) == NULL)
+                goto end;
+            if (!sk_OPENSSL_STRING_push(certflst, opt_arg()))
+                goto end;
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    if (!nocrl) {
+        in = bio_open_default(infile, 'r', informat);
+        if (in == NULL)
+            goto end;
+
+        if (informat == FORMAT_ASN1)
+            crl = d2i_X509_CRL_bio(in, NULL);
+        else if (informat == FORMAT_PEM)
+            crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
+        if (crl == NULL) {
+            BIO_printf(bio_err, "unable to load CRL\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    if ((p7 = PKCS7_new()) == NULL)
+        goto end;
+    if ((p7s = PKCS7_SIGNED_new()) == NULL)
+        goto end;
+    p7->type = OBJ_nid2obj(NID_pkcs7_signed);
+    p7->d.sign = p7s;
+    p7s->contents->type = OBJ_nid2obj(NID_pkcs7_data);
+
+    if (!ASN1_INTEGER_set(p7s->version, 1))
+        goto end;
+    if ((crl_stack = sk_X509_CRL_new_null()) == NULL)
+        goto end;
+    p7s->crl = crl_stack;
+    if (crl != NULL) {
+        sk_X509_CRL_push(crl_stack, crl);
+        crl = NULL;             /* now part of p7 for OPENSSL_freeing */
+    }
+
+    if ((cert_stack = sk_X509_new_null()) == NULL)
+        goto end;
+    p7s->cert = cert_stack;
+
+    if (certflst)
+        for (i = 0; i < sk_OPENSSL_STRING_num(certflst); i++) {
+            certfile = sk_OPENSSL_STRING_value(certflst, i);
+            if (add_certs_from_file(cert_stack, certfile) < 0) {
+                BIO_printf(bio_err, "error loading certificates\n");
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+        }
+
+    out = bio_open_default(outfile, 'w', outformat);
+    if (out == NULL)
+        goto end;
+
+    if (outformat == FORMAT_ASN1)
+        i = i2d_PKCS7_bio(out, p7);
+    else if (outformat == FORMAT_PEM)
+        i = PEM_write_bio_PKCS7(out, p7);
+    if (!i) {
+        BIO_printf(bio_err, "unable to write pkcs7 object\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+    ret = 0;
+ end:
+    sk_OPENSSL_STRING_free(certflst);
+    BIO_free(in);
+    BIO_free_all(out);
+    PKCS7_free(p7);
+    X509_CRL_free(crl);
+
+    return (ret);
+}
+
+/*-
+ *----------------------------------------------------------------------
+ * int add_certs_from_file
+ *
+ *      Read a list of certificates to be checked from a file.
+ *
+ * Results:
+ *      number of certs added if successful, -1 if not.
+ *----------------------------------------------------------------------
+ */
+static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile)
+{
+    BIO *in = NULL;
+    int count = 0;
+    int ret = -1;
+    STACK_OF(X509_INFO) *sk = NULL;
+    X509_INFO *xi;
+
+    in = BIO_new_file(certfile, "r");
+    if (in == NULL) {
+        BIO_printf(bio_err, "error opening the file, %s\n", certfile);
+        goto end;
+    }
+
+    /* This loads from a file, a stack of x509/crl/pkey sets */
+    sk = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
+    if (sk == NULL) {
+        BIO_printf(bio_err, "error reading the file, %s\n", certfile);
+        goto end;
+    }
+
+    /* scan over it and pull out the CRL's */
+    while (sk_X509_INFO_num(sk)) {
+        xi = sk_X509_INFO_shift(sk);
+        if (xi->x509 != NULL) {
+            sk_X509_push(stack, xi->x509);
+            xi->x509 = NULL;
+            count++;
+        }
+        X509_INFO_free(xi);
+    }
+
+    ret = count;
+ end:
+    /* never need to OPENSSL_free x */
+    BIO_free(in);
+    sk_X509_INFO_free(sk);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/dgst.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/dgst.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/dgst.c	(revision 331)
@@ -0,0 +1,480 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/hmac.h>
+
+#undef BUFSIZE
+#define BUFSIZE 1024*8
+
+int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
+          EVP_PKEY *key, unsigned char *sigin, int siglen,
+          const char *sig_name, const char *md_name,
+          const char *file);
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_C, OPT_R, OPT_RAND, OPT_OUT, OPT_SIGN, OPT_PASSIN, OPT_VERIFY,
+    OPT_PRVERIFY, OPT_SIGNATURE, OPT_KEYFORM, OPT_ENGINE, OPT_ENGINE_IMPL,
+    OPT_HEX, OPT_BINARY, OPT_DEBUG, OPT_FIPS_FINGERPRINT,
+    OPT_HMAC, OPT_MAC, OPT_SIGOPT, OPT_MACOPT,
+    OPT_DIGEST
+} OPTION_CHOICE;
+
+OPTIONS dgst_options[] = {
+    {OPT_HELP_STR, 1, '-', "Usage: %s [options] [file...]\n"},
+    {OPT_HELP_STR, 1, '-',
+        "  file... files to digest (default is stdin)\n"},
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"c", OPT_C, '-', "Print the digest with separating colons"},
+    {"r", OPT_R, '-', "Print the digest in coreutils format"},
+    {"rand", OPT_RAND, 's',
+     "Use file(s) containing random data to seed RNG or an EGD sock"},
+    {"out", OPT_OUT, '>', "Output to filename rather than stdout"},
+    {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
+    {"sign", OPT_SIGN, 's', "Sign digest using private key"},
+    {"verify", OPT_VERIFY, 's',
+     "Verify a signature using public key"},
+    {"prverify", OPT_PRVERIFY, 's',
+     "Verify a signature using private key"},
+    {"signature", OPT_SIGNATURE, '<', "File with signature to verify"},
+    {"keyform", OPT_KEYFORM, 'f', "Key file format (PEM or ENGINE)"},
+    {"hex", OPT_HEX, '-', "Print as hex dump"},
+    {"binary", OPT_BINARY, '-', "Print in binary form"},
+    {"d", OPT_DEBUG, '-', "Print debug info"},
+    {"debug", OPT_DEBUG, '-', "Print debug info"},
+    {"fips-fingerprint", OPT_FIPS_FINGERPRINT, '-',
+     "Compute HMAC with the key used in OpenSSL-FIPS fingerprint"},
+    {"hmac", OPT_HMAC, 's', "Create hashed MAC with key"},
+    {"mac", OPT_MAC, 's', "Create MAC (not necessarily HMAC)"},
+    {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"},
+    {"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form or key"},
+    {"", OPT_DIGEST, '-', "Any supported digest"},
+#ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
+    {"engine_impl", OPT_ENGINE_IMPL, '-',
+     "Also use engine given by -engine for digest operations"},
+#endif
+    {NULL}
+};
+
+int dgst_main(int argc, char **argv)
+{
+    BIO *in = NULL, *inp, *bmd = NULL, *out = NULL;
+    ENGINE *e = NULL, *impl = NULL;
+    EVP_PKEY *sigkey = NULL;
+    STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL;
+    char *hmac_key = NULL;
+    char *mac_name = NULL;
+    char *passinarg = NULL, *passin = NULL;
+    const EVP_MD *md = NULL, *m;
+    const char *outfile = NULL, *keyfile = NULL, *prog = NULL;
+    const char *sigfile = NULL, *randfile = NULL;
+    OPTION_CHOICE o;
+    int separator = 0, debug = 0, keyform = FORMAT_PEM, siglen = 0;
+    int i, ret = 1, out_bin = -1, want_pub = 0, do_verify = 0;
+    unsigned char *buf = NULL, *sigbuf = NULL;
+    int engine_impl = 0;
+
+    prog = opt_progname(argv[0]);
+    buf = app_malloc(BUFSIZE, "I/O buffer");
+    md = EVP_get_digestbyname(prog);
+
+    prog = opt_init(argc, argv, dgst_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(dgst_options);
+            ret = 0;
+            goto end;
+        case OPT_C:
+            separator = 1;
+            break;
+        case OPT_R:
+            separator = 2;
+            break;
+        case OPT_RAND:
+            randfile = opt_arg();
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_SIGN:
+            keyfile = opt_arg();
+            break;
+        case OPT_PASSIN:
+            passinarg = opt_arg();
+            break;
+        case OPT_VERIFY:
+            keyfile = opt_arg();
+            want_pub = do_verify = 1;
+            break;
+        case OPT_PRVERIFY:
+            keyfile = opt_arg();
+            do_verify = 1;
+            break;
+        case OPT_SIGNATURE:
+            sigfile = opt_arg();
+            break;
+        case OPT_KEYFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform))
+                goto opthelp;
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        case OPT_ENGINE_IMPL:
+            engine_impl = 1;
+            break;
+        case OPT_HEX:
+            out_bin = 0;
+            break;
+        case OPT_BINARY:
+            out_bin = 1;
+            break;
+        case OPT_DEBUG:
+            debug = 1;
+            break;
+        case OPT_FIPS_FINGERPRINT:
+            hmac_key = "etaonrishdlcupfm";
+            break;
+        case OPT_HMAC:
+            hmac_key = opt_arg();
+            break;
+        case OPT_MAC:
+            mac_name = opt_arg();
+            break;
+        case OPT_SIGOPT:
+            if (!sigopts)
+                sigopts = sk_OPENSSL_STRING_new_null();
+            if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
+                goto opthelp;
+            break;
+        case OPT_MACOPT:
+            if (!macopts)
+                macopts = sk_OPENSSL_STRING_new_null();
+            if (!macopts || !sk_OPENSSL_STRING_push(macopts, opt_arg()))
+                goto opthelp;
+            break;
+        case OPT_DIGEST:
+            if (!opt_md(opt_unknown(), &m))
+                goto opthelp;
+            md = m;
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    argv = opt_rest();
+    if (keyfile != NULL && argc > 1) {
+        BIO_printf(bio_err, "%s: Can only sign or verify one file.\n", prog);
+        goto end;
+    }
+
+    if (do_verify && !sigfile) {
+        BIO_printf(bio_err,
+                   "No signature to verify: use the -signature option\n");
+        goto end;
+    }
+    if (engine_impl)
+        impl = e;
+
+    in = BIO_new(BIO_s_file());
+    bmd = BIO_new(BIO_f_md());
+    if ((in == NULL) || (bmd == NULL)) {
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    if (debug) {
+        BIO_set_callback(in, BIO_debug_callback);
+        /* needed for windows 3.1 */
+        BIO_set_callback_arg(in, (char *)bio_err);
+    }
+
+    if (!app_passwd(passinarg, NULL, &passin, NULL)) {
+        BIO_printf(bio_err, "Error getting password\n");
+        goto end;
+    }
+
+    if (out_bin == -1) {
+        if (keyfile)
+            out_bin = 1;
+        else
+            out_bin = 0;
+    }
+
+    if (randfile)
+        app_RAND_load_file(randfile, 0);
+
+    out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT);
+    if (out == NULL)
+        goto end;
+
+    if ((! !mac_name + ! !keyfile + ! !hmac_key) > 1) {
+        BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n");
+        goto end;
+    }
+
+    if (keyfile) {
+        if (want_pub)
+            sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "key file");
+        else
+            sigkey = load_key(keyfile, keyform, 0, passin, e, "key file");
+        if (!sigkey) {
+            /*
+             * load_[pub]key() has already printed an appropriate message
+             */
+            goto end;
+        }
+    }
+
+    if (mac_name) {
+        EVP_PKEY_CTX *mac_ctx = NULL;
+        int r = 0;
+        if (!init_gen_str(&mac_ctx, mac_name, impl, 0))
+            goto mac_end;
+        if (macopts) {
+            char *macopt;
+            for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) {
+                macopt = sk_OPENSSL_STRING_value(macopts, i);
+                if (pkey_ctrl_string(mac_ctx, macopt) <= 0) {
+                    BIO_printf(bio_err,
+                               "MAC parameter error \"%s\"\n", macopt);
+                    ERR_print_errors(bio_err);
+                    goto mac_end;
+                }
+            }
+        }
+        if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) {
+            BIO_puts(bio_err, "Error generating key\n");
+            ERR_print_errors(bio_err);
+            goto mac_end;
+        }
+        r = 1;
+ mac_end:
+        EVP_PKEY_CTX_free(mac_ctx);
+        if (r == 0)
+            goto end;
+    }
+
+    if (hmac_key) {
+        sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, impl,
+                                      (unsigned char *)hmac_key, -1);
+        if (!sigkey)
+            goto end;
+    }
+
+    if (sigkey) {
+        EVP_MD_CTX *mctx = NULL;
+        EVP_PKEY_CTX *pctx = NULL;
+        int r;
+        if (!BIO_get_md_ctx(bmd, &mctx)) {
+            BIO_printf(bio_err, "Error getting context\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        if (do_verify)
+            r = EVP_DigestVerifyInit(mctx, &pctx, md, impl, sigkey);
+        else
+            r = EVP_DigestSignInit(mctx, &pctx, md, impl, sigkey);
+        if (!r) {
+            BIO_printf(bio_err, "Error setting context\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        if (sigopts) {
+            char *sigopt;
+            for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
+                sigopt = sk_OPENSSL_STRING_value(sigopts, i);
+                if (pkey_ctrl_string(pctx, sigopt) <= 0) {
+                    BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt);
+                    ERR_print_errors(bio_err);
+                    goto end;
+                }
+            }
+        }
+    }
+    /* we use md as a filter, reading from 'in' */
+    else {
+        EVP_MD_CTX *mctx = NULL;
+        if (!BIO_get_md_ctx(bmd, &mctx)) {
+            BIO_printf(bio_err, "Error getting context\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        if (md == NULL)
+            md = EVP_sha256();
+        if (!EVP_DigestInit_ex(mctx, md, impl)) {
+            BIO_printf(bio_err, "Error setting digest\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    if (sigfile && sigkey) {
+        BIO *sigbio = BIO_new_file(sigfile, "rb");
+        if (!sigbio) {
+            BIO_printf(bio_err, "Error opening signature file %s\n", sigfile);
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        siglen = EVP_PKEY_size(sigkey);
+        sigbuf = app_malloc(siglen, "signature buffer");
+        siglen = BIO_read(sigbio, sigbuf, siglen);
+        BIO_free(sigbio);
+        if (siglen <= 0) {
+            BIO_printf(bio_err, "Error reading signature file %s\n", sigfile);
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+    inp = BIO_push(bmd, in);
+
+    if (md == NULL) {
+        EVP_MD_CTX *tctx;
+        BIO_get_md_ctx(bmd, &tctx);
+        md = EVP_MD_CTX_md(tctx);
+    }
+
+    if (argc == 0) {
+        BIO_set_fp(in, stdin, BIO_NOCLOSE);
+        ret = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf,
+                    siglen, NULL, NULL, "stdin");
+    } else {
+        const char *md_name = NULL, *sig_name = NULL;
+        if (!out_bin) {
+            if (sigkey) {
+                const EVP_PKEY_ASN1_METHOD *ameth;
+                ameth = EVP_PKEY_get0_asn1(sigkey);
+                if (ameth)
+                    EVP_PKEY_asn1_get0_info(NULL, NULL,
+                                            NULL, NULL, &sig_name, ameth);
+            }
+            if (md)
+                md_name = EVP_MD_name(md);
+        }
+        ret = 0;
+        for (i = 0; i < argc; i++) {
+            int r;
+            if (BIO_read_filename(in, argv[i]) <= 0) {
+                perror(argv[i]);
+                ret++;
+                continue;
+            } else
+                r = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf,
+                          siglen, sig_name, md_name, argv[i]);
+            if (r)
+                ret = r;
+            (void)BIO_reset(bmd);
+        }
+    }
+ end:
+    OPENSSL_clear_free(buf, BUFSIZE);
+    BIO_free(in);
+    OPENSSL_free(passin);
+    BIO_free_all(out);
+    EVP_PKEY_free(sigkey);
+    sk_OPENSSL_STRING_free(sigopts);
+    sk_OPENSSL_STRING_free(macopts);
+    OPENSSL_free(sigbuf);
+    BIO_free(bmd);
+    release_engine(e);
+    return (ret);
+}
+
+int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
+          EVP_PKEY *key, unsigned char *sigin, int siglen,
+          const char *sig_name, const char *md_name,
+          const char *file)
+{
+    size_t len;
+    int i;
+
+    for (;;) {
+        i = BIO_read(bp, (char *)buf, BUFSIZE);
+        if (i < 0) {
+            BIO_printf(bio_err, "Read Error in %s\n", file);
+            ERR_print_errors(bio_err);
+            return 1;
+        }
+        if (i == 0)
+            break;
+    }
+    if (sigin) {
+        EVP_MD_CTX *ctx;
+        BIO_get_md_ctx(bp, &ctx);
+        i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int)siglen);
+        if (i > 0)
+            BIO_printf(out, "Verified OK\n");
+        else if (i == 0) {
+            BIO_printf(out, "Verification Failure\n");
+            return 1;
+        } else {
+            BIO_printf(bio_err, "Error Verifying Data\n");
+            ERR_print_errors(bio_err);
+            return 1;
+        }
+        return 0;
+    }
+    if (key) {
+        EVP_MD_CTX *ctx;
+        BIO_get_md_ctx(bp, &ctx);
+        len = BUFSIZE;
+        if (!EVP_DigestSignFinal(ctx, buf, &len)) {
+            BIO_printf(bio_err, "Error Signing Data\n");
+            ERR_print_errors(bio_err);
+            return 1;
+        }
+    } else {
+        len = BIO_gets(bp, (char *)buf, BUFSIZE);
+        if ((int)len < 0) {
+            ERR_print_errors(bio_err);
+            return 1;
+        }
+    }
+
+    if (binout)
+        BIO_write(out, buf, len);
+    else if (sep == 2) {
+        for (i = 0; i < (int)len; i++)
+            BIO_printf(out, "%02x", buf[i]);
+        BIO_printf(out, " *%s\n", file);
+    } else {
+        if (sig_name) {
+            BIO_puts(out, sig_name);
+            if (md_name)
+                BIO_printf(out, "-%s", md_name);
+            BIO_printf(out, "(%s)= ", file);
+        } else if (md_name)
+            BIO_printf(out, "%s(%s)= ", md_name, file);
+        else
+            BIO_printf(out, "(%s)= ", file);
+        for (i = 0; i < (int)len; i++) {
+            if (sep && (i != 0))
+                BIO_printf(out, ":");
+            BIO_printf(out, "%02x", buf[i]);
+        }
+        BIO_printf(out, "\n");
+    }
+    return 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/dhparam.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/dhparam.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/dhparam.c	(revision 331)
@@ -0,0 +1,380 @@
+/*
+ * Copyright 1995-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 <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_DH
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <time.h>
+# include <string.h>
+# include "apps.h"
+# include <openssl/bio.h>
+# include <openssl/err.h>
+# include <openssl/bn.h>
+# include <openssl/dh.h>
+# include <openssl/x509.h>
+# include <openssl/pem.h>
+
+# ifndef OPENSSL_NO_DSA
+#  include <openssl/dsa.h>
+# endif
+
+# define DEFBITS 2048
+
+static int dh_cb(int p, int n, BN_GENCB *cb);
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT,
+    OPT_ENGINE, OPT_CHECK, OPT_TEXT, OPT_NOOUT,
+    OPT_RAND, OPT_DSAPARAM, OPT_C, OPT_2, OPT_5
+} OPTION_CHOICE;
+
+OPTIONS dhparam_options[] = {
+    {OPT_HELP_STR, 1, '-', "Usage: %s [flags] [numbits]\n"},
+    {OPT_HELP_STR, 1, '-', "Valid options are:\n"},
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"in", OPT_IN, '<', "Input file"},
+    {"inform", OPT_INFORM, 'F', "Input format, DER or PEM"},
+    {"outform", OPT_OUTFORM, 'F', "Output format, DER or PEM"},
+    {"out", OPT_OUT, '>', "Output file"},
+    {"check", OPT_CHECK, '-', "Check the DH parameters"},
+    {"text", OPT_TEXT, '-', "Print a text form of the DH parameters"},
+    {"noout", OPT_NOOUT, '-', "Don't output any DH parameters"},
+    {"rand", OPT_RAND, 's',
+     "Load the file(s) into the random number generator"},
+    {"C", OPT_C, '-', "Print C code"},
+    {"2", OPT_2, '-', "Generate parameters using 2 as the generator value"},
+    {"5", OPT_5, '-', "Generate parameters using 5 as the generator value"},
+# ifndef OPENSSL_NO_DSA
+    {"dsaparam", OPT_DSAPARAM, '-',
+     "Read or generate DSA parameters, convert to DH"},
+# endif
+# ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
+# endif
+    {NULL}
+};
+
+int dhparam_main(int argc, char **argv)
+{
+    BIO *in = NULL, *out = NULL;
+    DH *dh = NULL;
+    char *infile = NULL, *outfile = NULL, *prog, *inrand = NULL;
+    ENGINE *e = NULL;
+#ifndef OPENSSL_NO_DSA
+    int dsaparam = 0;
+#endif
+    int i, text = 0, C = 0, ret = 1, num = 0, g = 0;
+    int informat = FORMAT_PEM, outformat = FORMAT_PEM, check = 0, noout = 0;
+    OPTION_CHOICE o;
+
+    prog = opt_init(argc, argv, dhparam_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(dhparam_options);
+            ret = 0;
+            goto end;
+        case OPT_INFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
+                goto opthelp;
+            break;
+        case OPT_OUTFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
+                goto opthelp;
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        case OPT_CHECK:
+            check = 1;
+            break;
+        case OPT_TEXT:
+            text = 1;
+            break;
+        case OPT_DSAPARAM:
+#ifndef OPENSSL_NO_DSA
+            dsaparam = 1;
+#endif
+            break;
+        case OPT_C:
+            C = 1;
+            break;
+        case OPT_2:
+            g = 2;
+            break;
+        case OPT_5:
+            g = 5;
+            break;
+        case OPT_NOOUT:
+            noout = 1;
+            break;
+        case OPT_RAND:
+            inrand = opt_arg();
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    argv = opt_rest();
+
+    if (argv[0] && (!opt_int(argv[0], &num) || num <= 0))
+        goto end;
+
+    if (g && !num)
+        num = DEFBITS;
+
+# ifndef OPENSSL_NO_DSA
+    if (dsaparam && g) {
+        BIO_printf(bio_err,
+                   "generator may not be chosen for DSA parameters\n");
+        goto end;
+    }
+# endif
+    /* DH parameters */
+    if (num && !g)
+        g = 2;
+
+    if (num) {
+
+        BN_GENCB *cb;
+        cb = BN_GENCB_new();
+        if (cb == NULL) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+
+        BN_GENCB_set(cb, dh_cb, bio_err);
+        if (!app_RAND_load_file(NULL, 1) && inrand == NULL) {
+            BIO_printf(bio_err,
+                       "warning, not much extra random data, consider using the -rand option\n");
+        }
+        if (inrand != NULL)
+            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
+                       app_RAND_load_files(inrand));
+
+# ifndef OPENSSL_NO_DSA
+        if (dsaparam) {
+            DSA *dsa = DSA_new();
+
+            BIO_printf(bio_err,
+                       "Generating DSA parameters, %d bit long prime\n", num);
+            if (dsa == NULL
+                || !DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL,
+                                               cb)) {
+                DSA_free(dsa);
+                BN_GENCB_free(cb);
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+
+            dh = DSA_dup_DH(dsa);
+            DSA_free(dsa);
+            if (dh == NULL) {
+                BN_GENCB_free(cb);
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+        } else
+# endif
+        {
+            dh = DH_new();
+            BIO_printf(bio_err,
+                       "Generating DH parameters, %d bit long safe prime, generator %d\n",
+                       num, g);
+            BIO_printf(bio_err, "This is going to take a long time\n");
+            if (dh == NULL || !DH_generate_parameters_ex(dh, num, g, cb)) {
+                BN_GENCB_free(cb);
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+        }
+
+        BN_GENCB_free(cb);
+        app_RAND_write_file(NULL);
+    } else {
+
+        in = bio_open_default(infile, 'r', informat);
+        if (in == NULL)
+            goto end;
+
+# ifndef OPENSSL_NO_DSA
+        if (dsaparam) {
+            DSA *dsa;
+
+            if (informat == FORMAT_ASN1)
+                dsa = d2i_DSAparams_bio(in, NULL);
+            else                /* informat == FORMAT_PEM */
+                dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL);
+
+            if (dsa == NULL) {
+                BIO_printf(bio_err, "unable to load DSA parameters\n");
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+
+            dh = DSA_dup_DH(dsa);
+            DSA_free(dsa);
+            if (dh == NULL) {
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+        } else
+# endif
+        {
+            if (informat == FORMAT_ASN1)
+                dh = d2i_DHparams_bio(in, NULL);
+            else                /* informat == FORMAT_PEM */
+                dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
+
+            if (dh == NULL) {
+                BIO_printf(bio_err, "unable to load DH parameters\n");
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+        }
+
+        /* dh != NULL */
+    }
+
+    out = bio_open_default(outfile, 'w', outformat);
+    if (out == NULL)
+        goto end;
+
+    if (text) {
+        DHparams_print(out, dh);
+    }
+
+    if (check) {
+        if (!DH_check(dh, &i)) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        if (i & DH_CHECK_P_NOT_PRIME)
+            BIO_printf(bio_err, "WARNING: p value is not prime\n");
+        if (i & DH_CHECK_P_NOT_SAFE_PRIME)
+            BIO_printf(bio_err, "WARNING: p value is not a safe prime\n");
+        if (i & DH_CHECK_Q_NOT_PRIME)
+            BIO_printf(bio_err, "WARNING: q value is not a prime\n");
+        if (i & DH_CHECK_INVALID_Q_VALUE)
+            BIO_printf(bio_err, "WARNING: q value is invalid\n");
+        if (i & DH_CHECK_INVALID_J_VALUE)
+            BIO_printf(bio_err, "WARNING: j value is invalid\n");
+        if (i & DH_UNABLE_TO_CHECK_GENERATOR)
+            BIO_printf(bio_err,
+                       "WARNING: unable to check the generator value\n");
+        if (i & DH_NOT_SUITABLE_GENERATOR)
+            BIO_printf(bio_err, "WARNING: the g value is not a generator\n");
+        if (i == 0)
+            BIO_printf(bio_err, "DH parameters appear to be ok.\n");
+        if (num != 0 && i != 0) {
+            /*
+             * We have generated parameters but DH_check() indicates they are
+             * invalid! This should never happen!
+             */
+            BIO_printf(bio_err, "ERROR: Invalid parameters generated\n");
+            goto end;
+        }
+    }
+    if (C) {
+        unsigned char *data;
+        int len, bits;
+        const BIGNUM *pbn, *gbn;
+
+        len = DH_size(dh);
+        bits = DH_bits(dh);
+        DH_get0_pqg(dh, &pbn, NULL, &gbn);
+        data = app_malloc(len, "print a BN");
+        BIO_printf(out, "#ifndef HEADER_DH_H\n"
+                        "# include <openssl/dh.h>\n"
+                        "#endif\n"
+                        "\n");
+        BIO_printf(out, "DH *get_dh%d()\n{\n", bits);
+        print_bignum_var(out, pbn, "dhp", bits, data);
+        print_bignum_var(out, gbn, "dhg", bits, data);
+        BIO_printf(out, "    DH *dh = DH_new();\n"
+                        "    BIGNUM *dhp_bn, *dhg_bn;\n"
+                        "\n"
+                        "    if (dh == NULL)\n"
+                        "        return NULL;\n");
+        BIO_printf(out, "    dhp_bn = BN_bin2bn(dhp_%d, sizeof (dhp_%d), NULL);\n",
+                   bits, bits);
+        BIO_printf(out, "    dhg_bn = BN_bin2bn(dhg_%d, sizeof (dhg_%d), NULL);\n",
+                   bits, bits);
+        BIO_printf(out, "    if (dhp_bn == NULL || dhg_bn == NULL\n"
+                        "            || !DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn)) {\n"
+                        "        DH_free(dh);\n"
+                        "        BN_free(dhp_bn);\n"
+                        "        BN_free(dhg_bn);\n"
+                        "        return NULL;\n"
+                        "    }\n");
+        if (DH_get_length(dh) > 0)
+            BIO_printf(out,
+                        "    if (!DH_set_length(dh, %ld)) {\n"
+                        "        DH_free(dh);\n"
+                        "    }\n", DH_get_length(dh));
+        BIO_printf(out, "    return dh;\n}\n");
+        OPENSSL_free(data);
+    }
+
+    if (!noout) {
+        const BIGNUM *q;
+        DH_get0_pqg(dh, NULL, &q, NULL);
+        if (outformat == FORMAT_ASN1)
+            i = i2d_DHparams_bio(out, dh);
+        else if (q != NULL)
+            i = PEM_write_bio_DHxparams(out, dh);
+        else
+            i = PEM_write_bio_DHparams(out, dh);
+        if (!i) {
+            BIO_printf(bio_err, "unable to write DH parameters\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+    ret = 0;
+ end:
+    BIO_free(in);
+    BIO_free_all(out);
+    DH_free(dh);
+    release_engine(e);
+    return (ret);
+}
+
+static int dh_cb(int p, int n, BN_GENCB *cb)
+{
+    char c = '*';
+
+    if (p == 0)
+        c = '.';
+    if (p == 1)
+        c = '+';
+    if (p == 2)
+        c = '*';
+    if (p == 3)
+        c = '\n';
+    BIO_write(BN_GENCB_get_arg(cb), &c, 1);
+    (void)BIO_flush(BN_GENCB_get_arg(cb));
+    return 1;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/dsa.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/dsa.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/dsa.c	(revision 331)
@@ -0,0 +1,262 @@
+/*
+ * Copyright 1995-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 <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_DSA
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+# include <time.h>
+# include "apps.h"
+# include <openssl/bio.h>
+# include <openssl/err.h>
+# include <openssl/dsa.h>
+# include <openssl/evp.h>
+# include <openssl/x509.h>
+# include <openssl/pem.h>
+# include <openssl/bn.h>
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_ENGINE,
+    /* Do not change the order here; see case statements below */
+    OPT_PVK_NONE, OPT_PVK_WEAK, OPT_PVK_STRONG,
+    OPT_NOOUT, OPT_TEXT, OPT_MODULUS, OPT_PUBIN,
+    OPT_PUBOUT, OPT_CIPHER, OPT_PASSIN, OPT_PASSOUT
+} OPTION_CHOICE;
+
+OPTIONS dsa_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"inform", OPT_INFORM, 'f', "Input format, DER PEM PVK"},
+    {"outform", OPT_OUTFORM, 'f', "Output format, DER PEM PVK"},
+    {"in", OPT_IN, 's', "Input key"},
+    {"out", OPT_OUT, '>', "Output file"},
+    {"noout", OPT_NOOUT, '-', "Don't print key out"},
+    {"text", OPT_TEXT, '-', "Print the key in text"},
+    {"modulus", OPT_MODULUS, '-', "Print the DSA public value"},
+    {"pubin", OPT_PUBIN, '-', "Expect a public key in input file"},
+    {"pubout", OPT_PUBOUT, '-', "Output public key, not private"},
+    {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
+    {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
+    {"", OPT_CIPHER, '-', "Any supported cipher"},
+# ifndef OPENSSL_NO_RC4
+    {"pvk-strong", OPT_PVK_STRONG, '-', "Enable 'Strong' PVK encoding level (default)"},
+    {"pvk-weak", OPT_PVK_WEAK, '-', "Enable 'Weak' PVK encoding level"},
+    {"pvk-none", OPT_PVK_NONE, '-', "Don't enforce PVK encoding"},
+# endif
+# ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
+# endif
+    {NULL}
+};
+
+int dsa_main(int argc, char **argv)
+{
+    BIO *out = NULL;
+    DSA *dsa = NULL;
+    ENGINE *e = NULL;
+    const EVP_CIPHER *enc = NULL;
+    char *infile = NULL, *outfile = NULL, *prog;
+    char *passin = NULL, *passout = NULL, *passinarg = NULL, *passoutarg = NULL;
+    OPTION_CHOICE o;
+    int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, noout = 0;
+    int i, modulus = 0, pubin = 0, pubout = 0, ret = 1;
+# ifndef OPENSSL_NO_RC4
+    int pvk_encr = 2;
+# endif
+    int private = 0;
+
+    prog = opt_init(argc, argv, dsa_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            ret = 0;
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(dsa_options);
+            ret = 0;
+            goto end;
+        case OPT_INFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat))
+                goto opthelp;
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUTFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_ANY, &outformat))
+                goto opthelp;
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        case OPT_PASSIN:
+            passinarg = opt_arg();
+            break;
+        case OPT_PASSOUT:
+            passoutarg = opt_arg();
+            break;
+        case OPT_PVK_STRONG:    /* pvk_encr:= 2 */
+        case OPT_PVK_WEAK:      /* pvk_encr:= 1 */
+        case OPT_PVK_NONE:      /* pvk_encr:= 0 */
+#ifndef OPENSSL_NO_RC4
+            pvk_encr = (o - OPT_PVK_NONE);
+#endif
+            break;
+        case OPT_NOOUT:
+            noout = 1;
+            break;
+        case OPT_TEXT:
+            text = 1;
+            break;
+        case OPT_MODULUS:
+            modulus = 1;
+            break;
+        case OPT_PUBIN:
+            pubin = 1;
+            break;
+        case OPT_PUBOUT:
+            pubout = 1;
+            break;
+        case OPT_CIPHER:
+            if (!opt_cipher(opt_unknown(), &enc))
+                goto end;
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    private = pubin || pubout ? 0 : 1;
+    if (text && !pubin)
+        private = 1;
+
+    if (!app_passwd(passinarg, passoutarg, &passin, &passout)) {
+        BIO_printf(bio_err, "Error getting passwords\n");
+        goto end;
+    }
+
+    BIO_printf(bio_err, "read DSA key\n");
+    {
+        EVP_PKEY *pkey;
+
+        if (pubin)
+            pkey = load_pubkey(infile, informat, 1, passin, e, "Public Key");
+        else
+            pkey = load_key(infile, informat, 1, passin, e, "Private Key");
+
+        if (pkey) {
+            dsa = EVP_PKEY_get1_DSA(pkey);
+            EVP_PKEY_free(pkey);
+        }
+    }
+    if (dsa == NULL) {
+        BIO_printf(bio_err, "unable to load Key\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    out = bio_open_owner(outfile, outformat, private);
+    if (out == NULL)
+        goto end;
+
+    if (text) {
+        assert(pubin || private);
+        if (!DSA_print(out, dsa, 0)) {
+            perror(outfile);
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    if (modulus) {
+        const BIGNUM *pub_key = NULL;
+        DSA_get0_key(dsa, &pub_key, NULL);
+        BIO_printf(out, "Public Key=");
+        BN_print(out, pub_key);
+        BIO_printf(out, "\n");
+    }
+
+    if (noout) {
+        ret = 0;
+        goto end;
+    }
+    BIO_printf(bio_err, "writing DSA key\n");
+    if (outformat == FORMAT_ASN1) {
+        if (pubin || pubout)
+            i = i2d_DSA_PUBKEY_bio(out, dsa);
+        else {
+            assert(private);
+            i = i2d_DSAPrivateKey_bio(out, dsa);
+        }
+    } else if (outformat == FORMAT_PEM) {
+        if (pubin || pubout)
+            i = PEM_write_bio_DSA_PUBKEY(out, dsa);
+        else {
+            assert(private);
+            i = PEM_write_bio_DSAPrivateKey(out, dsa, enc,
+                                            NULL, 0, NULL, passout);
+        }
+# ifndef OPENSSL_NO_RSA
+    } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) {
+        EVP_PKEY *pk;
+        pk = EVP_PKEY_new();
+        EVP_PKEY_set1_DSA(pk, dsa);
+        if (outformat == FORMAT_PVK) {
+            if (pubin) {
+                BIO_printf(bio_err, "PVK form impossible with public key input\n");
+                EVP_PKEY_free(pk);
+                goto end;
+            }
+            assert(private);
+#  ifdef OPENSSL_NO_RC4
+            BIO_printf(bio_err, "PVK format not supported\n");
+            EVP_PKEY_free(pk);
+            goto end;
+#  else
+            i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout);
+#  endif
+        }
+        else if (pubin || pubout)
+            i = i2b_PublicKey_bio(out, pk);
+        else {
+            assert(private);
+            i = i2b_PrivateKey_bio(out, pk);
+        }
+        EVP_PKEY_free(pk);
+# endif
+    } else {
+        BIO_printf(bio_err, "bad output format specified for outfile\n");
+        goto end;
+    }
+    if (i <= 0) {
+        BIO_printf(bio_err, "unable to write private key\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+    ret = 0;
+ end:
+    BIO_free_all(out);
+    DSA_free(dsa);
+    release_engine(e);
+    OPENSSL_free(passin);
+    OPENSSL_free(passout);
+    return (ret);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/dsaparam.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/dsaparam.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/dsaparam.c	(revision 331)
@@ -0,0 +1,313 @@
+/*
+ * Copyright 1995-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 <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_DSA
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <time.h>
+# include <string.h>
+# include "apps.h"
+# include <openssl/bio.h>
+# include <openssl/err.h>
+# include <openssl/bn.h>
+# include <openssl/dsa.h>
+# include <openssl/x509.h>
+# include <openssl/pem.h>
+
+# ifdef GENCB_TEST
+
+static int stop_keygen_flag = 0;
+
+static void timebomb_sigalarm(int foo)
+{
+    stop_keygen_flag = 1;
+}
+
+# endif
+
+static int dsa_cb(int p, int n, BN_GENCB *cb);
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT, OPT_C,
+    OPT_NOOUT, OPT_GENKEY, OPT_RAND, OPT_ENGINE,
+    OPT_TIMEBOMB
+} OPTION_CHOICE;
+
+OPTIONS dsaparam_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"},
+    {"in", OPT_IN, '<', "Input file"},
+    {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"},
+    {"out", OPT_OUT, '>', "Output file"},
+    {"text", OPT_TEXT, '-', "Print as text"},
+    {"C", OPT_C, '-', "Output C code"},
+    {"noout", OPT_NOOUT, '-', "No output"},
+    {"genkey", OPT_GENKEY, '-', "Generate a DSA key"},
+    {"rand", OPT_RAND, 's', "Files to use for random number input"},
+# ifdef GENCB_TEST
+    {"timebomb", OPT_TIMEBOMB, 'p', "Interrupt keygen after 'pnum' seconds"},
+# endif
+# ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
+# endif
+    {NULL}
+};
+
+int dsaparam_main(int argc, char **argv)
+{
+    ENGINE *e = NULL;
+    DSA *dsa = NULL;
+    BIO *in = NULL, *out = NULL;
+    BN_GENCB *cb = NULL;
+    int numbits = -1, num = 0, genkey = 0, need_rand = 0;
+    int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0;
+    int ret = 1, i, text = 0, private = 0;
+# ifdef GENCB_TEST
+    int timebomb = 0;
+# endif
+    char *infile = NULL, *outfile = NULL, *prog, *inrand = NULL;
+    OPTION_CHOICE o;
+
+    prog = opt_init(argc, argv, dsaparam_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(dsaparam_options);
+            ret = 0;
+            goto end;
+        case OPT_INFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
+                goto opthelp;
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUTFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
+                goto opthelp;
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        case OPT_TIMEBOMB:
+# ifdef GENCB_TEST
+            timebomb = atoi(opt_arg());
+            break;
+# endif
+        case OPT_TEXT:
+            text = 1;
+            break;
+        case OPT_C:
+            C = 1;
+            break;
+        case OPT_GENKEY:
+            genkey = need_rand = 1;
+            break;
+        case OPT_RAND:
+            inrand = opt_arg();
+            need_rand = 1;
+            break;
+        case OPT_NOOUT:
+            noout = 1;
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    argv = opt_rest();
+
+    if (argc == 1) {
+        if (!opt_int(argv[0], &num) || num < 0)
+            goto end;
+        /* generate a key */
+        numbits = num;
+        need_rand = 1;
+    }
+    private = genkey ? 1 : 0;
+
+    in = bio_open_default(infile, 'r', informat);
+    if (in == NULL)
+        goto end;
+    out = bio_open_owner(outfile, outformat, private);
+    if (out == NULL)
+        goto end;
+
+    if (need_rand) {
+        app_RAND_load_file(NULL, (inrand != NULL));
+        if (inrand != NULL)
+            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
+                       app_RAND_load_files(inrand));
+    }
+
+    if (numbits > 0) {
+        cb = BN_GENCB_new();
+        if (cb == NULL) {
+            BIO_printf(bio_err, "Error allocating BN_GENCB object\n");
+            goto end;
+        }
+        BN_GENCB_set(cb, dsa_cb, bio_err);
+        assert(need_rand);
+        dsa = DSA_new();
+        if (dsa == NULL) {
+            BIO_printf(bio_err, "Error allocating DSA object\n");
+            goto end;
+        }
+        BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n",
+                   num);
+        BIO_printf(bio_err, "This could take some time\n");
+# ifdef GENCB_TEST
+        if (timebomb > 0) {
+            struct sigaction act;
+            act.sa_handler = timebomb_sigalarm;
+            act.sa_flags = 0;
+            BIO_printf(bio_err,
+                       "(though I'll stop it if not done within %d secs)\n",
+                       timebomb);
+            if (sigaction(SIGALRM, &act, NULL) != 0) {
+                BIO_printf(bio_err, "Error, couldn't set SIGALRM handler\n");
+                goto end;
+            }
+            alarm(timebomb);
+        }
+# endif
+        if (!DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL, cb)) {
+# ifdef GENCB_TEST
+            if (stop_keygen_flag) {
+                BIO_printf(bio_err, "DSA key generation time-stopped\n");
+                /* This is an asked-for behaviour! */
+                ret = 0;
+                goto end;
+            }
+# endif
+            ERR_print_errors(bio_err);
+            BIO_printf(bio_err, "Error, DSA key generation failed\n");
+            goto end;
+        }
+    } else if (informat == FORMAT_ASN1)
+        dsa = d2i_DSAparams_bio(in, NULL);
+    else
+        dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL);
+    if (dsa == NULL) {
+        BIO_printf(bio_err, "unable to load DSA parameters\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    if (text) {
+        DSAparams_print(out, dsa);
+    }
+
+    if (C) {
+        const BIGNUM *p = NULL, *q = NULL, *g = NULL;
+        unsigned char *data;
+        int len, bits_p;
+
+        DSA_get0_pqg(dsa, &p, &q, &g);
+        len = BN_num_bytes(p);
+        bits_p = BN_num_bits(p);
+
+        data = app_malloc(len + 20, "BN space");
+
+        BIO_printf(bio_out, "DSA *get_dsa%d()\n{\n", bits_p);
+        print_bignum_var(bio_out, p, "dsap", len, data);
+        print_bignum_var(bio_out, q, "dsaq", len, data);
+        print_bignum_var(bio_out, g, "dsag", len, data);
+        BIO_printf(bio_out, "    DSA *dsa = DSA_new();\n"
+                            "\n");
+        BIO_printf(bio_out, "    if (dsa == NULL)\n"
+                            "        return NULL;\n");
+        BIO_printf(bio_out, "    dsa->p = BN_bin2bn(dsap_%d, sizeof (dsap_%d), NULL);\n",
+               bits_p, bits_p);
+        BIO_printf(bio_out, "    dsa->q = BN_bin2bn(dsaq_%d, sizeof (dsaq_%d), NULL);\n",
+               bits_p, bits_p);
+        BIO_printf(bio_out, "    dsa->g = BN_bin2bn(dsag_%d, sizeof (dsag_%d), NULL);\n",
+               bits_p, bits_p);
+        BIO_printf(bio_out, "    if (!dsa->p || !dsa->q || !dsa->g) {\n"
+                            "        DSA_free(dsa);\n"
+                            "        return NULL;\n"
+                            "    }\n"
+                            "    return(dsa);\n}\n");
+        OPENSSL_free(data);
+    }
+
+    if (!noout) {
+        if (outformat == FORMAT_ASN1)
+            i = i2d_DSAparams_bio(out, dsa);
+        else
+            i = PEM_write_bio_DSAparams(out, dsa);
+        if (!i) {
+            BIO_printf(bio_err, "unable to write DSA parameters\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+    if (genkey) {
+        DSA *dsakey;
+
+        assert(need_rand);
+        if ((dsakey = DSAparams_dup(dsa)) == NULL)
+            goto end;
+        if (!DSA_generate_key(dsakey)) {
+            ERR_print_errors(bio_err);
+            DSA_free(dsakey);
+            goto end;
+        }
+        assert(private);
+        if (outformat == FORMAT_ASN1)
+            i = i2d_DSAPrivateKey_bio(out, dsakey);
+        else
+            i = PEM_write_bio_DSAPrivateKey(out, dsakey, NULL, NULL, 0, NULL,
+                                            NULL);
+        DSA_free(dsakey);
+    }
+    if (need_rand)
+        app_RAND_write_file(NULL);
+    ret = 0;
+ end:
+    BN_GENCB_free(cb);
+    BIO_free(in);
+    BIO_free_all(out);
+    DSA_free(dsa);
+    release_engine(e);
+    return (ret);
+}
+
+static int dsa_cb(int p, int n, BN_GENCB *cb)
+{
+    char c = '*';
+
+    if (p == 0)
+        c = '.';
+    if (p == 1)
+        c = '+';
+    if (p == 2)
+        c = '*';
+    if (p == 3)
+        c = '\n';
+    BIO_write(BN_GENCB_get_arg(cb), &c, 1);
+    (void)BIO_flush(BN_GENCB_get_arg(cb));
+# ifdef GENCB_TEST
+    if (stop_keygen_flag)
+        return 0;
+# endif
+    return 1;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/ec.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/ec.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/ec.c	(revision 331)
@@ -0,0 +1,281 @@
+/*
+ * Copyright 2002-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 <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_EC
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+# include "apps.h"
+# include <openssl/bio.h>
+# include <openssl/err.h>
+# include <openssl/evp.h>
+# include <openssl/pem.h>
+
+static OPT_PAIR conv_forms[] = {
+    {"compressed", POINT_CONVERSION_COMPRESSED},
+    {"uncompressed", POINT_CONVERSION_UNCOMPRESSED},
+    {"hybrid", POINT_CONVERSION_HYBRID},
+    {NULL}
+};
+
+static OPT_PAIR param_enc[] = {
+    {"named_curve", OPENSSL_EC_NAMED_CURVE},
+    {"explicit", 0},
+    {NULL}
+};
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_IN, OPT_OUT,
+    OPT_NOOUT, OPT_TEXT, OPT_PARAM_OUT, OPT_PUBIN, OPT_PUBOUT,
+    OPT_PASSIN, OPT_PASSOUT, OPT_PARAM_ENC, OPT_CONV_FORM, OPT_CIPHER,
+    OPT_NO_PUBLIC, OPT_CHECK
+} OPTION_CHOICE;
+
+OPTIONS ec_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"in", OPT_IN, 's', "Input file"},
+    {"inform", OPT_INFORM, 'f', "Input format - DER or PEM"},
+    {"out", OPT_OUT, '>', "Output file"},
+    {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"},
+    {"noout", OPT_NOOUT, '-', "Don't print key out"},
+    {"text", OPT_TEXT, '-', "Print the key"},
+    {"param_out", OPT_PARAM_OUT, '-', "Print the elliptic curve parameters"},
+    {"pubin", OPT_PUBIN, '-', "Expect a public key in input file"},
+    {"pubout", OPT_PUBOUT, '-', "Output public key, not private"},
+    {"no_public", OPT_NO_PUBLIC, '-', "exclude public key from private key"},
+    {"check", OPT_CHECK, '-', "check key consistency"},
+    {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
+    {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
+    {"param_enc", OPT_PARAM_ENC, 's',
+     "Specifies the way the ec parameters are encoded"},
+    {"conv_form", OPT_CONV_FORM, 's', "Specifies the point conversion form "},
+    {"", OPT_CIPHER, '-', "Any supported cipher"},
+# ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+# endif
+    {NULL}
+};
+
+int ec_main(int argc, char **argv)
+{
+    BIO *in = NULL, *out = NULL;
+    ENGINE *e = NULL;
+    EC_KEY *eckey = NULL;
+    const EC_GROUP *group;
+    const EVP_CIPHER *enc = NULL;
+    point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
+    char *infile = NULL, *outfile = NULL, *prog;
+    char *passin = NULL, *passout = NULL, *passinarg = NULL, *passoutarg = NULL;
+    OPTION_CHOICE o;
+    int asn1_flag = OPENSSL_EC_NAMED_CURVE, new_form = 0, new_asn1_flag = 0;
+    int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, noout = 0;
+    int pubin = 0, pubout = 0, param_out = 0, i, ret = 1, private = 0;
+    int no_public = 0, check = 0;
+
+    prog = opt_init(argc, argv, ec_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(ec_options);
+            ret = 0;
+            goto end;
+        case OPT_INFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat))
+                goto opthelp;
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUTFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
+                goto opthelp;
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_NOOUT:
+            noout = 1;
+            break;
+        case OPT_TEXT:
+            text = 1;
+            break;
+        case OPT_PARAM_OUT:
+            param_out = 1;
+            break;
+        case OPT_PUBIN:
+            pubin = 1;
+            break;
+        case OPT_PUBOUT:
+            pubout = 1;
+            break;
+        case OPT_PASSIN:
+            passinarg = opt_arg();
+            break;
+        case OPT_PASSOUT:
+            passoutarg = opt_arg();
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        case OPT_CIPHER:
+            if (!opt_cipher(opt_unknown(), &enc))
+                goto opthelp;
+            break;
+        case OPT_CONV_FORM:
+            if (!opt_pair(opt_arg(), conv_forms, &i))
+                goto opthelp;
+            new_form = 1;
+            form = i;
+            break;
+        case OPT_PARAM_ENC:
+            if (!opt_pair(opt_arg(), param_enc, &i))
+                goto opthelp;
+            new_asn1_flag = 1;
+            asn1_flag = i;
+            break;
+        case OPT_NO_PUBLIC:
+            no_public = 1;
+            break;
+        case OPT_CHECK:
+            check = 1;
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    private = param_out || pubin || pubout ? 0 : 1;
+    if (text && !pubin)
+        private = 1;
+
+    if (!app_passwd(passinarg, passoutarg, &passin, &passout)) {
+        BIO_printf(bio_err, "Error getting passwords\n");
+        goto end;
+    }
+
+    if (informat != FORMAT_ENGINE) {
+        in = bio_open_default(infile, 'r', informat);
+        if (in == NULL)
+            goto end;
+    }
+
+    BIO_printf(bio_err, "read EC key\n");
+    if (informat == FORMAT_ASN1) {
+        if (pubin)
+            eckey = d2i_EC_PUBKEY_bio(in, NULL);
+        else
+            eckey = d2i_ECPrivateKey_bio(in, NULL);
+    } else if (informat == FORMAT_ENGINE) {
+        EVP_PKEY *pkey;
+        if (pubin)
+            pkey = load_pubkey(infile, informat , 1, passin, e, "Public Key");
+        else
+            pkey = load_key(infile, informat, 1, passin, e, "Private Key");
+        if (pkey != NULL) {
+            eckey = EVP_PKEY_get1_EC_KEY(pkey);
+            EVP_PKEY_free(pkey);
+        }
+    } else {
+        if (pubin)
+            eckey = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, NULL);
+        else
+            eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL, passin);
+    }
+    if (eckey == NULL) {
+        BIO_printf(bio_err, "unable to load Key\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    out = bio_open_owner(outfile, outformat, private);
+    if (out == NULL)
+        goto end;
+
+    group = EC_KEY_get0_group(eckey);
+
+    if (new_form)
+        EC_KEY_set_conv_form(eckey, form);
+
+    if (new_asn1_flag)
+        EC_KEY_set_asn1_flag(eckey, asn1_flag);
+
+    if (no_public)
+        EC_KEY_set_enc_flags(eckey, EC_PKEY_NO_PUBKEY);
+
+    if (text) {
+        assert(pubin || private);
+        if (!EC_KEY_print(out, eckey, 0)) {
+            perror(outfile);
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    if (check) {
+        if (EC_KEY_check_key(eckey) == 1) {
+            BIO_printf(bio_err, "EC Key valid.\n");
+        } else {
+            BIO_printf(bio_err, "EC Key Invalid!\n");
+            ERR_print_errors(bio_err);
+        }
+    }
+
+    if (noout) {
+        ret = 0;
+        goto end;
+    }
+
+    BIO_printf(bio_err, "writing EC key\n");
+    if (outformat == FORMAT_ASN1) {
+        if (param_out)
+            i = i2d_ECPKParameters_bio(out, group);
+        else if (pubin || pubout)
+            i = i2d_EC_PUBKEY_bio(out, eckey);
+        else {
+            assert(private);
+            i = i2d_ECPrivateKey_bio(out, eckey);
+        }
+    } else {
+        if (param_out)
+            i = PEM_write_bio_ECPKParameters(out, group);
+        else if (pubin || pubout)
+            i = PEM_write_bio_EC_PUBKEY(out, eckey);
+        else {
+            assert(private);
+            i = PEM_write_bio_ECPrivateKey(out, eckey, enc,
+                                           NULL, 0, NULL, passout);
+        }
+    }
+
+    if (!i) {
+        BIO_printf(bio_err, "unable to write private key\n");
+        ERR_print_errors(bio_err);
+    } else
+        ret = 0;
+ end:
+    BIO_free(in);
+    BIO_free_all(out);
+    EC_KEY_free(eckey);
+    release_engine(e);
+    OPENSSL_free(passin);
+    OPENSSL_free(passout);
+    return (ret);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/ecparam.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/ecparam.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/ecparam.c	(revision 331)
@@ -0,0 +1,465 @@
+/*
+ * Copyright 2002-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#include <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_EC
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <time.h>
+# include <string.h>
+# include "apps.h"
+# include <openssl/bio.h>
+# include <openssl/err.h>
+# include <openssl/bn.h>
+# include <openssl/ec.h>
+# include <openssl/x509.h>
+# include <openssl/pem.h>
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT, OPT_C,
+    OPT_CHECK, OPT_LIST_CURVES, OPT_NO_SEED, OPT_NOOUT, OPT_NAME,
+    OPT_CONV_FORM, OPT_PARAM_ENC, OPT_GENKEY, OPT_RAND, OPT_ENGINE
+} OPTION_CHOICE;
+
+OPTIONS ecparam_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"inform", OPT_INFORM, 'F', "Input format - default PEM (DER or PEM)"},
+    {"outform", OPT_OUTFORM, 'F', "Output format - default PEM"},
+    {"in", OPT_IN, '<', "Input file  - default stdin"},
+    {"out", OPT_OUT, '>', "Output file - default stdout"},
+    {"text", OPT_TEXT, '-', "Print the ec parameters in text form"},
+    {"C", OPT_C, '-', "Print a 'C' function creating the parameters"},
+    {"check", OPT_CHECK, '-', "Validate the ec parameters"},
+    {"list_curves", OPT_LIST_CURVES, '-',
+     "Prints a list of all curve 'short names'"},
+    {"no_seed", OPT_NO_SEED, '-',
+     "If 'explicit' parameters are chosen do not use the seed"},
+    {"noout", OPT_NOOUT, '-', "Do not print the ec parameter"},
+    {"name", OPT_NAME, 's',
+     "Use the ec parameters with specified 'short name'"},
+    {"conv_form", OPT_CONV_FORM, 's', "Specifies the point conversion form "},
+    {"param_enc", OPT_PARAM_ENC, 's',
+     "Specifies the way the ec parameters are encoded"},
+    {"genkey", OPT_GENKEY, '-', "Generate ec key"},
+    {"rand", OPT_RAND, 's', "Files to use for random number input"},
+# ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+# endif
+    {NULL}
+};
+
+static OPT_PAIR forms[] = {
+    {"compressed", POINT_CONVERSION_COMPRESSED},
+    {"uncompressed", POINT_CONVERSION_UNCOMPRESSED},
+    {"hybrid", POINT_CONVERSION_HYBRID},
+    {NULL}
+};
+
+static OPT_PAIR encodings[] = {
+    {"named_curve", OPENSSL_EC_NAMED_CURVE},
+    {"explicit", 0},
+    {NULL}
+};
+
+int ecparam_main(int argc, char **argv)
+{
+    ENGINE *e = NULL;
+    BIGNUM *ec_gen = NULL, *ec_order = NULL, *ec_cofactor = NULL;
+    BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL;
+    BIO *in = NULL, *out = NULL;
+    EC_GROUP *group = NULL;
+    point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
+    char *curve_name = NULL, *inrand = NULL;
+    char *infile = NULL, *outfile = NULL, *prog;
+    unsigned char *buffer = NULL;
+    OPTION_CHOICE o;
+    int asn1_flag = OPENSSL_EC_NAMED_CURVE, new_asn1_flag = 0;
+    int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0;
+    int ret = 1, private = 0;
+    int list_curves = 0, no_seed = 0, check = 0, new_form = 0;
+    int text = 0, i, need_rand = 0, genkey = 0;
+
+    prog = opt_init(argc, argv, ecparam_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(ecparam_options);
+            ret = 0;
+            goto end;
+        case OPT_INFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
+                goto opthelp;
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUTFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
+                goto opthelp;
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_TEXT:
+            text = 1;
+            break;
+        case OPT_C:
+            C = 1;
+            break;
+        case OPT_CHECK:
+            check = 1;
+            break;
+        case OPT_LIST_CURVES:
+            list_curves = 1;
+            break;
+        case OPT_NO_SEED:
+            no_seed = 1;
+            break;
+        case OPT_NOOUT:
+            noout = 1;
+            break;
+        case OPT_NAME:
+            curve_name = opt_arg();
+            break;
+        case OPT_CONV_FORM:
+            if (!opt_pair(opt_arg(), forms, &new_form))
+                goto opthelp;
+            form = new_form;
+            new_form = 1;
+            break;
+        case OPT_PARAM_ENC:
+            if (!opt_pair(opt_arg(), encodings, &asn1_flag))
+                goto opthelp;
+            new_asn1_flag = 1;
+            break;
+        case OPT_GENKEY:
+            genkey = need_rand = 1;
+            break;
+        case OPT_RAND:
+            inrand = opt_arg();
+            need_rand = 1;
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    private = genkey ? 1 : 0;
+
+    in = bio_open_default(infile, 'r', informat);
+    if (in == NULL)
+        goto end;
+    out = bio_open_owner(outfile, outformat, private);
+    if (out == NULL)
+        goto end;
+
+    if (list_curves) {
+        EC_builtin_curve *curves = NULL;
+        size_t crv_len = EC_get_builtin_curves(NULL, 0);
+        size_t n;
+
+        curves = app_malloc((int)sizeof(*curves) * crv_len, "list curves");
+        if (!EC_get_builtin_curves(curves, crv_len)) {
+            OPENSSL_free(curves);
+            goto end;
+        }
+
+        for (n = 0; n < crv_len; n++) {
+            const char *comment;
+            const char *sname;
+            comment = curves[n].comment;
+            sname = OBJ_nid2sn(curves[n].nid);
+            if (comment == NULL)
+                comment = "CURVE DESCRIPTION NOT AVAILABLE";
+            if (sname == NULL)
+                sname = "";
+
+            BIO_printf(out, "  %-10s: ", sname);
+            BIO_printf(out, "%s\n", comment);
+        }
+
+        OPENSSL_free(curves);
+        ret = 0;
+        goto end;
+    }
+
+    if (curve_name != NULL) {
+        int nid;
+
+        /*
+         * workaround for the SECG curve names secp192r1 and secp256r1 (which
+         * are the same as the curves prime192v1 and prime256v1 defined in
+         * X9.62)
+         */
+        if (strcmp(curve_name, "secp192r1") == 0) {
+            BIO_printf(bio_err, "using curve name prime192v1 "
+                       "instead of secp192r1\n");
+            nid = NID_X9_62_prime192v1;
+        } else if (strcmp(curve_name, "secp256r1") == 0) {
+            BIO_printf(bio_err, "using curve name prime256v1 "
+                       "instead of secp256r1\n");
+            nid = NID_X9_62_prime256v1;
+        } else
+            nid = OBJ_sn2nid(curve_name);
+
+        if (nid == 0)
+            nid = EC_curve_nist2nid(curve_name);
+
+        if (nid == 0) {
+            BIO_printf(bio_err, "unknown curve name (%s)\n", curve_name);
+            goto end;
+        }
+
+        group = EC_GROUP_new_by_curve_name(nid);
+        if (group == NULL) {
+            BIO_printf(bio_err, "unable to create curve (%s)\n", curve_name);
+            goto end;
+        }
+        EC_GROUP_set_asn1_flag(group, asn1_flag);
+        EC_GROUP_set_point_conversion_form(group, form);
+    } else if (informat == FORMAT_ASN1)
+        group = d2i_ECPKParameters_bio(in, NULL);
+    else
+        group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
+    if (group == NULL) {
+        BIO_printf(bio_err, "unable to load elliptic curve parameters\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    if (new_form)
+        EC_GROUP_set_point_conversion_form(group, form);
+
+    if (new_asn1_flag)
+        EC_GROUP_set_asn1_flag(group, asn1_flag);
+
+    if (no_seed) {
+        EC_GROUP_set_seed(group, NULL, 0);
+    }
+
+    if (text) {
+        if (!ECPKParameters_print(out, group, 0))
+            goto end;
+    }
+
+    if (check) {
+        BIO_printf(bio_err, "checking elliptic curve parameters: ");
+        if (!EC_GROUP_check(group, NULL)) {
+            BIO_printf(bio_err, "failed\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        BIO_printf(bio_err, "ok\n");
+
+    }
+
+    if (C) {
+        size_t buf_len = 0, tmp_len = 0;
+        const EC_POINT *point;
+        int is_prime, len = 0;
+        const EC_METHOD *meth = EC_GROUP_method_of(group);
+
+        if ((ec_p = BN_new()) == NULL
+                || (ec_a = BN_new()) == NULL
+                || (ec_b = BN_new()) == NULL
+                || (ec_gen = BN_new()) == NULL
+                || (ec_order = BN_new()) == NULL
+                || (ec_cofactor = BN_new()) == NULL) {
+            perror("Can't allocate BN");
+            goto end;
+        }
+
+        is_prime = (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field);
+        if (!is_prime) {
+            BIO_printf(bio_err, "Can only handle X9.62 prime fields\n");
+            goto end;
+        }
+
+        if (!EC_GROUP_get_curve_GFp(group, ec_p, ec_a, ec_b, NULL))
+            goto end;
+
+        if ((point = EC_GROUP_get0_generator(group)) == NULL)
+            goto end;
+        if (!EC_POINT_point2bn(group, point,
+                               EC_GROUP_get_point_conversion_form(group),
+                               ec_gen, NULL))
+            goto end;
+        if (!EC_GROUP_get_order(group, ec_order, NULL))
+            goto end;
+        if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL))
+            goto end;
+
+        if (!ec_p || !ec_a || !ec_b || !ec_gen || !ec_order || !ec_cofactor)
+            goto end;
+
+        len = BN_num_bits(ec_order);
+
+        if ((tmp_len = (size_t)BN_num_bytes(ec_p)) > buf_len)
+            buf_len = tmp_len;
+        if ((tmp_len = (size_t)BN_num_bytes(ec_a)) > buf_len)
+            buf_len = tmp_len;
+        if ((tmp_len = (size_t)BN_num_bytes(ec_b)) > buf_len)
+            buf_len = tmp_len;
+        if ((tmp_len = (size_t)BN_num_bytes(ec_gen)) > buf_len)
+            buf_len = tmp_len;
+        if ((tmp_len = (size_t)BN_num_bytes(ec_order)) > buf_len)
+            buf_len = tmp_len;
+        if ((tmp_len = (size_t)BN_num_bytes(ec_cofactor)) > buf_len)
+            buf_len = tmp_len;
+
+        buffer = app_malloc(buf_len, "BN buffer");
+
+        BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n{\n", len);
+        print_bignum_var(out, ec_p, "ec_p", len, buffer);
+        print_bignum_var(out, ec_a, "ec_a", len, buffer);
+        print_bignum_var(out, ec_b, "ec_b", len, buffer);
+        print_bignum_var(out, ec_gen, "ec_gen", len, buffer);
+        print_bignum_var(out, ec_order, "ec_order", len, buffer);
+        print_bignum_var(out, ec_cofactor, "ec_cofactor", len, buffer);
+        BIO_printf(out, "    int ok = 0;\n"
+                        "    EC_GROUP *group = NULL;\n"
+                        "    EC_POINT *point = NULL;\n"
+                        "    BIGNUM *tmp_1 = NULL;\n"
+                        "    BIGNUM *tmp_2 = NULL;\n"
+                        "    BIGNUM *tmp_3 = NULL;\n"
+                        "\n");
+
+        BIO_printf(out, "    if ((tmp_1 = BN_bin2bn(ec_p_%d, sizeof (ec_p_%d), NULL)) == NULL)\n"
+                        "        goto err;\n", len, len);
+        BIO_printf(out, "    if ((tmp_2 = BN_bin2bn(ec_a_%d, sizeof (ec_a_%d), NULL)) == NULL)\n"
+                        "        goto err;\n", len, len);
+        BIO_printf(out, "    if ((tmp_3 = BN_bin2bn(ec_b_%d, sizeof (ec_b_%d), NULL)) == NULL)\n"
+                        "        goto err;\n", len, len);
+        BIO_printf(out, "    if ((group = EC_GROUP_new_curve_GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)\n"
+                        "        goto err;\n"
+                        "\n");
+        BIO_printf(out, "    /* build generator */\n");
+        BIO_printf(out, "    if ((tmp_1 = BN_bin2bn(ec_gen_%d, sizeof (ec_gen_%d), tmp_1)) == NULL)\n"
+                        "        goto err;\n", len, len);
+        BIO_printf(out, "    point = EC_POINT_bn2point(group, tmp_1, NULL, NULL);\n");
+        BIO_printf(out, "    if (point == NULL)\n"
+                        "        goto err;\n");
+        BIO_printf(out, "    if ((tmp_2 = BN_bin2bn(ec_order_%d, sizeof (ec_order_%d), tmp_2)) == NULL)\n"
+                        "        goto err;\n", len, len);
+        BIO_printf(out, "    if ((tmp_3 = BN_bin2bn(ec_cofactor_%d, sizeof (ec_cofactor_%d), tmp_3)) == NULL)\n"
+                        "        goto err;\n", len, len);
+        BIO_printf(out, "    if (!EC_GROUP_set_generator(group, point, tmp_2, tmp_3))\n"
+                        "        goto err;\n"
+                        "ok = 1;"
+                        "\n");
+        BIO_printf(out, "err:\n"
+                        "    BN_free(tmp_1);\n"
+                        "    BN_free(tmp_2);\n"
+                        "    BN_free(tmp_3);\n"
+                        "    EC_POINT_free(point);\n"
+                        "    if (!ok) {\n"
+                        "        EC_GROUP_free(group);\n"
+                        "        return NULL;\n"
+                        "    }\n"
+                        "    return (group);\n"
+                        "}\n");
+    }
+
+    if (!noout) {
+        if (outformat == FORMAT_ASN1)
+            i = i2d_ECPKParameters_bio(out, group);
+        else
+            i = PEM_write_bio_ECPKParameters(out, group);
+        if (!i) {
+            BIO_printf(bio_err, "unable to write elliptic "
+                       "curve parameters\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    if (need_rand) {
+        app_RAND_load_file(NULL, (inrand != NULL));
+        if (inrand != NULL)
+            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
+                       app_RAND_load_files(inrand));
+    }
+
+    if (genkey) {
+        EC_KEY *eckey = EC_KEY_new();
+
+        if (eckey == NULL)
+            goto end;
+
+        assert(need_rand);
+
+        if (EC_KEY_set_group(eckey, group) == 0) {
+            BIO_printf(bio_err, "unable to set group when generating key\n");
+            EC_KEY_free(eckey);
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+
+        if (!EC_KEY_generate_key(eckey)) {
+            BIO_printf(bio_err, "unable to generate key\n");
+            EC_KEY_free(eckey);
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        assert(private);
+        if (outformat == FORMAT_ASN1)
+            i = i2d_ECPrivateKey_bio(out, eckey);
+        else
+            i = PEM_write_bio_ECPrivateKey(out, eckey, NULL,
+                                           NULL, 0, NULL, NULL);
+        EC_KEY_free(eckey);
+    }
+
+    if (need_rand)
+        app_RAND_write_file(NULL);
+
+    ret = 0;
+ end:
+    BN_free(ec_p);
+    BN_free(ec_a);
+    BN_free(ec_b);
+    BN_free(ec_gen);
+    BN_free(ec_order);
+    BN_free(ec_cofactor);
+    OPENSSL_free(buffer);
+    EC_GROUP_free(group);
+    release_engine(e);
+    BIO_free(in);
+    BIO_free_all(out);
+    return (ret);
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/enc.c	(revision 331)
@@ -0,0 +1,604 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/rand.h>
+#include <openssl/pem.h>
+#ifndef OPENSSL_NO_COMP
+# include <openssl/comp.h>
+#endif
+#include <ctype.h>
+
+#undef SIZE
+#undef BSIZE
+#define SIZE    (512)
+#define BSIZE   (8*1024)
+
+static int set_hex(char *in, unsigned char *out, int size);
+static void show_ciphers(const OBJ_NAME *name, void *bio_);
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_LIST,
+    OPT_E, OPT_IN, OPT_OUT, OPT_PASS, OPT_ENGINE, OPT_D, OPT_P, OPT_V,
+    OPT_NOPAD, OPT_SALT, OPT_NOSALT, OPT_DEBUG, OPT_UPPER_P, OPT_UPPER_A,
+    OPT_A, OPT_Z, OPT_BUFSIZE, OPT_K, OPT_KFILE, OPT_UPPER_K, OPT_NONE,
+    OPT_UPPER_S, OPT_IV, OPT_MD, OPT_CIPHER
+} OPTION_CHOICE;
+
+OPTIONS enc_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"ciphers", OPT_LIST, '-', "List ciphers"},
+    {"in", OPT_IN, '<', "Input file"},
+    {"out", OPT_OUT, '>', "Output file"},
+    {"pass", OPT_PASS, 's', "Passphrase source"},
+    {"e", OPT_E, '-', "Encrypt"},
+    {"d", OPT_D, '-', "Decrypt"},
+    {"p", OPT_P, '-', "Print the iv/key"},
+    {"P", OPT_UPPER_P, '-', "Print the iv/key and exit"},
+    {"v", OPT_V, '-', "Verbose output"},
+    {"nopad", OPT_NOPAD, '-', "Disable standard block padding"},
+    {"salt", OPT_SALT, '-', "Use salt in the KDF (default)"},
+    {"nosalt", OPT_NOSALT, '-', "Do not use salt in the KDF"},
+    {"debug", OPT_DEBUG, '-', "Print debug info"},
+    {"a", OPT_A, '-', "Base64 encode/decode, depending on encryption flag"},
+    {"base64", OPT_A, '-', "Same as option -a"},
+    {"A", OPT_UPPER_A, '-',
+     "Used with -[base64|a] to specify base64 buffer as a single line"},
+    {"bufsize", OPT_BUFSIZE, 's', "Buffer size"},
+    {"k", OPT_K, 's', "Passphrase"},
+    {"kfile", OPT_KFILE, '<', "Read passphrase from file"},
+    {"K", OPT_UPPER_K, 's', "Raw key, in hex"},
+    {"S", OPT_UPPER_S, 's', "Salt, in hex"},
+    {"iv", OPT_IV, 's', "IV in hex"},
+    {"md", OPT_MD, 's', "Use specified digest to create a key from the passphrase"},
+    {"none", OPT_NONE, '-', "Don't encrypt"},
+    {"", OPT_CIPHER, '-', "Any supported cipher"},
+#ifdef ZLIB
+    {"z", OPT_Z, '-', "Use zlib as the 'encryption'"},
+#endif
+#ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+#endif
+    {NULL}
+};
+
+int enc_main(int argc, char **argv)
+{
+    static char buf[128];
+    static const char magic[] = "Salted__";
+    ENGINE *e = NULL;
+    BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL, *rbio =
+        NULL, *wbio = NULL;
+    EVP_CIPHER_CTX *ctx = NULL;
+    const EVP_CIPHER *cipher = NULL, *c;
+    const EVP_MD *dgst = NULL;
+    char *hkey = NULL, *hiv = NULL, *hsalt = NULL, *p;
+    char *infile = NULL, *outfile = NULL, *prog;
+    char *str = NULL, *passarg = NULL, *pass = NULL, *strbuf = NULL;
+    char mbuf[sizeof magic - 1];
+    OPTION_CHOICE o;
+    int bsize = BSIZE, verbose = 0, debug = 0, olb64 = 0, nosalt = 0;
+    int enc = 1, printkey = 0, i, k;
+    int base64 = 0, informat = FORMAT_BINARY, outformat = FORMAT_BINARY;
+    int ret = 1, inl, nopad = 0;
+    unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
+    unsigned char *buff = NULL, salt[PKCS5_SALT_LEN];
+    long n;
+#ifdef ZLIB
+    int do_zlib = 0;
+    BIO *bzl = NULL;
+#endif
+
+    /* first check the program name */
+    prog = opt_progname(argv[0]);
+    if (strcmp(prog, "base64") == 0)
+        base64 = 1;
+#ifdef ZLIB
+    else if (strcmp(prog, "zlib") == 0)
+        do_zlib = 1;
+#endif
+    else {
+        cipher = EVP_get_cipherbyname(prog);
+        if (cipher == NULL && strcmp(prog, "enc") != 0) {
+            BIO_printf(bio_err, "%s is not a known cipher\n", prog);
+            goto end;
+        }
+    }
+
+    prog = opt_init(argc, argv, enc_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(enc_options);
+            ret = 0;
+            goto end;
+        case OPT_LIST:
+            BIO_printf(bio_err, "Supported ciphers:\n");
+            OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
+                                   show_ciphers, bio_err);
+            BIO_printf(bio_err, "\n");
+            goto end;
+        case OPT_E:
+            enc = 1;
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_PASS:
+            passarg = opt_arg();
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        case OPT_D:
+            enc = 0;
+            break;
+        case OPT_P:
+            printkey = 1;
+            break;
+        case OPT_V:
+            verbose = 1;
+            break;
+        case OPT_NOPAD:
+            nopad = 1;
+            break;
+        case OPT_SALT:
+            nosalt = 0;
+            break;
+        case OPT_NOSALT:
+            nosalt = 1;
+            break;
+        case OPT_DEBUG:
+            debug = 1;
+            break;
+        case OPT_UPPER_P:
+            printkey = 2;
+            break;
+        case OPT_UPPER_A:
+            olb64 = 1;
+            break;
+        case OPT_A:
+            base64 = 1;
+            break;
+        case OPT_Z:
+#ifdef ZLIB
+            do_zlib = 1;
+#endif
+            break;
+        case OPT_BUFSIZE:
+            p = opt_arg();
+            i = (int)strlen(p) - 1;
+            k = i >= 1 && p[i] == 'k';
+            if (k)
+                p[i] = '\0';
+            if (!opt_long(opt_arg(), &n)
+                    || n < 0 || (k && n >= LONG_MAX / 1024))
+                goto opthelp;
+            if (k)
+                n *= 1024;
+            bsize = (int)n;
+            break;
+        case OPT_K:
+            str = opt_arg();
+            break;
+        case OPT_KFILE:
+            in = bio_open_default(opt_arg(), 'r', FORMAT_TEXT);
+            if (in == NULL)
+                goto opthelp;
+            i = BIO_gets(in, buf, sizeof buf);
+            BIO_free(in);
+            in = NULL;
+            if (i <= 0) {
+                BIO_printf(bio_err,
+                           "%s Can't read key from %s\n", prog, opt_arg());
+                goto opthelp;
+            }
+            while (--i > 0 && (buf[i] == '\r' || buf[i] == '\n'))
+                buf[i] = '\0';
+            if (i <= 0) {
+                BIO_printf(bio_err, "%s: zero length password\n", prog);
+                goto opthelp;
+            }
+            str = buf;
+            break;
+        case OPT_UPPER_K:
+            hkey = opt_arg();
+            break;
+        case OPT_UPPER_S:
+            hsalt = opt_arg();
+            break;
+        case OPT_IV:
+            hiv = opt_arg();
+            break;
+        case OPT_MD:
+            if (!opt_md(opt_arg(), &dgst))
+                goto opthelp;
+            break;
+        case OPT_CIPHER:
+            if (!opt_cipher(opt_unknown(), &c))
+                goto opthelp;
+            cipher = c;
+            break;
+        case OPT_NONE:
+            cipher = NULL;
+            break;
+        }
+    }
+
+    if (cipher && EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) {
+        BIO_printf(bio_err, "%s: AEAD ciphers not supported\n", prog);
+        goto end;
+    }
+
+    if (cipher && (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE)) {
+        BIO_printf(bio_err, "%s XTS ciphers not supported\n", prog);
+        goto end;
+    }
+
+    if (dgst == NULL)
+        dgst = EVP_sha256();
+
+    /* It must be large enough for a base64 encoded line */
+    if (base64 && bsize < 80)
+        bsize = 80;
+    if (verbose)
+        BIO_printf(bio_err, "bufsize=%d\n", bsize);
+
+#ifdef ZLIB
+    if (!do_zlib)
+#endif
+        if (base64) {
+            if (enc)
+                outformat = FORMAT_BASE64;
+            else
+                informat = FORMAT_BASE64;
+        }
+
+    strbuf = app_malloc(SIZE, "strbuf");
+    buff = app_malloc(EVP_ENCODE_LENGTH(bsize), "evp buffer");
+
+    if (infile == NULL) {
+        unbuffer(stdin);
+        in = dup_bio_in(informat);
+    } else
+        in = bio_open_default(infile, 'r', informat);
+    if (in == NULL)
+        goto end;
+
+    if (!str && passarg) {
+        if (!app_passwd(passarg, NULL, &pass, NULL)) {
+            BIO_printf(bio_err, "Error getting password\n");
+            goto end;
+        }
+        str = pass;
+    }
+
+    if ((str == NULL) && (cipher != NULL) && (hkey == NULL)) {
+        if (1) {
+#ifndef OPENSSL_NO_UI
+            for (;;) {
+                char prompt[200];
+
+                BIO_snprintf(prompt, sizeof prompt, "enter %s %s password:",
+                             OBJ_nid2ln(EVP_CIPHER_nid(cipher)),
+                             (enc) ? "encryption" : "decryption");
+                strbuf[0] = '\0';
+                i = EVP_read_pw_string((char *)strbuf, SIZE, prompt, enc);
+                if (i == 0) {
+                    if (strbuf[0] == '\0') {
+                        ret = 1;
+                        goto end;
+                    }
+                    str = strbuf;
+                    break;
+                }
+                if (i < 0) {
+                    BIO_printf(bio_err, "bad password read\n");
+                    goto end;
+                }
+            }
+        } else {
+#endif
+            BIO_printf(bio_err, "password required\n");
+            goto end;
+        }
+    }
+
+    out = bio_open_default(outfile, 'w', outformat);
+    if (out == NULL)
+        goto end;
+
+    if (debug) {
+        BIO_set_callback(in, BIO_debug_callback);
+        BIO_set_callback(out, BIO_debug_callback);
+        BIO_set_callback_arg(in, (char *)bio_err);
+        BIO_set_callback_arg(out, (char *)bio_err);
+    }
+
+    rbio = in;
+    wbio = out;
+
+#ifdef ZLIB
+    if (do_zlib) {
+        if ((bzl = BIO_new(BIO_f_zlib())) == NULL)
+            goto end;
+        if (debug) {
+            BIO_set_callback(bzl, BIO_debug_callback);
+            BIO_set_callback_arg(bzl, (char *)bio_err);
+        }
+        if (enc)
+            wbio = BIO_push(bzl, wbio);
+        else
+            rbio = BIO_push(bzl, rbio);
+    }
+#endif
+
+    if (base64) {
+        if ((b64 = BIO_new(BIO_f_base64())) == NULL)
+            goto end;
+        if (debug) {
+            BIO_set_callback(b64, BIO_debug_callback);
+            BIO_set_callback_arg(b64, (char *)bio_err);
+        }
+        if (olb64)
+            BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
+        if (enc)
+            wbio = BIO_push(b64, wbio);
+        else
+            rbio = BIO_push(b64, rbio);
+    }
+
+    if (cipher != NULL) {
+        /*
+         * Note that str is NULL if a key was passed on the command line, so
+         * we get no salt in that case. Is this a bug?
+         */
+        if (str != NULL) {
+            /*
+             * Salt handling: if encrypting generate a salt and write to
+             * output BIO. If decrypting read salt from input BIO.
+             */
+            unsigned char *sptr;
+            size_t str_len = strlen(str);
+
+            if (nosalt)
+                sptr = NULL;
+            else {
+                if (enc) {
+                    if (hsalt) {
+                        if (!set_hex(hsalt, salt, sizeof salt)) {
+                            BIO_printf(bio_err, "invalid hex salt value\n");
+                            goto end;
+                        }
+                    } else if (RAND_bytes(salt, sizeof salt) <= 0)
+                        goto end;
+                    /*
+                     * If -P option then don't bother writing
+                     */
+                    if ((printkey != 2)
+                        && (BIO_write(wbio, magic,
+                                      sizeof magic - 1) != sizeof magic - 1
+                            || BIO_write(wbio,
+                                         (char *)salt,
+                                         sizeof salt) != sizeof salt)) {
+                        BIO_printf(bio_err, "error writing output file\n");
+                        goto end;
+                    }
+                } else if (BIO_read(rbio, mbuf, sizeof mbuf) != sizeof mbuf
+                           || BIO_read(rbio,
+                                       (unsigned char *)salt,
+                                       sizeof salt) != sizeof salt) {
+                    BIO_printf(bio_err, "error reading input file\n");
+                    goto end;
+                } else if (memcmp(mbuf, magic, sizeof magic - 1)) {
+                    BIO_printf(bio_err, "bad magic number\n");
+                    goto end;
+                }
+
+                sptr = salt;
+            }
+
+            if (!EVP_BytesToKey(cipher, dgst, sptr,
+                                (unsigned char *)str,
+                                str_len, 1, key, iv)) {
+                BIO_printf(bio_err, "EVP_BytesToKey failed\n");
+                goto end;
+            }
+            /*
+             * zero the complete buffer or the string passed from the command
+             * line bug picked up by Larry J. Hughes Jr. <hughes@indiana.edu>
+             */
+            if (str == strbuf)
+                OPENSSL_cleanse(str, SIZE);
+            else
+                OPENSSL_cleanse(str, str_len);
+        }
+        if (hiv != NULL) {
+            int siz = EVP_CIPHER_iv_length(cipher);
+            if (siz == 0) {
+                BIO_printf(bio_err, "warning: iv not use by this cipher\n");
+            } else if (!set_hex(hiv, iv, sizeof iv)) {
+                BIO_printf(bio_err, "invalid hex iv value\n");
+                goto end;
+            }
+        }
+        if ((hiv == NULL) && (str == NULL)
+            && EVP_CIPHER_iv_length(cipher) != 0) {
+            /*
+             * No IV was explicitly set and no IV was generated during
+             * EVP_BytesToKey. Hence the IV is undefined, making correct
+             * decryption impossible.
+             */
+            BIO_printf(bio_err, "iv undefined\n");
+            goto end;
+        }
+        if ((hkey != NULL) && !set_hex(hkey, key, EVP_CIPHER_key_length(cipher))) {
+            BIO_printf(bio_err, "invalid hex key value\n");
+            goto end;
+        }
+
+        if ((benc = BIO_new(BIO_f_cipher())) == NULL)
+            goto end;
+
+        /*
+         * Since we may be changing parameters work on the encryption context
+         * rather than calling BIO_set_cipher().
+         */
+
+        BIO_get_cipher_ctx(benc, &ctx);
+
+        if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)) {
+            BIO_printf(bio_err, "Error setting cipher %s\n",
+                       EVP_CIPHER_name(cipher));
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+
+        if (nopad)
+            EVP_CIPHER_CTX_set_padding(ctx, 0);
+
+        if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc)) {
+            BIO_printf(bio_err, "Error setting cipher %s\n",
+                       EVP_CIPHER_name(cipher));
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+
+        if (debug) {
+            BIO_set_callback(benc, BIO_debug_callback);
+            BIO_set_callback_arg(benc, (char *)bio_err);
+        }
+
+        if (printkey) {
+            if (!nosalt) {
+                printf("salt=");
+                for (i = 0; i < (int)sizeof(salt); i++)
+                    printf("%02X", salt[i]);
+                printf("\n");
+            }
+            if (EVP_CIPHER_key_length(cipher) > 0) {
+                printf("key=");
+                for (i = 0; i < EVP_CIPHER_key_length(cipher); i++)
+                    printf("%02X", key[i]);
+                printf("\n");
+            }
+            if (EVP_CIPHER_iv_length(cipher) > 0) {
+                printf("iv =");
+                for (i = 0; i < EVP_CIPHER_iv_length(cipher); i++)
+                    printf("%02X", iv[i]);
+                printf("\n");
+            }
+            if (printkey == 2) {
+                ret = 0;
+                goto end;
+            }
+        }
+    }
+
+    /* Only encrypt/decrypt as we write the file */
+    if (benc != NULL)
+        wbio = BIO_push(benc, wbio);
+
+    for (;;) {
+        inl = BIO_read(rbio, (char *)buff, bsize);
+        if (inl <= 0)
+            break;
+        if (BIO_write(wbio, (char *)buff, inl) != inl) {
+            BIO_printf(bio_err, "error writing output file\n");
+            goto end;
+        }
+    }
+    if (!BIO_flush(wbio)) {
+        BIO_printf(bio_err, "bad decrypt\n");
+        goto end;
+    }
+
+    ret = 0;
+    if (verbose) {
+        BIO_printf(bio_err, "bytes read   :%8"PRIu64"\n", BIO_number_read(in));
+        BIO_printf(bio_err, "bytes written:%8"PRIu64"\n", BIO_number_written(out));
+    }
+ end:
+    ERR_print_errors(bio_err);
+    OPENSSL_free(strbuf);
+    OPENSSL_free(buff);
+    BIO_free(in);
+    BIO_free_all(out);
+    BIO_free(benc);
+    BIO_free(b64);
+#ifdef ZLIB
+    BIO_free(bzl);
+#endif
+    release_engine(e);
+    OPENSSL_free(pass);
+    return (ret);
+}
+
+static void show_ciphers(const OBJ_NAME *name, void *bio_)
+{
+    BIO *bio = bio_;
+    static int n;
+
+    if (!islower((unsigned char)*name->name))
+        return;
+
+    BIO_printf(bio, "-%-25s", name->name);
+    if (++n == 3) {
+        BIO_printf(bio, "\n");
+        n = 0;
+    } else
+        BIO_printf(bio, " ");
+}
+
+static int set_hex(char *in, unsigned char *out, int size)
+{
+    int i, n;
+    unsigned char j;
+
+    n = strlen(in);
+    if (n > (size * 2)) {
+        BIO_printf(bio_err, "hex string is too long\n");
+        return (0);
+    }
+    memset(out, 0, size);
+    for (i = 0; i < n; i++) {
+        j = (unsigned char)*in;
+        *(in++) = '\0';
+        if (j == 0)
+            break;
+        if (!isxdigit(j)) {
+            BIO_printf(bio_err, "non-hex digit\n");
+            return (0);
+        }
+        j = (unsigned char)OPENSSL_hexchar2int(j);
+        if (i & 1)
+            out[i / 2] |= j;
+        else
+            out[i / 2] = (j << 4);
+    }
+    return (1);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/engine.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/engine.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/engine.c	(revision 331)
@@ -0,0 +1,445 @@
+/*
+ * Copyright 2000-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 <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_ENGINE
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include "apps.h"
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+# include <openssl/err.h>
+# include <openssl/engine.h>
+# include <openssl/ssl.h>
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_C, OPT_T, OPT_TT, OPT_PRE, OPT_POST,
+    OPT_V = 100, OPT_VV, OPT_VVV, OPT_VVVV
+} OPTION_CHOICE;
+
+OPTIONS engine_options[] = {
+    {OPT_HELP_STR, 1, '-', "Usage: %s [options] engine...\n"},
+    {OPT_HELP_STR, 1, '-',
+        "  engine... Engines to load\n"},
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"v", OPT_V, '-', "List 'control commands' For each specified engine"},
+    {"vv", OPT_VV, '-', "Also display each command's description"},
+    {"vvv", OPT_VVV, '-', "Also add the input flags for each command"},
+    {"vvvv", OPT_VVVV, '-', "Also show internal input flags"},
+    {"c", OPT_C, '-', "List the capabilities of specified engine"},
+    {"t", OPT_T, '-', "Check that specified engine is available"},
+    {"tt", OPT_TT, '-', "Display error trace for unavailable engines"},
+    {"pre", OPT_PRE, 's', "Run command against the ENGINE before loading it"},
+    {"post", OPT_POST, 's', "Run command against the ENGINE after loading it"},
+    {OPT_MORE_STR, OPT_EOF, 1,
+     "Commands are like \"SO_PATH:/lib/libdriver.so\""},
+    {NULL}
+};
+
+static int append_buf(char **buf, int *size, const char *s)
+{
+    if (*buf == NULL) {
+        *size = 256;
+        *buf = app_malloc(*size, "engine buffer");
+        **buf = '\0';
+    }
+
+    if (strlen(*buf) + strlen(s) >= (unsigned int)*size) {
+        char *tmp;
+        *size += 256;
+        tmp = OPENSSL_realloc(*buf, *size);
+        if (tmp == NULL) {
+            OPENSSL_free(*buf);
+            *buf = NULL;
+            return 0;
+        }
+        *buf = tmp;
+    }
+
+    if (**buf != '\0')
+        OPENSSL_strlcat(*buf, ", ", *size);
+    OPENSSL_strlcat(*buf, s, *size);
+
+    return 1;
+}
+
+static int util_flags(BIO *out, unsigned int flags, const char *indent)
+{
+    int started = 0, err = 0;
+    /* Indent before displaying input flags */
+    BIO_printf(out, "%s%s(input flags): ", indent, indent);
+    if (flags == 0) {
+        BIO_printf(out, "<no flags>\n");
+        return 1;
+    }
+    /*
+     * If the object is internal, mark it in a way that shows instead of
+     * having it part of all the other flags, even if it really is.
+     */
+    if (flags & ENGINE_CMD_FLAG_INTERNAL) {
+        BIO_printf(out, "[Internal] ");
+    }
+
+    if (flags & ENGINE_CMD_FLAG_NUMERIC) {
+        BIO_printf(out, "NUMERIC");
+        started = 1;
+    }
+    /*
+     * Now we check that no combinations of the mutually exclusive NUMERIC,
+     * STRING, and NO_INPUT flags have been used. Future flags that can be
+     * OR'd together with these would need to added after these to preserve
+     * the testing logic.
+     */
+    if (flags & ENGINE_CMD_FLAG_STRING) {
+        if (started) {
+            BIO_printf(out, "|");
+            err = 1;
+        }
+        BIO_printf(out, "STRING");
+        started = 1;
+    }
+    if (flags & ENGINE_CMD_FLAG_NO_INPUT) {
+        if (started) {
+            BIO_printf(out, "|");
+            err = 1;
+        }
+        BIO_printf(out, "NO_INPUT");
+        started = 1;
+    }
+    /* Check for unknown flags */
+    flags = flags & ~ENGINE_CMD_FLAG_NUMERIC &
+        ~ENGINE_CMD_FLAG_STRING &
+        ~ENGINE_CMD_FLAG_NO_INPUT & ~ENGINE_CMD_FLAG_INTERNAL;
+    if (flags) {
+        if (started)
+            BIO_printf(out, "|");
+        BIO_printf(out, "<0x%04X>", flags);
+    }
+    if (err)
+        BIO_printf(out, "  <illegal flags!>");
+    BIO_printf(out, "\n");
+    return 1;
+}
+
+static int util_verbose(ENGINE *e, int verbose, BIO *out, const char *indent)
+{
+    static const int line_wrap = 78;
+    int num;
+    int ret = 0;
+    char *name = NULL;
+    char *desc = NULL;
+    int flags;
+    int xpos = 0;
+    STACK_OF(OPENSSL_STRING) *cmds = NULL;
+    if (!ENGINE_ctrl(e, ENGINE_CTRL_HAS_CTRL_FUNCTION, 0, NULL, NULL) ||
+        ((num = ENGINE_ctrl(e, ENGINE_CTRL_GET_FIRST_CMD_TYPE,
+                            0, NULL, NULL)) <= 0)) {
+        return 1;
+    }
+
+    cmds = sk_OPENSSL_STRING_new_null();
+    if (!cmds)
+        goto err;
+
+    do {
+        int len;
+        /* Get the command input flags */
+        if ((flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num,
+                                 NULL, NULL)) < 0)
+            goto err;
+        if (!(flags & ENGINE_CMD_FLAG_INTERNAL) || verbose >= 4) {
+            /* Get the command name */
+            if ((len = ENGINE_ctrl(e, ENGINE_CTRL_GET_NAME_LEN_FROM_CMD, num,
+                                   NULL, NULL)) <= 0)
+                goto err;
+            name = app_malloc(len + 1, "name buffer");
+            if (ENGINE_ctrl(e, ENGINE_CTRL_GET_NAME_FROM_CMD, num, name,
+                            NULL) <= 0)
+                goto err;
+            /* Get the command description */
+            if ((len = ENGINE_ctrl(e, ENGINE_CTRL_GET_DESC_LEN_FROM_CMD, num,
+                                   NULL, NULL)) < 0)
+                goto err;
+            if (len > 0) {
+                desc = app_malloc(len + 1, "description buffer");
+                if (ENGINE_ctrl(e, ENGINE_CTRL_GET_DESC_FROM_CMD, num, desc,
+                                NULL) <= 0)
+                    goto err;
+            }
+            /* Now decide on the output */
+            if (xpos == 0)
+                /* Do an indent */
+                xpos = BIO_puts(out, indent);
+            else
+                /* Otherwise prepend a ", " */
+                xpos += BIO_printf(out, ", ");
+            if (verbose == 1) {
+                /*
+                 * We're just listing names, comma-delimited
+                 */
+                if ((xpos > (int)strlen(indent)) &&
+                    (xpos + (int)strlen(name) > line_wrap)) {
+                    BIO_printf(out, "\n");
+                    xpos = BIO_puts(out, indent);
+                }
+                xpos += BIO_printf(out, "%s", name);
+            } else {
+                /* We're listing names plus descriptions */
+                BIO_printf(out, "%s: %s\n", name,
+                           (desc == NULL) ? "<no description>" : desc);
+                /* ... and sometimes input flags */
+                if ((verbose >= 3) && !util_flags(out, flags, indent))
+                    goto err;
+                xpos = 0;
+            }
+        }
+        OPENSSL_free(name);
+        name = NULL;
+        OPENSSL_free(desc);
+        desc = NULL;
+        /* Move to the next command */
+        num = ENGINE_ctrl(e, ENGINE_CTRL_GET_NEXT_CMD_TYPE, num, NULL, NULL);
+    } while (num > 0);
+    if (xpos > 0)
+        BIO_printf(out, "\n");
+    ret = 1;
+ err:
+    sk_OPENSSL_STRING_free(cmds);
+    OPENSSL_free(name);
+    OPENSSL_free(desc);
+    return ret;
+}
+
+static void util_do_cmds(ENGINE *e, STACK_OF(OPENSSL_STRING) *cmds,
+                         BIO *out, const char *indent)
+{
+    int loop, res, num = sk_OPENSSL_STRING_num(cmds);
+
+    if (num < 0) {
+        BIO_printf(out, "[Error]: internal stack error\n");
+        return;
+    }
+    for (loop = 0; loop < num; loop++) {
+        char buf[256];
+        const char *cmd, *arg;
+        cmd = sk_OPENSSL_STRING_value(cmds, loop);
+        res = 1;                /* assume success */
+        /* Check if this command has no ":arg" */
+        if ((arg = strstr(cmd, ":")) == NULL) {
+            if (!ENGINE_ctrl_cmd_string(e, cmd, NULL, 0))
+                res = 0;
+        } else {
+            if ((int)(arg - cmd) > 254) {
+                BIO_printf(out, "[Error]: command name too long\n");
+                return;
+            }
+            memcpy(buf, cmd, (int)(arg - cmd));
+            buf[arg - cmd] = '\0';
+            arg++;              /* Move past the ":" */
+            /* Call the command with the argument */
+            if (!ENGINE_ctrl_cmd_string(e, buf, arg, 0))
+                res = 0;
+        }
+        if (res)
+            BIO_printf(out, "[Success]: %s\n", cmd);
+        else {
+            BIO_printf(out, "[Failure]: %s\n", cmd);
+            ERR_print_errors(out);
+        }
+    }
+}
+
+int engine_main(int argc, char **argv)
+{
+    int ret = 1, i;
+    int verbose = 0, list_cap = 0, test_avail = 0, test_avail_noise = 0;
+    ENGINE *e;
+    STACK_OF(OPENSSL_CSTRING) *engines = sk_OPENSSL_CSTRING_new_null();
+    STACK_OF(OPENSSL_STRING) *pre_cmds = sk_OPENSSL_STRING_new_null();
+    STACK_OF(OPENSSL_STRING) *post_cmds = sk_OPENSSL_STRING_new_null();
+    BIO *out;
+    const char *indent = "     ";
+    OPTION_CHOICE o;
+    char *prog;
+    char *argv1;
+
+    out = dup_bio_out(FORMAT_TEXT);
+    if (engines == NULL || pre_cmds == NULL || post_cmds == NULL)
+        goto end;
+
+    /* Remember the original command name, parse/skip any leading engine
+     * names, and then setup to parse the rest of the line as flags. */
+    prog = argv[0];
+    while ((argv1 = argv[1]) != NULL && *argv1 != '-') {
+        sk_OPENSSL_CSTRING_push(engines, argv1);
+        argc--;
+        argv++;
+    }
+    argv[0] = prog;
+    opt_init(argc, argv, engine_options);
+
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(engine_options);
+            ret = 0;
+            goto end;
+        case OPT_VVVV:
+        case OPT_VVV:
+        case OPT_VV:
+        case OPT_V:
+            /* Convert to an integer from one to four. */
+            i = (int)(o - OPT_V) + 1;
+            if (verbose < i)
+                verbose = i;
+            break;
+        case OPT_C:
+            list_cap = 1;
+            break;
+        case OPT_TT:
+            test_avail_noise++;
+        case OPT_T:
+            test_avail++;
+            break;
+        case OPT_PRE:
+            sk_OPENSSL_STRING_push(pre_cmds, opt_arg());
+            break;
+        case OPT_POST:
+            sk_OPENSSL_STRING_push(post_cmds, opt_arg());
+            break;
+        }
+    }
+
+    /* Allow any trailing parameters as engine names. */
+    argc = opt_num_rest();
+    argv = opt_rest();
+    for ( ; *argv; argv++) {
+        if (**argv == '-') {
+            BIO_printf(bio_err, "%s: Cannot mix flags and engine names.\n",
+                       prog);
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        }
+        sk_OPENSSL_CSTRING_push(engines, *argv);
+    }
+
+    if (sk_OPENSSL_CSTRING_num(engines) == 0) {
+        for (e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e)) {
+            sk_OPENSSL_CSTRING_push(engines, ENGINE_get_id(e));
+        }
+    }
+
+    ret = 0;
+    for (i = 0; i < sk_OPENSSL_CSTRING_num(engines); i++) {
+        const char *id = sk_OPENSSL_CSTRING_value(engines, i);
+        if ((e = ENGINE_by_id(id)) != NULL) {
+            const char *name = ENGINE_get_name(e);
+            /*
+             * Do "id" first, then "name". Easier to auto-parse.
+             */
+            BIO_printf(out, "(%s) %s\n", id, name);
+            util_do_cmds(e, pre_cmds, out, indent);
+            if (strcmp(ENGINE_get_id(e), id) != 0) {
+                BIO_printf(out, "Loaded: (%s) %s\n",
+                           ENGINE_get_id(e), ENGINE_get_name(e));
+            }
+            if (list_cap) {
+                int cap_size = 256;
+                char *cap_buf = NULL;
+                int k, n;
+                const int *nids;
+                ENGINE_CIPHERS_PTR fn_c;
+                ENGINE_DIGESTS_PTR fn_d;
+                ENGINE_PKEY_METHS_PTR fn_pk;
+
+                if (ENGINE_get_RSA(e) != NULL
+                    && !append_buf(&cap_buf, &cap_size, "RSA"))
+                    goto end;
+                if (ENGINE_get_DSA(e) != NULL
+                    && !append_buf(&cap_buf, &cap_size, "DSA"))
+                    goto end;
+                if (ENGINE_get_DH(e) != NULL
+                    && !append_buf(&cap_buf, &cap_size, "DH"))
+                    goto end;
+                if (ENGINE_get_RAND(e) != NULL
+                    && !append_buf(&cap_buf, &cap_size, "RAND"))
+                    goto end;
+
+                fn_c = ENGINE_get_ciphers(e);
+                if (!fn_c)
+                    goto skip_ciphers;
+                n = fn_c(e, NULL, &nids, 0);
+                for (k = 0; k < n; ++k)
+                    if (!append_buf(&cap_buf, &cap_size, OBJ_nid2sn(nids[k])))
+                        goto end;
+
+ skip_ciphers:
+                fn_d = ENGINE_get_digests(e);
+                if (!fn_d)
+                    goto skip_digests;
+                n = fn_d(e, NULL, &nids, 0);
+                for (k = 0; k < n; ++k)
+                    if (!append_buf(&cap_buf, &cap_size, OBJ_nid2sn(nids[k])))
+                        goto end;
+
+ skip_digests:
+                fn_pk = ENGINE_get_pkey_meths(e);
+                if (!fn_pk)
+                    goto skip_pmeths;
+                n = fn_pk(e, NULL, &nids, 0);
+                for (k = 0; k < n; ++k)
+                    if (!append_buf(&cap_buf, &cap_size, OBJ_nid2sn(nids[k])))
+                        goto end;
+ skip_pmeths:
+                if (cap_buf && (*cap_buf != '\0'))
+                    BIO_printf(out, " [%s]\n", cap_buf);
+
+                OPENSSL_free(cap_buf);
+            }
+            if (test_avail) {
+                BIO_printf(out, "%s", indent);
+                if (ENGINE_init(e)) {
+                    BIO_printf(out, "[ available ]\n");
+                    util_do_cmds(e, post_cmds, out, indent);
+                    ENGINE_finish(e);
+                } else {
+                    BIO_printf(out, "[ unavailable ]\n");
+                    if (test_avail_noise)
+                        ERR_print_errors_fp(stdout);
+                    ERR_clear_error();
+                }
+            }
+            if ((verbose > 0) && !util_verbose(e, verbose, out, indent))
+                goto end;
+            ENGINE_free(e);
+        } else {
+            ERR_print_errors(bio_err);
+            /* because exit codes above 127 have special meaning on Unix */
+            if (++ret > 127)
+                ret = 127;
+        }
+    }
+
+ end:
+
+    ERR_print_errors(bio_err);
+    sk_OPENSSL_CSTRING_free(engines);
+    sk_OPENSSL_STRING_free(pre_cmds);
+    sk_OPENSSL_STRING_free(post_cmds);
+    BIO_free_all(out);
+    return (ret);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/errstr.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/errstr.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/errstr.c	(revision 331)
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/lhash.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP
+} OPTION_CHOICE;
+
+OPTIONS errstr_options[] = {
+    {OPT_HELP_STR, 1, '-', "Usage: %s [options] errnum...\n"},
+    {OPT_HELP_STR, 1, '-', "  errnum  Error number\n"},
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {NULL}
+};
+
+int errstr_main(int argc, char **argv)
+{
+    OPTION_CHOICE o;
+    char buf[256], *prog;
+    int ret = 1;
+    unsigned long l;
+
+    prog = opt_init(argc, argv, errstr_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(errstr_options);
+            ret = 0;
+            goto end;
+        }
+    }
+
+    ret = 0;
+    for (argv = opt_rest(); *argv; argv++) {
+        if (sscanf(*argv, "%lx", &l) == 0)
+            ret++;
+        else {
+            /* We're not really an SSL application so this won't auto-init, but
+             * we're still interested in SSL error strings
+             */
+            OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
+                             | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
+            ERR_error_string_n(l, buf, sizeof buf);
+            BIO_printf(bio_out, "%s\n", buf);
+        }
+    }
+ end:
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/gendsa.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/gendsa.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/gendsa.c	(revision 331)
@@ -0,0 +1,147 @@
+/*
+ * Copyright 1995-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 <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_DSA
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <stdio.h>
+# include <string.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include "apps.h"
+# include <openssl/bio.h>
+# include <openssl/err.h>
+# include <openssl/bn.h>
+# include <openssl/dsa.h>
+# include <openssl/x509.h>
+# include <openssl/pem.h>
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_OUT, OPT_PASSOUT, OPT_ENGINE, OPT_RAND, OPT_CIPHER
+} OPTION_CHOICE;
+
+OPTIONS gendsa_options[] = {
+    {OPT_HELP_STR, 1, '-', "Usage: %s [args] dsaparam-file\n"},
+    {OPT_HELP_STR, 1, '-', "Valid options are:\n"},
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"out", OPT_OUT, '>', "Output the key to the specified file"},
+    {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
+    {"rand", OPT_RAND, 's',
+     "Load the file(s) into the random number generator"},
+    {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"},
+# ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+# endif
+    {NULL}
+};
+
+int gendsa_main(int argc, char **argv)
+{
+    ENGINE *e = NULL;
+    BIO *out = NULL, *in = NULL;
+    DSA *dsa = NULL;
+    const EVP_CIPHER *enc = NULL;
+    char *inrand = NULL, *dsaparams = NULL;
+    char *outfile = NULL, *passoutarg = NULL, *passout = NULL, *prog;
+    OPTION_CHOICE o;
+    int ret = 1, private = 0;
+    const BIGNUM *p = NULL;
+
+    prog = opt_init(argc, argv, gendsa_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            ret = 0;
+            opt_help(gendsa_options);
+            goto end;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_PASSOUT:
+            passoutarg = opt_arg();
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        case OPT_RAND:
+            inrand = opt_arg();
+            break;
+        case OPT_CIPHER:
+            if (!opt_cipher(opt_unknown(), &enc))
+                goto end;
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    argv = opt_rest();
+    private = 1;
+
+    if (argc != 1)
+        goto opthelp;
+    dsaparams = *argv;
+
+    if (!app_passwd(NULL, passoutarg, NULL, &passout)) {
+        BIO_printf(bio_err, "Error getting password\n");
+        goto end;
+    }
+
+    in = bio_open_default(dsaparams, 'r', FORMAT_PEM);
+    if (in == NULL)
+        goto end2;
+
+    if ((dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL)) == NULL) {
+        BIO_printf(bio_err, "unable to load DSA parameter file\n");
+        goto end;
+    }
+    BIO_free(in);
+    in = NULL;
+
+    out = bio_open_owner(outfile, FORMAT_PEM, private);
+    if (out == NULL)
+        goto end2;
+
+    if (!app_RAND_load_file(NULL, 1) && inrand == NULL) {
+        BIO_printf(bio_err,
+                   "warning, not much extra random data, consider using the -rand option\n");
+    }
+    if (inrand != NULL)
+        BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
+                   app_RAND_load_files(inrand));
+
+    DSA_get0_pqg(dsa, &p, NULL, NULL);
+    BIO_printf(bio_err, "Generating DSA key, %d bits\n", BN_num_bits(p));
+    if (!DSA_generate_key(dsa))
+        goto end;
+
+    app_RAND_write_file(NULL);
+
+    assert(private);
+    if (!PEM_write_bio_DSAPrivateKey(out, dsa, enc, NULL, 0, NULL, passout))
+        goto end;
+    ret = 0;
+ end:
+    if (ret != 0)
+        ERR_print_errors(bio_err);
+ end2:
+    BIO_free(in);
+    BIO_free_all(out);
+    DSA_free(dsa);
+    release_engine(e);
+    OPENSSL_free(passout);
+    return (ret);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/genpkey.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/genpkey.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/genpkey.c	(revision 331)
@@ -0,0 +1,314 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+
+static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e);
+static int genpkey_cb(EVP_PKEY_CTX *ctx);
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_ENGINE, OPT_OUTFORM, OPT_OUT, OPT_PASS, OPT_PARAMFILE,
+    OPT_ALGORITHM, OPT_PKEYOPT, OPT_GENPARAM, OPT_TEXT, OPT_CIPHER
+} OPTION_CHOICE;
+
+OPTIONS genpkey_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"out", OPT_OUT, '>', "Output file"},
+    {"outform", OPT_OUTFORM, 'F', "output format (DER or PEM)"},
+    {"pass", OPT_PASS, 's', "Output file pass phrase source"},
+    {"paramfile", OPT_PARAMFILE, '<', "Parameters file"},
+    {"algorithm", OPT_ALGORITHM, 's', "The public key algorithm"},
+    {"pkeyopt", OPT_PKEYOPT, 's',
+     "Set the public key algorithm option as opt:value"},
+    {"genparam", OPT_GENPARAM, '-', "Generate parameters, not key"},
+    {"text", OPT_TEXT, '-', "Print the in text"},
+    {"", OPT_CIPHER, '-', "Cipher to use to encrypt the key"},
+#ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+#endif
+    /* This is deliberately last. */
+    {OPT_HELP_STR, 1, 1,
+     "Order of options may be important!  See the documentation.\n"},
+    {NULL}
+};
+
+int genpkey_main(int argc, char **argv)
+{
+    BIO *in = NULL, *out = NULL;
+    ENGINE *e = NULL;
+    EVP_PKEY *pkey = NULL;
+    EVP_PKEY_CTX *ctx = NULL;
+    char *outfile = NULL, *passarg = NULL, *pass = NULL, *prog;
+    const EVP_CIPHER *cipher = NULL;
+    OPTION_CHOICE o;
+    int outformat = FORMAT_PEM, text = 0, ret = 1, rv, do_param = 0;
+    int private = 0;
+
+    prog = opt_init(argc, argv, genpkey_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            ret = 0;
+            opt_help(genpkey_options);
+            goto end;
+        case OPT_OUTFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
+                goto opthelp;
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_PASS:
+            passarg = opt_arg();
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        case OPT_PARAMFILE:
+            if (do_param == 1)
+                goto opthelp;
+            if (!init_keygen_file(&ctx, opt_arg(), e))
+                goto end;
+            break;
+        case OPT_ALGORITHM:
+            if (!init_gen_str(&ctx, opt_arg(), e, do_param))
+                goto end;
+            break;
+        case OPT_PKEYOPT:
+            if (ctx == NULL) {
+                BIO_printf(bio_err, "%s: No keytype specified.\n", prog);
+                goto opthelp;
+            }
+            if (pkey_ctrl_string(ctx, opt_arg()) <= 0) {
+                BIO_printf(bio_err,
+                           "%s: Error setting %s parameter:\n",
+                           prog, opt_arg());
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+            break;
+        case OPT_GENPARAM:
+            if (ctx != NULL)
+                goto opthelp;
+            do_param = 1;
+            break;
+        case OPT_TEXT:
+            text = 1;
+            break;
+        case OPT_CIPHER:
+            if (!opt_cipher(opt_unknown(), &cipher)
+                || do_param == 1)
+                goto opthelp;
+        }
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    private = do_param ? 0 : 1;
+
+    if (ctx == NULL)
+        goto opthelp;
+
+    if (!app_passwd(passarg, NULL, &pass, NULL)) {
+        BIO_puts(bio_err, "Error getting password\n");
+        goto end;
+    }
+
+    out = bio_open_owner(outfile, outformat, private);
+    if (out == NULL)
+        goto end;
+
+    EVP_PKEY_CTX_set_cb(ctx, genpkey_cb);
+    EVP_PKEY_CTX_set_app_data(ctx, bio_err);
+
+    if (do_param) {
+        if (EVP_PKEY_paramgen(ctx, &pkey) <= 0) {
+            BIO_puts(bio_err, "Error generating parameters\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    } else {
+        if (EVP_PKEY_keygen(ctx, &pkey) <= 0) {
+            BIO_puts(bio_err, "Error generating key\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    if (do_param)
+        rv = PEM_write_bio_Parameters(out, pkey);
+    else if (outformat == FORMAT_PEM) {
+        assert(private);
+        rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, NULL, pass);
+    } else if (outformat == FORMAT_ASN1) {
+        assert(private);
+        rv = i2d_PrivateKey_bio(out, pkey);
+    } else {
+        BIO_printf(bio_err, "Bad format specified for key\n");
+        goto end;
+    }
+
+    if (rv <= 0) {
+        BIO_puts(bio_err, "Error writing key\n");
+        ERR_print_errors(bio_err);
+    }
+
+    if (text) {
+        if (do_param)
+            rv = EVP_PKEY_print_params(out, pkey, 0, NULL);
+        else
+            rv = EVP_PKEY_print_private(out, pkey, 0, NULL);
+
+        if (rv <= 0) {
+            BIO_puts(bio_err, "Error printing key\n");
+            ERR_print_errors(bio_err);
+        }
+    }
+
+    ret = 0;
+
+ end:
+    EVP_PKEY_free(pkey);
+    EVP_PKEY_CTX_free(ctx);
+    BIO_free_all(out);
+    BIO_free(in);
+    release_engine(e);
+    OPENSSL_free(pass);
+    return ret;
+}
+
+static int init_keygen_file(EVP_PKEY_CTX **pctx, const char *file, ENGINE *e)
+{
+    BIO *pbio;
+    EVP_PKEY *pkey = NULL;
+    EVP_PKEY_CTX *ctx = NULL;
+    if (*pctx) {
+        BIO_puts(bio_err, "Parameters already set!\n");
+        return 0;
+    }
+
+    pbio = BIO_new_file(file, "r");
+    if (!pbio) {
+        BIO_printf(bio_err, "Can't open parameter file %s\n", file);
+        return 0;
+    }
+
+    pkey = PEM_read_bio_Parameters(pbio, NULL);
+    BIO_free(pbio);
+
+    if (!pkey) {
+        BIO_printf(bio_err, "Error reading parameter file %s\n", file);
+        return 0;
+    }
+
+    ctx = EVP_PKEY_CTX_new(pkey, e);
+    if (ctx == NULL)
+        goto err;
+    if (EVP_PKEY_keygen_init(ctx) <= 0)
+        goto err;
+    EVP_PKEY_free(pkey);
+    *pctx = ctx;
+    return 1;
+
+ err:
+    BIO_puts(bio_err, "Error initializing context\n");
+    ERR_print_errors(bio_err);
+    EVP_PKEY_CTX_free(ctx);
+    EVP_PKEY_free(pkey);
+    return 0;
+
+}
+
+int init_gen_str(EVP_PKEY_CTX **pctx,
+                 const char *algname, ENGINE *e, int do_param)
+{
+    EVP_PKEY_CTX *ctx = NULL;
+    const EVP_PKEY_ASN1_METHOD *ameth;
+    ENGINE *tmpeng = NULL;
+    int pkey_id;
+
+    if (*pctx) {
+        BIO_puts(bio_err, "Algorithm already set!\n");
+        return 0;
+    }
+
+    ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1);
+
+#ifndef OPENSSL_NO_ENGINE
+    if (!ameth && e)
+        ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1);
+#endif
+
+    if (!ameth) {
+        BIO_printf(bio_err, "Algorithm %s not found\n", algname);
+        return 0;
+    }
+
+    ERR_clear_error();
+
+    EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE_finish(tmpeng);
+#endif
+    ctx = EVP_PKEY_CTX_new_id(pkey_id, e);
+
+    if (!ctx)
+        goto err;
+    if (do_param) {
+        if (EVP_PKEY_paramgen_init(ctx) <= 0)
+            goto err;
+    } else {
+        if (EVP_PKEY_keygen_init(ctx) <= 0)
+            goto err;
+    }
+
+    *pctx = ctx;
+    return 1;
+
+ err:
+    BIO_printf(bio_err, "Error initializing %s context\n", algname);
+    ERR_print_errors(bio_err);
+    EVP_PKEY_CTX_free(ctx);
+    return 0;
+
+}
+
+static int genpkey_cb(EVP_PKEY_CTX *ctx)
+{
+    char c = '*';
+    BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
+    int p;
+    p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
+    if (p == 0)
+        c = '.';
+    if (p == 1)
+        c = '+';
+    if (p == 2)
+        c = '*';
+    if (p == 3)
+        c = '\n';
+    BIO_write(b, &c, 1);
+    (void)BIO_flush(b);
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/genrsa.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/genrsa.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/genrsa.c	(revision 331)
@@ -0,0 +1,192 @@
+/*
+ * Copyright 1995-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 <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_RSA
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <stdio.h>
+# include <string.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include "apps.h"
+# include <openssl/bio.h>
+# include <openssl/err.h>
+# include <openssl/bn.h>
+# include <openssl/rsa.h>
+# include <openssl/evp.h>
+# include <openssl/x509.h>
+# include <openssl/pem.h>
+# include <openssl/rand.h>
+
+# define DEFBITS 2048
+
+static int genrsa_cb(int p, int n, BN_GENCB *cb);
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_3, OPT_F4, OPT_ENGINE,
+    OPT_OUT, OPT_RAND, OPT_PASSOUT, OPT_CIPHER
+} OPTION_CHOICE;
+
+OPTIONS genrsa_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"3", OPT_3, '-', "Use 3 for the E value"},
+    {"F4", OPT_F4, '-', "Use F4 (0x10001) for the E value"},
+    {"f4", OPT_F4, '-', "Use F4 (0x10001) for the E value"},
+    {"out", OPT_OUT, 's', "Output the key to specified file"},
+    {"rand", OPT_RAND, 's',
+     "Load the file(s) into the random number generator"},
+    {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
+    {"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"},
+# ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+# endif
+    {NULL}
+};
+
+int genrsa_main(int argc, char **argv)
+{
+    BN_GENCB *cb = BN_GENCB_new();
+    PW_CB_DATA cb_data;
+    ENGINE *eng = NULL;
+    BIGNUM *bn = BN_new();
+    BIO *out = NULL;
+    const BIGNUM *e;
+    RSA *rsa = NULL;
+    const EVP_CIPHER *enc = NULL;
+    int ret = 1, num = DEFBITS, private = 0;
+    unsigned long f4 = RSA_F4;
+    char *outfile = NULL, *passoutarg = NULL, *passout = NULL;
+    char *inrand = NULL, *prog, *hexe, *dece;
+    OPTION_CHOICE o;
+
+    if (bn == NULL || cb == NULL)
+        goto end;
+
+    BN_GENCB_set(cb, genrsa_cb, bio_err);
+
+    prog = opt_init(argc, argv, genrsa_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            ret = 0;
+            opt_help(genrsa_options);
+            goto end;
+        case OPT_3:
+            f4 = 3;
+            break;
+        case OPT_F4:
+            f4 = RSA_F4;
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_ENGINE:
+            eng = setup_engine(opt_arg(), 0);
+            break;
+        case OPT_RAND:
+            inrand = opt_arg();
+            break;
+        case OPT_PASSOUT:
+            passoutarg = opt_arg();
+            break;
+        case OPT_CIPHER:
+            if (!opt_cipher(opt_unknown(), &enc))
+                goto end;
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    argv = opt_rest();
+    private = 1;
+
+    if (argv[0] && (!opt_int(argv[0], &num) || num <= 0))
+        goto end;
+
+    if (!app_passwd(NULL, passoutarg, NULL, &passout)) {
+        BIO_printf(bio_err, "Error getting password\n");
+        goto end;
+    }
+
+    out = bio_open_owner(outfile, FORMAT_PEM, private);
+    if (out == NULL)
+        goto end;
+
+    if (!app_RAND_load_file(NULL, 1) && inrand == NULL
+        && !RAND_status()) {
+        BIO_printf(bio_err,
+                   "warning, not much extra random data, consider using the -rand option\n");
+    }
+    if (inrand != NULL)
+        BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
+                   app_RAND_load_files(inrand));
+
+    BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus\n",
+               num);
+    rsa = eng ? RSA_new_method(eng) : RSA_new();
+    if (rsa == NULL)
+        goto end;
+
+    if (!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, cb))
+        goto end;
+
+    app_RAND_write_file(NULL);
+
+    RSA_get0_key(rsa, NULL, &e, NULL);
+    hexe = BN_bn2hex(e);
+    dece = BN_bn2dec(e);
+    if (hexe && dece) {
+        BIO_printf(bio_err, "e is %s (0x%s)\n", dece, hexe);
+    }
+    OPENSSL_free(hexe);
+    OPENSSL_free(dece);
+    cb_data.password = passout;
+    cb_data.prompt_info = outfile;
+    assert(private);
+    if (!PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0,
+                                     (pem_password_cb *)password_callback,
+                                     &cb_data))
+        goto end;
+
+    ret = 0;
+ end:
+    BN_free(bn);
+    BN_GENCB_free(cb);
+    RSA_free(rsa);
+    BIO_free_all(out);
+    release_engine(eng);
+    OPENSSL_free(passout);
+    if (ret != 0)
+        ERR_print_errors(bio_err);
+    return (ret);
+}
+
+static int genrsa_cb(int p, int n, BN_GENCB *cb)
+{
+    char c = '*';
+
+    if (p == 0)
+        c = '.';
+    if (p == 1)
+        c = '+';
+    if (p == 2)
+        c = '*';
+    if (p == 3)
+        c = '\n';
+    BIO_write(BN_GENCB_get_arg(cb), &c, 1);
+    (void)BIO_flush(BN_GENCB_get_arg(cb));
+    return 1;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/nseq.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/nseq.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/nseq.c	(revision 331)
@@ -0,0 +1,113 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/pem.h>
+#include <openssl/err.h>
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_TOSEQ, OPT_IN, OPT_OUT
+} OPTION_CHOICE;
+
+OPTIONS nseq_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"toseq", OPT_TOSEQ, '-', "Output NS Sequence file"},
+    {"in", OPT_IN, '<', "Input file"},
+    {"out", OPT_OUT, '>', "Output file"},
+    {NULL}
+};
+
+int nseq_main(int argc, char **argv)
+{
+    BIO *in = NULL, *out = NULL;
+    X509 *x509 = NULL;
+    NETSCAPE_CERT_SEQUENCE *seq = NULL;
+    OPTION_CHOICE o;
+    int toseq = 0, ret = 1, i;
+    char *infile = NULL, *outfile = NULL, *prog;
+
+    prog = opt_init(argc, argv, nseq_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            ret = 0;
+            opt_help(nseq_options);
+            goto end;
+        case OPT_TOSEQ:
+            toseq = 1;
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    in = bio_open_default(infile, 'r', FORMAT_PEM);
+    if (in == NULL)
+        goto end;
+    out = bio_open_default(outfile, 'w', FORMAT_PEM);
+    if (out == NULL)
+        goto end;
+
+    if (toseq) {
+        seq = NETSCAPE_CERT_SEQUENCE_new();
+        if (seq == NULL)
+            goto end;
+        seq->certs = sk_X509_new_null();
+        if (seq->certs == NULL)
+            goto end;
+        while ((x509 = PEM_read_bio_X509(in, NULL, NULL, NULL)))
+            sk_X509_push(seq->certs, x509);
+
+        if (!sk_X509_num(seq->certs)) {
+            BIO_printf(bio_err, "%s: Error reading certs file %s\n",
+                       prog, infile);
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        PEM_write_bio_NETSCAPE_CERT_SEQUENCE(out, seq);
+        ret = 0;
+        goto end;
+    }
+
+    seq = PEM_read_bio_NETSCAPE_CERT_SEQUENCE(in, NULL, NULL, NULL);
+    if (seq == NULL) {
+        BIO_printf(bio_err, "%s: Error reading sequence file %s\n",
+                   prog, infile);
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    for (i = 0; i < sk_X509_num(seq->certs); i++) {
+        x509 = sk_X509_value(seq->certs, i);
+        dump_cert_text(out, x509);
+        PEM_write_bio_X509(out, x509);
+    }
+    ret = 0;
+ end:
+    BIO_free(in);
+    BIO_free_all(out);
+    NETSCAPE_CERT_SEQUENCE_free(seq);
+
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/ocsp.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/ocsp.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/ocsp.c	(revision 331)
@@ -0,0 +1,1290 @@
+/*
+ * Copyright 2001-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 <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_OCSP
+NON_EMPTY_TRANSLATION_UNIT
+#else
+# ifdef OPENSSL_SYS_VMS
+#  define _XOPEN_SOURCE_EXTENDED/* So fd_set and friends get properly defined
+                                 * on OpenVMS */
+# endif
+
+# define USE_SOCKETS
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+# include <time.h>
+# include <ctype.h>
+
+/* Needs to be included before the openssl headers */
+# include "apps.h"
+# include <openssl/e_os2.h>
+# include <openssl/crypto.h>
+# include <openssl/err.h>
+# include <openssl/ssl.h>
+# include <openssl/evp.h>
+# include <openssl/bn.h>
+# include <openssl/x509v3.h>
+
+# if defined(NETWARE_CLIB)
+#  ifdef NETWARE_BSDSOCK
+#   include <sys/socket.h>
+#   include <sys/bsdskt.h>
+#  else
+#   include <novsock2.h>
+#  endif
+# elif defined(NETWARE_LIBC)
+#  ifdef NETWARE_BSDSOCK
+#   include <sys/select.h>
+#  else
+#   include <novsock2.h>
+#  endif
+# endif
+
+/* Maximum leeway in validity period: default 5 minutes */
+# define MAX_VALIDITY_PERIOD    (5 * 60)
+
+static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert,
+                         const EVP_MD *cert_id_md, X509 *issuer,
+                         STACK_OF(OCSP_CERTID) *ids);
+static int add_ocsp_serial(OCSP_REQUEST **req, char *serial,
+                           const EVP_MD *cert_id_md, X509 *issuer,
+                           STACK_OF(OCSP_CERTID) *ids);
+static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
+                              STACK_OF(OPENSSL_STRING) *names,
+                              STACK_OF(OCSP_CERTID) *ids, long nsec,
+                              long maxage);
+static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req,
+                              CA_DB *db, X509 *ca, X509 *rcert,
+                              EVP_PKEY *rkey, const EVP_MD *md,
+                              STACK_OF(X509) *rother, unsigned long flags,
+                              int nmin, int ndays, int badsig);
+
+static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser);
+static BIO *init_responder(const char *port);
+static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio);
+static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp);
+
+# ifndef OPENSSL_NO_SOCK
+static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host,
+                                      const char *path,
+                                      const STACK_OF(CONF_VALUE) *headers,
+                                      OCSP_REQUEST *req, int req_timeout);
+# endif
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_OUTFILE, OPT_TIMEOUT, OPT_URL, OPT_HOST, OPT_PORT,
+    OPT_IGNORE_ERR, OPT_NOVERIFY, OPT_NONCE, OPT_NO_NONCE,
+    OPT_RESP_NO_CERTS, OPT_RESP_KEY_ID, OPT_NO_CERTS,
+    OPT_NO_SIGNATURE_VERIFY, OPT_NO_CERT_VERIFY, OPT_NO_CHAIN,
+    OPT_NO_CERT_CHECKS, OPT_NO_EXPLICIT, OPT_TRUST_OTHER,
+    OPT_NO_INTERN, OPT_BADSIG, OPT_TEXT, OPT_REQ_TEXT, OPT_RESP_TEXT,
+    OPT_REQIN, OPT_RESPIN, OPT_SIGNER, OPT_VAFILE, OPT_SIGN_OTHER,
+    OPT_VERIFY_OTHER, OPT_CAFILE, OPT_CAPATH, OPT_NOCAFILE, OPT_NOCAPATH,
+    OPT_VALIDITY_PERIOD, OPT_STATUS_AGE, OPT_SIGNKEY, OPT_REQOUT,
+    OPT_RESPOUT, OPT_PATH, OPT_ISSUER, OPT_CERT, OPT_SERIAL,
+    OPT_INDEX, OPT_CA, OPT_NMIN, OPT_REQUEST, OPT_NDAYS, OPT_RSIGNER,
+    OPT_RKEY, OPT_ROTHER, OPT_RMD, OPT_HEADER,
+    OPT_V_ENUM,
+    OPT_MD
+} OPTION_CHOICE;
+
+OPTIONS ocsp_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"out", OPT_OUTFILE, '>', "Output filename"},
+    {"timeout", OPT_TIMEOUT, 'p',
+     "Connection timeout (in seconds) to the OCSP responder"},
+    {"url", OPT_URL, 's', "Responder URL"},
+    {"host", OPT_HOST, 's', "TCP/IP hostname:port to connect to"},
+    {"port", OPT_PORT, 'p', "Port to run responder on"},
+    {"ignore_err", OPT_IGNORE_ERR, '-',
+     "Ignore Error response from OCSP responder, and retry "},
+    {"noverify", OPT_NOVERIFY, '-', "Don't verify response at all"},
+    {"nonce", OPT_NONCE, '-', "Add OCSP nonce to request"},
+    {"no_nonce", OPT_NO_NONCE, '-', "Don't add OCSP nonce to request"},
+    {"resp_no_certs", OPT_RESP_NO_CERTS, '-',
+     "Don't include any certificates in response"},
+    {"resp_key_id", OPT_RESP_KEY_ID, '-',
+     "Identify response by signing certificate key ID"},
+    {"no_certs", OPT_NO_CERTS, '-',
+     "Don't include any certificates in signed request"},
+    {"no_signature_verify", OPT_NO_SIGNATURE_VERIFY, '-',
+     "Don't check signature on response"},
+    {"no_cert_verify", OPT_NO_CERT_VERIFY, '-',
+     "Don't check signing certificate"},
+    {"no_chain", OPT_NO_CHAIN, '-', "Don't chain verify response"},
+    {"no_cert_checks", OPT_NO_CERT_CHECKS, '-',
+     "Don't do additional checks on signing certificate"},
+    {"no_explicit", OPT_NO_EXPLICIT, '-',
+     "Do not explicitly check the chain, just verify the root"},
+    {"trust_other", OPT_TRUST_OTHER, '-',
+     "Don't verify additional certificates"},
+    {"no_intern", OPT_NO_INTERN, '-',
+     "Don't search certificates contained in response for signer"},
+    {"badsig", OPT_BADSIG, '-',
+        "Corrupt last byte of loaded OSCP response signature (for test)"},
+    {"text", OPT_TEXT, '-', "Print text form of request and response"},
+    {"req_text", OPT_REQ_TEXT, '-', "Print text form of request"},
+    {"resp_text", OPT_RESP_TEXT, '-', "Print text form of response"},
+    {"reqin", OPT_REQIN, 's', "File with the DER-encoded request"},
+    {"respin", OPT_RESPIN, 's', "File with the DER-encoded response"},
+    {"signer", OPT_SIGNER, '<', "Certificate to sign OCSP request with"},
+    {"VAfile", OPT_VAFILE, '<', "Validator certificates file"},
+    {"sign_other", OPT_SIGN_OTHER, '<',
+     "Additional certificates to include in signed request"},
+    {"verify_other", OPT_VERIFY_OTHER, '<',
+     "Additional certificates to search for signer"},
+    {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"},
+    {"CApath", OPT_CAPATH, '<', "Trusted certificates directory"},
+    {"no-CAfile", OPT_NOCAFILE, '-',
+     "Do not load the default certificates file"},
+    {"no-CApath", OPT_NOCAPATH, '-',
+     "Do not load certificates from the default certificates directory"},
+    {"validity_period", OPT_VALIDITY_PERIOD, 'u',
+     "Maximum validity discrepancy in seconds"},
+    {"status_age", OPT_STATUS_AGE, 'p', "Maximum status age in seconds"},
+    {"signkey", OPT_SIGNKEY, 's', "Private key to sign OCSP request with"},
+    {"reqout", OPT_REQOUT, 's', "Output file for the DER-encoded request"},
+    {"respout", OPT_RESPOUT, 's', "Output file for the DER-encoded response"},
+    {"path", OPT_PATH, 's', "Path to use in OCSP request"},
+    {"issuer", OPT_ISSUER, '<', "Issuer certificate"},
+    {"cert", OPT_CERT, '<', "Certificate to check"},
+    {"serial", OPT_SERIAL, 's', "Serial number to check"},
+    {"index", OPT_INDEX, '<', "Certificate status index file"},
+    {"CA", OPT_CA, '<', "CA certificate"},
+    {"nmin", OPT_NMIN, 'p', "Number of minutes before next update"},
+    {"nrequest", OPT_REQUEST, 'p',
+     "Number of requests to accept (default unlimited)"},
+    {"ndays", OPT_NDAYS, 'p', "Number of days before next update"},
+    {"rsigner", OPT_RSIGNER, '<',
+     "Responder certificate to sign responses with"},
+    {"rkey", OPT_RKEY, '<', "Responder key to sign responses with"},
+    {"rother", OPT_ROTHER, '<', "Other certificates to include in response"},
+    {"rmd", OPT_RMD, 's', "Digest Algorithm to use in signature of OCSP response"},
+    {"header", OPT_HEADER, 's', "key=value header to add"},
+    {"", OPT_MD, '-', "Any supported digest algorithm (sha1,sha256, ... )"},
+    OPT_V_OPTIONS,
+    {NULL}
+};
+
+int ocsp_main(int argc, char **argv)
+{
+    BIO *acbio = NULL, *cbio = NULL, *derbio = NULL, *out = NULL;
+    const EVP_MD *cert_id_md = NULL, *rsign_md = NULL;
+    int trailing_md = 0;
+    CA_DB *rdb = NULL;
+    EVP_PKEY *key = NULL, *rkey = NULL;
+    OCSP_BASICRESP *bs = NULL;
+    OCSP_REQUEST *req = NULL;
+    OCSP_RESPONSE *resp = NULL;
+    STACK_OF(CONF_VALUE) *headers = NULL;
+    STACK_OF(OCSP_CERTID) *ids = NULL;
+    STACK_OF(OPENSSL_STRING) *reqnames = NULL;
+    STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
+    STACK_OF(X509) *issuers = NULL;
+    X509 *issuer = NULL, *cert = NULL, *rca_cert = NULL;
+    X509 *signer = NULL, *rsigner = NULL;
+    X509_STORE *store = NULL;
+    X509_VERIFY_PARAM *vpm = NULL;
+    const char *CAfile = NULL, *CApath = NULL;
+    char *header, *value;
+    char *host = NULL, *port = NULL, *path = "/", *outfile = NULL;
+    char *rca_filename = NULL, *reqin = NULL, *respin = NULL;
+    char *reqout = NULL, *respout = NULL, *ridx_filename = NULL;
+    char *rsignfile = NULL, *rkeyfile = NULL;
+    char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL;
+    char *signfile = NULL, *keyfile = NULL;
+    char *thost = NULL, *tport = NULL, *tpath = NULL;
+    int noCAfile = 0, noCApath = 0;
+    int accept_count = -1, add_nonce = 1, noverify = 0, use_ssl = -1;
+    int vpmtouched = 0, badsig = 0, i, ignore_err = 0, nmin = 0, ndays = -1;
+    int req_text = 0, resp_text = 0, ret = 1;
+#ifndef OPENSSL_NO_SOCK
+    int req_timeout = -1;
+#endif
+    long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
+    unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
+    OPTION_CHOICE o;
+    char *prog;
+
+    reqnames = sk_OPENSSL_STRING_new_null();
+    if (!reqnames)
+        goto end;
+    ids = sk_OCSP_CERTID_new_null();
+    if (!ids)
+        goto end;
+    if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
+        return 1;
+
+    prog = opt_init(argc, argv, ocsp_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            ret = 0;
+            opt_help(ocsp_options);
+            goto end;
+        case OPT_OUTFILE:
+            outfile = opt_arg();
+            break;
+        case OPT_TIMEOUT:
+#ifndef OPENSSL_NO_SOCK
+            req_timeout = atoi(opt_arg());
+#endif
+            break;
+        case OPT_URL:
+            OPENSSL_free(thost);
+            OPENSSL_free(tport);
+            OPENSSL_free(tpath);
+            thost = tport = tpath = NULL;
+            if (!OCSP_parse_url(opt_arg(), &host, &port, &path, &use_ssl)) {
+                BIO_printf(bio_err, "%s Error parsing URL\n", prog);
+                goto end;
+            }
+            thost = host;
+            tport = port;
+            tpath = path;
+            break;
+        case OPT_HOST:
+            host = opt_arg();
+            break;
+        case OPT_PORT:
+            port = opt_arg();
+            break;
+        case OPT_IGNORE_ERR:
+            ignore_err = 1;
+            break;
+        case OPT_NOVERIFY:
+            noverify = 1;
+            break;
+        case OPT_NONCE:
+            add_nonce = 2;
+            break;
+        case OPT_NO_NONCE:
+            add_nonce = 0;
+            break;
+        case OPT_RESP_NO_CERTS:
+            rflags |= OCSP_NOCERTS;
+            break;
+        case OPT_RESP_KEY_ID:
+            rflags |= OCSP_RESPID_KEY;
+            break;
+        case OPT_NO_CERTS:
+            sign_flags |= OCSP_NOCERTS;
+            break;
+        case OPT_NO_SIGNATURE_VERIFY:
+            verify_flags |= OCSP_NOSIGS;
+            break;
+        case OPT_NO_CERT_VERIFY:
+            verify_flags |= OCSP_NOVERIFY;
+            break;
+        case OPT_NO_CHAIN:
+            verify_flags |= OCSP_NOCHAIN;
+            break;
+        case OPT_NO_CERT_CHECKS:
+            verify_flags |= OCSP_NOCHECKS;
+            break;
+        case OPT_NO_EXPLICIT:
+            verify_flags |= OCSP_NOEXPLICIT;
+            break;
+        case OPT_TRUST_OTHER:
+            verify_flags |= OCSP_TRUSTOTHER;
+            break;
+        case OPT_NO_INTERN:
+            verify_flags |= OCSP_NOINTERN;
+            break;
+        case OPT_BADSIG:
+            badsig = 1;
+            break;
+        case OPT_TEXT:
+            req_text = resp_text = 1;
+            break;
+        case OPT_REQ_TEXT:
+            req_text = 1;
+            break;
+        case OPT_RESP_TEXT:
+            resp_text = 1;
+            break;
+        case OPT_REQIN:
+            reqin = opt_arg();
+            break;
+        case OPT_RESPIN:
+            respin = opt_arg();
+            break;
+        case OPT_SIGNER:
+            signfile = opt_arg();
+            break;
+        case OPT_VAFILE:
+            verify_certfile = opt_arg();
+            verify_flags |= OCSP_TRUSTOTHER;
+            break;
+        case OPT_SIGN_OTHER:
+            sign_certfile = opt_arg();
+            break;
+        case OPT_VERIFY_OTHER:
+            verify_certfile = opt_arg();
+            break;
+        case OPT_CAFILE:
+            CAfile = opt_arg();
+            break;
+        case OPT_CAPATH:
+            CApath = opt_arg();
+            break;
+        case OPT_NOCAFILE:
+            noCAfile = 1;
+            break;
+        case OPT_NOCAPATH:
+            noCApath = 1;
+            break;
+        case OPT_V_CASES:
+            if (!opt_verify(o, vpm))
+                goto end;
+            vpmtouched++;
+            break;
+        case OPT_VALIDITY_PERIOD:
+            opt_long(opt_arg(), &nsec);
+            break;
+        case OPT_STATUS_AGE:
+            opt_long(opt_arg(), &maxage);
+            break;
+        case OPT_SIGNKEY:
+            keyfile = opt_arg();
+            break;
+        case OPT_REQOUT:
+            reqout = opt_arg();
+            break;
+        case OPT_RESPOUT:
+            respout = opt_arg();
+            break;
+        case OPT_PATH:
+            path = opt_arg();
+            break;
+        case OPT_ISSUER:
+            issuer = load_cert(opt_arg(), FORMAT_PEM, "issuer certificate");
+            if (issuer == NULL)
+                goto end;
+            if (issuers == NULL) {
+                if ((issuers = sk_X509_new_null()) == NULL)
+                    goto end;
+            }
+            sk_X509_push(issuers, issuer);
+            break;
+        case OPT_CERT:
+            X509_free(cert);
+            cert = load_cert(opt_arg(), FORMAT_PEM, "certificate");
+            if (cert == NULL)
+                goto end;
+            if (cert_id_md == NULL)
+                cert_id_md = EVP_sha1();
+            if (!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids))
+                goto end;
+            if (!sk_OPENSSL_STRING_push(reqnames, opt_arg()))
+                goto end;
+            trailing_md = 0;
+            break;
+        case OPT_SERIAL:
+            if (cert_id_md == NULL)
+                cert_id_md = EVP_sha1();
+            if (!add_ocsp_serial(&req, opt_arg(), cert_id_md, issuer, ids))
+                goto end;
+            if (!sk_OPENSSL_STRING_push(reqnames, opt_arg()))
+                goto end;
+            trailing_md = 0;
+            break;
+        case OPT_INDEX:
+            ridx_filename = opt_arg();
+            break;
+        case OPT_CA:
+            rca_filename = opt_arg();
+            break;
+        case OPT_NMIN:
+            opt_int(opt_arg(), &nmin);
+            if (ndays == -1)
+                ndays = 0;
+            break;
+        case OPT_REQUEST:
+            opt_int(opt_arg(), &accept_count);
+            break;
+        case OPT_NDAYS:
+            ndays = atoi(opt_arg());
+            break;
+        case OPT_RSIGNER:
+            rsignfile = opt_arg();
+            break;
+        case OPT_RKEY:
+            rkeyfile = opt_arg();
+            break;
+        case OPT_ROTHER:
+            rcertfile = opt_arg();
+            break;
+        case OPT_RMD:   /* Response MessageDigest */
+            if (!opt_md(opt_arg(), &rsign_md))
+                goto end;
+            break;
+        case OPT_HEADER:
+            header = opt_arg();
+            value = strchr(header, '=');
+            if (value == NULL) {
+                BIO_printf(bio_err, "Missing = in header key=value\n");
+                goto opthelp;
+            }
+            *value++ = '\0';
+            if (!X509V3_add_value(header, value, &headers))
+                goto end;
+            break;
+        case OPT_MD:
+            if (trailing_md) {
+                BIO_printf(bio_err,
+                           "%s: Digest must be before -cert or -serial\n",
+                           prog);
+                goto opthelp;
+            }
+            if (!opt_md(opt_unknown(), &cert_id_md))
+                goto opthelp;
+            trailing_md = 1;
+            break;
+        }
+    }
+
+    if (trailing_md) {
+        BIO_printf(bio_err, "%s: Digest must be before -cert or -serial\n",
+                   prog);
+        goto opthelp;
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    /* Have we anything to do? */
+    if (!req && !reqin && !respin && !(port && ridx_filename))
+        goto opthelp;
+
+    out = bio_open_default(outfile, 'w', FORMAT_TEXT);
+    if (out == NULL)
+        goto end;
+
+    if (!req && (add_nonce != 2))
+        add_nonce = 0;
+
+    if (!req && reqin) {
+        derbio = bio_open_default(reqin, 'r', FORMAT_ASN1);
+        if (derbio == NULL)
+            goto end;
+        req = d2i_OCSP_REQUEST_bio(derbio, NULL);
+        BIO_free(derbio);
+        if (!req) {
+            BIO_printf(bio_err, "Error reading OCSP request\n");
+            goto end;
+        }
+    }
+
+    if (!req && port) {
+        acbio = init_responder(port);
+        if (!acbio)
+            goto end;
+    }
+
+    if (rsignfile) {
+        if (!rkeyfile)
+            rkeyfile = rsignfile;
+        rsigner = load_cert(rsignfile, FORMAT_PEM, "responder certificate");
+        if (!rsigner) {
+            BIO_printf(bio_err, "Error loading responder certificate\n");
+            goto end;
+        }
+        rca_cert = load_cert(rca_filename, FORMAT_PEM, "CA certificate");
+        if (rcertfile) {
+            if (!load_certs(rcertfile, &rother, FORMAT_PEM, NULL,
+                            "responder other certificates"))
+                goto end;
+        }
+        rkey = load_key(rkeyfile, FORMAT_PEM, 0, NULL, NULL,
+                        "responder private key");
+        if (!rkey)
+            goto end;
+    }
+    if (acbio)
+        BIO_printf(bio_err, "Waiting for OCSP client connections...\n");
+
+ redo_accept:
+
+    if (acbio) {
+        if (!do_responder(&req, &cbio, acbio))
+            goto end;
+        if (!req) {
+            resp =
+                OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST,
+                                     NULL);
+            send_ocsp_response(cbio, resp);
+            goto done_resp;
+        }
+    }
+
+    if (!req && (signfile || reqout || host || add_nonce || ridx_filename)) {
+        BIO_printf(bio_err, "Need an OCSP request for this operation!\n");
+        goto end;
+    }
+
+    if (req && add_nonce)
+        OCSP_request_add1_nonce(req, NULL, -1);
+
+    if (signfile) {
+        if (!keyfile)
+            keyfile = signfile;
+        signer = load_cert(signfile, FORMAT_PEM, "signer certificate");
+        if (!signer) {
+            BIO_printf(bio_err, "Error loading signer certificate\n");
+            goto end;
+        }
+        if (sign_certfile) {
+            if (!load_certs(sign_certfile, &sign_other, FORMAT_PEM, NULL,
+                            "signer certificates"))
+                goto end;
+        }
+        key = load_key(keyfile, FORMAT_PEM, 0, NULL, NULL,
+                       "signer private key");
+        if (!key)
+            goto end;
+
+        if (!OCSP_request_sign
+            (req, signer, key, NULL, sign_other, sign_flags)) {
+            BIO_printf(bio_err, "Error signing OCSP request\n");
+            goto end;
+        }
+    }
+
+    if (req_text && req)
+        OCSP_REQUEST_print(out, req, 0);
+
+    if (reqout) {
+        derbio = bio_open_default(reqout, 'w', FORMAT_ASN1);
+        if (derbio == NULL)
+            goto end;
+        i2d_OCSP_REQUEST_bio(derbio, req);
+        BIO_free(derbio);
+    }
+
+    if (ridx_filename && (!rkey || !rsigner || !rca_cert)) {
+        BIO_printf(bio_err,
+                   "Need a responder certificate, key and CA for this operation!\n");
+        goto end;
+    }
+
+    if (ridx_filename && !rdb) {
+        rdb = load_index(ridx_filename, NULL);
+        if (!rdb)
+            goto end;
+        if (!index_index(rdb))
+            goto end;
+    }
+
+    if (rdb) {
+        make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey,
+                               rsign_md, rother, rflags, nmin, ndays, badsig);
+        if (cbio)
+            send_ocsp_response(cbio, resp);
+    } else if (host) {
+# ifndef OPENSSL_NO_SOCK
+        resp = process_responder(req, host, path,
+                                 port, use_ssl, headers, req_timeout);
+        if (!resp)
+            goto end;
+# else
+        BIO_printf(bio_err,
+                   "Error creating connect BIO - sockets not supported.\n");
+        goto end;
+# endif
+    } else if (respin) {
+        derbio = bio_open_default(respin, 'r', FORMAT_ASN1);
+        if (derbio == NULL)
+            goto end;
+        resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
+        BIO_free(derbio);
+        if (!resp) {
+            BIO_printf(bio_err, "Error reading OCSP response\n");
+            goto end;
+        }
+    } else {
+        ret = 0;
+        goto end;
+    }
+
+ done_resp:
+
+    if (respout) {
+        derbio = bio_open_default(respout, 'w', FORMAT_ASN1);
+        if (derbio == NULL)
+            goto end;
+        i2d_OCSP_RESPONSE_bio(derbio, resp);
+        BIO_free(derbio);
+    }
+
+    i = OCSP_response_status(resp);
+    if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
+        BIO_printf(out, "Responder Error: %s (%d)\n",
+                   OCSP_response_status_str(i), i);
+        if (ignore_err)
+            goto redo_accept;
+        ret = 0;
+        goto end;
+    }
+
+    if (resp_text)
+        OCSP_RESPONSE_print(out, resp, 0);
+
+    /* If running as responder don't verify our own response */
+    if (cbio) {
+        /* If not unlimited, see if we took all we should. */
+        if (accept_count != -1 && --accept_count <= 0) {
+            ret = 0;
+            goto end;
+        }
+        BIO_free_all(cbio);
+        cbio = NULL;
+        OCSP_REQUEST_free(req);
+        req = NULL;
+        OCSP_RESPONSE_free(resp);
+        resp = NULL;
+        goto redo_accept;
+    }
+    if (ridx_filename) {
+        ret = 0;
+        goto end;
+    }
+
+    if (!store) {
+        store = setup_verify(CAfile, CApath, noCAfile, noCApath);
+        if (!store)
+            goto end;
+    }
+    if (vpmtouched)
+        X509_STORE_set1_param(store, vpm);
+    if (verify_certfile) {
+        if (!load_certs(verify_certfile, &verify_other, FORMAT_PEM, NULL,
+                        "validator certificate"))
+            goto end;
+    }
+
+    bs = OCSP_response_get1_basic(resp);
+    if (!bs) {
+        BIO_printf(bio_err, "Error parsing response\n");
+        goto end;
+    }
+
+    ret = 0;
+
+    if (!noverify) {
+        if (req && ((i = OCSP_check_nonce(req, bs)) <= 0)) {
+            if (i == -1)
+                BIO_printf(bio_err, "WARNING: no nonce in response\n");
+            else {
+                BIO_printf(bio_err, "Nonce Verify error\n");
+                ret = 1;
+                goto end;
+            }
+        }
+
+        i = OCSP_basic_verify(bs, verify_other, store, verify_flags);
+        if (i <= 0 && issuers) {
+            i = OCSP_basic_verify(bs, issuers, store, OCSP_TRUSTOTHER);
+            if (i > 0)
+                ERR_clear_error();
+        }
+        if (i <= 0) {
+            BIO_printf(bio_err, "Response Verify Failure\n");
+            ERR_print_errors(bio_err);
+            ret = 1;
+        } else
+            BIO_printf(bio_err, "Response verify OK\n");
+
+    }
+
+    print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage);
+
+ end:
+    ERR_print_errors(bio_err);
+    X509_free(signer);
+    X509_STORE_free(store);
+    X509_VERIFY_PARAM_free(vpm);
+    EVP_PKEY_free(key);
+    EVP_PKEY_free(rkey);
+    X509_free(cert);
+    sk_X509_pop_free(issuers, X509_free);
+    X509_free(rsigner);
+    X509_free(rca_cert);
+    free_index(rdb);
+    BIO_free_all(cbio);
+    BIO_free_all(acbio);
+    BIO_free(out);
+    OCSP_REQUEST_free(req);
+    OCSP_RESPONSE_free(resp);
+    OCSP_BASICRESP_free(bs);
+    sk_OPENSSL_STRING_free(reqnames);
+    sk_OCSP_CERTID_free(ids);
+    sk_X509_pop_free(sign_other, X509_free);
+    sk_X509_pop_free(verify_other, X509_free);
+    sk_CONF_VALUE_pop_free(headers, X509V3_conf_free);
+    OPENSSL_free(thost);
+    OPENSSL_free(tport);
+    OPENSSL_free(tpath);
+
+    return (ret);
+}
+
+static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert,
+                         const EVP_MD *cert_id_md, X509 *issuer,
+                         STACK_OF(OCSP_CERTID) *ids)
+{
+    OCSP_CERTID *id;
+    if (!issuer) {
+        BIO_printf(bio_err, "No issuer certificate specified\n");
+        return 0;
+    }
+    if (*req == NULL)
+        *req = OCSP_REQUEST_new();
+    if (*req == NULL)
+        goto err;
+    id = OCSP_cert_to_id(cert_id_md, cert, issuer);
+    if (!id || !sk_OCSP_CERTID_push(ids, id))
+        goto err;
+    if (!OCSP_request_add0_id(*req, id))
+        goto err;
+    return 1;
+
+ err:
+    BIO_printf(bio_err, "Error Creating OCSP request\n");
+    return 0;
+}
+
+static int add_ocsp_serial(OCSP_REQUEST **req, char *serial,
+                           const EVP_MD *cert_id_md, X509 *issuer,
+                           STACK_OF(OCSP_CERTID) *ids)
+{
+    OCSP_CERTID *id;
+    X509_NAME *iname;
+    ASN1_BIT_STRING *ikey;
+    ASN1_INTEGER *sno;
+    if (!issuer) {
+        BIO_printf(bio_err, "No issuer certificate specified\n");
+        return 0;
+    }
+    if (*req == NULL)
+        *req = OCSP_REQUEST_new();
+    if (*req == NULL)
+        goto err;
+    iname = X509_get_subject_name(issuer);
+    ikey = X509_get0_pubkey_bitstr(issuer);
+    sno = s2i_ASN1_INTEGER(NULL, serial);
+    if (!sno) {
+        BIO_printf(bio_err, "Error converting serial number %s\n", serial);
+        return 0;
+    }
+    id = OCSP_cert_id_new(cert_id_md, iname, ikey, sno);
+    ASN1_INTEGER_free(sno);
+    if (id == NULL || !sk_OCSP_CERTID_push(ids, id))
+        goto err;
+    if (!OCSP_request_add0_id(*req, id))
+        goto err;
+    return 1;
+
+ err:
+    BIO_printf(bio_err, "Error Creating OCSP request\n");
+    return 0;
+}
+
+static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
+                              STACK_OF(OPENSSL_STRING) *names,
+                              STACK_OF(OCSP_CERTID) *ids, long nsec,
+                              long maxage)
+{
+    OCSP_CERTID *id;
+    const char *name;
+    int i, status, reason;
+    ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
+
+    if (!bs || !req || !sk_OPENSSL_STRING_num(names)
+        || !sk_OCSP_CERTID_num(ids))
+        return;
+
+    for (i = 0; i < sk_OCSP_CERTID_num(ids); i++) {
+        id = sk_OCSP_CERTID_value(ids, i);
+        name = sk_OPENSSL_STRING_value(names, i);
+        BIO_printf(out, "%s: ", name);
+
+        if (!OCSP_resp_find_status(bs, id, &status, &reason,
+                                   &rev, &thisupd, &nextupd)) {
+            BIO_puts(out, "ERROR: No Status found.\n");
+            continue;
+        }
+
+        /*
+         * Check validity: if invalid write to output BIO so we know which
+         * response this refers to.
+         */
+        if (!OCSP_check_validity(thisupd, nextupd, nsec, maxage)) {
+            BIO_puts(out, "WARNING: Status times invalid.\n");
+            ERR_print_errors(out);
+        }
+        BIO_printf(out, "%s\n", OCSP_cert_status_str(status));
+
+        BIO_puts(out, "\tThis Update: ");
+        ASN1_GENERALIZEDTIME_print(out, thisupd);
+        BIO_puts(out, "\n");
+
+        if (nextupd) {
+            BIO_puts(out, "\tNext Update: ");
+            ASN1_GENERALIZEDTIME_print(out, nextupd);
+            BIO_puts(out, "\n");
+        }
+
+        if (status != V_OCSP_CERTSTATUS_REVOKED)
+            continue;
+
+        if (reason != -1)
+            BIO_printf(out, "\tReason: %s\n", OCSP_crl_reason_str(reason));
+
+        BIO_puts(out, "\tRevocation Time: ");
+        ASN1_GENERALIZEDTIME_print(out, rev);
+        BIO_puts(out, "\n");
+    }
+}
+
+static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req,
+                              CA_DB *db, X509 *ca, X509 *rcert,
+                              EVP_PKEY *rkey, const EVP_MD *rmd,
+                              STACK_OF(X509) *rother, unsigned long flags,
+                              int nmin, int ndays, int badsig)
+{
+    ASN1_TIME *thisupd = NULL, *nextupd = NULL;
+    OCSP_CERTID *cid, *ca_id = NULL;
+    OCSP_BASICRESP *bs = NULL;
+    int i, id_count;
+
+    id_count = OCSP_request_onereq_count(req);
+
+    if (id_count <= 0) {
+        *resp =
+            OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL);
+        goto end;
+    }
+
+    bs = OCSP_BASICRESP_new();
+    thisupd = X509_gmtime_adj(NULL, 0);
+    if (ndays != -1)
+        nextupd = X509_time_adj_ex(NULL, ndays, nmin * 60, NULL);
+
+    /* Examine each certificate id in the request */
+    for (i = 0; i < id_count; i++) {
+        OCSP_ONEREQ *one;
+        ASN1_INTEGER *serial;
+        char **inf;
+        ASN1_OBJECT *cert_id_md_oid;
+        const EVP_MD *cert_id_md;
+        one = OCSP_request_onereq_get0(req, i);
+        cid = OCSP_onereq_get0_id(one);
+
+        OCSP_id_get0_info(NULL, &cert_id_md_oid, NULL, NULL, cid);
+
+        cert_id_md = EVP_get_digestbyobj(cert_id_md_oid);
+        if (!cert_id_md) {
+            *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR,
+                                         NULL);
+            goto end;
+        }
+        OCSP_CERTID_free(ca_id);
+        ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca);
+
+        /* Is this request about our CA? */
+        if (OCSP_id_issuer_cmp(ca_id, cid)) {
+            OCSP_basic_add1_status(bs, cid,
+                                   V_OCSP_CERTSTATUS_UNKNOWN,
+                                   0, NULL, thisupd, nextupd);
+            continue;
+        }
+        OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid);
+        inf = lookup_serial(db, serial);
+        if (!inf)
+            OCSP_basic_add1_status(bs, cid,
+                                   V_OCSP_CERTSTATUS_UNKNOWN,
+                                   0, NULL, thisupd, nextupd);
+        else if (inf[DB_type][0] == DB_TYPE_VAL)
+            OCSP_basic_add1_status(bs, cid,
+                                   V_OCSP_CERTSTATUS_GOOD,
+                                   0, NULL, thisupd, nextupd);
+        else if (inf[DB_type][0] == DB_TYPE_REV) {
+            ASN1_OBJECT *inst = NULL;
+            ASN1_TIME *revtm = NULL;
+            ASN1_GENERALIZEDTIME *invtm = NULL;
+            OCSP_SINGLERESP *single;
+            int reason = -1;
+            unpack_revinfo(&revtm, &reason, &inst, &invtm, inf[DB_rev_date]);
+            single = OCSP_basic_add1_status(bs, cid,
+                                            V_OCSP_CERTSTATUS_REVOKED,
+                                            reason, revtm, thisupd, nextupd);
+            if (invtm)
+                OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date,
+                                             invtm, 0, 0);
+            else if (inst)
+                OCSP_SINGLERESP_add1_ext_i2d(single,
+                                             NID_hold_instruction_code, inst,
+                                             0, 0);
+            ASN1_OBJECT_free(inst);
+            ASN1_TIME_free(revtm);
+            ASN1_GENERALIZEDTIME_free(invtm);
+        }
+    }
+
+    OCSP_copy_nonce(bs, req);
+
+    OCSP_basic_sign(bs, rcert, rkey, rmd, rother, flags);
+
+    if (badsig) {
+        const ASN1_OCTET_STRING *sig = OCSP_resp_get0_signature(bs);
+        corrupt_signature(sig);
+    }
+
+    *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs);
+
+ end:
+    ASN1_TIME_free(thisupd);
+    ASN1_TIME_free(nextupd);
+    OCSP_CERTID_free(ca_id);
+    OCSP_BASICRESP_free(bs);
+}
+
+static char **lookup_serial(CA_DB *db, ASN1_INTEGER *ser)
+{
+    int i;
+    BIGNUM *bn = NULL;
+    char *itmp, *row[DB_NUMBER], **rrow;
+    for (i = 0; i < DB_NUMBER; i++)
+        row[i] = NULL;
+    bn = ASN1_INTEGER_to_BN(ser, NULL);
+    OPENSSL_assert(bn);         /* FIXME: should report an error at this
+                                 * point and abort */
+    if (BN_is_zero(bn))
+        itmp = OPENSSL_strdup("00");
+    else
+        itmp = BN_bn2hex(bn);
+    row[DB_serial] = itmp;
+    BN_free(bn);
+    rrow = TXT_DB_get_by_index(db->db, DB_serial, row);
+    OPENSSL_free(itmp);
+    return rrow;
+}
+
+/* Quick and dirty OCSP server: read in and parse input request */
+
+static BIO *init_responder(const char *port)
+{
+# ifdef OPENSSL_NO_SOCK
+    BIO_printf(bio_err,
+               "Error setting up accept BIO - sockets not supported.\n");
+    return NULL;
+# else
+    BIO *acbio = NULL, *bufbio = NULL;
+
+    bufbio = BIO_new(BIO_f_buffer());
+    if (bufbio == NULL)
+        goto err;
+    acbio = BIO_new(BIO_s_accept());
+    if (acbio == NULL
+        || BIO_set_bind_mode(acbio, BIO_BIND_REUSEADDR) < 0
+        || BIO_set_accept_port(acbio, port) < 0) {
+        BIO_printf(bio_err, "Error setting up accept BIO\n");
+        ERR_print_errors(bio_err);
+        goto err;
+    }
+
+    BIO_set_accept_bios(acbio, bufbio);
+    bufbio = NULL;
+    if (BIO_do_accept(acbio) <= 0) {
+        BIO_printf(bio_err, "Error starting accept\n");
+        ERR_print_errors(bio_err);
+        goto err;
+    }
+
+    return acbio;
+
+ err:
+    BIO_free_all(acbio);
+    BIO_free(bufbio);
+    return NULL;
+# endif
+}
+
+# ifndef OPENSSL_NO_SOCK
+/*
+ * Decode %xx URL-decoding in-place. Ignores mal-formed sequences.
+ */
+static int urldecode(char *p)
+{
+    unsigned char *out = (unsigned char *)p;
+    unsigned char *save = out;
+
+    for (; *p; p++) {
+        if (*p != '%')
+            *out++ = *p;
+        else if (isxdigit(_UC(p[1])) && isxdigit(_UC(p[2]))) {
+            /* Don't check, can't fail because of ixdigit() call. */
+            *out++ = (OPENSSL_hexchar2int(p[1]) << 4)
+                   | OPENSSL_hexchar2int(p[2]);
+            p += 2;
+        }
+        else
+            return -1;
+    }
+    *out = '\0';
+    return (int)(out - save);
+}
+# endif
+
+static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio)
+{
+# ifdef OPENSSL_NO_SOCK
+    return 0;
+# else
+    int len;
+    OCSP_REQUEST *req = NULL;
+    char inbuf[2048], reqbuf[2048];
+    char *p, *q;
+    BIO *cbio = NULL, *getbio = NULL, *b64 = NULL;
+
+    if (BIO_do_accept(acbio) <= 0) {
+        BIO_printf(bio_err, "Error accepting connection\n");
+        ERR_print_errors(bio_err);
+        return 0;
+    }
+
+    cbio = BIO_pop(acbio);
+    *pcbio = cbio;
+
+    /* Read the request line. */
+    len = BIO_gets(cbio, reqbuf, sizeof reqbuf);
+    if (len <= 0)
+        return 1;
+    if (strncmp(reqbuf, "GET ", 4) == 0) {
+        /* Expecting GET {sp} /URL {sp} HTTP/1.x */
+        for (p = reqbuf + 4; *p == ' '; ++p)
+            continue;
+        if (*p != '/') {
+            BIO_printf(bio_err, "Invalid request -- bad URL\n");
+            return 1;
+        }
+        p++;
+
+        /* Splice off the HTTP version identifier. */
+        for (q = p; *q; q++)
+            if (*q == ' ')
+                break;
+        if (strncmp(q, " HTTP/1.", 8) != 0) {
+            BIO_printf(bio_err, "Invalid request -- bad HTTP vesion\n");
+            return 1;
+        }
+        *q = '\0';
+        len = urldecode(p);
+        if (len <= 0) {
+            BIO_printf(bio_err, "Invalid request -- bad URL encoding\n");
+            return 1;
+        }
+        if ((getbio = BIO_new_mem_buf(p, len)) == NULL
+            || (b64 = BIO_new(BIO_f_base64())) == NULL) {
+            BIO_printf(bio_err, "Could not allocate memory\n");
+            ERR_print_errors(bio_err);
+            return 1;
+        }
+        BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
+        getbio = BIO_push(b64, getbio);
+    } else if (strncmp(reqbuf, "POST ", 5) != 0) {
+        BIO_printf(bio_err, "Invalid request -- bad HTTP verb\n");
+        return 1;
+    }
+
+    /* Read and skip past the headers. */
+    for (;;) {
+        len = BIO_gets(cbio, inbuf, sizeof inbuf);
+        if (len <= 0)
+            return 1;
+        if ((inbuf[0] == '\r') || (inbuf[0] == '\n'))
+            break;
+    }
+
+    /* Try to read OCSP request */
+    if (getbio) {
+        req = d2i_OCSP_REQUEST_bio(getbio, NULL);
+        BIO_free_all(getbio);
+    } else
+        req = d2i_OCSP_REQUEST_bio(cbio, NULL);
+
+    if (!req) {
+        BIO_printf(bio_err, "Error parsing OCSP request\n");
+        ERR_print_errors(bio_err);
+    }
+
+    *preq = req;
+
+    return 1;
+# endif
+}
+
+static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp)
+{
+    char http_resp[] =
+        "HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n"
+        "Content-Length: %d\r\n\r\n";
+    if (!cbio)
+        return 0;
+    BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL));
+    i2d_OCSP_RESPONSE_bio(cbio, resp);
+    (void)BIO_flush(cbio);
+    return 1;
+}
+
+# ifndef OPENSSL_NO_SOCK
+static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host,
+                                      const char *path,
+                                      const STACK_OF(CONF_VALUE) *headers,
+                                      OCSP_REQUEST *req, int req_timeout)
+{
+    int fd;
+    int rv;
+    int i;
+    int add_host = 1;
+    OCSP_REQ_CTX *ctx = NULL;
+    OCSP_RESPONSE *rsp = NULL;
+    fd_set confds;
+    struct timeval tv;
+
+    if (req_timeout != -1)
+        BIO_set_nbio(cbio, 1);
+
+    rv = BIO_do_connect(cbio);
+
+    if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio))) {
+        BIO_puts(bio_err, "Error connecting BIO\n");
+        return NULL;
+    }
+
+    if (BIO_get_fd(cbio, &fd) < 0) {
+        BIO_puts(bio_err, "Can't get connection fd\n");
+        goto err;
+    }
+
+    if (req_timeout != -1 && rv <= 0) {
+        FD_ZERO(&confds);
+        openssl_fdset(fd, &confds);
+        tv.tv_usec = 0;
+        tv.tv_sec = req_timeout;
+        rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
+        if (rv == 0) {
+            BIO_puts(bio_err, "Timeout on connect\n");
+            return NULL;
+        }
+    }
+
+    ctx = OCSP_sendreq_new(cbio, path, NULL, -1);
+    if (ctx == NULL)
+        return NULL;
+
+    for (i = 0; i < sk_CONF_VALUE_num(headers); i++) {
+        CONF_VALUE *hdr = sk_CONF_VALUE_value(headers, i);
+        if (add_host == 1 && strcasecmp("host", hdr->name) == 0)
+            add_host = 0;
+        if (!OCSP_REQ_CTX_add1_header(ctx, hdr->name, hdr->value))
+            goto err;
+    }
+
+    if (add_host == 1 && OCSP_REQ_CTX_add1_header(ctx, "Host", host) == 0)
+        goto err;
+
+    if (!OCSP_REQ_CTX_set1_req(ctx, req))
+        goto err;
+
+    for (;;) {
+        rv = OCSP_sendreq_nbio(&rsp, ctx);
+        if (rv != -1)
+            break;
+        if (req_timeout == -1)
+            continue;
+        FD_ZERO(&confds);
+        openssl_fdset(fd, &confds);
+        tv.tv_usec = 0;
+        tv.tv_sec = req_timeout;
+        if (BIO_should_read(cbio))
+            rv = select(fd + 1, (void *)&confds, NULL, NULL, &tv);
+        else if (BIO_should_write(cbio))
+            rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
+        else {
+            BIO_puts(bio_err, "Unexpected retry condition\n");
+            goto err;
+        }
+        if (rv == 0) {
+            BIO_puts(bio_err, "Timeout on request\n");
+            break;
+        }
+        if (rv == -1) {
+            BIO_puts(bio_err, "Select error\n");
+            break;
+        }
+
+    }
+ err:
+    OCSP_REQ_CTX_free(ctx);
+
+    return rsp;
+}
+
+OCSP_RESPONSE *process_responder(OCSP_REQUEST *req,
+                                 const char *host, const char *path,
+                                 const char *port, int use_ssl,
+                                 STACK_OF(CONF_VALUE) *headers,
+                                 int req_timeout)
+{
+    BIO *cbio = NULL;
+    SSL_CTX *ctx = NULL;
+    OCSP_RESPONSE *resp = NULL;
+
+    cbio = BIO_new_connect(host);
+    if (!cbio) {
+        BIO_printf(bio_err, "Error creating connect BIO\n");
+        goto end;
+    }
+    if (port)
+        BIO_set_conn_port(cbio, port);
+    if (use_ssl == 1) {
+        BIO *sbio;
+        ctx = SSL_CTX_new(TLS_client_method());
+        if (ctx == NULL) {
+            BIO_printf(bio_err, "Error creating SSL context.\n");
+            goto end;
+        }
+        SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
+        sbio = BIO_new_ssl(ctx, 1);
+        cbio = BIO_push(sbio, cbio);
+    }
+
+    resp = query_responder(cbio, host, path, headers, req, req_timeout);
+    if (!resp)
+        BIO_printf(bio_err, "Error querying OCSP responder\n");
+ end:
+    BIO_free_all(cbio);
+    SSL_CTX_free(ctx);
+    return resp;
+}
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/openssl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/openssl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/openssl.c	(revision 331)
@@ -0,0 +1,695 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <openssl/bio.h>
+#include <openssl/crypto.h>
+#include <openssl/lhash.h>
+#include <openssl/conf.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+#ifndef OPENSSL_NO_ENGINE
+# include <openssl/engine.h>
+#endif
+#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+#define USE_SOCKETS /* needed for the _O_BINARY defs in the MS world */
+#include "s_apps.h"
+/* Needed to get the other O_xxx flags. */
+#ifdef OPENSSL_SYS_VMS
+# include <unixio.h>
+#endif
+#define INCLUDE_FUNCTION_TABLE
+#include "apps.h"
+
+
+#ifdef OPENSSL_NO_CAMELLIA
+# define FORMAT "%-15s"
+# define COLUMNS 5
+#else
+# define FORMAT "%-18s"
+# define COLUMNS 4
+#endif
+
+/* Special sentinel to exit the program. */
+#define EXIT_THE_PROGRAM (-1)
+
+/*
+ * The LHASH callbacks ("hash" & "cmp") have been replaced by functions with
+ * the base prototypes (we cast each variable inside the function to the
+ * required type of "FUNCTION*"). This removes the necessity for
+ * macro-generated wrapper functions.
+ */
+static LHASH_OF(FUNCTION) *prog_init(void);
+static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]);
+static void list_pkey(void);
+static void list_type(FUNC_TYPE ft);
+static void list_disabled(void);
+char *default_config_file = NULL;
+
+BIO *bio_in = NULL;
+BIO *bio_out = NULL;
+BIO *bio_err = NULL;
+
+static int apps_startup()
+{
+#ifdef SIGPIPE
+    signal(SIGPIPE, SIG_IGN);
+#endif
+
+    /* Set non-default library initialisation settings */
+    if (!OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN
+                             | OPENSSL_INIT_LOAD_CONFIG, NULL))
+        return 0;
+
+#ifndef OPENSSL_NO_UI
+    setup_ui_method();
+#endif
+
+    return 1;
+}
+
+static void apps_shutdown()
+{
+#ifndef OPENSSL_NO_UI
+    destroy_ui_method();
+#endif
+}
+
+static char *make_config_name()
+{
+    const char *t;
+    size_t len;
+    char *p;
+
+    if ((t = getenv("OPENSSL_CONF")) != NULL)
+        return OPENSSL_strdup(t);
+
+    t = X509_get_default_cert_area();
+    len = strlen(t) + 1 + strlen(OPENSSL_CONF) + 1;
+    p = app_malloc(len, "config filename buffer");
+    strcpy(p, t);
+#ifndef OPENSSL_SYS_VMS
+    strcat(p, "/");
+#endif
+    strcat(p, OPENSSL_CONF);
+
+    return p;
+}
+
+int main(int argc, char *argv[])
+{
+    FUNCTION f, *fp;
+    LHASH_OF(FUNCTION) *prog = NULL;
+    char **copied_argv = NULL;
+    char *p, *pname;
+    char buf[1024];
+    const char *prompt;
+    ARGS arg;
+    int first, n, i, ret = 0;
+
+    arg.argv = NULL;
+    arg.size = 0;
+
+    /* Set up some of the environment. */
+    default_config_file = make_config_name();
+    bio_in = dup_bio_in(FORMAT_TEXT);
+    bio_out = dup_bio_out(FORMAT_TEXT);
+    bio_err = dup_bio_err(FORMAT_TEXT);
+
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+    copied_argv = argv = copy_argv(&argc, argv);
+#elif defined(_WIN32)
+    /*
+     * Replace argv[] with UTF-8 encoded strings.
+     */
+    win32_utf8argv(&argc, &argv);
+#endif
+
+    p = getenv("OPENSSL_DEBUG_MEMORY");
+    if (p != NULL && strcmp(p, "on") == 0)
+        CRYPTO_set_mem_debug(1);
+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+    if (getenv("OPENSSL_FIPS")) {
+#ifdef OPENSSL_FIPS
+        if (!FIPS_mode_set(1)) {
+            ERR_print_errors(bio_err);
+            return 1;
+        }
+#else
+        BIO_printf(bio_err, "FIPS mode not supported.\n");
+        return 1;
+#endif
+    }
+
+    if (!apps_startup())
+        goto end;
+
+    prog = prog_init();
+    pname = opt_progname(argv[0]);
+
+    /* first check the program name */
+    f.name = pname;
+    fp = lh_FUNCTION_retrieve(prog, &f);
+    if (fp != NULL) {
+        argv[0] = pname;
+        ret = fp->func(argc, argv);
+        goto end;
+    }
+
+    /* If there is stuff on the command line, run with that. */
+    if (argc != 1) {
+        argc--;
+        argv++;
+        ret = do_cmd(prog, argc, argv);
+        if (ret < 0)
+            ret = 0;
+        goto end;
+    }
+
+    /* ok, lets enter interactive mode */
+    for (;;) {
+        ret = 0;
+        /* Read a line, continue reading if line ends with \ */
+        for (p = buf, n = sizeof buf, i = 0, first = 1; n > 0; first = 0) {
+            prompt = first ? "OpenSSL> " : "> ";
+            p[0] = '\0';
+#ifndef READLINE
+            fputs(prompt, stdout);
+            fflush(stdout);
+            if (!fgets(p, n, stdin))
+                goto end;
+            if (p[0] == '\0')
+                goto end;
+            i = strlen(p);
+            if (i <= 1)
+                break;
+            if (p[i - 2] != '\\')
+                break;
+            i -= 2;
+            p += i;
+            n -= i;
+#else
+            {
+                extern char *readline(const char *);
+                extern void add_history(const char *cp);
+                char *text;
+
+                text = readline(prompt);
+                if (text == NULL)
+                    goto end;
+                i = strlen(text);
+                if (i == 0 || i > n)
+                    break;
+                if (text[i - 1] != '\\') {
+                    p += strlen(strcpy(p, text));
+                    free(text);
+                    add_history(buf);
+                    break;
+                }
+
+                text[i - 1] = '\0';
+                p += strlen(strcpy(p, text));
+                free(text);
+                n -= i;
+            }
+#endif
+        }
+
+        if (!chopup_args(&arg, buf)) {
+            BIO_printf(bio_err, "Can't parse (no memory?)\n");
+            break;
+        }
+
+        ret = do_cmd(prog, arg.argc, arg.argv);
+        if (ret == EXIT_THE_PROGRAM) {
+            ret = 0;
+            goto end;
+        }
+        if (ret != 0)
+            BIO_printf(bio_err, "error in %s\n", arg.argv[0]);
+        (void)BIO_flush(bio_out);
+        (void)BIO_flush(bio_err);
+    }
+    ret = 1;
+ end:
+    OPENSSL_free(copied_argv);
+    OPENSSL_free(default_config_file);
+    lh_FUNCTION_free(prog);
+    OPENSSL_free(arg.argv);
+
+    BIO_free(bio_in);
+    BIO_free_all(bio_out);
+    apps_shutdown();
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+    if (CRYPTO_mem_leaks(bio_err) <= 0)
+        ret = 1;
+#endif
+    BIO_free(bio_err);
+    EXIT(ret);
+}
+
+OPTIONS exit_options[] = {
+    {NULL}
+};
+
+static void list_cipher_fn(const EVP_CIPHER *c,
+                           const char *from, const char *to, void *arg)
+{
+    if (c)
+        BIO_printf(arg, "%s\n", EVP_CIPHER_name(c));
+    else {
+        if (!from)
+            from = "<undefined>";
+        if (!to)
+            to = "<undefined>";
+        BIO_printf(arg, "%s => %s\n", from, to);
+    }
+}
+
+static void list_md_fn(const EVP_MD *m,
+                       const char *from, const char *to, void *arg)
+{
+    if (m)
+        BIO_printf(arg, "%s\n", EVP_MD_name(m));
+    else {
+        if (!from)
+            from = "<undefined>";
+        if (!to)
+            to = "<undefined>";
+        BIO_printf((BIO *)arg, "%s => %s\n", from, to);
+    }
+}
+
+/* Unified enum for help and list commands. */
+typedef enum HELPLIST_CHOICE {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_COMMANDS, OPT_DIGEST_COMMANDS,
+    OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS,
+    OPT_PK_ALGORITHMS, OPT_DISABLED
+} HELPLIST_CHOICE;
+
+OPTIONS list_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"commands", OPT_COMMANDS, '-', "List of standard commands"},
+    {"digest-commands", OPT_DIGEST_COMMANDS, '-',
+     "List of message digest commands"},
+    {"digest-algorithms", OPT_DIGEST_ALGORITHMS, '-',
+     "List of message digest algorithms"},
+    {"cipher-commands", OPT_CIPHER_COMMANDS, '-', "List of cipher commands"},
+    {"cipher-algorithms", OPT_CIPHER_ALGORITHMS, '-',
+     "List of cipher algorithms"},
+    {"public-key-algorithms", OPT_PK_ALGORITHMS, '-',
+     "List of public key algorithms"},
+    {"disabled", OPT_DISABLED, '-',
+     "List of disabled features"},
+    {NULL}
+};
+
+int list_main(int argc, char **argv)
+{
+    char *prog;
+    HELPLIST_CHOICE o;
+    int done = 0;
+
+    prog = opt_init(argc, argv, list_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:  /* Never hit, but suppresses warning */
+        case OPT_ERR:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            return 1;
+        case OPT_HELP:
+            opt_help(list_options);
+            break;
+        case OPT_COMMANDS:
+            list_type(FT_general);
+            break;
+        case OPT_DIGEST_COMMANDS:
+            list_type(FT_md);
+            break;
+        case OPT_DIGEST_ALGORITHMS:
+            EVP_MD_do_all_sorted(list_md_fn, bio_out);
+            break;
+        case OPT_CIPHER_COMMANDS:
+            list_type(FT_cipher);
+            break;
+        case OPT_CIPHER_ALGORITHMS:
+            EVP_CIPHER_do_all_sorted(list_cipher_fn, bio_out);
+            break;
+        case OPT_PK_ALGORITHMS:
+            list_pkey();
+            break;
+        case OPT_DISABLED:
+            list_disabled();
+            break;
+        }
+        done = 1;
+    }
+
+    if (!done) {
+        BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+        return 1;
+    }
+
+    return 0;
+}
+
+OPTIONS help_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {NULL}
+};
+
+int help_main(int argc, char **argv)
+{
+    FUNCTION *fp;
+    int i, nl;
+    FUNC_TYPE tp;
+    char *prog;
+    HELPLIST_CHOICE o;
+
+    prog = opt_init(argc, argv, help_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        default:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            return 1;
+        case OPT_HELP:
+            opt_help(help_options);
+            return 0;
+        }
+    }
+
+    if (opt_num_rest() != 0) {
+        BIO_printf(bio_err, "Usage: %s\n", prog);
+        return 1;
+    }
+
+    BIO_printf(bio_err, "\nStandard commands");
+    i = 0;
+    tp = FT_none;
+    for (fp = functions; fp->name != NULL; fp++) {
+        nl = 0;
+        if (((i++) % COLUMNS) == 0) {
+            BIO_printf(bio_err, "\n");
+            nl = 1;
+        }
+        if (fp->type != tp) {
+            tp = fp->type;
+            if (!nl)
+                BIO_printf(bio_err, "\n");
+            if (tp == FT_md) {
+                i = 1;
+                BIO_printf(bio_err,
+                           "\nMessage Digest commands (see the `dgst' command for more details)\n");
+            } else if (tp == FT_cipher) {
+                i = 1;
+                BIO_printf(bio_err,
+                           "\nCipher commands (see the `enc' command for more details)\n");
+            }
+        }
+        BIO_printf(bio_err, FORMAT, fp->name);
+    }
+    BIO_printf(bio_err, "\n\n");
+    return 0;
+}
+
+int exit_main(int argc, char **argv)
+{
+    return EXIT_THE_PROGRAM;
+}
+
+static void list_type(FUNC_TYPE ft)
+{
+    FUNCTION *fp;
+    int i = 0;
+
+    for (fp = functions; fp->name != NULL; fp++)
+        if (fp->type == ft) {
+            if ((i++ % COLUMNS) == 0)
+                BIO_printf(bio_out, "\n");
+            BIO_printf(bio_out, FORMAT, fp->name);
+        }
+    BIO_printf(bio_out, "\n");
+}
+
+static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[])
+{
+    FUNCTION f, *fp;
+
+    if (argc <= 0 || argv[0] == NULL)
+        return (0);
+    f.name = argv[0];
+    fp = lh_FUNCTION_retrieve(prog, &f);
+    if (fp == NULL) {
+        if (EVP_get_digestbyname(argv[0])) {
+            f.type = FT_md;
+            f.func = dgst_main;
+            fp = &f;
+        } else if (EVP_get_cipherbyname(argv[0])) {
+            f.type = FT_cipher;
+            f.func = enc_main;
+            fp = &f;
+        }
+    }
+    if (fp != NULL) {
+        return (fp->func(argc, argv));
+    }
+    if ((strncmp(argv[0], "no-", 3)) == 0) {
+        /*
+         * User is asking if foo is unsupported, by trying to "run" the
+         * no-foo command.  Strange.
+         */
+        f.name = argv[0] + 3;
+        if (lh_FUNCTION_retrieve(prog, &f) == NULL) {
+            BIO_printf(bio_out, "%s\n", argv[0]);
+            return (0);
+        }
+        BIO_printf(bio_out, "%s\n", argv[0] + 3);
+        return 1;
+    }
+    if (strcmp(argv[0], "quit") == 0 || strcmp(argv[0], "q") == 0 ||
+        strcmp(argv[0], "exit") == 0 || strcmp(argv[0], "bye") == 0)
+        /* Special value to mean "exit the program. */
+        return EXIT_THE_PROGRAM;
+
+    BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n",
+               argv[0]);
+    return (1);
+}
+
+static void list_pkey(void)
+{
+    int i;
+
+    for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
+        const EVP_PKEY_ASN1_METHOD *ameth;
+        int pkey_id, pkey_base_id, pkey_flags;
+        const char *pinfo, *pem_str;
+        ameth = EVP_PKEY_asn1_get0(i);
+        EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags,
+                                &pinfo, &pem_str, ameth);
+        if (pkey_flags & ASN1_PKEY_ALIAS) {
+            BIO_printf(bio_out, "Name: %s\n", OBJ_nid2ln(pkey_id));
+            BIO_printf(bio_out, "\tAlias for: %s\n",
+                       OBJ_nid2ln(pkey_base_id));
+        } else {
+            BIO_printf(bio_out, "Name: %s\n", pinfo);
+            BIO_printf(bio_out, "\tType: %s Algorithm\n",
+                       pkey_flags & ASN1_PKEY_DYNAMIC ?
+                       "External" : "Builtin");
+            BIO_printf(bio_out, "\tOID: %s\n", OBJ_nid2ln(pkey_id));
+            if (pem_str == NULL)
+                pem_str = "(none)";
+            BIO_printf(bio_out, "\tPEM string: %s\n", pem_str);
+        }
+
+    }
+}
+
+static int function_cmp(const FUNCTION * a, const FUNCTION * b)
+{
+    return strncmp(a->name, b->name, 8);
+}
+
+static unsigned long function_hash(const FUNCTION * a)
+{
+    return OPENSSL_LH_strhash(a->name);
+}
+
+static int SortFnByName(const void *_f1, const void *_f2)
+{
+    const FUNCTION *f1 = _f1;
+    const FUNCTION *f2 = _f2;
+
+    if (f1->type != f2->type)
+        return f1->type - f2->type;
+    return strcmp(f1->name, f2->name);
+}
+
+static void list_disabled(void)
+{
+    BIO_puts(bio_out, "Disabled algorithms:\n");
+#ifdef OPENSSL_NO_BF
+    BIO_puts(bio_out, "BF\n");
+#endif
+#ifdef OPENSSL_NO_BLAKE2
+    BIO_puts(bio_out, "BLAKE2\n");
+#endif
+#ifdef OPENSSL_NO_CAMELLIA
+    BIO_puts(bio_out, "CAMELLIA\n");
+#endif
+#ifdef OPENSSL_NO_CAST
+    BIO_puts(bio_out, "CAST\n");
+#endif
+#ifdef OPENSSL_NO_CMAC
+    BIO_puts(bio_out, "CMAC\n");
+#endif
+#ifdef OPENSSL_NO_CMS
+    BIO_puts(bio_out, "CMS\n");
+#endif
+#ifdef OPENSSL_NO_COMP
+    BIO_puts(bio_out, "COMP\n");
+#endif
+#ifdef OPENSSL_NO_DES
+    BIO_puts(bio_out, "DES\n");
+#endif
+#ifdef OPENSSL_NO_DGRAM
+    BIO_puts(bio_out, "DGRAM\n");
+#endif
+#ifdef OPENSSL_NO_DH
+    BIO_puts(bio_out, "DH\n");
+#endif
+#ifdef OPENSSL_NO_DSA
+    BIO_puts(bio_out, "DSA\n");
+#endif
+#if defined(OPENSSL_NO_DTLS)
+    BIO_puts(bio_out, "DTLS\n");
+#endif
+#if defined(OPENSSL_NO_DTLS1)
+    BIO_puts(bio_out, "DTLS1\n");
+#endif
+#if defined(OPENSSL_NO_DTLS1_2)
+    BIO_puts(bio_out, "DTLS1_2\n");
+#endif
+#ifdef OPENSSL_NO_EC
+    BIO_puts(bio_out, "EC\n");
+#endif
+#ifdef OPENSSL_NO_EC2M
+    BIO_puts(bio_out, "EC2M\n");
+#endif
+#ifdef OPENSSL_NO_ENGINE
+    BIO_puts(bio_out, "ENGINE\n");
+#endif
+#ifdef OPENSSL_NO_GOST
+    BIO_puts(bio_out, "GOST\n");
+#endif
+#ifdef OPENSSL_NO_HEARTBEATS
+    BIO_puts(bio_out, "HEARTBEATS\n");
+#endif
+#ifdef OPENSSL_NO_IDEA
+    BIO_puts(bio_out, "IDEA\n");
+#endif
+#ifdef OPENSSL_NO_MD2
+    BIO_puts(bio_out, "MD2\n");
+#endif
+#ifdef OPENSSL_NO_MD4
+    BIO_puts(bio_out, "MD4\n");
+#endif
+#ifdef OPENSSL_NO_MD5
+    BIO_puts(bio_out, "MD5\n");
+#endif
+#ifdef OPENSSL_NO_MDC2
+    BIO_puts(bio_out, "MDC2\n");
+#endif
+#ifdef OPENSSL_NO_OCB
+    BIO_puts(bio_out, "OCB\n");
+#endif
+#ifdef OPENSSL_NO_OCSP
+    BIO_puts(bio_out, "OCSP\n");
+#endif
+#ifdef OPENSSL_NO_PSK
+    BIO_puts(bio_out, "PSK\n");
+#endif
+#ifdef OPENSSL_NO_RC2
+    BIO_puts(bio_out, "RC2\n");
+#endif
+#ifdef OPENSSL_NO_RC4
+    BIO_puts(bio_out, "RC4\n");
+#endif
+#ifdef OPENSSL_NO_RC5
+    BIO_puts(bio_out, "RC5\n");
+#endif
+#ifdef OPENSSL_NO_RMD160
+    BIO_puts(bio_out, "RMD160\n");
+#endif
+#ifdef OPENSSL_NO_RSA
+    BIO_puts(bio_out, "RSA\n");
+#endif
+#ifdef OPENSSL_NO_SCRYPT
+    BIO_puts(bio_out, "SCRYPT\n");
+#endif
+#ifdef OPENSSL_NO_SCTP
+    BIO_puts(bio_out, "SCTP\n");
+#endif
+#ifdef OPENSSL_NO_SEED
+    BIO_puts(bio_out, "SEED\n");
+#endif
+#ifdef OPENSSL_NO_SOCK
+    BIO_puts(bio_out, "SOCK\n");
+#endif
+#ifdef OPENSSL_NO_SRP
+    BIO_puts(bio_out, "SRP\n");
+#endif
+#ifdef OPENSSL_NO_SRTP
+    BIO_puts(bio_out, "SRTP\n");
+#endif
+#ifdef OPENSSL_NO_SSL3
+    BIO_puts(bio_out, "SSL3\n");
+#endif
+#ifdef OPENSSL_NO_TLS1
+    BIO_puts(bio_out, "TLS1\n");
+#endif
+#ifdef OPENSSL_NO_TLS1_1
+    BIO_puts(bio_out, "TLS1_1\n");
+#endif
+#ifdef OPENSSL_NO_TLS1_2
+    BIO_puts(bio_out, "TLS1_2\n");
+#endif
+#ifdef OPENSSL_NO_WHIRLPOOL
+    BIO_puts(bio_out, "WHIRLPOOL\n");
+#endif
+#ifndef ZLIB
+    BIO_puts(bio_out, "ZLIB\n");
+#endif
+}
+
+static LHASH_OF(FUNCTION) *prog_init(void)
+{
+    LHASH_OF(FUNCTION) *ret;
+    FUNCTION *f;
+    size_t i;
+
+    /* Sort alphabetically within category. For nicer help displays. */
+    for (i = 0, f = functions; f->name != NULL; ++f, ++i) ;
+    qsort(functions, i, sizeof(*functions), SortFnByName);
+
+    if ((ret = lh_FUNCTION_new(function_hash, function_cmp)) == NULL)
+        return (NULL);
+
+    for (f = functions; f->name != NULL; f++)
+        (void)lh_FUNCTION_insert(ret, f);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/opt.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/opt.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/opt.c	(revision 331)
@@ -0,0 +1,977 @@
+/*
+ * Copyright 2015-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
+ */
+
+/* #define COMPILE_STANDALONE_TEST_DRIVER  */
+#include "apps.h"
+#include <string.h>
+#if !defined(OPENSSL_SYS_MSDOS)
+# include OPENSSL_UNISTD
+#endif
+
+#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+#include <limits.h>
+#include <openssl/bio.h>
+#include <openssl/x509v3.h>
+
+#define MAX_OPT_HELP_WIDTH 30
+const char OPT_HELP_STR[] = "--";
+const char OPT_MORE_STR[] = "---";
+
+/* Our state */
+static char **argv;
+static int argc;
+static int opt_index;
+static char *arg;
+static char *flag;
+static char *dunno;
+static const OPTIONS *unknown;
+static const OPTIONS *opts;
+static char prog[40];
+
+/*
+ * Return the simple name of the program; removing various platform gunk.
+ */
+#if defined(OPENSSL_SYS_WIN32)
+char *opt_progname(const char *argv0)
+{
+    size_t i, n;
+    const char *p;
+    char *q;
+
+    /* find the last '/', '\' or ':' */
+    for (p = argv0 + strlen(argv0); --p > argv0;)
+        if (*p == '/' || *p == '\\' || *p == ':') {
+            p++;
+            break;
+        }
+
+    /* Strip off trailing nonsense. */
+    n = strlen(p);
+    if (n > 4 &&
+        (strcmp(&p[n - 4], ".exe") == 0 || strcmp(&p[n - 4], ".EXE") == 0))
+        n -= 4;
+
+    /* Copy over the name, in lowercase. */
+    if (n > sizeof prog - 1)
+        n = sizeof prog - 1;
+    for (q = prog, i = 0; i < n; i++, p++)
+        *q++ = isupper(*p) ? tolower(*p) : *p;
+    *q = '\0';
+    return prog;
+}
+
+#elif defined(OPENSSL_SYS_VMS)
+
+char *opt_progname(const char *argv0)
+{
+    const char *p, *q;
+
+    /* Find last special character sys:[foo.bar]openssl */
+    for (p = argv0 + strlen(argv0); --p > argv0;)
+        if (*p == ':' || *p == ']' || *p == '>') {
+            p++;
+            break;
+        }
+
+    q = strrchr(p, '.');
+    strncpy(prog, p, sizeof prog - 1);
+    prog[sizeof prog - 1] = '\0';
+    if (q != NULL && q - p < sizeof prog)
+        prog[q - p] = '\0';
+    return prog;
+}
+
+#else
+
+char *opt_progname(const char *argv0)
+{
+    const char *p;
+
+    /* Could use strchr, but this is like the ones above. */
+    for (p = argv0 + strlen(argv0); --p > argv0;)
+        if (*p == '/') {
+            p++;
+            break;
+        }
+    strncpy(prog, p, sizeof prog - 1);
+    prog[sizeof prog - 1] = '\0';
+    return prog;
+}
+#endif
+
+char *opt_getprog(void)
+{
+    return prog;
+}
+
+/* Set up the arg parsing. */
+char *opt_init(int ac, char **av, const OPTIONS *o)
+{
+    /* Store state. */
+    argc = ac;
+    argv = av;
+    opt_index = 1;
+    opts = o;
+    opt_progname(av[0]);
+    unknown = NULL;
+
+    for (; o->name; ++o) {
+#ifndef NDEBUG
+        const OPTIONS *next;
+        int duplicated, i;
+#endif
+
+        if (o->name == OPT_HELP_STR || o->name == OPT_MORE_STR)
+            continue;
+#ifndef NDEBUG
+        i = o->valtype;
+
+        /* Make sure options are legit. */
+        assert(o->name[0] != '-');
+        assert(o->retval > 0);
+        switch (i) {
+        case   0: case '-': case '/': case '<': case '>': case 'E': case 'F':
+        case 'M': case 'U': case 'f': case 'l': case 'n': case 'p': case 's':
+        case 'u': case 'c':
+            break;
+        default:
+            assert(0);
+        }
+
+        /* Make sure there are no duplicates. */
+        for (next = o + 1; next->name; ++next) {
+            /*
+             * Some compilers inline strcmp and the assert string is too long.
+             */
+            duplicated = strcmp(o->name, next->name) == 0;
+            assert(!duplicated);
+        }
+#endif
+        if (o->name[0] == '\0') {
+            assert(unknown == NULL);
+            unknown = o;
+            assert(unknown->valtype == 0 || unknown->valtype == '-');
+        }
+    }
+    return prog;
+}
+
+static OPT_PAIR formats[] = {
+    {"PEM/DER", OPT_FMT_PEMDER},
+    {"pkcs12", OPT_FMT_PKCS12},
+    {"smime", OPT_FMT_SMIME},
+    {"engine", OPT_FMT_ENGINE},
+    {"msblob", OPT_FMT_MSBLOB},
+    {"netscape", OPT_FMT_NETSCAPE},
+    {"nss", OPT_FMT_NSS},
+    {"text", OPT_FMT_TEXT},
+    {"http", OPT_FMT_HTTP},
+    {"pvk", OPT_FMT_PVK},
+    {NULL}
+};
+
+/* Print an error message about a failed format parse. */
+int opt_format_error(const char *s, unsigned long flags)
+{
+    OPT_PAIR *ap;
+
+    if (flags == OPT_FMT_PEMDER)
+        BIO_printf(bio_err, "%s: Bad format \"%s\"; must be pem or der\n",
+                   prog, s);
+    else {
+        BIO_printf(bio_err, "%s: Bad format \"%s\"; must be one of:\n",
+                   prog, s);
+        for (ap = formats; ap->name; ap++)
+            if (flags & ap->retval)
+                BIO_printf(bio_err, "   %s\n", ap->name);
+    }
+    return 0;
+}
+
+/* Parse a format string, put it into *result; return 0 on failure, else 1. */
+int opt_format(const char *s, unsigned long flags, int *result)
+{
+    switch (*s) {
+    default:
+        return 0;
+    case 'D':
+    case 'd':
+        if ((flags & OPT_FMT_PEMDER) == 0)
+            return opt_format_error(s, flags);
+        *result = FORMAT_ASN1;
+        break;
+    case 'T':
+    case 't':
+        if ((flags & OPT_FMT_TEXT) == 0)
+            return opt_format_error(s, flags);
+        *result = FORMAT_TEXT;
+        break;
+    case 'N':
+    case 'n':
+        if ((flags & OPT_FMT_NSS) == 0)
+            return opt_format_error(s, flags);
+        if (strcmp(s, "NSS") != 0 && strcmp(s, "nss") != 0)
+            return opt_format_error(s, flags);
+        *result = FORMAT_NSS;
+        break;
+    case 'S':
+    case 's':
+        if ((flags & OPT_FMT_SMIME) == 0)
+            return opt_format_error(s, flags);
+        *result = FORMAT_SMIME;
+        break;
+    case 'M':
+    case 'm':
+        if ((flags & OPT_FMT_MSBLOB) == 0)
+            return opt_format_error(s, flags);
+        *result = FORMAT_MSBLOB;
+        break;
+    case 'E':
+    case 'e':
+        if ((flags & OPT_FMT_ENGINE) == 0)
+            return opt_format_error(s, flags);
+        *result = FORMAT_ENGINE;
+        break;
+    case 'H':
+    case 'h':
+        if ((flags & OPT_FMT_HTTP) == 0)
+            return opt_format_error(s, flags);
+        *result = FORMAT_HTTP;
+        break;
+    case '1':
+        if ((flags & OPT_FMT_PKCS12) == 0)
+            return opt_format_error(s, flags);
+        *result = FORMAT_PKCS12;
+        break;
+    case 'P':
+    case 'p':
+        if (s[1] == '\0' || strcmp(s, "PEM") == 0 || strcmp(s, "pem") == 0) {
+            if ((flags & OPT_FMT_PEMDER) == 0)
+                return opt_format_error(s, flags);
+            *result = FORMAT_PEM;
+        } else if (strcmp(s, "PVK") == 0 || strcmp(s, "pvk") == 0) {
+            if ((flags & OPT_FMT_PVK) == 0)
+                return opt_format_error(s, flags);
+            *result = FORMAT_PVK;
+        } else if (strcmp(s, "P12") == 0 || strcmp(s, "p12") == 0
+                   || strcmp(s, "PKCS12") == 0 || strcmp(s, "pkcs12") == 0) {
+            if ((flags & OPT_FMT_PKCS12) == 0)
+                return opt_format_error(s, flags);
+            *result = FORMAT_PKCS12;
+        } else
+            return 0;
+        break;
+    }
+    return 1;
+}
+
+/* Parse a cipher name, put it in *EVP_CIPHER; return 0 on failure, else 1. */
+int opt_cipher(const char *name, const EVP_CIPHER **cipherp)
+{
+    *cipherp = EVP_get_cipherbyname(name);
+    if (*cipherp)
+        return 1;
+    BIO_printf(bio_err, "%s: Unknown cipher %s\n", prog, name);
+    return 0;
+}
+
+/*
+ * Parse message digest name, put it in *EVP_MD; return 0 on failure, else 1.
+ */
+int opt_md(const char *name, const EVP_MD **mdp)
+{
+    *mdp = EVP_get_digestbyname(name);
+    if (*mdp)
+        return 1;
+    BIO_printf(bio_err, "%s: Unknown digest %s\n", prog, name);
+    return 0;
+}
+
+/* Look through a list of name/value pairs. */
+int opt_pair(const char *name, const OPT_PAIR* pairs, int *result)
+{
+    const OPT_PAIR *pp;
+
+    for (pp = pairs; pp->name; pp++)
+        if (strcmp(pp->name, name) == 0) {
+            *result = pp->retval;
+            return 1;
+        }
+    BIO_printf(bio_err, "%s: Value must be one of:\n", prog);
+    for (pp = pairs; pp->name; pp++)
+        BIO_printf(bio_err, "\t%s\n", pp->name);
+    return 0;
+}
+
+/* Parse an int, put it into *result; return 0 on failure, else 1. */
+int opt_int(const char *value, int *result)
+{
+    long l;
+
+    if (!opt_long(value, &l))
+        return 0;
+    *result = (int)l;
+    if (*result != l) {
+        BIO_printf(bio_err, "%s: Value \"%s\" outside integer range\n",
+                   prog, value);
+        return 0;
+    }
+    return 1;
+}
+
+/* Parse a long, put it into *result; return 0 on failure, else 1. */
+int opt_long(const char *value, long *result)
+{
+    int oerrno = errno;
+    long l;
+    char *endp;
+
+    errno = 0;
+    l = strtol(value, &endp, 0);
+    if (*endp
+            || endp == value
+            || ((l == LONG_MAX || l == LONG_MIN) && errno == ERANGE)
+            || (l == 0 && errno != 0)) {
+        BIO_printf(bio_err, "%s: Can't parse \"%s\" as a number\n",
+                   prog, value);
+        errno = oerrno;
+        return 0;
+    }
+    *result = l;
+    errno = oerrno;
+    return 1;
+}
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && \
+    defined(INTMAX_MAX) && defined(UINTMAX_MAX)
+
+/* Parse an intmax_t, put it into *result; return 0 on failure, else 1. */
+int opt_imax(const char *value, intmax_t *result)
+{
+    int oerrno = errno;
+    intmax_t m;
+    char *endp;
+
+    errno = 0;
+    m = strtoimax(value, &endp, 0);
+    if (*endp
+            || endp == value
+            || ((m == INTMAX_MAX || m == INTMAX_MIN) && errno == ERANGE)
+            || (m == 0 && errno != 0)) {
+        BIO_printf(bio_err, "%s: Can't parse \"%s\" as a number\n",
+                   prog, value);
+        errno = oerrno;
+        return 0;
+    }
+    *result = m;
+    errno = oerrno;
+    return 1;
+}
+
+/* Parse a uintmax_t, put it into *result; return 0 on failure, else 1. */
+int opt_umax(const char *value, uintmax_t *result)
+{
+    int oerrno = errno;
+    uintmax_t m;
+    char *endp;
+
+    errno = 0;
+    m = strtoumax(value, &endp, 0);
+    if (*endp
+            || endp == value
+            || (m == UINTMAX_MAX && errno == ERANGE)
+            || (m == 0 && errno != 0)) {
+        BIO_printf(bio_err, "%s: Can't parse \"%s\" as a number\n",
+                   prog, value);
+        errno = oerrno;
+        return 0;
+    }
+    *result = m;
+    errno = oerrno;
+    return 1;
+}
+#endif
+
+/*
+ * Parse an unsigned long, put it into *result; return 0 on failure, else 1.
+ */
+int opt_ulong(const char *value, unsigned long *result)
+{
+    int oerrno = errno;
+    char *endptr;
+    unsigned long l;
+
+    errno = 0;
+    l = strtoul(value, &endptr, 0);
+    if (*endptr
+            || endptr == value
+            || ((l == ULONG_MAX) && errno == ERANGE)
+            || (l == 0 && errno != 0)) {
+        BIO_printf(bio_err, "%s: Can't parse \"%s\" as an unsigned number\n",
+                   prog, value);
+        errno = oerrno;
+        return 0;
+    }
+    *result = l;
+    errno = oerrno;
+    return 1;
+}
+
+/*
+ * We pass opt as an int but cast it to "enum range" so that all the
+ * items in the OPT_V_ENUM enumeration are caught; this makes -Wswitch
+ * in gcc do the right thing.
+ */
+enum range { OPT_V_ENUM };
+
+int opt_verify(int opt, X509_VERIFY_PARAM *vpm)
+{
+    int i;
+    ossl_intmax_t t = 0;
+    ASN1_OBJECT *otmp;
+    X509_PURPOSE *xptmp;
+    const X509_VERIFY_PARAM *vtmp;
+
+    assert(vpm != NULL);
+    assert(opt > OPT_V__FIRST);
+    assert(opt < OPT_V__LAST);
+
+    switch ((enum range)opt) {
+    case OPT_V__FIRST:
+    case OPT_V__LAST:
+        return 0;
+    case OPT_V_POLICY:
+        otmp = OBJ_txt2obj(opt_arg(), 0);
+        if (otmp == NULL) {
+            BIO_printf(bio_err, "%s: Invalid Policy %s\n", prog, opt_arg());
+            return 0;
+        }
+        X509_VERIFY_PARAM_add0_policy(vpm, otmp);
+        break;
+    case OPT_V_PURPOSE:
+        /* purpose name -> purpose index */
+        i = X509_PURPOSE_get_by_sname(opt_arg());
+        if (i < 0) {
+            BIO_printf(bio_err, "%s: Invalid purpose %s\n", prog, opt_arg());
+            return 0;
+        }
+
+        /* purpose index -> purpose object */
+        xptmp = X509_PURPOSE_get0(i);
+
+        /* purpose object -> purpose value */
+        i = X509_PURPOSE_get_id(xptmp);
+
+        if (!X509_VERIFY_PARAM_set_purpose(vpm, i)) {
+            BIO_printf(bio_err,
+                       "%s: Internal error setting purpose %s\n",
+                       prog, opt_arg());
+            return 0;
+        }
+        break;
+    case OPT_V_VERIFY_NAME:
+        vtmp = X509_VERIFY_PARAM_lookup(opt_arg());
+        if (vtmp == NULL) {
+            BIO_printf(bio_err, "%s: Invalid verify name %s\n",
+                       prog, opt_arg());
+            return 0;
+        }
+        X509_VERIFY_PARAM_set1(vpm, vtmp);
+        break;
+    case OPT_V_VERIFY_DEPTH:
+        i = atoi(opt_arg());
+        if (i >= 0)
+            X509_VERIFY_PARAM_set_depth(vpm, i);
+        break;
+    case OPT_V_VERIFY_AUTH_LEVEL:
+        i = atoi(opt_arg());
+        if (i >= 0)
+            X509_VERIFY_PARAM_set_auth_level(vpm, i);
+        break;
+    case OPT_V_ATTIME:
+        if (!opt_imax(opt_arg(), &t))
+            return 0;
+        if (t != (time_t)t) {
+            BIO_printf(bio_err, "%s: epoch time out of range %s\n",
+                       prog, opt_arg());
+            return 0;
+        }
+        X509_VERIFY_PARAM_set_time(vpm, (time_t)t);
+        break;
+    case OPT_V_VERIFY_HOSTNAME:
+        if (!X509_VERIFY_PARAM_set1_host(vpm, opt_arg(), 0))
+            return 0;
+        break;
+    case OPT_V_VERIFY_EMAIL:
+        if (!X509_VERIFY_PARAM_set1_email(vpm, opt_arg(), 0))
+            return 0;
+        break;
+    case OPT_V_VERIFY_IP:
+        if (!X509_VERIFY_PARAM_set1_ip_asc(vpm, opt_arg()))
+            return 0;
+        break;
+    case OPT_V_IGNORE_CRITICAL:
+        X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_IGNORE_CRITICAL);
+        break;
+    case OPT_V_ISSUER_CHECKS:
+        /* NOP, deprecated */
+        break;
+    case OPT_V_CRL_CHECK:
+        X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CRL_CHECK);
+        break;
+    case OPT_V_CRL_CHECK_ALL:
+        X509_VERIFY_PARAM_set_flags(vpm,
+                                    X509_V_FLAG_CRL_CHECK |
+                                    X509_V_FLAG_CRL_CHECK_ALL);
+        break;
+    case OPT_V_POLICY_CHECK:
+        X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_POLICY_CHECK);
+        break;
+    case OPT_V_EXPLICIT_POLICY:
+        X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_EXPLICIT_POLICY);
+        break;
+    case OPT_V_INHIBIT_ANY:
+        X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_INHIBIT_ANY);
+        break;
+    case OPT_V_INHIBIT_MAP:
+        X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_INHIBIT_MAP);
+        break;
+    case OPT_V_X509_STRICT:
+        X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_X509_STRICT);
+        break;
+    case OPT_V_EXTENDED_CRL:
+        X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_EXTENDED_CRL_SUPPORT);
+        break;
+    case OPT_V_USE_DELTAS:
+        X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_USE_DELTAS);
+        break;
+    case OPT_V_POLICY_PRINT:
+        X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NOTIFY_POLICY);
+        break;
+    case OPT_V_CHECK_SS_SIG:
+        X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CHECK_SS_SIGNATURE);
+        break;
+    case OPT_V_TRUSTED_FIRST:
+        X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_TRUSTED_FIRST);
+        break;
+    case OPT_V_SUITEB_128_ONLY:
+        X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_128_LOS_ONLY);
+        break;
+    case OPT_V_SUITEB_128:
+        X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_128_LOS);
+        break;
+    case OPT_V_SUITEB_192:
+        X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_192_LOS);
+        break;
+    case OPT_V_PARTIAL_CHAIN:
+        X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_PARTIAL_CHAIN);
+        break;
+    case OPT_V_NO_ALT_CHAINS:
+        X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NO_ALT_CHAINS);
+        break;
+    case OPT_V_NO_CHECK_TIME:
+        X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NO_CHECK_TIME);
+        break;
+    case OPT_V_ALLOW_PROXY_CERTS:
+        X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_ALLOW_PROXY_CERTS);
+        break;
+    }
+    return 1;
+
+}
+
+/*
+ * Parse the next flag (and value if specified), return 0 if done, -1 on
+ * error, otherwise the flag's retval.
+ */
+int opt_next(void)
+{
+    char *p;
+    const OPTIONS *o;
+    int ival;
+    long lval;
+    unsigned long ulval;
+    ossl_intmax_t imval;
+    ossl_uintmax_t umval;
+
+    /* Look at current arg; at end of the list? */
+    arg = NULL;
+    p = argv[opt_index];
+    if (p == NULL)
+        return 0;
+
+    /* If word doesn't start with a -, we're done. */
+    if (*p != '-')
+        return 0;
+
+    /* Hit "--" ? We're done. */
+    opt_index++;
+    if (strcmp(p, "--") == 0)
+        return 0;
+
+    /* Allow -nnn and --nnn */
+    if (*++p == '-')
+        p++;
+    flag = p - 1;
+
+    /* If we have --flag=foo, snip it off */
+    if ((arg = strchr(p, '=')) != NULL)
+        *arg++ = '\0';
+    for (o = opts; o->name; ++o) {
+        /* If not this option, move on to the next one. */
+        if (strcmp(p, o->name) != 0)
+            continue;
+
+        /* If it doesn't take a value, make sure none was given. */
+        if (o->valtype == 0 || o->valtype == '-') {
+            if (arg) {
+                BIO_printf(bio_err,
+                           "%s: Option -%s does not take a value\n", prog, p);
+                return -1;
+            }
+            return o->retval;
+        }
+
+        /* Want a value; get the next param if =foo not used. */
+        if (arg == NULL) {
+            if (argv[opt_index] == NULL) {
+                BIO_printf(bio_err,
+                           "%s: Option -%s needs a value\n", prog, o->name);
+                return -1;
+            }
+            arg = argv[opt_index++];
+        }
+
+        /* Syntax-check value. */
+        switch (o->valtype) {
+        default:
+        case 's':
+            /* Just a string. */
+            break;
+        case '/':
+            if (app_isdir(arg) >= 0)
+                break;
+            BIO_printf(bio_err, "%s: Not a directory: %s\n", prog, arg);
+            return -1;
+        case '<':
+            /* Input file. */
+            if (strcmp(arg, "-") == 0 || app_access(arg, R_OK) >= 0)
+                break;
+            BIO_printf(bio_err,
+                       "%s: Cannot open input file %s, %s\n",
+                       prog, arg, strerror(errno));
+            return -1;
+        case '>':
+            /* Output file. */
+            if (strcmp(arg, "-") == 0 || app_access(arg, W_OK) >= 0 || errno == ENOENT)
+                break;
+            BIO_printf(bio_err,
+                       "%s: Cannot open output file %s, %s\n",
+                       prog, arg, strerror(errno));
+            return -1;
+        case 'p':
+        case 'n':
+            if (!opt_int(arg, &ival)
+                    || (o->valtype == 'p' && ival <= 0)) {
+                BIO_printf(bio_err,
+                           "%s: Non-positive number \"%s\" for -%s\n",
+                           prog, arg, o->name);
+                return -1;
+            }
+            break;
+        case 'M':
+            if (!opt_imax(arg, &imval)) {
+                BIO_printf(bio_err,
+                           "%s: Invalid number \"%s\" for -%s\n",
+                           prog, arg, o->name);
+                return -1;
+            }
+            break;
+        case 'U':
+            if (!opt_umax(arg, &umval)) {
+                BIO_printf(bio_err,
+                           "%s: Invalid number \"%s\" for -%s\n",
+                           prog, arg, o->name);
+                return -1;
+            }
+            break;
+        case 'l':
+            if (!opt_long(arg, &lval)) {
+                BIO_printf(bio_err,
+                           "%s: Invalid number \"%s\" for -%s\n",
+                           prog, arg, o->name);
+                return -1;
+            }
+            break;
+        case 'u':
+            if (!opt_ulong(arg, &ulval)) {
+                BIO_printf(bio_err,
+                           "%s: Invalid number \"%s\" for -%s\n",
+                           prog, arg, o->name);
+                return -1;
+            }
+            break;
+        case 'c':
+        case 'E':
+        case 'F':
+        case 'f':
+            if (opt_format(arg,
+                           o->valtype == 'c' ? OPT_FMT_PDS :
+                           o->valtype == 'E' ? OPT_FMT_PDE :
+                           o->valtype == 'F' ? OPT_FMT_PEMDER
+                           : OPT_FMT_ANY, &ival))
+                break;
+            BIO_printf(bio_err,
+                       "%s: Invalid format \"%s\" for -%s\n",
+                       prog, arg, o->name);
+            return -1;
+        }
+
+        /* Return the flag value. */
+        return o->retval;
+    }
+    if (unknown != NULL) {
+        dunno = p;
+        return unknown->retval;
+    }
+    BIO_printf(bio_err, "%s: Option unknown option -%s\n", prog, p);
+    return -1;
+}
+
+/* Return the most recent flag parameter. */
+char *opt_arg(void)
+{
+    return arg;
+}
+
+/* Return the most recent flag. */
+char *opt_flag(void)
+{
+    return flag;
+}
+
+/* Return the unknown option. */
+char *opt_unknown(void)
+{
+    return dunno;
+}
+
+/* Return the rest of the arguments after parsing flags. */
+char **opt_rest(void)
+{
+    return &argv[opt_index];
+}
+
+/* How many items in remaining args? */
+int opt_num_rest(void)
+{
+    int i = 0;
+    char **pp;
+
+    for (pp = opt_rest(); *pp; pp++, i++)
+        continue;
+    return i;
+}
+
+/* Return a string describing the parameter type. */
+static const char *valtype2param(const OPTIONS *o)
+{
+    switch (o->valtype) {
+    case 0:
+    case '-':
+        return "";
+    case 's':
+        return "val";
+    case '/':
+        return "dir";
+    case '<':
+        return "infile";
+    case '>':
+        return "outfile";
+    case 'p':
+        return "+int";
+    case 'n':
+        return "int";
+    case 'l':
+        return "long";
+    case 'u':
+        return "ulong";
+    case 'E':
+        return "PEM|DER|ENGINE";
+    case 'F':
+        return "PEM|DER";
+    case 'f':
+        return "format";
+    case 'M':
+        return "intmax";
+    case 'U':
+        return "uintmax";
+    }
+    return "parm";
+}
+
+void opt_help(const OPTIONS *list)
+{
+    const OPTIONS *o;
+    int i;
+    int standard_prolog;
+    int width = 5;
+    char start[80 + 1];
+    char *p;
+    const char *help;
+
+    /* Starts with its own help message? */
+    standard_prolog = list[0].name != OPT_HELP_STR;
+
+    /* Find the widest help. */
+    for (o = list; o->name; o++) {
+        if (o->name == OPT_MORE_STR)
+            continue;
+        i = 2 + (int)strlen(o->name);
+        if (o->valtype != '-')
+            i += 1 + strlen(valtype2param(o));
+        if (i < MAX_OPT_HELP_WIDTH && i > width)
+            width = i;
+        assert(i < (int)sizeof start);
+    }
+
+    if (standard_prolog)
+        BIO_printf(bio_err, "Usage: %s [options]\nValid options are:\n",
+                   prog);
+
+    /* Now let's print. */
+    for (o = list; o->name; o++) {
+        help = o->helpstr ? o->helpstr : "(No additional info)";
+        if (o->name == OPT_HELP_STR) {
+            BIO_printf(bio_err, help, prog);
+            continue;
+        }
+
+        /* Pad out prefix */
+        memset(start, ' ', sizeof(start) - 1);
+        start[sizeof start - 1] = '\0';
+
+        if (o->name == OPT_MORE_STR) {
+            /* Continuation of previous line; pad and print. */
+            start[width] = '\0';
+            BIO_printf(bio_err, "%s  %s\n", start, help);
+            continue;
+        }
+
+        /* Build up the "-flag [param]" part. */
+        p = start;
+        *p++ = ' ';
+        *p++ = '-';
+        if (o->name[0])
+            p += strlen(strcpy(p, o->name));
+        else
+            *p++ = '*';
+        if (o->valtype != '-') {
+            *p++ = ' ';
+            p += strlen(strcpy(p, valtype2param(o)));
+        }
+        *p = ' ';
+        if ((int)(p - start) >= MAX_OPT_HELP_WIDTH) {
+            *p = '\0';
+            BIO_printf(bio_err, "%s\n", start);
+            memset(start, ' ', sizeof(start));
+        }
+        start[width] = '\0';
+        BIO_printf(bio_err, "%s  %s\n", start, help);
+    }
+}
+
+#ifdef COMPILE_STANDALONE_TEST_DRIVER
+# include <sys/stat.h>
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_IN, OPT_INFORM, OPT_OUT, OPT_COUNT, OPT_U, OPT_FLAG,
+    OPT_STR, OPT_NOTUSED
+} OPTION_CHOICE;
+
+static OPTIONS options[] = {
+    {OPT_HELP_STR, 1, '-', "Usage: %s flags\n"},
+    {OPT_HELP_STR, 1, '-', "Valid options are:\n"},
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"in", OPT_IN, '<', "input file"},
+    {OPT_MORE_STR, 1, '-', "more detail about input"},
+    {"inform", OPT_INFORM, 'f', "input file format; defaults to pem"},
+    {"out", OPT_OUT, '>', "output file"},
+    {"count", OPT_COUNT, 'p', "a counter greater than zero"},
+    {"u", OPT_U, 'u', "an unsigned number"},
+    {"flag", OPT_FLAG, 0, "just some flag"},
+    {"str", OPT_STR, 's', "the magic word"},
+    {"areallyverylongoption", OPT_HELP, '-', "long way for help"},
+    {NULL}
+};
+
+BIO *bio_err;
+
+int app_isdir(const char *name)
+{
+    struct stat sb;
+
+    return name != NULL && stat(name, &sb) >= 0 && S_ISDIR(sb.st_mode);
+}
+
+int main(int ac, char **av)
+{
+    OPTION_CHOICE o;
+    char **rest;
+    char *prog;
+
+    bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
+
+    prog = opt_init(ac, av, options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (c) {
+        case OPT_NOTUSED:
+        case OPT_EOF:
+        case OPT_ERR:
+            printf("%s: Usage error; try -help.\n", prog);
+            return 1;
+        case OPT_HELP:
+            opt_help(options);
+            return 0;
+        case OPT_IN:
+            printf("in %s\n", opt_arg());
+            break;
+        case OPT_INFORM:
+            printf("inform %s\n", opt_arg());
+            break;
+        case OPT_OUT:
+            printf("out %s\n", opt_arg());
+            break;
+        case OPT_COUNT:
+            printf("count %s\n", opt_arg());
+            break;
+        case OPT_U:
+            printf("u %s\n", opt_arg());
+            break;
+        case OPT_FLAG:
+            printf("flag\n");
+            break;
+        case OPT_STR:
+            printf("str %s\n", opt_arg());
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    argv = opt_rest();
+
+    printf("args = %d\n", argc);
+    if (argc)
+        while (*argv)
+            printf("  %s\n", *argv++);
+    return 0;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/passwd.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/passwd.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/passwd.c	(revision 331)
@@ -0,0 +1,512 @@
+/*
+ * Copyright 2000-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
+ */
+
+#if defined OPENSSL_NO_MD5 || defined CHARSET_EBCDIC
+# define NO_MD5CRYPT_1
+#endif
+
+#if !defined(OPENSSL_NO_DES) || !defined(NO_MD5CRYPT_1)
+
+# include <string.h>
+
+# include "apps.h"
+
+# include <openssl/bio.h>
+# include <openssl/err.h>
+# include <openssl/evp.h>
+# include <openssl/rand.h>
+# ifndef OPENSSL_NO_DES
+#  include <openssl/des.h>
+# endif
+# ifndef NO_MD5CRYPT_1
+#  include <openssl/md5.h>
+# endif
+
+static unsigned const char cov_2char[64] = {
+    /* from crypto/des/fcrypt.c */
+    0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+    0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44,
+    0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
+    0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54,
+    0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62,
+    0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
+    0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
+    0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
+};
+
+static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
+                     char *passwd, BIO *out, int quiet, int table,
+                     int reverse, size_t pw_maxlen, int usecrypt, int use1,
+                     int useapr1);
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_IN,
+    OPT_NOVERIFY, OPT_QUIET, OPT_TABLE, OPT_REVERSE, OPT_APR1,
+    OPT_1, OPT_CRYPT, OPT_SALT, OPT_STDIN
+} OPTION_CHOICE;
+
+OPTIONS passwd_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"in", OPT_IN, '<', "Pead passwords from file"},
+    {"noverify", OPT_NOVERIFY, '-',
+     "Never verify when reading password from terminal"},
+    {"quiet", OPT_QUIET, '-', "No warnings"},
+    {"table", OPT_TABLE, '-', "Format output as table"},
+    {"reverse", OPT_REVERSE, '-', "Switch table columns"},
+    {"salt", OPT_SALT, 's', "Use provided salt"},
+    {"stdin", OPT_STDIN, '-', "Read passwords from stdin"},
+# ifndef NO_MD5CRYPT_1
+    {"apr1", OPT_APR1, '-', "MD5-based password algorithm, Apache variant"},
+    {"1", OPT_1, '-', "MD5-based password algorithm"},
+# endif
+# ifndef OPENSSL_NO_DES
+    {"crypt", OPT_CRYPT, '-', "Standard Unix password algorithm (default)"},
+# endif
+    {NULL}
+};
+
+int passwd_main(int argc, char **argv)
+{
+    BIO *in = NULL;
+    char *infile = NULL, *salt = NULL, *passwd = NULL, **passwds = NULL;
+    char *salt_malloc = NULL, *passwd_malloc = NULL, *prog;
+    OPTION_CHOICE o;
+    int in_stdin = 0, pw_source_defined = 0;
+#ifndef OPENSSL_NO_UI
+    int in_noverify = 0;
+#endif
+    int passed_salt = 0, quiet = 0, table = 0, reverse = 0;
+    int ret = 1, usecrypt = 0, use1 = 0, useapr1 = 0;
+    size_t passwd_malloc_size = 0, pw_maxlen = 256;
+
+    prog = opt_init(argc, argv, passwd_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(passwd_options);
+            ret = 0;
+            goto end;
+        case OPT_IN:
+            if (pw_source_defined)
+                goto opthelp;
+            infile = opt_arg();
+            pw_source_defined = 1;
+            break;
+        case OPT_NOVERIFY:
+#ifndef OPENSSL_NO_UI
+            in_noverify = 1;
+#endif
+            break;
+        case OPT_QUIET:
+            quiet = 1;
+            break;
+        case OPT_TABLE:
+            table = 1;
+            break;
+        case OPT_REVERSE:
+            reverse = 1;
+            break;
+        case OPT_1:
+            use1 = 1;
+            break;
+        case OPT_APR1:
+            useapr1 = 1;
+            break;
+        case OPT_CRYPT:
+            usecrypt = 1;
+            break;
+        case OPT_SALT:
+            passed_salt = 1;
+            salt = opt_arg();
+            break;
+        case OPT_STDIN:
+            if (pw_source_defined)
+                goto opthelp;
+            in_stdin = 1;
+            pw_source_defined = 1;
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    argv = opt_rest();
+
+    if (*argv) {
+        if (pw_source_defined)
+            goto opthelp;
+        pw_source_defined = 1;
+        passwds = argv;
+    }
+
+    if (!usecrypt && !use1 && !useapr1) {
+        /* use default */
+        usecrypt = 1;
+    }
+    if (usecrypt + use1 + useapr1 > 1) {
+        /* conflict */
+        goto opthelp;
+    }
+
+# ifdef OPENSSL_NO_DES
+    if (usecrypt)
+        goto opthelp;
+# endif
+# ifdef NO_MD5CRYPT_1
+    if (use1 || useapr1)
+        goto opthelp;
+# endif
+
+    if (infile != NULL && in_stdin) {
+        BIO_printf(bio_err, "%s: Can't combine -in and -stdin\n", prog);
+        goto end;
+    }
+
+    if (infile != NULL || in_stdin) {
+        /*
+         * If in_stdin is true, we know that infile is NULL, and that
+         * bio_open_default() will give us back an alias for stdin.
+         */
+        in = bio_open_default(infile, 'r', FORMAT_TEXT);
+        if (in == NULL)
+            goto end;
+    }
+
+    if (usecrypt)
+        pw_maxlen = 8;
+    else if (use1 || useapr1)
+        pw_maxlen = 256;        /* arbitrary limit, should be enough for most
+                                 * passwords */
+
+    if (passwds == NULL) {
+        /* no passwords on the command line */
+
+        passwd_malloc_size = pw_maxlen + 2;
+        /* longer than necessary so that we can warn about truncation */
+        passwd = passwd_malloc =
+            app_malloc(passwd_malloc_size, "password buffer");
+    }
+
+    if ((in == NULL) && (passwds == NULL)) {
+        if (1) {
+#ifndef OPENSSL_NO_UI
+            /* build a null-terminated list */
+            static char *passwds_static[2] = { NULL, NULL };
+
+            passwds = passwds_static;
+            if (in == NULL)
+                if (EVP_read_pw_string
+                    (passwd_malloc, passwd_malloc_size, "Password: ",
+                     !(passed_salt || in_noverify)) != 0)
+                    goto end;
+            passwds[0] = passwd_malloc;
+        } else {
+#endif
+            BIO_printf(bio_err, "password required\n");
+            goto end;
+        }
+    }
+
+
+    if (in == NULL) {
+        assert(passwds != NULL);
+        assert(*passwds != NULL);
+
+        do {                    /* loop over list of passwords */
+            passwd = *passwds++;
+            if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, bio_out,
+                           quiet, table, reverse, pw_maxlen, usecrypt, use1,
+                           useapr1))
+                goto end;
+        }
+        while (*passwds != NULL);
+    } else
+        /* in != NULL */
+    {
+        int done;
+
+        assert(passwd != NULL);
+        do {
+            int r = BIO_gets(in, passwd, pw_maxlen + 1);
+            if (r > 0) {
+                char *c = (strchr(passwd, '\n'));
+                if (c != NULL)
+                    *c = 0;     /* truncate at newline */
+                else {
+                    /* ignore rest of line */
+                    char trash[BUFSIZ];
+                    do
+                        r = BIO_gets(in, trash, sizeof trash);
+                    while ((r > 0) && (!strchr(trash, '\n')));
+                }
+
+                if (!do_passwd
+                    (passed_salt, &salt, &salt_malloc, passwd, bio_out, quiet,
+                     table, reverse, pw_maxlen, usecrypt, use1, useapr1))
+                    goto end;
+            }
+            done = (r <= 0);
+        }
+        while (!done);
+    }
+    ret = 0;
+
+ end:
+    ERR_print_errors(bio_err);
+    OPENSSL_free(salt_malloc);
+    OPENSSL_free(passwd_malloc);
+    BIO_free(in);
+    return (ret);
+}
+
+# ifndef NO_MD5CRYPT_1
+/*
+ * MD5-based password algorithm (should probably be available as a library
+ * function; then the static buffer would not be acceptable). For magic
+ * string "1", this should be compatible to the MD5-based BSD password
+ * algorithm. For 'magic' string "apr1", this is compatible to the MD5-based
+ * Apache password algorithm. (Apparently, the Apache password algorithm is
+ * identical except that the 'magic' string was changed -- the laziest
+ * application of the NIH principle I've ever encountered.)
+ */
+static char *md5crypt(const char *passwd, const char *magic, const char *salt)
+{
+    /* "$apr1$..salt..$.......md5hash..........\0" */
+    static char out_buf[6 + 9 + 24 + 2];
+    unsigned char buf[MD5_DIGEST_LENGTH];
+    char *salt_out;
+    int n;
+    unsigned int i;
+    EVP_MD_CTX *md = NULL, *md2 = NULL;
+    size_t passwd_len, salt_len, magic_len;
+
+    passwd_len = strlen(passwd);
+    out_buf[0] = '$';
+    out_buf[1] = 0;
+    magic_len = strlen(magic);
+
+    if (magic_len > 4)    /* assert it's  "1" or "apr1" */
+        return NULL;
+
+    OPENSSL_strlcat(out_buf, magic, sizeof out_buf);
+    OPENSSL_strlcat(out_buf, "$", sizeof out_buf);
+    OPENSSL_strlcat(out_buf, salt, sizeof out_buf);
+
+    if (strlen(out_buf) > 6 + 8) /* assert "$apr1$..salt.." */
+        return NULL;
+
+    salt_out = out_buf + 2 + magic_len;
+    salt_len = strlen(salt_out);
+
+    if (salt_len > 8)
+        return NULL;
+
+    md = EVP_MD_CTX_new();
+    if (md == NULL
+        || !EVP_DigestInit_ex(md, EVP_md5(), NULL)
+        || !EVP_DigestUpdate(md, passwd, passwd_len)
+        || !EVP_DigestUpdate(md, "$", 1)
+        || !EVP_DigestUpdate(md, magic, magic_len)
+        || !EVP_DigestUpdate(md, "$", 1)
+        || !EVP_DigestUpdate(md, salt_out, salt_len))
+        goto err;
+
+    md2 = EVP_MD_CTX_new();
+    if (md2 == NULL
+        || !EVP_DigestInit_ex(md2, EVP_md5(), NULL)
+        || !EVP_DigestUpdate(md2, passwd, passwd_len)
+        || !EVP_DigestUpdate(md2, salt_out, salt_len)
+        || !EVP_DigestUpdate(md2, passwd, passwd_len)
+        || !EVP_DigestFinal_ex(md2, buf, NULL))
+        goto err;
+
+    for (i = passwd_len; i > sizeof buf; i -= sizeof buf) {
+        if (!EVP_DigestUpdate(md, buf, sizeof buf))
+            goto err;
+    }
+    if (!EVP_DigestUpdate(md, buf, i))
+        goto err;
+
+    n = passwd_len;
+    while (n) {
+        if (!EVP_DigestUpdate(md, (n & 1) ? "\0" : passwd, 1))
+            goto err;
+        n >>= 1;
+    }
+    if (!EVP_DigestFinal_ex(md, buf, NULL))
+        return NULL;
+
+    for (i = 0; i < 1000; i++) {
+        if (!EVP_DigestInit_ex(md2, EVP_md5(), NULL))
+            goto err;
+        if (!EVP_DigestUpdate(md2,
+                              (i & 1) ? (unsigned const char *)passwd : buf,
+                              (i & 1) ? passwd_len : sizeof buf))
+            goto err;
+        if (i % 3) {
+            if (!EVP_DigestUpdate(md2, salt_out, salt_len))
+                goto err;
+        }
+        if (i % 7) {
+            if (!EVP_DigestUpdate(md2, passwd, passwd_len))
+                goto err;
+        }
+        if (!EVP_DigestUpdate(md2,
+                              (i & 1) ? buf : (unsigned const char *)passwd,
+                              (i & 1) ? sizeof buf : passwd_len))
+                goto err;
+        if (!EVP_DigestFinal_ex(md2, buf, NULL))
+                goto err;
+    }
+    EVP_MD_CTX_free(md2);
+    EVP_MD_CTX_free(md);
+    md2 = NULL;
+    md = NULL;
+
+    {
+        /* transform buf into output string */
+        unsigned char buf_perm[sizeof buf];
+        int dest, source;
+        char *output;
+
+        /* silly output permutation */
+        for (dest = 0, source = 0; dest < 14;
+             dest++, source = (source + 6) % 17)
+            buf_perm[dest] = buf[source];
+        buf_perm[14] = buf[5];
+        buf_perm[15] = buf[11];
+#  ifndef PEDANTIC              /* Unfortunately, this generates a "no
+                                 * effect" warning */
+        assert(16 == sizeof buf_perm);
+#  endif
+
+        output = salt_out + salt_len;
+        assert(output == out_buf + strlen(out_buf));
+
+        *output++ = '$';
+
+        for (i = 0; i < 15; i += 3) {
+            *output++ = cov_2char[buf_perm[i + 2] & 0x3f];
+            *output++ = cov_2char[((buf_perm[i + 1] & 0xf) << 2) |
+                                  (buf_perm[i + 2] >> 6)];
+            *output++ = cov_2char[((buf_perm[i] & 3) << 4) |
+                                  (buf_perm[i + 1] >> 4)];
+            *output++ = cov_2char[buf_perm[i] >> 2];
+        }
+        assert(i == 15);
+        *output++ = cov_2char[buf_perm[i] & 0x3f];
+        *output++ = cov_2char[buf_perm[i] >> 6];
+        *output = 0;
+        assert(strlen(out_buf) < sizeof(out_buf));
+    }
+
+    return out_buf;
+
+ err:
+    EVP_MD_CTX_free(md2);
+    EVP_MD_CTX_free(md);
+    return NULL;
+}
+# endif
+
+static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
+                     char *passwd, BIO *out, int quiet, int table,
+                     int reverse, size_t pw_maxlen, int usecrypt, int use1,
+                     int useapr1)
+{
+    char *hash = NULL;
+
+    assert(salt_p != NULL);
+    assert(salt_malloc_p != NULL);
+
+    /* first make sure we have a salt */
+    if (!passed_salt) {
+# ifndef OPENSSL_NO_DES
+        if (usecrypt) {
+            if (*salt_malloc_p == NULL) {
+                *salt_p = *salt_malloc_p = app_malloc(3, "salt buffer");
+            }
+            if (RAND_bytes((unsigned char *)*salt_p, 2) <= 0)
+                goto end;
+            (*salt_p)[0] = cov_2char[(*salt_p)[0] & 0x3f]; /* 6 bits */
+            (*salt_p)[1] = cov_2char[(*salt_p)[1] & 0x3f]; /* 6 bits */
+            (*salt_p)[2] = 0;
+#  ifdef CHARSET_EBCDIC
+            ascii2ebcdic(*salt_p, *salt_p, 2); /* des_crypt will convert back
+                                                * to ASCII */
+#  endif
+        }
+# endif                         /* !OPENSSL_NO_DES */
+
+# ifndef NO_MD5CRYPT_1
+        if (use1 || useapr1) {
+            int i;
+
+            if (*salt_malloc_p == NULL) {
+                *salt_p = *salt_malloc_p = app_malloc(9, "salt buffer");
+            }
+            if (RAND_bytes((unsigned char *)*salt_p, 8) <= 0)
+                goto end;
+
+            for (i = 0; i < 8; i++)
+                (*salt_p)[i] = cov_2char[(*salt_p)[i] & 0x3f]; /* 6 bits */
+            (*salt_p)[8] = 0;
+        }
+# endif                         /* !NO_MD5CRYPT_1 */
+    }
+
+    assert(*salt_p != NULL);
+
+    /* truncate password if necessary */
+    if ((strlen(passwd) > pw_maxlen)) {
+        if (!quiet)
+            /*
+             * XXX: really we should know how to print a size_t, not cast it
+             */
+            BIO_printf(bio_err,
+                       "Warning: truncating password to %u characters\n",
+                       (unsigned)pw_maxlen);
+        passwd[pw_maxlen] = 0;
+    }
+    assert(strlen(passwd) <= pw_maxlen);
+
+    /* now compute password hash */
+# ifndef OPENSSL_NO_DES
+    if (usecrypt)
+        hash = DES_crypt(passwd, *salt_p);
+# endif
+# ifndef NO_MD5CRYPT_1
+    if (use1 || useapr1)
+        hash = md5crypt(passwd, (use1 ? "1" : "apr1"), *salt_p);
+# endif
+    assert(hash != NULL);
+
+    if (table && !reverse)
+        BIO_printf(out, "%s\t%s\n", passwd, hash);
+    else if (table && reverse)
+        BIO_printf(out, "%s\t%s\n", hash, passwd);
+    else
+        BIO_printf(out, "%s\n", hash);
+    return 1;
+
+ end:
+    return 0;
+}
+#else
+
+int passwd_main(int argc, char **argv)
+{
+    BIO_printf(bio_err, "Program not available.\n");
+    return (1);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/pkcs12.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/pkcs12.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/pkcs12.c	(revision 331)
@@ -0,0 +1,935 @@
+/*
+ * Copyright 1999-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 <openssl/opensslconf.h>
+#if defined(OPENSSL_NO_DES)
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+# include "apps.h"
+# include <openssl/crypto.h>
+# include <openssl/err.h>
+# include <openssl/pem.h>
+# include <openssl/pkcs12.h>
+
+# define NOKEYS          0x1
+# define NOCERTS         0x2
+# define INFO            0x4
+# define CLCERTS         0x8
+# define CACERTS         0x10
+
+static int get_cert_chain(X509 *cert, X509_STORE *store,
+                          STACK_OF(X509) **chain);
+int dump_certs_keys_p12(BIO *out, const PKCS12 *p12,
+                        const char *pass, int passlen, int options,
+                        char *pempass, const EVP_CIPHER *enc);
+int dump_certs_pkeys_bags(BIO *out, const STACK_OF(PKCS12_SAFEBAG) *bags,
+                          const char *pass, int passlen, int options,
+                          char *pempass, const EVP_CIPHER *enc);
+int dump_certs_pkeys_bag(BIO *out, const PKCS12_SAFEBAG *bags,
+                         const char *pass, int passlen,
+                         int options, char *pempass, const EVP_CIPHER *enc);
+int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst,
+                  const char *name);
+void hex_prin(BIO *out, unsigned char *buf, int len);
+static int alg_print(const X509_ALGOR *alg);
+int cert_load(BIO *in, STACK_OF(X509) *sk);
+static int set_pbe(int *ppbe, const char *str);
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_CIPHER, OPT_NOKEYS, OPT_KEYEX, OPT_KEYSIG, OPT_NOCERTS, OPT_CLCERTS,
+    OPT_CACERTS, OPT_NOOUT, OPT_INFO, OPT_CHAIN, OPT_TWOPASS, OPT_NOMACVER,
+    OPT_DESCERT, OPT_EXPORT, OPT_NOITER, OPT_MACITER, OPT_NOMACITER,
+    OPT_NOMAC, OPT_LMK, OPT_NODES, OPT_MACALG, OPT_CERTPBE, OPT_KEYPBE,
+    OPT_RAND, OPT_INKEY, OPT_CERTFILE, OPT_NAME, OPT_CSP, OPT_CANAME,
+    OPT_IN, OPT_OUT, OPT_PASSIN, OPT_PASSOUT, OPT_PASSWORD, OPT_CAPATH,
+    OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_ENGINE
+} OPTION_CHOICE;
+
+OPTIONS pkcs12_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"nokeys", OPT_NOKEYS, '-', "Don't output private keys"},
+    {"keyex", OPT_KEYEX, '-', "Set MS key exchange type"},
+    {"keysig", OPT_KEYSIG, '-', "Set MS key signature type"},
+    {"nocerts", OPT_NOCERTS, '-', "Don't output certificates"},
+    {"clcerts", OPT_CLCERTS, '-', "Only output client certificates"},
+    {"cacerts", OPT_CACERTS, '-', "Only output CA certificates"},
+    {"noout", OPT_NOOUT, '-', "Don't output anything, just verify"},
+    {"info", OPT_INFO, '-', "Print info about PKCS#12 structure"},
+    {"chain", OPT_CHAIN, '-', "Add certificate chain"},
+    {"twopass", OPT_TWOPASS, '-', "Separate MAC, encryption passwords"},
+    {"nomacver", OPT_NOMACVER, '-', "Don't verify MAC"},
+# ifndef OPENSSL_NO_RC2
+    {"descert", OPT_DESCERT, '-',
+     "Encrypt output with 3DES (default RC2-40)"},
+    {"certpbe", OPT_CERTPBE, 's',
+     "Certificate PBE algorithm (default RC2-40)"},
+# else
+    {"descert", OPT_DESCERT, '-', "Encrypt output with 3DES (the default)"},
+    {"certpbe", OPT_CERTPBE, 's', "Certificate PBE algorithm (default 3DES)"},
+# endif
+    {"export", OPT_EXPORT, '-', "Output PKCS12 file"},
+    {"noiter", OPT_NOITER, '-', "Don't use encryption iteration"},
+    {"maciter", OPT_MACITER, '-', "Use MAC iteration"},
+    {"nomaciter", OPT_NOMACITER, '-', "Don't use MAC iteration"},
+    {"nomac", OPT_NOMAC, '-', "Don't generate MAC"},
+    {"LMK", OPT_LMK, '-',
+     "Add local machine keyset attribute to private key"},
+    {"nodes", OPT_NODES, '-', "Don't encrypt private keys"},
+    {"macalg", OPT_MACALG, 's',
+     "Digest algorithm used in MAC (default SHA1)"},
+    {"keypbe", OPT_KEYPBE, 's', "Private key PBE algorithm (default 3DES)"},
+    {"rand", OPT_RAND, 's',
+     "Load the file(s) into the random number generator"},
+    {"inkey", OPT_INKEY, '<', "Private key if not infile"},
+    {"certfile", OPT_CERTFILE, '<', "Load certs from file"},
+    {"name", OPT_NAME, 's', "Use name as friendly name"},
+    {"CSP", OPT_CSP, 's', "Microsoft CSP name"},
+    {"caname", OPT_CANAME, 's',
+     "Use name as CA friendly name (can be repeated)"},
+    {"in", OPT_IN, '<', "Input filename"},
+    {"out", OPT_OUT, '>', "Output filename"},
+    {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
+    {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
+    {"password", OPT_PASSWORD, 's', "Set import/export password source"},
+    {"CApath", OPT_CAPATH, '/', "PEM-format directory of CA's"},
+    {"CAfile", OPT_CAFILE, '<', "PEM-format file of CA's"},
+    {"no-CAfile", OPT_NOCAFILE, '-',
+     "Do not load the default certificates file"},
+    {"no-CApath", OPT_NOCAPATH, '-',
+     "Do not load certificates from the default certificates directory"},
+    {"", OPT_CIPHER, '-', "Any supported cipher"},
+# ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+# endif
+    {NULL}
+};
+
+int pkcs12_main(int argc, char **argv)
+{
+    char *infile = NULL, *outfile = NULL, *keyname = NULL, *certfile = NULL;
+    char *name = NULL, *csp_name = NULL;
+    char pass[2048] = "", macpass[2048] = "";
+    int export_cert = 0, options = 0, chain = 0, twopass = 0, keytype = 0;
+    int iter = PKCS12_DEFAULT_ITER, maciter = PKCS12_DEFAULT_ITER;
+# ifndef OPENSSL_NO_RC2
+    int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
+# else
+    int cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+# endif
+    int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+    int ret = 1, macver = 1, add_lmk = 0, private = 0;
+    int noprompt = 0;
+    char *passinarg = NULL, *passoutarg = NULL, *passarg = NULL;
+    char *passin = NULL, *passout = NULL, *inrand = NULL, *macalg = NULL;
+    char *cpass = NULL, *mpass = NULL, *badpass = NULL;
+    const char *CApath = NULL, *CAfile = NULL, *prog;
+    int noCApath = 0, noCAfile = 0;
+    ENGINE *e = NULL;
+    BIO *in = NULL, *out = NULL;
+    PKCS12 *p12 = NULL;
+    STACK_OF(OPENSSL_STRING) *canames = NULL;
+    const EVP_CIPHER *enc = EVP_des_ede3_cbc();
+    OPTION_CHOICE o;
+
+    prog = opt_init(argc, argv, pkcs12_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(pkcs12_options);
+            ret = 0;
+            goto end;
+        case OPT_NOKEYS:
+            options |= NOKEYS;
+            break;
+        case OPT_KEYEX:
+            keytype = KEY_EX;
+            break;
+        case OPT_KEYSIG:
+            keytype = KEY_SIG;
+            break;
+        case OPT_NOCERTS:
+            options |= NOCERTS;
+            break;
+        case OPT_CLCERTS:
+            options |= CLCERTS;
+            break;
+        case OPT_CACERTS:
+            options |= CACERTS;
+            break;
+        case OPT_NOOUT:
+            options |= (NOKEYS | NOCERTS);
+            break;
+        case OPT_INFO:
+            options |= INFO;
+            break;
+        case OPT_CHAIN:
+            chain = 1;
+            break;
+        case OPT_TWOPASS:
+            twopass = 1;
+            break;
+        case OPT_NOMACVER:
+            macver = 0;
+            break;
+        case OPT_DESCERT:
+            cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+            break;
+        case OPT_EXPORT:
+            export_cert = 1;
+            break;
+        case OPT_CIPHER:
+            if (!opt_cipher(opt_unknown(), &enc))
+                goto opthelp;
+            break;
+        case OPT_NOITER:
+            iter = 1;
+            break;
+        case OPT_MACITER:
+            maciter = PKCS12_DEFAULT_ITER;
+            break;
+        case OPT_NOMACITER:
+            maciter = 1;
+            break;
+        case OPT_NOMAC:
+            maciter = -1;
+            break;
+        case OPT_MACALG:
+            macalg = opt_arg();
+            break;
+        case OPT_NODES:
+            enc = NULL;
+            break;
+        case OPT_CERTPBE:
+            if (!set_pbe(&cert_pbe, opt_arg()))
+                goto opthelp;
+            break;
+        case OPT_KEYPBE:
+            if (!set_pbe(&key_pbe, opt_arg()))
+                goto opthelp;
+            break;
+        case OPT_RAND:
+            inrand = opt_arg();
+            break;
+        case OPT_INKEY:
+            keyname = opt_arg();
+            break;
+        case OPT_CERTFILE:
+            certfile = opt_arg();
+            break;
+        case OPT_NAME:
+            name = opt_arg();
+            break;
+        case OPT_LMK:
+            add_lmk = 1;
+            break;
+        case OPT_CSP:
+            csp_name = opt_arg();
+            break;
+        case OPT_CANAME:
+            if (canames == NULL
+                && (canames = sk_OPENSSL_STRING_new_null()) == NULL)
+                goto end;
+            sk_OPENSSL_STRING_push(canames, opt_arg());
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_PASSIN:
+            passinarg = opt_arg();
+            break;
+        case OPT_PASSOUT:
+            passoutarg = opt_arg();
+            break;
+        case OPT_PASSWORD:
+            passarg = opt_arg();
+            break;
+        case OPT_CAPATH:
+            CApath = opt_arg();
+            break;
+        case OPT_CAFILE:
+            CAfile = opt_arg();
+            break;
+        case OPT_NOCAPATH:
+            noCApath = 1;
+            break;
+        case OPT_NOCAFILE:
+            noCAfile = 1;
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    private = 1;
+
+    if (passarg) {
+        if (export_cert)
+            passoutarg = passarg;
+        else
+            passinarg = passarg;
+    }
+
+    if (!app_passwd(passinarg, passoutarg, &passin, &passout)) {
+        BIO_printf(bio_err, "Error getting passwords\n");
+        goto end;
+    }
+
+    if (!cpass) {
+        if (export_cert)
+            cpass = passout;
+        else
+            cpass = passin;
+    }
+
+    if (cpass) {
+        mpass = cpass;
+        noprompt = 1;
+    } else {
+        cpass = pass;
+        mpass = macpass;
+    }
+
+    if (export_cert || inrand) {
+        app_RAND_load_file(NULL, (inrand != NULL));
+        if (inrand != NULL)
+            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
+                       app_RAND_load_files(inrand));
+    }
+
+    if (twopass) {
+        if (1) {
+#ifndef OPENSSL_NO_UI
+            if (EVP_read_pw_string
+                (macpass, sizeof macpass, "Enter MAC Password:", export_cert)) {
+                BIO_printf(bio_err, "Can't read Password\n");
+                goto end;
+            }
+        } else {
+#endif
+            BIO_printf(bio_err, "Unsupported option -twopass\n");
+            goto end;
+        }
+    }
+
+    if (export_cert) {
+        EVP_PKEY *key = NULL;
+        X509 *ucert = NULL, *x = NULL;
+        STACK_OF(X509) *certs = NULL;
+        const EVP_MD *macmd = NULL;
+        unsigned char *catmp = NULL;
+        int i;
+
+        if ((options & (NOCERTS | NOKEYS)) == (NOCERTS | NOKEYS)) {
+            BIO_printf(bio_err, "Nothing to do!\n");
+            goto export_end;
+        }
+
+        if (options & NOCERTS)
+            chain = 0;
+
+        if (!(options & NOKEYS)) {
+            key = load_key(keyname ? keyname : infile,
+                           FORMAT_PEM, 1, passin, e, "private key");
+            if (!key)
+                goto export_end;
+        }
+
+        /* Load in all certs in input file */
+        if (!(options & NOCERTS)) {
+            if (!load_certs(infile, &certs, FORMAT_PEM, NULL,
+                            "certificates"))
+                goto export_end;
+
+            if (key) {
+                /* Look for matching private key */
+                for (i = 0; i < sk_X509_num(certs); i++) {
+                    x = sk_X509_value(certs, i);
+                    if (X509_check_private_key(x, key)) {
+                        ucert = x;
+                        /* Zero keyid and alias */
+                        X509_keyid_set1(ucert, NULL, 0);
+                        X509_alias_set1(ucert, NULL, 0);
+                        /* Remove from list */
+                        (void)sk_X509_delete(certs, i);
+                        break;
+                    }
+                }
+                if (!ucert) {
+                    BIO_printf(bio_err,
+                               "No certificate matches private key\n");
+                    goto export_end;
+                }
+            }
+
+        }
+
+        /* Add any more certificates asked for */
+        if (certfile) {
+            if (!load_certs(certfile, &certs, FORMAT_PEM, NULL,
+                            "certificates from certfile"))
+                goto export_end;
+        }
+
+        /* If chaining get chain from user cert */
+        if (chain) {
+            int vret;
+            STACK_OF(X509) *chain2;
+            X509_STORE *store;
+            if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath))
+                    == NULL)
+                goto export_end;
+
+            vret = get_cert_chain(ucert, store, &chain2);
+            X509_STORE_free(store);
+
+            if (vret == X509_V_OK) {
+                /* Exclude verified certificate */
+                for (i = 1; i < sk_X509_num(chain2); i++)
+                    sk_X509_push(certs, sk_X509_value(chain2, i));
+                /* Free first certificate */
+                X509_free(sk_X509_value(chain2, 0));
+                sk_X509_free(chain2);
+            } else {
+                if (vret != X509_V_ERR_UNSPECIFIED)
+                    BIO_printf(bio_err, "Error %s getting chain.\n",
+                               X509_verify_cert_error_string(vret));
+                else
+                    ERR_print_errors(bio_err);
+                goto export_end;
+            }
+        }
+
+        /* Add any CA names */
+
+        for (i = 0; i < sk_OPENSSL_STRING_num(canames); i++) {
+            catmp = (unsigned char *)sk_OPENSSL_STRING_value(canames, i);
+            X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
+        }
+
+        if (csp_name && key)
+            EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name,
+                                      MBSTRING_ASC, (unsigned char *)csp_name,
+                                      -1);
+
+        if (add_lmk && key)
+            EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1);
+
+        if (!noprompt) {
+            if (1) {
+#ifndef OPENSSL_NO_UI
+                if (EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:",
+                                       1)) {
+                    BIO_printf(bio_err, "Can't read Password\n");
+                    goto export_end;
+                }
+            } else {
+#endif
+                BIO_printf(bio_err, "Password required\n");
+                goto export_end;
+            }
+        }
+
+        if (!twopass)
+            OPENSSL_strlcpy(macpass, pass, sizeof macpass);
+
+        p12 = PKCS12_create(cpass, name, key, ucert, certs,
+                            key_pbe, cert_pbe, iter, -1, keytype);
+
+        if (!p12) {
+            ERR_print_errors(bio_err);
+            goto export_end;
+        }
+
+        if (macalg) {
+            if (!opt_md(macalg, &macmd))
+                goto opthelp;
+        }
+
+        if (maciter != -1)
+            PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd);
+
+        assert(private);
+
+        out = bio_open_owner(outfile, FORMAT_PKCS12, private);
+        if (out == NULL)
+            goto end;
+
+        i2d_PKCS12_bio(out, p12);
+
+        ret = 0;
+
+ export_end:
+
+        EVP_PKEY_free(key);
+        sk_X509_pop_free(certs, X509_free);
+        X509_free(ucert);
+
+        goto end;
+
+    }
+
+    in = bio_open_default(infile, 'r', FORMAT_PKCS12);
+    if (in == NULL)
+        goto end;
+    out = bio_open_owner(outfile, FORMAT_PEM, private);
+    if (out == NULL)
+        goto end;
+
+    if ((p12 = d2i_PKCS12_bio(in, NULL)) == NULL) {
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    if (!noprompt) {
+        if (1) {
+#ifndef OPENSSL_NO_UI
+            if (EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:",
+                                   0)) {
+                BIO_printf(bio_err, "Can't read Password\n");
+                goto end;
+            }
+        } else {
+#endif
+            BIO_printf(bio_err, "Password required\n");
+            goto end;
+        }
+    }
+
+    if (!twopass)
+        OPENSSL_strlcpy(macpass, pass, sizeof macpass);
+
+    if ((options & INFO) && PKCS12_mac_present(p12)) {
+        const ASN1_INTEGER *tmaciter;
+        const X509_ALGOR *macalgid;
+        const ASN1_OBJECT *macobj;
+        PKCS12_get0_mac(NULL, &macalgid, NULL, &tmaciter, p12);
+        X509_ALGOR_get0(&macobj, NULL, NULL, macalgid);
+        BIO_puts(bio_err, "MAC:");
+        i2a_ASN1_OBJECT(bio_err, macobj);
+        BIO_printf(bio_err, " Iteration %ld\n",
+                   tmaciter  != NULL ? ASN1_INTEGER_get(tmaciter) : 1L);
+    }
+    if (macver) {
+        /* If we enter empty password try no password first */
+        if (!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) {
+            /* If mac and crypto pass the same set it to NULL too */
+            if (!twopass)
+                cpass = NULL;
+        } else if (!PKCS12_verify_mac(p12, mpass, -1)) {
+            /*
+             * May be UTF8 from previous version of OpenSSL:
+             * convert to a UTF8 form which will translate
+             * to the same Unicode password.
+             */
+            unsigned char *utmp;
+            int utmplen;
+            utmp = OPENSSL_asc2uni(mpass, -1, NULL, &utmplen);
+            if (utmp == NULL)
+                goto end;
+            badpass = OPENSSL_uni2utf8(utmp, utmplen);
+            OPENSSL_free(utmp);
+            if (!PKCS12_verify_mac(p12, badpass, -1)) {
+                BIO_printf(bio_err, "Mac verify error: invalid password?\n");
+                ERR_print_errors(bio_err);
+                goto end;
+            } else {
+                BIO_printf(bio_err, "Warning: using broken algorithm\n");
+                if (!twopass)
+                    cpass = badpass;
+            }
+        }
+    }
+
+    assert(private);
+    if (!dump_certs_keys_p12(out, p12, cpass, -1, options, passout, enc)) {
+        BIO_printf(bio_err, "Error outputting keys and certificates\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+    ret = 0;
+ end:
+    PKCS12_free(p12);
+    if (export_cert || inrand)
+        app_RAND_write_file(NULL);
+    release_engine(e);
+    BIO_free(in);
+    BIO_free_all(out);
+    sk_OPENSSL_STRING_free(canames);
+    OPENSSL_free(badpass);
+    OPENSSL_free(passin);
+    OPENSSL_free(passout);
+    return (ret);
+}
+
+int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass,
+                        int passlen, int options, char *pempass,
+                        const EVP_CIPHER *enc)
+{
+    STACK_OF(PKCS7) *asafes = NULL;
+    STACK_OF(PKCS12_SAFEBAG) *bags;
+    int i, bagnid;
+    int ret = 0;
+    PKCS7 *p7;
+
+    if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
+        return 0;
+    for (i = 0; i < sk_PKCS7_num(asafes); i++) {
+        p7 = sk_PKCS7_value(asafes, i);
+        bagnid = OBJ_obj2nid(p7->type);
+        if (bagnid == NID_pkcs7_data) {
+            bags = PKCS12_unpack_p7data(p7);
+            if (options & INFO)
+                BIO_printf(bio_err, "PKCS7 Data\n");
+        } else if (bagnid == NID_pkcs7_encrypted) {
+            if (options & INFO) {
+                BIO_printf(bio_err, "PKCS7 Encrypted data: ");
+                alg_print(p7->d.encrypted->enc_data->algorithm);
+            }
+            bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
+        } else
+            continue;
+        if (!bags)
+            goto err;
+        if (!dump_certs_pkeys_bags(out, bags, pass, passlen,
+                                   options, pempass, enc)) {
+            sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+            goto err;
+        }
+        sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+        bags = NULL;
+    }
+    ret = 1;
+
+ err:
+    sk_PKCS7_pop_free(asafes, PKCS7_free);
+    return ret;
+}
+
+int dump_certs_pkeys_bags(BIO *out, const STACK_OF(PKCS12_SAFEBAG) *bags,
+                          const char *pass, int passlen, int options,
+                          char *pempass, const EVP_CIPHER *enc)
+{
+    int i;
+    for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
+        if (!dump_certs_pkeys_bag(out,
+                                  sk_PKCS12_SAFEBAG_value(bags, i),
+                                  pass, passlen, options, pempass, enc))
+            return 0;
+    }
+    return 1;
+}
+
+int dump_certs_pkeys_bag(BIO *out, const PKCS12_SAFEBAG *bag,
+                         const char *pass, int passlen, int options,
+                         char *pempass, const EVP_CIPHER *enc)
+{
+    EVP_PKEY *pkey;
+    PKCS8_PRIV_KEY_INFO *p8;
+    const PKCS8_PRIV_KEY_INFO *p8c;
+    X509 *x509;
+    const STACK_OF(X509_ATTRIBUTE) *attrs;
+    int ret = 0;
+
+    attrs = PKCS12_SAFEBAG_get0_attrs(bag);
+
+    switch (PKCS12_SAFEBAG_get_nid(bag)) {
+    case NID_keyBag:
+        if (options & INFO)
+            BIO_printf(bio_err, "Key bag\n");
+        if (options & NOKEYS)
+            return 1;
+        print_attribs(out, attrs, "Bag Attributes");
+        p8c = PKCS12_SAFEBAG_get0_p8inf(bag);
+        if ((pkey = EVP_PKCS82PKEY(p8c)) == NULL)
+            return 0;
+        print_attribs(out, PKCS8_pkey_get0_attrs(p8c), "Key Attributes");
+        ret = PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass);
+        EVP_PKEY_free(pkey);
+        break;
+
+    case NID_pkcs8ShroudedKeyBag:
+        if (options & INFO) {
+            const X509_SIG *tp8;
+            const X509_ALGOR *tp8alg;
+
+            BIO_printf(bio_err, "Shrouded Keybag: ");
+            tp8 = PKCS12_SAFEBAG_get0_pkcs8(bag);
+            X509_SIG_get0(tp8, &tp8alg, NULL);
+            alg_print(tp8alg);
+        }
+        if (options & NOKEYS)
+            return 1;
+        print_attribs(out, attrs, "Bag Attributes");
+        if ((p8 = PKCS12_decrypt_skey(bag, pass, passlen)) == NULL)
+            return 0;
+        if ((pkey = EVP_PKCS82PKEY(p8)) == NULL) {
+            PKCS8_PRIV_KEY_INFO_free(p8);
+            return 0;
+        }
+        print_attribs(out, PKCS8_pkey_get0_attrs(p8), "Key Attributes");
+        PKCS8_PRIV_KEY_INFO_free(p8);
+        ret = PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, pempass);
+        EVP_PKEY_free(pkey);
+        break;
+
+    case NID_certBag:
+        if (options & INFO)
+            BIO_printf(bio_err, "Certificate bag\n");
+        if (options & NOCERTS)
+            return 1;
+        if (PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID)) {
+            if (options & CACERTS)
+                return 1;
+        } else if (options & CLCERTS)
+            return 1;
+        print_attribs(out, attrs, "Bag Attributes");
+        if (PKCS12_SAFEBAG_get_bag_nid(bag) != NID_x509Certificate)
+            return 1;
+        if ((x509 = PKCS12_SAFEBAG_get1_cert(bag)) == NULL)
+            return 0;
+        dump_cert_text(out, x509);
+        ret = PEM_write_bio_X509(out, x509);
+        X509_free(x509);
+        break;
+
+    case NID_safeContentsBag:
+        if (options & INFO)
+            BIO_printf(bio_err, "Safe Contents bag\n");
+        print_attribs(out, attrs, "Bag Attributes");
+        return dump_certs_pkeys_bags(out, PKCS12_SAFEBAG_get0_safes(bag),
+                                     pass, passlen, options, pempass, enc);
+
+    default:
+        BIO_printf(bio_err, "Warning unsupported bag type: ");
+        i2a_ASN1_OBJECT(bio_err, PKCS12_SAFEBAG_get0_type(bag));
+        BIO_printf(bio_err, "\n");
+        return 1;
+    }
+    return ret;
+}
+
+/* Given a single certificate return a verified chain or NULL if error */
+
+static int get_cert_chain(X509 *cert, X509_STORE *store,
+                          STACK_OF(X509) **chain)
+{
+    X509_STORE_CTX *store_ctx = NULL;
+    STACK_OF(X509) *chn = NULL;
+    int i = 0;
+
+    store_ctx = X509_STORE_CTX_new();
+    if (store_ctx == NULL) {
+        i =  X509_V_ERR_UNSPECIFIED;
+        goto end;
+    }
+    if (!X509_STORE_CTX_init(store_ctx, store, cert, NULL)) {
+        i =  X509_V_ERR_UNSPECIFIED;
+        goto end;
+    }
+
+
+    if (X509_verify_cert(store_ctx) > 0)
+        chn = X509_STORE_CTX_get1_chain(store_ctx);
+    else if ((i = X509_STORE_CTX_get_error(store_ctx)) == 0)
+        i = X509_V_ERR_UNSPECIFIED;
+
+end:
+    X509_STORE_CTX_free(store_ctx);
+    *chain = chn;
+    return i;
+}
+
+static int alg_print(const X509_ALGOR *alg)
+{
+    int pbenid, aparamtype;
+    const ASN1_OBJECT *aoid;
+    const void *aparam;
+    PBEPARAM *pbe = NULL;
+
+    X509_ALGOR_get0(&aoid, &aparamtype, &aparam, alg);
+
+    pbenid = OBJ_obj2nid(aoid);
+
+    BIO_printf(bio_err, "%s", OBJ_nid2ln(pbenid));
+
+    /*
+     * If PBE algorithm is PBES2 decode algorithm parameters
+     * for additional details.
+     */
+    if (pbenid == NID_pbes2) {
+        PBE2PARAM *pbe2 = NULL;
+        int encnid;
+        if (aparamtype == V_ASN1_SEQUENCE)
+            pbe2 = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBE2PARAM));
+        if (pbe2 == NULL) {
+            BIO_puts(bio_err, "<unsupported parameters>");
+            goto done;
+        }
+        X509_ALGOR_get0(&aoid, &aparamtype, &aparam, pbe2->keyfunc);
+        pbenid = OBJ_obj2nid(aoid);
+        X509_ALGOR_get0(&aoid, NULL, NULL, pbe2->encryption);
+        encnid = OBJ_obj2nid(aoid);
+        BIO_printf(bio_err, ", %s, %s", OBJ_nid2ln(pbenid),
+                   OBJ_nid2sn(encnid));
+        /* If KDF is PBKDF2 decode parameters */
+        if (pbenid == NID_id_pbkdf2) {
+            PBKDF2PARAM *kdf = NULL;
+            int prfnid;
+            if (aparamtype == V_ASN1_SEQUENCE)
+                kdf = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBKDF2PARAM));
+            if (kdf == NULL) {
+                BIO_puts(bio_err, "<unsupported parameters>");
+                goto done;
+            }
+
+            if (kdf->prf == NULL) {
+                prfnid = NID_hmacWithSHA1;
+            } else {
+                X509_ALGOR_get0(&aoid, NULL, NULL, kdf->prf);
+                prfnid = OBJ_obj2nid(aoid);
+            }
+            BIO_printf(bio_err, ", Iteration %ld, PRF %s",
+                       ASN1_INTEGER_get(kdf->iter), OBJ_nid2sn(prfnid));
+            PBKDF2PARAM_free(kdf);
+        }
+        PBE2PARAM_free(pbe2);
+    } else {
+        if (aparamtype == V_ASN1_SEQUENCE)
+            pbe = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBEPARAM));
+        if (pbe == NULL) {
+            BIO_puts(bio_err, "<unsupported parameters>");
+            goto done;
+        }
+        BIO_printf(bio_err, ", Iteration %ld", ASN1_INTEGER_get(pbe->iter));
+        PBEPARAM_free(pbe);
+    }
+ done:
+    BIO_puts(bio_err, "\n");
+    return 1;
+}
+
+/* Load all certificates from a given file */
+
+int cert_load(BIO *in, STACK_OF(X509) *sk)
+{
+    int ret;
+    X509 *cert;
+    ret = 0;
+    while ((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
+        ret = 1;
+        sk_X509_push(sk, cert);
+    }
+    if (ret)
+        ERR_clear_error();
+    return ret;
+}
+
+/* Generalised attribute print: handle PKCS#8 and bag attributes */
+
+int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst,
+                  const char *name)
+{
+    X509_ATTRIBUTE *attr;
+    ASN1_TYPE *av;
+    char *value;
+    int i, attr_nid;
+    if (!attrlst) {
+        BIO_printf(out, "%s: <No Attributes>\n", name);
+        return 1;
+    }
+    if (!sk_X509_ATTRIBUTE_num(attrlst)) {
+        BIO_printf(out, "%s: <Empty Attributes>\n", name);
+        return 1;
+    }
+    BIO_printf(out, "%s\n", name);
+    for (i = 0; i < sk_X509_ATTRIBUTE_num(attrlst); i++) {
+        ASN1_OBJECT *attr_obj;
+        attr = sk_X509_ATTRIBUTE_value(attrlst, i);
+        attr_obj = X509_ATTRIBUTE_get0_object(attr);
+        attr_nid = OBJ_obj2nid(attr_obj);
+        BIO_printf(out, "    ");
+        if (attr_nid == NID_undef) {
+            i2a_ASN1_OBJECT(out, attr_obj);
+            BIO_printf(out, ": ");
+        } else
+            BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid));
+
+        if (X509_ATTRIBUTE_count(attr)) {
+            av = X509_ATTRIBUTE_get0_type(attr, 0);
+            switch (av->type) {
+            case V_ASN1_BMPSTRING:
+                value = OPENSSL_uni2asc(av->value.bmpstring->data,
+                                        av->value.bmpstring->length);
+                BIO_printf(out, "%s\n", value);
+                OPENSSL_free(value);
+                break;
+
+            case V_ASN1_OCTET_STRING:
+                hex_prin(out, av->value.octet_string->data,
+                         av->value.octet_string->length);
+                BIO_printf(out, "\n");
+                break;
+
+            case V_ASN1_BIT_STRING:
+                hex_prin(out, av->value.bit_string->data,
+                         av->value.bit_string->length);
+                BIO_printf(out, "\n");
+                break;
+
+            default:
+                BIO_printf(out, "<Unsupported tag %d>\n", av->type);
+                break;
+            }
+        } else
+            BIO_printf(out, "<No Values>\n");
+    }
+    return 1;
+}
+
+void hex_prin(BIO *out, unsigned char *buf, int len)
+{
+    int i;
+    for (i = 0; i < len; i++)
+        BIO_printf(out, "%02X ", buf[i]);
+}
+
+static int set_pbe(int *ppbe, const char *str)
+{
+    if (!str)
+        return 0;
+    if (strcmp(str, "NONE") == 0) {
+        *ppbe = -1;
+        return 1;
+    }
+    *ppbe = OBJ_txt2nid(str);
+    if (*ppbe == NID_undef) {
+        BIO_printf(bio_err, "Unknown PBE algorithm %s\n", str);
+        return 0;
+    }
+    return 1;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/pkcs7.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/pkcs7.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/pkcs7.c	(revision 331)
@@ -0,0 +1,197 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "apps.h"
+#include <openssl/err.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pem.h>
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_NOOUT,
+    OPT_TEXT, OPT_PRINT, OPT_PRINT_CERTS, OPT_ENGINE
+} OPTION_CHOICE;
+
+OPTIONS pkcs7_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"},
+    {"in", OPT_IN, '<', "Input file"},
+    {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"},
+    {"out", OPT_OUT, '>', "Output file"},
+    {"noout", OPT_NOOUT, '-', "Don't output encoded data"},
+    {"text", OPT_TEXT, '-', "Print full details of certificates"},
+    {"print", OPT_PRINT, '-', "Print out all fields of the PKCS7 structure"},
+    {"print_certs", OPT_PRINT_CERTS, '-',
+     "Print_certs  print any certs or crl in the input"},
+#ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+#endif
+    {NULL}
+};
+
+int pkcs7_main(int argc, char **argv)
+{
+    ENGINE *e = NULL;
+    PKCS7 *p7 = NULL;
+    BIO *in = NULL, *out = NULL;
+    int informat = FORMAT_PEM, outformat = FORMAT_PEM;
+    char *infile = NULL, *outfile = NULL, *prog;
+    int i, print_certs = 0, text = 0, noout = 0, p7_print = 0, ret = 1;
+    OPTION_CHOICE o;
+
+    prog = opt_init(argc, argv, pkcs7_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(pkcs7_options);
+            ret = 0;
+            goto end;
+        case OPT_INFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
+                goto opthelp;
+            break;
+        case OPT_OUTFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
+                goto opthelp;
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_NOOUT:
+            noout = 1;
+            break;
+        case OPT_TEXT:
+            text = 1;
+            break;
+        case OPT_PRINT:
+            p7_print = 1;
+            break;
+        case OPT_PRINT_CERTS:
+            print_certs = 1;
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    in = bio_open_default(infile, 'r', informat);
+    if (in == NULL)
+        goto end;
+
+    if (informat == FORMAT_ASN1)
+        p7 = d2i_PKCS7_bio(in, NULL);
+    else
+        p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
+    if (p7 == NULL) {
+        BIO_printf(bio_err, "unable to load PKCS7 object\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    out = bio_open_default(outfile, 'w', outformat);
+    if (out == NULL)
+        goto end;
+
+    if (p7_print)
+        PKCS7_print_ctx(out, p7, 0, NULL);
+
+    if (print_certs) {
+        STACK_OF(X509) *certs = NULL;
+        STACK_OF(X509_CRL) *crls = NULL;
+
+        i = OBJ_obj2nid(p7->type);
+        switch (i) {
+        case NID_pkcs7_signed:
+            if (p7->d.sign != NULL) {
+                certs = p7->d.sign->cert;
+                crls = p7->d.sign->crl;
+            }
+            break;
+        case NID_pkcs7_signedAndEnveloped:
+            if (p7->d.signed_and_enveloped != NULL) {
+                certs = p7->d.signed_and_enveloped->cert;
+                crls = p7->d.signed_and_enveloped->crl;
+            }
+            break;
+        default:
+            break;
+        }
+
+        if (certs != NULL) {
+            X509 *x;
+
+            for (i = 0; i < sk_X509_num(certs); i++) {
+                x = sk_X509_value(certs, i);
+                if (text)
+                    X509_print(out, x);
+                else
+                    dump_cert_text(out, x);
+
+                if (!noout)
+                    PEM_write_bio_X509(out, x);
+                BIO_puts(out, "\n");
+            }
+        }
+        if (crls != NULL) {
+            X509_CRL *crl;
+
+            for (i = 0; i < sk_X509_CRL_num(crls); i++) {
+                crl = sk_X509_CRL_value(crls, i);
+
+                X509_CRL_print(out, crl);
+
+                if (!noout)
+                    PEM_write_bio_X509_CRL(out, crl);
+                BIO_puts(out, "\n");
+            }
+        }
+
+        ret = 0;
+        goto end;
+    }
+
+    if (!noout) {
+        if (outformat == FORMAT_ASN1)
+            i = i2d_PKCS7_bio(out, p7);
+        else
+            i = PEM_write_bio_PKCS7(out, p7);
+
+        if (!i) {
+            BIO_printf(bio_err, "unable to write pkcs7 object\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+    ret = 0;
+ end:
+    PKCS7_free(p7);
+    release_engine(e);
+    BIO_free(in);
+    BIO_free_all(out);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/pkcs8.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/pkcs8.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/pkcs8.c	(revision 331)
@@ -0,0 +1,353 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/pkcs12.h>
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_IN, OPT_OUT,
+    OPT_TOPK8, OPT_NOITER, OPT_NOCRYPT,
+#ifndef OPENSSL_NO_SCRYPT
+    OPT_SCRYPT, OPT_SCRYPT_N, OPT_SCRYPT_R, OPT_SCRYPT_P,
+#endif
+    OPT_V2, OPT_V1, OPT_V2PRF, OPT_ITER, OPT_PASSIN, OPT_PASSOUT,
+    OPT_TRADITIONAL
+} OPTION_CHOICE;
+
+OPTIONS pkcs8_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"inform", OPT_INFORM, 'F', "Input format (DER or PEM)"},
+    {"outform", OPT_OUTFORM, 'F', "Output format (DER or PEM)"},
+    {"in", OPT_IN, '<', "Input file"},
+    {"out", OPT_OUT, '>', "Output file"},
+    {"topk8", OPT_TOPK8, '-', "Output PKCS8 file"},
+    {"noiter", OPT_NOITER, '-', "Use 1 as iteration count"},
+    {"nocrypt", OPT_NOCRYPT, '-', "Use or expect unencrypted private key"},
+    {"v2", OPT_V2, 's', "Use PKCS#5 v2.0 and cipher"},
+    {"v1", OPT_V1, 's', "Use PKCS#5 v1.5 and cipher"},
+    {"v2prf", OPT_V2PRF, 's', "Set the PRF algorithm to use with PKCS#5 v2.0"},
+    {"iter", OPT_ITER, 'p', "Specify the iteration count"},
+    {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
+    {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
+    {"traditional", OPT_TRADITIONAL, '-', "use traditional format private key"},
+#ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+#endif
+#ifndef OPENSSL_NO_SCRYPT
+    {"scrypt", OPT_SCRYPT, '-', "Use scrypt algorithm"},
+    {"scrypt_N", OPT_SCRYPT_N, 's', "Set scrypt N parameter"},
+    {"scrypt_r", OPT_SCRYPT_R, 's', "Set scrypt r parameter"},
+    {"scrypt_p", OPT_SCRYPT_P, 's', "Set scrypt p parameter"},
+#endif
+    {NULL}
+};
+
+int pkcs8_main(int argc, char **argv)
+{
+    BIO *in = NULL, *out = NULL;
+    ENGINE *e = NULL;
+    EVP_PKEY *pkey = NULL;
+    PKCS8_PRIV_KEY_INFO *p8inf = NULL;
+    X509_SIG *p8 = NULL;
+    const EVP_CIPHER *cipher = NULL;
+    char *infile = NULL, *outfile = NULL;
+    char *passinarg = NULL, *passoutarg = NULL, *prog;
+#ifndef OPENSSL_NO_UI
+    char pass[50];
+#endif
+    char *passin = NULL, *passout = NULL, *p8pass = NULL;
+    OPTION_CHOICE o;
+    int nocrypt = 0, ret = 1, iter = PKCS12_DEFAULT_ITER;
+    int informat = FORMAT_PEM, outformat = FORMAT_PEM, topk8 = 0, pbe_nid = -1;
+    int private = 0, traditional = 0;
+#ifndef OPENSSL_NO_SCRYPT
+    long scrypt_N = 0, scrypt_r = 0, scrypt_p = 0;
+#endif
+
+    prog = opt_init(argc, argv, pkcs8_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(pkcs8_options);
+            ret = 0;
+            goto end;
+        case OPT_INFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
+                goto opthelp;
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUTFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
+                goto opthelp;
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_TOPK8:
+            topk8 = 1;
+            break;
+        case OPT_NOITER:
+            iter = 1;
+            break;
+        case OPT_NOCRYPT:
+            nocrypt = 1;
+            break;
+        case OPT_TRADITIONAL:
+            traditional = 1;
+            break;
+        case OPT_V2:
+            if (!opt_cipher(opt_arg(), &cipher))
+                goto opthelp;
+            break;
+        case OPT_V1:
+            pbe_nid = OBJ_txt2nid(opt_arg());
+            if (pbe_nid == NID_undef) {
+                BIO_printf(bio_err,
+                           "%s: Unknown PBE algorithm %s\n", prog, opt_arg());
+                goto opthelp;
+            }
+            break;
+        case OPT_V2PRF:
+            pbe_nid = OBJ_txt2nid(opt_arg());
+            if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0)) {
+                BIO_printf(bio_err,
+                           "%s: Unknown PRF algorithm %s\n", prog, opt_arg());
+                goto opthelp;
+            }
+            if (cipher == NULL)
+                cipher = EVP_aes_256_cbc();
+            break;
+        case OPT_ITER:
+            if (!opt_int(opt_arg(), &iter))
+                goto opthelp;
+            break;
+        case OPT_PASSIN:
+            passinarg = opt_arg();
+            break;
+        case OPT_PASSOUT:
+            passoutarg = opt_arg();
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+#ifndef OPENSSL_NO_SCRYPT
+        case OPT_SCRYPT:
+            scrypt_N = 16384;
+            scrypt_r = 8;
+            scrypt_p = 1;
+            if (cipher == NULL)
+                cipher = EVP_aes_256_cbc();
+            break;
+        case OPT_SCRYPT_N:
+            if (!opt_long(opt_arg(), &scrypt_N) || scrypt_N <= 0)
+                goto opthelp;
+            break;
+        case OPT_SCRYPT_R:
+            if (!opt_long(opt_arg(), &scrypt_r) || scrypt_r <= 0)
+                goto opthelp;
+            break;
+        case OPT_SCRYPT_P:
+            if (!opt_long(opt_arg(), &scrypt_p) || scrypt_p <= 0)
+                goto opthelp;
+            break;
+#endif
+        }
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    private = 1;
+
+    if (!app_passwd(passinarg, passoutarg, &passin, &passout)) {
+        BIO_printf(bio_err, "Error getting passwords\n");
+        goto end;
+    }
+
+    if ((pbe_nid == -1) && cipher == NULL)
+        cipher = EVP_aes_256_cbc();
+
+    in = bio_open_default(infile, 'r', informat);
+    if (in == NULL)
+        goto end;
+    out = bio_open_owner(outfile, outformat, private);
+    if (out == NULL)
+        goto end;
+
+    if (topk8) {
+        pkey = load_key(infile, informat, 1, passin, e, "key");
+        if (!pkey)
+            goto end;
+        if ((p8inf = EVP_PKEY2PKCS8(pkey)) == NULL) {
+            BIO_printf(bio_err, "Error converting key\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        if (nocrypt) {
+            assert(private);
+            if (outformat == FORMAT_PEM)
+                PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf);
+            else if (outformat == FORMAT_ASN1)
+                i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf);
+            else {
+                BIO_printf(bio_err, "Bad format specified for key\n");
+                goto end;
+            }
+        } else {
+            X509_ALGOR *pbe;
+            if (cipher) {
+#ifndef OPENSSL_NO_SCRYPT
+                if (scrypt_N && scrypt_r && scrypt_p)
+                    pbe = PKCS5_pbe2_set_scrypt(cipher, NULL, 0, NULL,
+                                                scrypt_N, scrypt_r, scrypt_p);
+                else
+#endif
+                    pbe = PKCS5_pbe2_set_iv(cipher, iter, NULL, 0, NULL,
+                                            pbe_nid);
+            } else {
+                pbe = PKCS5_pbe_set(pbe_nid, iter, NULL, 0);
+            }
+            if (pbe == NULL) {
+                BIO_printf(bio_err, "Error setting PBE algorithm\n");
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+            if (passout)
+                p8pass = passout;
+            else if (1) {
+#ifndef OPENSSL_NO_UI
+                p8pass = pass;
+                if (EVP_read_pw_string
+                    (pass, sizeof pass, "Enter Encryption Password:", 1)) {
+                    X509_ALGOR_free(pbe);
+                    goto end;
+                }
+            } else {
+#endif
+                BIO_printf(bio_err, "Password required\n");
+                goto end;
+            }
+            app_RAND_load_file(NULL, 0);
+            p8 = PKCS8_set0_pbe(p8pass, strlen(p8pass), p8inf, pbe);
+            if (p8 == NULL) {
+                X509_ALGOR_free(pbe);
+                BIO_printf(bio_err, "Error encrypting key\n");
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+            app_RAND_write_file(NULL);
+            assert(private);
+            if (outformat == FORMAT_PEM)
+                PEM_write_bio_PKCS8(out, p8);
+            else if (outformat == FORMAT_ASN1)
+                i2d_PKCS8_bio(out, p8);
+            else {
+                BIO_printf(bio_err, "Bad format specified for key\n");
+                goto end;
+            }
+        }
+
+        ret = 0;
+        goto end;
+    }
+
+    if (nocrypt) {
+        if (informat == FORMAT_PEM)
+            p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in, NULL, NULL, NULL);
+        else if (informat == FORMAT_ASN1)
+            p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL);
+        else {
+            BIO_printf(bio_err, "Bad format specified for key\n");
+            goto end;
+        }
+    } else {
+        if (informat == FORMAT_PEM)
+            p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL);
+        else if (informat == FORMAT_ASN1)
+            p8 = d2i_PKCS8_bio(in, NULL);
+        else {
+            BIO_printf(bio_err, "Bad format specified for key\n");
+            goto end;
+        }
+
+        if (!p8) {
+            BIO_printf(bio_err, "Error reading key\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        if (passin)
+            p8pass = passin;
+        else if (1) {
+#ifndef OPENSSL_NO_UI
+            p8pass = pass;
+            if (EVP_read_pw_string(pass, sizeof pass, "Enter Password:", 0)) {
+                BIO_printf(bio_err, "Can't read Password\n");
+                goto end;
+            }
+        } else {
+#endif
+            BIO_printf(bio_err, "Password required\n");
+            goto end;
+        }
+        p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass));
+    }
+
+    if (!p8inf) {
+        BIO_printf(bio_err, "Error decrypting key\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    if ((pkey = EVP_PKCS82PKEY(p8inf)) == NULL) {
+        BIO_printf(bio_err, "Error converting key\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    assert(private);
+    if (outformat == FORMAT_PEM) {
+        if (traditional)
+            PEM_write_bio_PrivateKey_traditional(out, pkey, NULL, NULL, 0,
+                                                 NULL, passout);
+        else
+            PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout);
+    } else if (outformat == FORMAT_ASN1) {
+        i2d_PrivateKey_bio(out, pkey);
+    } else {
+        BIO_printf(bio_err, "Bad format specified for key\n");
+        goto end;
+    }
+    ret = 0;
+
+ end:
+    X509_SIG_free(p8);
+    PKCS8_PRIV_KEY_INFO_free(p8inf);
+    EVP_PKEY_free(pkey);
+    release_engine(e);
+    BIO_free_all(out);
+    BIO_free(in);
+    OPENSSL_free(passin);
+    OPENSSL_free(passout);
+
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/pkey.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/pkey.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/pkey.c	(revision 331)
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_INFORM, OPT_OUTFORM, OPT_PASSIN, OPT_PASSOUT, OPT_ENGINE,
+    OPT_IN, OPT_OUT, OPT_PUBIN, OPT_PUBOUT, OPT_TEXT_PUB,
+    OPT_TEXT, OPT_NOOUT, OPT_MD, OPT_TRADITIONAL
+} OPTION_CHOICE;
+
+OPTIONS pkey_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"inform", OPT_INFORM, 'f', "Input format (DER or PEM)"},
+    {"outform", OPT_OUTFORM, 'F', "Output format (DER or PEM)"},
+    {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
+    {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
+    {"in", OPT_IN, 's', "Input key"},
+    {"out", OPT_OUT, '>', "Output file"},
+    {"pubin", OPT_PUBIN, '-',
+     "Read public key from input (default is private key)"},
+    {"pubout", OPT_PUBOUT, '-', "Output public key, not private"},
+    {"text_pub", OPT_TEXT_PUB, '-', "Only output public key components"},
+    {"text", OPT_TEXT, '-', "Output in plaintext as well"},
+    {"noout", OPT_NOOUT, '-', "Don't output the key"},
+    {"", OPT_MD, '-', "Any supported cipher"},
+    {"traditional", OPT_TRADITIONAL, '-',
+     "Use traditional format for private keys"},
+#ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+#endif
+    {NULL}
+};
+
+int pkey_main(int argc, char **argv)
+{
+    BIO *in = NULL, *out = NULL;
+    ENGINE *e = NULL;
+    EVP_PKEY *pkey = NULL;
+    const EVP_CIPHER *cipher = NULL;
+    char *infile = NULL, *outfile = NULL, *passin = NULL, *passout = NULL;
+    char *passinarg = NULL, *passoutarg = NULL, *prog;
+    OPTION_CHOICE o;
+    int informat = FORMAT_PEM, outformat = FORMAT_PEM;
+    int pubin = 0, pubout = 0, pubtext = 0, text = 0, noout = 0, ret = 1;
+    int private = 0, traditional = 0;
+
+    prog = opt_init(argc, argv, pkey_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(pkey_options);
+            ret = 0;
+            goto end;
+        case OPT_INFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat))
+                goto opthelp;
+            break;
+        case OPT_OUTFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
+                goto opthelp;
+            break;
+        case OPT_PASSIN:
+            passinarg = opt_arg();
+            break;
+        case OPT_PASSOUT:
+            passoutarg = opt_arg();
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_PUBIN:
+            pubin = pubout = pubtext = 1;
+            break;
+        case OPT_PUBOUT:
+            pubout = 1;
+            break;
+        case OPT_TEXT_PUB:
+            pubtext = text = 1;
+            break;
+        case OPT_TEXT:
+            text = 1;
+            break;
+        case OPT_NOOUT:
+            noout = 1;
+            break;
+        case OPT_TRADITIONAL:
+            traditional = 1;
+            break;
+        case OPT_MD:
+            if (!opt_cipher(opt_unknown(), &cipher))
+                goto opthelp;
+        }
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    private = !noout && !pubout ? 1 : 0;
+    if (text && !pubtext)
+        private = 1;
+
+    if (!app_passwd(passinarg, passoutarg, &passin, &passout)) {
+        BIO_printf(bio_err, "Error getting passwords\n");
+        goto end;
+    }
+
+    out = bio_open_owner(outfile, outformat, private);
+    if (out == NULL)
+        goto end;
+
+    if (pubin)
+        pkey = load_pubkey(infile, informat, 1, passin, e, "Public Key");
+    else
+        pkey = load_key(infile, informat, 1, passin, e, "key");
+    if (!pkey)
+        goto end;
+
+    if (!noout) {
+        if (outformat == FORMAT_PEM) {
+            if (pubout)
+                PEM_write_bio_PUBKEY(out, pkey);
+            else {
+                assert(private);
+                if (traditional)
+                    PEM_write_bio_PrivateKey_traditional(out, pkey, cipher,
+                                                         NULL, 0, NULL,
+                                                         passout);
+                else
+                    PEM_write_bio_PrivateKey(out, pkey, cipher,
+                                             NULL, 0, NULL, passout);
+            }
+        } else if (outformat == FORMAT_ASN1) {
+            if (pubout)
+                i2d_PUBKEY_bio(out, pkey);
+            else {
+                assert(private);
+                i2d_PrivateKey_bio(out, pkey);
+            }
+        } else {
+            BIO_printf(bio_err, "Bad format specified for key\n");
+            goto end;
+        }
+
+    }
+
+    if (text) {
+        if (pubtext)
+            EVP_PKEY_print_public(out, pkey, 0, NULL);
+        else {
+            assert(private);
+            EVP_PKEY_print_private(out, pkey, 0, NULL);
+        }
+    }
+
+    ret = 0;
+
+ end:
+    EVP_PKEY_free(pkey);
+    release_engine(e);
+    BIO_free_all(out);
+    BIO_free(in);
+    OPENSSL_free(passin);
+    OPENSSL_free(passout);
+
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/pkeyparam.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/pkeyparam.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/pkeyparam.c	(revision 331)
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_IN, OPT_OUT, OPT_TEXT, OPT_NOOUT, OPT_ENGINE
+} OPTION_CHOICE;
+
+OPTIONS pkeyparam_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"in", OPT_IN, '<', "Input file"},
+    {"out", OPT_OUT, '>', "Output file"},
+    {"text", OPT_TEXT, '-', "Print parameters as text"},
+    {"noout", OPT_NOOUT, '-', "Don't output encoded parameters"},
+#ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+#endif
+    {NULL}
+};
+
+int pkeyparam_main(int argc, char **argv)
+{
+    ENGINE *e = NULL;
+    BIO *in = NULL, *out = NULL;
+    EVP_PKEY *pkey = NULL;
+    int text = 0, noout = 0, ret = 1;
+    OPTION_CHOICE o;
+    char *infile = NULL, *outfile = NULL, *prog;
+
+    prog = opt_init(argc, argv, pkeyparam_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(pkeyparam_options);
+            ret = 0;
+            goto end;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        case OPT_TEXT:
+            text = 1;
+            break;
+        case OPT_NOOUT:
+            noout = 1;
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    in = bio_open_default(infile, 'r', FORMAT_PEM);
+    if (in == NULL)
+        goto end;
+    out = bio_open_default(outfile, 'w', FORMAT_PEM);
+    if (out == NULL)
+        goto end;
+    pkey = PEM_read_bio_Parameters(in, NULL);
+    if (!pkey) {
+        BIO_printf(bio_err, "Error reading parameters\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    if (!noout)
+        PEM_write_bio_Parameters(out, pkey);
+
+    if (text)
+        EVP_PKEY_print_params(out, pkey, 0, NULL);
+
+    ret = 0;
+
+ end:
+    EVP_PKEY_free(pkey);
+    release_engine(e);
+    BIO_free_all(out);
+    BIO_free(in);
+
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/pkeyutl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/pkeyutl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/pkeyutl.c	(revision 331)
@@ -0,0 +1,489 @@
+/*
+ * Copyright 2006-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 "apps.h"
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+
+#define KEY_NONE        0
+#define KEY_PRIVKEY     1
+#define KEY_PUBKEY      2
+#define KEY_CERT        3
+
+static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
+                              const char *keyfile, int keyform, int key_type,
+                              char *passinarg, int pkey_op, ENGINE *e,
+                              const int impl);
+
+static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file,
+                      ENGINE *e);
+
+static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
+                    unsigned char *out, size_t *poutlen,
+                    const unsigned char *in, size_t inlen);
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_ENGINE, OPT_ENGINE_IMPL, OPT_IN, OPT_OUT,
+    OPT_PUBIN, OPT_CERTIN, OPT_ASN1PARSE, OPT_HEXDUMP, OPT_SIGN,
+    OPT_VERIFY, OPT_VERIFYRECOVER, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT,
+    OPT_DERIVE, OPT_SIGFILE, OPT_INKEY, OPT_PEERKEY, OPT_PASSIN,
+    OPT_PEERFORM, OPT_KEYFORM, OPT_PKEYOPT, OPT_KDF, OPT_KDFLEN
+} OPTION_CHOICE;
+
+OPTIONS pkeyutl_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"in", OPT_IN, '<', "Input file - default stdin"},
+    {"out", OPT_OUT, '>', "Output file - default stdout"},
+    {"pubin", OPT_PUBIN, '-', "Input is a public key"},
+    {"certin", OPT_CERTIN, '-', "Input is a cert with a public key"},
+    {"asn1parse", OPT_ASN1PARSE, '-', "asn1parse the output data"},
+    {"hexdump", OPT_HEXDUMP, '-', "Hex dump output"},
+    {"sign", OPT_SIGN, '-', "Sign input data with private key"},
+    {"verify", OPT_VERIFY, '-', "Verify with public key"},
+    {"verifyrecover", OPT_VERIFYRECOVER, '-',
+     "Verify with public key, recover original data"},
+    {"rev", OPT_REV, '-', "Reverse the order of the input buffer"},
+    {"encrypt", OPT_ENCRYPT, '-', "Encrypt input data with public key"},
+    {"decrypt", OPT_DECRYPT, '-', "Decrypt input data with private key"},
+    {"derive", OPT_DERIVE, '-', "Derive shared secret"},
+    {"kdf", OPT_KDF, 's', "Use KDF algorithm"},
+    {"kdflen", OPT_KDFLEN, 'p', "KDF algorithm output length"},
+    {"sigfile", OPT_SIGFILE, '<', "Signature file (verify operation only)"},
+    {"inkey", OPT_INKEY, 's', "Input private key file"},
+    {"peerkey", OPT_PEERKEY, 's', "Peer key file used in key derivation"},
+    {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
+    {"peerform", OPT_PEERFORM, 'E', "Peer key format - default PEM"},
+    {"keyform", OPT_KEYFORM, 'E', "Private key format - default PEM"},
+    {"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"},
+#ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+    {"engine_impl", OPT_ENGINE_IMPL, '-',
+     "Also use engine given by -engine for crypto operations"},
+#endif
+    {NULL}
+};
+
+int pkeyutl_main(int argc, char **argv)
+{
+    BIO *in = NULL, *out = NULL;
+    ENGINE *e = NULL;
+    EVP_PKEY_CTX *ctx = NULL;
+    char *infile = NULL, *outfile = NULL, *sigfile = NULL, *passinarg = NULL;
+    char hexdump = 0, asn1parse = 0, rev = 0, *prog;
+    unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL;
+    OPTION_CHOICE o;
+    int buf_inlen = 0, siglen = -1, keyform = FORMAT_PEM, peerform =
+        FORMAT_PEM;
+    int keysize = -1, pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY;
+    int engine_impl = 0;
+    int ret = 1, rv = -1;
+    size_t buf_outlen;
+    const char *inkey = NULL;
+    const char *peerkey = NULL;
+    const char *kdfalg = NULL;
+    int kdflen = 0;
+    STACK_OF(OPENSSL_STRING) *pkeyopts = NULL;
+
+    prog = opt_init(argc, argv, pkeyutl_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(pkeyutl_options);
+            ret = 0;
+            goto end;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_SIGFILE:
+            sigfile = opt_arg();
+            break;
+        case OPT_ENGINE_IMPL:
+            engine_impl = 1;
+            break;
+        case OPT_INKEY:
+            inkey = opt_arg();
+            break;
+        case OPT_PEERKEY:
+            peerkey = opt_arg();
+            break;
+        case OPT_PASSIN:
+            passinarg = opt_arg();
+            break;
+        case OPT_PEERFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PDE, &peerform))
+                goto opthelp;
+            break;
+        case OPT_KEYFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PDE, &keyform))
+                goto opthelp;
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        case OPT_PUBIN:
+            key_type = KEY_PUBKEY;
+            break;
+        case OPT_CERTIN:
+            key_type = KEY_CERT;
+            break;
+        case OPT_ASN1PARSE:
+            asn1parse = 1;
+            break;
+        case OPT_HEXDUMP:
+            hexdump = 1;
+            break;
+        case OPT_SIGN:
+            pkey_op = EVP_PKEY_OP_SIGN;
+            break;
+        case OPT_VERIFY:
+            pkey_op = EVP_PKEY_OP_VERIFY;
+            break;
+        case OPT_VERIFYRECOVER:
+            pkey_op = EVP_PKEY_OP_VERIFYRECOVER;
+            break;
+        case OPT_ENCRYPT:
+            pkey_op = EVP_PKEY_OP_ENCRYPT;
+            break;
+        case OPT_DECRYPT:
+            pkey_op = EVP_PKEY_OP_DECRYPT;
+            break;
+        case OPT_DERIVE:
+            pkey_op = EVP_PKEY_OP_DERIVE;
+            break;
+        case OPT_KDF:
+            pkey_op = EVP_PKEY_OP_DERIVE;
+            key_type = KEY_NONE;
+            kdfalg = opt_arg();
+            break;
+        case OPT_KDFLEN:
+            kdflen = atoi(opt_arg());
+            break;
+        case OPT_REV:
+            rev = 1;
+            break;
+        case OPT_PKEYOPT:
+            if ((pkeyopts == NULL &&
+                 (pkeyopts = sk_OPENSSL_STRING_new_null()) == NULL) ||
+                sk_OPENSSL_STRING_push(pkeyopts, opt_arg()) == 0) {
+                BIO_puts(bio_err, "out of memory\n");
+                goto end;
+            }
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    if (kdfalg != NULL) {
+        if (kdflen == 0)
+            goto opthelp;
+    } else if ((inkey == NULL)
+            || (peerkey != NULL && pkey_op != EVP_PKEY_OP_DERIVE)) {
+        goto opthelp;
+    }
+    ctx = init_ctx(kdfalg, &keysize, inkey, keyform, key_type,
+                   passinarg, pkey_op, e, engine_impl);
+    if (ctx == NULL) {
+        BIO_printf(bio_err, "%s: Error initializing context\n", prog);
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+    if (peerkey != NULL && !setup_peer(ctx, peerform, peerkey, e)) {
+        BIO_printf(bio_err, "%s: Error setting up peer key\n", prog);
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+    if (pkeyopts != NULL) {
+        int num = sk_OPENSSL_STRING_num(pkeyopts);
+        int i;
+
+        for (i = 0; i < num; ++i) {
+            const char *opt = sk_OPENSSL_STRING_value(pkeyopts, i);
+
+            if (pkey_ctrl_string(ctx, opt) <= 0) {
+                BIO_printf(bio_err, "%s: Can't set parameter:\n", prog);
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+        }
+    }
+
+    if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY)) {
+        BIO_printf(bio_err,
+                   "%s: Signature file specified for non verify\n", prog);
+        goto end;
+    }
+
+    if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY)) {
+        BIO_printf(bio_err,
+                   "%s: No signature file specified for verify\n", prog);
+        goto end;
+    }
+
+/* FIXME: seed PRNG only if needed */
+    app_RAND_load_file(NULL, 0);
+
+    if (pkey_op != EVP_PKEY_OP_DERIVE) {
+        in = bio_open_default(infile, 'r', FORMAT_BINARY);
+        if (in == NULL)
+            goto end;
+    }
+    out = bio_open_default(outfile, 'w', FORMAT_BINARY);
+    if (out == NULL)
+        goto end;
+
+    if (sigfile) {
+        BIO *sigbio = BIO_new_file(sigfile, "rb");
+        if (!sigbio) {
+            BIO_printf(bio_err, "Can't open signature file %s\n", sigfile);
+            goto end;
+        }
+        siglen = bio_to_mem(&sig, keysize * 10, sigbio);
+        BIO_free(sigbio);
+        if (siglen < 0) {
+            BIO_printf(bio_err, "Error reading signature data\n");
+            goto end;
+        }
+    }
+
+    if (in) {
+        /* Read the input data */
+        buf_inlen = bio_to_mem(&buf_in, keysize * 10, in);
+        if (buf_inlen < 0) {
+            BIO_printf(bio_err, "Error reading input Data\n");
+            exit(1);
+        }
+        if (rev) {
+            size_t i;
+            unsigned char ctmp;
+            size_t l = (size_t)buf_inlen;
+            for (i = 0; i < l / 2; i++) {
+                ctmp = buf_in[i];
+                buf_in[i] = buf_in[l - 1 - i];
+                buf_in[l - 1 - i] = ctmp;
+            }
+        }
+    }
+
+    if (pkey_op == EVP_PKEY_OP_VERIFY) {
+        rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen,
+                             buf_in, (size_t)buf_inlen);
+        if (rv == 1) {
+            BIO_puts(out, "Signature Verified Successfully\n");
+            ret = 0;
+        } else
+            BIO_puts(out, "Signature Verification Failure\n");
+        goto end;
+    }
+    if (kdflen != 0) {
+        buf_outlen = kdflen;
+        rv = 1;
+    } else {
+        rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen,
+                      buf_in, (size_t)buf_inlen);
+    }
+    if (rv > 0 && buf_outlen != 0) {
+        buf_out = app_malloc(buf_outlen, "buffer output");
+        rv = do_keyop(ctx, pkey_op,
+                      buf_out, (size_t *)&buf_outlen,
+                      buf_in, (size_t)buf_inlen);
+    }
+    if (rv <= 0) {
+        BIO_puts(bio_err, "Public Key operation error\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+    ret = 0;
+
+    if (asn1parse) {
+        if (!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1))
+            ERR_print_errors(bio_err);
+    } else if (hexdump)
+        BIO_dump(out, (char *)buf_out, buf_outlen);
+    else
+        BIO_write(out, buf_out, buf_outlen);
+
+ end:
+    EVP_PKEY_CTX_free(ctx);
+    release_engine(e);
+    BIO_free(in);
+    BIO_free_all(out);
+    OPENSSL_free(buf_in);
+    OPENSSL_free(buf_out);
+    OPENSSL_free(sig);
+    sk_OPENSSL_STRING_free(pkeyopts);
+    return ret;
+}
+
+static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
+                              const char *keyfile, int keyform, int key_type,
+                              char *passinarg, int pkey_op, ENGINE *e,
+                              const int engine_impl)
+{
+    EVP_PKEY *pkey = NULL;
+    EVP_PKEY_CTX *ctx = NULL;
+    ENGINE *impl = NULL;
+    char *passin = NULL;
+    int rv = -1;
+    X509 *x;
+    if (((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT)
+         || (pkey_op == EVP_PKEY_OP_DERIVE))
+        && (key_type != KEY_PRIVKEY && kdfalg == NULL)) {
+        BIO_printf(bio_err, "A private key is needed for this operation\n");
+        goto end;
+    }
+    if (!app_passwd(passinarg, NULL, &passin, NULL)) {
+        BIO_printf(bio_err, "Error getting password\n");
+        goto end;
+    }
+    switch (key_type) {
+    case KEY_PRIVKEY:
+        pkey = load_key(keyfile, keyform, 0, passin, e, "Private Key");
+        break;
+
+    case KEY_PUBKEY:
+        pkey = load_pubkey(keyfile, keyform, 0, NULL, e, "Public Key");
+        break;
+
+    case KEY_CERT:
+        x = load_cert(keyfile, keyform, "Certificate");
+        if (x) {
+            pkey = X509_get_pubkey(x);
+            X509_free(x);
+        }
+        break;
+
+    case KEY_NONE:
+        break;
+
+    }
+
+#ifndef OPENSSL_NO_ENGINE
+    if (engine_impl)
+        impl = e;
+#endif
+
+    if (kdfalg) {
+        int kdfnid = OBJ_sn2nid(kdfalg);
+        if (kdfnid == NID_undef)
+            goto end;
+        ctx = EVP_PKEY_CTX_new_id(kdfnid, impl);
+    } else {
+        if (pkey == NULL)
+            goto end;
+        *pkeysize = EVP_PKEY_size(pkey);
+        ctx = EVP_PKEY_CTX_new(pkey, impl);
+        EVP_PKEY_free(pkey);
+    }
+
+    if (ctx == NULL)
+        goto end;
+
+    switch (pkey_op) {
+    case EVP_PKEY_OP_SIGN:
+        rv = EVP_PKEY_sign_init(ctx);
+        break;
+
+    case EVP_PKEY_OP_VERIFY:
+        rv = EVP_PKEY_verify_init(ctx);
+        break;
+
+    case EVP_PKEY_OP_VERIFYRECOVER:
+        rv = EVP_PKEY_verify_recover_init(ctx);
+        break;
+
+    case EVP_PKEY_OP_ENCRYPT:
+        rv = EVP_PKEY_encrypt_init(ctx);
+        break;
+
+    case EVP_PKEY_OP_DECRYPT:
+        rv = EVP_PKEY_decrypt_init(ctx);
+        break;
+
+    case EVP_PKEY_OP_DERIVE:
+        rv = EVP_PKEY_derive_init(ctx);
+        break;
+    }
+
+    if (rv <= 0) {
+        EVP_PKEY_CTX_free(ctx);
+        ctx = NULL;
+    }
+
+ end:
+    OPENSSL_free(passin);
+    return ctx;
+
+}
+
+static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file,
+                      ENGINE* e)
+{
+    EVP_PKEY *peer = NULL;
+    ENGINE* engine = NULL;
+    int ret;
+
+    if (peerform == FORMAT_ENGINE)
+        engine = e;
+    peer = load_pubkey(file, peerform, 0, NULL, engine, "Peer Key");
+    if (!peer) {
+        BIO_printf(bio_err, "Error reading peer key %s\n", file);
+        ERR_print_errors(bio_err);
+        return 0;
+    }
+
+    ret = EVP_PKEY_derive_set_peer(ctx, peer);
+
+    EVP_PKEY_free(peer);
+    if (ret <= 0)
+        ERR_print_errors(bio_err);
+    return ret;
+}
+
+static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
+                    unsigned char *out, size_t *poutlen,
+                    const unsigned char *in, size_t inlen)
+{
+    int rv = 0;
+    switch (pkey_op) {
+    case EVP_PKEY_OP_VERIFYRECOVER:
+        rv = EVP_PKEY_verify_recover(ctx, out, poutlen, in, inlen);
+        break;
+
+    case EVP_PKEY_OP_SIGN:
+        rv = EVP_PKEY_sign(ctx, out, poutlen, in, inlen);
+        break;
+
+    case EVP_PKEY_OP_ENCRYPT:
+        rv = EVP_PKEY_encrypt(ctx, out, poutlen, in, inlen);
+        break;
+
+    case EVP_PKEY_OP_DECRYPT:
+        rv = EVP_PKEY_decrypt(ctx, out, poutlen, in, inlen);
+        break;
+
+    case EVP_PKEY_OP_DERIVE:
+        rv = EVP_PKEY_derive(ctx, out, poutlen);
+        break;
+
+    }
+    return rv;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/prime.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/prime.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/prime.c	(revision 331)
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2004-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 <string.h>
+
+#include "apps.h"
+#include <openssl/bn.h>
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_HEX, OPT_GENERATE, OPT_BITS, OPT_SAFE, OPT_CHECKS
+} OPTION_CHOICE;
+
+OPTIONS prime_options[] = {
+    {OPT_HELP_STR, 1, '-', "Usage: %s [options] [number...]\n"},
+    {OPT_HELP_STR, 1, '-',
+        "  number Number to check for primality\n"},
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"hex", OPT_HEX, '-', "Hex output"},
+    {"generate", OPT_GENERATE, '-', "Generate a prime"},
+    {"bits", OPT_BITS, 'p', "Size of number in bits"},
+    {"safe", OPT_SAFE, '-',
+     "When used with -generate, generate a safe prime"},
+    {"checks", OPT_CHECKS, 'p', "Number of checks"},
+    {NULL}
+};
+
+int prime_main(int argc, char **argv)
+{
+    BIGNUM *bn = NULL;
+    int hex = 0, checks = 20, generate = 0, bits = 0, safe = 0, ret = 1;
+    char *prog;
+    OPTION_CHOICE o;
+
+    prog = opt_init(argc, argv, prime_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(prime_options);
+            ret = 0;
+            goto end;
+        case OPT_HEX:
+            hex = 1;
+            break;
+        case OPT_GENERATE:
+            generate = 1;
+            break;
+        case OPT_BITS:
+            bits = atoi(opt_arg());
+            break;
+        case OPT_SAFE:
+            safe = 1;
+            break;
+        case OPT_CHECKS:
+            checks = atoi(opt_arg());
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    argv = opt_rest();
+
+    if (argc == 0 && !generate) {
+        BIO_printf(bio_err, "%s: No prime specified\n", prog);
+        goto end;
+    }
+
+    if (generate) {
+        char *s;
+
+        if (!bits) {
+            BIO_printf(bio_err, "Specify the number of bits.\n");
+            goto end;
+        }
+        bn = BN_new();
+        if (bn == NULL) {
+            BIO_printf(bio_err, "Out of memory.\n");
+            goto end;
+        }
+        if (!BN_generate_prime_ex(bn, bits, safe, NULL, NULL, NULL)) {
+            BIO_printf(bio_err, "Failed to generate prime.\n");
+            goto end;
+        }
+        s = hex ? BN_bn2hex(bn) : BN_bn2dec(bn);
+        if (s == NULL) {
+            BIO_printf(bio_err, "Out of memory.\n");
+            goto end;
+        }
+        BIO_printf(bio_out, "%s\n", s);
+        OPENSSL_free(s);
+    } else {
+        for ( ; *argv; argv++) {
+            int r;
+
+            if (hex)
+                r = BN_hex2bn(&bn, argv[0]);
+            else
+                r = BN_dec2bn(&bn, argv[0]);
+
+            if(!r) {
+                BIO_printf(bio_err, "Failed to process value (%s)\n", argv[0]);
+                goto end;
+            }
+
+            BN_print(bio_out, bn);
+            BIO_printf(bio_out, " (%s) %s prime\n",
+                       argv[0],
+                       BN_is_prime_ex(bn, checks, NULL, NULL)
+                           ? "is" : "is not");
+        }
+    }
+
+    ret = 0;
+ end:
+    BN_free(bn);
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/progs.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/progs.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/progs.h	(revision 331)
@@ -0,0 +1,418 @@
+/*
+ * WARNING: do not edit!
+ * Generated by apps/progs.pl
+ *
+ * Copyright 1995-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
+ */
+
+typedef enum FUNC_TYPE {
+    FT_none, FT_general, FT_md, FT_cipher, FT_pkey,
+    FT_md_alg, FT_cipher_alg
+} FUNC_TYPE;
+
+typedef struct function_st {
+    FUNC_TYPE type;
+    const char *name;
+    int (*func)(int argc, char *argv[]);
+    const OPTIONS *help;
+} FUNCTION;
+
+DEFINE_LHASH_OF(FUNCTION);
+
+extern int asn1parse_main(int argc, char *argv[]);
+extern int ca_main(int argc, char *argv[]);
+extern int ciphers_main(int argc, char *argv[]);
+extern int cms_main(int argc, char *argv[]);
+extern int crl_main(int argc, char *argv[]);
+extern int crl2pkcs7_main(int argc, char *argv[]);
+extern int dgst_main(int argc, char *argv[]);
+extern int dhparam_main(int argc, char *argv[]);
+extern int dsa_main(int argc, char *argv[]);
+extern int dsaparam_main(int argc, char *argv[]);
+extern int ec_main(int argc, char *argv[]);
+extern int ecparam_main(int argc, char *argv[]);
+extern int enc_main(int argc, char *argv[]);
+extern int engine_main(int argc, char *argv[]);
+extern int errstr_main(int argc, char *argv[]);
+extern int exit_main(int argc, char *argv[]);
+extern int gendsa_main(int argc, char *argv[]);
+extern int genpkey_main(int argc, char *argv[]);
+extern int genrsa_main(int argc, char *argv[]);
+extern int help_main(int argc, char *argv[]);
+extern int list_main(int argc, char *argv[]);
+extern int nseq_main(int argc, char *argv[]);
+extern int ocsp_main(int argc, char *argv[]);
+extern int passwd_main(int argc, char *argv[]);
+extern int pkcs12_main(int argc, char *argv[]);
+extern int pkcs7_main(int argc, char *argv[]);
+extern int pkcs8_main(int argc, char *argv[]);
+extern int pkey_main(int argc, char *argv[]);
+extern int pkeyparam_main(int argc, char *argv[]);
+extern int pkeyutl_main(int argc, char *argv[]);
+extern int prime_main(int argc, char *argv[]);
+extern int rand_main(int argc, char *argv[]);
+extern int rehash_main(int argc, char *argv[]);
+extern int req_main(int argc, char *argv[]);
+extern int rsa_main(int argc, char *argv[]);
+extern int rsautl_main(int argc, char *argv[]);
+extern int s_client_main(int argc, char *argv[]);
+extern int s_server_main(int argc, char *argv[]);
+extern int s_time_main(int argc, char *argv[]);
+extern int sess_id_main(int argc, char *argv[]);
+extern int smime_main(int argc, char *argv[]);
+extern int speed_main(int argc, char *argv[]);
+extern int spkac_main(int argc, char *argv[]);
+extern int srp_main(int argc, char *argv[]);
+extern int ts_main(int argc, char *argv[]);
+extern int verify_main(int argc, char *argv[]);
+extern int version_main(int argc, char *argv[]);
+extern int x509_main(int argc, char *argv[]);
+
+extern OPTIONS asn1parse_options[];
+extern OPTIONS ca_options[];
+extern OPTIONS ciphers_options[];
+extern OPTIONS cms_options[];
+extern OPTIONS crl_options[];
+extern OPTIONS crl2pkcs7_options[];
+extern OPTIONS dgst_options[];
+extern OPTIONS dhparam_options[];
+extern OPTIONS dsa_options[];
+extern OPTIONS dsaparam_options[];
+extern OPTIONS ec_options[];
+extern OPTIONS ecparam_options[];
+extern OPTIONS enc_options[];
+extern OPTIONS engine_options[];
+extern OPTIONS errstr_options[];
+extern OPTIONS exit_options[];
+extern OPTIONS gendsa_options[];
+extern OPTIONS genpkey_options[];
+extern OPTIONS genrsa_options[];
+extern OPTIONS help_options[];
+extern OPTIONS list_options[];
+extern OPTIONS nseq_options[];
+extern OPTIONS ocsp_options[];
+extern OPTIONS passwd_options[];
+extern OPTIONS pkcs12_options[];
+extern OPTIONS pkcs7_options[];
+extern OPTIONS pkcs8_options[];
+extern OPTIONS pkey_options[];
+extern OPTIONS pkeyparam_options[];
+extern OPTIONS pkeyutl_options[];
+extern OPTIONS prime_options[];
+extern OPTIONS rand_options[];
+extern OPTIONS rehash_options[];
+extern OPTIONS req_options[];
+extern OPTIONS rsa_options[];
+extern OPTIONS rsautl_options[];
+extern OPTIONS s_client_options[];
+extern OPTIONS s_server_options[];
+extern OPTIONS s_time_options[];
+extern OPTIONS sess_id_options[];
+extern OPTIONS smime_options[];
+extern OPTIONS speed_options[];
+extern OPTIONS spkac_options[];
+extern OPTIONS srp_options[];
+extern OPTIONS ts_options[];
+extern OPTIONS verify_options[];
+extern OPTIONS version_options[];
+extern OPTIONS x509_options[];
+
+#ifdef INCLUDE_FUNCTION_TABLE
+static FUNCTION functions[] = {
+    { FT_general, "asn1parse", asn1parse_main, asn1parse_options },
+    { FT_general, "ca", ca_main, ca_options },
+#ifndef OPENSSL_NO_SOCK
+    { FT_general, "ciphers", ciphers_main, ciphers_options },
+#endif
+#ifndef OPENSSL_NO_CMS
+    { FT_general, "cms", cms_main, cms_options },
+#endif
+    { FT_general, "crl", crl_main, crl_options },
+    { FT_general, "crl2pkcs7", crl2pkcs7_main, crl2pkcs7_options },
+    { FT_general, "dgst", dgst_main, dgst_options },
+#ifndef OPENSSL_NO_DH
+    { FT_general, "dhparam", dhparam_main, dhparam_options },
+#endif
+#ifndef OPENSSL_NO_DSA
+    { FT_general, "dsa", dsa_main, dsa_options },
+#endif
+#ifndef OPENSSL_NO_DSA
+    { FT_general, "dsaparam", dsaparam_main, dsaparam_options },
+#endif
+#ifndef OPENSSL_NO_EC
+    { FT_general, "ec", ec_main, ec_options },
+#endif
+#ifndef OPENSSL_NO_EC
+    { FT_general, "ecparam", ecparam_main, ecparam_options },
+#endif
+    { FT_general, "enc", enc_main, enc_options },
+#ifndef OPENSSL_NO_ENGINE
+    { FT_general, "engine", engine_main, engine_options },
+#endif
+    { FT_general, "errstr", errstr_main, errstr_options },
+    { FT_general, "exit", exit_main, exit_options },
+#ifndef OPENSSL_NO_DSA
+    { FT_general, "gendsa", gendsa_main, gendsa_options },
+#endif
+    { FT_general, "genpkey", genpkey_main, genpkey_options },
+#ifndef OPENSSL_NO_RSA
+    { FT_general, "genrsa", genrsa_main, genrsa_options },
+#endif
+    { FT_general, "help", help_main, help_options },
+    { FT_general, "list", list_main, list_options },
+    { FT_general, "nseq", nseq_main, nseq_options },
+#ifndef OPENSSL_NO_OCSP
+    { FT_general, "ocsp", ocsp_main, ocsp_options },
+#endif
+    { FT_general, "passwd", passwd_main, passwd_options },
+#ifndef OPENSSL_NO_DES
+    { FT_general, "pkcs12", pkcs12_main, pkcs12_options },
+#endif
+    { FT_general, "pkcs7", pkcs7_main, pkcs7_options },
+    { FT_general, "pkcs8", pkcs8_main, pkcs8_options },
+    { FT_general, "pkey", pkey_main, pkey_options },
+    { FT_general, "pkeyparam", pkeyparam_main, pkeyparam_options },
+    { FT_general, "pkeyutl", pkeyutl_main, pkeyutl_options },
+    { FT_general, "prime", prime_main, prime_options },
+    { FT_general, "rand", rand_main, rand_options },
+    { FT_general, "rehash", rehash_main, rehash_options },
+    { FT_general, "req", req_main, req_options },
+    { FT_general, "rsa", rsa_main, rsa_options },
+#ifndef OPENSSL_NO_RSA
+    { FT_general, "rsautl", rsautl_main, rsautl_options },
+#endif
+#ifndef OPENSSL_NO_SOCK
+    { FT_general, "s_client", s_client_main, s_client_options },
+#endif
+#ifndef OPENSSL_NO_SOCK
+    { FT_general, "s_server", s_server_main, s_server_options },
+#endif
+#ifndef OPENSSL_NO_SOCK
+    { FT_general, "s_time", s_time_main, s_time_options },
+#endif
+    { FT_general, "sess_id", sess_id_main, sess_id_options },
+    { FT_general, "smime", smime_main, smime_options },
+    { FT_general, "speed", speed_main, speed_options },
+    { FT_general, "spkac", spkac_main, spkac_options },
+#ifndef OPENSSL_NO_SRP
+    { FT_general, "srp", srp_main, srp_options },
+#endif
+#ifndef OPENSSL_NO_TS
+    { FT_general, "ts", ts_main, ts_options },
+#endif
+    { FT_general, "verify", verify_main, verify_options },
+    { FT_general, "version", version_main, version_options },
+    { FT_general, "x509", x509_main, x509_options },
+#ifndef OPENSSL_NO_MD2
+    { FT_md, "md2", dgst_main},
+#endif
+#ifndef OPENSSL_NO_MD4
+    { FT_md, "md4", dgst_main},
+#endif
+    { FT_md, "md5", dgst_main},
+#ifndef OPENSSL_NO_GOST
+    { FT_md, "gost", dgst_main},
+#endif
+    { FT_md, "sha1", dgst_main},
+    { FT_md, "sha224", dgst_main},
+    { FT_md, "sha256", dgst_main},
+    { FT_md, "sha384", dgst_main},
+    { FT_md, "sha512", dgst_main},
+#ifndef OPENSSL_NO_MDC2
+    { FT_md, "mdc2", dgst_main},
+#endif
+#ifndef OPENSSL_NO_RMD160
+    { FT_md, "rmd160", dgst_main},
+#endif
+#ifndef OPENSSL_NO_BLAKE2
+    { FT_md, "blake2b512", dgst_main},
+#endif
+#ifndef OPENSSL_NO_BLAKE2
+    { FT_md, "blake2s256", dgst_main},
+#endif
+    { FT_cipher, "aes-128-cbc", enc_main, enc_options },
+    { FT_cipher, "aes-128-ecb", enc_main, enc_options },
+    { FT_cipher, "aes-192-cbc", enc_main, enc_options },
+    { FT_cipher, "aes-192-ecb", enc_main, enc_options },
+    { FT_cipher, "aes-256-cbc", enc_main, enc_options },
+    { FT_cipher, "aes-256-ecb", enc_main, enc_options },
+#ifndef OPENSSL_NO_CAMELLIA
+    { FT_cipher, "camellia-128-cbc", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+    { FT_cipher, "camellia-128-ecb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+    { FT_cipher, "camellia-192-cbc", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+    { FT_cipher, "camellia-192-ecb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+    { FT_cipher, "camellia-256-cbc", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+    { FT_cipher, "camellia-256-ecb", enc_main, enc_options },
+#endif
+    { FT_cipher, "base64", enc_main, enc_options },
+#ifdef ZLIB
+    { FT_cipher, "zlib", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_DES
+    { FT_cipher, "des", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_DES
+    { FT_cipher, "des3", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_DES
+    { FT_cipher, "desx", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_IDEA
+    { FT_cipher, "idea", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_SEED
+    { FT_cipher, "seed", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_RC4
+    { FT_cipher, "rc4", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_RC4
+    { FT_cipher, "rc4-40", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_RC2
+    { FT_cipher, "rc2", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_BF
+    { FT_cipher, "bf", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_CAST
+    { FT_cipher, "cast", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_RC5
+    { FT_cipher, "rc5", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_DES
+    { FT_cipher, "des-ecb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_DES
+    { FT_cipher, "des-ede", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_DES
+    { FT_cipher, "des-ede3", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_DES
+    { FT_cipher, "des-cbc", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_DES
+    { FT_cipher, "des-ede-cbc", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_DES
+    { FT_cipher, "des-ede3-cbc", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_DES
+    { FT_cipher, "des-cfb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_DES
+    { FT_cipher, "des-ede-cfb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_DES
+    { FT_cipher, "des-ede3-cfb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_DES
+    { FT_cipher, "des-ofb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_DES
+    { FT_cipher, "des-ede-ofb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_DES
+    { FT_cipher, "des-ede3-ofb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_IDEA
+    { FT_cipher, "idea-cbc", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_IDEA
+    { FT_cipher, "idea-ecb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_IDEA
+    { FT_cipher, "idea-cfb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_IDEA
+    { FT_cipher, "idea-ofb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_SEED
+    { FT_cipher, "seed-cbc", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_SEED
+    { FT_cipher, "seed-ecb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_SEED
+    { FT_cipher, "seed-cfb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_SEED
+    { FT_cipher, "seed-ofb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_RC2
+    { FT_cipher, "rc2-cbc", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_RC2
+    { FT_cipher, "rc2-ecb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_RC2
+    { FT_cipher, "rc2-cfb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_RC2
+    { FT_cipher, "rc2-ofb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_RC2
+    { FT_cipher, "rc2-64-cbc", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_RC2
+    { FT_cipher, "rc2-40-cbc", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_BF
+    { FT_cipher, "bf-cbc", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_BF
+    { FT_cipher, "bf-ecb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_BF
+    { FT_cipher, "bf-cfb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_BF
+    { FT_cipher, "bf-ofb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_CAST
+    { FT_cipher, "cast5-cbc", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_CAST
+    { FT_cipher, "cast5-ecb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_CAST
+    { FT_cipher, "cast5-cfb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_CAST
+    { FT_cipher, "cast5-ofb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_CAST
+    { FT_cipher, "cast-cbc", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_RC5
+    { FT_cipher, "rc5-cbc", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_RC5
+    { FT_cipher, "rc5-ecb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_RC5
+    { FT_cipher, "rc5-cfb", enc_main, enc_options },
+#endif
+#ifndef OPENSSL_NO_RC5
+    { FT_cipher, "rc5-ofb", enc_main, enc_options },
+#endif
+    { 0, NULL, NULL}
+};
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/rand.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/rand.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/rand.c	(revision 331)
@@ -0,0 +1,132 @@
+/*
+ * Copyright 1998-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 "apps.h"
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_OUT, OPT_ENGINE, OPT_RAND, OPT_BASE64, OPT_HEX
+} OPTION_CHOICE;
+
+OPTIONS rand_options[] = {
+    {OPT_HELP_STR, 1, '-', "Usage: %s [flags] num\n"},
+    {OPT_HELP_STR, 1, '-', "Valid options are:\n"},
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"out", OPT_OUT, '>', "Output file"},
+    {"rand", OPT_RAND, 's',
+     "Load the file(s) into the random number generator"},
+    {"base64", OPT_BASE64, '-', "Base64 encode output"},
+    {"hex", OPT_HEX, '-', "Hex encode output"},
+#ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+#endif
+    {NULL}
+};
+
+int rand_main(int argc, char **argv)
+{
+    ENGINE *e = NULL;
+    BIO *out = NULL;
+    char *inrand = NULL, *outfile = NULL, *prog;
+    OPTION_CHOICE o;
+    int format = FORMAT_BINARY, i, num = -1, r, ret = 1;
+
+    prog = opt_init(argc, argv, rand_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(rand_options);
+            ret = 0;
+            goto end;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        case OPT_RAND:
+            inrand = opt_arg();
+            break;
+        case OPT_BASE64:
+            format = FORMAT_BASE64;
+            break;
+        case OPT_HEX:
+            format = FORMAT_TEXT;
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    argv = opt_rest();
+
+    if (argc != 1 || !opt_int(argv[0], &num) || num < 0)
+        goto opthelp;
+
+    app_RAND_load_file(NULL, (inrand != NULL));
+    if (inrand != NULL)
+        BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
+                   app_RAND_load_files(inrand));
+
+    out = bio_open_default(outfile, 'w', format);
+    if (out == NULL)
+        goto end;
+
+    if (format == FORMAT_BASE64) {
+        BIO *b64 = BIO_new(BIO_f_base64());
+        if (b64 == NULL)
+            goto end;
+        out = BIO_push(b64, out);
+    }
+
+    while (num > 0) {
+        unsigned char buf[4096];
+        int chunk;
+
+        chunk = num;
+        if (chunk > (int)sizeof(buf))
+            chunk = sizeof buf;
+        r = RAND_bytes(buf, chunk);
+        if (r <= 0)
+            goto end;
+        if (format != FORMAT_TEXT) {
+            if (BIO_write(out, buf, chunk) != chunk)
+                goto end;
+        } else {
+            for (i = 0; i < chunk; i++)
+                if (BIO_printf(out, "%02x", buf[i]) != 2)
+                    goto end;
+        }
+        num -= chunk;
+    }
+    if (format == FORMAT_TEXT)
+        BIO_puts(out, "\n");
+    if (BIO_flush(out) <= 0 || !app_RAND_write_file(NULL))
+        goto end;
+
+    ret = 0;
+
+ end:
+    if (ret != 0)
+        ERR_print_errors(bio_err);
+    release_engine(e);
+    BIO_free_all(out);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/rehash.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/rehash.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/rehash.c	(revision 331)
@@ -0,0 +1,480 @@
+/*
+ * Copyright 2015-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
+ */
+
+/*
+ * C implementation based on the original Perl and shell versions
+ *
+ * Copyright (c) 2013-2014 Timo Ter辰s <timo.teras@iki.fi>
+ */
+
+#include "apps.h"
+
+#if defined(OPENSSL_SYS_UNIX) || defined(__APPLE__) || \
+    (defined(__VMS) && defined(__DECC) && __CTRL_VER >= 80300000)
+# include <unistd.h>
+# include <stdio.h>
+# include <limits.h>
+# include <errno.h>
+# include <string.h>
+# include <ctype.h>
+# include <sys/stat.h>
+
+# include "internal/o_dir.h"
+# include <openssl/evp.h>
+# include <openssl/pem.h>
+# include <openssl/x509.h>
+
+
+# ifndef PATH_MAX
+#  define PATH_MAX 4096
+# endif
+# ifndef NAME_MAX
+#  define NAME_MAX 255
+# endif
+# define MAX_COLLISIONS  256
+
+typedef struct hentry_st {
+    struct hentry_st *next;
+    char *filename;
+    unsigned short old_id;
+    unsigned char need_symlink;
+    unsigned char digest[EVP_MAX_MD_SIZE];
+} HENTRY;
+
+typedef struct bucket_st {
+    struct bucket_st *next;
+    HENTRY *first_entry, *last_entry;
+    unsigned int hash;
+    unsigned short type;
+    unsigned short num_needed;
+} BUCKET;
+
+enum Type {
+    /* Keep in sync with |suffixes|, below. */
+    TYPE_CERT=0, TYPE_CRL=1
+};
+
+enum Hash {
+    HASH_OLD, HASH_NEW, HASH_BOTH
+};
+
+
+static int evpmdsize;
+static const EVP_MD *evpmd;
+static int remove_links = 1;
+static int verbose = 0;
+static BUCKET *hash_table[257];
+
+static const char *suffixes[] = { "", "r" };
+static const char *extensions[] = { "pem", "crt", "cer", "crl" };
+
+
+static void bit_set(unsigned char *set, unsigned int bit)
+{
+    set[bit >> 3] |= 1 << (bit & 0x7);
+}
+
+static int bit_isset(unsigned char *set, unsigned int bit)
+{
+    return set[bit >> 3] & (1 << (bit & 0x7));
+}
+
+
+/*
+ * Process an entry; return number of errors.
+ */
+static int add_entry(enum Type type, unsigned int hash, const char *filename,
+                      const unsigned char *digest, int need_symlink,
+                      unsigned short old_id)
+{
+    static BUCKET nilbucket;
+    static HENTRY nilhentry;
+    BUCKET *bp;
+    HENTRY *ep, *found = NULL;
+    unsigned int ndx = (type + hash) % OSSL_NELEM(hash_table);
+
+    for (bp = hash_table[ndx]; bp; bp = bp->next)
+        if (bp->type == type && bp->hash == hash)
+            break;
+    if (bp == NULL) {
+        bp = app_malloc(sizeof(*bp), "hash bucket");
+        *bp = nilbucket;
+        bp->next = hash_table[ndx];
+        bp->type = type;
+        bp->hash = hash;
+        hash_table[ndx] = bp;
+    }
+
+    for (ep = bp->first_entry; ep; ep = ep->next) {
+        if (digest && memcmp(digest, ep->digest, evpmdsize) == 0) {
+            BIO_printf(bio_err,
+                       "%s: skipping duplicate %s in %s\n", opt_getprog(),
+                       type == TYPE_CERT ? "certificate" : "CRL", filename);
+            return 1;
+        }
+        if (strcmp(filename, ep->filename) == 0) {
+            found = ep;
+            if (digest == NULL)
+                break;
+        }
+    }
+    ep = found;
+    if (ep == NULL) {
+        if (bp->num_needed >= MAX_COLLISIONS) {
+            BIO_printf(bio_err,
+                       "%s: hash table overflow for %s\n",
+                       opt_getprog(), filename);
+            return 1;
+        }
+        ep = app_malloc(sizeof(*ep), "collision bucket");
+        *ep = nilhentry;
+        ep->old_id = ~0;
+        ep->filename = OPENSSL_strdup(filename);
+        if (bp->last_entry)
+            bp->last_entry->next = ep;
+        if (bp->first_entry == NULL)
+            bp->first_entry = ep;
+        bp->last_entry = ep;
+    }
+
+    if (old_id < ep->old_id)
+        ep->old_id = old_id;
+    if (need_symlink && !ep->need_symlink) {
+        ep->need_symlink = 1;
+        bp->num_needed++;
+        memcpy(ep->digest, digest, evpmdsize);
+    }
+    return 0;
+}
+
+/*
+ * Check if a symlink goes to the right spot; return 0 if okay.
+ * This can be -1 if bad filename, or an error count.
+ */
+static int handle_symlink(const char *filename, const char *fullpath)
+{
+    unsigned int hash = 0;
+    int i, type, id;
+    unsigned char ch;
+    char linktarget[PATH_MAX], *endptr;
+    ossl_ssize_t n;
+
+    for (i = 0; i < 8; i++) {
+        ch = filename[i];
+        if (!isxdigit(ch))
+            return -1;
+        hash <<= 4;
+        hash += OPENSSL_hexchar2int(ch);
+    }
+    if (filename[i++] != '.')
+        return -1;
+    for (type = OSSL_NELEM(suffixes) - 1; type > 0; type--) {
+        const char *suffix = suffixes[type];
+        if (strncasecmp(suffix, &filename[i], strlen(suffix)) == 0)
+            break;
+    }
+    i += strlen(suffixes[type]);
+
+    id = strtoul(&filename[i], &endptr, 10);
+    if (*endptr != '\0')
+        return -1;
+
+    n = readlink(fullpath, linktarget, sizeof(linktarget));
+    if (n < 0 || n >= (int)sizeof(linktarget))
+        return -1;
+    linktarget[n] = 0;
+
+    return add_entry(type, hash, linktarget, NULL, 0, id);
+}
+
+/*
+ * process a file, return number of errors.
+ */
+static int do_file(const char *filename, const char *fullpath, enum Hash h)
+{
+    STACK_OF (X509_INFO) *inf = NULL;
+    X509_INFO *x;
+    X509_NAME *name = NULL;
+    BIO *b;
+    const char *ext;
+    unsigned char digest[EVP_MAX_MD_SIZE];
+    int type, errs = 0;
+    size_t i;
+
+    /* Does it end with a recognized extension? */
+    if ((ext = strrchr(filename, '.')) == NULL)
+        goto end;
+    for (i = 0; i < OSSL_NELEM(extensions); i++) {
+        if (strcasecmp(extensions[i], ext + 1) == 0)
+            break;
+    }
+    if (i >= OSSL_NELEM(extensions))
+        goto end;
+
+    /* Does it have X.509 data in it? */
+    if ((b = BIO_new_file(fullpath, "r")) == NULL) {
+        BIO_printf(bio_err, "%s: skipping %s, cannot open file\n",
+                   opt_getprog(), filename);
+        errs++;
+        goto end;
+    }
+    inf = PEM_X509_INFO_read_bio(b, NULL, NULL, NULL);
+    BIO_free(b);
+    if (inf == NULL)
+        goto end;
+
+    if (sk_X509_INFO_num(inf) != 1) {
+        BIO_printf(bio_err,
+                   "%s: skipping %s,"
+                   "it does not contain exactly one certificate or CRL\n",
+                   opt_getprog(), filename);
+        /* This is not an error. */
+        goto end;
+    }
+    x = sk_X509_INFO_value(inf, 0);
+    if (x->x509) {
+        type = TYPE_CERT;
+        name = X509_get_subject_name(x->x509);
+        X509_digest(x->x509, evpmd, digest, NULL);
+    } else if (x->crl) {
+        type = TYPE_CRL;
+        name = X509_CRL_get_issuer(x->crl);
+        X509_CRL_digest(x->crl, evpmd, digest, NULL);
+    } else {
+        ++errs;
+        goto end;
+    }
+    if (name) {
+        if ((h == HASH_NEW) || (h == HASH_BOTH))
+            errs += add_entry(type, X509_NAME_hash(name), filename, digest, 1, ~0);
+        if ((h == HASH_OLD) || (h == HASH_BOTH))
+            errs += add_entry(type, X509_NAME_hash_old(name), filename, digest, 1, ~0);
+    }
+
+end:
+    sk_X509_INFO_pop_free(inf, X509_INFO_free);
+    return errs;
+}
+
+static void str_free(char *s)
+{
+    OPENSSL_free(s);
+}
+
+/*
+ * Process a directory; return number of errors found.
+ */
+static int do_dir(const char *dirname, enum Hash h)
+{
+    BUCKET *bp, *nextbp;
+    HENTRY *ep, *nextep;
+    OPENSSL_DIR_CTX *d = NULL;
+    struct stat st;
+    unsigned char idmask[MAX_COLLISIONS / 8];
+    int n, numfiles, nextid, buflen, errs = 0;
+    size_t i;
+    const char *pathsep;
+    const char *filename;
+    char *buf, *copy;
+    STACK_OF(OPENSSL_STRING) *files = NULL;
+
+    if (app_access(dirname, W_OK) < 0) {
+        BIO_printf(bio_err, "Skipping %s, can't write\n", dirname);
+        return 1;
+    }
+    buflen = strlen(dirname);
+    pathsep = (buflen && dirname[buflen - 1] == '/') ? "" : "/";
+    buflen += NAME_MAX + 1 + 1;
+    buf = app_malloc(buflen, "filename buffer");
+
+    if (verbose)
+        BIO_printf(bio_out, "Doing %s\n", dirname);
+
+    if ((files = sk_OPENSSL_STRING_new_null()) == NULL) {
+        BIO_printf(bio_err, "Skipping %s, out of memory\n", dirname);
+        exit(1);
+    }
+    while ((filename = OPENSSL_DIR_read(&d, dirname)) != NULL) {
+        if ((copy = strdup(filename)) == NULL
+                || sk_OPENSSL_STRING_push(files, copy) == 0) {
+            BIO_puts(bio_err, "out of memory\n");
+            exit(1);
+        }
+    }
+    OPENSSL_DIR_end(&d);
+    sk_OPENSSL_STRING_sort(files);
+
+    numfiles = sk_OPENSSL_STRING_num(files);
+    for (n = 0; n < numfiles; ++n) {
+        filename = sk_OPENSSL_STRING_value(files, n);
+        if (snprintf(buf, buflen, "%s%s%s",
+                    dirname, pathsep, filename) >= buflen)
+            continue;
+        if (lstat(buf, &st) < 0)
+            continue;
+        if (S_ISLNK(st.st_mode) && handle_symlink(filename, buf) == 0)
+            continue;
+        errs += do_file(filename, buf, h);
+    }
+    sk_OPENSSL_STRING_pop_free(files, str_free);
+
+    for (i = 0; i < OSSL_NELEM(hash_table); i++) {
+        for (bp = hash_table[i]; bp; bp = nextbp) {
+            nextbp = bp->next;
+            nextid = 0;
+            memset(idmask, 0, (bp->num_needed + 7) / 8);
+            for (ep = bp->first_entry; ep; ep = ep->next)
+                if (ep->old_id < bp->num_needed)
+                    bit_set(idmask, ep->old_id);
+
+            for (ep = bp->first_entry; ep; ep = nextep) {
+                nextep = ep->next;
+                if (ep->old_id < bp->num_needed) {
+                    /* Link exists, and is used as-is */
+                    snprintf(buf, buflen, "%08x.%s%d", bp->hash,
+                             suffixes[bp->type], ep->old_id);
+                    if (verbose)
+                        BIO_printf(bio_out, "link %s -> %s\n",
+                                   ep->filename, buf);
+                } else if (ep->need_symlink) {
+                    /* New link needed (it may replace something) */
+                    while (bit_isset(idmask, nextid))
+                        nextid++;
+
+                    snprintf(buf, buflen, "%s%s%n%08x.%s%d",
+                             dirname, pathsep, &n, bp->hash,
+                             suffixes[bp->type], nextid);
+                    if (verbose)
+                        BIO_printf(bio_out, "link %s -> %s\n",
+                                   ep->filename, &buf[n]);
+                    if (unlink(buf) < 0 && errno != ENOENT) {
+                        BIO_printf(bio_err,
+                                   "%s: Can't unlink %s, %s\n",
+                                   opt_getprog(), buf, strerror(errno));
+                        errs++;
+                    }
+                    if (symlink(ep->filename, buf) < 0) {
+                        BIO_printf(bio_err,
+                                   "%s: Can't symlink %s, %s\n",
+                                   opt_getprog(), ep->filename,
+                                   strerror(errno));
+                        errs++;
+                    }
+                    bit_set(idmask, nextid);
+                } else if (remove_links) {
+                    /* Link to be deleted */
+                    snprintf(buf, buflen, "%s%s%n%08x.%s%d",
+                             dirname, pathsep, &n, bp->hash,
+                             suffixes[bp->type], ep->old_id);
+                    if (verbose)
+                        BIO_printf(bio_out, "unlink %s\n",
+                                   &buf[n]);
+                    if (unlink(buf) < 0 && errno != ENOENT) {
+                        BIO_printf(bio_err,
+                                   "%s: Can't unlink %s, %s\n",
+                                   opt_getprog(), buf, strerror(errno));
+                        errs++;
+                    }
+                }
+                OPENSSL_free(ep->filename);
+                OPENSSL_free(ep);
+            }
+            OPENSSL_free(bp);
+        }
+        hash_table[i] = NULL;
+    }
+
+    OPENSSL_free(buf);
+    return errs;
+}
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_COMPAT, OPT_OLD, OPT_N, OPT_VERBOSE
+} OPTION_CHOICE;
+
+OPTIONS rehash_options[] = {
+    {OPT_HELP_STR, 1, '-', "Usage: %s [options] [cert-directory...]\n"},
+    {OPT_HELP_STR, 1, '-', "Valid options are:\n"},
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"h", OPT_HELP, '-', "Display this summary"},
+    {"compat", OPT_COMPAT, '-', "Create both new- and old-style hash links"},
+    {"old", OPT_OLD, '-', "Use old-style hash to generate links"},
+    {"n", OPT_N, '-', "Do not remove existing links"},
+    {"v", OPT_VERBOSE, '-', "Verbose output"},
+    {NULL}
+};
+
+
+int rehash_main(int argc, char **argv)
+{
+    const char *env, *prog;
+    char *e, *m;
+    int errs = 0;
+    OPTION_CHOICE o;
+    enum Hash h = HASH_NEW;
+
+    prog = opt_init(argc, argv, rehash_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(rehash_options);
+            goto end;
+        case OPT_COMPAT:
+            h = HASH_BOTH;
+            break;
+        case OPT_OLD:
+            h = HASH_OLD;
+            break;
+        case OPT_N:
+            remove_links = 0;
+            break;
+        case OPT_VERBOSE:
+            verbose = 1;
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    argv = opt_rest();
+
+    evpmd = EVP_sha1();
+    evpmdsize = EVP_MD_size(evpmd);
+
+    if (*argv) {
+        while (*argv)
+            errs += do_dir(*argv++, h);
+    } else if ((env = getenv("SSL_CERT_DIR")) != NULL) {
+        m = OPENSSL_strdup(env);
+        for (e = strtok(m, ":"); e != NULL; e = strtok(NULL, ":"))
+            errs += do_dir(e, h);
+        OPENSSL_free(m);
+    } else {
+        errs += do_dir("/etc/ssl/certs", h);
+    }
+
+ end:
+    return errs;
+}
+
+#else
+OPTIONS rehash_options[] = {
+    {NULL}
+};
+
+int rehash_main(int argc, char **argv)
+{
+    BIO_printf(bio_err, "Not available; use c_rehash script\n");
+    return (1);
+}
+
+#endif /* defined(OPENSSL_SYS_UNIX) || defined(__APPLE__) */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/req.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/req.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/req.c	(revision 331)
@@ -0,0 +1,1508 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/conf.h>
+#include <openssl/err.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+#endif
+
+#define SECTION         "req"
+
+#define BITS            "default_bits"
+#define KEYFILE         "default_keyfile"
+#define PROMPT          "prompt"
+#define DISTINGUISHED_NAME      "distinguished_name"
+#define ATTRIBUTES      "attributes"
+#define V3_EXTENSIONS   "x509_extensions"
+#define REQ_EXTENSIONS  "req_extensions"
+#define STRING_MASK     "string_mask"
+#define UTF8_IN         "utf8"
+
+#define DEFAULT_KEY_LENGTH      2048
+#define MIN_KEY_LENGTH          512
+
+static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *dn, int mutlirdn,
+                    int attribs, unsigned long chtype);
+static int build_subject(X509_REQ *req, const char *subj, unsigned long chtype,
+                         int multirdn);
+static int prompt_info(X509_REQ *req,
+                       STACK_OF(CONF_VALUE) *dn_sk, const char *dn_sect,
+                       STACK_OF(CONF_VALUE) *attr_sk, const char *attr_sect,
+                       int attribs, unsigned long chtype);
+static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *sk,
+                     STACK_OF(CONF_VALUE) *attr, int attribs,
+                     unsigned long chtype);
+static int add_attribute_object(X509_REQ *req, char *text, const char *def,
+                                char *value, int nid, int n_min, int n_max,
+                                unsigned long chtype);
+static int add_DN_object(X509_NAME *n, char *text, const char *def,
+                         char *value, int nid, int n_min, int n_max,
+                         unsigned long chtype, int mval);
+static int genpkey_cb(EVP_PKEY_CTX *ctx);
+static int req_check_len(int len, int n_min, int n_max);
+static int check_end(const char *str, const char *end);
+static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr,
+                                    int *pkey_type, long *pkeylen,
+                                    char **palgnam, ENGINE *keygen_engine);
+static CONF *req_conf = NULL;
+static int batch = 0;
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_KEYGEN_ENGINE, OPT_KEY,
+    OPT_PUBKEY, OPT_NEW, OPT_CONFIG, OPT_KEYFORM, OPT_IN, OPT_OUT,
+    OPT_KEYOUT, OPT_PASSIN, OPT_PASSOUT, OPT_RAND, OPT_NEWKEY,
+    OPT_PKEYOPT, OPT_SIGOPT, OPT_BATCH, OPT_NEWHDR, OPT_MODULUS,
+    OPT_VERIFY, OPT_NODES, OPT_NOOUT, OPT_VERBOSE, OPT_UTF8,
+    OPT_NAMEOPT, OPT_REQOPT, OPT_SUBJ, OPT_SUBJECT, OPT_TEXT, OPT_X509,
+    OPT_MULTIVALUE_RDN, OPT_DAYS, OPT_SET_SERIAL, OPT_EXTENSIONS,
+    OPT_REQEXTS, OPT_MD
+} OPTION_CHOICE;
+
+OPTIONS req_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"inform", OPT_INFORM, 'F', "Input format - DER or PEM"},
+    {"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"},
+    {"in", OPT_IN, '<', "Input file"},
+    {"out", OPT_OUT, '>', "Output file"},
+    {"key", OPT_KEY, 's', "Private key to use"},
+    {"keyform", OPT_KEYFORM, 'f', "Key file format"},
+    {"pubkey", OPT_PUBKEY, '-', "Output public key"},
+    {"new", OPT_NEW, '-', "New request"},
+    {"config", OPT_CONFIG, '<', "Request template file"},
+    {"keyout", OPT_KEYOUT, '>', "File to send the key to"},
+    {"passin", OPT_PASSIN, 's', "Private key password source"},
+    {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
+    {"rand", OPT_RAND, 's',
+     "Load the file(s) into the random number generator"},
+    {"newkey", OPT_NEWKEY, 's', "Specify as type:bits"},
+    {"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"},
+    {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"},
+    {"batch", OPT_BATCH, '-',
+     "Do not ask anything during request generation"},
+    {"newhdr", OPT_NEWHDR, '-', "Output \"NEW\" in the header lines"},
+    {"modulus", OPT_MODULUS, '-', "RSA modulus"},
+    {"verify", OPT_VERIFY, '-', "Verify signature on REQ"},
+    {"nodes", OPT_NODES, '-', "Don't encrypt the output key"},
+    {"noout", OPT_NOOUT, '-', "Do not output REQ"},
+    {"verbose", OPT_VERBOSE, '-', "Verbose output"},
+    {"utf8", OPT_UTF8, '-', "Input characters are UTF8 (default ASCII)"},
+    {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"},
+    {"reqopt", OPT_REQOPT, 's', "Various request text options"},
+    {"text", OPT_TEXT, '-', "Text form of request"},
+    {"x509", OPT_X509, '-',
+     "Output a x509 structure instead of a cert request"},
+    {OPT_MORE_STR, 1, 1, "(Required by some CA's)"},
+    {"subj", OPT_SUBJ, 's', "Set or modify request subject"},
+    {"subject", OPT_SUBJECT, '-', "Output the request's subject"},
+    {"multivalue-rdn", OPT_MULTIVALUE_RDN, '-',
+     "Enable support for multivalued RDNs"},
+    {"days", OPT_DAYS, 'p', "Number of days cert is valid for"},
+    {"set_serial", OPT_SET_SERIAL, 's', "Serial number to use"},
+    {"extensions", OPT_EXTENSIONS, 's',
+     "Cert extension section (override value in config file)"},
+    {"reqexts", OPT_REQEXTS, 's',
+     "Request extension section (override value in config file)"},
+    {"", OPT_MD, '-', "Any supported digest"},
+#ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+    {"keygen_engine", OPT_KEYGEN_ENGINE, 's',
+     "Specify engine to be used for key generation operations"},
+#endif
+    {NULL}
+};
+
+int req_main(int argc, char **argv)
+{
+    ASN1_INTEGER *serial = NULL;
+    BIO *in = NULL, *out = NULL;
+    ENGINE *e = NULL, *gen_eng = NULL;
+    EVP_PKEY *pkey = NULL;
+    EVP_PKEY_CTX *genctx = NULL;
+    STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL;
+    X509 *x509ss = NULL;
+    X509_REQ *req = NULL;
+    const EVP_CIPHER *cipher = NULL;
+    const EVP_MD *md_alg = NULL, *digest = NULL;
+    char *extensions = NULL, *infile = NULL;
+    char *outfile = NULL, *keyfile = NULL, *inrand = NULL;
+    char *keyalgstr = NULL, *p, *prog, *passargin = NULL, *passargout = NULL;
+    char *passin = NULL, *passout = NULL;
+    char *nofree_passin = NULL, *nofree_passout = NULL;
+    char *req_exts = NULL, *subj = NULL;
+    char *template = default_config_file, *keyout = NULL;
+    const char *keyalg = NULL;
+    OPTION_CHOICE o;
+    int ret = 1, x509 = 0, days = 30, i = 0, newreq = 0, verbose = 0;
+    int pkey_type = -1, private = 0;
+    int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyform = FORMAT_PEM;
+    int modulus = 0, multirdn = 0, verify = 0, noout = 0, text = 0;
+    int nodes = 0, newhdr = 0, subject = 0, pubkey = 0;
+    long newkey = -1;
+    unsigned long chtype = MBSTRING_ASC, nmflag = 0, reqflag = 0;
+    char nmflag_set = 0;
+
+#ifndef OPENSSL_NO_DES
+    cipher = EVP_des_ede3_cbc();
+#endif
+
+    prog = opt_init(argc, argv, req_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(req_options);
+            ret = 0;
+            goto end;
+        case OPT_INFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
+                goto opthelp;
+            break;
+        case OPT_OUTFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
+                goto opthelp;
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        case OPT_KEYGEN_ENGINE:
+#ifndef OPENSSL_NO_ENGINE
+            gen_eng = ENGINE_by_id(opt_arg());
+            if (gen_eng == NULL) {
+                BIO_printf(bio_err, "Can't find keygen engine %s\n", *argv);
+                goto opthelp;
+            }
+#endif
+            break;
+        case OPT_KEY:
+            keyfile = opt_arg();
+            break;
+        case OPT_PUBKEY:
+            pubkey = 1;
+            break;
+        case OPT_NEW:
+            newreq = 1;
+            break;
+        case OPT_CONFIG:
+            template = opt_arg();
+            break;
+        case OPT_KEYFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform))
+                goto opthelp;
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_KEYOUT:
+            keyout = opt_arg();
+            break;
+        case OPT_PASSIN:
+            passargin = opt_arg();
+            break;
+        case OPT_PASSOUT:
+            passargout = opt_arg();
+            break;
+        case OPT_RAND:
+            inrand = opt_arg();
+            break;
+        case OPT_NEWKEY:
+            keyalg = opt_arg();
+            newreq = 1;
+            break;
+        case OPT_PKEYOPT:
+            if (!pkeyopts)
+                pkeyopts = sk_OPENSSL_STRING_new_null();
+            if (!pkeyopts || !sk_OPENSSL_STRING_push(pkeyopts, opt_arg()))
+                goto opthelp;
+            break;
+        case OPT_SIGOPT:
+            if (!sigopts)
+                sigopts = sk_OPENSSL_STRING_new_null();
+            if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
+                goto opthelp;
+            break;
+        case OPT_BATCH:
+            batch = 1;
+            break;
+        case OPT_NEWHDR:
+            newhdr = 1;
+            break;
+        case OPT_MODULUS:
+            modulus = 1;
+            break;
+        case OPT_VERIFY:
+            verify = 1;
+            break;
+        case OPT_NODES:
+            nodes = 1;
+            break;
+        case OPT_NOOUT:
+            noout = 1;
+            break;
+        case OPT_VERBOSE:
+            verbose = 1;
+            break;
+        case OPT_UTF8:
+            chtype = MBSTRING_UTF8;
+            break;
+        case OPT_NAMEOPT:
+            nmflag_set = 1;
+            if (!set_name_ex(&nmflag, opt_arg()))
+                goto opthelp;
+            break;
+        case OPT_REQOPT:
+            if (!set_cert_ex(&reqflag, opt_arg()))
+                goto opthelp;
+            break;
+        case OPT_TEXT:
+            text = 1;
+            break;
+        case OPT_X509:
+            x509 = 1;
+            newreq = 1;
+            break;
+        case OPT_DAYS:
+            days = atoi(opt_arg());
+            break;
+        case OPT_SET_SERIAL:
+            if (serial != NULL) {
+                BIO_printf(bio_err, "Serial number supplied twice\n");
+                goto opthelp;
+            }
+            serial = s2i_ASN1_INTEGER(NULL, opt_arg());
+            if (serial == NULL)
+                goto opthelp;
+            break;
+        case OPT_SUBJECT:
+            subject = 1;
+            break;
+        case OPT_SUBJ:
+            subj = opt_arg();
+            break;
+        case OPT_MULTIVALUE_RDN:
+            multirdn = 1;
+            break;
+        case OPT_EXTENSIONS:
+            extensions = opt_arg();
+            break;
+        case OPT_REQEXTS:
+            req_exts = opt_arg();
+            break;
+        case OPT_MD:
+            if (!opt_md(opt_unknown(), &md_alg))
+                goto opthelp;
+            digest = md_alg;
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    if (!nmflag_set)
+        nmflag = XN_FLAG_ONELINE;
+
+    /* TODO: simplify this as pkey is still always NULL here */
+    private = newreq && (pkey == NULL) ? 1 : 0;
+
+    if (!app_passwd(passargin, passargout, &passin, &passout)) {
+        BIO_printf(bio_err, "Error getting passwords\n");
+        goto end;
+    }
+
+    if (verbose)
+        BIO_printf(bio_err, "Using configuration from %s\n", template);
+    req_conf = app_load_config(template);
+    if (template != default_config_file && !app_load_modules(req_conf))
+        goto end;
+
+    if (req_conf != NULL) {
+        p = NCONF_get_string(req_conf, NULL, "oid_file");
+        if (p == NULL)
+            ERR_clear_error();
+        if (p != NULL) {
+            BIO *oid_bio;
+
+            oid_bio = BIO_new_file(p, "r");
+            if (oid_bio == NULL) {
+                /*-
+                BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
+                ERR_print_errors(bio_err);
+                */
+            } else {
+                OBJ_create_objects(oid_bio);
+                BIO_free(oid_bio);
+            }
+        }
+    }
+    if (!add_oid_section(req_conf))
+        goto end;
+
+    if (md_alg == NULL) {
+        p = NCONF_get_string(req_conf, SECTION, "default_md");
+        if (p == NULL)
+            ERR_clear_error();
+        else {
+            if (!opt_md(p, &md_alg))
+                goto opthelp;
+            digest = md_alg;
+        }
+    }
+
+    if (!extensions) {
+        extensions = NCONF_get_string(req_conf, SECTION, V3_EXTENSIONS);
+        if (!extensions)
+            ERR_clear_error();
+    }
+    if (extensions) {
+        /* Check syntax of file */
+        X509V3_CTX ctx;
+        X509V3_set_ctx_test(&ctx);
+        X509V3_set_nconf(&ctx, req_conf);
+        if (!X509V3_EXT_add_nconf(req_conf, &ctx, extensions, NULL)) {
+            BIO_printf(bio_err,
+                       "Error Loading extension section %s\n", extensions);
+            goto end;
+        }
+    }
+
+    if (passin == NULL) {
+        passin = nofree_passin =
+            NCONF_get_string(req_conf, SECTION, "input_password");
+        if (passin == NULL)
+            ERR_clear_error();
+    }
+
+    if (passout == NULL) {
+        passout = nofree_passout =
+            NCONF_get_string(req_conf, SECTION, "output_password");
+        if (passout == NULL)
+            ERR_clear_error();
+    }
+
+    p = NCONF_get_string(req_conf, SECTION, STRING_MASK);
+    if (!p)
+        ERR_clear_error();
+
+    if (p && !ASN1_STRING_set_default_mask_asc(p)) {
+        BIO_printf(bio_err, "Invalid global string mask setting %s\n", p);
+        goto end;
+    }
+
+    if (chtype != MBSTRING_UTF8) {
+        p = NCONF_get_string(req_conf, SECTION, UTF8_IN);
+        if (!p)
+            ERR_clear_error();
+        else if (strcmp(p, "yes") == 0)
+            chtype = MBSTRING_UTF8;
+    }
+
+    if (!req_exts) {
+        req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS);
+        if (!req_exts)
+            ERR_clear_error();
+    }
+    if (req_exts) {
+        /* Check syntax of file */
+        X509V3_CTX ctx;
+        X509V3_set_ctx_test(&ctx);
+        X509V3_set_nconf(&ctx, req_conf);
+        if (!X509V3_EXT_add_nconf(req_conf, &ctx, req_exts, NULL)) {
+            BIO_printf(bio_err,
+                       "Error Loading request extension section %s\n",
+                       req_exts);
+            goto end;
+        }
+    }
+
+    if (keyfile != NULL) {
+        pkey = load_key(keyfile, keyform, 0, passin, e, "Private Key");
+        if (!pkey) {
+            /* load_key() has already printed an appropriate message */
+            goto end;
+        } else {
+            char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE");
+            if (randfile == NULL)
+                ERR_clear_error();
+            app_RAND_load_file(randfile, 0);
+        }
+    }
+
+    if (newreq && (pkey == NULL)) {
+        char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE");
+        if (randfile == NULL)
+            ERR_clear_error();
+        app_RAND_load_file(randfile, 0);
+        if (inrand)
+            app_RAND_load_files(inrand);
+
+        if (!NCONF_get_number(req_conf, SECTION, BITS, &newkey)) {
+            newkey = DEFAULT_KEY_LENGTH;
+        }
+
+        if (keyalg) {
+            genctx = set_keygen_ctx(keyalg, &pkey_type, &newkey,
+                                    &keyalgstr, gen_eng);
+            if (!genctx)
+                goto end;
+        }
+
+        if (newkey < MIN_KEY_LENGTH
+            && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA)) {
+            BIO_printf(bio_err, "private key length is too short,\n");
+            BIO_printf(bio_err, "it needs to be at least %d bits, not %ld\n",
+                       MIN_KEY_LENGTH, newkey);
+            goto end;
+        }
+
+        if (!genctx) {
+            genctx = set_keygen_ctx(NULL, &pkey_type, &newkey,
+                                    &keyalgstr, gen_eng);
+            if (!genctx)
+                goto end;
+        }
+
+        if (pkeyopts) {
+            char *genopt;
+            for (i = 0; i < sk_OPENSSL_STRING_num(pkeyopts); i++) {
+                genopt = sk_OPENSSL_STRING_value(pkeyopts, i);
+                if (pkey_ctrl_string(genctx, genopt) <= 0) {
+                    BIO_printf(bio_err, "parameter error \"%s\"\n", genopt);
+                    ERR_print_errors(bio_err);
+                    goto end;
+                }
+            }
+        }
+
+        if (pkey_type == EVP_PKEY_EC) {
+            BIO_printf(bio_err, "Generating an EC private key\n");
+        } else {
+            BIO_printf(bio_err, "Generating a %ld bit %s private key\n",
+                       newkey, keyalgstr);
+        }
+
+        EVP_PKEY_CTX_set_cb(genctx, genpkey_cb);
+        EVP_PKEY_CTX_set_app_data(genctx, bio_err);
+
+        if (EVP_PKEY_keygen(genctx, &pkey) <= 0) {
+            BIO_puts(bio_err, "Error Generating Key\n");
+            goto end;
+        }
+
+        EVP_PKEY_CTX_free(genctx);
+        genctx = NULL;
+
+        app_RAND_write_file(randfile);
+
+        if (keyout == NULL) {
+            keyout = NCONF_get_string(req_conf, SECTION, KEYFILE);
+            if (keyout == NULL)
+                ERR_clear_error();
+        }
+
+        if (keyout == NULL)
+            BIO_printf(bio_err, "writing new private key to stdout\n");
+        else
+            BIO_printf(bio_err, "writing new private key to '%s'\n", keyout);
+        out = bio_open_owner(keyout, outformat, private);
+        if (out == NULL)
+            goto end;
+
+        p = NCONF_get_string(req_conf, SECTION, "encrypt_rsa_key");
+        if (p == NULL) {
+            ERR_clear_error();
+            p = NCONF_get_string(req_conf, SECTION, "encrypt_key");
+            if (p == NULL)
+                ERR_clear_error();
+        }
+        if ((p != NULL) && (strcmp(p, "no") == 0))
+            cipher = NULL;
+        if (nodes)
+            cipher = NULL;
+
+        i = 0;
+ loop:
+        assert(private);
+        if (!PEM_write_bio_PrivateKey(out, pkey, cipher,
+                                      NULL, 0, NULL, passout)) {
+            if ((ERR_GET_REASON(ERR_peek_error()) ==
+                 PEM_R_PROBLEMS_GETTING_PASSWORD) && (i < 3)) {
+                ERR_clear_error();
+                i++;
+                goto loop;
+            }
+            goto end;
+        }
+        BIO_free(out);
+        out = NULL;
+        BIO_printf(bio_err, "-----\n");
+    }
+
+    if (!newreq) {
+        in = bio_open_default(infile, 'r', informat);
+        if (in == NULL)
+            goto end;
+
+        if (informat == FORMAT_ASN1)
+            req = d2i_X509_REQ_bio(in, NULL);
+        else
+            req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
+        if (req == NULL) {
+            BIO_printf(bio_err, "unable to load X509 request\n");
+            goto end;
+        }
+    }
+
+    if (newreq) {
+        if (pkey == NULL) {
+            BIO_printf(bio_err, "you need to specify a private key\n");
+            goto end;
+        }
+
+        if (req == NULL) {
+            req = X509_REQ_new();
+            if (req == NULL) {
+                goto end;
+            }
+
+            i = make_REQ(req, pkey, subj, multirdn, !x509, chtype);
+            subj = NULL;        /* done processing '-subj' option */
+            if (!i) {
+                BIO_printf(bio_err, "problems making Certificate Request\n");
+                goto end;
+            }
+        }
+        if (x509) {
+            EVP_PKEY *tmppkey;
+            X509V3_CTX ext_ctx;
+            if ((x509ss = X509_new()) == NULL)
+                goto end;
+
+            /* Set version to V3 */
+            if (extensions && !X509_set_version(x509ss, 2))
+                goto end;
+            if (serial) {
+                if (!X509_set_serialNumber(x509ss, serial))
+                    goto end;
+            } else {
+                if (!rand_serial(NULL, X509_get_serialNumber(x509ss)))
+                    goto end;
+            }
+
+            if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req)))
+                goto end;
+            if (!set_cert_times(x509ss, NULL, NULL, days))
+                goto end;
+            if (!X509_set_subject_name
+                (x509ss, X509_REQ_get_subject_name(req)))
+                goto end;
+            tmppkey = X509_REQ_get0_pubkey(req);
+            if (!tmppkey || !X509_set_pubkey(x509ss, tmppkey))
+                goto end;
+
+            /* Set up V3 context struct */
+
+            X509V3_set_ctx(&ext_ctx, x509ss, x509ss, NULL, NULL, 0);
+            X509V3_set_nconf(&ext_ctx, req_conf);
+
+            /* Add extensions */
+            if (extensions && !X509V3_EXT_add_nconf(req_conf,
+                                                    &ext_ctx, extensions,
+                                                    x509ss)) {
+                BIO_printf(bio_err, "Error Loading extension section %s\n",
+                           extensions);
+                goto end;
+            }
+
+            i = do_X509_sign(x509ss, pkey, digest, sigopts);
+            if (!i) {
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+        } else {
+            X509V3_CTX ext_ctx;
+
+            /* Set up V3 context struct */
+
+            X509V3_set_ctx(&ext_ctx, NULL, NULL, req, NULL, 0);
+            X509V3_set_nconf(&ext_ctx, req_conf);
+
+            /* Add extensions */
+            if (req_exts && !X509V3_EXT_REQ_add_nconf(req_conf,
+                                                      &ext_ctx, req_exts,
+                                                      req)) {
+                BIO_printf(bio_err, "Error Loading extension section %s\n",
+                           req_exts);
+                goto end;
+            }
+            i = do_X509_REQ_sign(req, pkey, digest, sigopts);
+            if (!i) {
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+        }
+    }
+
+    if (subj && x509) {
+        BIO_printf(bio_err, "Cannot modify certificate subject\n");
+        goto end;
+    }
+
+    if (subj && !x509) {
+        if (verbose) {
+            BIO_printf(bio_err, "Modifying Request's Subject\n");
+            print_name(bio_err, "old subject=",
+                       X509_REQ_get_subject_name(req), nmflag);
+        }
+
+        if (build_subject(req, subj, chtype, multirdn) == 0) {
+            BIO_printf(bio_err, "ERROR: cannot modify subject\n");
+            ret = 1;
+            goto end;
+        }
+
+        if (verbose) {
+            print_name(bio_err, "new subject=",
+                       X509_REQ_get_subject_name(req), nmflag);
+        }
+    }
+
+    if (verify && !x509) {
+        EVP_PKEY *tpubkey = pkey;
+
+        if (tpubkey == NULL) {
+            tpubkey = X509_REQ_get0_pubkey(req);
+            if (tpubkey == NULL)
+                goto end;
+        }
+
+        i = X509_REQ_verify(req, tpubkey);
+
+        if (i < 0) {
+            goto end;
+        } else if (i == 0) {
+            BIO_printf(bio_err, "verify failure\n");
+            ERR_print_errors(bio_err);
+        } else                  /* if (i > 0) */
+            BIO_printf(bio_err, "verify OK\n");
+    }
+
+    if (noout && !text && !modulus && !subject && !pubkey) {
+        ret = 0;
+        goto end;
+    }
+
+    out = bio_open_default(outfile,
+                           keyout != NULL && outfile != NULL &&
+                           strcmp(keyout, outfile) == 0 ? 'a' : 'w',
+                           outformat);
+    if (out == NULL)
+        goto end;
+
+    if (pubkey) {
+        EVP_PKEY *tpubkey = X509_REQ_get0_pubkey(req);
+
+        if (tpubkey == NULL) {
+            BIO_printf(bio_err, "Error getting public key\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        PEM_write_bio_PUBKEY(out, tpubkey);
+    }
+
+    if (text) {
+        if (x509)
+            X509_print_ex(out, x509ss, nmflag, reqflag);
+        else
+            X509_REQ_print_ex(out, req, nmflag, reqflag);
+    }
+
+    if (subject) {
+        if (x509)
+            print_name(out, "subject=", X509_get_subject_name(x509ss),
+                       nmflag);
+        else
+            print_name(out, "subject=", X509_REQ_get_subject_name(req),
+                       nmflag);
+    }
+
+    if (modulus) {
+        EVP_PKEY *tpubkey;
+
+        if (x509)
+            tpubkey = X509_get0_pubkey(x509ss);
+        else
+            tpubkey = X509_REQ_get0_pubkey(req);
+        if (tpubkey == NULL) {
+            fprintf(stdout, "Modulus=unavailable\n");
+            goto end;
+        }
+        fprintf(stdout, "Modulus=");
+#ifndef OPENSSL_NO_RSA
+        if (EVP_PKEY_base_id(tpubkey) == EVP_PKEY_RSA) {
+            const BIGNUM *n;
+            RSA_get0_key(EVP_PKEY_get0_RSA(tpubkey), &n, NULL, NULL);
+            BN_print(out, n);
+        } else
+#endif
+            fprintf(stdout, "Wrong Algorithm type");
+        fprintf(stdout, "\n");
+    }
+
+    if (!noout && !x509) {
+        if (outformat == FORMAT_ASN1)
+            i = i2d_X509_REQ_bio(out, req);
+        else if (newhdr)
+            i = PEM_write_bio_X509_REQ_NEW(out, req);
+        else
+            i = PEM_write_bio_X509_REQ(out, req);
+        if (!i) {
+            BIO_printf(bio_err, "unable to write X509 request\n");
+            goto end;
+        }
+    }
+    if (!noout && x509 && (x509ss != NULL)) {
+        if (outformat == FORMAT_ASN1)
+            i = i2d_X509_bio(out, x509ss);
+        else
+            i = PEM_write_bio_X509(out, x509ss);
+        if (!i) {
+            BIO_printf(bio_err, "unable to write X509 certificate\n");
+            goto end;
+        }
+    }
+    ret = 0;
+ end:
+    if (ret) {
+        ERR_print_errors(bio_err);
+    }
+    NCONF_free(req_conf);
+    BIO_free(in);
+    BIO_free_all(out);
+    EVP_PKEY_free(pkey);
+    EVP_PKEY_CTX_free(genctx);
+    sk_OPENSSL_STRING_free(pkeyopts);
+    sk_OPENSSL_STRING_free(sigopts);
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE_free(gen_eng);
+#endif
+    OPENSSL_free(keyalgstr);
+    X509_REQ_free(req);
+    X509_free(x509ss);
+    ASN1_INTEGER_free(serial);
+    release_engine(e);
+    if (passin != nofree_passin)
+        OPENSSL_free(passin);
+    if (passout != nofree_passout)
+        OPENSSL_free(passout);
+    return (ret);
+}
+
+static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn,
+                    int attribs, unsigned long chtype)
+{
+    int ret = 0, i;
+    char no_prompt = 0;
+    STACK_OF(CONF_VALUE) *dn_sk, *attr_sk = NULL;
+    char *tmp, *dn_sect, *attr_sect;
+
+    tmp = NCONF_get_string(req_conf, SECTION, PROMPT);
+    if (tmp == NULL)
+        ERR_clear_error();
+    if ((tmp != NULL) && strcmp(tmp, "no") == 0)
+        no_prompt = 1;
+
+    dn_sect = NCONF_get_string(req_conf, SECTION, DISTINGUISHED_NAME);
+    if (dn_sect == NULL) {
+        BIO_printf(bio_err, "unable to find '%s' in config\n",
+                   DISTINGUISHED_NAME);
+        goto err;
+    }
+    dn_sk = NCONF_get_section(req_conf, dn_sect);
+    if (dn_sk == NULL) {
+        BIO_printf(bio_err, "unable to get '%s' section\n", dn_sect);
+        goto err;
+    }
+
+    attr_sect = NCONF_get_string(req_conf, SECTION, ATTRIBUTES);
+    if (attr_sect == NULL) {
+        ERR_clear_error();
+        attr_sk = NULL;
+    } else {
+        attr_sk = NCONF_get_section(req_conf, attr_sect);
+        if (attr_sk == NULL) {
+            BIO_printf(bio_err, "unable to get '%s' section\n", attr_sect);
+            goto err;
+        }
+    }
+
+    /* setup version number */
+    if (!X509_REQ_set_version(req, 0L))
+        goto err;               /* version 1 */
+
+    if (subj)
+        i = build_subject(req, subj, chtype, multirdn);
+    else if (no_prompt)
+        i = auto_info(req, dn_sk, attr_sk, attribs, chtype);
+    else
+        i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs,
+                        chtype);
+    if (!i)
+        goto err;
+
+    if (!X509_REQ_set_pubkey(req, pkey))
+        goto err;
+
+    ret = 1;
+ err:
+    return (ret);
+}
+
+/*
+ * subject is expected to be in the format /type0=value0/type1=value1/type2=...
+ * where characters may be escaped by \
+ */
+static int build_subject(X509_REQ *req, const char *subject, unsigned long chtype,
+                         int multirdn)
+{
+    X509_NAME *n;
+
+    if ((n = parse_name(subject, chtype, multirdn)) == NULL)
+        return 0;
+
+    if (!X509_REQ_set_subject_name(req, n)) {
+        X509_NAME_free(n);
+        return 0;
+    }
+    X509_NAME_free(n);
+    return 1;
+}
+
+static int prompt_info(X509_REQ *req,
+                       STACK_OF(CONF_VALUE) *dn_sk, const char *dn_sect,
+                       STACK_OF(CONF_VALUE) *attr_sk, const char *attr_sect,
+                       int attribs, unsigned long chtype)
+{
+    int i;
+    char *p, *q;
+    char buf[100];
+    int nid, mval;
+    long n_min, n_max;
+    char *type, *value;
+    const char *def;
+    CONF_VALUE *v;
+    X509_NAME *subj;
+    subj = X509_REQ_get_subject_name(req);
+
+    if (!batch) {
+        BIO_printf(bio_err,
+                   "You are about to be asked to enter information that will be incorporated\n");
+        BIO_printf(bio_err, "into your certificate request.\n");
+        BIO_printf(bio_err,
+                   "What you are about to enter is what is called a Distinguished Name or a DN.\n");
+        BIO_printf(bio_err,
+                   "There are quite a few fields but you can leave some blank\n");
+        BIO_printf(bio_err,
+                   "For some fields there will be a default value,\n");
+        BIO_printf(bio_err,
+                   "If you enter '.', the field will be left blank.\n");
+        BIO_printf(bio_err, "-----\n");
+    }
+
+    if (sk_CONF_VALUE_num(dn_sk)) {
+        i = -1;
+ start:for (;;) {
+            i++;
+            if (sk_CONF_VALUE_num(dn_sk) <= i)
+                break;
+
+            v = sk_CONF_VALUE_value(dn_sk, i);
+            p = q = NULL;
+            type = v->name;
+            if (!check_end(type, "_min") || !check_end(type, "_max") ||
+                !check_end(type, "_default") || !check_end(type, "_value"))
+                continue;
+            /*
+             * Skip past any leading X. X: X, etc to allow for multiple
+             * instances
+             */
+            for (p = v->name; *p; p++)
+                if ((*p == ':') || (*p == ',') || (*p == '.')) {
+                    p++;
+                    if (*p)
+                        type = p;
+                    break;
+                }
+            if (*type == '+') {
+                mval = -1;
+                type++;
+            } else
+                mval = 0;
+            /* If OBJ not recognised ignore it */
+            if ((nid = OBJ_txt2nid(type)) == NID_undef)
+                goto start;
+            if (BIO_snprintf(buf, sizeof buf, "%s_default", v->name)
+                >= (int)sizeof(buf)) {
+                BIO_printf(bio_err, "Name '%s' too long\n", v->name);
+                return 0;
+            }
+
+            if ((def = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
+                ERR_clear_error();
+                def = "";
+            }
+
+            BIO_snprintf(buf, sizeof buf, "%s_value", v->name);
+            if ((value = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
+                ERR_clear_error();
+                value = NULL;
+            }
+
+            BIO_snprintf(buf, sizeof buf, "%s_min", v->name);
+            if (!NCONF_get_number(req_conf, dn_sect, buf, &n_min)) {
+                ERR_clear_error();
+                n_min = -1;
+            }
+
+            BIO_snprintf(buf, sizeof buf, "%s_max", v->name);
+            if (!NCONF_get_number(req_conf, dn_sect, buf, &n_max)) {
+                ERR_clear_error();
+                n_max = -1;
+            }
+
+            if (!add_DN_object(subj, v->value, def, value, nid,
+                               n_min, n_max, chtype, mval))
+                return 0;
+        }
+        if (X509_NAME_entry_count(subj) == 0) {
+            BIO_printf(bio_err,
+                       "error, no objects specified in config file\n");
+            return 0;
+        }
+
+        if (attribs) {
+            if ((attr_sk != NULL) && (sk_CONF_VALUE_num(attr_sk) > 0)
+                && (!batch)) {
+                BIO_printf(bio_err,
+                           "\nPlease enter the following 'extra' attributes\n");
+                BIO_printf(bio_err,
+                           "to be sent with your certificate request\n");
+            }
+
+            i = -1;
+ start2:   for (;;) {
+                i++;
+                if ((attr_sk == NULL) || (sk_CONF_VALUE_num(attr_sk) <= i))
+                    break;
+
+                v = sk_CONF_VALUE_value(attr_sk, i);
+                type = v->name;
+                if ((nid = OBJ_txt2nid(type)) == NID_undef)
+                    goto start2;
+
+                if (BIO_snprintf(buf, sizeof buf, "%s_default", type)
+                    >= (int)sizeof(buf)) {
+                    BIO_printf(bio_err, "Name '%s' too long\n", v->name);
+                    return 0;
+                }
+
+                if ((def = NCONF_get_string(req_conf, attr_sect, buf))
+                    == NULL) {
+                    ERR_clear_error();
+                    def = "";
+                }
+
+                BIO_snprintf(buf, sizeof buf, "%s_value", type);
+                if ((value = NCONF_get_string(req_conf, attr_sect, buf))
+                    == NULL) {
+                    ERR_clear_error();
+                    value = NULL;
+                }
+
+                BIO_snprintf(buf, sizeof buf, "%s_min", type);
+                if (!NCONF_get_number(req_conf, attr_sect, buf, &n_min)) {
+                    ERR_clear_error();
+                    n_min = -1;
+                }
+
+                BIO_snprintf(buf, sizeof buf, "%s_max", type);
+                if (!NCONF_get_number(req_conf, attr_sect, buf, &n_max)) {
+                    ERR_clear_error();
+                    n_max = -1;
+                }
+
+                if (!add_attribute_object(req,
+                                          v->value, def, value, nid, n_min,
+                                          n_max, chtype))
+                    return 0;
+            }
+        }
+    } else {
+        BIO_printf(bio_err, "No template, please set one up.\n");
+        return 0;
+    }
+
+    return 1;
+
+}
+
+static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk,
+                     STACK_OF(CONF_VALUE) *attr_sk, int attribs,
+                     unsigned long chtype)
+{
+    int i, spec_char, plus_char;
+    char *p, *q;
+    char *type;
+    CONF_VALUE *v;
+    X509_NAME *subj;
+
+    subj = X509_REQ_get_subject_name(req);
+
+    for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
+        int mval;
+        v = sk_CONF_VALUE_value(dn_sk, i);
+        p = q = NULL;
+        type = v->name;
+        /*
+         * Skip past any leading X. X: X, etc to allow for multiple instances
+         */
+        for (p = v->name; *p; p++) {
+#ifndef CHARSET_EBCDIC
+            spec_char = ((*p == ':') || (*p == ',') || (*p == '.'));
+#else
+            spec_char = ((*p == os_toascii[':']) || (*p == os_toascii[','])
+                    || (*p == os_toascii['.']));
+#endif
+            if (spec_char) {
+                p++;
+                if (*p)
+                    type = p;
+                break;
+            }
+        }
+#ifndef CHARSET_EBCDIC
+        plus_char = (*type == '+');
+#else
+        plus_char = (*type == os_toascii['+']);
+#endif
+        if (plus_char) {
+            type++;
+            mval = -1;
+        } else
+            mval = 0;
+        if (!X509_NAME_add_entry_by_txt(subj, type, chtype,
+                                        (unsigned char *)v->value, -1, -1,
+                                        mval))
+            return 0;
+
+    }
+
+    if (!X509_NAME_entry_count(subj)) {
+        BIO_printf(bio_err, "error, no objects specified in config file\n");
+        return 0;
+    }
+    if (attribs) {
+        for (i = 0; i < sk_CONF_VALUE_num(attr_sk); i++) {
+            v = sk_CONF_VALUE_value(attr_sk, i);
+            if (!X509_REQ_add1_attr_by_txt(req, v->name, chtype,
+                                           (unsigned char *)v->value, -1))
+                return 0;
+        }
+    }
+    return 1;
+}
+
+static int add_DN_object(X509_NAME *n, char *text, const char *def,
+                         char *value, int nid, int n_min, int n_max,
+                         unsigned long chtype, int mval)
+{
+    int i, ret = 0;
+    char buf[1024];
+ start:
+    if (!batch)
+        BIO_printf(bio_err, "%s [%s]:", text, def);
+    (void)BIO_flush(bio_err);
+    if (value != NULL) {
+        OPENSSL_strlcpy(buf, value, sizeof buf);
+        OPENSSL_strlcat(buf, "\n", sizeof buf);
+        BIO_printf(bio_err, "%s\n", value);
+    } else {
+        buf[0] = '\0';
+        if (!batch) {
+            if (!fgets(buf, sizeof buf, stdin))
+                return 0;
+        } else {
+            buf[0] = '\n';
+            buf[1] = '\0';
+        }
+    }
+
+    if (buf[0] == '\0')
+        return (0);
+    else if (buf[0] == '\n') {
+        if ((def == NULL) || (def[0] == '\0'))
+            return (1);
+        OPENSSL_strlcpy(buf, def, sizeof buf);
+        OPENSSL_strlcat(buf, "\n", sizeof buf);
+    } else if ((buf[0] == '.') && (buf[1] == '\n'))
+        return (1);
+
+    i = strlen(buf);
+    if (buf[i - 1] != '\n') {
+        BIO_printf(bio_err, "weird input :-(\n");
+        return (0);
+    }
+    buf[--i] = '\0';
+#ifdef CHARSET_EBCDIC
+    ebcdic2ascii(buf, buf, i);
+#endif
+    if (!req_check_len(i, n_min, n_max)) {
+        if (batch || value)
+            return 0;
+        goto start;
+    }
+
+    if (!X509_NAME_add_entry_by_NID(n, nid, chtype,
+                                    (unsigned char *)buf, -1, -1, mval))
+        goto err;
+    ret = 1;
+ err:
+    return (ret);
+}
+
+static int add_attribute_object(X509_REQ *req, char *text, const char *def,
+                                char *value, int nid, int n_min,
+                                int n_max, unsigned long chtype)
+{
+    int i;
+    static char buf[1024];
+
+ start:
+    if (!batch)
+        BIO_printf(bio_err, "%s [%s]:", text, def);
+    (void)BIO_flush(bio_err);
+    if (value != NULL) {
+        OPENSSL_strlcpy(buf, value, sizeof buf);
+        OPENSSL_strlcat(buf, "\n", sizeof buf);
+        BIO_printf(bio_err, "%s\n", value);
+    } else {
+        buf[0] = '\0';
+        if (!batch) {
+            if (!fgets(buf, sizeof buf, stdin))
+                return 0;
+        } else {
+            buf[0] = '\n';
+            buf[1] = '\0';
+        }
+    }
+
+    if (buf[0] == '\0')
+        return (0);
+    else if (buf[0] == '\n') {
+        if ((def == NULL) || (def[0] == '\0'))
+            return (1);
+        OPENSSL_strlcpy(buf, def, sizeof buf);
+        OPENSSL_strlcat(buf, "\n", sizeof buf);
+    } else if ((buf[0] == '.') && (buf[1] == '\n'))
+        return (1);
+
+    i = strlen(buf);
+    if (buf[i - 1] != '\n') {
+        BIO_printf(bio_err, "weird input :-(\n");
+        return (0);
+    }
+    buf[--i] = '\0';
+#ifdef CHARSET_EBCDIC
+    ebcdic2ascii(buf, buf, i);
+#endif
+    if (!req_check_len(i, n_min, n_max)) {
+        if (batch || value)
+            return 0;
+        goto start;
+    }
+
+    if (!X509_REQ_add1_attr_by_NID(req, nid, chtype,
+                                   (unsigned char *)buf, -1)) {
+        BIO_printf(bio_err, "Error adding attribute\n");
+        ERR_print_errors(bio_err);
+        goto err;
+    }
+
+    return (1);
+ err:
+    return (0);
+}
+
+static int req_check_len(int len, int n_min, int n_max)
+{
+    if ((n_min > 0) && (len < n_min)) {
+        BIO_printf(bio_err,
+                   "string is too short, it needs to be at least %d bytes long\n",
+                   n_min);
+        return (0);
+    }
+    if ((n_max >= 0) && (len > n_max)) {
+        BIO_printf(bio_err,
+                   "string is too long, it needs to be less than  %d bytes long\n",
+                   n_max);
+        return (0);
+    }
+    return (1);
+}
+
+/* Check if the end of a string matches 'end' */
+static int check_end(const char *str, const char *end)
+{
+    int elen, slen;
+    const char *tmp;
+    elen = strlen(end);
+    slen = strlen(str);
+    if (elen > slen)
+        return 1;
+    tmp = str + slen - elen;
+    return strcmp(tmp, end);
+}
+
+static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr,
+                                    int *pkey_type, long *pkeylen,
+                                    char **palgnam, ENGINE *keygen_engine)
+{
+    EVP_PKEY_CTX *gctx = NULL;
+    EVP_PKEY *param = NULL;
+    long keylen = -1;
+    BIO *pbio = NULL;
+    const char *paramfile = NULL;
+
+    if (gstr == NULL) {
+        *pkey_type = EVP_PKEY_RSA;
+        keylen = *pkeylen;
+    } else if (gstr[0] >= '0' && gstr[0] <= '9') {
+        *pkey_type = EVP_PKEY_RSA;
+        keylen = atol(gstr);
+        *pkeylen = keylen;
+    } else if (strncmp(gstr, "param:", 6) == 0)
+        paramfile = gstr + 6;
+    else {
+        const char *p = strchr(gstr, ':');
+        int len;
+        ENGINE *tmpeng;
+        const EVP_PKEY_ASN1_METHOD *ameth;
+
+        if (p)
+            len = p - gstr;
+        else
+            len = strlen(gstr);
+        /*
+         * The lookup of a the string will cover all engines so keep a note
+         * of the implementation.
+         */
+
+        ameth = EVP_PKEY_asn1_find_str(&tmpeng, gstr, len);
+
+        if (!ameth) {
+            BIO_printf(bio_err, "Unknown algorithm %.*s\n", len, gstr);
+            return NULL;
+        }
+
+        EVP_PKEY_asn1_get0_info(NULL, pkey_type, NULL, NULL, NULL, ameth);
+#ifndef OPENSSL_NO_ENGINE
+        ENGINE_finish(tmpeng);
+#endif
+        if (*pkey_type == EVP_PKEY_RSA) {
+            if (p) {
+                keylen = atol(p + 1);
+                *pkeylen = keylen;
+            } else
+                keylen = *pkeylen;
+        } else if (p)
+            paramfile = p + 1;
+    }
+
+    if (paramfile) {
+        pbio = BIO_new_file(paramfile, "r");
+        if (!pbio) {
+            BIO_printf(bio_err, "Can't open parameter file %s\n", paramfile);
+            return NULL;
+        }
+        param = PEM_read_bio_Parameters(pbio, NULL);
+
+        if (!param) {
+            X509 *x;
+            (void)BIO_reset(pbio);
+            x = PEM_read_bio_X509(pbio, NULL, NULL, NULL);
+            if (x) {
+                param = X509_get_pubkey(x);
+                X509_free(x);
+            }
+        }
+
+        BIO_free(pbio);
+
+        if (!param) {
+            BIO_printf(bio_err, "Error reading parameter file %s\n", paramfile);
+            return NULL;
+        }
+        if (*pkey_type == -1)
+            *pkey_type = EVP_PKEY_id(param);
+        else if (*pkey_type != EVP_PKEY_base_id(param)) {
+            BIO_printf(bio_err, "Key Type does not match parameters\n");
+            EVP_PKEY_free(param);
+            return NULL;
+        }
+    }
+
+    if (palgnam) {
+        const EVP_PKEY_ASN1_METHOD *ameth;
+        ENGINE *tmpeng;
+        const char *anam;
+        ameth = EVP_PKEY_asn1_find(&tmpeng, *pkey_type);
+        if (!ameth) {
+            BIO_puts(bio_err, "Internal error: can't find key algorithm\n");
+            return NULL;
+        }
+        EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth);
+        *palgnam = OPENSSL_strdup(anam);
+#ifndef OPENSSL_NO_ENGINE
+        ENGINE_finish(tmpeng);
+#endif
+    }
+
+    if (param) {
+        gctx = EVP_PKEY_CTX_new(param, keygen_engine);
+        *pkeylen = EVP_PKEY_bits(param);
+        EVP_PKEY_free(param);
+    } else
+        gctx = EVP_PKEY_CTX_new_id(*pkey_type, keygen_engine);
+
+    if (gctx == NULL) {
+        BIO_puts(bio_err, "Error allocating keygen context\n");
+        ERR_print_errors(bio_err);
+        return NULL;
+    }
+
+    if (EVP_PKEY_keygen_init(gctx) <= 0) {
+        BIO_puts(bio_err, "Error initializing keygen context\n");
+        ERR_print_errors(bio_err);
+        EVP_PKEY_CTX_free(gctx);
+        return NULL;
+    }
+#ifndef OPENSSL_NO_RSA
+    if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) {
+        if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0) {
+            BIO_puts(bio_err, "Error setting RSA keysize\n");
+            ERR_print_errors(bio_err);
+            EVP_PKEY_CTX_free(gctx);
+            return NULL;
+        }
+    }
+#endif
+
+    return gctx;
+}
+
+static int genpkey_cb(EVP_PKEY_CTX *ctx)
+{
+    char c = '*';
+    BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
+    int p;
+    p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
+    if (p == 0)
+        c = '.';
+    if (p == 1)
+        c = '+';
+    if (p == 2)
+        c = '*';
+    if (p == 3)
+        c = '\n';
+    BIO_write(b, &c, 1);
+    (void)BIO_flush(b);
+    return 1;
+}
+
+static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey,
+                        const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts)
+{
+    EVP_PKEY_CTX *pkctx = NULL;
+    int i;
+
+    if (ctx == NULL)
+        return 0;
+    if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey))
+        return 0;
+    for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
+        char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
+        if (pkey_ctrl_string(pkctx, sigopt) <= 0) {
+            BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt);
+            ERR_print_errors(bio_err);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
+                 STACK_OF(OPENSSL_STRING) *sigopts)
+{
+    int rv;
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+
+    rv = do_sign_init(mctx, pkey, md, sigopts);
+    if (rv > 0)
+        rv = X509_sign_ctx(x, mctx);
+    EVP_MD_CTX_free(mctx);
+    return rv > 0 ? 1 : 0;
+}
+
+int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
+                     STACK_OF(OPENSSL_STRING) *sigopts)
+{
+    int rv;
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+    rv = do_sign_init(mctx, pkey, md, sigopts);
+    if (rv > 0)
+        rv = X509_REQ_sign_ctx(x, mctx);
+    EVP_MD_CTX_free(mctx);
+    return rv > 0 ? 1 : 0;
+}
+
+int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
+                     STACK_OF(OPENSSL_STRING) *sigopts)
+{
+    int rv;
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+    rv = do_sign_init(mctx, pkey, md, sigopts);
+    if (rv > 0)
+        rv = X509_CRL_sign_ctx(x, mctx);
+    EVP_MD_CTX_free(mctx);
+    return rv > 0 ? 1 : 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/rsa.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/rsa.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/rsa.c	(revision 331)
@@ -0,0 +1,310 @@
+/*
+ * Copyright 1995-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 <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_RSA
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+# include <time.h>
+# include "apps.h"
+# include <openssl/bio.h>
+# include <openssl/err.h>
+# include <openssl/rsa.h>
+# include <openssl/evp.h>
+# include <openssl/x509.h>
+# include <openssl/pem.h>
+# include <openssl/bn.h>
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_IN, OPT_OUT,
+    OPT_PUBIN, OPT_PUBOUT, OPT_PASSOUT, OPT_PASSIN,
+    OPT_RSAPUBKEY_IN, OPT_RSAPUBKEY_OUT,
+    /* Do not change the order here; see case statements below */
+    OPT_PVK_NONE, OPT_PVK_WEAK, OPT_PVK_STRONG,
+    OPT_NOOUT, OPT_TEXT, OPT_MODULUS, OPT_CHECK, OPT_CIPHER
+} OPTION_CHOICE;
+
+OPTIONS rsa_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"inform", OPT_INFORM, 'f', "Input format, one of DER NET PEM"},
+    {"outform", OPT_OUTFORM, 'f', "Output format, one of DER NET PEM PVK"},
+    {"in", OPT_IN, 's', "Input file"},
+    {"out", OPT_OUT, '>', "Output file"},
+    {"pubin", OPT_PUBIN, '-', "Expect a public key in input file"},
+    {"pubout", OPT_PUBOUT, '-', "Output a public key"},
+    {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
+    {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
+    {"RSAPublicKey_in", OPT_RSAPUBKEY_IN, '-', "Input is an RSAPublicKey"},
+    {"RSAPublicKey_out", OPT_RSAPUBKEY_OUT, '-', "Output is an RSAPublicKey"},
+    {"noout", OPT_NOOUT, '-', "Don't print key out"},
+    {"text", OPT_TEXT, '-', "Print the key in text"},
+    {"modulus", OPT_MODULUS, '-', "Print the RSA key modulus"},
+    {"check", OPT_CHECK, '-', "Verify key consistency"},
+    {"", OPT_CIPHER, '-', "Any supported cipher"},
+# if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
+    {"pvk-strong", OPT_PVK_STRONG, '-', "Enable 'Strong' PVK encoding level (default)"},
+    {"pvk-weak", OPT_PVK_WEAK, '-', "Enable 'Weak' PVK encoding level"},
+    {"pvk-none", OPT_PVK_NONE, '-', "Don't enforce PVK encoding"},
+# endif
+# ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+# endif
+    {NULL}
+};
+
+int rsa_main(int argc, char **argv)
+{
+    ENGINE *e = NULL;
+    BIO *out = NULL;
+    RSA *rsa = NULL;
+    const EVP_CIPHER *enc = NULL;
+    char *infile = NULL, *outfile = NULL, *prog;
+    char *passin = NULL, *passout = NULL, *passinarg = NULL, *passoutarg = NULL;
+    int i, private = 0;
+    int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, check = 0;
+    int noout = 0, modulus = 0, pubin = 0, pubout = 0, ret = 1;
+# if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
+    int pvk_encr = 2;
+# endif
+    OPTION_CHOICE o;
+
+    prog = opt_init(argc, argv, rsa_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(rsa_options);
+            ret = 0;
+            goto end;
+        case OPT_INFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat))
+                goto opthelp;
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUTFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_ANY, &outformat))
+                goto opthelp;
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_PASSIN:
+            passinarg = opt_arg();
+            break;
+        case OPT_PASSOUT:
+            passoutarg = opt_arg();
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        case OPT_PUBIN:
+            pubin = 1;
+            break;
+        case OPT_PUBOUT:
+            pubout = 1;
+            break;
+        case OPT_RSAPUBKEY_IN:
+            pubin = 2;
+            break;
+        case OPT_RSAPUBKEY_OUT:
+            pubout = 2;
+            break;
+        case OPT_PVK_STRONG:    /* pvk_encr:= 2 */
+        case OPT_PVK_WEAK:      /* pvk_encr:= 1 */
+        case OPT_PVK_NONE:      /* pvk_encr:= 0 */
+# if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
+            pvk_encr = (o - OPT_PVK_NONE);
+# endif
+            break;
+        case OPT_NOOUT:
+            noout = 1;
+            break;
+        case OPT_TEXT:
+            text = 1;
+            break;
+        case OPT_MODULUS:
+            modulus = 1;
+            break;
+        case OPT_CHECK:
+            check = 1;
+            break;
+        case OPT_CIPHER:
+            if (!opt_cipher(opt_unknown(), &enc))
+                goto opthelp;
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    private = (text && !pubin) || (!pubout && !noout) ? 1 : 0;
+
+    if (!app_passwd(passinarg, passoutarg, &passin, &passout)) {
+        BIO_printf(bio_err, "Error getting passwords\n");
+        goto end;
+    }
+    if (check && pubin) {
+        BIO_printf(bio_err, "Only private keys can be checked\n");
+        goto end;
+    }
+
+    {
+        EVP_PKEY *pkey;
+
+        if (pubin) {
+            int tmpformat = -1;
+            if (pubin == 2) {
+                if (informat == FORMAT_PEM)
+                    tmpformat = FORMAT_PEMRSA;
+                else if (informat == FORMAT_ASN1)
+                    tmpformat = FORMAT_ASN1RSA;
+            } else
+                tmpformat = informat;
+
+            pkey = load_pubkey(infile, tmpformat, 1, passin, e, "Public Key");
+        } else
+            pkey = load_key(infile, informat, 1, passin, e, "Private Key");
+
+        if (pkey != NULL)
+            rsa = EVP_PKEY_get1_RSA(pkey);
+        EVP_PKEY_free(pkey);
+    }
+
+    if (rsa == NULL) {
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    out = bio_open_owner(outfile, outformat, private);
+    if (out == NULL)
+        goto end;
+
+    if (text) {
+        assert(pubin || private);
+        if (!RSA_print(out, rsa, 0)) {
+            perror(outfile);
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    if (modulus) {
+        const BIGNUM *n;
+        RSA_get0_key(rsa, &n, NULL, NULL);
+        BIO_printf(out, "Modulus=");
+        BN_print(out, n);
+        BIO_printf(out, "\n");
+    }
+
+    if (check) {
+        int r = RSA_check_key(rsa);
+
+        if (r == 1)
+            BIO_printf(out, "RSA key ok\n");
+        else if (r == 0) {
+            unsigned long err;
+
+            while ((err = ERR_peek_error()) != 0 &&
+                   ERR_GET_LIB(err) == ERR_LIB_RSA &&
+                   ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY &&
+                   ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE) {
+                BIO_printf(out, "RSA key error: %s\n",
+                           ERR_reason_error_string(err));
+                ERR_get_error(); /* remove e from error stack */
+            }
+        } else if (r == -1) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    if (noout) {
+        ret = 0;
+        goto end;
+    }
+    BIO_printf(bio_err, "writing RSA key\n");
+    if (outformat == FORMAT_ASN1) {
+        if (pubout || pubin) {
+            if (pubout == 2)
+                i = i2d_RSAPublicKey_bio(out, rsa);
+            else
+                i = i2d_RSA_PUBKEY_bio(out, rsa);
+        } else {
+            assert(private);
+            i = i2d_RSAPrivateKey_bio(out, rsa);
+        }
+    }
+    else if (outformat == FORMAT_PEM) {
+        if (pubout || pubin) {
+            if (pubout == 2)
+                i = PEM_write_bio_RSAPublicKey(out, rsa);
+            else
+                i = PEM_write_bio_RSA_PUBKEY(out, rsa);
+        } else {
+            assert(private);
+            i = PEM_write_bio_RSAPrivateKey(out, rsa,
+                                            enc, NULL, 0, NULL, passout);
+        }
+# ifndef OPENSSL_NO_DSA
+    } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) {
+        EVP_PKEY *pk;
+        pk = EVP_PKEY_new();
+        EVP_PKEY_set1_RSA(pk, rsa);
+        if (outformat == FORMAT_PVK) {
+            if (pubin) {
+                BIO_printf(bio_err, "PVK form impossible with public key input\n");
+                EVP_PKEY_free(pk);
+                goto end;
+            }
+            assert(private);
+#  ifdef OPENSSL_NO_RC4
+            BIO_printf(bio_err, "PVK format not supported\n");
+            EVP_PKEY_free(pk);
+            goto end;
+#  else
+            i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout);
+#  endif
+        } else if (pubin || pubout) {
+            i = i2b_PublicKey_bio(out, pk);
+        } else {
+            assert(private);
+            i = i2b_PrivateKey_bio(out, pk);
+        }
+        EVP_PKEY_free(pk);
+# endif
+    } else {
+        BIO_printf(bio_err, "bad output format specified for outfile\n");
+        goto end;
+    }
+    if (i <= 0) {
+        BIO_printf(bio_err, "unable to write key\n");
+        ERR_print_errors(bio_err);
+    } else
+        ret = 0;
+ end:
+    release_engine(e);
+    BIO_free_all(out);
+    RSA_free(rsa);
+    OPENSSL_free(passin);
+    OPENSSL_free(passout);
+    return (ret);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/rsautl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/rsautl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/rsautl.c	(revision 331)
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2000-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 <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_RSA
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include "apps.h"
+# include <string.h>
+# include <openssl/err.h>
+# include <openssl/pem.h>
+# include <openssl/rsa.h>
+
+# define RSA_SIGN        1
+# define RSA_VERIFY      2
+# define RSA_ENCRYPT     3
+# define RSA_DECRYPT     4
+
+# define KEY_PRIVKEY     1
+# define KEY_PUBKEY      2
+# define KEY_CERT        3
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_ENGINE, OPT_IN, OPT_OUT, OPT_ASN1PARSE, OPT_HEXDUMP,
+    OPT_RAW, OPT_OAEP, OPT_SSL, OPT_PKCS, OPT_X931,
+    OPT_SIGN, OPT_VERIFY, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT,
+    OPT_PUBIN, OPT_CERTIN, OPT_INKEY, OPT_PASSIN, OPT_KEYFORM
+} OPTION_CHOICE;
+
+OPTIONS rsautl_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"in", OPT_IN, '<', "Input file"},
+    {"out", OPT_OUT, '>', "Output file"},
+    {"inkey", OPT_INKEY, 's', "Input key"},
+    {"keyform", OPT_KEYFORM, 'E', "Private key format - default PEM"},
+    {"pubin", OPT_PUBIN, '-', "Input is an RSA public"},
+    {"certin", OPT_CERTIN, '-', "Input is a cert carrying an RSA public key"},
+    {"ssl", OPT_SSL, '-', "Use SSL v2 padding"},
+    {"raw", OPT_RAW, '-', "Use no padding"},
+    {"pkcs", OPT_PKCS, '-', "Use PKCS#1 v1.5 padding (default)"},
+    {"oaep", OPT_OAEP, '-', "Use PKCS#1 OAEP"},
+    {"sign", OPT_SIGN, '-', "Sign with private key"},
+    {"verify", OPT_VERIFY, '-', "Verify with public key"},
+    {"asn1parse", OPT_ASN1PARSE, '-',
+     "Run output through asn1parse; useful with -verify"},
+    {"hexdump", OPT_HEXDUMP, '-', "Hex dump output"},
+    {"x931", OPT_X931, '-', "Use ANSI X9.31 padding"},
+    {"rev", OPT_REV, '-', "Reverse the order of the input buffer"},
+    {"encrypt", OPT_ENCRYPT, '-', "Encrypt with public key"},
+    {"decrypt", OPT_DECRYPT, '-', "Decrypt with private key"},
+    {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
+# ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+# endif
+    {NULL}
+};
+
+int rsautl_main(int argc, char **argv)
+{
+    BIO *in = NULL, *out = NULL;
+    ENGINE *e = NULL;
+    EVP_PKEY *pkey = NULL;
+    RSA *rsa = NULL;
+    X509 *x;
+    char *infile = NULL, *outfile = NULL, *keyfile = NULL;
+    char *passinarg = NULL, *passin = NULL, *prog;
+    char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY;
+    unsigned char *rsa_in = NULL, *rsa_out = NULL, pad = RSA_PKCS1_PADDING;
+    int rsa_inlen, keyformat = FORMAT_PEM, keysize, ret = 1;
+    int rsa_outlen = 0, hexdump = 0, asn1parse = 0, need_priv = 0, rev = 0;
+    OPTION_CHOICE o;
+
+    prog = opt_init(argc, argv, rsautl_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(rsautl_options);
+            ret = 0;
+            goto end;
+        case OPT_KEYFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PDE, &keyformat))
+                goto opthelp;
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        case OPT_ASN1PARSE:
+            asn1parse = 1;
+            break;
+        case OPT_HEXDUMP:
+            hexdump = 1;
+            break;
+        case OPT_RAW:
+            pad = RSA_NO_PADDING;
+            break;
+        case OPT_OAEP:
+            pad = RSA_PKCS1_OAEP_PADDING;
+            break;
+        case OPT_SSL:
+            pad = RSA_SSLV23_PADDING;
+            break;
+        case OPT_PKCS:
+            pad = RSA_PKCS1_PADDING;
+            break;
+        case OPT_X931:
+            pad = RSA_X931_PADDING;
+            break;
+        case OPT_SIGN:
+            rsa_mode = RSA_SIGN;
+            need_priv = 1;
+            break;
+        case OPT_VERIFY:
+            rsa_mode = RSA_VERIFY;
+            break;
+        case OPT_REV:
+            rev = 1;
+            break;
+        case OPT_ENCRYPT:
+            rsa_mode = RSA_ENCRYPT;
+            break;
+        case OPT_DECRYPT:
+            rsa_mode = RSA_DECRYPT;
+            need_priv = 1;
+            break;
+        case OPT_PUBIN:
+            key_type = KEY_PUBKEY;
+            break;
+        case OPT_CERTIN:
+            key_type = KEY_CERT;
+            break;
+        case OPT_INKEY:
+            keyfile = opt_arg();
+            break;
+        case OPT_PASSIN:
+            passinarg = opt_arg();
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    if (need_priv && (key_type != KEY_PRIVKEY)) {
+        BIO_printf(bio_err, "A private key is needed for this operation\n");
+        goto end;
+    }
+
+    if (!app_passwd(passinarg, NULL, &passin, NULL)) {
+        BIO_printf(bio_err, "Error getting password\n");
+        goto end;
+    }
+
+/* FIXME: seed PRNG only if needed */
+    app_RAND_load_file(NULL, 0);
+
+    switch (key_type) {
+    case KEY_PRIVKEY:
+        pkey = load_key(keyfile, keyformat, 0, passin, e, "Private Key");
+        break;
+
+    case KEY_PUBKEY:
+        pkey = load_pubkey(keyfile, keyformat, 0, NULL, e, "Public Key");
+        break;
+
+    case KEY_CERT:
+        x = load_cert(keyfile, keyformat, "Certificate");
+        if (x) {
+            pkey = X509_get_pubkey(x);
+            X509_free(x);
+        }
+        break;
+    }
+
+    if (!pkey) {
+        return 1;
+    }
+
+    rsa = EVP_PKEY_get1_RSA(pkey);
+    EVP_PKEY_free(pkey);
+
+    if (!rsa) {
+        BIO_printf(bio_err, "Error getting RSA key\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    in = bio_open_default(infile, 'r', FORMAT_BINARY);
+    if (in == NULL)
+        goto end;
+    out = bio_open_default(outfile, 'w', FORMAT_BINARY);
+    if (out == NULL)
+        goto end;
+
+    keysize = RSA_size(rsa);
+
+    rsa_in = app_malloc(keysize * 2, "hold rsa key");
+    rsa_out = app_malloc(keysize, "output rsa key");
+
+    /* Read the input data */
+    rsa_inlen = BIO_read(in, rsa_in, keysize * 2);
+    if (rsa_inlen < 0) {
+        BIO_printf(bio_err, "Error reading input Data\n");
+        goto end;
+    }
+    if (rev) {
+        int i;
+        unsigned char ctmp;
+        for (i = 0; i < rsa_inlen / 2; i++) {
+            ctmp = rsa_in[i];
+            rsa_in[i] = rsa_in[rsa_inlen - 1 - i];
+            rsa_in[rsa_inlen - 1 - i] = ctmp;
+        }
+    }
+    switch (rsa_mode) {
+
+    case RSA_VERIFY:
+        rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
+        break;
+
+    case RSA_SIGN:
+        rsa_outlen =
+            RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
+        break;
+
+    case RSA_ENCRYPT:
+        rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
+        break;
+
+    case RSA_DECRYPT:
+        rsa_outlen =
+            RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
+        break;
+    }
+
+    if (rsa_outlen < 0) {
+        BIO_printf(bio_err, "RSA operation error\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+    ret = 0;
+    if (asn1parse) {
+        if (!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) {
+            ERR_print_errors(bio_err);
+        }
+    } else if (hexdump)
+        BIO_dump(out, (char *)rsa_out, rsa_outlen);
+    else
+        BIO_write(out, rsa_out, rsa_outlen);
+ end:
+    RSA_free(rsa);
+    release_engine(e);
+    BIO_free(in);
+    BIO_free_all(out);
+    OPENSSL_free(rsa_in);
+    OPENSSL_free(rsa_out);
+    OPENSSL_free(passin);
+    return ret;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/s_apps.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/s_apps.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/s_apps.h	(revision 331)
@@ -0,0 +1,102 @@
+/*
+ * Copyright 1995-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 <openssl/opensslconf.h>
+
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
+# include <conio.h>
+#endif
+
+#if defined(OPENSSL_SYS_MSDOS) && !defined(_WIN32)
+# define _kbhit kbhit
+#endif
+
+#if defined(OPENSSL_SYS_VMS) && !defined(FD_SET)
+/*
+ * VAX C does not defined fd_set and friends, but it's actually quite simple
+ */
+/* These definitions are borrowed from SOCKETSHR.       /Richard Levitte */
+# define MAX_NOFILE      32
+# define NBBY             8     /* number of bits in a byte */
+
+# ifndef FD_SETSIZE
+#  define FD_SETSIZE      MAX_NOFILE
+# endif                         /* FD_SETSIZE */
+
+/* How many things we'll allow select to use. 0 if unlimited */
+# define MAXSELFD        MAX_NOFILE
+typedef int fd_mask;            /* int here! VMS prototypes int, not long */
+# define NFDBITS (sizeof(fd_mask) * NBBY)/* bits per mask (power of 2!) */
+# define NFDSHIFT 5             /* Shift based on above */
+
+typedef fd_mask fd_set;
+# define FD_SET(n, p)    (*(p) |= (1 << ((n) % NFDBITS)))
+# define FD_CLR(n, p)    (*(p) &= ~(1 << ((n) % NFDBITS)))
+# define FD_ISSET(n, p)  (*(p) & (1 << ((n) % NFDBITS)))
+# define FD_ZERO(p)      memset((p), 0, sizeof(*(p)))
+#endif
+
+#define PORT            "4433"
+#define PROTOCOL        "tcp"
+
+typedef int (*do_server_cb)(int s, int stype, unsigned char *context);
+int do_server(int *accept_sock, const char *host, const char *port,
+              int family, int type,
+              do_server_cb cb,
+              unsigned char *context, int naccept);
+#ifdef HEADER_X509_H
+int verify_callback(int ok, X509_STORE_CTX *ctx);
+#endif
+#ifdef HEADER_SSL_H
+int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
+int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
+                       STACK_OF(X509) *chain, int build_chain);
+int ssl_print_sigalgs(BIO *out, SSL *s);
+int ssl_print_point_formats(BIO *out, SSL *s);
+int ssl_print_curves(BIO *out, SSL *s, int noshared);
+#endif
+int ssl_print_tmp_key(BIO *out, SSL *s);
+int init_client(int *sock, const char *host, const char *port,
+                int family, int type);
+int should_retry(int i);
+
+long bio_dump_callback(BIO *bio, int cmd, const char *argp,
+                       int argi, long argl, long ret);
+
+#ifdef HEADER_SSL_H
+void apps_ssl_info_callback(const SSL *s, int where, int ret);
+void msg_cb(int write_p, int version, int content_type, const void *buf,
+            size_t len, SSL *ssl, void *arg);
+void tlsext_cb(SSL *s, int client_server, int type, const unsigned char *data,
+               int len, void *arg);
+#endif
+
+int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
+                             unsigned int *cookie_len);
+int verify_cookie_callback(SSL *ssl, const unsigned char *cookie,
+                           unsigned int cookie_len);
+
+typedef struct ssl_excert_st SSL_EXCERT;
+
+void ssl_ctx_set_excert(SSL_CTX *ctx, SSL_EXCERT *exc);
+void ssl_excert_free(SSL_EXCERT *exc);
+int args_excert(int option, SSL_EXCERT **pexc);
+int load_excert(SSL_EXCERT **pexc);
+void print_verify_detail(SSL *s, BIO *bio);
+void print_ssl_summary(SSL *s);
+#ifdef HEADER_SSL_H
+int config_ctx(SSL_CONF_CTX *cctx, STACK_OF(OPENSSL_STRING) *str, SSL_CTX *ctx);
+int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls,
+                     int crl_download);
+int ssl_load_stores(SSL_CTX *ctx, const char *vfyCApath,
+                    const char *vfyCAfile, const char *chCApath,
+                    const char *chCAfile, STACK_OF(X509_CRL) *crls,
+                    int crl_download);
+void ssl_ctx_security_debug(SSL_CTX *ctx, int verbose);
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/s_cb.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/s_cb.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/s_cb.c	(revision 331)
@@ -0,0 +1,1335 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* callback functions used by s_client, s_server, and s_time */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* for memcpy() and strcmp() */
+#define USE_SOCKETS
+#include "apps.h"
+#undef USE_SOCKETS
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/ssl.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_DH
+# include <openssl/dh.h>
+#endif
+#include "s_apps.h"
+
+#define COOKIE_SECRET_LENGTH    16
+
+VERIFY_CB_ARGS verify_args = { 0, 0, X509_V_OK, 0 };
+
+#ifndef OPENSSL_NO_SOCK
+static unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
+static int cookie_initialized = 0;
+#endif
+
+static const char *lookup(int val, const STRINT_PAIR* list, const char* def)
+{
+    for ( ; list->name; ++list)
+        if (list->retval == val)
+            return list->name;
+    return def;
+}
+
+int verify_callback(int ok, X509_STORE_CTX *ctx)
+{
+    X509 *err_cert;
+    int err, depth;
+
+    err_cert = X509_STORE_CTX_get_current_cert(ctx);
+    err = X509_STORE_CTX_get_error(ctx);
+    depth = X509_STORE_CTX_get_error_depth(ctx);
+
+    if (!verify_args.quiet || !ok) {
+        BIO_printf(bio_err, "depth=%d ", depth);
+        if (err_cert) {
+            X509_NAME_print_ex(bio_err,
+                               X509_get_subject_name(err_cert),
+                               0, XN_FLAG_ONELINE);
+            BIO_puts(bio_err, "\n");
+        } else
+            BIO_puts(bio_err, "<no cert>\n");
+    }
+    if (!ok) {
+        BIO_printf(bio_err, "verify error:num=%d:%s\n", err,
+                   X509_verify_cert_error_string(err));
+        if (verify_args.depth >= depth) {
+            if (!verify_args.return_error)
+                ok = 1;
+            verify_args.error = err;
+        } else {
+            ok = 0;
+            verify_args.error = X509_V_ERR_CERT_CHAIN_TOO_LONG;
+        }
+    }
+    switch (err) {
+    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+        BIO_puts(bio_err, "issuer= ");
+        X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert),
+                           0, XN_FLAG_ONELINE);
+        BIO_puts(bio_err, "\n");
+        break;
+    case X509_V_ERR_CERT_NOT_YET_VALID:
+    case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+        BIO_printf(bio_err, "notBefore=");
+        ASN1_TIME_print(bio_err, X509_get0_notBefore(err_cert));
+        BIO_printf(bio_err, "\n");
+        break;
+    case X509_V_ERR_CERT_HAS_EXPIRED:
+    case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+        BIO_printf(bio_err, "notAfter=");
+        ASN1_TIME_print(bio_err, X509_get0_notAfter(err_cert));
+        BIO_printf(bio_err, "\n");
+        break;
+    case X509_V_ERR_NO_EXPLICIT_POLICY:
+        if (!verify_args.quiet)
+            policies_print(ctx);
+        break;
+    }
+    if (err == X509_V_OK && ok == 2 && !verify_args.quiet)
+        policies_print(ctx);
+    if (ok && !verify_args.quiet)
+        BIO_printf(bio_err, "verify return:%d\n", ok);
+    return (ok);
+}
+
+int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file)
+{
+    if (cert_file != NULL) {
+        if (SSL_CTX_use_certificate_file(ctx, cert_file,
+                                         SSL_FILETYPE_PEM) <= 0) {
+            BIO_printf(bio_err, "unable to get certificate from '%s'\n",
+                       cert_file);
+            ERR_print_errors(bio_err);
+            return (0);
+        }
+        if (key_file == NULL)
+            key_file = cert_file;
+        if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0) {
+            BIO_printf(bio_err, "unable to get private key from '%s'\n",
+                       key_file);
+            ERR_print_errors(bio_err);
+            return (0);
+        }
+
+        /*
+         * If we are using DSA, we can copy the parameters from the private
+         * key
+         */
+
+        /*
+         * Now we know that a key and cert have been set against the SSL
+         * context
+         */
+        if (!SSL_CTX_check_private_key(ctx)) {
+            BIO_printf(bio_err,
+                       "Private key does not match the certificate public key\n");
+            return (0);
+        }
+    }
+    return (1);
+}
+
+int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
+                       STACK_OF(X509) *chain, int build_chain)
+{
+    int chflags = chain ? SSL_BUILD_CHAIN_FLAG_CHECK : 0;
+    if (cert == NULL)
+        return 1;
+    if (SSL_CTX_use_certificate(ctx, cert) <= 0) {
+        BIO_printf(bio_err, "error setting certificate\n");
+        ERR_print_errors(bio_err);
+        return 0;
+    }
+
+    if (SSL_CTX_use_PrivateKey(ctx, key) <= 0) {
+        BIO_printf(bio_err, "error setting private key\n");
+        ERR_print_errors(bio_err);
+        return 0;
+    }
+
+    /*
+     * Now we know that a key and cert have been set against the SSL context
+     */
+    if (!SSL_CTX_check_private_key(ctx)) {
+        BIO_printf(bio_err,
+                   "Private key does not match the certificate public key\n");
+        return 0;
+    }
+    if (chain && !SSL_CTX_set1_chain(ctx, chain)) {
+        BIO_printf(bio_err, "error setting certificate chain\n");
+        ERR_print_errors(bio_err);
+        return 0;
+    }
+    if (build_chain && !SSL_CTX_build_cert_chain(ctx, chflags)) {
+        BIO_printf(bio_err, "error building certificate chain\n");
+        ERR_print_errors(bio_err);
+        return 0;
+    }
+    return 1;
+}
+
+static STRINT_PAIR cert_type_list[] = {
+    {"RSA sign", TLS_CT_RSA_SIGN},
+    {"DSA sign", TLS_CT_DSS_SIGN},
+    {"RSA fixed DH", TLS_CT_RSA_FIXED_DH},
+    {"DSS fixed DH", TLS_CT_DSS_FIXED_DH},
+    {"ECDSA sign", TLS_CT_ECDSA_SIGN},
+    {"RSA fixed ECDH", TLS_CT_RSA_FIXED_ECDH},
+    {"ECDSA fixed ECDH", TLS_CT_ECDSA_FIXED_ECDH},
+    {"GOST01 Sign", TLS_CT_GOST01_SIGN},
+    {NULL}
+};
+
+static void ssl_print_client_cert_types(BIO *bio, SSL *s)
+{
+    const unsigned char *p;
+    int i;
+    int cert_type_num = SSL_get0_certificate_types(s, &p);
+    if (!cert_type_num)
+        return;
+    BIO_puts(bio, "Client Certificate Types: ");
+    for (i = 0; i < cert_type_num; i++) {
+        unsigned char cert_type = p[i];
+        const char *cname = lookup((int)cert_type, cert_type_list, NULL);
+
+        if (i)
+            BIO_puts(bio, ", ");
+        if (cname)
+            BIO_puts(bio, cname);
+        else
+            BIO_printf(bio, "UNKNOWN (%d),", cert_type);
+    }
+    BIO_puts(bio, "\n");
+}
+
+static int do_print_sigalgs(BIO *out, SSL *s, int shared)
+{
+    int i, nsig, client;
+    client = SSL_is_server(s) ? 0 : 1;
+    if (shared)
+        nsig = SSL_get_shared_sigalgs(s, -1, NULL, NULL, NULL, NULL, NULL);
+    else
+        nsig = SSL_get_sigalgs(s, -1, NULL, NULL, NULL, NULL, NULL);
+    if (nsig == 0)
+        return 1;
+
+    if (shared)
+        BIO_puts(out, "Shared ");
+
+    if (client)
+        BIO_puts(out, "Requested ");
+    BIO_puts(out, "Signature Algorithms: ");
+    for (i = 0; i < nsig; i++) {
+        int hash_nid, sign_nid;
+        unsigned char rhash, rsign;
+        const char *sstr = NULL;
+        if (shared)
+            SSL_get_shared_sigalgs(s, i, &sign_nid, &hash_nid, NULL,
+                                   &rsign, &rhash);
+        else
+            SSL_get_sigalgs(s, i, &sign_nid, &hash_nid, NULL, &rsign, &rhash);
+        if (i)
+            BIO_puts(out, ":");
+        if (sign_nid == EVP_PKEY_RSA)
+            sstr = "RSA";
+        else if (sign_nid == EVP_PKEY_DSA)
+            sstr = "DSA";
+        else if (sign_nid == EVP_PKEY_EC)
+            sstr = "ECDSA";
+        if (sstr)
+            BIO_printf(out, "%s+", sstr);
+        else
+            BIO_printf(out, "0x%02X+", (int)rsign);
+        if (hash_nid != NID_undef)
+            BIO_printf(out, "%s", OBJ_nid2sn(hash_nid));
+        else
+            BIO_printf(out, "0x%02X", (int)rhash);
+    }
+    BIO_puts(out, "\n");
+    return 1;
+}
+
+int ssl_print_sigalgs(BIO *out, SSL *s)
+{
+    int mdnid;
+    if (!SSL_is_server(s))
+        ssl_print_client_cert_types(out, s);
+    do_print_sigalgs(out, s, 0);
+    do_print_sigalgs(out, s, 1);
+    if (SSL_get_peer_signature_nid(s, &mdnid))
+        BIO_printf(out, "Peer signing digest: %s\n", OBJ_nid2sn(mdnid));
+    return 1;
+}
+
+#ifndef OPENSSL_NO_EC
+int ssl_print_point_formats(BIO *out, SSL *s)
+{
+    int i, nformats;
+    const char *pformats;
+    nformats = SSL_get0_ec_point_formats(s, &pformats);
+    if (nformats <= 0)
+        return 1;
+    BIO_puts(out, "Supported Elliptic Curve Point Formats: ");
+    for (i = 0; i < nformats; i++, pformats++) {
+        if (i)
+            BIO_puts(out, ":");
+        switch (*pformats) {
+        case TLSEXT_ECPOINTFORMAT_uncompressed:
+            BIO_puts(out, "uncompressed");
+            break;
+
+        case TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime:
+            BIO_puts(out, "ansiX962_compressed_prime");
+            break;
+
+        case TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2:
+            BIO_puts(out, "ansiX962_compressed_char2");
+            break;
+
+        default:
+            BIO_printf(out, "unknown(%d)", (int)*pformats);
+            break;
+
+        }
+    }
+    BIO_puts(out, "\n");
+    return 1;
+}
+
+int ssl_print_curves(BIO *out, SSL *s, int noshared)
+{
+    int i, ncurves, *curves, nid;
+    const char *cname;
+
+    ncurves = SSL_get1_curves(s, NULL);
+    if (ncurves <= 0)
+        return 1;
+    curves = app_malloc(ncurves * sizeof(int), "curves to print");
+    SSL_get1_curves(s, curves);
+
+    BIO_puts(out, "Supported Elliptic Curves: ");
+    for (i = 0; i < ncurves; i++) {
+        if (i)
+            BIO_puts(out, ":");
+        nid = curves[i];
+        /* If unrecognised print out hex version */
+        if (nid & TLSEXT_nid_unknown)
+            BIO_printf(out, "0x%04X", nid & 0xFFFF);
+        else {
+            /* Use NIST name for curve if it exists */
+            cname = EC_curve_nid2nist(nid);
+            if (!cname)
+                cname = OBJ_nid2sn(nid);
+            BIO_printf(out, "%s", cname);
+        }
+    }
+    OPENSSL_free(curves);
+    if (noshared) {
+        BIO_puts(out, "\n");
+        return 1;
+    }
+    BIO_puts(out, "\nShared Elliptic curves: ");
+    ncurves = SSL_get_shared_curve(s, -1);
+    for (i = 0; i < ncurves; i++) {
+        if (i)
+            BIO_puts(out, ":");
+        nid = SSL_get_shared_curve(s, i);
+        cname = EC_curve_nid2nist(nid);
+        if (!cname)
+            cname = OBJ_nid2sn(nid);
+        BIO_printf(out, "%s", cname);
+    }
+    if (ncurves == 0)
+        BIO_puts(out, "NONE");
+    BIO_puts(out, "\n");
+    return 1;
+}
+#endif
+int ssl_print_tmp_key(BIO *out, SSL *s)
+{
+    EVP_PKEY *key;
+    if (!SSL_get_server_tmp_key(s, &key))
+        return 1;
+    BIO_puts(out, "Server Temp Key: ");
+    switch (EVP_PKEY_id(key)) {
+    case EVP_PKEY_RSA:
+        BIO_printf(out, "RSA, %d bits\n", EVP_PKEY_bits(key));
+        break;
+
+    case EVP_PKEY_DH:
+        BIO_printf(out, "DH, %d bits\n", EVP_PKEY_bits(key));
+        break;
+#ifndef OPENSSL_NO_EC
+    case EVP_PKEY_EC:
+        {
+            EC_KEY *ec = EVP_PKEY_get1_EC_KEY(key);
+            int nid;
+            const char *cname;
+            nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
+            EC_KEY_free(ec);
+            cname = EC_curve_nid2nist(nid);
+            if (!cname)
+                cname = OBJ_nid2sn(nid);
+            BIO_printf(out, "ECDH, %s, %d bits\n", cname, EVP_PKEY_bits(key));
+        }
+    break;
+#endif
+    default:
+        BIO_printf(out, "%s, %d bits\n", OBJ_nid2sn(EVP_PKEY_id(key)),
+                   EVP_PKEY_bits(key));
+    }
+    EVP_PKEY_free(key);
+    return 1;
+}
+
+long bio_dump_callback(BIO *bio, int cmd, const char *argp,
+                       int argi, long argl, long ret)
+{
+    BIO *out;
+
+    out = (BIO *)BIO_get_callback_arg(bio);
+    if (out == NULL)
+        return (ret);
+
+    if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) {
+        BIO_printf(out, "read from %p [%p] (%lu bytes => %ld (0x%lX))\n",
+                   (void *)bio, (void *)argp, (unsigned long)argi, ret, ret);
+        BIO_dump(out, argp, (int)ret);
+        return (ret);
+    } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) {
+        BIO_printf(out, "write to %p [%p] (%lu bytes => %ld (0x%lX))\n",
+                   (void *)bio, (void *)argp, (unsigned long)argi, ret, ret);
+        BIO_dump(out, argp, (int)ret);
+    }
+    return (ret);
+}
+
+void apps_ssl_info_callback(const SSL *s, int where, int ret)
+{
+    const char *str;
+    int w;
+
+    w = where & ~SSL_ST_MASK;
+
+    if (w & SSL_ST_CONNECT)
+        str = "SSL_connect";
+    else if (w & SSL_ST_ACCEPT)
+        str = "SSL_accept";
+    else
+        str = "undefined";
+
+    if (where & SSL_CB_LOOP) {
+        BIO_printf(bio_err, "%s:%s\n", str, SSL_state_string_long(s));
+    } else if (where & SSL_CB_ALERT) {
+        str = (where & SSL_CB_READ) ? "read" : "write";
+        BIO_printf(bio_err, "SSL3 alert %s:%s:%s\n",
+                   str,
+                   SSL_alert_type_string_long(ret),
+                   SSL_alert_desc_string_long(ret));
+    } else if (where & SSL_CB_EXIT) {
+        if (ret == 0)
+            BIO_printf(bio_err, "%s:failed in %s\n",
+                       str, SSL_state_string_long(s));
+        else if (ret < 0) {
+            BIO_printf(bio_err, "%s:error in %s\n",
+                       str, SSL_state_string_long(s));
+        }
+    }
+}
+
+static STRINT_PAIR ssl_versions[] = {
+    {"SSL 3.0", SSL3_VERSION},
+    {"TLS 1.0", TLS1_VERSION},
+    {"TLS 1.1", TLS1_1_VERSION},
+    {"TLS 1.2", TLS1_2_VERSION},
+    {"DTLS 1.0", DTLS1_VERSION},
+    {"DTLS 1.0 (bad)", DTLS1_BAD_VER},
+    {NULL}
+};
+static STRINT_PAIR alert_types[] = {
+    {" close_notify", 0},
+    {" unexpected_message", 10},
+    {" bad_record_mac", 20},
+    {" decryption_failed", 21},
+    {" record_overflow", 22},
+    {" decompression_failure", 30},
+    {" handshake_failure", 40},
+    {" bad_certificate", 42},
+    {" unsupported_certificate", 43},
+    {" certificate_revoked", 44},
+    {" certificate_expired", 45},
+    {" certificate_unknown", 46},
+    {" illegal_parameter", 47},
+    {" unknown_ca", 48},
+    {" access_denied", 49},
+    {" decode_error", 50},
+    {" decrypt_error", 51},
+    {" export_restriction", 60},
+    {" protocol_version", 70},
+    {" insufficient_security", 71},
+    {" internal_error", 80},
+    {" user_canceled", 90},
+    {" no_renegotiation", 100},
+    {" unsupported_extension", 110},
+    {" certificate_unobtainable", 111},
+    {" unrecognized_name", 112},
+    {" bad_certificate_status_response", 113},
+    {" bad_certificate_hash_value", 114},
+    {" unknown_psk_identity", 115},
+    {NULL}
+};
+
+static STRINT_PAIR handshakes[] = {
+    {", HelloRequest", 0},
+    {", ClientHello", 1},
+    {", ServerHello", 2},
+    {", HelloVerifyRequest", 3},
+    {", NewSessionTicket", 4},
+    {", Certificate", 11},
+    {", ServerKeyExchange", 12},
+    {", CertificateRequest", 13},
+    {", ServerHelloDone", 14},
+    {", CertificateVerify", 15},
+    {", ClientKeyExchange", 16},
+    {", Finished", 20},
+    {", CertificateUrl", 21},
+    {", CertificateStatus", 22},
+    {", SupplementalData", 23},
+    {NULL}
+};
+
+void msg_cb(int write_p, int version, int content_type, const void *buf,
+            size_t len, SSL *ssl, void *arg)
+{
+    BIO *bio = arg;
+    const char *str_write_p = write_p ? ">>>" : "<<<";
+    const char *str_version = lookup(version, ssl_versions, "???");
+    const char *str_content_type = "", *str_details1 = "", *str_details2 = "";
+    const unsigned char* bp = buf;
+
+    if (version == SSL3_VERSION ||
+        version == TLS1_VERSION ||
+        version == TLS1_1_VERSION ||
+        version == TLS1_2_VERSION ||
+        version == DTLS1_VERSION || version == DTLS1_BAD_VER) {
+        switch (content_type) {
+        case 20:
+            str_content_type = "ChangeCipherSpec";
+            break;
+        case 21:
+            str_content_type = "Alert";
+            str_details1 = ", ???";
+            if (len == 2) {
+                switch (bp[0]) {
+                case 1:
+                    str_details1 = ", warning";
+                    break;
+                case 2:
+                    str_details1 = ", fatal";
+                    break;
+                }
+                str_details2 = lookup((int)bp[1], alert_types, " ???");
+            }
+            break;
+        case 22:
+            str_content_type = "Handshake";
+            str_details1 = "???";
+            if (len > 0)
+                str_details1 = lookup((int)bp[0], handshakes, "???");
+            break;
+        case 23:
+            str_content_type = "ApplicationData";
+            break;
+#ifndef OPENSSL_NO_HEARTBEATS
+        case 24:
+            str_details1 = ", Heartbeat";
+
+            if (len > 0) {
+                switch (bp[0]) {
+                case 1:
+                    str_details1 = ", HeartbeatRequest";
+                    break;
+                case 2:
+                    str_details1 = ", HeartbeatResponse";
+                    break;
+                }
+            }
+            break;
+#endif
+        }
+    }
+
+    BIO_printf(bio, "%s %s%s [length %04lx]%s%s\n", str_write_p, str_version,
+               str_content_type, (unsigned long)len, str_details1,
+               str_details2);
+
+    if (len > 0) {
+        size_t num, i;
+
+        BIO_printf(bio, "   ");
+        num = len;
+        for (i = 0; i < num; i++) {
+            if (i % 16 == 0 && i > 0)
+                BIO_printf(bio, "\n   ");
+            BIO_printf(bio, " %02x", ((const unsigned char *)buf)[i]);
+        }
+        if (i < len)
+            BIO_printf(bio, " ...");
+        BIO_printf(bio, "\n");
+    }
+    (void)BIO_flush(bio);
+}
+
+static STRINT_PAIR tlsext_types[] = {
+    {"server name", TLSEXT_TYPE_server_name},
+    {"max fragment length", TLSEXT_TYPE_max_fragment_length},
+    {"client certificate URL", TLSEXT_TYPE_client_certificate_url},
+    {"trusted CA keys", TLSEXT_TYPE_trusted_ca_keys},
+    {"truncated HMAC", TLSEXT_TYPE_truncated_hmac},
+    {"status request", TLSEXT_TYPE_status_request},
+    {"user mapping", TLSEXT_TYPE_user_mapping},
+    {"client authz", TLSEXT_TYPE_client_authz},
+    {"server authz", TLSEXT_TYPE_server_authz},
+    {"cert type", TLSEXT_TYPE_cert_type},
+    {"elliptic curves", TLSEXT_TYPE_elliptic_curves},
+    {"EC point formats", TLSEXT_TYPE_ec_point_formats},
+    {"SRP", TLSEXT_TYPE_srp},
+    {"signature algorithms", TLSEXT_TYPE_signature_algorithms},
+    {"use SRTP", TLSEXT_TYPE_use_srtp},
+    {"heartbeat", TLSEXT_TYPE_heartbeat},
+    {"session ticket", TLSEXT_TYPE_session_ticket},
+    {"renegotiation info", TLSEXT_TYPE_renegotiate},
+    {"signed certificate timestamps", TLSEXT_TYPE_signed_certificate_timestamp},
+    {"TLS padding", TLSEXT_TYPE_padding},
+#ifdef TLSEXT_TYPE_next_proto_neg
+    {"next protocol", TLSEXT_TYPE_next_proto_neg},
+#endif
+#ifdef TLSEXT_TYPE_encrypt_then_mac
+    {"encrypt-then-mac", TLSEXT_TYPE_encrypt_then_mac},
+#endif
+#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
+    {"application layer protocol negotiation",
+     TLSEXT_TYPE_application_layer_protocol_negotiation},
+#endif
+#ifdef TLSEXT_TYPE_extended_master_secret
+    {"extended master secret", TLSEXT_TYPE_extended_master_secret},
+#endif
+    {NULL}
+};
+
+void tlsext_cb(SSL *s, int client_server, int type,
+               const unsigned char *data, int len, void *arg)
+{
+    BIO *bio = arg;
+    const char *extname = lookup(type, tlsext_types, "unknown");
+
+    BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n",
+               client_server ? "server" : "client", extname, type, len);
+    BIO_dump(bio, (const char *)data, len);
+    (void)BIO_flush(bio);
+}
+
+#ifndef OPENSSL_NO_SOCK
+int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
+                             unsigned int *cookie_len)
+{
+    unsigned char *buffer;
+    size_t length;
+    unsigned short port;
+    BIO_ADDR *peer = NULL;
+
+    /* Initialize a random secret */
+    if (!cookie_initialized) {
+        if (RAND_bytes(cookie_secret, COOKIE_SECRET_LENGTH) <= 0) {
+            BIO_printf(bio_err, "error setting random cookie secret\n");
+            return 0;
+        }
+        cookie_initialized = 1;
+    }
+
+    peer = BIO_ADDR_new();
+    if (peer == NULL) {
+        BIO_printf(bio_err, "memory full\n");
+        return 0;
+    }
+
+    /* Read peer information */
+    (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), peer);
+
+    /* Create buffer with peer's address and port */
+    BIO_ADDR_rawaddress(peer, NULL, &length);
+    OPENSSL_assert(length != 0);
+    port = BIO_ADDR_rawport(peer);
+    length += sizeof(port);
+    buffer = app_malloc(length, "cookie generate buffer");
+
+    memcpy(buffer, &port, sizeof(port));
+    BIO_ADDR_rawaddress(peer, buffer + sizeof(port), NULL);
+
+    /* Calculate HMAC of buffer using the secret */
+    HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
+         buffer, length, cookie, cookie_len);
+
+    OPENSSL_free(buffer);
+    BIO_ADDR_free(peer);
+
+    return 1;
+}
+
+int verify_cookie_callback(SSL *ssl, const unsigned char *cookie,
+                           unsigned int cookie_len)
+{
+    unsigned char result[EVP_MAX_MD_SIZE];
+    unsigned int resultlength;
+
+    /* Note: we check cookie_initialized because if it's not,
+     * it cannot be valid */
+    if (cookie_initialized
+        && generate_cookie_callback(ssl, result, &resultlength)
+        && cookie_len == resultlength
+        && memcmp(result, cookie, resultlength) == 0)
+        return 1;
+
+    return 0;
+}
+#endif
+
+/*
+ * Example of extended certificate handling. Where the standard support of
+ * one certificate per algorithm is not sufficient an application can decide
+ * which certificate(s) to use at runtime based on whatever criteria it deems
+ * appropriate.
+ */
+
+/* Linked list of certificates, keys and chains */
+struct ssl_excert_st {
+    int certform;
+    const char *certfile;
+    int keyform;
+    const char *keyfile;
+    const char *chainfile;
+    X509 *cert;
+    EVP_PKEY *key;
+    STACK_OF(X509) *chain;
+    int build_chain;
+    struct ssl_excert_st *next, *prev;
+};
+
+static STRINT_PAIR chain_flags[] = {
+    {"Overall Validity", CERT_PKEY_VALID},
+    {"Sign with EE key", CERT_PKEY_SIGN},
+    {"EE signature", CERT_PKEY_EE_SIGNATURE},
+    {"CA signature", CERT_PKEY_CA_SIGNATURE},
+    {"EE key parameters", CERT_PKEY_EE_PARAM},
+    {"CA key parameters", CERT_PKEY_CA_PARAM},
+    {"Explicitly sign with EE key", CERT_PKEY_EXPLICIT_SIGN},
+    {"Issuer Name", CERT_PKEY_ISSUER_NAME},
+    {"Certificate Type", CERT_PKEY_CERT_TYPE},
+    {NULL}
+};
+
+static void print_chain_flags(SSL *s, int flags)
+{
+    STRINT_PAIR *pp;
+
+    for (pp = chain_flags; pp->name; ++pp)
+        BIO_printf(bio_err, "\t%s: %s\n",
+                   pp->name,
+                   (flags & pp->retval) ? "OK" : "NOT OK");
+    BIO_printf(bio_err, "\tSuite B: ");
+    if (SSL_set_cert_flags(s, 0) & SSL_CERT_FLAG_SUITEB_128_LOS)
+        BIO_puts(bio_err, flags & CERT_PKEY_SUITEB ? "OK\n" : "NOT OK\n");
+    else
+        BIO_printf(bio_err, "not tested\n");
+}
+
+/*
+ * Very basic selection callback: just use any certificate chain reported as
+ * valid. More sophisticated could prioritise according to local policy.
+ */
+static int set_cert_cb(SSL *ssl, void *arg)
+{
+    int i, rv;
+    SSL_EXCERT *exc = arg;
+#ifdef CERT_CB_TEST_RETRY
+    static int retry_cnt;
+    if (retry_cnt < 5) {
+        retry_cnt++;
+        BIO_printf(bio_err,
+                   "Certificate callback retry test: count %d\n",
+                   retry_cnt);
+        return -1;
+    }
+#endif
+    SSL_certs_clear(ssl);
+
+    if (!exc)
+        return 1;
+
+    /*
+     * Go to end of list and traverse backwards since we prepend newer
+     * entries this retains the original order.
+     */
+    while (exc->next)
+        exc = exc->next;
+
+    i = 0;
+
+    while (exc) {
+        i++;
+        rv = SSL_check_chain(ssl, exc->cert, exc->key, exc->chain);
+        BIO_printf(bio_err, "Checking cert chain %d:\nSubject: ", i);
+        X509_NAME_print_ex(bio_err, X509_get_subject_name(exc->cert), 0,
+                           XN_FLAG_ONELINE);
+        BIO_puts(bio_err, "\n");
+        print_chain_flags(ssl, rv);
+        if (rv & CERT_PKEY_VALID) {
+            if (!SSL_use_certificate(ssl, exc->cert)
+                    || !SSL_use_PrivateKey(ssl, exc->key)) {
+                return 0;
+            }
+            /*
+             * NB: we wouldn't normally do this as it is not efficient
+             * building chains on each connection better to cache the chain
+             * in advance.
+             */
+            if (exc->build_chain) {
+                if (!SSL_build_cert_chain(ssl, 0))
+                    return 0;
+            } else if (exc->chain)
+                SSL_set1_chain(ssl, exc->chain);
+        }
+        exc = exc->prev;
+    }
+    return 1;
+}
+
+void ssl_ctx_set_excert(SSL_CTX *ctx, SSL_EXCERT *exc)
+{
+    SSL_CTX_set_cert_cb(ctx, set_cert_cb, exc);
+}
+
+static int ssl_excert_prepend(SSL_EXCERT **pexc)
+{
+    SSL_EXCERT *exc = app_malloc(sizeof(*exc), "prepend cert");
+
+    memset(exc, 0, sizeof(*exc));
+
+    exc->next = *pexc;
+    *pexc = exc;
+
+    if (exc->next) {
+        exc->certform = exc->next->certform;
+        exc->keyform = exc->next->keyform;
+        exc->next->prev = exc;
+    } else {
+        exc->certform = FORMAT_PEM;
+        exc->keyform = FORMAT_PEM;
+    }
+    return 1;
+
+}
+
+void ssl_excert_free(SSL_EXCERT *exc)
+{
+    SSL_EXCERT *curr;
+
+    if (!exc)
+        return;
+    while (exc) {
+        X509_free(exc->cert);
+        EVP_PKEY_free(exc->key);
+        sk_X509_pop_free(exc->chain, X509_free);
+        curr = exc;
+        exc = exc->next;
+        OPENSSL_free(curr);
+    }
+}
+
+int load_excert(SSL_EXCERT **pexc)
+{
+    SSL_EXCERT *exc = *pexc;
+    if (!exc)
+        return 1;
+    /* If nothing in list, free and set to NULL */
+    if (!exc->certfile && !exc->next) {
+        ssl_excert_free(exc);
+        *pexc = NULL;
+        return 1;
+    }
+    for (; exc; exc = exc->next) {
+        if (!exc->certfile) {
+            BIO_printf(bio_err, "Missing filename\n");
+            return 0;
+        }
+        exc->cert = load_cert(exc->certfile, exc->certform,
+                              "Server Certificate");
+        if (!exc->cert)
+            return 0;
+        if (exc->keyfile) {
+            exc->key = load_key(exc->keyfile, exc->keyform,
+                                0, NULL, NULL, "Server Key");
+        } else {
+            exc->key = load_key(exc->certfile, exc->certform,
+                                0, NULL, NULL, "Server Key");
+        }
+        if (!exc->key)
+            return 0;
+        if (exc->chainfile) {
+            if (!load_certs(exc->chainfile, &exc->chain, FORMAT_PEM, NULL,
+                            "Server Chain"))
+                return 0;
+        }
+    }
+    return 1;
+}
+
+enum range { OPT_X_ENUM };
+
+int args_excert(int opt, SSL_EXCERT **pexc)
+{
+    SSL_EXCERT *exc = *pexc;
+
+    assert(opt > OPT_X__FIRST);
+    assert(opt < OPT_X__LAST);
+
+    if (exc == NULL) {
+        if (!ssl_excert_prepend(&exc)) {
+            BIO_printf(bio_err, " %s: Error initialising xcert\n",
+                       opt_getprog());
+            goto err;
+        }
+        *pexc = exc;
+    }
+
+    switch ((enum range)opt) {
+    case OPT_X__FIRST:
+    case OPT_X__LAST:
+        return 0;
+    case OPT_X_CERT:
+        if (exc->certfile && !ssl_excert_prepend(&exc)) {
+            BIO_printf(bio_err, "%s: Error adding xcert\n", opt_getprog());
+            goto err;
+        }
+        *pexc = exc;
+        exc->certfile = opt_arg();
+        break;
+    case OPT_X_KEY:
+        if (exc->keyfile) {
+            BIO_printf(bio_err, "%s: Key already specified\n", opt_getprog());
+            goto err;
+        }
+        exc->keyfile = opt_arg();
+        break;
+    case OPT_X_CHAIN:
+        if (exc->chainfile) {
+            BIO_printf(bio_err, "%s: Chain already specified\n",
+                       opt_getprog());
+            goto err;
+        }
+        exc->chainfile = opt_arg();
+        break;
+    case OPT_X_CHAIN_BUILD:
+        exc->build_chain = 1;
+        break;
+    case OPT_X_CERTFORM:
+        if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &exc->certform))
+            return 0;
+        break;
+    case OPT_X_KEYFORM:
+        if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &exc->keyform))
+            return 0;
+        break;
+    }
+    return 1;
+
+ err:
+    ERR_print_errors(bio_err);
+    ssl_excert_free(exc);
+    *pexc = NULL;
+    return 0;
+}
+
+static void print_raw_cipherlist(SSL *s)
+{
+    const unsigned char *rlist;
+    static const unsigned char scsv_id[] = { 0, 0xFF };
+    size_t i, rlistlen, num;
+    if (!SSL_is_server(s))
+        return;
+    num = SSL_get0_raw_cipherlist(s, NULL);
+    OPENSSL_assert(num == 2);
+    rlistlen = SSL_get0_raw_cipherlist(s, &rlist);
+    BIO_puts(bio_err, "Client cipher list: ");
+    for (i = 0; i < rlistlen; i += num, rlist += num) {
+        const SSL_CIPHER *c = SSL_CIPHER_find(s, rlist);
+        if (i)
+            BIO_puts(bio_err, ":");
+        if (c)
+            BIO_puts(bio_err, SSL_CIPHER_get_name(c));
+        else if (!memcmp(rlist, scsv_id, num))
+            BIO_puts(bio_err, "SCSV");
+        else {
+            size_t j;
+            BIO_puts(bio_err, "0x");
+            for (j = 0; j < num; j++)
+                BIO_printf(bio_err, "%02X", rlist[j]);
+        }
+    }
+    BIO_puts(bio_err, "\n");
+}
+
+/*
+ * Hex encoder for TLSA RRdata, not ':' delimited.
+ */
+static char *hexencode(const unsigned char *data, size_t len)
+{
+    static const char *hex = "0123456789abcdef";
+    char *out;
+    char *cp;
+    size_t outlen = 2 * len + 1;
+    int ilen = (int) outlen;
+
+    if (outlen < len || ilen < 0 || outlen != (size_t)ilen) {
+        BIO_printf(bio_err, "%s: %" PRIu64 "-byte buffer too large to hexencode\n",
+                   opt_getprog(), (uint64_t)len);
+        exit(1);
+    }
+    cp = out = app_malloc(ilen, "TLSA hex data buffer");
+
+    while (len-- > 0) {
+        *cp++ = hex[(*data >> 4) & 0x0f];
+        *cp++ = hex[*data++ & 0x0f];
+    }
+    *cp = '\0';
+    return out;
+}
+
+void print_verify_detail(SSL *s, BIO *bio)
+{
+    int mdpth;
+    EVP_PKEY *mspki;
+    long verify_err = SSL_get_verify_result(s);
+
+    if (verify_err == X509_V_OK) {
+        const char *peername = SSL_get0_peername(s);
+
+        BIO_printf(bio, "Verification: OK\n");
+        if (peername != NULL)
+            BIO_printf(bio, "Verified peername: %s\n", peername);
+    } else {
+        const char *reason = X509_verify_cert_error_string(verify_err);
+
+        BIO_printf(bio, "Verification error: %s\n", reason);
+    }
+
+    if ((mdpth = SSL_get0_dane_authority(s, NULL, &mspki)) >= 0) {
+        uint8_t usage, selector, mtype;
+        const unsigned char *data = NULL;
+        size_t dlen = 0;
+        char *hexdata;
+
+        mdpth = SSL_get0_dane_tlsa(s, &usage, &selector, &mtype, &data, &dlen);
+
+        /*
+         * The TLSA data field can be quite long when it is a certificate,
+         * public key or even a SHA2-512 digest.  Because the initial octets of
+         * ASN.1 certificates and public keys contain mostly boilerplate OIDs
+         * and lengths, we show the last 12 bytes of the data instead, as these
+         * are more likely to distinguish distinct TLSA records.
+         */
+#define TLSA_TAIL_SIZE 12
+        if (dlen > TLSA_TAIL_SIZE)
+            hexdata = hexencode(data + dlen - TLSA_TAIL_SIZE, TLSA_TAIL_SIZE);
+        else
+            hexdata = hexencode(data, dlen);
+        BIO_printf(bio, "DANE TLSA %d %d %d %s%s %s at depth %d\n",
+                   usage, selector, mtype,
+                   (dlen > TLSA_TAIL_SIZE) ? "..." : "", hexdata,
+                   (mspki != NULL) ? "signed the certificate" :
+                   mdpth ? "matched TA certificate" : "matched EE certificate",
+                   mdpth);
+        OPENSSL_free(hexdata);
+    }
+}
+
+void print_ssl_summary(SSL *s)
+{
+    const SSL_CIPHER *c;
+    X509 *peer;
+    /* const char *pnam = SSL_is_server(s) ? "client" : "server"; */
+
+    BIO_printf(bio_err, "Protocol version: %s\n", SSL_get_version(s));
+    print_raw_cipherlist(s);
+    c = SSL_get_current_cipher(s);
+    BIO_printf(bio_err, "Ciphersuite: %s\n", SSL_CIPHER_get_name(c));
+    do_print_sigalgs(bio_err, s, 0);
+    peer = SSL_get_peer_certificate(s);
+    if (peer) {
+        int nid;
+
+        BIO_puts(bio_err, "Peer certificate: ");
+        X509_NAME_print_ex(bio_err, X509_get_subject_name(peer),
+                           0, XN_FLAG_ONELINE);
+        BIO_puts(bio_err, "\n");
+        if (SSL_get_peer_signature_nid(s, &nid))
+            BIO_printf(bio_err, "Hash used: %s\n", OBJ_nid2sn(nid));
+        print_verify_detail(s, bio_err);
+    } else
+        BIO_puts(bio_err, "No peer certificate\n");
+    X509_free(peer);
+#ifndef OPENSSL_NO_EC
+    ssl_print_point_formats(bio_err, s);
+    if (SSL_is_server(s))
+        ssl_print_curves(bio_err, s, 1);
+    else
+        ssl_print_tmp_key(bio_err, s);
+#else
+    if (!SSL_is_server(s))
+        ssl_print_tmp_key(bio_err, s);
+#endif
+}
+
+int config_ctx(SSL_CONF_CTX *cctx, STACK_OF(OPENSSL_STRING) *str,
+               SSL_CTX *ctx)
+{
+    int i;
+
+    SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);
+    for (i = 0; i < sk_OPENSSL_STRING_num(str); i += 2) {
+        const char *flag = sk_OPENSSL_STRING_value(str, i);
+        const char *arg = sk_OPENSSL_STRING_value(str, i + 1);
+        if (SSL_CONF_cmd(cctx, flag, arg) <= 0) {
+            if (arg)
+                BIO_printf(bio_err, "Error with command: \"%s %s\"\n",
+                           flag, arg);
+            else
+                BIO_printf(bio_err, "Error with command: \"%s\"\n", flag);
+            ERR_print_errors(bio_err);
+            return 0;
+        }
+    }
+    if (!SSL_CONF_CTX_finish(cctx)) {
+        BIO_puts(bio_err, "Error finishing context\n");
+        ERR_print_errors(bio_err);
+        return 0;
+    }
+    return 1;
+}
+
+static int add_crls_store(X509_STORE *st, STACK_OF(X509_CRL) *crls)
+{
+    X509_CRL *crl;
+    int i;
+    for (i = 0; i < sk_X509_CRL_num(crls); i++) {
+        crl = sk_X509_CRL_value(crls, i);
+        X509_STORE_add_crl(st, crl);
+    }
+    return 1;
+}
+
+int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls, int crl_download)
+{
+    X509_STORE *st;
+    st = SSL_CTX_get_cert_store(ctx);
+    add_crls_store(st, crls);
+    if (crl_download)
+        store_setup_crl_download(st);
+    return 1;
+}
+
+int ssl_load_stores(SSL_CTX *ctx,
+                    const char *vfyCApath, const char *vfyCAfile,
+                    const char *chCApath, const char *chCAfile,
+                    STACK_OF(X509_CRL) *crls, int crl_download)
+{
+    X509_STORE *vfy = NULL, *ch = NULL;
+    int rv = 0;
+    if (vfyCApath != NULL || vfyCAfile != NULL) {
+        vfy = X509_STORE_new();
+        if (vfy == NULL)
+            goto err;
+        if (!X509_STORE_load_locations(vfy, vfyCAfile, vfyCApath))
+            goto err;
+        add_crls_store(vfy, crls);
+        SSL_CTX_set1_verify_cert_store(ctx, vfy);
+        if (crl_download)
+            store_setup_crl_download(vfy);
+    }
+    if (chCApath != NULL || chCAfile != NULL) {
+        ch = X509_STORE_new();
+        if (ch == NULL)
+            goto err;
+        if (!X509_STORE_load_locations(ch, chCAfile, chCApath))
+            goto err;
+        SSL_CTX_set1_chain_cert_store(ctx, ch);
+    }
+    rv = 1;
+ err:
+    X509_STORE_free(vfy);
+    X509_STORE_free(ch);
+    return rv;
+}
+
+/* Verbose print out of security callback */
+
+typedef struct {
+    BIO *out;
+    int verbose;
+    int (*old_cb) (const SSL *s, const SSL_CTX *ctx, int op, int bits, int nid,
+                   void *other, void *ex);
+} security_debug_ex;
+
+static STRINT_PAIR callback_types[] = {
+    {"Supported Ciphersuite", SSL_SECOP_CIPHER_SUPPORTED},
+    {"Shared Ciphersuite", SSL_SECOP_CIPHER_SHARED},
+    {"Check Ciphersuite", SSL_SECOP_CIPHER_CHECK},
+#ifndef OPENSSL_NO_DH
+    {"Temp DH key bits", SSL_SECOP_TMP_DH},
+#endif
+    {"Supported Curve", SSL_SECOP_CURVE_SUPPORTED},
+    {"Shared Curve", SSL_SECOP_CURVE_SHARED},
+    {"Check Curve", SSL_SECOP_CURVE_CHECK},
+    {"Supported Signature Algorithm digest", SSL_SECOP_SIGALG_SUPPORTED},
+    {"Shared Signature Algorithm digest", SSL_SECOP_SIGALG_SHARED},
+    {"Check Signature Algorithm digest", SSL_SECOP_SIGALG_CHECK},
+    {"Signature Algorithm mask", SSL_SECOP_SIGALG_MASK},
+    {"Certificate chain EE key", SSL_SECOP_EE_KEY},
+    {"Certificate chain CA key", SSL_SECOP_CA_KEY},
+    {"Peer Chain EE key", SSL_SECOP_PEER_EE_KEY},
+    {"Peer Chain CA key", SSL_SECOP_PEER_CA_KEY},
+    {"Certificate chain CA digest", SSL_SECOP_CA_MD},
+    {"Peer chain CA digest", SSL_SECOP_PEER_CA_MD},
+    {"SSL compression", SSL_SECOP_COMPRESSION},
+    {"Session ticket", SSL_SECOP_TICKET},
+    {NULL}
+};
+
+static int security_callback_debug(const SSL *s, const SSL_CTX *ctx,
+                                   int op, int bits, int nid,
+                                   void *other, void *ex)
+{
+    security_debug_ex *sdb = ex;
+    int rv, show_bits = 1, cert_md = 0;
+    const char *nm;
+    rv = sdb->old_cb(s, ctx, op, bits, nid, other, ex);
+    if (rv == 1 && sdb->verbose < 2)
+        return 1;
+    BIO_puts(sdb->out, "Security callback: ");
+
+    nm = lookup(op, callback_types, NULL);
+    switch (op) {
+    case SSL_SECOP_TICKET:
+    case SSL_SECOP_COMPRESSION:
+        show_bits = 0;
+        nm = NULL;
+        break;
+    case SSL_SECOP_VERSION:
+        BIO_printf(sdb->out, "Version=%s", lookup(nid, ssl_versions, "???"));
+        show_bits = 0;
+        nm = NULL;
+        break;
+    case SSL_SECOP_CA_MD:
+    case SSL_SECOP_PEER_CA_MD:
+        cert_md = 1;
+        break;
+    }
+    if (nm)
+        BIO_printf(sdb->out, "%s=", nm);
+
+    switch (op & SSL_SECOP_OTHER_TYPE) {
+
+    case SSL_SECOP_OTHER_CIPHER:
+        BIO_puts(sdb->out, SSL_CIPHER_get_name(other));
+        break;
+
+#ifndef OPENSSL_NO_EC
+    case SSL_SECOP_OTHER_CURVE:
+        {
+            const char *cname;
+            cname = EC_curve_nid2nist(nid);
+            if (cname == NULL)
+                cname = OBJ_nid2sn(nid);
+            BIO_puts(sdb->out, cname);
+        }
+        break;
+#endif
+#ifndef OPENSSL_NO_DH
+    case SSL_SECOP_OTHER_DH:
+        {
+            DH *dh = other;
+            BIO_printf(sdb->out, "%d", DH_bits(dh));
+            break;
+        }
+#endif
+    case SSL_SECOP_OTHER_CERT:
+        {
+            if (cert_md) {
+                int sig_nid = X509_get_signature_nid(other);
+                BIO_puts(sdb->out, OBJ_nid2sn(sig_nid));
+            } else {
+                EVP_PKEY *pkey = X509_get0_pubkey(other);
+                const char *algname = "";
+                EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL,
+                                        &algname, EVP_PKEY_get0_asn1(pkey));
+                BIO_printf(sdb->out, "%s, bits=%d",
+                           algname, EVP_PKEY_bits(pkey));
+            }
+            break;
+        }
+    case SSL_SECOP_OTHER_SIGALG:
+        {
+            const unsigned char *salg = other;
+            const char *sname = NULL;
+            switch (salg[1]) {
+            case TLSEXT_signature_anonymous:
+                sname = "anonymous";
+                break;
+            case TLSEXT_signature_rsa:
+                sname = "RSA";
+                break;
+            case TLSEXT_signature_dsa:
+                sname = "DSA";
+                break;
+            case TLSEXT_signature_ecdsa:
+                sname = "ECDSA";
+                break;
+            }
+
+            BIO_puts(sdb->out, OBJ_nid2sn(nid));
+            if (sname)
+                BIO_printf(sdb->out, ", algorithm=%s", sname);
+            else
+                BIO_printf(sdb->out, ", algid=%d", salg[1]);
+            break;
+        }
+
+    }
+
+    if (show_bits)
+        BIO_printf(sdb->out, ", security bits=%d", bits);
+    BIO_printf(sdb->out, ": %s\n", rv ? "yes" : "no");
+    return rv;
+}
+
+void ssl_ctx_security_debug(SSL_CTX *ctx, int verbose)
+{
+    static security_debug_ex sdb;
+
+    sdb.out = bio_err;
+    sdb.verbose = verbose;
+    sdb.old_cb = SSL_CTX_get_security_callback(ctx);
+    SSL_CTX_set_security_callback(ctx, security_callback_debug);
+    SSL_CTX_set0_security_ex_data(ctx, &sdb);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/s_client.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/s_client.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/s_client.c	(revision 331)
@@ -0,0 +1,2747 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <openssl/e_os2.h>
+
+#ifndef OPENSSL_NO_SOCK
+
+/*
+ * With IPv6, it looks like Digital has mixed up the proper order of
+ * recursive header file inclusion, resulting in the compiler complaining
+ * that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which is
+ * needed to have fileno() declared correctly...  So let's define u_int
+ */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
+# define __U_INT
+typedef unsigned int u_int;
+#endif
+
+#define USE_SOCKETS
+#include "apps.h"
+#include <openssl/x509.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+#include <openssl/ocsp.h>
+#include <openssl/bn.h>
+#include <openssl/async.h>
+#ifndef OPENSSL_NO_SRP
+# include <openssl/srp.h>
+#endif
+#ifndef OPENSSL_NO_CT
+# include <openssl/ct.h>
+#endif
+#include "s_apps.h"
+#include "timeouts.h"
+
+#if defined(__has_feature)
+# if __has_feature(memory_sanitizer)
+#  include <sanitizer/msan_interface.h>
+# endif
+#endif
+
+#undef BUFSIZZ
+#define BUFSIZZ 1024*8
+#define S_CLIENT_IRC_READ_TIMEOUT 8
+
+static char *prog;
+static int c_debug = 0;
+static int c_showcerts = 0;
+static char *keymatexportlabel = NULL;
+static int keymatexportlen = 20;
+static BIO *bio_c_out = NULL;
+static int c_quiet = 0;
+
+static void print_stuff(BIO *berr, SSL *con, int full);
+#ifndef OPENSSL_NO_OCSP
+static int ocsp_resp_cb(SSL *s, void *arg);
+#endif
+
+static int saved_errno;
+
+static void save_errno(void)
+{
+    saved_errno = errno;
+    errno = 0;
+}
+
+static int restore_errno(void)
+{
+    int ret = errno;
+    errno = saved_errno;
+    return ret;
+}
+
+static void do_ssl_shutdown(SSL *ssl)
+{
+    int ret;
+
+    do {
+        /* We only do unidirectional shutdown */
+        ret = SSL_shutdown(ssl);
+        if (ret < 0) {
+            switch (SSL_get_error(ssl, ret)) {
+            case SSL_ERROR_WANT_READ:
+            case SSL_ERROR_WANT_WRITE:
+            case SSL_ERROR_WANT_ASYNC:
+            case SSL_ERROR_WANT_ASYNC_JOB:
+                /* We just do busy waiting. Nothing clever */
+                continue;
+            }
+            ret = 0;
+        }
+    } while (ret < 0);
+}
+
+#ifndef OPENSSL_NO_PSK
+/* Default PSK identity and key */
+static char *psk_identity = "Client_identity";
+/*
+ * char *psk_key=NULL; by default PSK is not used
+ */
+
+static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity,
+                                  unsigned int max_identity_len,
+                                  unsigned char *psk,
+                                  unsigned int max_psk_len)
+{
+    int ret;
+    long key_len;
+    unsigned char *key;
+
+    if (c_debug)
+        BIO_printf(bio_c_out, "psk_client_cb\n");
+    if (!hint) {
+        /* no ServerKeyExchange message */
+        if (c_debug)
+            BIO_printf(bio_c_out,
+                       "NULL received PSK identity hint, continuing anyway\n");
+    } else if (c_debug)
+        BIO_printf(bio_c_out, "Received PSK identity hint '%s'\n", hint);
+
+    /*
+     * lookup PSK identity and PSK key based on the given identity hint here
+     */
+    ret = BIO_snprintf(identity, max_identity_len, "%s", psk_identity);
+    if (ret < 0 || (unsigned int)ret > max_identity_len)
+        goto out_err;
+    if (c_debug)
+        BIO_printf(bio_c_out, "created identity '%s' len=%d\n", identity,
+                   ret);
+
+    /* convert the PSK key to binary */
+    key = OPENSSL_hexstr2buf(psk_key, &key_len);
+    if (key == NULL) {
+        BIO_printf(bio_err, "Could not convert PSK key '%s' to buffer\n",
+                   psk_key);
+        return 0;
+    }
+    if (key_len > max_psk_len) {
+        BIO_printf(bio_err,
+                   "psk buffer of callback is too small (%d) for key (%ld)\n",
+                   max_psk_len, key_len);
+        OPENSSL_free(key);
+        return 0;
+    }
+
+    memcpy(psk, key, key_len);
+    OPENSSL_free(key);
+
+    if (c_debug)
+        BIO_printf(bio_c_out, "created PSK len=%ld\n", key_len);
+
+    return key_len;
+ out_err:
+    if (c_debug)
+        BIO_printf(bio_err, "Error in PSK client callback\n");
+    return 0;
+}
+#endif
+
+/* This is a context that we pass to callbacks */
+typedef struct tlsextctx_st {
+    BIO *biodebug;
+    int ack;
+} tlsextctx;
+
+static int ssl_servername_cb(SSL *s, int *ad, void *arg)
+{
+    tlsextctx *p = (tlsextctx *) arg;
+    const char *hn = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
+    if (SSL_get_servername_type(s) != -1)
+        p->ack = !SSL_session_reused(s) && hn != NULL;
+    else
+        BIO_printf(bio_err, "Can't use SSL_get_servername\n");
+
+    return SSL_TLSEXT_ERR_OK;
+}
+
+#ifndef OPENSSL_NO_SRP
+
+/* This is a context that we pass to all callbacks */
+typedef struct srp_arg_st {
+    char *srppassin;
+    char *srplogin;
+    int msg;                    /* copy from c_msg */
+    int debug;                  /* copy from c_debug */
+    int amp;                    /* allow more groups */
+    int strength;               /* minimal size for N */
+} SRP_ARG;
+
+# define SRP_NUMBER_ITERATIONS_FOR_PRIME 64
+
+static int srp_Verify_N_and_g(const BIGNUM *N, const BIGNUM *g)
+{
+    BN_CTX *bn_ctx = BN_CTX_new();
+    BIGNUM *p = BN_new();
+    BIGNUM *r = BN_new();
+    int ret =
+        g != NULL && N != NULL && bn_ctx != NULL && BN_is_odd(N) &&
+        BN_is_prime_ex(N, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) == 1 &&
+        p != NULL && BN_rshift1(p, N) &&
+        /* p = (N-1)/2 */
+        BN_is_prime_ex(p, SRP_NUMBER_ITERATIONS_FOR_PRIME, bn_ctx, NULL) == 1 &&
+        r != NULL &&
+        /* verify g^((N-1)/2) == -1 (mod N) */
+        BN_mod_exp(r, g, p, N, bn_ctx) &&
+        BN_add_word(r, 1) && BN_cmp(r, N) == 0;
+
+    BN_free(r);
+    BN_free(p);
+    BN_CTX_free(bn_ctx);
+    return ret;
+}
+
+/*-
+ * This callback is used here for two purposes:
+ * - extended debugging
+ * - making some primality tests for unknown groups
+ * The callback is only called for a non default group.
+ *
+ * An application does not need the call back at all if
+ * only the standard groups are used.  In real life situations,
+ * client and server already share well known groups,
+ * thus there is no need to verify them.
+ * Furthermore, in case that a server actually proposes a group that
+ * is not one of those defined in RFC 5054, it is more appropriate
+ * to add the group to a static list and then compare since
+ * primality tests are rather cpu consuming.
+ */
+
+static int ssl_srp_verify_param_cb(SSL *s, void *arg)
+{
+    SRP_ARG *srp_arg = (SRP_ARG *)arg;
+    BIGNUM *N = NULL, *g = NULL;
+
+    if (((N = SSL_get_srp_N(s)) == NULL) || ((g = SSL_get_srp_g(s)) == NULL))
+        return 0;
+    if (srp_arg->debug || srp_arg->msg || srp_arg->amp == 1) {
+        BIO_printf(bio_err, "SRP parameters:\n");
+        BIO_printf(bio_err, "\tN=");
+        BN_print(bio_err, N);
+        BIO_printf(bio_err, "\n\tg=");
+        BN_print(bio_err, g);
+        BIO_printf(bio_err, "\n");
+    }
+
+    if (SRP_check_known_gN_param(g, N))
+        return 1;
+
+    if (srp_arg->amp == 1) {
+        if (srp_arg->debug)
+            BIO_printf(bio_err,
+                       "SRP param N and g are not known params, going to check deeper.\n");
+
+        /*
+         * The srp_moregroups is a real debugging feature. Implementors
+         * should rather add the value to the known ones. The minimal size
+         * has already been tested.
+         */
+        if (BN_num_bits(g) <= BN_BITS && srp_Verify_N_and_g(N, g))
+            return 1;
+    }
+    BIO_printf(bio_err, "SRP param N and g rejected.\n");
+    return 0;
+}
+
+# define PWD_STRLEN 1024
+
+static char *ssl_give_srp_client_pwd_cb(SSL *s, void *arg)
+{
+    SRP_ARG *srp_arg = (SRP_ARG *)arg;
+    char *pass = app_malloc(PWD_STRLEN + 1, "SRP password buffer");
+    PW_CB_DATA cb_tmp;
+    int l;
+
+    cb_tmp.password = (char *)srp_arg->srppassin;
+    cb_tmp.prompt_info = "SRP user";
+    if ((l = password_callback(pass, PWD_STRLEN, 0, &cb_tmp)) < 0) {
+        BIO_printf(bio_err, "Can't read Password\n");
+        OPENSSL_free(pass);
+        return NULL;
+    }
+    *(pass + l) = '\0';
+
+    return pass;
+}
+
+#endif
+
+static char *srtp_profiles = NULL;
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+/* This the context that we pass to next_proto_cb */
+typedef struct tlsextnextprotoctx_st {
+    unsigned char *data;
+    size_t len;
+    int status;
+} tlsextnextprotoctx;
+
+static tlsextnextprotoctx next_proto;
+
+static int next_proto_cb(SSL *s, unsigned char **out, unsigned char *outlen,
+                         const unsigned char *in, unsigned int inlen,
+                         void *arg)
+{
+    tlsextnextprotoctx *ctx = arg;
+
+    if (!c_quiet) {
+        /* We can assume that |in| is syntactically valid. */
+        unsigned i;
+        BIO_printf(bio_c_out, "Protocols advertised by server: ");
+        for (i = 0; i < inlen;) {
+            if (i)
+                BIO_write(bio_c_out, ", ", 2);
+            BIO_write(bio_c_out, &in[i + 1], in[i]);
+            i += in[i] + 1;
+        }
+        BIO_write(bio_c_out, "\n", 1);
+    }
+
+    ctx->status =
+        SSL_select_next_proto(out, outlen, in, inlen, ctx->data, ctx->len);
+    return SSL_TLSEXT_ERR_OK;
+}
+#endif                         /* ndef OPENSSL_NO_NEXTPROTONEG */
+
+static int serverinfo_cli_parse_cb(SSL *s, unsigned int ext_type,
+                                   const unsigned char *in, size_t inlen,
+                                   int *al, void *arg)
+{
+    char pem_name[100];
+    unsigned char ext_buf[4 + 65536];
+
+    /* Reconstruct the type/len fields prior to extension data */
+    ext_buf[0] = ext_type >> 8;
+    ext_buf[1] = ext_type & 0xFF;
+    ext_buf[2] = inlen >> 8;
+    ext_buf[3] = inlen & 0xFF;
+    memcpy(ext_buf + 4, in, inlen);
+
+    BIO_snprintf(pem_name, sizeof(pem_name), "SERVERINFO FOR EXTENSION %d",
+                 ext_type);
+    PEM_write_bio(bio_c_out, pem_name, "", ext_buf, 4 + inlen);
+    return 1;
+}
+
+/*
+ * Hex decoder that tolerates optional whitespace.  Returns number of bytes
+ * produced, advances inptr to end of input string.
+ */
+static ossl_ssize_t hexdecode(const char **inptr, void *result)
+{
+    unsigned char **out = (unsigned char **)result;
+    const char *in = *inptr;
+    unsigned char *ret = app_malloc(strlen(in) / 2, "hexdecode");
+    unsigned char *cp = ret;
+    uint8_t byte;
+    int nibble = 0;
+
+    if (ret == NULL)
+        return -1;
+
+    for (byte = 0; *in; ++in) {
+        int x;
+
+        if (isspace(_UC(*in)))
+            continue;
+        x = OPENSSL_hexchar2int(*in);
+        if (x < 0) {
+            OPENSSL_free(ret);
+            return 0;
+        }
+        byte |= (char)x;
+        if ((nibble ^= 1) == 0) {
+            *cp++ = byte;
+            byte = 0;
+        } else {
+            byte <<= 4;
+        }
+    }
+    if (nibble != 0) {
+        OPENSSL_free(ret);
+        return 0;
+    }
+    *inptr = in;
+
+    return cp - (*out = ret);
+}
+
+/*
+ * Decode unsigned 0..255, returns 1 on success, <= 0 on failure. Advances
+ * inptr to next field skipping leading whitespace.
+ */
+static ossl_ssize_t checked_uint8(const char **inptr, void *out)
+{
+    uint8_t *result = (uint8_t *)out;
+    const char *in = *inptr;
+    char *endp;
+    long v;
+    int e;
+
+    save_errno();
+    v = strtol(in, &endp, 10);
+    e = restore_errno();
+
+    if (((v == LONG_MIN || v == LONG_MAX) && e == ERANGE) ||
+        endp == in || !isspace(_UC(*endp)) ||
+        v != (*result = (uint8_t) v)) {
+        return -1;
+    }
+    for (in = endp; isspace(_UC(*in)); ++in)
+        continue;
+
+    *inptr = in;
+    return 1;
+}
+
+struct tlsa_field {
+    void *var;
+    const char *name;
+    ossl_ssize_t (*parser)(const char **, void *);
+};
+
+static int tlsa_import_rr(SSL *con, const char *rrdata)
+{
+    /* Not necessary to re-init these values; the "parsers" do that. */
+    static uint8_t usage;
+    static uint8_t selector;
+    static uint8_t mtype;
+    static unsigned char *data;
+    static struct tlsa_field tlsa_fields[] = {
+        { &usage, "usage", checked_uint8 },
+        { &selector, "selector", checked_uint8 },
+        { &mtype, "mtype", checked_uint8 },
+        { &data, "data", hexdecode },
+        { NULL, }
+    };
+    struct tlsa_field *f;
+    int ret;
+    const char *cp = rrdata;
+    ossl_ssize_t len = 0;
+
+    for (f = tlsa_fields; f->var; ++f) {
+        /* Returns number of bytes produced, advances cp to next field */
+        if ((len = f->parser(&cp, f->var)) <= 0) {
+            BIO_printf(bio_err, "%s: warning: bad TLSA %s field in: %s\n",
+                       prog, f->name, rrdata);
+            return 0;
+        }
+    }
+    /* The data field is last, so len is its length */
+    ret = SSL_dane_tlsa_add(con, usage, selector, mtype, data, len);
+    OPENSSL_free(data);
+
+    if (ret == 0) {
+        ERR_print_errors(bio_err);
+        BIO_printf(bio_err, "%s: warning: unusable TLSA rrdata: %s\n",
+                   prog, rrdata);
+        return 0;
+    }
+    if (ret < 0) {
+        ERR_print_errors(bio_err);
+        BIO_printf(bio_err, "%s: warning: error loading TLSA rrdata: %s\n",
+                   prog, rrdata);
+        return 0;
+    }
+    return ret;
+}
+
+static int tlsa_import_rrset(SSL *con, STACK_OF(OPENSSL_STRING) *rrset)
+{
+    int num = sk_OPENSSL_STRING_num(rrset);
+    int count = 0;
+    int i;
+
+    for (i = 0; i < num; ++i) {
+        char *rrdata = sk_OPENSSL_STRING_value(rrset, i);
+        if (tlsa_import_rr(con, rrdata) > 0)
+            ++count;
+    }
+    return count > 0;
+}
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_4, OPT_6, OPT_HOST, OPT_PORT, OPT_CONNECT, OPT_UNIX,
+    OPT_XMPPHOST, OPT_VERIFY,
+    OPT_CERT, OPT_CRL, OPT_CRL_DOWNLOAD, OPT_SESS_OUT, OPT_SESS_IN,
+    OPT_CERTFORM, OPT_CRLFORM, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET,
+    OPT_BRIEF, OPT_PREXIT, OPT_CRLF, OPT_QUIET, OPT_NBIO,
+    OPT_SSL_CLIENT_ENGINE, OPT_RAND, OPT_IGN_EOF, OPT_NO_IGN_EOF,
+    OPT_DEBUG, OPT_TLSEXTDEBUG, OPT_STATUS, OPT_WDEBUG,
+    OPT_MSG, OPT_MSGFILE, OPT_ENGINE, OPT_TRACE, OPT_SECURITY_DEBUG,
+    OPT_SECURITY_DEBUG_VERBOSE, OPT_SHOWCERTS, OPT_NBIO_TEST, OPT_STATE,
+#ifndef OPENSSL_NO_PSK
+    OPT_PSK_IDENTITY, OPT_PSK,
+#endif
+#ifndef OPENSSL_NO_SRP
+    OPT_SRPUSER, OPT_SRPPASS, OPT_SRP_STRENGTH, OPT_SRP_LATEUSER,
+    OPT_SRP_MOREGROUPS,
+#endif
+    OPT_SSL3, OPT_SSL_CONFIG,
+    OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
+    OPT_DTLS1_2, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM, OPT_PASS,
+    OPT_CERT_CHAIN, OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH,
+        OPT_VERIFYCAPATH,
+    OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN, OPT_CAFILE, OPT_NOCAFILE,
+    OPT_CHAINCAFILE, OPT_VERIFYCAFILE, OPT_NEXTPROTONEG, OPT_ALPN,
+    OPT_SERVERINFO, OPT_STARTTLS, OPT_SERVERNAME,
+    OPT_USE_SRTP, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, OPT_SMTPHOST,
+    OPT_ASYNC, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF,
+    OPT_V_ENUM,
+    OPT_X_ENUM,
+    OPT_S_ENUM,
+    OPT_FALLBACKSCSV, OPT_NOCMDS, OPT_PROXY, OPT_DANE_TLSA_DOMAIN,
+#ifndef OPENSSL_NO_CT
+    OPT_CT, OPT_NOCT, OPT_CTLOG_FILE,
+#endif
+    OPT_DANE_TLSA_RRDATA, OPT_DANE_EE_NO_NAME
+} OPTION_CHOICE;
+
+OPTIONS s_client_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"host", OPT_HOST, 's', "Use -connect instead"},
+    {"port", OPT_PORT, 'p', "Use -connect instead"},
+    {"connect", OPT_CONNECT, 's',
+     "TCP/IP where to connect (default is :" PORT ")"},
+    {"proxy", OPT_PROXY, 's',
+     "Connect to via specified proxy to the real server"},
+#ifdef AF_UNIX
+    {"unix", OPT_UNIX, 's', "Connect over the specified Unix-domain socket"},
+#endif
+    {"4", OPT_4, '-', "Use IPv4 only"},
+#ifdef AF_INET6
+    {"6", OPT_6, '-', "Use IPv6 only"},
+#endif
+    {"verify", OPT_VERIFY, 'p', "Turn on peer certificate verification"},
+    {"cert", OPT_CERT, '<', "Certificate file to use, PEM format assumed"},
+    {"certform", OPT_CERTFORM, 'F',
+     "Certificate format (PEM or DER) PEM default"},
+    {"key", OPT_KEY, 's', "Private key file to use, if not in -cert file"},
+    {"keyform", OPT_KEYFORM, 'E', "Key format (PEM, DER or engine) PEM default"},
+    {"pass", OPT_PASS, 's', "Private key file pass phrase source"},
+    {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"},
+    {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"},
+    {"no-CAfile", OPT_NOCAFILE, '-',
+     "Do not load the default certificates file"},
+    {"no-CApath", OPT_NOCAPATH, '-',
+     "Do not load certificates from the default certificates directory"},
+    {"dane_tlsa_domain", OPT_DANE_TLSA_DOMAIN, 's', "DANE TLSA base domain"},
+    {"dane_tlsa_rrdata", OPT_DANE_TLSA_RRDATA, 's',
+     "DANE TLSA rrdata presentation form"},
+    {"dane_ee_no_namechecks", OPT_DANE_EE_NO_NAME, '-',
+     "Disable name checks when matching DANE-EE(3) TLSA records"},
+    {"reconnect", OPT_RECONNECT, '-',
+     "Drop and re-make the connection with the same Session-ID"},
+    {"showcerts", OPT_SHOWCERTS, '-', "Show all certificates in the chain"},
+    {"debug", OPT_DEBUG, '-', "Extra output"},
+    {"msg", OPT_MSG, '-', "Show protocol messages"},
+    {"msgfile", OPT_MSGFILE, '>',
+     "File to send output of -msg or -trace, instead of stdout"},
+    {"nbio_test", OPT_NBIO_TEST, '-', "More ssl protocol testing"},
+    {"state", OPT_STATE, '-', "Print the ssl states"},
+    {"crlf", OPT_CRLF, '-', "Convert LF from terminal into CRLF"},
+    {"quiet", OPT_QUIET, '-', "No s_client output"},
+    {"ign_eof", OPT_IGN_EOF, '-', "Ignore input eof (default when -quiet)"},
+    {"no_ign_eof", OPT_NO_IGN_EOF, '-', "Don't ignore input eof"},
+    {"starttls", OPT_STARTTLS, 's',
+     "Use the appropriate STARTTLS command before starting TLS"},
+    {"xmpphost", OPT_XMPPHOST, 's',
+     "Host to use with \"-starttls xmpp[-server]\""},
+    {"rand", OPT_RAND, 's',
+     "Load the file(s) into the random number generator"},
+    {"sess_out", OPT_SESS_OUT, '>', "File to write SSL session to"},
+    {"sess_in", OPT_SESS_IN, '<', "File to read SSL session from"},
+    {"use_srtp", OPT_USE_SRTP, 's',
+     "Offer SRTP key management with a colon-separated profile list"},
+    {"keymatexport", OPT_KEYMATEXPORT, 's',
+     "Export keying material using label"},
+    {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p',
+     "Export len bytes of keying material (default 20)"},
+    {"fallback_scsv", OPT_FALLBACKSCSV, '-', "Send the fallback SCSV"},
+    {"name", OPT_SMTPHOST, 's', "Hostname to use for \"-starttls smtp\""},
+    {"CRL", OPT_CRL, '<', "CRL file to use"},
+    {"crl_download", OPT_CRL_DOWNLOAD, '-', "Download CRL from distribution points"},
+    {"CRLform", OPT_CRLFORM, 'F', "CRL format (PEM or DER) PEM is default"},
+    {"verify_return_error", OPT_VERIFY_RET_ERROR, '-',
+     "Close connection on verification error"},
+    {"verify_quiet", OPT_VERIFY_QUIET, '-', "Restrict verify output to errors"},
+    {"brief", OPT_BRIEF, '-',
+     "Restrict output to brief summary of connection parameters"},
+    {"prexit", OPT_PREXIT, '-',
+     "Print session information when the program exits"},
+    {"security_debug", OPT_SECURITY_DEBUG, '-',
+     "Enable security debug messages"},
+    {"security_debug_verbose", OPT_SECURITY_DEBUG_VERBOSE, '-',
+     "Output more security debug output"},
+    {"cert_chain", OPT_CERT_CHAIN, '<',
+     "Certificate chain file (in PEM format)"},
+    {"chainCApath", OPT_CHAINCAPATH, '/',
+     "Use dir as certificate store path to build CA certificate chain"},
+    {"verifyCApath", OPT_VERIFYCAPATH, '/',
+     "Use dir as certificate store path to verify CA certificate"},
+    {"build_chain", OPT_BUILD_CHAIN, '-', "Build certificate chain"},
+    {"chainCAfile", OPT_CHAINCAFILE, '<',
+     "CA file for certificate chain (PEM format)"},
+    {"verifyCAfile", OPT_VERIFYCAFILE, '<',
+     "CA file for certificate verification (PEM format)"},
+    {"nocommands", OPT_NOCMDS, '-', "Do not use interactive command letters"},
+    {"servername", OPT_SERVERNAME, 's',
+     "Set TLS extension servername in ClientHello"},
+    {"tlsextdebug", OPT_TLSEXTDEBUG, '-',
+     "Hex dump of all TLS extensions received"},
+#ifndef OPENSSL_NO_OCSP
+    {"status", OPT_STATUS, '-', "Request certificate status from server"},
+#endif
+    {"serverinfo", OPT_SERVERINFO, 's',
+     "types  Send empty ClientHello extensions (comma-separated numbers)"},
+    {"alpn", OPT_ALPN, 's',
+     "Enable ALPN extension, considering named protocols supported (comma-separated list)"},
+    {"async", OPT_ASYNC, '-', "Support asynchronous operation"},
+    {"ssl_config", OPT_SSL_CONFIG, 's', "Use specified configuration file"},
+    {"split_send_frag", OPT_SPLIT_SEND_FRAG, 'n',
+     "Size used to split data for encrypt pipelines"},
+    {"max_pipelines", OPT_MAX_PIPELINES, 'n',
+     "Maximum number of encrypt/decrypt pipelines to be used"},
+    {"read_buf", OPT_READ_BUF, 'n',
+     "Default read buffer size to be used for connections"},
+    OPT_S_OPTIONS,
+    OPT_V_OPTIONS,
+    OPT_X_OPTIONS,
+#ifndef OPENSSL_NO_SSL3
+    {"ssl3", OPT_SSL3, '-', "Just use SSLv3"},
+#endif
+#ifndef OPENSSL_NO_TLS1
+    {"tls1", OPT_TLS1, '-', "Just use TLSv1"},
+#endif
+#ifndef OPENSSL_NO_TLS1_1
+    {"tls1_1", OPT_TLS1_1, '-', "Just use TLSv1.1"},
+#endif
+#ifndef OPENSSL_NO_TLS1_2
+    {"tls1_2", OPT_TLS1_2, '-', "Just use TLSv1.2"},
+#endif
+#ifndef OPENSSL_NO_DTLS
+    {"dtls", OPT_DTLS, '-', "Use any version of DTLS"},
+    {"timeout", OPT_TIMEOUT, '-',
+     "Enable send/receive timeout on DTLS connections"},
+    {"mtu", OPT_MTU, 'p', "Set the link layer MTU"},
+#endif
+#ifndef OPENSSL_NO_DTLS1
+    {"dtls1", OPT_DTLS1, '-', "Just use DTLSv1"},
+#endif
+#ifndef OPENSSL_NO_DTLS1_2
+    {"dtls1_2", OPT_DTLS1_2, '-', "Just use DTLSv1.2"},
+#endif
+#ifndef OPENSSL_NO_SSL_TRACE
+    {"trace", OPT_TRACE, '-', "Show trace output of protocol messages"},
+#endif
+#ifdef WATT32
+    {"wdebug", OPT_WDEBUG, '-', "WATT-32 tcp debugging"},
+#endif
+    {"nbio", OPT_NBIO, '-', "Use non-blocking IO"},
+#ifndef OPENSSL_NO_PSK
+    {"psk_identity", OPT_PSK_IDENTITY, 's', "PSK identity"},
+    {"psk", OPT_PSK, 's', "PSK in hex (without 0x)"},
+#endif
+#ifndef OPENSSL_NO_SRP
+    {"srpuser", OPT_SRPUSER, 's', "SRP authentication for 'user'"},
+    {"srppass", OPT_SRPPASS, 's', "Password for 'user'"},
+    {"srp_lateuser", OPT_SRP_LATEUSER, '-',
+     "SRP username into second ClientHello message"},
+    {"srp_moregroups", OPT_SRP_MOREGROUPS, '-',
+     "Tolerate other than the known g N values."},
+    {"srp_strength", OPT_SRP_STRENGTH, 'p', "Minimal length in bits for N"},
+#endif
+#ifndef OPENSSL_NO_NEXTPROTONEG
+    {"nextprotoneg", OPT_NEXTPROTONEG, 's',
+     "Enable NPN extension, considering named protocols supported (comma-separated list)"},
+#endif
+#ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+    {"ssl_client_engine", OPT_SSL_CLIENT_ENGINE, 's',
+     "Specify engine to be used for client certificate operations"},
+#endif
+#ifndef OPENSSL_NO_CT
+    {"ct", OPT_CT, '-', "Request and parse SCTs (also enables OCSP stapling)"},
+    {"noct", OPT_NOCT, '-', "Do not request or parse SCTs (default)"},
+    {"ctlogfile", OPT_CTLOG_FILE, '<', "CT log list CONF file"},
+#endif
+    {NULL, OPT_EOF, 0x00, NULL}
+};
+
+typedef enum PROTOCOL_choice {
+    PROTO_OFF,
+    PROTO_SMTP,
+    PROTO_POP3,
+    PROTO_IMAP,
+    PROTO_FTP,
+    PROTO_TELNET,
+    PROTO_XMPP,
+    PROTO_XMPP_SERVER,
+    PROTO_CONNECT,
+    PROTO_IRC
+} PROTOCOL_CHOICE;
+
+static const OPT_PAIR services[] = {
+    {"smtp", PROTO_SMTP},
+    {"pop3", PROTO_POP3},
+    {"imap", PROTO_IMAP},
+    {"ftp", PROTO_FTP},
+    {"xmpp", PROTO_XMPP},
+    {"xmpp-server", PROTO_XMPP_SERVER},
+    {"telnet", PROTO_TELNET},
+    {"irc", PROTO_IRC},
+    {NULL, 0}
+};
+
+#define IS_INET_FLAG(o) \
+ (o == OPT_4 || o == OPT_6 || o == OPT_HOST || o == OPT_PORT || o == OPT_CONNECT)
+#define IS_UNIX_FLAG(o) (o == OPT_UNIX)
+
+#define IS_PROT_FLAG(o) \
+ (o == OPT_SSL3 || o == OPT_TLS1 || o == OPT_TLS1_1 || o == OPT_TLS1_2 \
+  || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2)
+
+/* Free |*dest| and optionally set it to a copy of |source|. */
+static void freeandcopy(char **dest, const char *source)
+{
+    OPENSSL_free(*dest);
+    *dest = NULL;
+    if (source != NULL)
+        *dest = OPENSSL_strdup(source);
+}
+
+int s_client_main(int argc, char **argv)
+{
+    BIO *sbio;
+    EVP_PKEY *key = NULL;
+    SSL *con = NULL;
+    SSL_CTX *ctx = NULL;
+    STACK_OF(X509) *chain = NULL;
+    X509 *cert = NULL;
+    X509_VERIFY_PARAM *vpm = NULL;
+    SSL_EXCERT *exc = NULL;
+    SSL_CONF_CTX *cctx = NULL;
+    STACK_OF(OPENSSL_STRING) *ssl_args = NULL;
+    char *dane_tlsa_domain = NULL;
+    STACK_OF(OPENSSL_STRING) *dane_tlsa_rrset = NULL;
+    int dane_ee_no_name = 0;
+    STACK_OF(X509_CRL) *crls = NULL;
+    const SSL_METHOD *meth = TLS_client_method();
+    const char *CApath = NULL, *CAfile = NULL;
+    char *cbuf = NULL, *sbuf = NULL;
+    char *mbuf = NULL, *proxystr = NULL, *connectstr = NULL;
+    char *cert_file = NULL, *key_file = NULL, *chain_file = NULL;
+    char *chCApath = NULL, *chCAfile = NULL, *host = NULL;
+    char *port = OPENSSL_strdup(PORT);
+    char *inrand = NULL;
+    char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL;
+    char *sess_in = NULL, *sess_out = NULL, *crl_file = NULL, *p;
+    char *xmpphost = NULL;
+    const char *ehlo = "mail.example.com";
+    struct timeval timeout, *timeoutp;
+    fd_set readfds, writefds;
+    int noCApath = 0, noCAfile = 0;
+    int build_chain = 0, cbuf_len, cbuf_off, cert_format = FORMAT_PEM;
+    int key_format = FORMAT_PEM, crlf = 0, full_log = 1, mbuf_len = 0;
+    int prexit = 0;
+    int sdebug = 0;
+    int reconnect = 0, verify = SSL_VERIFY_NONE, vpmtouched = 0;
+    int ret = 1, in_init = 1, i, nbio_test = 0, s = -1, k, width, state = 0;
+    int sbuf_len, sbuf_off, cmdletters = 1;
+    int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM;
+    int starttls_proto = PROTO_OFF, crl_format = FORMAT_PEM, crl_download = 0;
+    int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending;
+#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS)
+    int at_eof = 0;
+#endif
+    int read_buf_len = 0;
+    int fallback_scsv = 0;
+    long randamt = 0;
+    OPTION_CHOICE o;
+#ifndef OPENSSL_NO_DTLS
+    int enable_timeouts = 0;
+    long socket_mtu = 0;
+#endif
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE *ssl_client_engine = NULL;
+#endif
+    ENGINE *e = NULL;
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
+    struct timeval tv;
+#endif
+    char *servername = NULL;
+    const char *alpn_in = NULL;
+    tlsextctx tlsextcbp = { NULL, 0 };
+    const char *ssl_config = NULL;
+#define MAX_SI_TYPES 100
+    unsigned short serverinfo_types[MAX_SI_TYPES];
+    int serverinfo_count = 0, start = 0, len;
+#ifndef OPENSSL_NO_NEXTPROTONEG
+    const char *next_proto_neg_in = NULL;
+#endif
+#ifndef OPENSSL_NO_SRP
+    char *srppass = NULL;
+    int srp_lateuser = 0;
+    SRP_ARG srp_arg = { NULL, NULL, 0, 0, 0, 1024 };
+#endif
+#ifndef OPENSSL_NO_CT
+    char *ctlog_file = NULL;
+    int ct_validation = 0;
+#endif
+    int min_version = 0, max_version = 0, prot_opt = 0, no_prot_opt = 0;
+    int async = 0;
+    unsigned int split_send_fragment = 0;
+    unsigned int max_pipelines = 0;
+    enum { use_inet, use_unix, use_unknown } connect_type = use_unknown;
+    int count4or6 = 0;
+    int c_nbio = 0, c_msg = 0, c_ign_eof = 0, c_brief = 0;
+    int c_tlsextdebug = 0;
+#ifndef OPENSSL_NO_OCSP
+    int c_status_req = 0;
+#endif
+    BIO *bio_c_msg = NULL;
+
+    FD_ZERO(&readfds);
+    FD_ZERO(&writefds);
+/* Known false-positive of MemorySanitizer. */
+#if defined(__has_feature)
+# if __has_feature(memory_sanitizer)
+    __msan_unpoison(&readfds, sizeof(readfds));
+    __msan_unpoison(&writefds, sizeof(writefds));
+# endif
+#endif
+
+    prog = opt_progname(argv[0]);
+    c_quiet = 0;
+    c_debug = 0;
+    c_showcerts = 0;
+    c_nbio = 0;
+    vpm = X509_VERIFY_PARAM_new();
+    cctx = SSL_CONF_CTX_new();
+
+    if (vpm == NULL || cctx == NULL) {
+        BIO_printf(bio_err, "%s: out of memory\n", prog);
+        goto end;
+    }
+
+    cbuf = app_malloc(BUFSIZZ, "cbuf");
+    sbuf = app_malloc(BUFSIZZ, "sbuf");
+    mbuf = app_malloc(BUFSIZZ, "mbuf");
+
+    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT | SSL_CONF_FLAG_CMDLINE);
+
+    prog = opt_init(argc, argv, s_client_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        /* Check for intermixing flags. */
+        if (connect_type == use_unix && IS_INET_FLAG(o)) {
+            BIO_printf(bio_err,
+                       "%s: Intermixed protocol flags (unix and internet domains)\n",
+                       prog);
+            goto end;
+        }
+        if (connect_type == use_inet && IS_UNIX_FLAG(o)) {
+            BIO_printf(bio_err,
+                       "%s: Intermixed protocol flags (internet and unix domains)\n",
+                       prog);
+            goto end;
+        }
+
+        if (IS_PROT_FLAG(o) && ++prot_opt > 1) {
+            BIO_printf(bio_err, "Cannot supply multiple protocol flags\n");
+            goto end;
+        }
+        if (IS_NO_PROT_FLAG(o))
+            no_prot_opt++;
+        if (prot_opt == 1 && no_prot_opt) {
+            BIO_printf(bio_err,
+                       "Cannot supply both a protocol flag and '-no_<prot>'\n");
+            goto end;
+        }
+
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(s_client_options);
+            ret = 0;
+            goto end;
+        case OPT_4:
+            connect_type = use_inet;
+            socket_family = AF_INET;
+            count4or6++;
+            break;
+#ifdef AF_INET6
+        case OPT_6:
+            connect_type = use_inet;
+            socket_family = AF_INET6;
+            count4or6++;
+            break;
+#endif
+        case OPT_HOST:
+            connect_type = use_inet;
+            freeandcopy(&host, opt_arg());
+            break;
+        case OPT_PORT:
+            connect_type = use_inet;
+            freeandcopy(&port, opt_arg());
+            break;
+        case OPT_CONNECT:
+            connect_type = use_inet;
+            freeandcopy(&connectstr, opt_arg());
+            break;
+        case OPT_PROXY:
+            proxystr = opt_arg();
+            starttls_proto = PROTO_CONNECT;
+            break;
+#ifdef AF_UNIX
+        case OPT_UNIX:
+            connect_type = use_unix;
+            socket_family = AF_UNIX;
+            freeandcopy(&host, opt_arg());
+            break;
+#endif
+        case OPT_XMPPHOST:
+            xmpphost = opt_arg();
+            break;
+        case OPT_SMTPHOST:
+            ehlo = opt_arg();
+            break;
+        case OPT_VERIFY:
+            verify = SSL_VERIFY_PEER;
+            verify_args.depth = atoi(opt_arg());
+            if (!c_quiet)
+                BIO_printf(bio_err, "verify depth is %d\n", verify_args.depth);
+            break;
+        case OPT_CERT:
+            cert_file = opt_arg();
+            break;
+        case OPT_CRL:
+            crl_file = opt_arg();
+            break;
+        case OPT_CRL_DOWNLOAD:
+            crl_download = 1;
+            break;
+        case OPT_SESS_OUT:
+            sess_out = opt_arg();
+            break;
+        case OPT_SESS_IN:
+            sess_in = opt_arg();
+            break;
+        case OPT_CERTFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &cert_format))
+                goto opthelp;
+            break;
+        case OPT_CRLFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &crl_format))
+                goto opthelp;
+            break;
+        case OPT_VERIFY_RET_ERROR:
+            verify_args.return_error = 1;
+            break;
+        case OPT_VERIFY_QUIET:
+            verify_args.quiet = 1;
+            break;
+        case OPT_BRIEF:
+            c_brief = verify_args.quiet = c_quiet = 1;
+            break;
+        case OPT_S_CASES:
+            if (ssl_args == NULL)
+                ssl_args = sk_OPENSSL_STRING_new_null();
+            if (ssl_args == NULL
+                || !sk_OPENSSL_STRING_push(ssl_args, opt_flag())
+                || !sk_OPENSSL_STRING_push(ssl_args, opt_arg())) {
+                BIO_printf(bio_err, "%s: Memory allocation failure\n", prog);
+                goto end;
+            }
+            break;
+        case OPT_V_CASES:
+            if (!opt_verify(o, vpm))
+                goto end;
+            vpmtouched++;
+            break;
+        case OPT_X_CASES:
+            if (!args_excert(o, &exc))
+                goto end;
+            break;
+        case OPT_PREXIT:
+            prexit = 1;
+            break;
+        case OPT_CRLF:
+            crlf = 1;
+            break;
+        case OPT_QUIET:
+            c_quiet = c_ign_eof = 1;
+            break;
+        case OPT_NBIO:
+            c_nbio = 1;
+            break;
+        case OPT_NOCMDS:
+            cmdletters = 0;
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 1);
+            break;
+        case OPT_SSL_CLIENT_ENGINE:
+#ifndef OPENSSL_NO_ENGINE
+            ssl_client_engine = ENGINE_by_id(opt_arg());
+            if (ssl_client_engine == NULL) {
+                BIO_printf(bio_err, "Error getting client auth engine\n");
+                goto opthelp;
+            }
+#endif
+            break;
+        case OPT_RAND:
+            inrand = opt_arg();
+            break;
+        case OPT_IGN_EOF:
+            c_ign_eof = 1;
+            break;
+        case OPT_NO_IGN_EOF:
+            c_ign_eof = 0;
+            break;
+        case OPT_DEBUG:
+            c_debug = 1;
+            break;
+        case OPT_TLSEXTDEBUG:
+            c_tlsextdebug = 1;
+            break;
+        case OPT_STATUS:
+#ifndef OPENSSL_NO_OCSP
+            c_status_req = 1;
+#endif
+            break;
+        case OPT_WDEBUG:
+#ifdef WATT32
+            dbug_init();
+#endif
+            break;
+        case OPT_MSG:
+            c_msg = 1;
+            break;
+        case OPT_MSGFILE:
+            bio_c_msg = BIO_new_file(opt_arg(), "w");
+            break;
+        case OPT_TRACE:
+#ifndef OPENSSL_NO_SSL_TRACE
+            c_msg = 2;
+#endif
+            break;
+        case OPT_SECURITY_DEBUG:
+            sdebug = 1;
+            break;
+        case OPT_SECURITY_DEBUG_VERBOSE:
+            sdebug = 2;
+            break;
+        case OPT_SHOWCERTS:
+            c_showcerts = 1;
+            break;
+        case OPT_NBIO_TEST:
+            nbio_test = 1;
+            break;
+        case OPT_STATE:
+            state = 1;
+            break;
+#ifndef OPENSSL_NO_PSK
+        case OPT_PSK_IDENTITY:
+            psk_identity = opt_arg();
+            break;
+        case OPT_PSK:
+            for (p = psk_key = opt_arg(); *p; p++) {
+                if (isxdigit(_UC(*p)))
+                    continue;
+                BIO_printf(bio_err, "Not a hex number '%s'\n", psk_key);
+                goto end;
+            }
+            break;
+#endif
+#ifndef OPENSSL_NO_SRP
+        case OPT_SRPUSER:
+            srp_arg.srplogin = opt_arg();
+            if (min_version < TLS1_VERSION)
+                min_version = TLS1_VERSION;
+            break;
+        case OPT_SRPPASS:
+            srppass = opt_arg();
+            if (min_version < TLS1_VERSION)
+                min_version = TLS1_VERSION;
+            break;
+        case OPT_SRP_STRENGTH:
+            srp_arg.strength = atoi(opt_arg());
+            BIO_printf(bio_err, "SRP minimal length for N is %d\n",
+                       srp_arg.strength);
+            if (min_version < TLS1_VERSION)
+                min_version = TLS1_VERSION;
+            break;
+        case OPT_SRP_LATEUSER:
+            srp_lateuser = 1;
+            if (min_version < TLS1_VERSION)
+                min_version = TLS1_VERSION;
+            break;
+        case OPT_SRP_MOREGROUPS:
+            srp_arg.amp = 1;
+            if (min_version < TLS1_VERSION)
+                min_version = TLS1_VERSION;
+            break;
+#endif
+        case OPT_SSL_CONFIG:
+            ssl_config = opt_arg();
+            break;
+        case OPT_SSL3:
+            min_version = SSL3_VERSION;
+            max_version = SSL3_VERSION;
+            break;
+        case OPT_TLS1_2:
+            min_version = TLS1_2_VERSION;
+            max_version = TLS1_2_VERSION;
+            break;
+        case OPT_TLS1_1:
+            min_version = TLS1_1_VERSION;
+            max_version = TLS1_1_VERSION;
+            break;
+        case OPT_TLS1:
+            min_version = TLS1_VERSION;
+            max_version = TLS1_VERSION;
+            break;
+        case OPT_DTLS:
+#ifndef OPENSSL_NO_DTLS
+            meth = DTLS_client_method();
+            socket_type = SOCK_DGRAM;
+#endif
+            break;
+        case OPT_DTLS1:
+#ifndef OPENSSL_NO_DTLS1
+            meth = DTLS_client_method();
+            min_version = DTLS1_VERSION;
+            max_version = DTLS1_VERSION;
+            socket_type = SOCK_DGRAM;
+#endif
+            break;
+        case OPT_DTLS1_2:
+#ifndef OPENSSL_NO_DTLS1_2
+            meth = DTLS_client_method();
+            min_version = DTLS1_2_VERSION;
+            max_version = DTLS1_2_VERSION;
+            socket_type = SOCK_DGRAM;
+#endif
+            break;
+        case OPT_TIMEOUT:
+#ifndef OPENSSL_NO_DTLS
+            enable_timeouts = 1;
+#endif
+            break;
+        case OPT_MTU:
+#ifndef OPENSSL_NO_DTLS
+            socket_mtu = atol(opt_arg());
+#endif
+            break;
+        case OPT_FALLBACKSCSV:
+            fallback_scsv = 1;
+            break;
+        case OPT_KEYFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PDE, &key_format))
+                goto opthelp;
+            break;
+        case OPT_PASS:
+            passarg = opt_arg();
+            break;
+        case OPT_CERT_CHAIN:
+            chain_file = opt_arg();
+            break;
+        case OPT_KEY:
+            key_file = opt_arg();
+            break;
+        case OPT_RECONNECT:
+            reconnect = 5;
+            break;
+        case OPT_CAPATH:
+            CApath = opt_arg();
+            break;
+        case OPT_NOCAPATH:
+            noCApath = 1;
+            break;
+        case OPT_CHAINCAPATH:
+            chCApath = opt_arg();
+            break;
+        case OPT_VERIFYCAPATH:
+            vfyCApath = opt_arg();
+            break;
+        case OPT_BUILD_CHAIN:
+            build_chain = 1;
+            break;
+        case OPT_CAFILE:
+            CAfile = opt_arg();
+            break;
+        case OPT_NOCAFILE:
+            noCAfile = 1;
+            break;
+#ifndef OPENSSL_NO_CT
+        case OPT_NOCT:
+            ct_validation = 0;
+            break;
+        case OPT_CT:
+            ct_validation = 1;
+            break;
+        case OPT_CTLOG_FILE:
+            ctlog_file = opt_arg();
+            break;
+#endif
+        case OPT_CHAINCAFILE:
+            chCAfile = opt_arg();
+            break;
+        case OPT_VERIFYCAFILE:
+            vfyCAfile = opt_arg();
+            break;
+        case OPT_DANE_TLSA_DOMAIN:
+            dane_tlsa_domain = opt_arg();
+            break;
+        case OPT_DANE_TLSA_RRDATA:
+            if (dane_tlsa_rrset == NULL)
+                dane_tlsa_rrset = sk_OPENSSL_STRING_new_null();
+            if (dane_tlsa_rrset == NULL ||
+                !sk_OPENSSL_STRING_push(dane_tlsa_rrset, opt_arg())) {
+                BIO_printf(bio_err, "%s: Memory allocation failure\n", prog);
+                goto end;
+            }
+            break;
+        case OPT_DANE_EE_NO_NAME:
+            dane_ee_no_name = 1;
+            break;
+        case OPT_NEXTPROTONEG:
+#ifndef OPENSSL_NO_NEXTPROTONEG
+            next_proto_neg_in = opt_arg();
+#endif
+            break;
+        case OPT_ALPN:
+            alpn_in = opt_arg();
+            break;
+        case OPT_SERVERINFO:
+            p = opt_arg();
+            len = strlen(p);
+            for (start = 0, i = 0; i <= len; ++i) {
+                if (i == len || p[i] == ',') {
+                    serverinfo_types[serverinfo_count] = atoi(p + start);
+                    if (++serverinfo_count == MAX_SI_TYPES)
+                        break;
+                    start = i + 1;
+                }
+            }
+            break;
+        case OPT_STARTTLS:
+            if (!opt_pair(opt_arg(), services, &starttls_proto))
+                goto end;
+            break;
+        case OPT_SERVERNAME:
+            servername = opt_arg();
+            break;
+        case OPT_USE_SRTP:
+            srtp_profiles = opt_arg();
+            break;
+        case OPT_KEYMATEXPORT:
+            keymatexportlabel = opt_arg();
+            break;
+        case OPT_KEYMATEXPORTLEN:
+            keymatexportlen = atoi(opt_arg());
+            break;
+        case OPT_ASYNC:
+            async = 1;
+            break;
+        case OPT_SPLIT_SEND_FRAG:
+            split_send_fragment = atoi(opt_arg());
+            if (split_send_fragment == 0) {
+                /*
+                 * Not allowed - set to a deliberately bad value so we get an
+                 * error message below
+                 */
+                split_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH + 1;
+            }
+            break;
+        case OPT_MAX_PIPELINES:
+            max_pipelines = atoi(opt_arg());
+            break;
+        case OPT_READ_BUF:
+            read_buf_len = atoi(opt_arg());
+            break;
+        }
+    }
+    if (count4or6 >= 2) {
+        BIO_printf(bio_err, "%s: Can't use both -4 and -6\n", prog);
+        goto opthelp;
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    if (proxystr) {
+        int res;
+        char *tmp_host = host, *tmp_port = port;
+        if (connectstr == NULL) {
+            BIO_printf(bio_err, "%s: -proxy requires use of -connect\n", prog);
+            goto opthelp;
+        }
+        res = BIO_parse_hostserv(proxystr, &host, &port, BIO_PARSE_PRIO_HOST);
+        if (tmp_host != host)
+            OPENSSL_free(tmp_host);
+        if (tmp_port != port)
+            OPENSSL_free(tmp_port);
+        if (!res) {
+            BIO_printf(bio_err,
+                       "%s: -proxy argument malformed or ambiguous\n", prog);
+            goto end;
+        }
+    } else {
+        int res = 1;
+        char *tmp_host = host, *tmp_port = port;
+        if (connectstr != NULL)
+            res = BIO_parse_hostserv(connectstr, &host, &port,
+                                     BIO_PARSE_PRIO_HOST);
+        if (tmp_host != host)
+            OPENSSL_free(tmp_host);
+        if (tmp_port != port)
+            OPENSSL_free(tmp_port);
+        if (!res) {
+            BIO_printf(bio_err,
+                       "%s: -connect argument malformed or ambiguous\n",
+                       prog);
+            goto end;
+        }
+    }
+
+    if (socket_family == AF_UNIX && socket_type != SOCK_STREAM) {
+        BIO_printf(bio_err,
+                   "Can't use unix sockets and datagrams together\n");
+        goto end;
+    }
+
+    if (split_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) {
+        BIO_printf(bio_err, "Bad split send fragment size\n");
+        goto end;
+    }
+
+    if (max_pipelines > SSL_MAX_PIPELINES) {
+        BIO_printf(bio_err, "Bad max pipelines value\n");
+        goto end;
+    }
+
+#if !defined(OPENSSL_NO_NEXTPROTONEG)
+    next_proto.status = -1;
+    if (next_proto_neg_in) {
+        next_proto.data =
+            next_protos_parse(&next_proto.len, next_proto_neg_in);
+        if (next_proto.data == NULL) {
+            BIO_printf(bio_err, "Error parsing -nextprotoneg argument\n");
+            goto end;
+        }
+    } else
+        next_proto.data = NULL;
+#endif
+
+    if (!app_passwd(passarg, NULL, &pass, NULL)) {
+        BIO_printf(bio_err, "Error getting password\n");
+        goto end;
+    }
+
+    if (key_file == NULL)
+        key_file = cert_file;
+
+    if (key_file) {
+        key = load_key(key_file, key_format, 0, pass, e,
+                       "client certificate private key file");
+        if (key == NULL) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    if (cert_file) {
+        cert = load_cert(cert_file, cert_format, "client certificate file");
+        if (cert == NULL) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    if (chain_file) {
+        if (!load_certs(chain_file, &chain, FORMAT_PEM, NULL,
+                        "client certificate chain"))
+            goto end;
+    }
+
+    if (crl_file) {
+        X509_CRL *crl;
+        crl = load_crl(crl_file, crl_format);
+        if (crl == NULL) {
+            BIO_puts(bio_err, "Error loading CRL\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        crls = sk_X509_CRL_new_null();
+        if (crls == NULL || !sk_X509_CRL_push(crls, crl)) {
+            BIO_puts(bio_err, "Error adding CRL\n");
+            ERR_print_errors(bio_err);
+            X509_CRL_free(crl);
+            goto end;
+        }
+    }
+
+    if (!load_excert(&exc))
+        goto end;
+
+    if (!app_RAND_load_file(NULL, 1) && inrand == NULL
+        && !RAND_status()) {
+        BIO_printf(bio_err,
+                   "warning, not much extra random data, consider using the -rand option\n");
+    }
+    if (inrand != NULL) {
+        randamt = app_RAND_load_files(inrand);
+        BIO_printf(bio_err, "%ld semi-random bytes loaded\n", randamt);
+    }
+
+    if (bio_c_out == NULL) {
+        if (c_quiet && !c_debug) {
+            bio_c_out = BIO_new(BIO_s_null());
+            if (c_msg && !bio_c_msg)
+                bio_c_msg = dup_bio_out(FORMAT_TEXT);
+        } else if (bio_c_out == NULL)
+            bio_c_out = dup_bio_out(FORMAT_TEXT);
+    }
+#ifndef OPENSSL_NO_SRP
+    if (!app_passwd(srppass, NULL, &srp_arg.srppassin, NULL)) {
+        BIO_printf(bio_err, "Error getting password\n");
+        goto end;
+    }
+#endif
+
+    ctx = SSL_CTX_new(meth);
+    if (ctx == NULL) {
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    if (sdebug)
+        ssl_ctx_security_debug(ctx, sdebug);
+
+    if (ssl_config) {
+        if (SSL_CTX_config(ctx, ssl_config) == 0) {
+            BIO_printf(bio_err, "Error using configuration \"%s\"\n",
+                       ssl_config);
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0)
+        goto end;
+    if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
+        goto end;
+
+    if (vpmtouched && !SSL_CTX_set1_param(ctx, vpm)) {
+        BIO_printf(bio_err, "Error setting verify params\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    if (async) {
+        SSL_CTX_set_mode(ctx, SSL_MODE_ASYNC);
+    }
+    if (split_send_fragment > 0) {
+        SSL_CTX_set_split_send_fragment(ctx, split_send_fragment);
+    }
+    if (max_pipelines > 0) {
+        SSL_CTX_set_max_pipelines(ctx, max_pipelines);
+    }
+
+    if (read_buf_len > 0) {
+        SSL_CTX_set_default_read_buffer_len(ctx, read_buf_len);
+    }
+
+    if (!config_ctx(cctx, ssl_args, ctx))
+        goto end;
+
+    if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile,
+                         crls, crl_download)) {
+        BIO_printf(bio_err, "Error loading store locations\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+#ifndef OPENSSL_NO_ENGINE
+    if (ssl_client_engine) {
+        if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine)) {
+            BIO_puts(bio_err, "Error setting client auth engine\n");
+            ERR_print_errors(bio_err);
+            ENGINE_free(ssl_client_engine);
+            goto end;
+        }
+        ENGINE_free(ssl_client_engine);
+    }
+#endif
+
+#ifndef OPENSSL_NO_PSK
+    if (psk_key != NULL) {
+        if (c_debug)
+            BIO_printf(bio_c_out, "PSK key given, setting client callback\n");
+        SSL_CTX_set_psk_client_callback(ctx, psk_client_cb);
+    }
+#endif
+#ifndef OPENSSL_NO_SRTP
+    if (srtp_profiles != NULL) {
+        /* Returns 0 on success! */
+        if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles) != 0) {
+            BIO_printf(bio_err, "Error setting SRTP profile\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+#endif
+
+    if (exc)
+        ssl_ctx_set_excert(ctx, exc);
+
+#if !defined(OPENSSL_NO_NEXTPROTONEG)
+    if (next_proto.data)
+        SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
+#endif
+    if (alpn_in) {
+        size_t alpn_len;
+        unsigned char *alpn = next_protos_parse(&alpn_len, alpn_in);
+
+        if (alpn == NULL) {
+            BIO_printf(bio_err, "Error parsing -alpn argument\n");
+            goto end;
+        }
+        /* Returns 0 on success! */
+        if (SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len) != 0) {
+            BIO_printf(bio_err, "Error setting ALPN\n");
+            goto end;
+        }
+        OPENSSL_free(alpn);
+    }
+
+    for (i = 0; i < serverinfo_count; i++) {
+        if (!SSL_CTX_add_client_custom_ext(ctx,
+                                           serverinfo_types[i],
+                                           NULL, NULL, NULL,
+                                           serverinfo_cli_parse_cb, NULL)) {
+            BIO_printf(bio_err,
+                       "Warning: Unable to add custom extension %u, skipping\n",
+                       serverinfo_types[i]);
+        }
+    }
+
+    if (state)
+        SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback);
+
+#ifndef OPENSSL_NO_CT
+    /* Enable SCT processing, without early connection termination */
+    if (ct_validation &&
+        !SSL_CTX_enable_ct(ctx, SSL_CT_VALIDATION_PERMISSIVE)) {
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    if (!ctx_set_ctlog_list_file(ctx, ctlog_file)) {
+        if (ct_validation) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+
+        /*
+         * If CT validation is not enabled, the log list isn't needed so don't
+         * show errors or abort. We try to load it regardless because then we
+         * can show the names of the logs any SCTs came from (SCTs may be seen
+         * even with validation disabled).
+         */
+        ERR_clear_error();
+    }
+#endif
+
+    SSL_CTX_set_verify(ctx, verify, verify_callback);
+
+    if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) {
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    ssl_ctx_add_crls(ctx, crls, crl_download);
+
+    if (!set_cert_key_stuff(ctx, cert, key, chain, build_chain))
+        goto end;
+
+    if (servername != NULL) {
+        tlsextcbp.biodebug = bio_err;
+        SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
+        SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
+    }
+# ifndef OPENSSL_NO_SRP
+    if (srp_arg.srplogin) {
+        if (!srp_lateuser && !SSL_CTX_set_srp_username(ctx, srp_arg.srplogin)) {
+            BIO_printf(bio_err, "Unable to set SRP username\n");
+            goto end;
+        }
+        srp_arg.msg = c_msg;
+        srp_arg.debug = c_debug;
+        SSL_CTX_set_srp_cb_arg(ctx, &srp_arg);
+        SSL_CTX_set_srp_client_pwd_callback(ctx, ssl_give_srp_client_pwd_cb);
+        SSL_CTX_set_srp_strength(ctx, srp_arg.strength);
+        if (c_msg || c_debug || srp_arg.amp == 0)
+            SSL_CTX_set_srp_verify_param_callback(ctx,
+                                                  ssl_srp_verify_param_cb);
+    }
+# endif
+
+    if (dane_tlsa_domain != NULL) {
+        if (SSL_CTX_dane_enable(ctx) <= 0) {
+            BIO_printf(bio_err,
+                       "%s: Error enabling DANE TLSA authentication.\n",
+                       prog);
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    con = SSL_new(ctx);
+    if (sess_in) {
+        SSL_SESSION *sess;
+        BIO *stmp = BIO_new_file(sess_in, "r");
+        if (!stmp) {
+            BIO_printf(bio_err, "Can't open session file %s\n", sess_in);
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);
+        BIO_free(stmp);
+        if (!sess) {
+            BIO_printf(bio_err, "Can't open session file %s\n", sess_in);
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        if (!SSL_set_session(con, sess)) {
+            BIO_printf(bio_err, "Can't set session\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        SSL_SESSION_free(sess);
+    }
+
+    if (fallback_scsv)
+        SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV);
+
+    if (servername != NULL) {
+        if (!SSL_set_tlsext_host_name(con, servername)) {
+            BIO_printf(bio_err, "Unable to set TLS servername extension.\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    if (dane_tlsa_domain != NULL) {
+        if (SSL_dane_enable(con, dane_tlsa_domain) <= 0) {
+            BIO_printf(bio_err, "%s: Error enabling DANE TLSA "
+                       "authentication.\n", prog);
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        if (dane_tlsa_rrset == NULL) {
+            BIO_printf(bio_err, "%s: DANE TLSA authentication requires at "
+                       "least one -dane_tlsa_rrdata option.\n", prog);
+            goto end;
+        }
+        if (tlsa_import_rrset(con, dane_tlsa_rrset) <= 0) {
+            BIO_printf(bio_err, "%s: Failed to import any TLSA "
+                       "records.\n", prog);
+            goto end;
+        }
+        if (dane_ee_no_name)
+            SSL_dane_set_flags(con, DANE_FLAG_NO_DANE_EE_NAMECHECKS);
+    } else if (dane_tlsa_rrset != NULL) {
+        BIO_printf(bio_err, "%s: DANE TLSA authentication requires the "
+                   "-dane_tlsa_domain option.\n", prog);
+        goto end;
+    }
+
+ re_start:
+    if (init_client(&s, host, port, socket_family, socket_type) == 0) {
+        BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error());
+        BIO_closesocket(s);
+        goto end;
+    }
+    BIO_printf(bio_c_out, "CONNECTED(%08X)\n", s);
+
+    if (c_nbio) {
+        if (!BIO_socket_nbio(s, 1)) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        BIO_printf(bio_c_out, "Turned on non blocking io\n");
+    }
+#ifndef OPENSSL_NO_DTLS
+    if (socket_type == SOCK_DGRAM) {
+        union BIO_sock_info_u peer_info;
+
+        sbio = BIO_new_dgram(s, BIO_NOCLOSE);
+        if ((peer_info.addr = BIO_ADDR_new()) == NULL) {
+            BIO_printf(bio_err, "memory allocation failure\n");
+            BIO_closesocket(s);
+            goto end;
+        }
+        if (!BIO_sock_info(s, BIO_SOCK_INFO_ADDRESS, &peer_info)) {
+            BIO_printf(bio_err, "getsockname:errno=%d\n",
+                       get_last_socket_error());
+            BIO_ADDR_free(peer_info.addr);
+            BIO_closesocket(s);
+            goto end;
+        }
+
+        (void)BIO_ctrl_set_connected(sbio, peer_info.addr);
+        BIO_ADDR_free(peer_info.addr);
+        peer_info.addr = NULL;
+
+        if (enable_timeouts) {
+            timeout.tv_sec = 0;
+            timeout.tv_usec = DGRAM_RCV_TIMEOUT;
+            BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
+
+            timeout.tv_sec = 0;
+            timeout.tv_usec = DGRAM_SND_TIMEOUT;
+            BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
+        }
+
+        if (socket_mtu) {
+            if (socket_mtu < DTLS_get_link_min_mtu(con)) {
+                BIO_printf(bio_err, "MTU too small. Must be at least %ld\n",
+                           DTLS_get_link_min_mtu(con));
+                BIO_free(sbio);
+                goto shut;
+            }
+            SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
+            if (!DTLS_set_link_mtu(con, socket_mtu)) {
+                BIO_printf(bio_err, "Failed to set MTU\n");
+                BIO_free(sbio);
+                goto shut;
+            }
+        } else
+            /* want to do MTU discovery */
+            BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
+    } else
+#endif /* OPENSSL_NO_DTLS */
+        sbio = BIO_new_socket(s, BIO_NOCLOSE);
+
+    if (nbio_test) {
+        BIO *test;
+
+        test = BIO_new(BIO_f_nbio_test());
+        sbio = BIO_push(test, sbio);
+    }
+
+    if (c_debug) {
+        BIO_set_callback(sbio, bio_dump_callback);
+        BIO_set_callback_arg(sbio, (char *)bio_c_out);
+    }
+    if (c_msg) {
+#ifndef OPENSSL_NO_SSL_TRACE
+        if (c_msg == 2)
+            SSL_set_msg_callback(con, SSL_trace);
+        else
+#endif
+            SSL_set_msg_callback(con, msg_cb);
+        SSL_set_msg_callback_arg(con, bio_c_msg ? bio_c_msg : bio_c_out);
+    }
+
+    if (c_tlsextdebug) {
+        SSL_set_tlsext_debug_callback(con, tlsext_cb);
+        SSL_set_tlsext_debug_arg(con, bio_c_out);
+    }
+#ifndef OPENSSL_NO_OCSP
+    if (c_status_req) {
+        SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp);
+        SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb);
+        SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out);
+    }
+#endif
+
+    SSL_set_bio(con, sbio, sbio);
+    SSL_set_connect_state(con);
+
+    /* ok, lets connect */
+    if (fileno_stdin() > SSL_get_fd(con))
+        width = fileno_stdin() + 1;
+    else
+        width = SSL_get_fd(con) + 1;
+
+    read_tty = 1;
+    write_tty = 0;
+    tty_on = 0;
+    read_ssl = 1;
+    write_ssl = 1;
+
+    cbuf_len = 0;
+    cbuf_off = 0;
+    sbuf_len = 0;
+    sbuf_off = 0;
+
+    switch ((PROTOCOL_CHOICE) starttls_proto) {
+    case PROTO_OFF:
+        break;
+    case PROTO_SMTP:
+        {
+            /*
+             * This is an ugly hack that does a lot of assumptions. We do
+             * have to handle multi-line responses which may come in a single
+             * packet or not. We therefore have to use BIO_gets() which does
+             * need a buffering BIO. So during the initial chitchat we do
+             * push a buffering BIO into the chain that is removed again
+             * later on to not disturb the rest of the s_client operation.
+             */
+            int foundit = 0;
+            BIO *fbio = BIO_new(BIO_f_buffer());
+            BIO_push(fbio, sbio);
+            /* wait for multi-line response to end from SMTP */
+            do {
+                mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
+            }
+            while (mbuf_len > 3 && mbuf[3] == '-');
+            BIO_printf(fbio, "EHLO %s\r\n", ehlo);
+            (void)BIO_flush(fbio);
+            /* wait for multi-line response to end EHLO SMTP response */
+            do {
+                mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
+                if (strstr(mbuf, "STARTTLS"))
+                    foundit = 1;
+            }
+            while (mbuf_len > 3 && mbuf[3] == '-');
+            (void)BIO_flush(fbio);
+            BIO_pop(fbio);
+            BIO_free(fbio);
+            if (!foundit)
+                BIO_printf(bio_err,
+                           "didn't find starttls in server response,"
+                           " trying anyway...\n");
+            BIO_printf(sbio, "STARTTLS\r\n");
+            BIO_read(sbio, sbuf, BUFSIZZ);
+        }
+        break;
+    case PROTO_POP3:
+        {
+            BIO_read(sbio, mbuf, BUFSIZZ);
+            BIO_printf(sbio, "STLS\r\n");
+            mbuf_len = BIO_read(sbio, sbuf, BUFSIZZ);
+            if (mbuf_len < 0) {
+                BIO_printf(bio_err, "BIO_read failed\n");
+                goto end;
+            }
+        }
+        break;
+    case PROTO_IMAP:
+        {
+            int foundit = 0;
+            BIO *fbio = BIO_new(BIO_f_buffer());
+            BIO_push(fbio, sbio);
+            BIO_gets(fbio, mbuf, BUFSIZZ);
+            /* STARTTLS command requires CAPABILITY... */
+            BIO_printf(fbio, ". CAPABILITY\r\n");
+            (void)BIO_flush(fbio);
+            /* wait for multi-line CAPABILITY response */
+            do {
+                mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
+                if (strstr(mbuf, "STARTTLS"))
+                    foundit = 1;
+            }
+            while (mbuf_len > 3 && mbuf[0] != '.');
+            (void)BIO_flush(fbio);
+            BIO_pop(fbio);
+            BIO_free(fbio);
+            if (!foundit)
+                BIO_printf(bio_err,
+                           "didn't find STARTTLS in server response,"
+                           " trying anyway...\n");
+            BIO_printf(sbio, ". STARTTLS\r\n");
+            BIO_read(sbio, sbuf, BUFSIZZ);
+        }
+        break;
+    case PROTO_FTP:
+        {
+            BIO *fbio = BIO_new(BIO_f_buffer());
+            BIO_push(fbio, sbio);
+            /* wait for multi-line response to end from FTP */
+            do {
+                mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
+            }
+            while (mbuf_len > 3 && mbuf[3] == '-');
+            (void)BIO_flush(fbio);
+            BIO_pop(fbio);
+            BIO_free(fbio);
+            BIO_printf(sbio, "AUTH TLS\r\n");
+            BIO_read(sbio, sbuf, BUFSIZZ);
+        }
+        break;
+    case PROTO_XMPP:
+    case PROTO_XMPP_SERVER:
+        {
+            int seen = 0;
+            BIO_printf(sbio, "<stream:stream "
+                       "xmlns:stream='http://etherx.jabber.org/streams' "
+                       "xmlns='jabber:%s' to='%s' version='1.0'>",
+                       starttls_proto == PROTO_XMPP ? "client" : "server",
+                       xmpphost ? xmpphost : host);
+            seen = BIO_read(sbio, mbuf, BUFSIZZ);
+            mbuf[seen] = 0;
+            while (!strstr
+                   (mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'")
+                   && !strstr(mbuf,
+                              "<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\""))
+            {
+                seen = BIO_read(sbio, mbuf, BUFSIZZ);
+
+                if (seen <= 0)
+                    goto shut;
+
+                mbuf[seen] = 0;
+            }
+            BIO_printf(sbio,
+                       "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
+            seen = BIO_read(sbio, sbuf, BUFSIZZ);
+            sbuf[seen] = 0;
+            if (!strstr(sbuf, "<proceed"))
+                goto shut;
+            mbuf[0] = 0;
+        }
+        break;
+    case PROTO_TELNET:
+        {
+            static const unsigned char tls_do[] = {
+                /* IAC    DO   START_TLS */
+                   255,   253, 46
+            };
+            static const unsigned char tls_will[] = {
+                /* IAC  WILL START_TLS */
+                   255, 251, 46
+            };
+            static const unsigned char tls_follows[] = {
+                /* IAC  SB   START_TLS FOLLOWS IAC  SE */
+                   255, 250, 46,       1,      255, 240
+            };
+            int bytes;
+
+            /* Telnet server should demand we issue START_TLS */
+            bytes = BIO_read(sbio, mbuf, BUFSIZZ);
+            if (bytes != 3 || memcmp(mbuf, tls_do, 3) != 0)
+                goto shut;
+            /* Agree to issue START_TLS and send the FOLLOWS sub-command */
+            BIO_write(sbio, tls_will, 3);
+            BIO_write(sbio, tls_follows, 6);
+            (void)BIO_flush(sbio);
+            /* Telnet server also sent the FOLLOWS sub-command */
+            bytes = BIO_read(sbio, mbuf, BUFSIZZ);
+            if (bytes != 6 || memcmp(mbuf, tls_follows, 6) != 0)
+                goto shut;
+        }
+        break;
+    case PROTO_CONNECT:
+        {
+            enum {
+                error_proto,     /* Wrong protocol, not even HTTP */
+                error_connect,   /* CONNECT failed */
+                success
+            } foundit = error_connect;
+            BIO *fbio = BIO_new(BIO_f_buffer());
+
+            BIO_push(fbio, sbio);
+            BIO_printf(fbio, "CONNECT %s HTTP/1.0\r\n\r\n", connectstr);
+            (void)BIO_flush(fbio);
+            /*
+             * The first line is the HTTP response.  According to RFC 7230,
+             * it's formated exactly like this:
+             *
+             * HTTP/d.d ddd Reason text\r\n
+             */
+            mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
+            if (mbuf[8] != ' ') {
+                BIO_printf(bio_err,
+                           "%s: HTTP CONNECT failed, incorrect response "
+                           "from proxy\n", prog);
+                foundit = error_proto;
+            } else if (mbuf[9] != '2') {
+                BIO_printf(bio_err, "%s: HTTP CONNECT failed: %s ", prog,
+                           &mbuf[9]);
+            } else {
+                foundit = success;
+            }
+            if (foundit != error_proto) {
+                /* Read past all following headers */
+                do {
+                    mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
+                } while (mbuf_len > 2);
+            }
+            (void)BIO_flush(fbio);
+            BIO_pop(fbio);
+            BIO_free(fbio);
+            if (foundit != success) {
+                goto shut;
+            }
+        }
+        break;
+    case PROTO_IRC:
+        {
+            int numeric;
+            BIO *fbio = BIO_new(BIO_f_buffer());
+
+            BIO_push(fbio, sbio);
+            BIO_printf(fbio, "STARTTLS\r\n");
+            (void)BIO_flush(fbio);
+            width = SSL_get_fd(con) + 1;
+
+            do {
+                numeric = 0;
+
+                FD_ZERO(&readfds);
+                openssl_fdset(SSL_get_fd(con), &readfds);
+                timeout.tv_sec = S_CLIENT_IRC_READ_TIMEOUT;
+                timeout.tv_usec = 0;
+                /*
+                 * If the IRCd doesn't respond within
+                 * S_CLIENT_IRC_READ_TIMEOUT seconds, assume
+                 * it doesn't support STARTTLS. Many IRCds
+                 * will not give _any_ sort of response to a
+                 * STARTTLS command when it's not supported.
+                 */
+                if (!BIO_get_buffer_num_lines(fbio)
+                    && !BIO_pending(fbio)
+                    && !BIO_pending(sbio)
+                    && select(width, (void *)&readfds, NULL, NULL,
+                              &timeout) < 1) {
+                    BIO_printf(bio_err,
+                               "Timeout waiting for response (%d seconds).\n",
+                               S_CLIENT_IRC_READ_TIMEOUT);
+                    break;
+                }
+
+                mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
+                if (mbuf_len < 1 || sscanf(mbuf, "%*s %d", &numeric) != 1)
+                    break;
+                /* :example.net 451 STARTTLS :You have not registered */
+                /* :example.net 421 STARTTLS :Unknown command */
+                if ((numeric == 451 || numeric == 421)
+                    && strstr(mbuf, "STARTTLS") != NULL) {
+                    BIO_printf(bio_err, "STARTTLS not supported: %s", mbuf);
+                    break;
+                }
+                if (numeric == 691) {
+                    BIO_printf(bio_err, "STARTTLS negotiation failed: ");
+                    ERR_print_errors(bio_err);
+                    break;
+                }
+            } while (numeric != 670);
+
+            (void)BIO_flush(fbio);
+            BIO_pop(fbio);
+            BIO_free(fbio);
+            if (numeric != 670) {
+                BIO_printf(bio_err, "Server does not support STARTTLS.\n");
+                ret = 1;
+                goto shut;
+            }
+        }
+    }
+
+    for (;;) {
+        FD_ZERO(&readfds);
+        FD_ZERO(&writefds);
+
+        if ((SSL_version(con) == DTLS1_VERSION) &&
+            DTLSv1_get_timeout(con, &timeout))
+            timeoutp = &timeout;
+        else
+            timeoutp = NULL;
+
+        if (SSL_in_init(con) && !SSL_total_renegotiations(con)) {
+            in_init = 1;
+            tty_on = 0;
+        } else {
+            tty_on = 1;
+            if (in_init) {
+                in_init = 0;
+
+                if (servername != NULL && !SSL_session_reused(con)) {
+                    BIO_printf(bio_c_out,
+                               "Server did %sacknowledge servername extension.\n",
+                               tlsextcbp.ack ? "" : "not ");
+                }
+
+                if (sess_out) {
+                    BIO *stmp = BIO_new_file(sess_out, "w");
+                    if (stmp) {
+                        PEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con));
+                        BIO_free(stmp);
+                    } else
+                        BIO_printf(bio_err, "Error writing session file %s\n",
+                                   sess_out);
+                }
+                if (c_brief) {
+                    BIO_puts(bio_err, "CONNECTION ESTABLISHED\n");
+                    print_ssl_summary(con);
+                }
+
+                print_stuff(bio_c_out, con, full_log);
+                if (full_log > 0)
+                    full_log--;
+
+                if (starttls_proto) {
+                    BIO_write(bio_err, mbuf, mbuf_len);
+                    /* We don't need to know any more */
+                    if (!reconnect)
+                        starttls_proto = PROTO_OFF;
+                }
+
+                if (reconnect) {
+                    reconnect--;
+                    BIO_printf(bio_c_out,
+                               "drop connection and then reconnect\n");
+                    do_ssl_shutdown(con);
+                    SSL_set_connect_state(con);
+                    BIO_closesocket(SSL_get_fd(con));
+                    goto re_start;
+                }
+            }
+        }
+
+        ssl_pending = read_ssl && SSL_has_pending(con);
+
+        if (!ssl_pending) {
+#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS)
+            if (tty_on) {
+                /*
+                 * Note that select() returns when read _would not block_,
+                 * and EOF satisfies that.  To avoid a CPU-hogging loop,
+                 * set the flag so we exit.
+                 */
+                if (read_tty && !at_eof)
+                    openssl_fdset(fileno_stdin(), &readfds);
+#if !defined(OPENSSL_SYS_VMS)
+                if (write_tty)
+                    openssl_fdset(fileno_stdout(), &writefds);
+#endif
+            }
+            if (read_ssl)
+                openssl_fdset(SSL_get_fd(con), &readfds);
+            if (write_ssl)
+                openssl_fdset(SSL_get_fd(con), &writefds);
+#else
+            if (!tty_on || !write_tty) {
+                if (read_ssl)
+                    openssl_fdset(SSL_get_fd(con), &readfds);
+                if (write_ssl)
+                    openssl_fdset(SSL_get_fd(con), &writefds);
+            }
+#endif
+
+            /*
+             * Note: under VMS with SOCKETSHR the second parameter is
+             * currently of type (int *) whereas under other systems it is
+             * (void *) if you don't have a cast it will choke the compiler:
+             * if you do have a cast then you can either go for (int *) or
+             * (void *).
+             */
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
+            /*
+             * Under Windows/DOS we make the assumption that we can always
+             * write to the tty: therefore if we need to write to the tty we
+             * just fall through. Otherwise we timeout the select every
+             * second and see if there are any keypresses. Note: this is a
+             * hack, in a proper Windows application we wouldn't do this.
+             */
+            i = 0;
+            if (!write_tty) {
+                if (read_tty) {
+                    tv.tv_sec = 1;
+                    tv.tv_usec = 0;
+                    i = select(width, (void *)&readfds, (void *)&writefds,
+                               NULL, &tv);
+                    if (!i && (!has_stdin_waiting() || !read_tty))
+                        continue;
+                } else
+                    i = select(width, (void *)&readfds, (void *)&writefds,
+                               NULL, timeoutp);
+            }
+#else
+            i = select(width, (void *)&readfds, (void *)&writefds,
+                       NULL, timeoutp);
+#endif
+            if (i < 0) {
+                BIO_printf(bio_err, "bad select %d\n",
+                           get_last_socket_error());
+                goto shut;
+                /* goto end; */
+            }
+        }
+
+        if ((SSL_version(con) == DTLS1_VERSION)
+            && DTLSv1_handle_timeout(con) > 0) {
+            BIO_printf(bio_err, "TIMEOUT occurred\n");
+        }
+
+        if (!ssl_pending && FD_ISSET(SSL_get_fd(con), &writefds)) {
+            k = SSL_write(con, &(cbuf[cbuf_off]), (unsigned int)cbuf_len);
+            switch (SSL_get_error(con, k)) {
+            case SSL_ERROR_NONE:
+                cbuf_off += k;
+                cbuf_len -= k;
+                if (k <= 0)
+                    goto end;
+                /* we have done a  write(con,NULL,0); */
+                if (cbuf_len <= 0) {
+                    read_tty = 1;
+                    write_ssl = 0;
+                } else {        /* if (cbuf_len > 0) */
+
+                    read_tty = 0;
+                    write_ssl = 1;
+                }
+                break;
+            case SSL_ERROR_WANT_WRITE:
+                BIO_printf(bio_c_out, "write W BLOCK\n");
+                write_ssl = 1;
+                read_tty = 0;
+                break;
+            case SSL_ERROR_WANT_ASYNC:
+                BIO_printf(bio_c_out, "write A BLOCK\n");
+                wait_for_async(con);
+                write_ssl = 1;
+                read_tty = 0;
+                break;
+            case SSL_ERROR_WANT_READ:
+                BIO_printf(bio_c_out, "write R BLOCK\n");
+                write_tty = 0;
+                read_ssl = 1;
+                write_ssl = 0;
+                break;
+            case SSL_ERROR_WANT_X509_LOOKUP:
+                BIO_printf(bio_c_out, "write X BLOCK\n");
+                break;
+            case SSL_ERROR_ZERO_RETURN:
+                if (cbuf_len != 0) {
+                    BIO_printf(bio_c_out, "shutdown\n");
+                    ret = 0;
+                    goto shut;
+                } else {
+                    read_tty = 1;
+                    write_ssl = 0;
+                    break;
+                }
+
+            case SSL_ERROR_SYSCALL:
+                if ((k != 0) || (cbuf_len != 0)) {
+                    BIO_printf(bio_err, "write:errno=%d\n",
+                               get_last_socket_error());
+                    goto shut;
+                } else {
+                    read_tty = 1;
+                    write_ssl = 0;
+                }
+                break;
+            case SSL_ERROR_WANT_ASYNC_JOB:
+                /* This shouldn't ever happen in s_client - treat as an error */
+            case SSL_ERROR_SSL:
+                ERR_print_errors(bio_err);
+                goto shut;
+            }
+        }
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VMS)
+        /* Assume Windows/DOS/BeOS can always write */
+        else if (!ssl_pending && write_tty)
+#else
+        else if (!ssl_pending && FD_ISSET(fileno_stdout(), &writefds))
+#endif
+        {
+#ifdef CHARSET_EBCDIC
+            ascii2ebcdic(&(sbuf[sbuf_off]), &(sbuf[sbuf_off]), sbuf_len);
+#endif
+            i = raw_write_stdout(&(sbuf[sbuf_off]), sbuf_len);
+
+            if (i <= 0) {
+                BIO_printf(bio_c_out, "DONE\n");
+                ret = 0;
+                goto shut;
+                /* goto end; */
+            }
+
+            sbuf_len -= i;;
+            sbuf_off += i;
+            if (sbuf_len <= 0) {
+                read_ssl = 1;
+                write_tty = 0;
+            }
+        } else if (ssl_pending || FD_ISSET(SSL_get_fd(con), &readfds)) {
+#ifdef RENEG
+            {
+                static int iiii;
+                if (++iiii == 52) {
+                    SSL_renegotiate(con);
+                    iiii = 0;
+                }
+            }
+#endif
+            k = SSL_read(con, sbuf, 1024 /* BUFSIZZ */ );
+
+            switch (SSL_get_error(con, k)) {
+            case SSL_ERROR_NONE:
+                if (k <= 0)
+                    goto end;
+                sbuf_off = 0;
+                sbuf_len = k;
+
+                read_ssl = 0;
+                write_tty = 1;
+                break;
+            case SSL_ERROR_WANT_ASYNC:
+                BIO_printf(bio_c_out, "read A BLOCK\n");
+                wait_for_async(con);
+                write_tty = 0;
+                read_ssl = 1;
+                if ((read_tty == 0) && (write_ssl == 0))
+                    write_ssl = 1;
+                break;
+            case SSL_ERROR_WANT_WRITE:
+                BIO_printf(bio_c_out, "read W BLOCK\n");
+                write_ssl = 1;
+                read_tty = 0;
+                break;
+            case SSL_ERROR_WANT_READ:
+                BIO_printf(bio_c_out, "read R BLOCK\n");
+                write_tty = 0;
+                read_ssl = 1;
+                if ((read_tty == 0) && (write_ssl == 0))
+                    write_ssl = 1;
+                break;
+            case SSL_ERROR_WANT_X509_LOOKUP:
+                BIO_printf(bio_c_out, "read X BLOCK\n");
+                break;
+            case SSL_ERROR_SYSCALL:
+                ret = get_last_socket_error();
+                if (c_brief)
+                    BIO_puts(bio_err, "CONNECTION CLOSED BY SERVER\n");
+                else
+                    BIO_printf(bio_err, "read:errno=%d\n", ret);
+                goto shut;
+            case SSL_ERROR_ZERO_RETURN:
+                BIO_printf(bio_c_out, "closed\n");
+                ret = 0;
+                goto shut;
+            case SSL_ERROR_WANT_ASYNC_JOB:
+                /* This shouldn't ever happen in s_client. Treat as an error */
+            case SSL_ERROR_SSL:
+                ERR_print_errors(bio_err);
+                goto shut;
+                /* break; */
+            }
+        }
+/* OPENSSL_SYS_MSDOS includes OPENSSL_SYS_WINDOWS */
+#if defined(OPENSSL_SYS_MSDOS)
+        else if (has_stdin_waiting())
+#else
+        else if (FD_ISSET(fileno_stdin(), &readfds))
+#endif
+        {
+            if (crlf) {
+                int j, lf_num;
+
+                i = raw_read_stdin(cbuf, BUFSIZZ / 2);
+                lf_num = 0;
+                /* both loops are skipped when i <= 0 */
+                for (j = 0; j < i; j++)
+                    if (cbuf[j] == '\n')
+                        lf_num++;
+                for (j = i - 1; j >= 0; j--) {
+                    cbuf[j + lf_num] = cbuf[j];
+                    if (cbuf[j] == '\n') {
+                        lf_num--;
+                        i++;
+                        cbuf[j + lf_num] = '\r';
+                    }
+                }
+                assert(lf_num == 0);
+            } else
+                i = raw_read_stdin(cbuf, BUFSIZZ);
+#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS)
+            if (i == 0)
+                at_eof = 1;
+#endif
+
+            if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q' && cmdletters))) {
+                BIO_printf(bio_err, "DONE\n");
+                ret = 0;
+                goto shut;
+            }
+
+            if ((!c_ign_eof) && (cbuf[0] == 'R' && cmdletters)) {
+                BIO_printf(bio_err, "RENEGOTIATING\n");
+                SSL_renegotiate(con);
+                cbuf_len = 0;
+            }
+#ifndef OPENSSL_NO_HEARTBEATS
+            else if ((!c_ign_eof) && (cbuf[0] == 'B' && cmdletters)) {
+                BIO_printf(bio_err, "HEARTBEATING\n");
+                SSL_heartbeat(con);
+                cbuf_len = 0;
+            }
+#endif
+            else {
+                cbuf_len = i;
+                cbuf_off = 0;
+#ifdef CHARSET_EBCDIC
+                ebcdic2ascii(cbuf, cbuf, i);
+#endif
+            }
+
+            write_ssl = 1;
+            read_tty = 0;
+        }
+    }
+
+    ret = 0;
+ shut:
+    if (in_init)
+        print_stuff(bio_c_out, con, full_log);
+    do_ssl_shutdown(con);
+#if defined(OPENSSL_SYS_WINDOWS)
+    /*
+     * Give the socket time to send its last data before we close it.
+     * No amount of setting SO_LINGER etc on the socket seems to persuade
+     * Windows to send the data before closing the socket...but sleeping
+     * for a short time seems to do it (units in ms)
+     * TODO: Find a better way to do this
+     */
+    Sleep(50);
+#endif
+    BIO_closesocket(SSL_get_fd(con));
+ end:
+    if (con != NULL) {
+        if (prexit != 0)
+            print_stuff(bio_c_out, con, 1);
+        SSL_free(con);
+    }
+#if !defined(OPENSSL_NO_NEXTPROTONEG)
+    OPENSSL_free(next_proto.data);
+#endif
+    SSL_CTX_free(ctx);
+    X509_free(cert);
+    sk_X509_CRL_pop_free(crls, X509_CRL_free);
+    EVP_PKEY_free(key);
+    sk_X509_pop_free(chain, X509_free);
+    OPENSSL_free(pass);
+#ifndef OPENSSL_NO_SRP
+    OPENSSL_free(srp_arg.srppassin);
+#endif
+    OPENSSL_free(connectstr);
+    OPENSSL_free(host);
+    OPENSSL_free(port);
+    X509_VERIFY_PARAM_free(vpm);
+    ssl_excert_free(exc);
+    sk_OPENSSL_STRING_free(ssl_args);
+    sk_OPENSSL_STRING_free(dane_tlsa_rrset);
+    SSL_CONF_CTX_free(cctx);
+    OPENSSL_clear_free(cbuf, BUFSIZZ);
+    OPENSSL_clear_free(sbuf, BUFSIZZ);
+    OPENSSL_clear_free(mbuf, BUFSIZZ);
+    release_engine(e);
+    BIO_free(bio_c_out);
+    bio_c_out = NULL;
+    BIO_free(bio_c_msg);
+    bio_c_msg = NULL;
+    return (ret);
+}
+
+static void print_stuff(BIO *bio, SSL *s, int full)
+{
+    X509 *peer = NULL;
+    char buf[BUFSIZ];
+    STACK_OF(X509) *sk;
+    STACK_OF(X509_NAME) *sk2;
+    const SSL_CIPHER *c;
+    X509_NAME *xn;
+    int i;
+#ifndef OPENSSL_NO_COMP
+    const COMP_METHOD *comp, *expansion;
+#endif
+    unsigned char *exportedkeymat;
+#ifndef OPENSSL_NO_CT
+    const SSL_CTX *ctx = SSL_get_SSL_CTX(s);
+#endif
+
+    if (full) {
+        int got_a_chain = 0;
+
+        sk = SSL_get_peer_cert_chain(s);
+        if (sk != NULL) {
+            got_a_chain = 1;
+
+            BIO_printf(bio, "---\nCertificate chain\n");
+            for (i = 0; i < sk_X509_num(sk); i++) {
+                X509_NAME_oneline(X509_get_subject_name(sk_X509_value(sk, i)),
+                                  buf, sizeof buf);
+                BIO_printf(bio, "%2d s:%s\n", i, buf);
+                X509_NAME_oneline(X509_get_issuer_name(sk_X509_value(sk, i)),
+                                  buf, sizeof buf);
+                BIO_printf(bio, "   i:%s\n", buf);
+                if (c_showcerts)
+                    PEM_write_bio_X509(bio, sk_X509_value(sk, i));
+            }
+        }
+
+        BIO_printf(bio, "---\n");
+        peer = SSL_get_peer_certificate(s);
+        if (peer != NULL) {
+            BIO_printf(bio, "Server certificate\n");
+
+            /* Redundant if we showed the whole chain */
+            if (!(c_showcerts && got_a_chain))
+                PEM_write_bio_X509(bio, peer);
+            X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof buf);
+            BIO_printf(bio, "subject=%s\n", buf);
+            X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf);
+            BIO_printf(bio, "issuer=%s\n", buf);
+        } else
+            BIO_printf(bio, "no peer certificate available\n");
+
+        sk2 = SSL_get_client_CA_list(s);
+        if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0)) {
+            BIO_printf(bio, "---\nAcceptable client certificate CA names\n");
+            for (i = 0; i < sk_X509_NAME_num(sk2); i++) {
+                xn = sk_X509_NAME_value(sk2, i);
+                X509_NAME_oneline(xn, buf, sizeof(buf));
+                BIO_write(bio, buf, strlen(buf));
+                BIO_write(bio, "\n", 1);
+            }
+        } else {
+            BIO_printf(bio, "---\nNo client certificate CA names sent\n");
+        }
+
+        ssl_print_sigalgs(bio, s);
+        ssl_print_tmp_key(bio, s);
+
+#ifndef OPENSSL_NO_CT
+        /*
+         * When the SSL session is anonymous, or resumed via an abbreviated
+         * handshake, no SCTs are provided as part of the handshake.  While in
+         * a resumed session SCTs may be present in the session's certificate,
+         * no callbacks are invoked to revalidate these, and in any case that
+         * set of SCTs may be incomplete.  Thus it makes little sense to
+         * attempt to display SCTs from a resumed session's certificate, and of
+         * course none are associated with an anonymous peer.
+         */
+        if (peer != NULL && !SSL_session_reused(s) && SSL_ct_is_enabled(s)) {
+            const STACK_OF(SCT) *scts = SSL_get0_peer_scts(s);
+            int sct_count = scts != NULL ? sk_SCT_num(scts) : 0;
+
+            BIO_printf(bio, "---\nSCTs present (%i)\n", sct_count);
+            if (sct_count > 0) {
+                const CTLOG_STORE *log_store = SSL_CTX_get0_ctlog_store(ctx);
+
+                BIO_printf(bio, "---\n");
+                for (i = 0; i < sct_count; ++i) {
+                    SCT *sct = sk_SCT_value(scts, i);
+
+                    BIO_printf(bio, "SCT validation status: %s\n",
+                               SCT_validation_status_string(sct));
+                    SCT_print(sct, bio, 0, log_store);
+                    if (i < sct_count - 1)
+                        BIO_printf(bio, "\n---\n");
+                }
+                BIO_printf(bio, "\n");
+            }
+        }
+#endif
+
+        BIO_printf(bio,
+                   "---\nSSL handshake has read %" PRIu64
+                   " bytes and written %" PRIu64 " bytes\n",
+                   BIO_number_read(SSL_get_rbio(s)),
+                   BIO_number_written(SSL_get_wbio(s)));
+    }
+    print_verify_detail(s, bio);
+    BIO_printf(bio, (SSL_session_reused(s) ? "---\nReused, " : "---\nNew, "));
+    c = SSL_get_current_cipher(s);
+    BIO_printf(bio, "%s, Cipher is %s\n",
+               SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
+    if (peer != NULL) {
+        EVP_PKEY *pktmp;
+
+        pktmp = X509_get0_pubkey(peer);
+        BIO_printf(bio, "Server public key is %d bit\n",
+                   EVP_PKEY_bits(pktmp));
+    }
+    BIO_printf(bio, "Secure Renegotiation IS%s supported\n",
+               SSL_get_secure_renegotiation_support(s) ? "" : " NOT");
+#ifndef OPENSSL_NO_COMP
+    comp = SSL_get_current_compression(s);
+    expansion = SSL_get_current_expansion(s);
+    BIO_printf(bio, "Compression: %s\n",
+               comp ? SSL_COMP_get_name(comp) : "NONE");
+    BIO_printf(bio, "Expansion: %s\n",
+               expansion ? SSL_COMP_get_name(expansion) : "NONE");
+#endif
+
+#ifdef SSL_DEBUG
+    {
+        /* Print out local port of connection: useful for debugging */
+        int sock;
+        union BIO_sock_info_u info;
+
+        sock = SSL_get_fd(s);
+        if ((info.addr = BIO_ADDR_new()) != NULL
+            && BIO_sock_info(sock, BIO_SOCK_INFO_ADDRESS, &info)) {
+            BIO_printf(bio_c_out, "LOCAL PORT is %u\n",
+                       ntohs(BIO_ADDR_rawport(info.addr)));
+        }
+        BIO_ADDR_free(info.addr);
+    }
+#endif
+
+#if !defined(OPENSSL_NO_NEXTPROTONEG)
+    if (next_proto.status != -1) {
+        const unsigned char *proto;
+        unsigned int proto_len;
+        SSL_get0_next_proto_negotiated(s, &proto, &proto_len);
+        BIO_printf(bio, "Next protocol: (%d) ", next_proto.status);
+        BIO_write(bio, proto, proto_len);
+        BIO_write(bio, "\n", 1);
+    }
+#endif
+    {
+        const unsigned char *proto;
+        unsigned int proto_len;
+        SSL_get0_alpn_selected(s, &proto, &proto_len);
+        if (proto_len > 0) {
+            BIO_printf(bio, "ALPN protocol: ");
+            BIO_write(bio, proto, proto_len);
+            BIO_write(bio, "\n", 1);
+        } else
+            BIO_printf(bio, "No ALPN negotiated\n");
+    }
+
+#ifndef OPENSSL_NO_SRTP
+    {
+        SRTP_PROTECTION_PROFILE *srtp_profile =
+            SSL_get_selected_srtp_profile(s);
+
+        if (srtp_profile)
+            BIO_printf(bio, "SRTP Extension negotiated, profile=%s\n",
+                       srtp_profile->name);
+    }
+#endif
+
+    SSL_SESSION_print(bio, SSL_get_session(s));
+    if (SSL_get_session(s) != NULL && keymatexportlabel != NULL) {
+        BIO_printf(bio, "Keying material exporter:\n");
+        BIO_printf(bio, "    Label: '%s'\n", keymatexportlabel);
+        BIO_printf(bio, "    Length: %i bytes\n", keymatexportlen);
+        exportedkeymat = app_malloc(keymatexportlen, "export key");
+        if (!SSL_export_keying_material(s, exportedkeymat,
+                                        keymatexportlen,
+                                        keymatexportlabel,
+                                        strlen(keymatexportlabel),
+                                        NULL, 0, 0)) {
+            BIO_printf(bio, "    Error\n");
+        } else {
+            BIO_printf(bio, "    Keying material: ");
+            for (i = 0; i < keymatexportlen; i++)
+                BIO_printf(bio, "%02X", exportedkeymat[i]);
+            BIO_printf(bio, "\n");
+        }
+        OPENSSL_free(exportedkeymat);
+    }
+    BIO_printf(bio, "---\n");
+    X509_free(peer);
+    /* flush, or debugging output gets mixed with http response */
+    (void)BIO_flush(bio);
+}
+
+# ifndef OPENSSL_NO_OCSP
+static int ocsp_resp_cb(SSL *s, void *arg)
+{
+    const unsigned char *p;
+    int len;
+    OCSP_RESPONSE *rsp;
+    len = SSL_get_tlsext_status_ocsp_resp(s, &p);
+    BIO_puts(arg, "OCSP response: ");
+    if (!p) {
+        BIO_puts(arg, "no response sent\n");
+        return 1;
+    }
+    rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
+    if (!rsp) {
+        BIO_puts(arg, "response parse error\n");
+        BIO_dump_indent(arg, (char *)p, len, 4);
+        return 0;
+    }
+    BIO_puts(arg, "\n======================================\n");
+    OCSP_RESPONSE_print(arg, rsp, 0);
+    BIO_puts(arg, "======================================\n");
+    OCSP_RESPONSE_free(rsp);
+    return 1;
+}
+# endif
+
+#endif                          /* OPENSSL_NO_SOCK */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/s_server.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/s_server.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/s_server.c	(revision 331)
@@ -0,0 +1,3301 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if defined(_WIN32)
+/* Included before async.h to avoid some warnings */
+# include <windows.h>
+#endif
+
+#include <openssl/e_os2.h>
+#include <openssl/async.h>
+#include <openssl/ssl.h>
+
+#ifndef OPENSSL_NO_SOCK
+
+/*
+ * With IPv6, it looks like Digital has mixed up the proper order of
+ * recursive header file inclusion, resulting in the compiler complaining
+ * that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which is
+ * needed to have fileno() declared correctly...  So let's define u_int
+ */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
+# define __U_INT
+typedef unsigned int u_int;
+#endif
+
+#include <openssl/lhash.h>
+#include <openssl/bn.h>
+#define USE_SOCKETS
+#include "apps.h"
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/x509.h>
+#include <openssl/ssl.h>
+#include <openssl/rand.h>
+#include <openssl/ocsp.h>
+#ifndef OPENSSL_NO_DH
+# include <openssl/dh.h>
+#endif
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_SRP
+# include <openssl/srp.h>
+#endif
+#include "s_apps.h"
+#include "timeouts.h"
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
+static int not_resumable_sess_cb(SSL *s, int is_forward_secure);
+static int sv_body(int s, int stype, unsigned char *context);
+static int www_body(int s, int stype, unsigned char *context);
+static int rev_body(int s, int stype, unsigned char *context);
+static void close_accept_socket(void);
+static int init_ssl_connection(SSL *s);
+static void print_stats(BIO *bp, SSL_CTX *ctx);
+static int generate_session_id(const SSL *ssl, unsigned char *id,
+                               unsigned int *id_len);
+static void init_session_cache_ctx(SSL_CTX *sctx);
+static void free_sessions(void);
+#ifndef OPENSSL_NO_DH
+static DH *load_dh_param(const char *dhfile);
+#endif
+
+/* static int load_CA(SSL_CTX *ctx, char *file);*/
+
+static const int bufsize = 16 * 1024;
+static int accept_socket = -1;
+
+#define TEST_CERT       "server.pem"
+#define TEST_CERT2      "server2.pem"
+
+static int s_nbio = 0;
+static int s_nbio_test = 0;
+static int s_crlf = 0;
+static SSL_CTX *ctx = NULL;
+static SSL_CTX *ctx2 = NULL;
+static int www = 0;
+
+static BIO *bio_s_out = NULL;
+static BIO *bio_s_msg = NULL;
+static int s_debug = 0;
+static int s_tlsextdebug = 0;
+static int s_msg = 0;
+static int s_quiet = 0;
+static int s_ign_eof = 0;
+static int s_brief = 0;
+
+static char *keymatexportlabel = NULL;
+static int keymatexportlen = 20;
+
+static int async = 0;
+
+static const char *session_id_prefix = NULL;
+
+#ifndef OPENSSL_NO_DTLS
+static int enable_timeouts = 0;
+static long socket_mtu;
+
+#endif
+static int dtlslisten = 0;
+
+#ifndef OPENSSL_NO_PSK
+static char *psk_identity = "Client_identity";
+char *psk_key = NULL;           /* by default PSK is not used */
+
+static unsigned int psk_server_cb(SSL *ssl, const char *identity,
+                                  unsigned char *psk,
+                                  unsigned int max_psk_len)
+{
+    long key_len = 0;
+    unsigned char *key;
+
+    if (s_debug)
+        BIO_printf(bio_s_out, "psk_server_cb\n");
+    if (!identity) {
+        BIO_printf(bio_err, "Error: client did not send PSK identity\n");
+        goto out_err;
+    }
+    if (s_debug)
+        BIO_printf(bio_s_out, "identity_len=%d identity=%s\n",
+                   (int)strlen(identity), identity);
+
+    /* here we could lookup the given identity e.g. from a database */
+    if (strcmp(identity, psk_identity) != 0) {
+        BIO_printf(bio_s_out, "PSK error: client identity not found"
+                   " (got '%s' expected '%s')\n", identity, psk_identity);
+        goto out_err;
+    }
+    if (s_debug)
+        BIO_printf(bio_s_out, "PSK client identity found\n");
+
+    /* convert the PSK key to binary */
+    key = OPENSSL_hexstr2buf(psk_key, &key_len);
+    if (key == NULL) {
+        BIO_printf(bio_err, "Could not convert PSK key '%s' to buffer\n",
+                   psk_key);
+        return 0;
+    }
+    if (key_len > (int)max_psk_len) {
+        BIO_printf(bio_err,
+                   "psk buffer of callback is too small (%d) for key (%ld)\n",
+                   max_psk_len, key_len);
+        OPENSSL_free(key);
+        return 0;
+    }
+
+    memcpy(psk, key, key_len);
+    OPENSSL_free(key);
+
+    if (s_debug)
+        BIO_printf(bio_s_out, "fetched PSK len=%ld\n", key_len);
+    return key_len;
+ out_err:
+    if (s_debug)
+        BIO_printf(bio_err, "Error in PSK server callback\n");
+    (void)BIO_flush(bio_err);
+    (void)BIO_flush(bio_s_out);
+    return 0;
+}
+#endif
+
+#ifndef OPENSSL_NO_SRP
+/* This is a context that we pass to callbacks */
+typedef struct srpsrvparm_st {
+    char *login;
+    SRP_VBASE *vb;
+    SRP_user_pwd *user;
+} srpsrvparm;
+
+/*
+ * This callback pretends to require some asynchronous logic in order to
+ * obtain a verifier. When the callback is called for a new connection we
+ * return with a negative value. This will provoke the accept etc to return
+ * with an LOOKUP_X509. The main logic of the reinvokes the suspended call
+ * (which would normally occur after a worker has finished) and we set the
+ * user parameters.
+ */
+static int ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
+{
+    srpsrvparm *p = (srpsrvparm *) arg;
+    int ret = SSL3_AL_FATAL;
+
+    if (p->login == NULL && p->user == NULL) {
+        p->login = SSL_get_srp_username(s);
+        BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login);
+        return (-1);
+    }
+
+    if (p->user == NULL) {
+        BIO_printf(bio_err, "User %s doesn't exist\n", p->login);
+        goto err;
+    }
+
+    if (SSL_set_srp_server_param
+        (s, p->user->N, p->user->g, p->user->s, p->user->v,
+         p->user->info) < 0) {
+        *ad = SSL_AD_INTERNAL_ERROR;
+        goto err;
+    }
+    BIO_printf(bio_err,
+               "SRP parameters set: username = \"%s\" info=\"%s\" \n",
+               p->login, p->user->info);
+    ret = SSL_ERROR_NONE;
+
+ err:
+    SRP_user_pwd_free(p->user);
+    p->user = NULL;
+    p->login = NULL;
+    return ret;
+}
+
+#endif
+
+static int local_argc = 0;
+static char **local_argv;
+
+#ifdef CHARSET_EBCDIC
+static int ebcdic_new(BIO *bi);
+static int ebcdic_free(BIO *a);
+static int ebcdic_read(BIO *b, char *out, int outl);
+static int ebcdic_write(BIO *b, const char *in, int inl);
+static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr);
+static int ebcdic_gets(BIO *bp, char *buf, int size);
+static int ebcdic_puts(BIO *bp, const char *str);
+
+# define BIO_TYPE_EBCDIC_FILTER  (18|0x0200)
+static BIO_METHOD *methods_ebcdic = NULL;
+
+/* This struct is "unwarranted chumminess with the compiler." */
+typedef struct {
+    size_t alloced;
+    char buff[1];
+} EBCDIC_OUTBUFF;
+
+static const BIO_METHOD *BIO_f_ebcdic_filter()
+{
+    if (methods_ebcdic == NULL) {
+        methods_ebcdic = BIO_meth_new(BIO_TYPE_EBCDIC_FILTER,
+                                      "EBCDIC/ASCII filter");
+        if (methods_ebcdic == NULL
+            || !BIO_meth_set_write(methods_ebcdic, ebcdic_write)
+            || !BIO_meth_set_read(methods_ebcdic, ebcdic_read)
+            || !BIO_meth_set_puts(methods_ebcdic, ebcdic_puts)
+            || !BIO_meth_set_gets(methods_ebcdic, ebcdic_gets)
+            || !BIO_meth_set_ctrl(methods_ebcdic, ebcdic_ctrl)
+            || !BIO_meth_set_create(methods_ebcdic, ebcdic_new)
+            || !BIO_meth_set_destroy(methods_ebcdic, ebcdic_free))
+            return NULL;
+    }
+    return methods_ebcdic;
+}
+
+static int ebcdic_new(BIO *bi)
+{
+    EBCDIC_OUTBUFF *wbuf;
+
+    wbuf = app_malloc(sizeof(*wbuf) + 1024, "ebcdic wbuf");
+    wbuf->alloced = 1024;
+    wbuf->buff[0] = '\0';
+
+    BIO_set_data(bi, wbuf);
+    BIO_set_init(bi, 1);
+    return 1;
+}
+
+static int ebcdic_free(BIO *a)
+{
+    EBCDIC_OUTBUFF *wbuf;
+
+    if (a == NULL)
+        return 0;
+    wbuf = BIO_get_data(a);
+    OPENSSL_free(wbuf);
+    BIO_set_data(a, NULL);
+    BIO_set_init(a, 0);
+
+    return 1;
+}
+
+static int ebcdic_read(BIO *b, char *out, int outl)
+{
+    int ret = 0;
+    BIO *next = BIO_next(b);
+
+    if (out == NULL || outl == 0)
+        return (0);
+    if (next == NULL)
+        return (0);
+
+    ret = BIO_read(next, out, outl);
+    if (ret > 0)
+        ascii2ebcdic(out, out, ret);
+    return ret;
+}
+
+static int ebcdic_write(BIO *b, const char *in, int inl)
+{
+    EBCDIC_OUTBUFF *wbuf;
+    BIO *next = BIO_next(b);
+    int ret = 0;
+    int num;
+
+    if ((in == NULL) || (inl <= 0))
+        return (0);
+    if (next == NULL)
+        return 0;
+
+    wbuf = (EBCDIC_OUTBUFF *) BIO_get_data(b);
+
+    if (inl > (num = wbuf->alloced)) {
+        num = num + num;        /* double the size */
+        if (num < inl)
+            num = inl;
+        OPENSSL_free(wbuf);
+        wbuf = app_malloc(sizeof(*wbuf) + num, "grow ebcdic wbuf");
+
+        wbuf->alloced = num;
+        wbuf->buff[0] = '\0';
+
+        BIO_set_data(b, wbuf);
+    }
+
+    ebcdic2ascii(wbuf->buff, in, inl);
+
+    ret = BIO_write(next, wbuf->buff, inl);
+
+    return (ret);
+}
+
+static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    long ret;
+    BIO *next = BIO_next(b);
+
+    if (next == NULL)
+        return (0);
+    switch (cmd) {
+    case BIO_CTRL_DUP:
+        ret = 0L;
+        break;
+    default:
+        ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+    }
+    return (ret);
+}
+
+static int ebcdic_gets(BIO *bp, char *buf, int size)
+{
+    int i, ret = 0;
+    BIO *next = BIO_next(bp);
+
+    if (next == NULL)
+        return 0;
+/*      return(BIO_gets(bp->next_bio,buf,size));*/
+    for (i = 0; i < size - 1; ++i) {
+        ret = ebcdic_read(bp, &buf[i], 1);
+        if (ret <= 0)
+            break;
+        else if (buf[i] == '\n') {
+            ++i;
+            break;
+        }
+    }
+    if (i < size)
+        buf[i] = '\0';
+    return (ret < 0 && i == 0) ? ret : i;
+}
+
+static int ebcdic_puts(BIO *bp, const char *str)
+{
+    if (BIO_next(bp) == NULL)
+        return 0;
+    return ebcdic_write(bp, str, strlen(str));
+}
+#endif
+
+/* This is a context that we pass to callbacks */
+typedef struct tlsextctx_st {
+    char *servername;
+    BIO *biodebug;
+    int extension_error;
+} tlsextctx;
+
+static int ssl_servername_cb(SSL *s, int *ad, void *arg)
+{
+    tlsextctx *p = (tlsextctx *) arg;
+    const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
+    if (servername && p->biodebug)
+        BIO_printf(p->biodebug, "Hostname in TLS extension: \"%s\"\n",
+                   servername);
+
+    if (!p->servername)
+        return SSL_TLSEXT_ERR_NOACK;
+
+    if (servername) {
+        if (strcasecmp(servername, p->servername))
+            return p->extension_error;
+        if (ctx2) {
+            BIO_printf(p->biodebug, "Switching server context.\n");
+            SSL_set_SSL_CTX(s, ctx2);
+        }
+    }
+    return SSL_TLSEXT_ERR_OK;
+}
+
+/* Structure passed to cert status callback */
+
+typedef struct tlsextstatusctx_st {
+    /* Default responder to use */
+    char *host, *path, *port;
+    int use_ssl;
+    int timeout;
+    int verbose;
+} tlsextstatusctx;
+
+static tlsextstatusctx tlscstatp = { NULL, NULL, NULL, 0, -1, 0 };
+
+#ifndef OPENSSL_NO_OCSP
+/*
+ * Certificate Status callback. This is called when a client includes a
+ * certificate status request extension. This is a simplified version. It
+ * examines certificates each time and makes one OCSP responder query for
+ * each request. A full version would store details such as the OCSP
+ * certificate IDs and minimise the number of OCSP responses by caching them
+ * until they were considered "expired".
+ */
+
+static int cert_status_cb(SSL *s, void *arg)
+{
+    tlsextstatusctx *srctx = arg;
+    char *host = NULL, *port = NULL, *path = NULL;
+    int use_ssl;
+    unsigned char *rspder = NULL;
+    int rspderlen;
+    STACK_OF(OPENSSL_STRING) *aia = NULL;
+    X509 *x = NULL;
+    X509_STORE_CTX *inctx = NULL;
+    X509_OBJECT *obj;
+    OCSP_REQUEST *req = NULL;
+    OCSP_RESPONSE *resp = NULL;
+    OCSP_CERTID *id = NULL;
+    STACK_OF(X509_EXTENSION) *exts;
+    int ret = SSL_TLSEXT_ERR_NOACK;
+    int i;
+
+    if (srctx->verbose)
+        BIO_puts(bio_err, "cert_status: callback called\n");
+    /* Build up OCSP query from server certificate */
+    x = SSL_get_certificate(s);
+    aia = X509_get1_ocsp(x);
+    if (aia) {
+        if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0),
+                            &host, &port, &path, &use_ssl)) {
+            BIO_puts(bio_err, "cert_status: can't parse AIA URL\n");
+            goto err;
+        }
+        if (srctx->verbose)
+            BIO_printf(bio_err, "cert_status: AIA URL: %s\n",
+                       sk_OPENSSL_STRING_value(aia, 0));
+    } else {
+        if (!srctx->host) {
+            BIO_puts(bio_err,
+                     "cert_status: no AIA and no default responder URL\n");
+            goto done;
+        }
+        host = srctx->host;
+        path = srctx->path;
+        port = srctx->port;
+        use_ssl = srctx->use_ssl;
+    }
+
+    inctx = X509_STORE_CTX_new();
+    if (inctx == NULL)
+        goto err;
+    if (!X509_STORE_CTX_init(inctx,
+                             SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)),
+                             NULL, NULL))
+        goto err;
+    obj = X509_STORE_CTX_get_obj_by_subject(inctx, X509_LU_X509,
+                                            X509_get_issuer_name(x));
+    if (obj == NULL) {
+        BIO_puts(bio_err, "cert_status: Can't retrieve issuer certificate.\n");
+        goto done;
+    }
+    id = OCSP_cert_to_id(NULL, x, X509_OBJECT_get0_X509(obj));
+    X509_OBJECT_free(obj);
+    if (!id)
+        goto err;
+    req = OCSP_REQUEST_new();
+    if (req == NULL)
+        goto err;
+    if (!OCSP_request_add0_id(req, id))
+        goto err;
+    id = NULL;
+    /* Add any extensions to the request */
+    SSL_get_tlsext_status_exts(s, &exts);
+    for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
+        X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
+        if (!OCSP_REQUEST_add_ext(req, ext, -1))
+            goto err;
+    }
+    resp = process_responder(req, host, path, port, use_ssl, NULL,
+                             srctx->timeout);
+    if (!resp) {
+        BIO_puts(bio_err, "cert_status: error querying responder\n");
+        goto done;
+    }
+    rspderlen = i2d_OCSP_RESPONSE(resp, &rspder);
+    if (rspderlen <= 0)
+        goto err;
+    SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen);
+    if (srctx->verbose) {
+        BIO_puts(bio_err, "cert_status: ocsp response sent:\n");
+        OCSP_RESPONSE_print(bio_err, resp, 2);
+    }
+    ret = SSL_TLSEXT_ERR_OK;
+    goto done;
+
+ err:
+    ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+ done:
+    if (ret != SSL_TLSEXT_ERR_OK)
+        ERR_print_errors(bio_err);
+    if (aia) {
+        OPENSSL_free(host);
+        OPENSSL_free(path);
+        OPENSSL_free(port);
+        X509_email_free(aia);
+    }
+    OCSP_CERTID_free(id);
+    OCSP_REQUEST_free(req);
+    OCSP_RESPONSE_free(resp);
+    X509_STORE_CTX_free(inctx);
+    return ret;
+}
+#endif
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+/* This is the context that we pass to next_proto_cb */
+typedef struct tlsextnextprotoctx_st {
+    unsigned char *data;
+    unsigned int len;
+} tlsextnextprotoctx;
+
+static int next_proto_cb(SSL *s, const unsigned char **data,
+                         unsigned int *len, void *arg)
+{
+    tlsextnextprotoctx *next_proto = arg;
+
+    *data = next_proto->data;
+    *len = next_proto->len;
+
+    return SSL_TLSEXT_ERR_OK;
+}
+#endif                         /* ndef OPENSSL_NO_NEXTPROTONEG */
+
+/* This the context that we pass to alpn_cb */
+typedef struct tlsextalpnctx_st {
+    unsigned char *data;
+    size_t len;
+} tlsextalpnctx;
+
+static int alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen,
+                   const unsigned char *in, unsigned int inlen, void *arg)
+{
+    tlsextalpnctx *alpn_ctx = arg;
+
+    if (!s_quiet) {
+        /* We can assume that |in| is syntactically valid. */
+        unsigned int i;
+        BIO_printf(bio_s_out, "ALPN protocols advertised by the client: ");
+        for (i = 0; i < inlen;) {
+            if (i)
+                BIO_write(bio_s_out, ", ", 2);
+            BIO_write(bio_s_out, &in[i + 1], in[i]);
+            i += in[i] + 1;
+        }
+        BIO_write(bio_s_out, "\n", 1);
+    }
+
+    if (SSL_select_next_proto
+        ((unsigned char **)out, outlen, alpn_ctx->data, alpn_ctx->len, in,
+         inlen) != OPENSSL_NPN_NEGOTIATED) {
+        return SSL_TLSEXT_ERR_NOACK;
+    }
+
+    if (!s_quiet) {
+        BIO_printf(bio_s_out, "ALPN protocols selected: ");
+        BIO_write(bio_s_out, *out, *outlen);
+        BIO_write(bio_s_out, "\n", 1);
+    }
+
+    return SSL_TLSEXT_ERR_OK;
+}
+
+static int not_resumable_sess_cb(SSL *s, int is_forward_secure)
+{
+    /* disable resumption for sessions with forward secure ciphers */
+    return is_forward_secure;
+}
+
+#ifndef OPENSSL_NO_SRP
+static srpsrvparm srp_callback_parm;
+#endif
+#ifndef OPENSSL_NO_SRTP
+static char *srtp_profiles = NULL;
+#endif
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ENGINE,
+    OPT_4, OPT_6, OPT_ACCEPT, OPT_PORT, OPT_UNIX, OPT_UNLINK, OPT_NACCEPT,
+    OPT_VERIFY, OPT_UPPER_V_VERIFY, OPT_CONTEXT, OPT_CERT, OPT_CRL,
+    OPT_CRL_DOWNLOAD, OPT_SERVERINFO, OPT_CERTFORM, OPT_KEY, OPT_KEYFORM,
+    OPT_PASS, OPT_CERT_CHAIN, OPT_DHPARAM, OPT_DCERTFORM, OPT_DCERT,
+    OPT_DKEYFORM, OPT_DPASS, OPT_DKEY, OPT_DCERT_CHAIN, OPT_NOCERT,
+    OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH, OPT_NO_CACHE,
+    OPT_EXT_CACHE, OPT_CRLFORM, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET,
+    OPT_BUILD_CHAIN, OPT_CAFILE, OPT_NOCAFILE, OPT_CHAINCAFILE,
+    OPT_VERIFYCAFILE, OPT_NBIO, OPT_NBIO_TEST, OPT_IGN_EOF, OPT_NO_IGN_EOF,
+    OPT_DEBUG, OPT_TLSEXTDEBUG, OPT_STATUS, OPT_STATUS_VERBOSE,
+    OPT_STATUS_TIMEOUT, OPT_STATUS_URL, OPT_MSG, OPT_MSGFILE, OPT_TRACE,
+    OPT_SECURITY_DEBUG, OPT_SECURITY_DEBUG_VERBOSE, OPT_STATE, OPT_CRLF,
+    OPT_QUIET, OPT_BRIEF, OPT_NO_DHE,
+    OPT_NO_RESUME_EPHEMERAL, OPT_PSK_HINT, OPT_PSK, OPT_SRPVFILE,
+    OPT_SRPUSERSEED, OPT_REV, OPT_WWW, OPT_UPPER_WWW, OPT_HTTP, OPT_ASYNC,
+    OPT_SSL_CONFIG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF,
+    OPT_SSL3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
+    OPT_DTLS1_2, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN,
+    OPT_ID_PREFIX, OPT_RAND, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
+    OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN,
+    OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
+    OPT_S_ENUM,
+    OPT_V_ENUM,
+    OPT_X_ENUM
+} OPTION_CHOICE;
+
+OPTIONS s_server_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"port", OPT_PORT, 'p',
+     "TCP/IP port to listen on for connections (default is " PORT ")"},
+    {"accept", OPT_ACCEPT, 's',
+     "TCP/IP optional host and port to listen on for connections (default is *:" PORT ")"},
+#ifdef AF_UNIX
+    {"unix", OPT_UNIX, 's', "Unix domain socket to accept on"},
+#endif
+    {"4", OPT_4, '-', "Use IPv4 only"},
+    {"6", OPT_6, '-', "Use IPv6 only"},
+#ifdef AF_UNIX
+    {"unlink", OPT_UNLINK, '-', "For -unix, unlink existing socket first"},
+#endif
+    {"context", OPT_CONTEXT, 's', "Set session ID context"},
+    {"verify", OPT_VERIFY, 'n', "Turn on peer certificate verification"},
+    {"Verify", OPT_UPPER_V_VERIFY, 'n',
+     "Turn on peer certificate verification, must have a cert"},
+    {"cert", OPT_CERT, '<', "Certificate file to use; default is " TEST_CERT},
+    {"naccept", OPT_NACCEPT, 'p', "Terminate after #num connections"},
+    {"serverinfo", OPT_SERVERINFO, 's',
+     "PEM serverinfo file for certificate"},
+    {"certform", OPT_CERTFORM, 'F',
+     "Certificate format (PEM or DER) PEM default"},
+    {"key", OPT_KEY, '<',
+     "Private Key if not in -cert; default is " TEST_CERT},
+    {"keyform", OPT_KEYFORM, 'f',
+     "Key format (PEM, DER or ENGINE) PEM default"},
+    {"pass", OPT_PASS, 's', "Private key file pass phrase source"},
+    {"dcert", OPT_DCERT, '<',
+     "Second certificate file to use (usually for DSA)"},
+    {"dcertform", OPT_DCERTFORM, 'F',
+     "Second certificate format (PEM or DER) PEM default"},
+    {"dkey", OPT_DKEY, '<',
+     "Second private key file to use (usually for DSA)"},
+    {"dkeyform", OPT_DKEYFORM, 'F',
+     "Second key format (PEM, DER or ENGINE) PEM default"},
+    {"dpass", OPT_DPASS, 's', "Second private key file pass phrase source"},
+    {"nbio_test", OPT_NBIO_TEST, '-', "Test with the non-blocking test bio"},
+    {"crlf", OPT_CRLF, '-', "Convert LF from terminal into CRLF"},
+    {"debug", OPT_DEBUG, '-', "Print more output"},
+    {"msg", OPT_MSG, '-', "Show protocol messages"},
+    {"msgfile", OPT_MSGFILE, '>',
+     "File to send output of -msg or -trace, instead of stdout"},
+    {"state", OPT_STATE, '-', "Print the SSL states"},
+    {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"},
+    {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"},
+    {"no-CAfile", OPT_NOCAFILE, '-',
+     "Do not load the default certificates file"},
+    {"no-CApath", OPT_NOCAPATH, '-',
+     "Do not load certificates from the default certificates directory"},
+    {"nocert", OPT_NOCERT, '-', "Don't use any certificates (Anon-DH)"},
+    {"quiet", OPT_QUIET, '-', "No server output"},
+    {"no_resume_ephemeral", OPT_NO_RESUME_EPHEMERAL, '-',
+     "Disable caching and tickets if ephemeral (EC)DH is used"},
+    {"www", OPT_WWW, '-', "Respond to a 'GET /' with a status page"},
+    {"WWW", OPT_UPPER_WWW, '-', "Respond to a 'GET with the file ./path"},
+    {"servername", OPT_SERVERNAME, 's',
+     "Servername for HostName TLS extension"},
+    {"servername_fatal", OPT_SERVERNAME_FATAL, '-',
+     "mismatch send fatal alert (default warning alert)"},
+    {"cert2", OPT_CERT2, '<',
+     "Certificate file to use for servername; default is" TEST_CERT2},
+    {"key2", OPT_KEY2, '<',
+     "-Private Key file to use for servername if not in -cert2"},
+    {"tlsextdebug", OPT_TLSEXTDEBUG, '-',
+     "Hex dump of all TLS extensions received"},
+    {"HTTP", OPT_HTTP, '-', "Like -WWW but ./path includes HTTP headers"},
+    {"id_prefix", OPT_ID_PREFIX, 's',
+     "Generate SSL/TLS session IDs prefixed by arg"},
+    {"rand", OPT_RAND, 's',
+     "Load the file(s) into the random number generator"},
+    {"keymatexport", OPT_KEYMATEXPORT, 's',
+     "Export keying material using label"},
+    {"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p',
+     "Export len bytes of keying material (default 20)"},
+    {"CRL", OPT_CRL, '<', "CRL file to use"},
+    {"crl_download", OPT_CRL_DOWNLOAD, '-',
+     "Download CRL from distribution points"},
+    {"cert_chain", OPT_CERT_CHAIN, '<',
+     "certificate chain file in PEM format"},
+    {"dcert_chain", OPT_DCERT_CHAIN, '<',
+     "second certificate chain file in PEM format"},
+    {"chainCApath", OPT_CHAINCAPATH, '/',
+     "use dir as certificate store path to build CA certificate chain"},
+    {"verifyCApath", OPT_VERIFYCAPATH, '/',
+     "use dir as certificate store path to verify CA certificate"},
+    {"no_cache", OPT_NO_CACHE, '-', "Disable session cache"},
+    {"ext_cache", OPT_EXT_CACHE, '-',
+     "Disable internal cache, setup and use external cache"},
+    {"CRLform", OPT_CRLFORM, 'F', "CRL format (PEM or DER) PEM is default"},
+    {"verify_return_error", OPT_VERIFY_RET_ERROR, '-',
+     "Close connection on verification error"},
+    {"verify_quiet", OPT_VERIFY_QUIET, '-',
+     "No verify output except verify errors"},
+    {"build_chain", OPT_BUILD_CHAIN, '-', "Build certificate chain"},
+    {"chainCAfile", OPT_CHAINCAFILE, '<',
+     "CA file for certificate chain (PEM format)"},
+    {"verifyCAfile", OPT_VERIFYCAFILE, '<',
+     "CA file for certificate verification (PEM format)"},
+    {"ign_eof", OPT_IGN_EOF, '-', "ignore input eof (default when -quiet)"},
+    {"no_ign_eof", OPT_NO_IGN_EOF, '-', "Do not ignore input eof"},
+#ifndef OPENSSL_NO_OCSP
+    {"status", OPT_STATUS, '-', "Request certificate status from server"},
+    {"status_verbose", OPT_STATUS_VERBOSE, '-',
+     "Print more output in certificate status callback"},
+    {"status_timeout", OPT_STATUS_TIMEOUT, 'n',
+     "Status request responder timeout"},
+    {"status_url", OPT_STATUS_URL, 's', "Status request fallback URL"},
+#endif
+#ifndef OPENSSL_NO_SSL_TRACE
+    {"trace", OPT_TRACE, '-', "trace protocol messages"},
+#endif
+    {"security_debug", OPT_SECURITY_DEBUG, '-',
+     "Print output from SSL/TLS security framework"},
+    {"security_debug_verbose", OPT_SECURITY_DEBUG_VERBOSE, '-',
+     "Print more output from SSL/TLS security framework"},
+    {"brief", OPT_BRIEF, '-',
+     "Restrict output to brief summary of connection parameters"},
+    {"rev", OPT_REV, '-',
+     "act as a simple test server which just sends back with the received text reversed"},
+    {"async", OPT_ASYNC, '-', "Operate in asynchronous mode"},
+    {"ssl_config", OPT_SSL_CONFIG, 's',
+     "Configure SSL_CTX using the configuration 'val'"},
+    {"split_send_frag", OPT_SPLIT_SEND_FRAG, 'n',
+     "Size used to split data for encrypt pipelines"},
+    {"max_pipelines", OPT_MAX_PIPELINES, 'n',
+     "Maximum number of encrypt/decrypt pipelines to be used"},
+    {"read_buf", OPT_READ_BUF, 'n',
+     "Default read buffer size to be used for connections"},
+    OPT_S_OPTIONS,
+    OPT_V_OPTIONS,
+    OPT_X_OPTIONS,
+    {"nbio", OPT_NBIO, '-', "Use non-blocking IO"},
+#ifndef OPENSSL_NO_PSK
+    {"psk_hint", OPT_PSK_HINT, 's', "PSK identity hint to use"},
+    {"psk", OPT_PSK, 's', "PSK in hex (without 0x)"},
+#endif
+#ifndef OPENSSL_NO_SRP
+    {"srpvfile", OPT_SRPVFILE, '<', "The verifier file for SRP"},
+    {"srpuserseed", OPT_SRPUSERSEED, 's',
+     "A seed string for a default user salt"},
+#endif
+#ifndef OPENSSL_NO_SSL3
+    {"ssl3", OPT_SSL3, '-', "Just talk SSLv3"},
+#endif
+#ifndef OPENSSL_NO_TLS1
+    {"tls1", OPT_TLS1, '-', "Just talk TLSv1"},
+#endif
+#ifndef OPENSSL_NO_TLS1_1
+    {"tls1_1", OPT_TLS1_1, '-', "Just talk TLSv1.1"},
+#endif
+#ifndef OPENSSL_NO_TLS1_2
+    {"tls1_2", OPT_TLS1_2, '-', "just talk TLSv1.2"},
+#endif
+#ifndef OPENSSL_NO_DTLS
+    {"dtls", OPT_DTLS, '-', "Use any DTLS version"},
+    {"timeout", OPT_TIMEOUT, '-', "Enable timeouts"},
+    {"mtu", OPT_MTU, 'p', "Set link layer MTU"},
+    {"listen", OPT_LISTEN, '-',
+     "Listen for a DTLS ClientHello with a cookie and then connect"},
+#endif
+#ifndef OPENSSL_NO_DTLS1
+    {"dtls1", OPT_DTLS1, '-', "Just talk DTLSv1"},
+#endif
+#ifndef OPENSSL_NO_DTLS1_2
+    {"dtls1_2", OPT_DTLS1_2, '-', "Just talk DTLSv1.2"},
+#endif
+#ifndef OPENSSL_NO_DH
+    {"no_dhe", OPT_NO_DHE, '-', "Disable ephemeral DH"},
+#endif
+#ifndef OPENSSL_NO_NEXTPROTONEG
+    {"nextprotoneg", OPT_NEXTPROTONEG, 's',
+     "Set the advertised protocols for the NPN extension (comma-separated list)"},
+#endif
+#ifndef OPENSSL_NO_SRTP
+    {"use_srtp", OPT_SRTP_PROFILES, 's',
+     "Offer SRTP key management with a colon-separated profile list"},
+#endif
+    {"alpn", OPT_ALPN, 's',
+     "Set the advertised protocols for the ALPN extension (comma-separated list)"},
+#ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+#endif
+    {NULL, OPT_EOF, 0, NULL}
+};
+
+#define IS_PROT_FLAG(o) \
+ (o == OPT_SSL3 || o == OPT_TLS1 || o == OPT_TLS1_1 || o == OPT_TLS1_2 \
+  || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2)
+
+int s_server_main(int argc, char *argv[])
+{
+    ENGINE *engine = NULL;
+    EVP_PKEY *s_key = NULL, *s_dkey = NULL;
+    SSL_CONF_CTX *cctx = NULL;
+    const SSL_METHOD *meth = TLS_server_method();
+    SSL_EXCERT *exc = NULL;
+    STACK_OF(OPENSSL_STRING) *ssl_args = NULL;
+    STACK_OF(X509) *s_chain = NULL, *s_dchain = NULL;
+    STACK_OF(X509_CRL) *crls = NULL;
+    X509 *s_cert = NULL, *s_dcert = NULL;
+    X509_VERIFY_PARAM *vpm = NULL;
+    const char *CApath = NULL, *CAfile = NULL, *chCApath = NULL, *chCAfile = NULL;
+    char *dpassarg = NULL, *dpass = NULL, *inrand = NULL;
+    char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL;
+    char *crl_file = NULL, *prog;
+#ifdef AF_UNIX
+    int unlink_unix_path = 0;
+#endif
+    do_server_cb server_cb;
+    int vpmtouched = 0, build_chain = 0, no_cache = 0, ext_cache = 0;
+#ifndef OPENSSL_NO_DH
+    char *dhfile = NULL;
+    int no_dhe = 0;
+#endif
+    int nocert = 0, ret = 1;
+    int noCApath = 0, noCAfile = 0;
+    int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
+    int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
+    int rev = 0, naccept = -1, sdebug = 0;
+    int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM;
+    int state = 0, crl_format = FORMAT_PEM, crl_download = 0;
+    char *host = NULL;
+    char *port = BUF_strdup(PORT);
+    unsigned char *context = NULL;
+    OPTION_CHOICE o;
+    EVP_PKEY *s_key2 = NULL;
+    X509 *s_cert2 = NULL;
+    tlsextctx tlsextcbp = { NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING };
+    const char *ssl_config = NULL;
+    int read_buf_len = 0;
+#ifndef OPENSSL_NO_NEXTPROTONEG
+    const char *next_proto_neg_in = NULL;
+    tlsextnextprotoctx next_proto = { NULL, 0 };
+#endif
+    const char *alpn_in = NULL;
+    tlsextalpnctx alpn_ctx = { NULL, 0 };
+#ifndef OPENSSL_NO_PSK
+    /* by default do not send a PSK identity hint */
+    static char *psk_identity_hint = NULL;
+    char *p;
+#endif
+#ifndef OPENSSL_NO_SRP
+    char *srpuserseed = NULL;
+    char *srp_verifier_file = NULL;
+#endif
+    int min_version = 0, max_version = 0, prot_opt = 0, no_prot_opt = 0;
+    int s_server_verify = SSL_VERIFY_NONE;
+    int s_server_session_id_context = 1; /* anything will do */
+    const char *s_cert_file = TEST_CERT, *s_key_file = NULL, *s_chain_file = NULL;
+    const char *s_cert_file2 = TEST_CERT2, *s_key_file2 = NULL;
+    char *s_dcert_file = NULL, *s_dkey_file = NULL, *s_dchain_file = NULL;
+#ifndef OPENSSL_NO_OCSP
+    int s_tlsextstatus = 0;
+#endif
+    int no_resume_ephemeral = 0;
+    unsigned int split_send_fragment = 0, max_pipelines = 0;
+    const char *s_serverinfo_file = NULL;
+
+    /* Init of few remaining global variables */
+    local_argc = argc;
+    local_argv = argv;
+
+    ctx = ctx2 = NULL;
+    s_nbio = s_nbio_test = 0;
+    www = 0;
+    bio_s_out = NULL;
+    s_debug = 0;
+    s_msg = 0;
+    s_quiet = 0;
+    s_brief = 0;
+    async = 0;
+
+    cctx = SSL_CONF_CTX_new();
+    vpm = X509_VERIFY_PARAM_new();
+    if (cctx == NULL || vpm == NULL)
+        goto end;
+    SSL_CONF_CTX_set_flags(cctx,
+                           SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CMDLINE);
+
+    prog = opt_init(argc, argv, s_server_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        if (IS_PROT_FLAG(o) && ++prot_opt > 1) {
+            BIO_printf(bio_err, "Cannot supply multiple protocol flags\n");
+            goto end;
+        }
+        if (IS_NO_PROT_FLAG(o))
+            no_prot_opt++;
+        if (prot_opt == 1 && no_prot_opt) {
+            BIO_printf(bio_err,
+                       "Cannot supply both a protocol flag and '-no_<prot>'\n");
+            goto end;
+        }
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(s_server_options);
+            ret = 0;
+            goto end;
+
+        case OPT_4:
+#ifdef AF_UNIX
+            if (socket_family == AF_UNIX) {
+                OPENSSL_free(host); host = NULL;
+                OPENSSL_free(port); port = NULL;
+            }
+#endif
+            socket_family = AF_INET;
+            break;
+        case OPT_6:
+            if (1) {
+#ifdef AF_INET6
+#ifdef AF_UNIX
+                if (socket_family == AF_UNIX) {
+                    OPENSSL_free(host); host = NULL;
+                    OPENSSL_free(port); port = NULL;
+                }
+#endif
+                socket_family = AF_INET6;
+            } else {
+#endif
+                BIO_printf(bio_err, "%s: IPv6 domain sockets unsupported\n", prog);
+                goto end;
+            }
+            break;
+        case OPT_PORT:
+#ifdef AF_UNIX
+            if (socket_family == AF_UNIX) {
+                socket_family = AF_UNSPEC;
+            }
+#endif
+            OPENSSL_free(port); port = NULL;
+            OPENSSL_free(host); host = NULL;
+            if (BIO_parse_hostserv(opt_arg(), NULL, &port, BIO_PARSE_PRIO_SERV) < 1) {
+                BIO_printf(bio_err,
+                           "%s: -port argument malformed or ambiguous\n",
+                           port);
+                goto end;
+            }
+            break;
+        case OPT_ACCEPT:
+#ifdef AF_UNIX
+            if (socket_family == AF_UNIX) {
+                socket_family = AF_UNSPEC;
+            }
+#endif
+            OPENSSL_free(port); port = NULL;
+            OPENSSL_free(host); host = NULL;
+            if (BIO_parse_hostserv(opt_arg(), &host, &port, BIO_PARSE_PRIO_SERV) < 1) {
+                BIO_printf(bio_err,
+                           "%s: -accept argument malformed or ambiguous\n",
+                           port);
+                goto end;
+            }
+            break;
+#ifdef AF_UNIX
+        case OPT_UNIX:
+            socket_family = AF_UNIX;
+            OPENSSL_free(host); host = BUF_strdup(opt_arg());
+            OPENSSL_free(port); port = NULL;
+            break;
+        case OPT_UNLINK:
+            unlink_unix_path = 1;
+            break;
+#endif
+        case OPT_NACCEPT:
+            naccept = atol(opt_arg());
+            break;
+        case OPT_VERIFY:
+            s_server_verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
+            verify_args.depth = atoi(opt_arg());
+            if (!s_quiet)
+                BIO_printf(bio_err, "verify depth is %d\n", verify_args.depth);
+            break;
+        case OPT_UPPER_V_VERIFY:
+            s_server_verify =
+                SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
+                SSL_VERIFY_CLIENT_ONCE;
+            verify_args.depth = atoi(opt_arg());
+            if (!s_quiet)
+                BIO_printf(bio_err,
+                           "verify depth is %d, must return a certificate\n",
+                           verify_args.depth);
+            break;
+        case OPT_CONTEXT:
+            context = (unsigned char *)opt_arg();
+            break;
+        case OPT_CERT:
+            s_cert_file = opt_arg();
+            break;
+        case OPT_CRL:
+            crl_file = opt_arg();
+            break;
+        case OPT_CRL_DOWNLOAD:
+            crl_download = 1;
+            break;
+        case OPT_SERVERINFO:
+            s_serverinfo_file = opt_arg();
+            break;
+        case OPT_CERTFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_cert_format))
+                goto opthelp;
+            break;
+        case OPT_KEY:
+            s_key_file = opt_arg();
+            break;
+        case OPT_KEYFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_ANY, &s_key_format))
+                goto opthelp;
+            break;
+        case OPT_PASS:
+            passarg = opt_arg();
+            break;
+        case OPT_CERT_CHAIN:
+            s_chain_file = opt_arg();
+            break;
+        case OPT_DHPARAM:
+#ifndef OPENSSL_NO_DH
+            dhfile = opt_arg();
+#endif
+            break;
+        case OPT_DCERTFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_dcert_format))
+                goto opthelp;
+            break;
+        case OPT_DCERT:
+            s_dcert_file = opt_arg();
+            break;
+        case OPT_DKEYFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &s_dkey_format))
+                goto opthelp;
+            break;
+        case OPT_DPASS:
+            dpassarg = opt_arg();
+            break;
+        case OPT_DKEY:
+            s_dkey_file = opt_arg();
+            break;
+        case OPT_DCERT_CHAIN:
+            s_dchain_file = opt_arg();
+            break;
+        case OPT_NOCERT:
+            nocert = 1;
+            break;
+        case OPT_CAPATH:
+            CApath = opt_arg();
+            break;
+        case OPT_NOCAPATH:
+            noCApath = 1;
+            break;
+        case OPT_CHAINCAPATH:
+            chCApath = opt_arg();
+            break;
+        case OPT_VERIFYCAPATH:
+            vfyCApath = opt_arg();
+            break;
+        case OPT_NO_CACHE:
+            no_cache = 1;
+            break;
+        case OPT_EXT_CACHE:
+            ext_cache = 1;
+            break;
+        case OPT_CRLFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &crl_format))
+                goto opthelp;
+            break;
+        case OPT_S_CASES:
+            if (ssl_args == NULL)
+                ssl_args = sk_OPENSSL_STRING_new_null();
+            if (ssl_args == NULL
+                || !sk_OPENSSL_STRING_push(ssl_args, opt_flag())
+                || !sk_OPENSSL_STRING_push(ssl_args, opt_arg())) {
+                BIO_printf(bio_err, "%s: Memory allocation failure\n", prog);
+                goto end;
+            }
+            break;
+        case OPT_V_CASES:
+            if (!opt_verify(o, vpm))
+                goto end;
+            vpmtouched++;
+            break;
+        case OPT_X_CASES:
+            if (!args_excert(o, &exc))
+                goto end;
+            break;
+        case OPT_VERIFY_RET_ERROR:
+            verify_args.return_error = 1;
+            break;
+        case OPT_VERIFY_QUIET:
+            verify_args.quiet = 1;
+            break;
+        case OPT_BUILD_CHAIN:
+            build_chain = 1;
+            break;
+        case OPT_CAFILE:
+            CAfile = opt_arg();
+            break;
+        case OPT_NOCAFILE:
+            noCAfile = 1;
+            break;
+        case OPT_CHAINCAFILE:
+            chCAfile = opt_arg();
+            break;
+        case OPT_VERIFYCAFILE:
+            vfyCAfile = opt_arg();
+            break;
+        case OPT_NBIO:
+            s_nbio = 1;
+            break;
+        case OPT_NBIO_TEST:
+            s_nbio = s_nbio_test = 1;
+            break;
+        case OPT_IGN_EOF:
+            s_ign_eof = 1;
+            break;
+        case OPT_NO_IGN_EOF:
+            s_ign_eof = 0;
+            break;
+        case OPT_DEBUG:
+            s_debug = 1;
+            break;
+        case OPT_TLSEXTDEBUG:
+            s_tlsextdebug = 1;
+            break;
+        case OPT_STATUS:
+#ifndef OPENSSL_NO_OCSP
+            s_tlsextstatus = 1;
+#endif
+            break;
+        case OPT_STATUS_VERBOSE:
+#ifndef OPENSSL_NO_OCSP
+            s_tlsextstatus = tlscstatp.verbose = 1;
+#endif
+            break;
+        case OPT_STATUS_TIMEOUT:
+#ifndef OPENSSL_NO_OCSP
+            s_tlsextstatus = 1;
+            tlscstatp.timeout = atoi(opt_arg());
+#endif
+            break;
+        case OPT_STATUS_URL:
+#ifndef OPENSSL_NO_OCSP
+            s_tlsextstatus = 1;
+            if (!OCSP_parse_url(opt_arg(),
+                                &tlscstatp.host,
+                                &tlscstatp.port,
+                                &tlscstatp.path, &tlscstatp.use_ssl)) {
+                BIO_printf(bio_err, "Error parsing URL\n");
+                goto end;
+            }
+#endif
+            break;
+        case OPT_MSG:
+            s_msg = 1;
+            break;
+        case OPT_MSGFILE:
+            bio_s_msg = BIO_new_file(opt_arg(), "w");
+            break;
+        case OPT_TRACE:
+#ifndef OPENSSL_NO_SSL_TRACE
+            s_msg = 2;
+#endif
+            break;
+        case OPT_SECURITY_DEBUG:
+            sdebug = 1;
+            break;
+        case OPT_SECURITY_DEBUG_VERBOSE:
+            sdebug = 2;
+            break;
+        case OPT_STATE:
+            state = 1;
+            break;
+        case OPT_CRLF:
+            s_crlf = 1;
+            break;
+        case OPT_QUIET:
+            s_quiet = 1;
+            break;
+        case OPT_BRIEF:
+            s_quiet = s_brief = verify_args.quiet = 1;
+            break;
+        case OPT_NO_DHE:
+#ifndef OPENSSL_NO_DH
+            no_dhe = 1;
+#endif
+            break;
+        case OPT_NO_RESUME_EPHEMERAL:
+            no_resume_ephemeral = 1;
+            break;
+        case OPT_PSK_HINT:
+#ifndef OPENSSL_NO_PSK
+            psk_identity_hint = opt_arg();
+#endif
+            break;
+        case OPT_PSK:
+#ifndef OPENSSL_NO_PSK
+            for (p = psk_key = opt_arg(); *p; p++) {
+                if (isxdigit(_UC(*p)))
+                    continue;
+                BIO_printf(bio_err, "Not a hex number '%s'\n", *argv);
+                goto end;
+            }
+#endif
+            break;
+        case OPT_SRPVFILE:
+#ifndef OPENSSL_NO_SRP
+            srp_verifier_file = opt_arg();
+            if (min_version < TLS1_VERSION)
+                min_version = TLS1_VERSION;
+#endif
+            break;
+        case OPT_SRPUSERSEED:
+#ifndef OPENSSL_NO_SRP
+            srpuserseed = opt_arg();
+            if (min_version < TLS1_VERSION)
+                min_version = TLS1_VERSION;
+#endif
+            break;
+        case OPT_REV:
+            rev = 1;
+            break;
+        case OPT_WWW:
+            www = 1;
+            break;
+        case OPT_UPPER_WWW:
+            www = 2;
+            break;
+        case OPT_HTTP:
+            www = 3;
+            break;
+        case OPT_SSL_CONFIG:
+            ssl_config = opt_arg();
+            break;
+        case OPT_SSL3:
+            min_version = SSL3_VERSION;
+            max_version = SSL3_VERSION;
+            break;
+        case OPT_TLS1_2:
+            min_version = TLS1_2_VERSION;
+            max_version = TLS1_2_VERSION;
+            break;
+        case OPT_TLS1_1:
+            min_version = TLS1_1_VERSION;
+            max_version = TLS1_1_VERSION;
+            break;
+        case OPT_TLS1:
+            min_version = TLS1_VERSION;
+            max_version = TLS1_VERSION;
+            break;
+        case OPT_DTLS:
+#ifndef OPENSSL_NO_DTLS
+            meth = DTLS_server_method();
+            socket_type = SOCK_DGRAM;
+#endif
+            break;
+        case OPT_DTLS1:
+#ifndef OPENSSL_NO_DTLS
+            meth = DTLS_server_method();
+            min_version = DTLS1_VERSION;
+            max_version = DTLS1_VERSION;
+            socket_type = SOCK_DGRAM;
+#endif
+            break;
+        case OPT_DTLS1_2:
+#ifndef OPENSSL_NO_DTLS
+            meth = DTLS_server_method();
+            min_version = DTLS1_2_VERSION;
+            max_version = DTLS1_2_VERSION;
+            socket_type = SOCK_DGRAM;
+#endif
+            break;
+        case OPT_TIMEOUT:
+#ifndef OPENSSL_NO_DTLS
+            enable_timeouts = 1;
+#endif
+            break;
+        case OPT_MTU:
+#ifndef OPENSSL_NO_DTLS
+            socket_mtu = atol(opt_arg());
+#endif
+            break;
+        case OPT_LISTEN:
+#ifndef OPENSSL_NO_DTLS
+            dtlslisten = 1;
+#endif
+            break;
+        case OPT_ID_PREFIX:
+            session_id_prefix = opt_arg();
+            break;
+        case OPT_ENGINE:
+            engine = setup_engine(opt_arg(), 1);
+            break;
+        case OPT_RAND:
+            inrand = opt_arg();
+            break;
+        case OPT_SERVERNAME:
+            tlsextcbp.servername = opt_arg();
+            break;
+        case OPT_SERVERNAME_FATAL:
+            tlsextcbp.extension_error = SSL_TLSEXT_ERR_ALERT_FATAL;
+            break;
+        case OPT_CERT2:
+            s_cert_file2 = opt_arg();
+            break;
+        case OPT_KEY2:
+            s_key_file2 = opt_arg();
+            break;
+        case OPT_NEXTPROTONEG:
+# ifndef OPENSSL_NO_NEXTPROTONEG
+            next_proto_neg_in = opt_arg();
+#endif
+            break;
+        case OPT_ALPN:
+            alpn_in = opt_arg();
+            break;
+        case OPT_SRTP_PROFILES:
+#ifndef OPENSSL_NO_SRTP
+            srtp_profiles = opt_arg();
+#endif
+            break;
+        case OPT_KEYMATEXPORT:
+            keymatexportlabel = opt_arg();
+            break;
+        case OPT_KEYMATEXPORTLEN:
+            keymatexportlen = atoi(opt_arg());
+            break;
+        case OPT_ASYNC:
+            async = 1;
+            break;
+        case OPT_SPLIT_SEND_FRAG:
+            split_send_fragment = atoi(opt_arg());
+            if (split_send_fragment == 0) {
+                /*
+                 * Not allowed - set to a deliberately bad value so we get an
+                 * error message below
+                 */
+                split_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH + 1;
+            }
+            break;
+        case OPT_MAX_PIPELINES:
+            max_pipelines = atoi(opt_arg());
+            break;
+        case OPT_READ_BUF:
+            read_buf_len = atoi(opt_arg());
+            break;
+
+        }
+    }
+    argc = opt_num_rest();
+    argv = opt_rest();
+
+#ifndef OPENSSL_NO_DTLS
+    if (www && socket_type == SOCK_DGRAM) {
+        BIO_printf(bio_err, "Can't use -HTTP, -www or -WWW with DTLS\n");
+        goto end;
+    }
+
+    if (dtlslisten && socket_type != SOCK_DGRAM) {
+        BIO_printf(bio_err, "Can only use -listen with DTLS\n");
+        goto end;
+    }
+#endif
+
+#ifdef AF_UNIX
+    if (socket_family == AF_UNIX && socket_type != SOCK_STREAM) {
+        BIO_printf(bio_err,
+                   "Can't use unix sockets and datagrams together\n");
+        goto end;
+    }
+#endif
+
+    if (split_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) {
+        BIO_printf(bio_err, "Bad split send fragment size\n");
+        goto end;
+    }
+
+    if (max_pipelines > SSL_MAX_PIPELINES) {
+        BIO_printf(bio_err, "Bad max pipelines value\n");
+        goto end;
+    }
+
+    if (!app_passwd(passarg, dpassarg, &pass, &dpass)) {
+        BIO_printf(bio_err, "Error getting password\n");
+        goto end;
+    }
+
+    if (s_key_file == NULL)
+        s_key_file = s_cert_file;
+
+    if (s_key_file2 == NULL)
+        s_key_file2 = s_cert_file2;
+
+    if (!load_excert(&exc))
+        goto end;
+
+    if (nocert == 0) {
+        s_key = load_key(s_key_file, s_key_format, 0, pass, engine,
+                         "server certificate private key file");
+        if (!s_key) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+
+        s_cert = load_cert(s_cert_file, s_cert_format,
+                           "server certificate file");
+
+        if (!s_cert) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        if (s_chain_file) {
+            if (!load_certs(s_chain_file, &s_chain, FORMAT_PEM, NULL,
+                            "server certificate chain"))
+                goto end;
+        }
+
+        if (tlsextcbp.servername) {
+            s_key2 = load_key(s_key_file2, s_key_format, 0, pass, engine,
+                              "second server certificate private key file");
+            if (!s_key2) {
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+
+            s_cert2 = load_cert(s_cert_file2, s_cert_format,
+                                "second server certificate file");
+
+            if (!s_cert2) {
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+        }
+    }
+#if !defined(OPENSSL_NO_NEXTPROTONEG)
+    if (next_proto_neg_in) {
+        size_t len;
+        next_proto.data = next_protos_parse(&len, next_proto_neg_in);
+        if (next_proto.data == NULL)
+            goto end;
+        next_proto.len = len;
+    } else {
+        next_proto.data = NULL;
+    }
+#endif
+    alpn_ctx.data = NULL;
+    if (alpn_in) {
+        size_t len;
+        alpn_ctx.data = next_protos_parse(&len, alpn_in);
+        if (alpn_ctx.data == NULL)
+            goto end;
+        alpn_ctx.len = len;
+    }
+
+    if (crl_file) {
+        X509_CRL *crl;
+        crl = load_crl(crl_file, crl_format);
+        if (!crl) {
+            BIO_puts(bio_err, "Error loading CRL\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        crls = sk_X509_CRL_new_null();
+        if (!crls || !sk_X509_CRL_push(crls, crl)) {
+            BIO_puts(bio_err, "Error adding CRL\n");
+            ERR_print_errors(bio_err);
+            X509_CRL_free(crl);
+            goto end;
+        }
+    }
+
+    if (s_dcert_file) {
+
+        if (s_dkey_file == NULL)
+            s_dkey_file = s_dcert_file;
+
+        s_dkey = load_key(s_dkey_file, s_dkey_format,
+                          0, dpass, engine, "second certificate private key file");
+        if (!s_dkey) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+
+        s_dcert = load_cert(s_dcert_file, s_dcert_format,
+                            "second server certificate file");
+
+        if (!s_dcert) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        if (s_dchain_file) {
+            if (!load_certs(s_dchain_file, &s_dchain, FORMAT_PEM, NULL,
+                            "second server certificate chain"))
+                goto end;
+        }
+
+    }
+
+    if (!app_RAND_load_file(NULL, 1) && inrand == NULL
+        && !RAND_status()) {
+        BIO_printf(bio_err,
+                   "warning, not much extra random data, consider using the -rand option\n");
+    }
+    if (inrand != NULL)
+        BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
+                   app_RAND_load_files(inrand));
+
+    if (bio_s_out == NULL) {
+        if (s_quiet && !s_debug) {
+            bio_s_out = BIO_new(BIO_s_null());
+            if (s_msg && !bio_s_msg)
+                bio_s_msg = dup_bio_out(FORMAT_TEXT);
+        } else {
+            if (bio_s_out == NULL)
+                bio_s_out = dup_bio_out(FORMAT_TEXT);
+        }
+    }
+#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC)
+    if (nocert)
+#endif
+    {
+        s_cert_file = NULL;
+        s_key_file = NULL;
+        s_dcert_file = NULL;
+        s_dkey_file = NULL;
+        s_cert_file2 = NULL;
+        s_key_file2 = NULL;
+    }
+
+    ctx = SSL_CTX_new(meth);
+    if (ctx == NULL) {
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+    if (sdebug)
+        ssl_ctx_security_debug(ctx, sdebug);
+    if (ssl_config) {
+        if (SSL_CTX_config(ctx, ssl_config) == 0) {
+            BIO_printf(bio_err, "Error using configuration \"%s\"\n",
+                       ssl_config);
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+    if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0)
+        goto end;
+    if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
+        goto end;
+
+    if (session_id_prefix) {
+        if (strlen(session_id_prefix) >= 32)
+            BIO_printf(bio_err,
+                       "warning: id_prefix is too long, only one new session will be possible\n");
+        if (!SSL_CTX_set_generate_session_id(ctx, generate_session_id)) {
+            BIO_printf(bio_err, "error setting 'id_prefix'\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix);
+    }
+    SSL_CTX_set_quiet_shutdown(ctx, 1);
+    if (exc)
+        ssl_ctx_set_excert(ctx, exc);
+
+    if (state)
+        SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback);
+    if (no_cache)
+        SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
+    else if (ext_cache)
+        init_session_cache_ctx(ctx);
+    else
+        SSL_CTX_sess_set_cache_size(ctx, 128);
+
+    if (async) {
+        SSL_CTX_set_mode(ctx, SSL_MODE_ASYNC);
+    }
+    if (split_send_fragment > 0) {
+        SSL_CTX_set_split_send_fragment(ctx, split_send_fragment);
+    }
+    if (max_pipelines > 0) {
+        SSL_CTX_set_max_pipelines(ctx, max_pipelines);
+    }
+
+    if (read_buf_len > 0) {
+        SSL_CTX_set_default_read_buffer_len(ctx, read_buf_len);
+    }
+#ifndef OPENSSL_NO_SRTP
+    if (srtp_profiles != NULL) {
+        /* Returns 0 on success! */
+        if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles) != 0) {
+            BIO_printf(bio_err, "Error setting SRTP profile\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+#endif
+
+    if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) {
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+    if (vpmtouched && !SSL_CTX_set1_param(ctx, vpm)) {
+        BIO_printf(bio_err, "Error setting verify params\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    ssl_ctx_add_crls(ctx, crls, 0);
+    if (!config_ctx(cctx, ssl_args, ctx))
+        goto end;
+
+    if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile,
+                         crls, crl_download)) {
+        BIO_printf(bio_err, "Error loading store locations\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    if (s_cert2) {
+        ctx2 = SSL_CTX_new(meth);
+        if (ctx2 == NULL) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    if (ctx2) {
+        BIO_printf(bio_s_out, "Setting secondary ctx parameters\n");
+
+        if (sdebug)
+            ssl_ctx_security_debug(ctx, sdebug);
+
+        if (session_id_prefix) {
+            if (strlen(session_id_prefix) >= 32)
+                BIO_printf(bio_err,
+                           "warning: id_prefix is too long, only one new session will be possible\n");
+            if (!SSL_CTX_set_generate_session_id(ctx2, generate_session_id)) {
+                BIO_printf(bio_err, "error setting 'id_prefix'\n");
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+            BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix);
+        }
+        SSL_CTX_set_quiet_shutdown(ctx2, 1);
+        if (exc)
+            ssl_ctx_set_excert(ctx2, exc);
+
+        if (state)
+            SSL_CTX_set_info_callback(ctx2, apps_ssl_info_callback);
+
+        if (no_cache)
+            SSL_CTX_set_session_cache_mode(ctx2, SSL_SESS_CACHE_OFF);
+        else if (ext_cache)
+            init_session_cache_ctx(ctx2);
+        else
+            SSL_CTX_sess_set_cache_size(ctx2, 128);
+
+        if (async)
+            SSL_CTX_set_mode(ctx2, SSL_MODE_ASYNC);
+
+        if (!ctx_set_verify_locations(ctx2, CAfile, CApath, noCAfile,
+                                      noCApath)) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        if (vpmtouched && !SSL_CTX_set1_param(ctx2, vpm)) {
+            BIO_printf(bio_err, "Error setting verify params\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+
+        ssl_ctx_add_crls(ctx2, crls, 0);
+        if (!config_ctx(cctx, ssl_args, ctx2))
+            goto end;
+    }
+#ifndef OPENSSL_NO_NEXTPROTONEG
+    if (next_proto.data)
+        SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb,
+                                              &next_proto);
+#endif
+    if (alpn_ctx.data)
+        SSL_CTX_set_alpn_select_cb(ctx, alpn_cb, &alpn_ctx);
+
+#ifndef OPENSSL_NO_DH
+    if (!no_dhe) {
+        DH *dh = NULL;
+
+        if (dhfile)
+            dh = load_dh_param(dhfile);
+        else if (s_cert_file)
+            dh = load_dh_param(s_cert_file);
+
+        if (dh != NULL) {
+            BIO_printf(bio_s_out, "Setting temp DH parameters\n");
+        } else {
+            BIO_printf(bio_s_out, "Using default temp DH parameters\n");
+        }
+        (void)BIO_flush(bio_s_out);
+
+        if (dh == NULL)
+            SSL_CTX_set_dh_auto(ctx, 1);
+        else if (!SSL_CTX_set_tmp_dh(ctx, dh)) {
+            BIO_puts(bio_err, "Error setting temp DH parameters\n");
+            ERR_print_errors(bio_err);
+            DH_free(dh);
+            goto end;
+        }
+
+        if (ctx2) {
+            if (!dhfile) {
+                DH *dh2 = load_dh_param(s_cert_file2);
+                if (dh2 != NULL) {
+                    BIO_printf(bio_s_out, "Setting temp DH parameters\n");
+                    (void)BIO_flush(bio_s_out);
+
+                    DH_free(dh);
+                    dh = dh2;
+                }
+            }
+            if (dh == NULL)
+                SSL_CTX_set_dh_auto(ctx2, 1);
+            else if (!SSL_CTX_set_tmp_dh(ctx2, dh)) {
+                BIO_puts(bio_err, "Error setting temp DH parameters\n");
+                ERR_print_errors(bio_err);
+                DH_free(dh);
+                goto end;
+            }
+        }
+        DH_free(dh);
+    }
+#endif
+
+    if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain, build_chain))
+        goto end;
+
+    if (s_serverinfo_file != NULL
+        && !SSL_CTX_use_serverinfo_file(ctx, s_serverinfo_file)) {
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    if (ctx2 && !set_cert_key_stuff(ctx2, s_cert2, s_key2, NULL, build_chain))
+        goto end;
+
+    if (s_dcert != NULL) {
+        if (!set_cert_key_stuff(ctx, s_dcert, s_dkey, s_dchain, build_chain))
+            goto end;
+    }
+
+    if (no_resume_ephemeral) {
+        SSL_CTX_set_not_resumable_session_callback(ctx,
+                                                   not_resumable_sess_cb);
+
+        if (ctx2)
+            SSL_CTX_set_not_resumable_session_callback(ctx2,
+                                                       not_resumable_sess_cb);
+    }
+#ifndef OPENSSL_NO_PSK
+    if (psk_key != NULL) {
+        if (s_debug)
+            BIO_printf(bio_s_out, "PSK key given, setting server callback\n");
+        SSL_CTX_set_psk_server_callback(ctx, psk_server_cb);
+    }
+
+    if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint)) {
+        BIO_printf(bio_err, "error setting PSK identity hint to context\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+#endif
+
+    SSL_CTX_set_verify(ctx, s_server_verify, verify_callback);
+    if (!SSL_CTX_set_session_id_context(ctx,
+                                        (void *)&s_server_session_id_context,
+                                        sizeof s_server_session_id_context)) {
+        BIO_printf(bio_err, "error setting session id context\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    /* Set DTLS cookie generation and verification callbacks */
+    SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback);
+    SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback);
+
+    if (ctx2) {
+        SSL_CTX_set_verify(ctx2, s_server_verify, verify_callback);
+        if (!SSL_CTX_set_session_id_context(ctx2,
+                    (void *)&s_server_session_id_context,
+                    sizeof s_server_session_id_context)) {
+            BIO_printf(bio_err, "error setting session id context\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        tlsextcbp.biodebug = bio_s_out;
+        SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb);
+        SSL_CTX_set_tlsext_servername_arg(ctx2, &tlsextcbp);
+        SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
+        SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
+    }
+
+#ifndef OPENSSL_NO_SRP
+    if (srp_verifier_file != NULL) {
+        srp_callback_parm.vb = SRP_VBASE_new(srpuserseed);
+        srp_callback_parm.user = NULL;
+        srp_callback_parm.login = NULL;
+        if ((ret =
+             SRP_VBASE_init(srp_callback_parm.vb,
+                            srp_verifier_file)) != SRP_NO_ERROR) {
+            BIO_printf(bio_err,
+                       "Cannot initialize SRP verifier file \"%s\":ret=%d\n",
+                       srp_verifier_file, ret);
+            goto end;
+        }
+        SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_callback);
+        SSL_CTX_set_srp_cb_arg(ctx, &srp_callback_parm);
+        SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb);
+    } else
+#endif
+    if (CAfile != NULL) {
+        SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CAfile));
+
+        if (ctx2)
+            SSL_CTX_set_client_CA_list(ctx2, SSL_load_client_CA_file(CAfile));
+    }
+#ifndef OPENSSL_NO_OCSP
+    if (s_tlsextstatus) {
+        SSL_CTX_set_tlsext_status_cb(ctx, cert_status_cb);
+        SSL_CTX_set_tlsext_status_arg(ctx, &tlscstatp);
+        if (ctx2) {
+            SSL_CTX_set_tlsext_status_cb(ctx2, cert_status_cb);
+            SSL_CTX_set_tlsext_status_arg(ctx2, &tlscstatp);
+        }
+    }
+#endif
+
+    BIO_printf(bio_s_out, "ACCEPT\n");
+    (void)BIO_flush(bio_s_out);
+    if (rev)
+        server_cb = rev_body;
+    else if (www)
+        server_cb = www_body;
+    else
+        server_cb = sv_body;
+#ifdef AF_UNIX
+    if (socket_family == AF_UNIX
+        && unlink_unix_path)
+        unlink(host);
+#endif
+    do_server(&accept_socket, host, port, socket_family, socket_type,
+              server_cb, context, naccept);
+    print_stats(bio_s_out, ctx);
+    ret = 0;
+ end:
+    SSL_CTX_free(ctx);
+    X509_free(s_cert);
+    sk_X509_CRL_pop_free(crls, X509_CRL_free);
+    X509_free(s_dcert);
+    EVP_PKEY_free(s_key);
+    EVP_PKEY_free(s_dkey);
+    sk_X509_pop_free(s_chain, X509_free);
+    sk_X509_pop_free(s_dchain, X509_free);
+    OPENSSL_free(pass);
+    OPENSSL_free(dpass);
+    OPENSSL_free(host);
+    OPENSSL_free(port);
+    X509_VERIFY_PARAM_free(vpm);
+    free_sessions();
+    OPENSSL_free(tlscstatp.host);
+    OPENSSL_free(tlscstatp.port);
+    OPENSSL_free(tlscstatp.path);
+    SSL_CTX_free(ctx2);
+    X509_free(s_cert2);
+    EVP_PKEY_free(s_key2);
+#ifndef OPENSSL_NO_NEXTPROTONEG
+    OPENSSL_free(next_proto.data);
+#endif
+    OPENSSL_free(alpn_ctx.data);
+    ssl_excert_free(exc);
+    sk_OPENSSL_STRING_free(ssl_args);
+    SSL_CONF_CTX_free(cctx);
+    release_engine(engine);
+    BIO_free(bio_s_out);
+    bio_s_out = NULL;
+    BIO_free(bio_s_msg);
+    bio_s_msg = NULL;
+#ifdef CHARSET_EBCDIC
+    BIO_meth_free(methods_ebcdic);
+#endif
+    return (ret);
+}
+
+static void print_stats(BIO *bio, SSL_CTX *ssl_ctx)
+{
+    BIO_printf(bio, "%4ld items in the session cache\n",
+               SSL_CTX_sess_number(ssl_ctx));
+    BIO_printf(bio, "%4ld client connects (SSL_connect())\n",
+               SSL_CTX_sess_connect(ssl_ctx));
+    BIO_printf(bio, "%4ld client renegotiates (SSL_connect())\n",
+               SSL_CTX_sess_connect_renegotiate(ssl_ctx));
+    BIO_printf(bio, "%4ld client connects that finished\n",
+               SSL_CTX_sess_connect_good(ssl_ctx));
+    BIO_printf(bio, "%4ld server accepts (SSL_accept())\n",
+               SSL_CTX_sess_accept(ssl_ctx));
+    BIO_printf(bio, "%4ld server renegotiates (SSL_accept())\n",
+               SSL_CTX_sess_accept_renegotiate(ssl_ctx));
+    BIO_printf(bio, "%4ld server accepts that finished\n",
+               SSL_CTX_sess_accept_good(ssl_ctx));
+    BIO_printf(bio, "%4ld session cache hits\n", SSL_CTX_sess_hits(ssl_ctx));
+    BIO_printf(bio, "%4ld session cache misses\n",
+               SSL_CTX_sess_misses(ssl_ctx));
+    BIO_printf(bio, "%4ld session cache timeouts\n",
+               SSL_CTX_sess_timeouts(ssl_ctx));
+    BIO_printf(bio, "%4ld callback cache hits\n",
+               SSL_CTX_sess_cb_hits(ssl_ctx));
+    BIO_printf(bio, "%4ld cache full overflows (%ld allowed)\n",
+               SSL_CTX_sess_cache_full(ssl_ctx),
+               SSL_CTX_sess_get_cache_size(ssl_ctx));
+}
+
+static int sv_body(int s, int stype, unsigned char *context)
+{
+    char *buf = NULL;
+    fd_set readfds;
+    int ret = 1, width;
+    int k, i;
+    unsigned long l;
+    SSL *con = NULL;
+    BIO *sbio;
+    struct timeval timeout;
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
+    struct timeval tv;
+#else
+    struct timeval *timeoutp;
+#endif
+
+    buf = app_malloc(bufsize, "server buffer");
+    if (s_nbio) {
+        if (!BIO_socket_nbio(s, 1))
+            ERR_print_errors(bio_err);
+        else if (!s_quiet)
+            BIO_printf(bio_err, "Turned on non blocking io\n");
+    }
+
+    if (con == NULL) {
+        con = SSL_new(ctx);
+
+        if (s_tlsextdebug) {
+            SSL_set_tlsext_debug_callback(con, tlsext_cb);
+            SSL_set_tlsext_debug_arg(con, bio_s_out);
+        }
+
+        if (context
+            && !SSL_set_session_id_context(con,
+                                           context, strlen((char *)context))) {
+            BIO_printf(bio_err, "Error setting session id context\n");
+            ret = -1;
+            goto err;
+        }
+    }
+    if (!SSL_clear(con)) {
+        BIO_printf(bio_err, "Error clearing SSL connection\n");
+        ret = -1;
+        goto err;
+    }
+#ifndef OPENSSL_NO_DTLS
+    if (stype == SOCK_DGRAM) {
+
+        sbio = BIO_new_dgram(s, BIO_NOCLOSE);
+
+        if (enable_timeouts) {
+            timeout.tv_sec = 0;
+            timeout.tv_usec = DGRAM_RCV_TIMEOUT;
+            BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
+
+            timeout.tv_sec = 0;
+            timeout.tv_usec = DGRAM_SND_TIMEOUT;
+            BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
+        }
+
+        if (socket_mtu) {
+            if (socket_mtu < DTLS_get_link_min_mtu(con)) {
+                BIO_printf(bio_err, "MTU too small. Must be at least %ld\n",
+                           DTLS_get_link_min_mtu(con));
+                ret = -1;
+                BIO_free(sbio);
+                goto err;
+            }
+            SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
+            if (!DTLS_set_link_mtu(con, socket_mtu)) {
+                BIO_printf(bio_err, "Failed to set MTU\n");
+                ret = -1;
+                BIO_free(sbio);
+                goto err;
+            }
+        } else
+            /* want to do MTU discovery */
+            BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
+
+        /* turn on cookie exchange */
+        SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
+    } else
+#endif
+        sbio = BIO_new_socket(s, BIO_NOCLOSE);
+
+    if (s_nbio_test) {
+        BIO *test;
+
+        test = BIO_new(BIO_f_nbio_test());
+        sbio = BIO_push(test, sbio);
+    }
+
+    SSL_set_bio(con, sbio, sbio);
+    SSL_set_accept_state(con);
+    /* SSL_set_fd(con,s); */
+
+    if (s_debug) {
+        BIO_set_callback(SSL_get_rbio(con), bio_dump_callback);
+        BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out);
+    }
+    if (s_msg) {
+#ifndef OPENSSL_NO_SSL_TRACE
+        if (s_msg == 2)
+            SSL_set_msg_callback(con, SSL_trace);
+        else
+#endif
+            SSL_set_msg_callback(con, msg_cb);
+        SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out);
+    }
+
+    if (s_tlsextdebug) {
+        SSL_set_tlsext_debug_callback(con, tlsext_cb);
+        SSL_set_tlsext_debug_arg(con, bio_s_out);
+    }
+
+    if (fileno_stdin() > s)
+        width = fileno_stdin() + 1;
+    else
+        width = s + 1;
+    for (;;) {
+        int read_from_terminal;
+        int read_from_sslcon;
+
+        read_from_terminal = 0;
+        read_from_sslcon = SSL_has_pending(con)
+                           || (async && SSL_waiting_for_async(con));
+
+        if (!read_from_sslcon) {
+            FD_ZERO(&readfds);
+#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS)
+            openssl_fdset(fileno_stdin(), &readfds);
+#endif
+            openssl_fdset(s, &readfds);
+            /*
+             * Note: under VMS with SOCKETSHR the second parameter is
+             * currently of type (int *) whereas under other systems it is
+             * (void *) if you don't have a cast it will choke the compiler:
+             * if you do have a cast then you can either go for (int *) or
+             * (void *).
+             */
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
+            /*
+             * Under DOS (non-djgpp) and Windows we can't select on stdin:
+             * only on sockets. As a workaround we timeout the select every
+             * second and check for any keypress. In a proper Windows
+             * application we wouldn't do this because it is inefficient.
+             */
+            tv.tv_sec = 1;
+            tv.tv_usec = 0;
+            i = select(width, (void *)&readfds, NULL, NULL, &tv);
+            if (has_stdin_waiting())
+                read_from_terminal = 1;
+            if ((i < 0) || (!i && !read_from_terminal))
+                continue;
+#else
+            if ((SSL_version(con) == DTLS1_VERSION) &&
+                DTLSv1_get_timeout(con, &timeout))
+                timeoutp = &timeout;
+            else
+                timeoutp = NULL;
+
+            i = select(width, (void *)&readfds, NULL, NULL, timeoutp);
+
+            if ((SSL_version(con) == DTLS1_VERSION)
+                && DTLSv1_handle_timeout(con) > 0) {
+                BIO_printf(bio_err, "TIMEOUT occurred\n");
+            }
+
+            if (i <= 0)
+                continue;
+            if (FD_ISSET(fileno_stdin(), &readfds))
+                read_from_terminal = 1;
+#endif
+            if (FD_ISSET(s, &readfds))
+                read_from_sslcon = 1;
+        }
+        if (read_from_terminal) {
+            if (s_crlf) {
+                int j, lf_num;
+
+                i = raw_read_stdin(buf, bufsize / 2);
+                lf_num = 0;
+                /* both loops are skipped when i <= 0 */
+                for (j = 0; j < i; j++)
+                    if (buf[j] == '\n')
+                        lf_num++;
+                for (j = i - 1; j >= 0; j--) {
+                    buf[j + lf_num] = buf[j];
+                    if (buf[j] == '\n') {
+                        lf_num--;
+                        i++;
+                        buf[j + lf_num] = '\r';
+                    }
+                }
+                assert(lf_num == 0);
+            } else
+                i = raw_read_stdin(buf, bufsize);
+
+            if (!s_quiet && !s_brief) {
+                if ((i <= 0) || (buf[0] == 'Q')) {
+                    BIO_printf(bio_s_out, "DONE\n");
+                    (void)BIO_flush(bio_s_out);
+                    BIO_closesocket(s);
+                    close_accept_socket();
+                    ret = -11;
+                    goto err;
+                }
+                if ((i <= 0) || (buf[0] == 'q')) {
+                    BIO_printf(bio_s_out, "DONE\n");
+                    (void)BIO_flush(bio_s_out);
+                    if (SSL_version(con) != DTLS1_VERSION)
+                        BIO_closesocket(s);
+                    /*
+                     * close_accept_socket(); ret= -11;
+                     */
+                    goto err;
+                }
+#ifndef OPENSSL_NO_HEARTBEATS
+                if ((buf[0] == 'B') && ((buf[1] == '\n') || (buf[1] == '\r'))) {
+                    BIO_printf(bio_err, "HEARTBEATING\n");
+                    SSL_heartbeat(con);
+                    i = 0;
+                    continue;
+                }
+#endif
+                if ((buf[0] == 'r') && ((buf[1] == '\n') || (buf[1] == '\r'))) {
+                    SSL_renegotiate(con);
+                    i = SSL_do_handshake(con);
+                    printf("SSL_do_handshake -> %d\n", i);
+                    i = 0;      /* 13; */
+                    continue;
+                    /*
+                     * strcpy(buf,"server side RE-NEGOTIATE\n");
+                     */
+                }
+                if ((buf[0] == 'R') && ((buf[1] == '\n') || (buf[1] == '\r'))) {
+                    SSL_set_verify(con,
+                                   SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE,
+                                   NULL);
+                    SSL_renegotiate(con);
+                    i = SSL_do_handshake(con);
+                    printf("SSL_do_handshake -> %d\n", i);
+                    i = 0;      /* 13; */
+                    continue;
+                    /*
+                     * strcpy(buf,"server side RE-NEGOTIATE asking for client
+                     * cert\n");
+                     */
+                }
+                if (buf[0] == 'P') {
+                    static const char *str = "Lets print some clear text\n";
+                    BIO_write(SSL_get_wbio(con), str, strlen(str));
+                }
+                if (buf[0] == 'S') {
+                    print_stats(bio_s_out, SSL_get_SSL_CTX(con));
+                }
+            }
+#ifdef CHARSET_EBCDIC
+            ebcdic2ascii(buf, buf, i);
+#endif
+            l = k = 0;
+            for (;;) {
+                /* should do a select for the write */
+#ifdef RENEG
+                static count = 0;
+                if (++count == 100) {
+                    count = 0;
+                    SSL_renegotiate(con);
+                }
+#endif
+                k = SSL_write(con, &(buf[l]), (unsigned int)i);
+#ifndef OPENSSL_NO_SRP
+                while (SSL_get_error(con, k) == SSL_ERROR_WANT_X509_LOOKUP) {
+                    BIO_printf(bio_s_out, "LOOKUP renego during write\n");
+                    SRP_user_pwd_free(srp_callback_parm.user);
+                    srp_callback_parm.user =
+                        SRP_VBASE_get1_by_user(srp_callback_parm.vb,
+                                               srp_callback_parm.login);
+                    if (srp_callback_parm.user)
+                        BIO_printf(bio_s_out, "LOOKUP done %s\n",
+                                   srp_callback_parm.user->info);
+                    else
+                        BIO_printf(bio_s_out, "LOOKUP not successful\n");
+                    k = SSL_write(con, &(buf[l]), (unsigned int)i);
+                }
+#endif
+                switch (SSL_get_error(con, k)) {
+                case SSL_ERROR_NONE:
+                    break;
+                case SSL_ERROR_WANT_ASYNC:
+                    BIO_printf(bio_s_out, "Write BLOCK (Async)\n");
+                    (void)BIO_flush(bio_s_out);
+                    wait_for_async(con);
+                    break;
+                case SSL_ERROR_WANT_WRITE:
+                case SSL_ERROR_WANT_READ:
+                case SSL_ERROR_WANT_X509_LOOKUP:
+                    BIO_printf(bio_s_out, "Write BLOCK\n");
+                    (void)BIO_flush(bio_s_out);
+                    break;
+                case SSL_ERROR_WANT_ASYNC_JOB:
+                    /*
+                     * This shouldn't ever happen in s_server. Treat as an error
+                     */
+                case SSL_ERROR_SYSCALL:
+                case SSL_ERROR_SSL:
+                    BIO_printf(bio_s_out, "ERROR\n");
+                    (void)BIO_flush(bio_s_out);
+                    ERR_print_errors(bio_err);
+                    ret = 1;
+                    goto err;
+                    /* break; */
+                case SSL_ERROR_ZERO_RETURN:
+                    BIO_printf(bio_s_out, "DONE\n");
+                    (void)BIO_flush(bio_s_out);
+                    ret = 1;
+                    goto err;
+                }
+                if (k > 0) {
+                    l += k;
+                    i -= k;
+                }
+                if (i <= 0)
+                    break;
+            }
+        }
+        if (read_from_sslcon) {
+            /*
+             * init_ssl_connection handles all async events itself so if we're
+             * waiting for async then we shouldn't go back into
+             * init_ssl_connection
+             */
+            if ((!async || !SSL_waiting_for_async(con))
+                    && !SSL_is_init_finished(con)) {
+                i = init_ssl_connection(con);
+
+                if (i < 0) {
+                    ret = 0;
+                    goto err;
+                } else if (i == 0) {
+                    ret = 1;
+                    goto err;
+                }
+            } else {
+ again:
+                i = SSL_read(con, (char *)buf, bufsize);
+#ifndef OPENSSL_NO_SRP
+                while (SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) {
+                    BIO_printf(bio_s_out, "LOOKUP renego during read\n");
+                    SRP_user_pwd_free(srp_callback_parm.user);
+                    srp_callback_parm.user =
+                        SRP_VBASE_get1_by_user(srp_callback_parm.vb,
+                                               srp_callback_parm.login);
+                    if (srp_callback_parm.user)
+                        BIO_printf(bio_s_out, "LOOKUP done %s\n",
+                                   srp_callback_parm.user->info);
+                    else
+                        BIO_printf(bio_s_out, "LOOKUP not successful\n");
+                    i = SSL_read(con, (char *)buf, bufsize);
+                }
+#endif
+                switch (SSL_get_error(con, i)) {
+                case SSL_ERROR_NONE:
+#ifdef CHARSET_EBCDIC
+                    ascii2ebcdic(buf, buf, i);
+#endif
+                    raw_write_stdout(buf, (unsigned int)i);
+                    (void)BIO_flush(bio_s_out);
+                    if (SSL_has_pending(con))
+                        goto again;
+                    break;
+                case SSL_ERROR_WANT_ASYNC:
+                    BIO_printf(bio_s_out, "Read BLOCK (Async)\n");
+                    (void)BIO_flush(bio_s_out);
+                    wait_for_async(con);
+                    break;
+                case SSL_ERROR_WANT_WRITE:
+                case SSL_ERROR_WANT_READ:
+                    BIO_printf(bio_s_out, "Read BLOCK\n");
+                    (void)BIO_flush(bio_s_out);
+                    break;
+                case SSL_ERROR_WANT_ASYNC_JOB:
+                    /*
+                     * This shouldn't ever happen in s_server. Treat as an error
+                     */
+                case SSL_ERROR_SYSCALL:
+                case SSL_ERROR_SSL:
+                    BIO_printf(bio_s_out, "ERROR\n");
+                    (void)BIO_flush(bio_s_out);
+                    ERR_print_errors(bio_err);
+                    ret = 1;
+                    goto err;
+                case SSL_ERROR_ZERO_RETURN:
+                    BIO_printf(bio_s_out, "DONE\n");
+                    (void)BIO_flush(bio_s_out);
+                    ret = 1;
+                    goto err;
+                }
+            }
+        }
+    }
+ err:
+    if (con != NULL) {
+        BIO_printf(bio_s_out, "shutting down SSL\n");
+        SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
+        SSL_free(con);
+    }
+    BIO_printf(bio_s_out, "CONNECTION CLOSED\n");
+    OPENSSL_clear_free(buf, bufsize);
+    if (ret >= 0)
+        BIO_printf(bio_s_out, "ACCEPT\n");
+    (void)BIO_flush(bio_s_out);
+    return (ret);
+}
+
+static void close_accept_socket(void)
+{
+    BIO_printf(bio_err, "shutdown accept socket\n");
+    if (accept_socket >= 0) {
+        BIO_closesocket(accept_socket);
+    }
+}
+
+static int init_ssl_connection(SSL *con)
+{
+    int i;
+    const char *str;
+    X509 *peer;
+    long verify_err;
+    char buf[BUFSIZ];
+#if !defined(OPENSSL_NO_NEXTPROTONEG)
+    const unsigned char *next_proto_neg;
+    unsigned next_proto_neg_len;
+#endif
+    unsigned char *exportedkeymat;
+    int retry = 0;
+
+#ifndef OPENSSL_NO_DTLS
+    if (dtlslisten) {
+        BIO_ADDR *client = NULL;
+
+        if ((client = BIO_ADDR_new()) == NULL) {
+            BIO_printf(bio_err, "ERROR - memory\n");
+            return 0;
+        }
+        i = DTLSv1_listen(con, client);
+        if (i > 0) {
+            BIO *wbio;
+            int fd = -1;
+
+            wbio = SSL_get_wbio(con);
+            if (wbio) {
+                BIO_get_fd(wbio, &fd);
+            }
+
+            if (!wbio || BIO_connect(fd, client, 0) == 0) {
+                BIO_printf(bio_err, "ERROR - unable to connect\n");
+                BIO_ADDR_free(client);
+                return 0;
+            }
+            BIO_ADDR_free(client);
+            dtlslisten = 0;
+            i = SSL_accept(con);
+        } else {
+            BIO_ADDR_free(client);
+        }
+    } else
+#endif
+
+    do {
+        i = SSL_accept(con);
+
+        if (i <= 0)
+            retry = BIO_sock_should_retry(i);
+#ifdef CERT_CB_TEST_RETRY
+        {
+            while (i <= 0
+                    && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP
+                    && SSL_get_state(con) == TLS_ST_SR_CLNT_HELLO) {
+                BIO_printf(bio_err,
+                           "LOOKUP from certificate callback during accept\n");
+                i = SSL_accept(con);
+                if (i <= 0)
+                    retry = BIO_sock_should_retry(i);
+            }
+        }
+#endif
+
+#ifndef OPENSSL_NO_SRP
+        while (i <= 0
+               && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) {
+            BIO_printf(bio_s_out, "LOOKUP during accept %s\n",
+                       srp_callback_parm.login);
+            SRP_user_pwd_free(srp_callback_parm.user);
+            srp_callback_parm.user =
+                SRP_VBASE_get1_by_user(srp_callback_parm.vb,
+                                       srp_callback_parm.login);
+            if (srp_callback_parm.user)
+                BIO_printf(bio_s_out, "LOOKUP done %s\n",
+                           srp_callback_parm.user->info);
+            else
+                BIO_printf(bio_s_out, "LOOKUP not successful\n");
+            i = SSL_accept(con);
+            if (i <= 0)
+                retry = BIO_sock_should_retry(i);
+        }
+#endif
+    } while (i < 0 && SSL_waiting_for_async(con));
+
+    if (i <= 0) {
+        if ((dtlslisten && i == 0)
+                || (!dtlslisten && retry)) {
+            BIO_printf(bio_s_out, "DELAY\n");
+            return (1);
+        }
+
+        BIO_printf(bio_err, "ERROR\n");
+
+        verify_err = SSL_get_verify_result(con);
+        if (verify_err != X509_V_OK) {
+            BIO_printf(bio_err, "verify error:%s\n",
+                       X509_verify_cert_error_string(verify_err));
+        }
+        /* Always print any error messages */
+        ERR_print_errors(bio_err);
+        return (0);
+    }
+
+    if (s_brief)
+        print_ssl_summary(con);
+
+    PEM_write_bio_SSL_SESSION(bio_s_out, SSL_get_session(con));
+
+    peer = SSL_get_peer_certificate(con);
+    if (peer != NULL) {
+        BIO_printf(bio_s_out, "Client certificate\n");
+        PEM_write_bio_X509(bio_s_out, peer);
+        X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof buf);
+        BIO_printf(bio_s_out, "subject=%s\n", buf);
+        X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf);
+        BIO_printf(bio_s_out, "issuer=%s\n", buf);
+        X509_free(peer);
+        peer = NULL;
+    }
+
+    if (SSL_get_shared_ciphers(con, buf, sizeof buf) != NULL)
+        BIO_printf(bio_s_out, "Shared ciphers:%s\n", buf);
+    str = SSL_CIPHER_get_name(SSL_get_current_cipher(con));
+    ssl_print_sigalgs(bio_s_out, con);
+#ifndef OPENSSL_NO_EC
+    ssl_print_point_formats(bio_s_out, con);
+    ssl_print_curves(bio_s_out, con, 0);
+#endif
+    BIO_printf(bio_s_out, "CIPHER is %s\n", (str != NULL) ? str : "(NONE)");
+
+#if !defined(OPENSSL_NO_NEXTPROTONEG)
+    SSL_get0_next_proto_negotiated(con, &next_proto_neg, &next_proto_neg_len);
+    if (next_proto_neg) {
+        BIO_printf(bio_s_out, "NEXTPROTO is ");
+        BIO_write(bio_s_out, next_proto_neg, next_proto_neg_len);
+        BIO_printf(bio_s_out, "\n");
+    }
+#endif
+#ifndef OPENSSL_NO_SRTP
+    {
+        SRTP_PROTECTION_PROFILE *srtp_profile
+            = SSL_get_selected_srtp_profile(con);
+
+        if (srtp_profile)
+            BIO_printf(bio_s_out, "SRTP Extension negotiated, profile=%s\n",
+                       srtp_profile->name);
+    }
+#endif
+    if (SSL_session_reused(con))
+        BIO_printf(bio_s_out, "Reused session-id\n");
+    BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n",
+               SSL_get_secure_renegotiation_support(con) ? "" : " NOT");
+    if (keymatexportlabel != NULL) {
+        BIO_printf(bio_s_out, "Keying material exporter:\n");
+        BIO_printf(bio_s_out, "    Label: '%s'\n", keymatexportlabel);
+        BIO_printf(bio_s_out, "    Length: %i bytes\n", keymatexportlen);
+        exportedkeymat = app_malloc(keymatexportlen, "export key");
+        if (!SSL_export_keying_material(con, exportedkeymat,
+                                        keymatexportlen,
+                                        keymatexportlabel,
+                                        strlen(keymatexportlabel),
+                                        NULL, 0, 0)) {
+            BIO_printf(bio_s_out, "    Error\n");
+        } else {
+            BIO_printf(bio_s_out, "    Keying material: ");
+            for (i = 0; i < keymatexportlen; i++)
+                BIO_printf(bio_s_out, "%02X", exportedkeymat[i]);
+            BIO_printf(bio_s_out, "\n");
+        }
+        OPENSSL_free(exportedkeymat);
+    }
+
+    (void)BIO_flush(bio_s_out);
+    return (1);
+}
+
+#ifndef OPENSSL_NO_DH
+static DH *load_dh_param(const char *dhfile)
+{
+    DH *ret = NULL;
+    BIO *bio;
+
+    if ((bio = BIO_new_file(dhfile, "r")) == NULL)
+        goto err;
+    ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
+ err:
+    BIO_free(bio);
+    return (ret);
+}
+#endif
+
+static int www_body(int s, int stype, unsigned char *context)
+{
+    char *buf = NULL;
+    int ret = 1;
+    int i, j, k, dot;
+    SSL *con;
+    const SSL_CIPHER *c;
+    BIO *io, *ssl_bio, *sbio;
+#ifdef RENEG
+    int total_bytes = 0;
+#endif
+    int width;
+    fd_set readfds;
+
+    /* Set width for a select call if needed */
+    width = s + 1;
+
+    buf = app_malloc(bufsize, "server www buffer");
+    io = BIO_new(BIO_f_buffer());
+    ssl_bio = BIO_new(BIO_f_ssl());
+    if ((io == NULL) || (ssl_bio == NULL))
+        goto err;
+
+    if (s_nbio) {
+        if (!BIO_socket_nbio(s, 1))
+            ERR_print_errors(bio_err);
+        else if (!s_quiet)
+            BIO_printf(bio_err, "Turned on non blocking io\n");
+    }
+
+    /* lets make the output buffer a reasonable size */
+    if (!BIO_set_write_buffer_size(io, bufsize))
+        goto err;
+
+    if ((con = SSL_new(ctx)) == NULL)
+        goto err;
+
+    if (s_tlsextdebug) {
+        SSL_set_tlsext_debug_callback(con, tlsext_cb);
+        SSL_set_tlsext_debug_arg(con, bio_s_out);
+    }
+
+    if (context
+        && !SSL_set_session_id_context(con, context,
+                                       strlen((char *)context)))
+        goto err;
+
+    sbio = BIO_new_socket(s, BIO_NOCLOSE);
+    if (s_nbio_test) {
+        BIO *test;
+
+        test = BIO_new(BIO_f_nbio_test());
+        sbio = BIO_push(test, sbio);
+    }
+    SSL_set_bio(con, sbio, sbio);
+    SSL_set_accept_state(con);
+
+    /* SSL_set_fd(con,s); */
+    BIO_set_ssl(ssl_bio, con, BIO_CLOSE);
+    BIO_push(io, ssl_bio);
+#ifdef CHARSET_EBCDIC
+    io = BIO_push(BIO_new(BIO_f_ebcdic_filter()), io);
+#endif
+
+    if (s_debug) {
+        BIO_set_callback(SSL_get_rbio(con), bio_dump_callback);
+        BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out);
+    }
+    if (s_msg) {
+#ifndef OPENSSL_NO_SSL_TRACE
+        if (s_msg == 2)
+            SSL_set_msg_callback(con, SSL_trace);
+        else
+#endif
+            SSL_set_msg_callback(con, msg_cb);
+        SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out);
+    }
+
+    for (;;) {
+        i = BIO_gets(io, buf, bufsize - 1);
+        if (i < 0) {            /* error */
+            if (!BIO_should_retry(io) && !SSL_waiting_for_async(con)) {
+                if (!s_quiet)
+                    ERR_print_errors(bio_err);
+                goto err;
+            } else {
+                BIO_printf(bio_s_out, "read R BLOCK\n");
+#ifndef OPENSSL_NO_SRP
+                if (BIO_should_io_special(io)
+                    && BIO_get_retry_reason(io) == BIO_RR_SSL_X509_LOOKUP) {
+                    BIO_printf(bio_s_out, "LOOKUP renego during read\n");
+                    SRP_user_pwd_free(srp_callback_parm.user);
+                    srp_callback_parm.user =
+                        SRP_VBASE_get1_by_user(srp_callback_parm.vb,
+                                               srp_callback_parm.login);
+                    if (srp_callback_parm.user)
+                        BIO_printf(bio_s_out, "LOOKUP done %s\n",
+                                   srp_callback_parm.user->info);
+                    else
+                        BIO_printf(bio_s_out, "LOOKUP not successful\n");
+                    continue;
+                }
+#endif
+#if !defined(OPENSSL_SYS_MSDOS)
+                sleep(1);
+#endif
+                continue;
+            }
+        } else if (i == 0) {    /* end of input */
+            ret = 1;
+            goto end;
+        }
+
+        /* else we have data */
+        if (((www == 1) && (strncmp("GET ", buf, 4) == 0)) ||
+            ((www == 2) && (strncmp("GET /stats ", buf, 11) == 0))) {
+            char *p;
+            X509 *peer = NULL;
+            STACK_OF(SSL_CIPHER) *sk;
+            static const char *space = "                          ";
+
+            if (www == 1 && strncmp("GET /reneg", buf, 10) == 0) {
+                if (strncmp("GET /renegcert", buf, 14) == 0)
+                    SSL_set_verify(con,
+                                   SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE,
+                                   NULL);
+                i = SSL_renegotiate(con);
+                BIO_printf(bio_s_out, "SSL_renegotiate -> %d\n", i);
+                /* Send the HelloRequest */
+                i = SSL_do_handshake(con);
+                if (i <= 0) {
+                    BIO_printf(bio_s_out, "SSL_do_handshake() Retval %d\n",
+                               SSL_get_error(con, i));
+                    ERR_print_errors(bio_err);
+                    goto err;
+                }
+                /* Wait for a ClientHello to come back */
+                FD_ZERO(&readfds);
+                openssl_fdset(s, &readfds);
+                i = select(width, (void *)&readfds, NULL, NULL, NULL);
+                if (i <= 0 || !FD_ISSET(s, &readfds)) {
+                    BIO_printf(bio_s_out,
+                               "Error waiting for client response\n");
+                    ERR_print_errors(bio_err);
+                    goto err;
+                }
+                /*
+                 * We're not actually expecting any data here and we ignore
+                 * any that is sent. This is just to force the handshake that
+                 * we're expecting to come from the client. If they haven't
+                 * sent one there's not much we can do.
+                 */
+                BIO_gets(io, buf, bufsize - 1);
+            }
+
+            BIO_puts(io,
+                     "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
+            BIO_puts(io, "<HTML><BODY BGCOLOR=\"#ffffff\">\n");
+            BIO_puts(io, "<pre>\n");
+            /* BIO_puts(io, OpenSSL_version(OPENSSL_VERSION)); */
+            BIO_puts(io, "\n");
+            for (i = 0; i < local_argc; i++) {
+                const char *myp;
+                for (myp = local_argv[i]; *myp; myp++)
+                    switch (*myp) {
+                    case '<':
+                        BIO_puts(io, "&lt;");
+                        break;
+                    case '>':
+                        BIO_puts(io, "&gt;");
+                        break;
+                    case '&':
+                        BIO_puts(io, "&amp;");
+                        break;
+                    default:
+                        BIO_write(io, myp, 1);
+                        break;
+                    }
+                BIO_write(io, " ", 1);
+            }
+            BIO_puts(io, "\n");
+
+            BIO_printf(io,
+                       "Secure Renegotiation IS%s supported\n",
+                       SSL_get_secure_renegotiation_support(con) ?
+                       "" : " NOT");
+
+            /*
+             * The following is evil and should not really be done
+             */
+            BIO_printf(io, "Ciphers supported in s_server binary\n");
+            sk = SSL_get_ciphers(con);
+            j = sk_SSL_CIPHER_num(sk);
+            for (i = 0; i < j; i++) {
+                c = sk_SSL_CIPHER_value(sk, i);
+                BIO_printf(io, "%-11s:%-25s ",
+                           SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
+                if ((((i + 1) % 2) == 0) && (i + 1 != j))
+                    BIO_puts(io, "\n");
+            }
+            BIO_puts(io, "\n");
+            p = SSL_get_shared_ciphers(con, buf, bufsize);
+            if (p != NULL) {
+                BIO_printf(io,
+                           "---\nCiphers common between both SSL end points:\n");
+                j = i = 0;
+                while (*p) {
+                    if (*p == ':') {
+                        BIO_write(io, space, 26 - j);
+                        i++;
+                        j = 0;
+                        BIO_write(io, ((i % 3) ? " " : "\n"), 1);
+                    } else {
+                        BIO_write(io, p, 1);
+                        j++;
+                    }
+                    p++;
+                }
+                BIO_puts(io, "\n");
+            }
+            ssl_print_sigalgs(io, con);
+#ifndef OPENSSL_NO_EC
+            ssl_print_curves(io, con, 0);
+#endif
+            BIO_printf(io, (SSL_session_reused(con)
+                            ? "---\nReused, " : "---\nNew, "));
+            c = SSL_get_current_cipher(con);
+            BIO_printf(io, "%s, Cipher is %s\n",
+                       SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
+            SSL_SESSION_print(io, SSL_get_session(con));
+            BIO_printf(io, "---\n");
+            print_stats(io, SSL_get_SSL_CTX(con));
+            BIO_printf(io, "---\n");
+            peer = SSL_get_peer_certificate(con);
+            if (peer != NULL) {
+                BIO_printf(io, "Client certificate\n");
+                X509_print(io, peer);
+                PEM_write_bio_X509(io, peer);
+                X509_free(peer);
+                peer = NULL;
+            } else
+                BIO_puts(io, "no client certificate available\n");
+            BIO_puts(io, "</BODY></HTML>\r\n\r\n");
+            break;
+        } else if ((www == 2 || www == 3)
+                   && (strncmp("GET /", buf, 5) == 0)) {
+            BIO *file;
+            char *p, *e;
+            static const char *text =
+                "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
+
+            /* skip the '/' */
+            p = &(buf[5]);
+
+            dot = 1;
+            for (e = p; *e != '\0'; e++) {
+                if (e[0] == ' ')
+                    break;
+
+                switch (dot) {
+                case 1:
+                    dot = (e[0] == '.') ? 2 : 0;
+                    break;
+                case 2:
+                    dot = (e[0] == '.') ? 3 : 0;
+                    break;
+                case 3:
+                    dot = (e[0] == '/') ? -1 : 0;
+                    break;
+                }
+                if (dot == 0)
+                    dot = (e[0] == '/') ? 1 : 0;
+            }
+            dot = (dot == 3) || (dot == -1); /* filename contains ".."
+                                              * component */
+
+            if (*e == '\0') {
+                BIO_puts(io, text);
+                BIO_printf(io, "'%s' is an invalid file name\r\n", p);
+                break;
+            }
+            *e = '\0';
+
+            if (dot) {
+                BIO_puts(io, text);
+                BIO_printf(io, "'%s' contains '..' reference\r\n", p);
+                break;
+            }
+
+            if (*p == '/') {
+                BIO_puts(io, text);
+                BIO_printf(io, "'%s' is an invalid path\r\n", p);
+                break;
+            }
+
+            /* if a directory, do the index thang */
+            if (app_isdir(p) > 0) {
+                BIO_puts(io, text);
+                BIO_printf(io, "'%s' is a directory\r\n", p);
+                break;
+            }
+
+            if ((file = BIO_new_file(p, "r")) == NULL) {
+                BIO_puts(io, text);
+                BIO_printf(io, "Error opening '%s'\r\n", p);
+                ERR_print_errors(io);
+                break;
+            }
+
+            if (!s_quiet)
+                BIO_printf(bio_err, "FILE:%s\n", p);
+
+            if (www == 2) {
+                i = strlen(p);
+                if (((i > 5) && (strcmp(&(p[i - 5]), ".html") == 0)) ||
+                    ((i > 4) && (strcmp(&(p[i - 4]), ".php") == 0)) ||
+                    ((i > 4) && (strcmp(&(p[i - 4]), ".htm") == 0)))
+                    BIO_puts(io,
+                             "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
+                else
+                    BIO_puts(io,
+                             "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
+            }
+            /* send the file */
+            for (;;) {
+                i = BIO_read(file, buf, bufsize);
+                if (i <= 0)
+                    break;
+
+#ifdef RENEG
+                total_bytes += i;
+                BIO_printf(bio_err, "%d\n", i);
+                if (total_bytes > 3 * 1024) {
+                    total_bytes = 0;
+                    BIO_printf(bio_err, "RENEGOTIATE\n");
+                    SSL_renegotiate(con);
+                }
+#endif
+
+                for (j = 0; j < i;) {
+#ifdef RENEG
+                    static count = 0;
+                    if (++count == 13) {
+                        SSL_renegotiate(con);
+                    }
+#endif
+                    k = BIO_write(io, &(buf[j]), i - j);
+                    if (k <= 0) {
+                        if (!BIO_should_retry(io)
+                            && !SSL_waiting_for_async(con))
+                            goto write_error;
+                        else {
+                            BIO_printf(bio_s_out, "rwrite W BLOCK\n");
+                        }
+                    } else {
+                        j += k;
+                    }
+                }
+            }
+ write_error:
+            BIO_free(file);
+            break;
+        }
+    }
+
+    for (;;) {
+        i = (int)BIO_flush(io);
+        if (i <= 0) {
+            if (!BIO_should_retry(io))
+                break;
+        } else
+            break;
+    }
+ end:
+    /* make sure we re-use sessions */
+    SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
+
+ err:
+    if (ret >= 0)
+        BIO_printf(bio_s_out, "ACCEPT\n");
+    OPENSSL_free(buf);
+    BIO_free_all(io);
+    return (ret);
+}
+
+static int rev_body(int s, int stype, unsigned char *context)
+{
+    char *buf = NULL;
+    int i;
+    int ret = 1;
+    SSL *con;
+    BIO *io, *ssl_bio, *sbio;
+
+    buf = app_malloc(bufsize, "server rev buffer");
+    io = BIO_new(BIO_f_buffer());
+    ssl_bio = BIO_new(BIO_f_ssl());
+    if ((io == NULL) || (ssl_bio == NULL))
+        goto err;
+
+    /* lets make the output buffer a reasonable size */
+    if (!BIO_set_write_buffer_size(io, bufsize))
+        goto err;
+
+    if ((con = SSL_new(ctx)) == NULL)
+        goto err;
+
+    if (s_tlsextdebug) {
+        SSL_set_tlsext_debug_callback(con, tlsext_cb);
+        SSL_set_tlsext_debug_arg(con, bio_s_out);
+    }
+    if (context
+        && !SSL_set_session_id_context(con, context,
+                                       strlen((char *)context))) {
+        ERR_print_errors(bio_err);
+        goto err;
+    }
+
+    sbio = BIO_new_socket(s, BIO_NOCLOSE);
+    SSL_set_bio(con, sbio, sbio);
+    SSL_set_accept_state(con);
+
+    BIO_set_ssl(ssl_bio, con, BIO_CLOSE);
+    BIO_push(io, ssl_bio);
+#ifdef CHARSET_EBCDIC
+    io = BIO_push(BIO_new(BIO_f_ebcdic_filter()), io);
+#endif
+
+    if (s_debug) {
+        BIO_set_callback(SSL_get_rbio(con), bio_dump_callback);
+        BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out);
+    }
+    if (s_msg) {
+#ifndef OPENSSL_NO_SSL_TRACE
+        if (s_msg == 2)
+            SSL_set_msg_callback(con, SSL_trace);
+        else
+#endif
+            SSL_set_msg_callback(con, msg_cb);
+        SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out);
+    }
+
+    for (;;) {
+        i = BIO_do_handshake(io);
+        if (i > 0)
+            break;
+        if (!BIO_should_retry(io)) {
+            BIO_puts(bio_err, "CONNECTION FAILURE\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+#ifndef OPENSSL_NO_SRP
+        if (BIO_should_io_special(io)
+            && BIO_get_retry_reason(io) == BIO_RR_SSL_X509_LOOKUP) {
+            BIO_printf(bio_s_out, "LOOKUP renego during accept\n");
+            SRP_user_pwd_free(srp_callback_parm.user);
+            srp_callback_parm.user =
+                SRP_VBASE_get1_by_user(srp_callback_parm.vb,
+                                       srp_callback_parm.login);
+            if (srp_callback_parm.user)
+                BIO_printf(bio_s_out, "LOOKUP done %s\n",
+                           srp_callback_parm.user->info);
+            else
+                BIO_printf(bio_s_out, "LOOKUP not successful\n");
+            continue;
+        }
+#endif
+    }
+    BIO_printf(bio_err, "CONNECTION ESTABLISHED\n");
+    print_ssl_summary(con);
+
+    for (;;) {
+        i = BIO_gets(io, buf, bufsize - 1);
+        if (i < 0) {            /* error */
+            if (!BIO_should_retry(io)) {
+                if (!s_quiet)
+                    ERR_print_errors(bio_err);
+                goto err;
+            } else {
+                BIO_printf(bio_s_out, "read R BLOCK\n");
+#ifndef OPENSSL_NO_SRP
+                if (BIO_should_io_special(io)
+                    && BIO_get_retry_reason(io) == BIO_RR_SSL_X509_LOOKUP) {
+                    BIO_printf(bio_s_out, "LOOKUP renego during read\n");
+                    SRP_user_pwd_free(srp_callback_parm.user);
+                    srp_callback_parm.user =
+                        SRP_VBASE_get1_by_user(srp_callback_parm.vb,
+                                               srp_callback_parm.login);
+                    if (srp_callback_parm.user)
+                        BIO_printf(bio_s_out, "LOOKUP done %s\n",
+                                   srp_callback_parm.user->info);
+                    else
+                        BIO_printf(bio_s_out, "LOOKUP not successful\n");
+                    continue;
+                }
+#endif
+#if !defined(OPENSSL_SYS_MSDOS)
+                sleep(1);
+#endif
+                continue;
+            }
+        } else if (i == 0) {    /* end of input */
+            ret = 1;
+            BIO_printf(bio_err, "CONNECTION CLOSED\n");
+            goto end;
+        } else {
+            char *p = buf + i - 1;
+            while (i && (*p == '\n' || *p == '\r')) {
+                p--;
+                i--;
+            }
+            if (!s_ign_eof && (i == 5) && (strncmp(buf, "CLOSE", 5) == 0)) {
+                ret = 1;
+                BIO_printf(bio_err, "CONNECTION CLOSED\n");
+                goto end;
+            }
+            BUF_reverse((unsigned char *)buf, NULL, i);
+            buf[i] = '\n';
+            BIO_write(io, buf, i + 1);
+            for (;;) {
+                i = BIO_flush(io);
+                if (i > 0)
+                    break;
+                if (!BIO_should_retry(io))
+                    goto end;
+            }
+        }
+    }
+ end:
+    /* make sure we re-use sessions */
+    SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
+
+ err:
+
+    OPENSSL_free(buf);
+    BIO_free_all(io);
+    return (ret);
+}
+
+#define MAX_SESSION_ID_ATTEMPTS 10
+static int generate_session_id(const SSL *ssl, unsigned char *id,
+                               unsigned int *id_len)
+{
+    unsigned int count = 0;
+    do {
+        if (RAND_bytes(id, *id_len) <= 0)
+            return 0;
+        /*
+         * Prefix the session_id with the required prefix. NB: If our prefix
+         * is too long, clip it - but there will be worse effects anyway, eg.
+         * the server could only possibly create 1 session ID (ie. the
+         * prefix!) so all future session negotiations will fail due to
+         * conflicts.
+         */
+        memcpy(id, session_id_prefix,
+               (strlen(session_id_prefix) < *id_len) ?
+               strlen(session_id_prefix) : *id_len);
+    }
+    while (SSL_has_matching_session_id(ssl, id, *id_len) &&
+           (++count < MAX_SESSION_ID_ATTEMPTS));
+    if (count >= MAX_SESSION_ID_ATTEMPTS)
+        return 0;
+    return 1;
+}
+
+/*
+ * By default s_server uses an in-memory cache which caches SSL_SESSION
+ * structures without any serialisation. This hides some bugs which only
+ * become apparent in deployed servers. By implementing a basic external
+ * session cache some issues can be debugged using s_server.
+ */
+
+typedef struct simple_ssl_session_st {
+    unsigned char *id;
+    unsigned int idlen;
+    unsigned char *der;
+    int derlen;
+    struct simple_ssl_session_st *next;
+} simple_ssl_session;
+
+static simple_ssl_session *first = NULL;
+
+static int add_session(SSL *ssl, SSL_SESSION *session)
+{
+    simple_ssl_session *sess = app_malloc(sizeof(*sess), "get session");
+    unsigned char *p;
+
+    SSL_SESSION_get_id(session, &sess->idlen);
+    sess->derlen = i2d_SSL_SESSION(session, NULL);
+    if (sess->derlen < 0) {
+        BIO_printf(bio_err, "Error encoding session\n");
+        OPENSSL_free(sess);
+        return 0;
+    }
+
+    sess->id = OPENSSL_memdup(SSL_SESSION_get_id(session, NULL), sess->idlen);
+    sess->der = app_malloc(sess->derlen, "get session buffer");
+    if (!sess->id) {
+        BIO_printf(bio_err, "Out of memory adding to external cache\n");
+        OPENSSL_free(sess->id);
+        OPENSSL_free(sess->der);
+        OPENSSL_free(sess);
+        return 0;
+    }
+    p = sess->der;
+
+    /* Assume it still works. */
+    if (i2d_SSL_SESSION(session, &p) != sess->derlen) {
+        BIO_printf(bio_err, "Unexpected session encoding length\n");
+        OPENSSL_free(sess->id);
+        OPENSSL_free(sess->der);
+        OPENSSL_free(sess);
+        return 0;
+    }
+
+    sess->next = first;
+    first = sess;
+    BIO_printf(bio_err, "New session added to external cache\n");
+    return 0;
+}
+
+static SSL_SESSION *get_session(SSL *ssl, const unsigned char *id, int idlen,
+                                int *do_copy)
+{
+    simple_ssl_session *sess;
+    *do_copy = 0;
+    for (sess = first; sess; sess = sess->next) {
+        if (idlen == (int)sess->idlen && !memcmp(sess->id, id, idlen)) {
+            const unsigned char *p = sess->der;
+            BIO_printf(bio_err, "Lookup session: cache hit\n");
+            return d2i_SSL_SESSION(NULL, &p, sess->derlen);
+        }
+    }
+    BIO_printf(bio_err, "Lookup session: cache miss\n");
+    return NULL;
+}
+
+static void del_session(SSL_CTX *sctx, SSL_SESSION *session)
+{
+    simple_ssl_session *sess, *prev = NULL;
+    const unsigned char *id;
+    unsigned int idlen;
+    id = SSL_SESSION_get_id(session, &idlen);
+    for (sess = first; sess; sess = sess->next) {
+        if (idlen == sess->idlen && !memcmp(sess->id, id, idlen)) {
+            if (prev)
+                prev->next = sess->next;
+            else
+                first = sess->next;
+            OPENSSL_free(sess->id);
+            OPENSSL_free(sess->der);
+            OPENSSL_free(sess);
+            return;
+        }
+        prev = sess;
+    }
+}
+
+static void init_session_cache_ctx(SSL_CTX *sctx)
+{
+    SSL_CTX_set_session_cache_mode(sctx,
+                                   SSL_SESS_CACHE_NO_INTERNAL |
+                                   SSL_SESS_CACHE_SERVER);
+    SSL_CTX_sess_set_new_cb(sctx, add_session);
+    SSL_CTX_sess_set_get_cb(sctx, get_session);
+    SSL_CTX_sess_set_remove_cb(sctx, del_session);
+}
+
+static void free_sessions(void)
+{
+    simple_ssl_session *sess, *tsess;
+    for (sess = first; sess;) {
+        OPENSSL_free(sess->id);
+        OPENSSL_free(sess->der);
+        tsess = sess;
+        sess = sess->next;
+        OPENSSL_free(tsess);
+    }
+    first = NULL;
+}
+
+#endif                          /* OPENSSL_NO_SOCK */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/s_socket.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/s_socket.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/s_socket.c	(revision 331)
@@ -0,0 +1,201 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* socket-related functions used by s_client and s_server */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <openssl/opensslconf.h>
+
+/*
+ * With IPv6, it looks like Digital has mixed up the proper order of
+ * recursive header file inclusion, resulting in the compiler complaining
+ * that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which is
+ * needed to have fileno() declared correctly...  So let's define u_int
+ */
+#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
+# define __U_INT
+typedef unsigned int u_int;
+#endif
+
+#ifndef OPENSSL_NO_SOCK
+
+# define USE_SOCKETS
+# include "apps.h"
+# undef USE_SOCKETS
+# include "s_apps.h"
+
+# include <openssl/bio.h>
+# include <openssl/err.h>
+
+/*
+ * init_client - helper routine to set up socket communication
+ * @sock: pointer to storage of resulting socket.
+ * @host: the host name or path (for AF_UNIX) to connect to.
+ * @port: the port to connect to (ignored for AF_UNIX).
+ * @family: desired socket family, may be AF_INET, AF_INET6, AF_UNIX or
+ *  AF_UNSPEC
+ * @type: socket type, must be SOCK_STREAM or SOCK_DGRAM
+ *
+ * This will create a socket and use it to connect to a host:port, or if
+ * family == AF_UNIX, to the path found in host.
+ *
+ * If the host has more than one address, it will try them one by one until
+ * a successful connection is established.  The resulting socket will be
+ * found in *sock on success, it will be given INVALID_SOCKET otherwise.
+ *
+ * Returns 1 on success, 0 on failure.
+ */
+int init_client(int *sock, const char *host, const char *port,
+                int family, int type)
+{
+    BIO_ADDRINFO *res = NULL;
+    const BIO_ADDRINFO *ai = NULL;
+    int ret;
+
+    if (!BIO_sock_init())
+        return 0;
+
+    ret = BIO_lookup(host, port, BIO_LOOKUP_CLIENT, family, type, &res);
+    if (ret == 0) {
+        ERR_print_errors(bio_err);
+        return 0;
+    }
+
+    ret = 0;
+    for (ai = res; ai != NULL; ai = BIO_ADDRINFO_next(ai)) {
+        /* Admittedly, these checks are quite paranoid, we should not get
+         * anything in the BIO_ADDRINFO chain that we haven't
+         * asked for. */
+        OPENSSL_assert((family == AF_UNSPEC || family == BIO_ADDRINFO_family(res))
+                       && (type == 0 || type == BIO_ADDRINFO_socktype(res)));
+
+        *sock = BIO_socket(BIO_ADDRINFO_family(ai), BIO_ADDRINFO_socktype(ai),
+                           BIO_ADDRINFO_protocol(res), 0);
+        if (*sock == INVALID_SOCKET) {
+            /* Maybe the kernel doesn't support the socket family, even if
+             * BIO_lookup() added it in the returned result...
+             */
+            continue;
+        }
+        if (!BIO_connect(*sock, BIO_ADDRINFO_address(ai), 0)) {
+            BIO_closesocket(*sock);
+            *sock = INVALID_SOCKET;
+            continue;
+        }
+
+        /* Success, don't try any more addresses */
+        break;
+    }
+
+    if (*sock == INVALID_SOCKET) {
+        ERR_print_errors(bio_err);
+    } else {
+        /* Remove any stale errors from previous connection attempts */
+        ERR_clear_error();
+        ret = 1;
+    }
+    BIO_ADDRINFO_free(res);
+    return ret;
+}
+
+/*
+ * do_server - helper routine to perform a server operation
+ * @accept_sock: pointer to storage of resulting socket.
+ * @host: the host name or path (for AF_UNIX) to connect to.
+ * @port: the port to connect to (ignored for AF_UNIX).
+ * @family: desired socket family, may be AF_INET, AF_INET6, AF_UNIX or
+ *  AF_UNSPEC
+ * @type: socket type, must be SOCK_STREAM or SOCK_DGRAM
+ * @cb: pointer to a function that receives the accepted socket and
+ *  should perform the communication with the connecting client.
+ * @context: pointer to memory that's passed verbatim to the cb function.
+ * @naccept: number of times an incoming connect should be accepted.  If -1,
+ *  unlimited number.
+ *
+ * This will create a socket and use it to listen to a host:port, or if
+ * family == AF_UNIX, to the path found in host, then start accepting
+ * incoming connections and run cb on the resulting socket.
+ *
+ * 0 on failure, something other on success.
+ */
+int do_server(int *accept_sock, const char *host, const char *port,
+              int family, int type, do_server_cb cb,
+              unsigned char *context, int naccept)
+{
+    int asock = 0;
+    int sock;
+    int i;
+    BIO_ADDRINFO *res = NULL;
+    int ret = 0;
+
+    if (!BIO_sock_init())
+        return 0;
+
+    if (!BIO_lookup(host, port, BIO_LOOKUP_SERVER, family, type, &res)) {
+        ERR_print_errors(bio_err);
+        return 0;
+    }
+
+    /* Admittedly, these checks are quite paranoid, we should not get
+     * anything in the BIO_ADDRINFO chain that we haven't asked for */
+    OPENSSL_assert((family == AF_UNSPEC || family == BIO_ADDRINFO_family(res))
+                   && (type == 0 || type == BIO_ADDRINFO_socktype(res)));
+
+    asock = BIO_socket(BIO_ADDRINFO_family(res), BIO_ADDRINFO_socktype(res),
+                       BIO_ADDRINFO_protocol(res), 0);
+    if (asock == INVALID_SOCKET
+        || !BIO_listen(asock, BIO_ADDRINFO_address(res), BIO_SOCK_REUSEADDR)) {
+        BIO_ADDRINFO_free(res);
+        ERR_print_errors(bio_err);
+        if (asock != INVALID_SOCKET)
+            BIO_closesocket(asock);
+        goto end;
+    }
+
+    BIO_ADDRINFO_free(res);
+    res = NULL;
+
+    if (accept_sock != NULL)
+        *accept_sock = asock;
+    for (;;) {
+        if (type == SOCK_STREAM) {
+            do {
+                sock = BIO_accept_ex(asock, NULL, 0);
+            } while (sock < 0 && BIO_sock_should_retry(ret));
+            if (sock < 0) {
+                ERR_print_errors(bio_err);
+                BIO_closesocket(asock);
+                break;
+            }
+            i = (*cb)(sock, type, context);
+            BIO_closesocket(sock);
+        } else {
+            i = (*cb)(asock, type, context);
+        }
+
+        if (naccept != -1)
+            naccept--;
+        if (i < 0 || naccept == 0) {
+            BIO_closesocket(asock);
+            ret = i;
+            break;
+        }
+    }
+ end:
+# ifdef AF_UNIX
+    if (family == AF_UNIX)
+        unlink(host);
+# endif
+    return ret;
+}
+
+#endif  /* OPENSSL_NO_SOCK */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/s_time.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/s_time.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/s_time.c	(revision 331)
@@ -0,0 +1,422 @@
+/*
+ * Copyright 1995-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
+ */
+
+#define NO_SHUTDOWN
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_NO_SOCK
+
+#define USE_SOCKETS
+#include "apps.h"
+#include <openssl/x509.h>
+#include <openssl/ssl.h>
+#include <openssl/pem.h>
+#include "s_apps.h"
+#include <openssl/err.h>
+#if !defined(OPENSSL_SYS_MSDOS)
+# include OPENSSL_UNISTD
+#endif
+
+#undef ioctl
+#define ioctl ioctlsocket
+
+#define SSL_CONNECT_NAME        "localhost:4433"
+
+/* no default cert. */
+/*
+ * #define TEST_CERT "client.pem"
+ */
+
+#undef min
+#undef max
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+
+#undef SECONDS
+#define SECONDS 30
+#define SECONDSSTR "30"
+
+static SSL *doConnection(SSL *scon, const char *host, SSL_CTX *ctx);
+
+static const char fmt_http_get_cmd[] = "GET %s HTTP/1.0\r\n\r\n";
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_CONNECT, OPT_CIPHER, OPT_CERT, OPT_KEY, OPT_CAPATH,
+    OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NEW, OPT_REUSE, OPT_BUGS,
+    OPT_VERIFY, OPT_TIME, OPT_SSL3,
+    OPT_WWW
+} OPTION_CHOICE;
+
+OPTIONS s_time_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"connect", OPT_CONNECT, 's',
+     "Where to connect as post:port (default is " SSL_CONNECT_NAME ")"},
+    {"cipher", OPT_CIPHER, 's', "Cipher to use, see 'openssl ciphers'"},
+    {"cert", OPT_CERT, '<', "Cert file to use, PEM format assumed"},
+    {"key", OPT_KEY, '<', "File with key, PEM; default is -cert file"},
+    {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"},
+    {"cafile", OPT_CAFILE, '<', "PEM format file of CA's"},
+    {"no-CAfile", OPT_NOCAFILE, '-',
+     "Do not load the default certificates file"},
+    {"no-CApath", OPT_NOCAPATH, '-',
+     "Do not load certificates from the default certificates directory"},
+    {"new", OPT_NEW, '-', "Just time new connections"},
+    {"reuse", OPT_REUSE, '-', "Just time connection reuse"},
+    {"bugs", OPT_BUGS, '-', "Turn on SSL bug compatibility"},
+    {"verify", OPT_VERIFY, 'p',
+     "Turn on peer certificate verification, set depth"},
+    {"time", OPT_TIME, 'p', "Seconds to collect data, default " SECONDSSTR},
+    {"www", OPT_WWW, 's', "Fetch specified page from the site"},
+#ifndef OPENSSL_NO_SSL3
+    {"ssl3", OPT_SSL3, '-', "Just use SSLv3"},
+#endif
+    {NULL}
+};
+
+#define START   0
+#define STOP    1
+
+static double tm_Time_F(int s)
+{
+    return app_tminterval(s, 1);
+}
+
+int s_time_main(int argc, char **argv)
+{
+    char buf[1024 * 8];
+    SSL *scon = NULL;
+    SSL_CTX *ctx = NULL;
+    const SSL_METHOD *meth = NULL;
+    char *CApath = NULL, *CAfile = NULL, *cipher = NULL, *www_path = NULL;
+    char *host = SSL_CONNECT_NAME, *certfile = NULL, *keyfile = NULL, *prog;
+    double totalTime = 0.0;
+    int noCApath = 0, noCAfile = 0;
+    int maxtime = SECONDS, nConn = 0, perform = 3, ret = 1, i, st_bugs = 0;
+    long bytes_read = 0, finishtime = 0;
+    OPTION_CHOICE o;
+    int max_version = 0, ver, buf_len;
+    size_t buf_size;
+
+    meth = TLS_client_method();
+
+    prog = opt_init(argc, argv, s_time_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(s_time_options);
+            ret = 0;
+            goto end;
+        case OPT_CONNECT:
+            host = opt_arg();
+            break;
+        case OPT_REUSE:
+            perform = 2;
+            break;
+        case OPT_NEW:
+            perform = 1;
+            break;
+        case OPT_VERIFY:
+            if (!opt_int(opt_arg(), &verify_args.depth))
+                goto opthelp;
+            BIO_printf(bio_err, "%s: verify depth is %d\n",
+                       prog, verify_args.depth);
+            break;
+        case OPT_CERT:
+            certfile = opt_arg();
+            break;
+        case OPT_KEY:
+            keyfile = opt_arg();
+            break;
+        case OPT_CAPATH:
+            CApath = opt_arg();
+            break;
+        case OPT_CAFILE:
+            CAfile = opt_arg();
+            break;
+        case OPT_NOCAPATH:
+            noCApath = 1;
+            break;
+        case OPT_NOCAFILE:
+            noCAfile = 1;
+            break;
+        case OPT_CIPHER:
+            cipher = opt_arg();
+            break;
+        case OPT_BUGS:
+            st_bugs = 1;
+            break;
+        case OPT_TIME:
+            if (!opt_int(opt_arg(), &maxtime))
+                goto opthelp;
+            break;
+        case OPT_WWW:
+            www_path = opt_arg();
+            buf_size = strlen(www_path) + sizeof(fmt_http_get_cmd) - 2;  /* 2 is for %s */
+            if (buf_size > sizeof(buf)) {
+                BIO_printf(bio_err, "%s: -www option is too long\n", prog);
+                goto end;
+            }
+            break;
+        case OPT_SSL3:
+            max_version = SSL3_VERSION;
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    if (cipher == NULL)
+        cipher = getenv("SSL_CIPHER");
+    if (cipher == NULL) {
+        BIO_printf(bio_err, "No CIPHER specified\n");
+        goto end;
+    }
+
+    if ((ctx = SSL_CTX_new(meth)) == NULL)
+        goto end;
+
+    SSL_CTX_set_quiet_shutdown(ctx, 1);
+    if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
+        goto end;
+
+    if (st_bugs)
+        SSL_CTX_set_options(ctx, SSL_OP_ALL);
+    if (!SSL_CTX_set_cipher_list(ctx, cipher))
+        goto end;
+    if (!set_cert_stuff(ctx, certfile, keyfile))
+        goto end;
+
+    if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) {
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+    if (!(perform & 1))
+        goto next;
+    printf("Collecting connection statistics for %d seconds\n", maxtime);
+
+    /* Loop and time how long it takes to make connections */
+
+    bytes_read = 0;
+    finishtime = (long)time(NULL) + maxtime;
+    tm_Time_F(START);
+    for (;;) {
+        if (finishtime < (long)time(NULL))
+            break;
+
+        if ((scon = doConnection(NULL, host, ctx)) == NULL)
+            goto end;
+
+        if (www_path != NULL) {
+            buf_len = BIO_snprintf(buf, sizeof buf,
+                                   fmt_http_get_cmd, www_path);
+            if (SSL_write(scon, buf, buf_len) <= 0)
+                goto end;
+            while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
+                bytes_read += i;
+        }
+#ifdef NO_SHUTDOWN
+        SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
+#else
+        SSL_shutdown(scon);
+#endif
+        BIO_closesocket(SSL_get_fd(scon));
+
+        nConn += 1;
+        if (SSL_session_reused(scon))
+            ver = 'r';
+        else {
+            ver = SSL_version(scon);
+            if (ver == TLS1_VERSION)
+                ver = 't';
+            else if (ver == SSL3_VERSION)
+                ver = '3';
+            else
+                ver = '*';
+        }
+        fputc(ver, stdout);
+        fflush(stdout);
+
+        SSL_free(scon);
+        scon = NULL;
+    }
+    totalTime += tm_Time_F(STOP); /* Add the time for this iteration */
+
+    i = (int)((long)time(NULL) - finishtime + maxtime);
+    printf
+        ("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n",
+         nConn, totalTime, ((double)nConn / totalTime), bytes_read);
+    printf
+        ("%d connections in %ld real seconds, %ld bytes read per connection\n",
+         nConn, (long)time(NULL) - finishtime + maxtime, bytes_read / nConn);
+
+    /*
+     * Now loop and time connections using the same session id over and over
+     */
+
+ next:
+    if (!(perform & 2))
+        goto end;
+    printf("\n\nNow timing with session id reuse.\n");
+
+    /* Get an SSL object so we can reuse the session id */
+    if ((scon = doConnection(NULL, host, ctx)) == NULL) {
+        BIO_printf(bio_err, "Unable to get connection\n");
+        goto end;
+    }
+
+    if (www_path != NULL) {
+        buf_len = BIO_snprintf(buf, sizeof buf,
+                               fmt_http_get_cmd, www_path);
+        if (SSL_write(scon, buf, buf_len) <= 0)
+            goto end;
+        while (SSL_read(scon, buf, sizeof(buf)) > 0)
+            continue;
+    }
+#ifdef NO_SHUTDOWN
+    SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
+#else
+    SSL_shutdown(scon);
+#endif
+    BIO_closesocket(SSL_get_fd(scon));
+
+    nConn = 0;
+    totalTime = 0.0;
+
+    finishtime = (long)time(NULL) + maxtime;
+
+    printf("starting\n");
+    bytes_read = 0;
+    tm_Time_F(START);
+
+    for (;;) {
+        if (finishtime < (long)time(NULL))
+            break;
+
+        if ((doConnection(scon, host, ctx)) == NULL)
+            goto end;
+
+        if (www_path) {
+            BIO_snprintf(buf, sizeof buf, "GET %s HTTP/1.0\r\n\r\n",
+                         www_path);
+            if (SSL_write(scon, buf, strlen(buf)) <= 0)
+                goto end;
+            while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
+                bytes_read += i;
+        }
+#ifdef NO_SHUTDOWN
+        SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
+#else
+        SSL_shutdown(scon);
+#endif
+        BIO_closesocket(SSL_get_fd(scon));
+
+        nConn += 1;
+        if (SSL_session_reused(scon))
+            ver = 'r';
+        else {
+            ver = SSL_version(scon);
+            if (ver == TLS1_VERSION)
+                ver = 't';
+            else if (ver == SSL3_VERSION)
+                ver = '3';
+            else
+                ver = '*';
+        }
+        fputc(ver, stdout);
+        fflush(stdout);
+    }
+    totalTime += tm_Time_F(STOP); /* Add the time for this iteration */
+
+    printf
+        ("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n",
+         nConn, totalTime, ((double)nConn / totalTime), bytes_read);
+    printf
+        ("%d connections in %ld real seconds, %ld bytes read per connection\n",
+         nConn, (long)time(NULL) - finishtime + maxtime, bytes_read / nConn);
+
+    ret = 0;
+
+ end:
+    SSL_free(scon);
+    SSL_CTX_free(ctx);
+    return (ret);
+}
+
+/*-
+ * doConnection - make a connection
+ */
+static SSL *doConnection(SSL *scon, const char *host, SSL_CTX *ctx)
+{
+    BIO *conn;
+    SSL *serverCon;
+    int width, i;
+    fd_set readfds;
+
+    if ((conn = BIO_new(BIO_s_connect())) == NULL)
+        return (NULL);
+
+    BIO_set_conn_hostname(conn, host);
+
+    if (scon == NULL)
+        serverCon = SSL_new(ctx);
+    else {
+        serverCon = scon;
+        SSL_set_connect_state(serverCon);
+    }
+
+    SSL_set_bio(serverCon, conn, conn);
+
+    /* ok, lets connect */
+    for (;;) {
+        i = SSL_connect(serverCon);
+        if (BIO_sock_should_retry(i)) {
+            BIO_printf(bio_err, "DELAY\n");
+
+            i = SSL_get_fd(serverCon);
+            width = i + 1;
+            FD_ZERO(&readfds);
+            openssl_fdset(i, &readfds);
+            /*
+             * Note: under VMS with SOCKETSHR the 2nd parameter is currently
+             * of type (int *) whereas under other systems it is (void *) if
+             * you don't have a cast it will choke the compiler: if you do
+             * have a cast then you can either go for (int *) or (void *).
+             */
+            select(width, (void *)&readfds, NULL, NULL, NULL);
+            continue;
+        }
+        break;
+    }
+    if (i <= 0) {
+        BIO_printf(bio_err, "ERROR\n");
+        if (verify_args.error != X509_V_OK)
+            BIO_printf(bio_err, "verify error:%s\n",
+                       X509_verify_cert_error_string(verify_args.error));
+        else
+            ERR_print_errors(bio_err);
+        if (scon == NULL)
+            SSL_free(serverCon);
+        return NULL;
+    }
+
+    return serverCon;
+}
+#endif /* OPENSSL_NO_SOCK */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/sess_id.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/sess_id.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/sess_id.c	(revision 331)
@@ -0,0 +1,190 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT,
+    OPT_TEXT, OPT_CERT, OPT_NOOUT, OPT_CONTEXT
+} OPTION_CHOICE;
+
+OPTIONS sess_id_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"inform", OPT_INFORM, 'F', "Input format - default PEM (DER or PEM)"},
+    {"outform", OPT_OUTFORM, 'f',
+     "Output format - default PEM (PEM, DER or NSS)"},
+    {"in", OPT_IN, 's', "Input file - default stdin"},
+    {"out", OPT_OUT, 's', "Output file - default stdout"},
+    {"text", OPT_TEXT, '-', "Print ssl session id details"},
+    {"cert", OPT_CERT, '-', "Output certificate "},
+    {"noout", OPT_NOOUT, '-', "Don't output the encoded session info"},
+    {"context", OPT_CONTEXT, 's', "Set the session ID context"},
+    {NULL}
+};
+
+static SSL_SESSION *load_sess_id(char *file, int format);
+
+int sess_id_main(int argc, char **argv)
+{
+    SSL_SESSION *x = NULL;
+    X509 *peer = NULL;
+    BIO *out = NULL;
+    char *infile = NULL, *outfile = NULL, *context = NULL, *prog;
+    int informat = FORMAT_PEM, outformat = FORMAT_PEM;
+    int cert = 0, noout = 0, text = 0, ret = 1, i, num = 0;
+    OPTION_CHOICE o;
+
+    prog = opt_init(argc, argv, sess_id_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(sess_id_options);
+            ret = 0;
+            goto end;
+        case OPT_INFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
+                goto opthelp;
+            break;
+        case OPT_OUTFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER | OPT_FMT_NSS,
+                            &outformat))
+                goto opthelp;
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_TEXT:
+            text = ++num;
+            break;
+        case OPT_CERT:
+            cert = ++num;
+            break;
+        case OPT_NOOUT:
+            noout = ++num;
+            break;
+        case OPT_CONTEXT:
+            context = opt_arg();
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    x = load_sess_id(infile, informat);
+    if (x == NULL) {
+        goto end;
+    }
+    peer = SSL_SESSION_get0_peer(x);
+
+    if (context) {
+        size_t ctx_len = strlen(context);
+        if (ctx_len > SSL_MAX_SID_CTX_LENGTH) {
+            BIO_printf(bio_err, "Context too long\n");
+            goto end;
+        }
+        if (!SSL_SESSION_set1_id_context(x, (unsigned char *)context,
+                    ctx_len)) {
+            BIO_printf(bio_err, "Error setting id context\n");
+            goto end;
+        }
+    }
+
+    if (!noout || text) {
+        out = bio_open_default(outfile, 'w', outformat);
+        if (out == NULL)
+            goto end;
+    }
+
+    if (text) {
+        SSL_SESSION_print(out, x);
+
+        if (cert) {
+            if (peer == NULL)
+                BIO_puts(out, "No certificate present\n");
+            else
+                X509_print(out, peer);
+        }
+    }
+
+    if (!noout && !cert) {
+        if (outformat == FORMAT_ASN1)
+            i = i2d_SSL_SESSION_bio(out, x);
+        else if (outformat == FORMAT_PEM)
+            i = PEM_write_bio_SSL_SESSION(out, x);
+        else if (outformat == FORMAT_NSS)
+            i = SSL_SESSION_print_keylog(out, x);
+        else {
+            BIO_printf(bio_err, "bad output format specified for outfile\n");
+            goto end;
+        }
+        if (!i) {
+            BIO_printf(bio_err, "unable to write SSL_SESSION\n");
+            goto end;
+        }
+    } else if (!noout && (peer != NULL)) { /* just print the certificate */
+        if (outformat == FORMAT_ASN1)
+            i = (int)i2d_X509_bio(out, peer);
+        else if (outformat == FORMAT_PEM)
+            i = PEM_write_bio_X509(out, peer);
+        else {
+            BIO_printf(bio_err, "bad output format specified for outfile\n");
+            goto end;
+        }
+        if (!i) {
+            BIO_printf(bio_err, "unable to write X509\n");
+            goto end;
+        }
+    }
+    ret = 0;
+ end:
+    BIO_free_all(out);
+    SSL_SESSION_free(x);
+    return (ret);
+}
+
+static SSL_SESSION *load_sess_id(char *infile, int format)
+{
+    SSL_SESSION *x = NULL;
+    BIO *in = NULL;
+
+    in = bio_open_default(infile, 'r', format);
+    if (in == NULL)
+        goto end;
+    if (format == FORMAT_ASN1)
+        x = d2i_SSL_SESSION_bio(in, NULL);
+    else
+        x = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL);
+    if (x == NULL) {
+        BIO_printf(bio_err, "unable to load SSL_SESSION\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+ end:
+    BIO_free(in);
+    return (x);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/smime.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/smime.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/smime.c	(revision 331)
@@ -0,0 +1,656 @@
+/*
+ * Copyright 1999-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
+ */
+
+/* S/MIME utility function */
+
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/crypto.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/x509_vfy.h>
+#include <openssl/x509v3.h>
+
+static int save_certs(char *signerfile, STACK_OF(X509) *signers);
+static int smime_cb(int ok, X509_STORE_CTX *ctx);
+
+#define SMIME_OP        0x10
+#define SMIME_IP        0x20
+#define SMIME_SIGNERS   0x40
+#define SMIME_ENCRYPT   (1 | SMIME_OP)
+#define SMIME_DECRYPT   (2 | SMIME_IP)
+#define SMIME_SIGN      (3 | SMIME_OP | SMIME_SIGNERS)
+#define SMIME_VERIFY    (4 | SMIME_IP)
+#define SMIME_PK7OUT    (5 | SMIME_IP | SMIME_OP)
+#define SMIME_RESIGN    (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_ENCRYPT, OPT_DECRYPT, OPT_SIGN, OPT_RESIGN, OPT_VERIFY,
+    OPT_PK7OUT, OPT_TEXT, OPT_NOINTERN, OPT_NOVERIFY, OPT_NOCHAIN,
+    OPT_NOCERTS, OPT_NOATTR, OPT_NODETACH, OPT_NOSMIMECAP,
+    OPT_BINARY, OPT_NOSIGS, OPT_STREAM, OPT_INDEF, OPT_NOINDEF,
+    OPT_CRLFEOL, OPT_RAND, OPT_ENGINE, OPT_PASSIN,
+    OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP, OPT_MD,
+    OPT_CIPHER, OPT_INKEY, OPT_KEYFORM, OPT_CERTFILE, OPT_CAFILE,
+    OPT_V_ENUM,
+    OPT_CAPATH, OPT_NOCAFILE, OPT_NOCAPATH, OPT_IN, OPT_INFORM, OPT_OUT,
+    OPT_OUTFORM, OPT_CONTENT
+} OPTION_CHOICE;
+
+OPTIONS smime_options[] = {
+    {OPT_HELP_STR, 1, '-', "Usage: %s [options] cert.pem...\n"},
+    {OPT_HELP_STR, 1, '-',
+        "  cert.pem... recipient certs for encryption\n"},
+    {OPT_HELP_STR, 1, '-', "Valid options are:\n"},
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"encrypt", OPT_ENCRYPT, '-', "Encrypt message"},
+    {"decrypt", OPT_DECRYPT, '-', "Decrypt encrypted message"},
+    {"sign", OPT_SIGN, '-', "Sign message"},
+    {"verify", OPT_VERIFY, '-', "Verify signed message"},
+    {"pk7out", OPT_PK7OUT, '-', "Output PKCS#7 structure"},
+    {"nointern", OPT_NOINTERN, '-',
+     "Don't search certificates in message for signer"},
+    {"nosigs", OPT_NOSIGS, '-', "Don't verify message signature"},
+    {"noverify", OPT_NOVERIFY, '-', "Don't verify signers certificate"},
+    {"nocerts", OPT_NOCERTS, '-',
+     "Don't include signers certificate when signing"},
+    {"nodetach", OPT_NODETACH, '-', "Use opaque signing"},
+    {"noattr", OPT_NOATTR, '-', "Don't include any signed attributes"},
+    {"binary", OPT_BINARY, '-', "Don't translate message to text"},
+    {"certfile", OPT_CERTFILE, '<', "Other certificates file"},
+    {"signer", OPT_SIGNER, 's', "Signer certificate file"},
+    {"recip", OPT_RECIP, '<', "Recipient certificate file for decryption"},
+    {"in", OPT_IN, '<', "Input file"},
+    {"inform", OPT_INFORM, 'c', "Input format SMIME (default), PEM or DER"},
+    {"inkey", OPT_INKEY, '<',
+     "Input private key (if not signer or recipient)"},
+    {"keyform", OPT_KEYFORM, 'f', "Input private key format (PEM or ENGINE)"},
+    {"out", OPT_OUT, '>', "Output file"},
+    {"outform", OPT_OUTFORM, 'c',
+     "Output format SMIME (default), PEM or DER"},
+    {"content", OPT_CONTENT, '<',
+     "Supply or override content for detached signature"},
+    {"to", OPT_TO, 's', "To address"},
+    {"from", OPT_FROM, 's', "From address"},
+    {"subject", OPT_SUBJECT, 's', "Subject"},
+    {"text", OPT_TEXT, '-', "Include or delete text MIME headers"},
+    {"CApath", OPT_CAPATH, '/', "Trusted certificates directory"},
+    {"CAfile", OPT_CAFILE, '<', "Trusted certificates file"},
+    {"no-CAfile", OPT_NOCAFILE, '-',
+     "Do not load the default certificates file"},
+    {"no-CApath", OPT_NOCAPATH, '-',
+     "Do not load certificates from the default certificates directory"},
+    {"resign", OPT_RESIGN, '-', "Resign a signed message"},
+    {"nochain", OPT_NOCHAIN, '-', 
+     "set PKCS7_NOCHAIN so certificates contained in the message are not used as untrusted CAs" },
+    {"nosmimecap", OPT_NOSMIMECAP, '-', "Omit the SMIMECapabilities attribute"},
+    {"stream", OPT_STREAM, '-', "Enable CMS streaming" },
+    {"indef", OPT_INDEF, '-', "Same as -stream" },
+    {"noindef", OPT_NOINDEF, '-', "Disable CMS streaming"},
+    {"crlfeol", OPT_CRLFEOL, '-', "Use CRLF as EOL termination instead of CR only"},
+    {"rand", OPT_RAND, 's',
+     "Load the file(s) into the random number generator"},
+    {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
+    {"md", OPT_MD, 's', "Digest algorithm to use when signing or resigning"},
+    {"", OPT_CIPHER, '-', "Any supported cipher"},
+    OPT_V_OPTIONS,
+#ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+#endif
+    {NULL}
+};
+
+int smime_main(int argc, char **argv)
+{
+    BIO *in = NULL, *out = NULL, *indata = NULL;
+    EVP_PKEY *key = NULL;
+    PKCS7 *p7 = NULL;
+    STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL;
+    STACK_OF(X509) *encerts = NULL, *other = NULL;
+    X509 *cert = NULL, *recip = NULL, *signer = NULL;
+    X509_STORE *store = NULL;
+    X509_VERIFY_PARAM *vpm = NULL;
+    const EVP_CIPHER *cipher = NULL;
+    const EVP_MD *sign_md = NULL;
+    const char *CAfile = NULL, *CApath = NULL, *prog = NULL;
+    char *certfile = NULL, *keyfile = NULL, *contfile = NULL, *inrand = NULL;
+    char *infile = NULL, *outfile = NULL, *signerfile = NULL, *recipfile =
+        NULL;
+    char *passinarg = NULL, *passin = NULL, *to = NULL, *from =
+        NULL, *subject = NULL;
+    OPTION_CHOICE o;
+    int noCApath = 0, noCAfile = 0;
+    int flags = PKCS7_DETACHED, operation = 0, ret = 0, need_rand = 0, indef =
+        0;
+    int informat = FORMAT_SMIME, outformat = FORMAT_SMIME, keyform =
+        FORMAT_PEM;
+    int vpmtouched = 0, rv = 0;
+    ENGINE *e = NULL;
+    const char *mime_eol = "\n";
+
+    if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
+        return 1;
+
+    prog = opt_init(argc, argv, smime_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(smime_options);
+            ret = 0;
+            goto end;
+        case OPT_INFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PDS, &informat))
+                goto opthelp;
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUTFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PDS, &outformat))
+                goto opthelp;
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_ENCRYPT:
+            operation = SMIME_ENCRYPT;
+            break;
+        case OPT_DECRYPT:
+            operation = SMIME_DECRYPT;
+            break;
+        case OPT_SIGN:
+            operation = SMIME_SIGN;
+            break;
+        case OPT_RESIGN:
+            operation = SMIME_RESIGN;
+            break;
+        case OPT_VERIFY:
+            operation = SMIME_VERIFY;
+            break;
+        case OPT_PK7OUT:
+            operation = SMIME_PK7OUT;
+            break;
+        case OPT_TEXT:
+            flags |= PKCS7_TEXT;
+            break;
+        case OPT_NOINTERN:
+            flags |= PKCS7_NOINTERN;
+            break;
+        case OPT_NOVERIFY:
+            flags |= PKCS7_NOVERIFY;
+            break;
+        case OPT_NOCHAIN:
+            flags |= PKCS7_NOCHAIN;
+            break;
+        case OPT_NOCERTS:
+            flags |= PKCS7_NOCERTS;
+            break;
+        case OPT_NOATTR:
+            flags |= PKCS7_NOATTR;
+            break;
+        case OPT_NODETACH:
+            flags &= ~PKCS7_DETACHED;
+            break;
+        case OPT_NOSMIMECAP:
+            flags |= PKCS7_NOSMIMECAP;
+            break;
+        case OPT_BINARY:
+            flags |= PKCS7_BINARY;
+            break;
+        case OPT_NOSIGS:
+            flags |= PKCS7_NOSIGS;
+            break;
+        case OPT_STREAM:
+        case OPT_INDEF:
+            indef = 1;
+            break;
+        case OPT_NOINDEF:
+            indef = 0;
+            break;
+        case OPT_CRLFEOL:
+            flags |= PKCS7_CRLFEOL;
+            mime_eol = "\r\n";
+            break;
+        case OPT_RAND:
+            inrand = opt_arg();
+            need_rand = 1;
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        case OPT_PASSIN:
+            passinarg = opt_arg();
+            break;
+        case OPT_TO:
+            to = opt_arg();
+            break;
+        case OPT_FROM:
+            from = opt_arg();
+            break;
+        case OPT_SUBJECT:
+            subject = opt_arg();
+            break;
+        case OPT_SIGNER:
+            /* If previous -signer argument add signer to list */
+            if (signerfile) {
+                if (sksigners == NULL
+                    && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
+                    goto end;
+                sk_OPENSSL_STRING_push(sksigners, signerfile);
+                if (keyfile == NULL)
+                    keyfile = signerfile;
+                if (skkeys == NULL
+                    && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
+                    goto end;
+                sk_OPENSSL_STRING_push(skkeys, keyfile);
+                keyfile = NULL;
+            }
+            signerfile = opt_arg();
+            break;
+        case OPT_RECIP:
+            recipfile = opt_arg();
+            break;
+        case OPT_MD:
+            if (!opt_md(opt_arg(), &sign_md))
+                goto opthelp;
+            break;
+        case OPT_CIPHER:
+            if (!opt_cipher(opt_unknown(), &cipher))
+                goto opthelp;
+            break;
+        case OPT_INKEY:
+            /* If previous -inkey argument add signer to list */
+            if (keyfile) {
+                if (signerfile == NULL) {
+                    BIO_printf(bio_err,
+                               "%s: Must have -signer before -inkey\n", prog);
+                    goto opthelp;
+                }
+                if (sksigners == NULL
+                    && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
+                    goto end;
+                sk_OPENSSL_STRING_push(sksigners, signerfile);
+                signerfile = NULL;
+                if (skkeys == NULL
+                    && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
+                    goto end;
+                sk_OPENSSL_STRING_push(skkeys, keyfile);
+            }
+            keyfile = opt_arg();
+            break;
+        case OPT_KEYFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform))
+                goto opthelp;
+            break;
+        case OPT_CERTFILE:
+            certfile = opt_arg();
+            break;
+        case OPT_CAFILE:
+            CAfile = opt_arg();
+            break;
+        case OPT_CAPATH:
+            CApath = opt_arg();
+            break;
+        case OPT_NOCAFILE:
+            noCAfile = 1;
+            break;
+        case OPT_NOCAPATH:
+            noCApath = 1;
+            break;
+        case OPT_CONTENT:
+            contfile = opt_arg();
+            break;
+        case OPT_V_CASES:
+            if (!opt_verify(o, vpm))
+                goto opthelp;
+            vpmtouched++;
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    argv = opt_rest();
+
+    if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) {
+        BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
+        goto opthelp;
+    }
+
+    if (operation & SMIME_SIGNERS) {
+        /* Check to see if any final signer needs to be appended */
+        if (keyfile && !signerfile) {
+            BIO_puts(bio_err, "Illegal -inkey without -signer\n");
+            goto opthelp;
+        }
+        if (signerfile) {
+            if (!sksigners
+                && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
+                goto end;
+            sk_OPENSSL_STRING_push(sksigners, signerfile);
+            if (!skkeys && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
+                goto end;
+            if (!keyfile)
+                keyfile = signerfile;
+            sk_OPENSSL_STRING_push(skkeys, keyfile);
+        }
+        if (!sksigners) {
+            BIO_printf(bio_err, "No signer certificate specified\n");
+            goto opthelp;
+        }
+        signerfile = NULL;
+        keyfile = NULL;
+        need_rand = 1;
+    } else if (operation == SMIME_DECRYPT) {
+        if (!recipfile && !keyfile) {
+            BIO_printf(bio_err,
+                       "No recipient certificate or key specified\n");
+            goto opthelp;
+        }
+    } else if (operation == SMIME_ENCRYPT) {
+        if (argc == 0) {
+            BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
+            goto opthelp;
+        }
+        need_rand = 1;
+    } else if (!operation)
+        goto opthelp;
+
+    if (!app_passwd(passinarg, NULL, &passin, NULL)) {
+        BIO_printf(bio_err, "Error getting password\n");
+        goto end;
+    }
+
+    if (need_rand) {
+        app_RAND_load_file(NULL, (inrand != NULL));
+        if (inrand != NULL)
+            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
+                       app_RAND_load_files(inrand));
+    }
+
+    ret = 2;
+
+    if (!(operation & SMIME_SIGNERS))
+        flags &= ~PKCS7_DETACHED;
+
+    if (!(operation & SMIME_OP)) {
+        if (flags & PKCS7_BINARY)
+            outformat = FORMAT_BINARY;
+    }
+
+    if (!(operation & SMIME_IP)) {
+        if (flags & PKCS7_BINARY)
+            informat = FORMAT_BINARY;
+    }
+
+    if (operation == SMIME_ENCRYPT) {
+        if (!cipher) {
+#ifndef OPENSSL_NO_DES
+            cipher = EVP_des_ede3_cbc();
+#else
+            BIO_printf(bio_err, "No cipher selected\n");
+            goto end;
+#endif
+        }
+        encerts = sk_X509_new_null();
+        if (!encerts)
+            goto end;
+        while (*argv) {
+            cert = load_cert(*argv, FORMAT_PEM,
+                             "recipient certificate file");
+            if (cert == NULL)
+                goto end;
+            sk_X509_push(encerts, cert);
+            cert = NULL;
+            argv++;
+        }
+    }
+
+    if (certfile) {
+        if (!load_certs(certfile, &other, FORMAT_PEM, NULL,
+                        "certificate file")) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    if (recipfile && (operation == SMIME_DECRYPT)) {
+        if ((recip = load_cert(recipfile, FORMAT_PEM,
+                               "recipient certificate file")) == NULL) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    if (operation == SMIME_DECRYPT) {
+        if (!keyfile)
+            keyfile = recipfile;
+    } else if (operation == SMIME_SIGN) {
+        if (!keyfile)
+            keyfile = signerfile;
+    } else
+        keyfile = NULL;
+
+    if (keyfile) {
+        key = load_key(keyfile, keyform, 0, passin, e, "signing key file");
+        if (!key)
+            goto end;
+    }
+
+    in = bio_open_default(infile, 'r', informat);
+    if (in == NULL)
+        goto end;
+
+    if (operation & SMIME_IP) {
+        if (informat == FORMAT_SMIME)
+            p7 = SMIME_read_PKCS7(in, &indata);
+        else if (informat == FORMAT_PEM)
+            p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
+        else if (informat == FORMAT_ASN1)
+            p7 = d2i_PKCS7_bio(in, NULL);
+        else {
+            BIO_printf(bio_err, "Bad input format for PKCS#7 file\n");
+            goto end;
+        }
+
+        if (!p7) {
+            BIO_printf(bio_err, "Error reading S/MIME message\n");
+            goto end;
+        }
+        if (contfile) {
+            BIO_free(indata);
+            if ((indata = BIO_new_file(contfile, "rb")) == NULL) {
+                BIO_printf(bio_err, "Can't read content file %s\n", contfile);
+                goto end;
+            }
+        }
+    }
+
+    out = bio_open_default(outfile, 'w', outformat);
+    if (out == NULL)
+        goto end;
+
+    if (operation == SMIME_VERIFY) {
+        if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL)
+            goto end;
+        X509_STORE_set_verify_cb(store, smime_cb);
+        if (vpmtouched)
+            X509_STORE_set1_param(store, vpm);
+    }
+
+    ret = 3;
+
+    if (operation == SMIME_ENCRYPT) {
+        if (indef)
+            flags |= PKCS7_STREAM;
+        p7 = PKCS7_encrypt(encerts, in, cipher, flags);
+    } else if (operation & SMIME_SIGNERS) {
+        int i;
+        /*
+         * If detached data content we only enable streaming if S/MIME output
+         * format.
+         */
+        if (operation == SMIME_SIGN) {
+            if (flags & PKCS7_DETACHED) {
+                if (outformat == FORMAT_SMIME)
+                    flags |= PKCS7_STREAM;
+            } else if (indef)
+                flags |= PKCS7_STREAM;
+            flags |= PKCS7_PARTIAL;
+            p7 = PKCS7_sign(NULL, NULL, other, in, flags);
+            if (!p7)
+                goto end;
+            if (flags & PKCS7_NOCERTS) {
+                for (i = 0; i < sk_X509_num(other); i++) {
+                    X509 *x = sk_X509_value(other, i);
+                    PKCS7_add_certificate(p7, x);
+                }
+            }
+        } else
+            flags |= PKCS7_REUSE_DIGEST;
+        for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) {
+            signerfile = sk_OPENSSL_STRING_value(sksigners, i);
+            keyfile = sk_OPENSSL_STRING_value(skkeys, i);
+            signer = load_cert(signerfile, FORMAT_PEM,
+                               "signer certificate");
+            if (!signer)
+                goto end;
+            key = load_key(keyfile, keyform, 0, passin, e, "signing key file");
+            if (!key)
+                goto end;
+            if (!PKCS7_sign_add_signer(p7, signer, key, sign_md, flags))
+                goto end;
+            X509_free(signer);
+            signer = NULL;
+            EVP_PKEY_free(key);
+            key = NULL;
+        }
+        /* If not streaming or resigning finalize structure */
+        if ((operation == SMIME_SIGN) && !(flags & PKCS7_STREAM)) {
+            if (!PKCS7_final(p7, in, flags))
+                goto end;
+        }
+    }
+
+    if (!p7) {
+        BIO_printf(bio_err, "Error creating PKCS#7 structure\n");
+        goto end;
+    }
+
+    ret = 4;
+    if (operation == SMIME_DECRYPT) {
+        if (!PKCS7_decrypt(p7, key, recip, out, flags)) {
+            BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n");
+            goto end;
+        }
+    } else if (operation == SMIME_VERIFY) {
+        STACK_OF(X509) *signers;
+        if (PKCS7_verify(p7, other, store, indata, out, flags))
+            BIO_printf(bio_err, "Verification successful\n");
+        else {
+            BIO_printf(bio_err, "Verification failure\n");
+            goto end;
+        }
+        signers = PKCS7_get0_signers(p7, other, flags);
+        if (!save_certs(signerfile, signers)) {
+            BIO_printf(bio_err, "Error writing signers to %s\n", signerfile);
+            ret = 5;
+            goto end;
+        }
+        sk_X509_free(signers);
+    } else if (operation == SMIME_PK7OUT)
+        PEM_write_bio_PKCS7(out, p7);
+    else {
+        if (to)
+            BIO_printf(out, "To: %s%s", to, mime_eol);
+        if (from)
+            BIO_printf(out, "From: %s%s", from, mime_eol);
+        if (subject)
+            BIO_printf(out, "Subject: %s%s", subject, mime_eol);
+        if (outformat == FORMAT_SMIME) {
+            if (operation == SMIME_RESIGN)
+                rv = SMIME_write_PKCS7(out, p7, indata, flags);
+            else
+                rv = SMIME_write_PKCS7(out, p7, in, flags);
+        } else if (outformat == FORMAT_PEM)
+            rv = PEM_write_bio_PKCS7_stream(out, p7, in, flags);
+        else if (outformat == FORMAT_ASN1)
+            rv = i2d_PKCS7_bio_stream(out, p7, in, flags);
+        else {
+            BIO_printf(bio_err, "Bad output format for PKCS#7 file\n");
+            goto end;
+        }
+        if (rv == 0) {
+            BIO_printf(bio_err, "Error writing output\n");
+            ret = 3;
+            goto end;
+        }
+    }
+    ret = 0;
+ end:
+    if (need_rand)
+        app_RAND_write_file(NULL);
+    if (ret)
+        ERR_print_errors(bio_err);
+    sk_X509_pop_free(encerts, X509_free);
+    sk_X509_pop_free(other, X509_free);
+    X509_VERIFY_PARAM_free(vpm);
+    sk_OPENSSL_STRING_free(sksigners);
+    sk_OPENSSL_STRING_free(skkeys);
+    X509_STORE_free(store);
+    X509_free(cert);
+    X509_free(recip);
+    X509_free(signer);
+    EVP_PKEY_free(key);
+    PKCS7_free(p7);
+    release_engine(e);
+    BIO_free(in);
+    BIO_free(indata);
+    BIO_free_all(out);
+    OPENSSL_free(passin);
+    return (ret);
+}
+
+static int save_certs(char *signerfile, STACK_OF(X509) *signers)
+{
+    int i;
+    BIO *tmp;
+    if (!signerfile)
+        return 1;
+    tmp = BIO_new_file(signerfile, "w");
+    if (!tmp)
+        return 0;
+    for (i = 0; i < sk_X509_num(signers); i++)
+        PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
+    BIO_free(tmp);
+    return 1;
+}
+
+/* Minimal callback just to output policy info (if any) */
+
+static int smime_cb(int ok, X509_STORE_CTX *ctx)
+{
+    int error;
+
+    error = X509_STORE_CTX_get_error(ctx);
+
+    if ((error != X509_V_ERR_NO_EXPLICIT_POLICY)
+        && ((error != X509_V_OK) || (ok != 2)))
+        return ok;
+
+    policies_print(ctx);
+
+    return ok;
+
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/speed.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/speed.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/speed.c	(revision 331)
@@ -0,0 +1,3144 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The ECDH and ECDSA speed test software is originally written by
+ * Sumit Gupta of Sun Microsystems Laboratories.
+ *
+ */
+
+#undef SECONDS
+#define SECONDS                 3
+#define PRIME_SECONDS   10
+#define RSA_SECONDS             10
+#define DSA_SECONDS             10
+#define ECDSA_SECONDS   10
+#define ECDH_SECONDS    10
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "apps.h"
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/async.h>
+#if !defined(OPENSSL_SYS_MSDOS)
+# include OPENSSL_UNISTD
+#endif
+
+#if defined(_WIN32)
+# include <windows.h>
+#endif
+
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_DES
+# include <openssl/des.h>
+#endif
+#include <openssl/aes.h>
+#ifndef OPENSSL_NO_CAMELLIA
+# include <openssl/camellia.h>
+#endif
+#ifndef OPENSSL_NO_MD2
+# include <openssl/md2.h>
+#endif
+#ifndef OPENSSL_NO_MDC2
+# include <openssl/mdc2.h>
+#endif
+#ifndef OPENSSL_NO_MD4
+# include <openssl/md4.h>
+#endif
+#ifndef OPENSSL_NO_MD5
+# include <openssl/md5.h>
+#endif
+#include <openssl/hmac.h>
+#include <openssl/sha.h>
+#ifndef OPENSSL_NO_RMD160
+# include <openssl/ripemd.h>
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+# include <openssl/whrlpool.h>
+#endif
+#ifndef OPENSSL_NO_RC4
+# include <openssl/rc4.h>
+#endif
+#ifndef OPENSSL_NO_RC5
+# include <openssl/rc5.h>
+#endif
+#ifndef OPENSSL_NO_RC2
+# include <openssl/rc2.h>
+#endif
+#ifndef OPENSSL_NO_IDEA
+# include <openssl/idea.h>
+#endif
+#ifndef OPENSSL_NO_SEED
+# include <openssl/seed.h>
+#endif
+#ifndef OPENSSL_NO_BF
+# include <openssl/blowfish.h>
+#endif
+#ifndef OPENSSL_NO_CAST
+# include <openssl/cast.h>
+#endif
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+# include "./testrsa.h"
+#endif
+#include <openssl/x509.h>
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+# include "./testdsa.h"
+#endif
+#ifndef OPENSSL_NO_EC
+# include <openssl/ec.h>
+#endif
+#include <openssl/modes.h>
+
+#ifndef HAVE_FORK
+# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS)
+#  define HAVE_FORK 0
+# else
+#  define HAVE_FORK 1
+# endif
+#endif
+
+#if HAVE_FORK
+# undef NO_FORK
+#else
+# define NO_FORK
+#endif
+
+#undef BUFSIZE
+#define BUFSIZE (1024*16+1)
+#define MAX_MISALIGNMENT 63
+
+#define ALGOR_NUM       30
+#define SIZE_NUM        6
+#define PRIME_NUM       3
+#define RSA_NUM         7
+#define DSA_NUM         3
+
+#define EC_NUM          17
+#define MAX_ECDH_SIZE   256
+#define MISALIGN        64
+
+static volatile int run = 0;
+
+static int mr = 0;
+static int usertime = 1;
+
+typedef void *(*kdf_fn) (
+        const void *in, size_t inlen, void *out, size_t *xoutlen);
+
+typedef struct loopargs_st {
+    ASYNC_JOB *inprogress_job;
+    ASYNC_WAIT_CTX *wait_ctx;
+    unsigned char *buf;
+    unsigned char *buf2;
+    unsigned char *buf_malloc;
+    unsigned char *buf2_malloc;
+    unsigned int siglen;
+#ifndef OPENSSL_NO_RSA
+    RSA *rsa_key[RSA_NUM];
+#endif
+#ifndef OPENSSL_NO_DSA
+    DSA *dsa_key[DSA_NUM];
+#endif
+#ifndef OPENSSL_NO_EC
+    EC_KEY *ecdsa[EC_NUM];
+    EC_KEY *ecdh_a[EC_NUM];
+    EC_KEY *ecdh_b[EC_NUM];
+    unsigned char *secret_a;
+    unsigned char *secret_b;
+    size_t      outlen;
+    kdf_fn      kdf;
+#endif
+    EVP_CIPHER_CTX *ctx;
+    HMAC_CTX *hctx;
+    GCM128_CONTEXT *gcm_ctx;
+} loopargs_t;
+
+#ifndef OPENSSL_NO_MD2
+static int EVP_Digest_MD2_loop(void *args);
+#endif
+
+#ifndef OPENSSL_NO_MDC2
+static int EVP_Digest_MDC2_loop(void *args);
+#endif
+#ifndef OPENSSL_NO_MD4
+static int EVP_Digest_MD4_loop(void *args);
+#endif
+#ifndef OPENSSL_NO_MD5
+static int MD5_loop(void *args);
+static int HMAC_loop(void *args);
+#endif
+static int SHA1_loop(void *args);
+static int SHA256_loop(void *args);
+static int SHA512_loop(void *args);
+#ifndef OPENSSL_NO_WHIRLPOOL
+static int WHIRLPOOL_loop(void *args);
+#endif
+#ifndef OPENSSL_NO_RMD160
+static int EVP_Digest_RMD160_loop(void *args);
+#endif
+#ifndef OPENSSL_NO_RC4
+static int RC4_loop(void *args);
+#endif
+#ifndef OPENSSL_NO_DES
+static int DES_ncbc_encrypt_loop(void *args);
+static int DES_ede3_cbc_encrypt_loop(void *args);
+#endif
+static int AES_cbc_128_encrypt_loop(void *args);
+static int AES_cbc_192_encrypt_loop(void *args);
+static int AES_ige_128_encrypt_loop(void *args);
+static int AES_cbc_256_encrypt_loop(void *args);
+static int AES_ige_192_encrypt_loop(void *args);
+static int AES_ige_256_encrypt_loop(void *args);
+static int CRYPTO_gcm128_aad_loop(void *args);
+static int EVP_Update_loop(void *args);
+static int EVP_Digest_loop(void *args);
+#ifndef OPENSSL_NO_RSA
+static int RSA_sign_loop(void *args);
+static int RSA_verify_loop(void *args);
+#endif
+#ifndef OPENSSL_NO_DSA
+static int DSA_sign_loop(void *args);
+static int DSA_verify_loop(void *args);
+#endif
+#ifndef OPENSSL_NO_EC
+static int ECDSA_sign_loop(void *args);
+static int ECDSA_verify_loop(void *args);
+static int ECDH_compute_key_loop(void *args);
+#endif
+static int run_benchmark(int async_jobs, int (*loop_function)(void *), loopargs_t *loopargs);
+
+static double Time_F(int s);
+static void print_message(const char *s, long num, int length);
+static void pkey_print_message(const char *str, const char *str2,
+                               long num, int bits, int sec);
+static void print_result(int alg, int run_no, int count, double time_used);
+#ifndef NO_FORK
+static int do_multi(int multi);
+#endif
+
+static const char *names[ALGOR_NUM] = {
+    "md2", "mdc2", "md4", "md5", "hmac(md5)", "sha1", "rmd160", "rc4",
+    "des cbc", "des ede3", "idea cbc", "seed cbc",
+    "rc2 cbc", "rc5-32/12 cbc", "blowfish cbc", "cast cbc",
+    "aes-128 cbc", "aes-192 cbc", "aes-256 cbc",
+    "camellia-128 cbc", "camellia-192 cbc", "camellia-256 cbc",
+    "evp", "sha256", "sha512", "whirlpool",
+    "aes-128 ige", "aes-192 ige", "aes-256 ige", "ghash"
+};
+
+static double results[ALGOR_NUM][SIZE_NUM];
+
+static const int lengths[SIZE_NUM] = {
+    16, 64, 256, 1024, 8 * 1024, 16 * 1024
+};
+
+#ifndef OPENSSL_NO_RSA
+static double rsa_results[RSA_NUM][2];
+#endif
+#ifndef OPENSSL_NO_DSA
+static double dsa_results[DSA_NUM][2];
+#endif
+#ifndef OPENSSL_NO_EC
+static double ecdsa_results[EC_NUM][2];
+static double ecdh_results[EC_NUM][1];
+#endif
+
+#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC)
+static const char rnd_seed[] =
+    "string to make the random number generator think it has entropy";
+#endif
+
+#ifdef SIGALRM
+# if defined(__STDC__) || defined(sgi) || defined(_AIX)
+#  define SIGRETTYPE void
+# else
+#  define SIGRETTYPE int
+# endif
+
+static SIGRETTYPE sig_done(int sig);
+static SIGRETTYPE sig_done(int sig)
+{
+    signal(SIGALRM, sig_done);
+    run = 0;
+}
+#endif
+
+#define START   0
+#define STOP    1
+
+#if defined(_WIN32)
+
+# if !defined(SIGALRM)
+#  define SIGALRM
+# endif
+static unsigned int lapse, schlock;
+static void alarm_win32(unsigned int secs)
+{
+    lapse = secs * 1000;
+}
+
+# define alarm alarm_win32
+
+static DWORD WINAPI sleepy(VOID * arg)
+{
+    schlock = 1;
+    Sleep(lapse);
+    run = 0;
+    return 0;
+}
+
+static double Time_F(int s)
+{
+    double ret;
+    static HANDLE thr;
+
+    if (s == START) {
+        schlock = 0;
+        thr = CreateThread(NULL, 4096, sleepy, NULL, 0, NULL);
+        if (thr == NULL) {
+            DWORD err = GetLastError();
+            BIO_printf(bio_err, "unable to CreateThread (%lu)", err);
+            ExitProcess(err);
+        }
+        while (!schlock)
+            Sleep(0);           /* scheduler spinlock */
+        ret = app_tminterval(s, usertime);
+    } else {
+        ret = app_tminterval(s, usertime);
+        if (run)
+            TerminateThread(thr, 0);
+        CloseHandle(thr);
+    }
+
+    return ret;
+}
+#else
+
+static double Time_F(int s)
+{
+    double ret = app_tminterval(s, usertime);
+    if (s == STOP)
+        alarm(0);
+    return ret;
+}
+#endif
+
+static void multiblock_speed(const EVP_CIPHER *evp_cipher);
+
+static int found(const char *name, const OPT_PAIR *pairs, int *result)
+{
+    for (; pairs->name; pairs++)
+        if (strcmp(name, pairs->name) == 0) {
+            *result = pairs->retval;
+            return 1;
+        }
+    return 0;
+}
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_ELAPSED, OPT_EVP, OPT_DECRYPT, OPT_ENGINE, OPT_MULTI,
+    OPT_MR, OPT_MB, OPT_MISALIGN, OPT_ASYNCJOBS
+} OPTION_CHOICE;
+
+OPTIONS speed_options[] = {
+    {OPT_HELP_STR, 1, '-', "Usage: %s [options] ciphers...\n"},
+    {OPT_HELP_STR, 1, '-', "Valid options are:\n"},
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"evp", OPT_EVP, 's', "Use specified EVP cipher"},
+    {"decrypt", OPT_DECRYPT, '-',
+     "Time decryption instead of encryption (only EVP)"},
+    {"mr", OPT_MR, '-', "Produce machine readable output"},
+    {"mb", OPT_MB, '-',
+     "Enable (tls1.1) multi-block mode on evp_cipher requested with -evp"},
+    {"misalign", OPT_MISALIGN, 'n', "Amount to mis-align buffers"},
+    {"elapsed", OPT_ELAPSED, '-',
+     "Measure time in real time instead of CPU user time"},
+#ifndef NO_FORK
+    {"multi", OPT_MULTI, 'p', "Run benchmarks in parallel"},
+#endif
+#ifndef OPENSSL_NO_ASYNC
+    {"async_jobs", OPT_ASYNCJOBS, 'p',
+     "Enable async mode and start pnum jobs"},
+#endif
+#ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+#endif
+    {NULL},
+};
+
+#define D_MD2           0
+#define D_MDC2          1
+#define D_MD4           2
+#define D_MD5           3
+#define D_HMAC          4
+#define D_SHA1          5
+#define D_RMD160        6
+#define D_RC4           7
+#define D_CBC_DES       8
+#define D_EDE3_DES      9
+#define D_CBC_IDEA      10
+#define D_CBC_SEED      11
+#define D_CBC_RC2       12
+#define D_CBC_RC5       13
+#define D_CBC_BF        14
+#define D_CBC_CAST      15
+#define D_CBC_128_AES   16
+#define D_CBC_192_AES   17
+#define D_CBC_256_AES   18
+#define D_CBC_128_CML   19
+#define D_CBC_192_CML   20
+#define D_CBC_256_CML   21
+#define D_EVP           22
+#define D_SHA256        23
+#define D_SHA512        24
+#define D_WHIRLPOOL     25
+#define D_IGE_128_AES   26
+#define D_IGE_192_AES   27
+#define D_IGE_256_AES   28
+#define D_GHASH         29
+static OPT_PAIR doit_choices[] = {
+#ifndef OPENSSL_NO_MD2
+    {"md2", D_MD2},
+#endif
+#ifndef OPENSSL_NO_MDC2
+    {"mdc2", D_MDC2},
+#endif
+#ifndef OPENSSL_NO_MD4
+    {"md4", D_MD4},
+#endif
+#ifndef OPENSSL_NO_MD5
+    {"md5", D_MD5},
+    {"hmac", D_HMAC},
+#endif
+    {"sha1", D_SHA1},
+    {"sha256", D_SHA256},
+    {"sha512", D_SHA512},
+#ifndef OPENSSL_NO_WHIRLPOOL
+    {"whirlpool", D_WHIRLPOOL},
+#endif
+#ifndef OPENSSL_NO_RMD160
+    {"ripemd", D_RMD160},
+    {"rmd160", D_RMD160},
+    {"ripemd160", D_RMD160},
+#endif
+#ifndef OPENSSL_NO_RC4
+    {"rc4", D_RC4},
+#endif
+#ifndef OPENSSL_NO_DES
+    {"des-cbc", D_CBC_DES},
+    {"des-ede3", D_EDE3_DES},
+#endif
+    {"aes-128-cbc", D_CBC_128_AES},
+    {"aes-192-cbc", D_CBC_192_AES},
+    {"aes-256-cbc", D_CBC_256_AES},
+    {"aes-128-ige", D_IGE_128_AES},
+    {"aes-192-ige", D_IGE_192_AES},
+    {"aes-256-ige", D_IGE_256_AES},
+#ifndef OPENSSL_NO_RC2
+    {"rc2-cbc", D_CBC_RC2},
+    {"rc2", D_CBC_RC2},
+#endif
+#ifndef OPENSSL_NO_RC5
+    {"rc5-cbc", D_CBC_RC5},
+    {"rc5", D_CBC_RC5},
+#endif
+#ifndef OPENSSL_NO_IDEA
+    {"idea-cbc", D_CBC_IDEA},
+    {"idea", D_CBC_IDEA},
+#endif
+#ifndef OPENSSL_NO_SEED
+    {"seed-cbc", D_CBC_SEED},
+    {"seed", D_CBC_SEED},
+#endif
+#ifndef OPENSSL_NO_BF
+    {"bf-cbc", D_CBC_BF},
+    {"blowfish", D_CBC_BF},
+    {"bf", D_CBC_BF},
+#endif
+#ifndef OPENSSL_NO_CAST
+    {"cast-cbc", D_CBC_CAST},
+    {"cast", D_CBC_CAST},
+    {"cast5", D_CBC_CAST},
+#endif
+    {"ghash", D_GHASH},
+    {NULL}
+};
+
+#ifndef OPENSSL_NO_DSA
+# define R_DSA_512       0
+# define R_DSA_1024      1
+# define R_DSA_2048      2
+static OPT_PAIR dsa_choices[] = {
+    {"dsa512", R_DSA_512},
+    {"dsa1024", R_DSA_1024},
+    {"dsa2048", R_DSA_2048},
+    {NULL},
+};
+#endif
+
+#define R_RSA_512       0
+#define R_RSA_1024      1
+#define R_RSA_2048      2
+#define R_RSA_3072      3
+#define R_RSA_4096      4
+#define R_RSA_7680      5
+#define R_RSA_15360     6
+static OPT_PAIR rsa_choices[] = {
+    {"rsa512", R_RSA_512},
+    {"rsa1024", R_RSA_1024},
+    {"rsa2048", R_RSA_2048},
+    {"rsa3072", R_RSA_3072},
+    {"rsa4096", R_RSA_4096},
+    {"rsa7680", R_RSA_7680},
+    {"rsa15360", R_RSA_15360},
+    {NULL}
+};
+
+#define R_EC_P160    0
+#define R_EC_P192    1
+#define R_EC_P224    2
+#define R_EC_P256    3
+#define R_EC_P384    4
+#define R_EC_P521    5
+#define R_EC_K163    6
+#define R_EC_K233    7
+#define R_EC_K283    8
+#define R_EC_K409    9
+#define R_EC_K571    10
+#define R_EC_B163    11
+#define R_EC_B233    12
+#define R_EC_B283    13
+#define R_EC_B409    14
+#define R_EC_B571    15
+#define R_EC_X25519  16
+#ifndef OPENSSL_NO_EC
+static OPT_PAIR ecdsa_choices[] = {
+    {"ecdsap160", R_EC_P160},
+    {"ecdsap192", R_EC_P192},
+    {"ecdsap224", R_EC_P224},
+    {"ecdsap256", R_EC_P256},
+    {"ecdsap384", R_EC_P384},
+    {"ecdsap521", R_EC_P521},
+    {"ecdsak163", R_EC_K163},
+    {"ecdsak233", R_EC_K233},
+    {"ecdsak283", R_EC_K283},
+    {"ecdsak409", R_EC_K409},
+    {"ecdsak571", R_EC_K571},
+    {"ecdsab163", R_EC_B163},
+    {"ecdsab233", R_EC_B233},
+    {"ecdsab283", R_EC_B283},
+    {"ecdsab409", R_EC_B409},
+    {"ecdsab571", R_EC_B571},
+    {NULL}
+};
+
+static OPT_PAIR ecdh_choices[] = {
+    {"ecdhp160", R_EC_P160},
+    {"ecdhp192", R_EC_P192},
+    {"ecdhp224", R_EC_P224},
+    {"ecdhp256", R_EC_P256},
+    {"ecdhp384", R_EC_P384},
+    {"ecdhp521", R_EC_P521},
+    {"ecdhk163", R_EC_K163},
+    {"ecdhk233", R_EC_K233},
+    {"ecdhk283", R_EC_K283},
+    {"ecdhk409", R_EC_K409},
+    {"ecdhk571", R_EC_K571},
+    {"ecdhb163", R_EC_B163},
+    {"ecdhb233", R_EC_B233},
+    {"ecdhb283", R_EC_B283},
+    {"ecdhb409", R_EC_B409},
+    {"ecdhb571", R_EC_B571},
+    {"ecdhx25519", R_EC_X25519},
+    {NULL}
+};
+#endif
+
+#ifndef SIGALRM
+# define COND(d) (count < (d))
+# define COUNT(d) (d)
+#else
+# define COND(unused_cond) (run && count<0x7fffffff)
+# define COUNT(d) (count)
+#endif                         /* SIGALRM */
+
+static int testnum;
+
+/* Nb of iterations to do per algorithm and key-size */
+static long c[ALGOR_NUM][SIZE_NUM];
+
+#ifndef OPENSSL_NO_MD2
+static int EVP_Digest_MD2_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    unsigned char md2[MD2_DIGEST_LENGTH];
+    int count;
+
+    for (count = 0; COND(c[D_MD2][testnum]); count++) {
+        if (!EVP_Digest(buf, (size_t)lengths[testnum], md2, NULL, EVP_md2(),
+                NULL))
+            return -1;
+    }
+    return count;
+}
+#endif
+
+#ifndef OPENSSL_NO_MDC2
+static int EVP_Digest_MDC2_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    unsigned char mdc2[MDC2_DIGEST_LENGTH];
+    int count;
+
+    for (count = 0; COND(c[D_MDC2][testnum]); count++) {
+        if (!EVP_Digest(buf, (size_t)lengths[testnum], mdc2, NULL, EVP_mdc2(),
+                NULL))
+            return -1;
+    }
+    return count;
+}
+#endif
+
+#ifndef OPENSSL_NO_MD4
+static int EVP_Digest_MD4_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    unsigned char md4[MD4_DIGEST_LENGTH];
+    int count;
+
+    for (count = 0; COND(c[D_MD4][testnum]); count++) {
+        if (!EVP_Digest(buf, (size_t)lengths[testnum], md4, NULL, EVP_md4(),
+                NULL))
+            return -1;
+    }
+    return count;
+}
+#endif
+
+#ifndef OPENSSL_NO_MD5
+static int MD5_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    unsigned char md5[MD5_DIGEST_LENGTH];
+    int count;
+    for (count = 0; COND(c[D_MD5][testnum]); count++)
+        MD5(buf, lengths[testnum], md5);
+    return count;
+}
+
+static int HMAC_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    HMAC_CTX *hctx = tempargs->hctx;
+    unsigned char hmac[MD5_DIGEST_LENGTH];
+    int count;
+
+    for (count = 0; COND(c[D_HMAC][testnum]); count++) {
+        HMAC_Init_ex(hctx, NULL, 0, NULL, NULL);
+        HMAC_Update(hctx, buf, lengths[testnum]);
+        HMAC_Final(hctx, hmac, NULL);
+    }
+    return count;
+}
+#endif
+
+static int SHA1_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    unsigned char sha[SHA_DIGEST_LENGTH];
+    int count;
+    for (count = 0; COND(c[D_SHA1][testnum]); count++)
+        SHA1(buf, lengths[testnum], sha);
+    return count;
+}
+
+static int SHA256_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    unsigned char sha256[SHA256_DIGEST_LENGTH];
+    int count;
+    for (count = 0; COND(c[D_SHA256][testnum]); count++)
+        SHA256(buf, lengths[testnum], sha256);
+    return count;
+}
+
+static int SHA512_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    unsigned char sha512[SHA512_DIGEST_LENGTH];
+    int count;
+    for (count = 0; COND(c[D_SHA512][testnum]); count++)
+        SHA512(buf, lengths[testnum], sha512);
+    return count;
+}
+
+#ifndef OPENSSL_NO_WHIRLPOOL
+static int WHIRLPOOL_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    unsigned char whirlpool[WHIRLPOOL_DIGEST_LENGTH];
+    int count;
+    for (count = 0; COND(c[D_WHIRLPOOL][testnum]); count++)
+        WHIRLPOOL(buf, lengths[testnum], whirlpool);
+    return count;
+}
+#endif
+
+#ifndef OPENSSL_NO_RMD160
+static int EVP_Digest_RMD160_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    unsigned char rmd160[RIPEMD160_DIGEST_LENGTH];
+    int count;
+    for (count = 0; COND(c[D_RMD160][testnum]); count++) {
+        if (!EVP_Digest(buf, (size_t)lengths[testnum], &(rmd160[0]),
+                NULL, EVP_ripemd160(), NULL))
+            return -1;
+    }
+    return count;
+}
+#endif
+
+#ifndef OPENSSL_NO_RC4
+static RC4_KEY rc4_ks;
+static int RC4_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    int count;
+    for (count = 0; COND(c[D_RC4][testnum]); count++)
+        RC4(&rc4_ks, (size_t)lengths[testnum], buf, buf);
+    return count;
+}
+#endif
+
+#ifndef OPENSSL_NO_DES
+static unsigned char DES_iv[8];
+static DES_key_schedule sch;
+static DES_key_schedule sch2;
+static DES_key_schedule sch3;
+static int DES_ncbc_encrypt_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    int count;
+    for (count = 0; COND(c[D_CBC_DES][testnum]); count++)
+        DES_ncbc_encrypt(buf, buf, lengths[testnum], &sch,
+                &DES_iv, DES_ENCRYPT);
+    return count;
+}
+
+static int DES_ede3_cbc_encrypt_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    int count;
+    for (count = 0; COND(c[D_EDE3_DES][testnum]); count++)
+        DES_ede3_cbc_encrypt(buf, buf, lengths[testnum],
+                &sch, &sch2, &sch3,
+                &DES_iv, DES_ENCRYPT);
+    return count;
+}
+#endif
+
+#define MAX_BLOCK_SIZE 128
+
+static unsigned char iv[2 * MAX_BLOCK_SIZE / 8];
+static AES_KEY aes_ks1, aes_ks2, aes_ks3;
+static int AES_cbc_128_encrypt_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    int count;
+    for (count = 0; COND(c[D_CBC_128_AES][testnum]); count++)
+        AES_cbc_encrypt(buf, buf,
+                (size_t)lengths[testnum], &aes_ks1,
+                iv, AES_ENCRYPT);
+    return count;
+}
+
+static int AES_cbc_192_encrypt_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    int count;
+    for (count = 0; COND(c[D_CBC_192_AES][testnum]); count++)
+        AES_cbc_encrypt(buf, buf,
+                (size_t)lengths[testnum], &aes_ks2,
+                iv, AES_ENCRYPT);
+    return count;
+}
+
+static int AES_cbc_256_encrypt_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    int count;
+    for (count = 0; COND(c[D_CBC_256_AES][testnum]); count++)
+        AES_cbc_encrypt(buf, buf,
+                (size_t)lengths[testnum], &aes_ks3,
+                iv, AES_ENCRYPT);
+    return count;
+}
+
+static int AES_ige_128_encrypt_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    unsigned char *buf2 = tempargs->buf2;
+    int count;
+    for (count = 0; COND(c[D_IGE_128_AES][testnum]); count++)
+        AES_ige_encrypt(buf, buf2,
+                (size_t)lengths[testnum], &aes_ks1,
+                iv, AES_ENCRYPT);
+    return count;
+}
+
+static int AES_ige_192_encrypt_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    unsigned char *buf2 = tempargs->buf2;
+    int count;
+    for (count = 0; COND(c[D_IGE_192_AES][testnum]); count++)
+        AES_ige_encrypt(buf, buf2,
+                (size_t)lengths[testnum], &aes_ks2,
+                iv, AES_ENCRYPT);
+    return count;
+}
+
+static int AES_ige_256_encrypt_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    unsigned char *buf2 = tempargs->buf2;
+    int count;
+    for (count = 0; COND(c[D_IGE_256_AES][testnum]); count++)
+        AES_ige_encrypt(buf, buf2,
+                (size_t)lengths[testnum], &aes_ks3,
+                iv, AES_ENCRYPT);
+    return count;
+}
+
+static int CRYPTO_gcm128_aad_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    GCM128_CONTEXT *gcm_ctx = tempargs->gcm_ctx;
+    int count;
+    for (count = 0; COND(c[D_GHASH][testnum]); count++)
+        CRYPTO_gcm128_aad(gcm_ctx, buf, lengths[testnum]);
+    return count;
+}
+
+static long save_count = 0;
+static int decrypt = 0;
+static int EVP_Update_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    EVP_CIPHER_CTX *ctx = tempargs->ctx;
+    int outl, count;
+#ifndef SIGALRM
+    int nb_iter = save_count * 4 * lengths[0] / lengths[testnum];
+#endif
+    if (decrypt)
+        for (count = 0; COND(nb_iter); count++)
+            EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
+    else
+        for (count = 0; COND(nb_iter); count++)
+            EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
+    if (decrypt)
+        EVP_DecryptFinal_ex(ctx, buf, &outl);
+    else
+        EVP_EncryptFinal_ex(ctx, buf, &outl);
+    return count;
+}
+
+static const EVP_MD *evp_md = NULL;
+static int EVP_Digest_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    unsigned char md[EVP_MAX_MD_SIZE];
+    int count;
+#ifndef SIGALRM
+    int nb_iter = save_count * 4 * lengths[0] / lengths[testnum];
+#endif
+
+    for (count = 0; COND(nb_iter); count++) {
+        if (!EVP_Digest(buf, lengths[testnum], md, NULL, evp_md, NULL))
+            return -1;
+    }
+    return count;
+}
+
+#ifndef OPENSSL_NO_RSA
+static long rsa_c[RSA_NUM][2];  /* # RSA iteration test */
+
+static int RSA_sign_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    unsigned char *buf2 = tempargs->buf2;
+    unsigned int *rsa_num = &tempargs->siglen;
+    RSA **rsa_key = tempargs->rsa_key;
+    int ret, count;
+    for (count = 0; COND(rsa_c[testnum][0]); count++) {
+        ret = RSA_sign(NID_md5_sha1, buf, 36, buf2, rsa_num, rsa_key[testnum]);
+        if (ret == 0) {
+            BIO_printf(bio_err, "RSA sign failure\n");
+            ERR_print_errors(bio_err);
+            count = -1;
+            break;
+        }
+    }
+    return count;
+}
+
+static int RSA_verify_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    unsigned char *buf2 = tempargs->buf2;
+    unsigned int rsa_num = tempargs->siglen;
+    RSA **rsa_key = tempargs->rsa_key;
+    int ret, count;
+    for (count = 0; COND(rsa_c[testnum][1]); count++) {
+        ret = RSA_verify(NID_md5_sha1, buf, 36, buf2, rsa_num, rsa_key[testnum]);
+        if (ret <= 0) {
+            BIO_printf(bio_err, "RSA verify failure\n");
+            ERR_print_errors(bio_err);
+            count = -1;
+            break;
+        }
+    }
+    return count;
+}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+static long dsa_c[DSA_NUM][2];
+static int DSA_sign_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    unsigned char *buf2 = tempargs->buf2;
+    DSA **dsa_key = tempargs->dsa_key;
+    unsigned int *siglen = &tempargs->siglen;
+    int ret, count;
+    for (count = 0; COND(dsa_c[testnum][0]); count++) {
+        ret = DSA_sign(0, buf, 20, buf2, siglen, dsa_key[testnum]);
+        if (ret == 0) {
+            BIO_printf(bio_err, "DSA sign failure\n");
+            ERR_print_errors(bio_err);
+            count = -1;
+            break;
+        }
+    }
+    return count;
+}
+
+static int DSA_verify_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    unsigned char *buf2 = tempargs->buf2;
+    DSA **dsa_key = tempargs->dsa_key;
+    unsigned int siglen = tempargs->siglen;
+    int ret, count;
+    for (count = 0; COND(dsa_c[testnum][1]); count++) {
+        ret = DSA_verify(0, buf, 20, buf2, siglen, dsa_key[testnum]);
+        if (ret <= 0) {
+            BIO_printf(bio_err, "DSA verify failure\n");
+            ERR_print_errors(bio_err);
+            count = -1;
+            break;
+        }
+    }
+    return count;
+}
+#endif
+
+#ifndef OPENSSL_NO_EC
+static long ecdsa_c[EC_NUM][2];
+static int ECDSA_sign_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    EC_KEY **ecdsa = tempargs->ecdsa;
+    unsigned char *ecdsasig = tempargs->buf2;
+    unsigned int *ecdsasiglen = &tempargs->siglen;
+    int ret, count;
+    for (count = 0; COND(ecdsa_c[testnum][0]); count++) {
+        ret = ECDSA_sign(0, buf, 20,
+                ecdsasig, ecdsasiglen, ecdsa[testnum]);
+        if (ret == 0) {
+            BIO_printf(bio_err, "ECDSA sign failure\n");
+            ERR_print_errors(bio_err);
+            count = -1;
+            break;
+        }
+    }
+    return count;
+}
+
+static int ECDSA_verify_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    unsigned char *buf = tempargs->buf;
+    EC_KEY **ecdsa = tempargs->ecdsa;
+    unsigned char *ecdsasig = tempargs->buf2;
+    unsigned int ecdsasiglen = tempargs->siglen;
+    int ret, count;
+    for (count = 0; COND(ecdsa_c[testnum][1]); count++) {
+        ret = ECDSA_verify(0, buf, 20, ecdsasig, ecdsasiglen,
+                ecdsa[testnum]);
+        if (ret != 1) {
+            BIO_printf(bio_err, "ECDSA verify failure\n");
+            ERR_print_errors(bio_err);
+            count = -1;
+            break;
+        }
+    }
+    return count;
+}
+
+/* ******************************************************************** */
+static long ecdh_c[EC_NUM][1];
+
+static int ECDH_compute_key_loop(void *args)
+{
+    loopargs_t *tempargs = *(loopargs_t **)args;
+    EC_KEY **ecdh_a = tempargs->ecdh_a;
+    EC_KEY **ecdh_b = tempargs->ecdh_b;
+    unsigned char *secret_a = tempargs->secret_a;
+    int count;
+    size_t outlen = tempargs->outlen;
+    kdf_fn kdf = tempargs->kdf;
+
+    for (count = 0; COND(ecdh_c[testnum][0]); count++) {
+        ECDH_compute_key(secret_a, outlen,
+                EC_KEY_get0_public_key(ecdh_b[testnum]),
+                ecdh_a[testnum], kdf);
+    }
+    return count;
+}
+
+static const size_t KDF1_SHA1_len = 20;
+static void *KDF1_SHA1(const void *in, size_t inlen, void *out,
+                       size_t *outlen)
+{
+    if (*outlen < SHA_DIGEST_LENGTH)
+        return NULL;
+    *outlen = SHA_DIGEST_LENGTH;
+    return SHA1(in, inlen, out);
+}
+#endif                          /* OPENSSL_NO_EC */
+
+static int run_benchmark(int async_jobs,
+                         int (*loop_function)(void *), loopargs_t *loopargs)
+{
+    int job_op_count = 0;
+    int total_op_count = 0;
+    int num_inprogress = 0;
+    int error = 0, i = 0, ret = 0;
+    OSSL_ASYNC_FD job_fd = 0;
+    size_t num_job_fds = 0;
+
+    run = 1;
+
+    if (async_jobs == 0) {
+        return loop_function((void *)&loopargs);
+    }
+
+    for (i = 0; i < async_jobs && !error; i++) {
+        loopargs_t *looparg_item = loopargs + i;
+
+        /* Copy pointer content (looparg_t item address) into async context */
+        ret = ASYNC_start_job(&loopargs[i].inprogress_job, loopargs[i].wait_ctx,
+                              &job_op_count, loop_function,
+                              (void *)&looparg_item, sizeof(looparg_item));
+        switch (ret) {
+        case ASYNC_PAUSE:
+            ++num_inprogress;
+            break;
+        case ASYNC_FINISH:
+            if (job_op_count == -1) {
+                error = 1;
+            } else {
+                total_op_count += job_op_count;
+            }
+            break;
+        case ASYNC_NO_JOBS:
+        case ASYNC_ERR:
+            BIO_printf(bio_err, "Failure in the job\n");
+            ERR_print_errors(bio_err);
+            error = 1;
+            break;
+        }
+    }
+
+    while (num_inprogress > 0) {
+#if defined(OPENSSL_SYS_WINDOWS)
+        DWORD avail = 0;
+#elif defined(OPENSSL_SYS_UNIX)
+        int select_result = 0;
+        OSSL_ASYNC_FD max_fd = 0;
+        fd_set waitfdset;
+
+        FD_ZERO(&waitfdset);
+
+        for (i = 0; i < async_jobs && num_inprogress > 0; i++) {
+            if (loopargs[i].inprogress_job == NULL)
+                continue;
+
+            if (!ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, NULL, &num_job_fds)
+                    || num_job_fds > 1) {
+                BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
+                ERR_print_errors(bio_err);
+                error = 1;
+                break;
+            }
+            ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd, &num_job_fds);
+            FD_SET(job_fd, &waitfdset);
+            if (job_fd > max_fd)
+                max_fd = job_fd;
+        }
+
+        if (max_fd >= (OSSL_ASYNC_FD)FD_SETSIZE) {
+            BIO_printf(bio_err,
+                    "Error: max_fd (%d) must be smaller than FD_SETSIZE (%d). "
+                    "Decrease the value of async_jobs\n",
+                    max_fd, FD_SETSIZE);
+            ERR_print_errors(bio_err);
+            error = 1;
+            break;
+        }
+
+        select_result = select(max_fd + 1, &waitfdset, NULL, NULL, NULL);
+        if (select_result == -1 && errno == EINTR)
+            continue;
+
+        if (select_result == -1) {
+            BIO_printf(bio_err, "Failure in the select\n");
+            ERR_print_errors(bio_err);
+            error = 1;
+            break;
+        }
+
+        if (select_result == 0)
+            continue;
+#endif
+
+        for (i = 0; i < async_jobs; i++) {
+            if (loopargs[i].inprogress_job == NULL)
+                continue;
+
+            if (!ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, NULL, &num_job_fds)
+                    || num_job_fds > 1) {
+                BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
+                ERR_print_errors(bio_err);
+                error = 1;
+                break;
+            }
+            ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd, &num_job_fds);
+
+#if defined(OPENSSL_SYS_UNIX)
+            if (num_job_fds == 1 && !FD_ISSET(job_fd, &waitfdset))
+                continue;
+#elif defined(OPENSSL_SYS_WINDOWS)
+            if (num_job_fds == 1
+                && !PeekNamedPipe(job_fd, NULL, 0, NULL, &avail, NULL)
+                && avail > 0)
+                continue;
+#endif
+
+            ret = ASYNC_start_job(&loopargs[i].inprogress_job, 
+                    loopargs[i].wait_ctx, &job_op_count, loop_function, 
+                    (void *)(loopargs + i), sizeof(loopargs_t));
+            switch (ret) {
+            case ASYNC_PAUSE:
+                break;
+            case ASYNC_FINISH:
+                if (job_op_count == -1) {
+                    error = 1;
+                } else {
+                    total_op_count += job_op_count;
+                }
+                --num_inprogress;
+                loopargs[i].inprogress_job = NULL;
+                break;
+            case ASYNC_NO_JOBS:
+            case ASYNC_ERR:
+                --num_inprogress;
+                loopargs[i].inprogress_job = NULL;
+                BIO_printf(bio_err, "Failure in the job\n");
+                ERR_print_errors(bio_err);
+                error = 1;
+                break;
+            }
+        }
+    }
+
+    return error ? -1 : total_op_count;
+}
+
+int speed_main(int argc, char **argv)
+{
+    ENGINE *e = NULL;
+    loopargs_t *loopargs = NULL;
+    int async_init = 0;
+    int loopargs_len = 0;
+    char *prog;
+    const char *engine_id = NULL;
+    const EVP_CIPHER *evp_cipher = NULL;
+    double d = 0.0;
+    OPTION_CHOICE o;
+    int multiblock = 0, pr_header = 0;
+    int doit[ALGOR_NUM] = { 0 };
+    int ret = 1, i, k, misalign = 0;
+    long count = 0;
+#ifndef NO_FORK
+    int multi = 0;
+#endif
+    int async_jobs = 0;
+#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) \
+    || !defined(OPENSSL_NO_EC)
+    long rsa_count = 1;
+#endif
+
+    /* What follows are the buffers and key material. */
+#ifndef OPENSSL_NO_RC5
+    RC5_32_KEY rc5_ks;
+#endif
+#ifndef OPENSSL_NO_RC2
+    RC2_KEY rc2_ks;
+#endif
+#ifndef OPENSSL_NO_IDEA
+    IDEA_KEY_SCHEDULE idea_ks;
+#endif
+#ifndef OPENSSL_NO_SEED
+    SEED_KEY_SCHEDULE seed_ks;
+#endif
+#ifndef OPENSSL_NO_BF
+    BF_KEY bf_ks;
+#endif
+#ifndef OPENSSL_NO_CAST
+    CAST_KEY cast_ks;
+#endif
+    static const unsigned char key16[16] = {
+        0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
+        0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12
+    };
+    static const unsigned char key24[24] = {
+        0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
+        0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
+        0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34
+    };
+    static const unsigned char key32[32] = {
+        0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
+        0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
+        0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
+        0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56
+    };
+#ifndef OPENSSL_NO_CAMELLIA
+    static const unsigned char ckey24[24] = {
+        0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
+        0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
+        0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34
+    };
+    static const unsigned char ckey32[32] = {
+        0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
+        0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12,
+        0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34,
+        0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56
+    };
+    CAMELLIA_KEY camellia_ks1, camellia_ks2, camellia_ks3;
+#endif
+#ifndef OPENSSL_NO_DES
+    static DES_cblock key = {
+        0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0
+    };
+    static DES_cblock key2 = {
+        0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12
+    };
+    static DES_cblock key3 = {
+        0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34
+    };
+#endif
+#ifndef OPENSSL_NO_RSA
+    static const unsigned int rsa_bits[RSA_NUM] = {
+        512, 1024, 2048, 3072, 4096, 7680, 15360
+    };
+    static const unsigned char *rsa_data[RSA_NUM] = {
+        test512, test1024, test2048, test3072, test4096, test7680, test15360
+    };
+    static const int rsa_data_length[RSA_NUM] = {
+        sizeof(test512), sizeof(test1024),
+        sizeof(test2048), sizeof(test3072),
+        sizeof(test4096), sizeof(test7680),
+        sizeof(test15360)
+    };
+    int rsa_doit[RSA_NUM] = { 0 };
+#endif
+#ifndef OPENSSL_NO_DSA
+    static const unsigned int dsa_bits[DSA_NUM] = { 512, 1024, 2048 };
+    int dsa_doit[DSA_NUM] = { 0 };
+#endif
+#ifndef OPENSSL_NO_EC
+    /*
+     * We only test over the following curves as they are representative, To
+     * add tests over more curves, simply add the curve NID and curve name to
+     * the following arrays and increase the EC_NUM value accordingly.
+     */
+    static const unsigned int test_curves[EC_NUM] = {
+        /* Prime Curves */
+        NID_secp160r1, NID_X9_62_prime192v1, NID_secp224r1,
+        NID_X9_62_prime256v1, NID_secp384r1, NID_secp521r1,
+        /* Binary Curves */
+        NID_sect163k1, NID_sect233k1, NID_sect283k1,
+        NID_sect409k1, NID_sect571k1, NID_sect163r2,
+        NID_sect233r1, NID_sect283r1, NID_sect409r1,
+        NID_sect571r1,
+        /* Other */
+        NID_X25519
+    };
+    static const char *test_curves_names[EC_NUM] = {
+        /* Prime Curves */
+        "secp160r1", "nistp192", "nistp224",
+        "nistp256", "nistp384", "nistp521",
+        /* Binary Curves */
+        "nistk163", "nistk233", "nistk283",
+        "nistk409", "nistk571", "nistb163",
+        "nistb233", "nistb283", "nistb409",
+        "nistb571",
+        /* Other */
+        "X25519"
+    };
+    static const int test_curves_bits[EC_NUM] = {
+        160, 192, 224,
+        256, 384, 521,
+        163, 233, 283,
+        409, 571, 163,
+        233, 283, 409,
+        571, 253 /* X25519 */
+    };
+
+    int ecdsa_doit[EC_NUM] = { 0 };
+    int ecdh_doit[EC_NUM] = { 0 };
+#endif                          /* ndef OPENSSL_NO_EC */
+
+    prog = opt_init(argc, argv, speed_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opterr:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(speed_options);
+            ret = 0;
+            goto end;
+        case OPT_ELAPSED:
+            usertime = 0;
+            break;
+        case OPT_EVP:
+            evp_cipher = EVP_get_cipherbyname(opt_arg());
+            if (evp_cipher == NULL)
+                evp_md = EVP_get_digestbyname(opt_arg());
+            if (evp_cipher == NULL && evp_md == NULL) {
+                BIO_printf(bio_err,
+                           "%s: %s is an unknown cipher or digest\n",
+                           prog, opt_arg());
+                goto end;
+            }
+            doit[D_EVP] = 1;
+            break;
+        case OPT_DECRYPT:
+            decrypt = 1;
+            break;
+        case OPT_ENGINE:
+            /*
+             * In a forked execution, an engine might need to be
+             * initialised by each child process, not by the parent.
+             * So store the name here and run setup_engine() later on.
+             */
+            engine_id = opt_arg();
+            break;
+        case OPT_MULTI:
+#ifndef NO_FORK
+            multi = atoi(opt_arg());
+#endif
+            break;
+        case OPT_ASYNCJOBS:
+#ifndef OPENSSL_NO_ASYNC
+            async_jobs = atoi(opt_arg());
+            if (!ASYNC_is_capable()) {
+                BIO_printf(bio_err,
+                           "%s: async_jobs specified but async not supported\n",
+                           prog);
+                goto opterr;
+            }
+#endif
+            break;
+        case OPT_MISALIGN:
+            if (!opt_int(opt_arg(), &misalign))
+                goto end;
+            if (misalign > MISALIGN) {
+                BIO_printf(bio_err,
+                           "%s: Maximum offset is %d\n", prog, MISALIGN);
+                goto opterr;
+            }
+            break;
+        case OPT_MR:
+            mr = 1;
+            break;
+        case OPT_MB:
+            multiblock = 1;
+#ifdef OPENSSL_NO_MULTIBLOCK
+            BIO_printf(bio_err,
+                       "%s: -mb specified but multi-block support is disabled\n",
+                       prog);
+            goto end;
+#endif
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    argv = opt_rest();
+
+    /* Remaining arguments are algorithms. */
+    for ( ; *argv; argv++) {
+        if (found(*argv, doit_choices, &i)) {
+            doit[i] = 1;
+            continue;
+        }
+#ifndef OPENSSL_NO_DES
+        if (strcmp(*argv, "des") == 0) {
+            doit[D_CBC_DES] = doit[D_EDE3_DES] = 1;
+            continue;
+        }
+#endif
+        if (strcmp(*argv, "sha") == 0) {
+            doit[D_SHA1] = doit[D_SHA256] = doit[D_SHA512] = 1;
+            continue;
+        }
+#ifndef OPENSSL_NO_RSA
+# ifndef RSA_NULL
+        if (strcmp(*argv, "openssl") == 0) {
+            RSA_set_default_method(RSA_PKCS1_OpenSSL());
+            continue;
+        }
+# endif
+        if (strcmp(*argv, "rsa") == 0) {
+            rsa_doit[R_RSA_512] = rsa_doit[R_RSA_1024] =
+                rsa_doit[R_RSA_2048] = rsa_doit[R_RSA_3072] =
+                rsa_doit[R_RSA_4096] = rsa_doit[R_RSA_7680] =
+                rsa_doit[R_RSA_15360] = 1;
+            continue;
+        }
+        if (found(*argv, rsa_choices, &i)) {
+            rsa_doit[i] = 1;
+            continue;
+        }
+#endif
+#ifndef OPENSSL_NO_DSA
+        if (strcmp(*argv, "dsa") == 0) {
+            dsa_doit[R_DSA_512] = dsa_doit[R_DSA_1024] =
+                dsa_doit[R_DSA_2048] = 1;
+            continue;
+        }
+        if (found(*argv, dsa_choices, &i)) {
+            dsa_doit[i] = 2;
+            continue;
+        }
+#endif
+        if (strcmp(*argv, "aes") == 0) {
+            doit[D_CBC_128_AES] = doit[D_CBC_192_AES] =
+                doit[D_CBC_256_AES] = 1;
+            continue;
+        }
+#ifndef OPENSSL_NO_CAMELLIA
+        if (strcmp(*argv, "camellia") == 0) {
+            doit[D_CBC_128_CML] = doit[D_CBC_192_CML] =
+                doit[D_CBC_256_CML] = 1;
+            continue;
+        }
+#endif
+#ifndef OPENSSL_NO_EC
+        if (strcmp(*argv, "ecdsa") == 0) {
+            for (i = 0; i < EC_NUM; i++)
+                ecdsa_doit[i] = 1;
+            continue;
+        }
+        if (found(*argv, ecdsa_choices, &i)) {
+            ecdsa_doit[i] = 2;
+            continue;
+        }
+        if (strcmp(*argv, "ecdh") == 0) {
+            for (i = 0; i < EC_NUM; i++)
+                ecdh_doit[i] = 1;
+            continue;
+        }
+        if (found(*argv, ecdh_choices, &i)) {
+            ecdh_doit[i] = 2;
+            continue;
+        }
+#endif
+        BIO_printf(bio_err, "%s: Unknown algorithm %s\n", prog, *argv);
+        goto end;
+    }
+
+    /* Initialize the job pool if async mode is enabled */
+    if (async_jobs > 0) {
+        async_init = ASYNC_init_thread(async_jobs, async_jobs);
+        if (!async_init) {
+            BIO_printf(bio_err, "Error creating the ASYNC job pool\n");
+            goto end;
+        }
+    }
+
+    loopargs_len = (async_jobs == 0 ? 1 : async_jobs);
+    loopargs = app_malloc(loopargs_len * sizeof(loopargs_t), "array of loopargs");
+    memset(loopargs, 0, loopargs_len * sizeof(loopargs_t));
+
+    for (i = 0; i < loopargs_len; i++) {
+        if (async_jobs > 0) {
+            loopargs[i].wait_ctx = ASYNC_WAIT_CTX_new();
+            if (loopargs[i].wait_ctx == NULL) {
+                BIO_printf(bio_err, "Error creating the ASYNC_WAIT_CTX\n");
+                goto end;
+            }
+        }
+
+        loopargs[i].buf_malloc = app_malloc((int)BUFSIZE + MAX_MISALIGNMENT + 1, "input buffer");
+        loopargs[i].buf2_malloc = app_malloc((int)BUFSIZE + MAX_MISALIGNMENT + 1, "input buffer");
+        /* Align the start of buffers on a 64 byte boundary */
+        loopargs[i].buf = loopargs[i].buf_malloc + misalign;
+        loopargs[i].buf2 = loopargs[i].buf2_malloc + misalign;
+#ifndef OPENSSL_NO_EC
+        loopargs[i].secret_a = app_malloc(MAX_ECDH_SIZE, "ECDH secret a");
+        loopargs[i].secret_b = app_malloc(MAX_ECDH_SIZE, "ECDH secret b");
+#endif
+    }
+
+#ifndef NO_FORK
+    if (multi && do_multi(multi))
+        goto show_res;
+#endif
+
+    /* Initialize the engine after the fork */
+    e = setup_engine(engine_id, 0);
+
+    /* No parameters; turn on everything. */
+    if ((argc == 0) && !doit[D_EVP]) {
+        for (i = 0; i < ALGOR_NUM; i++)
+            if (i != D_EVP)
+                doit[i] = 1;
+#ifndef OPENSSL_NO_RSA
+        for (i = 0; i < RSA_NUM; i++)
+            rsa_doit[i] = 1;
+#endif
+#ifndef OPENSSL_NO_DSA
+        for (i = 0; i < DSA_NUM; i++)
+            dsa_doit[i] = 1;
+#endif
+#ifndef OPENSSL_NO_EC
+        for (i = 0; i < EC_NUM; i++)
+            ecdsa_doit[i] = 1;
+        for (i = 0; i < EC_NUM; i++)
+            ecdh_doit[i] = 1;
+#endif
+    }
+    for (i = 0; i < ALGOR_NUM; i++)
+        if (doit[i])
+            pr_header++;
+
+    if (usertime == 0 && !mr)
+        BIO_printf(bio_err,
+                   "You have chosen to measure elapsed time "
+                   "instead of user CPU time.\n");
+
+#ifndef OPENSSL_NO_RSA
+    for (i = 0; i < loopargs_len; i++) {
+        for (k = 0; k < RSA_NUM; k++) {
+            const unsigned char *p;
+
+            p = rsa_data[k];
+            loopargs[i].rsa_key[k] = d2i_RSAPrivateKey(NULL, &p, rsa_data_length[k]);
+            if (loopargs[i].rsa_key[k] == NULL) {
+                BIO_printf(bio_err, "internal error loading RSA key number %d\n",
+                        k);
+                goto end;
+            }
+        }
+    }
+#endif
+#ifndef OPENSSL_NO_DSA
+    for (i = 0; i < loopargs_len; i++) {
+        loopargs[i].dsa_key[0] = get_dsa512();
+        loopargs[i].dsa_key[1] = get_dsa1024();
+        loopargs[i].dsa_key[2] = get_dsa2048();
+    }
+#endif
+#ifndef OPENSSL_NO_DES
+    DES_set_key_unchecked(&key, &sch);
+    DES_set_key_unchecked(&key2, &sch2);
+    DES_set_key_unchecked(&key3, &sch3);
+#endif
+    AES_set_encrypt_key(key16, 128, &aes_ks1);
+    AES_set_encrypt_key(key24, 192, &aes_ks2);
+    AES_set_encrypt_key(key32, 256, &aes_ks3);
+#ifndef OPENSSL_NO_CAMELLIA
+    Camellia_set_key(key16, 128, &camellia_ks1);
+    Camellia_set_key(ckey24, 192, &camellia_ks2);
+    Camellia_set_key(ckey32, 256, &camellia_ks3);
+#endif
+#ifndef OPENSSL_NO_IDEA
+    IDEA_set_encrypt_key(key16, &idea_ks);
+#endif
+#ifndef OPENSSL_NO_SEED
+    SEED_set_key(key16, &seed_ks);
+#endif
+#ifndef OPENSSL_NO_RC4
+    RC4_set_key(&rc4_ks, 16, key16);
+#endif
+#ifndef OPENSSL_NO_RC2
+    RC2_set_key(&rc2_ks, 16, key16, 128);
+#endif
+#ifndef OPENSSL_NO_RC5
+    RC5_32_set_key(&rc5_ks, 16, key16, 12);
+#endif
+#ifndef OPENSSL_NO_BF
+    BF_set_key(&bf_ks, 16, key16);
+#endif
+#ifndef OPENSSL_NO_CAST
+    CAST_set_key(&cast_ks, 16, key16);
+#endif
+#ifndef SIGALRM
+# ifndef OPENSSL_NO_DES
+    BIO_printf(bio_err, "First we calculate the approximate speed ...\n");
+    count = 10;
+    do {
+        long it;
+        count *= 2;
+        Time_F(START);
+        for (it = count; it; it--)
+            DES_ecb_encrypt((DES_cblock *)loopargs[0].buf,
+                            (DES_cblock *)loopargs[0].buf, &sch, DES_ENCRYPT);
+        d = Time_F(STOP);
+    } while (d < 3);
+    save_count = count;
+    c[D_MD2][0] = count / 10;
+    c[D_MDC2][0] = count / 10;
+    c[D_MD4][0] = count;
+    c[D_MD5][0] = count;
+    c[D_HMAC][0] = count;
+    c[D_SHA1][0] = count;
+    c[D_RMD160][0] = count;
+    c[D_RC4][0] = count * 5;
+    c[D_CBC_DES][0] = count;
+    c[D_EDE3_DES][0] = count / 3;
+    c[D_CBC_IDEA][0] = count;
+    c[D_CBC_SEED][0] = count;
+    c[D_CBC_RC2][0] = count;
+    c[D_CBC_RC5][0] = count;
+    c[D_CBC_BF][0] = count;
+    c[D_CBC_CAST][0] = count;
+    c[D_CBC_128_AES][0] = count;
+    c[D_CBC_192_AES][0] = count;
+    c[D_CBC_256_AES][0] = count;
+    c[D_CBC_128_CML][0] = count;
+    c[D_CBC_192_CML][0] = count;
+    c[D_CBC_256_CML][0] = count;
+    c[D_SHA256][0] = count;
+    c[D_SHA512][0] = count;
+    c[D_WHIRLPOOL][0] = count;
+    c[D_IGE_128_AES][0] = count;
+    c[D_IGE_192_AES][0] = count;
+    c[D_IGE_256_AES][0] = count;
+    c[D_GHASH][0] = count;
+
+    for (i = 1; i < SIZE_NUM; i++) {
+        long l0, l1;
+
+        l0 = (long)lengths[0];
+        l1 = (long)lengths[i];
+
+        c[D_MD2][i] = c[D_MD2][0] * 4 * l0 / l1;
+        c[D_MDC2][i] = c[D_MDC2][0] * 4 * l0 / l1;
+        c[D_MD4][i] = c[D_MD4][0] * 4 * l0 / l1;
+        c[D_MD5][i] = c[D_MD5][0] * 4 * l0 / l1;
+        c[D_HMAC][i] = c[D_HMAC][0] * 4 * l0 / l1;
+        c[D_SHA1][i] = c[D_SHA1][0] * 4 * l0 / l1;
+        c[D_RMD160][i] = c[D_RMD160][0] * 4 * l0 / l1;
+        c[D_SHA256][i] = c[D_SHA256][0] * 4 * l0 / l1;
+        c[D_SHA512][i] = c[D_SHA512][0] * 4 * l0 / l1;
+        c[D_WHIRLPOOL][i] = c[D_WHIRLPOOL][0] * 4 * l0 / l1;
+        c[D_GHASH][i] = c[D_GHASH][0] * 4 * l0 / l1;
+
+        l0 = (long)lengths[i - 1];
+
+        c[D_RC4][i] = c[D_RC4][i - 1] * l0 / l1;
+        c[D_CBC_DES][i] = c[D_CBC_DES][i - 1] * l0 / l1;
+        c[D_EDE3_DES][i] = c[D_EDE3_DES][i - 1] * l0 / l1;
+        c[D_CBC_IDEA][i] = c[D_CBC_IDEA][i - 1] * l0 / l1;
+        c[D_CBC_SEED][i] = c[D_CBC_SEED][i - 1] * l0 / l1;
+        c[D_CBC_RC2][i] = c[D_CBC_RC2][i - 1] * l0 / l1;
+        c[D_CBC_RC5][i] = c[D_CBC_RC5][i - 1] * l0 / l1;
+        c[D_CBC_BF][i] = c[D_CBC_BF][i - 1] * l0 / l1;
+        c[D_CBC_CAST][i] = c[D_CBC_CAST][i - 1] * l0 / l1;
+        c[D_CBC_128_AES][i] = c[D_CBC_128_AES][i - 1] * l0 / l1;
+        c[D_CBC_192_AES][i] = c[D_CBC_192_AES][i - 1] * l0 / l1;
+        c[D_CBC_256_AES][i] = c[D_CBC_256_AES][i - 1] * l0 / l1;
+        c[D_CBC_128_CML][i] = c[D_CBC_128_CML][i - 1] * l0 / l1;
+        c[D_CBC_192_CML][i] = c[D_CBC_192_CML][i - 1] * l0 / l1;
+        c[D_CBC_256_CML][i] = c[D_CBC_256_CML][i - 1] * l0 / l1;
+        c[D_IGE_128_AES][i] = c[D_IGE_128_AES][i - 1] * l0 / l1;
+        c[D_IGE_192_AES][i] = c[D_IGE_192_AES][i - 1] * l0 / l1;
+        c[D_IGE_256_AES][i] = c[D_IGE_256_AES][i - 1] * l0 / l1;
+    }
+
+#  ifndef OPENSSL_NO_RSA
+    rsa_c[R_RSA_512][0] = count / 2000;
+    rsa_c[R_RSA_512][1] = count / 400;
+    for (i = 1; i < RSA_NUM; i++) {
+        rsa_c[i][0] = rsa_c[i - 1][0] / 8;
+        rsa_c[i][1] = rsa_c[i - 1][1] / 4;
+        if (rsa_doit[i] <= 1 && rsa_c[i][0] == 0)
+            rsa_doit[i] = 0;
+        else {
+            if (rsa_c[i][0] == 0) {
+                rsa_c[i][0] = 1;            /* Set minimum iteration Nb to 1. */
+                rsa_c[i][1] = 20;
+            }
+        }
+    }
+#  endif
+
+#  ifndef OPENSSL_NO_DSA
+    dsa_c[R_DSA_512][0] = count / 1000;
+    dsa_c[R_DSA_512][1] = count / 1000 / 2;
+    for (i = 1; i < DSA_NUM; i++) {
+        dsa_c[i][0] = dsa_c[i - 1][0] / 4;
+        dsa_c[i][1] = dsa_c[i - 1][1] / 4;
+        if (dsa_doit[i] <= 1 && dsa_c[i][0] == 0)
+            dsa_doit[i] = 0;
+        else {
+            if (dsa_c[i][0] == 0) {
+                dsa_c[i][0] = 1;            /* Set minimum iteration Nb to 1. */
+                dsa_c[i][1] = 1;
+            }
+        }
+    }
+#  endif
+
+#  ifndef OPENSSL_NO_EC
+    ecdsa_c[R_EC_P160][0] = count / 1000;
+    ecdsa_c[R_EC_P160][1] = count / 1000 / 2;
+    for (i = R_EC_P192; i <= R_EC_P521; i++) {
+        ecdsa_c[i][0] = ecdsa_c[i - 1][0] / 2;
+        ecdsa_c[i][1] = ecdsa_c[i - 1][1] / 2;
+        if (ecdsa_doit[i] <= 1 && ecdsa_c[i][0] == 0)
+            ecdsa_doit[i] = 0;
+        else {
+            if (ecdsa_c[i][0] == 0) {
+                ecdsa_c[i][0] = 1;
+                ecdsa_c[i][1] = 1;
+            }
+        }
+    }
+    ecdsa_c[R_EC_K163][0] = count / 1000;
+    ecdsa_c[R_EC_K163][1] = count / 1000 / 2;
+    for (i = R_EC_K233; i <= R_EC_K571; i++) {
+        ecdsa_c[i][0] = ecdsa_c[i - 1][0] / 2;
+        ecdsa_c[i][1] = ecdsa_c[i - 1][1] / 2;
+        if (ecdsa_doit[i] <= 1 && ecdsa_c[i][0] == 0)
+            ecdsa_doit[i] = 0;
+        else {
+            if (ecdsa_c[i][0] == 0) {
+                ecdsa_c[i][0] = 1;
+                ecdsa_c[i][1] = 1;
+            }
+        }
+    }
+    ecdsa_c[R_EC_B163][0] = count / 1000;
+    ecdsa_c[R_EC_B163][1] = count / 1000 / 2;
+    for (i = R_EC_B233; i <= R_EC_B571; i++) {
+        ecdsa_c[i][0] = ecdsa_c[i - 1][0] / 2;
+        ecdsa_c[i][1] = ecdsa_c[i - 1][1] / 2;
+        if (ecdsa_doit[i] <= 1 && ecdsa_c[i][0] == 0)
+            ecdsa_doit[i] = 0;
+        else {
+            if (ecdsa_c[i][0] == 0) {
+                ecdsa_c[i][0] = 1;
+                ecdsa_c[i][1] = 1;
+            }
+        }
+    }
+
+    ecdh_c[R_EC_P160][0] = count / 1000;
+    for (i = R_EC_P192; i <= R_EC_P521; i++) {
+        ecdh_c[i][0] = ecdh_c[i - 1][0] / 2;
+        if (ecdh_doit[i] <= 1 && ecdh_c[i][0] == 0)
+            ecdh_doit[i] = 0;
+        else {
+            if (ecdh_c[i][0] == 0) {
+                ecdh_c[i][0] = 1;
+            }
+        }
+    }
+    ecdh_c[R_EC_K163][0] = count / 1000;
+    for (i = R_EC_K233; i <= R_EC_K571; i++) {
+        ecdh_c[i][0] = ecdh_c[i - 1][0] / 2;
+        if (ecdh_doit[i] <= 1 && ecdh_c[i][0] == 0)
+            ecdh_doit[i] = 0;
+        else {
+            if (ecdh_c[i][0] == 0) {
+                ecdh_c[i][0] = 1;
+            }
+        }
+    }
+    ecdh_c[R_EC_B163][0] = count / 1000;
+    for (i = R_EC_B233; i <= R_EC_B571; i++) {
+        ecdh_c[i][0] = ecdh_c[i - 1][0] / 2;
+        if (ecdh_doit[i] <= 1 && ecdh_c[i][0] == 0)
+            ecdh_doit[i] = 0;
+        else {
+            if (ecdh_c[i][0] == 0) {
+                ecdh_c[i][0] = 1;
+            }
+        }
+    }
+#  endif
+
+# else
+/* not worth fixing */
+#  error "You cannot disable DES on systems without SIGALRM."
+# endif                        /* OPENSSL_NO_DES */
+#else
+# ifndef _WIN32
+    signal(SIGALRM, sig_done);
+# endif
+#endif                         /* SIGALRM */
+
+#ifndef OPENSSL_NO_MD2
+    if (doit[D_MD2]) {
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            print_message(names[D_MD2], c[D_MD2][testnum], lengths[testnum]);
+            Time_F(START);
+            count = run_benchmark(async_jobs, EVP_Digest_MD2_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_MD2, testnum, count, d);
+        }
+    }
+#endif
+#ifndef OPENSSL_NO_MDC2
+    if (doit[D_MDC2]) {
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            print_message(names[D_MDC2], c[D_MDC2][testnum], lengths[testnum]);
+            Time_F(START);
+            count = run_benchmark(async_jobs, EVP_Digest_MDC2_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_MDC2, testnum, count, d);
+        }
+    }
+#endif
+
+#ifndef OPENSSL_NO_MD4
+    if (doit[D_MD4]) {
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            print_message(names[D_MD4], c[D_MD4][testnum], lengths[testnum]);
+            Time_F(START);
+            count = run_benchmark(async_jobs, EVP_Digest_MD4_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_MD4, testnum, count, d);
+        }
+    }
+#endif
+
+#ifndef OPENSSL_NO_MD5
+    if (doit[D_MD5]) {
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            print_message(names[D_MD5], c[D_MD5][testnum], lengths[testnum]);
+            Time_F(START);
+            count = run_benchmark(async_jobs, MD5_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_MD5, testnum, count, d);
+        }
+    }
+
+    if (doit[D_HMAC]) {
+        static const char hmac_key[] = "This is a key...";
+        int len = strlen(hmac_key);
+
+        for (i = 0; i < loopargs_len; i++) {
+            loopargs[i].hctx = HMAC_CTX_new();
+            if (loopargs[i].hctx == NULL) {
+                BIO_printf(bio_err, "HMAC malloc failure, exiting...");
+                exit(1);
+            }
+
+            HMAC_Init_ex(loopargs[i].hctx, hmac_key, len, EVP_md5(), NULL);
+        }
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            print_message(names[D_HMAC], c[D_HMAC][testnum], lengths[testnum]);
+            Time_F(START);
+            count = run_benchmark(async_jobs, HMAC_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_HMAC, testnum, count, d);
+        }
+        for (i = 0; i < loopargs_len; i++) {
+            HMAC_CTX_free(loopargs[i].hctx);
+        }
+    }
+#endif
+    if (doit[D_SHA1]) {
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            print_message(names[D_SHA1], c[D_SHA1][testnum], lengths[testnum]);
+            Time_F(START);
+            count = run_benchmark(async_jobs, SHA1_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_SHA1, testnum, count, d);
+        }
+    }
+    if (doit[D_SHA256]) {
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            print_message(names[D_SHA256], c[D_SHA256][testnum], lengths[testnum]);
+            Time_F(START);
+            count = run_benchmark(async_jobs, SHA256_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_SHA256, testnum, count, d);
+        }
+    }
+    if (doit[D_SHA512]) {
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            print_message(names[D_SHA512], c[D_SHA512][testnum], lengths[testnum]);
+            Time_F(START);
+            count = run_benchmark(async_jobs, SHA512_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_SHA512, testnum, count, d);
+        }
+    }
+
+#ifndef OPENSSL_NO_WHIRLPOOL
+    if (doit[D_WHIRLPOOL]) {
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            print_message(names[D_WHIRLPOOL], c[D_WHIRLPOOL][testnum], lengths[testnum]);
+            Time_F(START);
+            count = run_benchmark(async_jobs, WHIRLPOOL_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_WHIRLPOOL, testnum, count, d);
+        }
+    }
+#endif
+
+#ifndef OPENSSL_NO_RMD160
+    if (doit[D_RMD160]) {
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            print_message(names[D_RMD160], c[D_RMD160][testnum], lengths[testnum]);
+            Time_F(START);
+            count = run_benchmark(async_jobs, EVP_Digest_RMD160_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_RMD160, testnum, count, d);
+        }
+    }
+#endif
+#ifndef OPENSSL_NO_RC4
+    if (doit[D_RC4]) {
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            print_message(names[D_RC4], c[D_RC4][testnum], lengths[testnum]);
+            Time_F(START);
+            count = run_benchmark(async_jobs, RC4_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_RC4, testnum, count, d);
+        }
+    }
+#endif
+#ifndef OPENSSL_NO_DES
+    if (doit[D_CBC_DES]) {
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            print_message(names[D_CBC_DES], c[D_CBC_DES][testnum], lengths[testnum]);
+            Time_F(START);
+            count = run_benchmark(async_jobs, DES_ncbc_encrypt_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_CBC_DES, testnum, count, d);
+        }
+    }
+
+    if (doit[D_EDE3_DES]) {
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            print_message(names[D_EDE3_DES], c[D_EDE3_DES][testnum], lengths[testnum]);
+            Time_F(START);
+            count = run_benchmark(async_jobs, DES_ede3_cbc_encrypt_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_EDE3_DES, testnum, count, d);
+        }
+    }
+#endif
+
+    if (doit[D_CBC_128_AES]) {
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            print_message(names[D_CBC_128_AES], c[D_CBC_128_AES][testnum],
+                          lengths[testnum]);
+            Time_F(START);
+            count = run_benchmark(async_jobs, AES_cbc_128_encrypt_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_CBC_128_AES, testnum, count, d);
+        }
+    }
+    if (doit[D_CBC_192_AES]) {
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            print_message(names[D_CBC_192_AES], c[D_CBC_192_AES][testnum],
+                          lengths[testnum]);
+            Time_F(START);
+            count = run_benchmark(async_jobs, AES_cbc_192_encrypt_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_CBC_192_AES, testnum, count, d);
+        }
+    }
+    if (doit[D_CBC_256_AES]) {
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            print_message(names[D_CBC_256_AES], c[D_CBC_256_AES][testnum],
+                          lengths[testnum]);
+            Time_F(START);
+            count = run_benchmark(async_jobs, AES_cbc_256_encrypt_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_CBC_256_AES, testnum, count, d);
+        }
+    }
+
+    if (doit[D_IGE_128_AES]) {
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            print_message(names[D_IGE_128_AES], c[D_IGE_128_AES][testnum],
+                          lengths[testnum]);
+            Time_F(START);
+            count = run_benchmark(async_jobs, AES_ige_128_encrypt_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_IGE_128_AES, testnum, count, d);
+        }
+    }
+    if (doit[D_IGE_192_AES]) {
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            print_message(names[D_IGE_192_AES], c[D_IGE_192_AES][testnum],
+                          lengths[testnum]);
+            Time_F(START);
+            count = run_benchmark(async_jobs, AES_ige_192_encrypt_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_IGE_192_AES, testnum, count, d);
+        }
+    }
+    if (doit[D_IGE_256_AES]) {
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            print_message(names[D_IGE_256_AES], c[D_IGE_256_AES][testnum],
+                          lengths[testnum]);
+            Time_F(START);
+            count = run_benchmark(async_jobs, AES_ige_256_encrypt_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_IGE_256_AES, testnum, count, d);
+        }
+    }
+    if (doit[D_GHASH]) {
+        for (i = 0; i < loopargs_len; i++) {
+            loopargs[i].gcm_ctx = CRYPTO_gcm128_new(&aes_ks1, (block128_f) AES_encrypt);
+            CRYPTO_gcm128_setiv(loopargs[i].gcm_ctx, (unsigned char *)"0123456789ab", 12);
+        }
+
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            print_message(names[D_GHASH], c[D_GHASH][testnum], lengths[testnum]);
+            Time_F(START);
+            count = run_benchmark(async_jobs, CRYPTO_gcm128_aad_loop, loopargs);
+            d = Time_F(STOP);
+            print_result(D_GHASH, testnum, count, d);
+        }
+        for (i = 0; i < loopargs_len; i++)
+            CRYPTO_gcm128_release(loopargs[i].gcm_ctx);
+    }
+
+#ifndef OPENSSL_NO_CAMELLIA
+    if (doit[D_CBC_128_CML]) {
+        if (async_jobs > 0) {
+            BIO_printf(bio_err, "Async mode is not supported with %s\n",
+                       names[D_CBC_128_CML]);
+            doit[D_CBC_128_CML] = 0;
+        }
+        for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
+            print_message(names[D_CBC_128_CML], c[D_CBC_128_CML][testnum],
+                          lengths[testnum]);
+            Time_F(START);
+            for (count = 0, run = 1; COND(c[D_CBC_128_CML][testnum]); count++)
+                Camellia_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
+                                     (size_t)lengths[testnum], &camellia_ks1,
+                                     iv, CAMELLIA_ENCRYPT);
+            d = Time_F(STOP);
+            print_result(D_CBC_128_CML, testnum, count, d);
+        }
+    }
+    if (doit[D_CBC_192_CML]) {
+        if (async_jobs > 0) {
+            BIO_printf(bio_err, "Async mode is not supported with %s\n",
+                       names[D_CBC_192_CML]);
+            doit[D_CBC_192_CML] = 0;
+        }
+        for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
+            print_message(names[D_CBC_192_CML], c[D_CBC_192_CML][testnum],
+                          lengths[testnum]);
+            if (async_jobs > 0) {
+                BIO_printf(bio_err, "Async mode is not supported, exiting...");
+                exit(1);
+            }
+            Time_F(START);
+            for (count = 0, run = 1; COND(c[D_CBC_192_CML][testnum]); count++)
+                Camellia_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
+                                     (size_t)lengths[testnum], &camellia_ks2,
+                                     iv, CAMELLIA_ENCRYPT);
+            d = Time_F(STOP);
+            print_result(D_CBC_192_CML, testnum, count, d);
+        }
+    }
+    if (doit[D_CBC_256_CML]) {
+        if (async_jobs > 0) {
+            BIO_printf(bio_err, "Async mode is not supported with %s\n",
+                       names[D_CBC_256_CML]);
+            doit[D_CBC_256_CML] = 0;
+        }
+        for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
+            print_message(names[D_CBC_256_CML], c[D_CBC_256_CML][testnum],
+                          lengths[testnum]);
+            Time_F(START);
+            for (count = 0, run = 1; COND(c[D_CBC_256_CML][testnum]); count++)
+                Camellia_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
+                                     (size_t)lengths[testnum], &camellia_ks3,
+                                     iv, CAMELLIA_ENCRYPT);
+            d = Time_F(STOP);
+            print_result(D_CBC_256_CML, testnum, count, d);
+        }
+    }
+#endif
+#ifndef OPENSSL_NO_IDEA
+    if (doit[D_CBC_IDEA]) {
+        if (async_jobs > 0) {
+            BIO_printf(bio_err, "Async mode is not supported with %s\n",
+                       names[D_CBC_IDEA]);
+            doit[D_CBC_IDEA] = 0;
+        }
+        for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
+            print_message(names[D_CBC_IDEA], c[D_CBC_IDEA][testnum], lengths[testnum]);
+            Time_F(START);
+            for (count = 0, run = 1; COND(c[D_CBC_IDEA][testnum]); count++)
+                IDEA_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
+                                 (size_t)lengths[testnum], &idea_ks,
+                                 iv, IDEA_ENCRYPT);
+            d = Time_F(STOP);
+            print_result(D_CBC_IDEA, testnum, count, d);
+        }
+    }
+#endif
+#ifndef OPENSSL_NO_SEED
+    if (doit[D_CBC_SEED]) {
+        if (async_jobs > 0) {
+            BIO_printf(bio_err, "Async mode is not supported with %s\n",
+                       names[D_CBC_SEED]);
+            doit[D_CBC_SEED] = 0;
+        }
+        for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
+            print_message(names[D_CBC_SEED], c[D_CBC_SEED][testnum], lengths[testnum]);
+            Time_F(START);
+            for (count = 0, run = 1; COND(c[D_CBC_SEED][testnum]); count++)
+                SEED_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
+                                 (size_t)lengths[testnum], &seed_ks, iv, 1);
+            d = Time_F(STOP);
+            print_result(D_CBC_SEED, testnum, count, d);
+        }
+    }
+#endif
+#ifndef OPENSSL_NO_RC2
+    if (doit[D_CBC_RC2]) {
+        if (async_jobs > 0) {
+            BIO_printf(bio_err, "Async mode is not supported with %s\n",
+                       names[D_CBC_RC2]);
+            doit[D_CBC_RC2] = 0;
+        }
+        for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
+            print_message(names[D_CBC_RC2], c[D_CBC_RC2][testnum], lengths[testnum]);
+            if (async_jobs > 0) {
+                BIO_printf(bio_err, "Async mode is not supported, exiting...");
+                exit(1);
+            }
+            Time_F(START);
+            for (count = 0, run = 1; COND(c[D_CBC_RC2][testnum]); count++)
+                RC2_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
+                                (size_t)lengths[testnum], &rc2_ks,
+                                iv, RC2_ENCRYPT);
+            d = Time_F(STOP);
+            print_result(D_CBC_RC2, testnum, count, d);
+        }
+    }
+#endif
+#ifndef OPENSSL_NO_RC5
+    if (doit[D_CBC_RC5]) {
+        if (async_jobs > 0) {
+            BIO_printf(bio_err, "Async mode is not supported with %s\n",
+                       names[D_CBC_RC5]);
+            doit[D_CBC_RC5] = 0;
+        }
+        for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
+            print_message(names[D_CBC_RC5], c[D_CBC_RC5][testnum], lengths[testnum]);
+            if (async_jobs > 0) {
+                BIO_printf(bio_err, "Async mode is not supported, exiting...");
+                exit(1);
+            }
+            Time_F(START);
+            for (count = 0, run = 1; COND(c[D_CBC_RC5][testnum]); count++)
+                RC5_32_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
+                                   (size_t)lengths[testnum], &rc5_ks,
+                                   iv, RC5_ENCRYPT);
+            d = Time_F(STOP);
+            print_result(D_CBC_RC5, testnum, count, d);
+        }
+    }
+#endif
+#ifndef OPENSSL_NO_BF
+    if (doit[D_CBC_BF]) {
+        if (async_jobs > 0) {
+            BIO_printf(bio_err, "Async mode is not supported with %s\n",
+                       names[D_CBC_BF]);
+            doit[D_CBC_BF] = 0;
+        }
+        for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
+            print_message(names[D_CBC_BF], c[D_CBC_BF][testnum], lengths[testnum]);
+            Time_F(START);
+            for (count = 0, run = 1; COND(c[D_CBC_BF][testnum]); count++)
+                BF_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
+                               (size_t)lengths[testnum], &bf_ks,
+                               iv, BF_ENCRYPT);
+            d = Time_F(STOP);
+            print_result(D_CBC_BF, testnum, count, d);
+        }
+    }
+#endif
+#ifndef OPENSSL_NO_CAST
+    if (doit[D_CBC_CAST]) {
+        if (async_jobs > 0) {
+            BIO_printf(bio_err, "Async mode is not supported with %s\n",
+                       names[D_CBC_CAST]);
+            doit[D_CBC_CAST] = 0;
+        }
+        for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
+            print_message(names[D_CBC_CAST], c[D_CBC_CAST][testnum], lengths[testnum]);
+            Time_F(START);
+            for (count = 0, run = 1; COND(c[D_CBC_CAST][testnum]); count++)
+                CAST_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
+                                 (size_t)lengths[testnum], &cast_ks,
+                                 iv, CAST_ENCRYPT);
+            d = Time_F(STOP);
+            print_result(D_CBC_CAST, testnum, count, d);
+        }
+    }
+#endif
+
+    if (doit[D_EVP]) {
+        if (multiblock && evp_cipher) {
+            if (!
+                (EVP_CIPHER_flags(evp_cipher) &
+                 EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK)) {
+                BIO_printf(bio_err, "%s is not multi-block capable\n",
+                           OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher)));
+                goto end;
+            }
+            if (async_jobs > 0) {
+                BIO_printf(bio_err, "Async mode is not supported, exiting...");
+                exit(1);
+            }
+            multiblock_speed(evp_cipher);
+            ret = 0;
+            goto end;
+        }
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            if (evp_cipher) {
+
+                names[D_EVP] = OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher));
+                /*
+                 * -O3 -fschedule-insns messes up an optimization here!
+                 * names[D_EVP] somehow becomes NULL
+                 */
+                print_message(names[D_EVP], save_count, lengths[testnum]);
+
+                for (k = 0; k < loopargs_len; k++) {
+                    loopargs[k].ctx = EVP_CIPHER_CTX_new();
+                    if (decrypt)
+                        EVP_DecryptInit_ex(loopargs[k].ctx, evp_cipher, NULL, key16, iv);
+                    else
+                        EVP_EncryptInit_ex(loopargs[k].ctx, evp_cipher, NULL, key16, iv);
+                    EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
+                }
+
+                Time_F(START);
+                count = run_benchmark(async_jobs, EVP_Update_loop, loopargs);
+                d = Time_F(STOP);
+                for (k = 0; k < loopargs_len; k++) {
+                    EVP_CIPHER_CTX_free(loopargs[k].ctx);
+                }
+            }
+            if (evp_md) {
+                names[D_EVP] = OBJ_nid2ln(EVP_MD_type(evp_md));
+                print_message(names[D_EVP], save_count, lengths[testnum]);
+                Time_F(START);
+                count = run_benchmark(async_jobs, EVP_Digest_loop, loopargs);
+                d = Time_F(STOP);
+            }
+            print_result(D_EVP, testnum, count, d);
+        }
+    }
+
+    for (i = 0; i < loopargs_len; i++)
+        RAND_bytes(loopargs[i].buf, 36);
+
+#ifndef OPENSSL_NO_RSA
+    for (testnum = 0; testnum < RSA_NUM; testnum++) {
+        int st = 0;
+        if (!rsa_doit[testnum])
+            continue;
+        for (i = 0; i < loopargs_len; i++) {
+            st = RSA_sign(NID_md5_sha1, loopargs[i].buf, 36, loopargs[i].buf2,
+                          &loopargs[i].siglen, loopargs[i].rsa_key[testnum]);
+            if (st == 0)
+                break;
+        }
+        if (st == 0) {
+            BIO_printf(bio_err,
+                       "RSA sign failure.  No RSA sign will be done.\n");
+            ERR_print_errors(bio_err);
+            rsa_count = 1;
+        } else {
+            pkey_print_message("private", "rsa",
+                               rsa_c[testnum][0], rsa_bits[testnum], RSA_SECONDS);
+            /* RSA_blinding_on(rsa_key[testnum],NULL); */
+            Time_F(START);
+            count = run_benchmark(async_jobs, RSA_sign_loop, loopargs);
+            d = Time_F(STOP);
+            BIO_printf(bio_err,
+                       mr ? "+R1:%ld:%d:%.2f\n"
+                       : "%ld %d bit private RSA's in %.2fs\n",
+                       count, rsa_bits[testnum], d);
+            rsa_results[testnum][0] = d / (double)count;
+            rsa_count = count;
+        }
+
+        for (i = 0; i < loopargs_len; i++) {
+            st = RSA_verify(NID_md5_sha1, loopargs[i].buf, 36, loopargs[i].buf2,
+                            loopargs[i].siglen, loopargs[i].rsa_key[testnum]);
+            if (st <= 0)
+                break;
+        }
+        if (st <= 0) {
+            BIO_printf(bio_err,
+                       "RSA verify failure.  No RSA verify will be done.\n");
+            ERR_print_errors(bio_err);
+            rsa_doit[testnum] = 0;
+        } else {
+            pkey_print_message("public", "rsa",
+                               rsa_c[testnum][1], rsa_bits[testnum], RSA_SECONDS);
+            Time_F(START);
+            count = run_benchmark(async_jobs, RSA_verify_loop, loopargs);
+            d = Time_F(STOP);
+            BIO_printf(bio_err,
+                       mr ? "+R2:%ld:%d:%.2f\n"
+                       : "%ld %d bit public RSA's in %.2fs\n",
+                       count, rsa_bits[testnum], d);
+            rsa_results[testnum][1] = d / (double)count;
+        }
+
+        if (rsa_count <= 1) {
+            /* if longer than 10s, don't do any more */
+            for (testnum++; testnum < RSA_NUM; testnum++)
+                rsa_doit[testnum] = 0;
+        }
+    }
+#endif                          /* OPENSSL_NO_RSA */
+
+    for (i = 0; i < loopargs_len; i++)
+        RAND_bytes(loopargs[i].buf, 36);
+
+#ifndef OPENSSL_NO_DSA
+    if (RAND_status() != 1) {
+        RAND_seed(rnd_seed, sizeof rnd_seed);
+    }
+    for (testnum = 0; testnum < DSA_NUM; testnum++) {
+        int st = 0;
+        if (!dsa_doit[testnum])
+            continue;
+
+        /* DSA_generate_key(dsa_key[testnum]); */
+        /* DSA_sign_setup(dsa_key[testnum],NULL); */
+        for (i = 0; i < loopargs_len; i++) {
+            st = DSA_sign(0, loopargs[i].buf, 20, loopargs[i].buf2,
+                          &loopargs[i].siglen, loopargs[i].dsa_key[testnum]);
+            if (st == 0)
+                break;
+        }
+        if (st == 0) {
+            BIO_printf(bio_err,
+                       "DSA sign failure.  No DSA sign will be done.\n");
+            ERR_print_errors(bio_err);
+            rsa_count = 1;
+        } else {
+            pkey_print_message("sign", "dsa",
+                               dsa_c[testnum][0], dsa_bits[testnum], DSA_SECONDS);
+            Time_F(START);
+            count = run_benchmark(async_jobs, DSA_sign_loop, loopargs);
+            d = Time_F(STOP);
+            BIO_printf(bio_err,
+                       mr ? "+R3:%ld:%d:%.2f\n"
+                       : "%ld %d bit DSA signs in %.2fs\n",
+                       count, dsa_bits[testnum], d);
+            dsa_results[testnum][0] = d / (double)count;
+            rsa_count = count;
+        }
+
+        for (i = 0; i < loopargs_len; i++) {
+            st = DSA_verify(0, loopargs[i].buf, 20, loopargs[i].buf2,
+                            loopargs[i].siglen, loopargs[i].dsa_key[testnum]);
+            if (st <= 0)
+                break;
+        }
+        if (st <= 0) {
+            BIO_printf(bio_err,
+                       "DSA verify failure.  No DSA verify will be done.\n");
+            ERR_print_errors(bio_err);
+            dsa_doit[testnum] = 0;
+        } else {
+            pkey_print_message("verify", "dsa",
+                               dsa_c[testnum][1], dsa_bits[testnum], DSA_SECONDS);
+            Time_F(START);
+            count = run_benchmark(async_jobs, DSA_verify_loop, loopargs);
+            d = Time_F(STOP);
+            BIO_printf(bio_err,
+                       mr ? "+R4:%ld:%d:%.2f\n"
+                       : "%ld %d bit DSA verify in %.2fs\n",
+                       count, dsa_bits[testnum], d);
+            dsa_results[testnum][1] = d / (double)count;
+        }
+
+        if (rsa_count <= 1) {
+            /* if longer than 10s, don't do any more */
+            for (testnum++; testnum < DSA_NUM; testnum++)
+                dsa_doit[testnum] = 0;
+        }
+    }
+#endif                          /* OPENSSL_NO_DSA */
+
+#ifndef OPENSSL_NO_EC
+    if (RAND_status() != 1) {
+        RAND_seed(rnd_seed, sizeof rnd_seed);
+    }
+    for (testnum = 0; testnum < EC_NUM; testnum++) {
+        int st = 1;
+
+        if (!ecdsa_doit[testnum])
+            continue;           /* Ignore Curve */
+        for (i = 0; i < loopargs_len; i++) {
+            loopargs[i].ecdsa[testnum] = EC_KEY_new_by_curve_name(test_curves[testnum]);
+            if (loopargs[i].ecdsa[testnum] == NULL) {
+                st = 0;
+                break;
+            }
+        }
+        if (st == 0) {
+            BIO_printf(bio_err, "ECDSA failure.\n");
+            ERR_print_errors(bio_err);
+            rsa_count = 1;
+        } else {
+            for (i = 0; i < loopargs_len; i++) {
+                EC_KEY_precompute_mult(loopargs[i].ecdsa[testnum], NULL);
+                /* Perform ECDSA signature test */
+                EC_KEY_generate_key(loopargs[i].ecdsa[testnum]);
+                st = ECDSA_sign(0, loopargs[i].buf, 20, loopargs[i].buf2,
+                                &loopargs[i].siglen, loopargs[i].ecdsa[testnum]);
+                if (st == 0)
+                    break;
+            }
+            if (st == 0) {
+                BIO_printf(bio_err,
+                           "ECDSA sign failure.  No ECDSA sign will be done.\n");
+                ERR_print_errors(bio_err);
+                rsa_count = 1;
+            } else {
+                pkey_print_message("sign", "ecdsa",
+                                   ecdsa_c[testnum][0],
+                                   test_curves_bits[testnum], ECDSA_SECONDS);
+                Time_F(START);
+                count = run_benchmark(async_jobs, ECDSA_sign_loop, loopargs);
+                d = Time_F(STOP);
+
+                BIO_printf(bio_err,
+                           mr ? "+R5:%ld:%d:%.2f\n" :
+                           "%ld %d bit ECDSA signs in %.2fs \n",
+                           count, test_curves_bits[testnum], d);
+                ecdsa_results[testnum][0] = d / (double)count;
+                rsa_count = count;
+            }
+
+            /* Perform ECDSA verification test */
+            for (i = 0; i < loopargs_len; i++) {
+                st = ECDSA_verify(0, loopargs[i].buf, 20, loopargs[i].buf2,
+                                  loopargs[i].siglen, loopargs[i].ecdsa[testnum]);
+                if (st != 1)
+                    break;
+            }
+            if (st != 1) {
+                BIO_printf(bio_err,
+                           "ECDSA verify failure.  No ECDSA verify will be done.\n");
+                ERR_print_errors(bio_err);
+                ecdsa_doit[testnum] = 0;
+            } else {
+                pkey_print_message("verify", "ecdsa",
+                                   ecdsa_c[testnum][1],
+                                   test_curves_bits[testnum], ECDSA_SECONDS);
+                Time_F(START);
+                count = run_benchmark(async_jobs, ECDSA_verify_loop, loopargs);
+                d = Time_F(STOP);
+                BIO_printf(bio_err,
+                           mr ? "+R6:%ld:%d:%.2f\n"
+                           : "%ld %d bit ECDSA verify in %.2fs\n",
+                           count, test_curves_bits[testnum], d);
+                ecdsa_results[testnum][1] = d / (double)count;
+            }
+
+            if (rsa_count <= 1) {
+                /* if longer than 10s, don't do any more */
+                for (testnum++; testnum < EC_NUM; testnum++)
+                    ecdsa_doit[testnum] = 0;
+            }
+        }
+    }
+
+    if (RAND_status() != 1) {
+        RAND_seed(rnd_seed, sizeof rnd_seed);
+    }
+    for (testnum = 0; testnum < EC_NUM; testnum++) {
+        int ecdh_checks = 1;
+
+        if (!ecdh_doit[testnum])
+            continue;
+        for (i = 0; i < loopargs_len; i++) {
+            loopargs[i].ecdh_a[testnum] = EC_KEY_new_by_curve_name(test_curves[testnum]);
+            loopargs[i].ecdh_b[testnum] = EC_KEY_new_by_curve_name(test_curves[testnum]);
+            if (loopargs[i].ecdh_a[testnum] == NULL ||
+                loopargs[i].ecdh_b[testnum] == NULL) {
+                ecdh_checks = 0;
+                break;
+            }
+        }
+        if (ecdh_checks == 0) {
+            BIO_printf(bio_err, "ECDH failure.\n");
+            ERR_print_errors(bio_err);
+            rsa_count = 1;
+        } else {
+            for (i = 0; i < loopargs_len; i++) {
+                /* generate two ECDH key pairs */
+                if (!EC_KEY_generate_key(loopargs[i].ecdh_a[testnum]) ||
+                        !EC_KEY_generate_key(loopargs[i].ecdh_b[testnum])) {
+                    BIO_printf(bio_err, "ECDH key generation failure.\n");
+                    ERR_print_errors(bio_err);
+                    ecdh_checks = 0;
+                    rsa_count = 1;
+                } else {
+                    int secret_size_a, secret_size_b;
+                    /*
+                     * If field size is not more than 24 octets, then use SHA-1
+                     * hash of result; otherwise, use result (see section 4.8 of
+                     * draft-ietf-tls-ecc-03.txt).
+                     */
+                    int field_size = EC_GROUP_get_degree(
+                            EC_KEY_get0_group(loopargs[i].ecdh_a[testnum]));
+
+                    if (field_size <= 24 * 8) {                 /* 192 bits */
+                        loopargs[i].outlen = KDF1_SHA1_len;
+                        loopargs[i].kdf = KDF1_SHA1;
+                    } else {
+                        loopargs[i].outlen = (field_size + 7) / 8;
+                        loopargs[i].kdf = NULL;
+                    }
+                    secret_size_a =
+                        ECDH_compute_key(loopargs[i].secret_a, loopargs[i].outlen,
+                                EC_KEY_get0_public_key(loopargs[i].ecdh_b[testnum]),
+                                loopargs[i].ecdh_a[testnum], loopargs[i].kdf);
+                    secret_size_b =
+                        ECDH_compute_key(loopargs[i].secret_b, loopargs[i].outlen,
+                                EC_KEY_get0_public_key(loopargs[i].ecdh_a[testnum]),
+                                loopargs[i].ecdh_b[testnum], loopargs[i].kdf);
+                    if (secret_size_a != secret_size_b)
+                        ecdh_checks = 0;
+                    else
+                        ecdh_checks = 1;
+
+                    for (k = 0; k < secret_size_a && ecdh_checks == 1; k++) {
+                        if (loopargs[i].secret_a[k] != loopargs[i].secret_b[k])
+                            ecdh_checks = 0;
+                    }
+
+                    if (ecdh_checks == 0) {
+                        BIO_printf(bio_err, "ECDH computations don't match.\n");
+                        ERR_print_errors(bio_err);
+                        rsa_count = 1;
+                        break;
+                    }
+                }
+            }
+            if (ecdh_checks != 0) {
+                pkey_print_message("", "ecdh",
+                        ecdh_c[testnum][0],
+                        test_curves_bits[testnum], ECDH_SECONDS);
+                Time_F(START);
+                count = run_benchmark(async_jobs, ECDH_compute_key_loop, loopargs);
+                d = Time_F(STOP);
+                BIO_printf(bio_err,
+                        mr ? "+R7:%ld:%d:%.2f\n" :
+                        "%ld %d-bit ECDH ops in %.2fs\n", count,
+                        test_curves_bits[testnum], d);
+                ecdh_results[testnum][0] = d / (double)count;
+                rsa_count = count;
+            }
+        }
+
+        if (rsa_count <= 1) {
+            /* if longer than 10s, don't do any more */
+            for (testnum++; testnum < EC_NUM; testnum++)
+                ecdh_doit[testnum] = 0;
+        }
+    }
+#endif                          /* OPENSSL_NO_EC */
+#ifndef NO_FORK
+ show_res:
+#endif
+    if (!mr) {
+        printf("%s\n", OpenSSL_version(OPENSSL_VERSION));
+        printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON));
+        printf("options:");
+        printf("%s ", BN_options());
+#ifndef OPENSSL_NO_MD2
+        printf("%s ", MD2_options());
+#endif
+#ifndef OPENSSL_NO_RC4
+        printf("%s ", RC4_options());
+#endif
+#ifndef OPENSSL_NO_DES
+        printf("%s ", DES_options());
+#endif
+        printf("%s ", AES_options());
+#ifndef OPENSSL_NO_IDEA
+        printf("%s ", IDEA_options());
+#endif
+#ifndef OPENSSL_NO_BF
+        printf("%s ", BF_options());
+#endif
+        printf("\n%s\n", OpenSSL_version(OPENSSL_CFLAGS));
+    }
+
+    if (pr_header) {
+        if (mr)
+            printf("+H");
+        else {
+            printf
+                ("The 'numbers' are in 1000s of bytes per second processed.\n");
+            printf("type        ");
+        }
+        for (testnum = 0; testnum < SIZE_NUM; testnum++)
+            printf(mr ? ":%d" : "%7d bytes", lengths[testnum]);
+        printf("\n");
+    }
+
+    for (k = 0; k < ALGOR_NUM; k++) {
+        if (!doit[k])
+            continue;
+        if (mr)
+            printf("+F:%d:%s", k, names[k]);
+        else
+            printf("%-13s", names[k]);
+        for (testnum = 0; testnum < SIZE_NUM; testnum++) {
+            if (results[k][testnum] > 10000 && !mr)
+                printf(" %11.2fk", results[k][testnum] / 1e3);
+            else
+                printf(mr ? ":%.2f" : " %11.2f ", results[k][testnum]);
+        }
+        printf("\n");
+    }
+#ifndef OPENSSL_NO_RSA
+    testnum = 1;
+    for (k = 0; k < RSA_NUM; k++) {
+        if (!rsa_doit[k])
+            continue;
+        if (testnum && !mr) {
+            printf("%18ssign    verify    sign/s verify/s\n", " ");
+            testnum = 0;
+        }
+        if (mr)
+            printf("+F2:%u:%u:%f:%f\n",
+                   k, rsa_bits[k], rsa_results[k][0], rsa_results[k][1]);
+        else
+            printf("rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
+                   rsa_bits[k], rsa_results[k][0], rsa_results[k][1],
+                   1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1]);
+    }
+#endif
+#ifndef OPENSSL_NO_DSA
+    testnum = 1;
+    for (k = 0; k < DSA_NUM; k++) {
+        if (!dsa_doit[k])
+            continue;
+        if (testnum && !mr) {
+            printf("%18ssign    verify    sign/s verify/s\n", " ");
+            testnum = 0;
+        }
+        if (mr)
+            printf("+F3:%u:%u:%f:%f\n",
+                   k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]);
+        else
+            printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
+                   dsa_bits[k], dsa_results[k][0], dsa_results[k][1],
+                   1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1]);
+    }
+#endif
+#ifndef OPENSSL_NO_EC
+    testnum = 1;
+    for (k = 0; k < EC_NUM; k++) {
+        if (!ecdsa_doit[k])
+            continue;
+        if (testnum && !mr) {
+            printf("%30ssign    verify    sign/s verify/s\n", " ");
+            testnum = 0;
+        }
+
+        if (mr)
+            printf("+F4:%u:%u:%f:%f\n",
+                   k, test_curves_bits[k],
+                   ecdsa_results[k][0], ecdsa_results[k][1]);
+        else
+            printf("%4u bit ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
+                   test_curves_bits[k],
+                   test_curves_names[k],
+                   ecdsa_results[k][0], ecdsa_results[k][1],
+                   1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1]);
+    }
+
+    testnum = 1;
+    for (k = 0; k < EC_NUM; k++) {
+        if (!ecdh_doit[k])
+            continue;
+        if (testnum && !mr) {
+            printf("%30sop      op/s\n", " ");
+            testnum = 0;
+        }
+        if (mr)
+            printf("+F5:%u:%u:%f:%f\n",
+                   k, test_curves_bits[k],
+                   ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
+
+        else
+            printf("%4u bit ecdh (%s) %8.4fs %8.1f\n",
+                   test_curves_bits[k],
+                   test_curves_names[k],
+                   ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
+    }
+#endif
+
+    ret = 0;
+
+ end:
+    ERR_print_errors(bio_err);
+    for (i = 0; i < loopargs_len; i++) {
+        OPENSSL_free(loopargs[i].buf_malloc);
+        OPENSSL_free(loopargs[i].buf2_malloc);
+
+#ifndef OPENSSL_NO_RSA
+        for (k = 0; k < RSA_NUM; k++)
+            RSA_free(loopargs[i].rsa_key[k]);
+#endif
+#ifndef OPENSSL_NO_DSA
+        for (k = 0; k < DSA_NUM; k++)
+            DSA_free(loopargs[i].dsa_key[k]);
+#endif
+#ifndef OPENSSL_NO_EC
+        for (k = 0; k < EC_NUM; k++) {
+            EC_KEY_free(loopargs[i].ecdsa[k]);
+            EC_KEY_free(loopargs[i].ecdh_a[k]);
+            EC_KEY_free(loopargs[i].ecdh_b[k]);
+        }
+        OPENSSL_free(loopargs[i].secret_a);
+        OPENSSL_free(loopargs[i].secret_b);
+#endif
+    }
+
+    if (async_jobs > 0) {
+        for (i = 0; i < loopargs_len; i++)
+            ASYNC_WAIT_CTX_free(loopargs[i].wait_ctx);
+    }
+
+    if (async_init) {
+        ASYNC_cleanup_thread();
+    }
+    OPENSSL_free(loopargs);
+    release_engine(e);
+    return (ret);
+}
+
+static void print_message(const char *s, long num, int length)
+{
+#ifdef SIGALRM
+    BIO_printf(bio_err,
+               mr ? "+DT:%s:%d:%d\n"
+               : "Doing %s for %ds on %d size blocks: ", s, SECONDS, length);
+    (void)BIO_flush(bio_err);
+    alarm(SECONDS);
+#else
+    BIO_printf(bio_err,
+               mr ? "+DN:%s:%ld:%d\n"
+               : "Doing %s %ld times on %d size blocks: ", s, num, length);
+    (void)BIO_flush(bio_err);
+#endif
+}
+
+static void pkey_print_message(const char *str, const char *str2, long num,
+                               int bits, int tm)
+{
+#ifdef SIGALRM
+    BIO_printf(bio_err,
+               mr ? "+DTP:%d:%s:%s:%d\n"
+               : "Doing %d bit %s %s's for %ds: ", bits, str, str2, tm);
+    (void)BIO_flush(bio_err);
+    alarm(tm);
+#else
+    BIO_printf(bio_err,
+               mr ? "+DNP:%ld:%d:%s:%s\n"
+               : "Doing %ld %d bit %s %s's: ", num, bits, str, str2);
+    (void)BIO_flush(bio_err);
+#endif
+}
+
+static void print_result(int alg, int run_no, int count, double time_used)
+{
+    if (count == -1) {
+        BIO_puts(bio_err, "EVP error!\n");
+        exit(1);
+    }
+    BIO_printf(bio_err,
+               mr ? "+R:%d:%s:%f\n"
+               : "%d %s's in %.2fs\n", count, names[alg], time_used);
+    results[alg][run_no] = ((double)count) / time_used * lengths[run_no];
+}
+
+#ifndef NO_FORK
+static char *sstrsep(char **string, const char *delim)
+{
+    char isdelim[256];
+    char *token = *string;
+
+    if (**string == 0)
+        return NULL;
+
+    memset(isdelim, 0, sizeof isdelim);
+    isdelim[0] = 1;
+
+    while (*delim) {
+        isdelim[(unsigned char)(*delim)] = 1;
+        delim++;
+    }
+
+    while (!isdelim[(unsigned char)(**string)]) {
+        (*string)++;
+    }
+
+    if (**string) {
+        **string = 0;
+        (*string)++;
+    }
+
+    return token;
+}
+
+static int do_multi(int multi)
+{
+    int n;
+    int fd[2];
+    int *fds;
+    static char sep[] = ":";
+
+    fds = malloc(sizeof(*fds) * multi);
+    for (n = 0; n < multi; ++n) {
+        if (pipe(fd) == -1) {
+            BIO_printf(bio_err, "pipe failure\n");
+            exit(1);
+        }
+        fflush(stdout);
+        (void)BIO_flush(bio_err);
+        if (fork()) {
+            close(fd[1]);
+            fds[n] = fd[0];
+        } else {
+            close(fd[0]);
+            close(1);
+            if (dup(fd[1]) == -1) {
+                BIO_printf(bio_err, "dup failed\n");
+                exit(1);
+            }
+            close(fd[1]);
+            mr = 1;
+            usertime = 0;
+            free(fds);
+            return 0;
+        }
+        printf("Forked child %d\n", n);
+    }
+
+    /* for now, assume the pipe is long enough to take all the output */
+    for (n = 0; n < multi; ++n) {
+        FILE *f;
+        char buf[1024];
+        char *p;
+
+        f = fdopen(fds[n], "r");
+        while (fgets(buf, sizeof buf, f)) {
+            p = strchr(buf, '\n');
+            if (p)
+                *p = '\0';
+            if (buf[0] != '+') {
+                BIO_printf(bio_err, "Don't understand line '%s' from child %d\n",
+                        buf, n);
+                continue;
+            }
+            printf("Got: %s from %d\n", buf, n);
+            if (strncmp(buf, "+F:", 3) == 0) {
+                int alg;
+                int j;
+
+                p = buf + 3;
+                alg = atoi(sstrsep(&p, sep));
+                sstrsep(&p, sep);
+                for (j = 0; j < SIZE_NUM; ++j)
+                    results[alg][j] += atof(sstrsep(&p, sep));
+            } else if (strncmp(buf, "+F2:", 4) == 0) {
+                int k;
+                double d;
+
+                p = buf + 4;
+                k = atoi(sstrsep(&p, sep));
+                sstrsep(&p, sep);
+
+                d = atof(sstrsep(&p, sep));
+                if (n)
+                    rsa_results[k][0] = 1 / (1 / rsa_results[k][0] + 1 / d);
+                else
+                    rsa_results[k][0] = d;
+
+                d = atof(sstrsep(&p, sep));
+                if (n)
+                    rsa_results[k][1] = 1 / (1 / rsa_results[k][1] + 1 / d);
+                else
+                    rsa_results[k][1] = d;
+            }
+# ifndef OPENSSL_NO_DSA
+            else if (strncmp(buf, "+F3:", 4) == 0) {
+                int k;
+                double d;
+
+                p = buf + 4;
+                k = atoi(sstrsep(&p, sep));
+                sstrsep(&p, sep);
+
+                d = atof(sstrsep(&p, sep));
+                if (n)
+                    dsa_results[k][0] = 1 / (1 / dsa_results[k][0] + 1 / d);
+                else
+                    dsa_results[k][0] = d;
+
+                d = atof(sstrsep(&p, sep));
+                if (n)
+                    dsa_results[k][1] = 1 / (1 / dsa_results[k][1] + 1 / d);
+                else
+                    dsa_results[k][1] = d;
+            }
+# endif
+# ifndef OPENSSL_NO_EC
+            else if (strncmp(buf, "+F4:", 4) == 0) {
+                int k;
+                double d;
+
+                p = buf + 4;
+                k = atoi(sstrsep(&p, sep));
+                sstrsep(&p, sep);
+
+                d = atof(sstrsep(&p, sep));
+                if (n)
+                    ecdsa_results[k][0] =
+                        1 / (1 / ecdsa_results[k][0] + 1 / d);
+                else
+                    ecdsa_results[k][0] = d;
+
+                d = atof(sstrsep(&p, sep));
+                if (n)
+                    ecdsa_results[k][1] =
+                        1 / (1 / ecdsa_results[k][1] + 1 / d);
+                else
+                    ecdsa_results[k][1] = d;
+            } else if (strncmp(buf, "+F5:", 4) == 0) {
+                int k;
+                double d;
+
+                p = buf + 4;
+                k = atoi(sstrsep(&p, sep));
+                sstrsep(&p, sep);
+
+                d = atof(sstrsep(&p, sep));
+                if (n)
+                    ecdh_results[k][0] = 1 / (1 / ecdh_results[k][0] + 1 / d);
+                else
+                    ecdh_results[k][0] = d;
+
+            }
+# endif
+
+            else if (strncmp(buf, "+H:", 3) == 0) {
+                ;
+            } else
+                BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf, n);
+        }
+
+        fclose(f);
+    }
+    free(fds);
+    return 1;
+}
+#endif
+
+static void multiblock_speed(const EVP_CIPHER *evp_cipher)
+{
+    static int mblengths[] =
+        { 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 };
+    int j, count, num = OSSL_NELEM(mblengths);
+    const char *alg_name;
+    unsigned char *inp, *out, no_key[32], no_iv[16];
+    EVP_CIPHER_CTX *ctx;
+    double d = 0.0;
+
+    inp = app_malloc(mblengths[num - 1], "multiblock input buffer");
+    out = app_malloc(mblengths[num - 1] + 1024, "multiblock output buffer");
+    ctx = EVP_CIPHER_CTX_new();
+    EVP_EncryptInit_ex(ctx, evp_cipher, NULL, no_key, no_iv);
+    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY, sizeof(no_key),
+                        no_key);
+    alg_name = OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher));
+
+    for (j = 0; j < num; j++) {
+        print_message(alg_name, 0, mblengths[j]);
+        Time_F(START);
+        for (count = 0, run = 1; run && count < 0x7fffffff; count++) {
+            unsigned char aad[EVP_AEAD_TLS1_AAD_LEN];
+            EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
+            size_t len = mblengths[j];
+            int packlen;
+
+            memset(aad, 0, 8);  /* avoid uninitialized values */
+            aad[8] = 23;        /* SSL3_RT_APPLICATION_DATA */
+            aad[9] = 3;         /* version */
+            aad[10] = 2;
+            aad[11] = 0;        /* length */
+            aad[12] = 0;
+            mb_param.out = NULL;
+            mb_param.inp = aad;
+            mb_param.len = len;
+            mb_param.interleave = 8;
+
+            packlen = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
+                                          sizeof(mb_param), &mb_param);
+
+            if (packlen > 0) {
+                mb_param.out = out;
+                mb_param.inp = inp;
+                mb_param.len = len;
+                EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
+                                    sizeof(mb_param), &mb_param);
+            } else {
+                int pad;
+
+                RAND_bytes(out, 16);
+                len += 16;
+                aad[11] = len >> 8;
+                aad[12] = len;
+                pad = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD,
+                                          EVP_AEAD_TLS1_AAD_LEN, aad);
+                EVP_Cipher(ctx, out, inp, len + pad);
+            }
+        }
+        d = Time_F(STOP);
+        BIO_printf(bio_err, mr ? "+R:%d:%s:%f\n"
+                   : "%d %s's in %.2fs\n", count, "evp", d);
+        results[D_EVP][j] = ((double)count) / d * mblengths[j];
+    }
+
+    if (mr) {
+        fprintf(stdout, "+H");
+        for (j = 0; j < num; j++)
+            fprintf(stdout, ":%d", mblengths[j]);
+        fprintf(stdout, "\n");
+        fprintf(stdout, "+F:%d:%s", D_EVP, alg_name);
+        for (j = 0; j < num; j++)
+            fprintf(stdout, ":%.2f", results[D_EVP][j]);
+        fprintf(stdout, "\n");
+    } else {
+        fprintf(stdout,
+                "The 'numbers' are in 1000s of bytes per second processed.\n");
+        fprintf(stdout, "type                    ");
+        for (j = 0; j < num; j++)
+            fprintf(stdout, "%7d bytes", mblengths[j]);
+        fprintf(stdout, "\n");
+        fprintf(stdout, "%-24s", alg_name);
+
+        for (j = 0; j < num; j++) {
+            if (results[D_EVP][j] > 10000)
+                fprintf(stdout, " %11.2fk", results[D_EVP][j] / 1e3);
+            else
+                fprintf(stdout, " %11.2f ", results[D_EVP][j]);
+        }
+        fprintf(stdout, "\n");
+    }
+
+    OPENSSL_free(inp);
+    OPENSSL_free(out);
+    EVP_CIPHER_CTX_free(ctx);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/spkac.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/spkac.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/spkac.c	(revision 331)
@@ -0,0 +1,193 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/conf.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/lhash.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_NOOUT, OPT_PUBKEY, OPT_VERIFY, OPT_IN, OPT_OUT,
+    OPT_ENGINE, OPT_KEY, OPT_CHALLENGE, OPT_PASSIN, OPT_SPKAC,
+    OPT_SPKSECT
+} OPTION_CHOICE;
+
+OPTIONS spkac_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"in", OPT_IN, '<', "Input file"},
+    {"out", OPT_OUT, '>', "Output file"},
+    {"key", OPT_KEY, '<', "Create SPKAC using private key"},
+    {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
+    {"challenge", OPT_CHALLENGE, 's', "Challenge string"},
+    {"spkac", OPT_SPKAC, 's', "Alternative SPKAC name"},
+    {"noout", OPT_NOOUT, '-', "Don't print SPKAC"},
+    {"pubkey", OPT_PUBKEY, '-', "Output public key"},
+    {"verify", OPT_VERIFY, '-', "Verify SPKAC signature"},
+    {"spksect", OPT_SPKSECT, 's',
+     "Specify the name of an SPKAC-dedicated section of configuration"},
+#ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+#endif
+    {NULL}
+};
+
+int spkac_main(int argc, char **argv)
+{
+    BIO *out = NULL;
+    CONF *conf = NULL;
+    ENGINE *e = NULL;
+    EVP_PKEY *pkey = NULL;
+    NETSCAPE_SPKI *spki = NULL;
+    char *challenge = NULL, *keyfile = NULL;
+    char *infile = NULL, *outfile = NULL, *passinarg = NULL, *passin = NULL;
+    char *spkstr = NULL, *prog;
+    const char *spkac = "SPKAC", *spksect = "default";
+    int i, ret = 1, verify = 0, noout = 0, pubkey = 0;
+    OPTION_CHOICE o;
+
+    prog = opt_init(argc, argv, spkac_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(spkac_options);
+            ret = 0;
+            goto end;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_NOOUT:
+            noout = 1;
+            break;
+        case OPT_PUBKEY:
+            pubkey = 1;
+            break;
+        case OPT_VERIFY:
+            verify = 1;
+            break;
+        case OPT_PASSIN:
+            passinarg = opt_arg();
+            break;
+        case OPT_KEY:
+            keyfile = opt_arg();
+            break;
+        case OPT_CHALLENGE:
+            challenge = opt_arg();
+            break;
+        case OPT_SPKAC:
+            spkac = opt_arg();
+            break;
+        case OPT_SPKSECT:
+            spksect = opt_arg();
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    if (argc != 0)
+        goto opthelp;
+
+    if (!app_passwd(passinarg, NULL, &passin, NULL)) {
+        BIO_printf(bio_err, "Error getting password\n");
+        goto end;
+    }
+
+    if (keyfile) {
+        pkey = load_key(strcmp(keyfile, "-") ? keyfile : NULL,
+                        FORMAT_PEM, 1, passin, e, "private key");
+        if (!pkey) {
+            goto end;
+        }
+        spki = NETSCAPE_SPKI_new();
+        if (challenge)
+            ASN1_STRING_set(spki->spkac->challenge,
+                            challenge, (int)strlen(challenge));
+        NETSCAPE_SPKI_set_pubkey(spki, pkey);
+        NETSCAPE_SPKI_sign(spki, pkey, EVP_md5());
+        spkstr = NETSCAPE_SPKI_b64_encode(spki);
+
+        out = bio_open_default(outfile, 'w', FORMAT_TEXT);
+        if (out == NULL) {
+            OPENSSL_free(spkstr);
+            goto end;
+        }
+        BIO_printf(out, "SPKAC=%s\n", spkstr);
+        OPENSSL_free(spkstr);
+        ret = 0;
+        goto end;
+    }
+
+    if ((conf = app_load_config(infile)) == NULL)
+        goto end;
+
+    spkstr = NCONF_get_string(conf, spksect, spkac);
+
+    if (spkstr == NULL) {
+        BIO_printf(bio_err, "Can't find SPKAC called \"%s\"\n", spkac);
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    spki = NETSCAPE_SPKI_b64_decode(spkstr, -1);
+
+    if (!spki) {
+        BIO_printf(bio_err, "Error loading SPKAC\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    out = bio_open_default(outfile, 'w', FORMAT_TEXT);
+    if (out == NULL)
+        goto end;
+
+    if (!noout)
+        NETSCAPE_SPKI_print(out, spki);
+    pkey = NETSCAPE_SPKI_get_pubkey(spki);
+    if (verify) {
+        i = NETSCAPE_SPKI_verify(spki, pkey);
+        if (i > 0)
+            BIO_printf(bio_err, "Signature OK\n");
+        else {
+            BIO_printf(bio_err, "Signature Failure\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+    if (pubkey)
+        PEM_write_bio_PUBKEY(out, pkey);
+
+    ret = 0;
+
+ end:
+    NCONF_free(conf);
+    NETSCAPE_SPKI_free(spki);
+    BIO_free_all(out);
+    EVP_PKEY_free(pkey);
+    release_engine(e);
+    OPENSSL_free(passin);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/srp.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/srp.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/srp.c	(revision 331)
@@ -0,0 +1,609 @@
+/*
+ * Copyright 2004-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 <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_SRP
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+# include <openssl/conf.h>
+# include <openssl/bio.h>
+# include <openssl/err.h>
+# include <openssl/txt_db.h>
+# include <openssl/buffer.h>
+# include <openssl/srp.h>
+# include "apps.h"
+
+# define BASE_SECTION    "srp"
+# define CONFIG_FILE "openssl.cnf"
+
+# define ENV_RANDFILE            "RANDFILE"
+
+# define ENV_DATABASE            "srpvfile"
+# define ENV_DEFAULT_SRP         "default_srp"
+
+static int get_index(CA_DB *db, char *id, char type)
+{
+    char **pp;
+    int i;
+    if (id == NULL)
+        return -1;
+    if (type == DB_SRP_INDEX)
+        for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
+            pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
+            if (pp[DB_srptype][0] == DB_SRP_INDEX
+                && strcmp(id, pp[DB_srpid]) == 0)
+                return i;
+    } else
+        for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
+            pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
+
+            if (pp[DB_srptype][0] != DB_SRP_INDEX
+                && strcmp(id, pp[DB_srpid]) == 0)
+                return i;
+        }
+
+    return -1;
+}
+
+static void print_entry(CA_DB *db, int indx, int verbose, char *s)
+{
+    if (indx >= 0 && verbose) {
+        int j;
+        char **pp = sk_OPENSSL_PSTRING_value(db->db->data, indx);
+        BIO_printf(bio_err, "%s \"%s\"\n", s, pp[DB_srpid]);
+        for (j = 0; j < DB_NUMBER; j++) {
+            BIO_printf(bio_err, "  %d = \"%s\"\n", j, pp[j]);
+        }
+    }
+}
+
+static void print_index(CA_DB *db, int indexindex, int verbose)
+{
+    print_entry(db, indexindex, verbose, "g N entry");
+}
+
+static void print_user(CA_DB *db, int userindex, int verbose)
+{
+    if (verbose > 0) {
+        char **pp = sk_OPENSSL_PSTRING_value(db->db->data, userindex);
+
+        if (pp[DB_srptype][0] != 'I') {
+            print_entry(db, userindex, verbose, "User entry");
+            print_entry(db, get_index(db, pp[DB_srpgN], 'I'), verbose,
+                        "g N entry");
+        }
+
+    }
+}
+
+static int update_index(CA_DB *db, char **row)
+{
+    char **irow;
+    int i;
+
+    irow = app_malloc(sizeof(*irow) * (DB_NUMBER + 1), "row pointers");
+    for (i = 0; i < DB_NUMBER; i++) {
+        irow[i] = row[i];
+        row[i] = NULL;
+    }
+    irow[DB_NUMBER] = NULL;
+
+    if (!TXT_DB_insert(db->db, irow)) {
+        BIO_printf(bio_err, "failed to update srpvfile\n");
+        BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error);
+        OPENSSL_free(irow);
+        return 0;
+    }
+    return 1;
+}
+
+static char *lookup_conf(const CONF *conf, const char *section, const char *tag)
+{
+    char *entry = NCONF_get_string(conf, section, tag);
+    if (entry == NULL)
+        BIO_printf(bio_err, "variable lookup failed for %s::%s\n", section, tag);
+    return entry;
+}
+
+static char *srp_verify_user(const char *user, const char *srp_verifier,
+                             char *srp_usersalt, const char *g, const char *N,
+                             const char *passin, int verbose)
+{
+    char password[1024];
+    PW_CB_DATA cb_tmp;
+    char *verifier = NULL;
+    char *gNid = NULL;
+
+    cb_tmp.prompt_info = user;
+    cb_tmp.password = passin;
+
+    if (password_callback(password, sizeof(password), 0, &cb_tmp) > 0) {
+        if (verbose)
+            BIO_printf(bio_err,
+                       "Validating\n   user=\"%s\"\n srp_verifier=\"%s\"\n srp_usersalt=\"%s\"\n g=\"%s\"\n N=\"%s\"\n",
+                       user, srp_verifier, srp_usersalt, g, N);
+        BIO_printf(bio_err, "Pass %s\n", password);
+
+        OPENSSL_assert(srp_usersalt != NULL);
+        if (!
+            (gNid =
+             SRP_create_verifier(user, password, &srp_usersalt, &verifier, N,
+                                 g))) {
+            BIO_printf(bio_err, "Internal error validating SRP verifier\n");
+        } else {
+            if (strcmp(verifier, srp_verifier))
+                gNid = NULL;
+            OPENSSL_free(verifier);
+        }
+    }
+    return gNid;
+}
+
+static char *srp_create_user(char *user, char **srp_verifier,
+                             char **srp_usersalt, char *g, char *N,
+                             char *passout, int verbose)
+{
+    char password[1024];
+    PW_CB_DATA cb_tmp;
+    char *gNid = NULL;
+    char *salt = NULL;
+    cb_tmp.prompt_info = user;
+    cb_tmp.password = passout;
+
+    if (password_callback(password, sizeof(password), 1, &cb_tmp) > 0) {
+        if (verbose)
+            BIO_printf(bio_err, "Creating\n user=\"%s\"\n g=\"%s\"\n N=\"%s\"\n",
+                       user, g, N);
+        if (!
+            (gNid =
+             SRP_create_verifier(user, password, &salt, srp_verifier, N,
+                                 g))) {
+            BIO_printf(bio_err, "Internal error creating SRP verifier\n");
+        } else
+            *srp_usersalt = salt;
+        if (verbose > 1)
+            BIO_printf(bio_err, "gNid=%s salt =\"%s\"\n verifier =\"%s\"\n", gNid,
+                       salt, *srp_verifier);
+
+    }
+    return gNid;
+}
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_VERBOSE, OPT_CONFIG, OPT_NAME, OPT_SRPVFILE, OPT_ADD,
+    OPT_DELETE, OPT_MODIFY, OPT_LIST, OPT_GN, OPT_USERINFO,
+    OPT_PASSIN, OPT_PASSOUT, OPT_ENGINE
+} OPTION_CHOICE;
+
+OPTIONS srp_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"verbose", OPT_VERBOSE, '-', "Talk a lot while doing things"},
+    {"config", OPT_CONFIG, '<', "A config file"},
+    {"name", OPT_NAME, 's', "The particular srp definition to use"},
+    {"srpvfile", OPT_SRPVFILE, '<', "The srp verifier file name"},
+    {"add", OPT_ADD, '-', "Add a user and srp verifier"},
+    {"modify", OPT_MODIFY, '-',
+     "Modify the srp verifier of an existing user"},
+    {"delete", OPT_DELETE, '-', "Delete user from verifier file"},
+    {"list", OPT_LIST, '-', "List users"},
+    {"gn", OPT_GN, 's', "Set g and N values to be used for new verifier"},
+    {"userinfo", OPT_USERINFO, 's', "Additional info to be set for user"},
+    {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
+    {"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
+# ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+# endif
+    {NULL}
+};
+
+int srp_main(int argc, char **argv)
+{
+    ENGINE *e = NULL;
+    CA_DB *db = NULL;
+    CONF *conf = NULL;
+    int gNindex = -1, maxgN = -1, ret = 1, errors = 0, verbose = 0, i;
+    int doupdatedb = 0, mode = OPT_ERR;
+    char *user = NULL, *passinarg = NULL, *passoutarg = NULL;
+    char *passin = NULL, *passout = NULL, *gN = NULL, *userinfo = NULL;
+    char *randfile = NULL, *section = NULL;
+    char **gNrow = NULL, *configfile = NULL;
+    char *srpvfile = NULL, **pp, *prog;
+    OPTION_CHOICE o;
+
+    prog = opt_init(argc, argv, srp_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(srp_options);
+            ret = 0;
+            goto end;
+        case OPT_VERBOSE:
+            verbose++;
+            break;
+        case OPT_CONFIG:
+            configfile = opt_arg();
+            break;
+        case OPT_NAME:
+            section = opt_arg();
+            break;
+        case OPT_SRPVFILE:
+            srpvfile = opt_arg();
+            break;
+        case OPT_ADD:
+        case OPT_DELETE:
+        case OPT_MODIFY:
+        case OPT_LIST:
+            if (mode != OPT_ERR) {
+                BIO_printf(bio_err,
+                           "%s: Only one of -add/delete-modify/-list\n",
+                           prog);
+                goto opthelp;
+            }
+            mode = o;
+            break;
+        case OPT_GN:
+            gN = opt_arg();
+            break;
+        case OPT_USERINFO:
+            userinfo = opt_arg();
+            break;
+        case OPT_PASSIN:
+            passinarg = opt_arg();
+            break;
+        case OPT_PASSOUT:
+            passoutarg = opt_arg();
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    argv = opt_rest();
+
+    if (srpvfile && configfile) {
+        BIO_printf(bio_err,
+                   "-srpvfile and -configfile cannot be specified together.\n");
+        goto end;
+    }
+    if (mode == OPT_ERR) {
+        BIO_printf(bio_err,
+                   "Exactly one of the options -add, -delete, -modify -list must be specified.\n");
+        goto opthelp;
+    }
+    if ((mode == OPT_DELETE || mode == OPT_MODIFY || mode == OPT_ADD)
+        && argc < 1) {
+        BIO_printf(bio_err,
+                   "Need at least one user for options -add, -delete, -modify. \n");
+        goto opthelp;
+    }
+    if ((passin || passout) && argc != 1) {
+        BIO_printf(bio_err,
+                   "-passin, -passout arguments only valid with one user.\n");
+        goto opthelp;
+    }
+
+    if (!app_passwd(passinarg, passoutarg, &passin, &passout)) {
+        BIO_printf(bio_err, "Error getting passwords\n");
+        goto end;
+    }
+
+    if (!srpvfile) {
+        if (!configfile)
+            configfile = default_config_file;
+
+        if (verbose)
+            BIO_printf(bio_err, "Using configuration from %s\n",
+                       configfile);
+        conf = app_load_config(configfile);
+        if (conf == NULL)
+            goto end;
+        if (configfile != default_config_file && !app_load_modules(conf))
+            goto end;
+
+        /* Lets get the config section we are using */
+        if (section == NULL) {
+            if (verbose)
+                BIO_printf(bio_err,
+                           "trying to read " ENV_DEFAULT_SRP
+                           " in " BASE_SECTION "\n");
+
+            section = lookup_conf(conf, BASE_SECTION, ENV_DEFAULT_SRP);
+            if (section == NULL)
+                goto end;
+        }
+
+        if (randfile == NULL)
+            randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
+
+        if (verbose)
+            BIO_printf(bio_err,
+                       "trying to read " ENV_DATABASE " in section \"%s\"\n",
+                       section);
+
+        srpvfile = lookup_conf(conf, section, ENV_DATABASE);
+        if (srpvfile == NULL)
+            goto end;
+    }
+    if (randfile == NULL)
+        ERR_clear_error();
+    else
+        app_RAND_load_file(randfile, 0);
+
+    if (verbose)
+        BIO_printf(bio_err, "Trying to read SRP verifier file \"%s\"\n",
+                   srpvfile);
+
+    db = load_index(srpvfile, NULL);
+    if (db == NULL)
+        goto end;
+
+    /* Lets check some fields */
+    for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
+        pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
+
+        if (pp[DB_srptype][0] == DB_SRP_INDEX) {
+            maxgN = i;
+            if ((gNindex < 0) && (gN != NULL) && strcmp(gN, pp[DB_srpid]) == 0)
+                gNindex = i;
+
+            print_index(db, i, verbose > 1);
+        }
+    }
+
+    if (verbose)
+        BIO_printf(bio_err, "Database initialised\n");
+
+    if (gNindex >= 0) {
+        gNrow = sk_OPENSSL_PSTRING_value(db->db->data, gNindex);
+        print_entry(db, gNindex, verbose > 1, "Default g and N");
+    } else if (maxgN > 0 && !SRP_get_default_gN(gN)) {
+        BIO_printf(bio_err, "No g and N value for index \"%s\"\n", gN);
+        goto end;
+    } else {
+        if (verbose)
+            BIO_printf(bio_err, "Database has no g N information.\n");
+        gNrow = NULL;
+    }
+
+    if (verbose > 1)
+        BIO_printf(bio_err, "Starting user processing\n");
+
+    if (argc > 0)
+        user = *(argv++);
+
+    while (mode == OPT_LIST || user) {
+        int userindex = -1;
+
+        if (user != NULL && verbose > 1)
+            BIO_printf(bio_err, "Processing user \"%s\"\n", user);
+        if ((userindex = get_index(db, user, 'U')) >= 0) {
+            print_user(db, userindex, (verbose > 0) || mode == OPT_LIST);
+        }
+
+        if (mode == OPT_LIST) {
+            if (user == NULL) {
+                BIO_printf(bio_err, "List all users\n");
+
+                for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
+                    print_user(db, i, 1);
+                }
+            } else if (userindex < 0) {
+                BIO_printf(bio_err,
+                           "user \"%s\" does not exist, ignored. t\n", user);
+                errors++;
+            }
+        } else if (mode == OPT_ADD) {
+            if (userindex >= 0) {
+                /* reactivation of a new user */
+                char **row =
+                    sk_OPENSSL_PSTRING_value(db->db->data, userindex);
+                BIO_printf(bio_err, "user \"%s\" reactivated.\n", user);
+                row[DB_srptype][0] = 'V';
+
+                doupdatedb = 1;
+            } else {
+                char *row[DB_NUMBER];
+                char *gNid;
+                row[DB_srpverifier] = NULL;
+                row[DB_srpsalt] = NULL;
+                row[DB_srpinfo] = NULL;
+                if (!
+                    (gNid =
+                     srp_create_user(user, &(row[DB_srpverifier]),
+                                     &(row[DB_srpsalt]),
+                                     gNrow ? gNrow[DB_srpsalt] : gN,
+                                     gNrow ? gNrow[DB_srpverifier] : NULL,
+                                     passout, verbose))) {
+                    BIO_printf(bio_err,
+                               "Cannot create srp verifier for user \"%s\", operation abandoned .\n",
+                               user);
+                    errors++;
+                    goto end;
+                }
+                row[DB_srpid] = OPENSSL_strdup(user);
+                row[DB_srptype] = OPENSSL_strdup("v");
+                row[DB_srpgN] = OPENSSL_strdup(gNid);
+
+                if ((row[DB_srpid] == NULL)
+                    || (row[DB_srpgN] == NULL)
+                    || (row[DB_srptype] == NULL)
+                    || (row[DB_srpverifier] == NULL)
+                    || (row[DB_srpsalt] == NULL)
+                    || (userinfo
+                        && ((row[DB_srpinfo] = OPENSSL_strdup(userinfo)) == NULL))
+                    || !update_index(db, row)) {
+                    OPENSSL_free(row[DB_srpid]);
+                    OPENSSL_free(row[DB_srpgN]);
+                    OPENSSL_free(row[DB_srpinfo]);
+                    OPENSSL_free(row[DB_srptype]);
+                    OPENSSL_free(row[DB_srpverifier]);
+                    OPENSSL_free(row[DB_srpsalt]);
+                    goto end;
+                }
+                doupdatedb = 1;
+            }
+        } else if (mode == OPT_MODIFY) {
+            if (userindex < 0) {
+                BIO_printf(bio_err,
+                           "user \"%s\" does not exist, operation ignored.\n",
+                           user);
+                errors++;
+            } else {
+
+                char **row =
+                    sk_OPENSSL_PSTRING_value(db->db->data, userindex);
+                char type = row[DB_srptype][0];
+                if (type == 'v') {
+                    BIO_printf(bio_err,
+                               "user \"%s\" already updated, operation ignored.\n",
+                               user);
+                    errors++;
+                } else {
+                    char *gNid;
+
+                    if (row[DB_srptype][0] == 'V') {
+                        int user_gN;
+                        char **irow = NULL;
+                        if (verbose)
+                            BIO_printf(bio_err,
+                                       "Verifying password for user \"%s\"\n",
+                                       user);
+                        if ((user_gN =
+                             get_index(db, row[DB_srpgN], DB_SRP_INDEX)) >= 0)
+                            irow =
+                                sk_OPENSSL_PSTRING_value(db->db->data,
+                                                         userindex);
+
+                        if (!srp_verify_user
+                            (user, row[DB_srpverifier], row[DB_srpsalt],
+                             irow ? irow[DB_srpsalt] : row[DB_srpgN],
+                             irow ? irow[DB_srpverifier] : NULL, passin,
+                             verbose)) {
+                            BIO_printf(bio_err,
+                                       "Invalid password for user \"%s\", operation abandoned.\n",
+                                       user);
+                            errors++;
+                            goto end;
+                        }
+                    }
+                    if (verbose)
+                        BIO_printf(bio_err, "Password for user \"%s\" ok.\n",
+                                   user);
+
+                    if (!
+                        (gNid =
+                         srp_create_user(user, &(row[DB_srpverifier]),
+                                         &(row[DB_srpsalt]),
+                                         gNrow ? gNrow[DB_srpsalt] : NULL,
+                                         gNrow ? gNrow[DB_srpverifier] : NULL,
+                                         passout, verbose))) {
+                        BIO_printf(bio_err,
+                                   "Cannot create srp verifier for user \"%s\", operation abandoned.\n",
+                                   user);
+                        errors++;
+                        goto end;
+                    }
+
+                    row[DB_srptype][0] = 'v';
+                    row[DB_srpgN] = OPENSSL_strdup(gNid);
+
+                    if (row[DB_srpid] == NULL
+                        || row[DB_srpgN] == NULL
+                        || row[DB_srptype] == NULL
+                        || row[DB_srpverifier] == NULL
+                        || row[DB_srpsalt] == NULL
+                        || (userinfo
+                            && ((row[DB_srpinfo] = OPENSSL_strdup(userinfo))
+                                == NULL)))
+                        goto end;
+
+                    doupdatedb = 1;
+                }
+            }
+        } else if (mode == OPT_DELETE) {
+            if (userindex < 0) {
+                BIO_printf(bio_err,
+                           "user \"%s\" does not exist, operation ignored. t\n",
+                           user);
+                errors++;
+            } else {
+                char **xpp = sk_OPENSSL_PSTRING_value(db->db->data, userindex);
+
+                BIO_printf(bio_err, "user \"%s\" revoked. t\n", user);
+                xpp[DB_srptype][0] = 'R';
+                doupdatedb = 1;
+            }
+        }
+        if (--argc > 0)
+            user = *(argv++);
+        else {
+            user = NULL;
+        }
+    }
+
+    if (verbose)
+        BIO_printf(bio_err, "User procession done.\n");
+
+    if (doupdatedb) {
+        /* Lets check some fields */
+        for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
+            pp = sk_OPENSSL_PSTRING_value(db->db->data, i);
+
+            if (pp[DB_srptype][0] == 'v') {
+                pp[DB_srptype][0] = 'V';
+                print_user(db, i, verbose);
+            }
+        }
+
+        if (verbose)
+            BIO_printf(bio_err, "Trying to update srpvfile.\n");
+        if (!save_index(srpvfile, "new", db))
+            goto end;
+
+        if (verbose)
+            BIO_printf(bio_err, "Temporary srpvfile created.\n");
+        if (!rotate_index(srpvfile, "new", "old"))
+            goto end;
+
+        if (verbose)
+            BIO_printf(bio_err, "srpvfile updated.\n");
+    }
+
+    ret = (errors != 0);
+ end:
+    if (errors != 0)
+        if (verbose)
+            BIO_printf(bio_err, "User errors %d.\n", errors);
+
+    if (verbose)
+        BIO_printf(bio_err, "SRP terminating with code %d.\n", ret);
+
+    OPENSSL_free(passin);
+    OPENSSL_free(passout);
+    if (ret)
+        ERR_print_errors(bio_err);
+    if (randfile)
+        app_RAND_write_file(randfile);
+    NCONF_free(conf);
+    free_index(db);
+    release_engine(e);
+    return (ret);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/testdsa.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/testdsa.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/testdsa.h	(revision 331)
@@ -0,0 +1,290 @@
+/*
+ * Copyright 1998-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
+ */
+
+/* used by speed.c */
+DSA *get_dsa512(void);
+DSA *get_dsa1024(void);
+DSA *get_dsa2048(void);
+
+static unsigned char dsa512_priv[] = {
+    0x65, 0xe5, 0xc7, 0x38, 0x60, 0x24, 0xb5, 0x89, 0xd4, 0x9c, 0xeb, 0x4c,
+    0x9c, 0x1d, 0x7a, 0x22, 0xbd, 0xd1, 0xc2, 0xd2,
+};
+
+static unsigned char dsa512_pub[] = {
+    0x00, 0x95, 0xa7, 0x0d, 0xec, 0x93, 0x68, 0xba, 0x5f, 0xf7, 0x5f, 0x07,
+    0xf2, 0x3b, 0xad, 0x6b, 0x01, 0xdc, 0xbe, 0xec, 0xde, 0x04, 0x7a, 0x3a,
+    0x27, 0xb3, 0xec, 0x49, 0xfd, 0x08, 0x43, 0x3d, 0x7e, 0xa8, 0x2c, 0x5e,
+    0x7b, 0xbb, 0xfc, 0xf4, 0x6e, 0xeb, 0x6c, 0xb0, 0x6e, 0xf8, 0x02, 0x12,
+    0x8c, 0x38, 0x5d, 0x83, 0x56, 0x7d, 0xee, 0x53, 0x05, 0x3e, 0x24, 0x84,
+    0xbe, 0xba, 0x0a, 0x6b, 0xc8,
+};
+
+static unsigned char dsa512_p[] = {
+    0x9D, 0x1B, 0x69, 0x8E, 0x26, 0xDB, 0xF2, 0x2B, 0x11, 0x70, 0x19, 0x86,
+    0xF6, 0x19, 0xC8, 0xF8, 0x19, 0xF2, 0x18, 0x53, 0x94, 0x46, 0x06, 0xD0,
+    0x62, 0x50, 0x33, 0x4B, 0x02, 0x3C, 0x52, 0x30, 0x03, 0x8B, 0x3B, 0xF9,
+    0x5F, 0xD1, 0x24, 0x06, 0x4F, 0x7B, 0x4C, 0xBA, 0xAA, 0x40, 0x9B, 0xFD,
+    0x96, 0xE4, 0x37, 0x33, 0xBB, 0x2D, 0x5A, 0xD7, 0x5A, 0x11, 0x40, 0x66,
+    0xA2, 0x76, 0x7D, 0x31,
+};
+
+static unsigned char dsa512_q[] = {
+    0xFB, 0x53, 0xEF, 0x50, 0xB4, 0x40, 0x92, 0x31, 0x56, 0x86, 0x53, 0x7A,
+    0xE8, 0x8B, 0x22, 0x9A, 0x49, 0xFB, 0x71, 0x8F,
+};
+
+static unsigned char dsa512_g[] = {
+    0x83, 0x3E, 0x88, 0xE5, 0xC5, 0x89, 0x73, 0xCE, 0x3B, 0x6C, 0x01, 0x49,
+    0xBF, 0xB3, 0xC7, 0x9F, 0x0A, 0xEA, 0x44, 0x91, 0xE5, 0x30, 0xAA, 0xD9,
+    0xBE, 0x5B, 0x5F, 0xB7, 0x10, 0xD7, 0x89, 0xB7, 0x8E, 0x74, 0xFB, 0xCF,
+    0x29, 0x1E, 0xEB, 0xA8, 0x2C, 0x54, 0x51, 0xB8, 0x10, 0xDE, 0xA0, 0xCE,
+    0x2F, 0xCC, 0x24, 0x6B, 0x90, 0x77, 0xDE, 0xA2, 0x68, 0xA6, 0x52, 0x12,
+    0xA2, 0x03, 0x9D, 0x20,
+};
+
+DSA *get_dsa512()
+{
+    DSA *dsa;
+    BIGNUM *priv_key, *pub_key, *p, *q, *g;
+
+    if ((dsa = DSA_new()) == NULL)
+        return (NULL);
+    priv_key = BN_bin2bn(dsa512_priv, sizeof(dsa512_priv), NULL);
+    pub_key = BN_bin2bn(dsa512_pub, sizeof(dsa512_pub), NULL);
+    p = BN_bin2bn(dsa512_p, sizeof(dsa512_p), NULL);
+    q = BN_bin2bn(dsa512_q, sizeof(dsa512_q), NULL);
+    g = BN_bin2bn(dsa512_g, sizeof(dsa512_g), NULL);
+    if ((priv_key == NULL) || (pub_key == NULL) || (p == NULL) || (q == NULL)
+            || (g == NULL)) {
+        goto err;
+    }
+    if (!DSA_set0_pqg(dsa, p, q, g))
+        goto err;
+    p = q = g = NULL;
+
+    if (!DSA_set0_key(dsa, pub_key, priv_key))
+        goto err;
+
+    return dsa;
+ err:
+    DSA_free(dsa);
+    BN_free(priv_key);
+    BN_free(pub_key);
+    BN_free(p);
+    BN_free(q);
+    BN_free(g);
+    return NULL;
+}
+
+static unsigned char dsa1024_priv[] = {
+    0x7d, 0x21, 0xda, 0xbb, 0x62, 0x15, 0x47, 0x36, 0x07, 0x67, 0x12, 0xe8,
+    0x8c, 0xaa, 0x1c, 0xcd, 0x38, 0x12, 0x61, 0x18,
+};
+
+static unsigned char dsa1024_pub[] = {
+    0x3c, 0x4e, 0x9c, 0x2a, 0x7f, 0x16, 0xc1, 0x25, 0xeb, 0xac, 0x78, 0x63,
+    0x90, 0x14, 0x8c, 0x8b, 0xf4, 0x68, 0x43, 0x3c, 0x2d, 0xee, 0x65, 0x50,
+    0x7d, 0x9c, 0x8f, 0x8c, 0x8a, 0x51, 0xd6, 0x11, 0x2b, 0x99, 0xaf, 0x1e,
+    0x90, 0x97, 0xb5, 0xd3, 0xa6, 0x20, 0x25, 0xd6, 0xfe, 0x43, 0x02, 0xd5,
+    0x91, 0x7d, 0xa7, 0x8c, 0xdb, 0xc9, 0x85, 0xa3, 0x36, 0x48, 0xf7, 0x68,
+    0xaa, 0x60, 0xb1, 0xf7, 0x05, 0x68, 0x3a, 0xa3, 0x3f, 0xd3, 0x19, 0x82,
+    0xd8, 0x82, 0x7a, 0x77, 0xfb, 0xef, 0xf4, 0x15, 0x0a, 0xeb, 0x06, 0x04,
+    0x7f, 0x53, 0x07, 0x0c, 0xbc, 0xcb, 0x2d, 0x83, 0xdb, 0x3e, 0xd1, 0x28,
+    0xa5, 0xa1, 0x31, 0xe0, 0x67, 0xfa, 0x50, 0xde, 0x9b, 0x07, 0x83, 0x7e,
+    0x2c, 0x0b, 0xc3, 0x13, 0x50, 0x61, 0xe5, 0xad, 0xbd, 0x36, 0xb8, 0x97,
+    0x4e, 0x40, 0x7d, 0xe8, 0x83, 0x0d, 0xbc, 0x4b
+};
+
+static unsigned char dsa1024_p[] = {
+    0xA7, 0x3F, 0x6E, 0x85, 0xBF, 0x41, 0x6A, 0x29, 0x7D, 0xF0, 0x9F, 0x47,
+    0x19, 0x30, 0x90, 0x9A, 0x09, 0x1D, 0xDA, 0x6A, 0x33, 0x1E, 0xC5, 0x3D,
+    0x86, 0x96, 0xB3, 0x15, 0xE0, 0x53, 0x2E, 0x8F, 0xE0, 0x59, 0x82, 0x73,
+    0x90, 0x3E, 0x75, 0x31, 0x99, 0x47, 0x7A, 0x52, 0xFB, 0x85, 0xE4, 0xD9,
+    0xA6, 0x7B, 0x38, 0x9B, 0x68, 0x8A, 0x84, 0x9B, 0x87, 0xC6, 0x1E, 0xB5,
+    0x7E, 0x86, 0x4B, 0x53, 0x5B, 0x59, 0xCF, 0x71, 0x65, 0x19, 0x88, 0x6E,
+    0xCE, 0x66, 0xAE, 0x6B, 0x88, 0x36, 0xFB, 0xEC, 0x28, 0xDC, 0xC2, 0xD7,
+    0xA5, 0xBB, 0xE5, 0x2C, 0x39, 0x26, 0x4B, 0xDA, 0x9A, 0x70, 0x18, 0x95,
+    0x37, 0x95, 0x10, 0x56, 0x23, 0xF6, 0x15, 0xED, 0xBA, 0x04, 0x5E, 0xDE,
+    0x39, 0x4F, 0xFD, 0xB7, 0x43, 0x1F, 0xB5, 0xA4, 0x65, 0x6F, 0xCD, 0x80,
+    0x11, 0xE4, 0x70, 0x95, 0x5B, 0x50, 0xCD, 0x49,
+};
+
+static unsigned char dsa1024_q[] = {
+    0xF7, 0x07, 0x31, 0xED, 0xFA, 0x6C, 0x06, 0x03, 0xD5, 0x85, 0x8A, 0x1C,
+    0xAC, 0x9C, 0x65, 0xE7, 0x50, 0x66, 0x65, 0x6F,
+};
+
+static unsigned char dsa1024_g[] = {
+    0x4D, 0xDF, 0x4C, 0x03, 0xA6, 0x91, 0x8A, 0xF5, 0x19, 0x6F, 0x50, 0x46,
+    0x25, 0x99, 0xE5, 0x68, 0x6F, 0x30, 0xE3, 0x69, 0xE1, 0xE5, 0xB3, 0x5D,
+    0x98, 0xBB, 0x28, 0x86, 0x48, 0xFC, 0xDE, 0x99, 0x04, 0x3F, 0x5F, 0x88,
+    0x0C, 0x9C, 0x73, 0x24, 0x0D, 0x20, 0x5D, 0xB9, 0x2A, 0x9A, 0x3F, 0x18,
+    0x96, 0x27, 0xE4, 0x62, 0x87, 0xC1, 0x7B, 0x74, 0x62, 0x53, 0xFC, 0x61,
+    0x27, 0xA8, 0x7A, 0x91, 0x09, 0x9D, 0xB6, 0xF1, 0x4D, 0x9C, 0x54, 0x0F,
+    0x58, 0x06, 0xEE, 0x49, 0x74, 0x07, 0xCE, 0x55, 0x7E, 0x23, 0xCE, 0x16,
+    0xF6, 0xCA, 0xDC, 0x5A, 0x61, 0x01, 0x7E, 0xC9, 0x71, 0xB5, 0x4D, 0xF6,
+    0xDC, 0x34, 0x29, 0x87, 0x68, 0xF6, 0x5E, 0x20, 0x93, 0xB3, 0xDB, 0xF5,
+    0xE4, 0x09, 0x6C, 0x41, 0x17, 0x95, 0x92, 0xEB, 0x01, 0xB5, 0x73, 0xA5,
+    0x6A, 0x7E, 0xD8, 0x32, 0xED, 0x0E, 0x02, 0xB8,
+};
+
+DSA *get_dsa1024()
+{
+    DSA *dsa;
+    BIGNUM *priv_key, *pub_key, *p, *q, *g;
+
+    if ((dsa = DSA_new()) == NULL)
+        return (NULL);
+    priv_key = BN_bin2bn(dsa1024_priv, sizeof(dsa1024_priv), NULL);
+    pub_key = BN_bin2bn(dsa1024_pub, sizeof(dsa1024_pub), NULL);
+    p = BN_bin2bn(dsa1024_p, sizeof(dsa1024_p), NULL);
+    q = BN_bin2bn(dsa1024_q, sizeof(dsa1024_q), NULL);
+    g = BN_bin2bn(dsa1024_g, sizeof(dsa1024_g), NULL);
+    if ((priv_key == NULL) || (pub_key == NULL) || (p == NULL) || (q == NULL)
+            || (g == NULL)) {
+        goto err;
+    }
+    if (!DSA_set0_pqg(dsa, p, q, g))
+        goto err;
+    p = q = g = NULL;
+
+    if (!DSA_set0_key(dsa, pub_key, priv_key))
+        goto err;
+
+    return dsa;
+ err:
+    DSA_free(dsa);
+    BN_free(priv_key);
+    BN_free(pub_key);
+    BN_free(p);
+    BN_free(q);
+    BN_free(g);
+    return NULL;
+}
+
+static unsigned char dsa2048_priv[] = {
+    0x32, 0x67, 0x92, 0xf6, 0xc4, 0xe2, 0xe2, 0xe8, 0xa0, 0x8b, 0x6b, 0x45,
+    0x0c, 0x8a, 0x76, 0xb0, 0xee, 0xcf, 0x91, 0xa7,
+};
+
+static unsigned char dsa2048_pub[] = {
+    0x17, 0x8f, 0xa8, 0x11, 0x84, 0x92, 0xec, 0x83, 0x47, 0xc7, 0x6a, 0xb0,
+    0x92, 0xaf, 0x5a, 0x20, 0x37, 0xa3, 0x64, 0x79, 0xd2, 0xd0, 0x3d, 0xcd,
+    0xe0, 0x61, 0x88, 0x88, 0x21, 0xcc, 0x74, 0x5d, 0xce, 0x4c, 0x51, 0x47,
+    0xf0, 0xc5, 0x5c, 0x4c, 0x82, 0x7a, 0xaf, 0x72, 0xad, 0xb9, 0xe0, 0x53,
+    0xf2, 0x78, 0xb7, 0xf0, 0xb5, 0x48, 0x7f, 0x8a, 0x3a, 0x18, 0xd1, 0x9f,
+    0x8b, 0x7d, 0xa5, 0x47, 0xb7, 0x95, 0xab, 0x98, 0xf8, 0x7b, 0x74, 0x50,
+    0x56, 0x8e, 0x57, 0xf0, 0xee, 0xf5, 0xb7, 0xba, 0xab, 0x85, 0x86, 0xf9,
+    0x2b, 0xef, 0x41, 0x56, 0xa0, 0xa4, 0x9f, 0xb7, 0x38, 0x00, 0x46, 0x0a,
+    0xa6, 0xf1, 0xfc, 0x1f, 0xd8, 0x4e, 0x85, 0x44, 0x92, 0x43, 0x21, 0x5d,
+    0x6e, 0xcc, 0xc2, 0xcb, 0x26, 0x31, 0x0d, 0x21, 0xc4, 0xbd, 0x8d, 0x24,
+    0xbc, 0xd9, 0x18, 0x19, 0xd7, 0xdc, 0xf1, 0xe7, 0x93, 0x50, 0x48, 0x03,
+    0x2c, 0xae, 0x2e, 0xe7, 0x49, 0x88, 0x5f, 0x93, 0x57, 0x27, 0x99, 0x36,
+    0xb4, 0x20, 0xab, 0xfc, 0xa7, 0x2b, 0xf2, 0xd9, 0x98, 0xd7, 0xd4, 0x34,
+    0x9d, 0x96, 0x50, 0x58, 0x9a, 0xea, 0x54, 0xf3, 0xee, 0xf5, 0x63, 0x14,
+    0xee, 0x85, 0x83, 0x74, 0x76, 0xe1, 0x52, 0x95, 0xc3, 0xf7, 0xeb, 0x04,
+    0x04, 0x7b, 0xa7, 0x28, 0x1b, 0xcc, 0xea, 0x4a, 0x4e, 0x84, 0xda, 0xd8,
+    0x9c, 0x79, 0xd8, 0x9b, 0x66, 0x89, 0x2f, 0xcf, 0xac, 0xd7, 0x79, 0xf9,
+    0xa9, 0xd8, 0x45, 0x13, 0x78, 0xb9, 0x00, 0x14, 0xc9, 0x7e, 0x22, 0x51,
+    0x86, 0x67, 0xb0, 0x9f, 0x26, 0x11, 0x23, 0xc8, 0x38, 0xd7, 0x70, 0x1d,
+    0x15, 0x8e, 0x4d, 0x4f, 0x95, 0x97, 0x40, 0xa1, 0xc2, 0x7e, 0x01, 0x18,
+    0x72, 0xf4, 0x10, 0xe6, 0x8d, 0x52, 0x16, 0x7f, 0xf2, 0xc9, 0xf8, 0x33,
+    0x8b, 0x33, 0xb7, 0xce,
+};
+
+static unsigned char dsa2048_p[] = {
+    0xA0, 0x25, 0xFA, 0xAD, 0xF4, 0x8E, 0xB9, 0xE5, 0x99, 0xF3, 0x5D, 0x6F,
+    0x4F, 0x83, 0x34, 0xE2, 0x7E, 0xCF, 0x6F, 0xBF, 0x30, 0xAF, 0x6F, 0x81,
+    0xEB, 0xF8, 0xC4, 0x13, 0xD9, 0xA0, 0x5D, 0x8B, 0x5C, 0x8E, 0xDC, 0xC2,
+    0x1D, 0x0B, 0x41, 0x32, 0xB0, 0x1F, 0xFE, 0xEF, 0x0C, 0xC2, 0xA2, 0x7E,
+    0x68, 0x5C, 0x28, 0x21, 0xE9, 0xF5, 0xB1, 0x58, 0x12, 0x63, 0x4C, 0x19,
+    0x4E, 0xFF, 0x02, 0x4B, 0x92, 0xED, 0xD2, 0x07, 0x11, 0x4D, 0x8C, 0x58,
+    0x16, 0x5C, 0x55, 0x8E, 0xAD, 0xA3, 0x67, 0x7D, 0xB9, 0x86, 0x6E, 0x0B,
+    0xE6, 0x54, 0x6F, 0x40, 0xAE, 0x0E, 0x67, 0x4C, 0xF9, 0x12, 0x5B, 0x3C,
+    0x08, 0x7A, 0xF7, 0xFC, 0x67, 0x86, 0x69, 0xE7, 0x0A, 0x94, 0x40, 0xBF,
+    0x8B, 0x76, 0xFE, 0x26, 0xD1, 0xF2, 0xA1, 0x1A, 0x84, 0xA1, 0x43, 0x56,
+    0x28, 0xBC, 0x9A, 0x5F, 0xD7, 0x3B, 0x69, 0x89, 0x8A, 0x36, 0x2C, 0x51,
+    0xDF, 0x12, 0x77, 0x2F, 0x57, 0x7B, 0xA0, 0xAA, 0xDD, 0x7F, 0xA1, 0x62,
+    0x3B, 0x40, 0x7B, 0x68, 0x1A, 0x8F, 0x0D, 0x38, 0xBB, 0x21, 0x5D, 0x18,
+    0xFC, 0x0F, 0x46, 0xF7, 0xA3, 0xB0, 0x1D, 0x23, 0xC3, 0xD2, 0xC7, 0x72,
+    0x51, 0x18, 0xDF, 0x46, 0x95, 0x79, 0xD9, 0xBD, 0xB5, 0x19, 0x02, 0x2C,
+    0x87, 0xDC, 0xE7, 0x57, 0x82, 0x7E, 0xF1, 0x8B, 0x06, 0x3D, 0x00, 0xA5,
+    0x7B, 0x6B, 0x26, 0x27, 0x91, 0x0F, 0x6A, 0x77, 0xE4, 0xD5, 0x04, 0xE4,
+    0x12, 0x2C, 0x42, 0xFF, 0xD2, 0x88, 0xBB, 0xD3, 0x92, 0xA0, 0xF9, 0xC8,
+    0x51, 0x64, 0x14, 0x5C, 0xD8, 0xF9, 0x6C, 0x47, 0x82, 0xB4, 0x1C, 0x7F,
+    0x09, 0xB8, 0xF0, 0x25, 0x83, 0x1D, 0x3F, 0x3F, 0x05, 0xB3, 0x21, 0x0A,
+    0x5D, 0xA7, 0xD8, 0x54, 0xC3, 0x65, 0x7D, 0xC3, 0xB0, 0x1D, 0xBF, 0xAE,
+    0xF8, 0x68, 0xCF, 0x9B,
+};
+
+static unsigned char dsa2048_q[] = {
+    0x97, 0xE7, 0x33, 0x4D, 0xD3, 0x94, 0x3E, 0x0B, 0xDB, 0x62, 0x74, 0xC6,
+    0xA1, 0x08, 0xDD, 0x19, 0xA3, 0x75, 0x17, 0x1B,
+};
+
+static unsigned char dsa2048_g[] = {
+    0x2C, 0x78, 0x16, 0x59, 0x34, 0x63, 0xF4, 0xF3, 0x92, 0xFC, 0xB5, 0xA5,
+    0x4F, 0x13, 0xDE, 0x2F, 0x1C, 0xA4, 0x3C, 0xAE, 0xAD, 0x38, 0x3F, 0x7E,
+    0x90, 0xBF, 0x96, 0xA6, 0xAE, 0x25, 0x90, 0x72, 0xF5, 0x8E, 0x80, 0x0C,
+    0x39, 0x1C, 0xD9, 0xEC, 0xBA, 0x90, 0x5B, 0x3A, 0xE8, 0x58, 0x6C, 0x9E,
+    0x30, 0x42, 0x37, 0x02, 0x31, 0x82, 0xBC, 0x6A, 0xDF, 0x6A, 0x09, 0x29,
+    0xE3, 0xC0, 0x46, 0xD1, 0xCB, 0x85, 0xEC, 0x0C, 0x30, 0x5E, 0xEA, 0xC8,
+    0x39, 0x8E, 0x22, 0x9F, 0x22, 0x10, 0xD2, 0x34, 0x61, 0x68, 0x37, 0x3D,
+    0x2E, 0x4A, 0x5B, 0x9A, 0xF5, 0xC1, 0x48, 0xC6, 0xF6, 0xDC, 0x63, 0x1A,
+    0xD3, 0x96, 0x64, 0xBA, 0x34, 0xC9, 0xD1, 0xA0, 0xD1, 0xAE, 0x6C, 0x2F,
+    0x48, 0x17, 0x93, 0x14, 0x43, 0xED, 0xF0, 0x21, 0x30, 0x19, 0xC3, 0x1B,
+    0x5F, 0xDE, 0xA3, 0xF0, 0x70, 0x78, 0x18, 0xE1, 0xA8, 0xE4, 0xEE, 0x2E,
+    0x00, 0xA5, 0xE4, 0xB3, 0x17, 0xC8, 0x0C, 0x7D, 0x6E, 0x42, 0xDC, 0xB7,
+    0x46, 0x00, 0x36, 0x4D, 0xD4, 0x46, 0xAA, 0x3D, 0x3C, 0x46, 0x89, 0x40,
+    0xBF, 0x1D, 0x84, 0x77, 0x0A, 0x75, 0xF3, 0x87, 0x1D, 0x08, 0x4C, 0xA6,
+    0xD1, 0xA9, 0x1C, 0x1E, 0x12, 0x1E, 0xE1, 0xC7, 0x30, 0x28, 0x76, 0xA5,
+    0x7F, 0x6C, 0x85, 0x96, 0x2B, 0x6F, 0xDB, 0x80, 0x66, 0x26, 0xAE, 0xF5,
+    0x93, 0xC7, 0x8E, 0xAE, 0x9A, 0xED, 0xE4, 0xCA, 0x04, 0xEA, 0x3B, 0x72,
+    0xEF, 0xDC, 0x87, 0xED, 0x0D, 0xA5, 0x4C, 0x4A, 0xDD, 0x71, 0x22, 0x64,
+    0x59, 0x69, 0x4E, 0x8E, 0xBF, 0x43, 0xDC, 0xAB, 0x8E, 0x66, 0xBB, 0x01,
+    0xB6, 0xF4, 0xE7, 0xFD, 0xD2, 0xAD, 0x9F, 0x36, 0xC1, 0xA0, 0x29, 0x99,
+    0xD1, 0x96, 0x70, 0x59, 0x06, 0x78, 0x35, 0xBD, 0x65, 0x55, 0x52, 0x9E,
+    0xF8, 0xB2, 0xE5, 0x38,
+};
+
+DSA *get_dsa2048()
+{
+    DSA *dsa;
+    BIGNUM *priv_key, *pub_key, *p, *q, *g;
+
+    if ((dsa = DSA_new()) == NULL)
+        return (NULL);
+    priv_key = BN_bin2bn(dsa2048_priv, sizeof(dsa2048_priv), NULL);
+    pub_key = BN_bin2bn(dsa2048_pub, sizeof(dsa2048_pub), NULL);
+    p = BN_bin2bn(dsa2048_p, sizeof(dsa2048_p), NULL);
+    q = BN_bin2bn(dsa2048_q, sizeof(dsa2048_q), NULL);
+    g = BN_bin2bn(dsa2048_g, sizeof(dsa2048_g), NULL);
+    if ((priv_key == NULL) || (pub_key == NULL) || (p == NULL) || (q == NULL)
+            || (g == NULL)) {
+        goto err;
+    }
+    if (!DSA_set0_pqg(dsa, p, q, g))
+        goto err;
+    p = q = g = NULL;
+
+    if (!DSA_set0_key(dsa, pub_key, priv_key))
+        goto err;
+
+    return dsa;
+ err:
+    DSA_free(dsa);
+    BN_free(priv_key);
+    BN_free(pub_key);
+    BN_free(p);
+    BN_free(q);
+    BN_free(g);
+    return NULL;
+}
+
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/testrsa.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/testrsa.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/testrsa.h	(revision 331)
@@ -0,0 +1,1960 @@
+/*
+ * Copyright 1995-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
+ */
+
+static unsigned char test512[] = {
+    0x30, 0x82, 0x01, 0x3a, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00,
+    0xd6, 0x33, 0xb9, 0xc8, 0xfb, 0x4f, 0x3c, 0x7d, 0xc0, 0x01,
+    0x86, 0xd0, 0xe7, 0xa0, 0x55, 0xf2, 0x95, 0x93, 0xcc, 0x4f,
+    0xb7, 0x5b, 0x67, 0x5b, 0x94, 0x68, 0xc9, 0x34, 0x15, 0xde,
+    0xa5, 0x2e, 0x1c, 0x33, 0xc2, 0x6e, 0xfc, 0x34, 0x5e, 0x71,
+    0x13, 0xb7, 0xd6, 0xee, 0xd8, 0xa5, 0x65, 0x05, 0x72, 0x87,
+    0xa8, 0xb0, 0x77, 0xfe, 0x57, 0xf5, 0xfc, 0x5f, 0x55, 0x83,
+    0x87, 0xdd, 0x57, 0x49, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
+    0x41, 0x00, 0xa7, 0xf7, 0x91, 0xc5, 0x0f, 0x84, 0x57, 0xdc,
+    0x07, 0xf7, 0x6a, 0x7f, 0x60, 0x52, 0xb3, 0x72, 0xf1, 0x66,
+    0x1f, 0x7d, 0x97, 0x3b, 0x9e, 0xb6, 0x0a, 0x8f, 0x8c, 0xcf,
+    0x42, 0x23, 0x00, 0x04, 0xd4, 0x28, 0x0e, 0x1c, 0x90, 0xc4,
+    0x11, 0x25, 0x25, 0xa5, 0x93, 0xa5, 0x2f, 0x70, 0x02, 0xdf,
+    0x81, 0x9c, 0x49, 0x03, 0xa0, 0xf8, 0x6d, 0x54, 0x2e, 0x26,
+    0xde, 0xaa, 0x85, 0x59, 0xa8, 0x31, 0x02, 0x21, 0x00, 0xeb,
+    0x47, 0xd7, 0x3b, 0xf6, 0xc3, 0xdd, 0x5a, 0x46, 0xc5, 0xb9,
+    0x2b, 0x9a, 0xa0, 0x09, 0x8f, 0xa6, 0xfb, 0xf3, 0x78, 0x7a,
+    0x33, 0x70, 0x9d, 0x0f, 0x42, 0x6b, 0x13, 0x68, 0x24, 0xd3,
+    0x15, 0x02, 0x21, 0x00, 0xe9, 0x10, 0xb0, 0xb3, 0x0d, 0xe2,
+    0x82, 0x68, 0x77, 0x8a, 0x6e, 0x7c, 0xda, 0xbc, 0x3e, 0x53,
+    0x83, 0xfb, 0xd6, 0x22, 0xe7, 0xb5, 0xae, 0x6e, 0x80, 0xda,
+    0x00, 0x55, 0x97, 0xc1, 0xd0, 0x65, 0x02, 0x20, 0x4c, 0xf8,
+    0x73, 0xb1, 0x6a, 0x49, 0x29, 0x61, 0x1f, 0x46, 0x10, 0x0d,
+    0xf3, 0xc7, 0xe7, 0x58, 0xd7, 0x88, 0x15, 0x5e, 0x94, 0x9b,
+    0xbf, 0x7b, 0xa2, 0x42, 0x58, 0x45, 0x41, 0x0c, 0xcb, 0x01,
+    0x02, 0x20, 0x12, 0x11, 0xba, 0x31, 0x57, 0x9d, 0x3d, 0x11,
+    0x0e, 0x5b, 0x8c, 0x2f, 0x5f, 0xe2, 0x02, 0x4f, 0x05, 0x47,
+    0x8c, 0x15, 0x8e, 0xb3, 0x56, 0x3f, 0xb8, 0xfb, 0xad, 0xd4,
+    0xf4, 0xfc, 0x10, 0xc5, 0x02, 0x20, 0x18, 0xa1, 0x29, 0x99,
+    0x5b, 0xd9, 0xc8, 0xd4, 0xfc, 0x49, 0x7a, 0x2a, 0x21, 0x2c,
+    0x49, 0xe4, 0x4f, 0xeb, 0xef, 0x51, 0xf1, 0xab, 0x6d, 0xfb,
+    0x4b, 0x14, 0xe9, 0x4b, 0x52, 0xb5, 0x82, 0x2c,
+};
+
+static unsigned char test1024[] = {
+    0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81,
+    0x00, 0xdc, 0x98, 0x43, 0xe8, 0x3d, 0x43, 0x5b, 0xe4, 0x05,
+    0xcd, 0xd0, 0xa9, 0x3e, 0xcb, 0x83, 0x75, 0xf6, 0xb5, 0xa5,
+    0x9f, 0x6b, 0xe9, 0x34, 0x41, 0x29, 0x18, 0xfa, 0x6a, 0x55,
+    0x4d, 0x70, 0xfc, 0xec, 0xae, 0x87, 0x38, 0x0a, 0x20, 0xa9,
+    0xc0, 0x45, 0x77, 0x6e, 0x57, 0x60, 0x57, 0xf4, 0xed, 0x96,
+    0x22, 0xcb, 0x8f, 0xe1, 0x33, 0x3a, 0x17, 0x1f, 0xed, 0x37,
+    0xa5, 0x6f, 0xeb, 0xa6, 0xbc, 0x12, 0x80, 0x1d, 0x53, 0xbd,
+    0x70, 0xeb, 0x21, 0x76, 0x3e, 0xc9, 0x2f, 0x1a, 0x45, 0x24,
+    0x82, 0xff, 0xcd, 0x59, 0x32, 0x06, 0x2e, 0x12, 0x3b, 0x23,
+    0x78, 0xed, 0x12, 0x3d, 0xe0, 0x8d, 0xf9, 0x67, 0x4f, 0x37,
+    0x4e, 0x47, 0x02, 0x4c, 0x2d, 0xc0, 0x4f, 0x1f, 0xb3, 0x94,
+    0xe1, 0x41, 0x2e, 0x2d, 0x90, 0x10, 0xfc, 0x82, 0x91, 0x8b,
+    0x0f, 0x22, 0xd4, 0xf2, 0xfc, 0x2c, 0xab, 0x53, 0x55, 0x02,
+    0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x2b, 0xcc, 0x3f,
+    0x8f, 0x58, 0xba, 0x8b, 0x00, 0x16, 0xf6, 0xea, 0x3a, 0xf0,
+    0x30, 0xd0, 0x05, 0x17, 0xda, 0xb0, 0xeb, 0x9a, 0x2d, 0x4f,
+    0x26, 0xb0, 0xd6, 0x38, 0xc1, 0xeb, 0xf5, 0xd8, 0x3d, 0x1f,
+    0x70, 0xf7, 0x7f, 0xf4, 0xe2, 0xcf, 0x51, 0x51, 0x79, 0x88,
+    0xfa, 0xe8, 0x32, 0x0e, 0x7b, 0x2d, 0x97, 0xf2, 0xfa, 0xba,
+    0x27, 0xc5, 0x9c, 0xd9, 0xc5, 0xeb, 0x8a, 0x79, 0x52, 0x3c,
+    0x64, 0x34, 0x7d, 0xc2, 0xcf, 0x28, 0xc7, 0x4e, 0xd5, 0x43,
+    0x0b, 0xd1, 0xa6, 0xca, 0x6d, 0x03, 0x2d, 0x72, 0x23, 0xbc,
+    0x6d, 0x05, 0xfa, 0x16, 0x09, 0x2f, 0x2e, 0x5c, 0xb6, 0xee,
+    0x74, 0xdd, 0xd2, 0x48, 0x8e, 0x36, 0x0c, 0x06, 0x3d, 0x4d,
+    0xe5, 0x10, 0x82, 0xeb, 0x6a, 0xf3, 0x4b, 0x9f, 0xd6, 0xed,
+    0x11, 0xb1, 0x6e, 0xec, 0xf4, 0xfe, 0x8e, 0x75, 0x94, 0x20,
+    0x2f, 0xcb, 0xac, 0x46, 0xf1, 0x02, 0x41, 0x00, 0xf9, 0x8c,
+    0xa3, 0x85, 0xb1, 0xdd, 0x29, 0xaf, 0x65, 0xc1, 0x33, 0xf3,
+    0x95, 0xc5, 0x52, 0x68, 0x0b, 0xd4, 0xf1, 0xe5, 0x0e, 0x02,
+    0x9f, 0x4f, 0xfa, 0x77, 0xdc, 0x46, 0x9e, 0xc7, 0xa6, 0xe4,
+    0x16, 0x29, 0xda, 0xb0, 0x07, 0xcf, 0x5b, 0xa9, 0x12, 0x8a,
+    0xdd, 0x63, 0x0a, 0xde, 0x2e, 0x8c, 0x66, 0x8b, 0x8c, 0xdc,
+    0x19, 0xa3, 0x7e, 0xf4, 0x3b, 0xd0, 0x1a, 0x8c, 0xa4, 0xc2,
+    0xe1, 0xd3, 0x02, 0x41, 0x00, 0xe2, 0x4c, 0x05, 0xf2, 0x04,
+    0x86, 0x4e, 0x61, 0x43, 0xdb, 0xb0, 0xb9, 0x96, 0x86, 0x52,
+    0x2c, 0xca, 0x8d, 0x7b, 0xab, 0x0b, 0x13, 0x0d, 0x7e, 0x38,
+    0x5b, 0xe2, 0x2e, 0x7b, 0x0e, 0xe7, 0x19, 0x99, 0x38, 0xe7,
+    0xf2, 0x21, 0xbd, 0x85, 0x85, 0xe3, 0xfd, 0x28, 0x77, 0x20,
+    0x31, 0x71, 0x2c, 0xd0, 0xff, 0xfb, 0x2e, 0xaf, 0x85, 0xb4,
+    0x86, 0xca, 0xf3, 0xbb, 0xca, 0xaa, 0x0f, 0x95, 0x37, 0x02,
+    0x40, 0x0e, 0x41, 0x9a, 0x95, 0xe8, 0xb3, 0x59, 0xce, 0x4b,
+    0x61, 0xde, 0x35, 0xec, 0x38, 0x79, 0x9c, 0xb8, 0x10, 0x52,
+    0x41, 0x63, 0xab, 0x82, 0xae, 0x6f, 0x00, 0xa9, 0xf4, 0xde,
+    0xdd, 0x49, 0x0b, 0x7e, 0xb8, 0xa5, 0x65, 0xa9, 0x0c, 0x8f,
+    0x8f, 0xf9, 0x1f, 0x35, 0xc6, 0x92, 0xb8, 0x5e, 0xb0, 0x66,
+    0xab, 0x52, 0x40, 0xc0, 0xb6, 0x36, 0x6a, 0x7d, 0x80, 0x46,
+    0x04, 0x02, 0xe5, 0x9f, 0x41, 0x02, 0x41, 0x00, 0xc0, 0xad,
+    0xcc, 0x4e, 0x21, 0xee, 0x1d, 0x24, 0x91, 0xfb, 0xa7, 0x80,
+    0x8d, 0x9a, 0xb6, 0xb3, 0x2e, 0x8f, 0xc2, 0xe1, 0x82, 0xdf,
+    0x69, 0x18, 0xb4, 0x71, 0xff, 0xa6, 0x65, 0xde, 0xed, 0x84,
+    0x8d, 0x42, 0xb7, 0xb3, 0x21, 0x69, 0x56, 0x1c, 0x07, 0x60,
+    0x51, 0x29, 0x04, 0xff, 0x34, 0x06, 0xdd, 0xb9, 0x67, 0x2c,
+    0x7c, 0x04, 0x93, 0x0e, 0x46, 0x15, 0xbb, 0x2a, 0xb7, 0x1b,
+    0xe7, 0x87, 0x02, 0x40, 0x78, 0xda, 0x5d, 0x07, 0x51, 0x0c,
+    0x16, 0x7a, 0x9f, 0x29, 0x20, 0x84, 0x0d, 0x42, 0xfa, 0xd7,
+    0x00, 0xd8, 0x77, 0x7e, 0xb0, 0xb0, 0x6b, 0xd6, 0x5b, 0x53,
+    0xb8, 0x9b, 0x7a, 0xcd, 0xc7, 0x2b, 0xb8, 0x6a, 0x63, 0xa9,
+    0xfb, 0x6f, 0xa4, 0x72, 0xbf, 0x4c, 0x5d, 0x00, 0x14, 0xba,
+    0xfa, 0x59, 0x88, 0xed, 0xe4, 0xe0, 0x8c, 0xa2, 0xec, 0x14,
+    0x7e, 0x2d, 0xe2, 0xf0, 0x46, 0x49, 0x95, 0x45,
+};
+
+static unsigned char test2048[] = {
+    0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01,
+    0x01, 0x00, 0xc0, 0xc0, 0xce, 0x3e, 0x3c, 0x53, 0x67, 0x3f,
+    0x4f, 0xc5, 0x2f, 0xa4, 0xc2, 0x5a, 0x2f, 0x58, 0xfd, 0x27,
+    0x52, 0x6a, 0xe8, 0xcf, 0x4a, 0x73, 0x47, 0x8d, 0x25, 0x0f,
+    0x5f, 0x03, 0x26, 0x78, 0xef, 0xf0, 0x22, 0x12, 0xd3, 0xde,
+    0x47, 0xb2, 0x1c, 0x0b, 0x38, 0x63, 0x1a, 0x6c, 0x85, 0x7a,
+    0x80, 0xc6, 0x8f, 0xa0, 0x41, 0xaf, 0x62, 0xc4, 0x67, 0x32,
+    0x88, 0xf8, 0xa6, 0x9c, 0xf5, 0x23, 0x1d, 0xe4, 0xac, 0x3f,
+    0x29, 0xf9, 0xec, 0xe1, 0x8b, 0x26, 0x03, 0x2c, 0xb2, 0xab,
+    0xf3, 0x7d, 0xb5, 0xca, 0x49, 0xc0, 0x8f, 0x1c, 0xdf, 0x33,
+    0x3a, 0x60, 0xda, 0x3c, 0xb0, 0x16, 0xf8, 0xa9, 0x12, 0x8f,
+    0x64, 0xac, 0x23, 0x0c, 0x69, 0x64, 0x97, 0x5d, 0x99, 0xd4,
+    0x09, 0x83, 0x9b, 0x61, 0xd3, 0xac, 0xf0, 0xde, 0xdd, 0x5e,
+    0x9f, 0x44, 0x94, 0xdb, 0x3a, 0x4d, 0x97, 0xe8, 0x52, 0x29,
+    0xf7, 0xdb, 0x94, 0x07, 0x45, 0x90, 0x78, 0x1e, 0x31, 0x0b,
+    0x80, 0xf7, 0x57, 0xad, 0x1c, 0x79, 0xc5, 0xcb, 0x32, 0xb0,
+    0xce, 0xcd, 0x74, 0xb3, 0xe2, 0x94, 0xc5, 0x78, 0x2f, 0x34,
+    0x1a, 0x45, 0xf7, 0x8c, 0x52, 0xa5, 0xbc, 0x8d, 0xec, 0xd1,
+    0x2f, 0x31, 0x3b, 0xf0, 0x49, 0x59, 0x5e, 0x88, 0x9d, 0x15,
+    0x92, 0x35, 0x32, 0xc1, 0xe7, 0x61, 0xec, 0x50, 0x48, 0x7c,
+    0xba, 0x05, 0xf9, 0xf8, 0xf8, 0xa7, 0x8c, 0x83, 0xe8, 0x66,
+    0x5b, 0xeb, 0xfe, 0xd8, 0x4f, 0xdd, 0x6d, 0x36, 0xc0, 0xb2,
+    0x90, 0x0f, 0xb8, 0x52, 0xf9, 0x04, 0x9b, 0x40, 0x2c, 0x27,
+    0xd6, 0x36, 0x8e, 0xc2, 0x1b, 0x44, 0xf3, 0x92, 0xd5, 0x15,
+    0x9e, 0x9a, 0xbc, 0xf3, 0x7d, 0x03, 0xd7, 0x02, 0x14, 0x20,
+    0xe9, 0x10, 0x92, 0xfd, 0xf9, 0xfc, 0x8f, 0xe5, 0x18, 0xe1,
+    0x95, 0xcc, 0x9e, 0x60, 0xa6, 0xfa, 0x38, 0x4d, 0x02, 0x03,
+    0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x00, 0xc3, 0xc3,
+    0x0d, 0xb4, 0x27, 0x90, 0x8d, 0x4b, 0xbf, 0xb8, 0x84, 0xaa,
+    0xd0, 0xb8, 0xc7, 0x5d, 0x99, 0xbe, 0x55, 0xf6, 0x3e, 0x7c,
+    0x49, 0x20, 0xcb, 0x8a, 0x8e, 0x19, 0x0e, 0x66, 0x24, 0xac,
+    0xaf, 0x03, 0x33, 0x97, 0xeb, 0x95, 0xd5, 0x3b, 0x0f, 0x40,
+    0x56, 0x04, 0x50, 0xd1, 0xe6, 0xbe, 0x84, 0x0b, 0x25, 0xd3,
+    0x9c, 0xe2, 0x83, 0x6c, 0xf5, 0x62, 0x5d, 0xba, 0x2b, 0x7d,
+    0x3d, 0x7a, 0x6c, 0xe1, 0xd2, 0x0e, 0x54, 0x93, 0x80, 0x01,
+    0x91, 0x51, 0x09, 0xe8, 0x5b, 0x8e, 0x47, 0xbd, 0x64, 0xe4,
+    0x0e, 0x03, 0x83, 0x55, 0xcf, 0x5a, 0x37, 0xf0, 0x25, 0xb5,
+    0x7d, 0x21, 0xd7, 0x69, 0xdf, 0x6f, 0xc2, 0xcf, 0x10, 0xc9,
+    0x8a, 0x40, 0x9f, 0x7a, 0x70, 0xc0, 0xe8, 0xe8, 0xc0, 0xe6,
+    0x9a, 0x15, 0x0a, 0x8d, 0x4e, 0x46, 0xcb, 0x7a, 0xdb, 0xb3,
+    0xcb, 0x83, 0x02, 0xc4, 0xf0, 0xab, 0xeb, 0x02, 0x01, 0x0e,
+    0x23, 0xfc, 0x1d, 0xc4, 0xbd, 0xd4, 0xaa, 0x5d, 0x31, 0x46,
+    0x99, 0xce, 0x9e, 0xf8, 0x04, 0x75, 0x10, 0x67, 0xc4, 0x53,
+    0x47, 0x44, 0xfa, 0xc2, 0x25, 0x73, 0x7e, 0xd0, 0x8e, 0x59,
+    0xd1, 0xb2, 0x5a, 0xf4, 0xc7, 0x18, 0x92, 0x2f, 0x39, 0xab,
+    0xcd, 0xa3, 0xb5, 0xc2, 0xb9, 0xc7, 0xb9, 0x1b, 0x9f, 0x48,
+    0xfa, 0x13, 0xc6, 0x98, 0x4d, 0xca, 0x84, 0x9c, 0x06, 0xca,
+    0xe7, 0x89, 0x01, 0x04, 0xc4, 0x6c, 0xfd, 0x29, 0x59, 0x35,
+    0xe7, 0xf3, 0xdd, 0xce, 0x64, 0x59, 0xbf, 0x21, 0x13, 0xa9,
+    0x9f, 0x0e, 0xc5, 0xff, 0xbd, 0x33, 0x00, 0xec, 0xac, 0x6b,
+    0x11, 0xef, 0x51, 0x5e, 0xad, 0x07, 0x15, 0xde, 0xb8, 0x5f,
+    0xc6, 0xb9, 0xa3, 0x22, 0x65, 0x46, 0x83, 0x14, 0xdf, 0xd0,
+    0xf1, 0x44, 0x8a, 0xe1, 0x9c, 0x23, 0x33, 0xb4, 0x97, 0x33,
+    0xe6, 0x6b, 0x81, 0x02, 0x81, 0x81, 0x00, 0xec, 0x12, 0xa7,
+    0x59, 0x74, 0x6a, 0xde, 0x3e, 0xad, 0xd8, 0x36, 0x80, 0x50,
+    0xa2, 0xd5, 0x21, 0x81, 0x07, 0xf1, 0xd0, 0x91, 0xf2, 0x6c,
+    0x12, 0x2f, 0x9d, 0x1a, 0x26, 0xf8, 0x30, 0x65, 0xdf, 0xe8,
+    0xc0, 0x9b, 0x6a, 0x30, 0x98, 0x82, 0x87, 0xec, 0xa2, 0x56,
+    0x87, 0x62, 0x6f, 0xe7, 0x9f, 0xf6, 0x56, 0xe6, 0x71, 0x8f,
+    0x49, 0x86, 0x93, 0x5a, 0x4d, 0x34, 0x58, 0xfe, 0xd9, 0x04,
+    0x13, 0xaf, 0x79, 0xb7, 0xad, 0x11, 0xd1, 0x30, 0x9a, 0x14,
+    0x06, 0xa0, 0xfa, 0xb7, 0x55, 0xdc, 0x6c, 0x5a, 0x4c, 0x2c,
+    0x59, 0x56, 0xf6, 0xe8, 0x9d, 0xaf, 0x0a, 0x78, 0x99, 0x06,
+    0x06, 0x9e, 0xe7, 0x9c, 0x51, 0x55, 0x43, 0xfc, 0x3b, 0x6c,
+    0x0b, 0xbf, 0x2d, 0x41, 0xa7, 0xaf, 0xb7, 0xe0, 0xe8, 0x28,
+    0x18, 0xb4, 0x13, 0xd1, 0xe6, 0x97, 0xd0, 0x9f, 0x6a, 0x80,
+    0xca, 0xdd, 0x1a, 0x7e, 0x15, 0x02, 0x81, 0x81, 0x00, 0xd1,
+    0x06, 0x0c, 0x1f, 0xe3, 0xd0, 0xab, 0xd6, 0xca, 0x7c, 0xbc,
+    0x7d, 0x13, 0x35, 0xce, 0x27, 0xcd, 0xd8, 0x49, 0x51, 0x63,
+    0x64, 0x0f, 0xca, 0x06, 0x12, 0xfc, 0x07, 0x3e, 0xaf, 0x61,
+    0x6d, 0xe2, 0x53, 0x39, 0x27, 0xae, 0xc3, 0x11, 0x9e, 0x94,
+    0x01, 0x4f, 0xe3, 0xf3, 0x67, 0xf9, 0x77, 0xf9, 0xe7, 0x95,
+    0x3a, 0x6f, 0xe2, 0x20, 0x73, 0x3e, 0xa4, 0x7a, 0x28, 0xd4,
+    0x61, 0x97, 0xf6, 0x17, 0xa0, 0x23, 0x10, 0x2b, 0xce, 0x84,
+    0x57, 0x7e, 0x25, 0x1f, 0xf4, 0xa8, 0x54, 0xd2, 0x65, 0x94,
+    0xcc, 0x95, 0x0a, 0xab, 0x30, 0xc1, 0x59, 0x1f, 0x61, 0x8e,
+    0xb9, 0x6b, 0xd7, 0x4e, 0xb9, 0x83, 0x43, 0x79, 0x85, 0x11,
+    0xbc, 0x0f, 0xae, 0x25, 0x20, 0x05, 0xbc, 0xd2, 0x48, 0xa1,
+    0x68, 0x09, 0x84, 0xf6, 0x12, 0x9a, 0x66, 0xb9, 0x2b, 0xbb,
+    0x76, 0x03, 0x17, 0x46, 0x4e, 0x97, 0x59, 0x02, 0x81, 0x80,
+    0x09, 0x4c, 0xfa, 0xd6, 0xe5, 0x65, 0x48, 0x78, 0x43, 0xb5,
+    0x1f, 0x00, 0x93, 0x2c, 0xb7, 0x24, 0xe8, 0xc6, 0x7d, 0x5a,
+    0x70, 0x45, 0x92, 0xc8, 0x6c, 0xa3, 0xcd, 0xe1, 0xf7, 0x29,
+    0x40, 0xfa, 0x3f, 0x5b, 0x47, 0x44, 0x39, 0xc1, 0xe8, 0x72,
+    0x9e, 0x7a, 0x0e, 0xda, 0xaa, 0xa0, 0x2a, 0x09, 0xfd, 0x54,
+    0x93, 0x23, 0xaa, 0x37, 0x85, 0x5b, 0xcc, 0xd4, 0xf9, 0xd8,
+    0xff, 0xc1, 0x61, 0x0d, 0xbd, 0x7e, 0x18, 0x24, 0x73, 0x6d,
+    0x40, 0x72, 0xf1, 0x93, 0x09, 0x48, 0x97, 0x6c, 0x84, 0x90,
+    0xa8, 0x46, 0x14, 0x01, 0x39, 0x11, 0xe5, 0x3c, 0x41, 0x27,
+    0x32, 0x75, 0x24, 0xed, 0xa1, 0xd9, 0x12, 0x29, 0x8a, 0x28,
+    0x71, 0x89, 0x8d, 0xca, 0x30, 0xb0, 0x01, 0xc4, 0x2f, 0x82,
+    0x19, 0x14, 0x4c, 0x70, 0x1c, 0xb8, 0x23, 0x2e, 0xe8, 0x90,
+    0x49, 0x97, 0x92, 0x97, 0x6b, 0x7a, 0x9d, 0xb9, 0x02, 0x81,
+    0x80, 0x0f, 0x0e, 0xa1, 0x76, 0xf6, 0xa1, 0x44, 0x8f, 0xaf,
+    0x7c, 0x76, 0xd3, 0x87, 0xbb, 0xbb, 0x83, 0x10, 0x88, 0x01,
+    0x18, 0x14, 0xd1, 0xd3, 0x75, 0x59, 0x24, 0xaa, 0xf5, 0x16,
+    0xa5, 0xe9, 0x9d, 0xd1, 0xcc, 0xee, 0xf4, 0x15, 0xd9, 0xc5,
+    0x7e, 0x27, 0xe9, 0x44, 0x49, 0x06, 0x72, 0xb9, 0xfc, 0xd3,
+    0x8a, 0xc4, 0x2c, 0x36, 0x7d, 0x12, 0x9b, 0x5a, 0xaa, 0xdc,
+    0x85, 0xee, 0x6e, 0xad, 0x54, 0xb3, 0xf4, 0xfc, 0x31, 0xa1,
+    0x06, 0x3a, 0x70, 0x57, 0x0c, 0xf3, 0x95, 0x5b, 0x3e, 0xe8,
+    0xfd, 0x1a, 0x4f, 0xf6, 0x78, 0x93, 0x46, 0x6a, 0xd7, 0x31,
+    0xb4, 0x84, 0x64, 0x85, 0x09, 0x38, 0x89, 0x92, 0x94, 0x1c,
+    0xbf, 0xe2, 0x3c, 0x2a, 0xe0, 0xff, 0x99, 0xa3, 0xf0, 0x2b,
+    0x31, 0xc2, 0x36, 0xcd, 0x60, 0xbf, 0x9d, 0x2d, 0x74, 0x32,
+    0xe8, 0x9c, 0x93, 0x6e, 0xbb, 0x91, 0x7b, 0xfd, 0xd9, 0x02,
+    0x81, 0x81, 0x00, 0xa2, 0x71, 0x25, 0x38, 0xeb, 0x2a, 0xe9,
+    0x37, 0xcd, 0xfe, 0x44, 0xce, 0x90, 0x3f, 0x52, 0x87, 0x84,
+    0x52, 0x1b, 0xae, 0x8d, 0x22, 0x94, 0xce, 0x38, 0xe6, 0x04,
+    0x88, 0x76, 0x85, 0x9a, 0xd3, 0x14, 0x09, 0xe5, 0x69, 0x9a,
+    0xff, 0x58, 0x92, 0x02, 0x6a, 0x7d, 0x7c, 0x1e, 0x2c, 0xfd,
+    0xa8, 0xca, 0x32, 0x14, 0x4f, 0x0d, 0x84, 0x0d, 0x37, 0x43,
+    0xbf, 0xe4, 0x5d, 0x12, 0xc8, 0x24, 0x91, 0x27, 0x8d, 0x46,
+    0xd9, 0x54, 0x53, 0xe7, 0x62, 0x71, 0xa8, 0x2b, 0x71, 0x41,
+    0x8d, 0x75, 0xf8, 0x3a, 0xa0, 0x61, 0x29, 0x46, 0xa6, 0xe5,
+    0x82, 0xfa, 0x3a, 0xd9, 0x08, 0xfa, 0xfc, 0x63, 0xfd, 0x6b,
+    0x30, 0xbc, 0xf4, 0x4e, 0x9e, 0x8c, 0x25, 0x0c, 0xb6, 0x55,
+    0xe7, 0x3c, 0xd4, 0x4e, 0x0b, 0xfd, 0x8b, 0xc3, 0x0e, 0x1d,
+    0x9c, 0x44, 0x57, 0x8f, 0x1f, 0x86, 0xf7, 0xd5, 0x1b, 0xe4,
+    0x95,
+};
+
+static unsigned char test3072[] = {
+    0x30, 0x82, 0x06, 0xe3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01,
+    0x81, 0x00, 0xbc, 0x3b, 0x23, 0xc0, 0x33, 0xa7, 0x8b, 0xaa,
+    0xca, 0xa3, 0x8c, 0x94, 0xf2, 0x4c, 0x52, 0x08, 0x85, 0x80,
+    0xfc, 0x36, 0x15, 0xfa, 0x03, 0x06, 0xb6, 0xd6, 0x3f, 0x60,
+    0x8a, 0x89, 0x0d, 0xba, 0x1a, 0x51, 0x0b, 0x12, 0xea, 0x71,
+    0x77, 0xf6, 0x3a, 0x30, 0x21, 0x3d, 0x24, 0xf8, 0x2e, 0xd0,
+    0x17, 0x3a, 0x85, 0x94, 0x25, 0x42, 0x89, 0xff, 0x6a, 0x68,
+    0xdf, 0x1f, 0x86, 0xae, 0xa5, 0xbb, 0x9a, 0x79, 0xf6, 0x69,
+    0x94, 0xfe, 0xde, 0xfe, 0xce, 0x1b, 0x2e, 0xae, 0x1d, 0x91,
+    0xcb, 0xb9, 0xf1, 0x2d, 0xd8, 0x00, 0x82, 0x51, 0x8e, 0xf9,
+    0xfd, 0xac, 0xf1, 0x0e, 0x7f, 0xb7, 0x95, 0x85, 0x35, 0xf9,
+    0xcb, 0xbe, 0x5f, 0xd3, 0x58, 0xe3, 0xa1, 0x54, 0x9e, 0x30,
+    0xb1, 0x8d, 0x01, 0x97, 0x82, 0x06, 0x8e, 0x77, 0xfb, 0xce,
+    0x50, 0x2f, 0xbf, 0xf1, 0xff, 0x57, 0x0a, 0x42, 0x03, 0xfd,
+    0x0e, 0xba, 0x1e, 0xca, 0x85, 0xc1, 0x9b, 0xa5, 0x9d, 0x09,
+    0x0e, 0xe9, 0xbb, 0xc5, 0x73, 0x47, 0x0d, 0x39, 0x3c, 0x64,
+    0x06, 0x9a, 0x79, 0x3f, 0x50, 0x87, 0x9c, 0x18, 0x2d, 0x62,
+    0x01, 0xfc, 0xed, 0xc1, 0x58, 0x28, 0x21, 0x94, 0x1e, 0xf9,
+    0x2d, 0x96, 0x4f, 0xd0, 0xbc, 0xf1, 0xe0, 0x8a, 0xfa, 0x4d,
+    0xb6, 0x78, 0x4a, 0xde, 0x17, 0x59, 0xb0, 0x22, 0xa0, 0x9a,
+    0xd3, 0x70, 0xb6, 0xc2, 0xbe, 0xbc, 0x96, 0xca, 0x41, 0x5f,
+    0x58, 0x4e, 0xce, 0xef, 0x64, 0x45, 0xdd, 0x3f, 0x81, 0x92,
+    0xcc, 0x40, 0x79, 0xfc, 0x19, 0xe2, 0xbc, 0x77, 0x2f, 0x43,
+    0xfb, 0x8e, 0xad, 0x82, 0x4a, 0x0b, 0xb1, 0xbc, 0x09, 0x8a,
+    0x80, 0xc3, 0x0f, 0xef, 0xd2, 0x06, 0xd3, 0x4b, 0x0c, 0x7f,
+    0xae, 0x60, 0x3f, 0x2e, 0x52, 0xb4, 0xe4, 0xc2, 0x5c, 0xa6,
+    0x71, 0xc0, 0x13, 0x9c, 0xca, 0xa6, 0x0d, 0x13, 0xd7, 0xb7,
+    0x14, 0x94, 0x3f, 0x0d, 0x8b, 0x06, 0x70, 0x2f, 0x15, 0x82,
+    0x8d, 0x47, 0x45, 0xa6, 0x00, 0x8a, 0x14, 0x91, 0xde, 0x2f,
+    0x50, 0x17, 0xe3, 0x1d, 0x34, 0x29, 0x8c, 0xe4, 0x57, 0x74,
+    0x2a, 0x3a, 0x82, 0x65, 0x26, 0xf7, 0x8d, 0xcc, 0x1b, 0x8f,
+    0xaf, 0xe5, 0x85, 0xe5, 0xbe, 0x85, 0xd6, 0xb7, 0x04, 0xe8,
+    0xf5, 0xd4, 0x74, 0xe2, 0x54, 0x14, 0xdd, 0x58, 0xcf, 0x1f,
+    0x11, 0x8a, 0x9f, 0x82, 0xa2, 0x01, 0xf9, 0xc2, 0xdf, 0x7b,
+    0x84, 0xb1, 0xd8, 0x5b, 0x70, 0xbb, 0x24, 0xe7, 0xd0, 0x2a,
+    0x75, 0x3d, 0x55, 0xac, 0x45, 0xe9, 0xab, 0xc6, 0x84, 0x8a,
+    0xe7, 0x6d, 0x26, 0x12, 0x89, 0xb5, 0x67, 0xe8, 0x46, 0x9d,
+    0x46, 0x1a, 0xfa, 0x2d, 0xc0, 0x5b, 0x60, 0x46, 0x8b, 0xb7,
+    0x32, 0x03, 0xff, 0x75, 0xee, 0x9f, 0x3c, 0xdd, 0xb6, 0x35,
+    0x4e, 0x82, 0xbd, 0x99, 0x73, 0x51, 0x02, 0x03, 0x01, 0x00,
+    0x01, 0x02, 0x82, 0x01, 0x80, 0x42, 0xee, 0xa4, 0x9f, 0xcb,
+    0xbe, 0x60, 0x23, 0xb3, 0x3a, 0xc4, 0xda, 0x91, 0xee, 0x21,
+    0x9d, 0x76, 0x1b, 0x8f, 0x93, 0x8b, 0xed, 0x02, 0xf6, 0x78,
+    0x3d, 0x66, 0xfb, 0xe5, 0x47, 0x26, 0xe2, 0x6e, 0x49, 0x33,
+    0x2e, 0xde, 0xbe, 0xca, 0x71, 0x7b, 0xef, 0x71, 0x62, 0x54,
+    0xab, 0x0b, 0xba, 0x63, 0x08, 0x24, 0x47, 0xb1, 0x98, 0x1f,
+    0x89, 0xfb, 0x44, 0x9f, 0x52, 0x8e, 0x89, 0xbb, 0xd5, 0x21,
+    0xf1, 0x0c, 0x76, 0x2e, 0xcd, 0x12, 0x6e, 0x78, 0xcb, 0xa1,
+    0xa5, 0xb8, 0x4e, 0x07, 0xab, 0x6e, 0xdf, 0x66, 0x57, 0x87,
+    0xff, 0x88, 0x5f, 0xcc, 0x9c, 0x9a, 0x7b, 0x15, 0x5f, 0x2a,
+    0x83, 0xdb, 0xd5, 0x9f, 0x65, 0x6a, 0x9d, 0xb4, 0x95, 0xfc,
+    0xe0, 0x22, 0x00, 0x1e, 0xa2, 0x8d, 0x56, 0x5a, 0x9e, 0x0a,
+    0x3b, 0x10, 0x07, 0x24, 0xec, 0x55, 0xcc, 0xaf, 0x87, 0x3b,
+    0xd6, 0x8d, 0xa4, 0x86, 0x80, 0x18, 0x42, 0xdb, 0x9d, 0x24,
+    0xc3, 0x97, 0x3b, 0x89, 0x5a, 0x03, 0xb3, 0x0a, 0x72, 0xd1,
+    0x78, 0xf0, 0xc8, 0x80, 0xb0, 0x9d, 0x3c, 0xae, 0x5e, 0x0a,
+    0x5b, 0x6e, 0x87, 0xd3, 0x3d, 0x25, 0x2e, 0x03, 0x33, 0x01,
+    0xfd, 0xb1, 0xa5, 0xd9, 0x58, 0x01, 0xb9, 0xaf, 0xf6, 0x32,
+    0x6a, 0x38, 0xe7, 0x39, 0x63, 0x3c, 0xfc, 0x0c, 0x41, 0x90,
+    0x28, 0x40, 0x03, 0xcd, 0xfb, 0xde, 0x80, 0x74, 0x21, 0xaa,
+    0xae, 0x58, 0xe9, 0x97, 0x18, 0x85, 0x58, 0x3d, 0x2b, 0xd6,
+    0x61, 0xf6, 0xe8, 0xbc, 0x6d, 0x2a, 0xf3, 0xb8, 0xea, 0x8c,
+    0x64, 0x44, 0xc6, 0xd3, 0x9f, 0x00, 0x7b, 0xb2, 0x52, 0x18,
+    0x11, 0x04, 0x96, 0xb7, 0x05, 0xbb, 0xc2, 0x38, 0x5b, 0xa7,
+    0x0a, 0x84, 0xb6, 0x4f, 0x02, 0x63, 0xa4, 0x57, 0x00, 0xe3,
+    0xde, 0xe4, 0xf2, 0xb3, 0x55, 0xd9, 0x00, 0xa9, 0xd2, 0x5c,
+    0x69, 0x9f, 0xe5, 0x80, 0x4f, 0x23, 0x7c, 0xd9, 0xa7, 0x77,
+    0x4a, 0xbb, 0x09, 0x6d, 0x45, 0x02, 0xcf, 0x32, 0x90, 0xfd,
+    0x10, 0xb6, 0xb3, 0x93, 0xd9, 0x3b, 0x1d, 0x57, 0x66, 0xb5,
+    0xb3, 0xb1, 0x6e, 0x53, 0x5f, 0x04, 0x60, 0x29, 0xcd, 0xe8,
+    0xb8, 0xab, 0x62, 0x82, 0x33, 0x40, 0xc7, 0xf8, 0x64, 0x60,
+    0x0e, 0xab, 0x06, 0x3e, 0xa0, 0xa3, 0x62, 0x11, 0x3f, 0x67,
+    0x5d, 0x24, 0x9e, 0x60, 0x29, 0xdc, 0x4c, 0xd5, 0x13, 0xee,
+    0x3d, 0xb7, 0x84, 0x93, 0x27, 0xb5, 0x6a, 0xf9, 0xf0, 0xdd,
+    0x50, 0xac, 0x46, 0x3c, 0xe6, 0xd5, 0xec, 0xf7, 0xb7, 0x9f,
+    0x23, 0x39, 0x9c, 0x88, 0x8c, 0x5a, 0x62, 0x3f, 0x8d, 0x4a,
+    0xd7, 0xeb, 0x5e, 0x1e, 0x49, 0xf8, 0xa9, 0x53, 0x11, 0x75,
+    0xd0, 0x43, 0x1e, 0xc7, 0x29, 0x22, 0x80, 0x1f, 0xc5, 0x83,
+    0x8d, 0x20, 0x04, 0x87, 0x7f, 0x57, 0x8c, 0xf5, 0xa1, 0x02,
+    0x81, 0xc1, 0x00, 0xf7, 0xaa, 0xf5, 0xa5, 0x00, 0xdb, 0xd6,
+    0x11, 0xfc, 0x07, 0x6d, 0x22, 0x24, 0x2b, 0x4b, 0xc5, 0x67,
+    0x0f, 0x37, 0xa5, 0xdb, 0x8f, 0x38, 0xe2, 0x05, 0x43, 0x9a,
+    0x44, 0x05, 0x3f, 0xa9, 0xac, 0x4c, 0x98, 0x3c, 0x72, 0x38,
+    0xc3, 0x89, 0x33, 0x58, 0x73, 0x51, 0xcc, 0x5d, 0x2f, 0x8f,
+    0x6d, 0x3f, 0xa1, 0x22, 0x9e, 0xfb, 0x9a, 0xb4, 0xb8, 0x79,
+    0x95, 0xaf, 0x83, 0xcf, 0x5a, 0xb7, 0x14, 0x14, 0x0c, 0x51,
+    0x8a, 0x11, 0xe6, 0xd6, 0x21, 0x1e, 0x17, 0x13, 0xd3, 0x69,
+    0x7a, 0x3a, 0xd5, 0xaf, 0x3f, 0xb8, 0x25, 0x01, 0xcb, 0x2b,
+    0xe6, 0xfc, 0x03, 0xd8, 0xd4, 0xf7, 0x20, 0xe0, 0x21, 0xef,
+    0x1a, 0xca, 0x61, 0xeb, 0x8e, 0x96, 0x45, 0x8e, 0x5c, 0xe6,
+    0x81, 0x0b, 0x2d, 0x05, 0x32, 0xf9, 0x41, 0x62, 0xb4, 0x33,
+    0x98, 0x10, 0x3a, 0xcd, 0xf0, 0x7a, 0x8b, 0x1a, 0x48, 0xd7,
+    0x3b, 0x01, 0xf5, 0x18, 0x65, 0x8f, 0x3c, 0xc2, 0x31, 0x3b,
+    0xd3, 0xa7, 0x17, 0x5f, 0x7c, 0x0c, 0xe7, 0x25, 0x18, 0x5a,
+    0x08, 0xe1, 0x09, 0x89, 0x13, 0xa7, 0xc5, 0x12, 0xab, 0x88,
+    0x30, 0xcd, 0x06, 0xf9, 0xba, 0x6f, 0xca, 0x9c, 0x8a, 0xda,
+    0x3e, 0x53, 0x90, 0xd7, 0x16, 0x2e, 0xfc, 0xbc, 0xad, 0xd6,
+    0x3d, 0xc0, 0x66, 0x4c, 0x02, 0x3d, 0x31, 0xfd, 0x6c, 0xdb,
+    0x1c, 0xdf, 0x96, 0x33, 0x23, 0x02, 0x81, 0xc1, 0x00, 0xc2,
+    0x90, 0x47, 0xc4, 0xfb, 0x59, 0xf0, 0xc5, 0x14, 0x75, 0x29,
+    0xfa, 0x77, 0xa1, 0x8d, 0xd4, 0x90, 0xa1, 0x0d, 0x3f, 0x16,
+    0x88, 0xe3, 0x4c, 0x8f, 0x8f, 0x18, 0x8c, 0x9c, 0x8a, 0xd5,
+    0xa7, 0x41, 0x99, 0xf3, 0x80, 0x8e, 0xb1, 0xb8, 0x63, 0xd8,
+    0x3f, 0x95, 0xd0, 0xd0, 0x2b, 0xf5, 0xe6, 0x93, 0xe8, 0xfe,
+    0xd0, 0x73, 0xd5, 0xbd, 0xb4, 0xee, 0x51, 0x19, 0x6a, 0x10,
+    0xca, 0xc8, 0xba, 0xa4, 0x4d, 0x84, 0x54, 0x38, 0x17, 0xb5,
+    0xd0, 0xa8, 0x75, 0x22, 0xc5, 0x1b, 0x61, 0xa6, 0x51, 0x88,
+    0x63, 0xf0, 0x4f, 0xd1, 0x88, 0xd9, 0x16, 0x49, 0x30, 0xe1,
+    0xa8, 0x47, 0xc9, 0x30, 0x1d, 0x5c, 0x75, 0xd8, 0x89, 0xb6,
+    0x1d, 0x45, 0xd8, 0x0f, 0x94, 0x89, 0xb3, 0xe4, 0x51, 0xfa,
+    0x21, 0xff, 0x6f, 0xb6, 0x30, 0x6f, 0x33, 0x24, 0xbc, 0x09,
+    0x98, 0xe9, 0x20, 0x02, 0x0b, 0xde, 0xff, 0xc5, 0x06, 0xb6,
+    0x28, 0xa3, 0xa1, 0x07, 0xe8, 0xe1, 0xd2, 0xc2, 0xf1, 0xd1,
+    0x23, 0x6b, 0x4c, 0x3a, 0xae, 0x85, 0xec, 0xf9, 0xff, 0xa7,
+    0x9b, 0x25, 0xb8, 0x95, 0x1d, 0xa8, 0x14, 0x81, 0x4f, 0x79,
+    0x4f, 0xd6, 0x39, 0x5d, 0xe6, 0x5f, 0xd2, 0x34, 0x54, 0x8b,
+    0x1e, 0x40, 0x4c, 0x15, 0x5a, 0x45, 0xce, 0x0c, 0xb0, 0xdf,
+    0xa1, 0x17, 0xb8, 0xb0, 0x6a, 0x82, 0xa5, 0x97, 0x92, 0x70,
+    0xfb, 0x02, 0x81, 0xc0, 0x77, 0x46, 0x44, 0x2b, 0x04, 0xf0,
+    0xda, 0x75, 0xaa, 0xd4, 0xc0, 0xc0, 0x32, 0x7f, 0x0f, 0x6c,
+    0xb0, 0x27, 0x69, 0xfb, 0x5c, 0x73, 0xeb, 0x47, 0x1e, 0x95,
+    0xe2, 0x13, 0x64, 0x1b, 0xb6, 0xd1, 0x1d, 0xca, 0x2b, 0x42,
+    0x2f, 0x08, 0x2c, 0x69, 0x27, 0xed, 0xd1, 0xb5, 0x04, 0x23,
+    0xc5, 0x85, 0x2d, 0xa1, 0xa2, 0x94, 0xc2, 0x43, 0x4d, 0x49,
+    0x92, 0x74, 0x7e, 0x24, 0x92, 0x95, 0xf3, 0x99, 0x9d, 0xd6,
+    0x18, 0xe6, 0xcf, 0x9c, 0x45, 0xff, 0x89, 0x08, 0x40, 0x2a,
+    0x0e, 0xa0, 0x28, 0xf9, 0x83, 0xfe, 0xc1, 0xe6, 0x40, 0xa8,
+    0xe2, 0x29, 0xc9, 0xb0, 0xe8, 0x9a, 0x17, 0xb2, 0x23, 0x7e,
+    0xf4, 0x32, 0x08, 0xc9, 0x83, 0xb2, 0x15, 0xb8, 0xc5, 0xc9,
+    0x03, 0xd1, 0x9d, 0xda, 0x3e, 0xa8, 0xbf, 0xd5, 0xb7, 0x7d,
+    0x65, 0x63, 0x94, 0x5d, 0x5d, 0x94, 0xb4, 0xcf, 0x8d, 0x07,
+    0x0b, 0x70, 0x85, 0x8e, 0xce, 0x03, 0x0b, 0x2a, 0x8d, 0xb3,
+    0x3c, 0x46, 0xc0, 0x2f, 0xc7, 0x72, 0x6c, 0x9c, 0x5d, 0x07,
+    0x0f, 0x45, 0x3b, 0x6b, 0x66, 0x32, 0xab, 0x17, 0x83, 0xd8,
+    0x4c, 0x2c, 0x84, 0x71, 0x19, 0x8f, 0xaa, 0x0a, 0xff, 0xbc,
+    0xf7, 0x42, 0x10, 0xe8, 0xae, 0x4d, 0x26, 0xaf, 0xdd, 0x06,
+    0x33, 0x29, 0x66, 0x21, 0x5d, 0xf5, 0xae, 0x17, 0x07, 0x1f,
+    0x87, 0x9e, 0xae, 0x27, 0x1d, 0xd5, 0x02, 0x81, 0xc0, 0x56,
+    0x17, 0x4f, 0x9a, 0x8a, 0xf9, 0xde, 0x3e, 0xe6, 0x71, 0x7d,
+    0x94, 0xb5, 0xb0, 0xc7, 0xb8, 0x62, 0x12, 0xd1, 0x70, 0xb4,
+    0x00, 0xf8, 0x4a, 0xdd, 0x4f, 0x1d, 0x36, 0xc2, 0xe1, 0xef,
+    0xee, 0x25, 0x6a, 0x00, 0xc4, 0x46, 0xdf, 0xbe, 0xce, 0x77,
+    0x56, 0x93, 0x6d, 0x25, 0x5f, 0xfe, 0x5b, 0xfb, 0xe0, 0xe2,
+    0x37, 0xcc, 0xb9, 0xac, 0x4a, 0xce, 0x15, 0x16, 0xa0, 0xc7,
+    0x33, 0x63, 0xa4, 0xaa, 0xa5, 0x1e, 0x43, 0xc1, 0xda, 0x43,
+    0xfa, 0x43, 0x40, 0x29, 0x95, 0x7c, 0x2b, 0x36, 0x53, 0xe7,
+    0x7d, 0x09, 0x4d, 0xd8, 0x52, 0xac, 0x74, 0x5f, 0x08, 0x81,
+    0x21, 0x5c, 0x3a, 0x5a, 0xce, 0xf3, 0x25, 0xb6, 0x1e, 0x21,
+    0x76, 0x4c, 0x7c, 0x71, 0x50, 0x71, 0xaa, 0x27, 0x02, 0x5b,
+    0x23, 0x06, 0x0b, 0x21, 0x5b, 0xc7, 0x28, 0xa3, 0x3d, 0x8d,
+    0x25, 0x9b, 0x2a, 0x2d, 0x9d, 0xa1, 0x1c, 0x1d, 0xcb, 0x7d,
+    0x78, 0xf8, 0x06, 0x7e, 0x20, 0x7f, 0x24, 0x2a, 0x5c, 0xa4,
+    0x04, 0xff, 0x2a, 0x68, 0xe0, 0xe6, 0xa3, 0xd8, 0x6f, 0x56,
+    0x73, 0xa1, 0x3a, 0x4e, 0xc9, 0x23, 0xa1, 0x87, 0x22, 0x6a,
+    0x74, 0x78, 0x3f, 0x44, 0x1c, 0x77, 0x13, 0xe5, 0x51, 0xef,
+    0x89, 0x00, 0x3c, 0x6a, 0x4a, 0x5a, 0x8e, 0xf5, 0x30, 0xa2,
+    0x93, 0x7e, 0x92, 0x9b, 0x85, 0x55, 0xaf, 0xfe, 0x24, 0xaf,
+    0x57, 0x02, 0x81, 0xc1, 0x00, 0xa4, 0xc2, 0x6a, 0x59, 0x45,
+    0xea, 0x71, 0x7d, 0x4c, 0xaf, 0xaf, 0xd6, 0x55, 0x97, 0x73,
+    0xc5, 0xa1, 0x3c, 0xf6, 0x59, 0x23, 0xb6, 0x1f, 0x5e, 0x9c,
+    0x96, 0x0f, 0x97, 0x66, 0x82, 0x91, 0x48, 0x36, 0x70, 0x02,
+    0x67, 0xde, 0x34, 0xa6, 0x95, 0x7b, 0x51, 0x43, 0x66, 0xa4,
+    0x16, 0x45, 0x59, 0x12, 0xdb, 0x35, 0x19, 0x4b, 0xbf, 0x1d,
+    0xab, 0xf3, 0x3f, 0xb4, 0xb4, 0x6f, 0x66, 0xb0, 0x67, 0xc6,
+    0x77, 0x2c, 0x46, 0xa8, 0x03, 0x64, 0x9a, 0x13, 0x9d, 0x40,
+    0x22, 0x56, 0x76, 0x1a, 0x7c, 0x1e, 0xe2, 0xda, 0x7f, 0x09,
+    0xcf, 0x10, 0xe3, 0xf2, 0xf4, 0x2a, 0x3b, 0x46, 0xc7, 0x61,
+    0x9b, 0xef, 0x4a, 0x18, 0x60, 0x8c, 0x32, 0x71, 0xb9, 0xdd,
+    0xac, 0xa0, 0xc6, 0x8d, 0x3f, 0xab, 0xc3, 0x21, 0x2c, 0xeb,
+    0x91, 0x8f, 0xc7, 0x43, 0x0d, 0x0c, 0x67, 0x9e, 0xab, 0xe6,
+    0x8d, 0xb6, 0x2d, 0x41, 0xca, 0x43, 0xd8, 0xcb, 0x30, 0xfb,
+    0x3b, 0x40, 0x0d, 0x10, 0x9b, 0xb1, 0x55, 0x93, 0x73, 0x8b,
+    0x60, 0xef, 0xc0, 0xee, 0xc0, 0xa6, 0x7a, 0x79, 0x90, 0xfd,
+    0x4c, 0x25, 0xd4, 0x4f, 0x67, 0xbe, 0xf7, 0x86, 0x3c, 0x5d,
+    0x2b, 0x7d, 0x97, 0x3d, 0xa2, 0x91, 0xa5, 0x06, 0x69, 0xf6,
+    0x7a, 0xb8, 0x77, 0xe6, 0x70, 0xa9, 0xd8, 0x86, 0x4b, 0xa6,
+    0xcf, 0x67, 0x1d, 0x33, 0xcf, 0xfe, 0x3e
+};
+
+static unsigned char test4096[] = {
+    0x30, 0x82, 0x09, 0x29, 0x02, 0x01, 0x00, 0x02, 0x82, 0x02,
+    0x01, 0x00, 0xc0, 0x71, 0xac, 0x1a, 0x13, 0x88, 0x82, 0x43,
+    0x3b, 0x51, 0x57, 0x71, 0x8d, 0xb6, 0x2b, 0x82, 0x65, 0x21,
+    0x53, 0x5f, 0x28, 0x29, 0x4f, 0x8d, 0x7c, 0x8a, 0xb9, 0x44,
+    0xb3, 0x28, 0x41, 0x4f, 0xd3, 0xfa, 0x6a, 0xf8, 0xb9, 0x28,
+    0x50, 0x39, 0x67, 0x53, 0x2c, 0x3c, 0xd7, 0xcb, 0x96, 0x41,
+    0x40, 0x32, 0xbb, 0xeb, 0x70, 0xae, 0x1f, 0xb0, 0x65, 0xf7,
+    0x3a, 0xd9, 0x22, 0xfd, 0x10, 0xae, 0xbd, 0x02, 0xe2, 0xdd,
+    0xf3, 0xc2, 0x79, 0x3c, 0xc6, 0xfc, 0x75, 0xbb, 0xaf, 0x4e,
+    0x3a, 0x36, 0xc2, 0x4f, 0xea, 0x25, 0xdf, 0x13, 0x16, 0x4b,
+    0x20, 0xfe, 0x4b, 0x69, 0x16, 0xc4, 0x7f, 0x1a, 0x43, 0xa6,
+    0x17, 0x1b, 0xb9, 0x0a, 0xf3, 0x09, 0x86, 0x28, 0x89, 0xcf,
+    0x2c, 0xd0, 0xd4, 0x81, 0xaf, 0xc6, 0x6d, 0xe6, 0x21, 0x8d,
+    0xee, 0xef, 0xea, 0xdc, 0xb7, 0xc6, 0x3b, 0x63, 0x9f, 0x0e,
+    0xad, 0x89, 0x78, 0x23, 0x18, 0xbf, 0x70, 0x7e, 0x84, 0xe0,
+    0x37, 0xec, 0xdb, 0x8e, 0x9c, 0x3e, 0x6a, 0x19, 0xcc, 0x99,
+    0x72, 0xe6, 0xb5, 0x7d, 0x6d, 0xfa, 0xe5, 0xd3, 0xe4, 0x90,
+    0xb5, 0xb2, 0xb2, 0x12, 0x70, 0x4e, 0xca, 0xf8, 0x10, 0xf8,
+    0xa3, 0x14, 0xc2, 0x48, 0x19, 0xeb, 0x60, 0x99, 0xbb, 0x2a,
+    0x1f, 0xb1, 0x7a, 0xb1, 0x3d, 0x24, 0xfb, 0xa0, 0x29, 0xda,
+    0xbd, 0x1b, 0xd7, 0xa4, 0xbf, 0xef, 0x60, 0x2d, 0x22, 0xca,
+    0x65, 0x98, 0xf1, 0xc4, 0xe1, 0xc9, 0x02, 0x6b, 0x16, 0x28,
+    0x2f, 0xa1, 0xaa, 0x79, 0x00, 0xda, 0xdc, 0x7c, 0x43, 0xf7,
+    0x42, 0x3c, 0xa0, 0xef, 0x68, 0xf7, 0xdf, 0xb9, 0x69, 0xfb,
+    0x8e, 0x01, 0xed, 0x01, 0x42, 0xb5, 0x4e, 0x57, 0xa6, 0x26,
+    0xb8, 0xd0, 0x7b, 0x56, 0x6d, 0x03, 0xc6, 0x40, 0x8c, 0x8c,
+    0x2a, 0x55, 0xd7, 0x9c, 0x35, 0x00, 0x94, 0x93, 0xec, 0x03,
+    0xeb, 0x22, 0xef, 0x77, 0xbb, 0x79, 0x13, 0x3f, 0x15, 0xa1,
+    0x8f, 0xca, 0xdf, 0xfd, 0xd3, 0xb8, 0xe1, 0xd4, 0xcc, 0x09,
+    0x3f, 0x3c, 0x2c, 0xdb, 0xd1, 0x49, 0x7f, 0x38, 0x07, 0x83,
+    0x6d, 0xeb, 0x08, 0x66, 0xe9, 0x06, 0x44, 0x12, 0xac, 0x95,
+    0x22, 0x90, 0x23, 0x67, 0xd4, 0x08, 0xcc, 0xf4, 0xb7, 0xdc,
+    0xcc, 0x87, 0xd4, 0xac, 0x69, 0x35, 0x4c, 0xb5, 0x39, 0x36,
+    0xcd, 0xa4, 0xd2, 0x95, 0xca, 0x0d, 0xc5, 0xda, 0xc2, 0xc5,
+    0x22, 0x32, 0x28, 0x08, 0xe3, 0xd2, 0x8b, 0x38, 0x30, 0xdc,
+    0x8c, 0x75, 0x4f, 0x6a, 0xec, 0x7a, 0xac, 0x16, 0x3e, 0xa8,
+    0xd4, 0x6a, 0x45, 0xe1, 0xa8, 0x4f, 0x2e, 0x80, 0x34, 0xaa,
+    0x54, 0x1b, 0x02, 0x95, 0x7d, 0x8a, 0x6d, 0xcc, 0x79, 0xca,
+    0xf2, 0xa4, 0x2e, 0x8d, 0xfb, 0xfe, 0x15, 0x51, 0x10, 0x0e,
+    0x4d, 0x88, 0xb1, 0xc7, 0xf4, 0x79, 0xdb, 0xf0, 0xb4, 0x56,
+    0x44, 0x37, 0xca, 0x5a, 0xc1, 0x8c, 0x48, 0xac, 0xae, 0x48,
+    0x80, 0x83, 0x01, 0x3f, 0xde, 0xd9, 0xd3, 0x2c, 0x51, 0x46,
+    0xb1, 0x41, 0xb6, 0xc6, 0x91, 0x72, 0xf9, 0x83, 0x55, 0x1b,
+    0x8c, 0xba, 0xf3, 0x73, 0xe5, 0x2c, 0x74, 0x50, 0x3a, 0xbe,
+    0xc5, 0x2f, 0xa7, 0xb2, 0x6d, 0x8c, 0x9e, 0x13, 0x77, 0xa3,
+    0x13, 0xcd, 0x6d, 0x8c, 0x45, 0xe1, 0xfc, 0x0b, 0xb7, 0x69,
+    0xe9, 0x27, 0xbc, 0x65, 0xc3, 0xfa, 0x9b, 0xd0, 0xef, 0xfe,
+    0xe8, 0x1f, 0xb3, 0x5e, 0x34, 0xf4, 0x8c, 0xea, 0xfc, 0xd3,
+    0x81, 0xbf, 0x3d, 0x30, 0xb2, 0xb4, 0x01, 0xe8, 0x43, 0x0f,
+    0xba, 0x02, 0x23, 0x42, 0x76, 0x82, 0x31, 0x73, 0x91, 0xed,
+    0x07, 0x46, 0x61, 0x0d, 0x39, 0x83, 0x40, 0xce, 0x7a, 0xd4,
+    0xdb, 0x80, 0x2c, 0x1f, 0x0d, 0xd1, 0x34, 0xd4, 0x92, 0xe3,
+    0xd4, 0xf1, 0xc2, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
+    0x82, 0x02, 0x01, 0x00, 0x97, 0x6c, 0xda, 0x6e, 0xea, 0x4f,
+    0xcf, 0xaf, 0xf7, 0x4c, 0xd9, 0xf1, 0x90, 0x00, 0x77, 0xdb,
+    0xf2, 0x97, 0x76, 0x72, 0xb9, 0xb7, 0x47, 0xd1, 0x9c, 0xdd,
+    0xcb, 0x4a, 0x33, 0x6e, 0xc9, 0x75, 0x76, 0xe6, 0xe4, 0xa5,
+    0x31, 0x8c, 0x77, 0x13, 0xb4, 0x29, 0xcd, 0xf5, 0x52, 0x17,
+    0xef, 0xf3, 0x08, 0x00, 0xe3, 0xbd, 0x2e, 0xbc, 0xd4, 0x52,
+    0x88, 0xe9, 0x30, 0x75, 0x0b, 0x02, 0xf5, 0xcd, 0x89, 0x0c,
+    0x6c, 0x57, 0x19, 0x27, 0x3d, 0x1e, 0x85, 0xb4, 0xc1, 0x2f,
+    0x1d, 0x92, 0x00, 0x5c, 0x76, 0x29, 0x4b, 0xa4, 0xe1, 0x12,
+    0xb3, 0xc8, 0x09, 0xfe, 0x0e, 0x78, 0x72, 0x61, 0xcb, 0x61,
+    0x6f, 0x39, 0x91, 0x95, 0x4e, 0xd5, 0x3e, 0xc7, 0x8f, 0xb8,
+    0xf6, 0x36, 0xfe, 0x9c, 0x93, 0x9a, 0x38, 0x25, 0x7a, 0xf4,
+    0x4a, 0x12, 0xd4, 0xa0, 0x13, 0xbd, 0xf9, 0x1d, 0x12, 0x3e,
+    0x21, 0x39, 0xfb, 0x72, 0xe0, 0x05, 0x3d, 0xc3, 0xe5, 0x50,
+    0xa8, 0x5d, 0x85, 0xa3, 0xea, 0x5f, 0x1c, 0xb2, 0x3f, 0xea,
+    0x6d, 0x03, 0x91, 0x55, 0xd8, 0x19, 0x0a, 0x21, 0x12, 0x16,
+    0xd9, 0x12, 0xc4, 0xe6, 0x07, 0x18, 0x5b, 0x26, 0xa4, 0xae,
+    0xed, 0x2b, 0xb7, 0xa6, 0xed, 0xf8, 0xad, 0xec, 0x77, 0xe6,
+    0x7f, 0x4f, 0x76, 0x00, 0xc0, 0xfa, 0x15, 0x92, 0xb4, 0x2c,
+    0x22, 0xc2, 0xeb, 0x6a, 0xad, 0x14, 0x05, 0xb2, 0xe5, 0x8a,
+    0x9e, 0x85, 0x83, 0xcc, 0x04, 0xf1, 0x56, 0x78, 0x44, 0x5e,
+    0xde, 0xe0, 0x60, 0x1a, 0x65, 0x79, 0x31, 0x23, 0x05, 0xbb,
+    0x01, 0xff, 0xdd, 0x2e, 0xb7, 0xb3, 0xaa, 0x74, 0xe0, 0xa5,
+    0x94, 0xaf, 0x4b, 0xde, 0x58, 0x0f, 0x55, 0xde, 0x33, 0xf6,
+    0xe3, 0xd6, 0x34, 0x36, 0x57, 0xd6, 0x79, 0x91, 0x2e, 0xbe,
+    0x3b, 0xd9, 0x4e, 0xb6, 0x9d, 0x21, 0x5c, 0xd3, 0x48, 0x14,
+    0x7f, 0x4a, 0xc4, 0x60, 0xa9, 0x29, 0xf8, 0x53, 0x7f, 0x88,
+    0x11, 0x2d, 0xb5, 0xc5, 0x2d, 0x6f, 0xee, 0x85, 0x0b, 0xf7,
+    0x8d, 0x9a, 0xbe, 0xb0, 0x42, 0xf2, 0x2e, 0x71, 0xaf, 0x19,
+    0x31, 0x6d, 0xec, 0xcd, 0x6f, 0x2b, 0x23, 0xdf, 0xb4, 0x40,
+    0xaf, 0x2c, 0x0a, 0xc3, 0x1b, 0x7d, 0x7d, 0x03, 0x1d, 0x4b,
+    0xf3, 0xb5, 0xe0, 0x85, 0xd8, 0xdf, 0x91, 0x6b, 0x0a, 0x69,
+    0xf7, 0xf2, 0x69, 0x66, 0x5b, 0xf1, 0xcf, 0x46, 0x7d, 0xe9,
+    0x70, 0xfa, 0x6d, 0x7e, 0x75, 0x4e, 0xa9, 0x77, 0xe6, 0x8c,
+    0x02, 0xf7, 0x14, 0x4d, 0xa5, 0x41, 0x8f, 0x3f, 0xc1, 0x62,
+    0x1e, 0x71, 0x5e, 0x38, 0xb4, 0xd6, 0xe6, 0xe1, 0x4b, 0xc2,
+    0x2c, 0x30, 0x83, 0x81, 0x6f, 0x49, 0x2e, 0x96, 0xe6, 0xc9,
+    0x9a, 0xf7, 0x5d, 0x09, 0xa0, 0x55, 0x02, 0xa5, 0x3a, 0x25,
+    0x23, 0xd0, 0x92, 0xc3, 0xa3, 0xe3, 0x0e, 0x12, 0x2f, 0x4d,
+    0xef, 0xf3, 0x55, 0x5a, 0xbe, 0xe6, 0x19, 0x86, 0x31, 0xab,
+    0x75, 0x9a, 0xd3, 0xf0, 0x2c, 0xc5, 0x41, 0x92, 0xd9, 0x1f,
+    0x5f, 0x11, 0x8c, 0x75, 0x1c, 0x63, 0xd0, 0x02, 0x80, 0x2c,
+    0x68, 0xcb, 0x93, 0xfb, 0x51, 0x73, 0x49, 0xb4, 0x60, 0xda,
+    0xe2, 0x26, 0xaf, 0xa9, 0x46, 0x12, 0xb8, 0xec, 0x50, 0xdd,
+    0x12, 0x06, 0x5f, 0xce, 0x59, 0xe6, 0xf6, 0x1c, 0xe0, 0x54,
+    0x10, 0xad, 0xf6, 0xcd, 0x98, 0xcc, 0x0f, 0xfb, 0xcb, 0x41,
+    0x14, 0x9d, 0xed, 0xe4, 0xb4, 0x74, 0x5f, 0x09, 0x60, 0xc7,
+    0x12, 0xf6, 0x7b, 0x3c, 0x8f, 0xa7, 0x20, 0xbc, 0xe4, 0xb1,
+    0xef, 0xeb, 0xa4, 0x93, 0xc5, 0x06, 0xca, 0x9a, 0x27, 0x9d,
+    0x87, 0xf3, 0xde, 0xca, 0xe5, 0xe7, 0xf6, 0x1c, 0x01, 0x65,
+    0x5b, 0xfb, 0x19, 0x79, 0x6e, 0x08, 0x26, 0xc5, 0xc8, 0x28,
+    0x0e, 0xb6, 0x3b, 0x07, 0x08, 0xc1, 0x02, 0x82, 0x01, 0x01,
+    0x00, 0xe8, 0x1c, 0x73, 0xa6, 0xb8, 0xe0, 0x0e, 0x6d, 0x8d,
+    0x1b, 0xb9, 0x53, 0xed, 0x58, 0x94, 0xe6, 0x1d, 0x60, 0x14,
+    0x5c, 0x76, 0x43, 0xc4, 0x58, 0x19, 0xc4, 0x24, 0xe8, 0xbc,
+    0x1b, 0x3b, 0x0b, 0x13, 0x24, 0x45, 0x54, 0x0e, 0xcc, 0x37,
+    0xf0, 0xe0, 0x63, 0x7d, 0xc3, 0xf7, 0xfb, 0x81, 0x74, 0x81,
+    0xc4, 0x0f, 0x1a, 0x21, 0x48, 0xaf, 0xce, 0xc1, 0xc4, 0x94,
+    0x18, 0x06, 0x44, 0x8d, 0xd3, 0xd2, 0x22, 0x2d, 0x2d, 0x3e,
+    0x5a, 0x31, 0xdc, 0x95, 0x8e, 0xf4, 0x41, 0xfc, 0x58, 0xc9,
+    0x40, 0x92, 0x17, 0x5f, 0xe3, 0xda, 0xac, 0x9e, 0x3f, 0x1c,
+    0x2a, 0x6b, 0x58, 0x5f, 0x48, 0x78, 0x20, 0xb1, 0xaf, 0x24,
+    0x9b, 0x3c, 0x20, 0x8b, 0x93, 0x25, 0x9e, 0xe6, 0x6b, 0xbc,
+    0x13, 0x42, 0x14, 0x6c, 0x36, 0x31, 0xff, 0x7a, 0xd1, 0xc1,
+    0x1a, 0x26, 0x14, 0x7f, 0xa9, 0x76, 0xa7, 0x0c, 0xf8, 0xcc,
+    0xed, 0x07, 0x6a, 0xd2, 0xdf, 0x62, 0xee, 0x0a, 0x7c, 0x84,
+    0xcb, 0x49, 0x90, 0xb2, 0x03, 0x0d, 0xa2, 0x82, 0x06, 0x77,
+    0xf1, 0xcd, 0x67, 0xf2, 0x47, 0x21, 0x02, 0x3f, 0x43, 0x21,
+    0xf0, 0x46, 0x30, 0x62, 0x51, 0x72, 0xb1, 0xe7, 0x48, 0xc6,
+    0x67, 0x12, 0xcd, 0x9e, 0xd6, 0x15, 0xe5, 0x21, 0xed, 0xfa,
+    0x8f, 0x30, 0xa6, 0x41, 0xfe, 0xb6, 0xfa, 0x8f, 0x34, 0x14,
+    0x19, 0xe8, 0x11, 0xf7, 0xa5, 0x77, 0x3e, 0xb7, 0xf9, 0x39,
+    0x07, 0x8c, 0x67, 0x2a, 0xab, 0x7b, 0x08, 0xf8, 0xb0, 0x06,
+    0xa8, 0xea, 0x2f, 0x8f, 0xfa, 0xcc, 0xcc, 0x40, 0xce, 0xf3,
+    0x70, 0x4f, 0x3f, 0x7f, 0xe2, 0x0c, 0xea, 0x76, 0x4a, 0x35,
+    0x4e, 0x47, 0xad, 0x2b, 0xa7, 0x97, 0x5d, 0x74, 0x43, 0x97,
+    0x90, 0xd2, 0xfb, 0xd9, 0xf9, 0x96, 0x01, 0x33, 0x05, 0xed,
+    0x7b, 0x03, 0x05, 0xad, 0xf8, 0x49, 0x03, 0x02, 0x82, 0x01,
+    0x01, 0x00, 0xd4, 0x40, 0x17, 0x66, 0x10, 0x92, 0x95, 0xc8,
+    0xec, 0x62, 0xa9, 0x7a, 0xcb, 0x93, 0x8e, 0xe6, 0x53, 0xd4,
+    0x80, 0x48, 0x27, 0x4b, 0x41, 0xce, 0x61, 0xdf, 0xbf, 0x94,
+    0xa4, 0x3d, 0x71, 0x03, 0x0b, 0xed, 0x25, 0x71, 0x98, 0xa4,
+    0xd6, 0xd5, 0x4a, 0x57, 0xf5, 0x6c, 0x1b, 0xda, 0x21, 0x7d,
+    0x35, 0x45, 0xb3, 0xf3, 0x6a, 0xd9, 0xd3, 0x43, 0xe8, 0x5c,
+    0x54, 0x1c, 0x83, 0x1b, 0xb4, 0x5f, 0xf2, 0x97, 0x24, 0x2e,
+    0xdc, 0x40, 0xde, 0x92, 0x23, 0x59, 0x8e, 0xbc, 0xd2, 0xa1,
+    0xf2, 0xe0, 0x4c, 0xdd, 0x0b, 0xd1, 0xe7, 0xae, 0x65, 0xbc,
+    0xb5, 0xf5, 0x5b, 0x98, 0xe9, 0xd7, 0xc2, 0xb7, 0x0e, 0x55,
+    0x71, 0x0e, 0x3c, 0x0a, 0x24, 0x6b, 0xa6, 0xe6, 0x14, 0x61,
+    0x11, 0xfd, 0x33, 0x42, 0x99, 0x2b, 0x84, 0x77, 0x74, 0x92,
+    0x91, 0xf5, 0x79, 0x79, 0xcf, 0xad, 0x8e, 0x04, 0xef, 0x80,
+    0x1e, 0x57, 0xf4, 0x14, 0xf5, 0x35, 0x09, 0x74, 0xb2, 0x13,
+    0x71, 0x58, 0x6b, 0xea, 0x32, 0x5d, 0xf3, 0xd3, 0x76, 0x48,
+    0x39, 0x10, 0x23, 0x84, 0x9d, 0xbe, 0x92, 0x77, 0x4a, 0xed,
+    0x70, 0x3e, 0x1a, 0xa2, 0x6c, 0xb3, 0x81, 0x00, 0xc3, 0xc9,
+    0xe4, 0x52, 0xc8, 0x24, 0x88, 0x0c, 0x41, 0xad, 0x87, 0x5a,
+    0xea, 0xa3, 0x7a, 0x85, 0x1c, 0x5e, 0x31, 0x7f, 0xc3, 0x35,
+    0xc6, 0xfa, 0x10, 0xc8, 0x75, 0x10, 0xc4, 0x96, 0x99, 0xe7,
+    0xfe, 0x01, 0xb4, 0x74, 0xdb, 0xb4, 0x11, 0xc3, 0xc8, 0x8c,
+    0xf6, 0xf7, 0x3b, 0x66, 0x50, 0xfc, 0xdb, 0xeb, 0xca, 0x47,
+    0x85, 0x89, 0xe1, 0x65, 0xd9, 0x62, 0x34, 0x3c, 0x70, 0xd8,
+    0x2e, 0xb4, 0x2f, 0x65, 0x3c, 0x4a, 0xa6, 0x2a, 0xe7, 0xc7,
+    0xd8, 0x41, 0x8f, 0x8a, 0x43, 0xbf, 0x42, 0xf2, 0x4d, 0xbc,
+    0xfc, 0x9e, 0x27, 0x95, 0xfb, 0x75, 0xff, 0xab, 0x02, 0x82,
+    0x01, 0x00, 0x41, 0x2f, 0x44, 0x57, 0x6d, 0x12, 0x17, 0x5b,
+    0x32, 0xc6, 0xb7, 0x6c, 0x57, 0x7a, 0x8a, 0x0e, 0x79, 0xef,
+    0x72, 0xa8, 0x68, 0xda, 0x2d, 0x38, 0xe4, 0xbb, 0x8d, 0xf6,
+    0x02, 0x65, 0xcf, 0x56, 0x13, 0xe1, 0x1a, 0xcb, 0x39, 0x80,
+    0xa6, 0xb1, 0x32, 0x03, 0x1e, 0xdd, 0xbb, 0x35, 0xd9, 0xac,
+    0x43, 0x89, 0x31, 0x08, 0x90, 0x92, 0x5e, 0x35, 0x3d, 0x7b,
+    0x9c, 0x6f, 0x86, 0xcb, 0x17, 0xdd, 0x85, 0xe4, 0xed, 0x35,
+    0x08, 0x8e, 0xc1, 0xf4, 0x05, 0xd8, 0x68, 0xc6, 0x63, 0x3c,
+    0xf7, 0xff, 0xf7, 0x47, 0x33, 0x39, 0xc5, 0x3e, 0xb7, 0x0e,
+    0x58, 0x35, 0x9d, 0x81, 0xea, 0xf8, 0x6a, 0x2c, 0x1c, 0x5a,
+    0x68, 0x78, 0x64, 0x11, 0x6b, 0xc1, 0x3e, 0x4e, 0x7a, 0xbd,
+    0x84, 0xcb, 0x0f, 0xc2, 0xb6, 0x85, 0x1d, 0xd3, 0x76, 0xc5,
+    0x93, 0x6a, 0x69, 0x89, 0x56, 0x34, 0xdc, 0x4a, 0x9b, 0xbc,
+    0xff, 0xa8, 0x0d, 0x6e, 0x35, 0x9c, 0x60, 0xa7, 0x23, 0x30,
+    0xc7, 0x06, 0x64, 0x39, 0x8b, 0x94, 0x89, 0xee, 0xba, 0x7f,
+    0x60, 0x8d, 0xfa, 0xb6, 0x97, 0x76, 0xdc, 0x51, 0x4a, 0x3c,
+    0xeb, 0x3a, 0x14, 0x2c, 0x20, 0x60, 0x69, 0x4a, 0x86, 0xfe,
+    0x8c, 0x21, 0x84, 0x49, 0x54, 0xb3, 0x20, 0xe1, 0x01, 0x7f,
+    0x58, 0xdf, 0x7f, 0xb5, 0x21, 0x51, 0x8c, 0x47, 0x9f, 0x91,
+    0xeb, 0x97, 0x3e, 0xf2, 0x54, 0xcf, 0x16, 0x46, 0xf9, 0xd9,
+    0xb6, 0xe7, 0x64, 0xc9, 0xd0, 0x54, 0xea, 0x2f, 0xa1, 0xcf,
+    0xa5, 0x7f, 0x28, 0x8d, 0x84, 0xec, 0xd5, 0x39, 0x03, 0x76,
+    0x5b, 0x2d, 0x8e, 0x43, 0xf2, 0x01, 0x24, 0xc9, 0x6f, 0xc0,
+    0xf5, 0x69, 0x6f, 0x7d, 0xb5, 0x85, 0xd2, 0x5f, 0x7f, 0x78,
+    0x40, 0x07, 0x7f, 0x09, 0x15, 0xb5, 0x1f, 0x28, 0x65, 0x10,
+    0xe4, 0x19, 0xa8, 0xc6, 0x9e, 0x8d, 0xdc, 0xcb, 0x02, 0x82,
+    0x01, 0x00, 0x13, 0x01, 0xee, 0x56, 0x80, 0x93, 0x70, 0x00,
+    0x7f, 0x52, 0xd2, 0x94, 0xa1, 0x98, 0x84, 0x4a, 0x92, 0x25,
+    0x4c, 0x9b, 0xa9, 0x91, 0x2e, 0xc2, 0x79, 0xb7, 0x5c, 0xe3,
+    0xc5, 0xd5, 0x8e, 0xc2, 0x54, 0x16, 0x17, 0xad, 0x55, 0x9b,
+    0x25, 0x76, 0x12, 0x63, 0x50, 0x22, 0x2f, 0x58, 0x58, 0x79,
+    0x6b, 0x04, 0xe3, 0xf9, 0x9f, 0x8f, 0x04, 0x41, 0x67, 0x94,
+    0xa5, 0x1f, 0xac, 0x8a, 0x15, 0x9c, 0x26, 0x10, 0x6c, 0xf8,
+    0x19, 0x57, 0x61, 0xd7, 0x3a, 0x7d, 0x31, 0xb0, 0x2d, 0x38,
+    0xbd, 0x94, 0x62, 0xad, 0xc4, 0xfa, 0x36, 0x42, 0x42, 0xf0,
+    0x24, 0x67, 0x65, 0x9d, 0x8b, 0x0b, 0x7c, 0x6f, 0x82, 0x44,
+    0x1a, 0x8c, 0xc8, 0xc9, 0xab, 0xbb, 0x4c, 0x45, 0xfc, 0x7b,
+    0x38, 0xee, 0x30, 0xe1, 0xfc, 0xef, 0x8d, 0xbc, 0x58, 0xdf,
+    0x2b, 0x5d, 0x0d, 0x54, 0xe0, 0x49, 0x4d, 0x97, 0x99, 0x8f,
+    0x22, 0xa8, 0x83, 0xbe, 0x40, 0xbb, 0x50, 0x2e, 0x78, 0x28,
+    0x0f, 0x95, 0x78, 0x8c, 0x8f, 0x98, 0x24, 0x56, 0xc2, 0x97,
+    0xf3, 0x2c, 0x43, 0xd2, 0x03, 0x82, 0x66, 0x81, 0x72, 0x5f,
+    0x53, 0x16, 0xec, 0xb1, 0xb1, 0x04, 0x5e, 0x40, 0x20, 0x48,
+    0x7b, 0x3f, 0x02, 0x97, 0x6a, 0xeb, 0x96, 0x12, 0x21, 0x35,
+    0xfe, 0x1f, 0x47, 0xc0, 0x95, 0xea, 0xc5, 0x8a, 0x08, 0x84,
+    0x4f, 0x5e, 0x63, 0x94, 0x60, 0x0f, 0x71, 0x5b, 0x7f, 0x4a,
+    0xec, 0x4f, 0x60, 0xc6, 0xba, 0x4a, 0x24, 0xf1, 0x20, 0x8b,
+    0xa7, 0x2e, 0x3a, 0xce, 0x8d, 0xe0, 0x27, 0x1d, 0xb5, 0x8e,
+    0xb4, 0x21, 0xc5, 0xe2, 0xa6, 0x16, 0x0a, 0x51, 0x83, 0x55,
+    0x88, 0xd1, 0x30, 0x11, 0x63, 0xd5, 0xd7, 0x8d, 0xae, 0x16,
+    0x12, 0x82, 0xc4, 0x85, 0x00, 0x4e, 0x27, 0x83, 0xa5, 0x7c,
+    0x90, 0x2e, 0xe5, 0xa2, 0xa3, 0xd3, 0x4c, 0x63, 0x02, 0x82,
+    0x01, 0x01, 0x00, 0x86, 0x08, 0x98, 0x98, 0xa5, 0x00, 0x05,
+    0x39, 0x77, 0xd9, 0x66, 0xb3, 0xcf, 0xca, 0xa0, 0x71, 0xb3,
+    0x50, 0xce, 0x3d, 0xb1, 0x93, 0x95, 0x35, 0xc4, 0xd4, 0x2e,
+    0x90, 0xdf, 0x0f, 0xfc, 0x60, 0xc1, 0x94, 0x68, 0x61, 0x43,
+    0xca, 0x9a, 0x23, 0x4a, 0x1e, 0x45, 0x72, 0x99, 0xb5, 0x1e,
+    0x61, 0x8d, 0x77, 0x0f, 0xa0, 0xbb, 0xd7, 0x77, 0xb4, 0x2a,
+    0x15, 0x11, 0x88, 0x2d, 0xb3, 0x56, 0x61, 0x5e, 0x6a, 0xed,
+    0xa4, 0x46, 0x4a, 0x3f, 0x50, 0x11, 0xd6, 0xba, 0xb6, 0xd7,
+    0x95, 0x65, 0x53, 0xc3, 0xa1, 0x8f, 0xe0, 0xa3, 0xf5, 0x1c,
+    0xfd, 0xaf, 0x6e, 0x43, 0xd7, 0x17, 0xa7, 0xd3, 0x81, 0x1b,
+    0xa4, 0xdf, 0xe0, 0x97, 0x8a, 0x46, 0x03, 0xd3, 0x46, 0x0e,
+    0x83, 0x48, 0x4e, 0xd2, 0x02, 0xcb, 0xc0, 0xad, 0x79, 0x95,
+    0x8c, 0x96, 0xba, 0x40, 0x34, 0x11, 0x71, 0x5e, 0xe9, 0x11,
+    0xf9, 0xc5, 0x4a, 0x5e, 0x91, 0x9d, 0xf5, 0x92, 0x4f, 0xeb,
+    0xc6, 0x70, 0x02, 0x2d, 0x3d, 0x04, 0xaa, 0xe9, 0x3a, 0x8e,
+    0xd5, 0xa8, 0xad, 0xf7, 0xce, 0x0d, 0x16, 0xb2, 0xec, 0x0a,
+    0x9c, 0xf5, 0x94, 0x39, 0xb9, 0x8a, 0xfc, 0x1e, 0xf9, 0xcc,
+    0xf2, 0x5f, 0x21, 0x31, 0x74, 0x72, 0x6b, 0x64, 0xae, 0x35,
+    0x61, 0x8d, 0x0d, 0xcb, 0xe7, 0xda, 0x39, 0xca, 0xf3, 0x21,
+    0x66, 0x0b, 0x95, 0xd7, 0x0a, 0x7c, 0xca, 0xa1, 0xa9, 0x5a,
+    0xe8, 0xac, 0xe0, 0x71, 0x54, 0xaf, 0x28, 0xcf, 0xd5, 0x70,
+    0x89, 0xe0, 0xf3, 0x9e, 0x43, 0x6c, 0x8d, 0x7b, 0x99, 0x01,
+    0x68, 0x4d, 0xa1, 0x45, 0x46, 0x0c, 0x43, 0xbc, 0xcc, 0x2c,
+    0xdd, 0xc5, 0x46, 0xc8, 0x4e, 0x0e, 0xbe, 0xed, 0xb9, 0x26,
+    0xab, 0x2e, 0xdb, 0xeb, 0x8f, 0xff, 0xdb, 0xb0, 0xc6, 0x55,
+    0xaf, 0xf8, 0x2a, 0x91, 0x9d, 0x50, 0x44, 0x21, 0x17,
+};
+
+static unsigned char test7680[] = {
+    0x30, 0x82, 0x11, 0x09, 0x02, 0x01, 0x00, 0x02, 0x82, 0x03,
+    0xc1, 0x00, 0xe3, 0x27, 0x46, 0x99, 0xb5, 0x17, 0xab, 0xfa,
+    0x65, 0x05, 0x7a, 0x06, 0x81, 0x14, 0xce, 0x43, 0x21, 0x49,
+    0x0f, 0x08, 0xf1, 0x70, 0xb4, 0xc1, 0x10, 0xd1, 0x87, 0xf8,
+    0x29, 0x91, 0x36, 0x66, 0x2d, 0xbe, 0x7b, 0x1d, 0xa2, 0x0b,
+    0x20, 0x38, 0xd9, 0x8e, 0x78, 0x27, 0xcf, 0xb5, 0x45, 0x58,
+    0x3d, 0xf4, 0xda, 0xf0, 0xdc, 0x21, 0x17, 0x52, 0xcd, 0x68,
+    0xe2, 0x81, 0xac, 0x88, 0x61, 0x10, 0xbc, 0xb0, 0x7f, 0xe4,
+    0xf3, 0x78, 0xb7, 0x28, 0x6c, 0x5f, 0x5c, 0xc2, 0x8d, 0x3d,
+    0xb0, 0x87, 0x41, 0x15, 0x2e, 0x09, 0x5f, 0xea, 0x06, 0x7f,
+    0xe9, 0x35, 0x18, 0x90, 0x50, 0xad, 0xf6, 0xb9, 0xfd, 0x33,
+    0x02, 0x1a, 0x99, 0x9e, 0xa5, 0x7d, 0x2c, 0x3b, 0x24, 0xe7,
+    0x31, 0x35, 0x73, 0x9a, 0xb0, 0xfe, 0x03, 0xfc, 0xc6, 0x98,
+    0x78, 0xd9, 0x66, 0x95, 0xa5, 0x12, 0xbc, 0x1e, 0x82, 0xbc,
+    0xf1, 0xc5, 0x31, 0xcd, 0xa6, 0xb1, 0x0c, 0x02, 0xbf, 0x7f,
+    0xb7, 0xaf, 0x5f, 0xd6, 0xed, 0xf7, 0xc1, 0x59, 0x86, 0x3a,
+    0x35, 0x95, 0x54, 0x21, 0x8d, 0x6a, 0xb3, 0xd1, 0x2b, 0x71,
+    0xf5, 0xf1, 0x66, 0x00, 0xb1, 0x88, 0xee, 0x3b, 0xa4, 0x41,
+    0x52, 0x1a, 0xf5, 0x0e, 0x32, 0xb6, 0xbf, 0x52, 0xab, 0x51,
+    0x55, 0x91, 0x32, 0x4f, 0xaf, 0x91, 0xac, 0xf7, 0xff, 0x8e,
+    0x3b, 0x2b, 0x61, 0xe9, 0x6d, 0x1d, 0x68, 0x80, 0x90, 0x79,
+    0x34, 0x96, 0xca, 0x49, 0x43, 0x7c, 0x89, 0x4e, 0x5e, 0x31,
+    0xb5, 0xce, 0x01, 0x9b, 0x09, 0xaf, 0x92, 0x06, 0x24, 0xe7,
+    0x22, 0x35, 0xcc, 0xa2, 0x0b, 0xfb, 0x5b, 0x87, 0x65, 0x71,
+    0xff, 0x64, 0x3e, 0xf9, 0xe8, 0x33, 0xa0, 0xc3, 0x4e, 0xb2,
+    0x41, 0x98, 0x54, 0xeb, 0x13, 0x99, 0xfb, 0x32, 0x78, 0x7e,
+    0xda, 0x4f, 0xd3, 0x46, 0x6a, 0xb5, 0x78, 0x81, 0x3f, 0x04,
+    0x13, 0x5f, 0x67, 0xaf, 0x88, 0xa5, 0x9e, 0x0d, 0xc5, 0xf3,
+    0xe7, 0x4c, 0x51, 0xf5, 0x51, 0x4a, 0xa4, 0x58, 0x64, 0xd9,
+    0xa2, 0x32, 0x54, 0x36, 0xce, 0x38, 0xd8, 0xc2, 0x0e, 0x0d,
+    0x60, 0x8e, 0x32, 0x7f, 0x90, 0x8a, 0xbc, 0x88, 0xbe, 0x6a,
+    0xc0, 0x47, 0x0f, 0x02, 0x41, 0xff, 0x3b, 0x7e, 0xc5, 0xa6,
+    0x33, 0x1d, 0x19, 0xd1, 0xd5, 0x67, 0x6c, 0xbf, 0x16, 0xb0,
+    0x7e, 0x80, 0x10, 0xbf, 0x7f, 0xdd, 0xd0, 0xf4, 0xc3, 0x94,
+    0x2c, 0x9a, 0x2c, 0xda, 0x69, 0x4e, 0xd6, 0x7b, 0x40, 0x4d,
+    0x2a, 0x27, 0xcb, 0x5a, 0xe5, 0x2d, 0x3f, 0x7d, 0x51, 0x9d,
+    0x9f, 0x70, 0xde, 0x50, 0xb1, 0xd3, 0xd2, 0x38, 0x4d, 0x1c,
+    0xca, 0xc2, 0x1e, 0x80, 0xd0, 0x36, 0x82, 0x04, 0xe6, 0x17,
+    0x79, 0x9f, 0x2e, 0xc9, 0xed, 0x2b, 0xd5, 0x1b, 0xfa, 0x7d,
+    0x1a, 0x80, 0xb5, 0x0e, 0x2f, 0x05, 0xbe, 0x4a, 0x1b, 0xfe,
+    0x0a, 0xad, 0x01, 0xde, 0x91, 0xc8, 0xf9, 0x81, 0xbe, 0xc7,
+    0xaf, 0xe7, 0x87, 0xed, 0x9d, 0xb8, 0x6c, 0xad, 0x65, 0xed,
+    0x5e, 0xd3, 0x67, 0x8c, 0x62, 0x3a, 0xe7, 0xfd, 0x67, 0xe0,
+    0xbb, 0x57, 0xaf, 0x56, 0xeb, 0x4a, 0x58, 0x6e, 0xad, 0xf2,
+    0xbe, 0xc3, 0x70, 0x29, 0xf8, 0xeb, 0x68, 0x45, 0xa0, 0xbd,
+    0xcd, 0xa5, 0xb4, 0xd9, 0x01, 0xb7, 0x44, 0xeb, 0x97, 0xf3,
+    0x0c, 0x56, 0xe4, 0x26, 0xd0, 0xa5, 0xb1, 0xa3, 0x49, 0x6e,
+    0x88, 0xf2, 0x22, 0xe2, 0x7b, 0x58, 0x3a, 0xd9, 0x52, 0xa4,
+    0xb1, 0x4c, 0x5c, 0x7c, 0xf0, 0x88, 0x7b, 0x9f, 0x06, 0xe9,
+    0x32, 0x4e, 0xf2, 0x64, 0x83, 0x8b, 0xa2, 0xea, 0x1d, 0x25,
+    0xf1, 0x8d, 0x16, 0x8b, 0xe0, 0xab, 0xd2, 0xe9, 0xe4, 0x6b,
+    0x7d, 0x76, 0x98, 0x22, 0x53, 0x31, 0x6b, 0xcc, 0xf1, 0xe5,
+    0x1d, 0xd7, 0xa5, 0xb0, 0xea, 0x6b, 0x38, 0x14, 0x0c, 0x06,
+    0x10, 0x27, 0xd8, 0x33, 0xf3, 0x9a, 0xae, 0x94, 0xdd, 0x0b,
+    0xb4, 0x6d, 0xe5, 0x91, 0xdd, 0xf1, 0x0f, 0x27, 0xa4, 0x94,
+    0x55, 0xf0, 0xde, 0x07, 0x29, 0xe6, 0x3f, 0x26, 0x19, 0xa1,
+    0xdd, 0xd1, 0x06, 0x99, 0xda, 0x54, 0x23, 0x3c, 0xf5, 0x5c,
+    0x2e, 0x96, 0xa9, 0x21, 0x23, 0x25, 0x2e, 0x6f, 0xf1, 0xf9,
+    0x11, 0x54, 0xe5, 0x7b, 0xb9, 0x1f, 0x11, 0xe2, 0x9e, 0x6b,
+    0x61, 0x8b, 0xa3, 0x8b, 0xc1, 0x20, 0x9b, 0xfb, 0x51, 0xef,
+    0xbb, 0xb9, 0xf6, 0xaf, 0x66, 0xb3, 0x2c, 0x25, 0xef, 0x76,
+    0xcb, 0xbf, 0x7a, 0x93, 0x2f, 0xe1, 0x17, 0x56, 0xc1, 0x00,
+    0x33, 0xb5, 0xd9, 0x91, 0x05, 0x31, 0xcc, 0x72, 0xcd, 0x4a,
+    0x93, 0x9a, 0xe3, 0x21, 0x42, 0x9e, 0xb8, 0x4e, 0x6c, 0x27,
+    0x93, 0xf0, 0x7f, 0x22, 0xdb, 0xe5, 0xb3, 0xa3, 0xf7, 0xe7,
+    0x80, 0xbb, 0x91, 0xca, 0xf7, 0xe8, 0x52, 0xb8, 0x11, 0x64,
+    0x66, 0x25, 0x94, 0xf8, 0x6f, 0x0b, 0x3b, 0xb7, 0xff, 0x80,
+    0x9e, 0x36, 0xe9, 0x88, 0x2e, 0xab, 0x05, 0xbf, 0x99, 0x9f,
+    0x2b, 0x4f, 0xc6, 0xb1, 0x13, 0x5b, 0x06, 0xff, 0x0a, 0x7b,
+    0xbc, 0x7f, 0x07, 0xa0, 0x35, 0xc2, 0x2d, 0x44, 0x3e, 0xad,
+    0x44, 0xcb, 0x47, 0x18, 0x26, 0x71, 0x7b, 0x17, 0xc9, 0x6d,
+    0xb5, 0x4b, 0xcf, 0xdf, 0x14, 0x2c, 0x6c, 0xdf, 0x21, 0xce,
+    0x93, 0x49, 0x34, 0x69, 0x49, 0xfd, 0x3e, 0x71, 0x5b, 0xfa,
+    0x07, 0xc5, 0x7e, 0x5e, 0x54, 0x1a, 0x3c, 0xa6, 0x29, 0xb5,
+    0xbf, 0x0d, 0xf1, 0xc6, 0xa4, 0x61, 0xd6, 0x17, 0x1d, 0xf0,
+    0xa2, 0x78, 0x8f, 0xbc, 0x7e, 0x0c, 0xb4, 0xf0, 0x1e, 0x05,
+    0xea, 0xb5, 0xad, 0x68, 0x95, 0x0b, 0x27, 0xb4, 0x29, 0x7c,
+    0x70, 0x2a, 0x9a, 0x0a, 0x39, 0xd4, 0x76, 0xb7, 0x72, 0x30,
+    0x5e, 0xae, 0x9c, 0x4a, 0x55, 0xc7, 0x46, 0xd7, 0x5f, 0xbe,
+    0x10, 0x61, 0x25, 0x18, 0x7a, 0x9f, 0xd3, 0x05, 0x3d, 0x6f,
+    0x9a, 0x1e, 0xec, 0x2b, 0x03, 0xe0, 0x49, 0x6a, 0x9c, 0xd6,
+    0xdb, 0xc2, 0xa1, 0xe1, 0x0a, 0xbb, 0x31, 0x42, 0xc8, 0x43,
+    0x4e, 0x7c, 0xa9, 0x7c, 0x60, 0xea, 0xbe, 0xf1, 0x8b, 0xe8,
+    0xb2, 0x90, 0x83, 0x14, 0x21, 0xe4, 0xb3, 0x0d, 0x7c, 0x63,
+    0x3c, 0x98, 0x55, 0xc6, 0x44, 0xa6, 0xa8, 0x1e, 0x42, 0xb7,
+    0x89, 0xa8, 0xbd, 0xb8, 0x34, 0x3d, 0x09, 0x80, 0x99, 0x73,
+    0x9f, 0xaf, 0x17, 0x56, 0xf2, 0x73, 0x3e, 0x1e, 0x6e, 0xe9,
+    0x18, 0xa0, 0x5b, 0x69, 0xce, 0xfd, 0x3d, 0x77, 0x81, 0x95,
+    0x3b, 0xf1, 0xde, 0x26, 0xe9, 0x27, 0xef, 0x92, 0x2a, 0x97,
+    0xdc, 0x95, 0xa5, 0xa3, 0xb0, 0xfb, 0x96, 0x89, 0x4f, 0xe6,
+    0xc1, 0x42, 0x0b, 0xfd, 0xb4, 0x6d, 0x0a, 0x9f, 0x9b, 0x31,
+    0xd8, 0x21, 0x38, 0x8a, 0xee, 0xb6, 0x5c, 0x12, 0xa8, 0xb4,
+    0x07, 0x79, 0x41, 0xa7, 0x7f, 0x13, 0x74, 0xad, 0x0b, 0xee,
+    0x28, 0x52, 0xac, 0x2f, 0x4d, 0x30, 0x1c, 0xc5, 0xa6, 0xa5,
+    0x61, 0x42, 0xbd, 0xe1, 0x4f, 0xd3, 0xec, 0x66, 0xf2, 0x63,
+    0xf4, 0x93, 0xdb, 0x35, 0x2d, 0x3b, 0x71, 0x25, 0x09, 0xde,
+    0xda, 0x46, 0xda, 0xe2, 0xa7, 0xa3, 0xdf, 0xcd, 0xbf, 0x58,
+    0x05, 0x25, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x03,
+    0xc0, 0x5f, 0xd5, 0x15, 0x1b, 0x09, 0xe4, 0xa7, 0xc0, 0xa6,
+    0xd8, 0x0d, 0xa8, 0x2a, 0xd3, 0x1d, 0x46, 0x03, 0x07, 0xf0,
+    0x98, 0xe4, 0x4b, 0x99, 0x66, 0x8e, 0x72, 0xe7, 0xbb, 0x51,
+    0xc6, 0x1a, 0xbe, 0x36, 0xf4, 0x52, 0xba, 0xa8, 0xbf, 0xaa,
+    0xe3, 0x71, 0x1d, 0x83, 0x21, 0xc0, 0xa6, 0x88, 0x4f, 0xf7,
+    0x2b, 0x93, 0x26, 0xe4, 0xa7, 0xed, 0x50, 0x18, 0xaa, 0xf4,
+    0x4c, 0xa2, 0xfe, 0x92, 0x7c, 0xde, 0x2e, 0x54, 0x76, 0xc2,
+    0x25, 0x1e, 0x98, 0xa6, 0x48, 0x01, 0x39, 0x6f, 0x1f, 0x24,
+    0x97, 0x9b, 0x64, 0x95, 0x1c, 0x8d, 0x63, 0x8d, 0x44, 0x6f,
+    0x9d, 0xdf, 0xf4, 0x1a, 0xa5, 0x9a, 0x1e, 0xd3, 0x6c, 0xae,
+    0xa9, 0x8c, 0x3f, 0xfb, 0x2f, 0x78, 0xf6, 0xa6, 0xd6, 0x06,
+    0xd3, 0xb7, 0x26, 0xff, 0x1e, 0xdb, 0x8d, 0xcc, 0x37, 0x4d,
+    0x5c, 0xe2, 0xc3, 0xa5, 0x75, 0xe6, 0xf9, 0xb4, 0x4c, 0x84,
+    0x6f, 0x9e, 0x58, 0x55, 0xc8, 0x01, 0xfa, 0x32, 0xd2, 0x6e,
+    0x2b, 0x45, 0xf2, 0xc6, 0x48, 0xad, 0x40, 0xd8, 0xb9, 0x3c,
+    0x1b, 0xf8, 0xf7, 0x82, 0xd3, 0x0e, 0x73, 0xe3, 0xb1, 0x5b,
+    0x82, 0x71, 0x77, 0x3f, 0x6f, 0x36, 0x9a, 0xe0, 0xec, 0x51,
+    0xf8, 0x5f, 0x84, 0x92, 0xee, 0xb8, 0x7e, 0xe7, 0x1a, 0x14,
+    0x50, 0x82, 0x7a, 0x4d, 0xe6, 0xd6, 0xa3, 0x76, 0x24, 0x8a,
+    0x5f, 0xfe, 0x19, 0xdd, 0xd7, 0xf7, 0x5b, 0xae, 0x18, 0x04,
+    0x90, 0xcd, 0x5c, 0xe5, 0x64, 0xe8, 0x04, 0xb1, 0x06, 0xa5,
+    0xdd, 0xf8, 0x9d, 0x71, 0x13, 0xaa, 0x36, 0x7f, 0x61, 0x27,
+    0xf4, 0xac, 0x95, 0x7d, 0x1a, 0x99, 0x7d, 0xe0, 0xd5, 0x9c,
+    0x5a, 0xad, 0x9a, 0xff, 0x54, 0xb0, 0xb1, 0x55, 0x45, 0x2d,
+    0x19, 0x58, 0x52, 0x28, 0xdd, 0xe0, 0xb5, 0x65, 0x52, 0x97,
+    0x45, 0xf0, 0x2b, 0x98, 0x1f, 0x61, 0x6c, 0x9d, 0xaa, 0x59,
+    0x85, 0xf9, 0x97, 0x7b, 0xbd, 0xeb, 0x95, 0x81, 0xfb, 0x29,
+    0x8c, 0xf0, 0x52, 0xdf, 0xed, 0xee, 0xb2, 0x00, 0x32, 0x35,
+    0x14, 0xa8, 0xa4, 0xca, 0x91, 0xff, 0x18, 0xb7, 0x96, 0xfb,
+    0x32, 0x62, 0xa9, 0xa0, 0xd0, 0x77, 0x43, 0xf5, 0x99, 0xd1,
+    0xee, 0xe8, 0xad, 0x1a, 0x2c, 0xd4, 0xeb, 0xe1, 0xf5, 0x01,
+    0x41, 0x78, 0xc0, 0x27, 0x19, 0x50, 0x2e, 0xba, 0x22, 0xd1,
+    0xeb, 0xb3, 0xa5, 0x27, 0x0b, 0xec, 0xf9, 0x26, 0x7e, 0x1f,
+    0xe7, 0x17, 0x9f, 0x39, 0xa8, 0x72, 0x22, 0x63, 0x79, 0x6a,
+    0x9c, 0x89, 0x55, 0x9a, 0xb4, 0x61, 0x41, 0xbc, 0xaa, 0x14,
+    0x37, 0x29, 0x03, 0xc0, 0x52, 0x4e, 0x31, 0x44, 0x8f, 0x2e,
+    0x17, 0x81, 0x88, 0xf4, 0xce, 0xda, 0x41, 0xb8, 0xd5, 0x14,
+    0x91, 0x8c, 0xca, 0xd2, 0x0d, 0x99, 0x06, 0x09, 0xc2, 0xb7,
+    0xe8, 0xae, 0xfa, 0x01, 0xea, 0x99, 0x62, 0x68, 0xb6, 0xdf,
+    0xc8, 0x27, 0xae, 0xbf, 0xb0, 0x9b, 0x5b, 0x1a, 0xa2, 0xe2,
+    0x5a, 0x7a, 0xe5, 0x4b, 0x92, 0x1f, 0xff, 0x73, 0xae, 0x16,
+    0x40, 0x78, 0x42, 0x28, 0xbb, 0x13, 0x5e, 0xbc, 0x71, 0x7a,
+    0x78, 0x3e, 0xd8, 0x1b, 0xc2, 0x2c, 0xd6, 0xdc, 0xfa, 0x39,
+    0x72, 0xf8, 0xa2, 0x2c, 0x8b, 0x1c, 0x5d, 0xab, 0xb8, 0x07,
+    0xc7, 0xae, 0x29, 0x93, 0x68, 0xbf, 0x61, 0xe9, 0xa4, 0x37,
+    0x83, 0x7d, 0x13, 0xc7, 0x18, 0xf0, 0x7d, 0xa4, 0x20, 0x47,
+    0x14, 0x68, 0x95, 0x46, 0x56, 0x6d, 0xd5, 0x7b, 0xe1, 0x51,
+    0x8f, 0x96, 0xc1, 0x7b, 0x35, 0x09, 0x7a, 0x89, 0x0e, 0xdf,
+    0x12, 0xd5, 0xe1, 0x9c, 0x2a, 0x94, 0x95, 0x43, 0x93, 0x48,
+    0xa6, 0x23, 0xe6, 0xd8, 0xf2, 0xb8, 0x0e, 0xba, 0x6d, 0x61,
+    0x03, 0xaf, 0x40, 0x63, 0x2b, 0x2f, 0xee, 0x61, 0x4c, 0xc4,
+    0x70, 0x3d, 0x78, 0xc1, 0x4f, 0x8e, 0x0b, 0x9b, 0x06, 0x35,
+    0x6d, 0x6d, 0x83, 0x37, 0xbb, 0x39, 0x7d, 0x7f, 0x33, 0x93,
+    0xc4, 0xeb, 0x8e, 0xfc, 0xda, 0xf0, 0x54, 0xfe, 0x1d, 0xc4,
+    0xd3, 0x83, 0x99, 0xdf, 0x65, 0xee, 0x00, 0x7d, 0x86, 0x27,
+    0xd4, 0x3a, 0x6b, 0xe6, 0x82, 0x8e, 0x58, 0x2d, 0x03, 0x38,
+    0xef, 0x6c, 0x82, 0x87, 0x18, 0x3b, 0x47, 0xe7, 0xbc, 0xe1,
+    0x58, 0x70, 0x4d, 0x46, 0x96, 0x34, 0x60, 0x96, 0x15, 0x09,
+    0x3c, 0x84, 0x40, 0xaf, 0x80, 0x32, 0x75, 0xc7, 0x23, 0x6c,
+    0xfb, 0x1d, 0x57, 0x73, 0x19, 0x09, 0xe8, 0x1a, 0x4c, 0x02,
+    0x5c, 0x7e, 0x4e, 0xbe, 0x75, 0xf8, 0x73, 0xff, 0x2d, 0x54,
+    0x19, 0x55, 0xf5, 0xf4, 0x1b, 0xc9, 0xbc, 0xc2, 0x19, 0xcb,
+    0xb7, 0x4e, 0x6a, 0x0d, 0xff, 0xca, 0x7d, 0xd0, 0x88, 0x91,
+    0x8b, 0x9b, 0x21, 0xa4, 0xa2, 0x43, 0x0d, 0xbc, 0x9e, 0x73,
+    0x7d, 0x54, 0x7d, 0x95, 0xcc, 0x63, 0x5e, 0xc1, 0xb8, 0xe6,
+    0x27, 0xff, 0x20, 0x07, 0xe8, 0x6e, 0x7e, 0xf2, 0x0f, 0x5a,
+    0x09, 0xef, 0xe5, 0x4d, 0x80, 0x39, 0x95, 0xd5, 0xf4, 0xee,
+    0x3b, 0xca, 0x7c, 0x73, 0xf8, 0x39, 0x5a, 0xc1, 0x1d, 0x7d,
+    0x94, 0x72, 0x32, 0xad, 0x58, 0xe2, 0xfc, 0x71, 0x6e, 0x66,
+    0xaa, 0xa1, 0x59, 0xd6, 0xac, 0xab, 0xbe, 0x8c, 0x53, 0x99,
+    0xcd, 0xe8, 0x2d, 0xb5, 0xb3, 0x46, 0x58, 0x2e, 0x16, 0xd7,
+    0x4d, 0x8b, 0x7d, 0x4a, 0xb1, 0x4c, 0x85, 0x91, 0x1b, 0x57,
+    0x54, 0xf8, 0x14, 0x59, 0xdb, 0xc4, 0x2c, 0x9c, 0x08, 0x6d,
+    0x3d, 0xd7, 0xf6, 0xa6, 0xe6, 0xb3, 0x2a, 0xe7, 0x29, 0x1c,
+    0xab, 0xb4, 0xed, 0x13, 0x19, 0xf8, 0xb6, 0x60, 0x92, 0x44,
+    0x53, 0xd4, 0xa9, 0x7e, 0xba, 0x21, 0xa2, 0xdc, 0x6e, 0xa5,
+    0x5e, 0x53, 0x59, 0x3c, 0x52, 0x61, 0x7b, 0x5f, 0x19, 0xad,
+    0xc8, 0x6d, 0x68, 0x8d, 0x7a, 0xc9, 0xd6, 0xef, 0xeb, 0x67,
+    0x4f, 0xca, 0xe7, 0xf6, 0x29, 0x36, 0x97, 0xfb, 0x3e, 0x37,
+    0x95, 0x85, 0x71, 0x70, 0xf6, 0x63, 0x86, 0x2a, 0x29, 0xd7,
+    0x9a, 0x96, 0x76, 0xa7, 0x47, 0x98, 0x4e, 0x06, 0x31, 0xaf,
+    0xf3, 0x4f, 0x2a, 0x65, 0x90, 0x6a, 0x4b, 0x8e, 0x43, 0x79,
+    0xe2, 0xdd, 0xce, 0x08, 0x1c, 0x01, 0xec, 0x38, 0x41, 0xdd,
+    0x19, 0xd8, 0xf3, 0x36, 0x03, 0x35, 0x03, 0xaf, 0x1c, 0x45,
+    0x3c, 0xac, 0x13, 0xaa, 0x36, 0x16, 0x48, 0x77, 0xb3, 0xbe,
+    0xa3, 0xb3, 0x9d, 0x7f, 0x20, 0xca, 0x74, 0x65, 0xac, 0x93,
+    0xa7, 0x54, 0xad, 0xc8, 0x68, 0x0e, 0xf8, 0x44, 0x1f, 0xad,
+    0x2c, 0xb7, 0x9a, 0x9a, 0x07, 0xe5, 0xcd, 0x87, 0xe0, 0x14,
+    0xb5, 0xaf, 0xd3, 0xd7, 0xcf, 0x13, 0x9f, 0x3b, 0xbd, 0xfe,
+    0x29, 0x0b, 0x72, 0xf5, 0x4c, 0x54, 0x94, 0xc7, 0x66, 0xec,
+    0xa8, 0x41, 0x96, 0x3d, 0x17, 0xed, 0x19, 0xc0, 0x82, 0x3e,
+    0x5f, 0x9a, 0x91, 0xfe, 0xd1, 0x2f, 0xb8, 0x94, 0xaa, 0x58,
+    0x68, 0x95, 0x31, 0x87, 0x57, 0x9a, 0x75, 0x94, 0x4d, 0x38,
+    0x7d, 0x56, 0x82, 0x81, 0x9c, 0xb9, 0x34, 0x2b, 0xe7, 0x40,
+    0xd9, 0x3c, 0x77, 0x5b, 0x95, 0x51, 0x06, 0x11, 0x41, 0xe3,
+    0x8b, 0xb7, 0x32, 0xeb, 0xe1, 0x05, 0x1b, 0x10, 0xa8, 0x0e,
+    0xa1, 0x02, 0x82, 0x01, 0xe1, 0x00, 0xfa, 0x38, 0x34, 0xfe,
+    0x55, 0x87, 0x71, 0x62, 0x47, 0x00, 0x33, 0x64, 0x67, 0x70,
+    0x79, 0x76, 0xdf, 0xfe, 0xc3, 0x28, 0x38, 0xdf, 0x90, 0xd4,
+    0xc0, 0xee, 0x98, 0xbf, 0x9d, 0x9b, 0x85, 0xd8, 0x61, 0x65,
+    0xa5, 0x70, 0xf5, 0xd2, 0x2c, 0xbf, 0x2f, 0xb5, 0x55, 0x79,
+    0x92, 0x13, 0xba, 0x4d, 0x3c, 0x39, 0xbf, 0xd5, 0x31, 0x13,
+    0x7a, 0x31, 0xf4, 0x8b, 0xce, 0xf8, 0xd0, 0xd3, 0x9b, 0xe2,
+    0xee, 0x31, 0xdb, 0xba, 0xcc, 0x1a, 0xba, 0x1c, 0x8d, 0xee,
+    0xea, 0xcb, 0xd3, 0x5a, 0xad, 0x87, 0xd6, 0xf9, 0x15, 0x2f,
+    0x6e, 0x00, 0x06, 0x74, 0x25, 0x8d, 0xff, 0xc8, 0xa6, 0x11,
+    0x1c, 0xe8, 0x16, 0x1a, 0xde, 0x53, 0x05, 0xb9, 0x53, 0x55,
+    0x28, 0x83, 0x3d, 0xbe, 0x61, 0x0c, 0xc4, 0x98, 0x7d, 0xf6,
+    0xec, 0x36, 0xc3, 0xe5, 0xe7, 0x1d, 0x14, 0x64, 0xcb, 0x0d,
+    0x62, 0x5d, 0x7a, 0xcd, 0x88, 0xfc, 0x66, 0x4e, 0xf9, 0x36,
+    0x47, 0x95, 0x18, 0x3a, 0x48, 0x2a, 0xff, 0x62, 0x8f, 0x6c,
+    0xe2, 0xc2, 0xe9, 0xd3, 0x6a, 0x45, 0x5c, 0xf5, 0x89, 0x53,
+    0x5c, 0xbe, 0xcf, 0xad, 0x87, 0x22, 0x9c, 0x31, 0x48, 0xdb,
+    0xd8, 0xe4, 0xe5, 0x38, 0xae, 0xc2, 0xb0, 0xd2, 0xba, 0xb7,
+    0x30, 0x53, 0x2d, 0xb1, 0x35, 0xf1, 0x58, 0x0f, 0x8a, 0x06,
+    0x51, 0x76, 0xb9, 0x2c, 0x32, 0xe0, 0xd1, 0xaa, 0x82, 0x34,
+    0x69, 0x71, 0x1c, 0x5f, 0x35, 0xa8, 0x9d, 0x11, 0xac, 0x13,
+    0xdb, 0x7b, 0xf6, 0x93, 0xe3, 0xb9, 0xbd, 0xd9, 0xb2, 0x86,
+    0xff, 0x61, 0x88, 0x2b, 0x72, 0x5c, 0x84, 0xe1, 0x0c, 0x72,
+    0xab, 0x44, 0xff, 0x23, 0x13, 0xaf, 0xd1, 0x5a, 0xd3, 0xea,
+    0x73, 0xfe, 0xd5, 0xa4, 0x7d, 0x9e, 0x4e, 0xac, 0x03, 0x93,
+    0x72, 0x14, 0x2d, 0x96, 0x6f, 0xee, 0xb4, 0xcd, 0x4e, 0xab,
+    0xea, 0x71, 0x93, 0x81, 0xe0, 0x3d, 0xcd, 0x61, 0x96, 0x25,
+    0x76, 0xbd, 0xc4, 0xb5, 0xdd, 0x7c, 0xf1, 0xb9, 0xe1, 0x2c,
+    0x58, 0x1b, 0xa4, 0x46, 0x4b, 0x12, 0x57, 0x58, 0xaa, 0x3a,
+    0xae, 0x89, 0xa3, 0xb3, 0xcf, 0x1f, 0x8d, 0x67, 0xdf, 0x6d,
+    0x7e, 0x8e, 0xfa, 0xc5, 0x09, 0x73, 0x46, 0x56, 0x55, 0x90,
+    0xeb, 0x77, 0x4e, 0x16, 0x4f, 0x68, 0x7b, 0x1f, 0x61, 0x23,
+    0xec, 0xa9, 0x71, 0x30, 0x33, 0x25, 0xc7, 0x4e, 0x26, 0x2e,
+    0x4e, 0x2b, 0xc2, 0x64, 0x5f, 0xf5, 0x8f, 0x7a, 0x4b, 0x1c,
+    0x06, 0xb3, 0x91, 0xf6, 0x9b, 0x51, 0xb7, 0xb0, 0x64, 0x72,
+    0x04, 0xe5, 0xfa, 0x14, 0x2f, 0xed, 0x61, 0x29, 0x03, 0x73,
+    0x19, 0x15, 0x6e, 0x2c, 0x8b, 0x0e, 0xec, 0x4d, 0xf1, 0xe3,
+    0x6f, 0x58, 0x7c, 0xc9, 0x48, 0x67, 0x3f, 0x51, 0xb5, 0xb7,
+    0x26, 0x46, 0xa7, 0x25, 0x79, 0x55, 0xfe, 0x3a, 0x44, 0xb4,
+    0x44, 0xfc, 0xb8, 0x14, 0x34, 0x47, 0xd7, 0xa3, 0x0e, 0x76,
+    0xe7, 0x83, 0x9a, 0x02, 0xc3, 0xcf, 0x2b, 0xd9, 0x83, 0x93,
+    0xd5, 0xee, 0x99, 0x74, 0x45, 0x62, 0x23, 0xa6, 0x02, 0xc9,
+    0xc0, 0x10, 0x70, 0x0a, 0x99, 0x29, 0x0c, 0x79, 0x04, 0x4c,
+    0x77, 0x21, 0x96, 0xf0, 0xa5, 0x17, 0x22, 0xbe, 0xab, 0x9b,
+    0xd7, 0x42, 0xd3, 0xe9, 0xc0, 0x42, 0x44, 0x7d, 0x9d, 0xc9,
+    0x3d, 0xf9, 0x36, 0x97, 0x1b, 0x75, 0x52, 0x8f, 0xe9, 0xb9,
+    0x8c, 0xa7, 0x64, 0x19, 0x5b, 0x5d, 0x60, 0xb4, 0x42, 0x95,
+    0xc9, 0xdb, 0x82, 0x03, 0xc6, 0xb0, 0x28, 0x72, 0x64, 0x03,
+    0x41, 0x4d, 0x8f, 0xc6, 0xd0, 0xcd, 0x02, 0x82, 0x01, 0xe1,
+    0x00, 0xe8, 0x66, 0xa7, 0xf9, 0x0f, 0x5a, 0x21, 0xfc, 0x88,
+    0x4e, 0x91, 0xd5, 0x4a, 0xf0, 0xf4, 0x32, 0xe5, 0x0d, 0xf3,
+    0x06, 0x95, 0xd0, 0x4e, 0x47, 0x0c, 0x04, 0x66, 0x77, 0xfd,
+    0xb8, 0x93, 0x0d, 0xff, 0x8f, 0x97, 0xa0, 0x4a, 0x36, 0x37,
+    0xa6, 0x5e, 0x95, 0x79, 0xc8, 0xb2, 0x21, 0x98, 0x81, 0xf1,
+    0xb8, 0xf4, 0x52, 0xaf, 0x3c, 0x8c, 0x86, 0x85, 0x55, 0x56,
+    0xfc, 0x90, 0xe3, 0x32, 0x50, 0x7c, 0x54, 0x07, 0x9e, 0xed,
+    0xfc, 0xd4, 0xb9, 0x5c, 0x98, 0x22, 0xfb, 0x72, 0xd7, 0x83,
+    0xf0, 0xd1, 0x61, 0x10, 0xbd, 0x68, 0x5d, 0x72, 0xc1, 0xce,
+    0x92, 0x43, 0x77, 0x9f, 0xb8, 0x8d, 0x8e, 0xf2, 0xe3, 0x62,
+    0x4a, 0x93, 0x03, 0xd3, 0xd9, 0x01, 0xa8, 0x99, 0x6f, 0xa3,
+    0x4c, 0x6d, 0x7a, 0xf2, 0x9e, 0x8e, 0x6b, 0xbc, 0xe4, 0x9d,
+    0x8e, 0xe7, 0x25, 0x86, 0xa4, 0xa9, 0xc2, 0xef, 0xdf, 0xbb,
+    0x6e, 0x3d, 0x4b, 0x57, 0x95, 0x81, 0x6f, 0x68, 0x3f, 0x19,
+    0xa8, 0xff, 0x5a, 0x08, 0x7a, 0xe4, 0x4c, 0x4e, 0xb4, 0xea,
+    0xf4, 0xc8, 0x2f, 0xef, 0x8c, 0x5e, 0xcd, 0x62, 0x1c, 0x8c,
+    0x93, 0x60, 0x5d, 0xa3, 0x11, 0x64, 0x0b, 0xeb, 0x6d, 0x21,
+    0xbc, 0x3a, 0x5b, 0x5c, 0x0c, 0xa7, 0x8a, 0xc6, 0xa8, 0xe1,
+    0x48, 0x81, 0x01, 0xb5, 0x65, 0xab, 0x2e, 0xbe, 0x38, 0x94,
+    0xf7, 0xa6, 0x33, 0xc1, 0x6e, 0x0b, 0x88, 0x38, 0xe7, 0x1b,
+    0x04, 0x9a, 0x10, 0x2d, 0x1d, 0x3f, 0x5f, 0x5f, 0xc8, 0xef,
+    0xcd, 0xc5, 0x16, 0xdc, 0x84, 0xc0, 0x66, 0xe0, 0xa3, 0xfc,
+    0xfa, 0x96, 0xc7, 0xb7, 0xec, 0x4f, 0x40, 0x0a, 0xc5, 0xbe,
+    0x6d, 0x39, 0x4a, 0x7e, 0x91, 0x4f, 0xe1, 0x03, 0xd2, 0x39,
+    0xbc, 0x87, 0x69, 0xa1, 0xf0, 0x6d, 0x11, 0xf5, 0xb4, 0x9d,
+    0xae, 0x76, 0x6b, 0xc6, 0xbf, 0xe4, 0x47, 0xbc, 0x4d, 0x13,
+    0x88, 0xa8, 0x83, 0xf5, 0xae, 0x1d, 0xfb, 0x4d, 0x4c, 0x44,
+    0x03, 0xd8, 0xa4, 0x2e, 0x4d, 0xf8, 0x5f, 0x45, 0x94, 0x58,
+    0xd7, 0xd9, 0x4b, 0x47, 0xd8, 0xfc, 0x35, 0x05, 0xed, 0xb4,
+    0xb6, 0xc2, 0x36, 0x2e, 0xba, 0xd2, 0x7a, 0xba, 0x69, 0x34,
+    0xbf, 0xf1, 0xa1, 0x5e, 0x17, 0x71, 0x89, 0xd3, 0x54, 0x57,
+    0x05, 0x2b, 0x82, 0xe3, 0x0a, 0x64, 0x5c, 0x3b, 0x8c, 0x6b,
+    0xc7, 0x10, 0x8a, 0xb5, 0xd3, 0xd7, 0x90, 0xeb, 0xdb, 0x1d,
+    0xa0, 0xbf, 0x6b, 0xea, 0xcd, 0x31, 0x7a, 0x8d, 0x64, 0xcc,
+    0x58, 0xc0, 0x07, 0xa4, 0x6e, 0x14, 0x0b, 0xf3, 0xea, 0x3e,
+    0x87, 0x9f, 0x7c, 0xb8, 0x1c, 0x22, 0x26, 0x8a, 0x7d, 0x90,
+    0xdd, 0x57, 0x28, 0x38, 0xcc, 0x0e, 0x71, 0x92, 0x89, 0xee,
+    0x79, 0x88, 0xbc, 0x05, 0x21, 0xda, 0x42, 0x92, 0x52, 0x66,
+    0xac, 0x4a, 0xe5, 0xf5, 0x6e, 0x47, 0xd5, 0xba, 0x37, 0xd3,
+    0x7c, 0x89, 0xd4, 0xd8, 0x6f, 0xde, 0x63, 0x44, 0xb5, 0x88,
+    0xdd, 0xb1, 0x30, 0xb4, 0x6d, 0xcd, 0xbf, 0xc8, 0x34, 0x27,
+    0x59, 0x7d, 0x79, 0xdc, 0x96, 0x5b, 0x8e, 0xc0, 0x87, 0xc0,
+    0x4e, 0x40, 0x07, 0x13, 0x91, 0x6b, 0x3a, 0x12, 0x03, 0x64,
+    0x70, 0xaf, 0x80, 0x24, 0x1c, 0x5c, 0xfb, 0xf5, 0xc0, 0x74,
+    0x5e, 0xaf, 0x06, 0x18, 0x04, 0x67, 0x4a, 0xbd, 0xac, 0xd7,
+    0xca, 0xbe, 0x4e, 0xa1, 0x19, 0x48, 0x7d, 0xa6, 0x59, 0xf6,
+    0x1a, 0x62, 0x50, 0x53, 0x46, 0xa4, 0x5b, 0x9c, 0x5a, 0xfd,
+    0x89, 0x9d, 0xd4, 0xde, 0xf4, 0xa7, 0x3d, 0x88, 0x73, 0xa5,
+    0xb9, 0x02, 0x82, 0x01, 0xe1, 0x00, 0xe7, 0x70, 0x59, 0xc3,
+    0xed, 0xc4, 0x6b, 0xa1, 0xa5, 0x5e, 0x90, 0x2a, 0x8c, 0x6a,
+    0xc2, 0x4e, 0xab, 0xfc, 0xee, 0xf2, 0x23, 0x38, 0xd6, 0xb3,
+    0x93, 0x08, 0x9e, 0x0c, 0x8e, 0x71, 0x2d, 0xa9, 0xe8, 0xdc,
+    0xa5, 0xdc, 0x07, 0xe3, 0xb1, 0x33, 0xdd, 0xa2, 0xf2, 0x3e,
+    0x92, 0x58, 0xe0, 0xf7, 0x53, 0x7f, 0x6e, 0xea, 0x78, 0x8c,
+    0x35, 0x78, 0x43, 0x63, 0x95, 0xbb, 0x1b, 0x1c, 0xbf, 0x91,
+    0x75, 0x14, 0x74, 0xd3, 0x20, 0xba, 0x8f, 0xee, 0x9d, 0x71,
+    0xa1, 0x87, 0x8a, 0x24, 0xd3, 0x61, 0x53, 0xfb, 0xec, 0x16,
+    0x84, 0xbe, 0x4d, 0x39, 0xdd, 0x0a, 0xac, 0xce, 0x20, 0x9c,
+    0xaf, 0x8a, 0x13, 0xf8, 0x22, 0x2f, 0xd4, 0x99, 0x88, 0x74,
+    0xba, 0x16, 0x3a, 0x63, 0xff, 0x4c, 0x5a, 0x03, 0x5a, 0x6f,
+    0xac, 0x29, 0x33, 0xa5, 0x50, 0xd1, 0xda, 0xed, 0x27, 0xcb,
+    0x67, 0x72, 0x63, 0x85, 0xfc, 0xf0, 0xc8, 0x88, 0xbf, 0x85,
+    0xef, 0x4b, 0xfe, 0xae, 0xd9, 0xd5, 0xbb, 0x86, 0xa4, 0x76,
+    0xe8, 0x7f, 0xb4, 0xdb, 0xb1, 0xee, 0x1a, 0x7f, 0x99, 0xd7,
+    0x9b, 0x6f, 0x7a, 0x94, 0x5c, 0xec, 0x2c, 0x60, 0x81, 0xad,
+    0xa7, 0xbe, 0x80, 0x2e, 0x9f, 0xa6, 0xc0, 0xfb, 0x09, 0x6d,
+    0x2b, 0xab, 0xa4, 0x15, 0xc7, 0x79, 0x46, 0x24, 0x89, 0x5c,
+    0x32, 0xb9, 0x87, 0xa9, 0x54, 0x1e, 0x12, 0x90, 0x8e, 0x02,
+    0x80, 0x8c, 0xf8, 0xdb, 0x2f, 0xbc, 0x98, 0x1b, 0xa2, 0x78,
+    0x73, 0x89, 0x03, 0x97, 0xe3, 0x09, 0x08, 0x8b, 0x75, 0xcf,
+    0xdc, 0x23, 0x90, 0x59, 0xef, 0x5b, 0x98, 0x24, 0xb8, 0xe8,
+    0xcf, 0x75, 0xf0, 0x2f, 0xb7, 0xa3, 0xe6, 0x17, 0x06, 0xf0,
+    0x52, 0xfe, 0x21, 0x0a, 0x16, 0x8e, 0xf8, 0xe1, 0xae, 0x25,
+    0x11, 0x5d, 0x8c, 0x95, 0x1b, 0x4f, 0x45, 0xb8, 0xa8, 0xcd,
+    0xe6, 0xf9, 0xca, 0xa0, 0x54, 0x93, 0x95, 0x86, 0x6f, 0xe4,
+    0x93, 0x22, 0x0f, 0xf2, 0xcf, 0xbd, 0x23, 0xb0, 0xf4, 0x8f,
+    0x99, 0xa7, 0x67, 0x99, 0x05, 0x13, 0x1f, 0xeb, 0x88, 0xf8,
+    0xe2, 0x3b, 0xb9, 0x49, 0x35, 0x89, 0x4f, 0xb8, 0x06, 0x37,
+    0x36, 0xda, 0x75, 0x25, 0x0f, 0x0a, 0xaa, 0xc2, 0x6c, 0x3e,
+    0xb1, 0x2d, 0x16, 0xf3, 0x17, 0xdb, 0xe2, 0x16, 0x32, 0x39,
+    0x92, 0x4b, 0x5f, 0xc0, 0x5f, 0x6e, 0xd0, 0x1c, 0x7e, 0xc0,
+    0x51, 0xd9, 0xb3, 0xe2, 0x37, 0xc7, 0xe0, 0x40, 0x13, 0x7d,
+    0x06, 0xcd, 0xcd, 0x72, 0xb6, 0x53, 0x2d, 0x7e, 0x60, 0x49,
+    0xfe, 0x31, 0xe1, 0xd0, 0x0e, 0x4c, 0x98, 0x93, 0xe0, 0xf6,
+    0xf2, 0xfa, 0x99, 0x7f, 0x65, 0xd8, 0x15, 0xc6, 0x3a, 0xb8,
+    0x4d, 0x63, 0x21, 0x78, 0xe4, 0x19, 0x6b, 0xbd, 0xde, 0x40,
+    0x5b, 0x8c, 0xfa, 0x49, 0x75, 0x23, 0x8f, 0x14, 0xc2, 0x3b,
+    0xa3, 0x9b, 0xc5, 0x80, 0x1a, 0xa3, 0x60, 0xd7, 0x17, 0x27,
+    0xf0, 0x18, 0x0f, 0xba, 0x02, 0xf7, 0x7a, 0xed, 0xa4, 0x00,
+    0x77, 0xde, 0x4b, 0xdd, 0xf9, 0xd7, 0x3e, 0x75, 0xed, 0x1a,
+    0x43, 0x26, 0x71, 0x1b, 0xbc, 0x72, 0xf5, 0x70, 0x72, 0x03,
+    0x70, 0x25, 0x87, 0x81, 0x6a, 0x92, 0x2d, 0xb7, 0x02, 0xf0,
+    0x10, 0x79, 0x65, 0x9d, 0x4e, 0x11, 0x7d, 0x5c, 0x5b, 0x37,
+    0xaa, 0xb4, 0xfa, 0x43, 0x66, 0x48, 0x6c, 0x67, 0x64, 0x9e,
+    0x15, 0x75, 0x36, 0xe7, 0x25, 0x55, 0x07, 0x7f, 0x74, 0x1f,
+    0x2c, 0x28, 0x76, 0xe7, 0x9b, 0x3d, 0x91, 0x0b, 0xcd, 0x6a,
+    0x1d, 0x5a, 0xea, 0x63, 0xd0, 0xf9, 0x02, 0x82, 0x01, 0xe0,
+    0x3e, 0x31, 0xf2, 0xf4, 0x29, 0x92, 0xa2, 0x93, 0xd5, 0xda,
+    0xc9, 0x16, 0x7e, 0xf6, 0xdb, 0x33, 0x9f, 0xaf, 0x4b, 0x01,
+    0xd1, 0x28, 0x2d, 0x3a, 0xc0, 0x51, 0x91, 0x26, 0xbd, 0xa5,
+    0x1e, 0xdd, 0xd9, 0x2e, 0x11, 0x93, 0x19, 0x29, 0x47, 0x5d,
+    0x63, 0xe4, 0xb6, 0xf1, 0xea, 0x12, 0x29, 0xa1, 0x65, 0x12,
+    0x6d, 0x78, 0x8f, 0x63, 0x31, 0xec, 0x72, 0x54, 0x73, 0x72,
+    0x26, 0x48, 0x57, 0x57, 0xc8, 0xde, 0x28, 0x27, 0xf5, 0x62,
+    0xfb, 0x7f, 0x1b, 0xf3, 0xaf, 0x31, 0x01, 0xfc, 0x01, 0x58,
+    0x7a, 0x80, 0x72, 0x9d, 0x6e, 0x07, 0xcc, 0x45, 0x67, 0xc6,
+    0x26, 0xfe, 0x25, 0xa5, 0x9b, 0x64, 0xcd, 0x45, 0xe3, 0x31,
+    0x38, 0x05, 0x07, 0x36, 0x05, 0x46, 0x9c, 0xc1, 0x8e, 0xbf,
+    0x4e, 0x71, 0x5f, 0xea, 0xe5, 0x0c, 0x9a, 0x41, 0xc8, 0x94,
+    0xcc, 0xf1, 0x73, 0x06, 0x30, 0x54, 0x76, 0x23, 0xb7, 0x22,
+    0x7a, 0x8e, 0xe6, 0x42, 0xa1, 0xa0, 0x32, 0x12, 0xe9, 0x08,
+    0x1c, 0x46, 0x79, 0x0c, 0x82, 0x7a, 0x95, 0x79, 0xbf, 0x83,
+    0x80, 0xeb, 0xab, 0x3d, 0x32, 0xc5, 0xde, 0x62, 0xeb, 0x90,
+    0x29, 0x73, 0x05, 0xc8, 0x0a, 0xb1, 0x51, 0xf1, 0x23, 0xdd,
+    0x1e, 0xf5, 0x02, 0x3e, 0x74, 0xbc, 0x24, 0x0c, 0x60, 0x36,
+    0x2a, 0x28, 0x4d, 0xe6, 0x86, 0x98, 0x7c, 0xd9, 0xe1, 0xac,
+    0x21, 0x33, 0xaa, 0xa9, 0x8b, 0xb6, 0x8a, 0x1b, 0xf7, 0x54,
+    0x14, 0xf3, 0x0d, 0x4f, 0xcd, 0x7c, 0xf5, 0xc2, 0x6d, 0xc2,
+    0xf0, 0xe2, 0xfc, 0x63, 0x1e, 0xa6, 0xa9, 0xa9, 0xd9, 0x73,
+    0x2a, 0xd5, 0x0a, 0x38, 0xd8, 0xc0, 0xb7, 0xe1, 0x51, 0xe4,
+    0x23, 0x37, 0xf7, 0x85, 0x66, 0x0e, 0x3f, 0x1a, 0x8c, 0xcf,
+    0x12, 0xa2, 0x47, 0x6f, 0x73, 0x91, 0x21, 0xe3, 0x93, 0x6b,
+    0x74, 0x4f, 0xc5, 0xa1, 0xe7, 0x32, 0xf7, 0x86, 0xdd, 0x1a,
+    0x6e, 0x96, 0xda, 0x32, 0x1d, 0xdd, 0xfa, 0x42, 0xd5, 0xd4,
+    0xfd, 0xae, 0x7a, 0xa1, 0xed, 0x3d, 0x79, 0xfe, 0x88, 0x84,
+    0x43, 0xa7, 0xec, 0xf3, 0x7a, 0x13, 0xaa, 0xa1, 0x82, 0x02,
+    0x83, 0x19, 0x43, 0x0a, 0x46, 0x78, 0x07, 0xd9, 0x4d, 0xff,
+    0xac, 0x67, 0xd6, 0x29, 0x89, 0xfe, 0x2b, 0xab, 0x5f, 0x9a,
+    0x87, 0x99, 0x80, 0xaf, 0x70, 0x4a, 0x6a, 0xb9, 0x5a, 0xc2,
+    0xac, 0x7f, 0xa2, 0xc7, 0xad, 0xe2, 0x1f, 0xec, 0xc5, 0x12,
+    0x17, 0x08, 0x87, 0x8f, 0x20, 0x95, 0xbe, 0xaf, 0x62, 0x2c,
+    0xc2, 0x3f, 0x89, 0x56, 0xd8, 0x50, 0x96, 0x97, 0x72, 0xe2,
+    0x92, 0xe1, 0x2a, 0xd8, 0x84, 0x9f, 0x31, 0xe3, 0x06, 0xd8,
+    0xe5, 0x91, 0x63, 0x19, 0xe1, 0x27, 0xad, 0xe2, 0xf2, 0x0a,
+    0x5e, 0x78, 0x8b, 0x1b, 0x13, 0x31, 0x4b, 0xbd, 0x77, 0xb2,
+    0xd6, 0x5c, 0x92, 0x81, 0x50, 0x02, 0x37, 0xd2, 0xe6, 0xeb,
+    0x66, 0x6b, 0xaa, 0xfc, 0xcd, 0x54, 0x5d, 0xb8, 0x03, 0x87,
+    0xe8, 0xfa, 0xb2, 0xde, 0xcb, 0xf8, 0x6e, 0x58, 0xde, 0xcb,
+    0x09, 0x54, 0x8a, 0x9f, 0x46, 0xa3, 0x7e, 0x8d, 0x15, 0xff,
+    0x1b, 0x0d, 0x89, 0xc4, 0x1a, 0x21, 0x31, 0x5e, 0xed, 0x0b,
+    0x67, 0x3c, 0x70, 0xed, 0x92, 0x48, 0xef, 0xec, 0xf0, 0x77,
+    0xc2, 0x79, 0x6c, 0x06, 0x09, 0xaa, 0xab, 0xf6, 0x4c, 0xcd,
+    0xfa, 0x7e, 0x4a, 0x88, 0xdc, 0xa8, 0x9b, 0xd3, 0x69, 0x94,
+    0x88, 0x09, 0x1d, 0x30, 0x43, 0x9e, 0x2c, 0xcb, 0x01, 0x1d,
+    0x4a, 0x3b, 0x04, 0xec, 0x0e, 0xb1, 0xde, 0x09, 0xad, 0x29,
+    0x02, 0x82, 0x01, 0xe1, 0x00, 0x9f, 0x02, 0x13, 0x7a, 0xd0,
+    0xa9, 0x8a, 0x7a, 0xa0, 0x05, 0xbb, 0x44, 0x6f, 0xaf, 0xf7,
+    0xe3, 0xd4, 0x35, 0xef, 0x73, 0x39, 0xd5, 0xe0, 0xa2, 0x0f,
+    0x1a, 0x25, 0xa8, 0xf7, 0xc2, 0xa5, 0xec, 0x57, 0xf8, 0x0d,
+    0x2a, 0xb6, 0x64, 0x03, 0x8c, 0x22, 0x0f, 0xe7, 0x98, 0xa1,
+    0x12, 0xfe, 0x24, 0xef, 0x61, 0x28, 0x9f, 0xa7, 0x22, 0x6b,
+    0x6d, 0xab, 0x8d, 0x7d, 0x2a, 0x8b, 0xae, 0x8b, 0xfd, 0xcb,
+    0xd5, 0x0b, 0x79, 0x1b, 0x89, 0xcb, 0x5b, 0x7a, 0x8c, 0xdc,
+    0xe8, 0x8d, 0xdd, 0x35, 0x9f, 0x06, 0x69, 0x64, 0x12, 0xeb,
+    0x46, 0x79, 0xdf, 0x82, 0x2c, 0x89, 0x75, 0x9e, 0x7a, 0xec,
+    0xad, 0xe5, 0x88, 0x31, 0xfa, 0x86, 0x93, 0xca, 0xf1, 0x2d,
+    0x9b, 0x62, 0x5a, 0xe9, 0x43, 0x09, 0xf3, 0x8c, 0xe5, 0xc7,
+    0xc0, 0xce, 0x86, 0xe7, 0xdb, 0xc7, 0x4d, 0x27, 0xd5, 0xee,
+    0x76, 0xce, 0x35, 0x30, 0x47, 0xef, 0x00, 0x1b, 0x69, 0x9a,
+    0x3f, 0xa5, 0x2a, 0xc9, 0x07, 0xab, 0x99, 0xba, 0x2a, 0xe7,
+    0xfb, 0xa9, 0x4e, 0xb9, 0xae, 0x2c, 0x50, 0xfc, 0x35, 0x49,
+    0xe6, 0x97, 0x78, 0x3c, 0xb1, 0x59, 0xd7, 0x1d, 0x4e, 0x4e,
+    0xea, 0xde, 0xa0, 0xd0, 0xc4, 0x1d, 0xb1, 0xd3, 0x53, 0x1e,
+    0xf9, 0xbf, 0xb3, 0x6a, 0x17, 0xb4, 0xda, 0xcc, 0x27, 0x19,
+    0xc6, 0x35, 0xe8, 0x28, 0xd3, 0xe3, 0x76, 0x3a, 0xdc, 0xd0,
+    0x75, 0xc8, 0xb4, 0x6c, 0xbe, 0x84, 0x2a, 0x45, 0xd1, 0x43,
+    0x22, 0x54, 0xd7, 0xc5, 0xd0, 0xd7, 0x73, 0x35, 0x6b, 0xa8,
+    0xfa, 0xad, 0x60, 0xc0, 0x64, 0xc1, 0x58, 0x89, 0x09, 0x81,
+    0x0a, 0x0b, 0xea, 0x33, 0x91, 0xb0, 0xef, 0x53, 0x50, 0x41,
+    0xae, 0xd9, 0xee, 0xbe, 0x9e, 0xf0, 0x0b, 0xa0, 0x7c, 0xbf,
+    0x3f, 0xc9, 0x4b, 0xe0, 0x48, 0xd8, 0x10, 0xd5, 0x2e, 0xce,
+    0xf0, 0x7c, 0xd8, 0x05, 0xde, 0x09, 0x7e, 0x8c, 0x63, 0x4c,
+    0xdb, 0x8b, 0x91, 0xcd, 0x7f, 0xb6, 0x6b, 0xad, 0xce, 0xb1,
+    0x17, 0x6c, 0xf7, 0x08, 0x0d, 0x7c, 0xda, 0x4f, 0x0a, 0x07,
+    0xd0, 0xae, 0x72, 0x3c, 0x67, 0x4a, 0x44, 0x54, 0x47, 0xce,
+    0xe1, 0x17, 0x07, 0x12, 0xde, 0x52, 0xef, 0xef, 0x4c, 0x2b,
+    0x42, 0x7d, 0x09, 0x80, 0x36, 0x34, 0xdc, 0x45, 0x6f, 0xb0,
+    0x2d, 0xab, 0xa0, 0x0c, 0x58, 0xae, 0x35, 0xd3, 0x9b, 0x37,
+    0xc1, 0x1d, 0xeb, 0xfe, 0xc3, 0x04, 0xc9, 0x1d, 0xe7, 0x3d,
+    0x16, 0x64, 0xed, 0xf5, 0xe8, 0xdf, 0x99, 0xa4, 0xfb, 0xad,
+    0x79, 0x88, 0xd5, 0x8c, 0x62, 0x33, 0x9e, 0x35, 0xa6, 0x7f,
+    0x9d, 0xb6, 0x1a, 0x40, 0x6d, 0xc3, 0x89, 0x5d, 0x7b, 0xe2,
+    0xc8, 0xd3, 0x16, 0x13, 0x07, 0x9a, 0x38, 0x22, 0x33, 0x03,
+    0xac, 0x70, 0x3e, 0xce, 0x32, 0x56, 0x0b, 0x58, 0x56, 0xb8,
+    0xe9, 0xd8, 0x42, 0x35, 0x6c, 0xb9, 0x02, 0xb3, 0x64, 0xeb,
+    0xaa, 0x09, 0x3f, 0xac, 0x66, 0x08, 0xb4, 0x5f, 0x3e, 0xb4,
+    0xec, 0x39, 0xb1, 0x99, 0xe4, 0x5d, 0x1d, 0x32, 0x14, 0xc1,
+    0x48, 0x8f, 0x6c, 0x65, 0x87, 0x34, 0x50, 0xa4, 0xf4, 0x9b,
+    0x5b, 0x2e, 0xb5, 0x79, 0x0d, 0x11, 0x62, 0xa4, 0x35, 0x9c,
+    0x6f, 0x92, 0xd0, 0x68, 0x07, 0xdd, 0x69, 0x85, 0x48, 0xe3,
+    0x5d, 0x10, 0x34, 0xaf, 0xea, 0x41, 0x72, 0x5a, 0x71, 0x00,
+    0xf8, 0xe6, 0x47, 0x7f, 0xa0, 0x6f, 0x91, 0x96, 0x40, 0x00,
+    0x40, 0x70, 0xfb, 0x63, 0xcf, 0xc9, 0x36, 0x04, 0x1c, 0x3b,
+    0x11, 0x08, 0x29, 0x81, 0x9f
+};
+
+static unsigned char test15360[] = {
+    0x30, 0x82, 0x21, 0xe8, 0x02, 0x01, 0x00, 0x02, 0x82, 0x07,
+    0x81, 0x00, 0xad, 0x3f, 0xaa, 0xdc, 0x8c, 0x85, 0xcb, 0x60,
+    0xd2, 0xf5, 0x30, 0xa1, 0x0f, 0x26, 0xec, 0xdf, 0xfc, 0x91,
+    0x39, 0xbd, 0x3e, 0x8f, 0x99, 0x64, 0x1e, 0x51, 0xd2, 0x27,
+    0x5e, 0x76, 0xcd, 0x86, 0x33, 0x07, 0xf9, 0xbd, 0x3b, 0x06,
+    0xc3, 0x3c, 0x85, 0xcb, 0x7e, 0x91, 0x14, 0xb0, 0x0b, 0x77,
+    0x22, 0x30, 0x71, 0xb8, 0xbb, 0x74, 0x30, 0x33, 0x35, 0x56,
+    0x34, 0x47, 0x10, 0x8f, 0x88, 0xe2, 0x6f, 0xdc, 0x3b, 0xe9,
+    0x58, 0x9d, 0x0c, 0xdc, 0x8f, 0x70, 0x41, 0x7a, 0x12, 0xd2,
+    0x9a, 0x35, 0xbe, 0x0a, 0x57, 0x13, 0x0c, 0xe9, 0xbf, 0x77,
+    0x54, 0x00, 0x74, 0xb7, 0x1a, 0x3e, 0xa7, 0xe9, 0xb6, 0xe7,
+    0x4f, 0x1e, 0xa4, 0xc0, 0x7c, 0x4c, 0x66, 0xc5, 0xce, 0xad,
+    0x96, 0x1b, 0xe2, 0x1a, 0xf1, 0x3d, 0x8b, 0x50, 0xcf, 0xe2,
+    0x15, 0x21, 0x6d, 0x83, 0x95, 0x00, 0xee, 0x97, 0xc4, 0xae,
+    0xc9, 0x38, 0x62, 0x6c, 0xb2, 0xe7, 0x7f, 0x15, 0x0a, 0xab,
+    0x86, 0xb9, 0xd9, 0x8a, 0xf8, 0xeb, 0x88, 0x5d, 0xdc, 0x0c,
+    0x1e, 0xc5, 0xe6, 0xa1, 0x7b, 0xbf, 0xf1, 0x02, 0xe3, 0xad,
+    0xf8, 0xed, 0x17, 0x9f, 0x83, 0x11, 0x31, 0x3b, 0xad, 0xb4,
+    0xf9, 0x8d, 0x1d, 0x56, 0x9b, 0xac, 0x68, 0x55, 0x0a, 0x74,
+    0x20, 0xee, 0x57, 0xe7, 0x1c, 0x6d, 0x05, 0xa1, 0x4e, 0xa5,
+    0x11, 0x99, 0xb4, 0x86, 0xdb, 0x58, 0xe7, 0xf6, 0xb6, 0x4f,
+    0x92, 0x58, 0x57, 0x9b, 0x74, 0x04, 0xe5, 0xd1, 0x1d, 0x7c,
+    0x4b, 0xb8, 0x1f, 0x5d, 0x0e, 0x93, 0xee, 0x44, 0x18, 0xb6,
+    0x58, 0x0e, 0xa1, 0x0b, 0x8e, 0x2e, 0x99, 0x4c, 0x72, 0x91,
+    0xfa, 0xfa, 0xe2, 0x22, 0x05, 0x5d, 0x2b, 0x2d, 0xd8, 0x60,
+    0xd5, 0x1b, 0x08, 0x56, 0x2b, 0xb5, 0x21, 0xdb, 0x1a, 0xe6,
+    0xa8, 0x39, 0xa2, 0xf4, 0x58, 0xcb, 0xd2, 0xf9, 0xce, 0xc0,
+    0x1e, 0x1b, 0xf9, 0xa7, 0x37, 0xca, 0xa3, 0x77, 0x6e, 0xb1,
+    0xaf, 0x33, 0xb5, 0x6d, 0x5f, 0x33, 0x2e, 0x1a, 0x34, 0xdb,
+    0x42, 0xbe, 0x5f, 0xf9, 0x09, 0xb7, 0x9f, 0xd4, 0x09, 0xfb,
+    0x87, 0x13, 0x3c, 0xe2, 0x27, 0xb8, 0xf3, 0x1d, 0x7e, 0x92,
+    0xdd, 0x87, 0x86, 0x55, 0x69, 0x9b, 0x55, 0xcd, 0xef, 0x7a,
+    0x71, 0x5d, 0x81, 0x3a, 0xd9, 0xf7, 0x7f, 0xde, 0xe0, 0x92,
+    0xd9, 0x78, 0x0f, 0x1d, 0x43, 0xb1, 0x1e, 0x29, 0xc1, 0x49,
+    0xb6, 0x5e, 0x85, 0x83, 0xd9, 0x04, 0xfd, 0x79, 0xd8, 0x47,
+    0x03, 0x2e, 0x85, 0x19, 0xfd, 0x63, 0xe7, 0xa4, 0x8b, 0xc0,
+    0x94, 0x0e, 0xb7, 0x54, 0x97, 0xd6, 0x44, 0x5d, 0x63, 0x12,
+    0xff, 0xdd, 0xde, 0x2c, 0x00, 0x0e, 0xc9, 0xca, 0x7e, 0xa2,
+    0x65, 0x25, 0xb0, 0x1d, 0xa9, 0x20, 0x4f, 0xdd, 0xea, 0x3a,
+    0xb5, 0xe8, 0x0f, 0xf3, 0xb2, 0xb7, 0x00, 0x4a, 0xe8, 0xa4,
+    0x83, 0x49, 0xbd, 0x78, 0xdf, 0xac, 0x2c, 0x37, 0x81, 0xb3,
+    0xf3, 0xb7, 0x13, 0x93, 0x3e, 0xb2, 0x79, 0x55, 0xf2, 0xd8,
+    0x9c, 0xf7, 0xf2, 0xf1, 0xd5, 0x6c, 0x9c, 0xff, 0xec, 0xf4,
+    0xea, 0x08, 0x3c, 0x65, 0x35, 0xb7, 0x09, 0x03, 0x6d, 0x99,
+    0x1d, 0x5b, 0x73, 0x06, 0x61, 0xb4, 0xf0, 0xc5, 0xdb, 0x3e,
+    0xe0, 0x1d, 0xa8, 0x5b, 0x7a, 0x5b, 0x5b, 0x9c, 0x11, 0x75,
+    0x83, 0x1d, 0xf4, 0x73, 0x27, 0xf3, 0x79, 0xf2, 0x82, 0xd6,
+    0x28, 0x45, 0x58, 0x23, 0x6c, 0x29, 0xd3, 0x50, 0x51, 0x1b,
+    0x38, 0xef, 0x89, 0x90, 0x84, 0xa2, 0x4c, 0x35, 0x7b, 0x30,
+    0x5e, 0xbd, 0x1a, 0xd5, 0xdf, 0xcd, 0xcd, 0x74, 0x3f, 0x2e,
+    0x01, 0xea, 0x33, 0x07, 0x74, 0xfb, 0x86, 0x75, 0x20, 0x0e,
+    0x4f, 0xbf, 0x65, 0xd4, 0x15, 0x19, 0x6f, 0x8d, 0x37, 0xcd,
+    0xb6, 0x6f, 0x50, 0x9d, 0x5e, 0x04, 0x81, 0x7d, 0xec, 0xd6,
+    0xbb, 0x40, 0x1b, 0xe0, 0xf5, 0xd5, 0x86, 0x26, 0xc5, 0x41,
+    0x84, 0x0e, 0x3e, 0x73, 0xb7, 0xa4, 0xbe, 0x2a, 0xfe, 0xd7,
+    0xe4, 0x4d, 0x5c, 0x2d, 0x6a, 0x04, 0xe6, 0xdd, 0x28, 0xa0,
+    0x75, 0x4c, 0xe0, 0x23, 0x2c, 0xad, 0xec, 0xaa, 0x72, 0xfd,
+    0x03, 0xc0, 0x65, 0xfa, 0xc4, 0x3c, 0x25, 0x10, 0xae, 0x3f,
+    0x09, 0x96, 0x4e, 0xff, 0xfe, 0xc7, 0xe4, 0x9e, 0xec, 0xb5,
+    0x6e, 0xec, 0xf3, 0x7a, 0x83, 0x7a, 0x8b, 0xbb, 0x91, 0x8d,
+    0xab, 0x3c, 0x4d, 0x7f, 0x34, 0x77, 0xbe, 0x0c, 0x87, 0xf2,
+    0xc3, 0xd6, 0xcb, 0xcc, 0xfa, 0x1e, 0xaf, 0x21, 0x24, 0xe9,
+    0xaa, 0x89, 0x61, 0x0c, 0x7a, 0x1c, 0x7d, 0x00, 0x87, 0x69,
+    0x30, 0xa0, 0xb4, 0x3b, 0x96, 0x1c, 0x00, 0x14, 0x07, 0xb8,
+    0x3f, 0x59, 0x62, 0x3a, 0x3f, 0xfb, 0x68, 0xb8, 0x81, 0x7d,
+    0x4a, 0x9d, 0x1c, 0xa2, 0x07, 0xa3, 0xb1, 0x42, 0x7b, 0xfa,
+    0x9b, 0xbc, 0x94, 0x30, 0x7e, 0xea, 0xe7, 0x40, 0x7e, 0xd4,
+    0x0f, 0x33, 0x3b, 0x57, 0xda, 0x8b, 0x6d, 0x64, 0xd5, 0xe4,
+    0x91, 0x83, 0xf0, 0x3d, 0xae, 0x8b, 0x91, 0xf0, 0xcd, 0xb1,
+    0xa0, 0xe0, 0x0d, 0xe1, 0xbb, 0x22, 0x78, 0x1f, 0x3a, 0xe5,
+    0x53, 0x28, 0xf0, 0x35, 0xae, 0x71, 0xe6, 0xfd, 0x63, 0xb2,
+    0x9c, 0x3f, 0xdd, 0x95, 0x7b, 0xc4, 0xe9, 0x2f, 0xd9, 0x93,
+    0x3a, 0x10, 0x42, 0x1c, 0x90, 0xab, 0xfb, 0xd3, 0x02, 0xe9,
+    0x59, 0xbc, 0x53, 0x7e, 0xf3, 0xe1, 0x52, 0x15, 0xa6, 0x58,
+    0x9e, 0xc1, 0xa6, 0x0e, 0x2e, 0x35, 0x07, 0x3a, 0xc3, 0x1f,
+    0xaa, 0x58, 0xe7, 0xc6, 0x33, 0x6a, 0x39, 0x4b, 0x21, 0x15,
+    0x3d, 0x92, 0x4e, 0x5e, 0xf9, 0x01, 0xd6, 0x0f, 0x28, 0x61,
+    0x15, 0xdf, 0xed, 0x6f, 0x75, 0xc4, 0x8f, 0xcb, 0x16, 0x55,
+    0x09, 0xc7, 0x24, 0xb2, 0x0c, 0x49, 0x25, 0x8d, 0x5e, 0xf1,
+    0x0e, 0xe0, 0xe2, 0xc4, 0xcc, 0x1f, 0x4e, 0x60, 0x5c, 0x5e,
+    0xc6, 0x7f, 0x68, 0x7f, 0xdb, 0x1a, 0x01, 0x67, 0x07, 0xb1,
+    0x56, 0x93, 0xf2, 0x26, 0x81, 0xc0, 0x33, 0xb8, 0x48, 0xf9,
+    0x2c, 0x5c, 0x18, 0x29, 0xed, 0xe0, 0x6c, 0xa0, 0xac, 0xd2,
+    0x90, 0x4b, 0x52, 0x87, 0xbb, 0xb5, 0x05, 0xd8, 0x56, 0xc5,
+    0xb8, 0x8f, 0x3f, 0x49, 0x52, 0x9a, 0xa2, 0xd0, 0x40, 0x80,
+    0x5b, 0x16, 0x15, 0xbc, 0x74, 0x8e, 0x00, 0x10, 0xaf, 0xfb,
+    0x6d, 0xba, 0xcb, 0xbc, 0xe6, 0x13, 0x75, 0xce, 0x27, 0xae,
+    0x85, 0x57, 0x6c, 0xc0, 0x8a, 0x84, 0x6f, 0x34, 0x16, 0xd4,
+    0x35, 0xd2, 0xcc, 0x55, 0x00, 0xc1, 0xd8, 0x28, 0x2c, 0x9c,
+    0x84, 0x78, 0xbf, 0xf0, 0x3b, 0x0d, 0x9f, 0x81, 0xd4, 0xef,
+    0x99, 0x77, 0x53, 0xd2, 0x8e, 0x43, 0x52, 0xf0, 0x32, 0x7e,
+    0xba, 0xbf, 0xb6, 0x0e, 0x9d, 0x9b, 0x00, 0xd0, 0x50, 0x55,
+    0x67, 0x5a, 0x2c, 0x8b, 0x9b, 0x29, 0xfb, 0x41, 0x74, 0x4c,
+    0xb7, 0xd8, 0x98, 0xa2, 0xfb, 0x73, 0x07, 0x96, 0xef, 0xcd,
+    0x47, 0x13, 0x1d, 0xe2, 0xb1, 0xac, 0xf3, 0xcf, 0x47, 0x98,
+    0x7b, 0x6f, 0xf6, 0x32, 0x44, 0x41, 0x78, 0x09, 0x8e, 0x64,
+    0x0c, 0xbf, 0xe2, 0x0f, 0x8c, 0x44, 0x2f, 0x4e, 0x55, 0xe0,
+    0xc6, 0xfd, 0x05, 0x74, 0x18, 0x1a, 0xb9, 0xfa, 0xcb, 0xd3,
+    0xfa, 0x69, 0x50, 0x63, 0xce, 0x2b, 0xef, 0x92, 0x0f, 0x11,
+    0xd4, 0x9b, 0x53, 0x6c, 0xed, 0xc5, 0x0b, 0x7c, 0xbd, 0xa1,
+    0x5d, 0xdf, 0xab, 0xcf, 0xaa, 0x83, 0x5e, 0xa8, 0xc5, 0xfe,
+    0x91, 0x2b, 0x23, 0x1f, 0x39, 0x3d, 0x71, 0x74, 0xbf, 0xa2,
+    0xf1, 0xda, 0x2f, 0x29, 0x02, 0x9b, 0xea, 0x48, 0x2c, 0xaf,
+    0xe7, 0xa9, 0xf5, 0x68, 0xab, 0x8f, 0x18, 0xb9, 0x7b, 0x28,
+    0xf0, 0x92, 0xfb, 0x07, 0xd7, 0xbd, 0x43, 0xcd, 0x7f, 0xfc,
+    0xb9, 0x5f, 0x24, 0xf8, 0x48, 0x2e, 0xbe, 0x42, 0x87, 0x80,
+    0x38, 0x78, 0x9e, 0x8c, 0x52, 0x6d, 0xfa, 0x2e, 0x46, 0x35,
+    0x7a, 0x59, 0x88, 0xb9, 0x3e, 0xcb, 0x79, 0xb4, 0x8a, 0x9e,
+    0xd5, 0xd0, 0x30, 0x8c, 0xb2, 0x0c, 0x9d, 0x8d, 0x2d, 0x64,
+    0x0b, 0xf6, 0xeb, 0xf1, 0xde, 0xea, 0x74, 0xfc, 0xbc, 0x01,
+    0x18, 0x48, 0x4e, 0x35, 0x02, 0x83, 0x01, 0xb2, 0x50, 0xa0,
+    0x44, 0x19, 0x30, 0x00, 0x12, 0x4a, 0xa0, 0x6d, 0x6b, 0x8b,
+    0xf1, 0xce, 0xda, 0x2e, 0x16, 0x35, 0x52, 0x26, 0xf9, 0xbe,
+    0xb1, 0x37, 0xfc, 0x0a, 0x8b, 0x6f, 0x06, 0x11, 0x7b, 0xf7,
+    0xa8, 0x40, 0xbd, 0x8d, 0x94, 0xa4, 0xa2, 0xe0, 0xb6, 0xdf,
+    0x62, 0xc0, 0x6f, 0xb3, 0x5d, 0x84, 0xb9, 0xaa, 0x2f, 0xc1,
+    0x3b, 0xcb, 0x20, 0xc6, 0x68, 0x69, 0x15, 0x74, 0xbc, 0xdb,
+    0x43, 0x9c, 0x4a, 0xfc, 0x72, 0xc1, 0xf5, 0x87, 0x80, 0xe8,
+    0x6c, 0xd5, 0xc1, 0x2e, 0x34, 0x5e, 0x96, 0x76, 0x08, 0x3e,
+    0x45, 0xe4, 0xa0, 0x4a, 0x7a, 0xc1, 0x67, 0x38, 0xf2, 0x31,
+    0x1f, 0x7b, 0x0f, 0x54, 0xbd, 0x0d, 0x1f, 0x9e, 0x8e, 0x99,
+    0x8b, 0x58, 0xd9, 0x94, 0x87, 0xaa, 0x8b, 0x82, 0x5d, 0x5e,
+    0xe8, 0x50, 0xf4, 0xf2, 0xc7, 0xe9, 0x85, 0x6b, 0xd2, 0xef,
+    0x13, 0xc1, 0xed, 0x57, 0x2a, 0xc5, 0xd6, 0x5d, 0xa4, 0x3b,
+    0x29, 0xba, 0xab, 0x1b, 0xaa, 0x21, 0x41, 0xe9, 0xdc, 0x47,
+    0x88, 0xef, 0x0c, 0xfc, 0xb2, 0xdc, 0xf7, 0xdb, 0x55, 0x4d,
+    0x70, 0xc7, 0xe2, 0x8a, 0x8a, 0xe1, 0xde, 0xcf, 0xe5, 0xca,
+    0x23, 0x36, 0x29, 0xe5, 0xfc, 0x54, 0x66, 0xda, 0xe9, 0xab,
+    0x58, 0x20, 0xb2, 0x8e, 0xb2, 0x7d, 0x5d, 0xb8, 0xc7, 0x6c,
+    0x48, 0x53, 0x2b, 0x47, 0xe0, 0x12, 0x00, 0x0e, 0xfe, 0xa5,
+    0x93, 0x34, 0xf9, 0x3e, 0xa6, 0x3f, 0x56, 0xaa, 0x43, 0x65,
+    0xbb, 0x5a, 0x70, 0x3e, 0x62, 0xac, 0x3f, 0x5b, 0x90, 0x02,
+    0x50, 0x5d, 0x05, 0xa8, 0xd5, 0x67, 0x1a, 0x62, 0xec, 0xd4,
+    0xde, 0x29, 0x04, 0xac, 0x6d, 0x15, 0x5d, 0xa0, 0xec, 0xf2,
+    0x57, 0x13, 0x0e, 0x17, 0x96, 0x0c, 0x32, 0x6a, 0xc5, 0xe0,
+    0xa8, 0xff, 0x85, 0xa4, 0xa3, 0xe3, 0x0e, 0x35, 0x5d, 0xd1,
+    0x28, 0x84, 0xaa, 0xc4, 0x84, 0xcd, 0x25, 0x63, 0x85, 0x82,
+    0x3e, 0x12, 0x30, 0x17, 0x57, 0x45, 0xb8, 0xb4, 0x34, 0x01,
+    0x3a, 0xa2, 0x77, 0x61, 0xc8, 0x3d, 0x1f, 0xc5, 0x0e, 0x4a,
+    0xbb, 0xf6, 0xa0, 0x5d, 0x79, 0x4b, 0xc8, 0xf3, 0x9c, 0x87,
+    0x05, 0x2f, 0xea, 0x25, 0x28, 0x91, 0x69, 0x77, 0x7c, 0xba,
+    0xea, 0x4a, 0x75, 0x2e, 0x2b, 0x17, 0x83, 0x50, 0x32, 0x43,
+    0x4f, 0xcd, 0xf1, 0x77, 0xb1, 0x22, 0x0a, 0x8b, 0x69, 0x58,
+    0x09, 0x35, 0x07, 0x6d, 0x61, 0x4a, 0x8d, 0x18, 0x65, 0x6e,
+    0x9b, 0x62, 0x07, 0xd0, 0x6a, 0x92, 0x39, 0x05, 0x80, 0x14,
+    0xfa, 0x1c, 0x93, 0x84, 0x0c, 0xb5, 0x8c, 0x41, 0x91, 0x4e,
+    0x48, 0xf0, 0xf2, 0xba, 0x1d, 0x73, 0x2f, 0x1e, 0xa1, 0x55,
+    0xc3, 0x02, 0x8c, 0xb1, 0xf2, 0x37, 0xa6, 0x9a, 0x6b, 0xcd,
+    0x45, 0x2e, 0x08, 0x90, 0x26, 0x63, 0x91, 0xff, 0x22, 0x5e,
+    0xcd, 0xae, 0x9b, 0x19, 0x1e, 0x10, 0x62, 0x4e, 0x1f, 0x2d,
+    0x81, 0x69, 0x4f, 0x41, 0xe5, 0x94, 0xff, 0x7e, 0xcc, 0x15,
+    0x36, 0x1e, 0x29, 0x59, 0x37, 0xe7, 0x64, 0x40, 0x17, 0x1a,
+    0x32, 0xba, 0x01, 0x26, 0x30, 0x80, 0x60, 0x07, 0x86, 0x6e,
+    0xd4, 0xb3, 0xe2, 0x44, 0x16, 0x33, 0xf2, 0x4c, 0x84, 0x0e,
+    0xb1, 0x4a, 0xc7, 0x92, 0xa6, 0xa3, 0x42, 0x36, 0x05, 0x3e,
+    0x74, 0xa8, 0xb1, 0xc5, 0x63, 0x59, 0x0d, 0x1e, 0x36, 0x45,
+    0x2b, 0x36, 0x5e, 0xca, 0xab, 0x97, 0x49, 0xd3, 0xab, 0xae,
+    0x63, 0x0a, 0xd1, 0x03, 0x57, 0x88, 0xa4, 0xa4, 0x3c, 0xda,
+    0x15, 0x49, 0x1a, 0x5d, 0xe6, 0x5e, 0xb9, 0x82, 0x23, 0xc0,
+    0x83, 0x96, 0xfe, 0x38, 0x0b, 0x80, 0x0e, 0xde, 0x22, 0xeb,
+    0x5d, 0xe4, 0x56, 0x32, 0xbe, 0xe0, 0xc0, 0x6e, 0x69, 0x63,
+    0x27, 0x4e, 0x00, 0x58, 0x80, 0x70, 0xd9, 0xcc, 0x4e, 0xae,
+    0x6c, 0x5e, 0x6a, 0x43, 0x81, 0xfd, 0x45, 0xb2, 0xa4, 0x6c,
+    0xf0, 0x9c, 0x66, 0x5c, 0x7d, 0x5c, 0x78, 0x55, 0x33, 0x4b,
+    0x3c, 0x3b, 0x1d, 0x18, 0x58, 0x79, 0x6a, 0x02, 0xec, 0xce,
+    0x53, 0x69, 0xc0, 0x17, 0xed, 0x57, 0xaf, 0x71, 0x5b, 0x42,
+    0x1b, 0x49, 0xd8, 0xe8, 0x96, 0x80, 0xb6, 0x48, 0x1b, 0x7c,
+    0xf8, 0x74, 0x1c, 0xb1, 0xc4, 0x10, 0xb7, 0xf4, 0x97, 0x7e,
+    0x6b, 0x8f, 0x54, 0xba, 0x37, 0xb9, 0x35, 0x9e, 0x7b, 0x17,
+    0x16, 0x9b, 0x89, 0x39, 0xae, 0x4f, 0x2e, 0x18, 0x65, 0xb4,
+    0x76, 0x20, 0x9a, 0x58, 0xe2, 0x57, 0x6e, 0x1c, 0x3f, 0x8e,
+    0x9a, 0xbb, 0xd8, 0xfc, 0x4c, 0xd6, 0x2d, 0xc1, 0xa6, 0x46,
+    0xac, 0x13, 0x1e, 0xa7, 0xf7, 0x1d, 0x28, 0x3a, 0xf4, 0xd6,
+    0x48, 0xfb, 0xe5, 0xb3, 0x84, 0x94, 0x47, 0x92, 0xae, 0x9a,
+    0x58, 0xc5, 0xac, 0x23, 0x1b, 0xb5, 0xcd, 0x96, 0xd2, 0x5e,
+    0xb2, 0x41, 0xfc, 0x9a, 0xae, 0x19, 0xf1, 0x7b, 0x4b, 0x53,
+    0x1b, 0xfa, 0xa5, 0x0c, 0x49, 0x6d, 0xff, 0xf4, 0x51, 0x88,
+    0x19, 0x04, 0xd9, 0x85, 0x8e, 0xe2, 0x3a, 0x62, 0x31, 0x5c,
+    0x6e, 0xe8, 0x4d, 0x04, 0x1d, 0xd8, 0xc2, 0x7b, 0x51, 0xe7,
+    0x59, 0xbc, 0x85, 0x5c, 0xc4, 0xcc, 0xad, 0xcb, 0x93, 0x69,
+    0x18, 0xe4, 0x71, 0x9e, 0x63, 0x33, 0x99, 0xb6, 0x3b, 0x23,
+    0x11, 0x17, 0x7a, 0x3d, 0x6f, 0xb9, 0x6b, 0xf1, 0xf2, 0xa7,
+    0x03, 0xfd, 0xf0, 0xcd, 0x5b, 0xb5, 0xda, 0x9a, 0xd9, 0x95,
+    0x02, 0x76, 0xd8, 0x38, 0xd3, 0xbd, 0xa0, 0x4a, 0x9a, 0xab,
+    0x70, 0xde, 0xc6, 0xf9, 0xa5, 0x19, 0x9c, 0xc4, 0xf9, 0x07,
+    0x4d, 0xea, 0x15, 0xc2, 0x91, 0x4d, 0x54, 0xa9, 0x2c, 0xca,
+    0xdf, 0xaa, 0xd1, 0xc4, 0xc0, 0x18, 0x77, 0x28, 0x2a, 0x2c,
+    0xc3, 0x7c, 0x26, 0xbd, 0xd8, 0x0d, 0x51, 0xa1, 0x4d, 0xad,
+    0x76, 0x76, 0xaa, 0xa9, 0x45, 0x82, 0x4f, 0x76, 0xfb, 0x1a,
+    0xd3, 0x71, 0x3c, 0x55, 0xa2, 0x5c, 0xe0, 0xd6, 0xda, 0x35,
+    0xbe, 0x25, 0x23, 0x26, 0x51, 0xc6, 0xb4, 0xf3, 0x3e, 0x2c,
+    0x54, 0x09, 0xc7, 0x6f, 0xa5, 0x08, 0x81, 0xba, 0x75, 0xda,
+    0xcb, 0x4d, 0x05, 0xdd, 0xca, 0x93, 0x48, 0x30, 0xe8, 0x4a,
+    0x1f, 0xfd, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x07,
+    0x80, 0x25, 0x2f, 0xbc, 0x49, 0xf8, 0xb3, 0xa3, 0x32, 0xd6,
+    0x35, 0x20, 0xca, 0x01, 0x49, 0x96, 0xa0, 0x81, 0x42, 0xde,
+    0xc4, 0xdb, 0x0f, 0xd1, 0x99, 0xe6, 0xd4, 0x23, 0x2a, 0xa6,
+    0x21, 0x13, 0xfe, 0x51, 0x27, 0xce, 0x18, 0x2a, 0xfa, 0x49,
+    0x9f, 0xcd, 0x0c, 0x1f, 0xcf, 0x9e, 0x44, 0x27, 0x41, 0xdc,
+    0x09, 0xcf, 0xef, 0x19, 0xf5, 0x57, 0x7f, 0x36, 0x5c, 0x99,
+    0x7e, 0x03, 0x74, 0xfb, 0xa9, 0xb6, 0xde, 0xeb, 0xd1, 0x2b,
+    0x5f, 0x12, 0x6a, 0xa9, 0x33, 0x2c, 0x2a, 0xba, 0xad, 0x8f,
+    0xc2, 0x27, 0x57, 0x6a, 0xd7, 0x40, 0xf7, 0x4f, 0x4c, 0x9a,
+    0xb0, 0x3a, 0x5d, 0x2e, 0xf9, 0xf1, 0xea, 0xbd, 0x82, 0xaa,
+    0xbd, 0xe6, 0x19, 0x16, 0xd5, 0x03, 0x5e, 0x43, 0xfd, 0x88,
+    0x71, 0xd5, 0xb7, 0x78, 0xbe, 0x80, 0x0f, 0xc9, 0x7f, 0x3a,
+    0x8f, 0xe1, 0x44, 0xd4, 0x0f, 0xce, 0x26, 0xaf, 0x65, 0xe0,
+    0xf5, 0x04, 0x53, 0x56, 0x97, 0x4f, 0xf4, 0xc1, 0x44, 0x8d,
+    0xf7, 0x88, 0x55, 0x47, 0x16, 0xaf, 0x3f, 0x8e, 0x42, 0xdf,
+    0xbc, 0x14, 0xc3, 0xe6, 0x9f, 0x0d, 0x69, 0x54, 0x5b, 0x7c,
+    0x49, 0xcf, 0xbf, 0x42, 0x4f, 0xc7, 0x64, 0x8a, 0xe5, 0x84,
+    0x87, 0x20, 0x9b, 0xfd, 0x70, 0x25, 0x38, 0xd3, 0xb4, 0x97,
+    0x78, 0xf1, 0x4f, 0x3f, 0x0f, 0xbb, 0x9c, 0xa3, 0x17, 0xd5,
+    0x4e, 0x4b, 0xac, 0x82, 0x9a, 0x73, 0xb7, 0xc5, 0xec, 0x10,
+    0x7a, 0x7b, 0xdb, 0x77, 0x2c, 0xb1, 0xf3, 0x8f, 0xc3, 0xa5,
+    0x31, 0x11, 0x32, 0x55, 0x35, 0xb5, 0x77, 0xd2, 0x62, 0x19,
+    0x46, 0x92, 0x94, 0xbb, 0x61, 0x0f, 0x30, 0x94, 0x8a, 0xf6,
+    0xf7, 0x30, 0xe0, 0xa2, 0x8c, 0x1b, 0xff, 0x8c, 0x29, 0x44,
+    0xb4, 0xb7, 0xb6, 0x5f, 0x4d, 0x52, 0xc6, 0x07, 0xe1, 0x28,
+    0x8c, 0xae, 0x88, 0x8a, 0x22, 0xbd, 0xd7, 0x36, 0xe4, 0x8f,
+    0xd1, 0xeb, 0x65, 0x54, 0x19, 0x5f, 0xba, 0xfb, 0xfc, 0x91,
+    0xa1, 0xa4, 0xb8, 0xa4, 0x2d, 0x85, 0x20, 0xc4, 0xe5, 0xa7,
+    0x4e, 0xdb, 0xa4, 0xc5, 0xcc, 0x2f, 0x37, 0x41, 0x29, 0x47,
+    0x15, 0xff, 0x04, 0x80, 0x08, 0x37, 0xce, 0xc5, 0xe3, 0x5a,
+    0x3f, 0x83, 0xbb, 0x03, 0x9e, 0xfe, 0xec, 0xe4, 0x11, 0x41,
+    0x12, 0x13, 0xf2, 0x00, 0xe5, 0x1a, 0x02, 0x49, 0xeb, 0xdb,
+    0x57, 0xe4, 0xce, 0xa0, 0x3f, 0xfd, 0x3c, 0x73, 0x2b, 0x92,
+    0x44, 0x79, 0x9e, 0x12, 0x4f, 0xfa, 0xe4, 0x53, 0x62, 0xf2,
+    0xb0, 0xe2, 0x8a, 0xf0, 0x93, 0xa8, 0x1d, 0xee, 0x8d, 0x58,
+    0x7a, 0x4c, 0x29, 0x91, 0x29, 0xc1, 0xa4, 0xd5, 0xe6, 0x37,
+    0x1b, 0x75, 0x5b, 0xb6, 0x6b, 0x76, 0x2e, 0xcb, 0xbd, 0xa9,
+    0xbe, 0x4c, 0x2e, 0x21, 0xa6, 0x38, 0xde, 0x66, 0x2f, 0x51,
+    0xea, 0x4c, 0xba, 0x3f, 0x4a, 0xfe, 0x7a, 0x15, 0xb3, 0x72,
+    0x26, 0xba, 0xcf, 0x9e, 0x1b, 0x03, 0xa6, 0xaa, 0x65, 0x68,
+    0xd3, 0x8c, 0x15, 0x17, 0xe9, 0x11, 0x18, 0x3c, 0xb6, 0xf8,
+    0x02, 0x54, 0x98, 0x49, 0xfa, 0x35, 0x3c, 0xcd, 0xac, 0xc8,
+    0x2b, 0x1a, 0x63, 0x93, 0x03, 0x05, 0xa1, 0x41, 0xbe, 0x12,
+    0xca, 0x15, 0x47, 0x72, 0x63, 0x77, 0x26, 0xd0, 0xe7, 0x8f,
+    0x0d, 0x6e, 0x9c, 0xac, 0x07, 0xbe, 0x03, 0x22, 0xd0, 0x39,
+    0x63, 0x8d, 0x9b, 0xc6, 0x20, 0x81, 0xb5, 0x67, 0x15, 0xf6,
+    0xb0, 0xe3, 0xb9, 0x3e, 0xb7, 0x3f, 0x8f, 0x46, 0xc9, 0x74,
+    0x10, 0x1e, 0x53, 0xf1, 0xd4, 0x30, 0x4d, 0x6e, 0x72, 0xb4,
+    0x73, 0x1c, 0xb6, 0x79, 0x82, 0x60, 0x2e, 0x2a, 0x7d, 0x82,
+    0x95, 0xb5, 0x7c, 0x4d, 0x44, 0xcb, 0xd8, 0x8a, 0x17, 0xe8,
+    0x50, 0x29, 0xd8, 0x3a, 0xeb, 0x29, 0xc1, 0x83, 0x0f, 0xd9,
+    0xaf, 0xcc, 0xfa, 0xea, 0x3a, 0x47, 0x5d, 0x33, 0x1f, 0xe8,
+    0x33, 0x5b, 0x88, 0x8e, 0xdb, 0xd5, 0x1e, 0xaf, 0x4a, 0x5f,
+    0xc0, 0xfa, 0xf0, 0xb5, 0xa3, 0x5b, 0xda, 0x38, 0xb7, 0x38,
+    0x5e, 0xce, 0x81, 0x44, 0xf7, 0x66, 0x62, 0x64, 0x1d, 0x04,
+    0xf0, 0x8a, 0x4f, 0xa2, 0x80, 0x76, 0x83, 0x23, 0x89, 0x61,
+    0x6b, 0xc3, 0xb7, 0xee, 0xb5, 0x06, 0x33, 0xad, 0x63, 0x04,
+    0x78, 0xc9, 0xde, 0x32, 0xde, 0xcf, 0x18, 0xb9, 0xb0, 0x3b,
+    0xee, 0x0a, 0x58, 0xea, 0xad, 0xbc, 0x1e, 0x77, 0xa0, 0x93,
+    0xf7, 0xae, 0x9e, 0xb6, 0x31, 0x59, 0x8e, 0xb1, 0x03, 0x8f,
+    0xbb, 0xa4, 0x25, 0x0c, 0x2e, 0xd7, 0xe2, 0x62, 0x5c, 0xf1,
+    0x68, 0xe9, 0x76, 0xd7, 0x23, 0x14, 0x45, 0xaf, 0xcb, 0x09,
+    0x50, 0x05, 0x3f, 0xa0, 0xf9, 0xc3, 0x9e, 0x89, 0x05, 0xa8,
+    0x3b, 0x54, 0x55, 0x32, 0x74, 0x91, 0x46, 0xc1, 0x2c, 0x96,
+    0x7e, 0x60, 0xad, 0xfa, 0xbb, 0xcd, 0x09, 0x7b, 0x39, 0x10,
+    0x82, 0x8a, 0xc0, 0x5a, 0x0d, 0xab, 0xb3, 0x71, 0x45, 0xad,
+    0x39, 0x8e, 0xec, 0x4d, 0x91, 0x8d, 0xda, 0x8d, 0xfa, 0xb0,
+    0xad, 0x44, 0x3c, 0xc9, 0x21, 0x56, 0x22, 0xfc, 0xd3, 0xba,
+    0xb7, 0x3c, 0xe3, 0x8d, 0xda, 0x59, 0x34, 0x42, 0xdd, 0x04,
+    0x5b, 0x8e, 0x2b, 0xc7, 0x94, 0xd5, 0x42, 0xe0, 0x4a, 0x6f,
+    0x35, 0x5a, 0x27, 0x82, 0xd8, 0x82, 0x40, 0xee, 0x0f, 0xa6,
+    0xef, 0xe4, 0x70, 0xe3, 0x30, 0xb7, 0x2d, 0xd4, 0xbb, 0x27,
+    0xb2, 0xbf, 0xad, 0x49, 0x45, 0xbc, 0xeb, 0xbe, 0xb7, 0xd8,
+    0xe3, 0xb1, 0xf3, 0xeb, 0x41, 0x20, 0x9b, 0x21, 0x54, 0xc3,
+    0xa8, 0xaf, 0x9f, 0x20, 0x5c, 0x15, 0x8e, 0x25, 0xbc, 0xbc,
+    0x69, 0x91, 0xfe, 0xda, 0xad, 0xe5, 0x37, 0x7d, 0xb0, 0x51,
+    0x14, 0xae, 0x8f, 0x35, 0x15, 0x0a, 0xd4, 0x49, 0xa7, 0xd9,
+    0x20, 0x70, 0xa4, 0xf2, 0xf4, 0x24, 0x66, 0x52, 0xd1, 0xa5,
+    0x22, 0xea, 0x29, 0xd9, 0xb2, 0x82, 0x8d, 0x36, 0x66, 0x75,
+    0x6e, 0xd5, 0x8c, 0x54, 0x08, 0x21, 0xf2, 0xee, 0x78, 0xc7,
+    0x1f, 0x9c, 0x63, 0x5d, 0x88, 0x56, 0xd1, 0xa0, 0x80, 0x33,
+    0x60, 0x55, 0x23, 0x72, 0xd6, 0xb0, 0x1a, 0x50, 0xde, 0x25,
+    0x70, 0xb5, 0x77, 0x42, 0xf8, 0x19, 0x18, 0x15, 0x8f, 0xfd,
+    0x0c, 0x6a, 0x46, 0x1f, 0xbf, 0xe7, 0x60, 0x91, 0xe7, 0xbb,
+    0x25, 0x63, 0x66, 0xff, 0x11, 0x97, 0xbb, 0xfd, 0x3a, 0x17,
+    0x94, 0x77, 0xb4, 0xc5, 0x21, 0xba, 0x30, 0x94, 0xdd, 0xe5,
+    0xeb, 0x1d, 0x01, 0xba, 0xf9, 0xb0, 0x30, 0xdb, 0x11, 0x93,
+    0xb7, 0xfa, 0x79, 0xe8, 0x5e, 0xb3, 0x39, 0xf4, 0x51, 0x68,
+    0x31, 0xce, 0xe9, 0x0e, 0x93, 0xde, 0xff, 0xec, 0x27, 0xbd,
+    0xa6, 0x1a, 0x4c, 0xe0, 0x92, 0x5c, 0xd4, 0x07, 0xd2, 0xa1,
+    0xdd, 0x12, 0x83, 0xd2, 0x9a, 0x79, 0xb3, 0x3c, 0xfb, 0x07,
+    0xe3, 0x18, 0x1a, 0xa3, 0x24, 0x80, 0xb4, 0xcc, 0xf4, 0xc6,
+    0xa5, 0x6c, 0x25, 0xd7, 0x99, 0x1a, 0x30, 0xf0, 0xa9, 0xfc,
+    0x2e, 0x83, 0x44, 0xac, 0x64, 0x76, 0x34, 0xb0, 0xa6, 0x6f,
+    0x20, 0x5a, 0x14, 0xf2, 0x07, 0xa7, 0x6f, 0x4d, 0xab, 0xf5,
+    0xfc, 0x9d, 0xd6, 0x3e, 0x82, 0x48, 0x31, 0x25, 0x47, 0xc9,
+    0x0e, 0x1d, 0xdb, 0x98, 0x91, 0x56, 0xf5, 0xfe, 0x66, 0x8d,
+    0x48, 0xf0, 0x4c, 0x6c, 0x2c, 0x96, 0x54, 0x43, 0xec, 0x76,
+    0xf2, 0xe1, 0x76, 0x68, 0xc8, 0xe1, 0xde, 0x0d, 0x8e, 0x6f,
+    0xfc, 0x15, 0xd5, 0x93, 0x92, 0xfe, 0xca, 0x9b, 0x30, 0x61,
+    0x03, 0x0b, 0xca, 0x99, 0x2f, 0xd3, 0x15, 0xe9, 0x66, 0x81,
+    0xbd, 0x56, 0x17, 0x14, 0x4a, 0x2e, 0xf1, 0x34, 0x84, 0x55,
+    0x9d, 0xc0, 0x2b, 0xa7, 0x4a, 0xee, 0xf1, 0x7c, 0x67, 0xc7,
+    0xf3, 0x08, 0x1e, 0x6d, 0x6b, 0x5b, 0xcc, 0x81, 0x91, 0x5c,
+    0x94, 0x1a, 0x80, 0xda, 0x3a, 0xce, 0x36, 0x05, 0xb0, 0x7a,
+    0xe8, 0xd0, 0xb4, 0x57, 0x9c, 0xf9, 0xea, 0xf3, 0x26, 0x1d,
+    0xcb, 0xf8, 0xdd, 0x65, 0xaf, 0xf7, 0xcd, 0xf7, 0xa1, 0x3d,
+    0xfc, 0x9a, 0x3b, 0x08, 0xb9, 0xfa, 0x3c, 0x16, 0x49, 0x4a,
+    0xf1, 0xba, 0x4d, 0x31, 0xdd, 0x5e, 0x4f, 0x3d, 0x66, 0x22,
+    0x1b, 0x08, 0x91, 0x7d, 0xc6, 0xaf, 0x15, 0x07, 0x3c, 0xa1,
+    0xf7, 0x07, 0xfd, 0x3e, 0x90, 0xbb, 0x6f, 0x7a, 0xe9, 0xe1,
+    0x2f, 0xb9, 0xee, 0x91, 0x8e, 0x18, 0xcc, 0x8d, 0x1d, 0x22,
+    0xa0, 0xa0, 0x28, 0x25, 0xfc, 0xd4, 0x94, 0xd3, 0xaa, 0xcf,
+    0xce, 0xd0, 0x85, 0x82, 0x6f, 0x20, 0x9f, 0x55, 0x0e, 0xe5,
+    0x72, 0x0d, 0x17, 0x3e, 0x34, 0xc7, 0x2c, 0x0a, 0x14, 0x45,
+    0x27, 0xe2, 0xc7, 0x2f, 0x86, 0xa1, 0x55, 0x3e, 0x78, 0x03,
+    0xe9, 0x78, 0x2e, 0xd3, 0x99, 0xee, 0xa0, 0x14, 0xf8, 0xe3,
+    0x6c, 0xeb, 0x3f, 0x9a, 0xf3, 0x15, 0xce, 0xd5, 0x76, 0xf6,
+    0x3a, 0x86, 0x30, 0x76, 0xf9, 0x88, 0x30, 0xf5, 0x4a, 0x50,
+    0x58, 0x80, 0xe9, 0xd9, 0xd4, 0xb9, 0x34, 0x42, 0xa6, 0x4e,
+    0x9c, 0x1a, 0x07, 0x16, 0x9e, 0xee, 0xe4, 0x88, 0x04, 0x8e,
+    0xa8, 0xe7, 0xcd, 0xe8, 0x47, 0x1e, 0x54, 0x45, 0xd2, 0x65,
+    0xd8, 0xee, 0x4b, 0xbd, 0xd0, 0x85, 0xaa, 0xfb, 0x06, 0x53,
+    0x91, 0x7e, 0xe0, 0x59, 0x20, 0x57, 0x6a, 0xee, 0xd8, 0x9f,
+    0x77, 0x7f, 0xd7, 0x40, 0x63, 0xbb, 0x21, 0x75, 0x76, 0x11,
+    0x27, 0xcf, 0x05, 0xbb, 0x41, 0x30, 0x98, 0xbf, 0xdc, 0x5f,
+    0xc6, 0xa4, 0x1e, 0x30, 0xa1, 0x53, 0xd4, 0x36, 0x7f, 0x2e,
+    0x86, 0xd7, 0xd9, 0x95, 0x29, 0xd5, 0x46, 0x18, 0x60, 0x27,
+    0xe4, 0x6f, 0xcb, 0xf4, 0xe2, 0xfe, 0xff, 0x3e, 0xff, 0x15,
+    0xc6, 0xf2, 0x31, 0xf9, 0x2a, 0xc8, 0x05, 0x4e, 0x7c, 0x2e,
+    0x92, 0xc8, 0x41, 0x4f, 0x9e, 0x23, 0x21, 0x4d, 0x74, 0xf8,
+    0xc3, 0x44, 0x39, 0xc2, 0x69, 0x4b, 0x2e, 0x76, 0x5e, 0x44,
+    0x12, 0x65, 0x31, 0x98, 0xbe, 0x0a, 0x10, 0x11, 0x12, 0x2c,
+    0x67, 0x3d, 0x85, 0x2e, 0xd3, 0x97, 0x54, 0x1e, 0xb6, 0xad,
+    0xd9, 0x45, 0x11, 0x53, 0x04, 0x7c, 0x3f, 0xf4, 0xc9, 0xac,
+    0x82, 0x1b, 0x84, 0xf4, 0x20, 0x6b, 0xf1, 0xf5, 0x72, 0x04,
+    0x24, 0xc1, 0xd3, 0x42, 0x43, 0x52, 0x9d, 0x2d, 0xd3, 0x89,
+    0x8e, 0xd8, 0x28, 0xb9, 0xa2, 0xb4, 0xed, 0xbc, 0x76, 0x87,
+    0x55, 0x67, 0x39, 0xd9, 0xb7, 0x20, 0x6a, 0xec, 0xec, 0xb8,
+    0x14, 0x51, 0x91, 0xb9, 0x96, 0x0f, 0x7a, 0x3a, 0x12, 0xde,
+    0x14, 0x3b, 0x83, 0xcf, 0x41, 0x5b, 0x5d, 0xff, 0x33, 0x68,
+    0xdb, 0x53, 0x64, 0x93, 0xb1, 0xc3, 0x8a, 0x46, 0xa8, 0x44,
+    0x9c, 0x14, 0x12, 0x6c, 0x92, 0x6f, 0xae, 0xc3, 0x45, 0xb2,
+    0xa1, 0x67, 0x81, 0x3c, 0x22, 0x47, 0xfd, 0xa4, 0x7a, 0x79,
+    0xa8, 0x0a, 0xfb, 0x7a, 0x91, 0x6e, 0xe9, 0x53, 0xec, 0x98,
+    0x82, 0x57, 0xad, 0x05, 0x38, 0x55, 0xc1, 0xce, 0x3a, 0x04,
+    0x4d, 0x12, 0x72, 0x37, 0x4a, 0x36, 0x54, 0x3f, 0x67, 0x8a,
+    0xee, 0xd9, 0xf3, 0x80, 0xd5, 0xd7, 0xb8, 0xfc, 0x6e, 0x4f,
+    0x60, 0x2b, 0x5a, 0xa4, 0xc5, 0x05, 0xdb, 0xe5, 0x09, 0xe3,
+    0xeb, 0xa2, 0x51, 0x33, 0x30, 0x96, 0x46, 0x01, 0x26, 0x8f,
+    0x38, 0xc9, 0x97, 0x32, 0x2d, 0xb4, 0x59, 0x15, 0x15, 0x38,
+    0x66, 0x66, 0xfe, 0xcb, 0xee, 0xc1, 0xf6, 0x4e, 0xb7, 0xdf,
+    0x7b, 0x63, 0xe6, 0x3f, 0xe0, 0x1c, 0x97, 0xed, 0x86, 0xf3,
+    0xd2, 0xad, 0x42, 0x29, 0x20, 0x28, 0xa6, 0x59, 0x58, 0x7d,
+    0x8f, 0x5c, 0x43, 0x07, 0xd1, 0x7e, 0x83, 0xba, 0x9c, 0x1b,
+    0xfe, 0x17, 0x9e, 0xc8, 0x09, 0x63, 0x9a, 0x2d, 0x61, 0x33,
+    0x51, 0x46, 0x01, 0xa8, 0xe9, 0x43, 0x1e, 0x4e, 0xfe, 0x61,
+    0x1a, 0x28, 0x11, 0x65, 0x70, 0x43, 0x9f, 0xfc, 0x21, 0x1d,
+    0x76, 0x7b, 0x40, 0x08, 0x18, 0xd3, 0xe8, 0xc2, 0xe3, 0x8c,
+    0xe7, 0x27, 0xc2, 0xec, 0xb0, 0x08, 0x3e, 0x6b, 0x8f, 0x77,
+    0x6d, 0x9e, 0xa6, 0xab, 0xce, 0x9a, 0xf8, 0x8f, 0x77, 0xb3,
+    0xf4, 0xe8, 0x8b, 0xe7, 0xd9, 0xa1, 0x95, 0x40, 0x6b, 0xca,
+    0x21, 0x98, 0xff, 0xdc, 0xdc, 0x96, 0xc3, 0x08, 0x81, 0x72,
+    0x9a, 0xdd, 0xe2, 0xcf, 0x95, 0x99, 0xa6, 0xa3, 0x5e, 0x9e,
+    0x25, 0x60, 0xa3, 0xc3, 0x39, 0xf7, 0x54, 0x6c, 0xf2, 0x75,
+    0xa9, 0x38, 0x12, 0x38, 0x4d, 0x42, 0xe8, 0xec, 0x13, 0x25,
+    0xa0, 0xf8, 0x04, 0xb8, 0xf6, 0x66, 0x0b, 0x56, 0xe1, 0xfb,
+    0x26, 0x03, 0xe6, 0xa5, 0xf1, 0x4d, 0x7f, 0xa5, 0x9d, 0x58,
+    0x71, 0xd8, 0xc7, 0x6a, 0xbe, 0xdc, 0x90, 0x89, 0xb1, 0x36,
+    0xb4, 0xb6, 0xb4, 0xbb, 0xaf, 0x6e, 0x43, 0x10, 0xa6, 0xea,
+    0xee, 0x12, 0xcb, 0x08, 0x2c, 0x4e, 0x66, 0xf0, 0x1f, 0xf4,
+    0xbf, 0xd3, 0xeb, 0x63, 0x48, 0xd0, 0xbe, 0x8a, 0xed, 0x24,
+    0xdb, 0x0f, 0x23, 0x1d, 0x2e, 0x30, 0x97, 0x0f, 0xd8, 0xc6,
+    0x3b, 0x04, 0x2f, 0x33, 0x78, 0x20, 0x6e, 0xb1, 0x33, 0x03,
+    0x27, 0xac, 0x0a, 0x37, 0x15, 0x31, 0xef, 0x4d, 0x43, 0xcc,
+    0xa0, 0x49, 0x80, 0xe3, 0x8c, 0xc0, 0xf3, 0xf7, 0x2d, 0x37,
+    0x1d, 0xd3, 0x90, 0x5f, 0xad, 0x31, 0xb5, 0x95, 0x17, 0x69,
+    0x4b, 0xec, 0x84, 0x9d, 0x2b, 0x8d, 0xdd, 0x9b, 0x58, 0x04,
+    0xba, 0x28, 0x0e, 0x28, 0xc1, 0x54, 0x6c, 0xb0, 0x25, 0x0c,
+    0x4f, 0x98, 0x47, 0xf7, 0x93, 0xc2, 0xae, 0x2f, 0x6d, 0x29,
+    0x9c, 0x3d, 0xe3, 0xb5, 0xe3, 0x28, 0x43, 0x14, 0xe6, 0x92,
+    0x4c, 0x79, 0x90, 0x59, 0x75, 0x77, 0x56, 0x43, 0xda, 0xac,
+    0xa9, 0x42, 0xd7, 0xca, 0x95, 0x73, 0x26, 0x54, 0x1f, 0x3a,
+    0x8a, 0x37, 0x64, 0xd7, 0xcf, 0xe1, 0x31, 0xf7, 0x40, 0x59,
+    0xfd, 0xff, 0xea, 0x72, 0xfd, 0xc4, 0xde, 0xe3, 0x4d, 0x8a,
+    0xf5, 0x80, 0xc0, 0x61, 0x21, 0xbd, 0xbd, 0x8e, 0x42, 0xd5,
+    0x4c, 0xe4, 0xf4, 0x78, 0x31, 0xca, 0xf1, 0xec, 0x7c, 0x7b,
+    0x85, 0x6a, 0x05, 0x54, 0xbe, 0x38, 0x54, 0x2f, 0x1f, 0xda,
+    0x9f, 0x98, 0xe2, 0x79, 0xd7, 0x42, 0xca, 0xba, 0x85, 0x21,
+    0xe2, 0xcb, 0x2b, 0xae, 0x4a, 0x4e, 0x35, 0xfb, 0xcf, 0x3d,
+    0xc5, 0xae, 0x27, 0x30, 0xa9, 0x45, 0xe6, 0x3b, 0x43, 0x3e,
+    0x35, 0xe3, 0xf2, 0x0d, 0x53, 0x32, 0x2b, 0xf6, 0xe6, 0xc7,
+    0xd5, 0x02, 0x82, 0x03, 0xc1, 0x00, 0xd4, 0x04, 0x9b, 0xef,
+    0x5d, 0x58, 0xb0, 0xa3, 0xaa, 0xd2, 0xab, 0x53, 0x65, 0x99,
+    0x03, 0x49, 0x48, 0x4d, 0xf5, 0xdf, 0x5d, 0x16, 0x14, 0x11,
+    0x60, 0x45, 0x1b, 0xff, 0x4a, 0x60, 0x2b, 0x37, 0x63, 0xf6,
+    0xa7, 0x8a, 0xa8, 0xff, 0x08, 0x97, 0x08, 0xfc, 0xbb, 0xb3,
+    0x20, 0xa3, 0xcd, 0xd9, 0x58, 0xdb, 0x16, 0x1b, 0x88, 0x02,
+    0x1e, 0x0f, 0x43, 0x9b, 0x16, 0x7e, 0xbe, 0xb1, 0x9c, 0x13,
+    0x10, 0xdc, 0xa1, 0x56, 0xff, 0xa3, 0xff, 0x5e, 0x69, 0x30,
+    0xee, 0x7e, 0x76, 0x5f, 0x84, 0x94, 0xeb, 0x8f, 0x58, 0xf8,
+    0xcf, 0xbb, 0x99, 0x6e, 0xf0, 0xd8, 0x32, 0xf6, 0xce, 0x48,
+    0x6f, 0x7c, 0xc8, 0x8f, 0xd3, 0x86, 0x22, 0x49, 0x9f, 0xde,
+    0x11, 0x05, 0xa4, 0xdc, 0x92, 0xfb, 0x0f, 0xfa, 0x09, 0x4d,
+    0x17, 0x1a, 0xe2, 0x76, 0x67, 0x40, 0xa9, 0x5b, 0x1b, 0x54,
+    0x66, 0x48, 0xf7, 0xc3, 0x59, 0xd4, 0xcf, 0x55, 0xd0, 0x7f,
+    0x3b, 0xb0, 0xa2, 0xd8, 0xec, 0xb7, 0x88, 0xe7, 0xb0, 0x30,
+    0x72, 0x42, 0x65, 0xe2, 0x91, 0xa7, 0x9b, 0xf6, 0x07, 0x45,
+    0x52, 0x51, 0xaa, 0xbe, 0x32, 0x35, 0xe4, 0x88, 0x23, 0xe7,
+    0xcb, 0x3c, 0x1c, 0xfb, 0x0b, 0x96, 0xd5, 0xb3, 0x92, 0x86,
+    0x79, 0x5b, 0x47, 0x93, 0xd6, 0xbd, 0xc7, 0x21, 0x17, 0xd0,
+    0xc9, 0xc7, 0x69, 0x84, 0x80, 0x98, 0xaf, 0x2c, 0x63, 0xd1,
+    0xef, 0x6e, 0xca, 0x84, 0x30, 0x32, 0x83, 0x2d, 0x49, 0xbb,
+    0x1f, 0x2a, 0xfe, 0x40, 0x7c, 0x03, 0xd4, 0x45, 0xdc, 0xfe,
+    0x94, 0xf9, 0xe4, 0x36, 0x47, 0xfa, 0x7e, 0x2e, 0x93, 0x03,
+    0xf8, 0x15, 0xf9, 0xce, 0xc3, 0x5b, 0x76, 0x10, 0xec, 0x89,
+    0x8c, 0xce, 0x25, 0xa5, 0x77, 0x9a, 0xc5, 0x1e, 0xdd, 0x07,
+    0x1b, 0x5b, 0xac, 0x6f, 0xdb, 0x94, 0x85, 0xdf, 0x02, 0x22,
+    0xd1, 0xa9, 0x01, 0x8e, 0x63, 0xa1, 0xee, 0x94, 0x9c, 0xdb,
+    0xb4, 0x1a, 0x43, 0xe1, 0x1f, 0x4e, 0x2f, 0x68, 0x50, 0x0c,
+    0x2f, 0x5b, 0xc5, 0x1b, 0xe1, 0x8d, 0x4b, 0xe0, 0x63, 0x8d,
+    0x7a, 0x30, 0xbe, 0xb7, 0x2e, 0x02, 0xc6, 0x02, 0xac, 0xa8,
+    0xb8, 0x65, 0xc6, 0x28, 0xee, 0xe4, 0xec, 0x99, 0xa1, 0x9a,
+    0xfd, 0x1f, 0xb5, 0x85, 0x7a, 0x94, 0x16, 0xe2, 0xe7, 0x74,
+    0x06, 0x54, 0x1b, 0xd0, 0xaf, 0x58, 0x4e, 0x50, 0x7e, 0xd6,
+    0xe4, 0x31, 0xd2, 0x0c, 0xd7, 0x9d, 0xe2, 0x00, 0x30, 0xbe,
+    0x26, 0x30, 0x48, 0x99, 0x98, 0x58, 0x54, 0x5a, 0xc4, 0x0a,
+    0x6c, 0xa1, 0x06, 0xe9, 0x38, 0xe6, 0x79, 0x39, 0x00, 0x9e,
+    0xb6, 0xe3, 0xf7, 0x01, 0xcf, 0x2f, 0x82, 0x5e, 0xc3, 0x21,
+    0x1b, 0x79, 0x93, 0xb5, 0xe4, 0x39, 0x9d, 0x32, 0x9d, 0x72,
+    0xa4, 0xa8, 0xc9, 0x90, 0xce, 0xaf, 0xc0, 0x00, 0xad, 0x20,
+    0x87, 0x26, 0xc7, 0xd3, 0x5f, 0x2e, 0xf0, 0x5e, 0xf8, 0x8b,
+    0x85, 0xa3, 0xc6, 0x66, 0xd8, 0x2f, 0x86, 0xfe, 0x7d, 0x8d,
+    0x22, 0xa5, 0x6d, 0x68, 0x3e, 0x87, 0x6e, 0xf7, 0xf1, 0xf0,
+    0x07, 0xc4, 0xe3, 0xf1, 0x84, 0xc4, 0x93, 0x42, 0x06, 0x20,
+    0x80, 0x64, 0xb3, 0x52, 0x5c, 0xa5, 0xcf, 0xee, 0xfe, 0xa4,
+    0x09, 0x41, 0xbe, 0xaa, 0x78, 0x52, 0x76, 0x3f, 0xf7, 0xe8,
+    0xa1, 0x6b, 0x0a, 0xbc, 0x22, 0xbe, 0xdf, 0x72, 0x7b, 0xea,
+    0x90, 0x43, 0xee, 0xc2, 0x0b, 0x26, 0xdc, 0x02, 0x26, 0xa7,
+    0x50, 0x04, 0x7a, 0x06, 0x91, 0xae, 0x93, 0xd5, 0xd2, 0xc9,
+    0xa1, 0xe1, 0xfc, 0xb9, 0x8c, 0x94, 0xca, 0xa8, 0x1c, 0x2c,
+    0x57, 0x97, 0x3e, 0x50, 0xed, 0x93, 0x45, 0x7a, 0x2c, 0x59,
+    0x7b, 0x34, 0x8f, 0xcd, 0xd6, 0x17, 0x93, 0xd8, 0xde, 0xe8,
+    0xb0, 0x9e, 0x27, 0x15, 0xc5, 0xbb, 0xa5, 0xbb, 0xc2, 0x30,
+    0x9b, 0xc7, 0x27, 0x02, 0x18, 0xd8, 0xdb, 0xa4, 0x84, 0x37,
+    0x64, 0xf7, 0xf7, 0xf1, 0xc8, 0x86, 0x4c, 0x64, 0x97, 0x08,
+    0xe9, 0x4e, 0x0e, 0xb6, 0x92, 0xe9, 0x4c, 0x7b, 0x7f, 0xe1,
+    0xcc, 0xa0, 0x71, 0xa7, 0x34, 0x48, 0x46, 0xbb, 0x37, 0xce,
+    0xb0, 0x4d, 0x39, 0xa8, 0x0e, 0xab, 0xf6, 0x2f, 0x7c, 0x88,
+    0xae, 0xcf, 0x90, 0xc6, 0x01, 0xd3, 0x5b, 0x37, 0xe9, 0xb1,
+    0x28, 0x42, 0x14, 0xbf, 0x59, 0x35, 0x04, 0xab, 0x46, 0x6e,
+    0xa8, 0x29, 0xe2, 0x7a, 0x77, 0x0e, 0x07, 0x67, 0xe4, 0x2b,
+    0x03, 0xd2, 0x02, 0x36, 0x16, 0xd7, 0x81, 0x5d, 0x38, 0x9c,
+    0x68, 0x9c, 0xf5, 0x9e, 0x49, 0x7d, 0x99, 0xfd, 0xcd, 0x1d,
+    0xd2, 0xdf, 0x3c, 0x36, 0x19, 0x85, 0xaa, 0xb1, 0x30, 0x7a,
+    0x21, 0xb1, 0x83, 0x16, 0xcf, 0xd1, 0x75, 0xa5, 0x9d, 0xd7,
+    0xc1, 0x60, 0xa8, 0xdb, 0x1e, 0xb9, 0x3e, 0x9c, 0x12, 0x42,
+    0xe8, 0x47, 0x49, 0x18, 0x9f, 0x5c, 0x12, 0xd1, 0x69, 0xd5,
+    0x7d, 0xa8, 0x3c, 0xda, 0x35, 0x8a, 0x6c, 0x63, 0xb8, 0x62,
+    0x8a, 0x61, 0xfa, 0xf2, 0x61, 0x11, 0x1e, 0xb6, 0xf3, 0x5c,
+    0x62, 0x9d, 0xa7, 0x62, 0x0c, 0x87, 0x93, 0xe2, 0x23, 0x6c,
+    0x3d, 0xa9, 0x2c, 0x4b, 0xd5, 0x7f, 0xfe, 0x72, 0x27, 0x36,
+    0x06, 0xcb, 0x65, 0x38, 0xef, 0x13, 0x57, 0x6a, 0xc9, 0xc6,
+    0x4f, 0x51, 0xd0, 0x90, 0x06, 0xa0, 0x23, 0x65, 0x95, 0xce,
+    0x16, 0x8f, 0x8d, 0xb2, 0xf9, 0x7f, 0x3c, 0x2c, 0x30, 0x5a,
+    0x38, 0xf1, 0x62, 0x79, 0x4b, 0xe5, 0xd7, 0x0a, 0x3f, 0x83,
+    0x5f, 0x46, 0x26, 0x97, 0xb7, 0x08, 0x8c, 0x5b, 0xb8, 0x02,
+    0x28, 0xf2, 0x4d, 0xdf, 0x93, 0x97, 0xc5, 0x94, 0x4b, 0x0e,
+    0x42, 0xc3, 0x35, 0x91, 0x6b, 0x69, 0x61, 0x76, 0x7f, 0x94,
+    0xcf, 0x0b, 0x81, 0x33, 0xff, 0xf3, 0x0c, 0xc7, 0x01, 0x94,
+    0x94, 0xa9, 0xed, 0xcd, 0x4b, 0xc8, 0xcb, 0x91, 0xf9, 0x7a,
+    0x47, 0xcd, 0x79, 0x3c, 0xa6, 0xde, 0x52, 0xd2, 0x47, 0x5c,
+    0x10, 0x62, 0xbb, 0xe5, 0x32, 0xde, 0x83, 0xcf, 0xa8, 0x52,
+    0xb3, 0xe7, 0xf9, 0xec, 0x17, 0x34, 0xbf, 0x33, 0x5d, 0xb2,
+    0x4e, 0x56, 0xf7, 0x29, 0xd9, 0x5c, 0x1b, 0x83, 0x01, 0xbb,
+    0xb9, 0x2b, 0x95, 0x52, 0x08, 0xab, 0xa4, 0x51, 0x03, 0xa1,
+    0xfb, 0x6a, 0x50, 0xcd, 0xa8, 0x9d, 0x95, 0x6f, 0x7e, 0xb1,
+    0x80, 0x1e, 0x9d, 0x81, 0x01, 0x26, 0x41, 0x78, 0x36, 0x3c,
+    0x8a, 0x44, 0xf4, 0x98, 0x88, 0x1c, 0x5d, 0x06, 0xd3, 0xd2,
+    0xb2, 0x58, 0x7d, 0xa1, 0x45, 0x1b, 0xbf, 0x8c, 0xf6, 0x6a,
+    0xfa, 0xfd, 0x08, 0x29, 0x3e, 0x91, 0x57, 0xf1, 0x3d, 0x20,
+    0xed, 0x49, 0x6e, 0x9c, 0x46, 0xd5, 0x08, 0x8d, 0x9b, 0xf8,
+    0xef, 0xa3, 0x3a, 0x98, 0xcb, 0xb4, 0xcb, 0x5b, 0x30, 0x25,
+    0x20, 0xcc, 0x04, 0xa1, 0xeb, 0xeb, 0xee, 0x1b, 0x36, 0x85,
+    0xc1, 0x93, 0x16, 0x5a, 0x31, 0xdf, 0xd6, 0x0e, 0x73, 0x9e,
+    0x63, 0x6e, 0x96, 0x90, 0x54, 0xd2, 0xc2, 0x53, 0x69, 0x93,
+    0xd5, 0x54, 0xca, 0xd8, 0x84, 0xf7, 0x8f, 0x9a, 0xd1, 0x80,
+    0x0d, 0x57, 0xa8, 0x26, 0xbe, 0x45, 0x64, 0xd5, 0x2b, 0xbb,
+    0x45, 0xb5, 0x08, 0xb9, 0x37, 0x57, 0x02, 0x82, 0x03, 0xc1,
+    0x00, 0xd1, 0x30, 0x2e, 0xb7, 0x9b, 0xe7, 0x5d, 0x13, 0x74,
+    0x1f, 0x52, 0xf2, 0x02, 0x18, 0xe9, 0x07, 0x87, 0x9e, 0xed,
+    0xde, 0x83, 0x92, 0xcf, 0x73, 0x61, 0x21, 0xc4, 0x62, 0x30,
+    0x6c, 0xa2, 0x36, 0xbd, 0xe2, 0xc5, 0x19, 0xf6, 0xdf, 0x51,
+    0x7b, 0xca, 0xd4, 0xe4, 0x51, 0x83, 0x49, 0x27, 0xdd, 0xbd,
+    0xb0, 0x10, 0x79, 0x39, 0xdd, 0x0e, 0x3d, 0x65, 0xad, 0x6d,
+    0xa3, 0x95, 0x52, 0x85, 0xdb, 0x18, 0x94, 0x60, 0xaa, 0xc0,
+    0xc8, 0x8b, 0xdb, 0xfe, 0xf9, 0xf0, 0x86, 0xf9, 0x33, 0x8a,
+    0xd7, 0xbe, 0x8d, 0x43, 0x83, 0x4d, 0xe4, 0x17, 0x2b, 0x46,
+    0x54, 0x44, 0x1b, 0xbe, 0x52, 0x64, 0x47, 0x02, 0x6c, 0x4a,
+    0x64, 0xb4, 0x3f, 0x21, 0x2f, 0xbb, 0xe3, 0x72, 0x7c, 0x26,
+    0x14, 0xdf, 0x80, 0x50, 0xd4, 0x94, 0xe9, 0xc6, 0x7d, 0x71,
+    0xd8, 0xaf, 0xfb, 0x74, 0x36, 0x33, 0xbe, 0x58, 0x63, 0xad,
+    0xcb, 0xdf, 0xc0, 0x73, 0x9e, 0x19, 0xb0, 0x65, 0xe1, 0xd1,
+    0x10, 0x44, 0xf1, 0xf0, 0x08, 0xa3, 0x09, 0x25, 0xeb, 0xd5,
+    0xcb, 0xdd, 0x98, 0xdd, 0xbc, 0x09, 0x2c, 0xef, 0xc1, 0x8d,
+    0x43, 0x15, 0x41, 0xc2, 0xa1, 0x84, 0x37, 0x70, 0x5a, 0xd5,
+    0xf5, 0xb2, 0x6a, 0x1f, 0xbb, 0xcc, 0x30, 0xb9, 0xd9, 0xc7,
+    0x36, 0x21, 0xf3, 0x69, 0x3e, 0x91, 0x38, 0x4d, 0xa5, 0xc4,
+    0xf7, 0x84, 0x90, 0x34, 0x0e, 0x47, 0x7e, 0x26, 0xf2, 0x98,
+    0x25, 0x26, 0xda, 0xf0, 0x4e, 0x55, 0xea, 0x4d, 0x9b, 0x8a,
+    0x4a, 0xe1, 0x1f, 0xa0, 0x07, 0x90, 0x9e, 0x59, 0x64, 0xae,
+    0xd9, 0xd6, 0x7e, 0x72, 0xa1, 0xc4, 0xea, 0x7d, 0xbd, 0x1f,
+    0x7d, 0x2b, 0xd9, 0x2c, 0xdc, 0x8b, 0xc0, 0xda, 0x52, 0x0c,
+    0xd1, 0xd0, 0x56, 0xb7, 0x93, 0xc7, 0x26, 0x79, 0x71, 0xd0,
+    0x0d, 0xae, 0xaa, 0xa7, 0xe4, 0xc1, 0x59, 0x27, 0x68, 0x97,
+    0x9a, 0xff, 0x3d, 0x36, 0x07, 0x55, 0x77, 0x07, 0x97, 0x69,
+    0xf3, 0x99, 0x91, 0x3f, 0x63, 0xfd, 0x70, 0x8c, 0xa1, 0xeb,
+    0xc5, 0x21, 0xa3, 0xfe, 0x99, 0x96, 0x11, 0x37, 0xb9, 0xe6,
+    0x93, 0xf8, 0xd0, 0xb1, 0xa3, 0x57, 0x7a, 0xa8, 0x63, 0xdd,
+    0x09, 0x56, 0xb0, 0x3b, 0xa6, 0x59, 0xc7, 0x89, 0x54, 0x16,
+    0xe9, 0x2d, 0x78, 0x7d, 0xaf, 0x4e, 0x0a, 0x5b, 0x62, 0x3b,
+    0x0b, 0xcb, 0x24, 0x89, 0x4e, 0x1c, 0x3d, 0xe1, 0xbd, 0x5a,
+    0x3e, 0xc5, 0xfd, 0x15, 0x3d, 0x08, 0x38, 0x33, 0x5e, 0x37,
+    0x4c, 0xe3, 0xe3, 0xe9, 0xc4, 0x1d, 0x2b, 0xd4, 0x58, 0x25,
+    0x58, 0x23, 0x8e, 0xc6, 0x83, 0x9a, 0xf3, 0x9a, 0x78, 0xe9,
+    0xa7, 0xca, 0xd7, 0xdd, 0x89, 0x20, 0x6e, 0x02, 0xea, 0x6b,
+    0x37, 0x74, 0xda, 0xa0, 0xc2, 0x5a, 0x2b, 0x80, 0x1c, 0x28,
+    0x91, 0x0d, 0x50, 0x64, 0xf0, 0x12, 0xe7, 0xc4, 0x7e, 0xdd,
+    0x28, 0x3b, 0x26, 0x9a, 0xf4, 0x39, 0x56, 0xa4, 0x72, 0x4d,
+    0xcb, 0x67, 0x3c, 0x68, 0xb2, 0x6f, 0xf0, 0xd0, 0x15, 0x90,
+    0xc8, 0x08, 0xbb, 0x0b, 0x08, 0x6b, 0x8a, 0xde, 0x41, 0x57,
+    0xbc, 0x63, 0x0e, 0x00, 0x8d, 0xf8, 0xdd, 0x93, 0xce, 0x58,
+    0x7b, 0xa8, 0xb9, 0x64, 0x26, 0x06, 0xe7, 0x71, 0x23, 0x0f,
+    0x41, 0xf1, 0xb7, 0xae, 0x59, 0x2e, 0xd0, 0x73, 0xc5, 0xd9,
+    0xdc, 0x0e, 0x1c, 0x02, 0x58, 0x69, 0xb3, 0x15, 0x6d, 0x96,
+    0x2b, 0xdb, 0x7b, 0x3b, 0x6c, 0x38, 0x32, 0x6b, 0xd8, 0x08,
+    0xb2, 0xbd, 0xa7, 0x49, 0x43, 0xeb, 0x90, 0x42, 0x70, 0xc5,
+    0xba, 0xcd, 0x4a, 0x44, 0x8f, 0x83, 0x0d, 0x17, 0x51, 0x5a,
+    0x95, 0xa2, 0x57, 0x9a, 0x16, 0x19, 0x91, 0xbb, 0x90, 0x5c,
+    0x2a, 0x16, 0xe8, 0x26, 0x10, 0x3c, 0xb7, 0x10, 0x5c, 0xf8,
+    0xc5, 0x15, 0x2b, 0x70, 0x75, 0x69, 0xba, 0x7b, 0x3d, 0x0b,
+    0x57, 0xac, 0x39, 0x12, 0x2e, 0xd6, 0xd9, 0x13, 0x74, 0x8e,
+    0xa8, 0x0b, 0x17, 0xe1, 0x03, 0x7a, 0xba, 0x1d, 0x07, 0x91,
+    0x8c, 0x2a, 0x3a, 0x8d, 0xe0, 0x2a, 0x94, 0xd4, 0x16, 0x35,
+    0x64, 0x8b, 0x92, 0x2c, 0x2f, 0xa4, 0x18, 0xfe, 0x3f, 0x02,
+    0x19, 0x8c, 0xb9, 0xeb, 0xaf, 0x01, 0x06, 0xa8, 0x37, 0x7f,
+    0xe2, 0x44, 0x10, 0xce, 0xeb, 0x8d, 0xd0, 0x73, 0xc4, 0x1e,
+    0x3d, 0x2c, 0xaf, 0x77, 0xb2, 0xef, 0xe5, 0x95, 0x8b, 0xdf,
+    0x02, 0xfc, 0x93, 0xb8, 0xa9, 0x27, 0x88, 0x1d, 0x1d, 0x82,
+    0x9f, 0xb6, 0xe4, 0x12, 0x05, 0x79, 0xb6, 0x1c, 0x41, 0x0d,
+    0xc1, 0x53, 0x49, 0x8f, 0x3d, 0xc9, 0xad, 0x84, 0xcb, 0x0b,
+    0x88, 0x7e, 0xfe, 0x73, 0x59, 0x21, 0x64, 0xc5, 0x50, 0x53,
+    0xdc, 0x98, 0xc6, 0x43, 0xb8, 0xf5, 0xc3, 0xa1, 0xf5, 0xb2,
+    0xd8, 0x86, 0xe9, 0xae, 0x98, 0xf9, 0x3b, 0x99, 0xc0, 0xe7,
+    0xd7, 0x4a, 0xed, 0xac, 0x89, 0x84, 0xb0, 0x8e, 0xd3, 0xab,
+    0xec, 0x03, 0x02, 0x12, 0x4b, 0x44, 0x17, 0x4d, 0x98, 0x26,
+    0x1e, 0x51, 0xc5, 0xbb, 0xcd, 0xdc, 0x50, 0xab, 0x83, 0x37,
+    0x49, 0x90, 0x1e, 0x34, 0xad, 0x81, 0x22, 0x6c, 0xe4, 0xdd,
+    0x19, 0x01, 0x09, 0x25, 0x2d, 0x9e, 0x52, 0x90, 0x72, 0xa1,
+    0x68, 0x3d, 0x0c, 0x49, 0x99, 0x19, 0x75, 0x5a, 0xca, 0x08,
+    0x69, 0xa1, 0xd2, 0x88, 0x8c, 0xea, 0xcf, 0x9c, 0xbc, 0x23,
+    0xad, 0x3f, 0xb9, 0xfc, 0xb9, 0x30, 0x0d, 0xd6, 0xd9, 0x65,
+    0x0c, 0x7e, 0x99, 0x68, 0x35, 0x26, 0x07, 0xd1, 0x55, 0xbf,
+    0x8e, 0xde, 0xe7, 0xe7, 0x01, 0xcb, 0xca, 0x0a, 0x39, 0x2e,
+    0xcc, 0x19, 0xec, 0x77, 0xf3, 0xab, 0xb2, 0xe6, 0x0e, 0x54,
+    0x06, 0x01, 0x50, 0x77, 0xd3, 0x61, 0x36, 0x05, 0x90, 0xe4,
+    0xd8, 0xc4, 0x1d, 0xf5, 0xc7, 0xfa, 0x65, 0xf0, 0x46, 0x6a,
+    0x5f, 0xa7, 0xc3, 0x8c, 0x6f, 0x04, 0x7f, 0xcf, 0x97, 0xb9,
+    0x68, 0x92, 0x31, 0x09, 0x02, 0x9f, 0x22, 0xc9, 0xf8, 0xe6,
+    0x7e, 0xa8, 0x95, 0x5b, 0x6b, 0xfe, 0x9c, 0x4e, 0x63, 0x2d,
+    0x8c, 0x1a, 0x4c, 0x8b, 0x14, 0x79, 0x08, 0xd5, 0x96, 0x76,
+    0xd1, 0xb4, 0x2f, 0xae, 0x5d, 0x91, 0x88, 0x7c, 0xdd, 0xd2,
+    0x06, 0x86, 0xcf, 0x0a, 0x83, 0x6f, 0xda, 0xca, 0x71, 0x7c,
+    0xe7, 0xe5, 0x34, 0xa8, 0x9a, 0x53, 0x8d, 0xa5, 0xaa, 0x5d,
+    0xb5, 0x17, 0x81, 0x34, 0x6f, 0xbe, 0xbb, 0xb6, 0x58, 0x22,
+    0x90, 0x80, 0xf6, 0x9c, 0x1c, 0xb0, 0x79, 0x8f, 0x92, 0x5b,
+    0x7d, 0x1c, 0x71, 0x5f, 0xb4, 0x87, 0x36, 0xbe, 0x81, 0x8d,
+    0x4a, 0xfc, 0x28, 0x72, 0x81, 0xaf, 0x5f, 0xbd, 0x5f, 0x99,
+    0xe3, 0xc9, 0x37, 0xb0, 0x6e, 0xad, 0x70, 0x96, 0xfa, 0xe3,
+    0x99, 0xf7, 0x08, 0x14, 0x21, 0x21, 0xb7, 0x1a, 0xaa, 0xe8,
+    0x07, 0xb6, 0xfd, 0xa3, 0x7a, 0x2d, 0x93, 0x64, 0x8f, 0x89,
+    0x2c, 0x71, 0x49, 0x71, 0xb8, 0x45, 0xca, 0xe0, 0x7c, 0x00,
+    0x8d, 0xbd, 0xb8, 0x1c, 0x3a, 0x94, 0xa2, 0xa7, 0x6d, 0x0a,
+    0x2e, 0x84, 0xaf, 0xbd, 0xab, 0x05, 0x95, 0x64, 0x8b, 0x05,
+    0xc8, 0xc9, 0x4e, 0xea, 0xb5, 0x96, 0x4a, 0x47, 0xdd, 0xf2,
+    0xcb, 0x02, 0x82, 0x03, 0xc0, 0x59, 0xb3, 0xd9, 0x85, 0xdc,
+    0xa8, 0xb9, 0x93, 0x85, 0xa2, 0xbc, 0x79, 0xfc, 0x72, 0x50,
+    0xc1, 0xa0, 0xa5, 0xdb, 0x71, 0x35, 0xa1, 0x31, 0xbc, 0x68,
+    0x4e, 0xd5, 0x19, 0x9e, 0x0e, 0x32, 0x3a, 0xad, 0x40, 0x9e,
+    0x82, 0x3c, 0x1e, 0x2b, 0x34, 0x3b, 0xc9, 0x32, 0x61, 0x07,
+    0x5e, 0x46, 0xa9, 0xbe, 0xbe, 0x73, 0x0c, 0x12, 0xef, 0x52,
+    0x68, 0x82, 0xe2, 0x0b, 0x12, 0x74, 0xfc, 0x10, 0x5c, 0xc0,
+    0xb5, 0x98, 0x4d, 0x86, 0xbb, 0x8c, 0x40, 0x15, 0xa1, 0x6e,
+    0x46, 0x73, 0x2e, 0xd6, 0x99, 0x6b, 0x50, 0xab, 0x04, 0x1a,
+    0x5f, 0xf4, 0xfa, 0xcb, 0x4b, 0xad, 0xc4, 0x5e, 0x62, 0xa7,
+    0x48, 0xd4, 0x52, 0x85, 0xdc, 0x2a, 0x85, 0x9b, 0xee, 0x08,
+    0xa5, 0xaa, 0xaa, 0xe8, 0x44, 0xf0, 0xed, 0x89, 0x21, 0xe4,
+    0xb4, 0xab, 0x3c, 0x0d, 0x53, 0x7e, 0x53, 0xdd, 0xac, 0x47,
+    0xda, 0x77, 0x79, 0x5f, 0x78, 0x7a, 0x80, 0x84, 0x46, 0x50,
+    0xaa, 0xdb, 0x3b, 0x8c, 0x6b, 0xda, 0xb0, 0xac, 0x0a, 0xd3,
+    0x4c, 0xe4, 0x6e, 0x87, 0xd1, 0xb2, 0x5a, 0xd5, 0x98, 0xae,
+    0xcb, 0x7e, 0xc2, 0x19, 0xdc, 0x53, 0x64, 0x86, 0x4c, 0x7b,
+    0xe0, 0x63, 0x22, 0x94, 0x34, 0xad, 0x15, 0xdc, 0xd8, 0xa8,
+    0x5f, 0xc6, 0x58, 0xf6, 0x72, 0x34, 0xdd, 0xfb, 0x85, 0x8a,
+    0xd9, 0xa3, 0xfb, 0x3b, 0xad, 0x5d, 0xf0, 0x1a, 0x0b, 0xa8,
+    0x91, 0xe7, 0x7d, 0x26, 0x27, 0x38, 0xf8, 0xe0, 0x49, 0x1b,
+    0x56, 0xc5, 0x5b, 0xe3, 0x1c, 0x7b, 0xa3, 0x53, 0x6d, 0x22,
+    0xfa, 0xd7, 0x63, 0x5f, 0xf0, 0xcb, 0x92, 0x49, 0x01, 0x54,
+    0xe5, 0x77, 0x5b, 0xd3, 0xab, 0xce, 0xb8, 0x3a, 0x5b, 0xb8,
+    0x07, 0x40, 0x46, 0x51, 0xe4, 0x59, 0xa2, 0x45, 0x41, 0xcc,
+    0x81, 0x6c, 0xe3, 0xa6, 0xb3, 0xa0, 0x30, 0x4a, 0x67, 0x10,
+    0xed, 0xc0, 0x8a, 0xcd, 0xfc, 0xa5, 0x44, 0x9b, 0x59, 0x19,
+    0x4a, 0x43, 0x8d, 0xec, 0x00, 0xd8, 0x6d, 0xf9, 0xf0, 0x2d,
+    0xd9, 0x55, 0xfc, 0x05, 0xe2, 0x12, 0x48, 0x4d, 0xd6, 0x7d,
+    0xec, 0x41, 0xc4, 0x9e, 0xe2, 0xed, 0x84, 0x14, 0x29, 0x0e,
+    0x5b, 0x81, 0x0b, 0xb0, 0x87, 0x8a, 0xd3, 0x35, 0x5c, 0xad,
+    0xdb, 0xcc, 0xa1, 0x3c, 0xcb, 0x8b, 0x23, 0x55, 0x69, 0xf1,
+    0x83, 0x84, 0x81, 0x36, 0xae, 0xd5, 0xf3, 0x98, 0xb6, 0xb2,
+    0xb5, 0xa1, 0x79, 0x6d, 0x80, 0x8f, 0x2e, 0x25, 0x71, 0x4e,
+    0x16, 0xff, 0xa0, 0x7c, 0xa4, 0x62, 0x8c, 0x44, 0x85, 0x64,
+    0x90, 0x7c, 0xac, 0x10, 0x36, 0xf2, 0xf2, 0xfb, 0x20, 0x2b,
+    0xa1, 0x27, 0xd0, 0xcc, 0x27, 0xfd, 0xb0, 0xba, 0x3e, 0x37,
+    0xb1, 0xa8, 0x9d, 0x3c, 0x82, 0x63, 0xd0, 0x16, 0x6d, 0x7a,
+    0xdd, 0x2e, 0xea, 0xe5, 0x87, 0xd6, 0x64, 0x72, 0xdb, 0x60,
+    0x53, 0x38, 0x18, 0x66, 0x1d, 0x25, 0xf6, 0x08, 0x92, 0x7f,
+    0x68, 0x5b, 0x79, 0x07, 0xde, 0x93, 0xee, 0xf8, 0x8f, 0xce,
+    0x28, 0xcf, 0xb1, 0x5b, 0x43, 0x51, 0xdf, 0xf5, 0xac, 0xe8,
+    0x9c, 0x95, 0x14, 0x8a, 0x67, 0xe1, 0x25, 0xfe, 0x11, 0xa2,
+    0x40, 0xf8, 0xdd, 0xcf, 0xf5, 0x17, 0x94, 0xb6, 0x88, 0x10,
+    0xa2, 0x90, 0x58, 0xef, 0xaf, 0x73, 0xf8, 0x7c, 0x9b, 0x20,
+    0x30, 0x79, 0xca, 0x3f, 0xa9, 0x22, 0x40, 0xfd, 0xcc, 0xb0,
+    0x5d, 0x0d, 0x97, 0x6b, 0xc0, 0x75, 0x35, 0x33, 0xc5, 0x76,
+    0x45, 0x6e, 0x9b, 0x78, 0xe7, 0xb4, 0x04, 0xb3, 0xba, 0x3b,
+    0x93, 0xb1, 0xa9, 0x8f, 0xa1, 0x24, 0x5d, 0x1c, 0x0e, 0x66,
+    0xc0, 0xc6, 0xcc, 0xd6, 0xb7, 0x88, 0x9d, 0xb8, 0x45, 0xe3,
+    0xaa, 0xc9, 0x6c, 0xfd, 0x37, 0xdc, 0x85, 0xd5, 0x49, 0xfd,
+    0xef, 0xeb, 0xf9, 0x7a, 0x3f, 0x7a, 0x4f, 0x86, 0x49, 0xaa,
+    0x9f, 0x08, 0x12, 0x0b, 0x11, 0x35, 0x5c, 0xd5, 0xd3, 0xda,
+    0x14, 0x50, 0x03, 0x2c, 0x24, 0x26, 0x0e, 0x29, 0x18, 0xcc,
+    0x1d, 0x0a, 0x7c, 0x94, 0x8b, 0xc0, 0xa0, 0x3f, 0xea, 0xf8,
+    0xf8, 0xa9, 0x1d, 0x65, 0x31, 0x6f, 0x3b, 0xa6, 0xd0, 0xfc,
+    0x26, 0xb0, 0x4e, 0x3a, 0x66, 0xe7, 0x32, 0x10, 0x2e, 0x84,
+    0x47, 0xad, 0xa9, 0x18, 0xfc, 0xa3, 0x8b, 0x74, 0x84, 0x4f,
+    0xd4, 0x25, 0x93, 0x0f, 0xdb, 0x2e, 0xae, 0x88, 0x8e, 0x28,
+    0xf8, 0x0f, 0xaa, 0x60, 0xd4, 0xbe, 0xad, 0x66, 0x0c, 0x0d,
+    0x01, 0xbd, 0x8d, 0xc4, 0xfc, 0x48, 0xef, 0x78, 0x14, 0x34,
+    0xee, 0xb3, 0xbc, 0xd4, 0xbb, 0x1f, 0x7c, 0x12, 0x5c, 0x9b,
+    0xeb, 0x77, 0x3e, 0x2c, 0x6e, 0x31, 0x59, 0xe6, 0x78, 0xc5,
+    0xe8, 0xa4, 0xdd, 0xf1, 0xef, 0x5d, 0x27, 0x45, 0x31, 0x13,
+    0xd0, 0x21, 0xa1, 0x13, 0xce, 0xac, 0x7e, 0xbb, 0xfb, 0x32,
+    0xeb, 0x76, 0x31, 0xc4, 0xba, 0xdf, 0xfb, 0x5a, 0x1b, 0xc9,
+    0x9e, 0x74, 0xa0, 0x9e, 0x26, 0x82, 0xd5, 0x6e, 0x1d, 0xc3,
+    0x0e, 0xd1, 0x6d, 0xdb, 0x43, 0xb3, 0x0b, 0x14, 0xcb, 0xf1,
+    0xad, 0x62, 0x34, 0x49, 0xb8, 0xd3, 0x08, 0xca, 0x93, 0xf1,
+    0x42, 0xb2, 0x4b, 0x23, 0x79, 0x93, 0xde, 0x18, 0x58, 0xf3,
+    0x66, 0xfa, 0xdc, 0xab, 0xca, 0x33, 0x22, 0x2b, 0x5c, 0x8c,
+    0x12, 0xc1, 0x7b, 0x2e, 0x52, 0x72, 0xa7, 0x78, 0x4a, 0x49,
+    0xa1, 0x53, 0x02, 0x76, 0x2d, 0x2e, 0xf8, 0x43, 0x3c, 0xe8,
+    0xfa, 0xb7, 0xff, 0x39, 0xed, 0x74, 0x9e, 0x11, 0x61, 0x33,
+    0xde, 0x2a, 0x55, 0xe6, 0x4a, 0xe7, 0x97, 0xa6, 0xb2, 0xc3,
+    0x40, 0x41, 0x52, 0x66, 0xcf, 0xbf, 0xf8, 0x8e, 0x08, 0xea,
+    0x96, 0x4d, 0x03, 0xc9, 0xbe, 0x3c, 0x4e, 0x36, 0x8c, 0x6f,
+    0x4d, 0x1e, 0xcd, 0x31, 0x6d, 0x53, 0xea, 0x9e, 0xf0, 0x8e,
+    0x35, 0x97, 0x37, 0x54, 0xe9, 0x0f, 0xb8, 0x23, 0x25, 0x69,
+    0x5b, 0xb5, 0xff, 0xc3, 0x5a, 0x2d, 0x10, 0x6a, 0xc0, 0xb8,
+    0xee, 0x0d, 0x31, 0x5b, 0xe4, 0x69, 0x40, 0x62, 0xa7, 0x1b,
+    0x16, 0xfa, 0xd6, 0xb8, 0xba, 0xc8, 0x6a, 0xa3, 0x29, 0xdd,
+    0x9b, 0x4d, 0xd7, 0x96, 0xef, 0x31, 0x74, 0xac, 0x37, 0x10,
+    0x91, 0x30, 0x0c, 0x15, 0x3f, 0x09, 0xb6, 0x7d, 0x22, 0xfb,
+    0x8c, 0x6f, 0xc3, 0x93, 0xa3, 0x98, 0xa6, 0x23, 0xa4, 0x55,
+    0xe0, 0x9e, 0x23, 0x06, 0xa9, 0x78, 0xe9, 0xb3, 0x88, 0xc9,
+    0xb7, 0x83, 0x05, 0x46, 0x11, 0x3a, 0x0a, 0xb9, 0x74, 0x5b,
+    0xa0, 0xb5, 0x06, 0x96, 0x86, 0xb6, 0xf4, 0x9d, 0x0d, 0x86,
+    0x43, 0xa8, 0x40, 0x4b, 0x08, 0x93, 0x7c, 0xad, 0xb0, 0x50,
+    0xb4, 0xd0, 0xe7, 0xad, 0xd0, 0x54, 0x5e, 0x15, 0xaf, 0xad,
+    0x34, 0x12, 0x86, 0xb3, 0x29, 0x3b, 0x20, 0xc9, 0xad, 0xeb,
+    0xc2, 0x65, 0xf3, 0x5c, 0x2d, 0xe5, 0xff, 0xfd, 0x81, 0x79,
+    0xf5, 0x11, 0x6f, 0xf7, 0xca, 0x0c, 0x76, 0xf0, 0xd4, 0x02,
+    0x9d, 0xb7, 0x76, 0x39, 0x6d, 0x32, 0x6a, 0xb8, 0x30, 0xa4,
+    0x01, 0xcc, 0x10, 0xef, 0xb1, 0x0e, 0x41, 0x22, 0x82, 0x5b,
+    0x22, 0xcb, 0x32, 0x19, 0x2e, 0xa3, 0x0a, 0xce, 0x05, 0xdd,
+    0xe8, 0x4a, 0x58, 0x92, 0xe1, 0x02, 0x82, 0x03, 0xc0, 0x22,
+    0x0f, 0x95, 0x5b, 0xc2, 0x1f, 0xde, 0xf0, 0xde, 0xf4, 0x86,
+    0xbd, 0xef, 0x07, 0x7d, 0x52, 0x03, 0x8c, 0x26, 0x31, 0x17,
+    0xfd, 0x5c, 0x97, 0xed, 0xd5, 0xe0, 0xb3, 0x18, 0x2d, 0x68,
+    0x10, 0x3f, 0xc4, 0xdf, 0xd1, 0x05, 0x78, 0x81, 0x3d, 0x05,
+    0xde, 0xba, 0x3a, 0x67, 0x85, 0x0e, 0xdf, 0xb5, 0x16, 0x28,
+    0xe8, 0x84, 0x3a, 0x71, 0x2a, 0x20, 0x17, 0x28, 0x05, 0xfd,
+    0xb7, 0x4d, 0x22, 0x4a, 0x93, 0x46, 0x56, 0x27, 0x43, 0xc0,
+    0x3a, 0x16, 0xff, 0x3d, 0x61, 0xcc, 0xcb, 0xce, 0xac, 0xa8,
+    0x53, 0x3a, 0x0d, 0xf4, 0x2d, 0xd2, 0x73, 0xf2, 0x64, 0xa0,
+    0x1e, 0x60, 0x53, 0xec, 0x0d, 0xff, 0xe0, 0x00, 0x10, 0xfb,
+    0xa4, 0x57, 0xd3, 0xfc, 0xe4, 0xe0, 0xec, 0x44, 0x0b, 0x1c,
+    0x05, 0x39, 0xa4, 0x13, 0x87, 0x29, 0x11, 0x9d, 0xea, 0xe9,
+    0x64, 0xa9, 0x1c, 0x76, 0x3a, 0x65, 0x0b, 0xfd, 0xed, 0x77,
+    0x46, 0x4f, 0xcd, 0x0b, 0x63, 0xc4, 0x83, 0x0b, 0x56, 0x79,
+    0xd3, 0x67, 0x01, 0x11, 0x02, 0xd9, 0x50, 0xd8, 0x23, 0xf4,
+    0xb6, 0x02, 0x4c, 0xae, 0xb5, 0xc9, 0x68, 0x1b, 0x87, 0x33,
+    0xbb, 0xdc, 0x64, 0x0e, 0x32, 0x34, 0xb2, 0x25, 0xaa, 0x76,
+    0xdd, 0x7e, 0xc3, 0x46, 0x51, 0x1c, 0xc1, 0xd0, 0x05, 0x09,
+    0x6c, 0x27, 0xd3, 0xcf, 0x33, 0x7a, 0xb9, 0x26, 0x24, 0x23,
+    0x4a, 0x93, 0x9f, 0x4b, 0x96, 0xc7, 0xe2, 0xb2, 0x51, 0x42,
+    0x4d, 0x5d, 0xd9, 0x73, 0x75, 0xce, 0x23, 0x28, 0x56, 0x5e,
+    0xe7, 0x96, 0x58, 0x04, 0xfd, 0x33, 0x93, 0x08, 0x41, 0x62,
+    0x02, 0x7e, 0xc9, 0xc6, 0x55, 0x64, 0x19, 0xda, 0x39, 0xb8,
+    0x5d, 0x09, 0x47, 0xf3, 0xdd, 0x77, 0xee, 0xea, 0x35, 0x73,
+    0x95, 0xdb, 0x18, 0x4d, 0xd1, 0xfe, 0xee, 0x40, 0x31, 0x2a,
+    0x22, 0x91, 0x69, 0xd6, 0xed, 0x9c, 0x54, 0x14, 0x73, 0x61,
+    0x61, 0xe7, 0x1d, 0x34, 0x96, 0x47, 0xff, 0x28, 0x7a, 0x48,
+    0xa3, 0xf4, 0xcd, 0x64, 0x23, 0xe2, 0x52, 0x2f, 0x20, 0x8f,
+    0x04, 0xb3, 0xdc, 0xf0, 0x29, 0x67, 0x88, 0x76, 0x79, 0xdb,
+    0x86, 0xa7, 0x95, 0xf0, 0x15, 0x81, 0xbb, 0x98, 0xee, 0xff,
+    0x55, 0x7c, 0xb0, 0xee, 0x67, 0x65, 0xfd, 0xf2, 0x29, 0x0f,
+    0x85, 0x51, 0xf9, 0xac, 0x5c, 0x55, 0x5a, 0xde, 0x40, 0x62,
+    0x58, 0x55, 0x9f, 0x09, 0x4c, 0x2e, 0x28, 0x75, 0xbc, 0x48,
+    0xe2, 0x97, 0x85, 0xb3, 0x83, 0xeb, 0x21, 0x49, 0x21, 0xd4,
+    0xed, 0x74, 0x4f, 0xc1, 0x6c, 0x34, 0x8c, 0x11, 0xb0, 0x93,
+    0x41, 0x99, 0x23, 0x2e, 0xa4, 0xc1, 0x9f, 0x34, 0x74, 0x64,
+    0xbb, 0xd7, 0x4f, 0x8f, 0x9f, 0x3a, 0x0c, 0x4f, 0x5e, 0xdd,
+    0x41, 0x07, 0xf1, 0xfd, 0x5a, 0x9d, 0xe6, 0x77, 0xd8, 0x7e,
+    0x71, 0x7b, 0xad, 0xf7, 0x76, 0x13, 0x71, 0x90, 0xb3, 0x0f,
+    0x46, 0x8e, 0xee, 0x7b, 0x33, 0x97, 0x5d, 0x21, 0x3b, 0xa0,
+    0x58, 0x9e, 0xb7, 0x87, 0x30, 0x8f, 0xc1, 0x23, 0x2c, 0xde,
+    0xf7, 0x0d, 0xa9, 0xd6, 0x50, 0xeb, 0x35, 0x7a, 0x82, 0xab,
+    0x22, 0x49, 0x86, 0xd4, 0x61, 0xc7, 0xc2, 0x4e, 0x77, 0xfc,
+    0x16, 0x0b, 0xaf, 0x81, 0x6a, 0x47, 0xea, 0xac, 0x7e, 0x51,
+    0x4c, 0x56, 0x30, 0x21, 0x46, 0x41, 0xc3, 0x92, 0x60, 0x99,
+    0x4f, 0x88, 0x36, 0x3b, 0x27, 0xb4, 0xb2, 0x7e, 0x44, 0x2f,
+    0xdd, 0x95, 0xe4, 0x5e, 0x16, 0x1f, 0xa7, 0x32, 0x6b, 0x60,
+    0x24, 0x0f, 0xf2, 0xe6, 0x35, 0x3c, 0x0c, 0x3e, 0xb5, 0xd6,
+    0xdd, 0x63, 0xe2, 0x76, 0x35, 0x38, 0x79, 0xbf, 0xa5, 0x23,
+    0xa4, 0xdd, 0xeb, 0x01, 0x48, 0xd0, 0x60, 0x86, 0x11, 0x38,
+    0x5f, 0x9e, 0x6b, 0x00, 0x67, 0xd2, 0x5b, 0x41, 0x0a, 0x5e,
+    0x13, 0x0f, 0xa1, 0x9e, 0x90, 0x85, 0xa6, 0x7f, 0xe5, 0x4b,
+    0x9e, 0x93, 0x4e, 0x5b, 0x1f, 0x47, 0x62, 0xb0, 0x23, 0xbe,
+    0x82, 0xa9, 0xd9, 0xb6, 0x2e, 0xfd, 0xb1, 0x10, 0xca, 0xe0,
+    0xc9, 0x5d, 0xf6, 0x85, 0x18, 0x6c, 0x9c, 0x1d, 0x1f, 0x7c,
+    0xf6, 0x55, 0x09, 0x80, 0xcf, 0xac, 0xfe, 0x37, 0x6a, 0x4f,
+    0x96, 0xaa, 0x40, 0x79, 0x8b, 0x4a, 0xf2, 0x96, 0x79, 0x12,
+    0x1a, 0x26, 0x87, 0x06, 0x35, 0x4d, 0xd4, 0x3e, 0x14, 0x39,
+    0xe5, 0x6c, 0x39, 0x0f, 0x84, 0xb3, 0x5f, 0xed, 0xf4, 0xff,
+    0x89, 0x52, 0x05, 0x00, 0xf1, 0xd1, 0xc3, 0xcf, 0x54, 0x10,
+    0x24, 0x7c, 0xa6, 0xb5, 0x95, 0xa8, 0x6e, 0x13, 0x3e, 0x4a,
+    0x40, 0x6c, 0xf9, 0x63, 0x90, 0x44, 0x52, 0x07, 0x53, 0xb7,
+    0x51, 0xd9, 0x18, 0x47, 0x2e, 0xb0, 0x4e, 0x0f, 0x09, 0x99,
+    0x3a, 0x97, 0x26, 0x53, 0xa6, 0x02, 0x06, 0x0e, 0x93, 0xe1,
+    0x0b, 0xc5, 0xa9, 0x14, 0xd3, 0xd6, 0x8a, 0x29, 0x75, 0xcd,
+    0xb6, 0x7b, 0x64, 0x7c, 0xdd, 0x7e, 0xb4, 0x0a, 0x87, 0x48,
+    0x4a, 0x1b, 0x0e, 0x74, 0x4c, 0xd3, 0x0e, 0x96, 0x0e, 0x53,
+    0xc4, 0x3d, 0x7b, 0x1c, 0x87, 0x6a, 0x15, 0xd8, 0x77, 0xba,
+    0xe6, 0xa0, 0x2f, 0x2c, 0x1a, 0x9d, 0xde, 0x79, 0xfd, 0xab,
+    0x44, 0x80, 0xf0, 0x37, 0x9a, 0x3b, 0xf8, 0xde, 0x3d, 0x29,
+    0xcb, 0x89, 0x64, 0x4b, 0x57, 0xe7, 0x6b, 0x84, 0x09, 0x27,
+    0x17, 0x2f, 0xb2, 0xba, 0x3d, 0x09, 0xc9, 0x3c, 0x89, 0xe6,
+    0x19, 0x73, 0x83, 0xf7, 0xc6, 0x19, 0x18, 0x96, 0xb2, 0x7d,
+    0x1e, 0x9f, 0x70, 0x1f, 0xfc, 0x1f, 0xe2, 0xb5, 0x69, 0x1e,
+    0xf4, 0x65, 0x91, 0xce, 0x4b, 0xdc, 0x74, 0x49, 0x21, 0x64,
+    0x8b, 0x33, 0x50, 0xd2, 0xc1, 0x33, 0x62, 0x5b, 0xde, 0x0a,
+    0x72, 0xbe, 0xc0, 0x05, 0x51, 0x15, 0x80, 0xed, 0x32, 0x3a,
+    0x64, 0xa2, 0x73, 0x68, 0x5b, 0x16, 0xcf, 0x70, 0x5c, 0x98,
+    0xe5, 0x67, 0x45, 0x60, 0x57, 0x2b, 0x47, 0x0a, 0x22, 0x73,
+    0xc3, 0x56, 0x33, 0x3e, 0x14, 0x1d, 0x0c, 0xd1, 0x03, 0x08,
+    0x92, 0x21, 0x2b, 0xa9, 0x6e, 0x6b, 0xf9, 0x0c, 0x1e, 0x86,
+    0xdd, 0xb5, 0xbb, 0xa4, 0xa5, 0x82, 0x99, 0x98, 0x49, 0x36,
+    0xec, 0x98, 0x98, 0x95, 0xac, 0xc2, 0xa0, 0x1f, 0xa5, 0x7e,
+    0x67, 0xd1, 0xcf, 0x6a, 0xf4, 0x16, 0x08, 0x7a, 0x8d, 0x0b,
+    0xae, 0x12, 0x51, 0xe6, 0x8e, 0xe6, 0xcd, 0xa1, 0xaa, 0x6d,
+    0xe4, 0x54, 0xd4, 0x69, 0x1b, 0x09, 0x6a, 0xba, 0x5e, 0x0b,
+    0x11, 0x9c, 0x83, 0xb3, 0x5c, 0x67, 0xbb, 0x2d, 0xf8, 0x66,
+    0x1c, 0x33, 0xb8, 0x22, 0x58, 0x10, 0x96, 0xe9, 0x99, 0xaf,
+    0x0b, 0x2a, 0xf1, 0xe0, 0xcb, 0x56, 0xfb, 0x6d, 0x04, 0x40,
+    0xec, 0x37, 0x67, 0x1e, 0x08, 0x7a, 0x1c, 0xe9, 0xd8, 0x54,
+    0xf7, 0xd4, 0xc7, 0x3c, 0x45, 0x23, 0x2b, 0x76, 0xd2, 0x62,
+    0xc2, 0x53, 0xce, 0xfe, 0x02, 0xc4, 0xd9, 0xf6, 0x3c, 0xed,
+    0x49, 0x47, 0x21, 0xf9, 0x03, 0x3a, 0xa0, 0x16, 0x3a, 0xfe,
+    0x0c, 0x2f, 0x54, 0x7e, 0x85, 0x29, 0x7b, 0xc0, 0xaf, 0xa8,
+    0x5d, 0x31, 0x25, 0xda, 0xa7, 0xe3, 0x92, 0x1b, 0x64, 0x01,
+    0x1b, 0x3f, 0x6e, 0x47, 0xc5, 0x5a, 0x84, 0x52, 0x17, 0x02,
+    0x82, 0x03, 0xc1, 0x00, 0x81, 0x99, 0x2e, 0x72, 0x41, 0x6e,
+    0x86, 0xeb, 0x6f, 0x42, 0xd1, 0x38, 0x6e, 0xaa, 0x1a, 0xd5,
+    0x0a, 0xad, 0x51, 0xb1, 0xce, 0xd6, 0x35, 0xbe, 0x34, 0xd8,
+    0xc1, 0xe4, 0x5f, 0xdf, 0x2e, 0xe4, 0x90, 0xf2, 0x61, 0x21,
+    0x46, 0xc6, 0xfe, 0xab, 0x0f, 0x6c, 0x97, 0x78, 0xcd, 0x55,
+    0x86, 0x83, 0x61, 0x99, 0x49, 0x14, 0x86, 0xc6, 0x86, 0xf1,
+    0x41, 0x66, 0xc9, 0x39, 0x52, 0x99, 0x49, 0x07, 0xd6, 0x9d,
+    0xb7, 0x40, 0x34, 0x5f, 0xe7, 0x3a, 0xfa, 0x95, 0xeb, 0xa1,
+    0x03, 0xb7, 0x52, 0x71, 0x93, 0x30, 0x0b, 0x51, 0x58, 0x82,
+    0x07, 0x2f, 0x44, 0xa9, 0x4f, 0x9b, 0x1b, 0xf3, 0xd6, 0x21,
+    0x3d, 0x68, 0xef, 0x3f, 0xaf, 0xc2, 0x6f, 0xa0, 0xd5, 0x2b,
+    0xb8, 0x73, 0x84, 0x67, 0x36, 0x8b, 0xa4, 0x25, 0xe0, 0x86,
+    0xd9, 0x14, 0x5c, 0x6c, 0xd8, 0x61, 0xe1, 0x0a, 0x6c, 0xaf,
+    0xbb, 0x9c, 0xf6, 0x74, 0xca, 0x5a, 0x04, 0xac, 0x85, 0xc1,
+    0x1b, 0x4d, 0xf2, 0x07, 0xb6, 0x1e, 0x97, 0x7b, 0x75, 0xdf,
+    0x9b, 0x8a, 0x31, 0xc6, 0x90, 0xd5, 0x8d, 0x39, 0xc2, 0x54,
+    0xf4, 0xe2, 0x83, 0x57, 0x12, 0x19, 0xf5, 0xb2, 0xd2, 0x53,
+    0x81, 0x6d, 0xf0, 0x09, 0xc9, 0x80, 0x8b, 0x07, 0x7c, 0x59,
+    0xcd, 0x78, 0x00, 0xd6, 0x44, 0x7f, 0xe4, 0xdb, 0x77, 0x02,
+    0x00, 0x25, 0x79, 0x91, 0xc9, 0xde, 0xd0, 0xed, 0x3f, 0xfc,
+    0x37, 0x36, 0xea, 0xf0, 0x56, 0x50, 0xe7, 0x38, 0xca, 0xe1,
+    0x67, 0x12, 0x96, 0x55, 0x3e, 0xff, 0x97, 0xe5, 0xa7, 0x03,
+    0x5b, 0x72, 0x80, 0xd6, 0xa5, 0x23, 0x39, 0x78, 0x07, 0xc8,
+    0x83, 0x19, 0x74, 0xfb, 0x79, 0xc2, 0x9e, 0xbd, 0xf9, 0xaf,
+    0x09, 0x0f, 0xbd, 0x3d, 0x34, 0xe8, 0x44, 0x89, 0xb1, 0xf1,
+    0x2b, 0xa5, 0xff, 0x22, 0xc9, 0x47, 0xe2, 0x31, 0xb5, 0x6b,
+    0x8a, 0x65, 0x5f, 0x81, 0x5f, 0x89, 0xb0, 0x03, 0x5d, 0x53,
+    0x0e, 0xdd, 0xfb, 0xe5, 0x70, 0xaa, 0xd2, 0x37, 0x4d, 0xa1,
+    0x7c, 0xf2, 0xe4, 0x7f, 0xf1, 0x4a, 0xaf, 0x12, 0xd1, 0x83,
+    0xdc, 0xb2, 0x9e, 0xc1, 0x95, 0x3d, 0x04, 0x9f, 0xa3, 0xad,
+    0xcc, 0x78, 0x14, 0x9a, 0xf9, 0x58, 0x39, 0x08, 0x15, 0xda,
+    0x1b, 0x94, 0x50, 0x2d, 0x44, 0xc0, 0x23, 0x1c, 0x36, 0x5f,
+    0x16, 0x08, 0xa3, 0xdf, 0x9e, 0x4f, 0xbb, 0x07, 0xcd, 0xe3,
+    0x8c, 0xbf, 0xf1, 0xc3, 0x3e, 0x98, 0xf8, 0x49, 0x79, 0x58,
+    0xc9, 0x0f, 0x47, 0xc0, 0xab, 0x2f, 0x21, 0x63, 0xf6, 0xe6,
+    0xfe, 0x8a, 0xea, 0xbc, 0x32, 0x63, 0xca, 0x75, 0xf8, 0xa4,
+    0x1b, 0x6c, 0xfe, 0x9a, 0x6e, 0x68, 0x1f, 0x48, 0x59, 0xfb,
+    0x34, 0x43, 0x10, 0xd5, 0x0d, 0x80, 0x54, 0xcb, 0x67, 0x21,
+    0xc7, 0x13, 0x85, 0x38, 0x0c, 0xf9, 0x40, 0x2e, 0x2e, 0x4a,
+    0x05, 0x9e, 0x51, 0xae, 0xdd, 0xba, 0x23, 0x83, 0x66, 0x2a,
+    0xbf, 0x7f, 0xca, 0x9c, 0x6c, 0x2d, 0x6b, 0x7d, 0x68, 0x52,
+    0x81, 0x56, 0x2f, 0xea, 0xf9, 0xe7, 0xf1, 0x55, 0x16, 0xfc,
+    0x29, 0xe2, 0xa5, 0x1e, 0x0a, 0x06, 0xe0, 0x85, 0x4e, 0xa6,
+    0x5d, 0x20, 0x9d, 0x2b, 0xa2, 0xad, 0xaa, 0xd6, 0x9b, 0xd2,
+    0x98, 0x29, 0x45, 0x5c, 0x55, 0xc0, 0x91, 0xa2, 0x65, 0xcd,
+    0xac, 0xc6, 0x1a, 0x53, 0xa1, 0x46, 0x13, 0xf9, 0xfe, 0x1a,
+    0xf6, 0xdf, 0xa5, 0x1a, 0x58, 0x7c, 0x81, 0x2e, 0x46, 0x46,
+    0xf7, 0x2f, 0xd6, 0xaa, 0x21, 0xb0, 0x0e, 0x7e, 0xac, 0xb8,
+    0xc6, 0x76, 0x62, 0x82, 0x3b, 0x0a, 0x36, 0xbe, 0x97, 0x16,
+    0xd5, 0x79, 0x55, 0x15, 0x64, 0x2a, 0xbe, 0x19, 0x4e, 0x93,
+    0x3b, 0x44, 0x7c, 0xe2, 0xfc, 0x18, 0x4e, 0x83, 0x37, 0xfb,
+    0x26, 0x78, 0x6d, 0x24, 0x6b, 0x48, 0x21, 0x67, 0xde, 0xf5,
+    0x00, 0x22, 0x9a, 0xec, 0x40, 0x16, 0x96, 0x8a, 0x3f, 0xd5,
+    0xa6, 0x5e, 0x03, 0x84, 0xbb, 0x15, 0x4d, 0x55, 0x71, 0x00,
+    0x90, 0xc2, 0x96, 0x25, 0x01, 0xab, 0xe6, 0x47, 0x44, 0x6f,
+    0xf9, 0x53, 0x80, 0x2b, 0xa8, 0x83, 0xc8, 0x14, 0x77, 0x13,
+    0x00, 0x66, 0xee, 0x7e, 0x7a, 0xa0, 0x28, 0x65, 0xf3, 0x31,
+    0xb6, 0xac, 0xd7, 0x87, 0x84, 0x29, 0xed, 0x5b, 0xcd, 0x74,
+    0xc0, 0x89, 0x51, 0x11, 0x9a, 0xd5, 0x7b, 0xe0, 0x9c, 0xd0,
+    0x8d, 0x72, 0xe3, 0x77, 0xda, 0x0a, 0xc2, 0xdc, 0x6f, 0xad,
+    0x49, 0x03, 0xfa, 0xe6, 0x7e, 0xa6, 0x24, 0x32, 0xe6, 0x8f,
+    0xd9, 0x70, 0xfa, 0x59, 0x70, 0xa9, 0xa3, 0x08, 0x7d, 0x89,
+    0xc4, 0x96, 0x61, 0xc2, 0xf5, 0xe5, 0xb5, 0x3b, 0x0d, 0xec,
+    0xb8, 0x9c, 0xee, 0x09, 0x77, 0x27, 0xbd, 0x35, 0x66, 0x90,
+    0x9e, 0x46, 0xf7, 0xbd, 0xa6, 0xc5, 0x31, 0xd4, 0x6a, 0x52,
+    0x17, 0x5d, 0x0a, 0x0e, 0x2c, 0x34, 0x7a, 0x6a, 0x21, 0xac,
+    0x42, 0xf0, 0x31, 0xde, 0x48, 0xe0, 0x27, 0xd0, 0x79, 0xc9,
+    0x06, 0x94, 0x7b, 0x51, 0x4b, 0x5b, 0x02, 0x6a, 0x19, 0xba,
+    0x71, 0x45, 0x9c, 0xdf, 0xe6, 0x30, 0x9e, 0xaa, 0xad, 0xa1,
+    0x87, 0xf6, 0x37, 0xde, 0xa2, 0x97, 0x68, 0x20, 0x2d, 0x5a,
+    0xdc, 0xdd, 0x91, 0x63, 0x5f, 0x79, 0xda, 0x99, 0x20, 0x3a,
+    0x4b, 0xe5, 0x43, 0x0e, 0x12, 0x70, 0x57, 0x91, 0xfa, 0xee,
+    0xc4, 0xb6, 0xb6, 0xb1, 0xf1, 0x06, 0xbd, 0xcf, 0x8d, 0x2a,
+    0x05, 0xc0, 0x07, 0x23, 0x84, 0x85, 0xef, 0x9c, 0xbb, 0x6f,
+    0x5f, 0x4a, 0x9a, 0x27, 0x9f, 0x9f, 0x32, 0x97, 0xe8, 0x24,
+    0xb9, 0x64, 0x2c, 0x39, 0xff, 0x2f, 0x4b, 0xc4, 0x7e, 0x65,
+    0xfe, 0xbb, 0x5c, 0xa0, 0xb2, 0x6e, 0xc4, 0xb6, 0x93, 0x2b,
+    0x51, 0x9e, 0x2e, 0x1f, 0xd8, 0xcf, 0x60, 0xe0, 0x75, 0x15,
+    0xf9, 0xa0, 0x67, 0x99, 0x88, 0x2b, 0x76, 0xce, 0x41, 0x42,
+    0x10, 0x29, 0x89, 0xbf, 0xca, 0xb7, 0x61, 0x08, 0x94, 0xee,
+    0xa0, 0xb3, 0x3a, 0x09, 0xc5, 0x6f, 0x04, 0xf9, 0x1b, 0xb5,
+    0x64, 0x99, 0x08, 0xe4, 0xcc, 0xce, 0xdf, 0x71, 0x65, 0x8a,
+    0x6d, 0x62, 0xde, 0x76, 0x1d, 0x6d, 0x6b, 0x78, 0x22, 0x32,
+    0x63, 0xdd, 0x53, 0x7d, 0xec, 0xed, 0x9d, 0x82, 0xa9, 0x2c,
+    0x5c, 0x8a, 0x17, 0xdd, 0x85, 0xf9, 0xd2, 0xac, 0x6e, 0x98,
+    0x60, 0x2e, 0x08, 0xd4, 0x06, 0x76, 0xf4, 0x97, 0xca, 0xb1,
+    0x72, 0x50, 0x5b, 0x83, 0xea, 0xbb, 0x39, 0x0f, 0x18, 0xb3,
+    0xb8, 0x03, 0xee, 0x7c, 0x84, 0xa9, 0x69, 0xcd, 0x1d, 0xbd,
+    0xe2, 0xb7, 0xce, 0xe2, 0x6f, 0x03, 0x49, 0x52, 0x67, 0xa0,
+    0x1b, 0x23, 0x43, 0x92, 0x2c, 0x7c, 0x3b, 0x65, 0xe8, 0x61,
+    0x99, 0xde, 0xb5, 0xf1, 0x63, 0x73, 0x92, 0x6c, 0x70, 0x8b,
+    0x83, 0x10, 0xb4, 0x06, 0x2c, 0x99, 0x12, 0x73, 0xec, 0x87,
+    0x92, 0x09, 0x67, 0x96, 0xd6, 0x9c, 0x9f, 0x35, 0x48, 0x48,
+    0x3b, 0x44, 0x00, 0x73, 0x1c, 0x59, 0xeb, 0x81, 0x7b, 0xd1,
+    0xda, 0x76, 0xcf, 0xc2, 0x4d, 0xf1, 0xa2, 0x5b, 0x2f, 0x5f,
+    0x91, 0x29, 0x6e, 0x08, 0x37, 0xd6, 0xaa, 0xd2, 0xf8, 0x4f,
+    0x5e, 0x00, 0x16, 0x52
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/timeouts.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/timeouts.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/timeouts.h	(revision 331)
@@ -0,0 +1,17 @@
+/*
+ * Copyright 1999-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
+ */
+
+#ifndef INCLUDED_TIMEOUTS_H
+# define INCLUDED_TIMEOUTS_H
+
+/* numbers in us */
+# define DGRAM_RCV_TIMEOUT         250000
+# define DGRAM_SND_TIMEOUT         250000
+
+#endif                          /* ! INCLUDED_TIMEOUTS_H */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/ts.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/ts.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/ts.c	(revision 331)
@@ -0,0 +1,995 @@
+/*
+ * Copyright 2006-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 <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_TS
+NON_EMPTY_TRANSLATION_UNIT
+#else
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+# include "apps.h"
+# include <openssl/bio.h>
+# include <openssl/err.h>
+# include <openssl/pem.h>
+# include <openssl/rand.h>
+# include <openssl/ts.h>
+# include <openssl/bn.h>
+
+/* Request nonce length, in bits (must be a multiple of 8). */
+# define NONCE_LENGTH            64
+
+/* Name of config entry that defines the OID file. */
+# define ENV_OID_FILE            "oid_file"
+
+/* Is |EXACTLY_ONE| of three pointers set? */
+# define EXACTLY_ONE(a, b, c) \
+        (( a && !b && !c) || \
+         ( b && !a && !c) || \
+         ( c && !a && !b))
+
+static ASN1_OBJECT *txt2obj(const char *oid);
+static CONF *load_config_file(const char *configfile);
+
+/* Query related functions. */
+static int query_command(const char *data, const char *digest,
+                         const EVP_MD *md, const char *policy, int no_nonce,
+                         int cert, const char *in, const char *out, int text);
+static TS_REQ *create_query(BIO *data_bio, const char *digest, const EVP_MD *md,
+                            const char *policy, int no_nonce, int cert);
+static int create_digest(BIO *input, const char *digest,
+                         const EVP_MD *md, unsigned char **md_value);
+static ASN1_INTEGER *create_nonce(int bits);
+
+/* Reply related functions. */
+static int reply_command(CONF *conf, const char *section, const char *engine,
+                         const char *queryfile, const char *passin, const char *inkey,
+                         const EVP_MD *md, const char *signer, const char *chain,
+                         const char *policy, const char *in, int token_in,
+                         const char *out, int token_out, int text);
+static TS_RESP *read_PKCS7(BIO *in_bio);
+static TS_RESP *create_response(CONF *conf, const char *section, const char *engine,
+                                const char *queryfile, const char *passin,
+                                const char *inkey, const EVP_MD *md, const char *signer,
+                                const char *chain, const char *policy);
+static ASN1_INTEGER *serial_cb(TS_RESP_CTX *ctx, void *data);
+static ASN1_INTEGER *next_serial(const char *serialfile);
+static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial);
+
+/* Verify related functions. */
+static int verify_command(const char *data, const char *digest, const char *queryfile,
+                          const char *in, int token_in,
+                          const char *CApath, const char *CAfile, const char *untrusted,
+                          X509_VERIFY_PARAM *vpm);
+static TS_VERIFY_CTX *create_verify_ctx(const char *data, const char *digest,
+                                        const char *queryfile,
+                                        const char *CApath, const char *CAfile,
+                                        const char *untrusted,
+                                        X509_VERIFY_PARAM *vpm);
+static X509_STORE *create_cert_store(const char *CApath, const char *CAfile,
+                                     X509_VERIFY_PARAM *vpm);
+static int verify_cb(int ok, X509_STORE_CTX *ctx);
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_ENGINE, OPT_CONFIG, OPT_SECTION, OPT_QUERY, OPT_DATA,
+    OPT_DIGEST, OPT_RAND, OPT_TSPOLICY, OPT_NO_NONCE, OPT_CERT,
+    OPT_IN, OPT_TOKEN_IN, OPT_OUT, OPT_TOKEN_OUT, OPT_TEXT,
+    OPT_REPLY, OPT_QUERYFILE, OPT_PASSIN, OPT_INKEY, OPT_SIGNER,
+    OPT_CHAIN, OPT_VERIFY, OPT_CAPATH, OPT_CAFILE, OPT_UNTRUSTED,
+    OPT_MD, OPT_V_ENUM
+} OPTION_CHOICE;
+
+OPTIONS ts_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"config", OPT_CONFIG, '<', "Configuration file"},
+    {"section", OPT_SECTION, 's', "Section to use within config file"},
+    {"query", OPT_QUERY, '-', "Generate a TS query"},
+    {"data", OPT_DATA, '<', "File to hash"},
+    {"digest", OPT_DIGEST, 's', "Digest (as a hex string)"},
+    {"rand", OPT_RAND, 's',
+     "Load the file(s) into the random number generator"},
+    {"tspolicy", OPT_TSPOLICY, 's', "Policy OID to use"},
+    {"no_nonce", OPT_NO_NONCE, '-', "Do not include a nonce"},
+    {"cert", OPT_CERT, '-', "Put cert request into query"},
+    {"in", OPT_IN, '<', "Input file"},
+    {"token_in", OPT_TOKEN_IN, '-', "Input is a PKCS#7 file"},
+    {"out", OPT_OUT, '>', "Output file"},
+    {"token_out", OPT_TOKEN_OUT, '-', "Output is a PKCS#7 file"},
+    {"text", OPT_TEXT, '-', "Output text (not DER)"},
+    {"reply", OPT_REPLY, '-', "Generate a TS reply"},
+    {"queryfile", OPT_QUERYFILE, '<', "File containing a TS query"},
+    {"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
+    {"inkey", OPT_INKEY, '<', "File with private key for reply"},
+    {"signer", OPT_SIGNER, 's', "Signer certificate file"},
+    {"chain", OPT_CHAIN, '<', "File with signer CA chain"},
+    {"verify", OPT_VERIFY, '-', "Verify a TS response"},
+    {"CApath", OPT_CAPATH, '/', "Path to trusted CA files"},
+    {"CAfile", OPT_CAFILE, '<', "File with trusted CA certs"},
+    {"untrusted", OPT_UNTRUSTED, '<', "File with untrusted certs"},
+    {"", OPT_MD, '-', "Any supported digest"},
+# ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+# endif
+    {OPT_HELP_STR, 1, '-', "\nOptions specific to 'ts -verify': \n"},
+    OPT_V_OPTIONS,
+    {OPT_HELP_STR, 1, '-', "\n"},
+    {NULL}
+};
+
+/*
+ * This command is so complex, special help is needed.
+ */
+static char* opt_helplist[] = {
+    "Typical uses:",
+    "ts -query [-rand file...] [-config file] [-data file]",
+    "          [-digest hexstring] [-tspolicy oid] [-no_nonce] [-cert]",
+    "          [-in file] [-out file] [-text]",
+    "  or",
+    "ts -reply [-config file] [-section tsa_section]",
+    "          [-queryfile file] [-passin password]",
+    "          [-signer tsa_cert.pem] [-inkey private_key.pem]",
+    "          [-chain certs_file.pem] [-tspolicy oid]",
+    "          [-in file] [-token_in] [-out file] [-token_out]",
+# ifndef OPENSSL_NO_ENGINE
+    "          [-text] [-engine id]",
+# else
+    "          [-text]",
+# endif
+    "  or",
+    "ts -verify -CApath dir -CAfile file.pem -untrusted file.pem",
+    "           [-data file] [-digest hexstring]",
+    "           [-queryfile file] -in file [-token_in]",
+    "           [[options specific to 'ts -verify']]",
+    NULL,
+};
+
+int ts_main(int argc, char **argv)
+{
+    CONF *conf = NULL;
+    const char *CAfile = NULL, *untrusted = NULL, *prog;
+    const char *configfile = default_config_file, *engine = NULL;
+    const char *section = NULL;
+    char **helpp;
+    char *password = NULL;
+    char *data = NULL, *digest = NULL, *rnd = NULL, *policy = NULL;
+    char *in = NULL, *out = NULL, *queryfile = NULL, *passin = NULL;
+    char *inkey = NULL, *signer = NULL, *chain = NULL, *CApath = NULL;
+    const EVP_MD *md = NULL;
+    OPTION_CHOICE o, mode = OPT_ERR;
+    int ret = 1, no_nonce = 0, cert = 0, text = 0;
+    int vpmtouched = 0;
+    X509_VERIFY_PARAM *vpm = NULL;
+    /* Input is ContentInfo instead of TimeStampResp. */
+    int token_in = 0;
+    /* Output is ContentInfo instead of TimeStampResp. */
+    int token_out = 0;
+
+    if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
+        goto end;
+
+    prog = opt_init(argc, argv, ts_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(ts_options);
+            for (helpp = opt_helplist; *helpp; ++helpp)
+                BIO_printf(bio_err, "%s\n", *helpp);
+            ret = 0;
+            goto end;
+        case OPT_CONFIG:
+            configfile = opt_arg();
+            break;
+        case OPT_SECTION:
+            section = opt_arg();
+            break;
+        case OPT_QUERY:
+        case OPT_REPLY:
+        case OPT_VERIFY:
+            if (mode != OPT_ERR)
+                goto opthelp;
+            mode = o;
+            break;
+        case OPT_DATA:
+            data = opt_arg();
+            break;
+        case OPT_DIGEST:
+            digest = opt_arg();
+            break;
+        case OPT_RAND:
+            rnd = opt_arg();
+            break;
+        case OPT_TSPOLICY:
+            policy = opt_arg();
+            break;
+        case OPT_NO_NONCE:
+            no_nonce = 1;
+            break;
+        case OPT_CERT:
+            cert = 1;
+            break;
+        case OPT_IN:
+            in = opt_arg();
+            break;
+        case OPT_TOKEN_IN:
+            token_in = 1;
+            break;
+        case OPT_OUT:
+            out = opt_arg();
+            break;
+        case OPT_TOKEN_OUT:
+            token_out = 1;
+            break;
+        case OPT_TEXT:
+            text = 1;
+            break;
+        case OPT_QUERYFILE:
+            queryfile = opt_arg();
+            break;
+        case OPT_PASSIN:
+            passin = opt_arg();
+            break;
+        case OPT_INKEY:
+            inkey = opt_arg();
+            break;
+        case OPT_SIGNER:
+            signer = opt_arg();
+            break;
+        case OPT_CHAIN:
+            chain = opt_arg();
+            break;
+        case OPT_CAPATH:
+            CApath = opt_arg();
+            break;
+        case OPT_CAFILE:
+            CAfile = opt_arg();
+            break;
+        case OPT_UNTRUSTED:
+            untrusted = opt_arg();
+            break;
+        case OPT_ENGINE:
+            engine = opt_arg();
+            break;
+        case OPT_MD:
+            if (!opt_md(opt_unknown(), &md))
+                goto opthelp;
+            break;
+        case OPT_V_CASES:
+            if (!opt_verify(o, vpm))
+                goto end;
+            vpmtouched++;
+            break;
+        }
+    }
+    if (mode == OPT_ERR || opt_num_rest() != 0)
+        goto opthelp;
+
+    /* Seed the random number generator if it is going to be used. */
+    if (mode == OPT_QUERY && !no_nonce) {
+        if (!app_RAND_load_file(NULL, 1) && rnd == NULL)
+            BIO_printf(bio_err, "warning, not much extra random "
+                       "data, consider using the -rand option\n");
+        if (rnd != NULL)
+            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
+                       app_RAND_load_files(rnd));
+    }
+
+    if (mode == OPT_REPLY && passin &&
+        !app_passwd(passin, NULL, &password, NULL)) {
+        BIO_printf(bio_err, "Error getting password.\n");
+        goto end;
+    }
+
+    conf = load_config_file(configfile);
+    if (configfile != default_config_file && !app_load_modules(conf))
+        goto end;
+
+    /* Check parameter consistency and execute the appropriate function. */
+    switch (mode) {
+    default:
+    case OPT_ERR:
+        goto opthelp;
+    case OPT_QUERY:
+        if (vpmtouched)
+            goto opthelp;
+        if ((data != NULL) && (digest != NULL))
+            goto opthelp;
+        ret = !query_command(data, digest, md, policy, no_nonce, cert,
+                             in, out, text);
+        break;
+    case OPT_REPLY:
+        if (vpmtouched)
+            goto opthelp;
+        if ((in != NULL) && (queryfile != NULL))
+            goto opthelp;
+        if (in == NULL) {
+            if ((conf == NULL) || (token_in != 0))
+                goto opthelp;
+        }
+        ret = !reply_command(conf, section, engine, queryfile,
+                             password, inkey, md, signer, chain, policy,
+                             in, token_in, out, token_out, text);
+        break;
+    case OPT_VERIFY:
+        if ((in == NULL) || !EXACTLY_ONE(queryfile, data, digest))
+            goto opthelp;
+        ret = !verify_command(data, digest, queryfile, in, token_in,
+                              CApath, CAfile, untrusted,
+                              vpmtouched ? vpm : NULL);
+    }
+
+ end:
+    X509_VERIFY_PARAM_free(vpm);
+    app_RAND_write_file(NULL);
+    NCONF_free(conf);
+    OPENSSL_free(password);
+    return (ret);
+}
+
+/*
+ * Configuration file-related function definitions.
+ */
+
+static ASN1_OBJECT *txt2obj(const char *oid)
+{
+    ASN1_OBJECT *oid_obj = NULL;
+
+    if ((oid_obj = OBJ_txt2obj(oid, 0)) == NULL)
+        BIO_printf(bio_err, "cannot convert %s to OID\n", oid);
+
+    return oid_obj;
+}
+
+static CONF *load_config_file(const char *configfile)
+{
+    CONF *conf = app_load_config(configfile);
+
+    if (conf != NULL) {
+        const char *p;
+
+        BIO_printf(bio_err, "Using configuration from %s\n", configfile);
+        p = NCONF_get_string(conf, NULL, ENV_OID_FILE);
+        if (p != NULL) {
+            BIO *oid_bio = BIO_new_file(p, "r");
+            if (!oid_bio)
+                ERR_print_errors(bio_err);
+            else {
+                OBJ_create_objects(oid_bio);
+                BIO_free_all(oid_bio);
+            }
+        } else
+            ERR_clear_error();
+        if (!add_oid_section(conf))
+            ERR_print_errors(bio_err);
+    }
+    return conf;
+}
+
+/*
+ * Query-related method definitions.
+ */
+static int query_command(const char *data, const char *digest, const EVP_MD *md,
+                         const char *policy, int no_nonce,
+                         int cert, const char *in, const char *out, int text)
+{
+    int ret = 0;
+    TS_REQ *query = NULL;
+    BIO *in_bio = NULL;
+    BIO *data_bio = NULL;
+    BIO *out_bio = NULL;
+
+    /* Build query object. */
+    if (in != NULL) {
+        if ((in_bio = bio_open_default(in, 'r', FORMAT_ASN1)) == NULL)
+            goto end;
+        query = d2i_TS_REQ_bio(in_bio, NULL);
+    } else {
+        if (digest == NULL
+            && (data_bio = bio_open_default(data, 'r', FORMAT_ASN1)) == NULL)
+            goto end;
+        query = create_query(data_bio, digest, md, policy, no_nonce, cert);
+    }
+    if (query == NULL)
+        goto end;
+
+    if (text) {
+        if ((out_bio = bio_open_default(out, 'w', FORMAT_TEXT)) == NULL)
+            goto end;
+        if (!TS_REQ_print_bio(out_bio, query))
+            goto end;
+    } else {
+        if ((out_bio = bio_open_default(out, 'w', FORMAT_ASN1)) == NULL)
+            goto end;
+        if (!i2d_TS_REQ_bio(out_bio, query))
+            goto end;
+    }
+
+    ret = 1;
+
+ end:
+    ERR_print_errors(bio_err);
+    BIO_free_all(in_bio);
+    BIO_free_all(data_bio);
+    BIO_free_all(out_bio);
+    TS_REQ_free(query);
+    return ret;
+}
+
+static TS_REQ *create_query(BIO *data_bio, const char *digest, const EVP_MD *md,
+                            const char *policy, int no_nonce, int cert)
+{
+    int ret = 0;
+    TS_REQ *ts_req = NULL;
+    int len;
+    TS_MSG_IMPRINT *msg_imprint = NULL;
+    X509_ALGOR *algo = NULL;
+    unsigned char *data = NULL;
+    ASN1_OBJECT *policy_obj = NULL;
+    ASN1_INTEGER *nonce_asn1 = NULL;
+
+    if (md == NULL && (md = EVP_get_digestbyname("sha1")) == NULL)
+        goto err;
+    if ((ts_req = TS_REQ_new()) == NULL)
+        goto err;
+    if (!TS_REQ_set_version(ts_req, 1))
+        goto err;
+    if ((msg_imprint = TS_MSG_IMPRINT_new()) == NULL)
+        goto err;
+    if ((algo = X509_ALGOR_new()) == NULL)
+        goto err;
+    if ((algo->algorithm = OBJ_nid2obj(EVP_MD_type(md))) == NULL)
+        goto err;
+    if ((algo->parameter = ASN1_TYPE_new()) == NULL)
+        goto err;
+    algo->parameter->type = V_ASN1_NULL;
+    if (!TS_MSG_IMPRINT_set_algo(msg_imprint, algo))
+        goto err;
+    if ((len = create_digest(data_bio, digest, md, &data)) == 0)
+        goto err;
+    if (!TS_MSG_IMPRINT_set_msg(msg_imprint, data, len))
+        goto err;
+    if (!TS_REQ_set_msg_imprint(ts_req, msg_imprint))
+        goto err;
+    if (policy && (policy_obj = txt2obj(policy)) == NULL)
+        goto err;
+    if (policy_obj && !TS_REQ_set_policy_id(ts_req, policy_obj))
+        goto err;
+
+    /* Setting nonce if requested. */
+    if (!no_nonce && (nonce_asn1 = create_nonce(NONCE_LENGTH)) == NULL)
+        goto err;
+    if (nonce_asn1 && !TS_REQ_set_nonce(ts_req, nonce_asn1))
+        goto err;
+    if (!TS_REQ_set_cert_req(ts_req, cert))
+        goto err;
+
+    ret = 1;
+ err:
+    if (!ret) {
+        TS_REQ_free(ts_req);
+        ts_req = NULL;
+        BIO_printf(bio_err, "could not create query\n");
+        ERR_print_errors(bio_err);
+    }
+    TS_MSG_IMPRINT_free(msg_imprint);
+    X509_ALGOR_free(algo);
+    OPENSSL_free(data);
+    ASN1_OBJECT_free(policy_obj);
+    ASN1_INTEGER_free(nonce_asn1);
+    return ts_req;
+}
+
+static int create_digest(BIO *input, const char *digest, const EVP_MD *md,
+                         unsigned char **md_value)
+{
+    int md_value_len;
+    int rv = 0;
+    EVP_MD_CTX *md_ctx = NULL;
+
+    md_value_len = EVP_MD_size(md);
+    if (md_value_len < 0)
+        return 0;
+
+    if (input) {
+        unsigned char buffer[4096];
+        int length;
+
+        md_ctx = EVP_MD_CTX_new();
+        if (md_ctx == NULL)
+            return 0;
+        *md_value = app_malloc(md_value_len, "digest buffer");
+        if (!EVP_DigestInit(md_ctx, md))
+            goto err;
+        while ((length = BIO_read(input, buffer, sizeof(buffer))) > 0) {
+            if (!EVP_DigestUpdate(md_ctx, buffer, length))
+                goto err;
+        }
+        if (!EVP_DigestFinal(md_ctx, *md_value, NULL))
+            goto err;
+        md_value_len = EVP_MD_size(md);
+    } else {
+        long digest_len;
+        *md_value = OPENSSL_hexstr2buf(digest, &digest_len);
+        if (!*md_value || md_value_len != digest_len) {
+            OPENSSL_free(*md_value);
+            *md_value = NULL;
+            BIO_printf(bio_err, "bad digest, %d bytes "
+                       "must be specified\n", md_value_len);
+            return 0;
+        }
+    }
+    rv = md_value_len;
+ err:
+    EVP_MD_CTX_free(md_ctx);
+    return rv;
+}
+
+static ASN1_INTEGER *create_nonce(int bits)
+{
+    unsigned char buf[20];
+    ASN1_INTEGER *nonce = NULL;
+    int len = (bits - 1) / 8 + 1;
+    int i;
+
+    if (len > (int)sizeof(buf))
+        goto err;
+    if (RAND_bytes(buf, len) <= 0)
+        goto err;
+
+    /* Find the first non-zero byte and creating ASN1_INTEGER object. */
+    for (i = 0; i < len && !buf[i]; ++i)
+        continue;
+    if ((nonce = ASN1_INTEGER_new()) == NULL)
+        goto err;
+    OPENSSL_free(nonce->data);
+    nonce->length = len - i;
+    nonce->data = app_malloc(nonce->length + 1, "nonce buffer");
+    memcpy(nonce->data, buf + i, nonce->length);
+    return nonce;
+
+ err:
+    BIO_printf(bio_err, "could not create nonce\n");
+    ASN1_INTEGER_free(nonce);
+    return NULL;
+}
+
+/*
+ * Reply-related method definitions.
+ */
+
+static int reply_command(CONF *conf, const char *section, const char *engine,
+                         const char *queryfile, const char *passin, const char *inkey,
+                         const EVP_MD *md, const char *signer, const char *chain,
+                         const char *policy, const char *in, int token_in,
+                         const char *out, int token_out, int text)
+{
+    int ret = 0;
+    TS_RESP *response = NULL;
+    BIO *in_bio = NULL;
+    BIO *query_bio = NULL;
+    BIO *inkey_bio = NULL;
+    BIO *signer_bio = NULL;
+    BIO *out_bio = NULL;
+
+    if (in != NULL) {
+        if ((in_bio = BIO_new_file(in, "rb")) == NULL)
+            goto end;
+        if (token_in) {
+            response = read_PKCS7(in_bio);
+        } else {
+            response = d2i_TS_RESP_bio(in_bio, NULL);
+        }
+    } else {
+        response = create_response(conf, section, engine, queryfile,
+                                   passin, inkey, md, signer, chain, policy);
+        if (response)
+            BIO_printf(bio_err, "Response has been generated.\n");
+        else
+            BIO_printf(bio_err, "Response is not generated.\n");
+    }
+    if (response == NULL)
+        goto end;
+
+    /* Write response. */
+    if (text) {
+        if ((out_bio = bio_open_default(out, 'w', FORMAT_TEXT)) == NULL)
+        goto end;
+        if (token_out) {
+            TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response);
+            if (!TS_TST_INFO_print_bio(out_bio, tst_info))
+                goto end;
+        } else {
+            if (!TS_RESP_print_bio(out_bio, response))
+                goto end;
+        }
+    } else {
+        if ((out_bio = bio_open_default(out, 'w', FORMAT_ASN1)) == NULL)
+            goto end;
+        if (token_out) {
+            PKCS7 *token = TS_RESP_get_token(response);
+            if (!i2d_PKCS7_bio(out_bio, token))
+                goto end;
+        } else {
+            if (!i2d_TS_RESP_bio(out_bio, response))
+                goto end;
+        }
+    }
+
+    ret = 1;
+
+ end:
+    ERR_print_errors(bio_err);
+    BIO_free_all(in_bio);
+    BIO_free_all(query_bio);
+    BIO_free_all(inkey_bio);
+    BIO_free_all(signer_bio);
+    BIO_free_all(out_bio);
+    TS_RESP_free(response);
+    return ret;
+}
+
+/* Reads a PKCS7 token and adds default 'granted' status info to it. */
+static TS_RESP *read_PKCS7(BIO *in_bio)
+{
+    int ret = 0;
+    PKCS7 *token = NULL;
+    TS_TST_INFO *tst_info = NULL;
+    TS_RESP *resp = NULL;
+    TS_STATUS_INFO *si = NULL;
+
+    if ((token = d2i_PKCS7_bio(in_bio, NULL)) == NULL)
+        goto end;
+    if ((tst_info = PKCS7_to_TS_TST_INFO(token)) == NULL)
+        goto end;
+    if ((resp = TS_RESP_new()) == NULL)
+        goto end;
+    if ((si = TS_STATUS_INFO_new()) == NULL)
+        goto end;
+    if (!TS_STATUS_INFO_set_status(si, TS_STATUS_GRANTED))
+        goto end;
+    if (!TS_RESP_set_status_info(resp, si))
+        goto end;
+    TS_RESP_set_tst_info(resp, token, tst_info);
+    token = NULL;               /* Ownership is lost. */
+    tst_info = NULL;            /* Ownership is lost. */
+    ret = 1;
+
+ end:
+    PKCS7_free(token);
+    TS_TST_INFO_free(tst_info);
+    if (!ret) {
+        TS_RESP_free(resp);
+        resp = NULL;
+    }
+    TS_STATUS_INFO_free(si);
+    return resp;
+}
+
+static TS_RESP *create_response(CONF *conf, const char *section, const char *engine,
+                                const char *queryfile, const char *passin,
+                                const char *inkey, const EVP_MD *md, const char *signer,
+                                const char *chain, const char *policy)
+{
+    int ret = 0;
+    TS_RESP *response = NULL;
+    BIO *query_bio = NULL;
+    TS_RESP_CTX *resp_ctx = NULL;
+
+    if ((query_bio = BIO_new_file(queryfile, "rb")) == NULL)
+        goto end;
+    if ((section = TS_CONF_get_tsa_section(conf, section)) == NULL)
+        goto end;
+    if ((resp_ctx = TS_RESP_CTX_new()) == NULL)
+        goto end;
+    if (!TS_CONF_set_serial(conf, section, serial_cb, resp_ctx))
+        goto end;
+# ifndef OPENSSL_NO_ENGINE
+    if (!TS_CONF_set_crypto_device(conf, section, engine))
+        goto end;
+# endif
+    if (!TS_CONF_set_signer_cert(conf, section, signer, resp_ctx))
+        goto end;
+    if (!TS_CONF_set_certs(conf, section, chain, resp_ctx))
+        goto end;
+    if (!TS_CONF_set_signer_key(conf, section, inkey, passin, resp_ctx))
+        goto end;
+
+    if (md) {
+        if (!TS_RESP_CTX_set_signer_digest(resp_ctx, md))
+            goto end;
+    } else if (!TS_CONF_set_signer_digest(conf, section, NULL, resp_ctx)) {
+            goto end;
+    }
+
+    if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx))
+        goto end;
+    if (!TS_CONF_set_policies(conf, section, resp_ctx))
+        goto end;
+    if (!TS_CONF_set_digests(conf, section, resp_ctx))
+        goto end;
+    if (!TS_CONF_set_accuracy(conf, section, resp_ctx))
+        goto end;
+    if (!TS_CONF_set_clock_precision_digits(conf, section, resp_ctx))
+        goto end;
+    if (!TS_CONF_set_ordering(conf, section, resp_ctx))
+        goto end;
+    if (!TS_CONF_set_tsa_name(conf, section, resp_ctx))
+        goto end;
+    if (!TS_CONF_set_ess_cert_id_chain(conf, section, resp_ctx))
+        goto end;
+    if ((response = TS_RESP_create_response(resp_ctx, query_bio)) == NULL)
+        goto end;
+    ret = 1;
+
+ end:
+    if (!ret) {
+        TS_RESP_free(response);
+        response = NULL;
+    }
+    TS_RESP_CTX_free(resp_ctx);
+    BIO_free_all(query_bio);
+    return response;
+}
+
+static ASN1_INTEGER *serial_cb(TS_RESP_CTX *ctx, void *data)
+{
+    const char *serial_file = (const char *)data;
+    ASN1_INTEGER *serial = next_serial(serial_file);
+
+    if (!serial) {
+        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+                                    "Error during serial number "
+                                    "generation.");
+        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_ADD_INFO_NOT_AVAILABLE);
+    } else
+        save_ts_serial(serial_file, serial);
+
+    return serial;
+}
+
+static ASN1_INTEGER *next_serial(const char *serialfile)
+{
+    int ret = 0;
+    BIO *in = NULL;
+    ASN1_INTEGER *serial = NULL;
+    BIGNUM *bn = NULL;
+
+    if ((serial = ASN1_INTEGER_new()) == NULL)
+        goto err;
+
+    if ((in = BIO_new_file(serialfile, "r")) == NULL) {
+        ERR_clear_error();
+        BIO_printf(bio_err, "Warning: could not open file %s for "
+                   "reading, using serial number: 1\n", serialfile);
+        if (!ASN1_INTEGER_set(serial, 1))
+            goto err;
+    } else {
+        char buf[1024];
+        if (!a2i_ASN1_INTEGER(in, serial, buf, sizeof(buf))) {
+            BIO_printf(bio_err, "unable to load number from %s\n",
+                       serialfile);
+            goto err;
+        }
+        if ((bn = ASN1_INTEGER_to_BN(serial, NULL)) == NULL)
+            goto err;
+        ASN1_INTEGER_free(serial);
+        serial = NULL;
+        if (!BN_add_word(bn, 1))
+            goto err;
+        if ((serial = BN_to_ASN1_INTEGER(bn, NULL)) == NULL)
+            goto err;
+    }
+    ret = 1;
+
+ err:
+    if (!ret) {
+        ASN1_INTEGER_free(serial);
+        serial = NULL;
+    }
+    BIO_free_all(in);
+    BN_free(bn);
+    return serial;
+}
+
+static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial)
+{
+    int ret = 0;
+    BIO *out = NULL;
+
+    if ((out = BIO_new_file(serialfile, "w")) == NULL)
+        goto err;
+    if (i2a_ASN1_INTEGER(out, serial) <= 0)
+        goto err;
+    if (BIO_puts(out, "\n") <= 0)
+        goto err;
+    ret = 1;
+ err:
+    if (!ret)
+        BIO_printf(bio_err, "could not save serial number to %s\n",
+                   serialfile);
+    BIO_free_all(out);
+    return ret;
+}
+
+
+/*
+ * Verify-related method definitions.
+ */
+
+static int verify_command(const char *data, const char *digest, const char *queryfile,
+                          const char *in, int token_in,
+                          const char *CApath, const char *CAfile, const char *untrusted,
+                          X509_VERIFY_PARAM *vpm)
+{
+    BIO *in_bio = NULL;
+    PKCS7 *token = NULL;
+    TS_RESP *response = NULL;
+    TS_VERIFY_CTX *verify_ctx = NULL;
+    int ret = 0;
+
+    if ((in_bio = BIO_new_file(in, "rb")) == NULL)
+        goto end;
+    if (token_in) {
+        if ((token = d2i_PKCS7_bio(in_bio, NULL)) == NULL)
+            goto end;
+    } else {
+        if ((response = d2i_TS_RESP_bio(in_bio, NULL)) == NULL)
+            goto end;
+    }
+
+    if ((verify_ctx = create_verify_ctx(data, digest, queryfile,
+                                        CApath, CAfile, untrusted,
+                                        vpm)) == NULL)
+        goto end;
+
+    ret = token_in
+        ? TS_RESP_verify_token(verify_ctx, token)
+        : TS_RESP_verify_response(verify_ctx, response);
+
+ end:
+    printf("Verification: ");
+    if (ret)
+        printf("OK\n");
+    else {
+        printf("FAILED\n");
+        ERR_print_errors(bio_err);
+    }
+
+    BIO_free_all(in_bio);
+    PKCS7_free(token);
+    TS_RESP_free(response);
+    TS_VERIFY_CTX_free(verify_ctx);
+    return ret;
+}
+
+static TS_VERIFY_CTX *create_verify_ctx(const char *data, const char *digest,
+                                        const char *queryfile,
+                                        const char *CApath, const char *CAfile,
+                                        const char *untrusted,
+                                        X509_VERIFY_PARAM *vpm)
+{
+    TS_VERIFY_CTX *ctx = NULL;
+    BIO *input = NULL;
+    TS_REQ *request = NULL;
+    int ret = 0;
+    int f = 0;
+
+    if (data != NULL || digest != NULL) {
+        if ((ctx = TS_VERIFY_CTX_new()) == NULL)
+            goto err;
+        f = TS_VFY_VERSION | TS_VFY_SIGNER;
+        if (data != NULL) {
+            BIO *out = NULL;
+
+            f |= TS_VFY_DATA;
+            if ((out = BIO_new_file(data, "rb")) == NULL)
+                goto err;
+            if (TS_VERIFY_CTX_set_data(ctx, out) == NULL) {
+                BIO_free_all(out);
+                goto err;
+            }
+        } else if (digest != NULL) {
+            long imprint_len;
+            unsigned char *hexstr = OPENSSL_hexstr2buf(digest, &imprint_len);
+            f |= TS_VFY_IMPRINT;
+            if (TS_VERIFY_CTX_set_imprint(ctx, hexstr, imprint_len) == NULL) {
+                BIO_printf(bio_err, "invalid digest string\n");
+                goto err;
+            }
+        }
+
+    } else if (queryfile != NULL) {
+        if ((input = BIO_new_file(queryfile, "rb")) == NULL)
+            goto err;
+        if ((request = d2i_TS_REQ_bio(input, NULL)) == NULL)
+            goto err;
+        if ((ctx = TS_REQ_to_TS_VERIFY_CTX(request, NULL)) == NULL)
+            goto err;
+    } else
+        return NULL;
+
+    /* Add the signature verification flag and arguments. */
+    TS_VERIFY_CTX_add_flags(ctx, f | TS_VFY_SIGNATURE);
+
+    /* Initialising the X509_STORE object. */
+    if (TS_VERIFY_CTX_set_store(ctx, create_cert_store(CApath, CAfile, vpm))
+            == NULL)
+        goto err;
+
+    /* Loading untrusted certificates. */
+    if (untrusted
+        && TS_VERIFY_CTS_set_certs(ctx, TS_CONF_load_certs(untrusted)) == NULL)
+        goto err;
+    ret = 1;
+
+ err:
+    if (!ret) {
+        TS_VERIFY_CTX_free(ctx);
+        ctx = NULL;
+    }
+    BIO_free_all(input);
+    TS_REQ_free(request);
+    return ctx;
+}
+
+static X509_STORE *create_cert_store(const char *CApath, const char *CAfile,
+                                     X509_VERIFY_PARAM *vpm)
+{
+    X509_STORE *cert_ctx = NULL;
+    X509_LOOKUP *lookup = NULL;
+    int i;
+
+    cert_ctx = X509_STORE_new();
+    X509_STORE_set_verify_cb(cert_ctx, verify_cb);
+    if (CApath != NULL) {
+        lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir());
+        if (lookup == NULL) {
+            BIO_printf(bio_err, "memory allocation failure\n");
+            goto err;
+        }
+        i = X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM);
+        if (!i) {
+            BIO_printf(bio_err, "Error loading directory %s\n", CApath);
+            goto err;
+        }
+    }
+
+    if (CAfile != NULL) {
+        lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
+        if (lookup == NULL) {
+            BIO_printf(bio_err, "memory allocation failure\n");
+            goto err;
+        }
+        i = X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM);
+        if (!i) {
+            BIO_printf(bio_err, "Error loading file %s\n", CAfile);
+            goto err;
+        }
+    }
+
+    if (vpm != NULL)
+        X509_STORE_set1_param(cert_ctx, vpm);
+
+    return cert_ctx;
+
+ err:
+    X509_STORE_free(cert_ctx);
+    return NULL;
+}
+
+static int verify_cb(int ok, X509_STORE_CTX *ctx)
+{
+    return ok;
+}
+#endif  /* ndef OPENSSL_NO_TS */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/verify.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/verify.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/verify.c	(revision 331)
@@ -0,0 +1,311 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/pem.h>
+
+static int cb(int ok, X509_STORE_CTX *ctx);
+static int check(X509_STORE *ctx, const char *file,
+                 STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
+                 STACK_OF(X509_CRL) *crls, int show_chain);
+static int v_verbose = 0, vflags = 0;
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_ENGINE, OPT_CAPATH, OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE,
+    OPT_UNTRUSTED, OPT_TRUSTED, OPT_CRLFILE, OPT_CRL_DOWNLOAD, OPT_SHOW_CHAIN,
+    OPT_V_ENUM,
+    OPT_VERBOSE
+} OPTION_CHOICE;
+
+OPTIONS verify_options[] = {
+    {OPT_HELP_STR, 1, '-', "Usage: %s [options] cert.pem...\n"},
+    {OPT_HELP_STR, 1, '-', "Valid options are:\n"},
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"verbose", OPT_VERBOSE, '-',
+        "Print extra information about the operations being performed."},
+    {"CApath", OPT_CAPATH, '/', "A directory of trusted certificates"},
+    {"CAfile", OPT_CAFILE, '<', "A file of trusted certificates"},
+    {"no-CAfile", OPT_NOCAFILE, '-',
+     "Do not load the default certificates file"},
+    {"no-CApath", OPT_NOCAPATH, '-',
+     "Do not load certificates from the default certificates directory"},
+    {"untrusted", OPT_UNTRUSTED, '<', "A file of untrusted certificates"},
+    {"trusted", OPT_TRUSTED, '<', "A file of trusted certificates"},
+    {"CRLfile", OPT_CRLFILE, '<',
+        "File containing one or more CRL's (in PEM format) to load"},
+    {"crl_download", OPT_CRL_DOWNLOAD, '-',
+        "Attempt to download CRL information for this certificate"},
+    {"show_chain", OPT_SHOW_CHAIN, '-',
+        "Display information about the certificate chain"},
+    OPT_V_OPTIONS,
+#ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+#endif
+    {NULL}
+};
+
+int verify_main(int argc, char **argv)
+{
+    ENGINE *e = NULL;
+    STACK_OF(X509) *untrusted = NULL, *trusted = NULL;
+    STACK_OF(X509_CRL) *crls = NULL;
+    X509_STORE *store = NULL;
+    X509_VERIFY_PARAM *vpm = NULL;
+    const char *prog, *CApath = NULL, *CAfile = NULL;
+    int noCApath = 0, noCAfile = 0;
+    int vpmtouched = 0, crl_download = 0, show_chain = 0, i = 0, ret = 1;
+    OPTION_CHOICE o;
+
+    if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
+        goto end;
+
+    prog = opt_init(argc, argv, verify_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(verify_options);
+            BIO_printf(bio_err, "Recognized usages:\n");
+            for (i = 0; i < X509_PURPOSE_get_count(); i++) {
+                X509_PURPOSE *ptmp;
+                ptmp = X509_PURPOSE_get0(i);
+                BIO_printf(bio_err, "\t%-10s\t%s\n",
+                        X509_PURPOSE_get0_sname(ptmp),
+                        X509_PURPOSE_get0_name(ptmp));
+            }
+
+            BIO_printf(bio_err, "Recognized verify names:\n");
+            for (i = 0; i < X509_VERIFY_PARAM_get_count(); i++) {
+                const X509_VERIFY_PARAM *vptmp;
+                vptmp = X509_VERIFY_PARAM_get0(i);
+                BIO_printf(bio_err, "\t%-10s\n",
+                        X509_VERIFY_PARAM_get0_name(vptmp));
+            }
+            ret = 0;
+            goto end;
+        case OPT_V_CASES:
+            if (!opt_verify(o, vpm))
+                goto end;
+            vpmtouched++;
+            break;
+        case OPT_CAPATH:
+            CApath = opt_arg();
+            break;
+        case OPT_CAFILE:
+            CAfile = opt_arg();
+            break;
+        case OPT_NOCAPATH:
+            noCApath = 1;
+            break;
+        case OPT_NOCAFILE:
+            noCAfile = 1;
+            break;
+        case OPT_UNTRUSTED:
+            /* Zero or more times */
+            if (!load_certs(opt_arg(), &untrusted, FORMAT_PEM, NULL,
+                            "untrusted certificates"))
+                goto end;
+            break;
+        case OPT_TRUSTED:
+            /* Zero or more times */
+            noCAfile = 1;
+            noCApath = 1;
+            if (!load_certs(opt_arg(), &trusted, FORMAT_PEM, NULL,
+                            "trusted certificates"))
+                goto end;
+            break;
+        case OPT_CRLFILE:
+            /* Zero or more times */
+            if (!load_crls(opt_arg(), &crls, FORMAT_PEM, NULL,
+                           "other CRLs"))
+                goto end;
+            break;
+        case OPT_CRL_DOWNLOAD:
+            crl_download = 1;
+            break;
+        case OPT_ENGINE:
+            if ((e = setup_engine(opt_arg(), 0)) == NULL) {
+                /* Failure message already displayed */
+                goto end;
+            }
+            break;
+        case OPT_SHOW_CHAIN:
+            show_chain = 1;
+            break;
+        case OPT_VERBOSE:
+            v_verbose = 1;
+            break;
+        }
+    }
+    argc = opt_num_rest();
+    argv = opt_rest();
+    if (trusted != NULL && (CAfile || CApath)) {
+        BIO_printf(bio_err,
+                   "%s: Cannot use -trusted with -CAfile or -CApath\n",
+                   prog);
+        goto end;
+    }
+
+    if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL)
+        goto end;
+    X509_STORE_set_verify_cb(store, cb);
+
+    if (vpmtouched)
+        X509_STORE_set1_param(store, vpm);
+
+    ERR_clear_error();
+
+    if (crl_download)
+        store_setup_crl_download(store);
+
+    ret = 0;
+    if (argc < 1) {
+        if (check(store, NULL, untrusted, trusted, crls, show_chain) != 1)
+            ret = -1;
+    } else {
+        for (i = 0; i < argc; i++)
+            if (check(store, argv[i], untrusted, trusted, crls,
+                      show_chain) != 1)
+                ret = -1;
+    }
+
+ end:
+    X509_VERIFY_PARAM_free(vpm);
+    X509_STORE_free(store);
+    sk_X509_pop_free(untrusted, X509_free);
+    sk_X509_pop_free(trusted, X509_free);
+    sk_X509_CRL_pop_free(crls, X509_CRL_free);
+    release_engine(e);
+    return (ret < 0 ? 2 : ret);
+}
+
+static int check(X509_STORE *ctx, const char *file,
+                 STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
+                 STACK_OF(X509_CRL) *crls, int show_chain)
+{
+    X509 *x = NULL;
+    int i = 0, ret = 0;
+    X509_STORE_CTX *csc;
+    STACK_OF(X509) *chain = NULL;
+    int num_untrusted;
+
+    x = load_cert(file, FORMAT_PEM, "certificate file");
+    if (x == NULL)
+        goto end;
+
+    csc = X509_STORE_CTX_new();
+    if (csc == NULL) {
+        printf("error %s: X.509 store context allocation failed\n",
+               (file == NULL) ? "stdin" : file);
+        goto end;
+    }
+
+    X509_STORE_set_flags(ctx, vflags);
+    if (!X509_STORE_CTX_init(csc, ctx, x, uchain)) {
+        printf("error %s: X.509 store context initialization failed\n",
+               (file == NULL) ? "stdin" : file);
+        goto end;
+    }
+    if (tchain)
+        X509_STORE_CTX_set0_trusted_stack(csc, tchain);
+    if (crls)
+        X509_STORE_CTX_set0_crls(csc, crls);
+    i = X509_verify_cert(csc);
+    if (i > 0 && X509_STORE_CTX_get_error(csc) == X509_V_OK) {
+        printf("%s: OK\n", (file == NULL) ? "stdin" : file);
+        ret = 1;
+        if (show_chain) {
+            int j;
+
+            chain = X509_STORE_CTX_get1_chain(csc);
+            num_untrusted = X509_STORE_CTX_get_num_untrusted(csc);
+            printf("Chain:\n");
+            for (j = 0; j < sk_X509_num(chain); j++) {
+                X509 *cert = sk_X509_value(chain, j);
+                printf("depth=%d: ", j);
+                X509_NAME_print_ex_fp(stdout,
+                                      X509_get_subject_name(cert),
+                                      0, XN_FLAG_ONELINE);
+                if (j < num_untrusted)
+                    printf(" (untrusted)");
+                printf("\n");
+            }
+            sk_X509_pop_free(chain, X509_free);
+        }
+    } else {
+        printf("error %s: verification failed\n", (file == NULL) ? "stdin" : file);
+    }
+    X509_STORE_CTX_free(csc);
+
+ end:
+    if (i <= 0)
+        ERR_print_errors(bio_err);
+    X509_free(x);
+
+    return ret;
+}
+
+static int cb(int ok, X509_STORE_CTX *ctx)
+{
+    int cert_error = X509_STORE_CTX_get_error(ctx);
+    X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
+
+    if (!ok) {
+        if (current_cert) {
+            X509_NAME_print_ex(bio_err,
+                            X509_get_subject_name(current_cert),
+                            0, XN_FLAG_ONELINE);
+            BIO_printf(bio_err, "\n");
+        }
+        BIO_printf(bio_err, "%serror %d at %d depth lookup: %s\n",
+               X509_STORE_CTX_get0_parent_ctx(ctx) ? "[CRL path] " : "",
+               cert_error,
+               X509_STORE_CTX_get_error_depth(ctx),
+               X509_verify_cert_error_string(cert_error));
+        switch (cert_error) {
+        case X509_V_ERR_NO_EXPLICIT_POLICY:
+            policies_print(ctx);
+        case X509_V_ERR_CERT_HAS_EXPIRED:
+
+            /*
+             * since we are just checking the certificates, it is ok if they
+             * are self signed. But we should still warn the user.
+             */
+        case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+            /* Continue after extension errors too */
+        case X509_V_ERR_INVALID_CA:
+        case X509_V_ERR_INVALID_NON_CA:
+        case X509_V_ERR_PATH_LENGTH_EXCEEDED:
+        case X509_V_ERR_INVALID_PURPOSE:
+        case X509_V_ERR_CRL_HAS_EXPIRED:
+        case X509_V_ERR_CRL_NOT_YET_VALID:
+        case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
+            ok = 1;
+        }
+
+        return ok;
+
+    }
+    if (cert_error == X509_V_OK && ok == 2)
+        policies_print(ctx);
+    if (!v_verbose)
+        ERR_clear_error();
+    return (ok);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/version.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/version.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/version.c	(revision 331)
@@ -0,0 +1,140 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/evp.h>
+#include <openssl/crypto.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_MD2
+# include <openssl/md2.h>
+#endif
+#ifndef OPENSSL_NO_RC4
+# include <openssl/rc4.h>
+#endif
+#ifndef OPENSSL_NO_DES
+# include <openssl/des.h>
+#endif
+#ifndef OPENSSL_NO_IDEA
+# include <openssl/idea.h>
+#endif
+#ifndef OPENSSL_NO_BF
+# include <openssl/blowfish.h>
+#endif
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_B, OPT_D, OPT_E, OPT_F, OPT_O, OPT_P, OPT_V, OPT_A
+} OPTION_CHOICE;
+
+OPTIONS version_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"a", OPT_A, '-', "Show all data"},
+    {"b", OPT_B, '-', "Show build date"},
+    {"d", OPT_D, '-', "Show configuration directory"},
+    {"e", OPT_E, '-', "Show engines directory"},
+    {"f", OPT_F, '-', "Show compiler flags used"},
+    {"o", OPT_O, '-', "Show some internal datatype options"},
+    {"p", OPT_P, '-', "Show target build platform"},
+    {"v", OPT_V, '-', "Show library version"},
+    {NULL}
+};
+
+int version_main(int argc, char **argv)
+{
+    int ret = 1, dirty = 0;
+    int cflags = 0, version = 0, date = 0, options = 0, platform = 0, dir = 0;
+    int engdir = 0;
+    char *prog;
+    OPTION_CHOICE o;
+
+    prog = opt_init(argc, argv, version_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(version_options);
+            ret = 0;
+            goto end;
+        case OPT_B:
+            dirty = date = 1;
+            break;
+        case OPT_D:
+            dirty = dir = 1;
+            break;
+        case OPT_E:
+            dirty = engdir = 1;
+            break;
+        case OPT_F:
+            dirty = cflags = 1;
+            break;
+        case OPT_O:
+            dirty = options = 1;
+            break;
+        case OPT_P:
+            dirty = platform = 1;
+            break;
+        case OPT_V:
+            dirty = version = 1;
+            break;
+        case OPT_A:
+            cflags = version = date = platform = dir = engdir = 1;
+            break;
+        }
+    }
+    if (!dirty)
+        version = 1;
+
+    if (version) {
+        if (OpenSSL_version_num() == OPENSSL_VERSION_NUMBER) {
+            printf("%s\n", OpenSSL_version(OPENSSL_VERSION));
+        } else {
+            printf("%s (Library: %s)\n",
+                   OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_VERSION));
+        }
+    }
+    if (date)
+        printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON));
+    if (platform)
+        printf("%s\n", OpenSSL_version(OPENSSL_PLATFORM));
+    if (options) {
+        printf("options:  ");
+        printf("%s ", BN_options());
+#ifndef OPENSSL_NO_MD2
+        printf("%s ", MD2_options());
+#endif
+#ifndef OPENSSL_NO_RC4
+        printf("%s ", RC4_options());
+#endif
+#ifndef OPENSSL_NO_DES
+        printf("%s ", DES_options());
+#endif
+#ifndef OPENSSL_NO_IDEA
+        printf("%s ", IDEA_options());
+#endif
+#ifndef OPENSSL_NO_BF
+        printf("%s ", BF_options());
+#endif
+        printf("\n");
+    }
+    if (cflags)
+        printf("%s\n", OpenSSL_version(OPENSSL_CFLAGS));
+    if (dir)
+        printf("%s\n", OpenSSL_version(OPENSSL_DIR));
+    if (engdir)
+        printf("%s\n", OpenSSL_version(OPENSSL_ENGINES_DIR));
+    ret = 0;
+ end:
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/vms_term_sock.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/vms_term_sock.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/vms_term_sock.h	(revision 331)
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2016 VMS Software, Inc. 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
+ */
+
+#ifndef TERM_SOCK_H
+# define TERM_SOCK_H
+
+/*
+** Terminal Socket Function Codes
+*/
+# define TERM_SOCK_CREATE       1
+# define TERM_SOCK_DELETE       2
+
+/*
+** Terminal Socket Status Codes
+*/
+# define TERM_SOCK_FAILURE      0
+# define TERM_SOCK_SUCCESS      1
+
+/*
+** Terminal Socket Prototype
+*/
+int TerminalSocket (int FunctionCode, int *ReturnSocket);
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/apps/x509.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/apps/x509.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/apps/x509.c	(revision 331)
@@ -0,0 +1,1101 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/asn1.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#ifndef OPENSSL_NO_RSA
+# include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+#endif
+
+#undef POSTFIX
+#define POSTFIX ".srl"
+#define DEF_DAYS        30
+
+static int callb(int ok, X509_STORE_CTX *ctx);
+static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext,
+                const EVP_MD *digest, CONF *conf, const char *section);
+static int x509_certify(X509_STORE *ctx, const char *CAfile, const EVP_MD *digest,
+                        X509 *x, X509 *xca, EVP_PKEY *pkey,
+                        STACK_OF(OPENSSL_STRING) *sigopts, const char *serialfile,
+                        int create, int days, int clrext, CONF *conf,
+                        const char *section, ASN1_INTEGER *sno, int reqfile);
+static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt);
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
+    OPT_INFORM, OPT_OUTFORM, OPT_KEYFORM, OPT_REQ, OPT_CAFORM,
+    OPT_CAKEYFORM, OPT_SIGOPT, OPT_DAYS, OPT_PASSIN, OPT_EXTFILE,
+    OPT_EXTENSIONS, OPT_IN, OPT_OUT, OPT_SIGNKEY, OPT_CA,
+    OPT_CAKEY, OPT_CASERIAL, OPT_SET_SERIAL, OPT_FORCE_PUBKEY,
+    OPT_ADDTRUST, OPT_ADDREJECT, OPT_SETALIAS, OPT_CERTOPT, OPT_NAMEOPT,
+    OPT_C, OPT_EMAIL, OPT_OCSP_URI, OPT_SERIAL, OPT_NEXT_SERIAL,
+    OPT_MODULUS, OPT_PUBKEY, OPT_X509TOREQ, OPT_TEXT, OPT_HASH,
+    OPT_ISSUER_HASH, OPT_SUBJECT, OPT_ISSUER, OPT_FINGERPRINT, OPT_DATES,
+    OPT_PURPOSE, OPT_STARTDATE, OPT_ENDDATE, OPT_CHECKEND, OPT_CHECKHOST,
+    OPT_CHECKEMAIL, OPT_CHECKIP, OPT_NOOUT, OPT_TRUSTOUT, OPT_CLRTRUST,
+    OPT_CLRREJECT, OPT_ALIAS, OPT_CACREATESERIAL, OPT_CLREXT, OPT_OCSPID,
+    OPT_SUBJECT_HASH_OLD,
+    OPT_ISSUER_HASH_OLD,
+    OPT_BADSIG, OPT_MD, OPT_ENGINE, OPT_NOCERT
+} OPTION_CHOICE;
+
+OPTIONS x509_options[] = {
+    {"help", OPT_HELP, '-', "Display this summary"},
+    {"inform", OPT_INFORM, 'f',
+     "Input format - default PEM (one of DER, NET or PEM)"},
+    {"in", OPT_IN, '<', "Input file - default stdin"},
+    {"outform", OPT_OUTFORM, 'f',
+     "Output format - default PEM (one of DER, NET or PEM)"},
+    {"out", OPT_OUT, '>', "Output file - default stdout"},
+    {"keyform", OPT_KEYFORM, 'F', "Private key format - default PEM"},
+    {"passin", OPT_PASSIN, 's', "Private key password/pass-phrase source"},
+    {"serial", OPT_SERIAL, '-', "Print serial number value"},
+    {"subject_hash", OPT_HASH, '-', "Print subject hash value"},
+    {"issuer_hash", OPT_ISSUER_HASH, '-', "Print issuer hash value"},
+    {"hash", OPT_HASH, '-', "Synonym for -subject_hash"},
+    {"subject", OPT_SUBJECT, '-', "Print subject DN"},
+    {"issuer", OPT_ISSUER, '-', "Print issuer DN"},
+    {"email", OPT_EMAIL, '-', "Print email address(es)"},
+    {"startdate", OPT_STARTDATE, '-', "Set notBefore field"},
+    {"enddate", OPT_ENDDATE, '-', "Set notAfter field"},
+    {"purpose", OPT_PURPOSE, '-', "Print out certificate purposes"},
+    {"dates", OPT_DATES, '-', "Both Before and After dates"},
+    {"modulus", OPT_MODULUS, '-', "Print the RSA key modulus"},
+    {"pubkey", OPT_PUBKEY, '-', "Output the public key"},
+    {"fingerprint", OPT_FINGERPRINT, '-',
+     "Print the certificate fingerprint"},
+    {"alias", OPT_ALIAS, '-', "Output certificate alias"},
+    {"noout", OPT_NOOUT, '-', "No output, just status"},
+    {"nocert", OPT_NOCERT, '-', "No certificate output"},
+    {"ocspid", OPT_OCSPID, '-',
+     "Print OCSP hash values for the subject name and public key"},
+    {"ocsp_uri", OPT_OCSP_URI, '-', "Print OCSP Responder URL(s)"},
+    {"trustout", OPT_TRUSTOUT, '-', "Output a trusted certificate"},
+    {"clrtrust", OPT_CLRTRUST, '-', "Clear all trusted purposes"},
+    {"clrext", OPT_CLREXT, '-', "Clear all certificate extensions"},
+    {"addtrust", OPT_ADDTRUST, 's', "Trust certificate for a given purpose"},
+    {"addreject", OPT_ADDREJECT, 's',
+     "Reject certificate for a given purpose"},
+    {"setalias", OPT_SETALIAS, 's', "Set certificate alias"},
+    {"days", OPT_DAYS, 'n',
+     "How long till expiry of a signed certificate - def 30 days"},
+    {"checkend", OPT_CHECKEND, 'M',
+     "Check whether the cert expires in the next arg seconds"},
+    {OPT_MORE_STR, 1, 1, "Exit 1 if so, 0 if not"},
+    {"signkey", OPT_SIGNKEY, '<', "Self sign cert with arg"},
+    {"x509toreq", OPT_X509TOREQ, '-',
+     "Output a certification request object"},
+    {"req", OPT_REQ, '-', "Input is a certificate request, sign and output"},
+    {"CA", OPT_CA, '<', "Set the CA certificate, must be PEM format"},
+    {"CAkey", OPT_CAKEY, 's',
+     "The CA key, must be PEM format; if not in CAfile"},
+    {"CAcreateserial", OPT_CACREATESERIAL, '-',
+     "Create serial number file if it does not exist"},
+    {"CAserial", OPT_CASERIAL, 's', "Serial file"},
+    {"set_serial", OPT_SET_SERIAL, 's', "Serial number to use"},
+    {"text", OPT_TEXT, '-', "Print the certificate in text form"},
+    {"C", OPT_C, '-', "Print out C code forms"},
+    {"extfile", OPT_EXTFILE, '<', "File with X509V3 extensions to add"},
+    {"extensions", OPT_EXTENSIONS, 's', "Section from config file to use"},
+    {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"},
+    {"certopt", OPT_CERTOPT, 's', "Various certificate text options"},
+    {"checkhost", OPT_CHECKHOST, 's', "Check certificate matches host"},
+    {"checkemail", OPT_CHECKEMAIL, 's', "Check certificate matches email"},
+    {"checkip", OPT_CHECKIP, 's', "Check certificate matches ipaddr"},
+    {"CAform", OPT_CAFORM, 'F', "CA format - default PEM"},
+    {"CAkeyform", OPT_CAKEYFORM, 'F', "CA key format - default PEM"},
+    {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"},
+    {"force_pubkey", OPT_FORCE_PUBKEY, '<', "Force the Key to put inside certificate"},
+    {"next_serial", OPT_NEXT_SERIAL, '-', "Increment current certificate serial number"},
+    {"clrreject", OPT_CLRREJECT, '-',
+     "Clears all the prohibited or rejected uses of the certificate"},
+    {"badsig", OPT_BADSIG, '-', "Corrupt last byte of certificate signature (for test)"},
+    {"", OPT_MD, '-', "Any supported digest"},
+#ifndef OPENSSL_NO_MD5
+    {"subject_hash_old", OPT_SUBJECT_HASH_OLD, '-',
+     "Print old-style (MD5) issuer hash value"},
+    {"issuer_hash_old", OPT_ISSUER_HASH_OLD, '-',
+     "Print old-style (MD5) subject hash value"},
+#endif
+#ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+#endif
+    {NULL}
+};
+
+int x509_main(int argc, char **argv)
+{
+    ASN1_INTEGER *sno = NULL;
+    ASN1_OBJECT *objtmp = NULL;
+    BIO *out = NULL;
+    CONF *extconf = NULL;
+    EVP_PKEY *Upkey = NULL, *CApkey = NULL, *fkey = NULL;
+    STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
+    STACK_OF(OPENSSL_STRING) *sigopts = NULL;
+    X509 *x = NULL, *xca = NULL;
+    X509_REQ *req = NULL, *rq = NULL;
+    X509_STORE *ctx = NULL;
+    const EVP_MD *digest = NULL;
+    char *CAkeyfile = NULL, *CAserial = NULL, *fkeyfile = NULL, *alias = NULL;
+    char *checkhost = NULL, *checkemail = NULL, *checkip = NULL;
+    char *extsect = NULL, *extfile = NULL, *passin = NULL, *passinarg = NULL;
+    char *infile = NULL, *outfile = NULL, *keyfile = NULL, *CAfile = NULL;
+    char buf[256], *prog;
+    int x509req = 0, days = DEF_DAYS, modulus = 0, pubkey = 0, pprint = 0;
+    int C = 0, CAformat = FORMAT_PEM, CAkeyformat = FORMAT_PEM;
+    int fingerprint = 0, reqfile = 0, need_rand = 0, checkend = 0;
+    int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM;
+    int next_serial = 0, subject_hash = 0, issuer_hash = 0, ocspid = 0;
+    int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0, email = 0;
+    int ocsp_uri = 0, trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0;
+    int ret = 1, i, num = 0, badsig = 0, clrext = 0, nocert = 0;
+    int text = 0, serial = 0, subject = 0, issuer = 0, startdate = 0;
+    int enddate = 0;
+    time_t checkoffset = 0;
+    unsigned long nmflag = 0, certflag = 0;
+    char nmflag_set = 0;
+    OPTION_CHOICE o;
+    ENGINE *e = NULL;
+#ifndef OPENSSL_NO_MD5
+    int subject_hash_old = 0, issuer_hash_old = 0;
+#endif
+
+    ctx = X509_STORE_new();
+    if (ctx == NULL)
+        goto end;
+    X509_STORE_set_verify_cb(ctx, callb);
+
+    prog = opt_init(argc, argv, x509_options);
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_EOF:
+        case OPT_ERR:
+ opthelp:
+            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
+            goto end;
+        case OPT_HELP:
+            opt_help(x509_options);
+            ret = 0;
+            goto end;
+        case OPT_INFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_ANY, &informat))
+                goto opthelp;
+            break;
+        case OPT_IN:
+            infile = opt_arg();
+            break;
+        case OPT_OUTFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_ANY, &outformat))
+                goto opthelp;
+            break;
+        case OPT_KEYFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat))
+                goto opthelp;
+            break;
+        case OPT_CAFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &CAformat))
+                goto opthelp;
+            break;
+        case OPT_CAKEYFORM:
+            if (!opt_format(opt_arg(), OPT_FMT_ANY, &CAkeyformat))
+                goto opthelp;
+            break;
+        case OPT_OUT:
+            outfile = opt_arg();
+            break;
+        case OPT_REQ:
+            reqfile = need_rand = 1;
+            break;
+
+        case OPT_SIGOPT:
+            if (!sigopts)
+                sigopts = sk_OPENSSL_STRING_new_null();
+            if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
+                goto opthelp;
+            break;
+        case OPT_DAYS:
+            days = atoi(opt_arg());
+            break;
+        case OPT_PASSIN:
+            passinarg = opt_arg();
+            break;
+        case OPT_EXTFILE:
+            extfile = opt_arg();
+            break;
+        case OPT_EXTENSIONS:
+            extsect = opt_arg();
+            break;
+        case OPT_SIGNKEY:
+            keyfile = opt_arg();
+            sign_flag = ++num;
+            need_rand = 1;
+            break;
+        case OPT_CA:
+            CAfile = opt_arg();
+            CA_flag = ++num;
+            need_rand = 1;
+            break;
+        case OPT_CAKEY:
+            CAkeyfile = opt_arg();
+            break;
+        case OPT_CASERIAL:
+            CAserial = opt_arg();
+            break;
+        case OPT_SET_SERIAL:
+            if (sno != NULL) {
+                BIO_printf(bio_err, "Serial number supplied twice\n");
+                goto opthelp;
+            }
+            if ((sno = s2i_ASN1_INTEGER(NULL, opt_arg())) == NULL)
+                goto opthelp;
+            break;
+        case OPT_FORCE_PUBKEY:
+            fkeyfile = opt_arg();
+            break;
+        case OPT_ADDTRUST:
+            if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) {
+                BIO_printf(bio_err,
+                           "%s: Invalid trust object value %s\n",
+                           prog, opt_arg());
+                goto opthelp;
+            }
+            if (trust == NULL && (trust = sk_ASN1_OBJECT_new_null()) == NULL)
+                goto end;
+            sk_ASN1_OBJECT_push(trust, objtmp);
+            objtmp = NULL;
+            trustout = 1;
+            break;
+        case OPT_ADDREJECT:
+            if ((objtmp = OBJ_txt2obj(opt_arg(), 0)) == NULL) {
+                BIO_printf(bio_err,
+                           "%s: Invalid reject object value %s\n",
+                           prog, opt_arg());
+                goto opthelp;
+            }
+            if (reject == NULL
+                && (reject = sk_ASN1_OBJECT_new_null()) == NULL)
+                goto end;
+            sk_ASN1_OBJECT_push(reject, objtmp);
+            objtmp = NULL;
+            trustout = 1;
+            break;
+        case OPT_SETALIAS:
+            alias = opt_arg();
+            trustout = 1;
+            break;
+        case OPT_CERTOPT:
+            if (!set_cert_ex(&certflag, opt_arg()))
+                goto opthelp;
+            break;
+        case OPT_NAMEOPT:
+            nmflag_set = 1;
+            if (!set_name_ex(&nmflag, opt_arg()))
+                goto opthelp;
+            break;
+        case OPT_ENGINE:
+            e = setup_engine(opt_arg(), 0);
+            break;
+        case OPT_C:
+            C = ++num;
+            break;
+        case OPT_EMAIL:
+            email = ++num;
+            break;
+        case OPT_OCSP_URI:
+            ocsp_uri = ++num;
+            break;
+        case OPT_SERIAL:
+            serial = ++num;
+            break;
+        case OPT_NEXT_SERIAL:
+            next_serial = ++num;
+            break;
+        case OPT_MODULUS:
+            modulus = ++num;
+            break;
+        case OPT_PUBKEY:
+            pubkey = ++num;
+            break;
+        case OPT_X509TOREQ:
+            x509req = ++num;
+            break;
+        case OPT_TEXT:
+            text = ++num;
+            break;
+        case OPT_SUBJECT:
+            subject = ++num;
+            break;
+        case OPT_ISSUER:
+            issuer = ++num;
+            break;
+        case OPT_FINGERPRINT:
+            fingerprint = ++num;
+            break;
+        case OPT_HASH:
+            subject_hash = ++num;
+            break;
+        case OPT_ISSUER_HASH:
+            issuer_hash = ++num;
+            break;
+        case OPT_PURPOSE:
+            pprint = ++num;
+            break;
+        case OPT_STARTDATE:
+            startdate = ++num;
+            break;
+        case OPT_ENDDATE:
+            enddate = ++num;
+            break;
+        case OPT_NOOUT:
+            noout = ++num;
+            break;
+        case OPT_NOCERT:
+            nocert = 1;
+            break;
+        case OPT_TRUSTOUT:
+            trustout = 1;
+            break;
+        case OPT_CLRTRUST:
+            clrtrust = ++num;
+            break;
+        case OPT_CLRREJECT:
+            clrreject = ++num;
+            break;
+        case OPT_ALIAS:
+            aliasout = ++num;
+            break;
+        case OPT_CACREATESERIAL:
+            CA_createserial = ++num;
+            break;
+        case OPT_CLREXT:
+            clrext = 1;
+            break;
+        case OPT_OCSPID:
+            ocspid = ++num;
+            break;
+        case OPT_BADSIG:
+            badsig = 1;
+            break;
+#ifndef OPENSSL_NO_MD5
+        case OPT_SUBJECT_HASH_OLD:
+            subject_hash_old = ++num;
+            break;
+        case OPT_ISSUER_HASH_OLD:
+            issuer_hash_old = ++num;
+            break;
+#else
+        case OPT_SUBJECT_HASH_OLD:
+        case OPT_ISSUER_HASH_OLD:
+            break;
+#endif
+        case OPT_DATES:
+            startdate = ++num;
+            enddate = ++num;
+            break;
+        case OPT_CHECKEND:
+            checkend = 1;
+            {
+                intmax_t temp = 0;
+                if (!opt_imax(opt_arg(), &temp))
+                    goto opthelp;
+                checkoffset = (time_t)temp;
+                if ((intmax_t)checkoffset != temp) {
+                    BIO_printf(bio_err, "%s: checkend time out of range %s\n",
+                               prog, opt_arg());
+                    goto opthelp;
+                }
+            }
+            break;
+        case OPT_CHECKHOST:
+            checkhost = opt_arg();
+            break;
+        case OPT_CHECKEMAIL:
+            checkemail = opt_arg();
+            break;
+        case OPT_CHECKIP:
+            checkip = opt_arg();
+            break;
+        case OPT_MD:
+            if (!opt_md(opt_unknown(), &digest))
+                goto opthelp;
+        }
+    }
+    argc = opt_num_rest();
+    argv = opt_rest();
+    if (argc != 0) {
+        BIO_printf(bio_err, "%s: Unknown parameter %s\n", prog, argv[0]);
+        goto opthelp;
+    }
+
+    if (!nmflag_set)
+        nmflag = XN_FLAG_ONELINE;
+
+    out = bio_open_default(outfile, 'w', outformat);
+    if (out == NULL)
+        goto end;
+
+    if (need_rand)
+        app_RAND_load_file(NULL, 0);
+
+    if (!app_passwd(passinarg, NULL, &passin, NULL)) {
+        BIO_printf(bio_err, "Error getting password\n");
+        goto end;
+    }
+
+    if (!X509_STORE_set_default_paths(ctx)) {
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+
+    if (fkeyfile) {
+        fkey = load_pubkey(fkeyfile, keyformat, 0, NULL, e, "Forced key");
+        if (fkey == NULL)
+            goto end;
+    }
+
+    if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) {
+        CAkeyfile = CAfile;
+    } else if ((CA_flag) && (CAkeyfile == NULL)) {
+        BIO_printf(bio_err,
+                   "need to specify a CAkey if using the CA command\n");
+        goto end;
+    }
+
+    if (extfile) {
+        X509V3_CTX ctx2;
+        if ((extconf = app_load_config(extfile)) == NULL)
+            goto end;
+        if (!extsect) {
+            extsect = NCONF_get_string(extconf, "default", "extensions");
+            if (!extsect) {
+                ERR_clear_error();
+                extsect = "default";
+            }
+        }
+        X509V3_set_ctx_test(&ctx2);
+        X509V3_set_nconf(&ctx2, extconf);
+        if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) {
+            BIO_printf(bio_err,
+                       "Error Loading extension section %s\n", extsect);
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    if (reqfile) {
+        EVP_PKEY *pkey;
+        BIO *in;
+
+        if (!sign_flag && !CA_flag) {
+            BIO_printf(bio_err, "We need a private key to sign with\n");
+            goto end;
+        }
+        in = bio_open_default(infile, 'r', informat);
+        if (in == NULL)
+            goto end;
+        req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
+        BIO_free(in);
+
+        if (req == NULL) {
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+
+        if ((pkey = X509_REQ_get0_pubkey(req)) == NULL) {
+            BIO_printf(bio_err, "error unpacking public key\n");
+            goto end;
+        }
+        i = X509_REQ_verify(req, pkey);
+        if (i < 0) {
+            BIO_printf(bio_err, "Signature verification error\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+        if (i == 0) {
+            BIO_printf(bio_err,
+                       "Signature did not match the certificate request\n");
+            goto end;
+        } else
+            BIO_printf(bio_err, "Signature ok\n");
+
+        print_name(bio_err, "subject=", X509_REQ_get_subject_name(req),
+                   nmflag);
+
+        if ((x = X509_new()) == NULL)
+            goto end;
+
+        if (sno == NULL) {
+            sno = ASN1_INTEGER_new();
+            if (sno == NULL || !rand_serial(NULL, sno))
+                goto end;
+            if (!X509_set_serialNumber(x, sno))
+                goto end;
+            ASN1_INTEGER_free(sno);
+            sno = NULL;
+        } else if (!X509_set_serialNumber(x, sno))
+            goto end;
+
+        if (!X509_set_issuer_name(x, X509_REQ_get_subject_name(req)))
+            goto end;
+        if (!X509_set_subject_name(x, X509_REQ_get_subject_name(req)))
+            goto end;
+        if (!set_cert_times(x, NULL, NULL, days))
+            goto end;
+
+        if (fkey)
+            X509_set_pubkey(x, fkey);
+        else {
+            pkey = X509_REQ_get0_pubkey(req);
+            X509_set_pubkey(x, pkey);
+        }
+    } else
+        x = load_cert(infile, informat, "Certificate");
+
+    if (x == NULL)
+        goto end;
+    if (CA_flag) {
+        xca = load_cert(CAfile, CAformat, "CA Certificate");
+        if (xca == NULL)
+            goto end;
+    }
+
+    if (!noout || text || next_serial) {
+        OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3");
+
+    }
+
+    if (alias)
+        X509_alias_set1(x, (unsigned char *)alias, -1);
+
+    if (clrtrust)
+        X509_trust_clear(x);
+    if (clrreject)
+        X509_reject_clear(x);
+
+    if (trust) {
+        for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) {
+            objtmp = sk_ASN1_OBJECT_value(trust, i);
+            X509_add1_trust_object(x, objtmp);
+        }
+        objtmp = NULL;
+    }
+
+    if (reject) {
+        for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) {
+            objtmp = sk_ASN1_OBJECT_value(reject, i);
+            X509_add1_reject_object(x, objtmp);
+        }
+        objtmp = NULL;
+    }
+
+    if (badsig) {
+        const ASN1_BIT_STRING *signature;
+
+        X509_get0_signature(&signature, NULL, x);
+        corrupt_signature(signature);
+    }
+
+    if (num) {
+        for (i = 1; i <= num; i++) {
+            if (issuer == i) {
+                print_name(out, "issuer=", X509_get_issuer_name(x), nmflag);
+            } else if (subject == i) {
+                print_name(out, "subject=",
+                           X509_get_subject_name(x), nmflag);
+            } else if (serial == i) {
+                BIO_printf(out, "serial=");
+                i2a_ASN1_INTEGER(out, X509_get_serialNumber(x));
+                BIO_printf(out, "\n");
+            } else if (next_serial == i) {
+                ASN1_INTEGER *ser = X509_get_serialNumber(x);
+                BIGNUM *bnser = ASN1_INTEGER_to_BN(ser, NULL);
+
+                if (!bnser)
+                    goto end;
+                if (!BN_add_word(bnser, 1))
+                    goto end;
+                ser = BN_to_ASN1_INTEGER(bnser, NULL);
+                if (!ser)
+                    goto end;
+                BN_free(bnser);
+                i2a_ASN1_INTEGER(out, ser);
+                ASN1_INTEGER_free(ser);
+                BIO_puts(out, "\n");
+            } else if ((email == i) || (ocsp_uri == i)) {
+                int j;
+                STACK_OF(OPENSSL_STRING) *emlst;
+                if (email == i)
+                    emlst = X509_get1_email(x);
+                else
+                    emlst = X509_get1_ocsp(x);
+                for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
+                    BIO_printf(out, "%s\n",
+                               sk_OPENSSL_STRING_value(emlst, j));
+                X509_email_free(emlst);
+            } else if (aliasout == i) {
+                unsigned char *alstr;
+                alstr = X509_alias_get0(x, NULL);
+                if (alstr)
+                    BIO_printf(out, "%s\n", alstr);
+                else
+                    BIO_puts(out, "<No Alias>\n");
+            } else if (subject_hash == i) {
+                BIO_printf(out, "%08lx\n", X509_subject_name_hash(x));
+            }
+#ifndef OPENSSL_NO_MD5
+            else if (subject_hash_old == i) {
+                BIO_printf(out, "%08lx\n", X509_subject_name_hash_old(x));
+            }
+#endif
+            else if (issuer_hash == i) {
+                BIO_printf(out, "%08lx\n", X509_issuer_name_hash(x));
+            }
+#ifndef OPENSSL_NO_MD5
+            else if (issuer_hash_old == i) {
+                BIO_printf(out, "%08lx\n", X509_issuer_name_hash_old(x));
+            }
+#endif
+            else if (pprint == i) {
+                X509_PURPOSE *ptmp;
+                int j;
+                BIO_printf(out, "Certificate purposes:\n");
+                for (j = 0; j < X509_PURPOSE_get_count(); j++) {
+                    ptmp = X509_PURPOSE_get0(j);
+                    purpose_print(out, x, ptmp);
+                }
+            } else if (modulus == i) {
+                EVP_PKEY *pkey;
+
+                pkey = X509_get0_pubkey(x);
+                if (pkey == NULL) {
+                    BIO_printf(bio_err, "Modulus=unavailable\n");
+                    ERR_print_errors(bio_err);
+                    goto end;
+                }
+                BIO_printf(out, "Modulus=");
+#ifndef OPENSSL_NO_RSA
+                if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) {
+                    const BIGNUM *n;
+                    RSA_get0_key(EVP_PKEY_get0_RSA(pkey), &n, NULL, NULL);
+                    BN_print(out, n);
+                } else
+#endif
+#ifndef OPENSSL_NO_DSA
+                if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA) {
+                    const BIGNUM *dsapub = NULL;
+                    DSA_get0_key(EVP_PKEY_get0_DSA(pkey), &dsapub, NULL);
+                    BN_print(out, dsapub);
+                } else
+#endif
+                {
+                    BIO_printf(out, "Wrong Algorithm type");
+                }
+                BIO_printf(out, "\n");
+            } else if (pubkey == i) {
+                EVP_PKEY *pkey;
+
+                pkey = X509_get0_pubkey(x);
+                if (pkey == NULL) {
+                    BIO_printf(bio_err, "Error getting public key\n");
+                    ERR_print_errors(bio_err);
+                    goto end;
+                }
+                PEM_write_bio_PUBKEY(out, pkey);
+            } else if (C == i) {
+                unsigned char *d;
+                char *m;
+                int len;
+
+                X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof buf);
+                BIO_printf(out, "/*\n"
+                                " * Subject: %s\n", buf);
+
+                X509_NAME_oneline(X509_get_issuer_name(x), buf, sizeof buf);
+                BIO_printf(out, " * Issuer:  %s\n"
+                                " */\n", buf);
+
+                len = i2d_X509(x, NULL);
+                m = app_malloc(len, "x509 name buffer");
+                d = (unsigned char *)m;
+                len = i2d_X509_NAME(X509_get_subject_name(x), &d);
+                print_array(out, "the_subject_name", len, (unsigned char *)m);
+                d = (unsigned char *)m;
+                len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d);
+                print_array(out, "the_public_key", len, (unsigned char *)m);
+                d = (unsigned char *)m;
+                len = i2d_X509(x, &d);
+                print_array(out, "the_certificate", len, (unsigned char *)m);
+                OPENSSL_free(m);
+            } else if (text == i) {
+                X509_print_ex(out, x, nmflag, certflag);
+            } else if (startdate == i) {
+                BIO_puts(out, "notBefore=");
+                ASN1_TIME_print(out, X509_get0_notBefore(x));
+                BIO_puts(out, "\n");
+            } else if (enddate == i) {
+                BIO_puts(out, "notAfter=");
+                ASN1_TIME_print(out, X509_get0_notAfter(x));
+                BIO_puts(out, "\n");
+            } else if (fingerprint == i) {
+                int j;
+                unsigned int n;
+                unsigned char md[EVP_MAX_MD_SIZE];
+                const EVP_MD *fdig = digest;
+
+                if (!fdig)
+                    fdig = EVP_sha1();
+
+                if (!X509_digest(x, fdig, md, &n)) {
+                    BIO_printf(bio_err, "out of memory\n");
+                    goto end;
+                }
+                BIO_printf(out, "%s Fingerprint=",
+                           OBJ_nid2sn(EVP_MD_type(fdig)));
+                for (j = 0; j < (int)n; j++) {
+                    BIO_printf(out, "%02X%c", md[j], (j + 1 == (int)n)
+                               ? '\n' : ':');
+                }
+            }
+
+            /* should be in the library */
+            else if ((sign_flag == i) && (x509req == 0)) {
+                BIO_printf(bio_err, "Getting Private key\n");
+                if (Upkey == NULL) {
+                    Upkey = load_key(keyfile, keyformat, 0,
+                                     passin, e, "Private key");
+                    if (Upkey == NULL)
+                        goto end;
+                }
+
+                assert(need_rand);
+                if (!sign(x, Upkey, days, clrext, digest, extconf, extsect))
+                    goto end;
+            } else if (CA_flag == i) {
+                BIO_printf(bio_err, "Getting CA Private Key\n");
+                if (CAkeyfile != NULL) {
+                    CApkey = load_key(CAkeyfile, CAkeyformat,
+                                      0, passin, e, "CA Private Key");
+                    if (CApkey == NULL)
+                        goto end;
+                }
+
+                assert(need_rand);
+                if (!x509_certify(ctx, CAfile, digest, x, xca,
+                                  CApkey, sigopts,
+                                  CAserial, CA_createserial, days, clrext,
+                                  extconf, extsect, sno, reqfile))
+                    goto end;
+            } else if (x509req == i) {
+                EVP_PKEY *pk;
+
+                BIO_printf(bio_err, "Getting request Private Key\n");
+                if (keyfile == NULL) {
+                    BIO_printf(bio_err, "no request key file specified\n");
+                    goto end;
+                } else {
+                    pk = load_key(keyfile, keyformat, 0,
+                                  passin, e, "request key");
+                    if (pk == NULL)
+                        goto end;
+                }
+
+                BIO_printf(bio_err, "Generating certificate request\n");
+
+                rq = X509_to_X509_REQ(x, pk, digest);
+                EVP_PKEY_free(pk);
+                if (rq == NULL) {
+                    ERR_print_errors(bio_err);
+                    goto end;
+                }
+                if (!noout) {
+                    X509_REQ_print(out, rq);
+                    PEM_write_bio_X509_REQ(out, rq);
+                }
+                noout = 1;
+            } else if (ocspid == i) {
+                X509_ocspid_print(out, x);
+            }
+        }
+    }
+
+    if (checkend) {
+        time_t tcheck = time(NULL) + checkoffset;
+
+        if (X509_cmp_time(X509_get0_notAfter(x), &tcheck) < 0) {
+            BIO_printf(out, "Certificate will expire\n");
+            ret = 1;
+        } else {
+            BIO_printf(out, "Certificate will not expire\n");
+            ret = 0;
+        }
+        goto end;
+    }
+
+    print_cert_checks(out, x, checkhost, checkemail, checkip);
+
+    if (noout || nocert) {
+        ret = 0;
+        goto end;
+    }
+
+    if (outformat == FORMAT_ASN1)
+        i = i2d_X509_bio(out, x);
+    else if (outformat == FORMAT_PEM) {
+        if (trustout)
+            i = PEM_write_bio_X509_AUX(out, x);
+        else
+            i = PEM_write_bio_X509(out, x);
+    } else {
+        BIO_printf(bio_err, "bad output format specified for outfile\n");
+        goto end;
+    }
+    if (!i) {
+        BIO_printf(bio_err, "unable to write certificate\n");
+        ERR_print_errors(bio_err);
+        goto end;
+    }
+    ret = 0;
+ end:
+    if (need_rand)
+        app_RAND_write_file(NULL);
+    NCONF_free(extconf);
+    BIO_free_all(out);
+    X509_STORE_free(ctx);
+    X509_REQ_free(req);
+    X509_free(x);
+    X509_free(xca);
+    EVP_PKEY_free(Upkey);
+    EVP_PKEY_free(CApkey);
+    EVP_PKEY_free(fkey);
+    sk_OPENSSL_STRING_free(sigopts);
+    X509_REQ_free(rq);
+    ASN1_INTEGER_free(sno);
+    sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
+    sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
+    ASN1_OBJECT_free(objtmp);
+    release_engine(e);
+    OPENSSL_free(passin);
+    return (ret);
+}
+
+static ASN1_INTEGER *x509_load_serial(const char *CAfile, const char *serialfile,
+                                      int create)
+{
+    char *buf = NULL, *p;
+    ASN1_INTEGER *bs = NULL;
+    BIGNUM *serial = NULL;
+    size_t len;
+
+    len = ((serialfile == NULL)
+           ? (strlen(CAfile) + strlen(POSTFIX) + 1)
+           : (strlen(serialfile))) + 1;
+    buf = app_malloc(len, "serial# buffer");
+    if (serialfile == NULL) {
+        OPENSSL_strlcpy(buf, CAfile, len);
+        for (p = buf; *p; p++)
+            if (*p == '.') {
+                *p = '\0';
+                break;
+            }
+        OPENSSL_strlcat(buf, POSTFIX, len);
+    } else
+        OPENSSL_strlcpy(buf, serialfile, len);
+
+    serial = load_serial(buf, create, NULL);
+    if (serial == NULL)
+        goto end;
+
+    if (!BN_add_word(serial, 1)) {
+        BIO_printf(bio_err, "add_word failure\n");
+        goto end;
+    }
+
+    if (!save_serial(buf, NULL, serial, &bs))
+        goto end;
+
+ end:
+    OPENSSL_free(buf);
+    BN_free(serial);
+    return bs;
+}
+
+static int x509_certify(X509_STORE *ctx, const char *CAfile, const EVP_MD *digest,
+                        X509 *x, X509 *xca, EVP_PKEY *pkey,
+                        STACK_OF(OPENSSL_STRING) *sigopts,
+                        const char *serialfile, int create,
+                        int days, int clrext, CONF *conf, const char *section,
+                        ASN1_INTEGER *sno, int reqfile)
+{
+    int ret = 0;
+    ASN1_INTEGER *bs = NULL;
+    X509_STORE_CTX *xsc = NULL;
+    EVP_PKEY *upkey;
+
+    upkey = X509_get0_pubkey(xca);
+    if (upkey == NULL) {
+        BIO_printf(bio_err, "Error obtaining CA X509 public key\n");
+        goto end;
+    }
+    EVP_PKEY_copy_parameters(upkey, pkey);
+
+    xsc = X509_STORE_CTX_new();
+    if (xsc == NULL || !X509_STORE_CTX_init(xsc, ctx, x, NULL)) {
+        BIO_printf(bio_err, "Error initialising X509 store\n");
+        goto end;
+    }
+    if (sno)
+        bs = sno;
+    else if ((bs = x509_load_serial(CAfile, serialfile, create)) == NULL)
+        goto end;
+
+    /*
+     * NOTE: this certificate can/should be self signed, unless it was a
+     * certificate request in which case it is not.
+     */
+    X509_STORE_CTX_set_cert(xsc, x);
+    X509_STORE_CTX_set_flags(xsc, X509_V_FLAG_CHECK_SS_SIGNATURE);
+    if (!reqfile && X509_verify_cert(xsc) <= 0)
+        goto end;
+
+    if (!X509_check_private_key(xca, pkey)) {
+        BIO_printf(bio_err,
+                   "CA certificate and CA private key do not match\n");
+        goto end;
+    }
+
+    if (!X509_set_issuer_name(x, X509_get_subject_name(xca)))
+        goto end;
+    if (!X509_set_serialNumber(x, bs))
+        goto end;
+
+    if (!set_cert_times(x, NULL, NULL, days))
+        goto end;
+
+    if (clrext) {
+        while (X509_get_ext_count(x) > 0)
+            X509_delete_ext(x, 0);
+    }
+
+    if (conf) {
+        X509V3_CTX ctx2;
+        X509_set_version(x, 2); /* version 3 certificate */
+        X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
+        X509V3_set_nconf(&ctx2, conf);
+        if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x))
+            goto end;
+    }
+
+    if (!do_X509_sign(x, pkey, digest, sigopts))
+        goto end;
+    ret = 1;
+ end:
+    X509_STORE_CTX_free(xsc);
+    if (!ret)
+        ERR_print_errors(bio_err);
+    if (!sno)
+        ASN1_INTEGER_free(bs);
+    return ret;
+}
+
+static int callb(int ok, X509_STORE_CTX *ctx)
+{
+    int err;
+    X509 *err_cert;
+
+    /*
+     * it is ok to use a self signed certificate This case will catch both
+     * the initial ok == 0 and the final ok == 1 calls to this function
+     */
+    err = X509_STORE_CTX_get_error(ctx);
+    if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
+        return 1;
+
+    /*
+     * BAD we should have gotten an error.  Normally if everything worked
+     * X509_STORE_CTX_get_error(ctx) will still be set to
+     * DEPTH_ZERO_SELF_....
+     */
+    if (ok) {
+        BIO_printf(bio_err,
+                   "error with certificate to be certified - should be self signed\n");
+        return 0;
+    } else {
+        err_cert = X509_STORE_CTX_get_current_cert(ctx);
+        print_name(bio_err, NULL, X509_get_subject_name(err_cert), 0);
+        BIO_printf(bio_err,
+                   "error with certificate - error %d at depth %d\n%s\n", err,
+                   X509_STORE_CTX_get_error_depth(ctx),
+                   X509_verify_cert_error_string(err));
+        return 1;
+    }
+}
+
+/* self sign */
+static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext,
+                const EVP_MD *digest, CONF *conf, const char *section)
+{
+
+    if (!X509_set_issuer_name(x, X509_get_subject_name(x)))
+        goto err;
+    if (!set_cert_times(x, NULL, NULL, days))
+        goto err;
+    if (!X509_set_pubkey(x, pkey))
+        goto err;
+    if (clrext) {
+        while (X509_get_ext_count(x) > 0)
+            X509_delete_ext(x, 0);
+    }
+    if (conf) {
+        X509V3_CTX ctx;
+        X509_set_version(x, 2); /* version 3 certificate */
+        X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0);
+        X509V3_set_nconf(&ctx, conf);
+        if (!X509V3_EXT_add_nconf(conf, &ctx, section, x))
+            goto err;
+    }
+    if (!X509_sign(x, pkey, digest))
+        goto err;
+    return 1;
+ err:
+    ERR_print_errors(bio_err);
+    return 0;
+}
+
+static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt)
+{
+    int id, i, idret;
+    const char *pname;
+    id = X509_PURPOSE_get_id(pt);
+    pname = X509_PURPOSE_get0_name(pt);
+    for (i = 0; i < 2; i++) {
+        idret = X509_check_purpose(cert, id, i);
+        BIO_printf(bio, "%s%s : ", pname, i ? " CA" : "");
+        if (idret == 1)
+            BIO_printf(bio, "Yes\n");
+        else if (idret == 0)
+            BIO_printf(bio, "No\n");
+        else
+            BIO_printf(bio, "Yes (WARNING code=%d)\n", idret);
+    }
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/configdata.pm
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/configdata.pm	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/configdata.pm	(revision 331)
@@ -0,0 +1,7964 @@
+package configdata;
+
+use strict;
+use warnings;
+
+use Exporter;
+#use vars qw(@ISA @EXPORT);
+our @ISA = qw(Exporter);
+our @EXPORT = qw(%config %target %disabled %withargs %unified_info @disablables);
+
+our %config = (
+  afalgeng => "",
+  b32 => "1",
+  b64 => "0",
+  b64l => "0",
+  baseaddr => "0xFB00000",
+  bn_ll => "1",
+  build_file => "Makefile",
+  build_file_templates => [ "Configurations/unix-Makefile.tmpl", "Configurations/common.tmpl" ],
+  build_infos => [ "./build.info", "crypto/build.info", "ssl/build.info", "engines/build.info", "apps/build.info", "test/build.info", "util/build.info", "tools/build.info", "fuzz/build.info", "crypto/objects/build.info", "crypto/md4/build.info", "crypto/md5/build.info", "crypto/sha/build.info", "crypto/mdc2/build.info", "crypto/hmac/build.info", "crypto/ripemd/build.info", "crypto/whrlpool/build.info", "crypto/poly1305/build.info", "crypto/blake2/build.info", "crypto/des/build.info", "crypto/aes/build.info", "crypto/rc2/build.info", "crypto/rc4/build.info", "crypto/idea/build.info", "crypto/bf/build.info", "crypto/cast/build.info", "crypto/camellia/build.info", "crypto/seed/build.info", "crypto/chacha/build.info", "crypto/modes/build.info", "crypto/bn/build.info", "crypto/ec/build.info", "crypto/rsa/build.info", "crypto/dsa/build.info", "crypto/dh/build.info", "crypto/dso/build.info", "crypto/engine/build.info", "crypto/buffer/build.info", "crypto/bio/build.info", "crypto/stack/build.info", "crypto/lhash/build.info", "crypto/rand/build.info", "crypto/err/build.info", "crypto/evp/build.info", "crypto/asn1/build.info", "crypto/pem/build.info", "crypto/x509/build.info", "crypto/x509v3/build.info", "crypto/conf/build.info", "crypto/txt_db/build.info", "crypto/pkcs7/build.info", "crypto/pkcs12/build.info", "crypto/comp/build.info", "crypto/ocsp/build.info", "crypto/cms/build.info", "crypto/ts/build.info", "crypto/srp/build.info", "crypto/cmac/build.info", "crypto/ct/build.info", "crypto/async/build.info", "crypto/kdf/build.info" ],
+  build_type => "release",
+  builddir => ".",
+  cc => "gcc",
+  cflags => " -nostdinc -I../musl-1.1.18/include -I../zlib-1.2.11 -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing",
+  conf_files => [ "Configurations/00-base-templates.conf", "Configurations/10-main.conf" ],
+  cross_compile_prefix => "arm-none-eabi-",
+  defines => [ "NDEBUG", "OPENSSL_NO_DYNAMIC_ENGINE", "SSIZE_MAX=LONG_MAX", "__unix" ],
+  dirs => [ "crypto", "ssl", "engines", "apps", "test", "util", "tools", "fuzz" ],
+  dynamic_engines => "0",
+  engdirs => [  ],
+  ex_libs => "-static -L../musl-1.1.18/lib -L../zlib-1.2.11 ",
+  export_var_as_fn => "0",
+  fips => "0",
+  fipslibdir => "/usr/local/ssl/fips-2.0/lib/",
+  hashbangperl => "/usr/bin/env perl",
+  libdir => "",
+  major => "1",
+  makedepprog => "arm-none-eabi-gcc",
+  minor => "1.0",
+  openssl_algorithm_defines => [ "OPENSSL_NO_MD2", "OPENSSL_NO_RC5", "OPENSSL_NO_UI" ],
+  openssl_api_defines => [  ],
+  openssl_other_defines => [ "OPENSSL_NO_ASAN", "OPENSSL_NO_ASM", "OPENSSL_NO_CRYPTO_MDEBUG", "OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE", "OPENSSL_NO_EC_NISTP_64_GCC_128", "OPENSSL_NO_EGD", "OPENSSL_NO_FUZZ_AFL", "OPENSSL_NO_FUZZ_LIBFUZZER", "OPENSSL_NO_HEARTBEATS", "OPENSSL_NO_MSAN", "OPENSSL_NO_SCTP", "OPENSSL_NO_SSL_TRACE", "OPENSSL_NO_SSL3", "OPENSSL_NO_SSL3_METHOD", "OPENSSL_NO_UBSAN", "OPENSSL_NO_UNIT_TEST", "OPENSSL_NO_AFALGENG" ],
+  openssl_sys_defines => [  ],
+  openssl_thread_defines => [  ],
+  openssldir => "",
+  options => "--cross-compile-prefix=arm-none-eabi- enable-zlib enable-weak-ssl-ciphers -static -nostdinc -I../musl-1.1.18/include -I../zlib-1.2.11 -L../musl-1.1.18/lib -L../zlib-1.2.11 -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing -DSSIZE_MAX=LONG_MAX -D__unix no-asan no-asm no-crypto-mdebug no-crypto-mdebug-backtrace no-dso no-dynamic-engine no-ec_nistp_64_gcc_128 no-egd no-fuzz-afl no-fuzz-libfuzzer no-heartbeats no-md2 no-msan no-pic no-rc5 no-sctp no-shared no-ssl-trace no-ssl3 no-ssl3-method no-threads no-ubsan no-ui no-unit-test no-zlib-dynamic",
+  perl => "/usr/bin/perl",
+  perlargv => [ "--cross-compile-prefix=arm-none-eabi-", "no-threads", "zlib", "no-shared", "no-dso", "no-asm", "no-ui", "no-pic", "enable-weak-ssl-ciphers", "-static", "linux-armv4", "-nostdinc", "-I../musl-1.1.18/include", "-I../zlib-1.2.11", "-L../musl-1.1.18/lib", "-L../zlib-1.2.11", "-mlittle-endian", "-mcpu=cortex-a9", "-mthumb", "-mthumb-interwork", "-marm", "-march=armv7-a", "-mfpu=vfpv3", "-mfloat-abi=hard", "-mno-unaligned-access", "-fno-strict-aliasing", "-DSSIZE_MAX=LONG_MAX", "-D__unix" ],
+  prefix => "",
+  processor => "",
+  rc4_int => "unsigned char",
+  sdirs => [ "objects", "md4", "md5", "sha", "mdc2", "hmac", "ripemd", "whrlpool", "poly1305", "blake2", "des", "aes", "rc2", "rc4", "idea", "bf", "cast", "camellia", "seed", "chacha", "modes", "bn", "ec", "rsa", "dsa", "dh", "dso", "engine", "buffer", "bio", "stack", "lhash", "rand", "err", "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "cms", "ts", "srp", "cmac", "ct", "async", "kdf" ],
+  shared_ldflag => "",
+  shlib_major => "1",
+  shlib_minor => "1",
+  shlib_version_history => "",
+  shlib_version_number => "1.1",
+  sourcedir => ".",
+  target => "linux-armv4",
+  version => "1.1.0e",
+  version_num => "0x1010005fL",
+);
+
+our %target = (
+  _conf_fname_int => [ "Configurations/00-base-templates.conf", "Configurations/00-base-templates.conf", "Configurations/10-main.conf", "Configurations/10-main.conf" ],
+  aes_asm_src => "aes_core.c aes_cbc.c",
+  aes_obj => "aes_core.o aes_cbc.o",
+  apps_aux_src => "",
+  apps_obj => "",
+  ar => "ar",
+  bf_asm_src => "bf_enc.c",
+  bf_obj => "bf_enc.o",
+  bn_asm_src => "bn_asm.c",
+  bn_obj => "bn_asm.o",
+  bn_ops => "BN_LLONG RC4_CHAR",
+  build_file => "Makefile",
+  build_scheme => [ "unified", "unix" ],
+  cast_asm_src => "c_enc.c",
+  cast_obj => "c_enc.o",
+  cc => "gcc",
+  cflags => "-Wall -O3",
+  chacha_asm_src => "chacha_enc.c",
+  chacha_obj => "chacha_enc.o",
+  cmll_asm_src => "camellia.c cmll_misc.c cmll_cbc.c",
+  cmll_obj => "camellia.o cmll_misc.o cmll_cbc.o",
+  cpuid_asm_src => "mem_clr.c",
+  cpuid_obj => "mem_clr.o",
+  defines => [ "ZLIB" ],
+  des_asm_src => "des_enc.c fcrypt_b.c",
+  des_obj => "des_enc.o fcrypt_b.o",
+  dso_extension => ".so",
+  dso_scheme => "dlfcn",
+  ec_asm_src => "",
+  ec_obj => "",
+  ex_libs => "-lz -ldl",
+  exe_extension => "",
+  md5_asm_src => "",
+  md5_obj => "",
+  modes_asm_src => "",
+  modes_obj => "",
+  nm => "nm",
+  padlock_asm_src => "",
+  padlock_obj => "",
+  perlasm_scheme => "linux32",
+  poly1305_asm_src => "",
+  poly1305_obj => "",
+  ranlib => "\$(CROSS_COMPILE)ranlib",
+  rc => "windres",
+  rc4_asm_src => "rc4_enc.c rc4_skey.c",
+  rc4_obj => "rc4_enc.o rc4_skey.o",
+  rc5_asm_src => "rc5_enc.c",
+  rc5_obj => "rc5_enc.o",
+  rmd160_asm_src => "",
+  rmd160_obj => "",
+  shared_cflag => "",
+  shared_defines => [  ],
+  shared_extension => ".so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+  shared_extension_simple => ".so",
+  shared_ldflag => "",
+  shared_rcflag => "",
+  shared_target => "linux-shared",
+  template => "1",
+  thread_defines => [  ],
+  thread_scheme => "pthreads",
+  unistd => "<unistd.h>",
+  uplink_aux_src => "",
+  uplink_obj => "",
+  wp_asm_src => "wp_block.c",
+  wp_obj => "wp_block.o",
+);
+
+our %available_protocols = (
+  tls => [ "ssl3", "tls1", "tls1_1", "tls1_2" ],
+  dtls => [ "dtls1", "dtls1_2" ],
+);
+
+our @disablables = (
+  "afalgeng",
+  "asan",
+  "asm",
+  "async",
+  "autoalginit",
+  "autoerrinit",
+  "bf",
+  "blake2",
+  "camellia",
+  "capieng",
+  "cast",
+  "chacha",
+  "cmac",
+  "cms",
+  "comp",
+  "crypto-mdebug",
+  "crypto-mdebug-backtrace",
+  "ct",
+  "deprecated",
+  "des",
+  "dgram",
+  "dh",
+  "dsa",
+  "dso",
+  "dtls",
+  "dynamic-engine",
+  "ec",
+  "ec2m",
+  "ecdh",
+  "ecdsa",
+  "ec_nistp_64_gcc_128",
+  "egd",
+  "engine",
+  "err",
+  "filenames",
+  "fuzz-libfuzzer",
+  "fuzz-afl",
+  "gost",
+  "heartbeats",
+  "hw(-.+)?",
+  "idea",
+  "makedepend",
+  "md2",
+  "md4",
+  "mdc2",
+  "msan",
+  "multiblock",
+  "nextprotoneg",
+  "ocb",
+  "ocsp",
+  "pic",
+  "poly1305",
+  "posix-io",
+  "psk",
+  "rc2",
+  "rc4",
+  "rc5",
+  "rdrand",
+  "rfc3779",
+  "rmd160",
+  "scrypt",
+  "sctp",
+  "seed",
+  "shared",
+  "sock",
+  "srp",
+  "srtp",
+  "sse2",
+  "ssl",
+  "ssl-trace",
+  "static-engine",
+  "stdio",
+  "threads",
+  "tls",
+  "ts",
+  "ubsan",
+  "ui",
+  "unit-test",
+  "whirlpool",
+  "weak-ssl-ciphers",
+  "zlib",
+  "zlib-dynamic",
+  "ssl3",
+  "ssl3-method",
+  "tls1",
+  "tls1-method",
+  "tls1_1",
+  "tls1_1-method",
+  "tls1_2",
+  "tls1_2-method",
+  "dtls1",
+  "dtls1-method",
+  "dtls1_2",
+  "dtls1_2-method",
+);
+
+our %disabled = (
+  "afalgeng" => "cross-compiling",
+  "asan" => "default",
+  "asm" => "option",
+  "crypto-mdebug" => "default",
+  "crypto-mdebug-backtrace" => "default",
+  "dso" => "forced",
+  "dynamic-engine" => "forced",
+  "ec_nistp_64_gcc_128" => "default",
+  "egd" => "default",
+  "fuzz-afl" => "default",
+  "fuzz-libfuzzer" => "default",
+  "heartbeats" => "default",
+  "md2" => "default",
+  "msan" => "default",
+  "pic" => "forced",
+  "rc5" => "default",
+  "sctp" => "default",
+  "shared" => "forced",
+  "ssl-trace" => "default",
+  "ssl3" => "default",
+  "ssl3-method" => "default",
+  "threads" => "forced",
+  "ubsan" => "default",
+  "ui" => "option",
+  "unit-test" => "default",
+  "zlib-dynamic" => "default",
+);
+
+our %withargs = (
+);
+
+our %unified_info = (
+    "depends" =>
+        {
+            "" =>
+                [
+                    "crypto/include/internal/bn_conf.h",
+                    "crypto/include/internal/dso_conf.h",
+                    "include/openssl/opensslconf.h",
+                ],
+            "apps/openssl" =>
+                [
+                    "libssl",
+                ],
+            "crypto/aes/aes-586.s" =>
+                [
+                    "crypto/perlasm/x86asm.pl",
+                ],
+            "crypto/aes/aesni-586.s" =>
+                [
+                    "crypto/perlasm/x86asm.pl",
+                ],
+            "crypto/aes/aest4-sparcv9.S" =>
+                [
+                    "crypto/perlasm/sparcv9_modes.pl",
+                ],
+            "crypto/aes/vpaes-586.s" =>
+                [
+                    "crypto/perlasm/x86asm.pl",
+                ],
+            "crypto/bf/bf-586.s" =>
+                [
+                    "crypto/perlasm/cbc.pl",
+                    "crypto/perlasm/x86asm.pl",
+                ],
+            "crypto/bn/bn-586.s" =>
+                [
+                    "crypto/perlasm/x86asm.pl",
+                ],
+            "crypto/bn/co-586.s" =>
+                [
+                    "crypto/perlasm/x86asm.pl",
+                ],
+            "crypto/bn/x86-gf2m.s" =>
+                [
+                    "crypto/perlasm/x86asm.pl",
+                ],
+            "crypto/bn/x86-mont.s" =>
+                [
+                    "crypto/perlasm/x86asm.pl",
+                ],
+            "crypto/buildinf.h" =>
+                [
+                    "configdata.pm",
+                ],
+            "crypto/camellia/cmll-x86.s" =>
+                [
+                    "crypto/perlasm/x86asm.pl",
+                ],
+            "crypto/camellia/cmllt4-sparcv9.S" =>
+                [
+                    "crypto/perlasm/sparcv9_modes.pl",
+                ],
+            "crypto/cast/cast-586.s" =>
+                [
+                    "crypto/perlasm/cbc.pl",
+                    "crypto/perlasm/x86asm.pl",
+                ],
+            "crypto/cversion.o" =>
+                [
+                    "crypto/buildinf.h",
+                ],
+            "crypto/des/crypt586.s" =>
+                [
+                    "crypto/perlasm/cbc.pl",
+                    "crypto/perlasm/x86asm.pl",
+                ],
+            "crypto/des/des-586.s" =>
+                [
+                    "crypto/perlasm/cbc.pl",
+                    "crypto/perlasm/x86asm.pl",
+                ],
+            "crypto/include/internal/bn_conf.h" =>
+                [
+                    "configdata.pm",
+                ],
+            "crypto/include/internal/dso_conf.h" =>
+                [
+                    "configdata.pm",
+                ],
+            "crypto/rc4/rc4-586.s" =>
+                [
+                    "crypto/perlasm/x86asm.pl",
+                ],
+            "crypto/ripemd/rmd-586.s" =>
+                [
+                    "crypto/perlasm/x86asm.pl",
+                ],
+            "crypto/sha/sha1-586.s" =>
+                [
+                    "crypto/perlasm/x86asm.pl",
+                ],
+            "crypto/sha/sha256-586.s" =>
+                [
+                    "crypto/perlasm/x86asm.pl",
+                ],
+            "crypto/sha/sha512-586.s" =>
+                [
+                    "crypto/perlasm/x86asm.pl",
+                ],
+            "crypto/whrlpool/wp-mmx.s" =>
+                [
+                    "crypto/perlasm/x86asm.pl",
+                ],
+            "crypto/x86cpuid.s" =>
+                [
+                    "crypto/perlasm/x86asm.pl",
+                ],
+            "fuzz/asn1-test" =>
+                [
+                    "libcrypto",
+                ],
+            "fuzz/asn1parse-test" =>
+                [
+                    "libcrypto",
+                ],
+            "fuzz/bignum-test" =>
+                [
+                    "libcrypto",
+                ],
+            "fuzz/bndiv-test" =>
+                [
+                    "libcrypto",
+                ],
+            "fuzz/cms-test" =>
+                [
+                    "libcrypto",
+                ],
+            "fuzz/conf-test" =>
+                [
+                    "libcrypto",
+                ],
+            "fuzz/crl-test" =>
+                [
+                    "libcrypto",
+                ],
+            "fuzz/ct-test" =>
+                [
+                    "libcrypto",
+                ],
+            "fuzz/server-test" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "fuzz/x509-test" =>
+                [
+                    "libcrypto",
+                ],
+            "include/openssl/opensslconf.h" =>
+                [
+                    "configdata.pm",
+                ],
+            "libssl" =>
+                [
+                    "libcrypto",
+                ],
+            "test/aborttest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/afalgtest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/asynciotest" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/asynctest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/bad_dtls_test" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/bftest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/bio_enc_test" =>
+                [
+                    "libcrypto",
+                ],
+            "test/bioprinttest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/bntest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/buildtest_aes" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_asn1" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_asn1t" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_async" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_bio" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_blowfish" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_bn" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_buffer" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_camellia" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_cast" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_cmac" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_cms" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_comp" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_conf" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_conf_api" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_crypto" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_ct" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_des" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_dh" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_dsa" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_dtls1" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_e_os2" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_ebcdic" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_ec" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_ecdh" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_ecdsa" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_engine" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_err" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_evp" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_hmac" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_idea" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_kdf" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_lhash" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_md4" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_md5" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_mdc2" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_modes" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_obj_mac" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_objects" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_ocsp" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_opensslconf" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_opensslv" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_ossl_typ" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_pem" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_pem2" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_pkcs12" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_pkcs7" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_rand" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_rc2" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_rc4" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_ripemd" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_rsa" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_safestack" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_seed" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_sha" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_srp" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_srtp" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_ssl" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_ssl2" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_stack" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_symhacks" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_tls1" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_ts" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_txt_db" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_whrlpool" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_x509" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_x509_vfy" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/buildtest_x509v3" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/casttest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/cipherlist_test" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/clienthellotest" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/constant_time_test" =>
+                [
+                    "libcrypto",
+                ],
+            "test/crltest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/ct_test" =>
+                [
+                    "libcrypto",
+                ],
+            "test/d2i_test" =>
+                [
+                    "libcrypto",
+                ],
+            "test/danetest" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/destest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/dhtest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/dsatest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/dtlstest" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/dtlsv1listentest" =>
+                [
+                    "libssl",
+                ],
+            "test/ecdhtest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/ecdsatest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/ectest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/enginetest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/evp_extra_test" =>
+                [
+                    "libcrypto",
+                ],
+            "test/evp_test" =>
+                [
+                    "libcrypto",
+                ],
+            "test/exptest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/gmdifftest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/heartbeat_test" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/hmactest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/ideatest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/igetest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/md2test" =>
+                [
+                    "libcrypto",
+                ],
+            "test/md4test" =>
+                [
+                    "libcrypto",
+                ],
+            "test/md5test" =>
+                [
+                    "libcrypto",
+                ],
+            "test/mdc2test" =>
+                [
+                    "libcrypto",
+                ],
+            "test/memleaktest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/p5_crpt2_test" =>
+                [
+                    "libcrypto",
+                ],
+            "test/packettest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/pbelutest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/randtest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/rc2test" =>
+                [
+                    "libcrypto",
+                ],
+            "test/rc4test" =>
+                [
+                    "libcrypto",
+                ],
+            "test/rc5test" =>
+                [
+                    "libcrypto",
+                ],
+            "test/rmdtest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/rsa_test" =>
+                [
+                    "libcrypto",
+                ],
+            "test/sanitytest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/secmemtest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/sha1test" =>
+                [
+                    "libcrypto",
+                ],
+            "test/sha256t" =>
+                [
+                    "libcrypto",
+                ],
+            "test/sha512t" =>
+                [
+                    "libcrypto",
+                ],
+            "test/srptest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/ssl_test" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/ssl_test_ctx_test" =>
+                [
+                    "libcrypto",
+                ],
+            "test/sslapitest" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/sslcorrupttest" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/ssltest_old" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "test/threadstest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/v3ext" =>
+                [
+                    "libcrypto",
+                ],
+            "test/v3nametest" =>
+                [
+                    "libcrypto",
+                ],
+            "test/verify_extra_test" =>
+                [
+                    "libcrypto",
+                ],
+            "test/wp_test" =>
+                [
+                    "libcrypto",
+                ],
+            "test/x509aux" =>
+                [
+                    "libcrypto",
+                ],
+        },
+    "engines" =>
+        [
+        ],
+    "extra" =>
+        [
+            "crypto/alphacpuid.pl",
+            "crypto/arm64cpuid.pl",
+            "crypto/armv4cpuid.pl",
+            "crypto/ia64cpuid.S",
+            "crypto/pariscid.pl",
+            "crypto/ppccpuid.pl",
+            "crypto/x86_64cpuid.pl",
+            "crypto/x86cpuid.pl",
+            "ms/applink.c",
+            "ms/uplink-x86.pl",
+            "ms/uplink.c",
+        ],
+    "generate" =>
+        {
+            "crypto/aes/aes-586.s" =>
+                [
+                    "crypto/aes/asm/aes-586.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "crypto/aes/aes-armv4.S" =>
+                [
+                    "crypto/aes/asm/aes-armv4.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/aes/aes-ia64.s" =>
+                [
+                    "crypto/aes/asm/aes-ia64.S",
+                ],
+            "crypto/aes/aes-mips.S" =>
+                [
+                    "crypto/aes/asm/aes-mips.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/aes/aes-parisc.s" =>
+                [
+                    "crypto/aes/asm/aes-parisc.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/aes/aes-ppc.s" =>
+                [
+                    "crypto/aes/asm/aes-ppc.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/aes/aes-sparcv9.S" =>
+                [
+                    "crypto/aes/asm/aes-sparcv9.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/aes/aes-x86_64.s" =>
+                [
+                    "crypto/aes/asm/aes-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/aes/aesfx-sparcv9.S" =>
+                [
+                    "crypto/aes/asm/aesfx-sparcv9.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/aes/aesni-mb-x86_64.s" =>
+                [
+                    "crypto/aes/asm/aesni-mb-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/aes/aesni-sha1-x86_64.s" =>
+                [
+                    "crypto/aes/asm/aesni-sha1-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/aes/aesni-sha256-x86_64.s" =>
+                [
+                    "crypto/aes/asm/aesni-sha256-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/aes/aesni-x86.s" =>
+                [
+                    "crypto/aes/asm/aesni-x86.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "crypto/aes/aesni-x86_64.s" =>
+                [
+                    "crypto/aes/asm/aesni-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/aes/aesp8-ppc.s" =>
+                [
+                    "crypto/aes/asm/aesp8-ppc.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/aes/aest4-sparcv9.S" =>
+                [
+                    "crypto/aes/asm/aest4-sparcv9.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/aes/aesv8-armx.S" =>
+                [
+                    "crypto/aes/asm/aesv8-armx.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/aes/bsaes-armv7.S" =>
+                [
+                    "crypto/aes/asm/bsaes-armv7.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/aes/bsaes-x86_64.s" =>
+                [
+                    "crypto/aes/asm/bsaes-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/aes/vpaes-armv8.S" =>
+                [
+                    "crypto/aes/asm/vpaes-armv8.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/aes/vpaes-ppc.s" =>
+                [
+                    "crypto/aes/asm/vpaes-ppc.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/aes/vpaes-x86.s" =>
+                [
+                    "crypto/aes/asm/vpaes-x86.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "crypto/aes/vpaes-x86_64.s" =>
+                [
+                    "crypto/aes/asm/vpaes-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/alphacpuid.s" =>
+                [
+                    "crypto/alphacpuid.pl",
+                ],
+            "crypto/arm64cpuid.S" =>
+                [
+                    "crypto/arm64cpuid.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/armv4cpuid.S" =>
+                [
+                    "crypto/armv4cpuid.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bf/bf-586.s" =>
+                [
+                    "crypto/bf/asm/bf-586.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "crypto/bn/alpha-mont.S" =>
+                [
+                    "crypto/bn/asm/alpha-mont.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/armv4-gf2m.S" =>
+                [
+                    "crypto/bn/asm/armv4-gf2m.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/armv4-mont.S" =>
+                [
+                    "crypto/bn/asm/armv4-mont.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/armv8-mont.S" =>
+                [
+                    "crypto/bn/asm/armv8-mont.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/bn-586.s" =>
+                [
+                    "crypto/bn/asm/bn-586.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "crypto/bn/bn-ia64.s" =>
+                [
+                    "crypto/bn/asm/ia64.S",
+                ],
+            "crypto/bn/bn-mips.s" =>
+                [
+                    "crypto/bn/asm/mips.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/bn-ppc.s" =>
+                [
+                    "crypto/bn/asm/ppc.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/co-586.s" =>
+                [
+                    "crypto/bn/asm/co-586.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "crypto/bn/ia64-mont.s" =>
+                [
+                    "crypto/bn/asm/ia64-mont.pl",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                ],
+            "crypto/bn/mips-mont.s" =>
+                [
+                    "crypto/bn/asm/mips-mont.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/parisc-mont.s" =>
+                [
+                    "crypto/bn/asm/parisc-mont.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/ppc-mont.s" =>
+                [
+                    "crypto/bn/asm/ppc-mont.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/ppc64-mont.s" =>
+                [
+                    "crypto/bn/asm/ppc64-mont.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/rsaz-avx2.s" =>
+                [
+                    "crypto/bn/asm/rsaz-avx2.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/rsaz-x86_64.s" =>
+                [
+                    "crypto/bn/asm/rsaz-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/s390x-gf2m.s" =>
+                [
+                    "crypto/bn/asm/s390x-gf2m.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/s390x-mont.S" =>
+                [
+                    "crypto/bn/asm/s390x-mont.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/sparct4-mont.S" =>
+                [
+                    "crypto/bn/asm/sparct4-mont.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/sparcv9-gf2m.S" =>
+                [
+                    "crypto/bn/asm/sparcv9-gf2m.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/sparcv9-mont.S" =>
+                [
+                    "crypto/bn/asm/sparcv9-mont.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/sparcv9a-mont.S" =>
+                [
+                    "crypto/bn/asm/sparcv9a-mont.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/vis3-mont.S" =>
+                [
+                    "crypto/bn/asm/vis3-mont.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/x86-gf2m.s" =>
+                [
+                    "crypto/bn/asm/x86-gf2m.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "crypto/bn/x86-mont.s" =>
+                [
+                    "crypto/bn/asm/x86-mont.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "crypto/bn/x86_64-gf2m.s" =>
+                [
+                    "crypto/bn/asm/x86_64-gf2m.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/x86_64-mont.s" =>
+                [
+                    "crypto/bn/asm/x86_64-mont.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/bn/x86_64-mont5.s" =>
+                [
+                    "crypto/bn/asm/x86_64-mont5.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/buildinf.h" =>
+                [
+                    "util/mkbuildinf.pl",
+                    "\"\$(CC)",
+                    "\$(CFLAGS_Q)\"",
+                    "\"\$(PLATFORM)\"",
+                ],
+            "crypto/camellia/cmll-x86.s" =>
+                [
+                    "crypto/camellia/asm/cmll-x86.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "crypto/camellia/cmll-x86_64.s" =>
+                [
+                    "crypto/camellia/asm/cmll-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/camellia/cmllt4-sparcv9.S" =>
+                [
+                    "crypto/camellia/asm/cmllt4-sparcv9.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/cast/cast-586.s" =>
+                [
+                    "crypto/cast/asm/cast-586.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "crypto/chacha/chacha-armv4.S" =>
+                [
+                    "crypto/chacha/asm/chacha-armv4.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/chacha/chacha-armv8.S" =>
+                [
+                    "crypto/chacha/asm/chacha-armv8.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/chacha/chacha-ppc.s" =>
+                [
+                    "crypto/chacha/asm/chacha-ppc.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/chacha/chacha-x86.s" =>
+                [
+                    "crypto/chacha/asm/chacha-x86.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "crypto/chacha/chacha-x86_64.s" =>
+                [
+                    "crypto/chacha/asm/chacha-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/des/crypt586.s" =>
+                [
+                    "crypto/des/asm/crypt586.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                ],
+            "crypto/des/des-586.s" =>
+                [
+                    "crypto/des/asm/des-586.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                ],
+            "crypto/des/des_enc-sparc.S" =>
+                [
+                    "crypto/des/asm/des_enc.m4",
+                ],
+            "crypto/des/dest4-sparcv9.S" =>
+                [
+                    "crypto/des/asm/dest4-sparcv9.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/ec/ecp_nistz256-armv4.S" =>
+                [
+                    "crypto/ec/asm/ecp_nistz256-armv4.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/ec/ecp_nistz256-armv8.S" =>
+                [
+                    "crypto/ec/asm/ecp_nistz256-armv8.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/ec/ecp_nistz256-avx2.s" =>
+                [
+                    "crypto/ec/asm/ecp_nistz256-avx2.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/ec/ecp_nistz256-sparcv9.S" =>
+                [
+                    "crypto/ec/asm/ecp_nistz256-sparcv9.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/ec/ecp_nistz256-x86.s" =>
+                [
+                    "crypto/ec/asm/ecp_nistz256-x86.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "crypto/ec/ecp_nistz256-x86_64.s" =>
+                [
+                    "crypto/ec/asm/ecp_nistz256-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/ia64cpuid.s" =>
+                [
+                    "crypto/ia64cpuid.S",
+                ],
+            "crypto/include/internal/bn_conf.h" =>
+                [
+                    "crypto/include/internal/bn_conf.h.in",
+                ],
+            "crypto/include/internal/dso_conf.h" =>
+                [
+                    "crypto/include/internal/dso_conf.h.in",
+                ],
+            "crypto/md5/md5-586.s" =>
+                [
+                    "crypto/md5/asm/md5-586.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                ],
+            "crypto/md5/md5-sparcv9.S" =>
+                [
+                    "crypto/md5/asm/md5-sparcv9.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/md5/md5-x86_64.s" =>
+                [
+                    "crypto/md5/asm/md5-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/modes/aesni-gcm-x86_64.s" =>
+                [
+                    "crypto/modes/asm/aesni-gcm-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/modes/ghash-alpha.S" =>
+                [
+                    "crypto/modes/asm/ghash-alpha.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/modes/ghash-armv4.S" =>
+                [
+                    "crypto/modes/asm/ghash-armv4.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/modes/ghash-ia64.s" =>
+                [
+                    "crypto/modes/asm/ghash-ia64.pl",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                ],
+            "crypto/modes/ghash-parisc.s" =>
+                [
+                    "crypto/modes/asm/ghash-parisc.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/modes/ghash-sparcv9.S" =>
+                [
+                    "crypto/modes/asm/ghash-sparcv9.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/modes/ghash-x86.s" =>
+                [
+                    "crypto/modes/asm/ghash-x86.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "crypto/modes/ghash-x86_64.s" =>
+                [
+                    "crypto/modes/asm/ghash-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/modes/ghashp8-ppc.s" =>
+                [
+                    "crypto/modes/asm/ghashp8-ppc.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/modes/ghashv8-armx.S" =>
+                [
+                    "crypto/modes/asm/ghashv8-armx.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/pariscid.s" =>
+                [
+                    "crypto/pariscid.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/poly1305/poly1305-armv4.S" =>
+                [
+                    "crypto/poly1305/asm/poly1305-armv4.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/poly1305/poly1305-armv8.S" =>
+                [
+                    "crypto/poly1305/asm/poly1305-armv8.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/poly1305/poly1305-mips.S" =>
+                [
+                    "crypto/poly1305/asm/poly1305-mips.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/poly1305/poly1305-ppc.s" =>
+                [
+                    "crypto/poly1305/asm/poly1305-ppc.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/poly1305/poly1305-ppcfp.s" =>
+                [
+                    "crypto/poly1305/asm/poly1305-ppcfp.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/poly1305/poly1305-sparcv9.S" =>
+                [
+                    "crypto/poly1305/asm/poly1305-sparcv9.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/poly1305/poly1305-x86.s" =>
+                [
+                    "crypto/poly1305/asm/poly1305-x86.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "crypto/poly1305/poly1305-x86_64.s" =>
+                [
+                    "crypto/poly1305/asm/poly1305-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/ppccpuid.s" =>
+                [
+                    "crypto/ppccpuid.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/rc4/rc4-586.s" =>
+                [
+                    "crypto/rc4/asm/rc4-586.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "crypto/rc4/rc4-md5-x86_64.s" =>
+                [
+                    "crypto/rc4/asm/rc4-md5-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/rc4/rc4-parisc.s" =>
+                [
+                    "crypto/rc4/asm/rc4-parisc.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/rc4/rc4-x86_64.s" =>
+                [
+                    "crypto/rc4/asm/rc4-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/ripemd/rmd-586.s" =>
+                [
+                    "crypto/ripemd/asm/rmd-586.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                ],
+            "crypto/sha/sha1-586.s" =>
+                [
+                    "crypto/sha/asm/sha1-586.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "crypto/sha/sha1-alpha.S" =>
+                [
+                    "crypto/sha/asm/sha1-alpha.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha1-armv4-large.S" =>
+                [
+                    "crypto/sha/asm/sha1-armv4-large.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha1-armv8.S" =>
+                [
+                    "crypto/sha/asm/sha1-armv8.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha1-ia64.s" =>
+                [
+                    "crypto/sha/asm/sha1-ia64.pl",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                ],
+            "crypto/sha/sha1-mb-x86_64.s" =>
+                [
+                    "crypto/sha/asm/sha1-mb-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha1-mips.S" =>
+                [
+                    "crypto/sha/asm/sha1-mips.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha1-parisc.s" =>
+                [
+                    "crypto/sha/asm/sha1-parisc.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha1-ppc.s" =>
+                [
+                    "crypto/sha/asm/sha1-ppc.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha1-sparcv9.S" =>
+                [
+                    "crypto/sha/asm/sha1-sparcv9.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha1-x86_64.s" =>
+                [
+                    "crypto/sha/asm/sha1-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha256-586.s" =>
+                [
+                    "crypto/sha/asm/sha256-586.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "crypto/sha/sha256-armv4.S" =>
+                [
+                    "crypto/sha/asm/sha256-armv4.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha256-armv8.S" =>
+                [
+                    "crypto/sha/asm/sha512-armv8.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha256-ia64.s" =>
+                [
+                    "crypto/sha/asm/sha512-ia64.pl",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                ],
+            "crypto/sha/sha256-mb-x86_64.s" =>
+                [
+                    "crypto/sha/asm/sha256-mb-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha256-mips.S" =>
+                [
+                    "crypto/sha/asm/sha512-mips.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha256-parisc.s" =>
+                [
+                    "crypto/sha/asm/sha512-parisc.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha256-ppc.s" =>
+                [
+                    "crypto/sha/asm/sha512-ppc.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha256-sparcv9.S" =>
+                [
+                    "crypto/sha/asm/sha512-sparcv9.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha256-x86_64.s" =>
+                [
+                    "crypto/sha/asm/sha512-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha256p8-ppc.s" =>
+                [
+                    "crypto/sha/asm/sha512p8-ppc.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha512-586.s" =>
+                [
+                    "crypto/sha/asm/sha512-586.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "crypto/sha/sha512-armv4.S" =>
+                [
+                    "crypto/sha/asm/sha512-armv4.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha512-armv8.S" =>
+                [
+                    "crypto/sha/asm/sha512-armv8.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha512-ia64.s" =>
+                [
+                    "crypto/sha/asm/sha512-ia64.pl",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                ],
+            "crypto/sha/sha512-mips.S" =>
+                [
+                    "crypto/sha/asm/sha512-mips.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha512-parisc.s" =>
+                [
+                    "crypto/sha/asm/sha512-parisc.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha512-ppc.s" =>
+                [
+                    "crypto/sha/asm/sha512-ppc.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha512-sparcv9.S" =>
+                [
+                    "crypto/sha/asm/sha512-sparcv9.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha512-x86_64.s" =>
+                [
+                    "crypto/sha/asm/sha512-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/sha/sha512p8-ppc.s" =>
+                [
+                    "crypto/sha/asm/sha512p8-ppc.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/uplink-ia64.s" =>
+                [
+                    "ms/uplink-ia64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/uplink-x86.s" =>
+                [
+                    "ms/uplink-x86.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/uplink-x86_64.s" =>
+                [
+                    "ms/uplink-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/whrlpool/wp-mmx.s" =>
+                [
+                    "crypto/whrlpool/asm/wp-mmx.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "crypto/whrlpool/wp-x86_64.s" =>
+                [
+                    "crypto/whrlpool/asm/wp-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/x86_64cpuid.s" =>
+                [
+                    "crypto/x86_64cpuid.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "crypto/x86cpuid.s" =>
+                [
+                    "crypto/x86cpuid.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "engines/e_padlock-x86.s" =>
+                [
+                    "engines/asm/e_padlock-x86.pl",
+                    "\$(PERLASM_SCHEME)",
+                    "\$(CFLAGS)",
+                    "\$(LIB_CFLAGS)",
+                    "\$(PROCESSOR)",
+                ],
+            "engines/e_padlock-x86_64.s" =>
+                [
+                    "engines/asm/e_padlock-x86_64.pl",
+                    "\$(PERLASM_SCHEME)",
+                ],
+            "include/openssl/opensslconf.h" =>
+                [
+                    "include/openssl/opensslconf.h.in",
+                ],
+            "test/buildtest_aes.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "aes",
+                ],
+            "test/buildtest_asn1.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "asn1",
+                ],
+            "test/buildtest_asn1t.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "asn1t",
+                ],
+            "test/buildtest_async.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "async",
+                ],
+            "test/buildtest_bio.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "bio",
+                ],
+            "test/buildtest_blowfish.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "blowfish",
+                ],
+            "test/buildtest_bn.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "bn",
+                ],
+            "test/buildtest_buffer.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "buffer",
+                ],
+            "test/buildtest_camellia.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "camellia",
+                ],
+            "test/buildtest_cast.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "cast",
+                ],
+            "test/buildtest_cmac.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "cmac",
+                ],
+            "test/buildtest_cms.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "cms",
+                ],
+            "test/buildtest_comp.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "comp",
+                ],
+            "test/buildtest_conf.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "conf",
+                ],
+            "test/buildtest_conf_api.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "conf_api",
+                ],
+            "test/buildtest_crypto.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "crypto",
+                ],
+            "test/buildtest_ct.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "ct",
+                ],
+            "test/buildtest_des.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "des",
+                ],
+            "test/buildtest_dh.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "dh",
+                ],
+            "test/buildtest_dsa.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "dsa",
+                ],
+            "test/buildtest_dtls1.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "dtls1",
+                ],
+            "test/buildtest_e_os2.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "e_os2",
+                ],
+            "test/buildtest_ebcdic.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "ebcdic",
+                ],
+            "test/buildtest_ec.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "ec",
+                ],
+            "test/buildtest_ecdh.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "ecdh",
+                ],
+            "test/buildtest_ecdsa.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "ecdsa",
+                ],
+            "test/buildtest_engine.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "engine",
+                ],
+            "test/buildtest_err.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "err",
+                ],
+            "test/buildtest_evp.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "evp",
+                ],
+            "test/buildtest_hmac.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "hmac",
+                ],
+            "test/buildtest_idea.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "idea",
+                ],
+            "test/buildtest_kdf.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "kdf",
+                ],
+            "test/buildtest_lhash.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "lhash",
+                ],
+            "test/buildtest_md4.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "md4",
+                ],
+            "test/buildtest_md5.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "md5",
+                ],
+            "test/buildtest_mdc2.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "mdc2",
+                ],
+            "test/buildtest_modes.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "modes",
+                ],
+            "test/buildtest_obj_mac.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "obj_mac",
+                ],
+            "test/buildtest_objects.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "objects",
+                ],
+            "test/buildtest_ocsp.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "ocsp",
+                ],
+            "test/buildtest_opensslconf.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "opensslconf",
+                ],
+            "test/buildtest_opensslv.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "opensslv",
+                ],
+            "test/buildtest_ossl_typ.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "ossl_typ",
+                ],
+            "test/buildtest_pem.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "pem",
+                ],
+            "test/buildtest_pem2.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "pem2",
+                ],
+            "test/buildtest_pkcs12.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "pkcs12",
+                ],
+            "test/buildtest_pkcs7.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "pkcs7",
+                ],
+            "test/buildtest_rand.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "rand",
+                ],
+            "test/buildtest_rc2.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "rc2",
+                ],
+            "test/buildtest_rc4.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "rc4",
+                ],
+            "test/buildtest_ripemd.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "ripemd",
+                ],
+            "test/buildtest_rsa.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "rsa",
+                ],
+            "test/buildtest_safestack.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "safestack",
+                ],
+            "test/buildtest_seed.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "seed",
+                ],
+            "test/buildtest_sha.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "sha",
+                ],
+            "test/buildtest_srp.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "srp",
+                ],
+            "test/buildtest_srtp.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "srtp",
+                ],
+            "test/buildtest_ssl.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "ssl",
+                ],
+            "test/buildtest_ssl2.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "ssl2",
+                ],
+            "test/buildtest_stack.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "stack",
+                ],
+            "test/buildtest_symhacks.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "symhacks",
+                ],
+            "test/buildtest_tls1.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "tls1",
+                ],
+            "test/buildtest_ts.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "ts",
+                ],
+            "test/buildtest_txt_db.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "txt_db",
+                ],
+            "test/buildtest_whrlpool.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "whrlpool",
+                ],
+            "test/buildtest_x509.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "x509",
+                ],
+            "test/buildtest_x509_vfy.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "x509_vfy",
+                ],
+            "test/buildtest_x509v3.c" =>
+                [
+                    "test/generate_buildtest.pl",
+                    "x509v3",
+                ],
+        },
+    "includes" =>
+        {
+            "apps/openssl" =>
+                [
+                    ".",
+                    "include",
+                ],
+            "crypto/aes/aes-armv4.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/aes/aes-sparcv9.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/aes/aesfx-sparcv9.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/aes/aest4-sparcv9.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/aes/aesv8-armx.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/aes/bsaes-armv7.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/arm64cpuid.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/armv4cpuid.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/bn/armv4-gf2m.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/bn/armv4-mont.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/bn/bn_exp.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/bn/sparct4-mont.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/bn/sparcv9-gf2m.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/bn/sparcv9-mont.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/bn/sparcv9a-mont.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/bn/vis3-mont.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/buildinf.h" =>
+                [
+                    ".",
+                ],
+            "crypto/camellia/cmllt4-sparcv9.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/chacha/chacha-armv4.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/chacha/chacha-armv8.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/cversion.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/des/dest4-sparcv9.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/ec/ecp_nistz256-armv4.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/ec/ecp_nistz256-armv8.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/ec/ecp_nistz256-sparcv9.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/evp/e_aes.o" =>
+                [
+                    "crypto",
+                    "crypto/modes",
+                ],
+            "crypto/evp/e_aes_cbc_hmac_sha1.o" =>
+                [
+                    "crypto/modes",
+                ],
+            "crypto/evp/e_aes_cbc_hmac_sha256.o" =>
+                [
+                    "crypto/modes",
+                ],
+            "crypto/evp/e_camellia.o" =>
+                [
+                    "crypto",
+                    "crypto/modes",
+                ],
+            "crypto/evp/e_des.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/evp/e_des3.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/include/internal/bn_conf.h" =>
+                [
+                    ".",
+                ],
+            "crypto/include/internal/dso_conf.h" =>
+                [
+                    ".",
+                ],
+            "crypto/md5/md5-sparcv9.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/modes/gcm128.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/modes/ghash-armv4.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/modes/ghash-sparcv9.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/modes/ghashv8-armx.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/poly1305/poly1305-armv4.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/poly1305/poly1305-armv8.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/poly1305/poly1305-sparcv9.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/sha/sha1-armv4-large.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/sha/sha1-armv8.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/sha/sha1-sparcv9.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/sha/sha256-armv4.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/sha/sha256-armv8.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/sha/sha256-sparcv9.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/sha/sha512-armv4.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/sha/sha512-armv8.o" =>
+                [
+                    "crypto",
+                ],
+            "crypto/sha/sha512-sparcv9.o" =>
+                [
+                    "crypto",
+                ],
+            "fuzz/asn1-test" =>
+                [
+                    "include",
+                ],
+            "fuzz/asn1parse-test" =>
+                [
+                    "include",
+                ],
+            "fuzz/bignum-test" =>
+                [
+                    "include",
+                ],
+            "fuzz/bndiv-test" =>
+                [
+                    "include",
+                ],
+            "fuzz/cms-test" =>
+                [
+                    "include",
+                ],
+            "fuzz/conf-test" =>
+                [
+                    "include",
+                ],
+            "fuzz/crl-test" =>
+                [
+                    "include",
+                ],
+            "fuzz/ct-test" =>
+                [
+                    "include",
+                ],
+            "fuzz/server-test" =>
+                [
+                    "include",
+                ],
+            "fuzz/x509-test" =>
+                [
+                    "include",
+                ],
+            "include/openssl/opensslconf.h" =>
+                [
+                    ".",
+                ],
+            "libcrypto" =>
+                [
+                    ".",
+                    "crypto/include",
+                    "include",
+                ],
+            "libssl" =>
+                [
+                    ".",
+                    "include",
+                ],
+            "test/aborttest" =>
+                [
+                    "include",
+                ],
+            "test/afalgtest" =>
+                [
+                    ".",
+                    "include",
+                ],
+            "test/asynciotest" =>
+                [
+                    "include",
+                ],
+            "test/asynctest" =>
+                [
+                    ".",
+                    "include",
+                ],
+            "test/bad_dtls_test" =>
+                [
+                    "include",
+                ],
+            "test/bftest" =>
+                [
+                    "include",
+                ],
+            "test/bio_enc_test" =>
+                [
+                    "include",
+                ],
+            "test/bioprinttest" =>
+                [
+                    "include",
+                ],
+            "test/bntest" =>
+                [
+                    ".",
+                    "crypto/include",
+                    "include",
+                ],
+            "test/buildtest_aes" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_asn1" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_asn1t" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_async" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_bio" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_blowfish" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_bn" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_buffer" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_camellia" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_cast" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_cmac" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_cms" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_comp" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_conf" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_conf_api" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_crypto" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_ct" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_des" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_dh" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_dsa" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_dtls1" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_e_os2" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_ebcdic" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_ec" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_ecdh" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_ecdsa" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_engine" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_err" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_evp" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_hmac" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_idea" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_kdf" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_lhash" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_md4" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_md5" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_mdc2" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_modes" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_obj_mac" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_objects" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_ocsp" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_opensslconf" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_opensslv" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_ossl_typ" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_pem" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_pem2" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_pkcs12" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_pkcs7" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_rand" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_rc2" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_rc4" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_ripemd" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_rsa" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_safestack" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_seed" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_sha" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_srp" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_srtp" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_ssl" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_ssl2" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_stack" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_symhacks" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_tls1" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_ts" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_txt_db" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_whrlpool" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_x509" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_x509_vfy" =>
+                [
+                    "include",
+                ],
+            "test/buildtest_x509v3" =>
+                [
+                    "include",
+                ],
+            "test/casttest" =>
+                [
+                    "include",
+                ],
+            "test/cipherlist_test" =>
+                [
+                    ".",
+                    "include",
+                ],
+            "test/clienthellotest" =>
+                [
+                    "include",
+                ],
+            "test/constant_time_test" =>
+                [
+                    ".",
+                    "include",
+                ],
+            "test/crltest" =>
+                [
+                    "include",
+                ],
+            "test/ct_test" =>
+                [
+                    "crypto/include",
+                    "include",
+                ],
+            "test/d2i_test" =>
+                [
+                    ".",
+                    "include",
+                ],
+            "test/danetest" =>
+                [
+                    "include",
+                ],
+            "test/destest" =>
+                [
+                    "include",
+                ],
+            "test/dhtest" =>
+                [
+                    "include",
+                ],
+            "test/dsatest" =>
+                [
+                    "include",
+                ],
+            "test/dtlstest" =>
+                [
+                    "include",
+                    "test",
+                ],
+            "test/dtlsv1listentest" =>
+                [
+                    ".",
+                    "include",
+                ],
+            "test/ecdhtest" =>
+                [
+                    "include",
+                ],
+            "test/ecdsatest" =>
+                [
+                    "include",
+                ],
+            "test/ectest" =>
+                [
+                    "include",
+                ],
+            "test/enginetest" =>
+                [
+                    "include",
+                ],
+            "test/evp_extra_test" =>
+                [
+                    "include",
+                ],
+            "test/evp_test" =>
+                [
+                    "include",
+                ],
+            "test/exptest" =>
+                [
+                    "include",
+                ],
+            "test/gmdifftest" =>
+                [
+                    "include",
+                ],
+            "test/handshake_helper.o" =>
+                [
+                    "include",
+                ],
+            "test/heartbeat_test" =>
+                [
+                    ".",
+                    "include",
+                ],
+            "test/hmactest" =>
+                [
+                    "include",
+                ],
+            "test/ideatest" =>
+                [
+                    "include",
+                ],
+            "test/igetest" =>
+                [
+                    ".",
+                    "include",
+                ],
+            "test/md2test" =>
+                [
+                    "include",
+                ],
+            "test/md4test" =>
+                [
+                    "include",
+                ],
+            "test/md5test" =>
+                [
+                    "include",
+                ],
+            "test/mdc2test" =>
+                [
+                    "include",
+                ],
+            "test/memleaktest" =>
+                [
+                    "include",
+                ],
+            "test/p5_crpt2_test" =>
+                [
+                    "include",
+                ],
+            "test/packettest" =>
+                [
+                    "include",
+                ],
+            "test/pbelutest" =>
+                [
+                    "include",
+                ],
+            "test/randtest" =>
+                [
+                    "include",
+                ],
+            "test/rc2test" =>
+                [
+                    "include",
+                ],
+            "test/rc4test" =>
+                [
+                    "include",
+                ],
+            "test/rc5test" =>
+                [
+                    "include",
+                ],
+            "test/rmdtest" =>
+                [
+                    "include",
+                ],
+            "test/rsa_test" =>
+                [
+                    ".",
+                    "include",
+                ],
+            "test/sanitytest" =>
+                [
+                    "include",
+                ],
+            "test/secmemtest" =>
+                [
+                    "include",
+                ],
+            "test/sha1test" =>
+                [
+                    "include",
+                ],
+            "test/sha256t" =>
+                [
+                    "include",
+                ],
+            "test/sha512t" =>
+                [
+                    "include",
+                ],
+            "test/srptest" =>
+                [
+                    "include",
+                ],
+            "test/ssl_test" =>
+                [
+                    ".",
+                    "include",
+                ],
+            "test/ssl_test_ctx.o" =>
+                [
+                    "include",
+                ],
+            "test/ssl_test_ctx_test" =>
+                [
+                    ".",
+                    "include",
+                ],
+            "test/sslapitest" =>
+                [
+                    "include",
+                    ".",
+                ],
+            "test/sslcorrupttest" =>
+                [
+                    "include",
+                    "test",
+                ],
+            "test/ssltest_old" =>
+                [
+                    ".",
+                    "include",
+                ],
+            "test/ssltestlib.o" =>
+                [
+                    "include",
+                ],
+            "test/testutil.o" =>
+                [
+                    ".",
+                ],
+            "test/threadstest" =>
+                [
+                    ".",
+                    "include",
+                ],
+            "test/v3ext" =>
+                [
+                    "include",
+                ],
+            "test/v3nametest" =>
+                [
+                    "include",
+                ],
+            "test/verify_extra_test" =>
+                [
+                    "include",
+                ],
+            "test/wp_test" =>
+                [
+                    "include",
+                ],
+            "test/x509aux" =>
+                [
+                    "include",
+                ],
+        },
+    "install" =>
+        {
+            "libraries" =>
+                [
+                    "libcrypto",
+                    "libssl",
+                ],
+            "programs" =>
+                [
+                    "apps/openssl",
+                ],
+            "scripts" =>
+                [
+                    "apps/CA.pl",
+                    "apps/tsget",
+                    "tools/c_rehash",
+                ],
+        },
+    "ldadd" =>
+        {
+        },
+    "libraries" =>
+        [
+            "libcrypto",
+            "libssl",
+        ],
+    "ordinals" =>
+        {
+            "libcrypto" =>
+                [
+                    "crypto",
+                    "util/libcrypto.num",
+                ],
+            "libssl" =>
+                [
+                    "ssl",
+                    "util/libssl.num",
+                ],
+        },
+    "overrides" =>
+        [
+            "crypto/bn/bn-mips3.o",
+            "crypto/bn/pa-risc2.c",
+            "crypto/bn/pa-risc2W.o",
+        ],
+    "programs" =>
+        [
+            "apps/openssl",
+            "fuzz/asn1-test",
+            "fuzz/asn1parse-test",
+            "fuzz/bignum-test",
+            "fuzz/bndiv-test",
+            "fuzz/cms-test",
+            "fuzz/conf-test",
+            "fuzz/crl-test",
+            "fuzz/ct-test",
+            "fuzz/server-test",
+            "fuzz/x509-test",
+            "test/aborttest",
+            "test/afalgtest",
+            "test/asynciotest",
+            "test/asynctest",
+            "test/bad_dtls_test",
+            "test/bftest",
+            "test/bio_enc_test",
+            "test/bioprinttest",
+            "test/bntest",
+            "test/buildtest_aes",
+            "test/buildtest_asn1",
+            "test/buildtest_asn1t",
+            "test/buildtest_async",
+            "test/buildtest_bio",
+            "test/buildtest_blowfish",
+            "test/buildtest_bn",
+            "test/buildtest_buffer",
+            "test/buildtest_camellia",
+            "test/buildtest_cast",
+            "test/buildtest_cmac",
+            "test/buildtest_cms",
+            "test/buildtest_comp",
+            "test/buildtest_conf",
+            "test/buildtest_conf_api",
+            "test/buildtest_crypto",
+            "test/buildtest_ct",
+            "test/buildtest_des",
+            "test/buildtest_dh",
+            "test/buildtest_dsa",
+            "test/buildtest_dtls1",
+            "test/buildtest_e_os2",
+            "test/buildtest_ebcdic",
+            "test/buildtest_ec",
+            "test/buildtest_ecdh",
+            "test/buildtest_ecdsa",
+            "test/buildtest_engine",
+            "test/buildtest_err",
+            "test/buildtest_evp",
+            "test/buildtest_hmac",
+            "test/buildtest_idea",
+            "test/buildtest_kdf",
+            "test/buildtest_lhash",
+            "test/buildtest_md4",
+            "test/buildtest_md5",
+            "test/buildtest_mdc2",
+            "test/buildtest_modes",
+            "test/buildtest_obj_mac",
+            "test/buildtest_objects",
+            "test/buildtest_ocsp",
+            "test/buildtest_opensslconf",
+            "test/buildtest_opensslv",
+            "test/buildtest_ossl_typ",
+            "test/buildtest_pem",
+            "test/buildtest_pem2",
+            "test/buildtest_pkcs12",
+            "test/buildtest_pkcs7",
+            "test/buildtest_rand",
+            "test/buildtest_rc2",
+            "test/buildtest_rc4",
+            "test/buildtest_ripemd",
+            "test/buildtest_rsa",
+            "test/buildtest_safestack",
+            "test/buildtest_seed",
+            "test/buildtest_sha",
+            "test/buildtest_srp",
+            "test/buildtest_srtp",
+            "test/buildtest_ssl",
+            "test/buildtest_ssl2",
+            "test/buildtest_stack",
+            "test/buildtest_symhacks",
+            "test/buildtest_tls1",
+            "test/buildtest_ts",
+            "test/buildtest_txt_db",
+            "test/buildtest_whrlpool",
+            "test/buildtest_x509",
+            "test/buildtest_x509_vfy",
+            "test/buildtest_x509v3",
+            "test/casttest",
+            "test/cipherlist_test",
+            "test/clienthellotest",
+            "test/constant_time_test",
+            "test/crltest",
+            "test/ct_test",
+            "test/d2i_test",
+            "test/danetest",
+            "test/destest",
+            "test/dhtest",
+            "test/dsatest",
+            "test/dtlstest",
+            "test/dtlsv1listentest",
+            "test/ecdhtest",
+            "test/ecdsatest",
+            "test/ectest",
+            "test/enginetest",
+            "test/evp_extra_test",
+            "test/evp_test",
+            "test/exptest",
+            "test/gmdifftest",
+            "test/heartbeat_test",
+            "test/hmactest",
+            "test/ideatest",
+            "test/igetest",
+            "test/md2test",
+            "test/md4test",
+            "test/md5test",
+            "test/mdc2test",
+            "test/memleaktest",
+            "test/p5_crpt2_test",
+            "test/packettest",
+            "test/pbelutest",
+            "test/randtest",
+            "test/rc2test",
+            "test/rc4test",
+            "test/rc5test",
+            "test/rmdtest",
+            "test/rsa_test",
+            "test/sanitytest",
+            "test/secmemtest",
+            "test/sha1test",
+            "test/sha256t",
+            "test/sha512t",
+            "test/srptest",
+            "test/ssl_test",
+            "test/ssl_test_ctx_test",
+            "test/sslapitest",
+            "test/sslcorrupttest",
+            "test/ssltest_old",
+            "test/threadstest",
+            "test/v3ext",
+            "test/v3nametest",
+            "test/verify_extra_test",
+            "test/wp_test",
+            "test/x509aux",
+        ],
+    "rawlines" =>
+        [
+            "crypto/md5/md5-ia64.s: crypto/md5/asm/md5-ia64.S",
+            "	\$(CC) \$(CFLAGS) -E crypto/md5/asm/md5-ia64.S | 	\$(PERL) -ne 's/;\\s+/;\\n/g; print;' > \$\@",
+            "",
+            "##### SHA assembler implementations",
+            "",
+            "# GNU make \"catch all\"",
+            "crypto/sha/sha1-%.S:	crypto/sha/asm/sha1-%.pl",
+            "	CC=\"\$(CC)\" \$(PERL) \$< \$(PERLASM_SCHEME) \$\@",
+            "crypto/sha/sha256-%.S:	crypto/sha/asm/sha512-%.pl",
+            "	CC=\"\$(CC)\" \$(PERL) \$< \$(PERLASM_SCHEME) \$\@",
+            "crypto/sha/sha512-%.S:	crypto/sha/asm/sha512-%.pl",
+            "	CC=\"\$(CC)\" \$(PERL) \$< \$(PERLASM_SCHEME) \$\@",
+            "crypto/poly1305/poly1305-%.S:	crypto/poly1305/asm/poly1305-%.pl",
+            "	CC=\"\$(CC)\" \$(PERL) \$< \$(PERLASM_SCHEME) \$\@",
+            "##### AES assembler implementations",
+            "",
+            "# GNU make \"catch all\"",
+            "crypto/aes/aes-%.S:	crypto/aes/asm/aes-%.pl",
+            "	CC=\"\$(CC)\" \$(PERL) \$< \$(PERLASM_SCHEME) \$\@",
+            "crypto/aes/bsaes-%.S:	crypto/aes/asm/bsaes-%.pl",
+            "	CC=\"\$(CC)\" \$(PERL) \$< \$(PERLASM_SCHEME) \$\@",
+            "",
+            "crypto/rc4/rc4-ia64.s: crypto/rc4/asm/rc4-ia64.pl",
+            "	\@(trap \"rm \$\@.*\" INT 0; 	  \$(PERL) \$< \$(CFLAGS) \$(LIB_CFLAGS) \$\@.S; 	  case `awk '/^#define RC4_INT/{print\$\$NF}' \$(BLDDIR)/include/openssl/opensslconf.h` in 	  int)	set -x; \$(CC) \$(CFLAGS) \$(LIB_CFLAGS) -DSZ=4 -E \$\@.S > \$\@.i && mv -f \$\@.i \$\@;; 	  char)	set -x; \$(CC) \$(CFLAGS) \$(LIB_CFLAGS) -DSZ=1 -E \$\@.S > \$\@.i && mv -f \$\@.i \$\@;; 	  *)	exit 1 ;; 	  esac )",
+            "",
+            "# GNU make \"catch all\"",
+            "crypto/rc4/rc4-%.s:	crypto/rc4/asm/rc4-%.pl",
+            "	CC=\"\$(CC)\" \$(PERL) \$< \$(PERLASM_SCHEME) \$\@",
+            "##### CHACHA assembler implementations",
+            "",
+            "crypto/chacha/chacha-%.S:	crypto/chacha/asm/chacha-%.pl",
+            "	CC=\"\$(CC)\" \$(PERL) \$< \$(PERLASM_SCHEME) \$\@",
+            "# GNU make \"catch all\"",
+            "crypto/modes/ghash-%.S:	crypto/modes/asm/ghash-%.pl",
+            "	CC=\"\$(CC)\" \$(PERL) \$< \$(PERLASM_SCHEME) \$\@",
+            "##### BN assembler implementations",
+            "",
+            "crypto/bn/bn-mips3.o:	crypto/bn/asm/mips3.s",
+            "	\@if [ \"\$(CC)\" = \"gcc\" ]; then 		ABI=`expr \"\$(CFLAGS)\" : \".*-mabi=\\([n3264]*\\)\"` && 		as -\$\$ABI -O -o \$\@ crypto/bn/asm/mips3.s; 	else	\$(CC) -c \$(CFLAGS) \$(LIB_CFLAGS) -o \$\@ crypto/bn/asm/mips3.s; fi",
+            "",
+            "# GNU assembler fails to compile PA-RISC2 modules, insist on calling",
+            "# vendor assembler...",
+            "crypto/bn/pa-risc2W.o: crypto/bn/asm/pa-risc2W.s",
+            "	CC=\"\$(CC)\" \$(PERL) \$(SRCDIR)/util/fipsas.pl \$(SRCDIR) \$< /usr/ccs/bin/as -o pa-risc2W.o crypto/bn/asm/pa-risc2W.s",
+            "crypto/bn/pa-risc2.o: crypto/bn/asm/pa-risc2.s",
+            "	CC=\"\$(CC)\" \$(PERL) \$(SRCDIR)/util/fipsas.pl \$(SRCDIR) \$< /usr/ccs/bin/as -o pa-risc2.o crypto/bn/asm/pa-risc2.s",
+            "",
+            "crypto/ec/ecp_nistz256-%.S:	crypto/ec/asm/ecp_nistz256-%.pl",
+            "	CC=\"\$(CC)\" \$(PERL) \$< \$(PERLASM_SCHEME) \$\@",
+        ],
+    "rename" =>
+        {
+        },
+    "scripts" =>
+        [
+            "apps/CA.pl",
+            "apps/tsget",
+            "tools/c_rehash",
+            "util/shlib_wrap.sh",
+        ],
+    "shared_sources" =>
+        {
+        },
+    "sources" =>
+        {
+            "apps/CA.pl" =>
+                [
+                    "apps/CA.pl.in",
+                ],
+            "apps/app_rand.o" =>
+                [
+                    "apps/app_rand.c",
+                ],
+            "apps/apps.o" =>
+                [
+                    "apps/apps.c",
+                ],
+            "apps/asn1pars.o" =>
+                [
+                    "apps/asn1pars.c",
+                ],
+            "apps/ca.o" =>
+                [
+                    "apps/ca.c",
+                ],
+            "apps/ciphers.o" =>
+                [
+                    "apps/ciphers.c",
+                ],
+            "apps/cms.o" =>
+                [
+                    "apps/cms.c",
+                ],
+            "apps/crl.o" =>
+                [
+                    "apps/crl.c",
+                ],
+            "apps/crl2p7.o" =>
+                [
+                    "apps/crl2p7.c",
+                ],
+            "apps/dgst.o" =>
+                [
+                    "apps/dgst.c",
+                ],
+            "apps/dhparam.o" =>
+                [
+                    "apps/dhparam.c",
+                ],
+            "apps/dsa.o" =>
+                [
+                    "apps/dsa.c",
+                ],
+            "apps/dsaparam.o" =>
+                [
+                    "apps/dsaparam.c",
+                ],
+            "apps/ec.o" =>
+                [
+                    "apps/ec.c",
+                ],
+            "apps/ecparam.o" =>
+                [
+                    "apps/ecparam.c",
+                ],
+            "apps/enc.o" =>
+                [
+                    "apps/enc.c",
+                ],
+            "apps/engine.o" =>
+                [
+                    "apps/engine.c",
+                ],
+            "apps/errstr.o" =>
+                [
+                    "apps/errstr.c",
+                ],
+            "apps/gendsa.o" =>
+                [
+                    "apps/gendsa.c",
+                ],
+            "apps/genpkey.o" =>
+                [
+                    "apps/genpkey.c",
+                ],
+            "apps/genrsa.o" =>
+                [
+                    "apps/genrsa.c",
+                ],
+            "apps/nseq.o" =>
+                [
+                    "apps/nseq.c",
+                ],
+            "apps/ocsp.o" =>
+                [
+                    "apps/ocsp.c",
+                ],
+            "apps/openssl" =>
+                [
+                    "apps/app_rand.o",
+                    "apps/apps.o",
+                    "apps/asn1pars.o",
+                    "apps/ca.o",
+                    "apps/ciphers.o",
+                    "apps/cms.o",
+                    "apps/crl.o",
+                    "apps/crl2p7.o",
+                    "apps/dgst.o",
+                    "apps/dhparam.o",
+                    "apps/dsa.o",
+                    "apps/dsaparam.o",
+                    "apps/ec.o",
+                    "apps/ecparam.o",
+                    "apps/enc.o",
+                    "apps/engine.o",
+                    "apps/errstr.o",
+                    "apps/gendsa.o",
+                    "apps/genpkey.o",
+                    "apps/genrsa.o",
+                    "apps/nseq.o",
+                    "apps/ocsp.o",
+                    "apps/openssl.o",
+                    "apps/opt.o",
+                    "apps/passwd.o",
+                    "apps/pkcs12.o",
+                    "apps/pkcs7.o",
+                    "apps/pkcs8.o",
+                    "apps/pkey.o",
+                    "apps/pkeyparam.o",
+                    "apps/pkeyutl.o",
+                    "apps/prime.o",
+                    "apps/rand.o",
+                    "apps/rehash.o",
+                    "apps/req.o",
+                    "apps/rsa.o",
+                    "apps/rsautl.o",
+                    "apps/s_cb.o",
+                    "apps/s_client.o",
+                    "apps/s_server.o",
+                    "apps/s_socket.o",
+                    "apps/s_time.o",
+                    "apps/sess_id.o",
+                    "apps/smime.o",
+                    "apps/speed.o",
+                    "apps/spkac.o",
+                    "apps/srp.o",
+                    "apps/ts.o",
+                    "apps/verify.o",
+                    "apps/version.o",
+                    "apps/x509.o",
+                ],
+            "apps/openssl.o" =>
+                [
+                    "apps/openssl.c",
+                ],
+            "apps/opt.o" =>
+                [
+                    "apps/opt.c",
+                ],
+            "apps/passwd.o" =>
+                [
+                    "apps/passwd.c",
+                ],
+            "apps/pkcs12.o" =>
+                [
+                    "apps/pkcs12.c",
+                ],
+            "apps/pkcs7.o" =>
+                [
+                    "apps/pkcs7.c",
+                ],
+            "apps/pkcs8.o" =>
+                [
+                    "apps/pkcs8.c",
+                ],
+            "apps/pkey.o" =>
+                [
+                    "apps/pkey.c",
+                ],
+            "apps/pkeyparam.o" =>
+                [
+                    "apps/pkeyparam.c",
+                ],
+            "apps/pkeyutl.o" =>
+                [
+                    "apps/pkeyutl.c",
+                ],
+            "apps/prime.o" =>
+                [
+                    "apps/prime.c",
+                ],
+            "apps/rand.o" =>
+                [
+                    "apps/rand.c",
+                ],
+            "apps/rehash.o" =>
+                [
+                    "apps/rehash.c",
+                ],
+            "apps/req.o" =>
+                [
+                    "apps/req.c",
+                ],
+            "apps/rsa.o" =>
+                [
+                    "apps/rsa.c",
+                ],
+            "apps/rsautl.o" =>
+                [
+                    "apps/rsautl.c",
+                ],
+            "apps/s_cb.o" =>
+                [
+                    "apps/s_cb.c",
+                ],
+            "apps/s_client.o" =>
+                [
+                    "apps/s_client.c",
+                ],
+            "apps/s_server.o" =>
+                [
+                    "apps/s_server.c",
+                ],
+            "apps/s_socket.o" =>
+                [
+                    "apps/s_socket.c",
+                ],
+            "apps/s_time.o" =>
+                [
+                    "apps/s_time.c",
+                ],
+            "apps/sess_id.o" =>
+                [
+                    "apps/sess_id.c",
+                ],
+            "apps/smime.o" =>
+                [
+                    "apps/smime.c",
+                ],
+            "apps/speed.o" =>
+                [
+                    "apps/speed.c",
+                ],
+            "apps/spkac.o" =>
+                [
+                    "apps/spkac.c",
+                ],
+            "apps/srp.o" =>
+                [
+                    "apps/srp.c",
+                ],
+            "apps/ts.o" =>
+                [
+                    "apps/ts.c",
+                ],
+            "apps/tsget" =>
+                [
+                    "apps/tsget.in",
+                ],
+            "apps/verify.o" =>
+                [
+                    "apps/verify.c",
+                ],
+            "apps/version.o" =>
+                [
+                    "apps/version.c",
+                ],
+            "apps/x509.o" =>
+                [
+                    "apps/x509.c",
+                ],
+            "crypto/aes/aes_cbc.o" =>
+                [
+                    "crypto/aes/aes_cbc.c",
+                ],
+            "crypto/aes/aes_cfb.o" =>
+                [
+                    "crypto/aes/aes_cfb.c",
+                ],
+            "crypto/aes/aes_core.o" =>
+                [
+                    "crypto/aes/aes_core.c",
+                ],
+            "crypto/aes/aes_ecb.o" =>
+                [
+                    "crypto/aes/aes_ecb.c",
+                ],
+            "crypto/aes/aes_ige.o" =>
+                [
+                    "crypto/aes/aes_ige.c",
+                ],
+            "crypto/aes/aes_misc.o" =>
+                [
+                    "crypto/aes/aes_misc.c",
+                ],
+            "crypto/aes/aes_ofb.o" =>
+                [
+                    "crypto/aes/aes_ofb.c",
+                ],
+            "crypto/aes/aes_wrap.o" =>
+                [
+                    "crypto/aes/aes_wrap.c",
+                ],
+            "crypto/asn1/a_bitstr.o" =>
+                [
+                    "crypto/asn1/a_bitstr.c",
+                ],
+            "crypto/asn1/a_d2i_fp.o" =>
+                [
+                    "crypto/asn1/a_d2i_fp.c",
+                ],
+            "crypto/asn1/a_digest.o" =>
+                [
+                    "crypto/asn1/a_digest.c",
+                ],
+            "crypto/asn1/a_dup.o" =>
+                [
+                    "crypto/asn1/a_dup.c",
+                ],
+            "crypto/asn1/a_gentm.o" =>
+                [
+                    "crypto/asn1/a_gentm.c",
+                ],
+            "crypto/asn1/a_i2d_fp.o" =>
+                [
+                    "crypto/asn1/a_i2d_fp.c",
+                ],
+            "crypto/asn1/a_int.o" =>
+                [
+                    "crypto/asn1/a_int.c",
+                ],
+            "crypto/asn1/a_mbstr.o" =>
+                [
+                    "crypto/asn1/a_mbstr.c",
+                ],
+            "crypto/asn1/a_object.o" =>
+                [
+                    "crypto/asn1/a_object.c",
+                ],
+            "crypto/asn1/a_octet.o" =>
+                [
+                    "crypto/asn1/a_octet.c",
+                ],
+            "crypto/asn1/a_print.o" =>
+                [
+                    "crypto/asn1/a_print.c",
+                ],
+            "crypto/asn1/a_sign.o" =>
+                [
+                    "crypto/asn1/a_sign.c",
+                ],
+            "crypto/asn1/a_strex.o" =>
+                [
+                    "crypto/asn1/a_strex.c",
+                ],
+            "crypto/asn1/a_strnid.o" =>
+                [
+                    "crypto/asn1/a_strnid.c",
+                ],
+            "crypto/asn1/a_time.o" =>
+                [
+                    "crypto/asn1/a_time.c",
+                ],
+            "crypto/asn1/a_type.o" =>
+                [
+                    "crypto/asn1/a_type.c",
+                ],
+            "crypto/asn1/a_utctm.o" =>
+                [
+                    "crypto/asn1/a_utctm.c",
+                ],
+            "crypto/asn1/a_utf8.o" =>
+                [
+                    "crypto/asn1/a_utf8.c",
+                ],
+            "crypto/asn1/a_verify.o" =>
+                [
+                    "crypto/asn1/a_verify.c",
+                ],
+            "crypto/asn1/ameth_lib.o" =>
+                [
+                    "crypto/asn1/ameth_lib.c",
+                ],
+            "crypto/asn1/asn1_err.o" =>
+                [
+                    "crypto/asn1/asn1_err.c",
+                ],
+            "crypto/asn1/asn1_gen.o" =>
+                [
+                    "crypto/asn1/asn1_gen.c",
+                ],
+            "crypto/asn1/asn1_lib.o" =>
+                [
+                    "crypto/asn1/asn1_lib.c",
+                ],
+            "crypto/asn1/asn1_par.o" =>
+                [
+                    "crypto/asn1/asn1_par.c",
+                ],
+            "crypto/asn1/asn_mime.o" =>
+                [
+                    "crypto/asn1/asn_mime.c",
+                ],
+            "crypto/asn1/asn_moid.o" =>
+                [
+                    "crypto/asn1/asn_moid.c",
+                ],
+            "crypto/asn1/asn_mstbl.o" =>
+                [
+                    "crypto/asn1/asn_mstbl.c",
+                ],
+            "crypto/asn1/asn_pack.o" =>
+                [
+                    "crypto/asn1/asn_pack.c",
+                ],
+            "crypto/asn1/bio_asn1.o" =>
+                [
+                    "crypto/asn1/bio_asn1.c",
+                ],
+            "crypto/asn1/bio_ndef.o" =>
+                [
+                    "crypto/asn1/bio_ndef.c",
+                ],
+            "crypto/asn1/d2i_pr.o" =>
+                [
+                    "crypto/asn1/d2i_pr.c",
+                ],
+            "crypto/asn1/d2i_pu.o" =>
+                [
+                    "crypto/asn1/d2i_pu.c",
+                ],
+            "crypto/asn1/evp_asn1.o" =>
+                [
+                    "crypto/asn1/evp_asn1.c",
+                ],
+            "crypto/asn1/f_int.o" =>
+                [
+                    "crypto/asn1/f_int.c",
+                ],
+            "crypto/asn1/f_string.o" =>
+                [
+                    "crypto/asn1/f_string.c",
+                ],
+            "crypto/asn1/i2d_pr.o" =>
+                [
+                    "crypto/asn1/i2d_pr.c",
+                ],
+            "crypto/asn1/i2d_pu.o" =>
+                [
+                    "crypto/asn1/i2d_pu.c",
+                ],
+            "crypto/asn1/n_pkey.o" =>
+                [
+                    "crypto/asn1/n_pkey.c",
+                ],
+            "crypto/asn1/nsseq.o" =>
+                [
+                    "crypto/asn1/nsseq.c",
+                ],
+            "crypto/asn1/p5_pbe.o" =>
+                [
+                    "crypto/asn1/p5_pbe.c",
+                ],
+            "crypto/asn1/p5_pbev2.o" =>
+                [
+                    "crypto/asn1/p5_pbev2.c",
+                ],
+            "crypto/asn1/p5_scrypt.o" =>
+                [
+                    "crypto/asn1/p5_scrypt.c",
+                ],
+            "crypto/asn1/p8_pkey.o" =>
+                [
+                    "crypto/asn1/p8_pkey.c",
+                ],
+            "crypto/asn1/t_bitst.o" =>
+                [
+                    "crypto/asn1/t_bitst.c",
+                ],
+            "crypto/asn1/t_pkey.o" =>
+                [
+                    "crypto/asn1/t_pkey.c",
+                ],
+            "crypto/asn1/t_spki.o" =>
+                [
+                    "crypto/asn1/t_spki.c",
+                ],
+            "crypto/asn1/tasn_dec.o" =>
+                [
+                    "crypto/asn1/tasn_dec.c",
+                ],
+            "crypto/asn1/tasn_enc.o" =>
+                [
+                    "crypto/asn1/tasn_enc.c",
+                ],
+            "crypto/asn1/tasn_fre.o" =>
+                [
+                    "crypto/asn1/tasn_fre.c",
+                ],
+            "crypto/asn1/tasn_new.o" =>
+                [
+                    "crypto/asn1/tasn_new.c",
+                ],
+            "crypto/asn1/tasn_prn.o" =>
+                [
+                    "crypto/asn1/tasn_prn.c",
+                ],
+            "crypto/asn1/tasn_scn.o" =>
+                [
+                    "crypto/asn1/tasn_scn.c",
+                ],
+            "crypto/asn1/tasn_typ.o" =>
+                [
+                    "crypto/asn1/tasn_typ.c",
+                ],
+            "crypto/asn1/tasn_utl.o" =>
+                [
+                    "crypto/asn1/tasn_utl.c",
+                ],
+            "crypto/asn1/x_algor.o" =>
+                [
+                    "crypto/asn1/x_algor.c",
+                ],
+            "crypto/asn1/x_bignum.o" =>
+                [
+                    "crypto/asn1/x_bignum.c",
+                ],
+            "crypto/asn1/x_info.o" =>
+                [
+                    "crypto/asn1/x_info.c",
+                ],
+            "crypto/asn1/x_long.o" =>
+                [
+                    "crypto/asn1/x_long.c",
+                ],
+            "crypto/asn1/x_pkey.o" =>
+                [
+                    "crypto/asn1/x_pkey.c",
+                ],
+            "crypto/asn1/x_sig.o" =>
+                [
+                    "crypto/asn1/x_sig.c",
+                ],
+            "crypto/asn1/x_spki.o" =>
+                [
+                    "crypto/asn1/x_spki.c",
+                ],
+            "crypto/asn1/x_val.o" =>
+                [
+                    "crypto/asn1/x_val.c",
+                ],
+            "crypto/async/arch/async_null.o" =>
+                [
+                    "crypto/async/arch/async_null.c",
+                ],
+            "crypto/async/arch/async_posix.o" =>
+                [
+                    "crypto/async/arch/async_posix.c",
+                ],
+            "crypto/async/arch/async_win.o" =>
+                [
+                    "crypto/async/arch/async_win.c",
+                ],
+            "crypto/async/async.o" =>
+                [
+                    "crypto/async/async.c",
+                ],
+            "crypto/async/async_err.o" =>
+                [
+                    "crypto/async/async_err.c",
+                ],
+            "crypto/async/async_wait.o" =>
+                [
+                    "crypto/async/async_wait.c",
+                ],
+            "crypto/bf/bf_cfb64.o" =>
+                [
+                    "crypto/bf/bf_cfb64.c",
+                ],
+            "crypto/bf/bf_ecb.o" =>
+                [
+                    "crypto/bf/bf_ecb.c",
+                ],
+            "crypto/bf/bf_enc.o" =>
+                [
+                    "crypto/bf/bf_enc.c",
+                ],
+            "crypto/bf/bf_ofb64.o" =>
+                [
+                    "crypto/bf/bf_ofb64.c",
+                ],
+            "crypto/bf/bf_skey.o" =>
+                [
+                    "crypto/bf/bf_skey.c",
+                ],
+            "crypto/bio/b_addr.o" =>
+                [
+                    "crypto/bio/b_addr.c",
+                ],
+            "crypto/bio/b_dump.o" =>
+                [
+                    "crypto/bio/b_dump.c",
+                ],
+            "crypto/bio/b_print.o" =>
+                [
+                    "crypto/bio/b_print.c",
+                ],
+            "crypto/bio/b_sock.o" =>
+                [
+                    "crypto/bio/b_sock.c",
+                ],
+            "crypto/bio/b_sock2.o" =>
+                [
+                    "crypto/bio/b_sock2.c",
+                ],
+            "crypto/bio/bf_buff.o" =>
+                [
+                    "crypto/bio/bf_buff.c",
+                ],
+            "crypto/bio/bf_lbuf.o" =>
+                [
+                    "crypto/bio/bf_lbuf.c",
+                ],
+            "crypto/bio/bf_nbio.o" =>
+                [
+                    "crypto/bio/bf_nbio.c",
+                ],
+            "crypto/bio/bf_null.o" =>
+                [
+                    "crypto/bio/bf_null.c",
+                ],
+            "crypto/bio/bio_cb.o" =>
+                [
+                    "crypto/bio/bio_cb.c",
+                ],
+            "crypto/bio/bio_err.o" =>
+                [
+                    "crypto/bio/bio_err.c",
+                ],
+            "crypto/bio/bio_lib.o" =>
+                [
+                    "crypto/bio/bio_lib.c",
+                ],
+            "crypto/bio/bio_meth.o" =>
+                [
+                    "crypto/bio/bio_meth.c",
+                ],
+            "crypto/bio/bss_acpt.o" =>
+                [
+                    "crypto/bio/bss_acpt.c",
+                ],
+            "crypto/bio/bss_bio.o" =>
+                [
+                    "crypto/bio/bss_bio.c",
+                ],
+            "crypto/bio/bss_conn.o" =>
+                [
+                    "crypto/bio/bss_conn.c",
+                ],
+            "crypto/bio/bss_dgram.o" =>
+                [
+                    "crypto/bio/bss_dgram.c",
+                ],
+            "crypto/bio/bss_fd.o" =>
+                [
+                    "crypto/bio/bss_fd.c",
+                ],
+            "crypto/bio/bss_file.o" =>
+                [
+                    "crypto/bio/bss_file.c",
+                ],
+            "crypto/bio/bss_log.o" =>
+                [
+                    "crypto/bio/bss_log.c",
+                ],
+            "crypto/bio/bss_mem.o" =>
+                [
+                    "crypto/bio/bss_mem.c",
+                ],
+            "crypto/bio/bss_null.o" =>
+                [
+                    "crypto/bio/bss_null.c",
+                ],
+            "crypto/bio/bss_sock.o" =>
+                [
+                    "crypto/bio/bss_sock.c",
+                ],
+            "crypto/blake2/blake2b.o" =>
+                [
+                    "crypto/blake2/blake2b.c",
+                ],
+            "crypto/blake2/blake2s.o" =>
+                [
+                    "crypto/blake2/blake2s.c",
+                ],
+            "crypto/blake2/m_blake2b.o" =>
+                [
+                    "crypto/blake2/m_blake2b.c",
+                ],
+            "crypto/blake2/m_blake2s.o" =>
+                [
+                    "crypto/blake2/m_blake2s.c",
+                ],
+            "crypto/bn/bn_add.o" =>
+                [
+                    "crypto/bn/bn_add.c",
+                ],
+            "crypto/bn/bn_asm.o" =>
+                [
+                    "crypto/bn/bn_asm.c",
+                ],
+            "crypto/bn/bn_blind.o" =>
+                [
+                    "crypto/bn/bn_blind.c",
+                ],
+            "crypto/bn/bn_const.o" =>
+                [
+                    "crypto/bn/bn_const.c",
+                ],
+            "crypto/bn/bn_ctx.o" =>
+                [
+                    "crypto/bn/bn_ctx.c",
+                ],
+            "crypto/bn/bn_depr.o" =>
+                [
+                    "crypto/bn/bn_depr.c",
+                ],
+            "crypto/bn/bn_dh.o" =>
+                [
+                    "crypto/bn/bn_dh.c",
+                ],
+            "crypto/bn/bn_div.o" =>
+                [
+                    "crypto/bn/bn_div.c",
+                ],
+            "crypto/bn/bn_err.o" =>
+                [
+                    "crypto/bn/bn_err.c",
+                ],
+            "crypto/bn/bn_exp.o" =>
+                [
+                    "crypto/bn/bn_exp.c",
+                ],
+            "crypto/bn/bn_exp2.o" =>
+                [
+                    "crypto/bn/bn_exp2.c",
+                ],
+            "crypto/bn/bn_gcd.o" =>
+                [
+                    "crypto/bn/bn_gcd.c",
+                ],
+            "crypto/bn/bn_gf2m.o" =>
+                [
+                    "crypto/bn/bn_gf2m.c",
+                ],
+            "crypto/bn/bn_intern.o" =>
+                [
+                    "crypto/bn/bn_intern.c",
+                ],
+            "crypto/bn/bn_kron.o" =>
+                [
+                    "crypto/bn/bn_kron.c",
+                ],
+            "crypto/bn/bn_lib.o" =>
+                [
+                    "crypto/bn/bn_lib.c",
+                ],
+            "crypto/bn/bn_mod.o" =>
+                [
+                    "crypto/bn/bn_mod.c",
+                ],
+            "crypto/bn/bn_mont.o" =>
+                [
+                    "crypto/bn/bn_mont.c",
+                ],
+            "crypto/bn/bn_mpi.o" =>
+                [
+                    "crypto/bn/bn_mpi.c",
+                ],
+            "crypto/bn/bn_mul.o" =>
+                [
+                    "crypto/bn/bn_mul.c",
+                ],
+            "crypto/bn/bn_nist.o" =>
+                [
+                    "crypto/bn/bn_nist.c",
+                ],
+            "crypto/bn/bn_prime.o" =>
+                [
+                    "crypto/bn/bn_prime.c",
+                ],
+            "crypto/bn/bn_print.o" =>
+                [
+                    "crypto/bn/bn_print.c",
+                ],
+            "crypto/bn/bn_rand.o" =>
+                [
+                    "crypto/bn/bn_rand.c",
+                ],
+            "crypto/bn/bn_recp.o" =>
+                [
+                    "crypto/bn/bn_recp.c",
+                ],
+            "crypto/bn/bn_shift.o" =>
+                [
+                    "crypto/bn/bn_shift.c",
+                ],
+            "crypto/bn/bn_sqr.o" =>
+                [
+                    "crypto/bn/bn_sqr.c",
+                ],
+            "crypto/bn/bn_sqrt.o" =>
+                [
+                    "crypto/bn/bn_sqrt.c",
+                ],
+            "crypto/bn/bn_srp.o" =>
+                [
+                    "crypto/bn/bn_srp.c",
+                ],
+            "crypto/bn/bn_word.o" =>
+                [
+                    "crypto/bn/bn_word.c",
+                ],
+            "crypto/bn/bn_x931p.o" =>
+                [
+                    "crypto/bn/bn_x931p.c",
+                ],
+            "crypto/buffer/buf_err.o" =>
+                [
+                    "crypto/buffer/buf_err.c",
+                ],
+            "crypto/buffer/buffer.o" =>
+                [
+                    "crypto/buffer/buffer.c",
+                ],
+            "crypto/camellia/camellia.o" =>
+                [
+                    "crypto/camellia/camellia.c",
+                ],
+            "crypto/camellia/cmll_cbc.o" =>
+                [
+                    "crypto/camellia/cmll_cbc.c",
+                ],
+            "crypto/camellia/cmll_cfb.o" =>
+                [
+                    "crypto/camellia/cmll_cfb.c",
+                ],
+            "crypto/camellia/cmll_ctr.o" =>
+                [
+                    "crypto/camellia/cmll_ctr.c",
+                ],
+            "crypto/camellia/cmll_ecb.o" =>
+                [
+                    "crypto/camellia/cmll_ecb.c",
+                ],
+            "crypto/camellia/cmll_misc.o" =>
+                [
+                    "crypto/camellia/cmll_misc.c",
+                ],
+            "crypto/camellia/cmll_ofb.o" =>
+                [
+                    "crypto/camellia/cmll_ofb.c",
+                ],
+            "crypto/cast/c_cfb64.o" =>
+                [
+                    "crypto/cast/c_cfb64.c",
+                ],
+            "crypto/cast/c_ecb.o" =>
+                [
+                    "crypto/cast/c_ecb.c",
+                ],
+            "crypto/cast/c_enc.o" =>
+                [
+                    "crypto/cast/c_enc.c",
+                ],
+            "crypto/cast/c_ofb64.o" =>
+                [
+                    "crypto/cast/c_ofb64.c",
+                ],
+            "crypto/cast/c_skey.o" =>
+                [
+                    "crypto/cast/c_skey.c",
+                ],
+            "crypto/chacha/chacha_enc.o" =>
+                [
+                    "crypto/chacha/chacha_enc.c",
+                ],
+            "crypto/cmac/cm_ameth.o" =>
+                [
+                    "crypto/cmac/cm_ameth.c",
+                ],
+            "crypto/cmac/cm_pmeth.o" =>
+                [
+                    "crypto/cmac/cm_pmeth.c",
+                ],
+            "crypto/cmac/cmac.o" =>
+                [
+                    "crypto/cmac/cmac.c",
+                ],
+            "crypto/cms/cms_asn1.o" =>
+                [
+                    "crypto/cms/cms_asn1.c",
+                ],
+            "crypto/cms/cms_att.o" =>
+                [
+                    "crypto/cms/cms_att.c",
+                ],
+            "crypto/cms/cms_cd.o" =>
+                [
+                    "crypto/cms/cms_cd.c",
+                ],
+            "crypto/cms/cms_dd.o" =>
+                [
+                    "crypto/cms/cms_dd.c",
+                ],
+            "crypto/cms/cms_enc.o" =>
+                [
+                    "crypto/cms/cms_enc.c",
+                ],
+            "crypto/cms/cms_env.o" =>
+                [
+                    "crypto/cms/cms_env.c",
+                ],
+            "crypto/cms/cms_err.o" =>
+                [
+                    "crypto/cms/cms_err.c",
+                ],
+            "crypto/cms/cms_ess.o" =>
+                [
+                    "crypto/cms/cms_ess.c",
+                ],
+            "crypto/cms/cms_io.o" =>
+                [
+                    "crypto/cms/cms_io.c",
+                ],
+            "crypto/cms/cms_kari.o" =>
+                [
+                    "crypto/cms/cms_kari.c",
+                ],
+            "crypto/cms/cms_lib.o" =>
+                [
+                    "crypto/cms/cms_lib.c",
+                ],
+            "crypto/cms/cms_pwri.o" =>
+                [
+                    "crypto/cms/cms_pwri.c",
+                ],
+            "crypto/cms/cms_sd.o" =>
+                [
+                    "crypto/cms/cms_sd.c",
+                ],
+            "crypto/cms/cms_smime.o" =>
+                [
+                    "crypto/cms/cms_smime.c",
+                ],
+            "crypto/comp/c_zlib.o" =>
+                [
+                    "crypto/comp/c_zlib.c",
+                ],
+            "crypto/comp/comp_err.o" =>
+                [
+                    "crypto/comp/comp_err.c",
+                ],
+            "crypto/comp/comp_lib.o" =>
+                [
+                    "crypto/comp/comp_lib.c",
+                ],
+            "crypto/conf/conf_api.o" =>
+                [
+                    "crypto/conf/conf_api.c",
+                ],
+            "crypto/conf/conf_def.o" =>
+                [
+                    "crypto/conf/conf_def.c",
+                ],
+            "crypto/conf/conf_err.o" =>
+                [
+                    "crypto/conf/conf_err.c",
+                ],
+            "crypto/conf/conf_lib.o" =>
+                [
+                    "crypto/conf/conf_lib.c",
+                ],
+            "crypto/conf/conf_mall.o" =>
+                [
+                    "crypto/conf/conf_mall.c",
+                ],
+            "crypto/conf/conf_mod.o" =>
+                [
+                    "crypto/conf/conf_mod.c",
+                ],
+            "crypto/conf/conf_sap.o" =>
+                [
+                    "crypto/conf/conf_sap.c",
+                ],
+            "crypto/cpt_err.o" =>
+                [
+                    "crypto/cpt_err.c",
+                ],
+            "crypto/cryptlib.o" =>
+                [
+                    "crypto/cryptlib.c",
+                ],
+            "crypto/ct/ct_b64.o" =>
+                [
+                    "crypto/ct/ct_b64.c",
+                ],
+            "crypto/ct/ct_err.o" =>
+                [
+                    "crypto/ct/ct_err.c",
+                ],
+            "crypto/ct/ct_log.o" =>
+                [
+                    "crypto/ct/ct_log.c",
+                ],
+            "crypto/ct/ct_oct.o" =>
+                [
+                    "crypto/ct/ct_oct.c",
+                ],
+            "crypto/ct/ct_policy.o" =>
+                [
+                    "crypto/ct/ct_policy.c",
+                ],
+            "crypto/ct/ct_prn.o" =>
+                [
+                    "crypto/ct/ct_prn.c",
+                ],
+            "crypto/ct/ct_sct.o" =>
+                [
+                    "crypto/ct/ct_sct.c",
+                ],
+            "crypto/ct/ct_sct_ctx.o" =>
+                [
+                    "crypto/ct/ct_sct_ctx.c",
+                ],
+            "crypto/ct/ct_vfy.o" =>
+                [
+                    "crypto/ct/ct_vfy.c",
+                ],
+            "crypto/ct/ct_x509v3.o" =>
+                [
+                    "crypto/ct/ct_x509v3.c",
+                ],
+            "crypto/cversion.o" =>
+                [
+                    "crypto/cversion.c",
+                ],
+            "crypto/des/cbc_cksm.o" =>
+                [
+                    "crypto/des/cbc_cksm.c",
+                ],
+            "crypto/des/cbc_enc.o" =>
+                [
+                    "crypto/des/cbc_enc.c",
+                ],
+            "crypto/des/cfb64ede.o" =>
+                [
+                    "crypto/des/cfb64ede.c",
+                ],
+            "crypto/des/cfb64enc.o" =>
+                [
+                    "crypto/des/cfb64enc.c",
+                ],
+            "crypto/des/cfb_enc.o" =>
+                [
+                    "crypto/des/cfb_enc.c",
+                ],
+            "crypto/des/des_enc.o" =>
+                [
+                    "crypto/des/des_enc.c",
+                ],
+            "crypto/des/ecb3_enc.o" =>
+                [
+                    "crypto/des/ecb3_enc.c",
+                ],
+            "crypto/des/ecb_enc.o" =>
+                [
+                    "crypto/des/ecb_enc.c",
+                ],
+            "crypto/des/fcrypt.o" =>
+                [
+                    "crypto/des/fcrypt.c",
+                ],
+            "crypto/des/fcrypt_b.o" =>
+                [
+                    "crypto/des/fcrypt_b.c",
+                ],
+            "crypto/des/ofb64ede.o" =>
+                [
+                    "crypto/des/ofb64ede.c",
+                ],
+            "crypto/des/ofb64enc.o" =>
+                [
+                    "crypto/des/ofb64enc.c",
+                ],
+            "crypto/des/ofb_enc.o" =>
+                [
+                    "crypto/des/ofb_enc.c",
+                ],
+            "crypto/des/pcbc_enc.o" =>
+                [
+                    "crypto/des/pcbc_enc.c",
+                ],
+            "crypto/des/qud_cksm.o" =>
+                [
+                    "crypto/des/qud_cksm.c",
+                ],
+            "crypto/des/rand_key.o" =>
+                [
+                    "crypto/des/rand_key.c",
+                ],
+            "crypto/des/rpc_enc.o" =>
+                [
+                    "crypto/des/rpc_enc.c",
+                ],
+            "crypto/des/set_key.o" =>
+                [
+                    "crypto/des/set_key.c",
+                ],
+            "crypto/des/str2key.o" =>
+                [
+                    "crypto/des/str2key.c",
+                ],
+            "crypto/des/xcbc_enc.o" =>
+                [
+                    "crypto/des/xcbc_enc.c",
+                ],
+            "crypto/dh/dh_ameth.o" =>
+                [
+                    "crypto/dh/dh_ameth.c",
+                ],
+            "crypto/dh/dh_asn1.o" =>
+                [
+                    "crypto/dh/dh_asn1.c",
+                ],
+            "crypto/dh/dh_check.o" =>
+                [
+                    "crypto/dh/dh_check.c",
+                ],
+            "crypto/dh/dh_depr.o" =>
+                [
+                    "crypto/dh/dh_depr.c",
+                ],
+            "crypto/dh/dh_err.o" =>
+                [
+                    "crypto/dh/dh_err.c",
+                ],
+            "crypto/dh/dh_gen.o" =>
+                [
+                    "crypto/dh/dh_gen.c",
+                ],
+            "crypto/dh/dh_kdf.o" =>
+                [
+                    "crypto/dh/dh_kdf.c",
+                ],
+            "crypto/dh/dh_key.o" =>
+                [
+                    "crypto/dh/dh_key.c",
+                ],
+            "crypto/dh/dh_lib.o" =>
+                [
+                    "crypto/dh/dh_lib.c",
+                ],
+            "crypto/dh/dh_meth.o" =>
+                [
+                    "crypto/dh/dh_meth.c",
+                ],
+            "crypto/dh/dh_pmeth.o" =>
+                [
+                    "crypto/dh/dh_pmeth.c",
+                ],
+            "crypto/dh/dh_prn.o" =>
+                [
+                    "crypto/dh/dh_prn.c",
+                ],
+            "crypto/dh/dh_rfc5114.o" =>
+                [
+                    "crypto/dh/dh_rfc5114.c",
+                ],
+            "crypto/dsa/dsa_ameth.o" =>
+                [
+                    "crypto/dsa/dsa_ameth.c",
+                ],
+            "crypto/dsa/dsa_asn1.o" =>
+                [
+                    "crypto/dsa/dsa_asn1.c",
+                ],
+            "crypto/dsa/dsa_depr.o" =>
+                [
+                    "crypto/dsa/dsa_depr.c",
+                ],
+            "crypto/dsa/dsa_err.o" =>
+                [
+                    "crypto/dsa/dsa_err.c",
+                ],
+            "crypto/dsa/dsa_gen.o" =>
+                [
+                    "crypto/dsa/dsa_gen.c",
+                ],
+            "crypto/dsa/dsa_key.o" =>
+                [
+                    "crypto/dsa/dsa_key.c",
+                ],
+            "crypto/dsa/dsa_lib.o" =>
+                [
+                    "crypto/dsa/dsa_lib.c",
+                ],
+            "crypto/dsa/dsa_meth.o" =>
+                [
+                    "crypto/dsa/dsa_meth.c",
+                ],
+            "crypto/dsa/dsa_ossl.o" =>
+                [
+                    "crypto/dsa/dsa_ossl.c",
+                ],
+            "crypto/dsa/dsa_pmeth.o" =>
+                [
+                    "crypto/dsa/dsa_pmeth.c",
+                ],
+            "crypto/dsa/dsa_prn.o" =>
+                [
+                    "crypto/dsa/dsa_prn.c",
+                ],
+            "crypto/dsa/dsa_sign.o" =>
+                [
+                    "crypto/dsa/dsa_sign.c",
+                ],
+            "crypto/dsa/dsa_vrf.o" =>
+                [
+                    "crypto/dsa/dsa_vrf.c",
+                ],
+            "crypto/dso/dso_dl.o" =>
+                [
+                    "crypto/dso/dso_dl.c",
+                ],
+            "crypto/dso/dso_dlfcn.o" =>
+                [
+                    "crypto/dso/dso_dlfcn.c",
+                ],
+            "crypto/dso/dso_err.o" =>
+                [
+                    "crypto/dso/dso_err.c",
+                ],
+            "crypto/dso/dso_lib.o" =>
+                [
+                    "crypto/dso/dso_lib.c",
+                ],
+            "crypto/dso/dso_openssl.o" =>
+                [
+                    "crypto/dso/dso_openssl.c",
+                ],
+            "crypto/dso/dso_vms.o" =>
+                [
+                    "crypto/dso/dso_vms.c",
+                ],
+            "crypto/dso/dso_win32.o" =>
+                [
+                    "crypto/dso/dso_win32.c",
+                ],
+            "crypto/ebcdic.o" =>
+                [
+                    "crypto/ebcdic.c",
+                ],
+            "crypto/ec/curve25519.o" =>
+                [
+                    "crypto/ec/curve25519.c",
+                ],
+            "crypto/ec/ec2_mult.o" =>
+                [
+                    "crypto/ec/ec2_mult.c",
+                ],
+            "crypto/ec/ec2_oct.o" =>
+                [
+                    "crypto/ec/ec2_oct.c",
+                ],
+            "crypto/ec/ec2_smpl.o" =>
+                [
+                    "crypto/ec/ec2_smpl.c",
+                ],
+            "crypto/ec/ec_ameth.o" =>
+                [
+                    "crypto/ec/ec_ameth.c",
+                ],
+            "crypto/ec/ec_asn1.o" =>
+                [
+                    "crypto/ec/ec_asn1.c",
+                ],
+            "crypto/ec/ec_check.o" =>
+                [
+                    "crypto/ec/ec_check.c",
+                ],
+            "crypto/ec/ec_curve.o" =>
+                [
+                    "crypto/ec/ec_curve.c",
+                ],
+            "crypto/ec/ec_cvt.o" =>
+                [
+                    "crypto/ec/ec_cvt.c",
+                ],
+            "crypto/ec/ec_err.o" =>
+                [
+                    "crypto/ec/ec_err.c",
+                ],
+            "crypto/ec/ec_key.o" =>
+                [
+                    "crypto/ec/ec_key.c",
+                ],
+            "crypto/ec/ec_kmeth.o" =>
+                [
+                    "crypto/ec/ec_kmeth.c",
+                ],
+            "crypto/ec/ec_lib.o" =>
+                [
+                    "crypto/ec/ec_lib.c",
+                ],
+            "crypto/ec/ec_mult.o" =>
+                [
+                    "crypto/ec/ec_mult.c",
+                ],
+            "crypto/ec/ec_oct.o" =>
+                [
+                    "crypto/ec/ec_oct.c",
+                ],
+            "crypto/ec/ec_pmeth.o" =>
+                [
+                    "crypto/ec/ec_pmeth.c",
+                ],
+            "crypto/ec/ec_print.o" =>
+                [
+                    "crypto/ec/ec_print.c",
+                ],
+            "crypto/ec/ecdh_kdf.o" =>
+                [
+                    "crypto/ec/ecdh_kdf.c",
+                ],
+            "crypto/ec/ecdh_ossl.o" =>
+                [
+                    "crypto/ec/ecdh_ossl.c",
+                ],
+            "crypto/ec/ecdsa_ossl.o" =>
+                [
+                    "crypto/ec/ecdsa_ossl.c",
+                ],
+            "crypto/ec/ecdsa_sign.o" =>
+                [
+                    "crypto/ec/ecdsa_sign.c",
+                ],
+            "crypto/ec/ecdsa_vrf.o" =>
+                [
+                    "crypto/ec/ecdsa_vrf.c",
+                ],
+            "crypto/ec/eck_prn.o" =>
+                [
+                    "crypto/ec/eck_prn.c",
+                ],
+            "crypto/ec/ecp_mont.o" =>
+                [
+                    "crypto/ec/ecp_mont.c",
+                ],
+            "crypto/ec/ecp_nist.o" =>
+                [
+                    "crypto/ec/ecp_nist.c",
+                ],
+            "crypto/ec/ecp_nistp224.o" =>
+                [
+                    "crypto/ec/ecp_nistp224.c",
+                ],
+            "crypto/ec/ecp_nistp256.o" =>
+                [
+                    "crypto/ec/ecp_nistp256.c",
+                ],
+            "crypto/ec/ecp_nistp521.o" =>
+                [
+                    "crypto/ec/ecp_nistp521.c",
+                ],
+            "crypto/ec/ecp_nistputil.o" =>
+                [
+                    "crypto/ec/ecp_nistputil.c",
+                ],
+            "crypto/ec/ecp_oct.o" =>
+                [
+                    "crypto/ec/ecp_oct.c",
+                ],
+            "crypto/ec/ecp_smpl.o" =>
+                [
+                    "crypto/ec/ecp_smpl.c",
+                ],
+            "crypto/ec/ecx_meth.o" =>
+                [
+                    "crypto/ec/ecx_meth.c",
+                ],
+            "crypto/engine/eng_all.o" =>
+                [
+                    "crypto/engine/eng_all.c",
+                ],
+            "crypto/engine/eng_cnf.o" =>
+                [
+                    "crypto/engine/eng_cnf.c",
+                ],
+            "crypto/engine/eng_cryptodev.o" =>
+                [
+                    "crypto/engine/eng_cryptodev.c",
+                ],
+            "crypto/engine/eng_ctrl.o" =>
+                [
+                    "crypto/engine/eng_ctrl.c",
+                ],
+            "crypto/engine/eng_dyn.o" =>
+                [
+                    "crypto/engine/eng_dyn.c",
+                ],
+            "crypto/engine/eng_err.o" =>
+                [
+                    "crypto/engine/eng_err.c",
+                ],
+            "crypto/engine/eng_fat.o" =>
+                [
+                    "crypto/engine/eng_fat.c",
+                ],
+            "crypto/engine/eng_init.o" =>
+                [
+                    "crypto/engine/eng_init.c",
+                ],
+            "crypto/engine/eng_lib.o" =>
+                [
+                    "crypto/engine/eng_lib.c",
+                ],
+            "crypto/engine/eng_list.o" =>
+                [
+                    "crypto/engine/eng_list.c",
+                ],
+            "crypto/engine/eng_openssl.o" =>
+                [
+                    "crypto/engine/eng_openssl.c",
+                ],
+            "crypto/engine/eng_pkey.o" =>
+                [
+                    "crypto/engine/eng_pkey.c",
+                ],
+            "crypto/engine/eng_rdrand.o" =>
+                [
+                    "crypto/engine/eng_rdrand.c",
+                ],
+            "crypto/engine/eng_table.o" =>
+                [
+                    "crypto/engine/eng_table.c",
+                ],
+            "crypto/engine/tb_asnmth.o" =>
+                [
+                    "crypto/engine/tb_asnmth.c",
+                ],
+            "crypto/engine/tb_cipher.o" =>
+                [
+                    "crypto/engine/tb_cipher.c",
+                ],
+            "crypto/engine/tb_dh.o" =>
+                [
+                    "crypto/engine/tb_dh.c",
+                ],
+            "crypto/engine/tb_digest.o" =>
+                [
+                    "crypto/engine/tb_digest.c",
+                ],
+            "crypto/engine/tb_dsa.o" =>
+                [
+                    "crypto/engine/tb_dsa.c",
+                ],
+            "crypto/engine/tb_eckey.o" =>
+                [
+                    "crypto/engine/tb_eckey.c",
+                ],
+            "crypto/engine/tb_pkmeth.o" =>
+                [
+                    "crypto/engine/tb_pkmeth.c",
+                ],
+            "crypto/engine/tb_rand.o" =>
+                [
+                    "crypto/engine/tb_rand.c",
+                ],
+            "crypto/engine/tb_rsa.o" =>
+                [
+                    "crypto/engine/tb_rsa.c",
+                ],
+            "crypto/err/err.o" =>
+                [
+                    "crypto/err/err.c",
+                ],
+            "crypto/err/err_all.o" =>
+                [
+                    "crypto/err/err_all.c",
+                ],
+            "crypto/err/err_prn.o" =>
+                [
+                    "crypto/err/err_prn.c",
+                ],
+            "crypto/evp/bio_b64.o" =>
+                [
+                    "crypto/evp/bio_b64.c",
+                ],
+            "crypto/evp/bio_enc.o" =>
+                [
+                    "crypto/evp/bio_enc.c",
+                ],
+            "crypto/evp/bio_md.o" =>
+                [
+                    "crypto/evp/bio_md.c",
+                ],
+            "crypto/evp/bio_ok.o" =>
+                [
+                    "crypto/evp/bio_ok.c",
+                ],
+            "crypto/evp/c_allc.o" =>
+                [
+                    "crypto/evp/c_allc.c",
+                ],
+            "crypto/evp/c_alld.o" =>
+                [
+                    "crypto/evp/c_alld.c",
+                ],
+            "crypto/evp/cmeth_lib.o" =>
+                [
+                    "crypto/evp/cmeth_lib.c",
+                ],
+            "crypto/evp/digest.o" =>
+                [
+                    "crypto/evp/digest.c",
+                ],
+            "crypto/evp/e_aes.o" =>
+                [
+                    "crypto/evp/e_aes.c",
+                ],
+            "crypto/evp/e_aes_cbc_hmac_sha1.o" =>
+                [
+                    "crypto/evp/e_aes_cbc_hmac_sha1.c",
+                ],
+            "crypto/evp/e_aes_cbc_hmac_sha256.o" =>
+                [
+                    "crypto/evp/e_aes_cbc_hmac_sha256.c",
+                ],
+            "crypto/evp/e_bf.o" =>
+                [
+                    "crypto/evp/e_bf.c",
+                ],
+            "crypto/evp/e_camellia.o" =>
+                [
+                    "crypto/evp/e_camellia.c",
+                ],
+            "crypto/evp/e_cast.o" =>
+                [
+                    "crypto/evp/e_cast.c",
+                ],
+            "crypto/evp/e_chacha20_poly1305.o" =>
+                [
+                    "crypto/evp/e_chacha20_poly1305.c",
+                ],
+            "crypto/evp/e_des.o" =>
+                [
+                    "crypto/evp/e_des.c",
+                ],
+            "crypto/evp/e_des3.o" =>
+                [
+                    "crypto/evp/e_des3.c",
+                ],
+            "crypto/evp/e_idea.o" =>
+                [
+                    "crypto/evp/e_idea.c",
+                ],
+            "crypto/evp/e_null.o" =>
+                [
+                    "crypto/evp/e_null.c",
+                ],
+            "crypto/evp/e_old.o" =>
+                [
+                    "crypto/evp/e_old.c",
+                ],
+            "crypto/evp/e_rc2.o" =>
+                [
+                    "crypto/evp/e_rc2.c",
+                ],
+            "crypto/evp/e_rc4.o" =>
+                [
+                    "crypto/evp/e_rc4.c",
+                ],
+            "crypto/evp/e_rc4_hmac_md5.o" =>
+                [
+                    "crypto/evp/e_rc4_hmac_md5.c",
+                ],
+            "crypto/evp/e_rc5.o" =>
+                [
+                    "crypto/evp/e_rc5.c",
+                ],
+            "crypto/evp/e_seed.o" =>
+                [
+                    "crypto/evp/e_seed.c",
+                ],
+            "crypto/evp/e_xcbc_d.o" =>
+                [
+                    "crypto/evp/e_xcbc_d.c",
+                ],
+            "crypto/evp/encode.o" =>
+                [
+                    "crypto/evp/encode.c",
+                ],
+            "crypto/evp/evp_cnf.o" =>
+                [
+                    "crypto/evp/evp_cnf.c",
+                ],
+            "crypto/evp/evp_enc.o" =>
+                [
+                    "crypto/evp/evp_enc.c",
+                ],
+            "crypto/evp/evp_err.o" =>
+                [
+                    "crypto/evp/evp_err.c",
+                ],
+            "crypto/evp/evp_key.o" =>
+                [
+                    "crypto/evp/evp_key.c",
+                ],
+            "crypto/evp/evp_lib.o" =>
+                [
+                    "crypto/evp/evp_lib.c",
+                ],
+            "crypto/evp/evp_pbe.o" =>
+                [
+                    "crypto/evp/evp_pbe.c",
+                ],
+            "crypto/evp/evp_pkey.o" =>
+                [
+                    "crypto/evp/evp_pkey.c",
+                ],
+            "crypto/evp/m_md2.o" =>
+                [
+                    "crypto/evp/m_md2.c",
+                ],
+            "crypto/evp/m_md4.o" =>
+                [
+                    "crypto/evp/m_md4.c",
+                ],
+            "crypto/evp/m_md5.o" =>
+                [
+                    "crypto/evp/m_md5.c",
+                ],
+            "crypto/evp/m_md5_sha1.o" =>
+                [
+                    "crypto/evp/m_md5_sha1.c",
+                ],
+            "crypto/evp/m_mdc2.o" =>
+                [
+                    "crypto/evp/m_mdc2.c",
+                ],
+            "crypto/evp/m_null.o" =>
+                [
+                    "crypto/evp/m_null.c",
+                ],
+            "crypto/evp/m_ripemd.o" =>
+                [
+                    "crypto/evp/m_ripemd.c",
+                ],
+            "crypto/evp/m_sha1.o" =>
+                [
+                    "crypto/evp/m_sha1.c",
+                ],
+            "crypto/evp/m_sigver.o" =>
+                [
+                    "crypto/evp/m_sigver.c",
+                ],
+            "crypto/evp/m_wp.o" =>
+                [
+                    "crypto/evp/m_wp.c",
+                ],
+            "crypto/evp/names.o" =>
+                [
+                    "crypto/evp/names.c",
+                ],
+            "crypto/evp/p5_crpt.o" =>
+                [
+                    "crypto/evp/p5_crpt.c",
+                ],
+            "crypto/evp/p5_crpt2.o" =>
+                [
+                    "crypto/evp/p5_crpt2.c",
+                ],
+            "crypto/evp/p_dec.o" =>
+                [
+                    "crypto/evp/p_dec.c",
+                ],
+            "crypto/evp/p_enc.o" =>
+                [
+                    "crypto/evp/p_enc.c",
+                ],
+            "crypto/evp/p_lib.o" =>
+                [
+                    "crypto/evp/p_lib.c",
+                ],
+            "crypto/evp/p_open.o" =>
+                [
+                    "crypto/evp/p_open.c",
+                ],
+            "crypto/evp/p_seal.o" =>
+                [
+                    "crypto/evp/p_seal.c",
+                ],
+            "crypto/evp/p_sign.o" =>
+                [
+                    "crypto/evp/p_sign.c",
+                ],
+            "crypto/evp/p_verify.o" =>
+                [
+                    "crypto/evp/p_verify.c",
+                ],
+            "crypto/evp/pmeth_fn.o" =>
+                [
+                    "crypto/evp/pmeth_fn.c",
+                ],
+            "crypto/evp/pmeth_gn.o" =>
+                [
+                    "crypto/evp/pmeth_gn.c",
+                ],
+            "crypto/evp/pmeth_lib.o" =>
+                [
+                    "crypto/evp/pmeth_lib.c",
+                ],
+            "crypto/evp/scrypt.o" =>
+                [
+                    "crypto/evp/scrypt.c",
+                ],
+            "crypto/ex_data.o" =>
+                [
+                    "crypto/ex_data.c",
+                ],
+            "crypto/hmac/hm_ameth.o" =>
+                [
+                    "crypto/hmac/hm_ameth.c",
+                ],
+            "crypto/hmac/hm_pmeth.o" =>
+                [
+                    "crypto/hmac/hm_pmeth.c",
+                ],
+            "crypto/hmac/hmac.o" =>
+                [
+                    "crypto/hmac/hmac.c",
+                ],
+            "crypto/idea/i_cbc.o" =>
+                [
+                    "crypto/idea/i_cbc.c",
+                ],
+            "crypto/idea/i_cfb64.o" =>
+                [
+                    "crypto/idea/i_cfb64.c",
+                ],
+            "crypto/idea/i_ecb.o" =>
+                [
+                    "crypto/idea/i_ecb.c",
+                ],
+            "crypto/idea/i_ofb64.o" =>
+                [
+                    "crypto/idea/i_ofb64.c",
+                ],
+            "crypto/idea/i_skey.o" =>
+                [
+                    "crypto/idea/i_skey.c",
+                ],
+            "crypto/init.o" =>
+                [
+                    "crypto/init.c",
+                ],
+            "crypto/kdf/hkdf.o" =>
+                [
+                    "crypto/kdf/hkdf.c",
+                ],
+            "crypto/kdf/kdf_err.o" =>
+                [
+                    "crypto/kdf/kdf_err.c",
+                ],
+            "crypto/kdf/tls1_prf.o" =>
+                [
+                    "crypto/kdf/tls1_prf.c",
+                ],
+            "crypto/lhash/lh_stats.o" =>
+                [
+                    "crypto/lhash/lh_stats.c",
+                ],
+            "crypto/lhash/lhash.o" =>
+                [
+                    "crypto/lhash/lhash.c",
+                ],
+            "crypto/md4/md4_dgst.o" =>
+                [
+                    "crypto/md4/md4_dgst.c",
+                ],
+            "crypto/md4/md4_one.o" =>
+                [
+                    "crypto/md4/md4_one.c",
+                ],
+            "crypto/md5/md5_dgst.o" =>
+                [
+                    "crypto/md5/md5_dgst.c",
+                ],
+            "crypto/md5/md5_one.o" =>
+                [
+                    "crypto/md5/md5_one.c",
+                ],
+            "crypto/mdc2/mdc2_one.o" =>
+                [
+                    "crypto/mdc2/mdc2_one.c",
+                ],
+            "crypto/mdc2/mdc2dgst.o" =>
+                [
+                    "crypto/mdc2/mdc2dgst.c",
+                ],
+            "crypto/mem.o" =>
+                [
+                    "crypto/mem.c",
+                ],
+            "crypto/mem_clr.o" =>
+                [
+                    "crypto/mem_clr.c",
+                ],
+            "crypto/mem_dbg.o" =>
+                [
+                    "crypto/mem_dbg.c",
+                ],
+            "crypto/mem_sec.o" =>
+                [
+                    "crypto/mem_sec.c",
+                ],
+            "crypto/modes/cbc128.o" =>
+                [
+                    "crypto/modes/cbc128.c",
+                ],
+            "crypto/modes/ccm128.o" =>
+                [
+                    "crypto/modes/ccm128.c",
+                ],
+            "crypto/modes/cfb128.o" =>
+                [
+                    "crypto/modes/cfb128.c",
+                ],
+            "crypto/modes/ctr128.o" =>
+                [
+                    "crypto/modes/ctr128.c",
+                ],
+            "crypto/modes/cts128.o" =>
+                [
+                    "crypto/modes/cts128.c",
+                ],
+            "crypto/modes/gcm128.o" =>
+                [
+                    "crypto/modes/gcm128.c",
+                ],
+            "crypto/modes/ocb128.o" =>
+                [
+                    "crypto/modes/ocb128.c",
+                ],
+            "crypto/modes/ofb128.o" =>
+                [
+                    "crypto/modes/ofb128.c",
+                ],
+            "crypto/modes/wrap128.o" =>
+                [
+                    "crypto/modes/wrap128.c",
+                ],
+            "crypto/modes/xts128.o" =>
+                [
+                    "crypto/modes/xts128.c",
+                ],
+            "crypto/o_dir.o" =>
+                [
+                    "crypto/o_dir.c",
+                ],
+            "crypto/o_fips.o" =>
+                [
+                    "crypto/o_fips.c",
+                ],
+            "crypto/o_fopen.o" =>
+                [
+                    "crypto/o_fopen.c",
+                ],
+            "crypto/o_init.o" =>
+                [
+                    "crypto/o_init.c",
+                ],
+            "crypto/o_str.o" =>
+                [
+                    "crypto/o_str.c",
+                ],
+            "crypto/o_time.o" =>
+                [
+                    "crypto/o_time.c",
+                ],
+            "crypto/objects/o_names.o" =>
+                [
+                    "crypto/objects/o_names.c",
+                ],
+            "crypto/objects/obj_dat.o" =>
+                [
+                    "crypto/objects/obj_dat.c",
+                ],
+            "crypto/objects/obj_err.o" =>
+                [
+                    "crypto/objects/obj_err.c",
+                ],
+            "crypto/objects/obj_lib.o" =>
+                [
+                    "crypto/objects/obj_lib.c",
+                ],
+            "crypto/objects/obj_xref.o" =>
+                [
+                    "crypto/objects/obj_xref.c",
+                ],
+            "crypto/ocsp/ocsp_asn.o" =>
+                [
+                    "crypto/ocsp/ocsp_asn.c",
+                ],
+            "crypto/ocsp/ocsp_cl.o" =>
+                [
+                    "crypto/ocsp/ocsp_cl.c",
+                ],
+            "crypto/ocsp/ocsp_err.o" =>
+                [
+                    "crypto/ocsp/ocsp_err.c",
+                ],
+            "crypto/ocsp/ocsp_ext.o" =>
+                [
+                    "crypto/ocsp/ocsp_ext.c",
+                ],
+            "crypto/ocsp/ocsp_ht.o" =>
+                [
+                    "crypto/ocsp/ocsp_ht.c",
+                ],
+            "crypto/ocsp/ocsp_lib.o" =>
+                [
+                    "crypto/ocsp/ocsp_lib.c",
+                ],
+            "crypto/ocsp/ocsp_prn.o" =>
+                [
+                    "crypto/ocsp/ocsp_prn.c",
+                ],
+            "crypto/ocsp/ocsp_srv.o" =>
+                [
+                    "crypto/ocsp/ocsp_srv.c",
+                ],
+            "crypto/ocsp/ocsp_vfy.o" =>
+                [
+                    "crypto/ocsp/ocsp_vfy.c",
+                ],
+            "crypto/ocsp/v3_ocsp.o" =>
+                [
+                    "crypto/ocsp/v3_ocsp.c",
+                ],
+            "crypto/pem/pem_all.o" =>
+                [
+                    "crypto/pem/pem_all.c",
+                ],
+            "crypto/pem/pem_err.o" =>
+                [
+                    "crypto/pem/pem_err.c",
+                ],
+            "crypto/pem/pem_info.o" =>
+                [
+                    "crypto/pem/pem_info.c",
+                ],
+            "crypto/pem/pem_lib.o" =>
+                [
+                    "crypto/pem/pem_lib.c",
+                ],
+            "crypto/pem/pem_oth.o" =>
+                [
+                    "crypto/pem/pem_oth.c",
+                ],
+            "crypto/pem/pem_pk8.o" =>
+                [
+                    "crypto/pem/pem_pk8.c",
+                ],
+            "crypto/pem/pem_pkey.o" =>
+                [
+                    "crypto/pem/pem_pkey.c",
+                ],
+            "crypto/pem/pem_sign.o" =>
+                [
+                    "crypto/pem/pem_sign.c",
+                ],
+            "crypto/pem/pem_x509.o" =>
+                [
+                    "crypto/pem/pem_x509.c",
+                ],
+            "crypto/pem/pem_xaux.o" =>
+                [
+                    "crypto/pem/pem_xaux.c",
+                ],
+            "crypto/pem/pvkfmt.o" =>
+                [
+                    "crypto/pem/pvkfmt.c",
+                ],
+            "crypto/pkcs12/p12_add.o" =>
+                [
+                    "crypto/pkcs12/p12_add.c",
+                ],
+            "crypto/pkcs12/p12_asn.o" =>
+                [
+                    "crypto/pkcs12/p12_asn.c",
+                ],
+            "crypto/pkcs12/p12_attr.o" =>
+                [
+                    "crypto/pkcs12/p12_attr.c",
+                ],
+            "crypto/pkcs12/p12_crpt.o" =>
+                [
+                    "crypto/pkcs12/p12_crpt.c",
+                ],
+            "crypto/pkcs12/p12_crt.o" =>
+                [
+                    "crypto/pkcs12/p12_crt.c",
+                ],
+            "crypto/pkcs12/p12_decr.o" =>
+                [
+                    "crypto/pkcs12/p12_decr.c",
+                ],
+            "crypto/pkcs12/p12_init.o" =>
+                [
+                    "crypto/pkcs12/p12_init.c",
+                ],
+            "crypto/pkcs12/p12_key.o" =>
+                [
+                    "crypto/pkcs12/p12_key.c",
+                ],
+            "crypto/pkcs12/p12_kiss.o" =>
+                [
+                    "crypto/pkcs12/p12_kiss.c",
+                ],
+            "crypto/pkcs12/p12_mutl.o" =>
+                [
+                    "crypto/pkcs12/p12_mutl.c",
+                ],
+            "crypto/pkcs12/p12_npas.o" =>
+                [
+                    "crypto/pkcs12/p12_npas.c",
+                ],
+            "crypto/pkcs12/p12_p8d.o" =>
+                [
+                    "crypto/pkcs12/p12_p8d.c",
+                ],
+            "crypto/pkcs12/p12_p8e.o" =>
+                [
+                    "crypto/pkcs12/p12_p8e.c",
+                ],
+            "crypto/pkcs12/p12_sbag.o" =>
+                [
+                    "crypto/pkcs12/p12_sbag.c",
+                ],
+            "crypto/pkcs12/p12_utl.o" =>
+                [
+                    "crypto/pkcs12/p12_utl.c",
+                ],
+            "crypto/pkcs12/pk12err.o" =>
+                [
+                    "crypto/pkcs12/pk12err.c",
+                ],
+            "crypto/pkcs7/bio_pk7.o" =>
+                [
+                    "crypto/pkcs7/bio_pk7.c",
+                ],
+            "crypto/pkcs7/pk7_asn1.o" =>
+                [
+                    "crypto/pkcs7/pk7_asn1.c",
+                ],
+            "crypto/pkcs7/pk7_attr.o" =>
+                [
+                    "crypto/pkcs7/pk7_attr.c",
+                ],
+            "crypto/pkcs7/pk7_doit.o" =>
+                [
+                    "crypto/pkcs7/pk7_doit.c",
+                ],
+            "crypto/pkcs7/pk7_lib.o" =>
+                [
+                    "crypto/pkcs7/pk7_lib.c",
+                ],
+            "crypto/pkcs7/pk7_mime.o" =>
+                [
+                    "crypto/pkcs7/pk7_mime.c",
+                ],
+            "crypto/pkcs7/pk7_smime.o" =>
+                [
+                    "crypto/pkcs7/pk7_smime.c",
+                ],
+            "crypto/pkcs7/pkcs7err.o" =>
+                [
+                    "crypto/pkcs7/pkcs7err.c",
+                ],
+            "crypto/poly1305/poly1305.o" =>
+                [
+                    "crypto/poly1305/poly1305.c",
+                ],
+            "crypto/rand/md_rand.o" =>
+                [
+                    "crypto/rand/md_rand.c",
+                ],
+            "crypto/rand/rand_egd.o" =>
+                [
+                    "crypto/rand/rand_egd.c",
+                ],
+            "crypto/rand/rand_err.o" =>
+                [
+                    "crypto/rand/rand_err.c",
+                ],
+            "crypto/rand/rand_lib.o" =>
+                [
+                    "crypto/rand/rand_lib.c",
+                ],
+            "crypto/rand/rand_unix.o" =>
+                [
+                    "crypto/rand/rand_unix.c",
+                ],
+            "crypto/rand/rand_vms.o" =>
+                [
+                    "crypto/rand/rand_vms.c",
+                ],
+            "crypto/rand/rand_win.o" =>
+                [
+                    "crypto/rand/rand_win.c",
+                ],
+            "crypto/rand/randfile.o" =>
+                [
+                    "crypto/rand/randfile.c",
+                ],
+            "crypto/rc2/rc2_cbc.o" =>
+                [
+                    "crypto/rc2/rc2_cbc.c",
+                ],
+            "crypto/rc2/rc2_ecb.o" =>
+                [
+                    "crypto/rc2/rc2_ecb.c",
+                ],
+            "crypto/rc2/rc2_skey.o" =>
+                [
+                    "crypto/rc2/rc2_skey.c",
+                ],
+            "crypto/rc2/rc2cfb64.o" =>
+                [
+                    "crypto/rc2/rc2cfb64.c",
+                ],
+            "crypto/rc2/rc2ofb64.o" =>
+                [
+                    "crypto/rc2/rc2ofb64.c",
+                ],
+            "crypto/rc4/rc4_enc.o" =>
+                [
+                    "crypto/rc4/rc4_enc.c",
+                ],
+            "crypto/rc4/rc4_skey.o" =>
+                [
+                    "crypto/rc4/rc4_skey.c",
+                ],
+            "crypto/ripemd/rmd_dgst.o" =>
+                [
+                    "crypto/ripemd/rmd_dgst.c",
+                ],
+            "crypto/ripemd/rmd_one.o" =>
+                [
+                    "crypto/ripemd/rmd_one.c",
+                ],
+            "crypto/rsa/rsa_ameth.o" =>
+                [
+                    "crypto/rsa/rsa_ameth.c",
+                ],
+            "crypto/rsa/rsa_asn1.o" =>
+                [
+                    "crypto/rsa/rsa_asn1.c",
+                ],
+            "crypto/rsa/rsa_chk.o" =>
+                [
+                    "crypto/rsa/rsa_chk.c",
+                ],
+            "crypto/rsa/rsa_crpt.o" =>
+                [
+                    "crypto/rsa/rsa_crpt.c",
+                ],
+            "crypto/rsa/rsa_depr.o" =>
+                [
+                    "crypto/rsa/rsa_depr.c",
+                ],
+            "crypto/rsa/rsa_err.o" =>
+                [
+                    "crypto/rsa/rsa_err.c",
+                ],
+            "crypto/rsa/rsa_gen.o" =>
+                [
+                    "crypto/rsa/rsa_gen.c",
+                ],
+            "crypto/rsa/rsa_lib.o" =>
+                [
+                    "crypto/rsa/rsa_lib.c",
+                ],
+            "crypto/rsa/rsa_meth.o" =>
+                [
+                    "crypto/rsa/rsa_meth.c",
+                ],
+            "crypto/rsa/rsa_none.o" =>
+                [
+                    "crypto/rsa/rsa_none.c",
+                ],
+            "crypto/rsa/rsa_null.o" =>
+                [
+                    "crypto/rsa/rsa_null.c",
+                ],
+            "crypto/rsa/rsa_oaep.o" =>
+                [
+                    "crypto/rsa/rsa_oaep.c",
+                ],
+            "crypto/rsa/rsa_ossl.o" =>
+                [
+                    "crypto/rsa/rsa_ossl.c",
+                ],
+            "crypto/rsa/rsa_pk1.o" =>
+                [
+                    "crypto/rsa/rsa_pk1.c",
+                ],
+            "crypto/rsa/rsa_pmeth.o" =>
+                [
+                    "crypto/rsa/rsa_pmeth.c",
+                ],
+            "crypto/rsa/rsa_prn.o" =>
+                [
+                    "crypto/rsa/rsa_prn.c",
+                ],
+            "crypto/rsa/rsa_pss.o" =>
+                [
+                    "crypto/rsa/rsa_pss.c",
+                ],
+            "crypto/rsa/rsa_saos.o" =>
+                [
+                    "crypto/rsa/rsa_saos.c",
+                ],
+            "crypto/rsa/rsa_sign.o" =>
+                [
+                    "crypto/rsa/rsa_sign.c",
+                ],
+            "crypto/rsa/rsa_ssl.o" =>
+                [
+                    "crypto/rsa/rsa_ssl.c",
+                ],
+            "crypto/rsa/rsa_x931.o" =>
+                [
+                    "crypto/rsa/rsa_x931.c",
+                ],
+            "crypto/rsa/rsa_x931g.o" =>
+                [
+                    "crypto/rsa/rsa_x931g.c",
+                ],
+            "crypto/seed/seed.o" =>
+                [
+                    "crypto/seed/seed.c",
+                ],
+            "crypto/seed/seed_cbc.o" =>
+                [
+                    "crypto/seed/seed_cbc.c",
+                ],
+            "crypto/seed/seed_cfb.o" =>
+                [
+                    "crypto/seed/seed_cfb.c",
+                ],
+            "crypto/seed/seed_ecb.o" =>
+                [
+                    "crypto/seed/seed_ecb.c",
+                ],
+            "crypto/seed/seed_ofb.o" =>
+                [
+                    "crypto/seed/seed_ofb.c",
+                ],
+            "crypto/sha/sha1_one.o" =>
+                [
+                    "crypto/sha/sha1_one.c",
+                ],
+            "crypto/sha/sha1dgst.o" =>
+                [
+                    "crypto/sha/sha1dgst.c",
+                ],
+            "crypto/sha/sha256.o" =>
+                [
+                    "crypto/sha/sha256.c",
+                ],
+            "crypto/sha/sha512.o" =>
+                [
+                    "crypto/sha/sha512.c",
+                ],
+            "crypto/srp/srp_lib.o" =>
+                [
+                    "crypto/srp/srp_lib.c",
+                ],
+            "crypto/srp/srp_vfy.o" =>
+                [
+                    "crypto/srp/srp_vfy.c",
+                ],
+            "crypto/stack/stack.o" =>
+                [
+                    "crypto/stack/stack.c",
+                ],
+            "crypto/threads_none.o" =>
+                [
+                    "crypto/threads_none.c",
+                ],
+            "crypto/threads_pthread.o" =>
+                [
+                    "crypto/threads_pthread.c",
+                ],
+            "crypto/threads_win.o" =>
+                [
+                    "crypto/threads_win.c",
+                ],
+            "crypto/ts/ts_asn1.o" =>
+                [
+                    "crypto/ts/ts_asn1.c",
+                ],
+            "crypto/ts/ts_conf.o" =>
+                [
+                    "crypto/ts/ts_conf.c",
+                ],
+            "crypto/ts/ts_err.o" =>
+                [
+                    "crypto/ts/ts_err.c",
+                ],
+            "crypto/ts/ts_lib.o" =>
+                [
+                    "crypto/ts/ts_lib.c",
+                ],
+            "crypto/ts/ts_req_print.o" =>
+                [
+                    "crypto/ts/ts_req_print.c",
+                ],
+            "crypto/ts/ts_req_utils.o" =>
+                [
+                    "crypto/ts/ts_req_utils.c",
+                ],
+            "crypto/ts/ts_rsp_print.o" =>
+                [
+                    "crypto/ts/ts_rsp_print.c",
+                ],
+            "crypto/ts/ts_rsp_sign.o" =>
+                [
+                    "crypto/ts/ts_rsp_sign.c",
+                ],
+            "crypto/ts/ts_rsp_utils.o" =>
+                [
+                    "crypto/ts/ts_rsp_utils.c",
+                ],
+            "crypto/ts/ts_rsp_verify.o" =>
+                [
+                    "crypto/ts/ts_rsp_verify.c",
+                ],
+            "crypto/ts/ts_verify_ctx.o" =>
+                [
+                    "crypto/ts/ts_verify_ctx.c",
+                ],
+            "crypto/txt_db/txt_db.o" =>
+                [
+                    "crypto/txt_db/txt_db.c",
+                ],
+            "crypto/uid.o" =>
+                [
+                    "crypto/uid.c",
+                ],
+            "crypto/whrlpool/wp_block.o" =>
+                [
+                    "crypto/whrlpool/wp_block.c",
+                ],
+            "crypto/whrlpool/wp_dgst.o" =>
+                [
+                    "crypto/whrlpool/wp_dgst.c",
+                ],
+            "crypto/x509/by_dir.o" =>
+                [
+                    "crypto/x509/by_dir.c",
+                ],
+            "crypto/x509/by_file.o" =>
+                [
+                    "crypto/x509/by_file.c",
+                ],
+            "crypto/x509/t_crl.o" =>
+                [
+                    "crypto/x509/t_crl.c",
+                ],
+            "crypto/x509/t_req.o" =>
+                [
+                    "crypto/x509/t_req.c",
+                ],
+            "crypto/x509/t_x509.o" =>
+                [
+                    "crypto/x509/t_x509.c",
+                ],
+            "crypto/x509/x509_att.o" =>
+                [
+                    "crypto/x509/x509_att.c",
+                ],
+            "crypto/x509/x509_cmp.o" =>
+                [
+                    "crypto/x509/x509_cmp.c",
+                ],
+            "crypto/x509/x509_d2.o" =>
+                [
+                    "crypto/x509/x509_d2.c",
+                ],
+            "crypto/x509/x509_def.o" =>
+                [
+                    "crypto/x509/x509_def.c",
+                ],
+            "crypto/x509/x509_err.o" =>
+                [
+                    "crypto/x509/x509_err.c",
+                ],
+            "crypto/x509/x509_ext.o" =>
+                [
+                    "crypto/x509/x509_ext.c",
+                ],
+            "crypto/x509/x509_lu.o" =>
+                [
+                    "crypto/x509/x509_lu.c",
+                ],
+            "crypto/x509/x509_obj.o" =>
+                [
+                    "crypto/x509/x509_obj.c",
+                ],
+            "crypto/x509/x509_r2x.o" =>
+                [
+                    "crypto/x509/x509_r2x.c",
+                ],
+            "crypto/x509/x509_req.o" =>
+                [
+                    "crypto/x509/x509_req.c",
+                ],
+            "crypto/x509/x509_set.o" =>
+                [
+                    "crypto/x509/x509_set.c",
+                ],
+            "crypto/x509/x509_trs.o" =>
+                [
+                    "crypto/x509/x509_trs.c",
+                ],
+            "crypto/x509/x509_txt.o" =>
+                [
+                    "crypto/x509/x509_txt.c",
+                ],
+            "crypto/x509/x509_v3.o" =>
+                [
+                    "crypto/x509/x509_v3.c",
+                ],
+            "crypto/x509/x509_vfy.o" =>
+                [
+                    "crypto/x509/x509_vfy.c",
+                ],
+            "crypto/x509/x509_vpm.o" =>
+                [
+                    "crypto/x509/x509_vpm.c",
+                ],
+            "crypto/x509/x509cset.o" =>
+                [
+                    "crypto/x509/x509cset.c",
+                ],
+            "crypto/x509/x509name.o" =>
+                [
+                    "crypto/x509/x509name.c",
+                ],
+            "crypto/x509/x509rset.o" =>
+                [
+                    "crypto/x509/x509rset.c",
+                ],
+            "crypto/x509/x509spki.o" =>
+                [
+                    "crypto/x509/x509spki.c",
+                ],
+            "crypto/x509/x509type.o" =>
+                [
+                    "crypto/x509/x509type.c",
+                ],
+            "crypto/x509/x_all.o" =>
+                [
+                    "crypto/x509/x_all.c",
+                ],
+            "crypto/x509/x_attrib.o" =>
+                [
+                    "crypto/x509/x_attrib.c",
+                ],
+            "crypto/x509/x_crl.o" =>
+                [
+                    "crypto/x509/x_crl.c",
+                ],
+            "crypto/x509/x_exten.o" =>
+                [
+                    "crypto/x509/x_exten.c",
+                ],
+            "crypto/x509/x_name.o" =>
+                [
+                    "crypto/x509/x_name.c",
+                ],
+            "crypto/x509/x_pubkey.o" =>
+                [
+                    "crypto/x509/x_pubkey.c",
+                ],
+            "crypto/x509/x_req.o" =>
+                [
+                    "crypto/x509/x_req.c",
+                ],
+            "crypto/x509/x_x509.o" =>
+                [
+                    "crypto/x509/x_x509.c",
+                ],
+            "crypto/x509/x_x509a.o" =>
+                [
+                    "crypto/x509/x_x509a.c",
+                ],
+            "crypto/x509v3/pcy_cache.o" =>
+                [
+                    "crypto/x509v3/pcy_cache.c",
+                ],
+            "crypto/x509v3/pcy_data.o" =>
+                [
+                    "crypto/x509v3/pcy_data.c",
+                ],
+            "crypto/x509v3/pcy_lib.o" =>
+                [
+                    "crypto/x509v3/pcy_lib.c",
+                ],
+            "crypto/x509v3/pcy_map.o" =>
+                [
+                    "crypto/x509v3/pcy_map.c",
+                ],
+            "crypto/x509v3/pcy_node.o" =>
+                [
+                    "crypto/x509v3/pcy_node.c",
+                ],
+            "crypto/x509v3/pcy_tree.o" =>
+                [
+                    "crypto/x509v3/pcy_tree.c",
+                ],
+            "crypto/x509v3/v3_addr.o" =>
+                [
+                    "crypto/x509v3/v3_addr.c",
+                ],
+            "crypto/x509v3/v3_akey.o" =>
+                [
+                    "crypto/x509v3/v3_akey.c",
+                ],
+            "crypto/x509v3/v3_akeya.o" =>
+                [
+                    "crypto/x509v3/v3_akeya.c",
+                ],
+            "crypto/x509v3/v3_alt.o" =>
+                [
+                    "crypto/x509v3/v3_alt.c",
+                ],
+            "crypto/x509v3/v3_asid.o" =>
+                [
+                    "crypto/x509v3/v3_asid.c",
+                ],
+            "crypto/x509v3/v3_bcons.o" =>
+                [
+                    "crypto/x509v3/v3_bcons.c",
+                ],
+            "crypto/x509v3/v3_bitst.o" =>
+                [
+                    "crypto/x509v3/v3_bitst.c",
+                ],
+            "crypto/x509v3/v3_conf.o" =>
+                [
+                    "crypto/x509v3/v3_conf.c",
+                ],
+            "crypto/x509v3/v3_cpols.o" =>
+                [
+                    "crypto/x509v3/v3_cpols.c",
+                ],
+            "crypto/x509v3/v3_crld.o" =>
+                [
+                    "crypto/x509v3/v3_crld.c",
+                ],
+            "crypto/x509v3/v3_enum.o" =>
+                [
+                    "crypto/x509v3/v3_enum.c",
+                ],
+            "crypto/x509v3/v3_extku.o" =>
+                [
+                    "crypto/x509v3/v3_extku.c",
+                ],
+            "crypto/x509v3/v3_genn.o" =>
+                [
+                    "crypto/x509v3/v3_genn.c",
+                ],
+            "crypto/x509v3/v3_ia5.o" =>
+                [
+                    "crypto/x509v3/v3_ia5.c",
+                ],
+            "crypto/x509v3/v3_info.o" =>
+                [
+                    "crypto/x509v3/v3_info.c",
+                ],
+            "crypto/x509v3/v3_int.o" =>
+                [
+                    "crypto/x509v3/v3_int.c",
+                ],
+            "crypto/x509v3/v3_lib.o" =>
+                [
+                    "crypto/x509v3/v3_lib.c",
+                ],
+            "crypto/x509v3/v3_ncons.o" =>
+                [
+                    "crypto/x509v3/v3_ncons.c",
+                ],
+            "crypto/x509v3/v3_pci.o" =>
+                [
+                    "crypto/x509v3/v3_pci.c",
+                ],
+            "crypto/x509v3/v3_pcia.o" =>
+                [
+                    "crypto/x509v3/v3_pcia.c",
+                ],
+            "crypto/x509v3/v3_pcons.o" =>
+                [
+                    "crypto/x509v3/v3_pcons.c",
+                ],
+            "crypto/x509v3/v3_pku.o" =>
+                [
+                    "crypto/x509v3/v3_pku.c",
+                ],
+            "crypto/x509v3/v3_pmaps.o" =>
+                [
+                    "crypto/x509v3/v3_pmaps.c",
+                ],
+            "crypto/x509v3/v3_prn.o" =>
+                [
+                    "crypto/x509v3/v3_prn.c",
+                ],
+            "crypto/x509v3/v3_purp.o" =>
+                [
+                    "crypto/x509v3/v3_purp.c",
+                ],
+            "crypto/x509v3/v3_skey.o" =>
+                [
+                    "crypto/x509v3/v3_skey.c",
+                ],
+            "crypto/x509v3/v3_sxnet.o" =>
+                [
+                    "crypto/x509v3/v3_sxnet.c",
+                ],
+            "crypto/x509v3/v3_tlsf.o" =>
+                [
+                    "crypto/x509v3/v3_tlsf.c",
+                ],
+            "crypto/x509v3/v3_utl.o" =>
+                [
+                    "crypto/x509v3/v3_utl.c",
+                ],
+            "crypto/x509v3/v3err.o" =>
+                [
+                    "crypto/x509v3/v3err.c",
+                ],
+            "engines/e_capi.o" =>
+                [
+                    "engines/e_capi.c",
+                ],
+            "engines/e_padlock.o" =>
+                [
+                    "engines/e_padlock.c",
+                ],
+            "fuzz/asn1-test" =>
+                [
+                    "fuzz/asn1.o",
+                    "fuzz/test-corpus.o",
+                ],
+            "fuzz/asn1.o" =>
+                [
+                    "fuzz/asn1.c",
+                ],
+            "fuzz/asn1parse-test" =>
+                [
+                    "fuzz/asn1parse.o",
+                    "fuzz/test-corpus.o",
+                ],
+            "fuzz/asn1parse.o" =>
+                [
+                    "fuzz/asn1parse.c",
+                ],
+            "fuzz/bignum-test" =>
+                [
+                    "fuzz/bignum.o",
+                    "fuzz/test-corpus.o",
+                ],
+            "fuzz/bignum.o" =>
+                [
+                    "fuzz/bignum.c",
+                ],
+            "fuzz/bndiv-test" =>
+                [
+                    "fuzz/bndiv.o",
+                    "fuzz/test-corpus.o",
+                ],
+            "fuzz/bndiv.o" =>
+                [
+                    "fuzz/bndiv.c",
+                ],
+            "fuzz/cms-test" =>
+                [
+                    "fuzz/cms.o",
+                    "fuzz/test-corpus.o",
+                ],
+            "fuzz/cms.o" =>
+                [
+                    "fuzz/cms.c",
+                ],
+            "fuzz/conf-test" =>
+                [
+                    "fuzz/conf.o",
+                    "fuzz/test-corpus.o",
+                ],
+            "fuzz/conf.o" =>
+                [
+                    "fuzz/conf.c",
+                ],
+            "fuzz/crl-test" =>
+                [
+                    "fuzz/crl.o",
+                    "fuzz/test-corpus.o",
+                ],
+            "fuzz/crl.o" =>
+                [
+                    "fuzz/crl.c",
+                ],
+            "fuzz/ct-test" =>
+                [
+                    "fuzz/ct.o",
+                    "fuzz/test-corpus.o",
+                ],
+            "fuzz/ct.o" =>
+                [
+                    "fuzz/ct.c",
+                ],
+            "fuzz/server-test" =>
+                [
+                    "fuzz/server.o",
+                    "fuzz/test-corpus.o",
+                ],
+            "fuzz/server.o" =>
+                [
+                    "fuzz/server.c",
+                ],
+            "fuzz/test-corpus.o" =>
+                [
+                    "fuzz/test-corpus.c",
+                ],
+            "fuzz/x509-test" =>
+                [
+                    "fuzz/test-corpus.o",
+                    "fuzz/x509.o",
+                ],
+            "fuzz/x509.o" =>
+                [
+                    "fuzz/x509.c",
+                ],
+            "libcrypto" =>
+                [
+                    "crypto/aes/aes_cbc.o",
+                    "crypto/aes/aes_cfb.o",
+                    "crypto/aes/aes_core.o",
+                    "crypto/aes/aes_ecb.o",
+                    "crypto/aes/aes_ige.o",
+                    "crypto/aes/aes_misc.o",
+                    "crypto/aes/aes_ofb.o",
+                    "crypto/aes/aes_wrap.o",
+                    "crypto/asn1/a_bitstr.o",
+                    "crypto/asn1/a_d2i_fp.o",
+                    "crypto/asn1/a_digest.o",
+                    "crypto/asn1/a_dup.o",
+                    "crypto/asn1/a_gentm.o",
+                    "crypto/asn1/a_i2d_fp.o",
+                    "crypto/asn1/a_int.o",
+                    "crypto/asn1/a_mbstr.o",
+                    "crypto/asn1/a_object.o",
+                    "crypto/asn1/a_octet.o",
+                    "crypto/asn1/a_print.o",
+                    "crypto/asn1/a_sign.o",
+                    "crypto/asn1/a_strex.o",
+                    "crypto/asn1/a_strnid.o",
+                    "crypto/asn1/a_time.o",
+                    "crypto/asn1/a_type.o",
+                    "crypto/asn1/a_utctm.o",
+                    "crypto/asn1/a_utf8.o",
+                    "crypto/asn1/a_verify.o",
+                    "crypto/asn1/ameth_lib.o",
+                    "crypto/asn1/asn1_err.o",
+                    "crypto/asn1/asn1_gen.o",
+                    "crypto/asn1/asn1_lib.o",
+                    "crypto/asn1/asn1_par.o",
+                    "crypto/asn1/asn_mime.o",
+                    "crypto/asn1/asn_moid.o",
+                    "crypto/asn1/asn_mstbl.o",
+                    "crypto/asn1/asn_pack.o",
+                    "crypto/asn1/bio_asn1.o",
+                    "crypto/asn1/bio_ndef.o",
+                    "crypto/asn1/d2i_pr.o",
+                    "crypto/asn1/d2i_pu.o",
+                    "crypto/asn1/evp_asn1.o",
+                    "crypto/asn1/f_int.o",
+                    "crypto/asn1/f_string.o",
+                    "crypto/asn1/i2d_pr.o",
+                    "crypto/asn1/i2d_pu.o",
+                    "crypto/asn1/n_pkey.o",
+                    "crypto/asn1/nsseq.o",
+                    "crypto/asn1/p5_pbe.o",
+                    "crypto/asn1/p5_pbev2.o",
+                    "crypto/asn1/p5_scrypt.o",
+                    "crypto/asn1/p8_pkey.o",
+                    "crypto/asn1/t_bitst.o",
+                    "crypto/asn1/t_pkey.o",
+                    "crypto/asn1/t_spki.o",
+                    "crypto/asn1/tasn_dec.o",
+                    "crypto/asn1/tasn_enc.o",
+                    "crypto/asn1/tasn_fre.o",
+                    "crypto/asn1/tasn_new.o",
+                    "crypto/asn1/tasn_prn.o",
+                    "crypto/asn1/tasn_scn.o",
+                    "crypto/asn1/tasn_typ.o",
+                    "crypto/asn1/tasn_utl.o",
+                    "crypto/asn1/x_algor.o",
+                    "crypto/asn1/x_bignum.o",
+                    "crypto/asn1/x_info.o",
+                    "crypto/asn1/x_long.o",
+                    "crypto/asn1/x_pkey.o",
+                    "crypto/asn1/x_sig.o",
+                    "crypto/asn1/x_spki.o",
+                    "crypto/asn1/x_val.o",
+                    "crypto/async/arch/async_null.o",
+                    "crypto/async/arch/async_posix.o",
+                    "crypto/async/arch/async_win.o",
+                    "crypto/async/async.o",
+                    "crypto/async/async_err.o",
+                    "crypto/async/async_wait.o",
+                    "crypto/bf/bf_cfb64.o",
+                    "crypto/bf/bf_ecb.o",
+                    "crypto/bf/bf_enc.o",
+                    "crypto/bf/bf_ofb64.o",
+                    "crypto/bf/bf_skey.o",
+                    "crypto/bio/b_addr.o",
+                    "crypto/bio/b_dump.o",
+                    "crypto/bio/b_print.o",
+                    "crypto/bio/b_sock.o",
+                    "crypto/bio/b_sock2.o",
+                    "crypto/bio/bf_buff.o",
+                    "crypto/bio/bf_lbuf.o",
+                    "crypto/bio/bf_nbio.o",
+                    "crypto/bio/bf_null.o",
+                    "crypto/bio/bio_cb.o",
+                    "crypto/bio/bio_err.o",
+                    "crypto/bio/bio_lib.o",
+                    "crypto/bio/bio_meth.o",
+                    "crypto/bio/bss_acpt.o",
+                    "crypto/bio/bss_bio.o",
+                    "crypto/bio/bss_conn.o",
+                    "crypto/bio/bss_dgram.o",
+                    "crypto/bio/bss_fd.o",
+                    "crypto/bio/bss_file.o",
+                    "crypto/bio/bss_log.o",
+                    "crypto/bio/bss_mem.o",
+                    "crypto/bio/bss_null.o",
+                    "crypto/bio/bss_sock.o",
+                    "crypto/blake2/blake2b.o",
+                    "crypto/blake2/blake2s.o",
+                    "crypto/blake2/m_blake2b.o",
+                    "crypto/blake2/m_blake2s.o",
+                    "crypto/bn/bn_add.o",
+                    "crypto/bn/bn_asm.o",
+                    "crypto/bn/bn_blind.o",
+                    "crypto/bn/bn_const.o",
+                    "crypto/bn/bn_ctx.o",
+                    "crypto/bn/bn_depr.o",
+                    "crypto/bn/bn_dh.o",
+                    "crypto/bn/bn_div.o",
+                    "crypto/bn/bn_err.o",
+                    "crypto/bn/bn_exp.o",
+                    "crypto/bn/bn_exp2.o",
+                    "crypto/bn/bn_gcd.o",
+                    "crypto/bn/bn_gf2m.o",
+                    "crypto/bn/bn_intern.o",
+                    "crypto/bn/bn_kron.o",
+                    "crypto/bn/bn_lib.o",
+                    "crypto/bn/bn_mod.o",
+                    "crypto/bn/bn_mont.o",
+                    "crypto/bn/bn_mpi.o",
+                    "crypto/bn/bn_mul.o",
+                    "crypto/bn/bn_nist.o",
+                    "crypto/bn/bn_prime.o",
+                    "crypto/bn/bn_print.o",
+                    "crypto/bn/bn_rand.o",
+                    "crypto/bn/bn_recp.o",
+                    "crypto/bn/bn_shift.o",
+                    "crypto/bn/bn_sqr.o",
+                    "crypto/bn/bn_sqrt.o",
+                    "crypto/bn/bn_srp.o",
+                    "crypto/bn/bn_word.o",
+                    "crypto/bn/bn_x931p.o",
+                    "crypto/buffer/buf_err.o",
+                    "crypto/buffer/buffer.o",
+                    "crypto/camellia/camellia.o",
+                    "crypto/camellia/cmll_cbc.o",
+                    "crypto/camellia/cmll_cfb.o",
+                    "crypto/camellia/cmll_ctr.o",
+                    "crypto/camellia/cmll_ecb.o",
+                    "crypto/camellia/cmll_misc.o",
+                    "crypto/camellia/cmll_ofb.o",
+                    "crypto/cast/c_cfb64.o",
+                    "crypto/cast/c_ecb.o",
+                    "crypto/cast/c_enc.o",
+                    "crypto/cast/c_ofb64.o",
+                    "crypto/cast/c_skey.o",
+                    "crypto/chacha/chacha_enc.o",
+                    "crypto/cmac/cm_ameth.o",
+                    "crypto/cmac/cm_pmeth.o",
+                    "crypto/cmac/cmac.o",
+                    "crypto/cms/cms_asn1.o",
+                    "crypto/cms/cms_att.o",
+                    "crypto/cms/cms_cd.o",
+                    "crypto/cms/cms_dd.o",
+                    "crypto/cms/cms_enc.o",
+                    "crypto/cms/cms_env.o",
+                    "crypto/cms/cms_err.o",
+                    "crypto/cms/cms_ess.o",
+                    "crypto/cms/cms_io.o",
+                    "crypto/cms/cms_kari.o",
+                    "crypto/cms/cms_lib.o",
+                    "crypto/cms/cms_pwri.o",
+                    "crypto/cms/cms_sd.o",
+                    "crypto/cms/cms_smime.o",
+                    "crypto/comp/c_zlib.o",
+                    "crypto/comp/comp_err.o",
+                    "crypto/comp/comp_lib.o",
+                    "crypto/conf/conf_api.o",
+                    "crypto/conf/conf_def.o",
+                    "crypto/conf/conf_err.o",
+                    "crypto/conf/conf_lib.o",
+                    "crypto/conf/conf_mall.o",
+                    "crypto/conf/conf_mod.o",
+                    "crypto/conf/conf_sap.o",
+                    "crypto/cpt_err.o",
+                    "crypto/cryptlib.o",
+                    "crypto/ct/ct_b64.o",
+                    "crypto/ct/ct_err.o",
+                    "crypto/ct/ct_log.o",
+                    "crypto/ct/ct_oct.o",
+                    "crypto/ct/ct_policy.o",
+                    "crypto/ct/ct_prn.o",
+                    "crypto/ct/ct_sct.o",
+                    "crypto/ct/ct_sct_ctx.o",
+                    "crypto/ct/ct_vfy.o",
+                    "crypto/ct/ct_x509v3.o",
+                    "crypto/cversion.o",
+                    "crypto/des/cbc_cksm.o",
+                    "crypto/des/cbc_enc.o",
+                    "crypto/des/cfb64ede.o",
+                    "crypto/des/cfb64enc.o",
+                    "crypto/des/cfb_enc.o",
+                    "crypto/des/des_enc.o",
+                    "crypto/des/ecb3_enc.o",
+                    "crypto/des/ecb_enc.o",
+                    "crypto/des/fcrypt.o",
+                    "crypto/des/fcrypt_b.o",
+                    "crypto/des/ofb64ede.o",
+                    "crypto/des/ofb64enc.o",
+                    "crypto/des/ofb_enc.o",
+                    "crypto/des/pcbc_enc.o",
+                    "crypto/des/qud_cksm.o",
+                    "crypto/des/rand_key.o",
+                    "crypto/des/rpc_enc.o",
+                    "crypto/des/set_key.o",
+                    "crypto/des/str2key.o",
+                    "crypto/des/xcbc_enc.o",
+                    "crypto/dh/dh_ameth.o",
+                    "crypto/dh/dh_asn1.o",
+                    "crypto/dh/dh_check.o",
+                    "crypto/dh/dh_depr.o",
+                    "crypto/dh/dh_err.o",
+                    "crypto/dh/dh_gen.o",
+                    "crypto/dh/dh_kdf.o",
+                    "crypto/dh/dh_key.o",
+                    "crypto/dh/dh_lib.o",
+                    "crypto/dh/dh_meth.o",
+                    "crypto/dh/dh_pmeth.o",
+                    "crypto/dh/dh_prn.o",
+                    "crypto/dh/dh_rfc5114.o",
+                    "crypto/dsa/dsa_ameth.o",
+                    "crypto/dsa/dsa_asn1.o",
+                    "crypto/dsa/dsa_depr.o",
+                    "crypto/dsa/dsa_err.o",
+                    "crypto/dsa/dsa_gen.o",
+                    "crypto/dsa/dsa_key.o",
+                    "crypto/dsa/dsa_lib.o",
+                    "crypto/dsa/dsa_meth.o",
+                    "crypto/dsa/dsa_ossl.o",
+                    "crypto/dsa/dsa_pmeth.o",
+                    "crypto/dsa/dsa_prn.o",
+                    "crypto/dsa/dsa_sign.o",
+                    "crypto/dsa/dsa_vrf.o",
+                    "crypto/dso/dso_dl.o",
+                    "crypto/dso/dso_dlfcn.o",
+                    "crypto/dso/dso_err.o",
+                    "crypto/dso/dso_lib.o",
+                    "crypto/dso/dso_openssl.o",
+                    "crypto/dso/dso_vms.o",
+                    "crypto/dso/dso_win32.o",
+                    "crypto/ebcdic.o",
+                    "crypto/ec/curve25519.o",
+                    "crypto/ec/ec2_mult.o",
+                    "crypto/ec/ec2_oct.o",
+                    "crypto/ec/ec2_smpl.o",
+                    "crypto/ec/ec_ameth.o",
+                    "crypto/ec/ec_asn1.o",
+                    "crypto/ec/ec_check.o",
+                    "crypto/ec/ec_curve.o",
+                    "crypto/ec/ec_cvt.o",
+                    "crypto/ec/ec_err.o",
+                    "crypto/ec/ec_key.o",
+                    "crypto/ec/ec_kmeth.o",
+                    "crypto/ec/ec_lib.o",
+                    "crypto/ec/ec_mult.o",
+                    "crypto/ec/ec_oct.o",
+                    "crypto/ec/ec_pmeth.o",
+                    "crypto/ec/ec_print.o",
+                    "crypto/ec/ecdh_kdf.o",
+                    "crypto/ec/ecdh_ossl.o",
+                    "crypto/ec/ecdsa_ossl.o",
+                    "crypto/ec/ecdsa_sign.o",
+                    "crypto/ec/ecdsa_vrf.o",
+                    "crypto/ec/eck_prn.o",
+                    "crypto/ec/ecp_mont.o",
+                    "crypto/ec/ecp_nist.o",
+                    "crypto/ec/ecp_nistp224.o",
+                    "crypto/ec/ecp_nistp256.o",
+                    "crypto/ec/ecp_nistp521.o",
+                    "crypto/ec/ecp_nistputil.o",
+                    "crypto/ec/ecp_oct.o",
+                    "crypto/ec/ecp_smpl.o",
+                    "crypto/ec/ecx_meth.o",
+                    "crypto/engine/eng_all.o",
+                    "crypto/engine/eng_cnf.o",
+                    "crypto/engine/eng_cryptodev.o",
+                    "crypto/engine/eng_ctrl.o",
+                    "crypto/engine/eng_dyn.o",
+                    "crypto/engine/eng_err.o",
+                    "crypto/engine/eng_fat.o",
+                    "crypto/engine/eng_init.o",
+                    "crypto/engine/eng_lib.o",
+                    "crypto/engine/eng_list.o",
+                    "crypto/engine/eng_openssl.o",
+                    "crypto/engine/eng_pkey.o",
+                    "crypto/engine/eng_rdrand.o",
+                    "crypto/engine/eng_table.o",
+                    "crypto/engine/tb_asnmth.o",
+                    "crypto/engine/tb_cipher.o",
+                    "crypto/engine/tb_dh.o",
+                    "crypto/engine/tb_digest.o",
+                    "crypto/engine/tb_dsa.o",
+                    "crypto/engine/tb_eckey.o",
+                    "crypto/engine/tb_pkmeth.o",
+                    "crypto/engine/tb_rand.o",
+                    "crypto/engine/tb_rsa.o",
+                    "crypto/err/err.o",
+                    "crypto/err/err_all.o",
+                    "crypto/err/err_prn.o",
+                    "crypto/evp/bio_b64.o",
+                    "crypto/evp/bio_enc.o",
+                    "crypto/evp/bio_md.o",
+                    "crypto/evp/bio_ok.o",
+                    "crypto/evp/c_allc.o",
+                    "crypto/evp/c_alld.o",
+                    "crypto/evp/cmeth_lib.o",
+                    "crypto/evp/digest.o",
+                    "crypto/evp/e_aes.o",
+                    "crypto/evp/e_aes_cbc_hmac_sha1.o",
+                    "crypto/evp/e_aes_cbc_hmac_sha256.o",
+                    "crypto/evp/e_bf.o",
+                    "crypto/evp/e_camellia.o",
+                    "crypto/evp/e_cast.o",
+                    "crypto/evp/e_chacha20_poly1305.o",
+                    "crypto/evp/e_des.o",
+                    "crypto/evp/e_des3.o",
+                    "crypto/evp/e_idea.o",
+                    "crypto/evp/e_null.o",
+                    "crypto/evp/e_old.o",
+                    "crypto/evp/e_rc2.o",
+                    "crypto/evp/e_rc4.o",
+                    "crypto/evp/e_rc4_hmac_md5.o",
+                    "crypto/evp/e_rc5.o",
+                    "crypto/evp/e_seed.o",
+                    "crypto/evp/e_xcbc_d.o",
+                    "crypto/evp/encode.o",
+                    "crypto/evp/evp_cnf.o",
+                    "crypto/evp/evp_enc.o",
+                    "crypto/evp/evp_err.o",
+                    "crypto/evp/evp_key.o",
+                    "crypto/evp/evp_lib.o",
+                    "crypto/evp/evp_pbe.o",
+                    "crypto/evp/evp_pkey.o",
+                    "crypto/evp/m_md2.o",
+                    "crypto/evp/m_md4.o",
+                    "crypto/evp/m_md5.o",
+                    "crypto/evp/m_md5_sha1.o",
+                    "crypto/evp/m_mdc2.o",
+                    "crypto/evp/m_null.o",
+                    "crypto/evp/m_ripemd.o",
+                    "crypto/evp/m_sha1.o",
+                    "crypto/evp/m_sigver.o",
+                    "crypto/evp/m_wp.o",
+                    "crypto/evp/names.o",
+                    "crypto/evp/p5_crpt.o",
+                    "crypto/evp/p5_crpt2.o",
+                    "crypto/evp/p_dec.o",
+                    "crypto/evp/p_enc.o",
+                    "crypto/evp/p_lib.o",
+                    "crypto/evp/p_open.o",
+                    "crypto/evp/p_seal.o",
+                    "crypto/evp/p_sign.o",
+                    "crypto/evp/p_verify.o",
+                    "crypto/evp/pmeth_fn.o",
+                    "crypto/evp/pmeth_gn.o",
+                    "crypto/evp/pmeth_lib.o",
+                    "crypto/evp/scrypt.o",
+                    "crypto/ex_data.o",
+                    "crypto/hmac/hm_ameth.o",
+                    "crypto/hmac/hm_pmeth.o",
+                    "crypto/hmac/hmac.o",
+                    "crypto/idea/i_cbc.o",
+                    "crypto/idea/i_cfb64.o",
+                    "crypto/idea/i_ecb.o",
+                    "crypto/idea/i_ofb64.o",
+                    "crypto/idea/i_skey.o",
+                    "crypto/init.o",
+                    "crypto/kdf/hkdf.o",
+                    "crypto/kdf/kdf_err.o",
+                    "crypto/kdf/tls1_prf.o",
+                    "crypto/lhash/lh_stats.o",
+                    "crypto/lhash/lhash.o",
+                    "crypto/md4/md4_dgst.o",
+                    "crypto/md4/md4_one.o",
+                    "crypto/md5/md5_dgst.o",
+                    "crypto/md5/md5_one.o",
+                    "crypto/mdc2/mdc2_one.o",
+                    "crypto/mdc2/mdc2dgst.o",
+                    "crypto/mem.o",
+                    "crypto/mem_clr.o",
+                    "crypto/mem_dbg.o",
+                    "crypto/mem_sec.o",
+                    "crypto/modes/cbc128.o",
+                    "crypto/modes/ccm128.o",
+                    "crypto/modes/cfb128.o",
+                    "crypto/modes/ctr128.o",
+                    "crypto/modes/cts128.o",
+                    "crypto/modes/gcm128.o",
+                    "crypto/modes/ocb128.o",
+                    "crypto/modes/ofb128.o",
+                    "crypto/modes/wrap128.o",
+                    "crypto/modes/xts128.o",
+                    "crypto/o_dir.o",
+                    "crypto/o_fips.o",
+                    "crypto/o_fopen.o",
+                    "crypto/o_init.o",
+                    "crypto/o_str.o",
+                    "crypto/o_time.o",
+                    "crypto/objects/o_names.o",
+                    "crypto/objects/obj_dat.o",
+                    "crypto/objects/obj_err.o",
+                    "crypto/objects/obj_lib.o",
+                    "crypto/objects/obj_xref.o",
+                    "crypto/ocsp/ocsp_asn.o",
+                    "crypto/ocsp/ocsp_cl.o",
+                    "crypto/ocsp/ocsp_err.o",
+                    "crypto/ocsp/ocsp_ext.o",
+                    "crypto/ocsp/ocsp_ht.o",
+                    "crypto/ocsp/ocsp_lib.o",
+                    "crypto/ocsp/ocsp_prn.o",
+                    "crypto/ocsp/ocsp_srv.o",
+                    "crypto/ocsp/ocsp_vfy.o",
+                    "crypto/ocsp/v3_ocsp.o",
+                    "crypto/pem/pem_all.o",
+                    "crypto/pem/pem_err.o",
+                    "crypto/pem/pem_info.o",
+                    "crypto/pem/pem_lib.o",
+                    "crypto/pem/pem_oth.o",
+                    "crypto/pem/pem_pk8.o",
+                    "crypto/pem/pem_pkey.o",
+                    "crypto/pem/pem_sign.o",
+                    "crypto/pem/pem_x509.o",
+                    "crypto/pem/pem_xaux.o",
+                    "crypto/pem/pvkfmt.o",
+                    "crypto/pkcs12/p12_add.o",
+                    "crypto/pkcs12/p12_asn.o",
+                    "crypto/pkcs12/p12_attr.o",
+                    "crypto/pkcs12/p12_crpt.o",
+                    "crypto/pkcs12/p12_crt.o",
+                    "crypto/pkcs12/p12_decr.o",
+                    "crypto/pkcs12/p12_init.o",
+                    "crypto/pkcs12/p12_key.o",
+                    "crypto/pkcs12/p12_kiss.o",
+                    "crypto/pkcs12/p12_mutl.o",
+                    "crypto/pkcs12/p12_npas.o",
+                    "crypto/pkcs12/p12_p8d.o",
+                    "crypto/pkcs12/p12_p8e.o",
+                    "crypto/pkcs12/p12_sbag.o",
+                    "crypto/pkcs12/p12_utl.o",
+                    "crypto/pkcs12/pk12err.o",
+                    "crypto/pkcs7/bio_pk7.o",
+                    "crypto/pkcs7/pk7_asn1.o",
+                    "crypto/pkcs7/pk7_attr.o",
+                    "crypto/pkcs7/pk7_doit.o",
+                    "crypto/pkcs7/pk7_lib.o",
+                    "crypto/pkcs7/pk7_mime.o",
+                    "crypto/pkcs7/pk7_smime.o",
+                    "crypto/pkcs7/pkcs7err.o",
+                    "crypto/poly1305/poly1305.o",
+                    "crypto/rand/md_rand.o",
+                    "crypto/rand/rand_egd.o",
+                    "crypto/rand/rand_err.o",
+                    "crypto/rand/rand_lib.o",
+                    "crypto/rand/rand_unix.o",
+                    "crypto/rand/rand_vms.o",
+                    "crypto/rand/rand_win.o",
+                    "crypto/rand/randfile.o",
+                    "crypto/rc2/rc2_cbc.o",
+                    "crypto/rc2/rc2_ecb.o",
+                    "crypto/rc2/rc2_skey.o",
+                    "crypto/rc2/rc2cfb64.o",
+                    "crypto/rc2/rc2ofb64.o",
+                    "crypto/rc4/rc4_enc.o",
+                    "crypto/rc4/rc4_skey.o",
+                    "crypto/ripemd/rmd_dgst.o",
+                    "crypto/ripemd/rmd_one.o",
+                    "crypto/rsa/rsa_ameth.o",
+                    "crypto/rsa/rsa_asn1.o",
+                    "crypto/rsa/rsa_chk.o",
+                    "crypto/rsa/rsa_crpt.o",
+                    "crypto/rsa/rsa_depr.o",
+                    "crypto/rsa/rsa_err.o",
+                    "crypto/rsa/rsa_gen.o",
+                    "crypto/rsa/rsa_lib.o",
+                    "crypto/rsa/rsa_meth.o",
+                    "crypto/rsa/rsa_none.o",
+                    "crypto/rsa/rsa_null.o",
+                    "crypto/rsa/rsa_oaep.o",
+                    "crypto/rsa/rsa_ossl.o",
+                    "crypto/rsa/rsa_pk1.o",
+                    "crypto/rsa/rsa_pmeth.o",
+                    "crypto/rsa/rsa_prn.o",
+                    "crypto/rsa/rsa_pss.o",
+                    "crypto/rsa/rsa_saos.o",
+                    "crypto/rsa/rsa_sign.o",
+                    "crypto/rsa/rsa_ssl.o",
+                    "crypto/rsa/rsa_x931.o",
+                    "crypto/rsa/rsa_x931g.o",
+                    "crypto/seed/seed.o",
+                    "crypto/seed/seed_cbc.o",
+                    "crypto/seed/seed_cfb.o",
+                    "crypto/seed/seed_ecb.o",
+                    "crypto/seed/seed_ofb.o",
+                    "crypto/sha/sha1_one.o",
+                    "crypto/sha/sha1dgst.o",
+                    "crypto/sha/sha256.o",
+                    "crypto/sha/sha512.o",
+                    "crypto/srp/srp_lib.o",
+                    "crypto/srp/srp_vfy.o",
+                    "crypto/stack/stack.o",
+                    "crypto/threads_none.o",
+                    "crypto/threads_pthread.o",
+                    "crypto/threads_win.o",
+                    "crypto/ts/ts_asn1.o",
+                    "crypto/ts/ts_conf.o",
+                    "crypto/ts/ts_err.o",
+                    "crypto/ts/ts_lib.o",
+                    "crypto/ts/ts_req_print.o",
+                    "crypto/ts/ts_req_utils.o",
+                    "crypto/ts/ts_rsp_print.o",
+                    "crypto/ts/ts_rsp_sign.o",
+                    "crypto/ts/ts_rsp_utils.o",
+                    "crypto/ts/ts_rsp_verify.o",
+                    "crypto/ts/ts_verify_ctx.o",
+                    "crypto/txt_db/txt_db.o",
+                    "crypto/uid.o",
+                    "crypto/whrlpool/wp_block.o",
+                    "crypto/whrlpool/wp_dgst.o",
+                    "crypto/x509/by_dir.o",
+                    "crypto/x509/by_file.o",
+                    "crypto/x509/t_crl.o",
+                    "crypto/x509/t_req.o",
+                    "crypto/x509/t_x509.o",
+                    "crypto/x509/x509_att.o",
+                    "crypto/x509/x509_cmp.o",
+                    "crypto/x509/x509_d2.o",
+                    "crypto/x509/x509_def.o",
+                    "crypto/x509/x509_err.o",
+                    "crypto/x509/x509_ext.o",
+                    "crypto/x509/x509_lu.o",
+                    "crypto/x509/x509_obj.o",
+                    "crypto/x509/x509_r2x.o",
+                    "crypto/x509/x509_req.o",
+                    "crypto/x509/x509_set.o",
+                    "crypto/x509/x509_trs.o",
+                    "crypto/x509/x509_txt.o",
+                    "crypto/x509/x509_v3.o",
+                    "crypto/x509/x509_vfy.o",
+                    "crypto/x509/x509_vpm.o",
+                    "crypto/x509/x509cset.o",
+                    "crypto/x509/x509name.o",
+                    "crypto/x509/x509rset.o",
+                    "crypto/x509/x509spki.o",
+                    "crypto/x509/x509type.o",
+                    "crypto/x509/x_all.o",
+                    "crypto/x509/x_attrib.o",
+                    "crypto/x509/x_crl.o",
+                    "crypto/x509/x_exten.o",
+                    "crypto/x509/x_name.o",
+                    "crypto/x509/x_pubkey.o",
+                    "crypto/x509/x_req.o",
+                    "crypto/x509/x_x509.o",
+                    "crypto/x509/x_x509a.o",
+                    "crypto/x509v3/pcy_cache.o",
+                    "crypto/x509v3/pcy_data.o",
+                    "crypto/x509v3/pcy_lib.o",
+                    "crypto/x509v3/pcy_map.o",
+                    "crypto/x509v3/pcy_node.o",
+                    "crypto/x509v3/pcy_tree.o",
+                    "crypto/x509v3/v3_addr.o",
+                    "crypto/x509v3/v3_akey.o",
+                    "crypto/x509v3/v3_akeya.o",
+                    "crypto/x509v3/v3_alt.o",
+                    "crypto/x509v3/v3_asid.o",
+                    "crypto/x509v3/v3_bcons.o",
+                    "crypto/x509v3/v3_bitst.o",
+                    "crypto/x509v3/v3_conf.o",
+                    "crypto/x509v3/v3_cpols.o",
+                    "crypto/x509v3/v3_crld.o",
+                    "crypto/x509v3/v3_enum.o",
+                    "crypto/x509v3/v3_extku.o",
+                    "crypto/x509v3/v3_genn.o",
+                    "crypto/x509v3/v3_ia5.o",
+                    "crypto/x509v3/v3_info.o",
+                    "crypto/x509v3/v3_int.o",
+                    "crypto/x509v3/v3_lib.o",
+                    "crypto/x509v3/v3_ncons.o",
+                    "crypto/x509v3/v3_pci.o",
+                    "crypto/x509v3/v3_pcia.o",
+                    "crypto/x509v3/v3_pcons.o",
+                    "crypto/x509v3/v3_pku.o",
+                    "crypto/x509v3/v3_pmaps.o",
+                    "crypto/x509v3/v3_prn.o",
+                    "crypto/x509v3/v3_purp.o",
+                    "crypto/x509v3/v3_skey.o",
+                    "crypto/x509v3/v3_sxnet.o",
+                    "crypto/x509v3/v3_tlsf.o",
+                    "crypto/x509v3/v3_utl.o",
+                    "crypto/x509v3/v3err.o",
+                    "engines/e_capi.o",
+                    "engines/e_padlock.o",
+                ],
+            "libssl" =>
+                [
+                    "ssl/bio_ssl.o",
+                    "ssl/d1_lib.o",
+                    "ssl/d1_msg.o",
+                    "ssl/d1_srtp.o",
+                    "ssl/methods.o",
+                    "ssl/pqueue.o",
+                    "ssl/record/dtls1_bitmap.o",
+                    "ssl/record/rec_layer_d1.o",
+                    "ssl/record/rec_layer_s3.o",
+                    "ssl/record/ssl3_buffer.o",
+                    "ssl/record/ssl3_record.o",
+                    "ssl/s3_cbc.o",
+                    "ssl/s3_enc.o",
+                    "ssl/s3_lib.o",
+                    "ssl/s3_msg.o",
+                    "ssl/ssl_asn1.o",
+                    "ssl/ssl_cert.o",
+                    "ssl/ssl_ciph.o",
+                    "ssl/ssl_conf.o",
+                    "ssl/ssl_err.o",
+                    "ssl/ssl_init.o",
+                    "ssl/ssl_lib.o",
+                    "ssl/ssl_mcnf.o",
+                    "ssl/ssl_rsa.o",
+                    "ssl/ssl_sess.o",
+                    "ssl/ssl_stat.o",
+                    "ssl/ssl_txt.o",
+                    "ssl/ssl_utst.o",
+                    "ssl/statem/statem.o",
+                    "ssl/statem/statem_clnt.o",
+                    "ssl/statem/statem_dtls.o",
+                    "ssl/statem/statem_lib.o",
+                    "ssl/statem/statem_srvr.o",
+                    "ssl/t1_enc.o",
+                    "ssl/t1_ext.o",
+                    "ssl/t1_lib.o",
+                    "ssl/t1_reneg.o",
+                    "ssl/t1_trce.o",
+                    "ssl/tls_srp.o",
+                ],
+            "ssl/bio_ssl.o" =>
+                [
+                    "ssl/bio_ssl.c",
+                ],
+            "ssl/d1_lib.o" =>
+                [
+                    "ssl/d1_lib.c",
+                ],
+            "ssl/d1_msg.o" =>
+                [
+                    "ssl/d1_msg.c",
+                ],
+            "ssl/d1_srtp.o" =>
+                [
+                    "ssl/d1_srtp.c",
+                ],
+            "ssl/methods.o" =>
+                [
+                    "ssl/methods.c",
+                ],
+            "ssl/pqueue.o" =>
+                [
+                    "ssl/pqueue.c",
+                ],
+            "ssl/record/dtls1_bitmap.o" =>
+                [
+                    "ssl/record/dtls1_bitmap.c",
+                ],
+            "ssl/record/rec_layer_d1.o" =>
+                [
+                    "ssl/record/rec_layer_d1.c",
+                ],
+            "ssl/record/rec_layer_s3.o" =>
+                [
+                    "ssl/record/rec_layer_s3.c",
+                ],
+            "ssl/record/ssl3_buffer.o" =>
+                [
+                    "ssl/record/ssl3_buffer.c",
+                ],
+            "ssl/record/ssl3_record.o" =>
+                [
+                    "ssl/record/ssl3_record.c",
+                ],
+            "ssl/s3_cbc.o" =>
+                [
+                    "ssl/s3_cbc.c",
+                ],
+            "ssl/s3_enc.o" =>
+                [
+                    "ssl/s3_enc.c",
+                ],
+            "ssl/s3_lib.o" =>
+                [
+                    "ssl/s3_lib.c",
+                ],
+            "ssl/s3_msg.o" =>
+                [
+                    "ssl/s3_msg.c",
+                ],
+            "ssl/ssl_asn1.o" =>
+                [
+                    "ssl/ssl_asn1.c",
+                ],
+            "ssl/ssl_cert.o" =>
+                [
+                    "ssl/ssl_cert.c",
+                ],
+            "ssl/ssl_ciph.o" =>
+                [
+                    "ssl/ssl_ciph.c",
+                ],
+            "ssl/ssl_conf.o" =>
+                [
+                    "ssl/ssl_conf.c",
+                ],
+            "ssl/ssl_err.o" =>
+                [
+                    "ssl/ssl_err.c",
+                ],
+            "ssl/ssl_init.o" =>
+                [
+                    "ssl/ssl_init.c",
+                ],
+            "ssl/ssl_lib.o" =>
+                [
+                    "ssl/ssl_lib.c",
+                ],
+            "ssl/ssl_mcnf.o" =>
+                [
+                    "ssl/ssl_mcnf.c",
+                ],
+            "ssl/ssl_rsa.o" =>
+                [
+                    "ssl/ssl_rsa.c",
+                ],
+            "ssl/ssl_sess.o" =>
+                [
+                    "ssl/ssl_sess.c",
+                ],
+            "ssl/ssl_stat.o" =>
+                [
+                    "ssl/ssl_stat.c",
+                ],
+            "ssl/ssl_txt.o" =>
+                [
+                    "ssl/ssl_txt.c",
+                ],
+            "ssl/ssl_utst.o" =>
+                [
+                    "ssl/ssl_utst.c",
+                ],
+            "ssl/statem/statem.o" =>
+                [
+                    "ssl/statem/statem.c",
+                ],
+            "ssl/statem/statem_clnt.o" =>
+                [
+                    "ssl/statem/statem_clnt.c",
+                ],
+            "ssl/statem/statem_dtls.o" =>
+                [
+                    "ssl/statem/statem_dtls.c",
+                ],
+            "ssl/statem/statem_lib.o" =>
+                [
+                    "ssl/statem/statem_lib.c",
+                ],
+            "ssl/statem/statem_srvr.o" =>
+                [
+                    "ssl/statem/statem_srvr.c",
+                ],
+            "ssl/t1_enc.o" =>
+                [
+                    "ssl/t1_enc.c",
+                ],
+            "ssl/t1_ext.o" =>
+                [
+                    "ssl/t1_ext.c",
+                ],
+            "ssl/t1_lib.o" =>
+                [
+                    "ssl/t1_lib.c",
+                ],
+            "ssl/t1_reneg.o" =>
+                [
+                    "ssl/t1_reneg.c",
+                ],
+            "ssl/t1_trce.o" =>
+                [
+                    "ssl/t1_trce.c",
+                ],
+            "ssl/tls_srp.o" =>
+                [
+                    "ssl/tls_srp.c",
+                ],
+            "test/aborttest" =>
+                [
+                    "test/aborttest.o",
+                ],
+            "test/aborttest.o" =>
+                [
+                    "test/aborttest.c",
+                ],
+            "test/afalgtest" =>
+                [
+                    "test/afalgtest.o",
+                ],
+            "test/afalgtest.o" =>
+                [
+                    "test/afalgtest.c",
+                ],
+            "test/asynciotest" =>
+                [
+                    "test/asynciotest.o",
+                    "test/ssltestlib.o",
+                ],
+            "test/asynciotest.o" =>
+                [
+                    "test/asynciotest.c",
+                ],
+            "test/asynctest" =>
+                [
+                    "test/asynctest.o",
+                ],
+            "test/asynctest.o" =>
+                [
+                    "test/asynctest.c",
+                ],
+            "test/bad_dtls_test" =>
+                [
+                    "test/bad_dtls_test.o",
+                ],
+            "test/bad_dtls_test.o" =>
+                [
+                    "test/bad_dtls_test.c",
+                ],
+            "test/bftest" =>
+                [
+                    "test/bftest.o",
+                ],
+            "test/bftest.o" =>
+                [
+                    "test/bftest.c",
+                ],
+            "test/bio_enc_test" =>
+                [
+                    "test/bio_enc_test.o",
+                ],
+            "test/bio_enc_test.o" =>
+                [
+                    "test/bio_enc_test.c",
+                ],
+            "test/bioprinttest" =>
+                [
+                    "test/bioprinttest.o",
+                ],
+            "test/bioprinttest.o" =>
+                [
+                    "test/bioprinttest.c",
+                ],
+            "test/bntest" =>
+                [
+                    "test/bntest.o",
+                ],
+            "test/bntest.o" =>
+                [
+                    "test/bntest.c",
+                ],
+            "test/buildtest_aes" =>
+                [
+                    "test/buildtest_aes.o",
+                ],
+            "test/buildtest_aes.o" =>
+                [
+                    "test/buildtest_aes.c",
+                ],
+            "test/buildtest_asn1" =>
+                [
+                    "test/buildtest_asn1.o",
+                ],
+            "test/buildtest_asn1.o" =>
+                [
+                    "test/buildtest_asn1.c",
+                ],
+            "test/buildtest_asn1t" =>
+                [
+                    "test/buildtest_asn1t.o",
+                ],
+            "test/buildtest_asn1t.o" =>
+                [
+                    "test/buildtest_asn1t.c",
+                ],
+            "test/buildtest_async" =>
+                [
+                    "test/buildtest_async.o",
+                ],
+            "test/buildtest_async.o" =>
+                [
+                    "test/buildtest_async.c",
+                ],
+            "test/buildtest_bio" =>
+                [
+                    "test/buildtest_bio.o",
+                ],
+            "test/buildtest_bio.o" =>
+                [
+                    "test/buildtest_bio.c",
+                ],
+            "test/buildtest_blowfish" =>
+                [
+                    "test/buildtest_blowfish.o",
+                ],
+            "test/buildtest_blowfish.o" =>
+                [
+                    "test/buildtest_blowfish.c",
+                ],
+            "test/buildtest_bn" =>
+                [
+                    "test/buildtest_bn.o",
+                ],
+            "test/buildtest_bn.o" =>
+                [
+                    "test/buildtest_bn.c",
+                ],
+            "test/buildtest_buffer" =>
+                [
+                    "test/buildtest_buffer.o",
+                ],
+            "test/buildtest_buffer.o" =>
+                [
+                    "test/buildtest_buffer.c",
+                ],
+            "test/buildtest_camellia" =>
+                [
+                    "test/buildtest_camellia.o",
+                ],
+            "test/buildtest_camellia.o" =>
+                [
+                    "test/buildtest_camellia.c",
+                ],
+            "test/buildtest_cast" =>
+                [
+                    "test/buildtest_cast.o",
+                ],
+            "test/buildtest_cast.o" =>
+                [
+                    "test/buildtest_cast.c",
+                ],
+            "test/buildtest_cmac" =>
+                [
+                    "test/buildtest_cmac.o",
+                ],
+            "test/buildtest_cmac.o" =>
+                [
+                    "test/buildtest_cmac.c",
+                ],
+            "test/buildtest_cms" =>
+                [
+                    "test/buildtest_cms.o",
+                ],
+            "test/buildtest_cms.o" =>
+                [
+                    "test/buildtest_cms.c",
+                ],
+            "test/buildtest_comp" =>
+                [
+                    "test/buildtest_comp.o",
+                ],
+            "test/buildtest_comp.o" =>
+                [
+                    "test/buildtest_comp.c",
+                ],
+            "test/buildtest_conf" =>
+                [
+                    "test/buildtest_conf.o",
+                ],
+            "test/buildtest_conf.o" =>
+                [
+                    "test/buildtest_conf.c",
+                ],
+            "test/buildtest_conf_api" =>
+                [
+                    "test/buildtest_conf_api.o",
+                ],
+            "test/buildtest_conf_api.o" =>
+                [
+                    "test/buildtest_conf_api.c",
+                ],
+            "test/buildtest_crypto" =>
+                [
+                    "test/buildtest_crypto.o",
+                ],
+            "test/buildtest_crypto.o" =>
+                [
+                    "test/buildtest_crypto.c",
+                ],
+            "test/buildtest_ct" =>
+                [
+                    "test/buildtest_ct.o",
+                ],
+            "test/buildtest_ct.o" =>
+                [
+                    "test/buildtest_ct.c",
+                ],
+            "test/buildtest_des" =>
+                [
+                    "test/buildtest_des.o",
+                ],
+            "test/buildtest_des.o" =>
+                [
+                    "test/buildtest_des.c",
+                ],
+            "test/buildtest_dh" =>
+                [
+                    "test/buildtest_dh.o",
+                ],
+            "test/buildtest_dh.o" =>
+                [
+                    "test/buildtest_dh.c",
+                ],
+            "test/buildtest_dsa" =>
+                [
+                    "test/buildtest_dsa.o",
+                ],
+            "test/buildtest_dsa.o" =>
+                [
+                    "test/buildtest_dsa.c",
+                ],
+            "test/buildtest_dtls1" =>
+                [
+                    "test/buildtest_dtls1.o",
+                ],
+            "test/buildtest_dtls1.o" =>
+                [
+                    "test/buildtest_dtls1.c",
+                ],
+            "test/buildtest_e_os2" =>
+                [
+                    "test/buildtest_e_os2.o",
+                ],
+            "test/buildtest_e_os2.o" =>
+                [
+                    "test/buildtest_e_os2.c",
+                ],
+            "test/buildtest_ebcdic" =>
+                [
+                    "test/buildtest_ebcdic.o",
+                ],
+            "test/buildtest_ebcdic.o" =>
+                [
+                    "test/buildtest_ebcdic.c",
+                ],
+            "test/buildtest_ec" =>
+                [
+                    "test/buildtest_ec.o",
+                ],
+            "test/buildtest_ec.o" =>
+                [
+                    "test/buildtest_ec.c",
+                ],
+            "test/buildtest_ecdh" =>
+                [
+                    "test/buildtest_ecdh.o",
+                ],
+            "test/buildtest_ecdh.o" =>
+                [
+                    "test/buildtest_ecdh.c",
+                ],
+            "test/buildtest_ecdsa" =>
+                [
+                    "test/buildtest_ecdsa.o",
+                ],
+            "test/buildtest_ecdsa.o" =>
+                [
+                    "test/buildtest_ecdsa.c",
+                ],
+            "test/buildtest_engine" =>
+                [
+                    "test/buildtest_engine.o",
+                ],
+            "test/buildtest_engine.o" =>
+                [
+                    "test/buildtest_engine.c",
+                ],
+            "test/buildtest_err" =>
+                [
+                    "test/buildtest_err.o",
+                ],
+            "test/buildtest_err.o" =>
+                [
+                    "test/buildtest_err.c",
+                ],
+            "test/buildtest_evp" =>
+                [
+                    "test/buildtest_evp.o",
+                ],
+            "test/buildtest_evp.o" =>
+                [
+                    "test/buildtest_evp.c",
+                ],
+            "test/buildtest_hmac" =>
+                [
+                    "test/buildtest_hmac.o",
+                ],
+            "test/buildtest_hmac.o" =>
+                [
+                    "test/buildtest_hmac.c",
+                ],
+            "test/buildtest_idea" =>
+                [
+                    "test/buildtest_idea.o",
+                ],
+            "test/buildtest_idea.o" =>
+                [
+                    "test/buildtest_idea.c",
+                ],
+            "test/buildtest_kdf" =>
+                [
+                    "test/buildtest_kdf.o",
+                ],
+            "test/buildtest_kdf.o" =>
+                [
+                    "test/buildtest_kdf.c",
+                ],
+            "test/buildtest_lhash" =>
+                [
+                    "test/buildtest_lhash.o",
+                ],
+            "test/buildtest_lhash.o" =>
+                [
+                    "test/buildtest_lhash.c",
+                ],
+            "test/buildtest_md4" =>
+                [
+                    "test/buildtest_md4.o",
+                ],
+            "test/buildtest_md4.o" =>
+                [
+                    "test/buildtest_md4.c",
+                ],
+            "test/buildtest_md5" =>
+                [
+                    "test/buildtest_md5.o",
+                ],
+            "test/buildtest_md5.o" =>
+                [
+                    "test/buildtest_md5.c",
+                ],
+            "test/buildtest_mdc2" =>
+                [
+                    "test/buildtest_mdc2.o",
+                ],
+            "test/buildtest_mdc2.o" =>
+                [
+                    "test/buildtest_mdc2.c",
+                ],
+            "test/buildtest_modes" =>
+                [
+                    "test/buildtest_modes.o",
+                ],
+            "test/buildtest_modes.o" =>
+                [
+                    "test/buildtest_modes.c",
+                ],
+            "test/buildtest_obj_mac" =>
+                [
+                    "test/buildtest_obj_mac.o",
+                ],
+            "test/buildtest_obj_mac.o" =>
+                [
+                    "test/buildtest_obj_mac.c",
+                ],
+            "test/buildtest_objects" =>
+                [
+                    "test/buildtest_objects.o",
+                ],
+            "test/buildtest_objects.o" =>
+                [
+                    "test/buildtest_objects.c",
+                ],
+            "test/buildtest_ocsp" =>
+                [
+                    "test/buildtest_ocsp.o",
+                ],
+            "test/buildtest_ocsp.o" =>
+                [
+                    "test/buildtest_ocsp.c",
+                ],
+            "test/buildtest_opensslconf" =>
+                [
+                    "test/buildtest_opensslconf.o",
+                ],
+            "test/buildtest_opensslconf.o" =>
+                [
+                    "test/buildtest_opensslconf.c",
+                ],
+            "test/buildtest_opensslv" =>
+                [
+                    "test/buildtest_opensslv.o",
+                ],
+            "test/buildtest_opensslv.o" =>
+                [
+                    "test/buildtest_opensslv.c",
+                ],
+            "test/buildtest_ossl_typ" =>
+                [
+                    "test/buildtest_ossl_typ.o",
+                ],
+            "test/buildtest_ossl_typ.o" =>
+                [
+                    "test/buildtest_ossl_typ.c",
+                ],
+            "test/buildtest_pem" =>
+                [
+                    "test/buildtest_pem.o",
+                ],
+            "test/buildtest_pem.o" =>
+                [
+                    "test/buildtest_pem.c",
+                ],
+            "test/buildtest_pem2" =>
+                [
+                    "test/buildtest_pem2.o",
+                ],
+            "test/buildtest_pem2.o" =>
+                [
+                    "test/buildtest_pem2.c",
+                ],
+            "test/buildtest_pkcs12" =>
+                [
+                    "test/buildtest_pkcs12.o",
+                ],
+            "test/buildtest_pkcs12.o" =>
+                [
+                    "test/buildtest_pkcs12.c",
+                ],
+            "test/buildtest_pkcs7" =>
+                [
+                    "test/buildtest_pkcs7.o",
+                ],
+            "test/buildtest_pkcs7.o" =>
+                [
+                    "test/buildtest_pkcs7.c",
+                ],
+            "test/buildtest_rand" =>
+                [
+                    "test/buildtest_rand.o",
+                ],
+            "test/buildtest_rand.o" =>
+                [
+                    "test/buildtest_rand.c",
+                ],
+            "test/buildtest_rc2" =>
+                [
+                    "test/buildtest_rc2.o",
+                ],
+            "test/buildtest_rc2.o" =>
+                [
+                    "test/buildtest_rc2.c",
+                ],
+            "test/buildtest_rc4" =>
+                [
+                    "test/buildtest_rc4.o",
+                ],
+            "test/buildtest_rc4.o" =>
+                [
+                    "test/buildtest_rc4.c",
+                ],
+            "test/buildtest_ripemd" =>
+                [
+                    "test/buildtest_ripemd.o",
+                ],
+            "test/buildtest_ripemd.o" =>
+                [
+                    "test/buildtest_ripemd.c",
+                ],
+            "test/buildtest_rsa" =>
+                [
+                    "test/buildtest_rsa.o",
+                ],
+            "test/buildtest_rsa.o" =>
+                [
+                    "test/buildtest_rsa.c",
+                ],
+            "test/buildtest_safestack" =>
+                [
+                    "test/buildtest_safestack.o",
+                ],
+            "test/buildtest_safestack.o" =>
+                [
+                    "test/buildtest_safestack.c",
+                ],
+            "test/buildtest_seed" =>
+                [
+                    "test/buildtest_seed.o",
+                ],
+            "test/buildtest_seed.o" =>
+                [
+                    "test/buildtest_seed.c",
+                ],
+            "test/buildtest_sha" =>
+                [
+                    "test/buildtest_sha.o",
+                ],
+            "test/buildtest_sha.o" =>
+                [
+                    "test/buildtest_sha.c",
+                ],
+            "test/buildtest_srp" =>
+                [
+                    "test/buildtest_srp.o",
+                ],
+            "test/buildtest_srp.o" =>
+                [
+                    "test/buildtest_srp.c",
+                ],
+            "test/buildtest_srtp" =>
+                [
+                    "test/buildtest_srtp.o",
+                ],
+            "test/buildtest_srtp.o" =>
+                [
+                    "test/buildtest_srtp.c",
+                ],
+            "test/buildtest_ssl" =>
+                [
+                    "test/buildtest_ssl.o",
+                ],
+            "test/buildtest_ssl.o" =>
+                [
+                    "test/buildtest_ssl.c",
+                ],
+            "test/buildtest_ssl2" =>
+                [
+                    "test/buildtest_ssl2.o",
+                ],
+            "test/buildtest_ssl2.o" =>
+                [
+                    "test/buildtest_ssl2.c",
+                ],
+            "test/buildtest_stack" =>
+                [
+                    "test/buildtest_stack.o",
+                ],
+            "test/buildtest_stack.o" =>
+                [
+                    "test/buildtest_stack.c",
+                ],
+            "test/buildtest_symhacks" =>
+                [
+                    "test/buildtest_symhacks.o",
+                ],
+            "test/buildtest_symhacks.o" =>
+                [
+                    "test/buildtest_symhacks.c",
+                ],
+            "test/buildtest_tls1" =>
+                [
+                    "test/buildtest_tls1.o",
+                ],
+            "test/buildtest_tls1.o" =>
+                [
+                    "test/buildtest_tls1.c",
+                ],
+            "test/buildtest_ts" =>
+                [
+                    "test/buildtest_ts.o",
+                ],
+            "test/buildtest_ts.o" =>
+                [
+                    "test/buildtest_ts.c",
+                ],
+            "test/buildtest_txt_db" =>
+                [
+                    "test/buildtest_txt_db.o",
+                ],
+            "test/buildtest_txt_db.o" =>
+                [
+                    "test/buildtest_txt_db.c",
+                ],
+            "test/buildtest_whrlpool" =>
+                [
+                    "test/buildtest_whrlpool.o",
+                ],
+            "test/buildtest_whrlpool.o" =>
+                [
+                    "test/buildtest_whrlpool.c",
+                ],
+            "test/buildtest_x509" =>
+                [
+                    "test/buildtest_x509.o",
+                ],
+            "test/buildtest_x509.o" =>
+                [
+                    "test/buildtest_x509.c",
+                ],
+            "test/buildtest_x509_vfy" =>
+                [
+                    "test/buildtest_x509_vfy.o",
+                ],
+            "test/buildtest_x509_vfy.o" =>
+                [
+                    "test/buildtest_x509_vfy.c",
+                ],
+            "test/buildtest_x509v3" =>
+                [
+                    "test/buildtest_x509v3.o",
+                ],
+            "test/buildtest_x509v3.o" =>
+                [
+                    "test/buildtest_x509v3.c",
+                ],
+            "test/casttest" =>
+                [
+                    "test/casttest.o",
+                ],
+            "test/casttest.o" =>
+                [
+                    "test/casttest.c",
+                ],
+            "test/cipherlist_test" =>
+                [
+                    "test/cipherlist_test.o",
+                    "test/testutil.o",
+                ],
+            "test/cipherlist_test.o" =>
+                [
+                    "test/cipherlist_test.c",
+                ],
+            "test/clienthellotest" =>
+                [
+                    "test/clienthellotest.o",
+                ],
+            "test/clienthellotest.o" =>
+                [
+                    "test/clienthellotest.c",
+                ],
+            "test/constant_time_test" =>
+                [
+                    "test/constant_time_test.o",
+                ],
+            "test/constant_time_test.o" =>
+                [
+                    "test/constant_time_test.c",
+                ],
+            "test/crltest" =>
+                [
+                    "test/crltest.o",
+                    "test/testutil.o",
+                ],
+            "test/crltest.o" =>
+                [
+                    "test/crltest.c",
+                ],
+            "test/ct_test" =>
+                [
+                    "test/ct_test.o",
+                    "test/testutil.o",
+                ],
+            "test/ct_test.o" =>
+                [
+                    "test/ct_test.c",
+                ],
+            "test/d2i_test" =>
+                [
+                    "test/d2i_test.o",
+                    "test/testutil.o",
+                ],
+            "test/d2i_test.o" =>
+                [
+                    "test/d2i_test.c",
+                ],
+            "test/danetest" =>
+                [
+                    "test/danetest.o",
+                ],
+            "test/danetest.o" =>
+                [
+                    "test/danetest.c",
+                ],
+            "test/destest" =>
+                [
+                    "test/destest.o",
+                ],
+            "test/destest.o" =>
+                [
+                    "test/destest.c",
+                ],
+            "test/dhtest" =>
+                [
+                    "test/dhtest.o",
+                ],
+            "test/dhtest.o" =>
+                [
+                    "test/dhtest.c",
+                ],
+            "test/dsatest" =>
+                [
+                    "test/dsatest.o",
+                ],
+            "test/dsatest.o" =>
+                [
+                    "test/dsatest.c",
+                ],
+            "test/dtlstest" =>
+                [
+                    "test/dtlstest.o",
+                    "test/ssltestlib.o",
+                    "test/testutil.o",
+                ],
+            "test/dtlstest.o" =>
+                [
+                    "test/dtlstest.c",
+                ],
+            "test/dtlsv1listentest" =>
+                [
+                    "test/dtlsv1listentest.o",
+                ],
+            "test/dtlsv1listentest.o" =>
+                [
+                    "test/dtlsv1listentest.c",
+                ],
+            "test/ecdhtest" =>
+                [
+                    "test/ecdhtest.o",
+                ],
+            "test/ecdhtest.o" =>
+                [
+                    "test/ecdhtest.c",
+                ],
+            "test/ecdsatest" =>
+                [
+                    "test/ecdsatest.o",
+                ],
+            "test/ecdsatest.o" =>
+                [
+                    "test/ecdsatest.c",
+                ],
+            "test/ectest" =>
+                [
+                    "test/ectest.o",
+                ],
+            "test/ectest.o" =>
+                [
+                    "test/ectest.c",
+                ],
+            "test/enginetest" =>
+                [
+                    "test/enginetest.o",
+                ],
+            "test/enginetest.o" =>
+                [
+                    "test/enginetest.c",
+                ],
+            "test/evp_extra_test" =>
+                [
+                    "test/evp_extra_test.o",
+                ],
+            "test/evp_extra_test.o" =>
+                [
+                    "test/evp_extra_test.c",
+                ],
+            "test/evp_test" =>
+                [
+                    "test/evp_test.o",
+                ],
+            "test/evp_test.o" =>
+                [
+                    "test/evp_test.c",
+                ],
+            "test/exptest" =>
+                [
+                    "test/exptest.o",
+                ],
+            "test/exptest.o" =>
+                [
+                    "test/exptest.c",
+                ],
+            "test/gmdifftest" =>
+                [
+                    "test/gmdifftest.o",
+                ],
+            "test/gmdifftest.o" =>
+                [
+                    "test/gmdifftest.c",
+                ],
+            "test/handshake_helper.o" =>
+                [
+                    "test/handshake_helper.c",
+                ],
+            "test/heartbeat_test" =>
+                [
+                    "test/heartbeat_test.o",
+                    "test/testutil.o",
+                ],
+            "test/heartbeat_test.o" =>
+                [
+                    "test/heartbeat_test.c",
+                ],
+            "test/hmactest" =>
+                [
+                    "test/hmactest.o",
+                ],
+            "test/hmactest.o" =>
+                [
+                    "test/hmactest.c",
+                ],
+            "test/ideatest" =>
+                [
+                    "test/ideatest.o",
+                ],
+            "test/ideatest.o" =>
+                [
+                    "test/ideatest.c",
+                ],
+            "test/igetest" =>
+                [
+                    "test/igetest.o",
+                ],
+            "test/igetest.o" =>
+                [
+                    "test/igetest.c",
+                ],
+            "test/md2test" =>
+                [
+                    "test/md2test.o",
+                ],
+            "test/md2test.o" =>
+                [
+                    "test/md2test.c",
+                ],
+            "test/md4test" =>
+                [
+                    "test/md4test.o",
+                ],
+            "test/md4test.o" =>
+                [
+                    "test/md4test.c",
+                ],
+            "test/md5test" =>
+                [
+                    "test/md5test.o",
+                ],
+            "test/md5test.o" =>
+                [
+                    "test/md5test.c",
+                ],
+            "test/mdc2test" =>
+                [
+                    "test/mdc2test.o",
+                ],
+            "test/mdc2test.o" =>
+                [
+                    "test/mdc2test.c",
+                ],
+            "test/memleaktest" =>
+                [
+                    "test/memleaktest.o",
+                ],
+            "test/memleaktest.o" =>
+                [
+                    "test/memleaktest.c",
+                ],
+            "test/p5_crpt2_test" =>
+                [
+                    "test/p5_crpt2_test.o",
+                ],
+            "test/p5_crpt2_test.o" =>
+                [
+                    "test/p5_crpt2_test.c",
+                ],
+            "test/packettest" =>
+                [
+                    "test/packettest.o",
+                ],
+            "test/packettest.o" =>
+                [
+                    "test/packettest.c",
+                ],
+            "test/pbelutest" =>
+                [
+                    "test/pbelutest.o",
+                ],
+            "test/pbelutest.o" =>
+                [
+                    "test/pbelutest.c",
+                ],
+            "test/randtest" =>
+                [
+                    "test/randtest.o",
+                ],
+            "test/randtest.o" =>
+                [
+                    "test/randtest.c",
+                ],
+            "test/rc2test" =>
+                [
+                    "test/rc2test.o",
+                ],
+            "test/rc2test.o" =>
+                [
+                    "test/rc2test.c",
+                ],
+            "test/rc4test" =>
+                [
+                    "test/rc4test.o",
+                ],
+            "test/rc4test.o" =>
+                [
+                    "test/rc4test.c",
+                ],
+            "test/rc5test" =>
+                [
+                    "test/rc5test.o",
+                ],
+            "test/rc5test.o" =>
+                [
+                    "test/rc5test.c",
+                ],
+            "test/rmdtest" =>
+                [
+                    "test/rmdtest.o",
+                ],
+            "test/rmdtest.o" =>
+                [
+                    "test/rmdtest.c",
+                ],
+            "test/rsa_test" =>
+                [
+                    "test/rsa_test.o",
+                ],
+            "test/rsa_test.o" =>
+                [
+                    "test/rsa_test.c",
+                ],
+            "test/sanitytest" =>
+                [
+                    "test/sanitytest.o",
+                ],
+            "test/sanitytest.o" =>
+                [
+                    "test/sanitytest.c",
+                ],
+            "test/secmemtest" =>
+                [
+                    "test/secmemtest.o",
+                ],
+            "test/secmemtest.o" =>
+                [
+                    "test/secmemtest.c",
+                ],
+            "test/sha1test" =>
+                [
+                    "test/sha1test.o",
+                ],
+            "test/sha1test.o" =>
+                [
+                    "test/sha1test.c",
+                ],
+            "test/sha256t" =>
+                [
+                    "test/sha256t.o",
+                ],
+            "test/sha256t.o" =>
+                [
+                    "test/sha256t.c",
+                ],
+            "test/sha512t" =>
+                [
+                    "test/sha512t.o",
+                ],
+            "test/sha512t.o" =>
+                [
+                    "test/sha512t.c",
+                ],
+            "test/srptest" =>
+                [
+                    "test/srptest.o",
+                ],
+            "test/srptest.o" =>
+                [
+                    "test/srptest.c",
+                ],
+            "test/ssl_test" =>
+                [
+                    "test/handshake_helper.o",
+                    "test/ssl_test.o",
+                    "test/ssl_test_ctx.o",
+                    "test/testutil.o",
+                ],
+            "test/ssl_test.o" =>
+                [
+                    "test/ssl_test.c",
+                ],
+            "test/ssl_test_ctx.o" =>
+                [
+                    "test/ssl_test_ctx.c",
+                ],
+            "test/ssl_test_ctx_test" =>
+                [
+                    "test/ssl_test_ctx.o",
+                    "test/ssl_test_ctx_test.o",
+                    "test/testutil.o",
+                ],
+            "test/ssl_test_ctx_test.o" =>
+                [
+                    "test/ssl_test_ctx_test.c",
+                ],
+            "test/sslapitest" =>
+                [
+                    "test/sslapitest.o",
+                    "test/ssltestlib.o",
+                    "test/testutil.o",
+                ],
+            "test/sslapitest.o" =>
+                [
+                    "test/sslapitest.c",
+                ],
+            "test/sslcorrupttest" =>
+                [
+                    "test/sslcorrupttest.o",
+                    "test/ssltestlib.o",
+                    "test/testutil.o",
+                ],
+            "test/sslcorrupttest.o" =>
+                [
+                    "test/sslcorrupttest.c",
+                ],
+            "test/ssltest_old" =>
+                [
+                    "test/ssltest_old.o",
+                ],
+            "test/ssltest_old.o" =>
+                [
+                    "test/ssltest_old.c",
+                ],
+            "test/ssltestlib.o" =>
+                [
+                    "test/ssltestlib.c",
+                ],
+            "test/testutil.o" =>
+                [
+                    "test/testutil.c",
+                ],
+            "test/threadstest" =>
+                [
+                    "test/threadstest.o",
+                ],
+            "test/threadstest.o" =>
+                [
+                    "test/threadstest.c",
+                ],
+            "test/v3ext" =>
+                [
+                    "test/v3ext.o",
+                ],
+            "test/v3ext.o" =>
+                [
+                    "test/v3ext.c",
+                ],
+            "test/v3nametest" =>
+                [
+                    "test/v3nametest.o",
+                ],
+            "test/v3nametest.o" =>
+                [
+                    "test/v3nametest.c",
+                ],
+            "test/verify_extra_test" =>
+                [
+                    "test/verify_extra_test.o",
+                ],
+            "test/verify_extra_test.o" =>
+                [
+                    "test/verify_extra_test.c",
+                ],
+            "test/wp_test" =>
+                [
+                    "test/wp_test.o",
+                ],
+            "test/wp_test.o" =>
+                [
+                    "test/wp_test.c",
+                ],
+            "test/x509aux" =>
+                [
+                    "test/x509aux.o",
+                ],
+            "test/x509aux.o" =>
+                [
+                    "test/x509aux.c",
+                ],
+            "tools/c_rehash" =>
+                [
+                    "tools/c_rehash.in",
+                ],
+            "util/shlib_wrap.sh" =>
+                [
+                    "util/shlib_wrap.sh.in",
+                ],
+        },
+);
+
+1;
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/LPdir_unix.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/LPdir_unix.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/LPdir_unix.c	(revision 331)
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2004-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
+ */
+
+/*
+ * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#ifndef LPDIR_H
+# include "LPdir.h"
+#endif
+
+/*
+ * The POSIXly macro for the maximum number of characters in a file path is
+ * NAME_MAX.  However, some operating systems use PATH_MAX instead.
+ * Therefore, it seems natural to first check for PATH_MAX and use that, and
+ * if it doesn't exist, use NAME_MAX.
+ */
+#if defined(PATH_MAX)
+# define LP_ENTRY_SIZE PATH_MAX
+#elif defined(NAME_MAX)
+# define LP_ENTRY_SIZE NAME_MAX
+#endif
+
+/*
+ * Of course, there's the possibility that neither PATH_MAX nor NAME_MAX
+ * exist.  It's also possible that NAME_MAX exists but is define to a very
+ * small value (HP-UX offers 14), so we need to check if we got a result, and
+ * if it meets a minimum standard, and create or change it if not.
+ */
+#if !defined(LP_ENTRY_SIZE) || LP_ENTRY_SIZE<255
+# undef LP_ENTRY_SIZE
+# define LP_ENTRY_SIZE 255
+#endif
+
+struct LP_dir_context_st {
+    DIR *dir;
+    char entry_name[LP_ENTRY_SIZE + 1];
+};
+
+const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
+{
+    struct dirent *direntry = NULL;
+
+    if (ctx == NULL || directory == NULL) {
+        errno = EINVAL;
+        return 0;
+    }
+
+    errno = 0;
+    if (*ctx == NULL) {
+        *ctx = malloc(sizeof(**ctx));
+        if (*ctx == NULL) {
+            errno = ENOMEM;
+            return 0;
+        }
+        memset(*ctx, 0, sizeof(**ctx));
+
+        (*ctx)->dir = opendir(directory);
+        if ((*ctx)->dir == NULL) {
+            int save_errno = errno; /* Probably not needed, but I'm paranoid */
+            free(*ctx);
+            *ctx = NULL;
+            errno = save_errno;
+            return 0;
+        }
+    }
+
+    direntry = readdir((*ctx)->dir);
+    if (direntry == NULL) {
+        return 0;
+    }
+
+    strncpy((*ctx)->entry_name, direntry->d_name,
+            sizeof((*ctx)->entry_name) - 1);
+    (*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0';
+    return (*ctx)->entry_name;
+}
+
+int LP_find_file_end(LP_DIR_CTX **ctx)
+{
+    if (ctx != NULL && *ctx != NULL) {
+        int ret = closedir((*ctx)->dir);
+
+        free(*ctx);
+        switch (ret) {
+        case 0:
+            return 1;
+        case -1:
+            return 0;
+        default:
+            break;
+        }
+    }
+    errno = EINVAL;
+    return 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_cbc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_cbc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_cbc.c	(revision 331)
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2002-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 <openssl/aes.h>
+#include <openssl/modes.h>
+
+void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                     size_t len, const AES_KEY *key,
+                     unsigned char *ivec, const int enc)
+{
+
+    if (enc)
+        CRYPTO_cbc128_encrypt(in, out, len, key, ivec,
+                              (block128_f) AES_encrypt);
+    else
+        CRYPTO_cbc128_decrypt(in, out, len, key, ivec,
+                              (block128_f) AES_decrypt);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_cfb.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_cfb.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_cfb.c	(revision 331)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2002-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 <openssl/aes.h>
+#include <openssl/modes.h>
+
+/*
+ * The input and output encrypted as though 128bit cfb mode is being used.
+ * The extra state information to record how much of the 128bit block we have
+ * used is contained in *num;
+ */
+
+void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+                        size_t length, const AES_KEY *key,
+                        unsigned char *ivec, int *num, const int enc)
+{
+
+    CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc,
+                          (block128_f) AES_encrypt);
+}
+
+/* N.B. This expects the input to be packed, MS bit first */
+void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
+                      size_t length, const AES_KEY *key,
+                      unsigned char *ivec, int *num, const int enc)
+{
+    CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc,
+                            (block128_f) AES_encrypt);
+}
+
+void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
+                      size_t length, const AES_KEY *key,
+                      unsigned char *ivec, int *num, const int enc)
+{
+    CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc,
+                            (block128_f) AES_encrypt);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_core.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_core.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_core.c	(revision 331)
@@ -0,0 +1,1367 @@
+/*
+ * Copyright 2002-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
+ */
+
+/**
+ * rijndael-alg-fst.c
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Note: rewritten a little bit to provide error control and an OpenSSL-
+   compatible API */
+
+#include <assert.h>
+
+#include <stdlib.h>
+#include <openssl/crypto.h>
+#include <openssl/aes.h>
+#include "aes_locl.h"
+
+#ifndef AES_ASM
+/*-
+Te0[x] = S [x].[02, 01, 01, 03];
+Te1[x] = S [x].[03, 02, 01, 01];
+Te2[x] = S [x].[01, 03, 02, 01];
+Te3[x] = S [x].[01, 01, 03, 02];
+
+Td0[x] = Si[x].[0e, 09, 0d, 0b];
+Td1[x] = Si[x].[0b, 0e, 09, 0d];
+Td2[x] = Si[x].[0d, 0b, 0e, 09];
+Td3[x] = Si[x].[09, 0d, 0b, 0e];
+Td4[x] = Si[x].[01];
+*/
+
+static const u32 Te0[256] = {
+    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+};
+static const u32 Te1[256] = {
+    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+};
+static const u32 Te2[256] = {
+    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+};
+static const u32 Te3[256] = {
+    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+};
+
+static const u32 Td0[256] = {
+    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
+    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
+    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
+    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
+    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
+    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
+    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
+    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
+    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
+    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
+    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
+    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
+    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
+    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
+    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
+    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
+    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
+    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
+    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
+    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
+    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
+    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
+    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
+    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
+    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
+    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
+    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
+    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
+    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
+    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
+    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
+    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
+    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
+    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
+    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
+    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
+    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
+    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
+    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
+    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
+    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
+    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
+    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
+    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
+    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
+    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
+    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
+    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
+    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
+    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
+    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
+    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
+    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
+    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
+    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
+    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
+    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
+    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
+    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
+    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
+    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
+    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
+    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
+    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
+};
+static const u32 Td1[256] = {
+    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
+    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
+    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
+    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
+    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
+    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
+    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
+    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
+    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
+    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
+    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
+    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
+    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
+    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
+    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
+    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
+    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
+    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
+    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
+    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
+    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
+    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
+    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
+    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
+    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
+    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
+    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
+    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
+    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
+    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
+    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
+    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
+    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
+    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
+    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
+    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
+    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
+    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
+    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
+    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
+    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
+    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
+    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
+    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
+    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
+    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
+    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
+    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
+    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
+    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
+    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
+    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
+    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
+    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
+    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
+    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
+    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
+    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
+    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
+    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
+    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
+    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
+    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
+    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
+};
+static const u32 Td2[256] = {
+    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
+    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
+    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
+    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
+    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
+    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
+    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
+    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
+    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
+    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
+    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
+    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
+    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
+    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
+    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
+    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
+    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
+    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
+    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
+    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
+    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
+    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
+    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
+    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
+    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
+    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
+    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
+    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
+    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
+    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
+    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
+    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
+    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
+    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
+    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
+    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
+    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
+    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
+    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
+    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
+    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
+    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
+    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
+    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
+    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
+    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
+    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
+    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
+    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
+    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
+    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
+    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
+    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
+    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
+    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
+    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
+    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
+    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
+    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
+    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
+    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
+    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
+    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
+    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
+};
+static const u32 Td3[256] = {
+    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
+    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
+    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
+    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
+    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
+    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
+    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
+    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
+    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
+    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
+    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
+    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
+    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
+    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
+    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
+    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
+    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
+    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
+    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
+    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
+    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
+    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
+    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
+    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
+    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
+    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
+    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
+    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
+    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
+    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
+    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
+    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
+    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
+    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
+    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
+    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
+    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
+    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
+    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
+    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
+    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
+    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
+    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
+    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
+    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
+    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
+    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
+    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
+    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
+    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
+    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
+    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
+    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
+    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
+    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
+    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
+    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
+    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
+    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
+    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
+    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
+    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
+    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
+    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
+};
+static const u8 Td4[256] = {
+    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
+    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
+    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
+    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
+    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
+    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
+    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
+    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
+    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
+    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
+    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
+    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
+    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
+    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
+    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
+    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
+    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
+    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
+    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
+    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
+    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
+    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
+    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
+    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
+    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
+    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
+    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
+    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
+    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
+    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
+    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
+    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
+};
+static const u32 rcon[] = {
+    0x01000000, 0x02000000, 0x04000000, 0x08000000,
+    0x10000000, 0x20000000, 0x40000000, 0x80000000,
+    0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+
+/**
+ * Expand the cipher key into the encryption key schedule.
+ */
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+                        AES_KEY *key)
+{
+
+    u32 *rk;
+    int i = 0;
+    u32 temp;
+
+    if (!userKey || !key)
+        return -1;
+    if (bits != 128 && bits != 192 && bits != 256)
+        return -2;
+
+    rk = key->rd_key;
+
+    if (bits == 128)
+        key->rounds = 10;
+    else if (bits == 192)
+        key->rounds = 12;
+    else
+        key->rounds = 14;
+
+    rk[0] = GETU32(userKey     );
+    rk[1] = GETU32(userKey +  4);
+    rk[2] = GETU32(userKey +  8);
+    rk[3] = GETU32(userKey + 12);
+    if (bits == 128) {
+        while (1) {
+            temp  = rk[3];
+            rk[4] = rk[0] ^
+                (Te2[(temp >> 16) & 0xff] & 0xff000000) ^
+                (Te3[(temp >>  8) & 0xff] & 0x00ff0000) ^
+                (Te0[(temp      ) & 0xff] & 0x0000ff00) ^
+                (Te1[(temp >> 24)       ] & 0x000000ff) ^
+                rcon[i];
+            rk[5] = rk[1] ^ rk[4];
+            rk[6] = rk[2] ^ rk[5];
+            rk[7] = rk[3] ^ rk[6];
+            if (++i == 10) {
+                return 0;
+            }
+            rk += 4;
+        }
+    }
+    rk[4] = GETU32(userKey + 16);
+    rk[5] = GETU32(userKey + 20);
+    if (bits == 192) {
+        while (1) {
+            temp = rk[ 5];
+            rk[ 6] = rk[ 0] ^
+                (Te2[(temp >> 16) & 0xff] & 0xff000000) ^
+                (Te3[(temp >>  8) & 0xff] & 0x00ff0000) ^
+                (Te0[(temp      ) & 0xff] & 0x0000ff00) ^
+                (Te1[(temp >> 24)       ] & 0x000000ff) ^
+                rcon[i];
+            rk[ 7] = rk[ 1] ^ rk[ 6];
+            rk[ 8] = rk[ 2] ^ rk[ 7];
+            rk[ 9] = rk[ 3] ^ rk[ 8];
+            if (++i == 8) {
+                return 0;
+            }
+            rk[10] = rk[ 4] ^ rk[ 9];
+            rk[11] = rk[ 5] ^ rk[10];
+            rk += 6;
+        }
+    }
+    rk[6] = GETU32(userKey + 24);
+    rk[7] = GETU32(userKey + 28);
+    if (bits == 256) {
+        while (1) {
+            temp = rk[ 7];
+            rk[ 8] = rk[ 0] ^
+                (Te2[(temp >> 16) & 0xff] & 0xff000000) ^
+                (Te3[(temp >>  8) & 0xff] & 0x00ff0000) ^
+                (Te0[(temp      ) & 0xff] & 0x0000ff00) ^
+                (Te1[(temp >> 24)       ] & 0x000000ff) ^
+                rcon[i];
+            rk[ 9] = rk[ 1] ^ rk[ 8];
+            rk[10] = rk[ 2] ^ rk[ 9];
+            rk[11] = rk[ 3] ^ rk[10];
+            if (++i == 7) {
+                return 0;
+            }
+            temp = rk[11];
+            rk[12] = rk[ 4] ^
+                (Te2[(temp >> 24)       ] & 0xff000000) ^
+                (Te3[(temp >> 16) & 0xff] & 0x00ff0000) ^
+                (Te0[(temp >>  8) & 0xff] & 0x0000ff00) ^
+                (Te1[(temp      ) & 0xff] & 0x000000ff);
+            rk[13] = rk[ 5] ^ rk[12];
+            rk[14] = rk[ 6] ^ rk[13];
+            rk[15] = rk[ 7] ^ rk[14];
+
+            rk += 8;
+            }
+    }
+    return 0;
+}
+
+/**
+ * Expand the cipher key into the decryption key schedule.
+ */
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+                        AES_KEY *key)
+{
+
+    u32 *rk;
+    int i, j, status;
+    u32 temp;
+
+    /* first, start with an encryption schedule */
+    status = AES_set_encrypt_key(userKey, bits, key);
+    if (status < 0)
+        return status;
+
+    rk = key->rd_key;
+
+    /* invert the order of the round keys: */
+    for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
+        temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
+        temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
+        temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
+        temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
+    }
+    /* apply the inverse MixColumn transform to all round keys but the first and the last: */
+    for (i = 1; i < (key->rounds); i++) {
+        rk += 4;
+        rk[0] =
+            Td0[Te1[(rk[0] >> 24)       ] & 0xff] ^
+            Td1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^
+            Td2[Te1[(rk[0] >>  8) & 0xff] & 0xff] ^
+            Td3[Te1[(rk[0]      ) & 0xff] & 0xff];
+        rk[1] =
+            Td0[Te1[(rk[1] >> 24)       ] & 0xff] ^
+            Td1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^
+            Td2[Te1[(rk[1] >>  8) & 0xff] & 0xff] ^
+            Td3[Te1[(rk[1]      ) & 0xff] & 0xff];
+        rk[2] =
+            Td0[Te1[(rk[2] >> 24)       ] & 0xff] ^
+            Td1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^
+            Td2[Te1[(rk[2] >>  8) & 0xff] & 0xff] ^
+            Td3[Te1[(rk[2]      ) & 0xff] & 0xff];
+        rk[3] =
+            Td0[Te1[(rk[3] >> 24)       ] & 0xff] ^
+            Td1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^
+            Td2[Te1[(rk[3] >>  8) & 0xff] & 0xff] ^
+            Td3[Te1[(rk[3]      ) & 0xff] & 0xff];
+    }
+    return 0;
+}
+
+/*
+ * Encrypt a single block
+ * in and out can overlap
+ */
+void AES_encrypt(const unsigned char *in, unsigned char *out,
+                 const AES_KEY *key) {
+
+    const u32 *rk;
+    u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+    int r;
+#endif /* ?FULL_UNROLL */
+
+    assert(in && out && key);
+    rk = key->rd_key;
+
+    /*
+     * map byte array block to cipher state
+     * and add initial round key:
+     */
+    s0 = GETU32(in     ) ^ rk[0];
+    s1 = GETU32(in +  4) ^ rk[1];
+    s2 = GETU32(in +  8) ^ rk[2];
+    s3 = GETU32(in + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+    /* round 1: */
+    t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
+    t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
+    t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
+    t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
+    /* round 2: */
+    s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
+    s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
+    s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
+    s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
+    /* round 3: */
+    t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
+    t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
+    t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
+    t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
+    /* round 4: */
+    s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
+    s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
+    s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
+    s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
+    /* round 5: */
+    t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
+    t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
+    t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
+    t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
+    /* round 6: */
+    s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
+    s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
+    s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
+    s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
+    /* round 7: */
+    t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
+    t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
+    t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
+    t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
+    /* round 8: */
+    s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
+    s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
+    s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
+    s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
+    /* round 9: */
+    t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
+    t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
+    t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
+    t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
+    if (key->rounds > 10) {
+        /* round 10: */
+        s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
+        s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
+        s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
+        s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
+        /* round 11: */
+        t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
+        t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
+        t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
+        t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
+        if (key->rounds > 12) {
+            /* round 12: */
+            s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
+            s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
+            s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
+            s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
+            /* round 13: */
+            t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
+            t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
+            t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
+            t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
+        }
+    }
+    rk += key->rounds << 2;
+#else  /* !FULL_UNROLL */
+    /*
+     * Nr - 1 full rounds:
+     */
+    r = key->rounds >> 1;
+    for (;;) {
+        t0 =
+            Te0[(s0 >> 24)       ] ^
+            Te1[(s1 >> 16) & 0xff] ^
+            Te2[(s2 >>  8) & 0xff] ^
+            Te3[(s3      ) & 0xff] ^
+            rk[4];
+        t1 =
+            Te0[(s1 >> 24)       ] ^
+            Te1[(s2 >> 16) & 0xff] ^
+            Te2[(s3 >>  8) & 0xff] ^
+            Te3[(s0      ) & 0xff] ^
+            rk[5];
+        t2 =
+            Te0[(s2 >> 24)       ] ^
+            Te1[(s3 >> 16) & 0xff] ^
+            Te2[(s0 >>  8) & 0xff] ^
+            Te3[(s1      ) & 0xff] ^
+            rk[6];
+        t3 =
+            Te0[(s3 >> 24)       ] ^
+            Te1[(s0 >> 16) & 0xff] ^
+            Te2[(s1 >>  8) & 0xff] ^
+            Te3[(s2      ) & 0xff] ^
+            rk[7];
+
+        rk += 8;
+        if (--r == 0) {
+            break;
+        }
+
+        s0 =
+            Te0[(t0 >> 24)       ] ^
+            Te1[(t1 >> 16) & 0xff] ^
+            Te2[(t2 >>  8) & 0xff] ^
+            Te3[(t3      ) & 0xff] ^
+            rk[0];
+        s1 =
+            Te0[(t1 >> 24)       ] ^
+            Te1[(t2 >> 16) & 0xff] ^
+            Te2[(t3 >>  8) & 0xff] ^
+            Te3[(t0      ) & 0xff] ^
+            rk[1];
+        s2 =
+            Te0[(t2 >> 24)       ] ^
+            Te1[(t3 >> 16) & 0xff] ^
+            Te2[(t0 >>  8) & 0xff] ^
+            Te3[(t1      ) & 0xff] ^
+            rk[2];
+        s3 =
+            Te0[(t3 >> 24)       ] ^
+            Te1[(t0 >> 16) & 0xff] ^
+            Te2[(t1 >>  8) & 0xff] ^
+            Te3[(t2      ) & 0xff] ^
+            rk[3];
+    }
+#endif /* ?FULL_UNROLL */
+    /*
+     * apply last round and
+     * map cipher state to byte array block:
+     */
+    s0 =
+        (Te2[(t0 >> 24)       ] & 0xff000000) ^
+        (Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+        (Te0[(t2 >>  8) & 0xff] & 0x0000ff00) ^
+        (Te1[(t3      ) & 0xff] & 0x000000ff) ^
+        rk[0];
+    PUTU32(out     , s0);
+    s1 =
+        (Te2[(t1 >> 24)       ] & 0xff000000) ^
+        (Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+        (Te0[(t3 >>  8) & 0xff] & 0x0000ff00) ^
+        (Te1[(t0      ) & 0xff] & 0x000000ff) ^
+        rk[1];
+    PUTU32(out +  4, s1);
+    s2 =
+        (Te2[(t2 >> 24)       ] & 0xff000000) ^
+        (Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+        (Te0[(t0 >>  8) & 0xff] & 0x0000ff00) ^
+        (Te1[(t1      ) & 0xff] & 0x000000ff) ^
+        rk[2];
+    PUTU32(out +  8, s2);
+    s3 =
+        (Te2[(t3 >> 24)       ] & 0xff000000) ^
+        (Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+        (Te0[(t1 >>  8) & 0xff] & 0x0000ff00) ^
+        (Te1[(t2      ) & 0xff] & 0x000000ff) ^
+        rk[3];
+    PUTU32(out + 12, s3);
+}
+
+/*
+ * Decrypt a single block
+ * in and out can overlap
+ */
+void AES_decrypt(const unsigned char *in, unsigned char *out,
+                 const AES_KEY *key)
+{
+
+    const u32 *rk;
+    u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+    int r;
+#endif /* ?FULL_UNROLL */
+
+    assert(in && out && key);
+    rk = key->rd_key;
+
+    /*
+     * map byte array block to cipher state
+     * and add initial round key:
+     */
+    s0 = GETU32(in     ) ^ rk[0];
+    s1 = GETU32(in +  4) ^ rk[1];
+    s2 = GETU32(in +  8) ^ rk[2];
+    s3 = GETU32(in + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+    /* round 1: */
+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
+    /* round 2: */
+    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
+    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
+    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
+    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
+    /* round 3: */
+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
+    /* round 4: */
+    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
+    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
+    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
+    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
+    /* round 5: */
+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
+    /* round 6: */
+    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
+    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
+    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
+    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
+    /* round 7: */
+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
+    /* round 8: */
+    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
+    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
+    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
+    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
+    /* round 9: */
+    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
+    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
+    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
+    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
+    if (key->rounds > 10) {
+        /* round 10: */
+        s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
+        s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
+        s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
+        s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
+        /* round 11: */
+        t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
+        t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
+        t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
+        t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
+        if (key->rounds > 12) {
+            /* round 12: */
+            s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
+            s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
+            s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
+            s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
+            /* round 13: */
+            t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
+            t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
+            t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
+            t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
+        }
+    }
+    rk += key->rounds << 2;
+#else  /* !FULL_UNROLL */
+    /*
+     * Nr - 1 full rounds:
+     */
+    r = key->rounds >> 1;
+    for (;;) {
+        t0 =
+            Td0[(s0 >> 24)       ] ^
+            Td1[(s3 >> 16) & 0xff] ^
+            Td2[(s2 >>  8) & 0xff] ^
+            Td3[(s1      ) & 0xff] ^
+            rk[4];
+        t1 =
+            Td0[(s1 >> 24)       ] ^
+            Td1[(s0 >> 16) & 0xff] ^
+            Td2[(s3 >>  8) & 0xff] ^
+            Td3[(s2      ) & 0xff] ^
+            rk[5];
+        t2 =
+            Td0[(s2 >> 24)       ] ^
+            Td1[(s1 >> 16) & 0xff] ^
+            Td2[(s0 >>  8) & 0xff] ^
+            Td3[(s3      ) & 0xff] ^
+            rk[6];
+        t3 =
+            Td0[(s3 >> 24)       ] ^
+            Td1[(s2 >> 16) & 0xff] ^
+            Td2[(s1 >>  8) & 0xff] ^
+            Td3[(s0      ) & 0xff] ^
+            rk[7];
+
+        rk += 8;
+        if (--r == 0) {
+            break;
+        }
+
+        s0 =
+            Td0[(t0 >> 24)       ] ^
+            Td1[(t3 >> 16) & 0xff] ^
+            Td2[(t2 >>  8) & 0xff] ^
+            Td3[(t1      ) & 0xff] ^
+            rk[0];
+        s1 =
+            Td0[(t1 >> 24)       ] ^
+            Td1[(t0 >> 16) & 0xff] ^
+            Td2[(t3 >>  8) & 0xff] ^
+            Td3[(t2      ) & 0xff] ^
+            rk[1];
+        s2 =
+            Td0[(t2 >> 24)       ] ^
+            Td1[(t1 >> 16) & 0xff] ^
+            Td2[(t0 >>  8) & 0xff] ^
+            Td3[(t3      ) & 0xff] ^
+            rk[2];
+        s3 =
+            Td0[(t3 >> 24)       ] ^
+            Td1[(t2 >> 16) & 0xff] ^
+            Td2[(t1 >>  8) & 0xff] ^
+            Td3[(t0      ) & 0xff] ^
+            rk[3];
+    }
+#endif /* ?FULL_UNROLL */
+    /*
+     * apply last round and
+     * map cipher state to byte array block:
+     */
+    s0 =
+        ((u32)Td4[(t0 >> 24)       ] << 24) ^
+        ((u32)Td4[(t3 >> 16) & 0xff] << 16) ^
+        ((u32)Td4[(t2 >>  8) & 0xff] <<  8) ^
+        ((u32)Td4[(t1      ) & 0xff])       ^
+        rk[0];
+    PUTU32(out     , s0);
+    s1 =
+        ((u32)Td4[(t1 >> 24)       ] << 24) ^
+        ((u32)Td4[(t0 >> 16) & 0xff] << 16) ^
+        ((u32)Td4[(t3 >>  8) & 0xff] <<  8) ^
+        ((u32)Td4[(t2      ) & 0xff])       ^
+        rk[1];
+    PUTU32(out +  4, s1);
+    s2 =
+        ((u32)Td4[(t2 >> 24)       ] << 24) ^
+        ((u32)Td4[(t1 >> 16) & 0xff] << 16) ^
+        ((u32)Td4[(t0 >>  8) & 0xff] <<  8) ^
+        ((u32)Td4[(t3      ) & 0xff])       ^
+        rk[2];
+    PUTU32(out +  8, s2);
+    s3 =
+        ((u32)Td4[(t3 >> 24)       ] << 24) ^
+        ((u32)Td4[(t2 >> 16) & 0xff] << 16) ^
+        ((u32)Td4[(t1 >>  8) & 0xff] <<  8) ^
+        ((u32)Td4[(t0      ) & 0xff])       ^
+        rk[3];
+    PUTU32(out + 12, s3);
+}
+
+#else /* AES_ASM */
+
+static const u8 Te4[256] = {
+    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
+    0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
+    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
+    0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
+    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
+    0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
+    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
+    0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
+    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
+    0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
+    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
+    0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
+    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
+    0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
+    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
+    0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
+    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
+    0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
+    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
+    0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
+    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
+    0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
+    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
+    0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
+    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
+    0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
+    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
+    0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
+    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
+    0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
+    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
+    0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
+};
+static const u32 rcon[] = {
+    0x01000000, 0x02000000, 0x04000000, 0x08000000,
+    0x10000000, 0x20000000, 0x40000000, 0x80000000,
+    0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+
+/**
+ * Expand the cipher key into the encryption key schedule.
+ */
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+                        AES_KEY *key)
+{
+    u32 *rk;
+    int i = 0;
+    u32 temp;
+
+    if (!userKey || !key)
+        return -1;
+    if (bits != 128 && bits != 192 && bits != 256)
+        return -2;
+
+    rk = key->rd_key;
+
+    if (bits == 128)
+        key->rounds = 10;
+    else if (bits == 192)
+        key->rounds = 12;
+    else
+        key->rounds = 14;
+
+    rk[0] = GETU32(userKey     );
+    rk[1] = GETU32(userKey +  4);
+    rk[2] = GETU32(userKey +  8);
+    rk[3] = GETU32(userKey + 12);
+    if (bits == 128) {
+        while (1) {
+            temp  = rk[3];
+            rk[4] = rk[0] ^
+                ((u32)Te4[(temp >> 16) & 0xff] << 24) ^
+                ((u32)Te4[(temp >>  8) & 0xff] << 16) ^
+                ((u32)Te4[(temp      ) & 0xff] << 8) ^
+                ((u32)Te4[(temp >> 24)       ]) ^
+                rcon[i];
+            rk[5] = rk[1] ^ rk[4];
+            rk[6] = rk[2] ^ rk[5];
+            rk[7] = rk[3] ^ rk[6];
+            if (++i == 10) {
+                return 0;
+            }
+            rk += 4;
+        }
+    }
+    rk[4] = GETU32(userKey + 16);
+    rk[5] = GETU32(userKey + 20);
+    if (bits == 192) {
+        while (1) {
+            temp = rk[ 5];
+            rk[ 6] = rk[ 0] ^
+                ((u32)Te4[(temp >> 16) & 0xff] << 24) ^
+                ((u32)Te4[(temp >>  8) & 0xff] << 16) ^
+                ((u32)Te4[(temp      ) & 0xff] << 8) ^
+                ((u32)Te4[(temp >> 24)       ]) ^
+                rcon[i];
+            rk[ 7] = rk[ 1] ^ rk[ 6];
+            rk[ 8] = rk[ 2] ^ rk[ 7];
+            rk[ 9] = rk[ 3] ^ rk[ 8];
+            if (++i == 8) {
+                return 0;
+            }
+            rk[10] = rk[ 4] ^ rk[ 9];
+            rk[11] = rk[ 5] ^ rk[10];
+            rk += 6;
+        }
+    }
+    rk[6] = GETU32(userKey + 24);
+    rk[7] = GETU32(userKey + 28);
+    if (bits == 256) {
+        while (1) {
+            temp = rk[ 7];
+            rk[ 8] = rk[ 0] ^
+                ((u32)Te4[(temp >> 16) & 0xff] << 24) ^
+                ((u32)Te4[(temp >>  8) & 0xff] << 16) ^
+                ((u32)Te4[(temp      ) & 0xff] << 8) ^
+                ((u32)Te4[(temp >> 24)       ]) ^
+                rcon[i];
+            rk[ 9] = rk[ 1] ^ rk[ 8];
+            rk[10] = rk[ 2] ^ rk[ 9];
+            rk[11] = rk[ 3] ^ rk[10];
+            if (++i == 7) {
+                return 0;
+            }
+            temp = rk[11];
+            rk[12] = rk[ 4] ^
+                ((u32)Te4[(temp >> 24)       ] << 24) ^
+                ((u32)Te4[(temp >> 16) & 0xff] << 16) ^
+                ((u32)Te4[(temp >>  8) & 0xff] << 8) ^
+                ((u32)Te4[(temp      ) & 0xff]);
+            rk[13] = rk[ 5] ^ rk[12];
+            rk[14] = rk[ 6] ^ rk[13];
+            rk[15] = rk[ 7] ^ rk[14];
+
+            rk += 8;
+        }
+    }
+    return 0;
+}
+
+/**
+ * Expand the cipher key into the decryption key schedule.
+ */
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+                        AES_KEY *key)
+{
+
+    u32 *rk;
+    int i, j, status;
+    u32 temp;
+
+    /* first, start with an encryption schedule */
+    status = AES_set_encrypt_key(userKey, bits, key);
+    if (status < 0)
+        return status;
+
+    rk = key->rd_key;
+
+    /* invert the order of the round keys: */
+    for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
+        temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
+        temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
+        temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
+        temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
+    }
+    /* apply the inverse MixColumn transform to all round keys but the first and the last: */
+    for (i = 1; i < (key->rounds); i++) {
+        rk += 4;
+        for (j = 0; j < 4; j++) {
+            u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
+
+            tp1 = rk[j];
+            m = tp1 & 0x80808080;
+            tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
+                ((m - (m >> 7)) & 0x1b1b1b1b);
+            m = tp2 & 0x80808080;
+            tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
+                ((m - (m >> 7)) & 0x1b1b1b1b);
+            m = tp4 & 0x80808080;
+            tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
+                ((m - (m >> 7)) & 0x1b1b1b1b);
+            tp9 = tp8 ^ tp1;
+            tpb = tp9 ^ tp2;
+            tpd = tp9 ^ tp4;
+            tpe = tp8 ^ tp4 ^ tp2;
+#if defined(ROTATE)
+            rk[j] = tpe ^ ROTATE(tpd,16) ^
+                ROTATE(tp9,24) ^ ROTATE(tpb,8);
+#else
+            rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^
+                (tp9 >> 8) ^ (tp9 << 24) ^
+                (tpb >> 24) ^ (tpb << 8);
+#endif
+        }
+    }
+    return 0;
+}
+
+#endif /* AES_ASM */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_ecb.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_ecb.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_ecb.c	(revision 331)
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2002-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 <assert.h>
+
+#include <openssl/aes.h>
+#include "aes_locl.h"
+
+void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                     const AES_KEY *key, const int enc)
+{
+
+    assert(in && out && key);
+    assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc));
+
+    if (AES_ENCRYPT == enc)
+        AES_encrypt(in, out, key);
+    else
+        AES_decrypt(in, out, key);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_ige.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_ige.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_ige.c	(revision 331)
@@ -0,0 +1,281 @@
+/*
+ * Copyright 2006-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 "internal/cryptlib.h"
+
+#include <openssl/aes.h>
+#include "aes_locl.h"
+
+#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long))
+typedef struct {
+    unsigned long data[N_WORDS];
+} aes_block_t;
+
+/* XXX: probably some better way to do this */
+#if defined(__i386__) || defined(__x86_64__)
+# define UNALIGNED_MEMOPS_ARE_FAST 1
+#else
+# define UNALIGNED_MEMOPS_ARE_FAST 0
+#endif
+
+#if UNALIGNED_MEMOPS_ARE_FAST
+# define load_block(d, s)        (d) = *(const aes_block_t *)(s)
+# define store_block(d, s)       *(aes_block_t *)(d) = (s)
+#else
+# define load_block(d, s)        memcpy((d).data, (s), AES_BLOCK_SIZE)
+# define store_block(d, s)       memcpy((d), (s).data, AES_BLOCK_SIZE)
+#endif
+
+/* N.B. The IV for this mode is _twice_ the block size */
+
+void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
+                     size_t length, const AES_KEY *key,
+                     unsigned char *ivec, const int enc)
+{
+    size_t n;
+    size_t len = length;
+
+    OPENSSL_assert(in && out && key && ivec);
+    OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc));
+    OPENSSL_assert((length % AES_BLOCK_SIZE) == 0);
+
+    len = length / AES_BLOCK_SIZE;
+
+    if (AES_ENCRYPT == enc) {
+        if (in != out &&
+            (UNALIGNED_MEMOPS_ARE_FAST
+             || ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(long) ==
+             0)) {
+            aes_block_t *ivp = (aes_block_t *) ivec;
+            aes_block_t *iv2p = (aes_block_t *) (ivec + AES_BLOCK_SIZE);
+
+            while (len) {
+                aes_block_t *inp = (aes_block_t *) in;
+                aes_block_t *outp = (aes_block_t *) out;
+
+                for (n = 0; n < N_WORDS; ++n)
+                    outp->data[n] = inp->data[n] ^ ivp->data[n];
+                AES_encrypt((unsigned char *)outp->data,
+                            (unsigned char *)outp->data, key);
+                for (n = 0; n < N_WORDS; ++n)
+                    outp->data[n] ^= iv2p->data[n];
+                ivp = outp;
+                iv2p = inp;
+                --len;
+                in += AES_BLOCK_SIZE;
+                out += AES_BLOCK_SIZE;
+            }
+            memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
+            memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
+        } else {
+            aes_block_t tmp, tmp2;
+            aes_block_t iv;
+            aes_block_t iv2;
+
+            load_block(iv, ivec);
+            load_block(iv2, ivec + AES_BLOCK_SIZE);
+
+            while (len) {
+                load_block(tmp, in);
+                for (n = 0; n < N_WORDS; ++n)
+                    tmp2.data[n] = tmp.data[n] ^ iv.data[n];
+                AES_encrypt((unsigned char *)tmp2.data,
+                            (unsigned char *)tmp2.data, key);
+                for (n = 0; n < N_WORDS; ++n)
+                    tmp2.data[n] ^= iv2.data[n];
+                store_block(out, tmp2);
+                iv = tmp2;
+                iv2 = tmp;
+                --len;
+                in += AES_BLOCK_SIZE;
+                out += AES_BLOCK_SIZE;
+            }
+            memcpy(ivec, iv.data, AES_BLOCK_SIZE);
+            memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
+        }
+    } else {
+        if (in != out &&
+            (UNALIGNED_MEMOPS_ARE_FAST
+             || ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(long) ==
+             0)) {
+            aes_block_t *ivp = (aes_block_t *) ivec;
+            aes_block_t *iv2p = (aes_block_t *) (ivec + AES_BLOCK_SIZE);
+
+            while (len) {
+                aes_block_t tmp;
+                aes_block_t *inp = (aes_block_t *) in;
+                aes_block_t *outp = (aes_block_t *) out;
+
+                for (n = 0; n < N_WORDS; ++n)
+                    tmp.data[n] = inp->data[n] ^ iv2p->data[n];
+                AES_decrypt((unsigned char *)tmp.data,
+                            (unsigned char *)outp->data, key);
+                for (n = 0; n < N_WORDS; ++n)
+                    outp->data[n] ^= ivp->data[n];
+                ivp = inp;
+                iv2p = outp;
+                --len;
+                in += AES_BLOCK_SIZE;
+                out += AES_BLOCK_SIZE;
+            }
+            memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
+            memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
+        } else {
+            aes_block_t tmp, tmp2;
+            aes_block_t iv;
+            aes_block_t iv2;
+
+            load_block(iv, ivec);
+            load_block(iv2, ivec + AES_BLOCK_SIZE);
+
+            while (len) {
+                load_block(tmp, in);
+                tmp2 = tmp;
+                for (n = 0; n < N_WORDS; ++n)
+                    tmp.data[n] ^= iv2.data[n];
+                AES_decrypt((unsigned char *)tmp.data,
+                            (unsigned char *)tmp.data, key);
+                for (n = 0; n < N_WORDS; ++n)
+                    tmp.data[n] ^= iv.data[n];
+                store_block(out, tmp);
+                iv = tmp2;
+                iv2 = tmp;
+                --len;
+                in += AES_BLOCK_SIZE;
+                out += AES_BLOCK_SIZE;
+            }
+            memcpy(ivec, iv.data, AES_BLOCK_SIZE);
+            memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
+        }
+    }
+}
+
+/*
+ * Note that its effectively impossible to do biIGE in anything other
+ * than a single pass, so no provision is made for chaining.
+ */
+
+/* N.B. The IV for this mode is _four times_ the block size */
+
+void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
+                        size_t length, const AES_KEY *key,
+                        const AES_KEY *key2, const unsigned char *ivec,
+                        const int enc)
+{
+    size_t n;
+    size_t len = length;
+    unsigned char tmp[AES_BLOCK_SIZE];
+    unsigned char tmp2[AES_BLOCK_SIZE];
+    unsigned char tmp3[AES_BLOCK_SIZE];
+    unsigned char prev[AES_BLOCK_SIZE];
+    const unsigned char *iv;
+    const unsigned char *iv2;
+
+    OPENSSL_assert(in && out && key && ivec);
+    OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc));
+    OPENSSL_assert((length % AES_BLOCK_SIZE) == 0);
+
+    if (AES_ENCRYPT == enc) {
+        /*
+         * XXX: Do a separate case for when in != out (strictly should check
+         * for overlap, too)
+         */
+
+        /* First the forward pass */
+        iv = ivec;
+        iv2 = ivec + AES_BLOCK_SIZE;
+        while (len >= AES_BLOCK_SIZE) {
+            for (n = 0; n < AES_BLOCK_SIZE; ++n)
+                out[n] = in[n] ^ iv[n];
+            AES_encrypt(out, out, key);
+            for (n = 0; n < AES_BLOCK_SIZE; ++n)
+                out[n] ^= iv2[n];
+            iv = out;
+            memcpy(prev, in, AES_BLOCK_SIZE);
+            iv2 = prev;
+            len -= AES_BLOCK_SIZE;
+            in += AES_BLOCK_SIZE;
+            out += AES_BLOCK_SIZE;
+        }
+
+        /* And now backwards */
+        iv = ivec + AES_BLOCK_SIZE * 2;
+        iv2 = ivec + AES_BLOCK_SIZE * 3;
+        len = length;
+        while (len >= AES_BLOCK_SIZE) {
+            out -= AES_BLOCK_SIZE;
+            /*
+             * XXX: reduce copies by alternating between buffers
+             */
+            memcpy(tmp, out, AES_BLOCK_SIZE);
+            for (n = 0; n < AES_BLOCK_SIZE; ++n)
+                out[n] ^= iv[n];
+            /*
+             * hexdump(stdout, "out ^ iv", out, AES_BLOCK_SIZE);
+             */
+            AES_encrypt(out, out, key);
+            /*
+             * hexdump(stdout,"enc", out, AES_BLOCK_SIZE);
+             */
+            /*
+             * hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE);
+             */
+            for (n = 0; n < AES_BLOCK_SIZE; ++n)
+                out[n] ^= iv2[n];
+            /*
+             * hexdump(stdout,"out", out, AES_BLOCK_SIZE);
+             */
+            iv = out;
+            memcpy(prev, tmp, AES_BLOCK_SIZE);
+            iv2 = prev;
+            len -= AES_BLOCK_SIZE;
+        }
+    } else {
+        /* First backwards */
+        iv = ivec + AES_BLOCK_SIZE * 2;
+        iv2 = ivec + AES_BLOCK_SIZE * 3;
+        in += length;
+        out += length;
+        while (len >= AES_BLOCK_SIZE) {
+            in -= AES_BLOCK_SIZE;
+            out -= AES_BLOCK_SIZE;
+            memcpy(tmp, in, AES_BLOCK_SIZE);
+            memcpy(tmp2, in, AES_BLOCK_SIZE);
+            for (n = 0; n < AES_BLOCK_SIZE; ++n)
+                tmp[n] ^= iv2[n];
+            AES_decrypt(tmp, out, key);
+            for (n = 0; n < AES_BLOCK_SIZE; ++n)
+                out[n] ^= iv[n];
+            memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
+            iv = tmp3;
+            iv2 = out;
+            len -= AES_BLOCK_SIZE;
+        }
+
+        /* And now forwards */
+        iv = ivec;
+        iv2 = ivec + AES_BLOCK_SIZE;
+        len = length;
+        while (len >= AES_BLOCK_SIZE) {
+            memcpy(tmp, out, AES_BLOCK_SIZE);
+            memcpy(tmp2, out, AES_BLOCK_SIZE);
+            for (n = 0; n < AES_BLOCK_SIZE; ++n)
+                tmp[n] ^= iv2[n];
+            AES_decrypt(tmp, out, key);
+            for (n = 0; n < AES_BLOCK_SIZE; ++n)
+                out[n] ^= iv[n];
+            memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
+            iv = tmp3;
+            iv2 = out;
+            len -= AES_BLOCK_SIZE;
+            in += AES_BLOCK_SIZE;
+            out += AES_BLOCK_SIZE;
+        }
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_locl.h	(revision 331)
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2002-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
+ */
+
+#ifndef HEADER_AES_LOCL_H
+# define HEADER_AES_LOCL_H
+
+# include <openssl/e_os2.h>
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+
+# if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
+#  define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+#  define GETU32(p) SWAP(*((u32 *)(p)))
+#  define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
+# else
+#  define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] <<  8) ^ ((u32)(pt)[3]))
+#  define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >>  8); (ct)[3] = (u8)(st); }
+# endif
+
+# ifdef AES_LONG
+typedef unsigned long u32;
+# else
+typedef unsigned int u32;
+# endif
+typedef unsigned short u16;
+typedef unsigned char u8;
+
+# define MAXKC   (256/32)
+# define MAXKB   (256/8)
+# define MAXNR   14
+
+/* This controls loop-unrolling in aes_core.c */
+# undef FULL_UNROLL
+
+#endif                          /* !HEADER_AES_LOCL_H */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_misc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_misc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_misc.c	(revision 331)
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2002-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 <openssl/opensslv.h>
+#include <openssl/aes.h>
+#include "aes_locl.h"
+
+const char *AES_options(void)
+{
+#ifdef FULL_UNROLL
+    return "aes(full)";
+#else
+    return "aes(partial)";
+#endif
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_ofb.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_ofb.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_ofb.c	(revision 331)
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2002-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 <openssl/aes.h>
+#include <openssl/modes.h>
+
+void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+                        size_t length, const AES_KEY *key,
+                        unsigned char *ivec, int *num)
+{
+    CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num,
+                          (block128_f) AES_encrypt);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_wrap.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_wrap.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/aes/aes_wrap.c	(revision 331)
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2008-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 "internal/cryptlib.h"
+#include <openssl/aes.h>
+#include <openssl/modes.h>
+
+int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
+                 unsigned char *out,
+                 const unsigned char *in, unsigned int inlen)
+{
+    return CRYPTO_128_wrap(key, iv, out, in, inlen, (block128_f) AES_encrypt);
+}
+
+int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
+                   unsigned char *out,
+                   const unsigned char *in, unsigned int inlen)
+{
+    return CRYPTO_128_unwrap(key, iv, out, in, inlen,
+                             (block128_f) AES_decrypt);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/arm_arch.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/arm_arch.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/arm_arch.h	(revision 331)
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2011-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
+ */
+
+#ifndef __ARM_ARCH_H__
+# define __ARM_ARCH_H__
+
+# if !defined(__ARM_ARCH__)
+#  if defined(__CC_ARM)
+#   define __ARM_ARCH__ __TARGET_ARCH_ARM
+#   if defined(__BIG_ENDIAN)
+#    define __ARMEB__
+#   else
+#    define __ARMEL__
+#   endif
+#  elif defined(__GNUC__)
+#   if   defined(__aarch64__)
+#    define __ARM_ARCH__ 8
+#    if __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
+#     define __ARMEB__
+#    else
+#     define __ARMEL__
+#    endif
+  /*
+   * Why doesn't gcc define __ARM_ARCH__? Instead it defines
+   * bunch of below macros. See all_architectires[] table in
+   * gcc/config/arm/arm.c. On a side note it defines
+   * __ARMEL__/__ARMEB__ for little-/big-endian.
+   */
+#   elif defined(__ARM_ARCH)
+#    define __ARM_ARCH__ __ARM_ARCH
+#   elif defined(__ARM_ARCH_8A__)
+#    define __ARM_ARCH__ 8
+#   elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__)     || \
+        defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__)     || \
+        defined(__ARM_ARCH_7EM__)
+#    define __ARM_ARCH__ 7
+#   elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__)     || \
+        defined(__ARM_ARCH_6K__)|| defined(__ARM_ARCH_6M__)     || \
+        defined(__ARM_ARCH_6Z__)|| defined(__ARM_ARCH_6ZK__)    || \
+        defined(__ARM_ARCH_6T2__)
+#    define __ARM_ARCH__ 6
+#   elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__)     || \
+        defined(__ARM_ARCH_5E__)|| defined(__ARM_ARCH_5TE__)    || \
+        defined(__ARM_ARCH_5TEJ__)
+#    define __ARM_ARCH__ 5
+#   elif defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
+#    define __ARM_ARCH__ 4
+#   else
+#    error "unsupported ARM architecture"
+#   endif
+#  endif
+# endif
+
+# if !defined(__ARM_MAX_ARCH__)
+#  define __ARM_MAX_ARCH__ __ARM_ARCH__
+# endif
+
+# if __ARM_MAX_ARCH__<__ARM_ARCH__
+#  error "__ARM_MAX_ARCH__ can't be less than __ARM_ARCH__"
+# elif __ARM_MAX_ARCH__!=__ARM_ARCH__
+#  if __ARM_ARCH__<7 && __ARM_MAX_ARCH__>=7 && defined(__ARMEB__)
+#   error "can't build universal big-endian binary"
+#  endif
+# endif
+
+# if !__ASSEMBLER__
+extern unsigned int OPENSSL_armcap_P;
+# endif
+
+# define ARMV7_NEON      (1<<0)
+# define ARMV7_TICK      (1<<1)
+# define ARMV8_AES       (1<<2)
+# define ARMV8_SHA1      (1<<3)
+# define ARMV8_SHA256    (1<<4)
+# define ARMV8_PMULL     (1<<5)
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_bitstr.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_bitstr.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_bitstr.c	(revision 331)
@@ -0,0 +1,210 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include "asn1_locl.h"
+
+int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
+{
+    return ASN1_STRING_set(x, d, len);
+}
+
+int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
+{
+    int ret, j, bits, len;
+    unsigned char *p, *d;
+
+    if (a == NULL)
+        return (0);
+
+    len = a->length;
+
+    if (len > 0) {
+        if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) {
+            bits = (int)a->flags & 0x07;
+        } else {
+            for (; len > 0; len--) {
+                if (a->data[len - 1])
+                    break;
+            }
+            j = a->data[len - 1];
+            if (j & 0x01)
+                bits = 0;
+            else if (j & 0x02)
+                bits = 1;
+            else if (j & 0x04)
+                bits = 2;
+            else if (j & 0x08)
+                bits = 3;
+            else if (j & 0x10)
+                bits = 4;
+            else if (j & 0x20)
+                bits = 5;
+            else if (j & 0x40)
+                bits = 6;
+            else if (j & 0x80)
+                bits = 7;
+            else
+                bits = 0;       /* should not happen */
+        }
+    } else
+        bits = 0;
+
+    ret = 1 + len;
+    if (pp == NULL)
+        return (ret);
+
+    p = *pp;
+
+    *(p++) = (unsigned char)bits;
+    d = a->data;
+    if (len > 0) {
+        memcpy(p, d, len);
+        p += len;
+        p[-1] &= (0xff << bits);
+    }
+    *pp = p;
+    return (ret);
+}
+
+ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
+                                     const unsigned char **pp, long len)
+{
+    ASN1_BIT_STRING *ret = NULL;
+    const unsigned char *p;
+    unsigned char *s;
+    int i;
+
+    if (len < 1) {
+        i = ASN1_R_STRING_TOO_SHORT;
+        goto err;
+    }
+
+    if ((a == NULL) || ((*a) == NULL)) {
+        if ((ret = ASN1_BIT_STRING_new()) == NULL)
+            return (NULL);
+    } else
+        ret = (*a);
+
+    p = *pp;
+    i = *(p++);
+    if (i > 7) {
+        i = ASN1_R_INVALID_BIT_STRING_BITS_LEFT;
+        goto err;
+    }
+    /*
+     * We do this to preserve the settings.  If we modify the settings, via
+     * the _set_bit function, we will recalculate on output
+     */
+    ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */
+    ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | i); /* set */
+
+    if (len-- > 1) {            /* using one because of the bits left byte */
+        s = OPENSSL_malloc((int)len);
+        if (s == NULL) {
+            i = ERR_R_MALLOC_FAILURE;
+            goto err;
+        }
+        memcpy(s, p, (int)len);
+        s[len - 1] &= (0xff << i);
+        p += len;
+    } else
+        s = NULL;
+
+    ret->length = (int)len;
+    OPENSSL_free(ret->data);
+    ret->data = s;
+    ret->type = V_ASN1_BIT_STRING;
+    if (a != NULL)
+        (*a) = ret;
+    *pp = p;
+    return (ret);
+ err:
+    ASN1err(ASN1_F_C2I_ASN1_BIT_STRING, i);
+    if ((a == NULL) || (*a != ret))
+        ASN1_BIT_STRING_free(ret);
+    return (NULL);
+}
+
+/*
+ * These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
+ */
+int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
+{
+    int w, v, iv;
+    unsigned char *c;
+
+    w = n / 8;
+    v = 1 << (7 - (n & 0x07));
+    iv = ~v;
+    if (!value)
+        v = 0;
+
+    if (a == NULL)
+        return 0;
+
+    a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */
+
+    if ((a->length < (w + 1)) || (a->data == NULL)) {
+        if (!value)
+            return (1);         /* Don't need to set */
+        c = OPENSSL_clear_realloc(a->data, a->length, w + 1);
+        if (c == NULL) {
+            ASN1err(ASN1_F_ASN1_BIT_STRING_SET_BIT, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        if (w + 1 - a->length > 0)
+            memset(c + a->length, 0, w + 1 - a->length);
+        a->data = c;
+        a->length = w + 1;
+    }
+    a->data[w] = ((a->data[w]) & iv) | v;
+    while ((a->length > 0) && (a->data[a->length - 1] == 0))
+        a->length--;
+    return (1);
+}
+
+int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n)
+{
+    int w, v;
+
+    w = n / 8;
+    v = 1 << (7 - (n & 0x07));
+    if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL))
+        return (0);
+    return ((a->data[w] & v) != 0);
+}
+
+/*
+ * Checks if the given bit string contains only bits specified by
+ * the flags vector. Returns 0 if there is at least one bit set in 'a'
+ * which is not specified in 'flags', 1 otherwise.
+ * 'len' is the length of 'flags'.
+ */
+int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a,
+                          const unsigned char *flags, int flags_len)
+{
+    int i, ok;
+    /* Check if there is one bit set at all. */
+    if (!a || !a->data)
+        return 1;
+
+    /*
+     * Check each byte of the internal representation of the bit string.
+     */
+    ok = 1;
+    for (i = 0; i < a->length && ok; ++i) {
+        unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
+        /* We are done if there is an unneeded bit set. */
+        ok = (a->data[i] & mask) == 0;
+    }
+    return ok;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_d2i_fp.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_d2i_fp.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_d2i_fp.c	(revision 331)
@@ -0,0 +1,235 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <limits.h>
+#include "internal/cryptlib.h"
+#include "internal/numbers.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+
+static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb);
+
+#ifndef NO_OLD_ASN1
+# ifndef OPENSSL_NO_STDIO
+
+void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x)
+{
+    BIO *b;
+    void *ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        ASN1err(ASN1_F_ASN1_D2I_FP, ERR_R_BUF_LIB);
+        return (NULL);
+    }
+    BIO_set_fp(b, in, BIO_NOCLOSE);
+    ret = ASN1_d2i_bio(xnew, d2i, b, x);
+    BIO_free(b);
+    return (ret);
+}
+# endif
+
+void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x)
+{
+    BUF_MEM *b = NULL;
+    const unsigned char *p;
+    void *ret = NULL;
+    int len;
+
+    len = asn1_d2i_read_bio(in, &b);
+    if (len < 0)
+        goto err;
+
+    p = (unsigned char *)b->data;
+    ret = d2i(x, &p, len);
+ err:
+    BUF_MEM_free(b);
+    return (ret);
+}
+
+#endif
+
+void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x)
+{
+    BUF_MEM *b = NULL;
+    const unsigned char *p;
+    void *ret = NULL;
+    int len;
+
+    len = asn1_d2i_read_bio(in, &b);
+    if (len < 0)
+        goto err;
+
+    p = (const unsigned char *)b->data;
+    ret = ASN1_item_d2i(x, &p, len, it);
+ err:
+    BUF_MEM_free(b);
+    return (ret);
+}
+
+#ifndef OPENSSL_NO_STDIO
+void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
+{
+    BIO *b;
+    char *ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_D2I_FP, ERR_R_BUF_LIB);
+        return (NULL);
+    }
+    BIO_set_fp(b, in, BIO_NOCLOSE);
+    ret = ASN1_item_d2i_bio(it, b, x);
+    BIO_free(b);
+    return (ret);
+}
+#endif
+
+#define HEADER_SIZE   8
+#define ASN1_CHUNK_INITIAL_SIZE (16 * 1024)
+static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
+{
+    BUF_MEM *b;
+    unsigned char *p;
+    int i;
+    size_t want = HEADER_SIZE;
+    uint32_t eos = 0;
+    size_t off = 0;
+    size_t len = 0;
+
+    const unsigned char *q;
+    long slen;
+    int inf, tag, xclass;
+
+    b = BUF_MEM_new();
+    if (b == NULL) {
+        ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+
+    ERR_clear_error();
+    for (;;) {
+        if (want >= (len - off)) {
+            want -= (len - off);
+
+            if (len + want < len || !BUF_MEM_grow_clean(b, len + want)) {
+                ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            i = BIO_read(in, &(b->data[len]), want);
+            if ((i < 0) && ((len - off) == 0)) {
+                ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_NOT_ENOUGH_DATA);
+                goto err;
+            }
+            if (i > 0) {
+                if (len + i < len) {
+                    ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
+                    goto err;
+                }
+                len += i;
+            }
+        }
+        /* else data already loaded */
+
+        p = (unsigned char *)&(b->data[off]);
+        q = p;
+        inf = ASN1_get_object(&q, &slen, &tag, &xclass, len - off);
+        if (inf & 0x80) {
+            unsigned long e;
+
+            e = ERR_GET_REASON(ERR_peek_error());
+            if (e != ASN1_R_TOO_LONG)
+                goto err;
+            else
+                ERR_clear_error(); /* clear error */
+        }
+        i = q - p;            /* header length */
+        off += i;               /* end of data */
+
+        if (inf & 1) {
+            /* no data body so go round again */
+            if (eos == UINT32_MAX) {
+                ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_HEADER_TOO_LONG);
+                goto err;
+            }
+            eos++;
+            want = HEADER_SIZE;
+        } else if (eos && (slen == 0) && (tag == V_ASN1_EOC)) {
+            /* eos value, so go back and read another header */
+            eos--;
+            if (eos == 0)
+                break;
+            else
+                want = HEADER_SIZE;
+        } else {
+            /* suck in slen bytes of data */
+            want = slen;
+            if (want > (len - off)) {
+                size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE;
+
+                want -= (len - off);
+                if (want > INT_MAX /* BIO_read takes an int length */  ||
+                    len + want < len) {
+                    ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
+                    goto err;
+                }
+                while (want > 0) {
+                    /*
+                     * Read content in chunks of increasing size
+                     * so we can return an error for EOF without
+                     * having to allocate the entire content length
+                     * in one go.
+                     */
+                    size_t chunk = want > chunk_max ? chunk_max : want;
+
+                    if (!BUF_MEM_grow_clean(b, len + chunk)) {
+                        ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
+                        goto err;
+                    }
+                    want -= chunk;
+                    while (chunk > 0) {
+                        i = BIO_read(in, &(b->data[len]), chunk);
+                        if (i <= 0) {
+                            ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
+                                    ASN1_R_NOT_ENOUGH_DATA);
+                            goto err;
+                        }
+                    /*
+                     * This can't overflow because |len+want| didn't
+                     * overflow.
+                     */
+                        len += i;
+                        chunk -= i;
+                    }
+                    if (chunk_max < INT_MAX/2)
+                        chunk_max *= 2;
+                }
+            }
+            if (off + slen < off) {
+                ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
+                goto err;
+            }
+            off += slen;
+            if (eos == 0) {
+                break;
+            } else
+                want = HEADER_SIZE;
+        }
+    }
+
+    if (off > INT_MAX) {
+        ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
+        goto err;
+    }
+
+    *pb = b;
+    return off;
+ err:
+    BUF_MEM_free(b);
+    return -1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_digest.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_digest.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_digest.c	(revision 331)
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <time.h>
+
+#include "internal/cryptlib.h"
+
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/buffer.h>
+#include <openssl/x509.h>
+
+#ifndef NO_ASN1_OLD
+
+int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
+                unsigned char *md, unsigned int *len)
+{
+    int i;
+    unsigned char *str, *p;
+
+    i = i2d(data, NULL);
+    if ((str = OPENSSL_malloc(i)) == NULL) {
+        ASN1err(ASN1_F_ASN1_DIGEST, ERR_R_MALLOC_FAILURE);
+        return (0);
+    }
+    p = str;
+    i2d(data, &p);
+
+    if (!EVP_Digest(str, i, md, len, type, NULL)) {
+        OPENSSL_free(str);
+        return 0;
+    }
+    OPENSSL_free(str);
+    return (1);
+}
+
+#endif
+
+int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
+                     unsigned char *md, unsigned int *len)
+{
+    int i;
+    unsigned char *str = NULL;
+
+    i = ASN1_item_i2d(asn, &str, it);
+    if (!str)
+        return (0);
+
+    if (!EVP_Digest(str, i, md, len, type, NULL)) {
+        OPENSSL_free(str);
+        return 0;
+    }
+    OPENSSL_free(str);
+    return (1);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_dup.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_dup.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_dup.c	(revision 331)
@@ -0,0 +1,68 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+
+#ifndef NO_OLD_ASN1
+
+void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
+{
+    unsigned char *b, *p;
+    const unsigned char *p2;
+    int i;
+    char *ret;
+
+    if (x == NULL)
+        return (NULL);
+
+    i = i2d(x, NULL);
+    b = OPENSSL_malloc(i + 10);
+    if (b == NULL) {
+        ASN1err(ASN1_F_ASN1_DUP, ERR_R_MALLOC_FAILURE);
+        return (NULL);
+    }
+    p = b;
+    i = i2d(x, &p);
+    p2 = b;
+    ret = d2i(NULL, &p2, i);
+    OPENSSL_free(b);
+    return (ret);
+}
+
+#endif
+
+/*
+ * ASN1_ITEM version of dup: this follows the model above except we don't
+ * need to allocate the buffer. At some point this could be rewritten to
+ * directly dup the underlying structure instead of doing and encode and
+ * decode.
+ */
+
+void *ASN1_item_dup(const ASN1_ITEM *it, void *x)
+{
+    unsigned char *b = NULL;
+    const unsigned char *p;
+    long i;
+    void *ret;
+
+    if (x == NULL)
+        return (NULL);
+
+    i = ASN1_item_i2d(x, &b, it);
+    if (b == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_DUP, ERR_R_MALLOC_FAILURE);
+        return (NULL);
+    }
+    p = b;
+    ret = ASN1_item_d2i(NULL, &p, i, it);
+    OPENSSL_free(b);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_gentm.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_gentm.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_gentm.c	(revision 331)
@@ -0,0 +1,273 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*
+ * GENERALIZEDTIME implementation. Based on UTCTIME
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include "asn1_locl.h"
+
+int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d)
+{
+    static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 };
+    static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 };
+    char *a;
+    int n, i, l, o;
+
+    if (d->type != V_ASN1_GENERALIZEDTIME)
+        return (0);
+    l = d->length;
+    a = (char *)d->data;
+    o = 0;
+    /*
+     * GENERALIZEDTIME is similar to UTCTIME except the year is represented
+     * as YYYY. This stuff treats everything as a two digit field so make
+     * first two fields 00 to 99
+     */
+    if (l < 13)
+        goto err;
+    for (i = 0; i < 7; i++) {
+        if ((i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
+            i++;
+            if (tm)
+                tm->tm_sec = 0;
+            break;
+        }
+        if ((a[o] < '0') || (a[o] > '9'))
+            goto err;
+        n = a[o] - '0';
+        if (++o > l)
+            goto err;
+
+        if ((a[o] < '0') || (a[o] > '9'))
+            goto err;
+        n = (n * 10) + a[o] - '0';
+        if (++o > l)
+            goto err;
+
+        if ((n < min[i]) || (n > max[i]))
+            goto err;
+        if (tm) {
+            switch (i) {
+            case 0:
+                tm->tm_year = n * 100 - 1900;
+                break;
+            case 1:
+                tm->tm_year += n;
+                break;
+            case 2:
+                tm->tm_mon = n - 1;
+                break;
+            case 3:
+                tm->tm_mday = n;
+                break;
+            case 4:
+                tm->tm_hour = n;
+                break;
+            case 5:
+                tm->tm_min = n;
+                break;
+            case 6:
+                tm->tm_sec = n;
+                break;
+            }
+        }
+    }
+    /*
+     * Optional fractional seconds: decimal point followed by one or more
+     * digits.
+     */
+    if (a[o] == '.') {
+        if (++o > l)
+            goto err;
+        i = o;
+        while ((a[o] >= '0') && (a[o] <= '9') && (o <= l))
+            o++;
+        /* Must have at least one digit after decimal point */
+        if (i == o)
+            goto err;
+    }
+
+    if (a[o] == 'Z')
+        o++;
+    else if ((a[o] == '+') || (a[o] == '-')) {
+        int offsign = a[o] == '-' ? -1 : 1, offset = 0;
+        o++;
+        if (o + 4 > l)
+            goto err;
+        for (i = 7; i < 9; i++) {
+            if ((a[o] < '0') || (a[o] > '9'))
+                goto err;
+            n = a[o] - '0';
+            o++;
+            if ((a[o] < '0') || (a[o] > '9'))
+                goto err;
+            n = (n * 10) + a[o] - '0';
+            if ((n < min[i]) || (n > max[i]))
+                goto err;
+            if (tm) {
+                if (i == 7)
+                    offset = n * 3600;
+                else if (i == 8)
+                    offset += n * 60;
+            }
+            o++;
+        }
+        if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
+            return 0;
+    } else if (a[o]) {
+        /* Missing time zone information. */
+        goto err;
+    }
+    return (o == l);
+ err:
+    return (0);
+}
+
+int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d)
+{
+    return asn1_generalizedtime_to_tm(NULL, d);
+}
+
+int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str)
+{
+    ASN1_GENERALIZEDTIME t;
+
+    t.type = V_ASN1_GENERALIZEDTIME;
+    t.length = strlen(str);
+    t.data = (unsigned char *)str;
+    if (ASN1_GENERALIZEDTIME_check(&t)) {
+        if (s != NULL) {
+            if (!ASN1_STRING_set((ASN1_STRING *)s, str, t.length))
+                return 0;
+            s->type = V_ASN1_GENERALIZEDTIME;
+        }
+        return (1);
+    } else
+        return (0);
+}
+
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
+                                               time_t t)
+{
+    return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
+}
+
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
+                                               time_t t, int offset_day,
+                                               long offset_sec)
+{
+    char *p;
+    struct tm *ts;
+    struct tm data;
+    size_t len = 20;
+    ASN1_GENERALIZEDTIME *tmps = NULL;
+
+    if (s == NULL)
+        tmps = ASN1_GENERALIZEDTIME_new();
+    else
+        tmps = s;
+    if (tmps == NULL)
+        return NULL;
+
+    ts = OPENSSL_gmtime(&t, &data);
+    if (ts == NULL)
+        goto err;
+
+    if (offset_day || offset_sec) {
+        if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+            goto err;
+    }
+
+    p = (char *)tmps->data;
+    if ((p == NULL) || ((size_t)tmps->length < len)) {
+        p = OPENSSL_malloc(len);
+        if (p == NULL) {
+            ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        OPENSSL_free(tmps->data);
+        tmps->data = (unsigned char *)p;
+    }
+
+    BIO_snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ", ts->tm_year + 1900,
+                 ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min,
+                 ts->tm_sec);
+    tmps->length = strlen(p);
+    tmps->type = V_ASN1_GENERALIZEDTIME;
+#ifdef CHARSET_EBCDIC_not
+    ebcdic2ascii(tmps->data, tmps->data, tmps->length);
+#endif
+    return tmps;
+ err:
+    if (s == NULL)
+        ASN1_GENERALIZEDTIME_free(tmps);
+    return NULL;
+}
+
+const char *_asn1_mon[12] = {
+    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm)
+{
+    char *v;
+    int gmt = 0;
+    int i;
+    int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
+    char *f = NULL;
+    int f_len = 0;
+
+    i = tm->length;
+    v = (char *)tm->data;
+
+    if (i < 12)
+        goto err;
+    if (v[i - 1] == 'Z')
+        gmt = 1;
+    for (i = 0; i < 12; i++)
+        if ((v[i] > '9') || (v[i] < '0'))
+            goto err;
+    y = (v[0] - '0') * 1000 + (v[1] - '0') * 100
+        + (v[2] - '0') * 10 + (v[3] - '0');
+    M = (v[4] - '0') * 10 + (v[5] - '0');
+    if ((M > 12) || (M < 1))
+        goto err;
+    d = (v[6] - '0') * 10 + (v[7] - '0');
+    h = (v[8] - '0') * 10 + (v[9] - '0');
+    m = (v[10] - '0') * 10 + (v[11] - '0');
+    if (tm->length >= 14 &&
+        (v[12] >= '0') && (v[12] <= '9') &&
+        (v[13] >= '0') && (v[13] <= '9')) {
+        s = (v[12] - '0') * 10 + (v[13] - '0');
+        /* Check for fractions of seconds. */
+        if (tm->length >= 15 && v[14] == '.') {
+            int l = tm->length;
+            f = &v[14];         /* The decimal point. */
+            f_len = 1;
+            while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9')
+                ++f_len;
+        }
+    }
+
+    if (BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s",
+                   _asn1_mon[M - 1], d, h, m, s, f_len, f, y,
+                   (gmt) ? " GMT" : "") <= 0)
+        return (0);
+    else
+        return (1);
+ err:
+    BIO_write(bp, "Bad time value", 14);
+    return (0);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_i2d_fp.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_i2d_fp.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_i2d_fp.c	(revision 331)
@@ -0,0 +1,108 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+
+#ifndef NO_OLD_ASN1
+
+# ifndef OPENSSL_NO_STDIO
+int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
+{
+    BIO *b;
+    int ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        ASN1err(ASN1_F_ASN1_I2D_FP, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, out, BIO_NOCLOSE);
+    ret = ASN1_i2d_bio(i2d, b, x);
+    BIO_free(b);
+    return (ret);
+}
+# endif
+
+int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x)
+{
+    char *b;
+    unsigned char *p;
+    int i, j = 0, n, ret = 1;
+
+    n = i2d(x, NULL);
+    b = OPENSSL_malloc(n);
+    if (b == NULL) {
+        ASN1err(ASN1_F_ASN1_I2D_BIO, ERR_R_MALLOC_FAILURE);
+        return (0);
+    }
+
+    p = (unsigned char *)b;
+    i2d(x, &p);
+
+    for (;;) {
+        i = BIO_write(out, &(b[j]), n);
+        if (i == n)
+            break;
+        if (i <= 0) {
+            ret = 0;
+            break;
+        }
+        j += i;
+        n -= i;
+    }
+    OPENSSL_free(b);
+    return (ret);
+}
+
+#endif
+
+#ifndef OPENSSL_NO_STDIO
+int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
+{
+    BIO *b;
+    int ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_I2D_FP, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, out, BIO_NOCLOSE);
+    ret = ASN1_item_i2d_bio(it, b, x);
+    BIO_free(b);
+    return (ret);
+}
+#endif
+
+int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
+{
+    unsigned char *b = NULL;
+    int i, j = 0, n, ret = 1;
+
+    n = ASN1_item_i2d(x, &b, it);
+    if (b == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_I2D_BIO, ERR_R_MALLOC_FAILURE);
+        return (0);
+    }
+
+    for (;;) {
+        i = BIO_write(out, &(b[j]), n);
+        if (i == n)
+            break;
+        if (i <= 0) {
+            ret = 0;
+            break;
+        }
+        j += i;
+        n -= i;
+    }
+    OPENSSL_free(b);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_int.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_int.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_int.c	(revision 331)
@@ -0,0 +1,624 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include "internal/numbers.h"
+#include <limits.h>
+#include <openssl/asn1.h>
+#include <openssl/bn.h>
+#include "asn1_locl.h"
+
+ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
+{
+    return ASN1_STRING_dup(x);
+}
+
+int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
+{
+    int neg, ret;
+    /* Compare signs */
+    neg = x->type & V_ASN1_NEG;
+    if (neg != (y->type & V_ASN1_NEG)) {
+        if (neg)
+            return -1;
+        else
+            return 1;
+    }
+
+    ret = ASN1_STRING_cmp(x, y);
+
+    if (neg)
+        return -ret;
+    else
+        return ret;
+}
+
+/*-
+ * This converts a big endian buffer and sign into its content encoding.
+ * This is used for INTEGER and ENUMERATED types.
+ * The internal representation is an ASN1_STRING whose data is a big endian
+ * representation of the value, ignoring the sign. The sign is determined by
+ * the type: if type & V_ASN1_NEG is true it is negative, otherwise positive.
+ *
+ * Positive integers are no problem: they are almost the same as the DER
+ * encoding, except if the first byte is >= 0x80 we need to add a zero pad.
+ *
+ * Negative integers are a bit trickier...
+ * The DER representation of negative integers is in 2s complement form.
+ * The internal form is converted by complementing each octet and finally
+ * adding one to the result. This can be done less messily with a little trick.
+ * If the internal form has trailing zeroes then they will become FF by the
+ * complement and 0 by the add one (due to carry) so just copy as many trailing
+ * zeros to the destination as there are in the source. The carry will add one
+ * to the last none zero octet: so complement this octet and add one and finally
+ * complement any left over until you get to the start of the string.
+ *
+ * Padding is a little trickier too. If the first bytes is > 0x80 then we pad
+ * with 0xff. However if the first byte is 0x80 and one of the following bytes
+ * is non-zero we pad with 0xff. The reason for this distinction is that 0x80
+ * followed by optional zeros isn't padded.
+ */
+
+static size_t i2c_ibuf(const unsigned char *b, size_t blen, int neg,
+                       unsigned char **pp)
+{
+    int pad = 0;
+    size_t ret, i;
+    unsigned char *p, pb = 0;
+    const unsigned char *n;
+
+    if (b == NULL || blen == 0)
+        ret = 1;
+    else {
+        ret = blen;
+        i = b[0];
+        if (ret == 1 && i == 0)
+            neg = 0;
+        if (!neg && (i > 127)) {
+            pad = 1;
+            pb = 0;
+        } else if (neg) {
+            if (i > 128) {
+                pad = 1;
+                pb = 0xFF;
+            } else if (i == 128) {
+                /*
+                 * Special case: if any other bytes non zero we pad:
+                 * otherwise we don't.
+                 */
+                for (i = 1; i < blen; i++)
+                    if (b[i]) {
+                        pad = 1;
+                        pb = 0xFF;
+                        break;
+                    }
+            }
+        }
+        ret += pad;
+    }
+    if (pp == NULL)
+        return ret;
+    p = *pp;
+
+    if (pad)
+        *(p++) = pb;
+    if (b == NULL || blen == 0)
+        *p = 0;
+    else if (!neg)
+        memcpy(p, b, blen);
+    else {
+        /* Begin at the end of the encoding */
+        n = b + blen;
+        p += blen;
+        i = blen;
+        /* Copy zeros to destination as long as source is zero */
+        while (!n[-1] && i > 1) {
+            *(--p) = 0;
+            n--;
+            i--;
+        }
+        /* Complement and increment next octet */
+        *(--p) = ((*(--n)) ^ 0xff) + 1;
+        i--;
+        /* Complement any octets left */
+        for (; i > 0; i--)
+            *(--p) = *(--n) ^ 0xff;
+    }
+
+    *pp += ret;
+    return ret;
+}
+
+/*
+ * convert content octets into a big endian buffer. Returns the length
+ * of buffer or 0 on error: for malformed INTEGER. If output buffer is
+ * NULL just return length.
+ */
+
+static size_t c2i_ibuf(unsigned char *b, int *pneg,
+                       const unsigned char *p, size_t plen)
+{
+    size_t i;
+    int neg, pad;
+    /* Zero content length is illegal */
+    if (plen == 0) {
+        ASN1err(ASN1_F_C2I_IBUF, ASN1_R_ILLEGAL_ZERO_CONTENT);
+        return 0;
+    }
+    neg = p[0] & 0x80;
+    if (pneg)
+        *pneg = neg;
+    /* Handle common case where length is 1 octet separately */
+    if (plen == 1) {
+        if (b) {
+            if (neg)
+                b[0] = (p[0] ^ 0xFF) + 1;
+            else
+                b[0] = p[0];
+        }
+        return 1;
+    }
+    if (p[0] == 0 || p[0] == 0xFF)
+        pad = 1;
+    else
+        pad = 0;
+    /* reject illegal padding: first two octets MSB can't match */
+    if (pad && (neg == (p[1] & 0x80))) {
+        ASN1err(ASN1_F_C2I_IBUF, ASN1_R_ILLEGAL_PADDING);
+        return 0;
+    }
+    /* If positive just copy across */
+    if (neg == 0) {
+        if (b)
+            memcpy(b, p + pad, plen - pad);
+        return plen - pad;
+    }
+
+    if (neg && pad) {
+        /* check is any following octets are non zero */
+        for (i = 1; i < plen; i++) {
+            if (p[i] != 0)
+                break;
+        }
+        /* if all bytes are zero handle as special case */
+        if (i == plen) {
+            if (b) {
+                b[0] = 1;
+                memset(b + 1, 0, plen - 1);
+            }
+            return plen;
+        }
+    }
+
+    plen -= pad;
+    /* Must be negative: calculate twos complement */
+    if (b) {
+        const unsigned char *from = p + plen - 1 + pad;
+        unsigned char *to = b + plen;
+        i = plen;
+        while (*from == 0 && i) {
+            *--to = 0;
+            i--;
+            from--;
+        }
+        *--to = (*from-- ^ 0xff) + 1;
+        OPENSSL_assert(i != 0);
+        i--;
+        for (; i > 0; i--)
+            *--to = *from-- ^ 0xff;
+    }
+    return plen;
+}
+
+int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
+{
+    return i2c_ibuf(a->data, a->length, a->type & V_ASN1_NEG, pp);
+}
+
+/* Convert big endian buffer into uint64_t, return 0 on error */
+static int asn1_get_uint64(uint64_t *pr, const unsigned char *b, size_t blen)
+{
+    size_t i;
+    if (blen > sizeof(*pr)) {
+        ASN1err(ASN1_F_ASN1_GET_UINT64, ASN1_R_TOO_LARGE);
+        return 0;
+    }
+    *pr = 0;
+    if (b == NULL)
+        return 0;
+    for (i = 0; i < blen; i++) {
+        *pr <<= 8;
+        *pr |= b[i];
+    }
+    return 1;
+}
+
+static size_t asn1_put_uint64(unsigned char *b, uint64_t r)
+{
+    if (r >= 0x100) {
+        unsigned char *p;
+        uint64_t rtmp = r;
+        size_t i = 0;
+
+        /* Work out how many bytes we need */
+        while (rtmp) {
+            rtmp >>= 8;
+            i++;
+        }
+
+        /* Copy from end to beginning */
+        p = b + i - 1;
+
+        do {
+            *p-- = r & 0xFF;
+            r >>= 8;
+        } while (p >= b);
+
+        return i;
+    }
+
+    b[0] = (unsigned char)r;
+    return 1;
+
+}
+
+/*
+ * Absolute value of INT64_MIN: we can't just use -INT64_MIN as it produces
+ * overflow warnings.
+ */
+
+#define ABS_INT64_MIN \
+    ((uint64_t)INT64_MAX + (uint64_t)(-(INT64_MIN + INT64_MAX)))
+
+/* signed version of asn1_get_uint64 */
+static int asn1_get_int64(int64_t *pr, const unsigned char *b, size_t blen,
+                          int neg)
+{
+    uint64_t r;
+    if (asn1_get_uint64(&r, b, blen) == 0)
+        return 0;
+    if (neg) {
+        if (r > ABS_INT64_MIN) {
+            ASN1err(ASN1_F_ASN1_GET_INT64, ASN1_R_TOO_SMALL);
+            return 0;
+        }
+        *pr = 0 - (uint64_t)r;
+    } else {
+        if (r > INT64_MAX) {
+            ASN1err(ASN1_F_ASN1_GET_INT64, ASN1_R_TOO_LARGE);
+            return 0;
+        }
+        *pr = (int64_t)r;
+    }
+    return 1;
+}
+
+/* Convert ASN1 INTEGER content octets to ASN1_INTEGER structure */
+ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
+                               long len)
+{
+    ASN1_INTEGER *ret = NULL;
+    size_t r;
+    int neg;
+
+    r = c2i_ibuf(NULL, NULL, *pp, len);
+
+    if (r == 0)
+        return NULL;
+
+    if ((a == NULL) || ((*a) == NULL)) {
+        ret = ASN1_INTEGER_new();
+        if (ret == NULL)
+            return NULL;
+        ret->type = V_ASN1_INTEGER;
+    } else
+        ret = *a;
+
+    if (ASN1_STRING_set(ret, NULL, r) == 0)
+        goto err;
+
+    c2i_ibuf(ret->data, &neg, *pp, len);
+
+    if (neg)
+        ret->type |= V_ASN1_NEG;
+
+    *pp += len;
+    if (a != NULL)
+        (*a) = ret;
+    return ret;
+ err:
+    ASN1err(ASN1_F_C2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
+    if ((a == NULL) || (*a != ret))
+        ASN1_INTEGER_free(ret);
+    return NULL;
+}
+
+static int asn1_string_get_int64(int64_t *pr, const ASN1_STRING *a, int itype)
+{
+    if (a == NULL) {
+        ASN1err(ASN1_F_ASN1_STRING_GET_INT64, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    if ((a->type & ~V_ASN1_NEG) != itype) {
+        ASN1err(ASN1_F_ASN1_STRING_GET_INT64, ASN1_R_WRONG_INTEGER_TYPE);
+        return 0;
+    }
+    return asn1_get_int64(pr, a->data, a->length, a->type & V_ASN1_NEG);
+}
+
+static int asn1_string_set_int64(ASN1_STRING *a, int64_t r, int itype)
+{
+    unsigned char tbuf[sizeof(r)];
+    size_t l;
+    a->type = itype;
+    if (r < 0) {
+        l = asn1_put_uint64(tbuf, -r);
+        a->type |= V_ASN1_NEG;
+    } else {
+        l = asn1_put_uint64(tbuf, r);
+        a->type &= ~V_ASN1_NEG;
+    }
+    if (l == 0)
+        return 0;
+    return ASN1_STRING_set(a, tbuf, l);
+}
+
+static int asn1_string_get_uint64(uint64_t *pr, const ASN1_STRING *a,
+                                  int itype)
+{
+    if (a == NULL) {
+        ASN1err(ASN1_F_ASN1_STRING_GET_UINT64, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    if ((a->type & ~V_ASN1_NEG) != itype) {
+        ASN1err(ASN1_F_ASN1_STRING_GET_UINT64, ASN1_R_WRONG_INTEGER_TYPE);
+        return 0;
+    }
+    if (a->type & V_ASN1_NEG) {
+        ASN1err(ASN1_F_ASN1_STRING_GET_UINT64, ASN1_R_ILLEGAL_NEGATIVE_VALUE);
+        return 0;
+    }
+    return asn1_get_uint64(pr, a->data, a->length);
+}
+
+static int asn1_string_set_uint64(ASN1_STRING *a, uint64_t r, int itype)
+{
+    unsigned char tbuf[sizeof(r)];
+    size_t l;
+    a->type = itype;
+    l = asn1_put_uint64(tbuf, r);
+    if (l == 0)
+        return 0;
+    return ASN1_STRING_set(a, tbuf, l);
+}
+
+/*
+ * This is a version of d2i_ASN1_INTEGER that ignores the sign bit of ASN1
+ * integers: some broken software can encode a positive INTEGER with its MSB
+ * set as negative (it doesn't add a padding zero).
+ */
+
+ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
+                                long length)
+{
+    ASN1_INTEGER *ret = NULL;
+    const unsigned char *p;
+    unsigned char *s;
+    long len;
+    int inf, tag, xclass;
+    int i;
+
+    if ((a == NULL) || ((*a) == NULL)) {
+        if ((ret = ASN1_INTEGER_new()) == NULL)
+            return (NULL);
+        ret->type = V_ASN1_INTEGER;
+    } else
+        ret = (*a);
+
+    p = *pp;
+    inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+    if (inf & 0x80) {
+        i = ASN1_R_BAD_OBJECT_HEADER;
+        goto err;
+    }
+
+    if (tag != V_ASN1_INTEGER) {
+        i = ASN1_R_EXPECTING_AN_INTEGER;
+        goto err;
+    }
+
+    /*
+     * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
+     * a missing NULL parameter.
+     */
+    s = OPENSSL_malloc((int)len + 1);
+    if (s == NULL) {
+        i = ERR_R_MALLOC_FAILURE;
+        goto err;
+    }
+    ret->type = V_ASN1_INTEGER;
+    if (len) {
+        if ((*p == 0) && (len != 1)) {
+            p++;
+            len--;
+        }
+        memcpy(s, p, (int)len);
+        p += len;
+    }
+
+    OPENSSL_free(ret->data);
+    ret->data = s;
+    ret->length = (int)len;
+    if (a != NULL)
+        (*a) = ret;
+    *pp = p;
+    return (ret);
+ err:
+    ASN1err(ASN1_F_D2I_ASN1_UINTEGER, i);
+    if ((a == NULL) || (*a != ret))
+        ASN1_INTEGER_free(ret);
+    return (NULL);
+}
+
+static ASN1_STRING *bn_to_asn1_string(const BIGNUM *bn, ASN1_STRING *ai,
+                                      int atype)
+{
+    ASN1_INTEGER *ret;
+    int len;
+
+    if (ai == NULL) {
+        ret = ASN1_STRING_type_new(atype);
+    } else {
+        ret = ai;
+        ret->type = atype;
+    }
+
+    if (ret == NULL) {
+        ASN1err(ASN1_F_BN_TO_ASN1_STRING, ERR_R_NESTED_ASN1_ERROR);
+        goto err;
+    }
+
+    if (BN_is_negative(bn) && !BN_is_zero(bn))
+        ret->type |= V_ASN1_NEG_INTEGER;
+
+    len = BN_num_bytes(bn);
+
+    if (len == 0)
+        len = 1;
+
+    if (ASN1_STRING_set(ret, NULL, len) == 0) {
+        ASN1err(ASN1_F_BN_TO_ASN1_STRING, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    /* Correct zero case */
+    if (BN_is_zero(bn))
+        ret->data[0] = 0;
+    else
+        len = BN_bn2bin(bn, ret->data);
+    ret->length = len;
+    return ret;
+ err:
+    if (ret != ai)
+        ASN1_INTEGER_free(ret);
+    return (NULL);
+}
+
+static BIGNUM *asn1_string_to_bn(const ASN1_INTEGER *ai, BIGNUM *bn,
+                                 int itype)
+{
+    BIGNUM *ret;
+
+    if ((ai->type & ~V_ASN1_NEG) != itype) {
+        ASN1err(ASN1_F_ASN1_STRING_TO_BN, ASN1_R_WRONG_INTEGER_TYPE);
+        return NULL;
+    }
+
+    ret = BN_bin2bn(ai->data, ai->length, bn);
+    if (ret == 0) {
+        ASN1err(ASN1_F_ASN1_STRING_TO_BN, ASN1_R_BN_LIB);
+        return NULL;
+    }
+    if (ai->type & V_ASN1_NEG)
+        BN_set_negative(ret, 1);
+    return ret;
+}
+
+int ASN1_INTEGER_get_int64(int64_t *pr, const ASN1_INTEGER *a)
+{
+    return asn1_string_get_int64(pr, a, V_ASN1_INTEGER);
+}
+
+int ASN1_INTEGER_set_int64(ASN1_INTEGER *a, int64_t r)
+{
+    return asn1_string_set_int64(a, r, V_ASN1_INTEGER);
+}
+
+int ASN1_INTEGER_get_uint64(uint64_t *pr, const ASN1_INTEGER *a)
+{
+    return asn1_string_get_uint64(pr, a, V_ASN1_INTEGER);
+}
+
+int ASN1_INTEGER_set_uint64(ASN1_INTEGER *a, uint64_t r)
+{
+    return asn1_string_set_uint64(a, r, V_ASN1_INTEGER);
+}
+
+int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
+{
+    return ASN1_INTEGER_set_int64(a, v);
+}
+
+long ASN1_INTEGER_get(const ASN1_INTEGER *a)
+{
+    int i;
+    int64_t r;
+    if (a == NULL)
+        return 0;
+    i = ASN1_INTEGER_get_int64(&r, a);
+    if (i == 0)
+        return -1;
+    if (r > LONG_MAX || r < LONG_MIN)
+        return -1;
+    return (long)r;
+}
+
+ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
+{
+    return bn_to_asn1_string(bn, ai, V_ASN1_INTEGER);
+}
+
+BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
+{
+    return asn1_string_to_bn(ai, bn, V_ASN1_INTEGER);
+}
+
+int ASN1_ENUMERATED_get_int64(int64_t *pr, const ASN1_ENUMERATED *a)
+{
+    return asn1_string_get_int64(pr, a, V_ASN1_ENUMERATED);
+}
+
+int ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *a, int64_t r)
+{
+    return asn1_string_set_int64(a, r, V_ASN1_ENUMERATED);
+}
+
+int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
+{
+    return ASN1_ENUMERATED_set_int64(a, v);
+}
+
+long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a)
+{
+    int i;
+    int64_t r;
+    if (a == NULL)
+        return 0;
+    if ((a->type & ~V_ASN1_NEG) != V_ASN1_ENUMERATED)
+        return -1;
+    if (a->length > (int)sizeof(long))
+        return 0xffffffffL;
+    i = ASN1_ENUMERATED_get_int64(&r, a);
+    if (i == 0)
+        return -1;
+    if (r > LONG_MAX || r < LONG_MIN)
+        return -1;
+    return (long)r;
+}
+
+ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai)
+{
+    return bn_to_asn1_string(bn, ai, V_ASN1_ENUMERATED);
+}
+
+BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn)
+{
+    return asn1_string_to_bn(ai, bn, V_ASN1_ENUMERATED);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_mbstr.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_mbstr.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_mbstr.c	(revision 331)
@@ -0,0 +1,395 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include <ctype.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+
+static int traverse_string(const unsigned char *p, int len, int inform,
+                           int (*rfunc) (unsigned long value, void *in),
+                           void *arg);
+static int in_utf8(unsigned long value, void *arg);
+static int out_utf8(unsigned long value, void *arg);
+static int type_str(unsigned long value, void *arg);
+static int cpy_asc(unsigned long value, void *arg);
+static int cpy_bmp(unsigned long value, void *arg);
+static int cpy_univ(unsigned long value, void *arg);
+static int cpy_utf8(unsigned long value, void *arg);
+static int is_numeric(unsigned long value);
+static int is_printable(unsigned long value);
+
+/*
+ * These functions take a string in UTF8, ASCII or multibyte form and a mask
+ * of permissible ASN1 string types. It then works out the minimal type
+ * (using the order Numeric < Printable < IA5 < T61 < BMP < Universal < UTF8)
+ * and creates a string of the correct type with the supplied data. Yes this is
+ * horrible: it has to be :-( The 'ncopy' form checks minimum and maximum
+ * size limits too.
+ */
+
+int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
+                       int inform, unsigned long mask)
+{
+    return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
+}
+
+int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
+                        int inform, unsigned long mask,
+                        long minsize, long maxsize)
+{
+    int str_type;
+    int ret;
+    char free_out;
+    int outform, outlen = 0;
+    ASN1_STRING *dest;
+    unsigned char *p;
+    int nchar;
+    char strbuf[32];
+    int (*cpyfunc) (unsigned long, void *) = NULL;
+    if (len == -1)
+        len = strlen((const char *)in);
+    if (!mask)
+        mask = DIRSTRING_TYPE;
+
+    /* First do a string check and work out the number of characters */
+    switch (inform) {
+
+    case MBSTRING_BMP:
+        if (len & 1) {
+            ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
+                    ASN1_R_INVALID_BMPSTRING_LENGTH);
+            return -1;
+        }
+        nchar = len >> 1;
+        break;
+
+    case MBSTRING_UNIV:
+        if (len & 3) {
+            ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
+                    ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
+            return -1;
+        }
+        nchar = len >> 2;
+        break;
+
+    case MBSTRING_UTF8:
+        nchar = 0;
+        /* This counts the characters and does utf8 syntax checking */
+        ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
+        if (ret < 0) {
+            ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_INVALID_UTF8STRING);
+            return -1;
+        }
+        break;
+
+    case MBSTRING_ASC:
+        nchar = len;
+        break;
+
+    default:
+        ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT);
+        return -1;
+    }
+
+    if ((minsize > 0) && (nchar < minsize)) {
+        ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT);
+        BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize);
+        ERR_add_error_data(2, "minsize=", strbuf);
+        return -1;
+    }
+
+    if ((maxsize > 0) && (nchar > maxsize)) {
+        ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG);
+        BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
+        ERR_add_error_data(2, "maxsize=", strbuf);
+        return -1;
+    }
+
+    /* Now work out minimal type (if any) */
+    if (traverse_string(in, len, inform, type_str, &mask) < 0) {
+        ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS);
+        return -1;
+    }
+
+    /* Now work out output format and string type */
+    outform = MBSTRING_ASC;
+    if (mask & B_ASN1_NUMERICSTRING)
+        str_type = V_ASN1_NUMERICSTRING;
+    else if (mask & B_ASN1_PRINTABLESTRING)
+        str_type = V_ASN1_PRINTABLESTRING;
+    else if (mask & B_ASN1_IA5STRING)
+        str_type = V_ASN1_IA5STRING;
+    else if (mask & B_ASN1_T61STRING)
+        str_type = V_ASN1_T61STRING;
+    else if (mask & B_ASN1_BMPSTRING) {
+        str_type = V_ASN1_BMPSTRING;
+        outform = MBSTRING_BMP;
+    } else if (mask & B_ASN1_UNIVERSALSTRING) {
+        str_type = V_ASN1_UNIVERSALSTRING;
+        outform = MBSTRING_UNIV;
+    } else {
+        str_type = V_ASN1_UTF8STRING;
+        outform = MBSTRING_UTF8;
+    }
+    if (!out)
+        return str_type;
+    if (*out) {
+        free_out = 0;
+        dest = *out;
+        OPENSSL_free(dest->data);
+        dest->data = NULL;
+        dest->length = 0;
+        dest->type = str_type;
+    } else {
+        free_out = 1;
+        dest = ASN1_STRING_type_new(str_type);
+        if (dest == NULL) {
+            ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);
+            return -1;
+        }
+        *out = dest;
+    }
+    /* If both the same type just copy across */
+    if (inform == outform) {
+        if (!ASN1_STRING_set(dest, in, len)) {
+            ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);
+            return -1;
+        }
+        return str_type;
+    }
+
+    /* Work out how much space the destination will need */
+    switch (outform) {
+    case MBSTRING_ASC:
+        outlen = nchar;
+        cpyfunc = cpy_asc;
+        break;
+
+    case MBSTRING_BMP:
+        outlen = nchar << 1;
+        cpyfunc = cpy_bmp;
+        break;
+
+    case MBSTRING_UNIV:
+        outlen = nchar << 2;
+        cpyfunc = cpy_univ;
+        break;
+
+    case MBSTRING_UTF8:
+        outlen = 0;
+        traverse_string(in, len, inform, out_utf8, &outlen);
+        cpyfunc = cpy_utf8;
+        break;
+    }
+    if ((p = OPENSSL_malloc(outlen + 1)) == NULL) {
+        if (free_out)
+            ASN1_STRING_free(dest);
+        ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+    dest->length = outlen;
+    dest->data = p;
+    p[outlen] = 0;
+    traverse_string(in, len, inform, cpyfunc, &p);
+    return str_type;
+}
+
+/*
+ * This function traverses a string and passes the value of each character to
+ * an optional function along with a void * argument.
+ */
+
+static int traverse_string(const unsigned char *p, int len, int inform,
+                           int (*rfunc) (unsigned long value, void *in),
+                           void *arg)
+{
+    unsigned long value;
+    int ret;
+    while (len) {
+        if (inform == MBSTRING_ASC) {
+            value = *p++;
+            len--;
+        } else if (inform == MBSTRING_BMP) {
+            value = *p++ << 8;
+            value |= *p++;
+            len -= 2;
+        } else if (inform == MBSTRING_UNIV) {
+            value = ((unsigned long)*p++) << 24;
+            value |= ((unsigned long)*p++) << 16;
+            value |= *p++ << 8;
+            value |= *p++;
+            len -= 4;
+        } else {
+            ret = UTF8_getc(p, len, &value);
+            if (ret < 0)
+                return -1;
+            len -= ret;
+            p += ret;
+        }
+        if (rfunc) {
+            ret = rfunc(value, arg);
+            if (ret <= 0)
+                return ret;
+        }
+    }
+    return 1;
+}
+
+/* Various utility functions for traverse_string */
+
+/* Just count number of characters */
+
+static int in_utf8(unsigned long value, void *arg)
+{
+    int *nchar;
+    nchar = arg;
+    (*nchar)++;
+    return 1;
+}
+
+/* Determine size of output as a UTF8 String */
+
+static int out_utf8(unsigned long value, void *arg)
+{
+    int *outlen;
+    outlen = arg;
+    *outlen += UTF8_putc(NULL, -1, value);
+    return 1;
+}
+
+/*
+ * Determine the "type" of a string: check each character against a supplied
+ * "mask".
+ */
+
+static int type_str(unsigned long value, void *arg)
+{
+    unsigned long types;
+    types = *((unsigned long *)arg);
+    if ((types & B_ASN1_NUMERICSTRING) && !is_numeric(value))
+        types &= ~B_ASN1_NUMERICSTRING;
+    if ((types & B_ASN1_PRINTABLESTRING) && !is_printable(value))
+        types &= ~B_ASN1_PRINTABLESTRING;
+    if ((types & B_ASN1_IA5STRING) && (value > 127))
+        types &= ~B_ASN1_IA5STRING;
+    if ((types & B_ASN1_T61STRING) && (value > 0xff))
+        types &= ~B_ASN1_T61STRING;
+    if ((types & B_ASN1_BMPSTRING) && (value > 0xffff))
+        types &= ~B_ASN1_BMPSTRING;
+    if (!types)
+        return -1;
+    *((unsigned long *)arg) = types;
+    return 1;
+}
+
+/* Copy one byte per character ASCII like strings */
+
+static int cpy_asc(unsigned long value, void *arg)
+{
+    unsigned char **p, *q;
+    p = arg;
+    q = *p;
+    *q = (unsigned char)value;
+    (*p)++;
+    return 1;
+}
+
+/* Copy two byte per character BMPStrings */
+
+static int cpy_bmp(unsigned long value, void *arg)
+{
+    unsigned char **p, *q;
+    p = arg;
+    q = *p;
+    *q++ = (unsigned char)((value >> 8) & 0xff);
+    *q = (unsigned char)(value & 0xff);
+    *p += 2;
+    return 1;
+}
+
+/* Copy four byte per character UniversalStrings */
+
+static int cpy_univ(unsigned long value, void *arg)
+{
+    unsigned char **p, *q;
+    p = arg;
+    q = *p;
+    *q++ = (unsigned char)((value >> 24) & 0xff);
+    *q++ = (unsigned char)((value >> 16) & 0xff);
+    *q++ = (unsigned char)((value >> 8) & 0xff);
+    *q = (unsigned char)(value & 0xff);
+    *p += 4;
+    return 1;
+}
+
+/* Copy to a UTF8String */
+
+static int cpy_utf8(unsigned long value, void *arg)
+{
+    unsigned char **p;
+    int ret;
+    p = arg;
+    /* We already know there is enough room so pass 0xff as the length */
+    ret = UTF8_putc(*p, 0xff, value);
+    *p += ret;
+    return 1;
+}
+
+/* Return 1 if the character is permitted in a PrintableString */
+static int is_printable(unsigned long value)
+{
+    int ch;
+    if (value > 0x7f)
+        return 0;
+    ch = (int)value;
+    /*
+     * Note: we can't use 'isalnum' because certain accented characters may
+     * count as alphanumeric in some environments.
+     */
+#ifndef CHARSET_EBCDIC
+    if ((ch >= 'a') && (ch <= 'z'))
+        return 1;
+    if ((ch >= 'A') && (ch <= 'Z'))
+        return 1;
+    if ((ch >= '0') && (ch <= '9'))
+        return 1;
+    if ((ch == ' ') || strchr("'()+,-./:=?", ch))
+        return 1;
+#else                           /* CHARSET_EBCDIC */
+    if ((ch >= os_toascii['a']) && (ch <= os_toascii['z']))
+        return 1;
+    if ((ch >= os_toascii['A']) && (ch <= os_toascii['Z']))
+        return 1;
+    if ((ch >= os_toascii['0']) && (ch <= os_toascii['9']))
+        return 1;
+    if ((ch == os_toascii[' ']) || strchr("'()+,-./:=?", os_toebcdic[ch]))
+        return 1;
+#endif                          /* CHARSET_EBCDIC */
+    return 0;
+}
+
+/* Return 1 if the character is a digit or space */
+static int is_numeric(unsigned long value)
+{
+    int ch;
+    if (value > 0x7f)
+        return 0;
+    ch = (int)value;
+#ifndef CHARSET_EBCDIC
+    if (!isdigit(ch) && ch != ' ')
+        return 0;
+#else
+    if (ch > os_toascii['9'])
+        return 0;
+    if (ch < os_toascii['0'] && ch != os_toascii[' '])
+        return 0;
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_object.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_object.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_object.c	(revision 331)
@@ -0,0 +1,370 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <limits.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/bn.h>
+#include "internal/asn1_int.h"
+#include "asn1_locl.h"
+
+int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp)
+{
+    unsigned char *p;
+    int objsize;
+
+    if ((a == NULL) || (a->data == NULL))
+        return (0);
+
+    objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
+    if (pp == NULL || objsize == -1)
+        return objsize;
+
+    p = *pp;
+    ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
+    memcpy(p, a->data, a->length);
+    p += a->length;
+
+    *pp = p;
+    return (objsize);
+}
+
+int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
+{
+    int i, first, len = 0, c, use_bn;
+    char ftmp[24], *tmp = ftmp;
+    int tmpsize = sizeof ftmp;
+    const char *p;
+    unsigned long l;
+    BIGNUM *bl = NULL;
+
+    if (num == 0)
+        return (0);
+    else if (num == -1)
+        num = strlen(buf);
+
+    p = buf;
+    c = *(p++);
+    num--;
+    if ((c >= '0') && (c <= '2')) {
+        first = c - '0';
+    } else {
+        ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE);
+        goto err;
+    }
+
+    if (num <= 0) {
+        ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER);
+        goto err;
+    }
+    c = *(p++);
+    num--;
+    for (;;) {
+        if (num <= 0)
+            break;
+        if ((c != '.') && (c != ' ')) {
+            ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_SEPARATOR);
+            goto err;
+        }
+        l = 0;
+        use_bn = 0;
+        for (;;) {
+            if (num <= 0)
+                break;
+            num--;
+            c = *(p++);
+            if ((c == ' ') || (c == '.'))
+                break;
+            if ((c < '0') || (c > '9')) {
+                ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_DIGIT);
+                goto err;
+            }
+            if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) {
+                use_bn = 1;
+                if (bl == NULL)
+                    bl = BN_new();
+                if (bl == NULL || !BN_set_word(bl, l))
+                    goto err;
+            }
+            if (use_bn) {
+                if (!BN_mul_word(bl, 10L)
+                    || !BN_add_word(bl, c - '0'))
+                    goto err;
+            } else
+                l = l * 10L + (long)(c - '0');
+        }
+        if (len == 0) {
+            if ((first < 2) && (l >= 40)) {
+                ASN1err(ASN1_F_A2D_ASN1_OBJECT,
+                        ASN1_R_SECOND_NUMBER_TOO_LARGE);
+                goto err;
+            }
+            if (use_bn) {
+                if (!BN_add_word(bl, first * 40))
+                    goto err;
+            } else
+                l += (long)first *40;
+        }
+        i = 0;
+        if (use_bn) {
+            int blsize;
+            blsize = BN_num_bits(bl);
+            blsize = (blsize + 6) / 7;
+            if (blsize > tmpsize) {
+                if (tmp != ftmp)
+                    OPENSSL_free(tmp);
+                tmpsize = blsize + 32;
+                tmp = OPENSSL_malloc(tmpsize);
+                if (tmp == NULL)
+                    goto err;
+            }
+            while (blsize--) {
+                BN_ULONG t = BN_div_word(bl, 0x80L);
+                if (t == (BN_ULONG)-1)
+                    goto err;
+                tmp[i++] = (unsigned char)t;
+            }
+        } else {
+
+            for (;;) {
+                tmp[i++] = (unsigned char)l & 0x7f;
+                l >>= 7L;
+                if (l == 0L)
+                    break;
+            }
+
+        }
+        if (out != NULL) {
+            if (len + i > olen) {
+                ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_BUFFER_TOO_SMALL);
+                goto err;
+            }
+            while (--i > 0)
+                out[len++] = tmp[i] | 0x80;
+            out[len++] = tmp[0];
+        } else
+            len += i;
+    }
+    if (tmp != ftmp)
+        OPENSSL_free(tmp);
+    BN_free(bl);
+    return (len);
+ err:
+    if (tmp != ftmp)
+        OPENSSL_free(tmp);
+    BN_free(bl);
+    return (0);
+}
+
+int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a)
+{
+    return OBJ_obj2txt(buf, buf_len, a, 0);
+}
+
+int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a)
+{
+    char buf[80], *p = buf;
+    int i;
+
+    if ((a == NULL) || (a->data == NULL))
+        return (BIO_write(bp, "NULL", 4));
+    i = i2t_ASN1_OBJECT(buf, sizeof buf, a);
+    if (i > (int)(sizeof(buf) - 1)) {
+        p = OPENSSL_malloc(i + 1);
+        if (p == NULL)
+            return -1;
+        i2t_ASN1_OBJECT(p, i + 1, a);
+    }
+    if (i <= 0) {
+        i = BIO_write(bp, "<INVALID>", 9);
+        i += BIO_dump(bp, (const char *)a->data, a->length);
+        return i;
+    }
+    BIO_write(bp, p, i);
+    if (p != buf)
+        OPENSSL_free(p);
+    return (i);
+}
+
+ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
+                             long length)
+{
+    const unsigned char *p;
+    long len;
+    int tag, xclass;
+    int inf, i;
+    ASN1_OBJECT *ret = NULL;
+    p = *pp;
+    inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
+    if (inf & 0x80) {
+        i = ASN1_R_BAD_OBJECT_HEADER;
+        goto err;
+    }
+
+    if (tag != V_ASN1_OBJECT) {
+        i = ASN1_R_EXPECTING_AN_OBJECT;
+        goto err;
+    }
+    ret = c2i_ASN1_OBJECT(a, &p, len);
+    if (ret)
+        *pp = p;
+    return ret;
+ err:
+    ASN1err(ASN1_F_D2I_ASN1_OBJECT, i);
+    return (NULL);
+}
+
+ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
+                             long len)
+{
+    ASN1_OBJECT *ret = NULL, tobj;
+    const unsigned char *p;
+    unsigned char *data;
+    int i, length;
+
+    /*
+     * Sanity check OID encoding. Need at least one content octet. MSB must
+     * be clear in the last octet. can't have leading 0x80 in subidentifiers,
+     * see: X.690 8.19.2
+     */
+    if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
+        p[len - 1] & 0x80) {
+        ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
+        return NULL;
+    }
+    /* Now 0 < len <= INT_MAX, so the cast is safe. */
+    length = (int)len;
+    /*
+     * Try to lookup OID in table: these are all valid encodings so if we get
+     * a match we know the OID is valid.
+     */
+    tobj.nid = NID_undef;
+    tobj.data = p;
+    tobj.length = length;
+    tobj.flags = 0;
+    i = OBJ_obj2nid(&tobj);
+    if (i != NID_undef) {
+        /*
+         * Return shared registered OID object: this improves efficiency
+         * because we don't have to return a dynamically allocated OID
+         * and NID lookups can use the cached value.
+         */
+        ret = OBJ_nid2obj(i);
+        if (a) {
+            ASN1_OBJECT_free(*a);
+            *a = ret;
+        }
+        *pp += len;
+        return ret;
+    }
+    for (i = 0; i < length; i++, p++) {
+        if (*p == 0x80 && (!i || !(p[-1] & 0x80))) {
+            ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
+            return NULL;
+        }
+    }
+
+    /*
+     * only the ASN1_OBJECTs from the 'table' will have values for ->sn or
+     * ->ln
+     */
+    if ((a == NULL) || ((*a) == NULL) ||
+        !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
+        if ((ret = ASN1_OBJECT_new()) == NULL)
+            return (NULL);
+    } else
+        ret = (*a);
+
+    p = *pp;
+    /* detach data from object */
+    data = (unsigned char *)ret->data;
+    ret->data = NULL;
+    /* once detached we can change it */
+    if ((data == NULL) || (ret->length < length)) {
+        ret->length = 0;
+        OPENSSL_free(data);
+        data = OPENSSL_malloc(length);
+        if (data == NULL) {
+            i = ERR_R_MALLOC_FAILURE;
+            goto err;
+        }
+        ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+    }
+    memcpy(data, p, length);
+    /* reattach data to object, after which it remains const */
+    ret->data = data;
+    ret->length = length;
+    ret->sn = NULL;
+    ret->ln = NULL;
+    /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
+    p += length;
+
+    if (a != NULL)
+        (*a) = ret;
+    *pp = p;
+    return (ret);
+ err:
+    ASN1err(ASN1_F_C2I_ASN1_OBJECT, i);
+    if ((a == NULL) || (*a != ret))
+        ASN1_OBJECT_free(ret);
+    return (NULL);
+}
+
+ASN1_OBJECT *ASN1_OBJECT_new(void)
+{
+    ASN1_OBJECT *ret;
+
+    ret = OPENSSL_zalloc(sizeof(*ret));
+    if (ret == NULL) {
+        ASN1err(ASN1_F_ASN1_OBJECT_NEW, ERR_R_MALLOC_FAILURE);
+        return (NULL);
+    }
+    ret->flags = ASN1_OBJECT_FLAG_DYNAMIC;
+    return (ret);
+}
+
+void ASN1_OBJECT_free(ASN1_OBJECT *a)
+{
+    if (a == NULL)
+        return;
+    if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) {
+#ifndef CONST_STRICT            /* disable purely for compile-time strict
+                                 * const checking. Doing this on a "real"
+                                 * compile will cause memory leaks */
+        OPENSSL_free((void*)a->sn);
+        OPENSSL_free((void*)a->ln);
+#endif
+        a->sn = a->ln = NULL;
+    }
+    if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) {
+        OPENSSL_free((void*)a->data);
+        a->data = NULL;
+        a->length = 0;
+    }
+    if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
+        OPENSSL_free(a);
+}
+
+ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
+                                const char *sn, const char *ln)
+{
+    ASN1_OBJECT o;
+
+    o.sn = sn;
+    o.ln = ln;
+    o.data = data;
+    o.nid = nid;
+    o.length = len;
+    o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
+        ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+    return (OBJ_dup(&o));
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_octet.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_octet.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_octet.c	(revision 331)
@@ -0,0 +1,29 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+
+ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x)
+{
+    return ASN1_STRING_dup(x);
+}
+
+int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a,
+                          const ASN1_OCTET_STRING *b)
+{
+    return ASN1_STRING_cmp(a, b);
+}
+
+int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d,
+                          int len)
+{
+    return ASN1_STRING_set(x, d, len);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_print.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_print.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_print.c	(revision 331)
@@ -0,0 +1,109 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <ctype.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+
+int ASN1_PRINTABLE_type(const unsigned char *s, int len)
+{
+    int c;
+    int ia5 = 0;
+    int t61 = 0;
+
+    if (len <= 0)
+        len = -1;
+    if (s == NULL)
+        return (V_ASN1_PRINTABLESTRING);
+
+    while ((*s) && (len-- != 0)) {
+        c = *(s++);
+#ifndef CHARSET_EBCDIC
+        if (!(((c >= 'a') && (c <= 'z')) ||
+              ((c >= 'A') && (c <= 'Z')) ||
+              ((c >= '0') && (c <= '9')) ||
+              (c == ' ') || (c == '\'') ||
+              (c == '(') || (c == ')') ||
+              (c == '+') || (c == ',') ||
+              (c == '-') || (c == '.') ||
+              (c == '/') || (c == ':') || (c == '=') || (c == '?')))
+            ia5 = 1;
+        if (c & 0x80)
+            t61 = 1;
+#else
+        if (!isalnum(c) && (c != ' ') && strchr("'()+,-./:=?", c) == NULL)
+            ia5 = 1;
+        if (os_toascii[c] & 0x80)
+            t61 = 1;
+#endif
+    }
+    if (t61)
+        return (V_ASN1_T61STRING);
+    if (ia5)
+        return (V_ASN1_IA5STRING);
+    return (V_ASN1_PRINTABLESTRING);
+}
+
+int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s)
+{
+    int i;
+    unsigned char *p;
+
+    if (s->type != V_ASN1_UNIVERSALSTRING)
+        return (0);
+    if ((s->length % 4) != 0)
+        return (0);
+    p = s->data;
+    for (i = 0; i < s->length; i += 4) {
+        if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0'))
+            break;
+        else
+            p += 4;
+    }
+    if (i < s->length)
+        return (0);
+    p = s->data;
+    for (i = 3; i < s->length; i += 4) {
+        *(p++) = s->data[i];
+    }
+    *(p) = '\0';
+    s->length /= 4;
+    s->type = ASN1_PRINTABLE_type(s->data, s->length);
+    return (1);
+}
+
+int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v)
+{
+    int i, n;
+    char buf[80];
+    const char *p;
+
+    if (v == NULL)
+        return (0);
+    n = 0;
+    p = (const char *)v->data;
+    for (i = 0; i < v->length; i++) {
+        if ((p[i] > '~') || ((p[i] < ' ') &&
+                             (p[i] != '\n') && (p[i] != '\r')))
+            buf[n] = '.';
+        else
+            buf[n] = p[i];
+        n++;
+        if (n >= 80) {
+            if (BIO_write(bp, buf, n) <= 0)
+                return (0);
+            n = 0;
+        }
+    }
+    if (n > 0)
+        if (BIO_write(bp, buf, n) <= 0)
+            return (0);
+    return (1);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_sign.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_sign.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_sign.c	(revision 331)
@@ -0,0 +1,228 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <time.h>
+
+#include "internal/cryptlib.h"
+
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
+
+#ifndef NO_ASN1_OLD
+
+int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
+              ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey,
+              const EVP_MD *type)
+{
+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+    unsigned char *p, *buf_in = NULL, *buf_out = NULL;
+    int i, inl = 0, outl = 0, outll = 0;
+    X509_ALGOR *a;
+
+    if (ctx == NULL) {
+        ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    for (i = 0; i < 2; i++) {
+        if (i == 0)
+            a = algor1;
+        else
+            a = algor2;
+        if (a == NULL)
+            continue;
+        if (type->pkey_type == NID_dsaWithSHA1) {
+            /*
+             * special case: RFC 2459 tells us to omit 'parameters' with
+             * id-dsa-with-sha1
+             */
+            ASN1_TYPE_free(a->parameter);
+            a->parameter = NULL;
+        } else if ((a->parameter == NULL) ||
+                   (a->parameter->type != V_ASN1_NULL)) {
+            ASN1_TYPE_free(a->parameter);
+            if ((a->parameter = ASN1_TYPE_new()) == NULL)
+                goto err;
+            a->parameter->type = V_ASN1_NULL;
+        }
+        ASN1_OBJECT_free(a->algorithm);
+        a->algorithm = OBJ_nid2obj(type->pkey_type);
+        if (a->algorithm == NULL) {
+            ASN1err(ASN1_F_ASN1_SIGN, ASN1_R_UNKNOWN_OBJECT_TYPE);
+            goto err;
+        }
+        if (a->algorithm->length == 0) {
+            ASN1err(ASN1_F_ASN1_SIGN,
+                    ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
+            goto err;
+        }
+    }
+    inl = i2d(data, NULL);
+    buf_in = OPENSSL_malloc((unsigned int)inl);
+    outll = outl = EVP_PKEY_size(pkey);
+    buf_out = OPENSSL_malloc((unsigned int)outl);
+    if ((buf_in == NULL) || (buf_out == NULL)) {
+        outl = 0;
+        ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    p = buf_in;
+
+    i2d(data, &p);
+    if (!EVP_SignInit_ex(ctx, type, NULL)
+        || !EVP_SignUpdate(ctx, (unsigned char *)buf_in, inl)
+        || !EVP_SignFinal(ctx, (unsigned char *)buf_out,
+                          (unsigned int *)&outl, pkey)) {
+        outl = 0;
+        ASN1err(ASN1_F_ASN1_SIGN, ERR_R_EVP_LIB);
+        goto err;
+    }
+    OPENSSL_free(signature->data);
+    signature->data = buf_out;
+    buf_out = NULL;
+    signature->length = outl;
+    /*
+     * In the interests of compatibility, I'll make sure that the bit string
+     * has a 'not-used bits' value of 0
+     */
+    signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+    signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ err:
+    EVP_MD_CTX_free(ctx);
+    OPENSSL_clear_free((char *)buf_in, (unsigned int)inl);
+    OPENSSL_clear_free((char *)buf_out, outll);
+    return (outl);
+}
+
+#endif
+
+int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
+                   X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn,
+                   EVP_PKEY *pkey, const EVP_MD *type)
+{
+    int rv;
+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+
+    if (ctx == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_SIGN, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    if (!EVP_DigestSignInit(ctx, NULL, type, NULL, pkey)) {
+        EVP_MD_CTX_free(ctx);
+        return 0;
+    }
+
+    rv = ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, ctx);
+
+    EVP_MD_CTX_free(ctx);
+    return rv;
+}
+
+int ASN1_item_sign_ctx(const ASN1_ITEM *it,
+                       X509_ALGOR *algor1, X509_ALGOR *algor2,
+                       ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx)
+{
+    const EVP_MD *type;
+    EVP_PKEY *pkey;
+    unsigned char *buf_in = NULL, *buf_out = NULL;
+    size_t inl = 0, outl = 0, outll = 0;
+    int signid, paramtype;
+    int rv;
+
+    type = EVP_MD_CTX_md(ctx);
+    pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx));
+
+    if (type == NULL || pkey == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED);
+        goto err;
+    }
+
+    if (pkey->ameth == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
+        goto err;
+    }
+
+    if (pkey->ameth->item_sign) {
+        rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, signature);
+        if (rv == 1)
+            outl = signature->length;
+        /*-
+         * Return value meanings:
+         * <=0: error.
+         *   1: method does everything.
+         *   2: carry on as normal.
+         *   3: ASN1 method sets algorithm identifiers: just sign.
+         */
+        if (rv <= 0)
+            ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
+        if (rv <= 1)
+            goto err;
+    } else
+        rv = 2;
+
+    if (rv == 2) {
+        if (!OBJ_find_sigid_by_algs(&signid,
+                                    EVP_MD_nid(type),
+                                    pkey->ameth->pkey_id)) {
+            ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
+                    ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
+            goto err;
+        }
+
+        if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
+            paramtype = V_ASN1_NULL;
+        else
+            paramtype = V_ASN1_UNDEF;
+
+        if (algor1)
+            X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL);
+        if (algor2)
+            X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);
+
+    }
+
+    inl = ASN1_item_i2d(asn, &buf_in, it);
+    outll = outl = EVP_PKEY_size(pkey);
+    buf_out = OPENSSL_malloc((unsigned int)outl);
+    if ((buf_in == NULL) || (buf_out == NULL)) {
+        outl = 0;
+        ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (!EVP_DigestSignUpdate(ctx, buf_in, inl)
+        || !EVP_DigestSignFinal(ctx, buf_out, &outl)) {
+        outl = 0;
+        ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
+        goto err;
+    }
+    OPENSSL_free(signature->data);
+    signature->data = buf_out;
+    buf_out = NULL;
+    signature->length = outl;
+    /*
+     * In the interests of compatibility, I'll make sure that the bit string
+     * has a 'not-used bits' value of 0
+     */
+    signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+    signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+ err:
+    OPENSSL_clear_free((char *)buf_in, (unsigned int)inl);
+    OPENSSL_clear_free((char *)buf_out, outll);
+    return (outl);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_strex.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_strex.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_strex.c	(revision 331)
@@ -0,0 +1,645 @@
+/*
+ * Copyright 2000-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 <stdio.h>
+#include <string.h>
+#include "internal/cryptlib.h"
+#include "internal/asn1_int.h"
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+
+#include "charmap.h"
+
+/*
+ * ASN1_STRING_print_ex() and X509_NAME_print_ex(). Enhanced string and name
+ * printing routines handling multibyte characters, RFC2253 and a host of
+ * other options.
+ */
+
+#define CHARTYPE_BS_ESC         (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253)
+
+#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \
+                  ASN1_STRFLGS_ESC_2254 | \
+                  ASN1_STRFLGS_ESC_QUOTE | \
+                  ASN1_STRFLGS_ESC_CTRL | \
+                  ASN1_STRFLGS_ESC_MSB)
+
+/*
+ * Three IO functions for sending data to memory, a BIO and and a FILE
+ * pointer.
+ */
+static int send_bio_chars(void *arg, const void *buf, int len)
+{
+    if (!arg)
+        return 1;
+    if (BIO_write(arg, buf, len) != len)
+        return 0;
+    return 1;
+}
+
+#ifndef OPENSSL_NO_STDIO
+static int send_fp_chars(void *arg, const void *buf, int len)
+{
+    if (!arg)
+        return 1;
+    if (fwrite(buf, 1, len, arg) != (unsigned int)len)
+        return 0;
+    return 1;
+}
+#endif
+
+typedef int char_io (void *arg, const void *buf, int len);
+
+/*
+ * This function handles display of strings, one character at a time. It is
+ * passed an unsigned long for each character because it could come from 2 or
+ * even 4 byte forms.
+ */
+
+static int do_esc_char(unsigned long c, unsigned char flags, char *do_quotes,
+                       char_io *io_ch, void *arg)
+{
+    unsigned short chflgs;
+    unsigned char chtmp;
+    char tmphex[HEX_SIZE(long) + 3];
+
+    if (c > 0xffffffffL)
+        return -1;
+    if (c > 0xffff) {
+        BIO_snprintf(tmphex, sizeof tmphex, "\\W%08lX", c);
+        if (!io_ch(arg, tmphex, 10))
+            return -1;
+        return 10;
+    }
+    if (c > 0xff) {
+        BIO_snprintf(tmphex, sizeof tmphex, "\\U%04lX", c);
+        if (!io_ch(arg, tmphex, 6))
+            return -1;
+        return 6;
+    }
+    chtmp = (unsigned char)c;
+    if (chtmp > 0x7f)
+        chflgs = flags & ASN1_STRFLGS_ESC_MSB;
+    else
+        chflgs = char_type[chtmp] & flags;
+    if (chflgs & CHARTYPE_BS_ESC) {
+        /* If we don't escape with quotes, signal we need quotes */
+        if (chflgs & ASN1_STRFLGS_ESC_QUOTE) {
+            if (do_quotes)
+                *do_quotes = 1;
+            if (!io_ch(arg, &chtmp, 1))
+                return -1;
+            return 1;
+        }
+        if (!io_ch(arg, "\\", 1))
+            return -1;
+        if (!io_ch(arg, &chtmp, 1))
+            return -1;
+        return 2;
+    }
+    if (chflgs & (ASN1_STRFLGS_ESC_CTRL
+                  | ASN1_STRFLGS_ESC_MSB
+                  | ASN1_STRFLGS_ESC_2254)) {
+        BIO_snprintf(tmphex, 11, "\\%02X", chtmp);
+        if (!io_ch(arg, tmphex, 3))
+            return -1;
+        return 3;
+    }
+    /*
+     * If we get this far and do any escaping at all must escape the escape
+     * character itself: backslash.
+     */
+    if (chtmp == '\\' && flags & ESC_FLAGS) {
+        if (!io_ch(arg, "\\\\", 2))
+            return -1;
+        return 2;
+    }
+    if (!io_ch(arg, &chtmp, 1))
+        return -1;
+    return 1;
+}
+
+#define BUF_TYPE_WIDTH_MASK     0x7
+#define BUF_TYPE_CONVUTF8       0x8
+
+/*
+ * This function sends each character in a buffer to do_esc_char(). It
+ * interprets the content formats and converts to or from UTF8 as
+ * appropriate.
+ */
+
+static int do_buf(unsigned char *buf, int buflen,
+                  int type, unsigned short flags, char *quotes, char_io *io_ch,
+                  void *arg)
+{
+    int i, outlen, len;
+    unsigned short orflags;
+    unsigned char *p, *q;
+    unsigned long c;
+    p = buf;
+    q = buf + buflen;
+    outlen = 0;
+    while (p != q) {
+        if (p == buf && flags & ASN1_STRFLGS_ESC_2253)
+            orflags = CHARTYPE_FIRST_ESC_2253;
+        else
+            orflags = 0;
+        switch (type & BUF_TYPE_WIDTH_MASK) {
+        case 4:
+            c = ((unsigned long)*p++) << 24;
+            c |= ((unsigned long)*p++) << 16;
+            c |= ((unsigned long)*p++) << 8;
+            c |= *p++;
+            break;
+
+        case 2:
+            c = ((unsigned long)*p++) << 8;
+            c |= *p++;
+            break;
+
+        case 1:
+            c = *p++;
+            break;
+
+        case 0:
+            i = UTF8_getc(p, buflen, &c);
+            if (i < 0)
+                return -1;      /* Invalid UTF8String */
+            p += i;
+            break;
+        default:
+            return -1;          /* invalid width */
+        }
+        if (p == q && flags & ASN1_STRFLGS_ESC_2253)
+            orflags = CHARTYPE_LAST_ESC_2253;
+        if (type & BUF_TYPE_CONVUTF8) {
+            unsigned char utfbuf[6];
+            int utflen;
+            utflen = UTF8_putc(utfbuf, sizeof utfbuf, c);
+            for (i = 0; i < utflen; i++) {
+                /*
+                 * We don't need to worry about setting orflags correctly
+                 * because if utflen==1 its value will be correct anyway
+                 * otherwise each character will be > 0x7f and so the
+                 * character will never be escaped on first and last.
+                 */
+                len =
+                    do_esc_char(utfbuf[i], (unsigned short)(flags | orflags),
+                                quotes, io_ch, arg);
+                if (len < 0)
+                    return -1;
+                outlen += len;
+            }
+        } else {
+            len =
+                do_esc_char(c, (unsigned short)(flags | orflags), quotes,
+                            io_ch, arg);
+            if (len < 0)
+                return -1;
+            outlen += len;
+        }
+    }
+    return outlen;
+}
+
+/* This function hex dumps a buffer of characters */
+
+static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf,
+                       int buflen)
+{
+    static const char hexdig[] = "0123456789ABCDEF";
+    unsigned char *p, *q;
+    char hextmp[2];
+    if (arg) {
+        p = buf;
+        q = buf + buflen;
+        while (p != q) {
+            hextmp[0] = hexdig[*p >> 4];
+            hextmp[1] = hexdig[*p & 0xf];
+            if (!io_ch(arg, hextmp, 2))
+                return -1;
+            p++;
+        }
+    }
+    return buflen << 1;
+}
+
+/*
+ * "dump" a string. This is done when the type is unknown, or the flags
+ * request it. We can either dump the content octets or the entire DER
+ * encoding. This uses the RFC2253 #01234 format.
+ */
+
+static int do_dump(unsigned long lflags, char_io *io_ch, void *arg,
+                   const ASN1_STRING *str)
+{
+    /*
+     * Placing the ASN1_STRING in a temp ASN1_TYPE allows the DER encoding to
+     * readily obtained
+     */
+    ASN1_TYPE t;
+    unsigned char *der_buf, *p;
+    int outlen, der_len;
+
+    if (!io_ch(arg, "#", 1))
+        return -1;
+    /* If we don't dump DER encoding just dump content octets */
+    if (!(lflags & ASN1_STRFLGS_DUMP_DER)) {
+        outlen = do_hex_dump(io_ch, arg, str->data, str->length);
+        if (outlen < 0)
+            return -1;
+        return outlen + 1;
+    }
+    t.type = str->type;
+    t.value.ptr = (char *)str;
+    der_len = i2d_ASN1_TYPE(&t, NULL);
+    der_buf = OPENSSL_malloc(der_len);
+    if (der_buf == NULL)
+        return -1;
+    p = der_buf;
+    i2d_ASN1_TYPE(&t, &p);
+    outlen = do_hex_dump(io_ch, arg, der_buf, der_len);
+    OPENSSL_free(der_buf);
+    if (outlen < 0)
+        return -1;
+    return outlen + 1;
+}
+
+/*
+ * Lookup table to convert tags to character widths, 0 = UTF8 encoded, -1 is
+ * used for non string types otherwise it is the number of bytes per
+ * character
+ */
+
+static const signed char tag2nbyte[] = {
+    -1, -1, -1, -1, -1,         /* 0-4 */
+    -1, -1, -1, -1, -1,         /* 5-9 */
+    -1, -1, 0, -1,              /* 10-13 */
+    -1, -1, -1, -1,             /* 15-17 */
+    1, 1, 1,                    /* 18-20 */
+    -1, 1, 1, 1,                /* 21-24 */
+    -1, 1, -1,                  /* 25-27 */
+    4, -1, 2                    /* 28-30 */
+};
+
+/*
+ * This is the main function, print out an ASN1_STRING taking note of various
+ * escape and display options. Returns number of characters written or -1 if
+ * an error occurred.
+ */
+
+static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags,
+                       const ASN1_STRING *str)
+{
+    int outlen, len;
+    int type;
+    char quotes;
+    unsigned short flags;
+    quotes = 0;
+    /* Keep a copy of escape flags */
+    flags = (unsigned short)(lflags & ESC_FLAGS);
+
+    type = str->type;
+
+    outlen = 0;
+
+    if (lflags & ASN1_STRFLGS_SHOW_TYPE) {
+        const char *tagname;
+        tagname = ASN1_tag2str(type);
+        outlen += strlen(tagname);
+        if (!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1))
+            return -1;
+        outlen++;
+    }
+
+    /* Decide what to do with type, either dump content or display it */
+
+    /* Dump everything */
+    if (lflags & ASN1_STRFLGS_DUMP_ALL)
+        type = -1;
+    /* Ignore the string type */
+    else if (lflags & ASN1_STRFLGS_IGNORE_TYPE)
+        type = 1;
+    else {
+        /* Else determine width based on type */
+        if ((type > 0) && (type < 31))
+            type = tag2nbyte[type];
+        else
+            type = -1;
+        if ((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN))
+            type = 1;
+    }
+
+    if (type == -1) {
+        len = do_dump(lflags, io_ch, arg, str);
+        if (len < 0)
+            return -1;
+        outlen += len;
+        return outlen;
+    }
+
+    if (lflags & ASN1_STRFLGS_UTF8_CONVERT) {
+        /*
+         * Note: if string is UTF8 and we want to convert to UTF8 then we
+         * just interpret it as 1 byte per character to avoid converting
+         * twice.
+         */
+        if (!type)
+            type = 1;
+        else
+            type |= BUF_TYPE_CONVUTF8;
+    }
+
+    len = do_buf(str->data, str->length, type, flags, &quotes, io_ch, NULL);
+    if (len < 0)
+        return -1;
+    outlen += len;
+    if (quotes)
+        outlen += 2;
+    if (!arg)
+        return outlen;
+    if (quotes && !io_ch(arg, "\"", 1))
+        return -1;
+    if (do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0)
+        return -1;
+    if (quotes && !io_ch(arg, "\"", 1))
+        return -1;
+    return outlen;
+}
+
+/* Used for line indenting: print 'indent' spaces */
+
+static int do_indent(char_io *io_ch, void *arg, int indent)
+{
+    int i;
+    for (i = 0; i < indent; i++)
+        if (!io_ch(arg, " ", 1))
+            return 0;
+    return 1;
+}
+
+#define FN_WIDTH_LN     25
+#define FN_WIDTH_SN     10
+
+static int do_name_ex(char_io *io_ch, void *arg, const X509_NAME *n,
+                      int indent, unsigned long flags)
+{
+    int i, prev = -1, orflags, cnt;
+    int fn_opt, fn_nid;
+    ASN1_OBJECT *fn;
+    const ASN1_STRING *val;
+    const X509_NAME_ENTRY *ent;
+    char objtmp[80];
+    const char *objbuf;
+    int outlen, len;
+    char *sep_dn, *sep_mv, *sep_eq;
+    int sep_dn_len, sep_mv_len, sep_eq_len;
+    if (indent < 0)
+        indent = 0;
+    outlen = indent;
+    if (!do_indent(io_ch, arg, indent))
+        return -1;
+    switch (flags & XN_FLAG_SEP_MASK) {
+    case XN_FLAG_SEP_MULTILINE:
+        sep_dn = "\n";
+        sep_dn_len = 1;
+        sep_mv = " + ";
+        sep_mv_len = 3;
+        break;
+
+    case XN_FLAG_SEP_COMMA_PLUS:
+        sep_dn = ",";
+        sep_dn_len = 1;
+        sep_mv = "+";
+        sep_mv_len = 1;
+        indent = 0;
+        break;
+
+    case XN_FLAG_SEP_CPLUS_SPC:
+        sep_dn = ", ";
+        sep_dn_len = 2;
+        sep_mv = " + ";
+        sep_mv_len = 3;
+        indent = 0;
+        break;
+
+    case XN_FLAG_SEP_SPLUS_SPC:
+        sep_dn = "; ";
+        sep_dn_len = 2;
+        sep_mv = " + ";
+        sep_mv_len = 3;
+        indent = 0;
+        break;
+
+    default:
+        return -1;
+    }
+
+    if (flags & XN_FLAG_SPC_EQ) {
+        sep_eq = " = ";
+        sep_eq_len = 3;
+    } else {
+        sep_eq = "=";
+        sep_eq_len = 1;
+    }
+
+    fn_opt = flags & XN_FLAG_FN_MASK;
+
+    cnt = X509_NAME_entry_count(n);
+    for (i = 0; i < cnt; i++) {
+        if (flags & XN_FLAG_DN_REV)
+            ent = X509_NAME_get_entry(n, cnt - i - 1);
+        else
+            ent = X509_NAME_get_entry(n, i);
+        if (prev != -1) {
+            if (prev == X509_NAME_ENTRY_set(ent)) {
+                if (!io_ch(arg, sep_mv, sep_mv_len))
+                    return -1;
+                outlen += sep_mv_len;
+            } else {
+                if (!io_ch(arg, sep_dn, sep_dn_len))
+                    return -1;
+                outlen += sep_dn_len;
+                if (!do_indent(io_ch, arg, indent))
+                    return -1;
+                outlen += indent;
+            }
+        }
+        prev = X509_NAME_ENTRY_set(ent);
+        fn = X509_NAME_ENTRY_get_object(ent);
+        val = X509_NAME_ENTRY_get_data(ent);
+        fn_nid = OBJ_obj2nid(fn);
+        if (fn_opt != XN_FLAG_FN_NONE) {
+            int objlen, fld_len;
+            if ((fn_opt == XN_FLAG_FN_OID) || (fn_nid == NID_undef)) {
+                OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1);
+                fld_len = 0;    /* XXX: what should this be? */
+                objbuf = objtmp;
+            } else {
+                if (fn_opt == XN_FLAG_FN_SN) {
+                    fld_len = FN_WIDTH_SN;
+                    objbuf = OBJ_nid2sn(fn_nid);
+                } else if (fn_opt == XN_FLAG_FN_LN) {
+                    fld_len = FN_WIDTH_LN;
+                    objbuf = OBJ_nid2ln(fn_nid);
+                } else {
+                    fld_len = 0; /* XXX: what should this be? */
+                    objbuf = "";
+                }
+            }
+            objlen = strlen(objbuf);
+            if (!io_ch(arg, objbuf, objlen))
+                return -1;
+            if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) {
+                if (!do_indent(io_ch, arg, fld_len - objlen))
+                    return -1;
+                outlen += fld_len - objlen;
+            }
+            if (!io_ch(arg, sep_eq, sep_eq_len))
+                return -1;
+            outlen += objlen + sep_eq_len;
+        }
+        /*
+         * If the field name is unknown then fix up the DER dump flag. We
+         * might want to limit this further so it will DER dump on anything
+         * other than a few 'standard' fields.
+         */
+        if ((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS))
+            orflags = ASN1_STRFLGS_DUMP_ALL;
+        else
+            orflags = 0;
+
+        len = do_print_ex(io_ch, arg, flags | orflags, val);
+        if (len < 0)
+            return -1;
+        outlen += len;
+    }
+    return outlen;
+}
+
+/* Wrappers round the main functions */
+
+int X509_NAME_print_ex(BIO *out, const X509_NAME *nm, int indent,
+                       unsigned long flags)
+{
+    if (flags == XN_FLAG_COMPAT)
+        return X509_NAME_print(out, nm, indent);
+    return do_name_ex(send_bio_chars, out, nm, indent, flags);
+}
+
+#ifndef OPENSSL_NO_STDIO
+int X509_NAME_print_ex_fp(FILE *fp, const X509_NAME *nm, int indent,
+                          unsigned long flags)
+{
+    if (flags == XN_FLAG_COMPAT) {
+        BIO *btmp;
+        int ret;
+        btmp = BIO_new_fp(fp, BIO_NOCLOSE);
+        if (!btmp)
+            return -1;
+        ret = X509_NAME_print(btmp, nm, indent);
+        BIO_free(btmp);
+        return ret;
+    }
+    return do_name_ex(send_fp_chars, fp, nm, indent, flags);
+}
+#endif
+
+int ASN1_STRING_print_ex(BIO *out, const ASN1_STRING *str, unsigned long flags)
+{
+    return do_print_ex(send_bio_chars, out, flags, str);
+}
+
+#ifndef OPENSSL_NO_STDIO
+int ASN1_STRING_print_ex_fp(FILE *fp, const ASN1_STRING *str, unsigned long flags)
+{
+    return do_print_ex(send_fp_chars, fp, flags, str);
+}
+#endif
+
+/*
+ * Utility function: convert any string type to UTF8, returns number of bytes
+ * in output string or a negative error code
+ */
+
+int ASN1_STRING_to_UTF8(unsigned char **out, const ASN1_STRING *in)
+{
+    ASN1_STRING stmp, *str = &stmp;
+    int mbflag, type, ret;
+    if (!in)
+        return -1;
+    type = in->type;
+    if ((type < 0) || (type > 30))
+        return -1;
+    mbflag = tag2nbyte[type];
+    if (mbflag == -1)
+        return -1;
+    mbflag |= MBSTRING_FLAG;
+    stmp.data = NULL;
+    stmp.length = 0;
+    stmp.flags = 0;
+    ret =
+        ASN1_mbstring_copy(&str, in->data, in->length, mbflag,
+                           B_ASN1_UTF8STRING);
+    if (ret < 0)
+        return ret;
+    *out = stmp.data;
+    return stmp.length;
+}
+
+/* Return 1 if host is a valid hostname and 0 otherwise */
+int asn1_valid_host(const ASN1_STRING *host)
+{
+    int hostlen = host->length;
+    const unsigned char *hostptr = host->data;
+    int type = host->type;
+    int i;
+    char width = -1;
+    unsigned short chflags = 0, prevchflags;
+
+    if (type > 0 && type < 31)
+        width = tag2nbyte[type];
+    if (width == -1 || hostlen == 0)
+        return 0;
+    /* Treat UTF8String as width 1 as any MSB set is invalid */
+    if (width == 0)
+        width = 1;
+    for (i = 0 ; i < hostlen; i+= width) {
+        prevchflags = chflags;
+        /* Value must be <= 0x7F: check upper bytes are all zeroes */
+        if (width == 4) {
+            if (*hostptr++ != 0 || *hostptr++ != 0 || *hostptr++ != 0)
+                return 0;
+        } else if (width == 2) {
+            if (*hostptr++ != 0)
+                return 0;
+        }
+        if (*hostptr > 0x7f)
+            return 0;
+        chflags = char_type[*hostptr++];
+        if (!(chflags & (CHARTYPE_HOST_ANY | CHARTYPE_HOST_WILD))) {
+            /* Nothing else allowed at start or end of string */
+            if (i == 0 || i == hostlen - 1)
+                return 0;
+            /* Otherwise invalid if not dot or hyphen */
+            if (!(chflags & (CHARTYPE_HOST_DOT | CHARTYPE_HOST_HYPHEN)))
+                return 0;
+            /*
+             * If previous is dot or hyphen then illegal unless both
+             * are hyphens: as .- -. .. are all illegal
+             */
+            if (prevchflags & (CHARTYPE_HOST_DOT | CHARTYPE_HOST_HYPHEN)
+                && ((prevchflags & CHARTYPE_HOST_DOT)
+                    || (chflags & CHARTYPE_HOST_DOT)))
+                return 0;
+        }
+    }
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_strnid.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_strnid.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_strnid.c	(revision 331)
@@ -0,0 +1,287 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include <ctype.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+
+static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
+static void st_free(ASN1_STRING_TABLE *tbl);
+static int sk_table_cmp(const ASN1_STRING_TABLE *const *a,
+                        const ASN1_STRING_TABLE *const *b);
+
+/*
+ * This is the global mask for the mbstring functions: this is use to mask
+ * out certain types (such as BMPString and UTF8String) because certain
+ * software (e.g. Netscape) has problems with them.
+ */
+
+static unsigned long global_mask = B_ASN1_UTF8STRING;
+
+void ASN1_STRING_set_default_mask(unsigned long mask)
+{
+    global_mask = mask;
+}
+
+unsigned long ASN1_STRING_get_default_mask(void)
+{
+    return global_mask;
+}
+
+/*-
+ * This function sets the default to various "flavours" of configuration.
+ * based on an ASCII string. Currently this is:
+ * MASK:XXXX : a numerical mask value.
+ * nobmp : Don't use BMPStrings (just Printable, T61).
+ * pkix : PKIX recommendation in RFC2459.
+ * utf8only : only use UTF8Strings (RFC2459 recommendation for 2004).
+ * default:   the default value, Printable, T61, BMP.
+ */
+
+int ASN1_STRING_set_default_mask_asc(const char *p)
+{
+    unsigned long mask;
+    char *end;
+    if (strncmp(p, "MASK:", 5) == 0) {
+        if (!p[5])
+            return 0;
+        mask = strtoul(p + 5, &end, 0);
+        if (*end)
+            return 0;
+    } else if (strcmp(p, "nombstr") == 0)
+        mask = ~((unsigned long)(B_ASN1_BMPSTRING | B_ASN1_UTF8STRING));
+    else if (strcmp(p, "pkix") == 0)
+        mask = ~((unsigned long)B_ASN1_T61STRING);
+    else if (strcmp(p, "utf8only") == 0)
+        mask = B_ASN1_UTF8STRING;
+    else if (strcmp(p, "default") == 0)
+        mask = 0xFFFFFFFFL;
+    else
+        return 0;
+    ASN1_STRING_set_default_mask(mask);
+    return 1;
+}
+
+/*
+ * The following function generates an ASN1_STRING based on limits in a
+ * table. Frequently the types and length of an ASN1_STRING are restricted by
+ * a corresponding OID. For example certificates and certificate requests.
+ */
+
+ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out,
+                                    const unsigned char *in, int inlen,
+                                    int inform, int nid)
+{
+    ASN1_STRING_TABLE *tbl;
+    ASN1_STRING *str = NULL;
+    unsigned long mask;
+    int ret;
+    if (!out)
+        out = &str;
+    tbl = ASN1_STRING_TABLE_get(nid);
+    if (tbl) {
+        mask = tbl->mask;
+        if (!(tbl->flags & STABLE_NO_MASK))
+            mask &= global_mask;
+        ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
+                                  tbl->minsize, tbl->maxsize);
+    } else
+        ret =
+            ASN1_mbstring_copy(out, in, inlen, inform,
+                               DIRSTRING_TYPE & global_mask);
+    if (ret <= 0)
+        return NULL;
+    return *out;
+}
+
+/*
+ * Now the tables and helper functions for the string table:
+ */
+
+/* size limits: this stuff is taken straight from RFC3280 */
+
+#define ub_name                         32768
+#define ub_common_name                  64
+#define ub_locality_name                128
+#define ub_state_name                   128
+#define ub_organization_name            64
+#define ub_organization_unit_name       64
+#define ub_title                        64
+#define ub_email_address                128
+#define ub_serial_number                64
+
+/* From RFC4524 */
+
+#define ub_rfc822_mailbox               256
+
+/* This table must be kept in NID order */
+
+static const ASN1_STRING_TABLE tbl_standard[] = {
+    {NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0},
+    {NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
+    {NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0},
+    {NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0},
+    {NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0},
+    {NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE,
+     0},
+    {NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING,
+     STABLE_NO_MASK},
+    {NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0},
+    {NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0},
+    {NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0},
+    {NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0},
+    {NID_surname, 1, ub_name, DIRSTRING_TYPE, 0},
+    {NID_initials, 1, ub_name, DIRSTRING_TYPE, 0},
+    {NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING,
+     STABLE_NO_MASK},
+    {NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
+    {NID_name, 1, ub_name, DIRSTRING_TYPE, 0},
+    {NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
+    {NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
+    {NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
+    {NID_rfc822Mailbox, 1, ub_rfc822_mailbox, B_ASN1_IA5STRING,
+     STABLE_NO_MASK},
+    {NID_INN, 1, 12, B_ASN1_NUMERICSTRING, STABLE_NO_MASK},
+    {NID_OGRN, 1, 13, B_ASN1_NUMERICSTRING, STABLE_NO_MASK},
+    {NID_SNILS, 1, 11, B_ASN1_NUMERICSTRING, STABLE_NO_MASK}
+};
+
+static int sk_table_cmp(const ASN1_STRING_TABLE *const *a,
+                        const ASN1_STRING_TABLE *const *b)
+{
+    return (*a)->nid - (*b)->nid;
+}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
+
+static int table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b)
+{
+    return a->nid - b->nid;
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
+
+ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid)
+{
+    int idx;
+    ASN1_STRING_TABLE fnd;
+    fnd.nid = nid;
+    if (stable) {
+        idx = sk_ASN1_STRING_TABLE_find(stable, &fnd);
+        if (idx >= 0)
+            return sk_ASN1_STRING_TABLE_value(stable, idx);
+    }
+    return OBJ_bsearch_table(&fnd, tbl_standard, OSSL_NELEM(tbl_standard));
+}
+
+/*
+ * Return a string table pointer which can be modified: either directly from
+ * table or a copy of an internal value added to the table.
+ */
+
+static ASN1_STRING_TABLE *stable_get(int nid)
+{
+    ASN1_STRING_TABLE *tmp, *rv;
+    /* Always need a string table so allocate one if NULL */
+    if (stable == NULL) {
+        stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
+        if (stable == NULL)
+            return NULL;
+    }
+    tmp = ASN1_STRING_TABLE_get(nid);
+    if (tmp && tmp->flags & STABLE_FLAGS_MALLOC)
+        return tmp;
+    rv = OPENSSL_zalloc(sizeof(*rv));
+    if (rv == NULL)
+        return NULL;
+    if (!sk_ASN1_STRING_TABLE_push(stable, rv)) {
+        OPENSSL_free(rv);
+        return NULL;
+    }
+    if (tmp) {
+        rv->nid = tmp->nid;
+        rv->minsize = tmp->minsize;
+        rv->maxsize = tmp->maxsize;
+        rv->mask = tmp->mask;
+        rv->flags = tmp->flags | STABLE_FLAGS_MALLOC;
+    } else {
+        rv->minsize = -1;
+        rv->maxsize = -1;
+        rv->flags = STABLE_FLAGS_MALLOC;
+    }
+    return rv;
+}
+
+int ASN1_STRING_TABLE_add(int nid,
+                          long minsize, long maxsize, unsigned long mask,
+                          unsigned long flags)
+{
+    ASN1_STRING_TABLE *tmp;
+    tmp = stable_get(nid);
+    if (!tmp) {
+        ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    if (minsize >= 0)
+        tmp->minsize = minsize;
+    if (maxsize >= 0)
+        tmp->maxsize = maxsize;
+    if (mask)
+        tmp->mask = mask;
+    if (flags)
+        tmp->flags = STABLE_FLAGS_MALLOC | flags;
+    return 1;
+}
+
+void ASN1_STRING_TABLE_cleanup(void)
+{
+    STACK_OF(ASN1_STRING_TABLE) *tmp;
+    tmp = stable;
+    if (!tmp)
+        return;
+    stable = NULL;
+    sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
+}
+
+static void st_free(ASN1_STRING_TABLE *tbl)
+{
+    if (tbl->flags & STABLE_FLAGS_MALLOC)
+        OPENSSL_free(tbl);
+}
+
+
+#ifdef STRING_TABLE_TEST
+
+main()
+{
+    ASN1_STRING_TABLE *tmp;
+    int i, last_nid = -1;
+
+    for (tmp = tbl_standard, i = 0; i < OSSL_NELEM(tbl_standard); i++, tmp++) {
+        if (tmp->nid < last_nid) {
+            last_nid = 0;
+            break;
+        }
+        last_nid = tmp->nid;
+    }
+
+    if (last_nid != 0) {
+        printf("Table order OK\n");
+        exit(0);
+    }
+
+    for (tmp = tbl_standard, i = 0; i < OSSL_NELEM(tbl_standard); i++, tmp++)
+        printf("Index %d, NID %d, Name=%s\n", i, tmp->nid,
+               OBJ_nid2ln(tmp->nid));
+
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_time.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_time.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_time.c	(revision 331)
@@ -0,0 +1,163 @@
+/*
+ * Copyright 1999-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
+ */
+
+/*-
+ * This is an implementation of the ASN1 Time structure which is:
+ *    Time ::= CHOICE {
+ *      utcTime        UTCTime,
+ *      generalTime    GeneralizedTime }
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include "asn1_locl.h"
+
+IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME)
+
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME)
+
+ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t)
+{
+    return ASN1_TIME_adj(s, t, 0, 0);
+}
+
+ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
+                         int offset_day, long offset_sec)
+{
+    struct tm *ts;
+    struct tm data;
+
+    ts = OPENSSL_gmtime(&t, &data);
+    if (ts == NULL) {
+        ASN1err(ASN1_F_ASN1_TIME_ADJ, ASN1_R_ERROR_GETTING_TIME);
+        return NULL;
+    }
+    if (offset_day || offset_sec) {
+        if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+            return NULL;
+    }
+    if ((ts->tm_year >= 50) && (ts->tm_year < 150))
+        return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
+    return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
+}
+
+int ASN1_TIME_check(const ASN1_TIME *t)
+{
+    if (t->type == V_ASN1_GENERALIZEDTIME)
+        return ASN1_GENERALIZEDTIME_check(t);
+    else if (t->type == V_ASN1_UTCTIME)
+        return ASN1_UTCTIME_check(t);
+    return 0;
+}
+
+/* Convert an ASN1_TIME structure to GeneralizedTime */
+ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
+                                                   ASN1_GENERALIZEDTIME **out)
+{
+    ASN1_GENERALIZEDTIME *ret;
+    char *str;
+    int newlen;
+
+    if (!ASN1_TIME_check(t))
+        return NULL;
+
+    if (out == NULL || *out == NULL) {
+        if ((ret = ASN1_GENERALIZEDTIME_new()) == NULL)
+            return NULL;
+        if (out)
+            *out = ret;
+    } else
+        ret = *out;
+
+    /* If already GeneralizedTime just copy across */
+    if (t->type == V_ASN1_GENERALIZEDTIME) {
+        if (!ASN1_STRING_set(ret, t->data, t->length))
+            return NULL;
+        return ret;
+    }
+
+    /* grow the string */
+    if (!ASN1_STRING_set(ret, NULL, t->length + 2))
+        return NULL;
+    /* ASN1_STRING_set() allocated 'len + 1' bytes. */
+    newlen = t->length + 2 + 1;
+    str = (char *)ret->data;
+    /* Work out the century and prepend */
+    if (t->data[0] >= '5')
+        OPENSSL_strlcpy(str, "19", newlen);
+    else
+        OPENSSL_strlcpy(str, "20", newlen);
+
+    OPENSSL_strlcat(str, (char *)t->data, newlen);
+
+    return ret;
+}
+
+int ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
+{
+    ASN1_TIME t;
+
+    t.length = strlen(str);
+    t.data = (unsigned char *)str;
+    t.flags = 0;
+
+    t.type = V_ASN1_UTCTIME;
+
+    if (!ASN1_TIME_check(&t)) {
+        t.type = V_ASN1_GENERALIZEDTIME;
+        if (!ASN1_TIME_check(&t))
+            return 0;
+    }
+
+    if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t))
+        return 0;
+
+    return 1;
+}
+
+static int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *t)
+{
+    if (t == NULL) {
+        time_t now_t;
+        time(&now_t);
+        if (OPENSSL_gmtime(&now_t, tm))
+            return 1;
+        return 0;
+    }
+
+    if (t->type == V_ASN1_UTCTIME)
+        return asn1_utctime_to_tm(tm, t);
+    else if (t->type == V_ASN1_GENERALIZEDTIME)
+        return asn1_generalizedtime_to_tm(tm, t);
+
+    return 0;
+}
+
+int ASN1_TIME_diff(int *pday, int *psec,
+                   const ASN1_TIME *from, const ASN1_TIME *to)
+{
+    struct tm tm_from, tm_to;
+    if (!asn1_time_to_tm(&tm_from, from))
+        return 0;
+    if (!asn1_time_to_tm(&tm_to, to))
+        return 0;
+    return OPENSSL_gmtime_diff(pday, psec, &tm_from, &tm_to);
+}
+
+int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm)
+{
+    if (tm->type == V_ASN1_UTCTIME)
+        return ASN1_UTCTIME_print(bp, tm);
+    if (tm->type == V_ASN1_GENERALIZEDTIME)
+        return ASN1_GENERALIZEDTIME_print(bp, tm);
+    BIO_write(bp, "Bad time value", 14);
+    return (0);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_type.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_type.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_type.c	(revision 331)
@@ -0,0 +1,134 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include "asn1_locl.h"
+
+int ASN1_TYPE_get(const ASN1_TYPE *a)
+{
+    if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
+        return (a->type);
+    else
+        return (0);
+}
+
+void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value)
+{
+    if (a->value.ptr != NULL) {
+        ASN1_TYPE **tmp_a = &a;
+        asn1_primitive_free((ASN1_VALUE **)tmp_a, NULL, 0);
+    }
+    a->type = type;
+    if (type == V_ASN1_BOOLEAN)
+        a->value.boolean = value ? 0xff : 0;
+    else
+        a->value.ptr = value;
+}
+
+int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
+{
+    if (!value || (type == V_ASN1_BOOLEAN)) {
+        void *p = (void *)value;
+        ASN1_TYPE_set(a, type, p);
+    } else if (type == V_ASN1_OBJECT) {
+        ASN1_OBJECT *odup;
+        odup = OBJ_dup(value);
+        if (!odup)
+            return 0;
+        ASN1_TYPE_set(a, type, odup);
+    } else {
+        ASN1_STRING *sdup;
+        sdup = ASN1_STRING_dup(value);
+        if (!sdup)
+            return 0;
+        ASN1_TYPE_set(a, type, sdup);
+    }
+    return 1;
+}
+
+/* Returns 0 if they are equal, != 0 otherwise. */
+int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
+{
+    int result = -1;
+
+    if (!a || !b || a->type != b->type)
+        return -1;
+
+    switch (a->type) {
+    case V_ASN1_OBJECT:
+        result = OBJ_cmp(a->value.object, b->value.object);
+        break;
+    case V_ASN1_BOOLEAN:
+        result = a->value.boolean - b->value.boolean;
+        break;
+    case V_ASN1_NULL:
+        result = 0;             /* They do not have content. */
+        break;
+    case V_ASN1_INTEGER:
+    case V_ASN1_ENUMERATED:
+    case V_ASN1_BIT_STRING:
+    case V_ASN1_OCTET_STRING:
+    case V_ASN1_SEQUENCE:
+    case V_ASN1_SET:
+    case V_ASN1_NUMERICSTRING:
+    case V_ASN1_PRINTABLESTRING:
+    case V_ASN1_T61STRING:
+    case V_ASN1_VIDEOTEXSTRING:
+    case V_ASN1_IA5STRING:
+    case V_ASN1_UTCTIME:
+    case V_ASN1_GENERALIZEDTIME:
+    case V_ASN1_GRAPHICSTRING:
+    case V_ASN1_VISIBLESTRING:
+    case V_ASN1_GENERALSTRING:
+    case V_ASN1_UNIVERSALSTRING:
+    case V_ASN1_BMPSTRING:
+    case V_ASN1_UTF8STRING:
+    case V_ASN1_OTHER:
+    default:
+        result = ASN1_STRING_cmp((ASN1_STRING *)a->value.ptr,
+                                 (ASN1_STRING *)b->value.ptr);
+        break;
+    }
+
+    return result;
+}
+
+ASN1_TYPE *ASN1_TYPE_pack_sequence(const ASN1_ITEM *it, void *s, ASN1_TYPE **t)
+{
+    ASN1_OCTET_STRING *oct;
+    ASN1_TYPE *rt;
+
+    oct = ASN1_item_pack(s, it, NULL);
+    if (oct == NULL)
+        return NULL;
+
+    if (t && *t) {
+        rt = *t;
+    } else {
+        rt = ASN1_TYPE_new();
+        if (rt == NULL) {
+            ASN1_OCTET_STRING_free(oct);
+            return NULL;
+        }
+        if (t)
+            *t = rt;
+    }
+    ASN1_TYPE_set(rt, V_ASN1_SEQUENCE, oct);
+    return rt;
+}
+
+void *ASN1_TYPE_unpack_sequence(const ASN1_ITEM *it, const ASN1_TYPE *t)
+{
+    if (t == NULL || t->type != V_ASN1_SEQUENCE || t->value.sequence == NULL)
+        return NULL;
+    return ASN1_item_unpack(t->value.sequence, it);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_utctm.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_utctm.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_utctm.c	(revision 331)
@@ -0,0 +1,254 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <time.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include "asn1_locl.h"
+
+int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d)
+{
+    static const int min[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };
+    static const int max[8] = { 99, 12, 31, 23, 59, 59, 12, 59 };
+    char *a;
+    int n, i, l, o;
+
+    if (d->type != V_ASN1_UTCTIME)
+        return (0);
+    l = d->length;
+    a = (char *)d->data;
+    o = 0;
+
+    if (l < 11)
+        goto err;
+    for (i = 0; i < 6; i++) {
+        if ((i == 5) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
+            i++;
+            if (tm)
+                tm->tm_sec = 0;
+            break;
+        }
+        if ((a[o] < '0') || (a[o] > '9'))
+            goto err;
+        n = a[o] - '0';
+        if (++o > l)
+            goto err;
+
+        if ((a[o] < '0') || (a[o] > '9'))
+            goto err;
+        n = (n * 10) + a[o] - '0';
+        if (++o > l)
+            goto err;
+
+        if ((n < min[i]) || (n > max[i]))
+            goto err;
+        if (tm) {
+            switch (i) {
+            case 0:
+                tm->tm_year = n < 50 ? n + 100 : n;
+                break;
+            case 1:
+                tm->tm_mon = n - 1;
+                break;
+            case 2:
+                tm->tm_mday = n;
+                break;
+            case 3:
+                tm->tm_hour = n;
+                break;
+            case 4:
+                tm->tm_min = n;
+                break;
+            case 5:
+                tm->tm_sec = n;
+                break;
+            }
+        }
+    }
+    if (a[o] == 'Z')
+        o++;
+    else if ((a[o] == '+') || (a[o] == '-')) {
+        int offsign = a[o] == '-' ? -1 : 1, offset = 0;
+        o++;
+        if (o + 4 > l)
+            goto err;
+        for (i = 6; i < 8; i++) {
+            if ((a[o] < '0') || (a[o] > '9'))
+                goto err;
+            n = a[o] - '0';
+            o++;
+            if ((a[o] < '0') || (a[o] > '9'))
+                goto err;
+            n = (n * 10) + a[o] - '0';
+            if ((n < min[i]) || (n > max[i]))
+                goto err;
+            if (tm) {
+                if (i == 6)
+                    offset = n * 3600;
+                else if (i == 7)
+                    offset += n * 60;
+            }
+            o++;
+        }
+        if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
+            return 0;
+    }
+    return o == l;
+ err:
+    return 0;
+}
+
+int ASN1_UTCTIME_check(const ASN1_UTCTIME *d)
+{
+    return asn1_utctime_to_tm(NULL, d);
+}
+
+int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str)
+{
+    ASN1_UTCTIME t;
+
+    t.type = V_ASN1_UTCTIME;
+    t.length = strlen(str);
+    t.data = (unsigned char *)str;
+    if (ASN1_UTCTIME_check(&t)) {
+        if (s != NULL) {
+            if (!ASN1_STRING_set((ASN1_STRING *)s, str, t.length))
+                return 0;
+            s->type = V_ASN1_UTCTIME;
+        }
+        return (1);
+    } else
+        return (0);
+}
+
+ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t)
+{
+    return ASN1_UTCTIME_adj(s, t, 0, 0);
+}
+
+ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
+                               int offset_day, long offset_sec)
+{
+    char *p;
+    struct tm *ts;
+    struct tm data;
+    size_t len = 20;
+    int free_s = 0;
+
+    if (s == NULL) {
+        s = ASN1_UTCTIME_new();
+        if (s == NULL)
+            goto err;
+        free_s = 1;
+    }
+
+    ts = OPENSSL_gmtime(&t, &data);
+    if (ts == NULL)
+        goto err;
+
+    if (offset_day || offset_sec) {
+        if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
+            goto err;
+    }
+
+    if ((ts->tm_year < 50) || (ts->tm_year >= 150))
+        goto err;
+
+    p = (char *)s->data;
+    if ((p == NULL) || ((size_t)s->length < len)) {
+        p = OPENSSL_malloc(len);
+        if (p == NULL) {
+            ASN1err(ASN1_F_ASN1_UTCTIME_ADJ, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        OPENSSL_free(s->data);
+        s->data = (unsigned char *)p;
+    }
+
+    BIO_snprintf(p, len, "%02d%02d%02d%02d%02d%02dZ", ts->tm_year % 100,
+                 ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min,
+                 ts->tm_sec);
+    s->length = strlen(p);
+    s->type = V_ASN1_UTCTIME;
+#ifdef CHARSET_EBCDIC_not
+    ebcdic2ascii(s->data, s->data, s->length);
+#endif
+    return (s);
+ err:
+    if (free_s)
+        ASN1_UTCTIME_free(s);
+    return NULL;
+}
+
+int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t)
+{
+    struct tm stm, ttm;
+    int day, sec;
+
+    if (!asn1_utctime_to_tm(&stm, s))
+        return -2;
+
+    if (!OPENSSL_gmtime(&t, &ttm))
+        return -2;
+
+    if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm))
+        return -2;
+
+    if (day > 0)
+        return 1;
+    if (day < 0)
+        return -1;
+    if (sec > 0)
+        return 1;
+    if (sec < 0)
+        return -1;
+    return 0;
+}
+
+int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm)
+{
+    const char *v;
+    int gmt = 0;
+    int i;
+    int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
+
+    i = tm->length;
+    v = (const char *)tm->data;
+
+    if (i < 10)
+        goto err;
+    if (v[i - 1] == 'Z')
+        gmt = 1;
+    for (i = 0; i < 10; i++)
+        if ((v[i] > '9') || (v[i] < '0'))
+            goto err;
+    y = (v[0] - '0') * 10 + (v[1] - '0');
+    if (y < 50)
+        y += 100;
+    M = (v[2] - '0') * 10 + (v[3] - '0');
+    if ((M > 12) || (M < 1))
+        goto err;
+    d = (v[4] - '0') * 10 + (v[5] - '0');
+    h = (v[6] - '0') * 10 + (v[7] - '0');
+    m = (v[8] - '0') * 10 + (v[9] - '0');
+    if (tm->length >= 12 &&
+        (v[10] >= '0') && (v[10] <= '9') && (v[11] >= '0') && (v[11] <= '9'))
+        s = (v[10] - '0') * 10 + (v[11] - '0');
+
+    if (BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s",
+                   _asn1_mon[M - 1], d, h, m, s, y + 1900,
+                   (gmt) ? " GMT" : "") <= 0)
+        return (0);
+    else
+        return (1);
+ err:
+    BIO_write(bp, "Bad time value", 14);
+    return (0);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_utf8.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_utf8.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_utf8.c	(revision 331)
@@ -0,0 +1,188 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+
+/* UTF8 utilities */
+
+/*-
+ * This parses a UTF8 string one character at a time. It is passed a pointer
+ * to the string and the length of the string. It sets 'value' to the value of
+ * the current character. It returns the number of characters read or a
+ * negative error code:
+ * -1 = string too short
+ * -2 = illegal character
+ * -3 = subsequent characters not of the form 10xxxxxx
+ * -4 = character encoded incorrectly (not minimal length).
+ */
+
+int UTF8_getc(const unsigned char *str, int len, unsigned long *val)
+{
+    const unsigned char *p;
+    unsigned long value;
+    int ret;
+    if (len <= 0)
+        return 0;
+    p = str;
+
+    /* Check syntax and work out the encoded value (if correct) */
+    if ((*p & 0x80) == 0) {
+        value = *p++ & 0x7f;
+        ret = 1;
+    } else if ((*p & 0xe0) == 0xc0) {
+        if (len < 2)
+            return -1;
+        if ((p[1] & 0xc0) != 0x80)
+            return -3;
+        value = (*p++ & 0x1f) << 6;
+        value |= *p++ & 0x3f;
+        if (value < 0x80)
+            return -4;
+        ret = 2;
+    } else if ((*p & 0xf0) == 0xe0) {
+        if (len < 3)
+            return -1;
+        if (((p[1] & 0xc0) != 0x80)
+            || ((p[2] & 0xc0) != 0x80))
+            return -3;
+        value = (*p++ & 0xf) << 12;
+        value |= (*p++ & 0x3f) << 6;
+        value |= *p++ & 0x3f;
+        if (value < 0x800)
+            return -4;
+        ret = 3;
+    } else if ((*p & 0xf8) == 0xf0) {
+        if (len < 4)
+            return -1;
+        if (((p[1] & 0xc0) != 0x80)
+            || ((p[2] & 0xc0) != 0x80)
+            || ((p[3] & 0xc0) != 0x80))
+            return -3;
+        value = ((unsigned long)(*p++ & 0x7)) << 18;
+        value |= (*p++ & 0x3f) << 12;
+        value |= (*p++ & 0x3f) << 6;
+        value |= *p++ & 0x3f;
+        if (value < 0x10000)
+            return -4;
+        ret = 4;
+    } else if ((*p & 0xfc) == 0xf8) {
+        if (len < 5)
+            return -1;
+        if (((p[1] & 0xc0) != 0x80)
+            || ((p[2] & 0xc0) != 0x80)
+            || ((p[3] & 0xc0) != 0x80)
+            || ((p[4] & 0xc0) != 0x80))
+            return -3;
+        value = ((unsigned long)(*p++ & 0x3)) << 24;
+        value |= ((unsigned long)(*p++ & 0x3f)) << 18;
+        value |= ((unsigned long)(*p++ & 0x3f)) << 12;
+        value |= (*p++ & 0x3f) << 6;
+        value |= *p++ & 0x3f;
+        if (value < 0x200000)
+            return -4;
+        ret = 5;
+    } else if ((*p & 0xfe) == 0xfc) {
+        if (len < 6)
+            return -1;
+        if (((p[1] & 0xc0) != 0x80)
+            || ((p[2] & 0xc0) != 0x80)
+            || ((p[3] & 0xc0) != 0x80)
+            || ((p[4] & 0xc0) != 0x80)
+            || ((p[5] & 0xc0) != 0x80))
+            return -3;
+        value = ((unsigned long)(*p++ & 0x1)) << 30;
+        value |= ((unsigned long)(*p++ & 0x3f)) << 24;
+        value |= ((unsigned long)(*p++ & 0x3f)) << 18;
+        value |= ((unsigned long)(*p++ & 0x3f)) << 12;
+        value |= (*p++ & 0x3f) << 6;
+        value |= *p++ & 0x3f;
+        if (value < 0x4000000)
+            return -4;
+        ret = 6;
+    } else
+        return -2;
+    *val = value;
+    return ret;
+}
+
+/*
+ * This takes a character 'value' and writes the UTF8 encoded value in 'str'
+ * where 'str' is a buffer containing 'len' characters. Returns the number of
+ * characters written or -1 if 'len' is too small. 'str' can be set to NULL
+ * in which case it just returns the number of characters. It will need at
+ * most 6 characters.
+ */
+
+int UTF8_putc(unsigned char *str, int len, unsigned long value)
+{
+    if (!str)
+        len = 6;                /* Maximum we will need */
+    else if (len <= 0)
+        return -1;
+    if (value < 0x80) {
+        if (str)
+            *str = (unsigned char)value;
+        return 1;
+    }
+    if (value < 0x800) {
+        if (len < 2)
+            return -1;
+        if (str) {
+            *str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0);
+            *str = (unsigned char)((value & 0x3f) | 0x80);
+        }
+        return 2;
+    }
+    if (value < 0x10000) {
+        if (len < 3)
+            return -1;
+        if (str) {
+            *str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0);
+            *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+            *str = (unsigned char)((value & 0x3f) | 0x80);
+        }
+        return 3;
+    }
+    if (value < 0x200000) {
+        if (len < 4)
+            return -1;
+        if (str) {
+            *str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0);
+            *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+            *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+            *str = (unsigned char)((value & 0x3f) | 0x80);
+        }
+        return 4;
+    }
+    if (value < 0x4000000) {
+        if (len < 5)
+            return -1;
+        if (str) {
+            *str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8);
+            *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
+            *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+            *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+            *str = (unsigned char)((value & 0x3f) | 0x80);
+        }
+        return 5;
+    }
+    if (len < 6)
+        return -1;
+    if (str) {
+        *str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc);
+        *str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80);
+        *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
+        *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
+        *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
+        *str = (unsigned char)((value & 0x3f) | 0x80);
+    }
+    return 6;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_verify.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_verify.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/a_verify.c	(revision 331)
@@ -0,0 +1,182 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <time.h>
+
+#include "internal/cryptlib.h"
+
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include <openssl/bn.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
+
+#ifndef NO_ASN1_OLD
+
+int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
+                char *data, EVP_PKEY *pkey)
+{
+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+    const EVP_MD *type;
+    unsigned char *p, *buf_in = NULL;
+    int ret = -1, i, inl;
+
+    if (ctx == NULL) {
+        ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    i = OBJ_obj2nid(a->algorithm);
+    type = EVP_get_digestbyname(OBJ_nid2sn(i));
+    if (type == NULL) {
+        ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+        goto err;
+    }
+
+    if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) {
+        ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
+        goto err;
+    }
+
+    inl = i2d(data, NULL);
+    buf_in = OPENSSL_malloc((unsigned int)inl);
+    if (buf_in == NULL) {
+        ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    p = buf_in;
+
+    i2d(data, &p);
+    ret = EVP_VerifyInit_ex(ctx, type, NULL)
+        && EVP_VerifyUpdate(ctx, (unsigned char *)buf_in, inl);
+
+    OPENSSL_clear_free(buf_in, (unsigned int)inl);
+
+    if (!ret) {
+        ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB);
+        goto err;
+    }
+    ret = -1;
+
+    if (EVP_VerifyFinal(ctx, (unsigned char *)signature->data,
+                        (unsigned int)signature->length, pkey) <= 0) {
+        ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB);
+        ret = 0;
+        goto err;
+    }
+    ret = 1;
+ err:
+    EVP_MD_CTX_free(ctx);
+    return (ret);
+}
+
+#endif
+
+int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
+                     ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
+{
+    EVP_MD_CTX *ctx = NULL;
+    unsigned char *buf_in = NULL;
+    int ret = -1, inl;
+
+    int mdnid, pknid;
+
+    if (!pkey) {
+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
+        return -1;
+    }
+
+    if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) {
+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
+        return -1;
+    }
+
+    ctx = EVP_MD_CTX_new();
+    if (ctx == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    /* Convert signature OID into digest and public key OIDs */
+    if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) {
+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
+        goto err;
+    }
+    if (mdnid == NID_undef) {
+        if (!pkey->ameth || !pkey->ameth->item_verify) {
+            ASN1err(ASN1_F_ASN1_ITEM_VERIFY,
+                    ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
+            goto err;
+        }
+        ret = pkey->ameth->item_verify(ctx, it, asn, a, signature, pkey);
+        /*
+         * Return value of 2 means carry on, anything else means we exit
+         * straight away: either a fatal error of the underlying verification
+         * routine handles all verification.
+         */
+        if (ret != 2)
+            goto err;
+        ret = -1;
+    } else {
+        const EVP_MD *type;
+        type = EVP_get_digestbynid(mdnid);
+        if (type == NULL) {
+            ASN1err(ASN1_F_ASN1_ITEM_VERIFY,
+                    ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+            goto err;
+        }
+
+        /* Check public key OID matches public key type */
+        if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) {
+            ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_WRONG_PUBLIC_KEY_TYPE);
+            goto err;
+        }
+
+        if (!EVP_DigestVerifyInit(ctx, NULL, type, NULL, pkey)) {
+            ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
+            ret = 0;
+            goto err;
+        }
+
+    }
+
+    inl = ASN1_item_i2d(asn, &buf_in, it);
+
+    if (buf_in == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    ret = EVP_DigestVerifyUpdate(ctx, buf_in, inl);
+
+    OPENSSL_clear_free(buf_in, (unsigned int)inl);
+
+    if (!ret) {
+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
+        goto err;
+    }
+    ret = -1;
+
+    if (EVP_DigestVerifyFinal(ctx, signature->data,
+                              (size_t)signature->length) <= 0) {
+        ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
+        ret = 0;
+        goto err;
+    }
+    ret = 1;
+ err:
+    EVP_MD_CTX_free(ctx);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/ameth_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/ameth_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/ameth_lib.c	(revision 331)
@@ -0,0 +1,400 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/engine.h>
+#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
+
+/* Keep this sorted in type order !! */
+static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
+#ifndef OPENSSL_NO_RSA
+    &rsa_asn1_meths[0],
+    &rsa_asn1_meths[1],
+#endif
+#ifndef OPENSSL_NO_DH
+    &dh_asn1_meth,
+#endif
+#ifndef OPENSSL_NO_DSA
+    &dsa_asn1_meths[0],
+    &dsa_asn1_meths[1],
+    &dsa_asn1_meths[2],
+    &dsa_asn1_meths[3],
+    &dsa_asn1_meths[4],
+#endif
+#ifndef OPENSSL_NO_EC
+    &eckey_asn1_meth,
+#endif
+    &hmac_asn1_meth,
+#ifndef OPENSSL_NO_CMAC
+    &cmac_asn1_meth,
+#endif
+#ifndef OPENSSL_NO_DH
+    &dhx_asn1_meth,
+#endif
+#ifndef OPENSSL_NO_EC
+    &ecx25519_asn1_meth
+#endif
+};
+
+typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
+static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL;
+
+#ifdef TEST
+void main()
+{
+    int i;
+    for (i = 0; i < OSSL_NELEM(standard_methods); i++)
+        fprintf(stderr, "Number %d id=%d (%s)\n", i,
+                standard_methods[i]->pkey_id,
+                OBJ_nid2sn(standard_methods[i]->pkey_id));
+}
+#endif
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
+                           const EVP_PKEY_ASN1_METHOD *, ameth);
+
+static int ameth_cmp(const EVP_PKEY_ASN1_METHOD *const *a,
+                     const EVP_PKEY_ASN1_METHOD *const *b)
+{
+    return ((*a)->pkey_id - (*b)->pkey_id);
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
+                             const EVP_PKEY_ASN1_METHOD *, ameth);
+
+int EVP_PKEY_asn1_get_count(void)
+{
+    int num = OSSL_NELEM(standard_methods);
+    if (app_methods)
+        num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
+    return num;
+}
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx)
+{
+    int num = OSSL_NELEM(standard_methods);
+    if (idx < 0)
+        return NULL;
+    if (idx < num)
+        return standard_methods[idx];
+    idx -= num;
+    return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
+}
+
+static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
+{
+    EVP_PKEY_ASN1_METHOD tmp;
+    const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
+    tmp.pkey_id = type;
+    if (app_methods) {
+        int idx;
+        idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
+        if (idx >= 0)
+            return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
+    }
+    ret = OBJ_bsearch_ameth(&t, standard_methods, OSSL_NELEM(standard_methods));
+    if (!ret || !*ret)
+        return NULL;
+    return *ret;
+}
+
+/*
+ * Find an implementation of an ASN1 algorithm. If 'pe' is not NULL also
+ * search through engines and set *pe to a functional reference to the engine
+ * implementing 'type' or NULL if no engine implements it.
+ */
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type)
+{
+    const EVP_PKEY_ASN1_METHOD *t;
+
+    for (;;) {
+        t = pkey_asn1_find(type);
+        if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
+            break;
+        type = t->pkey_base_id;
+    }
+    if (pe) {
+#ifndef OPENSSL_NO_ENGINE
+        ENGINE *e;
+        /* type will contain the final unaliased type */
+        e = ENGINE_get_pkey_asn1_meth_engine(type);
+        if (e) {
+            *pe = e;
+            return ENGINE_get_pkey_asn1_meth(e, type);
+        }
+#endif
+        *pe = NULL;
+    }
+    return t;
+}
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
+                                                   const char *str, int len)
+{
+    int i;
+    const EVP_PKEY_ASN1_METHOD *ameth;
+    if (len == -1)
+        len = strlen(str);
+    if (pe) {
+#ifndef OPENSSL_NO_ENGINE
+        ENGINE *e;
+        ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
+        if (ameth) {
+            /*
+             * Convert structural into functional reference
+             */
+            if (!ENGINE_init(e))
+                ameth = NULL;
+            ENGINE_free(e);
+            *pe = e;
+            return ameth;
+        }
+#endif
+        *pe = NULL;
+    }
+    for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
+        ameth = EVP_PKEY_asn1_get0(i);
+        if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
+            continue;
+        if (((int)strlen(ameth->pem_str) == len)
+            && (strncasecmp(ameth->pem_str, str, len) == 0))
+            return ameth;
+    }
+    return NULL;
+}
+
+int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
+{
+    if (app_methods == NULL) {
+        app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
+        if (app_methods == NULL)
+            return 0;
+    }
+    if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
+        return 0;
+    sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
+    return 1;
+}
+
+int EVP_PKEY_asn1_add_alias(int to, int from)
+{
+    EVP_PKEY_ASN1_METHOD *ameth;
+    ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
+    if (ameth == NULL)
+        return 0;
+    ameth->pkey_base_id = to;
+    if (!EVP_PKEY_asn1_add0(ameth)) {
+        EVP_PKEY_asn1_free(ameth);
+        return 0;
+    }
+    return 1;
+}
+
+int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id,
+                            int *ppkey_flags, const char **pinfo,
+                            const char **ppem_str,
+                            const EVP_PKEY_ASN1_METHOD *ameth)
+{
+    if (!ameth)
+        return 0;
+    if (ppkey_id)
+        *ppkey_id = ameth->pkey_id;
+    if (ppkey_base_id)
+        *ppkey_base_id = ameth->pkey_base_id;
+    if (ppkey_flags)
+        *ppkey_flags = ameth->pkey_flags;
+    if (pinfo)
+        *pinfo = ameth->info;
+    if (ppem_str)
+        *ppem_str = ameth->pem_str;
+    return 1;
+}
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(const EVP_PKEY *pkey)
+{
+    return pkey->ameth;
+}
+
+EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags,
+                                        const char *pem_str, const char *info)
+{
+    EVP_PKEY_ASN1_METHOD *ameth = OPENSSL_zalloc(sizeof(*ameth));
+
+    if (ameth == NULL)
+        return NULL;
+
+    ameth->pkey_id = id;
+    ameth->pkey_base_id = id;
+    ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
+
+    if (info) {
+        ameth->info = OPENSSL_strdup(info);
+        if (!ameth->info)
+            goto err;
+    }
+
+    if (pem_str) {
+        ameth->pem_str = OPENSSL_strdup(pem_str);
+        if (!ameth->pem_str)
+            goto err;
+    }
+
+    return ameth;
+
+ err:
+    EVP_PKEY_asn1_free(ameth);
+    return NULL;
+
+}
+
+void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
+                        const EVP_PKEY_ASN1_METHOD *src)
+{
+
+    dst->pub_decode = src->pub_decode;
+    dst->pub_encode = src->pub_encode;
+    dst->pub_cmp = src->pub_cmp;
+    dst->pub_print = src->pub_print;
+
+    dst->priv_decode = src->priv_decode;
+    dst->priv_encode = src->priv_encode;
+    dst->priv_print = src->priv_print;
+
+    dst->old_priv_encode = src->old_priv_encode;
+    dst->old_priv_decode = src->old_priv_decode;
+
+    dst->pkey_size = src->pkey_size;
+    dst->pkey_bits = src->pkey_bits;
+
+    dst->param_decode = src->param_decode;
+    dst->param_encode = src->param_encode;
+    dst->param_missing = src->param_missing;
+    dst->param_copy = src->param_copy;
+    dst->param_cmp = src->param_cmp;
+    dst->param_print = src->param_print;
+
+    dst->pkey_free = src->pkey_free;
+    dst->pkey_ctrl = src->pkey_ctrl;
+
+    dst->item_sign = src->item_sign;
+    dst->item_verify = src->item_verify;
+
+}
+
+void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
+{
+    if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC)) {
+        OPENSSL_free(ameth->pem_str);
+        OPENSSL_free(ameth->info);
+        OPENSSL_free(ameth);
+    }
+}
+
+void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
+                              int (*pub_decode) (EVP_PKEY *pk,
+                                                 X509_PUBKEY *pub),
+                              int (*pub_encode) (X509_PUBKEY *pub,
+                                                 const EVP_PKEY *pk),
+                              int (*pub_cmp) (const EVP_PKEY *a,
+                                              const EVP_PKEY *b),
+                              int (*pub_print) (BIO *out,
+                                                const EVP_PKEY *pkey,
+                                                int indent, ASN1_PCTX *pctx),
+                              int (*pkey_size) (const EVP_PKEY *pk),
+                              int (*pkey_bits) (const EVP_PKEY *pk))
+{
+    ameth->pub_decode = pub_decode;
+    ameth->pub_encode = pub_encode;
+    ameth->pub_cmp = pub_cmp;
+    ameth->pub_print = pub_print;
+    ameth->pkey_size = pkey_size;
+    ameth->pkey_bits = pkey_bits;
+}
+
+void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
+                               int (*priv_decode) (EVP_PKEY *pk,
+                                                   const PKCS8_PRIV_KEY_INFO
+                                                   *p8inf),
+                               int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8,
+                                                   const EVP_PKEY *pk),
+                               int (*priv_print) (BIO *out,
+                                                  const EVP_PKEY *pkey,
+                                                  int indent,
+                                                  ASN1_PCTX *pctx))
+{
+    ameth->priv_decode = priv_decode;
+    ameth->priv_encode = priv_encode;
+    ameth->priv_print = priv_print;
+}
+
+void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
+                             int (*param_decode) (EVP_PKEY *pkey,
+                                                  const unsigned char **pder,
+                                                  int derlen),
+                             int (*param_encode) (const EVP_PKEY *pkey,
+                                                  unsigned char **pder),
+                             int (*param_missing) (const EVP_PKEY *pk),
+                             int (*param_copy) (EVP_PKEY *to,
+                                                const EVP_PKEY *from),
+                             int (*param_cmp) (const EVP_PKEY *a,
+                                               const EVP_PKEY *b),
+                             int (*param_print) (BIO *out,
+                                                 const EVP_PKEY *pkey,
+                                                 int indent, ASN1_PCTX *pctx))
+{
+    ameth->param_decode = param_decode;
+    ameth->param_encode = param_encode;
+    ameth->param_missing = param_missing;
+    ameth->param_copy = param_copy;
+    ameth->param_cmp = param_cmp;
+    ameth->param_print = param_print;
+}
+
+void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
+                            void (*pkey_free) (EVP_PKEY *pkey))
+{
+    ameth->pkey_free = pkey_free;
+}
+
+void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
+                            int (*pkey_ctrl) (EVP_PKEY *pkey, int op,
+                                              long arg1, void *arg2))
+{
+    ameth->pkey_ctrl = pkey_ctrl;
+}
+
+void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth,
+                                     int (*pkey_security_bits) (const EVP_PKEY
+                                                                *pk))
+{
+    ameth->pkey_security_bits = pkey_security_bits;
+}
+
+void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth,
+                            int (*item_verify) (EVP_MD_CTX *ctx,
+                                                const ASN1_ITEM *it,
+                                                void *asn,
+                                                X509_ALGOR *a,
+                                                ASN1_BIT_STRING *sig,
+                                                EVP_PKEY *pkey),
+                            int (*item_sign) (EVP_MD_CTX *ctx,
+                                              const ASN1_ITEM *it,
+                                              void *asn,
+                                              X509_ALGOR *alg1,
+                                              X509_ALGOR *alg2,
+                                              ASN1_BIT_STRING *sig))
+{
+    ameth->item_sign = item_sign;
+    ameth->item_verify = item_verify;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn1_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn1_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn1_err.c	(revision 331)
@@ -0,0 +1,267 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/asn1.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ASN1,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ASN1,0,reason)
+
+static ERR_STRING_DATA ASN1_str_functs[] = {
+    {ERR_FUNC(ASN1_F_A2D_ASN1_OBJECT), "a2d_ASN1_OBJECT"},
+    {ERR_FUNC(ASN1_F_A2I_ASN1_INTEGER), "a2i_ASN1_INTEGER"},
+    {ERR_FUNC(ASN1_F_A2I_ASN1_STRING), "a2i_ASN1_STRING"},
+    {ERR_FUNC(ASN1_F_APPEND_EXP), "append_exp"},
+    {ERR_FUNC(ASN1_F_ASN1_BIT_STRING_SET_BIT), "ASN1_BIT_STRING_set_bit"},
+    {ERR_FUNC(ASN1_F_ASN1_CB), "asn1_cb"},
+    {ERR_FUNC(ASN1_F_ASN1_CHECK_TLEN), "asn1_check_tlen"},
+    {ERR_FUNC(ASN1_F_ASN1_COLLECT), "asn1_collect"},
+    {ERR_FUNC(ASN1_F_ASN1_D2I_EX_PRIMITIVE), "asn1_d2i_ex_primitive"},
+    {ERR_FUNC(ASN1_F_ASN1_D2I_FP), "ASN1_d2i_fp"},
+    {ERR_FUNC(ASN1_F_ASN1_D2I_READ_BIO), "asn1_d2i_read_bio"},
+    {ERR_FUNC(ASN1_F_ASN1_DIGEST), "ASN1_digest"},
+    {ERR_FUNC(ASN1_F_ASN1_DO_ADB), "asn1_do_adb"},
+    {ERR_FUNC(ASN1_F_ASN1_DO_LOCK), "asn1_do_lock"},
+    {ERR_FUNC(ASN1_F_ASN1_DUP), "ASN1_dup"},
+    {ERR_FUNC(ASN1_F_ASN1_EX_C2I), "asn1_ex_c2i"},
+    {ERR_FUNC(ASN1_F_ASN1_FIND_END), "asn1_find_end"},
+    {ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_ADJ), "ASN1_GENERALIZEDTIME_adj"},
+    {ERR_FUNC(ASN1_F_ASN1_GENERATE_V3), "ASN1_generate_v3"},
+    {ERR_FUNC(ASN1_F_ASN1_GET_INT64), "asn1_get_int64"},
+    {ERR_FUNC(ASN1_F_ASN1_GET_OBJECT), "ASN1_get_object"},
+    {ERR_FUNC(ASN1_F_ASN1_GET_UINT64), "asn1_get_uint64"},
+    {ERR_FUNC(ASN1_F_ASN1_I2D_BIO), "ASN1_i2d_bio"},
+    {ERR_FUNC(ASN1_F_ASN1_I2D_FP), "ASN1_i2d_fp"},
+    {ERR_FUNC(ASN1_F_ASN1_ITEM_D2I_FP), "ASN1_item_d2i_fp"},
+    {ERR_FUNC(ASN1_F_ASN1_ITEM_DUP), "ASN1_item_dup"},
+    {ERR_FUNC(ASN1_F_ASN1_ITEM_EMBED_D2I), "asn1_item_embed_d2i"},
+    {ERR_FUNC(ASN1_F_ASN1_ITEM_EMBED_NEW), "asn1_item_embed_new"},
+    {ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_BIO), "ASN1_item_i2d_bio"},
+    {ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP), "ASN1_item_i2d_fp"},
+    {ERR_FUNC(ASN1_F_ASN1_ITEM_PACK), "ASN1_item_pack"},
+    {ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN), "ASN1_item_sign"},
+    {ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN_CTX), "ASN1_item_sign_ctx"},
+    {ERR_FUNC(ASN1_F_ASN1_ITEM_UNPACK), "ASN1_item_unpack"},
+    {ERR_FUNC(ASN1_F_ASN1_ITEM_VERIFY), "ASN1_item_verify"},
+    {ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY), "ASN1_mbstring_ncopy"},
+    {ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW), "ASN1_OBJECT_new"},
+    {ERR_FUNC(ASN1_F_ASN1_OUTPUT_DATA), "asn1_output_data"},
+    {ERR_FUNC(ASN1_F_ASN1_PCTX_NEW), "ASN1_PCTX_new"},
+    {ERR_FUNC(ASN1_F_ASN1_SCTX_NEW), "ASN1_SCTX_new"},
+    {ERR_FUNC(ASN1_F_ASN1_SIGN), "ASN1_sign"},
+    {ERR_FUNC(ASN1_F_ASN1_STR2TYPE), "asn1_str2type"},
+    {ERR_FUNC(ASN1_F_ASN1_STRING_GET_INT64), "asn1_string_get_int64"},
+    {ERR_FUNC(ASN1_F_ASN1_STRING_GET_UINT64), "asn1_string_get_uint64"},
+    {ERR_FUNC(ASN1_F_ASN1_STRING_SET), "ASN1_STRING_set"},
+    {ERR_FUNC(ASN1_F_ASN1_STRING_TABLE_ADD), "ASN1_STRING_TABLE_add"},
+    {ERR_FUNC(ASN1_F_ASN1_STRING_TO_BN), "asn1_string_to_bn"},
+    {ERR_FUNC(ASN1_F_ASN1_STRING_TYPE_NEW), "ASN1_STRING_type_new"},
+    {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_EX_D2I), "asn1_template_ex_d2i"},
+    {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NEW), "asn1_template_new"},
+    {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I), "asn1_template_noexp_d2i"},
+    {ERR_FUNC(ASN1_F_ASN1_TIME_ADJ), "ASN1_TIME_adj"},
+    {ERR_FUNC(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING),
+     "ASN1_TYPE_get_int_octetstring"},
+    {ERR_FUNC(ASN1_F_ASN1_TYPE_GET_OCTETSTRING), "ASN1_TYPE_get_octetstring"},
+    {ERR_FUNC(ASN1_F_ASN1_UTCTIME_ADJ), "ASN1_UTCTIME_adj"},
+    {ERR_FUNC(ASN1_F_ASN1_VERIFY), "ASN1_verify"},
+    {ERR_FUNC(ASN1_F_B64_READ_ASN1), "b64_read_asn1"},
+    {ERR_FUNC(ASN1_F_B64_WRITE_ASN1), "B64_write_ASN1"},
+    {ERR_FUNC(ASN1_F_BIO_NEW_NDEF), "BIO_new_NDEF"},
+    {ERR_FUNC(ASN1_F_BITSTR_CB), "bitstr_cb"},
+    {ERR_FUNC(ASN1_F_BN_TO_ASN1_STRING), "bn_to_asn1_string"},
+    {ERR_FUNC(ASN1_F_C2I_ASN1_BIT_STRING), "c2i_ASN1_BIT_STRING"},
+    {ERR_FUNC(ASN1_F_C2I_ASN1_INTEGER), "c2i_ASN1_INTEGER"},
+    {ERR_FUNC(ASN1_F_C2I_ASN1_OBJECT), "c2i_ASN1_OBJECT"},
+    {ERR_FUNC(ASN1_F_C2I_IBUF), "c2i_ibuf"},
+    {ERR_FUNC(ASN1_F_COLLECT_DATA), "collect_data"},
+    {ERR_FUNC(ASN1_F_D2I_ASN1_OBJECT), "d2i_ASN1_OBJECT"},
+    {ERR_FUNC(ASN1_F_D2I_ASN1_UINTEGER), "d2i_ASN1_UINTEGER"},
+    {ERR_FUNC(ASN1_F_D2I_AUTOPRIVATEKEY), "d2i_AutoPrivateKey"},
+    {ERR_FUNC(ASN1_F_D2I_PRIVATEKEY), "d2i_PrivateKey"},
+    {ERR_FUNC(ASN1_F_D2I_PUBLICKEY), "d2i_PublicKey"},
+    {ERR_FUNC(ASN1_F_DO_TCREATE), "do_tcreate"},
+    {ERR_FUNC(ASN1_F_I2D_ASN1_BIO_STREAM), "i2d_ASN1_bio_stream"},
+    {ERR_FUNC(ASN1_F_I2D_DSA_PUBKEY), "i2d_DSA_PUBKEY"},
+    {ERR_FUNC(ASN1_F_I2D_EC_PUBKEY), "i2d_EC_PUBKEY"},
+    {ERR_FUNC(ASN1_F_I2D_PRIVATEKEY), "i2d_PrivateKey"},
+    {ERR_FUNC(ASN1_F_I2D_PUBLICKEY), "i2d_PublicKey"},
+    {ERR_FUNC(ASN1_F_I2D_RSA_PUBKEY), "i2d_RSA_PUBKEY"},
+    {ERR_FUNC(ASN1_F_LONG_C2I), "long_c2i"},
+    {ERR_FUNC(ASN1_F_OID_MODULE_INIT), "oid_module_init"},
+    {ERR_FUNC(ASN1_F_PARSE_TAGGING), "parse_tagging"},
+    {ERR_FUNC(ASN1_F_PKCS5_PBE2_SET_IV), "PKCS5_pbe2_set_iv"},
+    {ERR_FUNC(ASN1_F_PKCS5_PBE2_SET_SCRYPT), "PKCS5_pbe2_set_scrypt"},
+    {ERR_FUNC(ASN1_F_PKCS5_PBE_SET), "PKCS5_pbe_set"},
+    {ERR_FUNC(ASN1_F_PKCS5_PBE_SET0_ALGOR), "PKCS5_pbe_set0_algor"},
+    {ERR_FUNC(ASN1_F_PKCS5_PBKDF2_SET), "PKCS5_pbkdf2_set"},
+    {ERR_FUNC(ASN1_F_PKCS5_SCRYPT_SET), "pkcs5_scrypt_set"},
+    {ERR_FUNC(ASN1_F_SMIME_READ_ASN1), "SMIME_read_ASN1"},
+    {ERR_FUNC(ASN1_F_SMIME_TEXT), "SMIME_text"},
+    {ERR_FUNC(ASN1_F_STBL_MODULE_INIT), "stbl_module_init"},
+    {ERR_FUNC(ASN1_F_X509_CRL_ADD0_REVOKED), "X509_CRL_add0_revoked"},
+    {ERR_FUNC(ASN1_F_X509_INFO_NEW), "X509_INFO_new"},
+    {ERR_FUNC(ASN1_F_X509_NAME_ENCODE), "x509_name_encode"},
+    {ERR_FUNC(ASN1_F_X509_NAME_EX_D2I), "x509_name_ex_d2i"},
+    {ERR_FUNC(ASN1_F_X509_NAME_EX_NEW), "x509_name_ex_new"},
+    {ERR_FUNC(ASN1_F_X509_PKEY_NEW), "X509_PKEY_new"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA ASN1_str_reasons[] = {
+    {ERR_REASON(ASN1_R_ADDING_OBJECT), "adding object"},
+    {ERR_REASON(ASN1_R_ASN1_PARSE_ERROR), "asn1 parse error"},
+    {ERR_REASON(ASN1_R_ASN1_SIG_PARSE_ERROR), "asn1 sig parse error"},
+    {ERR_REASON(ASN1_R_AUX_ERROR), "aux error"},
+    {ERR_REASON(ASN1_R_BAD_OBJECT_HEADER), "bad object header"},
+    {ERR_REASON(ASN1_R_BMPSTRING_IS_WRONG_LENGTH),
+     "bmpstring is wrong length"},
+    {ERR_REASON(ASN1_R_BN_LIB), "bn lib"},
+    {ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH), "boolean is wrong length"},
+    {ERR_REASON(ASN1_R_BUFFER_TOO_SMALL), "buffer too small"},
+    {ERR_REASON(ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),
+     "cipher has no object identifier"},
+    {ERR_REASON(ASN1_R_CONTEXT_NOT_INITIALISED), "context not initialised"},
+    {ERR_REASON(ASN1_R_DATA_IS_WRONG), "data is wrong"},
+    {ERR_REASON(ASN1_R_DECODE_ERROR), "decode error"},
+    {ERR_REASON(ASN1_R_DEPTH_EXCEEDED), "depth exceeded"},
+    {ERR_REASON(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED),
+     "digest and key type not supported"},
+    {ERR_REASON(ASN1_R_ENCODE_ERROR), "encode error"},
+    {ERR_REASON(ASN1_R_ERROR_GETTING_TIME), "error getting time"},
+    {ERR_REASON(ASN1_R_ERROR_LOADING_SECTION), "error loading section"},
+    {ERR_REASON(ASN1_R_ERROR_SETTING_CIPHER_PARAMS),
+     "error setting cipher params"},
+    {ERR_REASON(ASN1_R_EXPECTING_AN_INTEGER), "expecting an integer"},
+    {ERR_REASON(ASN1_R_EXPECTING_AN_OBJECT), "expecting an object"},
+    {ERR_REASON(ASN1_R_EXPLICIT_LENGTH_MISMATCH), "explicit length mismatch"},
+    {ERR_REASON(ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED),
+     "explicit tag not constructed"},
+    {ERR_REASON(ASN1_R_FIELD_MISSING), "field missing"},
+    {ERR_REASON(ASN1_R_FIRST_NUM_TOO_LARGE), "first num too large"},
+    {ERR_REASON(ASN1_R_HEADER_TOO_LONG), "header too long"},
+    {ERR_REASON(ASN1_R_ILLEGAL_BITSTRING_FORMAT), "illegal bitstring format"},
+    {ERR_REASON(ASN1_R_ILLEGAL_BOOLEAN), "illegal boolean"},
+    {ERR_REASON(ASN1_R_ILLEGAL_CHARACTERS), "illegal characters"},
+    {ERR_REASON(ASN1_R_ILLEGAL_FORMAT), "illegal format"},
+    {ERR_REASON(ASN1_R_ILLEGAL_HEX), "illegal hex"},
+    {ERR_REASON(ASN1_R_ILLEGAL_IMPLICIT_TAG), "illegal implicit tag"},
+    {ERR_REASON(ASN1_R_ILLEGAL_INTEGER), "illegal integer"},
+    {ERR_REASON(ASN1_R_ILLEGAL_NEGATIVE_VALUE), "illegal negative value"},
+    {ERR_REASON(ASN1_R_ILLEGAL_NESTED_TAGGING), "illegal nested tagging"},
+    {ERR_REASON(ASN1_R_ILLEGAL_NULL), "illegal null"},
+    {ERR_REASON(ASN1_R_ILLEGAL_NULL_VALUE), "illegal null value"},
+    {ERR_REASON(ASN1_R_ILLEGAL_OBJECT), "illegal object"},
+    {ERR_REASON(ASN1_R_ILLEGAL_OPTIONAL_ANY), "illegal optional any"},
+    {ERR_REASON(ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE),
+     "illegal options on item template"},
+    {ERR_REASON(ASN1_R_ILLEGAL_PADDING), "illegal padding"},
+    {ERR_REASON(ASN1_R_ILLEGAL_TAGGED_ANY), "illegal tagged any"},
+    {ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE), "illegal time value"},
+    {ERR_REASON(ASN1_R_ILLEGAL_ZERO_CONTENT), "illegal zero content"},
+    {ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT), "integer not ascii format"},
+    {ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),
+     "integer too large for long"},
+    {ERR_REASON(ASN1_R_INVALID_BIT_STRING_BITS_LEFT),
+     "invalid bit string bits left"},
+    {ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH), "invalid bmpstring length"},
+    {ERR_REASON(ASN1_R_INVALID_DIGIT), "invalid digit"},
+    {ERR_REASON(ASN1_R_INVALID_MIME_TYPE), "invalid mime type"},
+    {ERR_REASON(ASN1_R_INVALID_MODIFIER), "invalid modifier"},
+    {ERR_REASON(ASN1_R_INVALID_NUMBER), "invalid number"},
+    {ERR_REASON(ASN1_R_INVALID_OBJECT_ENCODING), "invalid object encoding"},
+    {ERR_REASON(ASN1_R_INVALID_SCRYPT_PARAMETERS),
+     "invalid scrypt parameters"},
+    {ERR_REASON(ASN1_R_INVALID_SEPARATOR), "invalid separator"},
+    {ERR_REASON(ASN1_R_INVALID_STRING_TABLE_VALUE),
+     "invalid string table value"},
+    {ERR_REASON(ASN1_R_INVALID_UNIVERSALSTRING_LENGTH),
+     "invalid universalstring length"},
+    {ERR_REASON(ASN1_R_INVALID_UTF8STRING), "invalid utf8string"},
+    {ERR_REASON(ASN1_R_INVALID_VALUE), "invalid value"},
+    {ERR_REASON(ASN1_R_LIST_ERROR), "list error"},
+    {ERR_REASON(ASN1_R_MIME_NO_CONTENT_TYPE), "mime no content type"},
+    {ERR_REASON(ASN1_R_MIME_PARSE_ERROR), "mime parse error"},
+    {ERR_REASON(ASN1_R_MIME_SIG_PARSE_ERROR), "mime sig parse error"},
+    {ERR_REASON(ASN1_R_MISSING_EOC), "missing eoc"},
+    {ERR_REASON(ASN1_R_MISSING_SECOND_NUMBER), "missing second number"},
+    {ERR_REASON(ASN1_R_MISSING_VALUE), "missing value"},
+    {ERR_REASON(ASN1_R_MSTRING_NOT_UNIVERSAL), "mstring not universal"},
+    {ERR_REASON(ASN1_R_MSTRING_WRONG_TAG), "mstring wrong tag"},
+    {ERR_REASON(ASN1_R_NESTED_ASN1_STRING), "nested asn1 string"},
+    {ERR_REASON(ASN1_R_NON_HEX_CHARACTERS), "non hex characters"},
+    {ERR_REASON(ASN1_R_NOT_ASCII_FORMAT), "not ascii format"},
+    {ERR_REASON(ASN1_R_NOT_ENOUGH_DATA), "not enough data"},
+    {ERR_REASON(ASN1_R_NO_CONTENT_TYPE), "no content type"},
+    {ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE), "no matching choice type"},
+    {ERR_REASON(ASN1_R_NO_MULTIPART_BODY_FAILURE),
+     "no multipart body failure"},
+    {ERR_REASON(ASN1_R_NO_MULTIPART_BOUNDARY), "no multipart boundary"},
+    {ERR_REASON(ASN1_R_NO_SIG_CONTENT_TYPE), "no sig content type"},
+    {ERR_REASON(ASN1_R_NULL_IS_WRONG_LENGTH), "null is wrong length"},
+    {ERR_REASON(ASN1_R_OBJECT_NOT_ASCII_FORMAT), "object not ascii format"},
+    {ERR_REASON(ASN1_R_ODD_NUMBER_OF_CHARS), "odd number of chars"},
+    {ERR_REASON(ASN1_R_SECOND_NUMBER_TOO_LARGE), "second number too large"},
+    {ERR_REASON(ASN1_R_SEQUENCE_LENGTH_MISMATCH), "sequence length mismatch"},
+    {ERR_REASON(ASN1_R_SEQUENCE_NOT_CONSTRUCTED), "sequence not constructed"},
+    {ERR_REASON(ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG),
+     "sequence or set needs config"},
+    {ERR_REASON(ASN1_R_SHORT_LINE), "short line"},
+    {ERR_REASON(ASN1_R_SIG_INVALID_MIME_TYPE), "sig invalid mime type"},
+    {ERR_REASON(ASN1_R_STREAMING_NOT_SUPPORTED), "streaming not supported"},
+    {ERR_REASON(ASN1_R_STRING_TOO_LONG), "string too long"},
+    {ERR_REASON(ASN1_R_STRING_TOO_SHORT), "string too short"},
+    {ERR_REASON(ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),
+     "the asn1 object identifier is not known for this md"},
+    {ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT), "time not ascii format"},
+    {ERR_REASON(ASN1_R_TOO_LARGE), "too large"},
+    {ERR_REASON(ASN1_R_TOO_LONG), "too long"},
+    {ERR_REASON(ASN1_R_TOO_SMALL), "too small"},
+    {ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED), "type not constructed"},
+    {ERR_REASON(ASN1_R_TYPE_NOT_PRIMITIVE), "type not primitive"},
+    {ERR_REASON(ASN1_R_UNEXPECTED_EOC), "unexpected eoc"},
+    {ERR_REASON(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH),
+     "universalstring is wrong length"},
+    {ERR_REASON(ASN1_R_UNKNOWN_FORMAT), "unknown format"},
+    {ERR_REASON(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM),
+     "unknown message digest algorithm"},
+    {ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE), "unknown object type"},
+    {ERR_REASON(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE), "unknown public key type"},
+    {ERR_REASON(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM),
+     "unknown signature algorithm"},
+    {ERR_REASON(ASN1_R_UNKNOWN_TAG), "unknown tag"},
+    {ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE),
+     "unsupported any defined by type"},
+    {ERR_REASON(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE),
+     "unsupported public key type"},
+    {ERR_REASON(ASN1_R_UNSUPPORTED_TYPE), "unsupported type"},
+    {ERR_REASON(ASN1_R_WRONG_INTEGER_TYPE), "wrong integer type"},
+    {ERR_REASON(ASN1_R_WRONG_PUBLIC_KEY_TYPE), "wrong public key type"},
+    {ERR_REASON(ASN1_R_WRONG_TAG), "wrong tag"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_ASN1_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(ASN1_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, ASN1_str_functs);
+        ERR_load_strings(0, ASN1_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn1_gen.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn1_gen.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn1_gen.c	(revision 331)
@@ -0,0 +1,789 @@
+/*
+ * Copyright 2002-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 "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/x509v3.h>
+
+#define ASN1_GEN_FLAG           0x10000
+#define ASN1_GEN_FLAG_IMP       (ASN1_GEN_FLAG|1)
+#define ASN1_GEN_FLAG_EXP       (ASN1_GEN_FLAG|2)
+#define ASN1_GEN_FLAG_TAG       (ASN1_GEN_FLAG|3)
+#define ASN1_GEN_FLAG_BITWRAP   (ASN1_GEN_FLAG|4)
+#define ASN1_GEN_FLAG_OCTWRAP   (ASN1_GEN_FLAG|5)
+#define ASN1_GEN_FLAG_SEQWRAP   (ASN1_GEN_FLAG|6)
+#define ASN1_GEN_FLAG_SETWRAP   (ASN1_GEN_FLAG|7)
+#define ASN1_GEN_FLAG_FORMAT    (ASN1_GEN_FLAG|8)
+
+#define ASN1_GEN_STR(str,val)   {str, sizeof(str) - 1, val}
+
+#define ASN1_FLAG_EXP_MAX       20
+/* Maximum number of nested sequences */
+#define ASN1_GEN_SEQ_MAX_DEPTH  50
+
+/* Input formats */
+
+/* ASCII: default */
+#define ASN1_GEN_FORMAT_ASCII   1
+/* UTF8 */
+#define ASN1_GEN_FORMAT_UTF8    2
+/* Hex */
+#define ASN1_GEN_FORMAT_HEX     3
+/* List of bits */
+#define ASN1_GEN_FORMAT_BITLIST 4
+
+struct tag_name_st {
+    const char *strnam;
+    int len;
+    int tag;
+};
+
+typedef struct {
+    int exp_tag;
+    int exp_class;
+    int exp_constructed;
+    int exp_pad;
+    long exp_len;
+} tag_exp_type;
+
+typedef struct {
+    int imp_tag;
+    int imp_class;
+    int utype;
+    int format;
+    const char *str;
+    tag_exp_type exp_list[ASN1_FLAG_EXP_MAX];
+    int exp_count;
+} tag_exp_arg;
+
+static ASN1_TYPE *generate_v3(const char *str, X509V3_CTX *cnf, int depth,
+                              int *perr);
+static int bitstr_cb(const char *elem, int len, void *bitstr);
+static int asn1_cb(const char *elem, int len, void *bitstr);
+static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class,
+                      int exp_constructed, int exp_pad, int imp_ok);
+static int parse_tagging(const char *vstart, int vlen, int *ptag,
+                         int *pclass);
+static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf,
+                             int depth, int *perr);
+static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype);
+static int asn1_str2tag(const char *tagstr, int len);
+
+ASN1_TYPE *ASN1_generate_nconf(const char *str, CONF *nconf)
+{
+    X509V3_CTX cnf;
+
+    if (!nconf)
+        return ASN1_generate_v3(str, NULL);
+
+    X509V3_set_nconf(&cnf, nconf);
+    return ASN1_generate_v3(str, &cnf);
+}
+
+ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf)
+{
+    int err = 0;
+    ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err);
+    if (err)
+        ASN1err(ASN1_F_ASN1_GENERATE_V3, err);
+    return ret;
+}
+
+static ASN1_TYPE *generate_v3(const char *str, X509V3_CTX *cnf, int depth,
+                              int *perr)
+{
+    ASN1_TYPE *ret;
+    tag_exp_arg asn1_tags;
+    tag_exp_type *etmp;
+
+    int i, len;
+
+    unsigned char *orig_der = NULL, *new_der = NULL;
+    const unsigned char *cpy_start;
+    unsigned char *p;
+    const unsigned char *cp;
+    int cpy_len;
+    long hdr_len = 0;
+    int hdr_constructed = 0, hdr_tag, hdr_class;
+    int r;
+
+    asn1_tags.imp_tag = -1;
+    asn1_tags.imp_class = -1;
+    asn1_tags.format = ASN1_GEN_FORMAT_ASCII;
+    asn1_tags.exp_count = 0;
+    if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) {
+        *perr = ASN1_R_UNKNOWN_TAG;
+        return NULL;
+    }
+
+    if ((asn1_tags.utype == V_ASN1_SEQUENCE)
+        || (asn1_tags.utype == V_ASN1_SET)) {
+        if (!cnf) {
+            *perr = ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG;
+            return NULL;
+        }
+        if (depth >= ASN1_GEN_SEQ_MAX_DEPTH) {
+            *perr = ASN1_R_ILLEGAL_NESTED_TAGGING;
+            return NULL;
+        }
+        ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf, depth, perr);
+    } else
+        ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype);
+
+    if (!ret)
+        return NULL;
+
+    /* If no tagging return base type */
+    if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0))
+        return ret;
+
+    /* Generate the encoding */
+    cpy_len = i2d_ASN1_TYPE(ret, &orig_der);
+    ASN1_TYPE_free(ret);
+    ret = NULL;
+    /* Set point to start copying for modified encoding */
+    cpy_start = orig_der;
+
+    /* Do we need IMPLICIT tagging? */
+    if (asn1_tags.imp_tag != -1) {
+        /* If IMPLICIT we will replace the underlying tag */
+        /* Skip existing tag+len */
+        r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class,
+                            cpy_len);
+        if (r & 0x80)
+            goto err;
+        /* Update copy length */
+        cpy_len -= cpy_start - orig_der;
+        /*
+         * For IMPLICIT tagging the length should match the original length
+         * and constructed flag should be consistent.
+         */
+        if (r & 0x1) {
+            /* Indefinite length constructed */
+            hdr_constructed = 2;
+            hdr_len = 0;
+        } else
+            /* Just retain constructed flag */
+            hdr_constructed = r & V_ASN1_CONSTRUCTED;
+        /*
+         * Work out new length with IMPLICIT tag: ignore constructed because
+         * it will mess up if indefinite length
+         */
+        len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag);
+    } else
+        len = cpy_len;
+
+    /* Work out length in any EXPLICIT, starting from end */
+
+    for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1;
+         i < asn1_tags.exp_count; i++, etmp--) {
+        /* Content length: number of content octets + any padding */
+        len += etmp->exp_pad;
+        etmp->exp_len = len;
+        /* Total object length: length including new header */
+        len = ASN1_object_size(0, len, etmp->exp_tag);
+    }
+
+    /* Allocate buffer for new encoding */
+
+    new_der = OPENSSL_malloc(len);
+    if (new_der == NULL)
+        goto err;
+
+    /* Generate tagged encoding */
+
+    p = new_der;
+
+    /* Output explicit tags first */
+
+    for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count;
+         i++, etmp++) {
+        ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len,
+                        etmp->exp_tag, etmp->exp_class);
+        if (etmp->exp_pad)
+            *p++ = 0;
+    }
+
+    /* If IMPLICIT, output tag */
+
+    if (asn1_tags.imp_tag != -1) {
+        if (asn1_tags.imp_class == V_ASN1_UNIVERSAL
+            && (asn1_tags.imp_tag == V_ASN1_SEQUENCE
+                || asn1_tags.imp_tag == V_ASN1_SET))
+            hdr_constructed = V_ASN1_CONSTRUCTED;
+        ASN1_put_object(&p, hdr_constructed, hdr_len,
+                        asn1_tags.imp_tag, asn1_tags.imp_class);
+    }
+
+    /* Copy across original encoding */
+    memcpy(p, cpy_start, cpy_len);
+
+    cp = new_der;
+
+    /* Obtain new ASN1_TYPE structure */
+    ret = d2i_ASN1_TYPE(NULL, &cp, len);
+
+ err:
+    OPENSSL_free(orig_der);
+    OPENSSL_free(new_der);
+
+    return ret;
+
+}
+
+static int asn1_cb(const char *elem, int len, void *bitstr)
+{
+    tag_exp_arg *arg = bitstr;
+    int i;
+    int utype;
+    int vlen = 0;
+    const char *p, *vstart = NULL;
+
+    int tmp_tag, tmp_class;
+
+    if (elem == NULL)
+        return -1;
+
+    for (i = 0, p = elem; i < len; p++, i++) {
+        /* Look for the ':' in name value pairs */
+        if (*p == ':') {
+            vstart = p + 1;
+            vlen = len - (vstart - elem);
+            len = p - elem;
+            break;
+        }
+    }
+
+    utype = asn1_str2tag(elem, len);
+
+    if (utype == -1) {
+        ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG);
+        ERR_add_error_data(2, "tag=", elem);
+        return -1;
+    }
+
+    /* If this is not a modifier mark end of string and exit */
+    if (!(utype & ASN1_GEN_FLAG)) {
+        arg->utype = utype;
+        arg->str = vstart;
+        /* If no value and not end of string, error */
+        if (!vstart && elem[len]) {
+            ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE);
+            return -1;
+        }
+        return 0;
+    }
+
+    switch (utype) {
+
+    case ASN1_GEN_FLAG_IMP:
+        /* Check for illegal multiple IMPLICIT tagging */
+        if (arg->imp_tag != -1) {
+            ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING);
+            return -1;
+        }
+        if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class))
+            return -1;
+        break;
+
+    case ASN1_GEN_FLAG_EXP:
+
+        if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class))
+            return -1;
+        if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0))
+            return -1;
+        break;
+
+    case ASN1_GEN_FLAG_SEQWRAP:
+        if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1))
+            return -1;
+        break;
+
+    case ASN1_GEN_FLAG_SETWRAP:
+        if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1))
+            return -1;
+        break;
+
+    case ASN1_GEN_FLAG_BITWRAP:
+        if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1))
+            return -1;
+        break;
+
+    case ASN1_GEN_FLAG_OCTWRAP:
+        if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1))
+            return -1;
+        break;
+
+    case ASN1_GEN_FLAG_FORMAT:
+        if (!vstart) {
+            ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT);
+            return -1;
+        }
+        if (strncmp(vstart, "ASCII", 5) == 0)
+            arg->format = ASN1_GEN_FORMAT_ASCII;
+        else if (strncmp(vstart, "UTF8", 4) == 0)
+            arg->format = ASN1_GEN_FORMAT_UTF8;
+        else if (strncmp(vstart, "HEX", 3) == 0)
+            arg->format = ASN1_GEN_FORMAT_HEX;
+        else if (strncmp(vstart, "BITLIST", 7) == 0)
+            arg->format = ASN1_GEN_FORMAT_BITLIST;
+        else {
+            ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT);
+            return -1;
+        }
+        break;
+
+    }
+
+    return 1;
+
+}
+
+static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
+{
+    char erch[2];
+    long tag_num;
+    char *eptr;
+    if (!vstart)
+        return 0;
+    tag_num = strtoul(vstart, &eptr, 10);
+    /* Check we haven't gone past max length: should be impossible */
+    if (eptr && *eptr && (eptr > vstart + vlen))
+        return 0;
+    if (tag_num < 0) {
+        ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER);
+        return 0;
+    }
+    *ptag = tag_num;
+    /* If we have non numeric characters, parse them */
+    if (eptr)
+        vlen -= eptr - vstart;
+    else
+        vlen = 0;
+    if (vlen) {
+        switch (*eptr) {
+
+        case 'U':
+            *pclass = V_ASN1_UNIVERSAL;
+            break;
+
+        case 'A':
+            *pclass = V_ASN1_APPLICATION;
+            break;
+
+        case 'P':
+            *pclass = V_ASN1_PRIVATE;
+            break;
+
+        case 'C':
+            *pclass = V_ASN1_CONTEXT_SPECIFIC;
+            break;
+
+        default:
+            erch[0] = *eptr;
+            erch[1] = 0;
+            ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER);
+            ERR_add_error_data(2, "Char=", erch);
+            return 0;
+
+        }
+    } else
+        *pclass = V_ASN1_CONTEXT_SPECIFIC;
+
+    return 1;
+
+}
+
+/* Handle multiple types: SET and SEQUENCE */
+
+static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf,
+                             int depth, int *perr)
+{
+    ASN1_TYPE *ret = NULL;
+    STACK_OF(ASN1_TYPE) *sk = NULL;
+    STACK_OF(CONF_VALUE) *sect = NULL;
+    unsigned char *der = NULL;
+    int derlen;
+    int i;
+    sk = sk_ASN1_TYPE_new_null();
+    if (!sk)
+        goto bad;
+    if (section) {
+        if (!cnf)
+            goto bad;
+        sect = X509V3_get_section(cnf, (char *)section);
+        if (!sect)
+            goto bad;
+        for (i = 0; i < sk_CONF_VALUE_num(sect); i++) {
+            ASN1_TYPE *typ =
+                generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf,
+                            depth + 1, perr);
+            if (!typ)
+                goto bad;
+            if (!sk_ASN1_TYPE_push(sk, typ))
+                goto bad;
+        }
+    }
+
+    /*
+     * Now we has a STACK of the components, convert to the correct form
+     */
+
+    if (utype == V_ASN1_SET)
+        derlen = i2d_ASN1_SET_ANY(sk, &der);
+    else
+        derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);
+
+    if (derlen < 0)
+        goto bad;
+    if ((ret = ASN1_TYPE_new()) == NULL)
+        goto bad;
+    if ((ret->value.asn1_string = ASN1_STRING_type_new(utype)) == NULL)
+        goto bad;
+
+    ret->type = utype;
+    ret->value.asn1_string->data = der;
+    ret->value.asn1_string->length = derlen;
+
+    der = NULL;
+
+ bad:
+
+    OPENSSL_free(der);
+
+    sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
+    X509V3_section_free(cnf, sect);
+
+    return ret;
+}
+
+static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class,
+                      int exp_constructed, int exp_pad, int imp_ok)
+{
+    tag_exp_type *exp_tmp;
+    /* Can only have IMPLICIT if permitted */
+    if ((arg->imp_tag != -1) && !imp_ok) {
+        ASN1err(ASN1_F_APPEND_EXP, ASN1_R_ILLEGAL_IMPLICIT_TAG);
+        return 0;
+    }
+
+    if (arg->exp_count == ASN1_FLAG_EXP_MAX) {
+        ASN1err(ASN1_F_APPEND_EXP, ASN1_R_DEPTH_EXCEEDED);
+        return 0;
+    }
+
+    exp_tmp = &arg->exp_list[arg->exp_count++];
+
+    /*
+     * If IMPLICIT set tag to implicit value then reset implicit tag since it
+     * has been used.
+     */
+    if (arg->imp_tag != -1) {
+        exp_tmp->exp_tag = arg->imp_tag;
+        exp_tmp->exp_class = arg->imp_class;
+        arg->imp_tag = -1;
+        arg->imp_class = -1;
+    } else {
+        exp_tmp->exp_tag = exp_tag;
+        exp_tmp->exp_class = exp_class;
+    }
+    exp_tmp->exp_constructed = exp_constructed;
+    exp_tmp->exp_pad = exp_pad;
+
+    return 1;
+}
+
+static int asn1_str2tag(const char *tagstr, int len)
+{
+    unsigned int i;
+    static const struct tag_name_st *tntmp, tnst[] = {
+        ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN),
+        ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN),
+        ASN1_GEN_STR("NULL", V_ASN1_NULL),
+        ASN1_GEN_STR("INT", V_ASN1_INTEGER),
+        ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER),
+        ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED),
+        ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED),
+        ASN1_GEN_STR("OID", V_ASN1_OBJECT),
+        ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT),
+        ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME),
+        ASN1_GEN_STR("UTC", V_ASN1_UTCTIME),
+        ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME),
+        ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME),
+        ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING),
+        ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING),
+        ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING),
+        ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING),
+        ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING),
+        ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING),
+        ASN1_GEN_STR("IA5", V_ASN1_IA5STRING),
+        ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING),
+        ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING),
+        ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING),
+        ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING),
+        ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING),
+        ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING),
+        ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING),
+        ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING),
+        ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING),
+        ASN1_GEN_STR("T61", V_ASN1_T61STRING),
+        ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING),
+        ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING),
+        ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING),
+        ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING),
+        ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING),
+        ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING),
+
+        /* Special cases */
+        ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE),
+        ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE),
+        ASN1_GEN_STR("SET", V_ASN1_SET),
+        /* type modifiers */
+        /* Explicit tag */
+        ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP),
+        ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP),
+        /* Implicit tag */
+        ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP),
+        ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP),
+        /* OCTET STRING wrapper */
+        ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP),
+        /* SEQUENCE wrapper */
+        ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP),
+        /* SET wrapper */
+        ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP),
+        /* BIT STRING wrapper */
+        ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP),
+        ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT),
+        ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT),
+    };
+
+    if (len == -1)
+        len = strlen(tagstr);
+
+    tntmp = tnst;
+    for (i = 0; i < OSSL_NELEM(tnst); i++, tntmp++) {
+        if ((len == tntmp->len) && (strncmp(tntmp->strnam, tagstr, len) == 0))
+            return tntmp->tag;
+    }
+
+    return -1;
+}
+
+static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
+{
+    ASN1_TYPE *atmp = NULL;
+    CONF_VALUE vtmp;
+    unsigned char *rdata;
+    long rdlen;
+    int no_unused = 1;
+
+    if ((atmp = ASN1_TYPE_new()) == NULL) {
+        ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    if (!str)
+        str = "";
+
+    switch (utype) {
+
+    case V_ASN1_NULL:
+        if (str && *str) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE);
+            goto bad_form;
+        }
+        break;
+
+    case V_ASN1_BOOLEAN:
+        if (format != ASN1_GEN_FORMAT_ASCII) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT);
+            goto bad_form;
+        }
+        vtmp.name = NULL;
+        vtmp.section = NULL;
+        vtmp.value = (char *)str;
+        if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN);
+            goto bad_str;
+        }
+        break;
+
+    case V_ASN1_INTEGER:
+    case V_ASN1_ENUMERATED:
+        if (format != ASN1_GEN_FORMAT_ASCII) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
+            goto bad_form;
+        }
+        if ((atmp->value.integer
+                    = s2i_ASN1_INTEGER(NULL, str)) == NULL) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER);
+            goto bad_str;
+        }
+        break;
+
+    case V_ASN1_OBJECT:
+        if (format != ASN1_GEN_FORMAT_ASCII) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
+            goto bad_form;
+        }
+        if ((atmp->value.object = OBJ_txt2obj(str, 0)) == NULL) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT);
+            goto bad_str;
+        }
+        break;
+
+    case V_ASN1_UTCTIME:
+    case V_ASN1_GENERALIZEDTIME:
+        if (format != ASN1_GEN_FORMAT_ASCII) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT);
+            goto bad_form;
+        }
+        if ((atmp->value.asn1_string = ASN1_STRING_new()) == NULL) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+            goto bad_str;
+        }
+        if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+            goto bad_str;
+        }
+        atmp->value.asn1_string->type = utype;
+        if (!ASN1_TIME_check(atmp->value.asn1_string)) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE);
+            goto bad_str;
+        }
+
+        break;
+
+    case V_ASN1_BMPSTRING:
+    case V_ASN1_PRINTABLESTRING:
+    case V_ASN1_IA5STRING:
+    case V_ASN1_T61STRING:
+    case V_ASN1_UTF8STRING:
+    case V_ASN1_VISIBLESTRING:
+    case V_ASN1_UNIVERSALSTRING:
+    case V_ASN1_GENERALSTRING:
+    case V_ASN1_NUMERICSTRING:
+        if (format == ASN1_GEN_FORMAT_ASCII)
+            format = MBSTRING_ASC;
+        else if (format == ASN1_GEN_FORMAT_UTF8)
+            format = MBSTRING_UTF8;
+        else {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT);
+            goto bad_form;
+        }
+
+        if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str,
+                               -1, format, ASN1_tag2bit(utype)) <= 0) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+            goto bad_str;
+        }
+
+        break;
+
+    case V_ASN1_BIT_STRING:
+    case V_ASN1_OCTET_STRING:
+        if ((atmp->value.asn1_string = ASN1_STRING_new()) == NULL) {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
+            goto bad_form;
+        }
+
+        if (format == ASN1_GEN_FORMAT_HEX) {
+            if ((rdata = OPENSSL_hexstr2buf(str, &rdlen)) == NULL) {
+                ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX);
+                goto bad_str;
+            }
+            atmp->value.asn1_string->data = rdata;
+            atmp->value.asn1_string->length = rdlen;
+            atmp->value.asn1_string->type = utype;
+        } else if (format == ASN1_GEN_FORMAT_ASCII)
+            ASN1_STRING_set(atmp->value.asn1_string, str, -1);
+        else if ((format == ASN1_GEN_FORMAT_BITLIST)
+                 && (utype == V_ASN1_BIT_STRING)) {
+            if (!CONF_parse_list
+                (str, ',', 1, bitstr_cb, atmp->value.bit_string)) {
+                ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR);
+                goto bad_str;
+            }
+            no_unused = 0;
+
+        } else {
+            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
+            goto bad_form;
+        }
+
+        if ((utype == V_ASN1_BIT_STRING) && no_unused) {
+            atmp->value.asn1_string->flags
+                &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+            atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+        }
+
+        break;
+
+    default:
+        ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE);
+        goto bad_str;
+    }
+
+    atmp->type = utype;
+    return atmp;
+
+ bad_str:
+    ERR_add_error_data(2, "string=", str);
+ bad_form:
+
+    ASN1_TYPE_free(atmp);
+    return NULL;
+
+}
+
+static int bitstr_cb(const char *elem, int len, void *bitstr)
+{
+    long bitnum;
+    char *eptr;
+    if (!elem)
+        return 0;
+    bitnum = strtoul(elem, &eptr, 10);
+    if (eptr && *eptr && (eptr != elem + len))
+        return 0;
+    if (bitnum < 0) {
+        ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER);
+        return 0;
+    }
+    if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) {
+        ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    return 1;
+}
+
+static int mask_cb(const char *elem, int len, void *arg)
+{
+    unsigned long *pmask = arg, tmpmask;
+    int tag;
+    if (elem == NULL)
+        return 0;
+    if ((len == 3) && (strncmp(elem, "DIR", 3) == 0)) {
+        *pmask |= B_ASN1_DIRECTORYSTRING;
+        return 1;
+    }
+    tag = asn1_str2tag(elem, len);
+    if (!tag || (tag & ASN1_GEN_FLAG))
+        return 0;
+    tmpmask = ASN1_tag2bit(tag);
+    if (!tmpmask)
+        return 0;
+    *pmask |= tmpmask;
+    return 1;
+}
+
+int ASN1_str2mask(const char *str, unsigned long *pmask)
+{
+    *pmask = 0;
+    return CONF_parse_list(str, '|', 1, mask_cb, pmask);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn1_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn1_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn1_lib.c	(revision 331)
@@ -0,0 +1,384 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <limits.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include "asn1_locl.h"
+
+static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
+                           long max);
+static void asn1_put_length(unsigned char **pp, int length);
+
+static int _asn1_check_infinite_end(const unsigned char **p, long len)
+{
+    /*
+     * If there is 0 or 1 byte left, the length check should pick things up
+     */
+    if (len <= 0)
+        return (1);
+    else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) {
+        (*p) += 2;
+        return (1);
+    }
+    return (0);
+}
+
+int ASN1_check_infinite_end(unsigned char **p, long len)
+{
+    return _asn1_check_infinite_end((const unsigned char **)p, len);
+}
+
+int ASN1_const_check_infinite_end(const unsigned char **p, long len)
+{
+    return _asn1_check_infinite_end(p, len);
+}
+
+int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
+                    int *pclass, long omax)
+{
+    int i, ret;
+    long l;
+    const unsigned char *p = *pp;
+    int tag, xclass, inf;
+    long max = omax;
+
+    if (!max)
+        goto err;
+    ret = (*p & V_ASN1_CONSTRUCTED);
+    xclass = (*p & V_ASN1_PRIVATE);
+    i = *p & V_ASN1_PRIMITIVE_TAG;
+    if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */
+        p++;
+        if (--max == 0)
+            goto err;
+        l = 0;
+        while (*p & 0x80) {
+            l <<= 7L;
+            l |= *(p++) & 0x7f;
+            if (--max == 0)
+                goto err;
+            if (l > (INT_MAX >> 7L))
+                goto err;
+        }
+        l <<= 7L;
+        l |= *(p++) & 0x7f;
+        tag = (int)l;
+        if (--max == 0)
+            goto err;
+    } else {
+        tag = i;
+        p++;
+        if (--max == 0)
+            goto err;
+    }
+    *ptag = tag;
+    *pclass = xclass;
+    if (!asn1_get_length(&p, &inf, plength, max))
+        goto err;
+
+    if (inf && !(ret & V_ASN1_CONSTRUCTED))
+        goto err;
+
+    if (*plength > (omax - (p - *pp))) {
+        ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_TOO_LONG);
+        /*
+         * Set this so that even if things are not long enough the values are
+         * set correctly
+         */
+        ret |= 0x80;
+    }
+    *pp = p;
+    return (ret | inf);
+ err:
+    ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_HEADER_TOO_LONG);
+    return (0x80);
+}
+
+static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
+                           long max)
+{
+    const unsigned char *p = *pp;
+    unsigned long ret = 0;
+    unsigned long i;
+
+    if (max-- < 1)
+        return 0;
+    if (*p == 0x80) {
+        *inf = 1;
+        ret = 0;
+        p++;
+    } else {
+        *inf = 0;
+        i = *p & 0x7f;
+        if (*(p++) & 0x80) {
+            if (max < (long)i + 1)
+                return 0;
+            /* Skip leading zeroes */
+            while (i && *p == 0) {
+                p++;
+                i--;
+            }
+            if (i > sizeof(long))
+                return 0;
+            while (i-- > 0) {
+                ret <<= 8L;
+                ret |= *(p++);
+            }
+        } else
+            ret = i;
+    }
+    if (ret > LONG_MAX)
+        return 0;
+    *pp = p;
+    *rl = (long)ret;
+    return 1;
+}
+
+/*
+ * class 0 is constructed constructed == 2 for indefinite length constructed
+ */
+void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
+                     int xclass)
+{
+    unsigned char *p = *pp;
+    int i, ttag;
+
+    i = (constructed) ? V_ASN1_CONSTRUCTED : 0;
+    i |= (xclass & V_ASN1_PRIVATE);
+    if (tag < 31)
+        *(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG);
+    else {
+        *(p++) = i | V_ASN1_PRIMITIVE_TAG;
+        for (i = 0, ttag = tag; ttag > 0; i++)
+            ttag >>= 7;
+        ttag = i;
+        while (i-- > 0) {
+            p[i] = tag & 0x7f;
+            if (i != (ttag - 1))
+                p[i] |= 0x80;
+            tag >>= 7;
+        }
+        p += ttag;
+    }
+    if (constructed == 2)
+        *(p++) = 0x80;
+    else
+        asn1_put_length(&p, length);
+    *pp = p;
+}
+
+int ASN1_put_eoc(unsigned char **pp)
+{
+    unsigned char *p = *pp;
+    *p++ = 0;
+    *p++ = 0;
+    *pp = p;
+    return 2;
+}
+
+static void asn1_put_length(unsigned char **pp, int length)
+{
+    unsigned char *p = *pp;
+    int i, l;
+    if (length <= 127)
+        *(p++) = (unsigned char)length;
+    else {
+        l = length;
+        for (i = 0; l > 0; i++)
+            l >>= 8;
+        *(p++) = i | 0x80;
+        l = i;
+        while (i-- > 0) {
+            p[i] = length & 0xff;
+            length >>= 8;
+        }
+        p += l;
+    }
+    *pp = p;
+}
+
+int ASN1_object_size(int constructed, int length, int tag)
+{
+    int ret = 1;
+    if (length < 0)
+        return -1;
+    if (tag >= 31) {
+        while (tag > 0) {
+            tag >>= 7;
+            ret++;
+        }
+    }
+    if (constructed == 2) {
+        ret += 3;
+    } else {
+        ret++;
+        if (length > 127) {
+            int tmplen = length;
+            while (tmplen > 0) {
+                tmplen >>= 8;
+                ret++;
+            }
+        }
+    }
+    if (ret >= INT_MAX - length)
+        return -1;
+    return ret + length;
+}
+
+int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
+{
+    if (str == NULL)
+        return 0;
+    dst->type = str->type;
+    if (!ASN1_STRING_set(dst, str->data, str->length))
+        return 0;
+    /* Copy flags but preserve embed value */
+    dst->flags &= ASN1_STRING_FLAG_EMBED;
+    dst->flags |= str->flags & ~ASN1_STRING_FLAG_EMBED;
+    return 1;
+}
+
+ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
+{
+    ASN1_STRING *ret;
+    if (!str)
+        return NULL;
+    ret = ASN1_STRING_new();
+    if (ret == NULL)
+        return NULL;
+    if (!ASN1_STRING_copy(ret, str)) {
+        ASN1_STRING_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
+{
+    unsigned char *c;
+    const char *data = _data;
+
+    if (len < 0) {
+        if (data == NULL)
+            return (0);
+        else
+            len = strlen(data);
+    }
+    if ((str->length <= len) || (str->data == NULL)) {
+        c = str->data;
+        str->data = OPENSSL_realloc(c, len + 1);
+        if (str->data == NULL) {
+            ASN1err(ASN1_F_ASN1_STRING_SET, ERR_R_MALLOC_FAILURE);
+            str->data = c;
+            return (0);
+        }
+    }
+    str->length = len;
+    if (data != NULL) {
+        memcpy(str->data, data, len);
+        /* an allowance for strings :-) */
+        str->data[len] = '\0';
+    }
+    return (1);
+}
+
+void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
+{
+    OPENSSL_free(str->data);
+    str->data = data;
+    str->length = len;
+}
+
+ASN1_STRING *ASN1_STRING_new(void)
+{
+    return (ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
+}
+
+ASN1_STRING *ASN1_STRING_type_new(int type)
+{
+    ASN1_STRING *ret;
+
+    ret = OPENSSL_zalloc(sizeof(*ret));
+    if (ret == NULL) {
+        ASN1err(ASN1_F_ASN1_STRING_TYPE_NEW, ERR_R_MALLOC_FAILURE);
+        return (NULL);
+    }
+    ret->type = type;
+    return (ret);
+}
+
+void asn1_string_embed_free(ASN1_STRING *a, int embed)
+{
+    if (a == NULL)
+        return;
+    if (!(a->flags & ASN1_STRING_FLAG_NDEF))
+        OPENSSL_free(a->data);
+    if (embed == 0)
+        OPENSSL_free(a);
+}
+
+void ASN1_STRING_free(ASN1_STRING *a)
+{
+    if (a == NULL)
+        return;
+    asn1_string_embed_free(a, a->flags & ASN1_STRING_FLAG_EMBED);
+}
+
+void ASN1_STRING_clear_free(ASN1_STRING *a)
+{
+    if (a == NULL)
+        return;
+    if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
+        OPENSSL_cleanse(a->data, a->length);
+    ASN1_STRING_free(a);
+}
+
+int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
+{
+    int i;
+
+    i = (a->length - b->length);
+    if (i == 0) {
+        i = memcmp(a->data, b->data, a->length);
+        if (i == 0)
+            return (a->type - b->type);
+        else
+            return (i);
+    } else
+        return (i);
+}
+
+int ASN1_STRING_length(const ASN1_STRING *x)
+{
+    return x->length;
+}
+
+void ASN1_STRING_length_set(ASN1_STRING *x, int len)
+{
+    x->length = len;
+}
+
+int ASN1_STRING_type(const ASN1_STRING *x)
+{
+    return x->type;
+}
+
+const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x)
+{
+    return x->data;
+}
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+unsigned char *ASN1_STRING_data(ASN1_STRING *x)
+{
+    return x->data;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn1_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn1_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn1_locl.h	(revision 331)
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2005-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
+ */
+
+/* Internal ASN1 structures and functions: not for application use */
+
+int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d);
+int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d);
+
+/* ASN1 scan context structure */
+
+struct asn1_sctx_st {
+    /* The ASN1_ITEM associated with this field */
+    const ASN1_ITEM *it;
+    /* If ASN1_TEMPLATE associated with this field */
+    const ASN1_TEMPLATE *tt;
+    /* Various flags associated with field and context */
+    unsigned long flags;
+    /* If SEQUENCE OF or SET OF, field index */
+    int skidx;
+    /* ASN1 depth of field */
+    int depth;
+    /* Structure and field name */
+    const char *sname, *fname;
+    /* If a primitive type the type of underlying field */
+    int prim_type;
+    /* The field value itself */
+    ASN1_VALUE **field;
+    /* Callback to pass information to */
+    int (*scan_cb) (ASN1_SCTX *ctx);
+    /* Context specific application data */
+    void *app_data;
+} /* ASN1_SCTX */ ;
+
+typedef struct mime_param_st MIME_PARAM;
+DEFINE_STACK_OF(MIME_PARAM)
+typedef struct mime_header_st MIME_HEADER;
+DEFINE_STACK_OF(MIME_HEADER)
+
+/* Month values for printing out times */
+extern const char *_asn1_mon[12];
+
+void asn1_string_embed_free(ASN1_STRING *a, int embed);
+
+int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_set_choice_selector(ASN1_VALUE **pval, int value,
+                             const ASN1_ITEM *it);
+
+ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+
+const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
+                                 int nullerr);
+
+int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);
+
+void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
+void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
+                     const ASN1_ITEM *it);
+int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
+                  const ASN1_ITEM *it);
+
+void asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed);
+void asn1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+
+ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
+                             long length);
+int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp);
+ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
+                                     const unsigned char **pp, long length);
+int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp);
+ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
+                               long length);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn1_par.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn1_par.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn1_par.c	(revision 331)
@@ -0,0 +1,375 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/asn1.h>
+
+#ifndef ASN1_PARSE_MAXDEPTH
+#define ASN1_PARSE_MAXDEPTH 128
+#endif
+
+static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
+                           int indent);
+static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
+                       int offset, int depth, int indent, int dump);
+static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
+                           int indent)
+{
+    static const char fmt[] = "%-18s";
+    char str[128];
+    const char *p;
+
+    if (constructed & V_ASN1_CONSTRUCTED)
+        p = "cons: ";
+    else
+        p = "prim: ";
+    if (BIO_write(bp, p, 6) < 6)
+        goto err;
+    BIO_indent(bp, indent, 128);
+
+    p = str;
+    if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
+        BIO_snprintf(str, sizeof str, "priv [ %d ] ", tag);
+    else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
+        BIO_snprintf(str, sizeof str, "cont [ %d ]", tag);
+    else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
+        BIO_snprintf(str, sizeof str, "appl [ %d ]", tag);
+    else if (tag > 30)
+        BIO_snprintf(str, sizeof str, "<ASN1 %d>", tag);
+    else
+        p = ASN1_tag2str(tag);
+
+    if (BIO_printf(bp, fmt, p) <= 0)
+        goto err;
+    return (1);
+ err:
+    return (0);
+}
+
+int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent)
+{
+    return (asn1_parse2(bp, &pp, len, 0, 0, indent, 0));
+}
+
+int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent,
+                    int dump)
+{
+    return (asn1_parse2(bp, &pp, len, 0, 0, indent, dump));
+}
+
+static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
+                       int offset, int depth, int indent, int dump)
+{
+    const unsigned char *p, *ep, *tot, *op, *opp;
+    long len;
+    int tag, xclass, ret = 0;
+    int nl, hl, j, r;
+    ASN1_OBJECT *o = NULL;
+    ASN1_OCTET_STRING *os = NULL;
+    /* ASN1_BMPSTRING *bmp=NULL; */
+    int dump_indent, dump_cont = 0;
+
+    if (depth > ASN1_PARSE_MAXDEPTH) {
+            BIO_puts(bp, "BAD RECURSION DEPTH\n");
+            return 0;
+    }
+
+    dump_indent = 6;            /* Because we know BIO_dump_indent() */
+    p = *pp;
+    tot = p + length;
+    while (length > 0) {
+        op = p;
+        j = ASN1_get_object(&p, &len, &tag, &xclass, length);
+        if (j & 0x80) {
+            if (BIO_write(bp, "Error in encoding\n", 18) <= 0)
+                goto end;
+            ret = 0;
+            goto end;
+        }
+        hl = (p - op);
+        length -= hl;
+        /*
+         * if j == 0x21 it is a constructed indefinite length object
+         */
+        if (BIO_printf(bp, "%5ld:", (long)offset + (long)(op - *pp))
+            <= 0)
+            goto end;
+
+        if (j != (V_ASN1_CONSTRUCTED | 1)) {
+            if (BIO_printf(bp, "d=%-2d hl=%ld l=%4ld ",
+                           depth, (long)hl, len) <= 0)
+                goto end;
+        } else {
+            if (BIO_printf(bp, "d=%-2d hl=%ld l=inf  ", depth, (long)hl) <= 0)
+                goto end;
+        }
+        if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0))
+            goto end;
+        if (j & V_ASN1_CONSTRUCTED) {
+            const unsigned char *sp = p;
+
+            ep = p + len;
+            if (BIO_write(bp, "\n", 1) <= 0)
+                goto end;
+            if (len > length) {
+                BIO_printf(bp, "length is greater than %ld\n", length);
+                ret = 0;
+                goto end;
+            }
+            if ((j == 0x21) && (len == 0)) {
+                for (;;) {
+                    r = asn1_parse2(bp, &p, (long)(tot - p),
+                                    offset + (p - *pp), depth + 1,
+                                    indent, dump);
+                    if (r == 0) {
+                        ret = 0;
+                        goto end;
+                    }
+                    if ((r == 2) || (p >= tot)) {
+                        len = p - sp;
+                        break;
+                    }
+                }
+            } else {
+                long tmp = len;
+
+                while (p < ep) {
+                    sp = p;
+                    r = asn1_parse2(bp, &p, tmp,
+                                    offset + (p - *pp), depth + 1,
+                                    indent, dump);
+                    if (r == 0) {
+                        ret = 0;
+                        goto end;
+                    }
+                    tmp -= p - sp;
+                }
+            }
+        } else if (xclass != 0) {
+            p += len;
+            if (BIO_write(bp, "\n", 1) <= 0)
+                goto end;
+        } else {
+            nl = 0;
+            if ((tag == V_ASN1_PRINTABLESTRING) ||
+                (tag == V_ASN1_T61STRING) ||
+                (tag == V_ASN1_IA5STRING) ||
+                (tag == V_ASN1_VISIBLESTRING) ||
+                (tag == V_ASN1_NUMERICSTRING) ||
+                (tag == V_ASN1_UTF8STRING) ||
+                (tag == V_ASN1_UTCTIME) || (tag == V_ASN1_GENERALIZEDTIME)) {
+                if (BIO_write(bp, ":", 1) <= 0)
+                    goto end;
+                if ((len > 0) && BIO_write(bp, (const char *)p, (int)len)
+                    != (int)len)
+                    goto end;
+            } else if (tag == V_ASN1_OBJECT) {
+                opp = op;
+                if (d2i_ASN1_OBJECT(&o, &opp, len + hl) != NULL) {
+                    if (BIO_write(bp, ":", 1) <= 0)
+                        goto end;
+                    i2a_ASN1_OBJECT(bp, o);
+                } else {
+                    if (BIO_puts(bp, ":BAD OBJECT") <= 0)
+                        goto end;
+                    dump_cont = 1;
+                }
+            } else if (tag == V_ASN1_BOOLEAN) {
+                if (len != 1) {
+                    if (BIO_puts(bp, ":BAD BOOLEAN") <= 0)
+                        goto end;
+                    dump_cont = 1;
+                }
+                if (len > 0)
+                    BIO_printf(bp, ":%u", p[0]);
+            } else if (tag == V_ASN1_BMPSTRING) {
+                /* do the BMP thang */
+            } else if (tag == V_ASN1_OCTET_STRING) {
+                int i, printable = 1;
+
+                opp = op;
+                os = d2i_ASN1_OCTET_STRING(NULL, &opp, len + hl);
+                if (os != NULL && os->length > 0) {
+                    opp = os->data;
+                    /*
+                     * testing whether the octet string is printable
+                     */
+                    for (i = 0; i < os->length; i++) {
+                        if (((opp[i] < ' ') &&
+                             (opp[i] != '\n') &&
+                             (opp[i] != '\r') &&
+                             (opp[i] != '\t')) || (opp[i] > '~')) {
+                            printable = 0;
+                            break;
+                        }
+                    }
+                    if (printable)
+                        /* printable string */
+                    {
+                        if (BIO_write(bp, ":", 1) <= 0)
+                            goto end;
+                        if (BIO_write(bp, (const char *)opp, os->length) <= 0)
+                            goto end;
+                    } else if (!dump)
+                        /*
+                         * not printable => print octet string as hex dump
+                         */
+                    {
+                        if (BIO_write(bp, "[HEX DUMP]:", 11) <= 0)
+                            goto end;
+                        for (i = 0; i < os->length; i++) {
+                            if (BIO_printf(bp, "%02X", opp[i]) <= 0)
+                                goto end;
+                        }
+                    } else
+                        /* print the normal dump */
+                    {
+                        if (!nl) {
+                            if (BIO_write(bp, "\n", 1) <= 0)
+                                goto end;
+                        }
+                        if (BIO_dump_indent(bp,
+                                            (const char *)opp,
+                                            ((dump == -1 || dump >
+                                              os->
+                                              length) ? os->length : dump),
+                                            dump_indent) <= 0)
+                            goto end;
+                        nl = 1;
+                    }
+                }
+                ASN1_OCTET_STRING_free(os);
+                os = NULL;
+            } else if (tag == V_ASN1_INTEGER) {
+                ASN1_INTEGER *bs;
+                int i;
+
+                opp = op;
+                bs = d2i_ASN1_INTEGER(NULL, &opp, len + hl);
+                if (bs != NULL) {
+                    if (BIO_write(bp, ":", 1) <= 0)
+                        goto end;
+                    if (bs->type == V_ASN1_NEG_INTEGER)
+                        if (BIO_write(bp, "-", 1) <= 0)
+                            goto end;
+                    for (i = 0; i < bs->length; i++) {
+                        if (BIO_printf(bp, "%02X", bs->data[i]) <= 0)
+                            goto end;
+                    }
+                    if (bs->length == 0) {
+                        if (BIO_write(bp, "00", 2) <= 0)
+                            goto end;
+                    }
+                } else {
+                    if (BIO_puts(bp, ":BAD INTEGER") <= 0)
+                        goto end;
+                    dump_cont = 1;
+                }
+                ASN1_INTEGER_free(bs);
+            } else if (tag == V_ASN1_ENUMERATED) {
+                ASN1_ENUMERATED *bs;
+                int i;
+
+                opp = op;
+                bs = d2i_ASN1_ENUMERATED(NULL, &opp, len + hl);
+                if (bs != NULL) {
+                    if (BIO_write(bp, ":", 1) <= 0)
+                        goto end;
+                    if (bs->type == V_ASN1_NEG_ENUMERATED)
+                        if (BIO_write(bp, "-", 1) <= 0)
+                            goto end;
+                    for (i = 0; i < bs->length; i++) {
+                        if (BIO_printf(bp, "%02X", bs->data[i]) <= 0)
+                            goto end;
+                    }
+                    if (bs->length == 0) {
+                        if (BIO_write(bp, "00", 2) <= 0)
+                            goto end;
+                    }
+                } else {
+                    if (BIO_puts(bp, ":BAD ENUMERATED") <= 0)
+                        goto end;
+                    dump_cont = 1;
+                }
+                ASN1_ENUMERATED_free(bs);
+            } else if (len > 0 && dump) {
+                if (!nl) {
+                    if (BIO_write(bp, "\n", 1) <= 0)
+                        goto end;
+                }
+                if (BIO_dump_indent(bp, (const char *)p,
+                                    ((dump == -1 || dump > len) ? len : dump),
+                                    dump_indent) <= 0)
+                    goto end;
+                nl = 1;
+            }
+            if (dump_cont) {
+                int i;
+                const unsigned char *tmp = op + hl;
+                if (BIO_puts(bp, ":[") <= 0)
+                    goto end;
+                for (i = 0; i < len; i++) {
+                    if (BIO_printf(bp, "%02X", tmp[i]) <= 0)
+                        goto end;
+                }
+                if (BIO_puts(bp, "]") <= 0)
+                    goto end;
+            }
+
+            if (!nl) {
+                if (BIO_write(bp, "\n", 1) <= 0)
+                    goto end;
+            }
+            p += len;
+            if ((tag == V_ASN1_EOC) && (xclass == 0)) {
+                ret = 2;        /* End of sequence */
+                goto end;
+            }
+        }
+        length -= len;
+    }
+    ret = 1;
+ end:
+    ASN1_OBJECT_free(o);
+    ASN1_OCTET_STRING_free(os);
+    *pp = p;
+    return (ret);
+}
+
+const char *ASN1_tag2str(int tag)
+{
+    static const char *const tag2str[] = {
+        /* 0-4 */
+        "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING",
+        /* 5-9 */
+        "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL",
+        /* 10-13 */
+        "ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>",
+        /* 15-17 */
+        "<ASN1 14>", "<ASN1 15>", "SEQUENCE", "SET",
+        /* 18-20 */
+        "NUMERICSTRING", "PRINTABLESTRING", "T61STRING",
+        /* 21-24 */
+        "VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME",
+        /* 25-27 */
+        "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING",
+        /* 28-30 */
+        "UNIVERSALSTRING", "<ASN1 29>", "BMPSTRING"
+    };
+
+    if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
+        tag &= ~0x100;
+
+    if (tag < 0 || tag > 30)
+        return "(unknown)";
+    return tag2str[tag];
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn_mime.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn_mime.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn_mime.c	(revision 331)
@@ -0,0 +1,980 @@
+/*
+ * Copyright 2008-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 <stdio.h>
+#include <ctype.h>
+#include "internal/cryptlib.h"
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include "internal/evp_int.h"
+#include "internal/bio.h"
+#include "asn1_locl.h"
+
+/*
+ * Generalised MIME like utilities for streaming ASN1. Although many have a
+ * PKCS7/CMS like flavour others are more general purpose.
+ */
+
+/*
+ * MIME format structures Note that all are translated to lower case apart
+ * from parameter values. Quotes are stripped off
+ */
+
+struct mime_param_st {
+    char *param_name;           /* Param name e.g. "micalg" */
+    char *param_value;          /* Param value e.g. "sha1" */
+};
+
+struct mime_header_st {
+    char *name;                 /* Name of line e.g. "content-type" */
+    char *value;                /* Value of line e.g. "text/plain" */
+    STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */
+};
+
+static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
+                            const ASN1_ITEM *it);
+static char *strip_ends(char *name);
+static char *strip_start(char *name);
+static char *strip_end(char *name);
+static MIME_HEADER *mime_hdr_new(const char *name, const char *value);
+static int mime_hdr_addparam(MIME_HEADER *mhdr, const char *name, const char *value);
+static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio);
+static int mime_hdr_cmp(const MIME_HEADER *const *a,
+                        const MIME_HEADER *const *b);
+static int mime_param_cmp(const MIME_PARAM *const *a,
+                          const MIME_PARAM *const *b);
+static void mime_param_free(MIME_PARAM *param);
+static int mime_bound_check(char *line, int linelen, const char *bound, int blen);
+static int multi_split(BIO *bio, const char *bound, STACK_OF(BIO) **ret);
+static int strip_eol(char *linebuf, int *plen, int flags);
+static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, const char *name);
+static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, const char *name);
+static void mime_hdr_free(MIME_HEADER *hdr);
+
+#define MAX_SMLEN 1024
+#define mime_debug(x)           /* x */
+
+/* Output an ASN1 structure in BER format streaming if necessary */
+
+int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+                        const ASN1_ITEM *it)
+{
+    /* If streaming create stream BIO and copy all content through it */
+    if (flags & SMIME_STREAM) {
+        BIO *bio, *tbio;
+        bio = BIO_new_NDEF(out, val, it);
+        if (!bio) {
+            ASN1err(ASN1_F_I2D_ASN1_BIO_STREAM, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        SMIME_crlf_copy(in, bio, flags);
+        (void)BIO_flush(bio);
+        /* Free up successive BIOs until we hit the old output BIO */
+        do {
+            tbio = BIO_pop(bio);
+            BIO_free(bio);
+            bio = tbio;
+        } while (bio != out);
+    }
+    /*
+     * else just write out ASN1 structure which will have all content stored
+     * internally
+     */
+    else
+        ASN1_item_i2d_bio(it, out, val);
+    return 1;
+}
+
+/* Base 64 read and write of ASN1 structure */
+
+static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+                          const ASN1_ITEM *it)
+{
+    BIO *b64;
+    int r;
+    b64 = BIO_new(BIO_f_base64());
+    if (b64 == NULL) {
+        ASN1err(ASN1_F_B64_WRITE_ASN1, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    /*
+     * prepend the b64 BIO so all data is base64 encoded.
+     */
+    out = BIO_push(b64, out);
+    r = i2d_ASN1_bio_stream(out, val, in, flags, it);
+    (void)BIO_flush(out);
+    BIO_pop(out);
+    BIO_free(b64);
+    return r;
+}
+
+/* Streaming ASN1 PEM write */
+
+int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+                              const char *hdr, const ASN1_ITEM *it)
+{
+    int r;
+    BIO_printf(out, "-----BEGIN %s-----\n", hdr);
+    r = B64_write_ASN1(out, val, in, flags, it);
+    BIO_printf(out, "-----END %s-----\n", hdr);
+    return r;
+}
+
+static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
+{
+    BIO *b64;
+    ASN1_VALUE *val;
+
+    if ((b64 = BIO_new(BIO_f_base64())) == NULL) {
+        ASN1err(ASN1_F_B64_READ_ASN1, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    bio = BIO_push(b64, bio);
+    val = ASN1_item_d2i_bio(it, bio, NULL);
+    if (!val)
+        ASN1err(ASN1_F_B64_READ_ASN1, ASN1_R_DECODE_ERROR);
+    (void)BIO_flush(bio);
+    BIO_pop(bio);
+    BIO_free(b64);
+    return val;
+}
+
+/* Generate the MIME "micalg" parameter from RFC3851, RFC4490 */
+
+static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
+{
+    const EVP_MD *md;
+    int i, have_unknown = 0, write_comma, ret = 0, md_nid;
+    have_unknown = 0;
+    write_comma = 0;
+    for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++) {
+        if (write_comma)
+            BIO_write(out, ",", 1);
+        write_comma = 1;
+        md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm);
+        md = EVP_get_digestbynid(md_nid);
+        if (md && md->md_ctrl) {
+            int rv;
+            char *micstr;
+            rv = md->md_ctrl(NULL, EVP_MD_CTRL_MICALG, 0, &micstr);
+            if (rv > 0) {
+                BIO_puts(out, micstr);
+                OPENSSL_free(micstr);
+                continue;
+            }
+            if (rv != -2)
+                goto err;
+        }
+        switch (md_nid) {
+        case NID_sha1:
+            BIO_puts(out, "sha1");
+            break;
+
+        case NID_md5:
+            BIO_puts(out, "md5");
+            break;
+
+        case NID_sha256:
+            BIO_puts(out, "sha-256");
+            break;
+
+        case NID_sha384:
+            BIO_puts(out, "sha-384");
+            break;
+
+        case NID_sha512:
+            BIO_puts(out, "sha-512");
+            break;
+
+        case NID_id_GostR3411_94:
+            BIO_puts(out, "gostr3411-94");
+            goto err;
+
+        default:
+            if (have_unknown)
+                write_comma = 0;
+            else {
+                BIO_puts(out, "unknown");
+                have_unknown = 1;
+            }
+            break;
+
+        }
+    }
+
+    ret = 1;
+ err:
+
+    return ret;
+
+}
+
+/* SMIME sender */
+
+int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
+                     int ctype_nid, int econt_nid,
+                     STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it)
+{
+    char bound[33], c;
+    int i;
+    const char *mime_prefix, *mime_eol, *cname = "smime.p7m";
+    const char *msg_type = NULL;
+    if (flags & SMIME_OLDMIME)
+        mime_prefix = "application/x-pkcs7-";
+    else
+        mime_prefix = "application/pkcs7-";
+
+    if (flags & SMIME_CRLFEOL)
+        mime_eol = "\r\n";
+    else
+        mime_eol = "\n";
+    if ((flags & SMIME_DETACHED) && data) {
+        /* We want multipart/signed */
+        /* Generate a random boundary */
+        if (RAND_bytes((unsigned char *)bound, 32) <= 0)
+            return 0;
+        for (i = 0; i < 32; i++) {
+            c = bound[i] & 0xf;
+            if (c < 10)
+                c += '0';
+            else
+                c += 'A' - 10;
+            bound[i] = c;
+        }
+        bound[32] = 0;
+        BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
+        BIO_printf(bio, "Content-Type: multipart/signed;");
+        BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix);
+        BIO_puts(bio, " micalg=\"");
+        asn1_write_micalg(bio, mdalgs);
+        BIO_printf(bio, "\"; boundary=\"----%s\"%s%s",
+                   bound, mime_eol, mime_eol);
+        BIO_printf(bio, "This is an S/MIME signed message%s%s",
+                   mime_eol, mime_eol);
+        /* Now write out the first part */
+        BIO_printf(bio, "------%s%s", bound, mime_eol);
+        if (!asn1_output_data(bio, data, val, flags, it))
+            return 0;
+        BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol);
+
+        /* Headers for signature */
+
+        BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix);
+        BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol);
+        BIO_printf(bio, "Content-Transfer-Encoding: base64%s", mime_eol);
+        BIO_printf(bio, "Content-Disposition: attachment;");
+        BIO_printf(bio, " filename=\"smime.p7s\"%s%s", mime_eol, mime_eol);
+        B64_write_ASN1(bio, val, NULL, 0, it);
+        BIO_printf(bio, "%s------%s--%s%s", mime_eol, bound,
+                   mime_eol, mime_eol);
+        return 1;
+    }
+
+    /* Determine smime-type header */
+
+    if (ctype_nid == NID_pkcs7_enveloped)
+        msg_type = "enveloped-data";
+    else if (ctype_nid == NID_pkcs7_signed) {
+        if (econt_nid == NID_id_smime_ct_receipt)
+            msg_type = "signed-receipt";
+        else if (sk_X509_ALGOR_num(mdalgs) >= 0)
+            msg_type = "signed-data";
+        else
+            msg_type = "certs-only";
+    } else if (ctype_nid == NID_id_smime_ct_compressedData) {
+        msg_type = "compressed-data";
+        cname = "smime.p7z";
+    }
+    /* MIME headers */
+    BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
+    BIO_printf(bio, "Content-Disposition: attachment;");
+    BIO_printf(bio, " filename=\"%s\"%s", cname, mime_eol);
+    BIO_printf(bio, "Content-Type: %smime;", mime_prefix);
+    if (msg_type)
+        BIO_printf(bio, " smime-type=%s;", msg_type);
+    BIO_printf(bio, " name=\"%s\"%s", cname, mime_eol);
+    BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s",
+               mime_eol, mime_eol);
+    if (!B64_write_ASN1(bio, val, data, flags, it))
+        return 0;
+    BIO_printf(bio, "%s", mime_eol);
+    return 1;
+}
+
+/* Handle output of ASN1 data */
+
+static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
+                            const ASN1_ITEM *it)
+{
+    BIO *tmpbio;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_STREAM_ARG sarg;
+    int rv = 1;
+
+    /*
+     * If data is not detached or resigning then the output BIO is already
+     * set up to finalise when it is written through.
+     */
+    if (!(flags & SMIME_DETACHED) || (flags & PKCS7_REUSE_DIGEST)) {
+        SMIME_crlf_copy(data, out, flags);
+        return 1;
+    }
+
+    if (!aux || !aux->asn1_cb) {
+        ASN1err(ASN1_F_ASN1_OUTPUT_DATA, ASN1_R_STREAMING_NOT_SUPPORTED);
+        return 0;
+    }
+
+    sarg.out = out;
+    sarg.ndef_bio = NULL;
+    sarg.boundary = NULL;
+
+    /* Let ASN1 code prepend any needed BIOs */
+
+    if (aux->asn1_cb(ASN1_OP_DETACHED_PRE, &val, it, &sarg) <= 0)
+        return 0;
+
+    /* Copy data across, passing through filter BIOs for processing */
+    SMIME_crlf_copy(data, sarg.ndef_bio, flags);
+
+    /* Finalize structure */
+    if (aux->asn1_cb(ASN1_OP_DETACHED_POST, &val, it, &sarg) <= 0)
+        rv = 0;
+
+    /* Now remove any digests prepended to the BIO */
+
+    while (sarg.ndef_bio != out) {
+        tmpbio = BIO_pop(sarg.ndef_bio);
+        BIO_free(sarg.ndef_bio);
+        sarg.ndef_bio = tmpbio;
+    }
+
+    return rv;
+
+}
+
+/*
+ * SMIME reader: handle multipart/signed and opaque signing. in multipart
+ * case the content is placed in a memory BIO pointed to by "bcont". In
+ * opaque this is set to NULL
+ */
+
+ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
+{
+    BIO *asnin;
+    STACK_OF(MIME_HEADER) *headers = NULL;
+    STACK_OF(BIO) *parts = NULL;
+    MIME_HEADER *hdr;
+    MIME_PARAM *prm;
+    ASN1_VALUE *val;
+    int ret;
+
+    if (bcont)
+        *bcont = NULL;
+
+    if ((headers = mime_parse_hdr(bio)) == NULL) {
+        ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_PARSE_ERROR);
+        return NULL;
+    }
+
+    if ((hdr = mime_hdr_find(headers, "content-type")) == NULL
+        || hdr->value == NULL) {
+        sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+        ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_CONTENT_TYPE);
+        return NULL;
+    }
+
+    /* Handle multipart/signed */
+
+    if (strcmp(hdr->value, "multipart/signed") == 0) {
+        /* Split into two parts */
+        prm = mime_param_find(hdr, "boundary");
+        if (!prm || !prm->param_value) {
+            sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+            ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY);
+            return NULL;
+        }
+        ret = multi_split(bio, prm->param_value, &parts);
+        sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+        if (!ret || (sk_BIO_num(parts) != 2)) {
+            ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE);
+            sk_BIO_pop_free(parts, BIO_vfree);
+            return NULL;
+        }
+
+        /* Parse the signature piece */
+        asnin = sk_BIO_value(parts, 1);
+
+        if ((headers = mime_parse_hdr(asnin)) == NULL) {
+            ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_SIG_PARSE_ERROR);
+            sk_BIO_pop_free(parts, BIO_vfree);
+            return NULL;
+        }
+
+        /* Get content type */
+
+        if ((hdr = mime_hdr_find(headers, "content-type")) == NULL
+            || hdr->value == NULL) {
+            sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+            ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE);
+            return NULL;
+        }
+
+        if (strcmp(hdr->value, "application/x-pkcs7-signature") &&
+            strcmp(hdr->value, "application/pkcs7-signature")) {
+            ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_SIG_INVALID_MIME_TYPE);
+            ERR_add_error_data(2, "type: ", hdr->value);
+            sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+            sk_BIO_pop_free(parts, BIO_vfree);
+            return NULL;
+        }
+        sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+        /* Read in ASN1 */
+        if ((val = b64_read_asn1(asnin, it)) == NULL) {
+            ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_SIG_PARSE_ERROR);
+            sk_BIO_pop_free(parts, BIO_vfree);
+            return NULL;
+        }
+
+        if (bcont) {
+            *bcont = sk_BIO_value(parts, 0);
+            BIO_free(asnin);
+            sk_BIO_free(parts);
+        } else
+            sk_BIO_pop_free(parts, BIO_vfree);
+        return val;
+    }
+
+    /* OK, if not multipart/signed try opaque signature */
+
+    if (strcmp(hdr->value, "application/x-pkcs7-mime") &&
+        strcmp(hdr->value, "application/pkcs7-mime")) {
+        ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_INVALID_MIME_TYPE);
+        ERR_add_error_data(2, "type: ", hdr->value);
+        sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+        return NULL;
+    }
+
+    sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+
+    if ((val = b64_read_asn1(bio, it)) == NULL) {
+        ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_PARSE_ERROR);
+        return NULL;
+    }
+    return val;
+
+}
+
+/* Copy text from one BIO to another making the output CRLF at EOL */
+int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
+{
+    BIO *bf;
+    char eol;
+    int len;
+    char linebuf[MAX_SMLEN];
+    /*
+     * Buffer output so we don't write one line at a time. This is useful
+     * when streaming as we don't end up with one OCTET STRING per line.
+     */
+    bf = BIO_new(BIO_f_buffer());
+    if (bf == NULL)
+        return 0;
+    out = BIO_push(bf, out);
+    if (flags & SMIME_BINARY) {
+        while ((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0)
+            BIO_write(out, linebuf, len);
+    } else {
+        int eolcnt = 0;
+        if (flags & SMIME_TEXT)
+            BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
+        while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) {
+            eol = strip_eol(linebuf, &len, flags);
+            if (len) {
+                /* Not EOF: write out all CRLF */
+                if (flags & SMIME_ASCIICRLF) {
+                    int i;
+                    for (i = 0; i < eolcnt; i++)
+                        BIO_write(out, "\r\n", 2);
+                    eolcnt = 0;
+                }
+                BIO_write(out, linebuf, len);
+                if (eol)
+                    BIO_write(out, "\r\n", 2);
+            } else if (flags & SMIME_ASCIICRLF)
+                eolcnt++;
+            else if (eol)
+                BIO_write(out, "\r\n", 2);
+        }
+    }
+    (void)BIO_flush(out);
+    BIO_pop(out);
+    BIO_free(bf);
+    return 1;
+}
+
+/* Strip off headers if they are text/plain */
+int SMIME_text(BIO *in, BIO *out)
+{
+    char iobuf[4096];
+    int len;
+    STACK_OF(MIME_HEADER) *headers;
+    MIME_HEADER *hdr;
+
+    if ((headers = mime_parse_hdr(in)) == NULL) {
+        ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_PARSE_ERROR);
+        return 0;
+    }
+    if ((hdr = mime_hdr_find(headers, "content-type")) == NULL
+        || hdr->value == NULL) {
+        ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_NO_CONTENT_TYPE);
+        sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+        return 0;
+    }
+    if (strcmp(hdr->value, "text/plain")) {
+        ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_INVALID_MIME_TYPE);
+        ERR_add_error_data(2, "type: ", hdr->value);
+        sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+        return 0;
+    }
+    sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+    while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0)
+        BIO_write(out, iobuf, len);
+    if (len < 0)
+        return 0;
+    return 1;
+}
+
+/*
+ * Split a multipart/XXX message body into component parts: result is
+ * canonical parts in a STACK of bios
+ */
+
+static int multi_split(BIO *bio, const char *bound, STACK_OF(BIO) **ret)
+{
+    char linebuf[MAX_SMLEN];
+    int len, blen;
+    int eol = 0, next_eol = 0;
+    BIO *bpart = NULL;
+    STACK_OF(BIO) *parts;
+    char state, part, first;
+
+    blen = strlen(bound);
+    part = 0;
+    state = 0;
+    first = 1;
+    parts = sk_BIO_new_null();
+    *ret = parts;
+    if (*ret == NULL)
+        return 0;
+    while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
+        state = mime_bound_check(linebuf, len, bound, blen);
+        if (state == 1) {
+            first = 1;
+            part++;
+        } else if (state == 2) {
+            if (!sk_BIO_push(parts, bpart)) {
+                BIO_free(bpart);
+                return 0;
+            }
+            return 1;
+        } else if (part) {
+            /* Strip CR+LF from linebuf */
+            next_eol = strip_eol(linebuf, &len, 0);
+            if (first) {
+                first = 0;
+                if (bpart)
+                    if (!sk_BIO_push(parts, bpart)) {
+                        BIO_free(bpart);
+                        return 0;
+                    }
+                bpart = BIO_new(BIO_s_mem());
+                if (bpart == NULL)
+                    return 0;
+                BIO_set_mem_eof_return(bpart, 0);
+            } else if (eol)
+                BIO_write(bpart, "\r\n", 2);
+            eol = next_eol;
+            if (len)
+                BIO_write(bpart, linebuf, len);
+        }
+    }
+    BIO_free(bpart);
+    return 0;
+}
+
+/* This is the big one: parse MIME header lines up to message body */
+
+#define MIME_INVALID    0
+#define MIME_START      1
+#define MIME_TYPE       2
+#define MIME_NAME       3
+#define MIME_VALUE      4
+#define MIME_QUOTE      5
+#define MIME_COMMENT    6
+
+static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
+{
+    char *p, *q, c;
+    char *ntmp;
+    char linebuf[MAX_SMLEN];
+    MIME_HEADER *mhdr = NULL, *new_hdr = NULL;
+    STACK_OF(MIME_HEADER) *headers;
+    int len, state, save_state = 0;
+
+    headers = sk_MIME_HEADER_new(mime_hdr_cmp);
+    if (headers == NULL)
+        return NULL;
+    while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
+        /* If whitespace at line start then continuation line */
+        if (mhdr && isspace((unsigned char)linebuf[0]))
+            state = MIME_NAME;
+        else
+            state = MIME_START;
+        ntmp = NULL;
+        /* Go through all characters */
+        for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n');
+             p++) {
+
+            /*
+             * State machine to handle MIME headers if this looks horrible
+             * that's because it *is*
+             */
+
+            switch (state) {
+            case MIME_START:
+                if (c == ':') {
+                    state = MIME_TYPE;
+                    *p = 0;
+                    ntmp = strip_ends(q);
+                    q = p + 1;
+                }
+                break;
+
+            case MIME_TYPE:
+                if (c == ';') {
+                    mime_debug("Found End Value\n");
+                    *p = 0;
+                    new_hdr = mime_hdr_new(ntmp, strip_ends(q));
+                    if (new_hdr == NULL)
+                        goto err;
+                    if (!sk_MIME_HEADER_push(headers, new_hdr))
+                        goto err;
+                    mhdr = new_hdr;
+                    new_hdr = NULL;
+                    ntmp = NULL;
+                    q = p + 1;
+                    state = MIME_NAME;
+                } else if (c == '(') {
+                    save_state = state;
+                    state = MIME_COMMENT;
+                }
+                break;
+
+            case MIME_COMMENT:
+                if (c == ')') {
+                    state = save_state;
+                }
+                break;
+
+            case MIME_NAME:
+                if (c == '=') {
+                    state = MIME_VALUE;
+                    *p = 0;
+                    ntmp = strip_ends(q);
+                    q = p + 1;
+                }
+                break;
+
+            case MIME_VALUE:
+                if (c == ';') {
+                    state = MIME_NAME;
+                    *p = 0;
+                    mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
+                    ntmp = NULL;
+                    q = p + 1;
+                } else if (c == '"') {
+                    mime_debug("Found Quote\n");
+                    state = MIME_QUOTE;
+                } else if (c == '(') {
+                    save_state = state;
+                    state = MIME_COMMENT;
+                }
+                break;
+
+            case MIME_QUOTE:
+                if (c == '"') {
+                    mime_debug("Found Match Quote\n");
+                    state = MIME_VALUE;
+                }
+                break;
+            }
+        }
+
+        if (state == MIME_TYPE) {
+            new_hdr = mime_hdr_new(ntmp, strip_ends(q));
+            if (new_hdr == NULL)
+                goto err;
+            if (!sk_MIME_HEADER_push(headers, new_hdr))
+                goto err;
+            mhdr = new_hdr;
+            new_hdr = NULL;
+        } else if (state == MIME_VALUE)
+            mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
+        if (p == linebuf)
+            break;              /* Blank line means end of headers */
+    }
+
+    return headers;
+
+err:
+    mime_hdr_free(new_hdr);
+    sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
+    return NULL;
+}
+
+static char *strip_ends(char *name)
+{
+    return strip_end(strip_start(name));
+}
+
+/* Strip a parameter of whitespace from start of param */
+static char *strip_start(char *name)
+{
+    char *p, c;
+    /* Look for first non white space or quote */
+    for (p = name; (c = *p); p++) {
+        if (c == '"') {
+            /* Next char is start of string if non null */
+            if (p[1])
+                return p + 1;
+            /* Else null string */
+            return NULL;
+        }
+        if (!isspace((unsigned char)c))
+            return p;
+    }
+    return NULL;
+}
+
+/* As above but strip from end of string : maybe should handle brackets? */
+static char *strip_end(char *name)
+{
+    char *p, c;
+    if (!name)
+        return NULL;
+    /* Look for first non white space or quote */
+    for (p = name + strlen(name) - 1; p >= name; p--) {
+        c = *p;
+        if (c == '"') {
+            if (p - 1 == name)
+                return NULL;
+            *p = 0;
+            return name;
+        }
+        if (isspace((unsigned char)c))
+            *p = 0;
+        else
+            return name;
+    }
+    return NULL;
+}
+
+static MIME_HEADER *mime_hdr_new(const char *name, const char *value)
+{
+    MIME_HEADER *mhdr = NULL;
+    char *tmpname = NULL, *tmpval = NULL, *p;
+    int c;
+
+    if (name) {
+        if ((tmpname = OPENSSL_strdup(name)) == NULL)
+            return NULL;
+        for (p = tmpname; *p; p++) {
+            c = (unsigned char)*p;
+            if (isupper(c)) {
+                c = tolower(c);
+                *p = c;
+            }
+        }
+    }
+    if (value) {
+        if ((tmpval = OPENSSL_strdup(value)) == NULL)
+            goto err;
+        for (p = tmpval; *p; p++) {
+            c = (unsigned char)*p;
+            if (isupper(c)) {
+                c = tolower(c);
+                *p = c;
+            }
+        }
+    }
+    mhdr = OPENSSL_malloc(sizeof(*mhdr));
+    if (mhdr == NULL)
+        goto err;
+    mhdr->name = tmpname;
+    mhdr->value = tmpval;
+    if ((mhdr->params = sk_MIME_PARAM_new(mime_param_cmp)) == NULL)
+        goto err;
+    return mhdr;
+
+ err:
+    OPENSSL_free(tmpname);
+    OPENSSL_free(tmpval);
+    OPENSSL_free(mhdr);
+    return NULL;
+}
+
+static int mime_hdr_addparam(MIME_HEADER *mhdr, const char *name, const char *value)
+{
+    char *tmpname = NULL, *tmpval = NULL, *p;
+    int c;
+    MIME_PARAM *mparam = NULL;
+    if (name) {
+        tmpname = OPENSSL_strdup(name);
+        if (!tmpname)
+            goto err;
+        for (p = tmpname; *p; p++) {
+            c = (unsigned char)*p;
+            if (isupper(c)) {
+                c = tolower(c);
+                *p = c;
+            }
+        }
+    }
+    if (value) {
+        tmpval = OPENSSL_strdup(value);
+        if (!tmpval)
+            goto err;
+    }
+    /* Parameter values are case sensitive so leave as is */
+    mparam = OPENSSL_malloc(sizeof(*mparam));
+    if (mparam == NULL)
+        goto err;
+    mparam->param_name = tmpname;
+    mparam->param_value = tmpval;
+    if (!sk_MIME_PARAM_push(mhdr->params, mparam))
+        goto err;
+    return 1;
+ err:
+    OPENSSL_free(tmpname);
+    OPENSSL_free(tmpval);
+    OPENSSL_free(mparam);
+    return 0;
+}
+
+static int mime_hdr_cmp(const MIME_HEADER *const *a,
+                        const MIME_HEADER *const *b)
+{
+    if (!(*a)->name || !(*b)->name)
+        return ! !(*a)->name - ! !(*b)->name;
+
+    return (strcmp((*a)->name, (*b)->name));
+}
+
+static int mime_param_cmp(const MIME_PARAM *const *a,
+                          const MIME_PARAM *const *b)
+{
+    if (!(*a)->param_name || !(*b)->param_name)
+        return ! !(*a)->param_name - ! !(*b)->param_name;
+    return (strcmp((*a)->param_name, (*b)->param_name));
+}
+
+/* Find a header with a given name (if possible) */
+
+static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, const char *name)
+{
+    MIME_HEADER htmp;
+    int idx;
+
+    htmp.name = (char *)name;
+    htmp.value = NULL;
+    htmp.params = NULL;
+
+    idx = sk_MIME_HEADER_find(hdrs, &htmp);
+    if (idx < 0)
+        return NULL;
+    return sk_MIME_HEADER_value(hdrs, idx);
+}
+
+static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, const char *name)
+{
+    MIME_PARAM param;
+    int idx;
+
+    param.param_name = (char *)name;
+    param.param_value = NULL;
+    idx = sk_MIME_PARAM_find(hdr->params, &param);
+    if (idx < 0)
+        return NULL;
+    return sk_MIME_PARAM_value(hdr->params, idx);
+}
+
+static void mime_hdr_free(MIME_HEADER *hdr)
+{
+    if (hdr == NULL)
+        return;
+    OPENSSL_free(hdr->name);
+    OPENSSL_free(hdr->value);
+    if (hdr->params)
+        sk_MIME_PARAM_pop_free(hdr->params, mime_param_free);
+    OPENSSL_free(hdr);
+}
+
+static void mime_param_free(MIME_PARAM *param)
+{
+    OPENSSL_free(param->param_name);
+    OPENSSL_free(param->param_value);
+    OPENSSL_free(param);
+}
+
+/*-
+ * Check for a multipart boundary. Returns:
+ * 0 : no boundary
+ * 1 : part boundary
+ * 2 : final boundary
+ */
+static int mime_bound_check(char *line, int linelen, const char *bound, int blen)
+{
+    if (linelen == -1)
+        linelen = strlen(line);
+    if (blen == -1)
+        blen = strlen(bound);
+    /* Quickly eliminate if line length too short */
+    if (blen + 2 > linelen)
+        return 0;
+    /* Check for part boundary */
+    if ((strncmp(line, "--", 2) == 0)
+        && strncmp(line + 2, bound, blen) == 0) {
+        if (strncmp(line + blen + 2, "--", 2) == 0)
+            return 2;
+        else
+            return 1;
+    }
+    return 0;
+}
+
+static int strip_eol(char *linebuf, int *plen, int flags)
+{
+    int len = *plen;
+    char *p, c;
+    int is_eol = 0;
+    p = linebuf + len - 1;
+    for (p = linebuf + len - 1; len > 0; len--, p--) {
+        c = *p;
+        if (c == '\n')
+            is_eol = 1;
+        else if (is_eol && flags & SMIME_ASCIICRLF && c < 33)
+            continue;
+        else if (c != '\r')
+            break;
+    }
+    *plen = len;
+    return is_eol;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn_moid.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn_moid.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn_moid.c	(revision 331)
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2002-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 <stdio.h>
+#include <ctype.h>
+#include <openssl/crypto.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509.h>
+#include "internal/asn1_int.h"
+#include "internal/objects.h"
+
+/* Simple ASN1 OID module: add all objects in a given section */
+
+static int do_create(const char *value, const char *name);
+
+static int oid_module_init(CONF_IMODULE *md, const CONF *cnf)
+{
+    int i;
+    const char *oid_section;
+    STACK_OF(CONF_VALUE) *sktmp;
+    CONF_VALUE *oval;
+
+    oid_section = CONF_imodule_get_value(md);
+    if ((sktmp = NCONF_get_section(cnf, oid_section)) == NULL) {
+        ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION);
+        return 0;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
+        oval = sk_CONF_VALUE_value(sktmp, i);
+        if (!do_create(oval->value, oval->name)) {
+            ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ADDING_OBJECT);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+static void oid_module_finish(CONF_IMODULE *md)
+{
+}
+
+void ASN1_add_oid_module(void)
+{
+    CONF_module_add("oid_section", oid_module_init, oid_module_finish);
+}
+
+/*-
+ * Create an OID based on a name value pair. Accept two formats.
+ * shortname = 1.2.3.4
+ * shortname = some long name, 1.2.3.4
+ */
+
+static int do_create(const char *value, const char *name)
+{
+    int nid;
+    ASN1_OBJECT *oid;
+    const char *ln, *ostr, *p;
+    char *lntmp;
+    p = strrchr(value, ',');
+    if (!p) {
+        ln = name;
+        ostr = value;
+    } else {
+        ln = NULL;
+        ostr = p + 1;
+        if (!*ostr)
+            return 0;
+        while (isspace((unsigned char)*ostr))
+            ostr++;
+    }
+
+    nid = OBJ_create(ostr, name, ln);
+
+    if (nid == NID_undef)
+        return 0;
+
+    if (p) {
+        ln = value;
+        while (isspace((unsigned char)*ln))
+            ln++;
+        p--;
+        while (isspace((unsigned char)*p)) {
+            if (p == ln)
+                return 0;
+            p--;
+        }
+        p++;
+        lntmp = OPENSSL_malloc((p - ln) + 1);
+        if (lntmp == NULL)
+            return 0;
+        memcpy(lntmp, ln, p - ln);
+        lntmp[p - ln] = 0;
+        oid = OBJ_nid2obj(nid);
+        oid->ln = lntmp;
+    }
+
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn_mstbl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn_mstbl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn_mstbl.c	(revision 331)
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2012-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 <stdio.h>
+#include <ctype.h>
+#include <openssl/crypto.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+/* Multi string module: add table entries from a given section */
+
+static int do_tcreate(const char *value, const char *name);
+
+static int stbl_module_init(CONF_IMODULE *md, const CONF *cnf)
+{
+    int i;
+    const char *stbl_section;
+    STACK_OF(CONF_VALUE) *sktmp;
+    CONF_VALUE *mval;
+
+    stbl_section = CONF_imodule_get_value(md);
+    if ((sktmp = NCONF_get_section(cnf, stbl_section)) == NULL) {
+        ASN1err(ASN1_F_STBL_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION);
+        return 0;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
+        mval = sk_CONF_VALUE_value(sktmp, i);
+        if (!do_tcreate(mval->value, mval->name)) {
+            ASN1err(ASN1_F_STBL_MODULE_INIT, ASN1_R_INVALID_VALUE);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+static void stbl_module_finish(CONF_IMODULE *md)
+{
+    ASN1_STRING_TABLE_cleanup();
+}
+
+void ASN1_add_stable_module(void)
+{
+    CONF_module_add("stbl_section", stbl_module_init, stbl_module_finish);
+}
+
+/*
+ * Create an table entry based on a name value pair. format is oid_name =
+ * n1:v1, n2:v2,... where name is "min", "max", "mask" or "flags".
+ */
+
+static int do_tcreate(const char *value, const char *name)
+{
+    char *eptr;
+    int nid, i, rv = 0;
+    long tbl_min = -1, tbl_max = -1;
+    unsigned long tbl_mask = 0, tbl_flags = 0;
+    STACK_OF(CONF_VALUE) *lst = NULL;
+    CONF_VALUE *cnf = NULL;
+    nid = OBJ_sn2nid(name);
+    if (nid == NID_undef)
+        nid = OBJ_ln2nid(name);
+    if (nid == NID_undef)
+        goto err;
+    lst = X509V3_parse_list(value);
+    if (!lst)
+        goto err;
+    for (i = 0; i < sk_CONF_VALUE_num(lst); i++) {
+        cnf = sk_CONF_VALUE_value(lst, i);
+        if (strcmp(cnf->name, "min") == 0) {
+            tbl_min = strtoul(cnf->value, &eptr, 0);
+            if (*eptr)
+                goto err;
+        } else if (strcmp(cnf->name, "max") == 0) {
+            tbl_max = strtoul(cnf->value, &eptr, 0);
+            if (*eptr)
+                goto err;
+        } else if (strcmp(cnf->name, "mask") == 0) {
+            if (!ASN1_str2mask(cnf->value, &tbl_mask) || !tbl_mask)
+                goto err;
+        } else if (strcmp(cnf->name, "flags") == 0) {
+            if (strcmp(cnf->value, "nomask") == 0)
+                tbl_flags = STABLE_NO_MASK;
+            else if (strcmp(cnf->value, "none") == 0)
+                tbl_flags = STABLE_FLAGS_CLEAR;
+            else
+                goto err;
+        } else
+            goto err;
+    }
+    rv = 1;
+ err:
+    if (rv == 0) {
+        ASN1err(ASN1_F_DO_TCREATE, ASN1_R_INVALID_STRING_TABLE_VALUE);
+        if (cnf)
+            ERR_add_error_data(4, "field=", cnf->name,
+                               ", value=", cnf->value);
+        else
+            ERR_add_error_data(4, "name=", name, ", value=", value);
+    } else {
+        rv = ASN1_STRING_TABLE_add(nid, tbl_min, tbl_max,
+                                   tbl_mask, tbl_flags);
+        if (!rv)
+            ASN1err(ASN1_F_DO_TCREATE, ERR_R_MALLOC_FAILURE);
+    }
+    sk_CONF_VALUE_pop_free(lst, X509V3_conf_free);
+    return rv;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn_pack.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn_pack.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/asn_pack.c	(revision 331)
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+
+/* ASN1 packing and unpacking functions */
+
+ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
+{
+    ASN1_STRING *octmp;
+
+     if (oct == NULL || *oct == NULL) {
+        if ((octmp = ASN1_STRING_new()) == NULL) {
+            ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE);
+            return NULL;
+        }
+    } else {
+        octmp = *oct;
+    }
+
+    OPENSSL_free(octmp->data);
+    octmp->data = NULL;
+
+    if ((octmp->length = ASN1_item_i2d(obj, &octmp->data, it)) == 0) {
+        ASN1err(ASN1_F_ASN1_ITEM_PACK, ASN1_R_ENCODE_ERROR);
+        goto err;
+    }
+    if (octmp->data == NULL) {
+        ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (oct != NULL && *oct == NULL)
+        *oct = octmp;
+
+    return octmp;
+ err:
+    if (oct == NULL || *oct == NULL)
+        ASN1_STRING_free(octmp);
+    return NULL;
+}
+
+/* Extract an ASN1 object from an ASN1_STRING */
+
+void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it)
+{
+    const unsigned char *p;
+    void *ret;
+
+    p = oct->data;
+    if ((ret = ASN1_item_d2i(NULL, &p, oct->length, it)) == NULL)
+        ASN1err(ASN1_F_ASN1_ITEM_UNPACK, ASN1_R_DECODE_ERROR);
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/bio_asn1.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/bio_asn1.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/bio_asn1.c	(revision 331)
@@ -0,0 +1,437 @@
+/*
+ * Copyright 2006-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
+ */
+
+/*
+ * Experimental ASN1 BIO. When written through the data is converted to an
+ * ASN1 string type: default is OCTET STRING. Additional functions can be
+ * provided to add prefix and suffix data.
+ */
+
+#include <string.h>
+#include <internal/bio.h>
+#include <openssl/asn1.h>
+
+/* Must be large enough for biggest tag+length */
+#define DEFAULT_ASN1_BUF_SIZE 20
+
+typedef enum {
+    ASN1_STATE_START,
+    ASN1_STATE_PRE_COPY,
+    ASN1_STATE_HEADER,
+    ASN1_STATE_HEADER_COPY,
+    ASN1_STATE_DATA_COPY,
+    ASN1_STATE_POST_COPY,
+    ASN1_STATE_DONE
+} asn1_bio_state_t;
+
+typedef struct BIO_ASN1_EX_FUNCS_st {
+    asn1_ps_func *ex_func;
+    asn1_ps_func *ex_free_func;
+} BIO_ASN1_EX_FUNCS;
+
+typedef struct BIO_ASN1_BUF_CTX_t {
+    /* Internal state */
+    asn1_bio_state_t state;
+    /* Internal buffer */
+    unsigned char *buf;
+    /* Size of buffer */
+    int bufsize;
+    /* Current position in buffer */
+    int bufpos;
+    /* Current buffer length */
+    int buflen;
+    /* Amount of data to copy */
+    int copylen;
+    /* Class and tag to use */
+    int asn1_class, asn1_tag;
+    asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
+    /* Extra buffer for prefix and suffix data */
+    unsigned char *ex_buf;
+    int ex_len;
+    int ex_pos;
+    void *ex_arg;
+} BIO_ASN1_BUF_CTX;
+
+static int asn1_bio_write(BIO *h, const char *buf, int num);
+static int asn1_bio_read(BIO *h, char *buf, int size);
+static int asn1_bio_puts(BIO *h, const char *str);
+static int asn1_bio_gets(BIO *h, char *str, int size);
+static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int asn1_bio_new(BIO *h);
+static int asn1_bio_free(BIO *data);
+static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+
+static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
+static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+                             asn1_ps_func *cleanup, asn1_bio_state_t next);
+static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+                             asn1_ps_func *setup,
+                             asn1_bio_state_t ex_state,
+                             asn1_bio_state_t other_state);
+
+static const BIO_METHOD methods_asn1 = {
+    BIO_TYPE_ASN1,
+    "asn1",
+    asn1_bio_write,
+    asn1_bio_read,
+    asn1_bio_puts,
+    asn1_bio_gets,
+    asn1_bio_ctrl,
+    asn1_bio_new,
+    asn1_bio_free,
+    asn1_bio_callback_ctrl,
+};
+
+const BIO_METHOD *BIO_f_asn1(void)
+{
+    return (&methods_asn1);
+}
+
+static int asn1_bio_new(BIO *b)
+{
+    BIO_ASN1_BUF_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+    if (ctx == NULL)
+        return 0;
+    if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) {
+        OPENSSL_free(ctx);
+        return 0;
+    }
+    BIO_set_data(b, ctx);
+    BIO_set_init(b, 1);
+
+    return 1;
+}
+
+static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
+{
+    ctx->buf = OPENSSL_malloc(size);
+    if (ctx->buf == NULL)
+        return 0;
+    ctx->bufsize = size;
+    ctx->asn1_class = V_ASN1_UNIVERSAL;
+    ctx->asn1_tag = V_ASN1_OCTET_STRING;
+    ctx->state = ASN1_STATE_START;
+    return 1;
+}
+
+static int asn1_bio_free(BIO *b)
+{
+    BIO_ASN1_BUF_CTX *ctx;
+
+    if (b == NULL)
+        return 0;
+
+    ctx = BIO_get_data(b);
+    if (ctx == NULL)
+        return 0;
+
+    OPENSSL_free(ctx->buf);
+    OPENSSL_free(ctx);
+    BIO_set_data(b, NULL);
+    BIO_set_init(b, 0);
+
+    return 1;
+}
+
+static int asn1_bio_write(BIO *b, const char *in, int inl)
+{
+    BIO_ASN1_BUF_CTX *ctx;
+    int wrmax, wrlen, ret;
+    unsigned char *p;
+    BIO *next;
+
+    ctx = BIO_get_data(b);
+    next = BIO_next(b);
+    if (in == NULL || inl < 0 || ctx == NULL || next == NULL)
+        return 0;
+
+    wrlen = 0;
+    ret = -1;
+
+    for (;;) {
+        switch (ctx->state) {
+
+            /* Setup prefix data, call it */
+        case ASN1_STATE_START:
+            if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
+                                   ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
+                return 0;
+            break;
+
+            /* Copy any pre data first */
+        case ASN1_STATE_PRE_COPY:
+
+            ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
+                                    ASN1_STATE_HEADER);
+
+            if (ret <= 0)
+                goto done;
+
+            break;
+
+        case ASN1_STATE_HEADER:
+            ctx->buflen = ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
+            OPENSSL_assert(ctx->buflen <= ctx->bufsize);
+            p = ctx->buf;
+            ASN1_put_object(&p, 0, inl, ctx->asn1_tag, ctx->asn1_class);
+            ctx->copylen = inl;
+            ctx->state = ASN1_STATE_HEADER_COPY;
+
+            break;
+
+        case ASN1_STATE_HEADER_COPY:
+            ret = BIO_write(next, ctx->buf + ctx->bufpos, ctx->buflen);
+            if (ret <= 0)
+                goto done;
+
+            ctx->buflen -= ret;
+            if (ctx->buflen)
+                ctx->bufpos += ret;
+            else {
+                ctx->bufpos = 0;
+                ctx->state = ASN1_STATE_DATA_COPY;
+            }
+
+            break;
+
+        case ASN1_STATE_DATA_COPY:
+
+            if (inl > ctx->copylen)
+                wrmax = ctx->copylen;
+            else
+                wrmax = inl;
+            ret = BIO_write(next, in, wrmax);
+            if (ret <= 0)
+                break;
+            wrlen += ret;
+            ctx->copylen -= ret;
+            in += ret;
+            inl -= ret;
+
+            if (ctx->copylen == 0)
+                ctx->state = ASN1_STATE_HEADER;
+
+            if (inl == 0)
+                goto done;
+
+            break;
+
+        default:
+            BIO_clear_retry_flags(b);
+            return 0;
+
+        }
+
+    }
+
+ done:
+    BIO_clear_retry_flags(b);
+    BIO_copy_next_retry(b);
+
+    return (wrlen > 0) ? wrlen : ret;
+
+}
+
+static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+                             asn1_ps_func *cleanup, asn1_bio_state_t next)
+{
+    int ret;
+
+    if (ctx->ex_len <= 0)
+        return 1;
+    for (;;) {
+        ret = BIO_write(BIO_next(b), ctx->ex_buf + ctx->ex_pos, ctx->ex_len);
+        if (ret <= 0)
+            break;
+        ctx->ex_len -= ret;
+        if (ctx->ex_len > 0)
+            ctx->ex_pos += ret;
+        else {
+            if (cleanup)
+                cleanup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg);
+            ctx->state = next;
+            ctx->ex_pos = 0;
+            break;
+        }
+    }
+    return ret;
+}
+
+static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+                             asn1_ps_func *setup,
+                             asn1_bio_state_t ex_state,
+                             asn1_bio_state_t other_state)
+{
+    if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg)) {
+        BIO_clear_retry_flags(b);
+        return 0;
+    }
+    if (ctx->ex_len > 0)
+        ctx->state = ex_state;
+    else
+        ctx->state = other_state;
+    return 1;
+}
+
+static int asn1_bio_read(BIO *b, char *in, int inl)
+{
+    BIO *next = BIO_next(b);
+    if (next == NULL)
+        return 0;
+    return BIO_read(next, in, inl);
+}
+
+static int asn1_bio_puts(BIO *b, const char *str)
+{
+    return asn1_bio_write(b, str, strlen(str));
+}
+
+static int asn1_bio_gets(BIO *b, char *str, int size)
+{
+    BIO *next = BIO_next(b);
+    if (next == NULL)
+        return 0;
+    return BIO_gets(next, str, size);
+}
+
+static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+    BIO *next = BIO_next(b);
+    if (next == NULL)
+        return 0;
+    return BIO_callback_ctrl(next, cmd, fp);
+}
+
+static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
+{
+    BIO_ASN1_BUF_CTX *ctx;
+    BIO_ASN1_EX_FUNCS *ex_func;
+    long ret = 1;
+    BIO *next;
+
+    ctx = BIO_get_data(b);
+    if (ctx == NULL)
+        return 0;
+    next = BIO_next(b);
+    switch (cmd) {
+
+    case BIO_C_SET_PREFIX:
+        ex_func = arg2;
+        ctx->prefix = ex_func->ex_func;
+        ctx->prefix_free = ex_func->ex_free_func;
+        break;
+
+    case BIO_C_GET_PREFIX:
+        ex_func = arg2;
+        ex_func->ex_func = ctx->prefix;
+        ex_func->ex_free_func = ctx->prefix_free;
+        break;
+
+    case BIO_C_SET_SUFFIX:
+        ex_func = arg2;
+        ctx->suffix = ex_func->ex_func;
+        ctx->suffix_free = ex_func->ex_free_func;
+        break;
+
+    case BIO_C_GET_SUFFIX:
+        ex_func = arg2;
+        ex_func->ex_func = ctx->suffix;
+        ex_func->ex_free_func = ctx->suffix_free;
+        break;
+
+    case BIO_C_SET_EX_ARG:
+        ctx->ex_arg = arg2;
+        break;
+
+    case BIO_C_GET_EX_ARG:
+        *(void **)arg2 = ctx->ex_arg;
+        break;
+
+    case BIO_CTRL_FLUSH:
+        if (next == NULL)
+            return 0;
+
+        /* Call post function if possible */
+        if (ctx->state == ASN1_STATE_HEADER) {
+            if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
+                                   ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
+                return 0;
+        }
+
+        if (ctx->state == ASN1_STATE_POST_COPY) {
+            ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
+                                    ASN1_STATE_DONE);
+            if (ret <= 0)
+                return ret;
+        }
+
+        if (ctx->state == ASN1_STATE_DONE)
+            return BIO_ctrl(next, cmd, arg1, arg2);
+        else {
+            BIO_clear_retry_flags(b);
+            return 0;
+        }
+
+    default:
+        if (next == NULL)
+            return 0;
+        return BIO_ctrl(next, cmd, arg1, arg2);
+
+    }
+
+    return ret;
+}
+
+static int asn1_bio_set_ex(BIO *b, int cmd,
+                           asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
+{
+    BIO_ASN1_EX_FUNCS extmp;
+    extmp.ex_func = ex_func;
+    extmp.ex_free_func = ex_free_func;
+    return BIO_ctrl(b, cmd, 0, &extmp);
+}
+
+static int asn1_bio_get_ex(BIO *b, int cmd,
+                           asn1_ps_func **ex_func,
+                           asn1_ps_func **ex_free_func)
+{
+    BIO_ASN1_EX_FUNCS extmp;
+    int ret;
+    ret = BIO_ctrl(b, cmd, 0, &extmp);
+    if (ret > 0) {
+        *ex_func = extmp.ex_func;
+        *ex_free_func = extmp.ex_free_func;
+    }
+    return ret;
+}
+
+int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
+                        asn1_ps_func *prefix_free)
+{
+    return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
+}
+
+int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
+                        asn1_ps_func **pprefix_free)
+{
+    return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
+}
+
+int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
+                        asn1_ps_func *suffix_free)
+{
+    return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
+}
+
+int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
+                        asn1_ps_func **psuffix_free)
+{
+    return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/bio_ndef.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/bio_ndef.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/bio_ndef.c	(revision 331)
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2008-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 <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+
+#include <stdio.h>
+
+/* Experimental NDEF ASN1 BIO support routines */
+
+/*
+ * The usage is quite simple, initialize an ASN1 structure, get a BIO from it
+ * then any data written through the BIO will end up translated to
+ * appropriate format on the fly. The data is streamed out and does *not*
+ * need to be all held in memory at once. When the BIO is flushed the output
+ * is finalized and any signatures etc written out. The BIO is a 'proper'
+ * BIO and can handle non blocking I/O correctly. The usage is simple. The
+ * implementation is *not*...
+ */
+
+/* BIO support data stored in the ASN1 BIO ex_arg */
+
+typedef struct ndef_aux_st {
+    /* ASN1 structure this BIO refers to */
+    ASN1_VALUE *val;
+    const ASN1_ITEM *it;
+    /* Top of the BIO chain */
+    BIO *ndef_bio;
+    /* Output BIO */
+    BIO *out;
+    /* Boundary where content is inserted */
+    unsigned char **boundary;
+    /* DER buffer start */
+    unsigned char *derbuf;
+} NDEF_SUPPORT;
+
+static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen,
+                            void *parg);
+static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
+                            void *parg);
+
+BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
+{
+    NDEF_SUPPORT *ndef_aux = NULL;
+    BIO *asn_bio = NULL;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_STREAM_ARG sarg;
+
+    if (!aux || !aux->asn1_cb) {
+        ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
+        return NULL;
+    }
+    ndef_aux = OPENSSL_zalloc(sizeof(*ndef_aux));
+    asn_bio = BIO_new(BIO_f_asn1());
+    if (ndef_aux == NULL || asn_bio == NULL)
+        goto err;
+
+    /* ASN1 bio needs to be next to output BIO */
+    out = BIO_push(asn_bio, out);
+    if (out == NULL)
+        goto err;
+
+    BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
+    BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
+
+    /*
+     * Now let callback prepends any digest, cipher etc BIOs ASN1 structure
+     * needs.
+     */
+
+    sarg.out = out;
+    sarg.ndef_bio = NULL;
+    sarg.boundary = NULL;
+
+    if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
+        goto err;
+
+    ndef_aux->val = val;
+    ndef_aux->it = it;
+    ndef_aux->ndef_bio = sarg.ndef_bio;
+    ndef_aux->boundary = sarg.boundary;
+    ndef_aux->out = out;
+
+    BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
+
+    return sarg.ndef_bio;
+
+ err:
+    BIO_free(asn_bio);
+    OPENSSL_free(ndef_aux);
+    return NULL;
+}
+
+static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+{
+    NDEF_SUPPORT *ndef_aux;
+    unsigned char *p;
+    int derlen;
+
+    if (!parg)
+        return 0;
+
+    ndef_aux = *(NDEF_SUPPORT **)parg;
+
+    derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+    p = OPENSSL_malloc(derlen);
+    if (p == NULL)
+        return 0;
+
+    ndef_aux->derbuf = p;
+    *pbuf = p;
+    derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
+
+    if (!*ndef_aux->boundary)
+        return 0;
+
+    *plen = *ndef_aux->boundary - *pbuf;
+
+    return 1;
+}
+
+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen,
+                            void *parg)
+{
+    NDEF_SUPPORT *ndef_aux;
+
+    if (!parg)
+        return 0;
+
+    ndef_aux = *(NDEF_SUPPORT **)parg;
+
+    OPENSSL_free(ndef_aux->derbuf);
+
+    ndef_aux->derbuf = NULL;
+    *pbuf = NULL;
+    *plen = 0;
+    return 1;
+}
+
+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
+                            void *parg)
+{
+    NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
+    if (!ndef_prefix_free(b, pbuf, plen, parg))
+        return 0;
+    OPENSSL_free(*pndef_aux);
+    *pndef_aux = NULL;
+    return 1;
+}
+
+static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+{
+    NDEF_SUPPORT *ndef_aux;
+    unsigned char *p;
+    int derlen;
+    const ASN1_AUX *aux;
+    ASN1_STREAM_ARG sarg;
+
+    if (!parg)
+        return 0;
+
+    ndef_aux = *(NDEF_SUPPORT **)parg;
+
+    aux = ndef_aux->it->funcs;
+
+    /* Finalize structures */
+    sarg.ndef_bio = ndef_aux->ndef_bio;
+    sarg.out = ndef_aux->out;
+    sarg.boundary = ndef_aux->boundary;
+    if (aux->asn1_cb(ASN1_OP_STREAM_POST,
+                     &ndef_aux->val, ndef_aux->it, &sarg) <= 0)
+        return 0;
+
+    derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+    p = OPENSSL_malloc(derlen);
+    if (p == NULL)
+        return 0;
+
+    ndef_aux->derbuf = p;
+    *pbuf = p;
+    derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
+
+    if (!*ndef_aux->boundary)
+        return 0;
+    *pbuf = *ndef_aux->boundary;
+    *plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
+
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/charmap.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/charmap.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/charmap.h	(revision 331)
@@ -0,0 +1,34 @@
+/*
+ * WARNING: do not edit!
+ * Generated by crypto/asn1/charmap.pl
+ *
+ * Copyright 2000-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
+ */
+
+#define CHARTYPE_HOST_ANY 4096
+#define CHARTYPE_HOST_DOT 8192
+#define CHARTYPE_HOST_HYPHEN 16384
+#define CHARTYPE_HOST_WILD 32768
+
+/*
+ * Mask of various character properties
+ */
+
+static const unsigned short char_type[] = {
+    1026,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+       2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+       2,    2,    2,    2,    2,    2,    2,    2,  120,    0,    1,   40,
+       0,    0,    0,   16, 1040, 1040, 33792,   25,   25, 16400, 8208,   16,
+    4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112,   16,    9,
+       9,   16,    9,   16,    0, 4112, 4112, 4112, 4112, 4112, 4112, 4112,
+    4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112,
+    4112, 4112, 4112, 4112, 4112, 4112, 4112,    0, 1025,    0,    0,    0,
+       0, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112,
+    4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112,
+    4112, 4112, 4112,    0,    0,    0,    0,    2
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/d2i_pr.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/d2i_pr.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/d2i_pr.c	(revision 331)
@@ -0,0 +1,125 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/engine.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
+
+EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
+                         long length)
+{
+    EVP_PKEY *ret;
+    const unsigned char *p = *pp;
+
+    if ((a == NULL) || (*a == NULL)) {
+        if ((ret = EVP_PKEY_new()) == NULL) {
+            ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_EVP_LIB);
+            return (NULL);
+        }
+    } else {
+        ret = *a;
+#ifndef OPENSSL_NO_ENGINE
+        ENGINE_finish(ret->engine);
+        ret->engine = NULL;
+#endif
+    }
+
+    if (!EVP_PKEY_set_type(ret, type)) {
+        ASN1err(ASN1_F_D2I_PRIVATEKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
+        goto err;
+    }
+
+    if (!ret->ameth->old_priv_decode ||
+        !ret->ameth->old_priv_decode(ret, &p, length)) {
+        if (ret->ameth->priv_decode) {
+            EVP_PKEY *tmp;
+            PKCS8_PRIV_KEY_INFO *p8 = NULL;
+            p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
+            if (!p8)
+                goto err;
+            tmp = EVP_PKCS82PKEY(p8);
+            PKCS8_PRIV_KEY_INFO_free(p8);
+            if (tmp == NULL)
+                goto err;
+            EVP_PKEY_free(ret);
+            ret = tmp;
+        } else {
+            ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
+            goto err;
+        }
+    }
+    *pp = p;
+    if (a != NULL)
+        (*a) = ret;
+    return (ret);
+ err:
+    if (a == NULL || *a != ret)
+        EVP_PKEY_free(ret);
+    return (NULL);
+}
+
+/*
+ * This works like d2i_PrivateKey() except it automatically works out the
+ * type
+ */
+
+EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
+                             long length)
+{
+    STACK_OF(ASN1_TYPE) *inkey;
+    const unsigned char *p;
+    int keytype;
+    p = *pp;
+    /*
+     * Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by
+     * analyzing it we can determine the passed structure: this assumes the
+     * input is surrounded by an ASN1 SEQUENCE.
+     */
+    inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
+    p = *pp;
+    /*
+     * Since we only need to discern "traditional format" RSA and DSA keys we
+     * can just count the elements.
+     */
+    if (sk_ASN1_TYPE_num(inkey) == 6)
+        keytype = EVP_PKEY_DSA;
+    else if (sk_ASN1_TYPE_num(inkey) == 4)
+        keytype = EVP_PKEY_EC;
+    else if (sk_ASN1_TYPE_num(inkey) == 3) { /* This seems to be PKCS8, not
+                                              * traditional format */
+        PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
+        EVP_PKEY *ret;
+
+        sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
+        if (!p8) {
+            ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,
+                    ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+            return NULL;
+        }
+        ret = EVP_PKCS82PKEY(p8);
+        PKCS8_PRIV_KEY_INFO_free(p8);
+        if (ret == NULL)
+            return NULL;
+        *pp = p;
+        if (a) {
+            *a = ret;
+        }
+        return ret;
+    } else
+        keytype = EVP_PKEY_RSA;
+    sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
+    return d2i_PrivateKey(keytype, a, pp, length);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/d2i_pu.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/d2i_pu.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/d2i_pu.c	(revision 331)
@@ -0,0 +1,78 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/asn1.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/ec.h>
+
+#include "internal/evp_int.h"
+
+EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp,
+                        long length)
+{
+    EVP_PKEY *ret;
+
+    if ((a == NULL) || (*a == NULL)) {
+        if ((ret = EVP_PKEY_new()) == NULL) {
+            ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB);
+            return (NULL);
+        }
+    } else
+        ret = *a;
+
+    if (!EVP_PKEY_set_type(ret, type)) {
+        ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB);
+        goto err;
+    }
+
+    switch (EVP_PKEY_id(ret)) {
+#ifndef OPENSSL_NO_RSA
+    case EVP_PKEY_RSA:
+        if ((ret->pkey.rsa = d2i_RSAPublicKey(NULL, pp, length)) == NULL) {
+            ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
+            goto err;
+        }
+        break;
+#endif
+#ifndef OPENSSL_NO_DSA
+    case EVP_PKEY_DSA:
+        /* TMP UGLY CAST */
+        if (!d2i_DSAPublicKey(&ret->pkey.dsa, pp, length)) {
+            ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
+            goto err;
+        }
+        break;
+#endif
+#ifndef OPENSSL_NO_EC
+    case EVP_PKEY_EC:
+        if (!o2i_ECPublicKey(&ret->pkey.ec, pp, length)) {
+            ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
+            goto err;
+        }
+        break;
+#endif
+    default:
+        ASN1err(ASN1_F_D2I_PUBLICKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
+        goto err;
+        /* break; */
+    }
+    if (a != NULL)
+        (*a) = ret;
+    return (ret);
+ err:
+    if (a == NULL || *a != ret)
+        EVP_PKEY_free(ret);
+    return (NULL);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/evp_asn1.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/evp_asn1.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/evp_asn1.c	(revision 331)
@@ -0,0 +1,115 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+
+int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len)
+{
+    ASN1_STRING *os;
+
+    if ((os = ASN1_OCTET_STRING_new()) == NULL)
+        return (0);
+    if (!ASN1_OCTET_STRING_set(os, data, len)) {
+        ASN1_OCTET_STRING_free(os);
+        return 0;
+    }
+    ASN1_TYPE_set(a, V_ASN1_OCTET_STRING, os);
+    return (1);
+}
+
+/* int max_len:  for returned value    */
+int ASN1_TYPE_get_octetstring(const ASN1_TYPE *a, unsigned char *data, int max_len)
+{
+    int ret, num;
+    const unsigned char *p;
+
+    if ((a->type != V_ASN1_OCTET_STRING) || (a->value.octet_string == NULL)) {
+        ASN1err(ASN1_F_ASN1_TYPE_GET_OCTETSTRING, ASN1_R_DATA_IS_WRONG);
+        return (-1);
+    }
+    p = ASN1_STRING_get0_data(a->value.octet_string);
+    ret = ASN1_STRING_length(a->value.octet_string);
+    if (ret < max_len)
+        num = ret;
+    else
+        num = max_len;
+    memcpy(data, p, num);
+    return (ret);
+}
+
+typedef struct {
+    long num;
+    ASN1_OCTET_STRING *oct;
+} asn1_int_oct;
+
+ASN1_SEQUENCE(asn1_int_oct) = {
+        ASN1_SIMPLE(asn1_int_oct, num, LONG),
+        ASN1_SIMPLE(asn1_int_oct, oct, ASN1_OCTET_STRING)
+} static_ASN1_SEQUENCE_END(asn1_int_oct)
+
+DECLARE_ASN1_ITEM(asn1_int_oct)
+
+int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, unsigned char *data,
+                                  int len)
+{
+    asn1_int_oct atmp;
+    ASN1_OCTET_STRING oct;
+
+    atmp.num = num;
+    atmp.oct = &oct;
+    oct.data = data;
+    oct.type = V_ASN1_OCTET_STRING;
+    oct.length = len;
+    oct.flags = 0;
+
+    if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(asn1_int_oct), &atmp, &a))
+        return 1;
+    return 0;
+}
+
+/*
+ * we return the actual length...
+ */
+/* int max_len:  for returned value    */
+int ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *a, long *num,
+                                  unsigned char *data, int max_len)
+{
+    asn1_int_oct *atmp = NULL;
+    int ret = -1, n;
+
+    if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL)) {
+        goto err;
+    }
+
+    atmp = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(asn1_int_oct), a);
+
+    if (atmp == NULL)
+        goto err;
+
+    if (num != NULL)
+        *num = atmp->num;
+
+    ret = ASN1_STRING_length(atmp->oct);
+    if (max_len > ret)
+        n = ret;
+    else
+        n = max_len;
+
+    if (data != NULL)
+        memcpy(data, ASN1_STRING_get0_data(atmp->oct), n);
+    if (ret == -1) {
+ err:
+        ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING, ASN1_R_DATA_IS_WRONG);
+    }
+    M_ASN1_free_of(atmp, asn1_int_oct);
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/f_int.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/f_int.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/f_int.c	(revision 331)
@@ -0,0 +1,167 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <ctype.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+
+int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a)
+{
+    int i, n = 0;
+    static const char *h = "0123456789ABCDEF";
+    char buf[2];
+
+    if (a == NULL)
+        return (0);
+
+    if (a->type & V_ASN1_NEG) {
+        if (BIO_write(bp, "-", 1) != 1)
+            goto err;
+        n = 1;
+    }
+
+    if (a->length == 0) {
+        if (BIO_write(bp, "00", 2) != 2)
+            goto err;
+        n += 2;
+    } else {
+        for (i = 0; i < a->length; i++) {
+            if ((i != 0) && (i % 35 == 0)) {
+                if (BIO_write(bp, "\\\n", 2) != 2)
+                    goto err;
+                n += 2;
+            }
+            buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
+            buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
+            if (BIO_write(bp, buf, 2) != 2)
+                goto err;
+            n += 2;
+        }
+    }
+    return (n);
+ err:
+    return (-1);
+}
+
+int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
+{
+    int i, j, k, m, n, again, bufsize;
+    unsigned char *s = NULL, *sp;
+    unsigned char *bufp;
+    int num = 0, slen = 0, first = 1;
+
+    bs->type = V_ASN1_INTEGER;
+
+    bufsize = BIO_gets(bp, buf, size);
+    for (;;) {
+        if (bufsize < 1)
+            goto err;
+        i = bufsize;
+        if (buf[i - 1] == '\n')
+            buf[--i] = '\0';
+        if (i == 0)
+            goto err;
+        if (buf[i - 1] == '\r')
+            buf[--i] = '\0';
+        if (i == 0)
+            goto err;
+        again = (buf[i - 1] == '\\');
+
+        for (j = 0; j < i; j++) {
+#ifndef CHARSET_EBCDIC
+            if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
+                  ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
+                  ((buf[j] >= 'A') && (buf[j] <= 'F'))))
+#else
+            /*
+             * This #ifdef is not strictly necessary, since the characters
+             * A...F a...f 0...9 are contiguous (yes, even in EBCDIC - but
+             * not the whole alphabet). Nevertheless, isxdigit() is faster.
+             */
+            if (!isxdigit(buf[j]))
+#endif
+            {
+                i = j;
+                break;
+            }
+        }
+        buf[i] = '\0';
+        /*
+         * We have now cleared all the crap off the end of the line
+         */
+        if (i < 2)
+            goto err;
+
+        bufp = (unsigned char *)buf;
+        if (first) {
+            first = 0;
+            if ((bufp[0] == '0') && (buf[1] == '0')) {
+                bufp += 2;
+                i -= 2;
+            }
+        }
+        k = 0;
+        i -= again;
+        if (i % 2 != 0) {
+            ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_ODD_NUMBER_OF_CHARS);
+            OPENSSL_free(s);
+            return 0;
+        }
+        i /= 2;
+        if (num + i > slen) {
+            sp = OPENSSL_clear_realloc(s, slen, num + i * 2);
+            if (sp == NULL) {
+                ASN1err(ASN1_F_A2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
+                OPENSSL_free(s);
+                return 0;
+            }
+            s = sp;
+            slen = num + i * 2;
+        }
+        for (j = 0; j < i; j++, k += 2) {
+            for (n = 0; n < 2; n++) {
+                m = OPENSSL_hexchar2int(bufp[k + n]);
+                if (m < 0) {
+                    ASN1err(ASN1_F_A2I_ASN1_INTEGER,
+                            ASN1_R_NON_HEX_CHARACTERS);
+                    goto err;
+                }
+                s[num + j] <<= 4;
+                s[num + j] |= m;
+            }
+        }
+        num += i;
+        if (again)
+            bufsize = BIO_gets(bp, buf, size);
+        else
+            break;
+    }
+    bs->length = num;
+    bs->data = s;
+    return 1;
+ err:
+    ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_SHORT_LINE);
+    OPENSSL_free(s);
+    return 0;
+}
+
+int i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a)
+{
+    return i2a_ASN1_INTEGER(bp, a);
+}
+
+int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
+{
+    int rv = a2i_ASN1_INTEGER(bp, bs, buf, size);
+    if (rv == 1)
+        bs->type = V_ASN1_INTEGER | (bs->type & V_ASN1_NEG);
+    return rv;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/f_string.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/f_string.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/f_string.c	(revision 331)
@@ -0,0 +1,148 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <ctype.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+
+int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type)
+{
+    int i, n = 0;
+    static const char *h = "0123456789ABCDEF";
+    char buf[2];
+
+    if (a == NULL)
+        return (0);
+
+    if (a->length == 0) {
+        if (BIO_write(bp, "0", 1) != 1)
+            goto err;
+        n = 1;
+    } else {
+        for (i = 0; i < a->length; i++) {
+            if ((i != 0) && (i % 35 == 0)) {
+                if (BIO_write(bp, "\\\n", 2) != 2)
+                    goto err;
+                n += 2;
+            }
+            buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
+            buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
+            if (BIO_write(bp, buf, 2) != 2)
+                goto err;
+            n += 2;
+        }
+    }
+    return (n);
+ err:
+    return (-1);
+}
+
+int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
+{
+    int i, j, k, m, n, again, bufsize, spec_char;
+    unsigned char *s = NULL, *sp;
+    unsigned char *bufp;
+    int num = 0, slen = 0, first = 1;
+
+    bufsize = BIO_gets(bp, buf, size);
+    for (;;) {
+        if (bufsize < 1) {
+            if (first)
+                break;
+            else
+                goto err;
+        }
+        first = 0;
+
+        i = bufsize;
+        if (buf[i - 1] == '\n')
+            buf[--i] = '\0';
+        if (i == 0)
+            goto err;
+        if (buf[i - 1] == '\r')
+            buf[--i] = '\0';
+        if (i == 0)
+            goto err;
+        again = (buf[i - 1] == '\\');
+
+        for (j = i - 1; j > 0; j--) {
+#ifndef CHARSET_EBCDIC
+            spec_char = (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
+                  ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
+                  ((buf[j] >= 'A') && (buf[j] <= 'F'))));
+#else
+            /*
+             * This #ifdef is not strictly necessary, since the characters
+             * A...F a...f 0...9 are contiguous (yes, even in EBCDIC - but
+             * not the whole alphabet). Nevertheless, isxdigit() is faster.
+             */
+            spec_char = (!isxdigit(buf[j]));
+#endif
+            if (spec_char) {
+                i = j;
+                break;
+            }
+        }
+        buf[i] = '\0';
+        /*
+         * We have now cleared all the crap off the end of the line
+         */
+        if (i < 2)
+            goto err;
+
+        bufp = (unsigned char *)buf;
+
+        k = 0;
+        i -= again;
+        if (i % 2 != 0) {
+            ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_ODD_NUMBER_OF_CHARS);
+            OPENSSL_free(s);
+            return 0;
+        }
+        i /= 2;
+        if (num + i > slen) {
+            sp = OPENSSL_realloc(s, (unsigned int)num + i * 2);
+            if (sp == NULL) {
+                ASN1err(ASN1_F_A2I_ASN1_STRING, ERR_R_MALLOC_FAILURE);
+                OPENSSL_free(s);
+                return 0;
+            }
+            s = sp;
+            slen = num + i * 2;
+        }
+        for (j = 0; j < i; j++, k += 2) {
+            for (n = 0; n < 2; n++) {
+                m = OPENSSL_hexchar2int(bufp[k + n]);
+                if (m < 0) {
+                    ASN1err(ASN1_F_A2I_ASN1_STRING,
+                            ASN1_R_NON_HEX_CHARACTERS);
+                    OPENSSL_free(s);
+                    return 0;
+                }
+                s[num + j] <<= 4;
+                s[num + j] |= m;
+            }
+        }
+        num += i;
+        if (again)
+            bufsize = BIO_gets(bp, buf, size);
+        else
+            break;
+    }
+    bs->length = num;
+    bs->data = s;
+    return 1;
+
+ err:
+    ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_SHORT_LINE);
+    OPENSSL_free(s);
+    return 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/i2d_pr.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/i2d_pr.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/i2d_pr.c	(revision 331)
@@ -0,0 +1,33 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
+
+int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
+{
+    if (a->ameth && a->ameth->old_priv_encode) {
+        return a->ameth->old_priv_encode(a, pp);
+    }
+    if (a->ameth && a->ameth->priv_encode) {
+        PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a);
+        int ret = 0;
+        if (p8 != NULL) {
+            ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp);
+            PKCS8_PRIV_KEY_INFO_free(p8);
+        }
+        return ret;
+    }
+    ASN1err(ASN1_F_I2D_PRIVATEKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+    return -1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/i2d_pu.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/i2d_pu.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/i2d_pu.c	(revision 331)
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/ec.h>
+
+int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp)
+{
+    switch (EVP_PKEY_id(a)) {
+#ifndef OPENSSL_NO_RSA
+    case EVP_PKEY_RSA:
+        return i2d_RSAPublicKey(EVP_PKEY_get0_RSA(a), pp);
+#endif
+#ifndef OPENSSL_NO_DSA
+    case EVP_PKEY_DSA:
+        return i2d_DSAPublicKey(EVP_PKEY_get0_DSA(a), pp);
+#endif
+#ifndef OPENSSL_NO_EC
+    case EVP_PKEY_EC:
+        return i2o_ECPublicKey(EVP_PKEY_get0_EC_KEY(a), pp);
+#endif
+    default:
+        ASN1err(ASN1_F_I2D_PUBLICKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+        return -1;
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/n_pkey.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/n_pkey.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/n_pkey.c	(revision 331)
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1995-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 "openssl/opensslconf.h"
+#ifdef OPENSSL_NO_RSA
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include "internal/cryptlib.h"
+# include <stdio.h>
+# include <openssl/rsa.h>
+# include <openssl/objects.h>
+# include <openssl/asn1t.h>
+# include <openssl/evp.h>
+# include <openssl/x509.h>
+
+# ifndef OPENSSL_NO_RC4
+
+typedef struct netscape_pkey_st {
+    long version;
+    X509_ALGOR *algor;
+    ASN1_OCTET_STRING *private_key;
+} NETSCAPE_PKEY;
+
+typedef struct netscape_encrypted_pkey_st {
+    ASN1_OCTET_STRING *os;
+    /*
+     * This is the same structure as DigestInfo so use it: although this
+     * isn't really anything to do with digests.
+     */
+    X509_SIG *enckey;
+} NETSCAPE_ENCRYPTED_PKEY;
+
+
+ASN1_BROKEN_SEQUENCE(NETSCAPE_ENCRYPTED_PKEY) = {
+        ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, os, ASN1_OCTET_STRING),
+        ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, enckey, X509_SIG)
+} static_ASN1_BROKEN_SEQUENCE_END(NETSCAPE_ENCRYPTED_PKEY)
+
+DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY,NETSCAPE_ENCRYPTED_PKEY)
+IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)
+
+ASN1_SEQUENCE(NETSCAPE_PKEY) = {
+        ASN1_SIMPLE(NETSCAPE_PKEY, version, LONG),
+        ASN1_SIMPLE(NETSCAPE_PKEY, algor, X509_ALGOR),
+        ASN1_SIMPLE(NETSCAPE_PKEY, private_key, ASN1_OCTET_STRING)
+} static_ASN1_SEQUENCE_END(NETSCAPE_PKEY)
+
+DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_PKEY,NETSCAPE_PKEY)
+IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)
+
+# endif                         /* OPENSSL_NO_RC4 */
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/nsseq.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/nsseq.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/nsseq.c	(revision 331)
@@ -0,0 +1,34 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include <stdlib.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+
+static int nsseq_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                    void *exarg)
+{
+    if (operation == ASN1_OP_NEW_POST) {
+        NETSCAPE_CERT_SEQUENCE *nsseq;
+        nsseq = (NETSCAPE_CERT_SEQUENCE *)*pval;
+        nsseq->type = OBJ_nid2obj(NID_netscape_cert_sequence);
+    }
+    return 1;
+}
+
+/* Netscape certificate sequence structure */
+
+ASN1_SEQUENCE_cb(NETSCAPE_CERT_SEQUENCE, nsseq_cb) = {
+        ASN1_SIMPLE(NETSCAPE_CERT_SEQUENCE, type, ASN1_OBJECT),
+        ASN1_EXP_SEQUENCE_OF_OPT(NETSCAPE_CERT_SEQUENCE, certs, X509, 0)
+} ASN1_SEQUENCE_END_cb(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE)
+
+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/p5_pbe.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/p5_pbe.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/p5_pbe.c	(revision 331)
@@ -0,0 +1,96 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/rand.h>
+
+/* PKCS#5 password based encryption structure */
+
+ASN1_SEQUENCE(PBEPARAM) = {
+        ASN1_SIMPLE(PBEPARAM, salt, ASN1_OCTET_STRING),
+        ASN1_SIMPLE(PBEPARAM, iter, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(PBEPARAM)
+
+IMPLEMENT_ASN1_FUNCTIONS(PBEPARAM)
+
+/* Set an algorithm identifier for a PKCS#5 PBE algorithm */
+
+int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
+                         const unsigned char *salt, int saltlen)
+{
+    PBEPARAM *pbe = NULL;
+    ASN1_STRING *pbe_str = NULL;
+    unsigned char *sstr = NULL;
+
+    pbe = PBEPARAM_new();
+    if (pbe == NULL) {
+        ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if (iter <= 0)
+        iter = PKCS5_DEFAULT_ITER;
+    if (!ASN1_INTEGER_set(pbe->iter, iter)) {
+        ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if (!saltlen)
+        saltlen = PKCS5_SALT_LEN;
+
+    sstr = OPENSSL_malloc(saltlen);
+    if (sstr == NULL) {
+        ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if (salt)
+        memcpy(sstr, salt, saltlen);
+    else if (RAND_bytes(sstr, saltlen) <= 0)
+        goto err;
+
+    ASN1_STRING_set0(pbe->salt, sstr, saltlen);
+    sstr = NULL;
+
+    if (!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) {
+        ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    PBEPARAM_free(pbe);
+    pbe = NULL;
+
+    if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str))
+        return 1;
+
+ err:
+    OPENSSL_free(sstr);
+    PBEPARAM_free(pbe);
+    ASN1_STRING_free(pbe_str);
+    return 0;
+}
+
+/* Return an algorithm identifier for a PKCS#5 PBE algorithm */
+
+X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
+                          const unsigned char *salt, int saltlen)
+{
+    X509_ALGOR *ret;
+    ret = X509_ALGOR_new();
+    if (ret == NULL) {
+        ASN1err(ASN1_F_PKCS5_PBE_SET, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen))
+        return ret;
+
+    X509_ALGOR_free(ret);
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/p5_pbev2.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/p5_pbev2.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/p5_pbev2.c	(revision 331)
@@ -0,0 +1,221 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/rand.h>
+
+/* PKCS#5 v2.0 password based encryption structures */
+
+ASN1_SEQUENCE(PBE2PARAM) = {
+        ASN1_SIMPLE(PBE2PARAM, keyfunc, X509_ALGOR),
+        ASN1_SIMPLE(PBE2PARAM, encryption, X509_ALGOR)
+} ASN1_SEQUENCE_END(PBE2PARAM)
+
+IMPLEMENT_ASN1_FUNCTIONS(PBE2PARAM)
+
+ASN1_SEQUENCE(PBKDF2PARAM) = {
+        ASN1_SIMPLE(PBKDF2PARAM, salt, ASN1_ANY),
+        ASN1_SIMPLE(PBKDF2PARAM, iter, ASN1_INTEGER),
+        ASN1_OPT(PBKDF2PARAM, keylength, ASN1_INTEGER),
+        ASN1_OPT(PBKDF2PARAM, prf, X509_ALGOR)
+} ASN1_SEQUENCE_END(PBKDF2PARAM)
+
+IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM)
+
+/*
+ * Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm: yes I know
+ * this is horrible! Extended version to allow application supplied PRF NID
+ * and IV.
+ */
+
+X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
+                              unsigned char *salt, int saltlen,
+                              unsigned char *aiv, int prf_nid)
+{
+    X509_ALGOR *scheme = NULL, *ret = NULL;
+    int alg_nid, keylen;
+    EVP_CIPHER_CTX *ctx = NULL;
+    unsigned char iv[EVP_MAX_IV_LENGTH];
+    PBE2PARAM *pbe2 = NULL;
+
+    alg_nid = EVP_CIPHER_type(cipher);
+    if (alg_nid == NID_undef) {
+        ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
+                ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
+        goto err;
+    }
+
+    if ((pbe2 = PBE2PARAM_new()) == NULL)
+        goto merr;
+
+    /* Setup the AlgorithmIdentifier for the encryption scheme */
+    scheme = pbe2->encryption;
+    scheme->algorithm = OBJ_nid2obj(alg_nid);
+    if ((scheme->parameter = ASN1_TYPE_new()) == NULL)
+        goto merr;
+
+    /* Create random IV */
+    if (EVP_CIPHER_iv_length(cipher)) {
+        if (aiv)
+            memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
+        else if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) <= 0)
+            goto err;
+    }
+
+    ctx = EVP_CIPHER_CTX_new();
+    if (ctx == NULL)
+        goto merr;
+
+    /* Dummy cipherinit to just setup the IV, and PRF */
+    if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, iv, 0))
+        goto err;
+    if (EVP_CIPHER_param_to_asn1(ctx, scheme->parameter) < 0) {
+        ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
+        goto err;
+    }
+    /*
+     * If prf NID unspecified see if cipher has a preference. An error is OK
+     * here: just means use default PRF.
+     */
+    if ((prf_nid == -1) &&
+        EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) {
+        ERR_clear_error();
+        prf_nid = NID_hmacWithSHA256;
+    }
+    EVP_CIPHER_CTX_free(ctx);
+    ctx = NULL;
+
+    /* If its RC2 then we'd better setup the key length */
+
+    if (alg_nid == NID_rc2_cbc)
+        keylen = EVP_CIPHER_key_length(cipher);
+    else
+        keylen = -1;
+
+    /* Setup keyfunc */
+
+    X509_ALGOR_free(pbe2->keyfunc);
+
+    pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen);
+
+    if (!pbe2->keyfunc)
+        goto merr;
+
+    /* Now set up top level AlgorithmIdentifier */
+
+    if ((ret = X509_ALGOR_new()) == NULL)
+        goto merr;
+
+    ret->algorithm = OBJ_nid2obj(NID_pbes2);
+
+    /* Encode PBE2PARAM into parameter */
+
+    if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM), pbe2,
+                                 &ret->parameter))
+         goto merr;
+
+    PBE2PARAM_free(pbe2);
+    pbe2 = NULL;
+
+    return ret;
+
+ merr:
+    ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ERR_R_MALLOC_FAILURE);
+
+ err:
+    EVP_CIPHER_CTX_free(ctx);
+    PBE2PARAM_free(pbe2);
+    /* Note 'scheme' is freed as part of pbe2 */
+    X509_ALGOR_free(ret);
+
+    return NULL;
+}
+
+X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
+                           unsigned char *salt, int saltlen)
+{
+    return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1);
+}
+
+X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
+                             int prf_nid, int keylen)
+{
+    X509_ALGOR *keyfunc = NULL;
+    PBKDF2PARAM *kdf = NULL;
+    ASN1_OCTET_STRING *osalt = NULL;
+
+    if ((kdf = PBKDF2PARAM_new()) == NULL)
+        goto merr;
+    if ((osalt = ASN1_OCTET_STRING_new()) == NULL)
+        goto merr;
+
+    kdf->salt->value.octet_string = osalt;
+    kdf->salt->type = V_ASN1_OCTET_STRING;
+
+    if (saltlen == 0)
+        saltlen = PKCS5_SALT_LEN;
+    if ((osalt->data = OPENSSL_malloc(saltlen)) == NULL)
+        goto merr;
+
+    osalt->length = saltlen;
+
+    if (salt)
+        memcpy(osalt->data, salt, saltlen);
+    else if (RAND_bytes(osalt->data, saltlen) <= 0)
+        goto merr;
+
+    if (iter <= 0)
+        iter = PKCS5_DEFAULT_ITER;
+
+    if (!ASN1_INTEGER_set(kdf->iter, iter))
+        goto merr;
+
+    /* If have a key len set it up */
+
+    if (keylen > 0) {
+        if ((kdf->keylength = ASN1_INTEGER_new()) == NULL)
+            goto merr;
+        if (!ASN1_INTEGER_set(kdf->keylength, keylen))
+            goto merr;
+    }
+
+    /* prf can stay NULL if we are using hmacWithSHA1 */
+    if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1) {
+        kdf->prf = X509_ALGOR_new();
+        if (kdf->prf == NULL)
+            goto merr;
+        X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid), V_ASN1_NULL, NULL);
+    }
+
+    /* Finally setup the keyfunc structure */
+
+    keyfunc = X509_ALGOR_new();
+    if (keyfunc == NULL)
+        goto merr;
+
+    keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);
+
+    /* Encode PBKDF2PARAM into parameter of pbe2 */
+
+    if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBKDF2PARAM), kdf,
+                                 &keyfunc->parameter))
+         goto merr;
+
+    PBKDF2PARAM_free(kdf);
+    return keyfunc;
+
+ merr:
+    ASN1err(ASN1_F_PKCS5_PBKDF2_SET, ERR_R_MALLOC_FAILURE);
+    PBKDF2PARAM_free(kdf);
+    X509_ALGOR_free(keyfunc);
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/p5_scrypt.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/p5_scrypt.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/p5_scrypt.c	(revision 331)
@@ -0,0 +1,283 @@
+/*
+ * Copyright 2015-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/rand.h>
+
+#ifndef OPENSSL_NO_SCRYPT
+/* PKCS#5 scrypt password based encryption structures */
+
+typedef struct {
+    ASN1_OCTET_STRING *salt;
+    ASN1_INTEGER *costParameter;
+    ASN1_INTEGER *blockSize;
+    ASN1_INTEGER *parallelizationParameter;
+    ASN1_INTEGER *keyLength;
+} SCRYPT_PARAMS;
+
+ASN1_SEQUENCE(SCRYPT_PARAMS) = {
+        ASN1_SIMPLE(SCRYPT_PARAMS, salt, ASN1_OCTET_STRING),
+        ASN1_SIMPLE(SCRYPT_PARAMS, costParameter, ASN1_INTEGER),
+        ASN1_SIMPLE(SCRYPT_PARAMS, blockSize, ASN1_INTEGER),
+        ASN1_SIMPLE(SCRYPT_PARAMS, parallelizationParameter, ASN1_INTEGER),
+        ASN1_OPT(SCRYPT_PARAMS, keyLength, ASN1_INTEGER),
+} static_ASN1_SEQUENCE_END(SCRYPT_PARAMS)
+
+DECLARE_ASN1_ALLOC_FUNCTIONS(SCRYPT_PARAMS)
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(SCRYPT_PARAMS)
+
+static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, size_t saltlen,
+                                    size_t keylen, uint64_t N, uint64_t r,
+                                    uint64_t p);
+
+/*
+ * Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm using scrypt
+ */
+
+X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher,
+                                  const unsigned char *salt, int saltlen,
+                                  unsigned char *aiv, uint64_t N, uint64_t r,
+                                  uint64_t p)
+{
+    X509_ALGOR *scheme = NULL, *ret = NULL;
+    int alg_nid;
+    size_t keylen = 0;
+    EVP_CIPHER_CTX *ctx = NULL;
+    unsigned char iv[EVP_MAX_IV_LENGTH];
+    PBE2PARAM *pbe2 = NULL;
+
+    if (!cipher) {
+        ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ERR_R_PASSED_NULL_PARAMETER);
+        goto err;
+    }
+
+    if (EVP_PBE_scrypt(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0) == 0) {
+        ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT,
+                ASN1_R_INVALID_SCRYPT_PARAMETERS);
+        goto err;
+    }
+
+    alg_nid = EVP_CIPHER_type(cipher);
+    if (alg_nid == NID_undef) {
+        ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT,
+                ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
+        goto err;
+    }
+
+    pbe2 = PBE2PARAM_new();
+    if (pbe2 == NULL)
+        goto merr;
+
+    /* Setup the AlgorithmIdentifier for the encryption scheme */
+    scheme = pbe2->encryption;
+
+    scheme->algorithm = OBJ_nid2obj(alg_nid);
+    scheme->parameter = ASN1_TYPE_new();
+    if (scheme->parameter == NULL)
+        goto merr;
+
+    /* Create random IV */
+    if (EVP_CIPHER_iv_length(cipher)) {
+        if (aiv)
+            memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
+        else if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
+            goto err;
+    }
+
+    ctx = EVP_CIPHER_CTX_new();
+    if (ctx == NULL)
+        goto merr;
+
+    /* Dummy cipherinit to just setup the IV */
+    if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, iv, 0) == 0)
+        goto err;
+    if (EVP_CIPHER_param_to_asn1(ctx, scheme->parameter) < 0) {
+        ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT,
+                ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
+        goto err;
+    }
+    EVP_CIPHER_CTX_free(ctx);
+    ctx = NULL;
+
+    /* If its RC2 then we'd better setup the key length */
+
+    if (alg_nid == NID_rc2_cbc)
+        keylen = EVP_CIPHER_key_length(cipher);
+
+    /* Setup keyfunc */
+
+    X509_ALGOR_free(pbe2->keyfunc);
+
+    pbe2->keyfunc = pkcs5_scrypt_set(salt, saltlen, keylen, N, r, p);
+
+    if (pbe2->keyfunc == NULL)
+        goto merr;
+
+    /* Now set up top level AlgorithmIdentifier */
+
+    ret = X509_ALGOR_new();
+    if (ret == NULL)
+        goto merr;
+
+    ret->algorithm = OBJ_nid2obj(NID_pbes2);
+
+    /* Encode PBE2PARAM into parameter */
+
+    if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBE2PARAM), pbe2,
+                                &ret->parameter) == NULL)
+        goto merr;
+
+    PBE2PARAM_free(pbe2);
+    pbe2 = NULL;
+
+    return ret;
+
+ merr:
+    ASN1err(ASN1_F_PKCS5_PBE2_SET_SCRYPT, ERR_R_MALLOC_FAILURE);
+
+ err:
+    PBE2PARAM_free(pbe2);
+    X509_ALGOR_free(ret);
+    EVP_CIPHER_CTX_free(ctx);
+
+    return NULL;
+}
+
+static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, size_t saltlen,
+                                    size_t keylen, uint64_t N, uint64_t r,
+                                    uint64_t p)
+{
+    X509_ALGOR *keyfunc = NULL;
+    SCRYPT_PARAMS *sparam = SCRYPT_PARAMS_new();
+
+    if (sparam == NULL)
+        goto merr;
+
+    if (!saltlen)
+        saltlen = PKCS5_SALT_LEN;
+
+    /* This will either copy salt or grow the buffer */
+    if (ASN1_STRING_set(sparam->salt, salt, saltlen) == 0)
+        goto merr;
+
+    if (salt == NULL && RAND_bytes(sparam->salt->data, saltlen) <= 0)
+        goto err;
+
+    if (ASN1_INTEGER_set_uint64(sparam->costParameter, N) == 0)
+        goto merr;
+
+    if (ASN1_INTEGER_set_uint64(sparam->blockSize, r) == 0)
+        goto merr;
+
+    if (ASN1_INTEGER_set_uint64(sparam->parallelizationParameter, p) == 0)
+        goto merr;
+
+    /* If have a key len set it up */
+
+    if (keylen > 0) {
+        sparam->keyLength = ASN1_INTEGER_new();
+        if (sparam->keyLength == NULL)
+            goto merr;
+        if (ASN1_INTEGER_set_int64(sparam->keyLength, keylen) == 0)
+            goto merr;
+    }
+
+    /* Finally setup the keyfunc structure */
+
+    keyfunc = X509_ALGOR_new();
+    if (keyfunc == NULL)
+        goto merr;
+
+    keyfunc->algorithm = OBJ_nid2obj(NID_id_scrypt);
+
+    /* Encode SCRYPT_PARAMS into parameter of pbe2 */
+
+    if (ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(SCRYPT_PARAMS), sparam,
+                                &keyfunc->parameter) == NULL)
+        goto merr;
+
+    SCRYPT_PARAMS_free(sparam);
+    return keyfunc;
+
+ merr:
+    ASN1err(ASN1_F_PKCS5_SCRYPT_SET, ERR_R_MALLOC_FAILURE);
+ err:
+    SCRYPT_PARAMS_free(sparam);
+    X509_ALGOR_free(keyfunc);
+    return NULL;
+}
+
+int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
+                             int passlen, ASN1_TYPE *param,
+                             const EVP_CIPHER *c, const EVP_MD *md, int en_de)
+{
+    unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
+    uint64_t p, r, N;
+    size_t saltlen;
+    size_t keylen = 0;
+    int rv = 0;
+    SCRYPT_PARAMS *sparam = NULL;
+
+    if (EVP_CIPHER_CTX_cipher(ctx) == NULL) {
+        EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, EVP_R_NO_CIPHER_SET);
+        goto err;
+    }
+
+    /* Decode parameter */
+
+    sparam = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(SCRYPT_PARAMS), param);
+
+    if (sparam == NULL) {
+        EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN, EVP_R_DECODE_ERROR);
+        goto err;
+    }
+
+    keylen = EVP_CIPHER_CTX_key_length(ctx);
+
+    /* Now check the parameters of sparam */
+
+    if (sparam->keyLength) {
+        uint64_t spkeylen;
+        if ((ASN1_INTEGER_get_uint64(&spkeylen, sparam->keyLength) == 0)
+            || (spkeylen != keylen)) {
+            EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN,
+                   EVP_R_UNSUPPORTED_KEYLENGTH);
+            goto err;
+        }
+    }
+    /* Check all parameters fit in uint64_t and are acceptable to scrypt */
+    if (ASN1_INTEGER_get_uint64(&N, sparam->costParameter) == 0
+        || ASN1_INTEGER_get_uint64(&r, sparam->blockSize) == 0
+        || ASN1_INTEGER_get_uint64(&p, sparam->parallelizationParameter) == 0
+        || EVP_PBE_scrypt(NULL, 0, NULL, 0, N, r, p, 0, NULL, 0) == 0) {
+        EVPerr(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN,
+               EVP_R_ILLEGAL_SCRYPT_PARAMETERS);
+        goto err;
+    }
+
+    /* it seems that its all OK */
+
+    salt = sparam->salt->data;
+    saltlen = sparam->salt->length;
+    if (EVP_PBE_scrypt(pass, passlen, salt, saltlen, N, r, p, 0, key, keylen)
+        == 0)
+        goto err;
+    rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
+ err:
+    if (keylen)
+        OPENSSL_cleanse(key, keylen);
+    SCRYPT_PARAMS_free(sparam);
+    return rv;
+}
+#endif /* OPENSSL_NO_SCRYPT */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/p8_pkey.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/p8_pkey.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/p8_pkey.c	(revision 331)
@@ -0,0 +1,80 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+
+/* Minor tweak to operation: zero private key data */
+static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                   void *exarg)
+{
+    /* Since the structure must still be valid use ASN1_OP_FREE_PRE */
+    if (operation == ASN1_OP_FREE_PRE) {
+        PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval;
+        if (key->pkey)
+            OPENSSL_cleanse(key->pkey->data, key->pkey->length);
+    }
+    return 1;
+}
+
+ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = {
+        ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, version, ASN1_INTEGER),
+        ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkeyalg, X509_ALGOR),
+        ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_OCTET_STRING),
+        ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0)
+} ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
+
+int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
+                    int version,
+                    int ptype, void *pval, unsigned char *penc, int penclen)
+{
+    if (version >= 0) {
+        if (!ASN1_INTEGER_set(priv->version, version))
+            return 0;
+    }
+    if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval))
+        return 0;
+    if (penc)
+        ASN1_STRING_set0(priv->pkey, penc, penclen);
+    return 1;
+}
+
+int PKCS8_pkey_get0(const ASN1_OBJECT **ppkalg,
+                    const unsigned char **pk, int *ppklen,
+                    const X509_ALGOR **pa, const PKCS8_PRIV_KEY_INFO *p8)
+{
+    if (ppkalg)
+        *ppkalg = p8->pkeyalg->algorithm;
+    if (pk) {
+        *pk = ASN1_STRING_get0_data(p8->pkey);
+        *ppklen = ASN1_STRING_length(p8->pkey);
+    }
+    if (pa)
+        *pa = p8->pkeyalg;
+    return 1;
+}
+
+const STACK_OF(X509_ATTRIBUTE) *
+PKCS8_pkey_get0_attrs(const PKCS8_PRIV_KEY_INFO *p8)
+{
+    return p8->attributes;
+}
+
+int PKCS8_pkey_add1_attr_by_NID(PKCS8_PRIV_KEY_INFO *p8, int nid, int type,
+                                const unsigned char *bytes, int len)
+{
+    if (X509at_add1_attr_by_NID(&p8->attributes, nid, type, bytes, len) != NULL)
+        return 1;
+    return 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/t_bitst.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/t_bitst.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/t_bitst.c	(revision 331)
@@ -0,0 +1,56 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
+                               BIT_STRING_BITNAME *tbl, int indent)
+{
+    BIT_STRING_BITNAME *bnam;
+    char first = 1;
+    BIO_printf(out, "%*s", indent, "");
+    for (bnam = tbl; bnam->lname; bnam++) {
+        if (ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
+            if (!first)
+                BIO_puts(out, ", ");
+            BIO_puts(out, bnam->lname);
+            first = 0;
+        }
+    }
+    BIO_puts(out, "\n");
+    return 1;
+}
+
+int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, const char *name, int value,
+                            BIT_STRING_BITNAME *tbl)
+{
+    int bitnum;
+    bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
+    if (bitnum < 0)
+        return 0;
+    if (bs) {
+        if (!ASN1_BIT_STRING_set_bit(bs, bitnum, value))
+            return 0;
+    }
+    return 1;
+}
+
+int ASN1_BIT_STRING_num_asc(const char *name, BIT_STRING_BITNAME *tbl)
+{
+    BIT_STRING_BITNAME *bnam;
+    for (bnam = tbl; bnam->lname; bnam++) {
+        if ((strcmp(bnam->sname, name) == 0)
+            || (strcmp(bnam->lname, name) == 0))
+            return bnam->bitnum;
+    }
+    return -1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/t_pkey.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/t_pkey.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/t_pkey.c	(revision 331)
@@ -0,0 +1,93 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include "internal/bn_int.h"
+
+/* Number of octets per line */
+#define ASN1_BUF_PRINT_WIDTH    15
+/* Maximum indent */
+#define ASN1_PRINT_MAX_INDENT 128
+
+int ASN1_buf_print(BIO *bp, const unsigned char *buf, size_t buflen, int indent)
+{
+    size_t i;
+
+    for (i = 0; i < buflen; i++) {
+        if ((i % ASN1_BUF_PRINT_WIDTH) == 0) {
+            if (i > 0 && BIO_puts(bp, "\n") <= 0)
+                return 0;
+            if (!BIO_indent(bp, indent, ASN1_PRINT_MAX_INDENT))
+                return 0;
+        }
+        /*
+         * Use colon separators for each octet for compatibility as
+         * this function is used to print out key components.
+         */
+        if (BIO_printf(bp, "%02x%s", buf[i],
+                       (i == buflen - 1) ? "" : ":") <= 0)
+                return 0;
+    }
+    if (BIO_write(bp, "\n", 1) <= 0)
+        return 0;
+    return 1;
+}
+
+int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
+                  unsigned char *ign, int indent)
+{
+    int n, rv = 0;
+    const char *neg;
+    unsigned char *buf = NULL, *tmp = NULL;
+    int buflen;
+
+    if (num == NULL)
+        return 1;
+    neg = BN_is_negative(num) ? "-" : "";
+    if (!BIO_indent(bp, indent, ASN1_PRINT_MAX_INDENT))
+        return 0;
+    if (BN_is_zero(num)) {
+        if (BIO_printf(bp, "%s 0\n", number) <= 0)
+            return 0;
+        return 1;
+    }
+
+    if (BN_num_bytes(num) <= BN_BYTES) {
+        if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg,
+                       (unsigned long)bn_get_words(num)[0], neg,
+                       (unsigned long)bn_get_words(num)[0]) <= 0)
+            return 0;
+        return 1;
+    }
+
+    buflen = BN_num_bytes(num) + 1;
+    buf = tmp = OPENSSL_malloc(buflen);
+    if (buf == NULL)
+        goto err;
+    buf[0] = 0;
+    if (BIO_printf(bp, "%s%s\n", number,
+                   (neg[0] == '-') ? " (Negative)" : "") <= 0)
+        goto err;
+    n = BN_bn2bin(num, buf + 1);
+
+    if (buf[1] & 0x80)
+        n++;
+    else
+        tmp++;
+
+    if (ASN1_buf_print(bp, tmp, n, indent + 4) == 0)
+        goto err;
+    rv = 1;
+    err:
+    OPENSSL_clear_free(buf, buflen);
+    return rv;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/t_spki.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/t_spki.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/t_spki.c	(revision 331)
@@ -0,0 +1,56 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/bn.h>
+
+/* Print out an SPKI */
+
+int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki)
+{
+    EVP_PKEY *pkey;
+    ASN1_IA5STRING *chal;
+    ASN1_OBJECT *spkioid;
+    int i, n;
+    char *s;
+    BIO_printf(out, "Netscape SPKI:\n");
+    X509_PUBKEY_get0_param(&spkioid, NULL, NULL, NULL, spki->spkac->pubkey);
+    i = OBJ_obj2nid(spkioid);
+    BIO_printf(out, "  Public Key Algorithm: %s\n",
+               (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
+    pkey = X509_PUBKEY_get(spki->spkac->pubkey);
+    if (!pkey)
+        BIO_printf(out, "  Unable to load public key\n");
+    else {
+        EVP_PKEY_print_public(out, pkey, 4, NULL);
+        EVP_PKEY_free(pkey);
+    }
+    chal = spki->spkac->challenge;
+    if (chal->length)
+        BIO_printf(out, "  Challenge String: %s\n", chal->data);
+    i = OBJ_obj2nid(spki->sig_algor.algorithm);
+    BIO_printf(out, "  Signature Algorithm: %s",
+               (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
+
+    n = spki->signature->length;
+    s = (char *)spki->signature->data;
+    for (i = 0; i < n; i++) {
+        if ((i % 18) == 0)
+            BIO_write(out, "\n      ", 7);
+        BIO_printf(out, "%02x%s", (unsigned char)s[i],
+                   ((i + 1) == n) ? "" : ":");
+    }
+    BIO_write(out, "\n", 1);
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_dec.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_dec.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_dec.c	(revision 331)
@@ -0,0 +1,1142 @@
+/*
+ * Copyright 2000-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 <stddef.h>
+#include <string.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+#include "internal/numbers.h"
+#include "asn1_locl.h"
+
+static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
+                               long len, const ASN1_ITEM *it,
+                               int tag, int aclass, char opt, ASN1_TLC *ctx);
+
+static int asn1_check_eoc(const unsigned char **in, long len);
+static int asn1_find_end(const unsigned char **in, long len, char inf);
+
+static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
+                        char inf, int tag, int aclass, int depth);
+
+static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen);
+
+static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
+                           char *inf, char *cst,
+                           const unsigned char **in, long len,
+                           int exptag, int expclass, char opt, ASN1_TLC *ctx);
+
+static int asn1_template_ex_d2i(ASN1_VALUE **pval,
+                                const unsigned char **in, long len,
+                                const ASN1_TEMPLATE *tt, char opt,
+                                ASN1_TLC *ctx);
+static int asn1_template_noexp_d2i(ASN1_VALUE **val,
+                                   const unsigned char **in, long len,
+                                   const ASN1_TEMPLATE *tt, char opt,
+                                   ASN1_TLC *ctx);
+static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
+                                 const unsigned char **in, long len,
+                                 const ASN1_ITEM *it,
+                                 int tag, int aclass, char opt,
+                                 ASN1_TLC *ctx);
+static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                       int utype, char *free_cont, const ASN1_ITEM *it);
+
+/* Table to convert tags to bit values, used for MSTRING type */
+static const unsigned long tag2bit[32] = {
+    /* tags  0 -  3 */
+    0, 0, 0, B_ASN1_BIT_STRING,
+    /* tags  4- 7 */
+    B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN,
+    /* tags  8-11 */
+    B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,
+    /* tags 12-15 */
+    B_ASN1_UTF8STRING, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,
+    /* tags 16-19 */
+    B_ASN1_SEQUENCE, 0, B_ASN1_NUMERICSTRING, B_ASN1_PRINTABLESTRING,
+    /* tags 20-22 */
+    B_ASN1_T61STRING, B_ASN1_VIDEOTEXSTRING, B_ASN1_IA5STRING,
+    /* tags 23-24 */
+    B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME,
+    /* tags 25-27 */
+    B_ASN1_GRAPHICSTRING, B_ASN1_ISO64STRING, B_ASN1_GENERALSTRING,
+    /* tags 28-31 */
+    B_ASN1_UNIVERSALSTRING, B_ASN1_UNKNOWN, B_ASN1_BMPSTRING, B_ASN1_UNKNOWN,
+};
+
+unsigned long ASN1_tag2bit(int tag)
+{
+    if ((tag < 0) || (tag > 30))
+        return 0;
+    return tag2bit[tag];
+}
+
+/* Macro to initialize and invalidate the cache */
+
+#define asn1_tlc_clear(c)       if (c) (c)->valid = 0
+/* Version to avoid compiler warning about 'c' always non-NULL */
+#define asn1_tlc_clear_nc(c)    (c)->valid = 0
+
+/*
+ * Decode an ASN1 item, this currently behaves just like a standard 'd2i'
+ * function. 'in' points to a buffer to read the data from, in future we
+ * will have more advanced versions that can input data a piece at a time and
+ * this will simply be a special case.
+ */
+
+ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval,
+                          const unsigned char **in, long len,
+                          const ASN1_ITEM *it)
+{
+    ASN1_TLC c;
+    ASN1_VALUE *ptmpval = NULL;
+    if (!pval)
+        pval = &ptmpval;
+    asn1_tlc_clear_nc(&c);
+    if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0)
+        return *pval;
+    return NULL;
+}
+
+int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
+                     const ASN1_ITEM *it,
+                     int tag, int aclass, char opt, ASN1_TLC *ctx)
+{
+    int rv;
+    rv = asn1_item_embed_d2i(pval, in, len, it, tag, aclass, opt, ctx);
+    if (rv <= 0)
+        ASN1_item_ex_free(pval, it);
+    return rv;
+}
+
+/*
+ * Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and
+ * tag mismatch return -1 to handle OPTIONAL
+ */
+
+static int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in,
+                               long len, const ASN1_ITEM *it,
+                               int tag, int aclass, char opt, ASN1_TLC *ctx)
+{
+    const ASN1_TEMPLATE *tt, *errtt = NULL;
+    const ASN1_EXTERN_FUNCS *ef;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_aux_cb *asn1_cb;
+    const unsigned char *p = NULL, *q;
+    unsigned char oclass;
+    char seq_eoc, seq_nolen, cst, isopt;
+    long tmplen;
+    int i;
+    int otag;
+    int ret = 0;
+    ASN1_VALUE **pchptr;
+    if (!pval)
+        return 0;
+    if (aux && aux->asn1_cb)
+        asn1_cb = aux->asn1_cb;
+    else
+        asn1_cb = 0;
+
+    switch (it->itype) {
+    case ASN1_ITYPE_PRIMITIVE:
+        if (it->templates) {
+            /*
+             * tagging or OPTIONAL is currently illegal on an item template
+             * because the flags can't get passed down. In practice this
+             * isn't a problem: we include the relevant flags from the item
+             * template in the template itself.
+             */
+            if ((tag != -1) || opt) {
+                ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I,
+                        ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
+                goto err;
+            }
+            return asn1_template_ex_d2i(pval, in, len,
+                                        it->templates, opt, ctx);
+        }
+        return asn1_d2i_ex_primitive(pval, in, len, it,
+                                     tag, aclass, opt, ctx);
+
+    case ASN1_ITYPE_MSTRING:
+        p = *in;
+        /* Just read in tag and class */
+        ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
+                              &p, len, -1, 0, 1, ctx);
+        if (!ret) {
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR);
+            goto err;
+        }
+
+        /* Must be UNIVERSAL class */
+        if (oclass != V_ASN1_UNIVERSAL) {
+            /* If OPTIONAL, assume this is OK */
+            if (opt)
+                return -1;
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL);
+            goto err;
+        }
+        /* Check tag matches bit map */
+        if (!(ASN1_tag2bit(otag) & it->utype)) {
+            /* If OPTIONAL, assume this is OK */
+            if (opt)
+                return -1;
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_MSTRING_WRONG_TAG);
+            goto err;
+        }
+        return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx);
+
+    case ASN1_ITYPE_EXTERN:
+        /* Use new style d2i */
+        ef = it->funcs;
+        return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx);
+
+    case ASN1_ITYPE_CHOICE:
+        if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
+            goto auxerr;
+        if (*pval) {
+            /* Free up and zero CHOICE value if initialised */
+            i = asn1_get_choice_selector(pval, it);
+            if ((i >= 0) && (i < it->tcount)) {
+                tt = it->templates + i;
+                pchptr = asn1_get_field_ptr(pval, tt);
+                asn1_template_free(pchptr, tt);
+                asn1_set_choice_selector(pval, -1, it);
+            }
+        } else if (!ASN1_item_ex_new(pval, it)) {
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR);
+            goto err;
+        }
+        /* CHOICE type, try each possibility in turn */
+        p = *in;
+        for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+            pchptr = asn1_get_field_ptr(pval, tt);
+            /*
+             * We mark field as OPTIONAL so its absence can be recognised.
+             */
+            ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx);
+            /* If field not present, try the next one */
+            if (ret == -1)
+                continue;
+            /* If positive return, read OK, break loop */
+            if (ret > 0)
+                break;
+            /*
+             * Must be an ASN1 parsing error.
+             * Free up any partial choice value
+             */
+            asn1_template_free(pchptr, tt);
+            errtt = tt;
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR);
+            goto err;
+        }
+
+        /* Did we fall off the end without reading anything? */
+        if (i == it->tcount) {
+            /* If OPTIONAL, this is OK */
+            if (opt) {
+                /* Free and zero it */
+                ASN1_item_ex_free(pval, it);
+                return -1;
+            }
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_NO_MATCHING_CHOICE_TYPE);
+            goto err;
+        }
+
+        asn1_set_choice_selector(pval, i, it);
+
+        if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
+            goto auxerr;
+        *in = p;
+        return 1;
+
+    case ASN1_ITYPE_NDEF_SEQUENCE:
+    case ASN1_ITYPE_SEQUENCE:
+        p = *in;
+        tmplen = len;
+
+        /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
+        if (tag == -1) {
+            tag = V_ASN1_SEQUENCE;
+            aclass = V_ASN1_UNIVERSAL;
+        }
+        /* Get SEQUENCE length and update len, p */
+        ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst,
+                              &p, len, tag, aclass, opt, ctx);
+        if (!ret) {
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR);
+            goto err;
+        } else if (ret == -1)
+            return -1;
+        if (aux && (aux->flags & ASN1_AFLG_BROKEN)) {
+            len = tmplen - (p - *in);
+            seq_nolen = 1;
+        }
+        /* If indefinite we don't do a length check */
+        else
+            seq_nolen = seq_eoc;
+        if (!cst) {
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
+            goto err;
+        }
+
+        if (!*pval && !ASN1_item_ex_new(pval, it)) {
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ERR_R_NESTED_ASN1_ERROR);
+            goto err;
+        }
+
+        if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
+            goto auxerr;
+
+        /* Free up and zero any ADB found */
+        for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+            if (tt->flags & ASN1_TFLG_ADB_MASK) {
+                const ASN1_TEMPLATE *seqtt;
+                ASN1_VALUE **pseqval;
+                seqtt = asn1_do_adb(pval, tt, 0);
+                if (seqtt == NULL)
+                    continue;
+                pseqval = asn1_get_field_ptr(pval, seqtt);
+                asn1_template_free(pseqval, seqtt);
+            }
+        }
+
+        /* Get each field entry */
+        for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+            const ASN1_TEMPLATE *seqtt;
+            ASN1_VALUE **pseqval;
+            seqtt = asn1_do_adb(pval, tt, 1);
+            if (seqtt == NULL)
+                goto err;
+            pseqval = asn1_get_field_ptr(pval, seqtt);
+            /* Have we ran out of data? */
+            if (!len)
+                break;
+            q = p;
+            if (asn1_check_eoc(&p, len)) {
+                if (!seq_eoc) {
+                    ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_UNEXPECTED_EOC);
+                    goto err;
+                }
+                len -= p - q;
+                seq_eoc = 0;
+                q = p;
+                break;
+            }
+            /*
+             * This determines the OPTIONAL flag value. The field cannot be
+             * omitted if it is the last of a SEQUENCE and there is still
+             * data to be read. This isn't strictly necessary but it
+             * increases efficiency in some cases.
+             */
+            if (i == (it->tcount - 1))
+                isopt = 0;
+            else
+                isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL);
+            /*
+             * attempt to read in field, allowing each to be OPTIONAL
+             */
+
+            ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx);
+            if (!ret) {
+                errtt = seqtt;
+                goto err;
+            } else if (ret == -1) {
+                /*
+                 * OPTIONAL component absent. Free and zero the field.
+                 */
+                asn1_template_free(pseqval, seqtt);
+                continue;
+            }
+            /* Update length */
+            len -= p - q;
+        }
+
+        /* Check for EOC if expecting one */
+        if (seq_eoc && !asn1_check_eoc(&p, len)) {
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_MISSING_EOC);
+            goto err;
+        }
+        /* Check all data read */
+        if (!seq_nolen && len) {
+            ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
+            goto err;
+        }
+
+        /*
+         * If we get here we've got no more data in the SEQUENCE, however we
+         * may not have read all fields so check all remaining are OPTIONAL
+         * and clear any that are.
+         */
+        for (; i < it->tcount; tt++, i++) {
+            const ASN1_TEMPLATE *seqtt;
+            seqtt = asn1_do_adb(pval, tt, 1);
+            if (seqtt == NULL)
+                goto err;
+            if (seqtt->flags & ASN1_TFLG_OPTIONAL) {
+                ASN1_VALUE **pseqval;
+                pseqval = asn1_get_field_ptr(pval, seqtt);
+                asn1_template_free(pseqval, seqtt);
+            } else {
+                errtt = seqtt;
+                ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_FIELD_MISSING);
+                goto err;
+            }
+        }
+        /* Save encoding */
+        if (!asn1_enc_save(pval, *in, p - *in, it))
+            goto auxerr;
+        if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL))
+            goto auxerr;
+        *in = p;
+        return 1;
+
+    default:
+        return 0;
+    }
+ auxerr:
+    ASN1err(ASN1_F_ASN1_ITEM_EMBED_D2I, ASN1_R_AUX_ERROR);
+ err:
+    if (errtt)
+        ERR_add_error_data(4, "Field=", errtt->field_name,
+                           ", Type=", it->sname);
+    else
+        ERR_add_error_data(2, "Type=", it->sname);
+    return 0;
+}
+
+/*
+ * Templates are handled with two separate functions. One handles any
+ * EXPLICIT tag and the other handles the rest.
+ */
+
+static int asn1_template_ex_d2i(ASN1_VALUE **val,
+                                const unsigned char **in, long inlen,
+                                const ASN1_TEMPLATE *tt, char opt,
+                                ASN1_TLC *ctx)
+{
+    int flags, aclass;
+    int ret;
+    long len;
+    const unsigned char *p, *q;
+    char exp_eoc;
+    if (!val)
+        return 0;
+    flags = tt->flags;
+    aclass = flags & ASN1_TFLG_TAG_CLASS;
+
+    p = *in;
+
+    /* Check if EXPLICIT tag expected */
+    if (flags & ASN1_TFLG_EXPTAG) {
+        char cst;
+        /*
+         * Need to work out amount of data available to the inner content and
+         * where it starts: so read in EXPLICIT header to get the info.
+         */
+        ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst,
+                              &p, inlen, tt->tag, aclass, opt, ctx);
+        q = p;
+        if (!ret) {
+            ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+            return 0;
+        } else if (ret == -1)
+            return -1;
+        if (!cst) {
+            ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
+                    ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
+            return 0;
+        }
+        /* We've found the field so it can't be OPTIONAL now */
+        ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);
+        if (!ret) {
+            ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+            return 0;
+        }
+        /* We read the field in OK so update length */
+        len -= p - q;
+        if (exp_eoc) {
+            /* If NDEF we must have an EOC here */
+            if (!asn1_check_eoc(&p, len)) {
+                ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ASN1_R_MISSING_EOC);
+                goto err;
+            }
+        } else {
+            /*
+             * Otherwise we must hit the EXPLICIT tag end or its an error
+             */
+            if (len) {
+                ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I,
+                        ASN1_R_EXPLICIT_LENGTH_MISMATCH);
+                goto err;
+            }
+        }
+    } else
+        return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx);
+
+    *in = p;
+    return 1;
+
+ err:
+    return 0;
+}
+
+static int asn1_template_noexp_d2i(ASN1_VALUE **val,
+                                   const unsigned char **in, long len,
+                                   const ASN1_TEMPLATE *tt, char opt,
+                                   ASN1_TLC *ctx)
+{
+    int flags, aclass;
+    int ret;
+    ASN1_VALUE *tval;
+    const unsigned char *p, *q;
+    if (!val)
+        return 0;
+    flags = tt->flags;
+    aclass = flags & ASN1_TFLG_TAG_CLASS;
+
+    p = *in;
+    q = p;
+
+    /*
+     * If field is embedded then val needs fixing so it is a pointer to
+     * a pointer to a field.
+     */
+    if (tt->flags & ASN1_TFLG_EMBED) {
+        tval = (ASN1_VALUE *)val;
+        val = &tval;
+    }
+
+    if (flags & ASN1_TFLG_SK_MASK) {
+        /* SET OF, SEQUENCE OF */
+        int sktag, skaclass;
+        char sk_eoc;
+        /* First work out expected inner tag value */
+        if (flags & ASN1_TFLG_IMPTAG) {
+            sktag = tt->tag;
+            skaclass = aclass;
+        } else {
+            skaclass = V_ASN1_UNIVERSAL;
+            if (flags & ASN1_TFLG_SET_OF)
+                sktag = V_ASN1_SET;
+            else
+                sktag = V_ASN1_SEQUENCE;
+        }
+        /* Get the tag */
+        ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL,
+                              &p, len, sktag, skaclass, opt, ctx);
+        if (!ret) {
+            ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
+            return 0;
+        } else if (ret == -1)
+            return -1;
+        if (!*val)
+            *val = (ASN1_VALUE *)OPENSSL_sk_new_null();
+        else {
+            /*
+             * We've got a valid STACK: free up any items present
+             */
+            STACK_OF(ASN1_VALUE) *sktmp = (STACK_OF(ASN1_VALUE) *)*val;
+            ASN1_VALUE *vtmp;
+            while (sk_ASN1_VALUE_num(sktmp) > 0) {
+                vtmp = sk_ASN1_VALUE_pop(sktmp);
+                ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item));
+            }
+        }
+
+        if (!*val) {
+            ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+
+        /* Read as many items as we can */
+        while (len > 0) {
+            ASN1_VALUE *skfield;
+            q = p;
+            /* See if EOC found */
+            if (asn1_check_eoc(&p, len)) {
+                if (!sk_eoc) {
+                    ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+                            ASN1_R_UNEXPECTED_EOC);
+                    goto err;
+                }
+                len -= p - q;
+                sk_eoc = 0;
+                break;
+            }
+            skfield = NULL;
+            if (!asn1_item_embed_d2i(&skfield, &p, len,
+                                     ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) {
+                ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I,
+                        ERR_R_NESTED_ASN1_ERROR);
+                /* |skfield| may be partially allocated despite failure. */
+                ASN1_item_free(skfield, ASN1_ITEM_ptr(tt->item));
+                goto err;
+            }
+            len -= p - q;
+            if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) {
+                ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE);
+                ASN1_item_free(skfield, ASN1_ITEM_ptr(tt->item));
+                goto err;
+            }
+        }
+        if (sk_eoc) {
+            ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC);
+            goto err;
+        }
+    } else if (flags & ASN1_TFLG_IMPTAG) {
+        /* IMPLICIT tagging */
+        ret = asn1_item_embed_d2i(val, &p, len,
+                                  ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt,
+                                  ctx);
+        if (!ret) {
+            ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
+            goto err;
+        } else if (ret == -1)
+            return -1;
+    } else {
+        /* Nothing special */
+        ret = asn1_item_embed_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item),
+                                  -1, 0, opt, ctx);
+        if (!ret) {
+            ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR);
+            goto err;
+        } else if (ret == -1)
+            return -1;
+    }
+
+    *in = p;
+    return 1;
+
+ err:
+    return 0;
+}
+
+static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
+                                 const unsigned char **in, long inlen,
+                                 const ASN1_ITEM *it,
+                                 int tag, int aclass, char opt, ASN1_TLC *ctx)
+{
+    int ret = 0, utype;
+    long plen;
+    char cst, inf, free_cont = 0;
+    const unsigned char *p;
+    BUF_MEM buf = { 0, NULL, 0, 0 };
+    const unsigned char *cont = NULL;
+    long len;
+    if (!pval) {
+        ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL);
+        return 0;               /* Should never happen */
+    }
+
+    if (it->itype == ASN1_ITYPE_MSTRING) {
+        utype = tag;
+        tag = -1;
+    } else
+        utype = it->utype;
+
+    if (utype == V_ASN1_ANY) {
+        /* If type is ANY need to figure out type from tag */
+        unsigned char oclass;
+        if (tag >= 0) {
+            ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_TAGGED_ANY);
+            return 0;
+        }
+        if (opt) {
+            ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
+                    ASN1_R_ILLEGAL_OPTIONAL_ANY);
+            return 0;
+        }
+        p = *in;
+        ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL,
+                              &p, inlen, -1, 0, 0, ctx);
+        if (!ret) {
+            ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
+            return 0;
+        }
+        if (oclass != V_ASN1_UNIVERSAL)
+            utype = V_ASN1_OTHER;
+    }
+    if (tag == -1) {
+        tag = utype;
+        aclass = V_ASN1_UNIVERSAL;
+    }
+    p = *in;
+    /* Check header */
+    ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst,
+                          &p, inlen, tag, aclass, opt, ctx);
+    if (!ret) {
+        ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR);
+        return 0;
+    } else if (ret == -1)
+        return -1;
+    ret = 0;
+    /* SEQUENCE, SET and "OTHER" are left in encoded form */
+    if ((utype == V_ASN1_SEQUENCE)
+        || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) {
+        /*
+         * Clear context cache for type OTHER because the auto clear when we
+         * have a exact match won't work
+         */
+        if (utype == V_ASN1_OTHER) {
+            asn1_tlc_clear(ctx);
+        }
+        /* SEQUENCE and SET must be constructed */
+        else if (!cst) {
+            ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE,
+                    ASN1_R_TYPE_NOT_CONSTRUCTED);
+            return 0;
+        }
+
+        cont = *in;
+        /* If indefinite length constructed find the real end */
+        if (inf) {
+            if (!asn1_find_end(&p, plen, inf))
+                goto err;
+            len = p - cont;
+        } else {
+            len = p - cont + plen;
+            p += plen;
+        }
+    } else if (cst) {
+        if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN
+            || utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER
+            || utype == V_ASN1_ENUMERATED) {
+            ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_TYPE_NOT_PRIMITIVE);
+            return 0;
+        }
+
+        /* Free any returned 'buf' content */
+        free_cont = 1;
+        /*
+         * Should really check the internal tags are correct but some things
+         * may get this wrong. The relevant specs say that constructed string
+         * types should be OCTET STRINGs internally irrespective of the type.
+         * So instead just check for UNIVERSAL class and ignore the tag.
+         */
+        if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) {
+            goto err;
+        }
+        len = buf.length;
+        /* Append a final null to string */
+        if (!BUF_MEM_grow_clean(&buf, len + 1)) {
+            ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        buf.data[len] = 0;
+        cont = (const unsigned char *)buf.data;
+    } else {
+        cont = p;
+        len = plen;
+        p += plen;
+    }
+
+    /* We now have content length and type: translate into a structure */
+    /* asn1_ex_c2i may reuse allocated buffer, and so sets free_cont to 0 */
+    if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it))
+        goto err;
+
+    *in = p;
+    ret = 1;
+ err:
+    if (free_cont)
+        OPENSSL_free(buf.data);
+    return ret;
+}
+
+/* Translate ASN1 content octets into a structure */
+
+static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                       int utype, char *free_cont, const ASN1_ITEM *it)
+{
+    ASN1_VALUE **opval = NULL;
+    ASN1_STRING *stmp;
+    ASN1_TYPE *typ = NULL;
+    int ret = 0;
+    const ASN1_PRIMITIVE_FUNCS *pf;
+    ASN1_INTEGER **tint;
+    pf = it->funcs;
+
+    if (pf && pf->prim_c2i)
+        return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
+    /* If ANY type clear type and set pointer to internal value */
+    if (it->utype == V_ASN1_ANY) {
+        if (!*pval) {
+            typ = ASN1_TYPE_new();
+            if (typ == NULL)
+                goto err;
+            *pval = (ASN1_VALUE *)typ;
+        } else
+            typ = (ASN1_TYPE *)*pval;
+
+        if (utype != typ->type)
+            ASN1_TYPE_set(typ, utype, NULL);
+        opval = pval;
+        pval = &typ->value.asn1_value;
+    }
+    switch (utype) {
+    case V_ASN1_OBJECT:
+        if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
+            goto err;
+        break;
+
+    case V_ASN1_NULL:
+        if (len) {
+            ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_NULL_IS_WRONG_LENGTH);
+            goto err;
+        }
+        *pval = (ASN1_VALUE *)1;
+        break;
+
+    case V_ASN1_BOOLEAN:
+        if (len != 1) {
+            ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
+            goto err;
+        } else {
+            ASN1_BOOLEAN *tbool;
+            tbool = (ASN1_BOOLEAN *)pval;
+            *tbool = *cont;
+        }
+        break;
+
+    case V_ASN1_BIT_STRING:
+        if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len))
+            goto err;
+        break;
+
+    case V_ASN1_INTEGER:
+    case V_ASN1_ENUMERATED:
+        tint = (ASN1_INTEGER **)pval;
+        if (!c2i_ASN1_INTEGER(tint, &cont, len))
+            goto err;
+        /* Fixup type to match the expected form */
+        (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
+        break;
+
+    case V_ASN1_OCTET_STRING:
+    case V_ASN1_NUMERICSTRING:
+    case V_ASN1_PRINTABLESTRING:
+    case V_ASN1_T61STRING:
+    case V_ASN1_VIDEOTEXSTRING:
+    case V_ASN1_IA5STRING:
+    case V_ASN1_UTCTIME:
+    case V_ASN1_GENERALIZEDTIME:
+    case V_ASN1_GRAPHICSTRING:
+    case V_ASN1_VISIBLESTRING:
+    case V_ASN1_GENERALSTRING:
+    case V_ASN1_UNIVERSALSTRING:
+    case V_ASN1_BMPSTRING:
+    case V_ASN1_UTF8STRING:
+    case V_ASN1_OTHER:
+    case V_ASN1_SET:
+    case V_ASN1_SEQUENCE:
+    default:
+        if (utype == V_ASN1_BMPSTRING && (len & 1)) {
+            ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
+            goto err;
+        }
+        if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) {
+            ASN1err(ASN1_F_ASN1_EX_C2I,
+                    ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
+            goto err;
+        }
+        /* All based on ASN1_STRING and handled the same */
+        if (!*pval) {
+            stmp = ASN1_STRING_type_new(utype);
+            if (stmp == NULL) {
+                ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            *pval = (ASN1_VALUE *)stmp;
+        } else {
+            stmp = (ASN1_STRING *)*pval;
+            stmp->type = utype;
+        }
+        /* If we've already allocated a buffer use it */
+        if (*free_cont) {
+            OPENSSL_free(stmp->data);
+            stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */
+            stmp->length = len;
+            *free_cont = 0;
+        } else {
+            if (!ASN1_STRING_set(stmp, cont, len)) {
+                ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE);
+                ASN1_STRING_free(stmp);
+                *pval = NULL;
+                goto err;
+            }
+        }
+        break;
+    }
+    /* If ASN1_ANY and NULL type fix up value */
+    if (typ && (utype == V_ASN1_NULL))
+        typ->value.ptr = NULL;
+
+    ret = 1;
+ err:
+    if (!ret) {
+        ASN1_TYPE_free(typ);
+        if (opval)
+            *opval = NULL;
+    }
+    return ret;
+}
+
+/*
+ * This function finds the end of an ASN1 structure when passed its maximum
+ * length, whether it is indefinite length and a pointer to the content. This
+ * is more efficient than calling asn1_collect because it does not recurse on
+ * each indefinite length header.
+ */
+
+static int asn1_find_end(const unsigned char **in, long len, char inf)
+{
+    uint32_t expected_eoc;
+    long plen;
+    const unsigned char *p = *in, *q;
+    /* If not indefinite length constructed just add length */
+    if (inf == 0) {
+        *in += len;
+        return 1;
+    }
+    expected_eoc = 1;
+    /*
+     * Indefinite length constructed form. Find the end when enough EOCs are
+     * found. If more indefinite length constructed headers are encountered
+     * increment the expected eoc count otherwise just skip to the end of the
+     * data.
+     */
+    while (len > 0) {
+        if (asn1_check_eoc(&p, len)) {
+            expected_eoc--;
+            if (expected_eoc == 0)
+                break;
+            len -= 2;
+            continue;
+        }
+        q = p;
+        /* Just read in a header: only care about the length */
+        if (!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
+                             -1, 0, 0, NULL)) {
+            ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR);
+            return 0;
+        }
+        if (inf) {
+            if (expected_eoc == UINT32_MAX) {
+                ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR);
+                return 0;
+            }
+            expected_eoc++;
+        } else {
+            p += plen;
+        }
+        len -= p - q;
+    }
+    if (expected_eoc) {
+        ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC);
+        return 0;
+    }
+    *in = p;
+    return 1;
+}
+
+/*
+ * This function collects the asn1 data from a constructed string type into
+ * a buffer. The values of 'in' and 'len' should refer to the contents of the
+ * constructed type and 'inf' should be set if it is indefinite length.
+ */
+
+#ifndef ASN1_MAX_STRING_NEST
+/*
+ * This determines how many levels of recursion are permitted in ASN1 string
+ * types. If it is not limited stack overflows can occur. If set to zero no
+ * recursion is allowed at all. Although zero should be adequate examples
+ * exist that require a value of 1. So 5 should be more than enough.
+ */
+# define ASN1_MAX_STRING_NEST 5
+#endif
+
+static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
+                        char inf, int tag, int aclass, int depth)
+{
+    const unsigned char *p, *q;
+    long plen;
+    char cst, ininf;
+    p = *in;
+    inf &= 1;
+    /*
+     * If no buffer and not indefinite length constructed just pass over the
+     * encoded data
+     */
+    if (!buf && !inf) {
+        *in += len;
+        return 1;
+    }
+    while (len > 0) {
+        q = p;
+        /* Check for EOC */
+        if (asn1_check_eoc(&p, len)) {
+            /*
+             * EOC is illegal outside indefinite length constructed form
+             */
+            if (!inf) {
+                ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_UNEXPECTED_EOC);
+                return 0;
+            }
+            inf = 0;
+            break;
+        }
+
+        if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
+                             len, tag, aclass, 0, NULL)) {
+            ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR);
+            return 0;
+        }
+
+        /* If indefinite length constructed update max length */
+        if (cst) {
+            if (depth >= ASN1_MAX_STRING_NEST) {
+                ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_NESTED_ASN1_STRING);
+                return 0;
+            }
+            if (!asn1_collect(buf, &p, plen, ininf, tag, aclass, depth + 1))
+                return 0;
+        } else if (plen && !collect_data(buf, &p, plen))
+            return 0;
+        len -= p - q;
+    }
+    if (inf) {
+        ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC);
+        return 0;
+    }
+    *in = p;
+    return 1;
+}
+
+static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
+{
+    int len;
+    if (buf) {
+        len = buf->length;
+        if (!BUF_MEM_grow_clean(buf, len + plen)) {
+            ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        memcpy(buf->data + len, *p, plen);
+    }
+    *p += plen;
+    return 1;
+}
+
+/* Check for ASN1 EOC and swallow it if found */
+
+static int asn1_check_eoc(const unsigned char **in, long len)
+{
+    const unsigned char *p;
+    if (len < 2)
+        return 0;
+    p = *in;
+    if (!p[0] && !p[1]) {
+        *in += 2;
+        return 1;
+    }
+    return 0;
+}
+
+/*
+ * Check an ASN1 tag and length: a bit like ASN1_get_object but it sets the
+ * length for indefinite length constructed form, we don't know the exact
+ * length but we can set an upper bound to the amount of data available minus
+ * the header length just read.
+ */
+
+static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
+                           char *inf, char *cst,
+                           const unsigned char **in, long len,
+                           int exptag, int expclass, char opt, ASN1_TLC *ctx)
+{
+    int i;
+    int ptag, pclass;
+    long plen;
+    const unsigned char *p, *q;
+    p = *in;
+    q = p;
+
+    if (ctx && ctx->valid) {
+        i = ctx->ret;
+        plen = ctx->plen;
+        pclass = ctx->pclass;
+        ptag = ctx->ptag;
+        p += ctx->hdrlen;
+    } else {
+        i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
+        if (ctx) {
+            ctx->ret = i;
+            ctx->plen = plen;
+            ctx->pclass = pclass;
+            ctx->ptag = ptag;
+            ctx->hdrlen = p - q;
+            ctx->valid = 1;
+            /*
+             * If definite length, and no error, length + header can't exceed
+             * total amount of data available.
+             */
+            if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) {
+                ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG);
+                asn1_tlc_clear(ctx);
+                return 0;
+            }
+        }
+    }
+
+    if (i & 0x80) {
+        ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER);
+        asn1_tlc_clear(ctx);
+        return 0;
+    }
+    if (exptag >= 0) {
+        if ((exptag != ptag) || (expclass != pclass)) {
+            /*
+             * If type is OPTIONAL, not an error: indicate missing type.
+             */
+            if (opt)
+                return -1;
+            asn1_tlc_clear(ctx);
+            ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG);
+            return 0;
+        }
+        /*
+         * We have a tag and class match: assume we are going to do something
+         * with it
+         */
+        asn1_tlc_clear(ctx);
+    }
+
+    if (i & 1)
+        plen = len - (p - q);
+
+    if (inf)
+        *inf = i & 1;
+
+    if (cst)
+        *cst = i & V_ASN1_CONSTRUCTED;
+
+    if (olen)
+        *olen = plen;
+
+    if (oclass)
+        *oclass = pclass;
+
+    if (otag)
+        *otag = ptag;
+
+    *in = p;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_enc.c	(revision 331)
@@ -0,0 +1,605 @@
+/*
+ * Copyright 2000-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 <stddef.h>
+#include <string.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include "internal/asn1_int.h"
+#include "asn1_locl.h"
+
+static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
+                                 const ASN1_ITEM *it, int tag, int aclass);
+static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
+                            int skcontlen, const ASN1_ITEM *item,
+                            int do_sort, int iclass);
+static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+                                const ASN1_TEMPLATE *tt, int tag, int aclass);
+static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
+                               const ASN1_ITEM *it, int flags);
+static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
+                       const ASN1_ITEM *it);
+
+/*
+ * Top level i2d equivalents: the 'ndef' variant instructs the encoder to use
+ * indefinite length constructed encoding, where appropriate
+ */
+
+int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out,
+                       const ASN1_ITEM *it)
+{
+    return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
+}
+
+int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
+{
+    return asn1_item_flags_i2d(val, out, it, 0);
+}
+
+/*
+ * Encode an ASN1 item, this is use by the standard 'i2d' function. 'out'
+ * points to a buffer to output the data to. The new i2d has one additional
+ * feature. If the output buffer is NULL (i.e. *out == NULL) then a buffer is
+ * allocated and populated with the encoding.
+ */
+
+static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
+                               const ASN1_ITEM *it, int flags)
+{
+    if (out && !*out) {
+        unsigned char *p, *buf;
+        int len;
+        len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
+        if (len <= 0)
+            return len;
+        buf = OPENSSL_malloc(len);
+        if (buf == NULL)
+            return -1;
+        p = buf;
+        ASN1_item_ex_i2d(&val, &p, it, -1, flags);
+        *out = buf;
+        return len;
+    }
+
+    return ASN1_item_ex_i2d(&val, out, it, -1, flags);
+}
+
+/*
+ * Encode an item, taking care of IMPLICIT tagging (if any). This function
+ * performs the normal item handling: it can be used in external types.
+ */
+
+int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+                     const ASN1_ITEM *it, int tag, int aclass)
+{
+    const ASN1_TEMPLATE *tt = NULL;
+    int i, seqcontlen, seqlen, ndef = 1;
+    const ASN1_EXTERN_FUNCS *ef;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_aux_cb *asn1_cb = 0;
+
+    if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
+        return 0;
+
+    if (aux && aux->asn1_cb)
+        asn1_cb = aux->asn1_cb;
+
+    switch (it->itype) {
+
+    case ASN1_ITYPE_PRIMITIVE:
+        if (it->templates)
+            return asn1_template_ex_i2d(pval, out, it->templates,
+                                        tag, aclass);
+        return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
+
+    case ASN1_ITYPE_MSTRING:
+        return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
+
+    case ASN1_ITYPE_CHOICE:
+        if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
+            return 0;
+        i = asn1_get_choice_selector(pval, it);
+        if ((i >= 0) && (i < it->tcount)) {
+            ASN1_VALUE **pchval;
+            const ASN1_TEMPLATE *chtt;
+            chtt = it->templates + i;
+            pchval = asn1_get_field_ptr(pval, chtt);
+            return asn1_template_ex_i2d(pchval, out, chtt, -1, aclass);
+        }
+        /* Fixme: error condition if selector out of range */
+        if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
+            return 0;
+        break;
+
+    case ASN1_ITYPE_EXTERN:
+        /* If new style i2d it does all the work */
+        ef = it->funcs;
+        return ef->asn1_ex_i2d(pval, out, it, tag, aclass);
+
+    case ASN1_ITYPE_NDEF_SEQUENCE:
+        /* Use indefinite length constructed if requested */
+        if (aclass & ASN1_TFLG_NDEF)
+            ndef = 2;
+        /* fall through */
+
+    case ASN1_ITYPE_SEQUENCE:
+        i = asn1_enc_restore(&seqcontlen, out, pval, it);
+        /* An error occurred */
+        if (i < 0)
+            return 0;
+        /* We have a valid cached encoding... */
+        if (i > 0)
+            return seqcontlen;
+        /* Otherwise carry on */
+        seqcontlen = 0;
+        /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
+        if (tag == -1) {
+            tag = V_ASN1_SEQUENCE;
+            /* Retain any other flags in aclass */
+            aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
+                | V_ASN1_UNIVERSAL;
+        }
+        if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
+            return 0;
+        /* First work out sequence content length */
+        for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+            const ASN1_TEMPLATE *seqtt;
+            ASN1_VALUE **pseqval;
+            int tmplen;
+            seqtt = asn1_do_adb(pval, tt, 1);
+            if (!seqtt)
+                return 0;
+            pseqval = asn1_get_field_ptr(pval, seqtt);
+            tmplen = asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, aclass);
+            if (tmplen == -1 || (tmplen > INT_MAX - seqcontlen))
+                return -1;
+            seqcontlen += tmplen;
+        }
+
+        seqlen = ASN1_object_size(ndef, seqcontlen, tag);
+        if (!out || seqlen == -1)
+            return seqlen;
+        /* Output SEQUENCE header */
+        ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
+        for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+            const ASN1_TEMPLATE *seqtt;
+            ASN1_VALUE **pseqval;
+            seqtt = asn1_do_adb(pval, tt, 1);
+            if (!seqtt)
+                return 0;
+            pseqval = asn1_get_field_ptr(pval, seqtt);
+            /* FIXME: check for errors in enhanced version */
+            asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
+        }
+        if (ndef == 2)
+            ASN1_put_eoc(out);
+        if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
+            return 0;
+        return seqlen;
+
+    default:
+        return 0;
+
+    }
+    return 0;
+}
+
+static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+                                const ASN1_TEMPLATE *tt, int tag, int iclass)
+{
+    int i, ret, flags, ttag, tclass, ndef;
+    ASN1_VALUE *tval;
+    flags = tt->flags;
+
+    /*
+     * If field is embedded then val needs fixing so it is a pointer to
+     * a pointer to a field.
+     */
+    if (flags & ASN1_TFLG_EMBED) {
+        tval = (ASN1_VALUE *)pval;
+        pval = &tval;
+    }
+    /*
+     * Work out tag and class to use: tagging may come either from the
+     * template or the arguments, not both because this would create
+     * ambiguity. Additionally the iclass argument may contain some
+     * additional flags which should be noted and passed down to other
+     * levels.
+     */
+    if (flags & ASN1_TFLG_TAG_MASK) {
+        /* Error if argument and template tagging */
+        if (tag != -1)
+            /* FIXME: error code here */
+            return -1;
+        /* Get tagging from template */
+        ttag = tt->tag;
+        tclass = flags & ASN1_TFLG_TAG_CLASS;
+    } else if (tag != -1) {
+        /* No template tagging, get from arguments */
+        ttag = tag;
+        tclass = iclass & ASN1_TFLG_TAG_CLASS;
+    } else {
+        ttag = -1;
+        tclass = 0;
+    }
+    /*
+     * Remove any class mask from iflag.
+     */
+    iclass &= ~ASN1_TFLG_TAG_CLASS;
+
+    /*
+     * At this point 'ttag' contains the outer tag to use, 'tclass' is the
+     * class and iclass is any flags passed to this function.
+     */
+
+    /* if template and arguments require ndef, use it */
+    if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))
+        ndef = 2;
+    else
+        ndef = 1;
+
+    if (flags & ASN1_TFLG_SK_MASK) {
+        /* SET OF, SEQUENCE OF */
+        STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
+        int isset, sktag, skaclass;
+        int skcontlen, sklen;
+        ASN1_VALUE *skitem;
+
+        if (!*pval)
+            return 0;
+
+        if (flags & ASN1_TFLG_SET_OF) {
+            isset = 1;
+            /* 2 means we reorder */
+            if (flags & ASN1_TFLG_SEQUENCE_OF)
+                isset = 2;
+        } else
+            isset = 0;
+
+        /*
+         * Work out inner tag value: if EXPLICIT or no tagging use underlying
+         * type.
+         */
+        if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) {
+            sktag = ttag;
+            skaclass = tclass;
+        } else {
+            skaclass = V_ASN1_UNIVERSAL;
+            if (isset)
+                sktag = V_ASN1_SET;
+            else
+                sktag = V_ASN1_SEQUENCE;
+        }
+
+        /* Determine total length of items */
+        skcontlen = 0;
+        for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
+            int tmplen;
+            skitem = sk_ASN1_VALUE_value(sk, i);
+            tmplen = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item),
+                                      -1, iclass);
+            if (tmplen == -1 || (skcontlen > INT_MAX - tmplen))
+                return -1;
+            skcontlen += tmplen;
+        }
+        sklen = ASN1_object_size(ndef, skcontlen, sktag);
+        if (sklen == -1)
+            return -1;
+        /* If EXPLICIT need length of surrounding tag */
+        if (flags & ASN1_TFLG_EXPTAG)
+            ret = ASN1_object_size(ndef, sklen, ttag);
+        else
+            ret = sklen;
+
+        if (!out || ret == -1)
+            return ret;
+
+        /* Now encode this lot... */
+        /* EXPLICIT tag */
+        if (flags & ASN1_TFLG_EXPTAG)
+            ASN1_put_object(out, ndef, sklen, ttag, tclass);
+        /* SET or SEQUENCE and IMPLICIT tag */
+        ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
+        /* And the stuff itself */
+        asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item),
+                         isset, iclass);
+        if (ndef == 2) {
+            ASN1_put_eoc(out);
+            if (flags & ASN1_TFLG_EXPTAG)
+                ASN1_put_eoc(out);
+        }
+
+        return ret;
+    }
+
+    if (flags & ASN1_TFLG_EXPTAG) {
+        /* EXPLICIT tagging */
+        /* Find length of tagged item */
+        i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, iclass);
+        if (!i)
+            return 0;
+        /* Find length of EXPLICIT tag */
+        ret = ASN1_object_size(ndef, i, ttag);
+        if (out && ret != -1) {
+            /* Output tag and item */
+            ASN1_put_object(out, ndef, i, ttag, tclass);
+            ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, iclass);
+            if (ndef == 2)
+                ASN1_put_eoc(out);
+        }
+        return ret;
+    }
+
+    /* Either normal or IMPLICIT tagging: combine class and flags */
+    return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
+                            ttag, tclass | iclass);
+
+}
+
+/* Temporary structure used to hold DER encoding of items for SET OF */
+
+typedef struct {
+    unsigned char *data;
+    int length;
+    ASN1_VALUE *field;
+} DER_ENC;
+
+static int der_cmp(const void *a, const void *b)
+{
+    const DER_ENC *d1 = a, *d2 = b;
+    int cmplen, i;
+    cmplen = (d1->length < d2->length) ? d1->length : d2->length;
+    i = memcmp(d1->data, d2->data, cmplen);
+    if (i)
+        return i;
+    return d1->length - d2->length;
+}
+
+/* Output the content octets of SET OF or SEQUENCE OF */
+
+static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
+                            int skcontlen, const ASN1_ITEM *item,
+                            int do_sort, int iclass)
+{
+    int i;
+    ASN1_VALUE *skitem;
+    unsigned char *tmpdat = NULL, *p = NULL;
+    DER_ENC *derlst = NULL, *tder;
+    if (do_sort) {
+        /* Don't need to sort less than 2 items */
+        if (sk_ASN1_VALUE_num(sk) < 2)
+            do_sort = 0;
+        else {
+            derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk)
+                                    * sizeof(*derlst));
+            if (derlst == NULL)
+                return 0;
+            tmpdat = OPENSSL_malloc(skcontlen);
+            if (tmpdat == NULL) {
+                OPENSSL_free(derlst);
+                return 0;
+            }
+        }
+    }
+    /* If not sorting just output each item */
+    if (!do_sort) {
+        for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
+            skitem = sk_ASN1_VALUE_value(sk, i);
+            ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
+        }
+        return 1;
+    }
+    p = tmpdat;
+
+    /* Doing sort: build up a list of each member's DER encoding */
+    for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
+        skitem = sk_ASN1_VALUE_value(sk, i);
+        tder->data = p;
+        tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
+        tder->field = skitem;
+    }
+
+    /* Now sort them */
+    qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
+    /* Output sorted DER encoding */
+    p = *out;
+    for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
+        memcpy(p, tder->data, tder->length);
+        p += tder->length;
+    }
+    *out = p;
+    /* If do_sort is 2 then reorder the STACK */
+    if (do_sort == 2) {
+        for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
+            (void)sk_ASN1_VALUE_set(sk, i, tder->field);
+    }
+    OPENSSL_free(derlst);
+    OPENSSL_free(tmpdat);
+    return 1;
+}
+
+static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
+                                 const ASN1_ITEM *it, int tag, int aclass)
+{
+    int len;
+    int utype;
+    int usetag;
+    int ndef = 0;
+
+    utype = it->utype;
+
+    /*
+     * Get length of content octets and maybe find out the underlying type.
+     */
+
+    len = asn1_ex_i2c(pval, NULL, &utype, it);
+
+    /*
+     * If SEQUENCE, SET or OTHER then header is included in pseudo content
+     * octets so don't include tag+length. We need to check here because the
+     * call to asn1_ex_i2c() could change utype.
+     */
+    if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) ||
+        (utype == V_ASN1_OTHER))
+        usetag = 0;
+    else
+        usetag = 1;
+
+    /* -1 means omit type */
+
+    if (len == -1)
+        return 0;
+
+    /* -2 return is special meaning use ndef */
+    if (len == -2) {
+        ndef = 2;
+        len = 0;
+    }
+
+    /* If not implicitly tagged get tag from underlying type */
+    if (tag == -1)
+        tag = utype;
+
+    /* Output tag+length followed by content octets */
+    if (out) {
+        if (usetag)
+            ASN1_put_object(out, ndef, len, tag, aclass);
+        asn1_ex_i2c(pval, *out, &utype, it);
+        if (ndef)
+            ASN1_put_eoc(out);
+        else
+            *out += len;
+    }
+
+    if (usetag)
+        return ASN1_object_size(ndef, len, tag);
+    return len;
+}
+
+/* Produce content octets from a structure */
+
+static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
+                       const ASN1_ITEM *it)
+{
+    ASN1_BOOLEAN *tbool = NULL;
+    ASN1_STRING *strtmp;
+    ASN1_OBJECT *otmp;
+    int utype;
+    const unsigned char *cont;
+    unsigned char c;
+    int len;
+    const ASN1_PRIMITIVE_FUNCS *pf;
+    pf = it->funcs;
+    if (pf && pf->prim_i2c)
+        return pf->prim_i2c(pval, cout, putype, it);
+
+    /* Should type be omitted? */
+    if ((it->itype != ASN1_ITYPE_PRIMITIVE)
+        || (it->utype != V_ASN1_BOOLEAN)) {
+        if (!*pval)
+            return -1;
+    }
+
+    if (it->itype == ASN1_ITYPE_MSTRING) {
+        /* If MSTRING type set the underlying type */
+        strtmp = (ASN1_STRING *)*pval;
+        utype = strtmp->type;
+        *putype = utype;
+    } else if (it->utype == V_ASN1_ANY) {
+        /* If ANY set type and pointer to value */
+        ASN1_TYPE *typ;
+        typ = (ASN1_TYPE *)*pval;
+        utype = typ->type;
+        *putype = utype;
+        pval = &typ->value.asn1_value;
+    } else
+        utype = *putype;
+
+    switch (utype) {
+    case V_ASN1_OBJECT:
+        otmp = (ASN1_OBJECT *)*pval;
+        cont = otmp->data;
+        len = otmp->length;
+        break;
+
+    case V_ASN1_NULL:
+        cont = NULL;
+        len = 0;
+        break;
+
+    case V_ASN1_BOOLEAN:
+        tbool = (ASN1_BOOLEAN *)pval;
+        if (*tbool == -1)
+            return -1;
+        if (it->utype != V_ASN1_ANY) {
+            /*
+             * Default handling if value == size field then omit
+             */
+            if (*tbool && (it->size > 0))
+                return -1;
+            if (!*tbool && !it->size)
+                return -1;
+        }
+        c = (unsigned char)*tbool;
+        cont = &c;
+        len = 1;
+        break;
+
+    case V_ASN1_BIT_STRING:
+        return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
+                                   cout ? &cout : NULL);
+
+    case V_ASN1_INTEGER:
+    case V_ASN1_ENUMERATED:
+        /*
+         * These are all have the same content format as ASN1_INTEGER
+         */
+        return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL);
+
+    case V_ASN1_OCTET_STRING:
+    case V_ASN1_NUMERICSTRING:
+    case V_ASN1_PRINTABLESTRING:
+    case V_ASN1_T61STRING:
+    case V_ASN1_VIDEOTEXSTRING:
+    case V_ASN1_IA5STRING:
+    case V_ASN1_UTCTIME:
+    case V_ASN1_GENERALIZEDTIME:
+    case V_ASN1_GRAPHICSTRING:
+    case V_ASN1_VISIBLESTRING:
+    case V_ASN1_GENERALSTRING:
+    case V_ASN1_UNIVERSALSTRING:
+    case V_ASN1_BMPSTRING:
+    case V_ASN1_UTF8STRING:
+    case V_ASN1_SEQUENCE:
+    case V_ASN1_SET:
+    default:
+        /* All based on ASN1_STRING and handled the same */
+        strtmp = (ASN1_STRING *)*pval;
+        /* Special handling for NDEF */
+        if ((it->size == ASN1_TFLG_NDEF)
+            && (strtmp->flags & ASN1_STRING_FLAG_NDEF)) {
+            if (cout) {
+                strtmp->data = cout;
+                strtmp->length = 0;
+            }
+            /* Special return code */
+            return -2;
+        }
+        cont = strtmp->data;
+        len = strtmp->length;
+
+        break;
+
+    }
+    if (cout && len)
+        memcpy(cout, cont, len);
+    return len;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_fre.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_fre.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_fre.c	(revision 331)
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2000-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 <stddef.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include "asn1_locl.h"
+
+static void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
+                                 int embed);
+
+/* Free up an ASN1 structure */
+
+void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
+{
+    asn1_item_embed_free(&val, it, 0);
+}
+
+void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    asn1_item_embed_free(pval, it, 0);
+}
+
+static void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
+                                 int embed)
+{
+    const ASN1_TEMPLATE *tt = NULL, *seqtt;
+    const ASN1_EXTERN_FUNCS *ef;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_aux_cb *asn1_cb;
+    int i;
+
+    if (!pval)
+        return;
+    if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
+        return;
+    if (aux && aux->asn1_cb)
+        asn1_cb = aux->asn1_cb;
+    else
+        asn1_cb = 0;
+
+    switch (it->itype) {
+
+    case ASN1_ITYPE_PRIMITIVE:
+        if (it->templates)
+            asn1_template_free(pval, it->templates);
+        else
+            asn1_primitive_free(pval, it, embed);
+        break;
+
+    case ASN1_ITYPE_MSTRING:
+        asn1_primitive_free(pval, it, embed);
+        break;
+
+    case ASN1_ITYPE_CHOICE:
+        if (asn1_cb) {
+            i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
+            if (i == 2)
+                return;
+        }
+        i = asn1_get_choice_selector(pval, it);
+        if ((i >= 0) && (i < it->tcount)) {
+            ASN1_VALUE **pchval;
+
+            tt = it->templates + i;
+            pchval = asn1_get_field_ptr(pval, tt);
+            asn1_template_free(pchval, tt);
+        }
+        if (asn1_cb)
+            asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
+        if (embed == 0) {
+            OPENSSL_free(*pval);
+            *pval = NULL;
+        }
+        break;
+
+    case ASN1_ITYPE_EXTERN:
+        ef = it->funcs;
+        if (ef && ef->asn1_ex_free)
+            ef->asn1_ex_free(pval, it);
+        break;
+
+    case ASN1_ITYPE_NDEF_SEQUENCE:
+    case ASN1_ITYPE_SEQUENCE:
+        if (asn1_do_lock(pval, -1, it) != 0) /* if error or ref-counter > 0 */
+            return;
+        if (asn1_cb) {
+            i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
+            if (i == 2)
+                return;
+        }
+        asn1_enc_free(pval, it);
+        /*
+         * If we free up as normal we will invalidate any ANY DEFINED BY
+         * field and we won't be able to determine the type of the field it
+         * defines. So free up in reverse order.
+         */
+        tt = it->templates + it->tcount;
+        for (i = 0; i < it->tcount; i++) {
+            ASN1_VALUE **pseqval;
+
+            tt--;
+            seqtt = asn1_do_adb(pval, tt, 0);
+            if (!seqtt)
+                continue;
+            pseqval = asn1_get_field_ptr(pval, seqtt);
+            asn1_template_free(pseqval, seqtt);
+        }
+        if (asn1_cb)
+            asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
+        if (embed == 0) {
+            OPENSSL_free(*pval);
+            *pval = NULL;
+        }
+        break;
+    }
+}
+
+void asn1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+{
+    int embed = tt->flags & ASN1_TFLG_EMBED;
+    ASN1_VALUE *tval;
+    if (embed) {
+        tval = (ASN1_VALUE *)pval;
+        pval = &tval;
+    }
+    if (tt->flags & ASN1_TFLG_SK_MASK) {
+        STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
+        int i;
+
+        for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
+            ASN1_VALUE *vtmp = sk_ASN1_VALUE_value(sk, i);
+
+            asn1_item_embed_free(&vtmp, ASN1_ITEM_ptr(tt->item), embed);
+        }
+        sk_ASN1_VALUE_free(sk);
+        *pval = NULL;
+    } else {
+        asn1_item_embed_free(pval, ASN1_ITEM_ptr(tt->item), embed);
+    }
+}
+
+void asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
+{
+    int utype;
+
+    /* Special case: if 'it' is a primitive with a free_func, use that. */
+    if (it) {
+        const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
+
+        if (pf && pf->prim_free) {
+            pf->prim_free(pval, it);
+            return;
+        }
+    }
+
+    /* Special case: if 'it' is NULL, free contents of ASN1_TYPE */
+    if (!it) {
+        ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
+
+        utype = typ->type;
+        pval = &typ->value.asn1_value;
+        if (!*pval)
+            return;
+    } else if (it->itype == ASN1_ITYPE_MSTRING) {
+        utype = -1;
+        if (!*pval)
+            return;
+    } else {
+        utype = it->utype;
+        if ((utype != V_ASN1_BOOLEAN) && !*pval)
+            return;
+    }
+
+    switch (utype) {
+    case V_ASN1_OBJECT:
+        ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
+        break;
+
+    case V_ASN1_BOOLEAN:
+        if (it)
+            *(ASN1_BOOLEAN *)pval = it->size;
+        else
+            *(ASN1_BOOLEAN *)pval = -1;
+        return;
+
+    case V_ASN1_NULL:
+        break;
+
+    case V_ASN1_ANY:
+        asn1_primitive_free(pval, NULL, 0);
+        OPENSSL_free(*pval);
+        break;
+
+    default:
+        asn1_string_embed_free((ASN1_STRING *)*pval, embed);
+        break;
+    }
+    *pval = NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_new.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_new.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_new.c	(revision 331)
@@ -0,0 +1,337 @@
+/*
+ * Copyright 2000-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 <stddef.h>
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/err.h>
+#include <openssl/asn1t.h>
+#include <string.h>
+#include "asn1_locl.h"
+
+static int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
+                               int embed);
+static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
+                              int embed);
+static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
+{
+    ASN1_VALUE *ret = NULL;
+    if (ASN1_item_ex_new(&ret, it) > 0)
+        return ret;
+    return NULL;
+}
+
+/* Allocate an ASN1 structure */
+
+int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    return asn1_item_embed_new(pval, it, 0);
+}
+
+int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
+{
+    const ASN1_TEMPLATE *tt = NULL;
+    const ASN1_EXTERN_FUNCS *ef;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_aux_cb *asn1_cb;
+    ASN1_VALUE **pseqval;
+    int i;
+    if (aux && aux->asn1_cb)
+        asn1_cb = aux->asn1_cb;
+    else
+        asn1_cb = 0;
+
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+    OPENSSL_mem_debug_push(it->sname ? it->sname : "asn1_item_embed_new");
+#endif
+
+    switch (it->itype) {
+
+    case ASN1_ITYPE_EXTERN:
+        ef = it->funcs;
+        if (ef && ef->asn1_ex_new) {
+            if (!ef->asn1_ex_new(pval, it))
+                goto memerr;
+        }
+        break;
+
+    case ASN1_ITYPE_PRIMITIVE:
+        if (it->templates) {
+            if (!asn1_template_new(pval, it->templates))
+                goto memerr;
+        } else if (!asn1_primitive_new(pval, it, embed))
+            goto memerr;
+        break;
+
+    case ASN1_ITYPE_MSTRING:
+        if (!asn1_primitive_new(pval, it, embed))
+            goto memerr;
+        break;
+
+    case ASN1_ITYPE_CHOICE:
+        if (asn1_cb) {
+            i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
+            if (!i)
+                goto auxerr;
+            if (i == 2) {
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+                OPENSSL_mem_debug_pop();
+#endif
+                return 1;
+            }
+        }
+        if (embed) {
+            memset(*pval, 0, it->size);
+        } else {
+            *pval = OPENSSL_zalloc(it->size);
+            if (*pval == NULL)
+                goto memerr;
+        }
+        asn1_set_choice_selector(pval, -1, it);
+        if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
+            goto auxerr2;
+        break;
+
+    case ASN1_ITYPE_NDEF_SEQUENCE:
+    case ASN1_ITYPE_SEQUENCE:
+        if (asn1_cb) {
+            i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
+            if (!i)
+                goto auxerr;
+            if (i == 2) {
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+                OPENSSL_mem_debug_pop();
+#endif
+                return 1;
+            }
+        }
+        if (embed) {
+            memset(*pval, 0, it->size);
+        } else {
+            *pval = OPENSSL_zalloc(it->size);
+            if (*pval == NULL)
+                goto memerr;
+        }
+        /* 0 : init. lock */
+        if (asn1_do_lock(pval, 0, it) < 0)
+            goto memerr2;
+        asn1_enc_init(pval, it);
+        for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
+            pseqval = asn1_get_field_ptr(pval, tt);
+            if (!asn1_template_new(pseqval, tt))
+                goto memerr2;
+        }
+        if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
+            goto auxerr2;
+        break;
+    }
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+    OPENSSL_mem_debug_pop();
+#endif
+    return 1;
+
+ memerr2:
+    ASN1_item_ex_free(pval, it);
+ memerr:
+    ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ERR_R_MALLOC_FAILURE);
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+    OPENSSL_mem_debug_pop();
+#endif
+    return 0;
+
+ auxerr2:
+    ASN1_item_ex_free(pval, it);
+ auxerr:
+    ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ASN1_R_AUX_ERROR);
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+    OPENSSL_mem_debug_pop();
+#endif
+    return 0;
+
+}
+
+static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    const ASN1_EXTERN_FUNCS *ef;
+
+    switch (it->itype) {
+
+    case ASN1_ITYPE_EXTERN:
+        ef = it->funcs;
+        if (ef && ef->asn1_ex_clear)
+            ef->asn1_ex_clear(pval, it);
+        else
+            *pval = NULL;
+        break;
+
+    case ASN1_ITYPE_PRIMITIVE:
+        if (it->templates)
+            asn1_template_clear(pval, it->templates);
+        else
+            asn1_primitive_clear(pval, it);
+        break;
+
+    case ASN1_ITYPE_MSTRING:
+        asn1_primitive_clear(pval, it);
+        break;
+
+    case ASN1_ITYPE_CHOICE:
+    case ASN1_ITYPE_SEQUENCE:
+    case ASN1_ITYPE_NDEF_SEQUENCE:
+        *pval = NULL;
+        break;
+    }
+}
+
+static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+{
+    const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
+    int embed = tt->flags & ASN1_TFLG_EMBED;
+    ASN1_VALUE *tval;
+    int ret;
+    if (embed) {
+        tval = (ASN1_VALUE *)pval;
+        pval = &tval;
+    }
+    if (tt->flags & ASN1_TFLG_OPTIONAL) {
+        asn1_template_clear(pval, tt);
+        return 1;
+    }
+    /* If ANY DEFINED BY nothing to do */
+
+    if (tt->flags & ASN1_TFLG_ADB_MASK) {
+        *pval = NULL;
+        return 1;
+    }
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+    OPENSSL_mem_debug_push(tt->field_name
+            ? tt->field_name : "asn1_template_new");
+#endif
+    /* If SET OF or SEQUENCE OF, its a STACK */
+    if (tt->flags & ASN1_TFLG_SK_MASK) {
+        STACK_OF(ASN1_VALUE) *skval;
+        skval = sk_ASN1_VALUE_new_null();
+        if (!skval) {
+            ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE);
+            ret = 0;
+            goto done;
+        }
+        *pval = (ASN1_VALUE *)skval;
+        ret = 1;
+        goto done;
+    }
+    /* Otherwise pass it back to the item routine */
+    ret = asn1_item_embed_new(pval, it, embed);
+ done:
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+    OPENSSL_mem_debug_pop();
+#endif
+    return ret;
+}
+
+static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+{
+    /* If ADB or STACK just NULL the field */
+    if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK))
+        *pval = NULL;
+    else
+        asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
+}
+
+/*
+ * NB: could probably combine most of the real XXX_new() behaviour and junk
+ * all the old functions.
+ */
+
+static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
+                              int embed)
+{
+    ASN1_TYPE *typ;
+    ASN1_STRING *str;
+    int utype;
+
+    if (!it)
+        return 0;
+
+    if (it->funcs) {
+        const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
+        if (pf->prim_new)
+            return pf->prim_new(pval, it);
+    }
+
+    if (it->itype == ASN1_ITYPE_MSTRING)
+        utype = -1;
+    else
+        utype = it->utype;
+    switch (utype) {
+    case V_ASN1_OBJECT:
+        *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
+        return 1;
+
+    case V_ASN1_BOOLEAN:
+        *(ASN1_BOOLEAN *)pval = it->size;
+        return 1;
+
+    case V_ASN1_NULL:
+        *pval = (ASN1_VALUE *)1;
+        return 1;
+
+    case V_ASN1_ANY:
+        typ = OPENSSL_malloc(sizeof(*typ));
+        if (typ == NULL)
+            return 0;
+        typ->value.ptr = NULL;
+        typ->type = -1;
+        *pval = (ASN1_VALUE *)typ;
+        break;
+
+    default:
+        if (embed) {
+            str = *(ASN1_STRING **)pval;
+            memset(str, 0, sizeof(*str));
+            str->type = utype;
+            str->flags = ASN1_STRING_FLAG_EMBED;
+        } else {
+            str = ASN1_STRING_type_new(utype);
+            *pval = (ASN1_VALUE *)str;
+        }
+        if (it->itype == ASN1_ITYPE_MSTRING && str)
+            str->flags |= ASN1_STRING_FLAG_MSTRING;
+        break;
+    }
+    if (*pval)
+        return 1;
+    return 0;
+}
+
+static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    int utype;
+    if (it && it->funcs) {
+        const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
+        if (pf->prim_clear)
+            pf->prim_clear(pval, it);
+        else
+            *pval = NULL;
+        return;
+    }
+    if (!it || (it->itype == ASN1_ITYPE_MSTRING))
+        utype = -1;
+    else
+        utype = it->utype;
+    if (utype == V_ASN1_BOOLEAN)
+        *(ASN1_BOOLEAN *)pval = it->size;
+    else
+        *pval = NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_prn.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_prn.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_prn.c	(revision 331)
@@ -0,0 +1,538 @@
+/*
+ * Copyright 2000-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 <stddef.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+#include "internal/asn1_int.h"
+#include "asn1_locl.h"
+
+/*
+ * Print routines.
+ */
+
+/* ASN1_PCTX routines */
+
+static ASN1_PCTX default_pctx = {
+    ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
+    0,                          /* nm_flags */
+    0,                          /* cert_flags */
+    0,                          /* oid_flags */
+    0                           /* str_flags */
+};
+
+ASN1_PCTX *ASN1_PCTX_new(void)
+{
+    ASN1_PCTX *ret;
+
+    ret = OPENSSL_zalloc(sizeof(*ret));
+    if (ret == NULL) {
+        ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    return ret;
+}
+
+void ASN1_PCTX_free(ASN1_PCTX *p)
+{
+    OPENSSL_free(p);
+}
+
+unsigned long ASN1_PCTX_get_flags(const ASN1_PCTX *p)
+{
+    return p->flags;
+}
+
+void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
+{
+    p->flags = flags;
+}
+
+unsigned long ASN1_PCTX_get_nm_flags(const ASN1_PCTX *p)
+{
+    return p->nm_flags;
+}
+
+void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
+{
+    p->nm_flags = flags;
+}
+
+unsigned long ASN1_PCTX_get_cert_flags(const ASN1_PCTX *p)
+{
+    return p->cert_flags;
+}
+
+void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
+{
+    p->cert_flags = flags;
+}
+
+unsigned long ASN1_PCTX_get_oid_flags(const ASN1_PCTX *p)
+{
+    return p->oid_flags;
+}
+
+void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
+{
+    p->oid_flags = flags;
+}
+
+unsigned long ASN1_PCTX_get_str_flags(const ASN1_PCTX *p)
+{
+    return p->str_flags;
+}
+
+void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
+{
+    p->str_flags = flags;
+}
+
+/* Main print routines */
+
+static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+                               const ASN1_ITEM *it,
+                               const char *fname, const char *sname,
+                               int nohdr, const ASN1_PCTX *pctx);
+
+static int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+                            const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
+
+static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
+                                const ASN1_ITEM *it, int indent,
+                                const char *fname, const char *sname,
+                                const ASN1_PCTX *pctx);
+
+static int asn1_print_fsname(BIO *out, int indent,
+                             const char *fname, const char *sname,
+                             const ASN1_PCTX *pctx);
+
+int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
+                    const ASN1_ITEM *it, const ASN1_PCTX *pctx)
+{
+    const char *sname;
+    if (pctx == NULL)
+        pctx = &default_pctx;
+    if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
+        sname = NULL;
+    else
+        sname = it->sname;
+    return asn1_item_print_ctx(out, &ifld, indent, it, NULL, sname, 0, pctx);
+}
+
+static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+                               const ASN1_ITEM *it,
+                               const char *fname, const char *sname,
+                               int nohdr, const ASN1_PCTX *pctx)
+{
+    const ASN1_TEMPLATE *tt;
+    const ASN1_EXTERN_FUNCS *ef;
+    ASN1_VALUE **tmpfld;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_aux_cb *asn1_cb;
+    ASN1_PRINT_ARG parg;
+    int i;
+    if (aux && aux->asn1_cb) {
+        parg.out = out;
+        parg.indent = indent;
+        parg.pctx = pctx;
+        asn1_cb = aux->asn1_cb;
+    } else
+        asn1_cb = 0;
+
+   if (((it->itype != ASN1_ITYPE_PRIMITIVE)
+       || (it->utype != V_ASN1_BOOLEAN)) && *fld == NULL) {
+        if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) {
+            if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+                return 0;
+            if (BIO_puts(out, "<ABSENT>\n") <= 0)
+                return 0;
+        }
+        return 1;
+    }
+
+    switch (it->itype) {
+    case ASN1_ITYPE_PRIMITIVE:
+        if (it->templates) {
+            if (!asn1_template_print_ctx(out, fld, indent,
+                                         it->templates, pctx))
+                return 0;
+            break;
+        }
+        /* fall through */
+    case ASN1_ITYPE_MSTRING:
+        if (!asn1_primitive_print(out, fld, it, indent, fname, sname, pctx))
+            return 0;
+        break;
+
+    case ASN1_ITYPE_EXTERN:
+        if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+            return 0;
+        /* Use new style print routine if possible */
+        ef = it->funcs;
+        if (ef && ef->asn1_ex_print) {
+            i = ef->asn1_ex_print(out, fld, indent, "", pctx);
+            if (!i)
+                return 0;
+            if ((i == 2) && (BIO_puts(out, "\n") <= 0))
+                return 0;
+            return 1;
+        } else if (sname &&
+                   BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
+            return 0;
+        break;
+
+    case ASN1_ITYPE_CHOICE:
+        /* CHOICE type, get selector */
+        i = asn1_get_choice_selector(fld, it);
+        /* This should never happen... */
+        if ((i < 0) || (i >= it->tcount)) {
+            if (BIO_printf(out, "ERROR: selector [%d] invalid\n", i) <= 0)
+                return 0;
+            return 1;
+        }
+        tt = it->templates + i;
+        tmpfld = asn1_get_field_ptr(fld, tt);
+        if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
+            return 0;
+        break;
+
+    case ASN1_ITYPE_SEQUENCE:
+    case ASN1_ITYPE_NDEF_SEQUENCE:
+        if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
+            return 0;
+        if (fname || sname) {
+            if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
+                if (BIO_puts(out, " {\n") <= 0)
+                    return 0;
+            } else {
+                if (BIO_puts(out, "\n") <= 0)
+                    return 0;
+            }
+        }
+
+        if (asn1_cb) {
+            i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
+            if (i == 0)
+                return 0;
+            if (i == 2)
+                return 1;
+        }
+
+        /* Print each field entry */
+        for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
+            const ASN1_TEMPLATE *seqtt;
+            seqtt = asn1_do_adb(fld, tt, 1);
+            if (!seqtt)
+                return 0;
+            tmpfld = asn1_get_field_ptr(fld, seqtt);
+            if (!asn1_template_print_ctx(out, tmpfld,
+                                         indent + 2, seqtt, pctx))
+                return 0;
+        }
+        if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
+            if (BIO_printf(out, "%*s}\n", indent, "") < 0)
+                return 0;
+        }
+
+        if (asn1_cb) {
+            i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
+            if (i == 0)
+                return 0;
+        }
+        break;
+
+    default:
+        BIO_printf(out, "Unprocessed type %d\n", it->itype);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
+                            const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
+{
+    int i, flags;
+    const char *sname, *fname;
+    ASN1_VALUE *tfld;
+    flags = tt->flags;
+    if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
+        sname = ASN1_ITEM_ptr(tt->item)->sname;
+    else
+        sname = NULL;
+    if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
+        fname = NULL;
+    else
+        fname = tt->field_name;
+
+    /*
+     * If field is embedded then fld needs fixing so it is a pointer to
+     * a pointer to a field.
+     */
+    if (flags & ASN1_TFLG_EMBED) {
+        tfld = (ASN1_VALUE *)fld;
+        fld = &tfld;
+    }
+
+    if (flags & ASN1_TFLG_SK_MASK) {
+        char *tname;
+        ASN1_VALUE *skitem;
+        STACK_OF(ASN1_VALUE) *stack;
+
+        /* SET OF, SEQUENCE OF */
+        if (fname) {
+            if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) {
+                if (flags & ASN1_TFLG_SET_OF)
+                    tname = "SET";
+                else
+                    tname = "SEQUENCE";
+                if (BIO_printf(out, "%*s%s OF %s {\n",
+                               indent, "", tname, tt->field_name) <= 0)
+                    return 0;
+            } else if (BIO_printf(out, "%*s%s:\n", indent, "", fname) <= 0)
+                return 0;
+        }
+        stack = (STACK_OF(ASN1_VALUE) *)*fld;
+        for (i = 0; i < sk_ASN1_VALUE_num(stack); i++) {
+            if ((i > 0) && (BIO_puts(out, "\n") <= 0))
+                return 0;
+
+            skitem = sk_ASN1_VALUE_value(stack, i);
+            if (!asn1_item_print_ctx(out, &skitem, indent + 2,
+                                     ASN1_ITEM_ptr(tt->item), NULL, NULL, 1,
+                                     pctx))
+                return 0;
+        }
+        if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0)
+            return 0;
+        if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
+            if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
+                return 0;
+        }
+        return 1;
+    }
+    return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
+                               fname, sname, 0, pctx);
+}
+
+static int asn1_print_fsname(BIO *out, int indent,
+                             const char *fname, const char *sname,
+                             const ASN1_PCTX *pctx)
+{
+    static const char spaces[] = "                    ";
+    static const int nspaces = sizeof(spaces) - 1;
+
+    while (indent > nspaces) {
+        if (BIO_write(out, spaces, nspaces) != nspaces)
+            return 0;
+        indent -= nspaces;
+    }
+    if (BIO_write(out, spaces, indent) != indent)
+        return 0;
+    if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
+        sname = NULL;
+    if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
+        fname = NULL;
+    if (!sname && !fname)
+        return 1;
+    if (fname) {
+        if (BIO_puts(out, fname) <= 0)
+            return 0;
+    }
+    if (sname) {
+        if (fname) {
+            if (BIO_printf(out, " (%s)", sname) <= 0)
+                return 0;
+        } else {
+            if (BIO_puts(out, sname) <= 0)
+                return 0;
+        }
+    }
+    if (BIO_write(out, ": ", 2) != 2)
+        return 0;
+    return 1;
+}
+
+static int asn1_print_boolean(BIO *out, int boolval)
+{
+    const char *str;
+    switch (boolval) {
+    case -1:
+        str = "BOOL ABSENT";
+        break;
+
+    case 0:
+        str = "FALSE";
+        break;
+
+    default:
+        str = "TRUE";
+        break;
+
+    }
+
+    if (BIO_puts(out, str) <= 0)
+        return 0;
+    return 1;
+
+}
+
+static int asn1_print_integer(BIO *out, const ASN1_INTEGER *str)
+{
+    char *s;
+    int ret = 1;
+    s = i2s_ASN1_INTEGER(NULL, str);
+    if (s == NULL)
+        return 0;
+    if (BIO_puts(out, s) <= 0)
+        ret = 0;
+    OPENSSL_free(s);
+    return ret;
+}
+
+static int asn1_print_oid(BIO *out, const ASN1_OBJECT *oid)
+{
+    char objbuf[80];
+    const char *ln;
+    ln = OBJ_nid2ln(OBJ_obj2nid(oid));
+    if (!ln)
+        ln = "";
+    OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1);
+    if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
+        return 0;
+    return 1;
+}
+
+static int asn1_print_obstring(BIO *out, const ASN1_STRING *str, int indent)
+{
+    if (str->type == V_ASN1_BIT_STRING) {
+        if (BIO_printf(out, " (%ld unused bits)\n", str->flags & 0x7) <= 0)
+            return 0;
+    } else if (BIO_puts(out, "\n") <= 0)
+        return 0;
+    if ((str->length > 0)
+        && BIO_dump_indent(out, (const char *)str->data, str->length,
+                           indent + 2) <= 0)
+        return 0;
+    return 1;
+}
+
+static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
+                                const ASN1_ITEM *it, int indent,
+                                const char *fname, const char *sname,
+                                const ASN1_PCTX *pctx)
+{
+    long utype;
+    ASN1_STRING *str;
+    int ret = 1, needlf = 1;
+    const char *pname;
+    const ASN1_PRIMITIVE_FUNCS *pf;
+    pf = it->funcs;
+    if (!asn1_print_fsname(out, indent, fname, sname, pctx))
+        return 0;
+    if (pf && pf->prim_print)
+        return pf->prim_print(out, fld, it, indent, pctx);
+    if (it->itype == ASN1_ITYPE_MSTRING) {
+        str = (ASN1_STRING *)*fld;
+        utype = str->type & ~V_ASN1_NEG;
+    } else {
+        utype = it->utype;
+        if (utype == V_ASN1_BOOLEAN)
+            str = NULL;
+        else
+            str = (ASN1_STRING *)*fld;
+    }
+    if (utype == V_ASN1_ANY) {
+        ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
+        utype = atype->type;
+        fld = &atype->value.asn1_value;
+        str = (ASN1_STRING *)*fld;
+        if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
+            pname = NULL;
+        else
+            pname = ASN1_tag2str(utype);
+    } else {
+        if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
+            pname = ASN1_tag2str(utype);
+        else
+            pname = NULL;
+    }
+
+    if (utype == V_ASN1_NULL) {
+        if (BIO_puts(out, "NULL\n") <= 0)
+            return 0;
+        return 1;
+    }
+
+    if (pname) {
+        if (BIO_puts(out, pname) <= 0)
+            return 0;
+        if (BIO_puts(out, ":") <= 0)
+            return 0;
+    }
+
+    switch (utype) {
+    case V_ASN1_BOOLEAN:
+        {
+            int boolval = *(int *)fld;
+            if (boolval == -1)
+                boolval = it->size;
+            ret = asn1_print_boolean(out, boolval);
+        }
+        break;
+
+    case V_ASN1_INTEGER:
+    case V_ASN1_ENUMERATED:
+        ret = asn1_print_integer(out, str);
+        break;
+
+    case V_ASN1_UTCTIME:
+        ret = ASN1_UTCTIME_print(out, str);
+        break;
+
+    case V_ASN1_GENERALIZEDTIME:
+        ret = ASN1_GENERALIZEDTIME_print(out, str);
+        break;
+
+    case V_ASN1_OBJECT:
+        ret = asn1_print_oid(out, (const ASN1_OBJECT *)*fld);
+        break;
+
+    case V_ASN1_OCTET_STRING:
+    case V_ASN1_BIT_STRING:
+        ret = asn1_print_obstring(out, str, indent);
+        needlf = 0;
+        break;
+
+    case V_ASN1_SEQUENCE:
+    case V_ASN1_SET:
+    case V_ASN1_OTHER:
+        if (BIO_puts(out, "\n") <= 0)
+            return 0;
+        if (ASN1_parse_dump(out, str->data, str->length, indent, 0) <= 0)
+            ret = 0;
+        needlf = 0;
+        break;
+
+    default:
+        ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
+
+    }
+    if (!ret)
+        return 0;
+    if (needlf && BIO_puts(out, "\n") <= 0)
+        return 0;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_scn.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_scn.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_scn.c	(revision 331)
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2010-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 <stddef.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+#include "asn1_locl.h"
+
+/*
+ * General ASN1 structure recursive scanner: iterate through all fields
+ * passing details to a callback.
+ */
+
+ASN1_SCTX *ASN1_SCTX_new(int (*scan_cb) (ASN1_SCTX *ctx))
+{
+    ASN1_SCTX *ret = OPENSSL_zalloc(sizeof(*ret));
+
+    if (ret == NULL) {
+        ASN1err(ASN1_F_ASN1_SCTX_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    ret->scan_cb = scan_cb;
+    return ret;
+}
+
+void ASN1_SCTX_free(ASN1_SCTX *p)
+{
+    OPENSSL_free(p);
+}
+
+const ASN1_ITEM *ASN1_SCTX_get_item(ASN1_SCTX *p)
+{
+    return p->it;
+}
+
+const ASN1_TEMPLATE *ASN1_SCTX_get_template(ASN1_SCTX *p)
+{
+    return p->tt;
+}
+
+unsigned long ASN1_SCTX_get_flags(ASN1_SCTX *p)
+{
+    return p->flags;
+}
+
+void ASN1_SCTX_set_app_data(ASN1_SCTX *p, void *data)
+{
+    p->app_data = data;
+}
+
+void *ASN1_SCTX_get_app_data(ASN1_SCTX *p)
+{
+    return p->app_data;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_typ.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_typ.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_typ.c	(revision 331)
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2000-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 <stdio.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+
+/* Declarations for string types */
+
+#define IMPLEMENT_ASN1_STRING_FUNCTIONS(sname) \
+    IMPLEMENT_ASN1_TYPE(sname) \
+    IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(sname, sname, sname) \
+sname *sname##_new(void) \
+{ \
+    return ASN1_STRING_type_new(V_##sname); \
+} \
+void sname##_free(sname *x) \
+{ \
+    ASN1_STRING_free(x); \
+}
+
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_OCTET_STRING)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_INTEGER)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_ENUMERATED)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_BIT_STRING)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UTF8STRING)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_PRINTABLESTRING)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_T61STRING)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_IA5STRING)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_GENERALSTRING)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UTCTIME)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_GENERALIZEDTIME)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_VISIBLESTRING)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UNIVERSALSTRING)
+IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_BMPSTRING)
+
+IMPLEMENT_ASN1_TYPE(ASN1_NULL)
+IMPLEMENT_ASN1_FUNCTIONS(ASN1_NULL)
+
+IMPLEMENT_ASN1_TYPE(ASN1_OBJECT)
+
+IMPLEMENT_ASN1_TYPE(ASN1_ANY)
+
+/* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */
+IMPLEMENT_ASN1_TYPE(ASN1_SEQUENCE)
+
+IMPLEMENT_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
+
+/* Multistring types */
+
+IMPLEMENT_ASN1_MSTRING(ASN1_PRINTABLE, B_ASN1_PRINTABLE)
+IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE)
+
+IMPLEMENT_ASN1_MSTRING(DISPLAYTEXT, B_ASN1_DISPLAYTEXT)
+IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT)
+
+IMPLEMENT_ASN1_MSTRING(DIRECTORYSTRING, B_ASN1_DIRECTORYSTRING)
+IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
+
+/* Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE */
+IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, -1)
+IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, 1)
+IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0)
+
+/* Special, OCTET STRING with indefinite length constructed support */
+
+IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING, ASN1_TFLG_NDEF)
+
+ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY)
+ASN1_ITEM_TEMPLATE_END(ASN1_SEQUENCE_ANY)
+
+ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ASN1_SET_ANY, ASN1_ANY)
+ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN1_SET_ANY)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_utl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_utl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/tasn_utl.c	(revision 331)
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2000-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 <stddef.h>
+#include <string.h>
+#include <internal/cryptlib.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+#include <openssl/err.h>
+#include "asn1_locl.h"
+
+/* Utility functions for manipulating fields and offsets */
+
+/* Add 'offset' to 'addr' */
+#define offset2ptr(addr, offset) (void *)(((char *) addr) + offset)
+
+/*
+ * Given an ASN1_ITEM CHOICE type return the selector value
+ */
+
+int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    int *sel = offset2ptr(*pval, it->utype);
+    return *sel;
+}
+
+/*
+ * Given an ASN1_ITEM CHOICE type set the selector value, return old value.
+ */
+
+int asn1_set_choice_selector(ASN1_VALUE **pval, int value,
+                             const ASN1_ITEM *it)
+{
+    int *sel, ret;
+    sel = offset2ptr(*pval, it->utype);
+    ret = *sel;
+    *sel = value;
+    return ret;
+}
+
+/*
+ * Do atomic reference counting. The value 'op' decides what to do.
+ * If it is +1 then the count is incremented.
+ * If |op| is 0, lock is initialised and count is set to 1.
+ * If |op| is -1, count is decremented and the return value is the current
+ * reference count or 0 if no reference count is active.
+ * It returns -1 on initialisation error.
+ * Used by ASN1_SEQUENCE construct of X509, X509_REQ, X509_CRL objects
+ */
+int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
+{
+    const ASN1_AUX *aux;
+    int *lck, ret;
+    CRYPTO_RWLOCK **lock;
+    if ((it->itype != ASN1_ITYPE_SEQUENCE)
+        && (it->itype != ASN1_ITYPE_NDEF_SEQUENCE))
+        return 0;
+    aux = it->funcs;
+    if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT))
+        return 0;
+    lck = offset2ptr(*pval, aux->ref_offset);
+    lock = offset2ptr(*pval, aux->ref_lock);
+    if (op == 0) {
+        *lck = 1;
+        *lock = CRYPTO_THREAD_lock_new();
+        if (*lock == NULL) {
+            ASN1err(ASN1_F_ASN1_DO_LOCK, ERR_R_MALLOC_FAILURE);
+            return -1;
+        }
+        return 1;
+    }
+    if (CRYPTO_atomic_add(lck, op, &ret, *lock) < 0)
+        return -1;  /* failed */
+#ifdef REF_PRINT
+    fprintf(stderr, "%p:%4d:%s\n", it, *lck, it->sname);
+#endif
+    REF_ASSERT_ISNT(ret < 0);
+    if (ret == 0) {
+        CRYPTO_THREAD_lock_free(*lock);
+        *lock = NULL;
+    }
+    return ret;
+}
+
+static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    const ASN1_AUX *aux;
+    if (!pval || !*pval)
+        return NULL;
+    aux = it->funcs;
+    if (!aux || !(aux->flags & ASN1_AFLG_ENCODING))
+        return NULL;
+    return offset2ptr(*pval, aux->enc_offset);
+}
+
+void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    ASN1_ENCODING *enc;
+    enc = asn1_get_enc_ptr(pval, it);
+    if (enc) {
+        enc->enc = NULL;
+        enc->len = 0;
+        enc->modified = 1;
+    }
+}
+
+void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    ASN1_ENCODING *enc;
+    enc = asn1_get_enc_ptr(pval, it);
+    if (enc) {
+        OPENSSL_free(enc->enc);
+        enc->enc = NULL;
+        enc->len = 0;
+        enc->modified = 1;
+    }
+}
+
+int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
+                  const ASN1_ITEM *it)
+{
+    ASN1_ENCODING *enc;
+    enc = asn1_get_enc_ptr(pval, it);
+    if (!enc)
+        return 1;
+
+    OPENSSL_free(enc->enc);
+    enc->enc = OPENSSL_malloc(inlen);
+    if (enc->enc == NULL)
+        return 0;
+    memcpy(enc->enc, in, inlen);
+    enc->len = inlen;
+    enc->modified = 0;
+
+    return 1;
+}
+
+int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
+                     const ASN1_ITEM *it)
+{
+    ASN1_ENCODING *enc;
+    enc = asn1_get_enc_ptr(pval, it);
+    if (!enc || enc->modified)
+        return 0;
+    if (out) {
+        memcpy(*out, enc->enc, enc->len);
+        *out += enc->len;
+    }
+    if (len)
+        *len = enc->len;
+    return 1;
+}
+
+/* Given an ASN1_TEMPLATE get a pointer to a field */
+ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
+{
+    ASN1_VALUE **pvaltmp;
+    pvaltmp = offset2ptr(*pval, tt->offset);
+    /*
+     * NOTE for BOOLEAN types the field is just a plain int so we can't
+     * return int **, so settle for (int *).
+     */
+    return pvaltmp;
+}
+
+/*
+ * Handle ANY DEFINED BY template, find the selector, look up the relevant
+ * ASN1_TEMPLATE in the table and return it.
+ */
+
+const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
+                                 int nullerr)
+{
+    const ASN1_ADB *adb;
+    const ASN1_ADB_TABLE *atbl;
+    long selector;
+    ASN1_VALUE **sfld;
+    int i;
+    if (!(tt->flags & ASN1_TFLG_ADB_MASK))
+        return tt;
+
+    /* Else ANY DEFINED BY ... get the table */
+    adb = ASN1_ADB_ptr(tt->item);
+
+    /* Get the selector field */
+    sfld = offset2ptr(*pval, adb->offset);
+
+    /* Check if NULL */
+    if (*sfld == NULL) {
+        if (!adb->null_tt)
+            goto err;
+        return adb->null_tt;
+    }
+
+    /*
+     * Convert type to a long: NB: don't check for NID_undef here because it
+     * might be a legitimate value in the table
+     */
+    if (tt->flags & ASN1_TFLG_ADB_OID)
+        selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld);
+    else
+        selector = ASN1_INTEGER_get((ASN1_INTEGER *)*sfld);
+
+    /* Let application callback translate value */
+    if (adb->adb_cb != NULL && adb->adb_cb(&selector) == 0) {
+        ASN1err(ASN1_F_ASN1_DO_ADB, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
+        return NULL;
+    }
+
+    /*
+     * Try to find matching entry in table Maybe should check application
+     * types first to allow application override? Might also be useful to
+     * have a flag which indicates table is sorted and we can do a binary
+     * search. For now stick to a linear search.
+     */
+
+    for (atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++)
+        if (atbl->value == selector)
+            return &atbl->tt;
+
+    /* FIXME: need to search application table too */
+
+    /* No match, return default type */
+    if (!adb->default_tt)
+        goto err;
+    return adb->default_tt;
+
+ err:
+    /* FIXME: should log the value or OID of unsupported type */
+    if (nullerr)
+        ASN1err(ASN1_F_ASN1_DO_ADB, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_algor.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_algor.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_algor.c	(revision 331)
@@ -0,0 +1,93 @@
+/*
+ * Copyright 1998-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 <stddef.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include "internal/evp_int.h"
+
+ASN1_SEQUENCE(X509_ALGOR) = {
+        ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT),
+        ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY)
+} ASN1_SEQUENCE_END(X509_ALGOR)
+
+ASN1_ITEM_TEMPLATE(X509_ALGORS) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR)
+ASN1_ITEM_TEMPLATE_END(X509_ALGORS)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_ALGOR)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_ALGORS, X509_ALGORS, X509_ALGORS)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_ALGOR)
+
+int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval)
+{
+    if (!alg)
+        return 0;
+    if (ptype != V_ASN1_UNDEF) {
+        if (alg->parameter == NULL)
+            alg->parameter = ASN1_TYPE_new();
+        if (alg->parameter == NULL)
+            return 0;
+    }
+    if (alg) {
+        ASN1_OBJECT_free(alg->algorithm);
+        alg->algorithm = aobj;
+    }
+    if (ptype == 0)
+        return 1;
+    if (ptype == V_ASN1_UNDEF) {
+        ASN1_TYPE_free(alg->parameter);
+        alg->parameter = NULL;
+    } else
+        ASN1_TYPE_set(alg->parameter, ptype, pval);
+    return 1;
+}
+
+void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype,
+                     const void **ppval, const X509_ALGOR *algor)
+{
+    if (paobj)
+        *paobj = algor->algorithm;
+    if (pptype) {
+        if (algor->parameter == NULL) {
+            *pptype = V_ASN1_UNDEF;
+            return;
+        } else
+            *pptype = algor->parameter->type;
+        if (ppval)
+            *ppval = algor->parameter->value.ptr;
+    }
+}
+
+/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
+
+void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
+{
+    int param_type;
+
+    if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
+        param_type = V_ASN1_UNDEF;
+    else
+        param_type = V_ASN1_NULL;
+
+    X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
+
+}
+
+int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
+{
+    int rv;
+    rv = OBJ_cmp(a->algorithm, b->algorithm);
+    if (rv)
+        return rv;
+    if (!a->parameter && !b->parameter)
+        return 0;
+    return ASN1_TYPE_cmp(a->parameter, b->parameter);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_bignum.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_bignum.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_bignum.c	(revision 331)
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2000-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/bn.h>
+
+/*
+ * Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER
+ * as a BIGNUM directly. Currently it ignores the sign which isn't a problem
+ * since all BIGNUMs used are non negative and anything that looks negative
+ * is normally due to an encoding error.
+ */
+
+#define BN_SENSITIVE    1
+
+static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static int bn_secure_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+                  const ASN1_ITEM *it);
+static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                  int utype, char *free_cont, const ASN1_ITEM *it);
+static int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                         int utype, char *free_cont, const ASN1_ITEM *it);
+static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                    int indent, const ASN1_PCTX *pctx);
+
+static ASN1_PRIMITIVE_FUNCS bignum_pf = {
+    NULL, 0,
+    bn_new,
+    bn_free,
+    0,
+    bn_c2i,
+    bn_i2c,
+    bn_print
+};
+
+static ASN1_PRIMITIVE_FUNCS cbignum_pf = {
+    NULL, 0,
+    bn_secure_new,
+    bn_free,
+    0,
+    bn_secure_c2i,
+    bn_i2c,
+    bn_print
+};
+
+ASN1_ITEM_start(BIGNUM)
+        ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM"
+ASN1_ITEM_end(BIGNUM)
+
+ASN1_ITEM_start(CBIGNUM)
+        ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &cbignum_pf, BN_SENSITIVE, "CBIGNUM"
+ASN1_ITEM_end(CBIGNUM)
+
+static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    *pval = (ASN1_VALUE *)BN_new();
+    if (*pval != NULL)
+        return 1;
+    else
+        return 0;
+}
+
+static int bn_secure_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    *pval = (ASN1_VALUE *)BN_secure_new();
+    if (*pval != NULL)
+        return 1;
+    else
+        return 0;
+}
+
+static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    if (!*pval)
+        return;
+    if (it->size & BN_SENSITIVE)
+        BN_clear_free((BIGNUM *)*pval);
+    else
+        BN_free((BIGNUM *)*pval);
+    *pval = NULL;
+}
+
+static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+                  const ASN1_ITEM *it)
+{
+    BIGNUM *bn;
+    int pad;
+    if (!*pval)
+        return -1;
+    bn = (BIGNUM *)*pval;
+    /* If MSB set in an octet we need a padding byte */
+    if (BN_num_bits(bn) & 0x7)
+        pad = 0;
+    else
+        pad = 1;
+    if (cont) {
+        if (pad)
+            *cont++ = 0;
+        BN_bn2bin(bn, cont);
+    }
+    return pad + BN_num_bytes(bn);
+}
+
+static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                  int utype, char *free_cont, const ASN1_ITEM *it)
+{
+    BIGNUM *bn;
+
+    if (*pval == NULL && !bn_new(pval, it))
+        return 0;
+    bn = (BIGNUM *)*pval;
+    if (!BN_bin2bn(cont, len, bn)) {
+        bn_free(pval, it);
+        return 0;
+    }
+    return 1;
+}
+
+static int bn_secure_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                         int utype, char *free_cont, const ASN1_ITEM *it)
+{
+    if (!*pval)
+        bn_secure_new(pval, it);
+    return bn_c2i(pval, cont, len, utype, free_cont, it);
+}
+
+static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                    int indent, const ASN1_PCTX *pctx)
+{
+    if (!BN_print(out, *(BIGNUM **)pval))
+        return 0;
+    if (BIO_puts(out, "\n") <= 0)
+        return 0;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_info.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_info.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_info.c	(revision 331)
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+
+X509_INFO *X509_INFO_new(void)
+{
+    X509_INFO *ret;
+
+    ret = OPENSSL_zalloc(sizeof(*ret));
+    if (ret == NULL) {
+        ASN1err(ASN1_F_X509_INFO_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    return ret;
+}
+
+void X509_INFO_free(X509_INFO *x)
+{
+    if (x == NULL)
+        return;
+
+    X509_free(x->x509);
+    X509_CRL_free(x->crl);
+    X509_PKEY_free(x->x_pkey);
+    OPENSSL_free(x->enc_data);
+    OPENSSL_free(x);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_long.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_long.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_long.c	(revision 331)
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2000-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/bn.h>
+
+/*
+ * Custom primitive type for long handling. This converts between an
+ * ASN1_INTEGER and a long directly.
+ */
+
+static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+                    const ASN1_ITEM *it);
+static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                    int utype, char *free_cont, const ASN1_ITEM *it);
+static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                      int indent, const ASN1_PCTX *pctx);
+
+static ASN1_PRIMITIVE_FUNCS long_pf = {
+    NULL, 0,
+    long_new,
+    long_free,
+    long_free,                  /* Clear should set to initial value */
+    long_c2i,
+    long_i2c,
+    long_print
+};
+
+ASN1_ITEM_start(LONG)
+        ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG"
+ASN1_ITEM_end(LONG)
+
+ASN1_ITEM_start(ZLONG)
+        ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG"
+ASN1_ITEM_end(ZLONG)
+
+static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    *(long *)pval = it->size;
+    return 1;
+}
+
+static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    *(long *)pval = it->size;
+}
+
+static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
+                    const ASN1_ITEM *it)
+{
+    long ltmp;
+    unsigned long utmp;
+    int clen, pad, i;
+    /* this exists to bypass broken gcc optimization */
+    char *cp = (char *)pval;
+
+    /* use memcpy, because we may not be long aligned */
+    memcpy(&ltmp, cp, sizeof(long));
+
+    if (ltmp == it->size)
+        return -1;
+    /*
+     * Convert the long to positive: we subtract one if negative so we can
+     * cleanly handle the padding if only the MSB of the leading octet is
+     * set.
+     */
+    if (ltmp < 0)
+        utmp = 0 - (unsigned long)ltmp - 1;
+    else
+        utmp = ltmp;
+    clen = BN_num_bits_word(utmp);
+    /* If MSB of leading octet set we need to pad */
+    if (!(clen & 0x7))
+        pad = 1;
+    else
+        pad = 0;
+
+    /* Convert number of bits to number of octets */
+    clen = (clen + 7) >> 3;
+
+    if (cont) {
+        if (pad)
+            *cont++ = (ltmp < 0) ? 0xff : 0;
+        for (i = clen - 1; i >= 0; i--) {
+            cont[i] = (unsigned char)(utmp & 0xff);
+            if (ltmp < 0)
+                cont[i] ^= 0xff;
+            utmp >>= 8;
+        }
+    }
+    return clen + pad;
+}
+
+static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
+                    int utype, char *free_cont, const ASN1_ITEM *it)
+{
+    int neg, i;
+    long ltmp;
+    unsigned long utmp = 0;
+    char *cp = (char *)pval;
+    if (len > (int)sizeof(long)) {
+        ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+        return 0;
+    }
+    /* Is it negative? */
+    if (len && (cont[0] & 0x80))
+        neg = 1;
+    else
+        neg = 0;
+    utmp = 0;
+    for (i = 0; i < len; i++) {
+        utmp <<= 8;
+        if (neg)
+            utmp |= cont[i] ^ 0xff;
+        else
+            utmp |= cont[i];
+    }
+    ltmp = (long)utmp;
+    if (neg) {
+        ltmp = -ltmp;
+        ltmp--;
+    }
+    if (ltmp == it->size) {
+        ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+        return 0;
+    }
+    memcpy(cp, &ltmp, sizeof(long));
+    return 1;
+}
+
+static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                      int indent, const ASN1_PCTX *pctx)
+{
+    return BIO_printf(out, "%ld\n", *(long *)pval);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_pkey.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_pkey.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_pkey.c	(revision 331)
@@ -0,0 +1,47 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+X509_PKEY *X509_PKEY_new(void)
+{
+    X509_PKEY *ret = NULL;
+
+    ret = OPENSSL_zalloc(sizeof(*ret));
+    if (ret == NULL)
+        goto err;
+
+    ret->enc_algor = X509_ALGOR_new();
+    ret->enc_pkey = ASN1_OCTET_STRING_new();
+    if (ret->enc_algor == NULL || ret->enc_pkey == NULL)
+        goto err;
+
+    return ret;
+err:
+    X509_PKEY_free(ret);
+    ASN1err(ASN1_F_X509_PKEY_NEW, ERR_R_MALLOC_FAILURE);
+    return NULL;
+}
+
+void X509_PKEY_free(X509_PKEY *x)
+{
+    if (x == NULL)
+        return;
+
+    X509_ALGOR_free(x->enc_algor);
+    ASN1_OCTET_STRING_free(x->enc_pkey);
+    EVP_PKEY_free(x->dec_pkey);
+    if (x->key_free)
+        OPENSSL_free(x->key_data);
+    OPENSSL_free(x);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_sig.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_sig.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_sig.c	(revision 331)
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+
+ASN1_SEQUENCE(X509_SIG) = {
+        ASN1_SIMPLE(X509_SIG, algor, X509_ALGOR),
+        ASN1_SIMPLE(X509_SIG, digest, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(X509_SIG)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_SIG)
+
+void X509_SIG_get0(const X509_SIG *sig, const X509_ALGOR **palg,
+                   const ASN1_OCTET_STRING **pdigest)
+{
+    if (palg)
+        *palg = sig->algor;
+    if (pdigest)
+        *pdigest = sig->digest;
+}
+
+void X509_SIG_getm(X509_SIG *sig, X509_ALGOR **palg,
+                   ASN1_OCTET_STRING **pdigest)
+{
+    if (palg)
+        *palg = sig->algor;
+    if (pdigest)
+        *pdigest = sig->digest;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_spki.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_spki.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_spki.c	(revision 331)
@@ -0,0 +1,33 @@
+/*
+ * Copyright 1995-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
+ */
+
+ /*
+  * This module was send to me my Pat Richards <patr@x509.com> who wrote it.
+  * It is under my Copyright with his permission
+  */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/asn1t.h>
+
+ASN1_SEQUENCE(NETSCAPE_SPKAC) = {
+        ASN1_SIMPLE(NETSCAPE_SPKAC, pubkey, X509_PUBKEY),
+        ASN1_SIMPLE(NETSCAPE_SPKAC, challenge, ASN1_IA5STRING)
+} ASN1_SEQUENCE_END(NETSCAPE_SPKAC)
+
+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
+
+ASN1_SEQUENCE(NETSCAPE_SPKI) = {
+        ASN1_SIMPLE(NETSCAPE_SPKI, spkac, NETSCAPE_SPKAC),
+        ASN1_EMBED(NETSCAPE_SPKI, sig_algor, X509_ALGOR),
+        ASN1_SIMPLE(NETSCAPE_SPKI, signature, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END(NETSCAPE_SPKI)
+
+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKI)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_val.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_val.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/asn1/x_val.c	(revision 331)
@@ -0,0 +1,20 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+
+ASN1_SEQUENCE(X509_VAL) = {
+        ASN1_SIMPLE(X509_VAL, notBefore, ASN1_TIME),
+        ASN1_SIMPLE(X509_VAL, notAfter, ASN1_TIME)
+} ASN1_SEQUENCE_END(X509_VAL)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_VAL)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/arch/async_null.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/arch/async_null.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/arch/async_null.c	(revision 331)
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2015-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
+ */
+
+/* This must be the first #include file */
+#include "../async_locl.h"
+
+#ifdef ASYNC_NULL
+int ASYNC_is_capable(void)
+{
+    return 0;
+}
+
+void async_local_cleanup(void)
+{
+}
+#endif
+
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/arch/async_null.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/arch/async_null.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/arch/async_null.h	(revision 331)
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015-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 <openssl/async.h>
+
+/*
+ * If we haven't managed to detect any other async architecture then we default
+ * to NULL.
+ */
+#ifndef ASYNC_ARCH
+# define ASYNC_NULL
+# define ASYNC_ARCH
+
+typedef struct async_fibre_st {
+    int dummy;
+} async_fibre;
+
+
+# define async_fibre_swapcontext(o,n,r)         0
+# define async_fibre_makecontext(c)             0
+# define async_fibre_free(f)
+# define async_fibre_init_dispatcher(f)
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/arch/async_posix.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/arch/async_posix.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/arch/async_posix.c	(revision 331)
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2015-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
+ */
+
+/* This must be the first #include file */
+#include "../async_locl.h"
+
+#ifdef ASYNC_POSIX
+
+# include <stddef.h>
+# include <unistd.h>
+
+#define STACKSIZE       32768
+
+int ASYNC_is_capable(void)
+{
+    ucontext_t ctx;
+
+    /*
+     * Some platforms provide getcontext() but it does not work (notably
+     * MacOSX PPC64). Check for a working getcontext();
+     */
+    return getcontext(&ctx) == 0;
+}
+
+void async_local_cleanup(void)
+{
+}
+
+int async_fibre_makecontext(async_fibre *fibre)
+{
+    fibre->env_init = 0;
+    if (getcontext(&fibre->fibre) == 0) {
+        fibre->fibre.uc_stack.ss_sp = OPENSSL_malloc(STACKSIZE);
+        if (fibre->fibre.uc_stack.ss_sp != NULL) {
+            fibre->fibre.uc_stack.ss_size = STACKSIZE;
+            fibre->fibre.uc_link = NULL;
+            makecontext(&fibre->fibre, async_start_func, 0);
+            return 1;
+        }
+    } else {
+        fibre->fibre.uc_stack.ss_sp = NULL;
+    }
+    return 0;
+}
+
+void async_fibre_free(async_fibre *fibre)
+{
+    OPENSSL_free(fibre->fibre.uc_stack.ss_sp);
+    fibre->fibre.uc_stack.ss_sp = NULL;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/arch/async_posix.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/arch/async_posix.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/arch/async_posix.h	(revision 331)
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2015-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
+ */
+
+#ifndef OPENSSL_ASYNC_ARCH_ASYNC_POSIX_H
+#define OPENSSL_ASYNC_ARCH_ASYNC_POSIX_H
+#include <openssl/e_os2.h>
+
+#if (defined(OPENSSL_SYS_UNIX) || defined(OPENSSL_SYS_CYGWIN)) \
+    && defined(OPENSSL_THREADS) && !defined(OPENSSL_NO_ASYNC) \
+    && !defined(__ANDROID__) && !defined(__OpenBSD__)
+
+# include <unistd.h>
+
+# if _POSIX_VERSION >= 200112L
+
+# include <pthread.h>
+
+#  define ASYNC_POSIX
+#  define ASYNC_ARCH
+
+#  include <ucontext.h>
+#  include <setjmp.h>
+#  include "e_os.h"
+
+typedef struct async_fibre_st {
+    ucontext_t fibre;
+    jmp_buf env;
+    int env_init;
+} async_fibre;
+
+static ossl_inline int async_fibre_swapcontext(async_fibre *o, async_fibre *n, int r)
+{
+    o->env_init = 1;
+
+    if (!r || !_setjmp(o->env)) {
+        if (n->env_init)
+            _longjmp(n->env, 1);
+        else
+            setcontext(&n->fibre);
+    }
+
+    return 1;
+}
+
+#  define async_fibre_init_dispatcher(d)
+
+int async_fibre_makecontext(async_fibre *fibre);
+void async_fibre_free(async_fibre *fibre);
+
+# endif
+#endif
+#endif /* OPENSSL_ASYNC_ARCH_ASYNC_POSIX_H */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/arch/async_win.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/arch/async_win.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/arch/async_win.c	(revision 331)
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2015-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
+ */
+
+/* This must be the first #include file */
+#include "../async_locl.h"
+
+#ifdef ASYNC_WIN
+
+# include <windows.h>
+# include "internal/cryptlib.h"
+
+int ASYNC_is_capable(void)
+{
+    return 1;
+}
+
+void async_local_cleanup(void)
+{
+    async_ctx *ctx = async_get_ctx();
+    if (ctx != NULL) {
+        async_fibre *fibre = &ctx->dispatcher;
+        if (fibre != NULL && fibre->fibre != NULL && fibre->converted) {
+            ConvertFiberToThread();
+            fibre->fibre = NULL;
+        }
+    }
+}
+
+int async_fibre_init_dispatcher(async_fibre *fibre)
+{
+    fibre->fibre = ConvertThreadToFiber(NULL);
+    if (fibre->fibre == NULL) {
+        fibre->converted = 0;
+        fibre->fibre = GetCurrentFiber();
+        if (fibre->fibre == NULL)
+            return 0;
+    } else {
+        fibre->converted = 1;
+    }
+
+    return 1;
+}
+
+VOID CALLBACK async_start_func_win(PVOID unused)
+{
+    async_start_func();
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/arch/async_win.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/arch/async_win.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/arch/async_win.h	(revision 331)
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2015-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
+ */
+
+/*
+ * This is the same detection used in cryptlib to set up the thread local
+ * storage that we depend on, so just copy that
+ */
+#if defined(_WIN32) && !defined(OPENSSL_NO_ASYNC)
+#include <openssl/async.h>
+# define ASYNC_WIN
+# define ASYNC_ARCH
+
+# include <windows.h>
+# include "internal/cryptlib.h"
+
+typedef struct async_fibre_st {
+    LPVOID fibre;
+    int converted;
+} async_fibre;
+
+# define async_fibre_swapcontext(o,n,r) \
+        (SwitchToFiber((n)->fibre), 1)
+# define async_fibre_makecontext(c) \
+        ((c)->fibre = CreateFiber(0, async_start_func_win, 0))
+# define async_fibre_free(f)             (DeleteFiber((f)->fibre))
+
+int async_fibre_init_dispatcher(async_fibre *fibre);
+VOID CALLBACK async_start_func_win(PVOID unused);
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/async.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/async.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/async.c	(revision 331)
@@ -0,0 +1,433 @@
+/*
+ * Copyright 2015-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
+ */
+
+/*
+ * Without this we start getting longjmp crashes because it thinks we're jumping
+ * up the stack when in fact we are jumping to an entirely different stack. The
+ * cost of this is not having certain buffer overrun/underrun checks etc for
+ * this source file :-(
+ */
+#undef _FORTIFY_SOURCE
+
+/* This must be the first #include file */
+#include "async_locl.h"
+
+#include <openssl/err.h>
+#include <internal/cryptlib_int.h>
+#include <string.h>
+
+#define ASYNC_JOB_RUNNING   0
+#define ASYNC_JOB_PAUSING   1
+#define ASYNC_JOB_PAUSED    2
+#define ASYNC_JOB_STOPPING  3
+
+static CRYPTO_THREAD_LOCAL ctxkey;
+static CRYPTO_THREAD_LOCAL poolkey;
+
+static void async_free_pool_internal(async_pool *pool);
+
+static async_ctx *async_ctx_new(void)
+{
+    async_ctx *nctx = NULL;
+
+    nctx = OPENSSL_malloc(sizeof (async_ctx));
+    if (nctx == NULL) {
+        ASYNCerr(ASYNC_F_ASYNC_CTX_NEW, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    async_fibre_init_dispatcher(&nctx->dispatcher);
+    nctx->currjob = NULL;
+    nctx->blocked = 0;
+    if (!CRYPTO_THREAD_set_local(&ctxkey, nctx))
+        goto err;
+
+    return nctx;
+err:
+    OPENSSL_free(nctx);
+
+    return NULL;
+}
+
+async_ctx *async_get_ctx(void)
+{
+    if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL))
+        return NULL;
+
+    return (async_ctx *)CRYPTO_THREAD_get_local(&ctxkey);
+}
+
+static int async_ctx_free(void)
+{
+    async_ctx *ctx;
+
+    ctx = async_get_ctx();
+
+    if (!CRYPTO_THREAD_set_local(&ctxkey, NULL))
+        return 0;
+
+    OPENSSL_free(ctx);
+
+    return 1;
+}
+
+static ASYNC_JOB *async_job_new(void)
+{
+    ASYNC_JOB *job = NULL;
+
+    job = OPENSSL_zalloc(sizeof (ASYNC_JOB));
+    if (job == NULL) {
+        ASYNCerr(ASYNC_F_ASYNC_JOB_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    job->status = ASYNC_JOB_RUNNING;
+
+    return job;
+}
+
+static void async_job_free(ASYNC_JOB *job)
+{
+    if (job != NULL) {
+        OPENSSL_free(job->funcargs);
+        async_fibre_free(&job->fibrectx);
+        OPENSSL_free(job);
+    }
+}
+
+static ASYNC_JOB *async_get_pool_job(void) {
+    ASYNC_JOB *job;
+    async_pool *pool;
+
+    pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey);
+    if (pool == NULL) {
+        /*
+         * Pool has not been initialised, so init with the defaults, i.e.
+         * no max size and no pre-created jobs
+         */
+        if (ASYNC_init_thread(0, 0) == 0)
+            return NULL;
+        pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey);
+    }
+
+    job = sk_ASYNC_JOB_pop(pool->jobs);
+    if (job == NULL) {
+        /* Pool is empty */
+        if ((pool->max_size != 0) && (pool->curr_size >= pool->max_size))
+            return NULL;
+
+        job = async_job_new();
+        if (job != NULL) {
+            if (! async_fibre_makecontext(&job->fibrectx)) {
+                async_job_free(job);
+                return NULL;
+            }
+            pool->curr_size++;
+        }
+    }
+    return job;
+}
+
+static void async_release_job(ASYNC_JOB *job) {
+    async_pool *pool;
+
+    pool = (async_pool *)CRYPTO_THREAD_get_local(&poolkey);
+    OPENSSL_free(job->funcargs);
+    job->funcargs = NULL;
+    sk_ASYNC_JOB_push(pool->jobs, job);
+}
+
+void async_start_func(void)
+{
+    ASYNC_JOB *job;
+    async_ctx *ctx = async_get_ctx();
+
+    while (1) {
+        /* Run the job */
+        job = ctx->currjob;
+        job->ret = job->func(job->funcargs);
+
+        /* Stop the job */
+        job->status = ASYNC_JOB_STOPPING;
+        if (!async_fibre_swapcontext(&job->fibrectx,
+                                     &ctx->dispatcher, 1)) {
+            /*
+             * Should not happen. Getting here will close the thread...can't do
+             * much about it
+             */
+            ASYNCerr(ASYNC_F_ASYNC_START_FUNC, ASYNC_R_FAILED_TO_SWAP_CONTEXT);
+        }
+    }
+}
+
+int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *wctx, int *ret,
+                    int (*func)(void *), void *args, size_t size)
+{
+    async_ctx *ctx = async_get_ctx();
+    if (ctx == NULL)
+        ctx = async_ctx_new();
+    if (ctx == NULL) {
+        return ASYNC_ERR;
+    }
+
+    if (*job) {
+        ctx->currjob = *job;
+    }
+
+    for (;;) {
+        if (ctx->currjob != NULL) {
+            if (ctx->currjob->status == ASYNC_JOB_STOPPING) {
+                *ret = ctx->currjob->ret;
+                ctx->currjob->waitctx = NULL;
+                async_release_job(ctx->currjob);
+                ctx->currjob = NULL;
+                *job = NULL;
+                return ASYNC_FINISH;
+            }
+
+            if (ctx->currjob->status == ASYNC_JOB_PAUSING) {
+                *job = ctx->currjob;
+                ctx->currjob->status = ASYNC_JOB_PAUSED;
+                ctx->currjob = NULL;
+                return ASYNC_PAUSE;
+            }
+
+            if (ctx->currjob->status == ASYNC_JOB_PAUSED) {
+                ctx->currjob = *job;
+                /* Resume previous job */
+                if (!async_fibre_swapcontext(&ctx->dispatcher,
+                        &ctx->currjob->fibrectx, 1)) {
+                    ASYNCerr(ASYNC_F_ASYNC_START_JOB,
+                             ASYNC_R_FAILED_TO_SWAP_CONTEXT);
+                    goto err;
+                }
+                continue;
+            }
+
+            /* Should not happen */
+            ASYNCerr(ASYNC_F_ASYNC_START_JOB, ERR_R_INTERNAL_ERROR);
+            async_release_job(ctx->currjob);
+            ctx->currjob = NULL;
+            *job = NULL;
+            return ASYNC_ERR;
+        }
+
+        /* Start a new job */
+        if ((ctx->currjob = async_get_pool_job()) == NULL) {
+            return ASYNC_NO_JOBS;
+        }
+
+        if (args != NULL) {
+            ctx->currjob->funcargs = OPENSSL_malloc(size);
+            if (ctx->currjob->funcargs == NULL) {
+                ASYNCerr(ASYNC_F_ASYNC_START_JOB, ERR_R_MALLOC_FAILURE);
+                async_release_job(ctx->currjob);
+                ctx->currjob = NULL;
+                return ASYNC_ERR;
+            }
+            memcpy(ctx->currjob->funcargs, args, size);
+        } else {
+            ctx->currjob->funcargs = NULL;
+        }
+
+        ctx->currjob->func = func;
+        ctx->currjob->waitctx = wctx;
+        if (!async_fibre_swapcontext(&ctx->dispatcher,
+                &ctx->currjob->fibrectx, 1)) {
+            ASYNCerr(ASYNC_F_ASYNC_START_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT);
+            goto err;
+        }
+    }
+
+err:
+    async_release_job(ctx->currjob);
+    ctx->currjob = NULL;
+    *job = NULL;
+    return ASYNC_ERR;
+}
+
+int ASYNC_pause_job(void)
+{
+    ASYNC_JOB *job;
+    async_ctx *ctx = async_get_ctx();
+
+    if (ctx == NULL
+            || ctx->currjob == NULL
+            || ctx->blocked) {
+        /*
+         * Could be we've deliberately not been started within a job so this is
+         * counted as success.
+         */
+        return 1;
+    }
+
+    job = ctx->currjob;
+    job->status = ASYNC_JOB_PAUSING;
+
+    if (!async_fibre_swapcontext(&job->fibrectx,
+                                 &ctx->dispatcher, 1)) {
+        ASYNCerr(ASYNC_F_ASYNC_PAUSE_JOB, ASYNC_R_FAILED_TO_SWAP_CONTEXT);
+        return 0;
+    }
+    /* Reset counts of added and deleted fds */
+    async_wait_ctx_reset_counts(job->waitctx);
+
+    return 1;
+}
+
+static void async_empty_pool(async_pool *pool)
+{
+    ASYNC_JOB *job;
+
+    if (!pool || !pool->jobs)
+        return;
+
+    do {
+        job = sk_ASYNC_JOB_pop(pool->jobs);
+        async_job_free(job);
+    } while (job);
+}
+
+int async_init(void)
+{
+    if (!CRYPTO_THREAD_init_local(&ctxkey, NULL))
+        return 0;
+
+    if (!CRYPTO_THREAD_init_local(&poolkey, NULL)) {
+        CRYPTO_THREAD_cleanup_local(&ctxkey);
+        return 0;
+    }
+
+    return 1;
+}
+
+void async_deinit(void)
+{
+    CRYPTO_THREAD_cleanup_local(&ctxkey);
+    CRYPTO_THREAD_cleanup_local(&poolkey);
+}
+
+int ASYNC_init_thread(size_t max_size, size_t init_size)
+{
+    async_pool *pool;
+    size_t curr_size = 0;
+
+    if (init_size > max_size) {
+        ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_INVALID_POOL_SIZE);
+        return 0;
+    }
+
+    if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) {
+        return 0;
+    }
+    if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_ASYNC)) {
+        return 0;
+    }
+
+    pool = OPENSSL_zalloc(sizeof *pool);
+    if (pool == NULL) {
+        ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    pool->jobs = sk_ASYNC_JOB_new_null();
+    if (pool->jobs == NULL) {
+        ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(pool);
+        return 0;
+    }
+
+    pool->max_size = max_size;
+
+    /* Pre-create jobs as required */
+    while (init_size--) {
+        ASYNC_JOB *job;
+        job = async_job_new();
+        if (job == NULL || !async_fibre_makecontext(&job->fibrectx)) {
+            /*
+             * Not actually fatal because we already created the pool, just
+             * skip creation of any more jobs
+             */
+            async_job_free(job);
+            break;
+        }
+        job->funcargs = NULL;
+        sk_ASYNC_JOB_push(pool->jobs, job);
+        curr_size++;
+    }
+    pool->curr_size = curr_size;
+    if (!CRYPTO_THREAD_set_local(&poolkey, pool)) {
+        ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ASYNC_R_FAILED_TO_SET_POOL);
+        goto err;
+    }
+
+    return 1;
+err:
+    async_free_pool_internal(pool);
+    return 0;
+}
+
+static void async_free_pool_internal(async_pool *pool)
+{
+    if (pool == NULL)
+        return;
+
+    async_empty_pool(pool);
+    sk_ASYNC_JOB_free(pool->jobs);
+    OPENSSL_free(pool);
+    CRYPTO_THREAD_set_local(&poolkey, NULL);
+    async_local_cleanup();
+    async_ctx_free();
+}
+
+void ASYNC_cleanup_thread(void)
+{
+    async_free_pool_internal((async_pool *)CRYPTO_THREAD_get_local(&poolkey));
+}
+
+ASYNC_JOB *ASYNC_get_current_job(void)
+{
+    async_ctx *ctx;
+
+    ctx = async_get_ctx();
+    if (ctx == NULL)
+        return NULL;
+
+    return ctx->currjob;
+}
+
+ASYNC_WAIT_CTX *ASYNC_get_wait_ctx(ASYNC_JOB *job)
+{
+    return job->waitctx;
+}
+
+void ASYNC_block_pause(void)
+{
+    async_ctx *ctx = async_get_ctx();
+    if (ctx == NULL || ctx->currjob == NULL) {
+        /*
+         * We're not in a job anyway so ignore this
+         */
+        return;
+    }
+    ctx->blocked++;
+}
+
+void ASYNC_unblock_pause(void)
+{
+    async_ctx *ctx = async_get_ctx();
+    if (ctx == NULL || ctx->currjob == NULL) {
+        /*
+         * We're not in a job anyway so ignore this
+         */
+        return;
+    }
+    if (ctx->blocked > 0)
+        ctx->blocked--;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/async_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/async_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/async_err.c	(revision 331)
@@ -0,0 +1,51 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/async.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ASYNC,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ASYNC,0,reason)
+
+static ERR_STRING_DATA ASYNC_str_functs[] = {
+    {ERR_FUNC(ASYNC_F_ASYNC_CTX_NEW), "async_ctx_new"},
+    {ERR_FUNC(ASYNC_F_ASYNC_INIT_THREAD), "ASYNC_init_thread"},
+    {ERR_FUNC(ASYNC_F_ASYNC_JOB_NEW), "async_job_new"},
+    {ERR_FUNC(ASYNC_F_ASYNC_PAUSE_JOB), "ASYNC_pause_job"},
+    {ERR_FUNC(ASYNC_F_ASYNC_START_FUNC), "async_start_func"},
+    {ERR_FUNC(ASYNC_F_ASYNC_START_JOB), "ASYNC_start_job"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA ASYNC_str_reasons[] = {
+    {ERR_REASON(ASYNC_R_FAILED_TO_SET_POOL), "failed to set pool"},
+    {ERR_REASON(ASYNC_R_FAILED_TO_SWAP_CONTEXT), "failed to swap context"},
+    {ERR_REASON(ASYNC_R_INIT_FAILED), "init failed"},
+    {ERR_REASON(ASYNC_R_INVALID_POOL_SIZE), "invalid pool size"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_ASYNC_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(ASYNC_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, ASYNC_str_functs);
+        ERR_load_strings(0, ASYNC_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/async_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/async_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/async_locl.h	(revision 331)
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2015-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
+ */
+
+/*
+ * Must do this before including any header files, because on MacOS/X <stlib.h>
+ * includes <signal.h> which includes <ucontext.h>
+ */
+#if defined(__APPLE__) && defined(__MACH__) && !defined(_XOPEN_SOURCE)
+# define _XOPEN_SOURCE          /* Otherwise incomplete ucontext_t structure */
+# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
+#if defined(_WIN32)
+# include <windows.h>
+#endif
+
+#include <internal/async.h>
+#include <openssl/crypto.h>
+
+typedef struct async_ctx_st async_ctx;
+typedef struct async_pool_st async_pool;
+
+#include "arch/async_win.h"
+#include "arch/async_posix.h"
+#include "arch/async_null.h"
+
+struct async_ctx_st {
+    async_fibre dispatcher;
+    ASYNC_JOB *currjob;
+    unsigned int blocked;
+};
+
+struct async_job_st {
+    async_fibre fibrectx;
+    int (*func) (void *);
+    void *funcargs;
+    int ret;
+    int status;
+    ASYNC_WAIT_CTX *waitctx;
+};
+
+struct fd_lookup_st {
+    const void *key;
+    OSSL_ASYNC_FD fd;
+    void *custom_data;
+    void (*cleanup)(ASYNC_WAIT_CTX *, const void *, OSSL_ASYNC_FD, void *);
+    int add;
+    int del;
+    struct fd_lookup_st *next;
+};
+
+struct async_wait_ctx_st {
+    struct fd_lookup_st *fds;
+    size_t numadd;
+    size_t numdel;
+};
+
+DEFINE_STACK_OF(ASYNC_JOB)
+
+struct async_pool_st {
+    STACK_OF(ASYNC_JOB) *jobs;
+    size_t curr_size;
+    size_t max_size;
+};
+
+void async_local_cleanup(void);
+void async_start_func(void);
+async_ctx *async_get_ctx(void);
+
+void async_wait_ctx_reset_counts(ASYNC_WAIT_CTX *ctx);
+
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/async_wait.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/async_wait.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/async/async_wait.c	(revision 331)
@@ -0,0 +1,211 @@
+/*
+ * 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
+ */
+
+/* This must be the first #include file */
+#include "async_locl.h"
+
+#include <openssl/err.h>
+
+ASYNC_WAIT_CTX *ASYNC_WAIT_CTX_new(void)
+{
+    return OPENSSL_zalloc(sizeof(ASYNC_WAIT_CTX));
+}
+
+void ASYNC_WAIT_CTX_free(ASYNC_WAIT_CTX *ctx)
+{
+    struct fd_lookup_st *curr;
+    struct fd_lookup_st *next;
+
+    if (ctx == NULL)
+        return;
+
+    curr = ctx->fds;
+    while (curr != NULL) {
+        if (!curr->del) {
+            /* Only try and cleanup if it hasn't been marked deleted */
+            if (curr->cleanup != NULL)
+                curr->cleanup(ctx, curr->key, curr->fd, curr->custom_data);
+        }
+        /* Always free the fd_lookup_st */
+        next = curr->next;
+        OPENSSL_free(curr);
+        curr = next;
+    }
+
+    OPENSSL_free(ctx);
+}
+int ASYNC_WAIT_CTX_set_wait_fd(ASYNC_WAIT_CTX *ctx, const void *key,
+                               OSSL_ASYNC_FD fd, void *custom_data,
+                               void (*cleanup)(ASYNC_WAIT_CTX *, const void *,
+                                               OSSL_ASYNC_FD, void *))
+{
+    struct fd_lookup_st *fdlookup;
+
+    fdlookup = OPENSSL_zalloc(sizeof *fdlookup);
+    if (fdlookup == NULL)
+        return 0;
+
+    fdlookup->key = key;
+    fdlookup->fd = fd;
+    fdlookup->custom_data = custom_data;
+    fdlookup->cleanup = cleanup;
+    fdlookup->add = 1;
+    fdlookup->next = ctx->fds;
+    ctx->fds = fdlookup;
+    ctx->numadd++;
+    return 1;
+}
+
+int ASYNC_WAIT_CTX_get_fd(ASYNC_WAIT_CTX *ctx, const void *key,
+                          OSSL_ASYNC_FD *fd, void **custom_data)
+{
+    struct fd_lookup_st *curr;
+
+    curr = ctx->fds;
+    while (curr != NULL) {
+        if (curr->del) {
+            /* This one has been marked deleted so do nothing */
+            curr = curr->next;
+            continue;
+        }
+        if (curr->key == key) {
+            *fd = curr->fd;
+            *custom_data = curr->custom_data;
+            return 1;
+        }
+        curr = curr->next;
+    }
+    return 0;
+}
+
+int ASYNC_WAIT_CTX_get_all_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *fd,
+                               size_t *numfds)
+{
+    struct fd_lookup_st *curr;
+
+    curr = ctx->fds;
+    *numfds = 0;
+    while (curr != NULL) {
+        if (curr->del) {
+            /* This one has been marked deleted so do nothing */
+            curr = curr->next;
+            continue;
+        }
+        if (fd != NULL) {
+            *fd = curr->fd;
+            fd++;
+        }
+        (*numfds)++;
+        curr = curr->next;
+    }
+    return 1;
+}
+
+int ASYNC_WAIT_CTX_get_changed_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *addfd,
+                                   size_t *numaddfds, OSSL_ASYNC_FD *delfd,
+                                   size_t *numdelfds)
+{
+    struct fd_lookup_st *curr;
+
+    *numaddfds = ctx->numadd;
+    *numdelfds = ctx->numdel;
+    if (addfd == NULL && delfd == NULL)
+        return 1;
+
+    curr = ctx->fds;
+
+    while (curr != NULL) {
+        /* We ignore fds that have been marked as both added and deleted */
+        if (curr->del && !curr->add && (delfd != NULL)) {
+            *delfd = curr->fd;
+            delfd++;
+        }
+        if (curr->add && !curr->del && (addfd != NULL)) {
+            *addfd = curr->fd;
+            addfd++;
+        }
+        curr = curr->next;
+    }
+
+    return 1;
+}
+
+int ASYNC_WAIT_CTX_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key)
+{
+    struct fd_lookup_st *curr, *prev;
+
+    curr = ctx->fds;
+    prev = NULL;
+    while (curr != NULL) {
+        if (curr->del == 1) {
+            /* This one has been marked deleted already so do nothing */
+            curr = curr->next;
+            continue;
+        }
+        if (curr->key == key) {
+            /* If fd has just been added, remove it from the list */
+            if (curr->add == 1) {
+                if (ctx->fds == curr) {
+                    ctx->fds = curr->next;
+                } else {
+                    prev->next = curr->next;
+                }
+
+                /* It is responsibility of the caller to cleanup before calling
+                 * ASYNC_WAIT_CTX_clear_fd
+                 */
+                OPENSSL_free(curr);
+                ctx->numadd--;
+                return 1;
+            }
+
+            /*
+             * Mark it as deleted. We don't call cleanup if explicitly asked
+             * to clear an fd. We assume the caller is going to do that (if
+             * appropriate).
+             */
+            curr->del = 1;
+            ctx->numdel++;
+            return 1;
+        }
+        prev = curr;
+        curr = curr->next;
+    }
+    return 0;
+}
+
+void async_wait_ctx_reset_counts(ASYNC_WAIT_CTX *ctx)
+{
+    struct fd_lookup_st *curr, *prev = NULL;
+
+    ctx->numadd = 0;
+    ctx->numdel = 0;
+
+    curr = ctx->fds;
+
+    while (curr != NULL) {
+        if (curr->del) {
+            if (prev == NULL)
+                ctx->fds = curr->next;
+            else
+                prev->next = curr->next;
+            OPENSSL_free(curr);
+            if (prev == NULL)
+                curr = ctx->fds;
+            else
+                curr = prev->next;
+            continue;
+        }
+        if (curr->add) {
+            curr->add = 0;
+        }
+        prev = curr;
+        curr = curr->next;
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_cfb64.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_cfb64.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_cfb64.c	(revision 331)
@@ -0,0 +1,74 @@
+/*
+ * Copyright 1995-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 <openssl/blowfish.h>
+#include "bf_locl.h"
+
+/*
+ * The input and output encrypted as though 64bit cfb mode is being used.
+ * The extra state information to record how much of the 64bit block we have
+ * used is contained in *num;
+ */
+
+void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                      long length, const BF_KEY *schedule,
+                      unsigned char *ivec, int *num, int encrypt)
+{
+    register BF_LONG v0, v1, t;
+    register int n = *num;
+    register long l = length;
+    BF_LONG ti[2];
+    unsigned char *iv, c, cc;
+
+    iv = (unsigned char *)ivec;
+    if (encrypt) {
+        while (l--) {
+            if (n == 0) {
+                n2l(iv, v0);
+                ti[0] = v0;
+                n2l(iv, v1);
+                ti[1] = v1;
+                BF_encrypt((BF_LONG *)ti, schedule);
+                iv = (unsigned char *)ivec;
+                t = ti[0];
+                l2n(t, iv);
+                t = ti[1];
+                l2n(t, iv);
+                iv = (unsigned char *)ivec;
+            }
+            c = *(in++) ^ iv[n];
+            *(out++) = c;
+            iv[n] = c;
+            n = (n + 1) & 0x07;
+        }
+    } else {
+        while (l--) {
+            if (n == 0) {
+                n2l(iv, v0);
+                ti[0] = v0;
+                n2l(iv, v1);
+                ti[1] = v1;
+                BF_encrypt((BF_LONG *)ti, schedule);
+                iv = (unsigned char *)ivec;
+                t = ti[0];
+                l2n(t, iv);
+                t = ti[1];
+                l2n(t, iv);
+                iv = (unsigned char *)ivec;
+            }
+            cc = *(in++);
+            c = iv[n];
+            iv[n] = cc;
+            *(out++) = c ^ cc;
+            n = (n + 1) & 0x07;
+        }
+    }
+    v0 = v1 = ti[0] = ti[1] = t = c = cc = 0;
+    *num = n;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_ecb.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_ecb.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_ecb.c	(revision 331)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 1995-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 <openssl/blowfish.h>
+#include "bf_locl.h"
+#include <openssl/opensslv.h>
+
+/*
+ * Blowfish as implemented from 'Blowfish: Springer-Verlag paper' (From
+ * LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION, CAMBRIDGE
+ * SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993)
+ */
+
+const char *BF_options(void)
+{
+    return ("blowfish(ptr)");
+}
+
+void BF_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                    const BF_KEY *key, int encrypt)
+{
+    BF_LONG l, d[2];
+
+    n2l(in, l);
+    d[0] = l;
+    n2l(in, l);
+    d[1] = l;
+    if (encrypt)
+        BF_encrypt(d, key);
+    else
+        BF_decrypt(d, key);
+    l = d[0];
+    l2n(l, out);
+    l = d[1];
+    l2n(l, out);
+    l = d[0] = d[1] = 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_enc.c	(revision 331)
@@ -0,0 +1,179 @@
+/*
+ * Copyright 1995-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 <openssl/blowfish.h>
+#include "bf_locl.h"
+
+/*
+ * Blowfish as implemented from 'Blowfish: Springer-Verlag paper' (From
+ * LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION, CAMBRIDGE
+ * SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993)
+ */
+
+#if (BF_ROUNDS != 16) && (BF_ROUNDS != 20)
+# error If you set BF_ROUNDS to some value other than 16 or 20, you will have \
+to modify the code.
+#endif
+
+void BF_encrypt(BF_LONG *data, const BF_KEY *key)
+{
+    register BF_LONG l, r;
+    register const BF_LONG *p, *s;
+
+    p = key->P;
+    s = &(key->S[0]);
+    l = data[0];
+    r = data[1];
+
+    l ^= p[0];
+    BF_ENC(r, l, s, p[1]);
+    BF_ENC(l, r, s, p[2]);
+    BF_ENC(r, l, s, p[3]);
+    BF_ENC(l, r, s, p[4]);
+    BF_ENC(r, l, s, p[5]);
+    BF_ENC(l, r, s, p[6]);
+    BF_ENC(r, l, s, p[7]);
+    BF_ENC(l, r, s, p[8]);
+    BF_ENC(r, l, s, p[9]);
+    BF_ENC(l, r, s, p[10]);
+    BF_ENC(r, l, s, p[11]);
+    BF_ENC(l, r, s, p[12]);
+    BF_ENC(r, l, s, p[13]);
+    BF_ENC(l, r, s, p[14]);
+    BF_ENC(r, l, s, p[15]);
+    BF_ENC(l, r, s, p[16]);
+# if BF_ROUNDS == 20
+    BF_ENC(r, l, s, p[17]);
+    BF_ENC(l, r, s, p[18]);
+    BF_ENC(r, l, s, p[19]);
+    BF_ENC(l, r, s, p[20]);
+# endif
+    r ^= p[BF_ROUNDS + 1];
+
+    data[1] = l & 0xffffffffU;
+    data[0] = r & 0xffffffffU;
+}
+
+#ifndef BF_DEFAULT_OPTIONS
+
+void BF_decrypt(BF_LONG *data, const BF_KEY *key)
+{
+    register BF_LONG l, r;
+    register const BF_LONG *p, *s;
+
+    p = key->P;
+    s = &(key->S[0]);
+    l = data[0];
+    r = data[1];
+
+    l ^= p[BF_ROUNDS + 1];
+#  if BF_ROUNDS == 20
+    BF_ENC(r, l, s, p[20]);
+    BF_ENC(l, r, s, p[19]);
+    BF_ENC(r, l, s, p[18]);
+    BF_ENC(l, r, s, p[17]);
+#  endif
+    BF_ENC(r, l, s, p[16]);
+    BF_ENC(l, r, s, p[15]);
+    BF_ENC(r, l, s, p[14]);
+    BF_ENC(l, r, s, p[13]);
+    BF_ENC(r, l, s, p[12]);
+    BF_ENC(l, r, s, p[11]);
+    BF_ENC(r, l, s, p[10]);
+    BF_ENC(l, r, s, p[9]);
+    BF_ENC(r, l, s, p[8]);
+    BF_ENC(l, r, s, p[7]);
+    BF_ENC(r, l, s, p[6]);
+    BF_ENC(l, r, s, p[5]);
+    BF_ENC(r, l, s, p[4]);
+    BF_ENC(l, r, s, p[3]);
+    BF_ENC(r, l, s, p[2]);
+    BF_ENC(l, r, s, p[1]);
+    r ^= p[0];
+
+    data[1] = l & 0xffffffffU;
+    data[0] = r & 0xffffffffU;
+}
+
+void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+                    const BF_KEY *schedule, unsigned char *ivec, int encrypt)
+{
+    register BF_LONG tin0, tin1;
+    register BF_LONG tout0, tout1, xor0, xor1;
+    register long l = length;
+    BF_LONG tin[2];
+
+    if (encrypt) {
+        n2l(ivec, tout0);
+        n2l(ivec, tout1);
+        ivec -= 8;
+        for (l -= 8; l >= 0; l -= 8) {
+            n2l(in, tin0);
+            n2l(in, tin1);
+            tin0 ^= tout0;
+            tin1 ^= tout1;
+            tin[0] = tin0;
+            tin[1] = tin1;
+            BF_encrypt(tin, schedule);
+            tout0 = tin[0];
+            tout1 = tin[1];
+            l2n(tout0, out);
+            l2n(tout1, out);
+        }
+        if (l != -8) {
+            n2ln(in, tin0, tin1, l + 8);
+            tin0 ^= tout0;
+            tin1 ^= tout1;
+            tin[0] = tin0;
+            tin[1] = tin1;
+            BF_encrypt(tin, schedule);
+            tout0 = tin[0];
+            tout1 = tin[1];
+            l2n(tout0, out);
+            l2n(tout1, out);
+        }
+        l2n(tout0, ivec);
+        l2n(tout1, ivec);
+    } else {
+        n2l(ivec, xor0);
+        n2l(ivec, xor1);
+        ivec -= 8;
+        for (l -= 8; l >= 0; l -= 8) {
+            n2l(in, tin0);
+            n2l(in, tin1);
+            tin[0] = tin0;
+            tin[1] = tin1;
+            BF_decrypt(tin, schedule);
+            tout0 = tin[0] ^ xor0;
+            tout1 = tin[1] ^ xor1;
+            l2n(tout0, out);
+            l2n(tout1, out);
+            xor0 = tin0;
+            xor1 = tin1;
+        }
+        if (l != -8) {
+            n2l(in, tin0);
+            n2l(in, tin1);
+            tin[0] = tin0;
+            tin[1] = tin1;
+            BF_decrypt(tin, schedule);
+            tout0 = tin[0] ^ xor0;
+            tout1 = tin[1] ^ xor1;
+            l2nn(tout0, tout1, out, l + 8);
+            xor0 = tin0;
+            xor1 = tin1;
+        }
+        l2n(xor0, ivec);
+        l2n(xor1, ivec);
+    }
+    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
+    tin[0] = tin[1] = 0;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_locl.h	(revision 331)
@@ -0,0 +1,70 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_BF_LOCL_H
+# define HEADER_BF_LOCL_H
+# include <openssl/opensslconf.h>
+
+/* NOTE - c is not incremented as per n2l */
+# define n2ln(c,l1,l2,n) { \
+                        c+=n; \
+                        l1=l2=0; \
+                        switch (n) { \
+                        case 8: l2 =((unsigned long)(*(--(c))))    ; \
+                        case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
+                        case 6: l2|=((unsigned long)(*(--(c))))<<16; \
+                        case 5: l2|=((unsigned long)(*(--(c))))<<24; \
+                        case 4: l1 =((unsigned long)(*(--(c))))    ; \
+                        case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
+                        case 2: l1|=((unsigned long)(*(--(c))))<<16; \
+                        case 1: l1|=((unsigned long)(*(--(c))))<<24; \
+                                } \
+                        }
+
+/* NOTE - c is not incremented as per l2n */
+# define l2nn(l1,l2,c,n) { \
+                        c+=n; \
+                        switch (n) { \
+                        case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
+                        case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+                        case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+                        case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+                        case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
+                        case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+                        case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+                        case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+                                } \
+                        }
+
+# undef n2l
+# define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
+                         l|=((unsigned long)(*((c)++)))<<16L, \
+                         l|=((unsigned long)(*((c)++)))<< 8L, \
+                         l|=((unsigned long)(*((c)++))))
+
+# undef l2n
+# define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)     )&0xff))
+
+/*
+ * This is actually a big endian algorithm, the most significant byte is used
+ * to lookup array 0
+ */
+
+# define BF_ENC(LL,R,S,P) ( \
+        LL^=P, \
+        LL^=((( S[       ((R>>24)&0xff)] + \
+                S[0x0100+((R>>16)&0xff)])^ \
+                S[0x0200+((R>> 8)&0xff)])+ \
+                S[0x0300+((R    )&0xff)])&0xffffffffU \
+        )
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_ofb64.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_ofb64.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_ofb64.c	(revision 331)
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1995-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 <openssl/blowfish.h>
+#include "bf_locl.h"
+
+/*
+ * The input and output encrypted as though 64bit ofb mode is being used.
+ * The extra state information to record how much of the 64bit block we have
+ * used is contained in *num;
+ */
+void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+                      long length, const BF_KEY *schedule,
+                      unsigned char *ivec, int *num)
+{
+    register BF_LONG v0, v1, t;
+    register int n = *num;
+    register long l = length;
+    unsigned char d[8];
+    register char *dp;
+    BF_LONG ti[2];
+    unsigned char *iv;
+    int save = 0;
+
+    iv = (unsigned char *)ivec;
+    n2l(iv, v0);
+    n2l(iv, v1);
+    ti[0] = v0;
+    ti[1] = v1;
+    dp = (char *)d;
+    l2n(v0, dp);
+    l2n(v1, dp);
+    while (l--) {
+        if (n == 0) {
+            BF_encrypt((BF_LONG *)ti, schedule);
+            dp = (char *)d;
+            t = ti[0];
+            l2n(t, dp);
+            t = ti[1];
+            l2n(t, dp);
+            save++;
+        }
+        *(out++) = *(in++) ^ d[n];
+        n = (n + 1) & 0x07;
+    }
+    if (save) {
+        v0 = ti[0];
+        v1 = ti[1];
+        iv = (unsigned char *)ivec;
+        l2n(v0, iv);
+        l2n(v1, iv);
+    }
+    t = v0 = v1 = ti[0] = ti[1] = 0;
+    *num = n;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_pi.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_pi.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_pi.h	(revision 331)
@@ -0,0 +1,530 @@
+/*
+ * Copyright 1995-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
+ */
+
+static const BF_KEY bf_init = {
+    {
+     0x243f6a88L, 0x85a308d3L, 0x13198a2eL, 0x03707344L,
+     0xa4093822L, 0x299f31d0L, 0x082efa98L, 0xec4e6c89L,
+     0x452821e6L, 0x38d01377L, 0xbe5466cfL, 0x34e90c6cL,
+     0xc0ac29b7L, 0xc97c50ddL, 0x3f84d5b5L, 0xb5470917L,
+     0x9216d5d9L, 0x8979fb1b}, {
+                                0xd1310ba6L, 0x98dfb5acL, 0x2ffd72dbL,
+                                0xd01adfb7L,
+                                0xb8e1afedL, 0x6a267e96L, 0xba7c9045L,
+                                0xf12c7f99L,
+                                0x24a19947L, 0xb3916cf7L, 0x0801f2e2L,
+                                0x858efc16L,
+                                0x636920d8L, 0x71574e69L, 0xa458fea3L,
+                                0xf4933d7eL,
+                                0x0d95748fL, 0x728eb658L, 0x718bcd58L,
+                                0x82154aeeL,
+                                0x7b54a41dL, 0xc25a59b5L, 0x9c30d539L,
+                                0x2af26013L,
+                                0xc5d1b023L, 0x286085f0L, 0xca417918L,
+                                0xb8db38efL,
+                                0x8e79dcb0L, 0x603a180eL, 0x6c9e0e8bL,
+                                0xb01e8a3eL,
+                                0xd71577c1L, 0xbd314b27L, 0x78af2fdaL,
+                                0x55605c60L,
+                                0xe65525f3L, 0xaa55ab94L, 0x57489862L,
+                                0x63e81440L,
+                                0x55ca396aL, 0x2aab10b6L, 0xb4cc5c34L,
+                                0x1141e8ceL,
+                                0xa15486afL, 0x7c72e993L, 0xb3ee1411L,
+                                0x636fbc2aL,
+                                0x2ba9c55dL, 0x741831f6L, 0xce5c3e16L,
+                                0x9b87931eL,
+                                0xafd6ba33L, 0x6c24cf5cL, 0x7a325381L,
+                                0x28958677L,
+                                0x3b8f4898L, 0x6b4bb9afL, 0xc4bfe81bL,
+                                0x66282193L,
+                                0x61d809ccL, 0xfb21a991L, 0x487cac60L,
+                                0x5dec8032L,
+                                0xef845d5dL, 0xe98575b1L, 0xdc262302L,
+                                0xeb651b88L,
+                                0x23893e81L, 0xd396acc5L, 0x0f6d6ff3L,
+                                0x83f44239L,
+                                0x2e0b4482L, 0xa4842004L, 0x69c8f04aL,
+                                0x9e1f9b5eL,
+                                0x21c66842L, 0xf6e96c9aL, 0x670c9c61L,
+                                0xabd388f0L,
+                                0x6a51a0d2L, 0xd8542f68L, 0x960fa728L,
+                                0xab5133a3L,
+                                0x6eef0b6cL, 0x137a3be4L, 0xba3bf050L,
+                                0x7efb2a98L,
+                                0xa1f1651dL, 0x39af0176L, 0x66ca593eL,
+                                0x82430e88L,
+                                0x8cee8619L, 0x456f9fb4L, 0x7d84a5c3L,
+                                0x3b8b5ebeL,
+                                0xe06f75d8L, 0x85c12073L, 0x401a449fL,
+                                0x56c16aa6L,
+                                0x4ed3aa62L, 0x363f7706L, 0x1bfedf72L,
+                                0x429b023dL,
+                                0x37d0d724L, 0xd00a1248L, 0xdb0fead3L,
+                                0x49f1c09bL,
+                                0x075372c9L, 0x80991b7bL, 0x25d479d8L,
+                                0xf6e8def7L,
+                                0xe3fe501aL, 0xb6794c3bL, 0x976ce0bdL,
+                                0x04c006baL,
+                                0xc1a94fb6L, 0x409f60c4L, 0x5e5c9ec2L,
+                                0x196a2463L,
+                                0x68fb6fafL, 0x3e6c53b5L, 0x1339b2ebL,
+                                0x3b52ec6fL,
+                                0x6dfc511fL, 0x9b30952cL, 0xcc814544L,
+                                0xaf5ebd09L,
+                                0xbee3d004L, 0xde334afdL, 0x660f2807L,
+                                0x192e4bb3L,
+                                0xc0cba857L, 0x45c8740fL, 0xd20b5f39L,
+                                0xb9d3fbdbL,
+                                0x5579c0bdL, 0x1a60320aL, 0xd6a100c6L,
+                                0x402c7279L,
+                                0x679f25feL, 0xfb1fa3ccL, 0x8ea5e9f8L,
+                                0xdb3222f8L,
+                                0x3c7516dfL, 0xfd616b15L, 0x2f501ec8L,
+                                0xad0552abL,
+                                0x323db5faL, 0xfd238760L, 0x53317b48L,
+                                0x3e00df82L,
+                                0x9e5c57bbL, 0xca6f8ca0L, 0x1a87562eL,
+                                0xdf1769dbL,
+                                0xd542a8f6L, 0x287effc3L, 0xac6732c6L,
+                                0x8c4f5573L,
+                                0x695b27b0L, 0xbbca58c8L, 0xe1ffa35dL,
+                                0xb8f011a0L,
+                                0x10fa3d98L, 0xfd2183b8L, 0x4afcb56cL,
+                                0x2dd1d35bL,
+                                0x9a53e479L, 0xb6f84565L, 0xd28e49bcL,
+                                0x4bfb9790L,
+                                0xe1ddf2daL, 0xa4cb7e33L, 0x62fb1341L,
+                                0xcee4c6e8L,
+                                0xef20cadaL, 0x36774c01L, 0xd07e9efeL,
+                                0x2bf11fb4L,
+                                0x95dbda4dL, 0xae909198L, 0xeaad8e71L,
+                                0x6b93d5a0L,
+                                0xd08ed1d0L, 0xafc725e0L, 0x8e3c5b2fL,
+                                0x8e7594b7L,
+                                0x8ff6e2fbL, 0xf2122b64L, 0x8888b812L,
+                                0x900df01cL,
+                                0x4fad5ea0L, 0x688fc31cL, 0xd1cff191L,
+                                0xb3a8c1adL,
+                                0x2f2f2218L, 0xbe0e1777L, 0xea752dfeL,
+                                0x8b021fa1L,
+                                0xe5a0cc0fL, 0xb56f74e8L, 0x18acf3d6L,
+                                0xce89e299L,
+                                0xb4a84fe0L, 0xfd13e0b7L, 0x7cc43b81L,
+                                0xd2ada8d9L,
+                                0x165fa266L, 0x80957705L, 0x93cc7314L,
+                                0x211a1477L,
+                                0xe6ad2065L, 0x77b5fa86L, 0xc75442f5L,
+                                0xfb9d35cfL,
+                                0xebcdaf0cL, 0x7b3e89a0L, 0xd6411bd3L,
+                                0xae1e7e49L,
+                                0x00250e2dL, 0x2071b35eL, 0x226800bbL,
+                                0x57b8e0afL,
+                                0x2464369bL, 0xf009b91eL, 0x5563911dL,
+                                0x59dfa6aaL,
+                                0x78c14389L, 0xd95a537fL, 0x207d5ba2L,
+                                0x02e5b9c5L,
+                                0x83260376L, 0x6295cfa9L, 0x11c81968L,
+                                0x4e734a41L,
+                                0xb3472dcaL, 0x7b14a94aL, 0x1b510052L,
+                                0x9a532915L,
+                                0xd60f573fL, 0xbc9bc6e4L, 0x2b60a476L,
+                                0x81e67400L,
+                                0x08ba6fb5L, 0x571be91fL, 0xf296ec6bL,
+                                0x2a0dd915L,
+                                0xb6636521L, 0xe7b9f9b6L, 0xff34052eL,
+                                0xc5855664L,
+                                0x53b02d5dL, 0xa99f8fa1L, 0x08ba4799L,
+                                0x6e85076aL,
+                                0x4b7a70e9L, 0xb5b32944L, 0xdb75092eL,
+                                0xc4192623L,
+                                0xad6ea6b0L, 0x49a7df7dL, 0x9cee60b8L,
+                                0x8fedb266L,
+                                0xecaa8c71L, 0x699a17ffL, 0x5664526cL,
+                                0xc2b19ee1L,
+                                0x193602a5L, 0x75094c29L, 0xa0591340L,
+                                0xe4183a3eL,
+                                0x3f54989aL, 0x5b429d65L, 0x6b8fe4d6L,
+                                0x99f73fd6L,
+                                0xa1d29c07L, 0xefe830f5L, 0x4d2d38e6L,
+                                0xf0255dc1L,
+                                0x4cdd2086L, 0x8470eb26L, 0x6382e9c6L,
+                                0x021ecc5eL,
+                                0x09686b3fL, 0x3ebaefc9L, 0x3c971814L,
+                                0x6b6a70a1L,
+                                0x687f3584L, 0x52a0e286L, 0xb79c5305L,
+                                0xaa500737L,
+                                0x3e07841cL, 0x7fdeae5cL, 0x8e7d44ecL,
+                                0x5716f2b8L,
+                                0xb03ada37L, 0xf0500c0dL, 0xf01c1f04L,
+                                0x0200b3ffL,
+                                0xae0cf51aL, 0x3cb574b2L, 0x25837a58L,
+                                0xdc0921bdL,
+                                0xd19113f9L, 0x7ca92ff6L, 0x94324773L,
+                                0x22f54701L,
+                                0x3ae5e581L, 0x37c2dadcL, 0xc8b57634L,
+                                0x9af3dda7L,
+                                0xa9446146L, 0x0fd0030eL, 0xecc8c73eL,
+                                0xa4751e41L,
+                                0xe238cd99L, 0x3bea0e2fL, 0x3280bba1L,
+                                0x183eb331L,
+                                0x4e548b38L, 0x4f6db908L, 0x6f420d03L,
+                                0xf60a04bfL,
+                                0x2cb81290L, 0x24977c79L, 0x5679b072L,
+                                0xbcaf89afL,
+                                0xde9a771fL, 0xd9930810L, 0xb38bae12L,
+                                0xdccf3f2eL,
+                                0x5512721fL, 0x2e6b7124L, 0x501adde6L,
+                                0x9f84cd87L,
+                                0x7a584718L, 0x7408da17L, 0xbc9f9abcL,
+                                0xe94b7d8cL,
+                                0xec7aec3aL, 0xdb851dfaL, 0x63094366L,
+                                0xc464c3d2L,
+                                0xef1c1847L, 0x3215d908L, 0xdd433b37L,
+                                0x24c2ba16L,
+                                0x12a14d43L, 0x2a65c451L, 0x50940002L,
+                                0x133ae4ddL,
+                                0x71dff89eL, 0x10314e55L, 0x81ac77d6L,
+                                0x5f11199bL,
+                                0x043556f1L, 0xd7a3c76bL, 0x3c11183bL,
+                                0x5924a509L,
+                                0xf28fe6edL, 0x97f1fbfaL, 0x9ebabf2cL,
+                                0x1e153c6eL,
+                                0x86e34570L, 0xeae96fb1L, 0x860e5e0aL,
+                                0x5a3e2ab3L,
+                                0x771fe71cL, 0x4e3d06faL, 0x2965dcb9L,
+                                0x99e71d0fL,
+                                0x803e89d6L, 0x5266c825L, 0x2e4cc978L,
+                                0x9c10b36aL,
+                                0xc6150ebaL, 0x94e2ea78L, 0xa5fc3c53L,
+                                0x1e0a2df4L,
+                                0xf2f74ea7L, 0x361d2b3dL, 0x1939260fL,
+                                0x19c27960L,
+                                0x5223a708L, 0xf71312b6L, 0xebadfe6eL,
+                                0xeac31f66L,
+                                0xe3bc4595L, 0xa67bc883L, 0xb17f37d1L,
+                                0x018cff28L,
+                                0xc332ddefL, 0xbe6c5aa5L, 0x65582185L,
+                                0x68ab9802L,
+                                0xeecea50fL, 0xdb2f953bL, 0x2aef7dadL,
+                                0x5b6e2f84L,
+                                0x1521b628L, 0x29076170L, 0xecdd4775L,
+                                0x619f1510L,
+                                0x13cca830L, 0xeb61bd96L, 0x0334fe1eL,
+                                0xaa0363cfL,
+                                0xb5735c90L, 0x4c70a239L, 0xd59e9e0bL,
+                                0xcbaade14L,
+                                0xeecc86bcL, 0x60622ca7L, 0x9cab5cabL,
+                                0xb2f3846eL,
+                                0x648b1eafL, 0x19bdf0caL, 0xa02369b9L,
+                                0x655abb50L,
+                                0x40685a32L, 0x3c2ab4b3L, 0x319ee9d5L,
+                                0xc021b8f7L,
+                                0x9b540b19L, 0x875fa099L, 0x95f7997eL,
+                                0x623d7da8L,
+                                0xf837889aL, 0x97e32d77L, 0x11ed935fL,
+                                0x16681281L,
+                                0x0e358829L, 0xc7e61fd6L, 0x96dedfa1L,
+                                0x7858ba99L,
+                                0x57f584a5L, 0x1b227263L, 0x9b83c3ffL,
+                                0x1ac24696L,
+                                0xcdb30aebL, 0x532e3054L, 0x8fd948e4L,
+                                0x6dbc3128L,
+                                0x58ebf2efL, 0x34c6ffeaL, 0xfe28ed61L,
+                                0xee7c3c73L,
+                                0x5d4a14d9L, 0xe864b7e3L, 0x42105d14L,
+                                0x203e13e0L,
+                                0x45eee2b6L, 0xa3aaabeaL, 0xdb6c4f15L,
+                                0xfacb4fd0L,
+                                0xc742f442L, 0xef6abbb5L, 0x654f3b1dL,
+                                0x41cd2105L,
+                                0xd81e799eL, 0x86854dc7L, 0xe44b476aL,
+                                0x3d816250L,
+                                0xcf62a1f2L, 0x5b8d2646L, 0xfc8883a0L,
+                                0xc1c7b6a3L,
+                                0x7f1524c3L, 0x69cb7492L, 0x47848a0bL,
+                                0x5692b285L,
+                                0x095bbf00L, 0xad19489dL, 0x1462b174L,
+                                0x23820e00L,
+                                0x58428d2aL, 0x0c55f5eaL, 0x1dadf43eL,
+                                0x233f7061L,
+                                0x3372f092L, 0x8d937e41L, 0xd65fecf1L,
+                                0x6c223bdbL,
+                                0x7cde3759L, 0xcbee7460L, 0x4085f2a7L,
+                                0xce77326eL,
+                                0xa6078084L, 0x19f8509eL, 0xe8efd855L,
+                                0x61d99735L,
+                                0xa969a7aaL, 0xc50c06c2L, 0x5a04abfcL,
+                                0x800bcadcL,
+                                0x9e447a2eL, 0xc3453484L, 0xfdd56705L,
+                                0x0e1e9ec9L,
+                                0xdb73dbd3L, 0x105588cdL, 0x675fda79L,
+                                0xe3674340L,
+                                0xc5c43465L, 0x713e38d8L, 0x3d28f89eL,
+                                0xf16dff20L,
+                                0x153e21e7L, 0x8fb03d4aL, 0xe6e39f2bL,
+                                0xdb83adf7L,
+                                0xe93d5a68L, 0x948140f7L, 0xf64c261cL,
+                                0x94692934L,
+                                0x411520f7L, 0x7602d4f7L, 0xbcf46b2eL,
+                                0xd4a20068L,
+                                0xd4082471L, 0x3320f46aL, 0x43b7d4b7L,
+                                0x500061afL,
+                                0x1e39f62eL, 0x97244546L, 0x14214f74L,
+                                0xbf8b8840L,
+                                0x4d95fc1dL, 0x96b591afL, 0x70f4ddd3L,
+                                0x66a02f45L,
+                                0xbfbc09ecL, 0x03bd9785L, 0x7fac6dd0L,
+                                0x31cb8504L,
+                                0x96eb27b3L, 0x55fd3941L, 0xda2547e6L,
+                                0xabca0a9aL,
+                                0x28507825L, 0x530429f4L, 0x0a2c86daL,
+                                0xe9b66dfbL,
+                                0x68dc1462L, 0xd7486900L, 0x680ec0a4L,
+                                0x27a18deeL,
+                                0x4f3ffea2L, 0xe887ad8cL, 0xb58ce006L,
+                                0x7af4d6b6L,
+                                0xaace1e7cL, 0xd3375fecL, 0xce78a399L,
+                                0x406b2a42L,
+                                0x20fe9e35L, 0xd9f385b9L, 0xee39d7abL,
+                                0x3b124e8bL,
+                                0x1dc9faf7L, 0x4b6d1856L, 0x26a36631L,
+                                0xeae397b2L,
+                                0x3a6efa74L, 0xdd5b4332L, 0x6841e7f7L,
+                                0xca7820fbL,
+                                0xfb0af54eL, 0xd8feb397L, 0x454056acL,
+                                0xba489527L,
+                                0x55533a3aL, 0x20838d87L, 0xfe6ba9b7L,
+                                0xd096954bL,
+                                0x55a867bcL, 0xa1159a58L, 0xcca92963L,
+                                0x99e1db33L,
+                                0xa62a4a56L, 0x3f3125f9L, 0x5ef47e1cL,
+                                0x9029317cL,
+                                0xfdf8e802L, 0x04272f70L, 0x80bb155cL,
+                                0x05282ce3L,
+                                0x95c11548L, 0xe4c66d22L, 0x48c1133fL,
+                                0xc70f86dcL,
+                                0x07f9c9eeL, 0x41041f0fL, 0x404779a4L,
+                                0x5d886e17L,
+                                0x325f51ebL, 0xd59bc0d1L, 0xf2bcc18fL,
+                                0x41113564L,
+                                0x257b7834L, 0x602a9c60L, 0xdff8e8a3L,
+                                0x1f636c1bL,
+                                0x0e12b4c2L, 0x02e1329eL, 0xaf664fd1L,
+                                0xcad18115L,
+                                0x6b2395e0L, 0x333e92e1L, 0x3b240b62L,
+                                0xeebeb922L,
+                                0x85b2a20eL, 0xe6ba0d99L, 0xde720c8cL,
+                                0x2da2f728L,
+                                0xd0127845L, 0x95b794fdL, 0x647d0862L,
+                                0xe7ccf5f0L,
+                                0x5449a36fL, 0x877d48faL, 0xc39dfd27L,
+                                0xf33e8d1eL,
+                                0x0a476341L, 0x992eff74L, 0x3a6f6eabL,
+                                0xf4f8fd37L,
+                                0xa812dc60L, 0xa1ebddf8L, 0x991be14cL,
+                                0xdb6e6b0dL,
+                                0xc67b5510L, 0x6d672c37L, 0x2765d43bL,
+                                0xdcd0e804L,
+                                0xf1290dc7L, 0xcc00ffa3L, 0xb5390f92L,
+                                0x690fed0bL,
+                                0x667b9ffbL, 0xcedb7d9cL, 0xa091cf0bL,
+                                0xd9155ea3L,
+                                0xbb132f88L, 0x515bad24L, 0x7b9479bfL,
+                                0x763bd6ebL,
+                                0x37392eb3L, 0xcc115979L, 0x8026e297L,
+                                0xf42e312dL,
+                                0x6842ada7L, 0xc66a2b3bL, 0x12754cccL,
+                                0x782ef11cL,
+                                0x6a124237L, 0xb79251e7L, 0x06a1bbe6L,
+                                0x4bfb6350L,
+                                0x1a6b1018L, 0x11caedfaL, 0x3d25bdd8L,
+                                0xe2e1c3c9L,
+                                0x44421659L, 0x0a121386L, 0xd90cec6eL,
+                                0xd5abea2aL,
+                                0x64af674eL, 0xda86a85fL, 0xbebfe988L,
+                                0x64e4c3feL,
+                                0x9dbc8057L, 0xf0f7c086L, 0x60787bf8L,
+                                0x6003604dL,
+                                0xd1fd8346L, 0xf6381fb0L, 0x7745ae04L,
+                                0xd736fcccL,
+                                0x83426b33L, 0xf01eab71L, 0xb0804187L,
+                                0x3c005e5fL,
+                                0x77a057beL, 0xbde8ae24L, 0x55464299L,
+                                0xbf582e61L,
+                                0x4e58f48fL, 0xf2ddfda2L, 0xf474ef38L,
+                                0x8789bdc2L,
+                                0x5366f9c3L, 0xc8b38e74L, 0xb475f255L,
+                                0x46fcd9b9L,
+                                0x7aeb2661L, 0x8b1ddf84L, 0x846a0e79L,
+                                0x915f95e2L,
+                                0x466e598eL, 0x20b45770L, 0x8cd55591L,
+                                0xc902de4cL,
+                                0xb90bace1L, 0xbb8205d0L, 0x11a86248L,
+                                0x7574a99eL,
+                                0xb77f19b6L, 0xe0a9dc09L, 0x662d09a1L,
+                                0xc4324633L,
+                                0xe85a1f02L, 0x09f0be8cL, 0x4a99a025L,
+                                0x1d6efe10L,
+                                0x1ab93d1dL, 0x0ba5a4dfL, 0xa186f20fL,
+                                0x2868f169L,
+                                0xdcb7da83L, 0x573906feL, 0xa1e2ce9bL,
+                                0x4fcd7f52L,
+                                0x50115e01L, 0xa70683faL, 0xa002b5c4L,
+                                0x0de6d027L,
+                                0x9af88c27L, 0x773f8641L, 0xc3604c06L,
+                                0x61a806b5L,
+                                0xf0177a28L, 0xc0f586e0L, 0x006058aaL,
+                                0x30dc7d62L,
+                                0x11e69ed7L, 0x2338ea63L, 0x53c2dd94L,
+                                0xc2c21634L,
+                                0xbbcbee56L, 0x90bcb6deL, 0xebfc7da1L,
+                                0xce591d76L,
+                                0x6f05e409L, 0x4b7c0188L, 0x39720a3dL,
+                                0x7c927c24L,
+                                0x86e3725fL, 0x724d9db9L, 0x1ac15bb4L,
+                                0xd39eb8fcL,
+                                0xed545578L, 0x08fca5b5L, 0xd83d7cd3L,
+                                0x4dad0fc4L,
+                                0x1e50ef5eL, 0xb161e6f8L, 0xa28514d9L,
+                                0x6c51133cL,
+                                0x6fd5c7e7L, 0x56e14ec4L, 0x362abfceL,
+                                0xddc6c837L,
+                                0xd79a3234L, 0x92638212L, 0x670efa8eL,
+                                0x406000e0L,
+                                0x3a39ce37L, 0xd3faf5cfL, 0xabc27737L,
+                                0x5ac52d1bL,
+                                0x5cb0679eL, 0x4fa33742L, 0xd3822740L,
+                                0x99bc9bbeL,
+                                0xd5118e9dL, 0xbf0f7315L, 0xd62d1c7eL,
+                                0xc700c47bL,
+                                0xb78c1b6bL, 0x21a19045L, 0xb26eb1beL,
+                                0x6a366eb4L,
+                                0x5748ab2fL, 0xbc946e79L, 0xc6a376d2L,
+                                0x6549c2c8L,
+                                0x530ff8eeL, 0x468dde7dL, 0xd5730a1dL,
+                                0x4cd04dc6L,
+                                0x2939bbdbL, 0xa9ba4650L, 0xac9526e8L,
+                                0xbe5ee304L,
+                                0xa1fad5f0L, 0x6a2d519aL, 0x63ef8ce2L,
+                                0x9a86ee22L,
+                                0xc089c2b8L, 0x43242ef6L, 0xa51e03aaL,
+                                0x9cf2d0a4L,
+                                0x83c061baL, 0x9be96a4dL, 0x8fe51550L,
+                                0xba645bd6L,
+                                0x2826a2f9L, 0xa73a3ae1L, 0x4ba99586L,
+                                0xef5562e9L,
+                                0xc72fefd3L, 0xf752f7daL, 0x3f046f69L,
+                                0x77fa0a59L,
+                                0x80e4a915L, 0x87b08601L, 0x9b09e6adL,
+                                0x3b3ee593L,
+                                0xe990fd5aL, 0x9e34d797L, 0x2cf0b7d9L,
+                                0x022b8b51L,
+                                0x96d5ac3aL, 0x017da67dL, 0xd1cf3ed6L,
+                                0x7c7d2d28L,
+                                0x1f9f25cfL, 0xadf2b89bL, 0x5ad6b472L,
+                                0x5a88f54cL,
+                                0xe029ac71L, 0xe019a5e6L, 0x47b0acfdL,
+                                0xed93fa9bL,
+                                0xe8d3c48dL, 0x283b57ccL, 0xf8d56629L,
+                                0x79132e28L,
+                                0x785f0191L, 0xed756055L, 0xf7960e44L,
+                                0xe3d35e8cL,
+                                0x15056dd4L, 0x88f46dbaL, 0x03a16125L,
+                                0x0564f0bdL,
+                                0xc3eb9e15L, 0x3c9057a2L, 0x97271aecL,
+                                0xa93a072aL,
+                                0x1b3f6d9bL, 0x1e6321f5L, 0xf59c66fbL,
+                                0x26dcf319L,
+                                0x7533d928L, 0xb155fdf5L, 0x03563482L,
+                                0x8aba3cbbL,
+                                0x28517711L, 0xc20ad9f8L, 0xabcc5167L,
+                                0xccad925fL,
+                                0x4de81751L, 0x3830dc8eL, 0x379d5862L,
+                                0x9320f991L,
+                                0xea7a90c2L, 0xfb3e7bceL, 0x5121ce64L,
+                                0x774fbe32L,
+                                0xa8b6e37eL, 0xc3293d46L, 0x48de5369L,
+                                0x6413e680L,
+                                0xa2ae0810L, 0xdd6db224L, 0x69852dfdL,
+                                0x09072166L,
+                                0xb39a460aL, 0x6445c0ddL, 0x586cdecfL,
+                                0x1c20c8aeL,
+                                0x5bbef7ddL, 0x1b588d40L, 0xccd2017fL,
+                                0x6bb4e3bbL,
+                                0xdda26a7eL, 0x3a59ff45L, 0x3e350a44L,
+                                0xbcb4cdd5L,
+                                0x72eacea8L, 0xfa6484bbL, 0x8d6612aeL,
+                                0xbf3c6f47L,
+                                0xd29be463L, 0x542f5d9eL, 0xaec2771bL,
+                                0xf64e6370L,
+                                0x740e0d8dL, 0xe75b1357L, 0xf8721671L,
+                                0xaf537d5dL,
+                                0x4040cb08L, 0x4eb4e2ccL, 0x34d2466aL,
+                                0x0115af84L,
+                                0xe1b00428L, 0x95983a1dL, 0x06b89fb4L,
+                                0xce6ea048L,
+                                0x6f3f3b82L, 0x3520ab82L, 0x011a1d4bL,
+                                0x277227f8L,
+                                0x611560b1L, 0xe7933fdcL, 0xbb3a792bL,
+                                0x344525bdL,
+                                0xa08839e1L, 0x51ce794bL, 0x2f32c9b7L,
+                                0xa01fbac9L,
+                                0xe01cc87eL, 0xbcc7d1f6L, 0xcf0111c3L,
+                                0xa1e8aac7L,
+                                0x1a908749L, 0xd44fbd9aL, 0xd0dadecbL,
+                                0xd50ada38L,
+                                0x0339c32aL, 0xc6913667L, 0x8df9317cL,
+                                0xe0b12b4fL,
+                                0xf79e59b7L, 0x43f5bb3aL, 0xf2d519ffL,
+                                0x27d9459cL,
+                                0xbf97222cL, 0x15e6fc2aL, 0x0f91fc71L,
+                                0x9b941525L,
+                                0xfae59361L, 0xceb69cebL, 0xc2a86459L,
+                                0x12baa8d1L,
+                                0xb6c1075eL, 0xe3056a0cL, 0x10d25065L,
+                                0xcb03a442L,
+                                0xe0ec6e0eL, 0x1698db3bL, 0x4c98a0beL,
+                                0x3278e964L,
+                                0x9f1f9532L, 0xe0d392dfL, 0xd3a0342bL,
+                                0x8971f21eL,
+                                0x1b0a7441L, 0x4ba3348cL, 0xc5be7120L,
+                                0xc37632d8L,
+                                0xdf359f8dL, 0x9b992f2eL, 0xe60b6f47L,
+                                0x0fe3f11dL,
+                                0xe54cda54L, 0x1edad891L, 0xce6279cfL,
+                                0xcd3e7e6fL,
+                                0x1618b166L, 0xfd2c1d05L, 0x848fd2c5L,
+                                0xf6fb2299L,
+                                0xf523f357L, 0xa6327623L, 0x93a83531L,
+                                0x56cccd02L,
+                                0xacf08162L, 0x5a75ebb5L, 0x6e163697L,
+                                0x88d273ccL,
+                                0xde966292L, 0x81b949d0L, 0x4c50901bL,
+                                0x71c65614L,
+                                0xe6c6c7bdL, 0x327a140aL, 0x45e1d006L,
+                                0xc3f27b9aL,
+                                0xc9aa53fdL, 0x62a80f00L, 0xbb25bfe2L,
+                                0x35bdd2f6L,
+                                0x71126905L, 0xb2040222L, 0xb6cbcf7cL,
+                                0xcd769c2bL,
+                                0x53113ec0L, 0x1640e3d3L, 0x38abbd60L,
+                                0x2547adf0L,
+                                0xba38209cL, 0xf746ce76L, 0x77afa1c5L,
+                                0x20756060L,
+                                0x85cbfe4eL, 0x8ae88dd8L, 0x7aaaf9b0L,
+                                0x4cf9aa7eL,
+                                0x1948c25cL, 0x02fb8a8cL, 0x01c36ae4L,
+                                0xd6ebe1f9L,
+                                0x90d4f869L, 0xa65cdea0L, 0x3f09252dL,
+                                0xc208e69fL,
+                                0xb74e6132L, 0xce77e25bL, 0x578fdfe3L,
+                                0x3ac372e6L,
+                                }
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_skey.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_skey.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bf/bf_skey.c	(revision 331)
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <string.h>
+#include <openssl/blowfish.h>
+#include "bf_locl.h"
+#include "bf_pi.h"
+
+void BF_set_key(BF_KEY *key, int len, const unsigned char *data)
+{
+    int i;
+    BF_LONG *p, ri, in[2];
+    const unsigned char *d, *end;
+
+    memcpy(key, &bf_init, sizeof(BF_KEY));
+    p = key->P;
+
+    if (len > ((BF_ROUNDS + 2) * 4))
+        len = (BF_ROUNDS + 2) * 4;
+
+    d = data;
+    end = &(data[len]);
+    for (i = 0; i < (BF_ROUNDS + 2); i++) {
+        ri = *(d++);
+        if (d >= end)
+            d = data;
+
+        ri <<= 8;
+        ri |= *(d++);
+        if (d >= end)
+            d = data;
+
+        ri <<= 8;
+        ri |= *(d++);
+        if (d >= end)
+            d = data;
+
+        ri <<= 8;
+        ri |= *(d++);
+        if (d >= end)
+            d = data;
+
+        p[i] ^= ri;
+    }
+
+    in[0] = 0L;
+    in[1] = 0L;
+    for (i = 0; i < (BF_ROUNDS + 2); i += 2) {
+        BF_encrypt(in, key);
+        p[i] = in[0];
+        p[i + 1] = in[1];
+    }
+
+    p = key->S;
+    for (i = 0; i < 4 * 256; i += 2) {
+        BF_encrypt(in, key);
+        p[i] = in[0];
+        p[i + 1] = in[1];
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/b_addr.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/b_addr.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/b_addr.c	(revision 331)
@@ -0,0 +1,897 @@
+/*
+ * 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 <string.h>
+
+#include "bio_lcl.h"
+#include <openssl/crypto.h>
+
+#ifndef OPENSSL_NO_SOCK
+#include <openssl/err.h>
+#include <openssl/buffer.h>
+#include <internal/thread_once.h>
+#include <ctype.h>
+
+#ifdef _HPUX_SOURCE
+static const char *ossl_hstrerror(int herr)
+{
+    switch (herr) {
+    case -1:
+        return strerror(errno);
+    case 0:
+        return "No error";
+    case HOST_NOT_FOUND:
+        return "Host not found";
+    case NO_DATA:                /* NO_ADDRESS is a synonym */
+        return "No data";
+    case NO_RECOVERY:
+        return "Non recoverable error";
+    case TRY_AGAIN:
+        return "Try again";
+    default:
+        break;
+    }
+    return "unknown error";
+}
+# define hstrerror(e) ossl_hstrerror(e)
+#endif
+
+CRYPTO_RWLOCK *bio_lookup_lock;
+static CRYPTO_ONCE bio_lookup_init = CRYPTO_ONCE_STATIC_INIT;
+
+/*
+ * Throughout this file and bio_lcl.h, the existence of the macro
+ * AI_PASSIVE is used to detect the availability of struct addrinfo,
+ * getnameinfo() and getaddrinfo().  If that macro doesn't exist,
+ * we use our own implementation instead, using gethostbyname,
+ * getservbyname and a few other.
+ */
+
+/**********************************************************************
+ *
+ * Address structure
+ *
+ */
+
+BIO_ADDR *BIO_ADDR_new(void)
+{
+    BIO_ADDR *ret = OPENSSL_zalloc(sizeof(*ret));
+
+    if (ret == NULL) {
+        BIOerr(BIO_F_BIO_ADDR_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    ret->sa.sa_family = AF_UNSPEC;
+    return ret;
+}
+
+void BIO_ADDR_free(BIO_ADDR *ap)
+{
+    OPENSSL_free(ap);
+}
+
+void BIO_ADDR_clear(BIO_ADDR *ap)
+{
+    memset(ap, 0, sizeof(*ap));
+    ap->sa.sa_family = AF_UNSPEC;
+}
+
+/*
+ * BIO_ADDR_make - non-public routine to fill a BIO_ADDR with the contents
+ * of a struct sockaddr.
+ */
+int BIO_ADDR_make(BIO_ADDR *ap, const struct sockaddr *sa)
+{
+    if (sa->sa_family == AF_INET) {
+        ap->s_in = *(const struct sockaddr_in *)sa;
+        return 1;
+    }
+#ifdef AF_INET6
+    if (sa->sa_family == AF_INET6) {
+        ap->s_in6 = *(const struct sockaddr_in6 *)sa;
+        return 1;
+    }
+#endif
+#ifdef AF_UNIX
+    if (ap->sa.sa_family == AF_UNIX) {
+        ap->s_un = *(const struct sockaddr_un *)sa;
+        return 1;
+    }
+#endif
+
+    return 0;
+}
+
+int BIO_ADDR_rawmake(BIO_ADDR *ap, int family,
+                     const void *where, size_t wherelen,
+                     unsigned short port)
+{
+#ifdef AF_UNIX
+    if (family == AF_UNIX) {
+        if (wherelen + 1 > sizeof(ap->s_un.sun_path))
+            return 0;
+        memset(&ap->s_un, 0, sizeof(ap->s_un));
+        ap->s_un.sun_family = family;
+        strncpy(ap->s_un.sun_path, where, sizeof(ap->s_un.sun_path) - 1);
+        return 1;
+    }
+#endif
+    if (family == AF_INET) {
+        if (wherelen != sizeof(struct in_addr))
+            return 0;
+        memset(&ap->s_in, 0, sizeof(ap->s_in));
+        ap->s_in.sin_family = family;
+        ap->s_in.sin_port = port;
+        ap->s_in.sin_addr = *(struct in_addr *)where;
+        return 1;
+    }
+#ifdef AF_INET6
+    if (family == AF_INET6) {
+        if (wherelen != sizeof(struct in6_addr))
+            return 0;
+        memset(&ap->s_in6, 0, sizeof(ap->s_in6));
+        ap->s_in6.sin6_family = family;
+        ap->s_in6.sin6_port = port;
+        ap->s_in6.sin6_addr = *(struct in6_addr *)where;
+        return 1;
+    }
+#endif
+
+    return 0;
+}
+
+int BIO_ADDR_family(const BIO_ADDR *ap)
+{
+    return ap->sa.sa_family;
+}
+
+int BIO_ADDR_rawaddress(const BIO_ADDR *ap, void *p, size_t *l)
+{
+    size_t len = 0;
+    const void *addrptr = NULL;
+
+    if (ap->sa.sa_family == AF_INET) {
+        len = sizeof(ap->s_in.sin_addr);
+        addrptr = &ap->s_in.sin_addr;
+    }
+#ifdef AF_INET6
+    else if (ap->sa.sa_family == AF_INET6) {
+        len = sizeof(ap->s_in6.sin6_addr);
+        addrptr = &ap->s_in6.sin6_addr;
+    }
+#endif
+#ifdef AF_UNIX
+    else if (ap->sa.sa_family == AF_UNIX) {
+        len = strlen(ap->s_un.sun_path);
+        addrptr = &ap->s_un.sun_path;
+    }
+#endif
+
+    if (addrptr == NULL)
+        return 0;
+
+    if (p != NULL) {
+        memcpy(p, addrptr, len);
+    }
+    if (l != NULL)
+        *l = len;
+
+    return 1;
+}
+
+unsigned short BIO_ADDR_rawport(const BIO_ADDR *ap)
+{
+    if (ap->sa.sa_family == AF_INET)
+        return ap->s_in.sin_port;
+#ifdef AF_INET6
+    if (ap->sa.sa_family == AF_INET6)
+        return ap->s_in6.sin6_port;
+#endif
+    return 0;
+}
+
+/*-
+ * addr_strings - helper function to get host and service names
+ * @ap: the BIO_ADDR that has the input info
+ * @numeric: 0 if actual names should be returned, 1 if the numeric
+ * representation should be returned.
+ * @hostname: a pointer to a pointer to a memory area to store the
+ * host name or numeric representation.  Unused if NULL.
+ * @service: a pointer to a pointer to a memory area to store the
+ * service name or numeric representation.  Unused if NULL.
+ *
+ * The return value is 0 on failure, with the error code in the error
+ * stack, and 1 on success.
+ */
+static int addr_strings(const BIO_ADDR *ap, int numeric,
+                        char **hostname, char **service)
+{
+    if (BIO_sock_init() != 1)
+        return 0;
+
+    if (1) {
+#ifdef AI_PASSIVE
+        int ret = 0;
+        char host[NI_MAXHOST] = "", serv[NI_MAXSERV] = "";
+        int flags = 0;
+
+        if (numeric)
+            flags |= NI_NUMERICHOST | NI_NUMERICSERV;
+
+        if ((ret = getnameinfo(BIO_ADDR_sockaddr(ap),
+                               BIO_ADDR_sockaddr_size(ap),
+                               host, sizeof(host), serv, sizeof(serv),
+                               flags)) != 0) {
+# ifdef EAI_SYSTEM
+            if (ret == EAI_SYSTEM) {
+                SYSerr(SYS_F_GETNAMEINFO, get_last_socket_error());
+                BIOerr(BIO_F_ADDR_STRINGS, ERR_R_SYS_LIB);
+            } else
+# endif
+            {
+                BIOerr(BIO_F_ADDR_STRINGS, ERR_R_SYS_LIB);
+                ERR_add_error_data(1, gai_strerror(ret));
+            }
+            return 0;
+        }
+
+        /* VMS getnameinfo() has a bug, it doesn't fill in serv, which
+         * leaves it with whatever garbage that happens to be there.
+         * However, we initialise serv with the empty string (serv[0]
+         * is therefore NUL), so it gets real easy to detect when things
+         * didn't go the way one might expect.
+         */
+        if (serv[0] == '\0') {
+            BIO_snprintf(serv, sizeof(serv), "%d",
+                         ntohs(BIO_ADDR_rawport(ap)));
+        }
+
+        if (hostname != NULL)
+            *hostname = OPENSSL_strdup(host);
+        if (service != NULL)
+            *service = OPENSSL_strdup(serv);
+    } else {
+#endif
+        if (hostname != NULL)
+            *hostname = OPENSSL_strdup(inet_ntoa(ap->s_in.sin_addr));
+        if (service != NULL) {
+            char serv[6];        /* port is 16 bits => max 5 decimal digits */
+            BIO_snprintf(serv, sizeof(serv), "%d", ntohs(ap->s_in.sin_port));
+            *service = OPENSSL_strdup(serv);
+        }
+    }
+
+    if ((hostname != NULL && *hostname == NULL)
+            || (service != NULL && *service == NULL)) {
+        if (hostname != NULL) {
+            OPENSSL_free(*hostname);
+            *hostname = NULL;
+        }
+        if (service != NULL) {
+            OPENSSL_free(*service);
+            *service = NULL;
+        }
+        BIOerr(BIO_F_ADDR_STRINGS, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    return 1;
+}
+
+char *BIO_ADDR_hostname_string(const BIO_ADDR *ap, int numeric)
+{
+    char *hostname = NULL;
+
+    if (addr_strings(ap, numeric, &hostname, NULL))
+        return hostname;
+
+    return NULL;
+}
+
+char *BIO_ADDR_service_string(const BIO_ADDR *ap, int numeric)
+{
+    char *service = NULL;
+
+    if (addr_strings(ap, numeric, NULL, &service))
+        return service;
+
+    return NULL;
+}
+
+char *BIO_ADDR_path_string(const BIO_ADDR *ap)
+{
+#ifdef AF_UNIX
+    if (ap->sa.sa_family == AF_UNIX)
+        return OPENSSL_strdup(ap->s_un.sun_path);
+#endif
+    return NULL;
+}
+
+/*
+ * BIO_ADDR_sockaddr - non-public routine to return the struct sockaddr
+ * for a given BIO_ADDR.  In reality, this is simply a type safe cast.
+ * The returned struct sockaddr is const, so it can't be tampered with.
+ */
+const struct sockaddr *BIO_ADDR_sockaddr(const BIO_ADDR *ap)
+{
+    return &(ap->sa);
+}
+
+/*
+ * BIO_ADDR_sockaddr_noconst - non-public function that does the same
+ * as BIO_ADDR_sockaddr, but returns a non-const.  USE WITH CARE, as
+ * it allows you to tamper with the data (and thereby the contents
+ * of the input BIO_ADDR).
+ */
+struct sockaddr *BIO_ADDR_sockaddr_noconst(BIO_ADDR *ap)
+{
+    return &(ap->sa);
+}
+
+/*
+ * BIO_ADDR_sockaddr_size - non-public function that returns the size
+ * of the struct sockaddr the BIO_ADDR is using.  If the protocol family
+ * isn't set or is something other than AF_INET, AF_INET6 or AF_UNIX,
+ * the size of the BIO_ADDR type is returned.
+ */
+socklen_t BIO_ADDR_sockaddr_size(const BIO_ADDR *ap)
+{
+    if (ap->sa.sa_family == AF_INET)
+        return sizeof(ap->s_in);
+#ifdef AF_INET6
+    if (ap->sa.sa_family == AF_INET6)
+        return sizeof(ap->s_in6);
+#endif
+#ifdef AF_UNIX
+    if (ap->sa.sa_family == AF_UNIX)
+        return sizeof(ap->s_un);
+#endif
+    return sizeof(*ap);
+}
+
+/**********************************************************************
+ *
+ * Address info database
+ *
+ */
+
+const BIO_ADDRINFO *BIO_ADDRINFO_next(const BIO_ADDRINFO *bai)
+{
+    if (bai != NULL)
+        return bai->bai_next;
+    return NULL;
+}
+
+int BIO_ADDRINFO_family(const BIO_ADDRINFO *bai)
+{
+    if (bai != NULL)
+        return bai->bai_family;
+    return 0;
+}
+
+int BIO_ADDRINFO_socktype(const BIO_ADDRINFO *bai)
+{
+    if (bai != NULL)
+        return bai->bai_socktype;
+    return 0;
+}
+
+int BIO_ADDRINFO_protocol(const BIO_ADDRINFO *bai)
+{
+    if (bai != NULL) {
+        if (bai->bai_protocol != 0)
+            return bai->bai_protocol;
+
+#ifdef AF_UNIX
+        if (bai->bai_family == AF_UNIX)
+            return 0;
+#endif
+
+        switch (bai->bai_socktype) {
+        case SOCK_STREAM:
+            return IPPROTO_TCP;
+        case SOCK_DGRAM:
+            return IPPROTO_UDP;
+        default:
+            break;
+        }
+    }
+    return 0;
+}
+
+/*
+ * BIO_ADDRINFO_sockaddr_size - non-public function that returns the size
+ * of the struct sockaddr inside the BIO_ADDRINFO.
+ */
+socklen_t BIO_ADDRINFO_sockaddr_size(const BIO_ADDRINFO *bai)
+{
+    if (bai != NULL)
+        return bai->bai_addrlen;
+    return 0;
+}
+
+/*
+ * BIO_ADDRINFO_sockaddr - non-public function that returns bai_addr
+ * as the struct sockaddr it is.
+ */
+const struct sockaddr *BIO_ADDRINFO_sockaddr(const BIO_ADDRINFO *bai)
+{
+    if (bai != NULL)
+        return bai->bai_addr;
+    return NULL;
+}
+
+const BIO_ADDR *BIO_ADDRINFO_address(const BIO_ADDRINFO *bai)
+{
+    if (bai != NULL)
+        return (BIO_ADDR *)bai->bai_addr;
+    return NULL;
+}
+
+void BIO_ADDRINFO_free(BIO_ADDRINFO *bai)
+{
+    if (bai == NULL)
+        return;
+
+#ifdef AI_PASSIVE
+# ifdef AF_UNIX
+#  define _cond bai->bai_family != AF_UNIX
+# else
+#  define _cond 1
+# endif
+    if (_cond) {
+        freeaddrinfo(bai);
+        return;
+    }
+#endif
+
+    /* Free manually when we know that addrinfo_wrap() was used.
+     * See further comment above addrinfo_wrap()
+     */
+    while (bai != NULL) {
+        BIO_ADDRINFO *next = bai->bai_next;
+        OPENSSL_free(bai->bai_addr);
+        OPENSSL_free(bai);
+        bai = next;
+    }
+}
+
+/**********************************************************************
+ *
+ * Service functions
+ *
+ */
+
+/*-
+ * The specs in hostserv can take these forms:
+ *
+ * host:service         => *host = "host", *service = "service"
+ * host:*               => *host = "host", *service = NULL
+ * host:                => *host = "host", *service = NULL
+ * :service             => *host = NULL, *service = "service"
+ * *:service            => *host = NULL, *service = "service"
+ *
+ * in case no : is present in the string, the result depends on
+ * hostserv_prio, as follows:
+ *
+ * when hostserv_prio == BIO_PARSE_PRIO_HOST
+ * host                 => *host = "host", *service untouched
+ *
+ * when hostserv_prio == BIO_PARSE_PRIO_SERV
+ * service              => *host untouched, *service = "service"
+ *
+ */
+int BIO_parse_hostserv(const char *hostserv, char **host, char **service,
+                       enum BIO_hostserv_priorities hostserv_prio)
+{
+    const char *h = NULL; size_t hl = 0;
+    const char *p = NULL; size_t pl = 0;
+
+    if (*hostserv == '[') {
+        if ((p = strchr(hostserv, ']')) == NULL)
+            goto spec_err;
+        h = hostserv + 1;
+        hl = p - h;
+        p++;
+        if (*p == '\0')
+            p = NULL;
+        else if (*p != ':')
+            goto spec_err;
+        else {
+            p++;
+            pl = strlen(p);
+        }
+    } else {
+        const char *p2 = strrchr(hostserv, ':');
+        p = strchr(hostserv, ':');
+
+        /*-
+         * Check for more than one colon.  There are three possible
+         * interpretations:
+         * 1. IPv6 address with port number, last colon being separator.
+         * 2. IPv6 address only.
+         * 3. IPv6 address only if hostserv_prio == BIO_PARSE_PRIO_HOST,
+         *    IPv6 address and port number if hostserv_prio == BIO_PARSE_PRIO_SERV
+         * Because of this ambiguity, we currently choose to make it an
+         * error.
+         */
+        if (p != p2)
+            goto amb_err;
+
+        if (p != NULL) {
+            h = hostserv;
+            hl = p - h;
+            p++;
+            pl = strlen(p);
+        } else if (hostserv_prio == BIO_PARSE_PRIO_HOST) {
+            h = hostserv;
+            hl = strlen(h);
+        } else {
+            p = hostserv;
+            pl = strlen(p);
+        }
+    }
+
+    if (p != NULL && strchr(p, ':'))
+        goto spec_err;
+
+    if (h != NULL && host != NULL) {
+        if (hl == 0
+            || (hl == 1 && h[0] == '*')) {
+            *host = NULL;
+        } else {
+            *host = OPENSSL_strndup(h, hl);
+            if (*host == NULL)
+                goto memerr;
+        }
+    }
+    if (p != NULL && service != NULL) {
+        if (pl == 0
+            || (pl == 1 && p[0] == '*')) {
+            *service = NULL;
+        } else {
+            *service = OPENSSL_strndup(p, pl);
+            if (*service == NULL)
+                goto memerr;
+        }
+    }
+
+    return 1;
+ amb_err:
+    BIOerr(BIO_F_BIO_PARSE_HOSTSERV, BIO_R_AMBIGUOUS_HOST_OR_SERVICE);
+    return 0;
+ spec_err:
+    BIOerr(BIO_F_BIO_PARSE_HOSTSERV, BIO_R_MALFORMED_HOST_OR_SERVICE);
+    return 0;
+ memerr:
+    BIOerr(BIO_F_BIO_PARSE_HOSTSERV, ERR_R_MALLOC_FAILURE);
+    return 0;
+}
+
+/* addrinfo_wrap is used to build our own addrinfo "chain".
+ * (it has only one entry, so calling it a chain may be a stretch)
+ * It should ONLY be called when getaddrinfo() and friends
+ * aren't available, OR when dealing with a non IP protocol
+ * family, such as AF_UNIX
+ *
+ * the return value is 1 on success, or 0 on failure, which
+ * only happens if a memory allocation error occurred.
+ */
+static int addrinfo_wrap(int family, int socktype,
+                         const void *where, size_t wherelen,
+                         unsigned short port,
+                         BIO_ADDRINFO **bai)
+{
+    OPENSSL_assert(bai != NULL);
+
+    *bai = OPENSSL_zalloc(sizeof(**bai));
+    if (*bai == NULL)
+        return 0;
+
+    (*bai)->bai_family = family;
+    (*bai)->bai_socktype = socktype;
+    if (socktype == SOCK_STREAM)
+        (*bai)->bai_protocol = IPPROTO_TCP;
+    if (socktype == SOCK_DGRAM)
+        (*bai)->bai_protocol = IPPROTO_UDP;
+#ifdef AF_UNIX
+    if (family == AF_UNIX)
+        (*bai)->bai_protocol = 0;
+#endif
+    {
+        /* Magic: We know that BIO_ADDR_sockaddr_noconst is really
+           just an advanced cast of BIO_ADDR* to struct sockaddr *
+           by the power of union, so while it may seem that we're
+           creating a memory leak here, we are not.  It will be
+           all right. */
+        BIO_ADDR *addr = BIO_ADDR_new();
+        if (addr != NULL) {
+            BIO_ADDR_rawmake(addr, family, where, wherelen, port);
+            (*bai)->bai_addr = BIO_ADDR_sockaddr_noconst(addr);
+        }
+    }
+    (*bai)->bai_next = NULL;
+    if ((*bai)->bai_addr == NULL) {
+        BIO_ADDRINFO_free(*bai);
+        *bai = NULL;
+        return 0;
+    }
+    return 1;
+}
+
+DEFINE_RUN_ONCE_STATIC(do_bio_lookup_init)
+{
+    OPENSSL_init_crypto(0, NULL);
+    bio_lookup_lock = CRYPTO_THREAD_lock_new();
+    return bio_lookup_lock != NULL;
+}
+
+/*-
+ * BIO_lookup - look up the node and service you want to connect to.
+ * @node: the node you want to connect to.
+ * @service: the service you want to connect to.
+ * @lookup_type: declare intent with the result, client or server.
+ * @family: the address family you want to use.  Use AF_UNSPEC for any, or
+ *  AF_INET, AF_INET6 or AF_UNIX.
+ * @socktype: The socket type you want to use.  Can be SOCK_STREAM, SOCK_DGRAM
+ *  or 0 for all.
+ * @res: Storage place for the resulting list of returned addresses
+ *
+ * This will do a lookup of the node and service that you want to connect to.
+ * It returns a linked list of different addresses you can try to connect to.
+ *
+ * When no longer needed you should call BIO_ADDRINFO_free() to free the result.
+ *
+ * The return value is 1 on success or 0 in case of error.
+ */
+int BIO_lookup(const char *host, const char *service,
+               enum BIO_lookup_type lookup_type,
+               int family, int socktype, BIO_ADDRINFO **res)
+{
+    int ret = 0;                 /* Assume failure */
+
+    switch(family) {
+    case AF_INET:
+#ifdef AF_INET6
+    case AF_INET6:
+#endif
+#ifdef AF_UNIX
+    case AF_UNIX:
+#endif
+#ifdef AF_UNSPEC
+    case AF_UNSPEC:
+#endif
+        break;
+    default:
+        BIOerr(BIO_F_BIO_LOOKUP, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY);
+        return 0;
+    }
+
+#ifdef AF_UNIX
+    if (family == AF_UNIX) {
+        if (addrinfo_wrap(family, socktype, host, strlen(host), 0, res))
+            return 1;
+        else
+            BIOerr(BIO_F_BIO_LOOKUP, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+#endif
+
+    if (BIO_sock_init() != 1)
+        return 0;
+
+    if (1) {
+        int gai_ret = 0;
+#ifdef AI_PASSIVE
+        struct addrinfo hints;
+        memset(&hints, 0, sizeof hints);
+
+        hints.ai_family = family;
+        hints.ai_socktype = socktype;
+
+        if (lookup_type == BIO_LOOKUP_SERVER)
+            hints.ai_flags |= AI_PASSIVE;
+
+        /* Note that |res| SHOULD be a 'struct addrinfo **' thanks to
+         * macro magic in bio_lcl.h
+         */
+        switch ((gai_ret = getaddrinfo(host, service, &hints, res))) {
+# ifdef EAI_SYSTEM
+        case EAI_SYSTEM:
+            SYSerr(SYS_F_GETADDRINFO, get_last_socket_error());
+            BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
+            break;
+# endif
+        case 0:
+            ret = 1;             /* Success */
+            break;
+        default:
+            BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
+            ERR_add_error_data(1, gai_strerror(gai_ret));
+            break;
+        }
+    } else {
+#endif
+        const struct hostent *he;
+/*
+ * Because struct hostent is defined for 32-bit pointers only with
+ * VMS C, we need to make sure that '&he_fallback_address' and
+ * '&he_fallback_addresses' are 32-bit pointers
+ */
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+# pragma pointer_size save
+# pragma pointer_size 32
+#endif
+        /* Windows doesn't seem to have in_addr_t */
+#ifdef OPENSSL_SYS_WINDOWS
+        static uint32_t he_fallback_address;
+        static const char *he_fallback_addresses[] =
+            { (char *)&he_fallback_address, NULL };
+#else
+        static in_addr_t he_fallback_address;
+        static const char *he_fallback_addresses[] =
+            { (char *)&he_fallback_address, NULL };
+#endif
+        static const struct hostent he_fallback =
+            { NULL, NULL, AF_INET, sizeof(he_fallback_address),
+              (char **)&he_fallback_addresses };
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+# pragma pointer_size restore
+#endif
+
+        struct servent *se;
+        /* Apparently, on WIN64, s_proto and s_port have traded places... */
+#ifdef _WIN64
+        struct servent se_fallback = { NULL, NULL, NULL, 0 };
+#else
+        struct servent se_fallback = { NULL, NULL, 0, NULL };
+#endif
+
+        if (!RUN_ONCE(&bio_lookup_init, do_bio_lookup_init)) {
+            BIOerr(BIO_F_BIO_LOOKUP, ERR_R_MALLOC_FAILURE);
+            ret = 0;
+            goto err;
+        }
+
+        CRYPTO_THREAD_write_lock(bio_lookup_lock);
+        he_fallback_address = INADDR_ANY;
+        if (host == NULL) {
+            he = &he_fallback;
+            switch(lookup_type) {
+            case BIO_LOOKUP_CLIENT:
+                he_fallback_address = INADDR_LOOPBACK;
+                break;
+            case BIO_LOOKUP_SERVER:
+                he_fallback_address = INADDR_ANY;
+                break;
+            default:
+                OPENSSL_assert(("We forgot to handle a lookup type!" == 0));
+                break;
+            }
+        } else {
+            he = gethostbyname(host);
+
+            if (he == NULL) {
+#ifndef OPENSSL_SYS_WINDOWS
+                BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
+                ERR_add_error_data(1, hstrerror(h_errno));
+#else
+                SYSerr(SYS_F_GETHOSTBYNAME, WSAGetLastError());
+#endif
+                ret = 0;
+                goto err;
+            }
+        }
+
+        if (service == NULL) {
+            se_fallback.s_port = 0;
+            se_fallback.s_proto = NULL;
+            se = &se_fallback;
+        } else {
+            char *endp = NULL;
+            long portnum = strtol(service, &endp, 10);
+
+/*
+ * Because struct servent is defined for 32-bit pointers only with
+ * VMS C, we need to make sure that 'proto' is a 32-bit pointer.
+ */
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+# pragma pointer_size save
+# pragma pointer_size 32
+#endif
+            char *proto = NULL;
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+# pragma pointer_size restore
+#endif
+
+            switch (socktype) {
+            case SOCK_STREAM:
+                proto = "tcp";
+                break;
+            case SOCK_DGRAM:
+                proto = "udp";
+                break;
+            }
+
+            if (endp != service && *endp == '\0'
+                    && portnum > 0 && portnum < 65536) {
+                se_fallback.s_port = htons(portnum);
+                se_fallback.s_proto = proto;
+                se = &se_fallback;
+            } else if (endp == service) {
+                se = getservbyname(service, proto);
+
+                if (se == NULL) {
+#ifndef OPENSSL_SYS_WINDOWS
+                    BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB);
+                    ERR_add_error_data(1, hstrerror(h_errno));
+#else
+                    SYSerr(SYS_F_GETSERVBYNAME, WSAGetLastError());
+#endif
+                    goto err;
+                }
+            } else {
+                BIOerr(BIO_F_BIO_LOOKUP, BIO_R_MALFORMED_HOST_OR_SERVICE);
+                goto err;
+            }
+        }
+
+        *res = NULL;
+
+        {
+/*
+ * Because hostent::h_addr_list is an array of 32-bit pointers with VMS C,
+ * we must make sure our iterator designates the same element type, hence
+ * the pointer size dance.
+ */
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+# pragma pointer_size save
+# pragma pointer_size 32
+#endif
+            char **addrlistp;
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+# pragma pointer_size restore
+#endif
+            size_t addresses;
+            BIO_ADDRINFO *tmp_bai = NULL;
+
+            /* The easiest way to create a linked list from an
+               array is to start from the back */
+            for(addrlistp = he->h_addr_list; *addrlistp != NULL;
+                addrlistp++)
+                ;
+
+            for(addresses = addrlistp - he->h_addr_list;
+                addrlistp--, addresses-- > 0; ) {
+                if (!addrinfo_wrap(he->h_addrtype, socktype,
+                                   *addrlistp, he->h_length,
+                                   se->s_port, &tmp_bai))
+                    goto addrinfo_malloc_err;
+                tmp_bai->bai_next = *res;
+                *res = tmp_bai;
+                continue;
+             addrinfo_malloc_err:
+                BIO_ADDRINFO_free(*res);
+                *res = NULL;
+                BIOerr(BIO_F_BIO_LOOKUP, ERR_R_MALLOC_FAILURE);
+                ret = 0;
+                goto err;
+            }
+
+            ret = 1;
+        }
+     err:
+        CRYPTO_THREAD_unlock(bio_lookup_lock);
+    }
+
+    return ret;
+}
+
+#endif /* OPENSSL_NO_SOCK */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/b_dump.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/b_dump.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/b_dump.c	(revision 331)
@@ -0,0 +1,158 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*
+ * Stolen from tjh's ssl/ssl_trc.c stuff.
+ */
+
+#include <stdio.h>
+#include "bio_lcl.h"
+
+#define TRUNCATE
+#define DUMP_WIDTH      16
+#define DUMP_WIDTH_LESS_INDENT(i) (DUMP_WIDTH-((i-(i>6?6:i)+3)/4))
+
+int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u),
+                void *u, const char *s, int len)
+{
+    return BIO_dump_indent_cb(cb, u, s, len, 0);
+}
+
+int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u),
+                       void *u, const char *s, int len, int indent)
+{
+    int ret = 0;
+    char buf[288 + 1], tmp[20], str[128 + 1];
+    int i, j, rows, trc;
+    unsigned char ch;
+    int dump_width;
+
+    trc = 0;
+
+#ifdef TRUNCATE
+    for (; (len > 0) && ((s[len - 1] == ' ') || (s[len - 1] == '\0')); len--)
+        trc++;
+#endif
+
+    if (indent < 0)
+        indent = 0;
+    if (indent) {
+        if (indent > 128)
+            indent = 128;
+        memset(str, ' ', indent);
+    }
+    str[indent] = '\0';
+
+    dump_width = DUMP_WIDTH_LESS_INDENT(indent);
+    rows = (len / dump_width);
+    if ((rows * dump_width) < len)
+        rows++;
+    for (i = 0; i < rows; i++) {
+        OPENSSL_strlcpy(buf, str, sizeof buf);
+        BIO_snprintf(tmp, sizeof tmp, "%04x - ", i * dump_width);
+        OPENSSL_strlcat(buf, tmp, sizeof buf);
+        for (j = 0; j < dump_width; j++) {
+            if (((i * dump_width) + j) >= len) {
+                OPENSSL_strlcat(buf, "   ", sizeof buf);
+            } else {
+                ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff;
+                BIO_snprintf(tmp, sizeof tmp, "%02x%c", ch,
+                             j == 7 ? '-' : ' ');
+                OPENSSL_strlcat(buf, tmp, sizeof buf);
+            }
+        }
+        OPENSSL_strlcat(buf, "  ", sizeof buf);
+        for (j = 0; j < dump_width; j++) {
+            if (((i * dump_width) + j) >= len)
+                break;
+            ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff;
+#ifndef CHARSET_EBCDIC
+            BIO_snprintf(tmp, sizeof tmp, "%c",
+                         ((ch >= ' ') && (ch <= '~')) ? ch : '.');
+#else
+            BIO_snprintf(tmp, sizeof tmp, "%c",
+                         ((ch >= os_toascii[' ']) && (ch <= os_toascii['~']))
+                         ? os_toebcdic[ch]
+                         : '.');
+#endif
+            OPENSSL_strlcat(buf, tmp, sizeof buf);
+        }
+        OPENSSL_strlcat(buf, "\n", sizeof buf);
+        /*
+         * if this is the last call then update the ddt_dump thing so that we
+         * will move the selection point in the debug window
+         */
+        ret += cb((void *)buf, strlen(buf), u);
+    }
+#ifdef TRUNCATE
+    if (trc > 0) {
+        BIO_snprintf(buf, sizeof buf, "%s%04x - <SPACES/NULS>\n", str,
+                     len + trc);
+        ret += cb((void *)buf, strlen(buf), u);
+    }
+#endif
+    return (ret);
+}
+
+#ifndef OPENSSL_NO_STDIO
+static int write_fp(const void *data, size_t len, void *fp)
+{
+    return UP_fwrite(data, len, 1, fp);
+}
+
+int BIO_dump_fp(FILE *fp, const char *s, int len)
+{
+    return BIO_dump_cb(write_fp, fp, s, len);
+}
+
+int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent)
+{
+    return BIO_dump_indent_cb(write_fp, fp, s, len, indent);
+}
+#endif
+
+static int write_bio(const void *data, size_t len, void *bp)
+{
+    return BIO_write((BIO *)bp, (const char *)data, len);
+}
+
+int BIO_dump(BIO *bp, const char *s, int len)
+{
+    return BIO_dump_cb(write_bio, bp, s, len);
+}
+
+int BIO_dump_indent(BIO *bp, const char *s, int len, int indent)
+{
+    return BIO_dump_indent_cb(write_bio, bp, s, len, indent);
+}
+
+int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data,
+                   int datalen)
+{
+    int i, j = 0;
+
+    if (datalen < 1)
+        return 1;
+
+    for (i = 0; i < datalen - 1; i++) {
+        if (i && !j)
+            BIO_printf(out, "%*s", indent, "");
+
+        BIO_printf(out, "%02X:", data[i]);
+
+        j = (j + 1) % width;
+        if (!j)
+            BIO_printf(out, "\n");
+    }
+
+    if (i && !j)
+        BIO_printf(out, "%*s", indent, "");
+    BIO_printf(out, "%02X", data[datalen - 1]);
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/b_print.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/b_print.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/b_print.c	(revision 331)
@@ -0,0 +1,944 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "internal/numbers.h"
+#include "internal/cryptlib.h"
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#include <openssl/bn.h>         /* To get BN_LLONG properly defined */
+#include <openssl/bio.h>
+
+#if defined(BN_LLONG) || defined(SIXTY_FOUR_BIT)
+# ifndef HAVE_LONG_LONG
+#  define HAVE_LONG_LONG 1
+# endif
+#endif
+
+/*
+ * Copyright Patrick Powell 1995
+ * This code is based on code written by Patrick Powell <papowell@astart.com>
+ * It may be used for any purpose as long as this notice remains intact
+ * on all source code distributions.
+ */
+
+#ifdef HAVE_LONG_DOUBLE
+# define LDOUBLE long double
+#else
+# define LDOUBLE double
+#endif
+
+#ifdef HAVE_LONG_LONG
+# if defined(_WIN32) && !defined(__GNUC__)
+#  define LLONG __int64
+# else
+#  define LLONG long long
+# endif
+#else
+# define LLONG long
+#endif
+
+static int fmtstr(char **, char **, size_t *, size_t *,
+                  const char *, int, int, int);
+static int fmtint(char **, char **, size_t *, size_t *,
+                  LLONG, int, int, int, int);
+static int fmtfp(char **, char **, size_t *, size_t *,
+                 LDOUBLE, int, int, int, int);
+static int doapr_outch(char **, char **, size_t *, size_t *, int);
+static int _dopr(char **sbuffer, char **buffer,
+                 size_t *maxlen, size_t *retlen, int *truncated,
+                 const char *format, va_list args);
+
+/* format read states */
+#define DP_S_DEFAULT    0
+#define DP_S_FLAGS      1
+#define DP_S_MIN        2
+#define DP_S_DOT        3
+#define DP_S_MAX        4
+#define DP_S_MOD        5
+#define DP_S_CONV       6
+#define DP_S_DONE       7
+
+/* format flags - Bits */
+/* left-aligned padding */
+#define DP_F_MINUS      (1 << 0)
+/* print an explicit '+' for a value with positive sign */
+#define DP_F_PLUS       (1 << 1)
+/* print an explicit ' ' for a value with positive sign */
+#define DP_F_SPACE      (1 << 2)
+/* print 0/0x prefix for octal/hex and decimal point for floating point */
+#define DP_F_NUM        (1 << 3)
+/* print leading zeroes */
+#define DP_F_ZERO       (1 << 4)
+/* print HEX in UPPPERcase */
+#define DP_F_UP         (1 << 5)
+/* treat value as unsigned */
+#define DP_F_UNSIGNED   (1 << 6)
+
+/* conversion flags */
+#define DP_C_SHORT      1
+#define DP_C_LONG       2
+#define DP_C_LDOUBLE    3
+#define DP_C_LLONG      4
+
+/* Floating point formats */
+#define F_FORMAT        0
+#define E_FORMAT        1
+#define G_FORMAT        2
+
+/* some handy macros */
+#define char_to_int(p) (p - '0')
+#define OSSL_MAX(p,q) ((p >= q) ? p : q)
+
+static int
+_dopr(char **sbuffer,
+      char **buffer,
+      size_t *maxlen,
+      size_t *retlen, int *truncated, const char *format, va_list args)
+{
+    char ch;
+    LLONG value;
+    LDOUBLE fvalue;
+    char *strvalue;
+    int min;
+    int max;
+    int state;
+    int flags;
+    int cflags;
+    size_t currlen;
+
+    state = DP_S_DEFAULT;
+    flags = currlen = cflags = min = 0;
+    max = -1;
+    ch = *format++;
+
+    while (state != DP_S_DONE) {
+        if (ch == '\0' || (buffer == NULL && currlen >= *maxlen))
+            state = DP_S_DONE;
+
+        switch (state) {
+        case DP_S_DEFAULT:
+            if (ch == '%')
+                state = DP_S_FLAGS;
+            else
+                if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
+                    return 0;
+            ch = *format++;
+            break;
+        case DP_S_FLAGS:
+            switch (ch) {
+            case '-':
+                flags |= DP_F_MINUS;
+                ch = *format++;
+                break;
+            case '+':
+                flags |= DP_F_PLUS;
+                ch = *format++;
+                break;
+            case ' ':
+                flags |= DP_F_SPACE;
+                ch = *format++;
+                break;
+            case '#':
+                flags |= DP_F_NUM;
+                ch = *format++;
+                break;
+            case '0':
+                flags |= DP_F_ZERO;
+                ch = *format++;
+                break;
+            default:
+                state = DP_S_MIN;
+                break;
+            }
+            break;
+        case DP_S_MIN:
+            if (isdigit((unsigned char)ch)) {
+                min = 10 * min + char_to_int(ch);
+                ch = *format++;
+            } else if (ch == '*') {
+                min = va_arg(args, int);
+                ch = *format++;
+                state = DP_S_DOT;
+            } else
+                state = DP_S_DOT;
+            break;
+        case DP_S_DOT:
+            if (ch == '.') {
+                state = DP_S_MAX;
+                ch = *format++;
+            } else
+                state = DP_S_MOD;
+            break;
+        case DP_S_MAX:
+            if (isdigit((unsigned char)ch)) {
+                if (max < 0)
+                    max = 0;
+                max = 10 * max + char_to_int(ch);
+                ch = *format++;
+            } else if (ch == '*') {
+                max = va_arg(args, int);
+                ch = *format++;
+                state = DP_S_MOD;
+            } else
+                state = DP_S_MOD;
+            break;
+        case DP_S_MOD:
+            switch (ch) {
+            case 'h':
+                cflags = DP_C_SHORT;
+                ch = *format++;
+                break;
+            case 'l':
+                if (*format == 'l') {
+                    cflags = DP_C_LLONG;
+                    format++;
+                } else
+                    cflags = DP_C_LONG;
+                ch = *format++;
+                break;
+            case 'q':
+                cflags = DP_C_LLONG;
+                ch = *format++;
+                break;
+            case 'L':
+                cflags = DP_C_LDOUBLE;
+                ch = *format++;
+                break;
+            default:
+                break;
+            }
+            state = DP_S_CONV;
+            break;
+        case DP_S_CONV:
+            switch (ch) {
+            case 'd':
+            case 'i':
+                switch (cflags) {
+                case DP_C_SHORT:
+                    value = (short int)va_arg(args, int);
+                    break;
+                case DP_C_LONG:
+                    value = va_arg(args, long int);
+                    break;
+                case DP_C_LLONG:
+                    value = va_arg(args, LLONG);
+                    break;
+                default:
+                    value = va_arg(args, int);
+                    break;
+                }
+                if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, 10, min,
+                            max, flags))
+                    return 0;
+                break;
+            case 'X':
+                flags |= DP_F_UP;
+                /* FALLTHROUGH */
+            case 'x':
+            case 'o':
+            case 'u':
+                flags |= DP_F_UNSIGNED;
+                switch (cflags) {
+                case DP_C_SHORT:
+                    value = (unsigned short int)va_arg(args, unsigned int);
+                    break;
+                case DP_C_LONG:
+                    value = (LLONG) va_arg(args, unsigned long int);
+                    break;
+                case DP_C_LLONG:
+                    value = va_arg(args, unsigned LLONG);
+                    break;
+                default:
+                    value = (LLONG) va_arg(args, unsigned int);
+                    break;
+                }
+                if (!fmtint(sbuffer, buffer, &currlen, maxlen, value,
+                            ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
+                            min, max, flags))
+                    return 0;
+                break;
+            case 'f':
+                if (cflags == DP_C_LDOUBLE)
+                    fvalue = va_arg(args, LDOUBLE);
+                else
+                    fvalue = va_arg(args, double);
+                if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
+                           flags, F_FORMAT))
+                    return 0;
+                break;
+            case 'E':
+                flags |= DP_F_UP;
+            case 'e':
+                if (cflags == DP_C_LDOUBLE)
+                    fvalue = va_arg(args, LDOUBLE);
+                else
+                    fvalue = va_arg(args, double);
+                if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
+                           flags, E_FORMAT))
+                    return 0;
+                break;
+            case 'G':
+                flags |= DP_F_UP;
+            case 'g':
+                if (cflags == DP_C_LDOUBLE)
+                    fvalue = va_arg(args, LDOUBLE);
+                else
+                    fvalue = va_arg(args, double);
+                if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
+                           flags, G_FORMAT))
+                    return 0;
+                break;
+            case 'c':
+                if(!doapr_outch(sbuffer, buffer, &currlen, maxlen,
+                            va_arg(args, int)))
+                    return 0;
+                break;
+            case 's':
+                strvalue = va_arg(args, char *);
+                if (max < 0) {
+                    if (buffer)
+                        max = INT_MAX;
+                    else
+                        max = *maxlen;
+                }
+                if (!fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
+                            flags, min, max))
+                    return 0;
+                break;
+            case 'p':
+                value = (size_t)va_arg(args, void *);
+                if (!fmtint(sbuffer, buffer, &currlen, maxlen,
+                            value, 16, min, max, flags | DP_F_NUM))
+                    return 0;
+                break;
+            case 'n':          /* XXX */
+                if (cflags == DP_C_SHORT) {
+                    short int *num;
+                    num = va_arg(args, short int *);
+                    *num = currlen;
+                } else if (cflags == DP_C_LONG) { /* XXX */
+                    long int *num;
+                    num = va_arg(args, long int *);
+                    *num = (long int)currlen;
+                } else if (cflags == DP_C_LLONG) { /* XXX */
+                    LLONG *num;
+                    num = va_arg(args, LLONG *);
+                    *num = (LLONG) currlen;
+                } else {
+                    int *num;
+                    num = va_arg(args, int *);
+                    *num = currlen;
+                }
+                break;
+            case '%':
+                if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
+                    return 0;
+                break;
+            case 'w':
+                /* not supported yet, treat as next char */
+                ch = *format++;
+                break;
+            default:
+                /* unknown, skip */
+                break;
+            }
+            ch = *format++;
+            state = DP_S_DEFAULT;
+            flags = cflags = min = 0;
+            max = -1;
+            break;
+        case DP_S_DONE:
+            break;
+        default:
+            break;
+        }
+    }
+    /*
+     * We have to truncate if there is no dynamic buffer and we have filled the
+     * static buffer.
+     */
+    if (buffer == NULL) {
+        *truncated = (currlen > *maxlen - 1);
+        if (*truncated)
+            currlen = *maxlen - 1;
+    }
+    if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0'))
+        return 0;
+    *retlen = currlen - 1;
+    return 1;
+}
+
+static int
+fmtstr(char **sbuffer,
+       char **buffer,
+       size_t *currlen,
+       size_t *maxlen, const char *value, int flags, int min, int max)
+{
+    int padlen;
+    size_t strln;
+    int cnt = 0;
+
+    if (value == 0)
+        value = "<NULL>";
+
+    strln = OPENSSL_strnlen(value, max < 0 ? SIZE_MAX : (size_t)max);
+
+    padlen = min - strln;
+    if (min < 0 || padlen < 0)
+        padlen = 0;
+    if (max >= 0) {
+        /*
+         * Calculate the maximum output including padding.
+         * Make sure max doesn't overflow into negativity
+         */
+        if (max < INT_MAX - padlen)
+            max += padlen;
+        else
+            max = INT_MAX;
+    }
+    if (flags & DP_F_MINUS)
+        padlen = -padlen;
+
+    while ((padlen > 0) && (max < 0 || cnt < max)) {
+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+            return 0;
+        --padlen;
+        ++cnt;
+    }
+    while (strln > 0 && (max < 0 || cnt < max)) {
+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *value++))
+            return 0;
+        --strln;
+        ++cnt;
+    }
+    while ((padlen < 0) && (max < 0 || cnt < max)) {
+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+            return 0;
+        ++padlen;
+        ++cnt;
+    }
+    return 1;
+}
+
+static int
+fmtint(char **sbuffer,
+       char **buffer,
+       size_t *currlen,
+       size_t *maxlen, LLONG value, int base, int min, int max, int flags)
+{
+    int signvalue = 0;
+    const char *prefix = "";
+    unsigned LLONG uvalue;
+    char convert[DECIMAL_SIZE(value) + 3];
+    int place = 0;
+    int spadlen = 0;
+    int zpadlen = 0;
+    int caps = 0;
+
+    if (max < 0)
+        max = 0;
+    uvalue = value;
+    if (!(flags & DP_F_UNSIGNED)) {
+        if (value < 0) {
+            signvalue = '-';
+            uvalue = 0 - (unsigned LLONG)value;
+        } else if (flags & DP_F_PLUS)
+            signvalue = '+';
+        else if (flags & DP_F_SPACE)
+            signvalue = ' ';
+    }
+    if (flags & DP_F_NUM) {
+        if (base == 8)
+            prefix = "0";
+        if (base == 16)
+            prefix = "0x";
+    }
+    if (flags & DP_F_UP)
+        caps = 1;
+    do {
+        convert[place++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")
+            [uvalue % (unsigned)base];
+        uvalue = (uvalue / (unsigned)base);
+    } while (uvalue && (place < (int)sizeof(convert)));
+    if (place == sizeof(convert))
+        place--;
+    convert[place] = 0;
+
+    zpadlen = max - place;
+    spadlen =
+        min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix);
+    if (zpadlen < 0)
+        zpadlen = 0;
+    if (spadlen < 0)
+        spadlen = 0;
+    if (flags & DP_F_ZERO) {
+        zpadlen = OSSL_MAX(zpadlen, spadlen);
+        spadlen = 0;
+    }
+    if (flags & DP_F_MINUS)
+        spadlen = -spadlen;
+
+    /* spaces */
+    while (spadlen > 0) {
+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+            return 0;
+        --spadlen;
+    }
+
+    /* sign */
+    if (signvalue)
+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+            return 0;
+
+    /* prefix */
+    while (*prefix) {
+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix))
+            return 0;
+        prefix++;
+    }
+
+    /* zeros */
+    if (zpadlen > 0) {
+        while (zpadlen > 0) {
+            if(!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+                return 0;
+            --zpadlen;
+        }
+    }
+    /* digits */
+    while (place > 0) {
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]))
+            return 0;
+    }
+
+    /* left justified spaces */
+    while (spadlen < 0) {
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+            return 0;
+        ++spadlen;
+    }
+    return 1;
+}
+
+static LDOUBLE abs_val(LDOUBLE value)
+{
+    LDOUBLE result = value;
+    if (value < 0)
+        result = -value;
+    return result;
+}
+
+static LDOUBLE pow_10(int in_exp)
+{
+    LDOUBLE result = 1;
+    while (in_exp) {
+        result *= 10;
+        in_exp--;
+    }
+    return result;
+}
+
+static long roundv(LDOUBLE value)
+{
+    long intpart;
+    intpart = (long)value;
+    value = value - intpart;
+    if (value >= 0.5)
+        intpart++;
+    return intpart;
+}
+
+static int
+fmtfp(char **sbuffer,
+      char **buffer,
+      size_t *currlen,
+      size_t *maxlen, LDOUBLE fvalue, int min, int max, int flags, int style)
+{
+    int signvalue = 0;
+    LDOUBLE ufvalue;
+    LDOUBLE tmpvalue;
+    char iconvert[20];
+    char fconvert[20];
+    char econvert[20];
+    int iplace = 0;
+    int fplace = 0;
+    int eplace = 0;
+    int padlen = 0;
+    int zpadlen = 0;
+    long exp = 0;
+    unsigned long intpart;
+    unsigned long fracpart;
+    unsigned long max10;
+    int realstyle;
+
+    if (max < 0)
+        max = 6;
+
+    if (fvalue < 0)
+        signvalue = '-';
+    else if (flags & DP_F_PLUS)
+        signvalue = '+';
+    else if (flags & DP_F_SPACE)
+        signvalue = ' ';
+
+    /*
+     * G_FORMAT sometimes prints like E_FORMAT and sometimes like F_FORMAT
+     * depending on the number to be printed. Work out which one it is and use
+     * that from here on.
+     */
+    if (style == G_FORMAT) {
+        if (fvalue == 0.0) {
+            realstyle = F_FORMAT;
+        } else if (fvalue < 0.0001) {
+            realstyle = E_FORMAT;
+        } else if ((max == 0 && fvalue >= 10)
+                    || (max > 0 && fvalue >= pow_10(max))) {
+            realstyle = E_FORMAT;
+        } else {
+            realstyle = F_FORMAT;
+        }
+    } else {
+        realstyle = style;
+    }
+
+    if (style != F_FORMAT) {
+        tmpvalue = fvalue;
+        /* Calculate the exponent */
+        if (fvalue != 0.0) {
+            while (tmpvalue < 1) {
+                tmpvalue *= 10;
+                exp--;
+            }
+            while (tmpvalue > 10) {
+                tmpvalue /= 10;
+                exp++;
+            }
+        }
+        if (style == G_FORMAT) {
+            /*
+             * In G_FORMAT the "precision" represents significant digits. We
+             * always have at least 1 significant digit.
+             */
+            if (max == 0)
+                max = 1;
+            /* Now convert significant digits to decimal places */
+            if (realstyle == F_FORMAT) {
+                max -= (exp + 1);
+                if (max < 0) {
+                    /*
+                     * Should not happen. If we're in F_FORMAT then exp < max?
+                     */
+                    return 0;
+                }
+            } else {
+                /*
+                 * In E_FORMAT there is always one significant digit in front
+                 * of the decimal point, so:
+                 * significant digits == 1 + decimal places
+                 */
+                max--;
+            }
+        }
+        if (realstyle == E_FORMAT)
+            fvalue = tmpvalue;
+    }
+    ufvalue = abs_val(fvalue);
+    if (ufvalue > ULONG_MAX) {
+        /* Number too big */
+        return 0;
+    }
+    intpart = (unsigned long)ufvalue;
+
+    /*
+     * sorry, we only support 9 digits past the decimal because of our
+     * conversion method
+     */
+    if (max > 9)
+        max = 9;
+
+    /*
+     * we "cheat" by converting the fractional part to integer by multiplying
+     * by a factor of 10
+     */
+    max10 = roundv(pow_10(max));
+    fracpart = roundv(pow_10(max) * (ufvalue - intpart));
+
+    if (fracpart >= max10) {
+        intpart++;
+        fracpart -= max10;
+    }
+
+    /* convert integer part */
+    do {
+        iconvert[iplace++] = "0123456789"[intpart % 10];
+        intpart = (intpart / 10);
+    } while (intpart && (iplace < (int)sizeof(iconvert)));
+    if (iplace == sizeof iconvert)
+        iplace--;
+    iconvert[iplace] = 0;
+
+    /* convert fractional part */
+    while (fplace < max) {
+        if (style == G_FORMAT && fplace == 0 && (fracpart % 10) == 0) {
+            /* We strip trailing zeros in G_FORMAT */
+            max--;
+            fracpart = fracpart / 10;
+            if (fplace < max)
+                continue;
+            break;
+        }
+        fconvert[fplace++] = "0123456789"[fracpart % 10];
+        fracpart = (fracpart / 10);
+    }
+
+    if (fplace == sizeof fconvert)
+        fplace--;
+    fconvert[fplace] = 0;
+
+    /* convert exponent part */
+    if (realstyle == E_FORMAT) {
+        int tmpexp;
+        if (exp < 0)
+            tmpexp = -exp;
+        else
+            tmpexp = exp;
+
+        do {
+            econvert[eplace++] = "0123456789"[tmpexp % 10];
+            tmpexp = (tmpexp / 10);
+        } while (tmpexp > 0 && eplace < (int)sizeof(econvert));
+        /* Exponent is huge!! Too big to print */
+        if (tmpexp > 0)
+            return 0;
+        /* Add a leading 0 for single digit exponents */
+        if (eplace == 1)
+            econvert[eplace++] = '0';
+    }
+
+    /*
+     * -1 for decimal point (if we have one, i.e. max > 0),
+     * another -1 if we are printing a sign
+     */
+    padlen = min - iplace - max - (max > 0 ? 1 : 0) - ((signvalue) ? 1 : 0);
+    /* Take some off for exponent prefix "+e" and exponent */
+    if (realstyle == E_FORMAT)
+        padlen -= 2 + eplace;
+    zpadlen = max - fplace;
+    if (zpadlen < 0)
+        zpadlen = 0;
+    if (padlen < 0)
+        padlen = 0;
+    if (flags & DP_F_MINUS)
+        padlen = -padlen;
+
+    if ((flags & DP_F_ZERO) && (padlen > 0)) {
+        if (signvalue) {
+            if (!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+                return 0;
+            --padlen;
+            signvalue = 0;
+        }
+        while (padlen > 0) {
+            if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+                return 0;
+            --padlen;
+        }
+    }
+    while (padlen > 0) {
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+            return 0;
+        --padlen;
+    }
+    if (signvalue && !doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+        return 0;
+
+    while (iplace > 0) {
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]))
+            return 0;
+    }
+
+    /*
+     * Decimal point. This should probably use locale to find the correct
+     * char to print out.
+     */
+    if (max > 0 || (flags & DP_F_NUM)) {
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '.'))
+            return 0;
+
+        while (fplace > 0) {
+            if(!doapr_outch(sbuffer, buffer, currlen, maxlen,
+                            fconvert[--fplace]))
+                return 0;
+        }
+    }
+    while (zpadlen > 0) {
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+            return 0;
+        --zpadlen;
+    }
+    if (realstyle == E_FORMAT) {
+        char ech;
+
+        if ((flags & DP_F_UP) == 0)
+            ech = 'e';
+        else
+            ech = 'E';
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ech))
+                return 0;
+        if (exp < 0) {
+            if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '-'))
+                    return 0;
+        } else {
+            if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '+'))
+                    return 0;
+        }
+        while (eplace > 0) {
+            if (!doapr_outch(sbuffer, buffer, currlen, maxlen,
+                             econvert[--eplace]))
+                return 0;
+        }
+    }
+
+    while (padlen < 0) {
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+            return 0;
+        ++padlen;
+    }
+    return 1;
+}
+
+#define BUFFER_INC  1024
+
+static int
+doapr_outch(char **sbuffer,
+            char **buffer, size_t *currlen, size_t *maxlen, int c)
+{
+    /* If we haven't at least one buffer, someone has doe a big booboo */
+    OPENSSL_assert(*sbuffer != NULL || buffer != NULL);
+
+    /* |currlen| must always be <= |*maxlen| */
+    OPENSSL_assert(*currlen <= *maxlen);
+
+    if (buffer && *currlen == *maxlen) {
+        if (*maxlen > INT_MAX - BUFFER_INC)
+            return 0;
+
+        *maxlen += BUFFER_INC;
+        if (*buffer == NULL) {
+            *buffer = OPENSSL_malloc(*maxlen);
+            if (*buffer == NULL)
+                return 0;
+            if (*currlen > 0) {
+                OPENSSL_assert(*sbuffer != NULL);
+                memcpy(*buffer, *sbuffer, *currlen);
+            }
+            *sbuffer = NULL;
+        } else {
+            char *tmpbuf;
+            tmpbuf = OPENSSL_realloc(*buffer, *maxlen);
+            if (tmpbuf == NULL)
+                return 0;
+            *buffer = tmpbuf;
+        }
+    }
+
+    if (*currlen < *maxlen) {
+        if (*sbuffer)
+            (*sbuffer)[(*currlen)++] = (char)c;
+        else
+            (*buffer)[(*currlen)++] = (char)c;
+    }
+
+    return 1;
+}
+
+/***************************************************************************/
+
+int BIO_printf(BIO *bio, const char *format, ...)
+{
+    va_list args;
+    int ret;
+
+    va_start(args, format);
+
+    ret = BIO_vprintf(bio, format, args);
+
+    va_end(args);
+    return (ret);
+}
+
+int BIO_vprintf(BIO *bio, const char *format, va_list args)
+{
+    int ret;
+    size_t retlen;
+    char hugebuf[1024 * 2];     /* Was previously 10k, which is unreasonable
+                                 * in small-stack environments, like threads
+                                 * or DOS programs. */
+    char *hugebufp = hugebuf;
+    size_t hugebufsize = sizeof(hugebuf);
+    char *dynbuf = NULL;
+    int ignored;
+
+    dynbuf = NULL;
+    if (!_dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, format,
+                args)) {
+        OPENSSL_free(dynbuf);
+        return -1;
+    }
+    if (dynbuf) {
+        ret = BIO_write(bio, dynbuf, (int)retlen);
+        OPENSSL_free(dynbuf);
+    } else {
+        ret = BIO_write(bio, hugebuf, (int)retlen);
+    }
+    return (ret);
+}
+
+/*
+ * As snprintf is not available everywhere, we provide our own
+ * implementation. This function has nothing to do with BIOs, but it's
+ * closely related to BIO_printf, and we need *some* name prefix ... (XXX the
+ * function should be renamed, but to what?)
+ */
+int BIO_snprintf(char *buf, size_t n, const char *format, ...)
+{
+    va_list args;
+    int ret;
+
+    va_start(args, format);
+
+    ret = BIO_vsnprintf(buf, n, format, args);
+
+    va_end(args);
+    return (ret);
+}
+
+int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
+{
+    size_t retlen;
+    int truncated;
+
+    if(!_dopr(&buf, NULL, &n, &retlen, &truncated, format, args))
+        return -1;
+
+    if (truncated)
+        /*
+         * In case of truncation, return -1 like traditional snprintf.
+         * (Current drafts for ISO/IEC 9899 say snprintf should return the
+         * number of characters that would have been written, had the buffer
+         * been large enough.)
+         */
+        return -1;
+    else
+        return (retlen <= INT_MAX) ? (int)retlen : -1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/b_sock.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/b_sock.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/b_sock.c	(revision 331)
@@ -0,0 +1,381 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "bio_lcl.h"
+#if defined(NETWARE_CLIB)
+# include <sys/ioctl.h>
+NETDB_DEFINE_CONTEXT
+#endif
+#ifndef OPENSSL_NO_SOCK
+# define SOCKET_PROTOCOL IPPROTO_TCP
+# ifdef SO_MAXCONN
+#  define MAX_LISTEN  SO_MAXCONN
+# elif defined(SOMAXCONN)
+#  define MAX_LISTEN  SOMAXCONN
+# else
+#  define MAX_LISTEN  32
+# endif
+# if defined(OPENSSL_SYS_WINDOWS)
+static int wsa_init_done = 0;
+# endif
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+int BIO_get_host_ip(const char *str, unsigned char *ip)
+{
+    BIO_ADDRINFO *res = NULL;
+    int ret = 0;
+
+    if (BIO_sock_init() != 1)
+        return 0;               /* don't generate another error code here */
+
+    if (BIO_lookup(str, NULL, BIO_LOOKUP_CLIENT, AF_INET, SOCK_STREAM, &res)) {
+        size_t l;
+
+        if (BIO_ADDRINFO_family(res) != AF_INET) {
+            BIOerr(BIO_F_BIO_GET_HOST_IP,
+                   BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET);
+        } else {
+            BIO_ADDR_rawaddress(BIO_ADDRINFO_address(res), NULL, &l);
+            /* Because only AF_INET addresses will reach this far,
+               we can assert that l should be 4 */
+            OPENSSL_assert(l == 4);
+
+            BIO_ADDR_rawaddress(BIO_ADDRINFO_address(res), ip, &l);
+            ret = 1;
+        }
+        BIO_ADDRINFO_free(res);
+    } else {
+        ERR_add_error_data(2, "host=", str);
+    }
+
+    return ret;
+}
+
+int BIO_get_port(const char *str, unsigned short *port_ptr)
+{
+    BIO_ADDRINFO *res = NULL;
+    int ret = 0;
+
+    if (str == NULL) {
+        BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_DEFINED);
+        return (0);
+    }
+
+    if (BIO_sock_init() != 1)
+        return 0;               /* don't generate another error code here */
+
+    if (BIO_lookup(NULL, str, BIO_LOOKUP_CLIENT, AF_INET, SOCK_STREAM, &res)) {
+        if (BIO_ADDRINFO_family(res) != AF_INET) {
+            BIOerr(BIO_F_BIO_GET_PORT,
+                   BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET);
+        } else {
+            *port_ptr = ntohs(BIO_ADDR_rawport(BIO_ADDRINFO_address(res)));
+            ret = 1;
+        }
+        BIO_ADDRINFO_free(res);
+    } else {
+        ERR_add_error_data(2, "host=", str);
+    }
+
+    return ret;
+}
+# endif
+
+int BIO_sock_error(int sock)
+{
+    int j = 0, i;
+    socklen_t size = sizeof(j);
+
+    /*
+     * Note: under Windows the third parameter is of type (char *) whereas
+     * under other systems it is (void *) if you don't have a cast it will
+     * choke the compiler: if you do have a cast then you can either go for
+     * (char *) or (void *).
+     */
+    i = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&j, &size);
+    if (i < 0)
+        return (get_last_socket_error());
+    else
+        return (j);
+}
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+struct hostent *BIO_gethostbyname(const char *name)
+{
+    /*
+     * Caching gethostbyname() results forever is wrong, so we have to let
+     * the true gethostbyname() worry about this
+     */
+#  if (defined(NETWARE_BSDSOCK) && !defined(__NOVELL_LIBC__))
+    return gethostbyname((char *)name);
+#  else
+    return gethostbyname(name);
+#  endif
+}
+# endif
+
+int BIO_sock_init(void)
+{
+# ifdef OPENSSL_SYS_WINDOWS
+    static struct WSAData wsa_state;
+
+    if (!wsa_init_done) {
+        int err;
+
+        wsa_init_done = 1;
+        memset(&wsa_state, 0, sizeof(wsa_state));
+        /*
+         * Not making wsa_state available to the rest of the code is formally
+         * wrong. But the structures we use are [believed to be] invariable
+         * among Winsock DLLs, while API availability is [expected to be]
+         * probed at run-time with DSO_global_lookup.
+         */
+        if (WSAStartup(0x0202, &wsa_state) != 0) {
+            err = WSAGetLastError();
+            SYSerr(SYS_F_WSASTARTUP, err);
+            BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP);
+            return (-1);
+        }
+    }
+# endif                         /* OPENSSL_SYS_WINDOWS */
+# ifdef WATT32
+    extern int _watt_do_exit;
+    _watt_do_exit = 0;          /* don't make sock_init() call exit() */
+    if (sock_init())
+        return (-1);
+# endif
+
+    return (1);
+}
+
+void bio_sock_cleanup_int(void)
+{
+# ifdef OPENSSL_SYS_WINDOWS
+    if (wsa_init_done) {
+        wsa_init_done = 0;
+        WSACleanup();
+    }
+# endif
+}
+
+# if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000
+
+int BIO_socket_ioctl(int fd, long type, void *arg)
+{
+    int i;
+
+#  ifdef __DJGPP__
+    i = ioctlsocket(fd, type, (char *)arg);
+#  else
+#   if defined(OPENSSL_SYS_VMS)
+    /*-
+     * 2011-02-18 SMS.
+     * VMS ioctl() can't tolerate a 64-bit "void *arg", but we
+     * observe that all the consumers pass in an "unsigned long *",
+     * so we arrange a local copy with a short pointer, and use
+     * that, instead.
+     */
+#    if __INITIAL_POINTER_SIZE == 64
+#     define ARG arg_32p
+#     pragma pointer_size save
+#     pragma pointer_size 32
+    unsigned long arg_32;
+    unsigned long *arg_32p;
+#     pragma pointer_size restore
+    arg_32p = &arg_32;
+    arg_32 = *((unsigned long *)arg);
+#    else                       /* __INITIAL_POINTER_SIZE == 64 */
+#     define ARG arg
+#    endif                      /* __INITIAL_POINTER_SIZE == 64 [else] */
+#   else                        /* defined(OPENSSL_SYS_VMS) */
+#    define ARG arg
+#   endif                       /* defined(OPENSSL_SYS_VMS) [else] */
+
+    i = ioctlsocket(fd, type, ARG);
+#  endif                        /* __DJGPP__ */
+    if (i < 0)
+        SYSerr(SYS_F_IOCTLSOCKET, get_last_socket_error());
+    return (i);
+}
+# endif                         /* __VMS_VER */
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+int BIO_get_accept_socket(char *host, int bind_mode)
+{
+    int s = INVALID_SOCKET;
+    char *h = NULL, *p = NULL;
+    BIO_ADDRINFO *res = NULL;
+
+    if (!BIO_parse_hostserv(host, &h, &p, BIO_PARSE_PRIO_SERV))
+        return INVALID_SOCKET;
+
+    if (BIO_sock_init() != 1)
+        return INVALID_SOCKET;
+
+    if (BIO_lookup(h, p, BIO_LOOKUP_SERVER, AF_UNSPEC, SOCK_STREAM, &res) != 0)
+        goto err;
+
+    if ((s = BIO_socket(BIO_ADDRINFO_family(res), BIO_ADDRINFO_socktype(res),
+                        BIO_ADDRINFO_protocol(res), 0)) == INVALID_SOCKET) {
+        s = INVALID_SOCKET;
+        goto err;
+    }
+
+    if (!BIO_listen(s, BIO_ADDRINFO_address(res),
+                    bind_mode ? BIO_SOCK_REUSEADDR : 0)) {
+        BIO_closesocket(s);
+        s = INVALID_SOCKET;
+    }
+
+ err:
+    BIO_ADDRINFO_free(res);
+    OPENSSL_free(h);
+    OPENSSL_free(p);
+
+    return s;
+}
+
+int BIO_accept(int sock, char **ip_port)
+{
+    BIO_ADDR res;
+    int ret = -1;
+
+    ret = BIO_accept_ex(sock, &res, 0);
+    if (ret == (int)INVALID_SOCKET) {
+        if (BIO_sock_should_retry(ret)) {
+            ret = -2;
+            goto end;
+        }
+        SYSerr(SYS_F_ACCEPT, get_last_socket_error());
+        BIOerr(BIO_F_BIO_ACCEPT, BIO_R_ACCEPT_ERROR);
+        goto end;
+    }
+
+    if (ip_port != NULL) {
+        char *host = BIO_ADDR_hostname_string(&res, 1);
+        char *port = BIO_ADDR_service_string(&res, 1);
+        if (host != NULL && port != NULL)
+            *ip_port = OPENSSL_zalloc(strlen(host) + strlen(port) + 2);
+        else
+            *ip_port = NULL;
+
+        if (*ip_port == NULL) {
+            BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE);
+            BIO_closesocket(ret);
+            ret = (int)INVALID_SOCKET;
+        } else {
+            strcpy(*ip_port, host);
+            strcat(*ip_port, ":");
+            strcat(*ip_port, port);
+        }
+        OPENSSL_free(host);
+        OPENSSL_free(port);
+    }
+
+ end:
+    return ret;
+}
+# endif
+
+int BIO_set_tcp_ndelay(int s, int on)
+{
+    int ret = 0;
+# if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP))
+    int opt;
+
+#  ifdef SOL_TCP
+    opt = SOL_TCP;
+#  else
+#   ifdef IPPROTO_TCP
+    opt = IPPROTO_TCP;
+#   endif
+#  endif
+
+    ret = setsockopt(s, opt, TCP_NODELAY, (char *)&on, sizeof(on));
+# endif
+    return (ret == 0);
+}
+
+int BIO_socket_nbio(int s, int mode)
+{
+    int ret = -1;
+    int l;
+
+    l = mode;
+# ifdef FIONBIO
+    l = mode;
+
+    ret = BIO_socket_ioctl(s, FIONBIO, &l);
+# elif defined(F_GETFL) && defined(F_SETFL) && (defined(O_NONBLOCK) || defined(FNDELAY))
+    /* make sure this call always pushes an error level; BIO_socket_ioctl() does so, so we do too. */
+
+    l = fcntl(s, F_GETFL, 0);
+    if (l == -1) {
+        SYSerr(SYS_F_FCNTL, get_last_rtl_error());
+        ret = -1;
+    } else {
+#  if defined(O_NONBLOCK)
+        l &= ~O_NONBLOCK;
+#  else
+        l &= ~FNDELAY; /* BSD4.x */
+#  endif
+        if (mode) {
+#  if defined(O_NONBLOCK)
+            l |= O_NONBLOCK;
+#  else
+            l |= FNDELAY; /* BSD4.x */
+#  endif
+        }
+        ret = fcntl(s, F_SETFL, l);
+
+        if (ret < 0) {
+            SYSerr(SYS_F_FCNTL, get_last_rtl_error());
+        }
+    }
+# else
+    /* make sure this call always pushes an error level; BIO_socket_ioctl() does so, so we do too. */
+    BIOerr(BIO_F_BIO_SOCKET_NBIO, ERR_R_PASSED_INVALID_ARGUMENT);
+# endif
+
+    return (ret == 0);
+}
+
+int BIO_sock_info(int sock,
+                  enum BIO_sock_info_type type, union BIO_sock_info_u *info)
+{
+    switch (type) {
+    case BIO_SOCK_INFO_ADDRESS:
+        {
+            socklen_t addr_len;
+            int ret = 0;
+            addr_len = sizeof(*info->addr);
+            ret = getsockname(sock, BIO_ADDR_sockaddr_noconst(info->addr),
+                              &addr_len);
+            if (ret == -1) {
+                SYSerr(SYS_F_GETSOCKNAME, get_last_socket_error());
+                BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_GETSOCKNAME_ERROR);
+                return 0;
+            }
+            if ((size_t)addr_len > sizeof(*info->addr)) {
+                BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS);
+                return 0;
+            }
+        }
+        break;
+    default:
+        BIOerr(BIO_F_BIO_SOCK_INFO, BIO_R_UNKNOWN_INFO_TYPE);
+        return 0;
+    }
+    return 1;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/b_sock2.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/b_sock2.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/b_sock2.c	(revision 331)
@@ -0,0 +1,270 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "bio_lcl.h"
+
+#include <openssl/err.h>
+
+#ifndef OPENSSL_NO_SOCK
+# ifdef SO_MAXCONN
+#  define MAX_LISTEN  SO_MAXCONN
+# elif defined(SOMAXCONN)
+#  define MAX_LISTEN  SOMAXCONN
+# else
+#  define MAX_LISTEN  32
+# endif
+
+/*-
+ * BIO_socket - create a socket
+ * @domain: the socket domain (AF_INET, AF_INET6, AF_UNIX, ...)
+ * @socktype: the socket type (SOCK_STEAM, SOCK_DGRAM)
+ * @protocol: the protocol to use (IPPROTO_TCP, IPPROTO_UDP)
+ * @options: BIO socket options (currently unused)
+ *
+ * Creates a socket.  This should be called before calling any
+ * of BIO_connect and BIO_listen.
+ *
+ * Returns the file descriptor on success or INVALID_SOCKET on failure.  On
+ * failure errno is set, and a status is added to the OpenSSL error stack.
+ */
+int BIO_socket(int domain, int socktype, int protocol, int options)
+{
+    int sock = -1;
+
+    if (BIO_sock_init() != 1)
+        return INVALID_SOCKET;
+
+    sock = socket(domain, socktype, protocol);
+    if (sock == -1) {
+        SYSerr(SYS_F_SOCKET, get_last_socket_error());
+        BIOerr(BIO_F_BIO_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET);
+        return INVALID_SOCKET;
+    }
+
+    return sock;
+}
+
+/*-
+ * BIO_connect - connect to an address
+ * @sock: the socket to connect with
+ * @addr: the address to connect to
+ * @options: BIO socket options
+ *
+ * Connects to the address using the given socket and options.
+ *
+ * Options can be a combination of the following:
+ * - BIO_SOCK_KEEPALIVE: enable regularly sending keep-alive messages.
+ * - BIO_SOCK_NONBLOCK: Make the socket non-blocking.
+ * - BIO_SOCK_NODELAY: don't delay small messages.
+ *
+ * options holds BIO socket options that can be used
+ * You should call this for every address returned by BIO_lookup
+ * until the connection is successful.
+ *
+ * Returns 1 on success or 0 on failure.  On failure errno is set
+ * and an error status is added to the OpenSSL error stack.
+ */
+int BIO_connect(int sock, const BIO_ADDR *addr, int options)
+{
+    int on = 1;
+
+    if (sock == -1) {
+        BIOerr(BIO_F_BIO_CONNECT, BIO_R_INVALID_SOCKET);
+        return 0;
+    }
+
+    if (!BIO_socket_nbio(sock, (options & BIO_SOCK_NONBLOCK) != 0))
+        return 0;
+
+    if (options & BIO_SOCK_KEEPALIVE) {
+        if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) != 0) {
+            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
+            BIOerr(BIO_F_BIO_CONNECT, BIO_R_UNABLE_TO_KEEPALIVE);
+            return 0;
+        }
+    }
+
+    if (options & BIO_SOCK_NODELAY) {
+        if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) != 0) {
+            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
+            BIOerr(BIO_F_BIO_CONNECT, BIO_R_UNABLE_TO_NODELAY);
+            return 0;
+        }
+    }
+
+    if (connect(sock, BIO_ADDR_sockaddr(addr),
+                BIO_ADDR_sockaddr_size(addr)) == -1) {
+        if (!BIO_sock_should_retry(-1)) {
+            SYSerr(SYS_F_CONNECT, get_last_socket_error());
+            BIOerr(BIO_F_BIO_CONNECT, BIO_R_CONNECT_ERROR);
+        }
+        return 0;
+    }
+    return 1;
+}
+
+/*-
+ * BIO_listen - Creates a listen socket
+ * @sock: the socket to listen with
+ * @addr: local address to bind to
+ * @options: BIO socket options
+ *
+ * Binds to the address using the given socket and options, then
+ * starts listening for incoming connections.
+ *
+ * Options can be a combination of the following:
+ * - BIO_SOCK_KEEPALIVE: enable regularly sending keep-alive messages.
+ * - BIO_SOCK_NONBLOCK: Make the socket non-blocking.
+ * - BIO_SOCK_NODELAY: don't delay small messages.
+ * - BIO_SOCK_REUSEADDR: Try to reuse the address and port combination
+ *   for a recently closed port.
+ * - BIO_SOCK_V6_ONLY: When creating an IPv6 socket, make it listen only
+ *   for IPv6 addresses and not IPv4 addresses mapped to IPv6.
+ *
+ * It's recommended that you set up both an IPv6 and IPv4 listen socket, and
+ * then check both for new clients that connect to it.  You want to set up
+ * the socket as non-blocking in that case since else it could hang.
+ *
+ * Not all operating systems support IPv4 addresses on an IPv6 socket, and for
+ * others it's an option.  If you pass the BIO_LISTEN_V6_ONLY it will try to
+ * create the IPv6 sockets to only listen for IPv6 connection.
+ *
+ * It could be that the first BIO_listen() call will listen to all the IPv6
+ * and IPv4 addresses and that then trying to bind to the IPv4 address will
+ * fail.  We can't tell the difference between already listening ourself to
+ * it and someone else listening to it when failing and errno is EADDRINUSE, so
+ * it's recommended to not give an error in that case if the first call was
+ * successful.
+ *
+ * When restarting the program it could be that the port is still in use.  If
+ * you set to BIO_SOCK_REUSEADDR option it will try to reuse the port anyway.
+ * It's recommended that you use this.
+ */
+int BIO_listen(int sock, const BIO_ADDR *addr, int options)
+{
+    int on = 1;
+    int socktype;
+    socklen_t socktype_len = sizeof(socktype);
+
+    if (sock == -1) {
+        BIOerr(BIO_F_BIO_LISTEN, BIO_R_INVALID_SOCKET);
+        return 0;
+    }
+
+    if (getsockopt(sock, SOL_SOCKET, SO_TYPE, &socktype, &socktype_len) != 0
+        || socktype_len != sizeof(socktype)) {
+        SYSerr(SYS_F_GETSOCKOPT, get_last_socket_error());
+        BIOerr(BIO_F_BIO_LISTEN, BIO_R_GETTING_SOCKTYPE);
+        return 0;
+    }
+
+    if (!BIO_socket_nbio(sock, (options & BIO_SOCK_NONBLOCK) != 0))
+        return 0;
+
+# ifndef OPENSSL_SYS_WINDOWS
+    /* SO_REUSEADDR has different behavior on Windows than on
+     * other operating systems, don't set it there. */
+    if (options & BIO_SOCK_REUSEADDR) {
+        if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) {
+            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
+            BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_REUSEADDR);
+            return 0;
+        }
+    }
+# endif
+
+    if (options & BIO_SOCK_KEEPALIVE) {
+        if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) != 0) {
+            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
+            BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_KEEPALIVE);
+            return 0;
+        }
+    }
+
+    if (options & BIO_SOCK_NODELAY) {
+        if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) != 0) {
+            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
+            BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_NODELAY);
+            return 0;
+        }
+    }
+
+# ifdef IPV6_V6ONLY
+    if ((options & BIO_SOCK_V6_ONLY) && BIO_ADDR_family(addr) == AF_INET6) {
+        if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) != 0) {
+            SYSerr(SYS_F_SETSOCKOPT, get_last_socket_error());
+            BIOerr(BIO_F_BIO_LISTEN, BIO_R_LISTEN_V6_ONLY);
+            return 0;
+        }
+    }
+# endif
+
+    if (bind(sock, BIO_ADDR_sockaddr(addr), BIO_ADDR_sockaddr_size(addr)) != 0) {
+        SYSerr(SYS_F_BIND, get_last_socket_error());
+        BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_BIND_SOCKET);
+        return 0;
+    }
+
+    if (socktype != SOCK_DGRAM && listen(sock, MAX_LISTEN) == -1) {
+        SYSerr(SYS_F_LISTEN, get_last_socket_error());
+        BIOerr(BIO_F_BIO_LISTEN, BIO_R_UNABLE_TO_LISTEN_SOCKET);
+        return 0;
+    }
+
+    return 1;
+}
+
+/*-
+ * BIO_accept_ex - Accept new incoming connections
+ * @sock: the listening socket
+ * @addr: the BIO_ADDR to store the peer address in
+ * @options: BIO socket options, applied on the accepted socket.
+ *
+ */
+int BIO_accept_ex(int accept_sock, BIO_ADDR *addr_, int options)
+{
+    socklen_t len;
+    int accepted_sock;
+    BIO_ADDR locaddr;
+    BIO_ADDR *addr = addr_ == NULL ? &locaddr : addr_;
+
+    len = sizeof(*addr);
+    accepted_sock = accept(accept_sock,
+                           BIO_ADDR_sockaddr_noconst(addr), &len);
+    if (accepted_sock == -1) {
+        if (!BIO_sock_should_retry(accepted_sock)) {
+            SYSerr(SYS_F_ACCEPT, get_last_socket_error());
+            BIOerr(BIO_F_BIO_ACCEPT_EX, BIO_R_ACCEPT_ERROR);
+        }
+        return INVALID_SOCKET;
+    }
+
+    if (!BIO_socket_nbio(accepted_sock, (options & BIO_SOCK_NONBLOCK) != 0)) {
+        closesocket(accepted_sock);
+        return INVALID_SOCKET;
+    }
+
+    return accepted_sock;
+}
+
+/*-
+ * BIO_closesocket - Close a socket
+ * @sock: the socket to close
+ */
+int BIO_closesocket(int sock)
+{
+    if (closesocket(sock) < 0)
+        return 0;
+    return 1;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bf_buff.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bf_buff.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bf_buff.c	(revision 331)
@@ -0,0 +1,455 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <errno.h>
+#include "bio_lcl.h"
+#include "internal/cryptlib.h"
+
+static int buffer_write(BIO *h, const char *buf, int num);
+static int buffer_read(BIO *h, char *buf, int size);
+static int buffer_puts(BIO *h, const char *str);
+static int buffer_gets(BIO *h, char *str, int size);
+static long buffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int buffer_new(BIO *h);
+static int buffer_free(BIO *data);
+static long buffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+#define DEFAULT_BUFFER_SIZE     4096
+
+static const BIO_METHOD methods_buffer = {
+    BIO_TYPE_BUFFER,
+    "buffer",
+    buffer_write,
+    buffer_read,
+    buffer_puts,
+    buffer_gets,
+    buffer_ctrl,
+    buffer_new,
+    buffer_free,
+    buffer_callback_ctrl,
+};
+
+const BIO_METHOD *BIO_f_buffer(void)
+{
+    return (&methods_buffer);
+}
+
+static int buffer_new(BIO *bi)
+{
+    BIO_F_BUFFER_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+    if (ctx == NULL)
+        return (0);
+    ctx->ibuf_size = DEFAULT_BUFFER_SIZE;
+    ctx->ibuf = OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
+    if (ctx->ibuf == NULL) {
+        OPENSSL_free(ctx);
+        return (0);
+    }
+    ctx->obuf_size = DEFAULT_BUFFER_SIZE;
+    ctx->obuf = OPENSSL_malloc(DEFAULT_BUFFER_SIZE);
+    if (ctx->obuf == NULL) {
+        OPENSSL_free(ctx->ibuf);
+        OPENSSL_free(ctx);
+        return (0);
+    }
+
+    bi->init = 1;
+    bi->ptr = (char *)ctx;
+    bi->flags = 0;
+    return (1);
+}
+
+static int buffer_free(BIO *a)
+{
+    BIO_F_BUFFER_CTX *b;
+
+    if (a == NULL)
+        return (0);
+    b = (BIO_F_BUFFER_CTX *)a->ptr;
+    OPENSSL_free(b->ibuf);
+    OPENSSL_free(b->obuf);
+    OPENSSL_free(a->ptr);
+    a->ptr = NULL;
+    a->init = 0;
+    a->flags = 0;
+    return (1);
+}
+
+static int buffer_read(BIO *b, char *out, int outl)
+{
+    int i, num = 0;
+    BIO_F_BUFFER_CTX *ctx;
+
+    if (out == NULL)
+        return (0);
+    ctx = (BIO_F_BUFFER_CTX *)b->ptr;
+
+    if ((ctx == NULL) || (b->next_bio == NULL))
+        return (0);
+    num = 0;
+    BIO_clear_retry_flags(b);
+
+ start:
+    i = ctx->ibuf_len;
+    /* If there is stuff left over, grab it */
+    if (i != 0) {
+        if (i > outl)
+            i = outl;
+        memcpy(out, &(ctx->ibuf[ctx->ibuf_off]), i);
+        ctx->ibuf_off += i;
+        ctx->ibuf_len -= i;
+        num += i;
+        if (outl == i)
+            return (num);
+        outl -= i;
+        out += i;
+    }
+
+    /*
+     * We may have done a partial read. try to do more. We have nothing in
+     * the buffer. If we get an error and have read some data, just return it
+     * and let them retry to get the error again. copy direct to parent
+     * address space
+     */
+    if (outl > ctx->ibuf_size) {
+        for (;;) {
+            i = BIO_read(b->next_bio, out, outl);
+            if (i <= 0) {
+                BIO_copy_next_retry(b);
+                if (i < 0)
+                    return ((num > 0) ? num : i);
+                if (i == 0)
+                    return (num);
+            }
+            num += i;
+            if (outl == i)
+                return (num);
+            out += i;
+            outl -= i;
+        }
+    }
+    /* else */
+
+    /* we are going to be doing some buffering */
+    i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size);
+    if (i <= 0) {
+        BIO_copy_next_retry(b);
+        if (i < 0)
+            return ((num > 0) ? num : i);
+        if (i == 0)
+            return (num);
+    }
+    ctx->ibuf_off = 0;
+    ctx->ibuf_len = i;
+
+    /* Lets re-read using ourselves :-) */
+    goto start;
+}
+
+static int buffer_write(BIO *b, const char *in, int inl)
+{
+    int i, num = 0;
+    BIO_F_BUFFER_CTX *ctx;
+
+    if ((in == NULL) || (inl <= 0))
+        return (0);
+    ctx = (BIO_F_BUFFER_CTX *)b->ptr;
+    if ((ctx == NULL) || (b->next_bio == NULL))
+        return (0);
+
+    BIO_clear_retry_flags(b);
+ start:
+    i = ctx->obuf_size - (ctx->obuf_len + ctx->obuf_off);
+    /* add to buffer and return */
+    if (i >= inl) {
+        memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, inl);
+        ctx->obuf_len += inl;
+        return (num + inl);
+    }
+    /* else */
+    /* stuff already in buffer, so add to it first, then flush */
+    if (ctx->obuf_len != 0) {
+        if (i > 0) {            /* lets fill it up if we can */
+            memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, i);
+            in += i;
+            inl -= i;
+            num += i;
+            ctx->obuf_len += i;
+        }
+        /* we now have a full buffer needing flushing */
+        for (;;) {
+            i = BIO_write(b->next_bio, &(ctx->obuf[ctx->obuf_off]),
+                          ctx->obuf_len);
+            if (i <= 0) {
+                BIO_copy_next_retry(b);
+
+                if (i < 0)
+                    return ((num > 0) ? num : i);
+                if (i == 0)
+                    return (num);
+            }
+            ctx->obuf_off += i;
+            ctx->obuf_len -= i;
+            if (ctx->obuf_len == 0)
+                break;
+        }
+    }
+    /*
+     * we only get here if the buffer has been flushed and we still have
+     * stuff to write
+     */
+    ctx->obuf_off = 0;
+
+    /* we now have inl bytes to write */
+    while (inl >= ctx->obuf_size) {
+        i = BIO_write(b->next_bio, in, inl);
+        if (i <= 0) {
+            BIO_copy_next_retry(b);
+            if (i < 0)
+                return ((num > 0) ? num : i);
+            if (i == 0)
+                return (num);
+        }
+        num += i;
+        in += i;
+        inl -= i;
+        if (inl == 0)
+            return (num);
+    }
+
+    /*
+     * copy the rest into the buffer since we have only a small amount left
+     */
+    goto start;
+}
+
+static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    BIO *dbio;
+    BIO_F_BUFFER_CTX *ctx;
+    long ret = 1;
+    char *p1, *p2;
+    int r, i, *ip;
+    int ibs, obs;
+
+    ctx = (BIO_F_BUFFER_CTX *)b->ptr;
+
+    switch (cmd) {
+    case BIO_CTRL_RESET:
+        ctx->ibuf_off = 0;
+        ctx->ibuf_len = 0;
+        ctx->obuf_off = 0;
+        ctx->obuf_len = 0;
+        if (b->next_bio == NULL)
+            return (0);
+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+        break;
+    case BIO_CTRL_INFO:
+        ret = (long)ctx->obuf_len;
+        break;
+    case BIO_C_GET_BUFF_NUM_LINES:
+        ret = 0;
+        p1 = ctx->ibuf;
+        for (i = 0; i < ctx->ibuf_len; i++) {
+            if (p1[ctx->ibuf_off + i] == '\n')
+                ret++;
+        }
+        break;
+    case BIO_CTRL_WPENDING:
+        ret = (long)ctx->obuf_len;
+        if (ret == 0) {
+            if (b->next_bio == NULL)
+                return (0);
+            ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+        }
+        break;
+    case BIO_CTRL_PENDING:
+        ret = (long)ctx->ibuf_len;
+        if (ret == 0) {
+            if (b->next_bio == NULL)
+                return (0);
+            ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+        }
+        break;
+    case BIO_C_SET_BUFF_READ_DATA:
+        if (num > ctx->ibuf_size) {
+            p1 = OPENSSL_malloc((int)num);
+            if (p1 == NULL)
+                goto malloc_error;
+            OPENSSL_free(ctx->ibuf);
+            ctx->ibuf = p1;
+        }
+        ctx->ibuf_off = 0;
+        ctx->ibuf_len = (int)num;
+        memcpy(ctx->ibuf, ptr, (int)num);
+        ret = 1;
+        break;
+    case BIO_C_SET_BUFF_SIZE:
+        if (ptr != NULL) {
+            ip = (int *)ptr;
+            if (*ip == 0) {
+                ibs = (int)num;
+                obs = ctx->obuf_size;
+            } else {            /* if (*ip == 1) */
+
+                ibs = ctx->ibuf_size;
+                obs = (int)num;
+            }
+        } else {
+            ibs = (int)num;
+            obs = (int)num;
+        }
+        p1 = ctx->ibuf;
+        p2 = ctx->obuf;
+        if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size)) {
+            p1 = OPENSSL_malloc((int)num);
+            if (p1 == NULL)
+                goto malloc_error;
+        }
+        if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size)) {
+            p2 = OPENSSL_malloc((int)num);
+            if (p2 == NULL) {
+                if (p1 != ctx->ibuf)
+                    OPENSSL_free(p1);
+                goto malloc_error;
+            }
+        }
+        if (ctx->ibuf != p1) {
+            OPENSSL_free(ctx->ibuf);
+            ctx->ibuf = p1;
+            ctx->ibuf_off = 0;
+            ctx->ibuf_len = 0;
+            ctx->ibuf_size = ibs;
+        }
+        if (ctx->obuf != p2) {
+            OPENSSL_free(ctx->obuf);
+            ctx->obuf = p2;
+            ctx->obuf_off = 0;
+            ctx->obuf_len = 0;
+            ctx->obuf_size = obs;
+        }
+        break;
+    case BIO_C_DO_STATE_MACHINE:
+        if (b->next_bio == NULL)
+            return (0);
+        BIO_clear_retry_flags(b);
+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+        BIO_copy_next_retry(b);
+        break;
+
+    case BIO_CTRL_FLUSH:
+        if (b->next_bio == NULL)
+            return (0);
+        if (ctx->obuf_len <= 0) {
+            ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+            break;
+        }
+
+        for (;;) {
+            BIO_clear_retry_flags(b);
+            if (ctx->obuf_len > 0) {
+                r = BIO_write(b->next_bio,
+                              &(ctx->obuf[ctx->obuf_off]), ctx->obuf_len);
+                BIO_copy_next_retry(b);
+                if (r <= 0)
+                    return ((long)r);
+                ctx->obuf_off += r;
+                ctx->obuf_len -= r;
+            } else {
+                ctx->obuf_len = 0;
+                ctx->obuf_off = 0;
+                break;
+            }
+        }
+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+        break;
+    case BIO_CTRL_DUP:
+        dbio = (BIO *)ptr;
+        if (!BIO_set_read_buffer_size(dbio, ctx->ibuf_size) ||
+            !BIO_set_write_buffer_size(dbio, ctx->obuf_size))
+            ret = 0;
+        break;
+    default:
+        if (b->next_bio == NULL)
+            return (0);
+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+        break;
+    }
+    return (ret);
+ malloc_error:
+    BIOerr(BIO_F_BUFFER_CTRL, ERR_R_MALLOC_FAILURE);
+    return (0);
+}
+
+static long buffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+    long ret = 1;
+
+    if (b->next_bio == NULL)
+        return (0);
+    switch (cmd) {
+    default:
+        ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+        break;
+    }
+    return (ret);
+}
+
+static int buffer_gets(BIO *b, char *buf, int size)
+{
+    BIO_F_BUFFER_CTX *ctx;
+    int num = 0, i, flag;
+    char *p;
+
+    ctx = (BIO_F_BUFFER_CTX *)b->ptr;
+    size--;                     /* reserve space for a '\0' */
+    BIO_clear_retry_flags(b);
+
+    for (;;) {
+        if (ctx->ibuf_len > 0) {
+            p = &(ctx->ibuf[ctx->ibuf_off]);
+            flag = 0;
+            for (i = 0; (i < ctx->ibuf_len) && (i < size); i++) {
+                *(buf++) = p[i];
+                if (p[i] == '\n') {
+                    flag = 1;
+                    i++;
+                    break;
+                }
+            }
+            num += i;
+            size -= i;
+            ctx->ibuf_len -= i;
+            ctx->ibuf_off += i;
+            if (flag || size == 0) {
+                *buf = '\0';
+                return (num);
+            }
+        } else {                /* read another chunk */
+
+            i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size);
+            if (i <= 0) {
+                BIO_copy_next_retry(b);
+                *buf = '\0';
+                if (i < 0)
+                    return ((num > 0) ? num : i);
+                if (i == 0)
+                    return (num);
+            }
+            ctx->ibuf_len = i;
+            ctx->ibuf_off = 0;
+        }
+    }
+}
+
+static int buffer_puts(BIO *b, const char *str)
+{
+    return (buffer_write(b, str, strlen(str)));
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bf_lbuf.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bf_lbuf.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bf_lbuf.c	(revision 331)
@@ -0,0 +1,319 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <errno.h>
+#include "bio_lcl.h"
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+
+static int linebuffer_write(BIO *h, const char *buf, int num);
+static int linebuffer_read(BIO *h, char *buf, int size);
+static int linebuffer_puts(BIO *h, const char *str);
+static int linebuffer_gets(BIO *h, char *str, int size);
+static long linebuffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int linebuffer_new(BIO *h);
+static int linebuffer_free(BIO *data);
+static long linebuffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+
+/* A 10k maximum should be enough for most purposes */
+#define DEFAULT_LINEBUFFER_SIZE 1024*10
+
+/* #define DEBUG */
+
+static const BIO_METHOD methods_linebuffer = {
+    BIO_TYPE_LINEBUFFER,
+    "linebuffer",
+    linebuffer_write,
+    linebuffer_read,
+    linebuffer_puts,
+    linebuffer_gets,
+    linebuffer_ctrl,
+    linebuffer_new,
+    linebuffer_free,
+    linebuffer_callback_ctrl,
+};
+
+const BIO_METHOD *BIO_f_linebuffer(void)
+{
+    return (&methods_linebuffer);
+}
+
+typedef struct bio_linebuffer_ctx_struct {
+    char *obuf;                 /* the output char array */
+    int obuf_size;              /* how big is the output buffer */
+    int obuf_len;               /* how many bytes are in it */
+} BIO_LINEBUFFER_CTX;
+
+static int linebuffer_new(BIO *bi)
+{
+    BIO_LINEBUFFER_CTX *ctx;
+
+    ctx = OPENSSL_malloc(sizeof(*ctx));
+    if (ctx == NULL)
+        return (0);
+    ctx->obuf = OPENSSL_malloc(DEFAULT_LINEBUFFER_SIZE);
+    if (ctx->obuf == NULL) {
+        OPENSSL_free(ctx);
+        return (0);
+    }
+    ctx->obuf_size = DEFAULT_LINEBUFFER_SIZE;
+    ctx->obuf_len = 0;
+
+    bi->init = 1;
+    bi->ptr = (char *)ctx;
+    bi->flags = 0;
+    return (1);
+}
+
+static int linebuffer_free(BIO *a)
+{
+    BIO_LINEBUFFER_CTX *b;
+
+    if (a == NULL)
+        return (0);
+    b = (BIO_LINEBUFFER_CTX *)a->ptr;
+    OPENSSL_free(b->obuf);
+    OPENSSL_free(a->ptr);
+    a->ptr = NULL;
+    a->init = 0;
+    a->flags = 0;
+    return (1);
+}
+
+static int linebuffer_read(BIO *b, char *out, int outl)
+{
+    int ret = 0;
+
+    if (out == NULL)
+        return (0);
+    if (b->next_bio == NULL)
+        return (0);
+    ret = BIO_read(b->next_bio, out, outl);
+    BIO_clear_retry_flags(b);
+    BIO_copy_next_retry(b);
+    return (ret);
+}
+
+static int linebuffer_write(BIO *b, const char *in, int inl)
+{
+    int i, num = 0, foundnl;
+    BIO_LINEBUFFER_CTX *ctx;
+
+    if ((in == NULL) || (inl <= 0))
+        return (0);
+    ctx = (BIO_LINEBUFFER_CTX *)b->ptr;
+    if ((ctx == NULL) || (b->next_bio == NULL))
+        return (0);
+
+    BIO_clear_retry_flags(b);
+
+    do {
+        const char *p;
+
+        for (p = in; p < in + inl && *p != '\n'; p++) ;
+        if (*p == '\n') {
+            p++;
+            foundnl = 1;
+        } else
+            foundnl = 0;
+
+        /*
+         * If a NL was found and we already have text in the save buffer,
+         * concatenate them and write
+         */
+        while ((foundnl || p - in > ctx->obuf_size - ctx->obuf_len)
+               && ctx->obuf_len > 0) {
+            int orig_olen = ctx->obuf_len;
+
+            i = ctx->obuf_size - ctx->obuf_len;
+            if (p - in > 0) {
+                if (i >= p - in) {
+                    memcpy(&(ctx->obuf[ctx->obuf_len]), in, p - in);
+                    ctx->obuf_len += p - in;
+                    inl -= p - in;
+                    num += p - in;
+                    in = p;
+                } else {
+                    memcpy(&(ctx->obuf[ctx->obuf_len]), in, i);
+                    ctx->obuf_len += i;
+                    inl -= i;
+                    in += i;
+                    num += i;
+                }
+            }
+            i = BIO_write(b->next_bio, ctx->obuf, ctx->obuf_len);
+            if (i <= 0) {
+                ctx->obuf_len = orig_olen;
+                BIO_copy_next_retry(b);
+
+                if (i < 0)
+                    return ((num > 0) ? num : i);
+                if (i == 0)
+                    return (num);
+            }
+            if (i < ctx->obuf_len)
+                memmove(ctx->obuf, ctx->obuf + i, ctx->obuf_len - i);
+            ctx->obuf_len -= i;
+        }
+
+        /*
+         * Now that the save buffer is emptied, let's write the input buffer
+         * if a NL was found and there is anything to write.
+         */
+        if ((foundnl || p - in > ctx->obuf_size) && p - in > 0) {
+            i = BIO_write(b->next_bio, in, p - in);
+            if (i <= 0) {
+                BIO_copy_next_retry(b);
+                if (i < 0)
+                    return ((num > 0) ? num : i);
+                if (i == 0)
+                    return (num);
+            }
+            num += i;
+            in += i;
+            inl -= i;
+        }
+    }
+    while (foundnl && inl > 0);
+    /*
+     * We've written as much as we can.  The rest of the input buffer, if
+     * any, is text that doesn't and with a NL and therefore needs to be
+     * saved for the next trip.
+     */
+    if (inl > 0) {
+        memcpy(&(ctx->obuf[ctx->obuf_len]), in, inl);
+        ctx->obuf_len += inl;
+        num += inl;
+    }
+    return num;
+}
+
+static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    BIO *dbio;
+    BIO_LINEBUFFER_CTX *ctx;
+    long ret = 1;
+    char *p;
+    int r;
+    int obs;
+
+    ctx = (BIO_LINEBUFFER_CTX *)b->ptr;
+
+    switch (cmd) {
+    case BIO_CTRL_RESET:
+        ctx->obuf_len = 0;
+        if (b->next_bio == NULL)
+            return (0);
+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+        break;
+    case BIO_CTRL_INFO:
+        ret = (long)ctx->obuf_len;
+        break;
+    case BIO_CTRL_WPENDING:
+        ret = (long)ctx->obuf_len;
+        if (ret == 0) {
+            if (b->next_bio == NULL)
+                return (0);
+            ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+        }
+        break;
+    case BIO_C_SET_BUFF_SIZE:
+        obs = (int)num;
+        p = ctx->obuf;
+        if ((obs > DEFAULT_LINEBUFFER_SIZE) && (obs != ctx->obuf_size)) {
+            p = OPENSSL_malloc((int)num);
+            if (p == NULL)
+                goto malloc_error;
+        }
+        if (ctx->obuf != p) {
+            if (ctx->obuf_len > obs) {
+                ctx->obuf_len = obs;
+            }
+            memcpy(p, ctx->obuf, ctx->obuf_len);
+            OPENSSL_free(ctx->obuf);
+            ctx->obuf = p;
+            ctx->obuf_size = obs;
+        }
+        break;
+    case BIO_C_DO_STATE_MACHINE:
+        if (b->next_bio == NULL)
+            return (0);
+        BIO_clear_retry_flags(b);
+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+        BIO_copy_next_retry(b);
+        break;
+
+    case BIO_CTRL_FLUSH:
+        if (b->next_bio == NULL)
+            return (0);
+        if (ctx->obuf_len <= 0) {
+            ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+            break;
+        }
+
+        for (;;) {
+            BIO_clear_retry_flags(b);
+            if (ctx->obuf_len > 0) {
+                r = BIO_write(b->next_bio, ctx->obuf, ctx->obuf_len);
+                BIO_copy_next_retry(b);
+                if (r <= 0)
+                    return ((long)r);
+                if (r < ctx->obuf_len)
+                    memmove(ctx->obuf, ctx->obuf + r, ctx->obuf_len - r);
+                ctx->obuf_len -= r;
+            } else {
+                ctx->obuf_len = 0;
+                break;
+            }
+        }
+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+        break;
+    case BIO_CTRL_DUP:
+        dbio = (BIO *)ptr;
+        if (!BIO_set_write_buffer_size(dbio, ctx->obuf_size))
+            ret = 0;
+        break;
+    default:
+        if (b->next_bio == NULL)
+            return (0);
+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+        break;
+    }
+    return (ret);
+ malloc_error:
+    BIOerr(BIO_F_LINEBUFFER_CTRL, ERR_R_MALLOC_FAILURE);
+    return (0);
+}
+
+static long linebuffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+    long ret = 1;
+
+    if (b->next_bio == NULL)
+        return (0);
+    switch (cmd) {
+    default:
+        ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+        break;
+    }
+    return (ret);
+}
+
+static int linebuffer_gets(BIO *b, char *buf, int size)
+{
+    if (b->next_bio == NULL)
+        return (0);
+    return (BIO_gets(b->next_bio, buf, size));
+}
+
+static int linebuffer_puts(BIO *b, const char *str)
+{
+    return (linebuffer_write(b, str, strlen(str)));
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bf_nbio.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bf_nbio.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bf_nbio.c	(revision 331)
@@ -0,0 +1,194 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <errno.h>
+#include "bio_lcl.h"
+#include "internal/cryptlib.h"
+#include <openssl/rand.h>
+
+/*
+ * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest
+ */
+
+static int nbiof_write(BIO *h, const char *buf, int num);
+static int nbiof_read(BIO *h, char *buf, int size);
+static int nbiof_puts(BIO *h, const char *str);
+static int nbiof_gets(BIO *h, char *str, int size);
+static long nbiof_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int nbiof_new(BIO *h);
+static int nbiof_free(BIO *data);
+static long nbiof_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+typedef struct nbio_test_st {
+    /* only set if we sent a 'should retry' error */
+    int lrn;
+    int lwn;
+} NBIO_TEST;
+
+static const BIO_METHOD methods_nbiof = {
+    BIO_TYPE_NBIO_TEST,
+    "non-blocking IO test filter",
+    nbiof_write,
+    nbiof_read,
+    nbiof_puts,
+    nbiof_gets,
+    nbiof_ctrl,
+    nbiof_new,
+    nbiof_free,
+    nbiof_callback_ctrl,
+};
+
+const BIO_METHOD *BIO_f_nbio_test(void)
+{
+    return (&methods_nbiof);
+}
+
+static int nbiof_new(BIO *bi)
+{
+    NBIO_TEST *nt;
+
+    if ((nt = OPENSSL_zalloc(sizeof(*nt))) == NULL)
+        return (0);
+    nt->lrn = -1;
+    nt->lwn = -1;
+    bi->ptr = (char *)nt;
+    bi->init = 1;
+    return (1);
+}
+
+static int nbiof_free(BIO *a)
+{
+    if (a == NULL)
+        return (0);
+    OPENSSL_free(a->ptr);
+    a->ptr = NULL;
+    a->init = 0;
+    a->flags = 0;
+    return (1);
+}
+
+static int nbiof_read(BIO *b, char *out, int outl)
+{
+    int ret = 0;
+    int num;
+    unsigned char n;
+
+    if (out == NULL)
+        return (0);
+    if (b->next_bio == NULL)
+        return (0);
+
+    BIO_clear_retry_flags(b);
+    if (RAND_bytes(&n, 1) <= 0)
+        return -1;
+    num = (n & 0x07);
+
+    if (outl > num)
+        outl = num;
+
+    if (num == 0) {
+        ret = -1;
+        BIO_set_retry_read(b);
+    } else {
+        ret = BIO_read(b->next_bio, out, outl);
+        if (ret < 0)
+            BIO_copy_next_retry(b);
+    }
+    return (ret);
+}
+
+static int nbiof_write(BIO *b, const char *in, int inl)
+{
+    NBIO_TEST *nt;
+    int ret = 0;
+    int num;
+    unsigned char n;
+
+    if ((in == NULL) || (inl <= 0))
+        return (0);
+    if (b->next_bio == NULL)
+        return (0);
+    nt = (NBIO_TEST *)b->ptr;
+
+    BIO_clear_retry_flags(b);
+
+    if (nt->lwn > 0) {
+        num = nt->lwn;
+        nt->lwn = 0;
+    } else {
+        if (RAND_bytes(&n, 1) <= 0)
+            return -1;
+        num = (n & 7);
+    }
+
+    if (inl > num)
+        inl = num;
+
+    if (num == 0) {
+        ret = -1;
+        BIO_set_retry_write(b);
+    } else {
+        ret = BIO_write(b->next_bio, in, inl);
+        if (ret < 0) {
+            BIO_copy_next_retry(b);
+            nt->lwn = inl;
+        }
+    }
+    return (ret);
+}
+
+static long nbiof_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    long ret;
+
+    if (b->next_bio == NULL)
+        return (0);
+    switch (cmd) {
+    case BIO_C_DO_STATE_MACHINE:
+        BIO_clear_retry_flags(b);
+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+        BIO_copy_next_retry(b);
+        break;
+    case BIO_CTRL_DUP:
+        ret = 0L;
+        break;
+    default:
+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+        break;
+    }
+    return (ret);
+}
+
+static long nbiof_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+    long ret = 1;
+
+    if (b->next_bio == NULL)
+        return (0);
+    switch (cmd) {
+    default:
+        ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+        break;
+    }
+    return (ret);
+}
+
+static int nbiof_gets(BIO *bp, char *buf, int size)
+{
+    if (bp->next_bio == NULL)
+        return (0);
+    return (BIO_gets(bp->next_bio, buf, size));
+}
+
+static int nbiof_puts(BIO *bp, const char *str)
+{
+    if (bp->next_bio == NULL)
+        return (0);
+    return (BIO_puts(bp->next_bio, str));
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bf_null.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bf_null.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bf_null.c	(revision 331)
@@ -0,0 +1,140 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <errno.h>
+#include "bio_lcl.h"
+#include "internal/cryptlib.h"
+
+/*
+ * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest
+ */
+
+static int nullf_write(BIO *h, const char *buf, int num);
+static int nullf_read(BIO *h, char *buf, int size);
+static int nullf_puts(BIO *h, const char *str);
+static int nullf_gets(BIO *h, char *str, int size);
+static long nullf_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int nullf_new(BIO *h);
+static int nullf_free(BIO *data);
+static long nullf_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+static const BIO_METHOD methods_nullf = {
+    BIO_TYPE_NULL_FILTER,
+    "NULL filter",
+    nullf_write,
+    nullf_read,
+    nullf_puts,
+    nullf_gets,
+    nullf_ctrl,
+    nullf_new,
+    nullf_free,
+    nullf_callback_ctrl,
+};
+
+const BIO_METHOD *BIO_f_null(void)
+{
+    return (&methods_nullf);
+}
+
+static int nullf_new(BIO *bi)
+{
+    bi->init = 1;
+    bi->ptr = NULL;
+    bi->flags = 0;
+    return (1);
+}
+
+static int nullf_free(BIO *a)
+{
+    if (a == NULL)
+        return (0);
+    /*-
+    a->ptr=NULL;
+    a->init=0;
+    a->flags=0;
+    */
+    return (1);
+}
+
+static int nullf_read(BIO *b, char *out, int outl)
+{
+    int ret = 0;
+
+    if (out == NULL)
+        return (0);
+    if (b->next_bio == NULL)
+        return (0);
+    ret = BIO_read(b->next_bio, out, outl);
+    BIO_clear_retry_flags(b);
+    BIO_copy_next_retry(b);
+    return (ret);
+}
+
+static int nullf_write(BIO *b, const char *in, int inl)
+{
+    int ret = 0;
+
+    if ((in == NULL) || (inl <= 0))
+        return (0);
+    if (b->next_bio == NULL)
+        return (0);
+    ret = BIO_write(b->next_bio, in, inl);
+    BIO_clear_retry_flags(b);
+    BIO_copy_next_retry(b);
+    return (ret);
+}
+
+static long nullf_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    long ret;
+
+    if (b->next_bio == NULL)
+        return (0);
+    switch (cmd) {
+    case BIO_C_DO_STATE_MACHINE:
+        BIO_clear_retry_flags(b);
+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+        BIO_copy_next_retry(b);
+        break;
+    case BIO_CTRL_DUP:
+        ret = 0L;
+        break;
+    default:
+        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+    }
+    return (ret);
+}
+
+static long nullf_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+    long ret = 1;
+
+    if (b->next_bio == NULL)
+        return (0);
+    switch (cmd) {
+    default:
+        ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+        break;
+    }
+    return (ret);
+}
+
+static int nullf_gets(BIO *bp, char *buf, int size)
+{
+    if (bp->next_bio == NULL)
+        return (0);
+    return (BIO_gets(bp->next_bio, buf, size));
+}
+
+static int nullf_puts(BIO *bp, const char *str)
+{
+    if (bp->next_bio == NULL)
+        return (0);
+    return (BIO_puts(bp->next_bio, str));
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bio_cb.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bio_cb.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bio_cb.c	(revision 331)
@@ -0,0 +1,99 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "bio_lcl.h"
+#include "internal/cryptlib.h"
+#include <openssl/err.h>
+
+long BIO_debug_callback(BIO *bio, int cmd, const char *argp,
+                        int argi, long argl, long ret)
+{
+    BIO *b;
+    char buf[256];
+    char *p;
+    long r = 1;
+    int len;
+    size_t p_maxlen;
+
+    if (BIO_CB_RETURN & cmd)
+        r = ret;
+
+    len = BIO_snprintf(buf, sizeof buf, "BIO[%p]: ", (void *)bio);
+
+    /* Ignore errors and continue printing the other information. */
+    if (len < 0)
+        len = 0;
+    p = buf + len;
+    p_maxlen = sizeof(buf) - len;
+
+    switch (cmd) {
+    case BIO_CB_FREE:
+        BIO_snprintf(p, p_maxlen, "Free - %s\n", bio->method->name);
+        break;
+    case BIO_CB_READ:
+        if (bio->method->type & BIO_TYPE_DESCRIPTOR)
+            BIO_snprintf(p, p_maxlen, "read(%d,%lu) - %s fd=%d\n",
+                         bio->num, (unsigned long)argi,
+                         bio->method->name, bio->num);
+        else
+            BIO_snprintf(p, p_maxlen, "read(%d,%lu) - %s\n",
+                         bio->num, (unsigned long)argi, bio->method->name);
+        break;
+    case BIO_CB_WRITE:
+        if (bio->method->type & BIO_TYPE_DESCRIPTOR)
+            BIO_snprintf(p, p_maxlen, "write(%d,%lu) - %s fd=%d\n",
+                         bio->num, (unsigned long)argi,
+                         bio->method->name, bio->num);
+        else
+            BIO_snprintf(p, p_maxlen, "write(%d,%lu) - %s\n",
+                         bio->num, (unsigned long)argi, bio->method->name);
+        break;
+    case BIO_CB_PUTS:
+        BIO_snprintf(p, p_maxlen, "puts() - %s\n", bio->method->name);
+        break;
+    case BIO_CB_GETS:
+        BIO_snprintf(p, p_maxlen, "gets(%lu) - %s\n", (unsigned long)argi,
+                     bio->method->name);
+        break;
+    case BIO_CB_CTRL:
+        BIO_snprintf(p, p_maxlen, "ctrl(%lu) - %s\n", (unsigned long)argi,
+                     bio->method->name);
+        break;
+    case BIO_CB_RETURN | BIO_CB_READ:
+        BIO_snprintf(p, p_maxlen, "read return %ld\n", ret);
+        break;
+    case BIO_CB_RETURN | BIO_CB_WRITE:
+        BIO_snprintf(p, p_maxlen, "write return %ld\n", ret);
+        break;
+    case BIO_CB_RETURN | BIO_CB_GETS:
+        BIO_snprintf(p, p_maxlen, "gets return %ld\n", ret);
+        break;
+    case BIO_CB_RETURN | BIO_CB_PUTS:
+        BIO_snprintf(p, p_maxlen, "puts return %ld\n", ret);
+        break;
+    case BIO_CB_RETURN | BIO_CB_CTRL:
+        BIO_snprintf(p, p_maxlen, "ctrl return %ld\n", ret);
+        break;
+    default:
+        BIO_snprintf(p, p_maxlen, "bio callback - unknown type (%d)\n", cmd);
+        break;
+    }
+
+    b = (BIO *)bio->cb_arg;
+    if (b != NULL)
+        BIO_write(b, buf, strlen(buf));
+#if !defined(OPENSSL_NO_STDIO)
+    else
+        fputs(buf, stderr);
+#endif
+    return (r);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bio_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bio_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bio_err.c	(revision 331)
@@ -0,0 +1,125 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/bio.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_BIO,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_BIO,0,reason)
+
+static ERR_STRING_DATA BIO_str_functs[] = {
+    {ERR_FUNC(BIO_F_ACPT_STATE), "acpt_state"},
+    {ERR_FUNC(BIO_F_ADDR_STRINGS), "addr_strings"},
+    {ERR_FUNC(BIO_F_BIO_ACCEPT), "BIO_accept"},
+    {ERR_FUNC(BIO_F_BIO_ACCEPT_EX), "BIO_accept_ex"},
+    {ERR_FUNC(BIO_F_BIO_ADDR_NEW), "BIO_ADDR_new"},
+    {ERR_FUNC(BIO_F_BIO_CALLBACK_CTRL), "BIO_callback_ctrl"},
+    {ERR_FUNC(BIO_F_BIO_CONNECT), "BIO_connect"},
+    {ERR_FUNC(BIO_F_BIO_CTRL), "BIO_ctrl"},
+    {ERR_FUNC(BIO_F_BIO_GETS), "BIO_gets"},
+    {ERR_FUNC(BIO_F_BIO_GET_HOST_IP), "BIO_get_host_ip"},
+    {ERR_FUNC(BIO_F_BIO_GET_NEW_INDEX), "BIO_get_new_index"},
+    {ERR_FUNC(BIO_F_BIO_GET_PORT), "BIO_get_port"},
+    {ERR_FUNC(BIO_F_BIO_LISTEN), "BIO_listen"},
+    {ERR_FUNC(BIO_F_BIO_LOOKUP), "BIO_lookup"},
+    {ERR_FUNC(BIO_F_BIO_MAKE_PAIR), "bio_make_pair"},
+    {ERR_FUNC(BIO_F_BIO_NEW), "BIO_new"},
+    {ERR_FUNC(BIO_F_BIO_NEW_FILE), "BIO_new_file"},
+    {ERR_FUNC(BIO_F_BIO_NEW_MEM_BUF), "BIO_new_mem_buf"},
+    {ERR_FUNC(BIO_F_BIO_NREAD), "BIO_nread"},
+    {ERR_FUNC(BIO_F_BIO_NREAD0), "BIO_nread0"},
+    {ERR_FUNC(BIO_F_BIO_NWRITE), "BIO_nwrite"},
+    {ERR_FUNC(BIO_F_BIO_NWRITE0), "BIO_nwrite0"},
+    {ERR_FUNC(BIO_F_BIO_PARSE_HOSTSERV), "BIO_parse_hostserv"},
+    {ERR_FUNC(BIO_F_BIO_PUTS), "BIO_puts"},
+    {ERR_FUNC(BIO_F_BIO_READ), "BIO_read"},
+    {ERR_FUNC(BIO_F_BIO_SOCKET), "BIO_socket"},
+    {ERR_FUNC(BIO_F_BIO_SOCKET_NBIO), "BIO_socket_nbio"},
+    {ERR_FUNC(BIO_F_BIO_SOCK_INFO), "BIO_sock_info"},
+    {ERR_FUNC(BIO_F_BIO_SOCK_INIT), "BIO_sock_init"},
+    {ERR_FUNC(BIO_F_BIO_WRITE), "BIO_write"},
+    {ERR_FUNC(BIO_F_BUFFER_CTRL), "buffer_ctrl"},
+    {ERR_FUNC(BIO_F_CONN_CTRL), "conn_ctrl"},
+    {ERR_FUNC(BIO_F_CONN_STATE), "conn_state"},
+    {ERR_FUNC(BIO_F_DGRAM_SCTP_READ), "dgram_sctp_read"},
+    {ERR_FUNC(BIO_F_DGRAM_SCTP_WRITE), "dgram_sctp_write"},
+    {ERR_FUNC(BIO_F_FILE_CTRL), "file_ctrl"},
+    {ERR_FUNC(BIO_F_FILE_READ), "file_read"},
+    {ERR_FUNC(BIO_F_LINEBUFFER_CTRL), "linebuffer_ctrl"},
+    {ERR_FUNC(BIO_F_MEM_WRITE), "mem_write"},
+    {ERR_FUNC(BIO_F_SSL_NEW), "SSL_new"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA BIO_str_reasons[] = {
+    {ERR_REASON(BIO_R_ACCEPT_ERROR), "accept error"},
+    {ERR_REASON(BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET),
+     "addrinfo addr is not af inet"},
+    {ERR_REASON(BIO_R_AMBIGUOUS_HOST_OR_SERVICE),
+     "ambiguous host or service"},
+    {ERR_REASON(BIO_R_BAD_FOPEN_MODE), "bad fopen mode"},
+    {ERR_REASON(BIO_R_BROKEN_PIPE), "broken pipe"},
+    {ERR_REASON(BIO_R_CONNECT_ERROR), "connect error"},
+    {ERR_REASON(BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET),
+     "gethostbyname addr is not af inet"},
+    {ERR_REASON(BIO_R_GETSOCKNAME_ERROR), "getsockname error"},
+    {ERR_REASON(BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS),
+     "getsockname truncated address"},
+    {ERR_REASON(BIO_R_GETTING_SOCKTYPE), "getting socktype"},
+    {ERR_REASON(BIO_R_INVALID_ARGUMENT), "invalid argument"},
+    {ERR_REASON(BIO_R_INVALID_SOCKET), "invalid socket"},
+    {ERR_REASON(BIO_R_IN_USE), "in use"},
+    {ERR_REASON(BIO_R_LISTEN_V6_ONLY), "listen v6 only"},
+    {ERR_REASON(BIO_R_LOOKUP_RETURNED_NOTHING), "lookup returned nothing"},
+    {ERR_REASON(BIO_R_MALFORMED_HOST_OR_SERVICE),
+     "malformed host or service"},
+    {ERR_REASON(BIO_R_NBIO_CONNECT_ERROR), "nbio connect error"},
+    {ERR_REASON(BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED),
+     "no accept addr or service specified"},
+    {ERR_REASON(BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED),
+     "no hostname or service specified"},
+    {ERR_REASON(BIO_R_NO_PORT_DEFINED), "no port defined"},
+    {ERR_REASON(BIO_R_NO_SUCH_FILE), "no such file"},
+    {ERR_REASON(BIO_R_NULL_PARAMETER), "null parameter"},
+    {ERR_REASON(BIO_R_UNABLE_TO_BIND_SOCKET), "unable to bind socket"},
+    {ERR_REASON(BIO_R_UNABLE_TO_CREATE_SOCKET), "unable to create socket"},
+    {ERR_REASON(BIO_R_UNABLE_TO_KEEPALIVE), "unable to keepalive"},
+    {ERR_REASON(BIO_R_UNABLE_TO_LISTEN_SOCKET), "unable to listen socket"},
+    {ERR_REASON(BIO_R_UNABLE_TO_NODELAY), "unable to nodelay"},
+    {ERR_REASON(BIO_R_UNABLE_TO_REUSEADDR), "unable to reuseaddr"},
+    {ERR_REASON(BIO_R_UNAVAILABLE_IP_FAMILY), "unavailable ip family"},
+    {ERR_REASON(BIO_R_UNINITIALIZED), "uninitialized"},
+    {ERR_REASON(BIO_R_UNKNOWN_INFO_TYPE), "unknown info type"},
+    {ERR_REASON(BIO_R_UNSUPPORTED_IP_FAMILY), "unsupported ip family"},
+    {ERR_REASON(BIO_R_UNSUPPORTED_METHOD), "unsupported method"},
+    {ERR_REASON(BIO_R_UNSUPPORTED_PROTOCOL_FAMILY),
+     "unsupported protocol family"},
+    {ERR_REASON(BIO_R_WRITE_TO_READ_ONLY_BIO), "write to read only BIO"},
+    {ERR_REASON(BIO_R_WSASTARTUP), "WSAStartup"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_BIO_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(BIO_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, BIO_str_functs);
+        ERR_load_strings(0, BIO_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bio_lcl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bio_lcl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bio_lcl.h	(revision 331)
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2005-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
+ */
+
+#define USE_SOCKETS
+#include "e_os.h"
+
+/* BEGIN BIO_ADDRINFO/BIO_ADDR stuff. */
+
+#ifndef OPENSSL_NO_SOCK
+/*
+ * Throughout this file and b_addr.c, the existence of the macro
+ * AI_PASSIVE is used to detect the availability of struct addrinfo,
+ * getnameinfo() and getaddrinfo().  If that macro doesn't exist,
+ * we use our own implementation instead.
+ */
+
+/*
+ * It's imperative that these macros get defined before openssl/bio.h gets
+ * included.  Otherwise, the AI_PASSIVE hack will not work properly.
+ * For clarity, we check for internal/cryptlib.h since it's a common header
+ * that also includes bio.h.
+ */
+# ifdef HEADER_CRYPTLIB_H
+#  error internal/cryptlib.h included before bio_lcl.h
+# endif
+# ifdef HEADER_BIO_H
+#  error openssl/bio.h included before bio_lcl.h
+# endif
+
+/*
+ * Undefine AF_UNIX on systems that define it but don't support it.
+ */
+# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_VMS)
+#  undef AF_UNIX
+# endif
+
+# ifdef AI_PASSIVE
+
+/*
+ * There's a bug in VMS C header file netdb.h, where struct addrinfo
+ * always is the P32 variant, but the functions that handle that structure,
+ * such as getaddrinfo() and freeaddrinfo() adapt to the initial pointer
+ * size.  The easiest workaround is to force struct addrinfo to be the
+ * 64-bit variant when compiling in P64 mode.
+ */
+#  if defined(OPENSSL_SYS_VMS) && __INITIAL_POINTER_SIZE == 64
+#   define addrinfo __addrinfo64
+#  endif
+
+#  define bio_addrinfo_st addrinfo
+#  define bai_family      ai_family
+#  define bai_socktype    ai_socktype
+#  define bai_protocol    ai_protocol
+#  define bai_addrlen     ai_addrlen
+#  define bai_addr        ai_addr
+#  define bai_next        ai_next
+# else
+struct bio_addrinfo_st {
+    int bai_family;
+    int bai_socktype;
+    int bai_protocol;
+    size_t bai_addrlen;
+    struct sockaddr *bai_addr;
+    struct bio_addrinfo_st *bai_next;
+};
+# endif
+
+union bio_addr_st {
+    struct sockaddr sa;
+# ifdef AF_INET6
+    struct sockaddr_in6 s_in6;
+# endif
+    struct sockaddr_in s_in;
+# ifdef AF_UNIX
+    struct sockaddr_un s_un;
+# endif
+};
+#endif
+
+/* END BIO_ADDRINFO/BIO_ADDR stuff. */
+
+#include "internal/cryptlib.h"
+#include <internal/bio.h>
+
+typedef struct bio_f_buffer_ctx_struct {
+    /*-
+     * Buffers are setup like this:
+     *
+     * <---------------------- size ----------------------->
+     * +---------------------------------------------------+
+     * | consumed | remaining          | free space        |
+     * +---------------------------------------------------+
+     * <-- off --><------- len ------->
+     */
+    /*- BIO *bio; *//*
+     * this is now in the BIO struct
+     */
+    int ibuf_size;              /* how big is the input buffer */
+    int obuf_size;              /* how big is the output buffer */
+    char *ibuf;                 /* the char array */
+    int ibuf_len;               /* how many bytes are in it */
+    int ibuf_off;               /* write/read offset */
+    char *obuf;                 /* the char array */
+    int obuf_len;               /* how many bytes are in it */
+    int obuf_off;               /* write/read offset */
+} BIO_F_BUFFER_CTX;
+
+struct bio_st {
+    const BIO_METHOD *method;
+    /* bio, mode, argp, argi, argl, ret */
+    long (*callback) (struct bio_st *, int, const char *, int, long, long);
+    char *cb_arg;               /* first argument for the callback */
+    int init;
+    int shutdown;
+    int flags;                  /* extra storage */
+    int retry_reason;
+    int num;
+    void *ptr;
+    struct bio_st *next_bio;    /* used by filter BIOs */
+    struct bio_st *prev_bio;    /* used by filter BIOs */
+    int references;
+    uint64_t num_read;
+    uint64_t num_write;
+    CRYPTO_EX_DATA ex_data;
+    CRYPTO_RWLOCK *lock;
+};
+
+#ifndef OPENSSL_NO_SOCK
+# ifdef OPENSSL_SYS_VMS
+typedef unsigned int socklen_t;
+# endif
+
+extern CRYPTO_RWLOCK *bio_lookup_lock;
+
+int BIO_ADDR_make(BIO_ADDR *ap, const struct sockaddr *sa);
+const struct sockaddr *BIO_ADDR_sockaddr(const BIO_ADDR *ap);
+struct sockaddr *BIO_ADDR_sockaddr_noconst(BIO_ADDR *ap);
+socklen_t BIO_ADDR_sockaddr_size(const BIO_ADDR *ap);
+socklen_t BIO_ADDRINFO_sockaddr_size(const BIO_ADDRINFO *bai);
+const struct sockaddr *BIO_ADDRINFO_sockaddr(const BIO_ADDRINFO *bai);
+#endif
+
+extern CRYPTO_RWLOCK *bio_type_lock;
+
+void bio_sock_cleanup_int(void);
+
+#if BIO_FLAGS_UPLINK==0
+/* Shortcut UPLINK calls on most platforms... */
+# define UP_stdin        stdin
+# define UP_stdout       stdout
+# define UP_stderr       stderr
+# define UP_fprintf      fprintf
+# define UP_fgets        fgets
+# define UP_fread        fread
+# define UP_fwrite       fwrite
+# undef  UP_fsetmod
+# define UP_feof         feof
+# define UP_fclose       fclose
+
+# define UP_fopen        fopen
+# define UP_fseek        fseek
+# define UP_ftell        ftell
+# define UP_fflush       fflush
+# define UP_ferror       ferror
+# ifdef _WIN32
+#  define UP_fileno       _fileno
+#  define UP_open         _open
+#  define UP_read         _read
+#  define UP_write        _write
+#  define UP_lseek        _lseek
+#  define UP_close        _close
+# else
+#  define UP_fileno       fileno
+#  define UP_open         open
+#  define UP_read         read
+#  define UP_write        write
+#  define UP_lseek        lseek
+#  define UP_close        close
+# endif
+
+#endif
+
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bio_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bio_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bio_lib.c	(revision 331)
@@ -0,0 +1,600 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <errno.h>
+#include <openssl/crypto.h>
+#include "bio_lcl.h"
+#include "internal/cryptlib.h"
+
+BIO *BIO_new(const BIO_METHOD *method)
+{
+    BIO *bio = OPENSSL_zalloc(sizeof(*bio));
+
+    if (bio == NULL) {
+        BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE);
+        return (NULL);
+    }
+
+    bio->method = method;
+    bio->shutdown = 1;
+    bio->references = 1;
+
+    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data))
+        goto err;
+
+    bio->lock = CRYPTO_THREAD_lock_new();
+    if (bio->lock == NULL) {
+        BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE);
+        CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
+        goto err;
+    }
+
+    if (method->create != NULL && !method->create(bio)) {
+        BIOerr(BIO_F_BIO_NEW, ERR_R_INIT_FAIL);
+        CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
+        CRYPTO_THREAD_lock_free(bio->lock);
+        goto err;
+    }
+
+    return bio;
+
+err:
+    OPENSSL_free(bio);
+    return NULL;
+}
+
+int BIO_free(BIO *a)
+{
+    int i;
+
+    if (a == NULL)
+        return 0;
+
+    if (CRYPTO_atomic_add(&a->references, -1, &i, a->lock) <= 0)
+        return 0;
+
+    REF_PRINT_COUNT("BIO", a);
+    if (i > 0)
+        return 1;
+    REF_ASSERT_ISNT(i < 0);
+    if ((a->callback != NULL) &&
+        ((i = (int)a->callback(a, BIO_CB_FREE, NULL, 0, 0L, 1L)) <= 0))
+        return i;
+
+    if ((a->method != NULL) && (a->method->destroy != NULL))
+        a->method->destroy(a);
+
+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
+
+    CRYPTO_THREAD_lock_free(a->lock);
+
+    OPENSSL_free(a);
+
+    return 1;
+}
+
+void BIO_set_data(BIO *a, void *ptr)
+{
+    a->ptr = ptr;
+}
+
+void *BIO_get_data(BIO *a)
+{
+    return a->ptr;
+}
+
+void BIO_set_init(BIO *a, int init)
+{
+    a->init = init;
+}
+
+int BIO_get_init(BIO *a)
+{
+    return a->init;
+}
+
+void BIO_set_shutdown(BIO *a, int shut)
+{
+    a->shutdown = shut;
+}
+
+int BIO_get_shutdown(BIO *a)
+{
+    return a->shutdown;
+}
+
+void BIO_vfree(BIO *a)
+{
+    BIO_free(a);
+}
+
+int BIO_up_ref(BIO *a)
+{
+    int i;
+
+    if (CRYPTO_atomic_add(&a->references, 1, &i, a->lock) <= 0)
+        return 0;
+
+    REF_PRINT_COUNT("BIO", a);
+    REF_ASSERT_ISNT(i < 2);
+    return ((i > 1) ? 1 : 0);
+}
+
+void BIO_clear_flags(BIO *b, int flags)
+{
+    b->flags &= ~flags;
+}
+
+int BIO_test_flags(const BIO *b, int flags)
+{
+    return (b->flags & flags);
+}
+
+void BIO_set_flags(BIO *b, int flags)
+{
+    b->flags |= flags;
+}
+
+long (*BIO_get_callback(const BIO *b)) (struct bio_st *, int, const char *,
+                                        int, long, long) {
+    return b->callback;
+}
+
+void BIO_set_callback(BIO *b,
+                      long (*cb) (struct bio_st *, int, const char *, int,
+                                  long, long))
+{
+    b->callback = cb;
+}
+
+void BIO_set_callback_arg(BIO *b, char *arg)
+{
+    b->cb_arg = arg;
+}
+
+char *BIO_get_callback_arg(const BIO *b)
+{
+    return b->cb_arg;
+}
+
+const char *BIO_method_name(const BIO *b)
+{
+    return b->method->name;
+}
+
+int BIO_method_type(const BIO *b)
+{
+    return b->method->type;
+}
+
+int BIO_read(BIO *b, void *out, int outl)
+{
+    int i;
+    long (*cb) (BIO *, int, const char *, int, long, long);
+
+    if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) {
+        BIOerr(BIO_F_BIO_READ, BIO_R_UNSUPPORTED_METHOD);
+        return (-2);
+    }
+
+    cb = b->callback;
+    if ((cb != NULL) &&
+        ((i = (int)cb(b, BIO_CB_READ, out, outl, 0L, 1L)) <= 0))
+        return (i);
+
+    if (!b->init) {
+        BIOerr(BIO_F_BIO_READ, BIO_R_UNINITIALIZED);
+        return (-2);
+    }
+
+    i = b->method->bread(b, out, outl);
+
+    if (i > 0)
+        b->num_read += (uint64_t)i;
+
+    if (cb != NULL)
+        i = (int)cb(b, BIO_CB_READ | BIO_CB_RETURN, out, outl, 0L, (long)i);
+    return (i);
+}
+
+int BIO_write(BIO *b, const void *in, int inl)
+{
+    int i;
+    long (*cb) (BIO *, int, const char *, int, long, long);
+
+    if (b == NULL)
+        return (0);
+
+    cb = b->callback;
+    if ((b->method == NULL) || (b->method->bwrite == NULL)) {
+        BIOerr(BIO_F_BIO_WRITE, BIO_R_UNSUPPORTED_METHOD);
+        return (-2);
+    }
+
+    if ((cb != NULL) &&
+        ((i = (int)cb(b, BIO_CB_WRITE, in, inl, 0L, 1L)) <= 0))
+        return (i);
+
+    if (!b->init) {
+        BIOerr(BIO_F_BIO_WRITE, BIO_R_UNINITIALIZED);
+        return (-2);
+    }
+
+    i = b->method->bwrite(b, in, inl);
+
+    if (i > 0)
+        b->num_write += (uint64_t)i;
+
+    if (cb != NULL)
+        i = (int)cb(b, BIO_CB_WRITE | BIO_CB_RETURN, in, inl, 0L, (long)i);
+    return (i);
+}
+
+int BIO_puts(BIO *b, const char *in)
+{
+    int i;
+    long (*cb) (BIO *, int, const char *, int, long, long);
+
+    if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) {
+        BIOerr(BIO_F_BIO_PUTS, BIO_R_UNSUPPORTED_METHOD);
+        return (-2);
+    }
+
+    cb = b->callback;
+
+    if ((cb != NULL) && ((i = (int)cb(b, BIO_CB_PUTS, in, 0, 0L, 1L)) <= 0))
+        return (i);
+
+    if (!b->init) {
+        BIOerr(BIO_F_BIO_PUTS, BIO_R_UNINITIALIZED);
+        return (-2);
+    }
+
+    i = b->method->bputs(b, in);
+
+    if (i > 0)
+        b->num_write += (uint64_t)i;
+
+    if (cb != NULL)
+        i = (int)cb(b, BIO_CB_PUTS | BIO_CB_RETURN, in, 0, 0L, (long)i);
+    return (i);
+}
+
+int BIO_gets(BIO *b, char *in, int inl)
+{
+    int i;
+    long (*cb) (BIO *, int, const char *, int, long, long);
+
+    if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) {
+        BIOerr(BIO_F_BIO_GETS, BIO_R_UNSUPPORTED_METHOD);
+        return (-2);
+    }
+
+    cb = b->callback;
+
+    if ((cb != NULL) && ((i = (int)cb(b, BIO_CB_GETS, in, inl, 0L, 1L)) <= 0))
+        return (i);
+
+    if (!b->init) {
+        BIOerr(BIO_F_BIO_GETS, BIO_R_UNINITIALIZED);
+        return (-2);
+    }
+
+    i = b->method->bgets(b, in, inl);
+
+    if (cb != NULL)
+        i = (int)cb(b, BIO_CB_GETS | BIO_CB_RETURN, in, inl, 0L, (long)i);
+    return (i);
+}
+
+int BIO_indent(BIO *b, int indent, int max)
+{
+    if (indent < 0)
+        indent = 0;
+    if (indent > max)
+        indent = max;
+    while (indent--)
+        if (BIO_puts(b, " ") != 1)
+            return 0;
+    return 1;
+}
+
+long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg)
+{
+    int i;
+
+    i = iarg;
+    return (BIO_ctrl(b, cmd, larg, (char *)&i));
+}
+
+void *BIO_ptr_ctrl(BIO *b, int cmd, long larg)
+{
+    void *p = NULL;
+
+    if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0)
+        return (NULL);
+    else
+        return (p);
+}
+
+long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
+{
+    long ret;
+    long (*cb) (BIO *, int, const char *, int, long, long);
+
+    if (b == NULL)
+        return (0);
+
+    if ((b->method == NULL) || (b->method->ctrl == NULL)) {
+        BIOerr(BIO_F_BIO_CTRL, BIO_R_UNSUPPORTED_METHOD);
+        return (-2);
+    }
+
+    cb = b->callback;
+
+    if ((cb != NULL) &&
+        ((ret = cb(b, BIO_CB_CTRL, parg, cmd, larg, 1L)) <= 0))
+        return (ret);
+
+    ret = b->method->ctrl(b, cmd, larg, parg);
+
+    if (cb != NULL)
+        ret = cb(b, BIO_CB_CTRL | BIO_CB_RETURN, parg, cmd, larg, ret);
+    return (ret);
+}
+
+long BIO_callback_ctrl(BIO *b, int cmd,
+                       void (*fp) (struct bio_st *, int, const char *, int,
+                                   long, long))
+{
+    long ret;
+    long (*cb) (BIO *, int, const char *, int, long, long);
+
+    if (b == NULL)
+        return (0);
+
+    if ((b->method == NULL) || (b->method->callback_ctrl == NULL)) {
+        BIOerr(BIO_F_BIO_CALLBACK_CTRL, BIO_R_UNSUPPORTED_METHOD);
+        return (-2);
+    }
+
+    cb = b->callback;
+
+    if ((cb != NULL) &&
+        ((ret = cb(b, BIO_CB_CTRL, (void *)&fp, cmd, 0, 1L)) <= 0))
+        return (ret);
+
+    ret = b->method->callback_ctrl(b, cmd, fp);
+
+    if (cb != NULL)
+        ret = cb(b, BIO_CB_CTRL | BIO_CB_RETURN, (void *)&fp, cmd, 0, ret);
+    return (ret);
+}
+
+/*
+ * It is unfortunate to duplicate in functions what the BIO_(w)pending macros
+ * do; but those macros have inappropriate return type, and for interfacing
+ * from other programming languages, C macros aren't much of a help anyway.
+ */
+size_t BIO_ctrl_pending(BIO *bio)
+{
+    return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL);
+}
+
+size_t BIO_ctrl_wpending(BIO *bio)
+{
+    return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL);
+}
+
+/* put the 'bio' on the end of b's list of operators */
+BIO *BIO_push(BIO *b, BIO *bio)
+{
+    BIO *lb;
+
+    if (b == NULL)
+        return (bio);
+    lb = b;
+    while (lb->next_bio != NULL)
+        lb = lb->next_bio;
+    lb->next_bio = bio;
+    if (bio != NULL)
+        bio->prev_bio = lb;
+    /* called to do internal processing */
+    BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb);
+    return (b);
+}
+
+/* Remove the first and return the rest */
+BIO *BIO_pop(BIO *b)
+{
+    BIO *ret;
+
+    if (b == NULL)
+        return (NULL);
+    ret = b->next_bio;
+
+    BIO_ctrl(b, BIO_CTRL_POP, 0, b);
+
+    if (b->prev_bio != NULL)
+        b->prev_bio->next_bio = b->next_bio;
+    if (b->next_bio != NULL)
+        b->next_bio->prev_bio = b->prev_bio;
+
+    b->next_bio = NULL;
+    b->prev_bio = NULL;
+    return (ret);
+}
+
+BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
+{
+    BIO *b, *last;
+
+    b = last = bio;
+    for (;;) {
+        if (!BIO_should_retry(b))
+            break;
+        last = b;
+        b = b->next_bio;
+        if (b == NULL)
+            break;
+    }
+    if (reason != NULL)
+        *reason = last->retry_reason;
+    return (last);
+}
+
+int BIO_get_retry_reason(BIO *bio)
+{
+    return (bio->retry_reason);
+}
+
+void BIO_set_retry_reason(BIO *bio, int reason)
+{
+    bio->retry_reason = reason;
+}
+
+BIO *BIO_find_type(BIO *bio, int type)
+{
+    int mt, mask;
+
+    if (bio == NULL)
+        return NULL;
+    mask = type & 0xff;
+    do {
+        if (bio->method != NULL) {
+            mt = bio->method->type;
+
+            if (!mask) {
+                if (mt & type)
+                    return (bio);
+            } else if (mt == type)
+                return (bio);
+        }
+        bio = bio->next_bio;
+    } while (bio != NULL);
+    return (NULL);
+}
+
+BIO *BIO_next(BIO *b)
+{
+    if (b == NULL)
+        return NULL;
+    return b->next_bio;
+}
+
+void BIO_set_next(BIO *b, BIO *next)
+{
+    b->next_bio = next;
+}
+
+void BIO_free_all(BIO *bio)
+{
+    BIO *b;
+    int ref;
+
+    while (bio != NULL) {
+        b = bio;
+        ref = b->references;
+        bio = bio->next_bio;
+        BIO_free(b);
+        /* Since ref count > 1, don't free anyone else. */
+        if (ref > 1)
+            break;
+    }
+}
+
+BIO *BIO_dup_chain(BIO *in)
+{
+    BIO *ret = NULL, *eoc = NULL, *bio, *new_bio;
+
+    for (bio = in; bio != NULL; bio = bio->next_bio) {
+        if ((new_bio = BIO_new(bio->method)) == NULL)
+            goto err;
+        new_bio->callback = bio->callback;
+        new_bio->cb_arg = bio->cb_arg;
+        new_bio->init = bio->init;
+        new_bio->shutdown = bio->shutdown;
+        new_bio->flags = bio->flags;
+
+        /* This will let SSL_s_sock() work with stdin/stdout */
+        new_bio->num = bio->num;
+
+        if (!BIO_dup_state(bio, (char *)new_bio)) {
+            BIO_free(new_bio);
+            goto err;
+        }
+
+        /* copy app data */
+        if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data,
+                                &bio->ex_data)) {
+            BIO_free(new_bio);
+            goto err;
+        }
+
+        if (ret == NULL) {
+            eoc = new_bio;
+            ret = eoc;
+        } else {
+            BIO_push(eoc, new_bio);
+            eoc = new_bio;
+        }
+    }
+    return (ret);
+ err:
+    BIO_free_all(ret);
+
+    return (NULL);
+}
+
+void BIO_copy_next_retry(BIO *b)
+{
+    BIO_set_flags(b, BIO_get_retry_flags(b->next_bio));
+    b->retry_reason = b->next_bio->retry_reason;
+}
+
+int BIO_set_ex_data(BIO *bio, int idx, void *data)
+{
+    return (CRYPTO_set_ex_data(&(bio->ex_data), idx, data));
+}
+
+void *BIO_get_ex_data(BIO *bio, int idx)
+{
+    return (CRYPTO_get_ex_data(&(bio->ex_data), idx));
+}
+
+uint64_t BIO_number_read(BIO *bio)
+{
+    if (bio)
+        return bio->num_read;
+    return 0;
+}
+
+uint64_t BIO_number_written(BIO *bio)
+{
+    if (bio)
+        return bio->num_write;
+    return 0;
+}
+
+void bio_free_ex_data(BIO *bio)
+{
+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
+}
+
+void bio_cleanup(void)
+{
+#ifndef OPENSSL_NO_SOCK
+    bio_sock_cleanup_int();
+    CRYPTO_THREAD_lock_free(bio_lookup_lock);
+    bio_lookup_lock = NULL;
+#endif
+    CRYPTO_THREAD_lock_free(bio_type_lock);
+    bio_type_lock = NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bio_meth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bio_meth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bio_meth.c	(revision 331)
@@ -0,0 +1,145 @@
+/*
+ * 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 "bio_lcl.h"
+#include <internal/thread_once.h>
+
+CRYPTO_RWLOCK *bio_type_lock = NULL;
+static CRYPTO_ONCE bio_type_init = CRYPTO_ONCE_STATIC_INIT;
+
+DEFINE_RUN_ONCE_STATIC(do_bio_type_init)
+{
+    bio_type_lock = CRYPTO_THREAD_lock_new();
+    return bio_type_lock != NULL;
+}
+
+int BIO_get_new_index()
+{
+    static int bio_count = BIO_TYPE_START;
+    int newval;
+
+    if (!RUN_ONCE(&bio_type_init, do_bio_type_init)) {
+        BIOerr(BIO_F_BIO_GET_NEW_INDEX, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+    if (!CRYPTO_atomic_add(&bio_count, 1, &newval, bio_type_lock))
+        return -1;
+    return newval;
+}
+
+BIO_METHOD *BIO_meth_new(int type, const char *name)
+{
+    BIO_METHOD *biom = OPENSSL_zalloc(sizeof(BIO_METHOD));
+
+    if (biom != NULL) {
+        biom->type = type;
+        biom->name = name;
+    }
+    return biom;
+}
+
+void BIO_meth_free(BIO_METHOD *biom)
+{
+    OPENSSL_free(biom);
+}
+
+int (*BIO_meth_get_write(BIO_METHOD *biom)) (BIO *, const char *, int)
+{
+    return biom->bwrite;
+}
+
+int BIO_meth_set_write(BIO_METHOD *biom,
+                       int (*bwrite) (BIO *, const char *, int))
+{
+    biom->bwrite = bwrite;
+    return 1;
+}
+
+int (*BIO_meth_get_read(BIO_METHOD *biom)) (BIO *, char *, int)
+{
+    return biom->bread;
+}
+
+int BIO_meth_set_read(BIO_METHOD *biom,
+                      int (*bread) (BIO *, char *, int))
+{
+    biom->bread = bread;
+    return 1;
+}
+
+int (*BIO_meth_get_puts(BIO_METHOD *biom)) (BIO *, const char *)
+{
+    return biom->bputs;
+}
+
+int BIO_meth_set_puts(BIO_METHOD *biom,
+                      int (*bputs) (BIO *, const char *))
+{
+    biom->bputs = bputs;
+    return 1;
+}
+
+int (*BIO_meth_get_gets(BIO_METHOD *biom)) (BIO *, char *, int)
+{
+    return biom->bgets;
+}
+
+int BIO_meth_set_gets(BIO_METHOD *biom,
+                      int (*bgets) (BIO *, char *, int))
+{
+    biom->bgets = bgets;
+    return 1;
+}
+
+long (*BIO_meth_get_ctrl(BIO_METHOD *biom)) (BIO *, int, long, void *)
+{
+    return biom->ctrl;
+}
+
+int BIO_meth_set_ctrl(BIO_METHOD *biom,
+                      long (*ctrl) (BIO *, int, long, void *))
+{
+    biom->ctrl = ctrl;
+    return 1;
+}
+
+int (*BIO_meth_get_create(BIO_METHOD *biom)) (BIO *)
+{
+    return biom->create;
+}
+
+int BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *))
+{
+    biom->create = create;
+    return 1;
+}
+
+int (*BIO_meth_get_destroy(BIO_METHOD *biom)) (BIO *)
+{
+    return biom->destroy;
+}
+
+int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *))
+{
+    biom->destroy = destroy;
+    return 1;
+}
+
+long (*BIO_meth_get_callback_ctrl(BIO_METHOD *biom)) (BIO *, int, bio_info_cb *)
+{
+    return biom->callback_ctrl;
+}
+
+int BIO_meth_set_callback_ctrl(BIO_METHOD *biom,
+                               long (*callback_ctrl) (BIO *, int,
+                                                      bio_info_cb *))
+{
+    biom->callback_ctrl = callback_ctrl;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_acpt.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_acpt.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_acpt.c	(revision 331)
@@ -0,0 +1,557 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <errno.h>
+#include "bio_lcl.h"
+
+#ifndef OPENSSL_NO_SOCK
+
+typedef struct bio_accept_st {
+    int state;
+    int accept_family;
+    int bind_mode;     /* Socket mode for BIO_listen */
+    int accepted_mode; /* Socket mode for BIO_accept (set on accepted sock) */
+    char *param_addr;
+    char *param_serv;
+
+    int accept_sock;
+
+    BIO_ADDRINFO *addr_first;
+    const BIO_ADDRINFO *addr_iter;
+    BIO_ADDR cache_accepting_addr;   /* Useful if we asked for port 0 */
+    char *cache_accepting_name, *cache_accepting_serv;
+    BIO_ADDR cache_peer_addr;
+    char *cache_peer_name, *cache_peer_serv;
+
+    BIO *bio_chain;
+} BIO_ACCEPT;
+
+static int acpt_write(BIO *h, const char *buf, int num);
+static int acpt_read(BIO *h, char *buf, int size);
+static int acpt_puts(BIO *h, const char *str);
+static long acpt_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int acpt_new(BIO *h);
+static int acpt_free(BIO *data);
+static int acpt_state(BIO *b, BIO_ACCEPT *c);
+static void acpt_close_socket(BIO *data);
+static BIO_ACCEPT *BIO_ACCEPT_new(void);
+static void BIO_ACCEPT_free(BIO_ACCEPT *a);
+
+# define ACPT_S_BEFORE                   1
+# define ACPT_S_GET_ADDR                 2
+# define ACPT_S_CREATE_SOCKET            3
+# define ACPT_S_LISTEN                   4
+# define ACPT_S_ACCEPT                   5
+# define ACPT_S_OK                       6
+
+static const BIO_METHOD methods_acceptp = {
+    BIO_TYPE_ACCEPT,
+    "socket accept",
+    acpt_write,
+    acpt_read,
+    acpt_puts,
+    NULL,                       /* connect_gets, */
+    acpt_ctrl,
+    acpt_new,
+    acpt_free,
+    NULL,
+};
+
+const BIO_METHOD *BIO_s_accept(void)
+{
+    return (&methods_acceptp);
+}
+
+static int acpt_new(BIO *bi)
+{
+    BIO_ACCEPT *ba;
+
+    bi->init = 0;
+    bi->num = (int)INVALID_SOCKET;
+    bi->flags = 0;
+    if ((ba = BIO_ACCEPT_new()) == NULL)
+        return (0);
+    bi->ptr = (char *)ba;
+    ba->state = ACPT_S_BEFORE;
+    bi->shutdown = 1;
+    return (1);
+}
+
+static BIO_ACCEPT *BIO_ACCEPT_new(void)
+{
+    BIO_ACCEPT *ret;
+
+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
+        return (NULL);
+    ret->accept_family = BIO_FAMILY_IPANY;
+    ret->accept_sock = (int)INVALID_SOCKET;
+    return (ret);
+}
+
+static void BIO_ACCEPT_free(BIO_ACCEPT *a)
+{
+    if (a == NULL)
+        return;
+
+    OPENSSL_free(a->param_addr);
+    OPENSSL_free(a->param_serv);
+    BIO_ADDRINFO_free(a->addr_first);
+    OPENSSL_free(a->cache_accepting_name);
+    OPENSSL_free(a->cache_accepting_serv);
+    OPENSSL_free(a->cache_peer_name);
+    OPENSSL_free(a->cache_peer_serv);
+    BIO_free(a->bio_chain);
+    OPENSSL_free(a);
+}
+
+static void acpt_close_socket(BIO *bio)
+{
+    BIO_ACCEPT *c;
+
+    c = (BIO_ACCEPT *)bio->ptr;
+    if (c->accept_sock != (int)INVALID_SOCKET) {
+        shutdown(c->accept_sock, 2);
+        closesocket(c->accept_sock);
+        c->accept_sock = (int)INVALID_SOCKET;
+        bio->num = (int)INVALID_SOCKET;
+    }
+}
+
+static int acpt_free(BIO *a)
+{
+    BIO_ACCEPT *data;
+
+    if (a == NULL)
+        return (0);
+    data = (BIO_ACCEPT *)a->ptr;
+
+    if (a->shutdown) {
+        acpt_close_socket(a);
+        BIO_ACCEPT_free(data);
+        a->ptr = NULL;
+        a->flags = 0;
+        a->init = 0;
+    }
+    return (1);
+}
+
+static int acpt_state(BIO *b, BIO_ACCEPT *c)
+{
+    BIO *bio = NULL, *dbio;
+    int s = -1, ret = -1;
+
+    for (;;) {
+        switch (c->state) {
+        case ACPT_S_BEFORE:
+            if (c->param_addr == NULL && c->param_serv == NULL) {
+                BIOerr(BIO_F_ACPT_STATE, BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED);
+                ERR_add_error_data(4,
+                                   "hostname=", c->param_addr,
+                                   " service=", c->param_serv);
+                goto exit_loop;
+            }
+
+            /* Because we're starting a new bind, any cached name and serv
+             * are now obsolete and need to be cleaned out.
+             * QUESTION: should this be done in acpt_close_socket() instead?
+             */
+            OPENSSL_free(c->cache_accepting_name);
+            c->cache_accepting_name = NULL;
+            OPENSSL_free(c->cache_accepting_serv);
+            c->cache_accepting_serv = NULL;
+            OPENSSL_free(c->cache_peer_name);
+            c->cache_peer_name = NULL;
+            OPENSSL_free(c->cache_peer_serv);
+            c->cache_peer_serv = NULL;
+
+            c->state = ACPT_S_GET_ADDR;
+            break;
+
+        case ACPT_S_GET_ADDR:
+            {
+                int family = AF_UNSPEC;
+                switch (c->accept_family) {
+                case BIO_FAMILY_IPV6:
+                    if (1) { /* This is a trick we use to avoid bit rot.
+                              * at least the "else" part will always be
+                              * compiled.
+                              */
+#ifdef AF_INET6
+                        family = AF_INET6;
+                    } else {
+#endif
+                        BIOerr(BIO_F_ACPT_STATE, BIO_R_UNAVAILABLE_IP_FAMILY);
+                        goto exit_loop;
+                    }
+                    break;
+                case BIO_FAMILY_IPV4:
+                    family = AF_INET;
+                    break;
+                case BIO_FAMILY_IPANY:
+                    family = AF_UNSPEC;
+                    break;
+                default:
+                    BIOerr(BIO_F_ACPT_STATE, BIO_R_UNSUPPORTED_IP_FAMILY);
+                    goto exit_loop;
+                }
+                if (BIO_lookup(c->param_addr, c->param_serv, BIO_LOOKUP_SERVER,
+                               family, SOCK_STREAM, &c->addr_first) == 0)
+                    goto exit_loop;
+            }
+            if (c->addr_first == NULL) {
+                BIOerr(BIO_F_ACPT_STATE, BIO_R_LOOKUP_RETURNED_NOTHING);
+                goto exit_loop;
+            }
+            /* We're currently not iterating, but set this as preparation
+             * for possible future development in that regard
+             */
+            c->addr_iter = c->addr_first;
+            c->state = ACPT_S_CREATE_SOCKET;
+            break;
+
+        case ACPT_S_CREATE_SOCKET:
+            ret = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
+                             BIO_ADDRINFO_socktype(c->addr_iter),
+                             BIO_ADDRINFO_protocol(c->addr_iter), 0);
+            if (ret == (int)INVALID_SOCKET) {
+                SYSerr(SYS_F_SOCKET, get_last_socket_error());
+                ERR_add_error_data(4,
+                                   "hostname=", c->param_addr,
+                                   " service=", c->param_serv);
+                BIOerr(BIO_F_ACPT_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET);
+                goto exit_loop;
+            }
+            c->accept_sock = ret;
+            b->num = ret;
+            c->state = ACPT_S_LISTEN;
+            break;
+
+        case ACPT_S_LISTEN:
+            {
+                if (!BIO_listen(c->accept_sock,
+                                BIO_ADDRINFO_address(c->addr_iter),
+                                c->bind_mode)) {
+                    BIO_closesocket(c->accept_sock);
+                    goto exit_loop;
+                }
+            }
+
+            {
+                union BIO_sock_info_u info;
+
+                info.addr = &c->cache_accepting_addr;
+                if (!BIO_sock_info(c->accept_sock, BIO_SOCK_INFO_ADDRESS,
+                                   &info)) {
+                    BIO_closesocket(c->accept_sock);
+                    goto exit_loop;
+                }
+            }
+
+            c->cache_accepting_name =
+                BIO_ADDR_hostname_string(&c->cache_accepting_addr, 1);
+            c->cache_accepting_serv =
+                BIO_ADDR_service_string(&c->cache_accepting_addr, 1);
+            c->state = ACPT_S_ACCEPT;
+            s = -1;
+            ret = 1;
+            goto end;
+
+        case ACPT_S_ACCEPT:
+            if (b->next_bio != NULL) {
+                c->state = ACPT_S_OK;
+                break;
+            }
+            BIO_clear_retry_flags(b);
+            b->retry_reason = 0;
+
+            s = BIO_accept_ex(c->accept_sock, &c->cache_peer_addr,
+                              c->accepted_mode);
+
+            /* If the returned socket is invalid, this might still be
+             * retryable
+             */
+            if (s < 0) {
+                if (BIO_sock_should_retry(s)) {
+                    BIO_set_retry_special(b);
+                    b->retry_reason = BIO_RR_ACCEPT;
+                    goto end;
+                }
+            }
+
+            /* If it wasn't retryable, we fail */
+            if (s < 0) {
+                ret = s;
+                goto exit_loop;
+            }
+
+            bio = BIO_new_socket(s, BIO_CLOSE);
+            if (bio == NULL)
+                goto exit_loop;
+
+            BIO_set_callback(bio, BIO_get_callback(b));
+            BIO_set_callback_arg(bio, BIO_get_callback_arg(b));
+
+            /*
+             * If the accept BIO has an bio_chain, we dup it and put the new
+             * socket at the end.
+             */
+            if (c->bio_chain != NULL) {
+                if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL)
+                    goto exit_loop;
+                if (!BIO_push(dbio, bio))
+                    goto exit_loop;
+                bio = dbio;
+            }
+            if (BIO_push(b, bio) == NULL)
+                goto exit_loop;
+
+            c->cache_peer_name =
+                BIO_ADDR_hostname_string(&c->cache_peer_addr, 1);
+            c->cache_peer_serv =
+                BIO_ADDR_service_string(&c->cache_peer_addr, 1);
+            c->state = ACPT_S_OK;
+            bio = NULL;
+            ret = 1;
+            goto end;
+
+        case ACPT_S_OK:
+            if (b->next_bio == NULL) {
+                c->state = ACPT_S_ACCEPT;
+                break;
+            }
+            ret = 1;
+            goto end;
+
+        default:
+            ret = 0;
+            goto end;
+        }
+    }
+
+  exit_loop:
+    if (bio != NULL)
+        BIO_free(bio);
+    else if (s >= 0)
+        BIO_closesocket(s);
+  end:
+    return ret;
+}
+
+static int acpt_read(BIO *b, char *out, int outl)
+{
+    int ret = 0;
+    BIO_ACCEPT *data;
+
+    BIO_clear_retry_flags(b);
+    data = (BIO_ACCEPT *)b->ptr;
+
+    while (b->next_bio == NULL) {
+        ret = acpt_state(b, data);
+        if (ret <= 0)
+            return (ret);
+    }
+
+    ret = BIO_read(b->next_bio, out, outl);
+    BIO_copy_next_retry(b);
+    return (ret);
+}
+
+static int acpt_write(BIO *b, const char *in, int inl)
+{
+    int ret;
+    BIO_ACCEPT *data;
+
+    BIO_clear_retry_flags(b);
+    data = (BIO_ACCEPT *)b->ptr;
+
+    while (b->next_bio == NULL) {
+        ret = acpt_state(b, data);
+        if (ret <= 0)
+            return (ret);
+    }
+
+    ret = BIO_write(b->next_bio, in, inl);
+    BIO_copy_next_retry(b);
+    return (ret);
+}
+
+static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    int *ip;
+    long ret = 1;
+    BIO_ACCEPT *data;
+    char **pp;
+
+    data = (BIO_ACCEPT *)b->ptr;
+
+    switch (cmd) {
+    case BIO_CTRL_RESET:
+        ret = 0;
+        data->state = ACPT_S_BEFORE;
+        acpt_close_socket(b);
+        BIO_ADDRINFO_free(data->addr_first);
+        data->addr_first = NULL;
+        b->flags = 0;
+        break;
+    case BIO_C_DO_STATE_MACHINE:
+        /* use this one to start the connection */
+        ret = (long)acpt_state(b, data);
+        break;
+    case BIO_C_SET_ACCEPT:
+        if (ptr != NULL) {
+            if (num == 0) {
+                char *hold_serv = data->param_serv;
+                /* We affect the hostname regardless.  However, the input
+                 * string might contain a host:service spec, so we must
+                 * parse it, which might or might not affect the service
+                 */
+                OPENSSL_free(data->param_addr);
+                data->param_addr = NULL;
+                ret = BIO_parse_hostserv(ptr,
+                                         &data->param_addr,
+                                         &data->param_serv,
+                                         BIO_PARSE_PRIO_SERV);
+                if (hold_serv != data->param_serv)
+                    OPENSSL_free(hold_serv);
+                b->init = 1;
+            } else if (num == 1) {
+                OPENSSL_free(data->param_serv);
+                data->param_serv = BUF_strdup(ptr);
+                b->init = 1;
+            } else if (num == 2) {
+                data->bind_mode |= BIO_SOCK_NONBLOCK;
+            } else if (num == 3) {
+                BIO_free(data->bio_chain);
+                data->bio_chain = (BIO *)ptr;
+            } else if (num == 4) {
+                data->accept_family = *(int *)ptr;
+            }
+        } else {
+            if (num == 2) {
+                data->bind_mode &= ~BIO_SOCK_NONBLOCK;
+            }
+        }
+        break;
+    case BIO_C_SET_NBIO:
+        if (num != 0)
+            data->accepted_mode |= BIO_SOCK_NONBLOCK;
+        else
+            data->accepted_mode &= ~BIO_SOCK_NONBLOCK;
+        break;
+    case BIO_C_SET_FD:
+        b->init = 1;
+        b->num = *((int *)ptr);
+        data->accept_sock = b->num;
+        data->state = ACPT_S_ACCEPT;
+        b->shutdown = (int)num;
+        b->init = 1;
+        break;
+    case BIO_C_GET_FD:
+        if (b->init) {
+            ip = (int *)ptr;
+            if (ip != NULL)
+                *ip = data->accept_sock;
+            ret = data->accept_sock;
+        } else
+            ret = -1;
+        break;
+    case BIO_C_GET_ACCEPT:
+        if (b->init) {
+            if (num == 0 && ptr != NULL) {
+                pp = (char **)ptr;
+                *pp = data->cache_accepting_name;
+            } else if (num == 1 && ptr != NULL) {
+                pp = (char **)ptr;
+                *pp = data->cache_accepting_serv;
+            } else if (num == 2 && ptr != NULL) {
+                pp = (char **)ptr;
+                *pp = data->cache_peer_name;
+            } else if (num == 3 && ptr != NULL) {
+                pp = (char **)ptr;
+                *pp = data->cache_peer_serv;
+            } else if (num == 4) {
+                switch (BIO_ADDRINFO_family(data->addr_iter)) {
+#ifdef AF_INET6
+                case AF_INET6:
+                    ret = BIO_FAMILY_IPV6;
+                    break;
+#endif
+                case AF_INET:
+                    ret = BIO_FAMILY_IPV4;
+                    break;
+                case 0:
+                    ret = data->accept_family;
+                    break;
+                default:
+                    ret = -1;
+                    break;
+                }
+            } else
+                ret = -1;
+        } else
+            ret = -1;
+        break;
+    case BIO_CTRL_GET_CLOSE:
+        ret = b->shutdown;
+        break;
+    case BIO_CTRL_SET_CLOSE:
+        b->shutdown = (int)num;
+        break;
+    case BIO_CTRL_PENDING:
+    case BIO_CTRL_WPENDING:
+        ret = 0;
+        break;
+    case BIO_CTRL_FLUSH:
+        break;
+    case BIO_C_SET_BIND_MODE:
+        data->bind_mode = (int)num;
+        break;
+    case BIO_C_GET_BIND_MODE:
+        ret = (long)data->bind_mode;
+        break;
+    case BIO_CTRL_DUP:
+/*-     dbio=(BIO *)ptr;
+        if (data->param_port) EAY EAY
+                BIO_set_port(dbio,data->param_port);
+        if (data->param_hostname)
+                BIO_set_hostname(dbio,data->param_hostname);
+        BIO_set_nbio(dbio,data->nbio); */
+        break;
+
+    default:
+        ret = 0;
+        break;
+    }
+    return (ret);
+}
+
+static int acpt_puts(BIO *bp, const char *str)
+{
+    int n, ret;
+
+    n = strlen(str);
+    ret = acpt_write(bp, str, n);
+    return (ret);
+}
+
+BIO *BIO_new_accept(const char *str)
+{
+    BIO *ret;
+
+    ret = BIO_new(BIO_s_accept());
+    if (ret == NULL)
+        return (NULL);
+    if (BIO_set_accept_name(ret, str))
+        return (ret);
+    BIO_free(ret);
+    return (NULL);
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_bio.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_bio.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_bio.c	(revision 331)
@@ -0,0 +1,805 @@
+/*
+ * Copyright 1999-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
+ */
+
+/*
+ * Special method for a BIO where the other endpoint is also a BIO of this
+ * kind, handled by the same thread (i.e. the "peer" is actually ourselves,
+ * wearing a different hat). Such "BIO pairs" are mainly for using the SSL
+ * library with I/O interfaces for which no specific BIO method is available.
+ * See ssl/ssltest.c for some hints on how this can be used.
+ */
+
+#include <assert.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "bio_lcl.h"
+#include <openssl/err.h>
+#include <openssl/crypto.h>
+
+#include "e_os.h"
+
+static int bio_new(BIO *bio);
+static int bio_free(BIO *bio);
+static int bio_read(BIO *bio, char *buf, int size);
+static int bio_write(BIO *bio, const char *buf, int num);
+static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr);
+static int bio_puts(BIO *bio, const char *str);
+
+static int bio_make_pair(BIO *bio1, BIO *bio2);
+static void bio_destroy_pair(BIO *bio);
+
+static const BIO_METHOD methods_biop = {
+    BIO_TYPE_BIO,
+    "BIO pair",
+    bio_write,
+    bio_read,
+    bio_puts,
+    NULL /* no bio_gets */ ,
+    bio_ctrl,
+    bio_new,
+    bio_free,
+    NULL                        /* no bio_callback_ctrl */
+};
+
+const BIO_METHOD *BIO_s_bio(void)
+{
+    return &methods_biop;
+}
+
+struct bio_bio_st {
+    BIO *peer;                  /* NULL if buf == NULL. If peer != NULL, then
+                                 * peer->ptr is also a bio_bio_st, and its
+                                 * "peer" member points back to us. peer !=
+                                 * NULL iff init != 0 in the BIO. */
+    /* This is for what we write (i.e. reading uses peer's struct): */
+    int closed;                 /* valid iff peer != NULL */
+    size_t len;                 /* valid iff buf != NULL; 0 if peer == NULL */
+    size_t offset;              /* valid iff buf != NULL; 0 if len == 0 */
+    size_t size;
+    char *buf;                  /* "size" elements (if != NULL) */
+    size_t request;             /* valid iff peer != NULL; 0 if len != 0,
+                                 * otherwise set by peer to number of bytes
+                                 * it (unsuccessfully) tried to read, never
+                                 * more than buffer space (size-len)
+                                 * warrants. */
+};
+
+static int bio_new(BIO *bio)
+{
+    struct bio_bio_st *b = OPENSSL_zalloc(sizeof(*b));
+
+    if (b == NULL)
+        return 0;
+
+    /* enough for one TLS record (just a default) */
+    b->size = 17 * 1024;
+
+    bio->ptr = b;
+    return 1;
+}
+
+static int bio_free(BIO *bio)
+{
+    struct bio_bio_st *b;
+
+    if (bio == NULL)
+        return 0;
+    b = bio->ptr;
+
+    assert(b != NULL);
+
+    if (b->peer)
+        bio_destroy_pair(bio);
+
+    OPENSSL_free(b->buf);
+    OPENSSL_free(b);
+
+    return 1;
+}
+
+static int bio_read(BIO *bio, char *buf, int size_)
+{
+    size_t size = size_;
+    size_t rest;
+    struct bio_bio_st *b, *peer_b;
+
+    BIO_clear_retry_flags(bio);
+
+    if (!bio->init)
+        return 0;
+
+    b = bio->ptr;
+    assert(b != NULL);
+    assert(b->peer != NULL);
+    peer_b = b->peer->ptr;
+    assert(peer_b != NULL);
+    assert(peer_b->buf != NULL);
+
+    peer_b->request = 0;        /* will be set in "retry_read" situation */
+
+    if (buf == NULL || size == 0)
+        return 0;
+
+    if (peer_b->len == 0) {
+        if (peer_b->closed)
+            return 0;           /* writer has closed, and no data is left */
+        else {
+            BIO_set_retry_read(bio); /* buffer is empty */
+            if (size <= peer_b->size)
+                peer_b->request = size;
+            else
+                /*
+                 * don't ask for more than the peer can deliver in one write
+                 */
+                peer_b->request = peer_b->size;
+            return -1;
+        }
+    }
+
+    /* we can read */
+    if (peer_b->len < size)
+        size = peer_b->len;
+
+    /* now read "size" bytes */
+
+    rest = size;
+
+    assert(rest > 0);
+    do {                        /* one or two iterations */
+        size_t chunk;
+
+        assert(rest <= peer_b->len);
+        if (peer_b->offset + rest <= peer_b->size)
+            chunk = rest;
+        else
+            /* wrap around ring buffer */
+            chunk = peer_b->size - peer_b->offset;
+        assert(peer_b->offset + chunk <= peer_b->size);
+
+        memcpy(buf, peer_b->buf + peer_b->offset, chunk);
+
+        peer_b->len -= chunk;
+        if (peer_b->len) {
+            peer_b->offset += chunk;
+            assert(peer_b->offset <= peer_b->size);
+            if (peer_b->offset == peer_b->size)
+                peer_b->offset = 0;
+            buf += chunk;
+        } else {
+            /* buffer now empty, no need to advance "buf" */
+            assert(chunk == rest);
+            peer_b->offset = 0;
+        }
+        rest -= chunk;
+    }
+    while (rest);
+
+    return size;
+}
+
+/*-
+ * non-copying interface: provide pointer to available data in buffer
+ *    bio_nread0:  return number of available bytes
+ *    bio_nread:   also advance index
+ * (example usage:  bio_nread0(), read from buffer, bio_nread()
+ *  or just         bio_nread(), read from buffer)
+ */
+/*
+ * WARNING: The non-copying interface is largely untested as of yet and may
+ * contain bugs.
+ */
+static ossl_ssize_t bio_nread0(BIO *bio, char **buf)
+{
+    struct bio_bio_st *b, *peer_b;
+    ossl_ssize_t num;
+
+    BIO_clear_retry_flags(bio);
+
+    if (!bio->init)
+        return 0;
+
+    b = bio->ptr;
+    assert(b != NULL);
+    assert(b->peer != NULL);
+    peer_b = b->peer->ptr;
+    assert(peer_b != NULL);
+    assert(peer_b->buf != NULL);
+
+    peer_b->request = 0;
+
+    if (peer_b->len == 0) {
+        char dummy;
+
+        /* avoid code duplication -- nothing available for reading */
+        return bio_read(bio, &dummy, 1); /* returns 0 or -1 */
+    }
+
+    num = peer_b->len;
+    if (peer_b->size < peer_b->offset + num)
+        /* no ring buffer wrap-around for non-copying interface */
+        num = peer_b->size - peer_b->offset;
+    assert(num > 0);
+
+    if (buf != NULL)
+        *buf = peer_b->buf + peer_b->offset;
+    return num;
+}
+
+static ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_)
+{
+    struct bio_bio_st *b, *peer_b;
+    ossl_ssize_t num, available;
+
+    if (num_ > OSSL_SSIZE_MAX)
+        num = OSSL_SSIZE_MAX;
+    else
+        num = (ossl_ssize_t) num_;
+
+    available = bio_nread0(bio, buf);
+    if (num > available)
+        num = available;
+    if (num <= 0)
+        return num;
+
+    b = bio->ptr;
+    peer_b = b->peer->ptr;
+
+    peer_b->len -= num;
+    if (peer_b->len) {
+        peer_b->offset += num;
+        assert(peer_b->offset <= peer_b->size);
+        if (peer_b->offset == peer_b->size)
+            peer_b->offset = 0;
+    } else
+        peer_b->offset = 0;
+
+    return num;
+}
+
+static int bio_write(BIO *bio, const char *buf, int num_)
+{
+    size_t num = num_;
+    size_t rest;
+    struct bio_bio_st *b;
+
+    BIO_clear_retry_flags(bio);
+
+    if (!bio->init || buf == NULL || num == 0)
+        return 0;
+
+    b = bio->ptr;
+    assert(b != NULL);
+    assert(b->peer != NULL);
+    assert(b->buf != NULL);
+
+    b->request = 0;
+    if (b->closed) {
+        /* we already closed */
+        BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE);
+        return -1;
+    }
+
+    assert(b->len <= b->size);
+
+    if (b->len == b->size) {
+        BIO_set_retry_write(bio); /* buffer is full */
+        return -1;
+    }
+
+    /* we can write */
+    if (num > b->size - b->len)
+        num = b->size - b->len;
+
+    /* now write "num" bytes */
+
+    rest = num;
+
+    assert(rest > 0);
+    do {                        /* one or two iterations */
+        size_t write_offset;
+        size_t chunk;
+
+        assert(b->len + rest <= b->size);
+
+        write_offset = b->offset + b->len;
+        if (write_offset >= b->size)
+            write_offset -= b->size;
+        /* b->buf[write_offset] is the first byte we can write to. */
+
+        if (write_offset + rest <= b->size)
+            chunk = rest;
+        else
+            /* wrap around ring buffer */
+            chunk = b->size - write_offset;
+
+        memcpy(b->buf + write_offset, buf, chunk);
+
+        b->len += chunk;
+
+        assert(b->len <= b->size);
+
+        rest -= chunk;
+        buf += chunk;
+    }
+    while (rest);
+
+    return num;
+}
+
+/*-
+ * non-copying interface: provide pointer to region to write to
+ *   bio_nwrite0:  check how much space is available
+ *   bio_nwrite:   also increase length
+ * (example usage:  bio_nwrite0(), write to buffer, bio_nwrite()
+ *  or just         bio_nwrite(), write to buffer)
+ */
+static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf)
+{
+    struct bio_bio_st *b;
+    size_t num;
+    size_t write_offset;
+
+    BIO_clear_retry_flags(bio);
+
+    if (!bio->init)
+        return 0;
+
+    b = bio->ptr;
+    assert(b != NULL);
+    assert(b->peer != NULL);
+    assert(b->buf != NULL);
+
+    b->request = 0;
+    if (b->closed) {
+        BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE);
+        return -1;
+    }
+
+    assert(b->len <= b->size);
+
+    if (b->len == b->size) {
+        BIO_set_retry_write(bio);
+        return -1;
+    }
+
+    num = b->size - b->len;
+    write_offset = b->offset + b->len;
+    if (write_offset >= b->size)
+        write_offset -= b->size;
+    if (write_offset + num > b->size)
+        /*
+         * no ring buffer wrap-around for non-copying interface (to fulfil
+         * the promise by BIO_ctrl_get_write_guarantee, BIO_nwrite may have
+         * to be called twice)
+         */
+        num = b->size - write_offset;
+
+    if (buf != NULL)
+        *buf = b->buf + write_offset;
+    assert(write_offset + num <= b->size);
+
+    return num;
+}
+
+static ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_)
+{
+    struct bio_bio_st *b;
+    ossl_ssize_t num, space;
+
+    if (num_ > OSSL_SSIZE_MAX)
+        num = OSSL_SSIZE_MAX;
+    else
+        num = (ossl_ssize_t) num_;
+
+    space = bio_nwrite0(bio, buf);
+    if (num > space)
+        num = space;
+    if (num <= 0)
+        return num;
+    b = bio->ptr;
+    assert(b != NULL);
+    b->len += num;
+    assert(b->len <= b->size);
+
+    return num;
+}
+
+static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
+{
+    long ret;
+    struct bio_bio_st *b = bio->ptr;
+
+    assert(b != NULL);
+
+    switch (cmd) {
+        /* specific CTRL codes */
+
+    case BIO_C_SET_WRITE_BUF_SIZE:
+        if (b->peer) {
+            BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE);
+            ret = 0;
+        } else if (num == 0) {
+            BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT);
+            ret = 0;
+        } else {
+            size_t new_size = num;
+
+            if (b->size != new_size) {
+                OPENSSL_free(b->buf);
+                b->buf = NULL;
+                b->size = new_size;
+            }
+            ret = 1;
+        }
+        break;
+
+    case BIO_C_GET_WRITE_BUF_SIZE:
+        ret = (long)b->size;
+        break;
+
+    case BIO_C_MAKE_BIO_PAIR:
+        {
+            BIO *other_bio = ptr;
+
+            if (bio_make_pair(bio, other_bio))
+                ret = 1;
+            else
+                ret = 0;
+        }
+        break;
+
+    case BIO_C_DESTROY_BIO_PAIR:
+        /*
+         * Affects both BIOs in the pair -- call just once! Or let
+         * BIO_free(bio1); BIO_free(bio2); do the job.
+         */
+        bio_destroy_pair(bio);
+        ret = 1;
+        break;
+
+    case BIO_C_GET_WRITE_GUARANTEE:
+        /*
+         * How many bytes can the caller feed to the next write without
+         * having to keep any?
+         */
+        if (b->peer == NULL || b->closed)
+            ret = 0;
+        else
+            ret = (long)b->size - b->len;
+        break;
+
+    case BIO_C_GET_READ_REQUEST:
+        /*
+         * If the peer unsuccessfully tried to read, how many bytes were
+         * requested? (As with BIO_CTRL_PENDING, that number can usually be
+         * treated as boolean.)
+         */
+        ret = (long)b->request;
+        break;
+
+    case BIO_C_RESET_READ_REQUEST:
+        /*
+         * Reset request.  (Can be useful after read attempts at the other
+         * side that are meant to be non-blocking, e.g. when probing SSL_read
+         * to see if any data is available.)
+         */
+        b->request = 0;
+        ret = 1;
+        break;
+
+    case BIO_C_SHUTDOWN_WR:
+        /* similar to shutdown(..., SHUT_WR) */
+        b->closed = 1;
+        ret = 1;
+        break;
+
+    case BIO_C_NREAD0:
+        /* prepare for non-copying read */
+        ret = (long)bio_nread0(bio, ptr);
+        break;
+
+    case BIO_C_NREAD:
+        /* non-copying read */
+        ret = (long)bio_nread(bio, ptr, (size_t)num);
+        break;
+
+    case BIO_C_NWRITE0:
+        /* prepare for non-copying write */
+        ret = (long)bio_nwrite0(bio, ptr);
+        break;
+
+    case BIO_C_NWRITE:
+        /* non-copying write */
+        ret = (long)bio_nwrite(bio, ptr, (size_t)num);
+        break;
+
+        /* standard CTRL codes follow */
+
+    case BIO_CTRL_RESET:
+        if (b->buf != NULL) {
+            b->len = 0;
+            b->offset = 0;
+        }
+        ret = 0;
+        break;
+
+    case BIO_CTRL_GET_CLOSE:
+        ret = bio->shutdown;
+        break;
+
+    case BIO_CTRL_SET_CLOSE:
+        bio->shutdown = (int)num;
+        ret = 1;
+        break;
+
+    case BIO_CTRL_PENDING:
+        if (b->peer != NULL) {
+            struct bio_bio_st *peer_b = b->peer->ptr;
+
+            ret = (long)peer_b->len;
+        } else
+            ret = 0;
+        break;
+
+    case BIO_CTRL_WPENDING:
+        if (b->buf != NULL)
+            ret = (long)b->len;
+        else
+            ret = 0;
+        break;
+
+    case BIO_CTRL_DUP:
+        /* See BIO_dup_chain for circumstances we have to expect. */
+        {
+            BIO *other_bio = ptr;
+            struct bio_bio_st *other_b;
+
+            assert(other_bio != NULL);
+            other_b = other_bio->ptr;
+            assert(other_b != NULL);
+
+            assert(other_b->buf == NULL); /* other_bio is always fresh */
+
+            other_b->size = b->size;
+        }
+
+        ret = 1;
+        break;
+
+    case BIO_CTRL_FLUSH:
+        ret = 1;
+        break;
+
+    case BIO_CTRL_EOF:
+        if (b->peer != NULL) {
+            struct bio_bio_st *peer_b = b->peer->ptr;
+
+            if (peer_b->len == 0 && peer_b->closed)
+                ret = 1;
+            else
+                ret = 0;
+        } else {
+            ret = 1;
+        }
+        break;
+
+    default:
+        ret = 0;
+    }
+    return ret;
+}
+
+static int bio_puts(BIO *bio, const char *str)
+{
+    return bio_write(bio, str, strlen(str));
+}
+
+static int bio_make_pair(BIO *bio1, BIO *bio2)
+{
+    struct bio_bio_st *b1, *b2;
+
+    assert(bio1 != NULL);
+    assert(bio2 != NULL);
+
+    b1 = bio1->ptr;
+    b2 = bio2->ptr;
+
+    if (b1->peer != NULL || b2->peer != NULL) {
+        BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE);
+        return 0;
+    }
+
+    if (b1->buf == NULL) {
+        b1->buf = OPENSSL_malloc(b1->size);
+        if (b1->buf == NULL) {
+            BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        b1->len = 0;
+        b1->offset = 0;
+    }
+
+    if (b2->buf == NULL) {
+        b2->buf = OPENSSL_malloc(b2->size);
+        if (b2->buf == NULL) {
+            BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        b2->len = 0;
+        b2->offset = 0;
+    }
+
+    b1->peer = bio2;
+    b1->closed = 0;
+    b1->request = 0;
+    b2->peer = bio1;
+    b2->closed = 0;
+    b2->request = 0;
+
+    bio1->init = 1;
+    bio2->init = 1;
+
+    return 1;
+}
+
+static void bio_destroy_pair(BIO *bio)
+{
+    struct bio_bio_st *b = bio->ptr;
+
+    if (b != NULL) {
+        BIO *peer_bio = b->peer;
+
+        if (peer_bio != NULL) {
+            struct bio_bio_st *peer_b = peer_bio->ptr;
+
+            assert(peer_b != NULL);
+            assert(peer_b->peer == bio);
+
+            peer_b->peer = NULL;
+            peer_bio->init = 0;
+            assert(peer_b->buf != NULL);
+            peer_b->len = 0;
+            peer_b->offset = 0;
+
+            b->peer = NULL;
+            bio->init = 0;
+            assert(b->buf != NULL);
+            b->len = 0;
+            b->offset = 0;
+        }
+    }
+}
+
+/* Exported convenience functions */
+int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1,
+                     BIO **bio2_p, size_t writebuf2)
+{
+    BIO *bio1 = NULL, *bio2 = NULL;
+    long r;
+    int ret = 0;
+
+    bio1 = BIO_new(BIO_s_bio());
+    if (bio1 == NULL)
+        goto err;
+    bio2 = BIO_new(BIO_s_bio());
+    if (bio2 == NULL)
+        goto err;
+
+    if (writebuf1) {
+        r = BIO_set_write_buf_size(bio1, writebuf1);
+        if (!r)
+            goto err;
+    }
+    if (writebuf2) {
+        r = BIO_set_write_buf_size(bio2, writebuf2);
+        if (!r)
+            goto err;
+    }
+
+    r = BIO_make_bio_pair(bio1, bio2);
+    if (!r)
+        goto err;
+    ret = 1;
+
+ err:
+    if (ret == 0) {
+        BIO_free(bio1);
+        bio1 = NULL;
+        BIO_free(bio2);
+        bio2 = NULL;
+    }
+
+    *bio1_p = bio1;
+    *bio2_p = bio2;
+    return ret;
+}
+
+size_t BIO_ctrl_get_write_guarantee(BIO *bio)
+{
+    return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL);
+}
+
+size_t BIO_ctrl_get_read_request(BIO *bio)
+{
+    return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL);
+}
+
+int BIO_ctrl_reset_read_request(BIO *bio)
+{
+    return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0);
+}
+
+/*
+ * BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now
+ * (conceivably some other BIOs could allow non-copying reads and writes
+ * too.)
+ */
+int BIO_nread0(BIO *bio, char **buf)
+{
+    long ret;
+
+    if (!bio->init) {
+        BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED);
+        return -2;
+    }
+
+    ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf);
+    if (ret > INT_MAX)
+        return INT_MAX;
+    else
+        return (int)ret;
+}
+
+int BIO_nread(BIO *bio, char **buf, int num)
+{
+    int ret;
+
+    if (!bio->init) {
+        BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED);
+        return -2;
+    }
+
+    ret = (int)BIO_ctrl(bio, BIO_C_NREAD, num, buf);
+    if (ret > 0)
+        bio->num_read += ret;
+    return ret;
+}
+
+int BIO_nwrite0(BIO *bio, char **buf)
+{
+    long ret;
+
+    if (!bio->init) {
+        BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED);
+        return -2;
+    }
+
+    ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf);
+    if (ret > INT_MAX)
+        return INT_MAX;
+    else
+        return (int)ret;
+}
+
+int BIO_nwrite(BIO *bio, char **buf, int num)
+{
+    int ret;
+
+    if (!bio->init) {
+        BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED);
+        return -2;
+    }
+
+    ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
+    if (ret > 0)
+        bio->num_write += ret;
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_conn.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_conn.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_conn.c	(revision 331)
@@ -0,0 +1,545 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <errno.h>
+
+#include "bio_lcl.h"
+
+#ifndef OPENSSL_NO_SOCK
+
+typedef struct bio_connect_st {
+    int state;
+    int connect_family;
+    char *param_hostname;
+    char *param_service;
+    int connect_mode;
+
+    BIO_ADDRINFO *addr_first;
+    const BIO_ADDRINFO *addr_iter;
+    /*
+     * int socket; this will be kept in bio->num so that it is compatible
+     * with the bss_sock bio
+     */
+    /*
+     * called when the connection is initially made callback(BIO,state,ret);
+     * The callback should return 'ret'.  state is for compatibility with the
+     * ssl info_callback
+     */
+    int (*info_callback) (const BIO *bio, int state, int ret);
+} BIO_CONNECT;
+
+static int conn_write(BIO *h, const char *buf, int num);
+static int conn_read(BIO *h, char *buf, int size);
+static int conn_puts(BIO *h, const char *str);
+static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int conn_new(BIO *h);
+static int conn_free(BIO *data);
+static long conn_callback_ctrl(BIO *h, int cmd, bio_info_cb *);
+
+static int conn_state(BIO *b, BIO_CONNECT *c);
+static void conn_close_socket(BIO *data);
+BIO_CONNECT *BIO_CONNECT_new(void);
+void BIO_CONNECT_free(BIO_CONNECT *a);
+
+#define BIO_CONN_S_BEFORE                1
+#define BIO_CONN_S_GET_ADDR              2
+#define BIO_CONN_S_CREATE_SOCKET         3
+#define BIO_CONN_S_CONNECT               4
+#define BIO_CONN_S_OK                    5
+#define BIO_CONN_S_BLOCKED_CONNECT       6
+
+static const BIO_METHOD methods_connectp = {
+    BIO_TYPE_CONNECT,
+    "socket connect",
+    conn_write,
+    conn_read,
+    conn_puts,
+    NULL,                       /* connect_gets, */
+    conn_ctrl,
+    conn_new,
+    conn_free,
+    conn_callback_ctrl,
+};
+
+static int conn_state(BIO *b, BIO_CONNECT *c)
+{
+    int ret = -1, i;
+    int (*cb) (const BIO *, int, int) = NULL;
+
+    if (c->info_callback != NULL)
+        cb = c->info_callback;
+
+    for (;;) {
+        switch (c->state) {
+        case BIO_CONN_S_BEFORE:
+            if (c->param_hostname == NULL && c->param_service == NULL) {
+                BIOerr(BIO_F_CONN_STATE, BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED);
+                ERR_add_error_data(4,
+                                   "hostname=", c->param_hostname,
+                                   " service=", c->param_service);
+                goto exit_loop;
+            }
+            c->state = BIO_CONN_S_GET_ADDR;
+            break;
+
+        case BIO_CONN_S_GET_ADDR:
+            {
+                int family = AF_UNSPEC;
+                switch (c->connect_family) {
+                case BIO_FAMILY_IPV6:
+                    if (1) { /* This is a trick we use to avoid bit rot.
+                              * at least the "else" part will always be
+                              * compiled.
+                              */
+#ifdef AF_INET6
+                        family = AF_INET6;
+                    } else {
+#endif
+                        BIOerr(BIO_F_CONN_STATE, BIO_R_UNAVAILABLE_IP_FAMILY);
+                        goto exit_loop;
+                    }
+                    break;
+                case BIO_FAMILY_IPV4:
+                    family = AF_INET;
+                    break;
+                case BIO_FAMILY_IPANY:
+                    family = AF_UNSPEC;
+                    break;
+                default:
+                    BIOerr(BIO_F_CONN_STATE, BIO_R_UNSUPPORTED_IP_FAMILY);
+                    goto exit_loop;
+                }
+                if (BIO_lookup(c->param_hostname, c->param_service,
+                               BIO_LOOKUP_CLIENT,
+                               family, SOCK_STREAM, &c->addr_first) == 0)
+                    goto exit_loop;
+            }
+            if (c->addr_first == NULL) {
+                BIOerr(BIO_F_CONN_STATE, BIO_R_LOOKUP_RETURNED_NOTHING);
+                goto exit_loop;
+            }
+            c->addr_iter = c->addr_first;
+            c->state = BIO_CONN_S_CREATE_SOCKET;
+            break;
+
+        case BIO_CONN_S_CREATE_SOCKET:
+            ret = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
+                             BIO_ADDRINFO_socktype(c->addr_iter),
+                             BIO_ADDRINFO_protocol(c->addr_iter), 0);
+            if (ret == (int)INVALID_SOCKET) {
+                SYSerr(SYS_F_SOCKET, get_last_socket_error());
+                ERR_add_error_data(4,
+                                   "hostname=", c->param_hostname,
+                                   " service=", c->param_service);
+                BIOerr(BIO_F_CONN_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET);
+                goto exit_loop;
+            }
+            b->num = ret;
+            c->state = BIO_CONN_S_CONNECT;
+            break;
+
+        case BIO_CONN_S_CONNECT:
+            BIO_clear_retry_flags(b);
+            ret = BIO_connect(b->num, BIO_ADDRINFO_address(c->addr_iter),
+                              BIO_SOCK_KEEPALIVE | c->connect_mode);
+            b->retry_reason = 0;
+            if (ret == 0) {
+                if (BIO_sock_should_retry(ret)) {
+                    BIO_set_retry_special(b);
+                    c->state = BIO_CONN_S_BLOCKED_CONNECT;
+                    b->retry_reason = BIO_RR_CONNECT;
+                    ERR_clear_error();
+                } else if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter))
+                           != NULL) {
+                    /*
+                     * if there are more addresses to try, do that first
+                     */
+                    BIO_closesocket(b->num);
+                    c->state = BIO_CONN_S_CREATE_SOCKET;
+                    ERR_clear_error();
+                    break;
+                } else {
+                    SYSerr(SYS_F_CONNECT, get_last_socket_error());
+                    ERR_add_error_data(4,
+                                       "hostname=", c->param_hostname,
+                                       " service=", c->param_service);
+                    BIOerr(BIO_F_CONN_STATE, BIO_R_CONNECT_ERROR);
+                }
+                goto exit_loop;
+            } else {
+                c->state = BIO_CONN_S_OK;
+            }
+            break;
+
+        case BIO_CONN_S_BLOCKED_CONNECT:
+            i = BIO_sock_error(b->num);
+            if (i) {
+                BIO_clear_retry_flags(b);
+                SYSerr(SYS_F_CONNECT, i);
+                ERR_add_error_data(4,
+                                   "hostname=", c->param_hostname,
+                                   " service=", c->param_service);
+                BIOerr(BIO_F_CONN_STATE, BIO_R_NBIO_CONNECT_ERROR);
+                ret = 0;
+                goto exit_loop;
+            } else
+                c->state = BIO_CONN_S_OK;
+            break;
+
+        case BIO_CONN_S_OK:
+            ret = 1;
+            goto exit_loop;
+        default:
+            /* abort(); */
+            goto exit_loop;
+        }
+
+        if (cb != NULL) {
+            if ((ret = cb((BIO *)b, c->state, ret)) == 0)
+                goto end;
+        }
+    }
+
+    /* Loop does not exit */
+ exit_loop:
+    if (cb != NULL)
+        ret = cb((BIO *)b, c->state, ret);
+ end:
+    return (ret);
+}
+
+BIO_CONNECT *BIO_CONNECT_new(void)
+{
+    BIO_CONNECT *ret;
+
+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
+        return (NULL);
+    ret->state = BIO_CONN_S_BEFORE;
+    ret->connect_family = BIO_FAMILY_IPANY;
+    return (ret);
+}
+
+void BIO_CONNECT_free(BIO_CONNECT *a)
+{
+    if (a == NULL)
+        return;
+
+    OPENSSL_free(a->param_hostname);
+    OPENSSL_free(a->param_service);
+    BIO_ADDRINFO_free(a->addr_first);
+    OPENSSL_free(a);
+}
+
+const BIO_METHOD *BIO_s_connect(void)
+{
+    return (&methods_connectp);
+}
+
+static int conn_new(BIO *bi)
+{
+    bi->init = 0;
+    bi->num = (int)INVALID_SOCKET;
+    bi->flags = 0;
+    if ((bi->ptr = (char *)BIO_CONNECT_new()) == NULL)
+        return (0);
+    else
+        return (1);
+}
+
+static void conn_close_socket(BIO *bio)
+{
+    BIO_CONNECT *c;
+
+    c = (BIO_CONNECT *)bio->ptr;
+    if (bio->num != (int)INVALID_SOCKET) {
+        /* Only do a shutdown if things were established */
+        if (c->state == BIO_CONN_S_OK)
+            shutdown(bio->num, 2);
+        BIO_closesocket(bio->num);
+        bio->num = (int)INVALID_SOCKET;
+    }
+}
+
+static int conn_free(BIO *a)
+{
+    BIO_CONNECT *data;
+
+    if (a == NULL)
+        return (0);
+    data = (BIO_CONNECT *)a->ptr;
+
+    if (a->shutdown) {
+        conn_close_socket(a);
+        BIO_CONNECT_free(data);
+        a->ptr = NULL;
+        a->flags = 0;
+        a->init = 0;
+    }
+    return (1);
+}
+
+static int conn_read(BIO *b, char *out, int outl)
+{
+    int ret = 0;
+    BIO_CONNECT *data;
+
+    data = (BIO_CONNECT *)b->ptr;
+    if (data->state != BIO_CONN_S_OK) {
+        ret = conn_state(b, data);
+        if (ret <= 0)
+            return (ret);
+    }
+
+    if (out != NULL) {
+        clear_socket_error();
+        ret = readsocket(b->num, out, outl);
+        BIO_clear_retry_flags(b);
+        if (ret <= 0) {
+            if (BIO_sock_should_retry(ret))
+                BIO_set_retry_read(b);
+        }
+    }
+    return (ret);
+}
+
+static int conn_write(BIO *b, const char *in, int inl)
+{
+    int ret;
+    BIO_CONNECT *data;
+
+    data = (BIO_CONNECT *)b->ptr;
+    if (data->state != BIO_CONN_S_OK) {
+        ret = conn_state(b, data);
+        if (ret <= 0)
+            return (ret);
+    }
+
+    clear_socket_error();
+    ret = writesocket(b->num, in, inl);
+    BIO_clear_retry_flags(b);
+    if (ret <= 0) {
+        if (BIO_sock_should_retry(ret))
+            BIO_set_retry_write(b);
+    }
+    return (ret);
+}
+
+static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    BIO *dbio;
+    int *ip;
+    const char **pptr = NULL;
+    long ret = 1;
+    BIO_CONNECT *data;
+
+    data = (BIO_CONNECT *)b->ptr;
+
+    switch (cmd) {
+    case BIO_CTRL_RESET:
+        ret = 0;
+        data->state = BIO_CONN_S_BEFORE;
+        conn_close_socket(b);
+        BIO_ADDRINFO_free(data->addr_first);
+        data->addr_first = NULL;
+        b->flags = 0;
+        break;
+    case BIO_C_DO_STATE_MACHINE:
+        /* use this one to start the connection */
+        if (data->state != BIO_CONN_S_OK)
+            ret = (long)conn_state(b, data);
+        else
+            ret = 1;
+        break;
+    case BIO_C_GET_CONNECT:
+        if (ptr != NULL) {
+            pptr = (const char **)ptr;
+            if (num == 0) {
+                *pptr = data->param_hostname;
+            } else if (num == 1) {
+                *pptr = data->param_service;
+            } else if (num == 2) {
+                *pptr = (const char *)BIO_ADDRINFO_address(data->addr_iter);
+            } else if (num == 3) {
+                switch (BIO_ADDRINFO_family(data->addr_iter)) {
+# ifdef AF_INET6
+                case AF_INET6:
+                    ret = BIO_FAMILY_IPV6;
+                    break;
+# endif
+                case AF_INET:
+                    ret = BIO_FAMILY_IPV4;
+                    break;
+                case 0:
+                    ret = data->connect_family;
+                    break;
+                default:
+                    ret = -1;
+                    break;
+                }
+            } else {
+                ret = 0;
+            }
+        } else {
+            ret = 0;
+        }
+        break;
+    case BIO_C_SET_CONNECT:
+        if (ptr != NULL) {
+            b->init = 1;
+            if (num == 0) {
+                char *hold_service = data->param_service;
+                /* We affect the hostname regardless.  However, the input
+                 * string might contain a host:service spec, so we must
+                 * parse it, which might or might not affect the service
+                 */
+                OPENSSL_free(data->param_hostname);
+                data->param_hostname = NULL;
+                ret = BIO_parse_hostserv(ptr,
+                                         &data->param_hostname,
+                                         &data->param_service,
+                                         BIO_PARSE_PRIO_HOST);
+                if (hold_service != data->param_service)
+                    OPENSSL_free(hold_service);
+            } else if (num == 1) {
+                OPENSSL_free(data->param_service);
+                data->param_service = BUF_strdup(ptr);
+            } else if (num == 2) {
+                const BIO_ADDR *addr = (const BIO_ADDR *)ptr;
+                if (ret) {
+                    data->param_hostname = BIO_ADDR_hostname_string(addr, 1);
+                    data->param_service = BIO_ADDR_service_string(addr, 1);
+                    BIO_ADDRINFO_free(data->addr_first);
+                    data->addr_first = NULL;
+                    data->addr_iter = NULL;
+                }
+            } else if (num == 3) {
+                data->connect_family = *(int *)ptr;
+            } else {
+                ret = 0;
+            }
+        }
+        break;
+    case BIO_C_SET_NBIO:
+        if (num != 0)
+            data->connect_mode |= BIO_SOCK_NONBLOCK;
+        else
+            data->connect_mode &= ~BIO_SOCK_NONBLOCK;
+        break;
+    case BIO_C_SET_CONNECT_MODE:
+        data->connect_mode = (int)num;
+        break;
+    case BIO_C_GET_FD:
+        if (b->init) {
+            ip = (int *)ptr;
+            if (ip != NULL)
+                *ip = b->num;
+            ret = b->num;
+        } else
+            ret = -1;
+        break;
+    case BIO_CTRL_GET_CLOSE:
+        ret = b->shutdown;
+        break;
+    case BIO_CTRL_SET_CLOSE:
+        b->shutdown = (int)num;
+        break;
+    case BIO_CTRL_PENDING:
+    case BIO_CTRL_WPENDING:
+        ret = 0;
+        break;
+    case BIO_CTRL_FLUSH:
+        break;
+    case BIO_CTRL_DUP:
+        {
+            dbio = (BIO *)ptr;
+            if (data->param_hostname)
+                BIO_set_conn_hostname(dbio, data->param_hostname);
+            if (data->param_service)
+                BIO_set_conn_port(dbio, data->param_service);
+            BIO_set_conn_ip_family(dbio, data->connect_family);
+            BIO_set_conn_mode(dbio, data->connect_mode);
+            /*
+             * FIXME: the cast of the function seems unlikely to be a good
+             * idea
+             */
+            (void)BIO_set_info_callback(dbio,
+                                        (bio_info_cb *)data->info_callback);
+        }
+        break;
+    case BIO_CTRL_SET_CALLBACK:
+        {
+# if 0                          /* FIXME: Should this be used? -- Richard
+                                 * Levitte */
+            BIOerr(BIO_F_CONN_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+            ret = -1;
+# else
+            ret = 0;
+# endif
+        }
+        break;
+    case BIO_CTRL_GET_CALLBACK:
+        {
+            int (**fptr) (const BIO *bio, int state, int xret);
+
+            fptr = (int (**)(const BIO *bio, int state, int xret))ptr;
+            *fptr = data->info_callback;
+        }
+        break;
+    default:
+        ret = 0;
+        break;
+    }
+    return (ret);
+}
+
+static long conn_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+    long ret = 1;
+    BIO_CONNECT *data;
+
+    data = (BIO_CONNECT *)b->ptr;
+
+    switch (cmd) {
+    case BIO_CTRL_SET_CALLBACK:
+        {
+            data->info_callback =
+                (int (*)(const struct bio_st *, int, int))fp;
+        }
+        break;
+    default:
+        ret = 0;
+        break;
+    }
+    return (ret);
+}
+
+static int conn_puts(BIO *bp, const char *str)
+{
+    int n, ret;
+
+    n = strlen(str);
+    ret = conn_write(bp, str, n);
+    return (ret);
+}
+
+BIO *BIO_new_connect(const char *str)
+{
+    BIO *ret;
+
+    ret = BIO_new(BIO_s_connect());
+    if (ret == NULL)
+        return (NULL);
+    if (BIO_set_conn_hostname(ret, str))
+        return (ret);
+    BIO_free(ret);
+    return (NULL);
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_dgram.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_dgram.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_dgram.c	(revision 331)
@@ -0,0 +1,1944 @@
+/*
+ * Copyright 2005-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 <stdio.h>
+#include <errno.h>
+
+#include "bio_lcl.h"
+#ifndef OPENSSL_NO_DGRAM
+
+# if !(defined(_WIN32) || defined(OPENSSL_SYS_VMS))
+#  include <sys/time.h>
+# endif
+# if defined(OPENSSL_SYS_VMS)
+#  include <sys/timeb.h>
+# endif
+
+# ifndef OPENSSL_NO_SCTP
+#  include <netinet/sctp.h>
+#  include <fcntl.h>
+#  define OPENSSL_SCTP_DATA_CHUNK_TYPE            0x00
+#  define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0
+# endif
+
+# if defined(OPENSSL_SYS_LINUX) && !defined(IP_MTU)
+#  define IP_MTU      14        /* linux is lame */
+# endif
+
+# if OPENSSL_USE_IPV6 && !defined(IPPROTO_IPV6)
+#  define IPPROTO_IPV6 41       /* windows is lame */
+# endif
+
+# if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED)
+/* Standard definition causes type-punning problems. */
+#  undef IN6_IS_ADDR_V4MAPPED
+#  define s6_addr32 __u6_addr.__u6_addr32
+#  define IN6_IS_ADDR_V4MAPPED(a)               \
+        (((a)->s6_addr32[0] == 0) &&          \
+         ((a)->s6_addr32[1] == 0) &&          \
+         ((a)->s6_addr32[2] == htonl(0x0000ffff)))
+# endif
+
+static int dgram_write(BIO *h, const char *buf, int num);
+static int dgram_read(BIO *h, char *buf, int size);
+static int dgram_puts(BIO *h, const char *str);
+static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int dgram_new(BIO *h);
+static int dgram_free(BIO *data);
+static int dgram_clear(BIO *bio);
+
+# ifndef OPENSSL_NO_SCTP
+static int dgram_sctp_write(BIO *h, const char *buf, int num);
+static int dgram_sctp_read(BIO *h, char *buf, int size);
+static int dgram_sctp_puts(BIO *h, const char *str);
+static long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int dgram_sctp_new(BIO *h);
+static int dgram_sctp_free(BIO *data);
+#  ifdef SCTP_AUTHENTICATION_EVENT
+static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification
+                                                  *snp);
+#  endif
+# endif
+
+static int BIO_dgram_should_retry(int s);
+
+static void get_current_time(struct timeval *t);
+
+static const BIO_METHOD methods_dgramp = {
+    BIO_TYPE_DGRAM,
+    "datagram socket",
+    dgram_write,
+    dgram_read,
+    dgram_puts,
+    NULL,                       /* dgram_gets, */
+    dgram_ctrl,
+    dgram_new,
+    dgram_free,
+    NULL,
+};
+
+# ifndef OPENSSL_NO_SCTP
+static const BIO_METHOD methods_dgramp_sctp = {
+    BIO_TYPE_DGRAM_SCTP,
+    "datagram sctp socket",
+    dgram_sctp_write,
+    dgram_sctp_read,
+    dgram_sctp_puts,
+    NULL,                       /* dgram_gets, */
+    dgram_sctp_ctrl,
+    dgram_sctp_new,
+    dgram_sctp_free,
+    NULL,
+};
+# endif
+
+typedef struct bio_dgram_data_st {
+    BIO_ADDR peer;
+    unsigned int connected;
+    unsigned int _errno;
+    unsigned int mtu;
+    struct timeval next_timeout;
+    struct timeval socket_timeout;
+    unsigned int peekmode;
+} bio_dgram_data;
+
+# ifndef OPENSSL_NO_SCTP
+typedef struct bio_dgram_sctp_save_message_st {
+    BIO *bio;
+    char *data;
+    int length;
+} bio_dgram_sctp_save_message;
+
+typedef struct bio_dgram_sctp_data_st {
+    BIO_ADDR peer;
+    unsigned int connected;
+    unsigned int _errno;
+    unsigned int mtu;
+    struct bio_dgram_sctp_sndinfo sndinfo;
+    struct bio_dgram_sctp_rcvinfo rcvinfo;
+    struct bio_dgram_sctp_prinfo prinfo;
+    void (*handle_notifications) (BIO *bio, void *context, void *buf);
+    void *notification_context;
+    int in_handshake;
+    int ccs_rcvd;
+    int ccs_sent;
+    int save_shutdown;
+    int peer_auth_tested;
+    bio_dgram_sctp_save_message saved_message;
+} bio_dgram_sctp_data;
+# endif
+
+const BIO_METHOD *BIO_s_datagram(void)
+{
+    return (&methods_dgramp);
+}
+
+BIO *BIO_new_dgram(int fd, int close_flag)
+{
+    BIO *ret;
+
+    ret = BIO_new(BIO_s_datagram());
+    if (ret == NULL)
+        return (NULL);
+    BIO_set_fd(ret, fd, close_flag);
+    return (ret);
+}
+
+static int dgram_new(BIO *bi)
+{
+    bio_dgram_data *data = OPENSSL_zalloc(sizeof(*data));
+
+    if (data == NULL)
+        return 0;
+    bi->ptr = data;
+    return (1);
+}
+
+static int dgram_free(BIO *a)
+{
+    bio_dgram_data *data;
+
+    if (a == NULL)
+        return (0);
+    if (!dgram_clear(a))
+        return 0;
+
+    data = (bio_dgram_data *)a->ptr;
+    OPENSSL_free(data);
+
+    return (1);
+}
+
+static int dgram_clear(BIO *a)
+{
+    if (a == NULL)
+        return (0);
+    if (a->shutdown) {
+        if (a->init) {
+            BIO_closesocket(a->num);
+        }
+        a->init = 0;
+        a->flags = 0;
+    }
+    return (1);
+}
+
+static void dgram_adjust_rcv_timeout(BIO *b)
+{
+# if defined(SO_RCVTIMEO)
+    bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+    union {
+        size_t s;
+        int i;
+    } sz = {
+        0
+    };
+
+    /* Is a timer active? */
+    if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
+        struct timeval timenow, timeleft;
+
+        /* Read current socket timeout */
+#  ifdef OPENSSL_SYS_WINDOWS
+        int timeout;
+
+        sz.i = sizeof(timeout);
+        if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+                       (void *)&timeout, &sz.i) < 0) {
+            perror("getsockopt");
+        } else {
+            data->socket_timeout.tv_sec = timeout / 1000;
+            data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
+        }
+#  else
+        sz.i = sizeof(data->socket_timeout);
+        if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+                       &(data->socket_timeout), (void *)&sz) < 0) {
+            perror("getsockopt");
+        } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0)
+            OPENSSL_assert(sz.s <= sizeof(data->socket_timeout));
+#  endif
+
+        /* Get current time */
+        get_current_time(&timenow);
+
+        /* Calculate time left until timer expires */
+        memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval));
+        if (timeleft.tv_usec < timenow.tv_usec) {
+            timeleft.tv_usec = 1000000 - timenow.tv_usec + timeleft.tv_usec;
+            timeleft.tv_sec--;
+        } else {
+            timeleft.tv_usec -= timenow.tv_usec;
+        }
+        if (timeleft.tv_sec < timenow.tv_sec) {
+            timeleft.tv_sec = 0;
+            timeleft.tv_usec = 1;
+        } else {
+            timeleft.tv_sec -= timenow.tv_sec;
+        }
+
+        /*
+         * Adjust socket timeout if next handshake message timer will expire
+         * earlier.
+         */
+        if ((data->socket_timeout.tv_sec == 0
+             && data->socket_timeout.tv_usec == 0)
+            || (data->socket_timeout.tv_sec > timeleft.tv_sec)
+            || (data->socket_timeout.tv_sec == timeleft.tv_sec
+                && data->socket_timeout.tv_usec >= timeleft.tv_usec)) {
+#  ifdef OPENSSL_SYS_WINDOWS
+            timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000;
+            if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+                           (void *)&timeout, sizeof(timeout)) < 0) {
+                perror("setsockopt");
+            }
+#  else
+            if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft,
+                           sizeof(struct timeval)) < 0) {
+                perror("setsockopt");
+            }
+#  endif
+        }
+    }
+# endif
+}
+
+static void dgram_reset_rcv_timeout(BIO *b)
+{
+# if defined(SO_RCVTIMEO)
+    bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+
+    /* Is a timer active? */
+    if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
+#  ifdef OPENSSL_SYS_WINDOWS
+        int timeout = data->socket_timeout.tv_sec * 1000 +
+            data->socket_timeout.tv_usec / 1000;
+        if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+                       (void *)&timeout, sizeof(timeout)) < 0) {
+            perror("setsockopt");
+        }
+#  else
+        if (setsockopt
+            (b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout),
+             sizeof(struct timeval)) < 0) {
+            perror("setsockopt");
+        }
+#  endif
+    }
+# endif
+}
+
+static int dgram_read(BIO *b, char *out, int outl)
+{
+    int ret = 0;
+    bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+    int flags = 0;
+
+    BIO_ADDR peer;
+    socklen_t len = sizeof(peer);
+
+    if (out != NULL) {
+        clear_socket_error();
+        memset(&peer, 0, sizeof(peer));
+        dgram_adjust_rcv_timeout(b);
+        if (data->peekmode)
+            flags = MSG_PEEK;
+        ret = recvfrom(b->num, out, outl, flags,
+                       BIO_ADDR_sockaddr_noconst(&peer), &len);
+
+        if (!data->connected && ret >= 0)
+            BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &peer);
+
+        BIO_clear_retry_flags(b);
+        if (ret < 0) {
+            if (BIO_dgram_should_retry(ret)) {
+                BIO_set_retry_read(b);
+                data->_errno = get_last_socket_error();
+            }
+        }
+
+        dgram_reset_rcv_timeout(b);
+    }
+    return (ret);
+}
+
+static int dgram_write(BIO *b, const char *in, int inl)
+{
+    int ret;
+    bio_dgram_data *data = (bio_dgram_data *)b->ptr;
+    clear_socket_error();
+
+    if (data->connected)
+        ret = writesocket(b->num, in, inl);
+    else {
+        int peerlen = BIO_ADDR_sockaddr_size(&data->peer);
+
+# if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
+        ret = sendto(b->num, (char *)in, inl, 0,
+                     BIO_ADDR_sockaddr(&data->peer), peerlen);
+# else
+        ret = sendto(b->num, in, inl, 0,
+                     BIO_ADDR_sockaddr(&data->peer), peerlen);
+# endif
+    }
+
+    BIO_clear_retry_flags(b);
+    if (ret <= 0) {
+        if (BIO_dgram_should_retry(ret)) {
+            BIO_set_retry_write(b);
+            data->_errno = get_last_socket_error();
+        }
+    }
+    return (ret);
+}
+
+static long dgram_get_mtu_overhead(bio_dgram_data *data)
+{
+    long ret;
+
+    switch (BIO_ADDR_family(&data->peer)) {
+    case AF_INET:
+        /*
+         * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
+         */
+        ret = 28;
+        break;
+# ifdef AF_INET6
+    case AF_INET6:
+        {
+#  ifdef IN6_IS_ADDR_V4MAPPED
+            struct in6_addr tmp_addr;
+            if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL)
+                && IN6_IS_ADDR_V4MAPPED(&tmp_addr))
+                /*
+                 * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP
+                 */
+                ret = 28;
+            else
+#  endif
+            /*
+             * Assume this is UDP - 40 bytes for IP, 8 bytes for UDP
+             */
+            ret = 48;
+        }
+        break;
+# endif
+    default:
+        /* We don't know. Go with the historical default */
+        ret = 28;
+        break;
+    }
+    return ret;
+}
+
+static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    long ret = 1;
+    int *ip;
+    bio_dgram_data *data = NULL;
+    int sockopt_val = 0;
+    int d_errno;
+# if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
+    socklen_t sockopt_len;      /* assume that system supporting IP_MTU is
+                                 * modern enough to define socklen_t */
+    socklen_t addr_len;
+    BIO_ADDR addr;
+# endif
+
+    data = (bio_dgram_data *)b->ptr;
+
+    switch (cmd) {
+    case BIO_CTRL_RESET:
+        num = 0;
+        ret = 0;
+        break;
+    case BIO_CTRL_INFO:
+        ret = 0;
+        break;
+    case BIO_C_SET_FD:
+        dgram_clear(b);
+        b->num = *((int *)ptr);
+        b->shutdown = (int)num;
+        b->init = 1;
+        break;
+    case BIO_C_GET_FD:
+        if (b->init) {
+            ip = (int *)ptr;
+            if (ip != NULL)
+                *ip = b->num;
+            ret = b->num;
+        } else
+            ret = -1;
+        break;
+    case BIO_CTRL_GET_CLOSE:
+        ret = b->shutdown;
+        break;
+    case BIO_CTRL_SET_CLOSE:
+        b->shutdown = (int)num;
+        break;
+    case BIO_CTRL_PENDING:
+    case BIO_CTRL_WPENDING:
+        ret = 0;
+        break;
+    case BIO_CTRL_DUP:
+    case BIO_CTRL_FLUSH:
+        ret = 1;
+        break;
+    case BIO_CTRL_DGRAM_CONNECT:
+        BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
+        break;
+        /* (Linux)kernel sets DF bit on outgoing IP packets */
+    case BIO_CTRL_DGRAM_MTU_DISCOVER:
+# if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
+        addr_len = (socklen_t) sizeof(addr);
+        memset(&addr, 0, sizeof(addr));
+        if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
+            ret = 0;
+            break;
+        }
+        switch (addr.sa.sa_family) {
+        case AF_INET:
+            sockopt_val = IP_PMTUDISC_DO;
+            if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
+                                  &sockopt_val, sizeof(sockopt_val))) < 0)
+                perror("setsockopt");
+            break;
+#  if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
+        case AF_INET6:
+            sockopt_val = IPV6_PMTUDISC_DO;
+            if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
+                                  &sockopt_val, sizeof(sockopt_val))) < 0)
+                perror("setsockopt");
+            break;
+#  endif
+        default:
+            ret = -1;
+            break;
+        }
+# else
+        ret = -1;
+# endif
+        break;
+    case BIO_CTRL_DGRAM_QUERY_MTU:
+# if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU)
+        addr_len = (socklen_t) sizeof(addr);
+        memset(&addr, 0, sizeof(addr));
+        if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
+            ret = 0;
+            break;
+        }
+        sockopt_len = sizeof(sockopt_val);
+        switch (addr.sa.sa_family) {
+        case AF_INET:
+            if ((ret =
+                 getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val,
+                            &sockopt_len)) < 0 || sockopt_val < 0) {
+                ret = 0;
+            } else {
+                /*
+                 * we assume that the transport protocol is UDP and no IP
+                 * options are used.
+                 */
+                data->mtu = sockopt_val - 8 - 20;
+                ret = data->mtu;
+            }
+            break;
+#  if OPENSSL_USE_IPV6 && defined(IPV6_MTU)
+        case AF_INET6:
+            if ((ret =
+                 getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU,
+                            (void *)&sockopt_val, &sockopt_len)) < 0
+                || sockopt_val < 0) {
+                ret = 0;
+            } else {
+                /*
+                 * we assume that the transport protocol is UDP and no IPV6
+                 * options are used.
+                 */
+                data->mtu = sockopt_val - 8 - 40;
+                ret = data->mtu;
+            }
+            break;
+#  endif
+        default:
+            ret = 0;
+            break;
+        }
+# else
+        ret = 0;
+# endif
+        break;
+    case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
+        ret = -dgram_get_mtu_overhead(data);
+        switch (BIO_ADDR_family(&data->peer)) {
+        case AF_INET:
+            ret += 576;
+            break;
+# if OPENSSL_USE_IPV6
+        case AF_INET6:
+            {
+#  ifdef IN6_IS_ADDR_V4MAPPED
+                struct in6_addr tmp_addr;
+                if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL)
+                    && IN6_IS_ADDR_V4MAPPED(&tmp_addr))
+                    ret += 576;
+                else
+#  endif
+                    ret += 1280;
+            }
+            break;
+# endif
+        default:
+            ret += 576;
+            break;
+        }
+        break;
+    case BIO_CTRL_DGRAM_GET_MTU:
+        return data->mtu;
+    case BIO_CTRL_DGRAM_SET_MTU:
+        data->mtu = num;
+        ret = num;
+        break;
+    case BIO_CTRL_DGRAM_SET_CONNECTED:
+        if (ptr != NULL) {
+            data->connected = 1;
+            BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
+        } else {
+            data->connected = 0;
+            memset(&data->peer, 0, sizeof(data->peer));
+        }
+        break;
+    case BIO_CTRL_DGRAM_GET_PEER:
+        ret = BIO_ADDR_sockaddr_size(&data->peer);
+        /* FIXME: if num < ret, we will only return part of an address.
+           That should bee an error, no? */
+        if (num == 0 || num > ret)
+            num = ret;
+        memcpy(ptr, &data->peer, (ret = num));
+        break;
+    case BIO_CTRL_DGRAM_SET_PEER:
+        BIO_ADDR_make(&data->peer, BIO_ADDR_sockaddr((BIO_ADDR *)ptr));
+        break;
+    case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
+        memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
+        break;
+# if defined(SO_RCVTIMEO)
+    case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
+#  ifdef OPENSSL_SYS_WINDOWS
+        {
+            struct timeval *tv = (struct timeval *)ptr;
+            int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
+            if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+                           (void *)&timeout, sizeof(timeout)) < 0) {
+                perror("setsockopt");
+                ret = -1;
+            }
+        }
+#  else
+        if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
+                       sizeof(struct timeval)) < 0) {
+            perror("setsockopt");
+            ret = -1;
+        }
+#  endif
+        break;
+    case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
+        {
+            union {
+                size_t s;
+                int i;
+            } sz = {
+                0
+            };
+#  ifdef OPENSSL_SYS_WINDOWS
+            int timeout;
+            struct timeval *tv = (struct timeval *)ptr;
+
+            sz.i = sizeof(timeout);
+            if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+                           (void *)&timeout, &sz.i) < 0) {
+                perror("getsockopt");
+                ret = -1;
+            } else {
+                tv->tv_sec = timeout / 1000;
+                tv->tv_usec = (timeout % 1000) * 1000;
+                ret = sizeof(*tv);
+            }
+#  else
+            sz.i = sizeof(struct timeval);
+            if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+                           ptr, (void *)&sz) < 0) {
+                perror("getsockopt");
+                ret = -1;
+            } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) {
+                OPENSSL_assert(sz.s <= sizeof(struct timeval));
+                ret = (int)sz.s;
+            } else
+                ret = sz.i;
+#  endif
+        }
+        break;
+# endif
+# if defined(SO_SNDTIMEO)
+    case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
+#  ifdef OPENSSL_SYS_WINDOWS
+        {
+            struct timeval *tv = (struct timeval *)ptr;
+            int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;
+            if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
+                           (void *)&timeout, sizeof(timeout)) < 0) {
+                perror("setsockopt");
+                ret = -1;
+            }
+        }
+#  else
+        if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
+                       sizeof(struct timeval)) < 0) {
+            perror("setsockopt");
+            ret = -1;
+        }
+#  endif
+        break;
+    case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
+        {
+            union {
+                size_t s;
+                int i;
+            } sz = {
+                0
+            };
+#  ifdef OPENSSL_SYS_WINDOWS
+            int timeout;
+            struct timeval *tv = (struct timeval *)ptr;
+
+            sz.i = sizeof(timeout);
+            if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
+                           (void *)&timeout, &sz.i) < 0) {
+                perror("getsockopt");
+                ret = -1;
+            } else {
+                tv->tv_sec = timeout / 1000;
+                tv->tv_usec = (timeout % 1000) * 1000;
+                ret = sizeof(*tv);
+            }
+#  else
+            sz.i = sizeof(struct timeval);
+            if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
+                           ptr, (void *)&sz) < 0) {
+                perror("getsockopt");
+                ret = -1;
+            } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) {
+                OPENSSL_assert(sz.s <= sizeof(struct timeval));
+                ret = (int)sz.s;
+            } else
+                ret = sz.i;
+#  endif
+        }
+        break;
+# endif
+    case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
+        /* fall-through */
+    case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
+# ifdef OPENSSL_SYS_WINDOWS
+        d_errno = (data->_errno == WSAETIMEDOUT);
+# else
+        d_errno = (data->_errno == EAGAIN);
+# endif
+        if (d_errno) {
+            ret = 1;
+            data->_errno = 0;
+        } else
+            ret = 0;
+        break;
+# ifdef EMSGSIZE
+    case BIO_CTRL_DGRAM_MTU_EXCEEDED:
+        if (data->_errno == EMSGSIZE) {
+            ret = 1;
+            data->_errno = 0;
+        } else
+            ret = 0;
+        break;
+# endif
+    case BIO_CTRL_DGRAM_SET_DONT_FRAG:
+        sockopt_val = num ? 1 : 0;
+
+        switch (data->peer.sa.sa_family) {
+        case AF_INET:
+# if defined(IP_DONTFRAG)
+            if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAG,
+                                  &sockopt_val, sizeof(sockopt_val))) < 0) {
+                perror("setsockopt");
+                ret = -1;
+            }
+# elif defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined (IP_PMTUDISC_PROBE)
+            if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
+                (ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER,
+                                  &sockopt_val, sizeof(sockopt_val))) < 0) {
+                perror("setsockopt");
+                ret = -1;
+            }
+# elif defined(OPENSSL_SYS_WINDOWS) && defined(IP_DONTFRAGMENT)
+            if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAGMENT,
+                                  (const char *)&sockopt_val,
+                                  sizeof(sockopt_val))) < 0) {
+                perror("setsockopt");
+                ret = -1;
+            }
+# else
+            ret = -1;
+# endif
+            break;
+# if OPENSSL_USE_IPV6
+        case AF_INET6:
+#  if defined(IPV6_DONTFRAG)
+            if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_DONTFRAG,
+                                  (const void *)&sockopt_val,
+                                  sizeof(sockopt_val))) < 0) {
+                perror("setsockopt");
+                ret = -1;
+            }
+#  elif defined(OPENSSL_SYS_LINUX) && defined(IPV6_MTUDISCOVER)
+            if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT),
+                (ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
+                                  &sockopt_val, sizeof(sockopt_val))) < 0) {
+                perror("setsockopt");
+                ret = -1;
+            }
+#  else
+            ret = -1;
+#  endif
+            break;
+# endif
+        default:
+            ret = -1;
+            break;
+        }
+        break;
+    case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
+        ret = dgram_get_mtu_overhead(data);
+        break;
+    case BIO_CTRL_DGRAM_SET_PEEK_MODE:
+        data->peekmode = (unsigned int)num;
+        break;
+    default:
+        ret = 0;
+        break;
+    }
+    return (ret);
+}
+
+static int dgram_puts(BIO *bp, const char *str)
+{
+    int n, ret;
+
+    n = strlen(str);
+    ret = dgram_write(bp, str, n);
+    return (ret);
+}
+
+# ifndef OPENSSL_NO_SCTP
+const BIO_METHOD *BIO_s_datagram_sctp(void)
+{
+    return (&methods_dgramp_sctp);
+}
+
+BIO *BIO_new_dgram_sctp(int fd, int close_flag)
+{
+    BIO *bio;
+    int ret, optval = 20000;
+    int auth_data = 0, auth_forward = 0;
+    unsigned char *p;
+    struct sctp_authchunk auth;
+    struct sctp_authchunks *authchunks;
+    socklen_t sockopt_len;
+#  ifdef SCTP_AUTHENTICATION_EVENT
+#   ifdef SCTP_EVENT
+    struct sctp_event event;
+#   else
+    struct sctp_event_subscribe event;
+#   endif
+#  endif
+
+    bio = BIO_new(BIO_s_datagram_sctp());
+    if (bio == NULL)
+        return (NULL);
+    BIO_set_fd(bio, fd, close_flag);
+
+    /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */
+    auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE;
+    ret =
+        setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth,
+                   sizeof(struct sctp_authchunk));
+    if (ret < 0) {
+        BIO_vfree(bio);
+        return (NULL);
+    }
+    auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE;
+    ret =
+        setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth,
+                   sizeof(struct sctp_authchunk));
+    if (ret < 0) {
+        BIO_vfree(bio);
+        return (NULL);
+    }
+
+    /*
+     * Test if activation was successful. When using accept(), SCTP-AUTH has
+     * to be activated for the listening socket already, otherwise the
+     * connected socket won't use it.
+     */
+    sockopt_len = (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
+    authchunks = OPENSSL_zalloc(sockopt_len);
+    if (authchunks == NULL) {
+        BIO_vfree(bio);
+        return (NULL);
+    }
+    ret = getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks,
+                   &sockopt_len);
+    if (ret < 0) {
+        OPENSSL_free(authchunks);
+        BIO_vfree(bio);
+        return (NULL);
+    }
+
+    for (p = (unsigned char *)authchunks->gauth_chunks;
+         p < (unsigned char *)authchunks + sockopt_len;
+         p += sizeof(uint8_t)) {
+        if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE)
+            auth_data = 1;
+        if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE)
+            auth_forward = 1;
+    }
+
+    OPENSSL_free(authchunks);
+
+    OPENSSL_assert(auth_data);
+    OPENSSL_assert(auth_forward);
+
+#  ifdef SCTP_AUTHENTICATION_EVENT
+#   ifdef SCTP_EVENT
+    memset(&event, 0, sizeof(event));
+    event.se_assoc_id = 0;
+    event.se_type = SCTP_AUTHENTICATION_EVENT;
+    event.se_on = 1;
+    ret =
+        setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &event,
+                   sizeof(struct sctp_event));
+    if (ret < 0) {
+        BIO_vfree(bio);
+        return (NULL);
+    }
+#   else
+    sockopt_len = (socklen_t) sizeof(struct sctp_event_subscribe);
+    ret = getsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, &sockopt_len);
+    if (ret < 0) {
+        BIO_vfree(bio);
+        return (NULL);
+    }
+
+    event.sctp_authentication_event = 1;
+
+    ret =
+        setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event,
+                   sizeof(struct sctp_event_subscribe));
+    if (ret < 0) {
+        BIO_vfree(bio);
+        return (NULL);
+    }
+#   endif
+#  endif
+
+    /*
+     * Disable partial delivery by setting the min size larger than the max
+     * record size of 2^14 + 2048 + 13
+     */
+    ret =
+        setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval,
+                   sizeof(optval));
+    if (ret < 0) {
+        BIO_vfree(bio);
+        return (NULL);
+    }
+
+    return (bio);
+}
+
+int BIO_dgram_is_sctp(BIO *bio)
+{
+    return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP);
+}
+
+static int dgram_sctp_new(BIO *bi)
+{
+    bio_dgram_sctp_data *data = NULL;
+
+    bi->init = 0;
+    bi->num = 0;
+    data = OPENSSL_zalloc(sizeof(*data));
+    if (data == NULL)
+        return 0;
+#  ifdef SCTP_PR_SCTP_NONE
+    data->prinfo.pr_policy = SCTP_PR_SCTP_NONE;
+#  endif
+    bi->ptr = data;
+
+    bi->flags = 0;
+    return (1);
+}
+
+static int dgram_sctp_free(BIO *a)
+{
+    bio_dgram_sctp_data *data;
+
+    if (a == NULL)
+        return (0);
+    if (!dgram_clear(a))
+        return 0;
+
+    data = (bio_dgram_sctp_data *) a->ptr;
+    if (data != NULL) {
+        OPENSSL_free(data->saved_message.data);
+        OPENSSL_free(data);
+    }
+
+    return (1);
+}
+
+#  ifdef SCTP_AUTHENTICATION_EVENT
+void dgram_sctp_handle_auth_free_key_event(BIO *b,
+                                           union sctp_notification *snp)
+{
+    int ret;
+    struct sctp_authkey_event *authkeyevent = &snp->sn_auth_event;
+
+    if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY) {
+        struct sctp_authkeyid authkeyid;
+
+        /* delete key */
+        authkeyid.scact_keynumber = authkeyevent->auth_keynumber;
+        ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
+                         &authkeyid, sizeof(struct sctp_authkeyid));
+    }
+}
+#  endif
+
+static int dgram_sctp_read(BIO *b, char *out, int outl)
+{
+    int ret = 0, n = 0, i, optval;
+    socklen_t optlen;
+    bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
+    union sctp_notification *snp;
+    struct msghdr msg;
+    struct iovec iov;
+    struct cmsghdr *cmsg;
+    char cmsgbuf[512];
+
+    if (out != NULL) {
+        clear_socket_error();
+
+        do {
+            memset(&data->rcvinfo, 0, sizeof(data->rcvinfo));
+            iov.iov_base = out;
+            iov.iov_len = outl;
+            msg.msg_name = NULL;
+            msg.msg_namelen = 0;
+            msg.msg_iov = &iov;
+            msg.msg_iovlen = 1;
+            msg.msg_control = cmsgbuf;
+            msg.msg_controllen = 512;
+            msg.msg_flags = 0;
+            n = recvmsg(b->num, &msg, 0);
+
+            if (n <= 0) {
+                if (n < 0)
+                    ret = n;
+                break;
+            }
+
+            if (msg.msg_controllen > 0) {
+                for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
+                     cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+                    if (cmsg->cmsg_level != IPPROTO_SCTP)
+                        continue;
+#  ifdef SCTP_RCVINFO
+                    if (cmsg->cmsg_type == SCTP_RCVINFO) {
+                        struct sctp_rcvinfo *rcvinfo;
+
+                        rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg);
+                        data->rcvinfo.rcv_sid = rcvinfo->rcv_sid;
+                        data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn;
+                        data->rcvinfo.rcv_flags = rcvinfo->rcv_flags;
+                        data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid;
+                        data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn;
+                        data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn;
+                        data->rcvinfo.rcv_context = rcvinfo->rcv_context;
+                    }
+#  endif
+#  ifdef SCTP_SNDRCV
+                    if (cmsg->cmsg_type == SCTP_SNDRCV) {
+                        struct sctp_sndrcvinfo *sndrcvinfo;
+
+                        sndrcvinfo =
+                            (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+                        data->rcvinfo.rcv_sid = sndrcvinfo->sinfo_stream;
+                        data->rcvinfo.rcv_ssn = sndrcvinfo->sinfo_ssn;
+                        data->rcvinfo.rcv_flags = sndrcvinfo->sinfo_flags;
+                        data->rcvinfo.rcv_ppid = sndrcvinfo->sinfo_ppid;
+                        data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn;
+                        data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn;
+                        data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context;
+                    }
+#  endif
+                }
+            }
+
+            if (msg.msg_flags & MSG_NOTIFICATION) {
+                snp = (union sctp_notification *)out;
+                if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
+#  ifdef SCTP_EVENT
+                    struct sctp_event event;
+#  else
+                    struct sctp_event_subscribe event;
+                    socklen_t eventsize;
+#  endif
+                    /*
+                     * If a message has been delayed until the socket is dry,
+                     * it can be sent now.
+                     */
+                    if (data->saved_message.length > 0) {
+                        i = dgram_sctp_write(data->saved_message.bio,
+                                         data->saved_message.data,
+                                         data->saved_message.length);
+                        if (i < 0) {
+                            ret = i;
+                            break;
+                        }
+                        OPENSSL_free(data->saved_message.data);
+                        data->saved_message.data = NULL;
+                        data->saved_message.length = 0;
+                    }
+
+                    /* disable sender dry event */
+#  ifdef SCTP_EVENT
+                    memset(&event, 0, sizeof(event));
+                    event.se_assoc_id = 0;
+                    event.se_type = SCTP_SENDER_DRY_EVENT;
+                    event.se_on = 0;
+                    i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
+                                   sizeof(struct sctp_event));
+                    if (i < 0) {
+                        ret = i;
+                        break;
+                    }
+#  else
+                    eventsize = sizeof(struct sctp_event_subscribe);
+                    i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
+                                   &eventsize);
+                    if (i < 0) {
+                        ret = i;
+                        break;
+                    }
+
+                    event.sctp_sender_dry_event = 0;
+
+                    i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
+                                   sizeof(struct sctp_event_subscribe));
+                    if (i < 0) {
+                        ret = i;
+                        break;
+                    }
+#  endif
+                }
+#  ifdef SCTP_AUTHENTICATION_EVENT
+                if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
+                    dgram_sctp_handle_auth_free_key_event(b, snp);
+#  endif
+
+                if (data->handle_notifications != NULL)
+                    data->handle_notifications(b, data->notification_context,
+                                               (void *)out);
+
+                memset(out, 0, outl);
+            } else
+                ret += n;
+        }
+        while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR)
+               && (ret < outl));
+
+        if (ret > 0 && !(msg.msg_flags & MSG_EOR)) {
+            /* Partial message read, this should never happen! */
+
+            /*
+             * The buffer was too small, this means the peer sent a message
+             * that was larger than allowed.
+             */
+            if (ret == outl)
+                return -1;
+
+            /*
+             * Test if socket buffer can handle max record size (2^14 + 2048
+             * + 13)
+             */
+            optlen = (socklen_t) sizeof(int);
+            ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen);
+            if (ret >= 0)
+                OPENSSL_assert(optval >= 18445);
+
+            /*
+             * Test if SCTP doesn't partially deliver below max record size
+             * (2^14 + 2048 + 13)
+             */
+            optlen = (socklen_t) sizeof(int);
+            ret =
+                getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT,
+                           &optval, &optlen);
+            if (ret >= 0)
+                OPENSSL_assert(optval >= 18445);
+
+            /*
+             * Partially delivered notification??? Probably a bug....
+             */
+            OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION));
+
+            /*
+             * Everything seems ok till now, so it's most likely a message
+             * dropped by PR-SCTP.
+             */
+            memset(out, 0, outl);
+            BIO_set_retry_read(b);
+            return -1;
+        }
+
+        BIO_clear_retry_flags(b);
+        if (ret < 0) {
+            if (BIO_dgram_should_retry(ret)) {
+                BIO_set_retry_read(b);
+                data->_errno = get_last_socket_error();
+            }
+        }
+
+        /* Test if peer uses SCTP-AUTH before continuing */
+        if (!data->peer_auth_tested) {
+            int ii, auth_data = 0, auth_forward = 0;
+            unsigned char *p;
+            struct sctp_authchunks *authchunks;
+
+            optlen =
+                (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t));
+            authchunks = OPENSSL_malloc(optlen);
+            if (authchunks == NULL) {
+                BIOerr(BIO_F_DGRAM_SCTP_READ, ERR_R_MALLOC_FAILURE);
+                return -1;
+            }
+            memset(authchunks, 0, optlen);
+            ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS,
+                            authchunks, &optlen);
+
+            if (ii >= 0)
+                for (p = (unsigned char *)authchunks->gauth_chunks;
+                     p < (unsigned char *)authchunks + optlen;
+                     p += sizeof(uint8_t)) {
+                    if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE)
+                        auth_data = 1;
+                    if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE)
+                        auth_forward = 1;
+                }
+
+            OPENSSL_free(authchunks);
+
+            if (!auth_data || !auth_forward) {
+                BIOerr(BIO_F_DGRAM_SCTP_READ, BIO_R_CONNECT_ERROR);
+                return -1;
+            }
+
+            data->peer_auth_tested = 1;
+        }
+    }
+    return (ret);
+}
+
+/*
+ * dgram_sctp_write - send message on SCTP socket
+ * @b: BIO to write to
+ * @in: data to send
+ * @inl: amount of bytes in @in to send
+ *
+ * Returns -1 on error or the sent amount of bytes on success
+ */
+static int dgram_sctp_write(BIO *b, const char *in, int inl)
+{
+    int ret;
+    bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
+    struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo);
+    struct bio_dgram_sctp_prinfo *pinfo = &(data->prinfo);
+    struct bio_dgram_sctp_sndinfo handshake_sinfo;
+    struct iovec iov[1];
+    struct msghdr msg;
+    struct cmsghdr *cmsg;
+#  if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
+    char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo)) +
+                 CMSG_SPACE(sizeof(struct sctp_prinfo))];
+    struct sctp_sndinfo *sndinfo;
+    struct sctp_prinfo *prinfo;
+#  else
+    char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
+    struct sctp_sndrcvinfo *sndrcvinfo;
+#  endif
+
+    clear_socket_error();
+
+    /*
+     * If we're send anything else than application data, disable all user
+     * parameters and flags.
+     */
+    if (in[0] != 23) {
+        memset(&handshake_sinfo, 0, sizeof(handshake_sinfo));
+#  ifdef SCTP_SACK_IMMEDIATELY
+        handshake_sinfo.snd_flags = SCTP_SACK_IMMEDIATELY;
+#  endif
+        sinfo = &handshake_sinfo;
+    }
+
+    /*
+     * If we have to send a shutdown alert message and the socket is not dry
+     * yet, we have to save it and send it as soon as the socket gets dry.
+     */
+    if (data->save_shutdown) {
+        ret = BIO_dgram_sctp_wait_for_dry(b);
+        if (ret < 0) {
+            return -1;
+        }
+        if (ret == 0) {
+            char *tmp;
+            data->saved_message.bio = b;
+            if ((tmp = OPENSSL_malloc(inl)) == NULL) {
+                BIOerr(BIO_F_DGRAM_SCTP_WRITE, ERR_R_MALLOC_FAILURE);
+                return -1;
+            }
+            OPENSSL_free(data->saved_message.data);
+            data->saved_message.data = tmp;
+            memcpy(data->saved_message.data, in, inl);
+            data->saved_message.length = inl;
+            return inl;
+        }
+    }
+
+    iov[0].iov_base = (char *)in;
+    iov[0].iov_len = inl;
+    msg.msg_name = NULL;
+    msg.msg_namelen = 0;
+    msg.msg_iov = iov;
+    msg.msg_iovlen = 1;
+    msg.msg_control = (caddr_t) cmsgbuf;
+    msg.msg_controllen = 0;
+    msg.msg_flags = 0;
+#  if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO)
+    cmsg = (struct cmsghdr *)cmsgbuf;
+    cmsg->cmsg_level = IPPROTO_SCTP;
+    cmsg->cmsg_type = SCTP_SNDINFO;
+    cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo));
+    sndinfo = (struct sctp_sndinfo *)CMSG_DATA(cmsg);
+    memset(sndinfo, 0, sizeof(*sndinfo));
+    sndinfo->snd_sid = sinfo->snd_sid;
+    sndinfo->snd_flags = sinfo->snd_flags;
+    sndinfo->snd_ppid = sinfo->snd_ppid;
+    sndinfo->snd_context = sinfo->snd_context;
+    msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo));
+
+    cmsg =
+        (struct cmsghdr *)&cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo))];
+    cmsg->cmsg_level = IPPROTO_SCTP;
+    cmsg->cmsg_type = SCTP_PRINFO;
+    cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo));
+    prinfo = (struct sctp_prinfo *)CMSG_DATA(cmsg);
+    memset(prinfo, 0, sizeof(*prinfo));
+    prinfo->pr_policy = pinfo->pr_policy;
+    prinfo->pr_value = pinfo->pr_value;
+    msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo));
+#  else
+    cmsg = (struct cmsghdr *)cmsgbuf;
+    cmsg->cmsg_level = IPPROTO_SCTP;
+    cmsg->cmsg_type = SCTP_SNDRCV;
+    cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
+    sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+    memset(sndrcvinfo, 0, sizeof(*sndrcvinfo));
+    sndrcvinfo->sinfo_stream = sinfo->snd_sid;
+    sndrcvinfo->sinfo_flags = sinfo->snd_flags;
+#   ifdef __FreeBSD__
+    sndrcvinfo->sinfo_flags |= pinfo->pr_policy;
+#   endif
+    sndrcvinfo->sinfo_ppid = sinfo->snd_ppid;
+    sndrcvinfo->sinfo_context = sinfo->snd_context;
+    sndrcvinfo->sinfo_timetolive = pinfo->pr_value;
+    msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo));
+#  endif
+
+    ret = sendmsg(b->num, &msg, 0);
+
+    BIO_clear_retry_flags(b);
+    if (ret <= 0) {
+        if (BIO_dgram_should_retry(ret)) {
+            BIO_set_retry_write(b);
+            data->_errno = get_last_socket_error();
+        }
+    }
+    return (ret);
+}
+
+static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    long ret = 1;
+    bio_dgram_sctp_data *data = NULL;
+    socklen_t sockopt_len = 0;
+    struct sctp_authkeyid authkeyid;
+    struct sctp_authkey *authkey = NULL;
+
+    data = (bio_dgram_sctp_data *) b->ptr;
+
+    switch (cmd) {
+    case BIO_CTRL_DGRAM_QUERY_MTU:
+        /*
+         * Set to maximum (2^14) and ignore user input to enable transport
+         * protocol fragmentation. Returns always 2^14.
+         */
+        data->mtu = 16384;
+        ret = data->mtu;
+        break;
+    case BIO_CTRL_DGRAM_SET_MTU:
+        /*
+         * Set to maximum (2^14) and ignore input to enable transport
+         * protocol fragmentation. Returns always 2^14.
+         */
+        data->mtu = 16384;
+        ret = data->mtu;
+        break;
+    case BIO_CTRL_DGRAM_SET_CONNECTED:
+    case BIO_CTRL_DGRAM_CONNECT:
+        /* Returns always -1. */
+        ret = -1;
+        break;
+    case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
+        /*
+         * SCTP doesn't need the DTLS timer Returns always 1.
+         */
+        break;
+    case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
+        /*
+         * We allow transport protocol fragmentation so this is irrelevant
+         */
+        ret = 0;
+        break;
+    case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE:
+        if (num > 0)
+            data->in_handshake = 1;
+        else
+            data->in_handshake = 0;
+
+        ret =
+            setsockopt(b->num, IPPROTO_SCTP, SCTP_NODELAY,
+                       &data->in_handshake, sizeof(int));
+        break;
+    case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY:
+        /*
+         * New shared key for SCTP AUTH. Returns 0 on success, -1 otherwise.
+         */
+
+        /* Get active key */
+        sockopt_len = sizeof(struct sctp_authkeyid);
+        ret =
+            getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid,
+                       &sockopt_len);
+        if (ret < 0)
+            break;
+
+        /* Add new key */
+        sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t);
+        authkey = OPENSSL_malloc(sockopt_len);
+        if (authkey == NULL) {
+            ret = -1;
+            break;
+        }
+        memset(authkey, 0, sockopt_len);
+        authkey->sca_keynumber = authkeyid.scact_keynumber + 1;
+#  ifndef __FreeBSD__
+        /*
+         * This field is missing in FreeBSD 8.2 and earlier, and FreeBSD 8.3
+         * and higher work without it.
+         */
+        authkey->sca_keylength = 64;
+#  endif
+        memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t));
+
+        ret =
+            setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey,
+                       sockopt_len);
+        OPENSSL_free(authkey);
+        authkey = NULL;
+        if (ret < 0)
+            break;
+
+        /* Reset active key */
+        ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
+                         &authkeyid, sizeof(struct sctp_authkeyid));
+        if (ret < 0)
+            break;
+
+        break;
+    case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY:
+        /* Returns 0 on success, -1 otherwise. */
+
+        /* Get active key */
+        sockopt_len = sizeof(struct sctp_authkeyid);
+        ret =
+            getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid,
+                       &sockopt_len);
+        if (ret < 0)
+            break;
+
+        /* Set active key */
+        authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1;
+        ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
+                         &authkeyid, sizeof(struct sctp_authkeyid));
+        if (ret < 0)
+            break;
+
+        /*
+         * CCS has been sent, so remember that and fall through to check if
+         * we need to deactivate an old key
+         */
+        data->ccs_sent = 1;
+
+    case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD:
+        /* Returns 0 on success, -1 otherwise. */
+
+        /*
+         * Has this command really been called or is this just a
+         * fall-through?
+         */
+        if (cmd == BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD)
+            data->ccs_rcvd = 1;
+
+        /*
+         * CSS has been both, received and sent, so deactivate an old key
+         */
+        if (data->ccs_rcvd == 1 && data->ccs_sent == 1) {
+            /* Get active key */
+            sockopt_len = sizeof(struct sctp_authkeyid);
+            ret =
+                getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
+                           &authkeyid, &sockopt_len);
+            if (ret < 0)
+                break;
+
+            /*
+             * Deactivate key or delete second last key if
+             * SCTP_AUTHENTICATION_EVENT is not available.
+             */
+            authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
+#  ifdef SCTP_AUTH_DEACTIVATE_KEY
+            sockopt_len = sizeof(struct sctp_authkeyid);
+            ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY,
+                             &authkeyid, sockopt_len);
+            if (ret < 0)
+                break;
+#  endif
+#  ifndef SCTP_AUTHENTICATION_EVENT
+            if (authkeyid.scact_keynumber > 0) {
+                authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
+                ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
+                                 &authkeyid, sizeof(struct sctp_authkeyid));
+                if (ret < 0)
+                    break;
+            }
+#  endif
+
+            data->ccs_rcvd = 0;
+            data->ccs_sent = 0;
+        }
+        break;
+    case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO:
+        /* Returns the size of the copied struct. */
+        if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo))
+            num = sizeof(struct bio_dgram_sctp_sndinfo);
+
+        memcpy(ptr, &(data->sndinfo), num);
+        ret = num;
+        break;
+    case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO:
+        /* Returns the size of the copied struct. */
+        if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo))
+            num = sizeof(struct bio_dgram_sctp_sndinfo);
+
+        memcpy(&(data->sndinfo), ptr, num);
+        break;
+    case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO:
+        /* Returns the size of the copied struct. */
+        if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo))
+            num = sizeof(struct bio_dgram_sctp_rcvinfo);
+
+        memcpy(ptr, &data->rcvinfo, num);
+
+        ret = num;
+        break;
+    case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO:
+        /* Returns the size of the copied struct. */
+        if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo))
+            num = sizeof(struct bio_dgram_sctp_rcvinfo);
+
+        memcpy(&(data->rcvinfo), ptr, num);
+        break;
+    case BIO_CTRL_DGRAM_SCTP_GET_PRINFO:
+        /* Returns the size of the copied struct. */
+        if (num > (long)sizeof(struct bio_dgram_sctp_prinfo))
+            num = sizeof(struct bio_dgram_sctp_prinfo);
+
+        memcpy(ptr, &(data->prinfo), num);
+        ret = num;
+        break;
+    case BIO_CTRL_DGRAM_SCTP_SET_PRINFO:
+        /* Returns the size of the copied struct. */
+        if (num > (long)sizeof(struct bio_dgram_sctp_prinfo))
+            num = sizeof(struct bio_dgram_sctp_prinfo);
+
+        memcpy(&(data->prinfo), ptr, num);
+        break;
+    case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN:
+        /* Returns always 1. */
+        if (num > 0)
+            data->save_shutdown = 1;
+        else
+            data->save_shutdown = 0;
+        break;
+
+    default:
+        /*
+         * Pass to default ctrl function to process SCTP unspecific commands
+         */
+        ret = dgram_ctrl(b, cmd, num, ptr);
+        break;
+    }
+    return (ret);
+}
+
+int BIO_dgram_sctp_notification_cb(BIO *b,
+                                   void (*handle_notifications) (BIO *bio,
+                                                                 void
+                                                                 *context,
+                                                                 void *buf),
+                                   void *context)
+{
+    bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
+
+    if (handle_notifications != NULL) {
+        data->handle_notifications = handle_notifications;
+        data->notification_context = context;
+    } else
+        return -1;
+
+    return 0;
+}
+
+/*
+ * BIO_dgram_sctp_wait_for_dry - Wait for SCTP SENDER_DRY event
+ * @b: The BIO to check for the dry event
+ *
+ * Wait until the peer confirms all packets have been received, and so that
+ * our kernel doesn't have anything to send anymore.  This is only received by
+ * the peer's kernel, not the application.
+ *
+ * Returns:
+ * -1 on error
+ *  0 when not dry yet
+ *  1 when dry
+ */
+int BIO_dgram_sctp_wait_for_dry(BIO *b)
+{
+    int is_dry = 0;
+    int sockflags = 0;
+    int n, ret;
+    union sctp_notification snp;
+    struct msghdr msg;
+    struct iovec iov;
+#  ifdef SCTP_EVENT
+    struct sctp_event event;
+#  else
+    struct sctp_event_subscribe event;
+    socklen_t eventsize;
+#  endif
+    bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
+
+    /* set sender dry event */
+#  ifdef SCTP_EVENT
+    memset(&event, 0, sizeof(event));
+    event.se_assoc_id = 0;
+    event.se_type = SCTP_SENDER_DRY_EVENT;
+    event.se_on = 1;
+    ret =
+        setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
+                   sizeof(struct sctp_event));
+#  else
+    eventsize = sizeof(struct sctp_event_subscribe);
+    ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
+    if (ret < 0)
+        return -1;
+
+    event.sctp_sender_dry_event = 1;
+
+    ret =
+        setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
+                   sizeof(struct sctp_event_subscribe));
+#  endif
+    if (ret < 0)
+        return -1;
+
+    /* peek for notification */
+    memset(&snp, 0, sizeof(snp));
+    iov.iov_base = (char *)&snp;
+    iov.iov_len = sizeof(union sctp_notification);
+    msg.msg_name = NULL;
+    msg.msg_namelen = 0;
+    msg.msg_iov = &iov;
+    msg.msg_iovlen = 1;
+    msg.msg_control = NULL;
+    msg.msg_controllen = 0;
+    msg.msg_flags = 0;
+
+    n = recvmsg(b->num, &msg, MSG_PEEK);
+    if (n <= 0) {
+        if ((n < 0) && (get_last_socket_error() != EAGAIN)
+            && (get_last_socket_error() != EWOULDBLOCK))
+            return -1;
+        else
+            return 0;
+    }
+
+    /* if we find a notification, process it and try again if necessary */
+    while (msg.msg_flags & MSG_NOTIFICATION) {
+        memset(&snp, 0, sizeof(snp));
+        iov.iov_base = (char *)&snp;
+        iov.iov_len = sizeof(union sctp_notification);
+        msg.msg_name = NULL;
+        msg.msg_namelen = 0;
+        msg.msg_iov = &iov;
+        msg.msg_iovlen = 1;
+        msg.msg_control = NULL;
+        msg.msg_controllen = 0;
+        msg.msg_flags = 0;
+
+        n = recvmsg(b->num, &msg, 0);
+        if (n <= 0) {
+            if ((n < 0) && (get_last_socket_error() != EAGAIN)
+                && (get_last_socket_error() != EWOULDBLOCK))
+                return -1;
+            else
+                return is_dry;
+        }
+
+        if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
+            is_dry = 1;
+
+            /* disable sender dry event */
+#  ifdef SCTP_EVENT
+            memset(&event, 0, sizeof(event));
+            event.se_assoc_id = 0;
+            event.se_type = SCTP_SENDER_DRY_EVENT;
+            event.se_on = 0;
+            ret =
+                setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
+                           sizeof(struct sctp_event));
+#  else
+            eventsize = (socklen_t) sizeof(struct sctp_event_subscribe);
+            ret =
+                getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
+                           &eventsize);
+            if (ret < 0)
+                return -1;
+
+            event.sctp_sender_dry_event = 0;
+
+            ret =
+                setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
+                           sizeof(struct sctp_event_subscribe));
+#  endif
+            if (ret < 0)
+                return -1;
+        }
+#  ifdef SCTP_AUTHENTICATION_EVENT
+        if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
+            dgram_sctp_handle_auth_free_key_event(b, &snp);
+#  endif
+
+        if (data->handle_notifications != NULL)
+            data->handle_notifications(b, data->notification_context,
+                                       (void *)&snp);
+
+        /* found notification, peek again */
+        memset(&snp, 0, sizeof(snp));
+        iov.iov_base = (char *)&snp;
+        iov.iov_len = sizeof(union sctp_notification);
+        msg.msg_name = NULL;
+        msg.msg_namelen = 0;
+        msg.msg_iov = &iov;
+        msg.msg_iovlen = 1;
+        msg.msg_control = NULL;
+        msg.msg_controllen = 0;
+        msg.msg_flags = 0;
+
+        /* if we have seen the dry already, don't wait */
+        if (is_dry) {
+            sockflags = fcntl(b->num, F_GETFL, 0);
+            fcntl(b->num, F_SETFL, O_NONBLOCK);
+        }
+
+        n = recvmsg(b->num, &msg, MSG_PEEK);
+
+        if (is_dry) {
+            fcntl(b->num, F_SETFL, sockflags);
+        }
+
+        if (n <= 0) {
+            if ((n < 0) && (get_last_socket_error() != EAGAIN)
+                && (get_last_socket_error() != EWOULDBLOCK))
+                return -1;
+            else
+                return is_dry;
+        }
+    }
+
+    /* read anything else */
+    return is_dry;
+}
+
+int BIO_dgram_sctp_msg_waiting(BIO *b)
+{
+    int n, sockflags;
+    union sctp_notification snp;
+    struct msghdr msg;
+    struct iovec iov;
+    bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
+
+    /* Check if there are any messages waiting to be read */
+    do {
+        memset(&snp, 0, sizeof(snp));
+        iov.iov_base = (char *)&snp;
+        iov.iov_len = sizeof(union sctp_notification);
+        msg.msg_name = NULL;
+        msg.msg_namelen = 0;
+        msg.msg_iov = &iov;
+        msg.msg_iovlen = 1;
+        msg.msg_control = NULL;
+        msg.msg_controllen = 0;
+        msg.msg_flags = 0;
+
+        sockflags = fcntl(b->num, F_GETFL, 0);
+        fcntl(b->num, F_SETFL, O_NONBLOCK);
+        n = recvmsg(b->num, &msg, MSG_PEEK);
+        fcntl(b->num, F_SETFL, sockflags);
+
+        /* if notification, process and try again */
+        if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)) {
+#  ifdef SCTP_AUTHENTICATION_EVENT
+            if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
+                dgram_sctp_handle_auth_free_key_event(b, &snp);
+#  endif
+
+            memset(&snp, 0, sizeof(snp));
+            iov.iov_base = (char *)&snp;
+            iov.iov_len = sizeof(union sctp_notification);
+            msg.msg_name = NULL;
+            msg.msg_namelen = 0;
+            msg.msg_iov = &iov;
+            msg.msg_iovlen = 1;
+            msg.msg_control = NULL;
+            msg.msg_controllen = 0;
+            msg.msg_flags = 0;
+            n = recvmsg(b->num, &msg, 0);
+
+            if (data->handle_notifications != NULL)
+                data->handle_notifications(b, data->notification_context,
+                                           (void *)&snp);
+        }
+
+    } while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION));
+
+    /* Return 1 if there is a message to be read, return 0 otherwise. */
+    if (n > 0)
+        return 1;
+    else
+        return 0;
+}
+
+static int dgram_sctp_puts(BIO *bp, const char *str)
+{
+    int n, ret;
+
+    n = strlen(str);
+    ret = dgram_sctp_write(bp, str, n);
+    return (ret);
+}
+# endif
+
+static int BIO_dgram_should_retry(int i)
+{
+    int err;
+
+    if ((i == 0) || (i == -1)) {
+        err = get_last_socket_error();
+
+# if defined(OPENSSL_SYS_WINDOWS)
+        /*
+         * If the socket return value (i) is -1 and err is unexpectedly 0 at
+         * this point, the error code was overwritten by another system call
+         * before this error handling is called.
+         */
+# endif
+
+        return (BIO_dgram_non_fatal_error(err));
+    }
+    return (0);
+}
+
+int BIO_dgram_non_fatal_error(int err)
+{
+    switch (err) {
+# if defined(OPENSSL_SYS_WINDOWS)
+#  if defined(WSAEWOULDBLOCK)
+    case WSAEWOULDBLOCK:
+#  endif
+# endif
+
+# ifdef EWOULDBLOCK
+#  ifdef WSAEWOULDBLOCK
+#   if WSAEWOULDBLOCK != EWOULDBLOCK
+    case EWOULDBLOCK:
+#   endif
+#  else
+    case EWOULDBLOCK:
+#  endif
+# endif
+
+# ifdef EINTR
+    case EINTR:
+# endif
+
+# ifdef EAGAIN
+#  if EWOULDBLOCK != EAGAIN
+    case EAGAIN:
+#  endif
+# endif
+
+# ifdef EPROTO
+    case EPROTO:
+# endif
+
+# ifdef EINPROGRESS
+    case EINPROGRESS:
+# endif
+
+# ifdef EALREADY
+    case EALREADY:
+# endif
+
+        return (1);
+        /* break; */
+    default:
+        break;
+    }
+    return (0);
+}
+
+static void get_current_time(struct timeval *t)
+{
+# if defined(_WIN32)
+    SYSTEMTIME st;
+    union {
+        unsigned __int64 ul;
+        FILETIME ft;
+    } now;
+
+    GetSystemTime(&st);
+    SystemTimeToFileTime(&st, &now.ft);
+#  ifdef  __MINGW32__
+    now.ul -= 116444736000000000ULL;
+#  else
+    now.ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */
+#  endif
+    t->tv_sec = (long)(now.ul / 10000000);
+    t->tv_usec = ((int)(now.ul % 10000000)) / 10;
+# elif defined(OPENSSL_SYS_VMS)
+    struct timeb tb;
+    ftime(&tb);
+    t->tv_sec = (long)tb.time;
+    t->tv_usec = (long)tb.millitm * 1000;
+# else
+    gettimeofday(t, NULL);
+# endif
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_fd.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_fd.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_fd.c	(revision 331)
@@ -0,0 +1,273 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <errno.h>
+
+#include "bio_lcl.h"
+
+#if defined(OPENSSL_NO_POSIX_IO)
+/*
+ * Dummy placeholder for BIO_s_fd...
+ */
+BIO *BIO_new_fd(int fd, int close_flag)
+{
+    return NULL;
+}
+
+int BIO_fd_non_fatal_error(int err)
+{
+    return 0;
+}
+
+int BIO_fd_should_retry(int i)
+{
+    return 0;
+}
+
+const BIO_METHOD *BIO_s_fd(void)
+{
+    return NULL;
+}
+#else
+/*
+ * As for unconditional usage of "UPLINK" interface in this module.
+ * Trouble is that unlike Unix file descriptors [which are indexes
+ * in kernel-side per-process table], corresponding descriptors on
+ * platforms which require "UPLINK" interface seem to be indexes
+ * in a user-land, non-global table. Well, in fact they are indexes
+ * in stdio _iob[], and recall that _iob[] was the very reason why
+ * "UPLINK" interface was introduced in first place. But one way on
+ * another. Neither libcrypto or libssl use this BIO meaning that
+ * file descriptors can only be provided by application. Therefore
+ * "UPLINK" calls are due...
+ */
+static int fd_write(BIO *h, const char *buf, int num);
+static int fd_read(BIO *h, char *buf, int size);
+static int fd_puts(BIO *h, const char *str);
+static int fd_gets(BIO *h, char *buf, int size);
+static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int fd_new(BIO *h);
+static int fd_free(BIO *data);
+int BIO_fd_should_retry(int s);
+
+static const BIO_METHOD methods_fdp = {
+    BIO_TYPE_FD, "file descriptor",
+    fd_write,
+    fd_read,
+    fd_puts,
+    fd_gets,
+    fd_ctrl,
+    fd_new,
+    fd_free,
+    NULL,
+};
+
+const BIO_METHOD *BIO_s_fd(void)
+{
+    return (&methods_fdp);
+}
+
+BIO *BIO_new_fd(int fd, int close_flag)
+{
+    BIO *ret;
+    ret = BIO_new(BIO_s_fd());
+    if (ret == NULL)
+        return (NULL);
+    BIO_set_fd(ret, fd, close_flag);
+    return (ret);
+}
+
+static int fd_new(BIO *bi)
+{
+    bi->init = 0;
+    bi->num = -1;
+    bi->ptr = NULL;
+    bi->flags = BIO_FLAGS_UPLINK; /* essentially redundant */
+    return (1);
+}
+
+static int fd_free(BIO *a)
+{
+    if (a == NULL)
+        return (0);
+    if (a->shutdown) {
+        if (a->init) {
+            UP_close(a->num);
+        }
+        a->init = 0;
+        a->flags = BIO_FLAGS_UPLINK;
+    }
+    return (1);
+}
+
+static int fd_read(BIO *b, char *out, int outl)
+{
+    int ret = 0;
+
+    if (out != NULL) {
+        clear_sys_error();
+        ret = UP_read(b->num, out, outl);
+        BIO_clear_retry_flags(b);
+        if (ret <= 0) {
+            if (BIO_fd_should_retry(ret))
+                BIO_set_retry_read(b);
+        }
+    }
+    return (ret);
+}
+
+static int fd_write(BIO *b, const char *in, int inl)
+{
+    int ret;
+    clear_sys_error();
+    ret = UP_write(b->num, in, inl);
+    BIO_clear_retry_flags(b);
+    if (ret <= 0) {
+        if (BIO_fd_should_retry(ret))
+            BIO_set_retry_write(b);
+    }
+    return (ret);
+}
+
+static long fd_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    long ret = 1;
+    int *ip;
+
+    switch (cmd) {
+    case BIO_CTRL_RESET:
+        num = 0;
+    case BIO_C_FILE_SEEK:
+        ret = (long)UP_lseek(b->num, num, 0);
+        break;
+    case BIO_C_FILE_TELL:
+    case BIO_CTRL_INFO:
+        ret = (long)UP_lseek(b->num, 0, 1);
+        break;
+    case BIO_C_SET_FD:
+        fd_free(b);
+        b->num = *((int *)ptr);
+        b->shutdown = (int)num;
+        b->init = 1;
+        break;
+    case BIO_C_GET_FD:
+        if (b->init) {
+            ip = (int *)ptr;
+            if (ip != NULL)
+                *ip = b->num;
+            ret = b->num;
+        } else
+            ret = -1;
+        break;
+    case BIO_CTRL_GET_CLOSE:
+        ret = b->shutdown;
+        break;
+    case BIO_CTRL_SET_CLOSE:
+        b->shutdown = (int)num;
+        break;
+    case BIO_CTRL_PENDING:
+    case BIO_CTRL_WPENDING:
+        ret = 0;
+        break;
+    case BIO_CTRL_DUP:
+    case BIO_CTRL_FLUSH:
+        ret = 1;
+        break;
+    default:
+        ret = 0;
+        break;
+    }
+    return (ret);
+}
+
+static int fd_puts(BIO *bp, const char *str)
+{
+    int n, ret;
+
+    n = strlen(str);
+    ret = fd_write(bp, str, n);
+    return (ret);
+}
+
+static int fd_gets(BIO *bp, char *buf, int size)
+{
+    int ret = 0;
+    char *ptr = buf;
+    char *end = buf + size - 1;
+
+    while ((ptr < end) && (fd_read(bp, ptr, 1) > 0) && (ptr[0] != '\n'))
+        ptr++;
+
+    ptr[0] = '\0';
+
+    if (buf[0] != '\0')
+        ret = strlen(buf);
+    return (ret);
+}
+
+int BIO_fd_should_retry(int i)
+{
+    int err;
+
+    if ((i == 0) || (i == -1)) {
+        err = get_last_sys_error();
+
+        return (BIO_fd_non_fatal_error(err));
+    }
+    return (0);
+}
+
+int BIO_fd_non_fatal_error(int err)
+{
+    switch (err) {
+
+# ifdef EWOULDBLOCK
+#  ifdef WSAEWOULDBLOCK
+#   if WSAEWOULDBLOCK != EWOULDBLOCK
+    case EWOULDBLOCK:
+#   endif
+#  else
+    case EWOULDBLOCK:
+#  endif
+# endif
+
+# if defined(ENOTCONN)
+    case ENOTCONN:
+# endif
+
+# ifdef EINTR
+    case EINTR:
+# endif
+
+# ifdef EAGAIN
+#  if EWOULDBLOCK != EAGAIN
+    case EAGAIN:
+#  endif
+# endif
+
+# ifdef EPROTO
+    case EPROTO:
+# endif
+
+# ifdef EINPROGRESS
+    case EINPROGRESS:
+# endif
+
+# ifdef EALREADY
+    case EALREADY:
+# endif
+        return (1);
+        /* break; */
+    default:
+        break;
+    }
+    return (0);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_file.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_file.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_file.c	(revision 331)
@@ -0,0 +1,419 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*-
+ * 03-Dec-1997  rdenny@dc3.com  Fix bug preventing use of stdin/stdout
+ *              with binary data (e.g. asn1parse -inform DER < xxx) under
+ *              Windows
+ */
+
+#ifndef HEADER_BSS_FILE_C
+# define HEADER_BSS_FILE_C
+
+# if defined(__linux) || defined(__sun) || defined(__hpux)
+/*
+ * Following definition aliases fopen to fopen64 on above mentioned
+ * platforms. This makes it possible to open and sequentially access files
+ * larger than 2GB from 32-bit application. It does not allow to traverse
+ * them beyond 2GB with fseek/ftell, but on the other hand *no* 32-bit
+ * platform permits that, not with fseek/ftell. Not to mention that breaking
+ * 2GB limit for seeking would require surgery to *our* API. But sequential
+ * access suffices for practical cases when you can run into large files,
+ * such as fingerprinting, so we can let API alone. For reference, the list
+ * of 32-bit platforms which allow for sequential access of large files
+ * without extra "magic" comprise *BSD, Darwin, IRIX...
+ */
+#  ifndef _FILE_OFFSET_BITS
+#   define _FILE_OFFSET_BITS 64
+#  endif
+# endif
+
+# include <stdio.h>
+# include <errno.h>
+# include "bio_lcl.h"
+# include <openssl/err.h>
+
+# if !defined(OPENSSL_NO_STDIO)
+
+static int file_write(BIO *h, const char *buf, int num);
+static int file_read(BIO *h, char *buf, int size);
+static int file_puts(BIO *h, const char *str);
+static int file_gets(BIO *h, char *str, int size);
+static long file_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int file_new(BIO *h);
+static int file_free(BIO *data);
+static const BIO_METHOD methods_filep = {
+    BIO_TYPE_FILE,
+    "FILE pointer",
+    file_write,
+    file_read,
+    file_puts,
+    file_gets,
+    file_ctrl,
+    file_new,
+    file_free,
+    NULL,
+};
+
+BIO *BIO_new_file(const char *filename, const char *mode)
+{
+    BIO  *ret;
+    FILE *file = openssl_fopen(filename, mode);
+    int fp_flags = BIO_CLOSE;
+
+    if (strchr(mode, 'b') == NULL)
+        fp_flags |= BIO_FP_TEXT;
+
+    if (file == NULL) {
+        SYSerr(SYS_F_FOPEN, get_last_sys_error());
+        ERR_add_error_data(5, "fopen('", filename, "','", mode, "')");
+        if (errno == ENOENT
+# ifdef ENXIO
+            || errno == ENXIO
+# endif
+            )
+            BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE);
+        else
+            BIOerr(BIO_F_BIO_NEW_FILE, ERR_R_SYS_LIB);
+        return (NULL);
+    }
+    if ((ret = BIO_new(BIO_s_file())) == NULL) {
+        fclose(file);
+        return (NULL);
+    }
+
+    BIO_clear_flags(ret, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage
+                                             * UPLINK */
+    BIO_set_fp(ret, file, fp_flags);
+    return (ret);
+}
+
+BIO *BIO_new_fp(FILE *stream, int close_flag)
+{
+    BIO *ret;
+
+    if ((ret = BIO_new(BIO_s_file())) == NULL)
+        return (NULL);
+
+    /* redundant flag, left for documentation purposes */
+    BIO_set_flags(ret, BIO_FLAGS_UPLINK);
+    BIO_set_fp(ret, stream, close_flag);
+    return (ret);
+}
+
+const BIO_METHOD *BIO_s_file(void)
+{
+    return (&methods_filep);
+}
+
+static int file_new(BIO *bi)
+{
+    bi->init = 0;
+    bi->num = 0;
+    bi->ptr = NULL;
+    bi->flags = BIO_FLAGS_UPLINK; /* default to UPLINK */
+    return (1);
+}
+
+static int file_free(BIO *a)
+{
+    if (a == NULL)
+        return (0);
+    if (a->shutdown) {
+        if ((a->init) && (a->ptr != NULL)) {
+            if (a->flags & BIO_FLAGS_UPLINK)
+                UP_fclose(a->ptr);
+            else
+                fclose(a->ptr);
+            a->ptr = NULL;
+            a->flags = BIO_FLAGS_UPLINK;
+        }
+        a->init = 0;
+    }
+    return (1);
+}
+
+static int file_read(BIO *b, char *out, int outl)
+{
+    int ret = 0;
+
+    if (b->init && (out != NULL)) {
+        if (b->flags & BIO_FLAGS_UPLINK)
+            ret = UP_fread(out, 1, (int)outl, b->ptr);
+        else
+            ret = fread(out, 1, (int)outl, (FILE *)b->ptr);
+        if (ret == 0
+            && (b->flags & BIO_FLAGS_UPLINK) ? UP_ferror((FILE *)b->ptr) :
+                                               ferror((FILE *)b->ptr)) {
+            SYSerr(SYS_F_FREAD, get_last_sys_error());
+            BIOerr(BIO_F_FILE_READ, ERR_R_SYS_LIB);
+            ret = -1;
+        }
+    }
+    return (ret);
+}
+
+static int file_write(BIO *b, const char *in, int inl)
+{
+    int ret = 0;
+
+    if (b->init && (in != NULL)) {
+        if (b->flags & BIO_FLAGS_UPLINK)
+            ret = UP_fwrite(in, (int)inl, 1, b->ptr);
+        else
+            ret = fwrite(in, (int)inl, 1, (FILE *)b->ptr);
+        if (ret)
+            ret = inl;
+        /* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */
+        /*
+         * according to Tim Hudson <tjh@cryptsoft.com>, the commented out
+         * version above can cause 'inl' write calls under some stupid stdio
+         * implementations (VMS)
+         */
+    }
+    return (ret);
+}
+
+static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    long ret = 1;
+    FILE *fp = (FILE *)b->ptr;
+    FILE **fpp;
+    char p[4];
+
+    switch (cmd) {
+    case BIO_C_FILE_SEEK:
+    case BIO_CTRL_RESET:
+        if (b->flags & BIO_FLAGS_UPLINK)
+            ret = (long)UP_fseek(b->ptr, num, 0);
+        else
+            ret = (long)fseek(fp, num, 0);
+        break;
+    case BIO_CTRL_EOF:
+        if (b->flags & BIO_FLAGS_UPLINK)
+            ret = (long)UP_feof(fp);
+        else
+            ret = (long)feof(fp);
+        break;
+    case BIO_C_FILE_TELL:
+    case BIO_CTRL_INFO:
+        if (b->flags & BIO_FLAGS_UPLINK)
+            ret = UP_ftell(b->ptr);
+        else
+            ret = ftell(fp);
+        break;
+    case BIO_C_SET_FILE_PTR:
+        file_free(b);
+        b->shutdown = (int)num & BIO_CLOSE;
+        b->ptr = ptr;
+        b->init = 1;
+#  if BIO_FLAGS_UPLINK!=0
+#   if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES)
+#    define _IOB_ENTRIES 20
+#   endif
+        /* Safety net to catch purely internal BIO_set_fp calls */
+#   if defined(_MSC_VER) && _MSC_VER>=1900
+        if (ptr == stdin || ptr == stdout || ptr == stderr)
+            BIO_clear_flags(b, BIO_FLAGS_UPLINK);
+#   elif defined(_IOB_ENTRIES)
+        if ((size_t)ptr >= (size_t)stdin &&
+            (size_t)ptr < (size_t)(stdin + _IOB_ENTRIES))
+            BIO_clear_flags(b, BIO_FLAGS_UPLINK);
+#   endif
+#  endif
+#  ifdef UP_fsetmod
+        if (b->flags & BIO_FLAGS_UPLINK)
+            UP_fsetmod(b->ptr, (char)((num & BIO_FP_TEXT) ? 't' : 'b'));
+        else
+#  endif
+        {
+#  if defined(OPENSSL_SYS_WINDOWS)
+            int fd = _fileno((FILE *)ptr);
+            if (num & BIO_FP_TEXT)
+                _setmode(fd, _O_TEXT);
+            else
+                _setmode(fd, _O_BINARY);
+#  elif defined(OPENSSL_SYS_MSDOS)
+            int fd = fileno((FILE *)ptr);
+            /* Set correct text/binary mode */
+            if (num & BIO_FP_TEXT)
+                _setmode(fd, _O_TEXT);
+            /* Dangerous to set stdin/stdout to raw (unless redirected) */
+            else {
+                if (fd == STDIN_FILENO || fd == STDOUT_FILENO) {
+                    if (isatty(fd) <= 0)
+                        _setmode(fd, _O_BINARY);
+                } else
+                    _setmode(fd, _O_BINARY);
+            }
+#  elif defined(OPENSSL_SYS_WIN32_CYGWIN)
+            int fd = fileno((FILE *)ptr);
+            if (num & BIO_FP_TEXT)
+                setmode(fd, O_TEXT);
+            else
+                setmode(fd, O_BINARY);
+#  endif
+        }
+        break;
+    case BIO_C_SET_FILENAME:
+        file_free(b);
+        b->shutdown = (int)num & BIO_CLOSE;
+        if (num & BIO_FP_APPEND) {
+            if (num & BIO_FP_READ)
+                OPENSSL_strlcpy(p, "a+", sizeof p);
+            else
+                OPENSSL_strlcpy(p, "a", sizeof p);
+        } else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE))
+            OPENSSL_strlcpy(p, "r+", sizeof p);
+        else if (num & BIO_FP_WRITE)
+            OPENSSL_strlcpy(p, "w", sizeof p);
+        else if (num & BIO_FP_READ)
+            OPENSSL_strlcpy(p, "r", sizeof p);
+        else {
+            BIOerr(BIO_F_FILE_CTRL, BIO_R_BAD_FOPEN_MODE);
+            ret = 0;
+            break;
+        }
+#  if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32_CYGWIN)
+        if (!(num & BIO_FP_TEXT))
+            strcat(p, "b");
+        else
+            strcat(p, "t");
+#  endif
+        fp = openssl_fopen(ptr, p);
+        if (fp == NULL) {
+            SYSerr(SYS_F_FOPEN, get_last_sys_error());
+            ERR_add_error_data(5, "fopen('", ptr, "','", p, "')");
+            BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB);
+            ret = 0;
+            break;
+        }
+        b->ptr = fp;
+        b->init = 1;
+        BIO_clear_flags(b, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage
+                                               * UPLINK */
+        break;
+    case BIO_C_GET_FILE_PTR:
+        /* the ptr parameter is actually a FILE ** in this case. */
+        if (ptr != NULL) {
+            fpp = (FILE **)ptr;
+            *fpp = (FILE *)b->ptr;
+        }
+        break;
+    case BIO_CTRL_GET_CLOSE:
+        ret = (long)b->shutdown;
+        break;
+    case BIO_CTRL_SET_CLOSE:
+        b->shutdown = (int)num;
+        break;
+    case BIO_CTRL_FLUSH:
+        if (b->flags & BIO_FLAGS_UPLINK)
+            UP_fflush(b->ptr);
+        else
+            fflush((FILE *)b->ptr);
+        break;
+    case BIO_CTRL_DUP:
+        ret = 1;
+        break;
+
+    case BIO_CTRL_WPENDING:
+    case BIO_CTRL_PENDING:
+    case BIO_CTRL_PUSH:
+    case BIO_CTRL_POP:
+    default:
+        ret = 0;
+        break;
+    }
+    return (ret);
+}
+
+static int file_gets(BIO *bp, char *buf, int size)
+{
+    int ret = 0;
+
+    buf[0] = '\0';
+    if (bp->flags & BIO_FLAGS_UPLINK) {
+        if (!UP_fgets(buf, size, bp->ptr))
+            goto err;
+    } else {
+        if (!fgets(buf, size, (FILE *)bp->ptr))
+            goto err;
+    }
+    if (buf[0] != '\0')
+        ret = strlen(buf);
+ err:
+    return (ret);
+}
+
+static int file_puts(BIO *bp, const char *str)
+{
+    int n, ret;
+
+    n = strlen(str);
+    ret = file_write(bp, str, n);
+    return (ret);
+}
+
+#else
+
+static int file_write(BIO *b, const char *in, int inl)
+{
+    return -1;
+}
+static int file_read(BIO *b, char *out, int outl)
+{
+    return -1;
+}
+static int file_puts(BIO *bp, const char *str)
+{
+    return -1;
+}
+static int file_gets(BIO *bp, char *buf, int size)
+{
+    return 0;
+}
+static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    return 0;
+}
+static int file_new(BIO *bi)
+{
+    return 0;
+}
+static int file_free(BIO *a)
+{
+    return 0;
+}
+
+static const BIO_METHOD methods_filep = {
+    BIO_TYPE_FILE,
+    "FILE pointer",
+    file_write,
+    file_read,
+    file_puts,
+    file_gets,
+    file_ctrl,
+    file_new,
+    file_free,
+    NULL,
+};
+
+const BIO_METHOD *BIO_s_file(void)
+{
+    return (&methods_filep);
+}
+
+BIO *BIO_new_file(const char *filename, const char *mode)
+{
+    return NULL;
+}
+
+# endif                         /* OPENSSL_NO_STDIO */
+
+#endif                          /* HEADER_BSS_FILE_C */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_log.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_log.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_log.c	(revision 331)
@@ -0,0 +1,406 @@
+/*
+ * Copyright 1999-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
+ */
+
+/*
+ * Why BIO_s_log?
+ *
+ * BIO_s_log is useful for system daemons (or services under NT). It is
+ * one-way BIO, it sends all stuff to syslogd (on system that commonly use
+ * that), or event log (on NT), or OPCOM (on OpenVMS).
+ *
+ */
+
+#include <stdio.h>
+#include <errno.h>
+
+#include "bio_lcl.h"
+#include "internal/cryptlib.h"
+
+#if defined(OPENSSL_SYS_WINCE)
+#elif defined(OPENSSL_SYS_WIN32)
+#elif defined(OPENSSL_SYS_VMS)
+# include <opcdef.h>
+# include <descrip.h>
+# include <lib$routines.h>
+# include <starlet.h>
+/* Some compiler options may mask the declaration of "_malloc32". */
+# if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE
+#  if __INITIAL_POINTER_SIZE == 64
+#   pragma pointer_size save
+#   pragma pointer_size 32
+void *_malloc32(__size_t);
+#   pragma pointer_size restore
+#  endif                        /* __INITIAL_POINTER_SIZE == 64 */
+# endif                         /* __INITIAL_POINTER_SIZE && defined
+                                 * _ANSI_C_SOURCE */
+#elif defined(OPENSSL_SYS_NETWARE)
+# define NO_SYSLOG
+#elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG)
+# include <syslog.h>
+#endif
+
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+
+#ifndef NO_SYSLOG
+
+# if defined(OPENSSL_SYS_WIN32)
+#  define LOG_EMERG       0
+#  define LOG_ALERT       1
+#  define LOG_CRIT        2
+#  define LOG_ERR         3
+#  define LOG_WARNING     4
+#  define LOG_NOTICE      5
+#  define LOG_INFO        6
+#  define LOG_DEBUG       7
+
+#  define LOG_DAEMON      (3<<3)
+# elif defined(OPENSSL_SYS_VMS)
+/* On VMS, we don't really care about these, but we need them to compile */
+#  define LOG_EMERG       0
+#  define LOG_ALERT       1
+#  define LOG_CRIT        2
+#  define LOG_ERR         3
+#  define LOG_WARNING     4
+#  define LOG_NOTICE      5
+#  define LOG_INFO        6
+#  define LOG_DEBUG       7
+
+#  define LOG_DAEMON      OPC$M_NM_NTWORK
+# endif
+
+static int slg_write(BIO *h, const char *buf, int num);
+static int slg_puts(BIO *h, const char *str);
+static long slg_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int slg_new(BIO *h);
+static int slg_free(BIO *data);
+static void xopenlog(BIO *bp, char *name, int level);
+static void xsyslog(BIO *bp, int priority, const char *string);
+static void xcloselog(BIO *bp);
+
+static const BIO_METHOD methods_slg = {
+    BIO_TYPE_MEM, "syslog",
+    slg_write,
+    NULL,
+    slg_puts,
+    NULL,
+    slg_ctrl,
+    slg_new,
+    slg_free,
+    NULL,
+};
+
+const BIO_METHOD *BIO_s_log(void)
+{
+    return (&methods_slg);
+}
+
+static int slg_new(BIO *bi)
+{
+    bi->init = 1;
+    bi->num = 0;
+    bi->ptr = NULL;
+    xopenlog(bi, "application", LOG_DAEMON);
+    return (1);
+}
+
+static int slg_free(BIO *a)
+{
+    if (a == NULL)
+        return (0);
+    xcloselog(a);
+    return (1);
+}
+
+static int slg_write(BIO *b, const char *in, int inl)
+{
+    int ret = inl;
+    char *buf;
+    char *pp;
+    int priority, i;
+    static const struct {
+        int strl;
+        char str[10];
+        int log_level;
+    } mapping[] = {
+        {
+            6, "PANIC ", LOG_EMERG
+        },
+        {
+            6, "EMERG ", LOG_EMERG
+        },
+        {
+            4, "EMR ", LOG_EMERG
+        },
+        {
+            6, "ALERT ", LOG_ALERT
+        },
+        {
+            4, "ALR ", LOG_ALERT
+        },
+        {
+            5, "CRIT ", LOG_CRIT
+        },
+        {
+            4, "CRI ", LOG_CRIT
+        },
+        {
+            6, "ERROR ", LOG_ERR
+        },
+        {
+            4, "ERR ", LOG_ERR
+        },
+        {
+            8, "WARNING ", LOG_WARNING
+        },
+        {
+            5, "WARN ", LOG_WARNING
+        },
+        {
+            4, "WAR ", LOG_WARNING
+        },
+        {
+            7, "NOTICE ", LOG_NOTICE
+        },
+        {
+            5, "NOTE ", LOG_NOTICE
+        },
+        {
+            4, "NOT ", LOG_NOTICE
+        },
+        {
+            5, "INFO ", LOG_INFO
+        },
+        {
+            4, "INF ", LOG_INFO
+        },
+        {
+            6, "DEBUG ", LOG_DEBUG
+        },
+        {
+            4, "DBG ", LOG_DEBUG
+        },
+        {
+            0, "", LOG_ERR
+        }
+        /* The default */
+    };
+
+    if ((buf = OPENSSL_malloc(inl + 1)) == NULL) {
+        return (0);
+    }
+    strncpy(buf, in, inl);
+    buf[inl] = '\0';
+
+    i = 0;
+    while (strncmp(buf, mapping[i].str, mapping[i].strl) != 0)
+        i++;
+    priority = mapping[i].log_level;
+    pp = buf + mapping[i].strl;
+
+    xsyslog(b, priority, pp);
+
+    OPENSSL_free(buf);
+    return (ret);
+}
+
+static long slg_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    switch (cmd) {
+    case BIO_CTRL_SET:
+        xcloselog(b);
+        xopenlog(b, ptr, num);
+        break;
+    default:
+        break;
+    }
+    return (0);
+}
+
+static int slg_puts(BIO *bp, const char *str)
+{
+    int n, ret;
+
+    n = strlen(str);
+    ret = slg_write(bp, str, n);
+    return (ret);
+}
+
+# if defined(OPENSSL_SYS_WIN32)
+
+static void xopenlog(BIO *bp, char *name, int level)
+{
+    if (check_winnt())
+        bp->ptr = RegisterEventSourceA(NULL, name);
+    else
+        bp->ptr = NULL;
+}
+
+static void xsyslog(BIO *bp, int priority, const char *string)
+{
+    LPCSTR lpszStrings[2];
+    WORD evtype = EVENTLOG_ERROR_TYPE;
+    char pidbuf[DECIMAL_SIZE(DWORD) + 4];
+
+    if (bp->ptr == NULL)
+        return;
+
+    switch (priority) {
+    case LOG_EMERG:
+    case LOG_ALERT:
+    case LOG_CRIT:
+    case LOG_ERR:
+        evtype = EVENTLOG_ERROR_TYPE;
+        break;
+    case LOG_WARNING:
+        evtype = EVENTLOG_WARNING_TYPE;
+        break;
+    case LOG_NOTICE:
+    case LOG_INFO:
+    case LOG_DEBUG:
+        evtype = EVENTLOG_INFORMATION_TYPE;
+        break;
+    default:
+        /*
+         * Should never happen, but set it
+         * as error anyway.
+         */
+        evtype = EVENTLOG_ERROR_TYPE;
+        break;
+    }
+
+    sprintf(pidbuf, "[%lu] ", GetCurrentProcessId());
+    lpszStrings[0] = pidbuf;
+    lpszStrings[1] = string;
+
+    ReportEventA(bp->ptr, evtype, 0, 1024, NULL, 2, 0, lpszStrings, NULL);
+}
+
+static void xcloselog(BIO *bp)
+{
+    if (bp->ptr)
+        DeregisterEventSource((HANDLE) (bp->ptr));
+    bp->ptr = NULL;
+}
+
+# elif defined(OPENSSL_SYS_VMS)
+
+static int VMS_OPC_target = LOG_DAEMON;
+
+static void xopenlog(BIO *bp, char *name, int level)
+{
+    VMS_OPC_target = level;
+}
+
+static void xsyslog(BIO *bp, int priority, const char *string)
+{
+    struct dsc$descriptor_s opc_dsc;
+
+/* Arrange 32-bit pointer to opcdef buffer and malloc(), if needed. */
+#  if __INITIAL_POINTER_SIZE == 64
+#   pragma pointer_size save
+#   pragma pointer_size 32
+#   define OPCDEF_TYPE __char_ptr32
+#   define OPCDEF_MALLOC _malloc32
+#  else                         /* __INITIAL_POINTER_SIZE == 64 */
+#   define OPCDEF_TYPE char *
+#   define OPCDEF_MALLOC OPENSSL_malloc
+#  endif                        /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+    struct opcdef *opcdef_p;
+
+#  if __INITIAL_POINTER_SIZE == 64
+#   pragma pointer_size restore
+#  endif                        /* __INITIAL_POINTER_SIZE == 64 */
+
+    char buf[10240];
+    unsigned int len;
+    struct dsc$descriptor_s buf_dsc;
+    $DESCRIPTOR(fao_cmd, "!AZ: !AZ");
+    char *priority_tag;
+
+    switch (priority) {
+    case LOG_EMERG:
+        priority_tag = "Emergency";
+        break;
+    case LOG_ALERT:
+        priority_tag = "Alert";
+        break;
+    case LOG_CRIT:
+        priority_tag = "Critical";
+        break;
+    case LOG_ERR:
+        priority_tag = "Error";
+        break;
+    case LOG_WARNING:
+        priority_tag = "Warning";
+        break;
+    case LOG_NOTICE:
+        priority_tag = "Notice";
+        break;
+    case LOG_INFO:
+        priority_tag = "Info";
+        break;
+    case LOG_DEBUG:
+        priority_tag = "DEBUG";
+        break;
+    }
+
+    buf_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+    buf_dsc.dsc$b_class = DSC$K_CLASS_S;
+    buf_dsc.dsc$a_pointer = buf;
+    buf_dsc.dsc$w_length = sizeof(buf) - 1;
+
+    lib$sys_fao(&fao_cmd, &len, &buf_dsc, priority_tag, string);
+
+    /* We know there's an 8-byte header.  That's documented. */
+    opcdef_p = OPCDEF_MALLOC(8 + len);
+    opcdef_p->opc$b_ms_type = OPC$_RQ_RQST;
+    memcpy(opcdef_p->opc$z_ms_target_classes, &VMS_OPC_target, 3);
+    opcdef_p->opc$l_ms_rqstid = 0;
+    memcpy(&opcdef_p->opc$l_ms_text, buf, len);
+
+    opc_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+    opc_dsc.dsc$b_class = DSC$K_CLASS_S;
+    opc_dsc.dsc$a_pointer = (OPCDEF_TYPE) opcdef_p;
+    opc_dsc.dsc$w_length = len + 8;
+
+    sys$sndopr(opc_dsc, 0);
+
+    OPENSSL_free(opcdef_p);
+}
+
+static void xcloselog(BIO *bp)
+{
+}
+
+# else                          /* Unix/Watt32 */
+
+static void xopenlog(BIO *bp, char *name, int level)
+{
+#  ifdef WATT32                 /* djgpp/DOS */
+    openlog(name, LOG_PID | LOG_CONS | LOG_NDELAY, level);
+#  else
+    openlog(name, LOG_PID | LOG_CONS, level);
+#  endif
+}
+
+static void xsyslog(BIO *bp, int priority, const char *string)
+{
+    syslog(priority, "%s", string);
+}
+
+static void xcloselog(BIO *bp)
+{
+    closelog();
+}
+
+# endif                         /* Unix */
+
+#endif                          /* NO_SYSLOG */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_mem.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_mem.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_mem.c	(revision 331)
@@ -0,0 +1,347 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <errno.h>
+#include "bio_lcl.h"
+#include "internal/cryptlib.h"
+
+static int mem_write(BIO *h, const char *buf, int num);
+static int mem_read(BIO *h, char *buf, int size);
+static int mem_puts(BIO *h, const char *str);
+static int mem_gets(BIO *h, char *str, int size);
+static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int mem_new(BIO *h);
+static int secmem_new(BIO *h);
+static int mem_free(BIO *data);
+static int mem_buf_free(BIO *data, int free_all);
+static int mem_buf_sync(BIO *h);
+
+static const BIO_METHOD mem_method = {
+    BIO_TYPE_MEM,
+    "memory buffer",
+    mem_write,
+    mem_read,
+    mem_puts,
+    mem_gets,
+    mem_ctrl,
+    mem_new,
+    mem_free,
+    NULL,
+};
+
+static const BIO_METHOD secmem_method = {
+    BIO_TYPE_MEM,
+    "secure memory buffer",
+    mem_write,
+    mem_read,
+    mem_puts,
+    mem_gets,
+    mem_ctrl,
+    secmem_new,
+    mem_free,
+    NULL,
+};
+
+/* BIO memory stores buffer and read pointer  */
+typedef struct bio_buf_mem_st {
+    struct buf_mem_st *buf;   /* allocated buffer */
+    struct buf_mem_st *readp; /* read pointer */
+} BIO_BUF_MEM;
+
+/*
+ * bio->num is used to hold the value to return on 'empty', if it is 0,
+ * should_retry is not set
+ */
+
+const BIO_METHOD *BIO_s_mem(void)
+{
+    return (&mem_method);
+}
+
+const BIO_METHOD *BIO_s_secmem(void)
+{
+    return(&secmem_method);
+}
+
+BIO *BIO_new_mem_buf(const void *buf, int len)
+{
+    BIO *ret;
+    BUF_MEM *b;
+    BIO_BUF_MEM *bb;
+    size_t sz;
+
+    if (buf == NULL) {
+        BIOerr(BIO_F_BIO_NEW_MEM_BUF, BIO_R_NULL_PARAMETER);
+        return NULL;
+    }
+    sz = (len < 0) ? strlen(buf) : (size_t)len;
+    if ((ret = BIO_new(BIO_s_mem())) == NULL)
+        return NULL;
+    bb = (BIO_BUF_MEM *)ret->ptr;
+    b = bb->buf;
+    /* Cast away const and trust in the MEM_RDONLY flag. */
+    b->data = (void *)buf;
+    b->length = sz;
+    b->max = sz;
+    *bb->readp = *bb->buf;
+    ret->flags |= BIO_FLAGS_MEM_RDONLY;
+    /* Since this is static data retrying won't help */
+    ret->num = 0;
+    return ret;
+}
+
+static int mem_init(BIO *bi, unsigned long flags)
+{
+    BIO_BUF_MEM *bb = OPENSSL_zalloc(sizeof(*bb));
+
+    if (bb == NULL)
+        return 0;
+    if ((bb->buf = BUF_MEM_new_ex(flags)) == NULL) {
+        OPENSSL_free(bb);
+        return 0;
+    }
+    if ((bb->readp = OPENSSL_zalloc(sizeof(*bb->readp))) == NULL) {
+        BUF_MEM_free(bb->buf);
+        OPENSSL_free(bb);
+        return 0;
+    }
+    *bb->readp = *bb->buf;
+    bi->shutdown = 1;
+    bi->init = 1;
+    bi->num = -1;
+    bi->ptr = (char *)bb;
+    return 1;
+}
+
+static int mem_new(BIO *bi)
+{
+    return (mem_init(bi, 0L));
+}
+
+static int secmem_new(BIO *bi)
+{
+    return (mem_init(bi, BUF_MEM_FLAG_SECURE));
+}
+
+static int mem_free(BIO *a)
+{
+    return (mem_buf_free(a, 1));
+}
+
+static int mem_buf_free(BIO *a, int free_all)
+{
+    if (a == NULL)
+        return (0);
+    if (a->shutdown) {
+        if ((a->init) && (a->ptr != NULL)) {
+            BUF_MEM *b;
+            BIO_BUF_MEM *bb = (BIO_BUF_MEM *)a->ptr;
+
+            if (bb != NULL) {
+                b = bb->buf;
+                if (a->flags & BIO_FLAGS_MEM_RDONLY)
+                    b->data = NULL;
+                BUF_MEM_free(b);
+                if (free_all) {
+                    OPENSSL_free(bb->readp);
+                    OPENSSL_free(bb);
+                }
+            }
+            a->ptr = NULL;
+        }
+    }
+    return (1);
+}
+
+/*
+ * Reallocate memory buffer if read pointer differs
+ */
+static int mem_buf_sync(BIO *b)
+{
+    if (b != NULL && b->init != 0 && b->ptr != NULL) {
+        BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
+
+        if (bbm->readp->data != bbm->buf->data) {
+            memmove(bbm->buf->data, bbm->readp->data, bbm->readp->length);
+            bbm->buf->length = bbm->readp->length;
+            bbm->readp->data = bbm->buf->data;
+        }
+    }
+    return (0);
+}
+
+static int mem_read(BIO *b, char *out, int outl)
+{
+    int ret = -1;
+    BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
+    BUF_MEM *bm = bbm->readp;
+
+    BIO_clear_retry_flags(b);
+    ret = (outl >= 0 && (size_t)outl > bm->length) ? (int)bm->length : outl;
+    if ((out != NULL) && (ret > 0)) {
+        memcpy(out, bm->data, ret);
+        bm->length -= ret;
+        bm->data += ret;
+    } else if (bm->length == 0) {
+        ret = b->num;
+        if (ret != 0)
+            BIO_set_retry_read(b);
+    }
+    return (ret);
+}
+
+static int mem_write(BIO *b, const char *in, int inl)
+{
+    int ret = -1;
+    int blen;
+    BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
+
+    if (in == NULL) {
+        BIOerr(BIO_F_MEM_WRITE, BIO_R_NULL_PARAMETER);
+        goto end;
+    }
+    if (b->flags & BIO_FLAGS_MEM_RDONLY) {
+        BIOerr(BIO_F_MEM_WRITE, BIO_R_WRITE_TO_READ_ONLY_BIO);
+        goto end;
+    }
+    BIO_clear_retry_flags(b);
+    blen = bbm->readp->length;
+    mem_buf_sync(b);
+    if (BUF_MEM_grow_clean(bbm->buf, blen + inl) == 0)
+        goto end;
+    memcpy(bbm->buf->data + blen, in, inl);
+    *bbm->readp = *bbm->buf;
+    ret = inl;
+ end:
+    return (ret);
+}
+
+static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    long ret = 1;
+    char **pptr;
+    BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
+    BUF_MEM *bm;
+
+    switch (cmd) {
+    case BIO_CTRL_RESET:
+        bm = bbm->buf;
+        if (bm->data != NULL) {
+            /* For read only case reset to the start again */
+            if ((b->flags & BIO_FLAGS_MEM_RDONLY) || (b->flags & BIO_FLAGS_NONCLEAR_RST)) {
+                bm->length = bm->max;
+            } else {
+                memset(bm->data, 0, bm->max);
+                bm->length = 0;
+            }
+            *bbm->readp = *bbm->buf;
+        }
+        break;
+    case BIO_CTRL_EOF:
+        bm = bbm->readp;
+        ret = (long)(bm->length == 0);
+        break;
+    case BIO_C_SET_BUF_MEM_EOF_RETURN:
+        b->num = (int)num;
+        break;
+    case BIO_CTRL_INFO:
+        bm = bbm->readp;
+        ret = (long)bm->length;
+        if (ptr != NULL) {
+            pptr = (char **)ptr;
+            *pptr = (char *)&(bm->data[0]);
+        }
+        break;
+    case BIO_C_SET_BUF_MEM:
+        mem_buf_free(b, 0);
+        b->shutdown = (int)num;
+        bbm->buf = ptr;
+        *bbm->readp = *bbm->buf;
+        b->ptr = bbm;
+        break;
+    case BIO_C_GET_BUF_MEM_PTR:
+        if (ptr != NULL) {
+            mem_buf_sync(b);
+            bm = bbm->readp;
+            pptr = (char **)ptr;
+            *pptr = (char *)bm;
+        }
+        break;
+    case BIO_CTRL_GET_CLOSE:
+        ret = (long)b->shutdown;
+        break;
+    case BIO_CTRL_SET_CLOSE:
+        b->shutdown = (int)num;
+        break;
+    case BIO_CTRL_WPENDING:
+        ret = 0L;
+        break;
+    case BIO_CTRL_PENDING:
+        bm = bbm->readp;
+        ret = (long)bm->length;
+        break;
+    case BIO_CTRL_DUP:
+    case BIO_CTRL_FLUSH:
+        ret = 1;
+        break;
+    case BIO_CTRL_PUSH:
+    case BIO_CTRL_POP:
+    default:
+        ret = 0;
+        break;
+    }
+    return (ret);
+}
+
+static int mem_gets(BIO *bp, char *buf, int size)
+{
+    int i, j;
+    int ret = -1;
+    char *p;
+    BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)bp->ptr;
+    BUF_MEM *bm = bbm->readp;
+
+    BIO_clear_retry_flags(bp);
+    j = bm->length;
+    if ((size - 1) < j)
+        j = size - 1;
+    if (j <= 0) {
+        *buf = '\0';
+        return 0;
+    }
+    p = bm->data;
+    for (i = 0; i < j; i++) {
+        if (p[i] == '\n') {
+            i++;
+            break;
+        }
+    }
+
+    /*
+     * i is now the max num of bytes to copy, either j or up to
+     * and including the first newline
+     */
+
+    i = mem_read(bp, buf, i);
+    if (i > 0)
+        buf[i] = '\0';
+    ret = i;
+    return (ret);
+}
+
+static int mem_puts(BIO *bp, const char *str)
+{
+    int n, ret;
+
+    n = strlen(str);
+    ret = mem_write(bp, str, n);
+    /* memory semantics is that it will always work */
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_null.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_null.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_null.c	(revision 331)
@@ -0,0 +1,100 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <errno.h>
+#include "bio_lcl.h"
+#include "internal/cryptlib.h"
+
+static int null_write(BIO *h, const char *buf, int num);
+static int null_read(BIO *h, char *buf, int size);
+static int null_puts(BIO *h, const char *str);
+static int null_gets(BIO *h, char *str, int size);
+static long null_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int null_new(BIO *h);
+static int null_free(BIO *data);
+static const BIO_METHOD null_method = {
+    BIO_TYPE_NULL,
+    "NULL",
+    null_write,
+    null_read,
+    null_puts,
+    null_gets,
+    null_ctrl,
+    null_new,
+    null_free,
+    NULL,
+};
+
+const BIO_METHOD *BIO_s_null(void)
+{
+    return (&null_method);
+}
+
+static int null_new(BIO *bi)
+{
+    bi->init = 1;
+    bi->num = 0;
+    bi->ptr = (NULL);
+    return (1);
+}
+
+static int null_free(BIO *a)
+{
+    if (a == NULL)
+        return (0);
+    return (1);
+}
+
+static int null_read(BIO *b, char *out, int outl)
+{
+    return (0);
+}
+
+static int null_write(BIO *b, const char *in, int inl)
+{
+    return (inl);
+}
+
+static long null_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    long ret = 1;
+
+    switch (cmd) {
+    case BIO_CTRL_RESET:
+    case BIO_CTRL_EOF:
+    case BIO_CTRL_SET:
+    case BIO_CTRL_SET_CLOSE:
+    case BIO_CTRL_FLUSH:
+    case BIO_CTRL_DUP:
+        ret = 1;
+        break;
+    case BIO_CTRL_GET_CLOSE:
+    case BIO_CTRL_INFO:
+    case BIO_CTRL_GET:
+    case BIO_CTRL_PENDING:
+    case BIO_CTRL_WPENDING:
+    default:
+        ret = 0;
+        break;
+    }
+    return (ret);
+}
+
+static int null_gets(BIO *bp, char *buf, int size)
+{
+    return (0);
+}
+
+static int null_puts(BIO *bp, const char *str)
+{
+    if (str == NULL)
+        return (0);
+    return (strlen(str));
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_sock.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_sock.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bio/bss_sock.c	(revision 331)
@@ -0,0 +1,231 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "bio_lcl.h"
+#include "internal/cryptlib.h"
+
+#ifndef OPENSSL_NO_SOCK
+
+# include <openssl/bio.h>
+
+# ifdef WATT32
+/* Watt-32 uses same names */
+#  undef sock_write
+#  undef sock_read
+#  undef sock_puts
+#  define sock_write SockWrite
+#  define sock_read  SockRead
+#  define sock_puts  SockPuts
+# endif
+
+static int sock_write(BIO *h, const char *buf, int num);
+static int sock_read(BIO *h, char *buf, int size);
+static int sock_puts(BIO *h, const char *str);
+static long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int sock_new(BIO *h);
+static int sock_free(BIO *data);
+int BIO_sock_should_retry(int s);
+
+static const BIO_METHOD methods_sockp = {
+    BIO_TYPE_SOCKET,
+    "socket",
+    sock_write,
+    sock_read,
+    sock_puts,
+    NULL,                       /* sock_gets, */
+    sock_ctrl,
+    sock_new,
+    sock_free,
+    NULL,
+};
+
+const BIO_METHOD *BIO_s_socket(void)
+{
+    return (&methods_sockp);
+}
+
+BIO *BIO_new_socket(int fd, int close_flag)
+{
+    BIO *ret;
+
+    ret = BIO_new(BIO_s_socket());
+    if (ret == NULL)
+        return (NULL);
+    BIO_set_fd(ret, fd, close_flag);
+    return (ret);
+}
+
+static int sock_new(BIO *bi)
+{
+    bi->init = 0;
+    bi->num = 0;
+    bi->ptr = NULL;
+    bi->flags = 0;
+    return (1);
+}
+
+static int sock_free(BIO *a)
+{
+    if (a == NULL)
+        return (0);
+    if (a->shutdown) {
+        if (a->init) {
+            BIO_closesocket(a->num);
+        }
+        a->init = 0;
+        a->flags = 0;
+    }
+    return (1);
+}
+
+static int sock_read(BIO *b, char *out, int outl)
+{
+    int ret = 0;
+
+    if (out != NULL) {
+        clear_socket_error();
+        ret = readsocket(b->num, out, outl);
+        BIO_clear_retry_flags(b);
+        if (ret <= 0) {
+            if (BIO_sock_should_retry(ret))
+                BIO_set_retry_read(b);
+        }
+    }
+    return (ret);
+}
+
+static int sock_write(BIO *b, const char *in, int inl)
+{
+    int ret;
+
+    clear_socket_error();
+    ret = writesocket(b->num, in, inl);
+    BIO_clear_retry_flags(b);
+    if (ret <= 0) {
+        if (BIO_sock_should_retry(ret))
+            BIO_set_retry_write(b);
+    }
+    return (ret);
+}
+
+static long sock_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    long ret = 1;
+    int *ip;
+
+    switch (cmd) {
+    case BIO_C_SET_FD:
+        sock_free(b);
+        b->num = *((int *)ptr);
+        b->shutdown = (int)num;
+        b->init = 1;
+        break;
+    case BIO_C_GET_FD:
+        if (b->init) {
+            ip = (int *)ptr;
+            if (ip != NULL)
+                *ip = b->num;
+            ret = b->num;
+        } else
+            ret = -1;
+        break;
+    case BIO_CTRL_GET_CLOSE:
+        ret = b->shutdown;
+        break;
+    case BIO_CTRL_SET_CLOSE:
+        b->shutdown = (int)num;
+        break;
+    case BIO_CTRL_DUP:
+    case BIO_CTRL_FLUSH:
+        ret = 1;
+        break;
+    default:
+        ret = 0;
+        break;
+    }
+    return (ret);
+}
+
+static int sock_puts(BIO *bp, const char *str)
+{
+    int n, ret;
+
+    n = strlen(str);
+    ret = sock_write(bp, str, n);
+    return (ret);
+}
+
+int BIO_sock_should_retry(int i)
+{
+    int err;
+
+    if ((i == 0) || (i == -1)) {
+        err = get_last_socket_error();
+
+        return (BIO_sock_non_fatal_error(err));
+    }
+    return (0);
+}
+
+int BIO_sock_non_fatal_error(int err)
+{
+    switch (err) {
+# if defined(OPENSSL_SYS_WINDOWS)
+#  if defined(WSAEWOULDBLOCK)
+    case WSAEWOULDBLOCK:
+#  endif
+# endif
+
+# ifdef EWOULDBLOCK
+#  ifdef WSAEWOULDBLOCK
+#   if WSAEWOULDBLOCK != EWOULDBLOCK
+    case EWOULDBLOCK:
+#   endif
+#  else
+    case EWOULDBLOCK:
+#  endif
+# endif
+
+# if defined(ENOTCONN)
+    case ENOTCONN:
+# endif
+
+# ifdef EINTR
+    case EINTR:
+# endif
+
+# ifdef EAGAIN
+#  if EWOULDBLOCK != EAGAIN
+    case EAGAIN:
+#  endif
+# endif
+
+# ifdef EPROTO
+    case EPROTO:
+# endif
+
+# ifdef EINPROGRESS
+    case EINPROGRESS:
+# endif
+
+# ifdef EALREADY
+    case EALREADY:
+# endif
+        return (1);
+        /* break; */
+    default:
+        break;
+    }
+    return (0);
+}
+
+#endif                          /* #ifndef OPENSSL_NO_SOCK */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/blake2/blake2_impl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/blake2/blake2_impl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/blake2/blake2_impl.h	(revision 331)
@@ -0,0 +1,130 @@
+/*
+ * 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
+ */
+
+/*
+ * Derived from the BLAKE2 reference implementation written by Samuel Neves.
+ * Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
+ * More information about the BLAKE2 hash function and its implementations
+ * can be found at https://blake2.net.
+ */
+
+#include <string.h>
+#include "e_os.h"
+
+static ossl_inline uint32_t load32(const uint8_t *src)
+{
+    const union {
+        long one;
+        char little;
+    } is_endian = { 1 };
+
+    if (is_endian.little) {
+        uint32_t w;
+        memcpy(&w, src, sizeof(w));
+        return w;
+    } else {
+        uint32_t w = ((uint32_t)src[0])
+                   | ((uint32_t)src[1] <<  8)
+                   | ((uint32_t)src[2] << 16)
+                   | ((uint32_t)src[3] << 24);
+        return w;
+    }
+}
+
+static ossl_inline uint64_t load64(const uint8_t *src)
+{
+    const union {
+        long one;
+        char little;
+    } is_endian = { 1 };
+
+    if (is_endian.little) {
+        uint64_t w;
+        memcpy(&w, src, sizeof(w));
+        return w;
+    } else {
+        uint64_t w = ((uint64_t)src[0])
+                   | ((uint64_t)src[1] <<  8)
+                   | ((uint64_t)src[2] << 16)
+                   | ((uint64_t)src[3] << 24)
+                   | ((uint64_t)src[4] << 32)
+                   | ((uint64_t)src[5] << 40)
+                   | ((uint64_t)src[6] << 48)
+                   | ((uint64_t)src[7] << 56);
+        return w;
+    }
+}
+
+static ossl_inline void store32(uint8_t *dst, uint32_t w)
+{
+    const union {
+        long one;
+        char little;
+    } is_endian = { 1 };
+
+    if (is_endian.little) {
+        memcpy(dst, &w, sizeof(w));
+    } else {
+        uint8_t *p = (uint8_t *)dst;
+        int i;
+
+        for (i = 0; i < 4; i++)
+            p[i] = (uint8_t)(w >> (8 * i));
+    }
+}
+
+static ossl_inline void store64(uint8_t *dst, uint64_t w)
+{
+    const union {
+        long one;
+        char little;
+    } is_endian = { 1 };
+
+    if (is_endian.little) {
+        memcpy(dst, &w, sizeof(w));
+    } else {
+        uint8_t *p = (uint8_t *)dst;
+        int i;
+
+        for (i = 0; i < 8; i++)
+            p[i] = (uint8_t)(w >> (8 * i));
+    }
+}
+
+static ossl_inline uint64_t load48(const uint8_t *src)
+{
+    uint64_t w = ((uint64_t)src[0])
+               | ((uint64_t)src[1] <<  8)
+               | ((uint64_t)src[2] << 16)
+               | ((uint64_t)src[3] << 24)
+               | ((uint64_t)src[4] << 32)
+               | ((uint64_t)src[5] << 40);
+    return w;
+}
+
+static ossl_inline void store48(uint8_t *dst, uint64_t w)
+{
+    uint8_t *p = (uint8_t *)dst;
+    p[0] = (uint8_t)w;
+    p[1] = (uint8_t)(w>>8);
+    p[2] = (uint8_t)(w>>16);
+    p[3] = (uint8_t)(w>>24);
+    p[4] = (uint8_t)(w>>32);
+    p[5] = (uint8_t)(w>>40);
+}
+
+static ossl_inline uint32_t rotr32(const uint32_t w, const unsigned int c)
+{
+    return (w >> c) | (w << (32 - c));
+}
+
+static ossl_inline uint64_t rotr64(const uint64_t w, const unsigned int c)
+{
+    return (w >> c) | (w << (64 - c));
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/blake2/blake2_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/blake2/blake2_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/blake2/blake2_locl.h	(revision 331)
@@ -0,0 +1,91 @@
+/*
+ * 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
+ */
+
+/*
+ * Derived from the BLAKE2 reference implementation written by Samuel Neves.
+ * Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
+ * More information about the BLAKE2 hash function and its implementations
+ * can be found at https://blake2.net.
+ */
+
+#include <stddef.h>
+#include "e_os.h"
+
+#define BLAKE2S_BLOCKBYTES    64
+#define BLAKE2S_OUTBYTES      32
+#define BLAKE2S_KEYBYTES      32
+#define BLAKE2S_SALTBYTES     8
+#define BLAKE2S_PERSONALBYTES 8
+
+#define BLAKE2B_BLOCKBYTES    128
+#define BLAKE2B_OUTBYTES      64
+#define BLAKE2B_KEYBYTES      64
+#define BLAKE2B_SALTBYTES     16
+#define BLAKE2B_PERSONALBYTES 16
+
+struct blake2s_param_st {
+    uint8_t  digest_length; /* 1 */
+    uint8_t  key_length;    /* 2 */
+    uint8_t  fanout;        /* 3 */
+    uint8_t  depth;         /* 4 */
+    uint8_t  leaf_length[4];/* 8 */
+    uint8_t  node_offset[6];/* 14 */
+    uint8_t  node_depth;    /* 15 */
+    uint8_t  inner_length;  /* 16 */
+    uint8_t  salt[BLAKE2S_SALTBYTES]; /* 24 */
+    uint8_t  personal[BLAKE2S_PERSONALBYTES];  /* 32 */
+};
+
+typedef struct blake2s_param_st BLAKE2S_PARAM;
+
+struct blake2s_ctx_st {
+    uint32_t h[8];
+    uint32_t t[2];
+    uint32_t f[2];
+    uint8_t  buf[BLAKE2S_BLOCKBYTES];
+    size_t   buflen;
+};
+
+struct blake2b_param_st {
+    uint8_t  digest_length; /* 1 */
+    uint8_t  key_length;    /* 2 */
+    uint8_t  fanout;        /* 3 */
+    uint8_t  depth;         /* 4 */
+    uint8_t  leaf_length[4];/* 8 */
+    uint8_t  node_offset[8];/* 16 */
+    uint8_t  node_depth;    /* 17 */
+    uint8_t  inner_length;  /* 18 */
+    uint8_t  reserved[14];  /* 32 */
+    uint8_t  salt[BLAKE2B_SALTBYTES]; /* 48 */
+    uint8_t  personal[BLAKE2B_PERSONALBYTES];  /* 64 */
+};
+
+typedef struct blake2b_param_st BLAKE2B_PARAM;
+
+struct blake2b_ctx_st {
+    uint64_t h[8];
+    uint64_t t[2];
+    uint64_t f[2];
+    uint8_t  buf[BLAKE2B_BLOCKBYTES];
+    size_t   buflen;
+};
+
+#define BLAKE2B_DIGEST_LENGTH 64
+#define BLAKE2S_DIGEST_LENGTH 32
+
+typedef struct blake2s_ctx_st BLAKE2S_CTX;
+typedef struct blake2b_ctx_st BLAKE2B_CTX;
+
+int BLAKE2b_Init(BLAKE2B_CTX *c);
+int BLAKE2b_Update(BLAKE2B_CTX *c, const void *data, size_t datalen);
+int BLAKE2b_Final(unsigned char *md, BLAKE2B_CTX *c);
+
+int BLAKE2s_Init(BLAKE2S_CTX *c);
+int BLAKE2s_Update(BLAKE2S_CTX *c, const void *data, size_t datalen);
+int BLAKE2s_Final(unsigned char *md, BLAKE2S_CTX *c);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/blake2/blake2b.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/blake2/blake2b.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/blake2/blake2b.c	(revision 331)
@@ -0,0 +1,270 @@
+/*
+ * 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
+ */
+
+/*
+ * Derived from the BLAKE2 reference implementation written by Samuel Neves.
+ * Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
+ * More information about the BLAKE2 hash function and its implementations
+ * can be found at https://blake2.net.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include "e_os.h"
+
+#include "blake2_locl.h"
+#include "blake2_impl.h"
+
+static const uint64_t blake2b_IV[8] =
+{
+    0x6a09e667f3bcc908U, 0xbb67ae8584caa73bU,
+    0x3c6ef372fe94f82bU, 0xa54ff53a5f1d36f1U,
+    0x510e527fade682d1U, 0x9b05688c2b3e6c1fU,
+    0x1f83d9abfb41bd6bU, 0x5be0cd19137e2179U
+};
+
+static const uint8_t blake2b_sigma[12][16] =
+{
+    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,
+    { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 } ,
+    { 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 } ,
+    {  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 } ,
+    {  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 } ,
+    {  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 } ,
+    { 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 } ,
+    { 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 } ,
+    {  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 } ,
+    { 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0 } ,
+    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,
+    { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 }
+};
+
+/* Set that it's the last block we'll compress */
+static ossl_inline void blake2b_set_lastblock(BLAKE2B_CTX *S)
+{
+    S->f[0] = -1;
+}
+
+/* Initialize the hashing state. */
+static ossl_inline void blake2b_init0(BLAKE2B_CTX *S)
+{
+    int i;
+
+    memset(S, 0, sizeof(BLAKE2B_CTX));
+    for (i = 0; i < 8; ++i) {
+        S->h[i] = blake2b_IV[i];
+    }
+}
+
+/* init xors IV with input parameter block */
+static void blake2b_init_param(BLAKE2B_CTX *S, const BLAKE2B_PARAM *P)
+{
+    size_t i;
+    const uint8_t *p = (const uint8_t *)(P);
+    blake2b_init0(S);
+
+    /* The param struct is carefully hand packed, and should be 64 bytes on
+     * every platform. */
+    assert(sizeof(BLAKE2B_PARAM) == 64);
+    /* IV XOR ParamBlock */
+    for (i = 0; i < 8; ++i) {
+        S->h[i] ^= load64(p + sizeof(S->h[i]) * i);
+    }
+}
+
+/* Initialize the hashing context.  Always returns 1. */
+int BLAKE2b_Init(BLAKE2B_CTX *c)
+{
+    BLAKE2B_PARAM P[1];
+    P->digest_length = BLAKE2B_DIGEST_LENGTH;
+    P->key_length    = 0;
+    P->fanout        = 1;
+    P->depth         = 1;
+    store32(P->leaf_length, 0);
+    store64(P->node_offset, 0);
+    P->node_depth    = 0;
+    P->inner_length  = 0;
+    memset(P->reserved, 0, sizeof(P->reserved));
+    memset(P->salt,     0, sizeof(P->salt));
+    memset(P->personal, 0, sizeof(P->personal));
+    blake2b_init_param(c, P);
+    return 1;
+}
+
+/* Permute the state while xoring in the block of data. */
+static void blake2b_compress(BLAKE2B_CTX *S,
+                            const uint8_t *blocks,
+                            size_t len)
+{
+    uint64_t m[16];
+    uint64_t v[16];
+    int i;
+    size_t increment;
+
+    /*
+     * There are two distinct usage vectors for this function:
+     *
+     * a) BLAKE2b_Update uses it to process complete blocks,
+     *    possibly more than one at a time;
+     *
+     * b) BLAK2b_Final uses it to process last block, always
+     *    single but possibly incomplete, in which case caller
+     *    pads input with zeros.
+     */
+    assert(len < BLAKE2B_BLOCKBYTES || len % BLAKE2B_BLOCKBYTES == 0);
+
+    /*
+     * Since last block is always processed with separate call,
+     * |len| not being multiple of complete blocks can be observed
+     * only with |len| being less than BLAKE2B_BLOCKBYTES ("less"
+     * including even zero), which is why following assignment doesn't
+     * have to reside inside the main loop below.
+     */
+    increment = len < BLAKE2B_BLOCKBYTES ? len : BLAKE2B_BLOCKBYTES;
+
+    for (i = 0; i < 8; ++i) {
+        v[i] = S->h[i];
+    }
+
+    do {
+        for (i = 0; i < 16; ++i) {
+            m[i] = load64(blocks + i * sizeof(m[i]));
+        }
+
+        /* blake2b_increment_counter */
+        S->t[0] += increment;
+        S->t[1] += (S->t[0] < increment);
+
+        v[8]  = blake2b_IV[0];
+        v[9]  = blake2b_IV[1];
+        v[10] = blake2b_IV[2];
+        v[11] = blake2b_IV[3];
+        v[12] = S->t[0] ^ blake2b_IV[4];
+        v[13] = S->t[1] ^ blake2b_IV[5];
+        v[14] = S->f[0] ^ blake2b_IV[6];
+        v[15] = S->f[1] ^ blake2b_IV[7];
+#define G(r,i,a,b,c,d) \
+        do { \
+            a = a + b + m[blake2b_sigma[r][2*i+0]]; \
+            d = rotr64(d ^ a, 32); \
+            c = c + d; \
+            b = rotr64(b ^ c, 24); \
+            a = a + b + m[blake2b_sigma[r][2*i+1]]; \
+            d = rotr64(d ^ a, 16); \
+            c = c + d; \
+            b = rotr64(b ^ c, 63); \
+        } while (0)
+#define ROUND(r)  \
+        do { \
+            G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
+            G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
+            G(r,2,v[ 2],v[ 6],v[10],v[14]); \
+            G(r,3,v[ 3],v[ 7],v[11],v[15]); \
+            G(r,4,v[ 0],v[ 5],v[10],v[15]); \
+            G(r,5,v[ 1],v[ 6],v[11],v[12]); \
+            G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
+            G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
+        } while (0)
+#if defined(OPENSSL_SMALL_FOOTPRINT)
+        /* 3x size reduction on x86_64, almost 7x on ARMv8, 9x on ARMv4 */
+        for (i = 0; i < 12; i++) {
+            ROUND(i);
+        }
+#else
+        ROUND(0);
+        ROUND(1);
+        ROUND(2);
+        ROUND(3);
+        ROUND(4);
+        ROUND(5);
+        ROUND(6);
+        ROUND(7);
+        ROUND(8);
+        ROUND(9);
+        ROUND(10);
+        ROUND(11);
+#endif
+
+        for (i = 0; i < 8; ++i) {
+            S->h[i] = v[i] ^= v[i + 8] ^ S->h[i];
+        }
+#undef G
+#undef ROUND
+        blocks += increment;
+        len -= increment;
+    } while (len);
+}
+
+/* Absorb the input data into the hash state.  Always returns 1. */
+int BLAKE2b_Update(BLAKE2B_CTX *c, const void *data, size_t datalen)
+{
+    const uint8_t *in = data;
+    size_t fill;
+
+    /*
+     * Intuitively one would expect intermediate buffer, c->buf, to
+     * store incomplete blocks. But in this case we are interested to
+     * temporarily stash even complete blocks, because last one in the
+     * stream has to be treated in special way, and at this point we
+     * don't know if last block in *this* call is last one "ever". This
+     * is the reason for why |datalen| is compared as >, and not >=.
+     */
+    fill = sizeof(c->buf) - c->buflen;
+    if (datalen > fill) {
+        if (c->buflen) {
+            memcpy(c->buf + c->buflen, in, fill); /* Fill buffer */
+            blake2b_compress(c, c->buf, BLAKE2B_BLOCKBYTES);
+            c->buflen = 0;
+            in += fill;
+            datalen -= fill;
+        }
+        if (datalen > BLAKE2B_BLOCKBYTES) {
+            size_t stashlen = datalen % BLAKE2B_BLOCKBYTES;
+            /*
+             * If |datalen| is a multiple of the blocksize, stash
+             * last complete block, it can be final one...
+             */
+            stashlen = stashlen ? stashlen : BLAKE2B_BLOCKBYTES;
+            datalen -= stashlen;
+            blake2b_compress(c, in, datalen);
+            in += datalen;
+            datalen = stashlen;
+        }
+    }
+
+    assert(datalen <= BLAKE2B_BLOCKBYTES);
+
+    memcpy(c->buf + c->buflen, in, datalen);
+    c->buflen += datalen; /* Be lazy, do not compress */
+
+    return 1;
+}
+
+/*
+ * Calculate the final hash and save it in md.
+ * Always returns 1.
+ */
+int BLAKE2b_Final(unsigned char *md, BLAKE2B_CTX *c)
+{
+    int i;
+
+    blake2b_set_lastblock(c);
+    /* Padding */
+    memset(c->buf + c->buflen, 0, sizeof(c->buf) - c->buflen);
+    blake2b_compress(c, c->buf, c->buflen);
+
+    /* Output full hash to message digest */
+    for (i = 0; i < 8; ++i) {
+        store64(md + sizeof(c->h[i]) * i, c->h[i]);
+    }
+
+    OPENSSL_cleanse(c, sizeof(BLAKE2B_CTX));
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/blake2/blake2s.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/blake2/blake2s.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/blake2/blake2s.c	(revision 331)
@@ -0,0 +1,264 @@
+/*
+ * 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
+ */
+
+/*
+ * Derived from the BLAKE2 reference implementation written by Samuel Neves.
+ * Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
+ * More information about the BLAKE2 hash function and its implementations
+ * can be found at https://blake2.net.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include "e_os.h"
+
+#include "blake2_locl.h"
+#include "blake2_impl.h"
+
+static const uint32_t blake2s_IV[8] =
+{
+    0x6A09E667U, 0xBB67AE85U, 0x3C6EF372U, 0xA54FF53AU,
+    0x510E527FU, 0x9B05688CU, 0x1F83D9ABU, 0x5BE0CD19U
+};
+
+static const uint8_t blake2s_sigma[10][16] =
+{
+    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 } ,
+    { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 } ,
+    { 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 } ,
+    {  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 } ,
+    {  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 } ,
+    {  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 } ,
+    { 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 } ,
+    { 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 } ,
+    {  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 } ,
+    { 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0 } ,
+};
+
+/* Set that it's the last block we'll compress */
+static ossl_inline void blake2s_set_lastblock(BLAKE2S_CTX *S)
+{
+    S->f[0] = -1;
+}
+
+/* Initialize the hashing state. */
+static ossl_inline void blake2s_init0(BLAKE2S_CTX *S)
+{
+    int i;
+
+    memset(S, 0, sizeof(BLAKE2S_CTX));
+    for (i = 0; i < 8; ++i) {
+        S->h[i] = blake2s_IV[i];
+    }
+}
+
+/* init2 xors IV with input parameter block */
+static void blake2s_init_param(BLAKE2S_CTX *S, const BLAKE2S_PARAM *P)
+{
+    const uint8_t *p = (const uint8_t *)(P);
+    size_t i;
+
+    /* The param struct is carefully hand packed, and should be 32 bytes on
+     * every platform. */
+    assert(sizeof(BLAKE2S_PARAM) == 32);
+    blake2s_init0(S);
+    /* IV XOR ParamBlock */
+    for (i = 0; i < 8; ++i) {
+        S->h[i] ^= load32(&p[i*4]);
+    }
+}
+
+/* Initialize the hashing context.  Always returns 1. */
+int BLAKE2s_Init(BLAKE2S_CTX *c)
+{
+    BLAKE2S_PARAM P[1];
+
+    P->digest_length = BLAKE2S_DIGEST_LENGTH;
+    P->key_length    = 0;
+    P->fanout        = 1;
+    P->depth         = 1;
+    store32(P->leaf_length, 0);
+    store48(P->node_offset, 0);
+    P->node_depth    = 0;
+    P->inner_length  = 0;
+    memset(P->salt,     0, sizeof(P->salt));
+    memset(P->personal, 0, sizeof(P->personal));
+    blake2s_init_param(c, P);
+    return 1;
+}
+
+/* Permute the state while xoring in the block of data. */
+static void blake2s_compress(BLAKE2S_CTX *S,
+                            const uint8_t *blocks,
+                            size_t len)
+{
+    uint32_t m[16];
+    uint32_t v[16];
+    size_t i;
+    size_t increment;
+
+    /*
+     * There are two distinct usage vectors for this function:
+     *
+     * a) BLAKE2s_Update uses it to process complete blocks,
+     *    possibly more than one at a time;
+     *
+     * b) BLAK2s_Final uses it to process last block, always
+     *    single but possibly incomplete, in which case caller
+     *    pads input with zeros.
+     */
+    assert(len < BLAKE2S_BLOCKBYTES || len % BLAKE2S_BLOCKBYTES == 0);
+
+    /*
+     * Since last block is always processed with separate call,
+     * |len| not being multiple of complete blocks can be observed
+     * only with |len| being less than BLAKE2S_BLOCKBYTES ("less"
+     * including even zero), which is why following assignment doesn't
+     * have to reside inside the main loop below.
+     */
+    increment = len < BLAKE2S_BLOCKBYTES ? len : BLAKE2S_BLOCKBYTES;
+
+    for (i = 0; i < 8; ++i) {
+        v[i] = S->h[i];
+    }
+
+    do {
+        for (i = 0; i < 16; ++i) {
+            m[i] = load32(blocks + i * sizeof(m[i]));
+        }
+
+        /* blake2s_increment_counter */
+        S->t[0] += increment;
+        S->t[1] += (S->t[0] < increment);
+
+        v[ 8] = blake2s_IV[0];
+        v[ 9] = blake2s_IV[1];
+        v[10] = blake2s_IV[2];
+        v[11] = blake2s_IV[3];
+        v[12] = S->t[0] ^ blake2s_IV[4];
+        v[13] = S->t[1] ^ blake2s_IV[5];
+        v[14] = S->f[0] ^ blake2s_IV[6];
+        v[15] = S->f[1] ^ blake2s_IV[7];
+#define G(r,i,a,b,c,d) \
+        do { \
+            a = a + b + m[blake2s_sigma[r][2*i+0]]; \
+            d = rotr32(d ^ a, 16); \
+            c = c + d; \
+            b = rotr32(b ^ c, 12); \
+            a = a + b + m[blake2s_sigma[r][2*i+1]]; \
+            d = rotr32(d ^ a, 8); \
+            c = c + d; \
+            b = rotr32(b ^ c, 7); \
+        } while (0)
+#define ROUND(r)  \
+        do { \
+            G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
+            G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
+            G(r,2,v[ 2],v[ 6],v[10],v[14]); \
+            G(r,3,v[ 3],v[ 7],v[11],v[15]); \
+            G(r,4,v[ 0],v[ 5],v[10],v[15]); \
+            G(r,5,v[ 1],v[ 6],v[11],v[12]); \
+            G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
+            G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
+        } while (0)
+#if defined(OPENSSL_SMALL_FOOTPRINT)
+        /* almost 3x reduction on x86_64, 4.5x on ARMv8, 4x on ARMv4 */
+        for (i = 0; i < 10; i++) {
+            ROUND(i);
+        }
+#else
+        ROUND(0);
+        ROUND(1);
+        ROUND(2);
+        ROUND(3);
+        ROUND(4);
+        ROUND(5);
+        ROUND(6);
+        ROUND(7);
+        ROUND(8);
+        ROUND(9);
+#endif
+
+        for (i = 0; i < 8; ++i) {
+            S->h[i] = v[i] ^= v[i + 8] ^ S->h[i];
+        }
+#undef G
+#undef ROUND
+        blocks += increment;
+        len -= increment;
+    } while (len);
+}
+
+/* Absorb the input data into the hash state.  Always returns 1. */
+int BLAKE2s_Update(BLAKE2S_CTX *c, const void *data, size_t datalen)
+{
+    const uint8_t *in = data;
+    size_t fill;
+
+    /*
+     * Intuitively one would expect intermediate buffer, c->buf, to
+     * store incomplete blocks. But in this case we are interested to
+     * temporarily stash even complete blocks, because last one in the
+     * stream has to be treated in special way, and at this point we
+     * don't know if last block in *this* call is last one "ever". This
+     * is the reason for why |datalen| is compared as >, and not >=.
+     */
+    fill = sizeof(c->buf) - c->buflen;
+    if (datalen > fill) {
+        if (c->buflen) {
+            memcpy(c->buf + c->buflen, in, fill); /* Fill buffer */
+            blake2s_compress(c, c->buf, BLAKE2S_BLOCKBYTES);
+            c->buflen = 0;
+            in += fill;
+            datalen -= fill;
+        }
+        if (datalen > BLAKE2S_BLOCKBYTES)  {
+            size_t stashlen = datalen % BLAKE2S_BLOCKBYTES;
+            /*
+             * If |datalen| is a multiple of the blocksize, stash
+             * last complete block, it can be final one...
+             */
+            stashlen = stashlen ? stashlen : BLAKE2S_BLOCKBYTES;
+            datalen -= stashlen;
+            blake2s_compress(c, in, datalen);
+            in += datalen;
+            datalen = stashlen;
+        }
+    }
+
+    assert(datalen <= BLAKE2S_BLOCKBYTES);
+
+    memcpy(c->buf + c->buflen, in, datalen);
+    c->buflen += datalen; /* Be lazy, do not compress */
+
+    return 1;
+}
+
+/*
+ * Calculate the final hash and save it in md.
+ * Always returns 1.
+ */
+int BLAKE2s_Final(unsigned char *md, BLAKE2S_CTX *c)
+{
+    int i;
+
+    blake2s_set_lastblock(c);
+    /* Padding */
+    memset(c->buf + c->buflen, 0, sizeof(c->buf) - c->buflen);
+    blake2s_compress(c, c->buf, c->buflen);
+
+    /* Output full hash to temp buffer */
+    for (i = 0; i < 8; ++i) {
+        store32(md + sizeof(c->h[i]) * i, c->h[i]);
+    }
+
+    OPENSSL_cleanse(c, sizeof(BLAKE2S_CTX));
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/blake2/m_blake2b.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/blake2/m_blake2b.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/blake2/m_blake2b.c	(revision 331)
@@ -0,0 +1,59 @@
+/*
+ * 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
+ */
+
+/*
+ * Derived from the BLAKE2 reference implementation written by Samuel Neves.
+ * Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
+ * More information about the BLAKE2 hash function and its implementations
+ * can be found at https://blake2.net.
+ */
+
+#include "internal/cryptlib.h"
+
+#ifndef OPENSSL_NO_BLAKE2
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "blake2_locl.h"
+# include "internal/evp_int.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+    return BLAKE2b_Init(EVP_MD_CTX_md_data(ctx));
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+    return BLAKE2b_Update(EVP_MD_CTX_md_data(ctx), data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+    return BLAKE2b_Final(md, EVP_MD_CTX_md_data(ctx));
+}
+
+static const EVP_MD blake2b_md = {
+    NID_blake2b512,
+    0,
+    BLAKE2B_DIGEST_LENGTH,
+    0,
+    init,
+    update,
+    final,
+    NULL,
+    NULL,
+    BLAKE2B_BLOCKBYTES,
+    sizeof(EVP_MD *) + sizeof(BLAKE2B_CTX),
+};
+
+const EVP_MD *EVP_blake2b512(void)
+{
+    return (&blake2b_md);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/blake2/m_blake2s.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/blake2/m_blake2s.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/blake2/m_blake2s.c	(revision 331)
@@ -0,0 +1,59 @@
+/*
+ * 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
+ */
+
+/*
+ * Derived from the BLAKE2 reference implementation written by Samuel Neves.
+ * Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
+ * More information about the BLAKE2 hash function and its implementations
+ * can be found at https://blake2.net.
+ */
+
+#include "internal/cryptlib.h"
+
+#ifndef OPENSSL_NO_BLAKE2
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "blake2_locl.h"
+# include "internal/evp_int.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+    return BLAKE2s_Init(EVP_MD_CTX_md_data(ctx));
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+    return BLAKE2s_Update(EVP_MD_CTX_md_data(ctx), data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+    return BLAKE2s_Final(md, EVP_MD_CTX_md_data(ctx));
+}
+
+static const EVP_MD blake2s_md = {
+    NID_blake2s256,
+    0,
+    BLAKE2S_DIGEST_LENGTH,
+    0,
+    init,
+    update,
+    final,
+    NULL,
+    NULL,
+    BLAKE2S_BLOCKBYTES,
+    sizeof(EVP_MD *) + sizeof(BLAKE2S_CTX),
+};
+
+const EVP_MD *EVP_blake2s256(void)
+{
+    return (&blake2s_md);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_add.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_add.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_add.c	(revision 331)
@@ -0,0 +1,205 @@
+/*
+ * Copyright 1995-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 "internal/cryptlib.h"
+#include "bn_lcl.h"
+
+/* r can == a or b */
+int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+{
+    int a_neg = a->neg, ret;
+
+    bn_check_top(a);
+    bn_check_top(b);
+
+    /*-
+     *  a +  b      a+b
+     *  a + -b      a-b
+     * -a +  b      b-a
+     * -a + -b      -(a+b)
+     */
+    if (a_neg ^ b->neg) {
+        /* only one is negative */
+        if (a_neg) {
+            const BIGNUM *tmp;
+
+            tmp = a;
+            a = b;
+            b = tmp;
+        }
+
+        /* we are now a - b */
+
+        if (BN_ucmp(a, b) < 0) {
+            if (!BN_usub(r, b, a))
+                return 0;
+            r->neg = 1;
+        } else {
+            if (!BN_usub(r, a, b))
+                return 0;
+            r->neg = 0;
+        }
+        return 1;
+    }
+
+    ret = BN_uadd(r, a, b);
+    r->neg = a_neg;
+    bn_check_top(r);
+    return ret;
+}
+
+/* unsigned add of b to a */
+int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+{
+    int max, min, dif;
+    const BN_ULONG *ap, *bp;
+    BN_ULONG *rp, carry, t1, t2;
+
+    bn_check_top(a);
+    bn_check_top(b);
+
+    if (a->top < b->top) {
+        const BIGNUM *tmp;
+
+        tmp = a;
+        a = b;
+        b = tmp;
+    }
+    max = a->top;
+    min = b->top;
+    dif = max - min;
+
+    if (bn_wexpand(r, max + 1) == NULL)
+        return 0;
+
+    r->top = max;
+
+    ap = a->d;
+    bp = b->d;
+    rp = r->d;
+
+    carry = bn_add_words(rp, ap, bp, min);
+    rp += min;
+    ap += min;
+
+    while (dif) {
+        dif--;
+        t1 = *(ap++);
+        t2 = (t1 + carry) & BN_MASK2;
+        *(rp++) = t2;
+        carry &= (t2 == 0);
+    }
+    *rp = carry;
+    r->top += carry;
+
+    r->neg = 0;
+    bn_check_top(r);
+    return 1;
+}
+
+/* unsigned subtraction of b from a, a must be larger than b. */
+int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+{
+    int max, min, dif;
+    BN_ULONG t1, t2, borrow, *rp;
+    const BN_ULONG *ap, *bp;
+
+    bn_check_top(a);
+    bn_check_top(b);
+
+    max = a->top;
+    min = b->top;
+    dif = max - min;
+
+    if (dif < 0) {              /* hmm... should not be happening */
+        BNerr(BN_F_BN_USUB, BN_R_ARG2_LT_ARG3);
+        return 0;
+    }
+
+    if (bn_wexpand(r, max) == NULL)
+        return 0;
+
+    ap = a->d;
+    bp = b->d;
+    rp = r->d;
+
+    borrow = bn_sub_words(rp, ap, bp, min);
+    ap += min;
+    rp += min;
+
+    while (dif) {
+        dif--;
+        t1 = *(ap++);
+        t2 = (t1 - borrow) & BN_MASK2;
+        *(rp++) = t2;
+        borrow &= (t1 == 0);
+    }
+
+    r->top = max;
+    r->neg = 0;
+    bn_correct_top(r);
+    return 1;
+}
+
+int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+{
+    int max;
+    int add = 0, neg = 0;
+
+    bn_check_top(a);
+    bn_check_top(b);
+
+    /*-
+     *  a -  b      a-b
+     *  a - -b      a+b
+     * -a -  b      -(a+b)
+     * -a - -b      b-a
+     */
+    if (a->neg) {
+        if (b->neg) {
+            const BIGNUM *tmp;
+
+            tmp = a;
+            a = b;
+            b = tmp;
+        } else {
+            add = 1;
+            neg = 1;
+        }
+    } else {
+        if (b->neg) {
+            add = 1;
+            neg = 0;
+        }
+    }
+
+    if (add) {
+        if (!BN_uadd(r, a, b))
+            return 0;
+        r->neg = neg;
+        return 1;
+    }
+
+    /* We are actually doing a - b :-) */
+
+    max = (a->top > b->top) ? a->top : b->top;
+    if (bn_wexpand(r, max) == NULL)
+        return 0;
+    if (BN_ucmp(a, b) < 0) {
+        if (!BN_usub(r, b, a))
+            return 0;
+        r->neg = 1;
+    } else {
+        if (!BN_usub(r, a, b))
+            return 0;
+        r->neg = 0;
+    }
+    bn_check_top(r);
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_asm.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_asm.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_asm.c	(revision 331)
@@ -0,0 +1,1039 @@
+/*
+ * Copyright 1995-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 <assert.h>
+#include <openssl/crypto.h>
+#include "internal/cryptlib.h"
+#include "bn_lcl.h"
+
+#if defined(BN_LLONG) || defined(BN_UMULT_HIGH)
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
+                          BN_ULONG w)
+{
+    BN_ULONG c1 = 0;
+
+    assert(num >= 0);
+    if (num <= 0)
+        return (c1);
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+    while (num & ~3) {
+        mul_add(rp[0], ap[0], w, c1);
+        mul_add(rp[1], ap[1], w, c1);
+        mul_add(rp[2], ap[2], w, c1);
+        mul_add(rp[3], ap[3], w, c1);
+        ap += 4;
+        rp += 4;
+        num -= 4;
+    }
+# endif
+    while (num) {
+        mul_add(rp[0], ap[0], w, c1);
+        ap++;
+        rp++;
+        num--;
+    }
+
+    return (c1);
+}
+
+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
+{
+    BN_ULONG c1 = 0;
+
+    assert(num >= 0);
+    if (num <= 0)
+        return (c1);
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+    while (num & ~3) {
+        mul(rp[0], ap[0], w, c1);
+        mul(rp[1], ap[1], w, c1);
+        mul(rp[2], ap[2], w, c1);
+        mul(rp[3], ap[3], w, c1);
+        ap += 4;
+        rp += 4;
+        num -= 4;
+    }
+# endif
+    while (num) {
+        mul(rp[0], ap[0], w, c1);
+        ap++;
+        rp++;
+        num--;
+    }
+    return (c1);
+}
+
+void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
+{
+    assert(n >= 0);
+    if (n <= 0)
+        return;
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+    while (n & ~3) {
+        sqr(r[0], r[1], a[0]);
+        sqr(r[2], r[3], a[1]);
+        sqr(r[4], r[5], a[2]);
+        sqr(r[6], r[7], a[3]);
+        a += 4;
+        r += 8;
+        n -= 4;
+    }
+# endif
+    while (n) {
+        sqr(r[0], r[1], a[0]);
+        a++;
+        r += 2;
+        n--;
+    }
+}
+
+#else                           /* !(defined(BN_LLONG) ||
+                                 * defined(BN_UMULT_HIGH)) */
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
+                          BN_ULONG w)
+{
+    BN_ULONG c = 0;
+    BN_ULONG bl, bh;
+
+    assert(num >= 0);
+    if (num <= 0)
+        return ((BN_ULONG)0);
+
+    bl = LBITS(w);
+    bh = HBITS(w);
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+    while (num & ~3) {
+        mul_add(rp[0], ap[0], bl, bh, c);
+        mul_add(rp[1], ap[1], bl, bh, c);
+        mul_add(rp[2], ap[2], bl, bh, c);
+        mul_add(rp[3], ap[3], bl, bh, c);
+        ap += 4;
+        rp += 4;
+        num -= 4;
+    }
+# endif
+    while (num) {
+        mul_add(rp[0], ap[0], bl, bh, c);
+        ap++;
+        rp++;
+        num--;
+    }
+    return (c);
+}
+
+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w)
+{
+    BN_ULONG carry = 0;
+    BN_ULONG bl, bh;
+
+    assert(num >= 0);
+    if (num <= 0)
+        return ((BN_ULONG)0);
+
+    bl = LBITS(w);
+    bh = HBITS(w);
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+    while (num & ~3) {
+        mul(rp[0], ap[0], bl, bh, carry);
+        mul(rp[1], ap[1], bl, bh, carry);
+        mul(rp[2], ap[2], bl, bh, carry);
+        mul(rp[3], ap[3], bl, bh, carry);
+        ap += 4;
+        rp += 4;
+        num -= 4;
+    }
+# endif
+    while (num) {
+        mul(rp[0], ap[0], bl, bh, carry);
+        ap++;
+        rp++;
+        num--;
+    }
+    return (carry);
+}
+
+void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n)
+{
+    assert(n >= 0);
+    if (n <= 0)
+        return;
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+    while (n & ~3) {
+        sqr64(r[0], r[1], a[0]);
+        sqr64(r[2], r[3], a[1]);
+        sqr64(r[4], r[5], a[2]);
+        sqr64(r[6], r[7], a[3]);
+        a += 4;
+        r += 8;
+        n -= 4;
+    }
+# endif
+    while (n) {
+        sqr64(r[0], r[1], a[0]);
+        a++;
+        r += 2;
+        n--;
+    }
+}
+
+#endif                          /* !(defined(BN_LLONG) ||
+                                 * defined(BN_UMULT_HIGH)) */
+
+#if defined(BN_LLONG) && defined(BN_DIV2W)
+
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+{
+    return ((BN_ULONG)(((((BN_ULLONG) h) << BN_BITS2) | l) / (BN_ULLONG) d));
+}
+
+#else
+
+/* Divide h,l by d and return the result. */
+/* I need to test this some more :-( */
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+{
+    BN_ULONG dh, dl, q, ret = 0, th, tl, t;
+    int i, count = 2;
+
+    if (d == 0)
+        return (BN_MASK2);
+
+    i = BN_num_bits_word(d);
+    assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i));
+
+    i = BN_BITS2 - i;
+    if (h >= d)
+        h -= d;
+
+    if (i) {
+        d <<= i;
+        h = (h << i) | (l >> (BN_BITS2 - i));
+        l <<= i;
+    }
+    dh = (d & BN_MASK2h) >> BN_BITS4;
+    dl = (d & BN_MASK2l);
+    for (;;) {
+        if ((h >> BN_BITS4) == dh)
+            q = BN_MASK2l;
+        else
+            q = h / dh;
+
+        th = q * dh;
+        tl = dl * q;
+        for (;;) {
+            t = h - th;
+            if ((t & BN_MASK2h) ||
+                ((tl) <= ((t << BN_BITS4) | ((l & BN_MASK2h) >> BN_BITS4))))
+                break;
+            q--;
+            th -= dh;
+            tl -= dl;
+        }
+        t = (tl >> BN_BITS4);
+        tl = (tl << BN_BITS4) & BN_MASK2h;
+        th += t;
+
+        if (l < tl)
+            th++;
+        l -= tl;
+        if (h < th) {
+            h += d;
+            q--;
+        }
+        h -= th;
+
+        if (--count == 0)
+            break;
+
+        ret = q << BN_BITS4;
+        h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2;
+        l = (l & BN_MASK2l) << BN_BITS4;
+    }
+    ret |= q;
+    return (ret);
+}
+#endif                          /* !defined(BN_LLONG) && defined(BN_DIV2W) */
+
+#ifdef BN_LLONG
+BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
+                      int n)
+{
+    BN_ULLONG ll = 0;
+
+    assert(n >= 0);
+    if (n <= 0)
+        return ((BN_ULONG)0);
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+    while (n & ~3) {
+        ll += (BN_ULLONG) a[0] + b[0];
+        r[0] = (BN_ULONG)ll & BN_MASK2;
+        ll >>= BN_BITS2;
+        ll += (BN_ULLONG) a[1] + b[1];
+        r[1] = (BN_ULONG)ll & BN_MASK2;
+        ll >>= BN_BITS2;
+        ll += (BN_ULLONG) a[2] + b[2];
+        r[2] = (BN_ULONG)ll & BN_MASK2;
+        ll >>= BN_BITS2;
+        ll += (BN_ULLONG) a[3] + b[3];
+        r[3] = (BN_ULONG)ll & BN_MASK2;
+        ll >>= BN_BITS2;
+        a += 4;
+        b += 4;
+        r += 4;
+        n -= 4;
+    }
+# endif
+    while (n) {
+        ll += (BN_ULLONG) a[0] + b[0];
+        r[0] = (BN_ULONG)ll & BN_MASK2;
+        ll >>= BN_BITS2;
+        a++;
+        b++;
+        r++;
+        n--;
+    }
+    return ((BN_ULONG)ll);
+}
+#else                           /* !BN_LLONG */
+BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
+                      int n)
+{
+    BN_ULONG c, l, t;
+
+    assert(n >= 0);
+    if (n <= 0)
+        return ((BN_ULONG)0);
+
+    c = 0;
+# ifndef OPENSSL_SMALL_FOOTPRINT
+    while (n & ~3) {
+        t = a[0];
+        t = (t + c) & BN_MASK2;
+        c = (t < c);
+        l = (t + b[0]) & BN_MASK2;
+        c += (l < t);
+        r[0] = l;
+        t = a[1];
+        t = (t + c) & BN_MASK2;
+        c = (t < c);
+        l = (t + b[1]) & BN_MASK2;
+        c += (l < t);
+        r[1] = l;
+        t = a[2];
+        t = (t + c) & BN_MASK2;
+        c = (t < c);
+        l = (t + b[2]) & BN_MASK2;
+        c += (l < t);
+        r[2] = l;
+        t = a[3];
+        t = (t + c) & BN_MASK2;
+        c = (t < c);
+        l = (t + b[3]) & BN_MASK2;
+        c += (l < t);
+        r[3] = l;
+        a += 4;
+        b += 4;
+        r += 4;
+        n -= 4;
+    }
+# endif
+    while (n) {
+        t = a[0];
+        t = (t + c) & BN_MASK2;
+        c = (t < c);
+        l = (t + b[0]) & BN_MASK2;
+        c += (l < t);
+        r[0] = l;
+        a++;
+        b++;
+        r++;
+        n--;
+    }
+    return ((BN_ULONG)c);
+}
+#endif                          /* !BN_LLONG */
+
+BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
+                      int n)
+{
+    BN_ULONG t1, t2;
+    int c = 0;
+
+    assert(n >= 0);
+    if (n <= 0)
+        return ((BN_ULONG)0);
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+    while (n & ~3) {
+        t1 = a[0];
+        t2 = b[0];
+        r[0] = (t1 - t2 - c) & BN_MASK2;
+        if (t1 != t2)
+            c = (t1 < t2);
+        t1 = a[1];
+        t2 = b[1];
+        r[1] = (t1 - t2 - c) & BN_MASK2;
+        if (t1 != t2)
+            c = (t1 < t2);
+        t1 = a[2];
+        t2 = b[2];
+        r[2] = (t1 - t2 - c) & BN_MASK2;
+        if (t1 != t2)
+            c = (t1 < t2);
+        t1 = a[3];
+        t2 = b[3];
+        r[3] = (t1 - t2 - c) & BN_MASK2;
+        if (t1 != t2)
+            c = (t1 < t2);
+        a += 4;
+        b += 4;
+        r += 4;
+        n -= 4;
+    }
+#endif
+    while (n) {
+        t1 = a[0];
+        t2 = b[0];
+        r[0] = (t1 - t2 - c) & BN_MASK2;
+        if (t1 != t2)
+            c = (t1 < t2);
+        a++;
+        b++;
+        r++;
+        n--;
+    }
+    return (c);
+}
+
+#if defined(BN_MUL_COMBA) && !defined(OPENSSL_SMALL_FOOTPRINT)
+
+# undef bn_mul_comba8
+# undef bn_mul_comba4
+# undef bn_sqr_comba8
+# undef bn_sqr_comba4
+
+/* mul_add_c(a,b,c0,c1,c2)  -- c+=a*b for three word number c=(c2,c1,c0) */
+/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */
+/* sqr_add_c(a,i,c0,c1,c2)  -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
+/*
+ * sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number
+ * c=(c2,c1,c0)
+ */
+
+# ifdef BN_LLONG
+/*
+ * Keep in mind that additions to multiplication result can not
+ * overflow, because its high half cannot be all-ones.
+ */
+#  define mul_add_c(a,b,c0,c1,c2)       do {    \
+        BN_ULONG hi;                            \
+        BN_ULLONG t = (BN_ULLONG)(a)*(b);       \
+        t += c0;                /* no carry */  \
+        c0 = (BN_ULONG)Lw(t);                   \
+        hi = (BN_ULONG)Hw(t);                   \
+        c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+        } while(0)
+
+#  define mul_add_c2(a,b,c0,c1,c2)      do {    \
+        BN_ULONG hi;                            \
+        BN_ULLONG t = (BN_ULLONG)(a)*(b);       \
+        BN_ULLONG tt = t+c0;    /* no carry */  \
+        c0 = (BN_ULONG)Lw(tt);                  \
+        hi = (BN_ULONG)Hw(tt);                  \
+        c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+        t += c0;                /* no carry */  \
+        c0 = (BN_ULONG)Lw(t);                   \
+        hi = (BN_ULONG)Hw(t);                   \
+        c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+        } while(0)
+
+#  define sqr_add_c(a,i,c0,c1,c2)       do {    \
+        BN_ULONG hi;                            \
+        BN_ULLONG t = (BN_ULLONG)a[i]*a[i];     \
+        t += c0;                /* no carry */  \
+        c0 = (BN_ULONG)Lw(t);                   \
+        hi = (BN_ULONG)Hw(t);                   \
+        c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+        } while(0)
+
+#  define sqr_add_c2(a,i,j,c0,c1,c2) \
+        mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+
+# elif defined(BN_UMULT_LOHI)
+/*
+ * Keep in mind that additions to hi can not overflow, because
+ * the high word of a multiplication result cannot be all-ones.
+ */
+#  define mul_add_c(a,b,c0,c1,c2)       do {    \
+        BN_ULONG ta = (a), tb = (b);            \
+        BN_ULONG lo, hi;                        \
+        BN_UMULT_LOHI(lo,hi,ta,tb);             \
+        c0 += lo; hi += (c0<lo)?1:0;            \
+        c1 += hi; c2 += (c1<hi)?1:0;            \
+        } while(0)
+
+#  define mul_add_c2(a,b,c0,c1,c2)      do {    \
+        BN_ULONG ta = (a), tb = (b);            \
+        BN_ULONG lo, hi, tt;                    \
+        BN_UMULT_LOHI(lo,hi,ta,tb);             \
+        c0 += lo; tt = hi+((c0<lo)?1:0);        \
+        c1 += tt; c2 += (c1<tt)?1:0;            \
+        c0 += lo; hi += (c0<lo)?1:0;            \
+        c1 += hi; c2 += (c1<hi)?1:0;            \
+        } while(0)
+
+#  define sqr_add_c(a,i,c0,c1,c2)       do {    \
+        BN_ULONG ta = (a)[i];                   \
+        BN_ULONG lo, hi;                        \
+        BN_UMULT_LOHI(lo,hi,ta,ta);             \
+        c0 += lo; hi += (c0<lo)?1:0;            \
+        c1 += hi; c2 += (c1<hi)?1:0;            \
+        } while(0)
+
+#  define sqr_add_c2(a,i,j,c0,c1,c2)    \
+        mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+
+# elif defined(BN_UMULT_HIGH)
+/*
+ * Keep in mind that additions to hi can not overflow, because
+ * the high word of a multiplication result cannot be all-ones.
+ */
+#  define mul_add_c(a,b,c0,c1,c2)       do {    \
+        BN_ULONG ta = (a), tb = (b);            \
+        BN_ULONG lo = ta * tb;                  \
+        BN_ULONG hi = BN_UMULT_HIGH(ta,tb);     \
+        c0 += lo; hi += (c0<lo)?1:0;            \
+        c1 += hi; c2 += (c1<hi)?1:0;            \
+        } while(0)
+
+#  define mul_add_c2(a,b,c0,c1,c2)      do {    \
+        BN_ULONG ta = (a), tb = (b), tt;        \
+        BN_ULONG lo = ta * tb;                  \
+        BN_ULONG hi = BN_UMULT_HIGH(ta,tb);     \
+        c0 += lo; tt = hi + ((c0<lo)?1:0);      \
+        c1 += tt; c2 += (c1<tt)?1:0;            \
+        c0 += lo; hi += (c0<lo)?1:0;            \
+        c1 += hi; c2 += (c1<hi)?1:0;            \
+        } while(0)
+
+#  define sqr_add_c(a,i,c0,c1,c2)       do {    \
+        BN_ULONG ta = (a)[i];                   \
+        BN_ULONG lo = ta * ta;                  \
+        BN_ULONG hi = BN_UMULT_HIGH(ta,ta);     \
+        c0 += lo; hi += (c0<lo)?1:0;            \
+        c1 += hi; c2 += (c1<hi)?1:0;            \
+        } while(0)
+
+#  define sqr_add_c2(a,i,j,c0,c1,c2)      \
+        mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+
+# else                          /* !BN_LLONG */
+/*
+ * Keep in mind that additions to hi can not overflow, because
+ * the high word of a multiplication result cannot be all-ones.
+ */
+#  define mul_add_c(a,b,c0,c1,c2)       do {    \
+        BN_ULONG lo = LBITS(a), hi = HBITS(a);  \
+        BN_ULONG bl = LBITS(b), bh = HBITS(b);  \
+        mul64(lo,hi,bl,bh);                     \
+        c0 = (c0+lo)&BN_MASK2; if (c0<lo) hi++; \
+        c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+        } while(0)
+
+#  define mul_add_c2(a,b,c0,c1,c2)      do {    \
+        BN_ULONG tt;                            \
+        BN_ULONG lo = LBITS(a), hi = HBITS(a);  \
+        BN_ULONG bl = LBITS(b), bh = HBITS(b);  \
+        mul64(lo,hi,bl,bh);                     \
+        tt = hi;                                \
+        c0 = (c0+lo)&BN_MASK2; if (c0<lo) tt++; \
+        c1 = (c1+tt)&BN_MASK2; if (c1<tt) c2++; \
+        c0 = (c0+lo)&BN_MASK2; if (c0<lo) hi++; \
+        c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+        } while(0)
+
+#  define sqr_add_c(a,i,c0,c1,c2)       do {    \
+        BN_ULONG lo, hi;                        \
+        sqr64(lo,hi,(a)[i]);                    \
+        c0 = (c0+lo)&BN_MASK2; if (c0<lo) hi++; \
+        c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+        } while(0)
+
+#  define sqr_add_c2(a,i,j,c0,c1,c2) \
+        mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+# endif                         /* !BN_LLONG */
+
+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+{
+    BN_ULONG c1, c2, c3;
+
+    c1 = 0;
+    c2 = 0;
+    c3 = 0;
+    mul_add_c(a[0], b[0], c1, c2, c3);
+    r[0] = c1;
+    c1 = 0;
+    mul_add_c(a[0], b[1], c2, c3, c1);
+    mul_add_c(a[1], b[0], c2, c3, c1);
+    r[1] = c2;
+    c2 = 0;
+    mul_add_c(a[2], b[0], c3, c1, c2);
+    mul_add_c(a[1], b[1], c3, c1, c2);
+    mul_add_c(a[0], b[2], c3, c1, c2);
+    r[2] = c3;
+    c3 = 0;
+    mul_add_c(a[0], b[3], c1, c2, c3);
+    mul_add_c(a[1], b[2], c1, c2, c3);
+    mul_add_c(a[2], b[1], c1, c2, c3);
+    mul_add_c(a[3], b[0], c1, c2, c3);
+    r[3] = c1;
+    c1 = 0;
+    mul_add_c(a[4], b[0], c2, c3, c1);
+    mul_add_c(a[3], b[1], c2, c3, c1);
+    mul_add_c(a[2], b[2], c2, c3, c1);
+    mul_add_c(a[1], b[3], c2, c3, c1);
+    mul_add_c(a[0], b[4], c2, c3, c1);
+    r[4] = c2;
+    c2 = 0;
+    mul_add_c(a[0], b[5], c3, c1, c2);
+    mul_add_c(a[1], b[4], c3, c1, c2);
+    mul_add_c(a[2], b[3], c3, c1, c2);
+    mul_add_c(a[3], b[2], c3, c1, c2);
+    mul_add_c(a[4], b[1], c3, c1, c2);
+    mul_add_c(a[5], b[0], c3, c1, c2);
+    r[5] = c3;
+    c3 = 0;
+    mul_add_c(a[6], b[0], c1, c2, c3);
+    mul_add_c(a[5], b[1], c1, c2, c3);
+    mul_add_c(a[4], b[2], c1, c2, c3);
+    mul_add_c(a[3], b[3], c1, c2, c3);
+    mul_add_c(a[2], b[4], c1, c2, c3);
+    mul_add_c(a[1], b[5], c1, c2, c3);
+    mul_add_c(a[0], b[6], c1, c2, c3);
+    r[6] = c1;
+    c1 = 0;
+    mul_add_c(a[0], b[7], c2, c3, c1);
+    mul_add_c(a[1], b[6], c2, c3, c1);
+    mul_add_c(a[2], b[5], c2, c3, c1);
+    mul_add_c(a[3], b[4], c2, c3, c1);
+    mul_add_c(a[4], b[3], c2, c3, c1);
+    mul_add_c(a[5], b[2], c2, c3, c1);
+    mul_add_c(a[6], b[1], c2, c3, c1);
+    mul_add_c(a[7], b[0], c2, c3, c1);
+    r[7] = c2;
+    c2 = 0;
+    mul_add_c(a[7], b[1], c3, c1, c2);
+    mul_add_c(a[6], b[2], c3, c1, c2);
+    mul_add_c(a[5], b[3], c3, c1, c2);
+    mul_add_c(a[4], b[4], c3, c1, c2);
+    mul_add_c(a[3], b[5], c3, c1, c2);
+    mul_add_c(a[2], b[6], c3, c1, c2);
+    mul_add_c(a[1], b[7], c3, c1, c2);
+    r[8] = c3;
+    c3 = 0;
+    mul_add_c(a[2], b[7], c1, c2, c3);
+    mul_add_c(a[3], b[6], c1, c2, c3);
+    mul_add_c(a[4], b[5], c1, c2, c3);
+    mul_add_c(a[5], b[4], c1, c2, c3);
+    mul_add_c(a[6], b[3], c1, c2, c3);
+    mul_add_c(a[7], b[2], c1, c2, c3);
+    r[9] = c1;
+    c1 = 0;
+    mul_add_c(a[7], b[3], c2, c3, c1);
+    mul_add_c(a[6], b[4], c2, c3, c1);
+    mul_add_c(a[5], b[5], c2, c3, c1);
+    mul_add_c(a[4], b[6], c2, c3, c1);
+    mul_add_c(a[3], b[7], c2, c3, c1);
+    r[10] = c2;
+    c2 = 0;
+    mul_add_c(a[4], b[7], c3, c1, c2);
+    mul_add_c(a[5], b[6], c3, c1, c2);
+    mul_add_c(a[6], b[5], c3, c1, c2);
+    mul_add_c(a[7], b[4], c3, c1, c2);
+    r[11] = c3;
+    c3 = 0;
+    mul_add_c(a[7], b[5], c1, c2, c3);
+    mul_add_c(a[6], b[6], c1, c2, c3);
+    mul_add_c(a[5], b[7], c1, c2, c3);
+    r[12] = c1;
+    c1 = 0;
+    mul_add_c(a[6], b[7], c2, c3, c1);
+    mul_add_c(a[7], b[6], c2, c3, c1);
+    r[13] = c2;
+    c2 = 0;
+    mul_add_c(a[7], b[7], c3, c1, c2);
+    r[14] = c3;
+    r[15] = c1;
+}
+
+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+{
+    BN_ULONG c1, c2, c3;
+
+    c1 = 0;
+    c2 = 0;
+    c3 = 0;
+    mul_add_c(a[0], b[0], c1, c2, c3);
+    r[0] = c1;
+    c1 = 0;
+    mul_add_c(a[0], b[1], c2, c3, c1);
+    mul_add_c(a[1], b[0], c2, c3, c1);
+    r[1] = c2;
+    c2 = 0;
+    mul_add_c(a[2], b[0], c3, c1, c2);
+    mul_add_c(a[1], b[1], c3, c1, c2);
+    mul_add_c(a[0], b[2], c3, c1, c2);
+    r[2] = c3;
+    c3 = 0;
+    mul_add_c(a[0], b[3], c1, c2, c3);
+    mul_add_c(a[1], b[2], c1, c2, c3);
+    mul_add_c(a[2], b[1], c1, c2, c3);
+    mul_add_c(a[3], b[0], c1, c2, c3);
+    r[3] = c1;
+    c1 = 0;
+    mul_add_c(a[3], b[1], c2, c3, c1);
+    mul_add_c(a[2], b[2], c2, c3, c1);
+    mul_add_c(a[1], b[3], c2, c3, c1);
+    r[4] = c2;
+    c2 = 0;
+    mul_add_c(a[2], b[3], c3, c1, c2);
+    mul_add_c(a[3], b[2], c3, c1, c2);
+    r[5] = c3;
+    c3 = 0;
+    mul_add_c(a[3], b[3], c1, c2, c3);
+    r[6] = c1;
+    r[7] = c2;
+}
+
+void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
+{
+    BN_ULONG c1, c2, c3;
+
+    c1 = 0;
+    c2 = 0;
+    c3 = 0;
+    sqr_add_c(a, 0, c1, c2, c3);
+    r[0] = c1;
+    c1 = 0;
+    sqr_add_c2(a, 1, 0, c2, c3, c1);
+    r[1] = c2;
+    c2 = 0;
+    sqr_add_c(a, 1, c3, c1, c2);
+    sqr_add_c2(a, 2, 0, c3, c1, c2);
+    r[2] = c3;
+    c3 = 0;
+    sqr_add_c2(a, 3, 0, c1, c2, c3);
+    sqr_add_c2(a, 2, 1, c1, c2, c3);
+    r[3] = c1;
+    c1 = 0;
+    sqr_add_c(a, 2, c2, c3, c1);
+    sqr_add_c2(a, 3, 1, c2, c3, c1);
+    sqr_add_c2(a, 4, 0, c2, c3, c1);
+    r[4] = c2;
+    c2 = 0;
+    sqr_add_c2(a, 5, 0, c3, c1, c2);
+    sqr_add_c2(a, 4, 1, c3, c1, c2);
+    sqr_add_c2(a, 3, 2, c3, c1, c2);
+    r[5] = c3;
+    c3 = 0;
+    sqr_add_c(a, 3, c1, c2, c3);
+    sqr_add_c2(a, 4, 2, c1, c2, c3);
+    sqr_add_c2(a, 5, 1, c1, c2, c3);
+    sqr_add_c2(a, 6, 0, c1, c2, c3);
+    r[6] = c1;
+    c1 = 0;
+    sqr_add_c2(a, 7, 0, c2, c3, c1);
+    sqr_add_c2(a, 6, 1, c2, c3, c1);
+    sqr_add_c2(a, 5, 2, c2, c3, c1);
+    sqr_add_c2(a, 4, 3, c2, c3, c1);
+    r[7] = c2;
+    c2 = 0;
+    sqr_add_c(a, 4, c3, c1, c2);
+    sqr_add_c2(a, 5, 3, c3, c1, c2);
+    sqr_add_c2(a, 6, 2, c3, c1, c2);
+    sqr_add_c2(a, 7, 1, c3, c1, c2);
+    r[8] = c3;
+    c3 = 0;
+    sqr_add_c2(a, 7, 2, c1, c2, c3);
+    sqr_add_c2(a, 6, 3, c1, c2, c3);
+    sqr_add_c2(a, 5, 4, c1, c2, c3);
+    r[9] = c1;
+    c1 = 0;
+    sqr_add_c(a, 5, c2, c3, c1);
+    sqr_add_c2(a, 6, 4, c2, c3, c1);
+    sqr_add_c2(a, 7, 3, c2, c3, c1);
+    r[10] = c2;
+    c2 = 0;
+    sqr_add_c2(a, 7, 4, c3, c1, c2);
+    sqr_add_c2(a, 6, 5, c3, c1, c2);
+    r[11] = c3;
+    c3 = 0;
+    sqr_add_c(a, 6, c1, c2, c3);
+    sqr_add_c2(a, 7, 5, c1, c2, c3);
+    r[12] = c1;
+    c1 = 0;
+    sqr_add_c2(a, 7, 6, c2, c3, c1);
+    r[13] = c2;
+    c2 = 0;
+    sqr_add_c(a, 7, c3, c1, c2);
+    r[14] = c3;
+    r[15] = c1;
+}
+
+void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
+{
+    BN_ULONG c1, c2, c3;
+
+    c1 = 0;
+    c2 = 0;
+    c3 = 0;
+    sqr_add_c(a, 0, c1, c2, c3);
+    r[0] = c1;
+    c1 = 0;
+    sqr_add_c2(a, 1, 0, c2, c3, c1);
+    r[1] = c2;
+    c2 = 0;
+    sqr_add_c(a, 1, c3, c1, c2);
+    sqr_add_c2(a, 2, 0, c3, c1, c2);
+    r[2] = c3;
+    c3 = 0;
+    sqr_add_c2(a, 3, 0, c1, c2, c3);
+    sqr_add_c2(a, 2, 1, c1, c2, c3);
+    r[3] = c1;
+    c1 = 0;
+    sqr_add_c(a, 2, c2, c3, c1);
+    sqr_add_c2(a, 3, 1, c2, c3, c1);
+    r[4] = c2;
+    c2 = 0;
+    sqr_add_c2(a, 3, 2, c3, c1, c2);
+    r[5] = c3;
+    c3 = 0;
+    sqr_add_c(a, 3, c1, c2, c3);
+    r[6] = c1;
+    r[7] = c2;
+}
+
+# ifdef OPENSSL_NO_ASM
+#  ifdef OPENSSL_BN_ASM_MONT
+#   include <alloca.h>
+/*
+ * This is essentially reference implementation, which may or may not
+ * result in performance improvement. E.g. on IA-32 this routine was
+ * observed to give 40% faster rsa1024 private key operations and 10%
+ * faster rsa4096 ones, while on AMD64 it improves rsa1024 sign only
+ * by 10% and *worsens* rsa4096 sign by 15%. Once again, it's a
+ * reference implementation, one to be used as starting point for
+ * platform-specific assembler. Mentioned numbers apply to compiler
+ * generated code compiled with and without -DOPENSSL_BN_ASM_MONT and
+ * can vary not only from platform to platform, but even for compiler
+ * versions. Assembler vs. assembler improvement coefficients can
+ * [and are known to] differ and are to be documented elsewhere.
+ */
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+                const BN_ULONG *np, const BN_ULONG *n0p, int num)
+{
+    BN_ULONG c0, c1, ml, *tp, n0;
+#   ifdef mul64
+    BN_ULONG mh;
+#   endif
+    volatile BN_ULONG *vp;
+    int i = 0, j;
+
+#   if 0                        /* template for platform-specific
+                                 * implementation */
+    if (ap == bp)
+        return bn_sqr_mont(rp, ap, np, n0p, num);
+#   endif
+    vp = tp = alloca((num + 2) * sizeof(BN_ULONG));
+
+    n0 = *n0p;
+
+    c0 = 0;
+    ml = bp[0];
+#   ifdef mul64
+    mh = HBITS(ml);
+    ml = LBITS(ml);
+    for (j = 0; j < num; ++j)
+        mul(tp[j], ap[j], ml, mh, c0);
+#   else
+    for (j = 0; j < num; ++j)
+        mul(tp[j], ap[j], ml, c0);
+#   endif
+
+    tp[num] = c0;
+    tp[num + 1] = 0;
+    goto enter;
+
+    for (i = 0; i < num; i++) {
+        c0 = 0;
+        ml = bp[i];
+#   ifdef mul64
+        mh = HBITS(ml);
+        ml = LBITS(ml);
+        for (j = 0; j < num; ++j)
+            mul_add(tp[j], ap[j], ml, mh, c0);
+#   else
+        for (j = 0; j < num; ++j)
+            mul_add(tp[j], ap[j], ml, c0);
+#   endif
+        c1 = (tp[num] + c0) & BN_MASK2;
+        tp[num] = c1;
+        tp[num + 1] = (c1 < c0 ? 1 : 0);
+ enter:
+        c1 = tp[0];
+        ml = (c1 * n0) & BN_MASK2;
+        c0 = 0;
+#   ifdef mul64
+        mh = HBITS(ml);
+        ml = LBITS(ml);
+        mul_add(c1, np[0], ml, mh, c0);
+#   else
+        mul_add(c1, ml, np[0], c0);
+#   endif
+        for (j = 1; j < num; j++) {
+            c1 = tp[j];
+#   ifdef mul64
+            mul_add(c1, np[j], ml, mh, c0);
+#   else
+            mul_add(c1, ml, np[j], c0);
+#   endif
+            tp[j - 1] = c1 & BN_MASK2;
+        }
+        c1 = (tp[num] + c0) & BN_MASK2;
+        tp[num - 1] = c1;
+        tp[num] = tp[num + 1] + (c1 < c0 ? 1 : 0);
+    }
+
+    if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) {
+        c0 = bn_sub_words(rp, tp, np, num);
+        if (tp[num] != 0 || c0 == 0) {
+            for (i = 0; i < num + 2; i++)
+                vp[i] = 0;
+            return 1;
+        }
+    }
+    for (i = 0; i < num; i++)
+        rp[i] = tp[i], vp[i] = 0;
+    vp[num] = 0;
+    vp[num + 1] = 0;
+    return 1;
+}
+#  else
+/*
+ * Return value of 0 indicates that multiplication/convolution was not
+ * performed to signal the caller to fall down to alternative/original
+ * code-path.
+ */
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+                const BN_ULONG *np, const BN_ULONG *n0, int num)
+{
+    return 0;
+}
+#  endif                        /* OPENSSL_BN_ASM_MONT */
+# endif
+
+#else                           /* !BN_MUL_COMBA */
+
+/* hmm... is it faster just to do a multiply? */
+# undef bn_sqr_comba4
+# undef bn_sqr_comba8
+void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
+{
+    BN_ULONG t[8];
+    bn_sqr_normal(r, a, 4, t);
+}
+
+void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
+{
+    BN_ULONG t[16];
+    bn_sqr_normal(r, a, 8, t);
+}
+
+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+{
+    r[4] = bn_mul_words(&(r[0]), a, 4, b[0]);
+    r[5] = bn_mul_add_words(&(r[1]), a, 4, b[1]);
+    r[6] = bn_mul_add_words(&(r[2]), a, 4, b[2]);
+    r[7] = bn_mul_add_words(&(r[3]), a, 4, b[3]);
+}
+
+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+{
+    r[8] = bn_mul_words(&(r[0]), a, 8, b[0]);
+    r[9] = bn_mul_add_words(&(r[1]), a, 8, b[1]);
+    r[10] = bn_mul_add_words(&(r[2]), a, 8, b[2]);
+    r[11] = bn_mul_add_words(&(r[3]), a, 8, b[3]);
+    r[12] = bn_mul_add_words(&(r[4]), a, 8, b[4]);
+    r[13] = bn_mul_add_words(&(r[5]), a, 8, b[5]);
+    r[14] = bn_mul_add_words(&(r[6]), a, 8, b[6]);
+    r[15] = bn_mul_add_words(&(r[7]), a, 8, b[7]);
+}
+
+# ifdef OPENSSL_NO_ASM
+#  ifdef OPENSSL_BN_ASM_MONT
+#   include <alloca.h>
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+                const BN_ULONG *np, const BN_ULONG *n0p, int num)
+{
+    BN_ULONG c0, c1, *tp, n0 = *n0p;
+    volatile BN_ULONG *vp;
+    int i = 0, j;
+
+    vp = tp = alloca((num + 2) * sizeof(BN_ULONG));
+
+    for (i = 0; i <= num; i++)
+        tp[i] = 0;
+
+    for (i = 0; i < num; i++) {
+        c0 = bn_mul_add_words(tp, ap, num, bp[i]);
+        c1 = (tp[num] + c0) & BN_MASK2;
+        tp[num] = c1;
+        tp[num + 1] = (c1 < c0 ? 1 : 0);
+
+        c0 = bn_mul_add_words(tp, np, num, tp[0] * n0);
+        c1 = (tp[num] + c0) & BN_MASK2;
+        tp[num] = c1;
+        tp[num + 1] += (c1 < c0 ? 1 : 0);
+        for (j = 0; j <= num; j++)
+            tp[j] = tp[j + 1];
+    }
+
+    if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) {
+        c0 = bn_sub_words(rp, tp, np, num);
+        if (tp[num] != 0 || c0 == 0) {
+            for (i = 0; i < num + 2; i++)
+                vp[i] = 0;
+            return 1;
+        }
+    }
+    for (i = 0; i < num; i++)
+        rp[i] = tp[i], vp[i] = 0;
+    vp[num] = 0;
+    vp[num + 1] = 0;
+    return 1;
+}
+#  else
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+                const BN_ULONG *np, const BN_ULONG *n0, int num)
+{
+    return 0;
+}
+#  endif                        /* OPENSSL_BN_ASM_MONT */
+# endif
+
+#endif                          /* !BN_MUL_COMBA */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_blind.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_blind.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_blind.c	(revision 331)
@@ -0,0 +1,289 @@
+/*
+ * Copyright 1998-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 <openssl/opensslconf.h>
+#include "internal/cryptlib.h"
+#include "bn_lcl.h"
+
+#define BN_BLINDING_COUNTER     32
+
+struct bn_blinding_st {
+    BIGNUM *A;
+    BIGNUM *Ai;
+    BIGNUM *e;
+    BIGNUM *mod;                /* just a reference */
+    CRYPTO_THREAD_ID tid;
+    int counter;
+    unsigned long flags;
+    BN_MONT_CTX *m_ctx;
+    int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+    CRYPTO_RWLOCK *lock;
+};
+
+BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
+{
+    BN_BLINDING *ret = NULL;
+
+    bn_check_top(mod);
+
+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
+        BNerr(BN_F_BN_BLINDING_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        BNerr(BN_F_BN_BLINDING_NEW, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ret);
+        return NULL;
+    }
+
+    BN_BLINDING_set_current_thread(ret);
+
+    if (A != NULL) {
+        if ((ret->A = BN_dup(A)) == NULL)
+            goto err;
+    }
+
+    if (Ai != NULL) {
+        if ((ret->Ai = BN_dup(Ai)) == NULL)
+            goto err;
+    }
+
+    /* save a copy of mod in the BN_BLINDING structure */
+    if ((ret->mod = BN_dup(mod)) == NULL)
+        goto err;
+
+    if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0)
+        BN_set_flags(ret->mod, BN_FLG_CONSTTIME);
+
+    /*
+     * Set the counter to the special value -1 to indicate that this is
+     * never-used fresh blinding that does not need updating before first
+     * use.
+     */
+    ret->counter = -1;
+
+    return ret;
+
+ err:
+    BN_BLINDING_free(ret);
+    return NULL;
+}
+
+void BN_BLINDING_free(BN_BLINDING *r)
+{
+    if (r == NULL)
+        return;
+
+    BN_free(r->A);
+    BN_free(r->Ai);
+    BN_free(r->e);
+    BN_free(r->mod);
+    CRYPTO_THREAD_lock_free(r->lock);
+    OPENSSL_free(r);
+}
+
+int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx)
+{
+    int ret = 0;
+
+    if ((b->A == NULL) || (b->Ai == NULL)) {
+        BNerr(BN_F_BN_BLINDING_UPDATE, BN_R_NOT_INITIALIZED);
+        goto err;
+    }
+
+    if (b->counter == -1)
+        b->counter = 0;
+
+    if (++b->counter == BN_BLINDING_COUNTER && b->e != NULL &&
+        !(b->flags & BN_BLINDING_NO_RECREATE)) {
+        /* re-create blinding parameters */
+        if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL))
+            goto err;
+    } else if (!(b->flags & BN_BLINDING_NO_UPDATE)) {
+        if (!BN_mod_mul(b->A, b->A, b->A, b->mod, ctx))
+            goto err;
+        if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx))
+            goto err;
+    }
+
+    ret = 1;
+ err:
+    if (b->counter == BN_BLINDING_COUNTER)
+        b->counter = 0;
+    return (ret);
+}
+
+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
+{
+    return BN_BLINDING_convert_ex(n, NULL, b, ctx);
+}
+
+int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
+{
+    int ret = 1;
+
+    bn_check_top(n);
+
+    if ((b->A == NULL) || (b->Ai == NULL)) {
+        BNerr(BN_F_BN_BLINDING_CONVERT_EX, BN_R_NOT_INITIALIZED);
+        return (0);
+    }
+
+    if (b->counter == -1)
+        /* Fresh blinding, doesn't need updating. */
+        b->counter = 0;
+    else if (!BN_BLINDING_update(b, ctx))
+        return (0);
+
+    if (r != NULL) {
+        if (!BN_copy(r, b->Ai))
+            ret = 0;
+    }
+
+    if (!BN_mod_mul(n, n, b->A, b->mod, ctx))
+        ret = 0;
+
+    return ret;
+}
+
+int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
+{
+    return BN_BLINDING_invert_ex(n, NULL, b, ctx);
+}
+
+int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,
+                          BN_CTX *ctx)
+{
+    int ret;
+
+    bn_check_top(n);
+
+    if (r != NULL)
+        ret = BN_mod_mul(n, n, r, b->mod, ctx);
+    else {
+        if (b->Ai == NULL) {
+            BNerr(BN_F_BN_BLINDING_INVERT_EX, BN_R_NOT_INITIALIZED);
+            return (0);
+        }
+        ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx);
+    }
+
+    bn_check_top(n);
+    return (ret);
+}
+
+int BN_BLINDING_is_current_thread(BN_BLINDING *b)
+{
+    return CRYPTO_THREAD_compare_id(CRYPTO_THREAD_get_current_id(), b->tid);
+}
+
+void BN_BLINDING_set_current_thread(BN_BLINDING *b)
+{
+    b->tid = CRYPTO_THREAD_get_current_id();
+}
+
+int BN_BLINDING_lock(BN_BLINDING *b)
+{
+    return CRYPTO_THREAD_write_lock(b->lock);
+}
+
+int BN_BLINDING_unlock(BN_BLINDING *b)
+{
+    return CRYPTO_THREAD_unlock(b->lock);
+}
+
+unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b)
+{
+    return b->flags;
+}
+
+void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags)
+{
+    b->flags = flags;
+}
+
+BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
+                                      const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
+                                      int (*bn_mod_exp) (BIGNUM *r,
+                                                         const BIGNUM *a,
+                                                         const BIGNUM *p,
+                                                         const BIGNUM *m,
+                                                         BN_CTX *ctx,
+                                                         BN_MONT_CTX *m_ctx),
+                                      BN_MONT_CTX *m_ctx)
+{
+    int retry_counter = 32;
+    BN_BLINDING *ret = NULL;
+
+    if (b == NULL)
+        ret = BN_BLINDING_new(NULL, NULL, m);
+    else
+        ret = b;
+
+    if (ret == NULL)
+        goto err;
+
+    if (ret->A == NULL && (ret->A = BN_new()) == NULL)
+        goto err;
+    if (ret->Ai == NULL && (ret->Ai = BN_new()) == NULL)
+        goto err;
+
+    if (e != NULL) {
+        BN_free(ret->e);
+        ret->e = BN_dup(e);
+    }
+    if (ret->e == NULL)
+        goto err;
+
+    if (bn_mod_exp != NULL)
+        ret->bn_mod_exp = bn_mod_exp;
+    if (m_ctx != NULL)
+        ret->m_ctx = m_ctx;
+
+    do {
+        int rv;
+        if (!BN_rand_range(ret->A, ret->mod))
+            goto err;
+        if (!int_bn_mod_inverse(ret->Ai, ret->A, ret->mod, ctx, &rv)) {
+            /*
+             * this should almost never happen for good RSA keys
+             */
+            if (rv) {
+                if (retry_counter-- == 0) {
+                    BNerr(BN_F_BN_BLINDING_CREATE_PARAM,
+                          BN_R_TOO_MANY_ITERATIONS);
+                    goto err;
+                }
+            } else
+                goto err;
+        } else
+            break;
+    } while (1);
+
+    if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL) {
+        if (!ret->bn_mod_exp
+            (ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx))
+            goto err;
+    } else {
+        if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx))
+            goto err;
+    }
+
+    return ret;
+ err:
+    if (b == NULL) {
+        BN_BLINDING_free(ret);
+        ret = NULL;
+    }
+
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_const.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_const.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_const.c	(revision 331)
@@ -0,0 +1,553 @@
+/*
+ * Copyright 2005-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 <openssl/bn.h>
+
+/*-
+ * "First Oakley Default Group" from RFC2409, section 6.1.
+ *
+ * The prime is: 2^768 - 2 ^704 - 1 + 2^64 * { [2^638 pi] + 149686 }
+ *
+ * RFC2409 specifies a generator of 2.
+ * RFC2412 specifies a generator of of 22.
+ */
+
+BIGNUM *BN_get_rfc2409_prime_768(BIGNUM *bn)
+{
+    static const unsigned char RFC2409_PRIME_768[] = {
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+        0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+        0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+        0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+        0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+        0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+        0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x3A, 0x36, 0x20,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    };
+    return BN_bin2bn(RFC2409_PRIME_768, sizeof(RFC2409_PRIME_768), bn);
+}
+
+/*-
+ * "Second Oakley Default Group" from RFC2409, section 6.2.
+ *
+ * The prime is: 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }.
+ *
+ * RFC2409 specifies a generator of 2.
+ * RFC2412 specifies a generator of 22.
+ */
+
+BIGNUM *BN_get_rfc2409_prime_1024(BIGNUM *bn)
+{
+    static const unsigned char RFC2409_PRIME_1024[] = {
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+        0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+        0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+        0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+        0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+        0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+        0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+        0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+        0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+        0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+        0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    };
+    return BN_bin2bn(RFC2409_PRIME_1024, sizeof(RFC2409_PRIME_1024), bn);
+}
+
+/*-
+ * "1536-bit MODP Group" from RFC3526, Section 2.
+ *
+ * The prime is: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 }
+ *
+ * RFC3526 specifies a generator of 2.
+ * RFC2312 specifies a generator of 22.
+ */
+
+BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *bn)
+{
+    static const unsigned char RFC3526_PRIME_1536[] = {
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+        0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+        0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+        0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+        0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+        0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+        0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+        0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+        0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+        0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+        0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+        0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+        0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+        0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+        0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+        0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+        0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+        0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+        0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x23, 0x73, 0x27,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    };
+    return BN_bin2bn(RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536), bn);
+}
+
+/*-
+ * "2048-bit MODP Group" from RFC3526, Section 3.
+ *
+ * The prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *BN_get_rfc3526_prime_2048(BIGNUM *bn)
+{
+    static const unsigned char RFC3526_PRIME_2048[] = {
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+        0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+        0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+        0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+        0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+        0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+        0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+        0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+        0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+        0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+        0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+        0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+        0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+        0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+        0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+        0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+        0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+        0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+        0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+        0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+        0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+        0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+        0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+        0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+        0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+        0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+        0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    };
+    return BN_bin2bn(RFC3526_PRIME_2048, sizeof(RFC3526_PRIME_2048), bn);
+}
+
+/*-
+ * "3072-bit MODP Group" from RFC3526, Section 4.
+ *
+ * The prime is: 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *BN_get_rfc3526_prime_3072(BIGNUM *bn)
+{
+    static const unsigned char RFC3526_PRIME_3072[] = {
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+        0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+        0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+        0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+        0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+        0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+        0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+        0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+        0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+        0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+        0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+        0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+        0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+        0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+        0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+        0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+        0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+        0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+        0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+        0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+        0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+        0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+        0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+        0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+        0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+        0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+        0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
+        0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
+        0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+        0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
+        0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
+        0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+        0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
+        0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
+        0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+        0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
+        0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
+        0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+        0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
+        0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
+        0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+        0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
+        0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    };
+    return BN_bin2bn(RFC3526_PRIME_3072, sizeof(RFC3526_PRIME_3072), bn);
+}
+
+/*-
+ * "4096-bit MODP Group" from RFC3526, Section 5.
+ *
+ * The prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *BN_get_rfc3526_prime_4096(BIGNUM *bn)
+{
+    static const unsigned char RFC3526_PRIME_4096[] = {
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+        0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+        0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+        0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+        0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+        0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+        0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+        0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+        0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+        0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+        0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+        0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+        0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+        0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+        0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+        0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+        0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+        0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+        0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+        0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+        0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+        0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+        0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+        0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+        0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+        0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+        0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
+        0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
+        0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+        0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
+        0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
+        0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+        0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
+        0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
+        0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+        0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
+        0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
+        0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+        0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
+        0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
+        0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+        0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
+        0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
+        0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
+        0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
+        0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
+        0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
+        0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
+        0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
+        0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
+        0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
+        0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
+        0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
+        0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
+        0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
+        0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
+        0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
+        0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
+        0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    };
+    return BN_bin2bn(RFC3526_PRIME_4096, sizeof(RFC3526_PRIME_4096), bn);
+}
+
+/*-
+ * "6144-bit MODP Group" from RFC3526, Section 6.
+ *
+ * The prime is: 2^6144 - 2^6080 - 1 + 2^64 * { [2^6014 pi] + 929484 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *BN_get_rfc3526_prime_6144(BIGNUM *bn)
+{
+    static const unsigned char RFC3526_PRIME_6144[] = {
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+        0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+        0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+        0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+        0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+        0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+        0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+        0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+        0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+        0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+        0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+        0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+        0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+        0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+        0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+        0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+        0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+        0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+        0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+        0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+        0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+        0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+        0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+        0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+        0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+        0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+        0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
+        0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
+        0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+        0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
+        0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
+        0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+        0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
+        0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
+        0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+        0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
+        0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
+        0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+        0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
+        0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
+        0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+        0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
+        0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
+        0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
+        0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
+        0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
+        0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
+        0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
+        0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
+        0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
+        0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
+        0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
+        0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
+        0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
+        0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
+        0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
+        0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
+        0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
+        0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92,
+        0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26,
+        0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE,
+        0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD,
+        0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E,
+        0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE,
+        0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31,
+        0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18,
+        0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED,
+        0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B,
+        0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B,
+        0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42,
+        0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF,
+        0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC,
+        0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03,
+        0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6,
+        0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82,
+        0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E,
+        0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3,
+        0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE,
+        0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5,
+        0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA,
+        0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8,
+        0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0,
+        0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28,
+        0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76,
+        0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0,
+        0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C,
+        0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32,
+        0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68,
+        0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE,
+        0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6,
+        0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xCC, 0x40, 0x24,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    };
+    return BN_bin2bn(RFC3526_PRIME_6144, sizeof(RFC3526_PRIME_6144), bn);
+}
+
+/*-
+ * "8192-bit MODP Group" from RFC3526, Section 7.
+ *
+ * The prime is: 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 }
+ *
+ * RFC3526 specifies a generator of 2.
+ */
+
+BIGNUM *BN_get_rfc3526_prime_8192(BIGNUM *bn)
+{
+    static const unsigned char RFC3526_PRIME_8192[] = {
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
+        0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
+        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
+        0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
+        0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
+        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
+        0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
+        0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
+        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
+        0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
+        0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
+        0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
+        0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
+        0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
+        0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
+        0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
+        0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
+        0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
+        0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
+        0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
+        0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
+        0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
+        0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
+        0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
+        0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
+        0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
+        0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
+        0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
+        0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
+        0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
+        0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
+        0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
+        0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
+        0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
+        0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
+        0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
+        0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
+        0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
+        0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
+        0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
+        0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
+        0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
+        0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
+        0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
+        0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
+        0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01,
+        0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
+        0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26,
+        0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
+        0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
+        0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
+        0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9,
+        0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
+        0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D,
+        0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
+        0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
+        0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
+        0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C,
+        0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
+        0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1,
+        0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
+        0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92,
+        0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26,
+        0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE,
+        0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD,
+        0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E,
+        0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE,
+        0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31,
+        0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18,
+        0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED,
+        0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B,
+        0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B,
+        0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42,
+        0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF,
+        0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC,
+        0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03,
+        0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6,
+        0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82,
+        0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E,
+        0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3,
+        0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE,
+        0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5,
+        0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA,
+        0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8,
+        0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0,
+        0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28,
+        0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76,
+        0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0,
+        0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C,
+        0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32,
+        0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68,
+        0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE,
+        0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6,
+        0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xBE, 0x11, 0x59,
+        0x74, 0xA3, 0x92, 0x6F, 0x12, 0xFE, 0xE5, 0xE4,
+        0x38, 0x77, 0x7C, 0xB6, 0xA9, 0x32, 0xDF, 0x8C,
+        0xD8, 0xBE, 0xC4, 0xD0, 0x73, 0xB9, 0x31, 0xBA,
+        0x3B, 0xC8, 0x32, 0xB6, 0x8D, 0x9D, 0xD3, 0x00,
+        0x74, 0x1F, 0xA7, 0xBF, 0x8A, 0xFC, 0x47, 0xED,
+        0x25, 0x76, 0xF6, 0x93, 0x6B, 0xA4, 0x24, 0x66,
+        0x3A, 0xAB, 0x63, 0x9C, 0x5A, 0xE4, 0xF5, 0x68,
+        0x34, 0x23, 0xB4, 0x74, 0x2B, 0xF1, 0xC9, 0x78,
+        0x23, 0x8F, 0x16, 0xCB, 0xE3, 0x9D, 0x65, 0x2D,
+        0xE3, 0xFD, 0xB8, 0xBE, 0xFC, 0x84, 0x8A, 0xD9,
+        0x22, 0x22, 0x2E, 0x04, 0xA4, 0x03, 0x7C, 0x07,
+        0x13, 0xEB, 0x57, 0xA8, 0x1A, 0x23, 0xF0, 0xC7,
+        0x34, 0x73, 0xFC, 0x64, 0x6C, 0xEA, 0x30, 0x6B,
+        0x4B, 0xCB, 0xC8, 0x86, 0x2F, 0x83, 0x85, 0xDD,
+        0xFA, 0x9D, 0x4B, 0x7F, 0xA2, 0xC0, 0x87, 0xE8,
+        0x79, 0x68, 0x33, 0x03, 0xED, 0x5B, 0xDD, 0x3A,
+        0x06, 0x2B, 0x3C, 0xF5, 0xB3, 0xA2, 0x78, 0xA6,
+        0x6D, 0x2A, 0x13, 0xF8, 0x3F, 0x44, 0xF8, 0x2D,
+        0xDF, 0x31, 0x0E, 0xE0, 0x74, 0xAB, 0x6A, 0x36,
+        0x45, 0x97, 0xE8, 0x99, 0xA0, 0x25, 0x5D, 0xC1,
+        0x64, 0xF3, 0x1C, 0xC5, 0x08, 0x46, 0x85, 0x1D,
+        0xF9, 0xAB, 0x48, 0x19, 0x5D, 0xED, 0x7E, 0xA1,
+        0xB1, 0xD5, 0x10, 0xBD, 0x7E, 0xE7, 0x4D, 0x73,
+        0xFA, 0xF3, 0x6B, 0xC3, 0x1E, 0xCF, 0xA2, 0x68,
+        0x35, 0x90, 0x46, 0xF4, 0xEB, 0x87, 0x9F, 0x92,
+        0x40, 0x09, 0x43, 0x8B, 0x48, 0x1C, 0x6C, 0xD7,
+        0x88, 0x9A, 0x00, 0x2E, 0xD5, 0xEE, 0x38, 0x2B,
+        0xC9, 0x19, 0x0D, 0xA6, 0xFC, 0x02, 0x6E, 0x47,
+        0x95, 0x58, 0xE4, 0x47, 0x56, 0x77, 0xE9, 0xAA,
+        0x9E, 0x30, 0x50, 0xE2, 0x76, 0x56, 0x94, 0xDF,
+        0xC8, 0x1F, 0x56, 0xE8, 0x80, 0xB9, 0x6E, 0x71,
+        0x60, 0xC9, 0x80, 0xDD, 0x98, 0xED, 0xD3, 0xDF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    };
+    return BN_bin2bn(RFC3526_PRIME_8192, sizeof(RFC3526_PRIME_8192), bn);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_ctx.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_ctx.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_ctx.c	(revision 331)
@@ -0,0 +1,353 @@
+/*
+ * Copyright 2000-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 "internal/cryptlib.h"
+#include "bn_lcl.h"
+
+/*-
+ * TODO list
+ *
+ * 1. Check a bunch of "(words+1)" type hacks in various bignum functions and
+ * check they can be safely removed.
+ *  - Check +1 and other ugliness in BN_from_montgomery()
+ *
+ * 2. Consider allowing a BN_new_ex() that, at least, lets you specify an
+ * appropriate 'block' size that will be honoured by bn_expand_internal() to
+ * prevent piddly little reallocations. OTOH, profiling bignum expansions in
+ * BN_CTX doesn't show this to be a big issue.
+ */
+
+/* How many bignums are in each "pool item"; */
+#define BN_CTX_POOL_SIZE        16
+/* The stack frame info is resizing, set a first-time expansion size; */
+#define BN_CTX_START_FRAMES     32
+
+/***********/
+/* BN_POOL */
+/***********/
+
+/* A bundle of bignums that can be linked with other bundles */
+typedef struct bignum_pool_item {
+    /* The bignum values */
+    BIGNUM vals[BN_CTX_POOL_SIZE];
+    /* Linked-list admin */
+    struct bignum_pool_item *prev, *next;
+} BN_POOL_ITEM;
+/* A linked-list of bignums grouped in bundles */
+typedef struct bignum_pool {
+    /* Linked-list admin */
+    BN_POOL_ITEM *head, *current, *tail;
+    /* Stack depth and allocation size */
+    unsigned used, size;
+} BN_POOL;
+static void BN_POOL_init(BN_POOL *);
+static void BN_POOL_finish(BN_POOL *);
+static BIGNUM *BN_POOL_get(BN_POOL *, int);
+static void BN_POOL_release(BN_POOL *, unsigned int);
+
+/************/
+/* BN_STACK */
+/************/
+
+/* A wrapper to manage the "stack frames" */
+typedef struct bignum_ctx_stack {
+    /* Array of indexes into the bignum stack */
+    unsigned int *indexes;
+    /* Number of stack frames, and the size of the allocated array */
+    unsigned int depth, size;
+} BN_STACK;
+static void BN_STACK_init(BN_STACK *);
+static void BN_STACK_finish(BN_STACK *);
+static int BN_STACK_push(BN_STACK *, unsigned int);
+static unsigned int BN_STACK_pop(BN_STACK *);
+
+/**********/
+/* BN_CTX */
+/**********/
+
+/* The opaque BN_CTX type */
+struct bignum_ctx {
+    /* The bignum bundles */
+    BN_POOL pool;
+    /* The "stack frames", if you will */
+    BN_STACK stack;
+    /* The number of bignums currently assigned */
+    unsigned int used;
+    /* Depth of stack overflow */
+    int err_stack;
+    /* Block "gets" until an "end" (compatibility behaviour) */
+    int too_many;
+    /* Flags. */
+    int flags;
+};
+
+/* Enable this to find BN_CTX bugs */
+#ifdef BN_CTX_DEBUG
+static const char *ctxdbg_cur = NULL;
+static void ctxdbg(BN_CTX *ctx)
+{
+    unsigned int bnidx = 0, fpidx = 0;
+    BN_POOL_ITEM *item = ctx->pool.head;
+    BN_STACK *stack = &ctx->stack;
+    fprintf(stderr, "(%16p): ", ctx);
+    while (bnidx < ctx->used) {
+        fprintf(stderr, "%03x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax);
+        if (!(bnidx % BN_CTX_POOL_SIZE))
+            item = item->next;
+    }
+    fprintf(stderr, "\n");
+    bnidx = 0;
+    fprintf(stderr, "          : ");
+    while (fpidx < stack->depth) {
+        while (bnidx++ < stack->indexes[fpidx])
+            fprintf(stderr, "    ");
+        fprintf(stderr, "^^^ ");
+        bnidx++;
+        fpidx++;
+    }
+    fprintf(stderr, "\n");
+}
+
+# define CTXDBG_ENTRY(str, ctx)  do { \
+                                ctxdbg_cur = (str); \
+                                fprintf(stderr,"Starting %s\n", ctxdbg_cur); \
+                                ctxdbg(ctx); \
+                                } while(0)
+# define CTXDBG_EXIT(ctx)        do { \
+                                fprintf(stderr,"Ending %s\n", ctxdbg_cur); \
+                                ctxdbg(ctx); \
+                                } while(0)
+# define CTXDBG_RET(ctx,ret)
+#else
+# define CTXDBG_ENTRY(str, ctx)
+# define CTXDBG_EXIT(ctx)
+# define CTXDBG_RET(ctx,ret)
+#endif
+
+
+BN_CTX *BN_CTX_new(void)
+{
+    BN_CTX *ret;
+
+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
+        BNerr(BN_F_BN_CTX_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    /* Initialise the structure */
+    BN_POOL_init(&ret->pool);
+    BN_STACK_init(&ret->stack);
+    return ret;
+}
+
+BN_CTX *BN_CTX_secure_new(void)
+{
+    BN_CTX *ret = BN_CTX_new();
+
+    if (ret != NULL)
+        ret->flags = BN_FLG_SECURE;
+    return ret;
+}
+
+void BN_CTX_free(BN_CTX *ctx)
+{
+    if (ctx == NULL)
+        return;
+#ifdef BN_CTX_DEBUG
+    {
+        BN_POOL_ITEM *pool = ctx->pool.head;
+        fprintf(stderr, "BN_CTX_free, stack-size=%d, pool-bignums=%d\n",
+                ctx->stack.size, ctx->pool.size);
+        fprintf(stderr, "dmaxs: ");
+        while (pool) {
+            unsigned loop = 0;
+            while (loop < BN_CTX_POOL_SIZE)
+                fprintf(stderr, "%02x ", pool->vals[loop++].dmax);
+            pool = pool->next;
+        }
+        fprintf(stderr, "\n");
+    }
+#endif
+    BN_STACK_finish(&ctx->stack);
+    BN_POOL_finish(&ctx->pool);
+    OPENSSL_free(ctx);
+}
+
+void BN_CTX_start(BN_CTX *ctx)
+{
+    CTXDBG_ENTRY("BN_CTX_start", ctx);
+    /* If we're already overflowing ... */
+    if (ctx->err_stack || ctx->too_many)
+        ctx->err_stack++;
+    /* (Try to) get a new frame pointer */
+    else if (!BN_STACK_push(&ctx->stack, ctx->used)) {
+        BNerr(BN_F_BN_CTX_START, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
+        ctx->err_stack++;
+    }
+    CTXDBG_EXIT(ctx);
+}
+
+void BN_CTX_end(BN_CTX *ctx)
+{
+    CTXDBG_ENTRY("BN_CTX_end", ctx);
+    if (ctx->err_stack)
+        ctx->err_stack--;
+    else {
+        unsigned int fp = BN_STACK_pop(&ctx->stack);
+        /* Does this stack frame have anything to release? */
+        if (fp < ctx->used)
+            BN_POOL_release(&ctx->pool, ctx->used - fp);
+        ctx->used = fp;
+        /* Unjam "too_many" in case "get" had failed */
+        ctx->too_many = 0;
+    }
+    CTXDBG_EXIT(ctx);
+}
+
+BIGNUM *BN_CTX_get(BN_CTX *ctx)
+{
+    BIGNUM *ret;
+
+    CTXDBG_ENTRY("BN_CTX_get", ctx);
+    if (ctx->err_stack || ctx->too_many)
+        return NULL;
+    if ((ret = BN_POOL_get(&ctx->pool, ctx->flags)) == NULL) {
+        /*
+         * Setting too_many prevents repeated "get" attempts from cluttering
+         * the error stack.
+         */
+        ctx->too_many = 1;
+        BNerr(BN_F_BN_CTX_GET, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
+        return NULL;
+    }
+    /* OK, make sure the returned bignum is "zero" */
+    BN_zero(ret);
+    ctx->used++;
+    CTXDBG_RET(ctx, ret);
+    return ret;
+}
+
+/************/
+/* BN_STACK */
+/************/
+
+static void BN_STACK_init(BN_STACK *st)
+{
+    st->indexes = NULL;
+    st->depth = st->size = 0;
+}
+
+static void BN_STACK_finish(BN_STACK *st)
+{
+    OPENSSL_free(st->indexes);
+    st->indexes = NULL;
+}
+
+
+static int BN_STACK_push(BN_STACK *st, unsigned int idx)
+{
+    if (st->depth == st->size) {
+        /* Need to expand */
+        unsigned int newsize =
+            st->size ? (st->size * 3 / 2) : BN_CTX_START_FRAMES;
+        unsigned int *newitems = OPENSSL_malloc(sizeof(*newitems) * newsize);
+        if (newitems == NULL)
+            return 0;
+        if (st->depth)
+            memcpy(newitems, st->indexes, sizeof(*newitems) * st->depth);
+        OPENSSL_free(st->indexes);
+        st->indexes = newitems;
+        st->size = newsize;
+    }
+    st->indexes[(st->depth)++] = idx;
+    return 1;
+}
+
+static unsigned int BN_STACK_pop(BN_STACK *st)
+{
+    return st->indexes[--(st->depth)];
+}
+
+/***********/
+/* BN_POOL */
+/***********/
+
+static void BN_POOL_init(BN_POOL *p)
+{
+    p->head = p->current = p->tail = NULL;
+    p->used = p->size = 0;
+}
+
+static void BN_POOL_finish(BN_POOL *p)
+{
+    unsigned int loop;
+    BIGNUM *bn;
+
+    while (p->head) {
+        for (loop = 0, bn = p->head->vals; loop++ < BN_CTX_POOL_SIZE; bn++)
+            if (bn->d)
+                BN_clear_free(bn);
+        p->current = p->head->next;
+        OPENSSL_free(p->head);
+        p->head = p->current;
+    }
+}
+
+
+static BIGNUM *BN_POOL_get(BN_POOL *p, int flag)
+{
+    BIGNUM *bn;
+    unsigned int loop;
+
+    /* Full; allocate a new pool item and link it in. */
+    if (p->used == p->size) {
+        BN_POOL_ITEM *item = OPENSSL_malloc(sizeof(*item));
+        if (item == NULL)
+            return NULL;
+        for (loop = 0, bn = item->vals; loop++ < BN_CTX_POOL_SIZE; bn++) {
+            bn_init(bn);
+            if ((flag & BN_FLG_SECURE) != 0)
+                BN_set_flags(bn, BN_FLG_SECURE);
+        }
+        item->prev = p->tail;
+        item->next = NULL;
+
+        if (p->head == NULL)
+            p->head = p->current = p->tail = item;
+        else {
+            p->tail->next = item;
+            p->tail = item;
+            p->current = item;
+        }
+        p->size += BN_CTX_POOL_SIZE;
+        p->used++;
+        /* Return the first bignum from the new pool */
+        return item->vals;
+    }
+
+    if (!p->used)
+        p->current = p->head;
+    else if ((p->used % BN_CTX_POOL_SIZE) == 0)
+        p->current = p->current->next;
+    return p->current->vals + ((p->used++) % BN_CTX_POOL_SIZE);
+}
+
+static void BN_POOL_release(BN_POOL *p, unsigned int num)
+{
+    unsigned int offset = (p->used - 1) % BN_CTX_POOL_SIZE;
+
+    p->used -= num;
+    while (num--) {
+        bn_check_top(p->current->vals + offset);
+        if (offset == 0) {
+            offset = BN_CTX_POOL_SIZE - 1;
+            p->current = p->current->prev;
+        } else
+            offset--;
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_depr.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_depr.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_depr.c	(revision 331)
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2002-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
+ */
+
+/*
+ * Support for deprecated functions goes here - static linkage will only
+ * slurp this code if applications are using them directly.
+ */
+
+#include <openssl/opensslconf.h>
+#if OPENSSL_API_COMPAT >= 0x00908000L
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <stdio.h>
+# include <time.h>
+# include "internal/cryptlib.h"
+# include "bn_lcl.h"
+
+BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe,
+                          const BIGNUM *add, const BIGNUM *rem,
+                          void (*callback) (int, int, void *), void *cb_arg)
+{
+    BN_GENCB cb;
+    BIGNUM *rnd = NULL;
+
+    BN_GENCB_set_old(&cb, callback, cb_arg);
+
+    if (ret == NULL) {
+        if ((rnd = BN_new()) == NULL)
+            goto err;
+    } else
+        rnd = ret;
+    if (!BN_generate_prime_ex(rnd, bits, safe, add, rem, &cb))
+        goto err;
+
+    /* we have a prime :-) */
+    return ret;
+ err:
+    BN_free(rnd);
+    return NULL;
+}
+
+int BN_is_prime(const BIGNUM *a, int checks,
+                void (*callback) (int, int, void *), BN_CTX *ctx_passed,
+                void *cb_arg)
+{
+    BN_GENCB cb;
+    BN_GENCB_set_old(&cb, callback, cb_arg);
+    return BN_is_prime_ex(a, checks, ctx_passed, &cb);
+}
+
+int BN_is_prime_fasttest(const BIGNUM *a, int checks,
+                         void (*callback) (int, int, void *),
+                         BN_CTX *ctx_passed, void *cb_arg,
+                         int do_trial_division)
+{
+    BN_GENCB cb;
+    BN_GENCB_set_old(&cb, callback, cb_arg);
+    return BN_is_prime_fasttest_ex(a, checks, ctx_passed,
+                                   do_trial_division, &cb);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_dh.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_dh.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_dh.c	(revision 331)
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2014-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 "bn_lcl.h"
+#include "e_os.h"
+
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#include "internal/bn_dh.h"
+/* DH parameters from RFC5114 */
+
+# if BN_BITS2 == 64
+static const BN_ULONG dh1024_160_p[] = {
+    0xDF1FB2BC2E4A4371ULL, 0xE68CFDA76D4DA708ULL, 0x45BF37DF365C1A65ULL,
+    0xA151AF5F0DC8B4BDULL, 0xFAA31A4FF55BCCC0ULL, 0x4EFFD6FAE5644738ULL,
+    0x98488E9C219A7372ULL, 0xACCBDD7D90C4BD70ULL, 0x24975C3CD49B83BFULL,
+    0x13ECB4AEA9061123ULL, 0x9838EF1E2EE652C0ULL, 0x6073E28675A23D18ULL,
+    0x9A6A9DCA52D23B61ULL, 0x52C99FBCFB06A3C6ULL, 0xDE92DE5EAE5D54ECULL,
+    0xB10B8F96A080E01DULL
+};
+
+static const BN_ULONG dh1024_160_g[] = {
+    0x855E6EEB22B3B2E5ULL, 0x858F4DCEF97C2A24ULL, 0x2D779D5918D08BC8ULL,
+    0xD662A4D18E73AFA3ULL, 0x1DBF0A0169B6A28AULL, 0xA6A24C087A091F53ULL,
+    0x909D0D2263F80A76ULL, 0xD7FBD7D3B9A92EE1ULL, 0x5E91547F9E2749F4ULL,
+    0x160217B4B01B886AULL, 0x777E690F5504F213ULL, 0x266FEA1E5C41564BULL,
+    0xD6406CFF14266D31ULL, 0xF8104DD258AC507FULL, 0x6765A442EFB99905ULL,
+    0xA4D1CBD5C3FD3412ULL
+};
+
+static const BN_ULONG dh1024_160_q[] = {
+    0x64B7CB9D49462353ULL, 0x81A8DF278ABA4E7DULL, 0x00000000F518AA87ULL
+};
+
+static const BN_ULONG dh2048_224_p[] = {
+    0x0AC4DFFE0C10E64FULL, 0xCF9DE5384E71B81CULL, 0x7EF363E2FFA31F71ULL,
+    0xE3FB73C16B8E75B9ULL, 0xC9B53DCF4BA80A29ULL, 0x23F10B0E16E79763ULL,
+    0xC52172E413042E9BULL, 0xBE60E69CC928B2B9ULL, 0x80CD86A1B9E587E8ULL,
+    0x315D75E198C641A4ULL, 0xCDF93ACC44328387ULL, 0x15987D9ADC0A486DULL,
+    0x7310F7121FD5A074ULL, 0x278273C7DE31EFDCULL, 0x1602E714415D9330ULL,
+    0x81286130BC8985DBULL, 0xB3BF8A3170918836ULL, 0x6A00E0A0B9C49708ULL,
+    0xC6BA0B2C8BBC27BEULL, 0xC9F98D11ED34DBF6ULL, 0x7AD5B7D0B6C12207ULL,
+    0xD91E8FEF55B7394BULL, 0x9037C9EDEFDA4DF8ULL, 0x6D3F8152AD6AC212ULL,
+    0x1DE6B85A1274A0A6ULL, 0xEB3D688A309C180EULL, 0xAF9A3C407BA1DF15ULL,
+    0xE6FA141DF95A56DBULL, 0xB54B1597B61D0A75ULL, 0xA20D64E5683B9FD1ULL,
+    0xD660FAA79559C51FULL, 0xAD107E1E9123A9D0ULL
+};
+
+static const BN_ULONG dh2048_224_g[] = {
+    0x84B890D3191F2BFAULL, 0x81BC087F2A7065B3ULL, 0x19C418E1F6EC0179ULL,
+    0x7B5A0F1C71CFFF4CULL, 0xEDFE72FE9B6AA4BDULL, 0x81E1BCFE94B30269ULL,
+    0x566AFBB48D6C0191ULL, 0xB539CCE3409D13CDULL, 0x6AA21E7F5F2FF381ULL,
+    0xD9E263E4770589EFULL, 0x10E183EDD19963DDULL, 0xB70A8137150B8EEBULL,
+    0x051AE3D428C8F8ACULL, 0xBB77A86F0C1AB15BULL, 0x6E3025E316A330EFULL,
+    0x19529A45D6F83456ULL, 0xF180EB34118E98D1ULL, 0xB5F6C6B250717CBEULL,
+    0x09939D54DA7460CDULL, 0xE247150422EA1ED4ULL, 0xB8A762D0521BC98AULL,
+    0xF4D027275AC1348BULL, 0xC17669101999024AULL, 0xBE5E9001A8D66AD7ULL,
+    0xC57DB17C620A8652ULL, 0xAB739D7700C29F52ULL, 0xDD921F01A70C4AFAULL,
+    0xA6824A4E10B9A6F0ULL, 0x74866A08CFE4FFE3ULL, 0x6CDEBE7B89998CAFULL,
+    0x9DF30B5C8FFDAC50ULL, 0xAC4032EF4F2D9AE3ULL
+};
+
+static const BN_ULONG dh2048_224_q[] = {
+    0xBF389A99B36371EBULL, 0x1F80535A4738CEBCULL, 0xC58D93FE99717710ULL,
+    0x00000000801C0D34ULL
+};
+
+static const BN_ULONG dh2048_256_p[] = {
+    0xDB094AE91E1A1597ULL, 0x693877FAD7EF09CAULL, 0x6116D2276E11715FULL,
+    0xA4B54330C198AF12ULL, 0x75F26375D7014103ULL, 0xC3A3960A54E710C3ULL,
+    0xDED4010ABD0BE621ULL, 0xC0B857F689962856ULL, 0xB3CA3F7971506026ULL,
+    0x1CCACB83E6B486F6ULL, 0x67E144E514056425ULL, 0xF6A167B5A41825D9ULL,
+    0x3AD8347796524D8EULL, 0xF13C6D9A51BFA4ABULL, 0x2D52526735488A0EULL,
+    0xB63ACAE1CAA6B790ULL, 0x4FDB70C581B23F76ULL, 0xBC39A0BF12307F5CULL,
+    0xB941F54EB1E59BB8ULL, 0x6C5BFC11D45F9088ULL, 0x22E0B1EF4275BF7BULL,
+    0x91F9E6725B4758C0ULL, 0x5A8A9D306BCF67EDULL, 0x209E0C6497517ABDULL,
+    0x3BF4296D830E9A7CULL, 0x16C3D91134096FAAULL, 0xFAF7DF4561B2AA30ULL,
+    0xE00DF8F1D61957D4ULL, 0x5D2CEED4435E3B00ULL, 0x8CEEF608660DD0F2ULL,
+    0xFFBBD19C65195999ULL, 0x87A8E61DB4B6663CULL
+};
+
+static const BN_ULONG dh2048_256_g[] = {
+    0x664B4C0F6CC41659ULL, 0x5E2327CFEF98C582ULL, 0xD647D148D4795451ULL,
+    0x2F63078490F00EF8ULL, 0x184B523D1DB246C3ULL, 0xC7891428CDC67EB6ULL,
+    0x7FD028370DF92B52ULL, 0xB3353BBB64E0EC37ULL, 0xECD06E1557CD0915ULL,
+    0xB7D2BBD2DF016199ULL, 0xC8484B1E052588B9ULL, 0xDB2A3B7313D3FE14ULL,
+    0xD052B985D182EA0AULL, 0xA4BD1BFFE83B9C80ULL, 0xDFC967C1FB3F2E55ULL,
+    0xB5045AF2767164E1ULL, 0x1D14348F6F2F9193ULL, 0x64E67982428EBC83ULL,
+    0x8AC376D282D6ED38ULL, 0x777DE62AAAB8A862ULL, 0xDDF463E5E9EC144BULL,
+    0x0196F931C77A57F2ULL, 0xA55AE31341000A65ULL, 0x901228F8C28CBB18ULL,
+    0xBC3773BF7E8C6F62ULL, 0xBE3A6C1B0C6B47B1ULL, 0xFF4FED4AAC0BB555ULL,
+    0x10DBC15077BE463FULL, 0x07F4793A1A0BA125ULL, 0x4CA7B18F21EF2054ULL,
+    0x2E77506660EDBD48ULL, 0x3FB32C9B73134D0BULL
+};
+
+static const BN_ULONG dh2048_256_q[] = {
+    0xA308B0FE64F5FBD3ULL, 0x99B1A47D1EB3750BULL, 0xB447997640129DA2ULL,
+    0x8CF83642A709A097ULL
+};
+
+# elif BN_BITS2 == 32
+
+static const BN_ULONG dh1024_160_p[] = {
+    0x2E4A4371, 0xDF1FB2BC, 0x6D4DA708, 0xE68CFDA7, 0x365C1A65, 0x45BF37DF,
+    0x0DC8B4BD, 0xA151AF5F, 0xF55BCCC0, 0xFAA31A4F, 0xE5644738, 0x4EFFD6FA,
+    0x219A7372, 0x98488E9C, 0x90C4BD70, 0xACCBDD7D, 0xD49B83BF, 0x24975C3C,
+    0xA9061123, 0x13ECB4AE, 0x2EE652C0, 0x9838EF1E, 0x75A23D18, 0x6073E286,
+    0x52D23B61, 0x9A6A9DCA, 0xFB06A3C6, 0x52C99FBC, 0xAE5D54EC, 0xDE92DE5E,
+    0xA080E01D, 0xB10B8F96
+};
+
+static const BN_ULONG dh1024_160_g[] = {
+    0x22B3B2E5, 0x855E6EEB, 0xF97C2A24, 0x858F4DCE, 0x18D08BC8, 0x2D779D59,
+    0x8E73AFA3, 0xD662A4D1, 0x69B6A28A, 0x1DBF0A01, 0x7A091F53, 0xA6A24C08,
+    0x63F80A76, 0x909D0D22, 0xB9A92EE1, 0xD7FBD7D3, 0x9E2749F4, 0x5E91547F,
+    0xB01B886A, 0x160217B4, 0x5504F213, 0x777E690F, 0x5C41564B, 0x266FEA1E,
+    0x14266D31, 0xD6406CFF, 0x58AC507F, 0xF8104DD2, 0xEFB99905, 0x6765A442,
+    0xC3FD3412, 0xA4D1CBD5
+};
+
+static const BN_ULONG dh1024_160_q[] = {
+    0x49462353, 0x64B7CB9D, 0x8ABA4E7D, 0x81A8DF27, 0xF518AA87
+};
+
+static const BN_ULONG dh2048_224_p[] = {
+    0x0C10E64F, 0x0AC4DFFE, 0x4E71B81C, 0xCF9DE538, 0xFFA31F71, 0x7EF363E2,
+    0x6B8E75B9, 0xE3FB73C1, 0x4BA80A29, 0xC9B53DCF, 0x16E79763, 0x23F10B0E,
+    0x13042E9B, 0xC52172E4, 0xC928B2B9, 0xBE60E69C, 0xB9E587E8, 0x80CD86A1,
+    0x98C641A4, 0x315D75E1, 0x44328387, 0xCDF93ACC, 0xDC0A486D, 0x15987D9A,
+    0x1FD5A074, 0x7310F712, 0xDE31EFDC, 0x278273C7, 0x415D9330, 0x1602E714,
+    0xBC8985DB, 0x81286130, 0x70918836, 0xB3BF8A31, 0xB9C49708, 0x6A00E0A0,
+    0x8BBC27BE, 0xC6BA0B2C, 0xED34DBF6, 0xC9F98D11, 0xB6C12207, 0x7AD5B7D0,
+    0x55B7394B, 0xD91E8FEF, 0xEFDA4DF8, 0x9037C9ED, 0xAD6AC212, 0x6D3F8152,
+    0x1274A0A6, 0x1DE6B85A, 0x309C180E, 0xEB3D688A, 0x7BA1DF15, 0xAF9A3C40,
+    0xF95A56DB, 0xE6FA141D, 0xB61D0A75, 0xB54B1597, 0x683B9FD1, 0xA20D64E5,
+    0x9559C51F, 0xD660FAA7, 0x9123A9D0, 0xAD107E1E
+};
+
+static const BN_ULONG dh2048_224_g[] = {
+    0x191F2BFA, 0x84B890D3, 0x2A7065B3, 0x81BC087F, 0xF6EC0179, 0x19C418E1,
+    0x71CFFF4C, 0x7B5A0F1C, 0x9B6AA4BD, 0xEDFE72FE, 0x94B30269, 0x81E1BCFE,
+    0x8D6C0191, 0x566AFBB4, 0x409D13CD, 0xB539CCE3, 0x5F2FF381, 0x6AA21E7F,
+    0x770589EF, 0xD9E263E4, 0xD19963DD, 0x10E183ED, 0x150B8EEB, 0xB70A8137,
+    0x28C8F8AC, 0x051AE3D4, 0x0C1AB15B, 0xBB77A86F, 0x16A330EF, 0x6E3025E3,
+    0xD6F83456, 0x19529A45, 0x118E98D1, 0xF180EB34, 0x50717CBE, 0xB5F6C6B2,
+    0xDA7460CD, 0x09939D54, 0x22EA1ED4, 0xE2471504, 0x521BC98A, 0xB8A762D0,
+    0x5AC1348B, 0xF4D02727, 0x1999024A, 0xC1766910, 0xA8D66AD7, 0xBE5E9001,
+    0x620A8652, 0xC57DB17C, 0x00C29F52, 0xAB739D77, 0xA70C4AFA, 0xDD921F01,
+    0x10B9A6F0, 0xA6824A4E, 0xCFE4FFE3, 0x74866A08, 0x89998CAF, 0x6CDEBE7B,
+    0x8FFDAC50, 0x9DF30B5C, 0x4F2D9AE3, 0xAC4032EF
+};
+
+static const BN_ULONG dh2048_224_q[] = {
+    0xB36371EB, 0xBF389A99, 0x4738CEBC, 0x1F80535A, 0x99717710, 0xC58D93FE,
+    0x801C0D34
+};
+
+static const BN_ULONG dh2048_256_p[] = {
+    0x1E1A1597, 0xDB094AE9, 0xD7EF09CA, 0x693877FA, 0x6E11715F, 0x6116D227,
+    0xC198AF12, 0xA4B54330, 0xD7014103, 0x75F26375, 0x54E710C3, 0xC3A3960A,
+    0xBD0BE621, 0xDED4010A, 0x89962856, 0xC0B857F6, 0x71506026, 0xB3CA3F79,
+    0xE6B486F6, 0x1CCACB83, 0x14056425, 0x67E144E5, 0xA41825D9, 0xF6A167B5,
+    0x96524D8E, 0x3AD83477, 0x51BFA4AB, 0xF13C6D9A, 0x35488A0E, 0x2D525267,
+    0xCAA6B790, 0xB63ACAE1, 0x81B23F76, 0x4FDB70C5, 0x12307F5C, 0xBC39A0BF,
+    0xB1E59BB8, 0xB941F54E, 0xD45F9088, 0x6C5BFC11, 0x4275BF7B, 0x22E0B1EF,
+    0x5B4758C0, 0x91F9E672, 0x6BCF67ED, 0x5A8A9D30, 0x97517ABD, 0x209E0C64,
+    0x830E9A7C, 0x3BF4296D, 0x34096FAA, 0x16C3D911, 0x61B2AA30, 0xFAF7DF45,
+    0xD61957D4, 0xE00DF8F1, 0x435E3B00, 0x5D2CEED4, 0x660DD0F2, 0x8CEEF608,
+    0x65195999, 0xFFBBD19C, 0xB4B6663C, 0x87A8E61D
+};
+
+static const BN_ULONG dh2048_256_g[] = {
+    0x6CC41659, 0x664B4C0F, 0xEF98C582, 0x5E2327CF, 0xD4795451, 0xD647D148,
+    0x90F00EF8, 0x2F630784, 0x1DB246C3, 0x184B523D, 0xCDC67EB6, 0xC7891428,
+    0x0DF92B52, 0x7FD02837, 0x64E0EC37, 0xB3353BBB, 0x57CD0915, 0xECD06E15,
+    0xDF016199, 0xB7D2BBD2, 0x052588B9, 0xC8484B1E, 0x13D3FE14, 0xDB2A3B73,
+    0xD182EA0A, 0xD052B985, 0xE83B9C80, 0xA4BD1BFF, 0xFB3F2E55, 0xDFC967C1,
+    0x767164E1, 0xB5045AF2, 0x6F2F9193, 0x1D14348F, 0x428EBC83, 0x64E67982,
+    0x82D6ED38, 0x8AC376D2, 0xAAB8A862, 0x777DE62A, 0xE9EC144B, 0xDDF463E5,
+    0xC77A57F2, 0x0196F931, 0x41000A65, 0xA55AE313, 0xC28CBB18, 0x901228F8,
+    0x7E8C6F62, 0xBC3773BF, 0x0C6B47B1, 0xBE3A6C1B, 0xAC0BB555, 0xFF4FED4A,
+    0x77BE463F, 0x10DBC150, 0x1A0BA125, 0x07F4793A, 0x21EF2054, 0x4CA7B18F,
+    0x60EDBD48, 0x2E775066, 0x73134D0B, 0x3FB32C9B
+};
+
+static const BN_ULONG dh2048_256_q[] = {
+    0x64F5FBD3, 0xA308B0FE, 0x1EB3750B, 0x99B1A47D, 0x40129DA2, 0xB4479976,
+    0xA709A097, 0x8CF83642
+};
+
+# else
+#  error "unsupported BN_BITS2"
+# endif
+
+/* Macro to make a BIGNUM from static data */
+
+# define make_dh_bn(x) extern const BIGNUM _bignum_##x; \
+                       const BIGNUM _bignum_##x = { (BN_ULONG *) x, \
+                        OSSL_NELEM(x),\
+                        OSSL_NELEM(x),\
+                        0, BN_FLG_STATIC_DATA };
+
+
+make_dh_bn(dh1024_160_p)
+make_dh_bn(dh1024_160_g)
+make_dh_bn(dh1024_160_q)
+make_dh_bn(dh2048_224_p)
+make_dh_bn(dh2048_224_g)
+make_dh_bn(dh2048_224_q)
+make_dh_bn(dh2048_256_p)
+make_dh_bn(dh2048_256_g)
+make_dh_bn(dh2048_256_q)
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_div.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_div.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_div.c	(revision 331)
@@ -0,0 +1,423 @@
+/*
+ * Copyright 1995-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 <openssl/bn.h>
+#include "internal/cryptlib.h"
+#include "bn_lcl.h"
+
+/* The old slow way */
+#if 0
+int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+           BN_CTX *ctx)
+{
+    int i, nm, nd;
+    int ret = 0;
+    BIGNUM *D;
+
+    bn_check_top(m);
+    bn_check_top(d);
+    if (BN_is_zero(d)) {
+        BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO);
+        return (0);
+    }
+
+    if (BN_ucmp(m, d) < 0) {
+        if (rem != NULL) {
+            if (BN_copy(rem, m) == NULL)
+                return (0);
+        }
+        if (dv != NULL)
+            BN_zero(dv);
+        return (1);
+    }
+
+    BN_CTX_start(ctx);
+    D = BN_CTX_get(ctx);
+    if (dv == NULL)
+        dv = BN_CTX_get(ctx);
+    if (rem == NULL)
+        rem = BN_CTX_get(ctx);
+    if (D == NULL || dv == NULL || rem == NULL)
+        goto end;
+
+    nd = BN_num_bits(d);
+    nm = BN_num_bits(m);
+    if (BN_copy(D, d) == NULL)
+        goto end;
+    if (BN_copy(rem, m) == NULL)
+        goto end;
+
+    /*
+     * The next 2 are needed so we can do a dv->d[0]|=1 later since
+     * BN_lshift1 will only work once there is a value :-)
+     */
+    BN_zero(dv);
+    if (bn_wexpand(dv, 1) == NULL)
+        goto end;
+    dv->top = 1;
+
+    if (!BN_lshift(D, D, nm - nd))
+        goto end;
+    for (i = nm - nd; i >= 0; i--) {
+        if (!BN_lshift1(dv, dv))
+            goto end;
+        if (BN_ucmp(rem, D) >= 0) {
+            dv->d[0] |= 1;
+            if (!BN_usub(rem, rem, D))
+                goto end;
+        }
+/* CAN IMPROVE (and have now :=) */
+        if (!BN_rshift1(D, D))
+            goto end;
+    }
+    rem->neg = BN_is_zero(rem) ? 0 : m->neg;
+    dv->neg = m->neg ^ d->neg;
+    ret = 1;
+ end:
+    BN_CTX_end(ctx);
+    return (ret);
+}
+
+#else
+
+# if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) \
+    && !defined(PEDANTIC) && !defined(BN_DIV3W)
+#  if defined(__GNUC__) && __GNUC__>=2
+#   if defined(__i386) || defined (__i386__)
+   /*-
+    * There were two reasons for implementing this template:
+    * - GNU C generates a call to a function (__udivdi3 to be exact)
+    *   in reply to ((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0 (I fail to
+    *   understand why...);
+    * - divl doesn't only calculate quotient, but also leaves
+    *   remainder in %edx which we can definitely use here:-)
+    *
+    *                                   <appro@fy.chalmers.se>
+    */
+#    undef bn_div_words
+#    define bn_div_words(n0,n1,d0)                \
+        ({  asm volatile (                      \
+                "divl   %4"                     \
+                : "=a"(q), "=d"(rem)            \
+                : "a"(n1), "d"(n0), "r"(d0)     \
+                : "cc");                        \
+            q;                                  \
+        })
+#    define REMAINDER_IS_ALREADY_CALCULATED
+#   elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG)
+   /*
+    * Same story here, but it's 128-bit by 64-bit division. Wow!
+    *                                   <appro@fy.chalmers.se>
+    */
+#    undef bn_div_words
+#    define bn_div_words(n0,n1,d0)                \
+        ({  asm volatile (                      \
+                "divq   %4"                     \
+                : "=a"(q), "=d"(rem)            \
+                : "a"(n1), "d"(n0), "r"(d0)     \
+                : "cc");                        \
+            q;                                  \
+        })
+#    define REMAINDER_IS_ALREADY_CALCULATED
+#   endif                       /* __<cpu> */
+#  endif                        /* __GNUC__ */
+# endif                         /* OPENSSL_NO_ASM */
+
+/*-
+ * BN_div computes  dv := num / divisor, rounding towards
+ * zero, and sets up rm  such that  dv*divisor + rm = num  holds.
+ * Thus:
+ *     dv->neg == num->neg ^ divisor->neg  (unless the result is zero)
+ *     rm->neg == num->neg                 (unless the remainder is zero)
+ * If 'dv' or 'rm' is NULL, the respective value is not returned.
+ */
+int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
+           BN_CTX *ctx)
+{
+    int norm_shift, i, loop;
+    BIGNUM *tmp, wnum, *snum, *sdiv, *res;
+    BN_ULONG *resp, *wnump;
+    BN_ULONG d0, d1;
+    int num_n, div_n;
+    int no_branch = 0;
+
+    /*
+     * Invalid zero-padding would have particularly bad consequences so don't
+     * just rely on bn_check_top() here (bn_check_top() works only for
+     * BN_DEBUG builds)
+     */
+    if ((num->top > 0 && num->d[num->top - 1] == 0) ||
+        (divisor->top > 0 && divisor->d[divisor->top - 1] == 0)) {
+        BNerr(BN_F_BN_DIV, BN_R_NOT_INITIALIZED);
+        return 0;
+    }
+
+    bn_check_top(num);
+    bn_check_top(divisor);
+
+    if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0)
+        || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0)) {
+        no_branch = 1;
+    }
+
+    bn_check_top(dv);
+    bn_check_top(rm);
+    /*- bn_check_top(num); *//*
+     * 'num' has been checked already
+     */
+    /*- bn_check_top(divisor); *//*
+     * 'divisor' has been checked already
+     */
+
+    if (BN_is_zero(divisor)) {
+        BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO);
+        return (0);
+    }
+
+    if (!no_branch && BN_ucmp(num, divisor) < 0) {
+        if (rm != NULL) {
+            if (BN_copy(rm, num) == NULL)
+                return (0);
+        }
+        if (dv != NULL)
+            BN_zero(dv);
+        return (1);
+    }
+
+    BN_CTX_start(ctx);
+    tmp = BN_CTX_get(ctx);
+    snum = BN_CTX_get(ctx);
+    sdiv = BN_CTX_get(ctx);
+    if (dv == NULL)
+        res = BN_CTX_get(ctx);
+    else
+        res = dv;
+    if (sdiv == NULL || res == NULL || tmp == NULL || snum == NULL)
+        goto err;
+
+    /* First we normalise the numbers */
+    norm_shift = BN_BITS2 - ((BN_num_bits(divisor)) % BN_BITS2);
+    if (!(BN_lshift(sdiv, divisor, norm_shift)))
+        goto err;
+    sdiv->neg = 0;
+    norm_shift += BN_BITS2;
+    if (!(BN_lshift(snum, num, norm_shift)))
+        goto err;
+    snum->neg = 0;
+
+    if (no_branch) {
+        /*
+         * Since we don't know whether snum is larger than sdiv, we pad snum
+         * with enough zeroes without changing its value.
+         */
+        if (snum->top <= sdiv->top + 1) {
+            if (bn_wexpand(snum, sdiv->top + 2) == NULL)
+                goto err;
+            for (i = snum->top; i < sdiv->top + 2; i++)
+                snum->d[i] = 0;
+            snum->top = sdiv->top + 2;
+        } else {
+            if (bn_wexpand(snum, snum->top + 1) == NULL)
+                goto err;
+            snum->d[snum->top] = 0;
+            snum->top++;
+        }
+    }
+
+    div_n = sdiv->top;
+    num_n = snum->top;
+    loop = num_n - div_n;
+    /*
+     * Lets setup a 'window' into snum This is the part that corresponds to
+     * the current 'area' being divided
+     */
+    wnum.neg = 0;
+    wnum.d = &(snum->d[loop]);
+    wnum.top = div_n;
+    /*
+     * only needed when BN_ucmp messes up the values between top and max
+     */
+    wnum.dmax = snum->dmax - loop; /* so we don't step out of bounds */
+
+    /* Get the top 2 words of sdiv */
+    /* div_n=sdiv->top; */
+    d0 = sdiv->d[div_n - 1];
+    d1 = (div_n == 1) ? 0 : sdiv->d[div_n - 2];
+
+    /* pointer to the 'top' of snum */
+    wnump = &(snum->d[num_n - 1]);
+
+    /* Setup to 'res' */
+    if (!bn_wexpand(res, (loop + 1)))
+        goto err;
+    res->neg = (num->neg ^ divisor->neg);
+    res->top = loop - no_branch;
+    resp = &(res->d[loop - 1]);
+
+    /* space for temp */
+    if (!bn_wexpand(tmp, (div_n + 1)))
+        goto err;
+
+    if (!no_branch) {
+        if (BN_ucmp(&wnum, sdiv) >= 0) {
+            /*
+             * If BN_DEBUG_RAND is defined BN_ucmp changes (via bn_pollute)
+             * the const bignum arguments => clean the values between top and
+             * max again
+             */
+            bn_clear_top2max(&wnum);
+            bn_sub_words(wnum.d, wnum.d, sdiv->d, div_n);
+            *resp = 1;
+        } else
+            res->top--;
+    }
+
+    /* Increase the resp pointer so that we never create an invalid pointer. */
+    resp++;
+
+    /*
+     * if res->top == 0 then clear the neg value otherwise decrease the resp
+     * pointer
+     */
+    if (res->top == 0)
+        res->neg = 0;
+    else
+        resp--;
+
+    for (i = 0; i < loop - 1; i++, wnump--) {
+        BN_ULONG q, l0;
+        /*
+         * the first part of the loop uses the top two words of snum and sdiv
+         * to calculate a BN_ULONG q such that | wnum - sdiv * q | < sdiv
+         */
+# if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM)
+        BN_ULONG bn_div_3_words(BN_ULONG *, BN_ULONG, BN_ULONG);
+        q = bn_div_3_words(wnump, d1, d0);
+# else
+        BN_ULONG n0, n1, rem = 0;
+
+        n0 = wnump[0];
+        n1 = wnump[-1];
+        if (n0 == d0)
+            q = BN_MASK2;
+        else {                  /* n0 < d0 */
+
+#  ifdef BN_LLONG
+            BN_ULLONG t2;
+
+#   if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words)
+            q = (BN_ULONG)(((((BN_ULLONG) n0) << BN_BITS2) | n1) / d0);
+#   else
+            q = bn_div_words(n0, n1, d0);
+#   endif
+
+#   ifndef REMAINDER_IS_ALREADY_CALCULATED
+            /*
+             * rem doesn't have to be BN_ULLONG. The least we
+             * know it's less that d0, isn't it?
+             */
+            rem = (n1 - q * d0) & BN_MASK2;
+#   endif
+            t2 = (BN_ULLONG) d1 *q;
+
+            for (;;) {
+                if (t2 <= ((((BN_ULLONG) rem) << BN_BITS2) | wnump[-2]))
+                    break;
+                q--;
+                rem += d0;
+                if (rem < d0)
+                    break;      /* don't let rem overflow */
+                t2 -= d1;
+            }
+#  else                         /* !BN_LLONG */
+            BN_ULONG t2l, t2h;
+
+            q = bn_div_words(n0, n1, d0);
+#   ifndef REMAINDER_IS_ALREADY_CALCULATED
+            rem = (n1 - q * d0) & BN_MASK2;
+#   endif
+
+#   if defined(BN_UMULT_LOHI)
+            BN_UMULT_LOHI(t2l, t2h, d1, q);
+#   elif defined(BN_UMULT_HIGH)
+            t2l = d1 * q;
+            t2h = BN_UMULT_HIGH(d1, q);
+#   else
+            {
+                BN_ULONG ql, qh;
+                t2l = LBITS(d1);
+                t2h = HBITS(d1);
+                ql = LBITS(q);
+                qh = HBITS(q);
+                mul64(t2l, t2h, ql, qh); /* t2=(BN_ULLONG)d1*q; */
+            }
+#   endif
+
+            for (;;) {
+                if ((t2h < rem) || ((t2h == rem) && (t2l <= wnump[-2])))
+                    break;
+                q--;
+                rem += d0;
+                if (rem < d0)
+                    break;      /* don't let rem overflow */
+                if (t2l < d1)
+                    t2h--;
+                t2l -= d1;
+            }
+#  endif                        /* !BN_LLONG */
+        }
+# endif                         /* !BN_DIV3W */
+
+        l0 = bn_mul_words(tmp->d, sdiv->d, div_n, q);
+        tmp->d[div_n] = l0;
+        wnum.d--;
+        /*
+         * ingore top values of the bignums just sub the two BN_ULONG arrays
+         * with bn_sub_words
+         */
+        if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n + 1)) {
+            /*
+             * Note: As we have considered only the leading two BN_ULONGs in
+             * the calculation of q, sdiv * q might be greater than wnum (but
+             * then (q-1) * sdiv is less or equal than wnum)
+             */
+            q--;
+            if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n))
+                /*
+                 * we can't have an overflow here (assuming that q != 0, but
+                 * if q == 0 then tmp is zero anyway)
+                 */
+                (*wnump)++;
+        }
+        /* store part of the result */
+        resp--;
+        *resp = q;
+    }
+    bn_correct_top(snum);
+    if (rm != NULL) {
+        /*
+         * Keep a copy of the neg flag in num because if rm==num BN_rshift()
+         * will overwrite it.
+         */
+        int neg = num->neg;
+        BN_rshift(rm, snum, norm_shift);
+        if (!BN_is_zero(rm))
+            rm->neg = neg;
+        bn_check_top(rm);
+    }
+    if (no_branch)
+        bn_correct_top(res);
+    BN_CTX_end(ctx);
+    return (1);
+ err:
+    bn_check_top(rm);
+    BN_CTX_end(ctx);
+    return (0);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_err.c	(revision 331)
@@ -0,0 +1,107 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_BN,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_BN,0,reason)
+
+static ERR_STRING_DATA BN_str_functs[] = {
+    {ERR_FUNC(BN_F_BNRAND), "bnrand"},
+    {ERR_FUNC(BN_F_BN_BLINDING_CONVERT_EX), "BN_BLINDING_convert_ex"},
+    {ERR_FUNC(BN_F_BN_BLINDING_CREATE_PARAM), "BN_BLINDING_create_param"},
+    {ERR_FUNC(BN_F_BN_BLINDING_INVERT_EX), "BN_BLINDING_invert_ex"},
+    {ERR_FUNC(BN_F_BN_BLINDING_NEW), "BN_BLINDING_new"},
+    {ERR_FUNC(BN_F_BN_BLINDING_UPDATE), "BN_BLINDING_update"},
+    {ERR_FUNC(BN_F_BN_BN2DEC), "BN_bn2dec"},
+    {ERR_FUNC(BN_F_BN_BN2HEX), "BN_bn2hex"},
+    {ERR_FUNC(BN_F_BN_COMPUTE_WNAF), "bn_compute_wNAF"},
+    {ERR_FUNC(BN_F_BN_CTX_GET), "BN_CTX_get"},
+    {ERR_FUNC(BN_F_BN_CTX_NEW), "BN_CTX_new"},
+    {ERR_FUNC(BN_F_BN_CTX_START), "BN_CTX_start"},
+    {ERR_FUNC(BN_F_BN_DIV), "BN_div"},
+    {ERR_FUNC(BN_F_BN_DIV_RECP), "BN_div_recp"},
+    {ERR_FUNC(BN_F_BN_EXP), "BN_exp"},
+    {ERR_FUNC(BN_F_BN_EXPAND_INTERNAL), "bn_expand_internal"},
+    {ERR_FUNC(BN_F_BN_GENCB_NEW), "BN_GENCB_new"},
+    {ERR_FUNC(BN_F_BN_GENERATE_DSA_NONCE), "BN_generate_dsa_nonce"},
+    {ERR_FUNC(BN_F_BN_GENERATE_PRIME_EX), "BN_generate_prime_ex"},
+    {ERR_FUNC(BN_F_BN_GF2M_MOD), "BN_GF2m_mod"},
+    {ERR_FUNC(BN_F_BN_GF2M_MOD_EXP), "BN_GF2m_mod_exp"},
+    {ERR_FUNC(BN_F_BN_GF2M_MOD_MUL), "BN_GF2m_mod_mul"},
+    {ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD), "BN_GF2m_mod_solve_quad"},
+    {ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR), "BN_GF2m_mod_solve_quad_arr"},
+    {ERR_FUNC(BN_F_BN_GF2M_MOD_SQR), "BN_GF2m_mod_sqr"},
+    {ERR_FUNC(BN_F_BN_GF2M_MOD_SQRT), "BN_GF2m_mod_sqrt"},
+    {ERR_FUNC(BN_F_BN_LSHIFT), "BN_lshift"},
+    {ERR_FUNC(BN_F_BN_MOD_EXP2_MONT), "BN_mod_exp2_mont"},
+    {ERR_FUNC(BN_F_BN_MOD_EXP_MONT), "BN_mod_exp_mont"},
+    {ERR_FUNC(BN_F_BN_MOD_EXP_MONT_CONSTTIME), "BN_mod_exp_mont_consttime"},
+    {ERR_FUNC(BN_F_BN_MOD_EXP_MONT_WORD), "BN_mod_exp_mont_word"},
+    {ERR_FUNC(BN_F_BN_MOD_EXP_RECP), "BN_mod_exp_recp"},
+    {ERR_FUNC(BN_F_BN_MOD_EXP_SIMPLE), "BN_mod_exp_simple"},
+    {ERR_FUNC(BN_F_BN_MOD_INVERSE), "BN_mod_inverse"},
+    {ERR_FUNC(BN_F_BN_MOD_INVERSE_NO_BRANCH), "BN_mod_inverse_no_branch"},
+    {ERR_FUNC(BN_F_BN_MOD_LSHIFT_QUICK), "BN_mod_lshift_quick"},
+    {ERR_FUNC(BN_F_BN_MOD_SQRT), "BN_mod_sqrt"},
+    {ERR_FUNC(BN_F_BN_MPI2BN), "BN_mpi2bn"},
+    {ERR_FUNC(BN_F_BN_NEW), "BN_new"},
+    {ERR_FUNC(BN_F_BN_RAND), "BN_rand"},
+    {ERR_FUNC(BN_F_BN_RAND_RANGE), "BN_rand_range"},
+    {ERR_FUNC(BN_F_BN_RSHIFT), "BN_rshift"},
+    {ERR_FUNC(BN_F_BN_SET_WORDS), "bn_set_words"},
+    {ERR_FUNC(BN_F_BN_USUB), "BN_usub"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA BN_str_reasons[] = {
+    {ERR_REASON(BN_R_ARG2_LT_ARG3), "arg2 lt arg3"},
+    {ERR_REASON(BN_R_BAD_RECIPROCAL), "bad reciprocal"},
+    {ERR_REASON(BN_R_BIGNUM_TOO_LONG), "bignum too long"},
+    {ERR_REASON(BN_R_BITS_TOO_SMALL), "bits too small"},
+    {ERR_REASON(BN_R_CALLED_WITH_EVEN_MODULUS), "called with even modulus"},
+    {ERR_REASON(BN_R_DIV_BY_ZERO), "div by zero"},
+    {ERR_REASON(BN_R_ENCODING_ERROR), "encoding error"},
+    {ERR_REASON(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA),
+     "expand on static bignum data"},
+    {ERR_REASON(BN_R_INPUT_NOT_REDUCED), "input not reduced"},
+    {ERR_REASON(BN_R_INVALID_LENGTH), "invalid length"},
+    {ERR_REASON(BN_R_INVALID_RANGE), "invalid range"},
+    {ERR_REASON(BN_R_INVALID_SHIFT), "invalid shift"},
+    {ERR_REASON(BN_R_NOT_A_SQUARE), "not a square"},
+    {ERR_REASON(BN_R_NOT_INITIALIZED), "not initialized"},
+    {ERR_REASON(BN_R_NO_INVERSE), "no inverse"},
+    {ERR_REASON(BN_R_NO_SOLUTION), "no solution"},
+    {ERR_REASON(BN_R_PRIVATE_KEY_TOO_LARGE), "private key too large"},
+    {ERR_REASON(BN_R_P_IS_NOT_PRIME), "p is not prime"},
+    {ERR_REASON(BN_R_TOO_MANY_ITERATIONS), "too many iterations"},
+    {ERR_REASON(BN_R_TOO_MANY_TEMPORARY_VARIABLES),
+     "too many temporary variables"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_BN_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(BN_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, BN_str_functs);
+        ERR_load_strings(0, BN_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_exp.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_exp.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_exp.c	(revision 331)
@@ -0,0 +1,1362 @@
+/*
+ * Copyright 1995-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 "internal/cryptlib.h"
+#include "internal/constant_time_locl.h"
+#include "bn_lcl.h"
+
+#include <stdlib.h>
+#ifdef _WIN32
+# include <malloc.h>
+# ifndef alloca
+#  define alloca _alloca
+# endif
+#elif defined(__GNUC__)
+# ifndef alloca
+#  define alloca(s) __builtin_alloca((s))
+# endif
+#elif defined(__sun)
+# include <alloca.h>
+#endif
+
+#include "rsaz_exp.h"
+
+#undef SPARC_T4_MONT
+#if defined(OPENSSL_BN_ASM_MONT) && (defined(__sparc__) || defined(__sparc))
+# include "sparc_arch.h"
+extern unsigned int OPENSSL_sparcv9cap_P[];
+# define SPARC_T4_MONT
+#endif
+
+/* maximum precomputation table size for *variable* sliding windows */
+#define TABLE_SIZE      32
+
+/* this one works - simple but works */
+int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+{
+    int i, bits, ret = 0;
+    BIGNUM *v, *rr;
+
+    if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
+        /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
+        BNerr(BN_F_BN_EXP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+
+    BN_CTX_start(ctx);
+    if ((r == a) || (r == p))
+        rr = BN_CTX_get(ctx);
+    else
+        rr = r;
+    v = BN_CTX_get(ctx);
+    if (rr == NULL || v == NULL)
+        goto err;
+
+    if (BN_copy(v, a) == NULL)
+        goto err;
+    bits = BN_num_bits(p);
+
+    if (BN_is_odd(p)) {
+        if (BN_copy(rr, a) == NULL)
+            goto err;
+    } else {
+        if (!BN_one(rr))
+            goto err;
+    }
+
+    for (i = 1; i < bits; i++) {
+        if (!BN_sqr(v, v, ctx))
+            goto err;
+        if (BN_is_bit_set(p, i)) {
+            if (!BN_mul(rr, rr, v, ctx))
+                goto err;
+        }
+    }
+    if (r != rr && BN_copy(r, rr) == NULL)
+        goto err;
+
+    ret = 1;
+ err:
+    BN_CTX_end(ctx);
+    bn_check_top(r);
+    return (ret);
+}
+
+int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
+               BN_CTX *ctx)
+{
+    int ret;
+
+    bn_check_top(a);
+    bn_check_top(p);
+    bn_check_top(m);
+
+    /*-
+     * For even modulus  m = 2^k*m_odd, it might make sense to compute
+     * a^p mod m_odd  and  a^p mod 2^k  separately (with Montgomery
+     * exponentiation for the odd part), using appropriate exponent
+     * reductions, and combine the results using the CRT.
+     *
+     * For now, we use Montgomery only if the modulus is odd; otherwise,
+     * exponentiation using the reciprocal-based quick remaindering
+     * algorithm is used.
+     *
+     * (Timing obtained with expspeed.c [computations  a^p mod m
+     * where  a, p, m  are of the same length: 256, 512, 1024, 2048,
+     * 4096, 8192 bits], compared to the running time of the
+     * standard algorithm:
+     *
+     *   BN_mod_exp_mont   33 .. 40 %  [AMD K6-2, Linux, debug configuration]
+     *                     55 .. 77 %  [UltraSparc processor, but
+     *                                  debug-solaris-sparcv8-gcc conf.]
+     *
+     *   BN_mod_exp_recp   50 .. 70 %  [AMD K6-2, Linux, debug configuration]
+     *                     62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc]
+     *
+     * On the Sparc, BN_mod_exp_recp was faster than BN_mod_exp_mont
+     * at 2048 and more bits, but at 512 and 1024 bits, it was
+     * slower even than the standard algorithm!
+     *
+     * "Real" timings [linux-elf, solaris-sparcv9-gcc configurations]
+     * should be obtained when the new Montgomery reduction code
+     * has been integrated into OpenSSL.)
+     */
+
+#define MONT_MUL_MOD
+#define MONT_EXP_WORD
+#define RECP_MUL_MOD
+
+#ifdef MONT_MUL_MOD
+    /*
+     * I have finally been able to take out this pre-condition of the top bit
+     * being set.  It was caused by an error in BN_div with negatives.  There
+     * was also another problem when for a^b%m a >= m.  eay 07-May-97
+     */
+    /* if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */
+
+    if (BN_is_odd(m)) {
+# ifdef MONT_EXP_WORD
+        if (a->top == 1 && !a->neg
+            && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0)) {
+            BN_ULONG A = a->d[0];
+            ret = BN_mod_exp_mont_word(r, A, p, m, ctx, NULL);
+        } else
+# endif
+            ret = BN_mod_exp_mont(r, a, p, m, ctx, NULL);
+    } else
+#endif
+#ifdef RECP_MUL_MOD
+    {
+        ret = BN_mod_exp_recp(r, a, p, m, ctx);
+    }
+#else
+    {
+        ret = BN_mod_exp_simple(r, a, p, m, ctx);
+    }
+#endif
+
+    bn_check_top(r);
+    return (ret);
+}
+
+int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                    const BIGNUM *m, BN_CTX *ctx)
+{
+    int i, j, bits, ret = 0, wstart, wend, window, wvalue;
+    int start = 1;
+    BIGNUM *aa;
+    /* Table of variables obtained from 'ctx' */
+    BIGNUM *val[TABLE_SIZE];
+    BN_RECP_CTX recp;
+
+    if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
+        /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
+        BNerr(BN_F_BN_MOD_EXP_RECP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+
+    bits = BN_num_bits(p);
+    if (bits == 0) {
+        /* x**0 mod 1 is still zero. */
+        if (BN_is_one(m)) {
+            ret = 1;
+            BN_zero(r);
+        } else {
+            ret = BN_one(r);
+        }
+        return ret;
+    }
+
+    BN_CTX_start(ctx);
+    aa = BN_CTX_get(ctx);
+    val[0] = BN_CTX_get(ctx);
+    if (!aa || !val[0])
+        goto err;
+
+    BN_RECP_CTX_init(&recp);
+    if (m->neg) {
+        /* ignore sign of 'm' */
+        if (!BN_copy(aa, m))
+            goto err;
+        aa->neg = 0;
+        if (BN_RECP_CTX_set(&recp, aa, ctx) <= 0)
+            goto err;
+    } else {
+        if (BN_RECP_CTX_set(&recp, m, ctx) <= 0)
+            goto err;
+    }
+
+    if (!BN_nnmod(val[0], a, m, ctx))
+        goto err;               /* 1 */
+    if (BN_is_zero(val[0])) {
+        BN_zero(r);
+        ret = 1;
+        goto err;
+    }
+
+    window = BN_window_bits_for_exponent_size(bits);
+    if (window > 1) {
+        if (!BN_mod_mul_reciprocal(aa, val[0], val[0], &recp, ctx))
+            goto err;           /* 2 */
+        j = 1 << (window - 1);
+        for (i = 1; i < j; i++) {
+            if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
+                !BN_mod_mul_reciprocal(val[i], val[i - 1], aa, &recp, ctx))
+                goto err;
+        }
+    }
+
+    start = 1;                  /* This is used to avoid multiplication etc
+                                 * when there is only the value '1' in the
+                                 * buffer. */
+    wvalue = 0;                 /* The 'value' of the window */
+    wstart = bits - 1;          /* The top bit of the window */
+    wend = 0;                   /* The bottom bit of the window */
+
+    if (!BN_one(r))
+        goto err;
+
+    for (;;) {
+        if (BN_is_bit_set(p, wstart) == 0) {
+            if (!start)
+                if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx))
+                    goto err;
+            if (wstart == 0)
+                break;
+            wstart--;
+            continue;
+        }
+        /*
+         * We now have wstart on a 'set' bit, we now need to work out how bit
+         * a window to do.  To do this we need to scan forward until the last
+         * set bit before the end of the window
+         */
+        j = wstart;
+        wvalue = 1;
+        wend = 0;
+        for (i = 1; i < window; i++) {
+            if (wstart - i < 0)
+                break;
+            if (BN_is_bit_set(p, wstart - i)) {
+                wvalue <<= (i - wend);
+                wvalue |= 1;
+                wend = i;
+            }
+        }
+
+        /* wend is the size of the current window */
+        j = wend + 1;
+        /* add the 'bytes above' */
+        if (!start)
+            for (i = 0; i < j; i++) {
+                if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx))
+                    goto err;
+            }
+
+        /* wvalue will be an odd number < 2^window */
+        if (!BN_mod_mul_reciprocal(r, r, val[wvalue >> 1], &recp, ctx))
+            goto err;
+
+        /* move the 'window' down further */
+        wstart -= wend + 1;
+        wvalue = 0;
+        start = 0;
+        if (wstart < 0)
+            break;
+    }
+    ret = 1;
+ err:
+    BN_CTX_end(ctx);
+    BN_RECP_CTX_free(&recp);
+    bn_check_top(r);
+    return (ret);
+}
+
+int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+                    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+{
+    int i, j, bits, ret = 0, wstart, wend, window, wvalue;
+    int start = 1;
+    BIGNUM *d, *r;
+    const BIGNUM *aa;
+    /* Table of variables obtained from 'ctx' */
+    BIGNUM *val[TABLE_SIZE];
+    BN_MONT_CTX *mont = NULL;
+
+    if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
+        return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
+    }
+
+    bn_check_top(a);
+    bn_check_top(p);
+    bn_check_top(m);
+
+    if (!BN_is_odd(m)) {
+        BNerr(BN_F_BN_MOD_EXP_MONT, BN_R_CALLED_WITH_EVEN_MODULUS);
+        return (0);
+    }
+    bits = BN_num_bits(p);
+    if (bits == 0) {
+        /* x**0 mod 1 is still zero. */
+        if (BN_is_one(m)) {
+            ret = 1;
+            BN_zero(rr);
+        } else {
+            ret = BN_one(rr);
+        }
+        return ret;
+    }
+
+    BN_CTX_start(ctx);
+    d = BN_CTX_get(ctx);
+    r = BN_CTX_get(ctx);
+    val[0] = BN_CTX_get(ctx);
+    if (!d || !r || !val[0])
+        goto err;
+
+    /*
+     * If this is not done, things will break in the montgomery part
+     */
+
+    if (in_mont != NULL)
+        mont = in_mont;
+    else {
+        if ((mont = BN_MONT_CTX_new()) == NULL)
+            goto err;
+        if (!BN_MONT_CTX_set(mont, m, ctx))
+            goto err;
+    }
+
+    if (a->neg || BN_ucmp(a, m) >= 0) {
+        if (!BN_nnmod(val[0], a, m, ctx))
+            goto err;
+        aa = val[0];
+    } else
+        aa = a;
+    if (BN_is_zero(aa)) {
+        BN_zero(rr);
+        ret = 1;
+        goto err;
+    }
+    if (!BN_to_montgomery(val[0], aa, mont, ctx))
+        goto err;               /* 1 */
+
+    window = BN_window_bits_for_exponent_size(bits);
+    if (window > 1) {
+        if (!BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx))
+            goto err;           /* 2 */
+        j = 1 << (window - 1);
+        for (i = 1; i < j; i++) {
+            if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
+                !BN_mod_mul_montgomery(val[i], val[i - 1], d, mont, ctx))
+                goto err;
+        }
+    }
+
+    start = 1;                  /* This is used to avoid multiplication etc
+                                 * when there is only the value '1' in the
+                                 * buffer. */
+    wvalue = 0;                 /* The 'value' of the window */
+    wstart = bits - 1;          /* The top bit of the window */
+    wend = 0;                   /* The bottom bit of the window */
+
+#if 1                           /* by Shay Gueron's suggestion */
+    j = m->top;                 /* borrow j */
+    if (m->d[j - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) {
+        if (bn_wexpand(r, j) == NULL)
+            goto err;
+        /* 2^(top*BN_BITS2) - m */
+        r->d[0] = (0 - m->d[0]) & BN_MASK2;
+        for (i = 1; i < j; i++)
+            r->d[i] = (~m->d[i]) & BN_MASK2;
+        r->top = j;
+        /*
+         * Upper words will be zero if the corresponding words of 'm' were
+         * 0xfff[...], so decrement r->top accordingly.
+         */
+        bn_correct_top(r);
+    } else
+#endif
+    if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
+        goto err;
+    for (;;) {
+        if (BN_is_bit_set(p, wstart) == 0) {
+            if (!start) {
+                if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
+                    goto err;
+            }
+            if (wstart == 0)
+                break;
+            wstart--;
+            continue;
+        }
+        /*
+         * We now have wstart on a 'set' bit, we now need to work out how bit
+         * a window to do.  To do this we need to scan forward until the last
+         * set bit before the end of the window
+         */
+        j = wstart;
+        wvalue = 1;
+        wend = 0;
+        for (i = 1; i < window; i++) {
+            if (wstart - i < 0)
+                break;
+            if (BN_is_bit_set(p, wstart - i)) {
+                wvalue <<= (i - wend);
+                wvalue |= 1;
+                wend = i;
+            }
+        }
+
+        /* wend is the size of the current window */
+        j = wend + 1;
+        /* add the 'bytes above' */
+        if (!start)
+            for (i = 0; i < j; i++) {
+                if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
+                    goto err;
+            }
+
+        /* wvalue will be an odd number < 2^window */
+        if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx))
+            goto err;
+
+        /* move the 'window' down further */
+        wstart -= wend + 1;
+        wvalue = 0;
+        start = 0;
+        if (wstart < 0)
+            break;
+    }
+#if defined(SPARC_T4_MONT)
+    if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) {
+        j = mont->N.top;        /* borrow j */
+        val[0]->d[0] = 1;       /* borrow val[0] */
+        for (i = 1; i < j; i++)
+            val[0]->d[i] = 0;
+        val[0]->top = j;
+        if (!BN_mod_mul_montgomery(rr, r, val[0], mont, ctx))
+            goto err;
+    } else
+#endif
+    if (!BN_from_montgomery(rr, r, mont, ctx))
+        goto err;
+    ret = 1;
+ err:
+    if (in_mont == NULL)
+        BN_MONT_CTX_free(mont);
+    BN_CTX_end(ctx);
+    bn_check_top(rr);
+    return (ret);
+}
+
+#if defined(SPARC_T4_MONT)
+static BN_ULONG bn_get_bits(const BIGNUM *a, int bitpos)
+{
+    BN_ULONG ret = 0;
+    int wordpos;
+
+    wordpos = bitpos / BN_BITS2;
+    bitpos %= BN_BITS2;
+    if (wordpos >= 0 && wordpos < a->top) {
+        ret = a->d[wordpos] & BN_MASK2;
+        if (bitpos) {
+            ret >>= bitpos;
+            if (++wordpos < a->top)
+                ret |= a->d[wordpos] << (BN_BITS2 - bitpos);
+        }
+    }
+
+    return ret & BN_MASK2;
+}
+#endif
+
+/*
+ * BN_mod_exp_mont_consttime() stores the precomputed powers in a specific
+ * layout so that accessing any of these table values shows the same access
+ * pattern as far as cache lines are concerned.  The following functions are
+ * used to transfer a BIGNUM from/to that table.
+ */
+
+static int MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top,
+                                        unsigned char *buf, int idx,
+                                        int window)
+{
+    int i, j;
+    int width = 1 << window;
+    BN_ULONG *table = (BN_ULONG *)buf;
+
+    if (top > b->top)
+        top = b->top;           /* this works because 'buf' is explicitly
+                                 * zeroed */
+    for (i = 0, j = idx; i < top; i++, j += width) {
+        table[j] = b->d[i];
+    }
+
+    return 1;
+}
+
+static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top,
+                                          unsigned char *buf, int idx,
+                                          int window)
+{
+    int i, j;
+    int width = 1 << window;
+    /*
+     * We declare table 'volatile' in order to discourage compiler
+     * from reordering loads from the table. Concern is that if
+     * reordered in specific manner loads might give away the
+     * information we are trying to conceal. Some would argue that
+     * compiler can reorder them anyway, but it can as well be
+     * argued that doing so would be violation of standard...
+     */
+    volatile BN_ULONG *table = (volatile BN_ULONG *)buf;
+
+    if (bn_wexpand(b, top) == NULL)
+        return 0;
+
+    if (window <= 3) {
+        for (i = 0; i < top; i++, table += width) {
+            BN_ULONG acc = 0;
+
+            for (j = 0; j < width; j++) {
+                acc |= table[j] &
+                       ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1));
+            }
+
+            b->d[i] = acc;
+        }
+    } else {
+        int xstride = 1 << (window - 2);
+        BN_ULONG y0, y1, y2, y3;
+
+        i = idx >> (window - 2);        /* equivalent of idx / xstride */
+        idx &= xstride - 1;             /* equivalent of idx % xstride */
+
+        y0 = (BN_ULONG)0 - (constant_time_eq_int(i,0)&1);
+        y1 = (BN_ULONG)0 - (constant_time_eq_int(i,1)&1);
+        y2 = (BN_ULONG)0 - (constant_time_eq_int(i,2)&1);
+        y3 = (BN_ULONG)0 - (constant_time_eq_int(i,3)&1);
+
+        for (i = 0; i < top; i++, table += width) {
+            BN_ULONG acc = 0;
+
+            for (j = 0; j < xstride; j++) {
+                acc |= ( (table[j + 0 * xstride] & y0) |
+                         (table[j + 1 * xstride] & y1) |
+                         (table[j + 2 * xstride] & y2) |
+                         (table[j + 3 * xstride] & y3) )
+                       & ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1));
+            }
+
+            b->d[i] = acc;
+        }
+    }
+
+    b->top = top;
+    bn_correct_top(b);
+    return 1;
+}
+
+/*
+ * Given a pointer value, compute the next address that is a cache line
+ * multiple.
+ */
+#define MOD_EXP_CTIME_ALIGN(x_) \
+        ((unsigned char*)(x_) + (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - (((size_t)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK))))
+
+/*
+ * This variant of BN_mod_exp_mont() uses fixed windows and the special
+ * precomputation memory layout to limit data-dependency to a minimum to
+ * protect secret exponents (cf. the hyper-threading timing attacks pointed
+ * out by Colin Percival,
+ * http://www.daemonology.net/hyperthreading-considered-harmful/)
+ */
+int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+                              const BIGNUM *m, BN_CTX *ctx,
+                              BN_MONT_CTX *in_mont)
+{
+    int i, bits, ret = 0, window, wvalue;
+    int top;
+    BN_MONT_CTX *mont = NULL;
+
+    int numPowers;
+    unsigned char *powerbufFree = NULL;
+    int powerbufLen = 0;
+    unsigned char *powerbuf = NULL;
+    BIGNUM tmp, am;
+#if defined(SPARC_T4_MONT)
+    unsigned int t4 = 0;
+#endif
+
+    bn_check_top(a);
+    bn_check_top(p);
+    bn_check_top(m);
+
+    if (!BN_is_odd(m)) {
+        BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME, BN_R_CALLED_WITH_EVEN_MODULUS);
+        return (0);
+    }
+
+    top = m->top;
+
+    bits = BN_num_bits(p);
+    if (bits == 0) {
+        /* x**0 mod 1 is still zero. */
+        if (BN_is_one(m)) {
+            ret = 1;
+            BN_zero(rr);
+        } else {
+            ret = BN_one(rr);
+        }
+        return ret;
+    }
+
+    BN_CTX_start(ctx);
+
+    /*
+     * Allocate a montgomery context if it was not supplied by the caller. If
+     * this is not done, things will break in the montgomery part.
+     */
+    if (in_mont != NULL)
+        mont = in_mont;
+    else {
+        if ((mont = BN_MONT_CTX_new()) == NULL)
+            goto err;
+        if (!BN_MONT_CTX_set(mont, m, ctx))
+            goto err;
+    }
+
+#ifdef RSAZ_ENABLED
+    /*
+     * If the size of the operands allow it, perform the optimized
+     * RSAZ exponentiation. For further information see
+     * crypto/bn/rsaz_exp.c and accompanying assembly modules.
+     */
+    if ((16 == a->top) && (16 == p->top) && (BN_num_bits(m) == 1024)
+        && rsaz_avx2_eligible()) {
+        if (NULL == bn_wexpand(rr, 16))
+            goto err;
+        RSAZ_1024_mod_exp_avx2(rr->d, a->d, p->d, m->d, mont->RR.d,
+                               mont->n0[0]);
+        rr->top = 16;
+        rr->neg = 0;
+        bn_correct_top(rr);
+        ret = 1;
+        goto err;
+    } else if ((8 == a->top) && (8 == p->top) && (BN_num_bits(m) == 512)) {
+        if (NULL == bn_wexpand(rr, 8))
+            goto err;
+        RSAZ_512_mod_exp(rr->d, a->d, p->d, m->d, mont->n0[0], mont->RR.d);
+        rr->top = 8;
+        rr->neg = 0;
+        bn_correct_top(rr);
+        ret = 1;
+        goto err;
+    }
+#endif
+
+    /* Get the window size to use with size of p. */
+    window = BN_window_bits_for_ctime_exponent_size(bits);
+#if defined(SPARC_T4_MONT)
+    if (window >= 5 && (top & 15) == 0 && top <= 64 &&
+        (OPENSSL_sparcv9cap_P[1] & (CFR_MONTMUL | CFR_MONTSQR)) ==
+        (CFR_MONTMUL | CFR_MONTSQR) && (t4 = OPENSSL_sparcv9cap_P[0]))
+        window = 5;
+    else
+#endif
+#if defined(OPENSSL_BN_ASM_MONT5)
+    if (window >= 5) {
+        window = 5;             /* ~5% improvement for RSA2048 sign, and even
+                                 * for RSA4096 */
+        /* reserve space for mont->N.d[] copy */
+        powerbufLen += top * sizeof(mont->N.d[0]);
+    }
+#endif
+    (void)0;
+
+    /*
+     * Allocate a buffer large enough to hold all of the pre-computed powers
+     * of am, am itself and tmp.
+     */
+    numPowers = 1 << window;
+    powerbufLen += sizeof(m->d[0]) * (top * numPowers +
+                                      ((2 * top) >
+                                       numPowers ? (2 * top) : numPowers));
+#ifdef alloca
+    if (powerbufLen < 3072)
+        powerbufFree =
+            alloca(powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH);
+    else
+#endif
+        if ((powerbufFree =
+             OPENSSL_malloc(powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH))
+            == NULL)
+        goto err;
+
+    powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree);
+    memset(powerbuf, 0, powerbufLen);
+
+#ifdef alloca
+    if (powerbufLen < 3072)
+        powerbufFree = NULL;
+#endif
+
+    /* lay down tmp and am right after powers table */
+    tmp.d = (BN_ULONG *)(powerbuf + sizeof(m->d[0]) * top * numPowers);
+    am.d = tmp.d + top;
+    tmp.top = am.top = 0;
+    tmp.dmax = am.dmax = top;
+    tmp.neg = am.neg = 0;
+    tmp.flags = am.flags = BN_FLG_STATIC_DATA;
+
+    /* prepare a^0 in Montgomery domain */
+#if 1                           /* by Shay Gueron's suggestion */
+    if (m->d[top - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) {
+        /* 2^(top*BN_BITS2) - m */
+        tmp.d[0] = (0 - m->d[0]) & BN_MASK2;
+        for (i = 1; i < top; i++)
+            tmp.d[i] = (~m->d[i]) & BN_MASK2;
+        tmp.top = top;
+    } else
+#endif
+    if (!BN_to_montgomery(&tmp, BN_value_one(), mont, ctx))
+        goto err;
+
+    /* prepare a^1 in Montgomery domain */
+    if (a->neg || BN_ucmp(a, m) >= 0) {
+        if (!BN_mod(&am, a, m, ctx))
+            goto err;
+        if (!BN_to_montgomery(&am, &am, mont, ctx))
+            goto err;
+    } else if (!BN_to_montgomery(&am, a, mont, ctx))
+        goto err;
+
+#if defined(SPARC_T4_MONT)
+    if (t4) {
+        typedef int (*bn_pwr5_mont_f) (BN_ULONG *tp, const BN_ULONG *np,
+                                       const BN_ULONG *n0, const void *table,
+                                       int power, int bits);
+        int bn_pwr5_mont_t4_8(BN_ULONG *tp, const BN_ULONG *np,
+                              const BN_ULONG *n0, const void *table,
+                              int power, int bits);
+        int bn_pwr5_mont_t4_16(BN_ULONG *tp, const BN_ULONG *np,
+                               const BN_ULONG *n0, const void *table,
+                               int power, int bits);
+        int bn_pwr5_mont_t4_24(BN_ULONG *tp, const BN_ULONG *np,
+                               const BN_ULONG *n0, const void *table,
+                               int power, int bits);
+        int bn_pwr5_mont_t4_32(BN_ULONG *tp, const BN_ULONG *np,
+                               const BN_ULONG *n0, const void *table,
+                               int power, int bits);
+        static const bn_pwr5_mont_f pwr5_funcs[4] = {
+            bn_pwr5_mont_t4_8, bn_pwr5_mont_t4_16,
+            bn_pwr5_mont_t4_24, bn_pwr5_mont_t4_32
+        };
+        bn_pwr5_mont_f pwr5_worker = pwr5_funcs[top / 16 - 1];
+
+        typedef int (*bn_mul_mont_f) (BN_ULONG *rp, const BN_ULONG *ap,
+                                      const void *bp, const BN_ULONG *np,
+                                      const BN_ULONG *n0);
+        int bn_mul_mont_t4_8(BN_ULONG *rp, const BN_ULONG *ap, const void *bp,
+                             const BN_ULONG *np, const BN_ULONG *n0);
+        int bn_mul_mont_t4_16(BN_ULONG *rp, const BN_ULONG *ap,
+                              const void *bp, const BN_ULONG *np,
+                              const BN_ULONG *n0);
+        int bn_mul_mont_t4_24(BN_ULONG *rp, const BN_ULONG *ap,
+                              const void *bp, const BN_ULONG *np,
+                              const BN_ULONG *n0);
+        int bn_mul_mont_t4_32(BN_ULONG *rp, const BN_ULONG *ap,
+                              const void *bp, const BN_ULONG *np,
+                              const BN_ULONG *n0);
+        static const bn_mul_mont_f mul_funcs[4] = {
+            bn_mul_mont_t4_8, bn_mul_mont_t4_16,
+            bn_mul_mont_t4_24, bn_mul_mont_t4_32
+        };
+        bn_mul_mont_f mul_worker = mul_funcs[top / 16 - 1];
+
+        void bn_mul_mont_vis3(BN_ULONG *rp, const BN_ULONG *ap,
+                              const void *bp, const BN_ULONG *np,
+                              const BN_ULONG *n0, int num);
+        void bn_mul_mont_t4(BN_ULONG *rp, const BN_ULONG *ap,
+                            const void *bp, const BN_ULONG *np,
+                            const BN_ULONG *n0, int num);
+        void bn_mul_mont_gather5_t4(BN_ULONG *rp, const BN_ULONG *ap,
+                                    const void *table, const BN_ULONG *np,
+                                    const BN_ULONG *n0, int num, int power);
+        void bn_flip_n_scatter5_t4(const BN_ULONG *inp, size_t num,
+                                   void *table, size_t power);
+        void bn_gather5_t4(BN_ULONG *out, size_t num,
+                           void *table, size_t power);
+        void bn_flip_t4(BN_ULONG *dst, BN_ULONG *src, size_t num);
+
+        BN_ULONG *np = mont->N.d, *n0 = mont->n0;
+        int stride = 5 * (6 - (top / 16 - 1)); /* multiple of 5, but less
+                                                * than 32 */
+
+        /*
+         * BN_to_montgomery can contaminate words above .top [in
+         * BN_DEBUG[_DEBUG] build]...
+         */
+        for (i = am.top; i < top; i++)
+            am.d[i] = 0;
+        for (i = tmp.top; i < top; i++)
+            tmp.d[i] = 0;
+
+        bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, 0);
+        bn_flip_n_scatter5_t4(am.d, top, powerbuf, 1);
+        if (!(*mul_worker) (tmp.d, am.d, am.d, np, n0) &&
+            !(*mul_worker) (tmp.d, am.d, am.d, np, n0))
+            bn_mul_mont_vis3(tmp.d, am.d, am.d, np, n0, top);
+        bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, 2);
+
+        for (i = 3; i < 32; i++) {
+            /* Calculate a^i = a^(i-1) * a */
+            if (!(*mul_worker) (tmp.d, tmp.d, am.d, np, n0) &&
+                !(*mul_worker) (tmp.d, tmp.d, am.d, np, n0))
+                bn_mul_mont_vis3(tmp.d, tmp.d, am.d, np, n0, top);
+            bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, i);
+        }
+
+        /* switch to 64-bit domain */
+        np = alloca(top * sizeof(BN_ULONG));
+        top /= 2;
+        bn_flip_t4(np, mont->N.d, top);
+
+        bits--;
+        for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--)
+            wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+        bn_gather5_t4(tmp.d, top, powerbuf, wvalue);
+
+        /*
+         * Scan the exponent one window at a time starting from the most
+         * significant bits.
+         */
+        while (bits >= 0) {
+            if (bits < stride)
+                stride = bits + 1;
+            bits -= stride;
+            wvalue = bn_get_bits(p, bits + 1);
+
+            if ((*pwr5_worker) (tmp.d, np, n0, powerbuf, wvalue, stride))
+                continue;
+            /* retry once and fall back */
+            if ((*pwr5_worker) (tmp.d, np, n0, powerbuf, wvalue, stride))
+                continue;
+
+            bits += stride - 5;
+            wvalue >>= stride - 5;
+            wvalue &= 31;
+            bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);
+            bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);
+            bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);
+            bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);
+            bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);
+            bn_mul_mont_gather5_t4(tmp.d, tmp.d, powerbuf, np, n0, top,
+                                   wvalue);
+        }
+
+        bn_flip_t4(tmp.d, tmp.d, top);
+        top *= 2;
+        /* back to 32-bit domain */
+        tmp.top = top;
+        bn_correct_top(&tmp);
+        OPENSSL_cleanse(np, top * sizeof(BN_ULONG));
+    } else
+#endif
+#if defined(OPENSSL_BN_ASM_MONT5)
+    if (window == 5 && top > 1) {
+        /*
+         * This optimization uses ideas from http://eprint.iacr.org/2011/239,
+         * specifically optimization of cache-timing attack countermeasures
+         * and pre-computation optimization.
+         */
+
+        /*
+         * Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as
+         * 512-bit RSA is hardly relevant, we omit it to spare size...
+         */
+        void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap,
+                                 const void *table, const BN_ULONG *np,
+                                 const BN_ULONG *n0, int num, int power);
+        void bn_scatter5(const BN_ULONG *inp, size_t num,
+                         void *table, size_t power);
+        void bn_gather5(BN_ULONG *out, size_t num, void *table, size_t power);
+        void bn_power5(BN_ULONG *rp, const BN_ULONG *ap,
+                       const void *table, const BN_ULONG *np,
+                       const BN_ULONG *n0, int num, int power);
+        int bn_get_bits5(const BN_ULONG *ap, int off);
+        int bn_from_montgomery(BN_ULONG *rp, const BN_ULONG *ap,
+                               const BN_ULONG *not_used, const BN_ULONG *np,
+                               const BN_ULONG *n0, int num);
+
+        BN_ULONG *n0 = mont->n0, *np;
+
+        /*
+         * BN_to_montgomery can contaminate words above .top [in
+         * BN_DEBUG[_DEBUG] build]...
+         */
+        for (i = am.top; i < top; i++)
+            am.d[i] = 0;
+        for (i = tmp.top; i < top; i++)
+            tmp.d[i] = 0;
+
+        /*
+         * copy mont->N.d[] to improve cache locality
+         */
+        for (np = am.d + top, i = 0; i < top; i++)
+            np[i] = mont->N.d[i];
+
+        bn_scatter5(tmp.d, top, powerbuf, 0);
+        bn_scatter5(am.d, am.top, powerbuf, 1);
+        bn_mul_mont(tmp.d, am.d, am.d, np, n0, top);
+        bn_scatter5(tmp.d, top, powerbuf, 2);
+
+# if 0
+        for (i = 3; i < 32; i++) {
+            /* Calculate a^i = a^(i-1) * a */
+            bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
+            bn_scatter5(tmp.d, top, powerbuf, i);
+        }
+# else
+        /* same as above, but uses squaring for 1/2 of operations */
+        for (i = 4; i < 32; i *= 2) {
+            bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+            bn_scatter5(tmp.d, top, powerbuf, i);
+        }
+        for (i = 3; i < 8; i += 2) {
+            int j;
+            bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
+            bn_scatter5(tmp.d, top, powerbuf, i);
+            for (j = 2 * i; j < 32; j *= 2) {
+                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+                bn_scatter5(tmp.d, top, powerbuf, j);
+            }
+        }
+        for (; i < 16; i += 2) {
+            bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
+            bn_scatter5(tmp.d, top, powerbuf, i);
+            bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+            bn_scatter5(tmp.d, top, powerbuf, 2 * i);
+        }
+        for (; i < 32; i += 2) {
+            bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
+            bn_scatter5(tmp.d, top, powerbuf, i);
+        }
+# endif
+        bits--;
+        for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--)
+            wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+        bn_gather5(tmp.d, top, powerbuf, wvalue);
+
+        /*
+         * Scan the exponent one window at a time starting from the most
+         * significant bits.
+         */
+        if (top & 7)
+            while (bits >= 0) {
+                for (wvalue = 0, i = 0; i < 5; i++, bits--)
+                    wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+
+                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+                bn_mul_mont_gather5(tmp.d, tmp.d, powerbuf, np, n0, top,
+                                    wvalue);
+        } else {
+            while (bits >= 0) {
+                wvalue = bn_get_bits5(p->d, bits - 4);
+                bits -= 5;
+                bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue);
+            }
+        }
+
+        ret = bn_from_montgomery(tmp.d, tmp.d, NULL, np, n0, top);
+        tmp.top = top;
+        bn_correct_top(&tmp);
+        if (ret) {
+            if (!BN_copy(rr, &tmp))
+                ret = 0;
+            goto err;           /* non-zero ret means it's not error */
+        }
+    } else
+#endif
+    {
+        if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0, window))
+            goto err;
+        if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am, top, powerbuf, 1, window))
+            goto err;
+
+        /*
+         * If the window size is greater than 1, then calculate
+         * val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1) (even
+         * powers could instead be computed as (a^(i/2))^2 to use the slight
+         * performance advantage of sqr over mul).
+         */
+        if (window > 1) {
+            if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx))
+                goto err;
+            if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 2,
+                                              window))
+                goto err;
+            for (i = 3; i < numPowers; i++) {
+                /* Calculate a^i = a^(i-1) * a */
+                if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx))
+                    goto err;
+                if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, i,
+                                                  window))
+                    goto err;
+            }
+        }
+
+        bits--;
+        for (wvalue = 0, i = bits % window; i >= 0; i--, bits--)
+            wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+        if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp, top, powerbuf, wvalue,
+                                            window))
+            goto err;
+
+        /*
+         * Scan the exponent one window at a time starting from the most
+         * significant bits.
+         */
+        while (bits >= 0) {
+            wvalue = 0;         /* The 'value' of the window */
+
+            /* Scan the window, squaring the result as we go */
+            for (i = 0; i < window; i++, bits--) {
+                if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp, mont, ctx))
+                    goto err;
+                wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+            }
+
+            /*
+             * Fetch the appropriate pre-computed value from the pre-buf
+             */
+            if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf, wvalue,
+                                                window))
+                goto err;
+
+            /* Multiply the result into the intermediate result */
+            if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx))
+                goto err;
+        }
+    }
+
+    /* Convert the final result from montgomery to standard format */
+#if defined(SPARC_T4_MONT)
+    if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) {
+        am.d[0] = 1;            /* borrow am */
+        for (i = 1; i < top; i++)
+            am.d[i] = 0;
+        if (!BN_mod_mul_montgomery(rr, &tmp, &am, mont, ctx))
+            goto err;
+    } else
+#endif
+    if (!BN_from_montgomery(rr, &tmp, mont, ctx))
+        goto err;
+    ret = 1;
+ err:
+    if (in_mont == NULL)
+        BN_MONT_CTX_free(mont);
+    if (powerbuf != NULL) {
+        OPENSSL_cleanse(powerbuf, powerbufLen);
+        OPENSSL_free(powerbufFree);
+    }
+    BN_CTX_end(ctx);
+    return (ret);
+}
+
+int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
+                         const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+{
+    BN_MONT_CTX *mont = NULL;
+    int b, bits, ret = 0;
+    int r_is_one;
+    BN_ULONG w, next_w;
+    BIGNUM *d, *r, *t;
+    BIGNUM *swap_tmp;
+#define BN_MOD_MUL_WORD(r, w, m) \
+                (BN_mul_word(r, (w)) && \
+                (/* BN_ucmp(r, (m)) < 0 ? 1 :*/  \
+                        (BN_mod(t, r, m, ctx) && (swap_tmp = r, r = t, t = swap_tmp, 1))))
+    /*
+     * BN_MOD_MUL_WORD is only used with 'w' large, so the BN_ucmp test is
+     * probably more overhead than always using BN_mod (which uses BN_copy if
+     * a similar test returns true).
+     */
+    /*
+     * We can use BN_mod and do not need BN_nnmod because our accumulator is
+     * never negative (the result of BN_mod does not depend on the sign of
+     * the modulus).
+     */
+#define BN_TO_MONTGOMERY_WORD(r, w, mont) \
+                (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx))
+
+    if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
+        /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
+        BNerr(BN_F_BN_MOD_EXP_MONT_WORD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+
+    bn_check_top(p);
+    bn_check_top(m);
+
+    if (!BN_is_odd(m)) {
+        BNerr(BN_F_BN_MOD_EXP_MONT_WORD, BN_R_CALLED_WITH_EVEN_MODULUS);
+        return (0);
+    }
+    if (m->top == 1)
+        a %= m->d[0];           /* make sure that 'a' is reduced */
+
+    bits = BN_num_bits(p);
+    if (bits == 0) {
+        /* x**0 mod 1 is still zero. */
+        if (BN_is_one(m)) {
+            ret = 1;
+            BN_zero(rr);
+        } else {
+            ret = BN_one(rr);
+        }
+        return ret;
+    }
+    if (a == 0) {
+        BN_zero(rr);
+        ret = 1;
+        return ret;
+    }
+
+    BN_CTX_start(ctx);
+    d = BN_CTX_get(ctx);
+    r = BN_CTX_get(ctx);
+    t = BN_CTX_get(ctx);
+    if (d == NULL || r == NULL || t == NULL)
+        goto err;
+
+    if (in_mont != NULL)
+        mont = in_mont;
+    else {
+        if ((mont = BN_MONT_CTX_new()) == NULL)
+            goto err;
+        if (!BN_MONT_CTX_set(mont, m, ctx))
+            goto err;
+    }
+
+    r_is_one = 1;               /* except for Montgomery factor */
+
+    /* bits-1 >= 0 */
+
+    /* The result is accumulated in the product r*w. */
+    w = a;                      /* bit 'bits-1' of 'p' is always set */
+    for (b = bits - 2; b >= 0; b--) {
+        /* First, square r*w. */
+        next_w = w * w;
+        if ((next_w / w) != w) { /* overflow */
+            if (r_is_one) {
+                if (!BN_TO_MONTGOMERY_WORD(r, w, mont))
+                    goto err;
+                r_is_one = 0;
+            } else {
+                if (!BN_MOD_MUL_WORD(r, w, m))
+                    goto err;
+            }
+            next_w = 1;
+        }
+        w = next_w;
+        if (!r_is_one) {
+            if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
+                goto err;
+        }
+
+        /* Second, multiply r*w by 'a' if exponent bit is set. */
+        if (BN_is_bit_set(p, b)) {
+            next_w = w * a;
+            if ((next_w / a) != w) { /* overflow */
+                if (r_is_one) {
+                    if (!BN_TO_MONTGOMERY_WORD(r, w, mont))
+                        goto err;
+                    r_is_one = 0;
+                } else {
+                    if (!BN_MOD_MUL_WORD(r, w, m))
+                        goto err;
+                }
+                next_w = a;
+            }
+            w = next_w;
+        }
+    }
+
+    /* Finally, set r:=r*w. */
+    if (w != 1) {
+        if (r_is_one) {
+            if (!BN_TO_MONTGOMERY_WORD(r, w, mont))
+                goto err;
+            r_is_one = 0;
+        } else {
+            if (!BN_MOD_MUL_WORD(r, w, m))
+                goto err;
+        }
+    }
+
+    if (r_is_one) {             /* can happen only if a == 1 */
+        if (!BN_one(rr))
+            goto err;
+    } else {
+        if (!BN_from_montgomery(rr, r, mont, ctx))
+            goto err;
+    }
+    ret = 1;
+ err:
+    if (in_mont == NULL)
+        BN_MONT_CTX_free(mont);
+    BN_CTX_end(ctx);
+    bn_check_top(rr);
+    return (ret);
+}
+
+/* The old fallback, simple version :-) */
+int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                      const BIGNUM *m, BN_CTX *ctx)
+{
+    int i, j, bits, ret = 0, wstart, wend, window, wvalue;
+    int start = 1;
+    BIGNUM *d;
+    /* Table of variables obtained from 'ctx' */
+    BIGNUM *val[TABLE_SIZE];
+
+    if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
+        /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
+        BNerr(BN_F_BN_MOD_EXP_SIMPLE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+
+    bits = BN_num_bits(p);
+   if (bits == 0) {
+        /* x**0 mod 1 is still zero. */
+        if (BN_is_one(m)) {
+            ret = 1;
+            BN_zero(r);
+        } else {
+            ret = BN_one(r);
+        }
+        return ret;
+    }
+
+    BN_CTX_start(ctx);
+    d = BN_CTX_get(ctx);
+    val[0] = BN_CTX_get(ctx);
+    if (!d || !val[0])
+        goto err;
+
+    if (!BN_nnmod(val[0], a, m, ctx))
+        goto err;               /* 1 */
+    if (BN_is_zero(val[0])) {
+        BN_zero(r);
+        ret = 1;
+        goto err;
+    }
+
+    window = BN_window_bits_for_exponent_size(bits);
+    if (window > 1) {
+        if (!BN_mod_mul(d, val[0], val[0], m, ctx))
+            goto err;           /* 2 */
+        j = 1 << (window - 1);
+        for (i = 1; i < j; i++) {
+            if (((val[i] = BN_CTX_get(ctx)) == NULL) ||
+                !BN_mod_mul(val[i], val[i - 1], d, m, ctx))
+                goto err;
+        }
+    }
+
+    start = 1;                  /* This is used to avoid multiplication etc
+                                 * when there is only the value '1' in the
+                                 * buffer. */
+    wvalue = 0;                 /* The 'value' of the window */
+    wstart = bits - 1;          /* The top bit of the window */
+    wend = 0;                   /* The bottom bit of the window */
+
+    if (!BN_one(r))
+        goto err;
+
+    for (;;) {
+        if (BN_is_bit_set(p, wstart) == 0) {
+            if (!start)
+                if (!BN_mod_mul(r, r, r, m, ctx))
+                    goto err;
+            if (wstart == 0)
+                break;
+            wstart--;
+            continue;
+        }
+        /*
+         * We now have wstart on a 'set' bit, we now need to work out how bit
+         * a window to do.  To do this we need to scan forward until the last
+         * set bit before the end of the window
+         */
+        j = wstart;
+        wvalue = 1;
+        wend = 0;
+        for (i = 1; i < window; i++) {
+            if (wstart - i < 0)
+                break;
+            if (BN_is_bit_set(p, wstart - i)) {
+                wvalue <<= (i - wend);
+                wvalue |= 1;
+                wend = i;
+            }
+        }
+
+        /* wend is the size of the current window */
+        j = wend + 1;
+        /* add the 'bytes above' */
+        if (!start)
+            for (i = 0; i < j; i++) {
+                if (!BN_mod_mul(r, r, r, m, ctx))
+                    goto err;
+            }
+
+        /* wvalue will be an odd number < 2^window */
+        if (!BN_mod_mul(r, r, val[wvalue >> 1], m, ctx))
+            goto err;
+
+        /* move the 'window' down further */
+        wstart -= wend + 1;
+        wvalue = 0;
+        start = 0;
+        if (wstart < 0)
+            break;
+    }
+    ret = 1;
+ err:
+    BN_CTX_end(ctx);
+    bn_check_top(r);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_exp2.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_exp2.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_exp2.c	(revision 331)
@@ -0,0 +1,201 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include "bn_lcl.h"
+
+#define TABLE_SIZE      32
+
+int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
+                     const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m,
+                     BN_CTX *ctx, BN_MONT_CTX *in_mont)
+{
+    int i, j, bits, b, bits1, bits2, ret =
+        0, wpos1, wpos2, window1, window2, wvalue1, wvalue2;
+    int r_is_one = 1;
+    BIGNUM *d, *r;
+    const BIGNUM *a_mod_m;
+    /* Tables of variables obtained from 'ctx' */
+    BIGNUM *val1[TABLE_SIZE], *val2[TABLE_SIZE];
+    BN_MONT_CTX *mont = NULL;
+
+    bn_check_top(a1);
+    bn_check_top(p1);
+    bn_check_top(a2);
+    bn_check_top(p2);
+    bn_check_top(m);
+
+    if (!(m->d[0] & 1)) {
+        BNerr(BN_F_BN_MOD_EXP2_MONT, BN_R_CALLED_WITH_EVEN_MODULUS);
+        return (0);
+    }
+    bits1 = BN_num_bits(p1);
+    bits2 = BN_num_bits(p2);
+    if ((bits1 == 0) && (bits2 == 0)) {
+        ret = BN_one(rr);
+        return ret;
+    }
+
+    bits = (bits1 > bits2) ? bits1 : bits2;
+
+    BN_CTX_start(ctx);
+    d = BN_CTX_get(ctx);
+    r = BN_CTX_get(ctx);
+    val1[0] = BN_CTX_get(ctx);
+    val2[0] = BN_CTX_get(ctx);
+    if (!d || !r || !val1[0] || !val2[0])
+        goto err;
+
+    if (in_mont != NULL)
+        mont = in_mont;
+    else {
+        if ((mont = BN_MONT_CTX_new()) == NULL)
+            goto err;
+        if (!BN_MONT_CTX_set(mont, m, ctx))
+            goto err;
+    }
+
+    window1 = BN_window_bits_for_exponent_size(bits1);
+    window2 = BN_window_bits_for_exponent_size(bits2);
+
+    /*
+     * Build table for a1:   val1[i] := a1^(2*i + 1) mod m  for i = 0 .. 2^(window1-1)
+     */
+    if (a1->neg || BN_ucmp(a1, m) >= 0) {
+        if (!BN_mod(val1[0], a1, m, ctx))
+            goto err;
+        a_mod_m = val1[0];
+    } else
+        a_mod_m = a1;
+    if (BN_is_zero(a_mod_m)) {
+        BN_zero(rr);
+        ret = 1;
+        goto err;
+    }
+
+    if (!BN_to_montgomery(val1[0], a_mod_m, mont, ctx))
+        goto err;
+    if (window1 > 1) {
+        if (!BN_mod_mul_montgomery(d, val1[0], val1[0], mont, ctx))
+            goto err;
+
+        j = 1 << (window1 - 1);
+        for (i = 1; i < j; i++) {
+            if (((val1[i] = BN_CTX_get(ctx)) == NULL) ||
+                !BN_mod_mul_montgomery(val1[i], val1[i - 1], d, mont, ctx))
+                goto err;
+        }
+    }
+
+    /*
+     * Build table for a2:   val2[i] := a2^(2*i + 1) mod m  for i = 0 .. 2^(window2-1)
+     */
+    if (a2->neg || BN_ucmp(a2, m) >= 0) {
+        if (!BN_mod(val2[0], a2, m, ctx))
+            goto err;
+        a_mod_m = val2[0];
+    } else
+        a_mod_m = a2;
+    if (BN_is_zero(a_mod_m)) {
+        BN_zero(rr);
+        ret = 1;
+        goto err;
+    }
+    if (!BN_to_montgomery(val2[0], a_mod_m, mont, ctx))
+        goto err;
+    if (window2 > 1) {
+        if (!BN_mod_mul_montgomery(d, val2[0], val2[0], mont, ctx))
+            goto err;
+
+        j = 1 << (window2 - 1);
+        for (i = 1; i < j; i++) {
+            if (((val2[i] = BN_CTX_get(ctx)) == NULL) ||
+                !BN_mod_mul_montgomery(val2[i], val2[i - 1], d, mont, ctx))
+                goto err;
+        }
+    }
+
+    /* Now compute the power product, using independent windows. */
+    r_is_one = 1;
+    wvalue1 = 0;                /* The 'value' of the first window */
+    wvalue2 = 0;                /* The 'value' of the second window */
+    wpos1 = 0;                  /* If wvalue1 > 0, the bottom bit of the
+                                 * first window */
+    wpos2 = 0;                  /* If wvalue2 > 0, the bottom bit of the
+                                 * second window */
+
+    if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
+        goto err;
+    for (b = bits - 1; b >= 0; b--) {
+        if (!r_is_one) {
+            if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))
+                goto err;
+        }
+
+        if (!wvalue1)
+            if (BN_is_bit_set(p1, b)) {
+                /*
+                 * consider bits b-window1+1 .. b for this window
+                 */
+                i = b - window1 + 1;
+                while (!BN_is_bit_set(p1, i)) /* works for i<0 */
+                    i++;
+                wpos1 = i;
+                wvalue1 = 1;
+                for (i = b - 1; i >= wpos1; i--) {
+                    wvalue1 <<= 1;
+                    if (BN_is_bit_set(p1, i))
+                        wvalue1++;
+                }
+            }
+
+        if (!wvalue2)
+            if (BN_is_bit_set(p2, b)) {
+                /*
+                 * consider bits b-window2+1 .. b for this window
+                 */
+                i = b - window2 + 1;
+                while (!BN_is_bit_set(p2, i))
+                    i++;
+                wpos2 = i;
+                wvalue2 = 1;
+                for (i = b - 1; i >= wpos2; i--) {
+                    wvalue2 <<= 1;
+                    if (BN_is_bit_set(p2, i))
+                        wvalue2++;
+                }
+            }
+
+        if (wvalue1 && b == wpos1) {
+            /* wvalue1 is odd and < 2^window1 */
+            if (!BN_mod_mul_montgomery(r, r, val1[wvalue1 >> 1], mont, ctx))
+                goto err;
+            wvalue1 = 0;
+            r_is_one = 0;
+        }
+
+        if (wvalue2 && b == wpos2) {
+            /* wvalue2 is odd and < 2^window2 */
+            if (!BN_mod_mul_montgomery(r, r, val2[wvalue2 >> 1], mont, ctx))
+                goto err;
+            wvalue2 = 0;
+            r_is_one = 0;
+        }
+    }
+    if (!BN_from_montgomery(rr, r, mont, ctx))
+        goto err;
+    ret = 1;
+ err:
+    if (in_mont == NULL)
+        BN_MONT_CTX_free(mont);
+    BN_CTX_end(ctx);
+    bn_check_top(rr);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_gcd.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_gcd.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_gcd.c	(revision 331)
@@ -0,0 +1,620 @@
+/*
+ * Copyright 1995-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 "internal/cryptlib.h"
+#include "bn_lcl.h"
+
+static BIGNUM *euclid(BIGNUM *a, BIGNUM *b);
+
+int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx)
+{
+    BIGNUM *a, *b, *t;
+    int ret = 0;
+
+    bn_check_top(in_a);
+    bn_check_top(in_b);
+
+    BN_CTX_start(ctx);
+    a = BN_CTX_get(ctx);
+    b = BN_CTX_get(ctx);
+    if (a == NULL || b == NULL)
+        goto err;
+
+    if (BN_copy(a, in_a) == NULL)
+        goto err;
+    if (BN_copy(b, in_b) == NULL)
+        goto err;
+    a->neg = 0;
+    b->neg = 0;
+
+    if (BN_cmp(a, b) < 0) {
+        t = a;
+        a = b;
+        b = t;
+    }
+    t = euclid(a, b);
+    if (t == NULL)
+        goto err;
+
+    if (BN_copy(r, t) == NULL)
+        goto err;
+    ret = 1;
+ err:
+    BN_CTX_end(ctx);
+    bn_check_top(r);
+    return (ret);
+}
+
+static BIGNUM *euclid(BIGNUM *a, BIGNUM *b)
+{
+    BIGNUM *t;
+    int shifts = 0;
+
+    bn_check_top(a);
+    bn_check_top(b);
+
+    /* 0 <= b <= a */
+    while (!BN_is_zero(b)) {
+        /* 0 < b <= a */
+
+        if (BN_is_odd(a)) {
+            if (BN_is_odd(b)) {
+                if (!BN_sub(a, a, b))
+                    goto err;
+                if (!BN_rshift1(a, a))
+                    goto err;
+                if (BN_cmp(a, b) < 0) {
+                    t = a;
+                    a = b;
+                    b = t;
+                }
+            } else {            /* a odd - b even */
+
+                if (!BN_rshift1(b, b))
+                    goto err;
+                if (BN_cmp(a, b) < 0) {
+                    t = a;
+                    a = b;
+                    b = t;
+                }
+            }
+        } else {                /* a is even */
+
+            if (BN_is_odd(b)) {
+                if (!BN_rshift1(a, a))
+                    goto err;
+                if (BN_cmp(a, b) < 0) {
+                    t = a;
+                    a = b;
+                    b = t;
+                }
+            } else {            /* a even - b even */
+
+                if (!BN_rshift1(a, a))
+                    goto err;
+                if (!BN_rshift1(b, b))
+                    goto err;
+                shifts++;
+            }
+        }
+        /* 0 <= b <= a */
+    }
+
+    if (shifts) {
+        if (!BN_lshift(a, a, shifts))
+            goto err;
+    }
+    bn_check_top(a);
+    return (a);
+ err:
+    return (NULL);
+}
+
+/* solves ax == 1 (mod n) */
+static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
+                                        const BIGNUM *a, const BIGNUM *n,
+                                        BN_CTX *ctx);
+
+BIGNUM *BN_mod_inverse(BIGNUM *in,
+                       const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
+{
+    BIGNUM *rv;
+    int noinv;
+    rv = int_bn_mod_inverse(in, a, n, ctx, &noinv);
+    if (noinv)
+        BNerr(BN_F_BN_MOD_INVERSE, BN_R_NO_INVERSE);
+    return rv;
+}
+
+BIGNUM *int_bn_mod_inverse(BIGNUM *in,
+                           const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx,
+                           int *pnoinv)
+{
+    BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
+    BIGNUM *ret = NULL;
+    int sign;
+
+    if (pnoinv)
+        *pnoinv = 0;
+
+    if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0)
+        || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0)) {
+        return BN_mod_inverse_no_branch(in, a, n, ctx);
+    }
+
+    bn_check_top(a);
+    bn_check_top(n);
+
+    BN_CTX_start(ctx);
+    A = BN_CTX_get(ctx);
+    B = BN_CTX_get(ctx);
+    X = BN_CTX_get(ctx);
+    D = BN_CTX_get(ctx);
+    M = BN_CTX_get(ctx);
+    Y = BN_CTX_get(ctx);
+    T = BN_CTX_get(ctx);
+    if (T == NULL)
+        goto err;
+
+    if (in == NULL)
+        R = BN_new();
+    else
+        R = in;
+    if (R == NULL)
+        goto err;
+
+    BN_one(X);
+    BN_zero(Y);
+    if (BN_copy(B, a) == NULL)
+        goto err;
+    if (BN_copy(A, n) == NULL)
+        goto err;
+    A->neg = 0;
+    if (B->neg || (BN_ucmp(B, A) >= 0)) {
+        if (!BN_nnmod(B, B, A, ctx))
+            goto err;
+    }
+    sign = -1;
+    /*-
+     * From  B = a mod |n|,  A = |n|  it follows that
+     *
+     *      0 <= B < A,
+     *     -sign*X*a  ==  B   (mod |n|),
+     *      sign*Y*a  ==  A   (mod |n|).
+     */
+
+    if (BN_is_odd(n) && (BN_num_bits(n) <= 2048)) {
+        /*
+         * Binary inversion algorithm; requires odd modulus. This is faster
+         * than the general algorithm if the modulus is sufficiently small
+         * (about 400 .. 500 bits on 32-bit systems, but much more on 64-bit
+         * systems)
+         */
+        int shift;
+
+        while (!BN_is_zero(B)) {
+            /*-
+             *      0 < B < |n|,
+             *      0 < A <= |n|,
+             * (1) -sign*X*a  ==  B   (mod |n|),
+             * (2)  sign*Y*a  ==  A   (mod |n|)
+             */
+
+            /*
+             * Now divide B by the maximum possible power of two in the
+             * integers, and divide X by the same value mod |n|. When we're
+             * done, (1) still holds.
+             */
+            shift = 0;
+            while (!BN_is_bit_set(B, shift)) { /* note that 0 < B */
+                shift++;
+
+                if (BN_is_odd(X)) {
+                    if (!BN_uadd(X, X, n))
+                        goto err;
+                }
+                /*
+                 * now X is even, so we can easily divide it by two
+                 */
+                if (!BN_rshift1(X, X))
+                    goto err;
+            }
+            if (shift > 0) {
+                if (!BN_rshift(B, B, shift))
+                    goto err;
+            }
+
+            /*
+             * Same for A and Y.  Afterwards, (2) still holds.
+             */
+            shift = 0;
+            while (!BN_is_bit_set(A, shift)) { /* note that 0 < A */
+                shift++;
+
+                if (BN_is_odd(Y)) {
+                    if (!BN_uadd(Y, Y, n))
+                        goto err;
+                }
+                /* now Y is even */
+                if (!BN_rshift1(Y, Y))
+                    goto err;
+            }
+            if (shift > 0) {
+                if (!BN_rshift(A, A, shift))
+                    goto err;
+            }
+
+            /*-
+             * We still have (1) and (2).
+             * Both  A  and  B  are odd.
+             * The following computations ensure that
+             *
+             *     0 <= B < |n|,
+             *      0 < A < |n|,
+             * (1) -sign*X*a  ==  B   (mod |n|),
+             * (2)  sign*Y*a  ==  A   (mod |n|),
+             *
+             * and that either  A  or  B  is even in the next iteration.
+             */
+            if (BN_ucmp(B, A) >= 0) {
+                /* -sign*(X + Y)*a == B - A  (mod |n|) */
+                if (!BN_uadd(X, X, Y))
+                    goto err;
+                /*
+                 * NB: we could use BN_mod_add_quick(X, X, Y, n), but that
+                 * actually makes the algorithm slower
+                 */
+                if (!BN_usub(B, B, A))
+                    goto err;
+            } else {
+                /*  sign*(X + Y)*a == A - B  (mod |n|) */
+                if (!BN_uadd(Y, Y, X))
+                    goto err;
+                /*
+                 * as above, BN_mod_add_quick(Y, Y, X, n) would slow things
+                 * down
+                 */
+                if (!BN_usub(A, A, B))
+                    goto err;
+            }
+        }
+    } else {
+        /* general inversion algorithm */
+
+        while (!BN_is_zero(B)) {
+            BIGNUM *tmp;
+
+            /*-
+             *      0 < B < A,
+             * (*) -sign*X*a  ==  B   (mod |n|),
+             *      sign*Y*a  ==  A   (mod |n|)
+             */
+
+            /* (D, M) := (A/B, A%B) ... */
+            if (BN_num_bits(A) == BN_num_bits(B)) {
+                if (!BN_one(D))
+                    goto err;
+                if (!BN_sub(M, A, B))
+                    goto err;
+            } else if (BN_num_bits(A) == BN_num_bits(B) + 1) {
+                /* A/B is 1, 2, or 3 */
+                if (!BN_lshift1(T, B))
+                    goto err;
+                if (BN_ucmp(A, T) < 0) {
+                    /* A < 2*B, so D=1 */
+                    if (!BN_one(D))
+                        goto err;
+                    if (!BN_sub(M, A, B))
+                        goto err;
+                } else {
+                    /* A >= 2*B, so D=2 or D=3 */
+                    if (!BN_sub(M, A, T))
+                        goto err;
+                    if (!BN_add(D, T, B))
+                        goto err; /* use D (:= 3*B) as temp */
+                    if (BN_ucmp(A, D) < 0) {
+                        /* A < 3*B, so D=2 */
+                        if (!BN_set_word(D, 2))
+                            goto err;
+                        /*
+                         * M (= A - 2*B) already has the correct value
+                         */
+                    } else {
+                        /* only D=3 remains */
+                        if (!BN_set_word(D, 3))
+                            goto err;
+                        /*
+                         * currently M = A - 2*B, but we need M = A - 3*B
+                         */
+                        if (!BN_sub(M, M, B))
+                            goto err;
+                    }
+                }
+            } else {
+                if (!BN_div(D, M, A, B, ctx))
+                    goto err;
+            }
+
+            /*-
+             * Now
+             *      A = D*B + M;
+             * thus we have
+             * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
+             */
+
+            tmp = A;            /* keep the BIGNUM object, the value does not
+                                 * matter */
+
+            /* (A, B) := (B, A mod B) ... */
+            A = B;
+            B = M;
+            /* ... so we have  0 <= B < A  again */
+
+            /*-
+             * Since the former  M  is now  B  and the former  B  is now  A,
+             * (**) translates into
+             *       sign*Y*a  ==  D*A + B    (mod |n|),
+             * i.e.
+             *       sign*Y*a - D*A  ==  B    (mod |n|).
+             * Similarly, (*) translates into
+             *      -sign*X*a  ==  A          (mod |n|).
+             *
+             * Thus,
+             *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
+             * i.e.
+             *        sign*(Y + D*X)*a  ==  B  (mod |n|).
+             *
+             * So if we set  (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
+             *      -sign*X*a  ==  B   (mod |n|),
+             *       sign*Y*a  ==  A   (mod |n|).
+             * Note that  X  and  Y  stay non-negative all the time.
+             */
+
+            /*
+             * most of the time D is very small, so we can optimize tmp :=
+             * D*X+Y
+             */
+            if (BN_is_one(D)) {
+                if (!BN_add(tmp, X, Y))
+                    goto err;
+            } else {
+                if (BN_is_word(D, 2)) {
+                    if (!BN_lshift1(tmp, X))
+                        goto err;
+                } else if (BN_is_word(D, 4)) {
+                    if (!BN_lshift(tmp, X, 2))
+                        goto err;
+                } else if (D->top == 1) {
+                    if (!BN_copy(tmp, X))
+                        goto err;
+                    if (!BN_mul_word(tmp, D->d[0]))
+                        goto err;
+                } else {
+                    if (!BN_mul(tmp, D, X, ctx))
+                        goto err;
+                }
+                if (!BN_add(tmp, tmp, Y))
+                    goto err;
+            }
+
+            M = Y;              /* keep the BIGNUM object, the value does not
+                                 * matter */
+            Y = X;
+            X = tmp;
+            sign = -sign;
+        }
+    }
+
+    /*-
+     * The while loop (Euclid's algorithm) ends when
+     *      A == gcd(a,n);
+     * we have
+     *       sign*Y*a  ==  A  (mod |n|),
+     * where  Y  is non-negative.
+     */
+
+    if (sign < 0) {
+        if (!BN_sub(Y, n, Y))
+            goto err;
+    }
+    /* Now  Y*a  ==  A  (mod |n|).  */
+
+    if (BN_is_one(A)) {
+        /* Y*a == 1  (mod |n|) */
+        if (!Y->neg && BN_ucmp(Y, n) < 0) {
+            if (!BN_copy(R, Y))
+                goto err;
+        } else {
+            if (!BN_nnmod(R, Y, n, ctx))
+                goto err;
+        }
+    } else {
+        if (pnoinv)
+            *pnoinv = 1;
+        goto err;
+    }
+    ret = R;
+ err:
+    if ((ret == NULL) && (in == NULL))
+        BN_free(R);
+    BN_CTX_end(ctx);
+    bn_check_top(ret);
+    return (ret);
+}
+
+/*
+ * BN_mod_inverse_no_branch is a special version of BN_mod_inverse. It does
+ * not contain branches that may leak sensitive information.
+ */
+static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
+                                        const BIGNUM *a, const BIGNUM *n,
+                                        BN_CTX *ctx)
+{
+    BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
+    BIGNUM *ret = NULL;
+    int sign;
+
+    bn_check_top(a);
+    bn_check_top(n);
+
+    BN_CTX_start(ctx);
+    A = BN_CTX_get(ctx);
+    B = BN_CTX_get(ctx);
+    X = BN_CTX_get(ctx);
+    D = BN_CTX_get(ctx);
+    M = BN_CTX_get(ctx);
+    Y = BN_CTX_get(ctx);
+    T = BN_CTX_get(ctx);
+    if (T == NULL)
+        goto err;
+
+    if (in == NULL)
+        R = BN_new();
+    else
+        R = in;
+    if (R == NULL)
+        goto err;
+
+    BN_one(X);
+    BN_zero(Y);
+    if (BN_copy(B, a) == NULL)
+        goto err;
+    if (BN_copy(A, n) == NULL)
+        goto err;
+    A->neg = 0;
+
+    if (B->neg || (BN_ucmp(B, A) >= 0)) {
+        /*
+         * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
+         * BN_div_no_branch will be called eventually.
+         */
+         {
+            BIGNUM local_B;
+            bn_init(&local_B);
+            BN_with_flags(&local_B, B, BN_FLG_CONSTTIME);
+            if (!BN_nnmod(B, &local_B, A, ctx))
+                goto err;
+            /* Ensure local_B goes out of scope before any further use of B */
+        }
+    }
+    sign = -1;
+    /*-
+     * From  B = a mod |n|,  A = |n|  it follows that
+     *
+     *      0 <= B < A,
+     *     -sign*X*a  ==  B   (mod |n|),
+     *      sign*Y*a  ==  A   (mod |n|).
+     */
+
+    while (!BN_is_zero(B)) {
+        BIGNUM *tmp;
+
+        /*-
+         *      0 < B < A,
+         * (*) -sign*X*a  ==  B   (mod |n|),
+         *      sign*Y*a  ==  A   (mod |n|)
+         */
+
+        /*
+         * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
+         * BN_div_no_branch will be called eventually.
+         */
+        {
+            BIGNUM local_A;
+            bn_init(&local_A);
+            BN_with_flags(&local_A, A, BN_FLG_CONSTTIME);
+
+            /* (D, M) := (A/B, A%B) ... */
+            if (!BN_div(D, M, &local_A, B, ctx))
+                goto err;
+            /* Ensure local_A goes out of scope before any further use of A */
+        }
+
+        /*-
+         * Now
+         *      A = D*B + M;
+         * thus we have
+         * (**)  sign*Y*a  ==  D*B + M   (mod |n|).
+         */
+
+        tmp = A;                /* keep the BIGNUM object, the value does not
+                                 * matter */
+
+        /* (A, B) := (B, A mod B) ... */
+        A = B;
+        B = M;
+        /* ... so we have  0 <= B < A  again */
+
+        /*-
+         * Since the former  M  is now  B  and the former  B  is now  A,
+         * (**) translates into
+         *       sign*Y*a  ==  D*A + B    (mod |n|),
+         * i.e.
+         *       sign*Y*a - D*A  ==  B    (mod |n|).
+         * Similarly, (*) translates into
+         *      -sign*X*a  ==  A          (mod |n|).
+         *
+         * Thus,
+         *   sign*Y*a + D*sign*X*a  ==  B  (mod |n|),
+         * i.e.
+         *        sign*(Y + D*X)*a  ==  B  (mod |n|).
+         *
+         * So if we set  (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at
+         *      -sign*X*a  ==  B   (mod |n|),
+         *       sign*Y*a  ==  A   (mod |n|).
+         * Note that  X  and  Y  stay non-negative all the time.
+         */
+
+        if (!BN_mul(tmp, D, X, ctx))
+            goto err;
+        if (!BN_add(tmp, tmp, Y))
+            goto err;
+
+        M = Y;                  /* keep the BIGNUM object, the value does not
+                                 * matter */
+        Y = X;
+        X = tmp;
+        sign = -sign;
+    }
+
+    /*-
+     * The while loop (Euclid's algorithm) ends when
+     *      A == gcd(a,n);
+     * we have
+     *       sign*Y*a  ==  A  (mod |n|),
+     * where  Y  is non-negative.
+     */
+
+    if (sign < 0) {
+        if (!BN_sub(Y, n, Y))
+            goto err;
+    }
+    /* Now  Y*a  ==  A  (mod |n|).  */
+
+    if (BN_is_one(A)) {
+        /* Y*a == 1  (mod |n|) */
+        if (!Y->neg && BN_ucmp(Y, n) < 0) {
+            if (!BN_copy(R, Y))
+                goto err;
+        } else {
+            if (!BN_nnmod(R, Y, n, ctx))
+                goto err;
+        }
+    } else {
+        BNerr(BN_F_BN_MOD_INVERSE_NO_BRANCH, BN_R_NO_INVERSE);
+        goto err;
+    }
+    ret = R;
+ err:
+    if ((ret == NULL) && (in == NULL))
+        BN_free(R);
+    BN_CTX_end(ctx);
+    bn_check_top(ret);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_gf2m.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_gf2m.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_gf2m.c	(revision 331)
@@ -0,0 +1,1224 @@
+/*
+ * Copyright 2002-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ */
+
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include "bn_lcl.h"
+
+#ifndef OPENSSL_NO_EC2M
+
+/*
+ * Maximum number of iterations before BN_GF2m_mod_solve_quad_arr should
+ * fail.
+ */
+# define MAX_ITERATIONS 50
+
+static const BN_ULONG SQR_tb[16] = { 0, 1, 4, 5, 16, 17, 20, 21,
+    64, 65, 68, 69, 80, 81, 84, 85
+};
+
+/* Platform-specific macros to accelerate squaring. */
+# if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+#  define SQR1(w) \
+    SQR_tb[(w) >> 60 & 0xF] << 56 | SQR_tb[(w) >> 56 & 0xF] << 48 | \
+    SQR_tb[(w) >> 52 & 0xF] << 40 | SQR_tb[(w) >> 48 & 0xF] << 32 | \
+    SQR_tb[(w) >> 44 & 0xF] << 24 | SQR_tb[(w) >> 40 & 0xF] << 16 | \
+    SQR_tb[(w) >> 36 & 0xF] <<  8 | SQR_tb[(w) >> 32 & 0xF]
+#  define SQR0(w) \
+    SQR_tb[(w) >> 28 & 0xF] << 56 | SQR_tb[(w) >> 24 & 0xF] << 48 | \
+    SQR_tb[(w) >> 20 & 0xF] << 40 | SQR_tb[(w) >> 16 & 0xF] << 32 | \
+    SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >>  8 & 0xF] << 16 | \
+    SQR_tb[(w) >>  4 & 0xF] <<  8 | SQR_tb[(w)       & 0xF]
+# endif
+# ifdef THIRTY_TWO_BIT
+#  define SQR1(w) \
+    SQR_tb[(w) >> 28 & 0xF] << 24 | SQR_tb[(w) >> 24 & 0xF] << 16 | \
+    SQR_tb[(w) >> 20 & 0xF] <<  8 | SQR_tb[(w) >> 16 & 0xF]
+#  define SQR0(w) \
+    SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >>  8 & 0xF] << 16 | \
+    SQR_tb[(w) >>  4 & 0xF] <<  8 | SQR_tb[(w)       & 0xF]
+# endif
+
+# if !defined(OPENSSL_BN_ASM_GF2m)
+/*
+ * Product of two polynomials a, b each with degree < BN_BITS2 - 1, result is
+ * a polynomial r with degree < 2 * BN_BITS - 1 The caller MUST ensure that
+ * the variables have the right amount of space allocated.
+ */
+#  ifdef THIRTY_TWO_BIT
+static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a,
+                            const BN_ULONG b)
+{
+    register BN_ULONG h, l, s;
+    BN_ULONG tab[8], top2b = a >> 30;
+    register BN_ULONG a1, a2, a4;
+
+    a1 = a & (0x3FFFFFFF);
+    a2 = a1 << 1;
+    a4 = a2 << 1;
+
+    tab[0] = 0;
+    tab[1] = a1;
+    tab[2] = a2;
+    tab[3] = a1 ^ a2;
+    tab[4] = a4;
+    tab[5] = a1 ^ a4;
+    tab[6] = a2 ^ a4;
+    tab[7] = a1 ^ a2 ^ a4;
+
+    s = tab[b & 0x7];
+    l = s;
+    s = tab[b >> 3 & 0x7];
+    l ^= s << 3;
+    h = s >> 29;
+    s = tab[b >> 6 & 0x7];
+    l ^= s << 6;
+    h ^= s >> 26;
+    s = tab[b >> 9 & 0x7];
+    l ^= s << 9;
+    h ^= s >> 23;
+    s = tab[b >> 12 & 0x7];
+    l ^= s << 12;
+    h ^= s >> 20;
+    s = tab[b >> 15 & 0x7];
+    l ^= s << 15;
+    h ^= s >> 17;
+    s = tab[b >> 18 & 0x7];
+    l ^= s << 18;
+    h ^= s >> 14;
+    s = tab[b >> 21 & 0x7];
+    l ^= s << 21;
+    h ^= s >> 11;
+    s = tab[b >> 24 & 0x7];
+    l ^= s << 24;
+    h ^= s >> 8;
+    s = tab[b >> 27 & 0x7];
+    l ^= s << 27;
+    h ^= s >> 5;
+    s = tab[b >> 30];
+    l ^= s << 30;
+    h ^= s >> 2;
+
+    /* compensate for the top two bits of a */
+
+    if (top2b & 01) {
+        l ^= b << 30;
+        h ^= b >> 2;
+    }
+    if (top2b & 02) {
+        l ^= b << 31;
+        h ^= b >> 1;
+    }
+
+    *r1 = h;
+    *r0 = l;
+}
+#  endif
+#  if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a,
+                            const BN_ULONG b)
+{
+    register BN_ULONG h, l, s;
+    BN_ULONG tab[16], top3b = a >> 61;
+    register BN_ULONG a1, a2, a4, a8;
+
+    a1 = a & (0x1FFFFFFFFFFFFFFFULL);
+    a2 = a1 << 1;
+    a4 = a2 << 1;
+    a8 = a4 << 1;
+
+    tab[0] = 0;
+    tab[1] = a1;
+    tab[2] = a2;
+    tab[3] = a1 ^ a2;
+    tab[4] = a4;
+    tab[5] = a1 ^ a4;
+    tab[6] = a2 ^ a4;
+    tab[7] = a1 ^ a2 ^ a4;
+    tab[8] = a8;
+    tab[9] = a1 ^ a8;
+    tab[10] = a2 ^ a8;
+    tab[11] = a1 ^ a2 ^ a8;
+    tab[12] = a4 ^ a8;
+    tab[13] = a1 ^ a4 ^ a8;
+    tab[14] = a2 ^ a4 ^ a8;
+    tab[15] = a1 ^ a2 ^ a4 ^ a8;
+
+    s = tab[b & 0xF];
+    l = s;
+    s = tab[b >> 4 & 0xF];
+    l ^= s << 4;
+    h = s >> 60;
+    s = tab[b >> 8 & 0xF];
+    l ^= s << 8;
+    h ^= s >> 56;
+    s = tab[b >> 12 & 0xF];
+    l ^= s << 12;
+    h ^= s >> 52;
+    s = tab[b >> 16 & 0xF];
+    l ^= s << 16;
+    h ^= s >> 48;
+    s = tab[b >> 20 & 0xF];
+    l ^= s << 20;
+    h ^= s >> 44;
+    s = tab[b >> 24 & 0xF];
+    l ^= s << 24;
+    h ^= s >> 40;
+    s = tab[b >> 28 & 0xF];
+    l ^= s << 28;
+    h ^= s >> 36;
+    s = tab[b >> 32 & 0xF];
+    l ^= s << 32;
+    h ^= s >> 32;
+    s = tab[b >> 36 & 0xF];
+    l ^= s << 36;
+    h ^= s >> 28;
+    s = tab[b >> 40 & 0xF];
+    l ^= s << 40;
+    h ^= s >> 24;
+    s = tab[b >> 44 & 0xF];
+    l ^= s << 44;
+    h ^= s >> 20;
+    s = tab[b >> 48 & 0xF];
+    l ^= s << 48;
+    h ^= s >> 16;
+    s = tab[b >> 52 & 0xF];
+    l ^= s << 52;
+    h ^= s >> 12;
+    s = tab[b >> 56 & 0xF];
+    l ^= s << 56;
+    h ^= s >> 8;
+    s = tab[b >> 60];
+    l ^= s << 60;
+    h ^= s >> 4;
+
+    /* compensate for the top three bits of a */
+
+    if (top3b & 01) {
+        l ^= b << 61;
+        h ^= b >> 3;
+    }
+    if (top3b & 02) {
+        l ^= b << 62;
+        h ^= b >> 2;
+    }
+    if (top3b & 04) {
+        l ^= b << 63;
+        h ^= b >> 1;
+    }
+
+    *r1 = h;
+    *r0 = l;
+}
+#  endif
+
+/*
+ * Product of two polynomials a, b each with degree < 2 * BN_BITS2 - 1,
+ * result is a polynomial r with degree < 4 * BN_BITS2 - 1 The caller MUST
+ * ensure that the variables have the right amount of space allocated.
+ */
+static void bn_GF2m_mul_2x2(BN_ULONG *r, const BN_ULONG a1, const BN_ULONG a0,
+                            const BN_ULONG b1, const BN_ULONG b0)
+{
+    BN_ULONG m1, m0;
+    /* r[3] = h1, r[2] = h0; r[1] = l1; r[0] = l0 */
+    bn_GF2m_mul_1x1(r + 3, r + 2, a1, b1);
+    bn_GF2m_mul_1x1(r + 1, r, a0, b0);
+    bn_GF2m_mul_1x1(&m1, &m0, a0 ^ a1, b0 ^ b1);
+    /* Correction on m1 ^= l1 ^ h1; m0 ^= l0 ^ h0; */
+    r[2] ^= m1 ^ r[1] ^ r[3];   /* h0 ^= m1 ^ l1 ^ h1; */
+    r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0; /* l1 ^= l0 ^ h0 ^ m0; */
+}
+# else
+void bn_GF2m_mul_2x2(BN_ULONG *r, BN_ULONG a1, BN_ULONG a0, BN_ULONG b1,
+                     BN_ULONG b0);
+# endif
+
+/*
+ * Add polynomials a and b and store result in r; r could be a or b, a and b
+ * could be equal; r is the bitwise XOR of a and b.
+ */
+int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
+{
+    int i;
+    const BIGNUM *at, *bt;
+
+    bn_check_top(a);
+    bn_check_top(b);
+
+    if (a->top < b->top) {
+        at = b;
+        bt = a;
+    } else {
+        at = a;
+        bt = b;
+    }
+
+    if (bn_wexpand(r, at->top) == NULL)
+        return 0;
+
+    for (i = 0; i < bt->top; i++) {
+        r->d[i] = at->d[i] ^ bt->d[i];
+    }
+    for (; i < at->top; i++) {
+        r->d[i] = at->d[i];
+    }
+
+    r->top = at->top;
+    bn_correct_top(r);
+
+    return 1;
+}
+
+/*-
+ * Some functions allow for representation of the irreducible polynomials
+ * as an int[], say p.  The irreducible f(t) is then of the form:
+ *     t^p[0] + t^p[1] + ... + t^p[k]
+ * where m = p[0] > p[1] > ... > p[k] = 0.
+ */
+
+/* Performs modular reduction of a and store result in r.  r could be a. */
+int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[])
+{
+    int j, k;
+    int n, dN, d0, d1;
+    BN_ULONG zz, *z;
+
+    bn_check_top(a);
+
+    if (!p[0]) {
+        /* reduction mod 1 => return 0 */
+        BN_zero(r);
+        return 1;
+    }
+
+    /*
+     * Since the algorithm does reduction in the r value, if a != r, copy the
+     * contents of a into r so we can do reduction in r.
+     */
+    if (a != r) {
+        if (!bn_wexpand(r, a->top))
+            return 0;
+        for (j = 0; j < a->top; j++) {
+            r->d[j] = a->d[j];
+        }
+        r->top = a->top;
+    }
+    z = r->d;
+
+    /* start reduction */
+    dN = p[0] / BN_BITS2;
+    for (j = r->top - 1; j > dN;) {
+        zz = z[j];
+        if (z[j] == 0) {
+            j--;
+            continue;
+        }
+        z[j] = 0;
+
+        for (k = 1; p[k] != 0; k++) {
+            /* reducing component t^p[k] */
+            n = p[0] - p[k];
+            d0 = n % BN_BITS2;
+            d1 = BN_BITS2 - d0;
+            n /= BN_BITS2;
+            z[j - n] ^= (zz >> d0);
+            if (d0)
+                z[j - n - 1] ^= (zz << d1);
+        }
+
+        /* reducing component t^0 */
+        n = dN;
+        d0 = p[0] % BN_BITS2;
+        d1 = BN_BITS2 - d0;
+        z[j - n] ^= (zz >> d0);
+        if (d0)
+            z[j - n - 1] ^= (zz << d1);
+    }
+
+    /* final round of reduction */
+    while (j == dN) {
+
+        d0 = p[0] % BN_BITS2;
+        zz = z[dN] >> d0;
+        if (zz == 0)
+            break;
+        d1 = BN_BITS2 - d0;
+
+        /* clear up the top d1 bits */
+        if (d0)
+            z[dN] = (z[dN] << d1) >> d1;
+        else
+            z[dN] = 0;
+        z[0] ^= zz;             /* reduction t^0 component */
+
+        for (k = 1; p[k] != 0; k++) {
+            BN_ULONG tmp_ulong;
+
+            /* reducing component t^p[k] */
+            n = p[k] / BN_BITS2;
+            d0 = p[k] % BN_BITS2;
+            d1 = BN_BITS2 - d0;
+            z[n] ^= (zz << d0);
+            if (d0 && (tmp_ulong = zz >> d1))
+                z[n + 1] ^= tmp_ulong;
+        }
+
+    }
+
+    bn_correct_top(r);
+    return 1;
+}
+
+/*
+ * Performs modular reduction of a by p and store result in r.  r could be a.
+ * This function calls down to the BN_GF2m_mod_arr implementation; this wrapper
+ * function is only provided for convenience; for best performance, use the
+ * BN_GF2m_mod_arr function.
+ */
+int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p)
+{
+    int ret = 0;
+    int arr[6];
+    bn_check_top(a);
+    bn_check_top(p);
+    ret = BN_GF2m_poly2arr(p, arr, OSSL_NELEM(arr));
+    if (!ret || ret > (int)OSSL_NELEM(arr)) {
+        BNerr(BN_F_BN_GF2M_MOD, BN_R_INVALID_LENGTH);
+        return 0;
+    }
+    ret = BN_GF2m_mod_arr(r, a, arr);
+    bn_check_top(r);
+    return ret;
+}
+
+/*
+ * Compute the product of two polynomials a and b, reduce modulo p, and store
+ * the result in r.  r could be a or b; a could be b.
+ */
+int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                        const int p[], BN_CTX *ctx)
+{
+    int zlen, i, j, k, ret = 0;
+    BIGNUM *s;
+    BN_ULONG x1, x0, y1, y0, zz[4];
+
+    bn_check_top(a);
+    bn_check_top(b);
+
+    if (a == b) {
+        return BN_GF2m_mod_sqr_arr(r, a, p, ctx);
+    }
+
+    BN_CTX_start(ctx);
+    if ((s = BN_CTX_get(ctx)) == NULL)
+        goto err;
+
+    zlen = a->top + b->top + 4;
+    if (!bn_wexpand(s, zlen))
+        goto err;
+    s->top = zlen;
+
+    for (i = 0; i < zlen; i++)
+        s->d[i] = 0;
+
+    for (j = 0; j < b->top; j += 2) {
+        y0 = b->d[j];
+        y1 = ((j + 1) == b->top) ? 0 : b->d[j + 1];
+        for (i = 0; i < a->top; i += 2) {
+            x0 = a->d[i];
+            x1 = ((i + 1) == a->top) ? 0 : a->d[i + 1];
+            bn_GF2m_mul_2x2(zz, x1, x0, y1, y0);
+            for (k = 0; k < 4; k++)
+                s->d[i + j + k] ^= zz[k];
+        }
+    }
+
+    bn_correct_top(s);
+    if (BN_GF2m_mod_arr(r, s, p))
+        ret = 1;
+    bn_check_top(r);
+
+ err:
+    BN_CTX_end(ctx);
+    return ret;
+}
+
+/*
+ * Compute the product of two polynomials a and b, reduce modulo p, and store
+ * the result in r.  r could be a or b; a could equal b. This function calls
+ * down to the BN_GF2m_mod_mul_arr implementation; this wrapper function is
+ * only provided for convenience; for best performance, use the
+ * BN_GF2m_mod_mul_arr function.
+ */
+int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                    const BIGNUM *p, BN_CTX *ctx)
+{
+    int ret = 0;
+    const int max = BN_num_bits(p) + 1;
+    int *arr = NULL;
+    bn_check_top(a);
+    bn_check_top(b);
+    bn_check_top(p);
+    if ((arr = OPENSSL_malloc(sizeof(*arr) * max)) == NULL)
+        goto err;
+    ret = BN_GF2m_poly2arr(p, arr, max);
+    if (!ret || ret > max) {
+        BNerr(BN_F_BN_GF2M_MOD_MUL, BN_R_INVALID_LENGTH);
+        goto err;
+    }
+    ret = BN_GF2m_mod_mul_arr(r, a, b, arr, ctx);
+    bn_check_top(r);
+ err:
+    OPENSSL_free(arr);
+    return ret;
+}
+
+/* Square a, reduce the result mod p, and store it in a.  r could be a. */
+int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[],
+                        BN_CTX *ctx)
+{
+    int i, ret = 0;
+    BIGNUM *s;
+
+    bn_check_top(a);
+    BN_CTX_start(ctx);
+    if ((s = BN_CTX_get(ctx)) == NULL)
+        goto err;
+    if (!bn_wexpand(s, 2 * a->top))
+        goto err;
+
+    for (i = a->top - 1; i >= 0; i--) {
+        s->d[2 * i + 1] = SQR1(a->d[i]);
+        s->d[2 * i] = SQR0(a->d[i]);
+    }
+
+    s->top = 2 * a->top;
+    bn_correct_top(s);
+    if (!BN_GF2m_mod_arr(r, s, p))
+        goto err;
+    bn_check_top(r);
+    ret = 1;
+ err:
+    BN_CTX_end(ctx);
+    return ret;
+}
+
+/*
+ * Square a, reduce the result mod p, and store it in a.  r could be a. This
+ * function calls down to the BN_GF2m_mod_sqr_arr implementation; this
+ * wrapper function is only provided for convenience; for best performance,
+ * use the BN_GF2m_mod_sqr_arr function.
+ */
+int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+{
+    int ret = 0;
+    const int max = BN_num_bits(p) + 1;
+    int *arr = NULL;
+
+    bn_check_top(a);
+    bn_check_top(p);
+    if ((arr = OPENSSL_malloc(sizeof(*arr) * max)) == NULL)
+        goto err;
+    ret = BN_GF2m_poly2arr(p, arr, max);
+    if (!ret || ret > max) {
+        BNerr(BN_F_BN_GF2M_MOD_SQR, BN_R_INVALID_LENGTH);
+        goto err;
+    }
+    ret = BN_GF2m_mod_sqr_arr(r, a, arr, ctx);
+    bn_check_top(r);
+ err:
+    OPENSSL_free(arr);
+    return ret;
+}
+
+/*
+ * Invert a, reduce modulo p, and store the result in r. r could be a. Uses
+ * Modified Almost Inverse Algorithm (Algorithm 10) from Hankerson, D.,
+ * Hernandez, J.L., and Menezes, A.  "Software Implementation of Elliptic
+ * Curve Cryptography Over Binary Fields".
+ */
+int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+{
+    BIGNUM *b, *c = NULL, *u = NULL, *v = NULL, *tmp;
+    int ret = 0;
+
+    bn_check_top(a);
+    bn_check_top(p);
+
+    BN_CTX_start(ctx);
+
+    if ((b = BN_CTX_get(ctx)) == NULL)
+        goto err;
+    if ((c = BN_CTX_get(ctx)) == NULL)
+        goto err;
+    if ((u = BN_CTX_get(ctx)) == NULL)
+        goto err;
+    if ((v = BN_CTX_get(ctx)) == NULL)
+        goto err;
+
+    if (!BN_GF2m_mod(u, a, p))
+        goto err;
+    if (BN_is_zero(u))
+        goto err;
+
+    if (!BN_copy(v, p))
+        goto err;
+# if 0
+    if (!BN_one(b))
+        goto err;
+
+    while (1) {
+        while (!BN_is_odd(u)) {
+            if (BN_is_zero(u))
+                goto err;
+            if (!BN_rshift1(u, u))
+                goto err;
+            if (BN_is_odd(b)) {
+                if (!BN_GF2m_add(b, b, p))
+                    goto err;
+            }
+            if (!BN_rshift1(b, b))
+                goto err;
+        }
+
+        if (BN_abs_is_word(u, 1))
+            break;
+
+        if (BN_num_bits(u) < BN_num_bits(v)) {
+            tmp = u;
+            u = v;
+            v = tmp;
+            tmp = b;
+            b = c;
+            c = tmp;
+        }
+
+        if (!BN_GF2m_add(u, u, v))
+            goto err;
+        if (!BN_GF2m_add(b, b, c))
+            goto err;
+    }
+# else
+    {
+        int i;
+        int ubits = BN_num_bits(u);
+        int vbits = BN_num_bits(v); /* v is copy of p */
+        int top = p->top;
+        BN_ULONG *udp, *bdp, *vdp, *cdp;
+
+        if (!bn_wexpand(u, top))
+            goto err;
+        udp = u->d;
+        for (i = u->top; i < top; i++)
+            udp[i] = 0;
+        u->top = top;
+        if (!bn_wexpand(b, top))
+          goto err;
+        bdp = b->d;
+        bdp[0] = 1;
+        for (i = 1; i < top; i++)
+            bdp[i] = 0;
+        b->top = top;
+        if (!bn_wexpand(c, top))
+          goto err;
+        cdp = c->d;
+        for (i = 0; i < top; i++)
+            cdp[i] = 0;
+        c->top = top;
+        vdp = v->d;             /* It pays off to "cache" *->d pointers,
+                                 * because it allows optimizer to be more
+                                 * aggressive. But we don't have to "cache"
+                                 * p->d, because *p is declared 'const'... */
+        while (1) {
+            while (ubits && !(udp[0] & 1)) {
+                BN_ULONG u0, u1, b0, b1, mask;
+
+                u0 = udp[0];
+                b0 = bdp[0];
+                mask = (BN_ULONG)0 - (b0 & 1);
+                b0 ^= p->d[0] & mask;
+                for (i = 0; i < top - 1; i++) {
+                    u1 = udp[i + 1];
+                    udp[i] = ((u0 >> 1) | (u1 << (BN_BITS2 - 1))) & BN_MASK2;
+                    u0 = u1;
+                    b1 = bdp[i + 1] ^ (p->d[i + 1] & mask);
+                    bdp[i] = ((b0 >> 1) | (b1 << (BN_BITS2 - 1))) & BN_MASK2;
+                    b0 = b1;
+                }
+                udp[i] = u0 >> 1;
+                bdp[i] = b0 >> 1;
+                ubits--;
+            }
+
+            if (ubits <= BN_BITS2) {
+                if (udp[0] == 0) /* poly was reducible */
+                    goto err;
+                if (udp[0] == 1)
+                    break;
+            }
+
+            if (ubits < vbits) {
+                i = ubits;
+                ubits = vbits;
+                vbits = i;
+                tmp = u;
+                u = v;
+                v = tmp;
+                tmp = b;
+                b = c;
+                c = tmp;
+                udp = vdp;
+                vdp = v->d;
+                bdp = cdp;
+                cdp = c->d;
+            }
+            for (i = 0; i < top; i++) {
+                udp[i] ^= vdp[i];
+                bdp[i] ^= cdp[i];
+            }
+            if (ubits == vbits) {
+                BN_ULONG ul;
+                int utop = (ubits - 1) / BN_BITS2;
+
+                while ((ul = udp[utop]) == 0 && utop)
+                    utop--;
+                ubits = utop * BN_BITS2 + BN_num_bits_word(ul);
+            }
+        }
+        bn_correct_top(b);
+    }
+# endif
+
+    if (!BN_copy(r, b))
+        goto err;
+    bn_check_top(r);
+    ret = 1;
+
+ err:
+# ifdef BN_DEBUG                /* BN_CTX_end would complain about the
+                                 * expanded form */
+    bn_correct_top(c);
+    bn_correct_top(u);
+    bn_correct_top(v);
+# endif
+    BN_CTX_end(ctx);
+    return ret;
+}
+
+/*
+ * Invert xx, reduce modulo p, and store the result in r. r could be xx.
+ * This function calls down to the BN_GF2m_mod_inv implementation; this
+ * wrapper function is only provided for convenience; for best performance,
+ * use the BN_GF2m_mod_inv function.
+ */
+int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const int p[],
+                        BN_CTX *ctx)
+{
+    BIGNUM *field;
+    int ret = 0;
+
+    bn_check_top(xx);
+    BN_CTX_start(ctx);
+    if ((field = BN_CTX_get(ctx)) == NULL)
+        goto err;
+    if (!BN_GF2m_arr2poly(p, field))
+        goto err;
+
+    ret = BN_GF2m_mod_inv(r, xx, field, ctx);
+    bn_check_top(r);
+
+ err:
+    BN_CTX_end(ctx);
+    return ret;
+}
+
+# ifndef OPENSSL_SUN_GF2M_DIV
+/*
+ * Divide y by x, reduce modulo p, and store the result in r. r could be x
+ * or y, x could equal y.
+ */
+int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x,
+                    const BIGNUM *p, BN_CTX *ctx)
+{
+    BIGNUM *xinv = NULL;
+    int ret = 0;
+
+    bn_check_top(y);
+    bn_check_top(x);
+    bn_check_top(p);
+
+    BN_CTX_start(ctx);
+    xinv = BN_CTX_get(ctx);
+    if (xinv == NULL)
+        goto err;
+
+    if (!BN_GF2m_mod_inv(xinv, x, p, ctx))
+        goto err;
+    if (!BN_GF2m_mod_mul(r, y, xinv, p, ctx))
+        goto err;
+    bn_check_top(r);
+    ret = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    return ret;
+}
+# else
+/*
+ * Divide y by x, reduce modulo p, and store the result in r. r could be x
+ * or y, x could equal y. Uses algorithm Modular_Division_GF(2^m) from
+ * Chang-Shantz, S.  "From Euclid's GCD to Montgomery Multiplication to the
+ * Great Divide".
+ */
+int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x,
+                    const BIGNUM *p, BN_CTX *ctx)
+{
+    BIGNUM *a, *b, *u, *v;
+    int ret = 0;
+
+    bn_check_top(y);
+    bn_check_top(x);
+    bn_check_top(p);
+
+    BN_CTX_start(ctx);
+
+    a = BN_CTX_get(ctx);
+    b = BN_CTX_get(ctx);
+    u = BN_CTX_get(ctx);
+    v = BN_CTX_get(ctx);
+    if (v == NULL)
+        goto err;
+
+    /* reduce x and y mod p */
+    if (!BN_GF2m_mod(u, y, p))
+        goto err;
+    if (!BN_GF2m_mod(a, x, p))
+        goto err;
+    if (!BN_copy(b, p))
+        goto err;
+
+    while (!BN_is_odd(a)) {
+        if (!BN_rshift1(a, a))
+            goto err;
+        if (BN_is_odd(u))
+            if (!BN_GF2m_add(u, u, p))
+                goto err;
+        if (!BN_rshift1(u, u))
+            goto err;
+    }
+
+    do {
+        if (BN_GF2m_cmp(b, a) > 0) {
+            if (!BN_GF2m_add(b, b, a))
+                goto err;
+            if (!BN_GF2m_add(v, v, u))
+                goto err;
+            do {
+                if (!BN_rshift1(b, b))
+                    goto err;
+                if (BN_is_odd(v))
+                    if (!BN_GF2m_add(v, v, p))
+                        goto err;
+                if (!BN_rshift1(v, v))
+                    goto err;
+            } while (!BN_is_odd(b));
+        } else if (BN_abs_is_word(a, 1))
+            break;
+        else {
+            if (!BN_GF2m_add(a, a, b))
+                goto err;
+            if (!BN_GF2m_add(u, u, v))
+                goto err;
+            do {
+                if (!BN_rshift1(a, a))
+                    goto err;
+                if (BN_is_odd(u))
+                    if (!BN_GF2m_add(u, u, p))
+                        goto err;
+                if (!BN_rshift1(u, u))
+                    goto err;
+            } while (!BN_is_odd(a));
+        }
+    } while (1);
+
+    if (!BN_copy(r, u))
+        goto err;
+    bn_check_top(r);
+    ret = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    return ret;
+}
+# endif
+
+/*
+ * Divide yy by xx, reduce modulo p, and store the result in r. r could be xx
+ * * or yy, xx could equal yy. This function calls down to the
+ * BN_GF2m_mod_div implementation; this wrapper function is only provided for
+ * convenience; for best performance, use the BN_GF2m_mod_div function.
+ */
+int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx,
+                        const int p[], BN_CTX *ctx)
+{
+    BIGNUM *field;
+    int ret = 0;
+
+    bn_check_top(yy);
+    bn_check_top(xx);
+
+    BN_CTX_start(ctx);
+    if ((field = BN_CTX_get(ctx)) == NULL)
+        goto err;
+    if (!BN_GF2m_arr2poly(p, field))
+        goto err;
+
+    ret = BN_GF2m_mod_div(r, yy, xx, field, ctx);
+    bn_check_top(r);
+
+ err:
+    BN_CTX_end(ctx);
+    return ret;
+}
+
+/*
+ * Compute the bth power of a, reduce modulo p, and store the result in r.  r
+ * could be a. Uses simple square-and-multiply algorithm A.5.1 from IEEE
+ * P1363.
+ */
+int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                        const int p[], BN_CTX *ctx)
+{
+    int ret = 0, i, n;
+    BIGNUM *u;
+
+    bn_check_top(a);
+    bn_check_top(b);
+
+    if (BN_is_zero(b))
+        return (BN_one(r));
+
+    if (BN_abs_is_word(b, 1))
+        return (BN_copy(r, a) != NULL);
+
+    BN_CTX_start(ctx);
+    if ((u = BN_CTX_get(ctx)) == NULL)
+        goto err;
+
+    if (!BN_GF2m_mod_arr(u, a, p))
+        goto err;
+
+    n = BN_num_bits(b) - 1;
+    for (i = n - 1; i >= 0; i--) {
+        if (!BN_GF2m_mod_sqr_arr(u, u, p, ctx))
+            goto err;
+        if (BN_is_bit_set(b, i)) {
+            if (!BN_GF2m_mod_mul_arr(u, u, a, p, ctx))
+                goto err;
+        }
+    }
+    if (!BN_copy(r, u))
+        goto err;
+    bn_check_top(r);
+    ret = 1;
+ err:
+    BN_CTX_end(ctx);
+    return ret;
+}
+
+/*
+ * Compute the bth power of a, reduce modulo p, and store the result in r.  r
+ * could be a. This function calls down to the BN_GF2m_mod_exp_arr
+ * implementation; this wrapper function is only provided for convenience;
+ * for best performance, use the BN_GF2m_mod_exp_arr function.
+ */
+int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                    const BIGNUM *p, BN_CTX *ctx)
+{
+    int ret = 0;
+    const int max = BN_num_bits(p) + 1;
+    int *arr = NULL;
+    bn_check_top(a);
+    bn_check_top(b);
+    bn_check_top(p);
+    if ((arr = OPENSSL_malloc(sizeof(*arr) * max)) == NULL)
+        goto err;
+    ret = BN_GF2m_poly2arr(p, arr, max);
+    if (!ret || ret > max) {
+        BNerr(BN_F_BN_GF2M_MOD_EXP, BN_R_INVALID_LENGTH);
+        goto err;
+    }
+    ret = BN_GF2m_mod_exp_arr(r, a, b, arr, ctx);
+    bn_check_top(r);
+ err:
+    OPENSSL_free(arr);
+    return ret;
+}
+
+/*
+ * Compute the square root of a, reduce modulo p, and store the result in r.
+ * r could be a. Uses exponentiation as in algorithm A.4.1 from IEEE P1363.
+ */
+int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const int p[],
+                         BN_CTX *ctx)
+{
+    int ret = 0;
+    BIGNUM *u;
+
+    bn_check_top(a);
+
+    if (!p[0]) {
+        /* reduction mod 1 => return 0 */
+        BN_zero(r);
+        return 1;
+    }
+
+    BN_CTX_start(ctx);
+    if ((u = BN_CTX_get(ctx)) == NULL)
+        goto err;
+
+    if (!BN_set_bit(u, p[0] - 1))
+        goto err;
+    ret = BN_GF2m_mod_exp_arr(r, a, u, p, ctx);
+    bn_check_top(r);
+
+ err:
+    BN_CTX_end(ctx);
+    return ret;
+}
+
+/*
+ * Compute the square root of a, reduce modulo p, and store the result in r.
+ * r could be a. This function calls down to the BN_GF2m_mod_sqrt_arr
+ * implementation; this wrapper function is only provided for convenience;
+ * for best performance, use the BN_GF2m_mod_sqrt_arr function.
+ */
+int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+{
+    int ret = 0;
+    const int max = BN_num_bits(p) + 1;
+    int *arr = NULL;
+    bn_check_top(a);
+    bn_check_top(p);
+    if ((arr = OPENSSL_malloc(sizeof(*arr) * max)) == NULL)
+        goto err;
+    ret = BN_GF2m_poly2arr(p, arr, max);
+    if (!ret || ret > max) {
+        BNerr(BN_F_BN_GF2M_MOD_SQRT, BN_R_INVALID_LENGTH);
+        goto err;
+    }
+    ret = BN_GF2m_mod_sqrt_arr(r, a, arr, ctx);
+    bn_check_top(r);
+ err:
+    OPENSSL_free(arr);
+    return ret;
+}
+
+/*
+ * Find r such that r^2 + r = a mod p.  r could be a. If no r exists returns
+ * 0. Uses algorithms A.4.7 and A.4.6 from IEEE P1363.
+ */
+int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const int p[],
+                               BN_CTX *ctx)
+{
+    int ret = 0, count = 0, j;
+    BIGNUM *a, *z, *rho, *w, *w2, *tmp;
+
+    bn_check_top(a_);
+
+    if (!p[0]) {
+        /* reduction mod 1 => return 0 */
+        BN_zero(r);
+        return 1;
+    }
+
+    BN_CTX_start(ctx);
+    a = BN_CTX_get(ctx);
+    z = BN_CTX_get(ctx);
+    w = BN_CTX_get(ctx);
+    if (w == NULL)
+        goto err;
+
+    if (!BN_GF2m_mod_arr(a, a_, p))
+        goto err;
+
+    if (BN_is_zero(a)) {
+        BN_zero(r);
+        ret = 1;
+        goto err;
+    }
+
+    if (p[0] & 0x1) {           /* m is odd */
+        /* compute half-trace of a */
+        if (!BN_copy(z, a))
+            goto err;
+        for (j = 1; j <= (p[0] - 1) / 2; j++) {
+            if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx))
+                goto err;
+            if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx))
+                goto err;
+            if (!BN_GF2m_add(z, z, a))
+                goto err;
+        }
+
+    } else {                    /* m is even */
+
+        rho = BN_CTX_get(ctx);
+        w2 = BN_CTX_get(ctx);
+        tmp = BN_CTX_get(ctx);
+        if (tmp == NULL)
+            goto err;
+        do {
+            if (!BN_rand(rho, p[0], BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
+                goto err;
+            if (!BN_GF2m_mod_arr(rho, rho, p))
+                goto err;
+            BN_zero(z);
+            if (!BN_copy(w, rho))
+                goto err;
+            for (j = 1; j <= p[0] - 1; j++) {
+                if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx))
+                    goto err;
+                if (!BN_GF2m_mod_sqr_arr(w2, w, p, ctx))
+                    goto err;
+                if (!BN_GF2m_mod_mul_arr(tmp, w2, a, p, ctx))
+                    goto err;
+                if (!BN_GF2m_add(z, z, tmp))
+                    goto err;
+                if (!BN_GF2m_add(w, w2, rho))
+                    goto err;
+            }
+            count++;
+        } while (BN_is_zero(w) && (count < MAX_ITERATIONS));
+        if (BN_is_zero(w)) {
+            BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_TOO_MANY_ITERATIONS);
+            goto err;
+        }
+    }
+
+    if (!BN_GF2m_mod_sqr_arr(w, z, p, ctx))
+        goto err;
+    if (!BN_GF2m_add(w, z, w))
+        goto err;
+    if (BN_GF2m_cmp(w, a)) {
+        BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_NO_SOLUTION);
+        goto err;
+    }
+
+    if (!BN_copy(r, z))
+        goto err;
+    bn_check_top(r);
+
+    ret = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    return ret;
+}
+
+/*
+ * Find r such that r^2 + r = a mod p.  r could be a. If no r exists returns
+ * 0. This function calls down to the BN_GF2m_mod_solve_quad_arr
+ * implementation; this wrapper function is only provided for convenience;
+ * for best performance, use the BN_GF2m_mod_solve_quad_arr function.
+ */
+int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                           BN_CTX *ctx)
+{
+    int ret = 0;
+    const int max = BN_num_bits(p) + 1;
+    int *arr = NULL;
+    bn_check_top(a);
+    bn_check_top(p);
+    if ((arr = OPENSSL_malloc(sizeof(*arr) * max)) == NULL)
+        goto err;
+    ret = BN_GF2m_poly2arr(p, arr, max);
+    if (!ret || ret > max) {
+        BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD, BN_R_INVALID_LENGTH);
+        goto err;
+    }
+    ret = BN_GF2m_mod_solve_quad_arr(r, a, arr, ctx);
+    bn_check_top(r);
+ err:
+    OPENSSL_free(arr);
+    return ret;
+}
+
+/*
+ * Convert the bit-string representation of a polynomial ( \sum_{i=0}^n a_i *
+ * x^i) into an array of integers corresponding to the bits with non-zero
+ * coefficient.  Array is terminated with -1. Up to max elements of the array
+ * will be filled.  Return value is total number of array elements that would
+ * be filled if array was large enough.
+ */
+int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max)
+{
+    int i, j, k = 0;
+    BN_ULONG mask;
+
+    if (BN_is_zero(a))
+        return 0;
+
+    for (i = a->top - 1; i >= 0; i--) {
+        if (!a->d[i])
+            /* skip word if a->d[i] == 0 */
+            continue;
+        mask = BN_TBIT;
+        for (j = BN_BITS2 - 1; j >= 0; j--) {
+            if (a->d[i] & mask) {
+                if (k < max)
+                    p[k] = BN_BITS2 * i + j;
+                k++;
+            }
+            mask >>= 1;
+        }
+    }
+
+    if (k < max) {
+        p[k] = -1;
+        k++;
+    }
+
+    return k;
+}
+
+/*
+ * Convert the coefficient array representation of a polynomial to a
+ * bit-string.  The array must be terminated by -1.
+ */
+int BN_GF2m_arr2poly(const int p[], BIGNUM *a)
+{
+    int i;
+
+    bn_check_top(a);
+    BN_zero(a);
+    for (i = 0; p[i] != -1; i++) {
+        if (BN_set_bit(a, p[i]) == 0)
+            return 0;
+    }
+    bn_check_top(a);
+
+    return 1;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_intern.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_intern.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_intern.c	(revision 331)
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2014-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 "internal/cryptlib.h"
+#include "bn_lcl.h"
+
+/*
+ * Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
+ * This is an array  r[]  of values that are either zero or odd with an
+ * absolute value less than  2^w  satisfying
+ *     scalar = \sum_j r[j]*2^j
+ * where at most one of any  w+1  consecutive digits is non-zero
+ * with the exception that the most significant digit may be only
+ * w-1 zeros away from that next non-zero digit.
+ */
+signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
+{
+    int window_val;
+    signed char *r = NULL;
+    int sign = 1;
+    int bit, next_bit, mask;
+    size_t len = 0, j;
+
+    if (BN_is_zero(scalar)) {
+        r = OPENSSL_malloc(1);
+        if (r == NULL) {
+            BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        r[0] = 0;
+        *ret_len = 1;
+        return r;
+    }
+
+    if (w <= 0 || w > 7) {      /* 'signed char' can represent integers with
+                                 * absolute values less than 2^7 */
+        BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+    bit = 1 << w;               /* at most 128 */
+    next_bit = bit << 1;        /* at most 256 */
+    mask = next_bit - 1;        /* at most 255 */
+
+    if (BN_is_negative(scalar)) {
+        sign = -1;
+    }
+
+    if (scalar->d == NULL || scalar->top == 0) {
+        BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
+    len = BN_num_bits(scalar);
+    r = OPENSSL_malloc(len + 1); /*
+                                  * Modified wNAF may be one digit longer than binary representation
+                                  * (*ret_len will be set to the actual length, i.e. at most
+                                  * BN_num_bits(scalar) + 1)
+                                  */
+    if (r == NULL) {
+        BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    window_val = scalar->d[0] & mask;
+    j = 0;
+    while ((window_val != 0) || (j + w + 1 < len)) { /* if j+w+1 >= len,
+                                                      * window_val will not
+                                                      * increase */
+        int digit = 0;
+
+        /* 0 <= window_val <= 2^(w+1) */
+
+        if (window_val & 1) {
+            /* 0 < window_val < 2^(w+1) */
+
+            if (window_val & bit) {
+                digit = window_val - next_bit; /* -2^w < digit < 0 */
+
+#if 1                           /* modified wNAF */
+                if (j + w + 1 >= len) {
+                    /*
+                     * Special case for generating modified wNAFs:
+                     * no new bits will be added into window_val,
+                     * so using a positive digit here will decrease
+                     * the total length of the representation
+                     */
+
+                    digit = window_val & (mask >> 1); /* 0 < digit < 2^w */
+                }
+#endif
+            } else {
+                digit = window_val; /* 0 < digit < 2^w */
+            }
+
+            if (digit <= -bit || digit >= bit || !(digit & 1)) {
+                BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+                goto err;
+            }
+
+            window_val -= digit;
+
+            /*
+             * now window_val is 0 or 2^(w+1) in standard wNAF generation;
+             * for modified window NAFs, it may also be 2^w
+             */
+            if (window_val != 0 && window_val != next_bit
+                && window_val != bit) {
+                BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+                goto err;
+            }
+        }
+
+        r[j++] = sign * digit;
+
+        window_val >>= 1;
+        window_val += bit * BN_is_bit_set(scalar, j + w);
+
+        if (window_val > next_bit) {
+            BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+    }
+
+    if (j > len + 1) {
+        BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+    *ret_len = j;
+    return r;
+
+ err:
+    OPENSSL_free(r);
+    return NULL;
+}
+
+int bn_get_top(const BIGNUM *a)
+{
+    return a->top;
+}
+
+void bn_set_top(BIGNUM *a, int top)
+{
+    a->top = top;
+}
+
+int bn_get_dmax(const BIGNUM *a)
+{
+    return a->dmax;
+}
+
+void bn_set_all_zero(BIGNUM *a)
+{
+    int i;
+
+    for (i = a->top; i < a->dmax; i++)
+        a->d[i] = 0;
+}
+
+int bn_copy_words(BN_ULONG *out, const BIGNUM *in, int size)
+{
+    if (in->top > size)
+        return 0;
+
+    memset(out, 0, sizeof(*out) * size);
+    if (in->d != NULL)
+        memcpy(out, in->d, sizeof(*out) * in->top);
+    return 1;
+}
+
+BN_ULONG *bn_get_words(const BIGNUM *a)
+{
+    return a->d;
+}
+
+void bn_set_static_words(BIGNUM *a, BN_ULONG *words, int size)
+{
+    a->d = words;
+    a->dmax = a->top = size;
+    a->neg = 0;
+    a->flags |= BN_FLG_STATIC_DATA;
+    bn_correct_top(a);
+}
+
+int bn_set_words(BIGNUM *a, BN_ULONG *words, int num_words)
+{
+    if (bn_wexpand(a, num_words) == NULL) {
+        BNerr(BN_F_BN_SET_WORDS, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    memcpy(a->d, words, sizeof(BN_ULONG) * num_words);
+    a->top = num_words;
+    bn_correct_top(a);
+    return 1;
+}
+
+size_t bn_sizeof_BIGNUM(void)
+{
+    return sizeof(BIGNUM);
+}
+
+BIGNUM *bn_array_el(BIGNUM *base, int el)
+{
+    return &base[el];
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_kron.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_kron.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_kron.c	(revision 331)
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2000-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 "internal/cryptlib.h"
+#include "bn_lcl.h"
+
+/* least significant word */
+#define BN_lsw(n) (((n)->top == 0) ? (BN_ULONG) 0 : (n)->d[0])
+
+/* Returns -2 for errors because both -1 and 0 are valid results. */
+int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+{
+    int i;
+    int ret = -2;               /* avoid 'uninitialized' warning */
+    int err = 0;
+    BIGNUM *A, *B, *tmp;
+    /*-
+     * In 'tab', only odd-indexed entries are relevant:
+     * For any odd BIGNUM n,
+     *     tab[BN_lsw(n) & 7]
+     * is $(-1)^{(n^2-1)/8}$ (using TeX notation).
+     * Note that the sign of n does not matter.
+     */
+    static const int tab[8] = { 0, 1, 0, -1, 0, -1, 0, 1 };
+
+    bn_check_top(a);
+    bn_check_top(b);
+
+    BN_CTX_start(ctx);
+    A = BN_CTX_get(ctx);
+    B = BN_CTX_get(ctx);
+    if (B == NULL)
+        goto end;
+
+    err = !BN_copy(A, a);
+    if (err)
+        goto end;
+    err = !BN_copy(B, b);
+    if (err)
+        goto end;
+
+    /*
+     * Kronecker symbol, implemented according to Henri Cohen,
+     * "A Course in Computational Algebraic Number Theory"
+     * (algorithm 1.4.10).
+     */
+
+    /* Cohen's step 1: */
+
+    if (BN_is_zero(B)) {
+        ret = BN_abs_is_word(A, 1);
+        goto end;
+    }
+
+    /* Cohen's step 2: */
+
+    if (!BN_is_odd(A) && !BN_is_odd(B)) {
+        ret = 0;
+        goto end;
+    }
+
+    /* now  B  is non-zero */
+    i = 0;
+    while (!BN_is_bit_set(B, i))
+        i++;
+    err = !BN_rshift(B, B, i);
+    if (err)
+        goto end;
+    if (i & 1) {
+        /* i is odd */
+        /* (thus  B  was even, thus  A  must be odd!)  */
+
+        /* set 'ret' to $(-1)^{(A^2-1)/8}$ */
+        ret = tab[BN_lsw(A) & 7];
+    } else {
+        /* i is even */
+        ret = 1;
+    }
+
+    if (B->neg) {
+        B->neg = 0;
+        if (A->neg)
+            ret = -ret;
+    }
+
+    /*
+     * now B is positive and odd, so what remains to be done is to compute
+     * the Jacobi symbol (A/B) and multiply it by 'ret'
+     */
+
+    while (1) {
+        /* Cohen's step 3: */
+
+        /*  B  is positive and odd */
+
+        if (BN_is_zero(A)) {
+            ret = BN_is_one(B) ? ret : 0;
+            goto end;
+        }
+
+        /* now  A  is non-zero */
+        i = 0;
+        while (!BN_is_bit_set(A, i))
+            i++;
+        err = !BN_rshift(A, A, i);
+        if (err)
+            goto end;
+        if (i & 1) {
+            /* i is odd */
+            /* multiply 'ret' by  $(-1)^{(B^2-1)/8}$ */
+            ret = ret * tab[BN_lsw(B) & 7];
+        }
+
+        /* Cohen's step 4: */
+        /* multiply 'ret' by  $(-1)^{(A-1)(B-1)/4}$ */
+        if ((A->neg ? ~BN_lsw(A) : BN_lsw(A)) & BN_lsw(B) & 2)
+            ret = -ret;
+
+        /* (A, B) := (B mod |A|, |A|) */
+        err = !BN_nnmod(B, B, A, ctx);
+        if (err)
+            goto end;
+        tmp = A;
+        A = B;
+        B = tmp;
+        tmp->neg = 0;
+    }
+ end:
+    BN_CTX_end(ctx);
+    if (err)
+        return -2;
+    else
+        return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_lcl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_lcl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_lcl.h	(revision 331)
@@ -0,0 +1,689 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_BN_LCL_H
+# define HEADER_BN_LCL_H
+
+/*
+ * The EDK2 build doesn't use bn_conf.h; it sets THIRTY_TWO_BIT or
+ * SIXTY_FOUR_BIT in its own environment since it doesn't re-run our
+ * Configure script and needs to support both 32-bit and 64-bit.
+ */
+# include <openssl/opensslconf.h>
+
+# if !defined(OPENSSL_SYS_UEFI)
+#  include "internal/bn_conf.h"
+# endif
+
+# include "internal/bn_int.h"
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+ * These preprocessor symbols control various aspects of the bignum headers
+ * and library code. They're not defined by any "normal" configuration, as
+ * they are intended for development and testing purposes. NB: defining all
+ * three can be useful for debugging application code as well as openssl
+ * itself. BN_DEBUG - turn on various debugging alterations to the bignum
+ * code BN_DEBUG_RAND - uses random poisoning of unused words to trip up
+ * mismanagement of bignum internals. You must also define BN_DEBUG.
+ */
+/* #define BN_DEBUG */
+/* #define BN_DEBUG_RAND */
+
+# ifndef OPENSSL_SMALL_FOOTPRINT
+#  define BN_MUL_COMBA
+#  define BN_SQR_COMBA
+#  define BN_RECURSION
+# endif
+
+/*
+ * This next option uses the C libraries (2 word)/(1 word) function. If it is
+ * not defined, I use my C version (which is slower). The reason for this
+ * flag is that when the particular C compiler library routine is used, and
+ * the library is linked with a different compiler, the library is missing.
+ * This mostly happens when the library is built with gcc and then linked
+ * using normal cc.  This would be a common occurrence because gcc normally
+ * produces code that is 2 times faster than system compilers for the big
+ * number stuff. For machines with only one compiler (or shared libraries),
+ * this should be on.  Again this in only really a problem on machines using
+ * "long long's", are 32bit, and are not using my assembler code.
+ */
+# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || \
+    defined(OPENSSL_SYS_WIN32) || defined(linux)
+#  define BN_DIV2W
+# endif
+
+/*
+ * 64-bit processor with LP64 ABI
+ */
+# ifdef SIXTY_FOUR_BIT_LONG
+#  define BN_ULLONG       unsigned long long
+#  define BN_BITS4        32
+#  define BN_MASK2        (0xffffffffffffffffL)
+#  define BN_MASK2l       (0xffffffffL)
+#  define BN_MASK2h       (0xffffffff00000000L)
+#  define BN_MASK2h1      (0xffffffff80000000L)
+#  define BN_DEC_CONV     (10000000000000000000UL)
+#  define BN_DEC_NUM      19
+#  define BN_DEC_FMT1     "%lu"
+#  define BN_DEC_FMT2     "%019lu"
+# endif
+
+/*
+ * 64-bit processor other than LP64 ABI
+ */
+# ifdef SIXTY_FOUR_BIT
+#  undef BN_LLONG
+#  undef BN_ULLONG
+#  define BN_BITS4        32
+#  define BN_MASK2        (0xffffffffffffffffLL)
+#  define BN_MASK2l       (0xffffffffL)
+#  define BN_MASK2h       (0xffffffff00000000LL)
+#  define BN_MASK2h1      (0xffffffff80000000LL)
+#  define BN_DEC_CONV     (10000000000000000000ULL)
+#  define BN_DEC_NUM      19
+#  define BN_DEC_FMT1     "%llu"
+#  define BN_DEC_FMT2     "%019llu"
+# endif
+
+# ifdef THIRTY_TWO_BIT
+#  ifdef BN_LLONG
+#   if defined(_WIN32) && !defined(__GNUC__)
+#    define BN_ULLONG     unsigned __int64
+#   else
+#    define BN_ULLONG     unsigned long long
+#   endif
+#  endif
+#  define BN_BITS4        16
+#  define BN_MASK2        (0xffffffffL)
+#  define BN_MASK2l       (0xffff)
+#  define BN_MASK2h1      (0xffff8000L)
+#  define BN_MASK2h       (0xffff0000L)
+#  define BN_DEC_CONV     (1000000000L)
+#  define BN_DEC_NUM      9
+#  define BN_DEC_FMT1     "%u"
+#  define BN_DEC_FMT2     "%09u"
+# endif
+
+
+/*-
+ * Bignum consistency macros
+ * There is one "API" macro, bn_fix_top(), for stripping leading zeroes from
+ * bignum data after direct manipulations on the data. There is also an
+ * "internal" macro, bn_check_top(), for verifying that there are no leading
+ * zeroes. Unfortunately, some auditing is required due to the fact that
+ * bn_fix_top() has become an overabused duct-tape because bignum data is
+ * occasionally passed around in an inconsistent state. So the following
+ * changes have been made to sort this out;
+ * - bn_fix_top()s implementation has been moved to bn_correct_top()
+ * - if BN_DEBUG isn't defined, bn_fix_top() maps to bn_correct_top(), and
+ *   bn_check_top() is as before.
+ * - if BN_DEBUG *is* defined;
+ *   - bn_check_top() tries to pollute unused words even if the bignum 'top' is
+ *     consistent. (ed: only if BN_DEBUG_RAND is defined)
+ *   - bn_fix_top() maps to bn_check_top() rather than "fixing" anything.
+ * The idea is to have debug builds flag up inconsistent bignums when they
+ * occur. If that occurs in a bn_fix_top(), we examine the code in question; if
+ * the use of bn_fix_top() was appropriate (ie. it follows directly after code
+ * that manipulates the bignum) it is converted to bn_correct_top(), and if it
+ * was not appropriate, we convert it permanently to bn_check_top() and track
+ * down the cause of the bug. Eventually, no internal code should be using the
+ * bn_fix_top() macro. External applications and libraries should try this with
+ * their own code too, both in terms of building against the openssl headers
+ * with BN_DEBUG defined *and* linking with a version of OpenSSL built with it
+ * defined. This not only improves external code, it provides more test
+ * coverage for openssl's own code.
+ */
+
+# ifdef BN_DEBUG
+
+#  ifdef BN_DEBUG_RAND
+/* To avoid "make update" cvs wars due to BN_DEBUG, use some tricks */
+#   ifndef RAND_bytes
+int RAND_bytes(unsigned char *buf, int num);
+#    define BN_DEBUG_TRIX
+#   endif
+#   define bn_pollute(a) \
+        do { \
+            const BIGNUM *_bnum1 = (a); \
+            if (_bnum1->top < _bnum1->dmax) { \
+                unsigned char _tmp_char; \
+                /* We cast away const without the compiler knowing, any \
+                 * *genuinely* constant variables that aren't mutable \
+                 * wouldn't be constructed with top!=dmax. */ \
+                BN_ULONG *_not_const; \
+                memcpy(&_not_const, &_bnum1->d, sizeof(_not_const)); \
+                RAND_bytes(&_tmp_char, 1); /* Debug only - safe to ignore error return */\
+                memset(_not_const + _bnum1->top, _tmp_char, \
+                       sizeof(*_not_const) * (_bnum1->dmax - _bnum1->top)); \
+            } \
+        } while(0)
+#   ifdef BN_DEBUG_TRIX
+#    undef RAND_bytes
+#   endif
+#  else
+#   define bn_pollute(a)
+#  endif
+#  define bn_check_top(a) \
+        do { \
+                const BIGNUM *_bnum2 = (a); \
+                if (_bnum2 != NULL) { \
+                        OPENSSL_assert(((_bnum2->top == 0) && !_bnum2->neg) || \
+                                (_bnum2->top && (_bnum2->d[_bnum2->top - 1] != 0))); \
+                        bn_pollute(_bnum2); \
+                } \
+        } while(0)
+
+#  define bn_fix_top(a)           bn_check_top(a)
+
+#  define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits+BN_BITS2-1))/BN_BITS2)
+#  define bn_wcheck_size(bn, words) \
+        do { \
+                const BIGNUM *_bnum2 = (bn); \
+                OPENSSL_assert((words) <= (_bnum2)->dmax && \
+                        (words) >= (_bnum2)->top); \
+                /* avoid unused variable warning with NDEBUG */ \
+                (void)(_bnum2); \
+        } while(0)
+
+# else                          /* !BN_DEBUG */
+
+#  define bn_pollute(a)
+#  define bn_check_top(a)
+#  define bn_fix_top(a)           bn_correct_top(a)
+#  define bn_check_size(bn, bits)
+#  define bn_wcheck_size(bn, words)
+
+# endif
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
+                          BN_ULONG w);
+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
+void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
+BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+                      int num);
+BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+                      int num);
+
+struct bignum_st {
+    BN_ULONG *d;                /* Pointer to an array of 'BN_BITS2' bit
+                                 * chunks. */
+    int top;                    /* Index of last used d +1. */
+    /* The next are internal book keeping for bn_expand. */
+    int dmax;                   /* Size of the d array. */
+    int neg;                    /* one if the number is negative */
+    int flags;
+};
+
+/* Used for montgomery multiplication */
+struct bn_mont_ctx_st {
+    int ri;                     /* number of bits in R */
+    BIGNUM RR;                  /* used to convert to montgomery form */
+    BIGNUM N;                   /* The modulus */
+    BIGNUM Ni;                  /* R*(1/R mod N) - N*Ni = 1 (Ni is only
+                                 * stored for bignum algorithm) */
+    BN_ULONG n0[2];             /* least significant word(s) of Ni; (type
+                                 * changed with 0.9.9, was "BN_ULONG n0;"
+                                 * before) */
+    int flags;
+};
+
+/*
+ * Used for reciprocal division/mod functions It cannot be shared between
+ * threads
+ */
+struct bn_recp_ctx_st {
+    BIGNUM N;                   /* the divisor */
+    BIGNUM Nr;                  /* the reciprocal */
+    int num_bits;
+    int shift;
+    int flags;
+};
+
+/* Used for slow "generation" functions. */
+struct bn_gencb_st {
+    unsigned int ver;           /* To handle binary (in)compatibility */
+    void *arg;                  /* callback-specific data */
+    union {
+        /* if (ver==1) - handles old style callbacks */
+        void (*cb_1) (int, int, void *);
+        /* if (ver==2) - new callback style */
+        int (*cb_2) (int, int, BN_GENCB *);
+    } cb;
+};
+
+/*-
+ * BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions
+ *
+ *
+ * For window size 'w' (w >= 2) and a random 'b' bits exponent,
+ * the number of multiplications is a constant plus on average
+ *
+ *    2^(w-1) + (b-w)/(w+1);
+ *
+ * here  2^(w-1)  is for precomputing the table (we actually need
+ * entries only for windows that have the lowest bit set), and
+ * (b-w)/(w+1)  is an approximation for the expected number of
+ * w-bit windows, not counting the first one.
+ *
+ * Thus we should use
+ *
+ *    w >= 6  if        b > 671
+ *     w = 5  if  671 > b > 239
+ *     w = 4  if  239 > b >  79
+ *     w = 3  if   79 > b >  23
+ *    w <= 2  if   23 > b
+ *
+ * (with draws in between).  Very small exponents are often selected
+ * with low Hamming weight, so we use  w = 1  for b <= 23.
+ */
+# define BN_window_bits_for_exponent_size(b) \
+                ((b) > 671 ? 6 : \
+                 (b) > 239 ? 5 : \
+                 (b) >  79 ? 4 : \
+                 (b) >  23 ? 3 : 1)
+
+/*
+ * BN_mod_exp_mont_conttime is based on the assumption that the L1 data cache
+ * line width of the target processor is at least the following value.
+ */
+# define MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH      ( 64 )
+# define MOD_EXP_CTIME_MIN_CACHE_LINE_MASK       (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - 1)
+
+/*
+ * Window sizes optimized for fixed window size modular exponentiation
+ * algorithm (BN_mod_exp_mont_consttime). To achieve the security goals of
+ * BN_mode_exp_mont_consttime, the maximum size of the window must not exceed
+ * log_2(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH). Window size thresholds are
+ * defined for cache line sizes of 32 and 64, cache line sizes where
+ * log_2(32)=5 and log_2(64)=6 respectively. A window size of 7 should only be
+ * used on processors that have a 128 byte or greater cache line size.
+ */
+# if MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 64
+
+#  define BN_window_bits_for_ctime_exponent_size(b) \
+                ((b) > 937 ? 6 : \
+                 (b) > 306 ? 5 : \
+                 (b) >  89 ? 4 : \
+                 (b) >  22 ? 3 : 1)
+#  define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE    (6)
+
+# elif MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 32
+
+#  define BN_window_bits_for_ctime_exponent_size(b) \
+                ((b) > 306 ? 5 : \
+                 (b) >  89 ? 4 : \
+                 (b) >  22 ? 3 : 1)
+#  define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE    (5)
+
+# endif
+
+/* Pentium pro 16,16,16,32,64 */
+/* Alpha       16,16,16,16.64 */
+# define BN_MULL_SIZE_NORMAL                     (16)/* 32 */
+# define BN_MUL_RECURSIVE_SIZE_NORMAL            (16)/* 32 less than */
+# define BN_SQR_RECURSIVE_SIZE_NORMAL            (16)/* 32 */
+# define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL        (32)/* 32 */
+# define BN_MONT_CTX_SET_SIZE_WORD               (64)/* 32 */
+
+/*
+ * 2011-02-22 SMS. In various places, a size_t variable or a type cast to
+ * size_t was used to perform integer-only operations on pointers.  This
+ * failed on VMS with 64-bit pointers (CC /POINTER_SIZE = 64) because size_t
+ * is still only 32 bits.  What's needed in these cases is an integer type
+ * with the same size as a pointer, which size_t is not certain to be. The
+ * only fix here is VMS-specific.
+ */
+# if defined(OPENSSL_SYS_VMS)
+#  if __INITIAL_POINTER_SIZE == 64
+#   define PTR_SIZE_INT long long
+#  else                         /* __INITIAL_POINTER_SIZE == 64 */
+#   define PTR_SIZE_INT int
+#  endif                        /* __INITIAL_POINTER_SIZE == 64 [else] */
+# elif !defined(PTR_SIZE_INT)   /* defined(OPENSSL_SYS_VMS) */
+#  define PTR_SIZE_INT size_t
+# endif                         /* defined(OPENSSL_SYS_VMS) [else] */
+
+# if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
+/*
+ * BN_UMULT_HIGH section.
+ *
+ * No, I'm not trying to overwhelm you when stating that the
+ * product of N-bit numbers is 2*N bits wide:-) No, I don't expect
+ * you to be impressed when I say that if the compiler doesn't
+ * support 2*N integer type, then you have to replace every N*N
+ * multiplication with 4 (N/2)*(N/2) accompanied by some shifts
+ * and additions which unavoidably results in severe performance
+ * penalties. Of course provided that the hardware is capable of
+ * producing 2*N result... That's when you normally start
+ * considering assembler implementation. However! It should be
+ * pointed out that some CPUs (most notably Alpha, PowerPC and
+ * upcoming IA-64 family:-) provide *separate* instruction
+ * calculating the upper half of the product placing the result
+ * into a general purpose register. Now *if* the compiler supports
+ * inline assembler, then it's not impossible to implement the
+ * "bignum" routines (and have the compiler optimize 'em)
+ * exhibiting "native" performance in C. That's what BN_UMULT_HIGH
+ * macro is about:-)
+ *
+ *                                      <appro@fy.chalmers.se>
+ */
+#  if defined(__alpha) && (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
+#   if defined(__DECC)
+#    include <c_asm.h>
+#    define BN_UMULT_HIGH(a,b)   (BN_ULONG)asm("umulh %a0,%a1,%v0",(a),(b))
+#   elif defined(__GNUC__) && __GNUC__>=2
+#    define BN_UMULT_HIGH(a,b)   ({      \
+        register BN_ULONG ret;          \
+        asm ("umulh     %1,%2,%0"       \
+             : "=r"(ret)                \
+             : "r"(a), "r"(b));         \
+        ret;                    })
+#   endif                       /* compiler */
+#  elif defined(_ARCH_PPC) && defined(__64BIT__) && defined(SIXTY_FOUR_BIT_LONG)
+#   if defined(__GNUC__) && __GNUC__>=2
+#    define BN_UMULT_HIGH(a,b)   ({      \
+        register BN_ULONG ret;          \
+        asm ("mulhdu    %0,%1,%2"       \
+             : "=r"(ret)                \
+             : "r"(a), "r"(b));         \
+        ret;                    })
+#   endif                       /* compiler */
+#  elif (defined(__x86_64) || defined(__x86_64__)) && \
+       (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
+#   if defined(__GNUC__) && __GNUC__>=2
+#    define BN_UMULT_HIGH(a,b)   ({      \
+        register BN_ULONG ret,discard;  \
+        asm ("mulq      %3"             \
+             : "=a"(discard),"=d"(ret)  \
+             : "a"(a), "g"(b)           \
+             : "cc");                   \
+        ret;                    })
+#    define BN_UMULT_LOHI(low,high,a,b)  \
+        asm ("mulq      %3"             \
+                : "=a"(low),"=d"(high)  \
+                : "a"(a),"g"(b)         \
+                : "cc");
+#   endif
+#  elif (defined(_M_AMD64) || defined(_M_X64)) && defined(SIXTY_FOUR_BIT)
+#   if defined(_MSC_VER) && _MSC_VER>=1400
+unsigned __int64 __umulh(unsigned __int64 a, unsigned __int64 b);
+unsigned __int64 _umul128(unsigned __int64 a, unsigned __int64 b,
+                          unsigned __int64 *h);
+#    pragma intrinsic(__umulh,_umul128)
+#    define BN_UMULT_HIGH(a,b)           __umulh((a),(b))
+#    define BN_UMULT_LOHI(low,high,a,b)  ((low)=_umul128((a),(b),&(high)))
+#   endif
+#  elif defined(__mips) && (defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG))
+#   if defined(__GNUC__) && __GNUC__>=2
+#    if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16
+      /* "h" constraint is not an option on R6 and was removed in 4.4 */
+#     define BN_UMULT_HIGH(a,b)          (((__uint128_t)(a)*(b))>>64)
+#     define BN_UMULT_LOHI(low,high,a,b) ({     \
+        __uint128_t ret=(__uint128_t)(a)*(b);   \
+        (high)=ret>>64; (low)=ret;       })
+#    else
+#     define BN_UMULT_HIGH(a,b) ({      \
+        register BN_ULONG ret;          \
+        asm ("dmultu    %1,%2"          \
+             : "=h"(ret)                \
+             : "r"(a), "r"(b) : "l");   \
+        ret;                    })
+#     define BN_UMULT_LOHI(low,high,a,b)\
+        asm ("dmultu    %2,%3"          \
+             : "=l"(low),"=h"(high)     \
+             : "r"(a), "r"(b));
+#    endif
+#   endif
+#  elif defined(__aarch64__) && defined(SIXTY_FOUR_BIT_LONG)
+#   if defined(__GNUC__) && __GNUC__>=2
+#    define BN_UMULT_HIGH(a,b)   ({      \
+        register BN_ULONG ret;          \
+        asm ("umulh     %0,%1,%2"       \
+             : "=r"(ret)                \
+             : "r"(a), "r"(b));         \
+        ret;                    })
+#   endif
+#  endif                        /* cpu */
+# endif                         /* OPENSSL_NO_ASM */
+
+/*************************************************************
+ * Using the long long type
+ */
+# define Lw(t)    (((BN_ULONG)(t))&BN_MASK2)
+# define Hw(t)    (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2)
+
+# ifdef BN_DEBUG_RAND
+#  define bn_clear_top2max(a) \
+        { \
+        int      ind = (a)->dmax - (a)->top; \
+        BN_ULONG *ftl = &(a)->d[(a)->top-1]; \
+        for (; ind != 0; ind--) \
+                *(++ftl) = 0x0; \
+        }
+# else
+#  define bn_clear_top2max(a)
+# endif
+
+# ifdef BN_LLONG
+#  define mul_add(r,a,w,c) { \
+        BN_ULLONG t; \
+        t=(BN_ULLONG)w * (a) + (r) + (c); \
+        (r)= Lw(t); \
+        (c)= Hw(t); \
+        }
+
+#  define mul(r,a,w,c) { \
+        BN_ULLONG t; \
+        t=(BN_ULLONG)w * (a) + (c); \
+        (r)= Lw(t); \
+        (c)= Hw(t); \
+        }
+
+#  define sqr(r0,r1,a) { \
+        BN_ULLONG t; \
+        t=(BN_ULLONG)(a)*(a); \
+        (r0)=Lw(t); \
+        (r1)=Hw(t); \
+        }
+
+# elif defined(BN_UMULT_LOHI)
+#  define mul_add(r,a,w,c) {              \
+        BN_ULONG high,low,ret,tmp=(a);  \
+        ret =  (r);                     \
+        BN_UMULT_LOHI(low,high,w,tmp);  \
+        ret += (c);                     \
+        (c) =  (ret<(c))?1:0;           \
+        (c) += high;                    \
+        ret += low;                     \
+        (c) += (ret<low)?1:0;           \
+        (r) =  ret;                     \
+        }
+
+#  define mul(r,a,w,c)    {               \
+        BN_ULONG high,low,ret,ta=(a);   \
+        BN_UMULT_LOHI(low,high,w,ta);   \
+        ret =  low + (c);               \
+        (c) =  high;                    \
+        (c) += (ret<low)?1:0;           \
+        (r) =  ret;                     \
+        }
+
+#  define sqr(r0,r1,a)    {               \
+        BN_ULONG tmp=(a);               \
+        BN_UMULT_LOHI(r0,r1,tmp,tmp);   \
+        }
+
+# elif defined(BN_UMULT_HIGH)
+#  define mul_add(r,a,w,c) {              \
+        BN_ULONG high,low,ret,tmp=(a);  \
+        ret =  (r);                     \
+        high=  BN_UMULT_HIGH(w,tmp);    \
+        ret += (c);                     \
+        low =  (w) * tmp;               \
+        (c) =  (ret<(c))?1:0;           \
+        (c) += high;                    \
+        ret += low;                     \
+        (c) += (ret<low)?1:0;           \
+        (r) =  ret;                     \
+        }
+
+#  define mul(r,a,w,c)    {               \
+        BN_ULONG high,low,ret,ta=(a);   \
+        low =  (w) * ta;                \
+        high=  BN_UMULT_HIGH(w,ta);     \
+        ret =  low + (c);               \
+        (c) =  high;                    \
+        (c) += (ret<low)?1:0;           \
+        (r) =  ret;                     \
+        }
+
+#  define sqr(r0,r1,a)    {               \
+        BN_ULONG tmp=(a);               \
+        (r0) = tmp * tmp;               \
+        (r1) = BN_UMULT_HIGH(tmp,tmp);  \
+        }
+
+# else
+/*************************************************************
+ * No long long type
+ */
+
+#  define LBITS(a)        ((a)&BN_MASK2l)
+#  define HBITS(a)        (((a)>>BN_BITS4)&BN_MASK2l)
+#  define L2HBITS(a)      (((a)<<BN_BITS4)&BN_MASK2)
+
+#  define LLBITS(a)       ((a)&BN_MASKl)
+#  define LHBITS(a)       (((a)>>BN_BITS2)&BN_MASKl)
+#  define LL2HBITS(a)     ((BN_ULLONG)((a)&BN_MASKl)<<BN_BITS2)
+
+#  define mul64(l,h,bl,bh) \
+        { \
+        BN_ULONG m,m1,lt,ht; \
+ \
+        lt=l; \
+        ht=h; \
+        m =(bh)*(lt); \
+        lt=(bl)*(lt); \
+        m1=(bl)*(ht); \
+        ht =(bh)*(ht); \
+        m=(m+m1)&BN_MASK2; if (m < m1) ht+=L2HBITS((BN_ULONG)1); \
+        ht+=HBITS(m); \
+        m1=L2HBITS(m); \
+        lt=(lt+m1)&BN_MASK2; if (lt < m1) ht++; \
+        (l)=lt; \
+        (h)=ht; \
+        }
+
+#  define sqr64(lo,ho,in) \
+        { \
+        BN_ULONG l,h,m; \
+ \
+        h=(in); \
+        l=LBITS(h); \
+        h=HBITS(h); \
+        m =(l)*(h); \
+        l*=l; \
+        h*=h; \
+        h+=(m&BN_MASK2h1)>>(BN_BITS4-1); \
+        m =(m&BN_MASK2l)<<(BN_BITS4+1); \
+        l=(l+m)&BN_MASK2; if (l < m) h++; \
+        (lo)=l; \
+        (ho)=h; \
+        }
+
+#  define mul_add(r,a,bl,bh,c) { \
+        BN_ULONG l,h; \
+ \
+        h= (a); \
+        l=LBITS(h); \
+        h=HBITS(h); \
+        mul64(l,h,(bl),(bh)); \
+ \
+        /* non-multiply part */ \
+        l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
+        (c)=(r); \
+        l=(l+(c))&BN_MASK2; if (l < (c)) h++; \
+        (c)=h&BN_MASK2; \
+        (r)=l; \
+        }
+
+#  define mul(r,a,bl,bh,c) { \
+        BN_ULONG l,h; \
+ \
+        h= (a); \
+        l=LBITS(h); \
+        h=HBITS(h); \
+        mul64(l,h,(bl),(bh)); \
+ \
+        /* non-multiply part */ \
+        l+=(c); if ((l&BN_MASK2) < (c)) h++; \
+        (c)=h&BN_MASK2; \
+        (r)=l&BN_MASK2; \
+        }
+# endif                         /* !BN_LLONG */
+
+void BN_RECP_CTX_init(BN_RECP_CTX *recp);
+void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
+
+void bn_init(BIGNUM *a);
+void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb);
+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
+void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp);
+void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a);
+void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a);
+int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n);
+int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl);
+void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
+                      int dna, int dnb, BN_ULONG *t);
+void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b,
+                           int n, int tna, int tnb, BN_ULONG *t);
+void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t);
+void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n);
+void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
+                          BN_ULONG *t);
+void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
+                 BN_ULONG *t);
+BN_ULONG bn_add_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
+                           int cl, int dl);
+BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
+                           int cl, int dl);
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+                const BN_ULONG *np, const BN_ULONG *n0, int num);
+
+BIGNUM *int_bn_mod_inverse(BIGNUM *in,
+                           const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx,
+                           int *noinv);
+
+int bn_probable_prime_dh(BIGNUM *rnd, int bits,
+                         const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx);
+int bn_probable_prime_dh_retry(BIGNUM *rnd, int bits, BN_CTX *ctx);
+int bn_probable_prime_dh_coprime(BIGNUM *rnd, int bits, BN_CTX *ctx);
+
+static ossl_inline BIGNUM *bn_expand(BIGNUM *a, int bits)
+{
+    if (bits > (INT_MAX - BN_BITS2 + 1))
+        return NULL;
+
+    if (((bits+BN_BITS2-1)/BN_BITS2) <= (a)->dmax)
+        return a;
+
+    return bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2);
+}
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_lib.c	(revision 331)
@@ -0,0 +1,1037 @@
+/*
+ * Copyright 1995-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 <assert.h>
+#include <limits.h>
+#include "internal/cryptlib.h"
+#include "bn_lcl.h"
+#include <openssl/opensslconf.h>
+
+/* This stuff appears to be completely unused, so is deprecated */
+#if OPENSSL_API_COMPAT < 0x00908000L
+/*-
+ * For a 32 bit machine
+ * 2 -   4 ==  128
+ * 3 -   8 ==  256
+ * 4 -  16 ==  512
+ * 5 -  32 == 1024
+ * 6 -  64 == 2048
+ * 7 - 128 == 4096
+ * 8 - 256 == 8192
+ */
+static int bn_limit_bits = 0;
+static int bn_limit_num = 8;    /* (1<<bn_limit_bits) */
+static int bn_limit_bits_low = 0;
+static int bn_limit_num_low = 8; /* (1<<bn_limit_bits_low) */
+static int bn_limit_bits_high = 0;
+static int bn_limit_num_high = 8; /* (1<<bn_limit_bits_high) */
+static int bn_limit_bits_mont = 0;
+static int bn_limit_num_mont = 8; /* (1<<bn_limit_bits_mont) */
+
+void BN_set_params(int mult, int high, int low, int mont)
+{
+    if (mult >= 0) {
+        if (mult > (int)(sizeof(int) * 8) - 1)
+            mult = sizeof(int) * 8 - 1;
+        bn_limit_bits = mult;
+        bn_limit_num = 1 << mult;
+    }
+    if (high >= 0) {
+        if (high > (int)(sizeof(int) * 8) - 1)
+            high = sizeof(int) * 8 - 1;
+        bn_limit_bits_high = high;
+        bn_limit_num_high = 1 << high;
+    }
+    if (low >= 0) {
+        if (low > (int)(sizeof(int) * 8) - 1)
+            low = sizeof(int) * 8 - 1;
+        bn_limit_bits_low = low;
+        bn_limit_num_low = 1 << low;
+    }
+    if (mont >= 0) {
+        if (mont > (int)(sizeof(int) * 8) - 1)
+            mont = sizeof(int) * 8 - 1;
+        bn_limit_bits_mont = mont;
+        bn_limit_num_mont = 1 << mont;
+    }
+}
+
+int BN_get_params(int which)
+{
+    if (which == 0)
+        return (bn_limit_bits);
+    else if (which == 1)
+        return (bn_limit_bits_high);
+    else if (which == 2)
+        return (bn_limit_bits_low);
+    else if (which == 3)
+        return (bn_limit_bits_mont);
+    else
+        return (0);
+}
+#endif
+
+const BIGNUM *BN_value_one(void)
+{
+    static const BN_ULONG data_one = 1L;
+    static const BIGNUM const_one =
+        { (BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA };
+
+    return (&const_one);
+}
+
+int BN_num_bits_word(BN_ULONG l)
+{
+    static const unsigned char bits[256] = {
+        0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+        8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+    };
+
+#if defined(SIXTY_FOUR_BIT_LONG)
+    if (l & 0xffffffff00000000L) {
+        if (l & 0xffff000000000000L) {
+            if (l & 0xff00000000000000L) {
+                return (bits[(int)(l >> 56)] + 56);
+            } else
+                return (bits[(int)(l >> 48)] + 48);
+        } else {
+            if (l & 0x0000ff0000000000L) {
+                return (bits[(int)(l >> 40)] + 40);
+            } else
+                return (bits[(int)(l >> 32)] + 32);
+        }
+    } else
+#else
+# ifdef SIXTY_FOUR_BIT
+    if (l & 0xffffffff00000000LL) {
+        if (l & 0xffff000000000000LL) {
+            if (l & 0xff00000000000000LL) {
+                return (bits[(int)(l >> 56)] + 56);
+            } else
+                return (bits[(int)(l >> 48)] + 48);
+        } else {
+            if (l & 0x0000ff0000000000LL) {
+                return (bits[(int)(l >> 40)] + 40);
+            } else
+                return (bits[(int)(l >> 32)] + 32);
+        }
+    } else
+# endif
+#endif
+    {
+#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+        if (l & 0xffff0000L) {
+            if (l & 0xff000000L)
+                return (bits[(int)(l >> 24L)] + 24);
+            else
+                return (bits[(int)(l >> 16L)] + 16);
+        } else
+#endif
+        {
+#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
+            if (l & 0xff00L)
+                return (bits[(int)(l >> 8)] + 8);
+            else
+#endif
+                return (bits[(int)(l)]);
+        }
+    }
+}
+
+int BN_num_bits(const BIGNUM *a)
+{
+    int i = a->top - 1;
+    bn_check_top(a);
+
+    if (BN_is_zero(a))
+        return 0;
+    return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));
+}
+
+static void bn_free_d(BIGNUM *a)
+{
+    if (BN_get_flags(a, BN_FLG_SECURE))
+        OPENSSL_secure_free(a->d);
+    else
+        OPENSSL_free(a->d);
+}
+
+
+void BN_clear_free(BIGNUM *a)
+{
+    int i;
+
+    if (a == NULL)
+        return;
+    bn_check_top(a);
+    if (a->d != NULL) {
+        OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0]));
+        if (!BN_get_flags(a, BN_FLG_STATIC_DATA))
+            bn_free_d(a);
+    }
+    i = BN_get_flags(a, BN_FLG_MALLOCED);
+    OPENSSL_cleanse(a, sizeof(*a));
+    if (i)
+        OPENSSL_free(a);
+}
+
+void BN_free(BIGNUM *a)
+{
+    if (a == NULL)
+        return;
+    bn_check_top(a);
+    if (!BN_get_flags(a, BN_FLG_STATIC_DATA))
+        bn_free_d(a);
+    if (a->flags & BN_FLG_MALLOCED)
+        OPENSSL_free(a);
+    else {
+#if OPENSSL_API_COMPAT < 0x00908000L
+        a->flags |= BN_FLG_FREE;
+#endif
+        a->d = NULL;
+    }
+}
+
+void bn_init(BIGNUM *a)
+{
+    static BIGNUM nilbn;
+
+    *a = nilbn;
+    bn_check_top(a);
+}
+
+BIGNUM *BN_new(void)
+{
+    BIGNUM *ret;
+
+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
+        BNerr(BN_F_BN_NEW, ERR_R_MALLOC_FAILURE);
+        return (NULL);
+    }
+    ret->flags = BN_FLG_MALLOCED;
+    bn_check_top(ret);
+    return (ret);
+}
+
+ BIGNUM *BN_secure_new(void)
+ {
+     BIGNUM *ret = BN_new();
+     if (ret != NULL)
+         ret->flags |= BN_FLG_SECURE;
+     return (ret);
+ }
+
+/* This is used by bn_expand2() */
+/* The caller MUST check that words > b->dmax before calling this */
+static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
+{
+    BN_ULONG *A, *a = NULL;
+    const BN_ULONG *B;
+    int i;
+
+    bn_check_top(b);
+
+    if (words > (INT_MAX / (4 * BN_BITS2))) {
+        BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_BIGNUM_TOO_LONG);
+        return NULL;
+    }
+    if (BN_get_flags(b, BN_FLG_STATIC_DATA)) {
+        BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
+        return (NULL);
+    }
+    if (BN_get_flags(b, BN_FLG_SECURE))
+        a = A = OPENSSL_secure_zalloc(words * sizeof(*a));
+    else
+        a = A = OPENSSL_zalloc(words * sizeof(*a));
+    if (A == NULL) {
+        BNerr(BN_F_BN_EXPAND_INTERNAL, ERR_R_MALLOC_FAILURE);
+        return (NULL);
+    }
+
+#if 1
+    B = b->d;
+    /* Check if the previous number needs to be copied */
+    if (B != NULL) {
+        for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) {
+            /*
+             * The fact that the loop is unrolled
+             * 4-wise is a tribute to Intel. It's
+             * the one that doesn't have enough
+             * registers to accommodate more data.
+             * I'd unroll it 8-wise otherwise:-)
+             *
+             *              <appro@fy.chalmers.se>
+             */
+            BN_ULONG a0, a1, a2, a3;
+            a0 = B[0];
+            a1 = B[1];
+            a2 = B[2];
+            a3 = B[3];
+            A[0] = a0;
+            A[1] = a1;
+            A[2] = a2;
+            A[3] = a3;
+        }
+        switch (b->top & 3) {
+        case 3:
+            A[2] = B[2];
+        case 2:
+            A[1] = B[1];
+        case 1:
+            A[0] = B[0];
+        case 0:
+            /* Without the "case 0" some old optimizers got this wrong. */
+            ;
+        }
+    }
+#else
+    memset(A, 0, sizeof(*A) * words);
+    memcpy(A, b->d, sizeof(b->d[0]) * b->top);
+#endif
+
+    return (a);
+}
+
+/*
+ * This is an internal function that should not be used in applications. It
+ * ensures that 'b' has enough room for a 'words' word number and initialises
+ * any unused part of b->d with leading zeros. It is mostly used by the
+ * various BIGNUM routines. If there is an error, NULL is returned. If not,
+ * 'b' is returned.
+ */
+
+BIGNUM *bn_expand2(BIGNUM *b, int words)
+{
+    bn_check_top(b);
+
+    if (words > b->dmax) {
+        BN_ULONG *a = bn_expand_internal(b, words);
+        if (!a)
+            return NULL;
+        if (b->d) {
+            OPENSSL_cleanse(b->d, b->dmax * sizeof(b->d[0]));
+            bn_free_d(b);
+        }
+        b->d = a;
+        b->dmax = words;
+    }
+
+    bn_check_top(b);
+    return b;
+}
+
+BIGNUM *BN_dup(const BIGNUM *a)
+{
+    BIGNUM *t;
+
+    if (a == NULL)
+        return NULL;
+    bn_check_top(a);
+
+    t = BN_get_flags(a, BN_FLG_SECURE) ? BN_secure_new() : BN_new();
+    if (t == NULL)
+        return NULL;
+    if (!BN_copy(t, a)) {
+        BN_free(t);
+        return NULL;
+    }
+    bn_check_top(t);
+    return t;
+}
+
+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
+{
+    int i;
+    BN_ULONG *A;
+    const BN_ULONG *B;
+
+    bn_check_top(b);
+
+    if (a == b)
+        return (a);
+    if (bn_wexpand(a, b->top) == NULL)
+        return (NULL);
+
+#if 1
+    A = a->d;
+    B = b->d;
+    for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) {
+        BN_ULONG a0, a1, a2, a3;
+        a0 = B[0];
+        a1 = B[1];
+        a2 = B[2];
+        a3 = B[3];
+        A[0] = a0;
+        A[1] = a1;
+        A[2] = a2;
+        A[3] = a3;
+    }
+    /* ultrix cc workaround, see comments in bn_expand_internal */
+    switch (b->top & 3) {
+    case 3:
+        A[2] = B[2];
+    case 2:
+        A[1] = B[1];
+    case 1:
+        A[0] = B[0];
+    case 0:;
+    }
+#else
+    memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);
+#endif
+
+    a->top = b->top;
+    a->neg = b->neg;
+    bn_check_top(a);
+    return (a);
+}
+
+void BN_swap(BIGNUM *a, BIGNUM *b)
+{
+    int flags_old_a, flags_old_b;
+    BN_ULONG *tmp_d;
+    int tmp_top, tmp_dmax, tmp_neg;
+
+    bn_check_top(a);
+    bn_check_top(b);
+
+    flags_old_a = a->flags;
+    flags_old_b = b->flags;
+
+    tmp_d = a->d;
+    tmp_top = a->top;
+    tmp_dmax = a->dmax;
+    tmp_neg = a->neg;
+
+    a->d = b->d;
+    a->top = b->top;
+    a->dmax = b->dmax;
+    a->neg = b->neg;
+
+    b->d = tmp_d;
+    b->top = tmp_top;
+    b->dmax = tmp_dmax;
+    b->neg = tmp_neg;
+
+    a->flags =
+        (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
+    b->flags =
+        (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
+    bn_check_top(a);
+    bn_check_top(b);
+}
+
+void BN_clear(BIGNUM *a)
+{
+    bn_check_top(a);
+    if (a->d != NULL)
+        OPENSSL_cleanse(a->d, sizeof(*a->d) * a->dmax);
+    a->top = 0;
+    a->neg = 0;
+}
+
+BN_ULONG BN_get_word(const BIGNUM *a)
+{
+    if (a->top > 1)
+        return BN_MASK2;
+    else if (a->top == 1)
+        return a->d[0];
+    /* a->top == 0 */
+    return 0;
+}
+
+int BN_set_word(BIGNUM *a, BN_ULONG w)
+{
+    bn_check_top(a);
+    if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL)
+        return (0);
+    a->neg = 0;
+    a->d[0] = w;
+    a->top = (w ? 1 : 0);
+    bn_check_top(a);
+    return (1);
+}
+
+BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
+{
+    unsigned int i, m;
+    unsigned int n;
+    BN_ULONG l;
+    BIGNUM *bn = NULL;
+
+    if (ret == NULL)
+        ret = bn = BN_new();
+    if (ret == NULL)
+        return (NULL);
+    bn_check_top(ret);
+    /* Skip leading zero's. */
+    for ( ; len > 0 && *s == 0; s++, len--)
+        continue;
+    n = len;
+    if (n == 0) {
+        ret->top = 0;
+        return (ret);
+    }
+    i = ((n - 1) / BN_BYTES) + 1;
+    m = ((n - 1) % (BN_BYTES));
+    if (bn_wexpand(ret, (int)i) == NULL) {
+        BN_free(bn);
+        return NULL;
+    }
+    ret->top = i;
+    ret->neg = 0;
+    l = 0;
+    while (n--) {
+        l = (l << 8L) | *(s++);
+        if (m-- == 0) {
+            ret->d[--i] = l;
+            l = 0;
+            m = BN_BYTES - 1;
+        }
+    }
+    /*
+     * need to call this due to clear byte at top if avoiding having the top
+     * bit set (-ve number)
+     */
+    bn_correct_top(ret);
+    return (ret);
+}
+
+/* ignore negative */
+static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
+{
+    int i;
+    BN_ULONG l;
+
+    bn_check_top(a);
+    i = BN_num_bytes(a);
+    if (tolen == -1)
+        tolen = i;
+    else if (tolen < i)
+        return -1;
+    /* Add leading zeroes if necessary */
+    if (tolen > i) {
+        memset(to, 0, tolen - i);
+        to += tolen - i;
+    }
+    while (i--) {
+        l = a->d[i / BN_BYTES];
+        *(to++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff;
+    }
+    return tolen;
+}
+
+int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
+{
+    if (tolen < 0)
+        return -1;
+    return bn2binpad(a, to, tolen);
+}
+
+int BN_bn2bin(const BIGNUM *a, unsigned char *to)
+{
+    return bn2binpad(a, to, -1);
+}
+
+BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret)
+{
+    unsigned int i, m;
+    unsigned int n;
+    BN_ULONG l;
+    BIGNUM *bn = NULL;
+
+    if (ret == NULL)
+        ret = bn = BN_new();
+    if (ret == NULL)
+        return (NULL);
+    bn_check_top(ret);
+    s += len;
+    /* Skip trailing zeroes. */
+    for ( ; len > 0 && s[-1] == 0; s--, len--)
+        continue;
+    n = len;
+    if (n == 0) {
+        ret->top = 0;
+        return ret;
+    }
+    i = ((n - 1) / BN_BYTES) + 1;
+    m = ((n - 1) % (BN_BYTES));
+    if (bn_wexpand(ret, (int)i) == NULL) {
+        BN_free(bn);
+        return NULL;
+    }
+    ret->top = i;
+    ret->neg = 0;
+    l = 0;
+    while (n--) {
+        s--;
+        l = (l << 8L) | *s;
+        if (m-- == 0) {
+            ret->d[--i] = l;
+            l = 0;
+            m = BN_BYTES - 1;
+        }
+    }
+    /*
+     * need to call this due to clear byte at top if avoiding having the top
+     * bit set (-ve number)
+     */
+    bn_correct_top(ret);
+    return ret;
+}
+
+int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen)
+{
+    int i;
+    BN_ULONG l;
+    bn_check_top(a);
+    i = BN_num_bytes(a);
+    if (tolen < i)
+        return -1;
+    /* Add trailing zeroes if necessary */
+    if (tolen > i)
+        memset(to + i, 0, tolen - i);
+    to += i;
+    while (i--) {
+        l = a->d[i / BN_BYTES];
+        to--;
+        *to = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff;
+    }
+    return tolen;
+}
+
+int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
+{
+    int i;
+    BN_ULONG t1, t2, *ap, *bp;
+
+    bn_check_top(a);
+    bn_check_top(b);
+
+    i = a->top - b->top;
+    if (i != 0)
+        return (i);
+    ap = a->d;
+    bp = b->d;
+    for (i = a->top - 1; i >= 0; i--) {
+        t1 = ap[i];
+        t2 = bp[i];
+        if (t1 != t2)
+            return ((t1 > t2) ? 1 : -1);
+    }
+    return (0);
+}
+
+int BN_cmp(const BIGNUM *a, const BIGNUM *b)
+{
+    int i;
+    int gt, lt;
+    BN_ULONG t1, t2;
+
+    if ((a == NULL) || (b == NULL)) {
+        if (a != NULL)
+            return (-1);
+        else if (b != NULL)
+            return (1);
+        else
+            return (0);
+    }
+
+    bn_check_top(a);
+    bn_check_top(b);
+
+    if (a->neg != b->neg) {
+        if (a->neg)
+            return (-1);
+        else
+            return (1);
+    }
+    if (a->neg == 0) {
+        gt = 1;
+        lt = -1;
+    } else {
+        gt = -1;
+        lt = 1;
+    }
+
+    if (a->top > b->top)
+        return (gt);
+    if (a->top < b->top)
+        return (lt);
+    for (i = a->top - 1; i >= 0; i--) {
+        t1 = a->d[i];
+        t2 = b->d[i];
+        if (t1 > t2)
+            return (gt);
+        if (t1 < t2)
+            return (lt);
+    }
+    return (0);
+}
+
+int BN_set_bit(BIGNUM *a, int n)
+{
+    int i, j, k;
+
+    if (n < 0)
+        return 0;
+
+    i = n / BN_BITS2;
+    j = n % BN_BITS2;
+    if (a->top <= i) {
+        if (bn_wexpand(a, i + 1) == NULL)
+            return (0);
+        for (k = a->top; k < i + 1; k++)
+            a->d[k] = 0;
+        a->top = i + 1;
+    }
+
+    a->d[i] |= (((BN_ULONG)1) << j);
+    bn_check_top(a);
+    return (1);
+}
+
+int BN_clear_bit(BIGNUM *a, int n)
+{
+    int i, j;
+
+    bn_check_top(a);
+    if (n < 0)
+        return 0;
+
+    i = n / BN_BITS2;
+    j = n % BN_BITS2;
+    if (a->top <= i)
+        return (0);
+
+    a->d[i] &= (~(((BN_ULONG)1) << j));
+    bn_correct_top(a);
+    return (1);
+}
+
+int BN_is_bit_set(const BIGNUM *a, int n)
+{
+    int i, j;
+
+    bn_check_top(a);
+    if (n < 0)
+        return 0;
+    i = n / BN_BITS2;
+    j = n % BN_BITS2;
+    if (a->top <= i)
+        return 0;
+    return (int)(((a->d[i]) >> j) & ((BN_ULONG)1));
+}
+
+int BN_mask_bits(BIGNUM *a, int n)
+{
+    int b, w;
+
+    bn_check_top(a);
+    if (n < 0)
+        return 0;
+
+    w = n / BN_BITS2;
+    b = n % BN_BITS2;
+    if (w >= a->top)
+        return 0;
+    if (b == 0)
+        a->top = w;
+    else {
+        a->top = w + 1;
+        a->d[w] &= ~(BN_MASK2 << b);
+    }
+    bn_correct_top(a);
+    return (1);
+}
+
+void BN_set_negative(BIGNUM *a, int b)
+{
+    if (b && !BN_is_zero(a))
+        a->neg = 1;
+    else
+        a->neg = 0;
+}
+
+int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
+{
+    int i;
+    BN_ULONG aa, bb;
+
+    aa = a[n - 1];
+    bb = b[n - 1];
+    if (aa != bb)
+        return ((aa > bb) ? 1 : -1);
+    for (i = n - 2; i >= 0; i--) {
+        aa = a[i];
+        bb = b[i];
+        if (aa != bb)
+            return ((aa > bb) ? 1 : -1);
+    }
+    return (0);
+}
+
+/*
+ * Here follows a specialised variants of bn_cmp_words().  It has the
+ * capability of performing the operation on arrays of different sizes. The
+ * sizes of those arrays is expressed through cl, which is the common length
+ * ( basically, min(len(a),len(b)) ), and dl, which is the delta between the
+ * two lengths, calculated as len(a)-len(b). All lengths are the number of
+ * BN_ULONGs...
+ */
+
+int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl)
+{
+    int n, i;
+    n = cl - 1;
+
+    if (dl < 0) {
+        for (i = dl; i < 0; i++) {
+            if (b[n - i] != 0)
+                return -1;      /* a < b */
+        }
+    }
+    if (dl > 0) {
+        for (i = dl; i > 0; i--) {
+            if (a[n + i] != 0)
+                return 1;       /* a > b */
+        }
+    }
+    return bn_cmp_words(a, b, cl);
+}
+
+/*
+ * Constant-time conditional swap of a and b.
+ * a and b are swapped if condition is not 0.  The code assumes that at most one bit of condition is set.
+ * nwords is the number of words to swap.  The code assumes that at least nwords are allocated in both a and b,
+ * and that no more than nwords are used by either a or b.
+ * a and b cannot be the same number
+ */
+void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
+{
+    BN_ULONG t;
+    int i;
+
+    bn_wcheck_size(a, nwords);
+    bn_wcheck_size(b, nwords);
+
+    assert(a != b);
+    assert((condition & (condition - 1)) == 0);
+    assert(sizeof(BN_ULONG) >= sizeof(int));
+
+    condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1;
+
+    t = (a->top ^ b->top) & condition;
+    a->top ^= t;
+    b->top ^= t;
+
+#define BN_CONSTTIME_SWAP(ind) \
+        do { \
+                t = (a->d[ind] ^ b->d[ind]) & condition; \
+                a->d[ind] ^= t; \
+                b->d[ind] ^= t; \
+        } while (0)
+
+    switch (nwords) {
+    default:
+        for (i = 10; i < nwords; i++)
+            BN_CONSTTIME_SWAP(i);
+        /* Fallthrough */
+    case 10:
+        BN_CONSTTIME_SWAP(9);   /* Fallthrough */
+    case 9:
+        BN_CONSTTIME_SWAP(8);   /* Fallthrough */
+    case 8:
+        BN_CONSTTIME_SWAP(7);   /* Fallthrough */
+    case 7:
+        BN_CONSTTIME_SWAP(6);   /* Fallthrough */
+    case 6:
+        BN_CONSTTIME_SWAP(5);   /* Fallthrough */
+    case 5:
+        BN_CONSTTIME_SWAP(4);   /* Fallthrough */
+    case 4:
+        BN_CONSTTIME_SWAP(3);   /* Fallthrough */
+    case 3:
+        BN_CONSTTIME_SWAP(2);   /* Fallthrough */
+    case 2:
+        BN_CONSTTIME_SWAP(1);   /* Fallthrough */
+    case 1:
+        BN_CONSTTIME_SWAP(0);
+    }
+#undef BN_CONSTTIME_SWAP
+}
+
+/* Bits of security, see SP800-57 */
+
+int BN_security_bits(int L, int N)
+{
+    int secbits, bits;
+    if (L >= 15360)
+        secbits = 256;
+    else if (L >= 7690)
+        secbits = 192;
+    else if (L >= 3072)
+        secbits = 128;
+    else if (L >= 2048)
+        secbits = 112;
+    else if (L >= 1024)
+        secbits = 80;
+    else
+        return 0;
+    if (N == -1)
+        return secbits;
+    bits = N / 2;
+    if (bits < 80)
+        return 0;
+    return bits >= secbits ? secbits : bits;
+}
+
+void BN_zero_ex(BIGNUM *a)
+{
+    a->top = 0;
+    a->neg = 0;
+}
+
+int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w)
+{
+    return ((a->top == 1) && (a->d[0] == w)) || ((w == 0) && (a->top == 0));
+}
+
+int BN_is_zero(const BIGNUM *a)
+{
+    return a->top == 0;
+}
+
+int BN_is_one(const BIGNUM *a)
+{
+    return BN_abs_is_word(a, 1) && !a->neg;
+}
+
+int BN_is_word(const BIGNUM *a, const BN_ULONG w)
+{
+    return BN_abs_is_word(a, w) && (!w || !a->neg);
+}
+
+int BN_is_odd(const BIGNUM *a)
+{
+    return (a->top > 0) && (a->d[0] & 1);
+}
+
+int BN_is_negative(const BIGNUM *a)
+{
+    return (a->neg != 0);
+}
+
+int BN_to_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
+                     BN_CTX *ctx)
+{
+    return BN_mod_mul_montgomery(r, a, &(mont->RR), mont, ctx);
+}
+
+void BN_with_flags(BIGNUM *dest, const BIGNUM *b, int flags)
+{
+    dest->d = b->d;
+    dest->top = b->top;
+    dest->dmax = b->dmax;
+    dest->neg = b->neg;
+    dest->flags = ((dest->flags & BN_FLG_MALLOCED)
+                   | (b->flags & ~BN_FLG_MALLOCED)
+                   | BN_FLG_STATIC_DATA | flags);
+}
+
+BN_GENCB *BN_GENCB_new(void)
+{
+    BN_GENCB *ret;
+
+    if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) {
+        BNerr(BN_F_BN_GENCB_NEW, ERR_R_MALLOC_FAILURE);
+        return (NULL);
+    }
+
+    return ret;
+}
+
+void BN_GENCB_free(BN_GENCB *cb)
+{
+    if (cb == NULL)
+        return;
+    OPENSSL_free(cb);
+}
+
+void BN_set_flags(BIGNUM *b, int n)
+{
+    b->flags |= n;
+}
+
+int BN_get_flags(const BIGNUM *b, int n)
+{
+    return b->flags & n;
+}
+
+/* Populate a BN_GENCB structure with an "old"-style callback */
+void BN_GENCB_set_old(BN_GENCB *gencb, void (*callback) (int, int, void *),
+                      void *cb_arg)
+{
+    BN_GENCB *tmp_gencb = gencb;
+    tmp_gencb->ver = 1;
+    tmp_gencb->arg = cb_arg;
+    tmp_gencb->cb.cb_1 = callback;
+}
+
+/* Populate a BN_GENCB structure with a "new"-style callback */
+void BN_GENCB_set(BN_GENCB *gencb, int (*callback) (int, int, BN_GENCB *),
+                  void *cb_arg)
+{
+    BN_GENCB *tmp_gencb = gencb;
+    tmp_gencb->ver = 2;
+    tmp_gencb->arg = cb_arg;
+    tmp_gencb->cb.cb_2 = callback;
+}
+
+void *BN_GENCB_get_arg(BN_GENCB *cb)
+{
+    return cb->arg;
+}
+
+BIGNUM *bn_wexpand(BIGNUM *a, int words)
+{
+    return (words <= a->dmax) ? a : bn_expand2(a, words);
+}
+
+void bn_correct_top(BIGNUM *a)
+{
+    BN_ULONG *ftl;
+    int tmp_top = a->top;
+
+    if (tmp_top > 0) {
+        for (ftl = &(a->d[tmp_top]); tmp_top > 0; tmp_top--) {
+            ftl--;
+            if (*ftl != 0)
+                break;
+        }
+        a->top = tmp_top;
+    }
+    if (a->top == 0)
+        a->neg = 0;
+    bn_pollute(a);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_mod.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_mod.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_mod.c	(revision 331)
@@ -0,0 +1,201 @@
+/*
+ * Copyright 1998-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 "internal/cryptlib.h"
+#include "bn_lcl.h"
+
+int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx)
+{
+    /*
+     * like BN_mod, but returns non-negative remainder (i.e., 0 <= r < |d|
+     * always holds)
+     */
+
+    if (!(BN_mod(r, m, d, ctx)))
+        return 0;
+    if (!r->neg)
+        return 1;
+    /* now   -|d| < r < 0,  so we have to set  r := r + |d| */
+    return (d->neg ? BN_sub : BN_add) (r, r, d);
+}
+
+int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+               BN_CTX *ctx)
+{
+    if (!BN_add(r, a, b))
+        return 0;
+    return BN_nnmod(r, r, m, ctx);
+}
+
+/*
+ * BN_mod_add variant that may be used if both a and b are non-negative and
+ * less than m
+ */
+int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                     const BIGNUM *m)
+{
+    if (!BN_uadd(r, a, b))
+        return 0;
+    if (BN_ucmp(r, m) >= 0)
+        return BN_usub(r, r, m);
+    return 1;
+}
+
+int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+               BN_CTX *ctx)
+{
+    if (!BN_sub(r, a, b))
+        return 0;
+    return BN_nnmod(r, r, m, ctx);
+}
+
+/*
+ * BN_mod_sub variant that may be used if both a and b are non-negative and
+ * less than m
+ */
+int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                     const BIGNUM *m)
+{
+    if (!BN_sub(r, a, b))
+        return 0;
+    if (r->neg)
+        return BN_add(r, r, m);
+    return 1;
+}
+
+/* slow but works */
+int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+               BN_CTX *ctx)
+{
+    BIGNUM *t;
+    int ret = 0;
+
+    bn_check_top(a);
+    bn_check_top(b);
+    bn_check_top(m);
+
+    BN_CTX_start(ctx);
+    if ((t = BN_CTX_get(ctx)) == NULL)
+        goto err;
+    if (a == b) {
+        if (!BN_sqr(t, a, ctx))
+            goto err;
+    } else {
+        if (!BN_mul(t, a, b, ctx))
+            goto err;
+    }
+    if (!BN_nnmod(r, t, m, ctx))
+        goto err;
+    bn_check_top(r);
+    ret = 1;
+ err:
+    BN_CTX_end(ctx);
+    return (ret);
+}
+
+int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
+{
+    if (!BN_sqr(r, a, ctx))
+        return 0;
+    /* r->neg == 0,  thus we don't need BN_nnmod */
+    return BN_mod(r, r, m, ctx);
+}
+
+int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx)
+{
+    if (!BN_lshift1(r, a))
+        return 0;
+    bn_check_top(r);
+    return BN_nnmod(r, r, m, ctx);
+}
+
+/*
+ * BN_mod_lshift1 variant that may be used if a is non-negative and less than
+ * m
+ */
+int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m)
+{
+    if (!BN_lshift1(r, a))
+        return 0;
+    bn_check_top(r);
+    if (BN_cmp(r, m) >= 0)
+        return BN_sub(r, r, m);
+    return 1;
+}
+
+int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m,
+                  BN_CTX *ctx)
+{
+    BIGNUM *abs_m = NULL;
+    int ret;
+
+    if (!BN_nnmod(r, a, m, ctx))
+        return 0;
+
+    if (m->neg) {
+        abs_m = BN_dup(m);
+        if (abs_m == NULL)
+            return 0;
+        abs_m->neg = 0;
+    }
+
+    ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m));
+    bn_check_top(r);
+
+    BN_free(abs_m);
+    return ret;
+}
+
+/*
+ * BN_mod_lshift variant that may be used if a is non-negative and less than
+ * m
+ */
+int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m)
+{
+    if (r != a) {
+        if (BN_copy(r, a) == NULL)
+            return 0;
+    }
+
+    while (n > 0) {
+        int max_shift;
+
+        /* 0 < r < m */
+        max_shift = BN_num_bits(m) - BN_num_bits(r);
+        /* max_shift >= 0 */
+
+        if (max_shift < 0) {
+            BNerr(BN_F_BN_MOD_LSHIFT_QUICK, BN_R_INPUT_NOT_REDUCED);
+            return 0;
+        }
+
+        if (max_shift > n)
+            max_shift = n;
+
+        if (max_shift) {
+            if (!BN_lshift(r, r, max_shift))
+                return 0;
+            n -= max_shift;
+        } else {
+            if (!BN_lshift1(r, r))
+                return 0;
+            --n;
+        }
+
+        /* BN_num_bits(r) <= BN_num_bits(m) */
+
+        if (BN_cmp(r, m) >= 0) {
+            if (!BN_sub(r, r, m))
+                return 0;
+        }
+    }
+    bn_check_top(r);
+
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_mont.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_mont.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_mont.c	(revision 331)
@@ -0,0 +1,434 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*
+ * Details about Montgomery multiplication algorithms can be found at
+ * http://security.ece.orst.edu/publications.html, e.g.
+ * http://security.ece.orst.edu/koc/papers/j37acmon.pdf and
+ * sections 3.8 and 4.2 in http://security.ece.orst.edu/koc/papers/r01rsasw.pdf
+ */
+
+#include "internal/cryptlib.h"
+#include "bn_lcl.h"
+
+#define MONT_WORD               /* use the faster word-based algorithm */
+
+#ifdef MONT_WORD
+static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont);
+#endif
+
+int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                          BN_MONT_CTX *mont, BN_CTX *ctx)
+{
+    BIGNUM *tmp;
+    int ret = 0;
+#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD)
+    int num = mont->N.top;
+
+    if (num > 1 && a->top == num && b->top == num) {
+        if (bn_wexpand(r, num) == NULL)
+            return (0);
+        if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) {
+            r->neg = a->neg ^ b->neg;
+            r->top = num;
+            bn_correct_top(r);
+            return (1);
+        }
+    }
+#endif
+
+    BN_CTX_start(ctx);
+    tmp = BN_CTX_get(ctx);
+    if (tmp == NULL)
+        goto err;
+
+    bn_check_top(tmp);
+    if (a == b) {
+        if (!BN_sqr(tmp, a, ctx))
+            goto err;
+    } else {
+        if (!BN_mul(tmp, a, b, ctx))
+            goto err;
+    }
+    /* reduce from aRR to aR */
+#ifdef MONT_WORD
+    if (!BN_from_montgomery_word(r, tmp, mont))
+        goto err;
+#else
+    if (!BN_from_montgomery(r, tmp, mont, ctx))
+        goto err;
+#endif
+    bn_check_top(r);
+    ret = 1;
+ err:
+    BN_CTX_end(ctx);
+    return (ret);
+}
+
+#ifdef MONT_WORD
+static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
+{
+    BIGNUM *n;
+    BN_ULONG *ap, *np, *rp, n0, v, carry;
+    int nl, max, i;
+
+    n = &(mont->N);
+    nl = n->top;
+    if (nl == 0) {
+        ret->top = 0;
+        return (1);
+    }
+
+    max = (2 * nl);             /* carry is stored separately */
+    if (bn_wexpand(r, max) == NULL)
+        return (0);
+
+    r->neg ^= n->neg;
+    np = n->d;
+    rp = r->d;
+
+    /* clear the top words of T */
+    i = max - r->top;
+    if (i)
+        memset(&rp[r->top], 0, sizeof(*rp) * i);
+
+    r->top = max;
+    n0 = mont->n0[0];
+
+    for (carry = 0, i = 0; i < nl; i++, rp++) {
+        v = bn_mul_add_words(rp, np, nl, (rp[0] * n0) & BN_MASK2);
+        v = (v + carry + rp[nl]) & BN_MASK2;
+        carry |= (v != rp[nl]);
+        carry &= (v <= rp[nl]);
+        rp[nl] = v;
+    }
+
+    if (bn_wexpand(ret, nl) == NULL)
+        return (0);
+    ret->top = nl;
+    ret->neg = r->neg;
+
+    rp = ret->d;
+    ap = &(r->d[nl]);
+
+# define BRANCH_FREE 1
+# if BRANCH_FREE
+    {
+        BN_ULONG *nrp;
+        size_t m;
+
+        v = bn_sub_words(rp, ap, np, nl) - carry;
+        /*
+         * if subtraction result is real, then trick unconditional memcpy
+         * below to perform in-place "refresh" instead of actual copy.
+         */
+        m = (0 - (size_t)v);
+        nrp =
+            (BN_ULONG *)(((PTR_SIZE_INT) rp & ~m) | ((PTR_SIZE_INT) ap & m));
+
+        for (i = 0, nl -= 4; i < nl; i += 4) {
+            BN_ULONG t1, t2, t3, t4;
+
+            t1 = nrp[i + 0];
+            t2 = nrp[i + 1];
+            t3 = nrp[i + 2];
+            ap[i + 0] = 0;
+            t4 = nrp[i + 3];
+            ap[i + 1] = 0;
+            rp[i + 0] = t1;
+            ap[i + 2] = 0;
+            rp[i + 1] = t2;
+            ap[i + 3] = 0;
+            rp[i + 2] = t3;
+            rp[i + 3] = t4;
+        }
+        for (nl += 4; i < nl; i++)
+            rp[i] = nrp[i], ap[i] = 0;
+    }
+# else
+    if (bn_sub_words(rp, ap, np, nl) - carry)
+        memcpy(rp, ap, nl * sizeof(BN_ULONG));
+# endif
+    bn_correct_top(r);
+    bn_correct_top(ret);
+    bn_check_top(ret);
+
+    return (1);
+}
+#endif                          /* MONT_WORD */
+
+int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont,
+                       BN_CTX *ctx)
+{
+    int retn = 0;
+#ifdef MONT_WORD
+    BIGNUM *t;
+
+    BN_CTX_start(ctx);
+    if ((t = BN_CTX_get(ctx)) && BN_copy(t, a))
+        retn = BN_from_montgomery_word(ret, t, mont);
+    BN_CTX_end(ctx);
+#else                           /* !MONT_WORD */
+    BIGNUM *t1, *t2;
+
+    BN_CTX_start(ctx);
+    t1 = BN_CTX_get(ctx);
+    t2 = BN_CTX_get(ctx);
+    if (t1 == NULL || t2 == NULL)
+        goto err;
+
+    if (!BN_copy(t1, a))
+        goto err;
+    BN_mask_bits(t1, mont->ri);
+
+    if (!BN_mul(t2, t1, &mont->Ni, ctx))
+        goto err;
+    BN_mask_bits(t2, mont->ri);
+
+    if (!BN_mul(t1, t2, &mont->N, ctx))
+        goto err;
+    if (!BN_add(t2, a, t1))
+        goto err;
+    if (!BN_rshift(ret, t2, mont->ri))
+        goto err;
+
+    if (BN_ucmp(ret, &(mont->N)) >= 0) {
+        if (!BN_usub(ret, ret, &(mont->N)))
+            goto err;
+    }
+    retn = 1;
+    bn_check_top(ret);
+ err:
+    BN_CTX_end(ctx);
+#endif                          /* MONT_WORD */
+    return (retn);
+}
+
+BN_MONT_CTX *BN_MONT_CTX_new(void)
+{
+    BN_MONT_CTX *ret;
+
+    if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)
+        return (NULL);
+
+    BN_MONT_CTX_init(ret);
+    ret->flags = BN_FLG_MALLOCED;
+    return (ret);
+}
+
+void BN_MONT_CTX_init(BN_MONT_CTX *ctx)
+{
+    ctx->ri = 0;
+    bn_init(&(ctx->RR));
+    bn_init(&(ctx->N));
+    bn_init(&(ctx->Ni));
+    ctx->n0[0] = ctx->n0[1] = 0;
+    ctx->flags = 0;
+}
+
+void BN_MONT_CTX_free(BN_MONT_CTX *mont)
+{
+    if (mont == NULL)
+        return;
+
+    BN_clear_free(&(mont->RR));
+    BN_clear_free(&(mont->N));
+    BN_clear_free(&(mont->Ni));
+    if (mont->flags & BN_FLG_MALLOCED)
+        OPENSSL_free(mont);
+}
+
+int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
+{
+    int ret = 0;
+    BIGNUM *Ri, *R;
+
+    if (BN_is_zero(mod))
+        return 0;
+
+    BN_CTX_start(ctx);
+    if ((Ri = BN_CTX_get(ctx)) == NULL)
+        goto err;
+    R = &(mont->RR);            /* grab RR as a temp */
+    if (!BN_copy(&(mont->N), mod))
+        goto err;               /* Set N */
+    mont->N.neg = 0;
+
+#ifdef MONT_WORD
+    {
+        BIGNUM tmod;
+        BN_ULONG buf[2];
+
+        bn_init(&tmod);
+        tmod.d = buf;
+        tmod.dmax = 2;
+        tmod.neg = 0;
+
+        mont->ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2;
+
+# if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32)
+        /*
+         * Only certain BN_BITS2<=32 platforms actually make use of n0[1],
+         * and we could use the #else case (with a shorter R value) for the
+         * others.  However, currently only the assembler files do know which
+         * is which.
+         */
+
+        BN_zero(R);
+        if (!(BN_set_bit(R, 2 * BN_BITS2)))
+            goto err;
+
+        tmod.top = 0;
+        if ((buf[0] = mod->d[0]))
+            tmod.top = 1;
+        if ((buf[1] = mod->top > 1 ? mod->d[1] : 0))
+            tmod.top = 2;
+
+        if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL)
+            goto err;
+        if (!BN_lshift(Ri, Ri, 2 * BN_BITS2))
+            goto err;           /* R*Ri */
+        if (!BN_is_zero(Ri)) {
+            if (!BN_sub_word(Ri, 1))
+                goto err;
+        } else {                /* if N mod word size == 1 */
+
+            if (bn_expand(Ri, (int)sizeof(BN_ULONG) * 2) == NULL)
+                goto err;
+            /* Ri-- (mod double word size) */
+            Ri->neg = 0;
+            Ri->d[0] = BN_MASK2;
+            Ri->d[1] = BN_MASK2;
+            Ri->top = 2;
+        }
+        if (!BN_div(Ri, NULL, Ri, &tmod, ctx))
+            goto err;
+        /*
+         * Ni = (R*Ri-1)/N, keep only couple of least significant words:
+         */
+        mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
+        mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0;
+# else
+        BN_zero(R);
+        if (!(BN_set_bit(R, BN_BITS2)))
+            goto err;           /* R */
+
+        buf[0] = mod->d[0];     /* tmod = N mod word size */
+        buf[1] = 0;
+        tmod.top = buf[0] != 0 ? 1 : 0;
+        /* Ri = R^-1 mod N */
+        if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL)
+            goto err;
+        if (!BN_lshift(Ri, Ri, BN_BITS2))
+            goto err;           /* R*Ri */
+        if (!BN_is_zero(Ri)) {
+            if (!BN_sub_word(Ri, 1))
+                goto err;
+        } else {                /* if N mod word size == 1 */
+
+            if (!BN_set_word(Ri, BN_MASK2))
+                goto err;       /* Ri-- (mod word size) */
+        }
+        if (!BN_div(Ri, NULL, Ri, &tmod, ctx))
+            goto err;
+        /*
+         * Ni = (R*Ri-1)/N, keep only least significant word:
+         */
+        mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0;
+        mont->n0[1] = 0;
+# endif
+    }
+#else                           /* !MONT_WORD */
+    {                           /* bignum version */
+        mont->ri = BN_num_bits(&mont->N);
+        BN_zero(R);
+        if (!BN_set_bit(R, mont->ri))
+            goto err;           /* R = 2^ri */
+        /* Ri = R^-1 mod N */
+        if ((BN_mod_inverse(Ri, R, &mont->N, ctx)) == NULL)
+            goto err;
+        if (!BN_lshift(Ri, Ri, mont->ri))
+            goto err;           /* R*Ri */
+        if (!BN_sub_word(Ri, 1))
+            goto err;
+        /*
+         * Ni = (R*Ri-1) / N
+         */
+        if (!BN_div(&(mont->Ni), NULL, Ri, &mont->N, ctx))
+            goto err;
+    }
+#endif
+
+    /* setup RR for conversions */
+    BN_zero(&(mont->RR));
+    if (!BN_set_bit(&(mont->RR), mont->ri * 2))
+        goto err;
+    if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx))
+        goto err;
+
+    ret = 1;
+ err:
+    BN_CTX_end(ctx);
+    return ret;
+}
+
+BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from)
+{
+    if (to == from)
+        return (to);
+
+    if (!BN_copy(&(to->RR), &(from->RR)))
+        return NULL;
+    if (!BN_copy(&(to->N), &(from->N)))
+        return NULL;
+    if (!BN_copy(&(to->Ni), &(from->Ni)))
+        return NULL;
+    to->ri = from->ri;
+    to->n0[0] = from->n0[0];
+    to->n0[1] = from->n0[1];
+    return (to);
+}
+
+BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_RWLOCK *lock,
+                                    const BIGNUM *mod, BN_CTX *ctx)
+{
+    BN_MONT_CTX *ret;
+
+    CRYPTO_THREAD_read_lock(lock);
+    ret = *pmont;
+    CRYPTO_THREAD_unlock(lock);
+    if (ret)
+        return ret;
+
+    /*
+     * We don't want to serialise globally while doing our lazy-init math in
+     * BN_MONT_CTX_set. That punishes threads that are doing independent
+     * things. Instead, punish the case where more than one thread tries to
+     * lazy-init the same 'pmont', by having each do the lazy-init math work
+     * independently and only use the one from the thread that wins the race
+     * (the losers throw away the work they've done).
+     */
+    ret = BN_MONT_CTX_new();
+    if (ret == NULL)
+        return NULL;
+    if (!BN_MONT_CTX_set(ret, mod, ctx)) {
+        BN_MONT_CTX_free(ret);
+        return NULL;
+    }
+
+    /* The locked compare-and-set, after the local work is done. */
+    CRYPTO_THREAD_write_lock(lock);
+    if (*pmont) {
+        BN_MONT_CTX_free(ret);
+        ret = *pmont;
+    } else
+        *pmont = ret;
+    CRYPTO_THREAD_unlock(lock);
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_mpi.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_mpi.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_mpi.c	(revision 331)
@@ -0,0 +1,86 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include "bn_lcl.h"
+
+int BN_bn2mpi(const BIGNUM *a, unsigned char *d)
+{
+    int bits;
+    int num = 0;
+    int ext = 0;
+    long l;
+
+    bits = BN_num_bits(a);
+    num = (bits + 7) / 8;
+    if (bits > 0) {
+        ext = ((bits & 0x07) == 0);
+    }
+    if (d == NULL)
+        return (num + 4 + ext);
+
+    l = num + ext;
+    d[0] = (unsigned char)(l >> 24) & 0xff;
+    d[1] = (unsigned char)(l >> 16) & 0xff;
+    d[2] = (unsigned char)(l >> 8) & 0xff;
+    d[3] = (unsigned char)(l) & 0xff;
+    if (ext)
+        d[4] = 0;
+    num = BN_bn2bin(a, &(d[4 + ext]));
+    if (a->neg)
+        d[4] |= 0x80;
+    return (num + 4 + ext);
+}
+
+BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *ain)
+{
+    long len;
+    int neg = 0;
+    BIGNUM *a = NULL;
+
+    if (n < 4) {
+        BNerr(BN_F_BN_MPI2BN, BN_R_INVALID_LENGTH);
+        return NULL;
+    }
+    len = ((long)d[0] << 24) | ((long)d[1] << 16) | ((int)d[2] << 8) | (int)
+        d[3];
+    if ((len + 4) != n) {
+        BNerr(BN_F_BN_MPI2BN, BN_R_ENCODING_ERROR);
+        return NULL;
+    }
+
+    if (ain == NULL)
+        a = BN_new();
+    else
+        a = ain;
+
+    if (a == NULL)
+        return NULL;
+
+    if (len == 0) {
+        a->neg = 0;
+        a->top = 0;
+        return a;
+    }
+    d += 4;
+    if ((*d) & 0x80)
+        neg = 1;
+    if (BN_bin2bn(d, (int)len, a) == NULL) {
+        if (ain == NULL)
+            BN_free(a);
+        return NULL;
+    }
+    a->neg = neg;
+    if (neg) {
+        BN_clear_bit(a, BN_num_bits(a) - 1);
+    }
+    bn_check_top(a);
+    return a;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_mul.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_mul.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_mul.c	(revision 331)
@@ -0,0 +1,1045 @@
+/*
+ * Copyright 1995-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 <assert.h>
+#include "internal/cryptlib.h"
+#include "bn_lcl.h"
+
+#if defined(OPENSSL_NO_ASM) || !defined(OPENSSL_BN_ASM_PART_WORDS)
+/*
+ * Here follows specialised variants of bn_add_words() and bn_sub_words().
+ * They have the property performing operations on arrays of different sizes.
+ * The sizes of those arrays is expressed through cl, which is the common
+ * length ( basically, min(len(a),len(b)) ), and dl, which is the delta
+ * between the two lengths, calculated as len(a)-len(b). All lengths are the
+ * number of BN_ULONGs...  For the operations that require a result array as
+ * parameter, it must have the length cl+abs(dl). These functions should
+ * probably end up in bn_asm.c as soon as there are assembler counterparts
+ * for the systems that use assembler files.
+ */
+
+BN_ULONG bn_sub_part_words(BN_ULONG *r,
+                           const BN_ULONG *a, const BN_ULONG *b,
+                           int cl, int dl)
+{
+    BN_ULONG c, t;
+
+    assert(cl >= 0);
+    c = bn_sub_words(r, a, b, cl);
+
+    if (dl == 0)
+        return c;
+
+    r += cl;
+    a += cl;
+    b += cl;
+
+    if (dl < 0) {
+        for (;;) {
+            t = b[0];
+            r[0] = (0 - t - c) & BN_MASK2;
+            if (t != 0)
+                c = 1;
+            if (++dl >= 0)
+                break;
+
+            t = b[1];
+            r[1] = (0 - t - c) & BN_MASK2;
+            if (t != 0)
+                c = 1;
+            if (++dl >= 0)
+                break;
+
+            t = b[2];
+            r[2] = (0 - t - c) & BN_MASK2;
+            if (t != 0)
+                c = 1;
+            if (++dl >= 0)
+                break;
+
+            t = b[3];
+            r[3] = (0 - t - c) & BN_MASK2;
+            if (t != 0)
+                c = 1;
+            if (++dl >= 0)
+                break;
+
+            b += 4;
+            r += 4;
+        }
+    } else {
+        int save_dl = dl;
+        while (c) {
+            t = a[0];
+            r[0] = (t - c) & BN_MASK2;
+            if (t != 0)
+                c = 0;
+            if (--dl <= 0)
+                break;
+
+            t = a[1];
+            r[1] = (t - c) & BN_MASK2;
+            if (t != 0)
+                c = 0;
+            if (--dl <= 0)
+                break;
+
+            t = a[2];
+            r[2] = (t - c) & BN_MASK2;
+            if (t != 0)
+                c = 0;
+            if (--dl <= 0)
+                break;
+
+            t = a[3];
+            r[3] = (t - c) & BN_MASK2;
+            if (t != 0)
+                c = 0;
+            if (--dl <= 0)
+                break;
+
+            save_dl = dl;
+            a += 4;
+            r += 4;
+        }
+        if (dl > 0) {
+            if (save_dl > dl) {
+                switch (save_dl - dl) {
+                case 1:
+                    r[1] = a[1];
+                    if (--dl <= 0)
+                        break;
+                case 2:
+                    r[2] = a[2];
+                    if (--dl <= 0)
+                        break;
+                case 3:
+                    r[3] = a[3];
+                    if (--dl <= 0)
+                        break;
+                }
+                a += 4;
+                r += 4;
+            }
+        }
+        if (dl > 0) {
+            for (;;) {
+                r[0] = a[0];
+                if (--dl <= 0)
+                    break;
+                r[1] = a[1];
+                if (--dl <= 0)
+                    break;
+                r[2] = a[2];
+                if (--dl <= 0)
+                    break;
+                r[3] = a[3];
+                if (--dl <= 0)
+                    break;
+
+                a += 4;
+                r += 4;
+            }
+        }
+    }
+    return c;
+}
+#endif
+
+BN_ULONG bn_add_part_words(BN_ULONG *r,
+                           const BN_ULONG *a, const BN_ULONG *b,
+                           int cl, int dl)
+{
+    BN_ULONG c, l, t;
+
+    assert(cl >= 0);
+    c = bn_add_words(r, a, b, cl);
+
+    if (dl == 0)
+        return c;
+
+    r += cl;
+    a += cl;
+    b += cl;
+
+    if (dl < 0) {
+        int save_dl = dl;
+        while (c) {
+            l = (c + b[0]) & BN_MASK2;
+            c = (l < c);
+            r[0] = l;
+            if (++dl >= 0)
+                break;
+
+            l = (c + b[1]) & BN_MASK2;
+            c = (l < c);
+            r[1] = l;
+            if (++dl >= 0)
+                break;
+
+            l = (c + b[2]) & BN_MASK2;
+            c = (l < c);
+            r[2] = l;
+            if (++dl >= 0)
+                break;
+
+            l = (c + b[3]) & BN_MASK2;
+            c = (l < c);
+            r[3] = l;
+            if (++dl >= 0)
+                break;
+
+            save_dl = dl;
+            b += 4;
+            r += 4;
+        }
+        if (dl < 0) {
+            if (save_dl < dl) {
+                switch (dl - save_dl) {
+                case 1:
+                    r[1] = b[1];
+                    if (++dl >= 0)
+                        break;
+                case 2:
+                    r[2] = b[2];
+                    if (++dl >= 0)
+                        break;
+                case 3:
+                    r[3] = b[3];
+                    if (++dl >= 0)
+                        break;
+                }
+                b += 4;
+                r += 4;
+            }
+        }
+        if (dl < 0) {
+            for (;;) {
+                r[0] = b[0];
+                if (++dl >= 0)
+                    break;
+                r[1] = b[1];
+                if (++dl >= 0)
+                    break;
+                r[2] = b[2];
+                if (++dl >= 0)
+                    break;
+                r[3] = b[3];
+                if (++dl >= 0)
+                    break;
+
+                b += 4;
+                r += 4;
+            }
+        }
+    } else {
+        int save_dl = dl;
+        while (c) {
+            t = (a[0] + c) & BN_MASK2;
+            c = (t < c);
+            r[0] = t;
+            if (--dl <= 0)
+                break;
+
+            t = (a[1] + c) & BN_MASK2;
+            c = (t < c);
+            r[1] = t;
+            if (--dl <= 0)
+                break;
+
+            t = (a[2] + c) & BN_MASK2;
+            c = (t < c);
+            r[2] = t;
+            if (--dl <= 0)
+                break;
+
+            t = (a[3] + c) & BN_MASK2;
+            c = (t < c);
+            r[3] = t;
+            if (--dl <= 0)
+                break;
+
+            save_dl = dl;
+            a += 4;
+            r += 4;
+        }
+        if (dl > 0) {
+            if (save_dl > dl) {
+                switch (save_dl - dl) {
+                case 1:
+                    r[1] = a[1];
+                    if (--dl <= 0)
+                        break;
+                case 2:
+                    r[2] = a[2];
+                    if (--dl <= 0)
+                        break;
+                case 3:
+                    r[3] = a[3];
+                    if (--dl <= 0)
+                        break;
+                }
+                a += 4;
+                r += 4;
+            }
+        }
+        if (dl > 0) {
+            for (;;) {
+                r[0] = a[0];
+                if (--dl <= 0)
+                    break;
+                r[1] = a[1];
+                if (--dl <= 0)
+                    break;
+                r[2] = a[2];
+                if (--dl <= 0)
+                    break;
+                r[3] = a[3];
+                if (--dl <= 0)
+                    break;
+
+                a += 4;
+                r += 4;
+            }
+        }
+    }
+    return c;
+}
+
+#ifdef BN_RECURSION
+/*
+ * Karatsuba recursive multiplication algorithm (cf. Knuth, The Art of
+ * Computer Programming, Vol. 2)
+ */
+
+/*-
+ * r is 2*n2 words in size,
+ * a and b are both n2 words in size.
+ * n2 must be a power of 2.
+ * We multiply and return the result.
+ * t must be 2*n2 words in size
+ * We calculate
+ * a[0]*b[0]
+ * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
+ * a[1]*b[1]
+ */
+/* dnX may not be positive, but n2/2+dnX has to be */
+void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
+                      int dna, int dnb, BN_ULONG *t)
+{
+    int n = n2 / 2, c1, c2;
+    int tna = n + dna, tnb = n + dnb;
+    unsigned int neg, zero;
+    BN_ULONG ln, lo, *p;
+
+# ifdef BN_MUL_COMBA
+#  if 0
+    if (n2 == 4) {
+        bn_mul_comba4(r, a, b);
+        return;
+    }
+#  endif
+    /*
+     * Only call bn_mul_comba 8 if n2 == 8 and the two arrays are complete
+     * [steve]
+     */
+    if (n2 == 8 && dna == 0 && dnb == 0) {
+        bn_mul_comba8(r, a, b);
+        return;
+    }
+# endif                         /* BN_MUL_COMBA */
+    /* Else do normal multiply */
+    if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) {
+        bn_mul_normal(r, a, n2 + dna, b, n2 + dnb);
+        if ((dna + dnb) < 0)
+            memset(&r[2 * n2 + dna + dnb], 0,
+                   sizeof(BN_ULONG) * -(dna + dnb));
+        return;
+    }
+    /* r=(a[0]-a[1])*(b[1]-b[0]) */
+    c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);
+    c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n);
+    zero = neg = 0;
+    switch (c1 * 3 + c2) {
+    case -4:
+        bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
+        bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
+        break;
+    case -3:
+        zero = 1;
+        break;
+    case -2:
+        bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
+        bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */
+        neg = 1;
+        break;
+    case -1:
+    case 0:
+    case 1:
+        zero = 1;
+        break;
+    case 2:
+        bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */
+        bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
+        neg = 1;
+        break;
+    case 3:
+        zero = 1;
+        break;
+    case 4:
+        bn_sub_part_words(t, a, &(a[n]), tna, n - tna);
+        bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n);
+        break;
+    }
+
+# ifdef BN_MUL_COMBA
+    if (n == 4 && dna == 0 && dnb == 0) { /* XXX: bn_mul_comba4 could take
+                                           * extra args to do this well */
+        if (!zero)
+            bn_mul_comba4(&(t[n2]), t, &(t[n]));
+        else
+            memset(&t[n2], 0, sizeof(*t) * 8);
+
+        bn_mul_comba4(r, a, b);
+        bn_mul_comba4(&(r[n2]), &(a[n]), &(b[n]));
+    } else if (n == 8 && dna == 0 && dnb == 0) { /* XXX: bn_mul_comba8 could
+                                                  * take extra args to do
+                                                  * this well */
+        if (!zero)
+            bn_mul_comba8(&(t[n2]), t, &(t[n]));
+        else
+            memset(&t[n2], 0, sizeof(*t) * 16);
+
+        bn_mul_comba8(r, a, b);
+        bn_mul_comba8(&(r[n2]), &(a[n]), &(b[n]));
+    } else
+# endif                         /* BN_MUL_COMBA */
+    {
+        p = &(t[n2 * 2]);
+        if (!zero)
+            bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);
+        else
+            memset(&t[n2], 0, sizeof(*t) * n2);
+        bn_mul_recursive(r, a, b, n, 0, 0, p);
+        bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]), n, dna, dnb, p);
+    }
+
+    /*-
+     * t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
+     * r[10] holds (a[0]*b[0])
+     * r[32] holds (b[1]*b[1])
+     */
+
+    c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
+
+    if (neg) {                  /* if t[32] is negative */
+        c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
+    } else {
+        /* Might have a carry */
+        c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));
+    }
+
+    /*-
+     * t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
+     * r[10] holds (a[0]*b[0])
+     * r[32] holds (b[1]*b[1])
+     * c1 holds the carry bits
+     */
+    c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
+    if (c1) {
+        p = &(r[n + n2]);
+        lo = *p;
+        ln = (lo + c1) & BN_MASK2;
+        *p = ln;
+
+        /*
+         * The overflow will stop before we over write words we should not
+         * overwrite
+         */
+        if (ln < (BN_ULONG)c1) {
+            do {
+                p++;
+                lo = *p;
+                ln = (lo + 1) & BN_MASK2;
+                *p = ln;
+            } while (ln == 0);
+        }
+    }
+}
+
+/*
+ * n+tn is the word length t needs to be n*4 is size, as does r
+ */
+/* tnX may not be negative but less than n */
+void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
+                           int tna, int tnb, BN_ULONG *t)
+{
+    int i, j, n2 = n * 2;
+    int c1, c2, neg;
+    BN_ULONG ln, lo, *p;
+
+    if (n < 8) {
+        bn_mul_normal(r, a, n + tna, b, n + tnb);
+        return;
+    }
+
+    /* r=(a[0]-a[1])*(b[1]-b[0]) */
+    c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);
+    c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n);
+    neg = 0;
+    switch (c1 * 3 + c2) {
+    case -4:
+        bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
+        bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
+        break;
+    case -3:
+        /* break; */
+    case -2:
+        bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
+        bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */
+        neg = 1;
+        break;
+    case -1:
+    case 0:
+    case 1:
+        /* break; */
+    case 2:
+        bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */
+        bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
+        neg = 1;
+        break;
+    case 3:
+        /* break; */
+    case 4:
+        bn_sub_part_words(t, a, &(a[n]), tna, n - tna);
+        bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n);
+        break;
+    }
+    /*
+     * The zero case isn't yet implemented here. The speedup would probably
+     * be negligible.
+     */
+# if 0
+    if (n == 4) {
+        bn_mul_comba4(&(t[n2]), t, &(t[n]));
+        bn_mul_comba4(r, a, b);
+        bn_mul_normal(&(r[n2]), &(a[n]), tn, &(b[n]), tn);
+        memset(&r[n2 + tn * 2], 0, sizeof(*r) * (n2 - tn * 2));
+    } else
+# endif
+    if (n == 8) {
+        bn_mul_comba8(&(t[n2]), t, &(t[n]));
+        bn_mul_comba8(r, a, b);
+        bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb);
+        memset(&r[n2 + tna + tnb], 0, sizeof(*r) * (n2 - tna - tnb));
+    } else {
+        p = &(t[n2 * 2]);
+        bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);
+        bn_mul_recursive(r, a, b, n, 0, 0, p);
+        i = n / 2;
+        /*
+         * If there is only a bottom half to the number, just do it
+         */
+        if (tna > tnb)
+            j = tna - i;
+        else
+            j = tnb - i;
+        if (j == 0) {
+            bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]),
+                             i, tna - i, tnb - i, p);
+            memset(&r[n2 + i * 2], 0, sizeof(*r) * (n2 - i * 2));
+        } else if (j > 0) {     /* eg, n == 16, i == 8 and tn == 11 */
+            bn_mul_part_recursive(&(r[n2]), &(a[n]), &(b[n]),
+                                  i, tna - i, tnb - i, p);
+            memset(&(r[n2 + tna + tnb]), 0,
+                   sizeof(BN_ULONG) * (n2 - tna - tnb));
+        } else {                /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
+
+            memset(&r[n2], 0, sizeof(*r) * n2);
+            if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL
+                && tnb < BN_MUL_RECURSIVE_SIZE_NORMAL) {
+                bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb);
+            } else {
+                for (;;) {
+                    i /= 2;
+                    /*
+                     * these simplified conditions work exclusively because
+                     * difference between tna and tnb is 1 or 0
+                     */
+                    if (i < tna || i < tnb) {
+                        bn_mul_part_recursive(&(r[n2]),
+                                              &(a[n]), &(b[n]),
+                                              i, tna - i, tnb - i, p);
+                        break;
+                    } else if (i == tna || i == tnb) {
+                        bn_mul_recursive(&(r[n2]),
+                                         &(a[n]), &(b[n]),
+                                         i, tna - i, tnb - i, p);
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    /*-
+     * t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
+     * r[10] holds (a[0]*b[0])
+     * r[32] holds (b[1]*b[1])
+     */
+
+    c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
+
+    if (neg) {                  /* if t[32] is negative */
+        c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
+    } else {
+        /* Might have a carry */
+        c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));
+    }
+
+    /*-
+     * t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
+     * r[10] holds (a[0]*b[0])
+     * r[32] holds (b[1]*b[1])
+     * c1 holds the carry bits
+     */
+    c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
+    if (c1) {
+        p = &(r[n + n2]);
+        lo = *p;
+        ln = (lo + c1) & BN_MASK2;
+        *p = ln;
+
+        /*
+         * The overflow will stop before we over write words we should not
+         * overwrite
+         */
+        if (ln < (BN_ULONG)c1) {
+            do {
+                p++;
+                lo = *p;
+                ln = (lo + 1) & BN_MASK2;
+                *p = ln;
+            } while (ln == 0);
+        }
+    }
+}
+
+/*-
+ * a and b must be the same size, which is n2.
+ * r needs to be n2 words and t needs to be n2*2
+ */
+void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
+                          BN_ULONG *t)
+{
+    int n = n2 / 2;
+
+    bn_mul_recursive(r, a, b, n, 0, 0, &(t[0]));
+    if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL) {
+        bn_mul_low_recursive(&(t[0]), &(a[0]), &(b[n]), n, &(t[n2]));
+        bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
+        bn_mul_low_recursive(&(t[0]), &(a[n]), &(b[0]), n, &(t[n2]));
+        bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
+    } else {
+        bn_mul_low_normal(&(t[0]), &(a[0]), &(b[n]), n);
+        bn_mul_low_normal(&(t[n]), &(a[n]), &(b[0]), n);
+        bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
+        bn_add_words(&(r[n]), &(r[n]), &(t[n]), n);
+    }
+}
+
+/*-
+ * a and b must be the same size, which is n2.
+ * r needs to be n2 words and t needs to be n2*2
+ * l is the low words of the output.
+ * t needs to be n2*3
+ */
+void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2,
+                 BN_ULONG *t)
+{
+    int i, n;
+    int c1, c2;
+    int neg, oneg, zero;
+    BN_ULONG ll, lc, *lp, *mp;
+
+    n = n2 / 2;
+
+    /* Calculate (al-ah)*(bh-bl) */
+    neg = zero = 0;
+    c1 = bn_cmp_words(&(a[0]), &(a[n]), n);
+    c2 = bn_cmp_words(&(b[n]), &(b[0]), n);
+    switch (c1 * 3 + c2) {
+    case -4:
+        bn_sub_words(&(r[0]), &(a[n]), &(a[0]), n);
+        bn_sub_words(&(r[n]), &(b[0]), &(b[n]), n);
+        break;
+    case -3:
+        zero = 1;
+        break;
+    case -2:
+        bn_sub_words(&(r[0]), &(a[n]), &(a[0]), n);
+        bn_sub_words(&(r[n]), &(b[n]), &(b[0]), n);
+        neg = 1;
+        break;
+    case -1:
+    case 0:
+    case 1:
+        zero = 1;
+        break;
+    case 2:
+        bn_sub_words(&(r[0]), &(a[0]), &(a[n]), n);
+        bn_sub_words(&(r[n]), &(b[0]), &(b[n]), n);
+        neg = 1;
+        break;
+    case 3:
+        zero = 1;
+        break;
+    case 4:
+        bn_sub_words(&(r[0]), &(a[0]), &(a[n]), n);
+        bn_sub_words(&(r[n]), &(b[n]), &(b[0]), n);
+        break;
+    }
+
+    oneg = neg;
+    /* t[10] = (a[0]-a[1])*(b[1]-b[0]) */
+    /* r[10] = (a[1]*b[1]) */
+# ifdef BN_MUL_COMBA
+    if (n == 8) {
+        bn_mul_comba8(&(t[0]), &(r[0]), &(r[n]));
+        bn_mul_comba8(r, &(a[n]), &(b[n]));
+    } else
+# endif
+    {
+        bn_mul_recursive(&(t[0]), &(r[0]), &(r[n]), n, 0, 0, &(t[n2]));
+        bn_mul_recursive(r, &(a[n]), &(b[n]), n, 0, 0, &(t[n2]));
+    }
+
+    /*-
+     * s0 == low(al*bl)
+     * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl)
+     * We know s0 and s1 so the only unknown is high(al*bl)
+     * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl))
+     * high(al*bl) == s1 - (r[0]+l[0]+t[0])
+     */
+    if (l != NULL) {
+        lp = &(t[n2 + n]);
+        bn_add_words(lp, &(r[0]), &(l[0]), n);
+    } else {
+        lp = &(r[0]);
+    }
+
+    if (neg)
+        neg = (int)(bn_sub_words(&(t[n2]), lp, &(t[0]), n));
+    else {
+        bn_add_words(&(t[n2]), lp, &(t[0]), n);
+        neg = 0;
+    }
+
+    if (l != NULL) {
+        bn_sub_words(&(t[n2 + n]), &(l[n]), &(t[n2]), n);
+    } else {
+        lp = &(t[n2 + n]);
+        mp = &(t[n2]);
+        for (i = 0; i < n; i++)
+            lp[i] = ((~mp[i]) + 1) & BN_MASK2;
+    }
+
+    /*-
+     * s[0] = low(al*bl)
+     * t[3] = high(al*bl)
+     * t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign
+     * r[10] = (a[1]*b[1])
+     */
+    /*-
+     * R[10] = al*bl
+     * R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0])
+     * R[32] = ah*bh
+     */
+    /*-
+     * R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow)
+     * R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow)
+     * R[3]=r[1]+(carry/borrow)
+     */
+    if (l != NULL) {
+        lp = &(t[n2]);
+        c1 = (int)(bn_add_words(lp, &(t[n2 + n]), &(l[0]), n));
+    } else {
+        lp = &(t[n2 + n]);
+        c1 = 0;
+    }
+    c1 += (int)(bn_add_words(&(t[n2]), lp, &(r[0]), n));
+    if (oneg)
+        c1 -= (int)(bn_sub_words(&(t[n2]), &(t[n2]), &(t[0]), n));
+    else
+        c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), &(t[0]), n));
+
+    c2 = (int)(bn_add_words(&(r[0]), &(r[0]), &(t[n2 + n]), n));
+    c2 += (int)(bn_add_words(&(r[0]), &(r[0]), &(r[n]), n));
+    if (oneg)
+        c2 -= (int)(bn_sub_words(&(r[0]), &(r[0]), &(t[n]), n));
+    else
+        c2 += (int)(bn_add_words(&(r[0]), &(r[0]), &(t[n]), n));
+
+    if (c1 != 0) {              /* Add starting at r[0], could be +ve or -ve */
+        i = 0;
+        if (c1 > 0) {
+            lc = c1;
+            do {
+                ll = (r[i] + lc) & BN_MASK2;
+                r[i++] = ll;
+                lc = (lc > ll);
+            } while (lc);
+        } else {
+            lc = -c1;
+            do {
+                ll = r[i];
+                r[i++] = (ll - lc) & BN_MASK2;
+                lc = (lc > ll);
+            } while (lc);
+        }
+    }
+    if (c2 != 0) {              /* Add starting at r[1] */
+        i = n;
+        if (c2 > 0) {
+            lc = c2;
+            do {
+                ll = (r[i] + lc) & BN_MASK2;
+                r[i++] = ll;
+                lc = (lc > ll);
+            } while (lc);
+        } else {
+            lc = -c2;
+            do {
+                ll = r[i];
+                r[i++] = (ll - lc) & BN_MASK2;
+                lc = (lc > ll);
+            } while (lc);
+        }
+    }
+}
+#endif                          /* BN_RECURSION */
+
+int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+{
+    int ret = 0;
+    int top, al, bl;
+    BIGNUM *rr;
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+    int i;
+#endif
+#ifdef BN_RECURSION
+    BIGNUM *t = NULL;
+    int j = 0, k;
+#endif
+
+    bn_check_top(a);
+    bn_check_top(b);
+    bn_check_top(r);
+
+    al = a->top;
+    bl = b->top;
+
+    if ((al == 0) || (bl == 0)) {
+        BN_zero(r);
+        return (1);
+    }
+    top = al + bl;
+
+    BN_CTX_start(ctx);
+    if ((r == a) || (r == b)) {
+        if ((rr = BN_CTX_get(ctx)) == NULL)
+            goto err;
+    } else
+        rr = r;
+
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+    i = al - bl;
+#endif
+#ifdef BN_MUL_COMBA
+    if (i == 0) {
+# if 0
+        if (al == 4) {
+            if (bn_wexpand(rr, 8) == NULL)
+                goto err;
+            rr->top = 8;
+            bn_mul_comba4(rr->d, a->d, b->d);
+            goto end;
+        }
+# endif
+        if (al == 8) {
+            if (bn_wexpand(rr, 16) == NULL)
+                goto err;
+            rr->top = 16;
+            bn_mul_comba8(rr->d, a->d, b->d);
+            goto end;
+        }
+    }
+#endif                          /* BN_MUL_COMBA */
+#ifdef BN_RECURSION
+    if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) {
+        if (i >= -1 && i <= 1) {
+            /*
+             * Find out the power of two lower or equal to the longest of the
+             * two numbers
+             */
+            if (i >= 0) {
+                j = BN_num_bits_word((BN_ULONG)al);
+            }
+            if (i == -1) {
+                j = BN_num_bits_word((BN_ULONG)bl);
+            }
+            j = 1 << (j - 1);
+            assert(j <= al || j <= bl);
+            k = j + j;
+            t = BN_CTX_get(ctx);
+            if (t == NULL)
+                goto err;
+            if (al > j || bl > j) {
+                if (bn_wexpand(t, k * 4) == NULL)
+                    goto err;
+                if (bn_wexpand(rr, k * 4) == NULL)
+                    goto err;
+                bn_mul_part_recursive(rr->d, a->d, b->d,
+                                      j, al - j, bl - j, t->d);
+            } else {            /* al <= j || bl <= j */
+
+                if (bn_wexpand(t, k * 2) == NULL)
+                    goto err;
+                if (bn_wexpand(rr, k * 2) == NULL)
+                    goto err;
+                bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d);
+            }
+            rr->top = top;
+            goto end;
+        }
+# if 0
+        if (i == 1 && !BN_get_flags(b, BN_FLG_STATIC_DATA)) {
+            BIGNUM *tmp_bn = (BIGNUM *)b;
+            if (bn_wexpand(tmp_bn, al) == NULL)
+                goto err;
+            tmp_bn->d[bl] = 0;
+            bl++;
+            i--;
+        } else if (i == -1 && !BN_get_flags(a, BN_FLG_STATIC_DATA)) {
+            BIGNUM *tmp_bn = (BIGNUM *)a;
+            if (bn_wexpand(tmp_bn, bl) == NULL)
+                goto err;
+            tmp_bn->d[al] = 0;
+            al++;
+            i++;
+        }
+        if (i == 0) {
+            /* symmetric and > 4 */
+            /* 16 or larger */
+            j = BN_num_bits_word((BN_ULONG)al);
+            j = 1 << (j - 1);
+            k = j + j;
+            t = BN_CTX_get(ctx);
+            if (al == j) {      /* exact multiple */
+                if (bn_wexpand(t, k * 2) == NULL)
+                    goto err;
+                if (bn_wexpand(rr, k * 2) == NULL)
+                    goto err;
+                bn_mul_recursive(rr->d, a->d, b->d, al, t->d);
+            } else {
+                if (bn_wexpand(t, k * 4) == NULL)
+                    goto err;
+                if (bn_wexpand(rr, k * 4) == NULL)
+                    goto err;
+                bn_mul_part_recursive(rr->d, a->d, b->d, al - j, j, t->d);
+            }
+            rr->top = top;
+            goto end;
+        }
+# endif
+    }
+#endif                          /* BN_RECURSION */
+    if (bn_wexpand(rr, top) == NULL)
+        goto err;
+    rr->top = top;
+    bn_mul_normal(rr->d, a->d, al, b->d, bl);
+
+#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)
+ end:
+#endif
+    rr->neg = a->neg ^ b->neg;
+    bn_correct_top(rr);
+    if (r != rr && BN_copy(r, rr) == NULL)
+        goto err;
+
+    ret = 1;
+ err:
+    bn_check_top(r);
+    BN_CTX_end(ctx);
+    return (ret);
+}
+
+void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
+{
+    BN_ULONG *rr;
+
+    if (na < nb) {
+        int itmp;
+        BN_ULONG *ltmp;
+
+        itmp = na;
+        na = nb;
+        nb = itmp;
+        ltmp = a;
+        a = b;
+        b = ltmp;
+
+    }
+    rr = &(r[na]);
+    if (nb <= 0) {
+        (void)bn_mul_words(r, a, na, 0);
+        return;
+    } else
+        rr[0] = bn_mul_words(r, a, na, b[0]);
+
+    for (;;) {
+        if (--nb <= 0)
+            return;
+        rr[1] = bn_mul_add_words(&(r[1]), a, na, b[1]);
+        if (--nb <= 0)
+            return;
+        rr[2] = bn_mul_add_words(&(r[2]), a, na, b[2]);
+        if (--nb <= 0)
+            return;
+        rr[3] = bn_mul_add_words(&(r[3]), a, na, b[3]);
+        if (--nb <= 0)
+            return;
+        rr[4] = bn_mul_add_words(&(r[4]), a, na, b[4]);
+        rr += 4;
+        r += 4;
+        b += 4;
+    }
+}
+
+void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+{
+    bn_mul_words(r, a, n, b[0]);
+
+    for (;;) {
+        if (--n <= 0)
+            return;
+        bn_mul_add_words(&(r[1]), a, n, b[1]);
+        if (--n <= 0)
+            return;
+        bn_mul_add_words(&(r[2]), a, n, b[2]);
+        if (--n <= 0)
+            return;
+        bn_mul_add_words(&(r[3]), a, n, b[3]);
+        if (--n <= 0)
+            return;
+        bn_mul_add_words(&(r[4]), a, n, b[4]);
+        r += 4;
+        b += 4;
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_nist.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_nist.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_nist.c	(revision 331)
@@ -0,0 +1,1239 @@
+/*
+ * Copyright 2002-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 "bn_lcl.h"
+#include "internal/cryptlib.h"
+
+#define BN_NIST_192_TOP (192+BN_BITS2-1)/BN_BITS2
+#define BN_NIST_224_TOP (224+BN_BITS2-1)/BN_BITS2
+#define BN_NIST_256_TOP (256+BN_BITS2-1)/BN_BITS2
+#define BN_NIST_384_TOP (384+BN_BITS2-1)/BN_BITS2
+#define BN_NIST_521_TOP (521+BN_BITS2-1)/BN_BITS2
+
+/* pre-computed tables are "carry-less" values of modulus*(i+1) */
+#if BN_BITS2 == 64
+static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
+    {0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFFULL},
+    {0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL},
+    {0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFCULL, 0xFFFFFFFFFFFFFFFFULL}
+};
+
+static const BN_ULONG _nist_p_192_sqr[] = {
+    0x0000000000000001ULL, 0x0000000000000002ULL, 0x0000000000000001ULL,
+    0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL
+};
+
+static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
+    {0x0000000000000001ULL, 0xFFFFFFFF00000000ULL,
+     0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL},
+    {0x0000000000000002ULL, 0xFFFFFFFE00000000ULL,
+     0xFFFFFFFFFFFFFFFFULL, 0x00000001FFFFFFFFULL} /* this one is
+                                                    * "carry-full" */
+};
+
+static const BN_ULONG _nist_p_224_sqr[] = {
+    0x0000000000000001ULL, 0xFFFFFFFE00000000ULL,
+    0xFFFFFFFFFFFFFFFFULL, 0x0000000200000000ULL,
+    0x0000000000000000ULL, 0xFFFFFFFFFFFFFFFEULL,
+    0xFFFFFFFFFFFFFFFFULL
+};
+
+static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
+    {0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL,
+     0x0000000000000000ULL, 0xFFFFFFFF00000001ULL},
+    {0xFFFFFFFFFFFFFFFEULL, 0x00000001FFFFFFFFULL,
+     0x0000000000000000ULL, 0xFFFFFFFE00000002ULL},
+    {0xFFFFFFFFFFFFFFFDULL, 0x00000002FFFFFFFFULL,
+     0x0000000000000000ULL, 0xFFFFFFFD00000003ULL},
+    {0xFFFFFFFFFFFFFFFCULL, 0x00000003FFFFFFFFULL,
+     0x0000000000000000ULL, 0xFFFFFFFC00000004ULL},
+    {0xFFFFFFFFFFFFFFFBULL, 0x00000004FFFFFFFFULL,
+     0x0000000000000000ULL, 0xFFFFFFFB00000005ULL},
+};
+
+static const BN_ULONG _nist_p_256_sqr[] = {
+    0x0000000000000001ULL, 0xFFFFFFFE00000000ULL,
+    0xFFFFFFFFFFFFFFFFULL, 0x00000001FFFFFFFEULL,
+    0x00000001FFFFFFFEULL, 0x00000001FFFFFFFEULL,
+    0xFFFFFFFE00000001ULL, 0xFFFFFFFE00000002ULL
+};
+
+static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
+    {0x00000000FFFFFFFFULL, 0xFFFFFFFF00000000ULL, 0xFFFFFFFFFFFFFFFEULL,
+     0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
+    {0x00000001FFFFFFFEULL, 0xFFFFFFFE00000000ULL, 0xFFFFFFFFFFFFFFFDULL,
+     0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
+    {0x00000002FFFFFFFDULL, 0xFFFFFFFD00000000ULL, 0xFFFFFFFFFFFFFFFCULL,
+     0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
+    {0x00000003FFFFFFFCULL, 0xFFFFFFFC00000000ULL, 0xFFFFFFFFFFFFFFFBULL,
+     0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
+    {0x00000004FFFFFFFBULL, 0xFFFFFFFB00000000ULL, 0xFFFFFFFFFFFFFFFAULL,
+     0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL},
+};
+
+static const BN_ULONG _nist_p_384_sqr[] = {
+    0xFFFFFFFE00000001ULL, 0x0000000200000000ULL, 0xFFFFFFFE00000000ULL,
+    0x0000000200000000ULL, 0x0000000000000001ULL, 0x0000000000000000ULL,
+    0x00000001FFFFFFFEULL, 0xFFFFFFFE00000000ULL, 0xFFFFFFFFFFFFFFFDULL,
+    0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL
+};
+
+static const BN_ULONG _nist_p_521[] =
+    { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+    0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+    0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+    0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+    0x00000000000001FFULL
+};
+
+static const BN_ULONG _nist_p_521_sqr[] = {
+    0x0000000000000001ULL, 0x0000000000000000ULL, 0x0000000000000000ULL,
+    0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL,
+    0x0000000000000000ULL, 0x0000000000000000ULL, 0xFFFFFFFFFFFFFC00ULL,
+    0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+    0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
+    0xFFFFFFFFFFFFFFFFULL, 0x000000000003FFFFULL
+};
+#elif BN_BITS2 == 32
+static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
+    {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+    {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+    {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}
+};
+
+static const BN_ULONG _nist_p_192_sqr[] = {
+    0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001, 0x00000000,
+    0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
+    {0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF,
+     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+    {0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE,
+     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}
+};
+
+static const BN_ULONG _nist_p_224_sqr[] = {
+    0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE,
+    0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000002,
+    0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF,
+    0xFFFFFFFF, 0xFFFFFFFF
+};
+
+static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
+    {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
+     0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF},
+    {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001,
+     0x00000000, 0x00000000, 0x00000002, 0xFFFFFFFE},
+    {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002,
+     0x00000000, 0x00000000, 0x00000003, 0xFFFFFFFD},
+    {0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003,
+     0x00000000, 0x00000000, 0x00000004, 0xFFFFFFFC},
+    {0xFFFFFFFB, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000004,
+     0x00000000, 0x00000000, 0x00000005, 0xFFFFFFFB},
+};
+
+static const BN_ULONG _nist_p_256_sqr[] = {
+    0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE,
+    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001,
+    0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001,
+    0x00000001, 0xFFFFFFFE, 0x00000002, 0xFFFFFFFE
+};
+
+static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
+    {0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
+     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+    {0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF,
+     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+    {0xFFFFFFFD, 0x00000002, 0x00000000, 0xFFFFFFFD, 0xFFFFFFFC, 0xFFFFFFFF,
+     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+    {0xFFFFFFFC, 0x00000003, 0x00000000, 0xFFFFFFFC, 0xFFFFFFFB, 0xFFFFFFFF,
+     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+    {0xFFFFFFFB, 0x00000004, 0x00000000, 0xFFFFFFFB, 0xFFFFFFFA, 0xFFFFFFFF,
+     0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
+};
+
+static const BN_ULONG _nist_p_384_sqr[] = {
+    0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, 0xFFFFFFFE,
+    0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+    0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF,
+    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+static const BN_ULONG _nist_p_521[] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+    0xFFFFFFFF, 0x000001FF
+};
+
+static const BN_ULONG _nist_p_521_sqr[] = {
+    0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFC00, 0xFFFFFFFF,
+    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+    0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+    0xFFFFFFFF, 0xFFFFFFFF, 0x0003FFFF
+};
+#else
+# error "unsupported BN_BITS2"
+#endif
+
+static const BIGNUM _bignum_nist_p_192 = {
+    (BN_ULONG *)_nist_p_192[0],
+    BN_NIST_192_TOP,
+    BN_NIST_192_TOP,
+    0,
+    BN_FLG_STATIC_DATA
+};
+
+static const BIGNUM _bignum_nist_p_224 = {
+    (BN_ULONG *)_nist_p_224[0],
+    BN_NIST_224_TOP,
+    BN_NIST_224_TOP,
+    0,
+    BN_FLG_STATIC_DATA
+};
+
+static const BIGNUM _bignum_nist_p_256 = {
+    (BN_ULONG *)_nist_p_256[0],
+    BN_NIST_256_TOP,
+    BN_NIST_256_TOP,
+    0,
+    BN_FLG_STATIC_DATA
+};
+
+static const BIGNUM _bignum_nist_p_384 = {
+    (BN_ULONG *)_nist_p_384[0],
+    BN_NIST_384_TOP,
+    BN_NIST_384_TOP,
+    0,
+    BN_FLG_STATIC_DATA
+};
+
+static const BIGNUM _bignum_nist_p_521 = {
+    (BN_ULONG *)_nist_p_521,
+    BN_NIST_521_TOP,
+    BN_NIST_521_TOP,
+    0,
+    BN_FLG_STATIC_DATA
+};
+
+const BIGNUM *BN_get0_nist_prime_192(void)
+{
+    return &_bignum_nist_p_192;
+}
+
+const BIGNUM *BN_get0_nist_prime_224(void)
+{
+    return &_bignum_nist_p_224;
+}
+
+const BIGNUM *BN_get0_nist_prime_256(void)
+{
+    return &_bignum_nist_p_256;
+}
+
+const BIGNUM *BN_get0_nist_prime_384(void)
+{
+    return &_bignum_nist_p_384;
+}
+
+const BIGNUM *BN_get0_nist_prime_521(void)
+{
+    return &_bignum_nist_p_521;
+}
+
+static void nist_cp_bn_0(BN_ULONG *dst, const BN_ULONG *src, int top, int max)
+{
+    int i;
+
+#ifdef BN_DEBUG
+    OPENSSL_assert(top <= max);
+#endif
+    for (i = 0; i < top; i++)
+        dst[i] = src[i];
+    for (; i < max; i++)
+        dst[i] = 0;
+}
+
+static void nist_cp_bn(BN_ULONG *dst, const BN_ULONG *src, int top)
+{
+    int i;
+
+    for (i = 0; i < top; i++)
+        dst[i] = src[i];
+}
+
+#if BN_BITS2 == 64
+# define bn_cp_64(to, n, from, m)        (to)[n] = (m>=0)?((from)[m]):0;
+# define bn_64_set_0(to, n)              (to)[n] = (BN_ULONG)0;
+/*
+ * two following macros are implemented under assumption that they
+ * are called in a sequence with *ascending* n, i.e. as they are...
+ */
+# define bn_cp_32_naked(to, n, from, m)  (((n)&1)?(to[(n)/2]|=((m)&1)?(from[(m)/2]&BN_MASK2h):(from[(m)/2]<<32))\
+                                                :(to[(n)/2] =((m)&1)?(from[(m)/2]>>32):(from[(m)/2]&BN_MASK2l)))
+# define bn_32_set_0(to, n)              (((n)&1)?(to[(n)/2]&=BN_MASK2l):(to[(n)/2]=0));
+# define bn_cp_32(to,n,from,m)           ((m)>=0)?bn_cp_32_naked(to,n,from,m):bn_32_set_0(to,n)
+# if defined(L_ENDIAN)
+#  if defined(__arch64__)
+#   define NIST_INT64 long
+#  else
+#   define NIST_INT64 long long
+#  endif
+# endif
+#else
+# define bn_cp_64(to, n, from, m) \
+        { \
+        bn_cp_32(to, (n)*2, from, (m)*2); \
+        bn_cp_32(to, (n)*2+1, from, (m)*2+1); \
+        }
+# define bn_64_set_0(to, n) \
+        { \
+        bn_32_set_0(to, (n)*2); \
+        bn_32_set_0(to, (n)*2+1); \
+        }
+# define bn_cp_32(to, n, from, m)        (to)[n] = (m>=0)?((from)[m]):0;
+# define bn_32_set_0(to, n)              (to)[n] = (BN_ULONG)0;
+# if defined(_WIN32) && !defined(__GNUC__)
+#  define NIST_INT64 __int64
+# elif defined(BN_LLONG)
+#  define NIST_INT64 long long
+# endif
+#endif                          /* BN_BITS2 != 64 */
+
+#define nist_set_192(to, from, a1, a2, a3) \
+        { \
+        bn_cp_64(to, 0, from, (a3) - 3) \
+        bn_cp_64(to, 1, from, (a2) - 3) \
+        bn_cp_64(to, 2, from, (a1) - 3) \
+        }
+
+int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
+                    BN_CTX *ctx)
+{
+    int top = a->top, i;
+    int carry;
+    register BN_ULONG *r_d, *a_d = a->d;
+    union {
+        BN_ULONG bn[BN_NIST_192_TOP];
+        unsigned int ui[BN_NIST_192_TOP * sizeof(BN_ULONG) /
+                        sizeof(unsigned int)];
+    } buf;
+    BN_ULONG c_d[BN_NIST_192_TOP], *res;
+    PTR_SIZE_INT mask;
+    static const BIGNUM _bignum_nist_p_192_sqr = {
+        (BN_ULONG *)_nist_p_192_sqr,
+        OSSL_NELEM(_nist_p_192_sqr),
+        OSSL_NELEM(_nist_p_192_sqr),
+        0, BN_FLG_STATIC_DATA
+    };
+
+    field = &_bignum_nist_p_192; /* just to make sure */
+
+    if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_192_sqr) >= 0)
+        return BN_nnmod(r, a, field, ctx);
+
+    i = BN_ucmp(field, a);
+    if (i == 0) {
+        BN_zero(r);
+        return 1;
+    } else if (i > 0)
+        return (r == a) ? 1 : (BN_copy(r, a) != NULL);
+
+    if (r != a) {
+        if (!bn_wexpand(r, BN_NIST_192_TOP))
+            return 0;
+        r_d = r->d;
+        nist_cp_bn(r_d, a_d, BN_NIST_192_TOP);
+    } else
+        r_d = a_d;
+
+    nist_cp_bn_0(buf.bn, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP,
+                 BN_NIST_192_TOP);
+
+#if defined(NIST_INT64)
+    {
+        NIST_INT64 acc;         /* accumulator */
+        unsigned int *rp = (unsigned int *)r_d;
+        const unsigned int *bp = (const unsigned int *)buf.ui;
+
+        acc = rp[0];
+        acc += bp[3 * 2 - 6];
+        acc += bp[5 * 2 - 6];
+        rp[0] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[1];
+        acc += bp[3 * 2 - 5];
+        acc += bp[5 * 2 - 5];
+        rp[1] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[2];
+        acc += bp[3 * 2 - 6];
+        acc += bp[4 * 2 - 6];
+        acc += bp[5 * 2 - 6];
+        rp[2] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[3];
+        acc += bp[3 * 2 - 5];
+        acc += bp[4 * 2 - 5];
+        acc += bp[5 * 2 - 5];
+        rp[3] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[4];
+        acc += bp[4 * 2 - 6];
+        acc += bp[5 * 2 - 6];
+        rp[4] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[5];
+        acc += bp[4 * 2 - 5];
+        acc += bp[5 * 2 - 5];
+        rp[5] = (unsigned int)acc;
+
+        carry = (int)(acc >> 32);
+    }
+#else
+    {
+        BN_ULONG t_d[BN_NIST_192_TOP];
+
+        nist_set_192(t_d, buf.bn, 0, 3, 3);
+        carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
+        nist_set_192(t_d, buf.bn, 4, 4, 0);
+        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
+        nist_set_192(t_d, buf.bn, 5, 5, 5)
+            carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
+    }
+#endif
+    if (carry > 0)
+        carry =
+            (int)bn_sub_words(r_d, r_d, _nist_p_192[carry - 1],
+                              BN_NIST_192_TOP);
+    else
+        carry = 1;
+
+    /*
+     * we need 'if (carry==0 || result>=modulus) result-=modulus;'
+     * as comparison implies subtraction, we can write
+     * 'tmp=result-modulus; if (!carry || !borrow) result=tmp;'
+     * this is what happens below, but without explicit if:-) a.
+     */
+    mask =
+        0 - (PTR_SIZE_INT) bn_sub_words(c_d, r_d, _nist_p_192[0],
+                                        BN_NIST_192_TOP);
+    mask &= 0 - (PTR_SIZE_INT) carry;
+    res = c_d;
+    res = (BN_ULONG *)
+        (((PTR_SIZE_INT) res & ~mask) | ((PTR_SIZE_INT) r_d & mask));
+    nist_cp_bn(r_d, res, BN_NIST_192_TOP);
+    r->top = BN_NIST_192_TOP;
+    bn_correct_top(r);
+
+    return 1;
+}
+
+typedef BN_ULONG (*bn_addsub_f) (BN_ULONG *, const BN_ULONG *,
+                                 const BN_ULONG *, int);
+
+#define nist_set_224(to, from, a1, a2, a3, a4, a5, a6, a7) \
+        { \
+        bn_cp_32(to, 0, from, (a7) - 7) \
+        bn_cp_32(to, 1, from, (a6) - 7) \
+        bn_cp_32(to, 2, from, (a5) - 7) \
+        bn_cp_32(to, 3, from, (a4) - 7) \
+        bn_cp_32(to, 4, from, (a3) - 7) \
+        bn_cp_32(to, 5, from, (a2) - 7) \
+        bn_cp_32(to, 6, from, (a1) - 7) \
+        }
+
+int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
+                    BN_CTX *ctx)
+{
+    int top = a->top, i;
+    int carry;
+    BN_ULONG *r_d, *a_d = a->d;
+    union {
+        BN_ULONG bn[BN_NIST_224_TOP];
+        unsigned int ui[BN_NIST_224_TOP * sizeof(BN_ULONG) /
+                        sizeof(unsigned int)];
+    } buf;
+    BN_ULONG c_d[BN_NIST_224_TOP], *res;
+    PTR_SIZE_INT mask;
+    union {
+        bn_addsub_f f;
+        PTR_SIZE_INT p;
+    } u;
+    static const BIGNUM _bignum_nist_p_224_sqr = {
+        (BN_ULONG *)_nist_p_224_sqr,
+        OSSL_NELEM(_nist_p_224_sqr),
+        OSSL_NELEM(_nist_p_224_sqr),
+        0, BN_FLG_STATIC_DATA
+    };
+
+    field = &_bignum_nist_p_224; /* just to make sure */
+
+    if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_224_sqr) >= 0)
+        return BN_nnmod(r, a, field, ctx);
+
+    i = BN_ucmp(field, a);
+    if (i == 0) {
+        BN_zero(r);
+        return 1;
+    } else if (i > 0)
+        return (r == a) ? 1 : (BN_copy(r, a) != NULL);
+
+    if (r != a) {
+        if (!bn_wexpand(r, BN_NIST_224_TOP))
+            return 0;
+        r_d = r->d;
+        nist_cp_bn(r_d, a_d, BN_NIST_224_TOP);
+    } else
+        r_d = a_d;
+
+#if BN_BITS2==64
+    /* copy upper 256 bits of 448 bit number ... */
+    nist_cp_bn_0(c_d, a_d + (BN_NIST_224_TOP - 1),
+                 top - (BN_NIST_224_TOP - 1), BN_NIST_224_TOP);
+    /* ... and right shift by 32 to obtain upper 224 bits */
+    nist_set_224(buf.bn, c_d, 14, 13, 12, 11, 10, 9, 8);
+    /* truncate lower part to 224 bits too */
+    r_d[BN_NIST_224_TOP - 1] &= BN_MASK2l;
+#else
+    nist_cp_bn_0(buf.bn, a_d + BN_NIST_224_TOP, top - BN_NIST_224_TOP,
+                 BN_NIST_224_TOP);
+#endif
+
+#if defined(NIST_INT64) && BN_BITS2!=64
+    {
+        NIST_INT64 acc;         /* accumulator */
+        unsigned int *rp = (unsigned int *)r_d;
+        const unsigned int *bp = (const unsigned int *)buf.ui;
+
+        acc = rp[0];
+        acc -= bp[7 - 7];
+        acc -= bp[11 - 7];
+        rp[0] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[1];
+        acc -= bp[8 - 7];
+        acc -= bp[12 - 7];
+        rp[1] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[2];
+        acc -= bp[9 - 7];
+        acc -= bp[13 - 7];
+        rp[2] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[3];
+        acc += bp[7 - 7];
+        acc += bp[11 - 7];
+        acc -= bp[10 - 7];
+        rp[3] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[4];
+        acc += bp[8 - 7];
+        acc += bp[12 - 7];
+        acc -= bp[11 - 7];
+        rp[4] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[5];
+        acc += bp[9 - 7];
+        acc += bp[13 - 7];
+        acc -= bp[12 - 7];
+        rp[5] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[6];
+        acc += bp[10 - 7];
+        acc -= bp[13 - 7];
+        rp[6] = (unsigned int)acc;
+
+        carry = (int)(acc >> 32);
+# if BN_BITS2==64
+        rp[7] = carry;
+# endif
+    }
+#else
+    {
+        BN_ULONG t_d[BN_NIST_224_TOP];
+
+        nist_set_224(t_d, buf.bn, 10, 9, 8, 7, 0, 0, 0);
+        carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
+        nist_set_224(t_d, buf.bn, 0, 13, 12, 11, 0, 0, 0);
+        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
+        nist_set_224(t_d, buf.bn, 13, 12, 11, 10, 9, 8, 7);
+        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
+        nist_set_224(t_d, buf.bn, 0, 0, 0, 0, 13, 12, 11);
+        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
+
+# if BN_BITS2==64
+        carry = (int)(r_d[BN_NIST_224_TOP - 1] >> 32);
+# endif
+    }
+#endif
+    u.f = bn_sub_words;
+    if (carry > 0) {
+        carry =
+            (int)bn_sub_words(r_d, r_d, _nist_p_224[carry - 1],
+                              BN_NIST_224_TOP);
+#if BN_BITS2==64
+        carry = (int)(~(r_d[BN_NIST_224_TOP - 1] >> 32)) & 1;
+#endif
+    } else if (carry < 0) {
+        /*
+         * it's a bit more complicated logic in this case. if bn_add_words
+         * yields no carry, then result has to be adjusted by unconditionally
+         * *adding* the modulus. but if it does, then result has to be
+         * compared to the modulus and conditionally adjusted by
+         * *subtracting* the latter.
+         */
+        carry =
+            (int)bn_add_words(r_d, r_d, _nist_p_224[-carry - 1],
+                              BN_NIST_224_TOP);
+        mask = 0 - (PTR_SIZE_INT) carry;
+        u.p = ((PTR_SIZE_INT) bn_sub_words & mask) |
+            ((PTR_SIZE_INT) bn_add_words & ~mask);
+    } else
+        carry = 1;
+
+    /* otherwise it's effectively same as in BN_nist_mod_192... */
+    mask =
+        0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_224[0], BN_NIST_224_TOP);
+    mask &= 0 - (PTR_SIZE_INT) carry;
+    res = c_d;
+    res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) |
+                       ((PTR_SIZE_INT) r_d & mask));
+    nist_cp_bn(r_d, res, BN_NIST_224_TOP);
+    r->top = BN_NIST_224_TOP;
+    bn_correct_top(r);
+
+    return 1;
+}
+
+#define nist_set_256(to, from, a1, a2, a3, a4, a5, a6, a7, a8) \
+        { \
+        bn_cp_32(to, 0, from, (a8) - 8) \
+        bn_cp_32(to, 1, from, (a7) - 8) \
+        bn_cp_32(to, 2, from, (a6) - 8) \
+        bn_cp_32(to, 3, from, (a5) - 8) \
+        bn_cp_32(to, 4, from, (a4) - 8) \
+        bn_cp_32(to, 5, from, (a3) - 8) \
+        bn_cp_32(to, 6, from, (a2) - 8) \
+        bn_cp_32(to, 7, from, (a1) - 8) \
+        }
+
+int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
+                    BN_CTX *ctx)
+{
+    int i, top = a->top;
+    int carry = 0;
+    register BN_ULONG *a_d = a->d, *r_d;
+    union {
+        BN_ULONG bn[BN_NIST_256_TOP];
+        unsigned int ui[BN_NIST_256_TOP * sizeof(BN_ULONG) /
+                        sizeof(unsigned int)];
+    } buf;
+    BN_ULONG c_d[BN_NIST_256_TOP], *res;
+    PTR_SIZE_INT mask;
+    union {
+        bn_addsub_f f;
+        PTR_SIZE_INT p;
+    } u;
+    static const BIGNUM _bignum_nist_p_256_sqr = {
+        (BN_ULONG *)_nist_p_256_sqr,
+        OSSL_NELEM(_nist_p_256_sqr),
+        OSSL_NELEM(_nist_p_256_sqr),
+        0, BN_FLG_STATIC_DATA
+    };
+
+    field = &_bignum_nist_p_256; /* just to make sure */
+
+    if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_256_sqr) >= 0)
+        return BN_nnmod(r, a, field, ctx);
+
+    i = BN_ucmp(field, a);
+    if (i == 0) {
+        BN_zero(r);
+        return 1;
+    } else if (i > 0)
+        return (r == a) ? 1 : (BN_copy(r, a) != NULL);
+
+    if (r != a) {
+        if (!bn_wexpand(r, BN_NIST_256_TOP))
+            return 0;
+        r_d = r->d;
+        nist_cp_bn(r_d, a_d, BN_NIST_256_TOP);
+    } else
+        r_d = a_d;
+
+    nist_cp_bn_0(buf.bn, a_d + BN_NIST_256_TOP, top - BN_NIST_256_TOP,
+                 BN_NIST_256_TOP);
+
+#if defined(NIST_INT64)
+    {
+        NIST_INT64 acc;         /* accumulator */
+        unsigned int *rp = (unsigned int *)r_d;
+        const unsigned int *bp = (const unsigned int *)buf.ui;
+
+        acc = rp[0];
+        acc += bp[8 - 8];
+        acc += bp[9 - 8];
+        acc -= bp[11 - 8];
+        acc -= bp[12 - 8];
+        acc -= bp[13 - 8];
+        acc -= bp[14 - 8];
+        rp[0] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[1];
+        acc += bp[9 - 8];
+        acc += bp[10 - 8];
+        acc -= bp[12 - 8];
+        acc -= bp[13 - 8];
+        acc -= bp[14 - 8];
+        acc -= bp[15 - 8];
+        rp[1] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[2];
+        acc += bp[10 - 8];
+        acc += bp[11 - 8];
+        acc -= bp[13 - 8];
+        acc -= bp[14 - 8];
+        acc -= bp[15 - 8];
+        rp[2] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[3];
+        acc += bp[11 - 8];
+        acc += bp[11 - 8];
+        acc += bp[12 - 8];
+        acc += bp[12 - 8];
+        acc += bp[13 - 8];
+        acc -= bp[15 - 8];
+        acc -= bp[8 - 8];
+        acc -= bp[9 - 8];
+        rp[3] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[4];
+        acc += bp[12 - 8];
+        acc += bp[12 - 8];
+        acc += bp[13 - 8];
+        acc += bp[13 - 8];
+        acc += bp[14 - 8];
+        acc -= bp[9 - 8];
+        acc -= bp[10 - 8];
+        rp[4] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[5];
+        acc += bp[13 - 8];
+        acc += bp[13 - 8];
+        acc += bp[14 - 8];
+        acc += bp[14 - 8];
+        acc += bp[15 - 8];
+        acc -= bp[10 - 8];
+        acc -= bp[11 - 8];
+        rp[5] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[6];
+        acc += bp[14 - 8];
+        acc += bp[14 - 8];
+        acc += bp[15 - 8];
+        acc += bp[15 - 8];
+        acc += bp[14 - 8];
+        acc += bp[13 - 8];
+        acc -= bp[8 - 8];
+        acc -= bp[9 - 8];
+        rp[6] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[7];
+        acc += bp[15 - 8];
+        acc += bp[15 - 8];
+        acc += bp[15 - 8];
+        acc += bp[8 - 8];
+        acc -= bp[10 - 8];
+        acc -= bp[11 - 8];
+        acc -= bp[12 - 8];
+        acc -= bp[13 - 8];
+        rp[7] = (unsigned int)acc;
+
+        carry = (int)(acc >> 32);
+    }
+#else
+    {
+        BN_ULONG t_d[BN_NIST_256_TOP];
+
+        /*
+         * S1
+         */
+        nist_set_256(t_d, buf.bn, 15, 14, 13, 12, 11, 0, 0, 0);
+        /*
+         * S2
+         */
+        nist_set_256(c_d, buf.bn, 0, 15, 14, 13, 12, 0, 0, 0);
+        carry = (int)bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP);
+        /* left shift */
+        {
+            register BN_ULONG *ap, t, c;
+            ap = t_d;
+            c = 0;
+            for (i = BN_NIST_256_TOP; i != 0; --i) {
+                t = *ap;
+                *(ap++) = ((t << 1) | c) & BN_MASK2;
+                c = (t & BN_TBIT) ? 1 : 0;
+            }
+            carry <<= 1;
+            carry |= c;
+        }
+        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+        /*
+         * S3
+         */
+        nist_set_256(t_d, buf.bn, 15, 14, 0, 0, 0, 10, 9, 8);
+        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+        /*
+         * S4
+         */
+        nist_set_256(t_d, buf.bn, 8, 13, 15, 14, 13, 11, 10, 9);
+        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+        /*
+         * D1
+         */
+        nist_set_256(t_d, buf.bn, 10, 8, 0, 0, 0, 13, 12, 11);
+        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+        /*
+         * D2
+         */
+        nist_set_256(t_d, buf.bn, 11, 9, 0, 0, 15, 14, 13, 12);
+        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+        /*
+         * D3
+         */
+        nist_set_256(t_d, buf.bn, 12, 0, 10, 9, 8, 15, 14, 13);
+        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+        /*
+         * D4
+         */
+        nist_set_256(t_d, buf.bn, 13, 0, 11, 10, 9, 0, 15, 14);
+        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
+
+    }
+#endif
+    /* see BN_nist_mod_224 for explanation */
+    u.f = bn_sub_words;
+    if (carry > 0)
+        carry =
+            (int)bn_sub_words(r_d, r_d, _nist_p_256[carry - 1],
+                              BN_NIST_256_TOP);
+    else if (carry < 0) {
+        carry =
+            (int)bn_add_words(r_d, r_d, _nist_p_256[-carry - 1],
+                              BN_NIST_256_TOP);
+        mask = 0 - (PTR_SIZE_INT) carry;
+        u.p = ((PTR_SIZE_INT) bn_sub_words & mask) |
+            ((PTR_SIZE_INT) bn_add_words & ~mask);
+    } else
+        carry = 1;
+
+    mask =
+        0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_256[0], BN_NIST_256_TOP);
+    mask &= 0 - (PTR_SIZE_INT) carry;
+    res = c_d;
+    res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) |
+                       ((PTR_SIZE_INT) r_d & mask));
+    nist_cp_bn(r_d, res, BN_NIST_256_TOP);
+    r->top = BN_NIST_256_TOP;
+    bn_correct_top(r);
+
+    return 1;
+}
+
+#define nist_set_384(to,from,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \
+        { \
+        bn_cp_32(to, 0, from,  (a12) - 12) \
+        bn_cp_32(to, 1, from,  (a11) - 12) \
+        bn_cp_32(to, 2, from,  (a10) - 12) \
+        bn_cp_32(to, 3, from,  (a9) - 12)  \
+        bn_cp_32(to, 4, from,  (a8) - 12)  \
+        bn_cp_32(to, 5, from,  (a7) - 12)  \
+        bn_cp_32(to, 6, from,  (a6) - 12)  \
+        bn_cp_32(to, 7, from,  (a5) - 12)  \
+        bn_cp_32(to, 8, from,  (a4) - 12)  \
+        bn_cp_32(to, 9, from,  (a3) - 12)  \
+        bn_cp_32(to, 10, from, (a2) - 12)  \
+        bn_cp_32(to, 11, from, (a1) - 12)  \
+        }
+
+int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
+                    BN_CTX *ctx)
+{
+    int i, top = a->top;
+    int carry = 0;
+    register BN_ULONG *r_d, *a_d = a->d;
+    union {
+        BN_ULONG bn[BN_NIST_384_TOP];
+        unsigned int ui[BN_NIST_384_TOP * sizeof(BN_ULONG) /
+                        sizeof(unsigned int)];
+    } buf;
+    BN_ULONG c_d[BN_NIST_384_TOP], *res;
+    PTR_SIZE_INT mask;
+    union {
+        bn_addsub_f f;
+        PTR_SIZE_INT p;
+    } u;
+    static const BIGNUM _bignum_nist_p_384_sqr = {
+        (BN_ULONG *)_nist_p_384_sqr,
+        OSSL_NELEM(_nist_p_384_sqr),
+        OSSL_NELEM(_nist_p_384_sqr),
+        0, BN_FLG_STATIC_DATA
+    };
+
+    field = &_bignum_nist_p_384; /* just to make sure */
+
+    if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_384_sqr) >= 0)
+        return BN_nnmod(r, a, field, ctx);
+
+    i = BN_ucmp(field, a);
+    if (i == 0) {
+        BN_zero(r);
+        return 1;
+    } else if (i > 0)
+        return (r == a) ? 1 : (BN_copy(r, a) != NULL);
+
+    if (r != a) {
+        if (!bn_wexpand(r, BN_NIST_384_TOP))
+            return 0;
+        r_d = r->d;
+        nist_cp_bn(r_d, a_d, BN_NIST_384_TOP);
+    } else
+        r_d = a_d;
+
+    nist_cp_bn_0(buf.bn, a_d + BN_NIST_384_TOP, top - BN_NIST_384_TOP,
+                 BN_NIST_384_TOP);
+
+#if defined(NIST_INT64)
+    {
+        NIST_INT64 acc;         /* accumulator */
+        unsigned int *rp = (unsigned int *)r_d;
+        const unsigned int *bp = (const unsigned int *)buf.ui;
+
+        acc = rp[0];
+        acc += bp[12 - 12];
+        acc += bp[21 - 12];
+        acc += bp[20 - 12];
+        acc -= bp[23 - 12];
+        rp[0] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[1];
+        acc += bp[13 - 12];
+        acc += bp[22 - 12];
+        acc += bp[23 - 12];
+        acc -= bp[12 - 12];
+        acc -= bp[20 - 12];
+        rp[1] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[2];
+        acc += bp[14 - 12];
+        acc += bp[23 - 12];
+        acc -= bp[13 - 12];
+        acc -= bp[21 - 12];
+        rp[2] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[3];
+        acc += bp[15 - 12];
+        acc += bp[12 - 12];
+        acc += bp[20 - 12];
+        acc += bp[21 - 12];
+        acc -= bp[14 - 12];
+        acc -= bp[22 - 12];
+        acc -= bp[23 - 12];
+        rp[3] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[4];
+        acc += bp[21 - 12];
+        acc += bp[21 - 12];
+        acc += bp[16 - 12];
+        acc += bp[13 - 12];
+        acc += bp[12 - 12];
+        acc += bp[20 - 12];
+        acc += bp[22 - 12];
+        acc -= bp[15 - 12];
+        acc -= bp[23 - 12];
+        acc -= bp[23 - 12];
+        rp[4] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[5];
+        acc += bp[22 - 12];
+        acc += bp[22 - 12];
+        acc += bp[17 - 12];
+        acc += bp[14 - 12];
+        acc += bp[13 - 12];
+        acc += bp[21 - 12];
+        acc += bp[23 - 12];
+        acc -= bp[16 - 12];
+        rp[5] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[6];
+        acc += bp[23 - 12];
+        acc += bp[23 - 12];
+        acc += bp[18 - 12];
+        acc += bp[15 - 12];
+        acc += bp[14 - 12];
+        acc += bp[22 - 12];
+        acc -= bp[17 - 12];
+        rp[6] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[7];
+        acc += bp[19 - 12];
+        acc += bp[16 - 12];
+        acc += bp[15 - 12];
+        acc += bp[23 - 12];
+        acc -= bp[18 - 12];
+        rp[7] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[8];
+        acc += bp[20 - 12];
+        acc += bp[17 - 12];
+        acc += bp[16 - 12];
+        acc -= bp[19 - 12];
+        rp[8] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[9];
+        acc += bp[21 - 12];
+        acc += bp[18 - 12];
+        acc += bp[17 - 12];
+        acc -= bp[20 - 12];
+        rp[9] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[10];
+        acc += bp[22 - 12];
+        acc += bp[19 - 12];
+        acc += bp[18 - 12];
+        acc -= bp[21 - 12];
+        rp[10] = (unsigned int)acc;
+        acc >>= 32;
+
+        acc += rp[11];
+        acc += bp[23 - 12];
+        acc += bp[20 - 12];
+        acc += bp[19 - 12];
+        acc -= bp[22 - 12];
+        rp[11] = (unsigned int)acc;
+
+        carry = (int)(acc >> 32);
+    }
+#else
+    {
+        BN_ULONG t_d[BN_NIST_384_TOP];
+
+        /*
+         * S1
+         */
+        nist_set_256(t_d, buf.bn, 0, 0, 0, 0, 0, 23 - 4, 22 - 4, 21 - 4);
+        /* left shift */
+        {
+            register BN_ULONG *ap, t, c;
+            ap = t_d;
+            c = 0;
+            for (i = 3; i != 0; --i) {
+                t = *ap;
+                *(ap++) = ((t << 1) | c) & BN_MASK2;
+                c = (t & BN_TBIT) ? 1 : 0;
+            }
+            *ap = c;
+        }
+        carry =
+            (int)bn_add_words(r_d + (128 / BN_BITS2), r_d + (128 / BN_BITS2),
+                              t_d, BN_NIST_256_TOP);
+        /*
+         * S2
+         */
+        carry += (int)bn_add_words(r_d, r_d, buf.bn, BN_NIST_384_TOP);
+        /*
+         * S3
+         */
+        nist_set_384(t_d, buf.bn, 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 22,
+                     21);
+        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+        /*
+         * S4
+         */
+        nist_set_384(t_d, buf.bn, 19, 18, 17, 16, 15, 14, 13, 12, 20, 0, 23,
+                     0);
+        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+        /*
+         * S5
+         */
+        nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 23, 22, 21, 20, 0, 0, 0, 0);
+        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+        /*
+         * S6
+         */
+        nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 23, 22, 21, 0, 0, 20);
+        carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+        /*
+         * D1
+         */
+        nist_set_384(t_d, buf.bn, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12,
+                     23);
+        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+        /*
+         * D2
+         */
+        nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 0, 23, 22, 21, 20, 0);
+        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+        /*
+         * D3
+         */
+        nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 0, 23, 23, 0, 0, 0);
+        carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
+
+    }
+#endif
+    /* see BN_nist_mod_224 for explanation */
+    u.f = bn_sub_words;
+    if (carry > 0)
+        carry =
+            (int)bn_sub_words(r_d, r_d, _nist_p_384[carry - 1],
+                              BN_NIST_384_TOP);
+    else if (carry < 0) {
+        carry =
+            (int)bn_add_words(r_d, r_d, _nist_p_384[-carry - 1],
+                              BN_NIST_384_TOP);
+        mask = 0 - (PTR_SIZE_INT) carry;
+        u.p = ((PTR_SIZE_INT) bn_sub_words & mask) |
+            ((PTR_SIZE_INT) bn_add_words & ~mask);
+    } else
+        carry = 1;
+
+    mask =
+        0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_384[0], BN_NIST_384_TOP);
+    mask &= 0 - (PTR_SIZE_INT) carry;
+    res = c_d;
+    res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) |
+                       ((PTR_SIZE_INT) r_d & mask));
+    nist_cp_bn(r_d, res, BN_NIST_384_TOP);
+    r->top = BN_NIST_384_TOP;
+    bn_correct_top(r);
+
+    return 1;
+}
+
+#define BN_NIST_521_RSHIFT      (521%BN_BITS2)
+#define BN_NIST_521_LSHIFT      (BN_BITS2-BN_NIST_521_RSHIFT)
+#define BN_NIST_521_TOP_MASK    ((BN_ULONG)BN_MASK2>>BN_NIST_521_LSHIFT)
+
+int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
+                    BN_CTX *ctx)
+{
+    int top = a->top, i;
+    BN_ULONG *r_d, *a_d = a->d, t_d[BN_NIST_521_TOP], val, tmp, *res;
+    PTR_SIZE_INT mask;
+    static const BIGNUM _bignum_nist_p_521_sqr = {
+        (BN_ULONG *)_nist_p_521_sqr,
+        OSSL_NELEM(_nist_p_521_sqr),
+        OSSL_NELEM(_nist_p_521_sqr),
+        0, BN_FLG_STATIC_DATA
+    };
+
+    field = &_bignum_nist_p_521; /* just to make sure */
+
+    if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_521_sqr) >= 0)
+        return BN_nnmod(r, a, field, ctx);
+
+    i = BN_ucmp(field, a);
+    if (i == 0) {
+        BN_zero(r);
+        return 1;
+    } else if (i > 0)
+        return (r == a) ? 1 : (BN_copy(r, a) != NULL);
+
+    if (r != a) {
+        if (!bn_wexpand(r, BN_NIST_521_TOP))
+            return 0;
+        r_d = r->d;
+        nist_cp_bn(r_d, a_d, BN_NIST_521_TOP);
+    } else
+        r_d = a_d;
+
+    /* upper 521 bits, copy ... */
+    nist_cp_bn_0(t_d, a_d + (BN_NIST_521_TOP - 1),
+                 top - (BN_NIST_521_TOP - 1), BN_NIST_521_TOP);
+    /* ... and right shift */
+    for (val = t_d[0], i = 0; i < BN_NIST_521_TOP - 1; i++) {
+#if 0
+        /*
+         * MSC ARM compiler [version 2013, presumably even earlier,
+         * much earlier] miscompiles this code, but not one in
+         * #else section. See RT#3541.
+         */
+        tmp = val >> BN_NIST_521_RSHIFT;
+        val = t_d[i + 1];
+        t_d[i] = (tmp | val << BN_NIST_521_LSHIFT) & BN_MASK2;
+#else
+        t_d[i] = (val >> BN_NIST_521_RSHIFT |
+                  (tmp = t_d[i + 1]) << BN_NIST_521_LSHIFT) & BN_MASK2;
+        val = tmp;
+#endif
+    }
+    t_d[i] = val >> BN_NIST_521_RSHIFT;
+    /* lower 521 bits */
+    r_d[i] &= BN_NIST_521_TOP_MASK;
+
+    bn_add_words(r_d, r_d, t_d, BN_NIST_521_TOP);
+    mask =
+        0 - (PTR_SIZE_INT) bn_sub_words(t_d, r_d, _nist_p_521,
+                                        BN_NIST_521_TOP);
+    res = t_d;
+    res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) |
+                       ((PTR_SIZE_INT) r_d & mask));
+    nist_cp_bn(r_d, res, BN_NIST_521_TOP);
+    r->top = BN_NIST_521_TOP;
+    bn_correct_top(r);
+
+    return 1;
+}
+
+int (*BN_nist_mod_func(const BIGNUM *p)) (BIGNUM *r, const BIGNUM *a,
+                                          const BIGNUM *field, BN_CTX *ctx) {
+    if (BN_ucmp(&_bignum_nist_p_192, p) == 0)
+        return BN_nist_mod_192;
+    if (BN_ucmp(&_bignum_nist_p_224, p) == 0)
+        return BN_nist_mod_224;
+    if (BN_ucmp(&_bignum_nist_p_256, p) == 0)
+        return BN_nist_mod_256;
+    if (BN_ucmp(&_bignum_nist_p_384, p) == 0)
+        return BN_nist_mod_384;
+    if (BN_ucmp(&_bignum_nist_p_521, p) == 0)
+        return BN_nist_mod_521;
+    return 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_prime.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_prime.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_prime.c	(revision 331)
@@ -0,0 +1,608 @@
+/*
+ * WARNING: do not edit!
+ * Generated by crypto/bn/bn_prime.pl
+ * Copyright 1995-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 <stdio.h>
+#include <time.h>
+#include "internal/cryptlib.h"
+#include "bn_lcl.h"
+
+/*
+ * The quick sieve algorithm approach to weeding out primes is Philip
+ * Zimmermann's, as implemented in PGP.  I have had a read of his comments
+ * and implemented my own version.
+ */
+#include "bn_prime.h"
+
+static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
+                   const BIGNUM *a1_odd, int k, BN_CTX *ctx,
+                   BN_MONT_CTX *mont);
+static int probable_prime(BIGNUM *rnd, int bits, prime_t *mods);
+static int probable_prime_dh_safe(BIGNUM *rnd, int bits,
+                                  const BIGNUM *add, const BIGNUM *rem,
+                                  BN_CTX *ctx);
+
+static const int prime_offsets[480] = {
+    13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83,
+    89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163,
+    167, 169, 173, 179, 181, 191, 193, 197, 199, 211, 221, 223, 227, 229,
+    233, 239, 241, 247, 251, 257, 263, 269, 271, 277, 281, 283, 289, 293,
+    299, 307, 311, 313, 317, 323, 331, 337, 347, 349, 353, 359, 361, 367,
+    373, 377, 379, 383, 389, 391, 397, 401, 403, 409, 419, 421, 431, 433,
+    437, 439, 443, 449, 457, 461, 463, 467, 479, 481, 487, 491, 493, 499,
+    503, 509, 521, 523, 527, 529, 533, 541, 547, 551, 557, 559, 563, 569,
+    571, 577, 587, 589, 593, 599, 601, 607, 611, 613, 617, 619, 629, 631,
+    641, 643, 647, 653, 659, 661, 667, 673, 677, 683, 689, 691, 697, 701,
+    703, 709, 713, 719, 727, 731, 733, 739, 743, 751, 757, 761, 767, 769,
+    773, 779, 787, 793, 797, 799, 809, 811, 817, 821, 823, 827, 829, 839,
+    841, 851, 853, 857, 859, 863, 871, 877, 881, 883, 887, 893, 899, 901,
+    907, 911, 919, 923, 929, 937, 941, 943, 947, 949, 953, 961, 967, 971,
+    977, 983, 989, 991, 997, 1003, 1007, 1009, 1013, 1019, 1021, 1027, 1031,
+    1033, 1037, 1039, 1049, 1051, 1061, 1063, 1069, 1073, 1079, 1081, 1087,
+    1091, 1093, 1097, 1103, 1109, 1117, 1121, 1123, 1129, 1139, 1147, 1151,
+    1153, 1157, 1159, 1163, 1171, 1181, 1187, 1189, 1193, 1201, 1207, 1213,
+    1217, 1219, 1223, 1229, 1231, 1237, 1241, 1247, 1249, 1259, 1261, 1271,
+    1273, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1313, 1319,
+    1321, 1327, 1333, 1339, 1343, 1349, 1357, 1361, 1363, 1367, 1369, 1373,
+    1381, 1387, 1391, 1399, 1403, 1409, 1411, 1417, 1423, 1427, 1429, 1433,
+    1439, 1447, 1451, 1453, 1457, 1459, 1469, 1471, 1481, 1483, 1487, 1489,
+    1493, 1499, 1501, 1511, 1513, 1517, 1523, 1531, 1537, 1541, 1543, 1549,
+    1553, 1559, 1567, 1571, 1577, 1579, 1583, 1591, 1597, 1601, 1607, 1609,
+    1613, 1619, 1621, 1627, 1633, 1637, 1643, 1649, 1651, 1657, 1663, 1667,
+    1669, 1679, 1681, 1691, 1693, 1697, 1699, 1703, 1709, 1711, 1717, 1721,
+    1723, 1733, 1739, 1741, 1747, 1751, 1753, 1759, 1763, 1769, 1777, 1781,
+    1783, 1787, 1789, 1801, 1807, 1811, 1817, 1819, 1823, 1829, 1831, 1843,
+    1847, 1849, 1853, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1891, 1901,
+    1907, 1909, 1913, 1919, 1921, 1927, 1931, 1933, 1937, 1943, 1949, 1951,
+    1957, 1961, 1963, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017,
+    2021, 2027, 2029, 2033, 2039, 2041, 2047, 2053, 2059, 2063, 2069, 2071,
+    2077, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2117, 2119, 2129, 2131,
+    2137, 2141, 2143, 2147, 2153, 2159, 2161, 2171, 2173, 2179, 2183, 2197,
+    2201, 2203, 2207, 2209, 2213, 2221, 2227, 2231, 2237, 2239, 2243, 2249,
+    2251, 2257, 2263, 2267, 2269, 2273, 2279, 2281, 2287, 2291, 2293, 2297,
+    2309, 2311
+};
+
+static const int prime_offset_count = 480;
+static const int prime_multiplier = 2310;
+static const int prime_multiplier_bits = 11; /* 2^|prime_multiplier_bits| <=
+                                              * |prime_multiplier| */
+static const int first_prime_index = 5;
+
+int BN_GENCB_call(BN_GENCB *cb, int a, int b)
+{
+    /* No callback means continue */
+    if (!cb)
+        return 1;
+    switch (cb->ver) {
+    case 1:
+        /* Deprecated-style callbacks */
+        if (!cb->cb.cb_1)
+            return 1;
+        cb->cb.cb_1(a, b, cb->arg);
+        return 1;
+    case 2:
+        /* New-style callbacks */
+        return cb->cb.cb_2(a, b, cb);
+    default:
+        break;
+    }
+    /* Unrecognised callback type */
+    return 0;
+}
+
+int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe,
+                         const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb)
+{
+    BIGNUM *t;
+    int found = 0;
+    int i, j, c1 = 0;
+    BN_CTX *ctx = NULL;
+    prime_t *mods = NULL;
+    int checks = BN_prime_checks_for_size(bits);
+
+    if (bits < 2) {
+        /* There are no prime numbers this small. */
+        BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL);
+        return 0;
+    } else if (bits == 2 && safe) {
+        /* The smallest safe prime (7) is three bits. */
+        BNerr(BN_F_BN_GENERATE_PRIME_EX, BN_R_BITS_TOO_SMALL);
+        return 0;
+    }
+
+    mods = OPENSSL_zalloc(sizeof(*mods) * NUMPRIMES);
+    if (mods == NULL)
+        goto err;
+
+    ctx = BN_CTX_new();
+    if (ctx == NULL)
+        goto err;
+    BN_CTX_start(ctx);
+    t = BN_CTX_get(ctx);
+    if (!t)
+        goto err;
+ loop:
+    /* make a random number and set the top and bottom bits */
+    if (add == NULL) {
+        if (!probable_prime(ret, bits, mods))
+            goto err;
+    } else {
+        if (safe) {
+            if (!probable_prime_dh_safe(ret, bits, add, rem, ctx))
+                goto err;
+        } else {
+            if (!bn_probable_prime_dh(ret, bits, add, rem, ctx))
+                goto err;
+        }
+    }
+
+    if (!BN_GENCB_call(cb, 0, c1++))
+        /* aborted */
+        goto err;
+
+    if (!safe) {
+        i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb);
+        if (i == -1)
+            goto err;
+        if (i == 0)
+            goto loop;
+    } else {
+        /*
+         * for "safe prime" generation, check that (p-1)/2 is prime. Since a
+         * prime is odd, We just need to divide by 2
+         */
+        if (!BN_rshift1(t, ret))
+            goto err;
+
+        for (i = 0; i < checks; i++) {
+            j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, cb);
+            if (j == -1)
+                goto err;
+            if (j == 0)
+                goto loop;
+
+            j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, cb);
+            if (j == -1)
+                goto err;
+            if (j == 0)
+                goto loop;
+
+            if (!BN_GENCB_call(cb, 2, c1 - 1))
+                goto err;
+            /* We have a safe prime test pass */
+        }
+    }
+    /* we have a prime :-) */
+    found = 1;
+ err:
+    OPENSSL_free(mods);
+    if (ctx != NULL)
+        BN_CTX_end(ctx);
+    BN_CTX_free(ctx);
+    bn_check_top(ret);
+    return found;
+}
+
+int BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
+                   BN_GENCB *cb)
+{
+    return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb);
+}
+
+int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
+                            int do_trial_division, BN_GENCB *cb)
+{
+    int i, j, ret = -1;
+    int k;
+    BN_CTX *ctx = NULL;
+    BIGNUM *A1, *A1_odd, *check; /* taken from ctx */
+    BN_MONT_CTX *mont = NULL;
+    const BIGNUM *A = NULL;
+
+    if (BN_cmp(a, BN_value_one()) <= 0)
+        return 0;
+
+    if (checks == BN_prime_checks)
+        checks = BN_prime_checks_for_size(BN_num_bits(a));
+
+    /* first look for small factors */
+    if (!BN_is_odd(a))
+        /* a is even => a is prime if and only if a == 2 */
+        return BN_is_word(a, 2);
+    if (do_trial_division) {
+        for (i = 1; i < NUMPRIMES; i++) {
+            BN_ULONG mod = BN_mod_word(a, primes[i]);
+            if (mod == (BN_ULONG)-1)
+                goto err;
+            if (mod == 0)
+                return 0;
+        }
+        if (!BN_GENCB_call(cb, 1, -1))
+            goto err;
+    }
+
+    if (ctx_passed != NULL)
+        ctx = ctx_passed;
+    else if ((ctx = BN_CTX_new()) == NULL)
+        goto err;
+    BN_CTX_start(ctx);
+
+    /* A := abs(a) */
+    if (a->neg) {
+        BIGNUM *t;
+        if ((t = BN_CTX_get(ctx)) == NULL)
+            goto err;
+        if (BN_copy(t, a) == NULL)
+            goto err;
+        t->neg = 0;
+        A = t;
+    } else
+        A = a;
+    A1 = BN_CTX_get(ctx);
+    A1_odd = BN_CTX_get(ctx);
+    check = BN_CTX_get(ctx);
+    if (check == NULL)
+        goto err;
+
+    /* compute A1 := A - 1 */
+    if (!BN_copy(A1, A))
+        goto err;
+    if (!BN_sub_word(A1, 1))
+        goto err;
+    if (BN_is_zero(A1)) {
+        ret = 0;
+        goto err;
+    }
+
+    /* write  A1  as  A1_odd * 2^k */
+    k = 1;
+    while (!BN_is_bit_set(A1, k))
+        k++;
+    if (!BN_rshift(A1_odd, A1, k))
+        goto err;
+
+    /* Montgomery setup for computations mod A */
+    mont = BN_MONT_CTX_new();
+    if (mont == NULL)
+        goto err;
+    if (!BN_MONT_CTX_set(mont, A, ctx))
+        goto err;
+
+    for (i = 0; i < checks; i++) {
+        if (!BN_pseudo_rand_range(check, A1))
+            goto err;
+        if (!BN_add_word(check, 1))
+            goto err;
+        /* now 1 <= check < A */
+
+        j = witness(check, A, A1, A1_odd, k, ctx, mont);
+        if (j == -1)
+            goto err;
+        if (j) {
+            ret = 0;
+            goto err;
+        }
+        if (!BN_GENCB_call(cb, 1, i))
+            goto err;
+    }
+    ret = 1;
+ err:
+    if (ctx != NULL) {
+        BN_CTX_end(ctx);
+        if (ctx_passed == NULL)
+            BN_CTX_free(ctx);
+    }
+    BN_MONT_CTX_free(mont);
+
+    return (ret);
+}
+
+int bn_probable_prime_dh_retry(BIGNUM *rnd, int bits, BN_CTX *ctx)
+{
+    int i;
+    int ret = 0;
+
+ loop:
+    if (!BN_rand(rnd, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD))
+        goto err;
+
+    /* we now have a random number 'rand' to test. */
+
+    for (i = 1; i < NUMPRIMES; i++) {
+        /* check that rnd is a prime */
+        BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]);
+        if (mod == (BN_ULONG)-1)
+            goto err;
+        if (mod <= 1) {
+            goto loop;
+        }
+    }
+    ret = 1;
+
+ err:
+    bn_check_top(rnd);
+    return (ret);
+}
+
+int bn_probable_prime_dh_coprime(BIGNUM *rnd, int bits, BN_CTX *ctx)
+{
+    int i;
+    BIGNUM *offset_index;
+    BIGNUM *offset_count;
+    int ret = 0;
+
+    OPENSSL_assert(bits > prime_multiplier_bits);
+
+    BN_CTX_start(ctx);
+    if ((offset_index = BN_CTX_get(ctx)) == NULL)
+        goto err;
+    if ((offset_count = BN_CTX_get(ctx)) == NULL)
+        goto err;
+
+    if (!BN_add_word(offset_count, prime_offset_count))
+        goto err;
+
+ loop:
+    if (!BN_rand(rnd, bits - prime_multiplier_bits,
+                 BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD))
+        goto err;
+    if (BN_is_bit_set(rnd, bits))
+        goto loop;
+    if (!BN_rand_range(offset_index, offset_count))
+        goto err;
+
+    if (!BN_mul_word(rnd, prime_multiplier)
+        || !BN_add_word(rnd, prime_offsets[BN_get_word(offset_index)]))
+        goto err;
+
+    /* we now have a random number 'rand' to test. */
+
+    /* skip coprimes */
+    for (i = first_prime_index; i < NUMPRIMES; i++) {
+        /* check that rnd is a prime */
+        BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]);
+        if (mod == (BN_ULONG)-1)
+            goto err;
+        if (mod <= 1)
+            goto loop;
+    }
+    ret = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    bn_check_top(rnd);
+    return ret;
+}
+
+static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1,
+                   const BIGNUM *a1_odd, int k, BN_CTX *ctx,
+                   BN_MONT_CTX *mont)
+{
+    if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */
+        return -1;
+    if (BN_is_one(w))
+        return 0;               /* probably prime */
+    if (BN_cmp(w, a1) == 0)
+        return 0;               /* w == -1 (mod a), 'a' is probably prime */
+    while (--k) {
+        if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */
+            return -1;
+        if (BN_is_one(w))
+            return 1;           /* 'a' is composite, otherwise a previous 'w'
+                                 * would have been == -1 (mod 'a') */
+        if (BN_cmp(w, a1) == 0)
+            return 0;           /* w == -1 (mod a), 'a' is probably prime */
+    }
+    /*
+     * If we get here, 'w' is the (a-1)/2-th power of the original 'w', and
+     * it is neither -1 nor +1 -- so 'a' cannot be prime
+     */
+    bn_check_top(w);
+    return 1;
+}
+
+static int probable_prime(BIGNUM *rnd, int bits, prime_t *mods)
+{
+    int i;
+    BN_ULONG delta;
+    BN_ULONG maxdelta = BN_MASK2 - primes[NUMPRIMES - 1];
+    char is_single_word = bits <= BN_BITS2;
+
+ again:
+    if (!BN_rand(rnd, bits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ODD))
+        return (0);
+    /* we now have a random number 'rnd' to test. */
+    for (i = 1; i < NUMPRIMES; i++) {
+        BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]);
+        if (mod == (BN_ULONG)-1)
+            return 0;
+        mods[i] = (prime_t) mod;
+    }
+    /*
+     * If bits is so small that it fits into a single word then we
+     * additionally don't want to exceed that many bits.
+     */
+    if (is_single_word) {
+        BN_ULONG size_limit;
+
+        if (bits == BN_BITS2) {
+            /*
+             * Shifting by this much has undefined behaviour so we do it a
+             * different way
+             */
+            size_limit = ~((BN_ULONG)0) - BN_get_word(rnd);
+        } else {
+            size_limit = (((BN_ULONG)1) << bits) - BN_get_word(rnd) - 1;
+        }
+        if (size_limit < maxdelta)
+            maxdelta = size_limit;
+    }
+    delta = 0;
+ loop:
+    if (is_single_word) {
+        BN_ULONG rnd_word = BN_get_word(rnd);
+
+        /*-
+         * In the case that the candidate prime is a single word then
+         * we check that:
+         *   1) It's greater than primes[i] because we shouldn't reject
+         *      3 as being a prime number because it's a multiple of
+         *      three.
+         *   2) That it's not a multiple of a known prime. We don't
+         *      check that rnd-1 is also coprime to all the known
+         *      primes because there aren't many small primes where
+         *      that's true.
+         */
+        for (i = 1; i < NUMPRIMES && primes[i] < rnd_word; i++) {
+            if ((mods[i] + delta) % primes[i] == 0) {
+                delta += 2;
+                if (delta > maxdelta)
+                    goto again;
+                goto loop;
+            }
+        }
+    } else {
+        for (i = 1; i < NUMPRIMES; i++) {
+            /*
+             * check that rnd is not a prime and also that gcd(rnd-1,primes)
+             * == 1 (except for 2)
+             */
+            if (((mods[i] + delta) % primes[i]) <= 1) {
+                delta += 2;
+                if (delta > maxdelta)
+                    goto again;
+                goto loop;
+            }
+        }
+    }
+    if (!BN_add_word(rnd, delta))
+        return (0);
+    if (BN_num_bits(rnd) != bits)
+        goto again;
+    bn_check_top(rnd);
+    return (1);
+}
+
+int bn_probable_prime_dh(BIGNUM *rnd, int bits,
+                         const BIGNUM *add, const BIGNUM *rem, BN_CTX *ctx)
+{
+    int i, ret = 0;
+    BIGNUM *t1;
+
+    BN_CTX_start(ctx);
+    if ((t1 = BN_CTX_get(ctx)) == NULL)
+        goto err;
+
+    if (!BN_rand(rnd, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD))
+        goto err;
+
+    /* we need ((rnd-rem) % add) == 0 */
+
+    if (!BN_mod(t1, rnd, add, ctx))
+        goto err;
+    if (!BN_sub(rnd, rnd, t1))
+        goto err;
+    if (rem == NULL) {
+        if (!BN_add_word(rnd, 1))
+            goto err;
+    } else {
+        if (!BN_add(rnd, rnd, rem))
+            goto err;
+    }
+
+    /* we now have a random number 'rand' to test. */
+
+ loop:
+    for (i = 1; i < NUMPRIMES; i++) {
+        /* check that rnd is a prime */
+        BN_ULONG mod = BN_mod_word(rnd, (BN_ULONG)primes[i]);
+        if (mod == (BN_ULONG)-1)
+            goto err;
+        if (mod <= 1) {
+            if (!BN_add(rnd, rnd, add))
+                goto err;
+            goto loop;
+        }
+    }
+    ret = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    bn_check_top(rnd);
+    return (ret);
+}
+
+static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd,
+                                  const BIGNUM *rem, BN_CTX *ctx)
+{
+    int i, ret = 0;
+    BIGNUM *t1, *qadd, *q;
+
+    bits--;
+    BN_CTX_start(ctx);
+    t1 = BN_CTX_get(ctx);
+    q = BN_CTX_get(ctx);
+    qadd = BN_CTX_get(ctx);
+    if (qadd == NULL)
+        goto err;
+
+    if (!BN_rshift1(qadd, padd))
+        goto err;
+
+    if (!BN_rand(q, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD))
+        goto err;
+
+    /* we need ((rnd-rem) % add) == 0 */
+    if (!BN_mod(t1, q, qadd, ctx))
+        goto err;
+    if (!BN_sub(q, q, t1))
+        goto err;
+    if (rem == NULL) {
+        if (!BN_add_word(q, 1))
+            goto err;
+    } else {
+        if (!BN_rshift1(t1, rem))
+            goto err;
+        if (!BN_add(q, q, t1))
+            goto err;
+    }
+
+    /* we now have a random number 'rand' to test. */
+    if (!BN_lshift1(p, q))
+        goto err;
+    if (!BN_add_word(p, 1))
+        goto err;
+
+ loop:
+    for (i = 1; i < NUMPRIMES; i++) {
+        /* check that p and q are prime */
+        /*
+         * check that for p and q gcd(p-1,primes) == 1 (except for 2)
+         */
+        BN_ULONG pmod = BN_mod_word(p, (BN_ULONG)primes[i]);
+        BN_ULONG qmod = BN_mod_word(q, (BN_ULONG)primes[i]);
+        if (pmod == (BN_ULONG)-1 || qmod == (BN_ULONG)-1)
+            goto err;
+        if (pmod == 0 || qmod == 0) {
+            if (!BN_add(p, p, padd))
+                goto err;
+            if (!BN_add(q, q, qadd))
+                goto err;
+            goto loop;
+        }
+    }
+    ret = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    bn_check_top(p);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_prime.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_prime.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_prime.h	(revision 331)
@@ -0,0 +1,274 @@
+/*
+ * WARNING: do not edit!
+ * Generated by crypto/bn/bn_prime.pl
+ *
+ * Copyright 1998-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
+ */
+
+typedef unsigned short prime_t;
+# define NUMPRIMES 2048
+
+static const prime_t primes[2048] = {
+
+       2,    3,    5,    7,   11,   13,   17,   19, 
+      23,   29,   31,   37,   41,   43,   47,   53, 
+      59,   61,   67,   71,   73,   79,   83,   89, 
+      97,  101,  103,  107,  109,  113,  127,  131, 
+     137,  139,  149,  151,  157,  163,  167,  173, 
+     179,  181,  191,  193,  197,  199,  211,  223, 
+     227,  229,  233,  239,  241,  251,  257,  263, 
+     269,  271,  277,  281,  283,  293,  307,  311, 
+     313,  317,  331,  337,  347,  349,  353,  359, 
+     367,  373,  379,  383,  389,  397,  401,  409, 
+     419,  421,  431,  433,  439,  443,  449,  457, 
+     461,  463,  467,  479,  487,  491,  499,  503, 
+     509,  521,  523,  541,  547,  557,  563,  569, 
+     571,  577,  587,  593,  599,  601,  607,  613, 
+     617,  619,  631,  641,  643,  647,  653,  659, 
+     661,  673,  677,  683,  691,  701,  709,  719, 
+     727,  733,  739,  743,  751,  757,  761,  769, 
+     773,  787,  797,  809,  811,  821,  823,  827, 
+     829,  839,  853,  857,  859,  863,  877,  881, 
+     883,  887,  907,  911,  919,  929,  937,  941, 
+     947,  953,  967,  971,  977,  983,  991,  997, 
+    1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 
+    1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 
+    1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 
+    1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 
+    1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 
+    1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 
+    1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 
+    1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 
+    1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 
+    1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 
+    1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 
+    1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 
+    1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 
+    1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 
+    1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 
+    1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 
+    1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 
+    2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 
+    2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 
+    2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 
+    2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 
+    2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 
+    2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 
+    2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 
+    2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 
+    2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 
+    2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 
+    2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 
+    2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 
+    2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 
+    2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 
+    2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 
+    2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 
+    3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 
+    3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 
+    3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 
+    3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 
+    3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 
+    3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 
+    3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 
+    3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, 
+    3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 
+    3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, 
+    3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 
+    3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 
+    3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 
+    3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 
+    3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 
+    4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 
+    4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 
+    4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, 
+    4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 
+    4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 
+    4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 
+    4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 
+    4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 
+    4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 
+    4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 
+    4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 
+    4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 
+    4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 
+    4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 
+    4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 
+    5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 
+    5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 
+    5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 
+    5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 
+    5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 
+    5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 
+    5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 
+    5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 
+    5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 
+    5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 
+    5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 
+    5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 
+    5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 
+    5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, 
+    6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 
+    6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 
+    6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 
+    6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, 
+    6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 
+    6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, 
+    6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 
+    6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 
+    6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 
+    6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 
+    6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 
+    6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 
+    6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 
+    6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 
+    6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 
+    7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 
+    7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 
+    7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 
+    7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 
+    7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 
+    7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, 
+    7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 
+    7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 
+    7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 
+    7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 
+    7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 
+    7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 
+    7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 
+    8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, 
+    8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, 
+    8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, 
+    8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, 
+    8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, 
+    8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, 
+    8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, 
+    8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609, 
+    8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, 
+    8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 
+    8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, 
+    8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861, 
+    8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, 
+    8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, 
+    9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, 
+    9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161, 
+    9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, 
+    9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, 
+    9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, 
+    9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, 
+    9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, 
+    9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587, 
+    9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649, 
+    9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, 
+    9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 
+    9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857, 
+    9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, 
+    9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037, 
+    10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, 
+    10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163, 
+    10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247, 
+    10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303, 
+    10313, 10321, 10331, 10333, 10337, 10343, 10357, 10369, 
+    10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459, 
+    10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531, 
+    10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, 
+    10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691, 
+    10709, 10711, 10723, 10729, 10733, 10739, 10753, 10771, 
+    10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859, 
+    10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937, 
+    10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003, 
+    11027, 11047, 11057, 11059, 11069, 11071, 11083, 11087, 
+    11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161, 
+    11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251, 
+    11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317, 
+    11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399, 
+    11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483, 
+    11489, 11491, 11497, 11503, 11519, 11527, 11549, 11551, 
+    11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657, 
+    11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731, 
+    11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813, 
+    11821, 11827, 11831, 11833, 11839, 11863, 11867, 11887, 
+    11897, 11903, 11909, 11923, 11927, 11933, 11939, 11941, 
+    11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, 
+    12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101, 
+    12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161, 
+    12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251, 
+    12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323, 
+    12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401, 
+    12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473, 
+    12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527, 
+    12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589, 
+    12601, 12611, 12613, 12619, 12637, 12641, 12647, 12653, 
+    12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739, 
+    12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, 
+    12823, 12829, 12841, 12853, 12889, 12893, 12899, 12907, 
+    12911, 12917, 12919, 12923, 12941, 12953, 12959, 12967, 
+    12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033, 
+    13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, 
+    13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177, 
+    13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259, 
+    13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337, 
+    13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421, 
+    13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499, 
+    13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597, 
+    13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, 
+    13687, 13691, 13693, 13697, 13709, 13711, 13721, 13723, 
+    13729, 13751, 13757, 13759, 13763, 13781, 13789, 13799, 
+    13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879, 
+    13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, 
+    13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033, 
+    14051, 14057, 14071, 14081, 14083, 14087, 14107, 14143, 
+    14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221, 
+    14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323, 
+    14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407, 
+    14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461, 
+    14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549, 
+    14551, 14557, 14561, 14563, 14591, 14593, 14621, 14627, 
+    14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699, 
+    14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753, 
+    14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, 
+    14827, 14831, 14843, 14851, 14867, 14869, 14879, 14887, 
+    14891, 14897, 14923, 14929, 14939, 14947, 14951, 14957, 
+    14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073, 
+    15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137, 
+    15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217, 
+    15227, 15233, 15241, 15259, 15263, 15269, 15271, 15277, 
+    15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331, 
+    15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401, 
+    15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473, 
+    15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569, 
+    15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643, 
+    15647, 15649, 15661, 15667, 15671, 15679, 15683, 15727, 
+    15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773, 
+    15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859, 
+    15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919, 
+    15923, 15937, 15959, 15971, 15973, 15991, 16001, 16007, 
+    16033, 16057, 16061, 16063, 16067, 16069, 16073, 16087, 
+    16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, 
+    16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249, 
+    16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349, 
+    16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427, 
+    16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493, 
+    16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603, 
+    16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661, 
+    16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747, 
+    16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843, 
+    16871, 16879, 16883, 16889, 16901, 16903, 16921, 16927, 
+    16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993, 
+    17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, 
+    17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159, 
+    17167, 17183, 17189, 17191, 17203, 17207, 17209, 17231, 
+    17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327, 
+    17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, 
+    17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467, 
+    17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519, 
+    17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599, 
+    17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683, 
+    17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783, 
+    17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863, 
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_print.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_print.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_print.c	(revision 331)
@@ -0,0 +1,345 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <ctype.h>
+#include <limits.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include "bn_lcl.h"
+
+static const char Hex[] = "0123456789ABCDEF";
+
+/* Must 'OPENSSL_free' the returned data */
+char *BN_bn2hex(const BIGNUM *a)
+{
+    int i, j, v, z = 0;
+    char *buf;
+    char *p;
+
+    if (BN_is_zero(a))
+        return OPENSSL_strdup("0");
+    buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2);
+    if (buf == NULL) {
+        BNerr(BN_F_BN_BN2HEX, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    p = buf;
+    if (a->neg)
+        *(p++) = '-';
+    if (BN_is_zero(a))
+        *(p++) = '0';
+    for (i = a->top - 1; i >= 0; i--) {
+        for (j = BN_BITS2 - 8; j >= 0; j -= 8) {
+            /* strip leading zeros */
+            v = ((int)(a->d[i] >> (long)j)) & 0xff;
+            if (z || (v != 0)) {
+                *(p++) = Hex[v >> 4];
+                *(p++) = Hex[v & 0x0f];
+                z = 1;
+            }
+        }
+    }
+    *p = '\0';
+ err:
+    return (buf);
+}
+
+/* Must 'OPENSSL_free' the returned data */
+char *BN_bn2dec(const BIGNUM *a)
+{
+    int i = 0, num, ok = 0;
+    char *buf = NULL;
+    char *p;
+    BIGNUM *t = NULL;
+    BN_ULONG *bn_data = NULL, *lp;
+    int bn_data_num;
+
+    /*-
+     * get an upper bound for the length of the decimal integer
+     * num <= (BN_num_bits(a) + 1) * log(2)
+     *     <= 3 * BN_num_bits(a) * 0.101 + log(2) + 1     (rounding error)
+     *     <= 3 * BN_num_bits(a) / 10 + 3 * BN_num_bits / 1000 + 1 + 1
+     */
+    i = BN_num_bits(a) * 3;
+    num = (i / 10 + i / 1000 + 1) + 1;
+    bn_data_num = num / BN_DEC_NUM + 1;
+    bn_data = OPENSSL_malloc(bn_data_num * sizeof(BN_ULONG));
+    buf = OPENSSL_malloc(num + 3);
+    if ((buf == NULL) || (bn_data == NULL)) {
+        BNerr(BN_F_BN_BN2DEC, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if ((t = BN_dup(a)) == NULL)
+        goto err;
+
+#define BUF_REMAIN (num+3 - (size_t)(p - buf))
+    p = buf;
+    lp = bn_data;
+    if (BN_is_zero(t)) {
+        *(p++) = '0';
+        *(p++) = '\0';
+    } else {
+        if (BN_is_negative(t))
+            *p++ = '-';
+
+        while (!BN_is_zero(t)) {
+            if (lp - bn_data >= bn_data_num)
+                goto err;
+            *lp = BN_div_word(t, BN_DEC_CONV);
+            if (*lp == (BN_ULONG)-1)
+                goto err;
+            lp++;
+        }
+        lp--;
+        /*
+         * We now have a series of blocks, BN_DEC_NUM chars in length, where
+         * the last one needs truncation. The blocks need to be reversed in
+         * order.
+         */
+        BIO_snprintf(p, BUF_REMAIN, BN_DEC_FMT1, *lp);
+        while (*p)
+            p++;
+        while (lp != bn_data) {
+            lp--;
+            BIO_snprintf(p, BUF_REMAIN, BN_DEC_FMT2, *lp);
+            while (*p)
+                p++;
+        }
+    }
+    ok = 1;
+ err:
+    OPENSSL_free(bn_data);
+    BN_free(t);
+    if (ok)
+        return buf;
+    OPENSSL_free(buf);
+    return NULL;
+}
+
+int BN_hex2bn(BIGNUM **bn, const char *a)
+{
+    BIGNUM *ret = NULL;
+    BN_ULONG l = 0;
+    int neg = 0, h, m, i, j, k, c;
+    int num;
+
+    if ((a == NULL) || (*a == '\0'))
+        return (0);
+
+    if (*a == '-') {
+        neg = 1;
+        a++;
+    }
+
+    for (i = 0; i <= (INT_MAX/4) && isxdigit((unsigned char)a[i]); i++)
+        continue;
+
+    if (i == 0 || i > INT_MAX/4)
+        goto err;
+
+    num = i + neg;
+    if (bn == NULL)
+        return (num);
+
+    /* a is the start of the hex digits, and it is 'i' long */
+    if (*bn == NULL) {
+        if ((ret = BN_new()) == NULL)
+            return (0);
+    } else {
+        ret = *bn;
+        BN_zero(ret);
+    }
+
+    /* i is the number of hex digits */
+    if (bn_expand(ret, i * 4) == NULL)
+        goto err;
+
+    j = i;                      /* least significant 'hex' */
+    m = 0;
+    h = 0;
+    while (j > 0) {
+        m = ((BN_BYTES * 2) <= j) ? (BN_BYTES * 2) : j;
+        l = 0;
+        for (;;) {
+            c = a[j - m];
+            k = OPENSSL_hexchar2int(c);
+            if (k < 0)
+                k = 0;          /* paranoia */
+            l = (l << 4) | k;
+
+            if (--m <= 0) {
+                ret->d[h++] = l;
+                break;
+            }
+        }
+        j -= (BN_BYTES * 2);
+    }
+    ret->top = h;
+    bn_correct_top(ret);
+
+    *bn = ret;
+    bn_check_top(ret);
+    /* Don't set the negative flag if it's zero. */
+    if (ret->top != 0)
+        ret->neg = neg;
+    return (num);
+ err:
+    if (*bn == NULL)
+        BN_free(ret);
+    return (0);
+}
+
+int BN_dec2bn(BIGNUM **bn, const char *a)
+{
+    BIGNUM *ret = NULL;
+    BN_ULONG l = 0;
+    int neg = 0, i, j;
+    int num;
+
+    if ((a == NULL) || (*a == '\0'))
+        return (0);
+    if (*a == '-') {
+        neg = 1;
+        a++;
+    }
+
+    for (i = 0; i <= (INT_MAX/4) && isdigit((unsigned char)a[i]); i++)
+        continue;
+
+    if (i == 0 || i > INT_MAX/4)
+        goto err;
+
+    num = i + neg;
+    if (bn == NULL)
+        return (num);
+
+    /*
+     * a is the start of the digits, and it is 'i' long. We chop it into
+     * BN_DEC_NUM digits at a time
+     */
+    if (*bn == NULL) {
+        if ((ret = BN_new()) == NULL)
+            return (0);
+    } else {
+        ret = *bn;
+        BN_zero(ret);
+    }
+
+    /* i is the number of digits, a bit of an over expand */
+    if (bn_expand(ret, i * 4) == NULL)
+        goto err;
+
+    j = BN_DEC_NUM - (i % BN_DEC_NUM);
+    if (j == BN_DEC_NUM)
+        j = 0;
+    l = 0;
+    while (--i >= 0) {
+        l *= 10;
+        l += *a - '0';
+        a++;
+        if (++j == BN_DEC_NUM) {
+            if (!BN_mul_word(ret, BN_DEC_CONV)
+                || !BN_add_word(ret, l))
+                goto err;
+            l = 0;
+            j = 0;
+        }
+    }
+
+    bn_correct_top(ret);
+    *bn = ret;
+    bn_check_top(ret);
+    /* Don't set the negative flag if it's zero. */
+    if (ret->top != 0)
+        ret->neg = neg;
+    return (num);
+ err:
+    if (*bn == NULL)
+        BN_free(ret);
+    return (0);
+}
+
+int BN_asc2bn(BIGNUM **bn, const char *a)
+{
+    const char *p = a;
+
+    if (*p == '-')
+        p++;
+
+    if (p[0] == '0' && (p[1] == 'X' || p[1] == 'x')) {
+        if (!BN_hex2bn(bn, p + 2))
+            return 0;
+    } else {
+        if (!BN_dec2bn(bn, p))
+            return 0;
+    }
+    /* Don't set the negative flag if it's zero. */
+    if (*a == '-' && (*bn)->top != 0)
+        (*bn)->neg = 1;
+    return 1;
+}
+
+# ifndef OPENSSL_NO_STDIO
+int BN_print_fp(FILE *fp, const BIGNUM *a)
+{
+    BIO *b;
+    int ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL)
+        return (0);
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = BN_print(b, a);
+    BIO_free(b);
+    return (ret);
+}
+# endif
+
+int BN_print(BIO *bp, const BIGNUM *a)
+{
+    int i, j, v, z = 0;
+    int ret = 0;
+
+    if ((a->neg) && (BIO_write(bp, "-", 1) != 1))
+        goto end;
+    if (BN_is_zero(a) && (BIO_write(bp, "0", 1) != 1))
+        goto end;
+    for (i = a->top - 1; i >= 0; i--) {
+        for (j = BN_BITS2 - 4; j >= 0; j -= 4) {
+            /* strip leading zeros */
+            v = ((int)(a->d[i] >> (long)j)) & 0x0f;
+            if (z || (v != 0)) {
+                if (BIO_write(bp, &(Hex[v]), 1) != 1)
+                    goto end;
+                z = 1;
+            }
+        }
+    }
+    ret = 1;
+ end:
+    return (ret);
+}
+
+char *BN_options(void)
+{
+    static int init = 0;
+    static char data[16];
+
+    if (!init) {
+        init++;
+#ifdef BN_LLONG
+        BIO_snprintf(data, sizeof data, "bn(%d,%d)",
+                     (int)sizeof(BN_ULLONG) * 8, (int)sizeof(BN_ULONG) * 8);
+#else
+        BIO_snprintf(data, sizeof data, "bn(%d,%d)",
+                     (int)sizeof(BN_ULONG) * 8, (int)sizeof(BN_ULONG) * 8);
+#endif
+    }
+    return (data);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_rand.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_rand.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_rand.c	(revision 331)
@@ -0,0 +1,258 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <time.h>
+#include "internal/cryptlib.h"
+#include "bn_lcl.h"
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+
+static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
+{
+    unsigned char *buf = NULL;
+    int ret = 0, bit, bytes, mask;
+    time_t tim;
+
+    if (bits == 0) {
+        if (top != BN_RAND_TOP_ANY || bottom != BN_RAND_BOTTOM_ANY)
+            goto toosmall;
+        BN_zero(rnd);
+        return 1;
+    }
+    if (bits < 0 || (bits == 1 && top > 0))
+        goto toosmall;
+
+    bytes = (bits + 7) / 8;
+    bit = (bits - 1) % 8;
+    mask = 0xff << (bit + 1);
+
+    buf = OPENSSL_malloc(bytes);
+    if (buf == NULL) {
+        BNerr(BN_F_BNRAND, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    /* make a random number and set the top and bottom bits */
+    time(&tim);
+    RAND_add(&tim, sizeof(tim), 0.0);
+
+    if (RAND_bytes(buf, bytes) <= 0)
+        goto err;
+
+    if (pseudorand == 2) {
+        /*
+         * generate patterns that are more likely to trigger BN library bugs
+         */
+        int i;
+        unsigned char c;
+
+        for (i = 0; i < bytes; i++) {
+            if (RAND_bytes(&c, 1) <= 0)
+                goto err;
+            if (c >= 128 && i > 0)
+                buf[i] = buf[i - 1];
+            else if (c < 42)
+                buf[i] = 0;
+            else if (c < 84)
+                buf[i] = 255;
+        }
+    }
+
+    if (top >= 0) {
+        if (top) {
+            if (bit == 0) {
+                buf[0] = 1;
+                buf[1] |= 0x80;
+            } else {
+                buf[0] |= (3 << (bit - 1));
+            }
+        } else {
+            buf[0] |= (1 << bit);
+        }
+    }
+    buf[0] &= ~mask;
+    if (bottom)                 /* set bottom bit if requested */
+        buf[bytes - 1] |= 1;
+    if (!BN_bin2bn(buf, bytes, rnd))
+        goto err;
+    ret = 1;
+ err:
+    OPENSSL_clear_free(buf, bytes);
+    bn_check_top(rnd);
+    return (ret);
+
+toosmall:
+    BNerr(BN_F_BNRAND, BN_R_BITS_TOO_SMALL);
+    return 0;
+}
+
+int BN_rand(BIGNUM *rnd, int bits, int top, int bottom)
+{
+    return bnrand(0, rnd, bits, top, bottom);
+}
+
+int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom)
+{
+    return bnrand(1, rnd, bits, top, bottom);
+}
+
+int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom)
+{
+    return bnrand(2, rnd, bits, top, bottom);
+}
+
+/* random number r:  0 <= r < range */
+static int bn_rand_range(int pseudo, BIGNUM *r, const BIGNUM *range)
+{
+    int (*bn_rand) (BIGNUM *, int, int, int) =
+        pseudo ? BN_pseudo_rand : BN_rand;
+    int n;
+    int count = 100;
+
+    if (range->neg || BN_is_zero(range)) {
+        BNerr(BN_F_BN_RAND_RANGE, BN_R_INVALID_RANGE);
+        return 0;
+    }
+
+    n = BN_num_bits(range);     /* n > 0 */
+
+    /* BN_is_bit_set(range, n - 1) always holds */
+
+    if (n == 1)
+        BN_zero(r);
+    else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3)) {
+        /*
+         * range = 100..._2, so 3*range (= 11..._2) is exactly one bit longer
+         * than range
+         */
+        do {
+            if (!bn_rand(r, n + 1, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY))
+                return 0;
+            /*
+             * If r < 3*range, use r := r MOD range (which is either r, r -
+             * range, or r - 2*range). Otherwise, iterate once more. Since
+             * 3*range = 11..._2, each iteration succeeds with probability >=
+             * .75.
+             */
+            if (BN_cmp(r, range) >= 0) {
+                if (!BN_sub(r, r, range))
+                    return 0;
+                if (BN_cmp(r, range) >= 0)
+                    if (!BN_sub(r, r, range))
+                        return 0;
+            }
+
+            if (!--count) {
+                BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS);
+                return 0;
+            }
+
+        }
+        while (BN_cmp(r, range) >= 0);
+    } else {
+        do {
+            /* range = 11..._2  or  range = 101..._2 */
+            if (!bn_rand(r, n, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY))
+                return 0;
+
+            if (!--count) {
+                BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS);
+                return 0;
+            }
+        }
+        while (BN_cmp(r, range) >= 0);
+    }
+
+    bn_check_top(r);
+    return 1;
+}
+
+int BN_rand_range(BIGNUM *r, const BIGNUM *range)
+{
+    return bn_rand_range(0, r, range);
+}
+
+int BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range)
+{
+    return bn_rand_range(1, r, range);
+}
+
+/*
+ * BN_generate_dsa_nonce generates a random number 0 <= out < range. Unlike
+ * BN_rand_range, it also includes the contents of |priv| and |message| in
+ * the generation so that an RNG failure isn't fatal as long as |priv|
+ * remains secret. This is intended for use in DSA and ECDSA where an RNG
+ * weakness leads directly to private key exposure unless this function is
+ * used.
+ */
+int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range,
+                          const BIGNUM *priv, const unsigned char *message,
+                          size_t message_len, BN_CTX *ctx)
+{
+    SHA512_CTX sha;
+    /*
+     * We use 512 bits of random data per iteration to ensure that we have at
+     * least |range| bits of randomness.
+     */
+    unsigned char random_bytes[64];
+    unsigned char digest[SHA512_DIGEST_LENGTH];
+    unsigned done, todo;
+    /* We generate |range|+8 bytes of random output. */
+    const unsigned num_k_bytes = BN_num_bytes(range) + 8;
+    unsigned char private_bytes[96];
+    unsigned char *k_bytes;
+    int ret = 0;
+
+    k_bytes = OPENSSL_malloc(num_k_bytes);
+    if (k_bytes == NULL)
+        goto err;
+
+    /* We copy |priv| into a local buffer to avoid exposing its length. */
+    todo = sizeof(priv->d[0]) * priv->top;
+    if (todo > sizeof(private_bytes)) {
+        /*
+         * No reasonable DSA or ECDSA key should have a private key this
+         * large and we don't handle this case in order to avoid leaking the
+         * length of the private key.
+         */
+        BNerr(BN_F_BN_GENERATE_DSA_NONCE, BN_R_PRIVATE_KEY_TOO_LARGE);
+        goto err;
+    }
+    memcpy(private_bytes, priv->d, todo);
+    memset(private_bytes + todo, 0, sizeof(private_bytes) - todo);
+
+    for (done = 0; done < num_k_bytes;) {
+        if (RAND_bytes(random_bytes, sizeof(random_bytes)) != 1)
+            goto err;
+        SHA512_Init(&sha);
+        SHA512_Update(&sha, &done, sizeof(done));
+        SHA512_Update(&sha, private_bytes, sizeof(private_bytes));
+        SHA512_Update(&sha, message, message_len);
+        SHA512_Update(&sha, random_bytes, sizeof(random_bytes));
+        SHA512_Final(digest, &sha);
+
+        todo = num_k_bytes - done;
+        if (todo > SHA512_DIGEST_LENGTH)
+            todo = SHA512_DIGEST_LENGTH;
+        memcpy(k_bytes + done, digest, todo);
+        done += todo;
+    }
+
+    if (!BN_bin2bn(k_bytes, num_k_bytes, out))
+        goto err;
+    if (BN_mod(out, out, range, ctx) != 1)
+        goto err;
+    ret = 1;
+
+ err:
+    OPENSSL_free(k_bytes);
+    OPENSSL_cleanse(private_bytes, sizeof(private_bytes));
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_recp.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_recp.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_recp.c	(revision 331)
@@ -0,0 +1,199 @@
+/*
+ * Copyright 1995-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 "internal/cryptlib.h"
+#include "bn_lcl.h"
+
+void BN_RECP_CTX_init(BN_RECP_CTX *recp)
+{
+    memset(recp, 0, sizeof(*recp));
+    bn_init(&(recp->N));
+    bn_init(&(recp->Nr));
+}
+
+BN_RECP_CTX *BN_RECP_CTX_new(void)
+{
+    BN_RECP_CTX *ret;
+
+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
+        return (NULL);
+
+    bn_init(&(ret->N));
+    bn_init(&(ret->Nr));
+    ret->flags = BN_FLG_MALLOCED;
+    return (ret);
+}
+
+void BN_RECP_CTX_free(BN_RECP_CTX *recp)
+{
+    if (recp == NULL)
+        return;
+
+    BN_free(&(recp->N));
+    BN_free(&(recp->Nr));
+    if (recp->flags & BN_FLG_MALLOCED)
+        OPENSSL_free(recp);
+}
+
+int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx)
+{
+    if (!BN_copy(&(recp->N), d))
+        return 0;
+    BN_zero(&(recp->Nr));
+    recp->num_bits = BN_num_bits(d);
+    recp->shift = 0;
+    return (1);
+}
+
+int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
+                          BN_RECP_CTX *recp, BN_CTX *ctx)
+{
+    int ret = 0;
+    BIGNUM *a;
+    const BIGNUM *ca;
+
+    BN_CTX_start(ctx);
+    if ((a = BN_CTX_get(ctx)) == NULL)
+        goto err;
+    if (y != NULL) {
+        if (x == y) {
+            if (!BN_sqr(a, x, ctx))
+                goto err;
+        } else {
+            if (!BN_mul(a, x, y, ctx))
+                goto err;
+        }
+        ca = a;
+    } else
+        ca = x;                 /* Just do the mod */
+
+    ret = BN_div_recp(NULL, r, ca, recp, ctx);
+ err:
+    BN_CTX_end(ctx);
+    bn_check_top(r);
+    return (ret);
+}
+
+int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
+                BN_RECP_CTX *recp, BN_CTX *ctx)
+{
+    int i, j, ret = 0;
+    BIGNUM *a, *b, *d, *r;
+
+    BN_CTX_start(ctx);
+    a = BN_CTX_get(ctx);
+    b = BN_CTX_get(ctx);
+    if (dv != NULL)
+        d = dv;
+    else
+        d = BN_CTX_get(ctx);
+    if (rem != NULL)
+        r = rem;
+    else
+        r = BN_CTX_get(ctx);
+    if (a == NULL || b == NULL || d == NULL || r == NULL)
+        goto err;
+
+    if (BN_ucmp(m, &(recp->N)) < 0) {
+        BN_zero(d);
+        if (!BN_copy(r, m)) {
+            BN_CTX_end(ctx);
+            return 0;
+        }
+        BN_CTX_end(ctx);
+        return (1);
+    }
+
+    /*
+     * We want the remainder Given input of ABCDEF / ab we need multiply
+     * ABCDEF by 3 digests of the reciprocal of ab
+     */
+
+    /* i := max(BN_num_bits(m), 2*BN_num_bits(N)) */
+    i = BN_num_bits(m);
+    j = recp->num_bits << 1;
+    if (j > i)
+        i = j;
+
+    /* Nr := round(2^i / N) */
+    if (i != recp->shift)
+        recp->shift = BN_reciprocal(&(recp->Nr), &(recp->N), i, ctx);
+    /* BN_reciprocal could have returned -1 for an error */
+    if (recp->shift == -1)
+        goto err;
+
+    /*-
+     * d := |round(round(m / 2^BN_num_bits(N)) * recp->Nr / 2^(i - BN_num_bits(N)))|
+     *    = |round(round(m / 2^BN_num_bits(N)) * round(2^i / N) / 2^(i - BN_num_bits(N)))|
+     *   <= |(m / 2^BN_num_bits(N)) * (2^i / N) * (2^BN_num_bits(N) / 2^i)|
+     *    = |m/N|
+     */
+    if (!BN_rshift(a, m, recp->num_bits))
+        goto err;
+    if (!BN_mul(b, a, &(recp->Nr), ctx))
+        goto err;
+    if (!BN_rshift(d, b, i - recp->num_bits))
+        goto err;
+    d->neg = 0;
+
+    if (!BN_mul(b, &(recp->N), d, ctx))
+        goto err;
+    if (!BN_usub(r, m, b))
+        goto err;
+    r->neg = 0;
+
+    j = 0;
+    while (BN_ucmp(r, &(recp->N)) >= 0) {
+        if (j++ > 2) {
+            BNerr(BN_F_BN_DIV_RECP, BN_R_BAD_RECIPROCAL);
+            goto err;
+        }
+        if (!BN_usub(r, r, &(recp->N)))
+            goto err;
+        if (!BN_add_word(d, 1))
+            goto err;
+    }
+
+    r->neg = BN_is_zero(r) ? 0 : m->neg;
+    d->neg = m->neg ^ recp->N.neg;
+    ret = 1;
+ err:
+    BN_CTX_end(ctx);
+    bn_check_top(dv);
+    bn_check_top(rem);
+    return (ret);
+}
+
+/*
+ * len is the expected size of the result We actually calculate with an extra
+ * word of precision, so we can do faster division if the remainder is not
+ * required.
+ */
+/* r := 2^len / m */
+int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx)
+{
+    int ret = -1;
+    BIGNUM *t;
+
+    BN_CTX_start(ctx);
+    if ((t = BN_CTX_get(ctx)) == NULL)
+        goto err;
+
+    if (!BN_set_bit(t, len))
+        goto err;
+
+    if (!BN_div(r, NULL, t, m, ctx))
+        goto err;
+
+    ret = len;
+ err:
+    bn_check_top(r);
+    BN_CTX_end(ctx);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_shift.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_shift.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_shift.c	(revision 331)
@@ -0,0 +1,175 @@
+/*
+ * Copyright 1995-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 "internal/cryptlib.h"
+#include "bn_lcl.h"
+
+int BN_lshift1(BIGNUM *r, const BIGNUM *a)
+{
+    register BN_ULONG *ap, *rp, t, c;
+    int i;
+
+    bn_check_top(r);
+    bn_check_top(a);
+
+    if (r != a) {
+        r->neg = a->neg;
+        if (bn_wexpand(r, a->top + 1) == NULL)
+            return (0);
+        r->top = a->top;
+    } else {
+        if (bn_wexpand(r, a->top + 1) == NULL)
+            return (0);
+    }
+    ap = a->d;
+    rp = r->d;
+    c = 0;
+    for (i = 0; i < a->top; i++) {
+        t = *(ap++);
+        *(rp++) = ((t << 1) | c) & BN_MASK2;
+        c = (t & BN_TBIT) ? 1 : 0;
+    }
+    if (c) {
+        *rp = 1;
+        r->top++;
+    }
+    bn_check_top(r);
+    return (1);
+}
+
+int BN_rshift1(BIGNUM *r, const BIGNUM *a)
+{
+    BN_ULONG *ap, *rp, t, c;
+    int i, j;
+
+    bn_check_top(r);
+    bn_check_top(a);
+
+    if (BN_is_zero(a)) {
+        BN_zero(r);
+        return (1);
+    }
+    i = a->top;
+    ap = a->d;
+    j = i - (ap[i - 1] == 1);
+    if (a != r) {
+        if (bn_wexpand(r, j) == NULL)
+            return (0);
+        r->neg = a->neg;
+    }
+    rp = r->d;
+    t = ap[--i];
+    c = (t & 1) ? BN_TBIT : 0;
+    if (t >>= 1)
+        rp[i] = t;
+    while (i > 0) {
+        t = ap[--i];
+        rp[i] = ((t >> 1) & BN_MASK2) | c;
+        c = (t & 1) ? BN_TBIT : 0;
+    }
+    r->top = j;
+    if (!r->top)
+        r->neg = 0; /* don't allow negative zero */
+    bn_check_top(r);
+    return (1);
+}
+
+int BN_lshift(BIGNUM *r, const BIGNUM *a, int n)
+{
+    int i, nw, lb, rb;
+    BN_ULONG *t, *f;
+    BN_ULONG l;
+
+    bn_check_top(r);
+    bn_check_top(a);
+
+    if (n < 0) {
+        BNerr(BN_F_BN_LSHIFT, BN_R_INVALID_SHIFT);
+        return 0;
+    }
+
+    nw = n / BN_BITS2;
+    if (bn_wexpand(r, a->top + nw + 1) == NULL)
+        return (0);
+    r->neg = a->neg;
+    lb = n % BN_BITS2;
+    rb = BN_BITS2 - lb;
+    f = a->d;
+    t = r->d;
+    t[a->top + nw] = 0;
+    if (lb == 0)
+        for (i = a->top - 1; i >= 0; i--)
+            t[nw + i] = f[i];
+    else
+        for (i = a->top - 1; i >= 0; i--) {
+            l = f[i];
+            t[nw + i + 1] |= (l >> rb) & BN_MASK2;
+            t[nw + i] = (l << lb) & BN_MASK2;
+        }
+    memset(t, 0, sizeof(*t) * nw);
+    r->top = a->top + nw + 1;
+    bn_correct_top(r);
+    bn_check_top(r);
+    return (1);
+}
+
+int BN_rshift(BIGNUM *r, const BIGNUM *a, int n)
+{
+    int i, j, nw, lb, rb;
+    BN_ULONG *t, *f;
+    BN_ULONG l, tmp;
+
+    bn_check_top(r);
+    bn_check_top(a);
+
+    if (n < 0) {
+        BNerr(BN_F_BN_RSHIFT, BN_R_INVALID_SHIFT);
+        return 0;
+    }
+
+    nw = n / BN_BITS2;
+    rb = n % BN_BITS2;
+    lb = BN_BITS2 - rb;
+    if (nw >= a->top || a->top == 0) {
+        BN_zero(r);
+        return (1);
+    }
+    i = (BN_num_bits(a) - n + (BN_BITS2 - 1)) / BN_BITS2;
+    if (r != a) {
+        if (bn_wexpand(r, i) == NULL)
+            return (0);
+        r->neg = a->neg;
+    } else {
+        if (n == 0)
+            return 1;           /* or the copying loop will go berserk */
+    }
+
+    f = &(a->d[nw]);
+    t = r->d;
+    j = a->top - nw;
+    r->top = i;
+
+    if (rb == 0) {
+        for (i = j; i != 0; i--)
+            *(t++) = *(f++);
+    } else {
+        l = *(f++);
+        for (i = j - 1; i != 0; i--) {
+            tmp = (l >> rb) & BN_MASK2;
+            l = *(f++);
+            *(t++) = (tmp | (l << lb)) & BN_MASK2;
+        }
+        if ((l = (l >> rb) & BN_MASK2))
+            *(t) = l;
+    }
+    if (!r->top)
+        r->neg = 0; /* don't allow negative zero */
+    bn_check_top(r);
+    return (1);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_sqr.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_sqr.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_sqr.c	(revision 331)
@@ -0,0 +1,235 @@
+/*
+ * Copyright 1995-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 "internal/cryptlib.h"
+#include "bn_lcl.h"
+
+/* r must not be a */
+/*
+ * I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96
+ */
+int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
+{
+    int max, al;
+    int ret = 0;
+    BIGNUM *tmp, *rr;
+
+    bn_check_top(a);
+
+    al = a->top;
+    if (al <= 0) {
+        r->top = 0;
+        r->neg = 0;
+        return 1;
+    }
+
+    BN_CTX_start(ctx);
+    rr = (a != r) ? r : BN_CTX_get(ctx);
+    tmp = BN_CTX_get(ctx);
+    if (!rr || !tmp)
+        goto err;
+
+    max = 2 * al;               /* Non-zero (from above) */
+    if (bn_wexpand(rr, max) == NULL)
+        goto err;
+
+    if (al == 4) {
+#ifndef BN_SQR_COMBA
+        BN_ULONG t[8];
+        bn_sqr_normal(rr->d, a->d, 4, t);
+#else
+        bn_sqr_comba4(rr->d, a->d);
+#endif
+    } else if (al == 8) {
+#ifndef BN_SQR_COMBA
+        BN_ULONG t[16];
+        bn_sqr_normal(rr->d, a->d, 8, t);
+#else
+        bn_sqr_comba8(rr->d, a->d);
+#endif
+    } else {
+#if defined(BN_RECURSION)
+        if (al < BN_SQR_RECURSIVE_SIZE_NORMAL) {
+            BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL * 2];
+            bn_sqr_normal(rr->d, a->d, al, t);
+        } else {
+            int j, k;
+
+            j = BN_num_bits_word((BN_ULONG)al);
+            j = 1 << (j - 1);
+            k = j + j;
+            if (al == j) {
+                if (bn_wexpand(tmp, k * 2) == NULL)
+                    goto err;
+                bn_sqr_recursive(rr->d, a->d, al, tmp->d);
+            } else {
+                if (bn_wexpand(tmp, max) == NULL)
+                    goto err;
+                bn_sqr_normal(rr->d, a->d, al, tmp->d);
+            }
+        }
+#else
+        if (bn_wexpand(tmp, max) == NULL)
+            goto err;
+        bn_sqr_normal(rr->d, a->d, al, tmp->d);
+#endif
+    }
+
+    rr->neg = 0;
+    /*
+     * If the most-significant half of the top word of 'a' is zero, then the
+     * square of 'a' will max-1 words.
+     */
+    if (a->d[al - 1] == (a->d[al - 1] & BN_MASK2l))
+        rr->top = max - 1;
+    else
+        rr->top = max;
+    if (r != rr && BN_copy(r, rr) == NULL)
+        goto err;
+
+    ret = 1;
+ err:
+    bn_check_top(rr);
+    bn_check_top(tmp);
+    BN_CTX_end(ctx);
+    return (ret);
+}
+
+/* tmp must have 2*n words */
+void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
+{
+    int i, j, max;
+    const BN_ULONG *ap;
+    BN_ULONG *rp;
+
+    max = n * 2;
+    ap = a;
+    rp = r;
+    rp[0] = rp[max - 1] = 0;
+    rp++;
+    j = n;
+
+    if (--j > 0) {
+        ap++;
+        rp[j] = bn_mul_words(rp, ap, j, ap[-1]);
+        rp += 2;
+    }
+
+    for (i = n - 2; i > 0; i--) {
+        j--;
+        ap++;
+        rp[j] = bn_mul_add_words(rp, ap, j, ap[-1]);
+        rp += 2;
+    }
+
+    bn_add_words(r, r, r, max);
+
+    /* There will not be a carry */
+
+    bn_sqr_words(tmp, a, n);
+
+    bn_add_words(r, r, tmp, max);
+}
+
+#ifdef BN_RECURSION
+/*-
+ * r is 2*n words in size,
+ * a and b are both n words in size.    (There's not actually a 'b' here ...)
+ * n must be a power of 2.
+ * We multiply and return the result.
+ * t must be 2*n words in size
+ * We calculate
+ * a[0]*b[0]
+ * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
+ * a[1]*b[1]
+ */
+void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t)
+{
+    int n = n2 / 2;
+    int zero, c1;
+    BN_ULONG ln, lo, *p;
+
+    if (n2 == 4) {
+# ifndef BN_SQR_COMBA
+        bn_sqr_normal(r, a, 4, t);
+# else
+        bn_sqr_comba4(r, a);
+# endif
+        return;
+    } else if (n2 == 8) {
+# ifndef BN_SQR_COMBA
+        bn_sqr_normal(r, a, 8, t);
+# else
+        bn_sqr_comba8(r, a);
+# endif
+        return;
+    }
+    if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL) {
+        bn_sqr_normal(r, a, n2, t);
+        return;
+    }
+    /* r=(a[0]-a[1])*(a[1]-a[0]) */
+    c1 = bn_cmp_words(a, &(a[n]), n);
+    zero = 0;
+    if (c1 > 0)
+        bn_sub_words(t, a, &(a[n]), n);
+    else if (c1 < 0)
+        bn_sub_words(t, &(a[n]), a, n);
+    else
+        zero = 1;
+
+    /* The result will always be negative unless it is zero */
+    p = &(t[n2 * 2]);
+
+    if (!zero)
+        bn_sqr_recursive(&(t[n2]), t, n, p);
+    else
+        memset(&t[n2], 0, sizeof(*t) * n2);
+    bn_sqr_recursive(r, a, n, p);
+    bn_sqr_recursive(&(r[n2]), &(a[n]), n, p);
+
+    /*-
+     * t[32] holds (a[0]-a[1])*(a[1]-a[0]), it is negative or zero
+     * r[10] holds (a[0]*b[0])
+     * r[32] holds (b[1]*b[1])
+     */
+
+    c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
+
+    /* t[32] is negative */
+    c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
+
+    /*-
+     * t[32] holds (a[0]-a[1])*(a[1]-a[0])+(a[0]*a[0])+(a[1]*a[1])
+     * r[10] holds (a[0]*a[0])
+     * r[32] holds (a[1]*a[1])
+     * c1 holds the carry bits
+     */
+    c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
+    if (c1) {
+        p = &(r[n + n2]);
+        lo = *p;
+        ln = (lo + c1) & BN_MASK2;
+        *p = ln;
+
+        /*
+         * The overflow will stop before we over write words we should not
+         * overwrite
+         */
+        if (ln < (BN_ULONG)c1) {
+            do {
+                p++;
+                lo = *p;
+                ln = (lo + 1) & BN_MASK2;
+                *p = ln;
+            } while (ln == 0);
+        }
+    }
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_sqrt.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_sqrt.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_sqrt.c	(revision 331)
@@ -0,0 +1,358 @@
+/*
+ * Copyright 2000-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 "internal/cryptlib.h"
+#include "bn_lcl.h"
+
+BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+/*
+ * Returns 'ret' such that ret^2 == a (mod p), using the Tonelli/Shanks
+ * algorithm (cf. Henri Cohen, "A Course in Algebraic Computational Number
+ * Theory", algorithm 1.5.1). 'p' must be prime!
+ */
+{
+    BIGNUM *ret = in;
+    int err = 1;
+    int r;
+    BIGNUM *A, *b, *q, *t, *x, *y;
+    int e, i, j;
+
+    if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) {
+        if (BN_abs_is_word(p, 2)) {
+            if (ret == NULL)
+                ret = BN_new();
+            if (ret == NULL)
+                goto end;
+            if (!BN_set_word(ret, BN_is_bit_set(a, 0))) {
+                if (ret != in)
+                    BN_free(ret);
+                return NULL;
+            }
+            bn_check_top(ret);
+            return ret;
+        }
+
+        BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
+        return (NULL);
+    }
+
+    if (BN_is_zero(a) || BN_is_one(a)) {
+        if (ret == NULL)
+            ret = BN_new();
+        if (ret == NULL)
+            goto end;
+        if (!BN_set_word(ret, BN_is_one(a))) {
+            if (ret != in)
+                BN_free(ret);
+            return NULL;
+        }
+        bn_check_top(ret);
+        return ret;
+    }
+
+    BN_CTX_start(ctx);
+    A = BN_CTX_get(ctx);
+    b = BN_CTX_get(ctx);
+    q = BN_CTX_get(ctx);
+    t = BN_CTX_get(ctx);
+    x = BN_CTX_get(ctx);
+    y = BN_CTX_get(ctx);
+    if (y == NULL)
+        goto end;
+
+    if (ret == NULL)
+        ret = BN_new();
+    if (ret == NULL)
+        goto end;
+
+    /* A = a mod p */
+    if (!BN_nnmod(A, a, p, ctx))
+        goto end;
+
+    /* now write  |p| - 1  as  2^e*q  where  q  is odd */
+    e = 1;
+    while (!BN_is_bit_set(p, e))
+        e++;
+    /* we'll set  q  later (if needed) */
+
+    if (e == 1) {
+        /*-
+         * The easy case:  (|p|-1)/2  is odd, so 2 has an inverse
+         * modulo  (|p|-1)/2,  and square roots can be computed
+         * directly by modular exponentiation.
+         * We have
+         *     2 * (|p|+1)/4 == 1   (mod (|p|-1)/2),
+         * so we can use exponent  (|p|+1)/4,  i.e.  (|p|-3)/4 + 1.
+         */
+        if (!BN_rshift(q, p, 2))
+            goto end;
+        q->neg = 0;
+        if (!BN_add_word(q, 1))
+            goto end;
+        if (!BN_mod_exp(ret, A, q, p, ctx))
+            goto end;
+        err = 0;
+        goto vrfy;
+    }
+
+    if (e == 2) {
+        /*-
+         * |p| == 5  (mod 8)
+         *
+         * In this case  2  is always a non-square since
+         * Legendre(2,p) = (-1)^((p^2-1)/8)  for any odd prime.
+         * So if  a  really is a square, then  2*a  is a non-square.
+         * Thus for
+         *      b := (2*a)^((|p|-5)/8),
+         *      i := (2*a)*b^2
+         * we have
+         *     i^2 = (2*a)^((1 + (|p|-5)/4)*2)
+         *         = (2*a)^((p-1)/2)
+         *         = -1;
+         * so if we set
+         *      x := a*b*(i-1),
+         * then
+         *     x^2 = a^2 * b^2 * (i^2 - 2*i + 1)
+         *         = a^2 * b^2 * (-2*i)
+         *         = a*(-i)*(2*a*b^2)
+         *         = a*(-i)*i
+         *         = a.
+         *
+         * (This is due to A.O.L. Atkin,
+         * <URL: http://listserv.nodak.edu/scripts/wa.exe?A2=ind9211&L=nmbrthry&O=T&P=562>,
+         * November 1992.)
+         */
+
+        /* t := 2*a */
+        if (!BN_mod_lshift1_quick(t, A, p))
+            goto end;
+
+        /* b := (2*a)^((|p|-5)/8) */
+        if (!BN_rshift(q, p, 3))
+            goto end;
+        q->neg = 0;
+        if (!BN_mod_exp(b, t, q, p, ctx))
+            goto end;
+
+        /* y := b^2 */
+        if (!BN_mod_sqr(y, b, p, ctx))
+            goto end;
+
+        /* t := (2*a)*b^2 - 1 */
+        if (!BN_mod_mul(t, t, y, p, ctx))
+            goto end;
+        if (!BN_sub_word(t, 1))
+            goto end;
+
+        /* x = a*b*t */
+        if (!BN_mod_mul(x, A, b, p, ctx))
+            goto end;
+        if (!BN_mod_mul(x, x, t, p, ctx))
+            goto end;
+
+        if (!BN_copy(ret, x))
+            goto end;
+        err = 0;
+        goto vrfy;
+    }
+
+    /*
+     * e > 2, so we really have to use the Tonelli/Shanks algorithm. First,
+     * find some y that is not a square.
+     */
+    if (!BN_copy(q, p))
+        goto end;               /* use 'q' as temp */
+    q->neg = 0;
+    i = 2;
+    do {
+        /*
+         * For efficiency, try small numbers first; if this fails, try random
+         * numbers.
+         */
+        if (i < 22) {
+            if (!BN_set_word(y, i))
+                goto end;
+        } else {
+            if (!BN_pseudo_rand(y, BN_num_bits(p), 0, 0))
+                goto end;
+            if (BN_ucmp(y, p) >= 0) {
+                if (!(p->neg ? BN_add : BN_sub) (y, y, p))
+                    goto end;
+            }
+            /* now 0 <= y < |p| */
+            if (BN_is_zero(y))
+                if (!BN_set_word(y, i))
+                    goto end;
+        }
+
+        r = BN_kronecker(y, q, ctx); /* here 'q' is |p| */
+        if (r < -1)
+            goto end;
+        if (r == 0) {
+            /* m divides p */
+            BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
+            goto end;
+        }
+    }
+    while (r == 1 && ++i < 82);
+
+    if (r != -1) {
+        /*
+         * Many rounds and still no non-square -- this is more likely a bug
+         * than just bad luck. Even if p is not prime, we should have found
+         * some y such that r == -1.
+         */
+        BNerr(BN_F_BN_MOD_SQRT, BN_R_TOO_MANY_ITERATIONS);
+        goto end;
+    }
+
+    /* Here's our actual 'q': */
+    if (!BN_rshift(q, q, e))
+        goto end;
+
+    /*
+     * Now that we have some non-square, we can find an element of order 2^e
+     * by computing its q'th power.
+     */
+    if (!BN_mod_exp(y, y, q, p, ctx))
+        goto end;
+    if (BN_is_one(y)) {
+        BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME);
+        goto end;
+    }
+
+    /*-
+     * Now we know that (if  p  is indeed prime) there is an integer
+     * k,  0 <= k < 2^e,  such that
+     *
+     *      a^q * y^k == 1   (mod p).
+     *
+     * As  a^q  is a square and  y  is not,  k  must be even.
+     * q+1  is even, too, so there is an element
+     *
+     *     X := a^((q+1)/2) * y^(k/2),
+     *
+     * and it satisfies
+     *
+     *     X^2 = a^q * a     * y^k
+     *         = a,
+     *
+     * so it is the square root that we are looking for.
+     */
+
+    /* t := (q-1)/2  (note that  q  is odd) */
+    if (!BN_rshift1(t, q))
+        goto end;
+
+    /* x := a^((q-1)/2) */
+    if (BN_is_zero(t)) {        /* special case: p = 2^e + 1 */
+        if (!BN_nnmod(t, A, p, ctx))
+            goto end;
+        if (BN_is_zero(t)) {
+            /* special case: a == 0  (mod p) */
+            BN_zero(ret);
+            err = 0;
+            goto end;
+        } else if (!BN_one(x))
+            goto end;
+    } else {
+        if (!BN_mod_exp(x, A, t, p, ctx))
+            goto end;
+        if (BN_is_zero(x)) {
+            /* special case: a == 0  (mod p) */
+            BN_zero(ret);
+            err = 0;
+            goto end;
+        }
+    }
+
+    /* b := a*x^2  (= a^q) */
+    if (!BN_mod_sqr(b, x, p, ctx))
+        goto end;
+    if (!BN_mod_mul(b, b, A, p, ctx))
+        goto end;
+
+    /* x := a*x    (= a^((q+1)/2)) */
+    if (!BN_mod_mul(x, x, A, p, ctx))
+        goto end;
+
+    while (1) {
+        /*-
+         * Now  b  is  a^q * y^k  for some even  k  (0 <= k < 2^E
+         * where  E  refers to the original value of  e,  which we
+         * don't keep in a variable),  and  x  is  a^((q+1)/2) * y^(k/2).
+         *
+         * We have  a*b = x^2,
+         *    y^2^(e-1) = -1,
+         *    b^2^(e-1) = 1.
+         */
+
+        if (BN_is_one(b)) {
+            if (!BN_copy(ret, x))
+                goto end;
+            err = 0;
+            goto vrfy;
+        }
+
+        /* find smallest  i  such that  b^(2^i) = 1 */
+        i = 1;
+        if (!BN_mod_sqr(t, b, p, ctx))
+            goto end;
+        while (!BN_is_one(t)) {
+            i++;
+            if (i == e) {
+                BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
+                goto end;
+            }
+            if (!BN_mod_mul(t, t, t, p, ctx))
+                goto end;
+        }
+
+        /* t := y^2^(e - i - 1) */
+        if (!BN_copy(t, y))
+            goto end;
+        for (j = e - i - 1; j > 0; j--) {
+            if (!BN_mod_sqr(t, t, p, ctx))
+                goto end;
+        }
+        if (!BN_mod_mul(y, t, t, p, ctx))
+            goto end;
+        if (!BN_mod_mul(x, x, t, p, ctx))
+            goto end;
+        if (!BN_mod_mul(b, b, y, p, ctx))
+            goto end;
+        e = i;
+    }
+
+ vrfy:
+    if (!err) {
+        /*
+         * verify the result -- the input might have been not a square (test
+         * added in 0.9.8)
+         */
+
+        if (!BN_mod_sqr(x, ret, p, ctx))
+            err = 1;
+
+        if (!err && 0 != BN_cmp(x, A)) {
+            BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
+            err = 1;
+        }
+    }
+
+ end:
+    if (err) {
+        if (ret != in)
+            BN_clear_free(ret);
+        ret = NULL;
+    }
+    BN_CTX_end(ctx);
+    bn_check_top(ret);
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_srp.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_srp.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_srp.c	(revision 331)
@@ -0,0 +1,545 @@
+/*
+ * Copyright 2014-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 "bn_lcl.h"
+#include "e_os.h"
+
+#ifndef OPENSSL_NO_SRP
+
+#include <openssl/srp.h>
+#include <internal/bn_srp.h>
+
+# if (BN_BYTES == 8)
+#  if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
+#   define bn_pack4(a1,a2,a3,a4) ((a1##UI64<<48)|(a2##UI64<<32)|(a3##UI64<<16)|a4##UI64)
+#  elif defined(__arch64__)
+#   define bn_pack4(a1,a2,a3,a4) ((a1##UL<<48)|(a2##UL<<32)|(a3##UL<<16)|a4##UL)
+#  else
+#   define bn_pack4(a1,a2,a3,a4) ((a1##ULL<<48)|(a2##ULL<<32)|(a3##ULL<<16)|a4##ULL)
+#  endif
+# elif (BN_BYTES == 4)
+#  define bn_pack4(a1,a2,a3,a4)  ((a3##UL<<16)|a4##UL), ((a1##UL<<16)|a2##UL)
+# else
+#  error "unsupported BN_BYTES"
+# endif
+
+static const BN_ULONG bn_group_1024_value[] = {
+    bn_pack4(0x9FC6, 0x1D2F, 0xC0EB, 0x06E3),
+    bn_pack4(0xFD51, 0x38FE, 0x8376, 0x435B),
+    bn_pack4(0x2FD4, 0xCBF4, 0x976E, 0xAA9A),
+    bn_pack4(0x68ED, 0xBC3C, 0x0572, 0x6CC0),
+    bn_pack4(0xC529, 0xF566, 0x660E, 0x57EC),
+    bn_pack4(0x8255, 0x9B29, 0x7BCF, 0x1885),
+    bn_pack4(0xCE8E, 0xF4AD, 0x69B1, 0x5D49),
+    bn_pack4(0x5DC7, 0xD7B4, 0x6154, 0xD6B6),
+    bn_pack4(0x8E49, 0x5C1D, 0x6089, 0xDAD1),
+    bn_pack4(0xE0D5, 0xD8E2, 0x50B9, 0x8BE4),
+    bn_pack4(0x383B, 0x4813, 0xD692, 0xC6E0),
+    bn_pack4(0xD674, 0xDF74, 0x96EA, 0x81D3),
+    bn_pack4(0x9EA2, 0x314C, 0x9C25, 0x6576),
+    bn_pack4(0x6072, 0x6187, 0x75FF, 0x3C0B),
+    bn_pack4(0x9C33, 0xF80A, 0xFA8F, 0xC5E8),
+    bn_pack4(0xEEAF, 0x0AB9, 0xADB3, 0x8DD6)
+};
+
+const BIGNUM bn_group_1024 = {
+    (BN_ULONG *)bn_group_1024_value,
+    OSSL_NELEM(bn_group_1024_value),
+    OSSL_NELEM(bn_group_1024_value),
+    0,
+    BN_FLG_STATIC_DATA
+};
+
+static const BN_ULONG bn_group_1536_value[] = {
+    bn_pack4(0xCF76, 0xE3FE, 0xD135, 0xF9BB),
+    bn_pack4(0x1518, 0x0F93, 0x499A, 0x234D),
+    bn_pack4(0x8CE7, 0xA28C, 0x2442, 0xC6F3),
+    bn_pack4(0x5A02, 0x1FFF, 0x5E91, 0x479E),
+    bn_pack4(0x7F8A, 0x2FE9, 0xB8B5, 0x292E),
+    bn_pack4(0x837C, 0x264A, 0xE3A9, 0xBEB8),
+    bn_pack4(0xE442, 0x734A, 0xF7CC, 0xB7AE),
+    bn_pack4(0x6577, 0x2E43, 0x7D6C, 0x7F8C),
+    bn_pack4(0xDB2F, 0xD53D, 0x24B7, 0xC486),
+    bn_pack4(0x6EDF, 0x0195, 0x3934, 0x9627),
+    bn_pack4(0x158B, 0xFD3E, 0x2B9C, 0x8CF5),
+    bn_pack4(0x764E, 0x3F4B, 0x53DD, 0x9DA1),
+    bn_pack4(0x4754, 0x8381, 0xDBC5, 0xB1FC),
+    bn_pack4(0x9B60, 0x9E0B, 0xE3BA, 0xB63D),
+    bn_pack4(0x8134, 0xB1C8, 0xB979, 0x8914),
+    bn_pack4(0xDF02, 0x8A7C, 0xEC67, 0xF0D0),
+    bn_pack4(0x80B6, 0x55BB, 0x9A22, 0xE8DC),
+    bn_pack4(0x1558, 0x903B, 0xA0D0, 0xF843),
+    bn_pack4(0x51C6, 0xA94B, 0xE460, 0x7A29),
+    bn_pack4(0x5F4F, 0x5F55, 0x6E27, 0xCBDE),
+    bn_pack4(0xBEEE, 0xA961, 0x4B19, 0xCC4D),
+    bn_pack4(0xDBA5, 0x1DF4, 0x99AC, 0x4C80),
+    bn_pack4(0xB1F1, 0x2A86, 0x17A4, 0x7BBB),
+    bn_pack4(0x9DEF, 0x3CAF, 0xB939, 0x277A)
+};
+
+const BIGNUM bn_group_1536 = {
+    (BN_ULONG *)bn_group_1536_value,
+    OSSL_NELEM(bn_group_1536_value),
+    OSSL_NELEM(bn_group_1536_value),
+    0,
+    BN_FLG_STATIC_DATA
+};
+
+static const BN_ULONG bn_group_2048_value[] = {
+    bn_pack4(0x0FA7, 0x111F, 0x9E4A, 0xFF73),
+    bn_pack4(0x9B65, 0xE372, 0xFCD6, 0x8EF2),
+    bn_pack4(0x35DE, 0x236D, 0x525F, 0x5475),
+    bn_pack4(0x94B5, 0xC803, 0xD89F, 0x7AE4),
+    bn_pack4(0x71AE, 0x35F8, 0xE9DB, 0xFBB6),
+    bn_pack4(0x2A56, 0x98F3, 0xA8D0, 0xC382),
+    bn_pack4(0x9CCC, 0x041C, 0x7BC3, 0x08D8),
+    bn_pack4(0xAF87, 0x4E73, 0x03CE, 0x5329),
+    bn_pack4(0x6160, 0x2790, 0x04E5, 0x7AE6),
+    bn_pack4(0x032C, 0xFBDB, 0xF52F, 0xB378),
+    bn_pack4(0x5EA7, 0x7A27, 0x75D2, 0xECFA),
+    bn_pack4(0x5445, 0x23B5, 0x24B0, 0xD57D),
+    bn_pack4(0x5B9D, 0x32E6, 0x88F8, 0x7748),
+    bn_pack4(0xF1D2, 0xB907, 0x8717, 0x461A),
+    bn_pack4(0x76BD, 0x207A, 0x436C, 0x6481),
+    bn_pack4(0xCA97, 0xB43A, 0x23FB, 0x8016),
+    bn_pack4(0x1D28, 0x1E44, 0x6B14, 0x773B),
+    bn_pack4(0x7359, 0xD041, 0xD5C3, 0x3EA7),
+    bn_pack4(0xA80D, 0x740A, 0xDBF4, 0xFF74),
+    bn_pack4(0x55F9, 0x7993, 0xEC97, 0x5EEA),
+    bn_pack4(0x2918, 0xA996, 0x2F0B, 0x93B8),
+    bn_pack4(0x661A, 0x05FB, 0xD5FA, 0xAAE8),
+    bn_pack4(0xCF60, 0x9517, 0x9A16, 0x3AB3),
+    bn_pack4(0xE808, 0x3969, 0xEDB7, 0x67B0),
+    bn_pack4(0xCD7F, 0x48A9, 0xDA04, 0xFD50),
+    bn_pack4(0xD523, 0x12AB, 0x4B03, 0x310D),
+    bn_pack4(0x8193, 0xE075, 0x7767, 0xA13D),
+    bn_pack4(0xA373, 0x29CB, 0xB4A0, 0x99ED),
+    bn_pack4(0xFC31, 0x9294, 0x3DB5, 0x6050),
+    bn_pack4(0xAF72, 0xB665, 0x1987, 0xEE07),
+    bn_pack4(0xF166, 0xDE5E, 0x1389, 0x582F),
+    bn_pack4(0xAC6B, 0xDB41, 0x324A, 0x9A9B)
+};
+
+const BIGNUM bn_group_2048 = {
+    (BN_ULONG *)bn_group_2048_value,
+    OSSL_NELEM(bn_group_2048_value),
+    OSSL_NELEM(bn_group_2048_value),
+    0,
+    BN_FLG_STATIC_DATA
+};
+
+static const BN_ULONG bn_group_3072_value[] = {
+    bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF),
+    bn_pack4(0x4B82, 0xD120, 0xA93A, 0xD2CA),
+    bn_pack4(0x43DB, 0x5BFC, 0xE0FD, 0x108E),
+    bn_pack4(0x08E2, 0x4FA0, 0x74E5, 0xAB31),
+    bn_pack4(0x7709, 0x88C0, 0xBAD9, 0x46E2),
+    bn_pack4(0xBBE1, 0x1757, 0x7A61, 0x5D6C),
+    bn_pack4(0x521F, 0x2B18, 0x177B, 0x200C),
+    bn_pack4(0xD876, 0x0273, 0x3EC8, 0x6A64),
+    bn_pack4(0xF12F, 0xFA06, 0xD98A, 0x0864),
+    bn_pack4(0xCEE3, 0xD226, 0x1AD2, 0xEE6B),
+    bn_pack4(0x1E8C, 0x94E0, 0x4A25, 0x619D),
+    bn_pack4(0xABF5, 0xAE8C, 0xDB09, 0x33D7),
+    bn_pack4(0xB397, 0x0F85, 0xA6E1, 0xE4C7),
+    bn_pack4(0x8AEA, 0x7157, 0x5D06, 0x0C7D),
+    bn_pack4(0xECFB, 0x8504, 0x58DB, 0xEF0A),
+    bn_pack4(0xA855, 0x21AB, 0xDF1C, 0xBA64),
+    bn_pack4(0xAD33, 0x170D, 0x0450, 0x7A33),
+    bn_pack4(0x1572, 0x8E5A, 0x8AAA, 0xC42D),
+    bn_pack4(0x15D2, 0x2618, 0x98FA, 0x0510),
+    bn_pack4(0x3995, 0x497C, 0xEA95, 0x6AE5),
+    bn_pack4(0xDE2B, 0xCBF6, 0x9558, 0x1718),
+    bn_pack4(0xB5C5, 0x5DF0, 0x6F4C, 0x52C9),
+    bn_pack4(0x9B27, 0x83A2, 0xEC07, 0xA28F),
+    bn_pack4(0xE39E, 0x772C, 0x180E, 0x8603),
+    bn_pack4(0x3290, 0x5E46, 0x2E36, 0xCE3B),
+    bn_pack4(0xF174, 0x6C08, 0xCA18, 0x217C),
+    bn_pack4(0x670C, 0x354E, 0x4ABC, 0x9804),
+    bn_pack4(0x9ED5, 0x2907, 0x7096, 0x966D),
+    bn_pack4(0x1C62, 0xF356, 0x2085, 0x52BB),
+    bn_pack4(0x8365, 0x5D23, 0xDCA3, 0xAD96),
+    bn_pack4(0x6916, 0x3FA8, 0xFD24, 0xCF5F),
+    bn_pack4(0x98DA, 0x4836, 0x1C55, 0xD39A),
+    bn_pack4(0xC200, 0x7CB8, 0xA163, 0xBF05),
+    bn_pack4(0x4928, 0x6651, 0xECE4, 0x5B3D),
+    bn_pack4(0xAE9F, 0x2411, 0x7C4B, 0x1FE6),
+    bn_pack4(0xEE38, 0x6BFB, 0x5A89, 0x9FA5),
+    bn_pack4(0x0BFF, 0x5CB6, 0xF406, 0xB7ED),
+    bn_pack4(0xF44C, 0x42E9, 0xA637, 0xED6B),
+    bn_pack4(0xE485, 0xB576, 0x625E, 0x7EC6),
+    bn_pack4(0x4FE1, 0x356D, 0x6D51, 0xC245),
+    bn_pack4(0x302B, 0x0A6D, 0xF25F, 0x1437),
+    bn_pack4(0xEF95, 0x19B3, 0xCD3A, 0x431B),
+    bn_pack4(0x514A, 0x0879, 0x8E34, 0x04DD),
+    bn_pack4(0x020B, 0xBEA6, 0x3B13, 0x9B22),
+    bn_pack4(0x2902, 0x4E08, 0x8A67, 0xCC74),
+    bn_pack4(0xC4C6, 0x628B, 0x80DC, 0x1CD1),
+    bn_pack4(0xC90F, 0xDAA2, 0x2168, 0xC234),
+    bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)
+};
+
+const BIGNUM bn_group_3072 = {
+    (BN_ULONG *)bn_group_3072_value,
+    OSSL_NELEM(bn_group_3072_value),
+    OSSL_NELEM(bn_group_3072_value),
+    0,
+    BN_FLG_STATIC_DATA
+};
+
+static const BN_ULONG bn_group_4096_value[] = {
+    bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF),
+    bn_pack4(0x4DF4, 0x35C9, 0x3406, 0x3199),
+    bn_pack4(0x86FF, 0xB7DC, 0x90A6, 0xC08F),
+    bn_pack4(0x93B4, 0xEA98, 0x8D8F, 0xDDC1),
+    bn_pack4(0xD006, 0x9127, 0xD5B0, 0x5AA9),
+    bn_pack4(0xB81B, 0xDD76, 0x2170, 0x481C),
+    bn_pack4(0x1F61, 0x2970, 0xCEE2, 0xD7AF),
+    bn_pack4(0x233B, 0xA186, 0x515B, 0xE7ED),
+    bn_pack4(0x99B2, 0x964F, 0xA090, 0xC3A2),
+    bn_pack4(0x287C, 0x5947, 0x4E6B, 0xC05D),
+    bn_pack4(0x2E8E, 0xFC14, 0x1FBE, 0xCAA6),
+    bn_pack4(0xDBBB, 0xC2DB, 0x04DE, 0x8EF9),
+    bn_pack4(0x2583, 0xE9CA, 0x2AD4, 0x4CE8),
+    bn_pack4(0x1A94, 0x6834, 0xB615, 0x0BDA),
+    bn_pack4(0x99C3, 0x2718, 0x6AF4, 0xE23C),
+    bn_pack4(0x8871, 0x9A10, 0xBDBA, 0x5B26),
+    bn_pack4(0x1A72, 0x3C12, 0xA787, 0xE6D7),
+    bn_pack4(0x4B82, 0xD120, 0xA921, 0x0801),
+    bn_pack4(0x43DB, 0x5BFC, 0xE0FD, 0x108E),
+    bn_pack4(0x08E2, 0x4FA0, 0x74E5, 0xAB31),
+    bn_pack4(0x7709, 0x88C0, 0xBAD9, 0x46E2),
+    bn_pack4(0xBBE1, 0x1757, 0x7A61, 0x5D6C),
+    bn_pack4(0x521F, 0x2B18, 0x177B, 0x200C),
+    bn_pack4(0xD876, 0x0273, 0x3EC8, 0x6A64),
+    bn_pack4(0xF12F, 0xFA06, 0xD98A, 0x0864),
+    bn_pack4(0xCEE3, 0xD226, 0x1AD2, 0xEE6B),
+    bn_pack4(0x1E8C, 0x94E0, 0x4A25, 0x619D),
+    bn_pack4(0xABF5, 0xAE8C, 0xDB09, 0x33D7),
+    bn_pack4(0xB397, 0x0F85, 0xA6E1, 0xE4C7),
+    bn_pack4(0x8AEA, 0x7157, 0x5D06, 0x0C7D),
+    bn_pack4(0xECFB, 0x8504, 0x58DB, 0xEF0A),
+    bn_pack4(0xA855, 0x21AB, 0xDF1C, 0xBA64),
+    bn_pack4(0xAD33, 0x170D, 0x0450, 0x7A33),
+    bn_pack4(0x1572, 0x8E5A, 0x8AAA, 0xC42D),
+    bn_pack4(0x15D2, 0x2618, 0x98FA, 0x0510),
+    bn_pack4(0x3995, 0x497C, 0xEA95, 0x6AE5),
+    bn_pack4(0xDE2B, 0xCBF6, 0x9558, 0x1718),
+    bn_pack4(0xB5C5, 0x5DF0, 0x6F4C, 0x52C9),
+    bn_pack4(0x9B27, 0x83A2, 0xEC07, 0xA28F),
+    bn_pack4(0xE39E, 0x772C, 0x180E, 0x8603),
+    bn_pack4(0x3290, 0x5E46, 0x2E36, 0xCE3B),
+    bn_pack4(0xF174, 0x6C08, 0xCA18, 0x217C),
+    bn_pack4(0x670C, 0x354E, 0x4ABC, 0x9804),
+    bn_pack4(0x9ED5, 0x2907, 0x7096, 0x966D),
+    bn_pack4(0x1C62, 0xF356, 0x2085, 0x52BB),
+    bn_pack4(0x8365, 0x5D23, 0xDCA3, 0xAD96),
+    bn_pack4(0x6916, 0x3FA8, 0xFD24, 0xCF5F),
+    bn_pack4(0x98DA, 0x4836, 0x1C55, 0xD39A),
+    bn_pack4(0xC200, 0x7CB8, 0xA163, 0xBF05),
+    bn_pack4(0x4928, 0x6651, 0xECE4, 0x5B3D),
+    bn_pack4(0xAE9F, 0x2411, 0x7C4B, 0x1FE6),
+    bn_pack4(0xEE38, 0x6BFB, 0x5A89, 0x9FA5),
+    bn_pack4(0x0BFF, 0x5CB6, 0xF406, 0xB7ED),
+    bn_pack4(0xF44C, 0x42E9, 0xA637, 0xED6B),
+    bn_pack4(0xE485, 0xB576, 0x625E, 0x7EC6),
+    bn_pack4(0x4FE1, 0x356D, 0x6D51, 0xC245),
+    bn_pack4(0x302B, 0x0A6D, 0xF25F, 0x1437),
+    bn_pack4(0xEF95, 0x19B3, 0xCD3A, 0x431B),
+    bn_pack4(0x514A, 0x0879, 0x8E34, 0x04DD),
+    bn_pack4(0x020B, 0xBEA6, 0x3B13, 0x9B22),
+    bn_pack4(0x2902, 0x4E08, 0x8A67, 0xCC74),
+    bn_pack4(0xC4C6, 0x628B, 0x80DC, 0x1CD1),
+    bn_pack4(0xC90F, 0xDAA2, 0x2168, 0xC234),
+    bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)
+};
+
+const BIGNUM bn_group_4096 = {
+    (BN_ULONG *)bn_group_4096_value,
+    OSSL_NELEM(bn_group_4096_value),
+    OSSL_NELEM(bn_group_4096_value),
+    0,
+    BN_FLG_STATIC_DATA
+};
+
+static const BN_ULONG bn_group_6144_value[] = {
+    bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF),
+    bn_pack4(0xE694, 0xF91E, 0x6DCC, 0x4024),
+    bn_pack4(0x12BF, 0x2D5B, 0x0B74, 0x74D6),
+    bn_pack4(0x043E, 0x8F66, 0x3F48, 0x60EE),
+    bn_pack4(0x387F, 0xE8D7, 0x6E3C, 0x0468),
+    bn_pack4(0xDA56, 0xC9EC, 0x2EF2, 0x9632),
+    bn_pack4(0xEB19, 0xCCB1, 0xA313, 0xD55C),
+    bn_pack4(0xF550, 0xAA3D, 0x8A1F, 0xBFF0),
+    bn_pack4(0x06A1, 0xD58B, 0xB7C5, 0xDA76),
+    bn_pack4(0xA797, 0x15EE, 0xF29B, 0xE328),
+    bn_pack4(0x14CC, 0x5ED2, 0x0F80, 0x37E0),
+    bn_pack4(0xCC8F, 0x6D7E, 0xBF48, 0xE1D8),
+    bn_pack4(0x4BD4, 0x07B2, 0x2B41, 0x54AA),
+    bn_pack4(0x0F1D, 0x45B7, 0xFF58, 0x5AC5),
+    bn_pack4(0x23A9, 0x7A7E, 0x36CC, 0x88BE),
+    bn_pack4(0x59E7, 0xC97F, 0xBEC7, 0xE8F3),
+    bn_pack4(0xB5A8, 0x4031, 0x900B, 0x1C9E),
+    bn_pack4(0xD55E, 0x702F, 0x4698, 0x0C82),
+    bn_pack4(0xF482, 0xD7CE, 0x6E74, 0xFEF6),
+    bn_pack4(0xF032, 0xEA15, 0xD172, 0x1D03),
+    bn_pack4(0x5983, 0xCA01, 0xC64B, 0x92EC),
+    bn_pack4(0x6FB8, 0xF401, 0x378C, 0xD2BF),
+    bn_pack4(0x3320, 0x5151, 0x2BD7, 0xAF42),
+    bn_pack4(0xDB7F, 0x1447, 0xE6CC, 0x254B),
+    bn_pack4(0x44CE, 0x6CBA, 0xCED4, 0xBB1B),
+    bn_pack4(0xDA3E, 0xDBEB, 0xCF9B, 0x14ED),
+    bn_pack4(0x1797, 0x27B0, 0x865A, 0x8918),
+    bn_pack4(0xB06A, 0x53ED, 0x9027, 0xD831),
+    bn_pack4(0xE5DB, 0x382F, 0x4130, 0x01AE),
+    bn_pack4(0xF8FF, 0x9406, 0xAD9E, 0x530E),
+    bn_pack4(0xC975, 0x1E76, 0x3DBA, 0x37BD),
+    bn_pack4(0xC1D4, 0xDCB2, 0x6026, 0x46DE),
+    bn_pack4(0x36C3, 0xFAB4, 0xD27C, 0x7026),
+    bn_pack4(0x4DF4, 0x35C9, 0x3402, 0x8492),
+    bn_pack4(0x86FF, 0xB7DC, 0x90A6, 0xC08F),
+    bn_pack4(0x93B4, 0xEA98, 0x8D8F, 0xDDC1),
+    bn_pack4(0xD006, 0x9127, 0xD5B0, 0x5AA9),
+    bn_pack4(0xB81B, 0xDD76, 0x2170, 0x481C),
+    bn_pack4(0x1F61, 0x2970, 0xCEE2, 0xD7AF),
+    bn_pack4(0x233B, 0xA186, 0x515B, 0xE7ED),
+    bn_pack4(0x99B2, 0x964F, 0xA090, 0xC3A2),
+    bn_pack4(0x287C, 0x5947, 0x4E6B, 0xC05D),
+    bn_pack4(0x2E8E, 0xFC14, 0x1FBE, 0xCAA6),
+    bn_pack4(0xDBBB, 0xC2DB, 0x04DE, 0x8EF9),
+    bn_pack4(0x2583, 0xE9CA, 0x2AD4, 0x4CE8),
+    bn_pack4(0x1A94, 0x6834, 0xB615, 0x0BDA),
+    bn_pack4(0x99C3, 0x2718, 0x6AF4, 0xE23C),
+    bn_pack4(0x8871, 0x9A10, 0xBDBA, 0x5B26),
+    bn_pack4(0x1A72, 0x3C12, 0xA787, 0xE6D7),
+    bn_pack4(0x4B82, 0xD120, 0xA921, 0x0801),
+    bn_pack4(0x43DB, 0x5BFC, 0xE0FD, 0x108E),
+    bn_pack4(0x08E2, 0x4FA0, 0x74E5, 0xAB31),
+    bn_pack4(0x7709, 0x88C0, 0xBAD9, 0x46E2),
+    bn_pack4(0xBBE1, 0x1757, 0x7A61, 0x5D6C),
+    bn_pack4(0x521F, 0x2B18, 0x177B, 0x200C),
+    bn_pack4(0xD876, 0x0273, 0x3EC8, 0x6A64),
+    bn_pack4(0xF12F, 0xFA06, 0xD98A, 0x0864),
+    bn_pack4(0xCEE3, 0xD226, 0x1AD2, 0xEE6B),
+    bn_pack4(0x1E8C, 0x94E0, 0x4A25, 0x619D),
+    bn_pack4(0xABF5, 0xAE8C, 0xDB09, 0x33D7),
+    bn_pack4(0xB397, 0x0F85, 0xA6E1, 0xE4C7),
+    bn_pack4(0x8AEA, 0x7157, 0x5D06, 0x0C7D),
+    bn_pack4(0xECFB, 0x8504, 0x58DB, 0xEF0A),
+    bn_pack4(0xA855, 0x21AB, 0xDF1C, 0xBA64),
+    bn_pack4(0xAD33, 0x170D, 0x0450, 0x7A33),
+    bn_pack4(0x1572, 0x8E5A, 0x8AAA, 0xC42D),
+    bn_pack4(0x15D2, 0x2618, 0x98FA, 0x0510),
+    bn_pack4(0x3995, 0x497C, 0xEA95, 0x6AE5),
+    bn_pack4(0xDE2B, 0xCBF6, 0x9558, 0x1718),
+    bn_pack4(0xB5C5, 0x5DF0, 0x6F4C, 0x52C9),
+    bn_pack4(0x9B27, 0x83A2, 0xEC07, 0xA28F),
+    bn_pack4(0xE39E, 0x772C, 0x180E, 0x8603),
+    bn_pack4(0x3290, 0x5E46, 0x2E36, 0xCE3B),
+    bn_pack4(0xF174, 0x6C08, 0xCA18, 0x217C),
+    bn_pack4(0x670C, 0x354E, 0x4ABC, 0x9804),
+    bn_pack4(0x9ED5, 0x2907, 0x7096, 0x966D),
+    bn_pack4(0x1C62, 0xF356, 0x2085, 0x52BB),
+    bn_pack4(0x8365, 0x5D23, 0xDCA3, 0xAD96),
+    bn_pack4(0x6916, 0x3FA8, 0xFD24, 0xCF5F),
+    bn_pack4(0x98DA, 0x4836, 0x1C55, 0xD39A),
+    bn_pack4(0xC200, 0x7CB8, 0xA163, 0xBF05),
+    bn_pack4(0x4928, 0x6651, 0xECE4, 0x5B3D),
+    bn_pack4(0xAE9F, 0x2411, 0x7C4B, 0x1FE6),
+    bn_pack4(0xEE38, 0x6BFB, 0x5A89, 0x9FA5),
+    bn_pack4(0x0BFF, 0x5CB6, 0xF406, 0xB7ED),
+    bn_pack4(0xF44C, 0x42E9, 0xA637, 0xED6B),
+    bn_pack4(0xE485, 0xB576, 0x625E, 0x7EC6),
+    bn_pack4(0x4FE1, 0x356D, 0x6D51, 0xC245),
+    bn_pack4(0x302B, 0x0A6D, 0xF25F, 0x1437),
+    bn_pack4(0xEF95, 0x19B3, 0xCD3A, 0x431B),
+    bn_pack4(0x514A, 0x0879, 0x8E34, 0x04DD),
+    bn_pack4(0x020B, 0xBEA6, 0x3B13, 0x9B22),
+    bn_pack4(0x2902, 0x4E08, 0x8A67, 0xCC74),
+    bn_pack4(0xC4C6, 0x628B, 0x80DC, 0x1CD1),
+    bn_pack4(0xC90F, 0xDAA2, 0x2168, 0xC234),
+    bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)
+};
+
+const BIGNUM bn_group_6144 = {
+    (BN_ULONG *)bn_group_6144_value,
+    OSSL_NELEM(bn_group_6144_value),
+    OSSL_NELEM(bn_group_6144_value),
+    0,
+    BN_FLG_STATIC_DATA
+};
+
+static const BN_ULONG bn_group_8192_value[] = {
+    bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF),
+    bn_pack4(0x60C9, 0x80DD, 0x98ED, 0xD3DF),
+    bn_pack4(0xC81F, 0x56E8, 0x80B9, 0x6E71),
+    bn_pack4(0x9E30, 0x50E2, 0x7656, 0x94DF),
+    bn_pack4(0x9558, 0xE447, 0x5677, 0xE9AA),
+    bn_pack4(0xC919, 0x0DA6, 0xFC02, 0x6E47),
+    bn_pack4(0x889A, 0x002E, 0xD5EE, 0x382B),
+    bn_pack4(0x4009, 0x438B, 0x481C, 0x6CD7),
+    bn_pack4(0x3590, 0x46F4, 0xEB87, 0x9F92),
+    bn_pack4(0xFAF3, 0x6BC3, 0x1ECF, 0xA268),
+    bn_pack4(0xB1D5, 0x10BD, 0x7EE7, 0x4D73),
+    bn_pack4(0xF9AB, 0x4819, 0x5DED, 0x7EA1),
+    bn_pack4(0x64F3, 0x1CC5, 0x0846, 0x851D),
+    bn_pack4(0x4597, 0xE899, 0xA025, 0x5DC1),
+    bn_pack4(0xDF31, 0x0EE0, 0x74AB, 0x6A36),
+    bn_pack4(0x6D2A, 0x13F8, 0x3F44, 0xF82D),
+    bn_pack4(0x062B, 0x3CF5, 0xB3A2, 0x78A6),
+    bn_pack4(0x7968, 0x3303, 0xED5B, 0xDD3A),
+    bn_pack4(0xFA9D, 0x4B7F, 0xA2C0, 0x87E8),
+    bn_pack4(0x4BCB, 0xC886, 0x2F83, 0x85DD),
+    bn_pack4(0x3473, 0xFC64, 0x6CEA, 0x306B),
+    bn_pack4(0x13EB, 0x57A8, 0x1A23, 0xF0C7),
+    bn_pack4(0x2222, 0x2E04, 0xA403, 0x7C07),
+    bn_pack4(0xE3FD, 0xB8BE, 0xFC84, 0x8AD9),
+    bn_pack4(0x238F, 0x16CB, 0xE39D, 0x652D),
+    bn_pack4(0x3423, 0xB474, 0x2BF1, 0xC978),
+    bn_pack4(0x3AAB, 0x639C, 0x5AE4, 0xF568),
+    bn_pack4(0x2576, 0xF693, 0x6BA4, 0x2466),
+    bn_pack4(0x741F, 0xA7BF, 0x8AFC, 0x47ED),
+    bn_pack4(0x3BC8, 0x32B6, 0x8D9D, 0xD300),
+    bn_pack4(0xD8BE, 0xC4D0, 0x73B9, 0x31BA),
+    bn_pack4(0x3877, 0x7CB6, 0xA932, 0xDF8C),
+    bn_pack4(0x74A3, 0x926F, 0x12FE, 0xE5E4),
+    bn_pack4(0xE694, 0xF91E, 0x6DBE, 0x1159),
+    bn_pack4(0x12BF, 0x2D5B, 0x0B74, 0x74D6),
+    bn_pack4(0x043E, 0x8F66, 0x3F48, 0x60EE),
+    bn_pack4(0x387F, 0xE8D7, 0x6E3C, 0x0468),
+    bn_pack4(0xDA56, 0xC9EC, 0x2EF2, 0x9632),
+    bn_pack4(0xEB19, 0xCCB1, 0xA313, 0xD55C),
+    bn_pack4(0xF550, 0xAA3D, 0x8A1F, 0xBFF0),
+    bn_pack4(0x06A1, 0xD58B, 0xB7C5, 0xDA76),
+    bn_pack4(0xA797, 0x15EE, 0xF29B, 0xE328),
+    bn_pack4(0x14CC, 0x5ED2, 0x0F80, 0x37E0),
+    bn_pack4(0xCC8F, 0x6D7E, 0xBF48, 0xE1D8),
+    bn_pack4(0x4BD4, 0x07B2, 0x2B41, 0x54AA),
+    bn_pack4(0x0F1D, 0x45B7, 0xFF58, 0x5AC5),
+    bn_pack4(0x23A9, 0x7A7E, 0x36CC, 0x88BE),
+    bn_pack4(0x59E7, 0xC97F, 0xBEC7, 0xE8F3),
+    bn_pack4(0xB5A8, 0x4031, 0x900B, 0x1C9E),
+    bn_pack4(0xD55E, 0x702F, 0x4698, 0x0C82),
+    bn_pack4(0xF482, 0xD7CE, 0x6E74, 0xFEF6),
+    bn_pack4(0xF032, 0xEA15, 0xD172, 0x1D03),
+    bn_pack4(0x5983, 0xCA01, 0xC64B, 0x92EC),
+    bn_pack4(0x6FB8, 0xF401, 0x378C, 0xD2BF),
+    bn_pack4(0x3320, 0x5151, 0x2BD7, 0xAF42),
+    bn_pack4(0xDB7F, 0x1447, 0xE6CC, 0x254B),
+    bn_pack4(0x44CE, 0x6CBA, 0xCED4, 0xBB1B),
+    bn_pack4(0xDA3E, 0xDBEB, 0xCF9B, 0x14ED),
+    bn_pack4(0x1797, 0x27B0, 0x865A, 0x8918),
+    bn_pack4(0xB06A, 0x53ED, 0x9027, 0xD831),
+    bn_pack4(0xE5DB, 0x382F, 0x4130, 0x01AE),
+    bn_pack4(0xF8FF, 0x9406, 0xAD9E, 0x530E),
+    bn_pack4(0xC975, 0x1E76, 0x3DBA, 0x37BD),
+    bn_pack4(0xC1D4, 0xDCB2, 0x6026, 0x46DE),
+    bn_pack4(0x36C3, 0xFAB4, 0xD27C, 0x7026),
+    bn_pack4(0x4DF4, 0x35C9, 0x3402, 0x8492),
+    bn_pack4(0x86FF, 0xB7DC, 0x90A6, 0xC08F),
+    bn_pack4(0x93B4, 0xEA98, 0x8D8F, 0xDDC1),
+    bn_pack4(0xD006, 0x9127, 0xD5B0, 0x5AA9),
+    bn_pack4(0xB81B, 0xDD76, 0x2170, 0x481C),
+    bn_pack4(0x1F61, 0x2970, 0xCEE2, 0xD7AF),
+    bn_pack4(0x233B, 0xA186, 0x515B, 0xE7ED),
+    bn_pack4(0x99B2, 0x964F, 0xA090, 0xC3A2),
+    bn_pack4(0x287C, 0x5947, 0x4E6B, 0xC05D),
+    bn_pack4(0x2E8E, 0xFC14, 0x1FBE, 0xCAA6),
+    bn_pack4(0xDBBB, 0xC2DB, 0x04DE, 0x8EF9),
+    bn_pack4(0x2583, 0xE9CA, 0x2AD4, 0x4CE8),
+    bn_pack4(0x1A94, 0x6834, 0xB615, 0x0BDA),
+    bn_pack4(0x99C3, 0x2718, 0x6AF4, 0xE23C),
+    bn_pack4(0x8871, 0x9A10, 0xBDBA, 0x5B26),
+    bn_pack4(0x1A72, 0x3C12, 0xA787, 0xE6D7),
+    bn_pack4(0x4B82, 0xD120, 0xA921, 0x0801),
+    bn_pack4(0x43DB, 0x5BFC, 0xE0FD, 0x108E),
+    bn_pack4(0x08E2, 0x4FA0, 0x74E5, 0xAB31),
+    bn_pack4(0x7709, 0x88C0, 0xBAD9, 0x46E2),
+    bn_pack4(0xBBE1, 0x1757, 0x7A61, 0x5D6C),
+    bn_pack4(0x521F, 0x2B18, 0x177B, 0x200C),
+    bn_pack4(0xD876, 0x0273, 0x3EC8, 0x6A64),
+    bn_pack4(0xF12F, 0xFA06, 0xD98A, 0x0864),
+    bn_pack4(0xCEE3, 0xD226, 0x1AD2, 0xEE6B),
+    bn_pack4(0x1E8C, 0x94E0, 0x4A25, 0x619D),
+    bn_pack4(0xABF5, 0xAE8C, 0xDB09, 0x33D7),
+    bn_pack4(0xB397, 0x0F85, 0xA6E1, 0xE4C7),
+    bn_pack4(0x8AEA, 0x7157, 0x5D06, 0x0C7D),
+    bn_pack4(0xECFB, 0x8504, 0x58DB, 0xEF0A),
+    bn_pack4(0xA855, 0x21AB, 0xDF1C, 0xBA64),
+    bn_pack4(0xAD33, 0x170D, 0x0450, 0x7A33),
+    bn_pack4(0x1572, 0x8E5A, 0x8AAA, 0xC42D),
+    bn_pack4(0x15D2, 0x2618, 0x98FA, 0x0510),
+    bn_pack4(0x3995, 0x497C, 0xEA95, 0x6AE5),
+    bn_pack4(0xDE2B, 0xCBF6, 0x9558, 0x1718),
+    bn_pack4(0xB5C5, 0x5DF0, 0x6F4C, 0x52C9),
+    bn_pack4(0x9B27, 0x83A2, 0xEC07, 0xA28F),
+    bn_pack4(0xE39E, 0x772C, 0x180E, 0x8603),
+    bn_pack4(0x3290, 0x5E46, 0x2E36, 0xCE3B),
+    bn_pack4(0xF174, 0x6C08, 0xCA18, 0x217C),
+    bn_pack4(0x670C, 0x354E, 0x4ABC, 0x9804),
+    bn_pack4(0x9ED5, 0x2907, 0x7096, 0x966D),
+    bn_pack4(0x1C62, 0xF356, 0x2085, 0x52BB),
+    bn_pack4(0x8365, 0x5D23, 0xDCA3, 0xAD96),
+    bn_pack4(0x6916, 0x3FA8, 0xFD24, 0xCF5F),
+    bn_pack4(0x98DA, 0x4836, 0x1C55, 0xD39A),
+    bn_pack4(0xC200, 0x7CB8, 0xA163, 0xBF05),
+    bn_pack4(0x4928, 0x6651, 0xECE4, 0x5B3D),
+    bn_pack4(0xAE9F, 0x2411, 0x7C4B, 0x1FE6),
+    bn_pack4(0xEE38, 0x6BFB, 0x5A89, 0x9FA5),
+    bn_pack4(0x0BFF, 0x5CB6, 0xF406, 0xB7ED),
+    bn_pack4(0xF44C, 0x42E9, 0xA637, 0xED6B),
+    bn_pack4(0xE485, 0xB576, 0x625E, 0x7EC6),
+    bn_pack4(0x4FE1, 0x356D, 0x6D51, 0xC245),
+    bn_pack4(0x302B, 0x0A6D, 0xF25F, 0x1437),
+    bn_pack4(0xEF95, 0x19B3, 0xCD3A, 0x431B),
+    bn_pack4(0x514A, 0x0879, 0x8E34, 0x04DD),
+    bn_pack4(0x020B, 0xBEA6, 0x3B13, 0x9B22),
+    bn_pack4(0x2902, 0x4E08, 0x8A67, 0xCC74),
+    bn_pack4(0xC4C6, 0x628B, 0x80DC, 0x1CD1),
+    bn_pack4(0xC90F, 0xDAA2, 0x2168, 0xC234),
+    bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF)
+};
+
+const BIGNUM bn_group_8192 = {
+    (BN_ULONG *)bn_group_8192_value,
+    OSSL_NELEM(bn_group_8192_value),
+    OSSL_NELEM(bn_group_8192_value),
+    0,
+    BN_FLG_STATIC_DATA
+};
+
+static const BN_ULONG bn_generator_19_value[] = { 19 };
+
+const BIGNUM bn_generator_19 = {
+    (BN_ULONG *)bn_generator_19_value,
+    1,
+    1,
+    0,
+    BN_FLG_STATIC_DATA
+};
+static const BN_ULONG bn_generator_5_value[] = { 5 };
+
+const BIGNUM bn_generator_5 = {
+    (BN_ULONG *)bn_generator_5_value,
+    1,
+    1,
+    0,
+    BN_FLG_STATIC_DATA
+};
+static const BN_ULONG bn_generator_2_value[] = { 2 };
+
+const BIGNUM bn_generator_2 = {
+    (BN_ULONG *)bn_generator_2_value,
+    1,
+    1,
+    0,
+    BN_FLG_STATIC_DATA
+};
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_word.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_word.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_word.c	(revision 331)
@@ -0,0 +1,201 @@
+/*
+ * Copyright 1995-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 "internal/cryptlib.h"
+#include "bn_lcl.h"
+
+BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w)
+{
+#ifndef BN_LLONG
+    BN_ULONG ret = 0;
+#else
+    BN_ULLONG ret = 0;
+#endif
+    int i;
+
+    if (w == 0)
+        return (BN_ULONG)-1;
+
+#ifndef BN_LLONG
+    /*
+     * If |w| is too long and we don't have BN_ULLONG then we need to fall
+     * back to using BN_div_word
+     */
+    if (w > ((BN_ULONG)1 << BN_BITS4)) {
+        BIGNUM *tmp = BN_dup(a);
+        if (tmp == NULL)
+            return (BN_ULONG)-1;
+
+        ret = BN_div_word(tmp, w);
+        BN_free(tmp);
+
+        return ret;
+    }
+#endif
+
+    bn_check_top(a);
+    w &= BN_MASK2;
+    for (i = a->top - 1; i >= 0; i--) {
+#ifndef BN_LLONG
+        /*
+         * We can assume here that | w <= ((BN_ULONG)1 << BN_BITS4) | and so
+         * | ret < ((BN_ULONG)1 << BN_BITS4) | and therefore the shifts here are
+         * safe and will not overflow
+         */
+        ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) & BN_MASK2l)) % w;
+        ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w;
+#else
+        ret = (BN_ULLONG) (((ret << (BN_ULLONG) BN_BITS2) | a->d[i]) %
+                           (BN_ULLONG) w);
+#endif
+    }
+    return ((BN_ULONG)ret);
+}
+
+BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w)
+{
+    BN_ULONG ret = 0;
+    int i, j;
+
+    bn_check_top(a);
+    w &= BN_MASK2;
+
+    if (!w)
+        /* actually this an error (division by zero) */
+        return (BN_ULONG)-1;
+    if (a->top == 0)
+        return 0;
+
+    /* normalize input (so bn_div_words doesn't complain) */
+    j = BN_BITS2 - BN_num_bits_word(w);
+    w <<= j;
+    if (!BN_lshift(a, a, j))
+        return (BN_ULONG)-1;
+
+    for (i = a->top - 1; i >= 0; i--) {
+        BN_ULONG l, d;
+
+        l = a->d[i];
+        d = bn_div_words(ret, l, w);
+        ret = (l - ((d * w) & BN_MASK2)) & BN_MASK2;
+        a->d[i] = d;
+    }
+    if ((a->top > 0) && (a->d[a->top - 1] == 0))
+        a->top--;
+    ret >>= j;
+    if (!a->top)
+        a->neg = 0; /* don't allow negative zero */
+    bn_check_top(a);
+    return (ret);
+}
+
+int BN_add_word(BIGNUM *a, BN_ULONG w)
+{
+    BN_ULONG l;
+    int i;
+
+    bn_check_top(a);
+    w &= BN_MASK2;
+
+    /* degenerate case: w is zero */
+    if (!w)
+        return 1;
+    /* degenerate case: a is zero */
+    if (BN_is_zero(a))
+        return BN_set_word(a, w);
+    /* handle 'a' when negative */
+    if (a->neg) {
+        a->neg = 0;
+        i = BN_sub_word(a, w);
+        if (!BN_is_zero(a))
+            a->neg = !(a->neg);
+        return (i);
+    }
+    for (i = 0; w != 0 && i < a->top; i++) {
+        a->d[i] = l = (a->d[i] + w) & BN_MASK2;
+        w = (w > l) ? 1 : 0;
+    }
+    if (w && i == a->top) {
+        if (bn_wexpand(a, a->top + 1) == NULL)
+            return 0;
+        a->top++;
+        a->d[i] = w;
+    }
+    bn_check_top(a);
+    return (1);
+}
+
+int BN_sub_word(BIGNUM *a, BN_ULONG w)
+{
+    int i;
+
+    bn_check_top(a);
+    w &= BN_MASK2;
+
+    /* degenerate case: w is zero */
+    if (!w)
+        return 1;
+    /* degenerate case: a is zero */
+    if (BN_is_zero(a)) {
+        i = BN_set_word(a, w);
+        if (i != 0)
+            BN_set_negative(a, 1);
+        return i;
+    }
+    /* handle 'a' when negative */
+    if (a->neg) {
+        a->neg = 0;
+        i = BN_add_word(a, w);
+        a->neg = 1;
+        return (i);
+    }
+
+    if ((a->top == 1) && (a->d[0] < w)) {
+        a->d[0] = w - a->d[0];
+        a->neg = 1;
+        return (1);
+    }
+    i = 0;
+    for (;;) {
+        if (a->d[i] >= w) {
+            a->d[i] -= w;
+            break;
+        } else {
+            a->d[i] = (a->d[i] - w) & BN_MASK2;
+            i++;
+            w = 1;
+        }
+    }
+    if ((a->d[i] == 0) && (i == (a->top - 1)))
+        a->top--;
+    bn_check_top(a);
+    return (1);
+}
+
+int BN_mul_word(BIGNUM *a, BN_ULONG w)
+{
+    BN_ULONG ll;
+
+    bn_check_top(a);
+    w &= BN_MASK2;
+    if (a->top) {
+        if (w == 0)
+            BN_zero(a);
+        else {
+            ll = bn_mul_words(a->d, a->d, a->top, w);
+            if (ll) {
+                if (bn_wexpand(a, a->top + 1) == NULL)
+                    return (0);
+                a->d[a->top++] = ll;
+            }
+        }
+    }
+    bn_check_top(a);
+    return (1);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_x931p.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_x931p.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/bn_x931p.c	(revision 331)
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2011-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 <stdio.h>
+#include <openssl/bn.h>
+#include "bn_lcl.h"
+
+/* X9.31 routines for prime derivation */
+
+/*
+ * X9.31 prime derivation. This is used to generate the primes pi (p1, p2,
+ * q1, q2) from a parameter Xpi by checking successive odd integers.
+ */
+
+static int bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx,
+                             BN_GENCB *cb)
+{
+    int i = 0, is_prime;
+    if (!BN_copy(pi, Xpi))
+        return 0;
+    if (!BN_is_odd(pi) && !BN_add_word(pi, 1))
+        return 0;
+    for (;;) {
+        i++;
+        BN_GENCB_call(cb, 0, i);
+        /* NB 27 MR is specified in X9.31 */
+        is_prime = BN_is_prime_fasttest_ex(pi, 27, ctx, 1, cb);
+        if (is_prime < 0)
+            return 0;
+        if (is_prime)
+            break;
+        if (!BN_add_word(pi, 2))
+            return 0;
+    }
+    BN_GENCB_call(cb, 2, i);
+    return 1;
+}
+
+/*
+ * This is the main X9.31 prime derivation function. From parameters Xp1, Xp2
+ * and Xp derive the prime p. If the parameters p1 or p2 are not NULL they
+ * will be returned too: this is needed for testing.
+ */
+
+int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+                            const BIGNUM *Xp, const BIGNUM *Xp1,
+                            const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx,
+                            BN_GENCB *cb)
+{
+    int ret = 0;
+
+    BIGNUM *t, *p1p2, *pm1;
+
+    /* Only even e supported */
+    if (!BN_is_odd(e))
+        return 0;
+
+    BN_CTX_start(ctx);
+    if (!p1)
+        p1 = BN_CTX_get(ctx);
+
+    if (!p2)
+        p2 = BN_CTX_get(ctx);
+
+    t = BN_CTX_get(ctx);
+
+    p1p2 = BN_CTX_get(ctx);
+
+    pm1 = BN_CTX_get(ctx);
+
+    if (pm1 == NULL)
+        goto err;
+
+    if (!bn_x931_derive_pi(p1, Xp1, ctx, cb))
+        goto err;
+
+    if (!bn_x931_derive_pi(p2, Xp2, ctx, cb))
+        goto err;
+
+    if (!BN_mul(p1p2, p1, p2, ctx))
+        goto err;
+
+    /* First set p to value of Rp */
+
+    if (!BN_mod_inverse(p, p2, p1, ctx))
+        goto err;
+
+    if (!BN_mul(p, p, p2, ctx))
+        goto err;
+
+    if (!BN_mod_inverse(t, p1, p2, ctx))
+        goto err;
+
+    if (!BN_mul(t, t, p1, ctx))
+        goto err;
+
+    if (!BN_sub(p, p, t))
+        goto err;
+
+    if (p->neg && !BN_add(p, p, p1p2))
+        goto err;
+
+    /* p now equals Rp */
+
+    if (!BN_mod_sub(p, p, Xp, p1p2, ctx))
+        goto err;
+
+    if (!BN_add(p, p, Xp))
+        goto err;
+
+    /* p now equals Yp0 */
+
+    for (;;) {
+        int i = 1;
+        BN_GENCB_call(cb, 0, i++);
+        if (!BN_copy(pm1, p))
+            goto err;
+        if (!BN_sub_word(pm1, 1))
+            goto err;
+        if (!BN_gcd(t, pm1, e, ctx))
+            goto err;
+        if (BN_is_one(t)) {
+            /*
+             * X9.31 specifies 8 MR and 1 Lucas test or any prime test
+             * offering similar or better guarantees 50 MR is considerably
+             * better.
+             */
+            int r = BN_is_prime_fasttest_ex(p, 50, ctx, 1, cb);
+            if (r < 0)
+                goto err;
+            if (r)
+                break;
+        }
+        if (!BN_add(p, p, p1p2))
+            goto err;
+    }
+
+    BN_GENCB_call(cb, 3, 0);
+
+    ret = 1;
+
+ err:
+
+    BN_CTX_end(ctx);
+
+    return ret;
+}
+
+/*
+ * Generate pair of parameters Xp, Xq for X9.31 prime generation. Note: nbits
+ * parameter is sum of number of bits in both.
+ */
+
+int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx)
+{
+    BIGNUM *t;
+    int i;
+    /*
+     * Number of bits for each prime is of the form 512+128s for s = 0, 1,
+     * ...
+     */
+    if ((nbits < 1024) || (nbits & 0xff))
+        return 0;
+    nbits >>= 1;
+    /*
+     * The random value Xp must be between sqrt(2) * 2^(nbits-1) and 2^nbits
+     * - 1. By setting the top two bits we ensure that the lower bound is
+     * exceeded.
+     */
+    if (!BN_rand(Xp, nbits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY))
+        goto err;
+
+    BN_CTX_start(ctx);
+    t = BN_CTX_get(ctx);
+
+    for (i = 0; i < 1000; i++) {
+        if (!BN_rand(Xq, nbits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ANY))
+            goto err;
+        /* Check that |Xp - Xq| > 2^(nbits - 100) */
+        BN_sub(t, Xp, Xq);
+        if (BN_num_bits(t) > (nbits - 100))
+            break;
+    }
+
+    BN_CTX_end(ctx);
+
+    if (i < 1000)
+        return 1;
+
+    return 0;
+
+ err:
+    BN_CTX_end(ctx);
+    return 0;
+}
+
+/*
+ * Generate primes using X9.31 algorithm. Of the values p, p1, p2, Xp1 and
+ * Xp2 only 'p' needs to be non-NULL. If any of the others are not NULL the
+ * relevant parameter will be stored in it. Due to the fact that |Xp - Xq| >
+ * 2^(nbits - 100) must be satisfied Xp and Xq are generated using the
+ * previous function and supplied as input.
+ */
+
+int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+                              BIGNUM *Xp1, BIGNUM *Xp2,
+                              const BIGNUM *Xp,
+                              const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb)
+{
+    int ret = 0;
+
+    BN_CTX_start(ctx);
+    if (!Xp1)
+        Xp1 = BN_CTX_get(ctx);
+    if (!Xp2)
+        Xp2 = BN_CTX_get(ctx);
+
+    if (!BN_rand(Xp1, 101, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
+        goto error;
+    if (!BN_rand(Xp2, 101, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
+        goto error;
+    if (!BN_X931_derive_prime_ex(p, p1, p2, Xp, Xp1, Xp2, e, ctx, cb))
+        goto error;
+
+    ret = 1;
+
+ error:
+    BN_CTX_end(ctx);
+
+    return ret;
+
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/rsaz_exp.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/rsaz_exp.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/bn/rsaz_exp.h	(revision 331)
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2013-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
+ */
+
+/*****************************************************************************
+*                                                                            *
+*  Copyright (c) 2012, Intel Corporation                                     *
+*                                                                            *
+*  All rights reserved.                                                      *
+*                                                                            *
+*  Redistribution and use in source and binary forms, with or without        *
+*  modification, are permitted provided that the following conditions are    *
+*  met:                                                                      *
+*                                                                            *
+*  *  Redistributions of source code must retain the above copyright         *
+*     notice, this list of conditions and the following disclaimer.          *
+*                                                                            *
+*  *  Redistributions in binary form must reproduce the above copyright      *
+*     notice, this list of conditions and the following disclaimer in the    *
+*     documentation and/or other materials provided with the                 *
+*     distribution.                                                          *
+*                                                                            *
+*  *  Neither the name of the Intel Corporation nor the names of its         *
+*     contributors may be used to endorse or promote products derived from   *
+*     this software without specific prior written permission.               *
+*                                                                            *
+*                                                                            *
+*  THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY          *
+*  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE         *
+*  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR        *
+*  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR            *
+*  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     *
+*  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
+*  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
+*  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
+*  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
+*  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
+*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
+*                                                                            *
+******************************************************************************
+* Developers and authors:                                                    *
+* Shay Gueron (1, 2), and Vlad Krasnov (1)                                   *
+* (1) Intel Corporation, Israel Development Center, Haifa, Israel            *
+* (2) University of Haifa, Israel                                            *
+*****************************************************************************/
+
+#ifndef RSAZ_EXP_H
+# define RSAZ_EXP_H
+
+# undef RSAZ_ENABLED
+# if defined(OPENSSL_BN_ASM_MONT) && \
+        (defined(__x86_64) || defined(__x86_64__) || \
+         defined(_M_AMD64) || defined(_M_X64))
+#  define RSAZ_ENABLED
+
+#  include <openssl/bn.h>
+
+void RSAZ_1024_mod_exp_avx2(BN_ULONG result[16],
+                            const BN_ULONG base_norm[16],
+                            const BN_ULONG exponent[16],
+                            const BN_ULONG m_norm[16], const BN_ULONG RR[16],
+                            BN_ULONG k0);
+int rsaz_avx2_eligible();
+
+void RSAZ_512_mod_exp(BN_ULONG result[8],
+                      const BN_ULONG base_norm[8], const BN_ULONG exponent[8],
+                      const BN_ULONG m_norm[8], BN_ULONG k0,
+                      const BN_ULONG RR[8]);
+
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/buffer/buf_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/buffer/buf_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/buffer/buf_err.c	(revision 331)
@@ -0,0 +1,44 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/buffer.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_BUF,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_BUF,0,reason)
+
+static ERR_STRING_DATA BUF_str_functs[] = {
+    {ERR_FUNC(BUF_F_BUF_MEM_GROW), "BUF_MEM_grow"},
+    {ERR_FUNC(BUF_F_BUF_MEM_GROW_CLEAN), "BUF_MEM_grow_clean"},
+    {ERR_FUNC(BUF_F_BUF_MEM_NEW), "BUF_MEM_new"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA BUF_str_reasons[] = {
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_BUF_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(BUF_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, BUF_str_functs);
+        ERR_load_strings(0, BUF_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/buffer/buffer.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/buffer/buffer.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/buffer/buffer.c	(revision 331)
@@ -0,0 +1,164 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+
+/*
+ * LIMIT_BEFORE_EXPANSION is the maximum n such that (n+3)/3*4 < 2**31. That
+ * function is applied in several functions in this file and this limit
+ * ensures that the result fits in an int.
+ */
+#define LIMIT_BEFORE_EXPANSION 0x5ffffffc
+
+BUF_MEM *BUF_MEM_new_ex(unsigned long flags)
+{
+    BUF_MEM *ret;
+
+    ret = BUF_MEM_new();
+    if (ret != NULL)
+        ret->flags = flags;
+    return (ret);
+}
+
+BUF_MEM *BUF_MEM_new(void)
+{
+    BUF_MEM *ret;
+
+    ret = OPENSSL_zalloc(sizeof(*ret));
+    if (ret == NULL) {
+        BUFerr(BUF_F_BUF_MEM_NEW, ERR_R_MALLOC_FAILURE);
+        return (NULL);
+    }
+    return (ret);
+}
+
+void BUF_MEM_free(BUF_MEM *a)
+{
+    if (a == NULL)
+        return;
+
+    if (a->data != NULL) {
+        if (a->flags & BUF_MEM_FLAG_SECURE)
+            OPENSSL_secure_free(a->data);
+        else
+            OPENSSL_clear_free(a->data, a->max);
+    }
+    OPENSSL_free(a);
+}
+
+/* Allocate a block of secure memory; copy over old data if there
+ * was any, and then free it. */
+static char *sec_alloc_realloc(BUF_MEM *str, size_t len)
+{
+    char *ret;
+
+    ret = OPENSSL_secure_malloc(len);
+    if (str->data != NULL) {
+        if (ret != NULL)
+            memcpy(ret, str->data, str->length);
+        OPENSSL_secure_free(str->data);
+    }
+    return (ret);
+}
+
+size_t BUF_MEM_grow(BUF_MEM *str, size_t len)
+{
+    char *ret;
+    size_t n;
+
+    if (str->length >= len) {
+        str->length = len;
+        return (len);
+    }
+    if (str->max >= len) {
+        if (str->data != NULL)
+            memset(&str->data[str->length], 0, len - str->length);
+        str->length = len;
+        return (len);
+    }
+    /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
+    if (len > LIMIT_BEFORE_EXPANSION) {
+        BUFerr(BUF_F_BUF_MEM_GROW, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    n = (len + 3) / 3 * 4;
+    if ((str->flags & BUF_MEM_FLAG_SECURE))
+        ret = sec_alloc_realloc(str, n);
+    else
+        ret = OPENSSL_realloc(str->data, n);
+    if (ret == NULL) {
+        BUFerr(BUF_F_BUF_MEM_GROW, ERR_R_MALLOC_FAILURE);
+        len = 0;
+    } else {
+        str->data = ret;
+        str->max = n;
+        memset(&str->data[str->length], 0, len - str->length);
+        str->length = len;
+    }
+    return (len);
+}
+
+size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len)
+{
+    char *ret;
+    size_t n;
+
+    if (str->length >= len) {
+        if (str->data != NULL)
+            memset(&str->data[len], 0, str->length - len);
+        str->length = len;
+        return (len);
+    }
+    if (str->max >= len) {
+        memset(&str->data[str->length], 0, len - str->length);
+        str->length = len;
+        return (len);
+    }
+    /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
+    if (len > LIMIT_BEFORE_EXPANSION) {
+        BUFerr(BUF_F_BUF_MEM_GROW_CLEAN, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    n = (len + 3) / 3 * 4;
+    if ((str->flags & BUF_MEM_FLAG_SECURE))
+        ret = sec_alloc_realloc(str, n);
+    else
+        ret = OPENSSL_clear_realloc(str->data, str->max, n);
+    if (ret == NULL) {
+        BUFerr(BUF_F_BUF_MEM_GROW_CLEAN, ERR_R_MALLOC_FAILURE);
+        len = 0;
+    } else {
+        str->data = ret;
+        str->max = n;
+        memset(&str->data[str->length], 0, len - str->length);
+        str->length = len;
+    }
+    return (len);
+}
+
+void BUF_reverse(unsigned char *out, const unsigned char *in, size_t size)
+{
+    size_t i;
+    if (in) {
+        out += size - 1;
+        for (i = 0; i < size; i++)
+            *out-- = *in++;
+    } else {
+        unsigned char *q;
+        char c;
+        q = out + size - 1;
+        for (i = 0; i < size / 2; i++) {
+            c = *q;
+            *q-- = *out;
+            *out++ = c;
+        }
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/buildinf.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/buildinf.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/buildinf.h	(revision 331)
@@ -0,0 +1,36 @@
+/* auto-generated by util/mkbuildinf.pl for crypto/cversion.c */
+#define CFLAGS cflags
+/*
+ * Generate CFLAGS as an array of individual characters. This is a
+ * workaround for the situation where CFLAGS gets too long for a C90 string
+ * literal
+ */
+static const char cflags[] = {
+    'c','o','m','p','i','l','e','r',':',' ','a','r','m','-','n','o',
+    'n','e','-','e','a','b','i','-','g','c','c',' ','-','D','Z','L',
+    'I','B',' ','-','D','N','D','E','B','U','G',' ','-','D','O','P',
+    'E','N','S','S','L','_','N','O','_','D','Y','N','A','M','I','C',
+    '_','E','N','G','I','N','E',' ','-','D','S','S','I','Z','E','_',
+    'M','A','X','=','L','O','N','G','_','M','A','X',' ','-','D','_',
+    '_','u','n','i','x',' ','-','D','O','P','E','N','S','S','L','D',
+    'I','R','=','"','\\','"','/','u','s','r','/','l','o','c','a','l',
+    '/','s','s','l','\\','"','"',' ','-','D','E','N','G','I','N','E',
+    'S','D','I','R','=','"','\\','"','/','u','s','r','/','l','o','c',
+    'a','l','/','l','i','b','/','e','n','g','i','n','e','s','-','1',
+    '.','1','\\','"','"',' ',' ','-','n','o','s','t','d','i','n','c',
+    ' ','-','I','.','.','/','m','u','s','l','-','1','.','1','.','1',
+    '8','/','i','n','c','l','u','d','e',' ','-','I','.','.','/','z',
+    'l','i','b','-','1','.','2','.','1','1',' ','-','m','l','i','t',
+    't','l','e','-','e','n','d','i','a','n',' ','-','m','c','p','u',
+    '=','c','o','r','t','e','x','-','a','9',' ','-','m','t','h','u',
+    'm','b',' ','-','m','t','h','u','m','b','-','i','n','t','e','r',
+    'w','o','r','k',' ','-','m','a','r','m',' ','-','m','a','r','c',
+    'h','=','a','r','m','v','7','-','a',' ','-','m','f','p','u','=',
+    'v','f','p','v','3',' ','-','m','f','l','o','a','t','-','a','b',
+    'i','=','h','a','r','d',' ','-','m','n','o','-','u','n','a','l',
+    'i','g','n','e','d','-','a','c','c','e','s','s',' ','-','f','n',
+    'o','-','s','t','r','i','c','t','-','a','l','i','a','s','i','n',
+    'g','\0'
+};
+#define PLATFORM "platform: linux-armv4"
+#define DATE "built on: Sat Dec 30 22:26:17 2017"
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/camellia.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/camellia.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/camellia.c	(revision 331)
@@ -0,0 +1,541 @@
+/*
+ * Copyright 2006-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
+ */
+
+/* ====================================================================
+ * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) .
+ * ALL RIGHTS RESERVED.
+ *
+ * Intellectual Property information for Camellia:
+ *     http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html
+ *
+ * News Release for Announcement of Camellia open source:
+ *     http://www.ntt.co.jp/news/news06e/0604/060413a.html
+ *
+ * The Camellia Code included herein is developed by
+ * NTT (Nippon Telegraph and Telephone Corporation), and is contributed
+ * to the OpenSSL project.
+ */
+
+/*
+ * Algorithm Specification
+ * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
+ */
+
+/*
+ * This release balances code size and performance. In particular key
+ * schedule setup is fully unrolled, because doing so *significantly*
+ * reduces amount of instructions per setup round and code increase is
+ * justifiable. In block functions on the other hand only inner loops
+ * are unrolled, as full unroll gives only nominal performance boost,
+ * while code size grows 4 or 7 times. Also, unlike previous versions
+ * this one "encourages" compiler to keep intermediate variables in
+ * registers, which should give better "all round" results, in other
+ * words reasonable performance even with not so modern compilers.
+ */
+
+#include <openssl/camellia.h>
+#include "cmll_locl.h"
+#include <string.h>
+#include <stdlib.h>
+
+/* 32-bit rotations */
+#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+# if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
+#  define RightRotate(x, s) _lrotr(x, s)
+#  define LeftRotate(x, s)  _lrotl(x, s)
+#  if _MSC_VER >= 1400
+#   define SWAP(x) _byteswap_ulong(x)
+#  else
+#   define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+#  endif
+#  define GETU32(p)   SWAP(*((u32 *)(p)))
+#  define PUTU32(p,v) (*((u32 *)(p)) = SWAP((v)))
+# elif defined(__GNUC__) && __GNUC__>=2
+#  if defined(__i386) || defined(__x86_64)
+#   define RightRotate(x,s) ({u32 ret; asm ("rorl %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; })
+#   define LeftRotate(x,s)  ({u32 ret; asm ("roll %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; })
+#   if defined(B_ENDIAN)        /* stratus.com does it */
+#    define GETU32(p)   (*(u32 *)(p))
+#    define PUTU32(p,v) (*(u32 *)(p)=(v))
+#   else
+#    define GETU32(p)   ({u32 r=*(const u32 *)(p); asm("bswapl %0":"=r"(r):"0"(r)); r; })
+#    define PUTU32(p,v) ({u32 r=(v); asm("bswapl %0":"=r"(r):"0"(r)); *(u32 *)(p)=r; })
+#   endif
+#  elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
+        defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__)
+#   define LeftRotate(x,s)  ({u32 ret; asm ("rlwinm %0,%1,%2,0,31":"=r"(ret):"r"(x),"I"(s)); ret; })
+#   define RightRotate(x,s) LeftRotate(x,(32-s))
+#  elif defined(__s390x__)
+#   define LeftRotate(x,s)  ({u32 ret; asm ("rll %0,%1,%2":"=r"(ret):"r"(x),"I"(s)); ret; })
+#   define RightRotate(x,s) LeftRotate(x,(32-s))
+#   define GETU32(p)   (*(u32 *)(p))
+#   define PUTU32(p,v) (*(u32 *)(p)=(v))
+#  endif
+# endif
+#endif
+
+#if !defined(RightRotate) && !defined(LeftRotate)
+# define RightRotate(x, s) ( ((x) >> (s)) + ((x) << (32 - s)) )
+# define LeftRotate(x, s)  ( ((x) << (s)) + ((x) >> (32 - s)) )
+#endif
+
+#if !defined(GETU32) && !defined(PUTU32)
+# define GETU32(p)   (((u32)(p)[0] << 24) ^ ((u32)(p)[1] << 16) ^ ((u32)(p)[2] <<  8) ^ ((u32)(p)[3]))
+# define PUTU32(p,v) ((p)[0] = (u8)((v) >> 24), (p)[1] = (u8)((v) >> 16), (p)[2] = (u8)((v) >>  8), (p)[3] = (u8)(v))
+#endif
+
+/* S-box data */
+#define SBOX1_1110 Camellia_SBOX[0]
+#define SBOX4_4404 Camellia_SBOX[1]
+#define SBOX2_0222 Camellia_SBOX[2]
+#define SBOX3_3033 Camellia_SBOX[3]
+static const u32 Camellia_SBOX[][256] = {
+    {0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700,
+     0xc0c0c000, 0xe5e5e500, 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500,
+     0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, 0x23232300, 0xefefef00,
+     0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100,
+     0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500,
+     0x92929200, 0xbdbdbd00, 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00,
+     0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, 0x3e3e3e00, 0x30303000,
+     0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00,
+     0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700,
+     0x5d5d5d00, 0x3d3d3d00, 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600,
+     0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, 0x8b8b8b00, 0x0d0d0d00,
+     0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00,
+     0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100,
+     0x84848400, 0x99999900, 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200,
+     0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, 0x6d6d6d00, 0xb7b7b700,
+     0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700,
+     0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00,
+     0x11111100, 0x1c1c1c00, 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600,
+     0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, 0xfefefe00, 0x44444400,
+     0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100,
+     0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00,
+     0x69696900, 0x50505000, 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00,
+     0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, 0x54545400, 0x5b5b5b00,
+     0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200,
+     0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700,
+     0x75757500, 0xdbdbdb00, 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00,
+     0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, 0x87878700, 0x5c5c5c00,
+     0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300,
+     0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00,
+     0xbfbfbf00, 0xe2e2e200, 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600,
+     0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, 0x81818100, 0x96969600,
+     0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00,
+     0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00,
+     0xbcbcbc00, 0x8e8e8e00, 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600,
+     0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, 0x78787800, 0x98989800,
+     0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00,
+     0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200,
+     0x8d8d8d00, 0xfafafa00, 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500,
+     0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, 0x36363600, 0x49494900,
+     0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400,
+     0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900,
+     0x43434300, 0xc1c1c100, 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400,
+     0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00},
+    {0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057,
+     0xeaea00ea, 0xaeae00ae, 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5,
+     0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, 0x86860086, 0xafaf00af,
+     0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b,
+     0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a,
+     0x51510051, 0x6c6c006c, 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0,
+     0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, 0xdfdf00df, 0xcbcb00cb,
+     0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004,
+     0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c,
+     0x53530053, 0xf2f200f2, 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a,
+     0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, 0xaaaa00aa, 0xa0a000a0,
+     0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064,
+     0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6,
+     0x09090009, 0xdddd00dd, 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090,
+     0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, 0x52520052, 0xd8d800d8,
+     0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063,
+     0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9,
+     0x2f2f002f, 0xb4b400b4, 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071,
+     0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, 0x72720072, 0xb9b900b9,
+     0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1,
+     0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad,
+     0x77770077, 0x80800080, 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5,
+     0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, 0xefef00ef, 0x93930093,
+     0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd,
+     0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f,
+     0xc5c500c5, 0x1a1a001a, 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d,
+     0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, 0x0d0d000d, 0x66660066,
+     0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099,
+     0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031,
+     0x17170017, 0xd7d700d7, 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c,
+     0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, 0x44440044, 0xb2b200b2,
+     0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050,
+     0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095,
+     0xffff00ff, 0xd2d200d2, 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db,
+     0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, 0x5c5c005c, 0x02020002,
+     0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2,
+     0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b,
+     0xbebe00be, 0x2e2e002e, 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e,
+     0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, 0x98980098, 0x6a6a006a,
+     0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa,
+     0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068,
+     0x38380038, 0xa4a400a4, 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1,
+     0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e},
+    {0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e,
+     0x00818181, 0x00cbcbcb, 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a,
+     0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, 0x00464646, 0x00dfdfdf,
+     0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242,
+     0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca,
+     0x00252525, 0x007b7b7b, 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f,
+     0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, 0x007c7c7c, 0x00606060,
+     0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434,
+     0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e,
+     0x00bababa, 0x007a7a7a, 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad,
+     0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, 0x00171717, 0x001a1a1a,
+     0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a,
+     0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363,
+     0x00090909, 0x00333333, 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585,
+     0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, 0x00dadada, 0x006f6f6f,
+     0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf,
+     0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636,
+     0x00222222, 0x00383838, 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c,
+     0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, 0x00fdfdfd, 0x00888888,
+     0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323,
+     0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9,
+     0x00d2d2d2, 0x00a0a0a0, 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa,
+     0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, 0x00a8a8a8, 0x00b6b6b6,
+     0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5,
+     0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef,
+     0x00eaeaea, 0x00b7b7b7, 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5,
+     0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, 0x000f0f0f, 0x00b8b8b8,
+     0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666,
+     0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe,
+     0x007f7f7f, 0x00c5c5c5, 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c,
+     0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, 0x00030303, 0x002d2d2d,
+     0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c,
+     0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc,
+     0x00797979, 0x001d1d1d, 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d,
+     0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, 0x00f0f0f0, 0x00313131,
+     0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575,
+     0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545,
+     0x001b1b1b, 0x00f5f5f5, 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa,
+     0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, 0x006c6c6c, 0x00929292,
+     0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949,
+     0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393,
+     0x00868686, 0x00838383, 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9,
+     0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d},
+    {0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393,
+     0x60006060, 0xf200f2f2, 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a,
+     0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, 0x91009191, 0xf700f7f7,
+     0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090,
+     0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2,
+     0x49004949, 0xde00dede, 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7,
+     0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, 0x1f001f1f, 0x18001818,
+     0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d,
+     0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3,
+     0xae00aeae, 0x9e009e9e, 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b,
+     0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, 0xc500c5c5, 0x86008686,
+     0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696,
+     0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8,
+     0x42004242, 0xcc00cccc, 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161,
+     0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, 0xb600b6b6, 0xdb00dbdb,
+     0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb,
+     0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d,
+     0x88008888, 0x0e000e0e, 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b,
+     0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, 0x7f007f7f, 0x22002222,
+     0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8,
+     0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e,
+     0xb400b4b4, 0x28002828, 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe,
+     0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, 0x2a002a2a, 0xad00adad,
+     0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969,
+     0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb,
+     0xba00baba, 0xed00eded, 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d,
+     0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, 0xc300c3c3, 0x2e002e2e,
+     0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999,
+     0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf,
+     0xdf00dfdf, 0x71007171, 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313,
+     0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, 0xc000c0c0, 0x4b004b4b,
+     0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717,
+     0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737,
+     0x5e005e5e, 0x47004747, 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b,
+     0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, 0x3c003c3c, 0x4c004c4c,
+     0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d,
+     0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151,
+     0xc600c6c6, 0x7d007d7d, 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa,
+     0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, 0x1b001b1b, 0xa400a4a4,
+     0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252,
+     0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4,
+     0xa100a1a1, 0xe000e0e0, 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a,
+     0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f}
+};
+
+/* Key generation constants */
+static const u32 SIGMA[] = {
+    0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2, 0xc6ef372f, 0xe94f82be,
+    0x54ff53a5, 0xf1d36f1c, 0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd
+};
+
+/* The phi algorithm given in C.2.7 of the Camellia spec document. */
+/*
+ * This version does not attempt to minimize amount of temporary
+ * variables, but instead explicitly exposes algorithm's parallelism.
+ * It is therefore most appropriate for platforms with not less than
+ * ~16 registers. For platforms with less registers [well, x86 to be
+ * specific] assembler version should be/is provided anyway...
+ */
+#define Camellia_Feistel(_s0,_s1,_s2,_s3,_key) do {\
+        register u32 _t0,_t1,_t2,_t3;\
+\
+        _t0  = _s0 ^ (_key)[0];\
+        _t3  = SBOX4_4404[_t0&0xff];\
+        _t1  = _s1 ^ (_key)[1];\
+        _t3 ^= SBOX3_3033[(_t0 >> 8)&0xff];\
+        _t2  = SBOX1_1110[_t1&0xff];\
+        _t3 ^= SBOX2_0222[(_t0 >> 16)&0xff];\
+        _t2 ^= SBOX4_4404[(_t1 >> 8)&0xff];\
+        _t3 ^= SBOX1_1110[(_t0 >> 24)];\
+        _t2 ^= _t3;\
+        _t3  = RightRotate(_t3,8);\
+        _t2 ^= SBOX3_3033[(_t1 >> 16)&0xff];\
+        _s3 ^= _t3;\
+        _t2 ^= SBOX2_0222[(_t1 >> 24)];\
+        _s2 ^= _t2; \
+        _s3 ^= _t2;\
+} while(0)
+
+/*
+ * Note that n has to be less than 32. Rotations for larger amount
+ * of bits are achieved by "rotating" order of s-elements and
+ * adjusting n accordingly, e.g. RotLeft128(s1,s2,s3,s0,n-32).
+ */
+#define RotLeft128(_s0,_s1,_s2,_s3,_n) do {\
+        u32 _t0=_s0>>(32-_n);\
+        _s0 = (_s0<<_n) | (_s1>>(32-_n));\
+        _s1 = (_s1<<_n) | (_s2>>(32-_n));\
+        _s2 = (_s2<<_n) | (_s3>>(32-_n));\
+        _s3 = (_s3<<_n) | _t0;\
+} while (0)
+
+int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, KEY_TABLE_TYPE k)
+{
+    register u32 s0, s1, s2, s3;
+
+    k[0] = s0 = GETU32(rawKey);
+    k[1] = s1 = GETU32(rawKey + 4);
+    k[2] = s2 = GETU32(rawKey + 8);
+    k[3] = s3 = GETU32(rawKey + 12);
+
+    if (keyBitLength != 128) {
+        k[8] = s0 = GETU32(rawKey + 16);
+        k[9] = s1 = GETU32(rawKey + 20);
+        if (keyBitLength == 192) {
+            k[10] = s2 = ~s0;
+            k[11] = s3 = ~s1;
+        } else {
+            k[10] = s2 = GETU32(rawKey + 24);
+            k[11] = s3 = GETU32(rawKey + 28);
+        }
+        s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3];
+    }
+
+    /* Use the Feistel routine to scramble the key material */
+    Camellia_Feistel(s0, s1, s2, s3, SIGMA + 0);
+    Camellia_Feistel(s2, s3, s0, s1, SIGMA + 2);
+
+    s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3];
+    Camellia_Feistel(s0, s1, s2, s3, SIGMA + 4);
+    Camellia_Feistel(s2, s3, s0, s1, SIGMA + 6);
+
+    /* Fill the keyTable. Requires many block rotations. */
+    if (keyBitLength == 128) {
+        k[4] = s0, k[5] = s1, k[6] = s2, k[7] = s3;
+        RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 15 */
+        k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
+        RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 30 */
+        k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3;
+        RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 45 */
+        k[24] = s0, k[25] = s1;
+        RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 60 */
+        k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3;
+        RotLeft128(s1, s2, s3, s0, 2); /* KA <<< 94 */
+        k[40] = s1, k[41] = s2, k[42] = s3, k[43] = s0;
+        RotLeft128(s1, s2, s3, s0, 17); /* KA <<<111 */
+        k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0;
+
+        s0 = k[0], s1 = k[1], s2 = k[2], s3 = k[3];
+        RotLeft128(s0, s1, s2, s3, 15); /* KL <<< 15 */
+        k[8] = s0, k[9] = s1, k[10] = s2, k[11] = s3;
+        RotLeft128(s0, s1, s2, s3, 30); /* KL <<< 45 */
+        k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3;
+        RotLeft128(s0, s1, s2, s3, 15); /* KL <<< 60 */
+        k[26] = s2, k[27] = s3;
+        RotLeft128(s0, s1, s2, s3, 17); /* KL <<< 77 */
+        k[32] = s0, k[33] = s1, k[34] = s2, k[35] = s3;
+        RotLeft128(s0, s1, s2, s3, 17); /* KL <<< 94 */
+        k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3;
+        RotLeft128(s0, s1, s2, s3, 17); /* KL <<<111 */
+        k[44] = s0, k[45] = s1, k[46] = s2, k[47] = s3;
+
+        return 3;               /* grand rounds */
+    } else {
+        k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
+        s0 ^= k[8], s1 ^= k[9], s2 ^= k[10], s3 ^= k[11];
+        Camellia_Feistel(s0, s1, s2, s3, (SIGMA + 8));
+        Camellia_Feistel(s2, s3, s0, s1, (SIGMA + 10));
+
+        k[4] = s0, k[5] = s1, k[6] = s2, k[7] = s3;
+        RotLeft128(s0, s1, s2, s3, 30); /* KB <<< 30 */
+        k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3;
+        RotLeft128(s0, s1, s2, s3, 30); /* KB <<< 60 */
+        k[40] = s0, k[41] = s1, k[42] = s2, k[43] = s3;
+        RotLeft128(s1, s2, s3, s0, 19); /* KB <<<111 */
+        k[64] = s1, k[65] = s2, k[66] = s3, k[67] = s0;
+
+        s0 = k[8], s1 = k[9], s2 = k[10], s3 = k[11];
+        RotLeft128(s0, s1, s2, s3, 15); /* KR <<< 15 */
+        k[8] = s0, k[9] = s1, k[10] = s2, k[11] = s3;
+        RotLeft128(s0, s1, s2, s3, 15); /* KR <<< 30 */
+        k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3;
+        RotLeft128(s0, s1, s2, s3, 30); /* KR <<< 60 */
+        k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3;
+        RotLeft128(s1, s2, s3, s0, 2); /* KR <<< 94 */
+        k[52] = s1, k[53] = s2, k[54] = s3, k[55] = s0;
+
+        s0 = k[12], s1 = k[13], s2 = k[14], s3 = k[15];
+        RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 15 */
+        k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3;
+        RotLeft128(s0, s1, s2, s3, 30); /* KA <<< 45 */
+        k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3;
+        /* KA <<< 77 */
+        k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0;
+        RotLeft128(s1, s2, s3, s0, 17); /* KA <<< 94 */
+        k[56] = s1, k[57] = s2, k[58] = s3, k[59] = s0;
+
+        s0 = k[0], s1 = k[1], s2 = k[2], s3 = k[3];
+        RotLeft128(s1, s2, s3, s0, 13); /* KL <<< 45 */
+        k[24] = s1, k[25] = s2, k[26] = s3, k[27] = s0;
+        RotLeft128(s1, s2, s3, s0, 15); /* KL <<< 60 */
+        k[32] = s1, k[33] = s2, k[34] = s3, k[35] = s0;
+        RotLeft128(s1, s2, s3, s0, 17); /* KL <<< 77 */
+        k[44] = s1, k[45] = s2, k[46] = s3, k[47] = s0;
+        RotLeft128(s2, s3, s0, s1, 2); /* KL <<<111 */
+        k[60] = s2, k[61] = s3, k[62] = s0, k[63] = s1;
+
+        return 4;               /* grand rounds */
+    }
+    /*
+     * It is possible to perform certain precalculations, which
+     * would spare few cycles in block procedure. It's not done,
+     * because it upsets the performance balance between key
+     * setup and block procedures, negatively affecting overall
+     * throughput in applications operating on short messages
+     * and volatile keys.
+     */
+}
+
+void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[],
+                                  const KEY_TABLE_TYPE keyTable,
+                                  u8 ciphertext[])
+{
+    register u32 s0, s1, s2, s3;
+    const u32 *k = keyTable, *kend = keyTable + grandRounds * 16;
+
+    s0 = GETU32(plaintext) ^ k[0];
+    s1 = GETU32(plaintext + 4) ^ k[1];
+    s2 = GETU32(plaintext + 8) ^ k[2];
+    s3 = GETU32(plaintext + 12) ^ k[3];
+    k += 4;
+
+    while (1) {
+        /* Camellia makes 6 Feistel rounds */
+        Camellia_Feistel(s0, s1, s2, s3, k + 0);
+        Camellia_Feistel(s2, s3, s0, s1, k + 2);
+        Camellia_Feistel(s0, s1, s2, s3, k + 4);
+        Camellia_Feistel(s2, s3, s0, s1, k + 6);
+        Camellia_Feistel(s0, s1, s2, s3, k + 8);
+        Camellia_Feistel(s2, s3, s0, s1, k + 10);
+        k += 12;
+
+        if (k == kend)
+            break;
+
+        /*
+         * This is the same function as the diffusion function D of the
+         * accompanying documentation. See section 3.2 for properties of the
+         * FLlayer function.
+         */
+        s1 ^= LeftRotate(s0 & k[0], 1);
+        s2 ^= s3 | k[3];
+        s0 ^= s1 | k[1];
+        s3 ^= LeftRotate(s2 & k[2], 1);
+        k += 4;
+    }
+
+    s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3];
+
+    PUTU32(ciphertext, s2);
+    PUTU32(ciphertext + 4, s3);
+    PUTU32(ciphertext + 8, s0);
+    PUTU32(ciphertext + 12, s1);
+}
+
+void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[],
+                           const KEY_TABLE_TYPE keyTable, u8 ciphertext[])
+{
+    Camellia_EncryptBlock_Rounds(keyBitLength == 128 ? 3 : 4,
+                                 plaintext, keyTable, ciphertext);
+}
+
+void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[],
+                                  const KEY_TABLE_TYPE keyTable,
+                                  u8 plaintext[])
+{
+    u32 s0, s1, s2, s3;
+    const u32 *k = keyTable + grandRounds * 16, *kend = keyTable + 4;
+
+    s0 = GETU32(ciphertext) ^ k[0];
+    s1 = GETU32(ciphertext + 4) ^ k[1];
+    s2 = GETU32(ciphertext + 8) ^ k[2];
+    s3 = GETU32(ciphertext + 12) ^ k[3];
+
+    while (1) {
+        /* Camellia makes 6 Feistel rounds */
+        k -= 12;
+        Camellia_Feistel(s0, s1, s2, s3, k + 10);
+        Camellia_Feistel(s2, s3, s0, s1, k + 8);
+        Camellia_Feistel(s0, s1, s2, s3, k + 6);
+        Camellia_Feistel(s2, s3, s0, s1, k + 4);
+        Camellia_Feistel(s0, s1, s2, s3, k + 2);
+        Camellia_Feistel(s2, s3, s0, s1, k + 0);
+
+        if (k == kend)
+            break;
+
+        /*
+         * This is the same function as the diffusion function D of the
+         * accompanying documentation. See section 3.2 for properties of the
+         * FLlayer function.
+         */
+        k -= 4;
+        s1 ^= LeftRotate(s0 & k[2], 1);
+        s2 ^= s3 | k[1];
+        s0 ^= s1 | k[3];
+        s3 ^= LeftRotate(s2 & k[0], 1);
+    }
+
+    k -= 4;
+    s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3];
+
+    PUTU32(plaintext, s2);
+    PUTU32(plaintext + 4, s3);
+    PUTU32(plaintext + 8, s0);
+    PUTU32(plaintext + 12, s1);
+}
+
+void Camellia_DecryptBlock(int keyBitLength, const u8 plaintext[],
+                           const KEY_TABLE_TYPE keyTable, u8 ciphertext[])
+{
+    Camellia_DecryptBlock_Rounds(keyBitLength == 128 ? 3 : 4,
+                                 plaintext, keyTable, ciphertext);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_cbc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_cbc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_cbc.c	(revision 331)
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2006-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 <openssl/camellia.h>
+#include <openssl/modes.h>
+
+void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                          size_t len, const CAMELLIA_KEY *key,
+                          unsigned char *ivec, const int enc)
+{
+
+    if (enc)
+        CRYPTO_cbc128_encrypt(in, out, len, key, ivec,
+                              (block128_f) Camellia_encrypt);
+    else
+        CRYPTO_cbc128_decrypt(in, out, len, key, ivec,
+                              (block128_f) Camellia_decrypt);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_cfb.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_cfb.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_cfb.c	(revision 331)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2006-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 <openssl/camellia.h>
+#include <openssl/modes.h>
+
+/*
+ * The input and output encrypted as though 128bit cfb mode is being used.
+ * The extra state information to record how much of the 128bit block we have
+ * used is contained in *num;
+ */
+
+void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t length, const CAMELLIA_KEY *key,
+                             unsigned char *ivec, int *num, const int enc)
+{
+
+    CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc,
+                          (block128_f) Camellia_encrypt);
+}
+
+/* N.B. This expects the input to be packed, MS bit first */
+void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t length, const CAMELLIA_KEY *key,
+                           unsigned char *ivec, int *num, const int enc)
+{
+    CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc,
+                            (block128_f) Camellia_encrypt);
+}
+
+void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t length, const CAMELLIA_KEY *key,
+                           unsigned char *ivec, int *num, const int enc)
+{
+    CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc,
+                            (block128_f) Camellia_encrypt);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_ctr.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_ctr.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_ctr.c	(revision 331)
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2006-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 <openssl/camellia.h>
+#include <openssl/modes.h>
+
+void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t length, const CAMELLIA_KEY *key,
+                             unsigned char ivec[CAMELLIA_BLOCK_SIZE],
+                             unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE],
+                             unsigned int *num)
+{
+
+    CRYPTO_ctr128_encrypt(in, out, length, key, ivec, ecount_buf, num,
+                          (block128_f) Camellia_encrypt);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_ecb.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_ecb.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_ecb.c	(revision 331)
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2006-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 <openssl/camellia.h>
+#include "cmll_locl.h"
+
+void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                          const CAMELLIA_KEY *key, const int enc)
+{
+    if (CAMELLIA_ENCRYPT == enc)
+        Camellia_encrypt(in, out, key);
+    else
+        Camellia_decrypt(in, out, key);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_locl.h	(revision 331)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2006-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
+ */
+
+/* ====================================================================
+ * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) .
+ * ALL RIGHTS RESERVED.
+ *
+ * Intellectual Property information for Camellia:
+ *     http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html
+ *
+ * News Release for Announcement of Camellia open source:
+ *     http://www.ntt.co.jp/news/news06e/0604/060413a.html
+ *
+ * The Camellia Code included herein is developed by
+ * NTT (Nippon Telegraph and Telephone Corporation), and is contributed
+ * to the OpenSSL project.
+ */
+
+#ifndef HEADER_CAMELLIA_LOCL_H
+# define HEADER_CAMELLIA_LOCL_H
+
+typedef unsigned int u32;
+typedef unsigned char u8;
+
+int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey,
+                     KEY_TABLE_TYPE keyTable);
+void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[],
+                                  const KEY_TABLE_TYPE keyTable,
+                                  u8 ciphertext[]);
+void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[],
+                                  const KEY_TABLE_TYPE keyTable,
+                                  u8 plaintext[]);
+void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[],
+                           const KEY_TABLE_TYPE keyTable, u8 ciphertext[]);
+void Camellia_DecryptBlock(int keyBitLength, const u8 ciphertext[],
+                           const KEY_TABLE_TYPE keyTable, u8 plaintext[]);
+#endif                          /* #ifndef HEADER_CAMELLIA_LOCL_H */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_misc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_misc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_misc.c	(revision 331)
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2006-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 <openssl/opensslv.h>
+#include <openssl/camellia.h>
+#include "cmll_locl.h"
+
+int Camellia_set_key(const unsigned char *userKey, const int bits,
+                     CAMELLIA_KEY *key)
+{
+    if (!userKey || !key)
+        return -1;
+    if (bits != 128 && bits != 192 && bits != 256)
+        return -2;
+    key->grand_rounds = Camellia_Ekeygen(bits, userKey, key->u.rd_key);
+    return 0;
+}
+
+void Camellia_encrypt(const unsigned char *in, unsigned char *out,
+                      const CAMELLIA_KEY *key)
+{
+    Camellia_EncryptBlock_Rounds(key->grand_rounds, in, key->u.rd_key, out);
+}
+
+void Camellia_decrypt(const unsigned char *in, unsigned char *out,
+                      const CAMELLIA_KEY *key)
+{
+    Camellia_DecryptBlock_Rounds(key->grand_rounds, in, key->u.rd_key, out);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_ofb.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_ofb.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/camellia/cmll_ofb.c	(revision 331)
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2006-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 <openssl/camellia.h>
+#include <openssl/modes.h>
+
+/*
+ * The input and output encrypted as though 128bit ofb mode is being used.
+ * The extra state information to record how much of the 128bit block we have
+ * used is contained in *num;
+ */
+void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t length, const CAMELLIA_KEY *key,
+                             unsigned char *ivec, int *num)
+{
+    CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num,
+                          (block128_f) Camellia_encrypt);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/c_cfb64.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/c_cfb64.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/c_cfb64.c	(revision 331)
@@ -0,0 +1,74 @@
+/*
+ * Copyright 1995-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 <openssl/cast.h>
+#include "cast_lcl.h"
+
+/*
+ * The input and output encrypted as though 64bit cfb mode is being used.
+ * The extra state information to record how much of the 64bit block we have
+ * used is contained in *num;
+ */
+
+void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                        long length, const CAST_KEY *schedule,
+                        unsigned char *ivec, int *num, int enc)
+{
+    register CAST_LONG v0, v1, t;
+    register int n = *num;
+    register long l = length;
+    CAST_LONG ti[2];
+    unsigned char *iv, c, cc;
+
+    iv = ivec;
+    if (enc) {
+        while (l--) {
+            if (n == 0) {
+                n2l(iv, v0);
+                ti[0] = v0;
+                n2l(iv, v1);
+                ti[1] = v1;
+                CAST_encrypt((CAST_LONG *)ti, schedule);
+                iv = ivec;
+                t = ti[0];
+                l2n(t, iv);
+                t = ti[1];
+                l2n(t, iv);
+                iv = ivec;
+            }
+            c = *(in++) ^ iv[n];
+            *(out++) = c;
+            iv[n] = c;
+            n = (n + 1) & 0x07;
+        }
+    } else {
+        while (l--) {
+            if (n == 0) {
+                n2l(iv, v0);
+                ti[0] = v0;
+                n2l(iv, v1);
+                ti[1] = v1;
+                CAST_encrypt((CAST_LONG *)ti, schedule);
+                iv = ivec;
+                t = ti[0];
+                l2n(t, iv);
+                t = ti[1];
+                l2n(t, iv);
+                iv = ivec;
+            }
+            cc = *(in++);
+            c = iv[n];
+            iv[n] = cc;
+            *(out++) = c ^ cc;
+            n = (n + 1) & 0x07;
+        }
+    }
+    v0 = v1 = ti[0] = ti[1] = t = c = cc = 0;
+    *num = n;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/c_ecb.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/c_ecb.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/c_ecb.c	(revision 331)
@@ -0,0 +1,32 @@
+/*
+ * Copyright 1995-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 <openssl/cast.h>
+#include "cast_lcl.h"
+#include <openssl/opensslv.h>
+
+void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                      const CAST_KEY *ks, int enc)
+{
+    CAST_LONG l, d[2];
+
+    n2l(in, l);
+    d[0] = l;
+    n2l(in, l);
+    d[1] = l;
+    if (enc)
+        CAST_encrypt(d, ks);
+    else
+        CAST_decrypt(d, ks);
+    l = d[0];
+    l2n(l, out);
+    l = d[1];
+    l2n(l, out);
+    l = d[0] = d[1] = 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/c_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/c_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/c_enc.c	(revision 331)
@@ -0,0 +1,151 @@
+/*
+ * Copyright 1995-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 <openssl/cast.h>
+#include "cast_lcl.h"
+
+void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key)
+{
+    register CAST_LONG l, r, t;
+    const register CAST_LONG *k;
+
+    k = &(key->data[0]);
+    l = data[0];
+    r = data[1];
+
+    E_CAST(0, k, l, r, +, ^, -);
+    E_CAST(1, k, r, l, ^, -, +);
+    E_CAST(2, k, l, r, -, +, ^);
+    E_CAST(3, k, r, l, +, ^, -);
+    E_CAST(4, k, l, r, ^, -, +);
+    E_CAST(5, k, r, l, -, +, ^);
+    E_CAST(6, k, l, r, +, ^, -);
+    E_CAST(7, k, r, l, ^, -, +);
+    E_CAST(8, k, l, r, -, +, ^);
+    E_CAST(9, k, r, l, +, ^, -);
+    E_CAST(10, k, l, r, ^, -, +);
+    E_CAST(11, k, r, l, -, +, ^);
+    if (!key->short_key) {
+        E_CAST(12, k, l, r, +, ^, -);
+        E_CAST(13, k, r, l, ^, -, +);
+        E_CAST(14, k, l, r, -, +, ^);
+        E_CAST(15, k, r, l, +, ^, -);
+    }
+
+    data[1] = l & 0xffffffffL;
+    data[0] = r & 0xffffffffL;
+}
+
+void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key)
+{
+    register CAST_LONG l, r, t;
+    const register CAST_LONG *k;
+
+    k = &(key->data[0]);
+    l = data[0];
+    r = data[1];
+
+    if (!key->short_key) {
+        E_CAST(15, k, l, r, +, ^, -);
+        E_CAST(14, k, r, l, -, +, ^);
+        E_CAST(13, k, l, r, ^, -, +);
+        E_CAST(12, k, r, l, +, ^, -);
+    }
+    E_CAST(11, k, l, r, -, +, ^);
+    E_CAST(10, k, r, l, ^, -, +);
+    E_CAST(9, k, l, r, +, ^, -);
+    E_CAST(8, k, r, l, -, +, ^);
+    E_CAST(7, k, l, r, ^, -, +);
+    E_CAST(6, k, r, l, +, ^, -);
+    E_CAST(5, k, l, r, -, +, ^);
+    E_CAST(4, k, r, l, ^, -, +);
+    E_CAST(3, k, l, r, +, ^, -);
+    E_CAST(2, k, r, l, -, +, ^);
+    E_CAST(1, k, l, r, ^, -, +);
+    E_CAST(0, k, r, l, +, ^, -);
+
+    data[1] = l & 0xffffffffL;
+    data[0] = r & 0xffffffffL;
+}
+
+void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                      long length, const CAST_KEY *ks, unsigned char *iv,
+                      int enc)
+{
+    register CAST_LONG tin0, tin1;
+    register CAST_LONG tout0, tout1, xor0, xor1;
+    register long l = length;
+    CAST_LONG tin[2];
+
+    if (enc) {
+        n2l(iv, tout0);
+        n2l(iv, tout1);
+        iv -= 8;
+        for (l -= 8; l >= 0; l -= 8) {
+            n2l(in, tin0);
+            n2l(in, tin1);
+            tin0 ^= tout0;
+            tin1 ^= tout1;
+            tin[0] = tin0;
+            tin[1] = tin1;
+            CAST_encrypt(tin, ks);
+            tout0 = tin[0];
+            tout1 = tin[1];
+            l2n(tout0, out);
+            l2n(tout1, out);
+        }
+        if (l != -8) {
+            n2ln(in, tin0, tin1, l + 8);
+            tin0 ^= tout0;
+            tin1 ^= tout1;
+            tin[0] = tin0;
+            tin[1] = tin1;
+            CAST_encrypt(tin, ks);
+            tout0 = tin[0];
+            tout1 = tin[1];
+            l2n(tout0, out);
+            l2n(tout1, out);
+        }
+        l2n(tout0, iv);
+        l2n(tout1, iv);
+    } else {
+        n2l(iv, xor0);
+        n2l(iv, xor1);
+        iv -= 8;
+        for (l -= 8; l >= 0; l -= 8) {
+            n2l(in, tin0);
+            n2l(in, tin1);
+            tin[0] = tin0;
+            tin[1] = tin1;
+            CAST_decrypt(tin, ks);
+            tout0 = tin[0] ^ xor0;
+            tout1 = tin[1] ^ xor1;
+            l2n(tout0, out);
+            l2n(tout1, out);
+            xor0 = tin0;
+            xor1 = tin1;
+        }
+        if (l != -8) {
+            n2l(in, tin0);
+            n2l(in, tin1);
+            tin[0] = tin0;
+            tin[1] = tin1;
+            CAST_decrypt(tin, ks);
+            tout0 = tin[0] ^ xor0;
+            tout1 = tin[1] ^ xor1;
+            l2nn(tout0, tout1, out, l + 8);
+            xor0 = tin0;
+            xor1 = tin1;
+        }
+        l2n(xor0, iv);
+        l2n(xor1, iv);
+    }
+    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
+    tin[0] = tin[1] = 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/c_ofb64.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/c_ofb64.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/c_ofb64.c	(revision 331)
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1995-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 <openssl/cast.h>
+#include "cast_lcl.h"
+
+/*
+ * The input and output encrypted as though 64bit ofb mode is being used.
+ * The extra state information to record how much of the 64bit block we have
+ * used is contained in *num;
+ */
+void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+                        long length, const CAST_KEY *schedule,
+                        unsigned char *ivec, int *num)
+{
+    register CAST_LONG v0, v1, t;
+    register int n = *num;
+    register long l = length;
+    unsigned char d[8];
+    register char *dp;
+    CAST_LONG ti[2];
+    unsigned char *iv;
+    int save = 0;
+
+    iv = ivec;
+    n2l(iv, v0);
+    n2l(iv, v1);
+    ti[0] = v0;
+    ti[1] = v1;
+    dp = (char *)d;
+    l2n(v0, dp);
+    l2n(v1, dp);
+    while (l--) {
+        if (n == 0) {
+            CAST_encrypt((CAST_LONG *)ti, schedule);
+            dp = (char *)d;
+            t = ti[0];
+            l2n(t, dp);
+            t = ti[1];
+            l2n(t, dp);
+            save++;
+        }
+        *(out++) = *(in++) ^ d[n];
+        n = (n + 1) & 0x07;
+    }
+    if (save) {
+        v0 = ti[0];
+        v1 = ti[1];
+        iv = ivec;
+        l2n(v0, iv);
+        l2n(v1, iv);
+    }
+    t = v0 = v1 = ti[0] = ti[1] = 0;
+    *num = n;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/c_skey.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/c_skey.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/c_skey.c	(revision 331)
@@ -0,0 +1,118 @@
+/*
+ * Copyright 1995-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 <openssl/cast.h>
+#include "cast_lcl.h"
+#include "cast_s.h"
+
+#define CAST_exp(l,A,a,n) \
+        A[n/4]=l; \
+        a[n+3]=(l    )&0xff; \
+        a[n+2]=(l>> 8)&0xff; \
+        a[n+1]=(l>>16)&0xff; \
+        a[n+0]=(l>>24)&0xff;
+
+#define S4 CAST_S_table4
+#define S5 CAST_S_table5
+#define S6 CAST_S_table6
+#define S7 CAST_S_table7
+
+void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data)
+{
+    CAST_LONG x[16];
+    CAST_LONG z[16];
+    CAST_LONG k[32];
+    CAST_LONG X[4], Z[4];
+    CAST_LONG l, *K;
+    int i;
+
+    for (i = 0; i < 16; i++)
+        x[i] = 0;
+    if (len > 16)
+        len = 16;
+    for (i = 0; i < len; i++)
+        x[i] = data[i];
+    if (len <= 10)
+        key->short_key = 1;
+    else
+        key->short_key = 0;
+
+    K = &k[0];
+    X[0] = ((x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3]) & 0xffffffffL;
+    X[1] = ((x[4] << 24) | (x[5] << 16) | (x[6] << 8) | x[7]) & 0xffffffffL;
+    X[2] = ((x[8] << 24) | (x[9] << 16) | (x[10] << 8) | x[11]) & 0xffffffffL;
+    X[3] =
+        ((x[12] << 24) | (x[13] << 16) | (x[14] << 8) | x[15]) & 0xffffffffL;
+
+    for (;;) {
+        l = X[0] ^ S4[x[13]] ^ S5[x[15]] ^ S6[x[12]] ^ S7[x[14]] ^ S6[x[8]];
+        CAST_exp(l, Z, z, 0);
+        l = X[2] ^ S4[z[0]] ^ S5[z[2]] ^ S6[z[1]] ^ S7[z[3]] ^ S7[x[10]];
+        CAST_exp(l, Z, z, 4);
+        l = X[3] ^ S4[z[7]] ^ S5[z[6]] ^ S6[z[5]] ^ S7[z[4]] ^ S4[x[9]];
+        CAST_exp(l, Z, z, 8);
+        l = X[1] ^ S4[z[10]] ^ S5[z[9]] ^ S6[z[11]] ^ S7[z[8]] ^ S5[x[11]];
+        CAST_exp(l, Z, z, 12);
+
+        K[0] = S4[z[8]] ^ S5[z[9]] ^ S6[z[7]] ^ S7[z[6]] ^ S4[z[2]];
+        K[1] = S4[z[10]] ^ S5[z[11]] ^ S6[z[5]] ^ S7[z[4]] ^ S5[z[6]];
+        K[2] = S4[z[12]] ^ S5[z[13]] ^ S6[z[3]] ^ S7[z[2]] ^ S6[z[9]];
+        K[3] = S4[z[14]] ^ S5[z[15]] ^ S6[z[1]] ^ S7[z[0]] ^ S7[z[12]];
+
+        l = Z[2] ^ S4[z[5]] ^ S5[z[7]] ^ S6[z[4]] ^ S7[z[6]] ^ S6[z[0]];
+        CAST_exp(l, X, x, 0);
+        l = Z[0] ^ S4[x[0]] ^ S5[x[2]] ^ S6[x[1]] ^ S7[x[3]] ^ S7[z[2]];
+        CAST_exp(l, X, x, 4);
+        l = Z[1] ^ S4[x[7]] ^ S5[x[6]] ^ S6[x[5]] ^ S7[x[4]] ^ S4[z[1]];
+        CAST_exp(l, X, x, 8);
+        l = Z[3] ^ S4[x[10]] ^ S5[x[9]] ^ S6[x[11]] ^ S7[x[8]] ^ S5[z[3]];
+        CAST_exp(l, X, x, 12);
+
+        K[4] = S4[x[3]] ^ S5[x[2]] ^ S6[x[12]] ^ S7[x[13]] ^ S4[x[8]];
+        K[5] = S4[x[1]] ^ S5[x[0]] ^ S6[x[14]] ^ S7[x[15]] ^ S5[x[13]];
+        K[6] = S4[x[7]] ^ S5[x[6]] ^ S6[x[8]] ^ S7[x[9]] ^ S6[x[3]];
+        K[7] = S4[x[5]] ^ S5[x[4]] ^ S6[x[10]] ^ S7[x[11]] ^ S7[x[7]];
+
+        l = X[0] ^ S4[x[13]] ^ S5[x[15]] ^ S6[x[12]] ^ S7[x[14]] ^ S6[x[8]];
+        CAST_exp(l, Z, z, 0);
+        l = X[2] ^ S4[z[0]] ^ S5[z[2]] ^ S6[z[1]] ^ S7[z[3]] ^ S7[x[10]];
+        CAST_exp(l, Z, z, 4);
+        l = X[3] ^ S4[z[7]] ^ S5[z[6]] ^ S6[z[5]] ^ S7[z[4]] ^ S4[x[9]];
+        CAST_exp(l, Z, z, 8);
+        l = X[1] ^ S4[z[10]] ^ S5[z[9]] ^ S6[z[11]] ^ S7[z[8]] ^ S5[x[11]];
+        CAST_exp(l, Z, z, 12);
+
+        K[8] = S4[z[3]] ^ S5[z[2]] ^ S6[z[12]] ^ S7[z[13]] ^ S4[z[9]];
+        K[9] = S4[z[1]] ^ S5[z[0]] ^ S6[z[14]] ^ S7[z[15]] ^ S5[z[12]];
+        K[10] = S4[z[7]] ^ S5[z[6]] ^ S6[z[8]] ^ S7[z[9]] ^ S6[z[2]];
+        K[11] = S4[z[5]] ^ S5[z[4]] ^ S6[z[10]] ^ S7[z[11]] ^ S7[z[6]];
+
+        l = Z[2] ^ S4[z[5]] ^ S5[z[7]] ^ S6[z[4]] ^ S7[z[6]] ^ S6[z[0]];
+        CAST_exp(l, X, x, 0);
+        l = Z[0] ^ S4[x[0]] ^ S5[x[2]] ^ S6[x[1]] ^ S7[x[3]] ^ S7[z[2]];
+        CAST_exp(l, X, x, 4);
+        l = Z[1] ^ S4[x[7]] ^ S5[x[6]] ^ S6[x[5]] ^ S7[x[4]] ^ S4[z[1]];
+        CAST_exp(l, X, x, 8);
+        l = Z[3] ^ S4[x[10]] ^ S5[x[9]] ^ S6[x[11]] ^ S7[x[8]] ^ S5[z[3]];
+        CAST_exp(l, X, x, 12);
+
+        K[12] = S4[x[8]] ^ S5[x[9]] ^ S6[x[7]] ^ S7[x[6]] ^ S4[x[3]];
+        K[13] = S4[x[10]] ^ S5[x[11]] ^ S6[x[5]] ^ S7[x[4]] ^ S5[x[7]];
+        K[14] = S4[x[12]] ^ S5[x[13]] ^ S6[x[3]] ^ S7[x[2]] ^ S6[x[8]];
+        K[15] = S4[x[14]] ^ S5[x[15]] ^ S6[x[1]] ^ S7[x[0]] ^ S7[x[13]];
+        if (K != k)
+            break;
+        K += 16;
+    }
+
+    for (i = 0; i < 16; i++) {
+        key->data[i * 2] = k[i];
+        key->data[i * 2 + 1] = ((k[i + 16]) + 16) & 0x1f;
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/cast_lcl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/cast_lcl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/cast_lcl.h	(revision 331)
@@ -0,0 +1,176 @@
+/*
+ * Copyright 1995-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 "e_os.h"
+
+#ifdef OPENSSL_SYS_WIN32
+# include <stdlib.h>
+#endif
+
+#undef c2l
+#define c2l(c,l)        (l =((unsigned long)(*((c)++)))    , \
+                         l|=((unsigned long)(*((c)++)))<< 8L, \
+                         l|=((unsigned long)(*((c)++)))<<16L, \
+                         l|=((unsigned long)(*((c)++)))<<24L)
+
+/* NOTE - c is not incremented as per c2l */
+#undef c2ln
+#define c2ln(c,l1,l2,n) { \
+                        c+=n; \
+                        l1=l2=0; \
+                        switch (n) { \
+                        case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
+                        case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
+                        case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
+                        case 5: l2|=((unsigned long)(*(--(c))));     \
+                        case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
+                        case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
+                        case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
+                        case 1: l1|=((unsigned long)(*(--(c))));     \
+                                } \
+                        }
+
+#undef l2c
+#define l2c(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+#undef l2cn
+#define l2cn(l1,l2,c,n) { \
+                        c+=n; \
+                        switch (n) { \
+                        case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
+                        case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
+                        case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
+                        case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
+                        case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
+                        case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
+                        case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
+                        case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
+                                } \
+                        }
+
+/* NOTE - c is not incremented as per n2l */
+#define n2ln(c,l1,l2,n) { \
+                        c+=n; \
+                        l1=l2=0; \
+                        switch (n) { \
+                        case 8: l2 =((unsigned long)(*(--(c))))    ; \
+                        case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
+                        case 6: l2|=((unsigned long)(*(--(c))))<<16; \
+                        case 5: l2|=((unsigned long)(*(--(c))))<<24; \
+                        case 4: l1 =((unsigned long)(*(--(c))))    ; \
+                        case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
+                        case 2: l1|=((unsigned long)(*(--(c))))<<16; \
+                        case 1: l1|=((unsigned long)(*(--(c))))<<24; \
+                                } \
+                        }
+
+/* NOTE - c is not incremented as per l2n */
+#define l2nn(l1,l2,c,n) { \
+                        c+=n; \
+                        switch (n) { \
+                        case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
+                        case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+                        case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+                        case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+                        case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
+                        case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+                        case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+                        case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+                                } \
+                        }
+
+#undef n2l
+#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
+                         l|=((unsigned long)(*((c)++)))<<16L, \
+                         l|=((unsigned long)(*((c)++)))<< 8L, \
+                         l|=((unsigned long)(*((c)++))))
+
+#undef l2n
+#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)     )&0xff))
+
+#if defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)
+# define ROTL(a,n)     (_lrotl(a,n))
+#else
+# define ROTL(a,n)     ((((a)<<(n))&0xffffffffL)|((a)>>((32-(n))&31)))
+#endif
+
+#define C_M    0x3fc
+#define C_0    22L
+#define C_1    14L
+#define C_2     6L
+#define C_3     2L              /* left shift */
+
+/* The rotate has an extra 16 added to it to help the x86 asm */
+#if defined(CAST_PTR)
+# define E_CAST(n,key,L,R,OP1,OP2,OP3) \
+        { \
+        int i; \
+        t=(key[n*2] OP1 R)&0xffffffffL; \
+        i=key[n*2+1]; \
+        t=ROTL(t,i); \
+        L^= (((((*(CAST_LONG *)((unsigned char *) \
+                        CAST_S_table0+((t>>C_2)&C_M)) OP2 \
+                *(CAST_LONG *)((unsigned char *) \
+                        CAST_S_table1+((t<<C_3)&C_M)))&0xffffffffL) OP3 \
+                *(CAST_LONG *)((unsigned char *) \
+                        CAST_S_table2+((t>>C_0)&C_M)))&0xffffffffL) OP1 \
+                *(CAST_LONG *)((unsigned char *) \
+                        CAST_S_table3+((t>>C_1)&C_M)))&0xffffffffL; \
+        }
+#elif defined(CAST_PTR2)
+# define E_CAST(n,key,L,R,OP1,OP2,OP3) \
+        { \
+        int i; \
+        CAST_LONG u,v,w; \
+        w=(key[n*2] OP1 R)&0xffffffffL; \
+        i=key[n*2+1]; \
+        w=ROTL(w,i); \
+        u=w>>C_2; \
+        v=w<<C_3; \
+        u&=C_M; \
+        v&=C_M; \
+        t= *(CAST_LONG *)((unsigned char *)CAST_S_table0+u); \
+        u=w>>C_0; \
+        t=(t OP2 *(CAST_LONG *)((unsigned char *)CAST_S_table1+v))&0xffffffffL;\
+        v=w>>C_1; \
+        u&=C_M; \
+        v&=C_M; \
+        t=(t OP3 *(CAST_LONG *)((unsigned char *)CAST_S_table2+u)&0xffffffffL);\
+        t=(t OP1 *(CAST_LONG *)((unsigned char *)CAST_S_table3+v)&0xffffffffL);\
+        L^=(t&0xffffffff); \
+        }
+#else
+# define E_CAST(n,key,L,R,OP1,OP2,OP3) \
+        { \
+        CAST_LONG a,b,c,d; \
+        t=(key[n*2] OP1 R)&0xffffffff; \
+        t=ROTL(t,(key[n*2+1])); \
+        a=CAST_S_table0[(t>> 8)&0xff]; \
+        b=CAST_S_table1[(t    )&0xff]; \
+        c=CAST_S_table2[(t>>24)&0xff]; \
+        d=CAST_S_table3[(t>>16)&0xff]; \
+        L^=(((((a OP2 b)&0xffffffffL) OP3 c)&0xffffffffL) OP1 d)&0xffffffffL; \
+        }
+#endif
+
+extern const CAST_LONG CAST_S_table0[256];
+extern const CAST_LONG CAST_S_table1[256];
+extern const CAST_LONG CAST_S_table2[256];
+extern const CAST_LONG CAST_S_table3[256];
+extern const CAST_LONG CAST_S_table4[256];
+extern const CAST_LONG CAST_S_table5[256];
+extern const CAST_LONG CAST_S_table6[256];
+extern const CAST_LONG CAST_S_table7[256];
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/cast_s.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/cast_s.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cast/cast_s.h	(revision 331)
@@ -0,0 +1,544 @@
+/*
+ * Copyright 1995-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
+ */
+
+OPENSSL_GLOBAL const CAST_LONG CAST_S_table0[256] = {
+    0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a,
+    0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
+    0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675,
+    0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
+    0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2,
+    0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
+    0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f,
+    0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0,
+    0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de,
+    0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
+    0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f,
+    0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
+    0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d,
+    0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d,
+    0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165,
+    0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
+    0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272,
+    0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
+    0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d,
+    0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
+    0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a,
+    0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167,
+    0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f,
+    0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
+    0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9,
+    0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779,
+    0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6,
+    0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2,
+    0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9,
+    0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
+    0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e,
+    0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d,
+    0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e,
+    0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5,
+    0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82,
+    0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
+    0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac,
+    0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
+    0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f,
+    0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
+    0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491,
+    0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
+    0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de,
+    0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96,
+    0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a,
+    0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,
+    0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79,
+    0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
+    0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779,
+    0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
+    0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755,
+    0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,
+    0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb,
+    0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
+    0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0,
+    0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872,
+    0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79,
+    0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,
+    0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298,
+    0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
+    0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571,
+    0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
+    0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d,
+    0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf,
+};
+
+OPENSSL_GLOBAL const CAST_LONG CAST_S_table1[256] = {
+    0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380,
+    0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
+    0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba,
+    0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
+    0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909,
+    0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
+    0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b,
+    0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
+    0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4,
+    0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
+    0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f,
+    0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
+    0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21,
+    0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b,
+    0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d,
+    0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c,
+    0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f,
+    0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
+    0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d,
+    0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
+    0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4,
+    0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd,
+    0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801,
+    0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
+    0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755,
+    0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b,
+    0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709,
+    0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
+    0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b,
+    0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
+    0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c,
+    0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
+    0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9,
+    0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c,
+    0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3,
+    0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
+    0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9,
+    0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f,
+    0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab,
+    0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
+    0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4,
+    0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
+    0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43,
+    0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58,
+    0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8,
+    0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
+    0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171,
+    0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
+    0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89,
+    0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
+    0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b,
+    0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
+    0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb,
+    0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
+    0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e,
+    0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f,
+    0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea,
+    0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
+    0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea,
+    0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
+    0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd,
+    0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
+    0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef,
+    0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1,
+};
+
+OPENSSL_GLOBAL const CAST_LONG CAST_S_table2[256] = {
+    0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907,
+    0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
+    0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae,
+    0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
+    0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e,
+    0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
+    0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc,
+    0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240,
+    0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e,
+    0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
+    0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f,
+    0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
+    0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99,
+    0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71,
+    0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f,
+    0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
+    0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380,
+    0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
+    0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8,
+    0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
+    0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504,
+    0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2,
+    0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6,
+    0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
+    0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e,
+    0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148,
+    0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d,
+    0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
+    0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1,
+    0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
+    0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c,
+    0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e,
+    0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15,
+    0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
+    0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4,
+    0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
+    0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b,
+    0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a,
+    0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392,
+    0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
+    0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231,
+    0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
+    0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889,
+    0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
+    0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67,
+    0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
+    0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49,
+    0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
+    0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d,
+    0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
+    0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d,
+    0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
+    0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e,
+    0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
+    0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767,
+    0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
+    0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce,
+    0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49,
+    0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24,
+    0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
+    0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0,
+    0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
+    0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5,
+    0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783,
+};
+
+OPENSSL_GLOBAL const CAST_LONG CAST_S_table3[256] = {
+    0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298,
+    0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
+    0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120,
+    0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
+    0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220,
+    0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
+    0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe,
+    0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121,
+    0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701,
+    0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
+    0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b,
+    0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
+    0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93,
+    0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb,
+    0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746,
+    0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5,
+    0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9,
+    0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
+    0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb,
+    0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
+    0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c,
+    0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23,
+    0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7,
+    0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
+    0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340,
+    0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
+    0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327,
+    0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119,
+    0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec,
+    0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
+    0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205,
+    0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a,
+    0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031,
+    0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79,
+    0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5,
+    0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
+    0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c,
+    0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
+    0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69,
+    0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
+    0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9,
+    0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
+    0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff,
+    0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
+    0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3,
+    0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2,
+    0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2,
+    0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
+    0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff,
+    0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
+    0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091,
+    0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919,
+    0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df,
+    0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
+    0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf,
+    0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
+    0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367,
+    0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab,
+    0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c,
+    0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
+    0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43,
+    0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
+    0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e,
+    0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2,
+};
+
+OPENSSL_GLOBAL const CAST_LONG CAST_S_table4[256] = {
+    0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911,
+    0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
+    0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00,
+    0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
+    0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180,
+    0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
+    0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2,
+    0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
+    0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725,
+    0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
+    0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b,
+    0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
+    0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571,
+    0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9,
+    0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec,
+    0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981,
+    0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea,
+    0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
+    0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263,
+    0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
+    0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468,
+    0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2,
+    0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b,
+    0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
+    0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284,
+    0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1,
+    0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4,
+    0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da,
+    0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7,
+    0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
+    0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce,
+    0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f,
+    0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6,
+    0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba,
+    0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4,
+    0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
+    0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561,
+    0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3,
+    0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6,
+    0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
+    0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406,
+    0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
+    0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472,
+    0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2,
+    0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487,
+    0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7,
+    0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288,
+    0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
+    0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2,
+    0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
+    0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78,
+    0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e,
+    0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76,
+    0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
+    0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0,
+    0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
+    0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58,
+    0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
+    0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2,
+    0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
+    0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be,
+    0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8,
+    0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55,
+    0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4,
+};
+
+OPENSSL_GLOBAL const CAST_LONG CAST_S_table5[256] = {
+    0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c,
+    0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac,
+    0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9,
+    0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138,
+    0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e,
+    0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
+    0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866,
+    0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98,
+    0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c,
+    0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
+    0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd,
+    0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
+    0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53,
+    0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
+    0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d,
+    0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8,
+    0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf,
+    0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
+    0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807,
+    0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
+    0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a,
+    0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387,
+    0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563,
+    0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
+    0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0,
+    0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf,
+    0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be,
+    0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf,
+    0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0,
+    0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
+    0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2,
+    0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289,
+    0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853,
+    0x20951063, 0x4576698d, 0xb6fad407, 0x592af950,
+    0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa,
+    0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
+    0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9,
+    0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b,
+    0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751,
+    0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
+    0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358,
+    0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
+    0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397,
+    0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976,
+    0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459,
+    0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0,
+    0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4,
+    0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
+    0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f,
+    0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
+    0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb,
+    0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
+    0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2,
+    0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
+    0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab,
+    0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25,
+    0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b,
+    0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121,
+    0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b,
+    0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
+    0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855,
+    0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd,
+    0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454,
+    0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f,
+};
+
+OPENSSL_GLOBAL const CAST_LONG CAST_S_table6[256] = {
+    0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693,
+    0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f,
+    0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82,
+    0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de,
+    0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd,
+    0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
+    0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f,
+    0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19,
+    0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9,
+    0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
+    0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e,
+    0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
+    0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83,
+    0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
+    0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e,
+    0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816,
+    0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a,
+    0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
+    0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f,
+    0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
+    0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b,
+    0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264,
+    0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78,
+    0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
+    0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d,
+    0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28,
+    0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802,
+    0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3,
+    0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9,
+    0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
+    0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302,
+    0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
+    0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858,
+    0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
+    0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a,
+    0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
+    0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4,
+    0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566,
+    0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df,
+    0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
+    0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9,
+    0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
+    0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c,
+    0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e,
+    0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07,
+    0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c,
+    0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939,
+    0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
+    0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e,
+    0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
+    0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378,
+    0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301,
+    0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd,
+    0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
+    0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567,
+    0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767,
+    0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2,
+    0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647,
+    0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf,
+    0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
+    0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2,
+    0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c,
+    0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada,
+    0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3,
+};
+
+OPENSSL_GLOBAL const CAST_LONG CAST_S_table7[256] = {
+    0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095,
+    0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5,
+    0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174,
+    0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc,
+    0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940,
+    0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
+    0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42,
+    0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d,
+    0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164,
+    0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
+    0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4,
+    0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
+    0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0,
+    0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc,
+    0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6,
+    0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c,
+    0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491,
+    0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
+    0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b,
+    0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
+    0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8,
+    0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
+    0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006,
+    0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
+    0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564,
+    0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5,
+    0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab,
+    0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472,
+    0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc,
+    0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
+    0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8,
+    0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c,
+    0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441,
+    0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb,
+    0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f,
+    0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
+    0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504,
+    0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70,
+    0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c,
+    0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
+    0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6,
+    0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
+    0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd,
+    0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3,
+    0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4,
+    0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4,
+    0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc,
+    0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
+    0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba,
+    0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
+    0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf,
+    0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e,
+    0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603,
+    0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
+    0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37,
+    0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c,
+    0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819,
+    0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384,
+    0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d,
+    0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
+    0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347,
+    0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
+    0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d,
+    0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e,
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/chacha/chacha_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/chacha/chacha_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/chacha/chacha_enc.c	(revision 331)
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2015-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
+ */
+
+/* Adapted from the public domain code by D. Bernstein from SUPERCOP. */
+
+#include <string.h>
+
+#include "internal/chacha.h"
+
+typedef unsigned int u32;
+typedef unsigned char u8;
+typedef union {
+    u32 u[16];
+    u8 c[64];
+} chacha_buf;
+
+# define ROTATE(v, n) (((v) << (n)) | ((v) >> (32 - (n))))
+
+# define U32TO8_LITTLE(p, v) do { \
+                                (p)[0] = (u8)(v >>  0); \
+                                (p)[1] = (u8)(v >>  8); \
+                                (p)[2] = (u8)(v >> 16); \
+                                (p)[3] = (u8)(v >> 24); \
+                                } while(0)
+
+/* QUARTERROUND updates a, b, c, d with a ChaCha "quarter" round. */
+# define QUARTERROUND(a,b,c,d) ( \
+                x[a] += x[b], x[d] = ROTATE((x[d] ^ x[a]),16), \
+                x[c] += x[d], x[b] = ROTATE((x[b] ^ x[c]),12), \
+                x[a] += x[b], x[d] = ROTATE((x[d] ^ x[a]), 8), \
+                x[c] += x[d], x[b] = ROTATE((x[b] ^ x[c]), 7)  )
+
+/* chacha_core performs 20 rounds of ChaCha on the input words in
+ * |input| and writes the 64 output bytes to |output|. */
+static void chacha20_core(chacha_buf *output, const u32 input[16])
+{
+    u32 x[16];
+    int i;
+    const union {
+        long one;
+        char little;
+    } is_endian = { 1 };
+
+    memcpy(x, input, sizeof(x));
+
+    for (i = 20; i > 0; i -= 2) {
+        QUARTERROUND(0, 4, 8, 12);
+        QUARTERROUND(1, 5, 9, 13);
+        QUARTERROUND(2, 6, 10, 14);
+        QUARTERROUND(3, 7, 11, 15);
+        QUARTERROUND(0, 5, 10, 15);
+        QUARTERROUND(1, 6, 11, 12);
+        QUARTERROUND(2, 7, 8, 13);
+        QUARTERROUND(3, 4, 9, 14);
+    }
+
+    if (is_endian.little) {
+        for (i = 0; i < 16; ++i)
+            output->u[i] = x[i] + input[i];
+    } else {
+        for (i = 0; i < 16; ++i)
+            U32TO8_LITTLE(output->c + 4 * i, (x[i] + input[i]));
+    }
+}
+
+void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp,
+                    size_t len, const unsigned int key[8],
+                    const unsigned int counter[4])
+{
+    u32 input[16];
+    chacha_buf buf;
+    size_t todo, i;
+
+    /* sigma constant "expand 32-byte k" in little-endian encoding */
+    input[0] = ((u32)'e') | ((u32)'x'<<8) | ((u32)'p'<<16) | ((u32)'a'<<24);
+    input[1] = ((u32)'n') | ((u32)'d'<<8) | ((u32)' '<<16) | ((u32)'3'<<24);
+    input[2] = ((u32)'2') | ((u32)'-'<<8) | ((u32)'b'<<16) | ((u32)'y'<<24);
+    input[3] = ((u32)'t') | ((u32)'e'<<8) | ((u32)' '<<16) | ((u32)'k'<<24);
+
+    input[4] = key[0];
+    input[5] = key[1];
+    input[6] = key[2];
+    input[7] = key[3];
+    input[8] = key[4];
+    input[9] = key[5];
+    input[10] = key[6];
+    input[11] = key[7];
+
+    input[12] = counter[0];
+    input[13] = counter[1];
+    input[14] = counter[2];
+    input[15] = counter[3];
+
+    while (len > 0) {
+        todo = sizeof(buf);
+        if (len < todo)
+            todo = len;
+
+        chacha20_core(&buf, input);
+
+        for (i = 0; i < todo; i++)
+            out[i] = inp[i] ^ buf.c[i];
+        out += todo;
+        inp += todo;
+        len -= todo;
+
+        /*
+         * Advance 32-bit counter. Note that as subroutine is so to
+         * say nonce-agnostic, this limited counter width doesn't
+         * prevent caller from implementing wider counter. It would
+         * simply take two calls split on counter overflow...
+         */
+        input[12]++;
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cmac/cm_ameth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cmac/cm_ameth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cmac/cm_ameth.c	(revision 331)
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2010-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/cmac.h>
+#include "internal/asn1_int.h"
+
+/*
+ * CMAC "ASN1" method. This is just here to indicate the maximum CMAC output
+ * length and to free up a CMAC key.
+ */
+
+static int cmac_size(const EVP_PKEY *pkey)
+{
+    return EVP_MAX_BLOCK_LENGTH;
+}
+
+static void cmac_key_free(EVP_PKEY *pkey)
+{
+    CMAC_CTX *cmctx = EVP_PKEY_get0(pkey);
+    CMAC_CTX_free(cmctx);
+}
+
+const EVP_PKEY_ASN1_METHOD cmac_asn1_meth = {
+    EVP_PKEY_CMAC,
+    EVP_PKEY_CMAC,
+    0,
+
+    "CMAC",
+    "OpenSSL CMAC method",
+
+    0, 0, 0, 0,
+
+    0, 0, 0,
+
+    cmac_size,
+    0, 0,
+    0, 0, 0, 0, 0, 0, 0,
+
+    cmac_key_free,
+    0,
+    0, 0
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cmac/cm_pmeth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cmac/cm_pmeth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cmac/cm_pmeth.c	(revision 331)
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2010-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/evp.h>
+#include <openssl/cmac.h>
+#include "internal/evp_int.h"
+
+/* The context structure and "key" is simply a CMAC_CTX */
+
+static int pkey_cmac_init(EVP_PKEY_CTX *ctx)
+{
+    ctx->data = CMAC_CTX_new();
+    if (ctx->data == NULL)
+        return 0;
+    ctx->keygen_info_count = 0;
+    return 1;
+}
+
+static int pkey_cmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+{
+    if (!pkey_cmac_init(dst))
+        return 0;
+    if (!CMAC_CTX_copy(dst->data, src->data))
+        return 0;
+    return 1;
+}
+
+static void pkey_cmac_cleanup(EVP_PKEY_CTX *ctx)
+{
+    CMAC_CTX_free(ctx->data);
+}
+
+static int pkey_cmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+    CMAC_CTX *cmkey = CMAC_CTX_new();
+    CMAC_CTX *cmctx = ctx->data;
+    if (cmkey == NULL)
+        return 0;
+    if (!CMAC_CTX_copy(cmkey, cmctx)) {
+        CMAC_CTX_free(cmkey);
+        return 0;
+    }
+    EVP_PKEY_assign(pkey, EVP_PKEY_CMAC, cmkey);
+
+    return 1;
+}
+
+static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+    if (!CMAC_Update(EVP_MD_CTX_pkey_ctx(ctx)->data, data, count))
+        return 0;
+    return 1;
+}
+
+static int cmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
+{
+    EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
+    EVP_MD_CTX_set_update_fn(mctx, int_update);
+    return 1;
+}
+
+static int cmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+                        EVP_MD_CTX *mctx)
+{
+    return CMAC_Final(ctx->data, sig, siglen);
+}
+
+static int pkey_cmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+    CMAC_CTX *cmctx = ctx->data;
+    switch (type) {
+
+    case EVP_PKEY_CTRL_SET_MAC_KEY:
+        if (!p2 || p1 < 0)
+            return 0;
+        if (!CMAC_Init(cmctx, p2, p1, NULL, NULL))
+            return 0;
+        break;
+
+    case EVP_PKEY_CTRL_CIPHER:
+        if (!CMAC_Init(cmctx, NULL, 0, p2, ctx->engine))
+            return 0;
+        break;
+
+    case EVP_PKEY_CTRL_MD:
+        if (ctx->pkey && !CMAC_CTX_copy(ctx->data,
+                                        (CMAC_CTX *)ctx->pkey->pkey.ptr))
+            return 0;
+        if (!CMAC_Init(cmctx, NULL, 0, NULL, NULL))
+            return 0;
+        break;
+
+    default:
+        return -2;
+
+    }
+    return 1;
+}
+
+static int pkey_cmac_ctrl_str(EVP_PKEY_CTX *ctx,
+                              const char *type, const char *value)
+{
+    if (!value) {
+        return 0;
+    }
+    if (strcmp(type, "cipher") == 0) {
+        const EVP_CIPHER *c;
+        c = EVP_get_cipherbyname(value);
+        if (!c)
+            return 0;
+        return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_CIPHER, -1, (void *)c);
+    }
+    if (strcmp(type, "key") == 0)
+        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value);
+    if (strcmp(type, "hexkey") == 0)
+        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value);
+    return -2;
+}
+
+const EVP_PKEY_METHOD cmac_pkey_meth = {
+    EVP_PKEY_CMAC,
+    EVP_PKEY_FLAG_SIGCTX_CUSTOM,
+    pkey_cmac_init,
+    pkey_cmac_copy,
+    pkey_cmac_cleanup,
+
+    0, 0,
+
+    0,
+    pkey_cmac_keygen,
+
+    0, 0,
+
+    0, 0,
+
+    0, 0,
+
+    cmac_signctx_init,
+    cmac_signctx,
+
+    0, 0,
+
+    0, 0,
+
+    0, 0,
+
+    0, 0,
+
+    pkey_cmac_ctrl,
+    pkey_cmac_ctrl_str
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cmac/cmac.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cmac/cmac.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cmac/cmac.c	(revision 331)
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2010-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "internal/cryptlib.h"
+#include <openssl/cmac.h>
+
+struct CMAC_CTX_st {
+    /* Cipher context to use */
+    EVP_CIPHER_CTX *cctx;
+    /* Keys k1 and k2 */
+    unsigned char k1[EVP_MAX_BLOCK_LENGTH];
+    unsigned char k2[EVP_MAX_BLOCK_LENGTH];
+    /* Temporary block */
+    unsigned char tbl[EVP_MAX_BLOCK_LENGTH];
+    /* Last (possibly partial) block */
+    unsigned char last_block[EVP_MAX_BLOCK_LENGTH];
+    /* Number of bytes in last block: -1 means context not initialised */
+    int nlast_block;
+};
+
+/* Make temporary keys K1 and K2 */
+
+static void make_kn(unsigned char *k1, const unsigned char *l, int bl)
+{
+    int i;
+    unsigned char c = l[0], carry = c >> 7, cnext;
+
+    /* Shift block to left, including carry */
+    for (i = 0; i < bl - 1; i++, c = cnext)
+        k1[i] = (c << 1) | ((cnext = l[i + 1]) >> 7);
+
+    /* If MSB set fixup with R */
+    k1[i] = (c << 1) ^ ((0 - carry) & (bl == 16 ? 0x87 : 0x1b));
+}
+
+CMAC_CTX *CMAC_CTX_new(void)
+{
+    CMAC_CTX *ctx;
+
+    ctx = OPENSSL_malloc(sizeof(*ctx));
+    if (ctx == NULL)
+        return NULL;
+    ctx->cctx = EVP_CIPHER_CTX_new();
+    if (ctx->cctx == NULL) {
+        OPENSSL_free(ctx);
+        return NULL;
+    }
+    ctx->nlast_block = -1;
+    return ctx;
+}
+
+void CMAC_CTX_cleanup(CMAC_CTX *ctx)
+{
+    EVP_CIPHER_CTX_free(ctx->cctx);
+    OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH);
+    OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH);
+    OPENSSL_cleanse(ctx->k2, EVP_MAX_BLOCK_LENGTH);
+    OPENSSL_cleanse(ctx->last_block, EVP_MAX_BLOCK_LENGTH);
+    ctx->nlast_block = -1;
+}
+
+EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx)
+{
+    return ctx->cctx;
+}
+
+void CMAC_CTX_free(CMAC_CTX *ctx)
+{
+    if (!ctx)
+        return;
+    CMAC_CTX_cleanup(ctx);
+    OPENSSL_free(ctx);
+}
+
+int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in)
+{
+    int bl;
+    if (in->nlast_block == -1)
+        return 0;
+    if (!EVP_CIPHER_CTX_copy(out->cctx, in->cctx))
+        return 0;
+    bl = EVP_CIPHER_CTX_block_size(in->cctx);
+    memcpy(out->k1, in->k1, bl);
+    memcpy(out->k2, in->k2, bl);
+    memcpy(out->tbl, in->tbl, bl);
+    memcpy(out->last_block, in->last_block, bl);
+    out->nlast_block = in->nlast_block;
+    return 1;
+}
+
+int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
+              const EVP_CIPHER *cipher, ENGINE *impl)
+{
+    static const unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH] = { 0 };
+    /* All zeros means restart */
+    if (!key && !cipher && !impl && keylen == 0) {
+        /* Not initialised */
+        if (ctx->nlast_block == -1)
+            return 0;
+        if (!EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, NULL, zero_iv))
+            return 0;
+        memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(ctx->cctx));
+        ctx->nlast_block = 0;
+        return 1;
+    }
+    /* Initialise context */
+    if (cipher && !EVP_EncryptInit_ex(ctx->cctx, cipher, impl, NULL, NULL))
+        return 0;
+    /* Non-NULL key means initialisation complete */
+    if (key) {
+        int bl;
+        if (!EVP_CIPHER_CTX_cipher(ctx->cctx))
+            return 0;
+        if (!EVP_CIPHER_CTX_set_key_length(ctx->cctx, keylen))
+            return 0;
+        if (!EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, key, zero_iv))
+            return 0;
+        bl = EVP_CIPHER_CTX_block_size(ctx->cctx);
+        if (!EVP_Cipher(ctx->cctx, ctx->tbl, zero_iv, bl))
+            return 0;
+        make_kn(ctx->k1, ctx->tbl, bl);
+        make_kn(ctx->k2, ctx->k1, bl);
+        OPENSSL_cleanse(ctx->tbl, bl);
+        /* Reset context again ready for first data block */
+        if (!EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, NULL, zero_iv))
+            return 0;
+        /* Zero tbl so resume works */
+        memset(ctx->tbl, 0, bl);
+        ctx->nlast_block = 0;
+    }
+    return 1;
+}
+
+int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen)
+{
+    const unsigned char *data = in;
+    size_t bl;
+    if (ctx->nlast_block == -1)
+        return 0;
+    if (dlen == 0)
+        return 1;
+    bl = EVP_CIPHER_CTX_block_size(ctx->cctx);
+    /* Copy into partial block if we need to */
+    if (ctx->nlast_block > 0) {
+        size_t nleft;
+        nleft = bl - ctx->nlast_block;
+        if (dlen < nleft)
+            nleft = dlen;
+        memcpy(ctx->last_block + ctx->nlast_block, data, nleft);
+        dlen -= nleft;
+        ctx->nlast_block += nleft;
+        /* If no more to process return */
+        if (dlen == 0)
+            return 1;
+        data += nleft;
+        /* Else not final block so encrypt it */
+        if (!EVP_Cipher(ctx->cctx, ctx->tbl, ctx->last_block, bl))
+            return 0;
+    }
+    /* Encrypt all but one of the complete blocks left */
+    while (dlen > bl) {
+        if (!EVP_Cipher(ctx->cctx, ctx->tbl, data, bl))
+            return 0;
+        dlen -= bl;
+        data += bl;
+    }
+    /* Copy any data left to last block buffer */
+    memcpy(ctx->last_block, data, dlen);
+    ctx->nlast_block = dlen;
+    return 1;
+
+}
+
+int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen)
+{
+    int i, bl, lb;
+    if (ctx->nlast_block == -1)
+        return 0;
+    bl = EVP_CIPHER_CTX_block_size(ctx->cctx);
+    *poutlen = (size_t)bl;
+    if (!out)
+        return 1;
+    lb = ctx->nlast_block;
+    /* Is last block complete? */
+    if (lb == bl) {
+        for (i = 0; i < bl; i++)
+            out[i] = ctx->last_block[i] ^ ctx->k1[i];
+    } else {
+        ctx->last_block[lb] = 0x80;
+        if (bl - lb > 1)
+            memset(ctx->last_block + lb + 1, 0, bl - lb - 1);
+        for (i = 0; i < bl; i++)
+            out[i] = ctx->last_block[i] ^ ctx->k2[i];
+    }
+    if (!EVP_Cipher(ctx->cctx, out, out, bl)) {
+        OPENSSL_cleanse(out, bl);
+        return 0;
+    }
+    return 1;
+}
+
+int CMAC_resume(CMAC_CTX *ctx)
+{
+    if (ctx->nlast_block == -1)
+        return 0;
+    /*
+     * The buffer "tbl" contains the last fully encrypted block which is the
+     * last IV (or all zeroes if no last encrypted block). The last block has
+     * not been modified since CMAC_final(). So reinitialising using the last
+     * decrypted block will allow CMAC to continue after calling
+     * CMAC_Final().
+     */
+    return EVP_EncryptInit_ex(ctx->cctx, NULL, NULL, NULL, ctx->tbl);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_asn1.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_asn1.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_asn1.c	(revision 331)
@@ -0,0 +1,402 @@
+/*
+ * Copyright 2008-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 <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/cms.h>
+#include "cms_lcl.h"
+
+
+ASN1_SEQUENCE(CMS_IssuerAndSerialNumber) = {
+        ASN1_SIMPLE(CMS_IssuerAndSerialNumber, issuer, X509_NAME),
+        ASN1_SIMPLE(CMS_IssuerAndSerialNumber, serialNumber, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(CMS_IssuerAndSerialNumber)
+
+ASN1_SEQUENCE(CMS_OtherCertificateFormat) = {
+        ASN1_SIMPLE(CMS_OtherCertificateFormat, otherCertFormat, ASN1_OBJECT),
+        ASN1_OPT(CMS_OtherCertificateFormat, otherCert, ASN1_ANY)
+} static_ASN1_SEQUENCE_END(CMS_OtherCertificateFormat)
+
+ASN1_CHOICE(CMS_CertificateChoices) = {
+        ASN1_SIMPLE(CMS_CertificateChoices, d.certificate, X509),
+        ASN1_IMP(CMS_CertificateChoices, d.extendedCertificate, ASN1_SEQUENCE, 0),
+        ASN1_IMP(CMS_CertificateChoices, d.v1AttrCert, ASN1_SEQUENCE, 1),
+        ASN1_IMP(CMS_CertificateChoices, d.v2AttrCert, ASN1_SEQUENCE, 2),
+        ASN1_IMP(CMS_CertificateChoices, d.other, CMS_OtherCertificateFormat, 3)
+} ASN1_CHOICE_END(CMS_CertificateChoices)
+
+ASN1_CHOICE(CMS_SignerIdentifier) = {
+        ASN1_SIMPLE(CMS_SignerIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
+        ASN1_IMP(CMS_SignerIdentifier, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0)
+} static_ASN1_CHOICE_END(CMS_SignerIdentifier)
+
+ASN1_NDEF_SEQUENCE(CMS_EncapsulatedContentInfo) = {
+        ASN1_SIMPLE(CMS_EncapsulatedContentInfo, eContentType, ASN1_OBJECT),
+        ASN1_NDEF_EXP_OPT(CMS_EncapsulatedContentInfo, eContent, ASN1_OCTET_STRING_NDEF, 0)
+} static_ASN1_NDEF_SEQUENCE_END(CMS_EncapsulatedContentInfo)
+
+/* Minor tweak to operation: free up signer key, cert */
+static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                     void *exarg)
+{
+    if (operation == ASN1_OP_FREE_POST) {
+        CMS_SignerInfo *si = (CMS_SignerInfo *)*pval;
+        EVP_PKEY_free(si->pkey);
+        X509_free(si->signer);
+        EVP_MD_CTX_free(si->mctx);
+    }
+    return 1;
+}
+
+ASN1_SEQUENCE_cb(CMS_SignerInfo, cms_si_cb) = {
+        ASN1_SIMPLE(CMS_SignerInfo, version, LONG),
+        ASN1_SIMPLE(CMS_SignerInfo, sid, CMS_SignerIdentifier),
+        ASN1_SIMPLE(CMS_SignerInfo, digestAlgorithm, X509_ALGOR),
+        ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, signedAttrs, X509_ATTRIBUTE, 0),
+        ASN1_SIMPLE(CMS_SignerInfo, signatureAlgorithm, X509_ALGOR),
+        ASN1_SIMPLE(CMS_SignerInfo, signature, ASN1_OCTET_STRING),
+        ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, unsignedAttrs, X509_ATTRIBUTE, 1)
+} ASN1_SEQUENCE_END_cb(CMS_SignerInfo, CMS_SignerInfo)
+
+ASN1_SEQUENCE(CMS_OtherRevocationInfoFormat) = {
+        ASN1_SIMPLE(CMS_OtherRevocationInfoFormat, otherRevInfoFormat, ASN1_OBJECT),
+        ASN1_OPT(CMS_OtherRevocationInfoFormat, otherRevInfo, ASN1_ANY)
+} static_ASN1_SEQUENCE_END(CMS_OtherRevocationInfoFormat)
+
+ASN1_CHOICE(CMS_RevocationInfoChoice) = {
+        ASN1_SIMPLE(CMS_RevocationInfoChoice, d.crl, X509_CRL),
+        ASN1_IMP(CMS_RevocationInfoChoice, d.other, CMS_OtherRevocationInfoFormat, 1)
+} ASN1_CHOICE_END(CMS_RevocationInfoChoice)
+
+ASN1_NDEF_SEQUENCE(CMS_SignedData) = {
+        ASN1_SIMPLE(CMS_SignedData, version, LONG),
+        ASN1_SET_OF(CMS_SignedData, digestAlgorithms, X509_ALGOR),
+        ASN1_SIMPLE(CMS_SignedData, encapContentInfo, CMS_EncapsulatedContentInfo),
+        ASN1_IMP_SET_OF_OPT(CMS_SignedData, certificates, CMS_CertificateChoices, 0),
+        ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1),
+        ASN1_SET_OF(CMS_SignedData, signerInfos, CMS_SignerInfo)
+} ASN1_NDEF_SEQUENCE_END(CMS_SignedData)
+
+ASN1_SEQUENCE(CMS_OriginatorInfo) = {
+        ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, certificates, CMS_CertificateChoices, 0),
+        ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, crls, CMS_RevocationInfoChoice, 1)
+} static_ASN1_SEQUENCE_END(CMS_OriginatorInfo)
+
+ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = {
+        ASN1_SIMPLE(CMS_EncryptedContentInfo, contentType, ASN1_OBJECT),
+        ASN1_SIMPLE(CMS_EncryptedContentInfo, contentEncryptionAlgorithm, X509_ALGOR),
+        ASN1_IMP_OPT(CMS_EncryptedContentInfo, encryptedContent, ASN1_OCTET_STRING_NDEF, 0)
+} static_ASN1_NDEF_SEQUENCE_END(CMS_EncryptedContentInfo)
+
+ASN1_SEQUENCE(CMS_KeyTransRecipientInfo) = {
+        ASN1_SIMPLE(CMS_KeyTransRecipientInfo, version, LONG),
+        ASN1_SIMPLE(CMS_KeyTransRecipientInfo, rid, CMS_SignerIdentifier),
+        ASN1_SIMPLE(CMS_KeyTransRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
+        ASN1_SIMPLE(CMS_KeyTransRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(CMS_KeyTransRecipientInfo)
+
+ASN1_SEQUENCE(CMS_OtherKeyAttribute) = {
+        ASN1_SIMPLE(CMS_OtherKeyAttribute, keyAttrId, ASN1_OBJECT),
+        ASN1_OPT(CMS_OtherKeyAttribute, keyAttr, ASN1_ANY)
+} ASN1_SEQUENCE_END(CMS_OtherKeyAttribute)
+
+ASN1_SEQUENCE(CMS_RecipientKeyIdentifier) = {
+        ASN1_SIMPLE(CMS_RecipientKeyIdentifier, subjectKeyIdentifier, ASN1_OCTET_STRING),
+        ASN1_OPT(CMS_RecipientKeyIdentifier, date, ASN1_GENERALIZEDTIME),
+        ASN1_OPT(CMS_RecipientKeyIdentifier, other, CMS_OtherKeyAttribute)
+} ASN1_SEQUENCE_END(CMS_RecipientKeyIdentifier)
+
+ASN1_CHOICE(CMS_KeyAgreeRecipientIdentifier) = {
+  ASN1_SIMPLE(CMS_KeyAgreeRecipientIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
+  ASN1_IMP(CMS_KeyAgreeRecipientIdentifier, d.rKeyId, CMS_RecipientKeyIdentifier, 0)
+} static_ASN1_CHOICE_END(CMS_KeyAgreeRecipientIdentifier)
+
+static int cms_rek_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                      void *exarg)
+{
+    CMS_RecipientEncryptedKey *rek = (CMS_RecipientEncryptedKey *)*pval;
+    if (operation == ASN1_OP_FREE_POST) {
+        EVP_PKEY_free(rek->pkey);
+    }
+    return 1;
+}
+
+ASN1_SEQUENCE_cb(CMS_RecipientEncryptedKey, cms_rek_cb) = {
+        ASN1_SIMPLE(CMS_RecipientEncryptedKey, rid, CMS_KeyAgreeRecipientIdentifier),
+        ASN1_SIMPLE(CMS_RecipientEncryptedKey, encryptedKey, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END_cb(CMS_RecipientEncryptedKey, CMS_RecipientEncryptedKey)
+
+ASN1_SEQUENCE(CMS_OriginatorPublicKey) = {
+  ASN1_SIMPLE(CMS_OriginatorPublicKey, algorithm, X509_ALGOR),
+  ASN1_SIMPLE(CMS_OriginatorPublicKey, publicKey, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END(CMS_OriginatorPublicKey)
+
+ASN1_CHOICE(CMS_OriginatorIdentifierOrKey) = {
+  ASN1_SIMPLE(CMS_OriginatorIdentifierOrKey, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
+  ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0),
+  ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.originatorKey, CMS_OriginatorPublicKey, 1)
+} static_ASN1_CHOICE_END(CMS_OriginatorIdentifierOrKey)
+
+static int cms_kari_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                       void *exarg)
+{
+    CMS_KeyAgreeRecipientInfo *kari = (CMS_KeyAgreeRecipientInfo *)*pval;
+    if (operation == ASN1_OP_NEW_POST) {
+        kari->ctx = EVP_CIPHER_CTX_new();
+        if (kari->ctx == NULL)
+            return 0;
+        EVP_CIPHER_CTX_set_flags(kari->ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
+        kari->pctx = NULL;
+    } else if (operation == ASN1_OP_FREE_POST) {
+        EVP_PKEY_CTX_free(kari->pctx);
+        EVP_CIPHER_CTX_free(kari->ctx);
+    }
+    return 1;
+}
+
+ASN1_SEQUENCE_cb(CMS_KeyAgreeRecipientInfo, cms_kari_cb) = {
+        ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, version, LONG),
+        ASN1_EXP(CMS_KeyAgreeRecipientInfo, originator, CMS_OriginatorIdentifierOrKey, 0),
+        ASN1_EXP_OPT(CMS_KeyAgreeRecipientInfo, ukm, ASN1_OCTET_STRING, 1),
+        ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
+        ASN1_SEQUENCE_OF(CMS_KeyAgreeRecipientInfo, recipientEncryptedKeys, CMS_RecipientEncryptedKey)
+} ASN1_SEQUENCE_END_cb(CMS_KeyAgreeRecipientInfo, CMS_KeyAgreeRecipientInfo)
+
+ASN1_SEQUENCE(CMS_KEKIdentifier) = {
+        ASN1_SIMPLE(CMS_KEKIdentifier, keyIdentifier, ASN1_OCTET_STRING),
+        ASN1_OPT(CMS_KEKIdentifier, date, ASN1_GENERALIZEDTIME),
+        ASN1_OPT(CMS_KEKIdentifier, other, CMS_OtherKeyAttribute)
+} static_ASN1_SEQUENCE_END(CMS_KEKIdentifier)
+
+ASN1_SEQUENCE(CMS_KEKRecipientInfo) = {
+        ASN1_SIMPLE(CMS_KEKRecipientInfo, version, LONG),
+        ASN1_SIMPLE(CMS_KEKRecipientInfo, kekid, CMS_KEKIdentifier),
+        ASN1_SIMPLE(CMS_KEKRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
+        ASN1_SIMPLE(CMS_KEKRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(CMS_KEKRecipientInfo)
+
+ASN1_SEQUENCE(CMS_PasswordRecipientInfo) = {
+        ASN1_SIMPLE(CMS_PasswordRecipientInfo, version, LONG),
+        ASN1_IMP_OPT(CMS_PasswordRecipientInfo, keyDerivationAlgorithm, X509_ALGOR, 0),
+        ASN1_SIMPLE(CMS_PasswordRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
+        ASN1_SIMPLE(CMS_PasswordRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(CMS_PasswordRecipientInfo)
+
+ASN1_SEQUENCE(CMS_OtherRecipientInfo) = {
+  ASN1_SIMPLE(CMS_OtherRecipientInfo, oriType, ASN1_OBJECT),
+  ASN1_OPT(CMS_OtherRecipientInfo, oriValue, ASN1_ANY)
+} static_ASN1_SEQUENCE_END(CMS_OtherRecipientInfo)
+
+/* Free up RecipientInfo additional data */
+static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                     void *exarg)
+{
+    if (operation == ASN1_OP_FREE_PRE) {
+        CMS_RecipientInfo *ri = (CMS_RecipientInfo *)*pval;
+        if (ri->type == CMS_RECIPINFO_TRANS) {
+            CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
+            EVP_PKEY_free(ktri->pkey);
+            X509_free(ktri->recip);
+            EVP_PKEY_CTX_free(ktri->pctx);
+        } else if (ri->type == CMS_RECIPINFO_KEK) {
+            CMS_KEKRecipientInfo *kekri = ri->d.kekri;
+            OPENSSL_clear_free(kekri->key, kekri->keylen);
+        } else if (ri->type == CMS_RECIPINFO_PASS) {
+            CMS_PasswordRecipientInfo *pwri = ri->d.pwri;
+            OPENSSL_clear_free(pwri->pass, pwri->passlen);
+        }
+    }
+    return 1;
+}
+
+ASN1_CHOICE_cb(CMS_RecipientInfo, cms_ri_cb) = {
+        ASN1_SIMPLE(CMS_RecipientInfo, d.ktri, CMS_KeyTransRecipientInfo),
+        ASN1_IMP(CMS_RecipientInfo, d.kari, CMS_KeyAgreeRecipientInfo, 1),
+        ASN1_IMP(CMS_RecipientInfo, d.kekri, CMS_KEKRecipientInfo, 2),
+        ASN1_IMP(CMS_RecipientInfo, d.pwri, CMS_PasswordRecipientInfo, 3),
+        ASN1_IMP(CMS_RecipientInfo, d.ori, CMS_OtherRecipientInfo, 4)
+} ASN1_CHOICE_END_cb(CMS_RecipientInfo, CMS_RecipientInfo, type)
+
+ASN1_NDEF_SEQUENCE(CMS_EnvelopedData) = {
+        ASN1_SIMPLE(CMS_EnvelopedData, version, LONG),
+        ASN1_IMP_OPT(CMS_EnvelopedData, originatorInfo, CMS_OriginatorInfo, 0),
+        ASN1_SET_OF(CMS_EnvelopedData, recipientInfos, CMS_RecipientInfo),
+        ASN1_SIMPLE(CMS_EnvelopedData, encryptedContentInfo, CMS_EncryptedContentInfo),
+        ASN1_IMP_SET_OF_OPT(CMS_EnvelopedData, unprotectedAttrs, X509_ATTRIBUTE, 1)
+} ASN1_NDEF_SEQUENCE_END(CMS_EnvelopedData)
+
+ASN1_NDEF_SEQUENCE(CMS_DigestedData) = {
+        ASN1_SIMPLE(CMS_DigestedData, version, LONG),
+        ASN1_SIMPLE(CMS_DigestedData, digestAlgorithm, X509_ALGOR),
+        ASN1_SIMPLE(CMS_DigestedData, encapContentInfo, CMS_EncapsulatedContentInfo),
+        ASN1_SIMPLE(CMS_DigestedData, digest, ASN1_OCTET_STRING)
+} ASN1_NDEF_SEQUENCE_END(CMS_DigestedData)
+
+ASN1_NDEF_SEQUENCE(CMS_EncryptedData) = {
+        ASN1_SIMPLE(CMS_EncryptedData, version, LONG),
+        ASN1_SIMPLE(CMS_EncryptedData, encryptedContentInfo, CMS_EncryptedContentInfo),
+        ASN1_IMP_SET_OF_OPT(CMS_EncryptedData, unprotectedAttrs, X509_ATTRIBUTE, 1)
+} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedData)
+
+ASN1_NDEF_SEQUENCE(CMS_AuthenticatedData) = {
+        ASN1_SIMPLE(CMS_AuthenticatedData, version, LONG),
+        ASN1_IMP_OPT(CMS_AuthenticatedData, originatorInfo, CMS_OriginatorInfo, 0),
+        ASN1_SET_OF(CMS_AuthenticatedData, recipientInfos, CMS_RecipientInfo),
+        ASN1_SIMPLE(CMS_AuthenticatedData, macAlgorithm, X509_ALGOR),
+        ASN1_IMP(CMS_AuthenticatedData, digestAlgorithm, X509_ALGOR, 1),
+        ASN1_SIMPLE(CMS_AuthenticatedData, encapContentInfo, CMS_EncapsulatedContentInfo),
+        ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, authAttrs, X509_ALGOR, 2),
+        ASN1_SIMPLE(CMS_AuthenticatedData, mac, ASN1_OCTET_STRING),
+        ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, unauthAttrs, X509_ALGOR, 3)
+} static_ASN1_NDEF_SEQUENCE_END(CMS_AuthenticatedData)
+
+ASN1_NDEF_SEQUENCE(CMS_CompressedData) = {
+        ASN1_SIMPLE(CMS_CompressedData, version, LONG),
+        ASN1_SIMPLE(CMS_CompressedData, compressionAlgorithm, X509_ALGOR),
+        ASN1_SIMPLE(CMS_CompressedData, encapContentInfo, CMS_EncapsulatedContentInfo),
+} ASN1_NDEF_SEQUENCE_END(CMS_CompressedData)
+
+/* This is the ANY DEFINED BY table for the top level ContentInfo structure */
+
+ASN1_ADB_TEMPLATE(cms_default) = ASN1_EXP(CMS_ContentInfo, d.other, ASN1_ANY, 0);
+
+ASN1_ADB(CMS_ContentInfo) = {
+        ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP(CMS_ContentInfo, d.data, ASN1_OCTET_STRING_NDEF, 0)),
+        ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP(CMS_ContentInfo, d.signedData, CMS_SignedData, 0)),
+        ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP(CMS_ContentInfo, d.envelopedData, CMS_EnvelopedData, 0)),
+        ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP(CMS_ContentInfo, d.digestedData, CMS_DigestedData, 0)),
+        ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP(CMS_ContentInfo, d.encryptedData, CMS_EncryptedData, 0)),
+        ADB_ENTRY(NID_id_smime_ct_authData, ASN1_NDEF_EXP(CMS_ContentInfo, d.authenticatedData, CMS_AuthenticatedData, 0)),
+        ADB_ENTRY(NID_id_smime_ct_compressedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.compressedData, CMS_CompressedData, 0)),
+} ASN1_ADB_END(CMS_ContentInfo, 0, contentType, 0, &cms_default_tt, NULL);
+
+/* CMS streaming support */
+static int cms_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                  void *exarg)
+{
+    ASN1_STREAM_ARG *sarg = exarg;
+    CMS_ContentInfo *cms = NULL;
+    if (pval)
+        cms = (CMS_ContentInfo *)*pval;
+    else
+        return 1;
+    switch (operation) {
+
+    case ASN1_OP_STREAM_PRE:
+        if (CMS_stream(&sarg->boundary, cms) <= 0)
+            return 0;
+    case ASN1_OP_DETACHED_PRE:
+        sarg->ndef_bio = CMS_dataInit(cms, sarg->out);
+        if (!sarg->ndef_bio)
+            return 0;
+        break;
+
+    case ASN1_OP_STREAM_POST:
+    case ASN1_OP_DETACHED_POST:
+        if (CMS_dataFinal(cms, sarg->ndef_bio) <= 0)
+            return 0;
+        break;
+
+    }
+    return 1;
+}
+
+ASN1_NDEF_SEQUENCE_cb(CMS_ContentInfo, cms_cb) = {
+        ASN1_SIMPLE(CMS_ContentInfo, contentType, ASN1_OBJECT),
+        ASN1_ADB_OBJECT(CMS_ContentInfo)
+} ASN1_NDEF_SEQUENCE_END_cb(CMS_ContentInfo, CMS_ContentInfo)
+
+/* Specials for signed attributes */
+
+/*
+ * When signing attributes we want to reorder them to match the sorted
+ * encoding.
+ */
+
+ASN1_ITEM_TEMPLATE(CMS_Attributes_Sign) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, CMS_ATTRIBUTES, X509_ATTRIBUTE)
+ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Sign)
+
+/*
+ * When verifying attributes we need to use the received order. So we use
+ * SEQUENCE OF and tag it to SET OF
+ */
+
+ASN1_ITEM_TEMPLATE(CMS_Attributes_Verify) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
+                                V_ASN1_SET, CMS_ATTRIBUTES, X509_ATTRIBUTE)
+ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Verify)
+
+
+
+ASN1_CHOICE(CMS_ReceiptsFrom) = {
+  ASN1_IMP(CMS_ReceiptsFrom, d.allOrFirstTier, LONG, 0),
+  ASN1_IMP_SEQUENCE_OF(CMS_ReceiptsFrom, d.receiptList, GENERAL_NAMES, 1)
+} static_ASN1_CHOICE_END(CMS_ReceiptsFrom)
+
+ASN1_SEQUENCE(CMS_ReceiptRequest) = {
+  ASN1_SIMPLE(CMS_ReceiptRequest, signedContentIdentifier, ASN1_OCTET_STRING),
+  ASN1_SIMPLE(CMS_ReceiptRequest, receiptsFrom, CMS_ReceiptsFrom),
+  ASN1_SEQUENCE_OF(CMS_ReceiptRequest, receiptsTo, GENERAL_NAMES)
+} ASN1_SEQUENCE_END(CMS_ReceiptRequest)
+
+ASN1_SEQUENCE(CMS_Receipt) = {
+  ASN1_SIMPLE(CMS_Receipt, version, LONG),
+  ASN1_SIMPLE(CMS_Receipt, contentType, ASN1_OBJECT),
+  ASN1_SIMPLE(CMS_Receipt, signedContentIdentifier, ASN1_OCTET_STRING),
+  ASN1_SIMPLE(CMS_Receipt, originatorSignatureValue, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(CMS_Receipt)
+
+/*
+ * Utilities to encode the CMS_SharedInfo structure used during key
+ * derivation.
+ */
+
+typedef struct {
+    X509_ALGOR *keyInfo;
+    ASN1_OCTET_STRING *entityUInfo;
+    ASN1_OCTET_STRING *suppPubInfo;
+} CMS_SharedInfo;
+
+ASN1_SEQUENCE(CMS_SharedInfo) = {
+  ASN1_SIMPLE(CMS_SharedInfo, keyInfo, X509_ALGOR),
+  ASN1_EXP_OPT(CMS_SharedInfo, entityUInfo, ASN1_OCTET_STRING, 0),
+  ASN1_EXP_OPT(CMS_SharedInfo, suppPubInfo, ASN1_OCTET_STRING, 2),
+} static_ASN1_SEQUENCE_END(CMS_SharedInfo)
+
+int CMS_SharedInfo_encode(unsigned char **pder, X509_ALGOR *kekalg,
+                          ASN1_OCTET_STRING *ukm, int keylen)
+{
+    union {
+        CMS_SharedInfo *pecsi;
+        ASN1_VALUE *a;
+    } intsi = {
+        NULL
+    };
+
+    ASN1_OCTET_STRING oklen;
+    unsigned char kl[4];
+    CMS_SharedInfo ecsi;
+
+    keylen <<= 3;
+    kl[0] = (keylen >> 24) & 0xff;
+    kl[1] = (keylen >> 16) & 0xff;
+    kl[2] = (keylen >> 8) & 0xff;
+    kl[3] = keylen & 0xff;
+    oklen.length = 4;
+    oklen.data = kl;
+    oklen.type = V_ASN1_OCTET_STRING;
+    oklen.flags = 0;
+    ecsi.keyInfo = kekalg;
+    ecsi.entityUInfo = ukm;
+    ecsi.suppPubInfo = &oklen;
+    intsi.pecsi = &ecsi;
+    return ASN1_item_i2d(intsi.a, pder, ASN1_ITEM_rptr(CMS_SharedInfo));
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_att.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_att.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_att.c	(revision 331)
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2008-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 <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include "cms_lcl.h"
+
+/* CMS SignedData Attribute utilities */
+
+int CMS_signed_get_attr_count(const CMS_SignerInfo *si)
+{
+    return X509at_get_attr_count(si->signedAttrs);
+}
+
+int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid, int lastpos)
+{
+    return X509at_get_attr_by_NID(si->signedAttrs, nid, lastpos);
+}
+
+int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, const ASN1_OBJECT *obj,
+                               int lastpos)
+{
+    return X509at_get_attr_by_OBJ(si->signedAttrs, obj, lastpos);
+}
+
+X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc)
+{
+    return X509at_get_attr(si->signedAttrs, loc);
+}
+
+X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc)
+{
+    return X509at_delete_attr(si->signedAttrs, loc);
+}
+
+int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr)
+{
+    if (X509at_add1_attr(&si->signedAttrs, attr))
+        return 1;
+    return 0;
+}
+
+int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
+                                const ASN1_OBJECT *obj, int type,
+                                const void *bytes, int len)
+{
+    if (X509at_add1_attr_by_OBJ(&si->signedAttrs, obj, type, bytes, len))
+        return 1;
+    return 0;
+}
+
+int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
+                                int nid, int type, const void *bytes, int len)
+{
+    if (X509at_add1_attr_by_NID(&si->signedAttrs, nid, type, bytes, len))
+        return 1;
+    return 0;
+}
+
+int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
+                                const char *attrname, int type,
+                                const void *bytes, int len)
+{
+    if (X509at_add1_attr_by_txt(&si->signedAttrs, attrname, type, bytes, len))
+        return 1;
+    return 0;
+}
+
+void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, const ASN1_OBJECT *oid,
+                                  int lastpos, int type)
+{
+    return X509at_get0_data_by_OBJ(si->signedAttrs, oid, lastpos, type);
+}
+
+int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si)
+{
+    return X509at_get_attr_count(si->unsignedAttrs);
+}
+
+int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
+                                 int lastpos)
+{
+    return X509at_get_attr_by_NID(si->unsignedAttrs, nid, lastpos);
+}
+
+int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si,
+                                 const ASN1_OBJECT *obj, int lastpos)
+{
+    return X509at_get_attr_by_OBJ(si->unsignedAttrs, obj, lastpos);
+}
+
+X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc)
+{
+    return X509at_get_attr(si->unsignedAttrs, loc);
+}
+
+X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc)
+{
+    return X509at_delete_attr(si->unsignedAttrs, loc);
+}
+
+int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr)
+{
+    if (X509at_add1_attr(&si->unsignedAttrs, attr))
+        return 1;
+    return 0;
+}
+
+int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
+                                  const ASN1_OBJECT *obj, int type,
+                                  const void *bytes, int len)
+{
+    if (X509at_add1_attr_by_OBJ(&si->unsignedAttrs, obj, type, bytes, len))
+        return 1;
+    return 0;
+}
+
+int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
+                                  int nid, int type,
+                                  const void *bytes, int len)
+{
+    if (X509at_add1_attr_by_NID(&si->unsignedAttrs, nid, type, bytes, len))
+        return 1;
+    return 0;
+}
+
+int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
+                                  const char *attrname, int type,
+                                  const void *bytes, int len)
+{
+    if (X509at_add1_attr_by_txt(&si->unsignedAttrs, attrname,
+                                type, bytes, len))
+        return 1;
+    return 0;
+}
+
+void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
+                                    int lastpos, int type)
+{
+    return X509at_get0_data_by_OBJ(si->unsignedAttrs, oid, lastpos, type);
+}
+
+/* Specific attribute cases */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_cd.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_cd.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_cd.c	(revision 331)
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2008-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 "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include <openssl/bio.h>
+#include <openssl/comp.h>
+#include "cms_lcl.h"
+
+#ifdef ZLIB
+
+/* CMS CompressedData Utilities */
+
+CMS_ContentInfo *cms_CompressedData_create(int comp_nid)
+{
+    CMS_ContentInfo *cms;
+    CMS_CompressedData *cd;
+    /*
+     * Will need something cleverer if there is ever more than one
+     * compression algorithm or parameters have some meaning...
+     */
+    if (comp_nid != NID_zlib_compression) {
+        CMSerr(CMS_F_CMS_COMPRESSEDDATA_CREATE,
+               CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+        return NULL;
+    }
+    cms = CMS_ContentInfo_new();
+    if (cms == NULL)
+        return NULL;
+
+    cd = M_ASN1_new_of(CMS_CompressedData);
+
+    if (cd == NULL)
+        goto err;
+
+    cms->contentType = OBJ_nid2obj(NID_id_smime_ct_compressedData);
+    cms->d.compressedData = cd;
+
+    cd->version = 0;
+
+    X509_ALGOR_set0(cd->compressionAlgorithm,
+                    OBJ_nid2obj(NID_zlib_compression), V_ASN1_UNDEF, NULL);
+
+    cd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data);
+
+    return cms;
+
+ err:
+    CMS_ContentInfo_free(cms);
+    return NULL;
+}
+
+BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms)
+{
+    CMS_CompressedData *cd;
+    const ASN1_OBJECT *compoid;
+    if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_compressedData) {
+        CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO,
+               CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA);
+        return NULL;
+    }
+    cd = cms->d.compressedData;
+    X509_ALGOR_get0(&compoid, NULL, NULL, cd->compressionAlgorithm);
+    if (OBJ_obj2nid(compoid) != NID_zlib_compression) {
+        CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO,
+               CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+        return NULL;
+    }
+    return BIO_new(BIO_f_zlib());
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_dd.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_dd.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_dd.c	(revision 331)
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2008-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 "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include "cms_lcl.h"
+
+/* CMS DigestedData Utilities */
+
+CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md)
+{
+    CMS_ContentInfo *cms;
+    CMS_DigestedData *dd;
+    cms = CMS_ContentInfo_new();
+    if (cms == NULL)
+        return NULL;
+
+    dd = M_ASN1_new_of(CMS_DigestedData);
+
+    if (dd == NULL)
+        goto err;
+
+    cms->contentType = OBJ_nid2obj(NID_pkcs7_digest);
+    cms->d.digestedData = dd;
+
+    dd->version = 0;
+    dd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data);
+
+    X509_ALGOR_set_md(dd->digestAlgorithm, md);
+
+    return cms;
+
+ err:
+    CMS_ContentInfo_free(cms);
+    return NULL;
+}
+
+BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms)
+{
+    CMS_DigestedData *dd;
+    dd = cms->d.digestedData;
+    return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm);
+}
+
+int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify)
+{
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+    unsigned char md[EVP_MAX_MD_SIZE];
+    unsigned int mdlen;
+    int r = 0;
+    CMS_DigestedData *dd;
+
+    if (mctx == NULL) {
+        CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    dd = cms->d.digestedData;
+
+    if (!cms_DigestAlgorithm_find_ctx(mctx, chain, dd->digestAlgorithm))
+        goto err;
+
+    if (EVP_DigestFinal_ex(mctx, md, &mdlen) <= 0)
+        goto err;
+
+    if (verify) {
+        if (mdlen != (unsigned int)dd->digest->length) {
+            CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
+                   CMS_R_MESSAGEDIGEST_WRONG_LENGTH);
+            goto err;
+        }
+
+        if (memcmp(md, dd->digest->data, mdlen))
+            CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
+                   CMS_R_VERIFICATION_FAILURE);
+        else
+            r = 1;
+    } else {
+        if (!ASN1_STRING_set(dd->digest, md, mdlen))
+            goto err;
+        r = 1;
+    }
+
+ err:
+    EVP_MD_CTX_free(mctx);
+
+    return r;
+
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_enc.c	(revision 331)
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2008-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 "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include <openssl/rand.h>
+#include "cms_lcl.h"
+
+/* CMS EncryptedData Utilities */
+
+/* Return BIO based on EncryptedContentInfo and key */
+
+BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
+{
+    BIO *b;
+    EVP_CIPHER_CTX *ctx;
+    const EVP_CIPHER *ciph;
+    X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
+    unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL;
+    unsigned char *tkey = NULL;
+    size_t tkeylen = 0;
+
+    int ok = 0;
+
+    int enc, keep_key = 0;
+
+    enc = ec->cipher ? 1 : 0;
+
+    b = BIO_new(BIO_f_cipher());
+    if (b == NULL) {
+        CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    BIO_get_cipher_ctx(b, &ctx);
+
+    if (enc) {
+        ciph = ec->cipher;
+        /*
+         * If not keeping key set cipher to NULL so subsequent calls decrypt.
+         */
+        if (ec->key)
+            ec->cipher = NULL;
+    } else {
+        ciph = EVP_get_cipherbyobj(calg->algorithm);
+
+        if (!ciph) {
+            CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_UNKNOWN_CIPHER);
+            goto err;
+        }
+    }
+
+    if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) {
+        CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+               CMS_R_CIPHER_INITIALISATION_ERROR);
+        goto err;
+    }
+
+    if (enc) {
+        int ivlen;
+        calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx));
+        /* Generate a random IV if we need one */
+        ivlen = EVP_CIPHER_CTX_iv_length(ctx);
+        if (ivlen > 0) {
+            if (RAND_bytes(iv, ivlen) <= 0)
+                goto err;
+            piv = iv;
+        }
+    } else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0) {
+        CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+               CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
+        goto err;
+    }
+    tkeylen = EVP_CIPHER_CTX_key_length(ctx);
+    /* Generate random session key */
+    if (!enc || !ec->key) {
+        tkey = OPENSSL_malloc(tkeylen);
+        if (tkey == NULL) {
+            CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0)
+            goto err;
+    }
+
+    if (!ec->key) {
+        ec->key = tkey;
+        ec->keylen = tkeylen;
+        tkey = NULL;
+        if (enc)
+            keep_key = 1;
+        else
+            ERR_clear_error();
+
+    }
+
+    if (ec->keylen != tkeylen) {
+        /* If necessary set key length */
+        if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0) {
+            /*
+             * Only reveal failure if debugging so we don't leak information
+             * which may be useful in MMA.
+             */
+            if (enc || ec->debug) {
+                CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+                       CMS_R_INVALID_KEY_LENGTH);
+                goto err;
+            } else {
+                /* Use random key */
+                OPENSSL_clear_free(ec->key, ec->keylen);
+                ec->key = tkey;
+                ec->keylen = tkeylen;
+                tkey = NULL;
+                ERR_clear_error();
+            }
+        }
+    }
+
+    if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0) {
+        CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+               CMS_R_CIPHER_INITIALISATION_ERROR);
+        goto err;
+    }
+    if (enc) {
+        calg->parameter = ASN1_TYPE_new();
+        if (calg->parameter == NULL) {
+            CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0) {
+            CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+                   CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
+            goto err;
+        }
+        /* If parameter type not set omit parameter */
+        if (calg->parameter->type == V_ASN1_UNDEF) {
+            ASN1_TYPE_free(calg->parameter);
+            calg->parameter = NULL;
+        }
+    }
+    ok = 1;
+
+ err:
+    if (!keep_key || !ok) {
+        OPENSSL_clear_free(ec->key, ec->keylen);
+        ec->key = NULL;
+    }
+    OPENSSL_clear_free(tkey, tkeylen);
+    if (ok)
+        return b;
+    BIO_free(b);
+    return NULL;
+}
+
+int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
+                              const EVP_CIPHER *cipher,
+                              const unsigned char *key, size_t keylen)
+{
+    ec->cipher = cipher;
+    if (key) {
+        ec->key = OPENSSL_malloc(keylen);
+        if (ec->key == NULL)
+            return 0;
+        memcpy(ec->key, key, keylen);
+    }
+    ec->keylen = keylen;
+    if (cipher)
+        ec->contentType = OBJ_nid2obj(NID_pkcs7_data);
+    return 1;
+}
+
+int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
+                               const unsigned char *key, size_t keylen)
+{
+    CMS_EncryptedContentInfo *ec;
+    if (!key || !keylen) {
+        CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NO_KEY);
+        return 0;
+    }
+    if (ciph) {
+        cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData);
+        if (!cms->d.encryptedData) {
+            CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted);
+        cms->d.encryptedData->version = 0;
+    } else if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted) {
+        CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NOT_ENCRYPTED_DATA);
+        return 0;
+    }
+    ec = cms->d.encryptedData->encryptedContentInfo;
+    return cms_EncryptedContent_init(ec, ciph, key, keylen);
+}
+
+BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms)
+{
+    CMS_EncryptedData *enc = cms->d.encryptedData;
+    if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs)
+        enc->version = 2;
+    return cms_EncryptedContent_init_bio(enc->encryptedContentInfo);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_env.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_env.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_env.c	(revision 331)
@@ -0,0 +1,902 @@
+/*
+ * Copyright 2008-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 "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include <openssl/aes.h>
+#include "cms_lcl.h"
+#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
+
+/* CMS EnvelopedData Utilities */
+
+CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms)
+{
+    if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) {
+        CMSerr(CMS_F_CMS_GET0_ENVELOPED,
+               CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA);
+        return NULL;
+    }
+    return cms->d.envelopedData;
+}
+
+static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
+{
+    if (cms->d.other == NULL) {
+        cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData);
+        if (!cms->d.envelopedData) {
+            CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT, ERR_R_MALLOC_FAILURE);
+            return NULL;
+        }
+        cms->d.envelopedData->version = 0;
+        cms->d.envelopedData->encryptedContentInfo->contentType =
+            OBJ_nid2obj(NID_pkcs7_data);
+        ASN1_OBJECT_free(cms->contentType);
+        cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped);
+        return cms->d.envelopedData;
+    }
+    return cms_get0_enveloped(cms);
+}
+
+int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd)
+{
+    EVP_PKEY *pkey;
+    int i;
+    if (ri->type == CMS_RECIPINFO_TRANS)
+        pkey = ri->d.ktri->pkey;
+    else if (ri->type == CMS_RECIPINFO_AGREE) {
+        EVP_PKEY_CTX *pctx = ri->d.kari->pctx;
+        if (!pctx)
+            return 0;
+        pkey = EVP_PKEY_CTX_get0_pkey(pctx);
+        if (!pkey)
+            return 0;
+    } else
+        return 0;
+    if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
+        return 1;
+    i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri);
+    if (i == -2) {
+        CMSerr(CMS_F_CMS_ENV_ASN1_CTRL,
+               CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+        return 0;
+    }
+    if (i <= 0) {
+        CMSerr(CMS_F_CMS_ENV_ASN1_CTRL, CMS_R_CTRL_FAILURE);
+        return 0;
+    }
+    return 1;
+}
+
+STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
+{
+    CMS_EnvelopedData *env;
+    env = cms_get0_enveloped(cms);
+    if (!env)
+        return NULL;
+    return env->recipientInfos;
+}
+
+int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
+{
+    return ri->type;
+}
+
+EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri)
+{
+    if (ri->type == CMS_RECIPINFO_TRANS)
+        return ri->d.ktri->pctx;
+    else if (ri->type == CMS_RECIPINFO_AGREE)
+        return ri->d.kari->pctx;
+    return NULL;
+}
+
+CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
+{
+    CMS_ContentInfo *cms;
+    CMS_EnvelopedData *env;
+    cms = CMS_ContentInfo_new();
+    if (cms == NULL)
+        goto merr;
+    env = cms_enveloped_data_init(cms);
+    if (env == NULL)
+        goto merr;
+    if (!cms_EncryptedContent_init(env->encryptedContentInfo,
+                                   cipher, NULL, 0))
+        goto merr;
+    return cms;
+ merr:
+    CMS_ContentInfo_free(cms);
+    CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE);
+    return NULL;
+}
+
+/* Key Transport Recipient Info (KTRI) routines */
+
+/* Initialise a ktri based on passed certificate and key */
+
+static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip,
+                                       EVP_PKEY *pk, unsigned int flags)
+{
+    CMS_KeyTransRecipientInfo *ktri;
+    int idtype;
+
+    ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo);
+    if (!ri->d.ktri)
+        return 0;
+    ri->type = CMS_RECIPINFO_TRANS;
+
+    ktri = ri->d.ktri;
+
+    if (flags & CMS_USE_KEYID) {
+        ktri->version = 2;
+        idtype = CMS_RECIPINFO_KEYIDENTIFIER;
+    } else {
+        ktri->version = 0;
+        idtype = CMS_RECIPINFO_ISSUER_SERIAL;
+    }
+
+    /*
+     * Not a typo: RecipientIdentifier and SignerIdentifier are the same
+     * structure.
+     */
+
+    if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype))
+        return 0;
+
+    X509_up_ref(recip);
+    EVP_PKEY_up_ref(pk);
+
+    ktri->pkey = pk;
+    ktri->recip = recip;
+
+    if (flags & CMS_KEY_PARAM) {
+        ktri->pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
+        if (ktri->pctx == NULL)
+            return 0;
+        if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0)
+            return 0;
+    } else if (!cms_env_asn1_ctrl(ri, 0))
+        return 0;
+    return 1;
+}
+
+/*
+ * Add a recipient certificate using appropriate type of RecipientInfo
+ */
+
+CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
+                                           X509 *recip, unsigned int flags)
+{
+    CMS_RecipientInfo *ri = NULL;
+    CMS_EnvelopedData *env;
+    EVP_PKEY *pk = NULL;
+    env = cms_get0_enveloped(cms);
+    if (!env)
+        goto err;
+
+    /* Initialize recipient info */
+    ri = M_ASN1_new_of(CMS_RecipientInfo);
+    if (!ri)
+        goto merr;
+
+    pk = X509_get0_pubkey(recip);
+    if (!pk) {
+        CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, CMS_R_ERROR_GETTING_PUBLIC_KEY);
+        goto err;
+    }
+
+    switch (cms_pkey_get_ri_type(pk)) {
+
+    case CMS_RECIPINFO_TRANS:
+        if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags))
+            goto err;
+        break;
+
+    case CMS_RECIPINFO_AGREE:
+        if (!cms_RecipientInfo_kari_init(ri, recip, pk, flags))
+            goto err;
+        break;
+
+    default:
+        CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
+               CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+        goto err;
+
+    }
+
+    if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
+        goto merr;
+
+    return ri;
+
+ merr:
+    CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE);
+ err:
+    M_ASN1_free_of(ri, CMS_RecipientInfo);
+    return NULL;
+
+}
+
+int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
+                                     EVP_PKEY **pk, X509 **recip,
+                                     X509_ALGOR **palg)
+{
+    CMS_KeyTransRecipientInfo *ktri;
+    if (ri->type != CMS_RECIPINFO_TRANS) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS,
+               CMS_R_NOT_KEY_TRANSPORT);
+        return 0;
+    }
+
+    ktri = ri->d.ktri;
+
+    if (pk)
+        *pk = ktri->pkey;
+    if (recip)
+        *recip = ktri->recip;
+    if (palg)
+        *palg = ktri->keyEncryptionAlgorithm;
+    return 1;
+}
+
+int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
+                                          ASN1_OCTET_STRING **keyid,
+                                          X509_NAME **issuer,
+                                          ASN1_INTEGER **sno)
+{
+    CMS_KeyTransRecipientInfo *ktri;
+    if (ri->type != CMS_RECIPINFO_TRANS) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID,
+               CMS_R_NOT_KEY_TRANSPORT);
+        return 0;
+    }
+    ktri = ri->d.ktri;
+
+    return cms_SignerIdentifier_get0_signer_id(ktri->rid, keyid, issuer, sno);
+}
+
+int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
+{
+    if (ri->type != CMS_RECIPINFO_TRANS) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP,
+               CMS_R_NOT_KEY_TRANSPORT);
+        return -2;
+    }
+    return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
+}
+
+int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey)
+{
+    if (ri->type != CMS_RECIPINFO_TRANS) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY, CMS_R_NOT_KEY_TRANSPORT);
+        return 0;
+    }
+    ri->d.ktri->pkey = pkey;
+    return 1;
+}
+
+/* Encrypt content key in key transport recipient info */
+
+static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
+                                          CMS_RecipientInfo *ri)
+{
+    CMS_KeyTransRecipientInfo *ktri;
+    CMS_EncryptedContentInfo *ec;
+    EVP_PKEY_CTX *pctx;
+    unsigned char *ek = NULL;
+    size_t eklen;
+
+    int ret = 0;
+
+    if (ri->type != CMS_RECIPINFO_TRANS) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_NOT_KEY_TRANSPORT);
+        return 0;
+    }
+    ktri = ri->d.ktri;
+    ec = cms->d.envelopedData->encryptedContentInfo;
+
+    pctx = ktri->pctx;
+
+    if (pctx) {
+        if (!cms_env_asn1_ctrl(ri, 0))
+            goto err;
+    } else {
+        pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
+        if (pctx == NULL)
+            return 0;
+
+        if (EVP_PKEY_encrypt_init(pctx) <= 0)
+            goto err;
+    }
+
+    if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
+                          EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR);
+        goto err;
+    }
+
+    if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0)
+        goto err;
+
+    ek = OPENSSL_malloc(eklen);
+
+    if (ek == NULL) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0)
+        goto err;
+
+    ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
+    ek = NULL;
+
+    ret = 1;
+
+ err:
+    EVP_PKEY_CTX_free(pctx);
+    ktri->pctx = NULL;
+    OPENSSL_free(ek);
+    return ret;
+
+}
+
+/* Decrypt content key from KTRI */
+
+static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
+                                          CMS_RecipientInfo *ri)
+{
+    CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
+    EVP_PKEY *pkey = ktri->pkey;
+    unsigned char *ek = NULL;
+    size_t eklen;
+    int ret = 0;
+    CMS_EncryptedContentInfo *ec;
+    ec = cms->d.envelopedData->encryptedContentInfo;
+
+    if (ktri->pkey == NULL) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_NO_PRIVATE_KEY);
+        return 0;
+    }
+
+    ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL);
+    if (ktri->pctx == NULL)
+        return 0;
+
+    if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0)
+        goto err;
+
+    if (!cms_env_asn1_ctrl(ri, 1))
+        goto err;
+
+    if (EVP_PKEY_CTX_ctrl(ktri->pctx, -1, EVP_PKEY_OP_DECRYPT,
+                          EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR);
+        goto err;
+    }
+
+    if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen,
+                         ktri->encryptedKey->data,
+                         ktri->encryptedKey->length) <= 0)
+        goto err;
+
+    ek = OPENSSL_malloc(eklen);
+
+    if (ek == NULL) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen,
+                         ktri->encryptedKey->data,
+                         ktri->encryptedKey->length) <= 0) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
+        goto err;
+    }
+
+    ret = 1;
+
+    OPENSSL_clear_free(ec->key, ec->keylen);
+    ec->key = ek;
+    ec->keylen = eklen;
+
+ err:
+    EVP_PKEY_CTX_free(ktri->pctx);
+    ktri->pctx = NULL;
+    if (!ret)
+        OPENSSL_free(ek);
+
+    return ret;
+}
+
+/* Key Encrypted Key (KEK) RecipientInfo routines */
+
+int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,
+                                   const unsigned char *id, size_t idlen)
+{
+    ASN1_OCTET_STRING tmp_os;
+    CMS_KEKRecipientInfo *kekri;
+    if (ri->type != CMS_RECIPINFO_KEK) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK);
+        return -2;
+    }
+    kekri = ri->d.kekri;
+    tmp_os.type = V_ASN1_OCTET_STRING;
+    tmp_os.flags = 0;
+    tmp_os.data = (unsigned char *)id;
+    tmp_os.length = (int)idlen;
+    return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier);
+}
+
+/* For now hard code AES key wrap info */
+
+static size_t aes_wrap_keylen(int nid)
+{
+    switch (nid) {
+    case NID_id_aes128_wrap:
+        return 16;
+
+    case NID_id_aes192_wrap:
+        return 24;
+
+    case NID_id_aes256_wrap:
+        return 32;
+
+    default:
+        return 0;
+    }
+}
+
+CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
+                                          unsigned char *key, size_t keylen,
+                                          unsigned char *id, size_t idlen,
+                                          ASN1_GENERALIZEDTIME *date,
+                                          ASN1_OBJECT *otherTypeId,
+                                          ASN1_TYPE *otherType)
+{
+    CMS_RecipientInfo *ri = NULL;
+    CMS_EnvelopedData *env;
+    CMS_KEKRecipientInfo *kekri;
+    env = cms_get0_enveloped(cms);
+    if (!env)
+        goto err;
+
+    if (nid == NID_undef) {
+        switch (keylen) {
+        case 16:
+            nid = NID_id_aes128_wrap;
+            break;
+
+        case 24:
+            nid = NID_id_aes192_wrap;
+            break;
+
+        case 32:
+            nid = NID_id_aes256_wrap;
+            break;
+
+        default:
+            CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH);
+            goto err;
+        }
+
+    } else {
+
+        size_t exp_keylen = aes_wrap_keylen(nid);
+
+        if (!exp_keylen) {
+            CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
+                   CMS_R_UNSUPPORTED_KEK_ALGORITHM);
+            goto err;
+        }
+
+        if (keylen != exp_keylen) {
+            CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH);
+            goto err;
+        }
+
+    }
+
+    /* Initialize recipient info */
+    ri = M_ASN1_new_of(CMS_RecipientInfo);
+    if (!ri)
+        goto merr;
+
+    ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo);
+    if (!ri->d.kekri)
+        goto merr;
+    ri->type = CMS_RECIPINFO_KEK;
+
+    kekri = ri->d.kekri;
+
+    if (otherTypeId) {
+        kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute);
+        if (kekri->kekid->other == NULL)
+            goto merr;
+    }
+
+    if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
+        goto merr;
+
+    /* After this point no calls can fail */
+
+    kekri->version = 4;
+
+    kekri->key = key;
+    kekri->keylen = keylen;
+
+    ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen);
+
+    kekri->kekid->date = date;
+
+    if (kekri->kekid->other) {
+        kekri->kekid->other->keyAttrId = otherTypeId;
+        kekri->kekid->other->keyAttr = otherType;
+    }
+
+    X509_ALGOR_set0(kekri->keyEncryptionAlgorithm,
+                    OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL);
+
+    return ri;
+
+ merr:
+    CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE);
+ err:
+    M_ASN1_free_of(ri, CMS_RecipientInfo);
+    return NULL;
+
+}
+
+int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
+                                    X509_ALGOR **palg,
+                                    ASN1_OCTET_STRING **pid,
+                                    ASN1_GENERALIZEDTIME **pdate,
+                                    ASN1_OBJECT **potherid,
+                                    ASN1_TYPE **pothertype)
+{
+    CMS_KEKIdentifier *rkid;
+    if (ri->type != CMS_RECIPINFO_KEK) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK);
+        return 0;
+    }
+    rkid = ri->d.kekri->kekid;
+    if (palg)
+        *palg = ri->d.kekri->keyEncryptionAlgorithm;
+    if (pid)
+        *pid = rkid->keyIdentifier;
+    if (pdate)
+        *pdate = rkid->date;
+    if (potherid) {
+        if (rkid->other)
+            *potherid = rkid->other->keyAttrId;
+        else
+            *potherid = NULL;
+    }
+    if (pothertype) {
+        if (rkid->other)
+            *pothertype = rkid->other->keyAttr;
+        else
+            *pothertype = NULL;
+    }
+    return 1;
+}
+
+int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
+                               unsigned char *key, size_t keylen)
+{
+    CMS_KEKRecipientInfo *kekri;
+    if (ri->type != CMS_RECIPINFO_KEK) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK);
+        return 0;
+    }
+
+    kekri = ri->d.kekri;
+    kekri->key = key;
+    kekri->keylen = keylen;
+    return 1;
+}
+
+/* Encrypt content key in KEK recipient info */
+
+static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms,
+                                           CMS_RecipientInfo *ri)
+{
+    CMS_EncryptedContentInfo *ec;
+    CMS_KEKRecipientInfo *kekri;
+    AES_KEY actx;
+    unsigned char *wkey = NULL;
+    int wkeylen;
+    int r = 0;
+
+    ec = cms->d.envelopedData->encryptedContentInfo;
+
+    kekri = ri->d.kekri;
+
+    if (!kekri->key) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY);
+        return 0;
+    }
+
+    if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx)) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
+               CMS_R_ERROR_SETTING_KEY);
+        goto err;
+    }
+
+    wkey = OPENSSL_malloc(ec->keylen + 8);
+
+    if (wkey == NULL) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen);
+
+    if (wkeylen <= 0) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR);
+        goto err;
+    }
+
+    ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen);
+
+    r = 1;
+
+ err:
+
+    if (!r)
+        OPENSSL_free(wkey);
+    OPENSSL_cleanse(&actx, sizeof(actx));
+
+    return r;
+
+}
+
+/* Decrypt content key in KEK recipient info */
+
+static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
+                                           CMS_RecipientInfo *ri)
+{
+    CMS_EncryptedContentInfo *ec;
+    CMS_KEKRecipientInfo *kekri;
+    AES_KEY actx;
+    unsigned char *ukey = NULL;
+    int ukeylen;
+    int r = 0, wrap_nid;
+
+    ec = cms->d.envelopedData->encryptedContentInfo;
+
+    kekri = ri->d.kekri;
+
+    if (!kekri->key) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY);
+        return 0;
+    }
+
+    wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm);
+    if (aes_wrap_keylen(wrap_nid) != kekri->keylen) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
+               CMS_R_INVALID_KEY_LENGTH);
+        return 0;
+    }
+
+    /* If encrypted key length is invalid don't bother */
+
+    if (kekri->encryptedKey->length < 16) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
+               CMS_R_INVALID_ENCRYPTED_KEY_LENGTH);
+        goto err;
+    }
+
+    if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx)) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
+               CMS_R_ERROR_SETTING_KEY);
+        goto err;
+    }
+
+    ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);
+
+    if (ukey == NULL) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    ukeylen = AES_unwrap_key(&actx, NULL, ukey,
+                             kekri->encryptedKey->data,
+                             kekri->encryptedKey->length);
+
+    if (ukeylen <= 0) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_UNWRAP_ERROR);
+        goto err;
+    }
+
+    ec->key = ukey;
+    ec->keylen = ukeylen;
+
+    r = 1;
+
+ err:
+
+    if (!r)
+        OPENSSL_free(ukey);
+    OPENSSL_cleanse(&actx, sizeof(actx));
+
+    return r;
+
+}
+
+int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
+{
+    switch (ri->type) {
+    case CMS_RECIPINFO_TRANS:
+        return cms_RecipientInfo_ktri_decrypt(cms, ri);
+
+    case CMS_RECIPINFO_KEK:
+        return cms_RecipientInfo_kekri_decrypt(cms, ri);
+
+    case CMS_RECIPINFO_PASS:
+        return cms_RecipientInfo_pwri_crypt(cms, ri, 0);
+
+    default:
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
+               CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE);
+        return 0;
+    }
+}
+
+int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
+{
+    switch (ri->type) {
+    case CMS_RECIPINFO_TRANS:
+        return cms_RecipientInfo_ktri_encrypt(cms, ri);
+
+    case CMS_RECIPINFO_AGREE:
+        return cms_RecipientInfo_kari_encrypt(cms, ri);
+
+    case CMS_RECIPINFO_KEK:
+        return cms_RecipientInfo_kekri_encrypt(cms, ri);
+
+    case CMS_RECIPINFO_PASS:
+        return cms_RecipientInfo_pwri_crypt(cms, ri, 1);
+
+    default:
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_ENCRYPT,
+               CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
+        return 0;
+    }
+}
+
+/* Check structures and fixup version numbers (if necessary) */
+
+static void cms_env_set_originfo_version(CMS_EnvelopedData *env)
+{
+    CMS_OriginatorInfo *org = env->originatorInfo;
+    int i;
+    if (org == NULL)
+        return;
+    for (i = 0; i < sk_CMS_CertificateChoices_num(org->certificates); i++) {
+        CMS_CertificateChoices *cch;
+        cch = sk_CMS_CertificateChoices_value(org->certificates, i);
+        if (cch->type == CMS_CERTCHOICE_OTHER) {
+            env->version = 4;
+            return;
+        } else if (cch->type == CMS_CERTCHOICE_V2ACERT) {
+            if (env->version < 3)
+                env->version = 3;
+        }
+    }
+
+    for (i = 0; i < sk_CMS_RevocationInfoChoice_num(org->crls); i++) {
+        CMS_RevocationInfoChoice *rch;
+        rch = sk_CMS_RevocationInfoChoice_value(org->crls, i);
+        if (rch->type == CMS_REVCHOICE_OTHER) {
+            env->version = 4;
+            return;
+        }
+    }
+}
+
+static void cms_env_set_version(CMS_EnvelopedData *env)
+{
+    int i;
+    CMS_RecipientInfo *ri;
+
+    /*
+     * Can't set version higher than 4 so if 4 or more already nothing to do.
+     */
+    if (env->version >= 4)
+        return;
+
+    cms_env_set_originfo_version(env);
+
+    if (env->version >= 3)
+        return;
+
+    for (i = 0; i < sk_CMS_RecipientInfo_num(env->recipientInfos); i++) {
+        ri = sk_CMS_RecipientInfo_value(env->recipientInfos, i);
+        if (ri->type == CMS_RECIPINFO_PASS || ri->type == CMS_RECIPINFO_OTHER) {
+            env->version = 3;
+            return;
+        } else if (ri->type != CMS_RECIPINFO_TRANS
+                   || ri->d.ktri->version != 0) {
+            env->version = 2;
+        }
+    }
+    if (env->originatorInfo || env->unprotectedAttrs)
+        env->version = 2;
+    if (env->version == 2)
+        return;
+    env->version = 0;
+}
+
+BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
+{
+    CMS_EncryptedContentInfo *ec;
+    STACK_OF(CMS_RecipientInfo) *rinfos;
+    CMS_RecipientInfo *ri;
+    int i, ok = 0;
+    BIO *ret;
+
+    /* Get BIO first to set up key */
+
+    ec = cms->d.envelopedData->encryptedContentInfo;
+    ret = cms_EncryptedContent_init_bio(ec);
+
+    /* If error or no cipher end of processing */
+
+    if (!ret || !ec->cipher)
+        return ret;
+
+    /* Now encrypt content key according to each RecipientInfo type */
+
+    rinfos = cms->d.envelopedData->recipientInfos;
+
+    for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) {
+        ri = sk_CMS_RecipientInfo_value(rinfos, i);
+        if (CMS_RecipientInfo_encrypt(cms, ri) <= 0) {
+            CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
+                   CMS_R_ERROR_SETTING_RECIPIENTINFO);
+            goto err;
+        }
+    }
+    cms_env_set_version(cms->d.envelopedData);
+
+    ok = 1;
+
+ err:
+    ec->cipher = NULL;
+    OPENSSL_clear_free(ec->key, ec->keylen);
+    ec->key = NULL;
+    ec->keylen = 0;
+    if (ok)
+        return ret;
+    BIO_free(ret);
+    return NULL;
+
+}
+
+/*
+ * Get RecipientInfo type (if any) supported by a key (public or private). To
+ * retain compatibility with previous behaviour if the ctrl value isn't
+ * supported we assume key transport.
+ */
+int cms_pkey_get_ri_type(EVP_PKEY *pk)
+{
+    if (pk->ameth && pk->ameth->pkey_ctrl) {
+        int i, r;
+        i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_RI_TYPE, 0, &r);
+        if (i > 0)
+            return r;
+    }
+    return CMS_RECIPINFO_TRANS;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_err.c	(revision 331)
@@ -0,0 +1,258 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_CMS,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_CMS,0,reason)
+
+static ERR_STRING_DATA CMS_str_functs[] = {
+    {ERR_FUNC(CMS_F_CHECK_CONTENT), "check_content"},
+    {ERR_FUNC(CMS_F_CMS_ADD0_CERT), "CMS_add0_cert"},
+    {ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_KEY), "CMS_add0_recipient_key"},
+    {ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD),
+     "CMS_add0_recipient_password"},
+    {ERR_FUNC(CMS_F_CMS_ADD1_RECEIPTREQUEST), "CMS_add1_ReceiptRequest"},
+    {ERR_FUNC(CMS_F_CMS_ADD1_RECIPIENT_CERT), "CMS_add1_recipient_cert"},
+    {ERR_FUNC(CMS_F_CMS_ADD1_SIGNER), "CMS_add1_signer"},
+    {ERR_FUNC(CMS_F_CMS_ADD1_SIGNINGTIME), "cms_add1_signingTime"},
+    {ERR_FUNC(CMS_F_CMS_COMPRESS), "CMS_compress"},
+    {ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_CREATE), "cms_CompressedData_create"},
+    {ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO),
+     "cms_CompressedData_init_bio"},
+    {ERR_FUNC(CMS_F_CMS_COPY_CONTENT), "cms_copy_content"},
+    {ERR_FUNC(CMS_F_CMS_COPY_MESSAGEDIGEST), "cms_copy_messageDigest"},
+    {ERR_FUNC(CMS_F_CMS_DATA), "CMS_data"},
+    {ERR_FUNC(CMS_F_CMS_DATAFINAL), "CMS_dataFinal"},
+    {ERR_FUNC(CMS_F_CMS_DATAINIT), "CMS_dataInit"},
+    {ERR_FUNC(CMS_F_CMS_DECRYPT), "CMS_decrypt"},
+    {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_KEY), "CMS_decrypt_set1_key"},
+    {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PASSWORD), "CMS_decrypt_set1_password"},
+    {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PKEY), "CMS_decrypt_set1_pkey"},
+    {ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX),
+     "cms_DigestAlgorithm_find_ctx"},
+    {ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO),
+     "cms_DigestAlgorithm_init_bio"},
+    {ERR_FUNC(CMS_F_CMS_DIGESTEDDATA_DO_FINAL), "cms_DigestedData_do_final"},
+    {ERR_FUNC(CMS_F_CMS_DIGEST_VERIFY), "CMS_digest_verify"},
+    {ERR_FUNC(CMS_F_CMS_ENCODE_RECEIPT), "cms_encode_Receipt"},
+    {ERR_FUNC(CMS_F_CMS_ENCRYPT), "CMS_encrypt"},
+    {ERR_FUNC(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO),
+     "cms_EncryptedContent_init_bio"},
+    {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT), "CMS_EncryptedData_decrypt"},
+    {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT), "CMS_EncryptedData_encrypt"},
+    {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY),
+     "CMS_EncryptedData_set1_key"},
+    {ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_CREATE), "CMS_EnvelopedData_create"},
+    {ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO),
+     "cms_EnvelopedData_init_bio"},
+    {ERR_FUNC(CMS_F_CMS_ENVELOPED_DATA_INIT), "cms_enveloped_data_init"},
+    {ERR_FUNC(CMS_F_CMS_ENV_ASN1_CTRL), "cms_env_asn1_ctrl"},
+    {ERR_FUNC(CMS_F_CMS_FINAL), "CMS_final"},
+    {ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES),
+     "cms_get0_certificate_choices"},
+    {ERR_FUNC(CMS_F_CMS_GET0_CONTENT), "CMS_get0_content"},
+    {ERR_FUNC(CMS_F_CMS_GET0_ECONTENT_TYPE), "cms_get0_econtent_type"},
+    {ERR_FUNC(CMS_F_CMS_GET0_ENVELOPED), "cms_get0_enveloped"},
+    {ERR_FUNC(CMS_F_CMS_GET0_REVOCATION_CHOICES),
+     "cms_get0_revocation_choices"},
+    {ERR_FUNC(CMS_F_CMS_GET0_SIGNED), "cms_get0_signed"},
+    {ERR_FUNC(CMS_F_CMS_MSGSIGDIGEST_ADD1), "cms_msgSigDigest_add1"},
+    {ERR_FUNC(CMS_F_CMS_RECEIPTREQUEST_CREATE0),
+     "CMS_ReceiptRequest_create0"},
+    {ERR_FUNC(CMS_F_CMS_RECEIPT_VERIFY), "cms_Receipt_verify"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_DECRYPT), "CMS_RecipientInfo_decrypt"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_ENCRYPT), "CMS_RecipientInfo_encrypt"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT),
+     "cms_RecipientInfo_kari_encrypt"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG),
+     "CMS_RecipientInfo_kari_get0_alg"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID),
+     "CMS_RecipientInfo_kari_get0_orig_id"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS),
+     "CMS_RecipientInfo_kari_get0_reks"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP),
+     "CMS_RecipientInfo_kari_orig_id_cmp"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT),
+     "cms_RecipientInfo_kekri_decrypt"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT),
+     "cms_RecipientInfo_kekri_encrypt"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID),
+     "CMS_RecipientInfo_kekri_get0_id"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP),
+     "CMS_RecipientInfo_kekri_id_cmp"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP),
+     "CMS_RecipientInfo_ktri_cert_cmp"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT),
+     "cms_RecipientInfo_ktri_decrypt"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT),
+     "cms_RecipientInfo_ktri_encrypt"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS),
+     "CMS_RecipientInfo_ktri_get0_algs"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID),
+     "CMS_RecipientInfo_ktri_get0_signer_id"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT),
+     "cms_RecipientInfo_pwri_crypt"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_KEY),
+     "CMS_RecipientInfo_set0_key"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD),
+     "CMS_RecipientInfo_set0_password"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY),
+     "CMS_RecipientInfo_set0_pkey"},
+    {ERR_FUNC(CMS_F_CMS_SD_ASN1_CTRL), "cms_sd_asn1_ctrl"},
+    {ERR_FUNC(CMS_F_CMS_SET1_IAS), "cms_set1_ias"},
+    {ERR_FUNC(CMS_F_CMS_SET1_KEYID), "cms_set1_keyid"},
+    {ERR_FUNC(CMS_F_CMS_SET1_SIGNERIDENTIFIER), "cms_set1_SignerIdentifier"},
+    {ERR_FUNC(CMS_F_CMS_SET_DETACHED), "CMS_set_detached"},
+    {ERR_FUNC(CMS_F_CMS_SIGN), "CMS_sign"},
+    {ERR_FUNC(CMS_F_CMS_SIGNED_DATA_INIT), "cms_signed_data_init"},
+    {ERR_FUNC(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN),
+     "cms_SignerInfo_content_sign"},
+    {ERR_FUNC(CMS_F_CMS_SIGNERINFO_SIGN), "CMS_SignerInfo_sign"},
+    {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY), "CMS_SignerInfo_verify"},
+    {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CERT),
+     "cms_signerinfo_verify_cert"},
+    {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT),
+     "CMS_SignerInfo_verify_content"},
+    {ERR_FUNC(CMS_F_CMS_SIGN_RECEIPT), "CMS_sign_receipt"},
+    {ERR_FUNC(CMS_F_CMS_STREAM), "CMS_stream"},
+    {ERR_FUNC(CMS_F_CMS_UNCOMPRESS), "CMS_uncompress"},
+    {ERR_FUNC(CMS_F_CMS_VERIFY), "CMS_verify"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA CMS_str_reasons[] = {
+    {ERR_REASON(CMS_R_ADD_SIGNER_ERROR), "add signer error"},
+    {ERR_REASON(CMS_R_CERTIFICATE_ALREADY_PRESENT),
+     "certificate already present"},
+    {ERR_REASON(CMS_R_CERTIFICATE_HAS_NO_KEYID), "certificate has no keyid"},
+    {ERR_REASON(CMS_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"},
+    {ERR_REASON(CMS_R_CIPHER_INITIALISATION_ERROR),
+     "cipher initialisation error"},
+    {ERR_REASON(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR),
+     "cipher parameter initialisation error"},
+    {ERR_REASON(CMS_R_CMS_DATAFINAL_ERROR), "cms datafinal error"},
+    {ERR_REASON(CMS_R_CMS_LIB), "cms lib"},
+    {ERR_REASON(CMS_R_CONTENTIDENTIFIER_MISMATCH),
+     "contentidentifier mismatch"},
+    {ERR_REASON(CMS_R_CONTENT_NOT_FOUND), "content not found"},
+    {ERR_REASON(CMS_R_CONTENT_TYPE_MISMATCH), "content type mismatch"},
+    {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA),
+     "content type not compressed data"},
+    {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA),
+     "content type not enveloped data"},
+    {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA),
+     "content type not signed data"},
+    {ERR_REASON(CMS_R_CONTENT_VERIFY_ERROR), "content verify error"},
+    {ERR_REASON(CMS_R_CTRL_ERROR), "ctrl error"},
+    {ERR_REASON(CMS_R_CTRL_FAILURE), "ctrl failure"},
+    {ERR_REASON(CMS_R_DECRYPT_ERROR), "decrypt error"},
+    {ERR_REASON(CMS_R_ERROR_GETTING_PUBLIC_KEY), "error getting public key"},
+    {ERR_REASON(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE),
+     "error reading messagedigest attribute"},
+    {ERR_REASON(CMS_R_ERROR_SETTING_KEY), "error setting key"},
+    {ERR_REASON(CMS_R_ERROR_SETTING_RECIPIENTINFO),
+     "error setting recipientinfo"},
+    {ERR_REASON(CMS_R_INVALID_ENCRYPTED_KEY_LENGTH),
+     "invalid encrypted key length"},
+    {ERR_REASON(CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER),
+     "invalid key encryption parameter"},
+    {ERR_REASON(CMS_R_INVALID_KEY_LENGTH), "invalid key length"},
+    {ERR_REASON(CMS_R_MD_BIO_INIT_ERROR), "md bio init error"},
+    {ERR_REASON(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH),
+     "messagedigest attribute wrong length"},
+    {ERR_REASON(CMS_R_MESSAGEDIGEST_WRONG_LENGTH),
+     "messagedigest wrong length"},
+    {ERR_REASON(CMS_R_MSGSIGDIGEST_ERROR), "msgsigdigest error"},
+    {ERR_REASON(CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE),
+     "msgsigdigest verification failure"},
+    {ERR_REASON(CMS_R_MSGSIGDIGEST_WRONG_LENGTH),
+     "msgsigdigest wrong length"},
+    {ERR_REASON(CMS_R_NEED_ONE_SIGNER), "need one signer"},
+    {ERR_REASON(CMS_R_NOT_A_SIGNED_RECEIPT), "not a signed receipt"},
+    {ERR_REASON(CMS_R_NOT_ENCRYPTED_DATA), "not encrypted data"},
+    {ERR_REASON(CMS_R_NOT_KEK), "not kek"},
+    {ERR_REASON(CMS_R_NOT_KEY_AGREEMENT), "not key agreement"},
+    {ERR_REASON(CMS_R_NOT_KEY_TRANSPORT), "not key transport"},
+    {ERR_REASON(CMS_R_NOT_PWRI), "not pwri"},
+    {ERR_REASON(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),
+     "not supported for this key type"},
+    {ERR_REASON(CMS_R_NO_CIPHER), "no cipher"},
+    {ERR_REASON(CMS_R_NO_CONTENT), "no content"},
+    {ERR_REASON(CMS_R_NO_CONTENT_TYPE), "no content type"},
+    {ERR_REASON(CMS_R_NO_DEFAULT_DIGEST), "no default digest"},
+    {ERR_REASON(CMS_R_NO_DIGEST_SET), "no digest set"},
+    {ERR_REASON(CMS_R_NO_KEY), "no key"},
+    {ERR_REASON(CMS_R_NO_KEY_OR_CERT), "no key or cert"},
+    {ERR_REASON(CMS_R_NO_MATCHING_DIGEST), "no matching digest"},
+    {ERR_REASON(CMS_R_NO_MATCHING_RECIPIENT), "no matching recipient"},
+    {ERR_REASON(CMS_R_NO_MATCHING_SIGNATURE), "no matching signature"},
+    {ERR_REASON(CMS_R_NO_MSGSIGDIGEST), "no msgsigdigest"},
+    {ERR_REASON(CMS_R_NO_PASSWORD), "no password"},
+    {ERR_REASON(CMS_R_NO_PRIVATE_KEY), "no private key"},
+    {ERR_REASON(CMS_R_NO_PUBLIC_KEY), "no public key"},
+    {ERR_REASON(CMS_R_NO_RECEIPT_REQUEST), "no receipt request"},
+    {ERR_REASON(CMS_R_NO_SIGNERS), "no signers"},
+    {ERR_REASON(CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),
+     "private key does not match certificate"},
+    {ERR_REASON(CMS_R_RECEIPT_DECODE_ERROR), "receipt decode error"},
+    {ERR_REASON(CMS_R_RECIPIENT_ERROR), "recipient error"},
+    {ERR_REASON(CMS_R_SIGNER_CERTIFICATE_NOT_FOUND),
+     "signer certificate not found"},
+    {ERR_REASON(CMS_R_SIGNFINAL_ERROR), "signfinal error"},
+    {ERR_REASON(CMS_R_SMIME_TEXT_ERROR), "smime text error"},
+    {ERR_REASON(CMS_R_STORE_INIT_ERROR), "store init error"},
+    {ERR_REASON(CMS_R_TYPE_NOT_COMPRESSED_DATA), "type not compressed data"},
+    {ERR_REASON(CMS_R_TYPE_NOT_DATA), "type not data"},
+    {ERR_REASON(CMS_R_TYPE_NOT_DIGESTED_DATA), "type not digested data"},
+    {ERR_REASON(CMS_R_TYPE_NOT_ENCRYPTED_DATA), "type not encrypted data"},
+    {ERR_REASON(CMS_R_TYPE_NOT_ENVELOPED_DATA), "type not enveloped data"},
+    {ERR_REASON(CMS_R_UNABLE_TO_FINALIZE_CONTEXT),
+     "unable to finalize context"},
+    {ERR_REASON(CMS_R_UNKNOWN_CIPHER), "unknown cipher"},
+    {ERR_REASON(CMS_R_UNKNOWN_DIGEST_ALGORIHM), "unknown digest algorihm"},
+    {ERR_REASON(CMS_R_UNKNOWN_ID), "unknown id"},
+    {ERR_REASON(CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM),
+     "unsupported compression algorithm"},
+    {ERR_REASON(CMS_R_UNSUPPORTED_CONTENT_TYPE), "unsupported content type"},
+    {ERR_REASON(CMS_R_UNSUPPORTED_KEK_ALGORITHM),
+     "unsupported kek algorithm"},
+    {ERR_REASON(CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM),
+     "unsupported key encryption algorithm"},
+    {ERR_REASON(CMS_R_UNSUPPORTED_RECIPIENT_TYPE),
+     "unsupported recipient type"},
+    {ERR_REASON(CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE),
+     "unsupported recpientinfo type"},
+    {ERR_REASON(CMS_R_UNSUPPORTED_TYPE), "unsupported type"},
+    {ERR_REASON(CMS_R_UNWRAP_ERROR), "unwrap error"},
+    {ERR_REASON(CMS_R_UNWRAP_FAILURE), "unwrap failure"},
+    {ERR_REASON(CMS_R_VERIFICATION_FAILURE), "verification failure"},
+    {ERR_REASON(CMS_R_WRAP_ERROR), "wrap error"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_CMS_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(CMS_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, CMS_str_functs);
+        ERR_load_strings(0, CMS_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_ess.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_ess.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_ess.c	(revision 331)
@@ -0,0 +1,337 @@
+/*
+ * Copyright 2008-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 "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include "cms_lcl.h"
+
+IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest)
+
+/* ESS services: for now just Signed Receipt related */
+
+int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr)
+{
+    ASN1_STRING *str;
+    CMS_ReceiptRequest *rr = NULL;
+    if (prr)
+        *prr = NULL;
+    str = CMS_signed_get0_data_by_OBJ(si,
+                                      OBJ_nid2obj
+                                      (NID_id_smime_aa_receiptRequest), -3,
+                                      V_ASN1_SEQUENCE);
+    if (!str)
+        return 0;
+
+    rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest));
+    if (!rr)
+        return -1;
+    if (prr)
+        *prr = rr;
+    else
+        CMS_ReceiptRequest_free(rr);
+    return 1;
+}
+
+CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
+                                               int allorfirst,
+                                               STACK_OF(GENERAL_NAMES)
+                                               *receiptList, STACK_OF(GENERAL_NAMES)
+                                               *receiptsTo)
+{
+    CMS_ReceiptRequest *rr = NULL;
+
+    rr = CMS_ReceiptRequest_new();
+    if (rr == NULL)
+        goto merr;
+    if (id)
+        ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen);
+    else {
+        if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32))
+            goto merr;
+        if (RAND_bytes(rr->signedContentIdentifier->data, 32) <= 0)
+            goto err;
+    }
+
+    sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free);
+    rr->receiptsTo = receiptsTo;
+
+    if (receiptList) {
+        rr->receiptsFrom->type = 1;
+        rr->receiptsFrom->d.receiptList = receiptList;
+    } else {
+        rr->receiptsFrom->type = 0;
+        rr->receiptsFrom->d.allOrFirstTier = allorfirst;
+    }
+
+    return rr;
+
+ merr:
+    CMSerr(CMS_F_CMS_RECEIPTREQUEST_CREATE0, ERR_R_MALLOC_FAILURE);
+
+ err:
+    CMS_ReceiptRequest_free(rr);
+    return NULL;
+
+}
+
+int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr)
+{
+    unsigned char *rrder = NULL;
+    int rrderlen, r = 0;
+
+    rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder);
+    if (rrderlen < 0)
+        goto merr;
+
+    if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest,
+                                     V_ASN1_SEQUENCE, rrder, rrderlen))
+        goto merr;
+
+    r = 1;
+
+ merr:
+    if (!r)
+        CMSerr(CMS_F_CMS_ADD1_RECEIPTREQUEST, ERR_R_MALLOC_FAILURE);
+
+    OPENSSL_free(rrder);
+
+    return r;
+
+}
+
+void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
+                                    ASN1_STRING **pcid,
+                                    int *pallorfirst,
+                                    STACK_OF(GENERAL_NAMES) **plist,
+                                    STACK_OF(GENERAL_NAMES) **prto)
+{
+    if (pcid)
+        *pcid = rr->signedContentIdentifier;
+    if (rr->receiptsFrom->type == 0) {
+        if (pallorfirst)
+            *pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier;
+        if (plist)
+            *plist = NULL;
+    } else {
+        if (pallorfirst)
+            *pallorfirst = -1;
+        if (plist)
+            *plist = rr->receiptsFrom->d.receiptList;
+    }
+    if (prto)
+        *prto = rr->receiptsTo;
+}
+
+/* Digest a SignerInfo structure for msgSigDigest attribute processing */
+
+static int cms_msgSigDigest(CMS_SignerInfo *si,
+                            unsigned char *dig, unsigned int *diglen)
+{
+    const EVP_MD *md;
+    md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
+    if (md == NULL)
+        return 0;
+    if (!ASN1_item_digest(ASN1_ITEM_rptr(CMS_Attributes_Verify), md,
+                          si->signedAttrs, dig, diglen))
+        return 0;
+    return 1;
+}
+
+/* Add a msgSigDigest attribute to a SignerInfo */
+
+int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src)
+{
+    unsigned char dig[EVP_MAX_MD_SIZE];
+    unsigned int diglen;
+    if (!cms_msgSigDigest(src, dig, &diglen)) {
+        CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR);
+        return 0;
+    }
+    if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest,
+                                     V_ASN1_OCTET_STRING, dig, diglen)) {
+        CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    return 1;
+}
+
+/* Verify signed receipt after it has already passed normal CMS verify */
+
+int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms)
+{
+    int r = 0, i;
+    CMS_ReceiptRequest *rr = NULL;
+    CMS_Receipt *rct = NULL;
+    STACK_OF(CMS_SignerInfo) *sis, *osis;
+    CMS_SignerInfo *si, *osi = NULL;
+    ASN1_OCTET_STRING *msig, **pcont;
+    ASN1_OBJECT *octype;
+    unsigned char dig[EVP_MAX_MD_SIZE];
+    unsigned int diglen;
+
+    /* Get SignerInfos, also checks SignedData content type */
+    osis = CMS_get0_SignerInfos(req_cms);
+    sis = CMS_get0_SignerInfos(cms);
+    if (!osis || !sis)
+        goto err;
+
+    if (sk_CMS_SignerInfo_num(sis) != 1) {
+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NEED_ONE_SIGNER);
+        goto err;
+    }
+
+    /* Check receipt content type */
+    if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt) {
+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NOT_A_SIGNED_RECEIPT);
+        goto err;
+    }
+
+    /* Extract and decode receipt content */
+    pcont = CMS_get0_content(cms);
+    if (!pcont || !*pcont) {
+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT);
+        goto err;
+    }
+
+    rct = ASN1_item_unpack(*pcont, ASN1_ITEM_rptr(CMS_Receipt));
+
+    if (!rct) {
+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_RECEIPT_DECODE_ERROR);
+        goto err;
+    }
+
+    /* Locate original request */
+
+    for (i = 0; i < sk_CMS_SignerInfo_num(osis); i++) {
+        osi = sk_CMS_SignerInfo_value(osis, i);
+        if (!ASN1_STRING_cmp(osi->signature, rct->originatorSignatureValue))
+            break;
+    }
+
+    if (i == sk_CMS_SignerInfo_num(osis)) {
+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MATCHING_SIGNATURE);
+        goto err;
+    }
+
+    si = sk_CMS_SignerInfo_value(sis, 0);
+
+    /* Get msgSigDigest value and compare */
+
+    msig = CMS_signed_get0_data_by_OBJ(si,
+                                       OBJ_nid2obj
+                                       (NID_id_smime_aa_msgSigDigest), -3,
+                                       V_ASN1_OCTET_STRING);
+
+    if (!msig) {
+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MSGSIGDIGEST);
+        goto err;
+    }
+
+    if (!cms_msgSigDigest(osi, dig, &diglen)) {
+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_ERROR);
+        goto err;
+    }
+
+    if (diglen != (unsigned int)msig->length) {
+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_WRONG_LENGTH);
+        goto err;
+    }
+
+    if (memcmp(dig, msig->data, diglen)) {
+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
+               CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE);
+        goto err;
+    }
+
+    /* Compare content types */
+
+    octype = CMS_signed_get0_data_by_OBJ(osi,
+                                         OBJ_nid2obj(NID_pkcs9_contentType),
+                                         -3, V_ASN1_OBJECT);
+    if (!octype) {
+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT_TYPE);
+        goto err;
+    }
+
+    /* Compare details in receipt request */
+
+    if (OBJ_cmp(octype, rct->contentType)) {
+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENT_TYPE_MISMATCH);
+        goto err;
+    }
+
+    /* Get original receipt request details */
+
+    if (CMS_get1_ReceiptRequest(osi, &rr) <= 0) {
+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST);
+        goto err;
+    }
+
+    if (ASN1_STRING_cmp(rr->signedContentIdentifier,
+                        rct->signedContentIdentifier)) {
+        CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENTIDENTIFIER_MISMATCH);
+        goto err;
+    }
+
+    r = 1;
+
+ err:
+    CMS_ReceiptRequest_free(rr);
+    M_ASN1_free_of(rct, CMS_Receipt);
+    return r;
+
+}
+
+/*
+ * Encode a Receipt into an OCTET STRING read for including into content of a
+ * SignedData ContentInfo.
+ */
+
+ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si)
+{
+    CMS_Receipt rct;
+    CMS_ReceiptRequest *rr = NULL;
+    ASN1_OBJECT *ctype;
+    ASN1_OCTET_STRING *os = NULL;
+
+    /* Get original receipt request */
+
+    /* Get original receipt request details */
+
+    if (CMS_get1_ReceiptRequest(si, &rr) <= 0) {
+        CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST);
+        goto err;
+    }
+
+    /* Get original content type */
+
+    ctype = CMS_signed_get0_data_by_OBJ(si,
+                                        OBJ_nid2obj(NID_pkcs9_contentType),
+                                        -3, V_ASN1_OBJECT);
+    if (!ctype) {
+        CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_CONTENT_TYPE);
+        goto err;
+    }
+
+    rct.version = 1;
+    rct.contentType = ctype;
+    rct.signedContentIdentifier = rr->signedContentIdentifier;
+    rct.originatorSignatureValue = si->signature;
+
+    os = ASN1_item_pack(&rct, ASN1_ITEM_rptr(CMS_Receipt), NULL);
+
+ err:
+    CMS_ReceiptRequest_free(rr);
+    return os;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_io.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_io.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_io.c	(revision 331)
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2008-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 <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/cms.h>
+#include "cms_lcl.h"
+
+int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms)
+{
+    ASN1_OCTET_STRING **pos;
+    pos = CMS_get0_content(cms);
+    if (pos == NULL)
+        return 0;
+    if (*pos == NULL)
+        *pos = ASN1_OCTET_STRING_new();
+    if (*pos != NULL) {
+        (*pos)->flags |= ASN1_STRING_FLAG_NDEF;
+        (*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
+        *boundary = &(*pos)->data;
+        return 1;
+    }
+    CMSerr(CMS_F_CMS_STREAM, ERR_R_MALLOC_FAILURE);
+    return 0;
+}
+
+CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms)
+{
+    return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
+}
+
+int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms)
+{
+    return ASN1_item_i2d_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
+}
+
+IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo)
+
+BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms)
+{
+    return BIO_new_NDEF(out, (ASN1_VALUE *)cms,
+                        ASN1_ITEM_rptr(CMS_ContentInfo));
+}
+
+/* CMS wrappers round generalised stream and MIME routines */
+
+int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags)
+{
+    return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)cms, in, flags,
+                               ASN1_ITEM_rptr(CMS_ContentInfo));
+}
+
+int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in,
+                             int flags)
+{
+    return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *)cms, in, flags,
+                                     "CMS", ASN1_ITEM_rptr(CMS_ContentInfo));
+}
+
+int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags)
+{
+    STACK_OF(X509_ALGOR) *mdalgs;
+    int ctype_nid = OBJ_obj2nid(cms->contentType);
+    int econt_nid = OBJ_obj2nid(CMS_get0_eContentType(cms));
+    if (ctype_nid == NID_pkcs7_signed)
+        mdalgs = cms->d.signedData->digestAlgorithms;
+    else
+        mdalgs = NULL;
+
+    return SMIME_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags,
+                            ctype_nid, econt_nid, mdalgs,
+                            ASN1_ITEM_rptr(CMS_ContentInfo));
+}
+
+CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont)
+{
+    return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont,
+                                              ASN1_ITEM_rptr
+                                              (CMS_ContentInfo));
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_kari.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_kari.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_kari.c	(revision 331)
@@ -0,0 +1,411 @@
+/*
+ * Copyright 2013-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 "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include <openssl/aes.h>
+#include "cms_lcl.h"
+#include "internal/asn1_int.h"
+
+/* Key Agreement Recipient Info (KARI) routines */
+
+int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri,
+                                    X509_ALGOR **palg,
+                                    ASN1_OCTET_STRING **pukm)
+{
+    if (ri->type != CMS_RECIPINFO_AGREE) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG,
+               CMS_R_NOT_KEY_AGREEMENT);
+        return 0;
+    }
+    if (palg)
+        *palg = ri->d.kari->keyEncryptionAlgorithm;
+    if (pukm)
+        *pukm = ri->d.kari->ukm;
+    return 1;
+}
+
+/* Retrieve recipient encrypted keys from a kari */
+
+STACK_OF(CMS_RecipientEncryptedKey)
+*CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri)
+{
+    if (ri->type != CMS_RECIPINFO_AGREE) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS,
+               CMS_R_NOT_KEY_AGREEMENT);
+        return NULL;
+    }
+    return ri->d.kari->recipientEncryptedKeys;
+}
+
+int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri,
+                                        X509_ALGOR **pubalg,
+                                        ASN1_BIT_STRING **pubkey,
+                                        ASN1_OCTET_STRING **keyid,
+                                        X509_NAME **issuer,
+                                        ASN1_INTEGER **sno)
+{
+    CMS_OriginatorIdentifierOrKey *oik;
+    if (ri->type != CMS_RECIPINFO_AGREE) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID,
+               CMS_R_NOT_KEY_AGREEMENT);
+        return 0;
+    }
+    oik = ri->d.kari->originator;
+    if (issuer)
+        *issuer = NULL;
+    if (sno)
+        *sno = NULL;
+    if (keyid)
+        *keyid = NULL;
+    if (pubalg)
+        *pubalg = NULL;
+    if (pubkey)
+        *pubkey = NULL;
+    if (oik->type == CMS_OIK_ISSUER_SERIAL) {
+        if (issuer)
+            *issuer = oik->d.issuerAndSerialNumber->issuer;
+        if (sno)
+            *sno = oik->d.issuerAndSerialNumber->serialNumber;
+    } else if (oik->type == CMS_OIK_KEYIDENTIFIER) {
+        if (keyid)
+            *keyid = oik->d.subjectKeyIdentifier;
+    } else if (oik->type == CMS_OIK_PUBKEY) {
+        if (pubalg)
+            *pubalg = oik->d.originatorKey->algorithm;
+        if (pubkey)
+            *pubkey = oik->d.originatorKey->publicKey;
+    } else
+        return 0;
+    return 1;
+}
+
+int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert)
+{
+    CMS_OriginatorIdentifierOrKey *oik;
+    if (ri->type != CMS_RECIPINFO_AGREE) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP,
+               CMS_R_NOT_KEY_AGREEMENT);
+        return -2;
+    }
+    oik = ri->d.kari->originator;
+    if (oik->type == CMS_OIK_ISSUER_SERIAL)
+        return cms_ias_cert_cmp(oik->d.issuerAndSerialNumber, cert);
+    else if (oik->type == CMS_OIK_KEYIDENTIFIER)
+        return cms_keyid_cert_cmp(oik->d.subjectKeyIdentifier, cert);
+    return -1;
+}
+
+int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek,
+                                      ASN1_OCTET_STRING **keyid,
+                                      ASN1_GENERALIZEDTIME **tm,
+                                      CMS_OtherKeyAttribute **other,
+                                      X509_NAME **issuer, ASN1_INTEGER **sno)
+{
+    CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
+    if (rid->type == CMS_REK_ISSUER_SERIAL) {
+        if (issuer)
+            *issuer = rid->d.issuerAndSerialNumber->issuer;
+        if (sno)
+            *sno = rid->d.issuerAndSerialNumber->serialNumber;
+        if (keyid)
+            *keyid = NULL;
+        if (tm)
+            *tm = NULL;
+        if (other)
+            *other = NULL;
+    } else if (rid->type == CMS_REK_KEYIDENTIFIER) {
+        if (keyid)
+            *keyid = rid->d.rKeyId->subjectKeyIdentifier;
+        if (tm)
+            *tm = rid->d.rKeyId->date;
+        if (other)
+            *other = rid->d.rKeyId->other;
+        if (issuer)
+            *issuer = NULL;
+        if (sno)
+            *sno = NULL;
+    } else
+        return 0;
+    return 1;
+}
+
+int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek,
+                                       X509 *cert)
+{
+    CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
+    if (rid->type == CMS_REK_ISSUER_SERIAL)
+        return cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert);
+    else if (rid->type == CMS_REK_KEYIDENTIFIER)
+        return cms_keyid_cert_cmp(rid->d.rKeyId->subjectKeyIdentifier, cert);
+    else
+        return -1;
+}
+
+int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk)
+{
+    EVP_PKEY_CTX *pctx;
+    CMS_KeyAgreeRecipientInfo *kari = ri->d.kari;
+
+    EVP_PKEY_CTX_free(kari->pctx);
+    kari->pctx = NULL;
+    if (!pk)
+        return 1;
+    pctx = EVP_PKEY_CTX_new(pk, NULL);
+    if (!pctx || !EVP_PKEY_derive_init(pctx))
+        goto err;
+    kari->pctx = pctx;
+    return 1;
+ err:
+    EVP_PKEY_CTX_free(pctx);
+    return 0;
+}
+
+EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri)
+{
+    if (ri->type == CMS_RECIPINFO_AGREE)
+        return ri->d.kari->ctx;
+    return NULL;
+}
+
+/*
+ * Derive KEK and decrypt/encrypt with it to produce either the original CEK
+ * or the encrypted CEK.
+ */
+
+static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
+                          const unsigned char *in, size_t inlen,
+                          CMS_KeyAgreeRecipientInfo *kari, int enc)
+{
+    /* Key encryption key */
+    unsigned char kek[EVP_MAX_KEY_LENGTH];
+    size_t keklen;
+    int rv = 0;
+    unsigned char *out = NULL;
+    int outlen;
+    keklen = EVP_CIPHER_CTX_key_length(kari->ctx);
+    if (keklen > EVP_MAX_KEY_LENGTH)
+        return 0;
+    /* Derive KEK */
+    if (EVP_PKEY_derive(kari->pctx, kek, &keklen) <= 0)
+        goto err;
+    /* Set KEK in context */
+    if (!EVP_CipherInit_ex(kari->ctx, NULL, NULL, kek, NULL, enc))
+        goto err;
+    /* obtain output length of ciphered key */
+    if (!EVP_CipherUpdate(kari->ctx, NULL, &outlen, in, inlen))
+        goto err;
+    out = OPENSSL_malloc(outlen);
+    if (out == NULL)
+        goto err;
+    if (!EVP_CipherUpdate(kari->ctx, out, &outlen, in, inlen))
+        goto err;
+    *pout = out;
+    *poutlen = (size_t)outlen;
+    rv = 1;
+
+ err:
+    OPENSSL_cleanse(kek, keklen);
+    if (!rv)
+        OPENSSL_free(out);
+    EVP_CIPHER_CTX_reset(kari->ctx);
+    /* FIXME: WHY IS kari->pctx freed here?  /RL */
+    EVP_PKEY_CTX_free(kari->pctx);
+    kari->pctx = NULL;
+    return rv;
+}
+
+int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms,
+                                   CMS_RecipientInfo *ri,
+                                   CMS_RecipientEncryptedKey *rek)
+{
+    int rv = 0;
+    unsigned char *enckey = NULL, *cek = NULL;
+    size_t enckeylen;
+    size_t ceklen;
+    CMS_EncryptedContentInfo *ec;
+    enckeylen = rek->encryptedKey->length;
+    enckey = rek->encryptedKey->data;
+    /* Setup all parameters to derive KEK */
+    if (!cms_env_asn1_ctrl(ri, 1))
+        goto err;
+    /* Attempt to decrypt CEK */
+    if (!cms_kek_cipher(&cek, &ceklen, enckey, enckeylen, ri->d.kari, 0))
+        goto err;
+    ec = cms->d.envelopedData->encryptedContentInfo;
+    OPENSSL_clear_free(ec->key, ec->keylen);
+    ec->key = cek;
+    ec->keylen = ceklen;
+    cek = NULL;
+    rv = 1;
+ err:
+    OPENSSL_free(cek);
+    return rv;
+}
+
+/* Create ephemeral key and initialise context based on it */
+static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari,
+                                         EVP_PKEY *pk)
+{
+    EVP_PKEY_CTX *pctx = NULL;
+    EVP_PKEY *ekey = NULL;
+    int rv = 0;
+    pctx = EVP_PKEY_CTX_new(pk, NULL);
+    if (!pctx)
+        goto err;
+    if (EVP_PKEY_keygen_init(pctx) <= 0)
+        goto err;
+    if (EVP_PKEY_keygen(pctx, &ekey) <= 0)
+        goto err;
+    EVP_PKEY_CTX_free(pctx);
+    pctx = EVP_PKEY_CTX_new(ekey, NULL);
+    if (!pctx)
+        goto err;
+    if (EVP_PKEY_derive_init(pctx) <= 0)
+        goto err;
+    kari->pctx = pctx;
+    rv = 1;
+ err:
+    if (!rv)
+        EVP_PKEY_CTX_free(pctx);
+    EVP_PKEY_free(ekey);
+    return rv;
+}
+
+/* Initialise a ktri based on passed certificate and key */
+
+int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
+                                EVP_PKEY *pk, unsigned int flags)
+{
+    CMS_KeyAgreeRecipientInfo *kari;
+    CMS_RecipientEncryptedKey *rek = NULL;
+
+    ri->d.kari = M_ASN1_new_of(CMS_KeyAgreeRecipientInfo);
+    if (!ri->d.kari)
+        return 0;
+    ri->type = CMS_RECIPINFO_AGREE;
+
+    kari = ri->d.kari;
+    kari->version = 3;
+
+    rek = M_ASN1_new_of(CMS_RecipientEncryptedKey);
+    if (!sk_CMS_RecipientEncryptedKey_push(kari->recipientEncryptedKeys, rek)) {
+        M_ASN1_free_of(rek, CMS_RecipientEncryptedKey);
+        return 0;
+    }
+
+    if (flags & CMS_USE_KEYID) {
+        rek->rid->type = CMS_REK_KEYIDENTIFIER;
+        rek->rid->d.rKeyId = M_ASN1_new_of(CMS_RecipientKeyIdentifier);
+        if (rek->rid->d.rKeyId == NULL)
+            return 0;
+        if (!cms_set1_keyid(&rek->rid->d.rKeyId->subjectKeyIdentifier, recip))
+            return 0;
+    } else {
+        rek->rid->type = CMS_REK_ISSUER_SERIAL;
+        if (!cms_set1_ias(&rek->rid->d.issuerAndSerialNumber, recip))
+            return 0;
+    }
+
+    /* Create ephemeral key */
+    if (!cms_kari_create_ephemeral_key(kari, pk))
+        return 0;
+
+    EVP_PKEY_up_ref(pk);
+    rek->pkey = pk;
+    return 1;
+}
+
+static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari,
+                         const EVP_CIPHER *cipher)
+{
+    EVP_CIPHER_CTX *ctx = kari->ctx;
+    const EVP_CIPHER *kekcipher;
+    int keylen = EVP_CIPHER_key_length(cipher);
+    /* If a suitable wrap algorithm is already set nothing to do */
+    kekcipher = EVP_CIPHER_CTX_cipher(ctx);
+
+    if (kekcipher) {
+        if (EVP_CIPHER_CTX_mode(ctx) != EVP_CIPH_WRAP_MODE)
+            return 0;
+        return 1;
+    }
+    /*
+     * Pick a cipher based on content encryption cipher. If it is DES3 use
+     * DES3 wrap otherwise use AES wrap similar to key size.
+     */
+#ifndef OPENSSL_NO_DES
+    if (EVP_CIPHER_type(cipher) == NID_des_ede3_cbc)
+        kekcipher = EVP_des_ede3_wrap();
+    else
+#endif
+    if (keylen <= 16)
+        kekcipher = EVP_aes_128_wrap();
+    else if (keylen <= 24)
+        kekcipher = EVP_aes_192_wrap();
+    else
+        kekcipher = EVP_aes_256_wrap();
+    return EVP_EncryptInit_ex(ctx, kekcipher, NULL, NULL, NULL);
+}
+
+/* Encrypt content key in key agreement recipient info */
+
+int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms,
+                                   CMS_RecipientInfo *ri)
+{
+    CMS_KeyAgreeRecipientInfo *kari;
+    CMS_EncryptedContentInfo *ec;
+    CMS_RecipientEncryptedKey *rek;
+    STACK_OF(CMS_RecipientEncryptedKey) *reks;
+    int i;
+
+    if (ri->type != CMS_RECIPINFO_AGREE) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT, CMS_R_NOT_KEY_AGREEMENT);
+        return 0;
+    }
+    kari = ri->d.kari;
+    reks = kari->recipientEncryptedKeys;
+    ec = cms->d.envelopedData->encryptedContentInfo;
+    /* Initialise wrap algorithm parameters */
+    if (!cms_wrap_init(kari, ec->cipher))
+        return 0;
+    /*
+     * If no originator key set up initialise for ephemeral key the public key
+     * ASN1 structure will set the actual public key value.
+     */
+    if (kari->originator->type == -1) {
+        CMS_OriginatorIdentifierOrKey *oik = kari->originator;
+        oik->type = CMS_OIK_PUBKEY;
+        oik->d.originatorKey = M_ASN1_new_of(CMS_OriginatorPublicKey);
+        if (!oik->d.originatorKey)
+            return 0;
+    }
+    /* Initialise KDF algorithm */
+    if (!cms_env_asn1_ctrl(ri, 0))
+        return 0;
+    /* For each rek, derive KEK, encrypt CEK */
+    for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) {
+        unsigned char *enckey;
+        size_t enckeylen;
+        rek = sk_CMS_RecipientEncryptedKey_value(reks, i);
+        if (EVP_PKEY_derive_set_peer(kari->pctx, rek->pkey) <= 0)
+            return 0;
+        if (!cms_kek_cipher(&enckey, &enckeylen, ec->key, ec->keylen,
+                            kari, 1))
+            return 0;
+        ASN1_STRING_set0(rek->encryptedKey, enckey, enckeylen);
+    }
+
+    return 1;
+
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_lcl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_lcl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_lcl.h	(revision 331)
@@ -0,0 +1,444 @@
+/*
+ * Copyright 2008-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
+ */
+
+#ifndef HEADER_CMS_LCL_H
+# define HEADER_CMS_LCL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# include <openssl/x509.h>
+
+/*
+ * Cryptographic message syntax (CMS) structures: taken from RFC3852
+ */
+
+/* Forward references */
+
+typedef struct CMS_IssuerAndSerialNumber_st CMS_IssuerAndSerialNumber;
+typedef struct CMS_EncapsulatedContentInfo_st CMS_EncapsulatedContentInfo;
+typedef struct CMS_SignerIdentifier_st CMS_SignerIdentifier;
+typedef struct CMS_SignedData_st CMS_SignedData;
+typedef struct CMS_OtherRevocationInfoFormat_st CMS_OtherRevocationInfoFormat;
+typedef struct CMS_OriginatorInfo_st CMS_OriginatorInfo;
+typedef struct CMS_EncryptedContentInfo_st CMS_EncryptedContentInfo;
+typedef struct CMS_EnvelopedData_st CMS_EnvelopedData;
+typedef struct CMS_DigestedData_st CMS_DigestedData;
+typedef struct CMS_EncryptedData_st CMS_EncryptedData;
+typedef struct CMS_AuthenticatedData_st CMS_AuthenticatedData;
+typedef struct CMS_CompressedData_st CMS_CompressedData;
+typedef struct CMS_OtherCertificateFormat_st CMS_OtherCertificateFormat;
+typedef struct CMS_KeyTransRecipientInfo_st CMS_KeyTransRecipientInfo;
+typedef struct CMS_OriginatorPublicKey_st CMS_OriginatorPublicKey;
+typedef struct CMS_OriginatorIdentifierOrKey_st CMS_OriginatorIdentifierOrKey;
+typedef struct CMS_KeyAgreeRecipientInfo_st CMS_KeyAgreeRecipientInfo;
+typedef struct CMS_RecipientKeyIdentifier_st CMS_RecipientKeyIdentifier;
+typedef struct CMS_KeyAgreeRecipientIdentifier_st
+    CMS_KeyAgreeRecipientIdentifier;
+typedef struct CMS_KEKIdentifier_st CMS_KEKIdentifier;
+typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo;
+typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo;
+typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo;
+typedef struct CMS_ReceiptsFrom_st CMS_ReceiptsFrom;
+
+struct CMS_ContentInfo_st {
+    ASN1_OBJECT *contentType;
+    union {
+        ASN1_OCTET_STRING *data;
+        CMS_SignedData *signedData;
+        CMS_EnvelopedData *envelopedData;
+        CMS_DigestedData *digestedData;
+        CMS_EncryptedData *encryptedData;
+        CMS_AuthenticatedData *authenticatedData;
+        CMS_CompressedData *compressedData;
+        ASN1_TYPE *other;
+        /* Other types ... */
+        void *otherData;
+    } d;
+};
+
+DEFINE_STACK_OF(CMS_CertificateChoices)
+
+struct CMS_SignedData_st {
+    long version;
+    STACK_OF(X509_ALGOR) *digestAlgorithms;
+    CMS_EncapsulatedContentInfo *encapContentInfo;
+    STACK_OF(CMS_CertificateChoices) *certificates;
+    STACK_OF(CMS_RevocationInfoChoice) *crls;
+    STACK_OF(CMS_SignerInfo) *signerInfos;
+};
+
+struct CMS_EncapsulatedContentInfo_st {
+    ASN1_OBJECT *eContentType;
+    ASN1_OCTET_STRING *eContent;
+    /* Set to 1 if incomplete structure only part set up */
+    int partial;
+};
+
+struct CMS_SignerInfo_st {
+    long version;
+    CMS_SignerIdentifier *sid;
+    X509_ALGOR *digestAlgorithm;
+    STACK_OF(X509_ATTRIBUTE) *signedAttrs;
+    X509_ALGOR *signatureAlgorithm;
+    ASN1_OCTET_STRING *signature;
+    STACK_OF(X509_ATTRIBUTE) *unsignedAttrs;
+    /* Signing certificate and key */
+    X509 *signer;
+    EVP_PKEY *pkey;
+    /* Digest and public key context for alternative parameters */
+    EVP_MD_CTX *mctx;
+    EVP_PKEY_CTX *pctx;
+};
+
+struct CMS_SignerIdentifier_st {
+    int type;
+    union {
+        CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
+        ASN1_OCTET_STRING *subjectKeyIdentifier;
+    } d;
+};
+
+struct CMS_EnvelopedData_st {
+    long version;
+    CMS_OriginatorInfo *originatorInfo;
+    STACK_OF(CMS_RecipientInfo) *recipientInfos;
+    CMS_EncryptedContentInfo *encryptedContentInfo;
+    STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs;
+};
+
+struct CMS_OriginatorInfo_st {
+    STACK_OF(CMS_CertificateChoices) *certificates;
+    STACK_OF(CMS_RevocationInfoChoice) *crls;
+};
+
+struct CMS_EncryptedContentInfo_st {
+    ASN1_OBJECT *contentType;
+    X509_ALGOR *contentEncryptionAlgorithm;
+    ASN1_OCTET_STRING *encryptedContent;
+    /* Content encryption algorithm and key */
+    const EVP_CIPHER *cipher;
+    unsigned char *key;
+    size_t keylen;
+    /* Set to 1 if we are debugging decrypt and don't fake keys for MMA */
+    int debug;
+};
+
+struct CMS_RecipientInfo_st {
+    int type;
+    union {
+        CMS_KeyTransRecipientInfo *ktri;
+        CMS_KeyAgreeRecipientInfo *kari;
+        CMS_KEKRecipientInfo *kekri;
+        CMS_PasswordRecipientInfo *pwri;
+        CMS_OtherRecipientInfo *ori;
+    } d;
+};
+
+typedef CMS_SignerIdentifier CMS_RecipientIdentifier;
+
+struct CMS_KeyTransRecipientInfo_st {
+    long version;
+    CMS_RecipientIdentifier *rid;
+    X509_ALGOR *keyEncryptionAlgorithm;
+    ASN1_OCTET_STRING *encryptedKey;
+    /* Recipient Key and cert */
+    X509 *recip;
+    EVP_PKEY *pkey;
+    /* Public key context for this operation */
+    EVP_PKEY_CTX *pctx;
+};
+
+struct CMS_KeyAgreeRecipientInfo_st {
+    long version;
+    CMS_OriginatorIdentifierOrKey *originator;
+    ASN1_OCTET_STRING *ukm;
+    X509_ALGOR *keyEncryptionAlgorithm;
+    STACK_OF(CMS_RecipientEncryptedKey) *recipientEncryptedKeys;
+    /* Public key context associated with current operation */
+    EVP_PKEY_CTX *pctx;
+    /* Cipher context for CEK wrapping */
+    EVP_CIPHER_CTX *ctx;
+};
+
+struct CMS_OriginatorIdentifierOrKey_st {
+    int type;
+    union {
+        CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
+        ASN1_OCTET_STRING *subjectKeyIdentifier;
+        CMS_OriginatorPublicKey *originatorKey;
+    } d;
+};
+
+struct CMS_OriginatorPublicKey_st {
+    X509_ALGOR *algorithm;
+    ASN1_BIT_STRING *publicKey;
+};
+
+struct CMS_RecipientEncryptedKey_st {
+    CMS_KeyAgreeRecipientIdentifier *rid;
+    ASN1_OCTET_STRING *encryptedKey;
+    /* Public key associated with this recipient */
+    EVP_PKEY *pkey;
+};
+
+struct CMS_KeyAgreeRecipientIdentifier_st {
+    int type;
+    union {
+        CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
+        CMS_RecipientKeyIdentifier *rKeyId;
+    } d;
+};
+
+struct CMS_RecipientKeyIdentifier_st {
+    ASN1_OCTET_STRING *subjectKeyIdentifier;
+    ASN1_GENERALIZEDTIME *date;
+    CMS_OtherKeyAttribute *other;
+};
+
+struct CMS_KEKRecipientInfo_st {
+    long version;
+    CMS_KEKIdentifier *kekid;
+    X509_ALGOR *keyEncryptionAlgorithm;
+    ASN1_OCTET_STRING *encryptedKey;
+    /* Extra info: symmetric key to use */
+    unsigned char *key;
+    size_t keylen;
+};
+
+struct CMS_KEKIdentifier_st {
+    ASN1_OCTET_STRING *keyIdentifier;
+    ASN1_GENERALIZEDTIME *date;
+    CMS_OtherKeyAttribute *other;
+};
+
+struct CMS_PasswordRecipientInfo_st {
+    long version;
+    X509_ALGOR *keyDerivationAlgorithm;
+    X509_ALGOR *keyEncryptionAlgorithm;
+    ASN1_OCTET_STRING *encryptedKey;
+    /* Extra info: password to use */
+    unsigned char *pass;
+    size_t passlen;
+};
+
+struct CMS_OtherRecipientInfo_st {
+    ASN1_OBJECT *oriType;
+    ASN1_TYPE *oriValue;
+};
+
+struct CMS_DigestedData_st {
+    long version;
+    X509_ALGOR *digestAlgorithm;
+    CMS_EncapsulatedContentInfo *encapContentInfo;
+    ASN1_OCTET_STRING *digest;
+};
+
+struct CMS_EncryptedData_st {
+    long version;
+    CMS_EncryptedContentInfo *encryptedContentInfo;
+    STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs;
+};
+
+struct CMS_AuthenticatedData_st {
+    long version;
+    CMS_OriginatorInfo *originatorInfo;
+    STACK_OF(CMS_RecipientInfo) *recipientInfos;
+    X509_ALGOR *macAlgorithm;
+    X509_ALGOR *digestAlgorithm;
+    CMS_EncapsulatedContentInfo *encapContentInfo;
+    STACK_OF(X509_ATTRIBUTE) *authAttrs;
+    ASN1_OCTET_STRING *mac;
+    STACK_OF(X509_ATTRIBUTE) *unauthAttrs;
+};
+
+struct CMS_CompressedData_st {
+    long version;
+    X509_ALGOR *compressionAlgorithm;
+    STACK_OF(CMS_RecipientInfo) *recipientInfos;
+    CMS_EncapsulatedContentInfo *encapContentInfo;
+};
+
+struct CMS_RevocationInfoChoice_st {
+    int type;
+    union {
+        X509_CRL *crl;
+        CMS_OtherRevocationInfoFormat *other;
+    } d;
+};
+
+# define CMS_REVCHOICE_CRL               0
+# define CMS_REVCHOICE_OTHER             1
+
+struct CMS_OtherRevocationInfoFormat_st {
+    ASN1_OBJECT *otherRevInfoFormat;
+    ASN1_TYPE *otherRevInfo;
+};
+
+struct CMS_CertificateChoices {
+    int type;
+    union {
+        X509 *certificate;
+        ASN1_STRING *extendedCertificate; /* Obsolete */
+        ASN1_STRING *v1AttrCert; /* Left encoded for now */
+        ASN1_STRING *v2AttrCert; /* Left encoded for now */
+        CMS_OtherCertificateFormat *other;
+    } d;
+};
+
+# define CMS_CERTCHOICE_CERT             0
+# define CMS_CERTCHOICE_EXCERT           1
+# define CMS_CERTCHOICE_V1ACERT          2
+# define CMS_CERTCHOICE_V2ACERT          3
+# define CMS_CERTCHOICE_OTHER            4
+
+struct CMS_OtherCertificateFormat_st {
+    ASN1_OBJECT *otherCertFormat;
+    ASN1_TYPE *otherCert;
+};
+
+/*
+ * This is also defined in pkcs7.h but we duplicate it to allow the CMS code
+ * to be independent of PKCS#7
+ */
+
+struct CMS_IssuerAndSerialNumber_st {
+    X509_NAME *issuer;
+    ASN1_INTEGER *serialNumber;
+};
+
+struct CMS_OtherKeyAttribute_st {
+    ASN1_OBJECT *keyAttrId;
+    ASN1_TYPE *keyAttr;
+};
+
+/* ESS structures */
+
+# ifdef HEADER_X509V3_H
+
+struct CMS_ReceiptRequest_st {
+    ASN1_OCTET_STRING *signedContentIdentifier;
+    CMS_ReceiptsFrom *receiptsFrom;
+    STACK_OF(GENERAL_NAMES) *receiptsTo;
+};
+
+struct CMS_ReceiptsFrom_st {
+    int type;
+    union {
+        long allOrFirstTier;
+        STACK_OF(GENERAL_NAMES) *receiptList;
+    } d;
+};
+# endif
+
+struct CMS_Receipt_st {
+    long version;
+    ASN1_OBJECT *contentType;
+    ASN1_OCTET_STRING *signedContentIdentifier;
+    ASN1_OCTET_STRING *originatorSignatureValue;
+};
+
+DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
+DECLARE_ASN1_ITEM(CMS_SignerInfo)
+DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber)
+DECLARE_ASN1_ITEM(CMS_Attributes_Sign)
+DECLARE_ASN1_ITEM(CMS_Attributes_Verify)
+DECLARE_ASN1_ITEM(CMS_RecipientInfo)
+DECLARE_ASN1_ITEM(CMS_PasswordRecipientInfo)
+DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber)
+
+# define CMS_SIGNERINFO_ISSUER_SERIAL    0
+# define CMS_SIGNERINFO_KEYIDENTIFIER    1
+
+# define CMS_RECIPINFO_ISSUER_SERIAL     0
+# define CMS_RECIPINFO_KEYIDENTIFIER     1
+
+# define CMS_REK_ISSUER_SERIAL           0
+# define CMS_REK_KEYIDENTIFIER           1
+
+# define CMS_OIK_ISSUER_SERIAL           0
+# define CMS_OIK_KEYIDENTIFIER           1
+# define CMS_OIK_PUBKEY                  2
+
+BIO *cms_content_bio(CMS_ContentInfo *cms);
+
+CMS_ContentInfo *cms_Data_create(void);
+
+CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md);
+BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms);
+int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify);
+
+BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms);
+int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain);
+int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert,
+                              int type);
+int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
+                                        ASN1_OCTET_STRING **keyid,
+                                        X509_NAME **issuer,
+                                        ASN1_INTEGER **sno);
+int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert);
+
+CMS_ContentInfo *cms_CompressedData_create(int comp_nid);
+BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms);
+
+BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm);
+int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
+                                 X509_ALGOR *mdalg);
+
+int cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert);
+int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert);
+int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert);
+int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert);
+
+BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec);
+BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms);
+int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
+                              const EVP_CIPHER *cipher,
+                              const unsigned char *key, size_t keylen);
+
+int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms);
+int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src);
+ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si);
+
+BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms);
+CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms);
+int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd);
+int cms_pkey_get_ri_type(EVP_PKEY *pk);
+/* KARI routines */
+int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
+                                EVP_PKEY *pk, unsigned int flags);
+int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms,
+                                   CMS_RecipientInfo *ri);
+
+/* PWRI routines */
+int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
+                                 int en_de);
+
+DECLARE_ASN1_ITEM(CMS_CertificateChoices)
+DECLARE_ASN1_ITEM(CMS_DigestedData)
+DECLARE_ASN1_ITEM(CMS_EncryptedData)
+DECLARE_ASN1_ITEM(CMS_EnvelopedData)
+DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo)
+DECLARE_ASN1_ITEM(CMS_KeyAgreeRecipientInfo)
+DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo)
+DECLARE_ASN1_ITEM(CMS_OriginatorPublicKey)
+DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute)
+DECLARE_ASN1_ITEM(CMS_Receipt)
+DECLARE_ASN1_ITEM(CMS_ReceiptRequest)
+DECLARE_ASN1_ITEM(CMS_RecipientEncryptedKey)
+DECLARE_ASN1_ITEM(CMS_RecipientKeyIdentifier)
+DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice)
+DECLARE_ASN1_ITEM(CMS_SignedData)
+DECLARE_ASN1_ITEM(CMS_CompressedData)
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_lib.c	(revision 331)
@@ -0,0 +1,587 @@
+/*
+ * Copyright 2008-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 <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/bio.h>
+#include <openssl/asn1.h>
+#include <openssl/cms.h>
+#include "cms_lcl.h"
+
+IMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo)
+IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
+
+const ASN1_OBJECT *CMS_get0_type(const CMS_ContentInfo *cms)
+{
+    return cms->contentType;
+}
+
+CMS_ContentInfo *cms_Data_create(void)
+{
+    CMS_ContentInfo *cms;
+    cms = CMS_ContentInfo_new();
+    if (cms != NULL) {
+        cms->contentType = OBJ_nid2obj(NID_pkcs7_data);
+        /* Never detached */
+        CMS_set_detached(cms, 0);
+    }
+    return cms;
+}
+
+BIO *cms_content_bio(CMS_ContentInfo *cms)
+{
+    ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
+    if (!pos)
+        return NULL;
+    /* If content detached data goes nowhere: create NULL BIO */
+    if (!*pos)
+        return BIO_new(BIO_s_null());
+    /*
+     * If content not detached and created return memory BIO
+     */
+    if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT))
+        return BIO_new(BIO_s_mem());
+    /* Else content was read in: return read only BIO for it */
+    return BIO_new_mem_buf((*pos)->data, (*pos)->length);
+}
+
+BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
+{
+    BIO *cmsbio, *cont;
+    if (icont)
+        cont = icont;
+    else
+        cont = cms_content_bio(cms);
+    if (!cont) {
+        CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT);
+        return NULL;
+    }
+    switch (OBJ_obj2nid(cms->contentType)) {
+
+    case NID_pkcs7_data:
+        return cont;
+
+    case NID_pkcs7_signed:
+        cmsbio = cms_SignedData_init_bio(cms);
+        break;
+
+    case NID_pkcs7_digest:
+        cmsbio = cms_DigestedData_init_bio(cms);
+        break;
+#ifdef ZLIB
+    case NID_id_smime_ct_compressedData:
+        cmsbio = cms_CompressedData_init_bio(cms);
+        break;
+#endif
+
+    case NID_pkcs7_encrypted:
+        cmsbio = cms_EncryptedData_init_bio(cms);
+        break;
+
+    case NID_pkcs7_enveloped:
+        cmsbio = cms_EnvelopedData_init_bio(cms);
+        break;
+
+    default:
+        CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE);
+        return NULL;
+    }
+
+    if (cmsbio)
+        return BIO_push(cmsbio, cont);
+
+    if (!icont)
+        BIO_free(cont);
+    return NULL;
+
+}
+
+int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
+{
+    ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
+    if (!pos)
+        return 0;
+    /* If embedded content find memory BIO and set content */
+    if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT)) {
+        BIO *mbio;
+        unsigned char *cont;
+        long contlen;
+        mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM);
+        if (!mbio) {
+            CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND);
+            return 0;
+        }
+        contlen = BIO_get_mem_data(mbio, &cont);
+        /* Set bio as read only so its content can't be clobbered */
+        BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY);
+        BIO_set_mem_eof_return(mbio, 0);
+        ASN1_STRING_set0(*pos, cont, contlen);
+        (*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
+    }
+
+    switch (OBJ_obj2nid(cms->contentType)) {
+
+    case NID_pkcs7_data:
+    case NID_pkcs7_enveloped:
+    case NID_pkcs7_encrypted:
+    case NID_id_smime_ct_compressedData:
+        /* Nothing to do */
+        return 1;
+
+    case NID_pkcs7_signed:
+        return cms_SignedData_final(cms, cmsbio);
+
+    case NID_pkcs7_digest:
+        return cms_DigestedData_do_final(cms, cmsbio, 0);
+
+    default:
+        CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE);
+        return 0;
+    }
+}
+
+/*
+ * Return an OCTET STRING pointer to content. This allows it to be accessed
+ * or set later.
+ */
+
+ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms)
+{
+    switch (OBJ_obj2nid(cms->contentType)) {
+
+    case NID_pkcs7_data:
+        return &cms->d.data;
+
+    case NID_pkcs7_signed:
+        return &cms->d.signedData->encapContentInfo->eContent;
+
+    case NID_pkcs7_enveloped:
+        return &cms->d.envelopedData->encryptedContentInfo->encryptedContent;
+
+    case NID_pkcs7_digest:
+        return &cms->d.digestedData->encapContentInfo->eContent;
+
+    case NID_pkcs7_encrypted:
+        return &cms->d.encryptedData->encryptedContentInfo->encryptedContent;
+
+    case NID_id_smime_ct_authData:
+        return &cms->d.authenticatedData->encapContentInfo->eContent;
+
+    case NID_id_smime_ct_compressedData:
+        return &cms->d.compressedData->encapContentInfo->eContent;
+
+    default:
+        if (cms->d.other->type == V_ASN1_OCTET_STRING)
+            return &cms->d.other->value.octet_string;
+        CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE);
+        return NULL;
+
+    }
+}
+
+/*
+ * Return an ASN1_OBJECT pointer to content type. This allows it to be
+ * accessed or set later.
+ */
+
+static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms)
+{
+    switch (OBJ_obj2nid(cms->contentType)) {
+
+    case NID_pkcs7_signed:
+        return &cms->d.signedData->encapContentInfo->eContentType;
+
+    case NID_pkcs7_enveloped:
+        return &cms->d.envelopedData->encryptedContentInfo->contentType;
+
+    case NID_pkcs7_digest:
+        return &cms->d.digestedData->encapContentInfo->eContentType;
+
+    case NID_pkcs7_encrypted:
+        return &cms->d.encryptedData->encryptedContentInfo->contentType;
+
+    case NID_id_smime_ct_authData:
+        return &cms->d.authenticatedData->encapContentInfo->eContentType;
+
+    case NID_id_smime_ct_compressedData:
+        return &cms->d.compressedData->encapContentInfo->eContentType;
+
+    default:
+        CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE, CMS_R_UNSUPPORTED_CONTENT_TYPE);
+        return NULL;
+
+    }
+}
+
+const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms)
+{
+    ASN1_OBJECT **petype;
+    petype = cms_get0_econtent_type(cms);
+    if (petype)
+        return *petype;
+    return NULL;
+}
+
+int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid)
+{
+    ASN1_OBJECT **petype, *etype;
+    petype = cms_get0_econtent_type(cms);
+    if (!petype)
+        return 0;
+    if (!oid)
+        return 1;
+    etype = OBJ_dup(oid);
+    if (!etype)
+        return 0;
+    ASN1_OBJECT_free(*petype);
+    *petype = etype;
+    return 1;
+}
+
+int CMS_is_detached(CMS_ContentInfo *cms)
+{
+    ASN1_OCTET_STRING **pos;
+    pos = CMS_get0_content(cms);
+    if (!pos)
+        return -1;
+    if (*pos)
+        return 0;
+    return 1;
+}
+
+int CMS_set_detached(CMS_ContentInfo *cms, int detached)
+{
+    ASN1_OCTET_STRING **pos;
+    pos = CMS_get0_content(cms);
+    if (!pos)
+        return 0;
+    if (detached) {
+        ASN1_OCTET_STRING_free(*pos);
+        *pos = NULL;
+        return 1;
+    }
+    if (*pos == NULL)
+        *pos = ASN1_OCTET_STRING_new();
+    if (*pos != NULL) {
+        /*
+         * NB: special flag to show content is created and not read in.
+         */
+        (*pos)->flags |= ASN1_STRING_FLAG_CONT;
+        return 1;
+    }
+    CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE);
+    return 0;
+}
+
+/* Create a digest BIO from an X509_ALGOR structure */
+
+BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm)
+{
+    BIO *mdbio = NULL;
+    const ASN1_OBJECT *digestoid;
+    const EVP_MD *digest;
+    X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm);
+    digest = EVP_get_digestbyobj(digestoid);
+    if (!digest) {
+        CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
+               CMS_R_UNKNOWN_DIGEST_ALGORIHM);
+        goto err;
+    }
+    mdbio = BIO_new(BIO_f_md());
+    if (mdbio == NULL || !BIO_set_md(mdbio, digest)) {
+        CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, CMS_R_MD_BIO_INIT_ERROR);
+        goto err;
+    }
+    return mdbio;
+ err:
+    BIO_free(mdbio);
+    return NULL;
+}
+
+/* Locate a message digest content from a BIO chain based on SignerInfo */
+
+int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
+                                 X509_ALGOR *mdalg)
+{
+    int nid;
+    const ASN1_OBJECT *mdoid;
+    X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg);
+    nid = OBJ_obj2nid(mdoid);
+    /* Look for digest type to match signature */
+    for (;;) {
+        EVP_MD_CTX *mtmp;
+        chain = BIO_find_type(chain, BIO_TYPE_MD);
+        if (chain == NULL) {
+            CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX,
+                   CMS_R_NO_MATCHING_DIGEST);
+            return 0;
+        }
+        BIO_get_md_ctx(chain, &mtmp);
+        if (EVP_MD_CTX_type(mtmp) == nid
+            /*
+             * Workaround for broken implementations that use signature
+             * algorithm OID instead of digest.
+             */
+            || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid)
+            return EVP_MD_CTX_copy_ex(mctx, mtmp);
+        chain = BIO_next(chain);
+    }
+}
+
+static STACK_OF(CMS_CertificateChoices)
+**cms_get0_certificate_choices(CMS_ContentInfo *cms)
+{
+    switch (OBJ_obj2nid(cms->contentType)) {
+
+    case NID_pkcs7_signed:
+        return &cms->d.signedData->certificates;
+
+    case NID_pkcs7_enveloped:
+        if (cms->d.envelopedData->originatorInfo == NULL)
+            return NULL;
+        return &cms->d.envelopedData->originatorInfo->certificates;
+
+    default:
+        CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES,
+               CMS_R_UNSUPPORTED_CONTENT_TYPE);
+        return NULL;
+
+    }
+}
+
+CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms)
+{
+    STACK_OF(CMS_CertificateChoices) **pcerts;
+    CMS_CertificateChoices *cch;
+    pcerts = cms_get0_certificate_choices(cms);
+    if (!pcerts)
+        return NULL;
+    if (!*pcerts)
+        *pcerts = sk_CMS_CertificateChoices_new_null();
+    if (!*pcerts)
+        return NULL;
+    cch = M_ASN1_new_of(CMS_CertificateChoices);
+    if (!cch)
+        return NULL;
+    if (!sk_CMS_CertificateChoices_push(*pcerts, cch)) {
+        M_ASN1_free_of(cch, CMS_CertificateChoices);
+        return NULL;
+    }
+    return cch;
+}
+
+int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert)
+{
+    CMS_CertificateChoices *cch;
+    STACK_OF(CMS_CertificateChoices) **pcerts;
+    int i;
+    pcerts = cms_get0_certificate_choices(cms);
+    if (!pcerts)
+        return 0;
+    for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) {
+        cch = sk_CMS_CertificateChoices_value(*pcerts, i);
+        if (cch->type == CMS_CERTCHOICE_CERT) {
+            if (!X509_cmp(cch->d.certificate, cert)) {
+                CMSerr(CMS_F_CMS_ADD0_CERT,
+                       CMS_R_CERTIFICATE_ALREADY_PRESENT);
+                return 0;
+            }
+        }
+    }
+    cch = CMS_add0_CertificateChoices(cms);
+    if (!cch)
+        return 0;
+    cch->type = CMS_CERTCHOICE_CERT;
+    cch->d.certificate = cert;
+    return 1;
+}
+
+int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert)
+{
+    int r;
+    r = CMS_add0_cert(cms, cert);
+    if (r > 0)
+        X509_up_ref(cert);
+    return r;
+}
+
+static STACK_OF(CMS_RevocationInfoChoice)
+**cms_get0_revocation_choices(CMS_ContentInfo *cms)
+{
+    switch (OBJ_obj2nid(cms->contentType)) {
+
+    case NID_pkcs7_signed:
+        return &cms->d.signedData->crls;
+
+    case NID_pkcs7_enveloped:
+        if (cms->d.envelopedData->originatorInfo == NULL)
+            return NULL;
+        return &cms->d.envelopedData->originatorInfo->crls;
+
+    default:
+        CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES,
+               CMS_R_UNSUPPORTED_CONTENT_TYPE);
+        return NULL;
+
+    }
+}
+
+CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms)
+{
+    STACK_OF(CMS_RevocationInfoChoice) **pcrls;
+    CMS_RevocationInfoChoice *rch;
+    pcrls = cms_get0_revocation_choices(cms);
+    if (!pcrls)
+        return NULL;
+    if (!*pcrls)
+        *pcrls = sk_CMS_RevocationInfoChoice_new_null();
+    if (!*pcrls)
+        return NULL;
+    rch = M_ASN1_new_of(CMS_RevocationInfoChoice);
+    if (!rch)
+        return NULL;
+    if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch)) {
+        M_ASN1_free_of(rch, CMS_RevocationInfoChoice);
+        return NULL;
+    }
+    return rch;
+}
+
+int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl)
+{
+    CMS_RevocationInfoChoice *rch;
+    rch = CMS_add0_RevocationInfoChoice(cms);
+    if (!rch)
+        return 0;
+    rch->type = CMS_REVCHOICE_CRL;
+    rch->d.crl = crl;
+    return 1;
+}
+
+int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl)
+{
+    int r;
+    r = CMS_add0_crl(cms, crl);
+    if (r > 0)
+        X509_CRL_up_ref(crl);
+    return r;
+}
+
+STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms)
+{
+    STACK_OF(X509) *certs = NULL;
+    CMS_CertificateChoices *cch;
+    STACK_OF(CMS_CertificateChoices) **pcerts;
+    int i;
+    pcerts = cms_get0_certificate_choices(cms);
+    if (!pcerts)
+        return NULL;
+    for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) {
+        cch = sk_CMS_CertificateChoices_value(*pcerts, i);
+        if (cch->type == 0) {
+            if (!certs) {
+                certs = sk_X509_new_null();
+                if (!certs)
+                    return NULL;
+            }
+            if (!sk_X509_push(certs, cch->d.certificate)) {
+                sk_X509_pop_free(certs, X509_free);
+                return NULL;
+            }
+            X509_up_ref(cch->d.certificate);
+        }
+    }
+    return certs;
+
+}
+
+STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms)
+{
+    STACK_OF(X509_CRL) *crls = NULL;
+    STACK_OF(CMS_RevocationInfoChoice) **pcrls;
+    CMS_RevocationInfoChoice *rch;
+    int i;
+    pcrls = cms_get0_revocation_choices(cms);
+    if (!pcrls)
+        return NULL;
+    for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++) {
+        rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i);
+        if (rch->type == 0) {
+            if (!crls) {
+                crls = sk_X509_CRL_new_null();
+                if (!crls)
+                    return NULL;
+            }
+            if (!sk_X509_CRL_push(crls, rch->d.crl)) {
+                sk_X509_CRL_pop_free(crls, X509_CRL_free);
+                return NULL;
+            }
+            X509_CRL_up_ref(rch->d.crl);
+        }
+    }
+    return crls;
+}
+
+int cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert)
+{
+    int ret;
+    ret = X509_NAME_cmp(ias->issuer, X509_get_issuer_name(cert));
+    if (ret)
+        return ret;
+    return ASN1_INTEGER_cmp(ias->serialNumber, X509_get_serialNumber(cert));
+}
+
+int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert)
+{
+    const ASN1_OCTET_STRING *cert_keyid = X509_get0_subject_key_id(cert);
+
+    if (cert_keyid == NULL)
+        return -1;
+    return ASN1_OCTET_STRING_cmp(keyid, cert_keyid);
+}
+
+int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert)
+{
+    CMS_IssuerAndSerialNumber *ias;
+    ias = M_ASN1_new_of(CMS_IssuerAndSerialNumber);
+    if (!ias)
+        goto err;
+    if (!X509_NAME_set(&ias->issuer, X509_get_issuer_name(cert)))
+        goto err;
+    if (!ASN1_STRING_copy(ias->serialNumber, X509_get_serialNumber(cert)))
+        goto err;
+    M_ASN1_free_of(*pias, CMS_IssuerAndSerialNumber);
+    *pias = ias;
+    return 1;
+ err:
+    M_ASN1_free_of(ias, CMS_IssuerAndSerialNumber);
+    CMSerr(CMS_F_CMS_SET1_IAS, ERR_R_MALLOC_FAILURE);
+    return 0;
+}
+
+int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert)
+{
+    ASN1_OCTET_STRING *keyid = NULL;
+    const ASN1_OCTET_STRING *cert_keyid;
+    cert_keyid = X509_get0_subject_key_id(cert);
+    if (cert_keyid == NULL) {
+        CMSerr(CMS_F_CMS_SET1_KEYID, CMS_R_CERTIFICATE_HAS_NO_KEYID);
+        return 0;
+    }
+    keyid = ASN1_STRING_dup(cert_keyid);
+    if (!keyid) {
+        CMSerr(CMS_F_CMS_SET1_KEYID, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    ASN1_OCTET_STRING_free(*pkeyid);
+    *pkeyid = keyid;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_pwri.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_pwri.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_pwri.c	(revision 331)
@@ -0,0 +1,392 @@
+/*
+ * Copyright 2009-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 "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include <openssl/rand.h>
+#include <openssl/aes.h>
+#include "cms_lcl.h"
+#include "internal/asn1_int.h"
+
+int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri,
+                                    unsigned char *pass, ossl_ssize_t passlen)
+{
+    CMS_PasswordRecipientInfo *pwri;
+    if (ri->type != CMS_RECIPINFO_PASS) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, CMS_R_NOT_PWRI);
+        return 0;
+    }
+
+    pwri = ri->d.pwri;
+    pwri->pass = pass;
+    if (pass && passlen < 0)
+        passlen = strlen((char *)pass);
+    pwri->passlen = passlen;
+    return 1;
+}
+
+CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
+                                               int iter, int wrap_nid,
+                                               int pbe_nid,
+                                               unsigned char *pass,
+                                               ossl_ssize_t passlen,
+                                               const EVP_CIPHER *kekciph)
+{
+    CMS_RecipientInfo *ri = NULL;
+    CMS_EnvelopedData *env;
+    CMS_PasswordRecipientInfo *pwri;
+    EVP_CIPHER_CTX *ctx = NULL;
+    X509_ALGOR *encalg = NULL;
+    unsigned char iv[EVP_MAX_IV_LENGTH];
+    int ivlen;
+
+    env = cms_get0_enveloped(cms);
+    if (!env)
+        return NULL;
+
+    if (wrap_nid <= 0)
+        wrap_nid = NID_id_alg_PWRI_KEK;
+
+    if (pbe_nid <= 0)
+        pbe_nid = NID_id_pbkdf2;
+
+    /* Get from enveloped data */
+    if (kekciph == NULL)
+        kekciph = env->encryptedContentInfo->cipher;
+
+    if (kekciph == NULL) {
+        CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER);
+        return NULL;
+    }
+    if (wrap_nid != NID_id_alg_PWRI_KEK) {
+        CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
+               CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
+        return NULL;
+    }
+
+    /* Setup algorithm identifier for cipher */
+    encalg = X509_ALGOR_new();
+    if (encalg == NULL) {
+        goto merr;
+    }
+    ctx = EVP_CIPHER_CTX_new();
+
+    if (EVP_EncryptInit_ex(ctx, kekciph, NULL, NULL, NULL) <= 0) {
+        CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB);
+        goto err;
+    }
+
+    ivlen = EVP_CIPHER_CTX_iv_length(ctx);
+
+    if (ivlen > 0) {
+        if (RAND_bytes(iv, ivlen) <= 0)
+            goto err;
+        if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0) {
+            CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB);
+            goto err;
+        }
+        encalg->parameter = ASN1_TYPE_new();
+        if (!encalg->parameter) {
+            CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        if (EVP_CIPHER_param_to_asn1(ctx, encalg->parameter) <= 0) {
+            CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
+                   CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
+            goto err;
+        }
+    }
+
+    encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx));
+
+    EVP_CIPHER_CTX_free(ctx);
+    ctx = NULL;
+
+    /* Initialize recipient info */
+    ri = M_ASN1_new_of(CMS_RecipientInfo);
+    if (ri == NULL)
+        goto merr;
+
+    ri->d.pwri = M_ASN1_new_of(CMS_PasswordRecipientInfo);
+    if (ri->d.pwri == NULL)
+        goto merr;
+    ri->type = CMS_RECIPINFO_PASS;
+
+    pwri = ri->d.pwri;
+    /* Since this is overwritten, free up empty structure already there */
+    X509_ALGOR_free(pwri->keyEncryptionAlgorithm);
+    pwri->keyEncryptionAlgorithm = X509_ALGOR_new();
+    if (pwri->keyEncryptionAlgorithm == NULL)
+        goto merr;
+    pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid);
+    pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new();
+    if (pwri->keyEncryptionAlgorithm->parameter == NULL)
+        goto merr;
+
+    if (!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR),
+                        &pwri->keyEncryptionAlgorithm->parameter->
+                        value.sequence))
+         goto merr;
+    pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE;
+
+    X509_ALGOR_free(encalg);
+    encalg = NULL;
+
+    /* Setup PBE algorithm */
+
+    pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1);
+
+    if (!pwri->keyDerivationAlgorithm)
+        goto err;
+
+    CMS_RecipientInfo_set0_password(ri, pass, passlen);
+    pwri->version = 0;
+
+    if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
+        goto merr;
+
+    return ri;
+
+ merr:
+    CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE);
+ err:
+    EVP_CIPHER_CTX_free(ctx);
+    if (ri)
+        M_ASN1_free_of(ri, CMS_RecipientInfo);
+    X509_ALGOR_free(encalg);
+    return NULL;
+
+}
+
+/*
+ * This is an implementation of the key wrapping mechanism in RFC3211, at
+ * some point this should go into EVP.
+ */
+
+static int kek_unwrap_key(unsigned char *out, size_t *outlen,
+                          const unsigned char *in, size_t inlen,
+                          EVP_CIPHER_CTX *ctx)
+{
+    size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
+    unsigned char *tmp;
+    int outl, rv = 0;
+    if (inlen < 2 * blocklen) {
+        /* too small */
+        return 0;
+    }
+    if (inlen % blocklen) {
+        /* Invalid size */
+        return 0;
+    }
+    tmp = OPENSSL_malloc(inlen);
+    if (tmp == NULL)
+        return 0;
+    /* setup IV by decrypting last two blocks */
+    if (!EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl,
+                           in + inlen - 2 * blocklen, blocklen * 2)
+        /*
+         * Do a decrypt of last decrypted block to set IV to correct value
+         * output it to start of buffer so we don't corrupt decrypted block
+         * this works because buffer is at least two block lengths long.
+         */
+        || !EVP_DecryptUpdate(ctx, tmp, &outl,
+                              tmp + inlen - blocklen, blocklen)
+        /* Can now decrypt first n - 1 blocks */
+        || !EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen)
+
+        /* Reset IV to original value */
+        || !EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL)
+        /* Decrypt again */
+        || !EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen))
+        goto err;
+    /* Check check bytes */
+    if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & (tmp[3] ^ tmp[6])) != 0xff) {
+        /* Check byte failure */
+        goto err;
+    }
+    if (inlen < (size_t)(tmp[0] - 4)) {
+        /* Invalid length value */
+        goto err;
+    }
+    *outlen = (size_t)tmp[0];
+    memcpy(out, tmp + 4, *outlen);
+    rv = 1;
+ err:
+    OPENSSL_clear_free(tmp, inlen);
+    return rv;
+
+}
+
+static int kek_wrap_key(unsigned char *out, size_t *outlen,
+                        const unsigned char *in, size_t inlen,
+                        EVP_CIPHER_CTX *ctx)
+{
+    size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
+    size_t olen;
+    int dummy;
+    /*
+     * First decide length of output buffer: need header and round up to
+     * multiple of block length.
+     */
+    olen = (inlen + 4 + blocklen - 1) / blocklen;
+    olen *= blocklen;
+    if (olen < 2 * blocklen) {
+        /* Key too small */
+        return 0;
+    }
+    if (inlen > 0xFF) {
+        /* Key too large */
+        return 0;
+    }
+    if (out) {
+        /* Set header */
+        out[0] = (unsigned char)inlen;
+        out[1] = in[0] ^ 0xFF;
+        out[2] = in[1] ^ 0xFF;
+        out[3] = in[2] ^ 0xFF;
+        memcpy(out + 4, in, inlen);
+        /* Add random padding to end */
+        if (olen > inlen + 4
+            && RAND_bytes(out + 4 + inlen, olen - 4 - inlen) <= 0)
+            return 0;
+        /* Encrypt twice */
+        if (!EVP_EncryptUpdate(ctx, out, &dummy, out, olen)
+            || !EVP_EncryptUpdate(ctx, out, &dummy, out, olen))
+            return 0;
+    }
+
+    *outlen = olen;
+
+    return 1;
+}
+
+/* Encrypt/Decrypt content key in PWRI recipient info */
+
+int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
+                                 int en_de)
+{
+    CMS_EncryptedContentInfo *ec;
+    CMS_PasswordRecipientInfo *pwri;
+    int r = 0;
+    X509_ALGOR *algtmp, *kekalg = NULL;
+    EVP_CIPHER_CTX *kekctx = NULL;
+    const EVP_CIPHER *kekcipher;
+    unsigned char *key = NULL;
+    size_t keylen;
+
+    ec = cms->d.envelopedData->encryptedContentInfo;
+
+    pwri = ri->d.pwri;
+
+    if (!pwri->pass) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD);
+        return 0;
+    }
+    algtmp = pwri->keyEncryptionAlgorithm;
+
+    if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
+               CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
+        return 0;
+    }
+
+    kekalg = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR),
+                                       algtmp->parameter);
+
+    if (kekalg == NULL) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
+               CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER);
+        return 0;
+    }
+
+    kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
+
+    if (!kekcipher) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNKNOWN_CIPHER);
+        return 0;
+    }
+
+    kekctx = EVP_CIPHER_CTX_new();
+    if (kekctx == NULL) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    /* Fixup cipher based on AlgorithmIdentifier to set IV etc */
+    if (!EVP_CipherInit_ex(kekctx, kekcipher, NULL, NULL, NULL, en_de))
+        goto err;
+    EVP_CIPHER_CTX_set_padding(kekctx, 0);
+    if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) < 0) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
+               CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
+        goto err;
+    }
+
+    algtmp = pwri->keyDerivationAlgorithm;
+
+    /* Finish password based key derivation to setup key in "ctx" */
+
+    if (EVP_PBE_CipherInit(algtmp->algorithm,
+                           (char *)pwri->pass, pwri->passlen,
+                           algtmp->parameter, kekctx, en_de) < 0) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB);
+        goto err;
+    }
+
+    /* Finally wrap/unwrap the key */
+
+    if (en_de) {
+
+        if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx))
+            goto err;
+
+        key = OPENSSL_malloc(keylen);
+
+        if (key == NULL)
+            goto err;
+
+        if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx))
+            goto err;
+        pwri->encryptedKey->data = key;
+        pwri->encryptedKey->length = keylen;
+    } else {
+        key = OPENSSL_malloc(pwri->encryptedKey->length);
+
+        if (key == NULL) {
+            CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        if (!kek_unwrap_key(key, &keylen,
+                            pwri->encryptedKey->data,
+                            pwri->encryptedKey->length, kekctx)) {
+            CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNWRAP_FAILURE);
+            goto err;
+        }
+
+        ec->key = key;
+        ec->keylen = keylen;
+
+    }
+
+    r = 1;
+
+ err:
+
+    EVP_CIPHER_CTX_free(kekctx);
+
+    if (!r)
+        OPENSSL_free(key);
+    X509_ALGOR_free(kekalg);
+
+    return r;
+
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_sd.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_sd.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_sd.c	(revision 331)
@@ -0,0 +1,923 @@
+/*
+ * Copyright 2008-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 "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include "cms_lcl.h"
+#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
+
+/* CMS SignedData Utilities */
+
+static CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms)
+{
+    if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed) {
+        CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA);
+        return NULL;
+    }
+    return cms->d.signedData;
+}
+
+static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms)
+{
+    if (cms->d.other == NULL) {
+        cms->d.signedData = M_ASN1_new_of(CMS_SignedData);
+        if (!cms->d.signedData) {
+            CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE);
+            return NULL;
+        }
+        cms->d.signedData->version = 1;
+        cms->d.signedData->encapContentInfo->eContentType =
+            OBJ_nid2obj(NID_pkcs7_data);
+        cms->d.signedData->encapContentInfo->partial = 1;
+        ASN1_OBJECT_free(cms->contentType);
+        cms->contentType = OBJ_nid2obj(NID_pkcs7_signed);
+        return cms->d.signedData;
+    }
+    return cms_get0_signed(cms);
+}
+
+/* Just initialise SignedData e.g. for certs only structure */
+
+int CMS_SignedData_init(CMS_ContentInfo *cms)
+{
+    if (cms_signed_data_init(cms))
+        return 1;
+    else
+        return 0;
+}
+
+/* Check structures and fixup version numbers (if necessary) */
+
+static void cms_sd_set_version(CMS_SignedData *sd)
+{
+    int i;
+    CMS_CertificateChoices *cch;
+    CMS_RevocationInfoChoice *rch;
+    CMS_SignerInfo *si;
+
+    for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++) {
+        cch = sk_CMS_CertificateChoices_value(sd->certificates, i);
+        if (cch->type == CMS_CERTCHOICE_OTHER) {
+            if (sd->version < 5)
+                sd->version = 5;
+        } else if (cch->type == CMS_CERTCHOICE_V2ACERT) {
+            if (sd->version < 4)
+                sd->version = 4;
+        } else if (cch->type == CMS_CERTCHOICE_V1ACERT) {
+            if (sd->version < 3)
+                sd->version = 3;
+        }
+    }
+
+    for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++) {
+        rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i);
+        if (rch->type == CMS_REVCHOICE_OTHER) {
+            if (sd->version < 5)
+                sd->version = 5;
+        }
+    }
+
+    if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data)
+        && (sd->version < 3))
+        sd->version = 3;
+
+    for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
+        si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
+        if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
+            if (si->version < 3)
+                si->version = 3;
+            if (sd->version < 3)
+                sd->version = 3;
+        } else if (si->version < 1)
+            si->version = 1;
+    }
+
+    if (sd->version < 1)
+        sd->version = 1;
+
+}
+
+/* Copy an existing messageDigest value */
+
+static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
+{
+    STACK_OF(CMS_SignerInfo) *sinfos;
+    CMS_SignerInfo *sitmp;
+    int i;
+    sinfos = CMS_get0_SignerInfos(cms);
+    for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
+        ASN1_OCTET_STRING *messageDigest;
+        sitmp = sk_CMS_SignerInfo_value(sinfos, i);
+        if (sitmp == si)
+            continue;
+        if (CMS_signed_get_attr_count(sitmp) < 0)
+            continue;
+        if (OBJ_cmp(si->digestAlgorithm->algorithm,
+                    sitmp->digestAlgorithm->algorithm))
+            continue;
+        messageDigest = CMS_signed_get0_data_by_OBJ(sitmp,
+                                                    OBJ_nid2obj
+                                                    (NID_pkcs9_messageDigest),
+                                                    -3, V_ASN1_OCTET_STRING);
+        if (!messageDigest) {
+            CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST,
+                   CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
+            return 0;
+        }
+
+        if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
+                                        V_ASN1_OCTET_STRING,
+                                        messageDigest, -1))
+            return 1;
+        else
+            return 0;
+    }
+    CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST);
+    return 0;
+}
+
+int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type)
+{
+    switch (type) {
+    case CMS_SIGNERINFO_ISSUER_SERIAL:
+        if (!cms_set1_ias(&sid->d.issuerAndSerialNumber, cert))
+            return 0;
+        break;
+
+    case CMS_SIGNERINFO_KEYIDENTIFIER:
+        if (!cms_set1_keyid(&sid->d.subjectKeyIdentifier, cert))
+            return 0;
+        break;
+
+    default:
+        CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID);
+        return 0;
+    }
+
+    sid->type = type;
+
+    return 1;
+}
+
+int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
+                                        ASN1_OCTET_STRING **keyid,
+                                        X509_NAME **issuer,
+                                        ASN1_INTEGER **sno)
+{
+    if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) {
+        if (issuer)
+            *issuer = sid->d.issuerAndSerialNumber->issuer;
+        if (sno)
+            *sno = sid->d.issuerAndSerialNumber->serialNumber;
+    } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
+        if (keyid)
+            *keyid = sid->d.subjectKeyIdentifier;
+    } else
+        return 0;
+    return 1;
+}
+
+int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)
+{
+    if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)
+        return cms_ias_cert_cmp(sid->d.issuerAndSerialNumber, cert);
+    else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
+        return cms_keyid_cert_cmp(sid->d.subjectKeyIdentifier, cert);
+    else
+        return -1;
+}
+
+static int cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd)
+{
+    EVP_PKEY *pkey = si->pkey;
+    int i;
+    if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
+        return 1;
+    i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si);
+    if (i == -2) {
+        CMSerr(CMS_F_CMS_SD_ASN1_CTRL, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+        return 0;
+    }
+    if (i <= 0) {
+        CMSerr(CMS_F_CMS_SD_ASN1_CTRL, CMS_R_CTRL_FAILURE);
+        return 0;
+    }
+    return 1;
+}
+
+CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
+                                X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
+                                unsigned int flags)
+{
+    CMS_SignedData *sd;
+    CMS_SignerInfo *si = NULL;
+    X509_ALGOR *alg;
+    int i, type;
+    if (!X509_check_private_key(signer, pk)) {
+        CMSerr(CMS_F_CMS_ADD1_SIGNER,
+               CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+        return NULL;
+    }
+    sd = cms_signed_data_init(cms);
+    if (!sd)
+        goto err;
+    si = M_ASN1_new_of(CMS_SignerInfo);
+    if (!si)
+        goto merr;
+    /* Call for side-effect of computing hash and caching extensions */
+    X509_check_purpose(signer, -1, -1);
+
+    X509_up_ref(signer);
+    EVP_PKEY_up_ref(pk);
+
+    si->pkey = pk;
+    si->signer = signer;
+    si->mctx = EVP_MD_CTX_new();
+    si->pctx = NULL;
+
+    if (si->mctx == NULL) {
+        CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (flags & CMS_USE_KEYID) {
+        si->version = 3;
+        if (sd->version < 3)
+            sd->version = 3;
+        type = CMS_SIGNERINFO_KEYIDENTIFIER;
+    } else {
+        type = CMS_SIGNERINFO_ISSUER_SERIAL;
+        si->version = 1;
+    }
+
+    if (!cms_set1_SignerIdentifier(si->sid, signer, type))
+        goto err;
+
+    if (md == NULL) {
+        int def_nid;
+        if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0)
+            goto err;
+        md = EVP_get_digestbynid(def_nid);
+        if (md == NULL) {
+            CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST);
+            goto err;
+        }
+    }
+
+    if (!md) {
+        CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET);
+        goto err;
+    }
+
+    X509_ALGOR_set_md(si->digestAlgorithm, md);
+
+    /* See if digest is present in digestAlgorithms */
+    for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
+        const ASN1_OBJECT *aoid;
+        alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
+        X509_ALGOR_get0(&aoid, NULL, NULL, alg);
+        if (OBJ_obj2nid(aoid) == EVP_MD_type(md))
+            break;
+    }
+
+    if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) {
+        alg = X509_ALGOR_new();
+        if (alg == NULL)
+            goto merr;
+        X509_ALGOR_set_md(alg, md);
+        if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) {
+            X509_ALGOR_free(alg);
+            goto merr;
+        }
+    }
+
+    if (!(flags & CMS_KEY_PARAM) && !cms_sd_asn1_ctrl(si, 0))
+        goto err;
+    if (!(flags & CMS_NOATTR)) {
+        /*
+         * Initialize signed attributes structure so other attributes
+         * such as signing time etc are added later even if we add none here.
+         */
+        if (!si->signedAttrs) {
+            si->signedAttrs = sk_X509_ATTRIBUTE_new_null();
+            if (!si->signedAttrs)
+                goto merr;
+        }
+
+        if (!(flags & CMS_NOSMIMECAP)) {
+            STACK_OF(X509_ALGOR) *smcap = NULL;
+            i = CMS_add_standard_smimecap(&smcap);
+            if (i)
+                i = CMS_add_smimecap(si, smcap);
+            sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
+            if (!i)
+                goto merr;
+        }
+        if (flags & CMS_REUSE_DIGEST) {
+            if (!cms_copy_messageDigest(cms, si))
+                goto err;
+            if (!(flags & (CMS_PARTIAL | CMS_KEY_PARAM)) &&
+                !CMS_SignerInfo_sign(si))
+                goto err;
+        }
+    }
+
+    if (!(flags & CMS_NOCERTS)) {
+        /* NB ignore -1 return for duplicate cert */
+        if (!CMS_add1_cert(cms, signer))
+            goto merr;
+    }
+
+    if (flags & CMS_KEY_PARAM) {
+        if (flags & CMS_NOATTR) {
+            si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL);
+            if (si->pctx == NULL)
+                goto err;
+            if (EVP_PKEY_sign_init(si->pctx) <= 0)
+                goto err;
+            if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0)
+                goto err;
+        } else if (EVP_DigestSignInit(si->mctx, &si->pctx, md, NULL, pk) <=
+                   0)
+            goto err;
+    }
+
+    if (!sd->signerInfos)
+        sd->signerInfos = sk_CMS_SignerInfo_new_null();
+    if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si))
+        goto merr;
+
+    return si;
+
+ merr:
+    CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE);
+ err:
+    M_ASN1_free_of(si, CMS_SignerInfo);
+    return NULL;
+
+}
+
+static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
+{
+    ASN1_TIME *tt;
+    int r = 0;
+    if (t)
+        tt = t;
+    else
+        tt = X509_gmtime_adj(NULL, 0);
+
+    if (!tt)
+        goto merr;
+
+    if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime,
+                                    tt->type, tt, -1) <= 0)
+        goto merr;
+
+    r = 1;
+
+ merr:
+
+    if (!t)
+        ASN1_TIME_free(tt);
+
+    if (!r)
+        CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE);
+
+    return r;
+
+}
+
+EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si)
+{
+    return si->pctx;
+}
+
+EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si)
+{
+    return si->mctx;
+}
+
+STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms)
+{
+    CMS_SignedData *sd;
+    sd = cms_get0_signed(cms);
+    if (!sd)
+        return NULL;
+    return sd->signerInfos;
+}
+
+STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
+{
+    STACK_OF(X509) *signers = NULL;
+    STACK_OF(CMS_SignerInfo) *sinfos;
+    CMS_SignerInfo *si;
+    int i;
+    sinfos = CMS_get0_SignerInfos(cms);
+    for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
+        si = sk_CMS_SignerInfo_value(sinfos, i);
+        if (si->signer) {
+            if (!signers) {
+                signers = sk_X509_new_null();
+                if (!signers)
+                    return NULL;
+            }
+            if (!sk_X509_push(signers, si->signer)) {
+                sk_X509_free(signers);
+                return NULL;
+            }
+        }
+    }
+    return signers;
+}
+
+void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer)
+{
+    if (signer) {
+        X509_up_ref(signer);
+        EVP_PKEY_free(si->pkey);
+        si->pkey = X509_get_pubkey(signer);
+    }
+    X509_free(si->signer);
+    si->signer = signer;
+}
+
+int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
+                                  ASN1_OCTET_STRING **keyid,
+                                  X509_NAME **issuer, ASN1_INTEGER **sno)
+{
+    return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno);
+}
+
+int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert)
+{
+    return cms_SignerIdentifier_cert_cmp(si->sid, cert);
+}
+
+int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts,
+                           unsigned int flags)
+{
+    CMS_SignedData *sd;
+    CMS_SignerInfo *si;
+    CMS_CertificateChoices *cch;
+    STACK_OF(CMS_CertificateChoices) *certs;
+    X509 *x;
+    int i, j;
+    int ret = 0;
+    sd = cms_get0_signed(cms);
+    if (!sd)
+        return -1;
+    certs = sd->certificates;
+    for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
+        si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
+        if (si->signer)
+            continue;
+
+        for (j = 0; j < sk_X509_num(scerts); j++) {
+            x = sk_X509_value(scerts, j);
+            if (CMS_SignerInfo_cert_cmp(si, x) == 0) {
+                CMS_SignerInfo_set1_signer_cert(si, x);
+                ret++;
+                break;
+            }
+        }
+
+        if (si->signer || (flags & CMS_NOINTERN))
+            continue;
+
+        for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) {
+            cch = sk_CMS_CertificateChoices_value(certs, j);
+            if (cch->type != 0)
+                continue;
+            x = cch->d.certificate;
+            if (CMS_SignerInfo_cert_cmp(si, x) == 0) {
+                CMS_SignerInfo_set1_signer_cert(si, x);
+                ret++;
+                break;
+            }
+        }
+    }
+    return ret;
+}
+
+void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk,
+                              X509 **signer, X509_ALGOR **pdig,
+                              X509_ALGOR **psig)
+{
+    if (pk)
+        *pk = si->pkey;
+    if (signer)
+        *signer = si->signer;
+    if (pdig)
+        *pdig = si->digestAlgorithm;
+    if (psig)
+        *psig = si->signatureAlgorithm;
+}
+
+ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si)
+{
+    return si->signature;
+}
+
+static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
+                                       CMS_SignerInfo *si, BIO *chain)
+{
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+    int r = 0;
+    EVP_PKEY_CTX *pctx = NULL;
+
+    if (mctx == NULL) {
+        CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    if (!si->pkey) {
+        CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY);
+        goto err;
+    }
+
+    if (!cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm))
+        goto err;
+    /* Set SignerInfo algorithm details if we used custom parameter */
+    if (si->pctx && !cms_sd_asn1_ctrl(si, 0))
+        goto err;
+
+    /*
+     * If any signed attributes calculate and add messageDigest attribute
+     */
+
+    if (CMS_signed_get_attr_count(si) >= 0) {
+        ASN1_OBJECT *ctype =
+            cms->d.signedData->encapContentInfo->eContentType;
+        unsigned char md[EVP_MAX_MD_SIZE];
+        unsigned int mdlen;
+        if (!EVP_DigestFinal_ex(mctx, md, &mdlen))
+            goto err;
+        if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
+                                         V_ASN1_OCTET_STRING, md, mdlen))
+            goto err;
+        /* Copy content type across */
+        if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType,
+                                        V_ASN1_OBJECT, ctype, -1) <= 0)
+            goto err;
+        if (!CMS_SignerInfo_sign(si))
+            goto err;
+    } else if (si->pctx) {
+        unsigned char *sig;
+        size_t siglen;
+        unsigned char md[EVP_MAX_MD_SIZE];
+        unsigned int mdlen;
+        pctx = si->pctx;
+        if (!EVP_DigestFinal_ex(mctx, md, &mdlen))
+            goto err;
+        siglen = EVP_PKEY_size(si->pkey);
+        sig = OPENSSL_malloc(siglen);
+        if (sig == NULL) {
+            CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        if (EVP_PKEY_sign(pctx, sig, &siglen, md, mdlen) <= 0) {
+            OPENSSL_free(sig);
+            goto err;
+        }
+        ASN1_STRING_set0(si->signature, sig, siglen);
+    } else {
+        unsigned char *sig;
+        unsigned int siglen;
+        sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey));
+        if (sig == NULL) {
+            CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        if (!EVP_SignFinal(mctx, sig, &siglen, si->pkey)) {
+            CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_SIGNFINAL_ERROR);
+            OPENSSL_free(sig);
+            goto err;
+        }
+        ASN1_STRING_set0(si->signature, sig, siglen);
+    }
+
+    r = 1;
+
+ err:
+    EVP_MD_CTX_free(mctx);
+    EVP_PKEY_CTX_free(pctx);
+    return r;
+
+}
+
+int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
+{
+    STACK_OF(CMS_SignerInfo) *sinfos;
+    CMS_SignerInfo *si;
+    int i;
+    sinfos = CMS_get0_SignerInfos(cms);
+    for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
+        si = sk_CMS_SignerInfo_value(sinfos, i);
+        if (!cms_SignerInfo_content_sign(cms, si, chain))
+            return 0;
+    }
+    cms->d.signedData->encapContentInfo->partial = 0;
+    return 1;
+}
+
+int CMS_SignerInfo_sign(CMS_SignerInfo *si)
+{
+    EVP_MD_CTX *mctx = si->mctx;
+    EVP_PKEY_CTX *pctx;
+    unsigned char *abuf = NULL;
+    int alen;
+    size_t siglen;
+    const EVP_MD *md = NULL;
+
+    md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
+    if (md == NULL)
+        return 0;
+
+    if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) {
+        if (!cms_add1_signingTime(si, NULL))
+            goto err;
+    }
+
+    if (si->pctx)
+        pctx = si->pctx;
+    else {
+        EVP_MD_CTX_reset(mctx);
+        if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0)
+            goto err;
+    }
+
+    if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
+                          EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) {
+        CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
+        goto err;
+    }
+
+    alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
+                         ASN1_ITEM_rptr(CMS_Attributes_Sign));
+    if (!abuf)
+        goto err;
+    if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0)
+        goto err;
+    if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0)
+        goto err;
+    OPENSSL_free(abuf);
+    abuf = OPENSSL_malloc(siglen);
+    if (abuf == NULL)
+        goto err;
+    if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0)
+        goto err;
+
+    if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
+                          EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) {
+        CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
+        goto err;
+    }
+
+    EVP_MD_CTX_reset(mctx);
+
+    ASN1_STRING_set0(si->signature, abuf, siglen);
+
+    return 1;
+
+ err:
+    OPENSSL_free(abuf);
+    EVP_MD_CTX_reset(mctx);
+    return 0;
+
+}
+
+int CMS_SignerInfo_verify(CMS_SignerInfo *si)
+{
+    EVP_MD_CTX *mctx = NULL;
+    unsigned char *abuf = NULL;
+    int alen, r = -1;
+    const EVP_MD *md = NULL;
+
+    if (!si->pkey) {
+        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY);
+        return -1;
+    }
+
+    md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
+    if (md == NULL)
+        return -1;
+    if (si->mctx == NULL)
+        si->mctx = EVP_MD_CTX_new();
+    mctx = si->mctx;
+    if (EVP_DigestVerifyInit(mctx, &si->pctx, md, NULL, si->pkey) <= 0)
+        goto err;
+
+    if (!cms_sd_asn1_ctrl(si, 1))
+        goto err;
+
+    alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
+                         ASN1_ITEM_rptr(CMS_Attributes_Verify));
+    if (!abuf)
+        goto err;
+    r = EVP_DigestVerifyUpdate(mctx, abuf, alen);
+    OPENSSL_free(abuf);
+    if (r <= 0) {
+        r = -1;
+        goto err;
+    }
+    r = EVP_DigestVerifyFinal(mctx,
+                              si->signature->data, si->signature->length);
+    if (r <= 0)
+        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE);
+ err:
+    EVP_MD_CTX_reset(mctx);
+    return r;
+}
+
+/* Create a chain of digest BIOs from a CMS ContentInfo */
+
+BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms)
+{
+    int i;
+    CMS_SignedData *sd;
+    BIO *chain = NULL;
+    sd = cms_get0_signed(cms);
+    if (!sd)
+        return NULL;
+    if (cms->d.signedData->encapContentInfo->partial)
+        cms_sd_set_version(sd);
+    for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
+        X509_ALGOR *digestAlgorithm;
+        BIO *mdbio;
+        digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
+        mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm);
+        if (!mdbio)
+            goto err;
+        if (chain)
+            BIO_push(chain, mdbio);
+        else
+            chain = mdbio;
+    }
+    return chain;
+ err:
+    BIO_free_all(chain);
+    return NULL;
+}
+
+int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
+{
+    ASN1_OCTET_STRING *os = NULL;
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+    EVP_PKEY_CTX *pkctx = NULL;
+    int r = -1;
+    unsigned char mval[EVP_MAX_MD_SIZE];
+    unsigned int mlen;
+
+    if (mctx == NULL) {
+        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    /* If we have any signed attributes look for messageDigest value */
+    if (CMS_signed_get_attr_count(si) >= 0) {
+        os = CMS_signed_get0_data_by_OBJ(si,
+                                         OBJ_nid2obj(NID_pkcs9_messageDigest),
+                                         -3, V_ASN1_OCTET_STRING);
+        if (!os) {
+            CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+                   CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
+            goto err;
+        }
+    }
+
+    if (!cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm))
+        goto err;
+
+    if (EVP_DigestFinal_ex(mctx, mval, &mlen) <= 0) {
+        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+               CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
+        goto err;
+    }
+
+    /* If messageDigest found compare it */
+
+    if (os) {
+        if (mlen != (unsigned int)os->length) {
+            CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+                   CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH);
+            goto err;
+        }
+
+        if (memcmp(mval, os->data, mlen)) {
+            CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+                   CMS_R_VERIFICATION_FAILURE);
+            r = 0;
+        } else
+            r = 1;
+    } else {
+        const EVP_MD *md = EVP_MD_CTX_md(mctx);
+        pkctx = EVP_PKEY_CTX_new(si->pkey, NULL);
+        if (pkctx == NULL)
+            goto err;
+        if (EVP_PKEY_verify_init(pkctx) <= 0)
+            goto err;
+        if (EVP_PKEY_CTX_set_signature_md(pkctx, md) <= 0)
+            goto err;
+        si->pctx = pkctx;
+        if (!cms_sd_asn1_ctrl(si, 1))
+            goto err;
+        r = EVP_PKEY_verify(pkctx, si->signature->data,
+                            si->signature->length, mval, mlen);
+        if (r <= 0) {
+            CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+                   CMS_R_VERIFICATION_FAILURE);
+            r = 0;
+        }
+    }
+
+ err:
+    EVP_PKEY_CTX_free(pkctx);
+    EVP_MD_CTX_free(mctx);
+    return r;
+
+}
+
+int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs)
+{
+    unsigned char *smder = NULL;
+    int smderlen, r;
+    smderlen = i2d_X509_ALGORS(algs, &smder);
+    if (smderlen <= 0)
+        return 0;
+    r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities,
+                                    V_ASN1_SEQUENCE, smder, smderlen);
+    OPENSSL_free(smder);
+    return r;
+}
+
+int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
+                            int algnid, int keysize)
+{
+    X509_ALGOR *alg;
+    ASN1_INTEGER *key = NULL;
+    if (keysize > 0) {
+        key = ASN1_INTEGER_new();
+        if (key == NULL || !ASN1_INTEGER_set(key, keysize))
+            return 0;
+    }
+    alg = X509_ALGOR_new();
+    if (alg == NULL) {
+        ASN1_INTEGER_free(key);
+        return 0;
+    }
+
+    X509_ALGOR_set0(alg, OBJ_nid2obj(algnid),
+                    key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key);
+    if (*algs == NULL)
+        *algs = sk_X509_ALGOR_new_null();
+    if (*algs == NULL || !sk_X509_ALGOR_push(*algs, alg)) {
+        X509_ALGOR_free(alg);
+        return 0;
+    }
+    return 1;
+}
+
+/* Check to see if a cipher exists and if so add S/MIME capabilities */
+
+static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
+{
+    if (EVP_get_cipherbynid(nid))
+        return CMS_add_simple_smimecap(sk, nid, arg);
+    return 1;
+}
+
+static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
+{
+    if (EVP_get_digestbynid(nid))
+        return CMS_add_simple_smimecap(sk, nid, arg);
+    return 1;
+}
+
+int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap)
+{
+    if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
+        || !cms_add_digest_smcap(smcap, NID_id_GostR3411_2012_256, -1)
+        || !cms_add_digest_smcap(smcap, NID_id_GostR3411_2012_512, -1)
+        || !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
+        || !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
+        || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
+        || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
+        || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
+        || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128)
+        || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64)
+        || !cms_add_cipher_smcap(smcap, NID_des_cbc, -1)
+        || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40))
+        return 0;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_smime.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_smime.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cms/cms_smime.c	(revision 331)
@@ -0,0 +1,844 @@
+/*
+ * Copyright 2008-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 "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include "cms_lcl.h"
+#include "internal/asn1_int.h"
+
+static BIO *cms_get_text_bio(BIO *out, unsigned int flags)
+{
+    BIO *rbio;
+    if (out == NULL)
+        rbio = BIO_new(BIO_s_null());
+    else if (flags & CMS_TEXT) {
+        rbio = BIO_new(BIO_s_mem());
+        BIO_set_mem_eof_return(rbio, 0);
+    } else
+        rbio = out;
+    return rbio;
+}
+
+static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
+{
+    unsigned char buf[4096];
+    int r = 0, i;
+    BIO *tmpout;
+
+    tmpout = cms_get_text_bio(out, flags);
+
+    if (tmpout == NULL) {
+        CMSerr(CMS_F_CMS_COPY_CONTENT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    /* Read all content through chain to process digest, decrypt etc */
+    for (;;) {
+        i = BIO_read(in, buf, sizeof(buf));
+        if (i <= 0) {
+            if (BIO_method_type(in) == BIO_TYPE_CIPHER) {
+                if (!BIO_get_cipher_status(in))
+                    goto err;
+            }
+            if (i < 0)
+                goto err;
+            break;
+        }
+
+        if (tmpout && (BIO_write(tmpout, buf, i) != i))
+            goto err;
+    }
+
+    if (flags & CMS_TEXT) {
+        if (!SMIME_text(tmpout, out)) {
+            CMSerr(CMS_F_CMS_COPY_CONTENT, CMS_R_SMIME_TEXT_ERROR);
+            goto err;
+        }
+    }
+
+    r = 1;
+
+ err:
+    if (tmpout != out)
+        BIO_free(tmpout);
+    return r;
+
+}
+
+static int check_content(CMS_ContentInfo *cms)
+{
+    ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
+    if (!pos || !*pos) {
+        CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT);
+        return 0;
+    }
+    return 1;
+}
+
+static void do_free_upto(BIO *f, BIO *upto)
+{
+    if (upto) {
+        BIO *tbio;
+        do {
+            tbio = BIO_pop(f);
+            BIO_free(f);
+            f = tbio;
+        }
+        while (f && f != upto);
+    } else
+        BIO_free_all(f);
+}
+
+int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags)
+{
+    BIO *cont;
+    int r;
+    if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) {
+        CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA);
+        return 0;
+    }
+    cont = CMS_dataInit(cms, NULL);
+    if (!cont)
+        return 0;
+    r = cms_copy_content(out, cont, flags);
+    BIO_free_all(cont);
+    return r;
+}
+
+CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags)
+{
+    CMS_ContentInfo *cms;
+    cms = cms_Data_create();
+    if (!cms)
+        return NULL;
+
+    if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
+        return cms;
+
+    CMS_ContentInfo_free(cms);
+
+    return NULL;
+}
+
+int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+                      unsigned int flags)
+{
+    BIO *cont;
+    int r;
+    if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) {
+        CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA);
+        return 0;
+    }
+
+    if (!dcont && !check_content(cms))
+        return 0;
+
+    cont = CMS_dataInit(cms, dcont);
+    if (!cont)
+        return 0;
+    r = cms_copy_content(out, cont, flags);
+    if (r)
+        r = cms_DigestedData_do_final(cms, cont, 1);
+    do_free_upto(cont, dcont);
+    return r;
+}
+
+CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
+                                   unsigned int flags)
+{
+    CMS_ContentInfo *cms;
+    if (!md)
+        md = EVP_sha1();
+    cms = cms_DigestedData_create(md);
+    if (!cms)
+        return NULL;
+
+    if (!(flags & CMS_DETACHED))
+        CMS_set_detached(cms, 0);
+
+    if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
+        return cms;
+
+    CMS_ContentInfo_free(cms);
+    return NULL;
+}
+
+int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
+                              const unsigned char *key, size_t keylen,
+                              BIO *dcont, BIO *out, unsigned int flags)
+{
+    BIO *cont;
+    int r;
+    if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) {
+        CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT,
+               CMS_R_TYPE_NOT_ENCRYPTED_DATA);
+        return 0;
+    }
+
+    if (!dcont && !check_content(cms))
+        return 0;
+
+    if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0)
+        return 0;
+    cont = CMS_dataInit(cms, dcont);
+    if (!cont)
+        return 0;
+    r = cms_copy_content(out, cont, flags);
+    do_free_upto(cont, dcont);
+    return r;
+}
+
+CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
+                                           const unsigned char *key,
+                                           size_t keylen, unsigned int flags)
+{
+    CMS_ContentInfo *cms;
+    if (!cipher) {
+        CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER);
+        return NULL;
+    }
+    cms = CMS_ContentInfo_new();
+    if (cms == NULL)
+        return NULL;
+    if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen))
+        return NULL;
+
+    if (!(flags & CMS_DETACHED))
+        CMS_set_detached(cms, 0);
+
+    if ((flags & (CMS_STREAM | CMS_PARTIAL))
+        || CMS_final(cms, in, NULL, flags))
+        return cms;
+
+    CMS_ContentInfo_free(cms);
+    return NULL;
+}
+
+static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
+                                      X509_STORE *store,
+                                      STACK_OF(X509) *certs,
+                                      STACK_OF(X509_CRL) *crls)
+{
+    X509_STORE_CTX *ctx = X509_STORE_CTX_new();
+    X509 *signer;
+    int i, j, r = 0;
+
+    if (ctx == NULL) {
+        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
+    if (!X509_STORE_CTX_init(ctx, store, signer, certs)) {
+        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, CMS_R_STORE_INIT_ERROR);
+        goto err;
+    }
+    X509_STORE_CTX_set_default(ctx, "smime_sign");
+    if (crls)
+        X509_STORE_CTX_set0_crls(ctx, crls);
+
+    i = X509_verify_cert(ctx);
+    if (i <= 0) {
+        j = X509_STORE_CTX_get_error(ctx);
+        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT,
+               CMS_R_CERTIFICATE_VERIFY_ERROR);
+        ERR_add_error_data(2, "Verify error:",
+                           X509_verify_cert_error_string(j));
+        goto err;
+    }
+    r = 1;
+ err:
+    X509_STORE_CTX_free(ctx);
+    return r;
+
+}
+
+int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
+               X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags)
+{
+    CMS_SignerInfo *si;
+    STACK_OF(CMS_SignerInfo) *sinfos;
+    STACK_OF(X509) *cms_certs = NULL;
+    STACK_OF(X509_CRL) *crls = NULL;
+    X509 *signer;
+    int i, scount = 0, ret = 0;
+    BIO *cmsbio = NULL, *tmpin = NULL, *tmpout = NULL;
+
+    if (!dcont && !check_content(cms))
+        return 0;
+    if (dcont && !(flags & CMS_BINARY)) {
+        const ASN1_OBJECT *coid = CMS_get0_eContentType(cms);
+        if (OBJ_obj2nid(coid) == NID_id_ct_asciiTextWithCRLF)
+            flags |= CMS_ASCIICRLF;
+    }
+
+    /* Attempt to find all signer certificates */
+
+    sinfos = CMS_get0_SignerInfos(cms);
+
+    if (sk_CMS_SignerInfo_num(sinfos) <= 0) {
+        CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_SIGNERS);
+        goto err;
+    }
+
+    for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
+        si = sk_CMS_SignerInfo_value(sinfos, i);
+        CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
+        if (signer)
+            scount++;
+    }
+
+    if (scount != sk_CMS_SignerInfo_num(sinfos))
+        scount += CMS_set1_signers_certs(cms, certs, flags);
+
+    if (scount != sk_CMS_SignerInfo_num(sinfos)) {
+        CMSerr(CMS_F_CMS_VERIFY, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND);
+        goto err;
+    }
+
+    /* Attempt to verify all signers certs */
+
+    if (!(flags & CMS_NO_SIGNER_CERT_VERIFY)) {
+        cms_certs = CMS_get1_certs(cms);
+        if (!(flags & CMS_NOCRL))
+            crls = CMS_get1_crls(cms);
+        for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
+            si = sk_CMS_SignerInfo_value(sinfos, i);
+            if (!cms_signerinfo_verify_cert(si, store, cms_certs, crls))
+                goto err;
+        }
+    }
+
+    /* Attempt to verify all SignerInfo signed attribute signatures */
+
+    if (!(flags & CMS_NO_ATTR_VERIFY)) {
+        for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
+            si = sk_CMS_SignerInfo_value(sinfos, i);
+            if (CMS_signed_get_attr_count(si) < 0)
+                continue;
+            if (CMS_SignerInfo_verify(si) <= 0)
+                goto err;
+        }
+    }
+
+    /*
+     * Performance optimization: if the content is a memory BIO then store
+     * its contents in a temporary read only memory BIO. This avoids
+     * potentially large numbers of slow copies of data which will occur when
+     * reading from a read write memory BIO when signatures are calculated.
+     */
+
+    if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM)) {
+        char *ptr;
+        long len;
+        len = BIO_get_mem_data(dcont, &ptr);
+        tmpin = BIO_new_mem_buf(ptr, len);
+        if (tmpin == NULL) {
+            CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE);
+            goto err2;
+        }
+    } else
+        tmpin = dcont;
+    /*
+     * If not binary mode and detached generate digests by *writing* through
+     * the BIO. That makes it possible to canonicalise the input.
+     */
+    if (!(flags & SMIME_BINARY) && dcont) {
+        /*
+         * Create output BIO so we can either handle text or to ensure
+         * included content doesn't override detached content.
+         */
+        tmpout = cms_get_text_bio(out, flags);
+        if (!tmpout) {
+            CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        cmsbio = CMS_dataInit(cms, tmpout);
+        if (!cmsbio)
+            goto err;
+        /*
+         * Don't use SMIME_TEXT for verify: it adds headers and we want to
+         * remove them.
+         */
+        SMIME_crlf_copy(dcont, cmsbio, flags & ~SMIME_TEXT);
+
+        if (flags & CMS_TEXT) {
+            if (!SMIME_text(tmpout, out)) {
+                CMSerr(CMS_F_CMS_VERIFY, CMS_R_SMIME_TEXT_ERROR);
+                goto err;
+            }
+        }
+    } else {
+        cmsbio = CMS_dataInit(cms, tmpin);
+        if (!cmsbio)
+            goto err;
+
+        if (!cms_copy_content(out, cmsbio, flags))
+            goto err;
+
+    }
+    if (!(flags & CMS_NO_CONTENT_VERIFY)) {
+        for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
+            si = sk_CMS_SignerInfo_value(sinfos, i);
+            if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0) {
+                CMSerr(CMS_F_CMS_VERIFY, CMS_R_CONTENT_VERIFY_ERROR);
+                goto err;
+            }
+        }
+    }
+
+    ret = 1;
+
+ err:
+    if (!(flags & SMIME_BINARY) && dcont) {
+        do_free_upto(cmsbio, tmpout);
+        if (tmpin != dcont)
+            BIO_free(tmpin);
+    } else {
+        if (dcont && (tmpin == dcont))
+            do_free_upto(cmsbio, dcont);
+        else
+            BIO_free_all(cmsbio);
+    }
+
+    if (out != tmpout)
+        BIO_free_all(tmpout);
+
+ err2:
+    sk_X509_pop_free(cms_certs, X509_free);
+    sk_X509_CRL_pop_free(crls, X509_CRL_free);
+
+    return ret;
+}
+
+int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
+                       STACK_OF(X509) *certs,
+                       X509_STORE *store, unsigned int flags)
+{
+    int r;
+    flags &= ~(CMS_DETACHED | CMS_TEXT);
+    r = CMS_verify(rcms, certs, store, NULL, NULL, flags);
+    if (r <= 0)
+        return r;
+    return cms_Receipt_verify(rcms, ocms);
+}
+
+CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey,
+                          STACK_OF(X509) *certs, BIO *data,
+                          unsigned int flags)
+{
+    CMS_ContentInfo *cms;
+    int i;
+
+    cms = CMS_ContentInfo_new();
+    if (cms == NULL || !CMS_SignedData_init(cms))
+        goto merr;
+    if (flags & CMS_ASCIICRLF
+        && !CMS_set1_eContentType(cms,
+                                  OBJ_nid2obj(NID_id_ct_asciiTextWithCRLF)))
+        goto err;
+
+    if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) {
+        CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR);
+        goto err;
+    }
+
+    for (i = 0; i < sk_X509_num(certs); i++) {
+        X509 *x = sk_X509_value(certs, i);
+        if (!CMS_add1_cert(cms, x))
+            goto merr;
+    }
+
+    if (!(flags & CMS_DETACHED))
+        CMS_set_detached(cms, 0);
+
+    if ((flags & (CMS_STREAM | CMS_PARTIAL))
+        || CMS_final(cms, data, NULL, flags))
+        return cms;
+    else
+        goto err;
+
+ merr:
+    CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE);
+
+ err:
+    CMS_ContentInfo_free(cms);
+    return NULL;
+}
+
+CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
+                                  X509 *signcert, EVP_PKEY *pkey,
+                                  STACK_OF(X509) *certs, unsigned int flags)
+{
+    CMS_SignerInfo *rct_si;
+    CMS_ContentInfo *cms = NULL;
+    ASN1_OCTET_STRING **pos, *os;
+    BIO *rct_cont = NULL;
+    int r = 0;
+
+    flags &= ~(CMS_STREAM | CMS_TEXT);
+    /* Not really detached but avoids content being allocated */
+    flags |= CMS_PARTIAL | CMS_BINARY | CMS_DETACHED;
+    if (!pkey || !signcert) {
+        CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_NO_KEY_OR_CERT);
+        return NULL;
+    }
+
+    /* Initialize signed data */
+
+    cms = CMS_sign(NULL, NULL, certs, NULL, flags);
+    if (!cms)
+        goto err;
+
+    /* Set inner content type to signed receipt */
+    if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt)))
+        goto err;
+
+    rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags);
+    if (!rct_si) {
+        CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_ADD_SIGNER_ERROR);
+        goto err;
+    }
+
+    os = cms_encode_Receipt(si);
+
+    if (!os)
+        goto err;
+
+    /* Set content to digest */
+    rct_cont = BIO_new_mem_buf(os->data, os->length);
+    if (!rct_cont)
+        goto err;
+
+    /* Add msgSigDigest attribute */
+
+    if (!cms_msgSigDigest_add1(rct_si, si))
+        goto err;
+
+    /* Finalize structure */
+    if (!CMS_final(cms, rct_cont, NULL, flags))
+        goto err;
+
+    /* Set embedded content */
+    pos = CMS_get0_content(cms);
+    *pos = os;
+
+    r = 1;
+
+ err:
+    BIO_free(rct_cont);
+    if (r)
+        return cms;
+    CMS_ContentInfo_free(cms);
+    return NULL;
+
+}
+
+CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
+                             const EVP_CIPHER *cipher, unsigned int flags)
+{
+    CMS_ContentInfo *cms;
+    int i;
+    X509 *recip;
+    cms = CMS_EnvelopedData_create(cipher);
+    if (!cms)
+        goto merr;
+    for (i = 0; i < sk_X509_num(certs); i++) {
+        recip = sk_X509_value(certs, i);
+        if (!CMS_add1_recipient_cert(cms, recip, flags)) {
+            CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR);
+            goto err;
+        }
+    }
+
+    if (!(flags & CMS_DETACHED))
+        CMS_set_detached(cms, 0);
+
+    if ((flags & (CMS_STREAM | CMS_PARTIAL))
+        || CMS_final(cms, data, NULL, flags))
+        return cms;
+    else
+        goto err;
+
+ merr:
+    CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE);
+ err:
+    CMS_ContentInfo_free(cms);
+    return NULL;
+}
+
+static int cms_kari_set1_pkey(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
+                              EVP_PKEY *pk, X509 *cert)
+{
+    int i;
+    STACK_OF(CMS_RecipientEncryptedKey) *reks;
+    CMS_RecipientEncryptedKey *rek;
+    reks = CMS_RecipientInfo_kari_get0_reks(ri);
+    if (!cert)
+        return 0;
+    for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) {
+        int rv;
+        rek = sk_CMS_RecipientEncryptedKey_value(reks, i);
+        if (CMS_RecipientEncryptedKey_cert_cmp(rek, cert))
+            continue;
+        CMS_RecipientInfo_kari_set0_pkey(ri, pk);
+        rv = CMS_RecipientInfo_kari_decrypt(cms, ri, rek);
+        CMS_RecipientInfo_kari_set0_pkey(ri, NULL);
+        if (rv > 0)
+            return 1;
+        return -1;
+    }
+    return 0;
+}
+
+int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
+{
+    STACK_OF(CMS_RecipientInfo) *ris;
+    CMS_RecipientInfo *ri;
+    int i, r, ri_type;
+    int debug = 0, match_ri = 0;
+    ris = CMS_get0_RecipientInfos(cms);
+    if (ris)
+        debug = cms->d.envelopedData->encryptedContentInfo->debug;
+    ri_type = cms_pkey_get_ri_type(pk);
+    if (ri_type == CMS_RECIPINFO_NONE) {
+        CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY,
+               CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+        return 0;
+    }
+
+    for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
+        ri = sk_CMS_RecipientInfo_value(ris, i);
+        if (CMS_RecipientInfo_type(ri) != ri_type)
+            continue;
+        match_ri = 1;
+        if (ri_type == CMS_RECIPINFO_AGREE) {
+            r = cms_kari_set1_pkey(cms, ri, pk, cert);
+            if (r > 0)
+                return 1;
+            if (r < 0)
+                return 0;
+        }
+        /*
+         * If we have a cert try matching RecipientInfo otherwise try them
+         * all.
+         */
+        else if (!cert || !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) {
+            CMS_RecipientInfo_set0_pkey(ri, pk);
+            r = CMS_RecipientInfo_decrypt(cms, ri);
+            CMS_RecipientInfo_set0_pkey(ri, NULL);
+            if (cert) {
+                /*
+                 * If not debugging clear any error and return success to
+                 * avoid leaking of information useful to MMA
+                 */
+                if (!debug) {
+                    ERR_clear_error();
+                    return 1;
+                }
+                if (r > 0)
+                    return 1;
+                CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_DECRYPT_ERROR);
+                return 0;
+            }
+            /*
+             * If no cert and not debugging don't leave loop after first
+             * successful decrypt. Always attempt to decrypt all recipients
+             * to avoid leaking timing of a successful decrypt.
+             */
+            else if (r > 0 && debug)
+                return 1;
+        }
+    }
+    /* If no cert and not debugging always return success */
+    if (match_ri && !cert && !debug) {
+        ERR_clear_error();
+        return 1;
+    }
+
+    CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT);
+    return 0;
+
+}
+
+int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
+                         unsigned char *key, size_t keylen,
+                         const unsigned char *id, size_t idlen)
+{
+    STACK_OF(CMS_RecipientInfo) *ris;
+    CMS_RecipientInfo *ri;
+    int i, r;
+    ris = CMS_get0_RecipientInfos(cms);
+    for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
+        ri = sk_CMS_RecipientInfo_value(ris, i);
+        if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK)
+            continue;
+
+        /*
+         * If we have an id try matching RecipientInfo otherwise try them
+         * all.
+         */
+        if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) {
+            CMS_RecipientInfo_set0_key(ri, key, keylen);
+            r = CMS_RecipientInfo_decrypt(cms, ri);
+            CMS_RecipientInfo_set0_key(ri, NULL, 0);
+            if (r > 0)
+                return 1;
+            if (id) {
+                CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_DECRYPT_ERROR);
+                return 0;
+            }
+            ERR_clear_error();
+        }
+    }
+
+    CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_NO_MATCHING_RECIPIENT);
+    return 0;
+
+}
+
+int CMS_decrypt_set1_password(CMS_ContentInfo *cms,
+                              unsigned char *pass, ossl_ssize_t passlen)
+{
+    STACK_OF(CMS_RecipientInfo) *ris;
+    CMS_RecipientInfo *ri;
+    int i, r;
+    ris = CMS_get0_RecipientInfos(cms);
+    for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
+        ri = sk_CMS_RecipientInfo_value(ris, i);
+        if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS)
+            continue;
+        CMS_RecipientInfo_set0_password(ri, pass, passlen);
+        r = CMS_RecipientInfo_decrypt(cms, ri);
+        CMS_RecipientInfo_set0_password(ri, NULL, 0);
+        if (r > 0)
+            return 1;
+    }
+
+    CMSerr(CMS_F_CMS_DECRYPT_SET1_PASSWORD, CMS_R_NO_MATCHING_RECIPIENT);
+    return 0;
+
+}
+
+int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
+                BIO *dcont, BIO *out, unsigned int flags)
+{
+    int r;
+    BIO *cont;
+    if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped) {
+        CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA);
+        return 0;
+    }
+    if (!dcont && !check_content(cms))
+        return 0;
+    if (flags & CMS_DEBUG_DECRYPT)
+        cms->d.envelopedData->encryptedContentInfo->debug = 1;
+    else
+        cms->d.envelopedData->encryptedContentInfo->debug = 0;
+    if (!pk && !cert && !dcont && !out)
+        return 1;
+    if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert))
+        return 0;
+    cont = CMS_dataInit(cms, dcont);
+    if (!cont)
+        return 0;
+    r = cms_copy_content(out, cont, flags);
+    do_free_upto(cont, dcont);
+    return r;
+}
+
+int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags)
+{
+    BIO *cmsbio;
+    int ret = 0;
+
+    if ((cmsbio = CMS_dataInit(cms, dcont)) == NULL) {
+        CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_LIB);
+        return 0;
+    }
+
+    SMIME_crlf_copy(data, cmsbio, flags);
+
+    (void)BIO_flush(cmsbio);
+
+    if (!CMS_dataFinal(cms, cmsbio)) {
+        CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_DATAFINAL_ERROR);
+        goto err;
+    }
+
+    ret = 1;
+
+ err:
+    do_free_upto(cmsbio, dcont);
+
+    return ret;
+
+}
+
+#ifdef ZLIB
+
+int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+                   unsigned int flags)
+{
+    BIO *cont;
+    int r;
+    if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData) {
+        CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_TYPE_NOT_COMPRESSED_DATA);
+        return 0;
+    }
+
+    if (!dcont && !check_content(cms))
+        return 0;
+
+    cont = CMS_dataInit(cms, dcont);
+    if (!cont)
+        return 0;
+    r = cms_copy_content(out, cont, flags);
+    do_free_upto(cont, dcont);
+    return r;
+}
+
+CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
+{
+    CMS_ContentInfo *cms;
+    if (comp_nid <= 0)
+        comp_nid = NID_zlib_compression;
+    cms = cms_CompressedData_create(comp_nid);
+    if (!cms)
+        return NULL;
+
+    if (!(flags & CMS_DETACHED))
+        CMS_set_detached(cms, 0);
+
+    if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
+        return cms;
+
+    CMS_ContentInfo_free(cms);
+    return NULL;
+}
+
+#else
+
+int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+                   unsigned int flags)
+{
+    CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+    return 0;
+}
+
+CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
+{
+    CMSerr(CMS_F_CMS_COMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+    return NULL;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/comp/c_zlib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/comp/c_zlib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/comp/c_zlib.c	(revision 331)
@@ -0,0 +1,615 @@
+/*
+ * Copyright 1998-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/objects.h>
+#include "internal/comp.h"
+#include <openssl/err.h>
+#include "internal/cryptlib_int.h"
+#include "internal/bio.h"
+#include "comp_lcl.h"
+
+COMP_METHOD *COMP_zlib(void);
+
+static COMP_METHOD zlib_method_nozlib = {
+    NID_undef,
+    "(undef)",
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+};
+
+#ifndef ZLIB
+# undef ZLIB_SHARED
+#else
+
+# include <zlib.h>
+
+static int zlib_stateful_init(COMP_CTX *ctx);
+static void zlib_stateful_finish(COMP_CTX *ctx);
+static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
+                                        unsigned int olen, unsigned char *in,
+                                        unsigned int ilen);
+static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
+                                      unsigned int olen, unsigned char *in,
+                                      unsigned int ilen);
+
+/* memory allocations functions for zlib initialisation */
+static void *zlib_zalloc(void *opaque, unsigned int no, unsigned int size)
+{
+    void *p;
+
+    p = OPENSSL_zalloc(no * size);
+    return p;
+}
+
+static void zlib_zfree(void *opaque, void *address)
+{
+    OPENSSL_free(address);
+}
+
+
+static COMP_METHOD zlib_stateful_method = {
+    NID_zlib_compression,
+    LN_zlib_compression,
+    zlib_stateful_init,
+    zlib_stateful_finish,
+    zlib_stateful_compress_block,
+    zlib_stateful_expand_block
+};
+
+/*
+ * When OpenSSL is built on Windows, we do not want to require that
+ * the ZLIB.DLL be available in order for the OpenSSL DLLs to
+ * work.  Therefore, all ZLIB routines are loaded at run time
+ * and we do not link to a .LIB file when ZLIB_SHARED is set.
+ */
+# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
+#  include <windows.h>
+# endif                         /* !(OPENSSL_SYS_WINDOWS ||
+                                 * OPENSSL_SYS_WIN32) */
+
+# ifdef ZLIB_SHARED
+#  include "internal/dso.h"
+
+/* Function pointers */
+typedef int (*compress_ft) (Bytef *dest, uLongf * destLen,
+                            const Bytef *source, uLong sourceLen);
+typedef int (*inflateEnd_ft) (z_streamp strm);
+typedef int (*inflate_ft) (z_streamp strm, int flush);
+typedef int (*inflateInit__ft) (z_streamp strm,
+                                const char *version, int stream_size);
+typedef int (*deflateEnd_ft) (z_streamp strm);
+typedef int (*deflate_ft) (z_streamp strm, int flush);
+typedef int (*deflateInit__ft) (z_streamp strm, int level,
+                                const char *version, int stream_size);
+typedef const char *(*zError__ft) (int err);
+static compress_ft p_compress = NULL;
+static inflateEnd_ft p_inflateEnd = NULL;
+static inflate_ft p_inflate = NULL;
+static inflateInit__ft p_inflateInit_ = NULL;
+static deflateEnd_ft p_deflateEnd = NULL;
+static deflate_ft p_deflate = NULL;
+static deflateInit__ft p_deflateInit_ = NULL;
+static zError__ft p_zError = NULL;
+
+static int zlib_loaded = 0;     /* only attempt to init func pts once */
+static DSO *zlib_dso = NULL;
+
+#  define compress                p_compress
+#  define inflateEnd              p_inflateEnd
+#  define inflate                 p_inflate
+#  define inflateInit_            p_inflateInit_
+#  define deflateEnd              p_deflateEnd
+#  define deflate                 p_deflate
+#  define deflateInit_            p_deflateInit_
+#  define zError                  p_zError
+# endif                         /* ZLIB_SHARED */
+
+struct zlib_state {
+    z_stream istream;
+    z_stream ostream;
+};
+
+static int zlib_stateful_init(COMP_CTX *ctx)
+{
+    int err;
+    struct zlib_state *state = OPENSSL_zalloc(sizeof(*state));
+
+    if (state == NULL)
+        goto err;
+
+    state->istream.zalloc = zlib_zalloc;
+    state->istream.zfree = zlib_zfree;
+    state->istream.opaque = Z_NULL;
+    state->istream.next_in = Z_NULL;
+    state->istream.next_out = Z_NULL;
+    err = inflateInit_(&state->istream, ZLIB_VERSION, sizeof(z_stream));
+    if (err != Z_OK)
+        goto err;
+
+    state->ostream.zalloc = zlib_zalloc;
+    state->ostream.zfree = zlib_zfree;
+    state->ostream.opaque = Z_NULL;
+    state->ostream.next_in = Z_NULL;
+    state->ostream.next_out = Z_NULL;
+    err = deflateInit_(&state->ostream, Z_DEFAULT_COMPRESSION,
+                       ZLIB_VERSION, sizeof(z_stream));
+    if (err != Z_OK)
+        goto err;
+
+    ctx->data = state;
+    return 1;
+ err:
+    OPENSSL_free(state);
+    return 0;
+}
+
+static void zlib_stateful_finish(COMP_CTX *ctx)
+{
+    struct zlib_state *state = ctx->data;
+    inflateEnd(&state->istream);
+    deflateEnd(&state->ostream);
+    OPENSSL_free(state);
+}
+
+static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
+                                        unsigned int olen, unsigned char *in,
+                                        unsigned int ilen)
+{
+    int err = Z_OK;
+    struct zlib_state *state = ctx->data;
+
+    if (state == NULL)
+        return -1;
+
+    state->ostream.next_in = in;
+    state->ostream.avail_in = ilen;
+    state->ostream.next_out = out;
+    state->ostream.avail_out = olen;
+    if (ilen > 0)
+        err = deflate(&state->ostream, Z_SYNC_FLUSH);
+    if (err != Z_OK)
+        return -1;
+    return olen - state->ostream.avail_out;
+}
+
+static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
+                                      unsigned int olen, unsigned char *in,
+                                      unsigned int ilen)
+{
+    int err = Z_OK;
+    struct zlib_state *state = ctx->data;
+
+    if (state == NULL)
+        return 0;
+
+    state->istream.next_in = in;
+    state->istream.avail_in = ilen;
+    state->istream.next_out = out;
+    state->istream.avail_out = olen;
+    if (ilen > 0)
+        err = inflate(&state->istream, Z_SYNC_FLUSH);
+    if (err != Z_OK)
+        return -1;
+    return olen - state->istream.avail_out;
+}
+
+#endif
+
+COMP_METHOD *COMP_zlib(void)
+{
+    COMP_METHOD *meth = &zlib_method_nozlib;
+
+#ifdef ZLIB_SHARED
+    /* LIBZ may be externally defined, and we should respect that value */
+# ifndef LIBZ
+#  if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
+#   define LIBZ "ZLIB1"
+#  elif defined(OPENSSL_SYS_VMS)
+#   define LIBZ "LIBZ"
+#  else
+#   define LIBZ "z"
+#  endif
+# endif
+
+    if (!zlib_loaded) {
+        zlib_dso = DSO_load(NULL, LIBZ, NULL, 0);
+        if (zlib_dso != NULL) {
+            p_compress = (compress_ft) DSO_bind_func(zlib_dso, "compress");
+            p_inflateEnd
+                = (inflateEnd_ft) DSO_bind_func(zlib_dso, "inflateEnd");
+            p_inflate = (inflate_ft) DSO_bind_func(zlib_dso, "inflate");
+            p_inflateInit_
+                = (inflateInit__ft) DSO_bind_func(zlib_dso, "inflateInit_");
+            p_deflateEnd
+                = (deflateEnd_ft) DSO_bind_func(zlib_dso, "deflateEnd");
+            p_deflate = (deflate_ft) DSO_bind_func(zlib_dso, "deflate");
+            p_deflateInit_
+                = (deflateInit__ft) DSO_bind_func(zlib_dso, "deflateInit_");
+            p_zError = (zError__ft) DSO_bind_func(zlib_dso, "zError");
+
+            if (p_compress && p_inflateEnd && p_inflate
+                && p_inflateInit_ && p_deflateEnd
+                && p_deflate && p_deflateInit_ && p_zError)
+                zlib_loaded++;
+
+            if (!OPENSSL_init_crypto(OPENSSL_INIT_ZLIB, NULL)) {
+                comp_zlib_cleanup_int();
+                return meth;
+            }
+            if (zlib_loaded)
+                meth = &zlib_stateful_method;
+        }
+    }
+#endif
+#if defined(ZLIB)
+    meth = &zlib_stateful_method;
+#endif
+
+    return (meth);
+}
+
+void comp_zlib_cleanup_int(void)
+{
+#ifdef ZLIB_SHARED
+    if (zlib_dso != NULL)
+        DSO_free(zlib_dso);
+    zlib_dso = NULL;
+#endif
+}
+
+#ifdef ZLIB
+
+/* Zlib based compression/decompression filter BIO */
+
+typedef struct {
+    unsigned char *ibuf;        /* Input buffer */
+    int ibufsize;               /* Buffer size */
+    z_stream zin;               /* Input decompress context */
+    unsigned char *obuf;        /* Output buffer */
+    int obufsize;               /* Output buffer size */
+    unsigned char *optr;        /* Position in output buffer */
+    int ocount;                 /* Amount of data in output buffer */
+    int odone;                  /* deflate EOF */
+    int comp_level;             /* Compression level to use */
+    z_stream zout;              /* Output compression context */
+} BIO_ZLIB_CTX;
+
+# define ZLIB_DEFAULT_BUFSIZE 1024
+
+static int bio_zlib_new(BIO *bi);
+static int bio_zlib_free(BIO *bi);
+static int bio_zlib_read(BIO *b, char *out, int outl);
+static int bio_zlib_write(BIO *b, const char *in, int inl);
+static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr);
+static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp);
+
+static const BIO_METHOD bio_meth_zlib = {
+    BIO_TYPE_COMP,
+    "zlib",
+    bio_zlib_write,
+    bio_zlib_read,
+    NULL,
+    NULL,
+    bio_zlib_ctrl,
+    bio_zlib_new,
+    bio_zlib_free,
+    bio_zlib_callback_ctrl
+};
+
+const BIO_METHOD *BIO_f_zlib(void)
+{
+    return &bio_meth_zlib;
+}
+
+static int bio_zlib_new(BIO *bi)
+{
+    BIO_ZLIB_CTX *ctx;
+# ifdef ZLIB_SHARED
+    (void)COMP_zlib();
+    if (!zlib_loaded) {
+        COMPerr(COMP_F_BIO_ZLIB_NEW, COMP_R_ZLIB_NOT_SUPPORTED);
+        return 0;
+    }
+# endif
+    ctx = OPENSSL_zalloc(sizeof(*ctx));
+    if (ctx == NULL) {
+        COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE;
+    ctx->obufsize = ZLIB_DEFAULT_BUFSIZE;
+    ctx->zin.zalloc = Z_NULL;
+    ctx->zin.zfree = Z_NULL;
+    ctx->zout.zalloc = Z_NULL;
+    ctx->zout.zfree = Z_NULL;
+    ctx->comp_level = Z_DEFAULT_COMPRESSION;
+    BIO_set_init(bi, 1);
+    BIO_set_data(bi, ctx);
+
+    return 1;
+}
+
+static int bio_zlib_free(BIO *bi)
+{
+    BIO_ZLIB_CTX *ctx;
+    if (!bi)
+        return 0;
+    ctx = BIO_get_data(bi);
+    if (ctx->ibuf) {
+        /* Destroy decompress context */
+        inflateEnd(&ctx->zin);
+        OPENSSL_free(ctx->ibuf);
+    }
+    if (ctx->obuf) {
+        /* Destroy compress context */
+        deflateEnd(&ctx->zout);
+        OPENSSL_free(ctx->obuf);
+    }
+    OPENSSL_free(ctx);
+    BIO_set_data(bi, NULL);
+    BIO_set_init(bi, 0);
+
+    return 1;
+}
+
+static int bio_zlib_read(BIO *b, char *out, int outl)
+{
+    BIO_ZLIB_CTX *ctx;
+    int ret;
+    z_stream *zin;
+    BIO *next = BIO_next(b);
+
+    if (!out || !outl)
+        return 0;
+    ctx = BIO_get_data(b);
+    zin = &ctx->zin;
+    BIO_clear_retry_flags(b);
+    if (!ctx->ibuf) {
+        ctx->ibuf = OPENSSL_malloc(ctx->ibufsize);
+        if (ctx->ibuf == NULL) {
+            COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        inflateInit(zin);
+        zin->next_in = ctx->ibuf;
+        zin->avail_in = 0;
+    }
+
+    /* Copy output data directly to supplied buffer */
+    zin->next_out = (unsigned char *)out;
+    zin->avail_out = (unsigned int)outl;
+    for (;;) {
+        /* Decompress while data available */
+        while (zin->avail_in) {
+            ret = inflate(zin, 0);
+            if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
+                COMPerr(COMP_F_BIO_ZLIB_READ, COMP_R_ZLIB_INFLATE_ERROR);
+                ERR_add_error_data(2, "zlib error:", zError(ret));
+                return 0;
+            }
+            /* If EOF or we've read everything then return */
+            if ((ret == Z_STREAM_END) || !zin->avail_out)
+                return outl - zin->avail_out;
+        }
+
+        /*
+         * No data in input buffer try to read some in, if an error then
+         * return the total data read.
+         */
+        ret = BIO_read(next, ctx->ibuf, ctx->ibufsize);
+        if (ret <= 0) {
+            /* Total data read */
+            int tot = outl - zin->avail_out;
+            BIO_copy_next_retry(b);
+            if (ret < 0)
+                return (tot > 0) ? tot : ret;
+            return tot;
+        }
+        zin->avail_in = ret;
+        zin->next_in = ctx->ibuf;
+    }
+}
+
+static int bio_zlib_write(BIO *b, const char *in, int inl)
+{
+    BIO_ZLIB_CTX *ctx;
+    int ret;
+    z_stream *zout;
+    BIO *next = BIO_next(b);
+
+    if (!in || !inl)
+        return 0;
+    ctx = BIO_get_data(b);
+    if (ctx->odone)
+        return 0;
+    zout = &ctx->zout;
+    BIO_clear_retry_flags(b);
+    if (!ctx->obuf) {
+        ctx->obuf = OPENSSL_malloc(ctx->obufsize);
+        /* Need error here */
+        if (ctx->obuf == NULL) {
+            COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        ctx->optr = ctx->obuf;
+        ctx->ocount = 0;
+        deflateInit(zout, ctx->comp_level);
+        zout->next_out = ctx->obuf;
+        zout->avail_out = ctx->obufsize;
+    }
+    /* Obtain input data directly from supplied buffer */
+    zout->next_in = (void *)in;
+    zout->avail_in = inl;
+    for (;;) {
+        /* If data in output buffer write it first */
+        while (ctx->ocount) {
+            ret = BIO_write(next, ctx->optr, ctx->ocount);
+            if (ret <= 0) {
+                /* Total data written */
+                int tot = inl - zout->avail_in;
+                BIO_copy_next_retry(b);
+                if (ret < 0)
+                    return (tot > 0) ? tot : ret;
+                return tot;
+            }
+            ctx->optr += ret;
+            ctx->ocount -= ret;
+        }
+
+        /* Have we consumed all supplied data? */
+        if (!zout->avail_in)
+            return inl;
+
+        /* Compress some more */
+
+        /* Reset buffer */
+        ctx->optr = ctx->obuf;
+        zout->next_out = ctx->obuf;
+        zout->avail_out = ctx->obufsize;
+        /* Compress some more */
+        ret = deflate(zout, 0);
+        if (ret != Z_OK) {
+            COMPerr(COMP_F_BIO_ZLIB_WRITE, COMP_R_ZLIB_DEFLATE_ERROR);
+            ERR_add_error_data(2, "zlib error:", zError(ret));
+            return 0;
+        }
+        ctx->ocount = ctx->obufsize - zout->avail_out;
+    }
+}
+
+static int bio_zlib_flush(BIO *b)
+{
+    BIO_ZLIB_CTX *ctx;
+    int ret;
+    z_stream *zout;
+    BIO *next = BIO_next(b);
+
+    ctx = BIO_get_data(b);
+    /* If no data written or already flush show success */
+    if (!ctx->obuf || (ctx->odone && !ctx->ocount))
+        return 1;
+    zout = &ctx->zout;
+    BIO_clear_retry_flags(b);
+    /* No more input data */
+    zout->next_in = NULL;
+    zout->avail_in = 0;
+    for (;;) {
+        /* If data in output buffer write it first */
+        while (ctx->ocount) {
+            ret = BIO_write(next, ctx->optr, ctx->ocount);
+            if (ret <= 0) {
+                BIO_copy_next_retry(b);
+                return ret;
+            }
+            ctx->optr += ret;
+            ctx->ocount -= ret;
+        }
+        if (ctx->odone)
+            return 1;
+
+        /* Compress some more */
+
+        /* Reset buffer */
+        ctx->optr = ctx->obuf;
+        zout->next_out = ctx->obuf;
+        zout->avail_out = ctx->obufsize;
+        /* Compress some more */
+        ret = deflate(zout, Z_FINISH);
+        if (ret == Z_STREAM_END)
+            ctx->odone = 1;
+        else if (ret != Z_OK) {
+            COMPerr(COMP_F_BIO_ZLIB_FLUSH, COMP_R_ZLIB_DEFLATE_ERROR);
+            ERR_add_error_data(2, "zlib error:", zError(ret));
+            return 0;
+        }
+        ctx->ocount = ctx->obufsize - zout->avail_out;
+    }
+}
+
+static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    BIO_ZLIB_CTX *ctx;
+    int ret, *ip;
+    int ibs, obs;
+    BIO *next = BIO_next(b);
+
+    if (next == NULL)
+        return 0;
+    ctx = BIO_get_data(b);
+    switch (cmd) {
+
+    case BIO_CTRL_RESET:
+        ctx->ocount = 0;
+        ctx->odone = 0;
+        ret = 1;
+        break;
+
+    case BIO_CTRL_FLUSH:
+        ret = bio_zlib_flush(b);
+        if (ret > 0)
+            ret = BIO_flush(next);
+        break;
+
+    case BIO_C_SET_BUFF_SIZE:
+        ibs = -1;
+        obs = -1;
+        if (ptr != NULL) {
+            ip = ptr;
+            if (*ip == 0)
+                ibs = (int)num;
+            else
+                obs = (int)num;
+        } else {
+            ibs = (int)num;
+            obs = ibs;
+        }
+
+        if (ibs != -1) {
+            OPENSSL_free(ctx->ibuf);
+            ctx->ibuf = NULL;
+            ctx->ibufsize = ibs;
+        }
+
+        if (obs != -1) {
+            OPENSSL_free(ctx->obuf);
+            ctx->obuf = NULL;
+            ctx->obufsize = obs;
+        }
+        ret = 1;
+        break;
+
+    case BIO_C_DO_STATE_MACHINE:
+        BIO_clear_retry_flags(b);
+        ret = BIO_ctrl(next, cmd, num, ptr);
+        BIO_copy_next_retry(b);
+        break;
+
+    default:
+        ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+
+    }
+
+    return ret;
+}
+
+static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+    BIO *next = BIO_next(b);
+    if (next == NULL)
+        return 0;
+    return BIO_callback_ctrl(next, cmd, fp);
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/comp/comp_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/comp/comp_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/comp/comp_err.c	(revision 331)
@@ -0,0 +1,48 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/comp.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_COMP,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_COMP,0,reason)
+
+static ERR_STRING_DATA COMP_str_functs[] = {
+    {ERR_FUNC(COMP_F_BIO_ZLIB_FLUSH), "bio_zlib_flush"},
+    {ERR_FUNC(COMP_F_BIO_ZLIB_NEW), "bio_zlib_new"},
+    {ERR_FUNC(COMP_F_BIO_ZLIB_READ), "bio_zlib_read"},
+    {ERR_FUNC(COMP_F_BIO_ZLIB_WRITE), "bio_zlib_write"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA COMP_str_reasons[] = {
+    {ERR_REASON(COMP_R_ZLIB_DEFLATE_ERROR), "zlib deflate error"},
+    {ERR_REASON(COMP_R_ZLIB_INFLATE_ERROR), "zlib inflate error"},
+    {ERR_REASON(COMP_R_ZLIB_NOT_SUPPORTED), "zlib not supported"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_COMP_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(COMP_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, COMP_str_functs);
+        ERR_load_strings(0, COMP_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/comp/comp_lcl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/comp/comp_lcl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/comp/comp_lcl.h	(revision 331)
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015-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
+ */
+
+struct comp_method_st {
+    int type;                   /* NID for compression library */
+    const char *name;           /* A text string to identify the library */
+    int (*init) (COMP_CTX *ctx);
+    void (*finish) (COMP_CTX *ctx);
+    int (*compress) (COMP_CTX *ctx,
+                     unsigned char *out, unsigned int olen,
+                     unsigned char *in, unsigned int ilen);
+    int (*expand) (COMP_CTX *ctx,
+                   unsigned char *out, unsigned int olen,
+                   unsigned char *in, unsigned int ilen);
+};
+
+struct comp_ctx_st {
+    struct comp_method_st *meth;
+    unsigned long compress_in;
+    unsigned long compress_out;
+    unsigned long expand_in;
+    unsigned long expand_out;
+    void* data;
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/comp/comp_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/comp/comp_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/comp/comp_lib.c	(revision 331)
@@ -0,0 +1,91 @@
+/*
+ * Copyright 1998-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/objects.h>
+#include <openssl/comp.h>
+#include "comp_lcl.h"
+
+COMP_CTX *COMP_CTX_new(COMP_METHOD *meth)
+{
+    COMP_CTX *ret;
+
+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
+        return (NULL);
+    ret->meth = meth;
+    if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
+        OPENSSL_free(ret);
+        ret = NULL;
+    }
+    return (ret);
+}
+
+const COMP_METHOD *COMP_CTX_get_method(const COMP_CTX *ctx)
+{
+    return ctx->meth;
+}
+
+int COMP_get_type(const COMP_METHOD *meth)
+{
+    return meth->type;
+}
+
+const char *COMP_get_name(const COMP_METHOD *meth)
+{
+    return meth->name;
+}
+
+void COMP_CTX_free(COMP_CTX *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    if (ctx->meth->finish != NULL)
+        ctx->meth->finish(ctx);
+
+    OPENSSL_free(ctx);
+}
+
+int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen,
+                        unsigned char *in, int ilen)
+{
+    int ret;
+    if (ctx->meth->compress == NULL) {
+        return (-1);
+    }
+    ret = ctx->meth->compress(ctx, out, olen, in, ilen);
+    if (ret > 0) {
+        ctx->compress_in += ilen;
+        ctx->compress_out += ret;
+    }
+    return (ret);
+}
+
+int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen,
+                      unsigned char *in, int ilen)
+{
+    int ret;
+
+    if (ctx->meth->expand == NULL) {
+        return (-1);
+    }
+    ret = ctx->meth->expand(ctx, out, olen, in, ilen);
+    if (ret > 0) {
+        ctx->expand_in += ilen;
+        ctx->expand_out += ret;
+    }
+    return (ret);
+}
+
+int COMP_CTX_get_type(const COMP_CTX* comp)
+{
+    return comp->meth ? comp->meth->type : NID_undef;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_api.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_api.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_api.c	(revision 331)
@@ -0,0 +1,214 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* Part of the code in here was originally in conf.c, which is now removed */
+
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/conf.h>
+#include <openssl/conf_api.h>
+#include "e_os.h"
+
+static void value_free_hash(const CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf);
+static void value_free_stack_doall(CONF_VALUE *a);
+
+/* Up until OpenSSL 0.9.5a, this was get_section */
+CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section)
+{
+    CONF_VALUE *v, vv;
+
+    if ((conf == NULL) || (section == NULL))
+        return (NULL);
+    vv.name = NULL;
+    vv.section = (char *)section;
+    v = lh_CONF_VALUE_retrieve(conf->data, &vv);
+    return (v);
+}
+
+/* Up until OpenSSL 0.9.5a, this was CONF_get_section */
+STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf,
+                                               const char *section)
+{
+    CONF_VALUE *v;
+
+    v = _CONF_get_section(conf, section);
+    if (v != NULL)
+        return ((STACK_OF(CONF_VALUE) *)v->value);
+    else
+        return (NULL);
+}
+
+int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value)
+{
+    CONF_VALUE *v = NULL;
+    STACK_OF(CONF_VALUE) *ts;
+
+    ts = (STACK_OF(CONF_VALUE) *)section->value;
+
+    value->section = section->section;
+    if (!sk_CONF_VALUE_push(ts, value)) {
+        return 0;
+    }
+
+    v = lh_CONF_VALUE_insert(conf->data, value);
+    if (v != NULL) {
+        (void)sk_CONF_VALUE_delete_ptr(ts, v);
+        OPENSSL_free(v->name);
+        OPENSSL_free(v->value);
+        OPENSSL_free(v);
+    }
+    return 1;
+}
+
+char *_CONF_get_string(const CONF *conf, const char *section,
+                       const char *name)
+{
+    CONF_VALUE *v, vv;
+    char *p;
+
+    if (name == NULL)
+        return (NULL);
+    if (conf != NULL) {
+        if (section != NULL) {
+            vv.name = (char *)name;
+            vv.section = (char *)section;
+            v = lh_CONF_VALUE_retrieve(conf->data, &vv);
+            if (v != NULL)
+                return (v->value);
+            if (strcmp(section, "ENV") == 0) {
+                p = getenv(name);
+                if (p != NULL)
+                    return (p);
+            }
+        }
+        vv.section = "default";
+        vv.name = (char *)name;
+        v = lh_CONF_VALUE_retrieve(conf->data, &vv);
+        if (v != NULL)
+            return (v->value);
+        else
+            return (NULL);
+    } else
+        return (getenv(name));
+}
+
+static unsigned long conf_value_hash(const CONF_VALUE *v)
+{
+    return (OPENSSL_LH_strhash(v->section) << 2) ^ OPENSSL_LH_strhash(v->name);
+}
+
+static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b)
+{
+    int i;
+
+    if (a->section != b->section) {
+        i = strcmp(a->section, b->section);
+        if (i)
+            return (i);
+    }
+
+    if ((a->name != NULL) && (b->name != NULL)) {
+        i = strcmp(a->name, b->name);
+        return (i);
+    } else if (a->name == b->name)
+        return (0);
+    else
+        return ((a->name == NULL) ? -1 : 1);
+}
+
+int _CONF_new_data(CONF *conf)
+{
+    if (conf == NULL) {
+        return 0;
+    }
+    if (conf->data == NULL) {
+        conf->data = lh_CONF_VALUE_new(conf_value_hash, conf_value_cmp);
+        if (conf->data == NULL)
+            return 0;
+    }
+    return 1;
+}
+
+typedef LHASH_OF(CONF_VALUE) LH_CONF_VALUE;
+
+IMPLEMENT_LHASH_DOALL_ARG_CONST(CONF_VALUE, LH_CONF_VALUE);
+
+void _CONF_free_data(CONF *conf)
+{
+    if (conf == NULL || conf->data == NULL)
+        return;
+
+    /* evil thing to make sure the 'OPENSSL_free()' works as expected */
+    lh_CONF_VALUE_set_down_load(conf->data, 0);
+    lh_CONF_VALUE_doall_LH_CONF_VALUE(conf->data, value_free_hash, conf->data);
+
+    /*
+     * We now have only 'section' entries in the hash table. Due to problems
+     * with
+     */
+
+    lh_CONF_VALUE_doall(conf->data, value_free_stack_doall);
+    lh_CONF_VALUE_free(conf->data);
+}
+
+static void value_free_hash(const CONF_VALUE *a, LHASH_OF(CONF_VALUE) *conf)
+{
+    if (a->name != NULL)
+        (void)lh_CONF_VALUE_delete(conf, a);
+}
+
+static void value_free_stack_doall(CONF_VALUE *a)
+{
+    CONF_VALUE *vv;
+    STACK_OF(CONF_VALUE) *sk;
+    int i;
+
+    if (a->name != NULL)
+        return;
+
+    sk = (STACK_OF(CONF_VALUE) *)a->value;
+    for (i = sk_CONF_VALUE_num(sk) - 1; i >= 0; i--) {
+        vv = sk_CONF_VALUE_value(sk, i);
+        OPENSSL_free(vv->value);
+        OPENSSL_free(vv->name);
+        OPENSSL_free(vv);
+    }
+    sk_CONF_VALUE_free(sk);
+    OPENSSL_free(a->section);
+    OPENSSL_free(a);
+}
+
+/* Up until OpenSSL 0.9.5a, this was new_section */
+CONF_VALUE *_CONF_new_section(CONF *conf, const char *section)
+{
+    STACK_OF(CONF_VALUE) *sk = NULL;
+    int i;
+    CONF_VALUE *v = NULL, *vv;
+
+    if ((sk = sk_CONF_VALUE_new_null()) == NULL)
+        goto err;
+    if ((v = OPENSSL_malloc(sizeof(*v))) == NULL)
+        goto err;
+    i = strlen(section) + 1;
+    if ((v->section = OPENSSL_malloc(i)) == NULL)
+        goto err;
+
+    memcpy(v->section, section, i);
+    v->name = NULL;
+    v->value = (char *)sk;
+
+    vv = lh_CONF_VALUE_insert(conf->data, v);
+    OPENSSL_assert(vv == NULL);
+    return v;
+
+ err:
+    sk_CONF_VALUE_free(sk);
+    OPENSSL_free(v);
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_def.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_def.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_def.c	(revision 331)
@@ -0,0 +1,630 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* Part of the code in here was originally in conf.c, which is now removed */
+
+#include <stdio.h>
+#include <string.h>
+#include "internal/cryptlib.h"
+#include <openssl/stack.h>
+#include <openssl/lhash.h>
+#include <openssl/conf.h>
+#include <openssl/conf_api.h>
+#include "conf_def.h"
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+
+static char *eat_ws(CONF *conf, char *p);
+static char *eat_alpha_numeric(CONF *conf, char *p);
+static void clear_comments(CONF *conf, char *p);
+static int str_copy(CONF *conf, char *section, char **to, char *from);
+static char *scan_quote(CONF *conf, char *p);
+static char *scan_dquote(CONF *conf, char *p);
+#define scan_esc(conf,p)        (((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2)))
+
+static CONF *def_create(CONF_METHOD *meth);
+static int def_init_default(CONF *conf);
+static int def_init_WIN32(CONF *conf);
+static int def_destroy(CONF *conf);
+static int def_destroy_data(CONF *conf);
+static int def_load(CONF *conf, const char *name, long *eline);
+static int def_load_bio(CONF *conf, BIO *bp, long *eline);
+static int def_dump(const CONF *conf, BIO *bp);
+static int def_is_number(const CONF *conf, char c);
+static int def_to_int(const CONF *conf, char c);
+
+static CONF_METHOD default_method = {
+    "OpenSSL default",
+    def_create,
+    def_init_default,
+    def_destroy,
+    def_destroy_data,
+    def_load_bio,
+    def_dump,
+    def_is_number,
+    def_to_int,
+    def_load
+};
+
+static CONF_METHOD WIN32_method = {
+    "WIN32",
+    def_create,
+    def_init_WIN32,
+    def_destroy,
+    def_destroy_data,
+    def_load_bio,
+    def_dump,
+    def_is_number,
+    def_to_int,
+    def_load
+};
+
+CONF_METHOD *NCONF_default()
+{
+    return &default_method;
+}
+
+CONF_METHOD *NCONF_WIN32()
+{
+    return &WIN32_method;
+}
+
+static CONF *def_create(CONF_METHOD *meth)
+{
+    CONF *ret;
+
+    ret = OPENSSL_malloc(sizeof(*ret));
+    if (ret != NULL)
+        if (meth->init(ret) == 0) {
+            OPENSSL_free(ret);
+            ret = NULL;
+        }
+    return ret;
+}
+
+static int def_init_default(CONF *conf)
+{
+    if (conf == NULL)
+        return 0;
+
+    conf->meth = &default_method;
+    conf->meth_data = (void *)CONF_type_default;
+    conf->data = NULL;
+
+    return 1;
+}
+
+static int def_init_WIN32(CONF *conf)
+{
+    if (conf == NULL)
+        return 0;
+
+    conf->meth = &WIN32_method;
+    conf->meth_data = (void *)CONF_type_win32;
+    conf->data = NULL;
+
+    return 1;
+}
+
+static int def_destroy(CONF *conf)
+{
+    if (def_destroy_data(conf)) {
+        OPENSSL_free(conf);
+        return 1;
+    }
+    return 0;
+}
+
+static int def_destroy_data(CONF *conf)
+{
+    if (conf == NULL)
+        return 0;
+    _CONF_free_data(conf);
+    return 1;
+}
+
+static int def_load(CONF *conf, const char *name, long *line)
+{
+    int ret;
+    BIO *in = NULL;
+
+#ifdef OPENSSL_SYS_VMS
+    in = BIO_new_file(name, "r");
+#else
+    in = BIO_new_file(name, "rb");
+#endif
+    if (in == NULL) {
+        if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE)
+            CONFerr(CONF_F_DEF_LOAD, CONF_R_NO_SUCH_FILE);
+        else
+            CONFerr(CONF_F_DEF_LOAD, ERR_R_SYS_LIB);
+        return 0;
+    }
+
+    ret = def_load_bio(conf, in, line);
+    BIO_free(in);
+
+    return ret;
+}
+
+static int def_load_bio(CONF *conf, BIO *in, long *line)
+{
+/* The macro BUFSIZE conflicts with a system macro in VxWorks */
+#define CONFBUFSIZE     512
+    int bufnum = 0, i, ii;
+    BUF_MEM *buff = NULL;
+    char *s, *p, *end;
+    int again;
+    long eline = 0;
+    char btmp[DECIMAL_SIZE(eline) + 1];
+    CONF_VALUE *v = NULL, *tv;
+    CONF_VALUE *sv = NULL;
+    char *section = NULL, *buf;
+    char *start, *psection, *pname;
+    void *h = (void *)(conf->data);
+
+    if ((buff = BUF_MEM_new()) == NULL) {
+        CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB);
+        goto err;
+    }
+
+    section = OPENSSL_strdup("default");
+    if (section == NULL) {
+        CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (_CONF_new_data(conf) == 0) {
+        CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    sv = _CONF_new_section(conf, section);
+    if (sv == NULL) {
+        CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+        goto err;
+    }
+
+    bufnum = 0;
+    again = 0;
+    for (;;) {
+        if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) {
+            CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB);
+            goto err;
+        }
+        p = &(buff->data[bufnum]);
+        *p = '\0';
+        BIO_gets(in, p, CONFBUFSIZE - 1);
+        p[CONFBUFSIZE - 1] = '\0';
+        ii = i = strlen(p);
+        if (i == 0 && !again)
+            break;
+        again = 0;
+        while (i > 0) {
+            if ((p[i - 1] != '\r') && (p[i - 1] != '\n'))
+                break;
+            else
+                i--;
+        }
+        /*
+         * we removed some trailing stuff so there is a new line on the end.
+         */
+        if (ii && i == ii)
+            again = 1;          /* long line */
+        else {
+            p[i] = '\0';
+            eline++;            /* another input line */
+        }
+
+        /* we now have a line with trailing \r\n removed */
+
+        /* i is the number of bytes */
+        bufnum += i;
+
+        v = NULL;
+        /* check for line continuation */
+        if (bufnum >= 1) {
+            /*
+             * If we have bytes and the last char '\\' and second last char
+             * is not '\\'
+             */
+            p = &(buff->data[bufnum - 1]);
+            if (IS_ESC(conf, p[0]) && ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) {
+                bufnum--;
+                again = 1;
+            }
+        }
+        if (again)
+            continue;
+        bufnum = 0;
+        buf = buff->data;
+
+        clear_comments(conf, buf);
+        s = eat_ws(conf, buf);
+        if (IS_EOF(conf, *s))
+            continue;           /* blank line */
+        if (*s == '[') {
+            char *ss;
+
+            s++;
+            start = eat_ws(conf, s);
+            ss = start;
+ again:
+            end = eat_alpha_numeric(conf, ss);
+            p = eat_ws(conf, end);
+            if (*p != ']') {
+                if (*p != '\0' && ss != p) {
+                    ss = p;
+                    goto again;
+                }
+                CONFerr(CONF_F_DEF_LOAD_BIO,
+                        CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
+                goto err;
+            }
+            *end = '\0';
+            if (!str_copy(conf, NULL, &section, start))
+                goto err;
+            if ((sv = _CONF_get_section(conf, section)) == NULL)
+                sv = _CONF_new_section(conf, section);
+            if (sv == NULL) {
+                CONFerr(CONF_F_DEF_LOAD_BIO,
+                        CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+                goto err;
+            }
+            continue;
+        } else {
+            pname = s;
+            psection = NULL;
+            end = eat_alpha_numeric(conf, s);
+            if ((end[0] == ':') && (end[1] == ':')) {
+                *end = '\0';
+                end += 2;
+                psection = pname;
+                pname = end;
+                end = eat_alpha_numeric(conf, end);
+            }
+            p = eat_ws(conf, end);
+            if (*p != '=') {
+                CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_EQUAL_SIGN);
+                goto err;
+            }
+            *end = '\0';
+            p++;
+            start = eat_ws(conf, p);
+            while (!IS_EOF(conf, *p))
+                p++;
+            p--;
+            while ((p != start) && (IS_WS(conf, *p)))
+                p--;
+            p++;
+            *p = '\0';
+
+            if ((v = OPENSSL_malloc(sizeof(*v))) == NULL) {
+                CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            if (psection == NULL)
+                psection = section;
+            v->name = OPENSSL_malloc(strlen(pname) + 1);
+            v->value = NULL;
+            if (v->name == NULL) {
+                CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            OPENSSL_strlcpy(v->name, pname, strlen(pname) + 1);
+            if (!str_copy(conf, psection, &(v->value), start))
+                goto err;
+
+            if (strcmp(psection, section) != 0) {
+                if ((tv = _CONF_get_section(conf, psection))
+                    == NULL)
+                    tv = _CONF_new_section(conf, psection);
+                if (tv == NULL) {
+                    CONFerr(CONF_F_DEF_LOAD_BIO,
+                            CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+                    goto err;
+                }
+            } else
+                tv = sv;
+            if (_CONF_add_string(conf, tv, v) == 0) {
+                CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            v = NULL;
+        }
+    }
+    BUF_MEM_free(buff);
+    OPENSSL_free(section);
+    return (1);
+ err:
+    BUF_MEM_free(buff);
+    OPENSSL_free(section);
+    if (line != NULL)
+        *line = eline;
+    BIO_snprintf(btmp, sizeof btmp, "%ld", eline);
+    ERR_add_error_data(2, "line ", btmp);
+    if (h != conf->data) {
+        CONF_free(conf->data);
+        conf->data = NULL;
+    }
+    if (v != NULL) {
+        OPENSSL_free(v->name);
+        OPENSSL_free(v->value);
+        OPENSSL_free(v);
+    }
+    return (0);
+}
+
+static void clear_comments(CONF *conf, char *p)
+{
+    for (;;) {
+        if (IS_FCOMMENT(conf, *p)) {
+            *p = '\0';
+            return;
+        }
+        if (!IS_WS(conf, *p)) {
+            break;
+        }
+        p++;
+    }
+
+    for (;;) {
+        if (IS_COMMENT(conf, *p)) {
+            *p = '\0';
+            return;
+        }
+        if (IS_DQUOTE(conf, *p)) {
+            p = scan_dquote(conf, p);
+            continue;
+        }
+        if (IS_QUOTE(conf, *p)) {
+            p = scan_quote(conf, p);
+            continue;
+        }
+        if (IS_ESC(conf, *p)) {
+            p = scan_esc(conf, p);
+            continue;
+        }
+        if (IS_EOF(conf, *p))
+            return;
+        else
+            p++;
+    }
+}
+
+static int str_copy(CONF *conf, char *section, char **pto, char *from)
+{
+    int q, r, rr = 0, to = 0, len = 0;
+    char *s, *e, *rp, *p, *rrp, *np, *cp, v;
+    BUF_MEM *buf;
+
+    if ((buf = BUF_MEM_new()) == NULL)
+        return (0);
+
+    len = strlen(from) + 1;
+    if (!BUF_MEM_grow(buf, len))
+        goto err;
+
+    for (;;) {
+        if (IS_QUOTE(conf, *from)) {
+            q = *from;
+            from++;
+            while (!IS_EOF(conf, *from) && (*from != q)) {
+                if (IS_ESC(conf, *from)) {
+                    from++;
+                    if (IS_EOF(conf, *from))
+                        break;
+                }
+                buf->data[to++] = *(from++);
+            }
+            if (*from == q)
+                from++;
+        } else if (IS_DQUOTE(conf, *from)) {
+            q = *from;
+            from++;
+            while (!IS_EOF(conf, *from)) {
+                if (*from == q) {
+                    if (*(from + 1) == q) {
+                        from++;
+                    } else {
+                        break;
+                    }
+                }
+                buf->data[to++] = *(from++);
+            }
+            if (*from == q)
+                from++;
+        } else if (IS_ESC(conf, *from)) {
+            from++;
+            v = *(from++);
+            if (IS_EOF(conf, v))
+                break;
+            else if (v == 'r')
+                v = '\r';
+            else if (v == 'n')
+                v = '\n';
+            else if (v == 'b')
+                v = '\b';
+            else if (v == 't')
+                v = '\t';
+            buf->data[to++] = v;
+        } else if (IS_EOF(conf, *from))
+            break;
+        else if (*from == '$') {
+            /* try to expand it */
+            rrp = NULL;
+            s = &(from[1]);
+            if (*s == '{')
+                q = '}';
+            else if (*s == '(')
+                q = ')';
+            else
+                q = 0;
+
+            if (q)
+                s++;
+            cp = section;
+            e = np = s;
+            while (IS_ALPHA_NUMERIC(conf, *e))
+                e++;
+            if ((e[0] == ':') && (e[1] == ':')) {
+                cp = np;
+                rrp = e;
+                rr = *e;
+                *rrp = '\0';
+                e += 2;
+                np = e;
+                while (IS_ALPHA_NUMERIC(conf, *e))
+                    e++;
+            }
+            r = *e;
+            *e = '\0';
+            rp = e;
+            if (q) {
+                if (r != q) {
+                    CONFerr(CONF_F_STR_COPY, CONF_R_NO_CLOSE_BRACE);
+                    goto err;
+                }
+                e++;
+            }
+            /*-
+             * So at this point we have
+             * np which is the start of the name string which is
+             *   '\0' terminated.
+             * cp which is the start of the section string which is
+             *   '\0' terminated.
+             * e is the 'next point after'.
+             * r and rr are the chars replaced by the '\0'
+             * rp and rrp is where 'r' and 'rr' came from.
+             */
+            p = _CONF_get_string(conf, cp, np);
+            if (rrp != NULL)
+                *rrp = rr;
+            *rp = r;
+            if (p == NULL) {
+                CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_HAS_NO_VALUE);
+                goto err;
+            }
+            if (!BUF_MEM_grow_clean(buf,
+                        (strlen(p) + buf->length - (e - from)))) {
+                CONFerr(CONF_F_STR_COPY, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            while (*p)
+                buf->data[to++] = *(p++);
+
+            /*
+             * Since we change the pointer 'from', we also have to change the
+             * perceived length of the string it points at.  /RL
+             */
+            len -= e - from;
+            from = e;
+
+            /*
+             * In case there were no braces or parenthesis around the
+             * variable reference, we have to put back the character that was
+             * replaced with a '\0'.  /RL
+             */
+            *rp = r;
+        } else
+            buf->data[to++] = *(from++);
+    }
+    buf->data[to] = '\0';
+    OPENSSL_free(*pto);
+    *pto = buf->data;
+    OPENSSL_free(buf);
+    return (1);
+ err:
+    BUF_MEM_free(buf);
+    return (0);
+}
+
+static char *eat_ws(CONF *conf, char *p)
+{
+    while (IS_WS(conf, *p) && (!IS_EOF(conf, *p)))
+        p++;
+    return (p);
+}
+
+static char *eat_alpha_numeric(CONF *conf, char *p)
+{
+    for (;;) {
+        if (IS_ESC(conf, *p)) {
+            p = scan_esc(conf, p);
+            continue;
+        }
+        if (!IS_ALPHA_NUMERIC_PUNCT(conf, *p))
+            return (p);
+        p++;
+    }
+}
+
+static char *scan_quote(CONF *conf, char *p)
+{
+    int q = *p;
+
+    p++;
+    while (!(IS_EOF(conf, *p)) && (*p != q)) {
+        if (IS_ESC(conf, *p)) {
+            p++;
+            if (IS_EOF(conf, *p))
+                return (p);
+        }
+        p++;
+    }
+    if (*p == q)
+        p++;
+    return (p);
+}
+
+static char *scan_dquote(CONF *conf, char *p)
+{
+    int q = *p;
+
+    p++;
+    while (!(IS_EOF(conf, *p))) {
+        if (*p == q) {
+            if (*(p + 1) == q) {
+                p++;
+            } else {
+                break;
+            }
+        }
+        p++;
+    }
+    if (*p == q)
+        p++;
+    return (p);
+}
+
+static void dump_value_doall_arg(const CONF_VALUE *a, BIO *out)
+{
+    if (a->name)
+        BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value);
+    else
+        BIO_printf(out, "[[%s]]\n", a->section);
+}
+
+IMPLEMENT_LHASH_DOALL_ARG_CONST(CONF_VALUE, BIO);
+
+static int def_dump(const CONF *conf, BIO *out)
+{
+    lh_CONF_VALUE_doall_BIO(conf->data, dump_value_doall_arg, out);
+    return 1;
+}
+
+static int def_is_number(const CONF *conf, char c)
+{
+    return IS_NUMBER(conf, c);
+}
+
+static int def_to_int(const CONF *conf, char c)
+{
+    return c - '0';
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_def.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_def.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_def.h	(revision 331)
@@ -0,0 +1,129 @@
+/*
+ * WARNING: do not edit!
+ * Generated by crypto/conf/keysets.pl
+ *
+ * Copyright 1995-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
+ */
+
+#define CONF_NUMBER             1
+#define CONF_UPPER              2
+#define CONF_LOWER              4
+#define CONF_UNDER              256
+#define CONF_PUNCTUATION        512
+#define CONF_WS                 16
+#define CONF_ESC                32
+#define CONF_QUOTE              64
+#define CONF_DQUOTE             1024
+#define CONF_COMMENT            128
+#define CONF_FCOMMENT           2048
+#define CONF_EOF                8
+#define CONF_HIGHBIT            4096
+#define CONF_ALPHA              (CONF_UPPER|CONF_LOWER)
+#define CONF_ALPHA_NUMERIC      (CONF_ALPHA|CONF_NUMBER|CONF_UNDER)
+#define CONF_ALPHA_NUMERIC_PUNCT (CONF_ALPHA|CONF_NUMBER|CONF_UNDER| \
+                                        CONF_PUNCTUATION)
+
+#define KEYTYPES(c)             ((const unsigned short *)((c)->meth_data))
+#ifndef CHARSET_EBCDIC
+# define IS_COMMENT(c,a)         (KEYTYPES(c)[(a)&0xff]&CONF_COMMENT)
+# define IS_FCOMMENT(c,a)        (KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT)
+# define IS_EOF(c,a)             (KEYTYPES(c)[(a)&0xff]&CONF_EOF)
+# define IS_ESC(c,a)             (KEYTYPES(c)[(a)&0xff]&CONF_ESC)
+# define IS_NUMBER(c,a)          (KEYTYPES(c)[(a)&0xff]&CONF_NUMBER)
+# define IS_WS(c,a)              (KEYTYPES(c)[(a)&0xff]&CONF_WS)
+# define IS_ALPHA_NUMERIC(c,a)   (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC)
+# define IS_ALPHA_NUMERIC_PUNCT(c,a) \
+                                (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC_PUNCT)
+# define IS_QUOTE(c,a)           (KEYTYPES(c)[(a)&0xff]&CONF_QUOTE)
+# define IS_DQUOTE(c,a)          (KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE)
+# define IS_HIGHBIT(c,a)         (KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT)
+
+#else                           /* CHARSET_EBCDIC */
+
+# define IS_COMMENT(c,a)         (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_COMMENT)
+# define IS_FCOMMENT(c,a)        (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_FCOMMENT)
+# define IS_EOF(c,a)             (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_EOF)
+# define IS_ESC(c,a)             (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_ESC)
+# define IS_NUMBER(c,a)          (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_NUMBER)
+# define IS_WS(c,a)              (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_WS)
+# define IS_ALPHA_NUMERIC(c,a)   (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_ALPHA_NUMERIC)
+# define IS_ALPHA_NUMERIC_PUNCT(c,a) \
+                                (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_ALPHA_NUMERIC_PUNCT)
+# define IS_QUOTE(c,a)           (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_QUOTE)
+# define IS_DQUOTE(c,a)          (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_DQUOTE)
+# define IS_HIGHBIT(c,a)         (KEYTYPES(c)[os_toascii[a & 0xff]]&CONF_HIGHBIT)
+#endif                          /* CHARSET_EBCDIC */
+
+static const unsigned short CONF_type_default[256] = {
+    0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000,
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    0x0010, 0x0200, 0x0040, 0x0080, 0x0000, 0x0200, 0x0200, 0x0040,
+    0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200,
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
+    0x0001, 0x0001, 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200,
+    0x0200, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
+    0x0002, 0x0002, 0x0002, 0x0000, 0x0020, 0x0000, 0x0200, 0x0100,
+    0x0040, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
+    0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+};
+
+static const unsigned short CONF_type_win32[256] = {
+    0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000,
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+    0x0010, 0x0200, 0x0400, 0x0000, 0x0000, 0x0200, 0x0200, 0x0000,
+    0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200,
+    0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
+    0x0001, 0x0001, 0x0000, 0x0A00, 0x0000, 0x0000, 0x0000, 0x0200,
+    0x0200, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
+    0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
+    0x0002, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0200, 0x0100,
+    0x0000, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
+    0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
+    0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+    0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000,
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_err.c	(revision 331)
@@ -0,0 +1,79 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/conf.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_CONF,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_CONF,0,reason)
+
+static ERR_STRING_DATA CONF_str_functs[] = {
+    {ERR_FUNC(CONF_F_CONF_DUMP_FP), "CONF_dump_fp"},
+    {ERR_FUNC(CONF_F_CONF_LOAD), "CONF_load"},
+    {ERR_FUNC(CONF_F_CONF_LOAD_FP), "CONF_load_fp"},
+    {ERR_FUNC(CONF_F_CONF_PARSE_LIST), "CONF_parse_list"},
+    {ERR_FUNC(CONF_F_DEF_LOAD), "def_load"},
+    {ERR_FUNC(CONF_F_DEF_LOAD_BIO), "def_load_bio"},
+    {ERR_FUNC(CONF_F_MODULE_INIT), "module_init"},
+    {ERR_FUNC(CONF_F_MODULE_LOAD_DSO), "module_load_dso"},
+    {ERR_FUNC(CONF_F_MODULE_RUN), "module_run"},
+    {ERR_FUNC(CONF_F_NCONF_DUMP_BIO), "NCONF_dump_bio"},
+    {ERR_FUNC(CONF_F_NCONF_DUMP_FP), "NCONF_dump_fp"},
+    {ERR_FUNC(CONF_F_NCONF_GET_NUMBER_E), "NCONF_get_number_e"},
+    {ERR_FUNC(CONF_F_NCONF_GET_SECTION), "NCONF_get_section"},
+    {ERR_FUNC(CONF_F_NCONF_GET_STRING), "NCONF_get_string"},
+    {ERR_FUNC(CONF_F_NCONF_LOAD), "NCONF_load"},
+    {ERR_FUNC(CONF_F_NCONF_LOAD_BIO), "NCONF_load_bio"},
+    {ERR_FUNC(CONF_F_NCONF_LOAD_FP), "NCONF_load_fp"},
+    {ERR_FUNC(CONF_F_NCONF_NEW), "NCONF_new"},
+    {ERR_FUNC(CONF_F_STR_COPY), "str_copy"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA CONF_str_reasons[] = {
+    {ERR_REASON(CONF_R_ERROR_LOADING_DSO), "error loading dso"},
+    {ERR_REASON(CONF_R_LIST_CANNOT_BE_NULL), "list cannot be null"},
+    {ERR_REASON(CONF_R_MISSING_CLOSE_SQUARE_BRACKET),
+     "missing close square bracket"},
+    {ERR_REASON(CONF_R_MISSING_EQUAL_SIGN), "missing equal sign"},
+    {ERR_REASON(CONF_R_MISSING_INIT_FUNCTION), "missing init function"},
+    {ERR_REASON(CONF_R_MODULE_INITIALIZATION_ERROR),
+     "module initialization error"},
+    {ERR_REASON(CONF_R_NO_CLOSE_BRACE), "no close brace"},
+    {ERR_REASON(CONF_R_NO_CONF), "no conf"},
+    {ERR_REASON(CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE),
+     "no conf or environment variable"},
+    {ERR_REASON(CONF_R_NO_SECTION), "no section"},
+    {ERR_REASON(CONF_R_NO_SUCH_FILE), "no such file"},
+    {ERR_REASON(CONF_R_NO_VALUE), "no value"},
+    {ERR_REASON(CONF_R_UNABLE_TO_CREATE_NEW_SECTION),
+     "unable to create new section"},
+    {ERR_REASON(CONF_R_UNKNOWN_MODULE_NAME), "unknown module name"},
+    {ERR_REASON(CONF_R_VARIABLE_HAS_NO_VALUE), "variable has no value"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_CONF_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(CONF_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, CONF_str_functs);
+        ERR_load_strings(0, CONF_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_lib.c	(revision 331)
@@ -0,0 +1,365 @@
+/*
+ * Copyright 2000-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 <stdio.h>
+#include <string.h>
+#include <internal/conf.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/conf.h>
+#include <openssl/conf_api.h>
+#include <openssl/lhash.h>
+#include "e_os.h"
+
+static CONF_METHOD *default_CONF_method = NULL;
+
+/* Init a 'CONF' structure from an old LHASH */
+
+void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash)
+{
+    if (default_CONF_method == NULL)
+        default_CONF_method = NCONF_default();
+
+    default_CONF_method->init(conf);
+    conf->data = hash;
+}
+
+/*
+ * The following section contains the "CONF classic" functions, rewritten in
+ * terms of the new CONF interface.
+ */
+
+int CONF_set_default_method(CONF_METHOD *meth)
+{
+    default_CONF_method = meth;
+    return 1;
+}
+
+LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file,
+                                long *eline)
+{
+    LHASH_OF(CONF_VALUE) *ltmp;
+    BIO *in = NULL;
+
+#ifdef OPENSSL_SYS_VMS
+    in = BIO_new_file(file, "r");
+#else
+    in = BIO_new_file(file, "rb");
+#endif
+    if (in == NULL) {
+        CONFerr(CONF_F_CONF_LOAD, ERR_R_SYS_LIB);
+        return NULL;
+    }
+
+    ltmp = CONF_load_bio(conf, in, eline);
+    BIO_free(in);
+
+    return ltmp;
+}
+
+#ifndef OPENSSL_NO_STDIO
+LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp,
+                                   long *eline)
+{
+    BIO *btmp;
+    LHASH_OF(CONF_VALUE) *ltmp;
+    if ((btmp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) {
+        CONFerr(CONF_F_CONF_LOAD_FP, ERR_R_BUF_LIB);
+        return NULL;
+    }
+    ltmp = CONF_load_bio(conf, btmp, eline);
+    BIO_free(btmp);
+    return ltmp;
+}
+#endif
+
+LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,
+                                    long *eline)
+{
+    CONF ctmp;
+    int ret;
+
+    CONF_set_nconf(&ctmp, conf);
+
+    ret = NCONF_load_bio(&ctmp, bp, eline);
+    if (ret)
+        return ctmp.data;
+    return NULL;
+}
+
+STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf,
+                                       const char *section)
+{
+    if (conf == NULL) {
+        return NULL;
+    } else {
+        CONF ctmp;
+        CONF_set_nconf(&ctmp, conf);
+        return NCONF_get_section(&ctmp, section);
+    }
+}
+
+char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group,
+                      const char *name)
+{
+    if (conf == NULL) {
+        return NCONF_get_string(NULL, group, name);
+    } else {
+        CONF ctmp;
+        CONF_set_nconf(&ctmp, conf);
+        return NCONF_get_string(&ctmp, group, name);
+    }
+}
+
+long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group,
+                     const char *name)
+{
+    int status;
+    long result = 0;
+
+    if (conf == NULL) {
+        status = NCONF_get_number_e(NULL, group, name, &result);
+    } else {
+        CONF ctmp;
+        CONF_set_nconf(&ctmp, conf);
+        status = NCONF_get_number_e(&ctmp, group, name, &result);
+    }
+
+    if (status == 0) {
+        /* This function does not believe in errors... */
+        ERR_clear_error();
+    }
+    return result;
+}
+
+void CONF_free(LHASH_OF(CONF_VALUE) *conf)
+{
+    CONF ctmp;
+    CONF_set_nconf(&ctmp, conf);
+    NCONF_free_data(&ctmp);
+}
+
+#ifndef OPENSSL_NO_STDIO
+int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out)
+{
+    BIO *btmp;
+    int ret;
+
+    if ((btmp = BIO_new_fp(out, BIO_NOCLOSE)) == NULL) {
+        CONFerr(CONF_F_CONF_DUMP_FP, ERR_R_BUF_LIB);
+        return 0;
+    }
+    ret = CONF_dump_bio(conf, btmp);
+    BIO_free(btmp);
+    return ret;
+}
+#endif
+
+int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out)
+{
+    CONF ctmp;
+    CONF_set_nconf(&ctmp, conf);
+    return NCONF_dump_bio(&ctmp, out);
+}
+
+/*
+ * The following section contains the "New CONF" functions.  They are
+ * completely centralised around a new CONF structure that may contain
+ * basically anything, but at least a method pointer and a table of data.
+ * These functions are also written in terms of the bridge functions used by
+ * the "CONF classic" functions, for consistency.
+ */
+
+CONF *NCONF_new(CONF_METHOD *meth)
+{
+    CONF *ret;
+
+    if (meth == NULL)
+        meth = NCONF_default();
+
+    ret = meth->create(meth);
+    if (ret == NULL) {
+        CONFerr(CONF_F_NCONF_NEW, ERR_R_MALLOC_FAILURE);
+        return (NULL);
+    }
+
+    return ret;
+}
+
+void NCONF_free(CONF *conf)
+{
+    if (conf == NULL)
+        return;
+    conf->meth->destroy(conf);
+}
+
+void NCONF_free_data(CONF *conf)
+{
+    if (conf == NULL)
+        return;
+    conf->meth->destroy_data(conf);
+}
+
+int NCONF_load(CONF *conf, const char *file, long *eline)
+{
+    if (conf == NULL) {
+        CONFerr(CONF_F_NCONF_LOAD, CONF_R_NO_CONF);
+        return 0;
+    }
+
+    return conf->meth->load(conf, file, eline);
+}
+
+#ifndef OPENSSL_NO_STDIO
+int NCONF_load_fp(CONF *conf, FILE *fp, long *eline)
+{
+    BIO *btmp;
+    int ret;
+    if ((btmp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) {
+        CONFerr(CONF_F_NCONF_LOAD_FP, ERR_R_BUF_LIB);
+        return 0;
+    }
+    ret = NCONF_load_bio(conf, btmp, eline);
+    BIO_free(btmp);
+    return ret;
+}
+#endif
+
+int NCONF_load_bio(CONF *conf, BIO *bp, long *eline)
+{
+    if (conf == NULL) {
+        CONFerr(CONF_F_NCONF_LOAD_BIO, CONF_R_NO_CONF);
+        return 0;
+    }
+
+    return conf->meth->load_bio(conf, bp, eline);
+}
+
+STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section)
+{
+    if (conf == NULL) {
+        CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_CONF);
+        return NULL;
+    }
+
+    if (section == NULL) {
+        CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_SECTION);
+        return NULL;
+    }
+
+    return _CONF_get_section_values(conf, section);
+}
+
+char *NCONF_get_string(const CONF *conf, const char *group, const char *name)
+{
+    char *s = _CONF_get_string(conf, group, name);
+
+    /*
+     * Since we may get a value from an environment variable even if conf is
+     * NULL, let's check the value first
+     */
+    if (s)
+        return s;
+
+    if (conf == NULL) {
+        CONFerr(CONF_F_NCONF_GET_STRING,
+                CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE);
+        return NULL;
+    }
+    CONFerr(CONF_F_NCONF_GET_STRING, CONF_R_NO_VALUE);
+    ERR_add_error_data(4, "group=", group, " name=", name);
+    return NULL;
+}
+
+int NCONF_get_number_e(const CONF *conf, const char *group, const char *name,
+                       long *result)
+{
+    char *str;
+
+    if (result == NULL) {
+        CONFerr(CONF_F_NCONF_GET_NUMBER_E, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    str = NCONF_get_string(conf, group, name);
+
+    if (str == NULL)
+        return 0;
+
+    for (*result = 0; conf->meth->is_number(conf, *str);) {
+        *result = (*result) * 10 + conf->meth->to_int(conf, *str);
+        str++;
+    }
+
+    return 1;
+}
+
+#ifndef OPENSSL_NO_STDIO
+int NCONF_dump_fp(const CONF *conf, FILE *out)
+{
+    BIO *btmp;
+    int ret;
+    if ((btmp = BIO_new_fp(out, BIO_NOCLOSE)) == NULL) {
+        CONFerr(CONF_F_NCONF_DUMP_FP, ERR_R_BUF_LIB);
+        return 0;
+    }
+    ret = NCONF_dump_bio(conf, btmp);
+    BIO_free(btmp);
+    return ret;
+}
+#endif
+
+int NCONF_dump_bio(const CONF *conf, BIO *out)
+{
+    if (conf == NULL) {
+        CONFerr(CONF_F_NCONF_DUMP_BIO, CONF_R_NO_CONF);
+        return 0;
+    }
+
+    return conf->meth->dump(conf, out);
+}
+
+/*
+ * These routines call the C malloc/free, to avoid intermixing with
+ * OpenSSL function pointers before the library is initialized.
+ */
+OPENSSL_INIT_SETTINGS *OPENSSL_INIT_new(void)
+{
+    OPENSSL_INIT_SETTINGS *ret = malloc(sizeof(*ret));
+
+    if (ret != NULL)
+        memset(ret, 0, sizeof(*ret));
+    return ret;
+}
+
+
+#ifndef OPENSSL_NO_STDIO
+int OPENSSL_INIT_set_config_appname(OPENSSL_INIT_SETTINGS *settings,
+                                    const char *appname)
+{
+    char *newappname = NULL;
+
+    if (appname != NULL) {
+        newappname = strdup(appname);
+        if (newappname == NULL)
+            return 0;
+    }
+
+    free(settings->appname);
+    settings->appname = newappname;
+
+    return 1;
+}
+#endif
+
+void OPENSSL_INIT_free(OPENSSL_INIT_SETTINGS *settings)
+{
+    free(settings->appname);
+    free(settings);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_mall.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_mall.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_mall.c	(revision 331)
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2002-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 <stdio.h>
+#include <openssl/crypto.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/engine.h>
+
+/* Load all OpenSSL builtin modules */
+
+void OPENSSL_load_builtin_modules(void)
+{
+    /* Add builtin modules here */
+    ASN1_add_oid_module();
+    ASN1_add_stable_module();
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE_add_conf_module();
+#endif
+    EVP_add_alg_module();
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_mod.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_mod.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_mod.c	(revision 331)
@@ -0,0 +1,549 @@
+/*
+ * Copyright 2002-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 <stdio.h>
+#include <ctype.h>
+#include <openssl/crypto.h>
+#include "internal/cryptlib.h"
+#include "internal/conf.h"
+#include "internal/dso.h"
+#include <openssl/x509.h>
+
+#define DSO_mod_init_name "OPENSSL_init"
+#define DSO_mod_finish_name "OPENSSL_finish"
+
+/*
+ * This structure contains a data about supported modules. entries in this
+ * table correspond to either dynamic or static modules.
+ */
+
+struct conf_module_st {
+    /* DSO of this module or NULL if static */
+    DSO *dso;
+    /* Name of the module */
+    char *name;
+    /* Init function */
+    conf_init_func *init;
+    /* Finish function */
+    conf_finish_func *finish;
+    /* Number of successfully initialized modules */
+    int links;
+    void *usr_data;
+};
+
+/*
+ * This structure contains information about modules that have been
+ * successfully initialized. There may be more than one entry for a given
+ * module.
+ */
+
+struct conf_imodule_st {
+    CONF_MODULE *pmod;
+    char *name;
+    char *value;
+    unsigned long flags;
+    void *usr_data;
+};
+
+static STACK_OF(CONF_MODULE) *supported_modules = NULL;
+static STACK_OF(CONF_IMODULE) *initialized_modules = NULL;
+
+static void module_free(CONF_MODULE *md);
+static void module_finish(CONF_IMODULE *imod);
+static int module_run(const CONF *cnf, const char *name, const char *value,
+                      unsigned long flags);
+static CONF_MODULE *module_add(DSO *dso, const char *name,
+                               conf_init_func *ifunc,
+                               conf_finish_func *ffunc);
+static CONF_MODULE *module_find(const char *name);
+static int module_init(CONF_MODULE *pmod, const char *name, const char *value,
+                       const CONF *cnf);
+static CONF_MODULE *module_load_dso(const CONF *cnf, const char *name,
+                                    const char *value);
+
+/* Main function: load modules from a CONF structure */
+
+int CONF_modules_load(const CONF *cnf, const char *appname,
+                      unsigned long flags)
+{
+    STACK_OF(CONF_VALUE) *values;
+    CONF_VALUE *vl;
+    char *vsection = NULL;
+
+    int ret, i;
+
+    if (!cnf)
+        return 1;
+
+    if (appname)
+        vsection = NCONF_get_string(cnf, NULL, appname);
+
+    if (!appname || (!vsection && (flags & CONF_MFLAGS_DEFAULT_SECTION)))
+        vsection = NCONF_get_string(cnf, NULL, "openssl_conf");
+
+    if (!vsection) {
+        ERR_clear_error();
+        return 1;
+    }
+
+    values = NCONF_get_section(cnf, vsection);
+
+    if (!values)
+        return 0;
+
+    for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+        vl = sk_CONF_VALUE_value(values, i);
+        ret = module_run(cnf, vl->name, vl->value, flags);
+        if (ret <= 0)
+            if (!(flags & CONF_MFLAGS_IGNORE_ERRORS))
+                return ret;
+    }
+
+    return 1;
+
+}
+
+int CONF_modules_load_file(const char *filename, const char *appname,
+                           unsigned long flags)
+{
+    char *file = NULL;
+    CONF *conf = NULL;
+    int ret = 0;
+    conf = NCONF_new(NULL);
+    if (conf == NULL)
+        goto err;
+
+    if (filename == NULL) {
+        file = CONF_get1_default_config_file();
+        if (!file)
+            goto err;
+    } else
+        file = (char *)filename;
+
+    if (NCONF_load(conf, file, NULL) <= 0) {
+        if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) &&
+            (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE)) {
+            ERR_clear_error();
+            ret = 1;
+        }
+        goto err;
+    }
+
+    ret = CONF_modules_load(conf, appname, flags);
+
+ err:
+    if (filename == NULL)
+        OPENSSL_free(file);
+    NCONF_free(conf);
+
+    return ret;
+}
+
+static int module_run(const CONF *cnf, const char *name, const char *value,
+                      unsigned long flags)
+{
+    CONF_MODULE *md;
+    int ret;
+
+    md = module_find(name);
+
+    /* Module not found: try to load DSO */
+    if (!md && !(flags & CONF_MFLAGS_NO_DSO))
+        md = module_load_dso(cnf, name, value);
+
+    if (!md) {
+        if (!(flags & CONF_MFLAGS_SILENT)) {
+            CONFerr(CONF_F_MODULE_RUN, CONF_R_UNKNOWN_MODULE_NAME);
+            ERR_add_error_data(2, "module=", name);
+        }
+        return -1;
+    }
+
+    ret = module_init(md, name, value, cnf);
+
+    if (ret <= 0) {
+        if (!(flags & CONF_MFLAGS_SILENT)) {
+            char rcode[DECIMAL_SIZE(ret) + 1];
+            CONFerr(CONF_F_MODULE_RUN, CONF_R_MODULE_INITIALIZATION_ERROR);
+            BIO_snprintf(rcode, sizeof rcode, "%-8d", ret);
+            ERR_add_error_data(6, "module=", name, ", value=", value,
+                               ", retcode=", rcode);
+        }
+    }
+
+    return ret;
+}
+
+/* Load a module from a DSO */
+static CONF_MODULE *module_load_dso(const CONF *cnf,
+                                    const char *name, const char *value)
+{
+    DSO *dso = NULL;
+    conf_init_func *ifunc;
+    conf_finish_func *ffunc;
+    const char *path = NULL;
+    int errcode = 0;
+    CONF_MODULE *md;
+    /* Look for alternative path in module section */
+    path = NCONF_get_string(cnf, value, "path");
+    if (!path) {
+        ERR_clear_error();
+        path = name;
+    }
+    dso = DSO_load(NULL, path, NULL, 0);
+    if (!dso) {
+        errcode = CONF_R_ERROR_LOADING_DSO;
+        goto err;
+    }
+    ifunc = (conf_init_func *)DSO_bind_func(dso, DSO_mod_init_name);
+    if (!ifunc) {
+        errcode = CONF_R_MISSING_INIT_FUNCTION;
+        goto err;
+    }
+    ffunc = (conf_finish_func *)DSO_bind_func(dso, DSO_mod_finish_name);
+    /* All OK, add module */
+    md = module_add(dso, name, ifunc, ffunc);
+
+    if (!md)
+        goto err;
+
+    return md;
+
+ err:
+    DSO_free(dso);
+    CONFerr(CONF_F_MODULE_LOAD_DSO, errcode);
+    ERR_add_error_data(4, "module=", name, ", path=", path);
+    return NULL;
+}
+
+/* add module to list */
+static CONF_MODULE *module_add(DSO *dso, const char *name,
+                               conf_init_func *ifunc, conf_finish_func *ffunc)
+{
+    CONF_MODULE *tmod = NULL;
+    if (supported_modules == NULL)
+        supported_modules = sk_CONF_MODULE_new_null();
+    if (supported_modules == NULL)
+        return NULL;
+    tmod = OPENSSL_zalloc(sizeof(*tmod));
+    if (tmod == NULL)
+        return NULL;
+
+    tmod->dso = dso;
+    tmod->name = OPENSSL_strdup(name);
+    tmod->init = ifunc;
+    tmod->finish = ffunc;
+    if (tmod->name == NULL) {
+        OPENSSL_free(tmod);
+        return NULL;
+    }
+
+    if (!sk_CONF_MODULE_push(supported_modules, tmod)) {
+        OPENSSL_free(tmod->name);
+        OPENSSL_free(tmod);
+        return NULL;
+    }
+
+    return tmod;
+}
+
+/*
+ * Find a module from the list. We allow module names of the form
+ * modname.XXXX to just search for modname to allow the same module to be
+ * initialized more than once.
+ */
+
+static CONF_MODULE *module_find(const char *name)
+{
+    CONF_MODULE *tmod;
+    int i, nchar;
+    char *p;
+    p = strrchr(name, '.');
+
+    if (p)
+        nchar = p - name;
+    else
+        nchar = strlen(name);
+
+    for (i = 0; i < sk_CONF_MODULE_num(supported_modules); i++) {
+        tmod = sk_CONF_MODULE_value(supported_modules, i);
+        if (strncmp(tmod->name, name, nchar) == 0)
+            return tmod;
+    }
+
+    return NULL;
+
+}
+
+/* initialize a module */
+static int module_init(CONF_MODULE *pmod, const char *name, const char *value,
+                       const CONF *cnf)
+{
+    int ret = 1;
+    int init_called = 0;
+    CONF_IMODULE *imod = NULL;
+
+    /* Otherwise add initialized module to list */
+    imod = OPENSSL_malloc(sizeof(*imod));
+    if (imod == NULL)
+        goto err;
+
+    imod->pmod = pmod;
+    imod->name = OPENSSL_strdup(name);
+    imod->value = OPENSSL_strdup(value);
+    imod->usr_data = NULL;
+
+    if (!imod->name || !imod->value)
+        goto memerr;
+
+    /* Try to initialize module */
+    if (pmod->init) {
+        ret = pmod->init(imod, cnf);
+        init_called = 1;
+        /* Error occurred, exit */
+        if (ret <= 0)
+            goto err;
+    }
+
+    if (initialized_modules == NULL) {
+        initialized_modules = sk_CONF_IMODULE_new_null();
+        if (!initialized_modules) {
+            CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    }
+
+    if (!sk_CONF_IMODULE_push(initialized_modules, imod)) {
+        CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    pmod->links++;
+
+    return ret;
+
+ err:
+
+    /* We've started the module so we'd better finish it */
+    if (pmod->finish && init_called)
+        pmod->finish(imod);
+
+ memerr:
+    if (imod) {
+        OPENSSL_free(imod->name);
+        OPENSSL_free(imod->value);
+        OPENSSL_free(imod);
+    }
+
+    return -1;
+
+}
+
+/*
+ * Unload any dynamic modules that have a link count of zero: i.e. have no
+ * active initialized modules. If 'all' is set then all modules are unloaded
+ * including static ones.
+ */
+
+void CONF_modules_unload(int all)
+{
+    int i;
+    CONF_MODULE *md;
+    CONF_modules_finish();
+    /* unload modules in reverse order */
+    for (i = sk_CONF_MODULE_num(supported_modules) - 1; i >= 0; i--) {
+        md = sk_CONF_MODULE_value(supported_modules, i);
+        /* If static or in use and 'all' not set ignore it */
+        if (((md->links > 0) || !md->dso) && !all)
+            continue;
+        /* Since we're working in reverse this is OK */
+        (void)sk_CONF_MODULE_delete(supported_modules, i);
+        module_free(md);
+    }
+    if (sk_CONF_MODULE_num(supported_modules) == 0) {
+        sk_CONF_MODULE_free(supported_modules);
+        supported_modules = NULL;
+    }
+}
+
+/* unload a single module */
+static void module_free(CONF_MODULE *md)
+{
+    DSO_free(md->dso);
+    OPENSSL_free(md->name);
+    OPENSSL_free(md);
+}
+
+/* finish and free up all modules instances */
+
+void CONF_modules_finish(void)
+{
+    CONF_IMODULE *imod;
+    while (sk_CONF_IMODULE_num(initialized_modules) > 0) {
+        imod = sk_CONF_IMODULE_pop(initialized_modules);
+        module_finish(imod);
+    }
+    sk_CONF_IMODULE_free(initialized_modules);
+    initialized_modules = NULL;
+}
+
+/* finish a module instance */
+
+static void module_finish(CONF_IMODULE *imod)
+{
+    if (!imod)
+        return;
+    if (imod->pmod->finish)
+        imod->pmod->finish(imod);
+    imod->pmod->links--;
+    OPENSSL_free(imod->name);
+    OPENSSL_free(imod->value);
+    OPENSSL_free(imod);
+}
+
+/* Add a static module to OpenSSL */
+
+int CONF_module_add(const char *name, conf_init_func *ifunc,
+                    conf_finish_func *ffunc)
+{
+    if (module_add(NULL, name, ifunc, ffunc))
+        return 1;
+    else
+        return 0;
+}
+
+void conf_modules_free_int(void)
+{
+    CONF_modules_finish();
+    CONF_modules_unload(1);
+}
+
+/* Utility functions */
+
+const char *CONF_imodule_get_name(const CONF_IMODULE *md)
+{
+    return md->name;
+}
+
+const char *CONF_imodule_get_value(const CONF_IMODULE *md)
+{
+    return md->value;
+}
+
+void *CONF_imodule_get_usr_data(const CONF_IMODULE *md)
+{
+    return md->usr_data;
+}
+
+void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data)
+{
+    md->usr_data = usr_data;
+}
+
+CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md)
+{
+    return md->pmod;
+}
+
+unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md)
+{
+    return md->flags;
+}
+
+void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags)
+{
+    md->flags = flags;
+}
+
+void *CONF_module_get_usr_data(CONF_MODULE *pmod)
+{
+    return pmod->usr_data;
+}
+
+void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data)
+{
+    pmod->usr_data = usr_data;
+}
+
+/* Return default config file name */
+
+char *CONF_get1_default_config_file(void)
+{
+    char *file;
+    int len;
+
+    file = getenv("OPENSSL_CONF");
+    if (file)
+        return OPENSSL_strdup(file);
+
+    len = strlen(X509_get_default_cert_area());
+#ifndef OPENSSL_SYS_VMS
+    len++;
+#endif
+    len += strlen(OPENSSL_CONF);
+
+    file = OPENSSL_malloc(len + 1);
+
+    if (file == NULL)
+        return NULL;
+    OPENSSL_strlcpy(file, X509_get_default_cert_area(), len + 1);
+#ifndef OPENSSL_SYS_VMS
+    OPENSSL_strlcat(file, "/", len + 1);
+#endif
+    OPENSSL_strlcat(file, OPENSSL_CONF, len + 1);
+
+    return file;
+}
+
+/*
+ * This function takes a list separated by 'sep' and calls the callback
+ * function giving the start and length of each member optionally stripping
+ * leading and trailing whitespace. This can be used to parse comma separated
+ * lists for example.
+ */
+
+int CONF_parse_list(const char *list_, int sep, int nospc,
+                    int (*list_cb) (const char *elem, int len, void *usr),
+                    void *arg)
+{
+    int ret;
+    const char *lstart, *tmpend, *p;
+
+    if (list_ == NULL) {
+        CONFerr(CONF_F_CONF_PARSE_LIST, CONF_R_LIST_CANNOT_BE_NULL);
+        return 0;
+    }
+
+    lstart = list_;
+    for (;;) {
+        if (nospc) {
+            while (*lstart && isspace((unsigned char)*lstart))
+                lstart++;
+        }
+        p = strchr(lstart, sep);
+        if (p == lstart || !*lstart)
+            ret = list_cb(NULL, 0, arg);
+        else {
+            if (p)
+                tmpend = p - 1;
+            else
+                tmpend = lstart + strlen(lstart) - 1;
+            if (nospc) {
+                while (isspace((unsigned char)*tmpend))
+                    tmpend--;
+            }
+            ret = list_cb(lstart, tmpend - lstart + 1, arg);
+        }
+        if (ret <= 0)
+            return ret;
+        if (p == NULL)
+            return 1;
+        lstart = p + 1;
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_sap.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_sap.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/conf/conf_sap.c	(revision 331)
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2002-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 <stdio.h>
+#include <openssl/crypto.h>
+#include "internal/cryptlib.h"
+#include <internal/conf.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/engine.h>
+
+/*
+ * This is the automatic configuration loader: it is called automatically by
+ * OpenSSL when any of a number of standard initialisation functions are
+ * called, unless this is overridden by calling OPENSSL_no_config()
+ */
+
+static int openssl_configured = 0;
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+void OPENSSL_config(const char *appname)
+{
+    OPENSSL_INIT_SETTINGS settings;
+
+    memset(&settings, 0, sizeof(settings));
+    if (appname != NULL)
+        settings.appname = strdup(appname);
+    OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, &settings);
+}
+#endif
+
+void openssl_config_int(const char *appname)
+{
+    if (openssl_configured)
+        return;
+
+    OPENSSL_load_builtin_modules();
+#ifndef OPENSSL_NO_ENGINE
+    /* Need to load ENGINEs */
+    ENGINE_load_builtin_engines();
+#endif
+    ERR_clear_error();
+#ifndef OPENSSL_SYS_UEFI
+    CONF_modules_load_file(NULL, appname,
+                               CONF_MFLAGS_DEFAULT_SECTION |
+                               CONF_MFLAGS_IGNORE_MISSING_FILE);
+#endif
+    openssl_configured = 1;
+}
+
+void openssl_no_config_int(void)
+{
+    openssl_configured = 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cpt_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cpt_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cpt_err.c	(revision 331)
@@ -0,0 +1,55 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/crypto.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_CRYPTO,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_CRYPTO,0,reason)
+
+static ERR_STRING_DATA CRYPTO_str_functs[] = {
+    {ERR_FUNC(CRYPTO_F_CRYPTO_DUP_EX_DATA), "CRYPTO_dup_ex_data"},
+    {ERR_FUNC(CRYPTO_F_CRYPTO_FREE_EX_DATA), "CRYPTO_free_ex_data"},
+    {ERR_FUNC(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX), "CRYPTO_get_ex_new_index"},
+    {ERR_FUNC(CRYPTO_F_CRYPTO_MEMDUP), "CRYPTO_memdup"},
+    {ERR_FUNC(CRYPTO_F_CRYPTO_NEW_EX_DATA), "CRYPTO_new_ex_data"},
+    {ERR_FUNC(CRYPTO_F_CRYPTO_SET_EX_DATA), "CRYPTO_set_ex_data"},
+    {ERR_FUNC(CRYPTO_F_FIPS_MODE_SET), "FIPS_mode_set"},
+    {ERR_FUNC(CRYPTO_F_GET_AND_LOCK), "get_and_lock"},
+    {ERR_FUNC(CRYPTO_F_OPENSSL_BUF2HEXSTR), "OPENSSL_buf2hexstr"},
+    {ERR_FUNC(CRYPTO_F_OPENSSL_HEXSTR2BUF), "OPENSSL_hexstr2buf"},
+    {ERR_FUNC(CRYPTO_F_OPENSSL_INIT_CRYPTO), "OPENSSL_init_crypto"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA CRYPTO_str_reasons[] = {
+    {ERR_REASON(CRYPTO_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"},
+    {ERR_REASON(CRYPTO_R_ILLEGAL_HEX_DIGIT), "illegal hex digit"},
+    {ERR_REASON(CRYPTO_R_ODD_NUMBER_OF_DIGITS), "odd number of digits"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_CRYPTO_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(CRYPTO_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, CRYPTO_str_functs);
+        ERR_load_strings(0, CRYPTO_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cryptlib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cryptlib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cryptlib.c	(revision 331)
@@ -0,0 +1,341 @@
+/*
+ * Copyright 1998-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include "internal/cryptlib_int.h"
+#include <openssl/safestack.h>
+
+#if     defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
+        defined(__x86_64) || defined(__x86_64__) || \
+        defined(_M_AMD64) || defined(_M_X64)
+
+extern unsigned int OPENSSL_ia32cap_P[4];
+
+# if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY)
+#include <stdio.h>
+#  define OPENSSL_CPUID_SETUP
+typedef uint64_t IA32CAP;
+void OPENSSL_cpuid_setup(void)
+{
+    static int trigger = 0;
+    IA32CAP OPENSSL_ia32_cpuid(unsigned int *);
+    IA32CAP vec;
+    char *env;
+
+    if (trigger)
+        return;
+
+    trigger = 1;
+    if ((env = getenv("OPENSSL_ia32cap"))) {
+        int off = (env[0] == '~') ? 1 : 0;
+#  if defined(_WIN32)
+        if (!sscanf(env + off, "%I64i", &vec))
+            vec = strtoul(env + off, NULL, 0);
+#  else
+        if (!sscanf(env + off, "%lli", (long long *)&vec))
+            vec = strtoul(env + off, NULL, 0);
+#  endif
+        if (off)
+            vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~vec;
+        else if (env[0] == ':')
+            vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
+
+        OPENSSL_ia32cap_P[2] = 0;
+        if ((env = strchr(env, ':'))) {
+            unsigned int vecx;
+            env++;
+            off = (env[0] == '~') ? 1 : 0;
+            vecx = strtoul(env + off, NULL, 0);
+            if (off)
+                OPENSSL_ia32cap_P[2] &= ~vecx;
+            else
+                OPENSSL_ia32cap_P[2] = vecx;
+        }
+    } else
+        vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
+
+    /*
+     * |(1<<10) sets a reserved bit to signal that variable
+     * was initialized already... This is to avoid interference
+     * with cpuid snippets in ELF .init segment.
+     */
+    OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10);
+    OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32);
+}
+# else
+unsigned int OPENSSL_ia32cap_P[4];
+# endif
+#endif
+int OPENSSL_NONPIC_relocated = 0;
+#if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ)
+void OPENSSL_cpuid_setup(void)
+{
+}
+#endif
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# include <tchar.h>
+# include <signal.h>
+# ifdef __WATCOMC__
+#  if defined(_UNICODE) || defined(__UNICODE__)
+#   define _vsntprintf _vsnwprintf
+#  else
+#   define _vsntprintf _vsnprintf
+#  endif
+# endif
+# ifdef _MSC_VER
+#  define alloca _alloca
+# endif
+
+# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
+int OPENSSL_isservice(void)
+{
+    HWINSTA h;
+    DWORD len;
+    WCHAR *name;
+    static union {
+        void *p;
+        FARPROC f;
+    } _OPENSSL_isservice = {
+        NULL
+    };
+
+    if (_OPENSSL_isservice.p == NULL) {
+        HANDLE mod = GetModuleHandle(NULL);
+        if (mod != NULL)
+            _OPENSSL_isservice.f = GetProcAddress(mod, "_OPENSSL_isservice");
+        if (_OPENSSL_isservice.p == NULL)
+            _OPENSSL_isservice.p = (void *)-1;
+    }
+
+    if (_OPENSSL_isservice.p != (void *)-1)
+        return (*_OPENSSL_isservice.f) ();
+
+    h = GetProcessWindowStation();
+    if (h == NULL)
+        return -1;
+
+    if (GetUserObjectInformationW(h, UOI_NAME, NULL, 0, &len) ||
+        GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+        return -1;
+
+    if (len > 512)
+        return -1;              /* paranoia */
+    len++, len &= ~1;           /* paranoia */
+    name = (WCHAR *)alloca(len + sizeof(WCHAR));
+    if (!GetUserObjectInformationW(h, UOI_NAME, name, len, &len))
+        return -1;
+
+    len++, len &= ~1;           /* paranoia */
+    name[len / sizeof(WCHAR)] = L'\0'; /* paranoia */
+#  if 1
+    /*
+     * This doesn't cover "interactive" services [working with real
+     * WinSta0's] nor programs started non-interactively by Task Scheduler
+     * [those are working with SAWinSta].
+     */
+    if (wcsstr(name, L"Service-0x"))
+        return 1;
+#  else
+    /* This covers all non-interactive programs such as services. */
+    if (!wcsstr(name, L"WinSta0"))
+        return 1;
+#  endif
+    else
+        return 0;
+}
+# else
+int OPENSSL_isservice(void)
+{
+    return 0;
+}
+# endif
+
+void OPENSSL_showfatal(const char *fmta, ...)
+{
+    va_list ap;
+    TCHAR buf[256];
+    const TCHAR *fmt;
+# ifdef STD_ERROR_HANDLE        /* what a dirty trick! */
+    HANDLE h;
+
+    if ((h = GetStdHandle(STD_ERROR_HANDLE)) != NULL &&
+        GetFileType(h) != FILE_TYPE_UNKNOWN) {
+        /* must be console application */
+        int len;
+        DWORD out;
+
+        va_start(ap, fmta);
+        len = _vsnprintf((char *)buf, sizeof(buf), fmta, ap);
+        WriteFile(h, buf, len < 0 ? sizeof(buf) : (DWORD) len, &out, NULL);
+        va_end(ap);
+        return;
+    }
+# endif
+
+    if (sizeof(TCHAR) == sizeof(char))
+        fmt = (const TCHAR *)fmta;
+    else
+        do {
+            int keepgoing;
+            size_t len_0 = strlen(fmta) + 1, i;
+            WCHAR *fmtw;
+
+            fmtw = (WCHAR *)alloca(len_0 * sizeof(WCHAR));
+            if (fmtw == NULL) {
+                fmt = (const TCHAR *)L"no stack?";
+                break;
+            }
+            if (!MultiByteToWideChar(CP_ACP, 0, fmta, len_0, fmtw, len_0))
+                for (i = 0; i < len_0; i++)
+                    fmtw[i] = (WCHAR)fmta[i];
+            for (i = 0; i < len_0; i++) {
+                if (fmtw[i] == L'%')
+                    do {
+                        keepgoing = 0;
+                        switch (fmtw[i + 1]) {
+                        case L'0':
+                        case L'1':
+                        case L'2':
+                        case L'3':
+                        case L'4':
+                        case L'5':
+                        case L'6':
+                        case L'7':
+                        case L'8':
+                        case L'9':
+                        case L'.':
+                        case L'*':
+                        case L'-':
+                            i++;
+                            keepgoing = 1;
+                            break;
+                        case L's':
+                            fmtw[i + 1] = L'S';
+                            break;
+                        case L'S':
+                            fmtw[i + 1] = L's';
+                            break;
+                        case L'c':
+                            fmtw[i + 1] = L'C';
+                            break;
+                        case L'C':
+                            fmtw[i + 1] = L'c';
+                            break;
+                        }
+                    } while (keepgoing);
+            }
+            fmt = (const TCHAR *)fmtw;
+        } while (0);
+
+    va_start(ap, fmta);
+    _vsntprintf(buf, OSSL_NELEM(buf) - 1, fmt, ap);
+    buf[OSSL_NELEM(buf) - 1] = _T('\0');
+    va_end(ap);
+
+# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
+    /* this -------------v--- guards NT-specific calls */
+    if (check_winnt() && OPENSSL_isservice() > 0) {
+        HANDLE hEventLog = RegisterEventSource(NULL, _T("OpenSSL"));
+
+        if (hEventLog != NULL) {
+            const TCHAR *pmsg = buf;
+
+            if (!ReportEvent(hEventLog, EVENTLOG_ERROR_TYPE, 0, 0, NULL,
+                             1, 0, &pmsg, NULL)) {
+#if defined(DEBUG)
+                /*
+                 * We are in a situation where we tried to report a critical
+                 * error and this failed for some reason. As a last resort,
+                 * in debug builds, send output to the debugger or any other
+                 * tool like DebugView which can monitor the output.
+                 */
+                OutputDebugString(pmsg);
+#endif
+            }
+
+            (void)DeregisterEventSource(hEventLog);
+        }
+    } else
+# endif
+        MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR);
+}
+#else
+void OPENSSL_showfatal(const char *fmta, ...)
+{
+#ifndef OPENSSL_NO_STDIO
+    va_list ap;
+
+    va_start(ap, fmta);
+    vfprintf(stderr, fmta, ap);
+    va_end(ap);
+#endif
+}
+
+int OPENSSL_isservice(void)
+{
+    return 0;
+}
+#endif
+
+void OPENSSL_die(const char *message, const char *file, int line)
+{
+    OPENSSL_showfatal("%s:%d: OpenSSL internal error: %s\n",
+                      file, line, message);
+#if !defined(_WIN32) || defined(__CYGWIN__)
+    abort();
+#else
+    /*
+     * Win32 abort() customarily shows a dialog, but we just did that...
+     */
+# if !defined(_WIN32_WCE)
+    raise(SIGABRT);
+# endif
+    _exit(3);
+#endif
+}
+
+#if !defined(OPENSSL_CPUID_OBJ)
+/* volatile unsigned char* pointers are there because
+ * 1. Accessing a variable declared volatile via a pointer
+ *    that lacks a volatile qualifier causes undefined behavior.
+ * 2. When the variable itself is not volatile the compiler is
+ *    not required to keep all those reads and can convert
+ *    this into canonical memcmp() which doesn't read the whole block.
+ * Pointers to volatile resolve the first problem fully. The second
+ * problem cannot be resolved in any Standard-compliant way but this
+ * works the problem around. Compilers typically react to
+ * pointers to volatile by preserving the reads and writes through them.
+ * The latter is not required by the Standard if the memory pointed to
+ * is not volatile.
+ * Pointers themselves are volatile in the function signature to work
+ * around a subtle bug in gcc 4.6+ which causes writes through
+ * pointers to volatile to not be emitted in some rare,
+ * never needed in real life, pieces of code.
+ */
+int CRYPTO_memcmp(const volatile void * volatile in_a,
+                  const volatile void * volatile in_b,
+                  size_t len)
+{
+    size_t i;
+    const volatile unsigned char *a = in_a;
+    const volatile unsigned char *b = in_b;
+    unsigned char x = 0;
+
+    for (i = 0; i < len; i++)
+        x |= a[i] ^ b[i];
+
+    return x;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_b64.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_b64.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_b64.c	(revision 331)
@@ -0,0 +1,164 @@
+/*
+ * 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 <limits.h>
+#include <string.h>
+
+#include <openssl/ct.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+
+#include "ct_locl.h"
+
+/*
+ * Decodes the base64 string |in| into |out|.
+ * A new string will be malloc'd and assigned to |out|. This will be owned by
+ * the caller. Do not provide a pre-allocated string in |out|.
+ */
+static int ct_base64_decode(const char *in, unsigned char **out)
+{
+    size_t inlen = strlen(in);
+    int outlen;
+    unsigned char *outbuf = NULL;
+
+    if (inlen == 0) {
+        *out = NULL;
+        return 0;
+    }
+
+    outlen = (inlen / 4) * 3;
+    outbuf = OPENSSL_malloc(outlen);
+    if (outbuf == NULL) {
+        CTerr(CT_F_CT_BASE64_DECODE, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    outlen = EVP_DecodeBlock(outbuf, (unsigned char *)in, inlen);
+    if (outlen < 0) {
+        CTerr(CT_F_CT_BASE64_DECODE, CT_R_BASE64_DECODE_ERROR);
+        goto err;
+    }
+
+    /* Subtract padding bytes from |outlen| */
+    while (in[--inlen] == '=') {
+        --outlen;
+    }
+
+    *out = outbuf;
+    return outlen;
+err:
+    OPENSSL_free(outbuf);
+    return -1;
+}
+
+SCT *SCT_new_from_base64(unsigned char version, const char *logid_base64,
+                         ct_log_entry_type_t entry_type, uint64_t timestamp,
+                         const char *extensions_base64,
+                         const char *signature_base64)
+{
+    SCT *sct = SCT_new();
+    unsigned char *dec = NULL;
+    const unsigned char* p = NULL;
+    int declen;
+
+    if (sct == NULL) {
+        CTerr(CT_F_SCT_NEW_FROM_BASE64, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    /*
+     * RFC6962 section 4.1 says we "MUST NOT expect this to be 0", but we
+     * can only construct SCT versions that have been defined.
+     */
+    if (!SCT_set_version(sct, version)) {
+        CTerr(CT_F_SCT_NEW_FROM_BASE64, CT_R_SCT_UNSUPPORTED_VERSION);
+        goto err;
+    }
+
+    declen = ct_base64_decode(logid_base64, &dec);
+    if (declen < 0) {
+        CTerr(CT_F_SCT_NEW_FROM_BASE64, X509_R_BASE64_DECODE_ERROR);
+        goto err;
+    }
+    if (!SCT_set0_log_id(sct, dec, declen))
+        goto err;
+    dec = NULL;
+
+    declen = ct_base64_decode(extensions_base64, &dec);
+    if (declen < 0) {
+        CTerr(CT_F_SCT_NEW_FROM_BASE64, X509_R_BASE64_DECODE_ERROR);
+        goto err;
+    }
+    SCT_set0_extensions(sct, dec, declen);
+    dec = NULL;
+
+    declen = ct_base64_decode(signature_base64, &dec);
+    if (declen < 0) {
+        CTerr(CT_F_SCT_NEW_FROM_BASE64, X509_R_BASE64_DECODE_ERROR);
+        goto err;
+    }
+
+    p = dec;
+    if (o2i_SCT_signature(sct, &p, declen) <= 0)
+        goto err;
+    OPENSSL_free(dec);
+    dec = NULL;
+
+    SCT_set_timestamp(sct, timestamp);
+
+    if (!SCT_set_log_entry_type(sct, entry_type))
+        goto err;
+
+    return sct;
+
+ err:
+    OPENSSL_free(dec);
+    SCT_free(sct);
+    return NULL;
+}
+
+/*
+ * Allocate, build and returns a new |ct_log| from input |pkey_base64|
+ * It returns 1 on success,
+ * 0 on decoding failure, or invalid parameter if any
+ * -1 on internal (malloc) failure
+ */
+int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *name)
+{
+    unsigned char *pkey_der = NULL;
+    int pkey_der_len = ct_base64_decode(pkey_base64, &pkey_der);
+    const unsigned char *p;
+    EVP_PKEY *pkey = NULL;
+
+    if (ct_log == NULL) {
+        CTerr(CT_F_CTLOG_NEW_FROM_BASE64, ERR_R_PASSED_INVALID_ARGUMENT);
+        return 0;
+    }
+
+    if (pkey_der_len <= 0) {
+        CTerr(CT_F_CTLOG_NEW_FROM_BASE64, CT_R_LOG_CONF_INVALID_KEY);
+        return 0;
+    }
+
+    p = pkey_der;
+    pkey = d2i_PUBKEY(NULL, &p, pkey_der_len);
+    OPENSSL_free(pkey_der);
+    if (pkey == NULL) {
+        CTerr(CT_F_CTLOG_NEW_FROM_BASE64, CT_R_LOG_CONF_INVALID_KEY);
+        return 0;
+    }
+
+    *ct_log = CTLOG_new(pkey, name);
+    if (*ct_log == NULL) {
+        EVP_PKEY_free(pkey);
+        return 0;
+    }
+
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_err.c	(revision 331)
@@ -0,0 +1,87 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/ct.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_CT,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_CT,0,reason)
+
+static ERR_STRING_DATA CT_str_functs[] = {
+    {ERR_FUNC(CT_F_CTLOG_NEW), "CTLOG_new"},
+    {ERR_FUNC(CT_F_CTLOG_NEW_FROM_BASE64), "CTLOG_new_from_base64"},
+    {ERR_FUNC(CT_F_CTLOG_NEW_FROM_CONF), "ctlog_new_from_conf"},
+    {ERR_FUNC(CT_F_CTLOG_STORE_LOAD_CTX_NEW), "ctlog_store_load_ctx_new"},
+    {ERR_FUNC(CT_F_CTLOG_STORE_LOAD_FILE), "CTLOG_STORE_load_file"},
+    {ERR_FUNC(CT_F_CTLOG_STORE_LOAD_LOG), "ctlog_store_load_log"},
+    {ERR_FUNC(CT_F_CTLOG_STORE_NEW), "CTLOG_STORE_new"},
+    {ERR_FUNC(CT_F_CT_BASE64_DECODE), "ct_base64_decode"},
+    {ERR_FUNC(CT_F_CT_POLICY_EVAL_CTX_NEW), "CT_POLICY_EVAL_CTX_new"},
+    {ERR_FUNC(CT_F_CT_V1_LOG_ID_FROM_PKEY), "ct_v1_log_id_from_pkey"},
+    {ERR_FUNC(CT_F_I2O_SCT), "i2o_SCT"},
+    {ERR_FUNC(CT_F_I2O_SCT_LIST), "i2o_SCT_LIST"},
+    {ERR_FUNC(CT_F_I2O_SCT_SIGNATURE), "i2o_SCT_signature"},
+    {ERR_FUNC(CT_F_O2I_SCT), "o2i_SCT"},
+    {ERR_FUNC(CT_F_O2I_SCT_LIST), "o2i_SCT_LIST"},
+    {ERR_FUNC(CT_F_O2I_SCT_SIGNATURE), "o2i_SCT_signature"},
+    {ERR_FUNC(CT_F_SCT_CTX_NEW), "SCT_CTX_new"},
+    {ERR_FUNC(CT_F_SCT_CTX_VERIFY), "SCT_CTX_verify"},
+    {ERR_FUNC(CT_F_SCT_NEW), "SCT_new"},
+    {ERR_FUNC(CT_F_SCT_NEW_FROM_BASE64), "SCT_new_from_base64"},
+    {ERR_FUNC(CT_F_SCT_SET0_LOG_ID), "SCT_set0_log_id"},
+    {ERR_FUNC(CT_F_SCT_SET1_EXTENSIONS), "SCT_set1_extensions"},
+    {ERR_FUNC(CT_F_SCT_SET1_LOG_ID), "SCT_set1_log_id"},
+    {ERR_FUNC(CT_F_SCT_SET1_SIGNATURE), "SCT_set1_signature"},
+    {ERR_FUNC(CT_F_SCT_SET_LOG_ENTRY_TYPE), "SCT_set_log_entry_type"},
+    {ERR_FUNC(CT_F_SCT_SET_SIGNATURE_NID), "SCT_set_signature_nid"},
+    {ERR_FUNC(CT_F_SCT_SET_VERSION), "SCT_set_version"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA CT_str_reasons[] = {
+    {ERR_REASON(CT_R_BASE64_DECODE_ERROR), "base64 decode error"},
+    {ERR_REASON(CT_R_INVALID_LOG_ID_LENGTH), "invalid log id length"},
+    {ERR_REASON(CT_R_LOG_CONF_INVALID), "log conf invalid"},
+    {ERR_REASON(CT_R_LOG_CONF_INVALID_KEY), "log conf invalid key"},
+    {ERR_REASON(CT_R_LOG_CONF_MISSING_DESCRIPTION),
+     "log conf missing description"},
+    {ERR_REASON(CT_R_LOG_CONF_MISSING_KEY), "log conf missing key"},
+    {ERR_REASON(CT_R_LOG_KEY_INVALID), "log key invalid"},
+    {ERR_REASON(CT_R_SCT_FUTURE_TIMESTAMP), "sct future timestamp"},
+    {ERR_REASON(CT_R_SCT_INVALID), "sct invalid"},
+    {ERR_REASON(CT_R_SCT_INVALID_SIGNATURE), "sct invalid signature"},
+    {ERR_REASON(CT_R_SCT_LIST_INVALID), "sct list invalid"},
+    {ERR_REASON(CT_R_SCT_LOG_ID_MISMATCH), "sct log id mismatch"},
+    {ERR_REASON(CT_R_SCT_NOT_SET), "sct not set"},
+    {ERR_REASON(CT_R_SCT_UNSUPPORTED_VERSION), "sct unsupported version"},
+    {ERR_REASON(CT_R_UNRECOGNIZED_SIGNATURE_NID),
+     "unrecognized signature nid"},
+    {ERR_REASON(CT_R_UNSUPPORTED_ENTRY_TYPE), "unsupported entry type"},
+    {ERR_REASON(CT_R_UNSUPPORTED_VERSION), "unsupported version"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_CT_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(CT_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, CT_str_functs);
+        ERR_load_strings(0, CT_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_locl.h	(revision 331)
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2015-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 <stddef.h>
+#include <openssl/ct.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/safestack.h>
+
+/*
+ * From RFC6962: opaque SerializedSCT<1..2^16-1>; struct { SerializedSCT
+ * sct_list <1..2^16-1>; } SignedCertificateTimestampList;
+ */
+# define MAX_SCT_SIZE            65535
+# define MAX_SCT_LIST_SIZE       MAX_SCT_SIZE
+
+/*
+ * Macros to read and write integers in network-byte order.
+ */
+
+#define n2s(c,s)        ((s=(((unsigned int)((c)[0]))<< 8)| \
+                            (((unsigned int)((c)[1]))    )),c+=2)
+
+#define s2n(s,c)        ((c[0]=(unsigned char)(((s)>> 8)&0xff), \
+                          c[1]=(unsigned char)(((s)    )&0xff)),c+=2)
+
+#define l2n3(l,c)       ((c[0]=(unsigned char)(((l)>>16)&0xff), \
+                          c[1]=(unsigned char)(((l)>> 8)&0xff), \
+                          c[2]=(unsigned char)(((l)    )&0xff)),c+=3)
+
+#define n2l8(c,l)       (l =((uint64_t)(*((c)++)))<<56, \
+                         l|=((uint64_t)(*((c)++)))<<48, \
+                         l|=((uint64_t)(*((c)++)))<<40, \
+                         l|=((uint64_t)(*((c)++)))<<32, \
+                         l|=((uint64_t)(*((c)++)))<<24, \
+                         l|=((uint64_t)(*((c)++)))<<16, \
+                         l|=((uint64_t)(*((c)++)))<< 8, \
+                         l|=((uint64_t)(*((c)++))))
+
+#define l2n8(l,c)       (*((c)++)=(unsigned char)(((l)>>56)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>48)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>40)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>32)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>24)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+                         *((c)++)=(unsigned char)(((l)    )&0xff))
+
+/* Signed Certificate Timestamp */
+struct sct_st {
+    sct_version_t version;
+    /* If version is not SCT_VERSION_V1, this contains the encoded SCT */
+    unsigned char *sct;
+    size_t sct_len;
+    /* If version is SCT_VERSION_V1, fields below contain components of the SCT */
+    unsigned char *log_id;
+    size_t log_id_len;
+    /*
+    * Note, we cannot distinguish between an unset timestamp, and one
+    * that is set to 0.  However since CT didn't exist in 1970, no real
+    * SCT should ever be set as such.
+    */
+    uint64_t timestamp;
+    unsigned char *ext;
+    size_t ext_len;
+    unsigned char hash_alg;
+    unsigned char sig_alg;
+    unsigned char *sig;
+    size_t sig_len;
+    /* Log entry type */
+    ct_log_entry_type_t entry_type;
+    /* Where this SCT was found, e.g. certificate, OCSP response, etc. */
+    sct_source_t source;
+    /* The result of the last attempt to validate this SCT. */
+    sct_validation_status_t validation_status;
+};
+
+/* Miscellaneous data that is useful when verifying an SCT  */
+struct sct_ctx_st {
+    /* Public key */
+    EVP_PKEY *pkey;
+    /* Hash of public key */
+    unsigned char *pkeyhash;
+    size_t pkeyhashlen;
+    /* For pre-certificate: issuer public key hash */
+    unsigned char *ihash;
+    size_t ihashlen;
+    /* certificate encoding */
+    unsigned char *certder;
+    size_t certderlen;
+    /* pre-certificate encoding */
+    unsigned char *preder;
+    size_t prederlen;
+    /* milliseconds since epoch (to check that the SCT isn't from the future) */
+    uint64_t epoch_time_in_ms;
+};
+
+/* Context when evaluating whether a Certificate Transparency policy is met */
+struct ct_policy_eval_ctx_st {
+    X509 *cert;
+    X509 *issuer;
+    CTLOG_STORE *log_store;
+    /* milliseconds since epoch (to check that SCTs aren't from the future) */
+    uint64_t epoch_time_in_ms;
+};
+
+/*
+ * Creates a new context for verifying an SCT.
+ */
+SCT_CTX *SCT_CTX_new(void);
+/*
+ * Deletes an SCT verification context.
+ */
+void SCT_CTX_free(SCT_CTX *sctx);
+
+/*
+ * Sets the certificate that the SCT was created for.
+ * If *cert does not have a poison extension, presigner must be NULL.
+ * If *cert does not have a poison extension, it may have a single SCT
+ * (NID_ct_precert_scts) extension.
+ * If either *cert or *presigner have an AKID (NID_authority_key_identifier)
+ * extension, both must have one.
+ * Returns 1 on success, 0 on failure.
+ */
+__owur int SCT_CTX_set1_cert(SCT_CTX *sctx, X509 *cert, X509 *presigner);
+
+/*
+ * Sets the issuer of the certificate that the SCT was created for.
+ * This is just a convenience method to save extracting the public key and
+ * calling SCT_CTX_set1_issuer_pubkey().
+ * Issuer must not be NULL.
+ * Returns 1 on success, 0 on failure.
+ */
+__owur int SCT_CTX_set1_issuer(SCT_CTX *sctx, const X509 *issuer);
+
+/*
+ * Sets the public key of the issuer of the certificate that the SCT was created
+ * for.
+ * The public key must not be NULL.
+ * Returns 1 on success, 0 on failure.
+ */
+__owur int SCT_CTX_set1_issuer_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey);
+
+/*
+ * Sets the public key of the CT log that the SCT is from.
+ * Returns 1 on success, 0 on failure.
+ */
+__owur int SCT_CTX_set1_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey);
+
+/*
+ * Sets the time to evaluate the SCT against, in milliseconds since the Unix
+ * epoch. If the SCT's timestamp is after this time, it will be interpreted as
+ * having been issued in the future. RFC6962 states that "TLS clients MUST
+ * reject SCTs whose timestamp is in the future", so an SCT will not validate
+ * in this case.
+ */
+void SCT_CTX_set_time(SCT_CTX *sctx, uint64_t time_in_ms);
+
+/*
+ * Verifies an SCT with the given context.
+ * Returns 1 if the SCT verifies successfully; any other value indicates
+ * failure. See EVP_DigestVerifyFinal() for the meaning of those values.
+ */
+__owur int SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct);
+
+/*
+ * Does this SCT have the minimum fields populated to be usable?
+ * Returns 1 if so, 0 otherwise.
+ */
+__owur int SCT_is_complete(const SCT *sct);
+
+/*
+ * Does this SCT have the signature-related fields populated?
+ * Returns 1 if so, 0 otherwise.
+ * This checks that the signature and hash algorithms are set to supported
+ * values and that the signature field is set.
+ */
+__owur int SCT_signature_is_complete(const SCT *sct);
+
+/*
+ * TODO(RJPercival): Create an SCT_signature struct and make i2o_SCT_signature
+ * and o2i_SCT_signature conform to the i2d/d2i conventions.
+ */
+
+/*
+* Serialize (to TLS format) an |sct| signature and write it to |out|.
+* If |out| is null, no signature will be output but the length will be returned.
+* If |out| points to a null pointer, a string will be allocated to hold the
+* TLS-format signature. It is the responsibility of the caller to free it.
+* If |out| points to an allocated string, the signature will be written to it.
+* The length of the signature in TLS format will be returned.
+*/
+__owur int i2o_SCT_signature(const SCT *sct, unsigned char **out);
+
+/*
+* Parses an SCT signature in TLS format and populates the |sct| with it.
+* |in| should be a pointer to a string containing the TLS-format signature.
+* |in| will be advanced to the end of the signature if parsing succeeds.
+* |len| should be the length of the signature in |in|.
+* Returns the number of bytes parsed, or a negative integer if an error occurs.
+* If an error occurs, the SCT's signature NID may be updated whilst the
+* signature field itself remains unset.
+*/
+__owur int o2i_SCT_signature(SCT *sct, const unsigned char **in, size_t len);
+
+/*
+ * Handlers for Certificate Transparency X509v3/OCSP extensions
+ */
+extern const X509V3_EXT_METHOD v3_ct_scts[3];
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_log.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_log.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_log.c	(revision 331)
@@ -0,0 +1,304 @@
+/*
+ * 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 <stdlib.h>
+#include <string.h>
+
+#include <openssl/conf.h>
+#include <openssl/ct.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/safestack.h>
+
+#include "internal/cryptlib.h"
+
+/*
+ * Information about a CT log server.
+ */
+struct ctlog_st {
+    char *name;
+    uint8_t log_id[CT_V1_HASHLEN];
+    EVP_PKEY *public_key;
+};
+
+/*
+ * A store for multiple CTLOG instances.
+ * It takes ownership of any CTLOG instances added to it.
+ */
+struct ctlog_store_st {
+    STACK_OF(CTLOG) *logs;
+};
+
+/* The context when loading a CT log list from a CONF file. */
+typedef struct ctlog_store_load_ctx_st {
+    CTLOG_STORE *log_store;
+    CONF *conf;
+    size_t invalid_log_entries;
+} CTLOG_STORE_LOAD_CTX;
+
+/*
+ * Creates an empty context for loading a CT log store.
+ * It should be populated before use.
+ */
+static CTLOG_STORE_LOAD_CTX *ctlog_store_load_ctx_new();
+
+/*
+ * Deletes a CT log store load context.
+ * Does not delete any of the fields.
+ */
+static void ctlog_store_load_ctx_free(CTLOG_STORE_LOAD_CTX* ctx);
+
+static CTLOG_STORE_LOAD_CTX *ctlog_store_load_ctx_new()
+{
+    CTLOG_STORE_LOAD_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+    if (ctx == NULL)
+        CTerr(CT_F_CTLOG_STORE_LOAD_CTX_NEW, ERR_R_MALLOC_FAILURE);
+
+    return ctx;
+}
+
+static void ctlog_store_load_ctx_free(CTLOG_STORE_LOAD_CTX* ctx)
+{
+    OPENSSL_free(ctx);
+}
+
+/* Converts a log's public key into a SHA256 log ID */
+static int ct_v1_log_id_from_pkey(EVP_PKEY *pkey,
+                                  unsigned char log_id[CT_V1_HASHLEN])
+{
+    int ret = 0;
+    unsigned char *pkey_der = NULL;
+    int pkey_der_len = i2d_PUBKEY(pkey, &pkey_der);
+
+    if (pkey_der_len <= 0) {
+        CTerr(CT_F_CT_V1_LOG_ID_FROM_PKEY, CT_R_LOG_KEY_INVALID);
+        goto err;
+    }
+
+    SHA256(pkey_der, pkey_der_len, log_id);
+    ret = 1;
+err:
+    OPENSSL_free(pkey_der);
+    return ret;
+}
+
+CTLOG_STORE *CTLOG_STORE_new(void)
+{
+    CTLOG_STORE *ret = OPENSSL_zalloc(sizeof(*ret));
+
+    if (ret == NULL) {
+        CTerr(CT_F_CTLOG_STORE_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    ret->logs = sk_CTLOG_new_null();
+    if (ret->logs == NULL)
+        goto err;
+
+    return ret;
+err:
+    OPENSSL_free(ret);
+    return NULL;
+}
+
+void CTLOG_STORE_free(CTLOG_STORE *store)
+{
+    if (store != NULL) {
+        sk_CTLOG_pop_free(store->logs, CTLOG_free);
+        OPENSSL_free(store);
+    }
+}
+
+static int ctlog_new_from_conf(CTLOG **ct_log, const CONF *conf, const char *section)
+{
+    const char *description = NCONF_get_string(conf, section, "description");
+    char *pkey_base64;
+
+    if (description == NULL) {
+        CTerr(CT_F_CTLOG_NEW_FROM_CONF, CT_R_LOG_CONF_MISSING_DESCRIPTION);
+        return 0;
+    }
+
+    pkey_base64 = NCONF_get_string(conf, section, "key");
+    if (pkey_base64 == NULL) {
+        CTerr(CT_F_CTLOG_NEW_FROM_CONF, CT_R_LOG_CONF_MISSING_KEY);
+        return 0;
+    }
+
+    return CTLOG_new_from_base64(ct_log, pkey_base64, description);
+}
+
+int CTLOG_STORE_load_default_file(CTLOG_STORE *store)
+{
+    const char *fpath = getenv(CTLOG_FILE_EVP);
+
+    if (fpath == NULL)
+      fpath = CTLOG_FILE;
+
+    return CTLOG_STORE_load_file(store, fpath);
+}
+
+/*
+ * Called by CONF_parse_list, which stops if this returns <= 0,
+ * Otherwise, one bad log entry would stop loading of any of
+ * the following log entries.
+ * It may stop parsing and returns -1 on any internal (malloc) error.
+ */
+static int ctlog_store_load_log(const char *log_name, int log_name_len,
+                                void *arg)
+{
+    CTLOG_STORE_LOAD_CTX *load_ctx = arg;
+    CTLOG *ct_log = NULL;
+    /* log_name may not be null-terminated, so fix that before using it */
+    char *tmp;
+    int ret = 0;
+
+    /* log_name will be NULL for empty list entries */
+    if (log_name == NULL)
+        return 1;
+
+    tmp = OPENSSL_strndup(log_name, log_name_len);
+    if (tmp == NULL)
+        goto mem_err;
+
+    ret = ctlog_new_from_conf(&ct_log, load_ctx->conf, tmp);
+    OPENSSL_free(tmp);
+
+    if (ret < 0) {
+        /* Propagate any internal error */
+        return ret;
+    }
+    if (ret == 0) {
+        /* If we can't load this log, record that fact and skip it */
+        ++load_ctx->invalid_log_entries;
+        return 1;
+    }
+
+    if (!sk_CTLOG_push(load_ctx->log_store->logs, ct_log)) {
+        goto mem_err;
+    }
+    return 1;
+
+mem_err:
+    CTLOG_free(ct_log);
+    CTerr(CT_F_CTLOG_STORE_LOAD_LOG, ERR_R_MALLOC_FAILURE);
+    return -1;
+}
+
+int CTLOG_STORE_load_file(CTLOG_STORE *store, const char *file)
+{
+    int ret = 0;
+    char *enabled_logs;
+    CTLOG_STORE_LOAD_CTX* load_ctx = ctlog_store_load_ctx_new();
+
+    load_ctx->log_store = store;
+    load_ctx->conf = NCONF_new(NULL);
+    if (load_ctx->conf == NULL)
+        goto end;
+
+    if (NCONF_load(load_ctx->conf, file, NULL) <= 0) {
+        CTerr(CT_F_CTLOG_STORE_LOAD_FILE, CT_R_LOG_CONF_INVALID);
+        goto end;
+    }
+
+    enabled_logs = NCONF_get_string(load_ctx->conf, NULL, "enabled_logs");
+    if (enabled_logs == NULL) {
+        CTerr(CT_F_CTLOG_STORE_LOAD_FILE, CT_R_LOG_CONF_INVALID);
+        goto end;
+    }
+
+    if (!CONF_parse_list(enabled_logs, ',', 1, ctlog_store_load_log, load_ctx) ||
+        load_ctx->invalid_log_entries > 0) {
+        CTerr(CT_F_CTLOG_STORE_LOAD_FILE, CT_R_LOG_CONF_INVALID);
+        goto end;
+    }
+
+    ret = 1;
+end:
+    NCONF_free(load_ctx->conf);
+    ctlog_store_load_ctx_free(load_ctx);
+    return ret;
+}
+
+/*
+ * Initialize a new CTLOG object.
+ * Takes ownership of the public key.
+ * Copies the name.
+ */
+CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name)
+{
+    CTLOG *ret = OPENSSL_zalloc(sizeof(*ret));
+
+    if (ret == NULL) {
+        CTerr(CT_F_CTLOG_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    ret->name = OPENSSL_strdup(name);
+    if (ret->name == NULL) {
+        CTerr(CT_F_CTLOG_NEW, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (ct_v1_log_id_from_pkey(public_key, ret->log_id) != 1)
+        goto err;
+
+    ret->public_key = public_key;
+    return ret;
+err:
+    CTLOG_free(ret);
+    return NULL;
+}
+
+/* Frees CT log and associated structures */
+void CTLOG_free(CTLOG *log)
+{
+    if (log != NULL) {
+        OPENSSL_free(log->name);
+        EVP_PKEY_free(log->public_key);
+        OPENSSL_free(log);
+    }
+}
+
+const char *CTLOG_get0_name(const CTLOG *log)
+{
+    return log->name;
+}
+
+void CTLOG_get0_log_id(const CTLOG *log, const uint8_t **log_id,
+                       size_t *log_id_len)
+{
+    *log_id = log->log_id;
+    *log_id_len = CT_V1_HASHLEN;
+}
+
+EVP_PKEY *CTLOG_get0_public_key(const CTLOG *log)
+{
+    return log->public_key;
+}
+
+/*
+ * Given a log ID, finds the matching log.
+ * Returns NULL if no match found.
+ */
+const CTLOG *CTLOG_STORE_get0_log_by_id(const CTLOG_STORE *store,
+                                        const uint8_t *log_id,
+                                        size_t log_id_len)
+{
+    int i;
+
+    for (i = 0; i < sk_CTLOG_num(store->logs); ++i) {
+        const CTLOG *log = sk_CTLOG_value(store->logs, i);
+        if (memcmp(log->log_id, log_id, log_id_len) == 0)
+            return log;
+    }
+
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_oct.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_oct.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_oct.c	(revision 331)
@@ -0,0 +1,407 @@
+/*
+ * 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
+ */
+
+#ifdef OPENSSL_NO_CT
+# error "CT is disabled"
+#endif
+
+#include <limits.h>
+#include <string.h>
+
+#include <openssl/asn1.h>
+#include <openssl/buffer.h>
+#include <openssl/ct.h>
+#include <openssl/err.h>
+
+#include "ct_locl.h"
+
+int o2i_SCT_signature(SCT *sct, const unsigned char **in, size_t len)
+{
+    size_t siglen;
+    size_t len_remaining = len;
+    const unsigned char *p;
+
+    if (sct->version != SCT_VERSION_V1) {
+        CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_UNSUPPORTED_VERSION);
+        return -1;
+    }
+    /*
+     * digitally-signed struct header: (1 byte) Hash algorithm (1 byte)
+     * Signature algorithm (2 bytes + ?) Signature
+     *
+     * This explicitly rejects empty signatures: they're invalid for
+     * all supported algorithms.
+     */
+    if (len <= 4) {
+        CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE);
+        return -1;
+    }
+
+    p = *in;
+    /* Get hash and signature algorithm */
+    sct->hash_alg = *p++;
+    sct->sig_alg = *p++;
+    if (SCT_get_signature_nid(sct) == NID_undef) {
+        CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE);
+        return -1;
+    }
+    /* Retrieve signature and check it is consistent with the buffer length */
+    n2s(p, siglen);
+    len_remaining -= (p - *in);
+    if (siglen > len_remaining) {
+        CTerr(CT_F_O2I_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE);
+        return -1;
+    }
+
+    if (SCT_set1_signature(sct, p, siglen) != 1)
+        return -1;
+    len_remaining -= siglen;
+    *in = p + siglen;
+
+    return len - len_remaining;
+}
+
+SCT *o2i_SCT(SCT **psct, const unsigned char **in, size_t len)
+{
+    SCT *sct = NULL;
+    const unsigned char *p;
+
+    if (len == 0 || len > MAX_SCT_SIZE) {
+        CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID);
+        goto err;
+    }
+
+    if ((sct = SCT_new()) == NULL)
+        goto err;
+
+    p = *in;
+
+    sct->version = *p;
+    if (sct->version == SCT_VERSION_V1) {
+        int sig_len;
+        size_t len2;
+        /*-
+         * Fixed-length header:
+         *   struct {
+         *     Version sct_version;     (1 byte)
+         *     log_id id;               (32 bytes)
+         *     uint64 timestamp;        (8 bytes)
+         *     CtExtensions extensions; (2 bytes + ?)
+         *   }
+         */
+        if (len < 43) {
+            CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID);
+            goto err;
+        }
+        len -= 43;
+        p++;
+        sct->log_id = BUF_memdup(p, CT_V1_HASHLEN);
+        if (sct->log_id == NULL)
+            goto err;
+        sct->log_id_len = CT_V1_HASHLEN;
+        p += CT_V1_HASHLEN;
+
+        n2l8(p, sct->timestamp);
+
+        n2s(p, len2);
+        if (len < len2) {
+            CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID);
+            goto err;
+        }
+        if (len2 > 0) {
+            sct->ext = BUF_memdup(p, len2);
+            if (sct->ext == NULL)
+                goto err;
+        }
+        sct->ext_len = len2;
+        p += len2;
+        len -= len2;
+
+        sig_len = o2i_SCT_signature(sct, &p, len);
+        if (sig_len <= 0) {
+            CTerr(CT_F_O2I_SCT, CT_R_SCT_INVALID);
+            goto err;
+        }
+        len -= sig_len;
+        *in = p + len;
+    } else {
+        /* If not V1 just cache encoding */
+        sct->sct = BUF_memdup(p, len);
+        if (sct->sct == NULL)
+            goto err;
+        sct->sct_len = len;
+        *in = p + len;
+    }
+
+    if (psct != NULL) {
+        SCT_free(*psct);
+        *psct = sct;
+    }
+
+    return sct;
+err:
+    SCT_free(sct);
+    return NULL;
+}
+
+int i2o_SCT_signature(const SCT *sct, unsigned char **out)
+{
+    size_t len;
+    unsigned char *p = NULL, *pstart = NULL;
+
+    if (!SCT_signature_is_complete(sct)) {
+        CTerr(CT_F_I2O_SCT_SIGNATURE, CT_R_SCT_INVALID_SIGNATURE);
+        goto err;
+    }
+
+    if (sct->version != SCT_VERSION_V1) {
+        CTerr(CT_F_I2O_SCT_SIGNATURE, CT_R_UNSUPPORTED_VERSION);
+        goto err;
+    }
+
+    /*
+    * (1 byte) Hash algorithm
+    * (1 byte) Signature algorithm
+    * (2 bytes + ?) Signature
+    */
+    len = 4 + sct->sig_len;
+
+    if (out != NULL) {
+        if (*out != NULL) {
+            p = *out;
+            *out += len;
+        } else {
+            pstart = p = OPENSSL_malloc(len);
+            if (p == NULL) {
+                CTerr(CT_F_I2O_SCT_SIGNATURE, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            *out = p;
+        }
+
+        *p++ = sct->hash_alg;
+        *p++ = sct->sig_alg;
+        s2n(sct->sig_len, p);
+        memcpy(p, sct->sig, sct->sig_len);
+    }
+
+    return len;
+err:
+    OPENSSL_free(pstart);
+    return -1;
+}
+
+int i2o_SCT(const SCT *sct, unsigned char **out)
+{
+    size_t len;
+    unsigned char *p = NULL, *pstart = NULL;
+
+    if (!SCT_is_complete(sct)) {
+        CTerr(CT_F_I2O_SCT, CT_R_SCT_NOT_SET);
+        goto err;
+    }
+    /*
+     * Fixed-length header: struct { (1 byte) Version sct_version; (32 bytes)
+     * log_id id; (8 bytes) uint64 timestamp; (2 bytes + ?) CtExtensions
+     * extensions; (1 byte) Hash algorithm (1 byte) Signature algorithm (2
+     * bytes + ?) Signature
+     */
+    if (sct->version == SCT_VERSION_V1)
+        len = 43 + sct->ext_len + 4 + sct->sig_len;
+    else
+        len = sct->sct_len;
+
+    if (out == NULL)
+        return len;
+
+    if (*out != NULL) {
+        p = *out;
+        *out += len;
+    } else {
+        pstart = p = OPENSSL_malloc(len);
+        if (p == NULL) {
+            CTerr(CT_F_I2O_SCT, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        *out = p;
+    }
+
+    if (sct->version == SCT_VERSION_V1) {
+        *p++ = sct->version;
+        memcpy(p, sct->log_id, CT_V1_HASHLEN);
+        p += CT_V1_HASHLEN;
+        l2n8(sct->timestamp, p);
+        s2n(sct->ext_len, p);
+        if (sct->ext_len > 0) {
+            memcpy(p, sct->ext, sct->ext_len);
+            p += sct->ext_len;
+        }
+        if (i2o_SCT_signature(sct, &p) <= 0)
+            goto err;
+    } else {
+        memcpy(p, sct->sct, len);
+    }
+
+    return len;
+err:
+    OPENSSL_free(pstart);
+    return -1;
+}
+
+STACK_OF(SCT) *o2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp,
+                            size_t len)
+{
+    STACK_OF(SCT) *sk = NULL;
+    size_t list_len, sct_len;
+
+    if (len < 2 || len > MAX_SCT_LIST_SIZE) {
+        CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID);
+        return NULL;
+    }
+
+    n2s(*pp, list_len);
+    if (list_len != len - 2) {
+        CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID);
+        return NULL;
+    }
+
+    if (a == NULL || *a == NULL) {
+        sk = sk_SCT_new_null();
+        if (sk == NULL)
+            return NULL;
+    } else {
+        SCT *sct;
+
+        /* Use the given stack, but empty it first. */
+        sk = *a;
+        while ((sct = sk_SCT_pop(sk)) != NULL)
+            SCT_free(sct);
+    }
+
+    while (list_len > 0) {
+        SCT *sct;
+
+        if (list_len < 2) {
+            CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID);
+            goto err;
+        }
+        n2s(*pp, sct_len);
+        list_len -= 2;
+
+        if (sct_len == 0 || sct_len > list_len) {
+            CTerr(CT_F_O2I_SCT_LIST, CT_R_SCT_LIST_INVALID);
+            goto err;
+        }
+        list_len -= sct_len;
+
+        if ((sct = o2i_SCT(NULL, pp, sct_len)) == NULL)
+            goto err;
+        if (!sk_SCT_push(sk, sct)) {
+            SCT_free(sct);
+            goto err;
+        }
+    }
+
+    if (a != NULL && *a == NULL)
+        *a = sk;
+    return sk;
+
+ err:
+    if (a == NULL || *a == NULL)
+        SCT_LIST_free(sk);
+    return NULL;
+}
+
+int i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp)
+{
+    int len, sct_len, i, is_pp_new = 0;
+    size_t len2;
+    unsigned char *p = NULL, *p2;
+
+    if (pp != NULL) {
+        if (*pp == NULL) {
+            if ((len = i2o_SCT_LIST(a, NULL)) == -1) {
+                CTerr(CT_F_I2O_SCT_LIST, CT_R_SCT_LIST_INVALID);
+                return -1;
+            }
+            if ((*pp = OPENSSL_malloc(len)) == NULL) {
+                CTerr(CT_F_I2O_SCT_LIST, ERR_R_MALLOC_FAILURE);
+                return -1;
+            }
+            is_pp_new = 1;
+        }
+        p = *pp + 2;
+    }
+
+    len2 = 2;
+    for (i = 0; i < sk_SCT_num(a); i++) {
+        if (pp != NULL) {
+            p2 = p;
+            p += 2;
+            if ((sct_len = i2o_SCT(sk_SCT_value(a, i), &p)) == -1)
+                goto err;
+            s2n(sct_len, p2);
+        } else {
+          if ((sct_len = i2o_SCT(sk_SCT_value(a, i), NULL)) == -1)
+              goto err;
+        }
+        len2 += 2 + sct_len;
+    }
+
+    if (len2 > MAX_SCT_LIST_SIZE)
+        goto err;
+
+    if (pp != NULL) {
+        p = *pp;
+        s2n(len2 - 2, p);
+        if (!is_pp_new)
+            *pp += len2;
+    }
+    return len2;
+
+ err:
+    if (is_pp_new) {
+        OPENSSL_free(*pp);
+        *pp = NULL;
+    }
+    return -1;
+}
+
+STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp,
+                            long len)
+{
+    ASN1_OCTET_STRING *oct = NULL;
+    STACK_OF(SCT) *sk = NULL;
+    const unsigned char *p;
+
+    p = *pp;
+    if (d2i_ASN1_OCTET_STRING(&oct, &p, len) == NULL)
+        return NULL;
+
+    p = oct->data;
+    if ((sk = o2i_SCT_LIST(a, &p, oct->length)) != NULL)
+        *pp += len;
+
+    ASN1_OCTET_STRING_free(oct);
+    return sk;
+}
+
+int i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **out)
+{
+    ASN1_OCTET_STRING oct;
+    int len;
+
+    oct.data = NULL;
+    if ((oct.length = i2o_SCT_LIST(a, &oct.data)) == -1)
+        return -1;
+
+    len = i2d_ASN1_OCTET_STRING(&oct, out);
+    OPENSSL_free(oct.data);
+    return len;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_policy.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_policy.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_policy.c	(revision 331)
@@ -0,0 +1,98 @@
+/*
+ * 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
+ */
+
+#ifdef OPENSSL_NO_CT
+# error "CT is disabled"
+#endif
+
+#include <openssl/ct.h>
+#include <openssl/err.h>
+#include <time.h>
+
+#include "ct_locl.h"
+
+/*
+ * Number of seconds in the future that an SCT timestamp can be, by default,
+ * without being considered invalid. This is added to time() when setting a
+ * default value for CT_POLICY_EVAL_CTX.epoch_time_in_ms.
+ * It can be overridden by calling CT_POLICY_EVAL_CTX_set_time().
+ */
+static const time_t SCT_CLOCK_DRIFT_TOLERANCE = 300;
+
+CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void)
+{
+    CT_POLICY_EVAL_CTX *ctx = OPENSSL_zalloc(sizeof(CT_POLICY_EVAL_CTX));
+
+    if (ctx == NULL) {
+        CTerr(CT_F_CT_POLICY_EVAL_CTX_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    /* time(NULL) shouldn't ever fail, so don't bother checking for -1. */
+    ctx->epoch_time_in_ms = (uint64_t)(time(NULL) + SCT_CLOCK_DRIFT_TOLERANCE) *
+            1000;
+
+    return ctx;
+}
+
+void CT_POLICY_EVAL_CTX_free(CT_POLICY_EVAL_CTX *ctx)
+{
+    if (ctx == NULL)
+        return;
+    X509_free(ctx->cert);
+    X509_free(ctx->issuer);
+    OPENSSL_free(ctx);
+}
+
+int CT_POLICY_EVAL_CTX_set1_cert(CT_POLICY_EVAL_CTX *ctx, X509 *cert)
+{
+    if (!X509_up_ref(cert))
+        return 0;
+    ctx->cert = cert;
+    return 1;
+}
+
+int CT_POLICY_EVAL_CTX_set1_issuer(CT_POLICY_EVAL_CTX *ctx, X509 *issuer)
+{
+    if (!X509_up_ref(issuer))
+        return 0;
+    ctx->issuer = issuer;
+    return 1;
+}
+
+void CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(CT_POLICY_EVAL_CTX *ctx,
+                                               CTLOG_STORE *log_store)
+{
+    ctx->log_store = log_store;
+}
+
+void CT_POLICY_EVAL_CTX_set_time(CT_POLICY_EVAL_CTX *ctx, uint64_t time_in_ms)
+{
+    ctx->epoch_time_in_ms = time_in_ms;
+}
+
+X509* CT_POLICY_EVAL_CTX_get0_cert(const CT_POLICY_EVAL_CTX *ctx)
+{
+    return ctx->cert;
+}
+
+X509* CT_POLICY_EVAL_CTX_get0_issuer(const CT_POLICY_EVAL_CTX *ctx)
+{
+    return ctx->issuer;
+}
+
+const CTLOG_STORE *CT_POLICY_EVAL_CTX_get0_log_store(const CT_POLICY_EVAL_CTX *ctx)
+{
+    return ctx->log_store;
+}
+
+uint64_t CT_POLICY_EVAL_CTX_get_time(const CT_POLICY_EVAL_CTX *ctx)
+{
+    return ctx->epoch_time_in_ms;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_prn.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_prn.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_prn.c	(revision 331)
@@ -0,0 +1,127 @@
+/*
+ * 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
+ */
+
+#ifdef OPENSSL_NO_CT
+# error "CT is disabled"
+#endif
+
+#include <openssl/asn1.h>
+#include <openssl/bio.h>
+
+#include "ct_locl.h"
+
+static void SCT_signature_algorithms_print(const SCT *sct, BIO *out)
+{
+    int nid = SCT_get_signature_nid(sct);
+
+    if (nid == NID_undef)
+        BIO_printf(out, "%02X%02X", sct->hash_alg, sct->sig_alg);
+    else
+        BIO_printf(out, "%s", OBJ_nid2ln(nid));
+}
+
+static void timestamp_print(uint64_t timestamp, BIO *out)
+{
+    ASN1_GENERALIZEDTIME *gen = ASN1_GENERALIZEDTIME_new();
+    char genstr[20];
+
+    if (gen == NULL)
+        return;
+    ASN1_GENERALIZEDTIME_adj(gen, (time_t)0,
+                             (int)(timestamp / 86400000),
+                             (timestamp % 86400000) / 1000);
+    /*
+     * Note GeneralizedTime from ASN1_GENERALIZETIME_adj is always 15
+     * characters long with a final Z. Update it with fractional seconds.
+     */
+    BIO_snprintf(genstr, sizeof(genstr), "%.14s.%03dZ",
+                 ASN1_STRING_get0_data(gen), (unsigned int)(timestamp % 1000));
+    if (ASN1_GENERALIZEDTIME_set_string(gen, genstr))
+        ASN1_GENERALIZEDTIME_print(out, gen);
+    ASN1_GENERALIZEDTIME_free(gen);
+}
+
+const char *SCT_validation_status_string(const SCT *sct)
+{
+
+    switch (SCT_get_validation_status(sct)) {
+    case SCT_VALIDATION_STATUS_NOT_SET:
+        return "not set";
+    case SCT_VALIDATION_STATUS_UNKNOWN_VERSION:
+        return "unknown version";
+    case SCT_VALIDATION_STATUS_UNKNOWN_LOG:
+        return "unknown log";
+    case SCT_VALIDATION_STATUS_UNVERIFIED:
+        return "unverified";
+    case SCT_VALIDATION_STATUS_INVALID:
+        return "invalid";
+    case SCT_VALIDATION_STATUS_VALID:
+        return "valid";
+    }
+    return "unknown status";
+}
+
+void SCT_print(const SCT *sct, BIO *out, int indent,
+               const CTLOG_STORE *log_store)
+{
+    const CTLOG *log = NULL;
+
+    if (log_store != NULL) {
+        log = CTLOG_STORE_get0_log_by_id(log_store, sct->log_id,
+                                         sct->log_id_len);
+    }
+
+    BIO_printf(out, "%*sSigned Certificate Timestamp:", indent, "");
+    BIO_printf(out, "\n%*sVersion   : ", indent + 4, "");
+
+    if (sct->version != SCT_VERSION_V1) {
+        BIO_printf(out, "unknown\n%*s", indent + 16, "");
+        BIO_hex_string(out, indent + 16, 16, sct->sct, sct->sct_len);
+        return;
+    }
+
+    BIO_printf(out, "v1 (0x0)");
+
+    if (log != NULL) {
+        BIO_printf(out, "\n%*sLog       : %s", indent + 4, "",
+                   CTLOG_get0_name(log));
+    }
+
+    BIO_printf(out, "\n%*sLog ID    : ", indent + 4, "");
+    BIO_hex_string(out, indent + 16, 16, sct->log_id, sct->log_id_len);
+
+    BIO_printf(out, "\n%*sTimestamp : ", indent + 4, "");
+    timestamp_print(sct->timestamp, out);
+
+    BIO_printf(out, "\n%*sExtensions: ", indent + 4, "");
+    if (sct->ext_len == 0)
+        BIO_printf(out, "none");
+    else
+        BIO_hex_string(out, indent + 16, 16, sct->ext, sct->ext_len);
+
+    BIO_printf(out, "\n%*sSignature : ", indent + 4, "");
+    SCT_signature_algorithms_print(sct, out);
+    BIO_printf(out, "\n%*s            ", indent + 4, "");
+    BIO_hex_string(out, indent + 16, 16, sct->sig, sct->sig_len);
+}
+
+void SCT_LIST_print(const STACK_OF(SCT) *sct_list, BIO *out, int indent,
+                    const char *separator, const CTLOG_STORE *log_store)
+{
+    int sct_count = sk_SCT_num(sct_list);
+    int i;
+
+    for (i = 0; i < sct_count; ++i) {
+        SCT *sct = sk_SCT_value(sct_list, i);
+
+        SCT_print(sct, out, indent, log_store);
+        if (i < sk_SCT_num(sct_list) - 1)
+            BIO_printf(out, "%s", separator);
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_sct.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_sct.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_sct.c	(revision 331)
@@ -0,0 +1,393 @@
+/*
+ * 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
+ */
+
+#ifdef OPENSSL_NO_CT
+# error "CT disabled"
+#endif
+
+#include <openssl/ct.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/tls1.h>
+#include <openssl/x509.h>
+
+#include "ct_locl.h"
+
+SCT *SCT_new(void)
+{
+    SCT *sct = OPENSSL_zalloc(sizeof(*sct));
+
+    if (sct == NULL) {
+        CTerr(CT_F_SCT_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    sct->entry_type = CT_LOG_ENTRY_TYPE_NOT_SET;
+    sct->version = SCT_VERSION_NOT_SET;
+    return sct;
+}
+
+void SCT_free(SCT *sct)
+{
+    if (sct == NULL)
+        return;
+
+    OPENSSL_free(sct->log_id);
+    OPENSSL_free(sct->ext);
+    OPENSSL_free(sct->sig);
+    OPENSSL_free(sct->sct);
+    OPENSSL_free(sct);
+}
+
+void SCT_LIST_free(STACK_OF(SCT) *a)
+{
+    sk_SCT_pop_free(a, SCT_free);
+}
+
+int SCT_set_version(SCT *sct, sct_version_t version)
+{
+    if (version != SCT_VERSION_V1) {
+        CTerr(CT_F_SCT_SET_VERSION, CT_R_UNSUPPORTED_VERSION);
+        return 0;
+    }
+    sct->version = version;
+    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+    return 1;
+}
+
+int SCT_set_log_entry_type(SCT *sct, ct_log_entry_type_t entry_type)
+{
+    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+
+    switch (entry_type) {
+    case CT_LOG_ENTRY_TYPE_X509:
+    case CT_LOG_ENTRY_TYPE_PRECERT:
+        sct->entry_type = entry_type;
+        return 1;
+    default:
+        CTerr(CT_F_SCT_SET_LOG_ENTRY_TYPE, CT_R_UNSUPPORTED_ENTRY_TYPE);
+        return 0;
+    }
+}
+
+int SCT_set0_log_id(SCT *sct, unsigned char *log_id, size_t log_id_len)
+{
+    if (sct->version == SCT_VERSION_V1 && log_id_len != CT_V1_HASHLEN) {
+        CTerr(CT_F_SCT_SET0_LOG_ID, CT_R_INVALID_LOG_ID_LENGTH);
+        return 0;
+    }
+
+    OPENSSL_free(sct->log_id);
+    sct->log_id = log_id;
+    sct->log_id_len = log_id_len;
+    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+    return 1;
+}
+
+int SCT_set1_log_id(SCT *sct, const unsigned char *log_id, size_t log_id_len)
+{
+    if (sct->version == SCT_VERSION_V1 && log_id_len != CT_V1_HASHLEN) {
+        CTerr(CT_F_SCT_SET1_LOG_ID, CT_R_INVALID_LOG_ID_LENGTH);
+        return 0;
+    }
+
+    OPENSSL_free(sct->log_id);
+    sct->log_id = NULL;
+    sct->log_id_len = 0;
+    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+
+    if (log_id != NULL && log_id_len > 0) {
+        sct->log_id = OPENSSL_memdup(log_id, log_id_len);
+        if (sct->log_id == NULL) {
+            CTerr(CT_F_SCT_SET1_LOG_ID, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        sct->log_id_len = log_id_len;
+    }
+    return 1;
+}
+
+
+void SCT_set_timestamp(SCT *sct, uint64_t timestamp)
+{
+    sct->timestamp = timestamp;
+    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+}
+
+int SCT_set_signature_nid(SCT *sct, int nid)
+{
+    switch (nid) {
+    case NID_sha256WithRSAEncryption:
+        sct->hash_alg = TLSEXT_hash_sha256;
+        sct->sig_alg = TLSEXT_signature_rsa;
+        sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+        return 1;
+    case NID_ecdsa_with_SHA256:
+        sct->hash_alg = TLSEXT_hash_sha256;
+        sct->sig_alg = TLSEXT_signature_ecdsa;
+        sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+        return 1;
+    default:
+        CTerr(CT_F_SCT_SET_SIGNATURE_NID, CT_R_UNRECOGNIZED_SIGNATURE_NID);
+        return 0;
+    }
+}
+
+void SCT_set0_extensions(SCT *sct, unsigned char *ext, size_t ext_len)
+{
+    OPENSSL_free(sct->ext);
+    sct->ext = ext;
+    sct->ext_len = ext_len;
+    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+}
+
+int SCT_set1_extensions(SCT *sct, const unsigned char *ext, size_t ext_len)
+{
+    OPENSSL_free(sct->ext);
+    sct->ext = NULL;
+    sct->ext_len = 0;
+    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+
+    if (ext != NULL && ext_len > 0) {
+        sct->ext = OPENSSL_memdup(ext, ext_len);
+        if (sct->ext == NULL) {
+            CTerr(CT_F_SCT_SET1_EXTENSIONS, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        sct->ext_len = ext_len;
+    }
+    return 1;
+}
+
+void SCT_set0_signature(SCT *sct, unsigned char *sig, size_t sig_len)
+{
+    OPENSSL_free(sct->sig);
+    sct->sig = sig;
+    sct->sig_len = sig_len;
+    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+}
+
+int SCT_set1_signature(SCT *sct, const unsigned char *sig, size_t sig_len)
+{
+    OPENSSL_free(sct->sig);
+    sct->sig = NULL;
+    sct->sig_len = 0;
+    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+
+    if (sig != NULL && sig_len > 0) {
+        sct->sig = OPENSSL_memdup(sig, sig_len);
+        if (sct->sig == NULL) {
+            CTerr(CT_F_SCT_SET1_SIGNATURE, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        sct->sig_len = sig_len;
+    }
+    return 1;
+}
+
+sct_version_t SCT_get_version(const SCT *sct)
+{
+    return sct->version;
+}
+
+ct_log_entry_type_t SCT_get_log_entry_type(const SCT *sct)
+{
+    return sct->entry_type;
+}
+
+size_t SCT_get0_log_id(const SCT *sct, unsigned char **log_id)
+{
+    *log_id = sct->log_id;
+    return sct->log_id_len;
+}
+
+uint64_t SCT_get_timestamp(const SCT *sct)
+{
+    return sct->timestamp;
+}
+
+int SCT_get_signature_nid(const SCT *sct)
+{
+    if (sct->version == SCT_VERSION_V1) {
+        if (sct->hash_alg == TLSEXT_hash_sha256) {
+            switch (sct->sig_alg) {
+            case TLSEXT_signature_ecdsa:
+                return NID_ecdsa_with_SHA256;
+            case TLSEXT_signature_rsa:
+                return NID_sha256WithRSAEncryption;
+            default:
+                return NID_undef;
+            }
+        }
+    }
+    return NID_undef;
+}
+
+size_t SCT_get0_extensions(const SCT *sct, unsigned char **ext)
+{
+    *ext = sct->ext;
+    return sct->ext_len;
+}
+
+size_t SCT_get0_signature(const SCT *sct, unsigned char **sig)
+{
+    *sig = sct->sig;
+    return sct->sig_len;
+}
+
+int SCT_is_complete(const SCT *sct)
+{
+    switch (sct->version) {
+    case SCT_VERSION_NOT_SET:
+        return 0;
+    case SCT_VERSION_V1:
+        return sct->log_id != NULL && SCT_signature_is_complete(sct);
+    default:
+        return sct->sct != NULL; /* Just need cached encoding */
+    }
+}
+
+int SCT_signature_is_complete(const SCT *sct)
+{
+    return SCT_get_signature_nid(sct) != NID_undef &&
+        sct->sig != NULL && sct->sig_len > 0;
+}
+
+sct_source_t SCT_get_source(const SCT *sct)
+{
+    return sct->source;
+}
+
+int SCT_set_source(SCT *sct, sct_source_t source)
+{
+    sct->source = source;
+    sct->validation_status = SCT_VALIDATION_STATUS_NOT_SET;
+    switch (source) {
+    case SCT_SOURCE_TLS_EXTENSION:
+    case SCT_SOURCE_OCSP_STAPLED_RESPONSE:
+        return SCT_set_log_entry_type(sct, CT_LOG_ENTRY_TYPE_X509);
+    case SCT_SOURCE_X509V3_EXTENSION:
+        return SCT_set_log_entry_type(sct, CT_LOG_ENTRY_TYPE_PRECERT);
+    default: /* if we aren't sure, leave the log entry type alone */
+        return 1;
+    }
+}
+
+sct_validation_status_t SCT_get_validation_status(const SCT *sct)
+{
+    return sct->validation_status;
+}
+
+int SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx)
+{
+    int is_sct_valid = -1;
+    SCT_CTX *sctx = NULL;
+    X509_PUBKEY *pub = NULL, *log_pkey = NULL;
+    const CTLOG *log;
+
+    /*
+     * With an unrecognized SCT version we don't know what such an SCT means,
+     * let alone validate one.  So we return validation failure (0).
+     */
+    if (sct->version != SCT_VERSION_V1) {
+        sct->validation_status = SCT_VALIDATION_STATUS_UNKNOWN_VERSION;
+        return 0;
+    }
+
+    log = CTLOG_STORE_get0_log_by_id(ctx->log_store,
+                                     sct->log_id, sct->log_id_len);
+
+    /* Similarly, an SCT from an unknown log also cannot be validated. */
+    if (log == NULL) {
+        sct->validation_status = SCT_VALIDATION_STATUS_UNKNOWN_LOG;
+        return 0;
+    }
+
+    sctx = SCT_CTX_new();
+    if (sctx == NULL)
+        goto err;
+
+    if (X509_PUBKEY_set(&log_pkey, CTLOG_get0_public_key(log)) != 1)
+        goto err;
+    if (SCT_CTX_set1_pubkey(sctx, log_pkey) != 1)
+        goto err;
+
+    if (SCT_get_log_entry_type(sct) == CT_LOG_ENTRY_TYPE_PRECERT) {
+        EVP_PKEY *issuer_pkey;
+
+        if (ctx->issuer == NULL) {
+            sct->validation_status = SCT_VALIDATION_STATUS_UNVERIFIED;
+            goto end;
+        }
+
+        issuer_pkey = X509_get0_pubkey(ctx->issuer);
+
+        if (X509_PUBKEY_set(&pub, issuer_pkey) != 1)
+            goto err;
+        if (SCT_CTX_set1_issuer_pubkey(sctx, pub) != 1)
+            goto err;
+    }
+
+    SCT_CTX_set_time(sctx, ctx->epoch_time_in_ms);
+
+    /*
+     * XXX: Potential for optimization.  This repeats some idempotent heavy
+     * lifting on the certificate for each candidate SCT, and appears to not
+     * use any information in the SCT itself, only the certificate is
+     * processed.  So it may make more sense to to do this just once, perhaps
+     * associated with the shared (by all SCTs) policy eval ctx.
+     *
+     * XXX: Failure here is global (SCT independent) and represents either an
+     * issue with the certificate (e.g. duplicate extensions) or an out of
+     * memory condition.  When the certificate is incompatible with CT, we just
+     * mark the SCTs invalid, rather than report a failure to determine the
+     * validation status.  That way, callbacks that want to do "soft" SCT
+     * processing will not abort handshakes with false positive internal
+     * errors.  Since the function does not distinguish between certificate
+     * issues (peer's fault) and internal problems (out fault) the safe thing
+     * to do is to report a validation failure and let the callback or
+     * application decide what to do.
+     */
+    if (SCT_CTX_set1_cert(sctx, ctx->cert, NULL) != 1)
+        sct->validation_status = SCT_VALIDATION_STATUS_UNVERIFIED;
+    else
+        sct->validation_status = SCT_CTX_verify(sctx, sct) == 1 ?
+            SCT_VALIDATION_STATUS_VALID : SCT_VALIDATION_STATUS_INVALID;
+
+end:
+    is_sct_valid = sct->validation_status == SCT_VALIDATION_STATUS_VALID;
+err:
+    X509_PUBKEY_free(pub);
+    X509_PUBKEY_free(log_pkey);
+    SCT_CTX_free(sctx);
+
+    return is_sct_valid;
+}
+
+int SCT_LIST_validate(const STACK_OF(SCT) *scts, CT_POLICY_EVAL_CTX *ctx)
+{
+    int are_scts_valid = 1;
+    int sct_count = scts != NULL ? sk_SCT_num(scts) : 0;
+    int i;
+
+    for (i = 0; i < sct_count; ++i) {
+        int is_sct_valid = -1;
+        SCT *sct = sk_SCT_value(scts, i);
+
+        if (sct == NULL)
+            continue;
+
+        is_sct_valid = SCT_validate(sct, ctx);
+        if (is_sct_valid < 0)
+            return is_sct_valid;
+        are_scts_valid &= is_sct_valid;
+    }
+
+    return are_scts_valid;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_sct_ctx.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_sct_ctx.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_sct_ctx.c	(revision 331)
@@ -0,0 +1,263 @@
+/*
+ * 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
+ */
+
+#ifdef OPENSSL_NO_CT
+# error "CT is disabled"
+#endif
+
+#include <stddef.h>
+#include <string.h>
+
+#include <openssl/err.h>
+#include <openssl/obj_mac.h>
+#include <openssl/x509.h>
+
+#include "ct_locl.h"
+
+SCT_CTX *SCT_CTX_new(void)
+{
+    SCT_CTX *sctx = OPENSSL_zalloc(sizeof(*sctx));
+
+    if (sctx == NULL)
+        CTerr(CT_F_SCT_CTX_NEW, ERR_R_MALLOC_FAILURE);
+
+    return sctx;
+}
+
+void SCT_CTX_free(SCT_CTX *sctx)
+{
+    if (sctx == NULL)
+        return;
+    EVP_PKEY_free(sctx->pkey);
+    OPENSSL_free(sctx->pkeyhash);
+    OPENSSL_free(sctx->ihash);
+    OPENSSL_free(sctx->certder);
+    OPENSSL_free(sctx->preder);
+    OPENSSL_free(sctx);
+}
+
+/*
+ * Finds the index of the first extension with the given NID in cert.
+ * If there is more than one extension with that NID, *is_duplicated is set to
+ * 1, otherwise 0 (unless it is NULL).
+ */
+static int ct_x509_get_ext(X509 *cert, int nid, int *is_duplicated)
+{
+    int ret = X509_get_ext_by_NID(cert, nid, -1);
+
+    if (is_duplicated != NULL)
+        *is_duplicated = ret >= 0 && X509_get_ext_by_NID(cert, nid, ret) >= 0;
+
+    return ret;
+}
+
+/*
+ * Modifies a certificate by deleting extensions and copying the issuer and
+ * AKID from the presigner certificate, if necessary.
+ * Returns 1 on success, 0 otherwise.
+ */
+__owur static int ct_x509_cert_fixup(X509 *cert, X509 *presigner)
+{
+    int preidx, certidx;
+    int pre_akid_ext_is_dup, cert_akid_ext_is_dup;
+
+    if (presigner == NULL)
+        return 1;
+
+    preidx = ct_x509_get_ext(presigner, NID_authority_key_identifier,
+                             &pre_akid_ext_is_dup);
+    certidx = ct_x509_get_ext(cert, NID_authority_key_identifier,
+                              &cert_akid_ext_is_dup);
+
+    /* An error occurred whilst searching for the extension */
+    if (preidx < -1 || certidx < -1)
+        return 0;
+    /* Invalid certificate if they contain duplicate extensions */
+    if (pre_akid_ext_is_dup || cert_akid_ext_is_dup)
+        return 0;
+    /* AKID must be present in both certificate or absent in both */
+    if (preidx >= 0 && certidx == -1)
+        return 0;
+    if (preidx == -1 && certidx >= 0)
+        return 0;
+    /* Copy issuer name */
+    if (!X509_set_issuer_name(cert, X509_get_issuer_name(presigner)))
+        return 0;
+    if (preidx != -1) {
+        /* Retrieve and copy AKID encoding */
+        X509_EXTENSION *preext = X509_get_ext(presigner, preidx);
+        X509_EXTENSION *certext = X509_get_ext(cert, certidx);
+        ASN1_OCTET_STRING *preextdata;
+
+        /* Should never happen */
+        if (preext == NULL || certext == NULL)
+            return 0;
+        preextdata = X509_EXTENSION_get_data(preext);
+        if (preextdata == NULL ||
+            !X509_EXTENSION_set_data(certext, preextdata))
+            return 0;
+    }
+    return 1;
+}
+
+int SCT_CTX_set1_cert(SCT_CTX *sctx, X509 *cert, X509 *presigner)
+{
+    unsigned char *certder = NULL, *preder = NULL;
+    X509 *pretmp = NULL;
+    int certderlen = 0, prederlen = 0;
+    int idx = -1;
+    int poison_ext_is_dup, sct_ext_is_dup;
+    int poison_idx = ct_x509_get_ext(cert, NID_ct_precert_poison, &poison_ext_is_dup);
+
+    /* Duplicate poison extensions are present - error */
+    if (poison_ext_is_dup)
+        goto err;
+
+    /* If *cert doesn't have a poison extension, it isn't a precert */
+    if (poison_idx == -1) {
+        /* cert isn't a precert, so we shouldn't have a presigner */
+        if (presigner != NULL)
+            goto err;
+
+        certderlen = i2d_X509(cert, &certder);
+        if (certderlen < 0)
+            goto err;
+    }
+
+    /* See if cert has a precert SCTs extension */
+    idx = ct_x509_get_ext(cert, NID_ct_precert_scts, &sct_ext_is_dup);
+    /* Duplicate SCT extensions are present - error */
+    if (sct_ext_is_dup)
+        goto err;
+
+    if (idx >= 0 && poison_idx >= 0) {
+        /*
+         * cert can't both contain SCTs (i.e. have an SCT extension) and be a
+         * precert (i.e. have a poison extension).
+         */
+        goto err;
+    }
+
+    if (idx == -1) {
+        idx = poison_idx;
+    }
+
+    /*
+     * If either a poison or SCT extension is present, remove it before encoding
+     * cert. This, along with ct_x509_cert_fixup(), gets a TBSCertificate (see
+     * RFC5280) from cert, which is what the CT log signed when it produced the
+     * SCT.
+     */
+    if (idx >= 0) {
+        X509_EXTENSION *ext;
+
+        /* Take a copy of certificate so we don't modify passed version */
+        pretmp = X509_dup(cert);
+        if (pretmp == NULL)
+            goto err;
+
+        ext = X509_delete_ext(pretmp, idx);
+        X509_EXTENSION_free(ext);
+
+        if (!ct_x509_cert_fixup(pretmp, presigner))
+            goto err;
+
+        prederlen = i2d_re_X509_tbs(pretmp, &preder);
+        if (prederlen <= 0)
+            goto err;
+    }
+
+    X509_free(pretmp);
+
+    OPENSSL_free(sctx->certder);
+    sctx->certder = certder;
+    sctx->certderlen = certderlen;
+
+    OPENSSL_free(sctx->preder);
+    sctx->preder = preder;
+    sctx->prederlen = prederlen;
+
+    return 1;
+err:
+    OPENSSL_free(certder);
+    OPENSSL_free(preder);
+    X509_free(pretmp);
+    return 0;
+}
+
+__owur static int ct_public_key_hash(X509_PUBKEY *pkey, unsigned char **hash,
+                                     size_t *hash_len)
+{
+    int ret = 0;
+    unsigned char *md = NULL, *der = NULL;
+    int der_len;
+    unsigned int md_len;
+
+    /* Reuse buffer if possible */
+    if (*hash != NULL && *hash_len >= SHA256_DIGEST_LENGTH) {
+        md = *hash;
+    } else {
+        md = OPENSSL_malloc(SHA256_DIGEST_LENGTH);
+        if (md == NULL)
+            goto err;
+    }
+
+    /* Calculate key hash */
+    der_len = i2d_X509_PUBKEY(pkey, &der);
+    if (der_len <= 0)
+        goto err;
+
+    if (!EVP_Digest(der, der_len, md, &md_len, EVP_sha256(), NULL))
+        goto err;
+
+    if (md != *hash) {
+        OPENSSL_free(*hash);
+        *hash = md;
+        *hash_len = SHA256_DIGEST_LENGTH;
+    }
+
+    md = NULL;
+    ret = 1;
+ err:
+    OPENSSL_free(md);
+    OPENSSL_free(der);
+    return ret;
+}
+
+int SCT_CTX_set1_issuer(SCT_CTX *sctx, const X509 *issuer)
+{
+    return SCT_CTX_set1_issuer_pubkey(sctx, X509_get_X509_PUBKEY(issuer));
+}
+
+int SCT_CTX_set1_issuer_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey)
+{
+    return ct_public_key_hash(pubkey, &sctx->ihash, &sctx->ihashlen);
+}
+
+int SCT_CTX_set1_pubkey(SCT_CTX *sctx, X509_PUBKEY *pubkey)
+{
+    EVP_PKEY *pkey = X509_PUBKEY_get(pubkey);
+
+    if (pkey == NULL)
+        return 0;
+
+    if (!ct_public_key_hash(pubkey, &sctx->pkeyhash, &sctx->pkeyhashlen)) {
+        EVP_PKEY_free(pkey);
+        return 0;
+    }
+
+    EVP_PKEY_free(sctx->pkey);
+    sctx->pkey = pkey;
+    return 1;
+}
+
+void SCT_CTX_set_time(SCT_CTX *sctx, uint64_t time_in_ms)
+{
+    sctx->epoch_time_in_ms = time_in_ms;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_vfy.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_vfy.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_vfy.c	(revision 331)
@@ -0,0 +1,140 @@
+/*
+ * 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 <string.h>
+
+#include <openssl/ct.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+#include "ct_locl.h"
+
+typedef enum sct_signature_type_t {
+    SIGNATURE_TYPE_NOT_SET = -1,
+    SIGNATURE_TYPE_CERT_TIMESTAMP,
+    SIGNATURE_TYPE_TREE_HASH
+} SCT_SIGNATURE_TYPE;
+
+/*
+ * Update encoding for SCT signature verification/generation to supplied
+ * EVP_MD_CTX.
+ */
+static int sct_ctx_update(EVP_MD_CTX *ctx, const SCT_CTX *sctx, const SCT *sct)
+{
+    unsigned char tmpbuf[12];
+    unsigned char *p, *der;
+    size_t derlen;
+    /*+
+     * digitally-signed struct {
+     *   (1 byte) Version sct_version;
+     *   (1 byte) SignatureType signature_type = certificate_timestamp;
+     *   (8 bytes) uint64 timestamp;
+     *   (2 bytes) LogEntryType entry_type;
+     *   (? bytes) select(entry_type) {
+     *     case x509_entry: ASN.1Cert;
+     *     case precert_entry: PreCert;
+     *   } signed_entry;
+     *   (2 bytes + sct->ext_len) CtExtensions extensions;
+     * }
+     */
+    if (sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET)
+        return 0;
+    if (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT && sctx->ihash == NULL)
+        return 0;
+
+    p = tmpbuf;
+    *p++ = sct->version;
+    *p++ = SIGNATURE_TYPE_CERT_TIMESTAMP;
+    l2n8(sct->timestamp, p);
+    s2n(sct->entry_type, p);
+
+    if (!EVP_DigestUpdate(ctx, tmpbuf, p - tmpbuf))
+        return 0;
+
+    if (sct->entry_type == CT_LOG_ENTRY_TYPE_X509) {
+        der = sctx->certder;
+        derlen = sctx->certderlen;
+    } else {
+        if (!EVP_DigestUpdate(ctx, sctx->ihash, sctx->ihashlen))
+            return 0;
+        der = sctx->preder;
+        derlen = sctx->prederlen;
+    }
+
+    /* If no encoding available, fatal error */
+    if (der == NULL)
+        return 0;
+
+    /* Include length first */
+    p = tmpbuf;
+    l2n3(derlen, p);
+
+    if (!EVP_DigestUpdate(ctx, tmpbuf, 3))
+        return 0;
+    if (!EVP_DigestUpdate(ctx, der, derlen))
+        return 0;
+
+    /* Add any extensions */
+    p = tmpbuf;
+    s2n(sct->ext_len, p);
+    if (!EVP_DigestUpdate(ctx, tmpbuf, 2))
+        return 0;
+
+    if (sct->ext_len && !EVP_DigestUpdate(ctx, sct->ext, sct->ext_len))
+        return 0;
+
+    return 1;
+}
+
+int SCT_CTX_verify(const SCT_CTX *sctx, const SCT *sct)
+{
+    EVP_MD_CTX *ctx = NULL;
+    int ret = 0;
+
+    if (!SCT_is_complete(sct) || sctx->pkey == NULL ||
+        sct->entry_type == CT_LOG_ENTRY_TYPE_NOT_SET ||
+        (sct->entry_type == CT_LOG_ENTRY_TYPE_PRECERT && sctx->ihash == NULL)) {
+        CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_NOT_SET);
+        return 0;
+    }
+    if (sct->version != SCT_VERSION_V1) {
+        CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_UNSUPPORTED_VERSION);
+        return 0;
+    }
+    if (sct->log_id_len != sctx->pkeyhashlen ||
+        memcmp(sct->log_id, sctx->pkeyhash, sctx->pkeyhashlen) != 0) {
+        CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_LOG_ID_MISMATCH);
+        return 0;
+    }
+    if (sct->timestamp > sctx->epoch_time_in_ms) {
+        CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_FUTURE_TIMESTAMP);
+        return 0;
+    }
+
+    ctx = EVP_MD_CTX_new();
+    if (ctx == NULL)
+        goto end;
+
+    if (!EVP_DigestVerifyInit(ctx, NULL, EVP_sha256(), NULL, sctx->pkey))
+        goto end;
+
+    if (!sct_ctx_update(ctx, sctx, sct))
+        goto end;
+
+    /* Verify signature */
+    ret = EVP_DigestVerifyFinal(ctx, sct->sig, sct->sig_len);
+    /* If ret < 0 some other error: fall through without setting error */
+    if (ret == 0)
+        CTerr(CT_F_SCT_CTX_VERIFY, CT_R_SCT_INVALID_SIGNATURE);
+
+end:
+    EVP_MD_CTX_free(ctx);
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_x509v3.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_x509v3.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ct/ct_x509v3.c	(revision 331)
@@ -0,0 +1,60 @@
+/*
+ * 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
+ */
+
+#ifdef OPENSSL_NO_CT
+# error "CT is disabled"
+#endif
+
+#include "ct_locl.h"
+
+static char *i2s_poison(const X509V3_EXT_METHOD *method, void *val)
+{
+    return OPENSSL_strdup("NULL");
+}
+
+static void *s2i_poison(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, const char *str)
+{
+   return ASN1_NULL_new();
+}
+
+static int i2r_SCT_LIST(X509V3_EXT_METHOD *method, STACK_OF(SCT) *sct_list,
+                 BIO *out, int indent)
+{
+    SCT_LIST_print(sct_list, out, indent, "\n", NULL);
+    return 1;
+}
+
+/* Handlers for X509v3/OCSP Certificate Transparency extensions */
+const X509V3_EXT_METHOD v3_ct_scts[3] = {
+    /* X509v3 extension in certificates that contains SCTs */
+    { NID_ct_precert_scts, 0, NULL,
+    NULL, (X509V3_EXT_FREE)SCT_LIST_free,
+    (X509V3_EXT_D2I)d2i_SCT_LIST, (X509V3_EXT_I2D)i2d_SCT_LIST,
+    NULL, NULL,
+    NULL, NULL,
+    (X509V3_EXT_I2R)i2r_SCT_LIST, NULL,
+    NULL },
+
+    /* X509v3 extension to mark a certificate as a pre-certificate */
+    { NID_ct_precert_poison, 0, ASN1_ITEM_ref(ASN1_NULL),
+    NULL, NULL, NULL, NULL,
+    i2s_poison, s2i_poison,
+    NULL, NULL,
+    NULL, NULL,
+    NULL },
+
+    /* OCSP extension that contains SCTs */
+    { NID_ct_cert_scts, 0, NULL,
+    0, (X509V3_EXT_FREE)SCT_LIST_free,
+    (X509V3_EXT_D2I)d2i_SCT_LIST, (X509V3_EXT_I2D)i2d_SCT_LIST,
+    NULL, NULL,
+    NULL, NULL,
+    (X509V3_EXT_I2R)i2r_SCT_LIST, NULL,
+    NULL },
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cversion.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cversion.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/cversion.c	(revision 331)
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1995-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 "internal/cryptlib.h"
+
+#ifndef NO_WINDOWS_BRAINDEATH
+# include "buildinf.h"
+#endif
+
+unsigned long OpenSSL_version_num(void)
+{
+    return OPENSSL_VERSION_NUMBER;
+}
+
+const char *OpenSSL_version(int t)
+{
+    if (t == OPENSSL_VERSION)
+        return OPENSSL_VERSION_TEXT;
+    if (t == OPENSSL_BUILT_ON) {
+#ifdef DATE
+# ifdef OPENSSL_USE_BUILD_DATE
+        return (DATE);
+# else
+        return ("built on: reproducible build, date unspecified");
+# endif
+#else
+        return ("built on: date not available");
+#endif
+    }
+    if (t == OPENSSL_CFLAGS) {
+#ifdef CFLAGS
+        return (CFLAGS);
+#else
+        return ("compiler: information not available");
+#endif
+    }
+    if (t == OPENSSL_PLATFORM) {
+#ifdef PLATFORM
+        return (PLATFORM);
+#else
+        return ("platform: information not available");
+#endif
+    }
+    if (t == OPENSSL_DIR) {
+#ifdef OPENSSLDIR
+        return "OPENSSLDIR: \"" OPENSSLDIR "\"";
+#else
+        return "OPENSSLDIR: N/A";
+#endif
+    }
+    if (t == OPENSSL_ENGINES_DIR) {
+#ifdef ENGINESDIR
+        return "ENGINESDIR: \"" ENGINESDIR "\"";
+#else
+        return "ENGINESDIR: N/A";
+#endif
+    }
+    return ("not available");
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/cbc_cksm.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/cbc_cksm.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/cbc_cksm.c	(revision 331)
@@ -0,0 +1,54 @@
+/*
+ * Copyright 1995-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 "des_locl.h"
+
+DES_LONG DES_cbc_cksum(const unsigned char *in, DES_cblock *output,
+                       long length, DES_key_schedule *schedule,
+                       const_DES_cblock *ivec)
+{
+    register DES_LONG tout0, tout1, tin0, tin1;
+    register long l = length;
+    DES_LONG tin[2];
+    unsigned char *out = &(*output)[0];
+    const unsigned char *iv = &(*ivec)[0];
+
+    c2l(iv, tout0);
+    c2l(iv, tout1);
+    for (; l > 0; l -= 8) {
+        if (l >= 8) {
+            c2l(in, tin0);
+            c2l(in, tin1);
+        } else
+            c2ln(in, tin0, tin1, l);
+
+        tin0 ^= tout0;
+        tin[0] = tin0;
+        tin1 ^= tout1;
+        tin[1] = tin1;
+        DES_encrypt1((DES_LONG *)tin, schedule, DES_ENCRYPT);
+        /* fix 15/10/91 eay - thanks to keithr@sco.COM */
+        tout0 = tin[0];
+        tout1 = tin[1];
+    }
+    if (out != NULL) {
+        l2c(tout0, out);
+        l2c(tout1, out);
+    }
+    tout0 = tin0 = tin1 = tin[0] = tin[1] = 0;
+    /*
+     * Transform the data in tout1 so that it will match the return value
+     * that the MIT Kerberos mit_des_cbc_cksum API returns.
+     */
+    tout1 = ((tout1 >> 24L) & 0x000000FF)
+        | ((tout1 >> 8L) & 0x0000FF00)
+        | ((tout1 << 8L) & 0x00FF0000)
+        | ((tout1 << 24L) & 0xFF000000);
+    return (tout1);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/cbc_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/cbc_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/cbc_enc.c	(revision 331)
@@ -0,0 +1,12 @@
+/*
+ * Copyright 1995-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
+ */
+
+#define CBC_ENC_C__DONT_UPDATE_IV
+
+#include "ncbc_enc.c"           /* des_cbc_encrypt */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/cfb64ede.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/cfb64ede.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/cfb64ede.c	(revision 331)
@@ -0,0 +1,190 @@
+/*
+ * Copyright 1995-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 "des_locl.h"
+#include "e_os.h"
+
+/*
+ * The input and output encrypted as though 64bit cfb mode is being used.
+ * The extra state information to record how much of the 64bit block we have
+ * used is contained in *num;
+ */
+
+void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                            long length, DES_key_schedule *ks1,
+                            DES_key_schedule *ks2, DES_key_schedule *ks3,
+                            DES_cblock *ivec, int *num, int enc)
+{
+    register DES_LONG v0, v1;
+    register long l = length;
+    register int n = *num;
+    DES_LONG ti[2];
+    unsigned char *iv, c, cc;
+
+    iv = &(*ivec)[0];
+    if (enc) {
+        while (l--) {
+            if (n == 0) {
+                c2l(iv, v0);
+                c2l(iv, v1);
+
+                ti[0] = v0;
+                ti[1] = v1;
+                DES_encrypt3(ti, ks1, ks2, ks3);
+                v0 = ti[0];
+                v1 = ti[1];
+
+                iv = &(*ivec)[0];
+                l2c(v0, iv);
+                l2c(v1, iv);
+                iv = &(*ivec)[0];
+            }
+            c = *(in++) ^ iv[n];
+            *(out++) = c;
+            iv[n] = c;
+            n = (n + 1) & 0x07;
+        }
+    } else {
+        while (l--) {
+            if (n == 0) {
+                c2l(iv, v0);
+                c2l(iv, v1);
+
+                ti[0] = v0;
+                ti[1] = v1;
+                DES_encrypt3(ti, ks1, ks2, ks3);
+                v0 = ti[0];
+                v1 = ti[1];
+
+                iv = &(*ivec)[0];
+                l2c(v0, iv);
+                l2c(v1, iv);
+                iv = &(*ivec)[0];
+            }
+            cc = *(in++);
+            c = iv[n];
+            iv[n] = cc;
+            *(out++) = c ^ cc;
+            n = (n + 1) & 0x07;
+        }
+    }
+    v0 = v1 = ti[0] = ti[1] = c = cc = 0;
+    *num = n;
+}
+
+/*
+ * This is compatible with the single key CFB-r for DES, even thought that's
+ * not what EVP needs.
+ */
+
+void DES_ede3_cfb_encrypt(const unsigned char *in, unsigned char *out,
+                          int numbits, long length, DES_key_schedule *ks1,
+                          DES_key_schedule *ks2, DES_key_schedule *ks3,
+                          DES_cblock *ivec, int enc)
+{
+    register DES_LONG d0, d1, v0, v1;
+    register unsigned long l = length, n = ((unsigned int)numbits + 7) / 8;
+    register int num = numbits, i;
+    DES_LONG ti[2];
+    unsigned char *iv;
+    unsigned char ovec[16];
+
+    if (num > 64)
+        return;
+    iv = &(*ivec)[0];
+    c2l(iv, v0);
+    c2l(iv, v1);
+    if (enc) {
+        while (l >= n) {
+            l -= n;
+            ti[0] = v0;
+            ti[1] = v1;
+            DES_encrypt3(ti, ks1, ks2, ks3);
+            c2ln(in, d0, d1, n);
+            in += n;
+            d0 ^= ti[0];
+            d1 ^= ti[1];
+            l2cn(d0, d1, out, n);
+            out += n;
+            /*
+             * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under
+             * gcc :-(
+             */
+            if (num == 32) {
+                v0 = v1;
+                v1 = d0;
+            } else if (num == 64) {
+                v0 = d0;
+                v1 = d1;
+            } else {
+                iv = &ovec[0];
+                l2c(v0, iv);
+                l2c(v1, iv);
+                l2c(d0, iv);
+                l2c(d1, iv);
+                /* shift ovec left most of the bits... */
+                memmove(ovec, ovec + num / 8, 8 + (num % 8 ? 1 : 0));
+                /* now the remaining bits */
+                if (num % 8 != 0)
+                    for (i = 0; i < 8; ++i) {
+                        ovec[i] <<= num % 8;
+                        ovec[i] |= ovec[i + 1] >> (8 - num % 8);
+                    }
+                iv = &ovec[0];
+                c2l(iv, v0);
+                c2l(iv, v1);
+            }
+        }
+    } else {
+        while (l >= n) {
+            l -= n;
+            ti[0] = v0;
+            ti[1] = v1;
+            DES_encrypt3(ti, ks1, ks2, ks3);
+            c2ln(in, d0, d1, n);
+            in += n;
+            /*
+             * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under
+             * gcc :-(
+             */
+            if (num == 32) {
+                v0 = v1;
+                v1 = d0;
+            } else if (num == 64) {
+                v0 = d0;
+                v1 = d1;
+            } else {
+                iv = &ovec[0];
+                l2c(v0, iv);
+                l2c(v1, iv);
+                l2c(d0, iv);
+                l2c(d1, iv);
+                /* shift ovec left most of the bits... */
+                memmove(ovec, ovec + num / 8, 8 + (num % 8 ? 1 : 0));
+                /* now the remaining bits */
+                if (num % 8 != 0)
+                    for (i = 0; i < 8; ++i) {
+                        ovec[i] <<= num % 8;
+                        ovec[i] |= ovec[i + 1] >> (8 - num % 8);
+                    }
+                iv = &ovec[0];
+                c2l(iv, v0);
+                c2l(iv, v1);
+            }
+            d0 ^= ti[0];
+            d1 ^= ti[1];
+            l2cn(d0, d1, out, n);
+            out += n;
+        }
+    }
+    iv = &(*ivec)[0];
+    l2c(v0, iv);
+    l2c(v1, iv);
+    v0 = v1 = d0 = d1 = ti[0] = ti[1] = 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/cfb64enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/cfb64enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/cfb64enc.c	(revision 331)
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1995-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 "des_locl.h"
+
+/*
+ * The input and output encrypted as though 64bit cfb mode is being used.
+ * The extra state information to record how much of the 64bit block we have
+ * used is contained in *num;
+ */
+
+void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                       long length, DES_key_schedule *schedule,
+                       DES_cblock *ivec, int *num, int enc)
+{
+    register DES_LONG v0, v1;
+    register long l = length;
+    register int n = *num;
+    DES_LONG ti[2];
+    unsigned char *iv, c, cc;
+
+    iv = &(*ivec)[0];
+    if (enc) {
+        while (l--) {
+            if (n == 0) {
+                c2l(iv, v0);
+                ti[0] = v0;
+                c2l(iv, v1);
+                ti[1] = v1;
+                DES_encrypt1(ti, schedule, DES_ENCRYPT);
+                iv = &(*ivec)[0];
+                v0 = ti[0];
+                l2c(v0, iv);
+                v0 = ti[1];
+                l2c(v0, iv);
+                iv = &(*ivec)[0];
+            }
+            c = *(in++) ^ iv[n];
+            *(out++) = c;
+            iv[n] = c;
+            n = (n + 1) & 0x07;
+        }
+    } else {
+        while (l--) {
+            if (n == 0) {
+                c2l(iv, v0);
+                ti[0] = v0;
+                c2l(iv, v1);
+                ti[1] = v1;
+                DES_encrypt1(ti, schedule, DES_ENCRYPT);
+                iv = &(*ivec)[0];
+                v0 = ti[0];
+                l2c(v0, iv);
+                v0 = ti[1];
+                l2c(v0, iv);
+                iv = &(*ivec)[0];
+            }
+            cc = *(in++);
+            c = iv[n];
+            iv[n] = cc;
+            *(out++) = c ^ cc;
+            n = (n + 1) & 0x07;
+        }
+    }
+    v0 = v1 = ti[0] = ti[1] = c = cc = 0;
+    *num = n;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/cfb_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/cfb_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/cfb_enc.c	(revision 331)
@@ -0,0 +1,150 @@
+/*
+ * Copyright 1995-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 "e_os.h"
+#include "des_locl.h"
+#include <assert.h>
+
+/*
+ * The input and output are loaded in multiples of 8 bits. What this means is
+ * that if you hame numbits=12 and length=2 the first 12 bits will be
+ * retrieved from the first byte and half the second.  The second 12 bits
+ * will come from the 3rd and half the 4th byte.
+ */
+/*
+ * Until Aug 1 2003 this function did not correctly implement CFB-r, so it
+ * will not be compatible with any encryption prior to that date. Ben.
+ */
+void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
+                     long length, DES_key_schedule *schedule,
+                     DES_cblock *ivec, int enc)
+{
+    register DES_LONG d0, d1, v0, v1;
+    register unsigned long l = length;
+    register int num = numbits / 8, n = (numbits + 7) / 8, i, rem =
+        numbits % 8;
+    DES_LONG ti[2];
+    unsigned char *iv;
+#ifndef L_ENDIAN
+    unsigned char ovec[16];
+#else
+    unsigned int sh[4];
+    unsigned char *ovec = (unsigned char *)sh;
+
+    /* I kind of count that compiler optimizes away this assertioni, */
+    assert(sizeof(sh[0]) == 4); /* as this holds true for all, */
+    /* but 16-bit platforms...      */
+
+#endif
+
+    if (numbits <= 0 || numbits > 64)
+        return;
+    iv = &(*ivec)[0];
+    c2l(iv, v0);
+    c2l(iv, v1);
+    if (enc) {
+        while (l >= (unsigned long)n) {
+            l -= n;
+            ti[0] = v0;
+            ti[1] = v1;
+            DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT);
+            c2ln(in, d0, d1, n);
+            in += n;
+            d0 ^= ti[0];
+            d1 ^= ti[1];
+            l2cn(d0, d1, out, n);
+            out += n;
+            /*
+             * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under
+             * gcc :-(
+             */
+            if (numbits == 32) {
+                v0 = v1;
+                v1 = d0;
+            } else if (numbits == 64) {
+                v0 = d0;
+                v1 = d1;
+            } else {
+#ifndef L_ENDIAN
+                iv = &ovec[0];
+                l2c(v0, iv);
+                l2c(v1, iv);
+                l2c(d0, iv);
+                l2c(d1, iv);
+#else
+                sh[0] = v0, sh[1] = v1, sh[2] = d0, sh[3] = d1;
+#endif
+                if (rem == 0)
+                    memmove(ovec, ovec + num, 8);
+                else
+                    for (i = 0; i < 8; ++i)
+                        ovec[i] = ovec[i + num] << rem |
+                            ovec[i + num + 1] >> (8 - rem);
+#ifdef L_ENDIAN
+                v0 = sh[0], v1 = sh[1];
+#else
+                iv = &ovec[0];
+                c2l(iv, v0);
+                c2l(iv, v1);
+#endif
+            }
+        }
+    } else {
+        while (l >= (unsigned long)n) {
+            l -= n;
+            ti[0] = v0;
+            ti[1] = v1;
+            DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT);
+            c2ln(in, d0, d1, n);
+            in += n;
+            /*
+             * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under
+             * gcc :-(
+             */
+            if (numbits == 32) {
+                v0 = v1;
+                v1 = d0;
+            } else if (numbits == 64) {
+                v0 = d0;
+                v1 = d1;
+            } else {
+#ifndef L_ENDIAN
+                iv = &ovec[0];
+                l2c(v0, iv);
+                l2c(v1, iv);
+                l2c(d0, iv);
+                l2c(d1, iv);
+#else
+                sh[0] = v0, sh[1] = v1, sh[2] = d0, sh[3] = d1;
+#endif
+                if (rem == 0)
+                    memmove(ovec, ovec + num, 8);
+                else
+                    for (i = 0; i < 8; ++i)
+                        ovec[i] = ovec[i + num] << rem |
+                            ovec[i + num + 1] >> (8 - rem);
+#ifdef L_ENDIAN
+                v0 = sh[0], v1 = sh[1];
+#else
+                iv = &ovec[0];
+                c2l(iv, v0);
+                c2l(iv, v1);
+#endif
+            }
+            d0 ^= ti[0];
+            d1 ^= ti[1];
+            l2cn(d0, d1, out, n);
+            out += n;
+        }
+    }
+    iv = &(*ivec)[0];
+    l2c(v0, iv);
+    l2c(v1, iv);
+    v0 = v1 = d0 = d1 = ti[0] = ti[1] = 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/des_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/des_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/des_enc.c	(revision 331)
@@ -0,0 +1,301 @@
+/*
+ * Copyright 1995-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 <openssl/crypto.h>
+#include "des_locl.h"
+#include "spr.h"
+
+void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc)
+{
+    register DES_LONG l, r, t, u;
+    register DES_LONG *s;
+
+    r = data[0];
+    l = data[1];
+
+    IP(r, l);
+    /*
+     * Things have been modified so that the initial rotate is done outside
+     * the loop.  This required the DES_SPtrans values in sp.h to be rotated
+     * 1 bit to the right. One perl script later and things have a 5% speed
+     * up on a sparc2. Thanks to Richard Outerbridge
+     * <71755.204@CompuServe.COM> for pointing this out.
+     */
+    /* clear the top bits on machines with 8byte longs */
+    /* shift left by 2 */
+    r = ROTATE(r, 29) & 0xffffffffL;
+    l = ROTATE(l, 29) & 0xffffffffL;
+
+    s = ks->ks->deslong;
+    /*
+     * I don't know if it is worth the effort of loop unrolling the inner
+     * loop
+     */
+    if (enc) {
+        D_ENCRYPT(l, r, 0);     /* 1 */
+        D_ENCRYPT(r, l, 2);     /* 2 */
+        D_ENCRYPT(l, r, 4);     /* 3 */
+        D_ENCRYPT(r, l, 6);     /* 4 */
+        D_ENCRYPT(l, r, 8);     /* 5 */
+        D_ENCRYPT(r, l, 10);    /* 6 */
+        D_ENCRYPT(l, r, 12);    /* 7 */
+        D_ENCRYPT(r, l, 14);    /* 8 */
+        D_ENCRYPT(l, r, 16);    /* 9 */
+        D_ENCRYPT(r, l, 18);    /* 10 */
+        D_ENCRYPT(l, r, 20);    /* 11 */
+        D_ENCRYPT(r, l, 22);    /* 12 */
+        D_ENCRYPT(l, r, 24);    /* 13 */
+        D_ENCRYPT(r, l, 26);    /* 14 */
+        D_ENCRYPT(l, r, 28);    /* 15 */
+        D_ENCRYPT(r, l, 30);    /* 16 */
+    } else {
+        D_ENCRYPT(l, r, 30);    /* 16 */
+        D_ENCRYPT(r, l, 28);    /* 15 */
+        D_ENCRYPT(l, r, 26);    /* 14 */
+        D_ENCRYPT(r, l, 24);    /* 13 */
+        D_ENCRYPT(l, r, 22);    /* 12 */
+        D_ENCRYPT(r, l, 20);    /* 11 */
+        D_ENCRYPT(l, r, 18);    /* 10 */
+        D_ENCRYPT(r, l, 16);    /* 9 */
+        D_ENCRYPT(l, r, 14);    /* 8 */
+        D_ENCRYPT(r, l, 12);    /* 7 */
+        D_ENCRYPT(l, r, 10);    /* 6 */
+        D_ENCRYPT(r, l, 8);     /* 5 */
+        D_ENCRYPT(l, r, 6);     /* 4 */
+        D_ENCRYPT(r, l, 4);     /* 3 */
+        D_ENCRYPT(l, r, 2);     /* 2 */
+        D_ENCRYPT(r, l, 0);     /* 1 */
+    }
+
+    /* rotate and clear the top bits on machines with 8byte longs */
+    l = ROTATE(l, 3) & 0xffffffffL;
+    r = ROTATE(r, 3) & 0xffffffffL;
+
+    FP(r, l);
+    data[0] = l;
+    data[1] = r;
+    l = r = t = u = 0;
+}
+
+void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc)
+{
+    register DES_LONG l, r, t, u;
+    register DES_LONG *s;
+
+    r = data[0];
+    l = data[1];
+
+    /*
+     * Things have been modified so that the initial rotate is done outside
+     * the loop.  This required the DES_SPtrans values in sp.h to be rotated
+     * 1 bit to the right. One perl script later and things have a 5% speed
+     * up on a sparc2. Thanks to Richard Outerbridge
+     * <71755.204@CompuServe.COM> for pointing this out.
+     */
+    /* clear the top bits on machines with 8byte longs */
+    r = ROTATE(r, 29) & 0xffffffffL;
+    l = ROTATE(l, 29) & 0xffffffffL;
+
+    s = ks->ks->deslong;
+    /*
+     * I don't know if it is worth the effort of loop unrolling the inner
+     * loop
+     */
+    if (enc) {
+        D_ENCRYPT(l, r, 0);     /* 1 */
+        D_ENCRYPT(r, l, 2);     /* 2 */
+        D_ENCRYPT(l, r, 4);     /* 3 */
+        D_ENCRYPT(r, l, 6);     /* 4 */
+        D_ENCRYPT(l, r, 8);     /* 5 */
+        D_ENCRYPT(r, l, 10);    /* 6 */
+        D_ENCRYPT(l, r, 12);    /* 7 */
+        D_ENCRYPT(r, l, 14);    /* 8 */
+        D_ENCRYPT(l, r, 16);    /* 9 */
+        D_ENCRYPT(r, l, 18);    /* 10 */
+        D_ENCRYPT(l, r, 20);    /* 11 */
+        D_ENCRYPT(r, l, 22);    /* 12 */
+        D_ENCRYPT(l, r, 24);    /* 13 */
+        D_ENCRYPT(r, l, 26);    /* 14 */
+        D_ENCRYPT(l, r, 28);    /* 15 */
+        D_ENCRYPT(r, l, 30);    /* 16 */
+    } else {
+        D_ENCRYPT(l, r, 30);    /* 16 */
+        D_ENCRYPT(r, l, 28);    /* 15 */
+        D_ENCRYPT(l, r, 26);    /* 14 */
+        D_ENCRYPT(r, l, 24);    /* 13 */
+        D_ENCRYPT(l, r, 22);    /* 12 */
+        D_ENCRYPT(r, l, 20);    /* 11 */
+        D_ENCRYPT(l, r, 18);    /* 10 */
+        D_ENCRYPT(r, l, 16);    /* 9 */
+        D_ENCRYPT(l, r, 14);    /* 8 */
+        D_ENCRYPT(r, l, 12);    /* 7 */
+        D_ENCRYPT(l, r, 10);    /* 6 */
+        D_ENCRYPT(r, l, 8);     /* 5 */
+        D_ENCRYPT(l, r, 6);     /* 4 */
+        D_ENCRYPT(r, l, 4);     /* 3 */
+        D_ENCRYPT(l, r, 2);     /* 2 */
+        D_ENCRYPT(r, l, 0);     /* 1 */
+    }
+    /* rotate and clear the top bits on machines with 8byte longs */
+    data[0] = ROTATE(l, 3) & 0xffffffffL;
+    data[1] = ROTATE(r, 3) & 0xffffffffL;
+    l = r = t = u = 0;
+}
+
+void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
+                  DES_key_schedule *ks2, DES_key_schedule *ks3)
+{
+    register DES_LONG l, r;
+
+    l = data[0];
+    r = data[1];
+    IP(l, r);
+    data[0] = l;
+    data[1] = r;
+    DES_encrypt2((DES_LONG *)data, ks1, DES_ENCRYPT);
+    DES_encrypt2((DES_LONG *)data, ks2, DES_DECRYPT);
+    DES_encrypt2((DES_LONG *)data, ks3, DES_ENCRYPT);
+    l = data[0];
+    r = data[1];
+    FP(r, l);
+    data[0] = l;
+    data[1] = r;
+}
+
+void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
+                  DES_key_schedule *ks2, DES_key_schedule *ks3)
+{
+    register DES_LONG l, r;
+
+    l = data[0];
+    r = data[1];
+    IP(l, r);
+    data[0] = l;
+    data[1] = r;
+    DES_encrypt2((DES_LONG *)data, ks3, DES_DECRYPT);
+    DES_encrypt2((DES_LONG *)data, ks2, DES_ENCRYPT);
+    DES_encrypt2((DES_LONG *)data, ks1, DES_DECRYPT);
+    l = data[0];
+    r = data[1];
+    FP(r, l);
+    data[0] = l;
+    data[1] = r;
+}
+
+#ifndef DES_DEFAULT_OPTIONS
+
+# undef CBC_ENC_C__DONT_UPDATE_IV
+# include "ncbc_enc.c"          /* DES_ncbc_encrypt */
+
+void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
+                          long length, DES_key_schedule *ks1,
+                          DES_key_schedule *ks2, DES_key_schedule *ks3,
+                          DES_cblock *ivec, int enc)
+{
+    register DES_LONG tin0, tin1;
+    register DES_LONG tout0, tout1, xor0, xor1;
+    register const unsigned char *in;
+    unsigned char *out;
+    register long l = length;
+    DES_LONG tin[2];
+    unsigned char *iv;
+
+    in = input;
+    out = output;
+    iv = &(*ivec)[0];
+
+    if (enc) {
+        c2l(iv, tout0);
+        c2l(iv, tout1);
+        for (l -= 8; l >= 0; l -= 8) {
+            c2l(in, tin0);
+            c2l(in, tin1);
+            tin0 ^= tout0;
+            tin1 ^= tout1;
+
+            tin[0] = tin0;
+            tin[1] = tin1;
+            DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3);
+            tout0 = tin[0];
+            tout1 = tin[1];
+
+            l2c(tout0, out);
+            l2c(tout1, out);
+        }
+        if (l != -8) {
+            c2ln(in, tin0, tin1, l + 8);
+            tin0 ^= tout0;
+            tin1 ^= tout1;
+
+            tin[0] = tin0;
+            tin[1] = tin1;
+            DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3);
+            tout0 = tin[0];
+            tout1 = tin[1];
+
+            l2c(tout0, out);
+            l2c(tout1, out);
+        }
+        iv = &(*ivec)[0];
+        l2c(tout0, iv);
+        l2c(tout1, iv);
+    } else {
+        register DES_LONG t0, t1;
+
+        c2l(iv, xor0);
+        c2l(iv, xor1);
+        for (l -= 8; l >= 0; l -= 8) {
+            c2l(in, tin0);
+            c2l(in, tin1);
+
+            t0 = tin0;
+            t1 = tin1;
+
+            tin[0] = tin0;
+            tin[1] = tin1;
+            DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3);
+            tout0 = tin[0];
+            tout1 = tin[1];
+
+            tout0 ^= xor0;
+            tout1 ^= xor1;
+            l2c(tout0, out);
+            l2c(tout1, out);
+            xor0 = t0;
+            xor1 = t1;
+        }
+        if (l != -8) {
+            c2l(in, tin0);
+            c2l(in, tin1);
+
+            t0 = tin0;
+            t1 = tin1;
+
+            tin[0] = tin0;
+            tin[1] = tin1;
+            DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3);
+            tout0 = tin[0];
+            tout1 = tin[1];
+
+            tout0 ^= xor0;
+            tout1 ^= xor1;
+            l2cn(tout0, tout1, out, l + 8);
+            xor0 = t0;
+            xor1 = t1;
+        }
+
+        iv = &(*ivec)[0];
+        l2c(xor0, iv);
+        l2c(xor1, iv);
+    }
+    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
+    tin[0] = tin[1] = 0;
+}
+
+#endif                          /* DES_DEFAULT_OPTIONS */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/des_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/des_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/des_locl.h	(revision 331)
@@ -0,0 +1,217 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_DES_LOCL_H
+# define HEADER_DES_LOCL_H
+
+# include <openssl/e_os2.h>
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+
+# include <openssl/des.h>
+
+# ifdef OPENSSL_BUILD_SHLIBCRYPTO
+#  undef OPENSSL_EXTERN
+#  define OPENSSL_EXTERN OPENSSL_EXPORT
+# endif
+
+# define ITERATIONS 16
+# define HALF_ITERATIONS 8
+
+/* used in des_read and des_write */
+# define MAXWRITE        (1024*16)
+# define BSIZE           (MAXWRITE+4)
+
+# define c2l(c,l)        (l =((DES_LONG)(*((c)++)))    , \
+                         l|=((DES_LONG)(*((c)++)))<< 8L, \
+                         l|=((DES_LONG)(*((c)++)))<<16L, \
+                         l|=((DES_LONG)(*((c)++)))<<24L)
+
+/* NOTE - c is not incremented as per c2l */
+# define c2ln(c,l1,l2,n) { \
+                        c+=n; \
+                        l1=l2=0; \
+                        switch (n) { \
+                        case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
+                        case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
+                        case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
+                        case 5: l2|=((DES_LONG)(*(--(c))));     \
+                        case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
+                        case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
+                        case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
+                        case 1: l1|=((DES_LONG)(*(--(c))));     \
+                                } \
+                        }
+
+# define l2c(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+/*
+ * replacements for htonl and ntohl since I have no idea what to do when
+ * faced with machines with 8 byte longs.
+ */
+# define HDRSIZE 4
+
+# define n2l(c,l)        (l =((DES_LONG)(*((c)++)))<<24L, \
+                         l|=((DES_LONG)(*((c)++)))<<16L, \
+                         l|=((DES_LONG)(*((c)++)))<< 8L, \
+                         l|=((DES_LONG)(*((c)++))))
+
+# define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)     )&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+# define l2cn(l1,l2,c,n) { \
+                        c+=n; \
+                        switch (n) { \
+                        case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
+                        case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
+                        case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
+                        case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
+                        case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
+                        case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
+                        case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
+                        case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
+                                } \
+                        }
+
+# if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER))
+#  define ROTATE(a,n)     (_lrotr(a,n))
+# elif defined(__ICC)
+#  define ROTATE(a,n)     (_rotr(a,n))
+# elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
+#  if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
+#   define ROTATE(a,n)   ({ register unsigned int ret;   \
+                                asm ("rorl %1,%0"       \
+                                        : "=r"(ret)     \
+                                        : "I"(n),"0"(a) \
+                                        : "cc");        \
+                           ret;                         \
+                        })
+#  endif
+# endif
+# ifndef ROTATE
+#  define ROTATE(a,n)     (((a)>>(n))+((a)<<(32-(n))))
+# endif
+
+/*
+ * Don't worry about the LOAD_DATA() stuff, that is used by fcrypt() to add
+ * it's little bit to the front
+ */
+
+# ifdef DES_FCRYPT
+
+#  define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
+        { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
+
+#  define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
+        t=R^(R>>16L); \
+        u=t&E0; t&=E1; \
+        tmp=(u<<16); u^=R^s[S  ]; u^=tmp; \
+        tmp=(t<<16); t^=R^s[S+1]; t^=tmp
+# else
+#  define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
+#  define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
+        u=R^s[S  ]; \
+        t=R^s[S+1]
+# endif
+
+/*
+ * It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there is no reason
+ * to not xor all the sub items together.  This potentially saves a register
+ * since things can be xored directly into L
+ */
+
+# define D_ENCRYPT(LL,R,S) { \
+        LOAD_DATA_tmp(R,S,u,t,E0,E1); \
+        t=ROTATE(t,4); \
+        LL^= \
+            DES_SPtrans[0][(u>> 2L)&0x3f]^ \
+            DES_SPtrans[2][(u>>10L)&0x3f]^ \
+            DES_SPtrans[4][(u>>18L)&0x3f]^ \
+            DES_SPtrans[6][(u>>26L)&0x3f]^ \
+            DES_SPtrans[1][(t>> 2L)&0x3f]^ \
+            DES_SPtrans[3][(t>>10L)&0x3f]^ \
+            DES_SPtrans[5][(t>>18L)&0x3f]^ \
+            DES_SPtrans[7][(t>>26L)&0x3f]; }
+
+        /*-
+         * IP and FP
+         * The problem is more of a geometric problem that random bit fiddling.
+         0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6
+         8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4
+        16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2
+        24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0
+
+        32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7
+        40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5
+        48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3
+        56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1
+
+        The output has been subject to swaps of the form
+        0 1 -> 3 1 but the odd and even bits have been put into
+        2 3    2 0
+        different words.  The main trick is to remember that
+        t=((l>>size)^r)&(mask);
+        r^=t;
+        l^=(t<<size);
+        can be used to swap and move bits between words.
+
+        So l =  0  1  2  3  r = 16 17 18 19
+                4  5  6  7      20 21 22 23
+                8  9 10 11      24 25 26 27
+               12 13 14 15      28 29 30 31
+        becomes (for size == 2 and mask == 0x3333)
+           t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19
+                 6^20  7^21 -- --        4  5 20 21       6  7 22 23
+                10^24 11^25 -- --        8  9 24 25      10 11 24 25
+                14^28 15^29 -- --       12 13 28 29      14 15 28 29
+
+        Thanks for hints from Richard Outerbridge - he told me IP&FP
+        could be done in 15 xor, 10 shifts and 5 ands.
+        When I finally started to think of the problem in 2D
+        I first got ~42 operations without xors.  When I remembered
+        how to use xors :-) I got it to its final state.
+        */
+# define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+        (b)^=(t),\
+        (a)^=((t)<<(n)))
+
+# define IP(l,r) \
+        { \
+        register DES_LONG tt; \
+        PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
+        PERM_OP(l,r,tt,16,0x0000ffffL); \
+        PERM_OP(r,l,tt, 2,0x33333333L); \
+        PERM_OP(l,r,tt, 8,0x00ff00ffL); \
+        PERM_OP(r,l,tt, 1,0x55555555L); \
+        }
+
+# define FP(l,r) \
+        { \
+        register DES_LONG tt; \
+        PERM_OP(l,r,tt, 1,0x55555555L); \
+        PERM_OP(r,l,tt, 8,0x00ff00ffL); \
+        PERM_OP(l,r,tt, 2,0x33333333L); \
+        PERM_OP(r,l,tt,16,0x0000ffffL); \
+        PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
+        }
+
+extern const DES_LONG DES_SPtrans[8][64];
+
+void fcrypt_body(DES_LONG *out, DES_key_schedule *ks,
+                 DES_LONG Eswap0, DES_LONG Eswap1);
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/ecb3_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/ecb3_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/ecb3_enc.c	(revision 331)
@@ -0,0 +1,33 @@
+/*
+ * Copyright 1995-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 "des_locl.h"
+
+void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
+                      DES_key_schedule *ks1, DES_key_schedule *ks2,
+                      DES_key_schedule *ks3, int enc)
+{
+    register DES_LONG l0, l1;
+    DES_LONG ll[2];
+    const unsigned char *in = &(*input)[0];
+    unsigned char *out = &(*output)[0];
+
+    c2l(in, l0);
+    c2l(in, l1);
+    ll[0] = l0;
+    ll[1] = l1;
+    if (enc)
+        DES_encrypt3(ll, ks1, ks2, ks3);
+    else
+        DES_decrypt3(ll, ks1, ks2, ks3);
+    l0 = ll[0];
+    l1 = ll[1];
+    l2c(l0, out);
+    l2c(l1, out);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/ecb_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/ecb_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/ecb_enc.c	(revision 331)
@@ -0,0 +1,51 @@
+/*
+ * Copyright 1995-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 "des_locl.h"
+#include <openssl/opensslv.h>
+#include <openssl/bio.h>
+
+
+const char *DES_options(void)
+{
+    static int init = 1;
+    static char buf[32];
+
+    if (init) {
+        const char *size;
+
+        if (sizeof(DES_LONG) != sizeof(long))
+            size = "int";
+        else
+            size = "long";
+        BIO_snprintf(buf, sizeof buf, "des(%s)", size);
+        init = 0;
+    }
+    return (buf);
+}
+
+void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output,
+                     DES_key_schedule *ks, int enc)
+{
+    register DES_LONG l;
+    DES_LONG ll[2];
+    const unsigned char *in = &(*input)[0];
+    unsigned char *out = &(*output)[0];
+
+    c2l(in, l);
+    ll[0] = l;
+    c2l(in, l);
+    ll[1] = l;
+    DES_encrypt1(ll, ks, enc);
+    l = ll[0];
+    l2c(l, out);
+    l = ll[1];
+    l2c(l, out);
+    l = ll[0] = ll[1] = 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/fcrypt.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/fcrypt.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/fcrypt.c	(revision 331)
@@ -0,0 +1,149 @@
+/*
+ * Copyright 1998-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
+ */
+
+/* NOCW */
+#include <stdio.h>
+#ifdef _OSD_POSIX
+# ifndef CHARSET_EBCDIC
+#  define CHARSET_EBCDIC 1
+# endif
+#endif
+#ifdef CHARSET_EBCDIC
+# include <openssl/ebcdic.h>
+#endif
+
+#include <openssl/crypto.h>
+#include "des_locl.h"
+
+/*
+ * Added more values to handle illegal salt values the way normal crypt()
+ * implementations do.  The patch was sent by Bjorn Gronvall <bg@sics.se>
+ */
+static unsigned const char con_salt[128] = {
+    0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9,
+    0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1,
+    0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9,
+    0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1,
+    0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9,
+    0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x00, 0x01,
+    0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
+    0x0A, 0x0B, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
+    0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
+    0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
+    0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22,
+    0x23, 0x24, 0x25, 0x20, 0x21, 0x22, 0x23, 0x24,
+    0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C,
+    0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34,
+    0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C,
+    0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44,
+};
+
+static unsigned const char cov_2char[64] = {
+    0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+    0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44,
+    0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
+    0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54,
+    0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62,
+    0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
+    0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
+    0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
+};
+
+char *DES_crypt(const char *buf, const char *salt)
+{
+    static char buff[14];
+
+#ifndef CHARSET_EBCDIC
+    return (DES_fcrypt(buf, salt, buff));
+#else
+    char e_salt[2 + 1];
+    char e_buf[32 + 1];         /* replace 32 by 8 ? */
+    char *ret;
+
+    if (salt[0] == '\0' || salt[1] == '\0')
+        return NULL;
+
+    /* Copy salt, convert to ASCII. */
+    e_salt[0] = salt[0];
+    e_salt[1] = salt[1];
+    e_salt[2] = '\0';
+    ebcdic2ascii(e_salt, e_salt, sizeof(e_salt));
+
+    /* Convert password to ASCII. */
+    OPENSSL_strlcpy(e_buf, buf, sizeof(e_buf));
+    ebcdic2ascii(e_buf, e_buf, sizeof e_buf);
+
+    /* Encrypt it (from/to ASCII); if it worked, convert back. */
+    ret = DES_fcrypt(e_buf, e_salt, buff);
+    if (ret != NULL)
+        ascii2ebcdic(ret, ret, strlen(ret));
+
+    return ret;
+#endif
+}
+
+char *DES_fcrypt(const char *buf, const char *salt, char *ret)
+{
+    unsigned int i, j, x, y;
+    DES_LONG Eswap0, Eswap1;
+    DES_LONG out[2], ll;
+    DES_cblock key;
+    DES_key_schedule ks;
+    unsigned char bb[9];
+    unsigned char *b = bb;
+    unsigned char c, u;
+
+    x = ret[0] = salt[0];
+    if (x == 0 || x >= sizeof(con_salt))
+        return NULL;
+    Eswap0 = con_salt[x] << 2;
+    x = ret[1] = salt[1];
+    if (x == 0 || x >= sizeof(con_salt))
+        return NULL;
+    Eswap1 = con_salt[x] << 6;
+
+    /*
+     * EAY r=strlen(buf); r=(r+7)/8;
+     */
+    for (i = 0; i < 8; i++) {
+        c = *(buf++);
+        if (!c)
+            break;
+        key[i] = (c << 1);
+    }
+    for (; i < 8; i++)
+        key[i] = 0;
+
+    DES_set_key_unchecked(&key, &ks);
+    fcrypt_body(&(out[0]), &ks, Eswap0, Eswap1);
+
+    ll = out[0];
+    l2c(ll, b);
+    ll = out[1];
+    l2c(ll, b);
+    y = 0;
+    u = 0x80;
+    bb[8] = 0;
+    for (i = 2; i < 13; i++) {
+        c = 0;
+        for (j = 0; j < 6; j++) {
+            c <<= 1;
+            if (bb[y] & u)
+                c |= 1;
+            u >>= 1;
+            if (!u) {
+                y++;
+                u = 0x80;
+            }
+        }
+        ret[i] = cov_2char[c];
+    }
+    ret[13] = '\0';
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/fcrypt_b.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/fcrypt_b.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/fcrypt_b.c	(revision 331)
@@ -0,0 +1,72 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+
+#define DES_FCRYPT
+#include "des_locl.h"
+#undef DES_FCRYPT
+
+#undef PERM_OP
+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+        (b)^=(t),\
+        (a)^=((t)<<(n)))
+
+#undef HPERM_OP
+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
+        (a)=(a)^(t)^(t>>(16-(n))))\
+
+void fcrypt_body(DES_LONG *out, DES_key_schedule *ks, DES_LONG Eswap0,
+                 DES_LONG Eswap1)
+{
+    register DES_LONG l, r, t, u;
+    register DES_LONG *s;
+    register int j;
+    register DES_LONG E0, E1;
+
+    l = 0;
+    r = 0;
+
+    s = (DES_LONG *)ks;
+    E0 = Eswap0;
+    E1 = Eswap1;
+
+    for (j = 0; j < 25; j++) {
+        D_ENCRYPT(l, r, 0);     /* 1 */
+        D_ENCRYPT(r, l, 2);     /* 2 */
+        D_ENCRYPT(l, r, 4);     /* 3 */
+        D_ENCRYPT(r, l, 6);     /* 4 */
+        D_ENCRYPT(l, r, 8);     /* 5 */
+        D_ENCRYPT(r, l, 10);    /* 6 */
+        D_ENCRYPT(l, r, 12);    /* 7 */
+        D_ENCRYPT(r, l, 14);    /* 8 */
+        D_ENCRYPT(l, r, 16);    /* 9 */
+        D_ENCRYPT(r, l, 18);    /* 10 */
+        D_ENCRYPT(l, r, 20);    /* 11 */
+        D_ENCRYPT(r, l, 22);    /* 12 */
+        D_ENCRYPT(l, r, 24);    /* 13 */
+        D_ENCRYPT(r, l, 26);    /* 14 */
+        D_ENCRYPT(l, r, 28);    /* 15 */
+        D_ENCRYPT(r, l, 30);    /* 16 */
+        t = l;
+        l = r;
+        r = t;
+    }
+    l = ROTATE(l, 3) & 0xffffffffL;
+    r = ROTATE(r, 3) & 0xffffffffL;
+
+    PERM_OP(l, r, t,  1, 0x55555555L);
+    PERM_OP(r, l, t,  8, 0x00ff00ffL);
+    PERM_OP(l, r, t,  2, 0x33333333L);
+    PERM_OP(r, l, t, 16, 0x0000ffffL);
+    PERM_OP(l, r, t,  4, 0x0f0f0f0fL);
+
+    out[0] = r;
+    out[1] = l;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/ncbc_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/ncbc_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/ncbc_enc.c	(revision 331)
@@ -0,0 +1,106 @@
+/*
+ * Copyright 1998-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
+ */
+
+/*-
+ * #included by:
+ *    cbc_enc.c  (DES_cbc_encrypt)
+ *    des_enc.c  (DES_ncbc_encrypt)
+ */
+
+#include "des_locl.h"
+
+#ifdef CBC_ENC_C__DONT_UPDATE_IV
+void DES_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+                     DES_key_schedule *_schedule, DES_cblock *ivec, int enc)
+#else
+void DES_ncbc_encrypt(const unsigned char *in, unsigned char *out,
+                      long length, DES_key_schedule *_schedule,
+                      DES_cblock *ivec, int enc)
+#endif
+{
+    register DES_LONG tin0, tin1;
+    register DES_LONG tout0, tout1, xor0, xor1;
+    register long l = length;
+    DES_LONG tin[2];
+    unsigned char *iv;
+
+    iv = &(*ivec)[0];
+
+    if (enc) {
+        c2l(iv, tout0);
+        c2l(iv, tout1);
+        for (l -= 8; l >= 0; l -= 8) {
+            c2l(in, tin0);
+            c2l(in, tin1);
+            tin0 ^= tout0;
+            tin[0] = tin0;
+            tin1 ^= tout1;
+            tin[1] = tin1;
+            DES_encrypt1((DES_LONG *)tin, _schedule, DES_ENCRYPT);
+            tout0 = tin[0];
+            l2c(tout0, out);
+            tout1 = tin[1];
+            l2c(tout1, out);
+        }
+        if (l != -8) {
+            c2ln(in, tin0, tin1, l + 8);
+            tin0 ^= tout0;
+            tin[0] = tin0;
+            tin1 ^= tout1;
+            tin[1] = tin1;
+            DES_encrypt1((DES_LONG *)tin, _schedule, DES_ENCRYPT);
+            tout0 = tin[0];
+            l2c(tout0, out);
+            tout1 = tin[1];
+            l2c(tout1, out);
+        }
+#ifndef CBC_ENC_C__DONT_UPDATE_IV
+        iv = &(*ivec)[0];
+        l2c(tout0, iv);
+        l2c(tout1, iv);
+#endif
+    } else {
+        c2l(iv, xor0);
+        c2l(iv, xor1);
+        for (l -= 8; l >= 0; l -= 8) {
+            c2l(in, tin0);
+            tin[0] = tin0;
+            c2l(in, tin1);
+            tin[1] = tin1;
+            DES_encrypt1((DES_LONG *)tin, _schedule, DES_DECRYPT);
+            tout0 = tin[0] ^ xor0;
+            tout1 = tin[1] ^ xor1;
+            l2c(tout0, out);
+            l2c(tout1, out);
+            xor0 = tin0;
+            xor1 = tin1;
+        }
+        if (l != -8) {
+            c2l(in, tin0);
+            tin[0] = tin0;
+            c2l(in, tin1);
+            tin[1] = tin1;
+            DES_encrypt1((DES_LONG *)tin, _schedule, DES_DECRYPT);
+            tout0 = tin[0] ^ xor0;
+            tout1 = tin[1] ^ xor1;
+            l2cn(tout0, tout1, out, l + 8);
+#ifndef CBC_ENC_C__DONT_UPDATE_IV
+            xor0 = tin0;
+            xor1 = tin1;
+#endif
+        }
+#ifndef CBC_ENC_C__DONT_UPDATE_IV
+        iv = &(*ivec)[0];
+        l2c(xor0, iv);
+        l2c(xor1, iv);
+#endif
+    }
+    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
+    tin[0] = tin[1] = 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/ofb64ede.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/ofb64ede.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/ofb64ede.c	(revision 331)
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1995-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 "des_locl.h"
+
+/*
+ * The input and output encrypted as though 64bit ofb mode is being used.
+ * The extra state information to record how much of the 64bit block we have
+ * used is contained in *num;
+ */
+void DES_ede3_ofb64_encrypt(register const unsigned char *in,
+                            register unsigned char *out, long length,
+                            DES_key_schedule *k1, DES_key_schedule *k2,
+                            DES_key_schedule *k3, DES_cblock *ivec, int *num)
+{
+    register DES_LONG v0, v1;
+    register int n = *num;
+    register long l = length;
+    DES_cblock d;
+    register char *dp;
+    DES_LONG ti[2];
+    unsigned char *iv;
+    int save = 0;
+
+    iv = &(*ivec)[0];
+    c2l(iv, v0);
+    c2l(iv, v1);
+    ti[0] = v0;
+    ti[1] = v1;
+    dp = (char *)d;
+    l2c(v0, dp);
+    l2c(v1, dp);
+    while (l--) {
+        if (n == 0) {
+            /* ti[0]=v0; */
+            /* ti[1]=v1; */
+            DES_encrypt3(ti, k1, k2, k3);
+            v0 = ti[0];
+            v1 = ti[1];
+
+            dp = (char *)d;
+            l2c(v0, dp);
+            l2c(v1, dp);
+            save++;
+        }
+        *(out++) = *(in++) ^ d[n];
+        n = (n + 1) & 0x07;
+    }
+    if (save) {
+        iv = &(*ivec)[0];
+        l2c(v0, iv);
+        l2c(v1, iv);
+    }
+    v0 = v1 = ti[0] = ti[1] = 0;
+    *num = n;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/ofb64enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/ofb64enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/ofb64enc.c	(revision 331)
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1995-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 "des_locl.h"
+
+/*
+ * The input and output encrypted as though 64bit ofb mode is being used.
+ * The extra state information to record how much of the 64bit block we have
+ * used is contained in *num;
+ */
+void DES_ofb64_encrypt(register const unsigned char *in,
+                       register unsigned char *out, long length,
+                       DES_key_schedule *schedule, DES_cblock *ivec, int *num)
+{
+    register DES_LONG v0, v1, t;
+    register int n = *num;
+    register long l = length;
+    DES_cblock d;
+    register unsigned char *dp;
+    DES_LONG ti[2];
+    unsigned char *iv;
+    int save = 0;
+
+    iv = &(*ivec)[0];
+    c2l(iv, v0);
+    c2l(iv, v1);
+    ti[0] = v0;
+    ti[1] = v1;
+    dp = d;
+    l2c(v0, dp);
+    l2c(v1, dp);
+    while (l--) {
+        if (n == 0) {
+            DES_encrypt1(ti, schedule, DES_ENCRYPT);
+            dp = d;
+            t = ti[0];
+            l2c(t, dp);
+            t = ti[1];
+            l2c(t, dp);
+            save++;
+        }
+        *(out++) = *(in++) ^ d[n];
+        n = (n + 1) & 0x07;
+    }
+    if (save) {
+        v0 = ti[0];
+        v1 = ti[1];
+        iv = &(*ivec)[0];
+        l2c(v0, iv);
+        l2c(v1, iv);
+    }
+    t = v0 = v1 = ti[0] = ti[1] = 0;
+    *num = n;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/ofb_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/ofb_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/ofb_enc.c	(revision 331)
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1995-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 "des_locl.h"
+
+/*
+ * The input and output are loaded in multiples of 8 bits. What this means is
+ * that if you have numbits=12 and length=2 the first 12 bits will be
+ * retrieved from the first byte and half the second.  The second 12 bits
+ * will come from the 3rd and half the 4th byte.
+ */
+void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
+                     long length, DES_key_schedule *schedule,
+                     DES_cblock *ivec)
+{
+    register DES_LONG d0, d1, vv0, vv1, v0, v1, n = (numbits + 7) / 8;
+    register DES_LONG mask0, mask1;
+    register long l = length;
+    register int num = numbits;
+    DES_LONG ti[2];
+    unsigned char *iv;
+
+    if (num > 64)
+        return;
+    if (num > 32) {
+        mask0 = 0xffffffffL;
+        if (num >= 64)
+            mask1 = mask0;
+        else
+            mask1 = (1L << (num - 32)) - 1;
+    } else {
+        if (num == 32)
+            mask0 = 0xffffffffL;
+        else
+            mask0 = (1L << num) - 1;
+        mask1 = 0x00000000L;
+    }
+
+    iv = &(*ivec)[0];
+    c2l(iv, v0);
+    c2l(iv, v1);
+    ti[0] = v0;
+    ti[1] = v1;
+    while (l-- > 0) {
+        ti[0] = v0;
+        ti[1] = v1;
+        DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT);
+        vv0 = ti[0];
+        vv1 = ti[1];
+        c2ln(in, d0, d1, n);
+        in += n;
+        d0 = (d0 ^ vv0) & mask0;
+        d1 = (d1 ^ vv1) & mask1;
+        l2cn(d0, d1, out, n);
+        out += n;
+
+        if (num == 32) {
+            v0 = v1;
+            v1 = vv0;
+        } else if (num == 64) {
+            v0 = vv0;
+            v1 = vv1;
+        } else if (num > 32) {  /* && num != 64 */
+            v0 = ((v1 >> (num - 32)) | (vv0 << (64 - num))) & 0xffffffffL;
+            v1 = ((vv0 >> (num - 32)) | (vv1 << (64 - num))) & 0xffffffffL;
+        } else {                /* num < 32 */
+
+            v0 = ((v0 >> num) | (v1 << (32 - num))) & 0xffffffffL;
+            v1 = ((v1 >> num) | (vv0 << (32 - num))) & 0xffffffffL;
+        }
+    }
+    iv = &(*ivec)[0];
+    l2c(v0, iv);
+    l2c(v1, iv);
+    v0 = v1 = d0 = d1 = ti[0] = ti[1] = vv0 = vv1 = 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/pcbc_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/pcbc_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/pcbc_enc.c	(revision 331)
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1995-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 "des_locl.h"
+
+void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output,
+                      long length, DES_key_schedule *schedule,
+                      DES_cblock *ivec, int enc)
+{
+    register DES_LONG sin0, sin1, xor0, xor1, tout0, tout1;
+    DES_LONG tin[2];
+    const unsigned char *in;
+    unsigned char *out, *iv;
+
+    in = input;
+    out = output;
+    iv = &(*ivec)[0];
+
+    if (enc) {
+        c2l(iv, xor0);
+        c2l(iv, xor1);
+        for (; length > 0; length -= 8) {
+            if (length >= 8) {
+                c2l(in, sin0);
+                c2l(in, sin1);
+            } else
+                c2ln(in, sin0, sin1, length);
+            tin[0] = sin0 ^ xor0;
+            tin[1] = sin1 ^ xor1;
+            DES_encrypt1((DES_LONG *)tin, schedule, DES_ENCRYPT);
+            tout0 = tin[0];
+            tout1 = tin[1];
+            xor0 = sin0 ^ tout0;
+            xor1 = sin1 ^ tout1;
+            l2c(tout0, out);
+            l2c(tout1, out);
+        }
+    } else {
+        c2l(iv, xor0);
+        c2l(iv, xor1);
+        for (; length > 0; length -= 8) {
+            c2l(in, sin0);
+            c2l(in, sin1);
+            tin[0] = sin0;
+            tin[1] = sin1;
+            DES_encrypt1((DES_LONG *)tin, schedule, DES_DECRYPT);
+            tout0 = tin[0] ^ xor0;
+            tout1 = tin[1] ^ xor1;
+            if (length >= 8) {
+                l2c(tout0, out);
+                l2c(tout1, out);
+            } else
+                l2cn(tout0, tout1, out, length);
+            xor0 = tout0 ^ sin0;
+            xor1 = tout1 ^ sin1;
+        }
+    }
+    tin[0] = tin[1] = 0;
+    sin0 = sin1 = xor0 = xor1 = tout0 = tout1 = 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/qud_cksm.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/qud_cksm.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/qud_cksm.c	(revision 331)
@@ -0,0 +1,77 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*
+ * From "Message Authentication" R.R. Jueneman, S.M. Matyas, C.H. Meyer IEEE
+ * Communications Magazine Sept 1985 Vol. 23 No. 9 p 29-40 This module in
+ * only based on the code in this paper and is almost definitely not the same
+ * as the MIT implementation.
+ */
+#include "des_locl.h"
+
+/* bug fix for dos - 7/6/91 - Larry hughes@logos.ucs.indiana.edu */
+#define Q_B0(a) (((DES_LONG)(a)))
+#define Q_B1(a) (((DES_LONG)(a))<<8)
+#define Q_B2(a) (((DES_LONG)(a))<<16)
+#define Q_B3(a) (((DES_LONG)(a))<<24)
+
+/* used to scramble things a bit */
+/* Got the value MIT uses via brute force :-) 2/10/90 eay */
+#define NOISE   ((DES_LONG)83653421L)
+
+DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[],
+                        long length, int out_count, DES_cblock *seed)
+{
+    DES_LONG z0, z1, t0, t1;
+    int i;
+    long l;
+    const unsigned char *cp;
+    DES_LONG *lp;
+
+    if (out_count < 1)
+        out_count = 1;
+    lp = (DES_LONG *)&(output[0])[0];
+
+    z0 = Q_B0((*seed)[0]) | Q_B1((*seed)[1]) | Q_B2((*seed)[2]) |
+        Q_B3((*seed)[3]);
+    z1 = Q_B0((*seed)[4]) | Q_B1((*seed)[5]) | Q_B2((*seed)[6]) |
+        Q_B3((*seed)[7]);
+
+    for (i = 0; ((i < 4) && (i < out_count)); i++) {
+        cp = input;
+        l = length;
+        while (l > 0) {
+            if (l > 1) {
+                t0 = (DES_LONG)(*(cp++));
+                t0 |= (DES_LONG)Q_B1(*(cp++));
+                l--;
+            } else
+                t0 = (DES_LONG)(*(cp++));
+            l--;
+            /* add */
+            t0 += z0;
+            t0 &= 0xffffffffL;
+            t1 = z1;
+            /* square, well sort of square */
+            z0 = ((((t0 * t0) & 0xffffffffL) + ((t1 * t1) & 0xffffffffL))
+                  & 0xffffffffL) % 0x7fffffffL;
+            z1 = ((t0 * ((t1 + NOISE) & 0xffffffffL)) & 0xffffffffL) %
+                0x7fffffffL;
+        }
+        if (lp != NULL) {
+            /*
+             * The MIT library assumes that the checksum is composed of
+             * 2*out_count 32 bit ints
+             */
+            *lp++ = z0;
+            *lp++ = z1;
+        }
+    }
+    return (z0);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/rand_key.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/rand_key.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/rand_key.c	(revision 331)
@@ -0,0 +1,21 @@
+/*
+ * Copyright 1998-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 <openssl/des.h>
+#include <openssl/rand.h>
+
+int DES_random_key(DES_cblock *ret)
+{
+    do {
+        if (RAND_bytes((unsigned char *)ret, sizeof(DES_cblock)) != 1)
+            return (0);
+    } while (DES_is_weak_key(ret));
+    DES_set_odd_parity(ret);
+    return (1);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/rpc_des.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/rpc_des.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/rpc_des.h	(revision 331)
@@ -0,0 +1,76 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*  @(#)des.h   2.2 88/08/10 4.0 RPCSRC; from 2.7 88/02/08 SMI  */
+/*-
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*
+ * Generic DES driver interface
+ * Keep this file hardware independent!
+ * Copyright (c) 1986 by Sun Microsystems, Inc.
+ */
+
+#define DES_MAXLEN      65536   /* maximum # of bytes to encrypt */
+#define DES_QUICKLEN    16      /* maximum # of bytes to encrypt quickly */
+
+enum desdir { ENCRYPT, DECRYPT };
+enum desmode { CBC, ECB };
+
+/*
+ * parameters to ioctl call
+ */
+struct desparams {
+    unsigned char des_key[8];   /* key (with low bit parity) */
+    enum desdir des_dir;        /* direction */
+    enum desmode des_mode;      /* mode */
+    unsigned char des_ivec[8];  /* input vector */
+    unsigned des_len;           /* number of bytes to crypt */
+    union {
+        unsigned char UDES_data[DES_QUICKLEN];
+        unsigned char *UDES_buf;
+    } UDES;
+#define des_data UDES.UDES_data /* direct data here if quick */
+#define des_buf  UDES.UDES_buf  /* otherwise, pointer to data */
+};
+
+/*
+ * Encrypt an arbitrary sized buffer
+ */
+#define DESIOCBLOCK     _IOWR('d', 6, struct desparams)
+
+/*
+ * Encrypt of small amount of data, quickly
+ */
+#define DESIOCQUICK     _IOWR('d', 7, struct desparams)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/rpc_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/rpc_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/rpc_enc.c	(revision 331)
@@ -0,0 +1,30 @@
+/*
+ * Copyright 1995-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 "rpc_des.h"
+#include "des_locl.h"
+
+int _des_crypt(char *buf, int len, struct desparams *desp);
+int _des_crypt(char *buf, int len, struct desparams *desp)
+{
+    DES_key_schedule ks;
+    int enc;
+
+    DES_set_key_unchecked(&desp->des_key, &ks);
+    enc = (desp->des_dir == ENCRYPT) ? DES_ENCRYPT : DES_DECRYPT;
+
+    if (desp->des_mode == CBC)
+        DES_ecb_encrypt((const_DES_cblock *)desp->UDES.UDES_buf,
+                        (DES_cblock *)desp->UDES.UDES_buf, &ks, enc);
+    else {
+        DES_ncbc_encrypt(desp->UDES.UDES_buf, desp->UDES.UDES_buf,
+                         len, &ks, &desp->des_ivec, enc);
+    }
+    return (1);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/set_key.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/set_key.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/set_key.c	(revision 331)
@@ -0,0 +1,389 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*-
+ * set_key.c v 1.4 eay 24/9/91
+ * 1.4 Speed up by 400% :-)
+ * 1.3 added register declarations.
+ * 1.2 unrolled make_key_sched a bit more
+ * 1.1 added norm_expand_bits
+ * 1.0 First working version
+ */
+#include <openssl/crypto.h>
+#include "des_locl.h"
+
+OPENSSL_IMPLEMENT_GLOBAL(int, DES_check_key, 0)
+                                                    /*
+                                                     * defaults to false
+                                                     */
+static const unsigned char odd_parity[256] = {
+    1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
+    16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
+    32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
+    49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
+    64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
+    81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
+    97, 97, 98, 98, 100, 100, 103, 103, 104, 104, 107, 107, 109, 109, 110,
+    110,
+    112, 112, 115, 115, 117, 117, 118, 118, 121, 121, 122, 122, 124, 124, 127,
+    127,
+    128, 128, 131, 131, 133, 133, 134, 134, 137, 137, 138, 138, 140, 140, 143,
+    143,
+    145, 145, 146, 146, 148, 148, 151, 151, 152, 152, 155, 155, 157, 157, 158,
+    158,
+    161, 161, 162, 162, 164, 164, 167, 167, 168, 168, 171, 171, 173, 173, 174,
+    174,
+    176, 176, 179, 179, 181, 181, 182, 182, 185, 185, 186, 186, 188, 188, 191,
+    191,
+    193, 193, 194, 194, 196, 196, 199, 199, 200, 200, 203, 203, 205, 205, 206,
+    206,
+    208, 208, 211, 211, 213, 213, 214, 214, 217, 217, 218, 218, 220, 220, 223,
+    223,
+    224, 224, 227, 227, 229, 229, 230, 230, 233, 233, 234, 234, 236, 236, 239,
+    239,
+    241, 241, 242, 242, 244, 244, 247, 247, 248, 248, 251, 251, 253, 253, 254,
+    254
+};
+
+void DES_set_odd_parity(DES_cblock *key)
+{
+    unsigned int i;
+
+    for (i = 0; i < DES_KEY_SZ; i++)
+        (*key)[i] = odd_parity[(*key)[i]];
+}
+
+int DES_check_key_parity(const_DES_cblock *key)
+{
+    unsigned int i;
+
+    for (i = 0; i < DES_KEY_SZ; i++) {
+        if ((*key)[i] != odd_parity[(*key)[i]])
+            return (0);
+    }
+    return (1);
+}
+
+/*-
+ * Weak and semi weak keys as taken from
+ * %A D.W. Davies
+ * %A W.L. Price
+ * %T Security for Computer Networks
+ * %I John Wiley & Sons
+ * %D 1984
+ * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
+ * (and actual cblock values).
+ */
+#define NUM_WEAK_KEY    16
+static const DES_cblock weak_keys[NUM_WEAK_KEY] = {
+    /* weak keys */
+    {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
+    {0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE},
+    {0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E},
+    {0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1},
+    /* semi-weak keys */
+    {0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE},
+    {0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01},
+    {0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1},
+    {0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E},
+    {0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1},
+    {0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01},
+    {0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE},
+    {0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E},
+    {0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E},
+    {0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01},
+    {0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE},
+    {0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1}
+};
+
+int DES_is_weak_key(const_DES_cblock *key)
+{
+    int i;
+
+    for (i = 0; i < NUM_WEAK_KEY; i++)
+        /*
+         * Added == 0 to comparison, I obviously don't run this section very
+         * often :-(, thanks to engineering@MorningStar.Com for the fix eay
+         * 93/06/29 Another problem, I was comparing only the first 4 bytes,
+         * 97/03/18
+         */
+        if (memcmp(weak_keys[i], key, sizeof(DES_cblock)) == 0)
+            return (1);
+    return (0);
+}
+
+/*-
+ * NOW DEFINED IN des_local.h
+ * See ecb_encrypt.c for a pseudo description of these macros.
+ * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+ *      (b)^=(t),\
+ *      (a)=((a)^((t)<<(n))))
+ */
+
+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
+        (a)=(a)^(t)^(t>>(16-(n))))
+
+static const DES_LONG des_skb[8][64] = {
+    {
+     /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+     0x00000000L, 0x00000010L, 0x20000000L, 0x20000010L,
+     0x00010000L, 0x00010010L, 0x20010000L, 0x20010010L,
+     0x00000800L, 0x00000810L, 0x20000800L, 0x20000810L,
+     0x00010800L, 0x00010810L, 0x20010800L, 0x20010810L,
+     0x00000020L, 0x00000030L, 0x20000020L, 0x20000030L,
+     0x00010020L, 0x00010030L, 0x20010020L, 0x20010030L,
+     0x00000820L, 0x00000830L, 0x20000820L, 0x20000830L,
+     0x00010820L, 0x00010830L, 0x20010820L, 0x20010830L,
+     0x00080000L, 0x00080010L, 0x20080000L, 0x20080010L,
+     0x00090000L, 0x00090010L, 0x20090000L, 0x20090010L,
+     0x00080800L, 0x00080810L, 0x20080800L, 0x20080810L,
+     0x00090800L, 0x00090810L, 0x20090800L, 0x20090810L,
+     0x00080020L, 0x00080030L, 0x20080020L, 0x20080030L,
+     0x00090020L, 0x00090030L, 0x20090020L, 0x20090030L,
+     0x00080820L, 0x00080830L, 0x20080820L, 0x20080830L,
+     0x00090820L, 0x00090830L, 0x20090820L, 0x20090830L,
+     },
+    {
+     /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
+     0x00000000L, 0x02000000L, 0x00002000L, 0x02002000L,
+     0x00200000L, 0x02200000L, 0x00202000L, 0x02202000L,
+     0x00000004L, 0x02000004L, 0x00002004L, 0x02002004L,
+     0x00200004L, 0x02200004L, 0x00202004L, 0x02202004L,
+     0x00000400L, 0x02000400L, 0x00002400L, 0x02002400L,
+     0x00200400L, 0x02200400L, 0x00202400L, 0x02202400L,
+     0x00000404L, 0x02000404L, 0x00002404L, 0x02002404L,
+     0x00200404L, 0x02200404L, 0x00202404L, 0x02202404L,
+     0x10000000L, 0x12000000L, 0x10002000L, 0x12002000L,
+     0x10200000L, 0x12200000L, 0x10202000L, 0x12202000L,
+     0x10000004L, 0x12000004L, 0x10002004L, 0x12002004L,
+     0x10200004L, 0x12200004L, 0x10202004L, 0x12202004L,
+     0x10000400L, 0x12000400L, 0x10002400L, 0x12002400L,
+     0x10200400L, 0x12200400L, 0x10202400L, 0x12202400L,
+     0x10000404L, 0x12000404L, 0x10002404L, 0x12002404L,
+     0x10200404L, 0x12200404L, 0x10202404L, 0x12202404L,
+     },
+    {
+     /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
+     0x00000000L, 0x00000001L, 0x00040000L, 0x00040001L,
+     0x01000000L, 0x01000001L, 0x01040000L, 0x01040001L,
+     0x00000002L, 0x00000003L, 0x00040002L, 0x00040003L,
+     0x01000002L, 0x01000003L, 0x01040002L, 0x01040003L,
+     0x00000200L, 0x00000201L, 0x00040200L, 0x00040201L,
+     0x01000200L, 0x01000201L, 0x01040200L, 0x01040201L,
+     0x00000202L, 0x00000203L, 0x00040202L, 0x00040203L,
+     0x01000202L, 0x01000203L, 0x01040202L, 0x01040203L,
+     0x08000000L, 0x08000001L, 0x08040000L, 0x08040001L,
+     0x09000000L, 0x09000001L, 0x09040000L, 0x09040001L,
+     0x08000002L, 0x08000003L, 0x08040002L, 0x08040003L,
+     0x09000002L, 0x09000003L, 0x09040002L, 0x09040003L,
+     0x08000200L, 0x08000201L, 0x08040200L, 0x08040201L,
+     0x09000200L, 0x09000201L, 0x09040200L, 0x09040201L,
+     0x08000202L, 0x08000203L, 0x08040202L, 0x08040203L,
+     0x09000202L, 0x09000203L, 0x09040202L, 0x09040203L,
+     },
+    {
+     /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
+     0x00000000L, 0x00100000L, 0x00000100L, 0x00100100L,
+     0x00000008L, 0x00100008L, 0x00000108L, 0x00100108L,
+     0x00001000L, 0x00101000L, 0x00001100L, 0x00101100L,
+     0x00001008L, 0x00101008L, 0x00001108L, 0x00101108L,
+     0x04000000L, 0x04100000L, 0x04000100L, 0x04100100L,
+     0x04000008L, 0x04100008L, 0x04000108L, 0x04100108L,
+     0x04001000L, 0x04101000L, 0x04001100L, 0x04101100L,
+     0x04001008L, 0x04101008L, 0x04001108L, 0x04101108L,
+     0x00020000L, 0x00120000L, 0x00020100L, 0x00120100L,
+     0x00020008L, 0x00120008L, 0x00020108L, 0x00120108L,
+     0x00021000L, 0x00121000L, 0x00021100L, 0x00121100L,
+     0x00021008L, 0x00121008L, 0x00021108L, 0x00121108L,
+     0x04020000L, 0x04120000L, 0x04020100L, 0x04120100L,
+     0x04020008L, 0x04120008L, 0x04020108L, 0x04120108L,
+     0x04021000L, 0x04121000L, 0x04021100L, 0x04121100L,
+     0x04021008L, 0x04121008L, 0x04021108L, 0x04121108L,
+     },
+    {
+     /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+     0x00000000L, 0x10000000L, 0x00010000L, 0x10010000L,
+     0x00000004L, 0x10000004L, 0x00010004L, 0x10010004L,
+     0x20000000L, 0x30000000L, 0x20010000L, 0x30010000L,
+     0x20000004L, 0x30000004L, 0x20010004L, 0x30010004L,
+     0x00100000L, 0x10100000L, 0x00110000L, 0x10110000L,
+     0x00100004L, 0x10100004L, 0x00110004L, 0x10110004L,
+     0x20100000L, 0x30100000L, 0x20110000L, 0x30110000L,
+     0x20100004L, 0x30100004L, 0x20110004L, 0x30110004L,
+     0x00001000L, 0x10001000L, 0x00011000L, 0x10011000L,
+     0x00001004L, 0x10001004L, 0x00011004L, 0x10011004L,
+     0x20001000L, 0x30001000L, 0x20011000L, 0x30011000L,
+     0x20001004L, 0x30001004L, 0x20011004L, 0x30011004L,
+     0x00101000L, 0x10101000L, 0x00111000L, 0x10111000L,
+     0x00101004L, 0x10101004L, 0x00111004L, 0x10111004L,
+     0x20101000L, 0x30101000L, 0x20111000L, 0x30111000L,
+     0x20101004L, 0x30101004L, 0x20111004L, 0x30111004L,
+     },
+    {
+     /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
+     0x00000000L, 0x08000000L, 0x00000008L, 0x08000008L,
+     0x00000400L, 0x08000400L, 0x00000408L, 0x08000408L,
+     0x00020000L, 0x08020000L, 0x00020008L, 0x08020008L,
+     0x00020400L, 0x08020400L, 0x00020408L, 0x08020408L,
+     0x00000001L, 0x08000001L, 0x00000009L, 0x08000009L,
+     0x00000401L, 0x08000401L, 0x00000409L, 0x08000409L,
+     0x00020001L, 0x08020001L, 0x00020009L, 0x08020009L,
+     0x00020401L, 0x08020401L, 0x00020409L, 0x08020409L,
+     0x02000000L, 0x0A000000L, 0x02000008L, 0x0A000008L,
+     0x02000400L, 0x0A000400L, 0x02000408L, 0x0A000408L,
+     0x02020000L, 0x0A020000L, 0x02020008L, 0x0A020008L,
+     0x02020400L, 0x0A020400L, 0x02020408L, 0x0A020408L,
+     0x02000001L, 0x0A000001L, 0x02000009L, 0x0A000009L,
+     0x02000401L, 0x0A000401L, 0x02000409L, 0x0A000409L,
+     0x02020001L, 0x0A020001L, 0x02020009L, 0x0A020009L,
+     0x02020401L, 0x0A020401L, 0x02020409L, 0x0A020409L,
+     },
+    {
+     /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
+     0x00000000L, 0x00000100L, 0x00080000L, 0x00080100L,
+     0x01000000L, 0x01000100L, 0x01080000L, 0x01080100L,
+     0x00000010L, 0x00000110L, 0x00080010L, 0x00080110L,
+     0x01000010L, 0x01000110L, 0x01080010L, 0x01080110L,
+     0x00200000L, 0x00200100L, 0x00280000L, 0x00280100L,
+     0x01200000L, 0x01200100L, 0x01280000L, 0x01280100L,
+     0x00200010L, 0x00200110L, 0x00280010L, 0x00280110L,
+     0x01200010L, 0x01200110L, 0x01280010L, 0x01280110L,
+     0x00000200L, 0x00000300L, 0x00080200L, 0x00080300L,
+     0x01000200L, 0x01000300L, 0x01080200L, 0x01080300L,
+     0x00000210L, 0x00000310L, 0x00080210L, 0x00080310L,
+     0x01000210L, 0x01000310L, 0x01080210L, 0x01080310L,
+     0x00200200L, 0x00200300L, 0x00280200L, 0x00280300L,
+     0x01200200L, 0x01200300L, 0x01280200L, 0x01280300L,
+     0x00200210L, 0x00200310L, 0x00280210L, 0x00280310L,
+     0x01200210L, 0x01200310L, 0x01280210L, 0x01280310L,
+     },
+    {
+     /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
+     0x00000000L, 0x04000000L, 0x00040000L, 0x04040000L,
+     0x00000002L, 0x04000002L, 0x00040002L, 0x04040002L,
+     0x00002000L, 0x04002000L, 0x00042000L, 0x04042000L,
+     0x00002002L, 0x04002002L, 0x00042002L, 0x04042002L,
+     0x00000020L, 0x04000020L, 0x00040020L, 0x04040020L,
+     0x00000022L, 0x04000022L, 0x00040022L, 0x04040022L,
+     0x00002020L, 0x04002020L, 0x00042020L, 0x04042020L,
+     0x00002022L, 0x04002022L, 0x00042022L, 0x04042022L,
+     0x00000800L, 0x04000800L, 0x00040800L, 0x04040800L,
+     0x00000802L, 0x04000802L, 0x00040802L, 0x04040802L,
+     0x00002800L, 0x04002800L, 0x00042800L, 0x04042800L,
+     0x00002802L, 0x04002802L, 0x00042802L, 0x04042802L,
+     0x00000820L, 0x04000820L, 0x00040820L, 0x04040820L,
+     0x00000822L, 0x04000822L, 0x00040822L, 0x04040822L,
+     0x00002820L, 0x04002820L, 0x00042820L, 0x04042820L,
+     0x00002822L, 0x04002822L, 0x00042822L, 0x04042822L,
+     }
+};
+
+int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule)
+{
+    if (DES_check_key) {
+        return DES_set_key_checked(key, schedule);
+    } else {
+        DES_set_key_unchecked(key, schedule);
+        return 0;
+    }
+}
+
+/*-
+ * return 0 if key parity is odd (correct),
+ * return -1 if key parity error,
+ * return -2 if illegal weak key.
+ */
+int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule)
+{
+    if (!DES_check_key_parity(key))
+        return (-1);
+    if (DES_is_weak_key(key))
+        return (-2);
+    DES_set_key_unchecked(key, schedule);
+    return 0;
+}
+
+void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule)
+{
+    static const int shifts2[16] =
+        { 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0 };
+    register DES_LONG c, d, t, s, t2;
+    register const unsigned char *in;
+    register DES_LONG *k;
+    register int i;
+
+#ifdef OPENBSD_DEV_CRYPTO
+    memcpy(schedule->key, key, sizeof schedule->key);
+    schedule->session = NULL;
+#endif
+    k = &schedule->ks->deslong[0];
+    in = &(*key)[0];
+
+    c2l(in, c);
+    c2l(in, d);
+
+    /*
+     * do PC1 in 47 simple operations :-) Thanks to John Fletcher
+     * (john_fletcher@lccmail.ocf.llnl.gov) for the inspiration. :-)
+     */
+    PERM_OP(d, c, t, 4, 0x0f0f0f0fL);
+    HPERM_OP(c, t, -2, 0xcccc0000L);
+    HPERM_OP(d, t, -2, 0xcccc0000L);
+    PERM_OP(d, c, t, 1, 0x55555555L);
+    PERM_OP(c, d, t, 8, 0x00ff00ffL);
+    PERM_OP(d, c, t, 1, 0x55555555L);
+    d = (((d & 0x000000ffL) << 16L) | (d & 0x0000ff00L) |
+         ((d & 0x00ff0000L) >> 16L) | ((c & 0xf0000000L) >> 4L));
+    c &= 0x0fffffffL;
+
+    for (i = 0; i < ITERATIONS; i++) {
+        if (shifts2[i]) {
+            c = ((c >> 2L) | (c << 26L));
+            d = ((d >> 2L) | (d << 26L));
+        } else {
+            c = ((c >> 1L) | (c << 27L));
+            d = ((d >> 1L) | (d << 27L));
+        }
+        c &= 0x0fffffffL;
+        d &= 0x0fffffffL;
+        /*
+         * could be a few less shifts but I am to lazy at this point in time
+         * to investigate
+         */
+        s = des_skb[0][(c) & 0x3f] |
+            des_skb[1][((c >> 6L) & 0x03) | ((c >> 7L) & 0x3c)] |
+            des_skb[2][((c >> 13L) & 0x0f) | ((c >> 14L) & 0x30)] |
+            des_skb[3][((c >> 20L) & 0x01) | ((c >> 21L) & 0x06) |
+                       ((c >> 22L) & 0x38)];
+        t = des_skb[4][(d) & 0x3f] |
+            des_skb[5][((d >> 7L) & 0x03) | ((d >> 8L) & 0x3c)] |
+            des_skb[6][(d >> 15L) & 0x3f] |
+            des_skb[7][((d >> 21L) & 0x0f) | ((d >> 22L) & 0x30)];
+
+        /* table contained 0213 4657 */
+        t2 = ((t << 16L) | (s & 0x0000ffffL)) & 0xffffffffL;
+        *(k++) = ROTATE(t2, 30) & 0xffffffffL;
+
+        t2 = ((s >> 16L) | (t & 0xffff0000L));
+        *(k++) = ROTATE(t2, 26) & 0xffffffffL;
+    }
+}
+
+int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule)
+{
+    return (DES_set_key(key, schedule));
+}
+
+/*-
+#undef des_fixup_key_parity
+void des_fixup_key_parity(des_cblock *key)
+        {
+        des_set_odd_parity(key);
+        }
+*/
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/spr.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/spr.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/spr.h	(revision 331)
@@ -0,0 +1,163 @@
+/*
+ * Copyright 1995-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
+ */
+
+OPENSSL_GLOBAL const DES_LONG DES_SPtrans[8][64] = {
+    {
+        /* nibble 0 */
+        0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
+        0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
+        0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
+        0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
+        0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
+        0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
+        0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
+        0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
+        0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
+        0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
+        0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
+        0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
+        0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
+        0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
+        0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
+        0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
+    },
+    {
+        /* nibble 1 */
+        0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
+        0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
+        0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
+        0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
+        0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
+        0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
+        0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
+        0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
+        0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
+        0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
+        0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
+        0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
+        0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
+        0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
+        0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
+        0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
+    },
+    {
+        /* nibble 2 */
+        0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
+        0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
+        0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
+        0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
+        0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
+        0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
+        0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
+        0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
+        0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
+        0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
+        0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
+        0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
+        0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
+        0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
+        0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
+        0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
+    },
+    {
+        /* nibble 3 */
+        0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
+        0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
+        0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
+        0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
+        0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
+        0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
+        0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
+        0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
+        0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
+        0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
+        0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
+        0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
+        0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
+        0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
+        0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
+        0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
+    },
+    {
+        /* nibble 4 */
+        0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
+        0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
+        0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
+        0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
+        0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
+        0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
+        0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
+        0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
+        0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
+        0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
+        0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
+        0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
+        0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
+        0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
+        0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
+        0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
+    },
+    {
+        /* nibble 5 */
+        0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
+        0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
+        0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
+        0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
+        0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
+        0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
+        0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
+        0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
+        0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
+        0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
+        0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
+        0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
+        0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
+        0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
+        0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
+        0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
+    },
+    {
+        /* nibble 6 */
+        0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
+        0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
+        0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
+        0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
+        0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
+        0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
+        0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
+        0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
+        0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
+        0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
+        0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
+        0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
+        0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
+        0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
+        0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
+        0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
+    },
+    {
+        /* nibble 7 */
+        0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
+        0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
+        0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
+        0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
+        0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
+        0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
+        0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
+        0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
+        0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
+        0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
+        0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
+        0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
+        0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
+        0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
+        0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
+        0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
+    }
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/str2key.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/str2key.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/str2key.c	(revision 331)
@@ -0,0 +1,97 @@
+/*
+ * Copyright 1995-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 <openssl/crypto.h>
+#include "des_locl.h"
+
+void DES_string_to_key(const char *str, DES_cblock *key)
+{
+    DES_key_schedule ks;
+    int i, length;
+
+    memset(key, 0, 8);
+    length = strlen(str);
+#ifdef OLD_STR_TO_KEY
+    for (i = 0; i < length; i++)
+        (*key)[i % 8] ^= (str[i] << 1);
+#else                           /* MIT COMPATIBLE */
+    for (i = 0; i < length; i++) {
+        register unsigned char j = str[i];
+
+        if ((i % 16) < 8)
+            (*key)[i % 8] ^= (j << 1);
+        else {
+            /* Reverse the bit order 05/05/92 eay */
+            j = ((j << 4) & 0xf0) | ((j >> 4) & 0x0f);
+            j = ((j << 2) & 0xcc) | ((j >> 2) & 0x33);
+            j = ((j << 1) & 0xaa) | ((j >> 1) & 0x55);
+            (*key)[7 - (i % 8)] ^= j;
+        }
+    }
+#endif
+    DES_set_odd_parity(key);
+    DES_set_key_unchecked(key, &ks);
+    DES_cbc_cksum((const unsigned char *)str, key, length, &ks, key);
+    OPENSSL_cleanse(&ks, sizeof(ks));
+    DES_set_odd_parity(key);
+}
+
+void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2)
+{
+    DES_key_schedule ks;
+    int i, length;
+
+    memset(key1, 0, 8);
+    memset(key2, 0, 8);
+    length = strlen(str);
+#ifdef OLD_STR_TO_KEY
+    if (length <= 8) {
+        for (i = 0; i < length; i++) {
+            (*key2)[i] = (*key1)[i] = (str[i] << 1);
+        }
+    } else {
+        for (i = 0; i < length; i++) {
+            if ((i / 8) & 1)
+                (*key2)[i % 8] ^= (str[i] << 1);
+            else
+                (*key1)[i % 8] ^= (str[i] << 1);
+        }
+    }
+#else                           /* MIT COMPATIBLE */
+    for (i = 0; i < length; i++) {
+        register unsigned char j = str[i];
+
+        if ((i % 32) < 16) {
+            if ((i % 16) < 8)
+                (*key1)[i % 8] ^= (j << 1);
+            else
+                (*key2)[i % 8] ^= (j << 1);
+        } else {
+            j = ((j << 4) & 0xf0) | ((j >> 4) & 0x0f);
+            j = ((j << 2) & 0xcc) | ((j >> 2) & 0x33);
+            j = ((j << 1) & 0xaa) | ((j >> 1) & 0x55);
+            if ((i % 16) < 8)
+                (*key1)[7 - (i % 8)] ^= j;
+            else
+                (*key2)[7 - (i % 8)] ^= j;
+        }
+    }
+    if (length <= 8)
+        memcpy(key2, key1, 8);
+#endif
+    DES_set_odd_parity(key1);
+    DES_set_odd_parity(key2);
+    DES_set_key_unchecked(key1, &ks);
+    DES_cbc_cksum((const unsigned char *)str, key1, length, &ks, key1);
+    DES_set_key_unchecked(key2, &ks);
+    DES_cbc_cksum((const unsigned char *)str, key2, length, &ks, key2);
+    OPENSSL_cleanse(&ks, sizeof(ks));
+    DES_set_odd_parity(key1);
+    DES_set_odd_parity(key2);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/xcbc_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/xcbc_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/des/xcbc_enc.c	(revision 331)
@@ -0,0 +1,103 @@
+/*
+ * Copyright 1995-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 "des_locl.h"
+
+/* RSA's DESX */
+
+void DES_xcbc_encrypt(const unsigned char *in, unsigned char *out,
+                      long length, DES_key_schedule *schedule,
+                      DES_cblock *ivec, const_DES_cblock *inw,
+                      const_DES_cblock *outw, int enc)
+{
+    register DES_LONG tin0, tin1;
+    register DES_LONG tout0, tout1, xor0, xor1;
+    register DES_LONG inW0, inW1, outW0, outW1;
+    register const unsigned char *in2;
+    register long l = length;
+    DES_LONG tin[2];
+    unsigned char *iv;
+
+    in2 = &(*inw)[0];
+    c2l(in2, inW0);
+    c2l(in2, inW1);
+    in2 = &(*outw)[0];
+    c2l(in2, outW0);
+    c2l(in2, outW1);
+
+    iv = &(*ivec)[0];
+
+    if (enc) {
+        c2l(iv, tout0);
+        c2l(iv, tout1);
+        for (l -= 8; l >= 0; l -= 8) {
+            c2l(in, tin0);
+            c2l(in, tin1);
+            tin0 ^= tout0 ^ inW0;
+            tin[0] = tin0;
+            tin1 ^= tout1 ^ inW1;
+            tin[1] = tin1;
+            DES_encrypt1(tin, schedule, DES_ENCRYPT);
+            tout0 = tin[0] ^ outW0;
+            l2c(tout0, out);
+            tout1 = tin[1] ^ outW1;
+            l2c(tout1, out);
+        }
+        if (l != -8) {
+            c2ln(in, tin0, tin1, l + 8);
+            tin0 ^= tout0 ^ inW0;
+            tin[0] = tin0;
+            tin1 ^= tout1 ^ inW1;
+            tin[1] = tin1;
+            DES_encrypt1(tin, schedule, DES_ENCRYPT);
+            tout0 = tin[0] ^ outW0;
+            l2c(tout0, out);
+            tout1 = tin[1] ^ outW1;
+            l2c(tout1, out);
+        }
+        iv = &(*ivec)[0];
+        l2c(tout0, iv);
+        l2c(tout1, iv);
+    } else {
+        c2l(iv, xor0);
+        c2l(iv, xor1);
+        for (l -= 8; l > 0; l -= 8) {
+            c2l(in, tin0);
+            tin[0] = tin0 ^ outW0;
+            c2l(in, tin1);
+            tin[1] = tin1 ^ outW1;
+            DES_encrypt1(tin, schedule, DES_DECRYPT);
+            tout0 = tin[0] ^ xor0 ^ inW0;
+            tout1 = tin[1] ^ xor1 ^ inW1;
+            l2c(tout0, out);
+            l2c(tout1, out);
+            xor0 = tin0;
+            xor1 = tin1;
+        }
+        if (l != -8) {
+            c2l(in, tin0);
+            tin[0] = tin0 ^ outW0;
+            c2l(in, tin1);
+            tin[1] = tin1 ^ outW1;
+            DES_encrypt1(tin, schedule, DES_DECRYPT);
+            tout0 = tin[0] ^ xor0 ^ inW0;
+            tout1 = tin[1] ^ xor1 ^ inW1;
+            l2cn(tout0, tout1, out, l + 8);
+            xor0 = tin0;
+            xor1 = tin1;
+        }
+
+        iv = &(*ivec)[0];
+        l2c(xor0, iv);
+        l2c(xor1, iv);
+    }
+    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
+    inW0 = inW1 = outW0 = outW1 = 0;
+    tin[0] = tin[1] = 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_ameth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_ameth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_ameth.c	(revision 331)
@@ -0,0 +1,870 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include "dh_locl.h"
+#include <openssl/bn.h>
+#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
+#include <openssl/cms.h>
+
+/*
+ * i2d/d2i like DH parameter functions which use the appropriate routine for
+ * PKCS#3 DH or X9.42 DH.
+ */
+
+static DH *d2i_dhp(const EVP_PKEY *pkey, const unsigned char **pp,
+                   long length)
+{
+    if (pkey->ameth == &dhx_asn1_meth)
+        return d2i_DHxparams(NULL, pp, length);
+    return d2i_DHparams(NULL, pp, length);
+}
+
+static int i2d_dhp(const EVP_PKEY *pkey, const DH *a, unsigned char **pp)
+{
+    if (pkey->ameth == &dhx_asn1_meth)
+        return i2d_DHxparams(a, pp);
+    return i2d_DHparams(a, pp);
+}
+
+static void int_dh_free(EVP_PKEY *pkey)
+{
+    DH_free(pkey->pkey.dh);
+}
+
+static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+{
+    const unsigned char *p, *pm;
+    int pklen, pmlen;
+    int ptype;
+    const void *pval;
+    const ASN1_STRING *pstr;
+    X509_ALGOR *palg;
+    ASN1_INTEGER *public_key = NULL;
+
+    DH *dh = NULL;
+
+    if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
+        return 0;
+    X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+    if (ptype != V_ASN1_SEQUENCE) {
+        DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR);
+        goto err;
+    }
+
+    pstr = pval;
+    pm = pstr->data;
+    pmlen = pstr->length;
+
+    if ((dh = d2i_dhp(pkey, &pm, pmlen)) == NULL) {
+        DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
+        goto err;
+    }
+
+    if ((public_key = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) {
+        DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
+        goto err;
+    }
+
+    /* We have parameters now set public key */
+    if ((dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) {
+        DHerr(DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR);
+        goto err;
+    }
+
+    ASN1_INTEGER_free(public_key);
+    EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
+    return 1;
+
+ err:
+    ASN1_INTEGER_free(public_key);
+    DH_free(dh);
+    return 0;
+
+}
+
+static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
+{
+    DH *dh;
+    int ptype;
+    unsigned char *penc = NULL;
+    int penclen;
+    ASN1_STRING *str;
+    ASN1_INTEGER *pub_key = NULL;
+
+    dh = pkey->pkey.dh;
+
+    str = ASN1_STRING_new();
+    if (str == NULL) {
+        DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    str->length = i2d_dhp(pkey, dh, &str->data);
+    if (str->length <= 0) {
+        DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    ptype = V_ASN1_SEQUENCE;
+
+    pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL);
+    if (!pub_key)
+        goto err;
+
+    penclen = i2d_ASN1_INTEGER(pub_key, &penc);
+
+    ASN1_INTEGER_free(pub_key);
+
+    if (penclen <= 0) {
+        DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
+                               ptype, str, penc, penclen))
+        return 1;
+
+ err:
+    OPENSSL_free(penc);
+    ASN1_STRING_free(str);
+
+    return 0;
+}
+
+/*
+ * PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in that
+ * the AlgorithmIdentifier contains the parameters, the private key is
+ * explicitly included and the pubkey must be recalculated.
+ */
+
+static int dh_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
+{
+    const unsigned char *p, *pm;
+    int pklen, pmlen;
+    int ptype;
+    const void *pval;
+    const ASN1_STRING *pstr;
+    const X509_ALGOR *palg;
+    ASN1_INTEGER *privkey = NULL;
+
+    DH *dh = NULL;
+
+    if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
+        return 0;
+
+    X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+    if (ptype != V_ASN1_SEQUENCE)
+        goto decerr;
+    if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL)
+        goto decerr;
+
+    pstr = pval;
+    pm = pstr->data;
+    pmlen = pstr->length;
+    if ((dh = d2i_dhp(pkey, &pm, pmlen)) == NULL)
+        goto decerr;
+
+    /* We have parameters now set private key */
+    if ((dh->priv_key = BN_secure_new()) == NULL
+        || !ASN1_INTEGER_to_BN(privkey, dh->priv_key)) {
+        DHerr(DH_F_DH_PRIV_DECODE, DH_R_BN_ERROR);
+        goto dherr;
+    }
+    /* Calculate public key */
+    if (!DH_generate_key(dh))
+        goto dherr;
+
+    EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
+
+    ASN1_STRING_clear_free(privkey);
+
+    return 1;
+
+ decerr:
+    DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR);
+ dherr:
+    DH_free(dh);
+    ASN1_STRING_clear_free(privkey);
+    return 0;
+}
+
+static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
+{
+    ASN1_STRING *params = NULL;
+    ASN1_INTEGER *prkey = NULL;
+    unsigned char *dp = NULL;
+    int dplen;
+
+    params = ASN1_STRING_new();
+
+    if (params == NULL) {
+        DHerr(DH_F_DH_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    params->length = i2d_dhp(pkey, pkey->pkey.dh, &params->data);
+    if (params->length <= 0) {
+        DHerr(DH_F_DH_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    params->type = V_ASN1_SEQUENCE;
+
+    /* Get private key into integer */
+    prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL);
+
+    if (!prkey) {
+        DHerr(DH_F_DH_PRIV_ENCODE, DH_R_BN_ERROR);
+        goto err;
+    }
+
+    dplen = i2d_ASN1_INTEGER(prkey, &dp);
+
+    ASN1_STRING_clear_free(prkey);
+    prkey = NULL;
+
+    if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
+                         V_ASN1_SEQUENCE, params, dp, dplen))
+        goto err;
+
+    return 1;
+
+ err:
+    OPENSSL_free(dp);
+    ASN1_STRING_free(params);
+    ASN1_STRING_clear_free(prkey);
+    return 0;
+}
+
+static int dh_param_decode(EVP_PKEY *pkey,
+                           const unsigned char **pder, int derlen)
+{
+    DH *dh;
+
+    if ((dh = d2i_dhp(pkey, pder, derlen)) == NULL) {
+        DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB);
+        return 0;
+    }
+    EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
+    return 1;
+}
+
+static int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
+{
+    return i2d_dhp(pkey, pkey->pkey.dh, pder);
+}
+
+static int do_dh_print(BIO *bp, const DH *x, int indent, int ptype)
+{
+    int reason = ERR_R_BUF_LIB;
+    const char *ktype = NULL;
+    BIGNUM *priv_key, *pub_key;
+
+    if (ptype == 2)
+        priv_key = x->priv_key;
+    else
+        priv_key = NULL;
+
+    if (ptype > 0)
+        pub_key = x->pub_key;
+    else
+        pub_key = NULL;
+
+    if (x->p == NULL || (ptype == 2 && priv_key == NULL)
+            || (ptype > 0 && pub_key == NULL)) {
+        reason = ERR_R_PASSED_NULL_PARAMETER;
+        goto err;
+    }
+
+    if (ptype == 2)
+        ktype = "DH Private-Key";
+    else if (ptype == 1)
+        ktype = "DH Public-Key";
+    else
+        ktype = "DH Parameters";
+
+    BIO_indent(bp, indent, 128);
+    if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0)
+        goto err;
+    indent += 4;
+
+    if (!ASN1_bn_print(bp, "private-key:", priv_key, NULL, indent))
+        goto err;
+    if (!ASN1_bn_print(bp, "public-key:", pub_key, NULL, indent))
+        goto err;
+
+    if (!ASN1_bn_print(bp, "prime:", x->p, NULL, indent))
+        goto err;
+    if (!ASN1_bn_print(bp, "generator:", x->g, NULL, indent))
+        goto err;
+    if (x->q && !ASN1_bn_print(bp, "subgroup order:", x->q, NULL, indent))
+        goto err;
+    if (x->j && !ASN1_bn_print(bp, "subgroup factor:", x->j, NULL, indent))
+        goto err;
+    if (x->seed) {
+        int i;
+        BIO_indent(bp, indent, 128);
+        BIO_puts(bp, "seed:");
+        for (i = 0; i < x->seedlen; i++) {
+            if ((i % 15) == 0) {
+                if (BIO_puts(bp, "\n") <= 0
+                    || !BIO_indent(bp, indent + 4, 128))
+                    goto err;
+            }
+            if (BIO_printf(bp, "%02x%s", x->seed[i],
+                           ((i + 1) == x->seedlen) ? "" : ":") <= 0)
+                goto err;
+        }
+        if (BIO_write(bp, "\n", 1) <= 0)
+            return (0);
+    }
+    if (x->counter && !ASN1_bn_print(bp, "counter:", x->counter, NULL, indent))
+        goto err;
+    if (x->length != 0) {
+        BIO_indent(bp, indent, 128);
+        if (BIO_printf(bp, "recommended-private-length: %d bits\n",
+                       (int)x->length) <= 0)
+            goto err;
+    }
+
+    return 1;
+
+ err:
+    DHerr(DH_F_DO_DH_PRINT, reason);
+    return 0;
+}
+
+static int int_dh_size(const EVP_PKEY *pkey)
+{
+    return (DH_size(pkey->pkey.dh));
+}
+
+static int dh_bits(const EVP_PKEY *pkey)
+{
+    return BN_num_bits(pkey->pkey.dh->p);
+}
+
+static int dh_security_bits(const EVP_PKEY *pkey)
+{
+    return DH_security_bits(pkey->pkey.dh);
+}
+
+static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+    if (BN_cmp(a->pkey.dh->p, b->pkey.dh->p) ||
+        BN_cmp(a->pkey.dh->g, b->pkey.dh->g))
+        return 0;
+    else if (a->ameth == &dhx_asn1_meth) {
+        if (BN_cmp(a->pkey.dh->q, b->pkey.dh->q))
+            return 0;
+    }
+    return 1;
+}
+
+static int int_dh_bn_cpy(BIGNUM **dst, const BIGNUM *src)
+{
+    BIGNUM *a;
+    if (src) {
+        a = BN_dup(src);
+        if (!a)
+            return 0;
+    } else
+        a = NULL;
+    BN_free(*dst);
+    *dst = a;
+    return 1;
+}
+
+static int int_dh_param_copy(DH *to, const DH *from, int is_x942)
+{
+    if (is_x942 == -1)
+        is_x942 = ! !from->q;
+    if (!int_dh_bn_cpy(&to->p, from->p))
+        return 0;
+    if (!int_dh_bn_cpy(&to->g, from->g))
+        return 0;
+    if (is_x942) {
+        if (!int_dh_bn_cpy(&to->q, from->q))
+            return 0;
+        if (!int_dh_bn_cpy(&to->j, from->j))
+            return 0;
+        OPENSSL_free(to->seed);
+        to->seed = NULL;
+        to->seedlen = 0;
+        if (from->seed) {
+            to->seed = OPENSSL_memdup(from->seed, from->seedlen);
+            if (!to->seed)
+                return 0;
+            to->seedlen = from->seedlen;
+        }
+    } else
+        to->length = from->length;
+    return 1;
+}
+
+DH *DHparams_dup(DH *dh)
+{
+    DH *ret;
+    ret = DH_new();
+    if (ret == NULL)
+        return NULL;
+    if (!int_dh_param_copy(ret, dh, -1)) {
+        DH_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+{
+    if (to->pkey.dh == NULL) {
+        to->pkey.dh = DH_new();
+        if (to->pkey.dh == NULL)
+            return 0;
+    }
+    return int_dh_param_copy(to->pkey.dh, from->pkey.dh,
+                             from->ameth == &dhx_asn1_meth);
+}
+
+static int dh_missing_parameters(const EVP_PKEY *a)
+{
+    if (a->pkey.dh == NULL || a->pkey.dh->p == NULL || a->pkey.dh->g == NULL)
+        return 1;
+    return 0;
+}
+
+static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+    if (dh_cmp_parameters(a, b) == 0)
+        return 0;
+    if (BN_cmp(b->pkey.dh->pub_key, a->pkey.dh->pub_key) != 0)
+        return 0;
+    else
+        return 1;
+}
+
+static int dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                          ASN1_PCTX *ctx)
+{
+    return do_dh_print(bp, pkey->pkey.dh, indent, 0);
+}
+
+static int dh_public_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                           ASN1_PCTX *ctx)
+{
+    return do_dh_print(bp, pkey->pkey.dh, indent, 1);
+}
+
+static int dh_private_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                            ASN1_PCTX *ctx)
+{
+    return do_dh_print(bp, pkey->pkey.dh, indent, 2);
+}
+
+int DHparams_print(BIO *bp, const DH *x)
+{
+    return do_dh_print(bp, x, 4, 0);
+}
+
+#ifndef OPENSSL_NO_CMS
+static int dh_cms_decrypt(CMS_RecipientInfo *ri);
+static int dh_cms_encrypt(CMS_RecipientInfo *ri);
+#endif
+
+static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+{
+    switch (op) {
+#ifndef OPENSSL_NO_CMS
+
+    case ASN1_PKEY_CTRL_CMS_ENVELOPE:
+        if (arg1 == 1)
+            return dh_cms_decrypt(arg2);
+        else if (arg1 == 0)
+            return dh_cms_encrypt(arg2);
+        return -2;
+
+    case ASN1_PKEY_CTRL_CMS_RI_TYPE:
+        *(int *)arg2 = CMS_RECIPINFO_AGREE;
+        return 1;
+#endif
+    default:
+        return -2;
+    }
+
+}
+
+const EVP_PKEY_ASN1_METHOD dh_asn1_meth = {
+    EVP_PKEY_DH,
+    EVP_PKEY_DH,
+    0,
+
+    "DH",
+    "OpenSSL PKCS#3 DH method",
+
+    dh_pub_decode,
+    dh_pub_encode,
+    dh_pub_cmp,
+    dh_public_print,
+
+    dh_priv_decode,
+    dh_priv_encode,
+    dh_private_print,
+
+    int_dh_size,
+    dh_bits,
+    dh_security_bits,
+
+    dh_param_decode,
+    dh_param_encode,
+    dh_missing_parameters,
+    dh_copy_parameters,
+    dh_cmp_parameters,
+    dh_param_print,
+    0,
+
+    int_dh_free,
+    0
+};
+
+const EVP_PKEY_ASN1_METHOD dhx_asn1_meth = {
+    EVP_PKEY_DHX,
+    EVP_PKEY_DHX,
+    0,
+
+    "X9.42 DH",
+    "OpenSSL X9.42 DH method",
+
+    dh_pub_decode,
+    dh_pub_encode,
+    dh_pub_cmp,
+    dh_public_print,
+
+    dh_priv_decode,
+    dh_priv_encode,
+    dh_private_print,
+
+    int_dh_size,
+    dh_bits,
+    dh_security_bits,
+
+    dh_param_decode,
+    dh_param_encode,
+    dh_missing_parameters,
+    dh_copy_parameters,
+    dh_cmp_parameters,
+    dh_param_print,
+    0,
+
+    int_dh_free,
+    dh_pkey_ctrl
+};
+
+#ifndef OPENSSL_NO_CMS
+
+static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
+                              X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
+{
+    const ASN1_OBJECT *aoid;
+    int atype;
+    const void *aval;
+    ASN1_INTEGER *public_key = NULL;
+    int rv = 0;
+    EVP_PKEY *pkpeer = NULL, *pk = NULL;
+    DH *dhpeer = NULL;
+    const unsigned char *p;
+    int plen;
+
+    X509_ALGOR_get0(&aoid, &atype, &aval, alg);
+    if (OBJ_obj2nid(aoid) != NID_dhpublicnumber)
+        goto err;
+    /* Only absent parameters allowed in RFC XXXX */
+    if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL)
+        goto err;
+
+    pk = EVP_PKEY_CTX_get0_pkey(pctx);
+    if (!pk)
+        goto err;
+    if (pk->type != EVP_PKEY_DHX)
+        goto err;
+    /* Get parameters from parent key */
+    dhpeer = DHparams_dup(pk->pkey.dh);
+    /* We have parameters now set public key */
+    plen = ASN1_STRING_length(pubkey);
+    p = ASN1_STRING_get0_data(pubkey);
+    if (!p || !plen)
+        goto err;
+
+    if ((public_key = d2i_ASN1_INTEGER(NULL, &p, plen)) == NULL) {
+        DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_DECODE_ERROR);
+        goto err;
+    }
+
+    /* We have parameters now set public key */
+    if ((dhpeer->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) {
+        DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_BN_DECODE_ERROR);
+        goto err;
+    }
+
+    pkpeer = EVP_PKEY_new();
+    if (pkpeer == NULL)
+        goto err;
+    EVP_PKEY_assign(pkpeer, pk->ameth->pkey_id, dhpeer);
+    dhpeer = NULL;
+    if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
+        rv = 1;
+ err:
+    ASN1_INTEGER_free(public_key);
+    EVP_PKEY_free(pkpeer);
+    DH_free(dhpeer);
+    return rv;
+}
+
+static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
+{
+    int rv = 0;
+
+    X509_ALGOR *alg, *kekalg = NULL;
+    ASN1_OCTET_STRING *ukm;
+    const unsigned char *p;
+    unsigned char *dukm = NULL;
+    size_t dukmlen = 0;
+    int keylen, plen;
+    const EVP_CIPHER *kekcipher;
+    EVP_CIPHER_CTX *kekctx;
+
+    if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
+        goto err;
+
+    /*
+     * For DH we only have one OID permissible. If ever any more get defined
+     * we will need something cleverer.
+     */
+    if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH) {
+        DHerr(DH_F_DH_CMS_SET_SHARED_INFO, DH_R_KDF_PARAMETER_ERROR);
+        goto err;
+    }
+
+    if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0)
+        goto err;
+
+    if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0)
+        goto err;
+
+    if (alg->parameter->type != V_ASN1_SEQUENCE)
+        goto err;
+
+    p = alg->parameter->value.sequence->data;
+    plen = alg->parameter->value.sequence->length;
+    kekalg = d2i_X509_ALGOR(NULL, &p, plen);
+    if (!kekalg)
+        goto err;
+    kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
+    if (!kekctx)
+        goto err;
+    kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
+    if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
+        goto err;
+    if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
+        goto err;
+    if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
+        goto err;
+
+    keylen = EVP_CIPHER_CTX_key_length(kekctx);
+    if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
+        goto err;
+    /* Use OBJ_nid2obj to ensure we use built in OID that isn't freed */
+    if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx,
+                                     OBJ_nid2obj(EVP_CIPHER_type(kekcipher)))
+        <= 0)
+        goto err;
+
+    if (ukm) {
+        dukmlen = ASN1_STRING_length(ukm);
+        dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen);
+        if (!dukm)
+            goto err;
+    }
+
+    if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
+        goto err;
+    dukm = NULL;
+
+    rv = 1;
+ err:
+    X509_ALGOR_free(kekalg);
+    OPENSSL_free(dukm);
+    return rv;
+}
+
+static int dh_cms_decrypt(CMS_RecipientInfo *ri)
+{
+    EVP_PKEY_CTX *pctx;
+    pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+    if (!pctx)
+        return 0;
+    /* See if we need to set peer key */
+    if (!EVP_PKEY_CTX_get0_peerkey(pctx)) {
+        X509_ALGOR *alg;
+        ASN1_BIT_STRING *pubkey;
+        if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
+                                                 NULL, NULL, NULL))
+            return 0;
+        if (!alg || !pubkey)
+            return 0;
+        if (!dh_cms_set_peerkey(pctx, alg, pubkey)) {
+            DHerr(DH_F_DH_CMS_DECRYPT, DH_R_PEER_KEY_ERROR);
+            return 0;
+        }
+    }
+    /* Set DH derivation parameters and initialise unwrap context */
+    if (!dh_cms_set_shared_info(pctx, ri)) {
+        DHerr(DH_F_DH_CMS_DECRYPT, DH_R_SHARED_INFO_ERROR);
+        return 0;
+    }
+    return 1;
+}
+
+static int dh_cms_encrypt(CMS_RecipientInfo *ri)
+{
+    EVP_PKEY_CTX *pctx;
+    EVP_PKEY *pkey;
+    EVP_CIPHER_CTX *ctx;
+    int keylen;
+    X509_ALGOR *talg, *wrap_alg = NULL;
+    const ASN1_OBJECT *aoid;
+    ASN1_BIT_STRING *pubkey;
+    ASN1_STRING *wrap_str;
+    ASN1_OCTET_STRING *ukm;
+    unsigned char *penc = NULL, *dukm = NULL;
+    int penclen;
+    size_t dukmlen = 0;
+    int rv = 0;
+    int kdf_type, wrap_nid;
+    const EVP_MD *kdf_md;
+    pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+    if (!pctx)
+        return 0;
+    /* Get ephemeral key */
+    pkey = EVP_PKEY_CTX_get0_pkey(pctx);
+    if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
+                                             NULL, NULL, NULL))
+        goto err;
+    X509_ALGOR_get0(&aoid, NULL, NULL, talg);
+    /* Is everything uninitialised? */
+    if (aoid == OBJ_nid2obj(NID_undef)) {
+        ASN1_INTEGER *pubk = BN_to_ASN1_INTEGER(pkey->pkey.dh->pub_key, NULL);
+        if (!pubk)
+            goto err;
+        /* Set the key */
+
+        penclen = i2d_ASN1_INTEGER(pubk, &penc);
+        ASN1_INTEGER_free(pubk);
+        if (penclen <= 0)
+            goto err;
+        ASN1_STRING_set0(pubkey, penc, penclen);
+        pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+        pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+
+        penc = NULL;
+        X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber),
+                        V_ASN1_UNDEF, NULL);
+    }
+
+    /* See if custom parameters set */
+    kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx);
+    if (kdf_type <= 0)
+        goto err;
+    if (!EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md))
+        goto err;
+
+    if (kdf_type == EVP_PKEY_DH_KDF_NONE) {
+        kdf_type = EVP_PKEY_DH_KDF_X9_42;
+        if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0)
+            goto err;
+    } else if (kdf_type != EVP_PKEY_DH_KDF_X9_42)
+        /* Unknown KDF */
+        goto err;
+    if (kdf_md == NULL) {
+        /* Only SHA1 supported */
+        kdf_md = EVP_sha1();
+        if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0)
+            goto err;
+    } else if (EVP_MD_type(kdf_md) != NID_sha1)
+        /* Unsupported digest */
+        goto err;
+
+    if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
+        goto err;
+
+    /* Get wrap NID */
+    ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
+    wrap_nid = EVP_CIPHER_CTX_type(ctx);
+    if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0)
+        goto err;
+    keylen = EVP_CIPHER_CTX_key_length(ctx);
+
+    /* Package wrap algorithm in an AlgorithmIdentifier */
+
+    wrap_alg = X509_ALGOR_new();
+    if (wrap_alg == NULL)
+        goto err;
+    wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
+    wrap_alg->parameter = ASN1_TYPE_new();
+    if (wrap_alg->parameter == NULL)
+        goto err;
+    if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
+        goto err;
+    if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
+        ASN1_TYPE_free(wrap_alg->parameter);
+        wrap_alg->parameter = NULL;
+    }
+
+    if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
+        goto err;
+
+    if (ukm) {
+        dukmlen = ASN1_STRING_length(ukm);
+        dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen);
+        if (!dukm)
+            goto err;
+    }
+
+    if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
+        goto err;
+    dukm = NULL;
+
+    /*
+     * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
+     * of another AlgorithmIdentifier.
+     */
+    penc = NULL;
+    penclen = i2d_X509_ALGOR(wrap_alg, &penc);
+    if (!penc || !penclen)
+        goto err;
+    wrap_str = ASN1_STRING_new();
+    if (wrap_str == NULL)
+        goto err;
+    ASN1_STRING_set0(wrap_str, penc, penclen);
+    penc = NULL;
+    X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH),
+                    V_ASN1_SEQUENCE, wrap_str);
+
+    rv = 1;
+
+ err:
+    OPENSSL_free(penc);
+    X509_ALGOR_free(wrap_alg);
+    return rv;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_asn1.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_asn1.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_asn1.c	(revision 331)
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2000-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include "dh_locl.h"
+#include <openssl/objects.h>
+#include <openssl/asn1t.h>
+
+/* Override the default free and new methods */
+static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                 void *exarg)
+{
+    if (operation == ASN1_OP_NEW_PRE) {
+        *pval = (ASN1_VALUE *)DH_new();
+        if (*pval != NULL)
+            return 2;
+        return 0;
+    } else if (operation == ASN1_OP_FREE_PRE) {
+        DH_free((DH *)*pval);
+        *pval = NULL;
+        return 2;
+    }
+    return 1;
+}
+
+ASN1_SEQUENCE_cb(DHparams, dh_cb) = {
+        ASN1_SIMPLE(DH, p, BIGNUM),
+        ASN1_SIMPLE(DH, g, BIGNUM),
+        ASN1_OPT(DH, length, ZLONG),
+} ASN1_SEQUENCE_END_cb(DH, DHparams)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams)
+
+/*
+ * Internal only structures for handling X9.42 DH: this gets translated to or
+ * from a DH structure straight away.
+ */
+
+typedef struct {
+    ASN1_BIT_STRING *seed;
+    BIGNUM *counter;
+} int_dhvparams;
+
+typedef struct {
+    BIGNUM *p;
+    BIGNUM *q;
+    BIGNUM *g;
+    BIGNUM *j;
+    int_dhvparams *vparams;
+} int_dhx942_dh;
+
+ASN1_SEQUENCE(DHvparams) = {
+        ASN1_SIMPLE(int_dhvparams, seed, ASN1_BIT_STRING),
+        ASN1_SIMPLE(int_dhvparams, counter, BIGNUM)
+} static_ASN1_SEQUENCE_END_name(int_dhvparams, DHvparams)
+
+ASN1_SEQUENCE(DHxparams) = {
+        ASN1_SIMPLE(int_dhx942_dh, p, BIGNUM),
+        ASN1_SIMPLE(int_dhx942_dh, g, BIGNUM),
+        ASN1_SIMPLE(int_dhx942_dh, q, BIGNUM),
+        ASN1_OPT(int_dhx942_dh, j, BIGNUM),
+        ASN1_OPT(int_dhx942_dh, vparams, DHvparams),
+} static_ASN1_SEQUENCE_END_name(int_dhx942_dh, DHxparams)
+
+int_dhx942_dh *d2i_int_dhx(int_dhx942_dh **a,
+                           const unsigned char **pp, long length);
+int i2d_int_dhx(const int_dhx942_dh *a, unsigned char **pp);
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(int_dhx942_dh, DHxparams, int_dhx)
+
+/* Application public function: read in X9.42 DH parameters into DH structure */
+
+DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length)
+{
+    int_dhx942_dh *dhx = NULL;
+    DH *dh = NULL;
+    dh = DH_new();
+    if (dh == NULL)
+        return NULL;
+    dhx = d2i_int_dhx(NULL, pp, length);
+    if (dhx == NULL) {
+        DH_free(dh);
+        return NULL;
+    }
+
+    if (a) {
+        DH_free(*a);
+        *a = dh;
+    }
+
+    dh->p = dhx->p;
+    dh->q = dhx->q;
+    dh->g = dhx->g;
+    dh->j = dhx->j;
+
+    if (dhx->vparams) {
+        dh->seed = dhx->vparams->seed->data;
+        dh->seedlen = dhx->vparams->seed->length;
+        dh->counter = dhx->vparams->counter;
+        dhx->vparams->seed->data = NULL;
+        ASN1_BIT_STRING_free(dhx->vparams->seed);
+        OPENSSL_free(dhx->vparams);
+        dhx->vparams = NULL;
+    }
+
+    OPENSSL_free(dhx);
+    return dh;
+}
+
+int i2d_DHxparams(const DH *dh, unsigned char **pp)
+{
+    int_dhx942_dh dhx;
+    int_dhvparams dhv;
+    ASN1_BIT_STRING bs;
+    dhx.p = dh->p;
+    dhx.g = dh->g;
+    dhx.q = dh->q;
+    dhx.j = dh->j;
+    if (dh->counter && dh->seed && dh->seedlen > 0) {
+        bs.flags = ASN1_STRING_FLAG_BITS_LEFT;
+        bs.data = dh->seed;
+        bs.length = dh->seedlen;
+        dhv.seed = &bs;
+        dhv.counter = dh->counter;
+        dhx.vparams = &dhv;
+    } else
+        dhx.vparams = NULL;
+
+    return i2d_int_dhx(&dhx, pp);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_check.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_check.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_check.c	(revision 331)
@@ -0,0 +1,183 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include "dh_locl.h"
+
+/*-
+ * Check that p and g are suitable enough
+ *
+ * p is odd
+ * 1 < g < p - 1
+ */
+
+int DH_check_params(const DH *dh, int *ret)
+{
+    int ok = 0;
+    BIGNUM *tmp = NULL;
+    BN_CTX *ctx = NULL;
+
+    *ret = 0;
+    ctx = BN_CTX_new();
+    if (ctx == NULL)
+        goto err;
+    BN_CTX_start(ctx);
+    tmp = BN_CTX_get(ctx);
+    if (tmp == NULL)
+        goto err;
+
+    if (!BN_is_odd(dh->p))
+        *ret |= DH_CHECK_P_NOT_PRIME;
+    if (BN_is_negative(dh->g) || BN_is_zero(dh->g) || BN_is_one(dh->g))
+        *ret |= DH_NOT_SUITABLE_GENERATOR;
+    if (BN_copy(tmp, dh->p) == NULL || !BN_sub_word(tmp, 1))
+        goto err;
+    if (BN_cmp(dh->g, tmp) >= 0)
+        *ret |= DH_NOT_SUITABLE_GENERATOR;
+
+    ok = 1;
+ err:
+    if (ctx != NULL) {
+        BN_CTX_end(ctx);
+        BN_CTX_free(ctx);
+    }
+    return (ok);
+}
+
+/*-
+ * Check that p is a safe prime and
+ * if g is 2, 3 or 5, check that it is a suitable generator
+ * where
+ * for 2, p mod 24 == 11
+ * for 3, p mod 12 == 5
+ * for 5, p mod 10 == 3 or 7
+ * should hold.
+ */
+
+int DH_check(const DH *dh, int *ret)
+{
+    int ok = 0, r;
+    BN_CTX *ctx = NULL;
+    BN_ULONG l;
+    BIGNUM *t1 = NULL, *t2 = NULL;
+
+    *ret = 0;
+    ctx = BN_CTX_new();
+    if (ctx == NULL)
+        goto err;
+    BN_CTX_start(ctx);
+    t1 = BN_CTX_get(ctx);
+    if (t1 == NULL)
+        goto err;
+    t2 = BN_CTX_get(ctx);
+    if (t2 == NULL)
+        goto err;
+
+    if (dh->q) {
+        if (BN_cmp(dh->g, BN_value_one()) <= 0)
+            *ret |= DH_NOT_SUITABLE_GENERATOR;
+        else if (BN_cmp(dh->g, dh->p) >= 0)
+            *ret |= DH_NOT_SUITABLE_GENERATOR;
+        else {
+            /* Check g^q == 1 mod p */
+            if (!BN_mod_exp(t1, dh->g, dh->q, dh->p, ctx))
+                goto err;
+            if (!BN_is_one(t1))
+                *ret |= DH_NOT_SUITABLE_GENERATOR;
+        }
+        r = BN_is_prime_ex(dh->q, BN_prime_checks, ctx, NULL);
+        if (r < 0)
+            goto err;
+        if (!r)
+            *ret |= DH_CHECK_Q_NOT_PRIME;
+        /* Check p == 1 mod q  i.e. q divides p - 1 */
+        if (!BN_div(t1, t2, dh->p, dh->q, ctx))
+            goto err;
+        if (!BN_is_one(t2))
+            *ret |= DH_CHECK_INVALID_Q_VALUE;
+        if (dh->j && BN_cmp(dh->j, t1))
+            *ret |= DH_CHECK_INVALID_J_VALUE;
+
+    } else if (BN_is_word(dh->g, DH_GENERATOR_2)) {
+        l = BN_mod_word(dh->p, 24);
+        if (l == (BN_ULONG)-1)
+            goto err;
+        if (l != 11)
+            *ret |= DH_NOT_SUITABLE_GENERATOR;
+    } else if (BN_is_word(dh->g, DH_GENERATOR_5)) {
+        l = BN_mod_word(dh->p, 10);
+        if (l == (BN_ULONG)-1)
+            goto err;
+        if ((l != 3) && (l != 7))
+            *ret |= DH_NOT_SUITABLE_GENERATOR;
+    } else
+        *ret |= DH_UNABLE_TO_CHECK_GENERATOR;
+
+    r = BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL);
+    if (r < 0)
+        goto err;
+    if (!r)
+        *ret |= DH_CHECK_P_NOT_PRIME;
+    else if (!dh->q) {
+        if (!BN_rshift1(t1, dh->p))
+            goto err;
+        r = BN_is_prime_ex(t1, BN_prime_checks, ctx, NULL);
+        if (r < 0)
+            goto err;
+	if (!r)
+            *ret |= DH_CHECK_P_NOT_SAFE_PRIME;
+    }
+    ok = 1;
+ err:
+    if (ctx != NULL) {
+        BN_CTX_end(ctx);
+        BN_CTX_free(ctx);
+    }
+    return (ok);
+}
+
+int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
+{
+    int ok = 0;
+    BIGNUM *tmp = NULL;
+    BN_CTX *ctx = NULL;
+
+    *ret = 0;
+    ctx = BN_CTX_new();
+    if (ctx == NULL)
+        goto err;
+    BN_CTX_start(ctx);
+    tmp = BN_CTX_get(ctx);
+    if (tmp == NULL || !BN_set_word(tmp, 1))
+        goto err;
+    if (BN_cmp(pub_key, tmp) <= 0)
+        *ret |= DH_CHECK_PUBKEY_TOO_SMALL;
+    if (BN_copy(tmp, dh->p) == NULL || !BN_sub_word(tmp, 1))
+        goto err;
+    if (BN_cmp(pub_key, tmp) >= 0)
+        *ret |= DH_CHECK_PUBKEY_TOO_LARGE;
+
+    if (dh->q != NULL) {
+        /* Check pub_key^q == 1 mod p */
+        if (!BN_mod_exp(tmp, pub_key, dh->q, dh->p, ctx))
+            goto err;
+        if (!BN_is_one(tmp))
+            *ret |= DH_CHECK_PUBKEY_INVALID;
+    }
+
+    ok = 1;
+ err:
+    if (ctx != NULL) {
+        BN_CTX_end(ctx);
+        BN_CTX_free(ctx);
+    }
+    return (ok);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_depr.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_depr.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_depr.c	(revision 331)
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2002-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
+ */
+
+/* This file contains deprecated functions as wrappers to the new ones */
+
+#include <openssl/opensslconf.h>
+#if OPENSSL_API_COMPAT >= 0x00908000L
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <stdio.h>
+# include "internal/cryptlib.h"
+# include <openssl/bn.h>
+# include <openssl/dh.h>
+
+DH *DH_generate_parameters(int prime_len, int generator,
+                           void (*callback) (int, int, void *), void *cb_arg)
+{
+    BN_GENCB *cb;
+    DH *ret = NULL;
+
+    if ((ret = DH_new()) == NULL)
+        return NULL;
+    cb = BN_GENCB_new();
+    if (cb == NULL) {
+        DH_free(ret);
+        return NULL;
+    }
+
+    BN_GENCB_set_old(cb, callback, cb_arg);
+
+    if (DH_generate_parameters_ex(ret, prime_len, generator, cb)) {
+        BN_GENCB_free(cb);
+        return ret;
+    }
+    BN_GENCB_free(cb);
+    DH_free(ret);
+    return NULL;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_err.c	(revision 331)
@@ -0,0 +1,73 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/dh.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_DH,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_DH,0,reason)
+
+static ERR_STRING_DATA DH_str_functs[] = {
+    {ERR_FUNC(DH_F_COMPUTE_KEY), "compute_key"},
+    {ERR_FUNC(DH_F_DHPARAMS_PRINT_FP), "DHparams_print_fp"},
+    {ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS), "dh_builtin_genparams"},
+    {ERR_FUNC(DH_F_DH_CMS_DECRYPT), "dh_cms_decrypt"},
+    {ERR_FUNC(DH_F_DH_CMS_SET_PEERKEY), "dh_cms_set_peerkey"},
+    {ERR_FUNC(DH_F_DH_CMS_SET_SHARED_INFO), "dh_cms_set_shared_info"},
+    {ERR_FUNC(DH_F_DH_METH_DUP), "DH_meth_dup"},
+    {ERR_FUNC(DH_F_DH_METH_NEW), "DH_meth_new"},
+    {ERR_FUNC(DH_F_DH_METH_SET1_NAME), "DH_meth_set1_name"},
+    {ERR_FUNC(DH_F_DH_NEW_METHOD), "DH_new_method"},
+    {ERR_FUNC(DH_F_DH_PARAM_DECODE), "dh_param_decode"},
+    {ERR_FUNC(DH_F_DH_PRIV_DECODE), "dh_priv_decode"},
+    {ERR_FUNC(DH_F_DH_PRIV_ENCODE), "dh_priv_encode"},
+    {ERR_FUNC(DH_F_DH_PUB_DECODE), "dh_pub_decode"},
+    {ERR_FUNC(DH_F_DH_PUB_ENCODE), "dh_pub_encode"},
+    {ERR_FUNC(DH_F_DO_DH_PRINT), "do_dh_print"},
+    {ERR_FUNC(DH_F_GENERATE_KEY), "generate_key"},
+    {ERR_FUNC(DH_F_PKEY_DH_DERIVE), "pkey_dh_derive"},
+    {ERR_FUNC(DH_F_PKEY_DH_KEYGEN), "pkey_dh_keygen"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA DH_str_reasons[] = {
+    {ERR_REASON(DH_R_BAD_GENERATOR), "bad generator"},
+    {ERR_REASON(DH_R_BN_DECODE_ERROR), "bn decode error"},
+    {ERR_REASON(DH_R_BN_ERROR), "bn error"},
+    {ERR_REASON(DH_R_DECODE_ERROR), "decode error"},
+    {ERR_REASON(DH_R_INVALID_PUBKEY), "invalid public key"},
+    {ERR_REASON(DH_R_KDF_PARAMETER_ERROR), "kdf parameter error"},
+    {ERR_REASON(DH_R_KEYS_NOT_SET), "keys not set"},
+    {ERR_REASON(DH_R_MODULUS_TOO_LARGE), "modulus too large"},
+    {ERR_REASON(DH_R_NO_PARAMETERS_SET), "no parameters set"},
+    {ERR_REASON(DH_R_NO_PRIVATE_VALUE), "no private value"},
+    {ERR_REASON(DH_R_PARAMETER_ENCODING_ERROR), "parameter encoding error"},
+    {ERR_REASON(DH_R_PEER_KEY_ERROR), "peer key error"},
+    {ERR_REASON(DH_R_SHARED_INFO_ERROR), "shared info error"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_DH_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(DH_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, DH_str_functs);
+        ERR_load_strings(0, DH_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_gen.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_gen.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_gen.c	(revision 331)
@@ -0,0 +1,130 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*
+ * NB: These functions have been upgraded - the previous prototypes are in
+ * dh_depr.c as wrappers to these ones.  - Geoff
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include "dh_locl.h"
+
+static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
+                                BN_GENCB *cb);
+
+int DH_generate_parameters_ex(DH *ret, int prime_len, int generator,
+                              BN_GENCB *cb)
+{
+    if (ret->meth->generate_params)
+        return ret->meth->generate_params(ret, prime_len, generator, cb);
+    return dh_builtin_genparams(ret, prime_len, generator, cb);
+}
+
+/*-
+ * We generate DH parameters as follows
+ * find a prime q which is prime_len/2 bits long.
+ * p=(2*q)+1 or (p-1)/2 = q
+ * For this case, g is a generator if
+ * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1.
+ * Since the factors of p-1 are q and 2, we just need to check
+ * g^2 mod p != 1 and g^q mod p != 1.
+ *
+ * Having said all that,
+ * there is another special case method for the generators 2, 3 and 5.
+ * for 2, p mod 24 == 11
+ * for 3, p mod 12 == 5  <<<<< does not work for safe primes.
+ * for 5, p mod 10 == 3 or 7
+ *
+ * Thanks to Phil Karn <karn@qualcomm.com> for the pointers about the
+ * special generators and for answering some of my questions.
+ *
+ * I've implemented the second simple method :-).
+ * Since DH should be using a safe prime (both p and q are prime),
+ * this generator function can take a very very long time to run.
+ */
+/*
+ * Actually there is no reason to insist that 'generator' be a generator.
+ * It's just as OK (and in some sense better) to use a generator of the
+ * order-q subgroup.
+ */
+static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
+                                BN_GENCB *cb)
+{
+    BIGNUM *t1, *t2;
+    int g, ok = -1;
+    BN_CTX *ctx = NULL;
+
+    ctx = BN_CTX_new();
+    if (ctx == NULL)
+        goto err;
+    BN_CTX_start(ctx);
+    t1 = BN_CTX_get(ctx);
+    t2 = BN_CTX_get(ctx);
+    if (t1 == NULL || t2 == NULL)
+        goto err;
+
+    /* Make sure 'ret' has the necessary elements */
+    if (!ret->p && ((ret->p = BN_new()) == NULL))
+        goto err;
+    if (!ret->g && ((ret->g = BN_new()) == NULL))
+        goto err;
+
+    if (generator <= 1) {
+        DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
+        goto err;
+    }
+    if (generator == DH_GENERATOR_2) {
+        if (!BN_set_word(t1, 24))
+            goto err;
+        if (!BN_set_word(t2, 11))
+            goto err;
+        g = 2;
+    } else if (generator == DH_GENERATOR_5) {
+        if (!BN_set_word(t1, 10))
+            goto err;
+        if (!BN_set_word(t2, 3))
+            goto err;
+        /*
+         * BN_set_word(t3,7); just have to miss out on these ones :-(
+         */
+        g = 5;
+    } else {
+        /*
+         * in the general case, don't worry if 'generator' is a generator or
+         * not: since we are using safe primes, it will generate either an
+         * order-q or an order-2q group, which both is OK
+         */
+        if (!BN_set_word(t1, 2))
+            goto err;
+        if (!BN_set_word(t2, 1))
+            goto err;
+        g = generator;
+    }
+
+    if (!BN_generate_prime_ex(ret->p, prime_len, 1, t1, t2, cb))
+        goto err;
+    if (!BN_GENCB_call(cb, 3, 0))
+        goto err;
+    if (!BN_set_word(ret->g, g))
+        goto err;
+    ok = 1;
+ err:
+    if (ok == -1) {
+        DHerr(DH_F_DH_BUILTIN_GENPARAMS, ERR_R_BN_LIB);
+        ok = 0;
+    }
+
+    if (ctx != NULL) {
+        BN_CTX_end(ctx);
+        BN_CTX_free(ctx);
+    }
+    return ok;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_kdf.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_kdf.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_kdf.c	(revision 331)
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2013-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 <e_os.h>
+
+#ifndef OPENSSL_NO_CMS
+#include <string.h>
+#include <openssl/dh.h>
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/cms.h>
+
+
+/* Key derivation from X9.42/RFC2631 */
+/* Uses CMS functions, hence the #ifdef wrapper. */
+
+#define DH_KDF_MAX      (1L << 30)
+
+/* Skip past an ASN1 structure: for OBJECT skip content octets too */
+
+static int skip_asn1(unsigned char **pp, long *plen, int exptag)
+{
+    const unsigned char *q = *pp;
+    int i, tag, xclass;
+    long tmplen;
+    i = ASN1_get_object(&q, &tmplen, &tag, &xclass, *plen);
+    if (i & 0x80)
+        return 0;
+    if (tag != exptag || xclass != V_ASN1_UNIVERSAL)
+        return 0;
+    if (tag == V_ASN1_OBJECT)
+        q += tmplen;
+    *plen -= q - *pp;
+    *pp = (unsigned char *)q;
+    return 1;
+}
+
+/*
+ * Encode the DH shared info structure, return an offset to the counter value
+ * so we can update the structure without reencoding it.
+ */
+
+static int dh_sharedinfo_encode(unsigned char **pder, unsigned char **pctr,
+                                ASN1_OBJECT *key_oid, size_t outlen,
+                                const unsigned char *ukm, size_t ukmlen)
+{
+    unsigned char *p;
+    int derlen;
+    long tlen;
+    /* "magic" value to check offset is sane */
+    static unsigned char ctr[4] = { 0xF3, 0x17, 0x22, 0x53 };
+    X509_ALGOR atmp;
+    ASN1_OCTET_STRING ctr_oct, ukm_oct, *pukm_oct;
+    ASN1_TYPE ctr_atype;
+    if (ukmlen > DH_KDF_MAX || outlen > DH_KDF_MAX)
+        return 0;
+    ctr_oct.data = ctr;
+    ctr_oct.length = 4;
+    ctr_oct.flags = 0;
+    ctr_oct.type = V_ASN1_OCTET_STRING;
+    ctr_atype.type = V_ASN1_OCTET_STRING;
+    ctr_atype.value.octet_string = &ctr_oct;
+    atmp.algorithm = key_oid;
+    atmp.parameter = &ctr_atype;
+    if (ukm) {
+        ukm_oct.type = V_ASN1_OCTET_STRING;
+        ukm_oct.flags = 0;
+        ukm_oct.data = (unsigned char *)ukm;
+        ukm_oct.length = ukmlen;
+        pukm_oct = &ukm_oct;
+    } else
+        pukm_oct = NULL;
+    derlen = CMS_SharedInfo_encode(pder, &atmp, pukm_oct, outlen);
+    if (derlen <= 0)
+        return 0;
+    p = *pder;
+    tlen = derlen;
+    if (!skip_asn1(&p, &tlen, V_ASN1_SEQUENCE))
+        return 0;
+    if (!skip_asn1(&p, &tlen, V_ASN1_SEQUENCE))
+        return 0;
+    if (!skip_asn1(&p, &tlen, V_ASN1_OBJECT))
+        return 0;
+    if (!skip_asn1(&p, &tlen, V_ASN1_OCTET_STRING))
+        return 0;
+    if (CRYPTO_memcmp(p, ctr, 4))
+        return 0;
+    *pctr = p;
+    return derlen;
+}
+
+int DH_KDF_X9_42(unsigned char *out, size_t outlen,
+                 const unsigned char *Z, size_t Zlen,
+                 ASN1_OBJECT *key_oid,
+                 const unsigned char *ukm, size_t ukmlen, const EVP_MD *md)
+{
+    EVP_MD_CTX *mctx = NULL;
+    int rv = 0;
+    unsigned int i;
+    size_t mdlen;
+    unsigned char *der = NULL, *ctr;
+    int derlen;
+    if (Zlen > DH_KDF_MAX)
+        return 0;
+    mctx = EVP_MD_CTX_new();
+    if (mctx == NULL)
+        return 0;
+    mdlen = EVP_MD_size(md);
+    derlen = dh_sharedinfo_encode(&der, &ctr, key_oid, outlen, ukm, ukmlen);
+    if (derlen == 0)
+        goto err;
+    for (i = 1;; i++) {
+        unsigned char mtmp[EVP_MAX_MD_SIZE];
+        if (!EVP_DigestInit_ex(mctx, md, NULL)
+            || !EVP_DigestUpdate(mctx, Z, Zlen))
+            goto err;
+        ctr[3] = i & 0xFF;
+        ctr[2] = (i >> 8) & 0xFF;
+        ctr[1] = (i >> 16) & 0xFF;
+        ctr[0] = (i >> 24) & 0xFF;
+        if (!EVP_DigestUpdate(mctx, der, derlen))
+            goto err;
+        if (outlen >= mdlen) {
+            if (!EVP_DigestFinal(mctx, out, NULL))
+                goto err;
+            outlen -= mdlen;
+            if (outlen == 0)
+                break;
+            out += mdlen;
+        } else {
+            if (!EVP_DigestFinal(mctx, mtmp, NULL))
+                goto err;
+            memcpy(out, mtmp, outlen);
+            OPENSSL_cleanse(mtmp, mdlen);
+            break;
+        }
+    }
+    rv = 1;
+ err:
+    OPENSSL_free(der);
+    EVP_MD_CTX_free(mctx);
+    return rv;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_key.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_key.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_key.c	(revision 331)
@@ -0,0 +1,215 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include "dh_locl.h"
+#include "internal/bn_int.h"
+
+static int generate_key(DH *dh);
+static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
+static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
+                         const BIGNUM *a, const BIGNUM *p,
+                         const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+static int dh_init(DH *dh);
+static int dh_finish(DH *dh);
+
+int DH_generate_key(DH *dh)
+{
+    return dh->meth->generate_key(dh);
+}
+
+int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+{
+    return dh->meth->compute_key(key, pub_key, dh);
+}
+
+int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+{
+    int rv, pad;
+    rv = dh->meth->compute_key(key, pub_key, dh);
+    if (rv <= 0)
+        return rv;
+    pad = BN_num_bytes(dh->p) - rv;
+    if (pad > 0) {
+        memmove(key + pad, key, rv);
+        memset(key, 0, pad);
+    }
+    return rv + pad;
+}
+
+static DH_METHOD dh_ossl = {
+    "OpenSSL DH Method",
+    generate_key,
+    compute_key,
+    dh_bn_mod_exp,
+    dh_init,
+    dh_finish,
+    DH_FLAG_FIPS_METHOD,
+    NULL,
+    NULL
+};
+
+const DH_METHOD *DH_OpenSSL(void)
+{
+    return &dh_ossl;
+}
+
+static int generate_key(DH *dh)
+{
+    int ok = 0;
+    int generate_new_key = 0;
+    unsigned l;
+    BN_CTX *ctx;
+    BN_MONT_CTX *mont = NULL;
+    BIGNUM *pub_key = NULL, *priv_key = NULL;
+
+    ctx = BN_CTX_new();
+    if (ctx == NULL)
+        goto err;
+
+    if (dh->priv_key == NULL) {
+        priv_key = BN_secure_new();
+        if (priv_key == NULL)
+            goto err;
+        generate_new_key = 1;
+    } else
+        priv_key = dh->priv_key;
+
+    if (dh->pub_key == NULL) {
+        pub_key = BN_new();
+        if (pub_key == NULL)
+            goto err;
+    } else
+        pub_key = dh->pub_key;
+
+    if (dh->flags & DH_FLAG_CACHE_MONT_P) {
+        mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
+                                      dh->lock, dh->p, ctx);
+        if (!mont)
+            goto err;
+    }
+
+    if (generate_new_key) {
+        if (dh->q) {
+            do {
+                if (!BN_rand_range(priv_key, dh->q))
+                    goto err;
+            }
+            while (BN_is_zero(priv_key) || BN_is_one(priv_key));
+        } else {
+            /* secret exponent length */
+            l = dh->length ? dh->length : BN_num_bits(dh->p) - 1;
+            if (!BN_rand(priv_key, l, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY))
+                goto err;
+        }
+    }
+
+    {
+        BIGNUM *prk = BN_new();
+
+        if (prk == NULL)
+            goto err;
+        BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
+
+        if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) {
+            BN_free(prk);
+            goto err;
+        }
+        /* We MUST free prk before any further use of priv_key */
+        BN_free(prk);
+    }
+
+    dh->pub_key = pub_key;
+    dh->priv_key = priv_key;
+    ok = 1;
+ err:
+    if (ok != 1)
+        DHerr(DH_F_GENERATE_KEY, ERR_R_BN_LIB);
+
+    if (pub_key != dh->pub_key)
+        BN_free(pub_key);
+    if (priv_key != dh->priv_key)
+        BN_free(priv_key);
+    BN_CTX_free(ctx);
+    return (ok);
+}
+
+static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+{
+    BN_CTX *ctx = NULL;
+    BN_MONT_CTX *mont = NULL;
+    BIGNUM *tmp;
+    int ret = -1;
+    int check_result;
+
+    if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) {
+        DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_LARGE);
+        goto err;
+    }
+
+    ctx = BN_CTX_new();
+    if (ctx == NULL)
+        goto err;
+    BN_CTX_start(ctx);
+    tmp = BN_CTX_get(ctx);
+    if (tmp == NULL)
+        goto err;
+
+    if (dh->priv_key == NULL) {
+        DHerr(DH_F_COMPUTE_KEY, DH_R_NO_PRIVATE_VALUE);
+        goto err;
+    }
+
+    if (dh->flags & DH_FLAG_CACHE_MONT_P) {
+        mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
+                                      dh->lock, dh->p, ctx);
+        BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME);
+        if (!mont)
+            goto err;
+    }
+
+    if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) {
+        DHerr(DH_F_COMPUTE_KEY, DH_R_INVALID_PUBKEY);
+        goto err;
+    }
+
+    if (!dh->
+        meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key, dh->p, ctx, mont)) {
+        DHerr(DH_F_COMPUTE_KEY, ERR_R_BN_LIB);
+        goto err;
+    }
+
+    ret = BN_bn2bin(tmp, key);
+ err:
+    if (ctx != NULL) {
+        BN_CTX_end(ctx);
+        BN_CTX_free(ctx);
+    }
+    return (ret);
+}
+
+static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
+                         const BIGNUM *a, const BIGNUM *p,
+                         const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+{
+    return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
+}
+
+static int dh_init(DH *dh)
+{
+    dh->flags |= DH_FLAG_CACHE_MONT_P;
+    return (1);
+}
+
+static int dh_finish(DH *dh)
+{
+    BN_MONT_CTX_free(dh->method_mont_p);
+    return (1);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_lib.c	(revision 331)
@@ -0,0 +1,284 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include "dh_locl.h"
+#include <openssl/engine.h>
+
+static const DH_METHOD *default_DH_method = NULL;
+
+void DH_set_default_method(const DH_METHOD *meth)
+{
+    default_DH_method = meth;
+}
+
+const DH_METHOD *DH_get_default_method(void)
+{
+    if (!default_DH_method)
+        default_DH_method = DH_OpenSSL();
+    return default_DH_method;
+}
+
+int DH_set_method(DH *dh, const DH_METHOD *meth)
+{
+    /*
+     * NB: The caller is specifically setting a method, so it's not up to us
+     * to deal with which ENGINE it comes from.
+     */
+    const DH_METHOD *mtmp;
+    mtmp = dh->meth;
+    if (mtmp->finish)
+        mtmp->finish(dh);
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE_finish(dh->engine);
+    dh->engine = NULL;
+#endif
+    dh->meth = meth;
+    if (meth->init)
+        meth->init(dh);
+    return 1;
+}
+
+DH *DH_new(void)
+{
+    return DH_new_method(NULL);
+}
+
+DH *DH_new_method(ENGINE *engine)
+{
+    DH *ret = OPENSSL_zalloc(sizeof(*ret));
+
+    if (ret == NULL) {
+        DHerr(DH_F_DH_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    ret->references = 1;
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        DHerr(DH_F_DH_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ret);
+        return NULL;
+    }
+
+    ret->meth = DH_get_default_method();
+#ifndef OPENSSL_NO_ENGINE
+    ret->flags = ret->meth->flags;  /* early default init */
+    if (engine) {
+        if (!ENGINE_init(engine)) {
+            DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB);
+            goto err;
+        }
+        ret->engine = engine;
+    } else
+        ret->engine = ENGINE_get_default_DH();
+    if (ret->engine) {
+        ret->meth = ENGINE_get_DH(ret->engine);
+        if (ret->meth == NULL) {
+            DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB);
+            goto err;
+        }
+    }
+#endif
+
+    ret->flags = ret->meth->flags;
+
+    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data))
+        goto err;
+
+    if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
+        DHerr(DH_F_DH_NEW_METHOD, ERR_R_INIT_FAIL);
+err:
+        DH_free(ret);
+        ret = NULL;
+    }
+
+    return ret;
+}
+
+void DH_free(DH *r)
+{
+    int i;
+
+    if (r == NULL)
+        return;
+
+    CRYPTO_atomic_add(&r->references, -1, &i, r->lock);
+    REF_PRINT_COUNT("DH", r);
+    if (i > 0)
+        return;
+    REF_ASSERT_ISNT(i < 0);
+
+    if (r->meth->finish)
+        r->meth->finish(r);
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE_finish(r->engine);
+#endif
+
+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, r, &r->ex_data);
+
+    CRYPTO_THREAD_lock_free(r->lock);
+
+    BN_clear_free(r->p);
+    BN_clear_free(r->g);
+    BN_clear_free(r->q);
+    BN_clear_free(r->j);
+    OPENSSL_free(r->seed);
+    BN_clear_free(r->counter);
+    BN_clear_free(r->pub_key);
+    BN_clear_free(r->priv_key);
+    OPENSSL_free(r);
+}
+
+int DH_up_ref(DH *r)
+{
+    int i;
+
+    if (CRYPTO_atomic_add(&r->references, 1, &i, r->lock) <= 0)
+        return 0;
+
+    REF_PRINT_COUNT("DH", r);
+    REF_ASSERT_ISNT(i < 2);
+    return ((i > 1) ? 1 : 0);
+}
+
+int DH_set_ex_data(DH *d, int idx, void *arg)
+{
+    return (CRYPTO_set_ex_data(&d->ex_data, idx, arg));
+}
+
+void *DH_get_ex_data(DH *d, int idx)
+{
+    return (CRYPTO_get_ex_data(&d->ex_data, idx));
+}
+
+int DH_bits(const DH *dh)
+{
+    return BN_num_bits(dh->p);
+}
+
+int DH_size(const DH *dh)
+{
+    return (BN_num_bytes(dh->p));
+}
+
+int DH_security_bits(const DH *dh)
+{
+    int N;
+    if (dh->q)
+        N = BN_num_bits(dh->q);
+    else if (dh->length)
+        N = dh->length;
+    else
+        N = -1;
+    return BN_security_bits(BN_num_bits(dh->p), N);
+}
+
+
+void DH_get0_pqg(const DH *dh,
+                 const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
+{
+    if (p != NULL)
+        *p = dh->p;
+    if (q != NULL)
+        *q = dh->q;
+    if (g != NULL)
+        *g = dh->g;
+}
+
+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;
+}
+
+long DH_get_length(const DH *dh)
+{
+    return dh->length;
+}
+
+int DH_set_length(DH *dh, long length)
+{
+    dh->length = length;
+    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_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
+{
+    /* If the field pub_key in dh is NULL, the corresponding input
+     * parameters MUST be non-NULL.  The priv_key field may
+     * be left NULL.
+     */
+    if (dh->pub_key == NULL && pub_key == NULL)
+        return 0;
+
+    if (pub_key != NULL) {
+        BN_free(dh->pub_key);
+        dh->pub_key = pub_key;
+    }
+    if (priv_key != NULL) {
+        BN_free(dh->priv_key);
+        dh->priv_key = priv_key;
+    }
+
+    return 1;
+}
+
+void DH_clear_flags(DH *dh, int flags)
+{
+    dh->flags &= ~flags;
+}
+
+int DH_test_flags(const DH *dh, int flags)
+{
+    return dh->flags & flags;
+}
+
+void DH_set_flags(DH *dh, int flags)
+{
+    dh->flags |= flags;
+}
+
+ENGINE *DH_get0_engine(DH *dh)
+{
+    return dh->engine;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_locl.h	(revision 331)
@@ -0,0 +1,56 @@
+/*
+ * 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 <openssl/dh.h>
+
+struct dh_st {
+    /*
+     * This first argument is used to pick up errors when a DH is passed
+     * instead of a EVP_PKEY
+     */
+    int pad;
+    int version;
+    BIGNUM *p;
+    BIGNUM *g;
+    long length;                /* optional */
+    BIGNUM *pub_key;            /* g^x % p */
+    BIGNUM *priv_key;           /* x */
+    int flags;
+    BN_MONT_CTX *method_mont_p;
+    /* Place holders if we want to do X9.42 DH */
+    BIGNUM *q;
+    BIGNUM *j;
+    unsigned char *seed;
+    int seedlen;
+    BIGNUM *counter;
+    int references;
+    CRYPTO_EX_DATA ex_data;
+    const DH_METHOD *meth;
+    ENGINE *engine;
+    CRYPTO_RWLOCK *lock;
+};
+
+struct dh_method {
+    char *name;
+    /* Methods here */
+    int (*generate_key) (DH *dh);
+    int (*compute_key) (unsigned char *key, const BIGNUM *pub_key, DH *dh);
+
+    /* Can be null */
+    int (*bn_mod_exp) (const DH *dh, BIGNUM *r, const BIGNUM *a,
+                       const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+                       BN_MONT_CTX *m_ctx);
+    int (*init) (DH *dh);
+    int (*finish) (DH *dh);
+    int flags;
+    char *app_data;
+    /* If this is non-NULL, it will be used to generate parameters */
+    int (*generate_params) (DH *dh, int prime_len, int generator,
+                            BN_GENCB *cb);
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_meth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_meth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_meth.c	(revision 331)
@@ -0,0 +1,173 @@
+/*
+ * 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 "dh_locl.h"
+#include <string.h>
+#include <openssl/err.h>
+
+DH_METHOD *DH_meth_new(const char *name, int flags)
+{
+    DH_METHOD *dhm = OPENSSL_zalloc(sizeof(*dhm));
+
+    if (dhm != NULL) {
+        dhm->flags = flags;
+
+        dhm->name = OPENSSL_strdup(name);
+        if (dhm->name != NULL)
+            return dhm;
+
+        OPENSSL_free(dhm);
+    }
+
+    DHerr(DH_F_DH_METH_NEW, ERR_R_MALLOC_FAILURE);
+    return NULL;
+}
+
+void DH_meth_free(DH_METHOD *dhm)
+{
+    if (dhm != NULL) {
+        OPENSSL_free(dhm->name);
+        OPENSSL_free(dhm);
+    }
+}
+
+DH_METHOD *DH_meth_dup(const DH_METHOD *dhm)
+{
+    DH_METHOD *ret = OPENSSL_malloc(sizeof(*ret));
+
+    if (ret != NULL) {
+        memcpy(ret, dhm, sizeof(*dhm));
+
+        ret->name = OPENSSL_strdup(dhm->name);
+        if (ret->name != NULL)
+            return ret;
+
+        OPENSSL_free(ret);
+    }
+
+    DHerr(DH_F_DH_METH_DUP, ERR_R_MALLOC_FAILURE);
+    return NULL;
+}
+
+const char *DH_meth_get0_name(const DH_METHOD *dhm)
+{
+    return dhm->name;
+}
+
+int DH_meth_set1_name(DH_METHOD *dhm, const char *name)
+{
+    char *tmpname = OPENSSL_strdup(name);
+
+    if (tmpname == NULL) {
+        DHerr(DH_F_DH_METH_SET1_NAME, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    OPENSSL_free(dhm->name);
+    dhm->name = tmpname;
+
+    return 1;
+}
+
+int DH_meth_get_flags(DH_METHOD *dhm)
+{
+    return dhm->flags;
+}
+
+int DH_meth_set_flags(DH_METHOD *dhm, int flags)
+{
+    dhm->flags = flags;
+    return 1;
+}
+
+void *DH_meth_get0_app_data(const DH_METHOD *dhm)
+{
+    return dhm->app_data;
+}
+
+int DH_meth_set0_app_data(DH_METHOD *dhm, void *app_data)
+{
+    dhm->app_data = app_data;
+    return 1;
+}
+
+int (*DH_meth_get_generate_key(const DH_METHOD *dhm)) (DH *)
+{
+    return dhm->generate_key;
+}
+
+int DH_meth_set_generate_key(DH_METHOD *dhm, int (*generate_key) (DH *))
+{
+    dhm->generate_key = generate_key;
+    return 1;
+}
+
+int (*DH_meth_get_compute_key(const DH_METHOD *dhm))
+        (unsigned char *key, const BIGNUM *pub_key, DH *dh)
+{
+    return dhm->compute_key;
+}
+
+int DH_meth_set_compute_key(DH_METHOD *dhm,
+        int (*compute_key) (unsigned char *key, const BIGNUM *pub_key, DH *dh))
+{
+    dhm->compute_key = compute_key;
+    return 1;
+}
+
+
+int (*DH_meth_get_bn_mod_exp(const DH_METHOD *dhm))
+    (const DH *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *,
+     BN_CTX *, BN_MONT_CTX *)
+{
+    return dhm->bn_mod_exp;
+}
+
+int DH_meth_set_bn_mod_exp(DH_METHOD *dhm,
+    int (*bn_mod_exp) (const DH *, BIGNUM *, const BIGNUM *, const BIGNUM *,
+                       const BIGNUM *, BN_CTX *, BN_MONT_CTX *))
+{
+    dhm->bn_mod_exp = bn_mod_exp;
+    return 1;
+}
+
+int (*DH_meth_get_init(const DH_METHOD *dhm))(DH *)
+{
+    return dhm->init;
+}
+
+int DH_meth_set_init(DH_METHOD *dhm, int (*init)(DH *))
+{
+    dhm->init = init;
+    return 1;
+}
+
+int (*DH_meth_get_finish(const DH_METHOD *dhm)) (DH *)
+{
+    return dhm->finish;
+}
+
+int DH_meth_set_finish(DH_METHOD *dhm, int (*finish) (DH *))
+{
+    dhm->finish = finish;
+    return 1;
+}
+
+int (*DH_meth_get_generate_params(const DH_METHOD *dhm))
+        (DH *, int, int, BN_GENCB *)
+{
+    return dhm->generate_params;
+}
+
+int DH_meth_set_generate_params(DH_METHOD *dhm,
+        int (*generate_params) (DH *, int, int, BN_GENCB *))
+{
+    dhm->generate_params = generate_params;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_pmeth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_pmeth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_pmeth.c	(revision 331)
@@ -0,0 +1,501 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/evp.h>
+#include "dh_locl.h"
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/objects.h>
+#include "internal/evp_int.h"
+
+/* DH pkey context structure */
+
+typedef struct {
+    /* Parameter gen parameters */
+    int prime_len;
+    int generator;
+    int use_dsa;
+    int subprime_len;
+    /* message digest used for parameter generation */
+    const EVP_MD *md;
+    int rfc5114_param;
+    /* Keygen callback info */
+    int gentmp[2];
+    /* KDF (if any) to use for DH */
+    char kdf_type;
+    /* OID to use for KDF */
+    ASN1_OBJECT *kdf_oid;
+    /* Message digest to use for key derivation */
+    const EVP_MD *kdf_md;
+    /* User key material */
+    unsigned char *kdf_ukm;
+    size_t kdf_ukmlen;
+    /* KDF output length */
+    size_t kdf_outlen;
+} DH_PKEY_CTX;
+
+static int pkey_dh_init(EVP_PKEY_CTX *ctx)
+{
+    DH_PKEY_CTX *dctx;
+
+    dctx = OPENSSL_zalloc(sizeof(*dctx));
+    if (dctx == NULL)
+        return 0;
+    dctx->prime_len = 1024;
+    dctx->subprime_len = -1;
+    dctx->generator = 2;
+    dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
+
+    ctx->data = dctx;
+    ctx->keygen_info = dctx->gentmp;
+    ctx->keygen_info_count = 2;
+
+    return 1;
+}
+
+static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
+{
+    DH_PKEY_CTX *dctx = ctx->data;
+    if (dctx != NULL) {
+        OPENSSL_free(dctx->kdf_ukm);
+        ASN1_OBJECT_free(dctx->kdf_oid);
+        OPENSSL_free(dctx);
+    }
+}
+
+
+static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+{
+    DH_PKEY_CTX *dctx, *sctx;
+    if (!pkey_dh_init(dst))
+        return 0;
+    sctx = src->data;
+    dctx = dst->data;
+    dctx->prime_len = sctx->prime_len;
+    dctx->subprime_len = sctx->subprime_len;
+    dctx->generator = sctx->generator;
+    dctx->use_dsa = sctx->use_dsa;
+    dctx->md = sctx->md;
+    dctx->rfc5114_param = sctx->rfc5114_param;
+
+    dctx->kdf_type = sctx->kdf_type;
+    dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
+    if (dctx->kdf_oid == NULL)
+        return 0;
+    dctx->kdf_md = sctx->kdf_md;
+    if (sctx->kdf_ukm != NULL) {
+        dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
+        if (dctx->kdf_ukm == NULL)
+          return 0;
+        dctx->kdf_ukmlen = sctx->kdf_ukmlen;
+    }
+    dctx->kdf_outlen = sctx->kdf_outlen;
+    return 1;
+}
+
+static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+    DH_PKEY_CTX *dctx = ctx->data;
+    switch (type) {
+    case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
+        if (p1 < 256)
+            return -2;
+        dctx->prime_len = p1;
+        return 1;
+
+    case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
+        if (dctx->use_dsa == 0)
+            return -2;
+        dctx->subprime_len = p1;
+        return 1;
+
+    case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
+        if (dctx->use_dsa)
+            return -2;
+        dctx->generator = p1;
+        return 1;
+
+    case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
+#ifdef OPENSSL_NO_DSA
+        if (p1 != 0)
+            return -2;
+#else
+        if (p1 < 0 || p1 > 2)
+            return -2;
+#endif
+        dctx->use_dsa = p1;
+        return 1;
+
+    case EVP_PKEY_CTRL_DH_RFC5114:
+        if (p1 < 1 || p1 > 3)
+            return -2;
+        dctx->rfc5114_param = p1;
+        return 1;
+
+    case EVP_PKEY_CTRL_PEER_KEY:
+        /* Default behaviour is OK */
+        return 1;
+
+    case EVP_PKEY_CTRL_DH_KDF_TYPE:
+        if (p1 == -2)
+            return dctx->kdf_type;
+#ifdef OPENSSL_NO_CMS
+        if (p1 != EVP_PKEY_DH_KDF_NONE)
+#else
+        if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
+#endif
+            return -2;
+        dctx->kdf_type = p1;
+        return 1;
+
+    case EVP_PKEY_CTRL_DH_KDF_MD:
+        dctx->kdf_md = p2;
+        return 1;
+
+    case EVP_PKEY_CTRL_GET_DH_KDF_MD:
+        *(const EVP_MD **)p2 = dctx->kdf_md;
+        return 1;
+
+    case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
+        if (p1 <= 0)
+            return -2;
+        dctx->kdf_outlen = (size_t)p1;
+        return 1;
+
+    case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
+        *(int *)p2 = dctx->kdf_outlen;
+        return 1;
+
+    case EVP_PKEY_CTRL_DH_KDF_UKM:
+        OPENSSL_free(dctx->kdf_ukm);
+        dctx->kdf_ukm = p2;
+        if (p2)
+            dctx->kdf_ukmlen = p1;
+        else
+            dctx->kdf_ukmlen = 0;
+        return 1;
+
+    case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
+        *(unsigned char **)p2 = dctx->kdf_ukm;
+        return dctx->kdf_ukmlen;
+
+    case EVP_PKEY_CTRL_DH_KDF_OID:
+        ASN1_OBJECT_free(dctx->kdf_oid);
+        dctx->kdf_oid = p2;
+        return 1;
+
+    case EVP_PKEY_CTRL_GET_DH_KDF_OID:
+        *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
+        return 1;
+
+    default:
+        return -2;
+
+    }
+}
+
+static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
+                            const char *type, const char *value)
+{
+    if (strcmp(type, "dh_paramgen_prime_len") == 0) {
+        int len;
+        len = atoi(value);
+        return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
+    }
+    if (strcmp(type, "dh_rfc5114") == 0) {
+        DH_PKEY_CTX *dctx = ctx->data;
+        int len;
+        len = atoi(value);
+        if (len < 0 || len > 3)
+            return -2;
+        dctx->rfc5114_param = len;
+        return 1;
+    }
+    if (strcmp(type, "dh_paramgen_generator") == 0) {
+        int len;
+        len = atoi(value);
+        return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
+    }
+    if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
+        int len;
+        len = atoi(value);
+        return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
+    }
+    if (strcmp(type, "dh_paramgen_type") == 0) {
+        int typ;
+        typ = atoi(value);
+        return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
+    }
+    return -2;
+}
+
+#ifndef OPENSSL_NO_DSA
+
+extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
+                                const EVP_MD *evpmd,
+                                const unsigned char *seed_in, size_t seed_len,
+                                unsigned char *seed_out, int *counter_ret,
+                                unsigned long *h_ret, BN_GENCB *cb);
+
+extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
+                                 const EVP_MD *evpmd,
+                                 const unsigned char *seed_in,
+                                 size_t seed_len, int idx,
+                                 unsigned char *seed_out, int *counter_ret,
+                                 unsigned long *h_ret, BN_GENCB *cb);
+
+static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
+{
+    DSA *ret;
+    int rv = 0;
+    int prime_len = dctx->prime_len;
+    int subprime_len = dctx->subprime_len;
+    const EVP_MD *md = dctx->md;
+    if (dctx->use_dsa > 2)
+        return NULL;
+    ret = DSA_new();
+    if (ret == NULL)
+        return NULL;
+    if (subprime_len == -1) {
+        if (prime_len >= 2048)
+            subprime_len = 256;
+        else
+            subprime_len = 160;
+    }
+    if (md == NULL) {
+        if (prime_len >= 2048)
+            md = EVP_sha256();
+        else
+            md = EVP_sha1();
+    }
+    if (dctx->use_dsa == 1)
+        rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
+                                  NULL, 0, NULL, NULL, NULL, pcb);
+    else if (dctx->use_dsa == 2)
+        rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
+                                   NULL, 0, -1, NULL, NULL, NULL, pcb);
+    if (rv <= 0) {
+        DSA_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+#endif
+
+static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+    DH *dh = NULL;
+    DH_PKEY_CTX *dctx = ctx->data;
+    BN_GENCB *pcb;
+    int ret;
+    if (dctx->rfc5114_param) {
+        switch (dctx->rfc5114_param) {
+        case 1:
+            dh = DH_get_1024_160();
+            break;
+
+        case 2:
+            dh = DH_get_2048_224();
+            break;
+
+        case 3:
+            dh = DH_get_2048_256();
+            break;
+
+        default:
+            return -2;
+        }
+        EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
+        return 1;
+    }
+
+    if (ctx->pkey_gencb) {
+        pcb = BN_GENCB_new();
+        if (pcb == NULL)
+            return 0;
+        evp_pkey_set_cb_translate(pcb, ctx);
+    } else
+        pcb = NULL;
+#ifndef OPENSSL_NO_DSA
+    if (dctx->use_dsa) {
+        DSA *dsa_dh;
+        dsa_dh = dsa_dh_generate(dctx, pcb);
+        BN_GENCB_free(pcb);
+        if (dsa_dh == NULL)
+            return 0;
+        dh = DSA_dup_DH(dsa_dh);
+        DSA_free(dsa_dh);
+        if (!dh)
+            return 0;
+        EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
+        return 1;
+    }
+#endif
+    dh = DH_new();
+    if (dh == NULL) {
+        BN_GENCB_free(pcb);
+        return 0;
+    }
+    ret = DH_generate_parameters_ex(dh,
+                                    dctx->prime_len, dctx->generator, pcb);
+    BN_GENCB_free(pcb);
+    if (ret)
+        EVP_PKEY_assign_DH(pkey, dh);
+    else
+        DH_free(dh);
+    return ret;
+}
+
+static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+    DH *dh = NULL;
+    if (ctx->pkey == NULL) {
+        DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
+        return 0;
+    }
+    dh = DH_new();
+    if (dh == NULL)
+        return 0;
+    EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
+    /* Note: if error return, pkey is freed by parent routine */
+    if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
+        return 0;
+    return DH_generate_key(pkey->pkey.dh);
+}
+
+static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
+                          size_t *keylen)
+{
+    int ret;
+    DH *dh;
+    DH_PKEY_CTX *dctx = ctx->data;
+    BIGNUM *dhpub;
+    if (!ctx->pkey || !ctx->peerkey) {
+        DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
+        return 0;
+    }
+    dh = ctx->pkey->pkey.dh;
+    dhpub = ctx->peerkey->pkey.dh->pub_key;
+    if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
+        if (key == NULL) {
+            *keylen = DH_size(dh);
+            return 1;
+        }
+        ret = DH_compute_key(key, dhpub, dh);
+        if (ret < 0)
+            return ret;
+        *keylen = ret;
+        return 1;
+    }
+#ifndef OPENSSL_NO_CMS
+    else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
+
+        unsigned char *Z = NULL;
+        size_t Zlen = 0;
+        if (!dctx->kdf_outlen || !dctx->kdf_oid)
+            return 0;
+        if (key == NULL) {
+            *keylen = dctx->kdf_outlen;
+            return 1;
+        }
+        if (*keylen != dctx->kdf_outlen)
+            return 0;
+        ret = 0;
+        Zlen = DH_size(dh);
+        Z = OPENSSL_malloc(Zlen);
+        if (Z == NULL) {
+            goto err;
+        }
+        if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
+            goto err;
+        if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
+                          dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
+            goto err;
+        *keylen = dctx->kdf_outlen;
+        ret = 1;
+ err:
+        OPENSSL_clear_free(Z, Zlen);
+        return ret;
+    }
+#endif
+    return 0;
+}
+
+const EVP_PKEY_METHOD dh_pkey_meth = {
+    EVP_PKEY_DH,
+    0,
+    pkey_dh_init,
+    pkey_dh_copy,
+    pkey_dh_cleanup,
+
+    0,
+    pkey_dh_paramgen,
+
+    0,
+    pkey_dh_keygen,
+
+    0,
+    0,
+
+    0,
+    0,
+
+    0, 0,
+
+    0, 0, 0, 0,
+
+    0, 0,
+
+    0, 0,
+
+    0,
+    pkey_dh_derive,
+
+    pkey_dh_ctrl,
+    pkey_dh_ctrl_str
+};
+
+const EVP_PKEY_METHOD dhx_pkey_meth = {
+    EVP_PKEY_DHX,
+    0,
+    pkey_dh_init,
+    pkey_dh_copy,
+    pkey_dh_cleanup,
+
+    0,
+    pkey_dh_paramgen,
+
+    0,
+    pkey_dh_keygen,
+
+    0,
+    0,
+
+    0,
+    0,
+
+    0, 0,
+
+    0, 0, 0, 0,
+
+    0, 0,
+
+    0, 0,
+
+    0,
+    pkey_dh_derive,
+
+    pkey_dh_ctrl,
+    pkey_dh_ctrl_str
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_prn.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_prn.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_prn.c	(revision 331)
@@ -0,0 +1,30 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/dh.h>
+
+#ifndef OPENSSL_NO_STDIO
+int DHparams_print_fp(FILE *fp, const DH *x)
+{
+    BIO *b;
+    int ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        DHerr(DH_F_DHPARAMS_PRINT_FP, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = DHparams_print(b, x);
+    BIO_free(b);
+    return (ret);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_rfc5114.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_rfc5114.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dh/dh_rfc5114.c	(revision 331)
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2011-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include "dh_locl.h"
+#include <openssl/bn.h>
+#include "internal/bn_dh.h"
+
+/*
+ * Macro to make a DH structure from BIGNUM data. NB: although just copying
+ * the BIGNUM static pointers would be more efficient, we can't do that
+ * because they get wiped using BN_clear_free() when DH_free() is called.
+ */
+
+#define make_dh(x) \
+DH *DH_get_##x(void) \
+{ \
+    DH *dh = DH_new(); \
+\
+    if (dh == NULL) \
+        return NULL; \
+    dh->p = BN_dup(&_bignum_dh##x##_p); \
+    dh->g = BN_dup(&_bignum_dh##x##_g); \
+    dh->q = BN_dup(&_bignum_dh##x##_q); \
+    if (dh->p == NULL || dh->q == NULL || dh->g == NULL) {\
+        DH_free(dh); \
+        return NULL; \
+    } \
+    return dh; \
+}
+
+make_dh(1024_160)
+make_dh(2048_224)
+make_dh(2048_256)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_ameth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_ameth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_ameth.c	(revision 331)
@@ -0,0 +1,567 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include "dsa_locl.h"
+#include <openssl/bn.h>
+#include <openssl/cms.h>
+#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
+
+static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+{
+    const unsigned char *p, *pm;
+    int pklen, pmlen;
+    int ptype;
+    const void *pval;
+    const ASN1_STRING *pstr;
+    X509_ALGOR *palg;
+    ASN1_INTEGER *public_key = NULL;
+
+    DSA *dsa = NULL;
+
+    if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
+        return 0;
+    X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+    if (ptype == V_ASN1_SEQUENCE) {
+        pstr = pval;
+        pm = pstr->data;
+        pmlen = pstr->length;
+
+        if ((dsa = d2i_DSAparams(NULL, &pm, pmlen)) == NULL) {
+            DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
+            goto err;
+        }
+
+    } else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF)) {
+        if ((dsa = DSA_new()) == NULL) {
+            DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    } else {
+        DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR);
+        goto err;
+    }
+
+    if ((public_key = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) {
+        DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
+        goto err;
+    }
+
+    if ((dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) {
+        DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR);
+        goto err;
+    }
+
+    ASN1_INTEGER_free(public_key);
+    EVP_PKEY_assign_DSA(pkey, dsa);
+    return 1;
+
+ err:
+    ASN1_INTEGER_free(public_key);
+    DSA_free(dsa);
+    return 0;
+
+}
+
+static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
+{
+    DSA *dsa;
+    int ptype;
+    unsigned char *penc = NULL;
+    int penclen;
+    ASN1_STRING *str = NULL;
+    ASN1_INTEGER *pubint = NULL;
+
+    dsa = pkey->pkey.dsa;
+    if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) {
+        str = ASN1_STRING_new();
+        if (str == NULL) {
+            DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        str->length = i2d_DSAparams(dsa, &str->data);
+        if (str->length <= 0) {
+            DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        ptype = V_ASN1_SEQUENCE;
+    } else
+        ptype = V_ASN1_UNDEF;
+
+    pubint = BN_to_ASN1_INTEGER(dsa->pub_key, NULL);
+
+    if (pubint == NULL) {
+        DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    penclen = i2d_ASN1_INTEGER(pubint, &penc);
+    ASN1_INTEGER_free(pubint);
+
+    if (penclen <= 0) {
+        DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA),
+                               ptype, str, penc, penclen))
+        return 1;
+
+ err:
+    OPENSSL_free(penc);
+    ASN1_STRING_free(str);
+
+    return 0;
+}
+
+/*
+ * In PKCS#8 DSA: you just get a private key integer and parameters in the
+ * AlgorithmIdentifier the pubkey must be recalculated.
+ */
+
+static int dsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
+{
+    const unsigned char *p, *pm;
+    int pklen, pmlen;
+    int ptype;
+    const void *pval;
+    const ASN1_STRING *pstr;
+    const X509_ALGOR *palg;
+    ASN1_INTEGER *privkey = NULL;
+    BN_CTX *ctx = NULL;
+
+    DSA *dsa = NULL;
+
+    int ret = 0;
+
+    if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
+        return 0;
+    X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+    if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL)
+        goto decerr;
+    if (privkey->type == V_ASN1_NEG_INTEGER || ptype != V_ASN1_SEQUENCE)
+        goto decerr;
+
+    pstr = pval;
+    pm = pstr->data;
+    pmlen = pstr->length;
+    if ((dsa = d2i_DSAparams(NULL, &pm, pmlen)) == NULL)
+        goto decerr;
+    /* We have parameters now set private key */
+    if ((dsa->priv_key = BN_secure_new()) == NULL
+        || !ASN1_INTEGER_to_BN(privkey, dsa->priv_key)) {
+        DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR);
+        goto dsaerr;
+    }
+    /* Calculate public key */
+    if ((dsa->pub_key = BN_new()) == NULL) {
+        DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
+        goto dsaerr;
+    }
+    if ((ctx = BN_CTX_new()) == NULL) {
+        DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
+        goto dsaerr;
+    }
+
+    if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) {
+        DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR);
+        goto dsaerr;
+    }
+
+    EVP_PKEY_assign_DSA(pkey, dsa);
+
+    ret = 1;
+    goto done;
+
+ decerr:
+    DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_DECODE_ERROR);
+ dsaerr:
+    DSA_free(dsa);
+ done:
+    BN_CTX_free(ctx);
+    ASN1_STRING_clear_free(privkey);
+    return ret;
+}
+
+static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
+{
+    ASN1_STRING *params = NULL;
+    ASN1_INTEGER *prkey = NULL;
+    unsigned char *dp = NULL;
+    int dplen;
+
+    if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key) {
+        DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_MISSING_PARAMETERS);
+        goto err;
+    }
+
+    params = ASN1_STRING_new();
+
+    if (params == NULL) {
+        DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    params->length = i2d_DSAparams(pkey->pkey.dsa, &params->data);
+    if (params->length <= 0) {
+        DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    params->type = V_ASN1_SEQUENCE;
+
+    /* Get private key into integer */
+    prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);
+
+    if (!prkey) {
+        DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_BN_ERROR);
+        goto err;
+    }
+
+    dplen = i2d_ASN1_INTEGER(prkey, &dp);
+
+    ASN1_STRING_clear_free(prkey);
+    prkey = NULL;
+
+    if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0,
+                         V_ASN1_SEQUENCE, params, dp, dplen))
+        goto err;
+
+    return 1;
+
+ err:
+    OPENSSL_free(dp);
+    ASN1_STRING_free(params);
+    ASN1_STRING_clear_free(prkey);
+    return 0;
+}
+
+static int int_dsa_size(const EVP_PKEY *pkey)
+{
+    return (DSA_size(pkey->pkey.dsa));
+}
+
+static int dsa_bits(const EVP_PKEY *pkey)
+{
+    return DSA_bits(pkey->pkey.dsa);
+}
+
+static int dsa_security_bits(const EVP_PKEY *pkey)
+{
+    return DSA_security_bits(pkey->pkey.dsa);
+}
+
+static int dsa_missing_parameters(const EVP_PKEY *pkey)
+{
+    DSA *dsa;
+    dsa = pkey->pkey.dsa;
+    if (dsa == NULL || dsa->p == NULL || dsa->q == NULL || dsa->g == NULL)
+        return 1;
+    return 0;
+}
+
+static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+{
+    BIGNUM *a;
+
+    if (to->pkey.dsa == NULL) {
+        to->pkey.dsa = DSA_new();
+        if (to->pkey.dsa == NULL)
+            return 0;
+    }
+
+    if ((a = BN_dup(from->pkey.dsa->p)) == NULL)
+        return 0;
+    BN_free(to->pkey.dsa->p);
+    to->pkey.dsa->p = a;
+
+    if ((a = BN_dup(from->pkey.dsa->q)) == NULL)
+        return 0;
+    BN_free(to->pkey.dsa->q);
+    to->pkey.dsa->q = a;
+
+    if ((a = BN_dup(from->pkey.dsa->g)) == NULL)
+        return 0;
+    BN_free(to->pkey.dsa->g);
+    to->pkey.dsa->g = a;
+    return 1;
+}
+
+static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+    if (BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) ||
+        BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) ||
+        BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g))
+        return 0;
+    else
+        return 1;
+}
+
+static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+    if (BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) != 0)
+        return 0;
+    else
+        return 1;
+}
+
+static void int_dsa_free(EVP_PKEY *pkey)
+{
+    DSA_free(pkey->pkey.dsa);
+}
+
+static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype)
+{
+    int ret = 0;
+    const char *ktype = NULL;
+    const BIGNUM *priv_key, *pub_key;
+
+    if (ptype == 2)
+        priv_key = x->priv_key;
+    else
+        priv_key = NULL;
+
+    if (ptype > 0)
+        pub_key = x->pub_key;
+    else
+        pub_key = NULL;
+
+    if (ptype == 2)
+        ktype = "Private-Key";
+    else if (ptype == 1)
+        ktype = "Public-Key";
+    else
+        ktype = "DSA-Parameters";
+
+    if (priv_key) {
+        if (!BIO_indent(bp, off, 128))
+            goto err;
+        if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p))
+            <= 0)
+            goto err;
+    }
+
+    if (!ASN1_bn_print(bp, "priv:", priv_key, NULL, off))
+        goto err;
+    if (!ASN1_bn_print(bp, "pub: ", pub_key, NULL, off))
+        goto err;
+    if (!ASN1_bn_print(bp, "P:   ", x->p, NULL, off))
+        goto err;
+    if (!ASN1_bn_print(bp, "Q:   ", x->q, NULL, off))
+        goto err;
+    if (!ASN1_bn_print(bp, "G:   ", x->g, NULL, off))
+        goto err;
+    ret = 1;
+ err:
+    return (ret);
+}
+
+static int dsa_param_decode(EVP_PKEY *pkey,
+                            const unsigned char **pder, int derlen)
+{
+    DSA *dsa;
+
+    if ((dsa = d2i_DSAparams(NULL, pder, derlen)) == NULL) {
+        DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB);
+        return 0;
+    }
+    EVP_PKEY_assign_DSA(pkey, dsa);
+    return 1;
+}
+
+static int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
+{
+    return i2d_DSAparams(pkey->pkey.dsa, pder);
+}
+
+static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                           ASN1_PCTX *ctx)
+{
+    return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
+}
+
+static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                         ASN1_PCTX *ctx)
+{
+    return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
+}
+
+static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                          ASN1_PCTX *ctx)
+{
+    return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
+}
+
+static int old_dsa_priv_decode(EVP_PKEY *pkey,
+                               const unsigned char **pder, int derlen)
+{
+    DSA *dsa;
+
+    if ((dsa = d2i_DSAPrivateKey(NULL, pder, derlen)) == NULL) {
+        DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB);
+        return 0;
+    }
+    EVP_PKEY_assign_DSA(pkey, dsa);
+    return 1;
+}
+
+static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
+{
+    return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
+}
+
+static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
+                         const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx)
+{
+    DSA_SIG *dsa_sig;
+    const unsigned char *p;
+
+    if (!sig) {
+        if (BIO_puts(bp, "\n") <= 0)
+            return 0;
+        else
+            return 1;
+    }
+    p = sig->data;
+    dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length);
+    if (dsa_sig) {
+        int rv = 0;
+        const BIGNUM *r, *s;
+
+        DSA_SIG_get0(dsa_sig, &r, &s);
+
+        if (BIO_write(bp, "\n", 1) != 1)
+            goto err;
+
+        if (!ASN1_bn_print(bp, "r:   ", r, NULL, indent))
+            goto err;
+        if (!ASN1_bn_print(bp, "s:   ", s, NULL, indent))
+            goto err;
+        rv = 1;
+ err:
+        DSA_SIG_free(dsa_sig);
+        return rv;
+    }
+    return X509_signature_dump(bp, sig, indent);
+}
+
+static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+{
+    switch (op) {
+    case ASN1_PKEY_CTRL_PKCS7_SIGN:
+        if (arg1 == 0) {
+            int snid, hnid;
+            X509_ALGOR *alg1, *alg2;
+            PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
+            if (alg1 == NULL || alg1->algorithm == NULL)
+                return -1;
+            hnid = OBJ_obj2nid(alg1->algorithm);
+            if (hnid == NID_undef)
+                return -1;
+            if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
+                return -1;
+            X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
+        }
+        return 1;
+#ifndef OPENSSL_NO_CMS
+    case ASN1_PKEY_CTRL_CMS_SIGN:
+        if (arg1 == 0) {
+            int snid, hnid;
+            X509_ALGOR *alg1, *alg2;
+            CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
+            if (alg1 == NULL || alg1->algorithm == NULL)
+                return -1;
+            hnid = OBJ_obj2nid(alg1->algorithm);
+            if (hnid == NID_undef)
+                return -1;
+            if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
+                return -1;
+            X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
+        }
+        return 1;
+
+    case ASN1_PKEY_CTRL_CMS_RI_TYPE:
+        *(int *)arg2 = CMS_RECIPINFO_NONE;
+        return 1;
+#endif
+
+    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+        *(int *)arg2 = NID_sha256;
+        return 2;
+
+    default:
+        return -2;
+
+    }
+
+}
+
+/* NB these are sorted in pkey_id order, lowest first */
+
+const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[5] = {
+
+    {
+     EVP_PKEY_DSA2,
+     EVP_PKEY_DSA,
+     ASN1_PKEY_ALIAS},
+
+    {
+     EVP_PKEY_DSA1,
+     EVP_PKEY_DSA,
+     ASN1_PKEY_ALIAS},
+
+    {
+     EVP_PKEY_DSA4,
+     EVP_PKEY_DSA,
+     ASN1_PKEY_ALIAS},
+
+    {
+     EVP_PKEY_DSA3,
+     EVP_PKEY_DSA,
+     ASN1_PKEY_ALIAS},
+
+    {
+     EVP_PKEY_DSA,
+     EVP_PKEY_DSA,
+     0,
+
+     "DSA",
+     "OpenSSL DSA method",
+
+     dsa_pub_decode,
+     dsa_pub_encode,
+     dsa_pub_cmp,
+     dsa_pub_print,
+
+     dsa_priv_decode,
+     dsa_priv_encode,
+     dsa_priv_print,
+
+     int_dsa_size,
+     dsa_bits,
+     dsa_security_bits,
+
+     dsa_param_decode,
+     dsa_param_encode,
+     dsa_missing_parameters,
+     dsa_copy_parameters,
+     dsa_cmp_parameters,
+     dsa_param_print,
+     dsa_sig_print,
+
+     int_dsa_free,
+     dsa_pkey_ctrl,
+     old_dsa_priv_decode,
+     old_dsa_priv_encode}
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_asn1.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_asn1.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_asn1.c	(revision 331)
@@ -0,0 +1,155 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include "dsa_locl.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/rand.h>
+
+ASN1_SEQUENCE(DSA_SIG) = {
+        ASN1_SIMPLE(DSA_SIG, r, CBIGNUM),
+        ASN1_SIMPLE(DSA_SIG, s, CBIGNUM)
+} static_ASN1_SEQUENCE_END(DSA_SIG)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA_SIG, DSA_SIG, DSA_SIG)
+
+DSA_SIG *DSA_SIG_new(void)
+{
+    DSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig));
+    if (sig == NULL)
+        DSAerr(DSA_F_DSA_SIG_NEW, ERR_R_MALLOC_FAILURE);
+    return sig;
+}
+
+void DSA_SIG_free(DSA_SIG *sig)
+{
+    if (sig == NULL)
+        return;
+    BN_clear_free(sig->r);
+    BN_clear_free(sig->s);
+    OPENSSL_free(sig);
+}
+
+void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
+{
+    if (pr != NULL)
+        *pr = sig->r;
+    if (ps != NULL)
+        *ps = sig->s;
+}
+
+int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
+{
+    if (r == NULL || s == NULL)
+        return 0;
+    BN_clear_free(sig->r);
+    BN_clear_free(sig->s);
+    sig->r = r;
+    sig->s = s;
+    return 1;
+}
+
+/* Override the default free and new methods */
+static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                  void *exarg)
+{
+    if (operation == ASN1_OP_NEW_PRE) {
+        *pval = (ASN1_VALUE *)DSA_new();
+        if (*pval != NULL)
+            return 2;
+        return 0;
+    } else if (operation == ASN1_OP_FREE_PRE) {
+        DSA_free((DSA *)*pval);
+        *pval = NULL;
+        return 2;
+    }
+    return 1;
+}
+
+ASN1_SEQUENCE_cb(DSAPrivateKey, dsa_cb) = {
+        ASN1_SIMPLE(DSA, version, LONG),
+        ASN1_SIMPLE(DSA, p, BIGNUM),
+        ASN1_SIMPLE(DSA, q, BIGNUM),
+        ASN1_SIMPLE(DSA, g, BIGNUM),
+        ASN1_SIMPLE(DSA, pub_key, BIGNUM),
+        ASN1_SIMPLE(DSA, priv_key, CBIGNUM)
+} static_ASN1_SEQUENCE_END_cb(DSA, DSAPrivateKey)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPrivateKey, DSAPrivateKey)
+
+ASN1_SEQUENCE_cb(DSAparams, dsa_cb) = {
+        ASN1_SIMPLE(DSA, p, BIGNUM),
+        ASN1_SIMPLE(DSA, q, BIGNUM),
+        ASN1_SIMPLE(DSA, g, BIGNUM),
+} static_ASN1_SEQUENCE_END_cb(DSA, DSAparams)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAparams, DSAparams)
+
+ASN1_SEQUENCE_cb(DSAPublicKey, dsa_cb) = {
+        ASN1_SIMPLE(DSA, pub_key, BIGNUM),
+        ASN1_SIMPLE(DSA, p, BIGNUM),
+        ASN1_SIMPLE(DSA, q, BIGNUM),
+        ASN1_SIMPLE(DSA, g, BIGNUM)
+} static_ASN1_SEQUENCE_END_cb(DSA, DSAPublicKey)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPublicKey, DSAPublicKey)
+
+DSA *DSAparams_dup(DSA *dsa)
+{
+    return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa);
+}
+
+int DSA_sign(int type, const unsigned char *dgst, int dlen,
+             unsigned char *sig, unsigned int *siglen, DSA *dsa)
+{
+    DSA_SIG *s;
+    RAND_seed(dgst, dlen);
+    s = DSA_do_sign(dgst, dlen, dsa);
+    if (s == NULL) {
+        *siglen = 0;
+        return (0);
+    }
+    *siglen = i2d_DSA_SIG(s, &sig);
+    DSA_SIG_free(s);
+    return (1);
+}
+
+/* data has already been hashed (probably with SHA or SHA-1). */
+/*-
+ * returns
+ *      1: correct signature
+ *      0: incorrect signature
+ *     -1: error
+ */
+int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
+               const unsigned char *sigbuf, int siglen, DSA *dsa)
+{
+    DSA_SIG *s;
+    const unsigned char *p = sigbuf;
+    unsigned char *der = NULL;
+    int derlen = -1;
+    int ret = -1;
+
+    s = DSA_SIG_new();
+    if (s == NULL)
+        return (ret);
+    if (d2i_DSA_SIG(&s, &p, siglen) == NULL)
+        goto err;
+    /* Ensure signature uses DER and doesn't have trailing garbage */
+    derlen = i2d_DSA_SIG(s, &der);
+    if (derlen != siglen || memcmp(sigbuf, der, derlen))
+        goto err;
+    ret = DSA_do_verify(dgst, dgst_len, s, dsa);
+ err:
+    OPENSSL_clear_free(der, derlen);
+    DSA_SIG_free(s);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_depr.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_depr.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_depr.c	(revision 331)
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2002-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
+ */
+
+/*
+ * This file contains deprecated function(s) that are now wrappers to the new
+ * version(s).
+ */
+
+/*
+ * Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186,
+ * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in FIPS PUB
+ * 180-1)
+ */
+#define xxxHASH    EVP_sha1()
+
+#include <openssl/opensslconf.h>
+#if OPENSSL_API_COMPAT >= 0x00908000L
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <stdio.h>
+# include <time.h>
+# include "internal/cryptlib.h"
+# include <openssl/evp.h>
+# include <openssl/bn.h>
+# include <openssl/dsa.h>
+# include <openssl/sha.h>
+
+DSA *DSA_generate_parameters(int bits,
+                             unsigned char *seed_in, int seed_len,
+                             int *counter_ret, unsigned long *h_ret,
+                             void (*callback) (int, int, void *),
+                             void *cb_arg)
+{
+    BN_GENCB *cb;
+    DSA *ret;
+
+    if ((ret = DSA_new()) == NULL)
+        return NULL;
+    cb = BN_GENCB_new();
+    if (cb == NULL)
+        goto err;
+
+    BN_GENCB_set_old(cb, callback, cb_arg);
+
+    if (DSA_generate_parameters_ex(ret, bits, seed_in, seed_len,
+                                   counter_ret, h_ret, cb)) {
+        BN_GENCB_free(cb);
+        return ret;
+    }
+    BN_GENCB_free(cb);
+err:
+    DSA_free(ret);
+    return NULL;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_err.c	(revision 331)
@@ -0,0 +1,76 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/dsa.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_DSA,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_DSA,0,reason)
+
+static ERR_STRING_DATA DSA_str_functs[] = {
+    {ERR_FUNC(DSA_F_DSAPARAMS_PRINT), "DSAparams_print"},
+    {ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP), "DSAparams_print_fp"},
+    {ERR_FUNC(DSA_F_DSA_BUILTIN_PARAMGEN), "dsa_builtin_paramgen"},
+    {ERR_FUNC(DSA_F_DSA_BUILTIN_PARAMGEN2), "dsa_builtin_paramgen2"},
+    {ERR_FUNC(DSA_F_DSA_DO_SIGN), "DSA_do_sign"},
+    {ERR_FUNC(DSA_F_DSA_DO_VERIFY), "DSA_do_verify"},
+    {ERR_FUNC(DSA_F_DSA_METH_DUP), "DSA_meth_dup"},
+    {ERR_FUNC(DSA_F_DSA_METH_NEW), "DSA_meth_new"},
+    {ERR_FUNC(DSA_F_DSA_METH_SET1_NAME), "DSA_meth_set1_name"},
+    {ERR_FUNC(DSA_F_DSA_NEW_METHOD), "DSA_new_method"},
+    {ERR_FUNC(DSA_F_DSA_PARAM_DECODE), "dsa_param_decode"},
+    {ERR_FUNC(DSA_F_DSA_PRINT_FP), "DSA_print_fp"},
+    {ERR_FUNC(DSA_F_DSA_PRIV_DECODE), "dsa_priv_decode"},
+    {ERR_FUNC(DSA_F_DSA_PRIV_ENCODE), "dsa_priv_encode"},
+    {ERR_FUNC(DSA_F_DSA_PUB_DECODE), "dsa_pub_decode"},
+    {ERR_FUNC(DSA_F_DSA_PUB_ENCODE), "dsa_pub_encode"},
+    {ERR_FUNC(DSA_F_DSA_SIGN), "DSA_sign"},
+    {ERR_FUNC(DSA_F_DSA_SIGN_SETUP), "DSA_sign_setup"},
+    {ERR_FUNC(DSA_F_DSA_SIG_NEW), "DSA_SIG_new"},
+    {ERR_FUNC(DSA_F_OLD_DSA_PRIV_DECODE), "old_dsa_priv_decode"},
+    {ERR_FUNC(DSA_F_PKEY_DSA_CTRL), "pkey_dsa_ctrl"},
+    {ERR_FUNC(DSA_F_PKEY_DSA_KEYGEN), "pkey_dsa_keygen"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA DSA_str_reasons[] = {
+    {ERR_REASON(DSA_R_BAD_Q_VALUE), "bad q value"},
+    {ERR_REASON(DSA_R_BN_DECODE_ERROR), "bn decode error"},
+    {ERR_REASON(DSA_R_BN_ERROR), "bn error"},
+    {ERR_REASON(DSA_R_DECODE_ERROR), "decode error"},
+    {ERR_REASON(DSA_R_INVALID_DIGEST_TYPE), "invalid digest type"},
+    {ERR_REASON(DSA_R_INVALID_PARAMETERS), "invalid parameters"},
+    {ERR_REASON(DSA_R_MISSING_PARAMETERS), "missing parameters"},
+    {ERR_REASON(DSA_R_MODULUS_TOO_LARGE), "modulus too large"},
+    {ERR_REASON(DSA_R_NO_PARAMETERS_SET), "no parameters set"},
+    {ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR), "parameter encoding error"},
+    {ERR_REASON(DSA_R_Q_NOT_PRIME), "q not prime"},
+    {ERR_REASON(DSA_R_SEED_LEN_SMALL),
+     "seed_len is less than the length of q"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_DSA_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(DSA_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, DSA_str_functs);
+        ERR_load_strings(0, DSA_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_gen.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_gen.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_gen.c	(revision 331)
@@ -0,0 +1,601 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*
+ * Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186,
+ * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in FIPS PUB
+ * 180-1)
+ */
+#define xxxHASH    EVP_sha1()
+
+#include <openssl/opensslconf.h>
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+#include "dsa_locl.h"
+
+int DSA_generate_parameters_ex(DSA *ret, int bits,
+                               const unsigned char *seed_in, int seed_len,
+                               int *counter_ret, unsigned long *h_ret,
+                               BN_GENCB *cb)
+{
+    if (ret->meth->dsa_paramgen)
+        return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
+                                       counter_ret, h_ret, cb);
+    else {
+        const EVP_MD *evpmd = bits >= 2048 ? EVP_sha256() : EVP_sha1();
+        size_t qbits = EVP_MD_size(evpmd) * 8;
+
+        return dsa_builtin_paramgen(ret, bits, qbits, evpmd,
+                                    seed_in, seed_len, NULL, counter_ret,
+                                    h_ret, cb);
+    }
+}
+
+int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
+                         const EVP_MD *evpmd, const unsigned char *seed_in,
+                         size_t seed_len, unsigned char *seed_out,
+                         int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
+{
+    int ok = 0;
+    unsigned char seed[SHA256_DIGEST_LENGTH];
+    unsigned char md[SHA256_DIGEST_LENGTH];
+    unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH];
+    BIGNUM *r0, *W, *X, *c, *test;
+    BIGNUM *g = NULL, *q = NULL, *p = NULL;
+    BN_MONT_CTX *mont = NULL;
+    int i, k, n = 0, m = 0, qsize = qbits >> 3;
+    int counter = 0;
+    int r = 0;
+    BN_CTX *ctx = NULL;
+    unsigned int h = 2;
+
+    if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
+        qsize != SHA256_DIGEST_LENGTH)
+        /* invalid q size */
+        return 0;
+
+    if (evpmd == NULL)
+        /* use SHA1 as default */
+        evpmd = EVP_sha1();
+
+    if (bits < 512)
+        bits = 512;
+
+    bits = (bits + 63) / 64 * 64;
+
+    if (seed_in != NULL) {
+        if (seed_len < (size_t)qsize) {
+            DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN, DSA_R_SEED_LEN_SMALL);
+            return 0;
+        }
+        if (seed_len > (size_t)qsize) {
+            /* Only consume as much seed as is expected. */
+            seed_len = qsize;
+        }
+        memcpy(seed, seed_in, seed_len);
+    }
+
+    if ((mont = BN_MONT_CTX_new()) == NULL)
+        goto err;
+
+    if ((ctx = BN_CTX_new()) == NULL)
+        goto err;
+
+    BN_CTX_start(ctx);
+
+    r0 = BN_CTX_get(ctx);
+    g = BN_CTX_get(ctx);
+    W = BN_CTX_get(ctx);
+    q = BN_CTX_get(ctx);
+    X = BN_CTX_get(ctx);
+    c = BN_CTX_get(ctx);
+    p = BN_CTX_get(ctx);
+    test = BN_CTX_get(ctx);
+
+    if (test == NULL)
+        goto err;
+
+    if (!BN_lshift(test, BN_value_one(), bits - 1))
+        goto err;
+
+    for (;;) {
+        for (;;) {              /* find q */
+            int use_random_seed = (seed_in == NULL);
+
+            /* step 1 */
+            if (!BN_GENCB_call(cb, 0, m++))
+                goto err;
+
+            if (use_random_seed) {
+                if (RAND_bytes(seed, qsize) <= 0)
+                    goto err;
+            } else {
+                /* If we come back through, use random seed next time. */
+                seed_in = NULL;
+            }
+            memcpy(buf, seed, qsize);
+            memcpy(buf2, seed, qsize);
+            /* precompute "SEED + 1" for step 7: */
+            for (i = qsize - 1; i >= 0; i--) {
+                buf[i]++;
+                if (buf[i] != 0)
+                    break;
+            }
+
+            /* step 2 */
+            if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL))
+                goto err;
+            if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL))
+                goto err;
+            for (i = 0; i < qsize; i++)
+                md[i] ^= buf2[i];
+
+            /* step 3 */
+            md[0] |= 0x80;
+            md[qsize - 1] |= 0x01;
+            if (!BN_bin2bn(md, qsize, q))
+                goto err;
+
+            /* step 4 */
+            r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
+                                        use_random_seed, cb);
+            if (r > 0)
+                break;
+            if (r != 0)
+                goto err;
+
+            /* do a callback call */
+            /* step 5 */
+        }
+
+        if (!BN_GENCB_call(cb, 2, 0))
+            goto err;
+        if (!BN_GENCB_call(cb, 3, 0))
+            goto err;
+
+        /* step 6 */
+        counter = 0;
+        /* "offset = 2" */
+
+        n = (bits - 1) / 160;
+
+        for (;;) {
+            if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
+                goto err;
+
+            /* step 7 */
+            BN_zero(W);
+            /* now 'buf' contains "SEED + offset - 1" */
+            for (k = 0; k <= n; k++) {
+                /*
+                 * obtain "SEED + offset + k" by incrementing:
+                 */
+                for (i = qsize - 1; i >= 0; i--) {
+                    buf[i]++;
+                    if (buf[i] != 0)
+                        break;
+                }
+
+                if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL))
+                    goto err;
+
+                /* step 8 */
+                if (!BN_bin2bn(md, qsize, r0))
+                    goto err;
+                if (!BN_lshift(r0, r0, (qsize << 3) * k))
+                    goto err;
+                if (!BN_add(W, W, r0))
+                    goto err;
+            }
+
+            /* more of step 8 */
+            if (!BN_mask_bits(W, bits - 1))
+                goto err;
+            if (!BN_copy(X, W))
+                goto err;
+            if (!BN_add(X, X, test))
+                goto err;
+
+            /* step 9 */
+            if (!BN_lshift1(r0, q))
+                goto err;
+            if (!BN_mod(c, X, r0, ctx))
+                goto err;
+            if (!BN_sub(r0, c, BN_value_one()))
+                goto err;
+            if (!BN_sub(p, X, r0))
+                goto err;
+
+            /* step 10 */
+            if (BN_cmp(p, test) >= 0) {
+                /* step 11 */
+                r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb);
+                if (r > 0)
+                    goto end;   /* found it */
+                if (r != 0)
+                    goto err;
+            }
+
+            /* step 13 */
+            counter++;
+            /* "offset = offset + n + 1" */
+
+            /* step 14 */
+            if (counter >= 4096)
+                break;
+        }
+    }
+ end:
+    if (!BN_GENCB_call(cb, 2, 1))
+        goto err;
+
+    /* We now need to generate g */
+    /* Set r0=(p-1)/q */
+    if (!BN_sub(test, p, BN_value_one()))
+        goto err;
+    if (!BN_div(r0, NULL, test, q, ctx))
+        goto err;
+
+    if (!BN_set_word(test, h))
+        goto err;
+    if (!BN_MONT_CTX_set(mont, p, ctx))
+        goto err;
+
+    for (;;) {
+        /* g=test^r0%p */
+        if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont))
+            goto err;
+        if (!BN_is_one(g))
+            break;
+        if (!BN_add(test, test, BN_value_one()))
+            goto err;
+        h++;
+    }
+
+    if (!BN_GENCB_call(cb, 3, 1))
+        goto err;
+
+    ok = 1;
+ err:
+    if (ok) {
+        BN_free(ret->p);
+        BN_free(ret->q);
+        BN_free(ret->g);
+        ret->p = BN_dup(p);
+        ret->q = BN_dup(q);
+        ret->g = BN_dup(g);
+        if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
+            ok = 0;
+            goto err;
+        }
+        if (counter_ret != NULL)
+            *counter_ret = counter;
+        if (h_ret != NULL)
+            *h_ret = h;
+        if (seed_out)
+            memcpy(seed_out, seed, qsize);
+    }
+    if (ctx)
+        BN_CTX_end(ctx);
+    BN_CTX_free(ctx);
+    BN_MONT_CTX_free(mont);
+    return ok;
+}
+
+/*
+ * This is a parameter generation algorithm for the DSA2 algorithm as
+ * described in FIPS 186-3.
+ */
+
+int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
+                          const EVP_MD *evpmd, const unsigned char *seed_in,
+                          size_t seed_len, int idx, unsigned char *seed_out,
+                          int *counter_ret, unsigned long *h_ret,
+                          BN_GENCB *cb)
+{
+    int ok = -1;
+    unsigned char *seed = NULL, *seed_tmp = NULL;
+    unsigned char md[EVP_MAX_MD_SIZE];
+    int mdsize;
+    BIGNUM *r0, *W, *X, *c, *test;
+    BIGNUM *g = NULL, *q = NULL, *p = NULL;
+    BN_MONT_CTX *mont = NULL;
+    int i, k, n = 0, m = 0, qsize = N >> 3;
+    int counter = 0;
+    int r = 0;
+    BN_CTX *ctx = NULL;
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+    unsigned int h = 2;
+
+    if (mctx == NULL)
+        goto err;
+
+    if (evpmd == NULL) {
+        if (N == 160)
+            evpmd = EVP_sha1();
+        else if (N == 224)
+            evpmd = EVP_sha224();
+        else
+            evpmd = EVP_sha256();
+    }
+
+    mdsize = EVP_MD_size(evpmd);
+    /* If unverifiable g generation only don't need seed */
+    if (!ret->p || !ret->q || idx >= 0) {
+        if (seed_len == 0)
+            seed_len = mdsize;
+
+        seed = OPENSSL_malloc(seed_len);
+
+        if (seed_out)
+            seed_tmp = seed_out;
+        else
+            seed_tmp = OPENSSL_malloc(seed_len);
+
+        if (seed == NULL || seed_tmp == NULL)
+            goto err;
+
+        if (seed_in)
+            memcpy(seed, seed_in, seed_len);
+
+    }
+
+    if ((ctx = BN_CTX_new()) == NULL)
+        goto err;
+
+    if ((mont = BN_MONT_CTX_new()) == NULL)
+        goto err;
+
+    BN_CTX_start(ctx);
+    r0 = BN_CTX_get(ctx);
+    g = BN_CTX_get(ctx);
+    W = BN_CTX_get(ctx);
+    X = BN_CTX_get(ctx);
+    c = BN_CTX_get(ctx);
+    test = BN_CTX_get(ctx);
+    if (test == NULL)
+        goto err;
+
+    /* if p, q already supplied generate g only */
+    if (ret->p && ret->q) {
+        p = ret->p;
+        q = ret->q;
+        if (idx >= 0)
+            memcpy(seed_tmp, seed, seed_len);
+        goto g_only;
+    } else {
+        p = BN_CTX_get(ctx);
+        q = BN_CTX_get(ctx);
+    }
+
+    if (!BN_lshift(test, BN_value_one(), L - 1))
+        goto err;
+    for (;;) {
+        for (;;) {              /* find q */
+            unsigned char *pmd;
+            /* step 1 */
+            if (!BN_GENCB_call(cb, 0, m++))
+                goto err;
+
+            if (!seed_in) {
+                if (RAND_bytes(seed, seed_len) <= 0)
+                    goto err;
+            }
+            /* step 2 */
+            if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL))
+                goto err;
+            /* Take least significant bits of md */
+            if (mdsize > qsize)
+                pmd = md + mdsize - qsize;
+            else
+                pmd = md;
+
+            if (mdsize < qsize)
+                memset(md + mdsize, 0, qsize - mdsize);
+
+            /* step 3 */
+            pmd[0] |= 0x80;
+            pmd[qsize - 1] |= 0x01;
+            if (!BN_bin2bn(pmd, qsize, q))
+                goto err;
+
+            /* step 4 */
+            r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
+                                        seed_in ? 1 : 0, cb);
+            if (r > 0)
+                break;
+            if (r != 0)
+                goto err;
+            /* Provided seed didn't produce a prime: error */
+            if (seed_in) {
+                ok = 0;
+                DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_Q_NOT_PRIME);
+                goto err;
+            }
+
+            /* do a callback call */
+            /* step 5 */
+        }
+        /* Copy seed to seed_out before we mess with it */
+        if (seed_out)
+            memcpy(seed_out, seed, seed_len);
+
+        if (!BN_GENCB_call(cb, 2, 0))
+            goto err;
+        if (!BN_GENCB_call(cb, 3, 0))
+            goto err;
+
+        /* step 6 */
+        counter = 0;
+        /* "offset = 1" */
+
+        n = (L - 1) / (mdsize << 3);
+
+        for (;;) {
+            if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
+                goto err;
+
+            /* step 7 */
+            BN_zero(W);
+            /* now 'buf' contains "SEED + offset - 1" */
+            for (k = 0; k <= n; k++) {
+                /*
+                 * obtain "SEED + offset + k" by incrementing:
+                 */
+                for (i = seed_len - 1; i >= 0; i--) {
+                    seed[i]++;
+                    if (seed[i] != 0)
+                        break;
+                }
+
+                if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL))
+                    goto err;
+
+                /* step 8 */
+                if (!BN_bin2bn(md, mdsize, r0))
+                    goto err;
+                if (!BN_lshift(r0, r0, (mdsize << 3) * k))
+                    goto err;
+                if (!BN_add(W, W, r0))
+                    goto err;
+            }
+
+            /* more of step 8 */
+            if (!BN_mask_bits(W, L - 1))
+                goto err;
+            if (!BN_copy(X, W))
+                goto err;
+            if (!BN_add(X, X, test))
+                goto err;
+
+            /* step 9 */
+            if (!BN_lshift1(r0, q))
+                goto err;
+            if (!BN_mod(c, X, r0, ctx))
+                goto err;
+            if (!BN_sub(r0, c, BN_value_one()))
+                goto err;
+            if (!BN_sub(p, X, r0))
+                goto err;
+
+            /* step 10 */
+            if (BN_cmp(p, test) >= 0) {
+                /* step 11 */
+                r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb);
+                if (r > 0)
+                    goto end;   /* found it */
+                if (r != 0)
+                    goto err;
+            }
+
+            /* step 13 */
+            counter++;
+            /* "offset = offset + n + 1" */
+
+            /* step 14 */
+            if (counter >= (int)(4 * L))
+                break;
+        }
+        if (seed_in) {
+            ok = 0;
+            DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS);
+            goto err;
+        }
+    }
+ end:
+    if (!BN_GENCB_call(cb, 2, 1))
+        goto err;
+
+ g_only:
+
+    /* We now need to generate g */
+    /* Set r0=(p-1)/q */
+    if (!BN_sub(test, p, BN_value_one()))
+        goto err;
+    if (!BN_div(r0, NULL, test, q, ctx))
+        goto err;
+
+    if (idx < 0) {
+        if (!BN_set_word(test, h))
+            goto err;
+    } else
+        h = 1;
+    if (!BN_MONT_CTX_set(mont, p, ctx))
+        goto err;
+
+    for (;;) {
+        static const unsigned char ggen[4] = { 0x67, 0x67, 0x65, 0x6e };
+        if (idx >= 0) {
+            md[0] = idx & 0xff;
+            md[1] = (h >> 8) & 0xff;
+            md[2] = h & 0xff;
+            if (!EVP_DigestInit_ex(mctx, evpmd, NULL))
+                goto err;
+            if (!EVP_DigestUpdate(mctx, seed_tmp, seed_len))
+                goto err;
+            if (!EVP_DigestUpdate(mctx, ggen, sizeof(ggen)))
+                goto err;
+            if (!EVP_DigestUpdate(mctx, md, 3))
+                goto err;
+            if (!EVP_DigestFinal_ex(mctx, md, NULL))
+                goto err;
+            if (!BN_bin2bn(md, mdsize, test))
+                goto err;
+        }
+        /* g=test^r0%p */
+        if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont))
+            goto err;
+        if (!BN_is_one(g))
+            break;
+        if (idx < 0 && !BN_add(test, test, BN_value_one()))
+            goto err;
+        h++;
+        if (idx >= 0 && h > 0xffff)
+            goto err;
+    }
+
+    if (!BN_GENCB_call(cb, 3, 1))
+        goto err;
+
+    ok = 1;
+ err:
+    if (ok == 1) {
+        if (p != ret->p) {
+            BN_free(ret->p);
+            ret->p = BN_dup(p);
+        }
+        if (q != ret->q) {
+            BN_free(ret->q);
+            ret->q = BN_dup(q);
+        }
+        BN_free(ret->g);
+        ret->g = BN_dup(g);
+        if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
+            ok = -1;
+            goto err;
+        }
+        if (counter_ret != NULL)
+            *counter_ret = counter;
+        if (h_ret != NULL)
+            *h_ret = h;
+    }
+    OPENSSL_free(seed);
+    if (seed_out != seed_tmp)
+        OPENSSL_free(seed_tmp);
+    if (ctx)
+        BN_CTX_end(ctx);
+    BN_CTX_free(ctx);
+    BN_MONT_CTX_free(mont);
+    EVP_MD_CTX_free(mctx);
+    return ok;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_key.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_key.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_key.c	(revision 331)
@@ -0,0 +1,77 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <time.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include "dsa_locl.h"
+
+static int dsa_builtin_keygen(DSA *dsa);
+
+int DSA_generate_key(DSA *dsa)
+{
+    if (dsa->meth->dsa_keygen)
+        return dsa->meth->dsa_keygen(dsa);
+    return dsa_builtin_keygen(dsa);
+}
+
+static int dsa_builtin_keygen(DSA *dsa)
+{
+    int ok = 0;
+    BN_CTX *ctx = NULL;
+    BIGNUM *pub_key = NULL, *priv_key = NULL;
+
+    if ((ctx = BN_CTX_new()) == NULL)
+        goto err;
+
+    if (dsa->priv_key == NULL) {
+        if ((priv_key = BN_secure_new()) == NULL)
+            goto err;
+    } else
+        priv_key = dsa->priv_key;
+
+    do
+        if (!BN_rand_range(priv_key, dsa->q))
+            goto err;
+    while (BN_is_zero(priv_key)) ;
+
+    if (dsa->pub_key == NULL) {
+        if ((pub_key = BN_new()) == NULL)
+            goto err;
+    } else
+        pub_key = dsa->pub_key;
+
+    {
+        BIGNUM *prk = BN_new();
+
+        if (prk == NULL)
+            goto err;
+        BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
+
+        if (!BN_mod_exp(pub_key, dsa->g, prk, dsa->p, ctx)) {
+            BN_free(prk);
+            goto err;
+        }
+        /* We MUST free prk before any further use of priv_key */
+        BN_free(prk);
+    }
+
+    dsa->priv_key = priv_key;
+    dsa->pub_key = pub_key;
+    ok = 1;
+
+ err:
+    if (pub_key != dsa->pub_key)
+        BN_free(pub_key);
+    if (priv_key != dsa->priv_key)
+        BN_free(priv_key);
+    BN_CTX_free(ctx);
+    return (ok);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_lib.c	(revision 331)
@@ -0,0 +1,346 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include "dsa_locl.h"
+#include <openssl/asn1.h>
+#include <openssl/engine.h>
+#include <openssl/dh.h>
+
+static const DSA_METHOD *default_DSA_method = NULL;
+
+void DSA_set_default_method(const DSA_METHOD *meth)
+{
+    default_DSA_method = meth;
+}
+
+const DSA_METHOD *DSA_get_default_method(void)
+{
+    if (!default_DSA_method)
+        default_DSA_method = DSA_OpenSSL();
+    return default_DSA_method;
+}
+
+DSA *DSA_new(void)
+{
+    return DSA_new_method(NULL);
+}
+
+int DSA_set_method(DSA *dsa, const DSA_METHOD *meth)
+{
+    /*
+     * NB: The caller is specifically setting a method, so it's not up to us
+     * to deal with which ENGINE it comes from.
+     */
+    const DSA_METHOD *mtmp;
+    mtmp = dsa->meth;
+    if (mtmp->finish)
+        mtmp->finish(dsa);
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE_finish(dsa->engine);
+    dsa->engine = NULL;
+#endif
+    dsa->meth = meth;
+    if (meth->init)
+        meth->init(dsa);
+    return 1;
+}
+
+const DSA_METHOD *DSA_get_method(DSA *d)
+{
+    return d->meth;
+}
+
+DSA *DSA_new_method(ENGINE *engine)
+{
+    DSA *ret = OPENSSL_zalloc(sizeof(*ret));
+
+    if (ret == NULL) {
+        DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    ret->references = 1;
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ret);
+        return NULL;
+    }
+
+    ret->meth = DSA_get_default_method();
+#ifndef OPENSSL_NO_ENGINE
+    ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; /* early default init */
+    if (engine) {
+        if (!ENGINE_init(engine)) {
+            DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
+            goto err;
+        }
+        ret->engine = engine;
+    } else
+        ret->engine = ENGINE_get_default_DSA();
+    if (ret->engine) {
+        ret->meth = ENGINE_get_DSA(ret->engine);
+        if (ret->meth == NULL) {
+            DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
+            goto err;
+        }
+    }
+#endif
+
+    ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;
+
+    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data))
+        goto err;
+
+    if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
+        DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_INIT_FAIL);
+err:
+        DSA_free(ret);
+        ret = NULL;
+    }
+
+    return ret;
+}
+
+void DSA_free(DSA *r)
+{
+    int i;
+
+    if (r == NULL)
+        return;
+
+    CRYPTO_atomic_add(&r->references, -1, &i, r->lock);
+    REF_PRINT_COUNT("DSA", r);
+    if (i > 0)
+        return;
+    REF_ASSERT_ISNT(i < 0);
+
+    if (r->meth->finish)
+        r->meth->finish(r);
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE_finish(r->engine);
+#endif
+
+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data);
+
+    CRYPTO_THREAD_lock_free(r->lock);
+
+    BN_clear_free(r->p);
+    BN_clear_free(r->q);
+    BN_clear_free(r->g);
+    BN_clear_free(r->pub_key);
+    BN_clear_free(r->priv_key);
+    OPENSSL_free(r);
+}
+
+int DSA_up_ref(DSA *r)
+{
+    int i;
+
+    if (CRYPTO_atomic_add(&r->references, 1, &i, r->lock) <= 0)
+        return 0;
+
+    REF_PRINT_COUNT("DSA", r);
+    REF_ASSERT_ISNT(i < 2);
+    return ((i > 1) ? 1 : 0);
+}
+
+int DSA_size(const DSA *r)
+{
+    int ret, i;
+    ASN1_INTEGER bs;
+    unsigned char buf[4];       /* 4 bytes looks really small. However,
+                                 * i2d_ASN1_INTEGER() will not look beyond
+                                 * the first byte, as long as the second
+                                 * parameter is NULL. */
+
+    i = BN_num_bits(r->q);
+    bs.length = (i + 7) / 8;
+    bs.data = buf;
+    bs.type = V_ASN1_INTEGER;
+    /* If the top bit is set the asn1 encoding is 1 larger. */
+    buf[0] = 0xff;
+
+    i = i2d_ASN1_INTEGER(&bs, NULL);
+    i += i;                     /* r and s */
+    ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
+    return (ret);
+}
+
+int DSA_set_ex_data(DSA *d, int idx, void *arg)
+{
+    return (CRYPTO_set_ex_data(&d->ex_data, idx, arg));
+}
+
+void *DSA_get_ex_data(DSA *d, int idx)
+{
+    return (CRYPTO_get_ex_data(&d->ex_data, idx));
+}
+
+int DSA_security_bits(const DSA *d)
+{
+    if (d->p && d->q)
+        return BN_security_bits(BN_num_bits(d->p), BN_num_bits(d->q));
+    return -1;
+}
+
+#ifndef OPENSSL_NO_DH
+DH *DSA_dup_DH(const DSA *r)
+{
+    /*
+     * DSA has p, q, g, optional pub_key, optional priv_key. DH has p,
+     * optional length, g, optional pub_key, optional priv_key, optional q.
+     */
+
+    DH *ret = NULL;
+    BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL, *priv_key = NULL;
+
+    if (r == NULL)
+        goto err;
+    ret = DH_new();
+    if (ret == NULL)
+        goto err;
+    if (r->p != NULL || r->g != NULL || r->q != NULL) {
+        if (r->p == NULL || r->g == NULL || r->q == NULL) {
+            /* Shouldn't happen */
+            goto err;
+        }
+        p = BN_dup(r->p);
+        g = BN_dup(r->g);
+        q = BN_dup(r->q);
+        if (p == NULL || g == NULL || q == NULL || !DH_set0_pqg(ret, p, q, g))
+            goto err;
+        p = g = q = NULL;
+    }
+
+    if (r->pub_key != NULL) {
+        pub_key = BN_dup(r->pub_key);
+        if (pub_key == NULL)
+            goto err;
+        if (r->priv_key != NULL) {
+            priv_key = BN_dup(r->priv_key);
+            if (priv_key == NULL)
+                goto err;
+        }
+        if (!DH_set0_key(ret, pub_key, priv_key))
+            goto err;
+    } else if (r->priv_key != NULL) {
+        /* Shouldn't happen */
+        goto err;
+    }
+
+    return ret;
+
+ err:
+    BN_free(p);
+    BN_free(g);
+    BN_free(q);
+    BN_free(pub_key);
+    BN_free(priv_key);
+    DH_free(ret);
+    return NULL;
+}
+#endif
+
+void DSA_get0_pqg(const DSA *d,
+                  const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
+{
+    if (p != NULL)
+        *p = d->p;
+    if (q != NULL)
+        *q = d->q;
+    if (g != NULL)
+        *g = d->g;
+}
+
+int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
+{
+    /* If the fields p, q and g in d are NULL, the corresponding input
+     * parameters MUST be non-NULL.
+     */
+    if ((d->p == NULL && p == NULL)
+        || (d->q == NULL && q == NULL)
+        || (d->g == NULL && g == NULL))
+        return 0;
+
+    if (p != NULL) {
+        BN_free(d->p);
+        d->p = p;
+    }
+    if (q != NULL) {
+        BN_free(d->q);
+        d->q = q;
+    }
+    if (g != NULL) {
+        BN_free(d->g);
+        d->g = g;
+    }
+
+    return 1;
+}
+
+void DSA_get0_key(const DSA *d,
+                  const BIGNUM **pub_key, const BIGNUM **priv_key)
+{
+    if (pub_key != NULL)
+        *pub_key = d->pub_key;
+    if (priv_key != NULL)
+        *priv_key = d->priv_key;
+}
+
+int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
+{
+    /* If the field pub_key in d is NULL, the corresponding input
+     * parameters MUST be non-NULL.  The priv_key field may
+     * be left NULL.
+     */
+    if (d->pub_key == NULL && pub_key == NULL)
+        return 0;
+
+    if (pub_key != NULL) {
+        BN_free(d->pub_key);
+        d->pub_key = pub_key;
+    }
+    if (priv_key != NULL) {
+        BN_free(d->priv_key);
+        d->priv_key = priv_key;
+    }
+
+    return 1;
+}
+
+void DSA_clear_flags(DSA *d, int flags)
+{
+    d->flags &= ~flags;
+}
+
+int DSA_test_flags(const DSA *d, int flags)
+{
+    return d->flags & flags;
+}
+
+void DSA_set_flags(DSA *d, int flags)
+{
+    d->flags |= flags;
+}
+
+ENGINE *DSA_get0_engine(DSA *d)
+{
+    return d->engine;
+}
+
+int DSA_bits(const DSA *dsa)
+{
+    return BN_num_bits(dsa->p);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_locl.h	(revision 331)
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2007-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 <openssl/dsa.h>
+
+struct dsa_st {
+    /*
+     * This first variable is used to pick up errors where a DSA is passed
+     * instead of of a EVP_PKEY
+     */
+    int pad;
+    long version;
+    BIGNUM *p;
+    BIGNUM *q;                  /* == 20 */
+    BIGNUM *g;
+    BIGNUM *pub_key;            /* y public key */
+    BIGNUM *priv_key;           /* x private key */
+    int flags;
+    /* Normally used to cache montgomery values */
+    BN_MONT_CTX *method_mont_p;
+    int references;
+    CRYPTO_EX_DATA ex_data;
+    const DSA_METHOD *meth;
+    /* functional reference if 'meth' is ENGINE-provided */
+    ENGINE *engine;
+    CRYPTO_RWLOCK *lock;
+};
+
+struct DSA_SIG_st {
+    BIGNUM *r;
+    BIGNUM *s;
+};
+
+struct dsa_method {
+    char *name;
+    DSA_SIG *(*dsa_do_sign) (const unsigned char *dgst, int dlen, DSA *dsa);
+    int (*dsa_sign_setup) (DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
+                           BIGNUM **rp);
+    int (*dsa_do_verify) (const unsigned char *dgst, int dgst_len,
+                          DSA_SIG *sig, DSA *dsa);
+    int (*dsa_mod_exp) (DSA *dsa, BIGNUM *rr, const BIGNUM *a1,
+                        const BIGNUM *p1, const BIGNUM *a2, const BIGNUM *p2,
+                        const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont);
+    /* Can be null */
+    int (*bn_mod_exp) (DSA *dsa, BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+    int (*init) (DSA *dsa);
+    int (*finish) (DSA *dsa);
+    int flags;
+    void *app_data;
+    /* If this is non-NULL, it is used to generate DSA parameters */
+    int (*dsa_paramgen) (DSA *dsa, int bits,
+                         const unsigned char *seed, int seed_len,
+                         int *counter_ret, unsigned long *h_ret,
+                         BN_GENCB *cb);
+    /* If this is non-NULL, it is used to generate DSA keys */
+    int (*dsa_keygen) (DSA *dsa);
+};
+
+int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
+                         const EVP_MD *evpmd, const unsigned char *seed_in,
+                         size_t seed_len, unsigned char *seed_out,
+                         int *counter_ret, unsigned long *h_ret,
+                         BN_GENCB *cb);
+
+int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
+                          const EVP_MD *evpmd, const unsigned char *seed_in,
+                          size_t seed_len, int idx, unsigned char *seed_out,
+                          int *counter_ret, unsigned long *h_ret,
+                          BN_GENCB *cb);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_meth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_meth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_meth.c	(revision 331)
@@ -0,0 +1,224 @@
+/*
+ * 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
+ */
+
+/*
+ * Licensed under the OpenSSL licenses, (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * https://www.openssl.org/source/license.html
+ * or in the file LICENSE in the source distribution.
+ */
+
+#include "dsa_locl.h"
+#include <string.h>
+#include <openssl/err.h>
+
+DSA_METHOD *DSA_meth_new(const char *name, int flags)
+{
+    DSA_METHOD *dsam = OPENSSL_zalloc(sizeof(*dsam));
+
+    if (dsam != NULL) {
+        dsam->flags = flags;
+
+        dsam->name = OPENSSL_strdup(name);
+        if (dsam->name != NULL)
+            return dsam;
+
+        OPENSSL_free(dsam);
+    }
+
+    DSAerr(DSA_F_DSA_METH_NEW, ERR_R_MALLOC_FAILURE);
+    return NULL;
+}
+
+void DSA_meth_free(DSA_METHOD *dsam)
+{
+    if (dsam != NULL) {
+        OPENSSL_free(dsam->name);
+        OPENSSL_free(dsam);
+    }
+}
+
+DSA_METHOD *DSA_meth_dup(const DSA_METHOD *dsam)
+{
+    DSA_METHOD *ret = OPENSSL_malloc(sizeof(*ret));
+
+    if (ret != NULL) {
+        memcpy(ret, dsam, sizeof(*dsam));
+
+        ret->name = OPENSSL_strdup(dsam->name);
+        if (ret->name != NULL)
+            return ret;
+
+        OPENSSL_free(ret);
+    }
+
+    DSAerr(DSA_F_DSA_METH_DUP, ERR_R_MALLOC_FAILURE);
+    return NULL;
+}
+
+const char *DSA_meth_get0_name(const DSA_METHOD *dsam)
+{
+    return dsam->name;
+}
+
+int DSA_meth_set1_name(DSA_METHOD *dsam, const char *name)
+{
+    char *tmpname = OPENSSL_strdup(name);
+
+    if (tmpname == NULL) {
+        DSAerr(DSA_F_DSA_METH_SET1_NAME, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    OPENSSL_free(dsam->name);
+    dsam->name = tmpname;
+
+    return 1;
+}
+
+int DSA_meth_get_flags(DSA_METHOD *dsam)
+{
+    return dsam->flags;
+}
+
+int DSA_meth_set_flags(DSA_METHOD *dsam, int flags)
+{
+    dsam->flags = flags;
+    return 1;
+}
+
+void *DSA_meth_get0_app_data(const DSA_METHOD *dsam)
+{
+    return dsam->app_data;
+}
+
+int DSA_meth_set0_app_data(DSA_METHOD *dsam, void *app_data)
+{
+    dsam->app_data = app_data;
+    return 1;
+}
+
+DSA_SIG *(*DSA_meth_get_sign(const DSA_METHOD *dsam))
+        (const unsigned char *, int, DSA *)
+{
+    return dsam->dsa_do_sign;
+}
+
+int DSA_meth_set_sign(DSA_METHOD *dsam,
+                       DSA_SIG *(*sign) (const unsigned char *, int, DSA *))
+{
+    dsam->dsa_do_sign = sign;
+    return 1;
+}
+
+int (*DSA_meth_get_sign_setup(const DSA_METHOD *dsam))
+        (DSA *, BN_CTX *, BIGNUM **, BIGNUM **)
+{
+    return dsam->dsa_sign_setup;
+}
+
+int DSA_meth_set_sign_setup(DSA_METHOD *dsam,
+        int (*sign_setup) (DSA *, BN_CTX *, BIGNUM **, BIGNUM **))
+{
+    dsam->dsa_sign_setup = sign_setup;
+    return 1;
+}
+
+int (*DSA_meth_get_verify(const DSA_METHOD *dsam))
+        (const unsigned char *, int , DSA_SIG *, DSA *)
+{
+    return dsam->dsa_do_verify;
+}
+
+int DSA_meth_set_verify(DSA_METHOD *dsam,
+    int (*verify) (const unsigned char *, int, DSA_SIG *, DSA *))
+{
+    dsam->dsa_do_verify = verify;
+    return 1;
+}
+
+int (*DSA_meth_get_mod_exp(const DSA_METHOD *dsam))
+        (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *,
+         const BIGNUM *, const BIGNUM *, BN_CTX *, BN_MONT_CTX *)
+{
+    return dsam->dsa_mod_exp;
+}
+
+int DSA_meth_set_mod_exp(DSA_METHOD *dsam,
+    int (*mod_exp) (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *,
+                    const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *,
+                    BN_MONT_CTX *))
+{
+    dsam->dsa_mod_exp = mod_exp;
+    return 1;
+}
+
+int (*DSA_meth_get_bn_mod_exp(const DSA_METHOD *dsam))
+    (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *,
+     BN_MONT_CTX *)
+{
+    return dsam->bn_mod_exp;
+}
+
+int DSA_meth_set_bn_mod_exp(DSA_METHOD *dsam,
+    int (*bn_mod_exp) (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *,
+                       const BIGNUM *, BN_CTX *, BN_MONT_CTX *))
+{
+    dsam->bn_mod_exp = bn_mod_exp;
+    return 1;
+}
+
+int (*DSA_meth_get_init(const DSA_METHOD *dsam))(DSA *)
+{
+    return dsam->init;
+}
+
+int DSA_meth_set_init(DSA_METHOD *dsam, int (*init)(DSA *))
+{
+    dsam->init = init;
+    return 1;
+}
+
+int (*DSA_meth_get_finish(const DSA_METHOD *dsam)) (DSA *)
+{
+    return dsam->finish;
+}
+
+int DSA_meth_set_finish(DSA_METHOD *dsam, int (*finish) (DSA *))
+{
+    dsam->finish = finish;
+    return 1;
+}
+
+int (*DSA_meth_get_paramgen(const DSA_METHOD *dsam))
+        (DSA *, int, const unsigned char *, int, int *, unsigned long *,
+         BN_GENCB *)
+{
+    return dsam->dsa_paramgen;
+}
+
+int DSA_meth_set_paramgen(DSA_METHOD *dsam,
+        int (*paramgen) (DSA *, int, const unsigned char *, int, int *,
+                         unsigned long *, BN_GENCB *))
+{
+    dsam->dsa_paramgen = paramgen;
+    return 1;
+}
+
+int (*DSA_meth_get_keygen(const DSA_METHOD *dsam)) (DSA *)
+{
+    return dsam->dsa_keygen;
+}
+
+int DSA_meth_set_keygen(DSA_METHOD *dsam, int (*keygen) (DSA *))
+{
+    dsam->dsa_keygen = keygen;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_ossl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_ossl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_ossl.c	(revision 331)
@@ -0,0 +1,338 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/sha.h>
+#include "dsa_locl.h"
+#include <openssl/asn1.h>
+
+static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
+static int dsa_sign_setup_no_digest(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
+                                    BIGNUM **rp);
+static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
+                          BIGNUM **rp, const unsigned char *dgst, int dlen);
+static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
+                         DSA_SIG *sig, DSA *dsa);
+static int dsa_init(DSA *dsa);
+static int dsa_finish(DSA *dsa);
+
+static DSA_METHOD openssl_dsa_meth = {
+    "OpenSSL DSA method",
+    dsa_do_sign,
+    dsa_sign_setup_no_digest,
+    dsa_do_verify,
+    NULL,                       /* dsa_mod_exp, */
+    NULL,                       /* dsa_bn_mod_exp, */
+    dsa_init,
+    dsa_finish,
+    DSA_FLAG_FIPS_METHOD,
+    NULL,
+    NULL,
+    NULL
+};
+
+const DSA_METHOD *DSA_OpenSSL(void)
+{
+    return &openssl_dsa_meth;
+}
+
+static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+{
+    BIGNUM *kinv = NULL;
+    BIGNUM *m;
+    BIGNUM *xr;
+    BN_CTX *ctx = NULL;
+    int reason = ERR_R_BN_LIB;
+    DSA_SIG *ret = NULL;
+    int rv = 0;
+
+    m = BN_new();
+    xr = BN_new();
+    if (m == NULL || xr == NULL)
+        goto err;
+
+    if (!dsa->p || !dsa->q || !dsa->g) {
+        reason = DSA_R_MISSING_PARAMETERS;
+        goto err;
+    }
+
+    ret = DSA_SIG_new();
+    if (ret == NULL)
+        goto err;
+    ret->r = BN_new();
+    ret->s = BN_new();
+    if (ret->r == NULL || ret->s == NULL)
+        goto err;
+
+    ctx = BN_CTX_new();
+    if (ctx == NULL)
+        goto err;
+ redo:
+    if (!dsa_sign_setup(dsa, ctx, &kinv, &ret->r, dgst, dlen))
+        goto err;
+
+    if (dlen > BN_num_bytes(dsa->q))
+        /*
+         * if the digest length is greater than the size of q use the
+         * BN_num_bits(dsa->q) leftmost bits of the digest, see fips 186-3,
+         * 4.2
+         */
+        dlen = BN_num_bytes(dsa->q);
+    if (BN_bin2bn(dgst, dlen, m) == NULL)
+        goto err;
+
+    /* Compute  s = inv(k) (m + xr) mod q */
+    if (!BN_mod_mul(xr, dsa->priv_key, ret->r, dsa->q, ctx))
+        goto err;               /* s = xr */
+    if (!BN_add(ret->s, xr, m))
+        goto err;               /* s = m + xr */
+    if (BN_cmp(ret->s, dsa->q) > 0)
+        if (!BN_sub(ret->s, ret->s, dsa->q))
+            goto err;
+    if (!BN_mod_mul(ret->s, ret->s, kinv, dsa->q, ctx))
+        goto err;
+
+    /*
+     * Redo if r or s is zero as required by FIPS 186-3: this is very
+     * unlikely.
+     */
+    if (BN_is_zero(ret->r) || BN_is_zero(ret->s))
+        goto redo;
+
+    rv = 1;
+
+ err:
+    if (rv == 0) {
+        DSAerr(DSA_F_DSA_DO_SIGN, reason);
+        DSA_SIG_free(ret);
+        ret = NULL;
+    }
+    BN_CTX_free(ctx);
+    BN_clear_free(m);
+    BN_clear_free(xr);
+    BN_clear_free(kinv);
+    return ret;
+}
+
+static int dsa_sign_setup_no_digest(DSA *dsa, BN_CTX *ctx_in,
+                                    BIGNUM **kinvp, BIGNUM **rp)
+{
+    return dsa_sign_setup(dsa, ctx_in, kinvp, rp, NULL, 0);
+}
+
+static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in,
+                          BIGNUM **kinvp, BIGNUM **rp,
+                          const unsigned char *dgst, int dlen)
+{
+    BN_CTX *ctx = NULL;
+    BIGNUM *k, *kinv = NULL, *r = *rp;
+    int ret = 0;
+
+    if (!dsa->p || !dsa->q || !dsa->g) {
+        DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS);
+        return 0;
+    }
+
+    k = BN_new();
+    if (k == NULL)
+        goto err;
+
+    if (ctx_in == NULL) {
+        if ((ctx = BN_CTX_new()) == NULL)
+            goto err;
+    } else
+        ctx = ctx_in;
+
+    /* Get random k */
+    do {
+        if (dgst != NULL) {
+            /*
+             * We calculate k from SHA512(private_key + H(message) + random).
+             * This protects the private key from a weak PRNG.
+             */
+            if (!BN_generate_dsa_nonce(k, dsa->q, dsa->priv_key, dgst,
+                                       dlen, ctx))
+                goto err;
+        } else if (!BN_rand_range(k, dsa->q))
+            goto err;
+    } while (BN_is_zero(k));
+
+    BN_set_flags(k, BN_FLG_CONSTTIME);
+
+    if (dsa->flags & DSA_FLAG_CACHE_MONT_P) {
+        if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p,
+                                    dsa->lock, dsa->p, ctx))
+            goto err;
+    }
+
+    /* Compute r = (g^k mod p) mod q */
+
+    /*
+     * We do not want timing information to leak the length of k, so we
+     * compute g^k using an equivalent exponent of fixed length. (This
+     * is a kludge that we need because the BN_mod_exp_mont() does not
+     * let us specify the desired timing behaviour.)
+     */
+
+    if (!BN_add(k, k, dsa->q))
+        goto err;
+    if (BN_num_bits(k) <= BN_num_bits(dsa->q)) {
+        if (!BN_add(k, k, dsa->q))
+            goto err;
+    }
+
+    if ((dsa)->meth->bn_mod_exp != NULL) {
+            if (!dsa->meth->bn_mod_exp(dsa, r, dsa->g, k, dsa->p, ctx,
+                                       dsa->method_mont_p))
+                goto err;
+    } else {
+            if (!BN_mod_exp_mont(r, dsa->g, k, dsa->p, ctx, dsa->method_mont_p))
+                goto err;
+    }
+
+    if (!BN_mod(r, r, dsa->q, ctx))
+        goto err;
+
+    /* Compute  part of 's = inv(k) (m + xr) mod q' */
+    if ((kinv = BN_mod_inverse(NULL, k, dsa->q, ctx)) == NULL)
+        goto err;
+
+    BN_clear_free(*kinvp);
+    *kinvp = kinv;
+    kinv = NULL;
+    ret = 1;
+ err:
+    if (!ret)
+        DSAerr(DSA_F_DSA_SIGN_SETUP, ERR_R_BN_LIB);
+    if (ctx != ctx_in)
+        BN_CTX_free(ctx);
+    BN_clear_free(k);
+    return ret;
+}
+
+static int dsa_do_verify(const unsigned char *dgst, int dgst_len,
+                         DSA_SIG *sig, DSA *dsa)
+{
+    BN_CTX *ctx;
+    BIGNUM *u1, *u2, *t1;
+    BN_MONT_CTX *mont = NULL;
+    const BIGNUM *r, *s;
+    int ret = -1, i;
+    if (!dsa->p || !dsa->q || !dsa->g) {
+        DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MISSING_PARAMETERS);
+        return -1;
+    }
+
+    i = BN_num_bits(dsa->q);
+    /* fips 186-3 allows only different sizes for q */
+    if (i != 160 && i != 224 && i != 256) {
+        DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_BAD_Q_VALUE);
+        return -1;
+    }
+
+    if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) {
+        DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MODULUS_TOO_LARGE);
+        return -1;
+    }
+    u1 = BN_new();
+    u2 = BN_new();
+    t1 = BN_new();
+    ctx = BN_CTX_new();
+    if (u1 == NULL || u2 == NULL || t1 == NULL || ctx == NULL)
+        goto err;
+
+    DSA_SIG_get0(sig, &r, &s);
+
+    if (BN_is_zero(r) || BN_is_negative(r) ||
+        BN_ucmp(r, dsa->q) >= 0) {
+        ret = 0;
+        goto err;
+    }
+    if (BN_is_zero(s) || BN_is_negative(s) ||
+        BN_ucmp(s, dsa->q) >= 0) {
+        ret = 0;
+        goto err;
+    }
+
+    /*
+     * Calculate W = inv(S) mod Q save W in u2
+     */
+    if ((BN_mod_inverse(u2, s, dsa->q, ctx)) == NULL)
+        goto err;
+
+    /* save M in u1 */
+    if (dgst_len > (i >> 3))
+        /*
+         * if the digest length is greater than the size of q use the
+         * BN_num_bits(dsa->q) leftmost bits of the digest, see fips 186-3,
+         * 4.2
+         */
+        dgst_len = (i >> 3);
+    if (BN_bin2bn(dgst, dgst_len, u1) == NULL)
+        goto err;
+
+    /* u1 = M * w mod q */
+    if (!BN_mod_mul(u1, u1, u2, dsa->q, ctx))
+        goto err;
+
+    /* u2 = r * w mod q */
+    if (!BN_mod_mul(u2, r, u2, dsa->q, ctx))
+        goto err;
+
+    if (dsa->flags & DSA_FLAG_CACHE_MONT_P) {
+        mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p,
+                                      dsa->lock, dsa->p, ctx);
+        if (!mont)
+            goto err;
+    }
+
+    if (dsa->meth->dsa_mod_exp != NULL) {
+        if (!dsa->meth->dsa_mod_exp(dsa, t1, dsa->g, u1, dsa->pub_key, u2,
+                                    dsa->p, ctx, mont))
+            goto err;
+    } else {
+        if (!BN_mod_exp2_mont(t1, dsa->g, u1, dsa->pub_key, u2, dsa->p, ctx,
+                              mont))
+            goto err;
+    }
+
+    /* let u1 = u1 mod q */
+    if (!BN_mod(u1, t1, dsa->q, ctx))
+        goto err;
+
+    /*
+     * V is now in u1.  If the signature is correct, it will be equal to R.
+     */
+    ret = (BN_ucmp(u1, r) == 0);
+
+ err:
+    if (ret < 0)
+        DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_BN_LIB);
+    BN_CTX_free(ctx);
+    BN_free(u1);
+    BN_free(u2);
+    BN_free(t1);
+    return (ret);
+}
+
+static int dsa_init(DSA *dsa)
+{
+    dsa->flags |= DSA_FLAG_CACHE_MONT_P;
+    return (1);
+}
+
+static int dsa_finish(DSA *dsa)
+{
+    BN_MONT_CTX_free(dsa->method_mont_p);
+    return (1);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_pmeth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_pmeth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_pmeth.c	(revision 331)
@@ -0,0 +1,273 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include "internal/evp_int.h"
+#include "dsa_locl.h"
+
+/* DSA pkey context structure */
+
+typedef struct {
+    /* Parameter gen parameters */
+    int nbits;                  /* size of p in bits (default: 1024) */
+    int qbits;                  /* size of q in bits (default: 160) */
+    const EVP_MD *pmd;          /* MD for parameter generation */
+    /* Keygen callback info */
+    int gentmp[2];
+    /* message digest */
+    const EVP_MD *md;           /* MD for the signature */
+} DSA_PKEY_CTX;
+
+static int pkey_dsa_init(EVP_PKEY_CTX *ctx)
+{
+    DSA_PKEY_CTX *dctx;
+    dctx = OPENSSL_malloc(sizeof(*dctx));
+    if (dctx == NULL)
+        return 0;
+    dctx->nbits = 1024;
+    dctx->qbits = 160;
+    dctx->pmd = NULL;
+    dctx->md = NULL;
+
+    ctx->data = dctx;
+    ctx->keygen_info = dctx->gentmp;
+    ctx->keygen_info_count = 2;
+
+    return 1;
+}
+
+static int pkey_dsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+{
+    DSA_PKEY_CTX *dctx, *sctx;
+    if (!pkey_dsa_init(dst))
+        return 0;
+    sctx = src->data;
+    dctx = dst->data;
+    dctx->nbits = sctx->nbits;
+    dctx->qbits = sctx->qbits;
+    dctx->pmd = sctx->pmd;
+    dctx->md = sctx->md;
+    return 1;
+}
+
+static void pkey_dsa_cleanup(EVP_PKEY_CTX *ctx)
+{
+    DSA_PKEY_CTX *dctx = ctx->data;
+    OPENSSL_free(dctx);
+}
+
+static int pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
+                         size_t *siglen, const unsigned char *tbs,
+                         size_t tbslen)
+{
+    int ret;
+    unsigned int sltmp;
+    DSA_PKEY_CTX *dctx = ctx->data;
+    DSA *dsa = ctx->pkey->pkey.dsa;
+
+    if (dctx->md) {
+        if (tbslen != (size_t)EVP_MD_size(dctx->md))
+            return 0;
+    } else {
+        if (tbslen != SHA_DIGEST_LENGTH)
+            return 0;
+    }
+
+    ret = DSA_sign(0, tbs, tbslen, sig, &sltmp, dsa);
+
+    if (ret <= 0)
+        return ret;
+    *siglen = sltmp;
+    return 1;
+}
+
+static int pkey_dsa_verify(EVP_PKEY_CTX *ctx,
+                           const unsigned char *sig, size_t siglen,
+                           const unsigned char *tbs, size_t tbslen)
+{
+    int ret;
+    DSA_PKEY_CTX *dctx = ctx->data;
+    DSA *dsa = ctx->pkey->pkey.dsa;
+
+    if (dctx->md) {
+        if (tbslen != (size_t)EVP_MD_size(dctx->md))
+            return 0;
+    } else {
+        if (tbslen != SHA_DIGEST_LENGTH)
+            return 0;
+    }
+
+    ret = DSA_verify(0, tbs, tbslen, sig, siglen, dsa);
+
+    return ret;
+}
+
+static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+    DSA_PKEY_CTX *dctx = ctx->data;
+    switch (type) {
+    case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS:
+        if (p1 < 256)
+            return -2;
+        dctx->nbits = p1;
+        return 1;
+
+    case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS:
+        if (p1 != 160 && p1 != 224 && p1 && p1 != 256)
+            return -2;
+        dctx->qbits = p1;
+        return 1;
+
+    case EVP_PKEY_CTRL_DSA_PARAMGEN_MD:
+        if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
+            EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
+            EVP_MD_type((const EVP_MD *)p2) != NID_sha256) {
+            DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
+            return 0;
+        }
+        dctx->pmd = p2;
+        return 1;
+
+    case EVP_PKEY_CTRL_MD:
+        if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
+            EVP_MD_type((const EVP_MD *)p2) != NID_dsa &&
+            EVP_MD_type((const EVP_MD *)p2) != NID_dsaWithSHA &&
+            EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
+            EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
+            EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
+            EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
+            DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
+            return 0;
+        }
+        dctx->md = p2;
+        return 1;
+
+    case EVP_PKEY_CTRL_GET_MD:
+        *(const EVP_MD **)p2 = dctx->md;
+        return 1;
+
+    case EVP_PKEY_CTRL_DIGESTINIT:
+    case EVP_PKEY_CTRL_PKCS7_SIGN:
+    case EVP_PKEY_CTRL_CMS_SIGN:
+        return 1;
+
+    case EVP_PKEY_CTRL_PEER_KEY:
+        DSAerr(DSA_F_PKEY_DSA_CTRL,
+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        return -2;
+    default:
+        return -2;
+
+    }
+}
+
+static int pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx,
+                             const char *type, const char *value)
+{
+    if (strcmp(type, "dsa_paramgen_bits") == 0) {
+        int nbits;
+        nbits = atoi(value);
+        return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits);
+    }
+    if (strcmp(type, "dsa_paramgen_q_bits") == 0) {
+        int qbits = atoi(value);
+        return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN,
+                                 EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, qbits,
+                                 NULL);
+    }
+    if (strcmp(type, "dsa_paramgen_md") == 0) {
+        return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN,
+                                 EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0,
+                                 (void *)EVP_get_digestbyname(value));
+    }
+    return -2;
+}
+
+static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+    DSA *dsa = NULL;
+    DSA_PKEY_CTX *dctx = ctx->data;
+    BN_GENCB *pcb;
+    int ret;
+    if (ctx->pkey_gencb) {
+        pcb = BN_GENCB_new();
+        if (pcb == NULL)
+            return 0;
+        evp_pkey_set_cb_translate(pcb, ctx);
+    } else
+        pcb = NULL;
+    dsa = DSA_new();
+    if (dsa == NULL) {
+        BN_GENCB_free(pcb);
+        return 0;
+    }
+    ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd,
+                               NULL, 0, NULL, NULL, NULL, pcb);
+    BN_GENCB_free(pcb);
+    if (ret)
+        EVP_PKEY_assign_DSA(pkey, dsa);
+    else
+        DSA_free(dsa);
+    return ret;
+}
+
+static int pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+    DSA *dsa = NULL;
+    if (ctx->pkey == NULL) {
+        DSAerr(DSA_F_PKEY_DSA_KEYGEN, DSA_R_NO_PARAMETERS_SET);
+        return 0;
+    }
+    dsa = DSA_new();
+    if (dsa == NULL)
+        return 0;
+    EVP_PKEY_assign_DSA(pkey, dsa);
+    /* Note: if error return, pkey is freed by parent routine */
+    if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
+        return 0;
+    return DSA_generate_key(pkey->pkey.dsa);
+}
+
+const EVP_PKEY_METHOD dsa_pkey_meth = {
+    EVP_PKEY_DSA,
+    EVP_PKEY_FLAG_AUTOARGLEN,
+    pkey_dsa_init,
+    pkey_dsa_copy,
+    pkey_dsa_cleanup,
+
+    0,
+    pkey_dsa_paramgen,
+
+    0,
+    pkey_dsa_keygen,
+
+    0,
+    pkey_dsa_sign,
+
+    0,
+    pkey_dsa_verify,
+
+    0, 0,
+
+    0, 0, 0, 0,
+
+    0, 0,
+
+    0, 0,
+
+    0, 0,
+
+    pkey_dsa_ctrl,
+    pkey_dsa_ctrl_str
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_prn.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_prn.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_prn.c	(revision 331)
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/dsa.h>
+
+#ifndef OPENSSL_NO_STDIO
+int DSA_print_fp(FILE *fp, const DSA *x, int off)
+{
+    BIO *b;
+    int ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        DSAerr(DSA_F_DSA_PRINT_FP, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = DSA_print(b, x, off);
+    BIO_free(b);
+    return (ret);
+}
+
+int DSAparams_print_fp(FILE *fp, const DSA *x)
+{
+    BIO *b;
+    int ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        DSAerr(DSA_F_DSAPARAMS_PRINT_FP, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = DSAparams_print(b, x);
+    BIO_free(b);
+    return (ret);
+}
+#endif
+
+int DSA_print(BIO *bp, const DSA *x, int off)
+{
+    EVP_PKEY *pk;
+    int ret;
+    pk = EVP_PKEY_new();
+    if (pk == NULL || !EVP_PKEY_set1_DSA(pk, (DSA *)x))
+        return 0;
+    ret = EVP_PKEY_print_private(bp, pk, off, NULL);
+    EVP_PKEY_free(pk);
+    return ret;
+}
+
+int DSAparams_print(BIO *bp, const DSA *x)
+{
+    EVP_PKEY *pk;
+    int ret;
+    pk = EVP_PKEY_new();
+    if (pk == NULL || !EVP_PKEY_set1_DSA(pk, (DSA *)x))
+        return 0;
+    ret = EVP_PKEY_print_params(bp, pk, 4, NULL);
+    EVP_PKEY_free(pk);
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_sign.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_sign.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_sign.c	(revision 331)
@@ -0,0 +1,24 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+#include "internal/cryptlib.h"
+#include "dsa_locl.h"
+#include <openssl/bn.h>
+
+DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+{
+    return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
+}
+
+int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
+{
+    return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_vrf.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_vrf.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dsa/dsa_vrf.c	(revision 331)
@@ -0,0 +1,19 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+#include "internal/cryptlib.h"
+#include "dsa_locl.h"
+
+int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
+                  DSA *dsa)
+{
+    return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_dl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_dl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_dl.c	(revision 331)
@@ -0,0 +1,279 @@
+/*
+ * Copyright 2000-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 "dso_locl.h"
+
+#ifdef DSO_DL
+
+# include <dl.h>
+
+/* Part of the hack in "dl_load" ... */
+# define DSO_MAX_TRANSLATED_SIZE 256
+
+static int dl_load(DSO *dso);
+static int dl_unload(DSO *dso);
+static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname);
+static char *dl_name_converter(DSO *dso, const char *filename);
+static char *dl_merger(DSO *dso, const char *filespec1,
+                       const char *filespec2);
+static int dl_pathbyaddr(void *addr, char *path, int sz);
+static void *dl_globallookup(const char *name);
+
+static DSO_METHOD dso_meth_dl = {
+    "OpenSSL 'dl' shared library method",
+    dl_load,
+    dl_unload,
+    dl_bind_func,
+    NULL,                       /* ctrl */
+    dl_name_converter,
+    dl_merger,
+    NULL,                       /* init */
+    NULL,                       /* finish */
+    dl_pathbyaddr,
+    dl_globallookup
+};
+
+DSO_METHOD *DSO_METHOD_openssl(void)
+{
+    return &dso_meth_dl;
+}
+
+/*
+ * For this DSO_METHOD, our meth_data STACK will contain; (i) the handle
+ * (shl_t) returned from shl_load(). NB: I checked on HPUX11 and shl_t is
+ * itself a pointer type so the cast is safe.
+ */
+
+static int dl_load(DSO *dso)
+{
+    shl_t ptr = NULL;
+    /*
+     * We don't do any fancy retries or anything, just take the method's (or
+     * DSO's if it has the callback set) best translation of the
+     * platform-independent filename and try once with that.
+     */
+    char *filename = DSO_convert_filename(dso, NULL);
+
+    if (filename == NULL) {
+        DSOerr(DSO_F_DL_LOAD, DSO_R_NO_FILENAME);
+        goto err;
+    }
+    ptr = shl_load(filename, BIND_IMMEDIATE |
+                   (dso->flags & DSO_FLAG_NO_NAME_TRANSLATION ? 0 :
+                    DYNAMIC_PATH), 0L);
+    if (ptr == NULL) {
+        char errbuf[160];
+        DSOerr(DSO_F_DL_LOAD, DSO_R_LOAD_FAILED);
+        if (openssl_strerror_r(errno, errbuf, sizeof(errbuf)))
+            ERR_add_error_data(4, "filename(", filename, "): ", errbuf);
+        goto err;
+    }
+    if (!sk_push(dso->meth_data, (char *)ptr)) {
+        DSOerr(DSO_F_DL_LOAD, DSO_R_STACK_ERROR);
+        goto err;
+    }
+    /*
+     * Success, stick the converted filename we've loaded under into the DSO
+     * (it also serves as the indicator that we are currently loaded).
+     */
+    dso->loaded_filename = filename;
+    return (1);
+ err:
+    /* Cleanup! */
+    OPENSSL_free(filename);
+    if (ptr != NULL)
+        shl_unload(ptr);
+    return (0);
+}
+
+static int dl_unload(DSO *dso)
+{
+    shl_t ptr;
+    if (dso == NULL) {
+        DSOerr(DSO_F_DL_UNLOAD, ERR_R_PASSED_NULL_PARAMETER);
+        return (0);
+    }
+    if (sk_num(dso->meth_data) < 1)
+        return (1);
+    /* Is this statement legal? */
+    ptr = (shl_t) sk_pop(dso->meth_data);
+    if (ptr == NULL) {
+        DSOerr(DSO_F_DL_UNLOAD, DSO_R_NULL_HANDLE);
+        /*
+         * Should push the value back onto the stack in case of a retry.
+         */
+        sk_push(dso->meth_data, (char *)ptr);
+        return (0);
+    }
+    shl_unload(ptr);
+    return (1);
+}
+
+static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname)
+{
+    shl_t ptr;
+    void *sym;
+
+    if ((dso == NULL) || (symname == NULL)) {
+        DSOerr(DSO_F_DL_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER);
+        return (NULL);
+    }
+    if (sk_num(dso->meth_data) < 1) {
+        DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_STACK_ERROR);
+        return (NULL);
+    }
+    ptr = (shl_t) sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
+    if (ptr == NULL) {
+        DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_NULL_HANDLE);
+        return (NULL);
+    }
+    if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0) {
+        char errbuf[160];
+        DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_SYM_FAILURE);
+        if (openssl_strerror_r(errno, errbuf, sizeof(errbuf)))
+            ERR_add_error_data(4, "symname(", symname, "): ", errbuf);
+        return (NULL);
+    }
+    return ((DSO_FUNC_TYPE)sym);
+}
+
+static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2)
+{
+    char *merged;
+
+    if (!filespec1 && !filespec2) {
+        DSOerr(DSO_F_DL_MERGER, ERR_R_PASSED_NULL_PARAMETER);
+        return (NULL);
+    }
+    /*
+     * If the first file specification is a rooted path, it rules. same goes
+     * if the second file specification is missing.
+     */
+    if (!filespec2 || filespec1[0] == '/') {
+        merged = OPENSSL_strdup(filespec1);
+        if (merged == NULL) {
+            DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE);
+            return (NULL);
+        }
+    }
+    /*
+     * If the first file specification is missing, the second one rules.
+     */
+    else if (!filespec1) {
+        merged = OPENSSL_strdup(filespec2);
+        if (merged == NULL) {
+            DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE);
+            return (NULL);
+        }
+    } else
+        /*
+         * This part isn't as trivial as it looks.  It assumes that the
+         * second file specification really is a directory, and makes no
+         * checks whatsoever.  Therefore, the result becomes the
+         * concatenation of filespec2 followed by a slash followed by
+         * filespec1.
+         */
+    {
+        int spec2len, len;
+
+        spec2len = (filespec2 ? strlen(filespec2) : 0);
+        len = spec2len + (filespec1 ? strlen(filespec1) : 0);
+
+        if (spec2len && filespec2[spec2len - 1] == '/') {
+            spec2len--;
+            len--;
+        }
+        merged = OPENSSL_malloc(len + 2);
+        if (merged == NULL) {
+            DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE);
+            return (NULL);
+        }
+        strcpy(merged, filespec2);
+        merged[spec2len] = '/';
+        strcpy(&merged[spec2len + 1], filespec1);
+    }
+    return (merged);
+}
+
+/*
+ * This function is identical to the one in dso_dlfcn.c, but as it is highly
+ * unlikely that both the "dl" *and* "dlfcn" variants are being compiled at
+ * the same time, there's no great duplicating the code. Figuring out an
+ * elegant way to share one copy of the code would be more difficult and
+ * would not leave the implementations independent.
+ */
+static char *dl_name_converter(DSO *dso, const char *filename)
+{
+    char *translated;
+    int len, rsize, transform;
+
+    len = strlen(filename);
+    rsize = len + 1;
+    transform = (strstr(filename, "/") == NULL);
+    {
+        /* We will convert this to "%s.s?" or "lib%s.s?" */
+        rsize += strlen(DSO_EXTENSION); /* The length of ".s?" */
+        if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
+            rsize += 3;         /* The length of "lib" */
+    }
+    translated = OPENSSL_malloc(rsize);
+    if (translated == NULL) {
+        DSOerr(DSO_F_DL_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED);
+        return (NULL);
+    }
+    if (transform) {
+        if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
+            sprintf(translated, "lib%s%s", filename, DSO_EXTENSION);
+        else
+            sprintf(translated, "%s%s", filename, DSO_EXTENSION);
+    } else
+        sprintf(translated, "%s", filename);
+    return (translated);
+}
+
+static int dl_pathbyaddr(void *addr, char *path, int sz)
+{
+    struct shl_descriptor inf;
+    int i, len;
+
+    if (addr == NULL) {
+        union {
+            int (*f) (void *, char *, int);
+            void *p;
+        } t = {
+            dl_pathbyaddr
+        };
+        addr = t.p;
+    }
+
+    for (i = -1; shl_get_r(i, &inf) == 0; i++) {
+        if (((size_t)addr >= inf.tstart && (size_t)addr < inf.tend) ||
+            ((size_t)addr >= inf.dstart && (size_t)addr < inf.dend)) {
+            len = (int)strlen(inf.filename);
+            if (sz <= 0)
+                return len + 1;
+            if (len >= sz)
+                len = sz - 1;
+            memcpy(path, inf.filename, len);
+            path[len++] = 0;
+            return len;
+        }
+    }
+
+    return -1;
+}
+
+static void *dl_globallookup(const char *name)
+{
+    void *ret;
+    shl_t h = NULL;
+
+    return shl_findsym(&h, name, TYPE_UNDEFINED, &ret) ? NULL : ret;
+}
+#endif                          /* DSO_DL */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_dlfcn.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_dlfcn.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_dlfcn.c	(revision 331)
@@ -0,0 +1,354 @@
+/*
+ * Copyright 2000-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
+ */
+
+/*
+ * We need to do this early, because stdio.h includes the header files that
+ * handle _GNU_SOURCE and other similar macros.  Defining it later is simply
+ * too late, because those headers are protected from re- inclusion.
+ */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE            /* make sure dladdr is declared */
+#endif
+
+#include "dso_locl.h"
+
+#ifdef DSO_DLFCN
+
+# ifdef HAVE_DLFCN_H
+#  ifdef __osf__
+#   define __EXTENSIONS__
+#  endif
+#  include <dlfcn.h>
+#  define HAVE_DLINFO 1
+#  if defined(_AIX) || defined(__CYGWIN__) || \
+     defined(__SCO_VERSION__) || defined(_SCO_ELF) || \
+     (defined(__osf__) && !defined(RTLD_NEXT))     || \
+     (defined(__OpenBSD__) && !defined(RTLD_SELF)) || \
+        defined(__ANDROID__)
+#   undef HAVE_DLINFO
+#  endif
+# endif
+
+/* Part of the hack in "dlfcn_load" ... */
+# define DSO_MAX_TRANSLATED_SIZE 256
+
+static int dlfcn_load(DSO *dso);
+static int dlfcn_unload(DSO *dso);
+static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname);
+static char *dlfcn_name_converter(DSO *dso, const char *filename);
+static char *dlfcn_merger(DSO *dso, const char *filespec1,
+                          const char *filespec2);
+static int dlfcn_pathbyaddr(void *addr, char *path, int sz);
+static void *dlfcn_globallookup(const char *name);
+
+static DSO_METHOD dso_meth_dlfcn = {
+    "OpenSSL 'dlfcn' shared library method",
+    dlfcn_load,
+    dlfcn_unload,
+    dlfcn_bind_func,
+    NULL,                       /* ctrl */
+    dlfcn_name_converter,
+    dlfcn_merger,
+    NULL,                       /* init */
+    NULL,                       /* finish */
+    dlfcn_pathbyaddr,
+    dlfcn_globallookup
+};
+
+DSO_METHOD *DSO_METHOD_openssl(void)
+{
+    return &dso_meth_dlfcn;
+}
+
+/*
+ * Prior to using the dlopen() function, we should decide on the flag we
+ * send. There's a few different ways of doing this and it's a messy
+ * venn-diagram to match up which platforms support what. So as we don't have
+ * autoconf yet, I'm implementing a hack that could be hacked further
+ * relatively easily to deal with cases as we find them. Initially this is to
+ * cope with OpenBSD.
+ */
+# if defined(__OpenBSD__) || defined(__NetBSD__)
+#  ifdef DL_LAZY
+#   define DLOPEN_FLAG DL_LAZY
+#  else
+#   ifdef RTLD_NOW
+#    define DLOPEN_FLAG RTLD_NOW
+#   else
+#    define DLOPEN_FLAG 0
+#   endif
+#  endif
+# else
+#  define DLOPEN_FLAG RTLD_NOW  /* Hope this works everywhere else */
+# endif
+
+/*
+ * For this DSO_METHOD, our meth_data STACK will contain; (i) the handle
+ * (void*) returned from dlopen().
+ */
+
+static int dlfcn_load(DSO *dso)
+{
+    void *ptr = NULL;
+    /* See applicable comments in dso_dl.c */
+    char *filename = DSO_convert_filename(dso, NULL);
+    int flags = DLOPEN_FLAG;
+
+    if (filename == NULL) {
+        DSOerr(DSO_F_DLFCN_LOAD, DSO_R_NO_FILENAME);
+        goto err;
+    }
+# ifdef RTLD_GLOBAL
+    if (dso->flags & DSO_FLAG_GLOBAL_SYMBOLS)
+        flags |= RTLD_GLOBAL;
+# endif
+    ptr = dlopen(filename, flags);
+    if (ptr == NULL) {
+        DSOerr(DSO_F_DLFCN_LOAD, DSO_R_LOAD_FAILED);
+        ERR_add_error_data(4, "filename(", filename, "): ", dlerror());
+        goto err;
+    }
+    if (!sk_void_push(dso->meth_data, (char *)ptr)) {
+        DSOerr(DSO_F_DLFCN_LOAD, DSO_R_STACK_ERROR);
+        goto err;
+    }
+    /* Success */
+    dso->loaded_filename = filename;
+    return (1);
+ err:
+    /* Cleanup! */
+    OPENSSL_free(filename);
+    if (ptr != NULL)
+        dlclose(ptr);
+    return (0);
+}
+
+static int dlfcn_unload(DSO *dso)
+{
+    void *ptr;
+    if (dso == NULL) {
+        DSOerr(DSO_F_DLFCN_UNLOAD, ERR_R_PASSED_NULL_PARAMETER);
+        return (0);
+    }
+    if (sk_void_num(dso->meth_data) < 1)
+        return (1);
+    ptr = sk_void_pop(dso->meth_data);
+    if (ptr == NULL) {
+        DSOerr(DSO_F_DLFCN_UNLOAD, DSO_R_NULL_HANDLE);
+        /*
+         * Should push the value back onto the stack in case of a retry.
+         */
+        sk_void_push(dso->meth_data, ptr);
+        return (0);
+    }
+    /* For now I'm not aware of any errors associated with dlclose() */
+    dlclose(ptr);
+    return (1);
+}
+
+static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname)
+{
+    void *ptr;
+    union {
+        DSO_FUNC_TYPE sym;
+        void *dlret;
+    } u;
+
+    if ((dso == NULL) || (symname == NULL)) {
+        DSOerr(DSO_F_DLFCN_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER);
+        return (NULL);
+    }
+    if (sk_void_num(dso->meth_data) < 1) {
+        DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_STACK_ERROR);
+        return (NULL);
+    }
+    ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
+    if (ptr == NULL) {
+        DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_NULL_HANDLE);
+        return (NULL);
+    }
+    u.dlret = dlsym(ptr, symname);
+    if (u.dlret == NULL) {
+        DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_SYM_FAILURE);
+        ERR_add_error_data(4, "symname(", symname, "): ", dlerror());
+        return (NULL);
+    }
+    return u.sym;
+}
+
+static char *dlfcn_merger(DSO *dso, const char *filespec1,
+                          const char *filespec2)
+{
+    char *merged;
+
+    if (!filespec1 && !filespec2) {
+        DSOerr(DSO_F_DLFCN_MERGER, ERR_R_PASSED_NULL_PARAMETER);
+        return (NULL);
+    }
+    /*
+     * If the first file specification is a rooted path, it rules. same goes
+     * if the second file specification is missing.
+     */
+    if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/')) {
+        merged = OPENSSL_strdup(filespec1);
+        if (merged == NULL) {
+            DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE);
+            return (NULL);
+        }
+    }
+    /*
+     * If the first file specification is missing, the second one rules.
+     */
+    else if (!filespec1) {
+        merged = OPENSSL_strdup(filespec2);
+        if (merged == NULL) {
+            DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE);
+            return (NULL);
+        }
+    } else {
+        /*
+         * This part isn't as trivial as it looks.  It assumes that the
+         * second file specification really is a directory, and makes no
+         * checks whatsoever.  Therefore, the result becomes the
+         * concatenation of filespec2 followed by a slash followed by
+         * filespec1.
+         */
+        int spec2len, len;
+
+        spec2len = strlen(filespec2);
+        len = spec2len + strlen(filespec1);
+
+        if (spec2len && filespec2[spec2len - 1] == '/') {
+            spec2len--;
+            len--;
+        }
+        merged = OPENSSL_malloc(len + 2);
+        if (merged == NULL) {
+            DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE);
+            return (NULL);
+        }
+        strcpy(merged, filespec2);
+        merged[spec2len] = '/';
+        strcpy(&merged[spec2len + 1], filespec1);
+    }
+    return (merged);
+}
+
+static char *dlfcn_name_converter(DSO *dso, const char *filename)
+{
+    char *translated;
+    int len, rsize, transform;
+
+    len = strlen(filename);
+    rsize = len + 1;
+    transform = (strstr(filename, "/") == NULL);
+    if (transform) {
+        /* We will convert this to "%s.so" or "lib%s.so" etc */
+        rsize += strlen(DSO_EXTENSION);    /* The length of ".so" */
+        if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
+            rsize += 3;         /* The length of "lib" */
+    }
+    translated = OPENSSL_malloc(rsize);
+    if (translated == NULL) {
+        DSOerr(DSO_F_DLFCN_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED);
+        return (NULL);
+    }
+    if (transform) {
+        if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
+            sprintf(translated, "lib%s" DSO_EXTENSION, filename);
+        else
+            sprintf(translated, "%s" DSO_EXTENSION, filename);
+    } else
+        sprintf(translated, "%s", filename);
+    return (translated);
+}
+
+# ifdef __sgi
+/*-
+This is a quote from IRIX manual for dladdr(3c):
+
+     <dlfcn.h> does not contain a prototype for dladdr or definition of
+     Dl_info.  The #include <dlfcn.h>  in the SYNOPSIS line is traditional,
+     but contains no dladdr prototype and no IRIX library contains an
+     implementation.  Write your own declaration based on the code below.
+
+     The following code is dependent on internal interfaces that are not
+     part of the IRIX compatibility guarantee; however, there is no future
+     intention to change this interface, so on a practical level, the code
+     below is safe to use on IRIX.
+*/
+#  include <rld_interface.h>
+#  ifndef _RLD_INTERFACE_DLFCN_H_DLADDR
+#   define _RLD_INTERFACE_DLFCN_H_DLADDR
+typedef struct Dl_info {
+    const char *dli_fname;
+    void *dli_fbase;
+    const char *dli_sname;
+    void *dli_saddr;
+    int dli_version;
+    int dli_reserved1;
+    long dli_reserved[4];
+} Dl_info;
+#  else
+typedef struct Dl_info Dl_info;
+#  endif
+#  define _RLD_DLADDR             14
+
+static int dladdr(void *address, Dl_info *dl)
+{
+    void *v;
+    v = _rld_new_interface(_RLD_DLADDR, address, dl);
+    return (int)v;
+}
+# endif                         /* __sgi */
+
+static int dlfcn_pathbyaddr(void *addr, char *path, int sz)
+{
+# ifdef HAVE_DLINFO
+    Dl_info dli;
+    int len;
+
+    if (addr == NULL) {
+        union {
+            int (*f) (void *, char *, int);
+            void *p;
+        } t = {
+            dlfcn_pathbyaddr
+        };
+        addr = t.p;
+    }
+
+    if (dladdr(addr, &dli)) {
+        len = (int)strlen(dli.dli_fname);
+        if (sz <= 0)
+            return len + 1;
+        if (len >= sz)
+            len = sz - 1;
+        memcpy(path, dli.dli_fname, len);
+        path[len++] = 0;
+        return len;
+    }
+
+    ERR_add_error_data(2, "dlfcn_pathbyaddr(): ", dlerror());
+# endif
+    return -1;
+}
+
+static void *dlfcn_globallookup(const char *name)
+{
+    void *ret = NULL, *handle = dlopen(NULL, RTLD_LAZY);
+
+    if (handle) {
+        ret = dlsym(handle, name);
+        dlclose(handle);
+    }
+
+    return ret;
+}
+#endif                          /* DSO_DLFCN */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_err.c	(revision 331)
@@ -0,0 +1,93 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include "internal/dso.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_DSO,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_DSO,0,reason)
+
+static ERR_STRING_DATA DSO_str_functs[] = {
+    {ERR_FUNC(DSO_F_DLFCN_BIND_FUNC), "dlfcn_bind_func"},
+    {ERR_FUNC(DSO_F_DLFCN_LOAD), "dlfcn_load"},
+    {ERR_FUNC(DSO_F_DLFCN_MERGER), "dlfcn_merger"},
+    {ERR_FUNC(DSO_F_DLFCN_NAME_CONVERTER), "dlfcn_name_converter"},
+    {ERR_FUNC(DSO_F_DLFCN_UNLOAD), "dlfcn_unload"},
+    {ERR_FUNC(DSO_F_DL_BIND_FUNC), "dl_bind_func"},
+    {ERR_FUNC(DSO_F_DL_LOAD), "dl_load"},
+    {ERR_FUNC(DSO_F_DL_MERGER), "dl_merger"},
+    {ERR_FUNC(DSO_F_DL_NAME_CONVERTER), "dl_name_converter"},
+    {ERR_FUNC(DSO_F_DL_UNLOAD), "dl_unload"},
+    {ERR_FUNC(DSO_F_DSO_BIND_FUNC), "DSO_bind_func"},
+    {ERR_FUNC(DSO_F_DSO_CONVERT_FILENAME), "DSO_convert_filename"},
+    {ERR_FUNC(DSO_F_DSO_CTRL), "DSO_ctrl"},
+    {ERR_FUNC(DSO_F_DSO_FREE), "DSO_free"},
+    {ERR_FUNC(DSO_F_DSO_GET_FILENAME), "DSO_get_filename"},
+    {ERR_FUNC(DSO_F_DSO_GLOBAL_LOOKUP), "DSO_global_lookup"},
+    {ERR_FUNC(DSO_F_DSO_LOAD), "DSO_load"},
+    {ERR_FUNC(DSO_F_DSO_MERGE), "DSO_merge"},
+    {ERR_FUNC(DSO_F_DSO_NEW_METHOD), "DSO_new_method"},
+    {ERR_FUNC(DSO_F_DSO_PATHBYADDR), "DSO_pathbyaddr"},
+    {ERR_FUNC(DSO_F_DSO_SET_FILENAME), "DSO_set_filename"},
+    {ERR_FUNC(DSO_F_DSO_UP_REF), "DSO_up_ref"},
+    {ERR_FUNC(DSO_F_VMS_BIND_SYM), "vms_bind_sym"},
+    {ERR_FUNC(DSO_F_VMS_LOAD), "vms_load"},
+    {ERR_FUNC(DSO_F_VMS_MERGER), "vms_merger"},
+    {ERR_FUNC(DSO_F_VMS_UNLOAD), "vms_unload"},
+    {ERR_FUNC(DSO_F_WIN32_BIND_FUNC), "win32_bind_func"},
+    {ERR_FUNC(DSO_F_WIN32_GLOBALLOOKUP), "win32_globallookup"},
+    {ERR_FUNC(DSO_F_WIN32_JOINER), "win32_joiner"},
+    {ERR_FUNC(DSO_F_WIN32_LOAD), "win32_load"},
+    {ERR_FUNC(DSO_F_WIN32_MERGER), "win32_merger"},
+    {ERR_FUNC(DSO_F_WIN32_NAME_CONVERTER), "win32_name_converter"},
+    {ERR_FUNC(DSO_F_WIN32_PATHBYADDR), "win32_pathbyaddr"},
+    {ERR_FUNC(DSO_F_WIN32_SPLITTER), "win32_splitter"},
+    {ERR_FUNC(DSO_F_WIN32_UNLOAD), "win32_unload"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA DSO_str_reasons[] = {
+    {ERR_REASON(DSO_R_CTRL_FAILED), "control command failed"},
+    {ERR_REASON(DSO_R_DSO_ALREADY_LOADED), "dso already loaded"},
+    {ERR_REASON(DSO_R_EMPTY_FILE_STRUCTURE), "empty file structure"},
+    {ERR_REASON(DSO_R_FAILURE), "failure"},
+    {ERR_REASON(DSO_R_FILENAME_TOO_BIG), "filename too big"},
+    {ERR_REASON(DSO_R_FINISH_FAILED), "cleanup method function failed"},
+    {ERR_REASON(DSO_R_INCORRECT_FILE_SYNTAX), "incorrect file syntax"},
+    {ERR_REASON(DSO_R_LOAD_FAILED), "could not load the shared library"},
+    {ERR_REASON(DSO_R_NAME_TRANSLATION_FAILED), "name translation failed"},
+    {ERR_REASON(DSO_R_NO_FILENAME), "no filename"},
+    {ERR_REASON(DSO_R_NULL_HANDLE), "a null shared library handle was used"},
+    {ERR_REASON(DSO_R_SET_FILENAME_FAILED), "set filename failed"},
+    {ERR_REASON(DSO_R_STACK_ERROR), "the meth_data stack is corrupt"},
+    {ERR_REASON(DSO_R_SYM_FAILURE),
+     "could not bind to the requested symbol name"},
+    {ERR_REASON(DSO_R_UNLOAD_FAILED), "could not unload the shared library"},
+    {ERR_REASON(DSO_R_UNSUPPORTED), "functionality not supported"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_DSO_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(DSO_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, DSO_str_functs);
+        ERR_load_strings(0, DSO_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_lib.c	(revision 331)
@@ -0,0 +1,349 @@
+/*
+ * Copyright 2000-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 "dso_locl.h"
+
+static DSO_METHOD *default_DSO_meth = NULL;
+
+static DSO *DSO_new_method(DSO_METHOD *meth)
+{
+    DSO *ret;
+
+    if (default_DSO_meth == NULL) {
+        /*
+         * We default to DSO_METH_openssl() which in turn defaults to
+         * stealing the "best available" method. Will fallback to
+         * DSO_METH_null() in the worst case.
+         */
+        default_DSO_meth = DSO_METHOD_openssl();
+    }
+    ret = OPENSSL_zalloc(sizeof(*ret));
+    if (ret == NULL) {
+        DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+        return (NULL);
+    }
+    ret->meth_data = sk_void_new_null();
+    if (ret->meth_data == NULL) {
+        /* sk_new doesn't generate any errors so we do */
+        DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ret);
+        return (NULL);
+    }
+    ret->meth = default_DSO_meth;
+    ret->references = 1;
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+        sk_void_free(ret->meth_data);
+        OPENSSL_free(ret);
+        return NULL;
+    }
+
+    if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
+        DSO_free(ret);
+        ret = NULL;
+    }
+
+    return ret;
+}
+
+DSO *DSO_new(void)
+{
+    return DSO_new_method(NULL);
+}
+
+int DSO_free(DSO *dso)
+{
+    int i;
+
+    if (dso == NULL)
+        return (1);
+
+    if (CRYPTO_atomic_add(&dso->references, -1, &i, dso->lock) <= 0)
+        return 0;
+
+    REF_PRINT_COUNT("DSO", dso);
+    if (i > 0)
+        return 1;
+    REF_ASSERT_ISNT(i < 0);
+
+    if ((dso->flags & DSO_FLAG_NO_UNLOAD_ON_FREE) == 0) {
+        if ((dso->meth->dso_unload != NULL) && !dso->meth->dso_unload(dso)) {
+            DSOerr(DSO_F_DSO_FREE, DSO_R_UNLOAD_FAILED);
+            return 0;
+        }
+    }
+
+    if ((dso->meth->finish != NULL) && !dso->meth->finish(dso)) {
+        DSOerr(DSO_F_DSO_FREE, DSO_R_FINISH_FAILED);
+        return 0;
+    }
+
+    sk_void_free(dso->meth_data);
+    OPENSSL_free(dso->filename);
+    OPENSSL_free(dso->loaded_filename);
+    CRYPTO_THREAD_lock_free(dso->lock);
+    OPENSSL_free(dso);
+    return 1;
+}
+
+int DSO_flags(DSO *dso)
+{
+    return ((dso == NULL) ? 0 : dso->flags);
+}
+
+int DSO_up_ref(DSO *dso)
+{
+    int i;
+
+    if (dso == NULL) {
+        DSOerr(DSO_F_DSO_UP_REF, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if (CRYPTO_atomic_add(&dso->references, 1, &i, dso->lock) <= 0)
+        return 0;
+
+    REF_PRINT_COUNT("DSO", r);
+    REF_ASSERT_ISNT(i < 2);
+    return ((i > 1) ? 1 : 0);
+}
+
+DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags)
+{
+    DSO *ret;
+    int allocated = 0;
+
+    if (dso == NULL) {
+        ret = DSO_new_method(meth);
+        if (ret == NULL) {
+            DSOerr(DSO_F_DSO_LOAD, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        allocated = 1;
+        /* Pass the provided flags to the new DSO object */
+        if (DSO_ctrl(ret, DSO_CTRL_SET_FLAGS, flags, NULL) < 0) {
+            DSOerr(DSO_F_DSO_LOAD, DSO_R_CTRL_FAILED);
+            goto err;
+        }
+    } else
+        ret = dso;
+    /* Don't load if we're currently already loaded */
+    if (ret->filename != NULL) {
+        DSOerr(DSO_F_DSO_LOAD, DSO_R_DSO_ALREADY_LOADED);
+        goto err;
+    }
+    /*
+     * filename can only be NULL if we were passed a dso that already has one
+     * set.
+     */
+    if (filename != NULL)
+        if (!DSO_set_filename(ret, filename)) {
+            DSOerr(DSO_F_DSO_LOAD, DSO_R_SET_FILENAME_FAILED);
+            goto err;
+        }
+    filename = ret->filename;
+    if (filename == NULL) {
+        DSOerr(DSO_F_DSO_LOAD, DSO_R_NO_FILENAME);
+        goto err;
+    }
+    if (ret->meth->dso_load == NULL) {
+        DSOerr(DSO_F_DSO_LOAD, DSO_R_UNSUPPORTED);
+        goto err;
+    }
+    if (!ret->meth->dso_load(ret)) {
+        DSOerr(DSO_F_DSO_LOAD, DSO_R_LOAD_FAILED);
+        goto err;
+    }
+    /* Load succeeded */
+    return (ret);
+ err:
+    if (allocated)
+        DSO_free(ret);
+    return (NULL);
+}
+
+DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname)
+{
+    DSO_FUNC_TYPE ret = NULL;
+
+    if ((dso == NULL) || (symname == NULL)) {
+        DSOerr(DSO_F_DSO_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER);
+        return (NULL);
+    }
+    if (dso->meth->dso_bind_func == NULL) {
+        DSOerr(DSO_F_DSO_BIND_FUNC, DSO_R_UNSUPPORTED);
+        return (NULL);
+    }
+    if ((ret = dso->meth->dso_bind_func(dso, symname)) == NULL) {
+        DSOerr(DSO_F_DSO_BIND_FUNC, DSO_R_SYM_FAILURE);
+        return (NULL);
+    }
+    /* Success */
+    return (ret);
+}
+
+/*
+ * I don't really like these *_ctrl functions very much to be perfectly
+ * honest. For one thing, I think I have to return a negative value for any
+ * error because possible DSO_ctrl() commands may return values such as
+ * "size"s that can legitimately be zero (making the standard
+ * "if (DSO_cmd(...))" form that works almost everywhere else fail at odd
+ * times. I'd prefer "output" values to be passed by reference and the return
+ * value as success/failure like usual ... but we conform when we must... :-)
+ */
+long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg)
+{
+    if (dso == NULL) {
+        DSOerr(DSO_F_DSO_CTRL, ERR_R_PASSED_NULL_PARAMETER);
+        return (-1);
+    }
+    /*
+     * We should intercept certain generic commands and only pass control to
+     * the method-specific ctrl() function if it's something we don't handle.
+     */
+    switch (cmd) {
+    case DSO_CTRL_GET_FLAGS:
+        return dso->flags;
+    case DSO_CTRL_SET_FLAGS:
+        dso->flags = (int)larg;
+        return (0);
+    case DSO_CTRL_OR_FLAGS:
+        dso->flags |= (int)larg;
+        return (0);
+    default:
+        break;
+    }
+    if ((dso->meth == NULL) || (dso->meth->dso_ctrl == NULL)) {
+        DSOerr(DSO_F_DSO_CTRL, DSO_R_UNSUPPORTED);
+        return (-1);
+    }
+    return (dso->meth->dso_ctrl(dso, cmd, larg, parg));
+}
+
+const char *DSO_get_filename(DSO *dso)
+{
+    if (dso == NULL) {
+        DSOerr(DSO_F_DSO_GET_FILENAME, ERR_R_PASSED_NULL_PARAMETER);
+        return (NULL);
+    }
+    return (dso->filename);
+}
+
+int DSO_set_filename(DSO *dso, const char *filename)
+{
+    char *copied;
+
+    if ((dso == NULL) || (filename == NULL)) {
+        DSOerr(DSO_F_DSO_SET_FILENAME, ERR_R_PASSED_NULL_PARAMETER);
+        return (0);
+    }
+    if (dso->loaded_filename) {
+        DSOerr(DSO_F_DSO_SET_FILENAME, DSO_R_DSO_ALREADY_LOADED);
+        return (0);
+    }
+    /* We'll duplicate filename */
+    copied = OPENSSL_strdup(filename);
+    if (copied == NULL) {
+        DSOerr(DSO_F_DSO_SET_FILENAME, ERR_R_MALLOC_FAILURE);
+        return (0);
+    }
+    OPENSSL_free(dso->filename);
+    dso->filename = copied;
+    return (1);
+}
+
+char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2)
+{
+    char *result = NULL;
+
+    if (dso == NULL || filespec1 == NULL) {
+        DSOerr(DSO_F_DSO_MERGE, ERR_R_PASSED_NULL_PARAMETER);
+        return (NULL);
+    }
+    if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) {
+        if (dso->merger != NULL)
+            result = dso->merger(dso, filespec1, filespec2);
+        else if (dso->meth->dso_merger != NULL)
+            result = dso->meth->dso_merger(dso, filespec1, filespec2);
+    }
+    return (result);
+}
+
+char *DSO_convert_filename(DSO *dso, const char *filename)
+{
+    char *result = NULL;
+
+    if (dso == NULL) {
+        DSOerr(DSO_F_DSO_CONVERT_FILENAME, ERR_R_PASSED_NULL_PARAMETER);
+        return (NULL);
+    }
+    if (filename == NULL)
+        filename = dso->filename;
+    if (filename == NULL) {
+        DSOerr(DSO_F_DSO_CONVERT_FILENAME, DSO_R_NO_FILENAME);
+        return (NULL);
+    }
+    if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) {
+        if (dso->name_converter != NULL)
+            result = dso->name_converter(dso, filename);
+        else if (dso->meth->dso_name_converter != NULL)
+            result = dso->meth->dso_name_converter(dso, filename);
+    }
+    if (result == NULL) {
+        result = OPENSSL_strdup(filename);
+        if (result == NULL) {
+            DSOerr(DSO_F_DSO_CONVERT_FILENAME, ERR_R_MALLOC_FAILURE);
+            return (NULL);
+        }
+    }
+    return (result);
+}
+
+int DSO_pathbyaddr(void *addr, char *path, int sz)
+{
+    DSO_METHOD *meth = default_DSO_meth;
+    if (meth == NULL)
+        meth = DSO_METHOD_openssl();
+    if (meth->pathbyaddr == NULL) {
+        DSOerr(DSO_F_DSO_PATHBYADDR, DSO_R_UNSUPPORTED);
+        return -1;
+    }
+    return (*meth->pathbyaddr) (addr, path, sz);
+}
+
+DSO *DSO_dsobyaddr(void *addr, int flags)
+{
+    DSO *ret = NULL;
+    char *filename = NULL;
+    int len = DSO_pathbyaddr(addr, NULL, 0);
+
+    if (len < 0)
+        return NULL;
+
+    filename = OPENSSL_malloc(len);
+    if (filename != NULL
+            && DSO_pathbyaddr(addr, filename, len) == len)
+        ret = DSO_load(NULL, filename, NULL, flags);
+
+    OPENSSL_free(filename);
+    return ret;
+}
+
+void *DSO_global_lookup(const char *name)
+{
+    DSO_METHOD *meth = default_DSO_meth;
+    if (meth == NULL)
+        meth = DSO_METHOD_openssl();
+    if (meth->globallookup == NULL) {
+        DSOerr(DSO_F_DSO_GLOBAL_LOOKUP, DSO_R_UNSUPPORTED);
+        return NULL;
+    }
+    return (*meth->globallookup) (name);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_locl.h	(revision 331)
@@ -0,0 +1,106 @@
+/*
+ * 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 <stdio.h>
+#include "internal/cryptlib.h"
+#include "internal/dso.h"
+#include "internal/dso_conf.h"
+
+/**********************************************************************/
+/* The low-level handle type used to refer to a loaded shared library */
+
+struct dso_st {
+    DSO_METHOD *meth;
+    /*
+     * Standard dlopen uses a (void *). Win32 uses a HANDLE. VMS doesn't use
+     * anything but will need to cache the filename for use in the dso_bind
+     * handler. All in all, let each method control its own destiny.
+     * "Handles" and such go in a STACK.
+     */
+    STACK_OF(void) *meth_data;
+    int references;
+    int flags;
+    /*
+     * For use by applications etc ... use this for your bits'n'pieces, don't
+     * touch meth_data!
+     */
+    CRYPTO_EX_DATA ex_data;
+    /*
+     * If this callback function pointer is set to non-NULL, then it will be
+     * used in DSO_load() in place of meth->dso_name_converter. NB: This
+     * should normally set using DSO_set_name_converter().
+     */
+    DSO_NAME_CONVERTER_FUNC name_converter;
+    /*
+     * If this callback function pointer is set to non-NULL, then it will be
+     * used in DSO_load() in place of meth->dso_merger. NB: This should
+     * normally set using DSO_set_merger().
+     */
+    DSO_MERGER_FUNC merger;
+    /*
+     * This is populated with (a copy of) the platform-independent filename
+     * used for this DSO.
+     */
+    char *filename;
+    /*
+     * This is populated with (a copy of) the translated filename by which
+     * the DSO was actually loaded. It is NULL iff the DSO is not currently
+     * loaded. NB: This is here because the filename translation process may
+     * involve a callback being invoked more than once not only to convert to
+     * a platform-specific form, but also to try different filenames in the
+     * process of trying to perform a load. As such, this variable can be
+     * used to indicate (a) whether this DSO structure corresponds to a
+     * loaded library or not, and (b) the filename with which it was actually
+     * loaded.
+     */
+    char *loaded_filename;
+    CRYPTO_RWLOCK *lock;
+};
+
+struct dso_meth_st {
+    const char *name;
+    /*
+     * Loads a shared library, NB: new DSO_METHODs must ensure that a
+     * successful load populates the loaded_filename field, and likewise a
+     * successful unload OPENSSL_frees and NULLs it out.
+     */
+    int (*dso_load) (DSO *dso);
+    /* Unloads a shared library */
+    int (*dso_unload) (DSO *dso);
+    /*
+     * Binds a function - assumes a return type of DSO_FUNC_TYPE. This should
+     * be cast to the real function prototype by the caller. Platforms that
+     * don't have compatible representations for different prototypes (this
+     * is possible within ANSI C) are highly unlikely to have shared
+     * libraries at all, let alone a DSO_METHOD implemented for them.
+     */
+    DSO_FUNC_TYPE (*dso_bind_func) (DSO *dso, const char *symname);
+    /*
+     * The generic (yuck) "ctrl()" function. NB: Negative return values
+     * (rather than zero) indicate errors.
+     */
+    long (*dso_ctrl) (DSO *dso, int cmd, long larg, void *parg);
+    /*
+     * The default DSO_METHOD-specific function for converting filenames to a
+     * canonical native form.
+     */
+    DSO_NAME_CONVERTER_FUNC dso_name_converter;
+    /*
+     * The default DSO_METHOD-specific function for converting filenames to a
+     * canonical native form.
+     */
+    DSO_MERGER_FUNC dso_merger;
+    /* [De]Initialisation handlers. */
+    int (*init) (DSO *dso);
+    int (*finish) (DSO *dso);
+    /* Return pathname of the module containing location */
+    int (*pathbyaddr) (void *addr, char *path, int sz);
+    /* Perform global symbol lookup, i.e. among *all* modules */
+    void *(*globallookup) (const char *symname);
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_openssl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_openssl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_openssl.c	(revision 331)
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2000-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 "dso_locl.h"
+
+#if !defined(DSO_VMS) && !defined(DSO_DLCFN) && !defined(DSO_DL) && !defined(DSO_WIN32) && !defined(DSO_DLFCN)
+
+static DSO_METHOD dso_meth_null = {
+    "NULL shared library method"
+};
+
+DSO_METHOD *DSO_METHOD_openssl(void)
+{
+    return &dso_meth_null;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_vms.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_vms.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_vms.c	(revision 331)
@@ -0,0 +1,468 @@
+/*
+ * Copyright 2000-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 "dso_locl.h"
+
+#ifdef OPENSSL_SYS_VMS
+
+# pragma message disable DOLLARID
+# include <errno.h>
+# include <rms.h>
+# include <lib$routines.h>
+# include <libfisdef.h>
+# include <stsdef.h>
+# include <descrip.h>
+# include <starlet.h>
+# include "../vms_rms.h"
+
+/* Some compiler options may mask the declaration of "_malloc32". */
+# if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE
+#  if __INITIAL_POINTER_SIZE == 64
+#   pragma pointer_size save
+#   pragma pointer_size 32
+void *_malloc32(__size_t);
+#   pragma pointer_size restore
+#  endif                        /* __INITIAL_POINTER_SIZE == 64 */
+# endif                         /* __INITIAL_POINTER_SIZE && defined
+                                 * _ANSI_C_SOURCE */
+
+# pragma message disable DOLLARID
+
+static int vms_load(DSO *dso);
+static int vms_unload(DSO *dso);
+static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname);
+static char *vms_name_converter(DSO *dso, const char *filename);
+static char *vms_merger(DSO *dso, const char *filespec1,
+                        const char *filespec2);
+
+static DSO_METHOD dso_meth_vms = {
+    "OpenSSL 'VMS' shared library method",
+    vms_load,
+    NULL,                       /* unload */
+    vms_bind_func,
+    NULL,                       /* ctrl */
+    vms_name_converter,
+    vms_merger,
+    NULL,                       /* init */
+    NULL,                       /* finish */
+    NULL,                       /* pathbyaddr */
+    NULL                        /* globallookup */
+};
+
+/*
+ * On VMS, the only "handle" is the file name.  LIB$FIND_IMAGE_SYMBOL depends
+ * on the reference to the file name being the same for all calls regarding
+ * one shared image, so we'll just store it in an instance of the following
+ * structure and put a pointer to that instance in the meth_data stack.
+ */
+typedef struct dso_internal_st {
+    /*
+     * This should contain the name only, no directory, no extension, nothing
+     * but a name.
+     */
+    struct dsc$descriptor_s filename_dsc;
+    char filename[NAMX_MAXRSS + 1];
+    /*
+     * This contains whatever is not in filename, if needed. Normally not
+     * defined.
+     */
+    struct dsc$descriptor_s imagename_dsc;
+    char imagename[NAMX_MAXRSS + 1];
+} DSO_VMS_INTERNAL;
+
+DSO_METHOD *DSO_METHOD_openssl(void)
+{
+    return &dso_meth_vms;
+}
+
+static int vms_load(DSO *dso)
+{
+    void *ptr = NULL;
+    /* See applicable comments in dso_dl.c */
+    char *filename = DSO_convert_filename(dso, NULL);
+
+/* Ensure 32-bit pointer for "p", and appropriate malloc() function. */
+# if __INITIAL_POINTER_SIZE == 64
+#  define DSO_MALLOC _malloc32
+#  pragma pointer_size save
+#  pragma pointer_size 32
+# else                          /* __INITIAL_POINTER_SIZE == 64 */
+#  define DSO_MALLOC OPENSSL_malloc
+# endif                         /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+    DSO_VMS_INTERNAL *p = NULL;
+
+# if __INITIAL_POINTER_SIZE == 64
+#  pragma pointer_size restore
+# endif                         /* __INITIAL_POINTER_SIZE == 64 */
+
+    const char *sp1, *sp2;      /* Search result */
+    const char *ext = NULL;     /* possible extension to add */
+
+    if (filename == NULL) {
+        DSOerr(DSO_F_VMS_LOAD, DSO_R_NO_FILENAME);
+        goto err;
+    }
+
+    /*-
+     * A file specification may look like this:
+     *
+     *      node::dev:[dir-spec]name.type;ver
+     *
+     * or (for compatibility with TOPS-20):
+     *
+     *      node::dev:<dir-spec>name.type;ver
+     *
+     * and the dir-spec uses '.' as separator.  Also, a dir-spec
+     * may consist of several parts, with mixed use of [] and <>:
+     *
+     *      [dir1.]<dir2>
+     *
+     * We need to split the file specification into the name and
+     * the rest (both before and after the name itself).
+     */
+    /*
+     * Start with trying to find the end of a dir-spec, and save the position
+     * of the byte after in sp1
+     */
+    sp1 = strrchr(filename, ']');
+    sp2 = strrchr(filename, '>');
+    if (sp1 == NULL)
+        sp1 = sp2;
+    if (sp2 != NULL && sp2 > sp1)
+        sp1 = sp2;
+    if (sp1 == NULL)
+        sp1 = strrchr(filename, ':');
+    if (sp1 == NULL)
+        sp1 = filename;
+    else
+        sp1++;                  /* The byte after the found character */
+    /* Now, let's see if there's a type, and save the position in sp2 */
+    sp2 = strchr(sp1, '.');
+    /*
+     * If there is a period and the next character is a semi-colon,
+     * we need to add an extension
+     */
+    if (sp2 != NULL && sp2[1] == ';')
+        ext = ".EXE";
+    /*
+     * If we found it, that's where we'll cut.  Otherwise, look for a version
+     * number and save the position in sp2
+     */
+    if (sp2 == NULL) {
+        sp2 = strchr(sp1, ';');
+        ext = ".EXE";
+    }
+    /*
+     * If there was still nothing to find, set sp2 to point at the end of the
+     * string
+     */
+    if (sp2 == NULL)
+        sp2 = sp1 + strlen(sp1);
+
+    /* Check that we won't get buffer overflows */
+    if (sp2 - sp1 > FILENAME_MAX
+        || (sp1 - filename) + strlen(sp2) > FILENAME_MAX) {
+        DSOerr(DSO_F_VMS_LOAD, DSO_R_FILENAME_TOO_BIG);
+        goto err;
+    }
+
+    p = DSO_MALLOC(sizeof(*p));
+    if (p == NULL) {
+        DSOerr(DSO_F_VMS_LOAD, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    strncpy(p->filename, sp1, sp2 - sp1);
+    p->filename[sp2 - sp1] = '\0';
+
+    strncpy(p->imagename, filename, sp1 - filename);
+    p->imagename[sp1 - filename] = '\0';
+    if (ext) {
+        strcat(p->imagename, ext);
+        if (*sp2 == '.')
+            sp2++;
+    }
+    strcat(p->imagename, sp2);
+
+    p->filename_dsc.dsc$w_length = strlen(p->filename);
+    p->filename_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+    p->filename_dsc.dsc$b_class = DSC$K_CLASS_S;
+    p->filename_dsc.dsc$a_pointer = p->filename;
+    p->imagename_dsc.dsc$w_length = strlen(p->imagename);
+    p->imagename_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+    p->imagename_dsc.dsc$b_class = DSC$K_CLASS_S;
+    p->imagename_dsc.dsc$a_pointer = p->imagename;
+
+    if (!sk_void_push(dso->meth_data, (char *)p)) {
+        DSOerr(DSO_F_VMS_LOAD, DSO_R_STACK_ERROR);
+        goto err;
+    }
+
+    /* Success (for now, we lie.  We actually do not know...) */
+    dso->loaded_filename = filename;
+    return (1);
+ err:
+    /* Cleanup! */
+    OPENSSL_free(p);
+    OPENSSL_free(filename);
+    return (0);
+}
+
+/*
+ * Note that this doesn't actually unload the shared image, as there is no
+ * such thing in VMS.  Next time it get loaded again, a new copy will
+ * actually be loaded.
+ */
+static int vms_unload(DSO *dso)
+{
+    DSO_VMS_INTERNAL *p;
+    if (dso == NULL) {
+        DSOerr(DSO_F_VMS_UNLOAD, ERR_R_PASSED_NULL_PARAMETER);
+        return (0);
+    }
+    if (sk_void_num(dso->meth_data) < 1)
+        return (1);
+    p = (DSO_VMS_INTERNAL *)sk_void_pop(dso->meth_data);
+    if (p == NULL) {
+        DSOerr(DSO_F_VMS_UNLOAD, DSO_R_NULL_HANDLE);
+        return (0);
+    }
+    /* Cleanup */
+    OPENSSL_free(p);
+    return (1);
+}
+
+/*
+ * We must do this in a separate function because of the way the exception
+ * handler works (it makes this function return
+ */
+static int do_find_symbol(DSO_VMS_INTERNAL *ptr,
+                          struct dsc$descriptor_s *symname_dsc, void **sym,
+                          unsigned long flags)
+{
+    /*
+     * Make sure that signals are caught and returned instead of aborting the
+     * program.  The exception handler gets unestablished automatically on
+     * return from this function.
+     */
+    lib$establish(lib$sig_to_ret);
+
+    if (ptr->imagename_dsc.dsc$w_length)
+        return lib$find_image_symbol(&ptr->filename_dsc,
+                                     symname_dsc, sym,
+                                     &ptr->imagename_dsc, flags);
+    else
+        return lib$find_image_symbol(&ptr->filename_dsc,
+                                     symname_dsc, sym, 0, flags);
+}
+
+void vms_bind_sym(DSO *dso, const char *symname, void **sym)
+{
+    DSO_VMS_INTERNAL *ptr;
+    int status;
+# ifdef LIB$M_FIS_MIXEDCASE
+    int flags = LIB$M_FIS_MIXEDCASE;
+# else
+    int flags = (1 << 4);
+# endif
+    struct dsc$descriptor_s symname_dsc;
+
+/* Arrange 32-bit pointer to (copied) string storage, if needed. */
+# if __INITIAL_POINTER_SIZE == 64
+#  define SYMNAME symname_32p
+#  pragma pointer_size save
+#  pragma pointer_size 32
+    char *symname_32p;
+#  pragma pointer_size restore
+    char symname_32[NAMX_MAXRSS + 1];
+# else                          /* __INITIAL_POINTER_SIZE == 64 */
+#  define SYMNAME ((char *) symname)
+# endif                         /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+    *sym = NULL;
+
+    if ((dso == NULL) || (symname == NULL)) {
+        DSOerr(DSO_F_VMS_BIND_SYM, ERR_R_PASSED_NULL_PARAMETER);
+        return;
+    }
+# if __INITIAL_POINTER_SIZE == 64
+    /* Copy the symbol name to storage with a 32-bit pointer. */
+    symname_32p = symname_32;
+    strcpy(symname_32p, symname);
+# endif                         /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+    symname_dsc.dsc$w_length = strlen(SYMNAME);
+    symname_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+    symname_dsc.dsc$b_class = DSC$K_CLASS_S;
+    symname_dsc.dsc$a_pointer = SYMNAME;
+
+    if (sk_void_num(dso->meth_data) < 1) {
+        DSOerr(DSO_F_VMS_BIND_SYM, DSO_R_STACK_ERROR);
+        return;
+    }
+    ptr = (DSO_VMS_INTERNAL *)sk_void_value(dso->meth_data,
+                                            sk_void_num(dso->meth_data) - 1);
+    if (ptr == NULL) {
+        DSOerr(DSO_F_VMS_BIND_SYM, DSO_R_NULL_HANDLE);
+        return;
+    }
+
+    if (dso->flags & DSO_FLAG_UPCASE_SYMBOL)
+        flags = 0;
+
+    status = do_find_symbol(ptr, &symname_dsc, sym, flags);
+
+    if (!$VMS_STATUS_SUCCESS(status)) {
+        unsigned short length;
+        char errstring[257];
+        struct dsc$descriptor_s errstring_dsc;
+
+        errstring_dsc.dsc$w_length = sizeof(errstring);
+        errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+        errstring_dsc.dsc$b_class = DSC$K_CLASS_S;
+        errstring_dsc.dsc$a_pointer = errstring;
+
+        *sym = NULL;
+
+        status = sys$getmsg(status, &length, &errstring_dsc, 1, 0);
+
+        if (!$VMS_STATUS_SUCCESS(status))
+            lib$signal(status); /* This is really bad.  Abort! */
+        else {
+            errstring[length] = '\0';
+
+            DSOerr(DSO_F_VMS_BIND_SYM, DSO_R_SYM_FAILURE);
+            if (ptr->imagename_dsc.dsc$w_length)
+                ERR_add_error_data(9,
+                                   "Symbol ", symname,
+                                   " in ", ptr->filename,
+                                   " (", ptr->imagename, ")",
+                                   ": ", errstring);
+            else
+                ERR_add_error_data(6,
+                                   "Symbol ", symname,
+                                   " in ", ptr->filename, ": ", errstring);
+        }
+        return;
+    }
+    return;
+}
+
+static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname)
+{
+    DSO_FUNC_TYPE sym = 0;
+    vms_bind_sym(dso, symname, (void **)&sym);
+    return sym;
+}
+
+static char *vms_merger(DSO *dso, const char *filespec1,
+                        const char *filespec2)
+{
+    int status;
+    int filespec1len, filespec2len;
+    struct FAB fab;
+    struct NAMX_STRUCT nam;
+    char esa[NAMX_MAXRSS + 1];
+    char *merged;
+
+/* Arrange 32-bit pointer to (copied) string storage, if needed. */
+# if __INITIAL_POINTER_SIZE == 64
+#  define FILESPEC1 filespec1_32p;
+#  define FILESPEC2 filespec2_32p;
+#  pragma pointer_size save
+#  pragma pointer_size 32
+    char *filespec1_32p;
+    char *filespec2_32p;
+#  pragma pointer_size restore
+    char filespec1_32[NAMX_MAXRSS + 1];
+    char filespec2_32[NAMX_MAXRSS + 1];
+# else                          /* __INITIAL_POINTER_SIZE == 64 */
+#  define FILESPEC1 ((char *) filespec1)
+#  define FILESPEC2 ((char *) filespec2)
+# endif                         /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+    if (!filespec1)
+        filespec1 = "";
+    if (!filespec2)
+        filespec2 = "";
+    filespec1len = strlen(filespec1);
+    filespec2len = strlen(filespec2);
+
+# if __INITIAL_POINTER_SIZE == 64
+    /* Copy the file names to storage with a 32-bit pointer. */
+    filespec1_32p = filespec1_32;
+    filespec2_32p = filespec2_32;
+    strcpy(filespec1_32p, filespec1);
+    strcpy(filespec2_32p, filespec2);
+# endif                         /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+    fab = cc$rms_fab;
+    nam = CC_RMS_NAMX;
+
+    FAB_OR_NAML(fab, nam).FAB_OR_NAML_FNA = FILESPEC1;
+    FAB_OR_NAML(fab, nam).FAB_OR_NAML_FNS = filespec1len;
+    FAB_OR_NAML(fab, nam).FAB_OR_NAML_DNA = FILESPEC2;
+    FAB_OR_NAML(fab, nam).FAB_OR_NAML_DNS = filespec2len;
+    NAMX_DNA_FNA_SET(fab)
+
+        nam.NAMX_ESA = esa;
+    nam.NAMX_ESS = NAMX_MAXRSS;
+    nam.NAMX_NOP = NAM$M_SYNCHK | NAM$M_PWD;
+    SET_NAMX_NO_SHORT_UPCASE(nam);
+
+    fab.FAB_NAMX = &nam;
+
+    status = sys$parse(&fab, 0, 0);
+
+    if (!$VMS_STATUS_SUCCESS(status)) {
+        unsigned short length;
+        char errstring[257];
+        struct dsc$descriptor_s errstring_dsc;
+
+        errstring_dsc.dsc$w_length = sizeof(errstring);
+        errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
+        errstring_dsc.dsc$b_class = DSC$K_CLASS_S;
+        errstring_dsc.dsc$a_pointer = errstring;
+
+        status = sys$getmsg(status, &length, &errstring_dsc, 1, 0);
+
+        if (!$VMS_STATUS_SUCCESS(status))
+            lib$signal(status); /* This is really bad.  Abort! */
+        else {
+            errstring[length] = '\0';
+
+            DSOerr(DSO_F_VMS_MERGER, DSO_R_FAILURE);
+            ERR_add_error_data(7,
+                               "filespec \"", filespec1, "\", ",
+                               "defaults \"", filespec2, "\": ", errstring);
+        }
+        return (NULL);
+    }
+
+    merged = OPENSSL_malloc(nam.NAMX_ESL + 1);
+    if (merged == NULL)
+        goto malloc_err;
+    strncpy(merged, nam.NAMX_ESA, nam.NAMX_ESL);
+    merged[nam.NAMX_ESL] = '\0';
+    return (merged);
+ malloc_err:
+    DSOerr(DSO_F_VMS_MERGER, ERR_R_MALLOC_FAILURE);
+}
+
+static char *vms_name_converter(DSO *dso, const char *filename)
+{
+    int len = strlen(filename);
+    char *not_translated = OPENSSL_malloc(len + 1);
+    if (not_translated != NULL)
+        strcpy(not_translated, filename);
+    return (not_translated);
+}
+
+#endif                          /* OPENSSL_SYS_VMS */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_win32.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_win32.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/dso/dso_win32.c	(revision 331)
@@ -0,0 +1,573 @@
+/*
+ * Copyright 2000-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 "dso_locl.h"
+
+#if defined(DSO_WIN32)
+
+# ifdef _WIN32_WCE
+#  if _WIN32_WCE < 300
+static FARPROC GetProcAddressA(HMODULE hModule, LPCSTR lpProcName)
+{
+    WCHAR lpProcNameW[64];
+    int i;
+
+    for (i = 0; lpProcName[i] && i < 64; i++)
+        lpProcNameW[i] = (WCHAR)lpProcName[i];
+    if (i == 64)
+        return NULL;
+    lpProcNameW[i] = 0;
+
+    return GetProcAddressW(hModule, lpProcNameW);
+}
+#  endif
+#  undef GetProcAddress
+#  define GetProcAddress GetProcAddressA
+
+static HINSTANCE LoadLibraryA(LPCSTR lpLibFileName)
+{
+    WCHAR *fnamw;
+    size_t len_0 = strlen(lpLibFileName) + 1, i;
+
+#  ifdef _MSC_VER
+    fnamw = (WCHAR *)_alloca(len_0 * sizeof(WCHAR));
+#  else
+    fnamw = (WCHAR *)alloca(len_0 * sizeof(WCHAR));
+#  endif
+    if (fnamw == NULL) {
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return NULL;
+    }
+#  if defined(_WIN32_WCE) && _WIN32_WCE>=101
+    if (!MultiByteToWideChar(CP_ACP, 0, lpLibFileName, len_0, fnamw, len_0))
+#  endif
+        for (i = 0; i < len_0; i++)
+            fnamw[i] = (WCHAR)lpLibFileName[i];
+
+    return LoadLibraryW(fnamw);
+}
+# endif
+
+/* Part of the hack in "win32_load" ... */
+# define DSO_MAX_TRANSLATED_SIZE 256
+
+static int win32_load(DSO *dso);
+static int win32_unload(DSO *dso);
+static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname);
+static char *win32_name_converter(DSO *dso, const char *filename);
+static char *win32_merger(DSO *dso, const char *filespec1,
+                          const char *filespec2);
+static void *win32_globallookup(const char *name);
+
+static const char *openssl_strnchr(const char *string, int c, size_t len);
+
+static DSO_METHOD dso_meth_win32 = {
+    "OpenSSL 'win32' shared library method",
+    win32_load,
+    win32_unload,
+    win32_bind_func,
+    NULL,                       /* ctrl */
+    win32_name_converter,
+    win32_merger,
+    NULL,                       /* init */
+    NULL,                       /* finish */
+    NULL,                       /* pathbyaddr */
+    win32_globallookup
+};
+
+DSO_METHOD *DSO_METHOD_openssl(void)
+{
+    return &dso_meth_win32;
+}
+
+/*
+ * For this DSO_METHOD, our meth_data STACK will contain; (i) a pointer to
+ * the handle (HINSTANCE) returned from LoadLibrary(), and copied.
+ */
+
+static int win32_load(DSO *dso)
+{
+    HINSTANCE h = NULL, *p = NULL;
+    /* See applicable comments from dso_dl.c */
+    char *filename = DSO_convert_filename(dso, NULL);
+
+    if (filename == NULL) {
+        DSOerr(DSO_F_WIN32_LOAD, DSO_R_NO_FILENAME);
+        goto err;
+    }
+    h = LoadLibraryA(filename);
+    if (h == NULL) {
+        DSOerr(DSO_F_WIN32_LOAD, DSO_R_LOAD_FAILED);
+        ERR_add_error_data(3, "filename(", filename, ")");
+        goto err;
+    }
+    p = OPENSSL_malloc(sizeof(*p));
+    if (p == NULL) {
+        DSOerr(DSO_F_WIN32_LOAD, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    *p = h;
+    if (!sk_void_push(dso->meth_data, p)) {
+        DSOerr(DSO_F_WIN32_LOAD, DSO_R_STACK_ERROR);
+        goto err;
+    }
+    /* Success */
+    dso->loaded_filename = filename;
+    return (1);
+ err:
+    /* Cleanup ! */
+    OPENSSL_free(filename);
+    OPENSSL_free(p);
+    if (h != NULL)
+        FreeLibrary(h);
+    return (0);
+}
+
+static int win32_unload(DSO *dso)
+{
+    HINSTANCE *p;
+    if (dso == NULL) {
+        DSOerr(DSO_F_WIN32_UNLOAD, ERR_R_PASSED_NULL_PARAMETER);
+        return (0);
+    }
+    if (sk_void_num(dso->meth_data) < 1)
+        return (1);
+    p = sk_void_pop(dso->meth_data);
+    if (p == NULL) {
+        DSOerr(DSO_F_WIN32_UNLOAD, DSO_R_NULL_HANDLE);
+        return (0);
+    }
+    if (!FreeLibrary(*p)) {
+        DSOerr(DSO_F_WIN32_UNLOAD, DSO_R_UNLOAD_FAILED);
+        /*
+         * We should push the value back onto the stack in case of a retry.
+         */
+        sk_void_push(dso->meth_data, p);
+        return (0);
+    }
+    /* Cleanup */
+    OPENSSL_free(p);
+    return (1);
+}
+
+static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname)
+{
+    HINSTANCE *ptr;
+    union {
+        void *p;
+        FARPROC f;
+    } sym;
+
+    if ((dso == NULL) || (symname == NULL)) {
+        DSOerr(DSO_F_WIN32_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER);
+        return (NULL);
+    }
+    if (sk_void_num(dso->meth_data) < 1) {
+        DSOerr(DSO_F_WIN32_BIND_FUNC, DSO_R_STACK_ERROR);
+        return (NULL);
+    }
+    ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
+    if (ptr == NULL) {
+        DSOerr(DSO_F_WIN32_BIND_FUNC, DSO_R_NULL_HANDLE);
+        return (NULL);
+    }
+    sym.f = GetProcAddress(*ptr, symname);
+    if (sym.p == NULL) {
+        DSOerr(DSO_F_WIN32_BIND_FUNC, DSO_R_SYM_FAILURE);
+        ERR_add_error_data(3, "symname(", symname, ")");
+        return (NULL);
+    }
+    return ((DSO_FUNC_TYPE)sym.f);
+}
+
+struct file_st {
+    const char *node;
+    int nodelen;
+    const char *device;
+    int devicelen;
+    const char *predir;
+    int predirlen;
+    const char *dir;
+    int dirlen;
+    const char *file;
+    int filelen;
+};
+
+static struct file_st *win32_splitter(DSO *dso, const char *filename,
+                                      int assume_last_is_dir)
+{
+    struct file_st *result = NULL;
+    enum { IN_NODE, IN_DEVICE, IN_FILE } position;
+    const char *start = filename;
+    char last;
+
+    if (!filename) {
+        DSOerr(DSO_F_WIN32_SPLITTER, DSO_R_NO_FILENAME);
+        /*
+         * goto err;
+         */
+        return (NULL);
+    }
+
+    result = OPENSSL_zalloc(sizeof(*result));
+    if (result == NULL) {
+        DSOerr(DSO_F_WIN32_SPLITTER, ERR_R_MALLOC_FAILURE);
+        return (NULL);
+    }
+
+    position = IN_DEVICE;
+
+    if ((filename[0] == '\\' && filename[1] == '\\')
+        || (filename[0] == '/' && filename[1] == '/')) {
+        position = IN_NODE;
+        filename += 2;
+        start = filename;
+        result->node = start;
+    }
+
+    do {
+        last = filename[0];
+        switch (last) {
+        case ':':
+            if (position != IN_DEVICE) {
+                DSOerr(DSO_F_WIN32_SPLITTER, DSO_R_INCORRECT_FILE_SYNTAX);
+                /*
+                 * goto err;
+                 */
+                OPENSSL_free(result);
+                return (NULL);
+            }
+            result->device = start;
+            result->devicelen = (int)(filename - start);
+            position = IN_FILE;
+            start = ++filename;
+            result->dir = start;
+            break;
+        case '\\':
+        case '/':
+            if (position == IN_NODE) {
+                result->nodelen = (int)(filename - start);
+                position = IN_FILE;
+                start = ++filename;
+                result->dir = start;
+            } else if (position == IN_DEVICE) {
+                position = IN_FILE;
+                filename++;
+                result->dir = start;
+                result->dirlen = (int)(filename - start);
+                start = filename;
+            } else {
+                filename++;
+                result->dirlen += (int)(filename - start);
+                start = filename;
+            }
+            break;
+        case '\0':
+            if (position == IN_NODE) {
+                result->nodelen = (int)(filename - start);
+            } else {
+                if (filename - start > 0) {
+                    if (assume_last_is_dir) {
+                        if (position == IN_DEVICE) {
+                            result->dir = start;
+                            result->dirlen = 0;
+                        }
+                        result->dirlen += (int)(filename - start);
+                    } else {
+                        result->file = start;
+                        result->filelen = (int)(filename - start);
+                    }
+                }
+            }
+            break;
+        default:
+            filename++;
+            break;
+        }
+    }
+    while (last);
+
+    if (!result->nodelen)
+        result->node = NULL;
+    if (!result->devicelen)
+        result->device = NULL;
+    if (!result->dirlen)
+        result->dir = NULL;
+    if (!result->filelen)
+        result->file = NULL;
+
+    return (result);
+}
+
+static char *win32_joiner(DSO *dso, const struct file_st *file_split)
+{
+    int len = 0, offset = 0;
+    char *result = NULL;
+    const char *start;
+
+    if (!file_split) {
+        DSOerr(DSO_F_WIN32_JOINER, ERR_R_PASSED_NULL_PARAMETER);
+        return (NULL);
+    }
+    if (file_split->node) {
+        len += 2 + file_split->nodelen; /* 2 for starting \\ */
+        if (file_split->predir || file_split->dir || file_split->file)
+            len++;              /* 1 for ending \ */
+    } else if (file_split->device) {
+        len += file_split->devicelen + 1; /* 1 for ending : */
+    }
+    len += file_split->predirlen;
+    if (file_split->predir && (file_split->dir || file_split->file)) {
+        len++;                  /* 1 for ending \ */
+    }
+    len += file_split->dirlen;
+    if (file_split->dir && file_split->file) {
+        len++;                  /* 1 for ending \ */
+    }
+    len += file_split->filelen;
+
+    if (!len) {
+        DSOerr(DSO_F_WIN32_JOINER, DSO_R_EMPTY_FILE_STRUCTURE);
+        return (NULL);
+    }
+
+    result = OPENSSL_malloc(len + 1);
+    if (result == NULL) {
+        DSOerr(DSO_F_WIN32_JOINER, ERR_R_MALLOC_FAILURE);
+        return (NULL);
+    }
+
+    if (file_split->node) {
+        strcpy(&result[offset], "\\\\");
+        offset += 2;
+        strncpy(&result[offset], file_split->node, file_split->nodelen);
+        offset += file_split->nodelen;
+        if (file_split->predir || file_split->dir || file_split->file) {
+            result[offset] = '\\';
+            offset++;
+        }
+    } else if (file_split->device) {
+        strncpy(&result[offset], file_split->device, file_split->devicelen);
+        offset += file_split->devicelen;
+        result[offset] = ':';
+        offset++;
+    }
+    start = file_split->predir;
+    while (file_split->predirlen > (start - file_split->predir)) {
+        const char *end = openssl_strnchr(start, '/',
+                                          file_split->predirlen - (start -
+                                                                   file_split->predir));
+        if (!end)
+            end = start
+                + file_split->predirlen - (start - file_split->predir);
+        strncpy(&result[offset], start, end - start);
+        offset += (int)(end - start);
+        result[offset] = '\\';
+        offset++;
+        start = end + 1;
+    }
+    start = file_split->dir;
+    while (file_split->dirlen > (start - file_split->dir)) {
+        const char *end = openssl_strnchr(start, '/',
+                                          file_split->dirlen - (start -
+                                                                file_split->dir));
+        if (!end)
+            end = start + file_split->dirlen - (start - file_split->dir);
+        strncpy(&result[offset], start, end - start);
+        offset += (int)(end - start);
+        result[offset] = '\\';
+        offset++;
+        start = end + 1;
+    }
+    strncpy(&result[offset], file_split->file, file_split->filelen);
+    offset += file_split->filelen;
+    result[offset] = '\0';
+    return (result);
+}
+
+static char *win32_merger(DSO *dso, const char *filespec1,
+                          const char *filespec2)
+{
+    char *merged = NULL;
+    struct file_st *filespec1_split = NULL;
+    struct file_st *filespec2_split = NULL;
+
+    if (!filespec1 && !filespec2) {
+        DSOerr(DSO_F_WIN32_MERGER, ERR_R_PASSED_NULL_PARAMETER);
+        return (NULL);
+    }
+    if (!filespec2) {
+        merged = OPENSSL_malloc(strlen(filespec1) + 1);
+        if (merged == NULL) {
+            DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE);
+            return (NULL);
+        }
+        strcpy(merged, filespec1);
+    } else if (!filespec1) {
+        merged = OPENSSL_malloc(strlen(filespec2) + 1);
+        if (merged == NULL) {
+            DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE);
+            return (NULL);
+        }
+        strcpy(merged, filespec2);
+    } else {
+        filespec1_split = win32_splitter(dso, filespec1, 0);
+        if (!filespec1_split) {
+            DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE);
+            return (NULL);
+        }
+        filespec2_split = win32_splitter(dso, filespec2, 1);
+        if (!filespec2_split) {
+            DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE);
+            OPENSSL_free(filespec1_split);
+            return (NULL);
+        }
+
+        /* Fill in into filespec1_split */
+        if (!filespec1_split->node && !filespec1_split->device) {
+            filespec1_split->node = filespec2_split->node;
+            filespec1_split->nodelen = filespec2_split->nodelen;
+            filespec1_split->device = filespec2_split->device;
+            filespec1_split->devicelen = filespec2_split->devicelen;
+        }
+        if (!filespec1_split->dir) {
+            filespec1_split->dir = filespec2_split->dir;
+            filespec1_split->dirlen = filespec2_split->dirlen;
+        } else if (filespec1_split->dir[0] != '\\'
+                   && filespec1_split->dir[0] != '/') {
+            filespec1_split->predir = filespec2_split->dir;
+            filespec1_split->predirlen = filespec2_split->dirlen;
+        }
+        if (!filespec1_split->file) {
+            filespec1_split->file = filespec2_split->file;
+            filespec1_split->filelen = filespec2_split->filelen;
+        }
+
+        merged = win32_joiner(dso, filespec1_split);
+    }
+    OPENSSL_free(filespec1_split);
+    OPENSSL_free(filespec2_split);
+    return (merged);
+}
+
+static char *win32_name_converter(DSO *dso, const char *filename)
+{
+    char *translated;
+    int len, transform;
+
+    len = strlen(filename);
+    transform = ((strstr(filename, "/") == NULL) &&
+                 (strstr(filename, "\\") == NULL) &&
+                 (strstr(filename, ":") == NULL));
+    if (transform)
+        /* We will convert this to "%s.dll" */
+        translated = OPENSSL_malloc(len + 5);
+    else
+        /* We will simply duplicate filename */
+        translated = OPENSSL_malloc(len + 1);
+    if (translated == NULL) {
+        DSOerr(DSO_F_WIN32_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED);
+        return (NULL);
+    }
+    if (transform)
+        sprintf(translated, "%s.dll", filename);
+    else
+        sprintf(translated, "%s", filename);
+    return (translated);
+}
+
+static const char *openssl_strnchr(const char *string, int c, size_t len)
+{
+    size_t i;
+    const char *p;
+    for (i = 0, p = string; i < len && *p; i++, p++) {
+        if (*p == c)
+            return p;
+    }
+    return NULL;
+}
+
+# include <tlhelp32.h>
+# ifdef _WIN32_WCE
+#  define DLLNAME "TOOLHELP.DLL"
+# else
+#  ifdef MODULEENTRY32
+#   undef MODULEENTRY32         /* unmask the ASCII version! */
+#  endif
+#  define DLLNAME "KERNEL32.DLL"
+# endif
+
+typedef HANDLE(WINAPI *CREATETOOLHELP32SNAPSHOT) (DWORD, DWORD);
+typedef BOOL(WINAPI *CLOSETOOLHELP32SNAPSHOT) (HANDLE);
+typedef BOOL(WINAPI *MODULE32) (HANDLE, MODULEENTRY32 *);
+
+static void *win32_globallookup(const char *name)
+{
+    HMODULE dll;
+    HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
+    MODULEENTRY32 me32;
+    CREATETOOLHELP32SNAPSHOT create_snap;
+    CLOSETOOLHELP32SNAPSHOT close_snap;
+    MODULE32 module_first, module_next;
+    union {
+        void *p;
+        FARPROC f;
+    } ret = { NULL };
+
+    dll = LoadLibrary(TEXT(DLLNAME));
+    if (dll == NULL) {
+        DSOerr(DSO_F_WIN32_GLOBALLOOKUP, DSO_R_UNSUPPORTED);
+        return NULL;
+    }
+
+    create_snap = (CREATETOOLHELP32SNAPSHOT)
+        GetProcAddress(dll, "CreateToolhelp32Snapshot");
+    if (create_snap == NULL) {
+        FreeLibrary(dll);
+        DSOerr(DSO_F_WIN32_GLOBALLOOKUP, DSO_R_UNSUPPORTED);
+        return NULL;
+    }
+    /* We take the rest for granted... */
+# ifdef _WIN32_WCE
+    close_snap = (CLOSETOOLHELP32SNAPSHOT)
+        GetProcAddress(dll, "CloseToolhelp32Snapshot");
+# else
+    close_snap = (CLOSETOOLHELP32SNAPSHOT) CloseHandle;
+# endif
+    module_first = (MODULE32) GetProcAddress(dll, "Module32First");
+    module_next = (MODULE32) GetProcAddress(dll, "Module32Next");
+
+    hModuleSnap = (*create_snap) (TH32CS_SNAPMODULE, 0);
+    if (hModuleSnap == INVALID_HANDLE_VALUE) {
+        FreeLibrary(dll);
+        DSOerr(DSO_F_WIN32_GLOBALLOOKUP, DSO_R_UNSUPPORTED);
+        return NULL;
+    }
+
+    me32.dwSize = sizeof(me32);
+
+    if (!(*module_first) (hModuleSnap, &me32)) {
+        (*close_snap) (hModuleSnap);
+        FreeLibrary(dll);
+        return NULL;
+    }
+
+    do {
+        if ((ret.f = GetProcAddress(me32.hModule, name))) {
+            (*close_snap) (hModuleSnap);
+            FreeLibrary(dll);
+            return ret.p;
+        }
+    } while ((*module_next) (hModuleSnap, &me32));
+
+    (*close_snap) (hModuleSnap);
+    FreeLibrary(dll);
+    return NULL;
+}
+#endif                          /* DSO_WIN32 */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ebcdic.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ebcdic.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ebcdic.c	(revision 331)
@@ -0,0 +1,366 @@
+/*
+ * Copyright 2000-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 <openssl/e_os2.h>
+#ifndef CHARSET_EBCDIC
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <openssl/ebcdic.h>
+
+/*-
+ *      Initial Port for  Apache-1.3     by <Martin.Kraemer@Mch.SNI.De>
+ *      Adapted for       OpenSSL-0.9.4  by <Martin.Kraemer@Mch.SNI.De>
+ */
+
+# ifdef CHARSET_EBCDIC_TEST
+/*
+ * Here we're looking to test the EBCDIC code on an ASCII system so we don't do
+ * any translation in these tables at all.
+ */
+
+/* The ebcdic-to-ascii table: */
+const unsigned char os_toascii[256] = {
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+    0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+    0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+    0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+    0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+    0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+    0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+    0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
+
+/* The ascii-to-ebcdic table: */
+const unsigned char os_toebcdic[256] = {
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+    0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+    0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+    0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+    0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+    0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+    0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+    0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
+
+# elif defined(_OSD_POSIX)
+/*
+ * "BS2000 OSD" is a POSIX subsystem on a main frame. It is made by Siemens
+ * AG, Germany, for their BS2000 mainframe machines. Within the POSIX
+ * subsystem, the same character set was chosen as in "native BS2000", namely
+ * EBCDIC. (EDF04)
+ *
+ * The name "ASCII" in these routines is misleading: actually, conversion is
+ * not between EBCDIC and ASCII, but EBCDIC(EDF04) and ISO-8859.1; that means
+ * that (western european) national characters are preserved.
+ *
+ * This table is identical to the one used by rsh/rcp/ftp and other POSIX
+ * tools.
+ */
+
+/* Here's the bijective ebcdic-to-ascii table: */
+const unsigned char os_toascii[256] = {
+    /*
+     * 00
+     */ 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f,
+    0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */
+    /*
+     * 10
+     */ 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97,
+    0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */
+    /*
+     * 20
+     */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b,
+    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /* ................ */
+    /*
+     * 30
+     */ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04,
+    0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /* ................ */
+    /*
+     * 40
+     */ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5,
+    0xe7, 0xf1, 0x60, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* .........`.<(+| */
+    /*
+     * 50
+     */ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef,
+    0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x9f, /* &.........!$*);. */
+    /*
+     * 60
+     */ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5,
+    0xc7, 0xd1, 0x5e, 0x2c, 0x25, 0x5f, 0x3e, 0x3f,    /*-/........^,%_>?*/
+    /*
+     * 70
+     */ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf,
+    0xcc, 0xa8, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /* ..........:#@'=" */
+    /*
+     * 80
+     */ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+    0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /* .abcdefghi...... */
+    /*
+     * 90
+     */ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
+    0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /* .jklmnopqr...... */
+    /*
+     * a0
+     */ 0xb5, 0xaf, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+    0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0xdd, 0xde, 0xae, /* ..stuvwxyz...... */
+    /*
+     * b0
+     */ 0xa2, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc,
+    0xbd, 0xbe, 0xac, 0x5b, 0x5c, 0x5d, 0xb4, 0xd7, /* ...........[\].. */
+    /*
+     * c0
+     */ 0xf9, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+    0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /* .ABCDEFGHI...... */
+    /*
+     * d0
+     */ 0xa6, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
+    0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xdb, 0xfa, 0xff, /* .JKLMNOPQR...... */
+    /*
+     * e0
+     */ 0xd9, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+    0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /* ..STUVWXYZ...... */
+    /*
+     * f0
+     */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+    0x38, 0x39, 0xb3, 0x7b, 0xdc, 0x7d, 0xda, 0x7e /* 0123456789.{.}.~ */
+};
+
+/* The ascii-to-ebcdic table: */
+const unsigned char os_toebcdic[256] = {
+    /*
+     * 00
+     */ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f,
+    0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */
+    /*
+     * 10
+     */ 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26,
+    0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */
+    /*
+     * 20
+     */ 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d,
+    0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61, /* !"#$%&'()*+,-./ */
+    /*
+     * 30
+     */ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+    0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f, /* 0123456789:;<=>? */
+    /*
+     * 40
+     */ 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+    0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, /* @ABCDEFGHIJKLMNO */
+    /*
+     * 50
+     */ 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
+    0xe7, 0xe8, 0xe9, 0xbb, 0xbc, 0xbd, 0x6a, 0x6d, /* PQRSTUVWXYZ[\]^_ */
+    /*
+     * 60
+     */ 0x4a, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+    0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* `abcdefghijklmno */
+    /*
+     * 70
+     */ 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
+    0xa7, 0xa8, 0xa9, 0xfb, 0x4f, 0xfd, 0xff, 0x07, /* pqrstuvwxyz{|}~. */
+    /*
+     * 80
+     */ 0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08,
+    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14, /* ................ */
+    /*
+     * 90
+     */ 0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17,
+    0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0x5f, /* ................ */
+    /*
+     * a0
+     */ 0x41, 0xaa, 0xb0, 0xb1, 0x9f, 0xb2, 0xd0, 0xb5,
+    0x79, 0xb4, 0x9a, 0x8a, 0xba, 0xca, 0xaf, 0xa1, /* ................ */
+    /*
+     * b0
+     */ 0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3,
+    0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab, /* ................ */
+    /*
+     * c0
+     */ 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68,
+    0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* ................ */
+    /*
+     * d0
+     */ 0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf,
+    0x80, 0xe0, 0xfe, 0xdd, 0xfc, 0xad, 0xae, 0x59, /* ................ */
+    /*
+     * e0
+     */ 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48,
+    0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* ................ */
+    /*
+     * f0
+     */ 0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1,
+    0x70, 0xc0, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf /* ................ */
+};
+
+# else /*_OSD_POSIX*/
+
+/*
+ * This code does basic character mapping for IBM's TPF and OS/390 operating
+ * systems. It is a modified version of the BS2000 table.
+ *
+ * Bijective EBCDIC (character set IBM-1047) to US-ASCII table: This table is
+ * bijective - there are no ambiguous or duplicate characters.
+ */
+const unsigned char os_toascii[256] = {
+    0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f, /* 00-0f: */
+    0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */
+    0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97, /* 10-1f: */
+    0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */
+    0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b, /* 20-2f: */
+    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /* ................ */
+    0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, /* 30-3f: */
+    0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /* ................ */
+    0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5, /* 40-4f: */
+    0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* ...........<(+| */
+    0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, /* 50-5f: */
+    0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e, /* &.........!$*);^ */
+    0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5, /* 60-6f: */
+    0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /* -/.........,%_>? */
+    0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, /* 70-7f: */
+    0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /* .........`:#@'=" */
+    0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 80-8f: */
+    0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /* .abcdefghi...... */
+    0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* 90-9f: */
+    0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /* .jklmnopqr...... */
+    0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* a0-af: */
+    0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0x5b, 0xde, 0xae, /* .~stuvwxyz...[.. */
+    0xac, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, /* b0-bf: */
+    0xbd, 0xbe, 0xdd, 0xa8, 0xaf, 0x5d, 0xb4, 0xd7, /* .............].. */
+    0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* c0-cf: */
+    0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /* {ABCDEFGHI...... */
+    0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, /* d0-df: */
+    0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0xff, /* }JKLMNOPQR...... */
+    0x5c, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* e0-ef: */
+    0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /* \.STUVWXYZ...... */
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* f0-ff: */
+    0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0x9f /* 0123456789...... */
+};
+
+/*
+ * The US-ASCII to EBCDIC (character set IBM-1047) table: This table is
+ * bijective (no ambiguous or duplicate characters)
+ */
+const unsigned char os_toebcdic[256] = {
+    0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f, /* 00-0f: */
+    0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */
+    0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26, /* 10-1f: */
+    0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */
+    0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d, /* 20-2f: */
+    0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61, /* !"#$%&'()*+,-./ */
+    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 30-3f: */
+    0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f, /* 0123456789:;<=>? */
+    0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 40-4f: */
+    0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, /* @ABCDEFGHIJKLMNO */
+    0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, /* 50-5f: */
+    0xe7, 0xe8, 0xe9, 0xad, 0xe0, 0xbd, 0x5f, 0x6d, /* PQRSTUVWXYZ[\]^_ */
+    0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 60-6f: */
+    0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* `abcdefghijklmno */
+    0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, /* 70-7f: */
+    0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0xa1, 0x07, /* pqrstuvwxyz{|}~. */
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08, /* 80-8f: */
+    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14, /* ................ */
+    0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17, /* 90-9f: */
+    0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0xff, /* ................ */
+    0x41, 0xaa, 0x4a, 0xb1, 0x9f, 0xb2, 0x6a, 0xb5, /* a0-af: */
+    0xbb, 0xb4, 0x9a, 0x8a, 0xb0, 0xca, 0xaf, 0xbc, /* ................ */
+    0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3, /* b0-bf: */
+    0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab, /* ................ */
+    0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68, /* c0-cf: */
+    0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* ................ */
+    0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf, /* d0-df: */
+    0x80, 0xfd, 0xfe, 0xfb, 0xfc, 0xba, 0xae, 0x59, /* ................ */
+    0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48, /* e0-ef: */
+    0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* ................ */
+    0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1, /* f0-ff: */
+    0x70, 0xdd, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf /* ................ */
+};
+# endif/*_OSD_POSIX*/
+
+/*
+ * Translate a memory block from EBCDIC (host charset) to ASCII (net charset)
+ * dest and srce may be identical, or separate memory blocks, but should not
+ * overlap. These functions intentionally have an interface compatible to
+ * memcpy(3).
+ */
+
+void *ebcdic2ascii(void *dest, const void *srce, size_t count)
+{
+    unsigned char *udest = dest;
+    const unsigned char *usrce = srce;
+
+    while (count-- != 0) {
+        *udest++ = os_toascii[*usrce++];
+    }
+
+    return dest;
+}
+
+void *ascii2ebcdic(void *dest, const void *srce, size_t count)
+{
+    unsigned char *udest = dest;
+    const unsigned char *usrce = srce;
+
+    while (count-- != 0) {
+        *udest++ = os_toebcdic[*usrce++];
+    }
+
+    return dest;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/curve25519.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/curve25519.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/curve25519.c	(revision 331)
@@ -0,0 +1,3394 @@
+/*
+ * 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
+ */
+
+/* This code is mostly taken from the ref10 version of Ed25519 in SUPERCOP
+ * 20141124 (http://bench.cr.yp.to/supercop.html).
+ *
+ * The field functions are shared by Ed25519 and X25519 where possible. */
+
+#include <string.h>
+#include "ec_lcl.h"
+
+
+/* fe means field element. Here the field is \Z/(2^255-19). An element t,
+ * entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77
+ * t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on
+ * context.  */
+typedef int32_t fe[10];
+
+static const int64_t kBottom25Bits = 0x1ffffffLL;
+static const int64_t kBottom26Bits = 0x3ffffffLL;
+static const int64_t kTop39Bits = 0xfffffffffe000000LL;
+static const int64_t kTop38Bits = 0xfffffffffc000000LL;
+
+static uint64_t load_3(const uint8_t *in) {
+  uint64_t result;
+  result = (uint64_t)in[0];
+  result |= ((uint64_t)in[1]) << 8;
+  result |= ((uint64_t)in[2]) << 16;
+  return result;
+}
+
+static uint64_t load_4(const uint8_t *in) {
+  uint64_t result;
+  result = (uint64_t)in[0];
+  result |= ((uint64_t)in[1]) << 8;
+  result |= ((uint64_t)in[2]) << 16;
+  result |= ((uint64_t)in[3]) << 24;
+  return result;
+}
+
+static void fe_frombytes(fe h, const uint8_t *s) {
+  /* Ignores top bit of h. */
+  int64_t h0 = load_4(s);
+  int64_t h1 = load_3(s + 4) << 6;
+  int64_t h2 = load_3(s + 7) << 5;
+  int64_t h3 = load_3(s + 10) << 3;
+  int64_t h4 = load_3(s + 13) << 2;
+  int64_t h5 = load_4(s + 16);
+  int64_t h6 = load_3(s + 20) << 7;
+  int64_t h7 = load_3(s + 23) << 5;
+  int64_t h8 = load_3(s + 26) << 4;
+  int64_t h9 = (load_3(s + 29) & 8388607) << 2;
+  int64_t carry0;
+  int64_t carry1;
+  int64_t carry2;
+  int64_t carry3;
+  int64_t carry4;
+  int64_t carry5;
+  int64_t carry6;
+  int64_t carry7;
+  int64_t carry8;
+  int64_t carry9;
+
+  carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
+  carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
+  carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
+  carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
+  carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
+
+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
+  carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
+  carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
+  carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
+
+  h[0] = h0;
+  h[1] = h1;
+  h[2] = h2;
+  h[3] = h3;
+  h[4] = h4;
+  h[5] = h5;
+  h[6] = h6;
+  h[7] = h7;
+  h[8] = h8;
+  h[9] = h9;
+}
+
+/* Preconditions:
+ *  |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+ *
+ * Write p=2^255-19; q=floor(h/p).
+ * Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
+ *
+ * Proof:
+ *   Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
+ *   Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4.
+ *
+ *   Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
+ *   Then 0<y<1.
+ *
+ *   Write r=h-pq.
+ *   Have 0<=r<=p-1=2^255-20.
+ *   Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.
+ *
+ *   Write x=r+19(2^-255)r+y.
+ *   Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
+ *
+ *   Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
+ *   so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q. */
+static void fe_tobytes(uint8_t *s, const fe h) {
+  int32_t h0 = h[0];
+  int32_t h1 = h[1];
+  int32_t h2 = h[2];
+  int32_t h3 = h[3];
+  int32_t h4 = h[4];
+  int32_t h5 = h[5];
+  int32_t h6 = h[6];
+  int32_t h7 = h[7];
+  int32_t h8 = h[8];
+  int32_t h9 = h[9];
+  int32_t q;
+
+  q = (19 * h9 + (((int32_t) 1) << 24)) >> 25;
+  q = (h0 + q) >> 26;
+  q = (h1 + q) >> 25;
+  q = (h2 + q) >> 26;
+  q = (h3 + q) >> 25;
+  q = (h4 + q) >> 26;
+  q = (h5 + q) >> 25;
+  q = (h6 + q) >> 26;
+  q = (h7 + q) >> 25;
+  q = (h8 + q) >> 26;
+  q = (h9 + q) >> 25;
+
+  /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
+  h0 += 19 * q;
+  /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
+
+  h1 += h0 >> 26; h0 &= kBottom26Bits;
+  h2 += h1 >> 25; h1 &= kBottom25Bits;
+  h3 += h2 >> 26; h2 &= kBottom26Bits;
+  h4 += h3 >> 25; h3 &= kBottom25Bits;
+  h5 += h4 >> 26; h4 &= kBottom26Bits;
+  h6 += h5 >> 25; h5 &= kBottom25Bits;
+  h7 += h6 >> 26; h6 &= kBottom26Bits;
+  h8 += h7 >> 25; h7 &= kBottom25Bits;
+  h9 += h8 >> 26; h8 &= kBottom26Bits;
+                  h9 &= kBottom25Bits;
+                  /* h10 = carry9 */
+
+  /* Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
+   * Have h0+...+2^230 h9 between 0 and 2^255-1;
+   * evidently 2^255 h10-2^255 q = 0.
+   * Goal: Output h0+...+2^230 h9.  */
+
+  s[0] = h0 >> 0;
+  s[1] = h0 >> 8;
+  s[2] = h0 >> 16;
+  s[3] = (h0 >> 24) | ((uint32_t)(h1) << 2);
+  s[4] = h1 >> 6;
+  s[5] = h1 >> 14;
+  s[6] = (h1 >> 22) | ((uint32_t)(h2) << 3);
+  s[7] = h2 >> 5;
+  s[8] = h2 >> 13;
+  s[9] = (h2 >> 21) | ((uint32_t)(h3) << 5);
+  s[10] = h3 >> 3;
+  s[11] = h3 >> 11;
+  s[12] = (h3 >> 19) | ((uint32_t)(h4) << 6);
+  s[13] = h4 >> 2;
+  s[14] = h4 >> 10;
+  s[15] = h4 >> 18;
+  s[16] = h5 >> 0;
+  s[17] = h5 >> 8;
+  s[18] = h5 >> 16;
+  s[19] = (h5 >> 24) | ((uint32_t)(h6) << 1);
+  s[20] = h6 >> 7;
+  s[21] = h6 >> 15;
+  s[22] = (h6 >> 23) | ((uint32_t)(h7) << 3);
+  s[23] = h7 >> 5;
+  s[24] = h7 >> 13;
+  s[25] = (h7 >> 21) | ((uint32_t)(h8) << 4);
+  s[26] = h8 >> 4;
+  s[27] = h8 >> 12;
+  s[28] = (h8 >> 20) | ((uint32_t)(h9) << 6);
+  s[29] = h9 >> 2;
+  s[30] = h9 >> 10;
+  s[31] = h9 >> 18;
+}
+
+/* h = f */
+static void fe_copy(fe h, const fe f) {
+  memmove(h, f, sizeof(int32_t) * 10);
+}
+
+/* h = 0 */
+static void fe_0(fe h) { memset(h, 0, sizeof(int32_t) * 10); }
+
+/* h = 1 */
+static void fe_1(fe h) {
+  memset(h, 0, sizeof(int32_t) * 10);
+  h[0] = 1;
+}
+
+/* h = f + g
+ * Can overlap h with f or g.
+ *
+ * Preconditions:
+ *    |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+ *    |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+ *
+ * Postconditions:
+ *    |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */
+static void fe_add(fe h, const fe f, const fe g) {
+  unsigned i;
+  for (i = 0; i < 10; i++) {
+    h[i] = f[i] + g[i];
+  }
+}
+
+/* h = f - g
+ * Can overlap h with f or g.
+ *
+ * Preconditions:
+ *    |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+ *    |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+ *
+ * Postconditions:
+ *    |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. */
+static void fe_sub(fe h, const fe f, const fe g) {
+  unsigned i;
+  for (i = 0; i < 10; i++) {
+    h[i] = f[i] - g[i];
+  }
+}
+
+/* h = f * g
+ * Can overlap h with f or g.
+ *
+ * Preconditions:
+ *    |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
+ *    |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
+ *
+ * Postconditions:
+ *    |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
+ *
+ * Notes on implementation strategy:
+ *
+ * Using schoolbook multiplication.
+ * Karatsuba would save a little in some cost models.
+ *
+ * Most multiplications by 2 and 19 are 32-bit precomputations;
+ * cheaper than 64-bit postcomputations.
+ *
+ * There is one remaining multiplication by 19 in the carry chain;
+ * one *19 precomputation can be merged into this,
+ * but the resulting data flow is considerably less clean.
+ *
+ * There are 12 carries below.
+ * 10 of them are 2-way parallelizable and vectorizable.
+ * Can get away with 11 carries, but then data flow is much deeper.
+ *
+ * With tighter constraints on inputs can squeeze carries into int32. */
+static void fe_mul(fe h, const fe f, const fe g) {
+  int32_t f0 = f[0];
+  int32_t f1 = f[1];
+  int32_t f2 = f[2];
+  int32_t f3 = f[3];
+  int32_t f4 = f[4];
+  int32_t f5 = f[5];
+  int32_t f6 = f[6];
+  int32_t f7 = f[7];
+  int32_t f8 = f[8];
+  int32_t f9 = f[9];
+  int32_t g0 = g[0];
+  int32_t g1 = g[1];
+  int32_t g2 = g[2];
+  int32_t g3 = g[3];
+  int32_t g4 = g[4];
+  int32_t g5 = g[5];
+  int32_t g6 = g[6];
+  int32_t g7 = g[7];
+  int32_t g8 = g[8];
+  int32_t g9 = g[9];
+  int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */
+  int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */
+  int32_t g3_19 = 19 * g3;
+  int32_t g4_19 = 19 * g4;
+  int32_t g5_19 = 19 * g5;
+  int32_t g6_19 = 19 * g6;
+  int32_t g7_19 = 19 * g7;
+  int32_t g8_19 = 19 * g8;
+  int32_t g9_19 = 19 * g9;
+  int32_t f1_2 = 2 * f1;
+  int32_t f3_2 = 2 * f3;
+  int32_t f5_2 = 2 * f5;
+  int32_t f7_2 = 2 * f7;
+  int32_t f9_2 = 2 * f9;
+  int64_t f0g0    = f0   * (int64_t) g0;
+  int64_t f0g1    = f0   * (int64_t) g1;
+  int64_t f0g2    = f0   * (int64_t) g2;
+  int64_t f0g3    = f0   * (int64_t) g3;
+  int64_t f0g4    = f0   * (int64_t) g4;
+  int64_t f0g5    = f0   * (int64_t) g5;
+  int64_t f0g6    = f0   * (int64_t) g6;
+  int64_t f0g7    = f0   * (int64_t) g7;
+  int64_t f0g8    = f0   * (int64_t) g8;
+  int64_t f0g9    = f0   * (int64_t) g9;
+  int64_t f1g0    = f1   * (int64_t) g0;
+  int64_t f1g1_2  = f1_2 * (int64_t) g1;
+  int64_t f1g2    = f1   * (int64_t) g2;
+  int64_t f1g3_2  = f1_2 * (int64_t) g3;
+  int64_t f1g4    = f1   * (int64_t) g4;
+  int64_t f1g5_2  = f1_2 * (int64_t) g5;
+  int64_t f1g6    = f1   * (int64_t) g6;
+  int64_t f1g7_2  = f1_2 * (int64_t) g7;
+  int64_t f1g8    = f1   * (int64_t) g8;
+  int64_t f1g9_38 = f1_2 * (int64_t) g9_19;
+  int64_t f2g0    = f2   * (int64_t) g0;
+  int64_t f2g1    = f2   * (int64_t) g1;
+  int64_t f2g2    = f2   * (int64_t) g2;
+  int64_t f2g3    = f2   * (int64_t) g3;
+  int64_t f2g4    = f2   * (int64_t) g4;
+  int64_t f2g5    = f2   * (int64_t) g5;
+  int64_t f2g6    = f2   * (int64_t) g6;
+  int64_t f2g7    = f2   * (int64_t) g7;
+  int64_t f2g8_19 = f2   * (int64_t) g8_19;
+  int64_t f2g9_19 = f2   * (int64_t) g9_19;
+  int64_t f3g0    = f3   * (int64_t) g0;
+  int64_t f3g1_2  = f3_2 * (int64_t) g1;
+  int64_t f3g2    = f3   * (int64_t) g2;
+  int64_t f3g3_2  = f3_2 * (int64_t) g3;
+  int64_t f3g4    = f3   * (int64_t) g4;
+  int64_t f3g5_2  = f3_2 * (int64_t) g5;
+  int64_t f3g6    = f3   * (int64_t) g6;
+  int64_t f3g7_38 = f3_2 * (int64_t) g7_19;
+  int64_t f3g8_19 = f3   * (int64_t) g8_19;
+  int64_t f3g9_38 = f3_2 * (int64_t) g9_19;
+  int64_t f4g0    = f4   * (int64_t) g0;
+  int64_t f4g1    = f4   * (int64_t) g1;
+  int64_t f4g2    = f4   * (int64_t) g2;
+  int64_t f4g3    = f4   * (int64_t) g3;
+  int64_t f4g4    = f4   * (int64_t) g4;
+  int64_t f4g5    = f4   * (int64_t) g5;
+  int64_t f4g6_19 = f4   * (int64_t) g6_19;
+  int64_t f4g7_19 = f4   * (int64_t) g7_19;
+  int64_t f4g8_19 = f4   * (int64_t) g8_19;
+  int64_t f4g9_19 = f4   * (int64_t) g9_19;
+  int64_t f5g0    = f5   * (int64_t) g0;
+  int64_t f5g1_2  = f5_2 * (int64_t) g1;
+  int64_t f5g2    = f5   * (int64_t) g2;
+  int64_t f5g3_2  = f5_2 * (int64_t) g3;
+  int64_t f5g4    = f5   * (int64_t) g4;
+  int64_t f5g5_38 = f5_2 * (int64_t) g5_19;
+  int64_t f5g6_19 = f5   * (int64_t) g6_19;
+  int64_t f5g7_38 = f5_2 * (int64_t) g7_19;
+  int64_t f5g8_19 = f5   * (int64_t) g8_19;
+  int64_t f5g9_38 = f5_2 * (int64_t) g9_19;
+  int64_t f6g0    = f6   * (int64_t) g0;
+  int64_t f6g1    = f6   * (int64_t) g1;
+  int64_t f6g2    = f6   * (int64_t) g2;
+  int64_t f6g3    = f6   * (int64_t) g3;
+  int64_t f6g4_19 = f6   * (int64_t) g4_19;
+  int64_t f6g5_19 = f6   * (int64_t) g5_19;
+  int64_t f6g6_19 = f6   * (int64_t) g6_19;
+  int64_t f6g7_19 = f6   * (int64_t) g7_19;
+  int64_t f6g8_19 = f6   * (int64_t) g8_19;
+  int64_t f6g9_19 = f6   * (int64_t) g9_19;
+  int64_t f7g0    = f7   * (int64_t) g0;
+  int64_t f7g1_2  = f7_2 * (int64_t) g1;
+  int64_t f7g2    = f7   * (int64_t) g2;
+  int64_t f7g3_38 = f7_2 * (int64_t) g3_19;
+  int64_t f7g4_19 = f7   * (int64_t) g4_19;
+  int64_t f7g5_38 = f7_2 * (int64_t) g5_19;
+  int64_t f7g6_19 = f7   * (int64_t) g6_19;
+  int64_t f7g7_38 = f7_2 * (int64_t) g7_19;
+  int64_t f7g8_19 = f7   * (int64_t) g8_19;
+  int64_t f7g9_38 = f7_2 * (int64_t) g9_19;
+  int64_t f8g0    = f8   * (int64_t) g0;
+  int64_t f8g1    = f8   * (int64_t) g1;
+  int64_t f8g2_19 = f8   * (int64_t) g2_19;
+  int64_t f8g3_19 = f8   * (int64_t) g3_19;
+  int64_t f8g4_19 = f8   * (int64_t) g4_19;
+  int64_t f8g5_19 = f8   * (int64_t) g5_19;
+  int64_t f8g6_19 = f8   * (int64_t) g6_19;
+  int64_t f8g7_19 = f8   * (int64_t) g7_19;
+  int64_t f8g8_19 = f8   * (int64_t) g8_19;
+  int64_t f8g9_19 = f8   * (int64_t) g9_19;
+  int64_t f9g0    = f9   * (int64_t) g0;
+  int64_t f9g1_38 = f9_2 * (int64_t) g1_19;
+  int64_t f9g2_19 = f9   * (int64_t) g2_19;
+  int64_t f9g3_38 = f9_2 * (int64_t) g3_19;
+  int64_t f9g4_19 = f9   * (int64_t) g4_19;
+  int64_t f9g5_38 = f9_2 * (int64_t) g5_19;
+  int64_t f9g6_19 = f9   * (int64_t) g6_19;
+  int64_t f9g7_38 = f9_2 * (int64_t) g7_19;
+  int64_t f9g8_19 = f9   * (int64_t) g8_19;
+  int64_t f9g9_38 = f9_2 * (int64_t) g9_19;
+  int64_t h0 = f0g0+f1g9_38+f2g8_19+f3g7_38+f4g6_19+f5g5_38+f6g4_19+f7g3_38+f8g2_19+f9g1_38;
+  int64_t h1 = f0g1+f1g0   +f2g9_19+f3g8_19+f4g7_19+f5g6_19+f6g5_19+f7g4_19+f8g3_19+f9g2_19;
+  int64_t h2 = f0g2+f1g1_2 +f2g0   +f3g9_38+f4g8_19+f5g7_38+f6g6_19+f7g5_38+f8g4_19+f9g3_38;
+  int64_t h3 = f0g3+f1g2   +f2g1   +f3g0   +f4g9_19+f5g8_19+f6g7_19+f7g6_19+f8g5_19+f9g4_19;
+  int64_t h4 = f0g4+f1g3_2 +f2g2   +f3g1_2 +f4g0   +f5g9_38+f6g8_19+f7g7_38+f8g6_19+f9g5_38;
+  int64_t h5 = f0g5+f1g4   +f2g3   +f3g2   +f4g1   +f5g0   +f6g9_19+f7g8_19+f8g7_19+f9g6_19;
+  int64_t h6 = f0g6+f1g5_2 +f2g4   +f3g3_2 +f4g2   +f5g1_2 +f6g0   +f7g9_38+f8g8_19+f9g7_38;
+  int64_t h7 = f0g7+f1g6   +f2g5   +f3g4   +f4g3   +f5g2   +f6g1   +f7g0   +f8g9_19+f9g8_19;
+  int64_t h8 = f0g8+f1g7_2 +f2g6   +f3g5_2 +f4g4   +f5g3_2 +f6g2   +f7g1_2 +f8g0   +f9g9_38;
+  int64_t h9 = f0g9+f1g8   +f2g7   +f3g6   +f4g5   +f5g4   +f6g3   +f7g2   +f8g1   +f9g0   ;
+  int64_t carry0;
+  int64_t carry1;
+  int64_t carry2;
+  int64_t carry3;
+  int64_t carry4;
+  int64_t carry5;
+  int64_t carry6;
+  int64_t carry7;
+  int64_t carry8;
+  int64_t carry9;
+
+  /* |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38))
+   *   i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8
+   * |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19))
+   *   i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 */
+
+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
+  /* |h0| <= 2^25 */
+  /* |h4| <= 2^25 */
+  /* |h1| <= 1.71*2^59 */
+  /* |h5| <= 1.71*2^59 */
+
+  carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
+  carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
+  /* |h1| <= 2^24; from now on fits into int32 */
+  /* |h5| <= 2^24; from now on fits into int32 */
+  /* |h2| <= 1.41*2^60 */
+  /* |h6| <= 1.41*2^60 */
+
+  carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
+  carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
+  /* |h2| <= 2^25; from now on fits into int32 unchanged */
+  /* |h6| <= 2^25; from now on fits into int32 unchanged */
+  /* |h3| <= 1.71*2^59 */
+  /* |h7| <= 1.71*2^59 */
+
+  carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
+  carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
+  /* |h3| <= 2^24; from now on fits into int32 unchanged */
+  /* |h7| <= 2^24; from now on fits into int32 unchanged */
+  /* |h4| <= 1.72*2^34 */
+  /* |h8| <= 1.41*2^60 */
+
+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
+  carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
+  /* |h4| <= 2^25; from now on fits into int32 unchanged */
+  /* |h8| <= 2^25; from now on fits into int32 unchanged */
+  /* |h5| <= 1.01*2^24 */
+  /* |h9| <= 1.71*2^59 */
+
+  carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
+  /* |h9| <= 2^24; from now on fits into int32 unchanged */
+  /* |h0| <= 1.1*2^39 */
+
+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
+  /* |h0| <= 2^25; from now on fits into int32 unchanged */
+  /* |h1| <= 1.01*2^24 */
+
+  h[0] = h0;
+  h[1] = h1;
+  h[2] = h2;
+  h[3] = h3;
+  h[4] = h4;
+  h[5] = h5;
+  h[6] = h6;
+  h[7] = h7;
+  h[8] = h8;
+  h[9] = h9;
+}
+
+/* h = f * f
+ * Can overlap h with f.
+ *
+ * Preconditions:
+ *    |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
+ *
+ * Postconditions:
+ *    |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
+ *
+ * See fe_mul.c for discussion of implementation strategy. */
+static void fe_sq(fe h, const fe f) {
+  int32_t f0 = f[0];
+  int32_t f1 = f[1];
+  int32_t f2 = f[2];
+  int32_t f3 = f[3];
+  int32_t f4 = f[4];
+  int32_t f5 = f[5];
+  int32_t f6 = f[6];
+  int32_t f7 = f[7];
+  int32_t f8 = f[8];
+  int32_t f9 = f[9];
+  int32_t f0_2 = 2 * f0;
+  int32_t f1_2 = 2 * f1;
+  int32_t f2_2 = 2 * f2;
+  int32_t f3_2 = 2 * f3;
+  int32_t f4_2 = 2 * f4;
+  int32_t f5_2 = 2 * f5;
+  int32_t f6_2 = 2 * f6;
+  int32_t f7_2 = 2 * f7;
+  int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
+  int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
+  int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
+  int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
+  int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
+  int64_t f0f0    = f0   * (int64_t) f0;
+  int64_t f0f1_2  = f0_2 * (int64_t) f1;
+  int64_t f0f2_2  = f0_2 * (int64_t) f2;
+  int64_t f0f3_2  = f0_2 * (int64_t) f3;
+  int64_t f0f4_2  = f0_2 * (int64_t) f4;
+  int64_t f0f5_2  = f0_2 * (int64_t) f5;
+  int64_t f0f6_2  = f0_2 * (int64_t) f6;
+  int64_t f0f7_2  = f0_2 * (int64_t) f7;
+  int64_t f0f8_2  = f0_2 * (int64_t) f8;
+  int64_t f0f9_2  = f0_2 * (int64_t) f9;
+  int64_t f1f1_2  = f1_2 * (int64_t) f1;
+  int64_t f1f2_2  = f1_2 * (int64_t) f2;
+  int64_t f1f3_4  = f1_2 * (int64_t) f3_2;
+  int64_t f1f4_2  = f1_2 * (int64_t) f4;
+  int64_t f1f5_4  = f1_2 * (int64_t) f5_2;
+  int64_t f1f6_2  = f1_2 * (int64_t) f6;
+  int64_t f1f7_4  = f1_2 * (int64_t) f7_2;
+  int64_t f1f8_2  = f1_2 * (int64_t) f8;
+  int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
+  int64_t f2f2    = f2   * (int64_t) f2;
+  int64_t f2f3_2  = f2_2 * (int64_t) f3;
+  int64_t f2f4_2  = f2_2 * (int64_t) f4;
+  int64_t f2f5_2  = f2_2 * (int64_t) f5;
+  int64_t f2f6_2  = f2_2 * (int64_t) f6;
+  int64_t f2f7_2  = f2_2 * (int64_t) f7;
+  int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
+  int64_t f2f9_38 = f2   * (int64_t) f9_38;
+  int64_t f3f3_2  = f3_2 * (int64_t) f3;
+  int64_t f3f4_2  = f3_2 * (int64_t) f4;
+  int64_t f3f5_4  = f3_2 * (int64_t) f5_2;
+  int64_t f3f6_2  = f3_2 * (int64_t) f6;
+  int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
+  int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
+  int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
+  int64_t f4f4    = f4   * (int64_t) f4;
+  int64_t f4f5_2  = f4_2 * (int64_t) f5;
+  int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
+  int64_t f4f7_38 = f4   * (int64_t) f7_38;
+  int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
+  int64_t f4f9_38 = f4   * (int64_t) f9_38;
+  int64_t f5f5_38 = f5   * (int64_t) f5_38;
+  int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
+  int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
+  int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
+  int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
+  int64_t f6f6_19 = f6   * (int64_t) f6_19;
+  int64_t f6f7_38 = f6   * (int64_t) f7_38;
+  int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
+  int64_t f6f9_38 = f6   * (int64_t) f9_38;
+  int64_t f7f7_38 = f7   * (int64_t) f7_38;
+  int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
+  int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
+  int64_t f8f8_19 = f8   * (int64_t) f8_19;
+  int64_t f8f9_38 = f8   * (int64_t) f9_38;
+  int64_t f9f9_38 = f9   * (int64_t) f9_38;
+  int64_t h0 = f0f0  +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
+  int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
+  int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
+  int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
+  int64_t h4 = f0f4_2+f1f3_4 +f2f2   +f5f9_76+f6f8_38+f7f7_38;
+  int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
+  int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
+  int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
+  int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4   +f9f9_38;
+  int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
+  int64_t carry0;
+  int64_t carry1;
+  int64_t carry2;
+  int64_t carry3;
+  int64_t carry4;
+  int64_t carry5;
+  int64_t carry6;
+  int64_t carry7;
+  int64_t carry8;
+  int64_t carry9;
+
+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
+
+  carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
+  carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
+
+  carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
+  carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
+
+  carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
+  carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
+
+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
+  carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
+
+  carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
+
+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
+
+  h[0] = h0;
+  h[1] = h1;
+  h[2] = h2;
+  h[3] = h3;
+  h[4] = h4;
+  h[5] = h5;
+  h[6] = h6;
+  h[7] = h7;
+  h[8] = h8;
+  h[9] = h9;
+}
+
+static void fe_invert(fe out, const fe z) {
+  fe t0;
+  fe t1;
+  fe t2;
+  fe t3;
+  int i;
+
+  /*
+   * Compute z ** -1 = z ** (2 ** 255 - 19 - 2) with the exponent as
+   * 2 ** 255 - 21 = (2 ** 5) * (2 ** 250 - 1) + 11.
+   */
+
+  /* t0 = z ** 2 */
+  fe_sq(t0, z);
+
+  /* t1 = t0 ** (2 ** 2) = z ** 8 */
+  fe_sq(t1, t0);
+  fe_sq(t1, t1);
+
+  /* t1 = z * t1 = z ** 9 */
+  fe_mul(t1, z, t1);
+  /* t0 = t0 * t1 = z ** 11 -- stash t0 away for the end. */
+  fe_mul(t0, t0, t1);
+
+  /* t2 = t0 ** 2 = z ** 22 */
+  fe_sq(t2, t0);
+
+  /* t1 = t1 * t2 = z ** (2 ** 5 - 1) */
+  fe_mul(t1, t1, t2);
+
+  /* t2 = t1 ** (2 ** 5) = z ** ((2 ** 5) * (2 ** 5 - 1)) */
+  fe_sq(t2, t1);
+  for (i = 1; i < 5; ++i) {
+    fe_sq(t2, t2);
+  }
+
+  /* t1 = t1 * t2 = z ** ((2 ** 5 + 1) * (2 ** 5 - 1)) = z ** (2 ** 10 - 1) */
+  fe_mul(t1, t2, t1);
+
+  /* Continuing similarly... */
+
+  /* t2 = z ** (2 ** 20 - 1) */
+  fe_sq(t2, t1);
+  for (i = 1; i < 10; ++i) {
+    fe_sq(t2, t2);
+  }
+  fe_mul(t2, t2, t1);
+
+  /* t2 = z ** (2 ** 40 - 1) */
+  fe_sq(t3, t2);
+  for (i = 1; i < 20; ++i) {
+    fe_sq(t3, t3);
+  }
+  fe_mul(t2, t3, t2);
+
+  /* t2 = z ** (2 ** 10) * (2 ** 40 - 1) */
+  for (i = 0; i < 10; ++i) {
+    fe_sq(t2, t2);
+  }
+  /* t1 = z ** (2 ** 50 - 1) */
+  fe_mul(t1, t2, t1);
+
+  /* t2 = z ** (2 ** 100 - 1) */
+  fe_sq(t2, t1);
+  for (i = 1; i < 50; ++i) {
+    fe_sq(t2, t2);
+  }
+  fe_mul(t2, t2, t1);
+
+  /* t2 = z ** (2 ** 200 - 1) */
+  fe_sq(t3, t2);
+  for (i = 1; i < 100; ++i) {
+    fe_sq(t3, t3);
+  }
+  fe_mul(t2, t3, t2);
+
+  /* t2 = z ** ((2 ** 50) * (2 ** 200 - 1) */
+  fe_sq(t2, t2);
+  for (i = 1; i < 50; ++i) {
+    fe_sq(t2, t2);
+  }
+
+  /* t1 = z ** (2 ** 250 - 1) */
+  fe_mul(t1, t2, t1);
+
+  /* t1 = z ** ((2 ** 5) * (2 ** 250 - 1)) */
+  fe_sq(t1, t1);
+  for (i = 1; i < 5; ++i) {
+    fe_sq(t1, t1);
+  }
+
+  /* Recall t0 = z ** 11; out = z ** (2 ** 255 - 21) */
+  fe_mul(out, t1, t0);
+}
+
+/* h = -f
+ *
+ * Preconditions:
+ *    |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
+ *
+ * Postconditions:
+ *    |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. */
+static void fe_neg(fe h, const fe f) {
+  unsigned i;
+  for (i = 0; i < 10; i++) {
+    h[i] = -f[i];
+  }
+}
+
+/* Replace (f,g) with (g,g) if b == 1;
+ * replace (f,g) with (f,g) if b == 0.
+ *
+ * Preconditions: b in {0,1}. */
+static void fe_cmov(fe f, const fe g, unsigned b) {
+  size_t i;
+  b = 0-b;
+  for (i = 0; i < 10; i++) {
+    int32_t x = f[i] ^ g[i];
+    x &= b;
+    f[i] ^= x;
+  }
+}
+
+/* h = 2 * f * f
+ * Can overlap h with f.
+ *
+ * Preconditions:
+ *    |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
+ *
+ * Postconditions:
+ *    |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
+ *
+ * See fe_mul.c for discussion of implementation strategy. */
+static void fe_sq2(fe h, const fe f) {
+  int32_t f0 = f[0];
+  int32_t f1 = f[1];
+  int32_t f2 = f[2];
+  int32_t f3 = f[3];
+  int32_t f4 = f[4];
+  int32_t f5 = f[5];
+  int32_t f6 = f[6];
+  int32_t f7 = f[7];
+  int32_t f8 = f[8];
+  int32_t f9 = f[9];
+  int32_t f0_2 = 2 * f0;
+  int32_t f1_2 = 2 * f1;
+  int32_t f2_2 = 2 * f2;
+  int32_t f3_2 = 2 * f3;
+  int32_t f4_2 = 2 * f4;
+  int32_t f5_2 = 2 * f5;
+  int32_t f6_2 = 2 * f6;
+  int32_t f7_2 = 2 * f7;
+  int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
+  int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
+  int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
+  int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
+  int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
+  int64_t f0f0    = f0   * (int64_t) f0;
+  int64_t f0f1_2  = f0_2 * (int64_t) f1;
+  int64_t f0f2_2  = f0_2 * (int64_t) f2;
+  int64_t f0f3_2  = f0_2 * (int64_t) f3;
+  int64_t f0f4_2  = f0_2 * (int64_t) f4;
+  int64_t f0f5_2  = f0_2 * (int64_t) f5;
+  int64_t f0f6_2  = f0_2 * (int64_t) f6;
+  int64_t f0f7_2  = f0_2 * (int64_t) f7;
+  int64_t f0f8_2  = f0_2 * (int64_t) f8;
+  int64_t f0f9_2  = f0_2 * (int64_t) f9;
+  int64_t f1f1_2  = f1_2 * (int64_t) f1;
+  int64_t f1f2_2  = f1_2 * (int64_t) f2;
+  int64_t f1f3_4  = f1_2 * (int64_t) f3_2;
+  int64_t f1f4_2  = f1_2 * (int64_t) f4;
+  int64_t f1f5_4  = f1_2 * (int64_t) f5_2;
+  int64_t f1f6_2  = f1_2 * (int64_t) f6;
+  int64_t f1f7_4  = f1_2 * (int64_t) f7_2;
+  int64_t f1f8_2  = f1_2 * (int64_t) f8;
+  int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
+  int64_t f2f2    = f2   * (int64_t) f2;
+  int64_t f2f3_2  = f2_2 * (int64_t) f3;
+  int64_t f2f4_2  = f2_2 * (int64_t) f4;
+  int64_t f2f5_2  = f2_2 * (int64_t) f5;
+  int64_t f2f6_2  = f2_2 * (int64_t) f6;
+  int64_t f2f7_2  = f2_2 * (int64_t) f7;
+  int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
+  int64_t f2f9_38 = f2   * (int64_t) f9_38;
+  int64_t f3f3_2  = f3_2 * (int64_t) f3;
+  int64_t f3f4_2  = f3_2 * (int64_t) f4;
+  int64_t f3f5_4  = f3_2 * (int64_t) f5_2;
+  int64_t f3f6_2  = f3_2 * (int64_t) f6;
+  int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
+  int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
+  int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
+  int64_t f4f4    = f4   * (int64_t) f4;
+  int64_t f4f5_2  = f4_2 * (int64_t) f5;
+  int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
+  int64_t f4f7_38 = f4   * (int64_t) f7_38;
+  int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
+  int64_t f4f9_38 = f4   * (int64_t) f9_38;
+  int64_t f5f5_38 = f5   * (int64_t) f5_38;
+  int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
+  int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
+  int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
+  int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
+  int64_t f6f6_19 = f6   * (int64_t) f6_19;
+  int64_t f6f7_38 = f6   * (int64_t) f7_38;
+  int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
+  int64_t f6f9_38 = f6   * (int64_t) f9_38;
+  int64_t f7f7_38 = f7   * (int64_t) f7_38;
+  int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
+  int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
+  int64_t f8f8_19 = f8   * (int64_t) f8_19;
+  int64_t f8f9_38 = f8   * (int64_t) f9_38;
+  int64_t f9f9_38 = f9   * (int64_t) f9_38;
+  int64_t h0 = f0f0  +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
+  int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
+  int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
+  int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
+  int64_t h4 = f0f4_2+f1f3_4 +f2f2   +f5f9_76+f6f8_38+f7f7_38;
+  int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
+  int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
+  int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
+  int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4   +f9f9_38;
+  int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
+  int64_t carry0;
+  int64_t carry1;
+  int64_t carry2;
+  int64_t carry3;
+  int64_t carry4;
+  int64_t carry5;
+  int64_t carry6;
+  int64_t carry7;
+  int64_t carry8;
+  int64_t carry9;
+
+  h0 += h0;
+  h1 += h1;
+  h2 += h2;
+  h3 += h3;
+  h4 += h4;
+  h5 += h5;
+  h6 += h6;
+  h7 += h7;
+  h8 += h8;
+  h9 += h9;
+
+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
+
+  carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
+  carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
+
+  carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
+  carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
+
+  carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
+  carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
+
+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
+  carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
+
+  carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
+
+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
+
+  h[0] = h0;
+  h[1] = h1;
+  h[2] = h2;
+  h[3] = h3;
+  h[4] = h4;
+  h[5] = h5;
+  h[6] = h6;
+  h[7] = h7;
+  h[8] = h8;
+  h[9] = h9;
+}
+
+/* ge means group element.
+
+ * Here the group is the set of pairs (x,y) of field elements (see fe.h)
+ * satisfying -x^2 + y^2 = 1 + d x^2y^2
+ * where d = -121665/121666.
+ *
+ * Representations:
+ *   ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z
+ *   ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
+ *   ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
+ *   ge_precomp (Duif): (y+x,y-x,2dxy) */
+
+typedef struct {
+  fe X;
+  fe Y;
+  fe Z;
+} ge_p2;
+
+typedef struct {
+  fe X;
+  fe Y;
+  fe Z;
+  fe T;
+} ge_p3;
+
+typedef struct {
+  fe X;
+  fe Y;
+  fe Z;
+  fe T;
+} ge_p1p1;
+
+typedef struct {
+  fe yplusx;
+  fe yminusx;
+  fe xy2d;
+} ge_precomp;
+
+typedef struct {
+  fe YplusX;
+  fe YminusX;
+  fe Z;
+  fe T2d;
+} ge_cached;
+
+static void ge_p3_0(ge_p3 *h) {
+  fe_0(h->X);
+  fe_1(h->Y);
+  fe_1(h->Z);
+  fe_0(h->T);
+}
+
+static void ge_precomp_0(ge_precomp *h) {
+  fe_1(h->yplusx);
+  fe_1(h->yminusx);
+  fe_0(h->xy2d);
+}
+
+/* r = p */
+static void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) {
+  fe_copy(r->X, p->X);
+  fe_copy(r->Y, p->Y);
+  fe_copy(r->Z, p->Z);
+}
+
+/* r = p */
+static void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) {
+  fe_mul(r->X, p->X, p->T);
+  fe_mul(r->Y, p->Y, p->Z);
+  fe_mul(r->Z, p->Z, p->T);
+}
+
+/* r = p */
+static void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) {
+  fe_mul(r->X, p->X, p->T);
+  fe_mul(r->Y, p->Y, p->Z);
+  fe_mul(r->Z, p->Z, p->T);
+  fe_mul(r->T, p->X, p->Y);
+}
+
+/* r = 2 * p */
+static void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) {
+  fe t0;
+
+  fe_sq(r->X, p->X);
+  fe_sq(r->Z, p->Y);
+  fe_sq2(r->T, p->Z);
+  fe_add(r->Y, p->X, p->Y);
+  fe_sq(t0, r->Y);
+  fe_add(r->Y, r->Z, r->X);
+  fe_sub(r->Z, r->Z, r->X);
+  fe_sub(r->X, t0, r->Y);
+  fe_sub(r->T, r->T, r->Z);
+}
+
+/* r = 2 * p */
+static void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) {
+  ge_p2 q;
+  ge_p3_to_p2(&q, p);
+  ge_p2_dbl(r, &q);
+}
+
+/* r = p + q */
+static void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) {
+  fe t0;
+
+  fe_add(r->X, p->Y, p->X);
+  fe_sub(r->Y, p->Y, p->X);
+  fe_mul(r->Z, r->X, q->yplusx);
+  fe_mul(r->Y, r->Y, q->yminusx);
+  fe_mul(r->T, q->xy2d, p->T);
+  fe_add(t0, p->Z, p->Z);
+  fe_sub(r->X, r->Z, r->Y);
+  fe_add(r->Y, r->Z, r->Y);
+  fe_add(r->Z, t0, r->T);
+  fe_sub(r->T, t0, r->T);
+}
+
+static uint8_t equal(signed char b, signed char c) {
+  uint8_t ub = b;
+  uint8_t uc = c;
+  uint8_t x = ub ^ uc; /* 0: yes; 1..255: no */
+  uint32_t y = x;      /* 0: yes; 1..255: no */
+  y -= 1;              /* 4294967295: yes; 0..254: no */
+  y >>= 31;            /* 1: yes; 0: no */
+  return y;
+}
+
+static void cmov(ge_precomp *t, const ge_precomp *u, uint8_t b) {
+  fe_cmov(t->yplusx, u->yplusx, b);
+  fe_cmov(t->yminusx, u->yminusx, b);
+  fe_cmov(t->xy2d, u->xy2d, b);
+}
+
+/* k25519Precomp[i][j] = (j+1)*256^i*B */
+static const ge_precomp k25519Precomp[32][8] = {
+    {
+        {
+            {25967493, -14356035, 29566456, 3660896, -12694345, 4014787,
+             27544626, -11754271, -6079156, 2047605},
+            {-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692,
+             5043384, 19500929, -15469378},
+            {-8738181, 4489570, 9688441, -14785194, 10184609, -12363380,
+             29287919, 11864899, -24514362, -4438546},
+        },
+        {
+            {-12815894, -12976347, -21581243, 11784320, -25355658, -2750717,
+             -11717903, -3814571, -358445, -10211303},
+            {-21703237, 6903825, 27185491, 6451973, -29577724, -9554005,
+             -15616551, 11189268, -26829678, -5319081},
+            {26966642, 11152617, 32442495, 15396054, 14353839, -12752335,
+             -3128826, -9541118, -15472047, -4166697},
+        },
+        {
+            {15636291, -9688557, 24204773, -7912398, 616977, -16685262,
+             27787600, -14772189, 28944400, -1550024},
+            {16568933, 4717097, -11556148, -1102322, 15682896, -11807043,
+             16354577, -11775962, 7689662, 11199574},
+            {30464156, -5976125, -11779434, -15670865, 23220365, 15915852,
+             7512774, 10017326, -17749093, -9920357},
+        },
+        {
+            {-17036878, 13921892, 10945806, -6033431, 27105052, -16084379,
+             -28926210, 15006023, 3284568, -6276540},
+            {23599295, -8306047, -11193664, -7687416, 13236774, 10506355,
+             7464579, 9656445, 13059162, 10374397},
+            {7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664,
+             -3839045, -641708, -101325},
+        },
+        {
+            {10861363, 11473154, 27284546, 1981175, -30064349, 12577861,
+             32867885, 14515107, -15438304, 10819380},
+            {4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668,
+             12483688, -12668491, 5581306},
+            {19563160, 16186464, -29386857, 4097519, 10237984, -4348115,
+             28542350, 13850243, -23678021, -15815942},
+        },
+        {
+            {-15371964, -12862754, 32573250, 4720197, -26436522, 5875511,
+             -19188627, -15224819, -9818940, -12085777},
+            {-8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240,
+             -15689887, 1762328, 14866737},
+            {-18199695, -15951423, -10473290, 1707278, -17185920, 3916101,
+             -28236412, 3959421, 27914454, 4383652},
+        },
+        {
+            {5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852,
+             5230134, -23952439, -15175766},
+            {-30269007, -3463509, 7665486, 10083793, 28475525, 1649722,
+             20654025, 16520125, 30598449, 7715701},
+            {28881845, 14381568, 9657904, 3680757, -20181635, 7843316,
+             -31400660, 1370708, 29794553, -1409300},
+        },
+        {
+            {14499471, -2729599, -33191113, -4254652, 28494862, 14271267,
+             30290735, 10876454, -33154098, 2381726},
+            {-7195431, -2655363, -14730155, 462251, -27724326, 3941372,
+             -6236617, 3696005, -32300832, 15351955},
+            {27431194, 8222322, 16448760, -3907995, -18707002, 11938355,
+             -32961401, -2970515, 29551813, 10109425},
+        },
+    },
+    {
+        {
+            {-13657040, -13155431, -31283750, 11777098, 21447386, 6519384,
+             -2378284, -1627556, 10092783, -4764171},
+            {27939166, 14210322, 4677035, 16277044, -22964462, -12398139,
+             -32508754, 12005538, -17810127, 12803510},
+            {17228999, -15661624, -1233527, 300140, -1224870, -11714777,
+             30364213, -9038194, 18016357, 4397660},
+        },
+        {
+            {-10958843, -7690207, 4776341, -14954238, 27850028, -15602212,
+             -26619106, 14544525, -17477504, 982639},
+            {29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899,
+             -4120128, -21047696, 9934963},
+            {5793303, 16271923, -24131614, -10116404, 29188560, 1206517,
+             -14747930, 4559895, -30123922, -10897950},
+        },
+        {
+            {-27643952, -11493006, 16282657, -11036493, 28414021, -15012264,
+             24191034, 4541697, -13338309, 5500568},
+            {12650548, -1497113, 9052871, 11355358, -17680037, -8400164,
+             -17430592, 12264343, 10874051, 13524335},
+            {25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038,
+             5080568, -22528059, 5376628},
+        },
+        {
+            {-26088264, -4011052, -17013699, -3537628, -6726793, 1920897,
+             -22321305, -9447443, 4535768, 1569007},
+            {-2255422, 14606630, -21692440, -8039818, 28430649, 8775819,
+             -30494562, 3044290, 31848280, 12543772},
+            {-22028579, 2943893, -31857513, 6777306, 13784462, -4292203,
+             -27377195, -2062731, 7718482, 14474653},
+        },
+        {
+            {2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965,
+             -7236665, 24316168, -5253567},
+            {13741529, 10911568, -33233417, -8603737, -20177830, -1033297,
+             33040651, -13424532, -20729456, 8321686},
+            {21060490, -2212744, 15712757, -4336099, 1639040, 10656336,
+             23845965, -11874838, -9984458, 608372},
+        },
+        {
+            {-13672732, -15087586, -10889693, -7557059, -6036909, 11305547,
+             1123968, -6780577, 27229399, 23887},
+            {-23244140, -294205, -11744728, 14712571, -29465699, -2029617,
+             12797024, -6440308, -1633405, 16678954},
+            {-29500620, 4770662, -16054387, 14001338, 7830047, 9564805,
+             -1508144, -4795045, -17169265, 4904953},
+        },
+        {
+            {24059557, 14617003, 19037157, -15039908, 19766093, -14906429,
+             5169211, 16191880, 2128236, -4326833},
+            {-16981152, 4124966, -8540610, -10653797, 30336522, -14105247,
+             -29806336, 916033, -6882542, -2986532},
+            {-22630907, 12419372, -7134229, -7473371, -16478904, 16739175,
+             285431, 2763829, 15736322, 4143876},
+        },
+        {
+            {2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801,
+             -14594663, 23527084, -16458268},
+            {33431127, -11130478, -17838966, -15626900, 8909499, 8376530,
+             -32625340, 4087881, -15188911, -14416214},
+            {1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055,
+             4357868, -4774191, -16323038},
+        },
+    },
+    {
+        {
+            {6721966, 13833823, -23523388, -1551314, 26354293, -11863321,
+             23365147, -3949732, 7390890, 2759800},
+            {4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353,
+             -4264057, 1244380, -12919645},
+            {-4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413,
+             9208236, 15886429, 16489664},
+        },
+        {
+            {1996075, 10375649, 14346367, 13311202, -6874135, -16438411,
+             -13693198, 398369, -30606455, -712933},
+            {-25307465, 9795880, -2777414, 14878809, -33531835, 14780363,
+             13348553, 12076947, -30836462, 5113182},
+            {-17770784, 11797796, 31950843, 13929123, -25888302, 12288344,
+             -30341101, -7336386, 13847711, 5387222},
+        },
+        {
+            {-18582163, -3416217, 17824843, -2340966, 22744343, -10442611,
+             8763061, 3617786, -19600662, 10370991},
+            {20246567, -14369378, 22358229, -543712, 18507283, -10413996,
+             14554437, -8746092, 32232924, 16763880},
+            {9648505, 10094563, 26416693, 14745928, -30374318, -6472621,
+             11094161, 15689506, 3140038, -16510092},
+        },
+        {
+            {-16160072, 5472695, 31895588, 4744994, 8823515, 10365685,
+             -27224800, 9448613, -28774454, 366295},
+            {19153450, 11523972, -11096490, -6503142, -24647631, 5420647,
+             28344573, 8041113, 719605, 11671788},
+            {8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916,
+             -15266516, 27000813, -10195553},
+        },
+        {
+            {-15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065,
+             5336097, 6750977, -14521026},
+            {11836410, -3979488, 26297894, 16080799, 23455045, 15735944,
+             1695823, -8819122, 8169720, 16220347},
+            {-18115838, 8653647, 17578566, -6092619, -8025777, -16012763,
+             -11144307, -2627664, -5990708, -14166033},
+        },
+        {
+            {-23308498, -10968312, 15213228, -10081214, -30853605, -11050004,
+             27884329, 2847284, 2655861, 1738395},
+            {-27537433, -14253021, -25336301, -8002780, -9370762, 8129821,
+             21651608, -3239336, -19087449, -11005278},
+            {1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092,
+             5821408, 10478196, 8544890},
+        },
+        {
+            {32173121, -16129311, 24896207, 3921497, 22579056, -3410854,
+             19270449, 12217473, 17789017, -3395995},
+            {-30552961, -2228401, -15578829, -10147201, 13243889, 517024,
+             15479401, -3853233, 30460520, 1052596},
+            {-11614875, 13323618, 32618793, 8175907, -15230173, 12596687,
+             27491595, -4612359, 3179268, -9478891},
+        },
+        {
+            {31947069, -14366651, -4640583, -15339921, -15125977, -6039709,
+             -14756777, -16411740, 19072640, -9511060},
+            {11685058, 11822410, 3158003, -13952594, 33402194, -4165066,
+             5977896, -5215017, 473099, 5040608},
+            {-20290863, 8198642, -27410132, 11602123, 1290375, -2799760,
+             28326862, 1721092, -19558642, -3131606},
+        },
+    },
+    {
+        {
+            {7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786,
+             8076149, -27868496, 11538389},
+            {-19935666, 3899861, 18283497, -6801568, -15728660, -11249211,
+             8754525, 7446702, -5676054, 5797016},
+            {-11295600, -3793569, -15782110, -7964573, 12708869, -8456199,
+             2014099, -9050574, -2369172, -5877341},
+        },
+        {
+            {-22472376, -11568741, -27682020, 1146375, 18956691, 16640559,
+             1192730, -3714199, 15123619, 10811505},
+            {14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363,
+             15776356, -28886779, -11974553},
+            {-28241164, -8072475, -4978962, -5315317, 29416931, 1847569,
+             -20654173, -16484855, 4714547, -9600655},
+        },
+        {
+            {15200332, 8368572, 19679101, 15970074, -31872674, 1959451,
+             24611599, -4543832, -11745876, 12340220},
+            {12876937, -10480056, 33134381, 6590940, -6307776, 14872440,
+             9613953, 8241152, 15370987, 9608631},
+            {-4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868,
+             15866074, -28210621, -8814099},
+        },
+        {
+            {26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233,
+             858697, 20571223, 8420556},
+            {14620715, 13067227, -15447274, 8264467, 14106269, 15080814,
+             33531827, 12516406, -21574435, -12476749},
+            {236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519,
+             7256740, 8791136, 15069930},
+        },
+        {
+            {1276410, -9371918, 22949635, -16322807, -23493039, -5702186,
+             14711875, 4874229, -30663140, -2331391},
+            {5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175,
+             -7912378, -33069337, 9234253},
+            {20590503, -9018988, 31529744, -7352666, -2706834, 10650548,
+             31559055, -11609587, 18979186, 13396066},
+        },
+        {
+            {24474287, 4968103, 22267082, 4407354, 24063882, -8325180,
+             -18816887, 13594782, 33514650, 7021958},
+            {-11566906, -6565505, -21365085, 15928892, -26158305, 4315421,
+             -25948728, -3916677, -21480480, 12868082},
+            {-28635013, 13504661, 19988037, -2132761, 21078225, 6443208,
+             -21446107, 2244500, -12455797, -8089383},
+        },
+        {
+            {-30595528, 13793479, -5852820, 319136, -25723172, -6263899,
+             33086546, 8957937, -15233648, 5540521},
+            {-11630176, -11503902, -8119500, -7643073, 2620056, 1022908,
+             -23710744, -1568984, -16128528, -14962807},
+            {23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819,
+             892185, -11513277, -15205948},
+        },
+        {
+            {9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819,
+             4763127, -19179614, 5867134},
+            {-32765025, 1927590, 31726409, -4753295, 23962434, -16019500,
+             27846559, 5931263, -29749703, -16108455},
+            {27461885, -2977536, 22380810, 1815854, -23033753, -3031938,
+             7283490, -15148073, -19526700, 7734629},
+        },
+    },
+    {
+        {
+            {-8010264, -9590817, -11120403, 6196038, 29344158, -13430885,
+             7585295, -3176626, 18549497, 15302069},
+            {-32658337, -6171222, -7672793, -11051681, 6258878, 13504381,
+             10458790, -6418461, -8872242, 8424746},
+            {24687205, 8613276, -30667046, -3233545, 1863892, -1830544,
+             19206234, 7134917, -11284482, -828919},
+        },
+        {
+            {11334899, -9218022, 8025293, 12707519, 17523892, -10476071,
+             10243738, -14685461, -5066034, 16498837},
+            {8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925,
+             -14124238, 6536641, 10543906},
+            {-28946384, 15479763, -17466835, 568876, -1497683, 11223454,
+             -2669190, -16625574, -27235709, 8876771},
+        },
+        {
+            {-25742899, -12566864, -15649966, -846607, -33026686, -796288,
+             -33481822, 15824474, -604426, -9039817},
+            {10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697,
+             -4890037, 1657394, 3084098},
+            {10477963, -7470260, 12119566, -13250805, 29016247, -5365589,
+             31280319, 14396151, -30233575, 15272409},
+        },
+        {
+            {-12288309, 3169463, 28813183, 16658753, 25116432, -5630466,
+             -25173957, -12636138, -25014757, 1950504},
+            {-26180358, 9489187, 11053416, -14746161, -31053720, 5825630,
+             -8384306, -8767532, 15341279, 8373727},
+            {28685821, 7759505, -14378516, -12002860, -31971820, 4079242,
+             298136, -10232602, -2878207, 15190420},
+        },
+        {
+            {-32932876, 13806336, -14337485, -15794431, -24004620, 10940928,
+             8669718, 2742393, -26033313, -6875003},
+            {-1580388, -11729417, -25979658, -11445023, -17411874, -10912854,
+             9291594, -16247779, -12154742, 6048605},
+            {-30305315, 14843444, 1539301, 11864366, 20201677, 1900163,
+             13934231, 5128323, 11213262, 9168384},
+        },
+        {
+            {-26280513, 11007847, 19408960, -940758, -18592965, -4328580,
+             -5088060, -11105150, 20470157, -16398701},
+            {-23136053, 9282192, 14855179, -15390078, -7362815, -14408560,
+             -22783952, 14461608, 14042978, 5230683},
+            {29969567, -2741594, -16711867, -8552442, 9175486, -2468974,
+             21556951, 3506042, -5933891, -12449708},
+        },
+        {
+            {-3144746, 8744661, 19704003, 4581278, -20430686, 6830683,
+             -21284170, 8971513, -28539189, 15326563},
+            {-19464629, 10110288, -17262528, -3503892, -23500387, 1355669,
+             -15523050, 15300988, -20514118, 9168260},
+            {-5353335, 4488613, -23803248, 16314347, 7780487, -15638939,
+             -28948358, 9601605, 33087103, -9011387},
+        },
+        {
+            {-19443170, -15512900, -20797467, -12445323, -29824447, 10229461,
+             -27444329, -15000531, -5996870, 15664672},
+            {23294591, -16632613, -22650781, -8470978, 27844204, 11461195,
+             13099750, -2460356, 18151676, 13417686},
+            {-24722913, -4176517, -31150679, 5988919, -26858785, 6685065,
+             1661597, -12551441, 15271676, -15452665},
+        },
+    },
+    {
+        {
+            {11433042, -13228665, 8239631, -5279517, -1985436, -725718,
+             -18698764, 2167544, -6921301, -13440182},
+            {-31436171, 15575146, 30436815, 12192228, -22463353, 9395379,
+             -9917708, -8638997, 12215110, 12028277},
+            {14098400, 6555944, 23007258, 5757252, -15427832, -12950502,
+             30123440, 4617780, -16900089, -655628},
+        },
+        {
+            {-4026201, -15240835, 11893168, 13718664, -14809462, 1847385,
+             -15819999, 10154009, 23973261, -12684474},
+            {-26531820, -3695990, -1908898, 2534301, -31870557, -16550355,
+             18341390, -11419951, 32013174, -10103539},
+            {-25479301, 10876443, -11771086, -14625140, -12369567, 1838104,
+             21911214, 6354752, 4425632, -837822},
+        },
+        {
+            {-10433389, -14612966, 22229858, -3091047, -13191166, 776729,
+             -17415375, -12020462, 4725005, 14044970},
+            {19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390,
+             -1411784, -19522291, -16109756},
+            {-24864089, 12986008, -10898878, -5558584, -11312371, -148526,
+             19541418, 8180106, 9282262, 10282508},
+        },
+        {
+            {-26205082, 4428547, -8661196, -13194263, 4098402, -14165257,
+             15522535, 8372215, 5542595, -10702683},
+            {-10562541, 14895633, 26814552, -16673850, -17480754, -2489360,
+             -2781891, 6993761, -18093885, 10114655},
+            {-20107055, -929418, 31422704, 10427861, -7110749, 6150669,
+             -29091755, -11529146, 25953725, -106158},
+        },
+        {
+            {-4234397, -8039292, -9119125, 3046000, 2101609, -12607294,
+             19390020, 6094296, -3315279, 12831125},
+            {-15998678, 7578152, 5310217, 14408357, -33548620, -224739,
+             31575954, 6326196, 7381791, -2421839},
+            {-20902779, 3296811, 24736065, -16328389, 18374254, 7318640,
+             6295303, 8082724, -15362489, 12339664},
+        },
+        {
+            {27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414,
+             15768922, 25091167, 14856294},
+            {-18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300,
+             -12695493, -22182473, -9012899},
+            {-11423429, -5421590, 11632845, 3405020, 30536730, -11674039,
+             -27260765, 13866390, 30146206, 9142070},
+        },
+        {
+            {3924129, -15307516, -13817122, -10054960, 12291820, -668366,
+             -27702774, 9326384, -8237858, 4171294},
+            {-15921940, 16037937, 6713787, 16606682, -21612135, 2790944,
+             26396185, 3731949, 345228, -5462949},
+            {-21327538, 13448259, 25284571, 1143661, 20614966, -8849387,
+             2031539, -12391231, -16253183, -13582083},
+        },
+        {
+            {31016211, -16722429, 26371392, -14451233, -5027349, 14854137,
+             17477601, 3842657, 28012650, -16405420},
+            {-5075835, 9368966, -8562079, -4600902, -15249953, 6970560,
+             -9189873, 16292057, -8867157, 3507940},
+            {29439664, 3537914, 23333589, 6997794, -17555561, -11018068,
+             -15209202, -15051267, -9164929, 6580396},
+        },
+    },
+    {
+        {
+            {-12185861, -7679788, 16438269, 10826160, -8696817, -6235611,
+             17860444, -9273846, -2095802, 9304567},
+            {20714564, -4336911, 29088195, 7406487, 11426967, -5095705,
+             14792667, -14608617, 5289421, -477127},
+            {-16665533, -10650790, -6160345, -13305760, 9192020, -1802462,
+             17271490, 12349094, 26939669, -3752294},
+        },
+        {
+            {-12889898, 9373458, 31595848, 16374215, 21471720, 13221525,
+             -27283495, -12348559, -3698806, 117887},
+            {22263325, -6560050, 3984570, -11174646, -15114008, -566785,
+             28311253, 5358056, -23319780, 541964},
+            {16259219, 3261970, 2309254, -15534474, -16885711, -4581916,
+             24134070, -16705829, -13337066, -13552195},
+        },
+        {
+            {9378160, -13140186, -22845982, -12745264, 28198281, -7244098,
+             -2399684, -717351, 690426, 14876244},
+            {24977353, -314384, -8223969, -13465086, 28432343, -1176353,
+             -13068804, -12297348, -22380984, 6618999},
+            {-1538174, 11685646, 12944378, 13682314, -24389511, -14413193,
+             8044829, -13817328, 32239829, -5652762},
+        },
+        {
+            {-18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647,
+             -10350059, 32779359, 5095274},
+            {-33008130, -5214506, -32264887, -3685216, 9460461, -9327423,
+             -24601656, 14506724, 21639561, -2630236},
+            {-16400943, -13112215, 25239338, 15531969, 3987758, -4499318,
+             -1289502, -6863535, 17874574, 558605},
+        },
+        {
+            {-13600129, 10240081, 9171883, 16131053, -20869254, 9599700,
+             33499487, 5080151, 2085892, 5119761},
+            {-22205145, -2519528, -16381601, 414691, -25019550, 2170430,
+             30634760, -8363614, -31999993, -5759884},
+            {-6845704, 15791202, 8550074, -1312654, 29928809, -12092256,
+             27534430, -7192145, -22351378, 12961482},
+        },
+        {
+            {-24492060, -9570771, 10368194, 11582341, -23397293, -2245287,
+             16533930, 8206996, -30194652, -5159638},
+            {-11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630,
+             7031275, 7589640, 8945490},
+            {-32152748, 8917967, 6661220, -11677616, -1192060, -15793393,
+             7251489, -11182180, 24099109, -14456170},
+        },
+        {
+            {5019558, -7907470, 4244127, -14714356, -26933272, 6453165,
+             -19118182, -13289025, -6231896, -10280736},
+            {10853594, 10721687, 26480089, 5861829, -22995819, 1972175,
+             -1866647, -10557898, -3363451, -6441124},
+            {-17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661,
+             -2008168, -13866408, 7421392},
+        },
+        {
+            {8139927, -6546497, 32257646, -5890546, 30375719, 1886181,
+             -21175108, 15441252, 28826358, -4123029},
+            {6267086, 9695052, 7709135, -16603597, -32869068, -1886135,
+             14795160, -7840124, 13746021, -1742048},
+            {28584902, 7787108, -6732942, -15050729, 22846041, -7571236,
+             -3181936, -363524, 4771362, -8419958},
+        },
+    },
+    {
+        {
+            {24949256, 6376279, -27466481, -8174608, -18646154, -9930606,
+             33543569, -12141695, 3569627, 11342593},
+            {26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886,
+             4608608, 7325975, -14801071},
+            {-11618399, -14554430, -24321212, 7655128, -1369274, 5214312,
+             -27400540, 10258390, -17646694, -8186692},
+        },
+        {
+            {11431204, 15823007, 26570245, 14329124, 18029990, 4796082,
+             -31446179, 15580664, 9280358, -3973687},
+            {-160783, -10326257, -22855316, -4304997, -20861367, -13621002,
+             -32810901, -11181622, -15545091, 4387441},
+            {-20799378, 12194512, 3937617, -5805892, -27154820, 9340370,
+             -24513992, 8548137, 20617071, -7482001},
+        },
+        {
+            {-938825, -3930586, -8714311, 16124718, 24603125, -6225393,
+             -13775352, -11875822, 24345683, 10325460},
+            {-19855277, -1568885, -22202708, 8714034, 14007766, 6928528,
+             16318175, -1010689, 4766743, 3552007},
+            {-21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514,
+             14481909, 10988822, -3994762},
+        },
+        {
+            {15564307, -14311570, 3101243, 5684148, 30446780, -8051356,
+             12677127, -6505343, -8295852, 13296005},
+            {-9442290, 6624296, -30298964, -11913677, -4670981, -2057379,
+             31521204, 9614054, -30000824, 12074674},
+            {4771191, -135239, 14290749, -13089852, 27992298, 14998318,
+             -1413936, -1556716, 29832613, -16391035},
+        },
+        {
+            {7064884, -7541174, -19161962, -5067537, -18891269, -2912736,
+             25825242, 5293297, -27122660, 13101590},
+            {-2298563, 2439670, -7466610, 1719965, -27267541, -16328445,
+             32512469, -5317593, -30356070, -4190957},
+            {-30006540, 10162316, -33180176, 3981723, -16482138, -13070044,
+             14413974, 9515896, 19568978, 9628812},
+        },
+        {
+            {33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894,
+             -6106839, -6291786, 3437740},
+            {-18978877, 3884493, 19469877, 12726490, 15913552, 13614290,
+             -22961733, 70104, 7463304, 4176122},
+            {-27124001, 10659917, 11482427, -16070381, 12771467, -6635117,
+             -32719404, -5322751, 24216882, 5944158},
+        },
+        {
+            {8894125, 7450974, -2664149, -9765752, -28080517, -12389115,
+             19345746, 14680796, 11632993, 5847885},
+            {26942781, -2315317, 9129564, -4906607, 26024105, 11769399,
+             -11518837, 6367194, -9727230, 4782140},
+            {19916461, -4828410, -22910704, -11414391, 25606324, -5972441,
+             33253853, 8220911, 6358847, -1873857},
+        },
+        {
+            {801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388,
+             -4480480, -13538503, 1387155},
+            {19646058, 5720633, -11416706, 12814209, 11607948, 12749789,
+             14147075, 15156355, -21866831, 11835260},
+            {19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523,
+             15467869, -26560550, 5052483},
+        },
+    },
+    {
+        {
+            {-3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123,
+             -12618185, 12228557, -7003677},
+            {32944382, 14922211, -22844894, 5188528, 21913450, -8719943,
+             4001465, 13238564, -6114803, 8653815},
+            {22865569, -4652735, 27603668, -12545395, 14348958, 8234005,
+             24808405, 5719875, 28483275, 2841751},
+        },
+        {
+            {-16420968, -1113305, -327719, -12107856, 21886282, -15552774,
+             -1887966, -315658, 19932058, -12739203},
+            {-11656086, 10087521, -8864888, -5536143, -19278573, -3055912,
+             3999228, 13239134, -4777469, -13910208},
+            {1382174, -11694719, 17266790, 9194690, -13324356, 9720081,
+             20403944, 11284705, -14013818, 3093230},
+        },
+        {
+            {16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424,
+             16271225, -24049421, -6691850},
+            {-21911077, -5927941, -4611316, -5560156, -31744103, -10785293,
+             24123614, 15193618, -21652117, -16739389},
+            {-9935934, -4289447, -25279823, 4372842, 2087473, 10399484,
+             31870908, 14690798, 17361620, 11864968},
+        },
+        {
+            {-11307610, 6210372, 13206574, 5806320, -29017692, -13967200,
+             -12331205, -7486601, -25578460, -16240689},
+            {14668462, -12270235, 26039039, 15305210, 25515617, 4542480,
+             10453892, 6577524, 9145645, -6443880},
+            {5974874, 3053895, -9433049, -10385191, -31865124, 3225009,
+             -7972642, 3936128, -5652273, -3050304},
+        },
+        {
+            {30625386, -4729400, -25555961, -12792866, -20484575, 7695099,
+             17097188, -16303496, -27999779, 1803632},
+            {-3553091, 9865099, -5228566, 4272701, -5673832, -16689700,
+             14911344, 12196514, -21405489, 7047412},
+            {20093277, 9920966, -11138194, -5343857, 13161587, 12044805,
+             -32856851, 4124601, -32343828, -10257566},
+        },
+        {
+            {-20788824, 14084654, -13531713, 7842147, 19119038, -13822605,
+             4752377, -8714640, -21679658, 2288038},
+            {-26819236, -3283715, 29965059, 3039786, -14473765, 2540457,
+             29457502, 14625692, -24819617, 12570232},
+            {-1063558, -11551823, 16920318, 12494842, 1278292, -5869109,
+             -21159943, -3498680, -11974704, 4724943},
+        },
+        {
+            {17960970, -11775534, -4140968, -9702530, -8876562, -1410617,
+             -12907383, -8659932, -29576300, 1903856},
+            {23134274, -14279132, -10681997, -1611936, 20684485, 15770816,
+             -12989750, 3190296, 26955097, 14109738},
+            {15308788, 5320727, -30113809, -14318877, 22902008, 7767164,
+             29425325, -11277562, 31960942, 11934971},
+        },
+        {
+            {-27395711, 8435796, 4109644, 12222639, -24627868, 14818669,
+             20638173, 4875028, 10491392, 1379718},
+            {-13159415, 9197841, 3875503, -8936108, -1383712, -5879801,
+             33518459, 16176658, 21432314, 12180697},
+            {-11787308, 11500838, 13787581, -13832590, -22430679, 10140205,
+             1465425, 12689540, -10301319, -13872883},
+        },
+    },
+    {
+        {
+            {5414091, -15386041, -21007664, 9643570, 12834970, 1186149,
+             -2622916, -1342231, 26128231, 6032912},
+            {-26337395, -13766162, 32496025, -13653919, 17847801, -12669156,
+             3604025, 8316894, -25875034, -10437358},
+            {3296484, 6223048, 24680646, -12246460, -23052020, 5903205,
+             -8862297, -4639164, 12376617, 3188849},
+        },
+        {
+            {29190488, -14659046, 27549113, -1183516, 3520066, -10697301,
+             32049515, -7309113, -16109234, -9852307},
+            {-14744486, -9309156, 735818, -598978, -20407687, -5057904,
+             25246078, -15795669, 18640741, -960977},
+            {-6928835, -16430795, 10361374, 5642961, 4910474, 12345252,
+             -31638386, -494430, 10530747, 1053335},
+        },
+        {
+            {-29265967, -14186805, -13538216, -12117373, -19457059, -10655384,
+             -31462369, -2948985, 24018831, 15026644},
+            {-22592535, -3145277, -2289276, 5953843, -13440189, 9425631,
+             25310643, 13003497, -2314791, -15145616},
+            {-27419985, -603321, -8043984, -1669117, -26092265, 13987819,
+             -27297622, 187899, -23166419, -2531735},
+        },
+        {
+            {-21744398, -13810475, 1844840, 5021428, -10434399, -15911473,
+             9716667, 16266922, -5070217, 726099},
+            {29370922, -6053998, 7334071, -15342259, 9385287, 2247707,
+             -13661962, -4839461, 30007388, -15823341},
+            {-936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109,
+             730663, 9835848, 4555336},
+        },
+        {
+            {-23376435, 1410446, -22253753, -12899614, 30867635, 15826977,
+             17693930, 544696, -11985298, 12422646},
+            {31117226, -12215734, -13502838, 6561947, -9876867, -12757670,
+             -5118685, -4096706, 29120153, 13924425},
+            {-17400879, -14233209, 19675799, -2734756, -11006962, -5858820,
+             -9383939, -11317700, 7240931, -237388},
+        },
+        {
+            {-31361739, -11346780, -15007447, -5856218, -22453340, -12152771,
+             1222336, 4389483, 3293637, -15551743},
+            {-16684801, -14444245, 11038544, 11054958, -13801175, -3338533,
+             -24319580, 7733547, 12796905, -6335822},
+            {-8759414, -10817836, -25418864, 10783769, -30615557, -9746811,
+             -28253339, 3647836, 3222231, -11160462},
+        },
+        {
+            {18606113, 1693100, -25448386, -15170272, 4112353, 10045021,
+             23603893, -2048234, -7550776, 2484985},
+            {9255317, -3131197, -12156162, -1004256, 13098013, -9214866,
+             16377220, -2102812, -19802075, -3034702},
+            {-22729289, 7496160, -5742199, 11329249, 19991973, -3347502,
+             -31718148, 9936966, -30097688, -10618797},
+        },
+        {
+            {21878590, -5001297, 4338336, 13643897, -3036865, 13160960,
+             19708896, 5415497, -7360503, -4109293},
+            {27736861, 10103576, 12500508, 8502413, -3413016, -9633558,
+             10436918, -1550276, -23659143, -8132100},
+            {19492550, -12104365, -29681976, -852630, -3208171, 12403437,
+             30066266, 8367329, 13243957, 8709688},
+        },
+    },
+    {
+        {
+            {12015105, 2801261, 28198131, 10151021, 24818120, -4743133,
+             -11194191, -5645734, 5150968, 7274186},
+            {2831366, -12492146, 1478975, 6122054, 23825128, -12733586,
+             31097299, 6083058, 31021603, -9793610},
+            {-2529932, -2229646, 445613, 10720828, -13849527, -11505937,
+             -23507731, 16354465, 15067285, -14147707},
+        },
+        {
+            {7840942, 14037873, -33364863, 15934016, -728213, -3642706,
+             21403988, 1057586, -19379462, -12403220},
+            {915865, -16469274, 15608285, -8789130, -24357026, 6060030,
+             -17371319, 8410997, -7220461, 16527025},
+            {32922597, -556987, 20336074, -16184568, 10903705, -5384487,
+             16957574, 52992, 23834301, 6588044},
+        },
+        {
+            {32752030, 11232950, 3381995, -8714866, 22652988, -10744103,
+             17159699, 16689107, -20314580, -1305992},
+            {-4689649, 9166776, -25710296, -10847306, 11576752, 12733943,
+             7924251, -2752281, 1976123, -7249027},
+            {21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041,
+             -3371252, 12331345, -8237197},
+        },
+        {
+            {8651614, -4477032, -16085636, -4996994, 13002507, 2950805,
+             29054427, -5106970, 10008136, -4667901},
+            {31486080, 15114593, -14261250, 12951354, 14369431, -7387845,
+             16347321, -13662089, 8684155, -10532952},
+            {19443825, 11385320, 24468943, -9659068, -23919258, 2187569,
+             -26263207, -6086921, 31316348, 14219878},
+        },
+        {
+            {-28594490, 1193785, 32245219, 11392485, 31092169, 15722801,
+             27146014, 6992409, 29126555, 9207390},
+            {32382935, 1110093, 18477781, 11028262, -27411763, -7548111,
+             -4980517, 10843782, -7957600, -14435730},
+            {2814918, 7836403, 27519878, -7868156, -20894015, -11553689,
+             -21494559, 8550130, 28346258, 1994730},
+        },
+        {
+            {-19578299, 8085545, -14000519, -3948622, 2785838, -16231307,
+             -19516951, 7174894, 22628102, 8115180},
+            {-30405132, 955511, -11133838, -15078069, -32447087, -13278079,
+             -25651578, 3317160, -9943017, 930272},
+            {-15303681, -6833769, 28856490, 1357446, 23421993, 1057177,
+             24091212, -1388970, -22765376, -10650715},
+        },
+        {
+            {-22751231, -5303997, -12907607, -12768866, -15811511, -7797053,
+             -14839018, -16554220, -1867018, 8398970},
+            {-31969310, 2106403, -4736360, 1362501, 12813763, 16200670,
+             22981545, -6291273, 18009408, -15772772},
+            {-17220923, -9545221, -27784654, 14166835, 29815394, 7444469,
+             29551787, -3727419, 19288549, 1325865},
+        },
+        {
+            {15100157, -15835752, -23923978, -1005098, -26450192, 15509408,
+             12376730, -3479146, 33166107, -8042750},
+            {20909231, 13023121, -9209752, 16251778, -5778415, -8094914,
+             12412151, 10018715, 2213263, -13878373},
+            {32529814, -11074689, 30361439, -16689753, -9135940, 1513226,
+             22922121, 6382134, -5766928, 8371348},
+        },
+    },
+    {
+        {
+            {9923462, 11271500, 12616794, 3544722, -29998368, -1721626,
+             12891687, -8193132, -26442943, 10486144},
+            {-22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726,
+             2610596, -23921530, -11455195},
+            {5408411, -1136691, -4969122, 10561668, 24145918, 14240566,
+             31319731, -4235541, 19985175, -3436086},
+        },
+        {
+            {-13994457, 16616821, 14549246, 3341099, 32155958, 13648976,
+             -17577068, 8849297, 65030, 8370684},
+            {-8320926, -12049626, 31204563, 5839400, -20627288, -1057277,
+             -19442942, 6922164, 12743482, -9800518},
+            {-2361371, 12678785, 28815050, 4759974, -23893047, 4884717,
+             23783145, 11038569, 18800704, 255233},
+        },
+        {
+            {-5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847,
+             9066957, 19258688, -14753793},
+            {-2936654, -10827535, -10432089, 14516793, -3640786, 4372541,
+             -31934921, 2209390, -1524053, 2055794},
+            {580882, 16705327, 5468415, -2683018, -30926419, -14696000,
+             -7203346, -8994389, -30021019, 7394435},
+        },
+        {
+            {23838809, 1822728, -15738443, 15242727, 8318092, -3733104,
+             -21672180, -3492205, -4821741, 14799921},
+            {13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804,
+             13496856, -9056018, 7402518},
+            {2286874, -4435931, -20042458, -2008336, -13696227, 5038122,
+             11006906, -15760352, 8205061, 1607563},
+        },
+        {
+            {14414086, -8002132, 3331830, -3208217, 22249151, -5594188,
+             18364661, -2906958, 30019587, -9029278},
+            {-27688051, 1585953, -10775053, 931069, -29120221, -11002319,
+             -14410829, 12029093, 9944378, 8024},
+            {4368715, -3709630, 29874200, -15022983, -20230386, -11410704,
+             -16114594, -999085, -8142388, 5640030},
+        },
+        {
+            {10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887,
+             -16694564, 15219798, -14327783},
+            {27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605,
+             -1173195, -18342183, 9742717},
+            {6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614,
+             7406442, 12420155, 1994844},
+        },
+        {
+            {14012521, -5024720, -18384453, -9578469, -26485342, -3936439,
+             -13033478, -10909803, 24319929, -6446333},
+            {16412690, -4507367, 10772641, 15929391, -17068788, -4658621,
+             10555945, -10484049, -30102368, -4739048},
+            {22397382, -7767684, -9293161, -12792868, 17166287, -9755136,
+             -27333065, 6199366, 21880021, -12250760},
+        },
+        {
+            {-4283307, 5368523, -31117018, 8163389, -30323063, 3209128,
+             16557151, 8890729, 8840445, 4957760},
+            {-15447727, 709327, -6919446, -10870178, -29777922, 6522332,
+             -21720181, 12130072, -14796503, 5005757},
+            {-2114751, -14308128, 23019042, 15765735, -25269683, 6002752,
+             10183197, -13239326, -16395286, -2176112},
+        },
+    },
+    {
+        {
+            {-19025756, 1632005, 13466291, -7995100, -23640451, 16573537,
+             -32013908, -3057104, 22208662, 2000468},
+            {3065073, -1412761, -25598674, -361432, -17683065, -5703415,
+             -8164212, 11248527, -3691214, -7414184},
+            {10379208, -6045554, 8877319, 1473647, -29291284, -12507580,
+             16690915, 2553332, -3132688, 16400289},
+        },
+        {
+            {15716668, 1254266, -18472690, 7446274, -8448918, 6344164,
+             -22097271, -7285580, 26894937, 9132066},
+            {24158887, 12938817, 11085297, -8177598, -28063478, -4457083,
+             -30576463, 64452, -6817084, -2692882},
+            {13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710,
+             -3418511, -4688006, 2364226},
+        },
+        {
+            {16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024,
+             -11697457, 15445875, -7798101},
+            {29004207, -7867081, 28661402, -640412, -12794003, -7943086,
+             31863255, -4135540, -278050, -15759279},
+            {-6122061, -14866665, -28614905, 14569919, -10857999, -3591829,
+             10343412, -6976290, -29828287, -10815811},
+        },
+        {
+            {27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636,
+             15372179, 17293797, 960709},
+            {20263915, 11434237, -5765435, 11236810, 13505955, -10857102,
+             -16111345, 6493122, -19384511, 7639714},
+            {-2830798, -14839232, 25403038, -8215196, -8317012, -16173699,
+             18006287, -16043750, 29994677, -15808121},
+        },
+        {
+            {9769828, 5202651, -24157398, -13631392, -28051003, -11561624,
+             -24613141, -13860782, -31184575, 709464},
+            {12286395, 13076066, -21775189, -1176622, -25003198, 4057652,
+             -32018128, -8890874, 16102007, 13205847},
+            {13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170,
+             8525972, 10151379, 10394400},
+        },
+        {
+            {4024660, -16137551, 22436262, 12276534, -9099015, -2686099,
+             19698229, 11743039, -33302334, 8934414},
+            {-15879800, -4525240, -8580747, -2934061, 14634845, -698278,
+             -9449077, 3137094, -11536886, 11721158},
+            {17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229,
+             8835153, -9205489, -1280045},
+        },
+        {
+            {-461409, -7830014, 20614118, 16688288, -7514766, -4807119,
+             22300304, 505429, 6108462, -6183415},
+            {-5070281, 12367917, -30663534, 3234473, 32617080, -8422642,
+             29880583, -13483331, -26898490, -7867459},
+            {-31975283, 5726539, 26934134, 10237677, -3173717, -605053,
+             24199304, 3795095, 7592688, -14992079},
+        },
+        {
+            {21594432, -14964228, 17466408, -4077222, 32537084, 2739898,
+             6407723, 12018833, -28256052, 4298412},
+            {-20650503, -11961496, -27236275, 570498, 3767144, -1717540,
+             13891942, -1569194, 13717174, 10805743},
+            {-14676630, -15644296, 15287174, 11927123, 24177847, -8175568,
+             -796431, 14860609, -26938930, -5863836},
+        },
+    },
+    {
+        {
+            {12962541, 5311799, -10060768, 11658280, 18855286, -7954201,
+             13286263, -12808704, -4381056, 9882022},
+            {18512079, 11319350, -20123124, 15090309, 18818594, 5271736,
+             -22727904, 3666879, -23967430, -3299429},
+            {-6789020, -3146043, 16192429, 13241070, 15898607, -14206114,
+             -10084880, -6661110, -2403099, 5276065},
+        },
+        {
+            {30169808, -5317648, 26306206, -11750859, 27814964, 7069267,
+             7152851, 3684982, 1449224, 13082861},
+            {10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382,
+             15056736, -21016438, -8202000},
+            {-33150110, 3261608, 22745853, 7948688, 19370557, -15177665,
+             -26171976, 6482814, -10300080, -11060101},
+        },
+        {
+            {32869458, -5408545, 25609743, 15678670, -10687769, -15471071,
+             26112421, 2521008, -22664288, 6904815},
+            {29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737,
+             3841096, -29003639, -6657642},
+            {10340844, -6630377, -18656632, -2278430, 12621151, -13339055,
+             30878497, -11824370, -25584551, 5181966},
+        },
+        {
+            {25940115, -12658025, 17324188, -10307374, -8671468, 15029094,
+             24396252, -16450922, -2322852, -12388574},
+            {-21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390,
+             12641087, 20603771, -6561742},
+            {-18882287, -11673380, 24849422, 11501709, 13161720, -4768874,
+             1925523, 11914390, 4662781, 7820689},
+        },
+        {
+            {12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456,
+             12172924, 16136752, 15264020},
+            {-10349955, -14680563, -8211979, 2330220, -17662549, -14545780,
+             10658213, 6671822, 19012087, 3772772},
+            {3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732,
+             -15762884, 20527771, 12988982},
+        },
+        {
+            {-14822485, -5797269, -3707987, 12689773, -898983, -10914866,
+             -24183046, -10564943, 3299665, -12424953},
+            {-16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197,
+             6461331, -25583147, 8991218},
+            {-17226263, 1816362, -1673288, -6086439, 31783888, -8175991,
+             -32948145, 7417950, -30242287, 1507265},
+        },
+        {
+            {29692663, 6829891, -10498800, 4334896, 20945975, -11906496,
+             -28887608, 8209391, 14606362, -10647073},
+            {-3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695,
+             9761487, 4170404, -2085325},
+            {-11587470, 14855945, -4127778, -1531857, -26649089, 15084046,
+             22186522, 16002000, -14276837, -8400798},
+        },
+        {
+            {-4811456, 13761029, -31703877, -2483919, -3312471, 7869047,
+             -7113572, -9620092, 13240845, 10965870},
+            {-7742563, -8256762, -14768334, -13656260, -23232383, 12387166,
+             4498947, 14147411, 29514390, 4302863},
+            {-13413405, -12407859, 20757302, -13801832, 14785143, 8976368,
+             -5061276, -2144373, 17846988, -13971927},
+        },
+    },
+    {
+        {
+            {-2244452, -754728, -4597030, -1066309, -6247172, 1455299,
+             -21647728, -9214789, -5222701, 12650267},
+            {-9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813,
+             13770293, -19134326, 10958663},
+            {22470984, 12369526, 23446014, -5441109, -21520802, -9698723,
+             -11772496, -11574455, -25083830, 4271862},
+        },
+        {
+            {-25169565, -10053642, -19909332, 15361595, -5984358, 2159192,
+             75375, -4278529, -32526221, 8469673},
+            {15854970, 4148314, -8893890, 7259002, 11666551, 13824734,
+             -30531198, 2697372, 24154791, -9460943},
+            {15446137, -15806644, 29759747, 14019369, 30811221, -9610191,
+             -31582008, 12840104, 24913809, 9815020},
+        },
+        {
+            {-4709286, -5614269, -31841498, -12288893, -14443537, 10799414,
+             -9103676, 13438769, 18735128, 9466238},
+            {11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821,
+             -10896103, -22728655, 16199064},
+            {14576810, 379472, -26786533, -8317236, -29426508, -10812974,
+             -102766, 1876699, 30801119, 2164795},
+        },
+        {
+            {15995086, 3199873, 13672555, 13712240, -19378835, -4647646,
+             -13081610, -15496269, -13492807, 1268052},
+            {-10290614, -3659039, -3286592, 10948818, 23037027, 3794475,
+             -3470338, -12600221, -17055369, 3565904},
+            {29210088, -9419337, -5919792, -4952785, 10834811, -13327726,
+             -16512102, -10820713, -27162222, -14030531},
+        },
+        {
+            {-13161890, 15508588, 16663704, -8156150, -28349942, 9019123,
+             -29183421, -3769423, 2244111, -14001979},
+            {-5152875, -3800936, -9306475, -6071583, 16243069, 14684434,
+             -25673088, -16180800, 13491506, 4641841},
+            {10813417, 643330, -19188515, -728916, 30292062, -16600078,
+             27548447, -7721242, 14476989, -12767431},
+        },
+        {
+            {10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937,
+             -1644259, -27912810, 12651324},
+            {-31185513, -813383, 22271204, 11835308, 10201545, 15351028,
+             17099662, 3988035, 21721536, -3148940},
+            {10202177, -6545839, -31373232, -9574638, -32150642, -8119683,
+             -12906320, 3852694, 13216206, 14842320},
+        },
+        {
+            {-15815640, -10601066, -6538952, -7258995, -6984659, -6581778,
+             -31500847, 13765824, -27434397, 9900184},
+            {14465505, -13833331, -32133984, -14738873, -27443187, 12990492,
+             33046193, 15796406, -7051866, -8040114},
+            {30924417, -8279620, 6359016, -12816335, 16508377, 9071735,
+             -25488601, 15413635, 9524356, -7018878},
+        },
+        {
+            {12274201, -13175547, 32627641, -1785326, 6736625, 13267305,
+             5237659, -5109483, 15663516, 4035784},
+            {-2951309, 8903985, 17349946, 601635, -16432815, -4612556,
+             -13732739, -15889334, -22258478, 4659091},
+            {-16916263, -4952973, -30393711, -15158821, 20774812, 15897498,
+             5736189, 15026997, -2178256, -13455585},
+        },
+    },
+    {
+        {
+            {-8858980, -2219056, 28571666, -10155518, -474467, -10105698,
+             -3801496, 278095, 23440562, -290208},
+            {10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275,
+             11551483, -16571960, -7442864},
+            {17932739, -12437276, -24039557, 10749060, 11316803, 7535897,
+             22503767, 5561594, -3646624, 3898661},
+        },
+        {
+            {7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531,
+             7152530, 21831162, 1245233},
+            {26958459, -14658026, 4314586, 8346991, -5677764, 11960072,
+             -32589295, -620035, -30402091, -16716212},
+            {-12165896, 9166947, 33491384, 13673479, 29787085, 13096535,
+             6280834, 14587357, -22338025, 13987525},
+        },
+        {
+            {-24349909, 7778775, 21116000, 15572597, -4833266, -5357778,
+             -4300898, -5124639, -7469781, -2858068},
+            {9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781,
+             6439245, -14581012, 4091397},
+            {-8426427, 1470727, -28109679, -1596990, 3978627, -5123623,
+             -19622683, 12092163, 29077877, -14741988},
+        },
+        {
+            {5269168, -6859726, -13230211, -8020715, 25932563, 1763552,
+             -5606110, -5505881, -20017847, 2357889},
+            {32264008, -15407652, -5387735, -1160093, -2091322, -3946900,
+             23104804, -12869908, 5727338, 189038},
+            {14609123, -8954470, -6000566, -16622781, -14577387, -7743898,
+             -26745169, 10942115, -25888931, -14884697},
+        },
+        {
+            {20513500, 5557931, -15604613, 7829531, 26413943, -2019404,
+             -21378968, 7471781, 13913677, -5137875},
+            {-25574376, 11967826, 29233242, 12948236, -6754465, 4713227,
+             -8940970, 14059180, 12878652, 8511905},
+            {-25656801, 3393631, -2955415, -7075526, -2250709, 9366908,
+             -30223418, 6812974, 5568676, -3127656},
+        },
+        {
+            {11630004, 12144454, 2116339, 13606037, 27378885, 15676917,
+             -17408753, -13504373, -14395196, 8070818},
+            {27117696, -10007378, -31282771, -5570088, 1127282, 12772488,
+             -29845906, 10483306, -11552749, -1028714},
+            {10637467, -5688064, 5674781, 1072708, -26343588, -6982302,
+             -1683975, 9177853, -27493162, 15431203},
+        },
+        {
+            {20525145, 10892566, -12742472, 12779443, -29493034, 16150075,
+             -28240519, 14943142, -15056790, -7935931},
+            {-30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767,
+             -3239766, -3356550, 9594024},
+            {-23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683,
+             -6492290, 13352335, -10977084},
+        },
+        {
+            {-1931799, -5407458, 3304649, -12884869, 17015806, -4877091,
+             -29783850, -7752482, -13215537, -319204},
+            {20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742,
+             15077870, -22750759, 14523817},
+            {27406042, -6041657, 27423596, -4497394, 4996214, 10002360,
+             -28842031, -4545494, -30172742, -4805667},
+        },
+    },
+    {
+        {
+            {11374242, 12660715, 17861383, -12540833, 10935568, 1099227,
+             -13886076, -9091740, -27727044, 11358504},
+            {-12730809, 10311867, 1510375, 10778093, -2119455, -9145702,
+             32676003, 11149336, -26123651, 4985768},
+            {-19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043,
+             13794114, -19414307, -15621255},
+        },
+        {
+            {6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603,
+             6970005, -1691065, -9004790},
+            {1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622,
+             -5475723, -16796596, -5031438},
+            {-22273315, -13524424, -64685, -4334223, -18605636, -10921968,
+             -20571065, -7007978, -99853, -10237333},
+        },
+        {
+            {17747465, 10039260, 19368299, -4050591, -20630635, -16041286,
+             31992683, -15857976, -29260363, -5511971},
+            {31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999,
+             -3744247, 4882242, -10626905},
+            {29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198,
+             3272828, -5190932, -4162409},
+        },
+        {
+            {12501286, 4044383, -8612957, -13392385, -32430052, 5136599,
+             -19230378, -3529697, 330070, -3659409},
+            {6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522,
+             -8573892, -271295, 12071499},
+            {-8365515, -4042521, 25133448, -4517355, -6211027, 2265927,
+             -32769618, 1936675, -5159697, 3829363},
+        },
+        {
+            {28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550,
+             -6567787, 26333140, 14267664},
+            {-11067219, 11871231, 27385719, -10559544, -4585914, -11189312,
+             10004786, -8709488, -21761224, 8930324},
+            {-21197785, -16396035, 25654216, -1725397, 12282012, 11008919,
+             1541940, 4757911, -26491501, -16408940},
+        },
+        {
+            {13537262, -7759490, -20604840, 10961927, -5922820, -13218065,
+             -13156584, 6217254, -15943699, 13814990},
+            {-17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681,
+             9257833, -1956526, -1776914},
+            {-25045300, -10191966, 15366585, 15166509, -13105086, 8423556,
+             -29171540, 12361135, -18685978, 4578290},
+        },
+        {
+            {24579768, 3711570, 1342322, -11180126, -27005135, 14124956,
+             -22544529, 14074919, 21964432, 8235257},
+            {-6528613, -2411497, 9442966, -5925588, 12025640, -1487420,
+             -2981514, -1669206, 13006806, 2355433},
+            {-16304899, -13605259, -6632427, -5142349, 16974359, -10911083,
+             27202044, 1719366, 1141648, -12796236},
+        },
+        {
+            {-12863944, -13219986, -8318266, -11018091, -6810145, -4843894,
+             13475066, -3133972, 32674895, 13715045},
+            {11423335, -5468059, 32344216, 8962751, 24989809, 9241752,
+             -13265253, 16086212, -28740881, -15642093},
+            {-1409668, 12530728, -6368726, 10847387, 19531186, -14132160,
+             -11709148, 7791794, -27245943, 4383347},
+        },
+    },
+    {
+        {
+            {-28970898, 5271447, -1266009, -9736989, -12455236, 16732599,
+             -4862407, -4906449, 27193557, 6245191},
+            {-15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898,
+             3260492, 22510453, 8577507},
+            {-12632451, 11257346, -32692994, 13548177, -721004, 10879011,
+             31168030, 13952092, -29571492, -3635906},
+        },
+        {
+            {3877321, -9572739, 32416692, 5405324, -11004407, -13656635,
+             3759769, 11935320, 5611860, 8164018},
+            {-16275802, 14667797, 15906460, 12155291, -22111149, -9039718,
+             32003002, -8832289, 5773085, -8422109},
+            {-23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725,
+             12376320, 31632953, 190926},
+        },
+        {
+            {-24593607, -16138885, -8423991, 13378746, 14162407, 6901328,
+             -8288749, 4508564, -25341555, -3627528},
+            {8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941,
+             -14786005, -1672488, 827625},
+            {-32720583, -16289296, -32503547, 7101210, 13354605, 2659080,
+             -1800575, -14108036, -24878478, 1541286},
+        },
+        {
+            {2901347, -1117687, 3880376, -10059388, -17620940, -3612781,
+             -21802117, -3567481, 20456845, -1885033},
+            {27019610, 12299467, -13658288, -1603234, -12861660, -4861471,
+             -19540150, -5016058, 29439641, 15138866},
+            {21536104, -6626420, -32447818, -10690208, -22408077, 5175814,
+             -5420040, -16361163, 7779328, 109896},
+        },
+        {
+            {30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390,
+             12180118, 23177719, -554075},
+            {26572847, 3405927, -31701700, 12890905, -19265668, 5335866,
+             -6493768, 2378492, 4439158, -13279347},
+            {-22716706, 3489070, -9225266, -332753, 18875722, -1140095,
+             14819434, -12731527, -17717757, -5461437},
+        },
+        {
+            {-5056483, 16566551, 15953661, 3767752, -10436499, 15627060,
+             -820954, 2177225, 8550082, -15114165},
+            {-18473302, 16596775, -381660, 15663611, 22860960, 15585581,
+             -27844109, -3582739, -23260460, -8428588},
+            {-32480551, 15707275, -8205912, -5652081, 29464558, 2713815,
+             -22725137, 15860482, -21902570, 1494193},
+        },
+        {
+            {-19562091, -14087393, -25583872, -9299552, 13127842, 759709,
+             21923482, 16529112, 8742704, 12967017},
+            {-28464899, 1553205, 32536856, -10473729, -24691605, -406174,
+             -8914625, -2933896, -29903758, 15553883},
+            {21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572,
+             14513274, 19375923, -12647961},
+        },
+        {
+            {8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818,
+             -6222716, 2862653, 9455043},
+            {29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124,
+             -2990080, 15511449, 4789663},
+            {-20679756, 7004547, 8824831, -9434977, -4045704, -3750736,
+             -5754762, 108893, 23513200, 16652362},
+        },
+    },
+    {
+        {
+            {-33256173, 4144782, -4476029, -6579123, 10770039, -7155542,
+             -6650416, -12936300, -18319198, 10212860},
+            {2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801,
+             2600940, -9988298, -12506466},
+            {-24645692, 13317462, -30449259, -15653928, 21365574, -10869657,
+             11344424, 864440, -2499677, -16710063},
+        },
+        {
+            {-26432803, 6148329, -17184412, -14474154, 18782929, -275997,
+             -22561534, 211300, 2719757, 4940997},
+            {-1323882, 3911313, -6948744, 14759765, -30027150, 7851207,
+             21690126, 8518463, 26699843, 5276295},
+            {-13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586,
+             149635, -15452774, 7159369},
+        },
+        {
+            {9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009,
+             8312176, 22477218, -8403385},
+            {18155857, -16504990, 19744716, 9006923, 15154154, -10538976,
+             24256460, -4864995, -22548173, 9334109},
+            {2986088, -4911893, 10776628, -3473844, 10620590, -7083203,
+             -21413845, 14253545, -22587149, 536906},
+        },
+        {
+            {4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551,
+             10589625, 10838060, -15420424},
+            {-19342404, 867880, 9277171, -3218459, -14431572, -1986443,
+             19295826, -15796950, 6378260, 699185},
+            {7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039,
+             15693155, -5045064, -13373962},
+        },
+        {
+            {-7737563, -5869402, -14566319, -7406919, 11385654, 13201616,
+             31730678, -10962840, -3918636, -9669325},
+            {10188286, -15770834, -7336361, 13427543, 22223443, 14896287,
+             30743455, 7116568, -21786507, 5427593},
+            {696102, 13206899, 27047647, -10632082, 15285305, -9853179,
+             10798490, -4578720, 19236243, 12477404},
+        },
+        {
+            {-11229439, 11243796, -17054270, -8040865, -788228, -8167967,
+             -3897669, 11180504, -23169516, 7733644},
+            {17800790, -14036179, -27000429, -11766671, 23887827, 3149671,
+             23466177, -10538171, 10322027, 15313801},
+            {26246234, 11968874, 32263343, -5468728, 6830755, -13323031,
+             -15794704, -101982, -24449242, 10890804},
+        },
+        {
+            {-31365647, 10271363, -12660625, -6267268, 16690207, -13062544,
+             -14982212, 16484931, 25180797, -5334884},
+            {-586574, 10376444, -32586414, -11286356, 19801893, 10997610,
+             2276632, 9482883, 316878, 13820577},
+            {-9882808, -4510367, -2115506, 16457136, -11100081, 11674996,
+             30756178, -7515054, 30696930, -3712849},
+        },
+        {
+            {32988917, -9603412, 12499366, 7910787, -10617257, -11931514,
+             -7342816, -9985397, -32349517, 7392473},
+            {-8855661, 15927861, 9866406, -3649411, -2396914, -16655781,
+             -30409476, -9134995, 25112947, -2926644},
+            {-2504044, -436966, 25621774, -5678772, 15085042, -5479877,
+             -24884878, -13526194, 5537438, -13914319},
+        },
+    },
+    {
+        {
+            {-11225584, 2320285, -9584280, 10149187, -33444663, 5808648,
+             -14876251, -1729667, 31234590, 6090599},
+            {-9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721,
+             15878753, -6970405, -9034768},
+            {-27757857, 247744, -15194774, -9002551, 23288161, -10011936,
+             -23869595, 6503646, 20650474, 1804084},
+        },
+        {
+            {-27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995,
+             -10329713, 27842616, -202328},
+            {-15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656,
+             5031932, -11375082, 12714369},
+            {20807691, -7270825, 29286141, 11421711, -27876523, -13868230,
+             -21227475, 1035546, -19733229, 12796920},
+        },
+        {
+            {12076899, -14301286, -8785001, -11848922, -25012791, 16400684,
+             -17591495, -12899438, 3480665, -15182815},
+            {-32361549, 5457597, 28548107, 7833186, 7303070, -11953545,
+             -24363064, -15921875, -33374054, 2771025},
+            {-21389266, 421932, 26597266, 6860826, 22486084, -6737172,
+             -17137485, -4210226, -24552282, 15673397},
+        },
+        {
+            {-20184622, 2338216, 19788685, -9620956, -4001265, -8740893,
+             -20271184, 4733254, 3727144, -12934448},
+            {6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594,
+             7975683, 31123697, -10958981},
+            {30069250, -11435332, 30434654, 2958439, 18399564, -976289,
+             12296869, 9204260, -16432438, 9648165},
+        },
+        {
+            {32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266,
+             5248604, -26008332, -11377501},
+            {17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711,
+             15298639, 2662509, -16297073},
+            {-1172927, -7558695, -4366770, -4287744, -21346413, -8434326,
+             32087529, -1222777, 32247248, -14389861},
+        },
+        {
+            {14312628, 1221556, 17395390, -8700143, -4945741, -8684635,
+             -28197744, -9637817, -16027623, -13378845},
+            {-1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502,
+             9803137, 17597934, 2346211},
+            {18510800, 15337574, 26171504, 981392, -22241552, 7827556,
+             -23491134, -11323352, 3059833, -11782870},
+        },
+        {
+            {10141598, 6082907, 17829293, -1947643, 9830092, 13613136,
+             -25556636, -5544586, -33502212, 3592096},
+            {33114168, -15889352, -26525686, -13343397, 33076705, 8716171,
+             1151462, 1521897, -982665, -6837803},
+            {-32939165, -4255815, 23947181, -324178, -33072974, -12305637,
+             -16637686, 3891704, 26353178, 693168},
+        },
+        {
+            {30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294,
+             -400668, 31375464, 14369965},
+            {-14370654, -7772529, 1510301, 6434173, -18784789, -6262728,
+             32732230, -13108839, 17901441, 16011505},
+            {18171223, -11934626, -12500402, 15197122, -11038147, -15230035,
+             -19172240, -16046376, 8764035, 12309598},
+        },
+    },
+    {
+        {
+            {5975908, -5243188, -19459362, -9681747, -11541277, 14015782,
+             -23665757, 1228319, 17544096, -10593782},
+            {5811932, -1715293, 3442887, -2269310, -18367348, -8359541,
+             -18044043, -15410127, -5565381, 12348900},
+            {-31399660, 11407555, 25755363, 6891399, -3256938, 14872274,
+             -24849353, 8141295, -10632534, -585479},
+        },
+        {
+            {-12675304, 694026, -5076145, 13300344, 14015258, -14451394,
+             -9698672, -11329050, 30944593, 1130208},
+            {8247766, -6710942, -26562381, -7709309, -14401939, -14648910,
+             4652152, 2488540, 23550156, -271232},
+            {17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737,
+             -5908146, -408818, -137719},
+        },
+        {
+            {16091085, -16253926, 18599252, 7340678, 2137637, -1221657,
+             -3364161, 14550936, 3260525, -7166271},
+            {-4910104, -13332887, 18550887, 10864893, -16459325, -7291596,
+             -23028869, -13204905, -12748722, 2701326},
+            {-8574695, 16099415, 4629974, -16340524, -20786213, -6005432,
+             -10018363, 9276971, 11329923, 1862132},
+        },
+        {
+            {14763076, -15903608, -30918270, 3689867, 3511892, 10313526,
+             -21951088, 12219231, -9037963, -940300},
+            {8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216,
+             -2909717, -15438168, 11595570},
+            {15214962, 3537601, -26238722, -14058872, 4418657, -15230761,
+             13947276, 10730794, -13489462, -4363670},
+        },
+        {
+            {-2538306, 7682793, 32759013, 263109, -29984731, -7955452,
+             -22332124, -10188635, 977108, 699994},
+            {-12466472, 4195084, -9211532, 550904, -15565337, 12917920,
+             19118110, -439841, -30534533, -14337913},
+            {31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237,
+             -10051775, 12493932, -5409317},
+        },
+        {
+            {-25680606, 5260744, -19235809, -6284470, -3695942, 16566087,
+             27218280, 2607121, 29375955, 6024730},
+            {842132, -2794693, -4763381, -8722815, 26332018, -12405641,
+             11831880, 6985184, -9940361, 2854096},
+            {-4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645,
+             960770, 12121869, 16648078},
+        },
+        {
+            {-15218652, 14667096, -13336229, 2013717, 30598287, -464137,
+             -31504922, -7882064, 20237806, 2838411},
+            {-19288047, 4453152, 15298546, -16178388, 22115043, -15972604,
+             12544294, -13470457, 1068881, -12499905},
+            {-9558883, -16518835, 33238498, 13506958, 30505848, -1114596,
+             -8486907, -2630053, 12521378, 4845654},
+        },
+        {
+            {-28198521, 10744108, -2958380, 10199664, 7759311, -13088600,
+             3409348, -873400, -6482306, -12885870},
+            {-23561822, 6230156, -20382013, 10655314, -24040585, -11621172,
+             10477734, -1240216, -3113227, 13974498},
+            {12966261, 15550616, -32038948, -1615346, 21025980, -629444,
+             5642325, 7188737, 18895762, 12629579},
+        },
+    },
+    {
+        {
+            {14741879, -14946887, 22177208, -11721237, 1279741, 8058600,
+             11758140, 789443, 32195181, 3895677},
+            {10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575,
+             -3566119, -8982069, 4429647},
+            {-2453894, 15725973, -20436342, -10410672, -5803908, -11040220,
+             -7135870, -11642895, 18047436, -15281743},
+        },
+        {
+            {-25173001, -11307165, 29759956, 11776784, -22262383, -15820455,
+             10993114, -12850837, -17620701, -9408468},
+            {21987233, 700364, -24505048, 14972008, -7774265, -5718395,
+             32155026, 2581431, -29958985, 8773375},
+            {-25568350, 454463, -13211935, 16126715, 25240068, 8594567,
+             20656846, 12017935, -7874389, -13920155},
+        },
+        {
+            {6028182, 6263078, -31011806, -11301710, -818919, 2461772,
+             -31841174, -5468042, -1721788, -2776725},
+            {-12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845,
+             -4166698, 28408820, 6816612},
+            {-10358094, -8237829, 19549651, -12169222, 22082623, 16147817,
+             20613181, 13982702, -10339570, 5067943},
+        },
+        {
+            {-30505967, -3821767, 12074681, 13582412, -19877972, 2443951,
+             -19719286, 12746132, 5331210, -10105944},
+            {30528811, 3601899, -1957090, 4619785, -27361822, -15436388,
+             24180793, -12570394, 27679908, -1648928},
+            {9402404, -13957065, 32834043, 10838634, -26580150, -13237195,
+             26653274, -8685565, 22611444, -12715406},
+        },
+        {
+            {22190590, 1118029, 22736441, 15130463, -30460692, -5991321,
+             19189625, -4648942, 4854859, 6622139},
+            {-8310738, -2953450, -8262579, -3388049, -10401731, -271929,
+             13424426, -3567227, 26404409, 13001963},
+            {-31241838, -15415700, -2994250, 8939346, 11562230, -12840670,
+             -26064365, -11621720, -15405155, 11020693},
+        },
+        {
+            {1866042, -7949489, -7898649, -10301010, 12483315, 13477547,
+             3175636, -12424163, 28761762, 1406734},
+            {-448555, -1777666, 13018551, 3194501, -9580420, -11161737,
+             24760585, -4347088, 25577411, -13378680},
+            {-24290378, 4759345, -690653, -1852816, 2066747, 10693769,
+             -29595790, 9884936, -9368926, 4745410},
+        },
+        {
+            {-9141284, 6049714, -19531061, -4341411, -31260798, 9944276,
+             -15462008, -11311852, 10931924, -11931931},
+            {-16561513, 14112680, -8012645, 4817318, -8040464, -11414606,
+             -22853429, 10856641, -20470770, 13434654},
+            {22759489, -10073434, -16766264, -1871422, 13637442, -10168091,
+             1765144, -12654326, 28445307, -5364710},
+        },
+        {
+            {29875063, 12493613, 2795536, -3786330, 1710620, 15181182,
+             -10195717, -8788675, 9074234, 1167180},
+            {-26205683, 11014233, -9842651, -2635485, -26908120, 7532294,
+             -18716888, -9535498, 3843903, 9367684},
+            {-10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123,
+             8601684, -139197, 4242895},
+        },
+    },
+    {
+        {
+            {22092954, -13191123, -2042793, -11968512, 32186753, -11517388,
+             -6574341, 2470660, -27417366, 16625501},
+            {-11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857,
+             2602725, -27351616, 14247413},
+            {6314175, -10264892, -32772502, 15957557, -10157730, 168750,
+             -8618807, 14290061, 27108877, -1180880},
+        },
+        {
+            {-8586597, -7170966, 13241782, 10960156, -32991015, -13794596,
+             33547976, -11058889, -27148451, 981874},
+            {22833440, 9293594, -32649448, -13618667, -9136966, 14756819,
+             -22928859, -13970780, -10479804, -16197962},
+            {-7768587, 3326786, -28111797, 10783824, 19178761, 14905060,
+             22680049, 13906969, -15933690, 3797899},
+        },
+        {
+            {21721356, -4212746, -12206123, 9310182, -3882239, -13653110,
+             23740224, -2709232, 20491983, -8042152},
+            {9209270, -15135055, -13256557, -6167798, -731016, 15289673,
+             25947805, 15286587, 30997318, -6703063},
+            {7392032, 16618386, 23946583, -8039892, -13265164, -1533858,
+             -14197445, -2321576, 17649998, -250080},
+        },
+        {
+            {-9301088, -14193827, 30609526, -3049543, -25175069, -1283752,
+             -15241566, -9525724, -2233253, 7662146},
+            {-17558673, 1763594, -33114336, 15908610, -30040870, -12174295,
+             7335080, -8472199, -3174674, 3440183},
+            {-19889700, -5977008, -24111293, -9688870, 10799743, -16571957,
+             40450, -4431835, 4862400, 1133},
+        },
+        {
+            {-32856209, -7873957, -5422389, 14860950, -16319031, 7956142,
+             7258061, 311861, -30594991, -7379421},
+            {-3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763,
+             16527196, 18278453, 15405622},
+            {-4381906, 8508652, -19898366, -3674424, -5984453, 15149970,
+             -13313598, 843523, -21875062, 13626197},
+        },
+        {
+            {2281448, -13487055, -10915418, -2609910, 1879358, 16164207,
+             -10783882, 3953792, 13340839, 15928663},
+            {31727126, -7179855, -18437503, -8283652, 2875793, -16390330,
+             -25269894, -7014826, -23452306, 5964753},
+            {4100420, -5959452, -17179337, 6017714, -18705837, 12227141,
+             -26684835, 11344144, 2538215, -7570755},
+        },
+        {
+            {-9433605, 6123113, 11159803, -2156608, 30016280, 14966241,
+             -20474983, 1485421, -629256, -15958862},
+            {-26804558, 4260919, 11851389, 9658551, -32017107, 16367492,
+             -20205425, -13191288, 11659922, -11115118},
+            {26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568,
+             -10170080, 33100372, -1306171},
+        },
+        {
+            {15121113, -5201871, -10389905, 15427821, -27509937, -15992507,
+             21670947, 4486675, -5931810, -14466380},
+            {16166486, -9483733, -11104130, 6023908, -31926798, -1364923,
+             2340060, -16254968, -10735770, -10039824},
+            {28042865, -3557089, -12126526, 12259706, -3717498, -6945899,
+             6766453, -8689599, 18036436, 5803270},
+        },
+    },
+    {
+        {
+            {-817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391,
+             4598332, -6159431, -14117438},
+            {-31031306, -14256194, 17332029, -2383520, 31312682, -5967183,
+             696309, 50292, -20095739, 11763584},
+            {-594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117,
+             -12613632, -19773211, -10713562},
+        },
+        {
+            {30464590, -11262872, -4127476, -12734478, 19835327, -7105613,
+             -24396175, 2075773, -17020157, 992471},
+            {18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841,
+             8080033, -11574335, -10601610},
+            {19598397, 10334610, 12555054, 2555664, 18821899, -10339780,
+             21873263, 16014234, 26224780, 16452269},
+        },
+        {
+            {-30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804,
+             -7618186, -20533829, 3698650},
+            {14187449, 3448569, -10636236, -10810935, -22663880, -3433596,
+             7268410, -10890444, 27394301, 12015369},
+            {19695761, 16087646, 28032085, 12999827, 6817792, 11427614,
+             20244189, -1312777, -13259127, -3402461},
+        },
+        {
+            {30860103, 12735208, -1888245, -4699734, -16974906, 2256940,
+             -8166013, 12298312, -8550524, -10393462},
+            {-5719826, -11245325, -1910649, 15569035, 26642876, -7587760,
+             -5789354, -15118654, -4976164, 12651793},
+            {-2848395, 9953421, 11531313, -5282879, 26895123, -12697089,
+             -13118820, -16517902, 9768698, -2533218},
+        },
+        {
+            {-24719459, 1894651, -287698, -4704085, 15348719, -8156530,
+             32767513, 12765450, 4940095, 10678226},
+            {18860224, 15980149, -18987240, -1562570, -26233012, -11071856,
+             -7843882, 13944024, -24372348, 16582019},
+            {-15504260, 4970268, -29893044, 4175593, -20993212, -2199756,
+             -11704054, 15444560, -11003761, 7989037},
+        },
+        {
+            {31490452, 5568061, -2412803, 2182383, -32336847, 4531686,
+             -32078269, 6200206, -19686113, -14800171},
+            {-17308668, -15879940, -31522777, -2831, -32887382, 16375549,
+             8680158, -16371713, 28550068, -6857132},
+            {-28126887, -5688091, 16837845, -1820458, -6850681, 12700016,
+             -30039981, 4364038, 1155602, 5988841},
+        },
+        {
+            {21890435, -13272907, -12624011, 12154349, -7831873, 15300496,
+             23148983, -4470481, 24618407, 8283181},
+            {-33136107, -10512751, 9975416, 6841041, -31559793, 16356536,
+             3070187, -7025928, 1466169, 10740210},
+            {-1509399, -15488185, -13503385, -10655916, 32799044, 909394,
+             -13938903, -5779719, -32164649, -15327040},
+        },
+        {
+            {3960823, -14267803, -28026090, -15918051, -19404858, 13146868,
+             15567327, 951507, -3260321, -573935},
+            {24740841, 5052253, -30094131, 8961361, 25877428, 6165135,
+             -24368180, 14397372, -7380369, -6144105},
+            {-28888365, 3510803, -28103278, -1158478, -11238128, -10631454,
+             -15441463, -14453128, -1625486, -6494814},
+        },
+    },
+    {
+        {
+            {793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843,
+             -4885251, -9906200, -621852},
+            {5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374,
+             1468826, -6171428, -15186581},
+            {-4859255, -3779343, -2917758, -6748019, 7778750, 11688288,
+             -30404353, -9871238, -1558923, -9863646},
+        },
+        {
+            {10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958,
+             14783338, -30581476, -15757844},
+            {10566929, 12612572, -31944212, 11118703, -12633376, 12362879,
+             21752402, 8822496, 24003793, 14264025},
+            {27713862, -7355973, -11008240, 9227530, 27050101, 2504721,
+             23886875, -13117525, 13958495, -5732453},
+        },
+        {
+            {-23481610, 4867226, -27247128, 3900521, 29838369, -8212291,
+             -31889399, -10041781, 7340521, -15410068},
+            {4646514, -8011124, -22766023, -11532654, 23184553, 8566613,
+             31366726, -1381061, -15066784, -10375192},
+            {-17270517, 12723032, -16993061, 14878794, 21619651, -6197576,
+             27584817, 3093888, -8843694, 3849921},
+        },
+        {
+            {-9064912, 2103172, 25561640, -15125738, -5239824, 9582958,
+             32477045, -9017955, 5002294, -15550259},
+            {-12057553, -11177906, 21115585, -13365155, 8808712, -12030708,
+             16489530, 13378448, -25845716, 12741426},
+            {-5946367, 10645103, -30911586, 15390284, -3286982, -7118677,
+             24306472, 15852464, 28834118, -7646072},
+        },
+        {
+            {-17335748, -9107057, -24531279, 9434953, -8472084, -583362,
+             -13090771, 455841, 20461858, 5491305},
+            {13669248, -16095482, -12481974, -10203039, -14569770, -11893198,
+             -24995986, 11293807, -28588204, -9421832},
+            {28497928, 6272777, -33022994, 14470570, 8906179, -1225630,
+             18504674, -14165166, 29867745, -8795943},
+        },
+        {
+            {-16207023, 13517196, -27799630, -13697798, 24009064, -6373891,
+             -6367600, -13175392, 22853429, -4012011},
+            {24191378, 16712145, -13931797, 15217831, 14542237, 1646131,
+             18603514, -11037887, 12876623, -2112447},
+            {17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753,
+             608397, 16031844, 3723494},
+        },
+        {
+            {-28632773, 12763728, -20446446, 7577504, 33001348, -13017745,
+             17558842, -7872890, 23896954, -4314245},
+            {-20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064,
+             7229064, -9919646, -8826859},
+            {28816045, 298879, -28165016, -15920938, 19000928, -1665890,
+             -12680833, -2949325, -18051778, -2082915},
+        },
+        {
+            {16000882, -344896, 3493092, -11447198, -29504595, -13159789,
+             12577740, 16041268, -19715240, 7847707},
+            {10151868, 10572098, 27312476, 7922682, 14825339, 4723128,
+             -32855931, -6519018, -10020567, 3852848},
+            {-11430470, 15697596, -21121557, -4420647, 5386314, 15063598,
+             16514493, -15932110, 29330899, -15076224},
+        },
+    },
+    {
+        {
+            {-25499735, -4378794, -15222908, -6901211, 16615731, 2051784,
+             3303702, 15490, -27548796, 12314391},
+            {15683520, -6003043, 18109120, -9980648, 15337968, -5997823,
+             -16717435, 15921866, 16103996, -3731215},
+            {-23169824, -10781249, 13588192, -1628807, -3798557, -1074929,
+             -19273607, 5402699, -29815713, -9841101},
+        },
+        {
+            {23190676, 2384583, -32714340, 3462154, -29903655, -1529132,
+             -11266856, 8911517, -25205859, 2739713},
+            {21374101, -3554250, -33524649, 9874411, 15377179, 11831242,
+             -33529904, 6134907, 4931255, 11987849},
+            {-7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539,
+             13861388, -30076310, 10117930},
+        },
+        {
+            {-29501170, -10744872, -26163768, 13051539, -25625564, 5089643,
+             -6325503, 6704079, 12890019, 15728940},
+            {-21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376,
+             -10428139, 12885167, 8311031},
+            {-17516482, 5352194, 10384213, -13811658, 7506451, 13453191,
+             26423267, 4384730, 1888765, -5435404},
+        },
+        {
+            {-25817338, -3107312, -13494599, -3182506, 30896459, -13921729,
+             -32251644, -12707869, -19464434, -3340243},
+            {-23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245,
+             14845197, 17151279, -9854116},
+            {-24830458, -12733720, -15165978, 10367250, -29530908, -265356,
+             22825805, -7087279, -16866484, 16176525},
+        },
+        {
+            {-23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182,
+             -10363426, -28746253, -10197509},
+            {-10626600, -4486402, -13320562, -5125317, 3432136, -6393229,
+             23632037, -1940610, 32808310, 1099883},
+            {15030977, 5768825, -27451236, -2887299, -6427378, -15361371,
+             -15277896, -6809350, 2051441, -15225865},
+        },
+        {
+            {-3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398,
+             -14154188, -22686354, 16633660},
+            {4577086, -16752288, 13249841, -15304328, 19958763, -14537274,
+             18559670, -10759549, 8402478, -9864273},
+            {-28406330, -1051581, -26790155, -907698, -17212414, -11030789,
+             9453451, -14980072, 17983010, 9967138},
+        },
+        {
+            {-25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990,
+             7806337, 17507396, 3651560},
+            {-10420457, -4118111, 14584639, 15971087, -15768321, 8861010,
+             26556809, -5574557, -18553322, -11357135},
+            {2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121,
+             8459447, -5605463, -7621941},
+        },
+        {
+            {-4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813,
+             -849066, 17258084, -7977739},
+            {18164541, -10595176, -17154882, -1542417, 19237078, -9745295,
+             23357533, -15217008, 26908270, 12150756},
+            {-30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168,
+             -5537701, -32302074, 16215819},
+        },
+    },
+    {
+        {
+            {-6898905, 9824394, -12304779, -4401089, -31397141, -6276835,
+             32574489, 12532905, -7503072, -8675347},
+            {-27343522, -16515468, -27151524, -10722951, 946346, 16291093,
+             254968, 7168080, 21676107, -1943028},
+            {21260961, -8424752, -16831886, -11920822, -23677961, 3968121,
+             -3651949, -6215466, -3556191, -7913075},
+        },
+        {
+            {16544754, 13250366, -16804428, 15546242, -4583003, 12757258,
+             -2462308, -8680336, -18907032, -9662799},
+            {-2415239, -15577728, 18312303, 4964443, -15272530, -12653564,
+             26820651, 16690659, 25459437, -4564609},
+            {-25144690, 11425020, 28423002, -11020557, -6144921, -15826224,
+             9142795, -2391602, -6432418, -1644817},
+        },
+        {
+            {-23104652, 6253476, 16964147, -3768872, -25113972, -12296437,
+             -27457225, -16344658, 6335692, 7249989},
+            {-30333227, 13979675, 7503222, -12368314, -11956721, -4621693,
+             -30272269, 2682242, 25993170, -12478523},
+            {4364628, 5930691, 32304656, -10044554, -8054781, 15091131,
+             22857016, -10598955, 31820368, 15075278},
+        },
+        {
+            {31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788,
+             -9650886, -17970238, 12833045},
+            {19073683, 14851414, -24403169, -11860168, 7625278, 11091125,
+             -19619190, 2074449, -9413939, 14905377},
+            {24483667, -11935567, -2518866, -11547418, -1553130, 15355506,
+             -25282080, 9253129, 27628530, -7555480},
+        },
+        {
+            {17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324,
+             -9157582, -14110875, 15297016},
+            {510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417,
+             -11864220, 8683221, 2921426},
+            {18606791, 11874196, 27155355, -5281482, -24031742, 6265446,
+             -25178240, -1278924, 4674690, 13890525},
+        },
+        {
+            {13609624, 13069022, -27372361, -13055908, 24360586, 9592974,
+             14977157, 9835105, 4389687, 288396},
+            {9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062,
+             8317628, 23388070, 16052080},
+            {12720016, 11937594, -31970060, -5028689, 26900120, 8561328,
+             -20155687, -11632979, -14754271, -10812892},
+        },
+        {
+            {15961858, 14150409, 26716931, -665832, -22794328, 13603569,
+             11829573, 7467844, -28822128, 929275},
+            {11038231, -11582396, -27310482, -7316562, -10498527, -16307831,
+             -23479533, -9371869, -21393143, 2465074},
+            {20017163, -4323226, 27915242, 1529148, 12396362, 15675764,
+             13817261, -9658066, 2463391, -4622140},
+        },
+        {
+            {-16358878, -12663911, -12065183, 4996454, -1256422, 1073572,
+             9583558, 12851107, 4003896, 12673717},
+            {-1731589, -15155870, -3262930, 16143082, 19294135, 13385325,
+             14741514, -9103726, 7903886, 2348101},
+            {24536016, -16515207, 12715592, -3862155, 1511293, 10047386,
+             -3842346, -7129159, -28377538, 10048127},
+        },
+    },
+    {
+        {
+            {-12622226, -6204820, 30718825, 2591312, -10617028, 12192840,
+             18873298, -7297090, -32297756, 15221632},
+            {-26478122, -11103864, 11546244, -1852483, 9180880, 7656409,
+             -21343950, 2095755, 29769758, 6593415},
+            {-31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345,
+             -6118678, 30958054, 8292160},
+        },
+        {
+            {31429822, -13959116, 29173532, 15632448, 12174511, -2760094,
+             32808831, 3977186, 26143136, -3148876},
+            {22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633,
+             -1674433, -3758243, -2304625},
+            {-15491917, 8012313, -2514730, -12702462, -23965846, -10254029,
+             -1612713, -1535569, -16664475, 8194478},
+        },
+        {
+            {27338066, -7507420, -7414224, 10140405, -19026427, -6589889,
+             27277191, 8855376, 28572286, 3005164},
+            {26287124, 4821776, 25476601, -4145903, -3764513, -15788984,
+             -18008582, 1182479, -26094821, -13079595},
+            {-7171154, 3178080, 23970071, 6201893, -17195577, -4489192,
+             -21876275, -13982627, 32208683, -1198248},
+        },
+        {
+            {-16657702, 2817643, -10286362, 14811298, 6024667, 13349505,
+             -27315504, -10497842, -27672585, -11539858},
+            {15941029, -9405932, -21367050, 8062055, 31876073, -238629,
+             -15278393, -1444429, 15397331, -4130193},
+            {8934485, -13485467, -23286397, -13423241, -32446090, 14047986,
+             31170398, -1441021, -27505566, 15087184},
+        },
+        {
+            {-18357243, -2156491, 24524913, -16677868, 15520427, -6360776,
+             -15502406, 11461896, 16788528, -5868942},
+            {-1947386, 16013773, 21750665, 3714552, -17401782, -16055433,
+             -3770287, -10323320, 31322514, -11615635},
+            {21426655, -5650218, -13648287, -5347537, -28812189, -4920970,
+             -18275391, -14621414, 13040862, -12112948},
+        },
+        {
+            {11293895, 12478086, -27136401, 15083750, -29307421, 14748872,
+             14555558, -13417103, 1613711, 4896935},
+            {-25894883, 15323294, -8489791, -8057900, 25967126, -13425460,
+             2825960, -4897045, -23971776, -11267415},
+            {-15924766, -5229880, -17443532, 6410664, 3622847, 10243618,
+             20615400, 12405433, -23753030, -8436416},
+        },
+        {
+            {-7091295, 12556208, -20191352, 9025187, -17072479, 4333801,
+             4378436, 2432030, 23097949, -566018},
+            {4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264,
+             10103221, -18512313, 2424778},
+            {366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678,
+             1344109, -3642553, 12412659},
+        },
+        {
+            {-24001791, 7690286, 14929416, -168257, -32210835, -13412986,
+             24162697, -15326504, -3141501, 11179385},
+            {18289522, -14724954, 8056945, 16430056, -21729724, 7842514,
+             -6001441, -1486897, -18684645, -11443503},
+            {476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959,
+             13403813, 11052904, 5219329},
+        },
+    },
+    {
+        {
+            {20678546, -8375738, -32671898, 8849123, -5009758, 14574752,
+             31186971, -3973730, 9014762, -8579056},
+            {-13644050, -10350239, -15962508, 5075808, -1514661, -11534600,
+             -33102500, 9160280, 8473550, -3256838},
+            {24900749, 14435722, 17209120, -15292541, -22592275, 9878983,
+             -7689309, -16335821, -24568481, 11788948},
+        },
+        {
+            {-3118155, -11395194, -13802089, 14797441, 9652448, -6845904,
+             -20037437, 10410733, -24568470, -1458691},
+            {-15659161, 16736706, -22467150, 10215878, -9097177, 7563911,
+             11871841, -12505194, -18513325, 8464118},
+            {-23400612, 8348507, -14585951, -861714, -3950205, -6373419,
+             14325289, 8628612, 33313881, -8370517},
+        },
+        {
+            {-20186973, -4967935, 22367356, 5271547, -1097117, -4788838,
+             -24805667, -10236854, -8940735, -5818269},
+            {-6948785, -1795212, -32625683, -16021179, 32635414, -7374245,
+             15989197, -12838188, 28358192, -4253904},
+            {-23561781, -2799059, -32351682, -1661963, -9147719, 10429267,
+             -16637684, 4072016, -5351664, 5596589},
+        },
+        {
+            {-28236598, -3390048, 12312896, 6213178, 3117142, 16078565,
+             29266239, 2557221, 1768301, 15373193},
+            {-7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902,
+             -4504991, -24660491, 3442910},
+            {-30210571, 5124043, 14181784, 8197961, 18964734, -11939093,
+             22597931, 7176455, -18585478, 13365930},
+        },
+        {
+            {-7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107,
+             -8570186, -9689599, -3031667},
+            {25008904, -10771599, -4305031, -9638010, 16265036, 15721635,
+             683793, -11823784, 15723479, -15163481},
+            {-9660625, 12374379, -27006999, -7026148, -7724114, -12314514,
+             11879682, 5400171, 519526, -1235876},
+        },
+        {
+            {22258397, -16332233, -7869817, 14613016, -22520255, -2950923,
+             -20353881, 7315967, 16648397, 7605640},
+            {-8081308, -8464597, -8223311, 9719710, 19259459, -15348212,
+             23994942, -5281555, -9468848, 4763278},
+            {-21699244, 9220969, -15730624, 1084137, -25476107, -2852390,
+             31088447, -7764523, -11356529, 728112},
+        },
+        {
+            {26047220, -11751471, -6900323, -16521798, 24092068, 9158119,
+             -4273545, -12555558, -29365436, -5498272},
+            {17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007,
+             12327945, 10750447, 10014012},
+            {-10312768, 3936952, 9156313, -8897683, 16498692, -994647,
+             -27481051, -666732, 3424691, 7540221},
+        },
+        {
+            {30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422,
+             -16317219, -9244265, 15258046},
+            {13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406,
+             2711395, 1062915, -5136345},
+            {-19240248, -11254599, -29509029, -7499965, -5835763, 13005411,
+             -6066489, 12194497, 32960380, 1459310},
+        },
+    },
+    {
+        {
+            {19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197,
+             -6101885, 18638003, -11174937},
+            {31395534, 15098109, 26581030, 8030562, -16527914, -5007134,
+             9012486, -7584354, -6643087, -5442636},
+            {-9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222,
+             9677543, -32294889, -6456008},
+        },
+        {
+            {-2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579,
+             -7839692, -7852844, -8138429},
+            {-15236356, -15433509, 7766470, 746860, 26346930, -10221762,
+             -27333451, 10754588, -9431476, 5203576},
+            {31834314, 14135496, -770007, 5159118, 20917671, -16768096,
+             -7467973, -7337524, 31809243, 7347066},
+        },
+        {
+            {-9606723, -11874240, 20414459, 13033986, 13716524, -11691881,
+             19797970, -12211255, 15192876, -2087490},
+            {-12663563, -2181719, 1168162, -3804809, 26747877, -14138091,
+             10609330, 12694420, 33473243, -13382104},
+            {33184999, 11180355, 15832085, -11385430, -1633671, 225884,
+             15089336, -11023903, -6135662, 14480053},
+        },
+        {
+            {31308717, -5619998, 31030840, -1897099, 15674547, -6582883,
+             5496208, 13685227, 27595050, 8737275},
+            {-20318852, -15150239, 10933843, -16178022, 8335352, -7546022,
+             -31008351, -12610604, 26498114, 66511},
+            {22644454, -8761729, -16671776, 4884562, -3105614, -13559366,
+             30540766, -4286747, -13327787, -7515095},
+        },
+        {
+            {-28017847, 9834845, 18617207, -2681312, -3401956, -13307506,
+             8205540, 13585437, -17127465, 15115439},
+            {23711543, -672915, 31206561, -8362711, 6164647, -9709987,
+             -33535882, -1426096, 8236921, 16492939},
+            {-23910559, -13515526, -26299483, -4503841, 25005590, -7687270,
+             19574902, 10071562, 6708380, -6222424},
+        },
+        {
+            {2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017,
+             9328700, 29955601, -11678310},
+            {3096359, 9271816, -21620864, -15521844, -14847996, -7592937,
+             -25892142, -12635595, -9917575, 6216608},
+            {-32615849, 338663, -25195611, 2510422, -29213566, -13820213,
+             24822830, -6146567, -26767480, 7525079},
+        },
+        {
+            {-23066649, -13985623, 16133487, -7896178, -3389565, 778788,
+             -910336, -2782495, -19386633, 11994101},
+            {21691500, -13624626, -641331, -14367021, 3285881, -3483596,
+             -25064666, 9718258, -7477437, 13381418},
+            {18445390, -4202236, 14979846, 11622458, -1727110, -3582980,
+             23111648, -6375247, 28535282, 15779576},
+        },
+        {
+            {30098053, 3089662, -9234387, 16662135, -21306940, 11308411,
+             -14068454, 12021730, 9955285, -16303356},
+            {9734894, -14576830, -7473633, -9138735, 2060392, 11313496,
+             -18426029, 9924399, 20194861, 13380996},
+            {-26378102, -7965207, -22167821, 15789297, -18055342, -6168792,
+             -1984914, 15707771, 26342023, 10146099},
+        },
+    },
+    {
+        {
+            {-26016874, -219943, 21339191, -41388, 19745256, -2878700,
+             -29637280, 2227040, 21612326, -545728},
+            {-13077387, 1184228, 23562814, -5970442, -20351244, -6348714,
+             25764461, 12243797, -20856566, 11649658},
+            {-10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944,
+             6114064, 33514190, 2333242},
+        },
+        {
+            {-21433588, -12421821, 8119782, 7219913, -21830522, -9016134,
+             -6679750, -12670638, 24350578, -13450001},
+            {-4116307, -11271533, -23886186, 4843615, -30088339, 690623,
+             -31536088, -10406836, 8317860, 12352766},
+            {18200138, -14475911, -33087759, -2696619, -23702521, -9102511,
+             -23552096, -2287550, 20712163, 6719373},
+        },
+        {
+            {26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530,
+             -3763210, 26224235, -3297458},
+            {-17168938, -14854097, -3395676, -16369877, -19954045, 14050420,
+             21728352, 9493610, 18620611, -16428628},
+            {-13323321, 13325349, 11432106, 5964811, 18609221, 6062965,
+             -5269471, -9725556, -30701573, -16479657},
+        },
+        {
+            {-23860538, -11233159, 26961357, 1640861, -32413112, -16737940,
+             12248509, -5240639, 13735342, 1934062},
+            {25089769, 6742589, 17081145, -13406266, 21909293, -16067981,
+             -15136294, -3765346, -21277997, 5473616},
+            {31883677, -7961101, 1083432, -11572403, 22828471, 13290673,
+             -7125085, 12469656, 29111212, -5451014},
+        },
+        {
+            {24244947, -15050407, -26262976, 2791540, -14997599, 16666678,
+             24367466, 6388839, -10295587, 452383},
+            {-25640782, -3417841, 5217916, 16224624, 19987036, -4082269,
+             -24236251, -5915248, 15766062, 8407814},
+            {-20406999, 13990231, 15495425, 16395525, 5377168, 15166495,
+             -8917023, -4388953, -8067909, 2276718},
+        },
+        {
+            {30157918, 12924066, -17712050, 9245753, 19895028, 3368142,
+             -23827587, 5096219, 22740376, -7303417},
+            {2041139, -14256350, 7783687, 13876377, -25946985, -13352459,
+             24051124, 13742383, -15637599, 13295222},
+            {33338237, -8505733, 12532113, 7977527, 9106186, -1715251,
+             -17720195, -4612972, -4451357, -14669444},
+        },
+        {
+            {-20045281, 5454097, -14346548, 6447146, 28862071, 1883651,
+             -2469266, -4141880, 7770569, 9620597},
+            {23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528,
+             -1694323, -33502340, -14767970},
+            {1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801,
+             1220118, 30494170, -11440799},
+        },
+        {
+            {-5037580, -13028295, -2970559, -3061767, 15640974, -6701666,
+             -26739026, 926050, -1684339, -13333647},
+            {13908495, -3549272, 30919928, -6273825, -21521863, 7989039,
+             9021034, 9078865, 3353509, 4033511},
+            {-29663431, -15113610, 32259991, -344482, 24295849, -12912123,
+             23161163, 8839127, 27485041, 7356032},
+        },
+    },
+    {
+        {
+            {9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142,
+             2625015, 28431036, -16771834},
+            {-23839233, -8311415, -25945511, 7480958, -17681669, -8354183,
+             -22545972, 14150565, 15970762, 4099461},
+            {29262576, 16756590, 26350592, -8793563, 8529671, -11208050,
+             13617293, -9937143, 11465739, 8317062},
+        },
+        {
+            {-25493081, -6962928, 32500200, -9419051, -23038724, -2302222,
+             14898637, 3848455, 20969334, -5157516},
+            {-20384450, -14347713, -18336405, 13884722, -33039454, 2842114,
+             -21610826, -3649888, 11177095, 14989547},
+            {-24496721, -11716016, 16959896, 2278463, 12066309, 10137771,
+             13515641, 2581286, -28487508, 9930240},
+        },
+        {
+            {-17751622, -2097826, 16544300, -13009300, -15914807, -14949081,
+             18345767, -13403753, 16291481, -5314038},
+            {-33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774,
+             6957617, 4368891, 9788741},
+            {16660756, 7281060, -10830758, 12911820, 20108584, -8101676,
+             -21722536, -8613148, 16250552, -11111103},
+        },
+        {
+            {-19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584,
+             10604807, -30190403, 4782747},
+            {-1354539, 14736941, -7367442, -13292886, 7710542, -14155590,
+             -9981571, 4383045, 22546403, 437323},
+            {31665577, -12180464, -16186830, 1491339, -18368625, 3294682,
+             27343084, 2786261, -30633590, -14097016},
+        },
+        {
+            {-14467279, -683715, -33374107, 7448552, 19294360, 14334329,
+             -19690631, 2355319, -19284671, -6114373},
+            {15121312, -15796162, 6377020, -6031361, -10798111, -12957845,
+             18952177, 15496498, -29380133, 11754228},
+            {-2637277, -13483075, 8488727, -14303896, 12728761, -1622493,
+             7141596, 11724556, 22761615, -10134141},
+        },
+        {
+            {16918416, 11729663, -18083579, 3022987, -31015732, -13339659,
+             -28741185, -12227393, 32851222, 11717399},
+            {11166634, 7338049, -6722523, 4531520, -29468672, -7302055,
+             31474879, 3483633, -1193175, -4030831},
+            {-185635, 9921305, 31456609, -13536438, -12013818, 13348923,
+             33142652, 6546660, -19985279, -3948376},
+        },
+        {
+            {-32460596, 11266712, -11197107, -7899103, 31703694, 3855903,
+             -8537131, -12833048, -30772034, -15486313},
+            {-18006477, 12709068, 3991746, -6479188, -21491523, -10550425,
+             -31135347, -16049879, 10928917, 3011958},
+            {-6957757, -15594337, 31696059, 334240, 29576716, 14796075,
+             -30831056, -12805180, 18008031, 10258577},
+        },
+        {
+            {-22448644, 15655569, 7018479, -4410003, -30314266, -1201591,
+             -1853465, 1367120, 25127874, 6671743},
+            {29701166, -14373934, -10878120, 9279288, -17568, 13127210,
+             21382910, 11042292, 25838796, 4642684},
+            {-20430234, 14955537, -24126347, 8124619, -5369288, -5990470,
+             30468147, -13900640, 18423289, 4177476},
+        },
+    },
+};
+
+static uint8_t negative(signed char b) {
+  uint32_t x = b;
+  x >>= 31; /* 1: yes; 0: no */
+  return x;
+}
+
+static void table_select(ge_precomp *t, int pos, signed char b) {
+  ge_precomp minust;
+  uint8_t bnegative = negative(b);
+  uint8_t babs = b - ((uint8_t)((-bnegative) & b) << 1);
+
+  ge_precomp_0(t);
+  cmov(t, &k25519Precomp[pos][0], equal(babs, 1));
+  cmov(t, &k25519Precomp[pos][1], equal(babs, 2));
+  cmov(t, &k25519Precomp[pos][2], equal(babs, 3));
+  cmov(t, &k25519Precomp[pos][3], equal(babs, 4));
+  cmov(t, &k25519Precomp[pos][4], equal(babs, 5));
+  cmov(t, &k25519Precomp[pos][5], equal(babs, 6));
+  cmov(t, &k25519Precomp[pos][6], equal(babs, 7));
+  cmov(t, &k25519Precomp[pos][7], equal(babs, 8));
+  fe_copy(minust.yplusx, t->yminusx);
+  fe_copy(minust.yminusx, t->yplusx);
+  fe_neg(minust.xy2d, t->xy2d);
+  cmov(t, &minust, bnegative);
+}
+
+/* h = a * B
+ * where a = a[0]+256*a[1]+...+256^31 a[31]
+ * B is the Ed25519 base point (x,4/5) with x positive.
+ *
+ * Preconditions:
+ *   a[31] <= 127 */
+static void ge_scalarmult_base(ge_p3 *h, const uint8_t *a) {
+  signed char e[64];
+  signed char carry;
+  ge_p1p1 r;
+  ge_p2 s;
+  ge_precomp t;
+  int i;
+
+  for (i = 0; i < 32; ++i) {
+    e[2 * i + 0] = (a[i] >> 0) & 15;
+    e[2 * i + 1] = (a[i] >> 4) & 15;
+  }
+  /* each e[i] is between 0 and 15 */
+  /* e[63] is between 0 and 7 */
+
+  carry = 0;
+  for (i = 0; i < 63; ++i) {
+    e[i] += carry;
+    carry = e[i] + 8;
+    carry >>= 4;
+    e[i] -= carry << 4;
+  }
+  e[63] += carry;
+  /* each e[i] is between -8 and 8 */
+
+  ge_p3_0(h);
+  for (i = 1; i < 64; i += 2) {
+    table_select(&t, i / 2, e[i]);
+    ge_madd(&r, h, &t);
+    ge_p1p1_to_p3(h, &r);
+  }
+
+  ge_p3_dbl(&r, h);
+  ge_p1p1_to_p2(&s, &r);
+  ge_p2_dbl(&r, &s);
+  ge_p1p1_to_p2(&s, &r);
+  ge_p2_dbl(&r, &s);
+  ge_p1p1_to_p2(&s, &r);
+  ge_p2_dbl(&r, &s);
+  ge_p1p1_to_p3(h, &r);
+
+  for (i = 0; i < 64; i += 2) {
+    table_select(&t, i / 2, e[i]);
+    ge_madd(&r, h, &t);
+    ge_p1p1_to_p3(h, &r);
+  }
+}
+
+/* Replace (f,g) with (g,f) if b == 1;
+ * replace (f,g) with (f,g) if b == 0.
+ *
+ * Preconditions: b in {0,1}. */
+static void fe_cswap(fe f, fe g, unsigned int b) {
+  size_t i;
+  b = 0-b;
+  for (i = 0; i < 10; i++) {
+    int32_t x = f[i] ^ g[i];
+    x &= b;
+    f[i] ^= x;
+    g[i] ^= x;
+  }
+}
+
+/* h = f * 121666
+ * Can overlap h with f.
+ *
+ * Preconditions:
+ *    |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
+ *
+ * Postconditions:
+ *    |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. */
+static void fe_mul121666(fe h, fe f) {
+  int32_t f0 = f[0];
+  int32_t f1 = f[1];
+  int32_t f2 = f[2];
+  int32_t f3 = f[3];
+  int32_t f4 = f[4];
+  int32_t f5 = f[5];
+  int32_t f6 = f[6];
+  int32_t f7 = f[7];
+  int32_t f8 = f[8];
+  int32_t f9 = f[9];
+  int64_t h0 = f0 * (int64_t) 121666;
+  int64_t h1 = f1 * (int64_t) 121666;
+  int64_t h2 = f2 * (int64_t) 121666;
+  int64_t h3 = f3 * (int64_t) 121666;
+  int64_t h4 = f4 * (int64_t) 121666;
+  int64_t h5 = f5 * (int64_t) 121666;
+  int64_t h6 = f6 * (int64_t) 121666;
+  int64_t h7 = f7 * (int64_t) 121666;
+  int64_t h8 = f8 * (int64_t) 121666;
+  int64_t h9 = f9 * (int64_t) 121666;
+  int64_t carry0;
+  int64_t carry1;
+  int64_t carry2;
+  int64_t carry3;
+  int64_t carry4;
+  int64_t carry5;
+  int64_t carry6;
+  int64_t carry7;
+  int64_t carry8;
+  int64_t carry9;
+
+  carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & kTop39Bits;
+  carry1 = h1 + (1 << 24); h2 += carry1 >> 25; h1 -= carry1 & kTop39Bits;
+  carry3 = h3 + (1 << 24); h4 += carry3 >> 25; h3 -= carry3 & kTop39Bits;
+  carry5 = h5 + (1 << 24); h6 += carry5 >> 25; h5 -= carry5 & kTop39Bits;
+  carry7 = h7 + (1 << 24); h8 += carry7 >> 25; h7 -= carry7 & kTop39Bits;
+
+  carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & kTop38Bits;
+  carry2 = h2 + (1 << 25); h3 += carry2 >> 26; h2 -= carry2 & kTop38Bits;
+  carry4 = h4 + (1 << 25); h5 += carry4 >> 26; h4 -= carry4 & kTop38Bits;
+  carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & kTop38Bits;
+  carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & kTop38Bits;
+
+  h[0] = h0;
+  h[1] = h1;
+  h[2] = h2;
+  h[3] = h3;
+  h[4] = h4;
+  h[5] = h5;
+  h[6] = h6;
+  h[7] = h7;
+  h[8] = h8;
+  h[9] = h9;
+}
+
+static void x25519_scalar_mult_generic(uint8_t out[32],
+                                       const uint8_t scalar[32],
+                                       const uint8_t point[32]) {
+  fe x1, x2, z2, x3, z3, tmp0, tmp1;
+  uint8_t e[32];
+  unsigned swap = 0;
+  int pos;
+
+  memcpy(e, scalar, 32);
+  e[0] &= 248;
+  e[31] &= 127;
+  e[31] |= 64;
+  fe_frombytes(x1, point);
+  fe_1(x2);
+  fe_0(z2);
+  fe_copy(x3, x1);
+  fe_1(z3);
+
+  for (pos = 254; pos >= 0; --pos) {
+    unsigned b = 1 & (e[pos / 8] >> (pos & 7));
+    swap ^= b;
+    fe_cswap(x2, x3, swap);
+    fe_cswap(z2, z3, swap);
+    swap = b;
+    fe_sub(tmp0, x3, z3);
+    fe_sub(tmp1, x2, z2);
+    fe_add(x2, x2, z2);
+    fe_add(z2, x3, z3);
+    fe_mul(z3, tmp0, x2);
+    fe_mul(z2, z2, tmp1);
+    fe_sq(tmp0, tmp1);
+    fe_sq(tmp1, x2);
+    fe_add(x3, z3, z2);
+    fe_sub(z2, z3, z2);
+    fe_mul(x2, tmp1, tmp0);
+    fe_sub(tmp1, tmp1, tmp0);
+    fe_sq(z2, z2);
+    fe_mul121666(z3, tmp1);
+    fe_sq(x3, x3);
+    fe_add(tmp0, tmp0, z3);
+    fe_mul(z3, x1, z2);
+    fe_mul(z2, tmp1, tmp0);
+  }
+  fe_cswap(x2, x3, swap);
+  fe_cswap(z2, z3, swap);
+
+  fe_invert(z2, z2);
+  fe_mul(x2, x2, z2);
+  fe_tobytes(out, x2);
+}
+
+static void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32],
+                               const uint8_t point[32]) {
+  x25519_scalar_mult_generic(out, scalar, point);
+}
+
+int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
+           const uint8_t peer_public_value[32]) {
+  static const uint8_t kZeros[32] = {0};
+  x25519_scalar_mult(out_shared_key, private_key, peer_public_value);
+  /* The all-zero output results when the input is a point of small order. */
+  return CRYPTO_memcmp(kZeros, out_shared_key, 32) != 0;
+}
+
+void X25519_public_from_private(uint8_t out_public_value[32],
+                                const uint8_t private_key[32]) {
+  uint8_t e[32];
+  ge_p3 A;
+  fe zplusy, zminusy, zminusy_inv;
+
+  memcpy(e, private_key, 32);
+  e[0] &= 248;
+  e[31] &= 127;
+  e[31] |= 64;
+
+  ge_scalarmult_base(&A, e);
+
+  /* We only need the u-coordinate of the curve25519 point. The map is
+   * u=(y+1)/(1-y). Since y=Y/Z, this gives u=(Z+Y)/(Z-Y). */
+  fe_add(zplusy, A.Z, A.Y);
+  fe_sub(zminusy, A.Z, A.Y);
+  fe_invert(zminusy_inv, zminusy);
+  fe_mul(zplusy, zplusy, zminusy_inv);
+  fe_tobytes(out_public_value, zplusy);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec2_mult.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec2_mult.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec2_mult.c	(revision 331)
@@ -0,0 +1,418 @@
+/*
+ * Copyright 2002-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The software is originally written by Sheueling Chang Shantz and
+ * Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#include <openssl/err.h>
+
+#include "internal/bn_int.h"
+#include "ec_lcl.h"
+
+#ifndef OPENSSL_NO_EC2M
+
+/*-
+ * Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective
+ * coordinates.
+ * Uses algorithm Mdouble in appendix of
+ *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over
+ *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
+ * modified to not require precomputation of c=b^{2^{m-1}}.
+ */
+static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z,
+                        BN_CTX *ctx)
+{
+    BIGNUM *t1;
+    int ret = 0;
+
+    /* Since Mdouble is static we can guarantee that ctx != NULL. */
+    BN_CTX_start(ctx);
+    t1 = BN_CTX_get(ctx);
+    if (t1 == NULL)
+        goto err;
+
+    if (!group->meth->field_sqr(group, x, x, ctx))
+        goto err;
+    if (!group->meth->field_sqr(group, t1, z, ctx))
+        goto err;
+    if (!group->meth->field_mul(group, z, x, t1, ctx))
+        goto err;
+    if (!group->meth->field_sqr(group, x, x, ctx))
+        goto err;
+    if (!group->meth->field_sqr(group, t1, t1, ctx))
+        goto err;
+    if (!group->meth->field_mul(group, t1, group->b, t1, ctx))
+        goto err;
+    if (!BN_GF2m_add(x, x, t1))
+        goto err;
+
+    ret = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    return ret;
+}
+
+/*-
+ * Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery
+ * projective coordinates.
+ * Uses algorithm Madd in appendix of
+ *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over
+ *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
+ */
+static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1,
+                     BIGNUM *z1, const BIGNUM *x2, const BIGNUM *z2,
+                     BN_CTX *ctx)
+{
+    BIGNUM *t1, *t2;
+    int ret = 0;
+
+    /* Since Madd is static we can guarantee that ctx != NULL. */
+    BN_CTX_start(ctx);
+    t1 = BN_CTX_get(ctx);
+    t2 = BN_CTX_get(ctx);
+    if (t2 == NULL)
+        goto err;
+
+    if (!BN_copy(t1, x))
+        goto err;
+    if (!group->meth->field_mul(group, x1, x1, z2, ctx))
+        goto err;
+    if (!group->meth->field_mul(group, z1, z1, x2, ctx))
+        goto err;
+    if (!group->meth->field_mul(group, t2, x1, z1, ctx))
+        goto err;
+    if (!BN_GF2m_add(z1, z1, x1))
+        goto err;
+    if (!group->meth->field_sqr(group, z1, z1, ctx))
+        goto err;
+    if (!group->meth->field_mul(group, x1, z1, t1, ctx))
+        goto err;
+    if (!BN_GF2m_add(x1, x1, t2))
+        goto err;
+
+    ret = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    return ret;
+}
+
+/*-
+ * Compute the x, y affine coordinates from the point (x1, z1) (x2, z2)
+ * using Montgomery point multiplication algorithm Mxy() in appendix of
+ *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over
+ *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
+ * Returns:
+ *     0 on error
+ *     1 if return value should be the point at infinity
+ *     2 otherwise
+ */
+static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y,
+                    BIGNUM *x1, BIGNUM *z1, BIGNUM *x2, BIGNUM *z2,
+                    BN_CTX *ctx)
+{
+    BIGNUM *t3, *t4, *t5;
+    int ret = 0;
+
+    if (BN_is_zero(z1)) {
+        BN_zero(x2);
+        BN_zero(z2);
+        return 1;
+    }
+
+    if (BN_is_zero(z2)) {
+        if (!BN_copy(x2, x))
+            return 0;
+        if (!BN_GF2m_add(z2, x, y))
+            return 0;
+        return 2;
+    }
+
+    /* Since Mxy is static we can guarantee that ctx != NULL. */
+    BN_CTX_start(ctx);
+    t3 = BN_CTX_get(ctx);
+    t4 = BN_CTX_get(ctx);
+    t5 = BN_CTX_get(ctx);
+    if (t5 == NULL)
+        goto err;
+
+    if (!BN_one(t5))
+        goto err;
+
+    if (!group->meth->field_mul(group, t3, z1, z2, ctx))
+        goto err;
+
+    if (!group->meth->field_mul(group, z1, z1, x, ctx))
+        goto err;
+    if (!BN_GF2m_add(z1, z1, x1))
+        goto err;
+    if (!group->meth->field_mul(group, z2, z2, x, ctx))
+        goto err;
+    if (!group->meth->field_mul(group, x1, z2, x1, ctx))
+        goto err;
+    if (!BN_GF2m_add(z2, z2, x2))
+        goto err;
+
+    if (!group->meth->field_mul(group, z2, z2, z1, ctx))
+        goto err;
+    if (!group->meth->field_sqr(group, t4, x, ctx))
+        goto err;
+    if (!BN_GF2m_add(t4, t4, y))
+        goto err;
+    if (!group->meth->field_mul(group, t4, t4, t3, ctx))
+        goto err;
+    if (!BN_GF2m_add(t4, t4, z2))
+        goto err;
+
+    if (!group->meth->field_mul(group, t3, t3, x, ctx))
+        goto err;
+    if (!group->meth->field_div(group, t3, t5, t3, ctx))
+        goto err;
+    if (!group->meth->field_mul(group, t4, t3, t4, ctx))
+        goto err;
+    if (!group->meth->field_mul(group, x2, x1, t3, ctx))
+        goto err;
+    if (!BN_GF2m_add(z2, x2, x))
+        goto err;
+
+    if (!group->meth->field_mul(group, z2, z2, t4, ctx))
+        goto err;
+    if (!BN_GF2m_add(z2, z2, y))
+        goto err;
+
+    ret = 2;
+
+ err:
+    BN_CTX_end(ctx);
+    return ret;
+}
+
+/*-
+ * Computes scalar*point and stores the result in r.
+ * point can not equal r.
+ * Uses a modified algorithm 2P of
+ *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over
+ *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
+ *
+ * To protect against side-channel attack the function uses constant time swap,
+ * avoiding conditional branches.
+ */
+static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group,
+                                             EC_POINT *r,
+                                             const BIGNUM *scalar,
+                                             const EC_POINT *point,
+                                             BN_CTX *ctx)
+{
+    BIGNUM *x1, *x2, *z1, *z2;
+    int ret = 0, i, group_top;
+    BN_ULONG mask, word;
+
+    if (r == point) {
+        ECerr(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, EC_R_INVALID_ARGUMENT);
+        return 0;
+    }
+
+    /* if result should be point at infinity */
+    if ((scalar == NULL) || BN_is_zero(scalar) || (point == NULL) ||
+        EC_POINT_is_at_infinity(group, point)) {
+        return EC_POINT_set_to_infinity(group, r);
+    }
+
+    /* only support affine coordinates */
+    if (!point->Z_is_one)
+        return 0;
+
+    /*
+     * Since point_multiply is static we can guarantee that ctx != NULL.
+     */
+    BN_CTX_start(ctx);
+    x1 = BN_CTX_get(ctx);
+    z1 = BN_CTX_get(ctx);
+    if (z1 == NULL)
+        goto err;
+
+    x2 = r->X;
+    z2 = r->Y;
+
+    group_top = bn_get_top(group->field);
+    if (bn_wexpand(x1, group_top) == NULL
+        || bn_wexpand(z1, group_top) == NULL
+        || bn_wexpand(x2, group_top) == NULL
+        || bn_wexpand(z2, group_top) == NULL)
+        goto err;
+
+    if (!BN_GF2m_mod_arr(x1, point->X, group->poly))
+        goto err;               /* x1 = x */
+    if (!BN_one(z1))
+        goto err;               /* z1 = 1 */
+    if (!group->meth->field_sqr(group, z2, x1, ctx))
+        goto err;               /* z2 = x1^2 = x^2 */
+    if (!group->meth->field_sqr(group, x2, z2, ctx))
+        goto err;
+    if (!BN_GF2m_add(x2, x2, group->b))
+        goto err;               /* x2 = x^4 + b */
+
+    /* find top most bit and go one past it */
+    i = bn_get_top(scalar) - 1;
+    mask = BN_TBIT;
+    word = bn_get_words(scalar)[i];
+    while (!(word & mask))
+        mask >>= 1;
+    mask >>= 1;
+    /* if top most bit was at word break, go to next word */
+    if (!mask) {
+        i--;
+        mask = BN_TBIT;
+    }
+
+    for (; i >= 0; i--) {
+        word = bn_get_words(scalar)[i];
+        while (mask) {
+            BN_consttime_swap(word & mask, x1, x2, group_top);
+            BN_consttime_swap(word & mask, z1, z2, group_top);
+            if (!gf2m_Madd(group, point->X, x2, z2, x1, z1, ctx))
+                goto err;
+            if (!gf2m_Mdouble(group, x1, z1, ctx))
+                goto err;
+            BN_consttime_swap(word & mask, x1, x2, group_top);
+            BN_consttime_swap(word & mask, z1, z2, group_top);
+            mask >>= 1;
+        }
+        mask = BN_TBIT;
+    }
+
+    /* convert out of "projective" coordinates */
+    i = gf2m_Mxy(group, point->X, point->Y, x1, z1, x2, z2, ctx);
+    if (i == 0)
+        goto err;
+    else if (i == 1) {
+        if (!EC_POINT_set_to_infinity(group, r))
+            goto err;
+    } else {
+        if (!BN_one(r->Z))
+            goto err;
+        r->Z_is_one = 1;
+    }
+
+    /* GF(2^m) field elements should always have BIGNUM::neg = 0 */
+    BN_set_negative(r->X, 0);
+    BN_set_negative(r->Y, 0);
+
+    ret = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    return ret;
+}
+
+/*-
+ * Computes the sum
+ *     scalar*group->generator + scalars[0]*points[0] + ... + scalars[num-1]*points[num-1]
+ * gracefully ignoring NULL scalar values.
+ */
+int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r,
+                       const BIGNUM *scalar, size_t num,
+                       const EC_POINT *points[], const BIGNUM *scalars[],
+                       BN_CTX *ctx)
+{
+    BN_CTX *new_ctx = NULL;
+    int ret = 0;
+    size_t i;
+    EC_POINT *p = NULL;
+    EC_POINT *acc = NULL;
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            return 0;
+    }
+
+    /*
+     * This implementation is more efficient than the wNAF implementation for
+     * 2 or fewer points.  Use the ec_wNAF_mul implementation for 3 or more
+     * points, or if we can perform a fast multiplication based on
+     * precomputation.
+     */
+    if ((scalar && (num > 1)) || (num > 2)
+        || (num == 0 && EC_GROUP_have_precompute_mult(group))) {
+        ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
+        goto err;
+    }
+
+    if ((p = EC_POINT_new(group)) == NULL)
+        goto err;
+    if ((acc = EC_POINT_new(group)) == NULL)
+        goto err;
+
+    if (!EC_POINT_set_to_infinity(group, acc))
+        goto err;
+
+    if (scalar) {
+        if (!ec_GF2m_montgomery_point_multiply
+            (group, p, scalar, group->generator, ctx))
+            goto err;
+        if (BN_is_negative(scalar))
+            if (!group->meth->invert(group, p, ctx))
+                goto err;
+        if (!group->meth->add(group, acc, acc, p, ctx))
+            goto err;
+    }
+
+    for (i = 0; i < num; i++) {
+        if (!ec_GF2m_montgomery_point_multiply
+            (group, p, scalars[i], points[i], ctx))
+            goto err;
+        if (BN_is_negative(scalars[i]))
+            if (!group->meth->invert(group, p, ctx))
+                goto err;
+        if (!group->meth->add(group, acc, acc, p, ctx))
+            goto err;
+    }
+
+    if (!EC_POINT_copy(r, acc))
+        goto err;
+
+    ret = 1;
+
+ err:
+    EC_POINT_free(p);
+    EC_POINT_free(acc);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+/*
+ * Precomputation for point multiplication: fall back to wNAF methods because
+ * ec_GF2m_simple_mul() uses ec_wNAF_mul() if appropriate
+ */
+
+int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+{
+    return ec_wNAF_precompute_mult(group, ctx);
+}
+
+int ec_GF2m_have_precompute_mult(const EC_GROUP *group)
+{
+    return ec_wNAF_have_precompute_mult(group);
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec2_oct.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec2_oct.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec2_oct.c	(revision 331)
@@ -0,0 +1,352 @@
+/*
+ * Copyright 2011-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The software is originally written by Sheueling Chang Shantz and
+ * Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#include <openssl/err.h>
+
+#include "ec_lcl.h"
+
+#ifndef OPENSSL_NO_EC2M
+
+/*-
+ * Calculates and sets the affine coordinates of an EC_POINT from the given
+ * compressed coordinates.  Uses algorithm 2.3.4 of SEC 1.
+ * Note that the simple implementation only uses affine coordinates.
+ *
+ * The method is from the following publication:
+ *
+ *     Harper, Menezes, Vanstone:
+ *     "Public-Key Cryptosystems with Very Small Key Lengths",
+ *     EUROCRYPT '92, Springer-Verlag LNCS 658,
+ *     published February 1993
+ *
+ * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe
+ * the same method, but claim no priority date earlier than July 29, 1994
+ * (and additionally fail to cite the EUROCRYPT '92 publication as prior art).
+ */
+int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group,
+                                              EC_POINT *point,
+                                              const BIGNUM *x_, int y_bit,
+                                              BN_CTX *ctx)
+{
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *tmp, *x, *y, *z;
+    int ret = 0, z0;
+
+    /* clear error queue */
+    ERR_clear_error();
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            return 0;
+    }
+
+    y_bit = (y_bit != 0) ? 1 : 0;
+
+    BN_CTX_start(ctx);
+    tmp = BN_CTX_get(ctx);
+    x = BN_CTX_get(ctx);
+    y = BN_CTX_get(ctx);
+    z = BN_CTX_get(ctx);
+    if (z == NULL)
+        goto err;
+
+    if (!BN_GF2m_mod_arr(x, x_, group->poly))
+        goto err;
+    if (BN_is_zero(x)) {
+        if (!BN_GF2m_mod_sqrt_arr(y, group->b, group->poly, ctx))
+            goto err;
+    } else {
+        if (!group->meth->field_sqr(group, tmp, x, ctx))
+            goto err;
+        if (!group->meth->field_div(group, tmp, group->b, tmp, ctx))
+            goto err;
+        if (!BN_GF2m_add(tmp, group->a, tmp))
+            goto err;
+        if (!BN_GF2m_add(tmp, x, tmp))
+            goto err;
+        if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx)) {
+            unsigned long err = ERR_peek_last_error();
+
+            if (ERR_GET_LIB(err) == ERR_LIB_BN
+                && ERR_GET_REASON(err) == BN_R_NO_SOLUTION) {
+                ERR_clear_error();
+                ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES,
+                      EC_R_INVALID_COMPRESSED_POINT);
+            } else
+                ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES,
+                      ERR_R_BN_LIB);
+            goto err;
+        }
+        z0 = (BN_is_odd(z)) ? 1 : 0;
+        if (!group->meth->field_mul(group, y, x, z, ctx))
+            goto err;
+        if (z0 != y_bit) {
+            if (!BN_GF2m_add(y, y, x))
+                goto err;
+        }
+    }
+
+    if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx))
+        goto err;
+
+    ret = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+/*
+ * Converts an EC_POINT to an octet string. If buf is NULL, the encoded
+ * length will be returned. If the length len of buf is smaller than required
+ * an error will be returned.
+ */
+size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
+                                point_conversion_form_t form,
+                                unsigned char *buf, size_t len, BN_CTX *ctx)
+{
+    size_t ret;
+    BN_CTX *new_ctx = NULL;
+    int used_ctx = 0;
+    BIGNUM *x, *y, *yxi;
+    size_t field_len, i, skip;
+
+    if ((form != POINT_CONVERSION_COMPRESSED)
+        && (form != POINT_CONVERSION_UNCOMPRESSED)
+        && (form != POINT_CONVERSION_HYBRID)) {
+        ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
+        goto err;
+    }
+
+    if (EC_POINT_is_at_infinity(group, point)) {
+        /* encodes to a single 0 octet */
+        if (buf != NULL) {
+            if (len < 1) {
+                ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+                return 0;
+            }
+            buf[0] = 0;
+        }
+        return 1;
+    }
+
+    /* ret := required output buffer length */
+    field_len = (EC_GROUP_get_degree(group) + 7) / 8;
+    ret =
+        (form ==
+         POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
+
+    /* if 'buf' is NULL, just return required length */
+    if (buf != NULL) {
+        if (len < ret) {
+            ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+            goto err;
+        }
+
+        if (ctx == NULL) {
+            ctx = new_ctx = BN_CTX_new();
+            if (ctx == NULL)
+                return 0;
+        }
+
+        BN_CTX_start(ctx);
+        used_ctx = 1;
+        x = BN_CTX_get(ctx);
+        y = BN_CTX_get(ctx);
+        yxi = BN_CTX_get(ctx);
+        if (yxi == NULL)
+            goto err;
+
+        if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx))
+            goto err;
+
+        buf[0] = form;
+        if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x)) {
+            if (!group->meth->field_div(group, yxi, y, x, ctx))
+                goto err;
+            if (BN_is_odd(yxi))
+                buf[0]++;
+        }
+
+        i = 1;
+
+        skip = field_len - BN_num_bytes(x);
+        if (skip > field_len) {
+            ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+        while (skip > 0) {
+            buf[i++] = 0;
+            skip--;
+        }
+        skip = BN_bn2bin(x, buf + i);
+        i += skip;
+        if (i != 1 + field_len) {
+            ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+
+        if (form == POINT_CONVERSION_UNCOMPRESSED
+            || form == POINT_CONVERSION_HYBRID) {
+            skip = field_len - BN_num_bytes(y);
+            if (skip > field_len) {
+                ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+                goto err;
+            }
+            while (skip > 0) {
+                buf[i++] = 0;
+                skip--;
+            }
+            skip = BN_bn2bin(y, buf + i);
+            i += skip;
+        }
+
+        if (i != ret) {
+            ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+    }
+
+    if (used_ctx)
+        BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+
+ err:
+    if (used_ctx)
+        BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return 0;
+}
+
+/*
+ * Converts an octet string representation to an EC_POINT. Note that the
+ * simple implementation only uses affine coordinates.
+ */
+int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
+                             const unsigned char *buf, size_t len,
+                             BN_CTX *ctx)
+{
+    point_conversion_form_t form;
+    int y_bit;
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *x, *y, *yxi;
+    size_t field_len, enc_len;
+    int ret = 0;
+
+    if (len == 0) {
+        ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
+        return 0;
+    }
+    form = buf[0];
+    y_bit = form & 1;
+    form = form & ~1U;
+    if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
+        && (form != POINT_CONVERSION_UNCOMPRESSED)
+        && (form != POINT_CONVERSION_HYBRID)) {
+        ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+        return 0;
+    }
+    if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
+        ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+        return 0;
+    }
+
+    if (form == 0) {
+        if (len != 1) {
+            ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+            return 0;
+        }
+
+        return EC_POINT_set_to_infinity(group, point);
+    }
+
+    field_len = (EC_GROUP_get_degree(group) + 7) / 8;
+    enc_len =
+        (form ==
+         POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
+
+    if (len != enc_len) {
+        ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+        return 0;
+    }
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            return 0;
+    }
+
+    BN_CTX_start(ctx);
+    x = BN_CTX_get(ctx);
+    y = BN_CTX_get(ctx);
+    yxi = BN_CTX_get(ctx);
+    if (yxi == NULL)
+        goto err;
+
+    if (!BN_bin2bn(buf + 1, field_len, x))
+        goto err;
+    if (BN_ucmp(x, group->field) >= 0) {
+        ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+        goto err;
+    }
+
+    if (form == POINT_CONVERSION_COMPRESSED) {
+        if (!EC_POINT_set_compressed_coordinates_GF2m
+            (group, point, x, y_bit, ctx))
+            goto err;
+    } else {
+        if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
+            goto err;
+        if (BN_ucmp(y, group->field) >= 0) {
+            ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+            goto err;
+        }
+        if (form == POINT_CONVERSION_HYBRID) {
+            if (!group->meth->field_div(group, yxi, y, x, ctx))
+                goto err;
+            if (y_bit != BN_is_odd(yxi)) {
+                ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+                goto err;
+            }
+        }
+
+        /*
+         * EC_POINT_set_affine_coordinates_GF2m is responsible for checking that
+         * the point is on the curve.
+         */
+        if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx))
+            goto err;
+    }
+
+    ret = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec2_smpl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec2_smpl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec2_smpl.c	(revision 331)
@@ -0,0 +1,758 @@
+/*
+ * Copyright 2002-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The software is originally written by Sheueling Chang Shantz and
+ * Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#include <openssl/err.h>
+
+#include "internal/bn_int.h"
+#include "ec_lcl.h"
+
+#ifndef OPENSSL_NO_EC2M
+
+const EC_METHOD *EC_GF2m_simple_method(void)
+{
+    static const EC_METHOD ret = {
+        EC_FLAGS_DEFAULT_OCT,
+        NID_X9_62_characteristic_two_field,
+        ec_GF2m_simple_group_init,
+        ec_GF2m_simple_group_finish,
+        ec_GF2m_simple_group_clear_finish,
+        ec_GF2m_simple_group_copy,
+        ec_GF2m_simple_group_set_curve,
+        ec_GF2m_simple_group_get_curve,
+        ec_GF2m_simple_group_get_degree,
+        ec_group_simple_order_bits,
+        ec_GF2m_simple_group_check_discriminant,
+        ec_GF2m_simple_point_init,
+        ec_GF2m_simple_point_finish,
+        ec_GF2m_simple_point_clear_finish,
+        ec_GF2m_simple_point_copy,
+        ec_GF2m_simple_point_set_to_infinity,
+        0 /* set_Jprojective_coordinates_GFp */ ,
+        0 /* get_Jprojective_coordinates_GFp */ ,
+        ec_GF2m_simple_point_set_affine_coordinates,
+        ec_GF2m_simple_point_get_affine_coordinates,
+        0, 0, 0,
+        ec_GF2m_simple_add,
+        ec_GF2m_simple_dbl,
+        ec_GF2m_simple_invert,
+        ec_GF2m_simple_is_at_infinity,
+        ec_GF2m_simple_is_on_curve,
+        ec_GF2m_simple_cmp,
+        ec_GF2m_simple_make_affine,
+        ec_GF2m_simple_points_make_affine,
+
+        /*
+         * the following three method functions are defined in ec2_mult.c
+         */
+        ec_GF2m_simple_mul,
+        ec_GF2m_precompute_mult,
+        ec_GF2m_have_precompute_mult,
+
+        ec_GF2m_simple_field_mul,
+        ec_GF2m_simple_field_sqr,
+        ec_GF2m_simple_field_div,
+        0 /* field_encode */ ,
+        0 /* field_decode */ ,
+        0,                      /* field_set_to_one */
+        ec_key_simple_priv2oct,
+        ec_key_simple_oct2priv,
+        0, /* set private */
+        ec_key_simple_generate_key,
+        ec_key_simple_check_key,
+        ec_key_simple_generate_public_key,
+        0, /* keycopy */
+        0, /* keyfinish */
+        ecdh_simple_compute_key
+    };
+
+    return &ret;
+}
+
+/*
+ * Initialize a GF(2^m)-based EC_GROUP structure. Note that all other members
+ * are handled by EC_GROUP_new.
+ */
+int ec_GF2m_simple_group_init(EC_GROUP *group)
+{
+    group->field = BN_new();
+    group->a = BN_new();
+    group->b = BN_new();
+
+    if (group->field == NULL || group->a == NULL || group->b == NULL) {
+        BN_free(group->field);
+        BN_free(group->a);
+        BN_free(group->b);
+        return 0;
+    }
+    return 1;
+}
+
+/*
+ * Free a GF(2^m)-based EC_GROUP structure. Note that all other members are
+ * handled by EC_GROUP_free.
+ */
+void ec_GF2m_simple_group_finish(EC_GROUP *group)
+{
+    BN_free(group->field);
+    BN_free(group->a);
+    BN_free(group->b);
+}
+
+/*
+ * Clear and free a GF(2^m)-based EC_GROUP structure. Note that all other
+ * members are handled by EC_GROUP_clear_free.
+ */
+void ec_GF2m_simple_group_clear_finish(EC_GROUP *group)
+{
+    BN_clear_free(group->field);
+    BN_clear_free(group->a);
+    BN_clear_free(group->b);
+    group->poly[0] = 0;
+    group->poly[1] = 0;
+    group->poly[2] = 0;
+    group->poly[3] = 0;
+    group->poly[4] = 0;
+    group->poly[5] = -1;
+}
+
+/*
+ * Copy a GF(2^m)-based EC_GROUP structure. Note that all other members are
+ * handled by EC_GROUP_copy.
+ */
+int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
+{
+    if (!BN_copy(dest->field, src->field))
+        return 0;
+    if (!BN_copy(dest->a, src->a))
+        return 0;
+    if (!BN_copy(dest->b, src->b))
+        return 0;
+    dest->poly[0] = src->poly[0];
+    dest->poly[1] = src->poly[1];
+    dest->poly[2] = src->poly[2];
+    dest->poly[3] = src->poly[3];
+    dest->poly[4] = src->poly[4];
+    dest->poly[5] = src->poly[5];
+    if (bn_wexpand(dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) ==
+        NULL)
+        return 0;
+    if (bn_wexpand(dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) ==
+        NULL)
+        return 0;
+    bn_set_all_zero(dest->a);
+    bn_set_all_zero(dest->b);
+    return 1;
+}
+
+/* Set the curve parameters of an EC_GROUP structure. */
+int ec_GF2m_simple_group_set_curve(EC_GROUP *group,
+                                   const BIGNUM *p, const BIGNUM *a,
+                                   const BIGNUM *b, BN_CTX *ctx)
+{
+    int ret = 0, i;
+
+    /* group->field */
+    if (!BN_copy(group->field, p))
+        goto err;
+    i = BN_GF2m_poly2arr(group->field, group->poly, 6) - 1;
+    if ((i != 5) && (i != 3)) {
+        ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD);
+        goto err;
+    }
+
+    /* group->a */
+    if (!BN_GF2m_mod_arr(group->a, a, group->poly))
+        goto err;
+    if (bn_wexpand(group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2)
+        == NULL)
+        goto err;
+    bn_set_all_zero(group->a);
+
+    /* group->b */
+    if (!BN_GF2m_mod_arr(group->b, b, group->poly))
+        goto err;
+    if (bn_wexpand(group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2)
+        == NULL)
+        goto err;
+    bn_set_all_zero(group->b);
+
+    ret = 1;
+ err:
+    return ret;
+}
+
+/*
+ * Get the curve parameters of an EC_GROUP structure. If p, a, or b are NULL
+ * then there values will not be set but the method will return with success.
+ */
+int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p,
+                                   BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
+{
+    int ret = 0;
+
+    if (p != NULL) {
+        if (!BN_copy(p, group->field))
+            return 0;
+    }
+
+    if (a != NULL) {
+        if (!BN_copy(a, group->a))
+            goto err;
+    }
+
+    if (b != NULL) {
+        if (!BN_copy(b, group->b))
+            goto err;
+    }
+
+    ret = 1;
+
+ err:
+    return ret;
+}
+
+/*
+ * Gets the degree of the field.  For a curve over GF(2^m) this is the value
+ * m.
+ */
+int ec_GF2m_simple_group_get_degree(const EC_GROUP *group)
+{
+    return BN_num_bits(group->field) - 1;
+}
+
+/*
+ * Checks the discriminant of the curve. y^2 + x*y = x^3 + a*x^2 + b is an
+ * elliptic curve <=> b != 0 (mod p)
+ */
+int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group,
+                                            BN_CTX *ctx)
+{
+    int ret = 0;
+    BIGNUM *b;
+    BN_CTX *new_ctx = NULL;
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL) {
+            ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT,
+                  ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    }
+    BN_CTX_start(ctx);
+    b = BN_CTX_get(ctx);
+    if (b == NULL)
+        goto err;
+
+    if (!BN_GF2m_mod_arr(b, group->b, group->poly))
+        goto err;
+
+    /*
+     * check the discriminant: y^2 + x*y = x^3 + a*x^2 + b is an elliptic
+     * curve <=> b != 0 (mod p)
+     */
+    if (BN_is_zero(b))
+        goto err;
+
+    ret = 1;
+
+ err:
+    if (ctx != NULL)
+        BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+/* Initializes an EC_POINT. */
+int ec_GF2m_simple_point_init(EC_POINT *point)
+{
+    point->X = BN_new();
+    point->Y = BN_new();
+    point->Z = BN_new();
+
+    if (point->X == NULL || point->Y == NULL || point->Z == NULL) {
+        BN_free(point->X);
+        BN_free(point->Y);
+        BN_free(point->Z);
+        return 0;
+    }
+    return 1;
+}
+
+/* Frees an EC_POINT. */
+void ec_GF2m_simple_point_finish(EC_POINT *point)
+{
+    BN_free(point->X);
+    BN_free(point->Y);
+    BN_free(point->Z);
+}
+
+/* Clears and frees an EC_POINT. */
+void ec_GF2m_simple_point_clear_finish(EC_POINT *point)
+{
+    BN_clear_free(point->X);
+    BN_clear_free(point->Y);
+    BN_clear_free(point->Z);
+    point->Z_is_one = 0;
+}
+
+/*
+ * Copy the contents of one EC_POINT into another.  Assumes dest is
+ * initialized.
+ */
+int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
+{
+    if (!BN_copy(dest->X, src->X))
+        return 0;
+    if (!BN_copy(dest->Y, src->Y))
+        return 0;
+    if (!BN_copy(dest->Z, src->Z))
+        return 0;
+    dest->Z_is_one = src->Z_is_one;
+
+    return 1;
+}
+
+/*
+ * Set an EC_POINT to the point at infinity. A point at infinity is
+ * represented by having Z=0.
+ */
+int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group,
+                                         EC_POINT *point)
+{
+    point->Z_is_one = 0;
+    BN_zero(point->Z);
+    return 1;
+}
+
+/*
+ * Set the coordinates of an EC_POINT using affine coordinates. Note that
+ * the simple implementation only uses affine coordinates.
+ */
+int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group,
+                                                EC_POINT *point,
+                                                const BIGNUM *x,
+                                                const BIGNUM *y, BN_CTX *ctx)
+{
+    int ret = 0;
+    if (x == NULL || y == NULL) {
+        ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES,
+              ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if (!BN_copy(point->X, x))
+        goto err;
+    BN_set_negative(point->X, 0);
+    if (!BN_copy(point->Y, y))
+        goto err;
+    BN_set_negative(point->Y, 0);
+    if (!BN_copy(point->Z, BN_value_one()))
+        goto err;
+    BN_set_negative(point->Z, 0);
+    point->Z_is_one = 1;
+    ret = 1;
+
+ err:
+    return ret;
+}
+
+/*
+ * Gets the affine coordinates of an EC_POINT. Note that the simple
+ * implementation only uses affine coordinates.
+ */
+int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group,
+                                                const EC_POINT *point,
+                                                BIGNUM *x, BIGNUM *y,
+                                                BN_CTX *ctx)
+{
+    int ret = 0;
+
+    if (EC_POINT_is_at_infinity(group, point)) {
+        ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES,
+              EC_R_POINT_AT_INFINITY);
+        return 0;
+    }
+
+    if (BN_cmp(point->Z, BN_value_one())) {
+        ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES,
+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    if (x != NULL) {
+        if (!BN_copy(x, point->X))
+            goto err;
+        BN_set_negative(x, 0);
+    }
+    if (y != NULL) {
+        if (!BN_copy(y, point->Y))
+            goto err;
+        BN_set_negative(y, 0);
+    }
+    ret = 1;
+
+ err:
+    return ret;
+}
+
+/*
+ * Computes a + b and stores the result in r.  r could be a or b, a could be
+ * b. Uses algorithm A.10.2 of IEEE P1363.
+ */
+int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+                       const EC_POINT *b, BN_CTX *ctx)
+{
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t;
+    int ret = 0;
+
+    if (EC_POINT_is_at_infinity(group, a)) {
+        if (!EC_POINT_copy(r, b))
+            return 0;
+        return 1;
+    }
+
+    if (EC_POINT_is_at_infinity(group, b)) {
+        if (!EC_POINT_copy(r, a))
+            return 0;
+        return 1;
+    }
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            return 0;
+    }
+
+    BN_CTX_start(ctx);
+    x0 = BN_CTX_get(ctx);
+    y0 = BN_CTX_get(ctx);
+    x1 = BN_CTX_get(ctx);
+    y1 = BN_CTX_get(ctx);
+    x2 = BN_CTX_get(ctx);
+    y2 = BN_CTX_get(ctx);
+    s = BN_CTX_get(ctx);
+    t = BN_CTX_get(ctx);
+    if (t == NULL)
+        goto err;
+
+    if (a->Z_is_one) {
+        if (!BN_copy(x0, a->X))
+            goto err;
+        if (!BN_copy(y0, a->Y))
+            goto err;
+    } else {
+        if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x0, y0, ctx))
+            goto err;
+    }
+    if (b->Z_is_one) {
+        if (!BN_copy(x1, b->X))
+            goto err;
+        if (!BN_copy(y1, b->Y))
+            goto err;
+    } else {
+        if (!EC_POINT_get_affine_coordinates_GF2m(group, b, x1, y1, ctx))
+            goto err;
+    }
+
+    if (BN_GF2m_cmp(x0, x1)) {
+        if (!BN_GF2m_add(t, x0, x1))
+            goto err;
+        if (!BN_GF2m_add(s, y0, y1))
+            goto err;
+        if (!group->meth->field_div(group, s, s, t, ctx))
+            goto err;
+        if (!group->meth->field_sqr(group, x2, s, ctx))
+            goto err;
+        if (!BN_GF2m_add(x2, x2, group->a))
+            goto err;
+        if (!BN_GF2m_add(x2, x2, s))
+            goto err;
+        if (!BN_GF2m_add(x2, x2, t))
+            goto err;
+    } else {
+        if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1)) {
+            if (!EC_POINT_set_to_infinity(group, r))
+                goto err;
+            ret = 1;
+            goto err;
+        }
+        if (!group->meth->field_div(group, s, y1, x1, ctx))
+            goto err;
+        if (!BN_GF2m_add(s, s, x1))
+            goto err;
+
+        if (!group->meth->field_sqr(group, x2, s, ctx))
+            goto err;
+        if (!BN_GF2m_add(x2, x2, s))
+            goto err;
+        if (!BN_GF2m_add(x2, x2, group->a))
+            goto err;
+    }
+
+    if (!BN_GF2m_add(y2, x1, x2))
+        goto err;
+    if (!group->meth->field_mul(group, y2, y2, s, ctx))
+        goto err;
+    if (!BN_GF2m_add(y2, y2, x2))
+        goto err;
+    if (!BN_GF2m_add(y2, y2, y1))
+        goto err;
+
+    if (!EC_POINT_set_affine_coordinates_GF2m(group, r, x2, y2, ctx))
+        goto err;
+
+    ret = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+/*
+ * Computes 2 * a and stores the result in r.  r could be a. Uses algorithm
+ * A.10.2 of IEEE P1363.
+ */
+int ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+                       BN_CTX *ctx)
+{
+    return ec_GF2m_simple_add(group, r, a, a, ctx);
+}
+
+int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
+{
+    if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(point->Y))
+        /* point is its own inverse */
+        return 1;
+
+    if (!EC_POINT_make_affine(group, point, ctx))
+        return 0;
+    return BN_GF2m_add(point->Y, point->X, point->Y);
+}
+
+/* Indicates whether the given point is the point at infinity. */
+int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group,
+                                  const EC_POINT *point)
+{
+    return BN_is_zero(point->Z);
+}
+
+/*-
+ * Determines whether the given EC_POINT is an actual point on the curve defined
+ * in the EC_GROUP.  A point is valid if it satisfies the Weierstrass equation:
+ *      y^2 + x*y = x^3 + a*x^2 + b.
+ */
+int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
+                               BN_CTX *ctx)
+{
+    int ret = -1;
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *lh, *y2;
+    int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
+                      const BIGNUM *, BN_CTX *);
+    int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+
+    if (EC_POINT_is_at_infinity(group, point))
+        return 1;
+
+    field_mul = group->meth->field_mul;
+    field_sqr = group->meth->field_sqr;
+
+    /* only support affine coordinates */
+    if (!point->Z_is_one)
+        return -1;
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            return -1;
+    }
+
+    BN_CTX_start(ctx);
+    y2 = BN_CTX_get(ctx);
+    lh = BN_CTX_get(ctx);
+    if (lh == NULL)
+        goto err;
+
+    /*-
+     * We have a curve defined by a Weierstrass equation
+     *      y^2 + x*y = x^3 + a*x^2 + b.
+     *  <=> x^3 + a*x^2 + x*y + b + y^2 = 0
+     *  <=> ((x + a) * x + y ) * x + b + y^2 = 0
+     */
+    if (!BN_GF2m_add(lh, point->X, group->a))
+        goto err;
+    if (!field_mul(group, lh, lh, point->X, ctx))
+        goto err;
+    if (!BN_GF2m_add(lh, lh, point->Y))
+        goto err;
+    if (!field_mul(group, lh, lh, point->X, ctx))
+        goto err;
+    if (!BN_GF2m_add(lh, lh, group->b))
+        goto err;
+    if (!field_sqr(group, y2, point->Y, ctx))
+        goto err;
+    if (!BN_GF2m_add(lh, lh, y2))
+        goto err;
+    ret = BN_is_zero(lh);
+ err:
+    if (ctx)
+        BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+/*-
+ * Indicates whether two points are equal.
+ * Return values:
+ *  -1   error
+ *   0   equal (in affine coordinates)
+ *   1   not equal
+ */
+int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
+                       const EC_POINT *b, BN_CTX *ctx)
+{
+    BIGNUM *aX, *aY, *bX, *bY;
+    BN_CTX *new_ctx = NULL;
+    int ret = -1;
+
+    if (EC_POINT_is_at_infinity(group, a)) {
+        return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
+    }
+
+    if (EC_POINT_is_at_infinity(group, b))
+        return 1;
+
+    if (a->Z_is_one && b->Z_is_one) {
+        return ((BN_cmp(a->X, b->X) == 0) && BN_cmp(a->Y, b->Y) == 0) ? 0 : 1;
+    }
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            return -1;
+    }
+
+    BN_CTX_start(ctx);
+    aX = BN_CTX_get(ctx);
+    aY = BN_CTX_get(ctx);
+    bX = BN_CTX_get(ctx);
+    bY = BN_CTX_get(ctx);
+    if (bY == NULL)
+        goto err;
+
+    if (!EC_POINT_get_affine_coordinates_GF2m(group, a, aX, aY, ctx))
+        goto err;
+    if (!EC_POINT_get_affine_coordinates_GF2m(group, b, bX, bY, ctx))
+        goto err;
+    ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1;
+
+ err:
+    if (ctx)
+        BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+/* Forces the given EC_POINT to internally use affine coordinates. */
+int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
+                               BN_CTX *ctx)
+{
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *x, *y;
+    int ret = 0;
+
+    if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
+        return 1;
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            return 0;
+    }
+
+    BN_CTX_start(ctx);
+    x = BN_CTX_get(ctx);
+    y = BN_CTX_get(ctx);
+    if (y == NULL)
+        goto err;
+
+    if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx))
+        goto err;
+    if (!BN_copy(point->X, x))
+        goto err;
+    if (!BN_copy(point->Y, y))
+        goto err;
+    if (!BN_one(point->Z))
+        goto err;
+    point->Z_is_one = 1;
+
+    ret = 1;
+
+ err:
+    if (ctx)
+        BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+/*
+ * Forces each of the EC_POINTs in the given array to use affine coordinates.
+ */
+int ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num,
+                                      EC_POINT *points[], BN_CTX *ctx)
+{
+    size_t i;
+
+    for (i = 0; i < num; i++) {
+        if (!group->meth->make_affine(group, points[i], ctx))
+            return 0;
+    }
+
+    return 1;
+}
+
+/* Wrapper to simple binary polynomial field multiplication implementation. */
+int ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r,
+                             const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+{
+    return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx);
+}
+
+/* Wrapper to simple binary polynomial field squaring implementation. */
+int ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r,
+                             const BIGNUM *a, BN_CTX *ctx)
+{
+    return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx);
+}
+
+/* Wrapper to simple binary polynomial field division implementation. */
+int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r,
+                             const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+{
+    return BN_GF2m_mod_div(r, a, b, group->field, ctx);
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_ameth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_ameth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_ameth.c	(revision 331)
@@ -0,0 +1,881 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/ec.h>
+#include <openssl/bn.h>
+#include <openssl/cms.h>
+#include <openssl/asn1t.h>
+#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
+#include "ec_lcl.h"
+
+#ifndef OPENSSL_NO_CMS
+static int ecdh_cms_decrypt(CMS_RecipientInfo *ri);
+static int ecdh_cms_encrypt(CMS_RecipientInfo *ri);
+#endif
+
+static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
+{
+    const EC_GROUP *group;
+    int nid;
+    if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
+        ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS);
+        return 0;
+    }
+    if (EC_GROUP_get_asn1_flag(group)
+        && (nid = EC_GROUP_get_curve_name(group)))
+        /* we have a 'named curve' => just set the OID */
+    {
+        *ppval = OBJ_nid2obj(nid);
+        *pptype = V_ASN1_OBJECT;
+    } else {                    /* explicit parameters */
+
+        ASN1_STRING *pstr = NULL;
+        pstr = ASN1_STRING_new();
+        if (pstr == NULL)
+            return 0;
+        pstr->length = i2d_ECParameters(ec_key, &pstr->data);
+        if (pstr->length <= 0) {
+            ASN1_STRING_free(pstr);
+            ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
+            return 0;
+        }
+        *ppval = pstr;
+        *pptype = V_ASN1_SEQUENCE;
+    }
+    return 1;
+}
+
+static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
+{
+    EC_KEY *ec_key = pkey->pkey.ec;
+    void *pval = NULL;
+    int ptype;
+    unsigned char *penc = NULL, *p;
+    int penclen;
+
+    if (!eckey_param2type(&ptype, &pval, ec_key)) {
+        ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB);
+        return 0;
+    }
+    penclen = i2o_ECPublicKey(ec_key, NULL);
+    if (penclen <= 0)
+        goto err;
+    penc = OPENSSL_malloc(penclen);
+    if (penc == NULL)
+        goto err;
+    p = penc;
+    penclen = i2o_ECPublicKey(ec_key, &p);
+    if (penclen <= 0)
+        goto err;
+    if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC),
+                               ptype, pval, penc, penclen))
+        return 1;
+ err:
+    if (ptype == V_ASN1_OBJECT)
+        ASN1_OBJECT_free(pval);
+    else
+        ASN1_STRING_free(pval);
+    OPENSSL_free(penc);
+    return 0;
+}
+
+static EC_KEY *eckey_type2param(int ptype, const void *pval)
+{
+    EC_KEY *eckey = NULL;
+    if (ptype == V_ASN1_SEQUENCE) {
+        const ASN1_STRING *pstr = pval;
+        const unsigned char *pm = NULL;
+        int pmlen;
+        pm = pstr->data;
+        pmlen = pstr->length;
+        if ((eckey = d2i_ECParameters(NULL, &pm, pmlen)) == NULL) {
+            ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
+            goto ecerr;
+        }
+    } else if (ptype == V_ASN1_OBJECT) {
+        const ASN1_OBJECT *poid = pval;
+        EC_GROUP *group;
+
+        /*
+         * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID
+         */
+        if ((eckey = EC_KEY_new()) == NULL) {
+            ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE);
+            goto ecerr;
+        }
+        group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid));
+        if (group == NULL)
+            goto ecerr;
+        EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
+        if (EC_KEY_set_group(eckey, group) == 0)
+            goto ecerr;
+        EC_GROUP_free(group);
+    } else {
+        ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR);
+        goto ecerr;
+    }
+
+    return eckey;
+
+ ecerr:
+    EC_KEY_free(eckey);
+    return NULL;
+}
+
+static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+{
+    const unsigned char *p = NULL;
+    const void *pval;
+    int ptype, pklen;
+    EC_KEY *eckey = NULL;
+    X509_ALGOR *palg;
+
+    if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
+        return 0;
+    X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+    eckey = eckey_type2param(ptype, pval);
+
+    if (!eckey) {
+        ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB);
+        return 0;
+    }
+
+    /* We have parameters now set public key */
+    if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
+        ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
+        goto ecerr;
+    }
+
+    EVP_PKEY_assign_EC_KEY(pkey, eckey);
+    return 1;
+
+ ecerr:
+    EC_KEY_free(eckey);
+    return 0;
+}
+
+static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+    int r;
+    const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
+    const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
+        *pb = EC_KEY_get0_public_key(b->pkey.ec);
+    if (group == NULL || pa == NULL || pb == NULL)
+        return -2;
+    r = EC_POINT_cmp(group, pa, pb, NULL);
+    if (r == 0)
+        return 1;
+    if (r == 1)
+        return 0;
+    return -2;
+}
+
+static int eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
+{
+    const unsigned char *p = NULL;
+    const void *pval;
+    int ptype, pklen;
+    EC_KEY *eckey = NULL;
+    const X509_ALGOR *palg;
+
+    if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
+        return 0;
+    X509_ALGOR_get0(NULL, &ptype, &pval, palg);
+
+    eckey = eckey_type2param(ptype, pval);
+
+    if (!eckey)
+        goto ecliberr;
+
+    /* We have parameters now set private key */
+    if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
+        ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
+        goto ecerr;
+    }
+
+    EVP_PKEY_assign_EC_KEY(pkey, eckey);
+    return 1;
+
+ ecliberr:
+    ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB);
+ ecerr:
+    EC_KEY_free(eckey);
+    return 0;
+}
+
+static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
+{
+    EC_KEY ec_key = *(pkey->pkey.ec);
+    unsigned char *ep, *p;
+    int eplen, ptype;
+    void *pval;
+    unsigned int old_flags;
+
+    if (!eckey_param2type(&ptype, &pval, &ec_key)) {
+        ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR);
+        return 0;
+    }
+
+    /* set the private key */
+
+    /*
+     * do not include the parameters in the SEC1 private key see PKCS#11
+     * 12.11
+     */
+    old_flags = EC_KEY_get_enc_flags(&ec_key);
+    EC_KEY_set_enc_flags(&ec_key, old_flags | EC_PKEY_NO_PARAMETERS);
+
+    eplen = i2d_ECPrivateKey(&ec_key, NULL);
+    if (!eplen) {
+        ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
+        return 0;
+    }
+    ep = OPENSSL_malloc(eplen);
+    if (ep == NULL) {
+        ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    p = ep;
+    if (!i2d_ECPrivateKey(&ec_key, &p)) {
+        OPENSSL_free(ep);
+        ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
+        return 0;
+    }
+
+    if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
+                         ptype, pval, ep, eplen)) {
+        OPENSSL_free(ep);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int int_ec_size(const EVP_PKEY *pkey)
+{
+    return ECDSA_size(pkey->pkey.ec);
+}
+
+static int ec_bits(const EVP_PKEY *pkey)
+{
+    return EC_GROUP_order_bits(EC_KEY_get0_group(pkey->pkey.ec));
+}
+
+static int ec_security_bits(const EVP_PKEY *pkey)
+{
+    int ecbits = ec_bits(pkey);
+    if (ecbits >= 512)
+        return 256;
+    if (ecbits >= 384)
+        return 192;
+    if (ecbits >= 256)
+        return 128;
+    if (ecbits >= 224)
+        return 112;
+    if (ecbits >= 160)
+        return 80;
+    return ecbits / 2;
+}
+
+static int ec_missing_parameters(const EVP_PKEY *pkey)
+{
+    if (pkey->pkey.ec == NULL || EC_KEY_get0_group(pkey->pkey.ec) == NULL)
+        return 1;
+    return 0;
+}
+
+static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+{
+    EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
+    if (group == NULL)
+        return 0;
+    if (to->pkey.ec == NULL) {
+        to->pkey.ec = EC_KEY_new();
+        if (to->pkey.ec == NULL)
+            return 0;
+    }
+    if (EC_KEY_set_group(to->pkey.ec, group) == 0)
+        return 0;
+    EC_GROUP_free(group);
+    return 1;
+}
+
+static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+    const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
+        *group_b = EC_KEY_get0_group(b->pkey.ec);
+    if (group_a == NULL || group_b == NULL)
+        return -2;
+    if (EC_GROUP_cmp(group_a, group_b, NULL))
+        return 0;
+    else
+        return 1;
+}
+
+static void int_ec_free(EVP_PKEY *pkey)
+{
+    EC_KEY_free(pkey->pkey.ec);
+}
+
+typedef enum {
+    EC_KEY_PRINT_PRIVATE,
+    EC_KEY_PRINT_PUBLIC,
+    EC_KEY_PRINT_PARAM
+} ec_print_t;
+
+static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, ec_print_t ktype)
+{
+    const char *ecstr;
+    unsigned char *priv = NULL, *pub = NULL;
+    size_t privlen = 0, publen = 0;
+    int ret = 0;
+    const EC_GROUP *group;
+
+    if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
+        ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if (ktype != EC_KEY_PRINT_PARAM && EC_KEY_get0_public_key(x) != NULL) {
+        publen = EC_KEY_key2buf(x, EC_KEY_get_conv_form(x), &pub, NULL);
+        if (publen == 0)
+            goto err;
+    }
+
+    if (ktype == EC_KEY_PRINT_PRIVATE && EC_KEY_get0_private_key(x) != NULL) {
+        privlen = EC_KEY_priv2buf(x, &priv);
+        if (privlen == 0)
+            goto err;
+    }
+
+    if (ktype == EC_KEY_PRINT_PRIVATE)
+        ecstr = "Private-Key";
+    else if (ktype == EC_KEY_PRINT_PUBLIC)
+        ecstr = "Public-Key";
+    else
+        ecstr = "ECDSA-Parameters";
+
+    if (!BIO_indent(bp, off, 128))
+        goto err;
+    if (BIO_printf(bp, "%s: (%d bit)\n", ecstr,
+                   EC_GROUP_order_bits(group)) <= 0)
+        goto err;
+
+    if (privlen != 0) {
+        if (BIO_printf(bp, "%*spriv:\n", off, "") <= 0)
+            goto err;
+        if (ASN1_buf_print(bp, priv, privlen, off + 4) == 0)
+            goto err;
+    }
+
+    if (publen != 0) {
+        if (BIO_printf(bp, "%*spub:\n", off, "") <= 0)
+            goto err;
+        if (ASN1_buf_print(bp, pub, publen, off + 4) == 0)
+            goto err;
+    }
+
+    if (!ECPKParameters_print(bp, group, off))
+        goto err;
+    ret = 1;
+ err:
+    if (!ret)
+        ECerr(EC_F_DO_EC_KEY_PRINT, ERR_R_EC_LIB);
+    OPENSSL_clear_free(priv, privlen);
+    OPENSSL_free(pub);
+    return ret;
+}
+
+static int eckey_param_decode(EVP_PKEY *pkey,
+                              const unsigned char **pder, int derlen)
+{
+    EC_KEY *eckey;
+
+    if ((eckey = d2i_ECParameters(NULL, pder, derlen)) == NULL) {
+        ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
+        return 0;
+    }
+    EVP_PKEY_assign_EC_KEY(pkey, eckey);
+    return 1;
+}
+
+static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
+{
+    return i2d_ECParameters(pkey->pkey.ec, pder);
+}
+
+static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                             ASN1_PCTX *ctx)
+{
+    return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PARAM);
+}
+
+static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                           ASN1_PCTX *ctx)
+{
+    return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PUBLIC);
+}
+
+static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                            ASN1_PCTX *ctx)
+{
+    return do_EC_KEY_print(bp, pkey->pkey.ec, indent, EC_KEY_PRINT_PRIVATE);
+}
+
+static int old_ec_priv_decode(EVP_PKEY *pkey,
+                              const unsigned char **pder, int derlen)
+{
+    EC_KEY *ec;
+
+    if ((ec = d2i_ECPrivateKey(NULL, pder, derlen)) == NULL) {
+        ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR);
+        return 0;
+    }
+    EVP_PKEY_assign_EC_KEY(pkey, ec);
+    return 1;
+}
+
+static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
+{
+    return i2d_ECPrivateKey(pkey->pkey.ec, pder);
+}
+
+static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+{
+    switch (op) {
+    case ASN1_PKEY_CTRL_PKCS7_SIGN:
+        if (arg1 == 0) {
+            int snid, hnid;
+            X509_ALGOR *alg1, *alg2;
+            PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
+            if (alg1 == NULL || alg1->algorithm == NULL)
+                return -1;
+            hnid = OBJ_obj2nid(alg1->algorithm);
+            if (hnid == NID_undef)
+                return -1;
+            if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
+                return -1;
+            X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
+        }
+        return 1;
+#ifndef OPENSSL_NO_CMS
+    case ASN1_PKEY_CTRL_CMS_SIGN:
+        if (arg1 == 0) {
+            int snid, hnid;
+            X509_ALGOR *alg1, *alg2;
+            CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
+            if (alg1 == NULL || alg1->algorithm == NULL)
+                return -1;
+            hnid = OBJ_obj2nid(alg1->algorithm);
+            if (hnid == NID_undef)
+                return -1;
+            if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
+                return -1;
+            X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
+        }
+        return 1;
+
+    case ASN1_PKEY_CTRL_CMS_ENVELOPE:
+        if (arg1 == 1)
+            return ecdh_cms_decrypt(arg2);
+        else if (arg1 == 0)
+            return ecdh_cms_encrypt(arg2);
+        return -2;
+
+    case ASN1_PKEY_CTRL_CMS_RI_TYPE:
+        *(int *)arg2 = CMS_RECIPINFO_AGREE;
+        return 1;
+#endif
+
+    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+        *(int *)arg2 = NID_sha256;
+        return 2;
+
+    case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
+        return EC_KEY_oct2key(EVP_PKEY_get0_EC_KEY(pkey), arg2, arg1, NULL);
+
+    case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
+        return EC_KEY_key2buf(EVP_PKEY_get0_EC_KEY(pkey),
+                              POINT_CONVERSION_UNCOMPRESSED, arg2, NULL);
+
+    default:
+        return -2;
+
+    }
+
+}
+
+const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
+    EVP_PKEY_EC,
+    EVP_PKEY_EC,
+    0,
+    "EC",
+    "OpenSSL EC algorithm",
+
+    eckey_pub_decode,
+    eckey_pub_encode,
+    eckey_pub_cmp,
+    eckey_pub_print,
+
+    eckey_priv_decode,
+    eckey_priv_encode,
+    eckey_priv_print,
+
+    int_ec_size,
+    ec_bits,
+    ec_security_bits,
+
+    eckey_param_decode,
+    eckey_param_encode,
+    ec_missing_parameters,
+    ec_copy_parameters,
+    ec_cmp_parameters,
+    eckey_param_print,
+    0,
+
+    int_ec_free,
+    ec_pkey_ctrl,
+    old_ec_priv_decode,
+    old_ec_priv_encode
+};
+
+int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
+{
+    int private = EC_KEY_get0_private_key(x) != NULL;
+
+    return do_EC_KEY_print(bp, x, off,
+                private ? EC_KEY_PRINT_PRIVATE : EC_KEY_PRINT_PUBLIC);
+}
+
+int ECParameters_print(BIO *bp, const EC_KEY *x)
+{
+    return do_EC_KEY_print(bp, x, 4, EC_KEY_PRINT_PARAM);
+}
+
+#ifndef OPENSSL_NO_CMS
+
+static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
+                                X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
+{
+    const ASN1_OBJECT *aoid;
+    int atype;
+    const void *aval;
+    int rv = 0;
+    EVP_PKEY *pkpeer = NULL;
+    EC_KEY *ecpeer = NULL;
+    const unsigned char *p;
+    int plen;
+    X509_ALGOR_get0(&aoid, &atype, &aval, alg);
+    if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey)
+        goto err;
+    /* If absent parameters get group from main key */
+    if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) {
+        const EC_GROUP *grp;
+        EVP_PKEY *pk;
+        pk = EVP_PKEY_CTX_get0_pkey(pctx);
+        if (!pk)
+            goto err;
+        grp = EC_KEY_get0_group(pk->pkey.ec);
+        ecpeer = EC_KEY_new();
+        if (ecpeer == NULL)
+            goto err;
+        if (!EC_KEY_set_group(ecpeer, grp))
+            goto err;
+    } else {
+        ecpeer = eckey_type2param(atype, aval);
+        if (!ecpeer)
+            goto err;
+    }
+    /* We have parameters now set public key */
+    plen = ASN1_STRING_length(pubkey);
+    p = ASN1_STRING_get0_data(pubkey);
+    if (!p || !plen)
+        goto err;
+    if (!o2i_ECPublicKey(&ecpeer, &p, plen))
+        goto err;
+    pkpeer = EVP_PKEY_new();
+    if (pkpeer == NULL)
+        goto err;
+    EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer);
+    if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
+        rv = 1;
+ err:
+    EC_KEY_free(ecpeer);
+    EVP_PKEY_free(pkpeer);
+    return rv;
+}
+
+/* Set KDF parameters based on KDF NID */
+static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid)
+{
+    int kdf_nid, kdfmd_nid, cofactor;
+    const EVP_MD *kdf_md;
+    if (eckdf_nid == NID_undef)
+        return 0;
+
+    /* Lookup KDF type, cofactor mode and digest */
+    if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid))
+        return 0;
+
+    if (kdf_nid == NID_dh_std_kdf)
+        cofactor = 0;
+    else if (kdf_nid == NID_dh_cofactor_kdf)
+        cofactor = 1;
+    else
+        return 0;
+
+    if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0)
+        return 0;
+
+    if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_62) <= 0)
+        return 0;
+
+    kdf_md = EVP_get_digestbynid(kdfmd_nid);
+    if (!kdf_md)
+        return 0;
+
+    if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
+        return 0;
+    return 1;
+}
+
+static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
+{
+    int rv = 0;
+
+    X509_ALGOR *alg, *kekalg = NULL;
+    ASN1_OCTET_STRING *ukm;
+    const unsigned char *p;
+    unsigned char *der = NULL;
+    int plen, keylen;
+    const EVP_CIPHER *kekcipher;
+    EVP_CIPHER_CTX *kekctx;
+
+    if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
+        return 0;
+
+    if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) {
+        ECerr(EC_F_ECDH_CMS_SET_SHARED_INFO, EC_R_KDF_PARAMETER_ERROR);
+        return 0;
+    }
+
+    if (alg->parameter->type != V_ASN1_SEQUENCE)
+        return 0;
+
+    p = alg->parameter->value.sequence->data;
+    plen = alg->parameter->value.sequence->length;
+    kekalg = d2i_X509_ALGOR(NULL, &p, plen);
+    if (!kekalg)
+        goto err;
+    kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
+    if (!kekctx)
+        goto err;
+    kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
+    if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
+        goto err;
+    if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
+        goto err;
+    if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
+        goto err;
+
+    keylen = EVP_CIPHER_CTX_key_length(kekctx);
+    if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
+        goto err;
+
+    plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen);
+
+    if (!plen)
+        goto err;
+
+    if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0)
+        goto err;
+    der = NULL;
+
+    rv = 1;
+ err:
+    X509_ALGOR_free(kekalg);
+    OPENSSL_free(der);
+    return rv;
+}
+
+static int ecdh_cms_decrypt(CMS_RecipientInfo *ri)
+{
+    EVP_PKEY_CTX *pctx;
+    pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+    if (!pctx)
+        return 0;
+    /* See if we need to set peer key */
+    if (!EVP_PKEY_CTX_get0_peerkey(pctx)) {
+        X509_ALGOR *alg;
+        ASN1_BIT_STRING *pubkey;
+        if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
+                                                 NULL, NULL, NULL))
+            return 0;
+        if (!alg || !pubkey)
+            return 0;
+        if (!ecdh_cms_set_peerkey(pctx, alg, pubkey)) {
+            ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_PEER_KEY_ERROR);
+            return 0;
+        }
+    }
+    /* Set ECDH derivation parameters and initialise unwrap context */
+    if (!ecdh_cms_set_shared_info(pctx, ri)) {
+        ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_SHARED_INFO_ERROR);
+        return 0;
+    }
+    return 1;
+}
+
+static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
+{
+    EVP_PKEY_CTX *pctx;
+    EVP_PKEY *pkey;
+    EVP_CIPHER_CTX *ctx;
+    int keylen;
+    X509_ALGOR *talg, *wrap_alg = NULL;
+    const ASN1_OBJECT *aoid;
+    ASN1_BIT_STRING *pubkey;
+    ASN1_STRING *wrap_str;
+    ASN1_OCTET_STRING *ukm;
+    unsigned char *penc = NULL;
+    int penclen;
+    int rv = 0;
+    int ecdh_nid, kdf_type, kdf_nid, wrap_nid;
+    const EVP_MD *kdf_md;
+    pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+    if (!pctx)
+        return 0;
+    /* Get ephemeral key */
+    pkey = EVP_PKEY_CTX_get0_pkey(pctx);
+    if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
+                                             NULL, NULL, NULL))
+        goto err;
+    X509_ALGOR_get0(&aoid, NULL, NULL, talg);
+    /* Is everything uninitialised? */
+    if (aoid == OBJ_nid2obj(NID_undef)) {
+
+        EC_KEY *eckey = pkey->pkey.ec;
+        /* Set the key */
+        unsigned char *p;
+
+        penclen = i2o_ECPublicKey(eckey, NULL);
+        if (penclen <= 0)
+            goto err;
+        penc = OPENSSL_malloc(penclen);
+        if (penc == NULL)
+            goto err;
+        p = penc;
+        penclen = i2o_ECPublicKey(eckey, &p);
+        if (penclen <= 0)
+            goto err;
+        ASN1_STRING_set0(pubkey, penc, penclen);
+        pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+        pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+
+        penc = NULL;
+        X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
+                        V_ASN1_UNDEF, NULL);
+    }
+
+    /* See if custom parameters set */
+    kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx);
+    if (kdf_type <= 0)
+        goto err;
+    if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md))
+        goto err;
+    ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx);
+    if (ecdh_nid < 0)
+        goto err;
+    else if (ecdh_nid == 0)
+        ecdh_nid = NID_dh_std_kdf;
+    else if (ecdh_nid == 1)
+        ecdh_nid = NID_dh_cofactor_kdf;
+
+    if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) {
+        kdf_type = EVP_PKEY_ECDH_KDF_X9_62;
+        if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0)
+            goto err;
+    } else
+        /* Unknown KDF */
+        goto err;
+    if (kdf_md == NULL) {
+        /* Fixme later for better MD */
+        kdf_md = EVP_sha1();
+        if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
+            goto err;
+    }
+
+    if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
+        goto err;
+
+    /* Lookup NID for KDF+cofactor+digest */
+
+    if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid))
+        goto err;
+    /* Get wrap NID */
+    ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
+    wrap_nid = EVP_CIPHER_CTX_type(ctx);
+    keylen = EVP_CIPHER_CTX_key_length(ctx);
+
+    /* Package wrap algorithm in an AlgorithmIdentifier */
+
+    wrap_alg = X509_ALGOR_new();
+    if (wrap_alg == NULL)
+        goto err;
+    wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
+    wrap_alg->parameter = ASN1_TYPE_new();
+    if (wrap_alg->parameter == NULL)
+        goto err;
+    if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
+        goto err;
+    if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
+        ASN1_TYPE_free(wrap_alg->parameter);
+        wrap_alg->parameter = NULL;
+    }
+
+    if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
+        goto err;
+
+    penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen);
+
+    if (!penclen)
+        goto err;
+
+    if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0)
+        goto err;
+    penc = NULL;
+
+    /*
+     * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
+     * of another AlgorithmIdentifier.
+     */
+    penclen = i2d_X509_ALGOR(wrap_alg, &penc);
+    if (!penc || !penclen)
+        goto err;
+    wrap_str = ASN1_STRING_new();
+    if (wrap_str == NULL)
+        goto err;
+    ASN1_STRING_set0(wrap_str, penc, penclen);
+    penc = NULL;
+    X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str);
+
+    rv = 1;
+
+ err:
+    OPENSSL_free(penc);
+    X509_ALGOR_free(wrap_alg);
+    return rv;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_asn1.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_asn1.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_asn1.c	(revision 331)
@@ -0,0 +1,1234 @@
+/*
+ * Copyright 2002-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 <string.h>
+#include "ec_lcl.h"
+#include <openssl/err.h>
+#include <openssl/asn1t.h>
+#include <openssl/objects.h>
+
+int EC_GROUP_get_basis_type(const EC_GROUP *group)
+{
+    int i = 0;
+
+    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
+        NID_X9_62_characteristic_two_field)
+        /* everything else is currently not supported */
+        return 0;
+
+    while (group->poly[i] != 0)
+        i++;
+
+    if (i == 4)
+        return NID_X9_62_ppBasis;
+    else if (i == 2)
+        return NID_X9_62_tpBasis;
+    else
+        /* everything else is currently not supported */
+        return 0;
+}
+
+#ifndef OPENSSL_NO_EC2M
+int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
+{
+    if (group == NULL)
+        return 0;
+
+    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
+        NID_X9_62_characteristic_two_field
+        || !((group->poly[0] != 0) && (group->poly[1] != 0)
+             && (group->poly[2] == 0))) {
+        ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS,
+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+
+    if (k)
+        *k = group->poly[1];
+
+    return 1;
+}
+
+int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
+                                   unsigned int *k2, unsigned int *k3)
+{
+    if (group == NULL)
+        return 0;
+
+    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
+        NID_X9_62_characteristic_two_field
+        || !((group->poly[0] != 0) && (group->poly[1] != 0)
+             && (group->poly[2] != 0) && (group->poly[3] != 0)
+             && (group->poly[4] == 0))) {
+        ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS,
+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+
+    if (k1)
+        *k1 = group->poly[3];
+    if (k2)
+        *k2 = group->poly[2];
+    if (k3)
+        *k3 = group->poly[1];
+
+    return 1;
+}
+#endif
+
+/* some structures needed for the asn1 encoding */
+typedef struct x9_62_pentanomial_st {
+    long k1;
+    long k2;
+    long k3;
+} X9_62_PENTANOMIAL;
+
+typedef struct x9_62_characteristic_two_st {
+    long m;
+    ASN1_OBJECT *type;
+    union {
+        char *ptr;
+        /* NID_X9_62_onBasis */
+        ASN1_NULL *onBasis;
+        /* NID_X9_62_tpBasis */
+        ASN1_INTEGER *tpBasis;
+        /* NID_X9_62_ppBasis */
+        X9_62_PENTANOMIAL *ppBasis;
+        /* anything else */
+        ASN1_TYPE *other;
+    } p;
+} X9_62_CHARACTERISTIC_TWO;
+
+typedef struct x9_62_fieldid_st {
+    ASN1_OBJECT *fieldType;
+    union {
+        char *ptr;
+        /* NID_X9_62_prime_field */
+        ASN1_INTEGER *prime;
+        /* NID_X9_62_characteristic_two_field */
+        X9_62_CHARACTERISTIC_TWO *char_two;
+        /* anything else */
+        ASN1_TYPE *other;
+    } p;
+} X9_62_FIELDID;
+
+typedef struct x9_62_curve_st {
+    ASN1_OCTET_STRING *a;
+    ASN1_OCTET_STRING *b;
+    ASN1_BIT_STRING *seed;
+} X9_62_CURVE;
+
+struct ec_parameters_st {
+    long version;
+    X9_62_FIELDID *fieldID;
+    X9_62_CURVE *curve;
+    ASN1_OCTET_STRING *base;
+    ASN1_INTEGER *order;
+    ASN1_INTEGER *cofactor;
+} /* ECPARAMETERS */ ;
+
+struct ecpk_parameters_st {
+    int type;
+    union {
+        ASN1_OBJECT *named_curve;
+        ECPARAMETERS *parameters;
+        ASN1_NULL *implicitlyCA;
+    } value;
+} /* ECPKPARAMETERS */ ;
+
+/* SEC1 ECPrivateKey */
+typedef struct ec_privatekey_st {
+    long version;
+    ASN1_OCTET_STRING *privateKey;
+    ECPKPARAMETERS *parameters;
+    ASN1_BIT_STRING *publicKey;
+} EC_PRIVATEKEY;
+
+/* the OpenSSL ASN.1 definitions */
+ASN1_SEQUENCE(X9_62_PENTANOMIAL) = {
+        ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG),
+        ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG),
+        ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG)
+} static_ASN1_SEQUENCE_END(X9_62_PENTANOMIAL)
+
+DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL)
+
+ASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY);
+
+ASN1_ADB(X9_62_CHARACTERISTIC_TWO) = {
+        ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)),
+        ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)),
+        ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL))
+} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL);
+
+ASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = {
+        ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG),
+        ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT),
+        ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO)
+} static_ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO)
+
+DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO)
+
+ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY);
+
+ASN1_ADB(X9_62_FIELDID) = {
+        ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)),
+        ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO))
+} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL);
+
+ASN1_SEQUENCE(X9_62_FIELDID) = {
+        ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT),
+        ASN1_ADB_OBJECT(X9_62_FIELDID)
+} static_ASN1_SEQUENCE_END(X9_62_FIELDID)
+
+ASN1_SEQUENCE(X9_62_CURVE) = {
+        ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING),
+        ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING),
+        ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING)
+} static_ASN1_SEQUENCE_END(X9_62_CURVE)
+
+ASN1_SEQUENCE(ECPARAMETERS) = {
+        ASN1_SIMPLE(ECPARAMETERS, version, LONG),
+        ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID),
+        ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE),
+        ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING),
+        ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER),
+        ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(ECPARAMETERS)
+
+DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
+
+ASN1_CHOICE(ECPKPARAMETERS) = {
+        ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT),
+        ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS),
+        ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL)
+} ASN1_CHOICE_END(ECPKPARAMETERS)
+
+DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS)
+IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
+
+ASN1_SEQUENCE(EC_PRIVATEKEY) = {
+        ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
+        ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
+        ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
+        ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
+} static_ASN1_SEQUENCE_END(EC_PRIVATEKEY)
+
+DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY)
+IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
+
+/* some declarations of internal function */
+
+/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */
+static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *);
+/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */
+static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *);
+
+/* the function definitions */
+
+static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field)
+{
+    int ok = 0, nid;
+    BIGNUM *tmp = NULL;
+
+    if (group == NULL || field == NULL)
+        return 0;
+
+    /* clear the old values (if necessary) */
+    ASN1_OBJECT_free(field->fieldType);
+    ASN1_TYPE_free(field->p.other);
+
+    nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
+    /* set OID for the field */
+    if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) {
+        ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
+        goto err;
+    }
+
+    if (nid == NID_X9_62_prime_field) {
+        if ((tmp = BN_new()) == NULL) {
+            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        /* the parameters are specified by the prime number p */
+        if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL)) {
+            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
+            goto err;
+        }
+        /* set the prime number */
+        field->p.prime = BN_to_ASN1_INTEGER(tmp, NULL);
+        if (field->p.prime == NULL) {
+            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
+            goto err;
+        }
+    } else if (nid == NID_X9_62_characteristic_two_field)
+#ifdef OPENSSL_NO_EC2M
+    {
+        ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED);
+        goto err;
+    }
+#else
+    {
+        int field_type;
+        X9_62_CHARACTERISTIC_TWO *char_two;
+
+        field->p.char_two = X9_62_CHARACTERISTIC_TWO_new();
+        char_two = field->p.char_two;
+
+        if (char_two == NULL) {
+            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+
+        char_two->m = (long)EC_GROUP_get_degree(group);
+
+        field_type = EC_GROUP_get_basis_type(group);
+
+        if (field_type == 0) {
+            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB);
+            goto err;
+        }
+        /* set base type OID */
+        if ((char_two->type = OBJ_nid2obj(field_type)) == NULL) {
+            ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB);
+            goto err;
+        }
+
+        if (field_type == NID_X9_62_tpBasis) {
+            unsigned int k;
+
+            if (!EC_GROUP_get_trinomial_basis(group, &k))
+                goto err;
+
+            char_two->p.tpBasis = ASN1_INTEGER_new();
+            if (char_two->p.tpBasis == NULL) {
+                ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k)) {
+                ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB);
+                goto err;
+            }
+        } else if (field_type == NID_X9_62_ppBasis) {
+            unsigned int k1, k2, k3;
+
+            if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3))
+                goto err;
+
+            char_two->p.ppBasis = X9_62_PENTANOMIAL_new();
+            if (char_two->p.ppBasis == NULL) {
+                ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+
+            /* set k? values */
+            char_two->p.ppBasis->k1 = (long)k1;
+            char_two->p.ppBasis->k2 = (long)k2;
+            char_two->p.ppBasis->k3 = (long)k3;
+        } else {                /* field_type == NID_X9_62_onBasis */
+
+            /* for ONB the parameters are (asn1) NULL */
+            char_two->p.onBasis = ASN1_NULL_new();
+            if (char_two->p.onBasis == NULL) {
+                ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+        }
+    }
+#endif
+    else {
+        ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_UNSUPPORTED_FIELD);
+        goto err;
+    }
+
+    ok = 1;
+
+ err:
+    BN_free(tmp);
+    return (ok);
+}
+
+static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
+{
+    int ok = 0, nid;
+    BIGNUM *tmp_1 = NULL, *tmp_2 = NULL;
+    unsigned char *buffer_1 = NULL, *buffer_2 = NULL,
+        *a_buf = NULL, *b_buf = NULL;
+    size_t len_1, len_2;
+    unsigned char char_zero = 0;
+
+    if (!group || !curve || !curve->a || !curve->b)
+        return 0;
+
+    if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) {
+        ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
+
+    /* get a and b */
+    if (nid == NID_X9_62_prime_field) {
+        if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL)) {
+            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
+            goto err;
+        }
+    }
+#ifndef OPENSSL_NO_EC2M
+    else {                      /* nid == NID_X9_62_characteristic_two_field */
+
+        if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL)) {
+            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB);
+            goto err;
+        }
+    }
+#endif
+    len_1 = (size_t)BN_num_bytes(tmp_1);
+    len_2 = (size_t)BN_num_bytes(tmp_2);
+
+    if (len_1 == 0) {
+        /* len_1 == 0 => a == 0 */
+        a_buf = &char_zero;
+        len_1 = 1;
+    } else {
+        if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL) {
+            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        if ((len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0) {
+            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
+            goto err;
+        }
+        a_buf = buffer_1;
+    }
+
+    if (len_2 == 0) {
+        /* len_2 == 0 => b == 0 */
+        b_buf = &char_zero;
+        len_2 = 1;
+    } else {
+        if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL) {
+            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        if ((len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0) {
+            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB);
+            goto err;
+        }
+        b_buf = buffer_2;
+    }
+
+    /* set a and b */
+    if (!ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) ||
+        !ASN1_OCTET_STRING_set(curve->b, b_buf, len_2)) {
+        ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
+        goto err;
+    }
+
+    /* set the seed (optional) */
+    if (group->seed) {
+        if (!curve->seed)
+            if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) {
+                ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+        curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+        curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+        if (!ASN1_BIT_STRING_set(curve->seed, group->seed,
+                                 (int)group->seed_len)) {
+            ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB);
+            goto err;
+        }
+    } else {
+        ASN1_BIT_STRING_free(curve->seed);
+        curve->seed = NULL;
+    }
+
+    ok = 1;
+
+ err:
+    OPENSSL_free(buffer_1);
+    OPENSSL_free(buffer_2);
+    BN_free(tmp_1);
+    BN_free(tmp_2);
+    return (ok);
+}
+
+ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group,
+                                               ECPARAMETERS *params)
+{
+    size_t len = 0;
+    ECPARAMETERS *ret = NULL;
+    const BIGNUM *tmp;
+    unsigned char *buffer = NULL;
+    const EC_POINT *point = NULL;
+    point_conversion_form_t form;
+
+    if (params == NULL) {
+        if ((ret = ECPARAMETERS_new()) == NULL) {
+            ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    } else
+        ret = params;
+
+    /* set the version (always one) */
+    ret->version = (long)0x1;
+
+    /* set the fieldID */
+    if (!ec_asn1_group2fieldid(group, ret->fieldID)) {
+        ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_EC_LIB);
+        goto err;
+    }
+
+    /* set the curve */
+    if (!ec_asn1_group2curve(group, ret->curve)) {
+        ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_EC_LIB);
+        goto err;
+    }
+
+    /* set the base point */
+    if ((point = EC_GROUP_get0_generator(group)) == NULL) {
+        ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, EC_R_UNDEFINED_GENERATOR);
+        goto err;
+    }
+
+    form = EC_GROUP_get_point_conversion_form(group);
+
+    len = EC_POINT_point2buf(group, point, form, &buffer, NULL);
+    if (len == 0) {
+        ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_EC_LIB);
+        goto err;
+    }
+    if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) {
+        OPENSSL_free(buffer);
+        ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    ASN1_STRING_set0(ret->base, buffer, len);
+
+    /* set the order */
+    tmp = EC_GROUP_get0_order(group);
+    if (tmp == NULL) {
+        ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_EC_LIB);
+        goto err;
+    }
+    ret->order = BN_to_ASN1_INTEGER(tmp, ret->order);
+    if (ret->order == NULL) {
+        ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_ASN1_LIB);
+        goto err;
+    }
+
+    /* set the cofactor (optional) */
+    tmp = EC_GROUP_get0_cofactor(group);
+    if (tmp != NULL) {
+        ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor);
+        if (ret->cofactor == NULL) {
+            ECerr(EC_F_EC_GROUP_GET_ECPARAMETERS, ERR_R_ASN1_LIB);
+            goto err;
+        }
+    }
+
+    return ret;
+
+ err:
+    if (params == NULL)
+        ECPARAMETERS_free(ret);
+    return NULL;
+}
+
+ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group,
+                                            ECPKPARAMETERS *params)
+{
+    int ok = 1, tmp;
+    ECPKPARAMETERS *ret = params;
+
+    if (ret == NULL) {
+        if ((ret = ECPKPARAMETERS_new()) == NULL) {
+            ECerr(EC_F_EC_GROUP_GET_ECPKPARAMETERS, ERR_R_MALLOC_FAILURE);
+            return NULL;
+        }
+    } else {
+        if (ret->type == 0)
+            ASN1_OBJECT_free(ret->value.named_curve);
+        else if (ret->type == 1 && ret->value.parameters)
+            ECPARAMETERS_free(ret->value.parameters);
+    }
+
+    if (EC_GROUP_get_asn1_flag(group)) {
+        /*
+         * use the asn1 OID to describe the the elliptic curve parameters
+         */
+        tmp = EC_GROUP_get_curve_name(group);
+        if (tmp) {
+            ret->type = 0;
+            if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL)
+                ok = 0;
+        } else
+            /* we don't know the nid => ERROR */
+            ok = 0;
+    } else {
+        /* use the ECPARAMETERS structure */
+        ret->type = 1;
+        if ((ret->value.parameters =
+             EC_GROUP_get_ecparameters(group, NULL)) == NULL)
+            ok = 0;
+    }
+
+    if (!ok) {
+        ECPKPARAMETERS_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params)
+{
+    int ok = 0, tmp;
+    EC_GROUP *ret = NULL;
+    BIGNUM *p = NULL, *a = NULL, *b = NULL;
+    EC_POINT *point = NULL;
+    long field_bits;
+
+    if (!params->fieldID || !params->fieldID->fieldType ||
+        !params->fieldID->p.ptr) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
+        goto err;
+    }
+
+    /* now extract the curve parameters a and b */
+    if (!params->curve || !params->curve->a ||
+        !params->curve->a->data || !params->curve->b ||
+        !params->curve->b->data) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
+        goto err;
+    }
+    a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL);
+    if (a == NULL) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_BN_LIB);
+        goto err;
+    }
+    b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL);
+    if (b == NULL) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_BN_LIB);
+        goto err;
+    }
+
+    /* get the field parameters */
+    tmp = OBJ_obj2nid(params->fieldID->fieldType);
+    if (tmp == NID_X9_62_characteristic_two_field)
+#ifdef OPENSSL_NO_EC2M
+    {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_GF2M_NOT_SUPPORTED);
+        goto err;
+    }
+#else
+    {
+        X9_62_CHARACTERISTIC_TWO *char_two;
+
+        char_two = params->fieldID->p.char_two;
+
+        field_bits = char_two->m;
+        if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_FIELD_TOO_LARGE);
+            goto err;
+        }
+
+        if ((p = BN_new()) == NULL) {
+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+
+        /* get the base type */
+        tmp = OBJ_obj2nid(char_two->type);
+
+        if (tmp == NID_X9_62_tpBasis) {
+            long tmp_long;
+
+            if (!char_two->p.tpBasis) {
+                ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
+                goto err;
+            }
+
+            tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis);
+
+            if (!(char_two->m > tmp_long && tmp_long > 0)) {
+                ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS,
+                      EC_R_INVALID_TRINOMIAL_BASIS);
+                goto err;
+            }
+
+            /* create the polynomial */
+            if (!BN_set_bit(p, (int)char_two->m))
+                goto err;
+            if (!BN_set_bit(p, (int)tmp_long))
+                goto err;
+            if (!BN_set_bit(p, 0))
+                goto err;
+        } else if (tmp == NID_X9_62_ppBasis) {
+            X9_62_PENTANOMIAL *penta;
+
+            penta = char_two->p.ppBasis;
+            if (!penta) {
+                ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
+                goto err;
+            }
+
+            if (!
+                (char_two->m > penta->k3 && penta->k3 > penta->k2
+                 && penta->k2 > penta->k1 && penta->k1 > 0)) {
+                ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS,
+                      EC_R_INVALID_PENTANOMIAL_BASIS);
+                goto err;
+            }
+
+            /* create the polynomial */
+            if (!BN_set_bit(p, (int)char_two->m))
+                goto err;
+            if (!BN_set_bit(p, (int)penta->k1))
+                goto err;
+            if (!BN_set_bit(p, (int)penta->k2))
+                goto err;
+            if (!BN_set_bit(p, (int)penta->k3))
+                goto err;
+            if (!BN_set_bit(p, 0))
+                goto err;
+        } else if (tmp == NID_X9_62_onBasis) {
+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_NOT_IMPLEMENTED);
+            goto err;
+        } else {                /* error */
+
+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
+            goto err;
+        }
+
+        /* create the EC_GROUP structure */
+        ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
+    }
+#endif
+    else if (tmp == NID_X9_62_prime_field) {
+        /* we have a curve over a prime field */
+        /* extract the prime number */
+        if (!params->fieldID->p.prime) {
+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
+            goto err;
+        }
+        p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL);
+        if (p == NULL) {
+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_ASN1_LIB);
+            goto err;
+        }
+
+        if (BN_is_negative(p) || BN_is_zero(p)) {
+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_INVALID_FIELD);
+            goto err;
+        }
+
+        field_bits = BN_num_bits(p);
+        if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_FIELD_TOO_LARGE);
+            goto err;
+        }
+
+        /* create the EC_GROUP structure */
+        ret = EC_GROUP_new_curve_GFp(p, a, b, NULL);
+    } else {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_INVALID_FIELD);
+        goto err;
+    }
+
+    if (ret == NULL) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB);
+        goto err;
+    }
+
+    /* extract seed (optional) */
+    if (params->curve->seed != NULL) {
+        OPENSSL_free(ret->seed);
+        if ((ret->seed = OPENSSL_malloc(params->curve->seed->length)) == NULL) {
+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        memcpy(ret->seed, params->curve->seed->data,
+               params->curve->seed->length);
+        ret->seed_len = params->curve->seed->length;
+    }
+
+    if (!params->order || !params->base || !params->base->data) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
+        goto err;
+    }
+
+    if ((point = EC_POINT_new(ret)) == NULL)
+        goto err;
+
+    /* set the point conversion form */
+    EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t)
+                                       (params->base->data[0] & ~0x01));
+
+    /* extract the ec point */
+    if (!EC_POINT_oct2point(ret, point, params->base->data,
+                            params->base->length, NULL)) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB);
+        goto err;
+    }
+
+    /* extract the order */
+    if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_ASN1_LIB);
+        goto err;
+    }
+    if (BN_is_negative(a) || BN_is_zero(a)) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_INVALID_GROUP_ORDER);
+        goto err;
+    }
+    if (BN_num_bits(a) > (int)field_bits + 1) { /* Hasse bound */
+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_INVALID_GROUP_ORDER);
+        goto err;
+    }
+
+    /* extract the cofactor (optional) */
+    if (params->cofactor == NULL) {
+        BN_free(b);
+        b = NULL;
+    } else if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_ASN1_LIB);
+        goto err;
+    }
+    /* set the generator, order and cofactor (if present) */
+    if (!EC_GROUP_set_generator(ret, point, a, b)) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, ERR_R_EC_LIB);
+        goto err;
+    }
+
+    ok = 1;
+
+ err:
+    if (!ok) {
+        EC_GROUP_clear_free(ret);
+        ret = NULL;
+    }
+
+    BN_free(p);
+    BN_free(a);
+    BN_free(b);
+    EC_POINT_free(point);
+    return (ret);
+}
+
+EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params)
+{
+    EC_GROUP *ret = NULL;
+    int tmp = 0;
+
+    if (params == NULL) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, EC_R_MISSING_PARAMETERS);
+        return NULL;
+    }
+
+    if (params->type == 0) {    /* the curve is given by an OID */
+        tmp = OBJ_obj2nid(params->value.named_curve);
+        if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) {
+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS,
+                  EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
+            return NULL;
+        }
+        EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE);
+    } else if (params->type == 1) { /* the parameters are given by a
+                                     * ECPARAMETERS structure */
+        ret = EC_GROUP_new_from_ecparameters(params->value.parameters);
+        if (!ret) {
+            ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, ERR_R_EC_LIB);
+            return NULL;
+        }
+        EC_GROUP_set_asn1_flag(ret, 0x0);
+    } else if (params->type == 2) { /* implicitlyCA */
+        return NULL;
+    } else {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS, EC_R_ASN1_ERROR);
+        return NULL;
+    }
+
+    return ret;
+}
+
+/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */
+
+EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
+{
+    EC_GROUP *group = NULL;
+    ECPKPARAMETERS *params = NULL;
+    const unsigned char *p = *in;
+
+    if ((params = d2i_ECPKPARAMETERS(NULL, &p, len)) == NULL) {
+        ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE);
+        ECPKPARAMETERS_free(params);
+        return NULL;
+    }
+
+    if ((group = EC_GROUP_new_from_ecpkparameters(params)) == NULL) {
+        ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE);
+        ECPKPARAMETERS_free(params);
+        return NULL;
+    }
+
+    if (a) {
+        EC_GROUP_clear_free(*a);
+        *a = group;
+    }
+
+    ECPKPARAMETERS_free(params);
+    *in = p;
+    return (group);
+}
+
+int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
+{
+    int ret = 0;
+    ECPKPARAMETERS *tmp = EC_GROUP_get_ecpkparameters(a, NULL);
+    if (tmp == NULL) {
+        ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
+        return 0;
+    }
+    if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) {
+        ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
+        ECPKPARAMETERS_free(tmp);
+        return 0;
+    }
+    ECPKPARAMETERS_free(tmp);
+    return (ret);
+}
+
+/* some EC_KEY functions */
+
+EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
+{
+    EC_KEY *ret = NULL;
+    EC_PRIVATEKEY *priv_key = NULL;
+    const unsigned char *p = *in;
+
+    if ((priv_key = d2i_EC_PRIVATEKEY(NULL, &p, len)) == NULL) {
+        ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+        return NULL;
+    }
+
+    if (a == NULL || *a == NULL) {
+        if ((ret = EC_KEY_new()) == NULL) {
+            ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    } else
+        ret = *a;
+
+    if (priv_key->parameters) {
+        EC_GROUP_clear_free(ret->group);
+        ret->group = EC_GROUP_new_from_ecpkparameters(priv_key->parameters);
+    }
+
+    if (ret->group == NULL) {
+        ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+        goto err;
+    }
+
+    ret->version = priv_key->version;
+
+    if (priv_key->privateKey) {
+        ASN1_OCTET_STRING *pkey = priv_key->privateKey;
+        if (EC_KEY_oct2priv(ret, ASN1_STRING_get0_data(pkey),
+                            ASN1_STRING_length(pkey)) == 0)
+            goto err;
+    } else {
+        ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_MISSING_PRIVATE_KEY);
+        goto err;
+    }
+
+    EC_POINT_clear_free(ret->pub_key);
+    ret->pub_key = EC_POINT_new(ret->group);
+    if (ret->pub_key == NULL) {
+        ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+        goto err;
+    }
+
+    if (priv_key->publicKey) {
+        const unsigned char *pub_oct;
+        int pub_oct_len;
+
+        pub_oct = ASN1_STRING_get0_data(priv_key->publicKey);
+        pub_oct_len = ASN1_STRING_length(priv_key->publicKey);
+        if (!EC_KEY_oct2key(ret, pub_oct, pub_oct_len, NULL)) {
+            ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+            goto err;
+        }
+    } else {
+        if (ret->group->meth->keygenpub == NULL
+            || ret->group->meth->keygenpub(ret) == 0)
+                goto err;
+        /* Remember the original private-key-only encoding. */
+        ret->enc_flag |= EC_PKEY_NO_PUBKEY;
+    }
+
+    if (a)
+        *a = ret;
+    EC_PRIVATEKEY_free(priv_key);
+    *in = p;
+    return (ret);
+
+ err:
+    if (a == NULL || *a != ret)
+        EC_KEY_free(ret);
+    EC_PRIVATEKEY_free(priv_key);
+    return NULL;
+}
+
+int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
+{
+    int ret = 0, ok = 0;
+    unsigned char *priv= NULL, *pub= NULL;
+    size_t privlen = 0, publen = 0;
+
+    EC_PRIVATEKEY *priv_key = NULL;
+
+    if (a == NULL || a->group == NULL ||
+        (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) {
+        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
+        goto err;
+    }
+
+    if ((priv_key = EC_PRIVATEKEY_new()) == NULL) {
+        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    priv_key->version = a->version;
+
+    privlen = EC_KEY_priv2buf(a, &priv);
+
+    if (privlen == 0) {
+        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
+        goto err;
+    }
+
+    ASN1_STRING_set0(priv_key->privateKey, priv, privlen);
+    priv = NULL;
+
+    if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) {
+        if ((priv_key->parameters =
+             EC_GROUP_get_ecpkparameters(a->group,
+                                        priv_key->parameters)) == NULL) {
+            ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
+            goto err;
+        }
+    }
+
+    if (!(a->enc_flag & EC_PKEY_NO_PUBKEY)) {
+        priv_key->publicKey = ASN1_BIT_STRING_new();
+        if (priv_key->publicKey == NULL) {
+            ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+
+        publen = EC_KEY_key2buf(a, a->conv_form, &pub, NULL);
+
+        if (publen == 0) {
+            ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
+            goto err;
+        }
+
+        priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+        priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+        ASN1_STRING_set0(priv_key->publicKey, pub, publen);
+        pub = NULL;
+    }
+
+    if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) {
+        ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
+        goto err;
+    }
+    ok = 1;
+ err:
+    OPENSSL_clear_free(priv, privlen);
+    OPENSSL_free(pub);
+    EC_PRIVATEKEY_free(priv_key);
+    return (ok ? ret : 0);
+}
+
+int i2d_ECParameters(EC_KEY *a, unsigned char **out)
+{
+    if (a == NULL) {
+        ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    return i2d_ECPKParameters(a->group, out);
+}
+
+EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len)
+{
+    EC_KEY *ret;
+
+    if (in == NULL || *in == NULL) {
+        ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
+        return NULL;
+    }
+
+    if (a == NULL || *a == NULL) {
+        if ((ret = EC_KEY_new()) == NULL) {
+            ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
+            return NULL;
+        }
+    } else
+        ret = *a;
+
+    if (!d2i_ECPKParameters(&ret->group, in, len)) {
+        ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
+        if (a == NULL || *a != ret)
+             EC_KEY_free(ret);
+        return NULL;
+    }
+
+    if (a)
+        *a = ret;
+
+    return ret;
+}
+
+EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len)
+{
+    EC_KEY *ret = NULL;
+
+    if (a == NULL || (*a) == NULL || (*a)->group == NULL) {
+        /*
+         * sorry, but a EC_GROUP-structure is necessary to set the public key
+         */
+        ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    ret = *a;
+    if (!EC_KEY_oct2key(ret, *in, len, NULL)) {
+        ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB);
+        return 0;
+    }
+    *in += len;
+    return ret;
+}
+
+int i2o_ECPublicKey(const EC_KEY *a, unsigned char **out)
+{
+    size_t buf_len = 0;
+    int new_buffer = 0;
+
+    if (a == NULL) {
+        ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    buf_len = EC_POINT_point2oct(a->group, a->pub_key,
+                                 a->conv_form, NULL, 0, NULL);
+
+    if (out == NULL || buf_len == 0)
+        /* out == NULL => just return the length of the octet string */
+        return buf_len;
+
+    if (*out == NULL) {
+        if ((*out = OPENSSL_malloc(buf_len)) == NULL) {
+            ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        new_buffer = 1;
+    }
+    if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
+                            *out, buf_len, NULL)) {
+        ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
+        if (new_buffer) {
+            OPENSSL_free(*out);
+            *out = NULL;
+        }
+        return 0;
+    }
+    if (!new_buffer)
+        *out += buf_len;
+    return buf_len;
+}
+
+ASN1_SEQUENCE(ECDSA_SIG) = {
+        ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM),
+        ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM)
+} static_ASN1_SEQUENCE_END(ECDSA_SIG)
+
+DECLARE_ASN1_FUNCTIONS_const(ECDSA_SIG)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSA_SIG, ECDSA_SIG)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ECDSA_SIG, ECDSA_SIG, ECDSA_SIG)
+
+ECDSA_SIG *ECDSA_SIG_new(void)
+{
+    ECDSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig));
+    if (sig == NULL)
+        ECerr(EC_F_ECDSA_SIG_NEW, ERR_R_MALLOC_FAILURE);
+    return sig;
+}
+
+void ECDSA_SIG_free(ECDSA_SIG *sig)
+{
+    if (sig == NULL)
+        return;
+    BN_clear_free(sig->r);
+    BN_clear_free(sig->s);
+    OPENSSL_free(sig);
+}
+
+void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
+{
+    if (pr != NULL)
+        *pr = sig->r;
+    if (ps != NULL)
+        *ps = sig->s;
+}
+
+int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
+{
+    if (r == NULL || s == NULL)
+        return 0;
+    BN_clear_free(sig->r);
+    BN_clear_free(sig->s);
+    sig->r = r;
+    sig->s = s;
+    return 1;
+}
+
+int ECDSA_size(const EC_KEY *r)
+{
+    int ret, i;
+    ASN1_INTEGER bs;
+    unsigned char buf[4];
+    const EC_GROUP *group;
+
+    if (r == NULL)
+        return 0;
+    group = EC_KEY_get0_group(r);
+    if (group == NULL)
+        return 0;
+
+    i = EC_GROUP_order_bits(group);
+    if (i == 0)
+        return 0;
+    bs.length = (i + 7) / 8;
+    bs.data = buf;
+    bs.type = V_ASN1_INTEGER;
+    /* If the top bit is set the asn1 encoding is 1 larger. */
+    buf[0] = 0xff;
+
+    i = i2d_ASN1_INTEGER(&bs, NULL);
+    i += i;                     /* r and s */
+    ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_check.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_check.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_check.c	(revision 331)
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2002-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 "ec_lcl.h"
+#include <openssl/err.h>
+
+int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
+{
+    int ret = 0;
+    const BIGNUM *order;
+    BN_CTX *new_ctx = NULL;
+    EC_POINT *point = NULL;
+
+    /* Custom curves assumed to be correct */
+    if ((group->meth->flags & EC_FLAGS_CUSTOM_CURVE) != 0)
+        return 1;
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL) {
+            ECerr(EC_F_EC_GROUP_CHECK, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    }
+
+    /* check the discriminant */
+    if (!EC_GROUP_check_discriminant(group, ctx)) {
+        ECerr(EC_F_EC_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO);
+        goto err;
+    }
+
+    /* check the generator */
+    if (group->generator == NULL) {
+        ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);
+        goto err;
+    }
+    if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) {
+        ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);
+        goto err;
+    }
+
+    /* check the order of the generator */
+    if ((point = EC_POINT_new(group)) == NULL)
+        goto err;
+    order = EC_GROUP_get0_order(group);
+    if (order == NULL)
+        goto err;
+    if (BN_is_zero(order)) {
+        ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER);
+        goto err;
+    }
+
+    if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx))
+        goto err;
+    if (!EC_POINT_is_at_infinity(group, point)) {
+        ECerr(EC_F_EC_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER);
+        goto err;
+    }
+
+    ret = 1;
+
+ err:
+    BN_CTX_free(new_ctx);
+    EC_POINT_free(point);
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_curve.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_curve.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_curve.c	(revision 331)
@@ -0,0 +1,3169 @@
+/*
+ * Copyright 2002-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#include <string.h>
+#include "ec_lcl.h"
+#include <openssl/err.h>
+#include <openssl/obj_mac.h>
+#include <openssl/opensslconf.h>
+#include "e_os.h"
+
+typedef struct {
+    int field_type,             /* either NID_X9_62_prime_field or
+                                 * NID_X9_62_characteristic_two_field */
+     seed_len, param_len;
+    unsigned int cofactor;      /* promoted to BN_ULONG */
+} EC_CURVE_DATA;
+
+/* the nist prime curves */
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 24 * 6];
+} _EC_NIST_PRIME_192 = {
+    {
+        NID_X9_62_prime_field, 20, 24, 1
+    },
+    {
+        /* seed */
+        0x30, 0x45, 0xAE, 0x6F, 0xC8, 0x42, 0x2F, 0x64, 0xED, 0x57, 0x95, 0x28,
+        0xD3, 0x81, 0x20, 0xEA, 0xE1, 0x21, 0x96, 0xD5,
+        /* p */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        /* a */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+        /* b */
+        0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7, 0x0F, 0xA7, 0xE9, 0xAB,
+        0x72, 0x24, 0x30, 0x49, 0xFE, 0xB8, 0xDE, 0xEC, 0xC1, 0x46, 0xB9, 0xB1,
+        /* x */
+        0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6, 0x7C, 0xBF, 0x20, 0xEB,
+        0x43, 0xA1, 0x88, 0x00, 0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12,
+        /* y */
+        0x07, 0x19, 0x2b, 0x95, 0xff, 0xc8, 0xda, 0x78, 0x63, 0x10, 0x11, 0xed,
+        0x6b, 0x24, 0xcd, 0xd5, 0x73, 0xf9, 0x77, 0xa1, 0x1e, 0x79, 0x48, 0x11,
+        /* order */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0x99, 0xDE, 0xF8, 0x36, 0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 28 * 6];
+} _EC_NIST_PRIME_224 = {
+    {
+        NID_X9_62_prime_field, 20, 28, 1
+    },
+    {
+        /* seed */
+        0xBD, 0x71, 0x34, 0x47, 0x99, 0xD5, 0xC7, 0xFC, 0xDC, 0x45, 0xB5, 0x9F,
+        0xA3, 0xB9, 0xAB, 0x8F, 0x6A, 0x94, 0x8B, 0xC5,
+        /* p */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x01,
+        /* a */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFE,
+        /* b */
+        0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56,
+        0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43,
+        0x23, 0x55, 0xFF, 0xB4,
+        /* x */
+        0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9,
+        0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6,
+        0x11, 0x5C, 0x1D, 0x21,
+        /* y */
+        0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
+        0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99,
+        0x85, 0x00, 0x7e, 0x34,
+        /* order */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45,
+        0x5C, 0x5C, 0x2A, 0x3D
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 48 * 6];
+} _EC_NIST_PRIME_384 = {
+    {
+        NID_X9_62_prime_field, 20, 48, 1
+    },
+    {
+        /* seed */
+        0xA3, 0x35, 0x92, 0x6A, 0xA3, 0x19, 0xA2, 0x7A, 0x1D, 0x00, 0x89, 0x6A,
+        0x67, 0x73, 0xA4, 0x82, 0x7A, 0xCD, 0xAC, 0x73,
+        /* p */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+        /* a */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC,
+        /* b */
+        0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B,
+        0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
+        0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
+        0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF,
+        /* x */
+        0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
+        0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
+        0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
+        0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7,
+        /* y */
+        0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf,
+        0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
+        0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce,
+        0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f,
+        /* order */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2,
+        0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 66 * 6];
+} _EC_NIST_PRIME_521 = {
+    {
+        NID_X9_62_prime_field, 20, 66, 1
+    },
+    {
+        /* seed */
+        0xD0, 0x9E, 0x88, 0x00, 0x29, 0x1C, 0xB8, 0x53, 0x96, 0xCC, 0x67, 0x17,
+        0x39, 0x32, 0x84, 0xAA, 0xA0, 0xDA, 0x64, 0xBA,
+        /* p */
+        0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        /* a */
+        0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+        /* b */
+        0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
+        0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
+        0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
+        0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
+        0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
+        0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00,
+        /* x */
+        0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
+        0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
+        0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
+        0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
+        0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
+        0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66,
+        /* y */
+        0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a,
+        0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
+        0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee,
+        0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
+        0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
+        0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
+        /* order */
+        0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86,
+        0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
+        0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
+        0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09
+    }
+};
+
+/* the x9.62 prime curves (minus the nist prime curves) */
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 24 * 6];
+} _EC_X9_62_PRIME_192V2 = {
+    {
+        NID_X9_62_prime_field, 20, 24, 1
+    },
+    {
+        /* seed */
+        0x31, 0xA9, 0x2E, 0xE2, 0x02, 0x9F, 0xD1, 0x0D, 0x90, 0x1B, 0x11, 0x3E,
+        0x99, 0x07, 0x10, 0xF0, 0xD2, 0x1A, 0xC6, 0xB6,
+        /* p */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        /* a */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+        /* b */
+        0xCC, 0x22, 0xD6, 0xDF, 0xB9, 0x5C, 0x6B, 0x25, 0xE4, 0x9C, 0x0D, 0x63,
+        0x64, 0xA4, 0xE5, 0x98, 0x0C, 0x39, 0x3A, 0xA2, 0x16, 0x68, 0xD9, 0x53,
+        /* x */
+        0xEE, 0xA2, 0xBA, 0xE7, 0xE1, 0x49, 0x78, 0x42, 0xF2, 0xDE, 0x77, 0x69,
+        0xCF, 0xE9, 0xC9, 0x89, 0xC0, 0x72, 0xAD, 0x69, 0x6F, 0x48, 0x03, 0x4A,
+        /* y */
+        0x65, 0x74, 0xd1, 0x1d, 0x69, 0xb6, 0xec, 0x7a, 0x67, 0x2b, 0xb8, 0x2a,
+        0x08, 0x3d, 0xf2, 0xf2, 0xb0, 0x84, 0x7d, 0xe9, 0x70, 0xb2, 0xde, 0x15,
+        /* order */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
+        0x5F, 0xB1, 0xA7, 0x24, 0xDC, 0x80, 0x41, 0x86, 0x48, 0xD8, 0xDD, 0x31
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 24 * 6];
+} _EC_X9_62_PRIME_192V3 = {
+    {
+        NID_X9_62_prime_field, 20, 24, 1
+    },
+    {
+        /* seed */
+        0xC4, 0x69, 0x68, 0x44, 0x35, 0xDE, 0xB3, 0x78, 0xC4, 0xB6, 0x5C, 0xA9,
+        0x59, 0x1E, 0x2A, 0x57, 0x63, 0x05, 0x9A, 0x2E,
+        /* p */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        /* a */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+        /* b */
+        0x22, 0x12, 0x3D, 0xC2, 0x39, 0x5A, 0x05, 0xCA, 0xA7, 0x42, 0x3D, 0xAE,
+        0xCC, 0xC9, 0x47, 0x60, 0xA7, 0xD4, 0x62, 0x25, 0x6B, 0xD5, 0x69, 0x16,
+        /* x */
+        0x7D, 0x29, 0x77, 0x81, 0x00, 0xC6, 0x5A, 0x1D, 0xA1, 0x78, 0x37, 0x16,
+        0x58, 0x8D, 0xCE, 0x2B, 0x8B, 0x4A, 0xEE, 0x8E, 0x22, 0x8F, 0x18, 0x96,
+        /* y */
+        0x38, 0xa9, 0x0f, 0x22, 0x63, 0x73, 0x37, 0x33, 0x4b, 0x49, 0xdc, 0xb6,
+        0x6a, 0x6d, 0xc8, 0xf9, 0x97, 0x8a, 0xca, 0x76, 0x48, 0xa9, 0x43, 0xb0,
+        /* order */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0x7A, 0x62, 0xD0, 0x31, 0xC8, 0x3F, 0x42, 0x94, 0xF6, 0x40, 0xEC, 0x13
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 30 * 6];
+} _EC_X9_62_PRIME_239V1 = {
+    {
+        NID_X9_62_prime_field, 20, 30, 1
+    },
+    {
+        /* seed */
+        0xE4, 0x3B, 0xB4, 0x60, 0xF0, 0xB8, 0x0C, 0xC0, 0xC0, 0xB0, 0x75, 0x79,
+        0x8E, 0x94, 0x80, 0x60, 0xF8, 0x32, 0x1B, 0x7D,
+        /* p */
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        /* a */
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+        /* b */
+        0x6B, 0x01, 0x6C, 0x3B, 0xDC, 0xF1, 0x89, 0x41, 0xD0, 0xD6, 0x54, 0x92,
+        0x14, 0x75, 0xCA, 0x71, 0xA9, 0xDB, 0x2F, 0xB2, 0x7D, 0x1D, 0x37, 0x79,
+        0x61, 0x85, 0xC2, 0x94, 0x2C, 0x0A,
+        /* x */
+        0x0F, 0xFA, 0x96, 0x3C, 0xDC, 0xA8, 0x81, 0x6C, 0xCC, 0x33, 0xB8, 0x64,
+        0x2B, 0xED, 0xF9, 0x05, 0xC3, 0xD3, 0x58, 0x57, 0x3D, 0x3F, 0x27, 0xFB,
+        0xBD, 0x3B, 0x3C, 0xB9, 0xAA, 0xAF,
+        /* y */
+        0x7d, 0xeb, 0xe8, 0xe4, 0xe9, 0x0a, 0x5d, 0xae, 0x6e, 0x40, 0x54, 0xca,
+        0x53, 0x0b, 0xa0, 0x46, 0x54, 0xb3, 0x68, 0x18, 0xce, 0x22, 0x6b, 0x39,
+        0xfc, 0xcb, 0x7b, 0x02, 0xf1, 0xae,
+        /* order */
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0x7F, 0xFF, 0xFF, 0x9E, 0x5E, 0x9A, 0x9F, 0x5D, 0x90, 0x71, 0xFB, 0xD1,
+        0x52, 0x26, 0x88, 0x90, 0x9D, 0x0B
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 30 * 6];
+} _EC_X9_62_PRIME_239V2 = {
+    {
+        NID_X9_62_prime_field, 20, 30, 1
+    },
+    {
+        /* seed */
+        0xE8, 0xB4, 0x01, 0x16, 0x04, 0x09, 0x53, 0x03, 0xCA, 0x3B, 0x80, 0x99,
+        0x98, 0x2B, 0xE0, 0x9F, 0xCB, 0x9A, 0xE6, 0x16,
+        /* p */
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        /* a */
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+        /* b */
+        0x61, 0x7F, 0xAB, 0x68, 0x32, 0x57, 0x6C, 0xBB, 0xFE, 0xD5, 0x0D, 0x99,
+        0xF0, 0x24, 0x9C, 0x3F, 0xEE, 0x58, 0xB9, 0x4B, 0xA0, 0x03, 0x8C, 0x7A,
+        0xE8, 0x4C, 0x8C, 0x83, 0x2F, 0x2C,
+        /* x */
+        0x38, 0xAF, 0x09, 0xD9, 0x87, 0x27, 0x70, 0x51, 0x20, 0xC9, 0x21, 0xBB,
+        0x5E, 0x9E, 0x26, 0x29, 0x6A, 0x3C, 0xDC, 0xF2, 0xF3, 0x57, 0x57, 0xA0,
+        0xEA, 0xFD, 0x87, 0xB8, 0x30, 0xE7,
+        /* y */
+        0x5b, 0x01, 0x25, 0xe4, 0xdb, 0xea, 0x0e, 0xc7, 0x20, 0x6d, 0xa0, 0xfc,
+        0x01, 0xd9, 0xb0, 0x81, 0x32, 0x9f, 0xb5, 0x55, 0xde, 0x6e, 0xf4, 0x60,
+        0x23, 0x7d, 0xff, 0x8b, 0xe4, 0xba,
+        /* order */
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0x80, 0x00, 0x00, 0xCF, 0xA7, 0xE8, 0x59, 0x43, 0x77, 0xD4, 0x14, 0xC0,
+        0x38, 0x21, 0xBC, 0x58, 0x20, 0x63
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 30 * 6];
+} _EC_X9_62_PRIME_239V3 = {
+    {
+        NID_X9_62_prime_field, 20, 30, 1
+    },
+    {
+        /* seed */
+        0x7D, 0x73, 0x74, 0x16, 0x8F, 0xFE, 0x34, 0x71, 0xB6, 0x0A, 0x85, 0x76,
+        0x86, 0xA1, 0x94, 0x75, 0xD3, 0xBF, 0xA2, 0xFF,
+        /* p */
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        /* a */
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+        /* b */
+        0x25, 0x57, 0x05, 0xFA, 0x2A, 0x30, 0x66, 0x54, 0xB1, 0xF4, 0xCB, 0x03,
+        0xD6, 0xA7, 0x50, 0xA3, 0x0C, 0x25, 0x01, 0x02, 0xD4, 0x98, 0x87, 0x17,
+        0xD9, 0xBA, 0x15, 0xAB, 0x6D, 0x3E,
+        /* x */
+        0x67, 0x68, 0xAE, 0x8E, 0x18, 0xBB, 0x92, 0xCF, 0xCF, 0x00, 0x5C, 0x94,
+        0x9A, 0xA2, 0xC6, 0xD9, 0x48, 0x53, 0xD0, 0xE6, 0x60, 0xBB, 0xF8, 0x54,
+        0xB1, 0xC9, 0x50, 0x5F, 0xE9, 0x5A,
+        /* y */
+        0x16, 0x07, 0xe6, 0x89, 0x8f, 0x39, 0x0c, 0x06, 0xbc, 0x1d, 0x55, 0x2b,
+        0xad, 0x22, 0x6f, 0x3b, 0x6f, 0xcf, 0xe4, 0x8b, 0x6e, 0x81, 0x84, 0x99,
+        0xaf, 0x18, 0xe3, 0xed, 0x6c, 0xf3,
+        /* order */
+        0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0x7F, 0xFF, 0xFF, 0x97, 0x5D, 0xEB, 0x41, 0xB3, 0xA6, 0x05, 0x7C, 0x3C,
+        0x43, 0x21, 0x46, 0x52, 0x65, 0x51
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 32 * 6];
+} _EC_X9_62_PRIME_256V1 = {
+    {
+        NID_X9_62_prime_field, 20, 32, 1
+    },
+    {
+        /* seed */
+        0xC4, 0x9D, 0x36, 0x08, 0x86, 0xE7, 0x04, 0x93, 0x6A, 0x66, 0x78, 0xE1,
+        0x13, 0x9D, 0x26, 0xB7, 0x81, 0x9F, 0x7E, 0x90,
+        /* p */
+        0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        /* a */
+        0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
+        /* b */
+        0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
+        0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
+        0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B,
+        /* x */
+        0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
+        0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
+        0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96,
+        /* y */
+        0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
+        0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
+        0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
+        /* order */
+        0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
+        0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
+    }
+};
+
+/* the secg prime curves (minus the nist and x9.62 prime curves) */
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 14 * 6];
+} _EC_SECG_PRIME_112R1 = {
+    {
+        NID_X9_62_prime_field, 20, 14, 1
+    },
+    {
+        /* seed */
+        0x00, 0xF5, 0x0B, 0x02, 0x8E, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61,
+        0x51, 0x75, 0x29, 0x04, 0x72, 0x78, 0x3F, 0xB1,
+        /* p */
+        0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD,
+        0x20, 0x8B,
+        /* a */
+        0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD,
+        0x20, 0x88,
+        /* b */
+        0x65, 0x9E, 0xF8, 0xBA, 0x04, 0x39, 0x16, 0xEE, 0xDE, 0x89, 0x11, 0x70,
+        0x2B, 0x22,
+        /* x */
+        0x09, 0x48, 0x72, 0x39, 0x99, 0x5A, 0x5E, 0xE7, 0x6B, 0x55, 0xF9, 0xC2,
+        0xF0, 0x98,
+        /* y */
+        0xa8, 0x9c, 0xe5, 0xaf, 0x87, 0x24, 0xc0, 0xa2, 0x3e, 0x0e, 0x0f, 0xf7,
+        0x75, 0x00,
+        /* order */
+        0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x76, 0x28, 0xDF, 0xAC, 0x65,
+        0x61, 0xC5
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 14 * 6];
+} _EC_SECG_PRIME_112R2 = {
+    {
+        NID_X9_62_prime_field, 20, 14, 4
+    },
+    {
+        /* seed */
+        0x00, 0x27, 0x57, 0xA1, 0x11, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61,
+        0x51, 0x75, 0x53, 0x16, 0xC0, 0x5E, 0x0B, 0xD4,
+        /* p */
+        0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD,
+        0x20, 0x8B,
+        /* a */
+        0x61, 0x27, 0xC2, 0x4C, 0x05, 0xF3, 0x8A, 0x0A, 0xAA, 0xF6, 0x5C, 0x0E,
+        0xF0, 0x2C,
+        /* b */
+        0x51, 0xDE, 0xF1, 0x81, 0x5D, 0xB5, 0xED, 0x74, 0xFC, 0xC3, 0x4C, 0x85,
+        0xD7, 0x09,
+        /* x */
+        0x4B, 0xA3, 0x0A, 0xB5, 0xE8, 0x92, 0xB4, 0xE1, 0x64, 0x9D, 0xD0, 0x92,
+        0x86, 0x43,
+        /* y */
+        0xad, 0xcd, 0x46, 0xf5, 0x88, 0x2e, 0x37, 0x47, 0xde, 0xf3, 0x6e, 0x95,
+        0x6e, 0x97,
+        /* order */
+        0x36, 0xDF, 0x0A, 0xAF, 0xD8, 0xB8, 0xD7, 0x59, 0x7C, 0xA1, 0x05, 0x20,
+        0xD0, 0x4B
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 16 * 6];
+} _EC_SECG_PRIME_128R1 = {
+    {
+        NID_X9_62_prime_field, 20, 16, 1
+    },
+    {
+        /* seed */
+        0x00, 0x0E, 0x0D, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75,
+        0x0C, 0xC0, 0x3A, 0x44, 0x73, 0xD0, 0x36, 0x79,
+        /* p */
+        0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF,
+        /* a */
+        0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFC,
+        /* b */
+        0xE8, 0x75, 0x79, 0xC1, 0x10, 0x79, 0xF4, 0x3D, 0xD8, 0x24, 0x99, 0x3C,
+        0x2C, 0xEE, 0x5E, 0xD3,
+        /* x */
+        0x16, 0x1F, 0xF7, 0x52, 0x8B, 0x89, 0x9B, 0x2D, 0x0C, 0x28, 0x60, 0x7C,
+        0xA5, 0x2C, 0x5B, 0x86,
+        /* y */
+        0xcf, 0x5a, 0xc8, 0x39, 0x5b, 0xaf, 0xeb, 0x13, 0xc0, 0x2d, 0xa2, 0x92,
+        0xdd, 0xed, 0x7a, 0x83,
+        /* order */
+        0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x75, 0xA3, 0x0D, 0x1B,
+        0x90, 0x38, 0xA1, 0x15
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 16 * 6];
+} _EC_SECG_PRIME_128R2 = {
+    {
+        NID_X9_62_prime_field, 20, 16, 4
+    },
+    {
+        /* seed */
+        0x00, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, 0x12, 0xD8,
+        0xF0, 0x34, 0x31, 0xFC, 0xE6, 0x3B, 0x88, 0xF4,
+        /* p */
+        0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF,
+        /* a */
+        0xD6, 0x03, 0x19, 0x98, 0xD1, 0xB3, 0xBB, 0xFE, 0xBF, 0x59, 0xCC, 0x9B,
+        0xBF, 0xF9, 0xAE, 0xE1,
+        /* b */
+        0x5E, 0xEE, 0xFC, 0xA3, 0x80, 0xD0, 0x29, 0x19, 0xDC, 0x2C, 0x65, 0x58,
+        0xBB, 0x6D, 0x8A, 0x5D,
+        /* x */
+        0x7B, 0x6A, 0xA5, 0xD8, 0x5E, 0x57, 0x29, 0x83, 0xE6, 0xFB, 0x32, 0xA7,
+        0xCD, 0xEB, 0xC1, 0x40,
+        /* y */
+        0x27, 0xb6, 0x91, 0x6a, 0x89, 0x4d, 0x3a, 0xee, 0x71, 0x06, 0xfe, 0x80,
+        0x5f, 0xc3, 0x4b, 0x44,
+        /* order */
+        0x3F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xBE, 0x00, 0x24, 0x72,
+        0x06, 0x13, 0xB5, 0xA3
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 21 * 6];
+} _EC_SECG_PRIME_160K1 = {
+    {
+        NID_X9_62_prime_field, 0, 21, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC, 0x73,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        /* b */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+        /* x */
+        0x00, 0x3B, 0x4C, 0x38, 0x2C, 0xE3, 0x7A, 0xA1, 0x92, 0xA4, 0x01, 0x9E,
+        0x76, 0x30, 0x36, 0xF4, 0xF5, 0xDD, 0x4D, 0x7E, 0xBB,
+        /* y */
+        0x00, 0x93, 0x8c, 0xf9, 0x35, 0x31, 0x8f, 0xdc, 0xed, 0x6b, 0xc2, 0x82,
+        0x86, 0x53, 0x17, 0x33, 0xc3, 0xf0, 0x3c, 0x4f, 0xee,
+        /* order */
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB8,
+        0xFA, 0x16, 0xDF, 0xAB, 0x9A, 0xCA, 0x16, 0xB6, 0xB3
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 21 * 6];
+} _EC_SECG_PRIME_160R1 = {
+    {
+        NID_X9_62_prime_field, 20, 21, 1
+    },
+    {
+        /* seed */
+        0x10, 0x53, 0xCD, 0xE4, 0x2C, 0x14, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56,
+        0x15, 0x17, 0x53, 0x3B, 0xF3, 0xF8, 0x33, 0x45,
+        /* p */
+        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF,
+        /* a */
+        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFC,
+        /* b */
+        0x00, 0x1C, 0x97, 0xBE, 0xFC, 0x54, 0xBD, 0x7A, 0x8B, 0x65, 0xAC, 0xF8,
+        0x9F, 0x81, 0xD4, 0xD4, 0xAD, 0xC5, 0x65, 0xFA, 0x45,
+        /* x */
+        0x00, 0x4A, 0x96, 0xB5, 0x68, 0x8E, 0xF5, 0x73, 0x28, 0x46, 0x64, 0x69,
+        0x89, 0x68, 0xC3, 0x8B, 0xB9, 0x13, 0xCB, 0xFC, 0x82,
+        /* y */
+        0x00, 0x23, 0xa6, 0x28, 0x55, 0x31, 0x68, 0x94, 0x7d, 0x59, 0xdc, 0xc9,
+        0x12, 0x04, 0x23, 0x51, 0x37, 0x7a, 0xc5, 0xfb, 0x32,
+        /* order */
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF4,
+        0xC8, 0xF9, 0x27, 0xAE, 0xD3, 0xCA, 0x75, 0x22, 0x57
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 21 * 6];
+} _EC_SECG_PRIME_160R2 = {
+    {
+        NID_X9_62_prime_field, 20, 21, 1
+    },
+    {
+        /* seed */
+        0xB9, 0x9B, 0x99, 0xB0, 0x99, 0xB3, 0x23, 0xE0, 0x27, 0x09, 0xA4, 0xD6,
+        0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x51,
+        /* p */
+        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC, 0x73,
+        /* a */
+        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC, 0x70,
+        /* b */
+        0x00, 0xB4, 0xE1, 0x34, 0xD3, 0xFB, 0x59, 0xEB, 0x8B, 0xAB, 0x57, 0x27,
+        0x49, 0x04, 0x66, 0x4D, 0x5A, 0xF5, 0x03, 0x88, 0xBA,
+        /* x */
+        0x00, 0x52, 0xDC, 0xB0, 0x34, 0x29, 0x3A, 0x11, 0x7E, 0x1F, 0x4F, 0xF1,
+        0x1B, 0x30, 0xF7, 0x19, 0x9D, 0x31, 0x44, 0xCE, 0x6D,
+        /* y */
+        0x00, 0xfe, 0xaf, 0xfe, 0xf2, 0xe3, 0x31, 0xf2, 0x96, 0xe0, 0x71, 0xfa,
+        0x0d, 0xf9, 0x98, 0x2c, 0xfe, 0xa7, 0xd4, 0x3f, 0x2e,
+        /* order */
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35,
+        0x1E, 0xE7, 0x86, 0xA8, 0x18, 0xF3, 0xA1, 0xA1, 0x6B
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 24 * 6];
+} _EC_SECG_PRIME_192K1 = {
+    {
+        NID_X9_62_prime_field, 0, 24, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xEE, 0x37,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        /* b */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+        /* x */
+        0xDB, 0x4F, 0xF1, 0x0E, 0xC0, 0x57, 0xE9, 0xAE, 0x26, 0xB0, 0x7D, 0x02,
+        0x80, 0xB7, 0xF4, 0x34, 0x1D, 0xA5, 0xD1, 0xB1, 0xEA, 0xE0, 0x6C, 0x7D,
+        /* y */
+        0x9b, 0x2f, 0x2f, 0x6d, 0x9c, 0x56, 0x28, 0xa7, 0x84, 0x41, 0x63, 0xd0,
+        0x15, 0xbe, 0x86, 0x34, 0x40, 0x82, 0xaa, 0x88, 0xd9, 0x5e, 0x2f, 0x9d,
+        /* order */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
+        0x26, 0xF2, 0xFC, 0x17, 0x0F, 0x69, 0x46, 0x6A, 0x74, 0xDE, 0xFD, 0x8D
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 29 * 6];
+} _EC_SECG_PRIME_224K1 = {
+    {
+        NID_X9_62_prime_field, 0, 29, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFE, 0xFF, 0xFF, 0xE5, 0x6D,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00,
+        /* b */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x05,
+        /* x */
+        0x00, 0xA1, 0x45, 0x5B, 0x33, 0x4D, 0xF0, 0x99, 0xDF, 0x30, 0xFC, 0x28,
+        0xA1, 0x69, 0xA4, 0x67, 0xE9, 0xE4, 0x70, 0x75, 0xA9, 0x0F, 0x7E, 0x65,
+        0x0E, 0xB6, 0xB7, 0xA4, 0x5C,
+        /* y */
+        0x00, 0x7e, 0x08, 0x9f, 0xed, 0x7f, 0xba, 0x34, 0x42, 0x82, 0xca, 0xfb,
+        0xd6, 0xf7, 0xe3, 0x19, 0xf7, 0xc0, 0xb0, 0xbd, 0x59, 0xe2, 0xca, 0x4b,
+        0xdb, 0x55, 0x6d, 0x61, 0xa5,
+        /* order */
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x01, 0xDC, 0xE8, 0xD2, 0xEC, 0x61, 0x84, 0xCA, 0xF0, 0xA9,
+        0x71, 0x76, 0x9F, 0xB1, 0xF7
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 32 * 6];
+} _EC_SECG_PRIME_256K1 = {
+    {
+        NID_X9_62_prime_field, 0, 32, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        /* b */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+        /* x */
+        0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95,
+        0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9,
+        0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98,
+        /* y */
+        0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, 0xfb, 0xfc,
+        0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48, 0xa6, 0x85, 0x54, 0x19,
+        0x9c, 0x47, 0xd0, 0x8f, 0xfb, 0x10, 0xd4, 0xb8,
+        /* order */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
+        0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41
+    }
+};
+
+/* some wap/wtls curves */
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 15 * 6];
+} _EC_WTLS_8 = {
+    {
+        NID_X9_62_prime_field, 0, 15, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFD, 0xE7,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00,
+        /* b */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x03,
+        /* x */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x01,
+        /* y */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x02,
+        /* order */
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xEC, 0xEA, 0x55, 0x1A,
+        0xD8, 0x37, 0xE9
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 21 * 6];
+} _EC_WTLS_9 = {
+    {
+        NID_X9_62_prime_field, 0, 21, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x80, 0x8F,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        /* b */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+        /* x */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        /* y */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+        /* order */
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xCD,
+        0xC9, 0x8A, 0xE0, 0xE2, 0xDE, 0x57, 0x4A, 0xBF, 0x33
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 28 * 6];
+} _EC_WTLS_12 = {
+    {
+        NID_X9_62_prime_field, 0, 28, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x01,
+        /* a */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFE,
+        /* b */
+        0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56,
+        0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43,
+        0x23, 0x55, 0xFF, 0xB4,
+        /* x */
+        0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9,
+        0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6,
+        0x11, 0x5C, 0x1D, 0x21,
+        /* y */
+        0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
+        0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99,
+        0x85, 0x00, 0x7e, 0x34,
+        /* order */
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45,
+        0x5C, 0x5C, 0x2A, 0x3D
+    }
+};
+
+#ifndef OPENSSL_NO_EC2M
+
+/* characteristic two curves */
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 15 * 6];
+} _EC_SECG_CHAR2_113R1 = {
+    {
+        NID_X9_62_characteristic_two_field, 20, 15, 2
+    },
+    {
+        /* seed */
+        0x10, 0xE7, 0x23, 0xAB, 0x14, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15,
+        0x17, 0x56, 0xFE, 0xBF, 0x8F, 0xCB, 0x49, 0xA9,
+        /* p */
+        0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x02, 0x01,
+        /* a */
+        0x00, 0x30, 0x88, 0x25, 0x0C, 0xA6, 0xE7, 0xC7, 0xFE, 0x64, 0x9C, 0xE8,
+        0x58, 0x20, 0xF7,
+        /* b */
+        0x00, 0xE8, 0xBE, 0xE4, 0xD3, 0xE2, 0x26, 0x07, 0x44, 0x18, 0x8B, 0xE0,
+        0xE9, 0xC7, 0x23,
+        /* x */
+        0x00, 0x9D, 0x73, 0x61, 0x6F, 0x35, 0xF4, 0xAB, 0x14, 0x07, 0xD7, 0x35,
+        0x62, 0xC1, 0x0F,
+        /* y */
+        0x00, 0xA5, 0x28, 0x30, 0x27, 0x79, 0x58, 0xEE, 0x84, 0xD1, 0x31, 0x5E,
+        0xD3, 0x18, 0x86,
+        /* order */
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0xCC, 0xEC, 0x8A,
+        0x39, 0xE5, 0x6F
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 15 * 6];
+} _EC_SECG_CHAR2_113R2 = {
+    {
+        NID_X9_62_characteristic_two_field, 20, 15, 2
+    },
+    {
+        /* seed */
+        0x10, 0xC0, 0xFB, 0x15, 0x76, 0x08, 0x60, 0xDE, 0xF1, 0xEE, 0xF4, 0xD6,
+        0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x5D,
+        /* p */
+        0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x02, 0x01,
+        /* a */
+        0x00, 0x68, 0x99, 0x18, 0xDB, 0xEC, 0x7E, 0x5A, 0x0D, 0xD6, 0xDF, 0xC0,
+        0xAA, 0x55, 0xC7,
+        /* b */
+        0x00, 0x95, 0xE9, 0xA9, 0xEC, 0x9B, 0x29, 0x7B, 0xD4, 0xBF, 0x36, 0xE0,
+        0x59, 0x18, 0x4F,
+        /* x */
+        0x01, 0xA5, 0x7A, 0x6A, 0x7B, 0x26, 0xCA, 0x5E, 0xF5, 0x2F, 0xCD, 0xB8,
+        0x16, 0x47, 0x97,
+        /* y */
+        0x00, 0xB3, 0xAD, 0xC9, 0x4E, 0xD1, 0xFE, 0x67, 0x4C, 0x06, 0xE6, 0x95,
+        0xBA, 0xBA, 0x1D,
+        /* order */
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x78, 0x9B, 0x24,
+        0x96, 0xAF, 0x93
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 17 * 6];
+} _EC_SECG_CHAR2_131R1 = {
+    {
+        NID_X9_62_characteristic_two_field, 20, 17, 2
+    },
+    {
+        /* seed */
+        0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, 0x98, 0x5B, 0xD3,
+        0xAD, 0xBA, 0xDA, 0x21, 0xB4, 0x3A, 0x97, 0xE2,
+        /* p */
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x01, 0x0D,
+        /* a */
+        0x07, 0xA1, 0x1B, 0x09, 0xA7, 0x6B, 0x56, 0x21, 0x44, 0x41, 0x8F, 0xF3,
+        0xFF, 0x8C, 0x25, 0x70, 0xB8,
+        /* b */
+        0x02, 0x17, 0xC0, 0x56, 0x10, 0x88, 0x4B, 0x63, 0xB9, 0xC6, 0xC7, 0x29,
+        0x16, 0x78, 0xF9, 0xD3, 0x41,
+        /* x */
+        0x00, 0x81, 0xBA, 0xF9, 0x1F, 0xDF, 0x98, 0x33, 0xC4, 0x0F, 0x9C, 0x18,
+        0x13, 0x43, 0x63, 0x83, 0x99,
+        /* y */
+        0x07, 0x8C, 0x6E, 0x7E, 0xA3, 0x8C, 0x00, 0x1F, 0x73, 0xC8, 0x13, 0x4B,
+        0x1B, 0x4E, 0xF9, 0xE1, 0x50,
+        /* order */
+        0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31, 0x23, 0x95,
+        0x3A, 0x94, 0x64, 0xB5, 0x4D
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 17 * 6];
+} _EC_SECG_CHAR2_131R2 = {
+    {
+        NID_X9_62_characteristic_two_field, 20, 17, 2
+    },
+    {
+        /* seed */
+        0x98, 0x5B, 0xD3, 0xAD, 0xBA, 0xD4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56,
+        0x15, 0x17, 0x5A, 0x21, 0xB4, 0x3A, 0x97, 0xE3,
+        /* p */
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x01, 0x0D,
+        /* a */
+        0x03, 0xE5, 0xA8, 0x89, 0x19, 0xD7, 0xCA, 0xFC, 0xBF, 0x41, 0x5F, 0x07,
+        0xC2, 0x17, 0x65, 0x73, 0xB2,
+        /* b */
+        0x04, 0xB8, 0x26, 0x6A, 0x46, 0xC5, 0x56, 0x57, 0xAC, 0x73, 0x4C, 0xE3,
+        0x8F, 0x01, 0x8F, 0x21, 0x92,
+        /* x */
+        0x03, 0x56, 0xDC, 0xD8, 0xF2, 0xF9, 0x50, 0x31, 0xAD, 0x65, 0x2D, 0x23,
+        0x95, 0x1B, 0xB3, 0x66, 0xA8,
+        /* y */
+        0x06, 0x48, 0xF0, 0x6D, 0x86, 0x79, 0x40, 0xA5, 0x36, 0x6D, 0x9E, 0x26,
+        0x5D, 0xE9, 0xEB, 0x24, 0x0F,
+        /* order */
+        0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x69, 0x54, 0xA2,
+        0x33, 0x04, 0x9B, 0xA9, 0x8F
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 21 * 6];
+} _EC_NIST_CHAR2_163K = {
+    {
+        NID_X9_62_characteristic_two_field, 0, 21, 2
+    },
+    {
+        /* no seed */
+        /* p */
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        /* b */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        /* x */
+        0x02, 0xFE, 0x13, 0xC0, 0x53, 0x7B, 0xBC, 0x11, 0xAC, 0xAA, 0x07, 0xD7,
+        0x93, 0xDE, 0x4E, 0x6D, 0x5E, 0x5C, 0x94, 0xEE, 0xE8,
+        /* y */
+        0x02, 0x89, 0x07, 0x0F, 0xB0, 0x5D, 0x38, 0xFF, 0x58, 0x32, 0x1F, 0x2E,
+        0x80, 0x05, 0x36, 0xD5, 0x38, 0xCC, 0xDA, 0xA3, 0xD9,
+        /* order */
+        0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01,
+        0x08, 0xA2, 0xE0, 0xCC, 0x0D, 0x99, 0xF8, 0xA5, 0xEF
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 21 * 6];
+} _EC_SECG_CHAR2_163R1 = {
+    {
+        NID_X9_62_characteristic_two_field, 0, 21, 2
+    },
+    {
+        /* p */
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9,
+        /* a */
+        0x07, 0xB6, 0x88, 0x2C, 0xAA, 0xEF, 0xA8, 0x4F, 0x95, 0x54, 0xFF, 0x84,
+        0x28, 0xBD, 0x88, 0xE2, 0x46, 0xD2, 0x78, 0x2A, 0xE2,
+        /* b */
+        0x07, 0x13, 0x61, 0x2D, 0xCD, 0xDC, 0xB4, 0x0A, 0xAB, 0x94, 0x6B, 0xDA,
+        0x29, 0xCA, 0x91, 0xF7, 0x3A, 0xF9, 0x58, 0xAF, 0xD9,
+        /* x */
+        0x03, 0x69, 0x97, 0x96, 0x97, 0xAB, 0x43, 0x89, 0x77, 0x89, 0x56, 0x67,
+        0x89, 0x56, 0x7F, 0x78, 0x7A, 0x78, 0x76, 0xA6, 0x54,
+        /* y */
+        0x00, 0x43, 0x5E, 0xDB, 0x42, 0xEF, 0xAF, 0xB2, 0x98, 0x9D, 0x51, 0xFE,
+        0xFC, 0xE3, 0xC8, 0x09, 0x88, 0xF4, 0x1F, 0xF8, 0x83,
+        /* order */
+        0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x48,
+        0xAA, 0xB6, 0x89, 0xC2, 0x9C, 0xA7, 0x10, 0x27, 0x9B
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 21 * 6];
+} _EC_NIST_CHAR2_163B = {
+    {
+        NID_X9_62_characteristic_two_field, 0, 21, 2
+    },
+    {
+        /* p */
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        /* b */
+        0x02, 0x0A, 0x60, 0x19, 0x07, 0xB8, 0xC9, 0x53, 0xCA, 0x14, 0x81, 0xEB,
+        0x10, 0x51, 0x2F, 0x78, 0x74, 0x4A, 0x32, 0x05, 0xFD,
+        /* x */
+        0x03, 0xF0, 0xEB, 0xA1, 0x62, 0x86, 0xA2, 0xD5, 0x7E, 0xA0, 0x99, 0x11,
+        0x68, 0xD4, 0x99, 0x46, 0x37, 0xE8, 0x34, 0x3E, 0x36,
+        /* y */
+        0x00, 0xD5, 0x1F, 0xBC, 0x6C, 0x71, 0xA0, 0x09, 0x4F, 0xA2, 0xCD, 0xD5,
+        0x45, 0xB1, 0x1C, 0x5C, 0x0C, 0x79, 0x73, 0x24, 0xF1,
+        /* order */
+        0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x92,
+        0xFE, 0x77, 0xE7, 0x0C, 0x12, 0xA4, 0x23, 0x4C, 0x33
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 25 * 6];
+} _EC_SECG_CHAR2_193R1 = {
+    {
+        NID_X9_62_characteristic_two_field, 20, 25, 2
+    },
+    {
+        /* seed */
+        0x10, 0x3F, 0xAE, 0xC7, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51,
+        0x75, 0x77, 0x7F, 0xC5, 0xB1, 0x91, 0xEF, 0x30,
+        /* p */
+        0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+        0x01,
+        /* a */
+        0x00, 0x17, 0x85, 0x8F, 0xEB, 0x7A, 0x98, 0x97, 0x51, 0x69, 0xE1, 0x71,
+        0xF7, 0x7B, 0x40, 0x87, 0xDE, 0x09, 0x8A, 0xC8, 0xA9, 0x11, 0xDF, 0x7B,
+        0x01,
+        /* b */
+        0x00, 0xFD, 0xFB, 0x49, 0xBF, 0xE6, 0xC3, 0xA8, 0x9F, 0xAC, 0xAD, 0xAA,
+        0x7A, 0x1E, 0x5B, 0xBC, 0x7C, 0xC1, 0xC2, 0xE5, 0xD8, 0x31, 0x47, 0x88,
+        0x14,
+        /* x */
+        0x01, 0xF4, 0x81, 0xBC, 0x5F, 0x0F, 0xF8, 0x4A, 0x74, 0xAD, 0x6C, 0xDF,
+        0x6F, 0xDE, 0xF4, 0xBF, 0x61, 0x79, 0x62, 0x53, 0x72, 0xD8, 0xC0, 0xC5,
+        0xE1,
+        /* y */
+        0x00, 0x25, 0xE3, 0x99, 0xF2, 0x90, 0x37, 0x12, 0xCC, 0xF3, 0xEA, 0x9E,
+        0x3A, 0x1A, 0xD1, 0x7F, 0xB0, 0xB3, 0x20, 0x1B, 0x6A, 0xF7, 0xCE, 0x1B,
+        0x05,
+        /* order */
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0xC7, 0xF3, 0x4A, 0x77, 0x8F, 0x44, 0x3A, 0xCC, 0x92, 0x0E, 0xBA,
+        0x49
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 25 * 6];
+} _EC_SECG_CHAR2_193R2 = {
+    {
+        NID_X9_62_characteristic_two_field, 20, 25, 2
+    },
+    {
+        /* seed */
+        0x10, 0xB7, 0xB4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x51,
+        0x37, 0xC8, 0xA1, 0x6F, 0xD0, 0xDA, 0x22, 0x11,
+        /* p */
+        0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+        0x01,
+        /* a */
+        0x01, 0x63, 0xF3, 0x5A, 0x51, 0x37, 0xC2, 0xCE, 0x3E, 0xA6, 0xED, 0x86,
+        0x67, 0x19, 0x0B, 0x0B, 0xC4, 0x3E, 0xCD, 0x69, 0x97, 0x77, 0x02, 0x70,
+        0x9B,
+        /* b */
+        0x00, 0xC9, 0xBB, 0x9E, 0x89, 0x27, 0xD4, 0xD6, 0x4C, 0x37, 0x7E, 0x2A,
+        0xB2, 0x85, 0x6A, 0x5B, 0x16, 0xE3, 0xEF, 0xB7, 0xF6, 0x1D, 0x43, 0x16,
+        0xAE,
+        /* x */
+        0x00, 0xD9, 0xB6, 0x7D, 0x19, 0x2E, 0x03, 0x67, 0xC8, 0x03, 0xF3, 0x9E,
+        0x1A, 0x7E, 0x82, 0xCA, 0x14, 0xA6, 0x51, 0x35, 0x0A, 0xAE, 0x61, 0x7E,
+        0x8F,
+        /* y */
+        0x01, 0xCE, 0x94, 0x33, 0x56, 0x07, 0xC3, 0x04, 0xAC, 0x29, 0xE7, 0xDE,
+        0xFB, 0xD9, 0xCA, 0x01, 0xF5, 0x96, 0xF9, 0x27, 0x22, 0x4C, 0xDE, 0xCF,
+        0x6C,
+        /* order */
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x01, 0x5A, 0xAB, 0x56, 0x1B, 0x00, 0x54, 0x13, 0xCC, 0xD4, 0xEE, 0x99,
+        0xD5
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 30 * 6];
+} _EC_NIST_CHAR2_233K = {
+    {
+        NID_X9_62_characteristic_two_field, 0, 30, 4
+    },
+    {
+        /* no seed */
+        0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        /* b */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        /* x */
+        0x01, 0x72, 0x32, 0xBA, 0x85, 0x3A, 0x7E, 0x73, 0x1A, 0xF1, 0x29, 0xF2,
+        0x2F, 0xF4, 0x14, 0x95, 0x63, 0xA4, 0x19, 0xC2, 0x6B, 0xF5, 0x0A, 0x4C,
+        0x9D, 0x6E, 0xEF, 0xAD, 0x61, 0x26,
+        /* y */
+        0x01, 0xDB, 0x53, 0x7D, 0xEC, 0xE8, 0x19, 0xB7, 0xF7, 0x0F, 0x55, 0x5A,
+        0x67, 0xC4, 0x27, 0xA8, 0xCD, 0x9B, 0xF1, 0x8A, 0xEB, 0x9B, 0x56, 0xE0,
+        0xC1, 0x10, 0x56, 0xFA, 0xE6, 0xA3,
+        /* order */
+        0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x06, 0x9D, 0x5B, 0xB9, 0x15, 0xBC, 0xD4, 0x6E, 0xFB,
+        0x1A, 0xD5, 0xF1, 0x73, 0xAB, 0xDF
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 30 * 6];
+} _EC_NIST_CHAR2_233B = {
+    {
+        NID_X9_62_characteristic_two_field, 20, 30, 2
+    },
+    {
+        /* seed */
+        0x74, 0xD5, 0x9F, 0xF0, 0x7F, 0x6B, 0x41, 0x3D, 0x0E, 0xA1, 0x4B, 0x34,
+        0x4B, 0x20, 0xA2, 0xDB, 0x04, 0x9B, 0x50, 0xC3,
+        /* p */
+        0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        /* b */
+        0x00, 0x66, 0x64, 0x7E, 0xDE, 0x6C, 0x33, 0x2C, 0x7F, 0x8C, 0x09, 0x23,
+        0xBB, 0x58, 0x21, 0x3B, 0x33, 0x3B, 0x20, 0xE9, 0xCE, 0x42, 0x81, 0xFE,
+        0x11, 0x5F, 0x7D, 0x8F, 0x90, 0xAD,
+        /* x */
+        0x00, 0xFA, 0xC9, 0xDF, 0xCB, 0xAC, 0x83, 0x13, 0xBB, 0x21, 0x39, 0xF1,
+        0xBB, 0x75, 0x5F, 0xEF, 0x65, 0xBC, 0x39, 0x1F, 0x8B, 0x36, 0xF8, 0xF8,
+        0xEB, 0x73, 0x71, 0xFD, 0x55, 0x8B,
+        /* y */
+        0x01, 0x00, 0x6A, 0x08, 0xA4, 0x19, 0x03, 0x35, 0x06, 0x78, 0xE5, 0x85,
+        0x28, 0xBE, 0xBF, 0x8A, 0x0B, 0xEF, 0xF8, 0x67, 0xA7, 0xCA, 0x36, 0x71,
+        0x6F, 0x7E, 0x01, 0xF8, 0x10, 0x52,
+        /* order */
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x13, 0xE9, 0x74, 0xE7, 0x2F, 0x8A, 0x69, 0x22, 0x03,
+        0x1D, 0x26, 0x03, 0xCF, 0xE0, 0xD7
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 30 * 6];
+} _EC_SECG_CHAR2_239K1 = {
+    {
+        NID_X9_62_characteristic_two_field, 0, 30, 4
+    },
+    {
+        /* no seed */
+        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        /* b */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        /* x */
+        0x29, 0xA0, 0xB6, 0xA8, 0x87, 0xA9, 0x83, 0xE9, 0x73, 0x09, 0x88, 0xA6,
+        0x87, 0x27, 0xA8, 0xB2, 0xD1, 0x26, 0xC4, 0x4C, 0xC2, 0xCC, 0x7B, 0x2A,
+        0x65, 0x55, 0x19, 0x30, 0x35, 0xDC,
+        /* y */
+        0x76, 0x31, 0x08, 0x04, 0xF1, 0x2E, 0x54, 0x9B, 0xDB, 0x01, 0x1C, 0x10,
+        0x30, 0x89, 0xE7, 0x35, 0x10, 0xAC, 0xB2, 0x75, 0xFC, 0x31, 0x2A, 0x5D,
+        0xC6, 0xB7, 0x65, 0x53, 0xF0, 0xCA,
+        /* order */
+        0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x5A, 0x79, 0xFE, 0xC6, 0x7C, 0xB6, 0xE9, 0x1F, 0x1C,
+        0x1D, 0xA8, 0x00, 0xE4, 0x78, 0xA5
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 36 * 6];
+} _EC_NIST_CHAR2_283K = {
+    {
+        NID_X9_62_characteristic_two_field, 0, 36, 4
+    },
+    {
+        /* no seed */
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        /* b */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        /* x */
+        0x05, 0x03, 0x21, 0x3F, 0x78, 0xCA, 0x44, 0x88, 0x3F, 0x1A, 0x3B, 0x81,
+        0x62, 0xF1, 0x88, 0xE5, 0x53, 0xCD, 0x26, 0x5F, 0x23, 0xC1, 0x56, 0x7A,
+        0x16, 0x87, 0x69, 0x13, 0xB0, 0xC2, 0xAC, 0x24, 0x58, 0x49, 0x28, 0x36,
+        /* y */
+        0x01, 0xCC, 0xDA, 0x38, 0x0F, 0x1C, 0x9E, 0x31, 0x8D, 0x90, 0xF9, 0x5D,
+        0x07, 0xE5, 0x42, 0x6F, 0xE8, 0x7E, 0x45, 0xC0, 0xE8, 0x18, 0x46, 0x98,
+        0xE4, 0x59, 0x62, 0x36, 0x4E, 0x34, 0x11, 0x61, 0x77, 0xDD, 0x22, 0x59,
+        /* order */
+        0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0xAE, 0x2E, 0xD0, 0x75, 0x77,
+        0x26, 0x5D, 0xFF, 0x7F, 0x94, 0x45, 0x1E, 0x06, 0x1E, 0x16, 0x3C, 0x61
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 36 * 6];
+} _EC_NIST_CHAR2_283B = {
+    {
+        NID_X9_62_characteristic_two_field, 20, 36, 2
+    },
+    {
+        /* no seed */
+        0x77, 0xE2, 0xB0, 0x73, 0x70, 0xEB, 0x0F, 0x83, 0x2A, 0x6D, 0xD5, 0xB6,
+        0x2D, 0xFC, 0x88, 0xCD, 0x06, 0xBB, 0x84, 0xBE,
+        /* p */
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        /* b */
+        0x02, 0x7B, 0x68, 0x0A, 0xC8, 0xB8, 0x59, 0x6D, 0xA5, 0xA4, 0xAF, 0x8A,
+        0x19, 0xA0, 0x30, 0x3F, 0xCA, 0x97, 0xFD, 0x76, 0x45, 0x30, 0x9F, 0xA2,
+        0xA5, 0x81, 0x48, 0x5A, 0xF6, 0x26, 0x3E, 0x31, 0x3B, 0x79, 0xA2, 0xF5,
+        /* x */
+        0x05, 0xF9, 0x39, 0x25, 0x8D, 0xB7, 0xDD, 0x90, 0xE1, 0x93, 0x4F, 0x8C,
+        0x70, 0xB0, 0xDF, 0xEC, 0x2E, 0xED, 0x25, 0xB8, 0x55, 0x7E, 0xAC, 0x9C,
+        0x80, 0xE2, 0xE1, 0x98, 0xF8, 0xCD, 0xBE, 0xCD, 0x86, 0xB1, 0x20, 0x53,
+        /* y */
+        0x03, 0x67, 0x68, 0x54, 0xFE, 0x24, 0x14, 0x1C, 0xB9, 0x8F, 0xE6, 0xD4,
+        0xB2, 0x0D, 0x02, 0xB4, 0x51, 0x6F, 0xF7, 0x02, 0x35, 0x0E, 0xDD, 0xB0,
+        0x82, 0x67, 0x79, 0xC8, 0x13, 0xF0, 0xDF, 0x45, 0xBE, 0x81, 0x12, 0xF4,
+        /* order */
+        0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x90, 0x39, 0x96, 0x60, 0xFC,
+        0x93, 0x8A, 0x90, 0x16, 0x5B, 0x04, 0x2A, 0x7C, 0xEF, 0xAD, 0xB3, 0x07
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 52 * 6];
+} _EC_NIST_CHAR2_409K = {
+    {
+        NID_X9_62_characteristic_two_field, 0, 52, 4
+    },
+    {
+        /* no seed */
+        /* p */
+        0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x01,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        /* b */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x01,
+        /* x */
+        0x00, 0x60, 0xF0, 0x5F, 0x65, 0x8F, 0x49, 0xC1, 0xAD, 0x3A, 0xB1, 0x89,
+        0x0F, 0x71, 0x84, 0x21, 0x0E, 0xFD, 0x09, 0x87, 0xE3, 0x07, 0xC8, 0x4C,
+        0x27, 0xAC, 0xCF, 0xB8, 0xF9, 0xF6, 0x7C, 0xC2, 0xC4, 0x60, 0x18, 0x9E,
+        0xB5, 0xAA, 0xAA, 0x62, 0xEE, 0x22, 0x2E, 0xB1, 0xB3, 0x55, 0x40, 0xCF,
+        0xE9, 0x02, 0x37, 0x46,
+        /* y */
+        0x01, 0xE3, 0x69, 0x05, 0x0B, 0x7C, 0x4E, 0x42, 0xAC, 0xBA, 0x1D, 0xAC,
+        0xBF, 0x04, 0x29, 0x9C, 0x34, 0x60, 0x78, 0x2F, 0x91, 0x8E, 0xA4, 0x27,
+        0xE6, 0x32, 0x51, 0x65, 0xE9, 0xEA, 0x10, 0xE3, 0xDA, 0x5F, 0x6C, 0x42,
+        0xE9, 0xC5, 0x52, 0x15, 0xAA, 0x9C, 0xA2, 0x7A, 0x58, 0x63, 0xEC, 0x48,
+        0xD8, 0xE0, 0x28, 0x6B,
+        /* order */
+        0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFE, 0x5F, 0x83, 0xB2, 0xD4, 0xEA, 0x20, 0x40, 0x0E, 0xC4,
+        0x55, 0x7D, 0x5E, 0xD3, 0xE3, 0xE7, 0xCA, 0x5B, 0x4B, 0x5C, 0x83, 0xB8,
+        0xE0, 0x1E, 0x5F, 0xCF
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 52 * 6];
+} _EC_NIST_CHAR2_409B = {
+    {
+        NID_X9_62_characteristic_two_field, 20, 52, 2
+    },
+    {
+        /* seed */
+        0x40, 0x99, 0xB5, 0xA4, 0x57, 0xF9, 0xD6, 0x9F, 0x79, 0x21, 0x3D, 0x09,
+        0x4C, 0x4B, 0xCD, 0x4D, 0x42, 0x62, 0x21, 0x0B,
+        /* p */
+        0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x01,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x01,
+        /* b */
+        0x00, 0x21, 0xA5, 0xC2, 0xC8, 0xEE, 0x9F, 0xEB, 0x5C, 0x4B, 0x9A, 0x75,
+        0x3B, 0x7B, 0x47, 0x6B, 0x7F, 0xD6, 0x42, 0x2E, 0xF1, 0xF3, 0xDD, 0x67,
+        0x47, 0x61, 0xFA, 0x99, 0xD6, 0xAC, 0x27, 0xC8, 0xA9, 0xA1, 0x97, 0xB2,
+        0x72, 0x82, 0x2F, 0x6C, 0xD5, 0x7A, 0x55, 0xAA, 0x4F, 0x50, 0xAE, 0x31,
+        0x7B, 0x13, 0x54, 0x5F,
+        /* x */
+        0x01, 0x5D, 0x48, 0x60, 0xD0, 0x88, 0xDD, 0xB3, 0x49, 0x6B, 0x0C, 0x60,
+        0x64, 0x75, 0x62, 0x60, 0x44, 0x1C, 0xDE, 0x4A, 0xF1, 0x77, 0x1D, 0x4D,
+        0xB0, 0x1F, 0xFE, 0x5B, 0x34, 0xE5, 0x97, 0x03, 0xDC, 0x25, 0x5A, 0x86,
+        0x8A, 0x11, 0x80, 0x51, 0x56, 0x03, 0xAE, 0xAB, 0x60, 0x79, 0x4E, 0x54,
+        0xBB, 0x79, 0x96, 0xA7,
+        /* y */
+        0x00, 0x61, 0xB1, 0xCF, 0xAB, 0x6B, 0xE5, 0xF3, 0x2B, 0xBF, 0xA7, 0x83,
+        0x24, 0xED, 0x10, 0x6A, 0x76, 0x36, 0xB9, 0xC5, 0xA7, 0xBD, 0x19, 0x8D,
+        0x01, 0x58, 0xAA, 0x4F, 0x54, 0x88, 0xD0, 0x8F, 0x38, 0x51, 0x4F, 0x1F,
+        0xDF, 0x4B, 0x4F, 0x40, 0xD2, 0x18, 0x1B, 0x36, 0x81, 0xC3, 0x64, 0xBA,
+        0x02, 0x73, 0xC7, 0x06,
+        /* order */
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x01, 0xE2, 0xAA, 0xD6, 0xA6, 0x12, 0xF3, 0x33, 0x07, 0xBE,
+        0x5F, 0xA4, 0x7C, 0x3C, 0x9E, 0x05, 0x2F, 0x83, 0x81, 0x64, 0xCD, 0x37,
+        0xD9, 0xA2, 0x11, 0x73
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 72 * 6];
+} _EC_NIST_CHAR2_571K = {
+    {
+        NID_X9_62_characteristic_two_field, 0, 72, 4
+    },
+    {
+        /* no seed */
+        /* p */
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x25,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        /* b */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        /* x */
+        0x02, 0x6E, 0xB7, 0xA8, 0x59, 0x92, 0x3F, 0xBC, 0x82, 0x18, 0x96, 0x31,
+        0xF8, 0x10, 0x3F, 0xE4, 0xAC, 0x9C, 0xA2, 0x97, 0x00, 0x12, 0xD5, 0xD4,
+        0x60, 0x24, 0x80, 0x48, 0x01, 0x84, 0x1C, 0xA4, 0x43, 0x70, 0x95, 0x84,
+        0x93, 0xB2, 0x05, 0xE6, 0x47, 0xDA, 0x30, 0x4D, 0xB4, 0xCE, 0xB0, 0x8C,
+        0xBB, 0xD1, 0xBA, 0x39, 0x49, 0x47, 0x76, 0xFB, 0x98, 0x8B, 0x47, 0x17,
+        0x4D, 0xCA, 0x88, 0xC7, 0xE2, 0x94, 0x52, 0x83, 0xA0, 0x1C, 0x89, 0x72,
+        /* y */
+        0x03, 0x49, 0xDC, 0x80, 0x7F, 0x4F, 0xBF, 0x37, 0x4F, 0x4A, 0xEA, 0xDE,
+        0x3B, 0xCA, 0x95, 0x31, 0x4D, 0xD5, 0x8C, 0xEC, 0x9F, 0x30, 0x7A, 0x54,
+        0xFF, 0xC6, 0x1E, 0xFC, 0x00, 0x6D, 0x8A, 0x2C, 0x9D, 0x49, 0x79, 0xC0,
+        0xAC, 0x44, 0xAE, 0xA7, 0x4F, 0xBE, 0xBB, 0xB9, 0xF7, 0x72, 0xAE, 0xDC,
+        0xB6, 0x20, 0xB0, 0x1A, 0x7B, 0xA7, 0xAF, 0x1B, 0x32, 0x04, 0x30, 0xC8,
+        0x59, 0x19, 0x84, 0xF6, 0x01, 0xCD, 0x4C, 0x14, 0x3E, 0xF1, 0xC7, 0xA3,
+        /* order */
+        0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x13, 0x18, 0x50, 0xE1, 0xF1, 0x9A, 0x63, 0xE4, 0xB3, 0x91, 0xA8, 0xDB,
+        0x91, 0x7F, 0x41, 0x38, 0xB6, 0x30, 0xD8, 0x4B, 0xE5, 0xD6, 0x39, 0x38,
+        0x1E, 0x91, 0xDE, 0xB4, 0x5C, 0xFE, 0x77, 0x8F, 0x63, 0x7C, 0x10, 0x01
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 72 * 6];
+} _EC_NIST_CHAR2_571B = {
+    {
+        NID_X9_62_characteristic_two_field, 20, 72, 2
+    },
+    {
+        /* seed */
+        0x2A, 0xA0, 0x58, 0xF7, 0x3A, 0x0E, 0x33, 0xAB, 0x48, 0x6B, 0x0F, 0x61,
+        0x04, 0x10, 0xC5, 0x3A, 0x7F, 0x13, 0x23, 0x10,
+        /* p */
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x25,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        /* b */
+        0x02, 0xF4, 0x0E, 0x7E, 0x22, 0x21, 0xF2, 0x95, 0xDE, 0x29, 0x71, 0x17,
+        0xB7, 0xF3, 0xD6, 0x2F, 0x5C, 0x6A, 0x97, 0xFF, 0xCB, 0x8C, 0xEF, 0xF1,
+        0xCD, 0x6B, 0xA8, 0xCE, 0x4A, 0x9A, 0x18, 0xAD, 0x84, 0xFF, 0xAB, 0xBD,
+        0x8E, 0xFA, 0x59, 0x33, 0x2B, 0xE7, 0xAD, 0x67, 0x56, 0xA6, 0x6E, 0x29,
+        0x4A, 0xFD, 0x18, 0x5A, 0x78, 0xFF, 0x12, 0xAA, 0x52, 0x0E, 0x4D, 0xE7,
+        0x39, 0xBA, 0xCA, 0x0C, 0x7F, 0xFE, 0xFF, 0x7F, 0x29, 0x55, 0x72, 0x7A,
+        /* x */
+        0x03, 0x03, 0x00, 0x1D, 0x34, 0xB8, 0x56, 0x29, 0x6C, 0x16, 0xC0, 0xD4,
+        0x0D, 0x3C, 0xD7, 0x75, 0x0A, 0x93, 0xD1, 0xD2, 0x95, 0x5F, 0xA8, 0x0A,
+        0xA5, 0xF4, 0x0F, 0xC8, 0xDB, 0x7B, 0x2A, 0xBD, 0xBD, 0xE5, 0x39, 0x50,
+        0xF4, 0xC0, 0xD2, 0x93, 0xCD, 0xD7, 0x11, 0xA3, 0x5B, 0x67, 0xFB, 0x14,
+        0x99, 0xAE, 0x60, 0x03, 0x86, 0x14, 0xF1, 0x39, 0x4A, 0xBF, 0xA3, 0xB4,
+        0xC8, 0x50, 0xD9, 0x27, 0xE1, 0xE7, 0x76, 0x9C, 0x8E, 0xEC, 0x2D, 0x19,
+        /* y */
+        0x03, 0x7B, 0xF2, 0x73, 0x42, 0xDA, 0x63, 0x9B, 0x6D, 0xCC, 0xFF, 0xFE,
+        0xB7, 0x3D, 0x69, 0xD7, 0x8C, 0x6C, 0x27, 0xA6, 0x00, 0x9C, 0xBB, 0xCA,
+        0x19, 0x80, 0xF8, 0x53, 0x39, 0x21, 0xE8, 0xA6, 0x84, 0x42, 0x3E, 0x43,
+        0xBA, 0xB0, 0x8A, 0x57, 0x62, 0x91, 0xAF, 0x8F, 0x46, 0x1B, 0xB2, 0xA8,
+        0xB3, 0x53, 0x1D, 0x2F, 0x04, 0x85, 0xC1, 0x9B, 0x16, 0xE2, 0xF1, 0x51,
+        0x6E, 0x23, 0xDD, 0x3C, 0x1A, 0x48, 0x27, 0xAF, 0x1B, 0x8A, 0xC1, 0x5B,
+        /* order */
+        0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xE6, 0x61, 0xCE, 0x18, 0xFF, 0x55, 0x98, 0x73, 0x08, 0x05, 0x9B, 0x18,
+        0x68, 0x23, 0x85, 0x1E, 0xC7, 0xDD, 0x9C, 0xA1, 0x16, 0x1D, 0xE9, 0x3D,
+        0x51, 0x74, 0xD6, 0x6E, 0x83, 0x82, 0xE9, 0xBB, 0x2F, 0xE8, 0x4E, 0x47
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 21 * 6];
+} _EC_X9_62_CHAR2_163V1 = {
+    {
+        NID_X9_62_characteristic_two_field, 20, 21, 2
+    },
+    {
+        /* seed */
+        0xD2, 0xC0, 0xFB, 0x15, 0x76, 0x08, 0x60, 0xDE, 0xF1, 0xEE, 0xF4, 0xD6,
+        0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x54,
+        /* p */
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
+        /* a */
+        0x07, 0x25, 0x46, 0xB5, 0x43, 0x52, 0x34, 0xA4, 0x22, 0xE0, 0x78, 0x96,
+        0x75, 0xF4, 0x32, 0xC8, 0x94, 0x35, 0xDE, 0x52, 0x42,
+        /* b */
+        0x00, 0xC9, 0x51, 0x7D, 0x06, 0xD5, 0x24, 0x0D, 0x3C, 0xFF, 0x38, 0xC7,
+        0x4B, 0x20, 0xB6, 0xCD, 0x4D, 0x6F, 0x9D, 0xD4, 0xD9,
+        /* x */
+        0x07, 0xAF, 0x69, 0x98, 0x95, 0x46, 0x10, 0x3D, 0x79, 0x32, 0x9F, 0xCC,
+        0x3D, 0x74, 0x88, 0x0F, 0x33, 0xBB, 0xE8, 0x03, 0xCB,
+        /* y */
+        0x01, 0xEC, 0x23, 0x21, 0x1B, 0x59, 0x66, 0xAD, 0xEA, 0x1D, 0x3F, 0x87,
+        0xF7, 0xEA, 0x58, 0x48, 0xAE, 0xF0, 0xB7, 0xCA, 0x9F,
+        /* order */
+        0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE6,
+        0x0F, 0xC8, 0x82, 0x1C, 0xC7, 0x4D, 0xAE, 0xAF, 0xC1
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 21 * 6];
+} _EC_X9_62_CHAR2_163V2 = {
+    {
+        NID_X9_62_characteristic_two_field, 20, 21, 2
+    },
+    {
+        /* seed */
+        0x53, 0x81, 0x4C, 0x05, 0x0D, 0x44, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56,
+        0x15, 0x17, 0x58, 0x0C, 0xA4, 0xE2, 0x9F, 0xFD,
+        /* p */
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
+        /* a */
+        0x01, 0x08, 0xB3, 0x9E, 0x77, 0xC4, 0xB1, 0x08, 0xBE, 0xD9, 0x81, 0xED,
+        0x0E, 0x89, 0x0E, 0x11, 0x7C, 0x51, 0x1C, 0xF0, 0x72,
+        /* b */
+        0x06, 0x67, 0xAC, 0xEB, 0x38, 0xAF, 0x4E, 0x48, 0x8C, 0x40, 0x74, 0x33,
+        0xFF, 0xAE, 0x4F, 0x1C, 0x81, 0x16, 0x38, 0xDF, 0x20,
+        /* x */
+        0x00, 0x24, 0x26, 0x6E, 0x4E, 0xB5, 0x10, 0x6D, 0x0A, 0x96, 0x4D, 0x92,
+        0xC4, 0x86, 0x0E, 0x26, 0x71, 0xDB, 0x9B, 0x6C, 0xC5,
+        /* y */
+        0x07, 0x9F, 0x68, 0x4D, 0xDF, 0x66, 0x84, 0xC5, 0xCD, 0x25, 0x8B, 0x38,
+        0x90, 0x02, 0x1B, 0x23, 0x86, 0xDF, 0xD1, 0x9F, 0xC5,
+        /* order */
+        0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xF6,
+        0x4D, 0xE1, 0x15, 0x1A, 0xDB, 0xB7, 0x8F, 0x10, 0xA7
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 21 * 6];
+} _EC_X9_62_CHAR2_163V3 = {
+    {
+        NID_X9_62_characteristic_two_field, 20, 21, 2
+    },
+    {
+        /* seed */
+        0x50, 0xCB, 0xF1, 0xD9, 0x5C, 0xA9, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75,
+        0x61, 0x51, 0x75, 0xF1, 0x6A, 0x36, 0xA3, 0xB8,
+        /* p */
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
+        /* a */
+        0x07, 0xA5, 0x26, 0xC6, 0x3D, 0x3E, 0x25, 0xA2, 0x56, 0xA0, 0x07, 0x69,
+        0x9F, 0x54, 0x47, 0xE3, 0x2A, 0xE4, 0x56, 0xB5, 0x0E,
+        /* b */
+        0x03, 0xF7, 0x06, 0x17, 0x98, 0xEB, 0x99, 0xE2, 0x38, 0xFD, 0x6F, 0x1B,
+        0xF9, 0x5B, 0x48, 0xFE, 0xEB, 0x48, 0x54, 0x25, 0x2B,
+        /* x */
+        0x02, 0xF9, 0xF8, 0x7B, 0x7C, 0x57, 0x4D, 0x0B, 0xDE, 0xCF, 0x8A, 0x22,
+        0xE6, 0x52, 0x47, 0x75, 0xF9, 0x8C, 0xDE, 0xBD, 0xCB,
+        /* y */
+        0x05, 0xB9, 0x35, 0x59, 0x0C, 0x15, 0x5E, 0x17, 0xEA, 0x48, 0xEB, 0x3F,
+        0xF3, 0x71, 0x8B, 0x89, 0x3D, 0xF5, 0x9A, 0x05, 0xD0,
+        /* order */
+        0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x1A,
+        0xEE, 0x14, 0x0F, 0x11, 0x0A, 0xFF, 0x96, 0x13, 0x09
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 23 * 6];
+} _EC_X9_62_CHAR2_176V1 = {
+    {
+        NID_X9_62_characteristic_two_field, 0, 23, 0xFF6E
+    },
+    {
+        /* no seed */
+        /* p */
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x07,
+        /* a */
+        0x00, 0xE4, 0xE6, 0xDB, 0x29, 0x95, 0x06, 0x5C, 0x40, 0x7D, 0x9D, 0x39,
+        0xB8, 0xD0, 0x96, 0x7B, 0x96, 0x70, 0x4B, 0xA8, 0xE9, 0xC9, 0x0B,
+        /* b */
+        0x00, 0x5D, 0xDA, 0x47, 0x0A, 0xBE, 0x64, 0x14, 0xDE, 0x8E, 0xC1, 0x33,
+        0xAE, 0x28, 0xE9, 0xBB, 0xD7, 0xFC, 0xEC, 0x0A, 0xE0, 0xFF, 0xF2,
+        /* x */
+        0x00, 0x8D, 0x16, 0xC2, 0x86, 0x67, 0x98, 0xB6, 0x00, 0xF9, 0xF0, 0x8B,
+        0xB4, 0xA8, 0xE8, 0x60, 0xF3, 0x29, 0x8C, 0xE0, 0x4A, 0x57, 0x98,
+        /* y */
+        0x00, 0x6F, 0xA4, 0x53, 0x9C, 0x2D, 0xAD, 0xDD, 0xD6, 0xBA, 0xB5, 0x16,
+        0x7D, 0x61, 0xB4, 0x36, 0xE1, 0xD9, 0x2B, 0xB1, 0x6A, 0x56, 0x2C,
+        /* order */
+        0x00, 0x00, 0x01, 0x00, 0x92, 0x53, 0x73, 0x97, 0xEC, 0xA4, 0xF6, 0x14,
+        0x57, 0x99, 0xD6, 0x2B, 0x0A, 0x19, 0xCE, 0x06, 0xFE, 0x26, 0xAD
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 24 * 6];
+} _EC_X9_62_CHAR2_191V1 = {
+    {
+        NID_X9_62_characteristic_two_field, 20, 24, 2
+    },
+    {
+        /* seed */
+        0x4E, 0x13, 0xCA, 0x54, 0x27, 0x44, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56,
+        0x15, 0x17, 0x55, 0x2F, 0x27, 0x9A, 0x8C, 0x84,
+        /* p */
+        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01,
+        /* a */
+        0x28, 0x66, 0x53, 0x7B, 0x67, 0x67, 0x52, 0x63, 0x6A, 0x68, 0xF5, 0x65,
+        0x54, 0xE1, 0x26, 0x40, 0x27, 0x6B, 0x64, 0x9E, 0xF7, 0x52, 0x62, 0x67,
+        /* b */
+        0x2E, 0x45, 0xEF, 0x57, 0x1F, 0x00, 0x78, 0x6F, 0x67, 0xB0, 0x08, 0x1B,
+        0x94, 0x95, 0xA3, 0xD9, 0x54, 0x62, 0xF5, 0xDE, 0x0A, 0xA1, 0x85, 0xEC,
+        /* x */
+        0x36, 0xB3, 0xDA, 0xF8, 0xA2, 0x32, 0x06, 0xF9, 0xC4, 0xF2, 0x99, 0xD7,
+        0xB2, 0x1A, 0x9C, 0x36, 0x91, 0x37, 0xF2, 0xC8, 0x4A, 0xE1, 0xAA, 0x0D,
+        /* y */
+        0x76, 0x5B, 0xE7, 0x34, 0x33, 0xB3, 0xF9, 0x5E, 0x33, 0x29, 0x32, 0xE7,
+        0x0E, 0xA2, 0x45, 0xCA, 0x24, 0x18, 0xEA, 0x0E, 0xF9, 0x80, 0x18, 0xFB,
+        /* order */
+        0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x04, 0xA2, 0x0E, 0x90, 0xC3, 0x90, 0x67, 0xC8, 0x93, 0xBB, 0xB9, 0xA5
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 24 * 6];
+} _EC_X9_62_CHAR2_191V2 = {
+    {
+        NID_X9_62_characteristic_two_field, 20, 24, 4
+    },
+    {
+        /* seed */
+        0x08, 0x71, 0xEF, 0x2F, 0xEF, 0x24, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56,
+        0x15, 0x17, 0x58, 0xBE, 0xE0, 0xD9, 0x5C, 0x15,
+        /* p */
+        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01,
+        /* a */
+        0x40, 0x10, 0x28, 0x77, 0x4D, 0x77, 0x77, 0xC7, 0xB7, 0x66, 0x6D, 0x13,
+        0x66, 0xEA, 0x43, 0x20, 0x71, 0x27, 0x4F, 0x89, 0xFF, 0x01, 0xE7, 0x18,
+        /* b */
+        0x06, 0x20, 0x04, 0x8D, 0x28, 0xBC, 0xBD, 0x03, 0xB6, 0x24, 0x9C, 0x99,
+        0x18, 0x2B, 0x7C, 0x8C, 0xD1, 0x97, 0x00, 0xC3, 0x62, 0xC4, 0x6A, 0x01,
+        /* x */
+        0x38, 0x09, 0xB2, 0xB7, 0xCC, 0x1B, 0x28, 0xCC, 0x5A, 0x87, 0x92, 0x6A,
+        0xAD, 0x83, 0xFD, 0x28, 0x78, 0x9E, 0x81, 0xE2, 0xC9, 0xE3, 0xBF, 0x10,
+        /* y */
+        0x17, 0x43, 0x43, 0x86, 0x62, 0x6D, 0x14, 0xF3, 0xDB, 0xF0, 0x17, 0x60,
+        0xD9, 0x21, 0x3A, 0x3E, 0x1C, 0xF3, 0x7A, 0xEC, 0x43, 0x7D, 0x66, 0x8A,
+        /* order */
+        0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x50, 0x50, 0x8C, 0xB8, 0x9F, 0x65, 0x28, 0x24, 0xE0, 0x6B, 0x81, 0x73
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 24 * 6];
+} _EC_X9_62_CHAR2_191V3 = {
+    {
+        NID_X9_62_characteristic_two_field, 20, 24, 6
+    },
+    {
+        /* seed */
+        0xE0, 0x53, 0x51, 0x2D, 0xC6, 0x84, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56,
+        0x15, 0x17, 0x50, 0x67, 0xAE, 0x78, 0x6D, 0x1F,
+        /* p */
+        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01,
+        /* a */
+        0x6C, 0x01, 0x07, 0x47, 0x56, 0x09, 0x91, 0x22, 0x22, 0x10, 0x56, 0x91,
+        0x1C, 0x77, 0xD7, 0x7E, 0x77, 0xA7, 0x77, 0xE7, 0xE7, 0xE7, 0x7F, 0xCB,
+        /* b */
+        0x71, 0xFE, 0x1A, 0xF9, 0x26, 0xCF, 0x84, 0x79, 0x89, 0xEF, 0xEF, 0x8D,
+        0xB4, 0x59, 0xF6, 0x63, 0x94, 0xD9, 0x0F, 0x32, 0xAD, 0x3F, 0x15, 0xE8,
+        /* x */
+        0x37, 0x5D, 0x4C, 0xE2, 0x4F, 0xDE, 0x43, 0x44, 0x89, 0xDE, 0x87, 0x46,
+        0xE7, 0x17, 0x86, 0x01, 0x50, 0x09, 0xE6, 0x6E, 0x38, 0xA9, 0x26, 0xDD,
+        /* y */
+        0x54, 0x5A, 0x39, 0x17, 0x61, 0x96, 0x57, 0x5D, 0x98, 0x59, 0x99, 0x36,
+        0x6E, 0x6A, 0xD3, 0x4C, 0xE0, 0xA7, 0x7C, 0xD7, 0x12, 0x7B, 0x06, 0xBE,
+        /* order */
+        0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+        0x61, 0x0C, 0x0B, 0x19, 0x68, 0x12, 0xBF, 0xB6, 0x28, 0x8A, 0x3E, 0xA3
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 27 * 6];
+} _EC_X9_62_CHAR2_208W1 = {
+    {
+        NID_X9_62_characteristic_two_field, 0, 27, 0xFE48
+    },
+    {
+        /* no seed */
+        /* p */
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x07,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00,
+        /* b */
+        0x00, 0xC8, 0x61, 0x9E, 0xD4, 0x5A, 0x62, 0xE6, 0x21, 0x2E, 0x11, 0x60,
+        0x34, 0x9E, 0x2B, 0xFA, 0x84, 0x44, 0x39, 0xFA, 0xFC, 0x2A, 0x3F, 0xD1,
+        0x63, 0x8F, 0x9E,
+        /* x */
+        0x00, 0x89, 0xFD, 0xFB, 0xE4, 0xAB, 0xE1, 0x93, 0xDF, 0x95, 0x59, 0xEC,
+        0xF0, 0x7A, 0xC0, 0xCE, 0x78, 0x55, 0x4E, 0x27, 0x84, 0xEB, 0x8C, 0x1E,
+        0xD1, 0xA5, 0x7A,
+        /* y */
+        0x00, 0x0F, 0x55, 0xB5, 0x1A, 0x06, 0xE7, 0x8E, 0x9A, 0xC3, 0x8A, 0x03,
+        0x5F, 0xF5, 0x20, 0xD8, 0xB0, 0x17, 0x81, 0xBE, 0xB1, 0xA6, 0xBB, 0x08,
+        0x61, 0x7D, 0xE3,
+        /* order */
+        0x00, 0x00, 0x01, 0x01, 0xBA, 0xF9, 0x5C, 0x97, 0x23, 0xC5, 0x7B, 0x6C,
+        0x21, 0xDA, 0x2E, 0xFF, 0x2D, 0x5E, 0xD5, 0x88, 0xBD, 0xD5, 0x71, 0x7E,
+        0x21, 0x2F, 0x9D
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 30 * 6];
+} _EC_X9_62_CHAR2_239V1 = {
+    {
+        NID_X9_62_characteristic_two_field, 20, 30, 4
+    },
+    {
+        /* seed */
+        0xD3, 0x4B, 0x9A, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75,
+        0xCA, 0x71, 0xB9, 0x20, 0xBF, 0xEF, 0xB0, 0x5D,
+        /* p */
+        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
+        /* a */
+        0x32, 0x01, 0x08, 0x57, 0x07, 0x7C, 0x54, 0x31, 0x12, 0x3A, 0x46, 0xB8,
+        0x08, 0x90, 0x67, 0x56, 0xF5, 0x43, 0x42, 0x3E, 0x8D, 0x27, 0x87, 0x75,
+        0x78, 0x12, 0x57, 0x78, 0xAC, 0x76,
+        /* b */
+        0x79, 0x04, 0x08, 0xF2, 0xEE, 0xDA, 0xF3, 0x92, 0xB0, 0x12, 0xED, 0xEF,
+        0xB3, 0x39, 0x2F, 0x30, 0xF4, 0x32, 0x7C, 0x0C, 0xA3, 0xF3, 0x1F, 0xC3,
+        0x83, 0xC4, 0x22, 0xAA, 0x8C, 0x16,
+        /* x */
+        0x57, 0x92, 0x70, 0x98, 0xFA, 0x93, 0x2E, 0x7C, 0x0A, 0x96, 0xD3, 0xFD,
+        0x5B, 0x70, 0x6E, 0xF7, 0xE5, 0xF5, 0xC1, 0x56, 0xE1, 0x6B, 0x7E, 0x7C,
+        0x86, 0x03, 0x85, 0x52, 0xE9, 0x1D,
+        /* y */
+        0x61, 0xD8, 0xEE, 0x50, 0x77, 0xC3, 0x3F, 0xEC, 0xF6, 0xF1, 0xA1, 0x6B,
+        0x26, 0x8D, 0xE4, 0x69, 0xC3, 0xC7, 0x74, 0x4E, 0xA9, 0xA9, 0x71, 0x64,
+        0x9F, 0xC7, 0xA9, 0x61, 0x63, 0x05,
+        /* order */
+        0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x0F, 0x4D, 0x42, 0xFF, 0xE1, 0x49, 0x2A, 0x49, 0x93,
+        0xF1, 0xCA, 0xD6, 0x66, 0xE4, 0x47
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 30 * 6];
+} _EC_X9_62_CHAR2_239V2 = {
+    {
+        NID_X9_62_characteristic_two_field, 20, 30, 6
+    },
+    {
+        /* seed */
+        0x2A, 0xA6, 0x98, 0x2F, 0xDF, 0xA4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56,
+        0x15, 0x17, 0x5D, 0x26, 0x67, 0x27, 0x27, 0x7D,
+        /* p */
+        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
+        /* a */
+        0x42, 0x30, 0x01, 0x77, 0x57, 0xA7, 0x67, 0xFA, 0xE4, 0x23, 0x98, 0x56,
+        0x9B, 0x74, 0x63, 0x25, 0xD4, 0x53, 0x13, 0xAF, 0x07, 0x66, 0x26, 0x64,
+        0x79, 0xB7, 0x56, 0x54, 0xE6, 0x5F,
+        /* b */
+        0x50, 0x37, 0xEA, 0x65, 0x41, 0x96, 0xCF, 0xF0, 0xCD, 0x82, 0xB2, 0xC1,
+        0x4A, 0x2F, 0xCF, 0x2E, 0x3F, 0xF8, 0x77, 0x52, 0x85, 0xB5, 0x45, 0x72,
+        0x2F, 0x03, 0xEA, 0xCD, 0xB7, 0x4B,
+        /* x */
+        0x28, 0xF9, 0xD0, 0x4E, 0x90, 0x00, 0x69, 0xC8, 0xDC, 0x47, 0xA0, 0x85,
+        0x34, 0xFE, 0x76, 0xD2, 0xB9, 0x00, 0xB7, 0xD7, 0xEF, 0x31, 0xF5, 0x70,
+        0x9F, 0x20, 0x0C, 0x4C, 0xA2, 0x05,
+        /* y */
+        0x56, 0x67, 0x33, 0x4C, 0x45, 0xAF, 0xF3, 0xB5, 0xA0, 0x3B, 0xAD, 0x9D,
+        0xD7, 0x5E, 0x2C, 0x71, 0xA9, 0x93, 0x62, 0x56, 0x7D, 0x54, 0x53, 0xF7,
+        0xFA, 0x6E, 0x22, 0x7E, 0xC8, 0x33,
+        /* order */
+        0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+        0x55, 0x55, 0x55, 0x3C, 0x6F, 0x28, 0x85, 0x25, 0x9C, 0x31, 0xE3, 0xFC,
+        0xDF, 0x15, 0x46, 0x24, 0x52, 0x2D
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 30 * 6];
+} _EC_X9_62_CHAR2_239V3 = {
+    {
+        NID_X9_62_characteristic_two_field, 20, 30, 0xA
+    },
+    {
+        /* seed */
+        0x9E, 0x07, 0x6F, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75,
+        0xE1, 0x1E, 0x9F, 0xDD, 0x77, 0xF9, 0x20, 0x41,
+        /* p */
+        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x10, 0x00, 0x00, 0x00, 0x01,
+        /* a */
+        0x01, 0x23, 0x87, 0x74, 0x66, 0x6A, 0x67, 0x76, 0x6D, 0x66, 0x76, 0xF7,
+        0x78, 0xE6, 0x76, 0xB6, 0x69, 0x99, 0x17, 0x66, 0x66, 0xE6, 0x87, 0x66,
+        0x6D, 0x87, 0x66, 0xC6, 0x6A, 0x9F,
+        /* b */
+        0x6A, 0x94, 0x19, 0x77, 0xBA, 0x9F, 0x6A, 0x43, 0x51, 0x99, 0xAC, 0xFC,
+        0x51, 0x06, 0x7E, 0xD5, 0x87, 0xF5, 0x19, 0xC5, 0xEC, 0xB5, 0x41, 0xB8,
+        0xE4, 0x41, 0x11, 0xDE, 0x1D, 0x40,
+        /* x */
+        0x70, 0xF6, 0xE9, 0xD0, 0x4D, 0x28, 0x9C, 0x4E, 0x89, 0x91, 0x3C, 0xE3,
+        0x53, 0x0B, 0xFD, 0xE9, 0x03, 0x97, 0x7D, 0x42, 0xB1, 0x46, 0xD5, 0x39,
+        0xBF, 0x1B, 0xDE, 0x4E, 0x9C, 0x92,
+        /* y */
+        0x2E, 0x5A, 0x0E, 0xAF, 0x6E, 0x5E, 0x13, 0x05, 0xB9, 0x00, 0x4D, 0xCE,
+        0x5C, 0x0E, 0xD7, 0xFE, 0x59, 0xA3, 0x56, 0x08, 0xF3, 0x38, 0x37, 0xC8,
+        0x16, 0xD8, 0x0B, 0x79, 0xF4, 0x61,
+        /* order */
+        0x0C, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
+        0xCC, 0xCC, 0xCC, 0xAC, 0x49, 0x12, 0xD2, 0xD9, 0xDF, 0x90, 0x3E, 0xF9,
+        0x88, 0x8B, 0x8A, 0x0E, 0x4C, 0xFF
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 35 * 6];
+} _EC_X9_62_CHAR2_272W1 = {
+    {
+        NID_X9_62_characteristic_two_field, 0, 35, 0xFF06
+    },
+    {
+        /* no seed */
+        /* p */
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B,
+        /* a */
+        0x00, 0x91, 0xA0, 0x91, 0xF0, 0x3B, 0x5F, 0xBA, 0x4A, 0xB2, 0xCC, 0xF4,
+        0x9C, 0x4E, 0xDD, 0x22, 0x0F, 0xB0, 0x28, 0x71, 0x2D, 0x42, 0xBE, 0x75,
+        0x2B, 0x2C, 0x40, 0x09, 0x4D, 0xBA, 0xCD, 0xB5, 0x86, 0xFB, 0x20,
+        /* b */
+        0x00, 0x71, 0x67, 0xEF, 0xC9, 0x2B, 0xB2, 0xE3, 0xCE, 0x7C, 0x8A, 0xAA,
+        0xFF, 0x34, 0xE1, 0x2A, 0x9C, 0x55, 0x70, 0x03, 0xD7, 0xC7, 0x3A, 0x6F,
+        0xAF, 0x00, 0x3F, 0x99, 0xF6, 0xCC, 0x84, 0x82, 0xE5, 0x40, 0xF7,
+        /* x */
+        0x00, 0x61, 0x08, 0xBA, 0xBB, 0x2C, 0xEE, 0xBC, 0xF7, 0x87, 0x05, 0x8A,
+        0x05, 0x6C, 0xBE, 0x0C, 0xFE, 0x62, 0x2D, 0x77, 0x23, 0xA2, 0x89, 0xE0,
+        0x8A, 0x07, 0xAE, 0x13, 0xEF, 0x0D, 0x10, 0xD1, 0x71, 0xDD, 0x8D,
+        /* y */
+        0x00, 0x10, 0xC7, 0x69, 0x57, 0x16, 0x85, 0x1E, 0xEF, 0x6B, 0xA7, 0xF6,
+        0x87, 0x2E, 0x61, 0x42, 0xFB, 0xD2, 0x41, 0xB8, 0x30, 0xFF, 0x5E, 0xFC,
+        0xAC, 0xEC, 0xCA, 0xB0, 0x5E, 0x02, 0x00, 0x5D, 0xDE, 0x9D, 0x23,
+        /* order */
+        0x00, 0x00, 0x01, 0x00, 0xFA, 0xF5, 0x13, 0x54, 0xE0, 0xE3, 0x9E, 0x48,
+        0x92, 0xDF, 0x6E, 0x31, 0x9C, 0x72, 0xC8, 0x16, 0x16, 0x03, 0xFA, 0x45,
+        0xAA, 0x7B, 0x99, 0x8A, 0x16, 0x7B, 0x8F, 0x1E, 0x62, 0x95, 0x21
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 39 * 6];
+} _EC_X9_62_CHAR2_304W1 = {
+    {
+        NID_X9_62_characteristic_two_field, 0, 39, 0xFE2E
+    },
+    {
+        /* no seed */
+        /* p */
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x08, 0x07,
+        /* a */
+        0x00, 0xFD, 0x0D, 0x69, 0x31, 0x49, 0xA1, 0x18, 0xF6, 0x51, 0xE6, 0xDC,
+        0xE6, 0x80, 0x20, 0x85, 0x37, 0x7E, 0x5F, 0x88, 0x2D, 0x1B, 0x51, 0x0B,
+        0x44, 0x16, 0x00, 0x74, 0xC1, 0x28, 0x80, 0x78, 0x36, 0x5A, 0x03, 0x96,
+        0xC8, 0xE6, 0x81,
+        /* b */
+        0x00, 0xBD, 0xDB, 0x97, 0xE5, 0x55, 0xA5, 0x0A, 0x90, 0x8E, 0x43, 0xB0,
+        0x1C, 0x79, 0x8E, 0xA5, 0xDA, 0xA6, 0x78, 0x8F, 0x1E, 0xA2, 0x79, 0x4E,
+        0xFC, 0xF5, 0x71, 0x66, 0xB8, 0xC1, 0x40, 0x39, 0x60, 0x1E, 0x55, 0x82,
+        0x73, 0x40, 0xBE,
+        /* x */
+        0x00, 0x19, 0x7B, 0x07, 0x84, 0x5E, 0x9B, 0xE2, 0xD9, 0x6A, 0xDB, 0x0F,
+        0x5F, 0x3C, 0x7F, 0x2C, 0xFF, 0xBD, 0x7A, 0x3E, 0xB8, 0xB6, 0xFE, 0xC3,
+        0x5C, 0x7F, 0xD6, 0x7F, 0x26, 0xDD, 0xF6, 0x28, 0x5A, 0x64, 0x4F, 0x74,
+        0x0A, 0x26, 0x14,
+        /* y */
+        0x00, 0xE1, 0x9F, 0xBE, 0xB7, 0x6E, 0x0D, 0xA1, 0x71, 0x51, 0x7E, 0xCF,
+        0x40, 0x1B, 0x50, 0x28, 0x9B, 0xF0, 0x14, 0x10, 0x32, 0x88, 0x52, 0x7A,
+        0x9B, 0x41, 0x6A, 0x10, 0x5E, 0x80, 0x26, 0x0B, 0x54, 0x9F, 0xDC, 0x1B,
+        0x92, 0xC0, 0x3B,
+        /* order */
+        0x00, 0x00, 0x01, 0x01, 0xD5, 0x56, 0x57, 0x2A, 0xAB, 0xAC, 0x80, 0x01,
+        0x01, 0xD5, 0x56, 0x57, 0x2A, 0xAB, 0xAC, 0x80, 0x01, 0x02, 0x2D, 0x5C,
+        0x91, 0xDD, 0x17, 0x3F, 0x8F, 0xB5, 0x61, 0xDA, 0x68, 0x99, 0x16, 0x44,
+        0x43, 0x05, 0x1D
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[20 + 45 * 6];
+} _EC_X9_62_CHAR2_359V1 = {
+    {
+        NID_X9_62_characteristic_two_field, 20, 45, 0x4C
+    },
+    {
+        /* seed */
+        0x2B, 0x35, 0x49, 0x20, 0xB7, 0x24, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56,
+        0x15, 0x17, 0x58, 0x5B, 0xA1, 0x33, 0x2D, 0xC6,
+        /* p */
+        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        /* a */
+        0x56, 0x67, 0x67, 0x6A, 0x65, 0x4B, 0x20, 0x75, 0x4F, 0x35, 0x6E, 0xA9,
+        0x20, 0x17, 0xD9, 0x46, 0x56, 0x7C, 0x46, 0x67, 0x55, 0x56, 0xF1, 0x95,
+        0x56, 0xA0, 0x46, 0x16, 0xB5, 0x67, 0xD2, 0x23, 0xA5, 0xE0, 0x56, 0x56,
+        0xFB, 0x54, 0x90, 0x16, 0xA9, 0x66, 0x56, 0xA5, 0x57,
+        /* b */
+        0x24, 0x72, 0xE2, 0xD0, 0x19, 0x7C, 0x49, 0x36, 0x3F, 0x1F, 0xE7, 0xF5,
+        0xB6, 0xDB, 0x07, 0x5D, 0x52, 0xB6, 0x94, 0x7D, 0x13, 0x5D, 0x8C, 0xA4,
+        0x45, 0x80, 0x5D, 0x39, 0xBC, 0x34, 0x56, 0x26, 0x08, 0x96, 0x87, 0x74,
+        0x2B, 0x63, 0x29, 0xE7, 0x06, 0x80, 0x23, 0x19, 0x88,
+        /* x */
+        0x3C, 0x25, 0x8E, 0xF3, 0x04, 0x77, 0x67, 0xE7, 0xED, 0xE0, 0xF1, 0xFD,
+        0xAA, 0x79, 0xDA, 0xEE, 0x38, 0x41, 0x36, 0x6A, 0x13, 0x2E, 0x16, 0x3A,
+        0xCE, 0xD4, 0xED, 0x24, 0x01, 0xDF, 0x9C, 0x6B, 0xDC, 0xDE, 0x98, 0xE8,
+        0xE7, 0x07, 0xC0, 0x7A, 0x22, 0x39, 0xB1, 0xB0, 0x97,
+        /* y */
+        0x53, 0xD7, 0xE0, 0x85, 0x29, 0x54, 0x70, 0x48, 0x12, 0x1E, 0x9C, 0x95,
+        0xF3, 0x79, 0x1D, 0xD8, 0x04, 0x96, 0x39, 0x48, 0xF3, 0x4F, 0xAE, 0x7B,
+        0xF4, 0x4E, 0xA8, 0x23, 0x65, 0xDC, 0x78, 0x68, 0xFE, 0x57, 0xE4, 0xAE,
+        0x2D, 0xE2, 0x11, 0x30, 0x5A, 0x40, 0x71, 0x04, 0xBD,
+        /* order */
+        0x01, 0xAF, 0x28, 0x6B, 0xCA, 0x1A, 0xF2, 0x86, 0xBC, 0xA1, 0xAF, 0x28,
+        0x6B, 0xCA, 0x1A, 0xF2, 0x86, 0xBC, 0xA1, 0xAF, 0x28, 0x6B, 0xC9, 0xFB,
+        0x8F, 0x6B, 0x85, 0xC5, 0x56, 0x89, 0x2C, 0x20, 0xA7, 0xEB, 0x96, 0x4F,
+        0xE7, 0x71, 0x9E, 0x74, 0xF4, 0x90, 0x75, 0x8D, 0x3B
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 47 * 6];
+} _EC_X9_62_CHAR2_368W1 = {
+    {
+        NID_X9_62_characteristic_two_field, 0, 47, 0xFF70
+    },
+    {
+        /* no seed */
+        /* p */
+        0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+        /* a */
+        0x00, 0xE0, 0xD2, 0xEE, 0x25, 0x09, 0x52, 0x06, 0xF5, 0xE2, 0xA4, 0xF9,
+        0xED, 0x22, 0x9F, 0x1F, 0x25, 0x6E, 0x79, 0xA0, 0xE2, 0xB4, 0x55, 0x97,
+        0x0D, 0x8D, 0x0D, 0x86, 0x5B, 0xD9, 0x47, 0x78, 0xC5, 0x76, 0xD6, 0x2F,
+        0x0A, 0xB7, 0x51, 0x9C, 0xCD, 0x2A, 0x1A, 0x90, 0x6A, 0xE3, 0x0D,
+        /* b */
+        0x00, 0xFC, 0x12, 0x17, 0xD4, 0x32, 0x0A, 0x90, 0x45, 0x2C, 0x76, 0x0A,
+        0x58, 0xED, 0xCD, 0x30, 0xC8, 0xDD, 0x06, 0x9B, 0x3C, 0x34, 0x45, 0x38,
+        0x37, 0xA3, 0x4E, 0xD5, 0x0C, 0xB5, 0x49, 0x17, 0xE1, 0xC2, 0x11, 0x2D,
+        0x84, 0xD1, 0x64, 0xF4, 0x44, 0xF8, 0xF7, 0x47, 0x86, 0x04, 0x6A,
+        /* x */
+        0x00, 0x10, 0x85, 0xE2, 0x75, 0x53, 0x81, 0xDC, 0xCC, 0xE3, 0xC1, 0x55,
+        0x7A, 0xFA, 0x10, 0xC2, 0xF0, 0xC0, 0xC2, 0x82, 0x56, 0x46, 0xC5, 0xB3,
+        0x4A, 0x39, 0x4C, 0xBC, 0xFA, 0x8B, 0xC1, 0x6B, 0x22, 0xE7, 0xE7, 0x89,
+        0xE9, 0x27, 0xBE, 0x21, 0x6F, 0x02, 0xE1, 0xFB, 0x13, 0x6A, 0x5F,
+        /* y */
+        0x00, 0x7B, 0x3E, 0xB1, 0xBD, 0xDC, 0xBA, 0x62, 0xD5, 0xD8, 0xB2, 0x05,
+        0x9B, 0x52, 0x57, 0x97, 0xFC, 0x73, 0x82, 0x2C, 0x59, 0x05, 0x9C, 0x62,
+        0x3A, 0x45, 0xFF, 0x38, 0x43, 0xCE, 0xE8, 0xF8, 0x7C, 0xD1, 0x85, 0x5A,
+        0xDA, 0xA8, 0x1E, 0x2A, 0x07, 0x50, 0xB8, 0x0F, 0xDA, 0x23, 0x10,
+        /* order */
+        0x00, 0x00, 0x01, 0x00, 0x90, 0x51, 0x2D, 0xA9, 0xAF, 0x72, 0xB0, 0x83,
+        0x49, 0xD9, 0x8A, 0x5D, 0xD4, 0xC7, 0xB0, 0x53, 0x2E, 0xCA, 0x51, 0xCE,
+        0x03, 0xE2, 0xD1, 0x0F, 0x3B, 0x7A, 0xC5, 0x79, 0xBD, 0x87, 0xE9, 0x09,
+        0xAE, 0x40, 0xA6, 0xF1, 0x31, 0xE9, 0xCF, 0xCE, 0x5B, 0xD9, 0x67
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 54 * 6];
+} _EC_X9_62_CHAR2_431R1 = {
+    {
+        NID_X9_62_characteristic_two_field, 0, 54, 0x2760
+    },
+    {
+        /* no seed */
+        /* p */
+        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        /* a */
+        0x1A, 0x82, 0x7E, 0xF0, 0x0D, 0xD6, 0xFC, 0x0E, 0x23, 0x4C, 0xAF, 0x04,
+        0x6C, 0x6A, 0x5D, 0x8A, 0x85, 0x39, 0x5B, 0x23, 0x6C, 0xC4, 0xAD, 0x2C,
+        0xF3, 0x2A, 0x0C, 0xAD, 0xBD, 0xC9, 0xDD, 0xF6, 0x20, 0xB0, 0xEB, 0x99,
+        0x06, 0xD0, 0x95, 0x7F, 0x6C, 0x6F, 0xEA, 0xCD, 0x61, 0x54, 0x68, 0xDF,
+        0x10, 0x4D, 0xE2, 0x96, 0xCD, 0x8F,
+        /* b */
+        0x10, 0xD9, 0xB4, 0xA3, 0xD9, 0x04, 0x7D, 0x8B, 0x15, 0x43, 0x59, 0xAB,
+        0xFB, 0x1B, 0x7F, 0x54, 0x85, 0xB0, 0x4C, 0xEB, 0x86, 0x82, 0x37, 0xDD,
+        0xC9, 0xDE, 0xDA, 0x98, 0x2A, 0x67, 0x9A, 0x5A, 0x91, 0x9B, 0x62, 0x6D,
+        0x4E, 0x50, 0xA8, 0xDD, 0x73, 0x1B, 0x10, 0x7A, 0x99, 0x62, 0x38, 0x1F,
+        0xB5, 0xD8, 0x07, 0xBF, 0x26, 0x18,
+        /* x */
+        0x12, 0x0F, 0xC0, 0x5D, 0x3C, 0x67, 0xA9, 0x9D, 0xE1, 0x61, 0xD2, 0xF4,
+        0x09, 0x26, 0x22, 0xFE, 0xCA, 0x70, 0x1B, 0xE4, 0xF5, 0x0F, 0x47, 0x58,
+        0x71, 0x4E, 0x8A, 0x87, 0xBB, 0xF2, 0xA6, 0x58, 0xEF, 0x8C, 0x21, 0xE7,
+        0xC5, 0xEF, 0xE9, 0x65, 0x36, 0x1F, 0x6C, 0x29, 0x99, 0xC0, 0xC2, 0x47,
+        0xB0, 0xDB, 0xD7, 0x0C, 0xE6, 0xB7,
+        /* y */
+        0x20, 0xD0, 0xAF, 0x89, 0x03, 0xA9, 0x6F, 0x8D, 0x5F, 0xA2, 0xC2, 0x55,
+        0x74, 0x5D, 0x3C, 0x45, 0x1B, 0x30, 0x2C, 0x93, 0x46, 0xD9, 0xB7, 0xE4,
+        0x85, 0xE7, 0xBC, 0xE4, 0x1F, 0x6B, 0x59, 0x1F, 0x3E, 0x8F, 0x6A, 0xDD,
+        0xCB, 0xB0, 0xBC, 0x4C, 0x2F, 0x94, 0x7A, 0x7D, 0xE1, 0xA8, 0x9B, 0x62,
+        0x5D, 0x6A, 0x59, 0x8B, 0x37, 0x60,
+        /* order */
+        0x00, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40,
+        0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40,
+        0x34, 0x03, 0x40, 0x34, 0x03, 0x23, 0xC3, 0x13, 0xFA, 0xB5, 0x05, 0x89,
+        0x70, 0x3B, 0x5E, 0xC6, 0x8D, 0x35, 0x87, 0xFE, 0xC6, 0x0D, 0x16, 0x1C,
+        0xC1, 0x49, 0xC1, 0xAD, 0x4A, 0x91
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 15 * 6];
+} _EC_WTLS_1 = {
+    {
+        NID_X9_62_characteristic_two_field, 0, 15, 2
+    },
+    {
+        /* no seed */
+        /* p */
+        0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x02, 0x01,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x01,
+        /* b */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x01,
+        /* x */
+        0x01, 0x66, 0x79, 0x79, 0xA4, 0x0B, 0xA4, 0x97, 0xE5, 0xD5, 0xC2, 0x70,
+        0x78, 0x06, 0x17,
+        /* y */
+        0x00, 0xF4, 0x4B, 0x4A, 0xF1, 0xEC, 0xC2, 0x63, 0x0E, 0x08, 0x78, 0x5C,
+        0xEB, 0xCC, 0x15,
+        /* order */
+        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xBF, 0x91, 0xAF,
+        0x6D, 0xEA, 0x73
+    }
+};
+
+/* IPSec curves */
+/*
+ * NOTE: The of curves over a extension field of non prime degree is not
+ * recommended (Weil-descent). As the group order is not a prime this curve
+ * is not suitable for ECDSA.
+ */
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 20 * 6];
+} _EC_IPSEC_155_ID3 = {
+    {
+        NID_X9_62_characteristic_two_field, 0, 20, 3
+    },
+    {
+        /* no seed */
+        /* p */
+        0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        /* b */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x33, 0x8f,
+        /* x */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b,
+        /* y */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc8,
+        /* order */
+        0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xC7, 0xF3,
+        0xC7, 0x88, 0x1B, 0xD0, 0x86, 0x8F, 0xA8, 0x6C
+    }
+};
+
+/*
+ * NOTE: The of curves over a extension field of non prime degree is not
+ * recommended (Weil-descent). As the group order is not a prime this curve
+ * is not suitable for ECDSA.
+ */
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 24 * 6];
+} _EC_IPSEC_185_ID4 = {
+    {
+        NID_X9_62_characteristic_two_field, 0, 24, 2
+    },
+    {
+        /* no seed */
+        /* p */
+        0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+        /* a */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        /* b */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xe9,
+        /* x */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+        /* y */
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
+        /* order */
+        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+        0xED, 0xF9, 0x7C, 0x44, 0xDB, 0x9F, 0x24, 0x20, 0xBA, 0xFC, 0xA7, 0x5E
+    }
+};
+
+#endif
+
+/*
+ * These curves were added by Annie Yousar <a.yousar@informatik.hu-berlin.de>
+ * For the definition of RFC 5639 curves see
+ * http://www.ietf.org/rfc/rfc5639.txt These curves are generated verifiable
+ * at random, nevertheless the seed is omitted as parameter because the
+ * generation mechanism is different from those defined in ANSI X9.62.
+ */
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 20 * 6];
+} _EC_brainpoolP160r1 = {
+    {
+        NID_X9_62_prime_field, 0, 20, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0xC7, 0xAD,
+        0x95, 0xB3, 0xD8, 0x13, 0x95, 0x15, 0x62, 0x0F,
+        /* a */
+        0x34, 0x0E, 0x7B, 0xE2, 0xA2, 0x80, 0xEB, 0x74, 0xE2, 0xBE, 0x61, 0xBA,
+        0xDA, 0x74, 0x5D, 0x97, 0xE8, 0xF7, 0xC3, 0x00,
+        /* b */
+        0x1E, 0x58, 0x9A, 0x85, 0x95, 0x42, 0x34, 0x12, 0x13, 0x4F, 0xAA, 0x2D,
+        0xBD, 0xEC, 0x95, 0xC8, 0xD8, 0x67, 0x5E, 0x58,
+        /* x */
+        0xBE, 0xD5, 0xAF, 0x16, 0xEA, 0x3F, 0x6A, 0x4F, 0x62, 0x93, 0x8C, 0x46,
+        0x31, 0xEB, 0x5A, 0xF7, 0xBD, 0xBC, 0xDB, 0xC3,
+        /* y */
+        0x16, 0x67, 0xCB, 0x47, 0x7A, 0x1A, 0x8E, 0xC3, 0x38, 0xF9, 0x47, 0x41,
+        0x66, 0x9C, 0x97, 0x63, 0x16, 0xDA, 0x63, 0x21,
+        /* order */
+        0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0x59, 0x91,
+        0xD4, 0x50, 0x29, 0x40, 0x9E, 0x60, 0xFC, 0x09
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 20 * 6];
+} _EC_brainpoolP160t1 = {
+    {
+        NID_X9_62_prime_field, 0, 20, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0xC7, 0xAD,
+        0x95, 0xB3, 0xD8, 0x13, 0x95, 0x15, 0x62, 0x0F,
+        /* a */
+        0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0xC7, 0xAD,
+        0x95, 0xB3, 0xD8, 0x13, 0x95, 0x15, 0x62, 0x0C,
+        /* b */
+        0x7A, 0x55, 0x6B, 0x6D, 0xAE, 0x53, 0x5B, 0x7B, 0x51, 0xED, 0x2C, 0x4D,
+        0x7D, 0xAA, 0x7A, 0x0B, 0x5C, 0x55, 0xF3, 0x80,
+        /* x */
+        0xB1, 0x99, 0xB1, 0x3B, 0x9B, 0x34, 0xEF, 0xC1, 0x39, 0x7E, 0x64, 0xBA,
+        0xEB, 0x05, 0xAC, 0xC2, 0x65, 0xFF, 0x23, 0x78,
+        /* y */
+        0xAD, 0xD6, 0x71, 0x8B, 0x7C, 0x7C, 0x19, 0x61, 0xF0, 0x99, 0x1B, 0x84,
+        0x24, 0x43, 0x77, 0x21, 0x52, 0xC9, 0xE0, 0xAD,
+        /* order */
+        0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0x59, 0x91,
+        0xD4, 0x50, 0x29, 0x40, 0x9E, 0x60, 0xFC, 0x09
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 24 * 6];
+} _EC_brainpoolP192r1 = {
+    {
+        NID_X9_62_prime_field, 0, 24, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x30,
+        0x93, 0xD1, 0x8D, 0xB7, 0x8F, 0xCE, 0x47, 0x6D, 0xE1, 0xA8, 0x62, 0x97,
+        /* a */
+        0x6A, 0x91, 0x17, 0x40, 0x76, 0xB1, 0xE0, 0xE1, 0x9C, 0x39, 0xC0, 0x31,
+        0xFE, 0x86, 0x85, 0xC1, 0xCA, 0xE0, 0x40, 0xE5, 0xC6, 0x9A, 0x28, 0xEF,
+        /* b */
+        0x46, 0x9A, 0x28, 0xEF, 0x7C, 0x28, 0xCC, 0xA3, 0xDC, 0x72, 0x1D, 0x04,
+        0x4F, 0x44, 0x96, 0xBC, 0xCA, 0x7E, 0xF4, 0x14, 0x6F, 0xBF, 0x25, 0xC9,
+        /* x */
+        0xC0, 0xA0, 0x64, 0x7E, 0xAA, 0xB6, 0xA4, 0x87, 0x53, 0xB0, 0x33, 0xC5,
+        0x6C, 0xB0, 0xF0, 0x90, 0x0A, 0x2F, 0x5C, 0x48, 0x53, 0x37, 0x5F, 0xD6,
+        /* y */
+        0x14, 0xB6, 0x90, 0x86, 0x6A, 0xBD, 0x5B, 0xB8, 0x8B, 0x5F, 0x48, 0x28,
+        0xC1, 0x49, 0x00, 0x02, 0xE6, 0x77, 0x3F, 0xA2, 0xFA, 0x29, 0x9B, 0x8F,
+        /* order */
+        0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x2F,
+        0x9E, 0x9E, 0x91, 0x6B, 0x5B, 0xE8, 0xF1, 0x02, 0x9A, 0xC4, 0xAC, 0xC1
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 24 * 6];
+} _EC_brainpoolP192t1 = {
+    {
+        NID_X9_62_prime_field, 0, 24, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x30,
+        0x93, 0xD1, 0x8D, 0xB7, 0x8F, 0xCE, 0x47, 0x6D, 0xE1, 0xA8, 0x62, 0x97,
+        /* a */
+        0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x30,
+        0x93, 0xD1, 0x8D, 0xB7, 0x8F, 0xCE, 0x47, 0x6D, 0xE1, 0xA8, 0x62, 0x94,
+        /* b */
+        0x13, 0xD5, 0x6F, 0xFA, 0xEC, 0x78, 0x68, 0x1E, 0x68, 0xF9, 0xDE, 0xB4,
+        0x3B, 0x35, 0xBE, 0xC2, 0xFB, 0x68, 0x54, 0x2E, 0x27, 0x89, 0x7B, 0x79,
+        /* x */
+        0x3A, 0xE9, 0xE5, 0x8C, 0x82, 0xF6, 0x3C, 0x30, 0x28, 0x2E, 0x1F, 0xE7,
+        0xBB, 0xF4, 0x3F, 0xA7, 0x2C, 0x44, 0x6A, 0xF6, 0xF4, 0x61, 0x81, 0x29,
+        /* y */
+        0x09, 0x7E, 0x2C, 0x56, 0x67, 0xC2, 0x22, 0x3A, 0x90, 0x2A, 0xB5, 0xCA,
+        0x44, 0x9D, 0x00, 0x84, 0xB7, 0xE5, 0xB3, 0xDE, 0x7C, 0xCC, 0x01, 0xC9,
+        /* order */
+        0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x2F,
+        0x9E, 0x9E, 0x91, 0x6B, 0x5B, 0xE8, 0xF1, 0x02, 0x9A, 0xC4, 0xAC, 0xC1
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 28 * 6];
+} _EC_brainpoolP224r1 = {
+    {
+        NID_X9_62_prime_field, 0, 28, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25,
+        0x75, 0xD1, 0xD7, 0x87, 0xB0, 0x9F, 0x07, 0x57, 0x97, 0xDA, 0x89, 0xF5,
+        0x7E, 0xC8, 0xC0, 0xFF,
+        /* a */
+        0x68, 0xA5, 0xE6, 0x2C, 0xA9, 0xCE, 0x6C, 0x1C, 0x29, 0x98, 0x03, 0xA6,
+        0xC1, 0x53, 0x0B, 0x51, 0x4E, 0x18, 0x2A, 0xD8, 0xB0, 0x04, 0x2A, 0x59,
+        0xCA, 0xD2, 0x9F, 0x43,
+        /* b */
+        0x25, 0x80, 0xF6, 0x3C, 0xCF, 0xE4, 0x41, 0x38, 0x87, 0x07, 0x13, 0xB1,
+        0xA9, 0x23, 0x69, 0xE3, 0x3E, 0x21, 0x35, 0xD2, 0x66, 0xDB, 0xB3, 0x72,
+        0x38, 0x6C, 0x40, 0x0B,
+        /* x */
+        0x0D, 0x90, 0x29, 0xAD, 0x2C, 0x7E, 0x5C, 0xF4, 0x34, 0x08, 0x23, 0xB2,
+        0xA8, 0x7D, 0xC6, 0x8C, 0x9E, 0x4C, 0xE3, 0x17, 0x4C, 0x1E, 0x6E, 0xFD,
+        0xEE, 0x12, 0xC0, 0x7D,
+        /* y */
+        0x58, 0xAA, 0x56, 0xF7, 0x72, 0xC0, 0x72, 0x6F, 0x24, 0xC6, 0xB8, 0x9E,
+        0x4E, 0xCD, 0xAC, 0x24, 0x35, 0x4B, 0x9E, 0x99, 0xCA, 0xA3, 0xF6, 0xD3,
+        0x76, 0x14, 0x02, 0xCD,
+        /* order */
+        0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25,
+        0x75, 0xD0, 0xFB, 0x98, 0xD1, 0x16, 0xBC, 0x4B, 0x6D, 0xDE, 0xBC, 0xA3,
+        0xA5, 0xA7, 0x93, 0x9F
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 28 * 6];
+} _EC_brainpoolP224t1 = {
+    {
+        NID_X9_62_prime_field, 0, 28, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25,
+        0x75, 0xD1, 0xD7, 0x87, 0xB0, 0x9F, 0x07, 0x57, 0x97, 0xDA, 0x89, 0xF5,
+        0x7E, 0xC8, 0xC0, 0xFF,
+        /* a */
+        0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25,
+        0x75, 0xD1, 0xD7, 0x87, 0xB0, 0x9F, 0x07, 0x57, 0x97, 0xDA, 0x89, 0xF5,
+        0x7E, 0xC8, 0xC0, 0xFC,
+        /* b */
+        0x4B, 0x33, 0x7D, 0x93, 0x41, 0x04, 0xCD, 0x7B, 0xEF, 0x27, 0x1B, 0xF6,
+        0x0C, 0xED, 0x1E, 0xD2, 0x0D, 0xA1, 0x4C, 0x08, 0xB3, 0xBB, 0x64, 0xF1,
+        0x8A, 0x60, 0x88, 0x8D,
+        /* x */
+        0x6A, 0xB1, 0xE3, 0x44, 0xCE, 0x25, 0xFF, 0x38, 0x96, 0x42, 0x4E, 0x7F,
+        0xFE, 0x14, 0x76, 0x2E, 0xCB, 0x49, 0xF8, 0x92, 0x8A, 0xC0, 0xC7, 0x60,
+        0x29, 0xB4, 0xD5, 0x80,
+        /* y */
+        0x03, 0x74, 0xE9, 0xF5, 0x14, 0x3E, 0x56, 0x8C, 0xD2, 0x3F, 0x3F, 0x4D,
+        0x7C, 0x0D, 0x4B, 0x1E, 0x41, 0xC8, 0xCC, 0x0D, 0x1C, 0x6A, 0xBD, 0x5F,
+        0x1A, 0x46, 0xDB, 0x4C,
+        /* order */
+        0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25,
+        0x75, 0xD0, 0xFB, 0x98, 0xD1, 0x16, 0xBC, 0x4B, 0x6D, 0xDE, 0xBC, 0xA3,
+        0xA5, 0xA7, 0x93, 0x9F
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 32 * 6];
+} _EC_brainpoolP256r1 = {
+    {
+        NID_X9_62_prime_field, 0, 32, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90,
+        0x9D, 0x83, 0x8D, 0x72, 0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28,
+        0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x77,
+        /* a */
+        0x7D, 0x5A, 0x09, 0x75, 0xFC, 0x2C, 0x30, 0x57, 0xEE, 0xF6, 0x75, 0x30,
+        0x41, 0x7A, 0xFF, 0xE7, 0xFB, 0x80, 0x55, 0xC1, 0x26, 0xDC, 0x5C, 0x6C,
+        0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, 0xB5, 0xD9,
+        /* b */
+        0x26, 0xDC, 0x5C, 0x6C, 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, 0xB5, 0xD9,
+        0xBB, 0xD7, 0x7C, 0xBF, 0x95, 0x84, 0x16, 0x29, 0x5C, 0xF7, 0xE1, 0xCE,
+        0x6B, 0xCC, 0xDC, 0x18, 0xFF, 0x8C, 0x07, 0xB6,
+        /* x */
+        0x8B, 0xD2, 0xAE, 0xB9, 0xCB, 0x7E, 0x57, 0xCB, 0x2C, 0x4B, 0x48, 0x2F,
+        0xFC, 0x81, 0xB7, 0xAF, 0xB9, 0xDE, 0x27, 0xE1, 0xE3, 0xBD, 0x23, 0xC2,
+        0x3A, 0x44, 0x53, 0xBD, 0x9A, 0xCE, 0x32, 0x62,
+        /* y */
+        0x54, 0x7E, 0xF8, 0x35, 0xC3, 0xDA, 0xC4, 0xFD, 0x97, 0xF8, 0x46, 0x1A,
+        0x14, 0x61, 0x1D, 0xC9, 0xC2, 0x77, 0x45, 0x13, 0x2D, 0xED, 0x8E, 0x54,
+        0x5C, 0x1D, 0x54, 0xC7, 0x2F, 0x04, 0x69, 0x97,
+        /* order */
+        0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90,
+        0x9D, 0x83, 0x8D, 0x71, 0x8C, 0x39, 0x7A, 0xA3, 0xB5, 0x61, 0xA6, 0xF7,
+        0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48, 0x56, 0xA7
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 32 * 6];
+} _EC_brainpoolP256t1 = {
+    {
+        NID_X9_62_prime_field, 0, 32, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90,
+        0x9D, 0x83, 0x8D, 0x72, 0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28,
+        0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x77,
+        /* a */
+        0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90,
+        0x9D, 0x83, 0x8D, 0x72, 0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28,
+        0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x74,
+        /* b */
+        0x66, 0x2C, 0x61, 0xC4, 0x30, 0xD8, 0x4E, 0xA4, 0xFE, 0x66, 0xA7, 0x73,
+        0x3D, 0x0B, 0x76, 0xB7, 0xBF, 0x93, 0xEB, 0xC4, 0xAF, 0x2F, 0x49, 0x25,
+        0x6A, 0xE5, 0x81, 0x01, 0xFE, 0xE9, 0x2B, 0x04,
+        /* x */
+        0xA3, 0xE8, 0xEB, 0x3C, 0xC1, 0xCF, 0xE7, 0xB7, 0x73, 0x22, 0x13, 0xB2,
+        0x3A, 0x65, 0x61, 0x49, 0xAF, 0xA1, 0x42, 0xC4, 0x7A, 0xAF, 0xBC, 0x2B,
+        0x79, 0xA1, 0x91, 0x56, 0x2E, 0x13, 0x05, 0xF4,
+        /* y */
+        0x2D, 0x99, 0x6C, 0x82, 0x34, 0x39, 0xC5, 0x6D, 0x7F, 0x7B, 0x22, 0xE1,
+        0x46, 0x44, 0x41, 0x7E, 0x69, 0xBC, 0xB6, 0xDE, 0x39, 0xD0, 0x27, 0x00,
+        0x1D, 0xAB, 0xE8, 0xF3, 0x5B, 0x25, 0xC9, 0xBE,
+        /* order */
+        0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90,
+        0x9D, 0x83, 0x8D, 0x71, 0x8C, 0x39, 0x7A, 0xA3, 0xB5, 0x61, 0xA6, 0xF7,
+        0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48, 0x56, 0xA7
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 40 * 6];
+} _EC_brainpoolP320r1 = {
+    {
+        NID_X9_62_prime_field, 0, 40, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E,
+        0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA6, 0xF6, 0xF4, 0x0D, 0xEF,
+        0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93, 0xEC, 0x28, 0xFC, 0xD4, 0x12, 0xB1,
+        0xF1, 0xB3, 0x2E, 0x27,
+        /* a */
+        0x3E, 0xE3, 0x0B, 0x56, 0x8F, 0xBA, 0xB0, 0xF8, 0x83, 0xCC, 0xEB, 0xD4,
+        0x6D, 0x3F, 0x3B, 0xB8, 0xA2, 0xA7, 0x35, 0x13, 0xF5, 0xEB, 0x79, 0xDA,
+        0x66, 0x19, 0x0E, 0xB0, 0x85, 0xFF, 0xA9, 0xF4, 0x92, 0xF3, 0x75, 0xA9,
+        0x7D, 0x86, 0x0E, 0xB4,
+        /* b */
+        0x52, 0x08, 0x83, 0x94, 0x9D, 0xFD, 0xBC, 0x42, 0xD3, 0xAD, 0x19, 0x86,
+        0x40, 0x68, 0x8A, 0x6F, 0xE1, 0x3F, 0x41, 0x34, 0x95, 0x54, 0xB4, 0x9A,
+        0xCC, 0x31, 0xDC, 0xCD, 0x88, 0x45, 0x39, 0x81, 0x6F, 0x5E, 0xB4, 0xAC,
+        0x8F, 0xB1, 0xF1, 0xA6,
+        /* x */
+        0x43, 0xBD, 0x7E, 0x9A, 0xFB, 0x53, 0xD8, 0xB8, 0x52, 0x89, 0xBC, 0xC4,
+        0x8E, 0xE5, 0xBF, 0xE6, 0xF2, 0x01, 0x37, 0xD1, 0x0A, 0x08, 0x7E, 0xB6,
+        0xE7, 0x87, 0x1E, 0x2A, 0x10, 0xA5, 0x99, 0xC7, 0x10, 0xAF, 0x8D, 0x0D,
+        0x39, 0xE2, 0x06, 0x11,
+        /* y */
+        0x14, 0xFD, 0xD0, 0x55, 0x45, 0xEC, 0x1C, 0xC8, 0xAB, 0x40, 0x93, 0x24,
+        0x7F, 0x77, 0x27, 0x5E, 0x07, 0x43, 0xFF, 0xED, 0x11, 0x71, 0x82, 0xEA,
+        0xA9, 0xC7, 0x78, 0x77, 0xAA, 0xAC, 0x6A, 0xC7, 0xD3, 0x52, 0x45, 0xD1,
+        0x69, 0x2E, 0x8E, 0xE1,
+        /* order */
+        0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E,
+        0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA5, 0xB6, 0x8F, 0x12, 0xA3,
+        0x2D, 0x48, 0x2E, 0xC7, 0xEE, 0x86, 0x58, 0xE9, 0x86, 0x91, 0x55, 0x5B,
+        0x44, 0xC5, 0x93, 0x11
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 40 * 6];
+} _EC_brainpoolP320t1 = {
+    {
+        NID_X9_62_prime_field, 0, 40, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E,
+        0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA6, 0xF6, 0xF4, 0x0D, 0xEF,
+        0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93, 0xEC, 0x28, 0xFC, 0xD4, 0x12, 0xB1,
+        0xF1, 0xB3, 0x2E, 0x27,
+        /* a */
+        0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E,
+        0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA6, 0xF6, 0xF4, 0x0D, 0xEF,
+        0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93, 0xEC, 0x28, 0xFC, 0xD4, 0x12, 0xB1,
+        0xF1, 0xB3, 0x2E, 0x24,
+        /* b */
+        0xA7, 0xF5, 0x61, 0xE0, 0x38, 0xEB, 0x1E, 0xD5, 0x60, 0xB3, 0xD1, 0x47,
+        0xDB, 0x78, 0x20, 0x13, 0x06, 0x4C, 0x19, 0xF2, 0x7E, 0xD2, 0x7C, 0x67,
+        0x80, 0xAA, 0xF7, 0x7F, 0xB8, 0xA5, 0x47, 0xCE, 0xB5, 0xB4, 0xFE, 0xF4,
+        0x22, 0x34, 0x03, 0x53,
+        /* x */
+        0x92, 0x5B, 0xE9, 0xFB, 0x01, 0xAF, 0xC6, 0xFB, 0x4D, 0x3E, 0x7D, 0x49,
+        0x90, 0x01, 0x0F, 0x81, 0x34, 0x08, 0xAB, 0x10, 0x6C, 0x4F, 0x09, 0xCB,
+        0x7E, 0xE0, 0x78, 0x68, 0xCC, 0x13, 0x6F, 0xFF, 0x33, 0x57, 0xF6, 0x24,
+        0xA2, 0x1B, 0xED, 0x52,
+        /* y */
+        0x63, 0xBA, 0x3A, 0x7A, 0x27, 0x48, 0x3E, 0xBF, 0x66, 0x71, 0xDB, 0xEF,
+        0x7A, 0xBB, 0x30, 0xEB, 0xEE, 0x08, 0x4E, 0x58, 0xA0, 0xB0, 0x77, 0xAD,
+        0x42, 0xA5, 0xA0, 0x98, 0x9D, 0x1E, 0xE7, 0x1B, 0x1B, 0x9B, 0xC0, 0x45,
+        0x5F, 0xB0, 0xD2, 0xC3,
+        /* order */
+        0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E,
+        0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA5, 0xB6, 0x8F, 0x12, 0xA3,
+        0x2D, 0x48, 0x2E, 0xC7, 0xEE, 0x86, 0x58, 0xE9, 0x86, 0x91, 0x55, 0x5B,
+        0x44, 0xC5, 0x93, 0x11
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 48 * 6];
+} _EC_brainpoolP384r1 = {
+    {
+        NID_X9_62_prime_field, 0, 48, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E,
+        0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB4,
+        0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7, 0x11, 0x23, 0xAC, 0xD3, 0xA7, 0x29,
+        0x90, 0x1D, 0x1A, 0x71, 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x53,
+        /* a */
+        0x7B, 0xC3, 0x82, 0xC6, 0x3D, 0x8C, 0x15, 0x0C, 0x3C, 0x72, 0x08, 0x0A,
+        0xCE, 0x05, 0xAF, 0xA0, 0xC2, 0xBE, 0xA2, 0x8E, 0x4F, 0xB2, 0x27, 0x87,
+        0x13, 0x91, 0x65, 0xEF, 0xBA, 0x91, 0xF9, 0x0F, 0x8A, 0xA5, 0x81, 0x4A,
+        0x50, 0x3A, 0xD4, 0xEB, 0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26,
+        /* b */
+        0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26, 0x8B, 0x39, 0xB5, 0x54,
+        0x16, 0xF0, 0x44, 0x7C, 0x2F, 0xB7, 0x7D, 0xE1, 0x07, 0xDC, 0xD2, 0xA6,
+        0x2E, 0x88, 0x0E, 0xA5, 0x3E, 0xEB, 0x62, 0xD5, 0x7C, 0xB4, 0x39, 0x02,
+        0x95, 0xDB, 0xC9, 0x94, 0x3A, 0xB7, 0x86, 0x96, 0xFA, 0x50, 0x4C, 0x11,
+        /* x */
+        0x1D, 0x1C, 0x64, 0xF0, 0x68, 0xCF, 0x45, 0xFF, 0xA2, 0xA6, 0x3A, 0x81,
+        0xB7, 0xC1, 0x3F, 0x6B, 0x88, 0x47, 0xA3, 0xE7, 0x7E, 0xF1, 0x4F, 0xE3,
+        0xDB, 0x7F, 0xCA, 0xFE, 0x0C, 0xBD, 0x10, 0xE8, 0xE8, 0x26, 0xE0, 0x34,
+        0x36, 0xD6, 0x46, 0xAA, 0xEF, 0x87, 0xB2, 0xE2, 0x47, 0xD4, 0xAF, 0x1E,
+        /* y */
+        0x8A, 0xBE, 0x1D, 0x75, 0x20, 0xF9, 0xC2, 0xA4, 0x5C, 0xB1, 0xEB, 0x8E,
+        0x95, 0xCF, 0xD5, 0x52, 0x62, 0xB7, 0x0B, 0x29, 0xFE, 0xEC, 0x58, 0x64,
+        0xE1, 0x9C, 0x05, 0x4F, 0xF9, 0x91, 0x29, 0x28, 0x0E, 0x46, 0x46, 0x21,
+        0x77, 0x91, 0x81, 0x11, 0x42, 0x82, 0x03, 0x41, 0x26, 0x3C, 0x53, 0x15,
+        /* order */
+        0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E,
+        0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB3,
+        0x1F, 0x16, 0x6E, 0x6C, 0xAC, 0x04, 0x25, 0xA7, 0xCF, 0x3A, 0xB6, 0xAF,
+        0x6B, 0x7F, 0xC3, 0x10, 0x3B, 0x88, 0x32, 0x02, 0xE9, 0x04, 0x65, 0x65
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 48 * 6];
+} _EC_brainpoolP384t1 = {
+    {
+        NID_X9_62_prime_field, 0, 48, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E,
+        0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB4,
+        0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7, 0x11, 0x23, 0xAC, 0xD3, 0xA7, 0x29,
+        0x90, 0x1D, 0x1A, 0x71, 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x53,
+        /* a */
+        0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E,
+        0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB4,
+        0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7, 0x11, 0x23, 0xAC, 0xD3, 0xA7, 0x29,
+        0x90, 0x1D, 0x1A, 0x71, 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x50,
+        /* b */
+        0x7F, 0x51, 0x9E, 0xAD, 0xA7, 0xBD, 0xA8, 0x1B, 0xD8, 0x26, 0xDB, 0xA6,
+        0x47, 0x91, 0x0F, 0x8C, 0x4B, 0x93, 0x46, 0xED, 0x8C, 0xCD, 0xC6, 0x4E,
+        0x4B, 0x1A, 0xBD, 0x11, 0x75, 0x6D, 0xCE, 0x1D, 0x20, 0x74, 0xAA, 0x26,
+        0x3B, 0x88, 0x80, 0x5C, 0xED, 0x70, 0x35, 0x5A, 0x33, 0xB4, 0x71, 0xEE,
+        /* x */
+        0x18, 0xDE, 0x98, 0xB0, 0x2D, 0xB9, 0xA3, 0x06, 0xF2, 0xAF, 0xCD, 0x72,
+        0x35, 0xF7, 0x2A, 0x81, 0x9B, 0x80, 0xAB, 0x12, 0xEB, 0xD6, 0x53, 0x17,
+        0x24, 0x76, 0xFE, 0xCD, 0x46, 0x2A, 0xAB, 0xFF, 0xC4, 0xFF, 0x19, 0x1B,
+        0x94, 0x6A, 0x5F, 0x54, 0xD8, 0xD0, 0xAA, 0x2F, 0x41, 0x88, 0x08, 0xCC,
+        /* y */
+        0x25, 0xAB, 0x05, 0x69, 0x62, 0xD3, 0x06, 0x51, 0xA1, 0x14, 0xAF, 0xD2,
+        0x75, 0x5A, 0xD3, 0x36, 0x74, 0x7F, 0x93, 0x47, 0x5B, 0x7A, 0x1F, 0xCA,
+        0x3B, 0x88, 0xF2, 0xB6, 0xA2, 0x08, 0xCC, 0xFE, 0x46, 0x94, 0x08, 0x58,
+        0x4D, 0xC2, 0xB2, 0x91, 0x26, 0x75, 0xBF, 0x5B, 0x9E, 0x58, 0x29, 0x28,
+        /* order */
+        0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E,
+        0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB3,
+        0x1F, 0x16, 0x6E, 0x6C, 0xAC, 0x04, 0x25, 0xA7, 0xCF, 0x3A, 0xB6, 0xAF,
+        0x6B, 0x7F, 0xC3, 0x10, 0x3B, 0x88, 0x32, 0x02, 0xE9, 0x04, 0x65, 0x65
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 64 * 6];
+} _EC_brainpoolP512r1 = {
+    {
+        NID_X9_62_prime_field, 0, 64, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE,
+        0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E,
+        0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x71, 0x7D, 0x4D, 0x9B, 0x00,
+        0x9B, 0xC6, 0x68, 0x42, 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6,
+        0x28, 0x81, 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56,
+        0x58, 0x3A, 0x48, 0xF3,
+        /* a */
+        0x78, 0x30, 0xA3, 0x31, 0x8B, 0x60, 0x3B, 0x89, 0xE2, 0x32, 0x71, 0x45,
+        0xAC, 0x23, 0x4C, 0xC5, 0x94, 0xCB, 0xDD, 0x8D, 0x3D, 0xF9, 0x16, 0x10,
+        0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98, 0x63, 0xBC, 0x2D, 0xED, 0x5D, 0x5A,
+        0xA8, 0x25, 0x3A, 0xA1, 0x0A, 0x2E, 0xF1, 0xC9, 0x8B, 0x9A, 0xC8, 0xB5,
+        0x7F, 0x11, 0x17, 0xA7, 0x2B, 0xF2, 0xC7, 0xB9, 0xE7, 0xC1, 0xAC, 0x4D,
+        0x77, 0xFC, 0x94, 0xCA,
+        /* b */
+        0x3D, 0xF9, 0x16, 0x10, 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98, 0x63, 0xBC,
+        0x2D, 0xED, 0x5D, 0x5A, 0xA8, 0x25, 0x3A, 0xA1, 0x0A, 0x2E, 0xF1, 0xC9,
+        0x8B, 0x9A, 0xC8, 0xB5, 0x7F, 0x11, 0x17, 0xA7, 0x2B, 0xF2, 0xC7, 0xB9,
+        0xE7, 0xC1, 0xAC, 0x4D, 0x77, 0xFC, 0x94, 0xCA, 0xDC, 0x08, 0x3E, 0x67,
+        0x98, 0x40, 0x50, 0xB7, 0x5E, 0xBA, 0xE5, 0xDD, 0x28, 0x09, 0xBD, 0x63,
+        0x80, 0x16, 0xF7, 0x23,
+        /* x */
+        0x81, 0xAE, 0xE4, 0xBD, 0xD8, 0x2E, 0xD9, 0x64, 0x5A, 0x21, 0x32, 0x2E,
+        0x9C, 0x4C, 0x6A, 0x93, 0x85, 0xED, 0x9F, 0x70, 0xB5, 0xD9, 0x16, 0xC1,
+        0xB4, 0x3B, 0x62, 0xEE, 0xF4, 0xD0, 0x09, 0x8E, 0xFF, 0x3B, 0x1F, 0x78,
+        0xE2, 0xD0, 0xD4, 0x8D, 0x50, 0xD1, 0x68, 0x7B, 0x93, 0xB9, 0x7D, 0x5F,
+        0x7C, 0x6D, 0x50, 0x47, 0x40, 0x6A, 0x5E, 0x68, 0x8B, 0x35, 0x22, 0x09,
+        0xBC, 0xB9, 0xF8, 0x22,
+        /* y */
+        0x7D, 0xDE, 0x38, 0x5D, 0x56, 0x63, 0x32, 0xEC, 0xC0, 0xEA, 0xBF, 0xA9,
+        0xCF, 0x78, 0x22, 0xFD, 0xF2, 0x09, 0xF7, 0x00, 0x24, 0xA5, 0x7B, 0x1A,
+        0xA0, 0x00, 0xC5, 0x5B, 0x88, 0x1F, 0x81, 0x11, 0xB2, 0xDC, 0xDE, 0x49,
+        0x4A, 0x5F, 0x48, 0x5E, 0x5B, 0xCA, 0x4B, 0xD8, 0x8A, 0x27, 0x63, 0xAE,
+        0xD1, 0xCA, 0x2B, 0x2F, 0xA8, 0xF0, 0x54, 0x06, 0x78, 0xCD, 0x1E, 0x0F,
+        0x3A, 0xD8, 0x08, 0x92,
+        /* order */
+        0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE,
+        0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E,
+        0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x70, 0x55, 0x3E, 0x5C, 0x41,
+        0x4C, 0xA9, 0x26, 0x19, 0x41, 0x86, 0x61, 0x19, 0x7F, 0xAC, 0x10, 0x47,
+        0x1D, 0xB1, 0xD3, 0x81, 0x08, 0x5D, 0xDA, 0xDD, 0xB5, 0x87, 0x96, 0x82,
+        0x9C, 0xA9, 0x00, 0x69
+    }
+};
+
+static const struct {
+    EC_CURVE_DATA h;
+    unsigned char data[0 + 64 * 6];
+} _EC_brainpoolP512t1 = {
+    {
+        NID_X9_62_prime_field, 0, 64, 1
+    },
+    {
+        /* no seed */
+        /* p */
+        0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE,
+        0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E,
+        0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x71, 0x7D, 0x4D, 0x9B, 0x00,
+        0x9B, 0xC6, 0x68, 0x42, 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6,
+        0x28, 0x81, 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56,
+        0x58, 0x3A, 0x48, 0xF3,
+        /* a */
+        0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE,
+        0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E,
+        0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x71, 0x7D, 0x4D, 0x9B, 0x00,
+        0x9B, 0xC6, 0x68, 0x42, 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6,
+        0x28, 0x81, 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56,
+        0x58, 0x3A, 0x48, 0xF0,
+        /* b */
+        0x7C, 0xBB, 0xBC, 0xF9, 0x44, 0x1C, 0xFA, 0xB7, 0x6E, 0x18, 0x90, 0xE4,
+        0x68, 0x84, 0xEA, 0xE3, 0x21, 0xF7, 0x0C, 0x0B, 0xCB, 0x49, 0x81, 0x52,
+        0x78, 0x97, 0x50, 0x4B, 0xEC, 0x3E, 0x36, 0xA6, 0x2B, 0xCD, 0xFA, 0x23,
+        0x04, 0x97, 0x65, 0x40, 0xF6, 0x45, 0x00, 0x85, 0xF2, 0xDA, 0xE1, 0x45,
+        0xC2, 0x25, 0x53, 0xB4, 0x65, 0x76, 0x36, 0x89, 0x18, 0x0E, 0xA2, 0x57,
+        0x18, 0x67, 0x42, 0x3E,
+        /* x */
+        0x64, 0x0E, 0xCE, 0x5C, 0x12, 0x78, 0x87, 0x17, 0xB9, 0xC1, 0xBA, 0x06,
+        0xCB, 0xC2, 0xA6, 0xFE, 0xBA, 0x85, 0x84, 0x24, 0x58, 0xC5, 0x6D, 0xDE,
+        0x9D, 0xB1, 0x75, 0x8D, 0x39, 0xC0, 0x31, 0x3D, 0x82, 0xBA, 0x51, 0x73,
+        0x5C, 0xDB, 0x3E, 0xA4, 0x99, 0xAA, 0x77, 0xA7, 0xD6, 0x94, 0x3A, 0x64,
+        0xF7, 0xA3, 0xF2, 0x5F, 0xE2, 0x6F, 0x06, 0xB5, 0x1B, 0xAA, 0x26, 0x96,
+        0xFA, 0x90, 0x35, 0xDA,
+        /* y */
+        0x5B, 0x53, 0x4B, 0xD5, 0x95, 0xF5, 0xAF, 0x0F, 0xA2, 0xC8, 0x92, 0x37,
+        0x6C, 0x84, 0xAC, 0xE1, 0xBB, 0x4E, 0x30, 0x19, 0xB7, 0x16, 0x34, 0xC0,
+        0x11, 0x31, 0x15, 0x9C, 0xAE, 0x03, 0xCE, 0xE9, 0xD9, 0x93, 0x21, 0x84,
+        0xBE, 0xEF, 0x21, 0x6B, 0xD7, 0x1D, 0xF2, 0xDA, 0xDF, 0x86, 0xA6, 0x27,
+        0x30, 0x6E, 0xCF, 0xF9, 0x6D, 0xBB, 0x8B, 0xAC, 0xE1, 0x98, 0xB6, 0x1E,
+        0x00, 0xF8, 0xB3, 0x32,
+        /* order */
+        0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE,
+        0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E,
+        0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x70, 0x55, 0x3E, 0x5C, 0x41,
+        0x4C, 0xA9, 0x26, 0x19, 0x41, 0x86, 0x61, 0x19, 0x7F, 0xAC, 0x10, 0x47,
+        0x1D, 0xB1, 0xD3, 0x81, 0x08, 0x5D, 0xDA, 0xDD, 0xB5, 0x87, 0x96, 0x82,
+        0x9C, 0xA9, 0x00, 0x69
+    }
+};
+
+typedef struct _ec_list_element_st {
+    int nid;
+    const EC_CURVE_DATA *data;
+    const EC_METHOD *(*meth) (void);
+    const char *comment;
+} ec_list_element;
+
+static const ec_list_element curve_list[] = {
+    /* prime field curves */
+    /* secg curves */
+    {NID_secp112r1, &_EC_SECG_PRIME_112R1.h, 0,
+     "SECG/WTLS curve over a 112 bit prime field"},
+    {NID_secp112r2, &_EC_SECG_PRIME_112R2.h, 0,
+     "SECG curve over a 112 bit prime field"},
+    {NID_secp128r1, &_EC_SECG_PRIME_128R1.h, 0,
+     "SECG curve over a 128 bit prime field"},
+    {NID_secp128r2, &_EC_SECG_PRIME_128R2.h, 0,
+     "SECG curve over a 128 bit prime field"},
+    {NID_secp160k1, &_EC_SECG_PRIME_160K1.h, 0,
+     "SECG curve over a 160 bit prime field"},
+    {NID_secp160r1, &_EC_SECG_PRIME_160R1.h, 0,
+     "SECG curve over a 160 bit prime field"},
+    {NID_secp160r2, &_EC_SECG_PRIME_160R2.h, 0,
+     "SECG/WTLS curve over a 160 bit prime field"},
+    /* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */
+    {NID_secp192k1, &_EC_SECG_PRIME_192K1.h, 0,
+     "SECG curve over a 192 bit prime field"},
+    {NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0,
+     "SECG curve over a 224 bit prime field"},
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+    {NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method,
+     "NIST/SECG curve over a 224 bit prime field"},
+#else
+    {NID_secp224r1, &_EC_NIST_PRIME_224.h, 0,
+     "NIST/SECG curve over a 224 bit prime field"},
+#endif
+    {NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0,
+     "SECG curve over a 256 bit prime field"},
+    /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
+    {NID_secp384r1, &_EC_NIST_PRIME_384.h, 0,
+     "NIST/SECG curve over a 384 bit prime field"},
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+    {NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method,
+     "NIST/SECG curve over a 521 bit prime field"},
+#else
+    {NID_secp521r1, &_EC_NIST_PRIME_521.h, 0,
+     "NIST/SECG curve over a 521 bit prime field"},
+#endif
+    /* X9.62 curves */
+    {NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0,
+     "NIST/X9.62/SECG curve over a 192 bit prime field"},
+    {NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, 0,
+     "X9.62 curve over a 192 bit prime field"},
+    {NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, 0,
+     "X9.62 curve over a 192 bit prime field"},
+    {NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, 0,
+     "X9.62 curve over a 239 bit prime field"},
+    {NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, 0,
+     "X9.62 curve over a 239 bit prime field"},
+    {NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0,
+     "X9.62 curve over a 239 bit prime field"},
+    {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h,
+#if defined(ECP_NISTZ256_ASM)
+     EC_GFp_nistz256_method,
+#elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
+     EC_GFp_nistp256_method,
+#else
+     0,
+#endif
+     "X9.62/SECG curve over a 256 bit prime field"},
+#ifndef OPENSSL_NO_EC2M
+    /* characteristic two field curves */
+    /* NIST/SECG curves */
+    {NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, 0,
+     "SECG curve over a 113 bit binary field"},
+    {NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, 0,
+     "SECG curve over a 113 bit binary field"},
+    {NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, 0,
+     "SECG/WTLS curve over a 131 bit binary field"},
+    {NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, 0,
+     "SECG curve over a 131 bit binary field"},
+    {NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0,
+     "NIST/SECG/WTLS curve over a 163 bit binary field"},
+    {NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, 0,
+     "SECG curve over a 163 bit binary field"},
+    {NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0,
+     "NIST/SECG curve over a 163 bit binary field"},
+    {NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, 0,
+     "SECG curve over a 193 bit binary field"},
+    {NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, 0,
+     "SECG curve over a 193 bit binary field"},
+    {NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0,
+     "NIST/SECG/WTLS curve over a 233 bit binary field"},
+    {NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0,
+     "NIST/SECG/WTLS curve over a 233 bit binary field"},
+    {NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, 0,
+     "SECG curve over a 239 bit binary field"},
+    {NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0,
+     "NIST/SECG curve over a 283 bit binary field"},
+    {NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0,
+     "NIST/SECG curve over a 283 bit binary field"},
+    {NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0,
+     "NIST/SECG curve over a 409 bit binary field"},
+    {NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0,
+     "NIST/SECG curve over a 409 bit binary field"},
+    {NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0,
+     "NIST/SECG curve over a 571 bit binary field"},
+    {NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0,
+     "NIST/SECG curve over a 571 bit binary field"},
+    /* X9.62 curves */
+    {NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, 0,
+     "X9.62 curve over a 163 bit binary field"},
+    {NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, 0,
+     "X9.62 curve over a 163 bit binary field"},
+    {NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, 0,
+     "X9.62 curve over a 163 bit binary field"},
+    {NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, 0,
+     "X9.62 curve over a 176 bit binary field"},
+    {NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, 0,
+     "X9.62 curve over a 191 bit binary field"},
+    {NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, 0,
+     "X9.62 curve over a 191 bit binary field"},
+    {NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, 0,
+     "X9.62 curve over a 191 bit binary field"},
+    {NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, 0,
+     "X9.62 curve over a 208 bit binary field"},
+    {NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, 0,
+     "X9.62 curve over a 239 bit binary field"},
+    {NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, 0,
+     "X9.62 curve over a 239 bit binary field"},
+    {NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, 0,
+     "X9.62 curve over a 239 bit binary field"},
+    {NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, 0,
+     "X9.62 curve over a 272 bit binary field"},
+    {NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, 0,
+     "X9.62 curve over a 304 bit binary field"},
+    {NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, 0,
+     "X9.62 curve over a 359 bit binary field"},
+    {NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, 0,
+     "X9.62 curve over a 368 bit binary field"},
+    {NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, 0,
+     "X9.62 curve over a 431 bit binary field"},
+    /*
+     * the WAP/WTLS curves [unlike SECG, spec has its own OIDs for curves
+     * from X9.62]
+     */
+    {NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, 0,
+     "WTLS curve over a 113 bit binary field"},
+    {NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, 0,
+     "NIST/SECG/WTLS curve over a 163 bit binary field"},
+    {NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, 0,
+     "SECG curve over a 113 bit binary field"},
+    {NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, 0,
+     "X9.62 curve over a 163 bit binary field"},
+#endif
+    {NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, 0,
+     "SECG/WTLS curve over a 112 bit prime field"},
+    {NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, 0,
+     "SECG/WTLS curve over a 160 bit prime field"},
+    {NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, 0,
+     "WTLS curve over a 112 bit prime field"},
+    {NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, 0,
+     "WTLS curve over a 160 bit prime field"},
+#ifndef OPENSSL_NO_EC2M
+    {NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, 0,
+     "NIST/SECG/WTLS curve over a 233 bit binary field"},
+    {NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, 0,
+     "NIST/SECG/WTLS curve over a 233 bit binary field"},
+#endif
+    {NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0,
+     "WTLS curve over a 224 bit prime field"},
+#ifndef OPENSSL_NO_EC2M
+    /* IPSec curves */
+    {NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0,
+     "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n"
+     "\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
+    {NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0,
+     "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n"
+     "\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
+#endif
+    /* brainpool curves */
+    {NID_brainpoolP160r1, &_EC_brainpoolP160r1.h, 0,
+     "RFC 5639 curve over a 160 bit prime field"},
+    {NID_brainpoolP160t1, &_EC_brainpoolP160t1.h, 0,
+     "RFC 5639 curve over a 160 bit prime field"},
+    {NID_brainpoolP192r1, &_EC_brainpoolP192r1.h, 0,
+     "RFC 5639 curve over a 192 bit prime field"},
+    {NID_brainpoolP192t1, &_EC_brainpoolP192t1.h, 0,
+     "RFC 5639 curve over a 192 bit prime field"},
+    {NID_brainpoolP224r1, &_EC_brainpoolP224r1.h, 0,
+     "RFC 5639 curve over a 224 bit prime field"},
+    {NID_brainpoolP224t1, &_EC_brainpoolP224t1.h, 0,
+     "RFC 5639 curve over a 224 bit prime field"},
+    {NID_brainpoolP256r1, &_EC_brainpoolP256r1.h, 0,
+     "RFC 5639 curve over a 256 bit prime field"},
+    {NID_brainpoolP256t1, &_EC_brainpoolP256t1.h, 0,
+     "RFC 5639 curve over a 256 bit prime field"},
+    {NID_brainpoolP320r1, &_EC_brainpoolP320r1.h, 0,
+     "RFC 5639 curve over a 320 bit prime field"},
+    {NID_brainpoolP320t1, &_EC_brainpoolP320t1.h, 0,
+     "RFC 5639 curve over a 320 bit prime field"},
+    {NID_brainpoolP384r1, &_EC_brainpoolP384r1.h, 0,
+     "RFC 5639 curve over a 384 bit prime field"},
+    {NID_brainpoolP384t1, &_EC_brainpoolP384t1.h, 0,
+     "RFC 5639 curve over a 384 bit prime field"},
+    {NID_brainpoolP512r1, &_EC_brainpoolP512r1.h, 0,
+     "RFC 5639 curve over a 512 bit prime field"},
+    {NID_brainpoolP512t1, &_EC_brainpoolP512t1.h, 0,
+     "RFC 5639 curve over a 512 bit prime field"},
+};
+
+#define curve_list_length OSSL_NELEM(curve_list)
+
+static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)
+{
+    EC_GROUP *group = NULL;
+    EC_POINT *P = NULL;
+    BN_CTX *ctx = NULL;
+    BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order =
+        NULL;
+    int ok = 0;
+    int seed_len, param_len;
+    const EC_METHOD *meth;
+    const EC_CURVE_DATA *data;
+    const unsigned char *params;
+
+    /* If no curve data curve method must handle everything */
+    if (curve.data == NULL)
+        return EC_GROUP_new(curve.meth != NULL ? curve.meth() : NULL);
+
+    if ((ctx = BN_CTX_new()) == NULL) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    data = curve.data;
+    seed_len = data->seed_len;
+    param_len = data->param_len;
+    params = (const unsigned char *)(data + 1); /* skip header */
+    params += seed_len;         /* skip seed */
+
+    if ((p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) == NULL
+        || (a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) == NULL
+        || (b = BN_bin2bn(params + 2 * param_len, param_len, NULL)) == NULL) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
+        goto err;
+    }
+
+    if (curve.meth != 0) {
+        meth = curve.meth();
+        if (((group = EC_GROUP_new(meth)) == NULL) ||
+            (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
+            ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+            goto err;
+        }
+    } else if (data->field_type == NID_X9_62_prime_field) {
+        if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
+            ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+            goto err;
+        }
+    }
+#ifndef OPENSSL_NO_EC2M
+    else {                      /* field_type ==
+                                 * NID_X9_62_characteristic_two_field */
+
+        if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) {
+            ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+            goto err;
+        }
+    }
+#endif
+
+    if ((P = EC_POINT_new(group)) == NULL) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+        goto err;
+    }
+
+    if ((x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) == NULL
+        || (y = BN_bin2bn(params + 4 * param_len, param_len, NULL)) == NULL) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
+        goto err;
+    }
+    if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+        goto err;
+    }
+    if ((order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) == NULL
+        || !BN_set_word(x, (BN_ULONG)data->cofactor)) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);
+        goto err;
+    }
+    if (!EC_GROUP_set_generator(group, P, order, x)) {
+        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+        goto err;
+    }
+    if (seed_len) {
+        if (!EC_GROUP_set_seed(group, params - seed_len, seed_len)) {
+            ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);
+            goto err;
+        }
+    }
+    ok = 1;
+ err:
+    if (!ok) {
+        EC_GROUP_free(group);
+        group = NULL;
+    }
+    EC_POINT_free(P);
+    BN_CTX_free(ctx);
+    BN_free(p);
+    BN_free(a);
+    BN_free(b);
+    BN_free(order);
+    BN_free(x);
+    BN_free(y);
+    return group;
+}
+
+EC_GROUP *EC_GROUP_new_by_curve_name(int nid)
+{
+    size_t i;
+    EC_GROUP *ret = NULL;
+
+    if (nid <= 0)
+        return NULL;
+
+    for (i = 0; i < curve_list_length; i++)
+        if (curve_list[i].nid == nid) {
+            ret = ec_group_new_from_data(curve_list[i]);
+            break;
+        }
+
+    if (ret == NULL) {
+        ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP);
+        return NULL;
+    }
+
+    EC_GROUP_set_curve_name(ret, nid);
+
+    return ret;
+}
+
+size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems)
+{
+    size_t i, min;
+
+    if (r == NULL || nitems == 0)
+        return curve_list_length;
+
+    min = nitems < curve_list_length ? nitems : curve_list_length;
+
+    for (i = 0; i < min; i++) {
+        r[i].nid = curve_list[i].nid;
+        r[i].comment = curve_list[i].comment;
+    }
+
+    return curve_list_length;
+}
+
+/* Functions to translate between common NIST curve names and NIDs */
+
+typedef struct {
+    const char *name;           /* NIST Name of curve */
+    int nid;                    /* Curve NID */
+} EC_NIST_NAME;
+
+static EC_NIST_NAME nist_curves[] = {
+    {"B-163", NID_sect163r2},
+    {"B-233", NID_sect233r1},
+    {"B-283", NID_sect283r1},
+    {"B-409", NID_sect409r1},
+    {"B-571", NID_sect571r1},
+    {"K-163", NID_sect163k1},
+    {"K-233", NID_sect233k1},
+    {"K-283", NID_sect283k1},
+    {"K-409", NID_sect409k1},
+    {"K-571", NID_sect571k1},
+    {"P-192", NID_X9_62_prime192v1},
+    {"P-224", NID_secp224r1},
+    {"P-256", NID_X9_62_prime256v1},
+    {"P-384", NID_secp384r1},
+    {"P-521", NID_secp521r1}
+};
+
+const char *EC_curve_nid2nist(int nid)
+{
+    size_t i;
+    for (i = 0; i < OSSL_NELEM(nist_curves); i++) {
+        if (nist_curves[i].nid == nid)
+            return nist_curves[i].name;
+    }
+    return NULL;
+}
+
+int EC_curve_nist2nid(const char *name)
+{
+    size_t i;
+    for (i = 0; i < OSSL_NELEM(nist_curves); i++) {
+        if (strcmp(nist_curves[i].name, name) == 0)
+            return nist_curves[i].nid;
+    }
+    return NID_undef;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_cvt.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_cvt.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_cvt.c	(revision 331)
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2001-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#include <openssl/err.h>
+#include "ec_lcl.h"
+
+EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
+                                 const BIGNUM *b, BN_CTX *ctx)
+{
+    const EC_METHOD *meth;
+    EC_GROUP *ret;
+
+#if defined(OPENSSL_BN_ASM_MONT)
+    /*
+     * This might appear controversial, but the fact is that generic
+     * prime method was observed to deliver better performance even
+     * for NIST primes on a range of platforms, e.g.: 60%-15%
+     * improvement on IA-64, ~25% on ARM, 30%-90% on P4, 20%-25%
+     * in 32-bit build and 35%--12% in 64-bit build on Core2...
+     * Coefficients are relative to optimized bn_nist.c for most
+     * intensive ECDSA verify and ECDH operations for 192- and 521-
+     * bit keys respectively. Choice of these boundary values is
+     * arguable, because the dependency of improvement coefficient
+     * from key length is not a "monotone" curve. For example while
+     * 571-bit result is 23% on ARM, 384-bit one is -1%. But it's
+     * generally faster, sometimes "respectfully" faster, sometimes
+     * "tolerably" slower... What effectively happens is that loop
+     * with bn_mul_add_words is put against bn_mul_mont, and the
+     * latter "wins" on short vectors. Correct solution should be
+     * implementing dedicated NxN multiplication subroutines for
+     * small N. But till it materializes, let's stick to generic
+     * prime method...
+     *                                              <appro>
+     */
+    meth = EC_GFp_mont_method();
+#else
+    if (BN_nist_mod_func(p))
+        meth = EC_GFp_nist_method();
+    else
+        meth = EC_GFp_mont_method();
+#endif
+
+    ret = EC_GROUP_new(meth);
+    if (ret == NULL)
+        return NULL;
+
+    if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) {
+        EC_GROUP_clear_free(ret);
+        return NULL;
+    }
+
+    return ret;
+}
+
+#ifndef OPENSSL_NO_EC2M
+EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a,
+                                  const BIGNUM *b, BN_CTX *ctx)
+{
+    const EC_METHOD *meth;
+    EC_GROUP *ret;
+
+    meth = EC_GF2m_simple_method();
+
+    ret = EC_GROUP_new(meth);
+    if (ret == NULL)
+        return NULL;
+
+    if (!EC_GROUP_set_curve_GF2m(ret, p, a, b, ctx)) {
+        EC_GROUP_clear_free(ret);
+        return NULL;
+    }
+
+    return ret;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_err.c	(revision 331)
@@ -0,0 +1,290 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/ec.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_EC,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_EC,0,reason)
+
+static ERR_STRING_DATA EC_str_functs[] = {
+    {ERR_FUNC(EC_F_BN_TO_FELEM), "BN_to_felem"},
+    {ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"},
+    {ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"},
+    {ERR_FUNC(EC_F_D2I_ECPRIVATEKEY), "d2i_ECPrivateKey"},
+    {ERR_FUNC(EC_F_DO_EC_KEY_PRINT), "do_EC_KEY_print"},
+    {ERR_FUNC(EC_F_ECDH_CMS_DECRYPT), "ecdh_cms_decrypt"},
+    {ERR_FUNC(EC_F_ECDH_CMS_SET_SHARED_INFO), "ecdh_cms_set_shared_info"},
+    {ERR_FUNC(EC_F_ECDH_COMPUTE_KEY), "ECDH_compute_key"},
+    {ERR_FUNC(EC_F_ECDH_SIMPLE_COMPUTE_KEY), "ecdh_simple_compute_key"},
+    {ERR_FUNC(EC_F_ECDSA_DO_SIGN_EX), "ECDSA_do_sign_ex"},
+    {ERR_FUNC(EC_F_ECDSA_DO_VERIFY), "ECDSA_do_verify"},
+    {ERR_FUNC(EC_F_ECDSA_SIGN_EX), "ECDSA_sign_ex"},
+    {ERR_FUNC(EC_F_ECDSA_SIGN_SETUP), "ECDSA_sign_setup"},
+    {ERR_FUNC(EC_F_ECDSA_SIG_NEW), "ECDSA_SIG_new"},
+    {ERR_FUNC(EC_F_ECDSA_VERIFY), "ECDSA_verify"},
+    {ERR_FUNC(EC_F_ECKEY_PARAM2TYPE), "eckey_param2type"},
+    {ERR_FUNC(EC_F_ECKEY_PARAM_DECODE), "eckey_param_decode"},
+    {ERR_FUNC(EC_F_ECKEY_PRIV_DECODE), "eckey_priv_decode"},
+    {ERR_FUNC(EC_F_ECKEY_PRIV_ENCODE), "eckey_priv_encode"},
+    {ERR_FUNC(EC_F_ECKEY_PUB_DECODE), "eckey_pub_decode"},
+    {ERR_FUNC(EC_F_ECKEY_PUB_ENCODE), "eckey_pub_encode"},
+    {ERR_FUNC(EC_F_ECKEY_TYPE2PARAM), "eckey_type2param"},
+    {ERR_FUNC(EC_F_ECPARAMETERS_PRINT), "ECParameters_print"},
+    {ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP), "ECParameters_print_fp"},
+    {ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT), "ECPKParameters_print"},
+    {ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT_FP), "ECPKParameters_print_fp"},
+    {ERR_FUNC(EC_F_ECP_NISTZ256_GET_AFFINE), "ecp_nistz256_get_affine"},
+    {ERR_FUNC(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE),
+     "ecp_nistz256_mult_precompute"},
+    {ERR_FUNC(EC_F_ECP_NISTZ256_POINTS_MUL), "ecp_nistz256_points_mul"},
+    {ERR_FUNC(EC_F_ECP_NISTZ256_PRE_COMP_NEW), "ecp_nistz256_pre_comp_new"},
+    {ERR_FUNC(EC_F_ECP_NISTZ256_WINDOWED_MUL), "ecp_nistz256_windowed_mul"},
+    {ERR_FUNC(EC_F_ECX_KEY_OP), "ecx_key_op"},
+    {ERR_FUNC(EC_F_ECX_PRIV_ENCODE), "ecx_priv_encode"},
+    {ERR_FUNC(EC_F_ECX_PUB_ENCODE), "ecx_pub_encode"},
+    {ERR_FUNC(EC_F_EC_ASN1_GROUP2CURVE), "ec_asn1_group2curve"},
+    {ERR_FUNC(EC_F_EC_ASN1_GROUP2FIELDID), "ec_asn1_group2fieldid"},
+    {ERR_FUNC(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY),
+     "ec_GF2m_montgomery_point_multiply"},
+    {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT),
+     "ec_GF2m_simple_group_check_discriminant"},
+    {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE),
+     "ec_GF2m_simple_group_set_curve"},
+    {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_OCT2POINT), "ec_GF2m_simple_oct2point"},
+    {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT2OCT), "ec_GF2m_simple_point2oct"},
+    {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES),
+     "ec_GF2m_simple_point_get_affine_coordinates"},
+    {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES),
+     "ec_GF2m_simple_point_set_affine_coordinates"},
+    {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES),
+     "ec_GF2m_simple_set_compressed_coordinates"},
+    {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_DECODE), "ec_GFp_mont_field_decode"},
+    {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_ENCODE), "ec_GFp_mont_field_encode"},
+    {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_MUL), "ec_GFp_mont_field_mul"},
+    {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE),
+     "ec_GFp_mont_field_set_to_one"},
+    {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SQR), "ec_GFp_mont_field_sqr"},
+    {ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE),
+     "ec_GFp_mont_group_set_curve"},
+    {ERR_FUNC(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE),
+     "ec_GFp_nistp224_group_set_curve"},
+    {ERR_FUNC(EC_F_EC_GFP_NISTP224_POINTS_MUL), "ec_GFp_nistp224_points_mul"},
+    {ERR_FUNC(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES),
+     "ec_GFp_nistp224_point_get_affine_coordinates"},
+    {ERR_FUNC(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE),
+     "ec_GFp_nistp256_group_set_curve"},
+    {ERR_FUNC(EC_F_EC_GFP_NISTP256_POINTS_MUL), "ec_GFp_nistp256_points_mul"},
+    {ERR_FUNC(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES),
+     "ec_GFp_nistp256_point_get_affine_coordinates"},
+    {ERR_FUNC(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE),
+     "ec_GFp_nistp521_group_set_curve"},
+    {ERR_FUNC(EC_F_EC_GFP_NISTP521_POINTS_MUL), "ec_GFp_nistp521_points_mul"},
+    {ERR_FUNC(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES),
+     "ec_GFp_nistp521_point_get_affine_coordinates"},
+    {ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_MUL), "ec_GFp_nist_field_mul"},
+    {ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_SQR), "ec_GFp_nist_field_sqr"},
+    {ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE),
+     "ec_GFp_nist_group_set_curve"},
+    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT),
+     "ec_GFp_simple_group_check_discriminant"},
+    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE),
+     "ec_GFp_simple_group_set_curve"},
+    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE), "ec_GFp_simple_make_affine"},
+    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_OCT2POINT), "ec_GFp_simple_oct2point"},
+    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT2OCT), "ec_GFp_simple_point2oct"},
+    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE),
+     "ec_GFp_simple_points_make_affine"},
+    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES),
+     "ec_GFp_simple_point_get_affine_coordinates"},
+    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES),
+     "ec_GFp_simple_point_set_affine_coordinates"},
+    {ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES),
+     "ec_GFp_simple_set_compressed_coordinates"},
+    {ERR_FUNC(EC_F_EC_GROUP_CHECK), "EC_GROUP_check"},
+    {ERR_FUNC(EC_F_EC_GROUP_CHECK_DISCRIMINANT),
+     "EC_GROUP_check_discriminant"},
+    {ERR_FUNC(EC_F_EC_GROUP_COPY), "EC_GROUP_copy"},
+    {ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GF2M), "EC_GROUP_get_curve_GF2m"},
+    {ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GFP), "EC_GROUP_get_curve_GFp"},
+    {ERR_FUNC(EC_F_EC_GROUP_GET_DEGREE), "EC_GROUP_get_degree"},
+    {ERR_FUNC(EC_F_EC_GROUP_GET_ECPARAMETERS), "EC_GROUP_get_ecparameters"},
+    {ERR_FUNC(EC_F_EC_GROUP_GET_ECPKPARAMETERS),
+     "EC_GROUP_get_ecpkparameters"},
+    {ERR_FUNC(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS),
+     "EC_GROUP_get_pentanomial_basis"},
+    {ERR_FUNC(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS),
+     "EC_GROUP_get_trinomial_basis"},
+    {ERR_FUNC(EC_F_EC_GROUP_NEW), "EC_GROUP_new"},
+    {ERR_FUNC(EC_F_EC_GROUP_NEW_BY_CURVE_NAME), "EC_GROUP_new_by_curve_name"},
+    {ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_DATA), "ec_group_new_from_data"},
+    {ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS),
+     "EC_GROUP_new_from_ecparameters"},
+    {ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS),
+     "EC_GROUP_new_from_ecpkparameters"},
+    {ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GF2M), "EC_GROUP_set_curve_GF2m"},
+    {ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GFP), "EC_GROUP_set_curve_GFp"},
+    {ERR_FUNC(EC_F_EC_GROUP_SET_GENERATOR), "EC_GROUP_set_generator"},
+    {ERR_FUNC(EC_F_EC_KEY_CHECK_KEY), "EC_KEY_check_key"},
+    {ERR_FUNC(EC_F_EC_KEY_COPY), "EC_KEY_copy"},
+    {ERR_FUNC(EC_F_EC_KEY_GENERATE_KEY), "EC_KEY_generate_key"},
+    {ERR_FUNC(EC_F_EC_KEY_NEW), "EC_KEY_new"},
+    {ERR_FUNC(EC_F_EC_KEY_NEW_METHOD), "EC_KEY_new_method"},
+    {ERR_FUNC(EC_F_EC_KEY_OCT2PRIV), "EC_KEY_oct2priv"},
+    {ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"},
+    {ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"},
+    {ERR_FUNC(EC_F_EC_KEY_PRIV2OCT), "EC_KEY_priv2oct"},
+    {ERR_FUNC(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES),
+     "EC_KEY_set_public_key_affine_coordinates"},
+    {ERR_FUNC(EC_F_EC_KEY_SIMPLE_CHECK_KEY), "ec_key_simple_check_key"},
+    {ERR_FUNC(EC_F_EC_KEY_SIMPLE_OCT2PRIV), "ec_key_simple_oct2priv"},
+    {ERR_FUNC(EC_F_EC_KEY_SIMPLE_PRIV2OCT), "ec_key_simple_priv2oct"},
+    {ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"},
+    {ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"},
+    {ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"},
+    {ERR_FUNC(EC_F_EC_POINT_COPY), "EC_POINT_copy"},
+    {ERR_FUNC(EC_F_EC_POINT_DBL), "EC_POINT_dbl"},
+    {ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M),
+     "EC_POINT_get_affine_coordinates_GF2m"},
+    {ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP),
+     "EC_POINT_get_affine_coordinates_GFp"},
+    {ERR_FUNC(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP),
+     "EC_POINT_get_Jprojective_coordinates_GFp"},
+    {ERR_FUNC(EC_F_EC_POINT_INVERT), "EC_POINT_invert"},
+    {ERR_FUNC(EC_F_EC_POINT_IS_AT_INFINITY), "EC_POINT_is_at_infinity"},
+    {ERR_FUNC(EC_F_EC_POINT_IS_ON_CURVE), "EC_POINT_is_on_curve"},
+    {ERR_FUNC(EC_F_EC_POINT_MAKE_AFFINE), "EC_POINT_make_affine"},
+    {ERR_FUNC(EC_F_EC_POINT_NEW), "EC_POINT_new"},
+    {ERR_FUNC(EC_F_EC_POINT_OCT2POINT), "EC_POINT_oct2point"},
+    {ERR_FUNC(EC_F_EC_POINT_POINT2OCT), "EC_POINT_point2oct"},
+    {ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M),
+     "EC_POINT_set_affine_coordinates_GF2m"},
+    {ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP),
+     "EC_POINT_set_affine_coordinates_GFp"},
+    {ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M),
+     "EC_POINT_set_compressed_coordinates_GF2m"},
+    {ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP),
+     "EC_POINT_set_compressed_coordinates_GFp"},
+    {ERR_FUNC(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP),
+     "EC_POINT_set_Jprojective_coordinates_GFp"},
+    {ERR_FUNC(EC_F_EC_POINT_SET_TO_INFINITY), "EC_POINT_set_to_infinity"},
+    {ERR_FUNC(EC_F_EC_PRE_COMP_NEW), "ec_pre_comp_new"},
+    {ERR_FUNC(EC_F_EC_WNAF_MUL), "ec_wNAF_mul"},
+    {ERR_FUNC(EC_F_EC_WNAF_PRECOMPUTE_MULT), "ec_wNAF_precompute_mult"},
+    {ERR_FUNC(EC_F_I2D_ECPARAMETERS), "i2d_ECParameters"},
+    {ERR_FUNC(EC_F_I2D_ECPKPARAMETERS), "i2d_ECPKParameters"},
+    {ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"},
+    {ERR_FUNC(EC_F_I2O_ECPUBLICKEY), "i2o_ECPublicKey"},
+    {ERR_FUNC(EC_F_NISTP224_PRE_COMP_NEW), "nistp224_pre_comp_new"},
+    {ERR_FUNC(EC_F_NISTP256_PRE_COMP_NEW), "nistp256_pre_comp_new"},
+    {ERR_FUNC(EC_F_NISTP521_PRE_COMP_NEW), "nistp521_pre_comp_new"},
+    {ERR_FUNC(EC_F_O2I_ECPUBLICKEY), "o2i_ECPublicKey"},
+    {ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE), "old_ec_priv_decode"},
+    {ERR_FUNC(EC_F_OSSL_ECDH_COMPUTE_KEY), "ossl_ecdh_compute_key"},
+    {ERR_FUNC(EC_F_OSSL_ECDSA_SIGN_SIG), "ossl_ecdsa_sign_sig"},
+    {ERR_FUNC(EC_F_OSSL_ECDSA_VERIFY_SIG), "ossl_ecdsa_verify_sig"},
+    {ERR_FUNC(EC_F_PKEY_ECX_DERIVE), "pkey_ecx_derive"},
+    {ERR_FUNC(EC_F_PKEY_EC_CTRL), "pkey_ec_ctrl"},
+    {ERR_FUNC(EC_F_PKEY_EC_CTRL_STR), "pkey_ec_ctrl_str"},
+    {ERR_FUNC(EC_F_PKEY_EC_DERIVE), "pkey_ec_derive"},
+    {ERR_FUNC(EC_F_PKEY_EC_KEYGEN), "pkey_ec_keygen"},
+    {ERR_FUNC(EC_F_PKEY_EC_PARAMGEN), "pkey_ec_paramgen"},
+    {ERR_FUNC(EC_F_PKEY_EC_SIGN), "pkey_ec_sign"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA EC_str_reasons[] = {
+    {ERR_REASON(EC_R_ASN1_ERROR), "asn1 error"},
+    {ERR_REASON(EC_R_BAD_SIGNATURE), "bad signature"},
+    {ERR_REASON(EC_R_BIGNUM_OUT_OF_RANGE), "bignum out of range"},
+    {ERR_REASON(EC_R_BUFFER_TOO_SMALL), "buffer too small"},
+    {ERR_REASON(EC_R_COORDINATES_OUT_OF_RANGE), "coordinates out of range"},
+    {ERR_REASON(EC_R_CURVE_DOES_NOT_SUPPORT_ECDH),
+     "curve does not support ecdh"},
+    {ERR_REASON(EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING),
+     "curve does not support signing"},
+    {ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE),
+     "d2i ecpkparameters failure"},
+    {ERR_REASON(EC_R_DECODE_ERROR), "decode error"},
+    {ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO), "discriminant is zero"},
+    {ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),
+     "ec group new by name failure"},
+    {ERR_REASON(EC_R_FIELD_TOO_LARGE), "field too large"},
+    {ERR_REASON(EC_R_GF2M_NOT_SUPPORTED), "gf2m not supported"},
+    {ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE),
+     "group2pkparameters failure"},
+    {ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE),
+     "i2d ecpkparameters failure"},
+    {ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS), "incompatible objects"},
+    {ERR_REASON(EC_R_INVALID_ARGUMENT), "invalid argument"},
+    {ERR_REASON(EC_R_INVALID_COMPRESSED_POINT), "invalid compressed point"},
+    {ERR_REASON(EC_R_INVALID_COMPRESSION_BIT), "invalid compression bit"},
+    {ERR_REASON(EC_R_INVALID_CURVE), "invalid curve"},
+    {ERR_REASON(EC_R_INVALID_DIGEST), "invalid digest"},
+    {ERR_REASON(EC_R_INVALID_DIGEST_TYPE), "invalid digest type"},
+    {ERR_REASON(EC_R_INVALID_ENCODING), "invalid encoding"},
+    {ERR_REASON(EC_R_INVALID_FIELD), "invalid field"},
+    {ERR_REASON(EC_R_INVALID_FORM), "invalid form"},
+    {ERR_REASON(EC_R_INVALID_GROUP_ORDER), "invalid group order"},
+    {ERR_REASON(EC_R_INVALID_KEY), "invalid key"},
+    {ERR_REASON(EC_R_INVALID_OUTPUT_LENGTH), "invalid output length"},
+    {ERR_REASON(EC_R_INVALID_PEER_KEY), "invalid peer key"},
+    {ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"},
+    {ERR_REASON(EC_R_INVALID_PRIVATE_KEY), "invalid private key"},
+    {ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS), "invalid trinomial basis"},
+    {ERR_REASON(EC_R_KDF_PARAMETER_ERROR), "kdf parameter error"},
+    {ERR_REASON(EC_R_KEYS_NOT_SET), "keys not set"},
+    {ERR_REASON(EC_R_MISSING_PARAMETERS), "missing parameters"},
+    {ERR_REASON(EC_R_MISSING_PRIVATE_KEY), "missing private key"},
+    {ERR_REASON(EC_R_NEED_NEW_SETUP_VALUES), "need new setup values"},
+    {ERR_REASON(EC_R_NOT_A_NIST_PRIME), "not a NIST prime"},
+    {ERR_REASON(EC_R_NOT_IMPLEMENTED), "not implemented"},
+    {ERR_REASON(EC_R_NOT_INITIALIZED), "not initialized"},
+    {ERR_REASON(EC_R_NO_PARAMETERS_SET), "no parameters set"},
+    {ERR_REASON(EC_R_NO_PRIVATE_VALUE), "no private value"},
+    {ERR_REASON(EC_R_OPERATION_NOT_SUPPORTED), "operation not supported"},
+    {ERR_REASON(EC_R_PASSED_NULL_PARAMETER), "passed null parameter"},
+    {ERR_REASON(EC_R_PEER_KEY_ERROR), "peer key error"},
+    {ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE),
+     "pkparameters2group failure"},
+    {ERR_REASON(EC_R_POINT_ARITHMETIC_FAILURE), "point arithmetic failure"},
+    {ERR_REASON(EC_R_POINT_AT_INFINITY), "point at infinity"},
+    {ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE), "point is not on curve"},
+    {ERR_REASON(EC_R_RANDOM_NUMBER_GENERATION_FAILED),
+     "random number generation failed"},
+    {ERR_REASON(EC_R_SHARED_INFO_ERROR), "shared info error"},
+    {ERR_REASON(EC_R_SLOT_FULL), "slot full"},
+    {ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"},
+    {ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"},
+    {ERR_REASON(EC_R_UNKNOWN_GROUP), "unknown group"},
+    {ERR_REASON(EC_R_UNKNOWN_ORDER), "unknown order"},
+    {ERR_REASON(EC_R_UNSUPPORTED_FIELD), "unsupported field"},
+    {ERR_REASON(EC_R_WRONG_CURVE_PARAMETERS), "wrong curve parameters"},
+    {ERR_REASON(EC_R_WRONG_ORDER), "wrong order"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_EC_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(EC_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, EC_str_functs);
+        ERR_load_strings(0, EC_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_key.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_key.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_key.c	(revision 331)
@@ -0,0 +1,637 @@
+/*
+ * Copyright 2002-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions originally developed by SUN MICROSYSTEMS, INC., and
+ * contributed to the OpenSSL project.
+ */
+
+#include <internal/cryptlib.h>
+#include <string.h>
+#include "ec_lcl.h"
+#include <openssl/err.h>
+#include <openssl/engine.h>
+
+EC_KEY *EC_KEY_new(void)
+{
+    return EC_KEY_new_method(NULL);
+}
+
+EC_KEY *EC_KEY_new_by_curve_name(int nid)
+{
+    EC_KEY *ret = EC_KEY_new();
+    if (ret == NULL)
+        return NULL;
+    ret->group = EC_GROUP_new_by_curve_name(nid);
+    if (ret->group == NULL) {
+        EC_KEY_free(ret);
+        return NULL;
+    }
+    if (ret->meth->set_group != NULL
+        && ret->meth->set_group(ret, ret->group) == 0) {
+        EC_KEY_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+void EC_KEY_free(EC_KEY *r)
+{
+    int i;
+
+    if (r == NULL)
+        return;
+
+    CRYPTO_atomic_add(&r->references, -1, &i, r->lock);
+    REF_PRINT_COUNT("EC_KEY", r);
+    if (i > 0)
+        return;
+    REF_ASSERT_ISNT(i < 0);
+
+    if (r->meth->finish != NULL)
+        r->meth->finish(r);
+
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE_finish(r->engine);
+#endif
+
+    if (r->group && r->group->meth->keyfinish)
+        r->group->meth->keyfinish(r);
+
+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data);
+    CRYPTO_THREAD_lock_free(r->lock);
+    EC_GROUP_free(r->group);
+    EC_POINT_free(r->pub_key);
+    BN_clear_free(r->priv_key);
+
+    OPENSSL_clear_free((void *)r, sizeof(EC_KEY));
+}
+
+EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
+{
+    if (dest == NULL || src == NULL) {
+        ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
+        return NULL;
+    }
+    if (src->meth != dest->meth) {
+        if (dest->meth->finish != NULL)
+            dest->meth->finish(dest);
+        if (dest->group && dest->group->meth->keyfinish)
+            dest->group->meth->keyfinish(dest);
+#ifndef OPENSSL_NO_ENGINE
+        if (ENGINE_finish(dest->engine) == 0)
+            return 0;
+        dest->engine = NULL;
+#endif
+    }
+    /* copy the parameters */
+    if (src->group != NULL) {
+        const EC_METHOD *meth = EC_GROUP_method_of(src->group);
+        /* clear the old group */
+        EC_GROUP_free(dest->group);
+        dest->group = EC_GROUP_new(meth);
+        if (dest->group == NULL)
+            return NULL;
+        if (!EC_GROUP_copy(dest->group, src->group))
+            return NULL;
+
+        /*  copy the public key */
+        if (src->pub_key != NULL) {
+            EC_POINT_free(dest->pub_key);
+            dest->pub_key = EC_POINT_new(src->group);
+            if (dest->pub_key == NULL)
+                return NULL;
+            if (!EC_POINT_copy(dest->pub_key, src->pub_key))
+                return NULL;
+        }
+        /* copy the private key */
+        if (src->priv_key != NULL) {
+            if (dest->priv_key == NULL) {
+                dest->priv_key = BN_new();
+                if (dest->priv_key == NULL)
+                    return NULL;
+            }
+            if (!BN_copy(dest->priv_key, src->priv_key))
+                return NULL;
+            if (src->group->meth->keycopy
+                && src->group->meth->keycopy(dest, src) == 0)
+                return NULL;
+        }
+    }
+
+
+    /* copy the rest */
+    dest->enc_flag = src->enc_flag;
+    dest->conv_form = src->conv_form;
+    dest->version = src->version;
+    dest->flags = src->flags;
+    if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_EC_KEY,
+                            &dest->ex_data, &src->ex_data))
+        return NULL;
+
+    if (src->meth != dest->meth) {
+#ifndef OPENSSL_NO_ENGINE
+        if (src->engine != NULL && ENGINE_init(src->engine) == 0)
+            return NULL;
+        dest->engine = src->engine;
+#endif
+        dest->meth = src->meth;
+    }
+
+    if (src->meth->copy != NULL && src->meth->copy(dest, src) == 0)
+        return NULL;
+
+    return dest;
+}
+
+EC_KEY *EC_KEY_dup(const EC_KEY *ec_key)
+{
+    EC_KEY *ret = EC_KEY_new_method(ec_key->engine);
+
+    if (ret == NULL)
+        return NULL;
+
+    if (EC_KEY_copy(ret, ec_key) == NULL) {
+        EC_KEY_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+int EC_KEY_up_ref(EC_KEY *r)
+{
+    int i;
+
+    if (CRYPTO_atomic_add(&r->references, 1, &i, r->lock) <= 0)
+        return 0;
+
+    REF_PRINT_COUNT("EC_KEY", r);
+    REF_ASSERT_ISNT(i < 2);
+    return ((i > 1) ? 1 : 0);
+}
+
+int EC_KEY_generate_key(EC_KEY *eckey)
+{
+    if (eckey == NULL || eckey->group == NULL) {
+        ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    if (eckey->meth->keygen != NULL)
+        return eckey->meth->keygen(eckey);
+    ECerr(EC_F_EC_KEY_GENERATE_KEY, EC_R_OPERATION_NOT_SUPPORTED);
+    return 0;
+}
+
+int ossl_ec_key_gen(EC_KEY *eckey)
+{
+    OPENSSL_assert(eckey->group->meth->keygen != NULL);
+    return eckey->group->meth->keygen(eckey);
+}
+
+int ec_key_simple_generate_key(EC_KEY *eckey)
+{
+    int ok = 0;
+    BN_CTX *ctx = NULL;
+    BIGNUM *priv_key = NULL;
+    const BIGNUM *order = NULL;
+    EC_POINT *pub_key = NULL;
+
+    if ((ctx = BN_CTX_new()) == NULL)
+        goto err;
+
+    if (eckey->priv_key == NULL) {
+        priv_key = BN_new();
+        if (priv_key == NULL)
+            goto err;
+    } else
+        priv_key = eckey->priv_key;
+
+    order = EC_GROUP_get0_order(eckey->group);
+    if (order == NULL)
+        goto err;
+
+    do
+        if (!BN_rand_range(priv_key, order))
+            goto err;
+    while (BN_is_zero(priv_key)) ;
+
+    if (eckey->pub_key == NULL) {
+        pub_key = EC_POINT_new(eckey->group);
+        if (pub_key == NULL)
+            goto err;
+    } else
+        pub_key = eckey->pub_key;
+
+    if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx))
+        goto err;
+
+    eckey->priv_key = priv_key;
+    eckey->pub_key = pub_key;
+
+    ok = 1;
+
+ err:
+    if (eckey->pub_key == NULL)
+        EC_POINT_free(pub_key);
+    if (eckey->priv_key != priv_key)
+        BN_free(priv_key);
+    BN_CTX_free(ctx);
+    return ok;
+}
+
+int ec_key_simple_generate_public_key(EC_KEY *eckey)
+{
+    return EC_POINT_mul(eckey->group, eckey->pub_key, eckey->priv_key, NULL,
+                        NULL, NULL);
+}
+
+int EC_KEY_check_key(const EC_KEY *eckey)
+{
+    if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
+        ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if (eckey->group->meth->keycheck == NULL) {
+        ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+
+    return eckey->group->meth->keycheck(eckey);
+}
+
+int ec_key_simple_check_key(const EC_KEY *eckey)
+{
+    int ok = 0;
+    BN_CTX *ctx = NULL;
+    const BIGNUM *order = NULL;
+    EC_POINT *point = NULL;
+
+    if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
+        ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) {
+        ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_AT_INFINITY);
+        goto err;
+    }
+
+    if ((ctx = BN_CTX_new()) == NULL)
+        goto err;
+    if ((point = EC_POINT_new(eckey->group)) == NULL)
+        goto err;
+
+    /* testing whether the pub_key is on the elliptic curve */
+    if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) {
+        ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
+        goto err;
+    }
+    /* testing whether pub_key * order is the point at infinity */
+    order = eckey->group->order;
+    if (BN_is_zero(order)) {
+        ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
+        goto err;
+    }
+    if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
+        ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB);
+        goto err;
+    }
+    if (!EC_POINT_is_at_infinity(eckey->group, point)) {
+        ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER);
+        goto err;
+    }
+    /*
+     * in case the priv_key is present : check if generator * priv_key ==
+     * pub_key
+     */
+    if (eckey->priv_key != NULL) {
+        if (BN_cmp(eckey->priv_key, order) >= 0) {
+            ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER);
+            goto err;
+        }
+        if (!EC_POINT_mul(eckey->group, point, eckey->priv_key,
+                          NULL, NULL, ctx)) {
+            ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB);
+            goto err;
+        }
+        if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) {
+            ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY);
+            goto err;
+        }
+    }
+    ok = 1;
+ err:
+    BN_CTX_free(ctx);
+    EC_POINT_free(point);
+    return ok;
+}
+
+int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
+                                             BIGNUM *y)
+{
+    BN_CTX *ctx = NULL;
+    BIGNUM *tx, *ty;
+    EC_POINT *point = NULL;
+    int ok = 0;
+#ifndef OPENSSL_NO_EC2M
+    int tmp_nid, is_char_two = 0;
+#endif
+
+    if (key == NULL || key->group == NULL || x == NULL || y == NULL) {
+        ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
+              ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    ctx = BN_CTX_new();
+    if (ctx == NULL)
+        return 0;
+
+    BN_CTX_start(ctx);
+    point = EC_POINT_new(key->group);
+
+    if (point == NULL)
+        goto err;
+
+    tx = BN_CTX_get(ctx);
+    ty = BN_CTX_get(ctx);
+    if (ty == NULL)
+        goto err;
+
+#ifndef OPENSSL_NO_EC2M
+    tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group));
+
+    if (tmp_nid == NID_X9_62_characteristic_two_field)
+        is_char_two = 1;
+
+    if (is_char_two) {
+        if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point,
+                                                  x, y, ctx))
+            goto err;
+        if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point,
+                                                  tx, ty, ctx))
+            goto err;
+    } else
+#endif
+    {
+        if (!EC_POINT_set_affine_coordinates_GFp(key->group, point,
+                                                 x, y, ctx))
+            goto err;
+        if (!EC_POINT_get_affine_coordinates_GFp(key->group, point,
+                                                 tx, ty, ctx))
+            goto err;
+    }
+    /*
+     * Check if retrieved coordinates match originals and are less than field
+     * order: if not values are out of range.
+     */
+    if (BN_cmp(x, tx) || BN_cmp(y, ty)
+        || (BN_cmp(x, key->group->field) >= 0)
+        || (BN_cmp(y, key->group->field) >= 0)) {
+        ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
+              EC_R_COORDINATES_OUT_OF_RANGE);
+        goto err;
+    }
+
+    if (!EC_KEY_set_public_key(key, point))
+        goto err;
+
+    if (EC_KEY_check_key(key) == 0)
+        goto err;
+
+    ok = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    BN_CTX_free(ctx);
+    EC_POINT_free(point);
+    return ok;
+
+}
+
+const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
+{
+    return key->group;
+}
+
+int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group)
+{
+    if (key->meth->set_group != NULL && key->meth->set_group(key, group) == 0)
+        return 0;
+    EC_GROUP_free(key->group);
+    key->group = EC_GROUP_dup(group);
+    return (key->group == NULL) ? 0 : 1;
+}
+
+const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
+{
+    return key->priv_key;
+}
+
+int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
+{
+    if (key->group == NULL || key->group->meth == NULL)
+        return 0;
+    if (key->group->meth->set_private != NULL
+        && key->group->meth->set_private(key, priv_key) == 0)
+        return 0;
+    if (key->meth->set_private != NULL
+        && key->meth->set_private(key, priv_key) == 0)
+        return 0;
+    BN_clear_free(key->priv_key);
+    key->priv_key = BN_dup(priv_key);
+    return (key->priv_key == NULL) ? 0 : 1;
+}
+
+const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
+{
+    return key->pub_key;
+}
+
+int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
+{
+    if (key->meth->set_public != NULL
+        && key->meth->set_public(key, pub_key) == 0)
+        return 0;
+    EC_POINT_free(key->pub_key);
+    key->pub_key = EC_POINT_dup(pub_key, key->group);
+    return (key->pub_key == NULL) ? 0 : 1;
+}
+
+unsigned int EC_KEY_get_enc_flags(const EC_KEY *key)
+{
+    return key->enc_flag;
+}
+
+void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags)
+{
+    key->enc_flag = flags;
+}
+
+point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key)
+{
+    return key->conv_form;
+}
+
+void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
+{
+    key->conv_form = cform;
+    if (key->group != NULL)
+        EC_GROUP_set_point_conversion_form(key->group, cform);
+}
+
+void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
+{
+    if (key->group != NULL)
+        EC_GROUP_set_asn1_flag(key->group, flag);
+}
+
+int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
+{
+    if (key->group == NULL)
+        return 0;
+    return EC_GROUP_precompute_mult(key->group, ctx);
+}
+
+int EC_KEY_get_flags(const EC_KEY *key)
+{
+    return key->flags;
+}
+
+void EC_KEY_set_flags(EC_KEY *key, int flags)
+{
+    key->flags |= flags;
+}
+
+void EC_KEY_clear_flags(EC_KEY *key, int flags)
+{
+    key->flags &= ~flags;
+}
+
+size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form,
+                        unsigned char **pbuf, BN_CTX *ctx)
+{
+    if (key == NULL || key->pub_key == NULL || key->group == NULL)
+        return 0;
+    return EC_POINT_point2buf(key->group, key->pub_key, form, pbuf, ctx);
+}
+
+int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len,
+                   BN_CTX *ctx)
+{
+    if (key == NULL || key->group == NULL)
+        return 0;
+    if (key->pub_key == NULL)
+        key->pub_key = EC_POINT_new(key->group);
+    if (key->pub_key == NULL)
+        return 0;
+    if (EC_POINT_oct2point(key->group, key->pub_key, buf, len, ctx) == 0)
+        return 0;
+    /*
+     * Save the point conversion form.
+     * For non-custom curves the first octet of the buffer (excluding
+     * the last significant bit) contains the point conversion form.
+     * EC_POINT_oct2point() has already performed sanity checking of
+     * the buffer so we know it is valid.
+     */
+    if ((key->group->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0)
+        key->conv_form = (point_conversion_form_t)(buf[0] & ~0x01);
+    return 1;
+}
+
+size_t EC_KEY_priv2oct(const EC_KEY *eckey,
+                       unsigned char *buf, size_t len)
+{
+    if (eckey->group == NULL || eckey->group->meth == NULL)
+        return 0;
+    if (eckey->group->meth->priv2oct == NULL) {
+        ECerr(EC_F_EC_KEY_PRIV2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+
+    return eckey->group->meth->priv2oct(eckey, buf, len);
+}
+
+size_t ec_key_simple_priv2oct(const EC_KEY *eckey,
+                              unsigned char *buf, size_t len)
+{
+    size_t buf_len;
+
+    buf_len = (EC_GROUP_order_bits(eckey->group) + 7) / 8;
+    if (eckey->priv_key == NULL)
+        return 0;
+    if (buf == NULL)
+        return buf_len;
+    else if (len < buf_len)
+        return 0;
+
+    /* Octetstring may need leading zeros if BN is to short */
+
+    if (BN_bn2binpad(eckey->priv_key, buf, buf_len) == -1) {
+        ECerr(EC_F_EC_KEY_SIMPLE_PRIV2OCT, EC_R_BUFFER_TOO_SMALL);
+        return 0;
+    }
+
+    return buf_len;
+}
+
+int EC_KEY_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len)
+{
+    if (eckey->group == NULL || eckey->group->meth == NULL)
+        return 0;
+    if (eckey->group->meth->oct2priv == NULL) {
+        ECerr(EC_F_EC_KEY_OCT2PRIV, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    return eckey->group->meth->oct2priv(eckey, buf, len);
+}
+
+int ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len)
+{
+    if (eckey->priv_key == NULL)
+        eckey->priv_key = BN_secure_new();
+    if (eckey->priv_key == NULL) {
+        ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    eckey->priv_key = BN_bin2bn(buf, len, eckey->priv_key);
+    if (eckey->priv_key == NULL) {
+        ECerr(EC_F_EC_KEY_SIMPLE_OCT2PRIV, ERR_R_BN_LIB);
+        return 0;
+    }
+    return 1;
+}
+
+size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf)
+{
+    size_t len;
+    unsigned char *buf;
+    len = EC_KEY_priv2oct(eckey, NULL, 0);
+    if (len == 0)
+        return 0;
+    buf = OPENSSL_malloc(len);
+    if (buf == NULL)
+        return 0;
+    len = EC_KEY_priv2oct(eckey, buf, len);
+    if (len == 0) {
+        OPENSSL_free(buf);
+        return 0;
+    }
+    *pbuf = buf;
+    return len;
+}
+
+int EC_KEY_can_sign(const EC_KEY *eckey)
+{
+    if (eckey->group == NULL || eckey->group->meth == NULL
+        || (eckey->group->meth->flags & EC_FLAGS_NO_SIGN))
+        return 0;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_kmeth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_kmeth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_kmeth.c	(revision 331)
@@ -0,0 +1,317 @@
+/*
+ * Copyright 2015-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 <string.h>
+#include <openssl/ec.h>
+#include <openssl/engine.h>
+#include <openssl/err.h>
+#include "ec_lcl.h"
+
+
+static const EC_KEY_METHOD openssl_ec_key_method = {
+    "OpenSSL EC_KEY method",
+    0,
+    0,0,0,0,0,0,
+    ossl_ec_key_gen,
+    ossl_ecdh_compute_key,
+    ossl_ecdsa_sign,
+    ossl_ecdsa_sign_setup,
+    ossl_ecdsa_sign_sig,
+    ossl_ecdsa_verify,
+    ossl_ecdsa_verify_sig
+};
+
+static const EC_KEY_METHOD *default_ec_key_meth = &openssl_ec_key_method;
+
+const EC_KEY_METHOD *EC_KEY_OpenSSL(void)
+{
+    return &openssl_ec_key_method;
+}
+
+const EC_KEY_METHOD *EC_KEY_get_default_method(void)
+{
+    return default_ec_key_meth;
+}
+
+void EC_KEY_set_default_method(const EC_KEY_METHOD *meth)
+{
+    if (meth == NULL)
+        default_ec_key_meth = &openssl_ec_key_method;
+    else
+        default_ec_key_meth = meth;
+}
+
+const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key)
+{
+    return key->meth;
+}
+
+int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth)
+{
+    void (*finish)(EC_KEY *key) = key->meth->finish;
+
+    if (finish != NULL)
+        finish(key);
+
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE_finish(key->engine);
+    key->engine = NULL;
+#endif
+
+    key->meth = meth;
+    if (meth->init != NULL)
+        return meth->init(key);
+    return 1;
+}
+
+EC_KEY *EC_KEY_new_method(ENGINE *engine)
+{
+    EC_KEY *ret = OPENSSL_zalloc(sizeof(*ret));
+
+    if (ret == NULL) {
+        ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    ret->references = 1;
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ret);
+        return NULL;
+    }
+
+    ret->meth = EC_KEY_get_default_method();
+#ifndef OPENSSL_NO_ENGINE
+    if (engine != NULL) {
+        if (!ENGINE_init(engine)) {
+            ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_ENGINE_LIB);
+            goto err;
+        }
+        ret->engine = engine;
+    } else
+        ret->engine = ENGINE_get_default_EC();
+    if (ret->engine != NULL) {
+        ret->meth = ENGINE_get_EC(ret->engine);
+        if (ret->meth == NULL) {
+            ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_ENGINE_LIB);
+            goto err;
+        }
+    }
+#endif
+
+    ret->version = 1;
+    ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
+
+    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EC_KEY, ret, &ret->ex_data)) {
+        goto err;
+    }
+
+    if (ret->meth->init != NULL && ret->meth->init(ret) == 0) {
+        ECerr(EC_F_EC_KEY_NEW_METHOD, ERR_R_INIT_FAIL);
+        goto err;
+    }
+    return ret;
+
+err:
+    EC_KEY_free(ret);
+    return NULL;
+}
+
+int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
+                     const EC_KEY *eckey,
+                     void *(*KDF) (const void *in, size_t inlen, void *out,
+                                   size_t *outlen))
+{
+    unsigned char *sec = NULL;
+    size_t seclen;
+    if (eckey->meth->compute_key == NULL) {
+        ECerr(EC_F_ECDH_COMPUTE_KEY, EC_R_OPERATION_NOT_SUPPORTED);
+        return 0;
+    }
+    if (outlen > INT_MAX) {
+        ECerr(EC_F_ECDH_COMPUTE_KEY, EC_R_INVALID_OUTPUT_LENGTH);
+        return 0;
+    }
+    if (!eckey->meth->compute_key(&sec, &seclen, pub_key, eckey))
+        return 0;
+    if (KDF != NULL) {
+        KDF(sec, seclen, out, &outlen);
+    } else {
+        if (outlen > seclen)
+            outlen = seclen;
+        memcpy(out, sec, outlen);
+    }
+    OPENSSL_clear_free(sec, seclen);
+    return outlen;
+}
+
+EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *meth)
+{
+    EC_KEY_METHOD *ret = OPENSSL_zalloc(sizeof(*meth));
+
+    if (ret == NULL)
+        return NULL;
+    if (meth != NULL)
+        *ret = *meth;
+    ret->flags |= EC_KEY_METHOD_DYNAMIC;
+    return ret;
+}
+
+void EC_KEY_METHOD_free(EC_KEY_METHOD *meth)
+{
+    if (meth->flags & EC_KEY_METHOD_DYNAMIC)
+        OPENSSL_free(meth);
+}
+
+void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth,
+                            int (*init)(EC_KEY *key),
+                            void (*finish)(EC_KEY *key),
+                            int (*copy)(EC_KEY *dest, const EC_KEY *src),
+                            int (*set_group)(EC_KEY *key, const EC_GROUP *grp),
+                            int (*set_private)(EC_KEY *key,
+                                               const BIGNUM *priv_key),
+                            int (*set_public)(EC_KEY *key,
+                                              const EC_POINT *pub_key))
+{
+    meth->init = init;
+    meth->finish = finish;
+    meth->copy = copy;
+    meth->set_group = set_group;
+    meth->set_private = set_private;
+    meth->set_public = set_public;
+}
+
+void EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth,
+                              int (*keygen)(EC_KEY *key))
+{
+    meth->keygen = keygen;
+}
+
+void EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth,
+                                   int (*ckey)(unsigned char **psec,
+                                               size_t *pseclen,
+                                               const EC_POINT *pub_key,
+                                               const EC_KEY *ecdh))
+{
+    meth->compute_key = ckey;
+}
+
+void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth,
+                            int (*sign)(int type, const unsigned char *dgst,
+                                        int dlen, unsigned char *sig,
+                                        unsigned int *siglen,
+                                        const BIGNUM *kinv, const BIGNUM *r,
+                                        EC_KEY *eckey),
+                            int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
+                                              BIGNUM **kinvp, BIGNUM **rp),
+                            ECDSA_SIG *(*sign_sig)(const unsigned char *dgst,
+                                                   int dgst_len,
+                                                   const BIGNUM *in_kinv,
+                                                   const BIGNUM *in_r,
+                                                   EC_KEY *eckey))
+{
+    meth->sign = sign;
+    meth->sign_setup = sign_setup;
+    meth->sign_sig = sign_sig;
+}
+
+void EC_KEY_METHOD_set_verify(EC_KEY_METHOD *meth,
+                              int (*verify)(int type, const unsigned
+                                            char *dgst, int dgst_len,
+                                            const unsigned char *sigbuf,
+                                            int sig_len, EC_KEY *eckey),
+                              int (*verify_sig)(const unsigned char *dgst,
+                                                int dgst_len,
+                                                const ECDSA_SIG *sig,
+                                                EC_KEY *eckey))
+{
+    meth->verify = verify;
+    meth->verify_sig = verify_sig;
+}
+
+void EC_KEY_METHOD_get_init(EC_KEY_METHOD *meth,
+                            int (**pinit)(EC_KEY *key),
+                            void (**pfinish)(EC_KEY *key),
+                            int (**pcopy)(EC_KEY *dest, const EC_KEY *src),
+                            int (**pset_group)(EC_KEY *key,
+                                               const EC_GROUP *grp),
+                            int (**pset_private)(EC_KEY *key,
+                                                 const BIGNUM *priv_key),
+                            int (**pset_public)(EC_KEY *key,
+                                                const EC_POINT *pub_key))
+{
+    if (pinit != NULL)
+        *pinit = meth->init;
+    if (pfinish != NULL)
+        *pfinish = meth->finish;
+    if (pcopy != NULL)
+        *pcopy = meth->copy;
+    if (pset_group != NULL)
+        *pset_group = meth->set_group;
+    if (pset_private != NULL)
+        *pset_private = meth->set_private;
+    if (pset_public != NULL)
+        *pset_public = meth->set_public;
+}
+
+void EC_KEY_METHOD_get_keygen(EC_KEY_METHOD *meth,
+                              int (**pkeygen)(EC_KEY *key))
+{
+    if (pkeygen != NULL)
+        *pkeygen = meth->keygen;
+}
+
+void EC_KEY_METHOD_get_compute_key(EC_KEY_METHOD *meth,
+                                   int (**pck)(unsigned char **pout,
+                                               size_t *poutlen,
+                                               const EC_POINT *pub_key,
+                                               const EC_KEY *ecdh))
+{
+    if (pck != NULL)
+        *pck = meth->compute_key;
+}
+
+void EC_KEY_METHOD_get_sign(EC_KEY_METHOD *meth,
+                            int (**psign)(int type, const unsigned char *dgst,
+                                          int dlen, unsigned char *sig,
+                                          unsigned int *siglen,
+                                          const BIGNUM *kinv, const BIGNUM *r,
+                                          EC_KEY *eckey),
+                            int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
+                                                BIGNUM **kinvp, BIGNUM **rp),
+                            ECDSA_SIG *(**psign_sig)(const unsigned char *dgst,
+                                                     int dgst_len,
+                                                     const BIGNUM *in_kinv,
+                                                     const BIGNUM *in_r,
+                                                     EC_KEY *eckey))
+{
+    if (psign != NULL)
+        *psign = meth->sign;
+    if (psign_setup != NULL)
+        *psign_setup = meth->sign_setup;
+    if (psign_sig != NULL)
+        *psign_sig = meth->sign_sig;
+}
+
+void EC_KEY_METHOD_get_verify(EC_KEY_METHOD *meth,
+                              int (**pverify)(int type, const unsigned
+                                              char *dgst, int dgst_len,
+                                              const unsigned char *sigbuf,
+                                              int sig_len, EC_KEY *eckey),
+                              int (**pverify_sig)(const unsigned char *dgst,
+                                                  int dgst_len,
+                                                  const ECDSA_SIG *sig,
+                                                  EC_KEY *eckey))
+{
+    if (pverify != NULL)
+        *pverify = meth->verify;
+    if (pverify_sig != NULL)
+        *pverify_sig = meth->verify_sig;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_lcl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_lcl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_lcl.h	(revision 331)
@@ -0,0 +1,613 @@
+/*
+ * Copyright 2001-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#include <stdlib.h>
+
+#include <openssl/obj_mac.h>
+#include <openssl/ec.h>
+#include <openssl/bn.h>
+
+#include "e_os.h"
+
+#if defined(__SUNPRO_C)
+# if __SUNPRO_C >= 0x520
+#  pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
+# endif
+#endif
+
+/* Use default functions for poin2oct, oct2point and compressed coordinates */
+#define EC_FLAGS_DEFAULT_OCT    0x1
+
+/* Use custom formats for EC_GROUP, EC_POINT and EC_KEY */
+#define EC_FLAGS_CUSTOM_CURVE   0x2
+
+/* Curve does not support signing operations */
+#define EC_FLAGS_NO_SIGN        0x4
+
+/*
+ * Structure details are not part of the exported interface, so all this may
+ * change in future versions.
+ */
+
+struct ec_method_st {
+    /* Various method flags */
+    int flags;
+    /* used by EC_METHOD_get_field_type: */
+    int field_type;             /* a NID */
+    /*
+     * used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free,
+     * EC_GROUP_copy:
+     */
+    int (*group_init) (EC_GROUP *);
+    void (*group_finish) (EC_GROUP *);
+    void (*group_clear_finish) (EC_GROUP *);
+    int (*group_copy) (EC_GROUP *, const EC_GROUP *);
+    /* used by EC_GROUP_set_curve_GFp, EC_GROUP_get_curve_GFp, */
+    /* EC_GROUP_set_curve_GF2m, and EC_GROUP_get_curve_GF2m: */
+    int (*group_set_curve) (EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
+                            const BIGNUM *b, BN_CTX *);
+    int (*group_get_curve) (const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b,
+                            BN_CTX *);
+    /* used by EC_GROUP_get_degree: */
+    int (*group_get_degree) (const EC_GROUP *);
+    int (*group_order_bits) (const EC_GROUP *);
+    /* used by EC_GROUP_check: */
+    int (*group_check_discriminant) (const EC_GROUP *, BN_CTX *);
+    /*
+     * used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free,
+     * EC_POINT_copy:
+     */
+    int (*point_init) (EC_POINT *);
+    void (*point_finish) (EC_POINT *);
+    void (*point_clear_finish) (EC_POINT *);
+    int (*point_copy) (EC_POINT *, const EC_POINT *);
+    /*-
+     * used by EC_POINT_set_to_infinity,
+     * EC_POINT_set_Jprojective_coordinates_GFp,
+     * EC_POINT_get_Jprojective_coordinates_GFp,
+     * EC_POINT_set_affine_coordinates_GFp,     ..._GF2m,
+     * EC_POINT_get_affine_coordinates_GFp,     ..._GF2m,
+     * EC_POINT_set_compressed_coordinates_GFp, ..._GF2m:
+     */
+    int (*point_set_to_infinity) (const EC_GROUP *, EC_POINT *);
+    int (*point_set_Jprojective_coordinates_GFp) (const EC_GROUP *,
+                                                  EC_POINT *, const BIGNUM *x,
+                                                  const BIGNUM *y,
+                                                  const BIGNUM *z, BN_CTX *);
+    int (*point_get_Jprojective_coordinates_GFp) (const EC_GROUP *,
+                                                  const EC_POINT *, BIGNUM *x,
+                                                  BIGNUM *y, BIGNUM *z,
+                                                  BN_CTX *);
+    int (*point_set_affine_coordinates) (const EC_GROUP *, EC_POINT *,
+                                         const BIGNUM *x, const BIGNUM *y,
+                                         BN_CTX *);
+    int (*point_get_affine_coordinates) (const EC_GROUP *, const EC_POINT *,
+                                         BIGNUM *x, BIGNUM *y, BN_CTX *);
+    int (*point_set_compressed_coordinates) (const EC_GROUP *, EC_POINT *,
+                                             const BIGNUM *x, int y_bit,
+                                             BN_CTX *);
+    /* used by EC_POINT_point2oct, EC_POINT_oct2point: */
+    size_t (*point2oct) (const EC_GROUP *, const EC_POINT *,
+                         point_conversion_form_t form, unsigned char *buf,
+                         size_t len, BN_CTX *);
+    int (*oct2point) (const EC_GROUP *, EC_POINT *, const unsigned char *buf,
+                      size_t len, BN_CTX *);
+    /* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */
+    int (*add) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
+                const EC_POINT *b, BN_CTX *);
+    int (*dbl) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
+    int (*invert) (const EC_GROUP *, EC_POINT *, BN_CTX *);
+    /*
+     * used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp:
+     */
+    int (*is_at_infinity) (const EC_GROUP *, const EC_POINT *);
+    int (*is_on_curve) (const EC_GROUP *, const EC_POINT *, BN_CTX *);
+    int (*point_cmp) (const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
+                      BN_CTX *);
+    /* used by EC_POINT_make_affine, EC_POINTs_make_affine: */
+    int (*make_affine) (const EC_GROUP *, EC_POINT *, BN_CTX *);
+    int (*points_make_affine) (const EC_GROUP *, size_t num, EC_POINT *[],
+                               BN_CTX *);
+    /*
+     * used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult,
+     * EC_POINT_have_precompute_mult (default implementations are used if the
+     * 'mul' pointer is 0):
+     */
+    int (*mul) (const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+                size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
+                BN_CTX *);
+    int (*precompute_mult) (EC_GROUP *group, BN_CTX *);
+    int (*have_precompute_mult) (const EC_GROUP *group);
+    /* internal functions */
+    /*
+     * 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and
+     * 'dbl' so that the same implementations of point operations can be used
+     * with different optimized implementations of expensive field
+     * operations:
+     */
+    int (*field_mul) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+                      const BIGNUM *b, BN_CTX *);
+    int (*field_sqr) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *);
+    int (*field_div) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+                      const BIGNUM *b, BN_CTX *);
+    /* e.g. to Montgomery */
+    int (*field_encode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+                         BN_CTX *);
+    /* e.g. from Montgomery */
+    int (*field_decode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+                         BN_CTX *);
+    int (*field_set_to_one) (const EC_GROUP *, BIGNUM *r, BN_CTX *);
+    /* private key operations */
+    size_t (*priv2oct)(const EC_KEY *eckey, unsigned char *buf, size_t len);
+    int (*oct2priv)(EC_KEY *eckey, const unsigned char *buf, size_t len);
+    int (*set_private)(EC_KEY *eckey, const BIGNUM *priv_key);
+    int (*keygen)(EC_KEY *eckey);
+    int (*keycheck)(const EC_KEY *eckey);
+    int (*keygenpub)(EC_KEY *eckey);
+    int (*keycopy)(EC_KEY *dst, const EC_KEY *src);
+    void (*keyfinish)(EC_KEY *eckey);
+    /* custom ECDH operation */
+    int (*ecdh_compute_key)(unsigned char **pout, size_t *poutlen,
+                            const EC_POINT *pub_key, const EC_KEY *ecdh);
+};
+
+/*
+ * Types and functions to manipulate pre-computed values.
+ */
+typedef struct nistp224_pre_comp_st NISTP224_PRE_COMP;
+typedef struct nistp256_pre_comp_st NISTP256_PRE_COMP;
+typedef struct nistp521_pre_comp_st NISTP521_PRE_COMP;
+typedef struct nistz256_pre_comp_st NISTZ256_PRE_COMP;
+typedef struct ec_pre_comp_st EC_PRE_COMP;
+
+struct ec_group_st {
+    const EC_METHOD *meth;
+    EC_POINT *generator;        /* optional */
+    BIGNUM *order, *cofactor;
+    int curve_name;             /* optional NID for named curve */
+    int asn1_flag;              /* flag to control the asn1 encoding */
+    point_conversion_form_t asn1_form;
+    unsigned char *seed;        /* optional seed for parameters (appears in
+                                 * ASN1) */
+    size_t seed_len;
+    /*
+     * The following members are handled by the method functions, even if
+     * they appear generic
+     */
+    /*
+     * Field specification. For curves over GF(p), this is the modulus; for
+     * curves over GF(2^m), this is the irreducible polynomial defining the
+     * field.
+     */
+    BIGNUM *field;
+    /*
+     * Field specification for curves over GF(2^m). The irreducible f(t) is
+     * then of the form: t^poly[0] + t^poly[1] + ... + t^poly[k] where m =
+     * poly[0] > poly[1] > ... > poly[k] = 0. The array is terminated with
+     * poly[k+1]=-1. All elliptic curve irreducibles have at most 5 non-zero
+     * terms.
+     */
+    int poly[6];
+    /*
+     * Curve coefficients. (Here the assumption is that BIGNUMs can be used
+     * or abused for all kinds of fields, not just GF(p).) For characteristic
+     * > 3, the curve is defined by a Weierstrass equation of the form y^2 =
+     * x^3 + a*x + b. For characteristic 2, the curve is defined by an
+     * equation of the form y^2 + x*y = x^3 + a*x^2 + b.
+     */
+    BIGNUM *a, *b;
+    /* enable optimized point arithmetics for special case */
+    int a_is_minus3;
+    /* method-specific (e.g., Montgomery structure) */
+    void *field_data1;
+    /* method-specific */
+    void *field_data2;
+    /* method-specific */
+    int (*field_mod_func) (BIGNUM *, const BIGNUM *, const BIGNUM *,
+                           BN_CTX *);
+    /* data for ECDSA inverse */
+    BN_MONT_CTX *mont_data;
+
+    /*
+     * Precomputed values for speed. The PCT_xxx names match the
+     * pre_comp.xxx union names; see the SETPRECOMP and HAVEPRECOMP
+     * macros, below.
+     */
+    enum {
+        PCT_none,
+        PCT_nistp224, PCT_nistp256, PCT_nistp521, PCT_nistz256,
+        PCT_ec
+    } pre_comp_type;
+    union {
+        NISTP224_PRE_COMP *nistp224;
+        NISTP256_PRE_COMP *nistp256;
+        NISTP521_PRE_COMP *nistp521;
+        NISTZ256_PRE_COMP *nistz256;
+        EC_PRE_COMP *ec;
+    } pre_comp;
+};
+
+#define SETPRECOMP(g, type, pre) \
+    g->pre_comp_type = PCT_##type, g->pre_comp.type = pre
+#define HAVEPRECOMP(g, type) \
+    g->pre_comp_type == PCT_##type && g->pre_comp.type != NULL
+
+struct ec_key_st {
+    const EC_KEY_METHOD *meth;
+    ENGINE *engine;
+    int version;
+    EC_GROUP *group;
+    EC_POINT *pub_key;
+    BIGNUM *priv_key;
+    unsigned int enc_flag;
+    point_conversion_form_t conv_form;
+    int references;
+    int flags;
+    CRYPTO_EX_DATA ex_data;
+    CRYPTO_RWLOCK *lock;
+};
+
+struct ec_point_st {
+    const EC_METHOD *meth;
+    /*
+     * All members except 'meth' are handled by the method functions, even if
+     * they appear generic
+     */
+    BIGNUM *X;
+    BIGNUM *Y;
+    BIGNUM *Z;                  /* Jacobian projective coordinates: * (X, Y,
+                                 * Z) represents (X/Z^2, Y/Z^3) if Z != 0 */
+    int Z_is_one;               /* enable optimized point arithmetics for
+                                 * special case */
+};
+
+NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *);
+NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *);
+NISTP521_PRE_COMP *EC_nistp521_pre_comp_dup(NISTP521_PRE_COMP *);
+NISTZ256_PRE_COMP *EC_nistz256_pre_comp_dup(NISTZ256_PRE_COMP *);
+NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *);
+EC_PRE_COMP *EC_ec_pre_comp_dup(EC_PRE_COMP *);
+
+void EC_pre_comp_free(EC_GROUP *group);
+void EC_nistp224_pre_comp_free(NISTP224_PRE_COMP *);
+void EC_nistp256_pre_comp_free(NISTP256_PRE_COMP *);
+void EC_nistp521_pre_comp_free(NISTP521_PRE_COMP *);
+void EC_nistz256_pre_comp_free(NISTZ256_PRE_COMP *);
+void EC_ec_pre_comp_free(EC_PRE_COMP *);
+
+/*
+ * method functions in ec_mult.c (ec_lib.c uses these as defaults if
+ * group->method->mul is 0)
+ */
+int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+                size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
+                BN_CTX *);
+int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *);
+int ec_wNAF_have_precompute_mult(const EC_GROUP *group);
+
+/* method functions in ecp_smpl.c */
+int ec_GFp_simple_group_init(EC_GROUP *);
+void ec_GFp_simple_group_finish(EC_GROUP *);
+void ec_GFp_simple_group_clear_finish(EC_GROUP *);
+int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *);
+int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p,
+                                  const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
+                                  BIGNUM *b, BN_CTX *);
+int ec_GFp_simple_group_get_degree(const EC_GROUP *);
+int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
+int ec_GFp_simple_point_init(EC_POINT *);
+void ec_GFp_simple_point_finish(EC_POINT *);
+void ec_GFp_simple_point_clear_finish(EC_POINT *);
+int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *);
+int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
+int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *,
+                                                  EC_POINT *, const BIGNUM *x,
+                                                  const BIGNUM *y,
+                                                  const BIGNUM *z, BN_CTX *);
+int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *,
+                                                  const EC_POINT *, BIGNUM *x,
+                                                  BIGNUM *y, BIGNUM *z,
+                                                  BN_CTX *);
+int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
+                                               const BIGNUM *x,
+                                               const BIGNUM *y, BN_CTX *);
+int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *,
+                                               const EC_POINT *, BIGNUM *x,
+                                               BIGNUM *y, BN_CTX *);
+int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
+                                             const BIGNUM *x, int y_bit,
+                                             BN_CTX *);
+size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *,
+                               point_conversion_form_t form,
+                               unsigned char *buf, size_t len, BN_CTX *);
+int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *,
+                            const unsigned char *buf, size_t len, BN_CTX *);
+int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
+                      const EC_POINT *b, BN_CTX *);
+int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
+                      BN_CTX *);
+int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
+int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
+int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
+                      BN_CTX *);
+int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num,
+                                     EC_POINT *[], BN_CTX *);
+int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+                            const BIGNUM *b, BN_CTX *);
+int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+                            BN_CTX *);
+
+/* method functions in ecp_mont.c */
+int ec_GFp_mont_group_init(EC_GROUP *);
+int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
+                                const BIGNUM *b, BN_CTX *);
+void ec_GFp_mont_group_finish(EC_GROUP *);
+void ec_GFp_mont_group_clear_finish(EC_GROUP *);
+int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *);
+int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+                          const BIGNUM *b, BN_CTX *);
+int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+                          BN_CTX *);
+int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+                             BN_CTX *);
+int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+                             BN_CTX *);
+int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *);
+
+/* method functions in ecp_nist.c */
+int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src);
+int ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a,
+                                const BIGNUM *b, BN_CTX *);
+int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+                          const BIGNUM *b, BN_CTX *);
+int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+                          BN_CTX *);
+
+/* method functions in ec2_smpl.c */
+int ec_GF2m_simple_group_init(EC_GROUP *);
+void ec_GF2m_simple_group_finish(EC_GROUP *);
+void ec_GF2m_simple_group_clear_finish(EC_GROUP *);
+int ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *);
+int ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p,
+                                   const BIGNUM *a, const BIGNUM *b,
+                                   BN_CTX *);
+int ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a,
+                                   BIGNUM *b, BN_CTX *);
+int ec_GF2m_simple_group_get_degree(const EC_GROUP *);
+int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *);
+int ec_GF2m_simple_point_init(EC_POINT *);
+void ec_GF2m_simple_point_finish(EC_POINT *);
+void ec_GF2m_simple_point_clear_finish(EC_POINT *);
+int ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *);
+int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *);
+int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *,
+                                                const BIGNUM *x,
+                                                const BIGNUM *y, BN_CTX *);
+int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *,
+                                                const EC_POINT *, BIGNUM *x,
+                                                BIGNUM *y, BN_CTX *);
+int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *,
+                                              const BIGNUM *x, int y_bit,
+                                              BN_CTX *);
+size_t ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *,
+                                point_conversion_form_t form,
+                                unsigned char *buf, size_t len, BN_CTX *);
+int ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *,
+                             const unsigned char *buf, size_t len, BN_CTX *);
+int ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
+                       const EC_POINT *b, BN_CTX *);
+int ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a,
+                       BN_CTX *);
+int ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *);
+int ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
+int ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b,
+                       BN_CTX *);
+int ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num,
+                                      EC_POINT *[], BN_CTX *);
+int ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+                             const BIGNUM *b, BN_CTX *);
+int ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+                             BN_CTX *);
+int ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a,
+                             const BIGNUM *b, BN_CTX *);
+
+/* method functions in ec2_mult.c */
+int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r,
+                       const BIGNUM *scalar, size_t num,
+                       const EC_POINT *points[], const BIGNUM *scalars[],
+                       BN_CTX *);
+int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ec_GF2m_have_precompute_mult(const EC_GROUP *group);
+
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+/* method functions in ecp_nistp224.c */
+int ec_GFp_nistp224_group_init(EC_GROUP *group);
+int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+                                    const BIGNUM *a, const BIGNUM *n,
+                                    BN_CTX *);
+int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
+                                                 const EC_POINT *point,
+                                                 BIGNUM *x, BIGNUM *y,
+                                                 BN_CTX *ctx);
+int ec_GFp_nistp224_mul(const EC_GROUP *group, EC_POINT *r,
+                        const BIGNUM *scalar, size_t num,
+                        const EC_POINT *points[], const BIGNUM *scalars[],
+                        BN_CTX *);
+int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
+                               const BIGNUM *scalar, size_t num,
+                               const EC_POINT *points[],
+                               const BIGNUM *scalars[], BN_CTX *ctx);
+int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group);
+
+/* method functions in ecp_nistp256.c */
+int ec_GFp_nistp256_group_init(EC_GROUP *group);
+int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+                                    const BIGNUM *a, const BIGNUM *n,
+                                    BN_CTX *);
+int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
+                                                 const EC_POINT *point,
+                                                 BIGNUM *x, BIGNUM *y,
+                                                 BN_CTX *ctx);
+int ec_GFp_nistp256_mul(const EC_GROUP *group, EC_POINT *r,
+                        const BIGNUM *scalar, size_t num,
+                        const EC_POINT *points[], const BIGNUM *scalars[],
+                        BN_CTX *);
+int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
+                               const BIGNUM *scalar, size_t num,
+                               const EC_POINT *points[],
+                               const BIGNUM *scalars[], BN_CTX *ctx);
+int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group);
+
+/* method functions in ecp_nistp521.c */
+int ec_GFp_nistp521_group_init(EC_GROUP *group);
+int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+                                    const BIGNUM *a, const BIGNUM *n,
+                                    BN_CTX *);
+int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group,
+                                                 const EC_POINT *point,
+                                                 BIGNUM *x, BIGNUM *y,
+                                                 BN_CTX *ctx);
+int ec_GFp_nistp521_mul(const EC_GROUP *group, EC_POINT *r,
+                        const BIGNUM *scalar, size_t num,
+                        const EC_POINT *points[], const BIGNUM *scalars[],
+                        BN_CTX *);
+int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
+                               const BIGNUM *scalar, size_t num,
+                               const EC_POINT *points[],
+                               const BIGNUM *scalars[], BN_CTX *ctx);
+int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group);
+
+/* utility functions in ecp_nistputil.c */
+void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
+                                              size_t felem_size,
+                                              void *tmp_felems,
+                                              void (*felem_one) (void *out),
+                                              int (*felem_is_zero) (const void
+                                                                    *in),
+                                              void (*felem_assign) (void *out,
+                                                                    const void
+                                                                    *in),
+                                              void (*felem_square) (void *out,
+                                                                    const void
+                                                                    *in),
+                                              void (*felem_mul) (void *out,
+                                                                 const void
+                                                                 *in1,
+                                                                 const void
+                                                                 *in2),
+                                              void (*felem_inv) (void *out,
+                                                                 const void
+                                                                 *in),
+                                              void (*felem_contract) (void
+                                                                      *out,
+                                                                      const
+                                                                      void
+                                                                      *in));
+void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
+                                     unsigned char *digit, unsigned char in);
+#endif
+int ec_precompute_mont_data(EC_GROUP *);
+int ec_group_simple_order_bits(const EC_GROUP *group);
+
+#ifdef ECP_NISTZ256_ASM
+/** Returns GFp methods using montgomery multiplication, with x86-64 optimized
+ * P256. See http://eprint.iacr.org/2013/816.
+ *  \return  EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_nistz256_method(void);
+#endif
+
+size_t ec_key_simple_priv2oct(const EC_KEY *eckey,
+                              unsigned char *buf, size_t len);
+int ec_key_simple_oct2priv(EC_KEY *eckey, const unsigned char *buf, size_t len);
+int ec_key_simple_generate_key(EC_KEY *eckey);
+int ec_key_simple_generate_public_key(EC_KEY *eckey);
+int ec_key_simple_check_key(const EC_KEY *eckey);
+
+/* EC_METHOD definitions */
+
+struct ec_key_method_st {
+    const char *name;
+    int32_t flags;
+    int (*init)(EC_KEY *key);
+    void (*finish)(EC_KEY *key);
+    int (*copy)(EC_KEY *dest, const EC_KEY *src);
+    int (*set_group)(EC_KEY *key, const EC_GROUP *grp);
+    int (*set_private)(EC_KEY *key, const BIGNUM *priv_key);
+    int (*set_public)(EC_KEY *key, const EC_POINT *pub_key);
+    int (*keygen)(EC_KEY *key);
+    int (*compute_key)(unsigned char **pout, size_t *poutlen,
+                       const EC_POINT *pub_key, const EC_KEY *ecdh);
+    int (*sign)(int type, const unsigned char *dgst, int dlen, unsigned char
+                *sig, unsigned int *siglen, const BIGNUM *kinv,
+                const BIGNUM *r, EC_KEY *eckey);
+    int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
+                      BIGNUM **rp);
+    ECDSA_SIG *(*sign_sig)(const unsigned char *dgst, int dgst_len,
+                           const BIGNUM *in_kinv, const BIGNUM *in_r,
+                           EC_KEY *eckey);
+
+    int (*verify)(int type, const unsigned char *dgst, int dgst_len,
+                  const unsigned char *sigbuf, int sig_len, EC_KEY *eckey);
+    int (*verify_sig)(const unsigned char *dgst, int dgst_len,
+                      const ECDSA_SIG *sig, EC_KEY *eckey);
+};
+
+#define EC_KEY_METHOD_DYNAMIC   1
+
+int ossl_ec_key_gen(EC_KEY *eckey);
+int ossl_ecdh_compute_key(unsigned char **pout, size_t *poutlen,
+                          const EC_POINT *pub_key, const EC_KEY *ecdh);
+int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
+                            const EC_POINT *pub_key, const EC_KEY *ecdh);
+
+struct ECDSA_SIG_st {
+    BIGNUM *r;
+    BIGNUM *s;
+};
+
+int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
+                          BIGNUM **rp);
+int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen,
+                    unsigned char *sig, unsigned int *siglen,
+                    const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey);
+ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
+                               const BIGNUM *in_kinv, const BIGNUM *in_r,
+                               EC_KEY *eckey);
+int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
+                      const unsigned char *sigbuf, int sig_len, EC_KEY *eckey);
+int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
+                          const ECDSA_SIG *sig, EC_KEY *eckey);
+
+int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
+           const uint8_t peer_public_value[32]);
+void X25519_public_from_private(uint8_t out_public_value[32],
+                                const uint8_t private_key[32]);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_lib.c	(revision 331)
@@ -0,0 +1,1004 @@
+/*
+ * Copyright 2001-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Binary polynomial ECC support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include <string.h>
+
+#include <openssl/err.h>
+#include <openssl/opensslv.h>
+
+#include "ec_lcl.h"
+
+/* functions for EC_GROUP objects */
+
+EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)
+{
+    EC_GROUP *ret;
+
+    if (meth == NULL) {
+        ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL);
+        return NULL;
+    }
+    if (meth->group_init == 0) {
+        ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return NULL;
+    }
+
+    ret = OPENSSL_zalloc(sizeof(*ret));
+    if (ret == NULL) {
+        ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    ret->meth = meth;
+    if ((ret->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) {
+        ret->order = BN_new();
+        if (ret->order == NULL)
+            goto err;
+        ret->cofactor = BN_new();
+        if (ret->cofactor == NULL)
+            goto err;
+    }
+    ret->asn1_flag = OPENSSL_EC_NAMED_CURVE;
+    ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED;
+    if (!meth->group_init(ret))
+        goto err;
+    return ret;
+
+ err:
+    BN_free(ret->order);
+    BN_free(ret->cofactor);
+    OPENSSL_free(ret);
+    return NULL;
+}
+
+void EC_pre_comp_free(EC_GROUP *group)
+{
+    switch (group->pre_comp_type) {
+    default:
+        break;
+#ifdef ECP_NISTZ256_REFERENCE_IMPLEMENTATION
+    case PCT_nistz256:
+        EC_nistz256_pre_comp_free(group->pre_comp.nistz256);
+        break;
+#endif
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+    case PCT_nistp224:
+        EC_nistp224_pre_comp_free(group->pre_comp.nistp224);
+        break;
+    case PCT_nistp256:
+        EC_nistp256_pre_comp_free(group->pre_comp.nistp256);
+        break;
+    case PCT_nistp521:
+        EC_nistp521_pre_comp_free(group->pre_comp.nistp521);
+        break;
+#endif
+    case PCT_ec:
+        EC_ec_pre_comp_free(group->pre_comp.ec);
+        break;
+    }
+    group->pre_comp.ec = NULL;
+}
+
+void EC_GROUP_free(EC_GROUP *group)
+{
+    if (!group)
+        return;
+
+    if (group->meth->group_finish != 0)
+        group->meth->group_finish(group);
+
+    EC_pre_comp_free(group);
+    BN_MONT_CTX_free(group->mont_data);
+    EC_POINT_free(group->generator);
+    BN_free(group->order);
+    BN_free(group->cofactor);
+    OPENSSL_free(group->seed);
+    OPENSSL_free(group);
+}
+
+void EC_GROUP_clear_free(EC_GROUP *group)
+{
+    if (!group)
+        return;
+
+    if (group->meth->group_clear_finish != 0)
+        group->meth->group_clear_finish(group);
+    else if (group->meth->group_finish != 0)
+        group->meth->group_finish(group);
+
+    EC_pre_comp_free(group);
+    BN_MONT_CTX_free(group->mont_data);
+    EC_POINT_clear_free(group->generator);
+    BN_clear_free(group->order);
+    BN_clear_free(group->cofactor);
+    OPENSSL_clear_free(group->seed, group->seed_len);
+    OPENSSL_clear_free(group, sizeof(*group));
+}
+
+int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
+{
+    if (dest->meth->group_copy == 0) {
+        ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    if (dest->meth != src->meth) {
+        ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
+    if (dest == src)
+        return 1;
+
+    /* Copy precomputed */
+    dest->pre_comp_type = src->pre_comp_type;
+    switch (src->pre_comp_type) {
+    default:
+        dest->pre_comp.ec = NULL;
+        break;
+#ifdef ECP_NISTZ256_REFERENCE_IMPLEMENTATION
+    case PCT_nistz256:
+        dest->pre_comp.nistz256 = EC_nistz256_pre_comp_dup(src->pre_comp.nistz256);
+        break;
+#endif
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+    case PCT_nistp224:
+        dest->pre_comp.nistp224 = EC_nistp224_pre_comp_dup(src->pre_comp.nistp224);
+        break;
+    case PCT_nistp256:
+        dest->pre_comp.nistp256 = EC_nistp256_pre_comp_dup(src->pre_comp.nistp256);
+        break;
+    case PCT_nistp521:
+        dest->pre_comp.nistp521 = EC_nistp521_pre_comp_dup(src->pre_comp.nistp521);
+        break;
+#endif
+    case PCT_ec:
+        dest->pre_comp.ec = EC_ec_pre_comp_dup(src->pre_comp.ec);
+        break;
+    }
+
+    if (src->mont_data != NULL) {
+        if (dest->mont_data == NULL) {
+            dest->mont_data = BN_MONT_CTX_new();
+            if (dest->mont_data == NULL)
+                return 0;
+        }
+        if (!BN_MONT_CTX_copy(dest->mont_data, src->mont_data))
+            return 0;
+    } else {
+        /* src->generator == NULL */
+        BN_MONT_CTX_free(dest->mont_data);
+        dest->mont_data = NULL;
+    }
+
+    if (src->generator != NULL) {
+        if (dest->generator == NULL) {
+            dest->generator = EC_POINT_new(dest);
+            if (dest->generator == NULL)
+                return 0;
+        }
+        if (!EC_POINT_copy(dest->generator, src->generator))
+            return 0;
+    } else {
+        /* src->generator == NULL */
+        EC_POINT_clear_free(dest->generator);
+        dest->generator = NULL;
+    }
+
+    if ((src->meth->flags & EC_FLAGS_CUSTOM_CURVE) == 0) {
+        if (!BN_copy(dest->order, src->order))
+            return 0;
+        if (!BN_copy(dest->cofactor, src->cofactor))
+            return 0;
+    }
+
+    dest->curve_name = src->curve_name;
+    dest->asn1_flag = src->asn1_flag;
+    dest->asn1_form = src->asn1_form;
+
+    if (src->seed) {
+        OPENSSL_free(dest->seed);
+        dest->seed = OPENSSL_malloc(src->seed_len);
+        if (dest->seed == NULL)
+            return 0;
+        if (!memcpy(dest->seed, src->seed, src->seed_len))
+            return 0;
+        dest->seed_len = src->seed_len;
+    } else {
+        OPENSSL_free(dest->seed);
+        dest->seed = NULL;
+        dest->seed_len = 0;
+    }
+
+    return dest->meth->group_copy(dest, src);
+}
+
+EC_GROUP *EC_GROUP_dup(const EC_GROUP *a)
+{
+    EC_GROUP *t = NULL;
+    int ok = 0;
+
+    if (a == NULL)
+        return NULL;
+
+    if ((t = EC_GROUP_new(a->meth)) == NULL)
+        return (NULL);
+    if (!EC_GROUP_copy(t, a))
+        goto err;
+
+    ok = 1;
+
+ err:
+    if (!ok) {
+        EC_GROUP_free(t);
+        return NULL;
+    }
+        return t;
+}
+
+const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)
+{
+    return group->meth;
+}
+
+int EC_METHOD_get_field_type(const EC_METHOD *meth)
+{
+    return meth->field_type;
+}
+
+int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
+                           const BIGNUM *order, const BIGNUM *cofactor)
+{
+    if (generator == NULL) {
+        ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if (group->generator == NULL) {
+        group->generator = EC_POINT_new(group);
+        if (group->generator == NULL)
+            return 0;
+    }
+    if (!EC_POINT_copy(group->generator, generator))
+        return 0;
+
+    if (order != NULL) {
+        if (!BN_copy(group->order, order))
+            return 0;
+    } else
+        BN_zero(group->order);
+
+    if (cofactor != NULL) {
+        if (!BN_copy(group->cofactor, cofactor))
+            return 0;
+    } else
+        BN_zero(group->cofactor);
+
+    /*
+     * Some groups have an order with
+     * factors of two, which makes the Montgomery setup fail.
+     * |group->mont_data| will be NULL in this case.
+     */
+    if (BN_is_odd(group->order)) {
+        return ec_precompute_mont_data(group);
+    }
+
+    BN_MONT_CTX_free(group->mont_data);
+    group->mont_data = NULL;
+    return 1;
+}
+
+const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
+{
+    return group->generator;
+}
+
+BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group)
+{
+    return group->mont_data;
+}
+
+int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx)
+{
+    if (group->order == NULL)
+        return 0;
+    if (!BN_copy(order, group->order))
+        return 0;
+
+    return !BN_is_zero(order);
+}
+
+const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group)
+{
+    return group->order;
+}
+
+int EC_GROUP_order_bits(const EC_GROUP *group)
+{
+    OPENSSL_assert(group->meth->group_order_bits != NULL);
+    return group->meth->group_order_bits(group);
+}
+
+int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
+                          BN_CTX *ctx)
+{
+
+    if (group->cofactor == NULL)
+        return 0;
+    if (!BN_copy(cofactor, group->cofactor))
+        return 0;
+
+    return !BN_is_zero(group->cofactor);
+}
+
+const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group)
+{
+    return group->cofactor;
+}
+
+void EC_GROUP_set_curve_name(EC_GROUP *group, int nid)
+{
+    group->curve_name = nid;
+}
+
+int EC_GROUP_get_curve_name(const EC_GROUP *group)
+{
+    return group->curve_name;
+}
+
+void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag)
+{
+    group->asn1_flag = flag;
+}
+
+int EC_GROUP_get_asn1_flag(const EC_GROUP *group)
+{
+    return group->asn1_flag;
+}
+
+void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
+                                        point_conversion_form_t form)
+{
+    group->asn1_form = form;
+}
+
+point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP
+                                                           *group)
+{
+    return group->asn1_form;
+}
+
+size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)
+{
+    OPENSSL_free(group->seed);
+    group->seed = NULL;
+    group->seed_len = 0;
+
+    if (!len || !p)
+        return 1;
+
+    if ((group->seed = OPENSSL_malloc(len)) == NULL)
+        return 0;
+    memcpy(group->seed, p, len);
+    group->seed_len = len;
+
+    return len;
+}
+
+unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group)
+{
+    return group->seed;
+}
+
+size_t EC_GROUP_get_seed_len(const EC_GROUP *group)
+{
+    return group->seed_len;
+}
+
+int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
+                           const BIGNUM *b, BN_CTX *ctx)
+{
+    if (group->meth->group_set_curve == 0) {
+        ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    return group->meth->group_set_curve(group, p, a, b, ctx);
+}
+
+int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
+                           BIGNUM *b, BN_CTX *ctx)
+{
+    if (group->meth->group_get_curve == 0) {
+        ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    return group->meth->group_get_curve(group, p, a, b, ctx);
+}
+
+#ifndef OPENSSL_NO_EC2M
+int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
+                            const BIGNUM *b, BN_CTX *ctx)
+{
+    if (group->meth->group_set_curve == 0) {
+        ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M,
+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    return group->meth->group_set_curve(group, p, a, b, ctx);
+}
+
+int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
+                            BIGNUM *b, BN_CTX *ctx)
+{
+    if (group->meth->group_get_curve == 0) {
+        ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M,
+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    return group->meth->group_get_curve(group, p, a, b, ctx);
+}
+#endif
+
+int EC_GROUP_get_degree(const EC_GROUP *group)
+{
+    if (group->meth->group_get_degree == 0) {
+        ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    return group->meth->group_get_degree(group);
+}
+
+int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
+{
+    if (group->meth->group_check_discriminant == 0) {
+        ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT,
+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    return group->meth->group_check_discriminant(group, ctx);
+}
+
+int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
+{
+    int r = 0;
+    BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
+    BN_CTX *ctx_new = NULL;
+
+    /* compare the field types */
+    if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
+        EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
+        return 1;
+    /* compare the curve name (if present in both) */
+    if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
+        EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
+        return 1;
+    if (a->meth->flags & EC_FLAGS_CUSTOM_CURVE)
+        return 0;
+
+    if (ctx == NULL)
+        ctx_new = ctx = BN_CTX_new();
+    if (ctx == NULL)
+        return -1;
+
+    BN_CTX_start(ctx);
+    a1 = BN_CTX_get(ctx);
+    a2 = BN_CTX_get(ctx);
+    a3 = BN_CTX_get(ctx);
+    b1 = BN_CTX_get(ctx);
+    b2 = BN_CTX_get(ctx);
+    b3 = BN_CTX_get(ctx);
+    if (b3 == NULL) {
+        BN_CTX_end(ctx);
+        BN_CTX_free(ctx_new);
+        return -1;
+    }
+
+    /*
+     * XXX This approach assumes that the external representation of curves
+     * over the same field type is the same.
+     */
+    if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) ||
+        !b->meth->group_get_curve(b, b1, b2, b3, ctx))
+        r = 1;
+
+    if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3))
+        r = 1;
+
+    /* XXX EC_POINT_cmp() assumes that the methods are equal */
+    if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a),
+                          EC_GROUP_get0_generator(b), ctx))
+        r = 1;
+
+    if (!r) {
+        const BIGNUM *ao, *bo, *ac, *bc;
+        /* compare the order and cofactor */
+        ao = EC_GROUP_get0_order(a);
+        bo = EC_GROUP_get0_order(b);
+        ac = EC_GROUP_get0_cofactor(a);
+        bc = EC_GROUP_get0_cofactor(b);
+        if (ao == NULL || bo == NULL) {
+            BN_CTX_end(ctx);
+            BN_CTX_free(ctx_new);
+            return -1;
+        }
+        if (BN_cmp(ao, bo) || BN_cmp(ac, bc))
+            r = 1;
+    }
+
+    BN_CTX_end(ctx);
+    BN_CTX_free(ctx_new);
+
+    return r;
+}
+
+/* functions for EC_POINT objects */
+
+EC_POINT *EC_POINT_new(const EC_GROUP *group)
+{
+    EC_POINT *ret;
+
+    if (group == NULL) {
+        ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER);
+        return NULL;
+    }
+    if (group->meth->point_init == 0) {
+        ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return NULL;
+    }
+
+    ret = OPENSSL_zalloc(sizeof(*ret));
+    if (ret == NULL) {
+        ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    ret->meth = group->meth;
+
+    if (!ret->meth->point_init(ret)) {
+        OPENSSL_free(ret);
+        return NULL;
+    }
+
+    return ret;
+}
+
+void EC_POINT_free(EC_POINT *point)
+{
+    if (!point)
+        return;
+
+    if (point->meth->point_finish != 0)
+        point->meth->point_finish(point);
+    OPENSSL_free(point);
+}
+
+void EC_POINT_clear_free(EC_POINT *point)
+{
+    if (!point)
+        return;
+
+    if (point->meth->point_clear_finish != 0)
+        point->meth->point_clear_finish(point);
+    else if (point->meth->point_finish != 0)
+        point->meth->point_finish(point);
+    OPENSSL_clear_free(point, sizeof(*point));
+}
+
+int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src)
+{
+    if (dest->meth->point_copy == 0) {
+        ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    if (dest->meth != src->meth) {
+        ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
+    if (dest == src)
+        return 1;
+    return dest->meth->point_copy(dest, src);
+}
+
+EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group)
+{
+    EC_POINT *t;
+    int r;
+
+    if (a == NULL)
+        return NULL;
+
+    t = EC_POINT_new(group);
+    if (t == NULL)
+        return (NULL);
+    r = EC_POINT_copy(t, a);
+    if (!r) {
+        EC_POINT_free(t);
+        return NULL;
+    }
+    return t;
+}
+
+const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)
+{
+    return point->meth;
+}
+
+int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
+{
+    if (group->meth->point_set_to_infinity == 0) {
+        ECerr(EC_F_EC_POINT_SET_TO_INFINITY,
+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    if (group->meth != point->meth) {
+        ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
+    return group->meth->point_set_to_infinity(group, point);
+}
+
+int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
+                                             EC_POINT *point, const BIGNUM *x,
+                                             const BIGNUM *y, const BIGNUM *z,
+                                             BN_CTX *ctx)
+{
+    if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
+        ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,
+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    if (group->meth != point->meth) {
+        ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP,
+              EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
+    return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x,
+                                                              y, z, ctx);
+}
+
+int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
+                                             const EC_POINT *point, BIGNUM *x,
+                                             BIGNUM *y, BIGNUM *z,
+                                             BN_CTX *ctx)
+{
+    if (group->meth->point_get_Jprojective_coordinates_GFp == 0) {
+        ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    if (group->meth != point->meth) {
+        ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,
+              EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
+    return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x,
+                                                              y, z, ctx);
+}
+
+int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group,
+                                        EC_POINT *point, const BIGNUM *x,
+                                        const BIGNUM *y, BN_CTX *ctx)
+{
+    if (group->meth->point_set_affine_coordinates == 0) {
+        ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    if (group->meth != point->meth) {
+        ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
+              EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
+    if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx))
+        return 0;
+
+    if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
+        ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP,
+              EC_R_POINT_IS_NOT_ON_CURVE);
+        return 0;
+    }
+    return 1;
+}
+
+#ifndef OPENSSL_NO_EC2M
+int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group,
+                                         EC_POINT *point, const BIGNUM *x,
+                                         const BIGNUM *y, BN_CTX *ctx)
+{
+    if (group->meth->point_set_affine_coordinates == 0) {
+        ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    if (group->meth != point->meth) {
+        ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
+              EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
+    if (!group->meth->point_set_affine_coordinates(group, point, x, y, ctx))
+        return 0;
+
+    if (EC_POINT_is_on_curve(group, point, ctx) <= 0) {
+        ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M,
+              EC_R_POINT_IS_NOT_ON_CURVE);
+        return 0;
+    }
+    return 1;
+}
+#endif
+
+int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
+                                        const EC_POINT *point, BIGNUM *x,
+                                        BIGNUM *y, BN_CTX *ctx)
+{
+    if (group->meth->point_get_affine_coordinates == 0) {
+        ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,
+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    if (group->meth != point->meth) {
+        ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,
+              EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
+    return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
+}
+
+#ifndef OPENSSL_NO_EC2M
+int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
+                                         const EC_POINT *point, BIGNUM *x,
+                                         BIGNUM *y, BN_CTX *ctx)
+{
+    if (group->meth->point_get_affine_coordinates == 0) {
+        ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M,
+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    if (group->meth != point->meth) {
+        ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M,
+              EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
+    return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
+}
+#endif
+
+int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+                 const EC_POINT *b, BN_CTX *ctx)
+{
+    if (group->meth->add == 0) {
+        ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    if ((group->meth != r->meth) || (r->meth != a->meth)
+        || (a->meth != b->meth)) {
+        ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
+    return group->meth->add(group, r, a, b, ctx);
+}
+
+int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+                 BN_CTX *ctx)
+{
+    if (group->meth->dbl == 0) {
+        ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    if ((group->meth != r->meth) || (r->meth != a->meth)) {
+        ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
+    return group->meth->dbl(group, r, a, ctx);
+}
+
+int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx)
+{
+    if (group->meth->invert == 0) {
+        ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    if (group->meth != a->meth) {
+        ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
+    return group->meth->invert(group, a, ctx);
+}
+
+int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
+{
+    if (group->meth->is_at_infinity == 0) {
+        ECerr(EC_F_EC_POINT_IS_AT_INFINITY,
+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    if (group->meth != point->meth) {
+        ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
+    return group->meth->is_at_infinity(group, point);
+}
+
+/*
+ * Check whether an EC_POINT is on the curve or not. Note that the return
+ * value for this function should NOT be treated as a boolean. Return values:
+ *  1: The point is on the curve
+ *  0: The point is not on the curve
+ * -1: An error occurred
+ */
+int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
+                         BN_CTX *ctx)
+{
+    if (group->meth->is_on_curve == 0) {
+        ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    if (group->meth != point->meth) {
+        ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
+    return group->meth->is_on_curve(group, point, ctx);
+}
+
+int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
+                 BN_CTX *ctx)
+{
+    if (group->meth->point_cmp == 0) {
+        ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return -1;
+    }
+    if ((group->meth != a->meth) || (a->meth != b->meth)) {
+        ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
+        return -1;
+    }
+    return group->meth->point_cmp(group, a, b, ctx);
+}
+
+int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
+{
+    if (group->meth->make_affine == 0) {
+        ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    if (group->meth != point->meth) {
+        ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
+    return group->meth->make_affine(group, point, ctx);
+}
+
+int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
+                          EC_POINT *points[], BN_CTX *ctx)
+{
+    size_t i;
+
+    if (group->meth->points_make_affine == 0) {
+        ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    for (i = 0; i < num; i++) {
+        if (group->meth != points[i]->meth) {
+            ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS);
+            return 0;
+        }
+    }
+    return group->meth->points_make_affine(group, num, points, ctx);
+}
+
+/*
+ * Functions for point multiplication. If group->meth->mul is 0, we use the
+ * wNAF-based implementations in ec_mult.c; otherwise we dispatch through
+ * methods.
+ */
+
+int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+                  size_t num, const EC_POINT *points[],
+                  const BIGNUM *scalars[], BN_CTX *ctx)
+{
+    if (group->meth->mul == 0)
+        /* use default */
+        return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
+
+    return group->meth->mul(group, r, scalar, num, points, scalars, ctx);
+}
+
+int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
+                 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
+{
+    /* just a convenient interface to EC_POINTs_mul() */
+
+    const EC_POINT *points[1];
+    const BIGNUM *scalars[1];
+
+    points[0] = point;
+    scalars[0] = p_scalar;
+
+    return EC_POINTs_mul(group, r, g_scalar,
+                         (point != NULL
+                          && p_scalar != NULL), points, scalars, ctx);
+}
+
+int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+{
+    if (group->meth->mul == 0)
+        /* use default */
+        return ec_wNAF_precompute_mult(group, ctx);
+
+    if (group->meth->precompute_mult != 0)
+        return group->meth->precompute_mult(group, ctx);
+    else
+        return 1;               /* nothing to do, so report success */
+}
+
+int EC_GROUP_have_precompute_mult(const EC_GROUP *group)
+{
+    if (group->meth->mul == 0)
+        /* use default */
+        return ec_wNAF_have_precompute_mult(group);
+
+    if (group->meth->have_precompute_mult != 0)
+        return group->meth->have_precompute_mult(group);
+    else
+        return 0;               /* cannot tell whether precomputation has
+                                 * been performed */
+}
+
+/*
+ * ec_precompute_mont_data sets |group->mont_data| from |group->order| and
+ * returns one on success. On error it returns zero.
+ */
+int ec_precompute_mont_data(EC_GROUP *group)
+{
+    BN_CTX *ctx = BN_CTX_new();
+    int ret = 0;
+
+    BN_MONT_CTX_free(group->mont_data);
+    group->mont_data = NULL;
+
+    if (ctx == NULL)
+        goto err;
+
+    group->mont_data = BN_MONT_CTX_new();
+    if (group->mont_data == NULL)
+        goto err;
+
+    if (!BN_MONT_CTX_set(group->mont_data, group->order, ctx)) {
+        BN_MONT_CTX_free(group->mont_data);
+        group->mont_data = NULL;
+        goto err;
+    }
+
+    ret = 1;
+
+ err:
+
+    BN_CTX_free(ctx);
+    return ret;
+}
+
+int EC_KEY_set_ex_data(EC_KEY *key, int idx, void *arg)
+{
+    return CRYPTO_set_ex_data(&key->ex_data, idx, arg);
+}
+
+void *EC_KEY_get_ex_data(const EC_KEY *key, int idx)
+{
+    return CRYPTO_get_ex_data(&key->ex_data, idx);
+}
+
+int ec_group_simple_order_bits(const EC_GROUP *group)
+{
+    if (group->order == NULL)
+        return 0;
+    return BN_num_bits(group->order);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_mult.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_mult.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_mult.c	(revision 331)
@@ -0,0 +1,680 @@
+/*
+ * Copyright 2001-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include <string.h>
+#include <openssl/err.h>
+
+#include "internal/cryptlib.h"
+#include "internal/bn_int.h"
+#include "ec_lcl.h"
+
+/*
+ * This file implements the wNAF-based interleaving multi-exponentiation method
+ * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp>);
+ * for multiplication with precomputation, we use wNAF splitting
+ * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp>).
+ */
+
+/* structure for precomputed multiples of the generator */
+struct ec_pre_comp_st {
+    const EC_GROUP *group;      /* parent EC_GROUP object */
+    size_t blocksize;           /* block size for wNAF splitting */
+    size_t numblocks;           /* max. number of blocks for which we have
+                                 * precomputation */
+    size_t w;                   /* window size */
+    EC_POINT **points;          /* array with pre-calculated multiples of
+                                 * generator: 'num' pointers to EC_POINT
+                                 * objects followed by a NULL */
+    size_t num;                 /* numblocks * 2^(w-1) */
+    int references;
+    CRYPTO_RWLOCK *lock;
+};
+
+static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group)
+{
+    EC_PRE_COMP *ret = NULL;
+
+    if (!group)
+        return NULL;
+
+    ret = OPENSSL_zalloc(sizeof(*ret));
+    if (ret == NULL) {
+        ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+        return ret;
+    }
+
+    ret->group = group;
+    ret->blocksize = 8;         /* default */
+    ret->w = 4;                 /* default */
+    ret->references = 1;
+
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+EC_PRE_COMP *EC_ec_pre_comp_dup(EC_PRE_COMP *pre)
+{
+    int i;
+    if (pre != NULL)
+        CRYPTO_atomic_add(&pre->references, 1, &i, pre->lock);
+    return pre;
+}
+
+void EC_ec_pre_comp_free(EC_PRE_COMP *pre)
+{
+    int i;
+
+    if (pre == NULL)
+        return;
+
+    CRYPTO_atomic_add(&pre->references, -1, &i, pre->lock);
+    REF_PRINT_COUNT("EC_ec", pre);
+    if (i > 0)
+        return;
+    REF_ASSERT_ISNT(i < 0);
+
+    if (pre->points != NULL) {
+        EC_POINT **pts;
+
+        for (pts = pre->points; *pts != NULL; pts++)
+            EC_POINT_free(*pts);
+        OPENSSL_free(pre->points);
+    }
+    CRYPTO_THREAD_lock_free(pre->lock);
+    OPENSSL_free(pre);
+}
+
+/*
+ * TODO: table should be optimised for the wNAF-based implementation,
+ * sometimes smaller windows will give better performance (thus the
+ * boundaries should be increased)
+ */
+#define EC_window_bits_for_scalar_size(b) \
+                ((size_t) \
+                 ((b) >= 2000 ? 6 : \
+                  (b) >=  800 ? 5 : \
+                  (b) >=  300 ? 4 : \
+                  (b) >=   70 ? 3 : \
+                  (b) >=   20 ? 2 : \
+                  1))
+
+/*-
+ * Compute
+ *      \sum scalars[i]*points[i],
+ * also including
+ *      scalar*generator
+ * in the addition if scalar != NULL
+ */
+int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
+                size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
+                BN_CTX *ctx)
+{
+    BN_CTX *new_ctx = NULL;
+    const EC_POINT *generator = NULL;
+    EC_POINT *tmp = NULL;
+    size_t totalnum;
+    size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */
+    size_t pre_points_per_block = 0;
+    size_t i, j;
+    int k;
+    int r_is_inverted = 0;
+    int r_is_at_infinity = 1;
+    size_t *wsize = NULL;       /* individual window sizes */
+    signed char **wNAF = NULL;  /* individual wNAFs */
+    size_t *wNAF_len = NULL;
+    size_t max_len = 0;
+    size_t num_val;
+    EC_POINT **val = NULL;      /* precomputation */
+    EC_POINT **v;
+    EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or
+                                 * 'pre_comp->points' */
+    const EC_PRE_COMP *pre_comp = NULL;
+    int num_scalar = 0;         /* flag: will be set to 1 if 'scalar' must be
+                                 * treated like other scalars, i.e.
+                                 * precomputation is not available */
+    int ret = 0;
+
+    if (group->meth != r->meth) {
+        ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
+
+    if ((scalar == NULL) && (num == 0)) {
+        return EC_POINT_set_to_infinity(group, r);
+    }
+
+    for (i = 0; i < num; i++) {
+        if (group->meth != points[i]->meth) {
+            ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);
+            return 0;
+        }
+    }
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            goto err;
+    }
+
+    if (scalar != NULL) {
+        generator = EC_GROUP_get0_generator(group);
+        if (generator == NULL) {
+            ECerr(EC_F_EC_WNAF_MUL, EC_R_UNDEFINED_GENERATOR);
+            goto err;
+        }
+
+        /* look if we can use precomputed multiples of generator */
+
+        pre_comp = group->pre_comp.ec;
+        if (pre_comp && pre_comp->numblocks
+            && (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) ==
+                0)) {
+            blocksize = pre_comp->blocksize;
+
+            /*
+             * determine maximum number of blocks that wNAF splitting may
+             * yield (NB: maximum wNAF length is bit length plus one)
+             */
+            numblocks = (BN_num_bits(scalar) / blocksize) + 1;
+
+            /*
+             * we cannot use more blocks than we have precomputation for
+             */
+            if (numblocks > pre_comp->numblocks)
+                numblocks = pre_comp->numblocks;
+
+            pre_points_per_block = (size_t)1 << (pre_comp->w - 1);
+
+            /* check that pre_comp looks sane */
+            if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) {
+                ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+                goto err;
+            }
+        } else {
+            /* can't use precomputation */
+            pre_comp = NULL;
+            numblocks = 1;
+            num_scalar = 1;     /* treat 'scalar' like 'num'-th element of
+                                 * 'scalars' */
+        }
+    }
+
+    totalnum = num + numblocks;
+
+    wsize = OPENSSL_malloc(totalnum * sizeof wsize[0]);
+    wNAF_len = OPENSSL_malloc(totalnum * sizeof wNAF_len[0]);
+    wNAF = OPENSSL_malloc((totalnum + 1) * sizeof wNAF[0]); /* includes space
+                                                             * for pivot */
+    val_sub = OPENSSL_malloc(totalnum * sizeof val_sub[0]);
+
+    /* Ensure wNAF is initialised in case we end up going to err */
+    if (wNAF != NULL)
+        wNAF[0] = NULL;         /* preliminary pivot */
+
+    if (wsize == NULL || wNAF_len == NULL || wNAF == NULL || val_sub == NULL) {
+        ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    /*
+     * num_val will be the total number of temporarily precomputed points
+     */
+    num_val = 0;
+
+    for (i = 0; i < num + num_scalar; i++) {
+        size_t bits;
+
+        bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar);
+        wsize[i] = EC_window_bits_for_scalar_size(bits);
+        num_val += (size_t)1 << (wsize[i] - 1);
+        wNAF[i + 1] = NULL;     /* make sure we always have a pivot */
+        wNAF[i] =
+            bn_compute_wNAF((i < num ? scalars[i] : scalar), wsize[i],
+                            &wNAF_len[i]);
+        if (wNAF[i] == NULL)
+            goto err;
+        if (wNAF_len[i] > max_len)
+            max_len = wNAF_len[i];
+    }
+
+    if (numblocks) {
+        /* we go here iff scalar != NULL */
+
+        if (pre_comp == NULL) {
+            if (num_scalar != 1) {
+                ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+                goto err;
+            }
+            /* we have already generated a wNAF for 'scalar' */
+        } else {
+            signed char *tmp_wNAF = NULL;
+            size_t tmp_len = 0;
+
+            if (num_scalar != 0) {
+                ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+                goto err;
+            }
+
+            /*
+             * use the window size for which we have precomputation
+             */
+            wsize[num] = pre_comp->w;
+            tmp_wNAF = bn_compute_wNAF(scalar, wsize[num], &tmp_len);
+            if (!tmp_wNAF)
+                goto err;
+
+            if (tmp_len <= max_len) {
+                /*
+                 * One of the other wNAFs is at least as long as the wNAF
+                 * belonging to the generator, so wNAF splitting will not buy
+                 * us anything.
+                 */
+
+                numblocks = 1;
+                totalnum = num + 1; /* don't use wNAF splitting */
+                wNAF[num] = tmp_wNAF;
+                wNAF[num + 1] = NULL;
+                wNAF_len[num] = tmp_len;
+                /*
+                 * pre_comp->points starts with the points that we need here:
+                 */
+                val_sub[num] = pre_comp->points;
+            } else {
+                /*
+                 * don't include tmp_wNAF directly into wNAF array - use wNAF
+                 * splitting and include the blocks
+                 */
+
+                signed char *pp;
+                EC_POINT **tmp_points;
+
+                if (tmp_len < numblocks * blocksize) {
+                    /*
+                     * possibly we can do with fewer blocks than estimated
+                     */
+                    numblocks = (tmp_len + blocksize - 1) / blocksize;
+                    if (numblocks > pre_comp->numblocks) {
+                        ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+                        OPENSSL_free(tmp_wNAF);
+                        goto err;
+                    }
+                    totalnum = num + numblocks;
+                }
+
+                /* split wNAF in 'numblocks' parts */
+                pp = tmp_wNAF;
+                tmp_points = pre_comp->points;
+
+                for (i = num; i < totalnum; i++) {
+                    if (i < totalnum - 1) {
+                        wNAF_len[i] = blocksize;
+                        if (tmp_len < blocksize) {
+                            ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+                            OPENSSL_free(tmp_wNAF);
+                            goto err;
+                        }
+                        tmp_len -= blocksize;
+                    } else
+                        /*
+                         * last block gets whatever is left (this could be
+                         * more or less than 'blocksize'!)
+                         */
+                        wNAF_len[i] = tmp_len;
+
+                    wNAF[i + 1] = NULL;
+                    wNAF[i] = OPENSSL_malloc(wNAF_len[i]);
+                    if (wNAF[i] == NULL) {
+                        ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
+                        OPENSSL_free(tmp_wNAF);
+                        goto err;
+                    }
+                    memcpy(wNAF[i], pp, wNAF_len[i]);
+                    if (wNAF_len[i] > max_len)
+                        max_len = wNAF_len[i];
+
+                    if (*tmp_points == NULL) {
+                        ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+                        OPENSSL_free(tmp_wNAF);
+                        goto err;
+                    }
+                    val_sub[i] = tmp_points;
+                    tmp_points += pre_points_per_block;
+                    pp += blocksize;
+                }
+                OPENSSL_free(tmp_wNAF);
+            }
+        }
+    }
+
+    /*
+     * All points we precompute now go into a single array 'val'.
+     * 'val_sub[i]' is a pointer to the subarray for the i-th point, or to a
+     * subarray of 'pre_comp->points' if we already have precomputation.
+     */
+    val = OPENSSL_malloc((num_val + 1) * sizeof val[0]);
+    if (val == NULL) {
+        ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    val[num_val] = NULL;        /* pivot element */
+
+    /* allocate points for precomputation */
+    v = val;
+    for (i = 0; i < num + num_scalar; i++) {
+        val_sub[i] = v;
+        for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++) {
+            *v = EC_POINT_new(group);
+            if (*v == NULL)
+                goto err;
+            v++;
+        }
+    }
+    if (!(v == val + num_val)) {
+        ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
+    if ((tmp = EC_POINT_new(group)) == NULL)
+        goto err;
+
+    /*-
+     * prepare precomputed values:
+     *    val_sub[i][0] :=     points[i]
+     *    val_sub[i][1] := 3 * points[i]
+     *    val_sub[i][2] := 5 * points[i]
+     *    ...
+     */
+    for (i = 0; i < num + num_scalar; i++) {
+        if (i < num) {
+            if (!EC_POINT_copy(val_sub[i][0], points[i]))
+                goto err;
+        } else {
+            if (!EC_POINT_copy(val_sub[i][0], generator))
+                goto err;
+        }
+
+        if (wsize[i] > 1) {
+            if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx))
+                goto err;
+            for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++) {
+                if (!EC_POINT_add
+                    (group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx))
+                    goto err;
+            }
+        }
+    }
+
+    if (!EC_POINTs_make_affine(group, num_val, val, ctx))
+        goto err;
+
+    r_is_at_infinity = 1;
+
+    for (k = max_len - 1; k >= 0; k--) {
+        if (!r_is_at_infinity) {
+            if (!EC_POINT_dbl(group, r, r, ctx))
+                goto err;
+        }
+
+        for (i = 0; i < totalnum; i++) {
+            if (wNAF_len[i] > (size_t)k) {
+                int digit = wNAF[i][k];
+                int is_neg;
+
+                if (digit) {
+                    is_neg = digit < 0;
+
+                    if (is_neg)
+                        digit = -digit;
+
+                    if (is_neg != r_is_inverted) {
+                        if (!r_is_at_infinity) {
+                            if (!EC_POINT_invert(group, r, ctx))
+                                goto err;
+                        }
+                        r_is_inverted = !r_is_inverted;
+                    }
+
+                    /* digit > 0 */
+
+                    if (r_is_at_infinity) {
+                        if (!EC_POINT_copy(r, val_sub[i][digit >> 1]))
+                            goto err;
+                        r_is_at_infinity = 0;
+                    } else {
+                        if (!EC_POINT_add
+                            (group, r, r, val_sub[i][digit >> 1], ctx))
+                            goto err;
+                    }
+                }
+            }
+        }
+    }
+
+    if (r_is_at_infinity) {
+        if (!EC_POINT_set_to_infinity(group, r))
+            goto err;
+    } else {
+        if (r_is_inverted)
+            if (!EC_POINT_invert(group, r, ctx))
+                goto err;
+    }
+
+    ret = 1;
+
+ err:
+    BN_CTX_free(new_ctx);
+    EC_POINT_free(tmp);
+    OPENSSL_free(wsize);
+    OPENSSL_free(wNAF_len);
+    if (wNAF != NULL) {
+        signed char **w;
+
+        for (w = wNAF; *w != NULL; w++)
+            OPENSSL_free(*w);
+
+        OPENSSL_free(wNAF);
+    }
+    if (val != NULL) {
+        for (v = val; *v != NULL; v++)
+            EC_POINT_clear_free(*v);
+
+        OPENSSL_free(val);
+    }
+    OPENSSL_free(val_sub);
+    return ret;
+}
+
+/*-
+ * ec_wNAF_precompute_mult()
+ * creates an EC_PRE_COMP object with preprecomputed multiples of the generator
+ * for use with wNAF splitting as implemented in ec_wNAF_mul().
+ *
+ * 'pre_comp->points' is an array of multiples of the generator
+ * of the following form:
+ * points[0] =     generator;
+ * points[1] = 3 * generator;
+ * ...
+ * points[2^(w-1)-1] =     (2^(w-1)-1) * generator;
+ * points[2^(w-1)]   =     2^blocksize * generator;
+ * points[2^(w-1)+1] = 3 * 2^blocksize * generator;
+ * ...
+ * points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) *  2^(blocksize*(numblocks-2)) * generator
+ * points[2^(w-1)*(numblocks-1)]   =              2^(blocksize*(numblocks-1)) * generator
+ * ...
+ * points[2^(w-1)*numblocks-1]     = (2^(w-1)) *  2^(blocksize*(numblocks-1)) * generator
+ * points[2^(w-1)*numblocks]       = NULL
+ */
+int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+{
+    const EC_POINT *generator;
+    EC_POINT *tmp_point = NULL, *base = NULL, **var;
+    BN_CTX *new_ctx = NULL;
+    const BIGNUM *order;
+    size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num;
+    EC_POINT **points = NULL;
+    EC_PRE_COMP *pre_comp;
+    int ret = 0;
+
+    /* if there is an old EC_PRE_COMP object, throw it away */
+    EC_pre_comp_free(group);
+    if ((pre_comp = ec_pre_comp_new(group)) == NULL)
+        return 0;
+
+    generator = EC_GROUP_get0_generator(group);
+    if (generator == NULL) {
+        ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR);
+        goto err;
+    }
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            goto err;
+    }
+
+    BN_CTX_start(ctx);
+
+    order = EC_GROUP_get0_order(group);
+    if (order == NULL)
+        goto err;
+    if (BN_is_zero(order)) {
+        ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER);
+        goto err;
+    }
+
+    bits = BN_num_bits(order);
+    /*
+     * The following parameters mean we precompute (approximately) one point
+     * per bit. TBD: The combination 8, 4 is perfect for 160 bits; for other
+     * bit lengths, other parameter combinations might provide better
+     * efficiency.
+     */
+    blocksize = 8;
+    w = 4;
+    if (EC_window_bits_for_scalar_size(bits) > w) {
+        /* let's not make the window too small ... */
+        w = EC_window_bits_for_scalar_size(bits);
+    }
+
+    numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks
+                                                     * to use for wNAF
+                                                     * splitting */
+
+    pre_points_per_block = (size_t)1 << (w - 1);
+    num = pre_points_per_block * numblocks; /* number of points to compute
+                                             * and store */
+
+    points = OPENSSL_malloc(sizeof(*points) * (num + 1));
+    if (points == NULL) {
+        ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    var = points;
+    var[num] = NULL;            /* pivot */
+    for (i = 0; i < num; i++) {
+        if ((var[i] = EC_POINT_new(group)) == NULL) {
+            ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    }
+
+    if ((tmp_point = EC_POINT_new(group)) == NULL
+        || (base = EC_POINT_new(group)) == NULL) {
+        ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (!EC_POINT_copy(base, generator))
+        goto err;
+
+    /* do the precomputation */
+    for (i = 0; i < numblocks; i++) {
+        size_t j;
+
+        if (!EC_POINT_dbl(group, tmp_point, base, ctx))
+            goto err;
+
+        if (!EC_POINT_copy(*var++, base))
+            goto err;
+
+        for (j = 1; j < pre_points_per_block; j++, var++) {
+            /*
+             * calculate odd multiples of the current base point
+             */
+            if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx))
+                goto err;
+        }
+
+        if (i < numblocks - 1) {
+            /*
+             * get the next base (multiply current one by 2^blocksize)
+             */
+            size_t k;
+
+            if (blocksize <= 2) {
+                ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_INTERNAL_ERROR);
+                goto err;
+            }
+
+            if (!EC_POINT_dbl(group, base, tmp_point, ctx))
+                goto err;
+            for (k = 2; k < blocksize; k++) {
+                if (!EC_POINT_dbl(group, base, base, ctx))
+                    goto err;
+            }
+        }
+    }
+
+    if (!EC_POINTs_make_affine(group, num, points, ctx))
+        goto err;
+
+    pre_comp->group = group;
+    pre_comp->blocksize = blocksize;
+    pre_comp->numblocks = numblocks;
+    pre_comp->w = w;
+    pre_comp->points = points;
+    points = NULL;
+    pre_comp->num = num;
+    SETPRECOMP(group, ec, pre_comp);
+    pre_comp = NULL;
+    ret = 1;
+
+ err:
+    if (ctx != NULL)
+        BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    EC_ec_pre_comp_free(pre_comp);
+    if (points) {
+        EC_POINT **p;
+
+        for (p = points; *p != NULL; p++)
+            EC_POINT_free(*p);
+        OPENSSL_free(points);
+    }
+    EC_POINT_free(tmp_point);
+    EC_POINT_free(base);
+    return ret;
+}
+
+int ec_wNAF_have_precompute_mult(const EC_GROUP *group)
+{
+    return HAVEPRECOMP(group, ec);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_oct.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_oct.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_oct.c	(revision 331)
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2011-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Binary polynomial ECC support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include <string.h>
+
+#include <openssl/err.h>
+#include <openssl/opensslv.h>
+
+#include "ec_lcl.h"
+
+int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
+                                            EC_POINT *point, const BIGNUM *x,
+                                            int y_bit, BN_CTX *ctx)
+{
+    if (group->meth->point_set_compressed_coordinates == 0
+        && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
+        ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP,
+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    if (group->meth != point->meth) {
+        ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP,
+              EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
+    if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
+        if (group->meth->field_type == NID_X9_62_prime_field)
+            return ec_GFp_simple_set_compressed_coordinates(group, point, x,
+                                                            y_bit, ctx);
+        else
+#ifdef OPENSSL_NO_EC2M
+        {
+            ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP,
+                  EC_R_GF2M_NOT_SUPPORTED);
+            return 0;
+        }
+#else
+            return ec_GF2m_simple_set_compressed_coordinates(group, point, x,
+                                                             y_bit, ctx);
+#endif
+    }
+    return group->meth->point_set_compressed_coordinates(group, point, x,
+                                                         y_bit, ctx);
+}
+
+#ifndef OPENSSL_NO_EC2M
+int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group,
+                                             EC_POINT *point, const BIGNUM *x,
+                                             int y_bit, BN_CTX *ctx)
+{
+    if (group->meth->point_set_compressed_coordinates == 0
+        && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
+        ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M,
+              ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    if (group->meth != point->meth) {
+        ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M,
+              EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
+    if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
+        if (group->meth->field_type == NID_X9_62_prime_field)
+            return ec_GFp_simple_set_compressed_coordinates(group, point, x,
+                                                            y_bit, ctx);
+        else
+            return ec_GF2m_simple_set_compressed_coordinates(group, point, x,
+                                                             y_bit, ctx);
+    }
+    return group->meth->point_set_compressed_coordinates(group, point, x,
+                                                         y_bit, ctx);
+}
+#endif
+
+size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point,
+                          point_conversion_form_t form, unsigned char *buf,
+                          size_t len, BN_CTX *ctx)
+{
+    if (group->meth->point2oct == 0
+        && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
+        ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    if (group->meth != point->meth) {
+        ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
+    if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
+        if (group->meth->field_type == NID_X9_62_prime_field)
+            return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx);
+        else
+#ifdef OPENSSL_NO_EC2M
+        {
+            ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_GF2M_NOT_SUPPORTED);
+            return 0;
+        }
+#else
+            return ec_GF2m_simple_point2oct(group, point,
+                                            form, buf, len, ctx);
+#endif
+    }
+
+    return group->meth->point2oct(group, point, form, buf, len, ctx);
+}
+
+int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
+                       const unsigned char *buf, size_t len, BN_CTX *ctx)
+{
+    if (group->meth->oct2point == 0
+        && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
+        ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        return 0;
+    }
+    if (group->meth != point->meth) {
+        ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS);
+        return 0;
+    }
+    if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
+        if (group->meth->field_type == NID_X9_62_prime_field)
+            return ec_GFp_simple_oct2point(group, point, buf, len, ctx);
+        else
+#ifdef OPENSSL_NO_EC2M
+        {
+            ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_GF2M_NOT_SUPPORTED);
+            return 0;
+        }
+#else
+            return ec_GF2m_simple_oct2point(group, point, buf, len, ctx);
+#endif
+    }
+    return group->meth->oct2point(group, point, buf, len, ctx);
+}
+
+size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point,
+                          point_conversion_form_t form,
+                          unsigned char **pbuf, BN_CTX *ctx)
+{
+    size_t len;
+    unsigned char *buf;
+    len = EC_POINT_point2oct(group, point, form, NULL, 0, NULL);
+    if (len == 0)
+        return 0;
+    buf = OPENSSL_malloc(len);
+    if (buf == NULL)
+        return 0;
+    len = EC_POINT_point2oct(group, point, form, buf, len, ctx);
+    if (len == 0) {
+        OPENSSL_free(buf);
+        return 0;
+    }
+    *pbuf = buf;
+    return len;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_pmeth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_pmeth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_pmeth.c	(revision 331)
@@ -0,0 +1,463 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/ec.h>
+#include "ec_lcl.h"
+#include <openssl/evp.h>
+#include "internal/evp_int.h"
+
+/* EC pkey context structure */
+
+typedef struct {
+    /* Key and paramgen group */
+    EC_GROUP *gen_group;
+    /* message digest */
+    const EVP_MD *md;
+    /* Duplicate key if custom cofactor needed */
+    EC_KEY *co_key;
+    /* Cofactor mode */
+    signed char cofactor_mode;
+    /* KDF (if any) to use for ECDH */
+    char kdf_type;
+    /* Message digest to use for key derivation */
+    const EVP_MD *kdf_md;
+    /* User key material */
+    unsigned char *kdf_ukm;
+    size_t kdf_ukmlen;
+    /* KDF output length */
+    size_t kdf_outlen;
+} EC_PKEY_CTX;
+
+static int pkey_ec_init(EVP_PKEY_CTX *ctx)
+{
+    EC_PKEY_CTX *dctx;
+
+    dctx = OPENSSL_zalloc(sizeof(*dctx));
+    if (dctx == NULL)
+        return 0;
+
+    dctx->cofactor_mode = -1;
+    dctx->kdf_type = EVP_PKEY_ECDH_KDF_NONE;
+    ctx->data = dctx;
+    return 1;
+}
+
+static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+{
+    EC_PKEY_CTX *dctx, *sctx;
+    if (!pkey_ec_init(dst))
+        return 0;
+    sctx = src->data;
+    dctx = dst->data;
+    if (sctx->gen_group) {
+        dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
+        if (!dctx->gen_group)
+            return 0;
+    }
+    dctx->md = sctx->md;
+
+    if (sctx->co_key) {
+        dctx->co_key = EC_KEY_dup(sctx->co_key);
+        if (!dctx->co_key)
+            return 0;
+    }
+    dctx->kdf_type = sctx->kdf_type;
+    dctx->kdf_md = sctx->kdf_md;
+    dctx->kdf_outlen = sctx->kdf_outlen;
+    if (sctx->kdf_ukm) {
+        dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
+        if (!dctx->kdf_ukm)
+            return 0;
+    } else
+        dctx->kdf_ukm = NULL;
+    dctx->kdf_ukmlen = sctx->kdf_ukmlen;
+    return 1;
+}
+
+static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx)
+{
+    EC_PKEY_CTX *dctx = ctx->data;
+    if (dctx) {
+        EC_GROUP_free(dctx->gen_group);
+        EC_KEY_free(dctx->co_key);
+        OPENSSL_free(dctx->kdf_ukm);
+        OPENSSL_free(dctx);
+    }
+}
+
+static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+                        const unsigned char *tbs, size_t tbslen)
+{
+    int ret, type;
+    unsigned int sltmp;
+    EC_PKEY_CTX *dctx = ctx->data;
+    EC_KEY *ec = ctx->pkey->pkey.ec;
+
+    if (!sig) {
+        *siglen = ECDSA_size(ec);
+        return 1;
+    } else if (*siglen < (size_t)ECDSA_size(ec)) {
+        ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL);
+        return 0;
+    }
+
+    if (dctx->md)
+        type = EVP_MD_type(dctx->md);
+    else
+        type = NID_sha1;
+
+    ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
+
+    if (ret <= 0)
+        return ret;
+    *siglen = (size_t)sltmp;
+    return 1;
+}
+
+static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
+                          const unsigned char *sig, size_t siglen,
+                          const unsigned char *tbs, size_t tbslen)
+{
+    int ret, type;
+    EC_PKEY_CTX *dctx = ctx->data;
+    EC_KEY *ec = ctx->pkey->pkey.ec;
+
+    if (dctx->md)
+        type = EVP_MD_type(dctx->md);
+    else
+        type = NID_sha1;
+
+    ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
+
+    return ret;
+}
+
+#ifndef OPENSSL_NO_EC
+static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
+                          size_t *keylen)
+{
+    int ret;
+    size_t outlen;
+    const EC_POINT *pubkey = NULL;
+    EC_KEY *eckey;
+    EC_PKEY_CTX *dctx = ctx->data;
+    if (!ctx->pkey || !ctx->peerkey) {
+        ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET);
+        return 0;
+    }
+
+    eckey = dctx->co_key ? dctx->co_key : ctx->pkey->pkey.ec;
+
+    if (!key) {
+        const EC_GROUP *group;
+        group = EC_KEY_get0_group(eckey);
+        *keylen = (EC_GROUP_get_degree(group) + 7) / 8;
+        return 1;
+    }
+    pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
+
+    /*
+     * NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is not
+     * an error, the result is truncated.
+     */
+
+    outlen = *keylen;
+
+    ret = ECDH_compute_key(key, outlen, pubkey, eckey, 0);
+    if (ret <= 0)
+        return 0;
+    *keylen = ret;
+    return 1;
+}
+
+static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx,
+                              unsigned char *key, size_t *keylen)
+{
+    EC_PKEY_CTX *dctx = ctx->data;
+    unsigned char *ktmp = NULL;
+    size_t ktmplen;
+    int rv = 0;
+    if (dctx->kdf_type == EVP_PKEY_ECDH_KDF_NONE)
+        return pkey_ec_derive(ctx, key, keylen);
+    if (!key) {
+        *keylen = dctx->kdf_outlen;
+        return 1;
+    }
+    if (*keylen != dctx->kdf_outlen)
+        return 0;
+    if (!pkey_ec_derive(ctx, NULL, &ktmplen))
+        return 0;
+    ktmp = OPENSSL_malloc(ktmplen);
+    if (ktmp == NULL)
+        return 0;
+    if (!pkey_ec_derive(ctx, ktmp, &ktmplen))
+        goto err;
+    /* Do KDF stuff */
+    if (!ECDH_KDF_X9_62(key, *keylen, ktmp, ktmplen,
+                        dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
+        goto err;
+    rv = 1;
+
+ err:
+    OPENSSL_clear_free(ktmp, ktmplen);
+    return rv;
+}
+#endif
+
+static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+    EC_PKEY_CTX *dctx = ctx->data;
+    EC_GROUP *group;
+    switch (type) {
+    case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
+        group = EC_GROUP_new_by_curve_name(p1);
+        if (group == NULL) {
+            ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE);
+            return 0;
+        }
+        EC_GROUP_free(dctx->gen_group);
+        dctx->gen_group = group;
+        return 1;
+
+    case EVP_PKEY_CTRL_EC_PARAM_ENC:
+        if (!dctx->gen_group) {
+            ECerr(EC_F_PKEY_EC_CTRL, EC_R_NO_PARAMETERS_SET);
+            return 0;
+        }
+        EC_GROUP_set_asn1_flag(dctx->gen_group, p1);
+        return 1;
+
+#ifndef OPENSSL_NO_EC
+    case EVP_PKEY_CTRL_EC_ECDH_COFACTOR:
+        if (p1 == -2) {
+            if (dctx->cofactor_mode != -1)
+                return dctx->cofactor_mode;
+            else {
+                EC_KEY *ec_key = ctx->pkey->pkey.ec;
+                return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 :
+                    0;
+            }
+        } else if (p1 < -1 || p1 > 1)
+            return -2;
+        dctx->cofactor_mode = p1;
+        if (p1 != -1) {
+            EC_KEY *ec_key = ctx->pkey->pkey.ec;
+            if (!ec_key->group)
+                return -2;
+            /* If cofactor is 1 cofactor mode does nothing */
+            if (BN_is_one(ec_key->group->cofactor))
+                return 1;
+            if (!dctx->co_key) {
+                dctx->co_key = EC_KEY_dup(ec_key);
+                if (!dctx->co_key)
+                    return 0;
+            }
+            if (p1)
+                EC_KEY_set_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH);
+            else
+                EC_KEY_clear_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH);
+        } else {
+            EC_KEY_free(dctx->co_key);
+            dctx->co_key = NULL;
+        }
+        return 1;
+#endif
+
+    case EVP_PKEY_CTRL_EC_KDF_TYPE:
+        if (p1 == -2)
+            return dctx->kdf_type;
+        if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_62)
+            return -2;
+        dctx->kdf_type = p1;
+        return 1;
+
+    case EVP_PKEY_CTRL_EC_KDF_MD:
+        dctx->kdf_md = p2;
+        return 1;
+
+    case EVP_PKEY_CTRL_GET_EC_KDF_MD:
+        *(const EVP_MD **)p2 = dctx->kdf_md;
+        return 1;
+
+    case EVP_PKEY_CTRL_EC_KDF_OUTLEN:
+        if (p1 <= 0)
+            return -2;
+        dctx->kdf_outlen = (size_t)p1;
+        return 1;
+
+    case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN:
+        *(int *)p2 = dctx->kdf_outlen;
+        return 1;
+
+    case EVP_PKEY_CTRL_EC_KDF_UKM:
+        OPENSSL_free(dctx->kdf_ukm);
+        dctx->kdf_ukm = p2;
+        if (p2)
+            dctx->kdf_ukmlen = p1;
+        else
+            dctx->kdf_ukmlen = 0;
+        return 1;
+
+    case EVP_PKEY_CTRL_GET_EC_KDF_UKM:
+        *(unsigned char **)p2 = dctx->kdf_ukm;
+        return dctx->kdf_ukmlen;
+
+    case EVP_PKEY_CTRL_MD:
+        if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
+            EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 &&
+            EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
+            EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
+            EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
+            EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
+            ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
+            return 0;
+        }
+        dctx->md = p2;
+        return 1;
+
+    case EVP_PKEY_CTRL_GET_MD:
+        *(const EVP_MD **)p2 = dctx->md;
+        return 1;
+
+    case EVP_PKEY_CTRL_PEER_KEY:
+        /* Default behaviour is OK */
+    case EVP_PKEY_CTRL_DIGESTINIT:
+    case EVP_PKEY_CTRL_PKCS7_SIGN:
+    case EVP_PKEY_CTRL_CMS_SIGN:
+        return 1;
+
+    default:
+        return -2;
+
+    }
+}
+
+static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
+                            const char *type, const char *value)
+{
+    if (strcmp(type, "ec_paramgen_curve") == 0) {
+        int nid;
+        nid = EC_curve_nist2nid(value);
+        if (nid == NID_undef)
+            nid = OBJ_sn2nid(value);
+        if (nid == NID_undef)
+            nid = OBJ_ln2nid(value);
+        if (nid == NID_undef) {
+            ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE);
+            return 0;
+        }
+        return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
+    } else if (strcmp(type, "ec_param_enc") == 0) {
+        int param_enc;
+        if (strcmp(value, "explicit") == 0)
+            param_enc = 0;
+        else if (strcmp(value, "named_curve") == 0)
+            param_enc = OPENSSL_EC_NAMED_CURVE;
+        else
+            return -2;
+        return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc);
+    } else if (strcmp(type, "ecdh_kdf_md") == 0) {
+        const EVP_MD *md;
+        if ((md = EVP_get_digestbyname(value)) == NULL) {
+            ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_DIGEST);
+            return 0;
+        }
+        return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md);
+    } else if (strcmp(type, "ecdh_cofactor_mode") == 0) {
+        int co_mode;
+        co_mode = atoi(value);
+        return EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, co_mode);
+    }
+
+    return -2;
+}
+
+static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+    EC_KEY *ec = NULL;
+    EC_PKEY_CTX *dctx = ctx->data;
+    int ret = 0;
+    if (dctx->gen_group == NULL) {
+        ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET);
+        return 0;
+    }
+    ec = EC_KEY_new();
+    if (ec == NULL)
+        return 0;
+    ret = EC_KEY_set_group(ec, dctx->gen_group);
+    if (ret)
+        EVP_PKEY_assign_EC_KEY(pkey, ec);
+    else
+        EC_KEY_free(ec);
+    return ret;
+}
+
+static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+    EC_KEY *ec = NULL;
+    EC_PKEY_CTX *dctx = ctx->data;
+    if (ctx->pkey == NULL && dctx->gen_group == NULL) {
+        ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
+        return 0;
+    }
+    ec = EC_KEY_new();
+    if (!ec)
+        return 0;
+    EVP_PKEY_assign_EC_KEY(pkey, ec);
+    if (ctx->pkey) {
+        /* Note: if error return, pkey is freed by parent routine */
+        if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
+            return 0;
+    } else {
+        if (!EC_KEY_set_group(ec, dctx->gen_group))
+            return 0;
+    }
+    return EC_KEY_generate_key(pkey->pkey.ec);
+}
+
+const EVP_PKEY_METHOD ec_pkey_meth = {
+    EVP_PKEY_EC,
+    0,
+    pkey_ec_init,
+    pkey_ec_copy,
+    pkey_ec_cleanup,
+
+    0,
+    pkey_ec_paramgen,
+
+    0,
+    pkey_ec_keygen,
+
+    0,
+    pkey_ec_sign,
+
+    0,
+    pkey_ec_verify,
+
+    0, 0,
+
+    0, 0, 0, 0,
+
+    0, 0,
+
+    0, 0,
+
+    0,
+#ifndef OPENSSL_NO_EC
+    pkey_ec_kdf_derive,
+#else
+    0,
+#endif
+    pkey_ec_ctrl,
+    pkey_ec_ctrl_str
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_print.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_print.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ec_print.c	(revision 331)
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2002-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 <openssl/crypto.h>
+#include "ec_lcl.h"
+
+BIGNUM *EC_POINT_point2bn(const EC_GROUP *group,
+                          const EC_POINT *point,
+                          point_conversion_form_t form,
+                          BIGNUM *ret, BN_CTX *ctx)
+{
+    size_t buf_len = 0;
+    unsigned char *buf;
+
+    buf_len = EC_POINT_point2buf(group, point, form, &buf, ctx);
+
+    if (buf_len == 0)
+        return NULL;
+
+    ret = BN_bin2bn(buf, buf_len, ret);
+
+    OPENSSL_free(buf);
+
+    return ret;
+}
+
+EC_POINT *EC_POINT_bn2point(const EC_GROUP *group,
+                            const BIGNUM *bn, EC_POINT *point, BN_CTX *ctx)
+{
+    size_t buf_len = 0;
+    unsigned char *buf;
+    EC_POINT *ret;
+
+    if ((buf_len = BN_num_bytes(bn)) == 0)
+        return NULL;
+    buf = OPENSSL_malloc(buf_len);
+    if (buf == NULL)
+        return NULL;
+
+    if (!BN_bn2bin(bn, buf)) {
+        OPENSSL_free(buf);
+        return NULL;
+    }
+
+    if (point == NULL) {
+        if ((ret = EC_POINT_new(group)) == NULL) {
+            OPENSSL_free(buf);
+            return NULL;
+        }
+    } else
+        ret = point;
+
+    if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx)) {
+        if (ret != point)
+            EC_POINT_clear_free(ret);
+        OPENSSL_free(buf);
+        return NULL;
+    }
+
+    OPENSSL_free(buf);
+    return ret;
+}
+
+static const char *HEX_DIGITS = "0123456789ABCDEF";
+
+/* the return value must be freed (using OPENSSL_free()) */
+char *EC_POINT_point2hex(const EC_GROUP *group,
+                         const EC_POINT *point,
+                         point_conversion_form_t form, BN_CTX *ctx)
+{
+    char *ret, *p;
+    size_t buf_len = 0, i;
+    unsigned char *buf = NULL, *pbuf;
+
+    buf_len = EC_POINT_point2buf(group, point, form, &buf, ctx);
+
+    if (buf_len == 0)
+        return NULL;
+
+    ret = OPENSSL_malloc(buf_len * 2 + 2);
+    if (ret == NULL) {
+        OPENSSL_free(buf);
+        return NULL;
+    }
+    p = ret;
+    pbuf = buf;
+    for (i = buf_len; i > 0; i--) {
+        int v = (int)*(pbuf++);
+        *(p++) = HEX_DIGITS[v >> 4];
+        *(p++) = HEX_DIGITS[v & 0x0F];
+    }
+    *p = '\0';
+
+    OPENSSL_free(buf);
+
+    return ret;
+}
+
+EC_POINT *EC_POINT_hex2point(const EC_GROUP *group,
+                             const char *buf, EC_POINT *point, BN_CTX *ctx)
+{
+    EC_POINT *ret = NULL;
+    BIGNUM *tmp_bn = NULL;
+
+    if (!BN_hex2bn(&tmp_bn, buf))
+        return NULL;
+
+    ret = EC_POINT_bn2point(group, tmp_bn, point, ctx);
+
+    BN_clear_free(tmp_bn);
+
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecdh_kdf.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecdh_kdf.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecdh_kdf.c	(revision 331)
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2015-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 <string.h>
+#include <openssl/ec.h>
+#include <openssl/evp.h>
+
+/* Key derivation function from X9.62/SECG */
+/* Way more than we will ever need */
+#define ECDH_KDF_MAX    (1 << 30)
+
+int ECDH_KDF_X9_62(unsigned char *out, size_t outlen,
+                   const unsigned char *Z, size_t Zlen,
+                   const unsigned char *sinfo, size_t sinfolen,
+                   const EVP_MD *md)
+{
+    EVP_MD_CTX *mctx = NULL;
+    int rv = 0;
+    unsigned int i;
+    size_t mdlen;
+    unsigned char ctr[4];
+    if (sinfolen > ECDH_KDF_MAX || outlen > ECDH_KDF_MAX
+        || Zlen > ECDH_KDF_MAX)
+        return 0;
+    mctx = EVP_MD_CTX_new();
+    if (mctx == NULL)
+        return 0;
+    mdlen = EVP_MD_size(md);
+    for (i = 1;; i++) {
+        unsigned char mtmp[EVP_MAX_MD_SIZE];
+        if (!EVP_DigestInit_ex(mctx, md, NULL))
+            goto err;
+        ctr[3] = i & 0xFF;
+        ctr[2] = (i >> 8) & 0xFF;
+        ctr[1] = (i >> 16) & 0xFF;
+        ctr[0] = (i >> 24) & 0xFF;
+        if (!EVP_DigestUpdate(mctx, Z, Zlen))
+            goto err;
+        if (!EVP_DigestUpdate(mctx, ctr, sizeof(ctr)))
+            goto err;
+        if (!EVP_DigestUpdate(mctx, sinfo, sinfolen))
+            goto err;
+        if (outlen >= mdlen) {
+            if (!EVP_DigestFinal(mctx, out, NULL))
+                goto err;
+            outlen -= mdlen;
+            if (outlen == 0)
+                break;
+            out += mdlen;
+        } else {
+            if (!EVP_DigestFinal(mctx, mtmp, NULL))
+                goto err;
+            memcpy(out, mtmp, outlen);
+            OPENSSL_cleanse(mtmp, mdlen);
+            break;
+        }
+    }
+    rv = 1;
+ err:
+    EVP_MD_CTX_free(mctx);
+    return rv;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecdh_ossl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecdh_ossl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecdh_ossl.c	(revision 331)
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2002-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The ECDH software is originally written by Douglas Stebila of
+ * Sun Microsystems Laboratories.
+ *
+ */
+
+#include <string.h>
+#include <limits.h>
+
+#include "internal/cryptlib.h"
+
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/objects.h>
+#include <openssl/ec.h>
+#include "ec_lcl.h"
+
+int ossl_ecdh_compute_key(unsigned char **psec, size_t *pseclen,
+                          const EC_POINT *pub_key, const EC_KEY *ecdh)
+{
+    if (ecdh->group->meth->ecdh_compute_key == NULL) {
+        ECerr(EC_F_OSSL_ECDH_COMPUTE_KEY, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH);
+        return 0;
+    }
+
+    return ecdh->group->meth->ecdh_compute_key(psec, pseclen, pub_key, ecdh);
+}
+
+/*-
+ * This implementation is based on the following primitives in the IEEE 1363 standard:
+ *  - ECKAS-DH1
+ *  - ECSVDP-DH
+ */
+int ecdh_simple_compute_key(unsigned char **pout, size_t *poutlen,
+                            const EC_POINT *pub_key, const EC_KEY *ecdh)
+{
+    BN_CTX *ctx;
+    EC_POINT *tmp = NULL;
+    BIGNUM *x = NULL, *y = NULL;
+    const BIGNUM *priv_key;
+    const EC_GROUP *group;
+    int ret = 0;
+    size_t buflen, len;
+    unsigned char *buf = NULL;
+
+    if ((ctx = BN_CTX_new()) == NULL)
+        goto err;
+    BN_CTX_start(ctx);
+    x = BN_CTX_get(ctx);
+    y = BN_CTX_get(ctx);
+
+    priv_key = EC_KEY_get0_private_key(ecdh);
+    if (priv_key == NULL) {
+        ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_NO_PRIVATE_VALUE);
+        goto err;
+    }
+
+    group = EC_KEY_get0_group(ecdh);
+
+    if (EC_KEY_get_flags(ecdh) & EC_FLAG_COFACTOR_ECDH) {
+        if (!EC_GROUP_get_cofactor(group, x, NULL) ||
+            !BN_mul(x, x, priv_key, ctx)) {
+            ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        priv_key = x;
+    }
+
+    if ((tmp = EC_POINT_new(group)) == NULL) {
+        ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)) {
+        ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE);
+        goto err;
+    }
+
+    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
+        NID_X9_62_prime_field) {
+        if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx)) {
+            ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE);
+            goto err;
+        }
+    }
+#ifndef OPENSSL_NO_EC2M
+    else {
+        if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx)) {
+            ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, EC_R_POINT_ARITHMETIC_FAILURE);
+            goto err;
+        }
+    }
+#endif
+
+    buflen = (EC_GROUP_get_degree(group) + 7) / 8;
+    len = BN_num_bytes(x);
+    if (len > buflen) {
+        ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+    if ((buf = OPENSSL_malloc(buflen)) == NULL) {
+        ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    memset(buf, 0, buflen - len);
+    if (len != (size_t)BN_bn2bin(x, buf + buflen - len)) {
+        ECerr(EC_F_ECDH_SIMPLE_COMPUTE_KEY, ERR_R_BN_LIB);
+        goto err;
+    }
+
+    *pout = buf;
+    *poutlen = buflen;
+    buf = NULL;
+
+    ret = 1;
+
+ err:
+    EC_POINT_free(tmp);
+    if (ctx)
+        BN_CTX_end(ctx);
+    BN_CTX_free(ctx);
+    OPENSSL_free(buf);
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecdsa_ossl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecdsa_ossl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecdsa_ossl.c	(revision 331)
@@ -0,0 +1,462 @@
+/*
+ * Copyright 2002-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 <string.h>
+#include <openssl/err.h>
+#include <openssl/obj_mac.h>
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#include <openssl/ec.h>
+#include "ec_lcl.h"
+
+int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen,
+                    unsigned char *sig, unsigned int *siglen,
+                    const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey)
+{
+    ECDSA_SIG *s;
+    RAND_seed(dgst, dlen);
+    s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey);
+    if (s == NULL) {
+        *siglen = 0;
+        return 0;
+    }
+    *siglen = i2d_ECDSA_SIG(s, &sig);
+    ECDSA_SIG_free(s);
+    return 1;
+}
+
+static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in,
+                            BIGNUM **kinvp, BIGNUM **rp,
+                            const unsigned char *dgst, int dlen)
+{
+    BN_CTX *ctx = NULL;
+    BIGNUM *k = NULL, *r = NULL, *X = NULL;
+    const BIGNUM *order;
+    EC_POINT *tmp_point = NULL;
+    const EC_GROUP *group;
+    int ret = 0;
+
+    if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
+        ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    if (!EC_KEY_can_sign(eckey)) {
+        ECerr(EC_F_ECDSA_SIGN_SETUP, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
+        return 0;
+    }
+
+    if (ctx_in == NULL) {
+        if ((ctx = BN_CTX_new()) == NULL) {
+            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+    } else
+        ctx = ctx_in;
+
+    k = BN_new();               /* this value is later returned in *kinvp */
+    r = BN_new();               /* this value is later returned in *rp */
+    X = BN_new();
+    if (k == NULL || r == NULL || X == NULL) {
+        ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if ((tmp_point = EC_POINT_new(group)) == NULL) {
+        ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
+        goto err;
+    }
+    order = EC_GROUP_get0_order(group);
+    if (order == NULL) {
+        ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
+        goto err;
+    }
+
+    do {
+        /* get random k */
+        do
+            if (dgst != NULL) {
+                if (!BN_generate_dsa_nonce
+                    (k, order, EC_KEY_get0_private_key(eckey), dgst, dlen,
+                     ctx)) {
+                    ECerr(EC_F_ECDSA_SIGN_SETUP,
+                             EC_R_RANDOM_NUMBER_GENERATION_FAILED);
+                    goto err;
+                }
+            } else {
+                if (!BN_rand_range(k, order)) {
+                    ECerr(EC_F_ECDSA_SIGN_SETUP,
+                             EC_R_RANDOM_NUMBER_GENERATION_FAILED);
+                    goto err;
+                }
+            }
+        while (BN_is_zero(k));
+
+        /*
+         * We do not want timing information to leak the length of k, so we
+         * compute G*k using an equivalent scalar of fixed bit-length.
+         */
+
+        if (!BN_add(k, k, order))
+            goto err;
+        if (BN_num_bits(k) <= BN_num_bits(order))
+            if (!BN_add(k, k, order))
+                goto err;
+
+        /* compute r the x-coordinate of generator * k */
+        if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
+            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
+            goto err;
+        }
+        if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
+            NID_X9_62_prime_field) {
+            if (!EC_POINT_get_affine_coordinates_GFp
+                (group, tmp_point, X, NULL, ctx)) {
+                ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
+                goto err;
+            }
+        }
+#ifndef OPENSSL_NO_EC2M
+        else {                  /* NID_X9_62_characteristic_two_field */
+
+            if (!EC_POINT_get_affine_coordinates_GF2m(group,
+                                                      tmp_point, X, NULL,
+                                                      ctx)) {
+                ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
+                goto err;
+            }
+        }
+#endif
+        if (!BN_nnmod(r, X, order, ctx)) {
+            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
+            goto err;
+        }
+    }
+    while (BN_is_zero(r));
+
+    /* compute the inverse of k */
+    if (EC_GROUP_get_mont_data(group) != NULL) {
+        /*
+         * We want inverse in constant time, therefore we utilize the fact
+         * order must be prime and use Fermats Little Theorem instead.
+         */
+        if (!BN_set_word(X, 2)) {
+            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
+            goto err;
+        }
+        if (!BN_mod_sub(X, order, X, order, ctx)) {
+            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
+            goto err;
+        }
+        BN_set_flags(X, BN_FLG_CONSTTIME);
+        if (!BN_mod_exp_mont_consttime
+            (k, k, X, order, ctx, EC_GROUP_get_mont_data(group))) {
+            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
+            goto err;
+        }
+    } else {
+        if (!BN_mod_inverse(k, k, order, ctx)) {
+            ECerr(EC_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
+            goto err;
+        }
+    }
+
+    /* clear old values if necessary */
+    BN_clear_free(*rp);
+    BN_clear_free(*kinvp);
+    /* save the pre-computed values  */
+    *rp = r;
+    *kinvp = k;
+    ret = 1;
+ err:
+    if (!ret) {
+        BN_clear_free(k);
+        BN_clear_free(r);
+    }
+    if (ctx != ctx_in)
+        BN_CTX_free(ctx);
+    EC_POINT_free(tmp_point);
+    BN_clear_free(X);
+    return (ret);
+}
+
+int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
+                          BIGNUM **rp)
+{
+    return ecdsa_sign_setup(eckey, ctx_in, kinvp, rp, NULL, 0);
+}
+
+ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
+                               const BIGNUM *in_kinv, const BIGNUM *in_r,
+                               EC_KEY *eckey)
+{
+    int ok = 0, i;
+    BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL;
+    const BIGNUM *order, *ckinv;
+    BN_CTX *ctx = NULL;
+    const EC_GROUP *group;
+    ECDSA_SIG *ret;
+    const BIGNUM *priv_key;
+
+    group = EC_KEY_get0_group(eckey);
+    priv_key = EC_KEY_get0_private_key(eckey);
+
+    if (group == NULL || priv_key == NULL) {
+        ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_PASSED_NULL_PARAMETER);
+        return NULL;
+    }
+
+    if (!EC_KEY_can_sign(eckey)) {
+        ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
+        return NULL;
+    }
+
+    ret = ECDSA_SIG_new();
+    if (ret == NULL) {
+        ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    ret->r = BN_new();
+    ret->s = BN_new();
+    if (ret->r == NULL || ret->s == NULL) {
+        ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    s = ret->s;
+
+    if ((ctx = BN_CTX_new()) == NULL ||
+        (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) {
+        ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    order = EC_GROUP_get0_order(group);
+    if (order == NULL) {
+        ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_EC_LIB);
+        goto err;
+    }
+    i = BN_num_bits(order);
+    /*
+     * Need to truncate digest if it is too long: first truncate whole bytes.
+     */
+    if (8 * dgst_len > i)
+        dgst_len = (i + 7) / 8;
+    if (!BN_bin2bn(dgst, dgst_len, m)) {
+        ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
+        goto err;
+    }
+    /* If still too long truncate remaining bits with a shift */
+    if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
+        ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
+        goto err;
+    }
+    do {
+        if (in_kinv == NULL || in_r == NULL) {
+            if (!ecdsa_sign_setup(eckey, ctx, &kinv, &ret->r, dgst, dgst_len)) {
+                ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_ECDSA_LIB);
+                goto err;
+            }
+            ckinv = kinv;
+        } else {
+            ckinv = in_kinv;
+            if (BN_copy(ret->r, in_r) == NULL) {
+                ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+        }
+
+        if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) {
+            ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
+            goto err;
+        }
+        if (!BN_mod_add_quick(s, tmp, m, order)) {
+            ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
+            goto err;
+        }
+        if (!BN_mod_mul(s, s, ckinv, order, ctx)) {
+            ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, ERR_R_BN_LIB);
+            goto err;
+        }
+        if (BN_is_zero(s)) {
+            /*
+             * if kinv and r have been supplied by the caller don't to
+             * generate new kinv and r values
+             */
+            if (in_kinv != NULL && in_r != NULL) {
+                ECerr(EC_F_OSSL_ECDSA_SIGN_SIG, EC_R_NEED_NEW_SETUP_VALUES);
+                goto err;
+            }
+        } else
+            /* s != 0 => we have a valid signature */
+            break;
+    }
+    while (1);
+
+    ok = 1;
+ err:
+    if (!ok) {
+        ECDSA_SIG_free(ret);
+        ret = NULL;
+    }
+    BN_CTX_free(ctx);
+    BN_clear_free(m);
+    BN_clear_free(tmp);
+    BN_clear_free(kinv);
+    return ret;
+}
+
+/*-
+ * returns
+ *      1: correct signature
+ *      0: incorrect signature
+ *     -1: error
+ */
+int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
+                      const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
+{
+    ECDSA_SIG *s;
+    const unsigned char *p = sigbuf;
+    unsigned char *der = NULL;
+    int derlen = -1;
+    int ret = -1;
+
+    s = ECDSA_SIG_new();
+    if (s == NULL)
+        return (ret);
+    if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL)
+        goto err;
+    /* Ensure signature uses DER and doesn't have trailing garbage */
+    derlen = i2d_ECDSA_SIG(s, &der);
+    if (derlen != sig_len || memcmp(sigbuf, der, derlen) != 0)
+        goto err;
+    ret = ECDSA_do_verify(dgst, dgst_len, s, eckey);
+ err:
+    OPENSSL_clear_free(der, derlen);
+    ECDSA_SIG_free(s);
+    return (ret);
+}
+
+int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
+                          const ECDSA_SIG *sig, EC_KEY *eckey)
+{
+    int ret = -1, i;
+    BN_CTX *ctx;
+    const BIGNUM *order;
+    BIGNUM *u1, *u2, *m, *X;
+    EC_POINT *point = NULL;
+    const EC_GROUP *group;
+    const EC_POINT *pub_key;
+
+    /* check input values */
+    if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
+        (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) {
+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_MISSING_PARAMETERS);
+        return -1;
+    }
+
+    if (!EC_KEY_can_sign(eckey)) {
+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
+        return -1;
+    }
+
+    ctx = BN_CTX_new();
+    if (ctx == NULL) {
+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+    BN_CTX_start(ctx);
+    u1 = BN_CTX_get(ctx);
+    u2 = BN_CTX_get(ctx);
+    m = BN_CTX_get(ctx);
+    X = BN_CTX_get(ctx);
+    if (X == NULL) {
+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
+        goto err;
+    }
+
+    order = EC_GROUP_get0_order(group);
+    if (order == NULL) {
+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
+        goto err;
+    }
+
+    if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
+        BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
+        BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) {
+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, EC_R_BAD_SIGNATURE);
+        ret = 0;                /* signature is invalid */
+        goto err;
+    }
+    /* calculate tmp1 = inv(S) mod order */
+    if (!BN_mod_inverse(u2, sig->s, order, ctx)) {
+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
+        goto err;
+    }
+    /* digest -> m */
+    i = BN_num_bits(order);
+    /*
+     * Need to truncate digest if it is too long: first truncate whole bytes.
+     */
+    if (8 * dgst_len > i)
+        dgst_len = (i + 7) / 8;
+    if (!BN_bin2bn(dgst, dgst_len, m)) {
+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
+        goto err;
+    }
+    /* If still too long truncate remaining bits with a shift */
+    if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
+        goto err;
+    }
+    /* u1 = m * tmp mod order */
+    if (!BN_mod_mul(u1, m, u2, order, ctx)) {
+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
+        goto err;
+    }
+    /* u2 = r * w mod q */
+    if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) {
+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
+        goto err;
+    }
+
+    if ((point = EC_POINT_new(group)) == NULL) {
+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) {
+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
+        goto err;
+    }
+    if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
+        NID_X9_62_prime_field) {
+        if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL, ctx)) {
+            ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
+            goto err;
+        }
+    }
+#ifndef OPENSSL_NO_EC2M
+    else {                      /* NID_X9_62_characteristic_two_field */
+
+        if (!EC_POINT_get_affine_coordinates_GF2m(group, point, X, NULL, ctx)) {
+            ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_EC_LIB);
+            goto err;
+        }
+    }
+#endif
+    if (!BN_nnmod(u1, X, order, ctx)) {
+        ECerr(EC_F_OSSL_ECDSA_VERIFY_SIG, ERR_R_BN_LIB);
+        goto err;
+    }
+    /*  if the signature is correct u1 is equal to sig->r */
+    ret = (BN_ucmp(u1, sig->r) == 0);
+ err:
+    BN_CTX_end(ctx);
+    BN_CTX_free(ctx);
+    EC_POINT_free(point);
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecdsa_sign.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecdsa_sign.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecdsa_sign.c	(revision 331)
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2015-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 <openssl/ec.h>
+#include "ec_lcl.h"
+#include <openssl/err.h>
+
+ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
+{
+    return ECDSA_do_sign_ex(dgst, dlen, NULL, NULL, eckey);
+}
+
+ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dlen,
+                            const BIGNUM *kinv, const BIGNUM *rp,
+                            EC_KEY *eckey)
+{
+    if (eckey->meth->sign_sig != NULL)
+        return eckey->meth->sign_sig(dgst, dlen, kinv, rp, eckey);
+    ECerr(EC_F_ECDSA_DO_SIGN_EX, EC_R_OPERATION_NOT_SUPPORTED);
+    return NULL;
+}
+
+int ECDSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char
+               *sig, unsigned int *siglen, EC_KEY *eckey)
+{
+    return ECDSA_sign_ex(type, dgst, dlen, sig, siglen, NULL, NULL, eckey);
+}
+
+int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen,
+                  unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv,
+                  const BIGNUM *r, EC_KEY *eckey)
+{
+    if (eckey->meth->sign != NULL)
+        return eckey->meth->sign(type, dgst, dlen, sig, siglen, kinv, r, eckey);
+    ECerr(EC_F_ECDSA_SIGN_EX, EC_R_OPERATION_NOT_SUPPORTED);
+    return 0;
+}
+
+int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
+                     BIGNUM **rp)
+{
+    if (eckey->meth->sign_setup != NULL)
+        return eckey->meth->sign_setup(eckey, ctx_in, kinvp, rp);
+    ECerr(EC_F_ECDSA_SIGN_SETUP, EC_R_OPERATION_NOT_SUPPORTED);
+    return 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecdsa_vrf.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecdsa_vrf.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecdsa_vrf.c	(revision 331)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2002-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 <openssl/ec.h>
+#include "ec_lcl.h"
+#include <openssl/err.h>
+
+/*-
+ * returns
+ *      1: correct signature
+ *      0: incorrect signature
+ *     -1: error
+ */
+int ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
+                    const ECDSA_SIG *sig, EC_KEY *eckey)
+{
+    if (eckey->meth->verify_sig != NULL)
+        return eckey->meth->verify_sig(dgst, dgst_len, sig, eckey);
+    ECerr(EC_F_ECDSA_DO_VERIFY, EC_R_OPERATION_NOT_SUPPORTED);
+    return 0;
+}
+
+/*-
+ * returns
+ *      1: correct signature
+ *      0: incorrect signature
+ *     -1: error
+ */
+int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
+                 const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
+{
+    if (eckey->meth->verify != NULL)
+        return eckey->meth->verify(type, dgst, dgst_len, sigbuf, sig_len,
+                                   eckey);
+    ECerr(EC_F_ECDSA_VERIFY, EC_R_OPERATION_NOT_SUPPORTED);
+    return 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/eck_prn.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/eck_prn.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/eck_prn.c	(revision 331)
@@ -0,0 +1,273 @@
+/*
+ * Copyright 2006-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions originally developed by SUN MICROSYSTEMS, INC., and
+ * contributed to the OpenSSL project.
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/ec.h>
+#include <openssl/bn.h>
+
+#ifndef OPENSSL_NO_STDIO
+int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off)
+{
+    BIO *b;
+    int ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        ECerr(EC_F_ECPKPARAMETERS_PRINT_FP, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = ECPKParameters_print(b, x, off);
+    BIO_free(b);
+    return (ret);
+}
+
+int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off)
+{
+    BIO *b;
+    int ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = EC_KEY_print(b, x, off);
+    BIO_free(b);
+    return (ret);
+}
+
+int ECParameters_print_fp(FILE *fp, const EC_KEY *x)
+{
+    BIO *b;
+    int ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = ECParameters_print(b, x);
+    BIO_free(b);
+    return (ret);
+}
+#endif
+
+static int print_bin(BIO *fp, const char *str, const unsigned char *num,
+                     size_t len, int off);
+
+int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
+{
+    int ret = 0, reason = ERR_R_BIO_LIB;
+    BN_CTX *ctx = NULL;
+    const EC_POINT *point = NULL;
+    BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL;
+    const BIGNUM *order = NULL, *cofactor = NULL;
+    const unsigned char *seed;
+    size_t seed_len = 0;
+
+    static const char *gen_compressed = "Generator (compressed):";
+    static const char *gen_uncompressed = "Generator (uncompressed):";
+    static const char *gen_hybrid = "Generator (hybrid):";
+
+    if (!x) {
+        reason = ERR_R_PASSED_NULL_PARAMETER;
+        goto err;
+    }
+
+    ctx = BN_CTX_new();
+    if (ctx == NULL) {
+        reason = ERR_R_MALLOC_FAILURE;
+        goto err;
+    }
+
+    if (EC_GROUP_get_asn1_flag(x)) {
+        /* the curve parameter are given by an asn1 OID */
+        int nid;
+        const char *nname;
+
+        if (!BIO_indent(bp, off, 128))
+            goto err;
+
+        nid = EC_GROUP_get_curve_name(x);
+        if (nid == 0)
+            goto err;
+        if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0)
+            goto err;
+        if (BIO_printf(bp, "\n") <= 0)
+            goto err;
+        nname = EC_curve_nid2nist(nid);
+        if (nname) {
+            if (!BIO_indent(bp, off, 128))
+                goto err;
+            if (BIO_printf(bp, "NIST CURVE: %s\n", nname) <= 0)
+                goto err;
+        }
+    } else {
+        /* explicit parameters */
+        int is_char_two = 0;
+        point_conversion_form_t form;
+        int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x));
+
+        if (tmp_nid == NID_X9_62_characteristic_two_field)
+            is_char_two = 1;
+
+        if ((p = BN_new()) == NULL || (a = BN_new()) == NULL ||
+            (b = BN_new()) == NULL) {
+            reason = ERR_R_MALLOC_FAILURE;
+            goto err;
+        }
+#ifndef OPENSSL_NO_EC2M
+        if (is_char_two) {
+            if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) {
+                reason = ERR_R_EC_LIB;
+                goto err;
+            }
+        } else                  /* prime field */
+#endif
+        {
+            if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) {
+                reason = ERR_R_EC_LIB;
+                goto err;
+            }
+        }
+
+        if ((point = EC_GROUP_get0_generator(x)) == NULL) {
+            reason = ERR_R_EC_LIB;
+            goto err;
+        }
+        order = EC_GROUP_get0_order(x);
+        cofactor = EC_GROUP_get0_cofactor(x);
+        if (order == NULL) {
+            reason = ERR_R_EC_LIB;
+            goto err;
+        }
+
+        form = EC_GROUP_get_point_conversion_form(x);
+
+        if ((gen = EC_POINT_point2bn(x, point, form, NULL, ctx)) == NULL) {
+            reason = ERR_R_EC_LIB;
+            goto err;
+        }
+
+        if ((seed = EC_GROUP_get0_seed(x)) != NULL)
+            seed_len = EC_GROUP_get_seed_len(x);
+
+        if (!BIO_indent(bp, off, 128))
+            goto err;
+
+        /* print the 'short name' of the field type */
+        if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid))
+            <= 0)
+            goto err;
+
+        if (is_char_two) {
+            /* print the 'short name' of the base type OID */
+            int basis_type = EC_GROUP_get_basis_type(x);
+            if (basis_type == 0)
+                goto err;
+
+            if (!BIO_indent(bp, off, 128))
+                goto err;
+
+            if (BIO_printf(bp, "Basis Type: %s\n",
+                           OBJ_nid2sn(basis_type)) <= 0)
+                goto err;
+
+            /* print the polynomial */
+            if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, NULL,
+                                              off))
+                goto err;
+        } else {
+            if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, NULL, off))
+                goto err;
+        }
+        if ((a != NULL) && !ASN1_bn_print(bp, "A:   ", a, NULL, off))
+            goto err;
+        if ((b != NULL) && !ASN1_bn_print(bp, "B:   ", b, NULL, off))
+            goto err;
+        if (form == POINT_CONVERSION_COMPRESSED) {
+            if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen,
+                                                NULL, off))
+                goto err;
+        } else if (form == POINT_CONVERSION_UNCOMPRESSED) {
+            if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen,
+                                                NULL, off))
+                goto err;
+        } else {                /* form == POINT_CONVERSION_HYBRID */
+
+            if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen,
+                                                NULL, off))
+                goto err;
+        }
+        if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order,
+                                              NULL, off))
+            goto err;
+        if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor,
+                                                 NULL, off))
+            goto err;
+        if (seed && !print_bin(bp, "Seed:", seed, seed_len, off))
+            goto err;
+    }
+    ret = 1;
+ err:
+    if (!ret)
+        ECerr(EC_F_ECPKPARAMETERS_PRINT, reason);
+    BN_free(p);
+    BN_free(a);
+    BN_free(b);
+    BN_free(gen);
+    BN_CTX_free(ctx);
+    return (ret);
+}
+
+static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
+                     size_t len, int off)
+{
+    size_t i;
+    char str[128];
+
+    if (buf == NULL)
+        return 1;
+    if (off > 0) {
+        if (off > 128)
+            off = 128;
+        memset(str, ' ', off);
+        if (BIO_write(fp, str, off) <= 0)
+            return 0;
+    } else {
+        off = 0;
+    }
+
+    if (BIO_printf(fp, "%s", name) <= 0)
+        return 0;
+
+    for (i = 0; i < len; i++) {
+        if ((i % 15) == 0) {
+            str[0] = '\n';
+            memset(&(str[1]), ' ', off + 4);
+            if (BIO_write(fp, str, off + 1 + 4) <= 0)
+                return 0;
+        }
+        if (BIO_printf(fp, "%02x%s", buf[i], ((i + 1) == len) ? "" : ":") <=
+            0)
+            return 0;
+    }
+    if (BIO_write(fp, "\n", 1) <= 0)
+        return 0;
+
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_mont.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_mont.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_mont.c	(revision 331)
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2001-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include <openssl/err.h>
+
+#include "ec_lcl.h"
+
+const EC_METHOD *EC_GFp_mont_method(void)
+{
+    static const EC_METHOD ret = {
+        EC_FLAGS_DEFAULT_OCT,
+        NID_X9_62_prime_field,
+        ec_GFp_mont_group_init,
+        ec_GFp_mont_group_finish,
+        ec_GFp_mont_group_clear_finish,
+        ec_GFp_mont_group_copy,
+        ec_GFp_mont_group_set_curve,
+        ec_GFp_simple_group_get_curve,
+        ec_GFp_simple_group_get_degree,
+        ec_group_simple_order_bits,
+        ec_GFp_simple_group_check_discriminant,
+        ec_GFp_simple_point_init,
+        ec_GFp_simple_point_finish,
+        ec_GFp_simple_point_clear_finish,
+        ec_GFp_simple_point_copy,
+        ec_GFp_simple_point_set_to_infinity,
+        ec_GFp_simple_set_Jprojective_coordinates_GFp,
+        ec_GFp_simple_get_Jprojective_coordinates_GFp,
+        ec_GFp_simple_point_set_affine_coordinates,
+        ec_GFp_simple_point_get_affine_coordinates,
+        0, 0, 0,
+        ec_GFp_simple_add,
+        ec_GFp_simple_dbl,
+        ec_GFp_simple_invert,
+        ec_GFp_simple_is_at_infinity,
+        ec_GFp_simple_is_on_curve,
+        ec_GFp_simple_cmp,
+        ec_GFp_simple_make_affine,
+        ec_GFp_simple_points_make_affine,
+        0 /* mul */ ,
+        0 /* precompute_mult */ ,
+        0 /* have_precompute_mult */ ,
+        ec_GFp_mont_field_mul,
+        ec_GFp_mont_field_sqr,
+        0 /* field_div */ ,
+        ec_GFp_mont_field_encode,
+        ec_GFp_mont_field_decode,
+        ec_GFp_mont_field_set_to_one,
+        ec_key_simple_priv2oct,
+        ec_key_simple_oct2priv,
+        0, /* set private */
+        ec_key_simple_generate_key,
+        ec_key_simple_check_key,
+        ec_key_simple_generate_public_key,
+        0, /* keycopy */
+        0, /* keyfinish */
+        ecdh_simple_compute_key
+    };
+
+    return &ret;
+}
+
+int ec_GFp_mont_group_init(EC_GROUP *group)
+{
+    int ok;
+
+    ok = ec_GFp_simple_group_init(group);
+    group->field_data1 = NULL;
+    group->field_data2 = NULL;
+    return ok;
+}
+
+void ec_GFp_mont_group_finish(EC_GROUP *group)
+{
+    BN_MONT_CTX_free(group->field_data1);
+    group->field_data1 = NULL;
+    BN_free(group->field_data2);
+    group->field_data2 = NULL;
+    ec_GFp_simple_group_finish(group);
+}
+
+void ec_GFp_mont_group_clear_finish(EC_GROUP *group)
+{
+    BN_MONT_CTX_free(group->field_data1);
+    group->field_data1 = NULL;
+    BN_clear_free(group->field_data2);
+    group->field_data2 = NULL;
+    ec_GFp_simple_group_clear_finish(group);
+}
+
+int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src)
+{
+    BN_MONT_CTX_free(dest->field_data1);
+    dest->field_data1 = NULL;
+    BN_clear_free(dest->field_data2);
+    dest->field_data2 = NULL;
+
+    if (!ec_GFp_simple_group_copy(dest, src))
+        return 0;
+
+    if (src->field_data1 != NULL) {
+        dest->field_data1 = BN_MONT_CTX_new();
+        if (dest->field_data1 == NULL)
+            return 0;
+        if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1))
+            goto err;
+    }
+    if (src->field_data2 != NULL) {
+        dest->field_data2 = BN_dup(src->field_data2);
+        if (dest->field_data2 == NULL)
+            goto err;
+    }
+
+    return 1;
+
+ err:
+    BN_MONT_CTX_free(dest->field_data1);
+    dest->field_data1 = NULL;
+    return 0;
+}
+
+int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+                                const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+{
+    BN_CTX *new_ctx = NULL;
+    BN_MONT_CTX *mont = NULL;
+    BIGNUM *one = NULL;
+    int ret = 0;
+
+    BN_MONT_CTX_free(group->field_data1);
+    group->field_data1 = NULL;
+    BN_free(group->field_data2);
+    group->field_data2 = NULL;
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            return 0;
+    }
+
+    mont = BN_MONT_CTX_new();
+    if (mont == NULL)
+        goto err;
+    if (!BN_MONT_CTX_set(mont, p, ctx)) {
+        ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB);
+        goto err;
+    }
+    one = BN_new();
+    if (one == NULL)
+        goto err;
+    if (!BN_to_montgomery(one, BN_value_one(), mont, ctx))
+        goto err;
+
+    group->field_data1 = mont;
+    mont = NULL;
+    group->field_data2 = one;
+    one = NULL;
+
+    ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+
+    if (!ret) {
+        BN_MONT_CTX_free(group->field_data1);
+        group->field_data1 = NULL;
+        BN_free(group->field_data2);
+        group->field_data2 = NULL;
+    }
+
+ err:
+    BN_free(one);
+    BN_CTX_free(new_ctx);
+    BN_MONT_CTX_free(mont);
+    return ret;
+}
+
+int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+                          const BIGNUM *b, BN_CTX *ctx)
+{
+    if (group->field_data1 == NULL) {
+        ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED);
+        return 0;
+    }
+
+    return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx);
+}
+
+int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+                          BN_CTX *ctx)
+{
+    if (group->field_data1 == NULL) {
+        ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED);
+        return 0;
+    }
+
+    return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx);
+}
+
+int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r,
+                             const BIGNUM *a, BN_CTX *ctx)
+{
+    if (group->field_data1 == NULL) {
+        ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED);
+        return 0;
+    }
+
+    return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx);
+}
+
+int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r,
+                             const BIGNUM *a, BN_CTX *ctx)
+{
+    if (group->field_data1 == NULL) {
+        ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED);
+        return 0;
+    }
+
+    return BN_from_montgomery(r, a, group->field_data1, ctx);
+}
+
+int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r,
+                                 BN_CTX *ctx)
+{
+    if (group->field_data2 == NULL) {
+        ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED);
+        return 0;
+    }
+
+    if (!BN_copy(r, group->field_data2))
+        return 0;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_nist.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_nist.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_nist.c	(revision 331)
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2001-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include <limits.h>
+
+#include <openssl/err.h>
+#include <openssl/obj_mac.h>
+#include "ec_lcl.h"
+
+const EC_METHOD *EC_GFp_nist_method(void)
+{
+    static const EC_METHOD ret = {
+        EC_FLAGS_DEFAULT_OCT,
+        NID_X9_62_prime_field,
+        ec_GFp_simple_group_init,
+        ec_GFp_simple_group_finish,
+        ec_GFp_simple_group_clear_finish,
+        ec_GFp_nist_group_copy,
+        ec_GFp_nist_group_set_curve,
+        ec_GFp_simple_group_get_curve,
+        ec_GFp_simple_group_get_degree,
+        ec_group_simple_order_bits,
+        ec_GFp_simple_group_check_discriminant,
+        ec_GFp_simple_point_init,
+        ec_GFp_simple_point_finish,
+        ec_GFp_simple_point_clear_finish,
+        ec_GFp_simple_point_copy,
+        ec_GFp_simple_point_set_to_infinity,
+        ec_GFp_simple_set_Jprojective_coordinates_GFp,
+        ec_GFp_simple_get_Jprojective_coordinates_GFp,
+        ec_GFp_simple_point_set_affine_coordinates,
+        ec_GFp_simple_point_get_affine_coordinates,
+        0, 0, 0,
+        ec_GFp_simple_add,
+        ec_GFp_simple_dbl,
+        ec_GFp_simple_invert,
+        ec_GFp_simple_is_at_infinity,
+        ec_GFp_simple_is_on_curve,
+        ec_GFp_simple_cmp,
+        ec_GFp_simple_make_affine,
+        ec_GFp_simple_points_make_affine,
+        0 /* mul */ ,
+        0 /* precompute_mult */ ,
+        0 /* have_precompute_mult */ ,
+        ec_GFp_nist_field_mul,
+        ec_GFp_nist_field_sqr,
+        0 /* field_div */ ,
+        0 /* field_encode */ ,
+        0 /* field_decode */ ,
+        0,                      /* field_set_to_one */
+        ec_key_simple_priv2oct,
+        ec_key_simple_oct2priv,
+        0, /* set private */
+        ec_key_simple_generate_key,
+        ec_key_simple_check_key,
+        ec_key_simple_generate_public_key,
+        0, /* keycopy */
+        0, /* keyfinish */
+        ecdh_simple_compute_key
+    };
+
+    return &ret;
+}
+
+int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src)
+{
+    dest->field_mod_func = src->field_mod_func;
+
+    return ec_GFp_simple_group_copy(dest, src);
+}
+
+int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+                                const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
+{
+    int ret = 0;
+    BN_CTX *new_ctx = NULL;
+
+    if (ctx == NULL)
+        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+            return 0;
+
+    BN_CTX_start(ctx);
+
+    if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
+        group->field_mod_func = BN_nist_mod_192;
+    else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0)
+        group->field_mod_func = BN_nist_mod_224;
+    else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0)
+        group->field_mod_func = BN_nist_mod_256;
+    else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0)
+        group->field_mod_func = BN_nist_mod_384;
+    else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0)
+        group->field_mod_func = BN_nist_mod_521;
+    else {
+        ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME);
+        goto err;
+    }
+
+    ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+
+ err:
+    BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+                          const BIGNUM *b, BN_CTX *ctx)
+{
+    int ret = 0;
+    BN_CTX *ctx_new = NULL;
+
+    if (!group || !r || !a || !b) {
+        ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER);
+        goto err;
+    }
+    if (!ctx)
+        if ((ctx_new = ctx = BN_CTX_new()) == NULL)
+            goto err;
+
+    if (!BN_mul(r, a, b, ctx))
+        goto err;
+    if (!group->field_mod_func(r, r, group->field, ctx))
+        goto err;
+
+    ret = 1;
+ err:
+    BN_CTX_free(ctx_new);
+    return ret;
+}
+
+int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+                          BN_CTX *ctx)
+{
+    int ret = 0;
+    BN_CTX *ctx_new = NULL;
+
+    if (!group || !r || !a) {
+        ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER);
+        goto err;
+    }
+    if (!ctx)
+        if ((ctx_new = ctx = BN_CTX_new()) == NULL)
+            goto err;
+
+    if (!BN_sqr(r, a, ctx))
+        goto err;
+    if (!group->field_mod_func(r, r, group->field, ctx))
+        goto err;
+
+    ret = 1;
+ err:
+    BN_CTX_free(ctx_new);
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_nistp224.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_nistp224.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_nistp224.c	(revision 331)
@@ -0,0 +1,1717 @@
+/*
+ * Copyright 2010-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
+ */
+
+/* Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ *
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/*
+ * A 64-bit implementation of the NIST P-224 elliptic curve point multiplication
+ *
+ * Inspired by Daniel J. Bernstein's public domain nistp224 implementation
+ * and Adam Langley's public domain 64-bit C implementation of curve25519
+ */
+
+#include <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <stdint.h>
+# include <string.h>
+# include <openssl/err.h>
+# include "ec_lcl.h"
+
+# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+  /* even with gcc, the typedef won't work for 32-bit platforms */
+typedef __uint128_t uint128_t;  /* nonstandard; implemented by gcc on 64-bit
+                                 * platforms */
+# else
+#  error "Need GCC 3.1 or later to define type uint128_t"
+# endif
+
+typedef uint8_t u8;
+typedef uint64_t u64;
+typedef int64_t s64;
+
+/******************************************************************************/
+/*-
+ * INTERNAL REPRESENTATION OF FIELD ELEMENTS
+ *
+ * Field elements are represented as a_0 + 2^56*a_1 + 2^112*a_2 + 2^168*a_3
+ * using 64-bit coefficients called 'limbs',
+ * and sometimes (for multiplication results) as
+ * b_0 + 2^56*b_1 + 2^112*b_2 + 2^168*b_3 + 2^224*b_4 + 2^280*b_5 + 2^336*b_6
+ * using 128-bit coefficients called 'widelimbs'.
+ * A 4-limb representation is an 'felem';
+ * a 7-widelimb representation is a 'widefelem'.
+ * Even within felems, bits of adjacent limbs overlap, and we don't always
+ * reduce the representations: we ensure that inputs to each felem
+ * multiplication satisfy a_i < 2^60, so outputs satisfy b_i < 4*2^60*2^60,
+ * and fit into a 128-bit word without overflow. The coefficients are then
+ * again partially reduced to obtain an felem satisfying a_i < 2^57.
+ * We only reduce to the unique minimal representation at the end of the
+ * computation.
+ */
+
+typedef uint64_t limb;
+typedef uint128_t widelimb;
+
+typedef limb felem[4];
+typedef widelimb widefelem[7];
+
+/*
+ * Field element represented as a byte arrary. 28*8 = 224 bits is also the
+ * group order size for the elliptic curve, and we also use this type for
+ * scalars for point multiplication.
+ */
+typedef u8 felem_bytearray[28];
+
+static const felem_bytearray nistp224_curve_params[5] = {
+    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
+     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */
+     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
+     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE},
+    {0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, /* b */
+     0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA,
+     0x27, 0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4},
+    {0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, /* x */
+     0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22,
+     0x34, 0x32, 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21},
+    {0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, /* y */
+     0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64,
+     0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34}
+};
+
+/*-
+ * Precomputed multiples of the standard generator
+ * Points are given in coordinates (X, Y, Z) where Z normally is 1
+ * (0 for the point at infinity).
+ * For each field element, slice a_0 is word 0, etc.
+ *
+ * The table has 2 * 16 elements, starting with the following:
+ * index | bits    | point
+ * ------+---------+------------------------------
+ *     0 | 0 0 0 0 | 0G
+ *     1 | 0 0 0 1 | 1G
+ *     2 | 0 0 1 0 | 2^56G
+ *     3 | 0 0 1 1 | (2^56 + 1)G
+ *     4 | 0 1 0 0 | 2^112G
+ *     5 | 0 1 0 1 | (2^112 + 1)G
+ *     6 | 0 1 1 0 | (2^112 + 2^56)G
+ *     7 | 0 1 1 1 | (2^112 + 2^56 + 1)G
+ *     8 | 1 0 0 0 | 2^168G
+ *     9 | 1 0 0 1 | (2^168 + 1)G
+ *    10 | 1 0 1 0 | (2^168 + 2^56)G
+ *    11 | 1 0 1 1 | (2^168 + 2^56 + 1)G
+ *    12 | 1 1 0 0 | (2^168 + 2^112)G
+ *    13 | 1 1 0 1 | (2^168 + 2^112 + 1)G
+ *    14 | 1 1 1 0 | (2^168 + 2^112 + 2^56)G
+ *    15 | 1 1 1 1 | (2^168 + 2^112 + 2^56 + 1)G
+ * followed by a copy of this with each element multiplied by 2^28.
+ *
+ * The reason for this is so that we can clock bits into four different
+ * locations when doing simple scalar multiplies against the base point,
+ * and then another four locations using the second 16 elements.
+ */
+static const felem gmul[2][16][3] = {
+{{{0, 0, 0, 0},
+  {0, 0, 0, 0},
+  {0, 0, 0, 0}},
+ {{0x3280d6115c1d21, 0xc1d356c2112234, 0x7f321390b94a03, 0xb70e0cbd6bb4bf},
+  {0xd5819985007e34, 0x75a05a07476444, 0xfb4c22dfe6cd43, 0xbd376388b5f723},
+  {1, 0, 0, 0}},
+ {{0xfd9675666ebbe9, 0xbca7664d40ce5e, 0x2242df8d8a2a43, 0x1f49bbb0f99bc5},
+  {0x29e0b892dc9c43, 0xece8608436e662, 0xdc858f185310d0, 0x9812dd4eb8d321},
+  {1, 0, 0, 0}},
+ {{0x6d3e678d5d8eb8, 0x559eed1cb362f1, 0x16e9a3bbce8a3f, 0xeedcccd8c2a748},
+  {0xf19f90ed50266d, 0xabf2b4bf65f9df, 0x313865468fafec, 0x5cb379ba910a17},
+  {1, 0, 0, 0}},
+ {{0x0641966cab26e3, 0x91fb2991fab0a0, 0xefec27a4e13a0b, 0x0499aa8a5f8ebe},
+  {0x7510407766af5d, 0x84d929610d5450, 0x81d77aae82f706, 0x6916f6d4338c5b},
+  {1, 0, 0, 0}},
+ {{0xea95ac3b1f15c6, 0x086000905e82d4, 0xdd323ae4d1c8b1, 0x932b56be7685a3},
+  {0x9ef93dea25dbbf, 0x41665960f390f0, 0xfdec76dbe2a8a7, 0x523e80f019062a},
+  {1, 0, 0, 0}},
+ {{0x822fdd26732c73, 0xa01c83531b5d0f, 0x363f37347c1ba4, 0xc391b45c84725c},
+  {0xbbd5e1b2d6ad24, 0xddfbcde19dfaec, 0xc393da7e222a7f, 0x1efb7890ede244},
+  {1, 0, 0, 0}},
+ {{0x4c9e90ca217da1, 0xd11beca79159bb, 0xff8d33c2c98b7c, 0x2610b39409f849},
+  {0x44d1352ac64da0, 0xcdbb7b2c46b4fb, 0x966c079b753c89, 0xfe67e4e820b112},
+  {1, 0, 0, 0}},
+ {{0xe28cae2df5312d, 0xc71b61d16f5c6e, 0x79b7619a3e7c4c, 0x05c73240899b47},
+  {0x9f7f6382c73e3a, 0x18615165c56bda, 0x641fab2116fd56, 0x72855882b08394},
+  {1, 0, 0, 0}},
+ {{0x0469182f161c09, 0x74a98ca8d00fb5, 0xb89da93489a3e0, 0x41c98768fb0c1d},
+  {0xe5ea05fb32da81, 0x3dce9ffbca6855, 0x1cfe2d3fbf59e6, 0x0e5e03408738a7},
+  {1, 0, 0, 0}},
+ {{0xdab22b2333e87f, 0x4430137a5dd2f6, 0xe03ab9f738beb8, 0xcb0c5d0dc34f24},
+  {0x764a7df0c8fda5, 0x185ba5c3fa2044, 0x9281d688bcbe50, 0xc40331df893881},
+  {1, 0, 0, 0}},
+ {{0xb89530796f0f60, 0xade92bd26909a3, 0x1a0c83fb4884da, 0x1765bf22a5a984},
+  {0x772a9ee75db09e, 0x23bc6c67cec16f, 0x4c1edba8b14e2f, 0xe2a215d9611369},
+  {1, 0, 0, 0}},
+ {{0x571e509fb5efb3, 0xade88696410552, 0xc8ae85fada74fe, 0x6c7e4be83bbde3},
+  {0xff9f51160f4652, 0xb47ce2495a6539, 0xa2946c53b582f4, 0x286d2db3ee9a60},
+  {1, 0, 0, 0}},
+ {{0x40bbd5081a44af, 0x0995183b13926c, 0xbcefba6f47f6d0, 0x215619e9cc0057},
+  {0x8bc94d3b0df45e, 0xf11c54a3694f6f, 0x8631b93cdfe8b5, 0xe7e3f4b0982db9},
+  {1, 0, 0, 0}},
+ {{0xb17048ab3e1c7b, 0xac38f36ff8a1d8, 0x1c29819435d2c6, 0xc813132f4c07e9},
+  {0x2891425503b11f, 0x08781030579fea, 0xf5426ba5cc9674, 0x1e28ebf18562bc},
+  {1, 0, 0, 0}},
+ {{0x9f31997cc864eb, 0x06cd91d28b5e4c, 0xff17036691a973, 0xf1aef351497c58},
+  {0xdd1f2d600564ff, 0xdead073b1402db, 0x74a684435bd693, 0xeea7471f962558},
+  {1, 0, 0, 0}}},
+{{{0, 0, 0, 0},
+  {0, 0, 0, 0},
+  {0, 0, 0, 0}},
+ {{0x9665266dddf554, 0x9613d78b60ef2d, 0xce27a34cdba417, 0xd35ab74d6afc31},
+  {0x85ccdd22deb15e, 0x2137e5783a6aab, 0xa141cffd8c93c6, 0x355a1830e90f2d},
+  {1, 0, 0, 0}},
+ {{0x1a494eadaade65, 0xd6da4da77fe53c, 0xe7992996abec86, 0x65c3553c6090e3},
+  {0xfa610b1fb09346, 0xf1c6540b8a4aaf, 0xc51a13ccd3cbab, 0x02995b1b18c28a},
+  {1, 0, 0, 0}},
+ {{0x7874568e7295ef, 0x86b419fbe38d04, 0xdc0690a7550d9a, 0xd3966a44beac33},
+  {0x2b7280ec29132f, 0xbeaa3b6a032df3, 0xdc7dd88ae41200, 0xd25e2513e3a100},
+  {1, 0, 0, 0}},
+ {{0x924857eb2efafd, 0xac2bce41223190, 0x8edaa1445553fc, 0x825800fd3562d5},
+  {0x8d79148ea96621, 0x23a01c3dd9ed8d, 0xaf8b219f9416b5, 0xd8db0cc277daea},
+  {1, 0, 0, 0}},
+ {{0x76a9c3b1a700f0, 0xe9acd29bc7e691, 0x69212d1a6b0327, 0x6322e97fe154be},
+  {0x469fc5465d62aa, 0x8d41ed18883b05, 0x1f8eae66c52b88, 0xe4fcbe9325be51},
+  {1, 0, 0, 0}},
+ {{0x825fdf583cac16, 0x020b857c7b023a, 0x683c17744b0165, 0x14ffd0a2daf2f1},
+  {0x323b36184218f9, 0x4944ec4e3b47d4, 0xc15b3080841acf, 0x0bced4b01a28bb},
+  {1, 0, 0, 0}},
+ {{0x92ac22230df5c4, 0x52f33b4063eda8, 0xcb3f19870c0c93, 0x40064f2ba65233},
+  {0xfe16f0924f8992, 0x012da25af5b517, 0x1a57bb24f723a6, 0x06f8bc76760def},
+  {1, 0, 0, 0}},
+ {{0x4a7084f7817cb9, 0xbcab0738ee9a78, 0x3ec11e11d9c326, 0xdc0fe90e0f1aae},
+  {0xcf639ea5f98390, 0x5c350aa22ffb74, 0x9afae98a4047b7, 0x956ec2d617fc45},
+  {1, 0, 0, 0}},
+ {{0x4306d648c1be6a, 0x9247cd8bc9a462, 0xf5595e377d2f2e, 0xbd1c3caff1a52e},
+  {0x045e14472409d0, 0x29f3e17078f773, 0x745a602b2d4f7d, 0x191837685cdfbb},
+  {1, 0, 0, 0}},
+ {{0x5b6ee254a8cb79, 0x4953433f5e7026, 0xe21faeb1d1def4, 0xc4c225785c09de},
+  {0x307ce7bba1e518, 0x31b125b1036db8, 0x47e91868839e8f, 0xc765866e33b9f3},
+  {1, 0, 0, 0}},
+ {{0x3bfece24f96906, 0x4794da641e5093, 0xde5df64f95db26, 0x297ecd89714b05},
+  {0x701bd3ebb2c3aa, 0x7073b4f53cb1d5, 0x13c5665658af16, 0x9895089d66fe58},
+  {1, 0, 0, 0}},
+ {{0x0fef05f78c4790, 0x2d773633b05d2e, 0x94229c3a951c94, 0xbbbd70df4911bb},
+  {0xb2c6963d2c1168, 0x105f47a72b0d73, 0x9fdf6111614080, 0x7b7e94b39e67b0},
+  {1, 0, 0, 0}},
+ {{0xad1a7d6efbe2b3, 0xf012482c0da69d, 0x6b3bdf12438345, 0x40d7558d7aa4d9},
+  {0x8a09fffb5c6d3d, 0x9a356e5d9ffd38, 0x5973f15f4f9b1c, 0xdcd5f59f63c3ea},
+  {1, 0, 0, 0}},
+ {{0xacf39f4c5ca7ab, 0x4c8071cc5fd737, 0xc64e3602cd1184, 0x0acd4644c9abba},
+  {0x6c011a36d8bf6e, 0xfecd87ba24e32a, 0x19f6f56574fad8, 0x050b204ced9405},
+  {1, 0, 0, 0}},
+ {{0xed4f1cae7d9a96, 0x5ceef7ad94c40a, 0x778e4a3bf3ef9b, 0x7405783dc3b55e},
+  {0x32477c61b6e8c6, 0xb46a97570f018b, 0x91176d0a7e95d1, 0x3df90fbc4c7d0e},
+  {1, 0, 0, 0}}}
+};
+
+/* Precomputation for the group generator. */
+struct nistp224_pre_comp_st {
+    felem g_pre_comp[2][16][3];
+    int references;
+    CRYPTO_RWLOCK *lock;
+};
+
+const EC_METHOD *EC_GFp_nistp224_method(void)
+{
+    static const EC_METHOD ret = {
+        EC_FLAGS_DEFAULT_OCT,
+        NID_X9_62_prime_field,
+        ec_GFp_nistp224_group_init,
+        ec_GFp_simple_group_finish,
+        ec_GFp_simple_group_clear_finish,
+        ec_GFp_nist_group_copy,
+        ec_GFp_nistp224_group_set_curve,
+        ec_GFp_simple_group_get_curve,
+        ec_GFp_simple_group_get_degree,
+        ec_group_simple_order_bits,
+        ec_GFp_simple_group_check_discriminant,
+        ec_GFp_simple_point_init,
+        ec_GFp_simple_point_finish,
+        ec_GFp_simple_point_clear_finish,
+        ec_GFp_simple_point_copy,
+        ec_GFp_simple_point_set_to_infinity,
+        ec_GFp_simple_set_Jprojective_coordinates_GFp,
+        ec_GFp_simple_get_Jprojective_coordinates_GFp,
+        ec_GFp_simple_point_set_affine_coordinates,
+        ec_GFp_nistp224_point_get_affine_coordinates,
+        0 /* point_set_compressed_coordinates */ ,
+        0 /* point2oct */ ,
+        0 /* oct2point */ ,
+        ec_GFp_simple_add,
+        ec_GFp_simple_dbl,
+        ec_GFp_simple_invert,
+        ec_GFp_simple_is_at_infinity,
+        ec_GFp_simple_is_on_curve,
+        ec_GFp_simple_cmp,
+        ec_GFp_simple_make_affine,
+        ec_GFp_simple_points_make_affine,
+        ec_GFp_nistp224_points_mul,
+        ec_GFp_nistp224_precompute_mult,
+        ec_GFp_nistp224_have_precompute_mult,
+        ec_GFp_nist_field_mul,
+        ec_GFp_nist_field_sqr,
+        0 /* field_div */ ,
+        0 /* field_encode */ ,
+        0 /* field_decode */ ,
+        0,                      /* field_set_to_one */
+        ec_key_simple_priv2oct,
+        ec_key_simple_oct2priv,
+        0, /* set private */
+        ec_key_simple_generate_key,
+        ec_key_simple_check_key,
+        ec_key_simple_generate_public_key,
+        0, /* keycopy */
+        0, /* keyfinish */
+        ecdh_simple_compute_key
+    };
+
+    return &ret;
+}
+
+/*
+ * Helper functions to convert field elements to/from internal representation
+ */
+static void bin28_to_felem(felem out, const u8 in[28])
+{
+    out[0] = *((const uint64_t *)(in)) & 0x00ffffffffffffff;
+    out[1] = (*((const uint64_t *)(in + 7))) & 0x00ffffffffffffff;
+    out[2] = (*((const uint64_t *)(in + 14))) & 0x00ffffffffffffff;
+    out[3] = (*((const uint64_t *)(in+20))) >> 8;
+}
+
+static void felem_to_bin28(u8 out[28], const felem in)
+{
+    unsigned i;
+    for (i = 0; i < 7; ++i) {
+        out[i] = in[0] >> (8 * i);
+        out[i + 7] = in[1] >> (8 * i);
+        out[i + 14] = in[2] >> (8 * i);
+        out[i + 21] = in[3] >> (8 * i);
+    }
+}
+
+/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
+static void flip_endian(u8 *out, const u8 *in, unsigned len)
+{
+    unsigned i;
+    for (i = 0; i < len; ++i)
+        out[i] = in[len - 1 - i];
+}
+
+/* From OpenSSL BIGNUM to internal representation */
+static int BN_to_felem(felem out, const BIGNUM *bn)
+{
+    felem_bytearray b_in;
+    felem_bytearray b_out;
+    unsigned num_bytes;
+
+    /* BN_bn2bin eats leading zeroes */
+    memset(b_out, 0, sizeof(b_out));
+    num_bytes = BN_num_bytes(bn);
+    if (num_bytes > sizeof b_out) {
+        ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+        return 0;
+    }
+    if (BN_is_negative(bn)) {
+        ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+        return 0;
+    }
+    num_bytes = BN_bn2bin(bn, b_in);
+    flip_endian(b_out, b_in, num_bytes);
+    bin28_to_felem(out, b_out);
+    return 1;
+}
+
+/* From internal representation to OpenSSL BIGNUM */
+static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
+{
+    felem_bytearray b_in, b_out;
+    felem_to_bin28(b_in, in);
+    flip_endian(b_out, b_in, sizeof b_out);
+    return BN_bin2bn(b_out, sizeof b_out, out);
+}
+
+/******************************************************************************/
+/*-
+ *                              FIELD OPERATIONS
+ *
+ * Field operations, using the internal representation of field elements.
+ * NB! These operations are specific to our point multiplication and cannot be
+ * expected to be correct in general - e.g., multiplication with a large scalar
+ * will cause an overflow.
+ *
+ */
+
+static void felem_one(felem out)
+{
+    out[0] = 1;
+    out[1] = 0;
+    out[2] = 0;
+    out[3] = 0;
+}
+
+static void felem_assign(felem out, const felem in)
+{
+    out[0] = in[0];
+    out[1] = in[1];
+    out[2] = in[2];
+    out[3] = in[3];
+}
+
+/* Sum two field elements: out += in */
+static void felem_sum(felem out, const felem in)
+{
+    out[0] += in[0];
+    out[1] += in[1];
+    out[2] += in[2];
+    out[3] += in[3];
+}
+
+/* Get negative value: out = -in */
+/* Assumes in[i] < 2^57 */
+static void felem_neg(felem out, const felem in)
+{
+    static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2);
+    static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2);
+    static const limb two58m42m2 = (((limb) 1) << 58) -
+        (((limb) 1) << 42) - (((limb) 1) << 2);
+
+    /* Set to 0 mod 2^224-2^96+1 to ensure out > in */
+    out[0] = two58p2 - in[0];
+    out[1] = two58m42m2 - in[1];
+    out[2] = two58m2 - in[2];
+    out[3] = two58m2 - in[3];
+}
+
+/* Subtract field elements: out -= in */
+/* Assumes in[i] < 2^57 */
+static void felem_diff(felem out, const felem in)
+{
+    static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2);
+    static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2);
+    static const limb two58m42m2 = (((limb) 1) << 58) -
+        (((limb) 1) << 42) - (((limb) 1) << 2);
+
+    /* Add 0 mod 2^224-2^96+1 to ensure out > in */
+    out[0] += two58p2;
+    out[1] += two58m42m2;
+    out[2] += two58m2;
+    out[3] += two58m2;
+
+    out[0] -= in[0];
+    out[1] -= in[1];
+    out[2] -= in[2];
+    out[3] -= in[3];
+}
+
+/* Subtract in unreduced 128-bit mode: out -= in */
+/* Assumes in[i] < 2^119 */
+static void widefelem_diff(widefelem out, const widefelem in)
+{
+    static const widelimb two120 = ((widelimb) 1) << 120;
+    static const widelimb two120m64 = (((widelimb) 1) << 120) -
+        (((widelimb) 1) << 64);
+    static const widelimb two120m104m64 = (((widelimb) 1) << 120) -
+        (((widelimb) 1) << 104) - (((widelimb) 1) << 64);
+
+    /* Add 0 mod 2^224-2^96+1 to ensure out > in */
+    out[0] += two120;
+    out[1] += two120m64;
+    out[2] += two120m64;
+    out[3] += two120;
+    out[4] += two120m104m64;
+    out[5] += two120m64;
+    out[6] += two120m64;
+
+    out[0] -= in[0];
+    out[1] -= in[1];
+    out[2] -= in[2];
+    out[3] -= in[3];
+    out[4] -= in[4];
+    out[5] -= in[5];
+    out[6] -= in[6];
+}
+
+/* Subtract in mixed mode: out128 -= in64 */
+/* in[i] < 2^63 */
+static void felem_diff_128_64(widefelem out, const felem in)
+{
+    static const widelimb two64p8 = (((widelimb) 1) << 64) +
+        (((widelimb) 1) << 8);
+    static const widelimb two64m8 = (((widelimb) 1) << 64) -
+        (((widelimb) 1) << 8);
+    static const widelimb two64m48m8 = (((widelimb) 1) << 64) -
+        (((widelimb) 1) << 48) - (((widelimb) 1) << 8);
+
+    /* Add 0 mod 2^224-2^96+1 to ensure out > in */
+    out[0] += two64p8;
+    out[1] += two64m48m8;
+    out[2] += two64m8;
+    out[3] += two64m8;
+
+    out[0] -= in[0];
+    out[1] -= in[1];
+    out[2] -= in[2];
+    out[3] -= in[3];
+}
+
+/*
+ * Multiply a field element by a scalar: out = out * scalar The scalars we
+ * actually use are small, so results fit without overflow
+ */
+static void felem_scalar(felem out, const limb scalar)
+{
+    out[0] *= scalar;
+    out[1] *= scalar;
+    out[2] *= scalar;
+    out[3] *= scalar;
+}
+
+/*
+ * Multiply an unreduced field element by a scalar: out = out * scalar The
+ * scalars we actually use are small, so results fit without overflow
+ */
+static void widefelem_scalar(widefelem out, const widelimb scalar)
+{
+    out[0] *= scalar;
+    out[1] *= scalar;
+    out[2] *= scalar;
+    out[3] *= scalar;
+    out[4] *= scalar;
+    out[5] *= scalar;
+    out[6] *= scalar;
+}
+
+/* Square a field element: out = in^2 */
+static void felem_square(widefelem out, const felem in)
+{
+    limb tmp0, tmp1, tmp2;
+    tmp0 = 2 * in[0];
+    tmp1 = 2 * in[1];
+    tmp2 = 2 * in[2];
+    out[0] = ((widelimb) in[0]) * in[0];
+    out[1] = ((widelimb) in[0]) * tmp1;
+    out[2] = ((widelimb) in[0]) * tmp2 + ((widelimb) in[1]) * in[1];
+    out[3] = ((widelimb) in[3]) * tmp0 + ((widelimb) in[1]) * tmp2;
+    out[4] = ((widelimb) in[3]) * tmp1 + ((widelimb) in[2]) * in[2];
+    out[5] = ((widelimb) in[3]) * tmp2;
+    out[6] = ((widelimb) in[3]) * in[3];
+}
+
+/* Multiply two field elements: out = in1 * in2 */
+static void felem_mul(widefelem out, const felem in1, const felem in2)
+{
+    out[0] = ((widelimb) in1[0]) * in2[0];
+    out[1] = ((widelimb) in1[0]) * in2[1] + ((widelimb) in1[1]) * in2[0];
+    out[2] = ((widelimb) in1[0]) * in2[2] + ((widelimb) in1[1]) * in2[1] +
+             ((widelimb) in1[2]) * in2[0];
+    out[3] = ((widelimb) in1[0]) * in2[3] + ((widelimb) in1[1]) * in2[2] +
+             ((widelimb) in1[2]) * in2[1] + ((widelimb) in1[3]) * in2[0];
+    out[4] = ((widelimb) in1[1]) * in2[3] + ((widelimb) in1[2]) * in2[2] +
+             ((widelimb) in1[3]) * in2[1];
+    out[5] = ((widelimb) in1[2]) * in2[3] + ((widelimb) in1[3]) * in2[2];
+    out[6] = ((widelimb) in1[3]) * in2[3];
+}
+
+/*-
+ * Reduce seven 128-bit coefficients to four 64-bit coefficients.
+ * Requires in[i] < 2^126,
+ * ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16 */
+static void felem_reduce(felem out, const widefelem in)
+{
+    static const widelimb two127p15 = (((widelimb) 1) << 127) +
+        (((widelimb) 1) << 15);
+    static const widelimb two127m71 = (((widelimb) 1) << 127) -
+        (((widelimb) 1) << 71);
+    static const widelimb two127m71m55 = (((widelimb) 1) << 127) -
+        (((widelimb) 1) << 71) - (((widelimb) 1) << 55);
+    widelimb output[5];
+
+    /* Add 0 mod 2^224-2^96+1 to ensure all differences are positive */
+    output[0] = in[0] + two127p15;
+    output[1] = in[1] + two127m71m55;
+    output[2] = in[2] + two127m71;
+    output[3] = in[3];
+    output[4] = in[4];
+
+    /* Eliminate in[4], in[5], in[6] */
+    output[4] += in[6] >> 16;
+    output[3] += (in[6] & 0xffff) << 40;
+    output[2] -= in[6];
+
+    output[3] += in[5] >> 16;
+    output[2] += (in[5] & 0xffff) << 40;
+    output[1] -= in[5];
+
+    output[2] += output[4] >> 16;
+    output[1] += (output[4] & 0xffff) << 40;
+    output[0] -= output[4];
+
+    /* Carry 2 -> 3 -> 4 */
+    output[3] += output[2] >> 56;
+    output[2] &= 0x00ffffffffffffff;
+
+    output[4] = output[3] >> 56;
+    output[3] &= 0x00ffffffffffffff;
+
+    /* Now output[2] < 2^56, output[3] < 2^56, output[4] < 2^72 */
+
+    /* Eliminate output[4] */
+    output[2] += output[4] >> 16;
+    /* output[2] < 2^56 + 2^56 = 2^57 */
+    output[1] += (output[4] & 0xffff) << 40;
+    output[0] -= output[4];
+
+    /* Carry 0 -> 1 -> 2 -> 3 */
+    output[1] += output[0] >> 56;
+    out[0] = output[0] & 0x00ffffffffffffff;
+
+    output[2] += output[1] >> 56;
+    /* output[2] < 2^57 + 2^72 */
+    out[1] = output[1] & 0x00ffffffffffffff;
+    output[3] += output[2] >> 56;
+    /* output[3] <= 2^56 + 2^16 */
+    out[2] = output[2] & 0x00ffffffffffffff;
+
+    /*-
+     * out[0] < 2^56, out[1] < 2^56, out[2] < 2^56,
+     * out[3] <= 2^56 + 2^16 (due to final carry),
+     * so out < 2*p
+     */
+    out[3] = output[3];
+}
+
+static void felem_square_reduce(felem out, const felem in)
+{
+    widefelem tmp;
+    felem_square(tmp, in);
+    felem_reduce(out, tmp);
+}
+
+static void felem_mul_reduce(felem out, const felem in1, const felem in2)
+{
+    widefelem tmp;
+    felem_mul(tmp, in1, in2);
+    felem_reduce(out, tmp);
+}
+
+/*
+ * Reduce to unique minimal representation. Requires 0 <= in < 2*p (always
+ * call felem_reduce first)
+ */
+static void felem_contract(felem out, const felem in)
+{
+    static const int64_t two56 = ((limb) 1) << 56;
+    /* 0 <= in < 2*p, p = 2^224 - 2^96 + 1 */
+    /* if in > p , reduce in = in - 2^224 + 2^96 - 1 */
+    int64_t tmp[4], a;
+    tmp[0] = in[0];
+    tmp[1] = in[1];
+    tmp[2] = in[2];
+    tmp[3] = in[3];
+    /* Case 1: a = 1 iff in >= 2^224 */
+    a = (in[3] >> 56);
+    tmp[0] -= a;
+    tmp[1] += a << 40;
+    tmp[3] &= 0x00ffffffffffffff;
+    /*
+     * Case 2: a = 0 iff p <= in < 2^224, i.e., the high 128 bits are all 1
+     * and the lower part is non-zero
+     */
+    a = ((in[3] & in[2] & (in[1] | 0x000000ffffffffff)) + 1) |
+        (((int64_t) (in[0] + (in[1] & 0x000000ffffffffff)) - 1) >> 63);
+    a &= 0x00ffffffffffffff;
+    /* turn a into an all-one mask (if a = 0) or an all-zero mask */
+    a = (a - 1) >> 63;
+    /* subtract 2^224 - 2^96 + 1 if a is all-one */
+    tmp[3] &= a ^ 0xffffffffffffffff;
+    tmp[2] &= a ^ 0xffffffffffffffff;
+    tmp[1] &= (a ^ 0xffffffffffffffff) | 0x000000ffffffffff;
+    tmp[0] -= 1 & a;
+
+    /*
+     * eliminate negative coefficients: if tmp[0] is negative, tmp[1] must be
+     * non-zero, so we only need one step
+     */
+    a = tmp[0] >> 63;
+    tmp[0] += two56 & a;
+    tmp[1] -= 1 & a;
+
+    /* carry 1 -> 2 -> 3 */
+    tmp[2] += tmp[1] >> 56;
+    tmp[1] &= 0x00ffffffffffffff;
+
+    tmp[3] += tmp[2] >> 56;
+    tmp[2] &= 0x00ffffffffffffff;
+
+    /* Now 0 <= out < p */
+    out[0] = tmp[0];
+    out[1] = tmp[1];
+    out[2] = tmp[2];
+    out[3] = tmp[3];
+}
+
+/*
+ * Zero-check: returns 1 if input is 0, and 0 otherwise. We know that field
+ * elements are reduced to in < 2^225, so we only need to check three cases:
+ * 0, 2^224 - 2^96 + 1, and 2^225 - 2^97 + 2
+ */
+static limb felem_is_zero(const felem in)
+{
+    limb zero, two224m96p1, two225m97p2;
+
+    zero = in[0] | in[1] | in[2] | in[3];
+    zero = (((int64_t) (zero) - 1) >> 63) & 1;
+    two224m96p1 = (in[0] ^ 1) | (in[1] ^ 0x00ffff0000000000)
+        | (in[2] ^ 0x00ffffffffffffff) | (in[3] ^ 0x00ffffffffffffff);
+    two224m96p1 = (((int64_t) (two224m96p1) - 1) >> 63) & 1;
+    two225m97p2 = (in[0] ^ 2) | (in[1] ^ 0x00fffe0000000000)
+        | (in[2] ^ 0x00ffffffffffffff) | (in[3] ^ 0x01ffffffffffffff);
+    two225m97p2 = (((int64_t) (two225m97p2) - 1) >> 63) & 1;
+    return (zero | two224m96p1 | two225m97p2);
+}
+
+static limb felem_is_zero_int(const felem in)
+{
+    return (int)(felem_is_zero(in) & ((limb) 1));
+}
+
+/* Invert a field element */
+/* Computation chain copied from djb's code */
+static void felem_inv(felem out, const felem in)
+{
+    felem ftmp, ftmp2, ftmp3, ftmp4;
+    widefelem tmp;
+    unsigned i;
+
+    felem_square(tmp, in);
+    felem_reduce(ftmp, tmp);    /* 2 */
+    felem_mul(tmp, in, ftmp);
+    felem_reduce(ftmp, tmp);    /* 2^2 - 1 */
+    felem_square(tmp, ftmp);
+    felem_reduce(ftmp, tmp);    /* 2^3 - 2 */
+    felem_mul(tmp, in, ftmp);
+    felem_reduce(ftmp, tmp);    /* 2^3 - 1 */
+    felem_square(tmp, ftmp);
+    felem_reduce(ftmp2, tmp);   /* 2^4 - 2 */
+    felem_square(tmp, ftmp2);
+    felem_reduce(ftmp2, tmp);   /* 2^5 - 4 */
+    felem_square(tmp, ftmp2);
+    felem_reduce(ftmp2, tmp);   /* 2^6 - 8 */
+    felem_mul(tmp, ftmp2, ftmp);
+    felem_reduce(ftmp, tmp);    /* 2^6 - 1 */
+    felem_square(tmp, ftmp);
+    felem_reduce(ftmp2, tmp);   /* 2^7 - 2 */
+    for (i = 0; i < 5; ++i) {   /* 2^12 - 2^6 */
+        felem_square(tmp, ftmp2);
+        felem_reduce(ftmp2, tmp);
+    }
+    felem_mul(tmp, ftmp2, ftmp);
+    felem_reduce(ftmp2, tmp);   /* 2^12 - 1 */
+    felem_square(tmp, ftmp2);
+    felem_reduce(ftmp3, tmp);   /* 2^13 - 2 */
+    for (i = 0; i < 11; ++i) {  /* 2^24 - 2^12 */
+        felem_square(tmp, ftmp3);
+        felem_reduce(ftmp3, tmp);
+    }
+    felem_mul(tmp, ftmp3, ftmp2);
+    felem_reduce(ftmp2, tmp);   /* 2^24 - 1 */
+    felem_square(tmp, ftmp2);
+    felem_reduce(ftmp3, tmp);   /* 2^25 - 2 */
+    for (i = 0; i < 23; ++i) {  /* 2^48 - 2^24 */
+        felem_square(tmp, ftmp3);
+        felem_reduce(ftmp3, tmp);
+    }
+    felem_mul(tmp, ftmp3, ftmp2);
+    felem_reduce(ftmp3, tmp);   /* 2^48 - 1 */
+    felem_square(tmp, ftmp3);
+    felem_reduce(ftmp4, tmp);   /* 2^49 - 2 */
+    for (i = 0; i < 47; ++i) {  /* 2^96 - 2^48 */
+        felem_square(tmp, ftmp4);
+        felem_reduce(ftmp4, tmp);
+    }
+    felem_mul(tmp, ftmp3, ftmp4);
+    felem_reduce(ftmp3, tmp);   /* 2^96 - 1 */
+    felem_square(tmp, ftmp3);
+    felem_reduce(ftmp4, tmp);   /* 2^97 - 2 */
+    for (i = 0; i < 23; ++i) {  /* 2^120 - 2^24 */
+        felem_square(tmp, ftmp4);
+        felem_reduce(ftmp4, tmp);
+    }
+    felem_mul(tmp, ftmp2, ftmp4);
+    felem_reduce(ftmp2, tmp);   /* 2^120 - 1 */
+    for (i = 0; i < 6; ++i) {   /* 2^126 - 2^6 */
+        felem_square(tmp, ftmp2);
+        felem_reduce(ftmp2, tmp);
+    }
+    felem_mul(tmp, ftmp2, ftmp);
+    felem_reduce(ftmp, tmp);    /* 2^126 - 1 */
+    felem_square(tmp, ftmp);
+    felem_reduce(ftmp, tmp);    /* 2^127 - 2 */
+    felem_mul(tmp, ftmp, in);
+    felem_reduce(ftmp, tmp);    /* 2^127 - 1 */
+    for (i = 0; i < 97; ++i) {  /* 2^224 - 2^97 */
+        felem_square(tmp, ftmp);
+        felem_reduce(ftmp, tmp);
+    }
+    felem_mul(tmp, ftmp, ftmp3);
+    felem_reduce(out, tmp);     /* 2^224 - 2^96 - 1 */
+}
+
+/*
+ * Copy in constant time: if icopy == 1, copy in to out, if icopy == 0, copy
+ * out to itself.
+ */
+static void copy_conditional(felem out, const felem in, limb icopy)
+{
+    unsigned i;
+    /*
+     * icopy is a (64-bit) 0 or 1, so copy is either all-zero or all-one
+     */
+    const limb copy = -icopy;
+    for (i = 0; i < 4; ++i) {
+        const limb tmp = copy & (in[i] ^ out[i]);
+        out[i] ^= tmp;
+    }
+}
+
+/******************************************************************************/
+/*-
+ *                       ELLIPTIC CURVE POINT OPERATIONS
+ *
+ * Points are represented in Jacobian projective coordinates:
+ * (X, Y, Z) corresponds to the affine point (X/Z^2, Y/Z^3),
+ * or to the point at infinity if Z == 0.
+ *
+ */
+
+/*-
+ * Double an elliptic curve point:
+ * (X', Y', Z') = 2 * (X, Y, Z), where
+ * X' = (3 * (X - Z^2) * (X + Z^2))^2 - 8 * X * Y^2
+ * Y' = 3 * (X - Z^2) * (X + Z^2) * (4 * X * Y^2 - X') - 8 * Y^2
+ * Z' = (Y + Z)^2 - Y^2 - Z^2 = 2 * Y * Z
+ * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed,
+ * while x_out == y_in is not (maybe this works, but it's not tested).
+ */
+static void
+point_double(felem x_out, felem y_out, felem z_out,
+             const felem x_in, const felem y_in, const felem z_in)
+{
+    widefelem tmp, tmp2;
+    felem delta, gamma, beta, alpha, ftmp, ftmp2;
+
+    felem_assign(ftmp, x_in);
+    felem_assign(ftmp2, x_in);
+
+    /* delta = z^2 */
+    felem_square(tmp, z_in);
+    felem_reduce(delta, tmp);
+
+    /* gamma = y^2 */
+    felem_square(tmp, y_in);
+    felem_reduce(gamma, tmp);
+
+    /* beta = x*gamma */
+    felem_mul(tmp, x_in, gamma);
+    felem_reduce(beta, tmp);
+
+    /* alpha = 3*(x-delta)*(x+delta) */
+    felem_diff(ftmp, delta);
+    /* ftmp[i] < 2^57 + 2^58 + 2 < 2^59 */
+    felem_sum(ftmp2, delta);
+    /* ftmp2[i] < 2^57 + 2^57 = 2^58 */
+    felem_scalar(ftmp2, 3);
+    /* ftmp2[i] < 3 * 2^58 < 2^60 */
+    felem_mul(tmp, ftmp, ftmp2);
+    /* tmp[i] < 2^60 * 2^59 * 4 = 2^121 */
+    felem_reduce(alpha, tmp);
+
+    /* x' = alpha^2 - 8*beta */
+    felem_square(tmp, alpha);
+    /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
+    felem_assign(ftmp, beta);
+    felem_scalar(ftmp, 8);
+    /* ftmp[i] < 8 * 2^57 = 2^60 */
+    felem_diff_128_64(tmp, ftmp);
+    /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
+    felem_reduce(x_out, tmp);
+
+    /* z' = (y + z)^2 - gamma - delta */
+    felem_sum(delta, gamma);
+    /* delta[i] < 2^57 + 2^57 = 2^58 */
+    felem_assign(ftmp, y_in);
+    felem_sum(ftmp, z_in);
+    /* ftmp[i] < 2^57 + 2^57 = 2^58 */
+    felem_square(tmp, ftmp);
+    /* tmp[i] < 4 * 2^58 * 2^58 = 2^118 */
+    felem_diff_128_64(tmp, delta);
+    /* tmp[i] < 2^118 + 2^64 + 8 < 2^119 */
+    felem_reduce(z_out, tmp);
+
+    /* y' = alpha*(4*beta - x') - 8*gamma^2 */
+    felem_scalar(beta, 4);
+    /* beta[i] < 4 * 2^57 = 2^59 */
+    felem_diff(beta, x_out);
+    /* beta[i] < 2^59 + 2^58 + 2 < 2^60 */
+    felem_mul(tmp, alpha, beta);
+    /* tmp[i] < 4 * 2^57 * 2^60 = 2^119 */
+    felem_square(tmp2, gamma);
+    /* tmp2[i] < 4 * 2^57 * 2^57 = 2^116 */
+    widefelem_scalar(tmp2, 8);
+    /* tmp2[i] < 8 * 2^116 = 2^119 */
+    widefelem_diff(tmp, tmp2);
+    /* tmp[i] < 2^119 + 2^120 < 2^121 */
+    felem_reduce(y_out, tmp);
+}
+
+/*-
+ * Add two elliptic curve points:
+ * (X_1, Y_1, Z_1) + (X_2, Y_2, Z_2) = (X_3, Y_3, Z_3), where
+ * X_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1)^2 - (Z_1^2 * X_2 - Z_2^2 * X_1)^3 -
+ * 2 * Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2
+ * Y_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1) * (Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2 - X_3) -
+ *        Z_2^3 * Y_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^3
+ * Z_3 = (Z_1^2 * X_2 - Z_2^2 * X_1) * (Z_1 * Z_2)
+ *
+ * This runs faster if 'mixed' is set, which requires Z_2 = 1 or Z_2 = 0.
+ */
+
+/*
+ * This function is not entirely constant-time: it includes a branch for
+ * checking whether the two input points are equal, (while not equal to the
+ * point at infinity). This case never happens during single point
+ * multiplication, so there is no timing leak for ECDH or ECDSA signing.
+ */
+static void point_add(felem x3, felem y3, felem z3,
+                      const felem x1, const felem y1, const felem z1,
+                      const int mixed, const felem x2, const felem y2,
+                      const felem z2)
+{
+    felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out;
+    widefelem tmp, tmp2;
+    limb z1_is_zero, z2_is_zero, x_equal, y_equal;
+
+    if (!mixed) {
+        /* ftmp2 = z2^2 */
+        felem_square(tmp, z2);
+        felem_reduce(ftmp2, tmp);
+
+        /* ftmp4 = z2^3 */
+        felem_mul(tmp, ftmp2, z2);
+        felem_reduce(ftmp4, tmp);
+
+        /* ftmp4 = z2^3*y1 */
+        felem_mul(tmp2, ftmp4, y1);
+        felem_reduce(ftmp4, tmp2);
+
+        /* ftmp2 = z2^2*x1 */
+        felem_mul(tmp2, ftmp2, x1);
+        felem_reduce(ftmp2, tmp2);
+    } else {
+        /*
+         * We'll assume z2 = 1 (special case z2 = 0 is handled later)
+         */
+
+        /* ftmp4 = z2^3*y1 */
+        felem_assign(ftmp4, y1);
+
+        /* ftmp2 = z2^2*x1 */
+        felem_assign(ftmp2, x1);
+    }
+
+    /* ftmp = z1^2 */
+    felem_square(tmp, z1);
+    felem_reduce(ftmp, tmp);
+
+    /* ftmp3 = z1^3 */
+    felem_mul(tmp, ftmp, z1);
+    felem_reduce(ftmp3, tmp);
+
+    /* tmp = z1^3*y2 */
+    felem_mul(tmp, ftmp3, y2);
+    /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
+
+    /* ftmp3 = z1^3*y2 - z2^3*y1 */
+    felem_diff_128_64(tmp, ftmp4);
+    /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
+    felem_reduce(ftmp3, tmp);
+
+    /* tmp = z1^2*x2 */
+    felem_mul(tmp, ftmp, x2);
+    /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
+
+    /* ftmp = z1^2*x2 - z2^2*x1 */
+    felem_diff_128_64(tmp, ftmp2);
+    /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */
+    felem_reduce(ftmp, tmp);
+
+    /*
+     * the formulae are incorrect if the points are equal so we check for
+     * this and do doubling if this happens
+     */
+    x_equal = felem_is_zero(ftmp);
+    y_equal = felem_is_zero(ftmp3);
+    z1_is_zero = felem_is_zero(z1);
+    z2_is_zero = felem_is_zero(z2);
+    /* In affine coordinates, (X_1, Y_1) == (X_2, Y_2) */
+    if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
+        point_double(x3, y3, z3, x1, y1, z1);
+        return;
+    }
+
+    /* ftmp5 = z1*z2 */
+    if (!mixed) {
+        felem_mul(tmp, z1, z2);
+        felem_reduce(ftmp5, tmp);
+    } else {
+        /* special case z2 = 0 is handled later */
+        felem_assign(ftmp5, z1);
+    }
+
+    /* z_out = (z1^2*x2 - z2^2*x1)*(z1*z2) */
+    felem_mul(tmp, ftmp, ftmp5);
+    felem_reduce(z_out, tmp);
+
+    /* ftmp = (z1^2*x2 - z2^2*x1)^2 */
+    felem_assign(ftmp5, ftmp);
+    felem_square(tmp, ftmp);
+    felem_reduce(ftmp, tmp);
+
+    /* ftmp5 = (z1^2*x2 - z2^2*x1)^3 */
+    felem_mul(tmp, ftmp, ftmp5);
+    felem_reduce(ftmp5, tmp);
+
+    /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
+    felem_mul(tmp, ftmp2, ftmp);
+    felem_reduce(ftmp2, tmp);
+
+    /* tmp = z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */
+    felem_mul(tmp, ftmp4, ftmp5);
+    /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */
+
+    /* tmp2 = (z1^3*y2 - z2^3*y1)^2 */
+    felem_square(tmp2, ftmp3);
+    /* tmp2[i] < 4 * 2^57 * 2^57 < 2^116 */
+
+    /* tmp2 = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 */
+    felem_diff_128_64(tmp2, ftmp5);
+    /* tmp2[i] < 2^116 + 2^64 + 8 < 2^117 */
+
+    /* ftmp5 = 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
+    felem_assign(ftmp5, ftmp2);
+    felem_scalar(ftmp5, 2);
+    /* ftmp5[i] < 2 * 2^57 = 2^58 */
+
+    /*-
+     * x_out = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 -
+     *  2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2
+     */
+    felem_diff_128_64(tmp2, ftmp5);
+    /* tmp2[i] < 2^117 + 2^64 + 8 < 2^118 */
+    felem_reduce(x_out, tmp2);
+
+    /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out */
+    felem_diff(ftmp2, x_out);
+    /* ftmp2[i] < 2^57 + 2^58 + 2 < 2^59 */
+
+    /*
+     * tmp2 = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out)
+     */
+    felem_mul(tmp2, ftmp3, ftmp2);
+    /* tmp2[i] < 4 * 2^57 * 2^59 = 2^118 */
+
+    /*-
+     * y_out = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) -
+     *  z2^3*y1*(z1^2*x2 - z2^2*x1)^3
+     */
+    widefelem_diff(tmp2, tmp);
+    /* tmp2[i] < 2^118 + 2^120 < 2^121 */
+    felem_reduce(y_out, tmp2);
+
+    /*
+     * the result (x_out, y_out, z_out) is incorrect if one of the inputs is
+     * the point at infinity, so we need to check for this separately
+     */
+
+    /*
+     * if point 1 is at infinity, copy point 2 to output, and vice versa
+     */
+    copy_conditional(x_out, x2, z1_is_zero);
+    copy_conditional(x_out, x1, z2_is_zero);
+    copy_conditional(y_out, y2, z1_is_zero);
+    copy_conditional(y_out, y1, z2_is_zero);
+    copy_conditional(z_out, z2, z1_is_zero);
+    copy_conditional(z_out, z1, z2_is_zero);
+    felem_assign(x3, x_out);
+    felem_assign(y3, y_out);
+    felem_assign(z3, z_out);
+}
+
+/*
+ * select_point selects the |idx|th point from a precomputation table and
+ * copies it to out.
+ * The pre_comp array argument should be size of |size| argument
+ */
+static void select_point(const u64 idx, unsigned int size,
+                         const felem pre_comp[][3], felem out[3])
+{
+    unsigned i, j;
+    limb *outlimbs = &out[0][0];
+
+    memset(out, 0, sizeof(*out) * 3);
+    for (i = 0; i < size; i++) {
+        const limb *inlimbs = &pre_comp[i][0][0];
+        u64 mask = i ^ idx;
+        mask |= mask >> 4;
+        mask |= mask >> 2;
+        mask |= mask >> 1;
+        mask &= 1;
+        mask--;
+        for (j = 0; j < 4 * 3; j++)
+            outlimbs[j] |= inlimbs[j] & mask;
+    }
+}
+
+/* get_bit returns the |i|th bit in |in| */
+static char get_bit(const felem_bytearray in, unsigned i)
+{
+    if (i >= 224)
+        return 0;
+    return (in[i >> 3] >> (i & 7)) & 1;
+}
+
+/*
+ * Interleaved point multiplication using precomputed point multiples: The
+ * small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[], the scalars
+ * in scalars[]. If g_scalar is non-NULL, we also add this multiple of the
+ * generator, using certain (large) precomputed multiples in g_pre_comp.
+ * Output point (X, Y, Z) is stored in x_out, y_out, z_out
+ */
+static void batch_mul(felem x_out, felem y_out, felem z_out,
+                      const felem_bytearray scalars[],
+                      const unsigned num_points, const u8 *g_scalar,
+                      const int mixed, const felem pre_comp[][17][3],
+                      const felem g_pre_comp[2][16][3])
+{
+    int i, skip;
+    unsigned num;
+    unsigned gen_mul = (g_scalar != NULL);
+    felem nq[3], tmp[4];
+    u64 bits;
+    u8 sign, digit;
+
+    /* set nq to the point at infinity */
+    memset(nq, 0, sizeof(nq));
+
+    /*
+     * Loop over all scalars msb-to-lsb, interleaving additions of multiples
+     * of the generator (two in each of the last 28 rounds) and additions of
+     * other points multiples (every 5th round).
+     */
+    skip = 1;                   /* save two point operations in the first
+                                 * round */
+    for (i = (num_points ? 220 : 27); i >= 0; --i) {
+        /* double */
+        if (!skip)
+            point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
+
+        /* add multiples of the generator */
+        if (gen_mul && (i <= 27)) {
+            /* first, look 28 bits upwards */
+            bits = get_bit(g_scalar, i + 196) << 3;
+            bits |= get_bit(g_scalar, i + 140) << 2;
+            bits |= get_bit(g_scalar, i + 84) << 1;
+            bits |= get_bit(g_scalar, i + 28);
+            /* select the point to add, in constant time */
+            select_point(bits, 16, g_pre_comp[1], tmp);
+
+            if (!skip) {
+                /* value 1 below is argument for "mixed" */
+                point_add(nq[0], nq[1], nq[2],
+                          nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]);
+            } else {
+                memcpy(nq, tmp, 3 * sizeof(felem));
+                skip = 0;
+            }
+
+            /* second, look at the current position */
+            bits = get_bit(g_scalar, i + 168) << 3;
+            bits |= get_bit(g_scalar, i + 112) << 2;
+            bits |= get_bit(g_scalar, i + 56) << 1;
+            bits |= get_bit(g_scalar, i);
+            /* select the point to add, in constant time */
+            select_point(bits, 16, g_pre_comp[0], tmp);
+            point_add(nq[0], nq[1], nq[2],
+                      nq[0], nq[1], nq[2],
+                      1 /* mixed */ , tmp[0], tmp[1], tmp[2]);
+        }
+
+        /* do other additions every 5 doublings */
+        if (num_points && (i % 5 == 0)) {
+            /* loop over all scalars */
+            for (num = 0; num < num_points; ++num) {
+                bits = get_bit(scalars[num], i + 4) << 5;
+                bits |= get_bit(scalars[num], i + 3) << 4;
+                bits |= get_bit(scalars[num], i + 2) << 3;
+                bits |= get_bit(scalars[num], i + 1) << 2;
+                bits |= get_bit(scalars[num], i) << 1;
+                bits |= get_bit(scalars[num], i - 1);
+                ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
+
+                /* select the point to add or subtract */
+                select_point(digit, 17, pre_comp[num], tmp);
+                felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative
+                                            * point */
+                copy_conditional(tmp[1], tmp[3], sign);
+
+                if (!skip) {
+                    point_add(nq[0], nq[1], nq[2],
+                              nq[0], nq[1], nq[2],
+                              mixed, tmp[0], tmp[1], tmp[2]);
+                } else {
+                    memcpy(nq, tmp, 3 * sizeof(felem));
+                    skip = 0;
+                }
+            }
+        }
+    }
+    felem_assign(x_out, nq[0]);
+    felem_assign(y_out, nq[1]);
+    felem_assign(z_out, nq[2]);
+}
+
+/******************************************************************************/
+/*
+ * FUNCTIONS TO MANAGE PRECOMPUTATION
+ */
+
+static NISTP224_PRE_COMP *nistp224_pre_comp_new()
+{
+    NISTP224_PRE_COMP *ret = OPENSSL_zalloc(sizeof(*ret));
+
+    if (!ret) {
+        ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+        return ret;
+    }
+
+    ret->references = 1;
+
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *p)
+{
+    int i;
+    if (p != NULL)
+        CRYPTO_atomic_add(&p->references, 1, &i, p->lock);
+    return p;
+}
+
+void EC_nistp224_pre_comp_free(NISTP224_PRE_COMP *p)
+{
+    int i;
+
+    if (p == NULL)
+        return;
+
+    CRYPTO_atomic_add(&p->references, -1, &i, p->lock);
+    REF_PRINT_COUNT("EC_nistp224", x);
+    if (i > 0)
+        return;
+    REF_ASSERT_ISNT(i < 0);
+
+    CRYPTO_THREAD_lock_free(p->lock);
+    OPENSSL_free(p);
+}
+
+/******************************************************************************/
+/*
+ * OPENSSL EC_METHOD FUNCTIONS
+ */
+
+int ec_GFp_nistp224_group_init(EC_GROUP *group)
+{
+    int ret;
+    ret = ec_GFp_simple_group_init(group);
+    group->a_is_minus3 = 1;
+    return ret;
+}
+
+int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+                                    const BIGNUM *a, const BIGNUM *b,
+                                    BN_CTX *ctx)
+{
+    int ret = 0;
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *curve_p, *curve_a, *curve_b;
+
+    if (ctx == NULL)
+        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+            return 0;
+    BN_CTX_start(ctx);
+    if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
+        ((curve_a = BN_CTX_get(ctx)) == NULL) ||
+        ((curve_b = BN_CTX_get(ctx)) == NULL))
+        goto err;
+    BN_bin2bn(nistp224_curve_params[0], sizeof(felem_bytearray), curve_p);
+    BN_bin2bn(nistp224_curve_params[1], sizeof(felem_bytearray), curve_a);
+    BN_bin2bn(nistp224_curve_params[2], sizeof(felem_bytearray), curve_b);
+    if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) {
+        ECerr(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE,
+              EC_R_WRONG_CURVE_PARAMETERS);
+        goto err;
+    }
+    group->field_mod_func = BN_nist_mod_224;
+    ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+ err:
+    BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+/*
+ * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') =
+ * (X/Z^2, Y/Z^3)
+ */
+int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group,
+                                                 const EC_POINT *point,
+                                                 BIGNUM *x, BIGNUM *y,
+                                                 BN_CTX *ctx)
+{
+    felem z1, z2, x_in, y_in, x_out, y_out;
+    widefelem tmp;
+
+    if (EC_POINT_is_at_infinity(group, point)) {
+        ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
+              EC_R_POINT_AT_INFINITY);
+        return 0;
+    }
+    if ((!BN_to_felem(x_in, point->X)) || (!BN_to_felem(y_in, point->Y)) ||
+        (!BN_to_felem(z1, point->Z)))
+        return 0;
+    felem_inv(z2, z1);
+    felem_square(tmp, z2);
+    felem_reduce(z1, tmp);
+    felem_mul(tmp, x_in, z1);
+    felem_reduce(x_in, tmp);
+    felem_contract(x_out, x_in);
+    if (x != NULL) {
+        if (!felem_to_BN(x, x_out)) {
+            ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
+                  ERR_R_BN_LIB);
+            return 0;
+        }
+    }
+    felem_mul(tmp, z1, z2);
+    felem_reduce(z1, tmp);
+    felem_mul(tmp, y_in, z1);
+    felem_reduce(y_in, tmp);
+    felem_contract(y_out, y_in);
+    if (y != NULL) {
+        if (!felem_to_BN(y, y_out)) {
+            ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES,
+                  ERR_R_BN_LIB);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+static void make_points_affine(size_t num, felem points[ /* num */ ][3],
+                               felem tmp_felems[ /* num+1 */ ])
+{
+    /*
+     * Runs in constant time, unless an input is the point at infinity (which
+     * normally shouldn't happen).
+     */
+    ec_GFp_nistp_points_make_affine_internal(num,
+                                             points,
+                                             sizeof(felem),
+                                             tmp_felems,
+                                             (void (*)(void *))felem_one,
+                                             (int (*)(const void *))
+                                             felem_is_zero_int,
+                                             (void (*)(void *, const void *))
+                                             felem_assign,
+                                             (void (*)(void *, const void *))
+                                             felem_square_reduce, (void (*)
+                                                                   (void *,
+                                                                    const void
+                                                                    *,
+                                                                    const void
+                                                                    *))
+                                             felem_mul_reduce,
+                                             (void (*)(void *, const void *))
+                                             felem_inv,
+                                             (void (*)(void *, const void *))
+                                             felem_contract);
+}
+
+/*
+ * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL
+ * values Result is stored in r (r can equal one of the inputs).
+ */
+int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r,
+                               const BIGNUM *scalar, size_t num,
+                               const EC_POINT *points[],
+                               const BIGNUM *scalars[], BN_CTX *ctx)
+{
+    int ret = 0;
+    int j;
+    unsigned i;
+    int mixed = 0;
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *x, *y, *z, *tmp_scalar;
+    felem_bytearray g_secret;
+    felem_bytearray *secrets = NULL;
+    felem (*pre_comp)[17][3] = NULL;
+    felem *tmp_felems = NULL;
+    felem_bytearray tmp;
+    unsigned num_bytes;
+    int have_pre_comp = 0;
+    size_t num_points = num;
+    felem x_in, y_in, z_in, x_out, y_out, z_out;
+    NISTP224_PRE_COMP *pre = NULL;
+    const felem(*g_pre_comp)[16][3] = NULL;
+    EC_POINT *generator = NULL;
+    const EC_POINT *p = NULL;
+    const BIGNUM *p_scalar = NULL;
+
+    if (ctx == NULL)
+        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+            return 0;
+    BN_CTX_start(ctx);
+    if (((x = BN_CTX_get(ctx)) == NULL) ||
+        ((y = BN_CTX_get(ctx)) == NULL) ||
+        ((z = BN_CTX_get(ctx)) == NULL) ||
+        ((tmp_scalar = BN_CTX_get(ctx)) == NULL))
+        goto err;
+
+    if (scalar != NULL) {
+        pre = group->pre_comp.nistp224;
+        if (pre)
+            /* we have precomputation, try to use it */
+            g_pre_comp = (const felem(*)[16][3])pre->g_pre_comp;
+        else
+            /* try to use the standard precomputation */
+            g_pre_comp = &gmul[0];
+        generator = EC_POINT_new(group);
+        if (generator == NULL)
+            goto err;
+        /* get the generator from precomputation */
+        if (!felem_to_BN(x, g_pre_comp[0][1][0]) ||
+            !felem_to_BN(y, g_pre_comp[0][1][1]) ||
+            !felem_to_BN(z, g_pre_comp[0][1][2])) {
+            ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+            goto err;
+        }
+        if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
+                                                      generator, x, y, z,
+                                                      ctx))
+            goto err;
+        if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
+            /* precomputation matches generator */
+            have_pre_comp = 1;
+        else
+            /*
+             * we don't have valid precomputation: treat the generator as a
+             * random point
+             */
+            num_points = num_points + 1;
+    }
+
+    if (num_points > 0) {
+        if (num_points >= 3) {
+            /*
+             * unless we precompute multiples for just one or two points,
+             * converting those into affine form is time well spent
+             */
+            mixed = 1;
+        }
+        secrets = OPENSSL_zalloc(sizeof(*secrets) * num_points);
+        pre_comp = OPENSSL_zalloc(sizeof(*pre_comp) * num_points);
+        if (mixed)
+            tmp_felems =
+                OPENSSL_malloc(sizeof(felem) * (num_points * 17 + 1));
+        if ((secrets == NULL) || (pre_comp == NULL)
+            || (mixed && (tmp_felems == NULL))) {
+            ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+
+        /*
+         * we treat NULL scalars as 0, and NULL points as points at infinity,
+         * i.e., they contribute nothing to the linear combination
+         */
+        for (i = 0; i < num_points; ++i) {
+            if (i == num)
+                /* the generator */
+            {
+                p = EC_GROUP_get0_generator(group);
+                p_scalar = scalar;
+            } else
+                /* the i^th point */
+            {
+                p = points[i];
+                p_scalar = scalars[i];
+            }
+            if ((p_scalar != NULL) && (p != NULL)) {
+                /* reduce scalar to 0 <= scalar < 2^224 */
+                if ((BN_num_bits(p_scalar) > 224)
+                    || (BN_is_negative(p_scalar))) {
+                    /*
+                     * this is an unusual input, and we don't guarantee
+                     * constant-timeness
+                     */
+                    if (!BN_nnmod(tmp_scalar, p_scalar, group->order, ctx)) {
+                        ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+                        goto err;
+                    }
+                    num_bytes = BN_bn2bin(tmp_scalar, tmp);
+                } else
+                    num_bytes = BN_bn2bin(p_scalar, tmp);
+                flip_endian(secrets[i], tmp, num_bytes);
+                /* precompute multiples */
+                if ((!BN_to_felem(x_out, p->X)) ||
+                    (!BN_to_felem(y_out, p->Y)) ||
+                    (!BN_to_felem(z_out, p->Z)))
+                    goto err;
+                felem_assign(pre_comp[i][1][0], x_out);
+                felem_assign(pre_comp[i][1][1], y_out);
+                felem_assign(pre_comp[i][1][2], z_out);
+                for (j = 2; j <= 16; ++j) {
+                    if (j & 1) {
+                        point_add(pre_comp[i][j][0], pre_comp[i][j][1],
+                                  pre_comp[i][j][2], pre_comp[i][1][0],
+                                  pre_comp[i][1][1], pre_comp[i][1][2], 0,
+                                  pre_comp[i][j - 1][0],
+                                  pre_comp[i][j - 1][1],
+                                  pre_comp[i][j - 1][2]);
+                    } else {
+                        point_double(pre_comp[i][j][0], pre_comp[i][j][1],
+                                     pre_comp[i][j][2], pre_comp[i][j / 2][0],
+                                     pre_comp[i][j / 2][1],
+                                     pre_comp[i][j / 2][2]);
+                    }
+                }
+            }
+        }
+        if (mixed)
+            make_points_affine(num_points * 17, pre_comp[0], tmp_felems);
+    }
+
+    /* the scalar for the generator */
+    if ((scalar != NULL) && (have_pre_comp)) {
+        memset(g_secret, 0, sizeof(g_secret));
+        /* reduce scalar to 0 <= scalar < 2^224 */
+        if ((BN_num_bits(scalar) > 224) || (BN_is_negative(scalar))) {
+            /*
+             * this is an unusual input, and we don't guarantee
+             * constant-timeness
+             */
+            if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) {
+                ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+                goto err;
+            }
+            num_bytes = BN_bn2bin(tmp_scalar, tmp);
+        } else
+            num_bytes = BN_bn2bin(scalar, tmp);
+        flip_endian(g_secret, tmp, num_bytes);
+        /* do the multiplication with generator precomputation */
+        batch_mul(x_out, y_out, z_out,
+                  (const felem_bytearray(*))secrets, num_points,
+                  g_secret,
+                  mixed, (const felem(*)[17][3])pre_comp, g_pre_comp);
+    } else
+        /* do the multiplication without generator precomputation */
+        batch_mul(x_out, y_out, z_out,
+                  (const felem_bytearray(*))secrets, num_points,
+                  NULL, mixed, (const felem(*)[17][3])pre_comp, NULL);
+    /* reduce the output to its unique minimal representation */
+    felem_contract(x_in, x_out);
+    felem_contract(y_in, y_out);
+    felem_contract(z_in, z_out);
+    if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) ||
+        (!felem_to_BN(z, z_in))) {
+        ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB);
+        goto err;
+    }
+    ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
+
+ err:
+    BN_CTX_end(ctx);
+    EC_POINT_free(generator);
+    BN_CTX_free(new_ctx);
+    OPENSSL_free(secrets);
+    OPENSSL_free(pre_comp);
+    OPENSSL_free(tmp_felems);
+    return ret;
+}
+
+int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+{
+    int ret = 0;
+    NISTP224_PRE_COMP *pre = NULL;
+    int i, j;
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *x, *y;
+    EC_POINT *generator = NULL;
+    felem tmp_felems[32];
+
+    /* throw away old precomputation */
+    EC_pre_comp_free(group);
+    if (ctx == NULL)
+        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+            return 0;
+    BN_CTX_start(ctx);
+    if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL))
+        goto err;
+    /* get the generator */
+    if (group->generator == NULL)
+        goto err;
+    generator = EC_POINT_new(group);
+    if (generator == NULL)
+        goto err;
+    BN_bin2bn(nistp224_curve_params[3], sizeof(felem_bytearray), x);
+    BN_bin2bn(nistp224_curve_params[4], sizeof(felem_bytearray), y);
+    if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
+        goto err;
+    if ((pre = nistp224_pre_comp_new()) == NULL)
+        goto err;
+    /*
+     * if the generator is the standard one, use built-in precomputation
+     */
+    if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) {
+        memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
+        goto done;
+    }
+    if ((!BN_to_felem(pre->g_pre_comp[0][1][0], group->generator->X)) ||
+        (!BN_to_felem(pre->g_pre_comp[0][1][1], group->generator->Y)) ||
+        (!BN_to_felem(pre->g_pre_comp[0][1][2], group->generator->Z)))
+        goto err;
+    /*
+     * compute 2^56*G, 2^112*G, 2^168*G for the first table, 2^28*G, 2^84*G,
+     * 2^140*G, 2^196*G for the second one
+     */
+    for (i = 1; i <= 8; i <<= 1) {
+        point_double(pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1],
+                     pre->g_pre_comp[1][i][2], pre->g_pre_comp[0][i][0],
+                     pre->g_pre_comp[0][i][1], pre->g_pre_comp[0][i][2]);
+        for (j = 0; j < 27; ++j) {
+            point_double(pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1],
+                         pre->g_pre_comp[1][i][2], pre->g_pre_comp[1][i][0],
+                         pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
+        }
+        if (i == 8)
+            break;
+        point_double(pre->g_pre_comp[0][2 * i][0],
+                     pre->g_pre_comp[0][2 * i][1],
+                     pre->g_pre_comp[0][2 * i][2], pre->g_pre_comp[1][i][0],
+                     pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]);
+        for (j = 0; j < 27; ++j) {
+            point_double(pre->g_pre_comp[0][2 * i][0],
+                         pre->g_pre_comp[0][2 * i][1],
+                         pre->g_pre_comp[0][2 * i][2],
+                         pre->g_pre_comp[0][2 * i][0],
+                         pre->g_pre_comp[0][2 * i][1],
+                         pre->g_pre_comp[0][2 * i][2]);
+        }
+    }
+    for (i = 0; i < 2; i++) {
+        /* g_pre_comp[i][0] is the point at infinity */
+        memset(pre->g_pre_comp[i][0], 0, sizeof(pre->g_pre_comp[i][0]));
+        /* the remaining multiples */
+        /* 2^56*G + 2^112*G resp. 2^84*G + 2^140*G */
+        point_add(pre->g_pre_comp[i][6][0], pre->g_pre_comp[i][6][1],
+                  pre->g_pre_comp[i][6][2], pre->g_pre_comp[i][4][0],
+                  pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2],
+                  0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
+                  pre->g_pre_comp[i][2][2]);
+        /* 2^56*G + 2^168*G resp. 2^84*G + 2^196*G */
+        point_add(pre->g_pre_comp[i][10][0], pre->g_pre_comp[i][10][1],
+                  pre->g_pre_comp[i][10][2], pre->g_pre_comp[i][8][0],
+                  pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
+                  0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
+                  pre->g_pre_comp[i][2][2]);
+        /* 2^112*G + 2^168*G resp. 2^140*G + 2^196*G */
+        point_add(pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1],
+                  pre->g_pre_comp[i][12][2], pre->g_pre_comp[i][8][0],
+                  pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
+                  0, pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1],
+                  pre->g_pre_comp[i][4][2]);
+        /*
+         * 2^56*G + 2^112*G + 2^168*G resp. 2^84*G + 2^140*G + 2^196*G
+         */
+        point_add(pre->g_pre_comp[i][14][0], pre->g_pre_comp[i][14][1],
+                  pre->g_pre_comp[i][14][2], pre->g_pre_comp[i][12][0],
+                  pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2],
+                  0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
+                  pre->g_pre_comp[i][2][2]);
+        for (j = 1; j < 8; ++j) {
+            /* odd multiples: add G resp. 2^28*G */
+            point_add(pre->g_pre_comp[i][2 * j + 1][0],
+                      pre->g_pre_comp[i][2 * j + 1][1],
+                      pre->g_pre_comp[i][2 * j + 1][2],
+                      pre->g_pre_comp[i][2 * j][0],
+                      pre->g_pre_comp[i][2 * j][1],
+                      pre->g_pre_comp[i][2 * j][2], 0,
+                      pre->g_pre_comp[i][1][0], pre->g_pre_comp[i][1][1],
+                      pre->g_pre_comp[i][1][2]);
+        }
+    }
+    make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_felems);
+
+ done:
+    SETPRECOMP(group, nistp224, pre);
+    pre = NULL;
+    ret = 1;
+ err:
+    BN_CTX_end(ctx);
+    EC_POINT_free(generator);
+    BN_CTX_free(new_ctx);
+    EC_nistp224_pre_comp_free(pre);
+    return ret;
+}
+
+int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group)
+{
+    return HAVEPRECOMP(group, nistp224);
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_nistp256.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_nistp256.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_nistp256.c	(revision 331)
@@ -0,0 +1,2350 @@
+/*
+ * Copyright 2011-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
+ */
+
+/* Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ *
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/*
+ * A 64-bit implementation of the NIST P-256 elliptic curve point multiplication
+ *
+ * OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c.
+ * Otherwise based on Emilia's P224 work, which was inspired by my curve25519
+ * work which got its smarts from Daniel J. Bernstein's work on the same.
+ */
+
+#include <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <stdint.h>
+# include <string.h>
+# include <openssl/err.h>
+# include "ec_lcl.h"
+
+# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+  /* even with gcc, the typedef won't work for 32-bit platforms */
+typedef __uint128_t uint128_t;  /* nonstandard; implemented by gcc on 64-bit
+                                 * platforms */
+typedef __int128_t int128_t;
+# else
+#  error "Need GCC 3.1 or later to define type uint128_t"
+# endif
+
+typedef uint8_t u8;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef int64_t s64;
+
+/*
+ * The underlying field. P256 operates over GF(2^256-2^224+2^192+2^96-1). We
+ * can serialise an element of this field into 32 bytes. We call this an
+ * felem_bytearray.
+ */
+
+typedef u8 felem_bytearray[32];
+
+/*
+ * These are the parameters of P256, taken from FIPS 186-3, page 86. These
+ * values are big-endian.
+ */
+static const felem_bytearray nistp256_curve_params[5] = {
+    {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* p */
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+    {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* a = -3 */
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc}, /* b */
+    {0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7,
+     0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc,
+     0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
+     0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b},
+    {0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, /* x */
+     0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2,
+     0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
+     0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96},
+    {0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, /* y */
+     0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
+     0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
+     0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5}
+};
+
+/*-
+ * The representation of field elements.
+ * ------------------------------------
+ *
+ * We represent field elements with either four 128-bit values, eight 128-bit
+ * values, or four 64-bit values. The field element represented is:
+ *   v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + v[3]*2^192  (mod p)
+ * or:
+ *   v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + ... + v[8]*2^512  (mod p)
+ *
+ * 128-bit values are called 'limbs'. Since the limbs are spaced only 64 bits
+ * apart, but are 128-bits wide, the most significant bits of each limb overlap
+ * with the least significant bits of the next.
+ *
+ * A field element with four limbs is an 'felem'. One with eight limbs is a
+ * 'longfelem'
+ *
+ * A field element with four, 64-bit values is called a 'smallfelem'. Small
+ * values are used as intermediate values before multiplication.
+ */
+
+# define NLIMBS 4
+
+typedef uint128_t limb;
+typedef limb felem[NLIMBS];
+typedef limb longfelem[NLIMBS * 2];
+typedef u64 smallfelem[NLIMBS];
+
+/* This is the value of the prime as four 64-bit words, little-endian. */
+static const u64 kPrime[4] =
+    { 0xfffffffffffffffful, 0xffffffff, 0, 0xffffffff00000001ul };
+static const u64 bottom63bits = 0x7ffffffffffffffful;
+
+/*
+ * bin32_to_felem takes a little-endian byte array and converts it into felem
+ * form. This assumes that the CPU is little-endian.
+ */
+static void bin32_to_felem(felem out, const u8 in[32])
+{
+    out[0] = *((u64 *)&in[0]);
+    out[1] = *((u64 *)&in[8]);
+    out[2] = *((u64 *)&in[16]);
+    out[3] = *((u64 *)&in[24]);
+}
+
+/*
+ * smallfelem_to_bin32 takes a smallfelem and serialises into a little
+ * endian, 32 byte array. This assumes that the CPU is little-endian.
+ */
+static void smallfelem_to_bin32(u8 out[32], const smallfelem in)
+{
+    *((u64 *)&out[0]) = in[0];
+    *((u64 *)&out[8]) = in[1];
+    *((u64 *)&out[16]) = in[2];
+    *((u64 *)&out[24]) = in[3];
+}
+
+/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
+static void flip_endian(u8 *out, const u8 *in, unsigned len)
+{
+    unsigned i;
+    for (i = 0; i < len; ++i)
+        out[i] = in[len - 1 - i];
+}
+
+/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
+static int BN_to_felem(felem out, const BIGNUM *bn)
+{
+    felem_bytearray b_in;
+    felem_bytearray b_out;
+    unsigned num_bytes;
+
+    /* BN_bn2bin eats leading zeroes */
+    memset(b_out, 0, sizeof(b_out));
+    num_bytes = BN_num_bytes(bn);
+    if (num_bytes > sizeof b_out) {
+        ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+        return 0;
+    }
+    if (BN_is_negative(bn)) {
+        ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+        return 0;
+    }
+    num_bytes = BN_bn2bin(bn, b_in);
+    flip_endian(b_out, b_in, num_bytes);
+    bin32_to_felem(out, b_out);
+    return 1;
+}
+
+/* felem_to_BN converts an felem into an OpenSSL BIGNUM */
+static BIGNUM *smallfelem_to_BN(BIGNUM *out, const smallfelem in)
+{
+    felem_bytearray b_in, b_out;
+    smallfelem_to_bin32(b_in, in);
+    flip_endian(b_out, b_in, sizeof b_out);
+    return BN_bin2bn(b_out, sizeof b_out, out);
+}
+
+/*-
+ * Field operations
+ * ----------------
+ */
+
+static void smallfelem_one(smallfelem out)
+{
+    out[0] = 1;
+    out[1] = 0;
+    out[2] = 0;
+    out[3] = 0;
+}
+
+static void smallfelem_assign(smallfelem out, const smallfelem in)
+{
+    out[0] = in[0];
+    out[1] = in[1];
+    out[2] = in[2];
+    out[3] = in[3];
+}
+
+static void felem_assign(felem out, const felem in)
+{
+    out[0] = in[0];
+    out[1] = in[1];
+    out[2] = in[2];
+    out[3] = in[3];
+}
+
+/* felem_sum sets out = out + in. */
+static void felem_sum(felem out, const felem in)
+{
+    out[0] += in[0];
+    out[1] += in[1];
+    out[2] += in[2];
+    out[3] += in[3];
+}
+
+/* felem_small_sum sets out = out + in. */
+static void felem_small_sum(felem out, const smallfelem in)
+{
+    out[0] += in[0];
+    out[1] += in[1];
+    out[2] += in[2];
+    out[3] += in[3];
+}
+
+/* felem_scalar sets out = out * scalar */
+static void felem_scalar(felem out, const u64 scalar)
+{
+    out[0] *= scalar;
+    out[1] *= scalar;
+    out[2] *= scalar;
+    out[3] *= scalar;
+}
+
+/* longfelem_scalar sets out = out * scalar */
+static void longfelem_scalar(longfelem out, const u64 scalar)
+{
+    out[0] *= scalar;
+    out[1] *= scalar;
+    out[2] *= scalar;
+    out[3] *= scalar;
+    out[4] *= scalar;
+    out[5] *= scalar;
+    out[6] *= scalar;
+    out[7] *= scalar;
+}
+
+# define two105m41m9 (((limb)1) << 105) - (((limb)1) << 41) - (((limb)1) << 9)
+# define two105 (((limb)1) << 105)
+# define two105m41p9 (((limb)1) << 105) - (((limb)1) << 41) + (((limb)1) << 9)
+
+/* zero105 is 0 mod p */
+static const felem zero105 =
+    { two105m41m9, two105, two105m41p9, two105m41p9 };
+
+/*-
+ * smallfelem_neg sets |out| to |-small|
+ * On exit:
+ *   out[i] < out[i] + 2^105
+ */
+static void smallfelem_neg(felem out, const smallfelem small)
+{
+    /* In order to prevent underflow, we subtract from 0 mod p. */
+    out[0] = zero105[0] - small[0];
+    out[1] = zero105[1] - small[1];
+    out[2] = zero105[2] - small[2];
+    out[3] = zero105[3] - small[3];
+}
+
+/*-
+ * felem_diff subtracts |in| from |out|
+ * On entry:
+ *   in[i] < 2^104
+ * On exit:
+ *   out[i] < out[i] + 2^105
+ */
+static void felem_diff(felem out, const felem in)
+{
+    /*
+     * In order to prevent underflow, we add 0 mod p before subtracting.
+     */
+    out[0] += zero105[0];
+    out[1] += zero105[1];
+    out[2] += zero105[2];
+    out[3] += zero105[3];
+
+    out[0] -= in[0];
+    out[1] -= in[1];
+    out[2] -= in[2];
+    out[3] -= in[3];
+}
+
+# define two107m43m11 (((limb)1) << 107) - (((limb)1) << 43) - (((limb)1) << 11)
+# define two107 (((limb)1) << 107)
+# define two107m43p11 (((limb)1) << 107) - (((limb)1) << 43) + (((limb)1) << 11)
+
+/* zero107 is 0 mod p */
+static const felem zero107 =
+    { two107m43m11, two107, two107m43p11, two107m43p11 };
+
+/*-
+ * An alternative felem_diff for larger inputs |in|
+ * felem_diff_zero107 subtracts |in| from |out|
+ * On entry:
+ *   in[i] < 2^106
+ * On exit:
+ *   out[i] < out[i] + 2^107
+ */
+static void felem_diff_zero107(felem out, const felem in)
+{
+    /*
+     * In order to prevent underflow, we add 0 mod p before subtracting.
+     */
+    out[0] += zero107[0];
+    out[1] += zero107[1];
+    out[2] += zero107[2];
+    out[3] += zero107[3];
+
+    out[0] -= in[0];
+    out[1] -= in[1];
+    out[2] -= in[2];
+    out[3] -= in[3];
+}
+
+/*-
+ * longfelem_diff subtracts |in| from |out|
+ * On entry:
+ *   in[i] < 7*2^67
+ * On exit:
+ *   out[i] < out[i] + 2^70 + 2^40
+ */
+static void longfelem_diff(longfelem out, const longfelem in)
+{
+    static const limb two70m8p6 =
+        (((limb) 1) << 70) - (((limb) 1) << 8) + (((limb) 1) << 6);
+    static const limb two70p40 = (((limb) 1) << 70) + (((limb) 1) << 40);
+    static const limb two70 = (((limb) 1) << 70);
+    static const limb two70m40m38p6 =
+        (((limb) 1) << 70) - (((limb) 1) << 40) - (((limb) 1) << 38) +
+        (((limb) 1) << 6);
+    static const limb two70m6 = (((limb) 1) << 70) - (((limb) 1) << 6);
+
+    /* add 0 mod p to avoid underflow */
+    out[0] += two70m8p6;
+    out[1] += two70p40;
+    out[2] += two70;
+    out[3] += two70m40m38p6;
+    out[4] += two70m6;
+    out[5] += two70m6;
+    out[6] += two70m6;
+    out[7] += two70m6;
+
+    /* in[i] < 7*2^67 < 2^70 - 2^40 - 2^38 + 2^6 */
+    out[0] -= in[0];
+    out[1] -= in[1];
+    out[2] -= in[2];
+    out[3] -= in[3];
+    out[4] -= in[4];
+    out[5] -= in[5];
+    out[6] -= in[6];
+    out[7] -= in[7];
+}
+
+# define two64m0 (((limb)1) << 64) - 1
+# define two110p32m0 (((limb)1) << 110) + (((limb)1) << 32) - 1
+# define two64m46 (((limb)1) << 64) - (((limb)1) << 46)
+# define two64m32 (((limb)1) << 64) - (((limb)1) << 32)
+
+/* zero110 is 0 mod p */
+static const felem zero110 = { two64m0, two110p32m0, two64m46, two64m32 };
+
+/*-
+ * felem_shrink converts an felem into a smallfelem. The result isn't quite
+ * minimal as the value may be greater than p.
+ *
+ * On entry:
+ *   in[i] < 2^109
+ * On exit:
+ *   out[i] < 2^64
+ */
+static void felem_shrink(smallfelem out, const felem in)
+{
+    felem tmp;
+    u64 a, b, mask;
+    s64 high, low;
+    static const u64 kPrime3Test = 0x7fffffff00000001ul; /* 2^63 - 2^32 + 1 */
+
+    /* Carry 2->3 */
+    tmp[3] = zero110[3] + in[3] + ((u64)(in[2] >> 64));
+    /* tmp[3] < 2^110 */
+
+    tmp[2] = zero110[2] + (u64)in[2];
+    tmp[0] = zero110[0] + in[0];
+    tmp[1] = zero110[1] + in[1];
+    /* tmp[0] < 2**110, tmp[1] < 2^111, tmp[2] < 2**65 */
+
+    /*
+     * We perform two partial reductions where we eliminate the high-word of
+     * tmp[3]. We don't update the other words till the end.
+     */
+    a = tmp[3] >> 64;           /* a < 2^46 */
+    tmp[3] = (u64)tmp[3];
+    tmp[3] -= a;
+    tmp[3] += ((limb) a) << 32;
+    /* tmp[3] < 2^79 */
+
+    b = a;
+    a = tmp[3] >> 64;           /* a < 2^15 */
+    b += a;                     /* b < 2^46 + 2^15 < 2^47 */
+    tmp[3] = (u64)tmp[3];
+    tmp[3] -= a;
+    tmp[3] += ((limb) a) << 32;
+    /* tmp[3] < 2^64 + 2^47 */
+
+    /*
+     * This adjusts the other two words to complete the two partial
+     * reductions.
+     */
+    tmp[0] += b;
+    tmp[1] -= (((limb) b) << 32);
+
+    /*
+     * In order to make space in tmp[3] for the carry from 2 -> 3, we
+     * conditionally subtract kPrime if tmp[3] is large enough.
+     */
+    high = tmp[3] >> 64;
+    /* As tmp[3] < 2^65, high is either 1 or 0 */
+    high <<= 63;
+    high >>= 63;
+    /*-
+     * high is:
+     *   all ones   if the high word of tmp[3] is 1
+     *   all zeros  if the high word of tmp[3] if 0 */
+    low = tmp[3];
+    mask = low >> 63;
+    /*-
+     * mask is:
+     *   all ones   if the MSB of low is 1
+     *   all zeros  if the MSB of low if 0 */
+    low &= bottom63bits;
+    low -= kPrime3Test;
+    /* if low was greater than kPrime3Test then the MSB is zero */
+    low = ~low;
+    low >>= 63;
+    /*-
+     * low is:
+     *   all ones   if low was > kPrime3Test
+     *   all zeros  if low was <= kPrime3Test */
+    mask = (mask & low) | high;
+    tmp[0] -= mask & kPrime[0];
+    tmp[1] -= mask & kPrime[1];
+    /* kPrime[2] is zero, so omitted */
+    tmp[3] -= mask & kPrime[3];
+    /* tmp[3] < 2**64 - 2**32 + 1 */
+
+    tmp[1] += ((u64)(tmp[0] >> 64));
+    tmp[0] = (u64)tmp[0];
+    tmp[2] += ((u64)(tmp[1] >> 64));
+    tmp[1] = (u64)tmp[1];
+    tmp[3] += ((u64)(tmp[2] >> 64));
+    tmp[2] = (u64)tmp[2];
+    /* tmp[i] < 2^64 */
+
+    out[0] = tmp[0];
+    out[1] = tmp[1];
+    out[2] = tmp[2];
+    out[3] = tmp[3];
+}
+
+/* smallfelem_expand converts a smallfelem to an felem */
+static void smallfelem_expand(felem out, const smallfelem in)
+{
+    out[0] = in[0];
+    out[1] = in[1];
+    out[2] = in[2];
+    out[3] = in[3];
+}
+
+/*-
+ * smallfelem_square sets |out| = |small|^2
+ * On entry:
+ *   small[i] < 2^64
+ * On exit:
+ *   out[i] < 7 * 2^64 < 2^67
+ */
+static void smallfelem_square(longfelem out, const smallfelem small)
+{
+    limb a;
+    u64 high, low;
+
+    a = ((uint128_t) small[0]) * small[0];
+    low = a;
+    high = a >> 64;
+    out[0] = low;
+    out[1] = high;
+
+    a = ((uint128_t) small[0]) * small[1];
+    low = a;
+    high = a >> 64;
+    out[1] += low;
+    out[1] += low;
+    out[2] = high;
+
+    a = ((uint128_t) small[0]) * small[2];
+    low = a;
+    high = a >> 64;
+    out[2] += low;
+    out[2] *= 2;
+    out[3] = high;
+
+    a = ((uint128_t) small[0]) * small[3];
+    low = a;
+    high = a >> 64;
+    out[3] += low;
+    out[4] = high;
+
+    a = ((uint128_t) small[1]) * small[2];
+    low = a;
+    high = a >> 64;
+    out[3] += low;
+    out[3] *= 2;
+    out[4] += high;
+
+    a = ((uint128_t) small[1]) * small[1];
+    low = a;
+    high = a >> 64;
+    out[2] += low;
+    out[3] += high;
+
+    a = ((uint128_t) small[1]) * small[3];
+    low = a;
+    high = a >> 64;
+    out[4] += low;
+    out[4] *= 2;
+    out[5] = high;
+
+    a = ((uint128_t) small[2]) * small[3];
+    low = a;
+    high = a >> 64;
+    out[5] += low;
+    out[5] *= 2;
+    out[6] = high;
+    out[6] += high;
+
+    a = ((uint128_t) small[2]) * small[2];
+    low = a;
+    high = a >> 64;
+    out[4] += low;
+    out[5] += high;
+
+    a = ((uint128_t) small[3]) * small[3];
+    low = a;
+    high = a >> 64;
+    out[6] += low;
+    out[7] = high;
+}
+
+/*-
+ * felem_square sets |out| = |in|^2
+ * On entry:
+ *   in[i] < 2^109
+ * On exit:
+ *   out[i] < 7 * 2^64 < 2^67
+ */
+static void felem_square(longfelem out, const felem in)
+{
+    u64 small[4];
+    felem_shrink(small, in);
+    smallfelem_square(out, small);
+}
+
+/*-
+ * smallfelem_mul sets |out| = |small1| * |small2|
+ * On entry:
+ *   small1[i] < 2^64
+ *   small2[i] < 2^64
+ * On exit:
+ *   out[i] < 7 * 2^64 < 2^67
+ */
+static void smallfelem_mul(longfelem out, const smallfelem small1,
+                           const smallfelem small2)
+{
+    limb a;
+    u64 high, low;
+
+    a = ((uint128_t) small1[0]) * small2[0];
+    low = a;
+    high = a >> 64;
+    out[0] = low;
+    out[1] = high;
+
+    a = ((uint128_t) small1[0]) * small2[1];
+    low = a;
+    high = a >> 64;
+    out[1] += low;
+    out[2] = high;
+
+    a = ((uint128_t) small1[1]) * small2[0];
+    low = a;
+    high = a >> 64;
+    out[1] += low;
+    out[2] += high;
+
+    a = ((uint128_t) small1[0]) * small2[2];
+    low = a;
+    high = a >> 64;
+    out[2] += low;
+    out[3] = high;
+
+    a = ((uint128_t) small1[1]) * small2[1];
+    low = a;
+    high = a >> 64;
+    out[2] += low;
+    out[3] += high;
+
+    a = ((uint128_t) small1[2]) * small2[0];
+    low = a;
+    high = a >> 64;
+    out[2] += low;
+    out[3] += high;
+
+    a = ((uint128_t) small1[0]) * small2[3];
+    low = a;
+    high = a >> 64;
+    out[3] += low;
+    out[4] = high;
+
+    a = ((uint128_t) small1[1]) * small2[2];
+    low = a;
+    high = a >> 64;
+    out[3] += low;
+    out[4] += high;
+
+    a = ((uint128_t) small1[2]) * small2[1];
+    low = a;
+    high = a >> 64;
+    out[3] += low;
+    out[4] += high;
+
+    a = ((uint128_t) small1[3]) * small2[0];
+    low = a;
+    high = a >> 64;
+    out[3] += low;
+    out[4] += high;
+
+    a = ((uint128_t) small1[1]) * small2[3];
+    low = a;
+    high = a >> 64;
+    out[4] += low;
+    out[5] = high;
+
+    a = ((uint128_t) small1[2]) * small2[2];
+    low = a;
+    high = a >> 64;
+    out[4] += low;
+    out[5] += high;
+
+    a = ((uint128_t) small1[3]) * small2[1];
+    low = a;
+    high = a >> 64;
+    out[4] += low;
+    out[5] += high;
+
+    a = ((uint128_t) small1[2]) * small2[3];
+    low = a;
+    high = a >> 64;
+    out[5] += low;
+    out[6] = high;
+
+    a = ((uint128_t) small1[3]) * small2[2];
+    low = a;
+    high = a >> 64;
+    out[5] += low;
+    out[6] += high;
+
+    a = ((uint128_t) small1[3]) * small2[3];
+    low = a;
+    high = a >> 64;
+    out[6] += low;
+    out[7] = high;
+}
+
+/*-
+ * felem_mul sets |out| = |in1| * |in2|
+ * On entry:
+ *   in1[i] < 2^109
+ *   in2[i] < 2^109
+ * On exit:
+ *   out[i] < 7 * 2^64 < 2^67
+ */
+static void felem_mul(longfelem out, const felem in1, const felem in2)
+{
+    smallfelem small1, small2;
+    felem_shrink(small1, in1);
+    felem_shrink(small2, in2);
+    smallfelem_mul(out, small1, small2);
+}
+
+/*-
+ * felem_small_mul sets |out| = |small1| * |in2|
+ * On entry:
+ *   small1[i] < 2^64
+ *   in2[i] < 2^109
+ * On exit:
+ *   out[i] < 7 * 2^64 < 2^67
+ */
+static void felem_small_mul(longfelem out, const smallfelem small1,
+                            const felem in2)
+{
+    smallfelem small2;
+    felem_shrink(small2, in2);
+    smallfelem_mul(out, small1, small2);
+}
+
+# define two100m36m4 (((limb)1) << 100) - (((limb)1) << 36) - (((limb)1) << 4)
+# define two100 (((limb)1) << 100)
+# define two100m36p4 (((limb)1) << 100) - (((limb)1) << 36) + (((limb)1) << 4)
+/* zero100 is 0 mod p */
+static const felem zero100 =
+    { two100m36m4, two100, two100m36p4, two100m36p4 };
+
+/*-
+ * Internal function for the different flavours of felem_reduce.
+ * felem_reduce_ reduces the higher coefficients in[4]-in[7].
+ * On entry:
+ *   out[0] >= in[6] + 2^32*in[6] + in[7] + 2^32*in[7]
+ *   out[1] >= in[7] + 2^32*in[4]
+ *   out[2] >= in[5] + 2^32*in[5]
+ *   out[3] >= in[4] + 2^32*in[5] + 2^32*in[6]
+ * On exit:
+ *   out[0] <= out[0] + in[4] + 2^32*in[5]
+ *   out[1] <= out[1] + in[5] + 2^33*in[6]
+ *   out[2] <= out[2] + in[7] + 2*in[6] + 2^33*in[7]
+ *   out[3] <= out[3] + 2^32*in[4] + 3*in[7]
+ */
+static void felem_reduce_(felem out, const longfelem in)
+{
+    int128_t c;
+    /* combine common terms from below */
+    c = in[4] + (in[5] << 32);
+    out[0] += c;
+    out[3] -= c;
+
+    c = in[5] - in[7];
+    out[1] += c;
+    out[2] -= c;
+
+    /* the remaining terms */
+    /* 256: [(0,1),(96,-1),(192,-1),(224,1)] */
+    out[1] -= (in[4] << 32);
+    out[3] += (in[4] << 32);
+
+    /* 320: [(32,1),(64,1),(128,-1),(160,-1),(224,-1)] */
+    out[2] -= (in[5] << 32);
+
+    /* 384: [(0,-1),(32,-1),(96,2),(128,2),(224,-1)] */
+    out[0] -= in[6];
+    out[0] -= (in[6] << 32);
+    out[1] += (in[6] << 33);
+    out[2] += (in[6] * 2);
+    out[3] -= (in[6] << 32);
+
+    /* 448: [(0,-1),(32,-1),(64,-1),(128,1),(160,2),(192,3)] */
+    out[0] -= in[7];
+    out[0] -= (in[7] << 32);
+    out[2] += (in[7] << 33);
+    out[3] += (in[7] * 3);
+}
+
+/*-
+ * felem_reduce converts a longfelem into an felem.
+ * To be called directly after felem_square or felem_mul.
+ * On entry:
+ *   in[0] < 2^64, in[1] < 3*2^64, in[2] < 5*2^64, in[3] < 7*2^64
+ *   in[4] < 7*2^64, in[5] < 5*2^64, in[6] < 3*2^64, in[7] < 2*64
+ * On exit:
+ *   out[i] < 2^101
+ */
+static void felem_reduce(felem out, const longfelem in)
+{
+    out[0] = zero100[0] + in[0];
+    out[1] = zero100[1] + in[1];
+    out[2] = zero100[2] + in[2];
+    out[3] = zero100[3] + in[3];
+
+    felem_reduce_(out, in);
+
+    /*-
+     * out[0] > 2^100 - 2^36 - 2^4 - 3*2^64 - 3*2^96 - 2^64 - 2^96 > 0
+     * out[1] > 2^100 - 2^64 - 7*2^96 > 0
+     * out[2] > 2^100 - 2^36 + 2^4 - 5*2^64 - 5*2^96 > 0
+     * out[3] > 2^100 - 2^36 + 2^4 - 7*2^64 - 5*2^96 - 3*2^96 > 0
+     *
+     * out[0] < 2^100 + 2^64 + 7*2^64 + 5*2^96 < 2^101
+     * out[1] < 2^100 + 3*2^64 + 5*2^64 + 3*2^97 < 2^101
+     * out[2] < 2^100 + 5*2^64 + 2^64 + 3*2^65 + 2^97 < 2^101
+     * out[3] < 2^100 + 7*2^64 + 7*2^96 + 3*2^64 < 2^101
+     */
+}
+
+/*-
+ * felem_reduce_zero105 converts a larger longfelem into an felem.
+ * On entry:
+ *   in[0] < 2^71
+ * On exit:
+ *   out[i] < 2^106
+ */
+static void felem_reduce_zero105(felem out, const longfelem in)
+{
+    out[0] = zero105[0] + in[0];
+    out[1] = zero105[1] + in[1];
+    out[2] = zero105[2] + in[2];
+    out[3] = zero105[3] + in[3];
+
+    felem_reduce_(out, in);
+
+    /*-
+     * out[0] > 2^105 - 2^41 - 2^9 - 2^71 - 2^103 - 2^71 - 2^103 > 0
+     * out[1] > 2^105 - 2^71 - 2^103 > 0
+     * out[2] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 > 0
+     * out[3] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 - 2^103 > 0
+     *
+     * out[0] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106
+     * out[1] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106
+     * out[2] < 2^105 + 2^71 + 2^71 + 2^71 + 2^103 < 2^106
+     * out[3] < 2^105 + 2^71 + 2^103 + 2^71 < 2^106
+     */
+}
+
+/*
+ * subtract_u64 sets *result = *result - v and *carry to one if the
+ * subtraction underflowed.
+ */
+static void subtract_u64(u64 *result, u64 *carry, u64 v)
+{
+    uint128_t r = *result;
+    r -= v;
+    *carry = (r >> 64) & 1;
+    *result = (u64)r;
+}
+
+/*
+ * felem_contract converts |in| to its unique, minimal representation. On
+ * entry: in[i] < 2^109
+ */
+static void felem_contract(smallfelem out, const felem in)
+{
+    unsigned i;
+    u64 all_equal_so_far = 0, result = 0, carry;
+
+    felem_shrink(out, in);
+    /* small is minimal except that the value might be > p */
+
+    all_equal_so_far--;
+    /*
+     * We are doing a constant time test if out >= kPrime. We need to compare
+     * each u64, from most-significant to least significant. For each one, if
+     * all words so far have been equal (m is all ones) then a non-equal
+     * result is the answer. Otherwise we continue.
+     */
+    for (i = 3; i < 4; i--) {
+        u64 equal;
+        uint128_t a = ((uint128_t) kPrime[i]) - out[i];
+        /*
+         * if out[i] > kPrime[i] then a will underflow and the high 64-bits
+         * will all be set.
+         */
+        result |= all_equal_so_far & ((u64)(a >> 64));
+
+        /*
+         * if kPrime[i] == out[i] then |equal| will be all zeros and the
+         * decrement will make it all ones.
+         */
+        equal = kPrime[i] ^ out[i];
+        equal--;
+        equal &= equal << 32;
+        equal &= equal << 16;
+        equal &= equal << 8;
+        equal &= equal << 4;
+        equal &= equal << 2;
+        equal &= equal << 1;
+        equal = ((s64) equal) >> 63;
+
+        all_equal_so_far &= equal;
+    }
+
+    /*
+     * if all_equal_so_far is still all ones then the two values are equal
+     * and so out >= kPrime is true.
+     */
+    result |= all_equal_so_far;
+
+    /* if out >= kPrime then we subtract kPrime. */
+    subtract_u64(&out[0], &carry, result & kPrime[0]);
+    subtract_u64(&out[1], &carry, carry);
+    subtract_u64(&out[2], &carry, carry);
+    subtract_u64(&out[3], &carry, carry);
+
+    subtract_u64(&out[1], &carry, result & kPrime[1]);
+    subtract_u64(&out[2], &carry, carry);
+    subtract_u64(&out[3], &carry, carry);
+
+    subtract_u64(&out[2], &carry, result & kPrime[2]);
+    subtract_u64(&out[3], &carry, carry);
+
+    subtract_u64(&out[3], &carry, result & kPrime[3]);
+}
+
+static void smallfelem_square_contract(smallfelem out, const smallfelem in)
+{
+    longfelem longtmp;
+    felem tmp;
+
+    smallfelem_square(longtmp, in);
+    felem_reduce(tmp, longtmp);
+    felem_contract(out, tmp);
+}
+
+static void smallfelem_mul_contract(smallfelem out, const smallfelem in1,
+                                    const smallfelem in2)
+{
+    longfelem longtmp;
+    felem tmp;
+
+    smallfelem_mul(longtmp, in1, in2);
+    felem_reduce(tmp, longtmp);
+    felem_contract(out, tmp);
+}
+
+/*-
+ * felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0
+ * otherwise.
+ * On entry:
+ *   small[i] < 2^64
+ */
+static limb smallfelem_is_zero(const smallfelem small)
+{
+    limb result;
+    u64 is_p;
+
+    u64 is_zero = small[0] | small[1] | small[2] | small[3];
+    is_zero--;
+    is_zero &= is_zero << 32;
+    is_zero &= is_zero << 16;
+    is_zero &= is_zero << 8;
+    is_zero &= is_zero << 4;
+    is_zero &= is_zero << 2;
+    is_zero &= is_zero << 1;
+    is_zero = ((s64) is_zero) >> 63;
+
+    is_p = (small[0] ^ kPrime[0]) |
+        (small[1] ^ kPrime[1]) |
+        (small[2] ^ kPrime[2]) | (small[3] ^ kPrime[3]);
+    is_p--;
+    is_p &= is_p << 32;
+    is_p &= is_p << 16;
+    is_p &= is_p << 8;
+    is_p &= is_p << 4;
+    is_p &= is_p << 2;
+    is_p &= is_p << 1;
+    is_p = ((s64) is_p) >> 63;
+
+    is_zero |= is_p;
+
+    result = is_zero;
+    result |= ((limb) is_zero) << 64;
+    return result;
+}
+
+static int smallfelem_is_zero_int(const smallfelem small)
+{
+    return (int)(smallfelem_is_zero(small) & ((limb) 1));
+}
+
+/*-
+ * felem_inv calculates |out| = |in|^{-1}
+ *
+ * Based on Fermat's Little Theorem:
+ *   a^p = a (mod p)
+ *   a^{p-1} = 1 (mod p)
+ *   a^{p-2} = a^{-1} (mod p)
+ */
+static void felem_inv(felem out, const felem in)
+{
+    felem ftmp, ftmp2;
+    /* each e_I will hold |in|^{2^I - 1} */
+    felem e2, e4, e8, e16, e32, e64;
+    longfelem tmp;
+    unsigned i;
+
+    felem_square(tmp, in);
+    felem_reduce(ftmp, tmp);    /* 2^1 */
+    felem_mul(tmp, in, ftmp);
+    felem_reduce(ftmp, tmp);    /* 2^2 - 2^0 */
+    felem_assign(e2, ftmp);
+    felem_square(tmp, ftmp);
+    felem_reduce(ftmp, tmp);    /* 2^3 - 2^1 */
+    felem_square(tmp, ftmp);
+    felem_reduce(ftmp, tmp);    /* 2^4 - 2^2 */
+    felem_mul(tmp, ftmp, e2);
+    felem_reduce(ftmp, tmp);    /* 2^4 - 2^0 */
+    felem_assign(e4, ftmp);
+    felem_square(tmp, ftmp);
+    felem_reduce(ftmp, tmp);    /* 2^5 - 2^1 */
+    felem_square(tmp, ftmp);
+    felem_reduce(ftmp, tmp);    /* 2^6 - 2^2 */
+    felem_square(tmp, ftmp);
+    felem_reduce(ftmp, tmp);    /* 2^7 - 2^3 */
+    felem_square(tmp, ftmp);
+    felem_reduce(ftmp, tmp);    /* 2^8 - 2^4 */
+    felem_mul(tmp, ftmp, e4);
+    felem_reduce(ftmp, tmp);    /* 2^8 - 2^0 */
+    felem_assign(e8, ftmp);
+    for (i = 0; i < 8; i++) {
+        felem_square(tmp, ftmp);
+        felem_reduce(ftmp, tmp);
+    }                           /* 2^16 - 2^8 */
+    felem_mul(tmp, ftmp, e8);
+    felem_reduce(ftmp, tmp);    /* 2^16 - 2^0 */
+    felem_assign(e16, ftmp);
+    for (i = 0; i < 16; i++) {
+        felem_square(tmp, ftmp);
+        felem_reduce(ftmp, tmp);
+    }                           /* 2^32 - 2^16 */
+    felem_mul(tmp, ftmp, e16);
+    felem_reduce(ftmp, tmp);    /* 2^32 - 2^0 */
+    felem_assign(e32, ftmp);
+    for (i = 0; i < 32; i++) {
+        felem_square(tmp, ftmp);
+        felem_reduce(ftmp, tmp);
+    }                           /* 2^64 - 2^32 */
+    felem_assign(e64, ftmp);
+    felem_mul(tmp, ftmp, in);
+    felem_reduce(ftmp, tmp);    /* 2^64 - 2^32 + 2^0 */
+    for (i = 0; i < 192; i++) {
+        felem_square(tmp, ftmp);
+        felem_reduce(ftmp, tmp);
+    }                           /* 2^256 - 2^224 + 2^192 */
+
+    felem_mul(tmp, e64, e32);
+    felem_reduce(ftmp2, tmp);   /* 2^64 - 2^0 */
+    for (i = 0; i < 16; i++) {
+        felem_square(tmp, ftmp2);
+        felem_reduce(ftmp2, tmp);
+    }                           /* 2^80 - 2^16 */
+    felem_mul(tmp, ftmp2, e16);
+    felem_reduce(ftmp2, tmp);   /* 2^80 - 2^0 */
+    for (i = 0; i < 8; i++) {
+        felem_square(tmp, ftmp2);
+        felem_reduce(ftmp2, tmp);
+    }                           /* 2^88 - 2^8 */
+    felem_mul(tmp, ftmp2, e8);
+    felem_reduce(ftmp2, tmp);   /* 2^88 - 2^0 */
+    for (i = 0; i < 4; i++) {
+        felem_square(tmp, ftmp2);
+        felem_reduce(ftmp2, tmp);
+    }                           /* 2^92 - 2^4 */
+    felem_mul(tmp, ftmp2, e4);
+    felem_reduce(ftmp2, tmp);   /* 2^92 - 2^0 */
+    felem_square(tmp, ftmp2);
+    felem_reduce(ftmp2, tmp);   /* 2^93 - 2^1 */
+    felem_square(tmp, ftmp2);
+    felem_reduce(ftmp2, tmp);   /* 2^94 - 2^2 */
+    felem_mul(tmp, ftmp2, e2);
+    felem_reduce(ftmp2, tmp);   /* 2^94 - 2^0 */
+    felem_square(tmp, ftmp2);
+    felem_reduce(ftmp2, tmp);   /* 2^95 - 2^1 */
+    felem_square(tmp, ftmp2);
+    felem_reduce(ftmp2, tmp);   /* 2^96 - 2^2 */
+    felem_mul(tmp, ftmp2, in);
+    felem_reduce(ftmp2, tmp);   /* 2^96 - 3 */
+
+    felem_mul(tmp, ftmp2, ftmp);
+    felem_reduce(out, tmp);     /* 2^256 - 2^224 + 2^192 + 2^96 - 3 */
+}
+
+static void smallfelem_inv_contract(smallfelem out, const smallfelem in)
+{
+    felem tmp;
+
+    smallfelem_expand(tmp, in);
+    felem_inv(tmp, tmp);
+    felem_contract(out, tmp);
+}
+
+/*-
+ * Group operations
+ * ----------------
+ *
+ * Building on top of the field operations we have the operations on the
+ * elliptic curve group itself. Points on the curve are represented in Jacobian
+ * coordinates
+ */
+
+/*-
+ * point_double calculates 2*(x_in, y_in, z_in)
+ *
+ * The method is taken from:
+ *   http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
+ *
+ * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed.
+ * while x_out == y_in is not (maybe this works, but it's not tested).
+ */
+static void
+point_double(felem x_out, felem y_out, felem z_out,
+             const felem x_in, const felem y_in, const felem z_in)
+{
+    longfelem tmp, tmp2;
+    felem delta, gamma, beta, alpha, ftmp, ftmp2;
+    smallfelem small1, small2;
+
+    felem_assign(ftmp, x_in);
+    /* ftmp[i] < 2^106 */
+    felem_assign(ftmp2, x_in);
+    /* ftmp2[i] < 2^106 */
+
+    /* delta = z^2 */
+    felem_square(tmp, z_in);
+    felem_reduce(delta, tmp);
+    /* delta[i] < 2^101 */
+
+    /* gamma = y^2 */
+    felem_square(tmp, y_in);
+    felem_reduce(gamma, tmp);
+    /* gamma[i] < 2^101 */
+    felem_shrink(small1, gamma);
+
+    /* beta = x*gamma */
+    felem_small_mul(tmp, small1, x_in);
+    felem_reduce(beta, tmp);
+    /* beta[i] < 2^101 */
+
+    /* alpha = 3*(x-delta)*(x+delta) */
+    felem_diff(ftmp, delta);
+    /* ftmp[i] < 2^105 + 2^106 < 2^107 */
+    felem_sum(ftmp2, delta);
+    /* ftmp2[i] < 2^105 + 2^106 < 2^107 */
+    felem_scalar(ftmp2, 3);
+    /* ftmp2[i] < 3 * 2^107 < 2^109 */
+    felem_mul(tmp, ftmp, ftmp2);
+    felem_reduce(alpha, tmp);
+    /* alpha[i] < 2^101 */
+    felem_shrink(small2, alpha);
+
+    /* x' = alpha^2 - 8*beta */
+    smallfelem_square(tmp, small2);
+    felem_reduce(x_out, tmp);
+    felem_assign(ftmp, beta);
+    felem_scalar(ftmp, 8);
+    /* ftmp[i] < 8 * 2^101 = 2^104 */
+    felem_diff(x_out, ftmp);
+    /* x_out[i] < 2^105 + 2^101 < 2^106 */
+
+    /* z' = (y + z)^2 - gamma - delta */
+    felem_sum(delta, gamma);
+    /* delta[i] < 2^101 + 2^101 = 2^102 */
+    felem_assign(ftmp, y_in);
+    felem_sum(ftmp, z_in);
+    /* ftmp[i] < 2^106 + 2^106 = 2^107 */
+    felem_square(tmp, ftmp);
+    felem_reduce(z_out, tmp);
+    felem_diff(z_out, delta);
+    /* z_out[i] < 2^105 + 2^101 < 2^106 */
+
+    /* y' = alpha*(4*beta - x') - 8*gamma^2 */
+    felem_scalar(beta, 4);
+    /* beta[i] < 4 * 2^101 = 2^103 */
+    felem_diff_zero107(beta, x_out);
+    /* beta[i] < 2^107 + 2^103 < 2^108 */
+    felem_small_mul(tmp, small2, beta);
+    /* tmp[i] < 7 * 2^64 < 2^67 */
+    smallfelem_square(tmp2, small1);
+    /* tmp2[i] < 7 * 2^64 */
+    longfelem_scalar(tmp2, 8);
+    /* tmp2[i] < 8 * 7 * 2^64 = 7 * 2^67 */
+    longfelem_diff(tmp, tmp2);
+    /* tmp[i] < 2^67 + 2^70 + 2^40 < 2^71 */
+    felem_reduce_zero105(y_out, tmp);
+    /* y_out[i] < 2^106 */
+}
+
+/*
+ * point_double_small is the same as point_double, except that it operates on
+ * smallfelems
+ */
+static void
+point_double_small(smallfelem x_out, smallfelem y_out, smallfelem z_out,
+                   const smallfelem x_in, const smallfelem y_in,
+                   const smallfelem z_in)
+{
+    felem felem_x_out, felem_y_out, felem_z_out;
+    felem felem_x_in, felem_y_in, felem_z_in;
+
+    smallfelem_expand(felem_x_in, x_in);
+    smallfelem_expand(felem_y_in, y_in);
+    smallfelem_expand(felem_z_in, z_in);
+    point_double(felem_x_out, felem_y_out, felem_z_out,
+                 felem_x_in, felem_y_in, felem_z_in);
+    felem_shrink(x_out, felem_x_out);
+    felem_shrink(y_out, felem_y_out);
+    felem_shrink(z_out, felem_z_out);
+}
+
+/* copy_conditional copies in to out iff mask is all ones. */
+static void copy_conditional(felem out, const felem in, limb mask)
+{
+    unsigned i;
+    for (i = 0; i < NLIMBS; ++i) {
+        const limb tmp = mask & (in[i] ^ out[i]);
+        out[i] ^= tmp;
+    }
+}
+
+/* copy_small_conditional copies in to out iff mask is all ones. */
+static void copy_small_conditional(felem out, const smallfelem in, limb mask)
+{
+    unsigned i;
+    const u64 mask64 = mask;
+    for (i = 0; i < NLIMBS; ++i) {
+        out[i] = ((limb) (in[i] & mask64)) | (out[i] & ~mask);
+    }
+}
+
+/*-
+ * point_add calculates (x1, y1, z1) + (x2, y2, z2)
+ *
+ * The method is taken from:
+ *   http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl,
+ * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity).
+ *
+ * This function includes a branch for checking whether the two input points
+ * are equal, (while not equal to the point at infinity). This case never
+ * happens during single point multiplication, so there is no timing leak for
+ * ECDH or ECDSA signing.
+ */
+static void point_add(felem x3, felem y3, felem z3,
+                      const felem x1, const felem y1, const felem z1,
+                      const int mixed, const smallfelem x2,
+                      const smallfelem y2, const smallfelem z2)
+{
+    felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out;
+    longfelem tmp, tmp2;
+    smallfelem small1, small2, small3, small4, small5;
+    limb x_equal, y_equal, z1_is_zero, z2_is_zero;
+
+    felem_shrink(small3, z1);
+
+    z1_is_zero = smallfelem_is_zero(small3);
+    z2_is_zero = smallfelem_is_zero(z2);
+
+    /* ftmp = z1z1 = z1**2 */
+    smallfelem_square(tmp, small3);
+    felem_reduce(ftmp, tmp);
+    /* ftmp[i] < 2^101 */
+    felem_shrink(small1, ftmp);
+
+    if (!mixed) {
+        /* ftmp2 = z2z2 = z2**2 */
+        smallfelem_square(tmp, z2);
+        felem_reduce(ftmp2, tmp);
+        /* ftmp2[i] < 2^101 */
+        felem_shrink(small2, ftmp2);
+
+        felem_shrink(small5, x1);
+
+        /* u1 = ftmp3 = x1*z2z2 */
+        smallfelem_mul(tmp, small5, small2);
+        felem_reduce(ftmp3, tmp);
+        /* ftmp3[i] < 2^101 */
+
+        /* ftmp5 = z1 + z2 */
+        felem_assign(ftmp5, z1);
+        felem_small_sum(ftmp5, z2);
+        /* ftmp5[i] < 2^107 */
+
+        /* ftmp5 = (z1 + z2)**2 - (z1z1 + z2z2) = 2z1z2 */
+        felem_square(tmp, ftmp5);
+        felem_reduce(ftmp5, tmp);
+        /* ftmp2 = z2z2 + z1z1 */
+        felem_sum(ftmp2, ftmp);
+        /* ftmp2[i] < 2^101 + 2^101 = 2^102 */
+        felem_diff(ftmp5, ftmp2);
+        /* ftmp5[i] < 2^105 + 2^101 < 2^106 */
+
+        /* ftmp2 = z2 * z2z2 */
+        smallfelem_mul(tmp, small2, z2);
+        felem_reduce(ftmp2, tmp);
+
+        /* s1 = ftmp2 = y1 * z2**3 */
+        felem_mul(tmp, y1, ftmp2);
+        felem_reduce(ftmp6, tmp);
+        /* ftmp6[i] < 2^101 */
+    } else {
+        /*
+         * We'll assume z2 = 1 (special case z2 = 0 is handled later)
+         */
+
+        /* u1 = ftmp3 = x1*z2z2 */
+        felem_assign(ftmp3, x1);
+        /* ftmp3[i] < 2^106 */
+
+        /* ftmp5 = 2z1z2 */
+        felem_assign(ftmp5, z1);
+        felem_scalar(ftmp5, 2);
+        /* ftmp5[i] < 2*2^106 = 2^107 */
+
+        /* s1 = ftmp2 = y1 * z2**3 */
+        felem_assign(ftmp6, y1);
+        /* ftmp6[i] < 2^106 */
+    }
+
+    /* u2 = x2*z1z1 */
+    smallfelem_mul(tmp, x2, small1);
+    felem_reduce(ftmp4, tmp);
+
+    /* h = ftmp4 = u2 - u1 */
+    felem_diff_zero107(ftmp4, ftmp3);
+    /* ftmp4[i] < 2^107 + 2^101 < 2^108 */
+    felem_shrink(small4, ftmp4);
+
+    x_equal = smallfelem_is_zero(small4);
+
+    /* z_out = ftmp5 * h */
+    felem_small_mul(tmp, small4, ftmp5);
+    felem_reduce(z_out, tmp);
+    /* z_out[i] < 2^101 */
+
+    /* ftmp = z1 * z1z1 */
+    smallfelem_mul(tmp, small1, small3);
+    felem_reduce(ftmp, tmp);
+
+    /* s2 = tmp = y2 * z1**3 */
+    felem_small_mul(tmp, y2, ftmp);
+    felem_reduce(ftmp5, tmp);
+
+    /* r = ftmp5 = (s2 - s1)*2 */
+    felem_diff_zero107(ftmp5, ftmp6);
+    /* ftmp5[i] < 2^107 + 2^107 = 2^108 */
+    felem_scalar(ftmp5, 2);
+    /* ftmp5[i] < 2^109 */
+    felem_shrink(small1, ftmp5);
+    y_equal = smallfelem_is_zero(small1);
+
+    if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
+        point_double(x3, y3, z3, x1, y1, z1);
+        return;
+    }
+
+    /* I = ftmp = (2h)**2 */
+    felem_assign(ftmp, ftmp4);
+    felem_scalar(ftmp, 2);
+    /* ftmp[i] < 2*2^108 = 2^109 */
+    felem_square(tmp, ftmp);
+    felem_reduce(ftmp, tmp);
+
+    /* J = ftmp2 = h * I */
+    felem_mul(tmp, ftmp4, ftmp);
+    felem_reduce(ftmp2, tmp);
+
+    /* V = ftmp4 = U1 * I */
+    felem_mul(tmp, ftmp3, ftmp);
+    felem_reduce(ftmp4, tmp);
+
+    /* x_out = r**2 - J - 2V */
+    smallfelem_square(tmp, small1);
+    felem_reduce(x_out, tmp);
+    felem_assign(ftmp3, ftmp4);
+    felem_scalar(ftmp4, 2);
+    felem_sum(ftmp4, ftmp2);
+    /* ftmp4[i] < 2*2^101 + 2^101 < 2^103 */
+    felem_diff(x_out, ftmp4);
+    /* x_out[i] < 2^105 + 2^101 */
+
+    /* y_out = r(V-x_out) - 2 * s1 * J */
+    felem_diff_zero107(ftmp3, x_out);
+    /* ftmp3[i] < 2^107 + 2^101 < 2^108 */
+    felem_small_mul(tmp, small1, ftmp3);
+    felem_mul(tmp2, ftmp6, ftmp2);
+    longfelem_scalar(tmp2, 2);
+    /* tmp2[i] < 2*2^67 = 2^68 */
+    longfelem_diff(tmp, tmp2);
+    /* tmp[i] < 2^67 + 2^70 + 2^40 < 2^71 */
+    felem_reduce_zero105(y_out, tmp);
+    /* y_out[i] < 2^106 */
+
+    copy_small_conditional(x_out, x2, z1_is_zero);
+    copy_conditional(x_out, x1, z2_is_zero);
+    copy_small_conditional(y_out, y2, z1_is_zero);
+    copy_conditional(y_out, y1, z2_is_zero);
+    copy_small_conditional(z_out, z2, z1_is_zero);
+    copy_conditional(z_out, z1, z2_is_zero);
+    felem_assign(x3, x_out);
+    felem_assign(y3, y_out);
+    felem_assign(z3, z_out);
+}
+
+/*
+ * point_add_small is the same as point_add, except that it operates on
+ * smallfelems
+ */
+static void point_add_small(smallfelem x3, smallfelem y3, smallfelem z3,
+                            smallfelem x1, smallfelem y1, smallfelem z1,
+                            smallfelem x2, smallfelem y2, smallfelem z2)
+{
+    felem felem_x3, felem_y3, felem_z3;
+    felem felem_x1, felem_y1, felem_z1;
+    smallfelem_expand(felem_x1, x1);
+    smallfelem_expand(felem_y1, y1);
+    smallfelem_expand(felem_z1, z1);
+    point_add(felem_x3, felem_y3, felem_z3, felem_x1, felem_y1, felem_z1, 0,
+              x2, y2, z2);
+    felem_shrink(x3, felem_x3);
+    felem_shrink(y3, felem_y3);
+    felem_shrink(z3, felem_z3);
+}
+
+/*-
+ * Base point pre computation
+ * --------------------------
+ *
+ * Two different sorts of precomputed tables are used in the following code.
+ * Each contain various points on the curve, where each point is three field
+ * elements (x, y, z).
+ *
+ * For the base point table, z is usually 1 (0 for the point at infinity).
+ * This table has 2 * 16 elements, starting with the following:
+ * index | bits    | point
+ * ------+---------+------------------------------
+ *     0 | 0 0 0 0 | 0G
+ *     1 | 0 0 0 1 | 1G
+ *     2 | 0 0 1 0 | 2^64G
+ *     3 | 0 0 1 1 | (2^64 + 1)G
+ *     4 | 0 1 0 0 | 2^128G
+ *     5 | 0 1 0 1 | (2^128 + 1)G
+ *     6 | 0 1 1 0 | (2^128 + 2^64)G
+ *     7 | 0 1 1 1 | (2^128 + 2^64 + 1)G
+ *     8 | 1 0 0 0 | 2^192G
+ *     9 | 1 0 0 1 | (2^192 + 1)G
+ *    10 | 1 0 1 0 | (2^192 + 2^64)G
+ *    11 | 1 0 1 1 | (2^192 + 2^64 + 1)G
+ *    12 | 1 1 0 0 | (2^192 + 2^128)G
+ *    13 | 1 1 0 1 | (2^192 + 2^128 + 1)G
+ *    14 | 1 1 1 0 | (2^192 + 2^128 + 2^64)G
+ *    15 | 1 1 1 1 | (2^192 + 2^128 + 2^64 + 1)G
+ * followed by a copy of this with each element multiplied by 2^32.
+ *
+ * The reason for this is so that we can clock bits into four different
+ * locations when doing simple scalar multiplies against the base point,
+ * and then another four locations using the second 16 elements.
+ *
+ * Tables for other points have table[i] = iG for i in 0 .. 16. */
+
+/* gmul is the table of precomputed base points */
+static const smallfelem gmul[2][16][3] = {
+    {{{0, 0, 0, 0},
+      {0, 0, 0, 0},
+      {0, 0, 0, 0}},
+     {{0xf4a13945d898c296, 0x77037d812deb33a0, 0xf8bce6e563a440f2,
+       0x6b17d1f2e12c4247},
+      {0xcbb6406837bf51f5, 0x2bce33576b315ece, 0x8ee7eb4a7c0f9e16,
+       0x4fe342e2fe1a7f9b},
+      {1, 0, 0, 0}},
+     {{0x90e75cb48e14db63, 0x29493baaad651f7e, 0x8492592e326e25de,
+       0x0fa822bc2811aaa5},
+      {0xe41124545f462ee7, 0x34b1a65050fe82f5, 0x6f4ad4bcb3df188b,
+       0xbff44ae8f5dba80d},
+      {1, 0, 0, 0}},
+     {{0x93391ce2097992af, 0xe96c98fd0d35f1fa, 0xb257c0de95e02789,
+       0x300a4bbc89d6726f},
+      {0xaa54a291c08127a0, 0x5bb1eeada9d806a5, 0x7f1ddb25ff1e3c6f,
+       0x72aac7e0d09b4644},
+      {1, 0, 0, 0}},
+     {{0x57c84fc9d789bd85, 0xfc35ff7dc297eac3, 0xfb982fd588c6766e,
+       0x447d739beedb5e67},
+      {0x0c7e33c972e25b32, 0x3d349b95a7fae500, 0xe12e9d953a4aaff7,
+       0x2d4825ab834131ee},
+      {1, 0, 0, 0}},
+     {{0x13949c932a1d367f, 0xef7fbd2b1a0a11b7, 0xddc6068bb91dfc60,
+       0xef9519328a9c72ff},
+      {0x196035a77376d8a8, 0x23183b0895ca1740, 0xc1ee9807022c219c,
+       0x611e9fc37dbb2c9b},
+      {1, 0, 0, 0}},
+     {{0xcae2b1920b57f4bc, 0x2936df5ec6c9bc36, 0x7dea6482e11238bf,
+       0x550663797b51f5d8},
+      {0x44ffe216348a964c, 0x9fb3d576dbdefbe1, 0x0afa40018d9d50e5,
+       0x157164848aecb851},
+      {1, 0, 0, 0}},
+     {{0xe48ecafffc5cde01, 0x7ccd84e70d715f26, 0xa2e8f483f43e4391,
+       0xeb5d7745b21141ea},
+      {0xcac917e2731a3479, 0x85f22cfe2844b645, 0x0990e6a158006cee,
+       0xeafd72ebdbecc17b},
+      {1, 0, 0, 0}},
+     {{0x6cf20ffb313728be, 0x96439591a3c6b94a, 0x2736ff8344315fc5,
+       0xa6d39677a7849276},
+      {0xf2bab833c357f5f4, 0x824a920c2284059b, 0x66b8babd2d27ecdf,
+       0x674f84749b0b8816},
+      {1, 0, 0, 0}},
+     {{0x2df48c04677c8a3e, 0x74e02f080203a56b, 0x31855f7db8c7fedb,
+       0x4e769e7672c9ddad},
+      {0xa4c36165b824bbb0, 0xfb9ae16f3b9122a5, 0x1ec0057206947281,
+       0x42b99082de830663},
+      {1, 0, 0, 0}},
+     {{0x6ef95150dda868b9, 0xd1f89e799c0ce131, 0x7fdc1ca008a1c478,
+       0x78878ef61c6ce04d},
+      {0x9c62b9121fe0d976, 0x6ace570ebde08d4f, 0xde53142c12309def,
+       0xb6cb3f5d7b72c321},
+      {1, 0, 0, 0}},
+     {{0x7f991ed2c31a3573, 0x5b82dd5bd54fb496, 0x595c5220812ffcae,
+       0x0c88bc4d716b1287},
+      {0x3a57bf635f48aca8, 0x7c8181f4df2564f3, 0x18d1b5b39c04e6aa,
+       0xdd5ddea3f3901dc6},
+      {1, 0, 0, 0}},
+     {{0xe96a79fb3e72ad0c, 0x43a0a28c42ba792f, 0xefe0a423083e49f3,
+       0x68f344af6b317466},
+      {0xcdfe17db3fb24d4a, 0x668bfc2271f5c626, 0x604ed93c24d67ff3,
+       0x31b9c405f8540a20},
+      {1, 0, 0, 0}},
+     {{0xd36b4789a2582e7f, 0x0d1a10144ec39c28, 0x663c62c3edbad7a0,
+       0x4052bf4b6f461db9},
+      {0x235a27c3188d25eb, 0xe724f33999bfcc5b, 0x862be6bd71d70cc8,
+       0xfecf4d5190b0fc61},
+      {1, 0, 0, 0}},
+     {{0x74346c10a1d4cfac, 0xafdf5cc08526a7a4, 0x123202a8f62bff7a,
+       0x1eddbae2c802e41a},
+      {0x8fa0af2dd603f844, 0x36e06b7e4c701917, 0x0c45f45273db33a0,
+       0x43104d86560ebcfc},
+      {1, 0, 0, 0}},
+     {{0x9615b5110d1d78e5, 0x66b0de3225c4744b, 0x0a4a46fb6aaf363a,
+       0xb48e26b484f7a21c},
+      {0x06ebb0f621a01b2d, 0xc004e4048b7b0f98, 0x64131bcdfed6f668,
+       0xfac015404d4d3dab},
+      {1, 0, 0, 0}}},
+    {{{0, 0, 0, 0},
+      {0, 0, 0, 0},
+      {0, 0, 0, 0}},
+     {{0x3a5a9e22185a5943, 0x1ab919365c65dfb6, 0x21656b32262c71da,
+       0x7fe36b40af22af89},
+      {0xd50d152c699ca101, 0x74b3d5867b8af212, 0x9f09f40407dca6f1,
+       0xe697d45825b63624},
+      {1, 0, 0, 0}},
+     {{0xa84aa9397512218e, 0xe9a521b074ca0141, 0x57880b3a18a2e902,
+       0x4a5b506612a677a6},
+      {0x0beada7a4c4f3840, 0x626db15419e26d9d, 0xc42604fbe1627d40,
+       0xeb13461ceac089f1},
+      {1, 0, 0, 0}},
+     {{0xf9faed0927a43281, 0x5e52c4144103ecbc, 0xc342967aa815c857,
+       0x0781b8291c6a220a},
+      {0x5a8343ceeac55f80, 0x88f80eeee54a05e3, 0x97b2a14f12916434,
+       0x690cde8df0151593},
+      {1, 0, 0, 0}},
+     {{0xaee9c75df7f82f2a, 0x9e4c35874afdf43a, 0xf5622df437371326,
+       0x8a535f566ec73617},
+      {0xc5f9a0ac223094b7, 0xcde533864c8c7669, 0x37e02819085a92bf,
+       0x0455c08468b08bd7},
+      {1, 0, 0, 0}},
+     {{0x0c0a6e2c9477b5d9, 0xf9a4bf62876dc444, 0x5050a949b6cdc279,
+       0x06bada7ab77f8276},
+      {0xc8b4aed1ea48dac9, 0xdebd8a4b7ea1070f, 0x427d49101366eb70,
+       0x5b476dfd0e6cb18a},
+      {1, 0, 0, 0}},
+     {{0x7c5c3e44278c340a, 0x4d54606812d66f3b, 0x29a751b1ae23c5d8,
+       0x3e29864e8a2ec908},
+      {0x142d2a6626dbb850, 0xad1744c4765bd780, 0x1f150e68e322d1ed,
+       0x239b90ea3dc31e7e},
+      {1, 0, 0, 0}},
+     {{0x78c416527a53322a, 0x305dde6709776f8e, 0xdbcab759f8862ed4,
+       0x820f4dd949f72ff7},
+      {0x6cc544a62b5debd4, 0x75be5d937b4e8cc4, 0x1b481b1b215c14d3,
+       0x140406ec783a05ec},
+      {1, 0, 0, 0}},
+     {{0x6a703f10e895df07, 0xfd75f3fa01876bd8, 0xeb5b06e70ce08ffe,
+       0x68f6b8542783dfee},
+      {0x90c76f8a78712655, 0xcf5293d2f310bf7f, 0xfbc8044dfda45028,
+       0xcbe1feba92e40ce6},
+      {1, 0, 0, 0}},
+     {{0xe998ceea4396e4c1, 0xfc82ef0b6acea274, 0x230f729f2250e927,
+       0xd0b2f94d2f420109},
+      {0x4305adddb38d4966, 0x10b838f8624c3b45, 0x7db2636658954e7a,
+       0x971459828b0719e5},
+      {1, 0, 0, 0}},
+     {{0x4bd6b72623369fc9, 0x57f2929e53d0b876, 0xc2d5cba4f2340687,
+       0x961610004a866aba},
+      {0x49997bcd2e407a5e, 0x69ab197d92ddcb24, 0x2cf1f2438fe5131c,
+       0x7acb9fadcee75e44},
+      {1, 0, 0, 0}},
+     {{0x254e839423d2d4c0, 0xf57f0c917aea685b, 0xa60d880f6f75aaea,
+       0x24eb9acca333bf5b},
+      {0xe3de4ccb1cda5dea, 0xfeef9341c51a6b4f, 0x743125f88bac4c4d,
+       0x69f891c5acd079cc},
+      {1, 0, 0, 0}},
+     {{0xeee44b35702476b5, 0x7ed031a0e45c2258, 0xb422d1e7bd6f8514,
+       0xe51f547c5972a107},
+      {0xa25bcd6fc9cf343d, 0x8ca922ee097c184e, 0xa62f98b3a9fe9a06,
+       0x1c309a2b25bb1387},
+      {1, 0, 0, 0}},
+     {{0x9295dbeb1967c459, 0xb00148833472c98e, 0xc504977708011828,
+       0x20b87b8aa2c4e503},
+      {0x3063175de057c277, 0x1bd539338fe582dd, 0x0d11adef5f69a044,
+       0xf5c6fa49919776be},
+      {1, 0, 0, 0}},
+     {{0x8c944e760fd59e11, 0x3876cba1102fad5f, 0xa454c3fad83faa56,
+       0x1ed7d1b9332010b9},
+      {0xa1011a270024b889, 0x05e4d0dcac0cd344, 0x52b520f0eb6a2a24,
+       0x3a2b03f03217257a},
+      {1, 0, 0, 0}},
+     {{0xf20fc2afdf1d043d, 0xf330240db58d5a62, 0xfc7d229ca0058c3b,
+       0x15fee545c78dd9f6},
+      {0x501e82885bc98cda, 0x41ef80e5d046ac04, 0x557d9f49461210fb,
+       0x4ab5b6b2b8753f81},
+      {1, 0, 0, 0}}}
+};
+
+/*
+ * select_point selects the |idx|th point from a precomputation table and
+ * copies it to out.
+ */
+static void select_point(const u64 idx, unsigned int size,
+                         const smallfelem pre_comp[16][3], smallfelem out[3])
+{
+    unsigned i, j;
+    u64 *outlimbs = &out[0][0];
+
+    memset(out, 0, sizeof(*out) * 3);
+
+    for (i = 0; i < size; i++) {
+        const u64 *inlimbs = (u64 *)&pre_comp[i][0][0];
+        u64 mask = i ^ idx;
+        mask |= mask >> 4;
+        mask |= mask >> 2;
+        mask |= mask >> 1;
+        mask &= 1;
+        mask--;
+        for (j = 0; j < NLIMBS * 3; j++)
+            outlimbs[j] |= inlimbs[j] & mask;
+    }
+}
+
+/* get_bit returns the |i|th bit in |in| */
+static char get_bit(const felem_bytearray in, int i)
+{
+    if ((i < 0) || (i >= 256))
+        return 0;
+    return (in[i >> 3] >> (i & 7)) & 1;
+}
+
+/*
+ * Interleaved point multiplication using precomputed point multiples: The
+ * small point multiples 0*P, 1*P, ..., 17*P are in pre_comp[], the scalars
+ * in scalars[]. If g_scalar is non-NULL, we also add this multiple of the
+ * generator, using certain (large) precomputed multiples in g_pre_comp.
+ * Output point (X, Y, Z) is stored in x_out, y_out, z_out
+ */
+static void batch_mul(felem x_out, felem y_out, felem z_out,
+                      const felem_bytearray scalars[],
+                      const unsigned num_points, const u8 *g_scalar,
+                      const int mixed, const smallfelem pre_comp[][17][3],
+                      const smallfelem g_pre_comp[2][16][3])
+{
+    int i, skip;
+    unsigned num, gen_mul = (g_scalar != NULL);
+    felem nq[3], ftmp;
+    smallfelem tmp[3];
+    u64 bits;
+    u8 sign, digit;
+
+    /* set nq to the point at infinity */
+    memset(nq, 0, sizeof(nq));
+
+    /*
+     * Loop over all scalars msb-to-lsb, interleaving additions of multiples
+     * of the generator (two in each of the last 32 rounds) and additions of
+     * other points multiples (every 5th round).
+     */
+    skip = 1;                   /* save two point operations in the first
+                                 * round */
+    for (i = (num_points ? 255 : 31); i >= 0; --i) {
+        /* double */
+        if (!skip)
+            point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
+
+        /* add multiples of the generator */
+        if (gen_mul && (i <= 31)) {
+            /* first, look 32 bits upwards */
+            bits = get_bit(g_scalar, i + 224) << 3;
+            bits |= get_bit(g_scalar, i + 160) << 2;
+            bits |= get_bit(g_scalar, i + 96) << 1;
+            bits |= get_bit(g_scalar, i + 32);
+            /* select the point to add, in constant time */
+            select_point(bits, 16, g_pre_comp[1], tmp);
+
+            if (!skip) {
+                /* Arg 1 below is for "mixed" */
+                point_add(nq[0], nq[1], nq[2],
+                          nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]);
+            } else {
+                smallfelem_expand(nq[0], tmp[0]);
+                smallfelem_expand(nq[1], tmp[1]);
+                smallfelem_expand(nq[2], tmp[2]);
+                skip = 0;
+            }
+
+            /* second, look at the current position */
+            bits = get_bit(g_scalar, i + 192) << 3;
+            bits |= get_bit(g_scalar, i + 128) << 2;
+            bits |= get_bit(g_scalar, i + 64) << 1;
+            bits |= get_bit(g_scalar, i);
+            /* select the point to add, in constant time */
+            select_point(bits, 16, g_pre_comp[0], tmp);
+            /* Arg 1 below is for "mixed" */
+            point_add(nq[0], nq[1], nq[2],
+                      nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]);
+        }
+
+        /* do other additions every 5 doublings */
+        if (num_points && (i % 5 == 0)) {
+            /* loop over all scalars */
+            for (num = 0; num < num_points; ++num) {
+                bits = get_bit(scalars[num], i + 4) << 5;
+                bits |= get_bit(scalars[num], i + 3) << 4;
+                bits |= get_bit(scalars[num], i + 2) << 3;
+                bits |= get_bit(scalars[num], i + 1) << 2;
+                bits |= get_bit(scalars[num], i) << 1;
+                bits |= get_bit(scalars[num], i - 1);
+                ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
+
+                /*
+                 * select the point to add or subtract, in constant time
+                 */
+                select_point(digit, 17, pre_comp[num], tmp);
+                smallfelem_neg(ftmp, tmp[1]); /* (X, -Y, Z) is the negative
+                                               * point */
+                copy_small_conditional(ftmp, tmp[1], (((limb) sign) - 1));
+                felem_contract(tmp[1], ftmp);
+
+                if (!skip) {
+                    point_add(nq[0], nq[1], nq[2],
+                              nq[0], nq[1], nq[2],
+                              mixed, tmp[0], tmp[1], tmp[2]);
+                } else {
+                    smallfelem_expand(nq[0], tmp[0]);
+                    smallfelem_expand(nq[1], tmp[1]);
+                    smallfelem_expand(nq[2], tmp[2]);
+                    skip = 0;
+                }
+            }
+        }
+    }
+    felem_assign(x_out, nq[0]);
+    felem_assign(y_out, nq[1]);
+    felem_assign(z_out, nq[2]);
+}
+
+/* Precomputation for the group generator. */
+struct nistp256_pre_comp_st {
+    smallfelem g_pre_comp[2][16][3];
+    int references;
+    CRYPTO_RWLOCK *lock;
+};
+
+const EC_METHOD *EC_GFp_nistp256_method(void)
+{
+    static const EC_METHOD ret = {
+        EC_FLAGS_DEFAULT_OCT,
+        NID_X9_62_prime_field,
+        ec_GFp_nistp256_group_init,
+        ec_GFp_simple_group_finish,
+        ec_GFp_simple_group_clear_finish,
+        ec_GFp_nist_group_copy,
+        ec_GFp_nistp256_group_set_curve,
+        ec_GFp_simple_group_get_curve,
+        ec_GFp_simple_group_get_degree,
+        ec_group_simple_order_bits,
+        ec_GFp_simple_group_check_discriminant,
+        ec_GFp_simple_point_init,
+        ec_GFp_simple_point_finish,
+        ec_GFp_simple_point_clear_finish,
+        ec_GFp_simple_point_copy,
+        ec_GFp_simple_point_set_to_infinity,
+        ec_GFp_simple_set_Jprojective_coordinates_GFp,
+        ec_GFp_simple_get_Jprojective_coordinates_GFp,
+        ec_GFp_simple_point_set_affine_coordinates,
+        ec_GFp_nistp256_point_get_affine_coordinates,
+        0 /* point_set_compressed_coordinates */ ,
+        0 /* point2oct */ ,
+        0 /* oct2point */ ,
+        ec_GFp_simple_add,
+        ec_GFp_simple_dbl,
+        ec_GFp_simple_invert,
+        ec_GFp_simple_is_at_infinity,
+        ec_GFp_simple_is_on_curve,
+        ec_GFp_simple_cmp,
+        ec_GFp_simple_make_affine,
+        ec_GFp_simple_points_make_affine,
+        ec_GFp_nistp256_points_mul,
+        ec_GFp_nistp256_precompute_mult,
+        ec_GFp_nistp256_have_precompute_mult,
+        ec_GFp_nist_field_mul,
+        ec_GFp_nist_field_sqr,
+        0 /* field_div */ ,
+        0 /* field_encode */ ,
+        0 /* field_decode */ ,
+        0,                      /* field_set_to_one */
+        ec_key_simple_priv2oct,
+        ec_key_simple_oct2priv,
+        0, /* set private */
+        ec_key_simple_generate_key,
+        ec_key_simple_check_key,
+        ec_key_simple_generate_public_key,
+        0, /* keycopy */
+        0, /* keyfinish */
+        ecdh_simple_compute_key
+    };
+
+    return &ret;
+}
+
+/******************************************************************************/
+/*
+ * FUNCTIONS TO MANAGE PRECOMPUTATION
+ */
+
+static NISTP256_PRE_COMP *nistp256_pre_comp_new()
+{
+    NISTP256_PRE_COMP *ret = OPENSSL_zalloc(sizeof(*ret));
+
+    if (ret == NULL) {
+        ECerr(EC_F_NISTP256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+        return ret;
+    }
+
+    ret->references = 1;
+
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        ECerr(EC_F_NISTP256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *p)
+{
+    int i;
+    if (p != NULL)
+        CRYPTO_atomic_add(&p->references, 1, &i, p->lock);
+    return p;
+}
+
+void EC_nistp256_pre_comp_free(NISTP256_PRE_COMP *pre)
+{
+    int i;
+
+    if (pre == NULL)
+        return;
+
+    CRYPTO_atomic_add(&pre->references, -1, &i, pre->lock);
+    REF_PRINT_COUNT("EC_nistp256", x);
+    if (i > 0)
+        return;
+    REF_ASSERT_ISNT(i < 0);
+
+    CRYPTO_THREAD_lock_free(pre->lock);
+    OPENSSL_free(pre);
+}
+
+/******************************************************************************/
+/*
+ * OPENSSL EC_METHOD FUNCTIONS
+ */
+
+int ec_GFp_nistp256_group_init(EC_GROUP *group)
+{
+    int ret;
+    ret = ec_GFp_simple_group_init(group);
+    group->a_is_minus3 = 1;
+    return ret;
+}
+
+int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+                                    const BIGNUM *a, const BIGNUM *b,
+                                    BN_CTX *ctx)
+{
+    int ret = 0;
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *curve_p, *curve_a, *curve_b;
+
+    if (ctx == NULL)
+        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+            return 0;
+    BN_CTX_start(ctx);
+    if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
+        ((curve_a = BN_CTX_get(ctx)) == NULL) ||
+        ((curve_b = BN_CTX_get(ctx)) == NULL))
+        goto err;
+    BN_bin2bn(nistp256_curve_params[0], sizeof(felem_bytearray), curve_p);
+    BN_bin2bn(nistp256_curve_params[1], sizeof(felem_bytearray), curve_a);
+    BN_bin2bn(nistp256_curve_params[2], sizeof(felem_bytearray), curve_b);
+    if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) {
+        ECerr(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE,
+              EC_R_WRONG_CURVE_PARAMETERS);
+        goto err;
+    }
+    group->field_mod_func = BN_nist_mod_256;
+    ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+ err:
+    BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+/*
+ * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') =
+ * (X/Z^2, Y/Z^3)
+ */
+int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
+                                                 const EC_POINT *point,
+                                                 BIGNUM *x, BIGNUM *y,
+                                                 BN_CTX *ctx)
+{
+    felem z1, z2, x_in, y_in;
+    smallfelem x_out, y_out;
+    longfelem tmp;
+
+    if (EC_POINT_is_at_infinity(group, point)) {
+        ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
+              EC_R_POINT_AT_INFINITY);
+        return 0;
+    }
+    if ((!BN_to_felem(x_in, point->X)) || (!BN_to_felem(y_in, point->Y)) ||
+        (!BN_to_felem(z1, point->Z)))
+        return 0;
+    felem_inv(z2, z1);
+    felem_square(tmp, z2);
+    felem_reduce(z1, tmp);
+    felem_mul(tmp, x_in, z1);
+    felem_reduce(x_in, tmp);
+    felem_contract(x_out, x_in);
+    if (x != NULL) {
+        if (!smallfelem_to_BN(x, x_out)) {
+            ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
+                  ERR_R_BN_LIB);
+            return 0;
+        }
+    }
+    felem_mul(tmp, z1, z2);
+    felem_reduce(z1, tmp);
+    felem_mul(tmp, y_in, z1);
+    felem_reduce(y_in, tmp);
+    felem_contract(y_out, y_in);
+    if (y != NULL) {
+        if (!smallfelem_to_BN(y, y_out)) {
+            ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES,
+                  ERR_R_BN_LIB);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+/* points below is of size |num|, and tmp_smallfelems is of size |num+1| */
+static void make_points_affine(size_t num, smallfelem points[][3],
+                               smallfelem tmp_smallfelems[])
+{
+    /*
+     * Runs in constant time, unless an input is the point at infinity (which
+     * normally shouldn't happen).
+     */
+    ec_GFp_nistp_points_make_affine_internal(num,
+                                             points,
+                                             sizeof(smallfelem),
+                                             tmp_smallfelems,
+                                             (void (*)(void *))smallfelem_one,
+                                             (int (*)(const void *))
+                                             smallfelem_is_zero_int,
+                                             (void (*)(void *, const void *))
+                                             smallfelem_assign,
+                                             (void (*)(void *, const void *))
+                                             smallfelem_square_contract,
+                                             (void (*)
+                                              (void *, const void *,
+                                               const void *))
+                                             smallfelem_mul_contract,
+                                             (void (*)(void *, const void *))
+                                             smallfelem_inv_contract,
+                                             /* nothing to contract */
+                                             (void (*)(void *, const void *))
+                                             smallfelem_assign);
+}
+
+/*
+ * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL
+ * values Result is stored in r (r can equal one of the inputs).
+ */
+int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
+                               const BIGNUM *scalar, size_t num,
+                               const EC_POINT *points[],
+                               const BIGNUM *scalars[], BN_CTX *ctx)
+{
+    int ret = 0;
+    int j;
+    int mixed = 0;
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *x, *y, *z, *tmp_scalar;
+    felem_bytearray g_secret;
+    felem_bytearray *secrets = NULL;
+    smallfelem (*pre_comp)[17][3] = NULL;
+    smallfelem *tmp_smallfelems = NULL;
+    felem_bytearray tmp;
+    unsigned i, num_bytes;
+    int have_pre_comp = 0;
+    size_t num_points = num;
+    smallfelem x_in, y_in, z_in;
+    felem x_out, y_out, z_out;
+    NISTP256_PRE_COMP *pre = NULL;
+    const smallfelem(*g_pre_comp)[16][3] = NULL;
+    EC_POINT *generator = NULL;
+    const EC_POINT *p = NULL;
+    const BIGNUM *p_scalar = NULL;
+
+    if (ctx == NULL)
+        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+            return 0;
+    BN_CTX_start(ctx);
+    if (((x = BN_CTX_get(ctx)) == NULL) ||
+        ((y = BN_CTX_get(ctx)) == NULL) ||
+        ((z = BN_CTX_get(ctx)) == NULL) ||
+        ((tmp_scalar = BN_CTX_get(ctx)) == NULL))
+        goto err;
+
+    if (scalar != NULL) {
+        pre = group->pre_comp.nistp256;
+        if (pre)
+            /* we have precomputation, try to use it */
+            g_pre_comp = (const smallfelem(*)[16][3])pre->g_pre_comp;
+        else
+            /* try to use the standard precomputation */
+            g_pre_comp = &gmul[0];
+        generator = EC_POINT_new(group);
+        if (generator == NULL)
+            goto err;
+        /* get the generator from precomputation */
+        if (!smallfelem_to_BN(x, g_pre_comp[0][1][0]) ||
+            !smallfelem_to_BN(y, g_pre_comp[0][1][1]) ||
+            !smallfelem_to_BN(z, g_pre_comp[0][1][2])) {
+            ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
+            goto err;
+        }
+        if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
+                                                      generator, x, y, z,
+                                                      ctx))
+            goto err;
+        if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
+            /* precomputation matches generator */
+            have_pre_comp = 1;
+        else
+            /*
+             * we don't have valid precomputation: treat the generator as a
+             * random point
+             */
+            num_points++;
+    }
+    if (num_points > 0) {
+        if (num_points >= 3) {
+            /*
+             * unless we precompute multiples for just one or two points,
+             * converting those into affine form is time well spent
+             */
+            mixed = 1;
+        }
+        secrets = OPENSSL_malloc(sizeof(*secrets) * num_points);
+        pre_comp = OPENSSL_malloc(sizeof(*pre_comp) * num_points);
+        if (mixed)
+            tmp_smallfelems =
+              OPENSSL_malloc(sizeof(*tmp_smallfelems) * (num_points * 17 + 1));
+        if ((secrets == NULL) || (pre_comp == NULL)
+            || (mixed && (tmp_smallfelems == NULL))) {
+            ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+
+        /*
+         * we treat NULL scalars as 0, and NULL points as points at infinity,
+         * i.e., they contribute nothing to the linear combination
+         */
+        memset(secrets, 0, sizeof(*secrets) * num_points);
+        memset(pre_comp, 0, sizeof(*pre_comp) * num_points);
+        for (i = 0; i < num_points; ++i) {
+            if (i == num)
+                /*
+                 * we didn't have a valid precomputation, so we pick the
+                 * generator
+                 */
+            {
+                p = EC_GROUP_get0_generator(group);
+                p_scalar = scalar;
+            } else
+                /* the i^th point */
+            {
+                p = points[i];
+                p_scalar = scalars[i];
+            }
+            if ((p_scalar != NULL) && (p != NULL)) {
+                /* reduce scalar to 0 <= scalar < 2^256 */
+                if ((BN_num_bits(p_scalar) > 256)
+                    || (BN_is_negative(p_scalar))) {
+                    /*
+                     * this is an unusual input, and we don't guarantee
+                     * constant-timeness
+                     */
+                    if (!BN_nnmod(tmp_scalar, p_scalar, group->order, ctx)) {
+                        ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
+                        goto err;
+                    }
+                    num_bytes = BN_bn2bin(tmp_scalar, tmp);
+                } else
+                    num_bytes = BN_bn2bin(p_scalar, tmp);
+                flip_endian(secrets[i], tmp, num_bytes);
+                /* precompute multiples */
+                if ((!BN_to_felem(x_out, p->X)) ||
+                    (!BN_to_felem(y_out, p->Y)) ||
+                    (!BN_to_felem(z_out, p->Z)))
+                    goto err;
+                felem_shrink(pre_comp[i][1][0], x_out);
+                felem_shrink(pre_comp[i][1][1], y_out);
+                felem_shrink(pre_comp[i][1][2], z_out);
+                for (j = 2; j <= 16; ++j) {
+                    if (j & 1) {
+                        point_add_small(pre_comp[i][j][0], pre_comp[i][j][1],
+                                        pre_comp[i][j][2], pre_comp[i][1][0],
+                                        pre_comp[i][1][1], pre_comp[i][1][2],
+                                        pre_comp[i][j - 1][0],
+                                        pre_comp[i][j - 1][1],
+                                        pre_comp[i][j - 1][2]);
+                    } else {
+                        point_double_small(pre_comp[i][j][0],
+                                           pre_comp[i][j][1],
+                                           pre_comp[i][j][2],
+                                           pre_comp[i][j / 2][0],
+                                           pre_comp[i][j / 2][1],
+                                           pre_comp[i][j / 2][2]);
+                    }
+                }
+            }
+        }
+        if (mixed)
+            make_points_affine(num_points * 17, pre_comp[0], tmp_smallfelems);
+    }
+
+    /* the scalar for the generator */
+    if ((scalar != NULL) && (have_pre_comp)) {
+        memset(g_secret, 0, sizeof(g_secret));
+        /* reduce scalar to 0 <= scalar < 2^256 */
+        if ((BN_num_bits(scalar) > 256) || (BN_is_negative(scalar))) {
+            /*
+             * this is an unusual input, and we don't guarantee
+             * constant-timeness
+             */
+            if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) {
+                ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
+                goto err;
+            }
+            num_bytes = BN_bn2bin(tmp_scalar, tmp);
+        } else
+            num_bytes = BN_bn2bin(scalar, tmp);
+        flip_endian(g_secret, tmp, num_bytes);
+        /* do the multiplication with generator precomputation */
+        batch_mul(x_out, y_out, z_out,
+                  (const felem_bytearray(*))secrets, num_points,
+                  g_secret,
+                  mixed, (const smallfelem(*)[17][3])pre_comp, g_pre_comp);
+    } else
+        /* do the multiplication without generator precomputation */
+        batch_mul(x_out, y_out, z_out,
+                  (const felem_bytearray(*))secrets, num_points,
+                  NULL, mixed, (const smallfelem(*)[17][3])pre_comp, NULL);
+    /* reduce the output to its unique minimal representation */
+    felem_contract(x_in, x_out);
+    felem_contract(y_in, y_out);
+    felem_contract(z_in, z_out);
+    if ((!smallfelem_to_BN(x, x_in)) || (!smallfelem_to_BN(y, y_in)) ||
+        (!smallfelem_to_BN(z, z_in))) {
+        ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB);
+        goto err;
+    }
+    ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
+
+ err:
+    BN_CTX_end(ctx);
+    EC_POINT_free(generator);
+    BN_CTX_free(new_ctx);
+    OPENSSL_free(secrets);
+    OPENSSL_free(pre_comp);
+    OPENSSL_free(tmp_smallfelems);
+    return ret;
+}
+
+int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+{
+    int ret = 0;
+    NISTP256_PRE_COMP *pre = NULL;
+    int i, j;
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *x, *y;
+    EC_POINT *generator = NULL;
+    smallfelem tmp_smallfelems[32];
+    felem x_tmp, y_tmp, z_tmp;
+
+    /* throw away old precomputation */
+    EC_pre_comp_free(group);
+    if (ctx == NULL)
+        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+            return 0;
+    BN_CTX_start(ctx);
+    if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL))
+        goto err;
+    /* get the generator */
+    if (group->generator == NULL)
+        goto err;
+    generator = EC_POINT_new(group);
+    if (generator == NULL)
+        goto err;
+    BN_bin2bn(nistp256_curve_params[3], sizeof(felem_bytearray), x);
+    BN_bin2bn(nistp256_curve_params[4], sizeof(felem_bytearray), y);
+    if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
+        goto err;
+    if ((pre = nistp256_pre_comp_new()) == NULL)
+        goto err;
+    /*
+     * if the generator is the standard one, use built-in precomputation
+     */
+    if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) {
+        memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
+        goto done;
+    }
+    if ((!BN_to_felem(x_tmp, group->generator->X)) ||
+        (!BN_to_felem(y_tmp, group->generator->Y)) ||
+        (!BN_to_felem(z_tmp, group->generator->Z)))
+        goto err;
+    felem_shrink(pre->g_pre_comp[0][1][0], x_tmp);
+    felem_shrink(pre->g_pre_comp[0][1][1], y_tmp);
+    felem_shrink(pre->g_pre_comp[0][1][2], z_tmp);
+    /*
+     * compute 2^64*G, 2^128*G, 2^192*G for the first table, 2^32*G, 2^96*G,
+     * 2^160*G, 2^224*G for the second one
+     */
+    for (i = 1; i <= 8; i <<= 1) {
+        point_double_small(pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1],
+                           pre->g_pre_comp[1][i][2], pre->g_pre_comp[0][i][0],
+                           pre->g_pre_comp[0][i][1],
+                           pre->g_pre_comp[0][i][2]);
+        for (j = 0; j < 31; ++j) {
+            point_double_small(pre->g_pre_comp[1][i][0],
+                               pre->g_pre_comp[1][i][1],
+                               pre->g_pre_comp[1][i][2],
+                               pre->g_pre_comp[1][i][0],
+                               pre->g_pre_comp[1][i][1],
+                               pre->g_pre_comp[1][i][2]);
+        }
+        if (i == 8)
+            break;
+        point_double_small(pre->g_pre_comp[0][2 * i][0],
+                           pre->g_pre_comp[0][2 * i][1],
+                           pre->g_pre_comp[0][2 * i][2],
+                           pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1],
+                           pre->g_pre_comp[1][i][2]);
+        for (j = 0; j < 31; ++j) {
+            point_double_small(pre->g_pre_comp[0][2 * i][0],
+                               pre->g_pre_comp[0][2 * i][1],
+                               pre->g_pre_comp[0][2 * i][2],
+                               pre->g_pre_comp[0][2 * i][0],
+                               pre->g_pre_comp[0][2 * i][1],
+                               pre->g_pre_comp[0][2 * i][2]);
+        }
+    }
+    for (i = 0; i < 2; i++) {
+        /* g_pre_comp[i][0] is the point at infinity */
+        memset(pre->g_pre_comp[i][0], 0, sizeof(pre->g_pre_comp[i][0]));
+        /* the remaining multiples */
+        /* 2^64*G + 2^128*G resp. 2^96*G + 2^160*G */
+        point_add_small(pre->g_pre_comp[i][6][0], pre->g_pre_comp[i][6][1],
+                        pre->g_pre_comp[i][6][2], pre->g_pre_comp[i][4][0],
+                        pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2],
+                        pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
+                        pre->g_pre_comp[i][2][2]);
+        /* 2^64*G + 2^192*G resp. 2^96*G + 2^224*G */
+        point_add_small(pre->g_pre_comp[i][10][0], pre->g_pre_comp[i][10][1],
+                        pre->g_pre_comp[i][10][2], pre->g_pre_comp[i][8][0],
+                        pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
+                        pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
+                        pre->g_pre_comp[i][2][2]);
+        /* 2^128*G + 2^192*G resp. 2^160*G + 2^224*G */
+        point_add_small(pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1],
+                        pre->g_pre_comp[i][12][2], pre->g_pre_comp[i][8][0],
+                        pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2],
+                        pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1],
+                        pre->g_pre_comp[i][4][2]);
+        /*
+         * 2^64*G + 2^128*G + 2^192*G resp. 2^96*G + 2^160*G + 2^224*G
+         */
+        point_add_small(pre->g_pre_comp[i][14][0], pre->g_pre_comp[i][14][1],
+                        pre->g_pre_comp[i][14][2], pre->g_pre_comp[i][12][0],
+                        pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2],
+                        pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1],
+                        pre->g_pre_comp[i][2][2]);
+        for (j = 1; j < 8; ++j) {
+            /* odd multiples: add G resp. 2^32*G */
+            point_add_small(pre->g_pre_comp[i][2 * j + 1][0],
+                            pre->g_pre_comp[i][2 * j + 1][1],
+                            pre->g_pre_comp[i][2 * j + 1][2],
+                            pre->g_pre_comp[i][2 * j][0],
+                            pre->g_pre_comp[i][2 * j][1],
+                            pre->g_pre_comp[i][2 * j][2],
+                            pre->g_pre_comp[i][1][0],
+                            pre->g_pre_comp[i][1][1],
+                            pre->g_pre_comp[i][1][2]);
+        }
+    }
+    make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_smallfelems);
+
+ done:
+    SETPRECOMP(group, nistp256, pre);
+    pre = NULL;
+    ret = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    EC_POINT_free(generator);
+    BN_CTX_free(new_ctx);
+    EC_nistp256_pre_comp_free(pre);
+    return ret;
+}
+
+int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group)
+{
+    return HAVEPRECOMP(group, nistp256);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_nistp521.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_nistp521.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_nistp521.c	(revision 331)
@@ -0,0 +1,2146 @@
+/*
+ * Copyright 2011-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
+ */
+
+/* Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ *
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/*
+ * A 64-bit implementation of the NIST P-521 elliptic curve point multiplication
+ *
+ * OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c.
+ * Otherwise based on Emilia's P224 work, which was inspired by my curve25519
+ * work which got its smarts from Daniel J. Bernstein's work on the same.
+ */
+
+#include <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# ifndef OPENSSL_SYS_VMS
+#  include <stdint.h>
+# else
+#  include <inttypes.h>
+# endif
+
+# include <string.h>
+# include <openssl/err.h>
+# include "ec_lcl.h"
+
+# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+  /* even with gcc, the typedef won't work for 32-bit platforms */
+typedef __uint128_t uint128_t;  /* nonstandard; implemented by gcc on 64-bit
+                                 * platforms */
+# else
+#  error "Need GCC 3.1 or later to define type uint128_t"
+# endif
+
+typedef uint8_t u8;
+typedef uint64_t u64;
+typedef int64_t s64;
+
+/*
+ * The underlying field. P521 operates over GF(2^521-1). We can serialise an
+ * element of this field into 66 bytes where the most significant byte
+ * contains only a single bit. We call this an felem_bytearray.
+ */
+
+typedef u8 felem_bytearray[66];
+
+/*
+ * These are the parameters of P521, taken from FIPS 186-3, section D.1.2.5.
+ * These values are big-endian.
+ */
+static const felem_bytearray nistp521_curve_params[5] = {
+    {0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* p */
+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+     0xff, 0xff},
+    {0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* a = -3 */
+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+     0xff, 0xfc},
+    {0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, /* b */
+     0x9a, 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85,
+     0x40, 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3,
+     0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1,
+     0x09, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e,
+     0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1,
+     0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c,
+     0x34, 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50,
+     0x3f, 0x00},
+    {0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, /* x */
+     0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95,
+     0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
+     0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d,
+     0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7,
+     0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
+     0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a,
+     0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5,
+     0xbd, 0x66},
+    {0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, /* y */
+     0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d,
+     0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
+     0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e,
+     0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4,
+     0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
+     0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72,
+     0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1,
+     0x66, 0x50}
+};
+
+/*-
+ * The representation of field elements.
+ * ------------------------------------
+ *
+ * We represent field elements with nine values. These values are either 64 or
+ * 128 bits and the field element represented is:
+ *   v[0]*2^0 + v[1]*2^58 + v[2]*2^116 + ... + v[8]*2^464  (mod p)
+ * Each of the nine values is called a 'limb'. Since the limbs are spaced only
+ * 58 bits apart, but are greater than 58 bits in length, the most significant
+ * bits of each limb overlap with the least significant bits of the next.
+ *
+ * A field element with 64-bit limbs is an 'felem'. One with 128-bit limbs is a
+ * 'largefelem' */
+
+# define NLIMBS 9
+
+typedef uint64_t limb;
+typedef limb felem[NLIMBS];
+typedef uint128_t largefelem[NLIMBS];
+
+static const limb bottom57bits = 0x1ffffffffffffff;
+static const limb bottom58bits = 0x3ffffffffffffff;
+
+/*
+ * bin66_to_felem takes a little-endian byte array and converts it into felem
+ * form. This assumes that the CPU is little-endian.
+ */
+static void bin66_to_felem(felem out, const u8 in[66])
+{
+    out[0] = (*((limb *) & in[0])) & bottom58bits;
+    out[1] = (*((limb *) & in[7]) >> 2) & bottom58bits;
+    out[2] = (*((limb *) & in[14]) >> 4) & bottom58bits;
+    out[3] = (*((limb *) & in[21]) >> 6) & bottom58bits;
+    out[4] = (*((limb *) & in[29])) & bottom58bits;
+    out[5] = (*((limb *) & in[36]) >> 2) & bottom58bits;
+    out[6] = (*((limb *) & in[43]) >> 4) & bottom58bits;
+    out[7] = (*((limb *) & in[50]) >> 6) & bottom58bits;
+    out[8] = (*((limb *) & in[58])) & bottom57bits;
+}
+
+/*
+ * felem_to_bin66 takes an felem and serialises into a little endian, 66 byte
+ * array. This assumes that the CPU is little-endian.
+ */
+static void felem_to_bin66(u8 out[66], const felem in)
+{
+    memset(out, 0, 66);
+    (*((limb *) & out[0])) = in[0];
+    (*((limb *) & out[7])) |= in[1] << 2;
+    (*((limb *) & out[14])) |= in[2] << 4;
+    (*((limb *) & out[21])) |= in[3] << 6;
+    (*((limb *) & out[29])) = in[4];
+    (*((limb *) & out[36])) |= in[5] << 2;
+    (*((limb *) & out[43])) |= in[6] << 4;
+    (*((limb *) & out[50])) |= in[7] << 6;
+    (*((limb *) & out[58])) = in[8];
+}
+
+/* To preserve endianness when using BN_bn2bin and BN_bin2bn */
+static void flip_endian(u8 *out, const u8 *in, unsigned len)
+{
+    unsigned i;
+    for (i = 0; i < len; ++i)
+        out[i] = in[len - 1 - i];
+}
+
+/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
+static int BN_to_felem(felem out, const BIGNUM *bn)
+{
+    felem_bytearray b_in;
+    felem_bytearray b_out;
+    unsigned num_bytes;
+
+    /* BN_bn2bin eats leading zeroes */
+    memset(b_out, 0, sizeof(b_out));
+    num_bytes = BN_num_bytes(bn);
+    if (num_bytes > sizeof b_out) {
+        ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+        return 0;
+    }
+    if (BN_is_negative(bn)) {
+        ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE);
+        return 0;
+    }
+    num_bytes = BN_bn2bin(bn, b_in);
+    flip_endian(b_out, b_in, num_bytes);
+    bin66_to_felem(out, b_out);
+    return 1;
+}
+
+/* felem_to_BN converts an felem into an OpenSSL BIGNUM */
+static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
+{
+    felem_bytearray b_in, b_out;
+    felem_to_bin66(b_in, in);
+    flip_endian(b_out, b_in, sizeof b_out);
+    return BN_bin2bn(b_out, sizeof b_out, out);
+}
+
+/*-
+ * Field operations
+ * ----------------
+ */
+
+static void felem_one(felem out)
+{
+    out[0] = 1;
+    out[1] = 0;
+    out[2] = 0;
+    out[3] = 0;
+    out[4] = 0;
+    out[5] = 0;
+    out[6] = 0;
+    out[7] = 0;
+    out[8] = 0;
+}
+
+static void felem_assign(felem out, const felem in)
+{
+    out[0] = in[0];
+    out[1] = in[1];
+    out[2] = in[2];
+    out[3] = in[3];
+    out[4] = in[4];
+    out[5] = in[5];
+    out[6] = in[6];
+    out[7] = in[7];
+    out[8] = in[8];
+}
+
+/* felem_sum64 sets out = out + in. */
+static void felem_sum64(felem out, const felem in)
+{
+    out[0] += in[0];
+    out[1] += in[1];
+    out[2] += in[2];
+    out[3] += in[3];
+    out[4] += in[4];
+    out[5] += in[5];
+    out[6] += in[6];
+    out[7] += in[7];
+    out[8] += in[8];
+}
+
+/* felem_scalar sets out = in * scalar */
+static void felem_scalar(felem out, const felem in, limb scalar)
+{
+    out[0] = in[0] * scalar;
+    out[1] = in[1] * scalar;
+    out[2] = in[2] * scalar;
+    out[3] = in[3] * scalar;
+    out[4] = in[4] * scalar;
+    out[5] = in[5] * scalar;
+    out[6] = in[6] * scalar;
+    out[7] = in[7] * scalar;
+    out[8] = in[8] * scalar;
+}
+
+/* felem_scalar64 sets out = out * scalar */
+static void felem_scalar64(felem out, limb scalar)
+{
+    out[0] *= scalar;
+    out[1] *= scalar;
+    out[2] *= scalar;
+    out[3] *= scalar;
+    out[4] *= scalar;
+    out[5] *= scalar;
+    out[6] *= scalar;
+    out[7] *= scalar;
+    out[8] *= scalar;
+}
+
+/* felem_scalar128 sets out = out * scalar */
+static void felem_scalar128(largefelem out, limb scalar)
+{
+    out[0] *= scalar;
+    out[1] *= scalar;
+    out[2] *= scalar;
+    out[3] *= scalar;
+    out[4] *= scalar;
+    out[5] *= scalar;
+    out[6] *= scalar;
+    out[7] *= scalar;
+    out[8] *= scalar;
+}
+
+/*-
+ * felem_neg sets |out| to |-in|
+ * On entry:
+ *   in[i] < 2^59 + 2^14
+ * On exit:
+ *   out[i] < 2^62
+ */
+static void felem_neg(felem out, const felem in)
+{
+    /* In order to prevent underflow, we subtract from 0 mod p. */
+    static const limb two62m3 = (((limb) 1) << 62) - (((limb) 1) << 5);
+    static const limb two62m2 = (((limb) 1) << 62) - (((limb) 1) << 4);
+
+    out[0] = two62m3 - in[0];
+    out[1] = two62m2 - in[1];
+    out[2] = two62m2 - in[2];
+    out[3] = two62m2 - in[3];
+    out[4] = two62m2 - in[4];
+    out[5] = two62m2 - in[5];
+    out[6] = two62m2 - in[6];
+    out[7] = two62m2 - in[7];
+    out[8] = two62m2 - in[8];
+}
+
+/*-
+ * felem_diff64 subtracts |in| from |out|
+ * On entry:
+ *   in[i] < 2^59 + 2^14
+ * On exit:
+ *   out[i] < out[i] + 2^62
+ */
+static void felem_diff64(felem out, const felem in)
+{
+    /*
+     * In order to prevent underflow, we add 0 mod p before subtracting.
+     */
+    static const limb two62m3 = (((limb) 1) << 62) - (((limb) 1) << 5);
+    static const limb two62m2 = (((limb) 1) << 62) - (((limb) 1) << 4);
+
+    out[0] += two62m3 - in[0];
+    out[1] += two62m2 - in[1];
+    out[2] += two62m2 - in[2];
+    out[3] += two62m2 - in[3];
+    out[4] += two62m2 - in[4];
+    out[5] += two62m2 - in[5];
+    out[6] += two62m2 - in[6];
+    out[7] += two62m2 - in[7];
+    out[8] += two62m2 - in[8];
+}
+
+/*-
+ * felem_diff_128_64 subtracts |in| from |out|
+ * On entry:
+ *   in[i] < 2^62 + 2^17
+ * On exit:
+ *   out[i] < out[i] + 2^63
+ */
+static void felem_diff_128_64(largefelem out, const felem in)
+{
+    /*
+     * In order to prevent underflow, we add 0 mod p before subtracting.
+     */
+    static const limb two63m6 = (((limb) 1) << 62) - (((limb) 1) << 5);
+    static const limb two63m5 = (((limb) 1) << 62) - (((limb) 1) << 4);
+
+    out[0] += two63m6 - in[0];
+    out[1] += two63m5 - in[1];
+    out[2] += two63m5 - in[2];
+    out[3] += two63m5 - in[3];
+    out[4] += two63m5 - in[4];
+    out[5] += two63m5 - in[5];
+    out[6] += two63m5 - in[6];
+    out[7] += two63m5 - in[7];
+    out[8] += two63m5 - in[8];
+}
+
+/*-
+ * felem_diff_128_64 subtracts |in| from |out|
+ * On entry:
+ *   in[i] < 2^126
+ * On exit:
+ *   out[i] < out[i] + 2^127 - 2^69
+ */
+static void felem_diff128(largefelem out, const largefelem in)
+{
+    /*
+     * In order to prevent underflow, we add 0 mod p before subtracting.
+     */
+    static const uint128_t two127m70 =
+        (((uint128_t) 1) << 127) - (((uint128_t) 1) << 70);
+    static const uint128_t two127m69 =
+        (((uint128_t) 1) << 127) - (((uint128_t) 1) << 69);
+
+    out[0] += (two127m70 - in[0]);
+    out[1] += (two127m69 - in[1]);
+    out[2] += (two127m69 - in[2]);
+    out[3] += (two127m69 - in[3]);
+    out[4] += (two127m69 - in[4]);
+    out[5] += (two127m69 - in[5]);
+    out[6] += (two127m69 - in[6]);
+    out[7] += (two127m69 - in[7]);
+    out[8] += (two127m69 - in[8]);
+}
+
+/*-
+ * felem_square sets |out| = |in|^2
+ * On entry:
+ *   in[i] < 2^62
+ * On exit:
+ *   out[i] < 17 * max(in[i]) * max(in[i])
+ */
+static void felem_square(largefelem out, const felem in)
+{
+    felem inx2, inx4;
+    felem_scalar(inx2, in, 2);
+    felem_scalar(inx4, in, 4);
+
+    /*-
+     * We have many cases were we want to do
+     *   in[x] * in[y] +
+     *   in[y] * in[x]
+     * This is obviously just
+     *   2 * in[x] * in[y]
+     * However, rather than do the doubling on the 128 bit result, we
+     * double one of the inputs to the multiplication by reading from
+     * |inx2|
+     */
+
+    out[0] = ((uint128_t) in[0]) * in[0];
+    out[1] = ((uint128_t) in[0]) * inx2[1];
+    out[2] = ((uint128_t) in[0]) * inx2[2] + ((uint128_t) in[1]) * in[1];
+    out[3] = ((uint128_t) in[0]) * inx2[3] + ((uint128_t) in[1]) * inx2[2];
+    out[4] = ((uint128_t) in[0]) * inx2[4] +
+             ((uint128_t) in[1]) * inx2[3] + ((uint128_t) in[2]) * in[2];
+    out[5] = ((uint128_t) in[0]) * inx2[5] +
+             ((uint128_t) in[1]) * inx2[4] + ((uint128_t) in[2]) * inx2[3];
+    out[6] = ((uint128_t) in[0]) * inx2[6] +
+             ((uint128_t) in[1]) * inx2[5] +
+             ((uint128_t) in[2]) * inx2[4] + ((uint128_t) in[3]) * in[3];
+    out[7] = ((uint128_t) in[0]) * inx2[7] +
+             ((uint128_t) in[1]) * inx2[6] +
+             ((uint128_t) in[2]) * inx2[5] + ((uint128_t) in[3]) * inx2[4];
+    out[8] = ((uint128_t) in[0]) * inx2[8] +
+             ((uint128_t) in[1]) * inx2[7] +
+             ((uint128_t) in[2]) * inx2[6] +
+             ((uint128_t) in[3]) * inx2[5] + ((uint128_t) in[4]) * in[4];
+
+    /*
+     * The remaining limbs fall above 2^521, with the first falling at 2^522.
+     * They correspond to locations one bit up from the limbs produced above
+     * so we would have to multiply by two to align them. Again, rather than
+     * operate on the 128-bit result, we double one of the inputs to the
+     * multiplication. If we want to double for both this reason, and the
+     * reason above, then we end up multiplying by four.
+     */
+
+    /* 9 */
+    out[0] += ((uint128_t) in[1]) * inx4[8] +
+              ((uint128_t) in[2]) * inx4[7] +
+              ((uint128_t) in[3]) * inx4[6] + ((uint128_t) in[4]) * inx4[5];
+
+    /* 10 */
+    out[1] += ((uint128_t) in[2]) * inx4[8] +
+              ((uint128_t) in[3]) * inx4[7] +
+              ((uint128_t) in[4]) * inx4[6] + ((uint128_t) in[5]) * inx2[5];
+
+    /* 11 */
+    out[2] += ((uint128_t) in[3]) * inx4[8] +
+              ((uint128_t) in[4]) * inx4[7] + ((uint128_t) in[5]) * inx4[6];
+
+    /* 12 */
+    out[3] += ((uint128_t) in[4]) * inx4[8] +
+              ((uint128_t) in[5]) * inx4[7] + ((uint128_t) in[6]) * inx2[6];
+
+    /* 13 */
+    out[4] += ((uint128_t) in[5]) * inx4[8] + ((uint128_t) in[6]) * inx4[7];
+
+    /* 14 */
+    out[5] += ((uint128_t) in[6]) * inx4[8] + ((uint128_t) in[7]) * inx2[7];
+
+    /* 15 */
+    out[6] += ((uint128_t) in[7]) * inx4[8];
+
+    /* 16 */
+    out[7] += ((uint128_t) in[8]) * inx2[8];
+}
+
+/*-
+ * felem_mul sets |out| = |in1| * |in2|
+ * On entry:
+ *   in1[i] < 2^64
+ *   in2[i] < 2^63
+ * On exit:
+ *   out[i] < 17 * max(in1[i]) * max(in2[i])
+ */
+static void felem_mul(largefelem out, const felem in1, const felem in2)
+{
+    felem in2x2;
+    felem_scalar(in2x2, in2, 2);
+
+    out[0] = ((uint128_t) in1[0]) * in2[0];
+
+    out[1] = ((uint128_t) in1[0]) * in2[1] +
+             ((uint128_t) in1[1]) * in2[0];
+
+    out[2] = ((uint128_t) in1[0]) * in2[2] +
+             ((uint128_t) in1[1]) * in2[1] +
+             ((uint128_t) in1[2]) * in2[0];
+
+    out[3] = ((uint128_t) in1[0]) * in2[3] +
+             ((uint128_t) in1[1]) * in2[2] +
+             ((uint128_t) in1[2]) * in2[1] +
+             ((uint128_t) in1[3]) * in2[0];
+
+    out[4] = ((uint128_t) in1[0]) * in2[4] +
+             ((uint128_t) in1[1]) * in2[3] +
+             ((uint128_t) in1[2]) * in2[2] +
+             ((uint128_t) in1[3]) * in2[1] +
+             ((uint128_t) in1[4]) * in2[0];
+
+    out[5] = ((uint128_t) in1[0]) * in2[5] +
+             ((uint128_t) in1[1]) * in2[4] +
+             ((uint128_t) in1[2]) * in2[3] +
+             ((uint128_t) in1[3]) * in2[2] +
+             ((uint128_t) in1[4]) * in2[1] +
+             ((uint128_t) in1[5]) * in2[0];
+
+    out[6] = ((uint128_t) in1[0]) * in2[6] +
+             ((uint128_t) in1[1]) * in2[5] +
+             ((uint128_t) in1[2]) * in2[4] +
+             ((uint128_t) in1[3]) * in2[3] +
+             ((uint128_t) in1[4]) * in2[2] +
+             ((uint128_t) in1[5]) * in2[1] +
+             ((uint128_t) in1[6]) * in2[0];
+
+    out[7] = ((uint128_t) in1[0]) * in2[7] +
+             ((uint128_t) in1[1]) * in2[6] +
+             ((uint128_t) in1[2]) * in2[5] +
+             ((uint128_t) in1[3]) * in2[4] +
+             ((uint128_t) in1[4]) * in2[3] +
+             ((uint128_t) in1[5]) * in2[2] +
+             ((uint128_t) in1[6]) * in2[1] +
+             ((uint128_t) in1[7]) * in2[0];
+
+    out[8] = ((uint128_t) in1[0]) * in2[8] +
+             ((uint128_t) in1[1]) * in2[7] +
+             ((uint128_t) in1[2]) * in2[6] +
+             ((uint128_t) in1[3]) * in2[5] +
+             ((uint128_t) in1[4]) * in2[4] +
+             ((uint128_t) in1[5]) * in2[3] +
+             ((uint128_t) in1[6]) * in2[2] +
+             ((uint128_t) in1[7]) * in2[1] +
+             ((uint128_t) in1[8]) * in2[0];
+
+    /* See comment in felem_square about the use of in2x2 here */
+
+    out[0] += ((uint128_t) in1[1]) * in2x2[8] +
+              ((uint128_t) in1[2]) * in2x2[7] +
+              ((uint128_t) in1[3]) * in2x2[6] +
+              ((uint128_t) in1[4]) * in2x2[5] +
+              ((uint128_t) in1[5]) * in2x2[4] +
+              ((uint128_t) in1[6]) * in2x2[3] +
+              ((uint128_t) in1[7]) * in2x2[2] +
+              ((uint128_t) in1[8]) * in2x2[1];
+
+    out[1] += ((uint128_t) in1[2]) * in2x2[8] +
+              ((uint128_t) in1[3]) * in2x2[7] +
+              ((uint128_t) in1[4]) * in2x2[6] +
+              ((uint128_t) in1[5]) * in2x2[5] +
+              ((uint128_t) in1[6]) * in2x2[4] +
+              ((uint128_t) in1[7]) * in2x2[3] +
+              ((uint128_t) in1[8]) * in2x2[2];
+
+    out[2] += ((uint128_t) in1[3]) * in2x2[8] +
+              ((uint128_t) in1[4]) * in2x2[7] +
+              ((uint128_t) in1[5]) * in2x2[6] +
+              ((uint128_t) in1[6]) * in2x2[5] +
+              ((uint128_t) in1[7]) * in2x2[4] +
+              ((uint128_t) in1[8]) * in2x2[3];
+
+    out[3] += ((uint128_t) in1[4]) * in2x2[8] +
+              ((uint128_t) in1[5]) * in2x2[7] +
+              ((uint128_t) in1[6]) * in2x2[6] +
+              ((uint128_t) in1[7]) * in2x2[5] +
+              ((uint128_t) in1[8]) * in2x2[4];
+
+    out[4] += ((uint128_t) in1[5]) * in2x2[8] +
+              ((uint128_t) in1[6]) * in2x2[7] +
+              ((uint128_t) in1[7]) * in2x2[6] +
+              ((uint128_t) in1[8]) * in2x2[5];
+
+    out[5] += ((uint128_t) in1[6]) * in2x2[8] +
+              ((uint128_t) in1[7]) * in2x2[7] +
+              ((uint128_t) in1[8]) * in2x2[6];
+
+    out[6] += ((uint128_t) in1[7]) * in2x2[8] +
+              ((uint128_t) in1[8]) * in2x2[7];
+
+    out[7] += ((uint128_t) in1[8]) * in2x2[8];
+}
+
+static const limb bottom52bits = 0xfffffffffffff;
+
+/*-
+ * felem_reduce converts a largefelem to an felem.
+ * On entry:
+ *   in[i] < 2^128
+ * On exit:
+ *   out[i] < 2^59 + 2^14
+ */
+static void felem_reduce(felem out, const largefelem in)
+{
+    u64 overflow1, overflow2;
+
+    out[0] = ((limb) in[0]) & bottom58bits;
+    out[1] = ((limb) in[1]) & bottom58bits;
+    out[2] = ((limb) in[2]) & bottom58bits;
+    out[3] = ((limb) in[3]) & bottom58bits;
+    out[4] = ((limb) in[4]) & bottom58bits;
+    out[5] = ((limb) in[5]) & bottom58bits;
+    out[6] = ((limb) in[6]) & bottom58bits;
+    out[7] = ((limb) in[7]) & bottom58bits;
+    out[8] = ((limb) in[8]) & bottom58bits;
+
+    /* out[i] < 2^58 */
+
+    out[1] += ((limb) in[0]) >> 58;
+    out[1] += (((limb) (in[0] >> 64)) & bottom52bits) << 6;
+    /*-
+     * out[1] < 2^58 + 2^6 + 2^58
+     *        = 2^59 + 2^6
+     */
+    out[2] += ((limb) (in[0] >> 64)) >> 52;
+
+    out[2] += ((limb) in[1]) >> 58;
+    out[2] += (((limb) (in[1] >> 64)) & bottom52bits) << 6;
+    out[3] += ((limb) (in[1] >> 64)) >> 52;
+
+    out[3] += ((limb) in[2]) >> 58;
+    out[3] += (((limb) (in[2] >> 64)) & bottom52bits) << 6;
+    out[4] += ((limb) (in[2] >> 64)) >> 52;
+
+    out[4] += ((limb) in[3]) >> 58;
+    out[4] += (((limb) (in[3] >> 64)) & bottom52bits) << 6;
+    out[5] += ((limb) (in[3] >> 64)) >> 52;
+
+    out[5] += ((limb) in[4]) >> 58;
+    out[5] += (((limb) (in[4] >> 64)) & bottom52bits) << 6;
+    out[6] += ((limb) (in[4] >> 64)) >> 52;
+
+    out[6] += ((limb) in[5]) >> 58;
+    out[6] += (((limb) (in[5] >> 64)) & bottom52bits) << 6;
+    out[7] += ((limb) (in[5] >> 64)) >> 52;
+
+    out[7] += ((limb) in[6]) >> 58;
+    out[7] += (((limb) (in[6] >> 64)) & bottom52bits) << 6;
+    out[8] += ((limb) (in[6] >> 64)) >> 52;
+
+    out[8] += ((limb) in[7]) >> 58;
+    out[8] += (((limb) (in[7] >> 64)) & bottom52bits) << 6;
+    /*-
+     * out[x > 1] < 2^58 + 2^6 + 2^58 + 2^12
+     *            < 2^59 + 2^13
+     */
+    overflow1 = ((limb) (in[7] >> 64)) >> 52;
+
+    overflow1 += ((limb) in[8]) >> 58;
+    overflow1 += (((limb) (in[8] >> 64)) & bottom52bits) << 6;
+    overflow2 = ((limb) (in[8] >> 64)) >> 52;
+
+    overflow1 <<= 1;            /* overflow1 < 2^13 + 2^7 + 2^59 */
+    overflow2 <<= 1;            /* overflow2 < 2^13 */
+
+    out[0] += overflow1;        /* out[0] < 2^60 */
+    out[1] += overflow2;        /* out[1] < 2^59 + 2^6 + 2^13 */
+
+    out[1] += out[0] >> 58;
+    out[0] &= bottom58bits;
+    /*-
+     * out[0] < 2^58
+     * out[1] < 2^59 + 2^6 + 2^13 + 2^2
+     *        < 2^59 + 2^14
+     */
+}
+
+static void felem_square_reduce(felem out, const felem in)
+{
+    largefelem tmp;
+    felem_square(tmp, in);
+    felem_reduce(out, tmp);
+}
+
+static void felem_mul_reduce(felem out, const felem in1, const felem in2)
+{
+    largefelem tmp;
+    felem_mul(tmp, in1, in2);
+    felem_reduce(out, tmp);
+}
+
+/*-
+ * felem_inv calculates |out| = |in|^{-1}
+ *
+ * Based on Fermat's Little Theorem:
+ *   a^p = a (mod p)
+ *   a^{p-1} = 1 (mod p)
+ *   a^{p-2} = a^{-1} (mod p)
+ */
+static void felem_inv(felem out, const felem in)
+{
+    felem ftmp, ftmp2, ftmp3, ftmp4;
+    largefelem tmp;
+    unsigned i;
+
+    felem_square(tmp, in);
+    felem_reduce(ftmp, tmp);    /* 2^1 */
+    felem_mul(tmp, in, ftmp);
+    felem_reduce(ftmp, tmp);    /* 2^2 - 2^0 */
+    felem_assign(ftmp2, ftmp);
+    felem_square(tmp, ftmp);
+    felem_reduce(ftmp, tmp);    /* 2^3 - 2^1 */
+    felem_mul(tmp, in, ftmp);
+    felem_reduce(ftmp, tmp);    /* 2^3 - 2^0 */
+    felem_square(tmp, ftmp);
+    felem_reduce(ftmp, tmp);    /* 2^4 - 2^1 */
+
+    felem_square(tmp, ftmp2);
+    felem_reduce(ftmp3, tmp);   /* 2^3 - 2^1 */
+    felem_square(tmp, ftmp3);
+    felem_reduce(ftmp3, tmp);   /* 2^4 - 2^2 */
+    felem_mul(tmp, ftmp3, ftmp2);
+    felem_reduce(ftmp3, tmp);   /* 2^4 - 2^0 */
+
+    felem_assign(ftmp2, ftmp3);
+    felem_square(tmp, ftmp3);
+    felem_reduce(ftmp3, tmp);   /* 2^5 - 2^1 */
+    felem_square(tmp, ftmp3);
+    felem_reduce(ftmp3, tmp);   /* 2^6 - 2^2 */
+    felem_square(tmp, ftmp3);
+    felem_reduce(ftmp3, tmp);   /* 2^7 - 2^3 */
+    felem_square(tmp, ftmp3);
+    felem_reduce(ftmp3, tmp);   /* 2^8 - 2^4 */
+    felem_assign(ftmp4, ftmp3);
+    felem_mul(tmp, ftmp3, ftmp);
+    felem_reduce(ftmp4, tmp);   /* 2^8 - 2^1 */
+    felem_square(tmp, ftmp4);
+    felem_reduce(ftmp4, tmp);   /* 2^9 - 2^2 */
+    felem_mul(tmp, ftmp3, ftmp2);
+    felem_reduce(ftmp3, tmp);   /* 2^8 - 2^0 */
+    felem_assign(ftmp2, ftmp3);
+
+    for (i = 0; i < 8; i++) {
+        felem_square(tmp, ftmp3);
+        felem_reduce(ftmp3, tmp); /* 2^16 - 2^8 */
+    }
+    felem_mul(tmp, ftmp3, ftmp2);
+    felem_reduce(ftmp3, tmp);   /* 2^16 - 2^0 */
+    felem_assign(ftmp2, ftmp3);
+
+    for (i = 0; i < 16; i++) {
+        felem_square(tmp, ftmp3);
+        felem_reduce(ftmp3, tmp); /* 2^32 - 2^16 */
+    }
+    felem_mul(tmp, ftmp3, ftmp2);
+    felem_reduce(ftmp3, tmp);   /* 2^32 - 2^0 */
+    felem_assign(ftmp2, ftmp3);
+
+    for (i = 0; i < 32; i++) {
+        felem_square(tmp, ftmp3);
+        felem_reduce(ftmp3, tmp); /* 2^64 - 2^32 */
+    }
+    felem_mul(tmp, ftmp3, ftmp2);
+    felem_reduce(ftmp3, tmp);   /* 2^64 - 2^0 */
+    felem_assign(ftmp2, ftmp3);
+
+    for (i = 0; i < 64; i++) {
+        felem_square(tmp, ftmp3);
+        felem_reduce(ftmp3, tmp); /* 2^128 - 2^64 */
+    }
+    felem_mul(tmp, ftmp3, ftmp2);
+    felem_reduce(ftmp3, tmp);   /* 2^128 - 2^0 */
+    felem_assign(ftmp2, ftmp3);
+
+    for (i = 0; i < 128; i++) {
+        felem_square(tmp, ftmp3);
+        felem_reduce(ftmp3, tmp); /* 2^256 - 2^128 */
+    }
+    felem_mul(tmp, ftmp3, ftmp2);
+    felem_reduce(ftmp3, tmp);   /* 2^256 - 2^0 */
+    felem_assign(ftmp2, ftmp3);
+
+    for (i = 0; i < 256; i++) {
+        felem_square(tmp, ftmp3);
+        felem_reduce(ftmp3, tmp); /* 2^512 - 2^256 */
+    }
+    felem_mul(tmp, ftmp3, ftmp2);
+    felem_reduce(ftmp3, tmp);   /* 2^512 - 2^0 */
+
+    for (i = 0; i < 9; i++) {
+        felem_square(tmp, ftmp3);
+        felem_reduce(ftmp3, tmp); /* 2^521 - 2^9 */
+    }
+    felem_mul(tmp, ftmp3, ftmp4);
+    felem_reduce(ftmp3, tmp);   /* 2^512 - 2^2 */
+    felem_mul(tmp, ftmp3, in);
+    felem_reduce(out, tmp);     /* 2^512 - 3 */
+}
+
+/* This is 2^521-1, expressed as an felem */
+static const felem kPrime = {
+    0x03ffffffffffffff, 0x03ffffffffffffff, 0x03ffffffffffffff,
+    0x03ffffffffffffff, 0x03ffffffffffffff, 0x03ffffffffffffff,
+    0x03ffffffffffffff, 0x03ffffffffffffff, 0x01ffffffffffffff
+};
+
+/*-
+ * felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0
+ * otherwise.
+ * On entry:
+ *   in[i] < 2^59 + 2^14
+ */
+static limb felem_is_zero(const felem in)
+{
+    felem ftmp;
+    limb is_zero, is_p;
+    felem_assign(ftmp, in);
+
+    ftmp[0] += ftmp[8] >> 57;
+    ftmp[8] &= bottom57bits;
+    /* ftmp[8] < 2^57 */
+    ftmp[1] += ftmp[0] >> 58;
+    ftmp[0] &= bottom58bits;
+    ftmp[2] += ftmp[1] >> 58;
+    ftmp[1] &= bottom58bits;
+    ftmp[3] += ftmp[2] >> 58;
+    ftmp[2] &= bottom58bits;
+    ftmp[4] += ftmp[3] >> 58;
+    ftmp[3] &= bottom58bits;
+    ftmp[5] += ftmp[4] >> 58;
+    ftmp[4] &= bottom58bits;
+    ftmp[6] += ftmp[5] >> 58;
+    ftmp[5] &= bottom58bits;
+    ftmp[7] += ftmp[6] >> 58;
+    ftmp[6] &= bottom58bits;
+    ftmp[8] += ftmp[7] >> 58;
+    ftmp[7] &= bottom58bits;
+    /* ftmp[8] < 2^57 + 4 */
+
+    /*
+     * The ninth limb of 2*(2^521-1) is 0x03ffffffffffffff, which is greater
+     * than our bound for ftmp[8]. Therefore we only have to check if the
+     * zero is zero or 2^521-1.
+     */
+
+    is_zero = 0;
+    is_zero |= ftmp[0];
+    is_zero |= ftmp[1];
+    is_zero |= ftmp[2];
+    is_zero |= ftmp[3];
+    is_zero |= ftmp[4];
+    is_zero |= ftmp[5];
+    is_zero |= ftmp[6];
+    is_zero |= ftmp[7];
+    is_zero |= ftmp[8];
+
+    is_zero--;
+    /*
+     * We know that ftmp[i] < 2^63, therefore the only way that the top bit
+     * can be set is if is_zero was 0 before the decrement.
+     */
+    is_zero = ((s64) is_zero) >> 63;
+
+    is_p = ftmp[0] ^ kPrime[0];
+    is_p |= ftmp[1] ^ kPrime[1];
+    is_p |= ftmp[2] ^ kPrime[2];
+    is_p |= ftmp[3] ^ kPrime[3];
+    is_p |= ftmp[4] ^ kPrime[4];
+    is_p |= ftmp[5] ^ kPrime[5];
+    is_p |= ftmp[6] ^ kPrime[6];
+    is_p |= ftmp[7] ^ kPrime[7];
+    is_p |= ftmp[8] ^ kPrime[8];
+
+    is_p--;
+    is_p = ((s64) is_p) >> 63;
+
+    is_zero |= is_p;
+    return is_zero;
+}
+
+static int felem_is_zero_int(const felem in)
+{
+    return (int)(felem_is_zero(in) & ((limb) 1));
+}
+
+/*-
+ * felem_contract converts |in| to its unique, minimal representation.
+ * On entry:
+ *   in[i] < 2^59 + 2^14
+ */
+static void felem_contract(felem out, const felem in)
+{
+    limb is_p, is_greater, sign;
+    static const limb two58 = ((limb) 1) << 58;
+
+    felem_assign(out, in);
+
+    out[0] += out[8] >> 57;
+    out[8] &= bottom57bits;
+    /* out[8] < 2^57 */
+    out[1] += out[0] >> 58;
+    out[0] &= bottom58bits;
+    out[2] += out[1] >> 58;
+    out[1] &= bottom58bits;
+    out[3] += out[2] >> 58;
+    out[2] &= bottom58bits;
+    out[4] += out[3] >> 58;
+    out[3] &= bottom58bits;
+    out[5] += out[4] >> 58;
+    out[4] &= bottom58bits;
+    out[6] += out[5] >> 58;
+    out[5] &= bottom58bits;
+    out[7] += out[6] >> 58;
+    out[6] &= bottom58bits;
+    out[8] += out[7] >> 58;
+    out[7] &= bottom58bits;
+    /* out[8] < 2^57 + 4 */
+
+    /*
+     * If the value is greater than 2^521-1 then we have to subtract 2^521-1
+     * out. See the comments in felem_is_zero regarding why we don't test for
+     * other multiples of the prime.
+     */
+
+    /*
+     * First, if |out| is equal to 2^521-1, we subtract it out to get zero.
+     */
+
+    is_p = out[0] ^ kPrime[0];
+    is_p |= out[1] ^ kPrime[1];
+    is_p |= out[2] ^ kPrime[2];
+    is_p |= out[3] ^ kPrime[3];
+    is_p |= out[4] ^ kPrime[4];
+    is_p |= out[5] ^ kPrime[5];
+    is_p |= out[6] ^ kPrime[6];
+    is_p |= out[7] ^ kPrime[7];
+    is_p |= out[8] ^ kPrime[8];
+
+    is_p--;
+    is_p &= is_p << 32;
+    is_p &= is_p << 16;
+    is_p &= is_p << 8;
+    is_p &= is_p << 4;
+    is_p &= is_p << 2;
+    is_p &= is_p << 1;
+    is_p = ((s64) is_p) >> 63;
+    is_p = ~is_p;
+
+    /* is_p is 0 iff |out| == 2^521-1 and all ones otherwise */
+
+    out[0] &= is_p;
+    out[1] &= is_p;
+    out[2] &= is_p;
+    out[3] &= is_p;
+    out[4] &= is_p;
+    out[5] &= is_p;
+    out[6] &= is_p;
+    out[7] &= is_p;
+    out[8] &= is_p;
+
+    /*
+     * In order to test that |out| >= 2^521-1 we need only test if out[8] >>
+     * 57 is greater than zero as (2^521-1) + x >= 2^522
+     */
+    is_greater = out[8] >> 57;
+    is_greater |= is_greater << 32;
+    is_greater |= is_greater << 16;
+    is_greater |= is_greater << 8;
+    is_greater |= is_greater << 4;
+    is_greater |= is_greater << 2;
+    is_greater |= is_greater << 1;
+    is_greater = ((s64) is_greater) >> 63;
+
+    out[0] -= kPrime[0] & is_greater;
+    out[1] -= kPrime[1] & is_greater;
+    out[2] -= kPrime[2] & is_greater;
+    out[3] -= kPrime[3] & is_greater;
+    out[4] -= kPrime[4] & is_greater;
+    out[5] -= kPrime[5] & is_greater;
+    out[6] -= kPrime[6] & is_greater;
+    out[7] -= kPrime[7] & is_greater;
+    out[8] -= kPrime[8] & is_greater;
+
+    /* Eliminate negative coefficients */
+    sign = -(out[0] >> 63);
+    out[0] += (two58 & sign);
+    out[1] -= (1 & sign);
+    sign = -(out[1] >> 63);
+    out[1] += (two58 & sign);
+    out[2] -= (1 & sign);
+    sign = -(out[2] >> 63);
+    out[2] += (two58 & sign);
+    out[3] -= (1 & sign);
+    sign = -(out[3] >> 63);
+    out[3] += (two58 & sign);
+    out[4] -= (1 & sign);
+    sign = -(out[4] >> 63);
+    out[4] += (two58 & sign);
+    out[5] -= (1 & sign);
+    sign = -(out[0] >> 63);
+    out[5] += (two58 & sign);
+    out[6] -= (1 & sign);
+    sign = -(out[6] >> 63);
+    out[6] += (two58 & sign);
+    out[7] -= (1 & sign);
+    sign = -(out[7] >> 63);
+    out[7] += (two58 & sign);
+    out[8] -= (1 & sign);
+    sign = -(out[5] >> 63);
+    out[5] += (two58 & sign);
+    out[6] -= (1 & sign);
+    sign = -(out[6] >> 63);
+    out[6] += (two58 & sign);
+    out[7] -= (1 & sign);
+    sign = -(out[7] >> 63);
+    out[7] += (two58 & sign);
+    out[8] -= (1 & sign);
+}
+
+/*-
+ * Group operations
+ * ----------------
+ *
+ * Building on top of the field operations we have the operations on the
+ * elliptic curve group itself. Points on the curve are represented in Jacobian
+ * coordinates */
+
+/*-
+ * point_double calculates 2*(x_in, y_in, z_in)
+ *
+ * The method is taken from:
+ *   http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
+ *
+ * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed.
+ * while x_out == y_in is not (maybe this works, but it's not tested). */
+static void
+point_double(felem x_out, felem y_out, felem z_out,
+             const felem x_in, const felem y_in, const felem z_in)
+{
+    largefelem tmp, tmp2;
+    felem delta, gamma, beta, alpha, ftmp, ftmp2;
+
+    felem_assign(ftmp, x_in);
+    felem_assign(ftmp2, x_in);
+
+    /* delta = z^2 */
+    felem_square(tmp, z_in);
+    felem_reduce(delta, tmp);   /* delta[i] < 2^59 + 2^14 */
+
+    /* gamma = y^2 */
+    felem_square(tmp, y_in);
+    felem_reduce(gamma, tmp);   /* gamma[i] < 2^59 + 2^14 */
+
+    /* beta = x*gamma */
+    felem_mul(tmp, x_in, gamma);
+    felem_reduce(beta, tmp);    /* beta[i] < 2^59 + 2^14 */
+
+    /* alpha = 3*(x-delta)*(x+delta) */
+    felem_diff64(ftmp, delta);
+    /* ftmp[i] < 2^61 */
+    felem_sum64(ftmp2, delta);
+    /* ftmp2[i] < 2^60 + 2^15 */
+    felem_scalar64(ftmp2, 3);
+    /* ftmp2[i] < 3*2^60 + 3*2^15 */
+    felem_mul(tmp, ftmp, ftmp2);
+    /*-
+     * tmp[i] < 17(3*2^121 + 3*2^76)
+     *        = 61*2^121 + 61*2^76
+     *        < 64*2^121 + 64*2^76
+     *        = 2^127 + 2^82
+     *        < 2^128
+     */
+    felem_reduce(alpha, tmp);
+
+    /* x' = alpha^2 - 8*beta */
+    felem_square(tmp, alpha);
+    /*
+     * tmp[i] < 17*2^120 < 2^125
+     */
+    felem_assign(ftmp, beta);
+    felem_scalar64(ftmp, 8);
+    /* ftmp[i] < 2^62 + 2^17 */
+    felem_diff_128_64(tmp, ftmp);
+    /* tmp[i] < 2^125 + 2^63 + 2^62 + 2^17 */
+    felem_reduce(x_out, tmp);
+
+    /* z' = (y + z)^2 - gamma - delta */
+    felem_sum64(delta, gamma);
+    /* delta[i] < 2^60 + 2^15 */
+    felem_assign(ftmp, y_in);
+    felem_sum64(ftmp, z_in);
+    /* ftmp[i] < 2^60 + 2^15 */
+    felem_square(tmp, ftmp);
+    /*
+     * tmp[i] < 17(2^122) < 2^127
+     */
+    felem_diff_128_64(tmp, delta);
+    /* tmp[i] < 2^127 + 2^63 */
+    felem_reduce(z_out, tmp);
+
+    /* y' = alpha*(4*beta - x') - 8*gamma^2 */
+    felem_scalar64(beta, 4);
+    /* beta[i] < 2^61 + 2^16 */
+    felem_diff64(beta, x_out);
+    /* beta[i] < 2^61 + 2^60 + 2^16 */
+    felem_mul(tmp, alpha, beta);
+    /*-
+     * tmp[i] < 17*((2^59 + 2^14)(2^61 + 2^60 + 2^16))
+     *        = 17*(2^120 + 2^75 + 2^119 + 2^74 + 2^75 + 2^30)
+     *        = 17*(2^120 + 2^119 + 2^76 + 2^74 + 2^30)
+     *        < 2^128
+     */
+    felem_square(tmp2, gamma);
+    /*-
+     * tmp2[i] < 17*(2^59 + 2^14)^2
+     *         = 17*(2^118 + 2^74 + 2^28)
+     */
+    felem_scalar128(tmp2, 8);
+    /*-
+     * tmp2[i] < 8*17*(2^118 + 2^74 + 2^28)
+     *         = 2^125 + 2^121 + 2^81 + 2^77 + 2^35 + 2^31
+     *         < 2^126
+     */
+    felem_diff128(tmp, tmp2);
+    /*-
+     * tmp[i] < 2^127 - 2^69 + 17(2^120 + 2^119 + 2^76 + 2^74 + 2^30)
+     *        = 2^127 + 2^124 + 2^122 + 2^120 + 2^118 + 2^80 + 2^78 + 2^76 +
+     *          2^74 + 2^69 + 2^34 + 2^30
+     *        < 2^128
+     */
+    felem_reduce(y_out, tmp);
+}
+
+/* copy_conditional copies in to out iff mask is all ones. */
+static void copy_conditional(felem out, const felem in, limb mask)
+{
+    unsigned i;
+    for (i = 0; i < NLIMBS; ++i) {
+        const limb tmp = mask & (in[i] ^ out[i]);
+        out[i] ^= tmp;
+    }
+}
+
+/*-
+ * point_add calculates (x1, y1, z1) + (x2, y2, z2)
+ *
+ * The method is taken from
+ *   http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl,
+ * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity).
+ *
+ * This function includes a branch for checking whether the two input points
+ * are equal (while not equal to the point at infinity). This case never
+ * happens during single point multiplication, so there is no timing leak for
+ * ECDH or ECDSA signing. */
+static void point_add(felem x3, felem y3, felem z3,
+                      const felem x1, const felem y1, const felem z1,
+                      const int mixed, const felem x2, const felem y2,
+                      const felem z2)
+{
+    felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out;
+    largefelem tmp, tmp2;
+    limb x_equal, y_equal, z1_is_zero, z2_is_zero;
+
+    z1_is_zero = felem_is_zero(z1);
+    z2_is_zero = felem_is_zero(z2);
+
+    /* ftmp = z1z1 = z1**2 */
+    felem_square(tmp, z1);
+    felem_reduce(ftmp, tmp);
+
+    if (!mixed) {
+        /* ftmp2 = z2z2 = z2**2 */
+        felem_square(tmp, z2);
+        felem_reduce(ftmp2, tmp);
+
+        /* u1 = ftmp3 = x1*z2z2 */
+        felem_mul(tmp, x1, ftmp2);
+        felem_reduce(ftmp3, tmp);
+
+        /* ftmp5 = z1 + z2 */
+        felem_assign(ftmp5, z1);
+        felem_sum64(ftmp5, z2);
+        /* ftmp5[i] < 2^61 */
+
+        /* ftmp5 = (z1 + z2)**2 - z1z1 - z2z2 = 2*z1z2 */
+        felem_square(tmp, ftmp5);
+        /* tmp[i] < 17*2^122 */
+        felem_diff_128_64(tmp, ftmp);
+        /* tmp[i] < 17*2^122 + 2^63 */
+        felem_diff_128_64(tmp, ftmp2);
+        /* tmp[i] < 17*2^122 + 2^64 */
+        felem_reduce(ftmp5, tmp);
+
+        /* ftmp2 = z2 * z2z2 */
+        felem_mul(tmp, ftmp2, z2);
+        felem_reduce(ftmp2, tmp);
+
+        /* s1 = ftmp6 = y1 * z2**3 */
+        felem_mul(tmp, y1, ftmp2);
+        felem_reduce(ftmp6, tmp);
+    } else {
+        /*
+         * We'll assume z2 = 1 (special case z2 = 0 is handled later)
+         */
+
+        /* u1 = ftmp3 = x1*z2z2 */
+        felem_assign(ftmp3, x1);
+
+        /* ftmp5 = 2*z1z2 */
+        felem_scalar(ftmp5, z1, 2);
+
+        /* s1 = ftmp6 = y1 * z2**3 */
+        felem_assign(ftmp6, y1);
+    }
+
+    /* u2 = x2*z1z1 */
+    felem_mul(tmp, x2, ftmp);
+    /* tmp[i] < 17*2^120 */
+
+    /* h = ftmp4 = u2 - u1 */
+    felem_diff_128_64(tmp, ftmp3);
+    /* tmp[i] < 17*2^120 + 2^63 */
+    felem_reduce(ftmp4, tmp);
+
+    x_equal = felem_is_zero(ftmp4);
+
+    /* z_out = ftmp5 * h */
+    felem_mul(tmp, ftmp5, ftmp4);
+    felem_reduce(z_out, tmp);
+
+    /* ftmp = z1 * z1z1 */
+    felem_mul(tmp, ftmp, z1);
+    felem_reduce(ftmp, tmp);
+
+    /* s2 = tmp = y2 * z1**3 */
+    felem_mul(tmp, y2, ftmp);
+    /* tmp[i] < 17*2^120 */
+
+    /* r = ftmp5 = (s2 - s1)*2 */
+    felem_diff_128_64(tmp, ftmp6);
+    /* tmp[i] < 17*2^120 + 2^63 */
+    felem_reduce(ftmp5, tmp);
+    y_equal = felem_is_zero(ftmp5);
+    felem_scalar64(ftmp5, 2);
+    /* ftmp5[i] < 2^61 */
+
+    if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) {
+        point_double(x3, y3, z3, x1, y1, z1);
+        return;
+    }
+
+    /* I = ftmp = (2h)**2 */
+    felem_assign(ftmp, ftmp4);
+    felem_scalar64(ftmp, 2);
+    /* ftmp[i] < 2^61 */
+    felem_square(tmp, ftmp);
+    /* tmp[i] < 17*2^122 */
+    felem_reduce(ftmp, tmp);
+
+    /* J = ftmp2 = h * I */
+    felem_mul(tmp, ftmp4, ftmp);
+    felem_reduce(ftmp2, tmp);
+
+    /* V = ftmp4 = U1 * I */
+    felem_mul(tmp, ftmp3, ftmp);
+    felem_reduce(ftmp4, tmp);
+
+    /* x_out = r**2 - J - 2V */
+    felem_square(tmp, ftmp5);
+    /* tmp[i] < 17*2^122 */
+    felem_diff_128_64(tmp, ftmp2);
+    /* tmp[i] < 17*2^122 + 2^63 */
+    felem_assign(ftmp3, ftmp4);
+    felem_scalar64(ftmp4, 2);
+    /* ftmp4[i] < 2^61 */
+    felem_diff_128_64(tmp, ftmp4);
+    /* tmp[i] < 17*2^122 + 2^64 */
+    felem_reduce(x_out, tmp);
+
+    /* y_out = r(V-x_out) - 2 * s1 * J */
+    felem_diff64(ftmp3, x_out);
+    /*
+     * ftmp3[i] < 2^60 + 2^60 = 2^61
+     */
+    felem_mul(tmp, ftmp5, ftmp3);
+    /* tmp[i] < 17*2^122 */
+    felem_mul(tmp2, ftmp6, ftmp2);
+    /* tmp2[i] < 17*2^120 */
+    felem_scalar128(tmp2, 2);
+    /* tmp2[i] < 17*2^121 */
+    felem_diff128(tmp, tmp2);
+        /*-
+         * tmp[i] < 2^127 - 2^69 + 17*2^122
+         *        = 2^126 - 2^122 - 2^6 - 2^2 - 1
+         *        < 2^127
+         */
+    felem_reduce(y_out, tmp);
+
+    copy_conditional(x_out, x2, z1_is_zero);
+    copy_conditional(x_out, x1, z2_is_zero);
+    copy_conditional(y_out, y2, z1_is_zero);
+    copy_conditional(y_out, y1, z2_is_zero);
+    copy_conditional(z_out, z2, z1_is_zero);
+    copy_conditional(z_out, z1, z2_is_zero);
+    felem_assign(x3, x_out);
+    felem_assign(y3, y_out);
+    felem_assign(z3, z_out);
+}
+
+/*-
+ * Base point pre computation
+ * --------------------------
+ *
+ * Two different sorts of precomputed tables are used in the following code.
+ * Each contain various points on the curve, where each point is three field
+ * elements (x, y, z).
+ *
+ * For the base point table, z is usually 1 (0 for the point at infinity).
+ * This table has 16 elements:
+ * index | bits    | point
+ * ------+---------+------------------------------
+ *     0 | 0 0 0 0 | 0G
+ *     1 | 0 0 0 1 | 1G
+ *     2 | 0 0 1 0 | 2^130G
+ *     3 | 0 0 1 1 | (2^130 + 1)G
+ *     4 | 0 1 0 0 | 2^260G
+ *     5 | 0 1 0 1 | (2^260 + 1)G
+ *     6 | 0 1 1 0 | (2^260 + 2^130)G
+ *     7 | 0 1 1 1 | (2^260 + 2^130 + 1)G
+ *     8 | 1 0 0 0 | 2^390G
+ *     9 | 1 0 0 1 | (2^390 + 1)G
+ *    10 | 1 0 1 0 | (2^390 + 2^130)G
+ *    11 | 1 0 1 1 | (2^390 + 2^130 + 1)G
+ *    12 | 1 1 0 0 | (2^390 + 2^260)G
+ *    13 | 1 1 0 1 | (2^390 + 2^260 + 1)G
+ *    14 | 1 1 1 0 | (2^390 + 2^260 + 2^130)G
+ *    15 | 1 1 1 1 | (2^390 + 2^260 + 2^130 + 1)G
+ *
+ * The reason for this is so that we can clock bits into four different
+ * locations when doing simple scalar multiplies against the base point.
+ *
+ * Tables for other points have table[i] = iG for i in 0 .. 16. */
+
+/* gmul is the table of precomputed base points */
+static const felem gmul[16][3] = {
+{{0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x017e7e31c2e5bd66, 0x022cf0615a90a6fe, 0x00127a2ffa8de334,
+  0x01dfbf9d64a3f877, 0x006b4d3dbaa14b5e, 0x014fed487e0a2bd8,
+  0x015b4429c6481390, 0x03a73678fb2d988e, 0x00c6858e06b70404},
+ {0x00be94769fd16650, 0x031c21a89cb09022, 0x039013fad0761353,
+  0x02657bd099031542, 0x03273e662c97ee72, 0x01e6d11a05ebef45,
+  0x03d1bd998f544495, 0x03001172297ed0b1, 0x011839296a789a3b},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x0373faacbc875bae, 0x00f325023721c671, 0x00f666fd3dbde5ad,
+  0x01a6932363f88ea7, 0x01fc6d9e13f9c47b, 0x03bcbffc2bbf734e,
+  0x013ee3c3647f3a92, 0x029409fefe75d07d, 0x00ef9199963d85e5},
+ {0x011173743ad5b178, 0x02499c7c21bf7d46, 0x035beaeabb8b1a58,
+  0x00f989c4752ea0a3, 0x0101e1de48a9c1a3, 0x01a20076be28ba6c,
+  0x02f8052e5eb2de95, 0x01bfe8f82dea117c, 0x0160074d3c36ddb7},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x012f3fc373393b3b, 0x03d3d6172f1419fa, 0x02adc943c0b86873,
+  0x00d475584177952b, 0x012a4d1673750ee2, 0x00512517a0f13b0c,
+  0x02b184671a7b1734, 0x0315b84236f1a50a, 0x00a4afc472edbdb9},
+ {0x00152a7077f385c4, 0x03044007d8d1c2ee, 0x0065829d61d52b52,
+  0x00494ff6b6631d0d, 0x00a11d94d5f06bcf, 0x02d2f89474d9282e,
+  0x0241c5727c06eeb9, 0x0386928710fbdb9d, 0x01f883f727b0dfbe},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x019b0c3c9185544d, 0x006243a37c9d97db, 0x02ee3cbe030a2ad2,
+  0x00cfdd946bb51e0d, 0x0271c00932606b91, 0x03f817d1ec68c561,
+  0x03f37009806a369c, 0x03c1f30baf184fd5, 0x01091022d6d2f065},
+ {0x0292c583514c45ed, 0x0316fca51f9a286c, 0x00300af507c1489a,
+  0x0295f69008298cf1, 0x02c0ed8274943d7b, 0x016509b9b47a431e,
+  0x02bc9de9634868ce, 0x005b34929bffcb09, 0x000c1a0121681524},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x0286abc0292fb9f2, 0x02665eee9805b3f7, 0x01ed7455f17f26d6,
+  0x0346355b83175d13, 0x006284944cd0a097, 0x0191895bcdec5e51,
+  0x02e288370afda7d9, 0x03b22312bfefa67a, 0x01d104d3fc0613fe},
+ {0x0092421a12f7e47f, 0x0077a83fa373c501, 0x03bd25c5f696bd0d,
+  0x035c41e4d5459761, 0x01ca0d1742b24f53, 0x00aaab27863a509c,
+  0x018b6de47df73917, 0x025c0b771705cd01, 0x01fd51d566d760a7},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x01dd92ff6b0d1dbd, 0x039c5e2e8f8afa69, 0x0261ed13242c3b27,
+  0x0382c6e67026e6a0, 0x01d60b10be2089f9, 0x03c15f3dce86723f,
+  0x03c764a32d2a062d, 0x017307eac0fad056, 0x018207c0b96c5256},
+ {0x0196a16d60e13154, 0x03e6ce74c0267030, 0x00ddbf2b4e52a5aa,
+  0x012738241bbf31c8, 0x00ebe8dc04685a28, 0x024c2ad6d380d4a2,
+  0x035ee062a6e62d0e, 0x0029ed74af7d3a0f, 0x00eef32aec142ebd},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x00c31ec398993b39, 0x03a9f45bcda68253, 0x00ac733c24c70890,
+  0x00872b111401ff01, 0x01d178c23195eafb, 0x03bca2c816b87f74,
+  0x0261a9af46fbad7a, 0x0324b2a8dd3d28f9, 0x00918121d8f24e23},
+ {0x032bc8c1ca983cd7, 0x00d869dfb08fc8c6, 0x01693cb61fce1516,
+  0x012a5ea68f4e88a8, 0x010869cab88d7ae3, 0x009081ad277ceee1,
+  0x033a77166d064cdc, 0x03955235a1fb3a95, 0x01251a4a9b25b65e},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x00148a3a1b27f40b, 0x0123186df1b31fdc, 0x00026e7beaad34ce,
+  0x01db446ac1d3dbba, 0x0299c1a33437eaec, 0x024540610183cbb7,
+  0x0173bb0e9ce92e46, 0x02b937e43921214b, 0x01ab0436a9bf01b5},
+ {0x0383381640d46948, 0x008dacbf0e7f330f, 0x03602122bcc3f318,
+  0x01ee596b200620d6, 0x03bd0585fda430b3, 0x014aed77fd123a83,
+  0x005ace749e52f742, 0x0390fe041da2b842, 0x0189a8ceb3299242},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x012a19d6b3282473, 0x00c0915918b423ce, 0x023a954eb94405ae,
+  0x00529f692be26158, 0x0289fa1b6fa4b2aa, 0x0198ae4ceea346ef,
+  0x0047d8cdfbdedd49, 0x00cc8c8953f0f6b8, 0x001424abbff49203},
+ {0x0256732a1115a03a, 0x0351bc38665c6733, 0x03f7b950fb4a6447,
+  0x000afffa94c22155, 0x025763d0a4dab540, 0x000511e92d4fc283,
+  0x030a7e9eda0ee96c, 0x004c3cd93a28bf0a, 0x017edb3a8719217f},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x011de5675a88e673, 0x031d7d0f5e567fbe, 0x0016b2062c970ae5,
+  0x03f4a2be49d90aa7, 0x03cef0bd13822866, 0x03f0923dcf774a6c,
+  0x0284bebc4f322f72, 0x016ab2645302bb2c, 0x01793f95dace0e2a},
+ {0x010646e13527a28f, 0x01ca1babd59dc5e7, 0x01afedfd9a5595df,
+  0x01f15785212ea6b1, 0x0324e5d64f6ae3f4, 0x02d680f526d00645,
+  0x0127920fadf627a7, 0x03b383f75df4f684, 0x0089e0057e783b0a},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x00f334b9eb3c26c6, 0x0298fdaa98568dce, 0x01c2d24843a82292,
+  0x020bcb24fa1b0711, 0x02cbdb3d2b1875e6, 0x0014907598f89422,
+  0x03abe3aa43b26664, 0x02cbf47f720bc168, 0x0133b5e73014b79b},
+ {0x034aab5dab05779d, 0x00cdc5d71fee9abb, 0x0399f16bd4bd9d30,
+  0x03582fa592d82647, 0x02be1cdfb775b0e9, 0x0034f7cea32e94cb,
+  0x0335a7f08f56f286, 0x03b707e9565d1c8b, 0x0015c946ea5b614f},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x024676f6cff72255, 0x00d14625cac96378, 0x00532b6008bc3767,
+  0x01fc16721b985322, 0x023355ea1b091668, 0x029de7afdc0317c3,
+  0x02fc8a7ca2da037c, 0x02de1217d74a6f30, 0x013f7173175b73bf},
+ {0x0344913f441490b5, 0x0200f9e272b61eca, 0x0258a246b1dd55d2,
+  0x03753db9ea496f36, 0x025e02937a09c5ef, 0x030cbd3d14012692,
+  0x01793a67e70dc72a, 0x03ec1d37048a662e, 0x006550f700c32a8d},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x00d3f48a347eba27, 0x008e636649b61bd8, 0x00d3b93716778fb3,
+  0x004d1915757bd209, 0x019d5311a3da44e0, 0x016d1afcbbe6aade,
+  0x0241bf5f73265616, 0x0384672e5d50d39b, 0x005009fee522b684},
+ {0x029b4fab064435fe, 0x018868ee095bbb07, 0x01ea3d6936cc92b8,
+  0x000608b00f78a2f3, 0x02db911073d1c20f, 0x018205938470100a,
+  0x01f1e4964cbe6ff2, 0x021a19a29eed4663, 0x01414485f42afa81},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x01612b3a17f63e34, 0x03813992885428e6, 0x022b3c215b5a9608,
+  0x029b4057e19f2fcb, 0x0384059a587af7e6, 0x02d6400ace6fe610,
+  0x029354d896e8e331, 0x00c047ee6dfba65e, 0x0037720542e9d49d},
+ {0x02ce9eed7c5e9278, 0x0374ed703e79643b, 0x01316c54c4072006,
+  0x005aaa09054b2ee8, 0x002824000c840d57, 0x03d4eba24771ed86,
+  0x0189c50aabc3bdae, 0x0338c01541e15510, 0x00466d56e38eed42},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}},
+{{0x007efd8330ad8bd6, 0x02465ed48047710b, 0x0034c6606b215e0c,
+  0x016ae30c53cbf839, 0x01fa17bd37161216, 0x018ead4e61ce8ab9,
+  0x005482ed5f5dee46, 0x037543755bba1d7f, 0x005e5ac7e70a9d0f},
+ {0x0117e1bb2fdcb2a2, 0x03deea36249f40c4, 0x028d09b4a6246cb7,
+  0x03524b8855bcf756, 0x023d7d109d5ceb58, 0x0178e43e3223ef9c,
+  0x0154536a0c6e966a, 0x037964d1286ee9fe, 0x0199bcd90e125055},
+ {1, 0, 0, 0, 0, 0, 0, 0, 0}}
+};
+
+/*
+ * select_point selects the |idx|th point from a precomputation table and
+ * copies it to out.
+ */
+ /* pre_comp below is of the size provided in |size| */
+static void select_point(const limb idx, unsigned int size,
+                         const felem pre_comp[][3], felem out[3])
+{
+    unsigned i, j;
+    limb *outlimbs = &out[0][0];
+
+    memset(out, 0, sizeof(*out) * 3);
+
+    for (i = 0; i < size; i++) {
+        const limb *inlimbs = &pre_comp[i][0][0];
+        limb mask = i ^ idx;
+        mask |= mask >> 4;
+        mask |= mask >> 2;
+        mask |= mask >> 1;
+        mask &= 1;
+        mask--;
+        for (j = 0; j < NLIMBS * 3; j++)
+            outlimbs[j] |= inlimbs[j] & mask;
+    }
+}
+
+/* get_bit returns the |i|th bit in |in| */
+static char get_bit(const felem_bytearray in, int i)
+{
+    if (i < 0)
+        return 0;
+    return (in[i >> 3] >> (i & 7)) & 1;
+}
+
+/*
+ * Interleaved point multiplication using precomputed point multiples: The
+ * small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[], the scalars
+ * in scalars[]. If g_scalar is non-NULL, we also add this multiple of the
+ * generator, using certain (large) precomputed multiples in g_pre_comp.
+ * Output point (X, Y, Z) is stored in x_out, y_out, z_out
+ */
+static void batch_mul(felem x_out, felem y_out, felem z_out,
+                      const felem_bytearray scalars[],
+                      const unsigned num_points, const u8 *g_scalar,
+                      const int mixed, const felem pre_comp[][17][3],
+                      const felem g_pre_comp[16][3])
+{
+    int i, skip;
+    unsigned num, gen_mul = (g_scalar != NULL);
+    felem nq[3], tmp[4];
+    limb bits;
+    u8 sign, digit;
+
+    /* set nq to the point at infinity */
+    memset(nq, 0, sizeof(nq));
+
+    /*
+     * Loop over all scalars msb-to-lsb, interleaving additions of multiples
+     * of the generator (last quarter of rounds) and additions of other
+     * points multiples (every 5th round).
+     */
+    skip = 1;                   /* save two point operations in the first
+                                 * round */
+    for (i = (num_points ? 520 : 130); i >= 0; --i) {
+        /* double */
+        if (!skip)
+            point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
+
+        /* add multiples of the generator */
+        if (gen_mul && (i <= 130)) {
+            bits = get_bit(g_scalar, i + 390) << 3;
+            if (i < 130) {
+                bits |= get_bit(g_scalar, i + 260) << 2;
+                bits |= get_bit(g_scalar, i + 130) << 1;
+                bits |= get_bit(g_scalar, i);
+            }
+            /* select the point to add, in constant time */
+            select_point(bits, 16, g_pre_comp, tmp);
+            if (!skip) {
+                /* The 1 argument below is for "mixed" */
+                point_add(nq[0], nq[1], nq[2],
+                          nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]);
+            } else {
+                memcpy(nq, tmp, 3 * sizeof(felem));
+                skip = 0;
+            }
+        }
+
+        /* do other additions every 5 doublings */
+        if (num_points && (i % 5 == 0)) {
+            /* loop over all scalars */
+            for (num = 0; num < num_points; ++num) {
+                bits = get_bit(scalars[num], i + 4) << 5;
+                bits |= get_bit(scalars[num], i + 3) << 4;
+                bits |= get_bit(scalars[num], i + 2) << 3;
+                bits |= get_bit(scalars[num], i + 1) << 2;
+                bits |= get_bit(scalars[num], i) << 1;
+                bits |= get_bit(scalars[num], i - 1);
+                ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
+
+                /*
+                 * select the point to add or subtract, in constant time
+                 */
+                select_point(digit, 17, pre_comp[num], tmp);
+                felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative
+                                            * point */
+                copy_conditional(tmp[1], tmp[3], (-(limb) sign));
+
+                if (!skip) {
+                    point_add(nq[0], nq[1], nq[2],
+                              nq[0], nq[1], nq[2],
+                              mixed, tmp[0], tmp[1], tmp[2]);
+                } else {
+                    memcpy(nq, tmp, 3 * sizeof(felem));
+                    skip = 0;
+                }
+            }
+        }
+    }
+    felem_assign(x_out, nq[0]);
+    felem_assign(y_out, nq[1]);
+    felem_assign(z_out, nq[2]);
+}
+
+/* Precomputation for the group generator. */
+struct nistp521_pre_comp_st {
+    felem g_pre_comp[16][3];
+    int references;
+    CRYPTO_RWLOCK *lock;
+};
+
+const EC_METHOD *EC_GFp_nistp521_method(void)
+{
+    static const EC_METHOD ret = {
+        EC_FLAGS_DEFAULT_OCT,
+        NID_X9_62_prime_field,
+        ec_GFp_nistp521_group_init,
+        ec_GFp_simple_group_finish,
+        ec_GFp_simple_group_clear_finish,
+        ec_GFp_nist_group_copy,
+        ec_GFp_nistp521_group_set_curve,
+        ec_GFp_simple_group_get_curve,
+        ec_GFp_simple_group_get_degree,
+        ec_group_simple_order_bits,
+        ec_GFp_simple_group_check_discriminant,
+        ec_GFp_simple_point_init,
+        ec_GFp_simple_point_finish,
+        ec_GFp_simple_point_clear_finish,
+        ec_GFp_simple_point_copy,
+        ec_GFp_simple_point_set_to_infinity,
+        ec_GFp_simple_set_Jprojective_coordinates_GFp,
+        ec_GFp_simple_get_Jprojective_coordinates_GFp,
+        ec_GFp_simple_point_set_affine_coordinates,
+        ec_GFp_nistp521_point_get_affine_coordinates,
+        0 /* point_set_compressed_coordinates */ ,
+        0 /* point2oct */ ,
+        0 /* oct2point */ ,
+        ec_GFp_simple_add,
+        ec_GFp_simple_dbl,
+        ec_GFp_simple_invert,
+        ec_GFp_simple_is_at_infinity,
+        ec_GFp_simple_is_on_curve,
+        ec_GFp_simple_cmp,
+        ec_GFp_simple_make_affine,
+        ec_GFp_simple_points_make_affine,
+        ec_GFp_nistp521_points_mul,
+        ec_GFp_nistp521_precompute_mult,
+        ec_GFp_nistp521_have_precompute_mult,
+        ec_GFp_nist_field_mul,
+        ec_GFp_nist_field_sqr,
+        0 /* field_div */ ,
+        0 /* field_encode */ ,
+        0 /* field_decode */ ,
+        0,                      /* field_set_to_one */
+        ec_key_simple_priv2oct,
+        ec_key_simple_oct2priv,
+        0, /* set private */
+        ec_key_simple_generate_key,
+        ec_key_simple_check_key,
+        ec_key_simple_generate_public_key,
+        0, /* keycopy */
+        0, /* keyfinish */
+        ecdh_simple_compute_key
+    };
+
+    return &ret;
+}
+
+/******************************************************************************/
+/*
+ * FUNCTIONS TO MANAGE PRECOMPUTATION
+ */
+
+static NISTP521_PRE_COMP *nistp521_pre_comp_new()
+{
+    NISTP521_PRE_COMP *ret = OPENSSL_zalloc(sizeof(*ret));
+
+    if (ret == NULL) {
+        ECerr(EC_F_NISTP521_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+        return ret;
+    }
+
+    ret->references = 1;
+
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        ECerr(EC_F_NISTP521_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+NISTP521_PRE_COMP *EC_nistp521_pre_comp_dup(NISTP521_PRE_COMP *p)
+{
+    int i;
+    if (p != NULL)
+        CRYPTO_atomic_add(&p->references, 1, &i, p->lock);
+    return p;
+}
+
+void EC_nistp521_pre_comp_free(NISTP521_PRE_COMP *p)
+{
+    int i;
+
+    if (p == NULL)
+        return;
+
+    CRYPTO_atomic_add(&p->references, -1, &i, p->lock);
+    REF_PRINT_COUNT("EC_nistp521", x);
+    if (i > 0)
+        return;
+    REF_ASSERT_ISNT(i < 0);
+
+    CRYPTO_THREAD_lock_free(p->lock);
+    OPENSSL_free(p);
+}
+
+/******************************************************************************/
+/*
+ * OPENSSL EC_METHOD FUNCTIONS
+ */
+
+int ec_GFp_nistp521_group_init(EC_GROUP *group)
+{
+    int ret;
+    ret = ec_GFp_simple_group_init(group);
+    group->a_is_minus3 = 1;
+    return ret;
+}
+
+int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+                                    const BIGNUM *a, const BIGNUM *b,
+                                    BN_CTX *ctx)
+{
+    int ret = 0;
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *curve_p, *curve_a, *curve_b;
+
+    if (ctx == NULL)
+        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+            return 0;
+    BN_CTX_start(ctx);
+    if (((curve_p = BN_CTX_get(ctx)) == NULL) ||
+        ((curve_a = BN_CTX_get(ctx)) == NULL) ||
+        ((curve_b = BN_CTX_get(ctx)) == NULL))
+        goto err;
+    BN_bin2bn(nistp521_curve_params[0], sizeof(felem_bytearray), curve_p);
+    BN_bin2bn(nistp521_curve_params[1], sizeof(felem_bytearray), curve_a);
+    BN_bin2bn(nistp521_curve_params[2], sizeof(felem_bytearray), curve_b);
+    if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) {
+        ECerr(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE,
+              EC_R_WRONG_CURVE_PARAMETERS);
+        goto err;
+    }
+    group->field_mod_func = BN_nist_mod_521;
+    ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
+ err:
+    BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+/*
+ * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') =
+ * (X/Z^2, Y/Z^3)
+ */
+int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group,
+                                                 const EC_POINT *point,
+                                                 BIGNUM *x, BIGNUM *y,
+                                                 BN_CTX *ctx)
+{
+    felem z1, z2, x_in, y_in, x_out, y_out;
+    largefelem tmp;
+
+    if (EC_POINT_is_at_infinity(group, point)) {
+        ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES,
+              EC_R_POINT_AT_INFINITY);
+        return 0;
+    }
+    if ((!BN_to_felem(x_in, point->X)) || (!BN_to_felem(y_in, point->Y)) ||
+        (!BN_to_felem(z1, point->Z)))
+        return 0;
+    felem_inv(z2, z1);
+    felem_square(tmp, z2);
+    felem_reduce(z1, tmp);
+    felem_mul(tmp, x_in, z1);
+    felem_reduce(x_in, tmp);
+    felem_contract(x_out, x_in);
+    if (x != NULL) {
+        if (!felem_to_BN(x, x_out)) {
+            ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES,
+                  ERR_R_BN_LIB);
+            return 0;
+        }
+    }
+    felem_mul(tmp, z1, z2);
+    felem_reduce(z1, tmp);
+    felem_mul(tmp, y_in, z1);
+    felem_reduce(y_in, tmp);
+    felem_contract(y_out, y_in);
+    if (y != NULL) {
+        if (!felem_to_BN(y, y_out)) {
+            ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES,
+                  ERR_R_BN_LIB);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+/* points below is of size |num|, and tmp_felems is of size |num+1/ */
+static void make_points_affine(size_t num, felem points[][3],
+                               felem tmp_felems[])
+{
+    /*
+     * Runs in constant time, unless an input is the point at infinity (which
+     * normally shouldn't happen).
+     */
+    ec_GFp_nistp_points_make_affine_internal(num,
+                                             points,
+                                             sizeof(felem),
+                                             tmp_felems,
+                                             (void (*)(void *))felem_one,
+                                             (int (*)(const void *))
+                                             felem_is_zero_int,
+                                             (void (*)(void *, const void *))
+                                             felem_assign,
+                                             (void (*)(void *, const void *))
+                                             felem_square_reduce, (void (*)
+                                                                   (void *,
+                                                                    const void
+                                                                    *,
+                                                                    const void
+                                                                    *))
+                                             felem_mul_reduce,
+                                             (void (*)(void *, const void *))
+                                             felem_inv,
+                                             (void (*)(void *, const void *))
+                                             felem_contract);
+}
+
+/*
+ * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL
+ * values Result is stored in r (r can equal one of the inputs).
+ */
+int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
+                               const BIGNUM *scalar, size_t num,
+                               const EC_POINT *points[],
+                               const BIGNUM *scalars[], BN_CTX *ctx)
+{
+    int ret = 0;
+    int j;
+    int mixed = 0;
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *x, *y, *z, *tmp_scalar;
+    felem_bytearray g_secret;
+    felem_bytearray *secrets = NULL;
+    felem (*pre_comp)[17][3] = NULL;
+    felem *tmp_felems = NULL;
+    felem_bytearray tmp;
+    unsigned i, num_bytes;
+    int have_pre_comp = 0;
+    size_t num_points = num;
+    felem x_in, y_in, z_in, x_out, y_out, z_out;
+    NISTP521_PRE_COMP *pre = NULL;
+    felem(*g_pre_comp)[3] = NULL;
+    EC_POINT *generator = NULL;
+    const EC_POINT *p = NULL;
+    const BIGNUM *p_scalar = NULL;
+
+    if (ctx == NULL)
+        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+            return 0;
+    BN_CTX_start(ctx);
+    if (((x = BN_CTX_get(ctx)) == NULL) ||
+        ((y = BN_CTX_get(ctx)) == NULL) ||
+        ((z = BN_CTX_get(ctx)) == NULL) ||
+        ((tmp_scalar = BN_CTX_get(ctx)) == NULL))
+        goto err;
+
+    if (scalar != NULL) {
+        pre = group->pre_comp.nistp521;
+        if (pre)
+            /* we have precomputation, try to use it */
+            g_pre_comp = &pre->g_pre_comp[0];
+        else
+            /* try to use the standard precomputation */
+            g_pre_comp = (felem(*)[3]) gmul;
+        generator = EC_POINT_new(group);
+        if (generator == NULL)
+            goto err;
+        /* get the generator from precomputation */
+        if (!felem_to_BN(x, g_pre_comp[1][0]) ||
+            !felem_to_BN(y, g_pre_comp[1][1]) ||
+            !felem_to_BN(z, g_pre_comp[1][2])) {
+            ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
+            goto err;
+        }
+        if (!EC_POINT_set_Jprojective_coordinates_GFp(group,
+                                                      generator, x, y, z,
+                                                      ctx))
+            goto err;
+        if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
+            /* precomputation matches generator */
+            have_pre_comp = 1;
+        else
+            /*
+             * we don't have valid precomputation: treat the generator as a
+             * random point
+             */
+            num_points++;
+    }
+
+    if (num_points > 0) {
+        if (num_points >= 2) {
+            /*
+             * unless we precompute multiples for just one point, converting
+             * those into affine form is time well spent
+             */
+            mixed = 1;
+        }
+        secrets = OPENSSL_zalloc(sizeof(*secrets) * num_points);
+        pre_comp = OPENSSL_zalloc(sizeof(*pre_comp) * num_points);
+        if (mixed)
+            tmp_felems =
+                OPENSSL_malloc(sizeof(*tmp_felems) * (num_points * 17 + 1));
+        if ((secrets == NULL) || (pre_comp == NULL)
+            || (mixed && (tmp_felems == NULL))) {
+            ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+
+        /*
+         * we treat NULL scalars as 0, and NULL points as points at infinity,
+         * i.e., they contribute nothing to the linear combination
+         */
+        for (i = 0; i < num_points; ++i) {
+            if (i == num)
+                /*
+                 * we didn't have a valid precomputation, so we pick the
+                 * generator
+                 */
+            {
+                p = EC_GROUP_get0_generator(group);
+                p_scalar = scalar;
+            } else
+                /* the i^th point */
+            {
+                p = points[i];
+                p_scalar = scalars[i];
+            }
+            if ((p_scalar != NULL) && (p != NULL)) {
+                /* reduce scalar to 0 <= scalar < 2^521 */
+                if ((BN_num_bits(p_scalar) > 521)
+                    || (BN_is_negative(p_scalar))) {
+                    /*
+                     * this is an unusual input, and we don't guarantee
+                     * constant-timeness
+                     */
+                    if (!BN_nnmod(tmp_scalar, p_scalar, group->order, ctx)) {
+                        ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
+                        goto err;
+                    }
+                    num_bytes = BN_bn2bin(tmp_scalar, tmp);
+                } else
+                    num_bytes = BN_bn2bin(p_scalar, tmp);
+                flip_endian(secrets[i], tmp, num_bytes);
+                /* precompute multiples */
+                if ((!BN_to_felem(x_out, p->X)) ||
+                    (!BN_to_felem(y_out, p->Y)) ||
+                    (!BN_to_felem(z_out, p->Z)))
+                    goto err;
+                memcpy(pre_comp[i][1][0], x_out, sizeof(felem));
+                memcpy(pre_comp[i][1][1], y_out, sizeof(felem));
+                memcpy(pre_comp[i][1][2], z_out, sizeof(felem));
+                for (j = 2; j <= 16; ++j) {
+                    if (j & 1) {
+                        point_add(pre_comp[i][j][0], pre_comp[i][j][1],
+                                  pre_comp[i][j][2], pre_comp[i][1][0],
+                                  pre_comp[i][1][1], pre_comp[i][1][2], 0,
+                                  pre_comp[i][j - 1][0],
+                                  pre_comp[i][j - 1][1],
+                                  pre_comp[i][j - 1][2]);
+                    } else {
+                        point_double(pre_comp[i][j][0], pre_comp[i][j][1],
+                                     pre_comp[i][j][2], pre_comp[i][j / 2][0],
+                                     pre_comp[i][j / 2][1],
+                                     pre_comp[i][j / 2][2]);
+                    }
+                }
+            }
+        }
+        if (mixed)
+            make_points_affine(num_points * 17, pre_comp[0], tmp_felems);
+    }
+
+    /* the scalar for the generator */
+    if ((scalar != NULL) && (have_pre_comp)) {
+        memset(g_secret, 0, sizeof(g_secret));
+        /* reduce scalar to 0 <= scalar < 2^521 */
+        if ((BN_num_bits(scalar) > 521) || (BN_is_negative(scalar))) {
+            /*
+             * this is an unusual input, and we don't guarantee
+             * constant-timeness
+             */
+            if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) {
+                ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
+                goto err;
+            }
+            num_bytes = BN_bn2bin(tmp_scalar, tmp);
+        } else
+            num_bytes = BN_bn2bin(scalar, tmp);
+        flip_endian(g_secret, tmp, num_bytes);
+        /* do the multiplication with generator precomputation */
+        batch_mul(x_out, y_out, z_out,
+                  (const felem_bytearray(*))secrets, num_points,
+                  g_secret,
+                  mixed, (const felem(*)[17][3])pre_comp,
+                  (const felem(*)[3])g_pre_comp);
+    } else
+        /* do the multiplication without generator precomputation */
+        batch_mul(x_out, y_out, z_out,
+                  (const felem_bytearray(*))secrets, num_points,
+                  NULL, mixed, (const felem(*)[17][3])pre_comp, NULL);
+    /* reduce the output to its unique minimal representation */
+    felem_contract(x_in, x_out);
+    felem_contract(y_in, y_out);
+    felem_contract(z_in, z_out);
+    if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) ||
+        (!felem_to_BN(z, z_in))) {
+        ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB);
+        goto err;
+    }
+    ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
+
+ err:
+    BN_CTX_end(ctx);
+    EC_POINT_free(generator);
+    BN_CTX_free(new_ctx);
+    OPENSSL_free(secrets);
+    OPENSSL_free(pre_comp);
+    OPENSSL_free(tmp_felems);
+    return ret;
+}
+
+int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
+{
+    int ret = 0;
+    NISTP521_PRE_COMP *pre = NULL;
+    int i, j;
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *x, *y;
+    EC_POINT *generator = NULL;
+    felem tmp_felems[16];
+
+    /* throw away old precomputation */
+    EC_pre_comp_free(group);
+    if (ctx == NULL)
+        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
+            return 0;
+    BN_CTX_start(ctx);
+    if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL))
+        goto err;
+    /* get the generator */
+    if (group->generator == NULL)
+        goto err;
+    generator = EC_POINT_new(group);
+    if (generator == NULL)
+        goto err;
+    BN_bin2bn(nistp521_curve_params[3], sizeof(felem_bytearray), x);
+    BN_bin2bn(nistp521_curve_params[4], sizeof(felem_bytearray), y);
+    if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx))
+        goto err;
+    if ((pre = nistp521_pre_comp_new()) == NULL)
+        goto err;
+    /*
+     * if the generator is the standard one, use built-in precomputation
+     */
+    if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) {
+        memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
+        goto done;
+    }
+    if ((!BN_to_felem(pre->g_pre_comp[1][0], group->generator->X)) ||
+        (!BN_to_felem(pre->g_pre_comp[1][1], group->generator->Y)) ||
+        (!BN_to_felem(pre->g_pre_comp[1][2], group->generator->Z)))
+        goto err;
+    /* compute 2^130*G, 2^260*G, 2^390*G */
+    for (i = 1; i <= 4; i <<= 1) {
+        point_double(pre->g_pre_comp[2 * i][0], pre->g_pre_comp[2 * i][1],
+                     pre->g_pre_comp[2 * i][2], pre->g_pre_comp[i][0],
+                     pre->g_pre_comp[i][1], pre->g_pre_comp[i][2]);
+        for (j = 0; j < 129; ++j) {
+            point_double(pre->g_pre_comp[2 * i][0],
+                         pre->g_pre_comp[2 * i][1],
+                         pre->g_pre_comp[2 * i][2],
+                         pre->g_pre_comp[2 * i][0],
+                         pre->g_pre_comp[2 * i][1],
+                         pre->g_pre_comp[2 * i][2]);
+        }
+    }
+    /* g_pre_comp[0] is the point at infinity */
+    memset(pre->g_pre_comp[0], 0, sizeof(pre->g_pre_comp[0]));
+    /* the remaining multiples */
+    /* 2^130*G + 2^260*G */
+    point_add(pre->g_pre_comp[6][0], pre->g_pre_comp[6][1],
+              pre->g_pre_comp[6][2], pre->g_pre_comp[4][0],
+              pre->g_pre_comp[4][1], pre->g_pre_comp[4][2],
+              0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
+              pre->g_pre_comp[2][2]);
+    /* 2^130*G + 2^390*G */
+    point_add(pre->g_pre_comp[10][0], pre->g_pre_comp[10][1],
+              pre->g_pre_comp[10][2], pre->g_pre_comp[8][0],
+              pre->g_pre_comp[8][1], pre->g_pre_comp[8][2],
+              0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
+              pre->g_pre_comp[2][2]);
+    /* 2^260*G + 2^390*G */
+    point_add(pre->g_pre_comp[12][0], pre->g_pre_comp[12][1],
+              pre->g_pre_comp[12][2], pre->g_pre_comp[8][0],
+              pre->g_pre_comp[8][1], pre->g_pre_comp[8][2],
+              0, pre->g_pre_comp[4][0], pre->g_pre_comp[4][1],
+              pre->g_pre_comp[4][2]);
+    /* 2^130*G + 2^260*G + 2^390*G */
+    point_add(pre->g_pre_comp[14][0], pre->g_pre_comp[14][1],
+              pre->g_pre_comp[14][2], pre->g_pre_comp[12][0],
+              pre->g_pre_comp[12][1], pre->g_pre_comp[12][2],
+              0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1],
+              pre->g_pre_comp[2][2]);
+    for (i = 1; i < 8; ++i) {
+        /* odd multiples: add G */
+        point_add(pre->g_pre_comp[2 * i + 1][0],
+                  pre->g_pre_comp[2 * i + 1][1],
+                  pre->g_pre_comp[2 * i + 1][2], pre->g_pre_comp[2 * i][0],
+                  pre->g_pre_comp[2 * i][1], pre->g_pre_comp[2 * i][2], 0,
+                  pre->g_pre_comp[1][0], pre->g_pre_comp[1][1],
+                  pre->g_pre_comp[1][2]);
+    }
+    make_points_affine(15, &(pre->g_pre_comp[1]), tmp_felems);
+
+ done:
+    SETPRECOMP(group, nistp521, pre);
+    ret = 1;
+    pre = NULL;
+ err:
+    BN_CTX_end(ctx);
+    EC_POINT_free(generator);
+    BN_CTX_free(new_ctx);
+    EC_nistp521_pre_comp_free(pre);
+    return ret;
+}
+
+int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group)
+{
+    return HAVEPRECOMP(group, nistp521);
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_nistputil.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_nistputil.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_nistputil.c	(revision 331)
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2011-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
+ */
+
+/* Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ *
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_EC_NISTP_64_GCC_128
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+/*
+ * Common utility functions for ecp_nistp224.c, ecp_nistp256.c, ecp_nistp521.c.
+ */
+
+# include <stddef.h>
+# include "ec_lcl.h"
+
+/*
+ * Convert an array of points into affine coordinates. (If the point at
+ * infinity is found (Z = 0), it remains unchanged.) This function is
+ * essentially an equivalent to EC_POINTs_make_affine(), but works with the
+ * internal representation of points as used by ecp_nistp###.c rather than
+ * with (BIGNUM-based) EC_POINT data structures. point_array is the
+ * input/output buffer ('num' points in projective form, i.e. three
+ * coordinates each), based on an internal representation of field elements
+ * of size 'felem_size'. tmp_felems needs to point to a temporary array of
+ * 'num'+1 field elements for storage of intermediate values.
+ */
+void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
+                                              size_t felem_size,
+                                              void *tmp_felems,
+                                              void (*felem_one) (void *out),
+                                              int (*felem_is_zero) (const void
+                                                                    *in),
+                                              void (*felem_assign) (void *out,
+                                                                    const void
+                                                                    *in),
+                                              void (*felem_square) (void *out,
+                                                                    const void
+                                                                    *in),
+                                              void (*felem_mul) (void *out,
+                                                                 const void
+                                                                 *in1,
+                                                                 const void
+                                                                 *in2),
+                                              void (*felem_inv) (void *out,
+                                                                 const void
+                                                                 *in),
+                                              void (*felem_contract) (void
+                                                                      *out,
+                                                                      const
+                                                                      void
+                                                                      *in))
+{
+    int i = 0;
+
+# define tmp_felem(I) (&((char *)tmp_felems)[(I) * felem_size])
+# define X(I) (&((char *)point_array)[3*(I) * felem_size])
+# define Y(I) (&((char *)point_array)[(3*(I) + 1) * felem_size])
+# define Z(I) (&((char *)point_array)[(3*(I) + 2) * felem_size])
+
+    if (!felem_is_zero(Z(0)))
+        felem_assign(tmp_felem(0), Z(0));
+    else
+        felem_one(tmp_felem(0));
+    for (i = 1; i < (int)num; i++) {
+        if (!felem_is_zero(Z(i)))
+            felem_mul(tmp_felem(i), tmp_felem(i - 1), Z(i));
+        else
+            felem_assign(tmp_felem(i), tmp_felem(i - 1));
+    }
+    /*
+     * Now each tmp_felem(i) is the product of Z(0) .. Z(i), skipping any
+     * zero-valued factors: if Z(i) = 0, we essentially pretend that Z(i) = 1
+     */
+
+    felem_inv(tmp_felem(num - 1), tmp_felem(num - 1));
+    for (i = num - 1; i >= 0; i--) {
+        if (i > 0)
+            /*
+             * tmp_felem(i-1) is the product of Z(0) .. Z(i-1), tmp_felem(i)
+             * is the inverse of the product of Z(0) .. Z(i)
+             */
+            /* 1/Z(i) */
+            felem_mul(tmp_felem(num), tmp_felem(i - 1), tmp_felem(i));
+        else
+            felem_assign(tmp_felem(num), tmp_felem(0)); /* 1/Z(0) */
+
+        if (!felem_is_zero(Z(i))) {
+            if (i > 0)
+                /*
+                 * For next iteration, replace tmp_felem(i-1) by its inverse
+                 */
+                felem_mul(tmp_felem(i - 1), tmp_felem(i), Z(i));
+
+            /*
+             * Convert point (X, Y, Z) into affine form (X/(Z^2), Y/(Z^3), 1)
+             */
+            felem_square(Z(i), tmp_felem(num)); /* 1/(Z^2) */
+            felem_mul(X(i), X(i), Z(i)); /* X/(Z^2) */
+            felem_mul(Z(i), Z(i), tmp_felem(num)); /* 1/(Z^3) */
+            felem_mul(Y(i), Y(i), Z(i)); /* Y/(Z^3) */
+            felem_contract(X(i), X(i));
+            felem_contract(Y(i), Y(i));
+            felem_one(Z(i));
+        } else {
+            if (i > 0)
+                /*
+                 * For next iteration, replace tmp_felem(i-1) by its inverse
+                 */
+                felem_assign(tmp_felem(i - 1), tmp_felem(i));
+        }
+    }
+}
+
+/*-
+ * This function looks at 5+1 scalar bits (5 current, 1 adjacent less
+ * significant bit), and recodes them into a signed digit for use in fast point
+ * multiplication: the use of signed rather than unsigned digits means that
+ * fewer points need to be precomputed, given that point inversion is easy
+ * (a precomputed point dP makes -dP available as well).
+ *
+ * BACKGROUND:
+ *
+ * Signed digits for multiplication were introduced by Booth ("A signed binary
+ * multiplication technique", Quart. Journ. Mech. and Applied Math., vol. IV,
+ * pt. 2 (1951), pp. 236-240), in that case for multiplication of integers.
+ * Booth's original encoding did not generally improve the density of nonzero
+ * digits over the binary representation, and was merely meant to simplify the
+ * handling of signed factors given in two's complement; but it has since been
+ * shown to be the basis of various signed-digit representations that do have
+ * further advantages, including the wNAF, using the following general approach:
+ *
+ * (1) Given a binary representation
+ *
+ *       b_k  ...  b_2  b_1  b_0,
+ *
+ *     of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1
+ *     by using bit-wise subtraction as follows:
+ *
+ *        b_k b_(k-1)  ...  b_2  b_1  b_0
+ *      -     b_k      ...  b_3  b_2  b_1  b_0
+ *       -------------------------------------
+ *        s_k b_(k-1)  ...  s_3  s_2  s_1  s_0
+ *
+ *     A left-shift followed by subtraction of the original value yields a new
+ *     representation of the same value, using signed bits s_i = b_(i+1) - b_i.
+ *     This representation from Booth's paper has since appeared in the
+ *     literature under a variety of different names including "reversed binary
+ *     form", "alternating greedy expansion", "mutual opposite form", and
+ *     "sign-alternating {+-1}-representation".
+ *
+ *     An interesting property is that among the nonzero bits, values 1 and -1
+ *     strictly alternate.
+ *
+ * (2) Various window schemes can be applied to the Booth representation of
+ *     integers: for example, right-to-left sliding windows yield the wNAF
+ *     (a signed-digit encoding independently discovered by various researchers
+ *     in the 1990s), and left-to-right sliding windows yield a left-to-right
+ *     equivalent of the wNAF (independently discovered by various researchers
+ *     around 2004).
+ *
+ * To prevent leaking information through side channels in point multiplication,
+ * we need to recode the given integer into a regular pattern: sliding windows
+ * as in wNAFs won't do, we need their fixed-window equivalent -- which is a few
+ * decades older: we'll be using the so-called "modified Booth encoding" due to
+ * MacSorley ("High-speed arithmetic in binary computers", Proc. IRE, vol. 49
+ * (1961), pp. 67-91), in a radix-2^5 setting.  That is, we always combine five
+ * signed bits into a signed digit:
+ *
+ *       s_(4j + 4) s_(4j + 3) s_(4j + 2) s_(4j + 1) s_(4j)
+ *
+ * The sign-alternating property implies that the resulting digit values are
+ * integers from -16 to 16.
+ *
+ * Of course, we don't actually need to compute the signed digits s_i as an
+ * intermediate step (that's just a nice way to see how this scheme relates
+ * to the wNAF): a direct computation obtains the recoded digit from the
+ * six bits b_(4j + 4) ... b_(4j - 1).
+ *
+ * This function takes those five bits as an integer (0 .. 63), writing the
+ * recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute
+ * value, in the range 0 .. 8).  Note that this integer essentially provides the
+ * input bits "shifted to the left" by one position: for example, the input to
+ * compute the least significant recoded digit, given that there's no bit b_-1,
+ * has to be b_4 b_3 b_2 b_1 b_0 0.
+ *
+ */
+void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign,
+                                     unsigned char *digit, unsigned char in)
+{
+    unsigned char s, d;
+
+    s = ~((in >> 5) - 1);       /* sets all bits to MSB(in), 'in' seen as
+                                 * 6-bit value */
+    d = (1 << 6) - in - 1;
+    d = (d & s) | (in & ~s);
+    d = (d >> 1) + (d & 1);
+
+    *sign = s & 1;
+    *digit = d;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_oct.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_oct.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_oct.c	(revision 331)
@@ -0,0 +1,372 @@
+/*
+ * Copyright 2011-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include <openssl/err.h>
+#include <openssl/symhacks.h>
+
+#include "ec_lcl.h"
+
+int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
+                                             EC_POINT *point,
+                                             const BIGNUM *x_, int y_bit,
+                                             BN_CTX *ctx)
+{
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *tmp1, *tmp2, *x, *y;
+    int ret = 0;
+
+    /* clear error queue */
+    ERR_clear_error();
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            return 0;
+    }
+
+    y_bit = (y_bit != 0);
+
+    BN_CTX_start(ctx);
+    tmp1 = BN_CTX_get(ctx);
+    tmp2 = BN_CTX_get(ctx);
+    x = BN_CTX_get(ctx);
+    y = BN_CTX_get(ctx);
+    if (y == NULL)
+        goto err;
+
+    /*-
+     * Recover y.  We have a Weierstrass equation
+     *     y^2 = x^3 + a*x + b,
+     * so  y  is one of the square roots of  x^3 + a*x + b.
+     */
+
+    /* tmp1 := x^3 */
+    if (!BN_nnmod(x, x_, group->field, ctx))
+        goto err;
+    if (group->meth->field_decode == 0) {
+        /* field_{sqr,mul} work on standard representation */
+        if (!group->meth->field_sqr(group, tmp2, x_, ctx))
+            goto err;
+        if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx))
+            goto err;
+    } else {
+        if (!BN_mod_sqr(tmp2, x_, group->field, ctx))
+            goto err;
+        if (!BN_mod_mul(tmp1, tmp2, x_, group->field, ctx))
+            goto err;
+    }
+
+    /* tmp1 := tmp1 + a*x */
+    if (group->a_is_minus3) {
+        if (!BN_mod_lshift1_quick(tmp2, x, group->field))
+            goto err;
+        if (!BN_mod_add_quick(tmp2, tmp2, x, group->field))
+            goto err;
+        if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, group->field))
+            goto err;
+    } else {
+        if (group->meth->field_decode) {
+            if (!group->meth->field_decode(group, tmp2, group->a, ctx))
+                goto err;
+            if (!BN_mod_mul(tmp2, tmp2, x, group->field, ctx))
+                goto err;
+        } else {
+            /* field_mul works on standard representation */
+            if (!group->meth->field_mul(group, tmp2, group->a, x, ctx))
+                goto err;
+        }
+
+        if (!BN_mod_add_quick(tmp1, tmp1, tmp2, group->field))
+            goto err;
+    }
+
+    /* tmp1 := tmp1 + b */
+    if (group->meth->field_decode) {
+        if (!group->meth->field_decode(group, tmp2, group->b, ctx))
+            goto err;
+        if (!BN_mod_add_quick(tmp1, tmp1, tmp2, group->field))
+            goto err;
+    } else {
+        if (!BN_mod_add_quick(tmp1, tmp1, group->b, group->field))
+            goto err;
+    }
+
+    if (!BN_mod_sqrt(y, tmp1, group->field, ctx)) {
+        unsigned long err = ERR_peek_last_error();
+
+        if (ERR_GET_LIB(err) == ERR_LIB_BN
+            && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) {
+            ERR_clear_error();
+            ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
+                  EC_R_INVALID_COMPRESSED_POINT);
+        } else
+            ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
+                  ERR_R_BN_LIB);
+        goto err;
+    }
+
+    if (y_bit != BN_is_odd(y)) {
+        if (BN_is_zero(y)) {
+            int kron;
+
+            kron = BN_kronecker(x, group->field, ctx);
+            if (kron == -2)
+                goto err;
+
+            if (kron == 1)
+                ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
+                      EC_R_INVALID_COMPRESSION_BIT);
+            else
+                /*
+                 * BN_mod_sqrt() should have cought this error (not a square)
+                 */
+                ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
+                      EC_R_INVALID_COMPRESSED_POINT);
+            goto err;
+        }
+        if (!BN_usub(y, group->field, y))
+            goto err;
+    }
+    if (y_bit != BN_is_odd(y)) {
+        ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES,
+              ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
+    if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
+        goto err;
+
+    ret = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point,
+                               point_conversion_form_t form,
+                               unsigned char *buf, size_t len, BN_CTX *ctx)
+{
+    size_t ret;
+    BN_CTX *new_ctx = NULL;
+    int used_ctx = 0;
+    BIGNUM *x, *y;
+    size_t field_len, i, skip;
+
+    if ((form != POINT_CONVERSION_COMPRESSED)
+        && (form != POINT_CONVERSION_UNCOMPRESSED)
+        && (form != POINT_CONVERSION_HYBRID)) {
+        ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM);
+        goto err;
+    }
+
+    if (EC_POINT_is_at_infinity(group, point)) {
+        /* encodes to a single 0 octet */
+        if (buf != NULL) {
+            if (len < 1) {
+                ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+                return 0;
+            }
+            buf[0] = 0;
+        }
+        return 1;
+    }
+
+    /* ret := required output buffer length */
+    field_len = BN_num_bytes(group->field);
+    ret =
+        (form ==
+         POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
+
+    /* if 'buf' is NULL, just return required length */
+    if (buf != NULL) {
+        if (len < ret) {
+            ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL);
+            goto err;
+        }
+
+        if (ctx == NULL) {
+            ctx = new_ctx = BN_CTX_new();
+            if (ctx == NULL)
+                return 0;
+        }
+
+        BN_CTX_start(ctx);
+        used_ctx = 1;
+        x = BN_CTX_get(ctx);
+        y = BN_CTX_get(ctx);
+        if (y == NULL)
+            goto err;
+
+        if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx))
+            goto err;
+
+        if ((form == POINT_CONVERSION_COMPRESSED
+             || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y))
+            buf[0] = form + 1;
+        else
+            buf[0] = form;
+
+        i = 1;
+
+        skip = field_len - BN_num_bytes(x);
+        if (skip > field_len) {
+            ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+        while (skip > 0) {
+            buf[i++] = 0;
+            skip--;
+        }
+        skip = BN_bn2bin(x, buf + i);
+        i += skip;
+        if (i != 1 + field_len) {
+            ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+
+        if (form == POINT_CONVERSION_UNCOMPRESSED
+            || form == POINT_CONVERSION_HYBRID) {
+            skip = field_len - BN_num_bytes(y);
+            if (skip > field_len) {
+                ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+                goto err;
+            }
+            while (skip > 0) {
+                buf[i++] = 0;
+                skip--;
+            }
+            skip = BN_bn2bin(y, buf + i);
+            i += skip;
+        }
+
+        if (i != ret) {
+            ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+    }
+
+    if (used_ctx)
+        BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+
+ err:
+    if (used_ctx)
+        BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return 0;
+}
+
+int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
+                            const unsigned char *buf, size_t len, BN_CTX *ctx)
+{
+    point_conversion_form_t form;
+    int y_bit;
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *x, *y;
+    size_t field_len, enc_len;
+    int ret = 0;
+
+    if (len == 0) {
+        ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL);
+        return 0;
+    }
+    form = buf[0];
+    y_bit = form & 1;
+    form = form & ~1U;
+    if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED)
+        && (form != POINT_CONVERSION_UNCOMPRESSED)
+        && (form != POINT_CONVERSION_HYBRID)) {
+        ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+        return 0;
+    }
+    if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
+        ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+        return 0;
+    }
+
+    if (form == 0) {
+        if (len != 1) {
+            ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+            return 0;
+        }
+
+        return EC_POINT_set_to_infinity(group, point);
+    }
+
+    field_len = BN_num_bytes(group->field);
+    enc_len =
+        (form ==
+         POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
+
+    if (len != enc_len) {
+        ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+        return 0;
+    }
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            return 0;
+    }
+
+    BN_CTX_start(ctx);
+    x = BN_CTX_get(ctx);
+    y = BN_CTX_get(ctx);
+    if (y == NULL)
+        goto err;
+
+    if (!BN_bin2bn(buf + 1, field_len, x))
+        goto err;
+    if (BN_ucmp(x, group->field) >= 0) {
+        ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+        goto err;
+    }
+
+    if (form == POINT_CONVERSION_COMPRESSED) {
+        if (!EC_POINT_set_compressed_coordinates_GFp
+            (group, point, x, y_bit, ctx))
+            goto err;
+    } else {
+        if (!BN_bin2bn(buf + 1 + field_len, field_len, y))
+            goto err;
+        if (BN_ucmp(y, group->field) >= 0) {
+            ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+            goto err;
+        }
+        if (form == POINT_CONVERSION_HYBRID) {
+            if (y_bit != BN_is_odd(y)) {
+                ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING);
+                goto err;
+            }
+        }
+
+        /*
+         * EC_POINT_set_affine_coordinates_GFp is responsible for checking that
+         * the point is on the curve.
+         */
+        if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
+            goto err;
+    }
+
+    ret = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_smpl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_smpl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecp_smpl.c	(revision 331)
@@ -0,0 +1,1369 @@
+/*
+ * Copyright 2001-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * Portions of this software developed by SUN MICROSYSTEMS, INC.,
+ * and contributed to the OpenSSL project.
+ */
+
+#include <openssl/err.h>
+#include <openssl/symhacks.h>
+
+#include "ec_lcl.h"
+
+const EC_METHOD *EC_GFp_simple_method(void)
+{
+    static const EC_METHOD ret = {
+        EC_FLAGS_DEFAULT_OCT,
+        NID_X9_62_prime_field,
+        ec_GFp_simple_group_init,
+        ec_GFp_simple_group_finish,
+        ec_GFp_simple_group_clear_finish,
+        ec_GFp_simple_group_copy,
+        ec_GFp_simple_group_set_curve,
+        ec_GFp_simple_group_get_curve,
+        ec_GFp_simple_group_get_degree,
+        ec_group_simple_order_bits,
+        ec_GFp_simple_group_check_discriminant,
+        ec_GFp_simple_point_init,
+        ec_GFp_simple_point_finish,
+        ec_GFp_simple_point_clear_finish,
+        ec_GFp_simple_point_copy,
+        ec_GFp_simple_point_set_to_infinity,
+        ec_GFp_simple_set_Jprojective_coordinates_GFp,
+        ec_GFp_simple_get_Jprojective_coordinates_GFp,
+        ec_GFp_simple_point_set_affine_coordinates,
+        ec_GFp_simple_point_get_affine_coordinates,
+        0, 0, 0,
+        ec_GFp_simple_add,
+        ec_GFp_simple_dbl,
+        ec_GFp_simple_invert,
+        ec_GFp_simple_is_at_infinity,
+        ec_GFp_simple_is_on_curve,
+        ec_GFp_simple_cmp,
+        ec_GFp_simple_make_affine,
+        ec_GFp_simple_points_make_affine,
+        0 /* mul */ ,
+        0 /* precompute_mult */ ,
+        0 /* have_precompute_mult */ ,
+        ec_GFp_simple_field_mul,
+        ec_GFp_simple_field_sqr,
+        0 /* field_div */ ,
+        0 /* field_encode */ ,
+        0 /* field_decode */ ,
+        0,                      /* field_set_to_one */
+        ec_key_simple_priv2oct,
+        ec_key_simple_oct2priv,
+        0, /* set private */
+        ec_key_simple_generate_key,
+        ec_key_simple_check_key,
+        ec_key_simple_generate_public_key,
+        0, /* keycopy */
+        0, /* keyfinish */
+        ecdh_simple_compute_key
+    };
+
+    return &ret;
+}
+
+/*
+ * Most method functions in this file are designed to work with
+ * non-trivial representations of field elements if necessary
+ * (see ecp_mont.c): while standard modular addition and subtraction
+ * are used, the field_mul and field_sqr methods will be used for
+ * multiplication, and field_encode and field_decode (if defined)
+ * will be used for converting between representations.
+ *
+ * Functions ec_GFp_simple_points_make_affine() and
+ * ec_GFp_simple_point_get_affine_coordinates() specifically assume
+ * that if a non-trivial representation is used, it is a Montgomery
+ * representation (i.e. 'encoding' means multiplying by some factor R).
+ */
+
+int ec_GFp_simple_group_init(EC_GROUP *group)
+{
+    group->field = BN_new();
+    group->a = BN_new();
+    group->b = BN_new();
+    if (group->field == NULL || group->a == NULL || group->b == NULL) {
+        BN_free(group->field);
+        BN_free(group->a);
+        BN_free(group->b);
+        return 0;
+    }
+    group->a_is_minus3 = 0;
+    return 1;
+}
+
+void ec_GFp_simple_group_finish(EC_GROUP *group)
+{
+    BN_free(group->field);
+    BN_free(group->a);
+    BN_free(group->b);
+}
+
+void ec_GFp_simple_group_clear_finish(EC_GROUP *group)
+{
+    BN_clear_free(group->field);
+    BN_clear_free(group->a);
+    BN_clear_free(group->b);
+}
+
+int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
+{
+    if (!BN_copy(dest->field, src->field))
+        return 0;
+    if (!BN_copy(dest->a, src->a))
+        return 0;
+    if (!BN_copy(dest->b, src->b))
+        return 0;
+
+    dest->a_is_minus3 = src->a_is_minus3;
+
+    return 1;
+}
+
+int ec_GFp_simple_group_set_curve(EC_GROUP *group,
+                                  const BIGNUM *p, const BIGNUM *a,
+                                  const BIGNUM *b, BN_CTX *ctx)
+{
+    int ret = 0;
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *tmp_a;
+
+    /* p must be a prime > 3 */
+    if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) {
+        ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD);
+        return 0;
+    }
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            return 0;
+    }
+
+    BN_CTX_start(ctx);
+    tmp_a = BN_CTX_get(ctx);
+    if (tmp_a == NULL)
+        goto err;
+
+    /* group->field */
+    if (!BN_copy(group->field, p))
+        goto err;
+    BN_set_negative(group->field, 0);
+
+    /* group->a */
+    if (!BN_nnmod(tmp_a, a, p, ctx))
+        goto err;
+    if (group->meth->field_encode) {
+        if (!group->meth->field_encode(group, group->a, tmp_a, ctx))
+            goto err;
+    } else if (!BN_copy(group->a, tmp_a))
+        goto err;
+
+    /* group->b */
+    if (!BN_nnmod(group->b, b, p, ctx))
+        goto err;
+    if (group->meth->field_encode)
+        if (!group->meth->field_encode(group, group->b, group->b, ctx))
+            goto err;
+
+    /* group->a_is_minus3 */
+    if (!BN_add_word(tmp_a, 3))
+        goto err;
+    group->a_is_minus3 = (0 == BN_cmp(tmp_a, group->field));
+
+    ret = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
+                                  BIGNUM *b, BN_CTX *ctx)
+{
+    int ret = 0;
+    BN_CTX *new_ctx = NULL;
+
+    if (p != NULL) {
+        if (!BN_copy(p, group->field))
+            return 0;
+    }
+
+    if (a != NULL || b != NULL) {
+        if (group->meth->field_decode) {
+            if (ctx == NULL) {
+                ctx = new_ctx = BN_CTX_new();
+                if (ctx == NULL)
+                    return 0;
+            }
+            if (a != NULL) {
+                if (!group->meth->field_decode(group, a, group->a, ctx))
+                    goto err;
+            }
+            if (b != NULL) {
+                if (!group->meth->field_decode(group, b, group->b, ctx))
+                    goto err;
+            }
+        } else {
+            if (a != NULL) {
+                if (!BN_copy(a, group->a))
+                    goto err;
+            }
+            if (b != NULL) {
+                if (!BN_copy(b, group->b))
+                    goto err;
+            }
+        }
+    }
+
+    ret = 1;
+
+ err:
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+int ec_GFp_simple_group_get_degree(const EC_GROUP *group)
+{
+    return BN_num_bits(group->field);
+}
+
+int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
+{
+    int ret = 0;
+    BIGNUM *a, *b, *order, *tmp_1, *tmp_2;
+    const BIGNUM *p = group->field;
+    BN_CTX *new_ctx = NULL;
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL) {
+            ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT,
+                  ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    }
+    BN_CTX_start(ctx);
+    a = BN_CTX_get(ctx);
+    b = BN_CTX_get(ctx);
+    tmp_1 = BN_CTX_get(ctx);
+    tmp_2 = BN_CTX_get(ctx);
+    order = BN_CTX_get(ctx);
+    if (order == NULL)
+        goto err;
+
+    if (group->meth->field_decode) {
+        if (!group->meth->field_decode(group, a, group->a, ctx))
+            goto err;
+        if (!group->meth->field_decode(group, b, group->b, ctx))
+            goto err;
+    } else {
+        if (!BN_copy(a, group->a))
+            goto err;
+        if (!BN_copy(b, group->b))
+            goto err;
+    }
+
+    /*-
+     * check the discriminant:
+     * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p)
+     * 0 =< a, b < p
+     */
+    if (BN_is_zero(a)) {
+        if (BN_is_zero(b))
+            goto err;
+    } else if (!BN_is_zero(b)) {
+        if (!BN_mod_sqr(tmp_1, a, p, ctx))
+            goto err;
+        if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx))
+            goto err;
+        if (!BN_lshift(tmp_1, tmp_2, 2))
+            goto err;
+        /* tmp_1 = 4*a^3 */
+
+        if (!BN_mod_sqr(tmp_2, b, p, ctx))
+            goto err;
+        if (!BN_mul_word(tmp_2, 27))
+            goto err;
+        /* tmp_2 = 27*b^2 */
+
+        if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx))
+            goto err;
+        if (BN_is_zero(a))
+            goto err;
+    }
+    ret = 1;
+
+ err:
+    if (ctx != NULL)
+        BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+int ec_GFp_simple_point_init(EC_POINT *point)
+{
+    point->X = BN_new();
+    point->Y = BN_new();
+    point->Z = BN_new();
+    point->Z_is_one = 0;
+
+    if (point->X == NULL || point->Y == NULL || point->Z == NULL) {
+        BN_free(point->X);
+        BN_free(point->Y);
+        BN_free(point->Z);
+        return 0;
+    }
+    return 1;
+}
+
+void ec_GFp_simple_point_finish(EC_POINT *point)
+{
+    BN_free(point->X);
+    BN_free(point->Y);
+    BN_free(point->Z);
+}
+
+void ec_GFp_simple_point_clear_finish(EC_POINT *point)
+{
+    BN_clear_free(point->X);
+    BN_clear_free(point->Y);
+    BN_clear_free(point->Z);
+    point->Z_is_one = 0;
+}
+
+int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
+{
+    if (!BN_copy(dest->X, src->X))
+        return 0;
+    if (!BN_copy(dest->Y, src->Y))
+        return 0;
+    if (!BN_copy(dest->Z, src->Z))
+        return 0;
+    dest->Z_is_one = src->Z_is_one;
+
+    return 1;
+}
+
+int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group,
+                                        EC_POINT *point)
+{
+    point->Z_is_one = 0;
+    BN_zero(point->Z);
+    return 1;
+}
+
+int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
+                                                  EC_POINT *point,
+                                                  const BIGNUM *x,
+                                                  const BIGNUM *y,
+                                                  const BIGNUM *z,
+                                                  BN_CTX *ctx)
+{
+    BN_CTX *new_ctx = NULL;
+    int ret = 0;
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            return 0;
+    }
+
+    if (x != NULL) {
+        if (!BN_nnmod(point->X, x, group->field, ctx))
+            goto err;
+        if (group->meth->field_encode) {
+            if (!group->meth->field_encode(group, point->X, point->X, ctx))
+                goto err;
+        }
+    }
+
+    if (y != NULL) {
+        if (!BN_nnmod(point->Y, y, group->field, ctx))
+            goto err;
+        if (group->meth->field_encode) {
+            if (!group->meth->field_encode(group, point->Y, point->Y, ctx))
+                goto err;
+        }
+    }
+
+    if (z != NULL) {
+        int Z_is_one;
+
+        if (!BN_nnmod(point->Z, z, group->field, ctx))
+            goto err;
+        Z_is_one = BN_is_one(point->Z);
+        if (group->meth->field_encode) {
+            if (Z_is_one && (group->meth->field_set_to_one != 0)) {
+                if (!group->meth->field_set_to_one(group, point->Z, ctx))
+                    goto err;
+            } else {
+                if (!group->
+                    meth->field_encode(group, point->Z, point->Z, ctx))
+                    goto err;
+            }
+        }
+        point->Z_is_one = Z_is_one;
+    }
+
+    ret = 1;
+
+ err:
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
+                                                  const EC_POINT *point,
+                                                  BIGNUM *x, BIGNUM *y,
+                                                  BIGNUM *z, BN_CTX *ctx)
+{
+    BN_CTX *new_ctx = NULL;
+    int ret = 0;
+
+    if (group->meth->field_decode != 0) {
+        if (ctx == NULL) {
+            ctx = new_ctx = BN_CTX_new();
+            if (ctx == NULL)
+                return 0;
+        }
+
+        if (x != NULL) {
+            if (!group->meth->field_decode(group, x, point->X, ctx))
+                goto err;
+        }
+        if (y != NULL) {
+            if (!group->meth->field_decode(group, y, point->Y, ctx))
+                goto err;
+        }
+        if (z != NULL) {
+            if (!group->meth->field_decode(group, z, point->Z, ctx))
+                goto err;
+        }
+    } else {
+        if (x != NULL) {
+            if (!BN_copy(x, point->X))
+                goto err;
+        }
+        if (y != NULL) {
+            if (!BN_copy(y, point->Y))
+                goto err;
+        }
+        if (z != NULL) {
+            if (!BN_copy(z, point->Z))
+                goto err;
+        }
+    }
+
+    ret = 1;
+
+ err:
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group,
+                                               EC_POINT *point,
+                                               const BIGNUM *x,
+                                               const BIGNUM *y, BN_CTX *ctx)
+{
+    if (x == NULL || y == NULL) {
+        /*
+         * unlike for projective coordinates, we do not tolerate this
+         */
+        ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES,
+              ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+
+    return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y,
+                                                    BN_value_one(), ctx);
+}
+
+int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
+                                               const EC_POINT *point,
+                                               BIGNUM *x, BIGNUM *y,
+                                               BN_CTX *ctx)
+{
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *Z, *Z_1, *Z_2, *Z_3;
+    const BIGNUM *Z_;
+    int ret = 0;
+
+    if (EC_POINT_is_at_infinity(group, point)) {
+        ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES,
+              EC_R_POINT_AT_INFINITY);
+        return 0;
+    }
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            return 0;
+    }
+
+    BN_CTX_start(ctx);
+    Z = BN_CTX_get(ctx);
+    Z_1 = BN_CTX_get(ctx);
+    Z_2 = BN_CTX_get(ctx);
+    Z_3 = BN_CTX_get(ctx);
+    if (Z_3 == NULL)
+        goto err;
+
+    /* transform  (X, Y, Z)  into  (x, y) := (X/Z^2, Y/Z^3) */
+
+    if (group->meth->field_decode) {
+        if (!group->meth->field_decode(group, Z, point->Z, ctx))
+            goto err;
+        Z_ = Z;
+    } else {
+        Z_ = point->Z;
+    }
+
+    if (BN_is_one(Z_)) {
+        if (group->meth->field_decode) {
+            if (x != NULL) {
+                if (!group->meth->field_decode(group, x, point->X, ctx))
+                    goto err;
+            }
+            if (y != NULL) {
+                if (!group->meth->field_decode(group, y, point->Y, ctx))
+                    goto err;
+            }
+        } else {
+            if (x != NULL) {
+                if (!BN_copy(x, point->X))
+                    goto err;
+            }
+            if (y != NULL) {
+                if (!BN_copy(y, point->Y))
+                    goto err;
+            }
+        }
+    } else {
+        if (!BN_mod_inverse(Z_1, Z_, group->field, ctx)) {
+            ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES,
+                  ERR_R_BN_LIB);
+            goto err;
+        }
+
+        if (group->meth->field_encode == 0) {
+            /* field_sqr works on standard representation */
+            if (!group->meth->field_sqr(group, Z_2, Z_1, ctx))
+                goto err;
+        } else {
+            if (!BN_mod_sqr(Z_2, Z_1, group->field, ctx))
+                goto err;
+        }
+
+        if (x != NULL) {
+            /*
+             * in the Montgomery case, field_mul will cancel out Montgomery
+             * factor in X:
+             */
+            if (!group->meth->field_mul(group, x, point->X, Z_2, ctx))
+                goto err;
+        }
+
+        if (y != NULL) {
+            if (group->meth->field_encode == 0) {
+                /*
+                 * field_mul works on standard representation
+                 */
+                if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx))
+                    goto err;
+            } else {
+                if (!BN_mod_mul(Z_3, Z_2, Z_1, group->field, ctx))
+                    goto err;
+            }
+
+            /*
+             * in the Montgomery case, field_mul will cancel out Montgomery
+             * factor in Y:
+             */
+            if (!group->meth->field_mul(group, y, point->Y, Z_3, ctx))
+                goto err;
+        }
+    }
+
+    ret = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+                      const EC_POINT *b, BN_CTX *ctx)
+{
+    int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
+                      const BIGNUM *, BN_CTX *);
+    int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+    const BIGNUM *p;
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
+    int ret = 0;
+
+    if (a == b)
+        return EC_POINT_dbl(group, r, a, ctx);
+    if (EC_POINT_is_at_infinity(group, a))
+        return EC_POINT_copy(r, b);
+    if (EC_POINT_is_at_infinity(group, b))
+        return EC_POINT_copy(r, a);
+
+    field_mul = group->meth->field_mul;
+    field_sqr = group->meth->field_sqr;
+    p = group->field;
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            return 0;
+    }
+
+    BN_CTX_start(ctx);
+    n0 = BN_CTX_get(ctx);
+    n1 = BN_CTX_get(ctx);
+    n2 = BN_CTX_get(ctx);
+    n3 = BN_CTX_get(ctx);
+    n4 = BN_CTX_get(ctx);
+    n5 = BN_CTX_get(ctx);
+    n6 = BN_CTX_get(ctx);
+    if (n6 == NULL)
+        goto end;
+
+    /*
+     * Note that in this function we must not read components of 'a' or 'b'
+     * once we have written the corresponding components of 'r'. ('r' might
+     * be one of 'a' or 'b'.)
+     */
+
+    /* n1, n2 */
+    if (b->Z_is_one) {
+        if (!BN_copy(n1, a->X))
+            goto end;
+        if (!BN_copy(n2, a->Y))
+            goto end;
+        /* n1 = X_a */
+        /* n2 = Y_a */
+    } else {
+        if (!field_sqr(group, n0, b->Z, ctx))
+            goto end;
+        if (!field_mul(group, n1, a->X, n0, ctx))
+            goto end;
+        /* n1 = X_a * Z_b^2 */
+
+        if (!field_mul(group, n0, n0, b->Z, ctx))
+            goto end;
+        if (!field_mul(group, n2, a->Y, n0, ctx))
+            goto end;
+        /* n2 = Y_a * Z_b^3 */
+    }
+
+    /* n3, n4 */
+    if (a->Z_is_one) {
+        if (!BN_copy(n3, b->X))
+            goto end;
+        if (!BN_copy(n4, b->Y))
+            goto end;
+        /* n3 = X_b */
+        /* n4 = Y_b */
+    } else {
+        if (!field_sqr(group, n0, a->Z, ctx))
+            goto end;
+        if (!field_mul(group, n3, b->X, n0, ctx))
+            goto end;
+        /* n3 = X_b * Z_a^2 */
+
+        if (!field_mul(group, n0, n0, a->Z, ctx))
+            goto end;
+        if (!field_mul(group, n4, b->Y, n0, ctx))
+            goto end;
+        /* n4 = Y_b * Z_a^3 */
+    }
+
+    /* n5, n6 */
+    if (!BN_mod_sub_quick(n5, n1, n3, p))
+        goto end;
+    if (!BN_mod_sub_quick(n6, n2, n4, p))
+        goto end;
+    /* n5 = n1 - n3 */
+    /* n6 = n2 - n4 */
+
+    if (BN_is_zero(n5)) {
+        if (BN_is_zero(n6)) {
+            /* a is the same point as b */
+            BN_CTX_end(ctx);
+            ret = EC_POINT_dbl(group, r, a, ctx);
+            ctx = NULL;
+            goto end;
+        } else {
+            /* a is the inverse of b */
+            BN_zero(r->Z);
+            r->Z_is_one = 0;
+            ret = 1;
+            goto end;
+        }
+    }
+
+    /* 'n7', 'n8' */
+    if (!BN_mod_add_quick(n1, n1, n3, p))
+        goto end;
+    if (!BN_mod_add_quick(n2, n2, n4, p))
+        goto end;
+    /* 'n7' = n1 + n3 */
+    /* 'n8' = n2 + n4 */
+
+    /* Z_r */
+    if (a->Z_is_one && b->Z_is_one) {
+        if (!BN_copy(r->Z, n5))
+            goto end;
+    } else {
+        if (a->Z_is_one) {
+            if (!BN_copy(n0, b->Z))
+                goto end;
+        } else if (b->Z_is_one) {
+            if (!BN_copy(n0, a->Z))
+                goto end;
+        } else {
+            if (!field_mul(group, n0, a->Z, b->Z, ctx))
+                goto end;
+        }
+        if (!field_mul(group, r->Z, n0, n5, ctx))
+            goto end;
+    }
+    r->Z_is_one = 0;
+    /* Z_r = Z_a * Z_b * n5 */
+
+    /* X_r */
+    if (!field_sqr(group, n0, n6, ctx))
+        goto end;
+    if (!field_sqr(group, n4, n5, ctx))
+        goto end;
+    if (!field_mul(group, n3, n1, n4, ctx))
+        goto end;
+    if (!BN_mod_sub_quick(r->X, n0, n3, p))
+        goto end;
+    /* X_r = n6^2 - n5^2 * 'n7' */
+
+    /* 'n9' */
+    if (!BN_mod_lshift1_quick(n0, r->X, p))
+        goto end;
+    if (!BN_mod_sub_quick(n0, n3, n0, p))
+        goto end;
+    /* n9 = n5^2 * 'n7' - 2 * X_r */
+
+    /* Y_r */
+    if (!field_mul(group, n0, n0, n6, ctx))
+        goto end;
+    if (!field_mul(group, n5, n4, n5, ctx))
+        goto end;               /* now n5 is n5^3 */
+    if (!field_mul(group, n1, n2, n5, ctx))
+        goto end;
+    if (!BN_mod_sub_quick(n0, n0, n1, p))
+        goto end;
+    if (BN_is_odd(n0))
+        if (!BN_add(n0, n0, p))
+            goto end;
+    /* now  0 <= n0 < 2*p,  and n0 is even */
+    if (!BN_rshift1(r->Y, n0))
+        goto end;
+    /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
+
+    ret = 1;
+
+ end:
+    if (ctx)                    /* otherwise we already called BN_CTX_end */
+        BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+                      BN_CTX *ctx)
+{
+    int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
+                      const BIGNUM *, BN_CTX *);
+    int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+    const BIGNUM *p;
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *n0, *n1, *n2, *n3;
+    int ret = 0;
+
+    if (EC_POINT_is_at_infinity(group, a)) {
+        BN_zero(r->Z);
+        r->Z_is_one = 0;
+        return 1;
+    }
+
+    field_mul = group->meth->field_mul;
+    field_sqr = group->meth->field_sqr;
+    p = group->field;
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            return 0;
+    }
+
+    BN_CTX_start(ctx);
+    n0 = BN_CTX_get(ctx);
+    n1 = BN_CTX_get(ctx);
+    n2 = BN_CTX_get(ctx);
+    n3 = BN_CTX_get(ctx);
+    if (n3 == NULL)
+        goto err;
+
+    /*
+     * Note that in this function we must not read components of 'a' once we
+     * have written the corresponding components of 'r'. ('r' might the same
+     * as 'a'.)
+     */
+
+    /* n1 */
+    if (a->Z_is_one) {
+        if (!field_sqr(group, n0, a->X, ctx))
+            goto err;
+        if (!BN_mod_lshift1_quick(n1, n0, p))
+            goto err;
+        if (!BN_mod_add_quick(n0, n0, n1, p))
+            goto err;
+        if (!BN_mod_add_quick(n1, n0, group->a, p))
+            goto err;
+        /* n1 = 3 * X_a^2 + a_curve */
+    } else if (group->a_is_minus3) {
+        if (!field_sqr(group, n1, a->Z, ctx))
+            goto err;
+        if (!BN_mod_add_quick(n0, a->X, n1, p))
+            goto err;
+        if (!BN_mod_sub_quick(n2, a->X, n1, p))
+            goto err;
+        if (!field_mul(group, n1, n0, n2, ctx))
+            goto err;
+        if (!BN_mod_lshift1_quick(n0, n1, p))
+            goto err;
+        if (!BN_mod_add_quick(n1, n0, n1, p))
+            goto err;
+        /*-
+         * n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2)
+         *    = 3 * X_a^2 - 3 * Z_a^4
+         */
+    } else {
+        if (!field_sqr(group, n0, a->X, ctx))
+            goto err;
+        if (!BN_mod_lshift1_quick(n1, n0, p))
+            goto err;
+        if (!BN_mod_add_quick(n0, n0, n1, p))
+            goto err;
+        if (!field_sqr(group, n1, a->Z, ctx))
+            goto err;
+        if (!field_sqr(group, n1, n1, ctx))
+            goto err;
+        if (!field_mul(group, n1, n1, group->a, ctx))
+            goto err;
+        if (!BN_mod_add_quick(n1, n1, n0, p))
+            goto err;
+        /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */
+    }
+
+    /* Z_r */
+    if (a->Z_is_one) {
+        if (!BN_copy(n0, a->Y))
+            goto err;
+    } else {
+        if (!field_mul(group, n0, a->Y, a->Z, ctx))
+            goto err;
+    }
+    if (!BN_mod_lshift1_quick(r->Z, n0, p))
+        goto err;
+    r->Z_is_one = 0;
+    /* Z_r = 2 * Y_a * Z_a */
+
+    /* n2 */
+    if (!field_sqr(group, n3, a->Y, ctx))
+        goto err;
+    if (!field_mul(group, n2, a->X, n3, ctx))
+        goto err;
+    if (!BN_mod_lshift_quick(n2, n2, 2, p))
+        goto err;
+    /* n2 = 4 * X_a * Y_a^2 */
+
+    /* X_r */
+    if (!BN_mod_lshift1_quick(n0, n2, p))
+        goto err;
+    if (!field_sqr(group, r->X, n1, ctx))
+        goto err;
+    if (!BN_mod_sub_quick(r->X, r->X, n0, p))
+        goto err;
+    /* X_r = n1^2 - 2 * n2 */
+
+    /* n3 */
+    if (!field_sqr(group, n0, n3, ctx))
+        goto err;
+    if (!BN_mod_lshift_quick(n3, n0, 3, p))
+        goto err;
+    /* n3 = 8 * Y_a^4 */
+
+    /* Y_r */
+    if (!BN_mod_sub_quick(n0, n2, r->X, p))
+        goto err;
+    if (!field_mul(group, n0, n1, n0, ctx))
+        goto err;
+    if (!BN_mod_sub_quick(r->Y, n0, n3, p))
+        goto err;
+    /* Y_r = n1 * (n2 - X_r) - n3 */
+
+    ret = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
+{
+    if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(point->Y))
+        /* point is its own inverse */
+        return 1;
+
+    return BN_usub(point->Y, group->field, point->Y);
+}
+
+int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
+{
+    return BN_is_zero(point->Z);
+}
+
+int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
+                              BN_CTX *ctx)
+{
+    int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
+                      const BIGNUM *, BN_CTX *);
+    int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+    const BIGNUM *p;
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *rh, *tmp, *Z4, *Z6;
+    int ret = -1;
+
+    if (EC_POINT_is_at_infinity(group, point))
+        return 1;
+
+    field_mul = group->meth->field_mul;
+    field_sqr = group->meth->field_sqr;
+    p = group->field;
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            return -1;
+    }
+
+    BN_CTX_start(ctx);
+    rh = BN_CTX_get(ctx);
+    tmp = BN_CTX_get(ctx);
+    Z4 = BN_CTX_get(ctx);
+    Z6 = BN_CTX_get(ctx);
+    if (Z6 == NULL)
+        goto err;
+
+    /*-
+     * We have a curve defined by a Weierstrass equation
+     *      y^2 = x^3 + a*x + b.
+     * The point to consider is given in Jacobian projective coordinates
+     * where  (X, Y, Z)  represents  (x, y) = (X/Z^2, Y/Z^3).
+     * Substituting this and multiplying by  Z^6  transforms the above equation into
+     *      Y^2 = X^3 + a*X*Z^4 + b*Z^6.
+     * To test this, we add up the right-hand side in 'rh'.
+     */
+
+    /* rh := X^2 */
+    if (!field_sqr(group, rh, point->X, ctx))
+        goto err;
+
+    if (!point->Z_is_one) {
+        if (!field_sqr(group, tmp, point->Z, ctx))
+            goto err;
+        if (!field_sqr(group, Z4, tmp, ctx))
+            goto err;
+        if (!field_mul(group, Z6, Z4, tmp, ctx))
+            goto err;
+
+        /* rh := (rh + a*Z^4)*X */
+        if (group->a_is_minus3) {
+            if (!BN_mod_lshift1_quick(tmp, Z4, p))
+                goto err;
+            if (!BN_mod_add_quick(tmp, tmp, Z4, p))
+                goto err;
+            if (!BN_mod_sub_quick(rh, rh, tmp, p))
+                goto err;
+            if (!field_mul(group, rh, rh, point->X, ctx))
+                goto err;
+        } else {
+            if (!field_mul(group, tmp, Z4, group->a, ctx))
+                goto err;
+            if (!BN_mod_add_quick(rh, rh, tmp, p))
+                goto err;
+            if (!field_mul(group, rh, rh, point->X, ctx))
+                goto err;
+        }
+
+        /* rh := rh + b*Z^6 */
+        if (!field_mul(group, tmp, group->b, Z6, ctx))
+            goto err;
+        if (!BN_mod_add_quick(rh, rh, tmp, p))
+            goto err;
+    } else {
+        /* point->Z_is_one */
+
+        /* rh := (rh + a)*X */
+        if (!BN_mod_add_quick(rh, rh, group->a, p))
+            goto err;
+        if (!field_mul(group, rh, rh, point->X, ctx))
+            goto err;
+        /* rh := rh + b */
+        if (!BN_mod_add_quick(rh, rh, group->b, p))
+            goto err;
+    }
+
+    /* 'lh' := Y^2 */
+    if (!field_sqr(group, tmp, point->Y, ctx))
+        goto err;
+
+    ret = (0 == BN_ucmp(tmp, rh));
+
+ err:
+    BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
+                      const EC_POINT *b, BN_CTX *ctx)
+{
+    /*-
+     * return values:
+     *  -1   error
+     *   0   equal (in affine coordinates)
+     *   1   not equal
+     */
+
+    int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
+                      const BIGNUM *, BN_CTX *);
+    int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
+    const BIGNUM *tmp1_, *tmp2_;
+    int ret = -1;
+
+    if (EC_POINT_is_at_infinity(group, a)) {
+        return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
+    }
+
+    if (EC_POINT_is_at_infinity(group, b))
+        return 1;
+
+    if (a->Z_is_one && b->Z_is_one) {
+        return ((BN_cmp(a->X, b->X) == 0) && BN_cmp(a->Y, b->Y) == 0) ? 0 : 1;
+    }
+
+    field_mul = group->meth->field_mul;
+    field_sqr = group->meth->field_sqr;
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            return -1;
+    }
+
+    BN_CTX_start(ctx);
+    tmp1 = BN_CTX_get(ctx);
+    tmp2 = BN_CTX_get(ctx);
+    Za23 = BN_CTX_get(ctx);
+    Zb23 = BN_CTX_get(ctx);
+    if (Zb23 == NULL)
+        goto end;
+
+    /*-
+     * We have to decide whether
+     *     (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3),
+     * or equivalently, whether
+     *     (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
+     */
+
+    if (!b->Z_is_one) {
+        if (!field_sqr(group, Zb23, b->Z, ctx))
+            goto end;
+        if (!field_mul(group, tmp1, a->X, Zb23, ctx))
+            goto end;
+        tmp1_ = tmp1;
+    } else
+        tmp1_ = a->X;
+    if (!a->Z_is_one) {
+        if (!field_sqr(group, Za23, a->Z, ctx))
+            goto end;
+        if (!field_mul(group, tmp2, b->X, Za23, ctx))
+            goto end;
+        tmp2_ = tmp2;
+    } else
+        tmp2_ = b->X;
+
+    /* compare  X_a*Z_b^2  with  X_b*Z_a^2 */
+    if (BN_cmp(tmp1_, tmp2_) != 0) {
+        ret = 1;                /* points differ */
+        goto end;
+    }
+
+    if (!b->Z_is_one) {
+        if (!field_mul(group, Zb23, Zb23, b->Z, ctx))
+            goto end;
+        if (!field_mul(group, tmp1, a->Y, Zb23, ctx))
+            goto end;
+        /* tmp1_ = tmp1 */
+    } else
+        tmp1_ = a->Y;
+    if (!a->Z_is_one) {
+        if (!field_mul(group, Za23, Za23, a->Z, ctx))
+            goto end;
+        if (!field_mul(group, tmp2, b->Y, Za23, ctx))
+            goto end;
+        /* tmp2_ = tmp2 */
+    } else
+        tmp2_ = b->Y;
+
+    /* compare  Y_a*Z_b^3  with  Y_b*Z_a^3 */
+    if (BN_cmp(tmp1_, tmp2_) != 0) {
+        ret = 1;                /* points differ */
+        goto end;
+    }
+
+    /* points are equal */
+    ret = 0;
+
+ end:
+    BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
+                              BN_CTX *ctx)
+{
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *x, *y;
+    int ret = 0;
+
+    if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
+        return 1;
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            return 0;
+    }
+
+    BN_CTX_start(ctx);
+    x = BN_CTX_get(ctx);
+    y = BN_CTX_get(ctx);
+    if (y == NULL)
+        goto err;
+
+    if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx))
+        goto err;
+    if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx))
+        goto err;
+    if (!point->Z_is_one) {
+        ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
+    ret = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    return ret;
+}
+
+int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
+                                     EC_POINT *points[], BN_CTX *ctx)
+{
+    BN_CTX *new_ctx = NULL;
+    BIGNUM *tmp, *tmp_Z;
+    BIGNUM **prod_Z = NULL;
+    size_t i;
+    int ret = 0;
+
+    if (num == 0)
+        return 1;
+
+    if (ctx == NULL) {
+        ctx = new_ctx = BN_CTX_new();
+        if (ctx == NULL)
+            return 0;
+    }
+
+    BN_CTX_start(ctx);
+    tmp = BN_CTX_get(ctx);
+    tmp_Z = BN_CTX_get(ctx);
+    if (tmp == NULL || tmp_Z == NULL)
+        goto err;
+
+    prod_Z = OPENSSL_malloc(num * sizeof prod_Z[0]);
+    if (prod_Z == NULL)
+        goto err;
+    for (i = 0; i < num; i++) {
+        prod_Z[i] = BN_new();
+        if (prod_Z[i] == NULL)
+            goto err;
+    }
+
+    /*
+     * Set each prod_Z[i] to the product of points[0]->Z .. points[i]->Z,
+     * skipping any zero-valued inputs (pretend that they're 1).
+     */
+
+    if (!BN_is_zero(points[0]->Z)) {
+        if (!BN_copy(prod_Z[0], points[0]->Z))
+            goto err;
+    } else {
+        if (group->meth->field_set_to_one != 0) {
+            if (!group->meth->field_set_to_one(group, prod_Z[0], ctx))
+                goto err;
+        } else {
+            if (!BN_one(prod_Z[0]))
+                goto err;
+        }
+    }
+
+    for (i = 1; i < num; i++) {
+        if (!BN_is_zero(points[i]->Z)) {
+            if (!group->
+                meth->field_mul(group, prod_Z[i], prod_Z[i - 1], points[i]->Z,
+                                ctx))
+                goto err;
+        } else {
+            if (!BN_copy(prod_Z[i], prod_Z[i - 1]))
+                goto err;
+        }
+    }
+
+    /*
+     * Now use a single explicit inversion to replace every non-zero
+     * points[i]->Z by its inverse.
+     */
+
+    if (!BN_mod_inverse(tmp, prod_Z[num - 1], group->field, ctx)) {
+        ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB);
+        goto err;
+    }
+    if (group->meth->field_encode != 0) {
+        /*
+         * In the Montgomery case, we just turned R*H (representing H) into
+         * 1/(R*H), but we need R*(1/H) (representing 1/H); i.e. we need to
+         * multiply by the Montgomery factor twice.
+         */
+        if (!group->meth->field_encode(group, tmp, tmp, ctx))
+            goto err;
+        if (!group->meth->field_encode(group, tmp, tmp, ctx))
+            goto err;
+    }
+
+    for (i = num - 1; i > 0; --i) {
+        /*
+         * Loop invariant: tmp is the product of the inverses of points[0]->Z
+         * .. points[i]->Z (zero-valued inputs skipped).
+         */
+        if (!BN_is_zero(points[i]->Z)) {
+            /*
+             * Set tmp_Z to the inverse of points[i]->Z (as product of Z
+             * inverses 0 .. i, Z values 0 .. i - 1).
+             */
+            if (!group->
+                meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx))
+                goto err;
+            /*
+             * Update tmp to satisfy the loop invariant for i - 1.
+             */
+            if (!group->meth->field_mul(group, tmp, tmp, points[i]->Z, ctx))
+                goto err;
+            /* Replace points[i]->Z by its inverse. */
+            if (!BN_copy(points[i]->Z, tmp_Z))
+                goto err;
+        }
+    }
+
+    if (!BN_is_zero(points[0]->Z)) {
+        /* Replace points[0]->Z by its inverse. */
+        if (!BN_copy(points[0]->Z, tmp))
+            goto err;
+    }
+
+    /* Finally, fix up the X and Y coordinates for all points. */
+
+    for (i = 0; i < num; i++) {
+        EC_POINT *p = points[i];
+
+        if (!BN_is_zero(p->Z)) {
+            /* turn  (X, Y, 1/Z)  into  (X/Z^2, Y/Z^3, 1) */
+
+            if (!group->meth->field_sqr(group, tmp, p->Z, ctx))
+                goto err;
+            if (!group->meth->field_mul(group, p->X, p->X, tmp, ctx))
+                goto err;
+
+            if (!group->meth->field_mul(group, tmp, tmp, p->Z, ctx))
+                goto err;
+            if (!group->meth->field_mul(group, p->Y, p->Y, tmp, ctx))
+                goto err;
+
+            if (group->meth->field_set_to_one != 0) {
+                if (!group->meth->field_set_to_one(group, p->Z, ctx))
+                    goto err;
+            } else {
+                if (!BN_one(p->Z))
+                    goto err;
+            }
+            p->Z_is_one = 1;
+        }
+    }
+
+    ret = 1;
+
+ err:
+    BN_CTX_end(ctx);
+    BN_CTX_free(new_ctx);
+    if (prod_Z != NULL) {
+        for (i = 0; i < num; i++) {
+            if (prod_Z[i] == NULL)
+                break;
+            BN_clear_free(prod_Z[i]);
+        }
+        OPENSSL_free(prod_Z);
+    }
+    return ret;
+}
+
+int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+                            const BIGNUM *b, BN_CTX *ctx)
+{
+    return BN_mod_mul(r, a, b, group->field, ctx);
+}
+
+int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
+                            BN_CTX *ctx)
+{
+    return BN_mod_sqr(r, a, group->field, ctx);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecx_meth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecx_meth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ec/ecx_meth.c	(revision 331)
@@ -0,0 +1,373 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/ec.h>
+#include <openssl/rand.h>
+#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
+#include "ec_lcl.h"
+
+#define X25519_KEYLEN        32
+#define X25519_BITS          253
+#define X25519_SECURITY_BITS 128
+
+typedef struct {
+    unsigned char pubkey[X25519_KEYLEN];
+    unsigned char *privkey;
+} X25519_KEY;
+
+typedef enum {
+    X25519_PUBLIC,
+    X25519_PRIVATE,
+    X25519_KEYGEN
+} ecx_key_op_t;
+
+/* Setup EVP_PKEY using public, private or generation */
+static int ecx_key_op(EVP_PKEY *pkey, const X509_ALGOR *palg,
+                      const unsigned char *p, int plen, ecx_key_op_t op)
+{
+    X25519_KEY *xkey;
+
+    if (op != X25519_KEYGEN) {
+        if (palg != NULL) {
+            int ptype;
+
+            /* Algorithm parameters must be absent */
+            X509_ALGOR_get0(NULL, &ptype, NULL, palg);
+            if (ptype != V_ASN1_UNDEF) {
+                ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
+                return 0;
+            }
+        }
+
+        if (p == NULL || plen != X25519_KEYLEN) {
+            ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
+            return 0;
+        }
+    }
+
+    xkey = OPENSSL_zalloc(sizeof(*xkey));
+    if (xkey == NULL) {
+        ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    if (op == X25519_PUBLIC) {
+        memcpy(xkey->pubkey, p, plen);
+    } else {
+        xkey->privkey = OPENSSL_secure_malloc(X25519_KEYLEN);
+        if (xkey->privkey == NULL) {
+            ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
+            OPENSSL_free(xkey);
+            return 0;
+        }
+        if (op == X25519_KEYGEN) {
+            if (RAND_bytes(xkey->privkey, X25519_KEYLEN) <= 0) {
+                OPENSSL_secure_free(xkey->privkey);
+                OPENSSL_free(xkey);
+                return 0;
+            }
+            xkey->privkey[0] &= 248;
+            xkey->privkey[31] &= 127;
+            xkey->privkey[31] |= 64;
+        } else {
+            memcpy(xkey->privkey, p, X25519_KEYLEN);
+        }
+        X25519_public_from_private(xkey->pubkey, xkey->privkey);
+    }
+
+    EVP_PKEY_assign(pkey, NID_X25519, xkey);
+    return 1;
+}
+
+static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
+{
+    const X25519_KEY *xkey = pkey->pkey.ptr;
+    unsigned char *penc;
+
+    if (xkey == NULL) {
+        ECerr(EC_F_ECX_PUB_ENCODE, EC_R_INVALID_KEY);
+        return 0;
+    }
+
+    penc = OPENSSL_memdup(xkey->pubkey, X25519_KEYLEN);
+    if (penc == NULL) {
+        ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(NID_X25519), V_ASN1_UNDEF,
+                                NULL, penc, X25519_KEYLEN)) {
+        OPENSSL_free(penc);
+        ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    return 1;
+}
+
+static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+{
+    const unsigned char *p;
+    int pklen;
+    X509_ALGOR *palg;
+
+    if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
+        return 0;
+    return ecx_key_op(pkey, palg, p, pklen, X25519_PUBLIC);
+}
+
+static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+    const X25519_KEY *akey = a->pkey.ptr;
+    const X25519_KEY *bkey = b->pkey.ptr;
+
+    if (akey == NULL || bkey == NULL)
+        return -2;
+    return !CRYPTO_memcmp(akey->pubkey, bkey->pubkey, X25519_KEYLEN);
+}
+
+static int ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
+{
+    const unsigned char *p;
+    int plen;
+    ASN1_OCTET_STRING *oct = NULL;
+    const X509_ALGOR *palg;
+    int rv;
+
+    if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8))
+        return 0;
+
+    oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
+    if (oct == NULL) {
+        p = NULL;
+        plen = 0;
+    } else {
+        p = ASN1_STRING_get0_data(oct);
+        plen = ASN1_STRING_length(oct);
+    }
+
+    rv = ecx_key_op(pkey, palg, p, plen, X25519_PRIVATE);
+    ASN1_OCTET_STRING_free(oct);
+    return rv;
+}
+
+static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
+{
+    const X25519_KEY *xkey = pkey->pkey.ptr;
+    ASN1_OCTET_STRING oct;
+    unsigned char *penc = NULL;
+    int penclen;
+
+    if (xkey == NULL || xkey->privkey == NULL) {
+        ECerr(EC_F_ECX_PRIV_ENCODE, EC_R_INVALID_PRIVATE_KEY);
+        return 0;
+    }
+
+    oct.data = xkey->privkey;
+    oct.length = X25519_KEYLEN;
+    oct.flags = 0;
+
+    penclen = i2d_ASN1_OCTET_STRING(&oct, &penc);
+    if (penclen < 0) {
+        ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X25519), 0,
+                         V_ASN1_UNDEF, NULL, penc, penclen)) {
+        OPENSSL_clear_free(penc, penclen);
+        ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int ecx_size(const EVP_PKEY *pkey)
+{
+    return X25519_KEYLEN;
+}
+
+static int ecx_bits(const EVP_PKEY *pkey)
+{
+    return X25519_BITS;
+}
+
+static int ecx_security_bits(const EVP_PKEY *pkey)
+{
+    return X25519_SECURITY_BITS;
+}
+
+static void ecx_free(EVP_PKEY *pkey)
+{
+    X25519_KEY *xkey = pkey->pkey.ptr;
+
+    if (xkey)
+        OPENSSL_secure_free(xkey->privkey);
+    OPENSSL_free(xkey);
+}
+
+/* "parameters" are always equal */
+static int ecx_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+    return 1;
+}
+
+static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                         ASN1_PCTX *ctx, ecx_key_op_t op)
+{
+    const X25519_KEY *xkey = pkey->pkey.ptr;
+
+    if (op == X25519_PRIVATE) {
+        if (xkey == NULL || xkey->privkey == NULL) {
+            if (BIO_printf(bp, "%*s<INVALID PRIVATE KEY>\n", indent, "") <= 0)
+                return 0;
+            return 1;
+        }
+        if (BIO_printf(bp, "%*sX25519 Private-Key:\n", indent, "") <= 0)
+            return 0;
+        if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0)
+            return 0;
+        if (ASN1_buf_print(bp, xkey->privkey, X25519_KEYLEN, indent + 4) == 0)
+            return 0;
+    } else {
+        if (xkey == NULL) {
+            if (BIO_printf(bp, "%*s<INVALID PUBLIC KEY>\n", indent, "") <= 0)
+                return 0;
+            return 1;
+        }
+        if (BIO_printf(bp, "%*sX25519 Public-Key:\n", indent, "") <= 0)
+            return 0;
+    }
+    if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0)
+        return 0;
+    if (ASN1_buf_print(bp, xkey->pubkey, X25519_KEYLEN, indent + 4) == 0)
+        return 0;
+    return 1;
+}
+
+static int ecx_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                          ASN1_PCTX *ctx)
+{
+    return ecx_key_print(bp, pkey, indent, ctx, X25519_PRIVATE);
+}
+
+static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                         ASN1_PCTX *ctx)
+{
+    return ecx_key_print(bp, pkey, indent, ctx, X25519_PUBLIC);
+}
+
+static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+{
+    switch (op) {
+
+    case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
+        return ecx_key_op(pkey, NULL, arg2, arg1, X25519_PUBLIC);
+
+    case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
+        if (pkey->pkey.ptr != NULL) {
+            const X25519_KEY *xkey = pkey->pkey.ptr;
+            unsigned char **ppt = arg2;
+            *ppt = OPENSSL_memdup(xkey->pubkey, X25519_KEYLEN);
+            if (*ppt != NULL)
+                return X25519_KEYLEN;
+        }
+        return 0;
+
+    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+        *(int *)arg2 = NID_sha256;
+        return 2;
+
+    default:
+        return -2;
+
+    }
+}
+
+const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
+    NID_X25519,
+    NID_X25519,
+    0,
+    "X25519",
+    "OpenSSL X25519 algorithm",
+
+    ecx_pub_decode,
+    ecx_pub_encode,
+    ecx_pub_cmp,
+    ecx_pub_print,
+
+    ecx_priv_decode,
+    ecx_priv_encode,
+    ecx_priv_print,
+
+    ecx_size,
+    ecx_bits,
+    ecx_security_bits,
+
+    0, 0, 0, 0,
+    ecx_cmp_parameters,
+    0, 0,
+
+    ecx_free,
+    ecx_ctrl,
+    NULL,
+    NULL
+};
+
+static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+    return ecx_key_op(pkey, NULL, NULL, 0, X25519_KEYGEN);
+}
+
+static int pkey_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
+                           size_t *keylen)
+{
+    const X25519_KEY *pkey, *peerkey;
+
+    if (ctx->pkey == NULL || ctx->peerkey == NULL) {
+        ECerr(EC_F_PKEY_ECX_DERIVE, EC_R_KEYS_NOT_SET);
+        return 0;
+    }
+    pkey = ctx->pkey->pkey.ptr;
+    peerkey = ctx->peerkey->pkey.ptr;
+    if (pkey == NULL || pkey->privkey == NULL) {
+        ECerr(EC_F_PKEY_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
+        return 0;
+    }
+    if (peerkey == NULL) {
+        ECerr(EC_F_PKEY_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
+        return 0;
+    }
+    *keylen = X25519_KEYLEN;
+    if (key != NULL && X25519(key, pkey->privkey, peerkey->pubkey) == 0)
+        return 0;
+    return 1;
+}
+
+static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+    /* Only need to handle peer key for derivation */
+    if (type == EVP_PKEY_CTRL_PEER_KEY)
+        return 1;
+    return -2;
+}
+
+const EVP_PKEY_METHOD ecx25519_pkey_meth = {
+    NID_X25519,
+    0, 0, 0, 0, 0, 0, 0,
+    pkey_ecx_keygen,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    pkey_ecx_derive,
+    pkey_ecx_ctrl,
+    0
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_all.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_all.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_all.c	(revision 331)
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2001-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 "internal/cryptlib.h"
+#include "eng_int.h"
+
+void ENGINE_load_builtin_engines(void)
+{
+    /* Some ENGINEs need this */
+    OPENSSL_cpuid_setup();
+
+    OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN, NULL);
+}
+
+#if (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)) && !defined(OPENSSL_NO_DEPRECATED)
+void ENGINE_setup_bsd_cryptodev(void)
+{
+    static int bsd_cryptodev_default_loaded = 0;
+    if (!bsd_cryptodev_default_loaded) {
+        OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_CRYPTODEV, NULL);
+        ENGINE_register_all_complete();
+    }
+    bsd_cryptodev_default_loaded = 1;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_cnf.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_cnf.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_cnf.c	(revision 331)
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2002-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 "eng_int.h"
+#include <openssl/conf.h>
+
+/* #define ENGINE_CONF_DEBUG */
+
+/* ENGINE config module */
+
+static const char *skip_dot(const char *name)
+{
+    const char *p = strchr(name, '.');
+
+    if (p != NULL)
+        return p + 1;
+    return name;
+}
+
+static STACK_OF(ENGINE) *initialized_engines = NULL;
+
+static int int_engine_init(ENGINE *e)
+{
+    if (!ENGINE_init(e))
+        return 0;
+    if (!initialized_engines)
+        initialized_engines = sk_ENGINE_new_null();
+    if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e)) {
+        ENGINE_finish(e);
+        return 0;
+    }
+    return 1;
+}
+
+static int int_engine_configure(const char *name, const char *value, const CONF *cnf)
+{
+    int i;
+    int ret = 0;
+    long do_init = -1;
+    STACK_OF(CONF_VALUE) *ecmds;
+    CONF_VALUE *ecmd = NULL;
+    const char *ctrlname, *ctrlvalue;
+    ENGINE *e = NULL;
+    int soft = 0;
+
+    name = skip_dot(name);
+#ifdef ENGINE_CONF_DEBUG
+    fprintf(stderr, "Configuring engine %s\n", name);
+#endif
+    /* Value is a section containing ENGINE commands */
+    ecmds = NCONF_get_section(cnf, value);
+
+    if (!ecmds) {
+        ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE,
+                  ENGINE_R_ENGINE_SECTION_ERROR);
+        return 0;
+    }
+
+    for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++) {
+        ecmd = sk_CONF_VALUE_value(ecmds, i);
+        ctrlname = skip_dot(ecmd->name);
+        ctrlvalue = ecmd->value;
+#ifdef ENGINE_CONF_DEBUG
+        fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n", ctrlname,
+                ctrlvalue);
+#endif
+
+        /* First handle some special pseudo ctrls */
+
+        /* Override engine name to use */
+        if (strcmp(ctrlname, "engine_id") == 0)
+            name = ctrlvalue;
+        else if (strcmp(ctrlname, "soft_load") == 0)
+            soft = 1;
+        /* Load a dynamic ENGINE */
+        else if (strcmp(ctrlname, "dynamic_path") == 0) {
+            e = ENGINE_by_id("dynamic");
+            if (!e)
+                goto err;
+            if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0))
+                goto err;
+            if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0))
+                goto err;
+            if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
+                goto err;
+        }
+        /* ... add other pseudos here ... */
+        else {
+            /*
+             * At this point we need an ENGINE structural reference if we
+             * don't already have one.
+             */
+            if (!e) {
+                e = ENGINE_by_id(name);
+                if (!e && soft) {
+                    ERR_clear_error();
+                    return 1;
+                }
+                if (!e)
+                    goto err;
+            }
+            /*
+             * Allow "EMPTY" to mean no value: this allows a valid "value" to
+             * be passed to ctrls of type NO_INPUT
+             */
+            if (strcmp(ctrlvalue, "EMPTY") == 0)
+                ctrlvalue = NULL;
+            if (strcmp(ctrlname, "init") == 0) {
+                if (!NCONF_get_number_e(cnf, value, "init", &do_init))
+                    goto err;
+                if (do_init == 1) {
+                    if (!int_engine_init(e))
+                        goto err;
+                } else if (do_init != 0) {
+                    ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE,
+                              ENGINE_R_INVALID_INIT_VALUE);
+                    goto err;
+                }
+            } else if (strcmp(ctrlname, "default_algorithms") == 0) {
+                if (!ENGINE_set_default_string(e, ctrlvalue))
+                    goto err;
+            } else if (!ENGINE_ctrl_cmd_string(e, ctrlname, ctrlvalue, 0))
+                goto err;
+        }
+
+    }
+    if (e && (do_init == -1) && !int_engine_init(e)) {
+        ecmd = NULL;
+        goto err;
+    }
+    ret = 1;
+ err:
+    if (ret != 1) {
+        ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE,
+                  ENGINE_R_ENGINE_CONFIGURATION_ERROR);
+        if (ecmd)
+            ERR_add_error_data(6, "section=", ecmd->section,
+                               ", name=", ecmd->name,
+                               ", value=", ecmd->value);
+    }
+    ENGINE_free(e);
+    return ret;
+}
+
+static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf)
+{
+    STACK_OF(CONF_VALUE) *elist;
+    CONF_VALUE *cval;
+    int i;
+#ifdef ENGINE_CONF_DEBUG
+    fprintf(stderr, "Called engine module: name %s, value %s\n",
+            CONF_imodule_get_name(md), CONF_imodule_get_value(md));
+#endif
+    /* Value is a section containing ENGINEs to configure */
+    elist = NCONF_get_section(cnf, CONF_imodule_get_value(md));
+
+    if (!elist) {
+        ENGINEerr(ENGINE_F_INT_ENGINE_MODULE_INIT,
+                  ENGINE_R_ENGINES_SECTION_ERROR);
+        return 0;
+    }
+
+    for (i = 0; i < sk_CONF_VALUE_num(elist); i++) {
+        cval = sk_CONF_VALUE_value(elist, i);
+        if (!int_engine_configure(cval->name, cval->value, cnf))
+            return 0;
+    }
+
+    return 1;
+}
+
+static void int_engine_module_finish(CONF_IMODULE *md)
+{
+    ENGINE *e;
+
+    while ((e = sk_ENGINE_pop(initialized_engines)))
+        ENGINE_finish(e);
+    sk_ENGINE_free(initialized_engines);
+    initialized_engines = NULL;
+}
+
+void ENGINE_add_conf_module(void)
+{
+    CONF_module_add("engines",
+                    int_engine_module_init, int_engine_module_finish);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_cryptodev.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_cryptodev.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_cryptodev.c	(revision 331)
@@ -0,0 +1,1754 @@
+/*
+ * Copyright 2002-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
+ */
+
+/*
+ * Copyright (c) 2002 Bob Beck <beck@openbsd.org>
+ * Copyright (c) 2002 Theo de Raadt
+ * Copyright (c) 2002 Markus Friedl
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <openssl/objects.h>
+#include <internal/engine.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
+
+#if (defined(__unix__) || defined(unix)) && !defined(USG) && \
+        (defined(OpenBSD) || defined(__FreeBSD__))
+# include <sys/param.h>
+# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041)
+#  define HAVE_CRYPTODEV
+# endif
+# if (OpenBSD >= 200110)
+#  define HAVE_SYSLOG_R
+# endif
+#endif
+
+#include <sys/types.h>
+#ifdef HAVE_CRYPTODEV
+# include <crypto/cryptodev.h>
+# include <sys/ioctl.h>
+# include <errno.h>
+# include <stdio.h>
+# include <unistd.h>
+# include <fcntl.h>
+# include <stdarg.h>
+# include <syslog.h>
+# include <errno.h>
+# include <string.h>
+#endif
+#include <openssl/dh.h>
+#include <openssl/dsa.h>
+#include <openssl/err.h>
+#include <openssl/rsa.h>
+
+#ifndef HAVE_CRYPTODEV
+
+void engine_load_cryptodev_int(void)
+{
+    /* This is a NOP on platforms without /dev/crypto */
+    return;
+}
+
+#else
+
+struct dev_crypto_state {
+    struct session_op d_sess;
+    int d_fd;
+# ifdef USE_CRYPTODEV_DIGESTS
+    char dummy_mac_key[HASH_MAX_LEN];
+    unsigned char digest_res[HASH_MAX_LEN];
+    char *mac_data;
+    int mac_len;
+# endif
+};
+
+static u_int32_t cryptodev_asymfeat = 0;
+
+static RSA_METHOD *cryptodev_rsa;
+#ifndef OPENSSL_NO_DSA
+static DSA_METHOD *cryptodev_dsa = NULL;
+#endif
+#ifndef OPENSSL_NO_DH
+static DH_METHOD *cryptodev_dh;
+#endif
+
+static int get_asym_dev_crypto(void);
+static int open_dev_crypto(void);
+static int get_dev_crypto(void);
+static int get_cryptodev_ciphers(const int **cnids);
+# ifdef USE_CRYPTODEV_DIGESTS
+static int get_cryptodev_digests(const int **cnids);
+# endif
+static int cryptodev_usable_ciphers(const int **nids);
+static int cryptodev_usable_digests(const int **nids);
+static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                            const unsigned char *in, size_t inl);
+static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                              const unsigned char *iv, int enc);
+static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx);
+static int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
+                                    const int **nids, int nid);
+static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
+                                    const int **nids, int nid);
+static int bn2crparam(const BIGNUM *a, struct crparam *crp);
+static int crparam2bn(struct crparam *crp, BIGNUM *a);
+static void zapparams(struct crypt_kop *kop);
+static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r,
+                          int slen, BIGNUM *s);
+
+static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a,
+                                const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+                                BN_MONT_CTX *m_ctx);
+static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
+                                       BN_CTX *ctx);
+static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
+                                 BN_CTX *ctx);
+#ifndef OPENSSL_NO_DSA
+static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, const BIGNUM *a,
+                                    const BIGNUM *p, const BIGNUM *m,
+                                    BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, const BIGNUM *g,
+                                     const BIGNUM *u1, const BIGNUM *pub_key,
+                                     const BIGNUM *u2, const BIGNUM *p,
+                                     BN_CTX *ctx, BN_MONT_CTX *mont);
+static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen,
+                                      DSA *dsa);
+static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len,
+                                DSA_SIG *sig, DSA *dsa);
+#endif
+#ifndef OPENSSL_NO_DH
+static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
+                                const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+                                BN_MONT_CTX *m_ctx);
+static int cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key,
+                                    DH *dh);
+#endif
+static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p,
+                          void (*f) (void));
+void engine_load_cryptodev_int(void);
+
+static const ENGINE_CMD_DEFN cryptodev_defns[] = {
+    {0, NULL, NULL, 0}
+};
+
+static struct {
+    int id;
+    int nid;
+    int ivmax;
+    int keylen;
+} ciphers[] = {
+    {
+        CRYPTO_ARC4, NID_rc4, 0, 16,
+    },
+    {
+        CRYPTO_DES_CBC, NID_des_cbc, 8, 8,
+    },
+    {
+        CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24,
+    },
+    {
+        CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16,
+    },
+    {
+        CRYPTO_AES_CBC, NID_aes_192_cbc, 16, 24,
+    },
+    {
+        CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32,
+    },
+# ifdef CRYPTO_AES_CTR
+    {
+        CRYPTO_AES_CTR, NID_aes_128_ctr, 14, 16,
+    },
+    {
+        CRYPTO_AES_CTR, NID_aes_192_ctr, 14, 24,
+    },
+    {
+        CRYPTO_AES_CTR, NID_aes_256_ctr, 14, 32,
+    },
+# endif
+    {
+        CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16,
+    },
+    {
+        CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16,
+    },
+    {
+        CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0,
+    },
+    {
+        0, NID_undef, 0, 0,
+    },
+};
+
+# ifdef USE_CRYPTODEV_DIGESTS
+static struct {
+    int id;
+    int nid;
+    int keylen;
+} digests[] = {
+    {
+        CRYPTO_MD5_HMAC, NID_hmacWithMD5, 16
+    },
+    {
+        CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, 20
+    },
+    {
+        CRYPTO_RIPEMD160_HMAC, NID_ripemd160, 16
+        /* ? */
+    },
+    {
+        CRYPTO_MD5_KPDK, NID_undef, 0
+    },
+    {
+        CRYPTO_SHA1_KPDK, NID_undef, 0
+    },
+    {
+        CRYPTO_MD5, NID_md5, 16
+    },
+    {
+        CRYPTO_SHA1, NID_sha1, 20
+    },
+    {
+        0, NID_undef, 0
+    },
+};
+# endif
+
+/*
+ * Return a fd if /dev/crypto seems usable, 0 otherwise.
+ */
+static int open_dev_crypto(void)
+{
+    static int fd = -1;
+
+    if (fd == -1) {
+        if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1)
+            return (-1);
+        /* close on exec */
+        if (fcntl(fd, F_SETFD, 1) == -1) {
+            close(fd);
+            fd = -1;
+            return (-1);
+        }
+    }
+    return (fd);
+}
+
+static int get_dev_crypto(void)
+{
+    int fd, retfd;
+
+    if ((fd = open_dev_crypto()) == -1)
+        return (-1);
+# ifndef CRIOGET_NOT_NEEDED
+    if (ioctl(fd, CRIOGET, &retfd) == -1)
+        return (-1);
+
+    /* close on exec */
+    if (fcntl(retfd, F_SETFD, 1) == -1) {
+        close(retfd);
+        return (-1);
+    }
+# else
+    retfd = fd;
+# endif
+    return (retfd);
+}
+
+static void put_dev_crypto(int fd)
+{
+# ifndef CRIOGET_NOT_NEEDED
+    close(fd);
+# endif
+}
+
+/* Caching version for asym operations */
+static int get_asym_dev_crypto(void)
+{
+    static int fd = -1;
+
+    if (fd == -1)
+        fd = get_dev_crypto();
+    return fd;
+}
+
+/*
+ * Find out what ciphers /dev/crypto will let us have a session for.
+ * XXX note, that some of these openssl doesn't deal with yet!
+ * returning them here is harmless, as long as we return NULL
+ * when asked for a handler in the cryptodev_engine_ciphers routine
+ */
+static int get_cryptodev_ciphers(const int **cnids)
+{
+    static int nids[CRYPTO_ALGORITHM_MAX];
+    struct session_op sess;
+    int fd, i, count = 0;
+
+    if ((fd = get_dev_crypto()) < 0) {
+        *cnids = NULL;
+        return (0);
+    }
+    memset(&sess, 0, sizeof(sess));
+    sess.key = (caddr_t) "123456789abcdefghijklmno";
+
+    for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
+        if (ciphers[i].nid == NID_undef)
+            continue;
+        sess.cipher = ciphers[i].id;
+        sess.keylen = ciphers[i].keylen;
+        sess.mac = 0;
+        if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
+            ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
+            nids[count++] = ciphers[i].nid;
+    }
+    put_dev_crypto(fd);
+
+    if (count > 0)
+        *cnids = nids;
+    else
+        *cnids = NULL;
+    return (count);
+}
+
+# ifdef USE_CRYPTODEV_DIGESTS
+/*
+ * Find out what digests /dev/crypto will let us have a session for.
+ * XXX note, that some of these openssl doesn't deal with yet!
+ * returning them here is harmless, as long as we return NULL
+ * when asked for a handler in the cryptodev_engine_digests routine
+ */
+static int get_cryptodev_digests(const int **cnids)
+{
+    static int nids[CRYPTO_ALGORITHM_MAX];
+    struct session_op sess;
+    int fd, i, count = 0;
+
+    if ((fd = get_dev_crypto()) < 0) {
+        *cnids = NULL;
+        return (0);
+    }
+    memset(&sess, 0, sizeof(sess));
+    sess.mackey = (caddr_t) "123456789abcdefghijklmno";
+    for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
+        if (digests[i].nid == NID_undef)
+            continue;
+        sess.mac = digests[i].id;
+        sess.mackeylen = digests[i].keylen;
+        sess.cipher = 0;
+        if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
+            ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
+            nids[count++] = digests[i].nid;
+    }
+    put_dev_crypto(fd);
+
+    if (count > 0)
+        *cnids = nids;
+    else
+        *cnids = NULL;
+    return (count);
+}
+# endif                         /* 0 */
+
+/*
+ * Find the useable ciphers|digests from dev/crypto - this is the first
+ * thing called by the engine init crud which determines what it
+ * can use for ciphers from this engine. We want to return
+ * only what we can do, anything else is handled by software.
+ *
+ * If we can't initialize the device to do anything useful for
+ * any reason, we want to return a NULL array, and 0 length,
+ * which forces everything to be done is software. By putting
+ * the initialization of the device in here, we ensure we can
+ * use this engine as the default, and if for whatever reason
+ * /dev/crypto won't do what we want it will just be done in
+ * software
+ *
+ * This can (should) be greatly expanded to perhaps take into
+ * account speed of the device, and what we want to do.
+ * (although the disabling of particular alg's could be controlled
+ * by the device driver with sysctl's.) - this is where we
+ * want most of the decisions made about what we actually want
+ * to use from /dev/crypto.
+ */
+static int cryptodev_usable_ciphers(const int **nids)
+{
+    return (get_cryptodev_ciphers(nids));
+}
+
+static int cryptodev_usable_digests(const int **nids)
+{
+# ifdef USE_CRYPTODEV_DIGESTS
+    return (get_cryptodev_digests(nids));
+# else
+    /*
+     * XXXX just disable all digests for now, because it sucks.
+     * we need a better way to decide this - i.e. I may not
+     * want digests on slow cards like hifn on fast machines,
+     * but might want them on slow or loaded machines, etc.
+     * will also want them when using crypto cards that don't
+     * suck moose gonads - would be nice to be able to decide something
+     * as reasonable default without having hackery that's card dependent.
+     * of course, the default should probably be just do everything,
+     * with perhaps a sysctl to turn algorithms off (or have them off
+     * by default) on cards that generally suck like the hifn.
+     */
+    *nids = NULL;
+    return (0);
+# endif
+}
+
+static int
+cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                 const unsigned char *in, size_t inl)
+{
+    struct crypt_op cryp;
+    struct dev_crypto_state *state = EVP_CIPHER_CTX_get_cipher_data(ctx);
+    struct session_op *sess = &state->d_sess;
+    const void *iiv;
+    unsigned char save_iv[EVP_MAX_IV_LENGTH];
+
+    if (state->d_fd < 0)
+        return (0);
+    if (!inl)
+        return (1);
+    if ((inl % EVP_CIPHER_CTX_block_size(ctx)) != 0)
+        return (0);
+
+    memset(&cryp, 0, sizeof(cryp));
+
+    cryp.ses = sess->ses;
+    cryp.flags = 0;
+    cryp.len = inl;
+    cryp.src = (caddr_t) in;
+    cryp.dst = (caddr_t) out;
+    cryp.mac = 0;
+
+    cryp.op = EVP_CIPHER_CTX_encrypting(ctx) ? COP_ENCRYPT : COP_DECRYPT;
+
+    if (EVP_CIPHER_CTX_iv_length(ctx) > 0) {
+        cryp.iv = (caddr_t) EVP_CIPHER_CTX_iv(ctx);
+        if (!EVP_CIPHER_CTX_encrypting(ctx)) {
+            iiv = in + inl - EVP_CIPHER_CTX_iv_length(ctx);
+            memcpy(save_iv, iiv, EVP_CIPHER_CTX_iv_length(ctx));
+        }
+    } else
+        cryp.iv = NULL;
+
+    if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) {
+        /*
+         * XXX need better error handling this can fail for a number of
+         * different reasons.
+         */
+        return (0);
+    }
+
+    if (EVP_CIPHER_CTX_iv_length(ctx) > 0) {
+        if (EVP_CIPHER_CTX_encrypting(ctx))
+            iiv = out + inl - EVP_CIPHER_CTX_iv_length(ctx);
+        else
+            iiv = save_iv;
+        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iiv,
+               EVP_CIPHER_CTX_iv_length(ctx));
+    }
+    return (1);
+}
+
+static int
+cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                   const unsigned char *iv, int enc)
+{
+    struct dev_crypto_state *state = EVP_CIPHER_CTX_get_cipher_data(ctx);
+    struct session_op *sess = &state->d_sess;
+    int cipher = -1, i;
+
+    for (i = 0; ciphers[i].id; i++)
+        if (EVP_CIPHER_CTX_nid(ctx) == ciphers[i].nid &&
+            EVP_CIPHER_CTX_iv_length(ctx) <= ciphers[i].ivmax &&
+            EVP_CIPHER_CTX_key_length(ctx) == ciphers[i].keylen) {
+            cipher = ciphers[i].id;
+            break;
+        }
+
+    if (!ciphers[i].id) {
+        state->d_fd = -1;
+        return (0);
+    }
+
+    memset(sess, 0, sizeof(*sess));
+
+    if ((state->d_fd = get_dev_crypto()) < 0)
+        return (0);
+
+    sess->key = (caddr_t) key;
+    sess->keylen = EVP_CIPHER_CTX_key_length(ctx);
+    sess->cipher = cipher;
+
+    if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
+        put_dev_crypto(state->d_fd);
+        state->d_fd = -1;
+        return (0);
+    }
+    return (1);
+}
+
+/*
+ * free anything we allocated earlier when initing a
+ * session, and close the session.
+ */
+static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
+{
+    int ret = 0;
+    struct dev_crypto_state *state = EVP_CIPHER_CTX_get_cipher_data(ctx);
+    struct session_op *sess = &state->d_sess;
+
+    if (state->d_fd < 0)
+        return (0);
+
+    /*
+     * XXX if this ioctl fails, something's wrong. the invoker may have called
+     * us with a bogus ctx, or we could have a device that for whatever
+     * reason just doesn't want to play ball - it's not clear what's right
+     * here - should this be an error? should it just increase a counter,
+     * hmm. For right now, we return 0 - I don't believe that to be "right".
+     * we could call the gorpy openssl lib error handlers that print messages
+     * to users of the library. hmm..
+     */
+
+    if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) {
+        ret = 0;
+    } else {
+        ret = 1;
+    }
+    put_dev_crypto(state->d_fd);
+    state->d_fd = -1;
+
+    return (ret);
+}
+
+/*
+ * libcrypto EVP stuff - this is how we get wired to EVP so the engine
+ * gets called when libcrypto requests a cipher NID.
+ */
+
+/* RC4 */
+static EVP_CIPHER *rc4_cipher = NULL;
+static const EVP_CIPHER *cryptodev_rc4(void)
+{
+    if (rc4_cipher == NULL) {
+        EVP_CIPHER *cipher;
+
+        if ((cipher = EVP_CIPHER_meth_new(NID_rc4, 1, 16)) == NULL
+            || !EVP_CIPHER_meth_set_iv_length(cipher, 0)
+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_VARIABLE_LENGTH)
+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))) {
+            EVP_CIPHER_meth_free(cipher);
+            cipher = NULL;
+        }
+        rc4_cipher = cipher;
+    }
+    return rc4_cipher;
+}
+
+/* DES CBC EVP */
+static EVP_CIPHER *des_cbc_cipher = NULL;
+static const EVP_CIPHER *cryptodev_des_cbc(void)
+{
+    if (des_cbc_cipher == NULL) {
+        EVP_CIPHER *cipher;
+
+        if ((cipher = EVP_CIPHER_meth_new(NID_des_cbc, 8, 8)) == NULL
+            || !EVP_CIPHER_meth_set_iv_length(cipher, 8)
+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE)
+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))
+            || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv)
+            || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) {
+            EVP_CIPHER_meth_free(cipher);
+            cipher = NULL;
+        }
+        des_cbc_cipher = cipher;
+    }
+    return des_cbc_cipher;
+}
+
+/* 3DES CBC EVP */
+static EVP_CIPHER *des3_cbc_cipher = NULL;
+static const EVP_CIPHER *cryptodev_3des_cbc(void)
+{
+    if (des3_cbc_cipher == NULL) {
+        EVP_CIPHER *cipher;
+
+        if ((cipher = EVP_CIPHER_meth_new(NID_des_ede3_cbc, 8, 24)) == NULL
+            || !EVP_CIPHER_meth_set_iv_length(cipher, 8)
+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE)
+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))
+            || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv)
+            || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) {
+            EVP_CIPHER_meth_free(cipher);
+            cipher = NULL;
+        }
+        des3_cbc_cipher = cipher;
+    }
+    return des3_cbc_cipher;
+}
+
+static EVP_CIPHER *bf_cbc_cipher = NULL;
+static const EVP_CIPHER *cryptodev_bf_cbc(void)
+{
+    if (bf_cbc_cipher == NULL) {
+        EVP_CIPHER *cipher;
+
+        if ((cipher = EVP_CIPHER_meth_new(NID_bf_cbc, 8, 16)) == NULL
+            || !EVP_CIPHER_meth_set_iv_length(cipher, 8)
+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE)
+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))
+            || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv)
+            || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) {
+            EVP_CIPHER_meth_free(cipher);
+            cipher = NULL;
+        }
+        bf_cbc_cipher = cipher;
+    }
+    return bf_cbc_cipher;
+}
+
+static EVP_CIPHER *cast_cbc_cipher = NULL;
+static const EVP_CIPHER *cryptodev_cast_cbc(void)
+{
+    if (cast_cbc_cipher == NULL) {
+        EVP_CIPHER *cipher;
+
+        if ((cipher = EVP_CIPHER_meth_new(NID_cast5_cbc, 8, 16)) == NULL
+            || !EVP_CIPHER_meth_set_iv_length(cipher, 8)
+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE)
+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))
+            || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv)
+            || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) {
+            EVP_CIPHER_meth_free(cipher);
+            cipher = NULL;
+        }
+        cast_cbc_cipher = cipher;
+    }
+    return cast_cbc_cipher;
+}
+
+static EVP_CIPHER *aes_cbc_cipher = NULL;
+static const EVP_CIPHER *cryptodev_aes_cbc(void)
+{
+    if (aes_cbc_cipher == NULL) {
+        EVP_CIPHER *cipher;
+
+        if ((cipher = EVP_CIPHER_meth_new(NID_aes_128_cbc, 16, 16)) == NULL
+            || !EVP_CIPHER_meth_set_iv_length(cipher, 16)
+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE)
+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))
+            || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv)
+            || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) {
+            EVP_CIPHER_meth_free(cipher);
+            cipher = NULL;
+        }
+        aes_cbc_cipher = cipher;
+    }
+    return aes_cbc_cipher;
+}
+
+static EVP_CIPHER *aes_192_cbc_cipher = NULL;
+static const EVP_CIPHER *cryptodev_aes_192_cbc(void)
+{
+    if (aes_192_cbc_cipher == NULL) {
+        EVP_CIPHER *cipher;
+
+        if ((cipher = EVP_CIPHER_meth_new(NID_aes_192_cbc, 16, 24)) == NULL
+            || !EVP_CIPHER_meth_set_iv_length(cipher, 16)
+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE)
+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))
+            || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv)
+            || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) {
+            EVP_CIPHER_meth_free(cipher);
+            cipher = NULL;
+        }
+        aes_192_cbc_cipher = cipher;
+    }
+    return aes_192_cbc_cipher;
+}
+
+static EVP_CIPHER *aes_256_cbc_cipher = NULL;
+static const EVP_CIPHER *cryptodev_aes_256_cbc(void)
+{
+    if (aes_256_cbc_cipher == NULL) {
+        EVP_CIPHER *cipher;
+
+        if ((cipher = EVP_CIPHER_meth_new(NID_aes_256_cbc, 16, 32)) == NULL
+            || !EVP_CIPHER_meth_set_iv_length(cipher, 16)
+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CBC_MODE)
+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))
+            || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv)
+            || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) {
+            EVP_CIPHER_meth_free(cipher);
+            cipher = NULL;
+        }
+        aes_256_cbc_cipher = cipher;
+    }
+    return aes_256_cbc_cipher;
+}
+
+# ifdef CRYPTO_AES_CTR
+static EVP_CIPHER *aes_ctr_cipher = NULL;
+static const EVP_CIPHER *cryptodev_aes_ctr(void)
+{
+    if (aes_ctr_cipher == NULL) {
+        EVP_CIPHER *cipher;
+
+        if ((cipher = EVP_CIPHER_meth_new(NID_aes_128_ctr, 16, 16)) == NULL
+            || !EVP_CIPHER_meth_set_iv_length(cipher, 14)
+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CTR_MODE)
+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))
+            || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv)
+            || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) {
+            EVP_CIPHER_meth_free(cipher);
+            cipher = NULL;
+        }
+        aes_ctr_cipher = cipher;
+    }
+    return aes_ctr_cipher;
+}
+
+static EVP_CIPHER *aes_192_ctr_cipher = NULL;
+static const EVP_CIPHER *cryptodev_aes_192_ctr(void)
+{
+    if (aes_192_ctr_cipher == NULL) {
+        EVP_CIPHER *cipher;
+
+        if ((cipher = EVP_CIPHER_meth_new(NID_aes_192_ctr, 16, 24)) == NULL
+            || !EVP_CIPHER_meth_set_iv_length(cipher, 14)
+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CTR_MODE)
+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))
+            || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv)
+            || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) {
+            EVP_CIPHER_meth_free(cipher);
+            cipher = NULL;
+        }
+        aes_192_ctr_cipher = cipher;
+    }
+    return aes_192_ctr_cipher;
+}
+
+static EVP_CIPHER *aes_256_ctr_cipher = NULL;
+static const EVP_CIPHER *cryptodev_aes_256_ctr(void)
+{
+    if (aes_256_ctr_cipher == NULL) {
+        EVP_CIPHER *cipher;
+
+        if ((cipher = EVP_CIPHER_meth_new(NID_aes_256_ctr, 16, 32)) == NULL
+            || !EVP_CIPHER_meth_set_iv_length(cipher, 14)
+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_CTR_MODE)
+            || !EVP_CIPHER_meth_set_init(cipher, cryptodev_init_key)
+            || !EVP_CIPHER_meth_set_do_cipher(cipher, cryptodev_cipher)
+            || !EVP_CIPHER_meth_set_cleanup(cipher, cryptodev_cleanup)
+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(struct dev_crypto_state))
+            || !EVP_CIPHER_meth_set_set_asn1_params(cipher, EVP_CIPHER_set_asn1_iv)
+            || !EVP_CIPHER_meth_set_get_asn1_params(cipher, EVP_CIPHER_get_asn1_iv)) {
+            EVP_CIPHER_meth_free(cipher);
+            cipher = NULL;
+        }
+        aes_256_ctr_cipher = cipher;
+    }
+    return aes_256_ctr_cipher;
+}
+# endif
+/*
+ * Registered by the ENGINE when used to find out how to deal with
+ * a particular NID in the ENGINE. this says what we'll do at the
+ * top level - note, that list is restricted by what we answer with
+ */
+static int
+cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
+                         const int **nids, int nid)
+{
+    if (!cipher)
+        return (cryptodev_usable_ciphers(nids));
+
+    switch (nid) {
+    case NID_rc4:
+        *cipher = cryptodev_rc4();
+        break;
+    case NID_des_ede3_cbc:
+        *cipher = cryptodev_3des_cbc();
+        break;
+    case NID_des_cbc:
+        *cipher = cryptodev_des_cbc();
+        break;
+    case NID_bf_cbc:
+        *cipher = cryptodev_bf_cbc();
+        break;
+    case NID_cast5_cbc:
+        *cipher = cryptodev_cast_cbc();
+        break;
+    case NID_aes_128_cbc:
+        *cipher = cryptodev_aes_cbc();
+        break;
+    case NID_aes_192_cbc:
+        *cipher = cryptodev_aes_192_cbc();
+        break;
+    case NID_aes_256_cbc:
+        *cipher = cryptodev_aes_256_cbc();
+        break;
+# ifdef CRYPTO_AES_CTR
+    case NID_aes_128_ctr:
+        *cipher = cryptodev_aes_ctr();
+        break;
+    case NID_aes_192_ctr:
+        *cipher = cryptodev_aes_192_ctr();
+        break;
+    case NID_aes_256_ctr:
+        *cipher = cryptodev_aes_256_ctr();
+        break;
+# endif
+    default:
+        *cipher = NULL;
+        break;
+    }
+    return (*cipher != NULL);
+}
+
+# ifdef USE_CRYPTODEV_DIGESTS
+
+/* convert digest type to cryptodev */
+static int digest_nid_to_cryptodev(int nid)
+{
+    int i;
+
+    for (i = 0; digests[i].id; i++)
+        if (digests[i].nid == nid)
+            return (digests[i].id);
+    return (0);
+}
+
+static int digest_key_length(int nid)
+{
+    int i;
+
+    for (i = 0; digests[i].id; i++)
+        if (digests[i].nid == nid)
+            return digests[i].keylen;
+    return (0);
+}
+
+static int cryptodev_digest_init(EVP_MD_CTX *ctx)
+{
+    struct dev_crypto_state *state = EVP_MD_CTX_md_data(ctx);
+    struct session_op *sess = &state->d_sess;
+    int digest;
+
+    if ((digest = digest_nid_to_cryptodev(EVP_MD_CTX_type(ctx))) == NID_undef) {
+        printf("cryptodev_digest_init: Can't get digest \n");
+        return (0);
+    }
+
+    memset(state, 0, sizeof(*state));
+
+    if ((state->d_fd = get_dev_crypto()) < 0) {
+        printf("cryptodev_digest_init: Can't get Dev \n");
+        return (0);
+    }
+
+    sess->mackey = state->dummy_mac_key;
+    sess->mackeylen = digest_key_length(EVP_MD_CTX_type(ctx));
+    sess->mac = digest;
+
+    if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) {
+        put_dev_crypto(state->d_fd);
+        state->d_fd = -1;
+        printf("cryptodev_digest_init: Open session failed\n");
+        return (0);
+    }
+
+    return (1);
+}
+
+static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data,
+                                   size_t count)
+{
+    struct crypt_op cryp;
+    struct dev_crypto_state *state = EVP_MD_CTX_md_data(ctx);
+    struct session_op *sess = &state->d_sess;
+    char *new_mac_data;
+
+    if (!data || state->d_fd < 0) {
+        printf("cryptodev_digest_update: illegal inputs \n");
+        return (0);
+    }
+
+    if (!count) {
+        return (0);
+    }
+
+    if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) {
+        /* if application doesn't support one buffer */
+        new_mac_data =
+            OPENSSL_realloc(state->mac_data, state->mac_len + count);
+
+        if (!new_mac_data) {
+            printf("cryptodev_digest_update: realloc failed\n");
+            return (0);
+        }
+        state->mac_data = new_mac_data;
+
+        memcpy(state->mac_data + state->mac_len, data, count);
+        state->mac_len += count;
+
+        return (1);
+    }
+
+    memset(&cryp, 0, sizeof(cryp));
+
+    cryp.ses = sess->ses;
+    cryp.flags = 0;
+    cryp.len = count;
+    cryp.src = (caddr_t) data;
+    cryp.dst = NULL;
+    cryp.mac = (caddr_t) state->digest_res;
+    if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
+        printf("cryptodev_digest_update: digest failed\n");
+        return (0);
+    }
+    return (1);
+}
+
+static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+    struct crypt_op cryp;
+    struct dev_crypto_state *state = EVP_MD_CTX_md_data(ctx);
+    struct session_op *sess = &state->d_sess;
+
+    int ret = 1;
+
+    if (!md || state->d_fd < 0) {
+        printf("cryptodev_digest_final: illegal input\n");
+        return (0);
+    }
+
+    if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT)) {
+        /* if application doesn't support one buffer */
+        memset(&cryp, 0, sizeof(cryp));
+        cryp.ses = sess->ses;
+        cryp.flags = 0;
+        cryp.len = state->mac_len;
+        cryp.src = state->mac_data;
+        cryp.dst = NULL;
+        cryp.mac = (caddr_t) md;
+        if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
+            printf("cryptodev_digest_final: digest failed\n");
+            return (0);
+        }
+
+        return 1;
+    }
+
+    memcpy(md, state->digest_res, EVP_MD_CTX_size(ctx));
+
+    return (ret);
+}
+
+static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx)
+{
+    int ret = 1;
+    struct dev_crypto_state *state = EVP_MD_CTX_md_data(ctx);
+    struct session_op *sess = &state->d_sess;
+
+    if (state == NULL)
+        return 0;
+
+    if (state->d_fd < 0) {
+        printf("cryptodev_digest_cleanup: illegal input\n");
+        return (0);
+    }
+
+    OPENSSL_free(state->mac_data);
+    state->mac_data = NULL;
+    state->mac_len = 0;
+
+    if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) {
+        printf("cryptodev_digest_cleanup: failed to close session\n");
+        ret = 0;
+    } else {
+        ret = 1;
+    }
+    put_dev_crypto(state->d_fd);
+    state->d_fd = -1;
+
+    return (ret);
+}
+
+static int cryptodev_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
+{
+    struct dev_crypto_state *fstate = EVP_MD_CTX_md_data(from);
+    struct dev_crypto_state *dstate = EVP_MD_CTX_md_data(to);
+    struct session_op *sess;
+    int digest;
+
+    if (dstate == NULL || fstate == NULL)
+        return 1;
+
+    memcpy(dstate, fstate, sizeof(struct dev_crypto_state));
+
+    sess = &dstate->d_sess;
+
+    digest = digest_nid_to_cryptodev(EVP_MD_CTX_type(to));
+
+    sess->mackey = dstate->dummy_mac_key;
+    sess->mackeylen = digest_key_length(EVP_MD_CTX_type(to));
+    sess->mac = digest;
+
+    dstate->d_fd = get_dev_crypto();
+
+    if (ioctl(dstate->d_fd, CIOCGSESSION, sess) < 0) {
+        put_dev_crypto(dstate->d_fd);
+        dstate->d_fd = -1;
+        printf("cryptodev_digest_copy: Open session failed\n");
+        return (0);
+    }
+
+    if (fstate->mac_len != 0) {
+        if (fstate->mac_data != NULL) {
+            dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
+            if (dstate->mac_data == NULL) {
+                printf("cryptodev_digest_copy: mac_data allocation failed\n");
+                return (0);
+            }
+            memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
+            dstate->mac_len = fstate->mac_len;
+        }
+    }
+
+    return 1;
+}
+
+static EVP_MD *sha1_md = NULL;
+static const EVP_MD *cryptodev_sha1(void)
+{
+    if (sha1_md == NULL) {
+        EVP_MD *md;
+
+        if ((md = EVP_MD_meth_new(NID_sha1, NID_undef)) == NULL
+            || !EVP_MD_meth_set_result_size(md, SHA_DIGEST_LENGTH)
+            || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_ONESHOT)
+            || !EVP_MD_meth_set_input_blocksize(md, SHA_CBLOCK)
+            || !EVP_MD_meth_set_app_datasize(md,
+                                             sizeof(struct dev_crypto_state))
+            || !EVP_MD_meth_set_init(md, cryptodev_digest_init)
+            || !EVP_MD_meth_set_update(md, cryptodev_digest_update)
+            || !EVP_MD_meth_set_final(md, cryptodev_digest_final)
+            || !EVP_MD_meth_set_copy(md, cryptodev_digest_copy)
+            || !EVP_MD_meth_set_cleanup(md, cryptodev_digest_cleanup)) {
+            EVP_MD_meth_free(md);
+            md = NULL;
+        }
+        sha1_md = md;
+    }
+    return sha1_md;
+}
+
+static EVP_MD *md5_md = NULL;
+static const EVP_MD *cryptodev_md5(void)
+{
+    if (md5_md == NULL) {
+        EVP_MD *md;
+
+        if ((md = EVP_MD_meth_new(NID_md5, NID_undef)) == NULL
+            || !EVP_MD_meth_set_result_size(md, 16 /* MD5_DIGEST_LENGTH */)
+            || !EVP_MD_meth_set_flags(md, EVP_MD_FLAG_ONESHOT)
+            || !EVP_MD_meth_set_input_blocksize(md, 64 /* MD5_CBLOCK */)
+            || !EVP_MD_meth_set_app_datasize(md,
+                                             sizeof(struct dev_crypto_state))
+            || !EVP_MD_meth_set_init(md, cryptodev_digest_init)
+            || !EVP_MD_meth_set_update(md, cryptodev_digest_update)
+            || !EVP_MD_meth_set_final(md, cryptodev_digest_final)
+            || !EVP_MD_meth_set_copy(md, cryptodev_digest_copy)
+            || !EVP_MD_meth_set_cleanup(md, cryptodev_digest_cleanup)) {
+            EVP_MD_meth_free(md);
+            md = NULL;
+        }
+        md5_md = md;
+    }
+    return md5_md;
+}
+
+# endif                         /* USE_CRYPTODEV_DIGESTS */
+
+static int
+cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest,
+                         const int **nids, int nid)
+{
+    if (!digest)
+        return (cryptodev_usable_digests(nids));
+
+    switch (nid) {
+# ifdef USE_CRYPTODEV_DIGESTS
+    case NID_md5:
+        *digest = cryptodev_md5();
+        break;
+    case NID_sha1:
+        *digest = cryptodev_sha1();
+        break;
+    default:
+# endif                         /* USE_CRYPTODEV_DIGESTS */
+        *digest = NULL;
+        break;
+    }
+    return (*digest != NULL);
+}
+
+static int cryptodev_engine_destroy(ENGINE *e)
+{
+    EVP_CIPHER_meth_free(rc4_cipher);
+    rc4_cipher = NULL;
+    EVP_CIPHER_meth_free(des_cbc_cipher);
+    des_cbc_cipher = NULL;
+    EVP_CIPHER_meth_free(des3_cbc_cipher);
+    des3_cbc_cipher = NULL;
+    EVP_CIPHER_meth_free(bf_cbc_cipher);
+    bf_cbc_cipher = NULL;
+    EVP_CIPHER_meth_free(cast_cbc_cipher);
+    cast_cbc_cipher = NULL;
+    EVP_CIPHER_meth_free(aes_cbc_cipher);
+    aes_cbc_cipher = NULL;
+    EVP_CIPHER_meth_free(aes_192_cbc_cipher);
+    aes_192_cbc_cipher = NULL;
+    EVP_CIPHER_meth_free(aes_256_cbc_cipher);
+    aes_256_cbc_cipher = NULL;
+# ifdef CRYPTO_AES_CTR
+    EVP_CIPHER_meth_free(aes_ctr_cipher);
+    aes_ctr_cipher = NULL;
+    EVP_CIPHER_meth_free(aes_192_ctr_cipher);
+    aes_192_ctr_cipher = NULL;
+    EVP_CIPHER_meth_free(aes_256_ctr_cipher);
+    aes_256_ctr_cipher = NULL;
+# endif
+# ifdef USE_CRYPTODEV_DIGESTS
+    EVP_MD_meth_free(sha1_md);
+    sha1_md = NULL;
+    EVP_MD_meth_free(md5_md);
+    md5_md = NULL;
+# endif
+    RSA_meth_free(cryptodev_rsa);
+    cryptodev_rsa = NULL;
+#ifndef OPENSSL_NO_DSA
+    DSA_meth_free(cryptodev_dsa);
+    cryptodev_dsa = NULL;
+#endif
+#ifndef OPENSSL_NO_DH
+    DH_meth_free(cryptodev_dh);
+    cryptodev_dh = NULL;
+#endif
+    return 1;
+}
+
+/*
+ * Convert a BIGNUM to the representation that /dev/crypto needs.
+ * Upon completion of use, the caller is responsible for freeing
+ * crp->crp_p.
+ */
+static int bn2crparam(const BIGNUM *a, struct crparam *crp)
+{
+    ssize_t bytes, bits;
+    u_char *b;
+
+    crp->crp_p = NULL;
+    crp->crp_nbits = 0;
+
+    bits = BN_num_bits(a);
+    bytes = BN_num_bytes(a);
+
+    b = OPENSSL_zalloc(bytes);
+    if (b == NULL)
+        return (1);
+
+    crp->crp_p = (caddr_t) b;
+    crp->crp_nbits = bits;
+
+    BN_bn2bin(a, b);
+    return (0);
+}
+
+/* Convert a /dev/crypto parameter to a BIGNUM */
+static int crparam2bn(struct crparam *crp, BIGNUM *a)
+{
+    u_int8_t *pd;
+    int i, bytes;
+
+    bytes = (crp->crp_nbits + 7) / 8;
+
+    if (bytes == 0)
+        return (-1);
+
+    if ((pd = OPENSSL_malloc(bytes)) == NULL)
+        return (-1);
+
+    for (i = 0; i < bytes; i++)
+        pd[i] = crp->crp_p[bytes - i - 1];
+
+    BN_bin2bn(pd, bytes, a);
+    free(pd);
+
+    return (0);
+}
+
+static void zapparams(struct crypt_kop *kop)
+{
+    int i;
+
+    for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) {
+        OPENSSL_free(kop->crk_param[i].crp_p);
+        kop->crk_param[i].crp_p = NULL;
+        kop->crk_param[i].crp_nbits = 0;
+    }
+}
+
+static int
+cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen,
+               BIGNUM *s)
+{
+    int fd, ret = -1;
+
+    if ((fd = get_asym_dev_crypto()) < 0)
+        return ret;
+
+    if (r) {
+        kop->crk_param[kop->crk_iparams].crp_p = OPENSSL_zalloc(rlen);
+        if (kop->crk_param[kop->crk_iparams].crp_p == NULL)
+            return ret;
+        kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8;
+        kop->crk_oparams++;
+    }
+    if (s) {
+        kop->crk_param[kop->crk_iparams + 1].crp_p =
+            OPENSSL_zalloc(slen);
+        /* No need to free the kop->crk_iparams parameter if it was allocated,
+         * callers of this routine have to free allocated parameters through
+         * zapparams both in case of success and failure
+         */
+        if (kop->crk_param[kop->crk_iparams+1].crp_p == NULL)
+            return ret;
+        kop->crk_param[kop->crk_iparams + 1].crp_nbits = slen * 8;
+        kop->crk_oparams++;
+    }
+
+    if (ioctl(fd, CIOCKEY, kop) == 0) {
+        if (r)
+            crparam2bn(&kop->crk_param[kop->crk_iparams], r);
+        if (s)
+            crparam2bn(&kop->crk_param[kop->crk_iparams + 1], s);
+        ret = 0;
+    }
+
+    return ret;
+}
+
+static int
+cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                     const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+{
+    struct crypt_kop kop;
+    int ret = 1;
+
+    /*
+     * Currently, we know we can do mod exp iff we can do any asymmetric
+     * operations at all.
+     */
+    if (cryptodev_asymfeat == 0) {
+        ret = BN_mod_exp(r, a, p, m, ctx);
+        return (ret);
+    }
+
+    memset(&kop, 0, sizeof(kop));
+    kop.crk_op = CRK_MOD_EXP;
+
+    /* inputs: a^p % m */
+    if (bn2crparam(a, &kop.crk_param[0]))
+        goto err;
+    if (bn2crparam(p, &kop.crk_param[1]))
+        goto err;
+    if (bn2crparam(m, &kop.crk_param[2]))
+        goto err;
+    kop.crk_iparams = 3;
+
+    if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) {
+        const RSA_METHOD *meth = RSA_PKCS1_OpenSSL();
+        printf("OCF asym process failed, Running in software\n");
+        ret = RSA_meth_get_bn_mod_exp(meth)(r, a, p, m, ctx, in_mont);
+
+    } else if (ECANCELED == kop.crk_status) {
+        const RSA_METHOD *meth = RSA_PKCS1_OpenSSL();
+        printf("OCF hardware operation cancelled. Running in Software\n");
+        ret = RSA_meth_get_bn_mod_exp(meth)(r, a, p, m, ctx, in_mont);
+    }
+    /* else cryptodev operation worked ok ==> ret = 1 */
+
+ err:
+    zapparams(&kop);
+    return (ret);
+}
+
+static int
+cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa,
+                            BN_CTX *ctx)
+{
+    int r;
+    const BIGNUM *n = NULL;
+    const BIGNUM *d = NULL;
+
+    ctx = BN_CTX_new();
+    RSA_get0_key(rsa, &n, NULL, &d);
+    r = cryptodev_bn_mod_exp(r0, I, d, n, ctx, NULL);
+    BN_CTX_free(ctx);
+    return (r);
+}
+
+static int
+cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+{
+    struct crypt_kop kop;
+    int ret = 1;
+    const BIGNUM *p = NULL;
+    const BIGNUM *q = NULL;
+    const BIGNUM *dmp1 = NULL;
+    const BIGNUM *dmq1 = NULL;
+    const BIGNUM *iqmp = NULL;
+    const BIGNUM *n = NULL;
+
+    RSA_get0_factors(rsa, &p, &q);
+    RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
+    RSA_get0_key(rsa, &n, NULL, NULL);
+
+    if (!p || !q || !dmp1 || !dmq1 || !iqmp) {
+        /* XXX 0 means failure?? */
+        return (0);
+    }
+
+    memset(&kop, 0, sizeof(kop));
+    kop.crk_op = CRK_MOD_EXP_CRT;
+    /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */
+    if (bn2crparam(p, &kop.crk_param[0]))
+        goto err;
+    if (bn2crparam(q, &kop.crk_param[1]))
+        goto err;
+    if (bn2crparam(I, &kop.crk_param[2]))
+        goto err;
+    if (bn2crparam(dmp1, &kop.crk_param[3]))
+        goto err;
+    if (bn2crparam(dmq1, &kop.crk_param[4]))
+        goto err;
+    if (bn2crparam(iqmp, &kop.crk_param[5]))
+        goto err;
+    kop.crk_iparams = 6;
+
+    if (cryptodev_asym(&kop, BN_num_bytes(n), r0, 0, NULL)) {
+        const RSA_METHOD *meth = RSA_PKCS1_OpenSSL();
+        printf("OCF asym process failed, running in Software\n");
+        ret = RSA_meth_get_mod_exp(meth)(r0, I, rsa, ctx);
+
+    } else if (ECANCELED == kop.crk_status) {
+        const RSA_METHOD *meth = RSA_PKCS1_OpenSSL();
+        printf("OCF hardware operation cancelled. Running in Software\n");
+        ret = RSA_meth_get_mod_exp(meth)(r0, I, rsa, ctx);
+    }
+    /* else cryptodev operation worked ok ==> ret = 1 */
+
+ err:
+    zapparams(&kop);
+    return (ret);
+}
+
+#ifndef OPENSSL_NO_DSA
+static int
+cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                         const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+{
+    return cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx);
+}
+
+static int
+cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, const BIGNUM *g,
+                          const BIGNUM *u1, const BIGNUM *pub_key,
+                          const BIGNUM *u2, const BIGNUM *p, BN_CTX *ctx,
+                          BN_MONT_CTX *mont)
+{
+    const BIGNUM *dsag, *dsap, *dsapub_key;
+    BIGNUM *t2;
+    int ret = 0;
+    const DSA_METHOD *meth;
+    int (*bn_mod_exp)(DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *,
+                      BN_CTX *, BN_MONT_CTX *);
+
+    t2 = BN_new();
+    if (t2 == NULL)
+        goto err;
+
+    /* v = ( g^u1 * y^u2 mod p ) mod q */
+    /* let t1 = g ^ u1 mod p */
+    ret = 0;
+
+    DSA_get0_pqg(dsa, &dsap, NULL, &dsag);
+    DSA_get0_key(dsa, &dsapub_key, NULL);
+
+    meth = DSA_get_method(dsa);
+    if (meth == NULL)
+        goto err;
+    bn_mod_exp = DSA_meth_get_bn_mod_exp(meth);
+    if (bn_mod_exp == NULL)
+        goto err;
+
+    if (!bn_mod_exp(dsa, t1, dsag, u1, dsap, ctx, mont))
+        goto err;
+
+    /* let t2 = y ^ u2 mod p */
+    if (!bn_mod_exp(dsa, t2, dsapub_key, u2, dsap, ctx, mont))
+        goto err;
+    /* let t1 = t1 * t2 mod p */
+    if (!BN_mod_mul(t1, t1, t2, dsap, ctx))
+        goto err;
+
+    ret = 1;
+ err:
+    BN_free(t2);
+    return (ret);
+}
+
+static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen,
+                                      DSA *dsa)
+{
+    struct crypt_kop kop;
+    BIGNUM *r, *s;
+    const BIGNUM *dsap = NULL, *dsaq = NULL, *dsag = NULL;
+    const BIGNUM *priv_key = NULL;
+    DSA_SIG *dsasig, *dsaret = NULL;
+
+    dsasig = DSA_SIG_new();
+    if (dsasig == NULL)
+        goto err;
+
+    memset(&kop, 0, sizeof(kop));
+    kop.crk_op = CRK_DSA_SIGN;
+
+    /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */
+    kop.crk_param[0].crp_p = (caddr_t) dgst;
+    kop.crk_param[0].crp_nbits = dlen * 8;
+    DSA_get0_pqg(dsa, &dsap, &dsaq, &dsag);
+    DSA_get0_key(dsa, NULL, &priv_key);
+    if (bn2crparam(dsap, &kop.crk_param[1]))
+        goto err;
+    if (bn2crparam(dsaq, &kop.crk_param[2]))
+        goto err;
+    if (bn2crparam(dsag, &kop.crk_param[3]))
+        goto err;
+    if (bn2crparam(priv_key, &kop.crk_param[4]))
+        goto err;
+    kop.crk_iparams = 5;
+
+    r = BN_new();
+    if (r == NULL)
+        goto err;
+    s = BN_new();
+    if (s == NULL)
+        goto err;
+    if (cryptodev_asym(&kop, BN_num_bytes(dsaq), r,
+                       BN_num_bytes(dsaq), s) == 0) {
+        DSA_SIG_set0(dsasig, r, s);
+        dsaret = dsasig;
+    } else {
+        dsaret = DSA_meth_get_sign(DSA_OpenSSL())(dgst, dlen, dsa);
+    }
+ err:
+    if (dsaret != dsasig)
+        DSA_SIG_free(dsasig);
+    kop.crk_param[0].crp_p = NULL;
+    zapparams(&kop);
+    return dsaret;
+}
+
+static int
+cryptodev_dsa_verify(const unsigned char *dgst, int dlen,
+                     DSA_SIG *sig, DSA *dsa)
+{
+    struct crypt_kop kop;
+    int dsaret = 1;
+    const BIGNUM *pr, *ps, *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL;
+
+    memset(&kop, 0, sizeof(kop));
+    kop.crk_op = CRK_DSA_VERIFY;
+
+    /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */
+    kop.crk_param[0].crp_p = (caddr_t) dgst;
+    kop.crk_param[0].crp_nbits = dlen * 8;
+    DSA_get0_pqg(dsa, &p, &q, &g);
+    if (bn2crparam(p, &kop.crk_param[1]))
+        goto err;
+    if (bn2crparam(q, &kop.crk_param[2]))
+        goto err;
+    if (bn2crparam(g, &kop.crk_param[3]))
+        goto err;
+    DSA_get0_key(dsa, &pub_key, NULL);
+    if (bn2crparam(pub_key, &kop.crk_param[4]))
+        goto err;
+    DSA_SIG_get0(sig, &pr, &ps);
+    if (bn2crparam(pr, &kop.crk_param[5]))
+        goto err;
+    if (bn2crparam(ps, &kop.crk_param[6]))
+        goto err;
+    kop.crk_iparams = 7;
+
+    if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) {
+        /*
+         * OCF success value is 0, if not zero, change dsaret to fail
+         */
+        if (0 != kop.crk_status)
+            dsaret = 0;
+    } else {
+        dsaret = DSA_meth_get_verify(DSA_OpenSSL())(dgst, dlen, sig, dsa);
+    }
+ err:
+    kop.crk_param[0].crp_p = NULL;
+    zapparams(&kop);
+    return (dsaret);
+}
+#endif
+
+#ifndef OPENSSL_NO_DH
+static int
+cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a,
+                     const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+                     BN_MONT_CTX *m_ctx)
+{
+    return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx));
+}
+
+static int
+cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+{
+    struct crypt_kop kop;
+    int dhret = 1;
+    int fd, keylen;
+    const BIGNUM *p = NULL;
+    const BIGNUM *priv_key = NULL;
+
+    if ((fd = get_asym_dev_crypto()) < 0) {
+        const DH_METHOD *meth = DH_OpenSSL();
+
+        return DH_meth_get_compute_key(meth)(key, pub_key, dh);
+    }
+
+    DH_get0_pqg(dh, &p, NULL, NULL);
+    DH_get0_key(dh, NULL, &priv_key);
+
+    keylen = BN_num_bits(p);
+
+    memset(&kop, 0, sizeof(kop));
+    kop.crk_op = CRK_DH_COMPUTE_KEY;
+
+    /* inputs: dh->priv_key pub_key dh->p key */
+    if (bn2crparam(priv_key, &kop.crk_param[0]))
+        goto err;
+    if (bn2crparam(pub_key, &kop.crk_param[1]))
+        goto err;
+    if (bn2crparam(p, &kop.crk_param[2]))
+        goto err;
+    kop.crk_iparams = 3;
+
+    kop.crk_param[3].crp_p = (caddr_t) key;
+    kop.crk_param[3].crp_nbits = keylen * 8;
+    kop.crk_oparams = 1;
+
+    if (ioctl(fd, CIOCKEY, &kop) == -1) {
+        const DH_METHOD *meth = DH_OpenSSL();
+
+        dhret = DH_meth_get_compute_key(meth)(key, pub_key, dh);
+    }
+ err:
+    kop.crk_param[3].crp_p = NULL;
+    zapparams(&kop);
+    return (dhret);
+}
+
+#endif /* ndef OPENSSL_NO_DH */
+
+/*
+ * ctrl right now is just a wrapper that doesn't do much
+ * but I expect we'll want some options soon.
+ */
+static int
+cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
+{
+# ifdef HAVE_SYSLOG_R
+    struct syslog_data sd = SYSLOG_DATA_INIT;
+# endif
+
+    switch (cmd) {
+    default:
+# ifdef HAVE_SYSLOG_R
+        syslog_r(LOG_ERR, &sd, "cryptodev_ctrl: unknown command %d", cmd);
+# else
+        syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd);
+# endif
+        break;
+    }
+    return (1);
+}
+
+void engine_load_cryptodev_int(void)
+{
+    ENGINE *engine = ENGINE_new();
+    int fd;
+
+    if (engine == NULL)
+        return;
+    if ((fd = get_dev_crypto()) < 0) {
+        ENGINE_free(engine);
+        return;
+    }
+
+    /*
+     * find out what asymmetric crypto algorithms we support
+     */
+    if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) {
+        put_dev_crypto(fd);
+        ENGINE_free(engine);
+        return;
+    }
+    put_dev_crypto(fd);
+
+    if (!ENGINE_set_id(engine, "cryptodev") ||
+        !ENGINE_set_name(engine, "BSD cryptodev engine") ||
+        !ENGINE_set_destroy_function(engine, cryptodev_engine_destroy) ||
+        !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) ||
+        !ENGINE_set_digests(engine, cryptodev_engine_digests) ||
+        !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) ||
+        !ENGINE_set_cmd_defns(engine, cryptodev_defns)) {
+        ENGINE_free(engine);
+        return;
+    }
+
+    cryptodev_rsa = RSA_meth_dup(RSA_PKCS1_OpenSSL());
+    if (cryptodev_rsa != NULL) {
+        RSA_meth_set1_name(cryptodev_rsa, "cryptodev RSA method");
+        RSA_meth_set_flags(cryptodev_rsa, 0);
+        if (ENGINE_set_RSA(engine, cryptodev_rsa)) {
+            if (cryptodev_asymfeat & CRF_MOD_EXP) {
+                RSA_meth_set_bn_mod_exp(cryptodev_rsa, cryptodev_bn_mod_exp);
+                if (cryptodev_asymfeat & CRF_MOD_EXP_CRT)
+                    RSA_meth_set_mod_exp(cryptodev_rsa, cryptodev_rsa_mod_exp);
+                else
+                    RSA_meth_set_mod_exp(cryptodev_rsa,
+                                         cryptodev_rsa_nocrt_mod_exp);
+            }
+        }
+    } else {
+        ENGINE_free(engine);
+        return;
+    }
+
+#ifndef OPENSSL_NO_DSA
+    cryptodev_dsa = DSA_meth_dup(DSA_OpenSSL());
+    if (cryptodev_dsa != NULL) {
+        DSA_meth_set1_name(cryptodev_dsa, "cryptodev DSA method");
+        DSA_meth_set_flags(cryptodev_dsa, 0);
+        if (ENGINE_set_DSA(engine, cryptodev_dsa)) {
+            if (cryptodev_asymfeat & CRF_DSA_SIGN)
+                DSA_meth_set_sign(cryptodev_dsa, cryptodev_dsa_do_sign);
+            if (cryptodev_asymfeat & CRF_MOD_EXP) {
+                DSA_meth_set_bn_mod_exp(cryptodev_dsa,
+                                        cryptodev_dsa_bn_mod_exp);
+                DSA_meth_set_mod_exp(cryptodev_dsa, cryptodev_dsa_dsa_mod_exp);
+            }
+            if (cryptodev_asymfeat & CRF_DSA_VERIFY)
+                DSA_meth_set_verify(cryptodev_dsa, cryptodev_dsa_verify);
+        }
+    } else {
+        ENGINE_free(engine);
+        return;
+    }
+#endif
+
+#ifndef OPENSSL_NO_DH
+    cryptodev_dh = DH_meth_dup(DH_OpenSSL());
+    if (cryptodev_dh != NULL) {
+        DH_meth_set1_name(cryptodev_dh, "cryptodev DH method");
+        DH_meth_set_flags(cryptodev_dh, 0);
+        if (ENGINE_set_DH(engine, cryptodev_dh)) {
+            if (cryptodev_asymfeat & CRF_MOD_EXP) {
+                DH_meth_set_bn_mod_exp(cryptodev_dh, cryptodev_mod_exp_dh);
+                if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY)
+                    DH_meth_set_compute_key(cryptodev_dh,
+                                            cryptodev_dh_compute_key);
+            }
+        }
+    } else {
+        ENGINE_free(engine);
+        return;
+    }
+#endif
+
+    ENGINE_add(engine);
+    ENGINE_free(engine);
+    ERR_clear_error();
+}
+
+#endif                          /* HAVE_CRYPTODEV */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_ctrl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_ctrl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_ctrl.c	(revision 331)
@@ -0,0 +1,338 @@
+/*
+ * Copyright 2001-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 "eng_int.h"
+
+/*
+ * When querying a ENGINE-specific control command's 'description', this
+ * string is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL.
+ */
+static const char *int_no_description = "";
+
+/*
+ * These internal functions handle 'CMD'-related control commands when the
+ * ENGINE in question has asked us to take care of it (ie. the ENGINE did not
+ * set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag.
+ */
+
+static int int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn)
+{
+    if ((defn->cmd_num == 0) || (defn->cmd_name == NULL))
+        return 1;
+    return 0;
+}
+
+static int int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s)
+{
+    int idx = 0;
+    while (!int_ctrl_cmd_is_null(defn) && (strcmp(defn->cmd_name, s) != 0)) {
+        idx++;
+        defn++;
+    }
+    if (int_ctrl_cmd_is_null(defn))
+        /* The given name wasn't found */
+        return -1;
+    return idx;
+}
+
+static int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num)
+{
+    int idx = 0;
+    /*
+     * NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So
+     * our searches don't need to take any longer than necessary.
+     */
+    while (!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num)) {
+        idx++;
+        defn++;
+    }
+    if (defn->cmd_num == num)
+        return idx;
+    /* The given cmd_num wasn't found */
+    return -1;
+}
+
+static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p,
+                           void (*f) (void))
+{
+    int idx;
+    char *s = (char *)p;
+    /* Take care of the easy one first (eg. it requires no searches) */
+    if (cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE) {
+        if ((e->cmd_defns == NULL) || int_ctrl_cmd_is_null(e->cmd_defns))
+            return 0;
+        return e->cmd_defns->cmd_num;
+    }
+    /* One or two commands require that "p" be a valid string buffer */
+    if ((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) ||
+        (cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) ||
+        (cmd == ENGINE_CTRL_GET_DESC_FROM_CMD)) {
+        if (s == NULL) {
+            ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ERR_R_PASSED_NULL_PARAMETER);
+            return -1;
+        }
+    }
+    /* Now handle cmd_name -> cmd_num conversion */
+    if (cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) {
+        if ((e->cmd_defns == NULL)
+            || ((idx = int_ctrl_cmd_by_name(e->cmd_defns, s)) < 0)) {
+            ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INVALID_CMD_NAME);
+            return -1;
+        }
+        return e->cmd_defns[idx].cmd_num;
+    }
+    /*
+     * For the rest of the commands, the 'long' argument must specify a valid
+     * command number - so we need to conduct a search.
+     */
+    if ((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns,
+                                                              (unsigned int)
+                                                              i)) < 0)) {
+        ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INVALID_CMD_NUMBER);
+        return -1;
+    }
+    /* Now the logic splits depending on command type */
+    switch (cmd) {
+    case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
+        idx++;
+        if (int_ctrl_cmd_is_null(e->cmd_defns + idx))
+            /* end-of-list */
+            return 0;
+        else
+            return e->cmd_defns[idx].cmd_num;
+    case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
+        return strlen(e->cmd_defns[idx].cmd_name);
+    case ENGINE_CTRL_GET_NAME_FROM_CMD:
+        return BIO_snprintf(s, strlen(e->cmd_defns[idx].cmd_name) + 1,
+                            "%s", e->cmd_defns[idx].cmd_name);
+    case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
+        if (e->cmd_defns[idx].cmd_desc)
+            return strlen(e->cmd_defns[idx].cmd_desc);
+        return strlen(int_no_description);
+    case ENGINE_CTRL_GET_DESC_FROM_CMD:
+        if (e->cmd_defns[idx].cmd_desc)
+            return BIO_snprintf(s,
+                                strlen(e->cmd_defns[idx].cmd_desc) + 1,
+                                "%s", e->cmd_defns[idx].cmd_desc);
+        return BIO_snprintf(s, strlen(int_no_description) + 1, "%s",
+                            int_no_description);
+    case ENGINE_CTRL_GET_CMD_FLAGS:
+        return e->cmd_defns[idx].cmd_flags;
+    }
+    /* Shouldn't really be here ... */
+    ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INTERNAL_LIST_ERROR);
+    return -1;
+}
+
+int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
+{
+    int ctrl_exists, ref_exists;
+    if (e == NULL) {
+        ENGINEerr(ENGINE_F_ENGINE_CTRL, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    CRYPTO_THREAD_write_lock(global_engine_lock);
+    ref_exists = ((e->struct_ref > 0) ? 1 : 0);
+    CRYPTO_THREAD_unlock(global_engine_lock);
+    ctrl_exists = ((e->ctrl == NULL) ? 0 : 1);
+    if (!ref_exists) {
+        ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_NO_REFERENCE);
+        return 0;
+    }
+    /*
+     * Intercept any "root-level" commands before trying to hand them on to
+     * ctrl() handlers.
+     */
+    switch (cmd) {
+    case ENGINE_CTRL_HAS_CTRL_FUNCTION:
+        return ctrl_exists;
+    case ENGINE_CTRL_GET_FIRST_CMD_TYPE:
+    case ENGINE_CTRL_GET_NEXT_CMD_TYPE:
+    case ENGINE_CTRL_GET_CMD_FROM_NAME:
+    case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD:
+    case ENGINE_CTRL_GET_NAME_FROM_CMD:
+    case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD:
+    case ENGINE_CTRL_GET_DESC_FROM_CMD:
+    case ENGINE_CTRL_GET_CMD_FLAGS:
+        if (ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL))
+            return int_ctrl_helper(e, cmd, i, p, f);
+        if (!ctrl_exists) {
+            ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_NO_CONTROL_FUNCTION);
+            /*
+             * For these cmd-related functions, failure is indicated by a -1
+             * return value (because 0 is used as a valid return in some
+             * places).
+             */
+            return -1;
+        }
+    default:
+        break;
+    }
+    /* Anything else requires a ctrl() handler to exist. */
+    if (!ctrl_exists) {
+        ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_NO_CONTROL_FUNCTION);
+        return 0;
+    }
+    return e->ctrl(e, cmd, i, p, f);
+}
+
+int ENGINE_cmd_is_executable(ENGINE *e, int cmd)
+{
+    int flags;
+    if ((flags =
+         ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, NULL, NULL)) < 0) {
+        ENGINEerr(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE,
+                  ENGINE_R_INVALID_CMD_NUMBER);
+        return 0;
+    }
+    if (!(flags & ENGINE_CMD_FLAG_NO_INPUT) &&
+        !(flags & ENGINE_CMD_FLAG_NUMERIC) &&
+        !(flags & ENGINE_CMD_FLAG_STRING))
+        return 0;
+    return 1;
+}
+
+int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
+                    long i, void *p, void (*f) (void), int cmd_optional)
+{
+    int num;
+
+    if (e == NULL || cmd_name == NULL) {
+        ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    if (e->ctrl == NULL
+        || (num = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FROM_NAME,
+                              0, (void *)cmd_name, NULL)) <= 0) {
+        /*
+         * If the command didn't *have* to be supported, we fake success.
+         * This allows certain settings to be specified for multiple ENGINEs
+         * and only require a change of ENGINE id (without having to
+         * selectively apply settings). Eg. changing from a hardware device
+         * back to the regular software ENGINE without editing the config
+         * file, etc.
+         */
+        if (cmd_optional) {
+            ERR_clear_error();
+            return 1;
+        }
+        ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD, ENGINE_R_INVALID_CMD_NAME);
+        return 0;
+    }
+    /*
+     * Force the result of the control command to 0 or 1, for the reasons
+     * mentioned before.
+     */
+    if (ENGINE_ctrl(e, num, i, p, f) > 0)
+        return 1;
+    return 0;
+}
+
+int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
+                           int cmd_optional)
+{
+    int num, flags;
+    long l;
+    char *ptr;
+
+    if (e == NULL || cmd_name == NULL) {
+        ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    if (e->ctrl == NULL
+        || (num = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FROM_NAME,
+                              0, (void *)cmd_name, NULL)) <= 0) {
+        /*
+         * If the command didn't *have* to be supported, we fake success.
+         * This allows certain settings to be specified for multiple ENGINEs
+         * and only require a change of ENGINE id (without having to
+         * selectively apply settings). Eg. changing from a hardware device
+         * back to the regular software ENGINE without editing the config
+         * file, etc.
+         */
+        if (cmd_optional) {
+            ERR_clear_error();
+            return 1;
+        }
+        ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, ENGINE_R_INVALID_CMD_NAME);
+        return 0;
+    }
+    if (!ENGINE_cmd_is_executable(e, num)) {
+        ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+                  ENGINE_R_CMD_NOT_EXECUTABLE);
+        return 0;
+    }
+
+    flags = ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, NULL, NULL);
+    if (flags < 0) {
+        /*
+         * Shouldn't happen, given that ENGINE_cmd_is_executable() returned
+         * success.
+         */
+        ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+                  ENGINE_R_INTERNAL_LIST_ERROR);
+        return 0;
+    }
+    /*
+     * If the command takes no input, there must be no input. And vice versa.
+     */
+    if (flags & ENGINE_CMD_FLAG_NO_INPUT) {
+        if (arg != NULL) {
+            ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+                      ENGINE_R_COMMAND_TAKES_NO_INPUT);
+            return 0;
+        }
+        /*
+         * We deliberately force the result of ENGINE_ctrl() to 0 or 1 rather
+         * than returning it as "return data". This is to ensure usage of
+         * these commands is consistent across applications and that certain
+         * applications don't understand it one way, and others another.
+         */
+        if (ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
+            return 1;
+        return 0;
+    }
+    /* So, we require input */
+    if (arg == NULL) {
+        ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+                  ENGINE_R_COMMAND_TAKES_INPUT);
+        return 0;
+    }
+    /* If it takes string input, that's easy */
+    if (flags & ENGINE_CMD_FLAG_STRING) {
+        /* Same explanation as above */
+        if (ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0)
+            return 1;
+        return 0;
+    }
+    /*
+     * If it doesn't take numeric either, then it is unsupported for use in a
+     * config-setting situation, which is what this function is for. This
+     * should never happen though, because ENGINE_cmd_is_executable() was
+     * used.
+     */
+    if (!(flags & ENGINE_CMD_FLAG_NUMERIC)) {
+        ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+                  ENGINE_R_INTERNAL_LIST_ERROR);
+        return 0;
+    }
+    l = strtol(arg, &ptr, 10);
+    if ((arg == ptr) || (*ptr != '\0')) {
+        ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING,
+                  ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER);
+        return 0;
+    }
+    /*
+     * Force the result of the control command to 0 or 1, for the reasons
+     * mentioned before.
+     */
+    if (ENGINE_ctrl(e, num, l, NULL, NULL) > 0)
+        return 1;
+    return 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_dyn.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_dyn.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_dyn.c	(revision 331)
@@ -0,0 +1,510 @@
+/*
+ * Copyright 2001-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 "eng_int.h"
+#include "internal/dso.h"
+#include <openssl/crypto.h>
+
+/*
+ * Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE
+ * loader should implement the hook-up functions with the following
+ * prototypes.
+ */
+
+/* Our ENGINE handlers */
+static int dynamic_init(ENGINE *e);
+static int dynamic_finish(ENGINE *e);
+static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p,
+                        void (*f) (void));
+/* Predeclare our context type */
+typedef struct st_dynamic_data_ctx dynamic_data_ctx;
+/* The implementation for the important control command */
+static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx);
+
+#define DYNAMIC_CMD_SO_PATH             ENGINE_CMD_BASE
+#define DYNAMIC_CMD_NO_VCHECK           (ENGINE_CMD_BASE + 1)
+#define DYNAMIC_CMD_ID                  (ENGINE_CMD_BASE + 2)
+#define DYNAMIC_CMD_LIST_ADD            (ENGINE_CMD_BASE + 3)
+#define DYNAMIC_CMD_DIR_LOAD            (ENGINE_CMD_BASE + 4)
+#define DYNAMIC_CMD_DIR_ADD             (ENGINE_CMD_BASE + 5)
+#define DYNAMIC_CMD_LOAD                (ENGINE_CMD_BASE + 6)
+
+/* The constants used when creating the ENGINE */
+static const char *engine_dynamic_id = "dynamic";
+static const char *engine_dynamic_name = "Dynamic engine loading support";
+static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = {
+    {DYNAMIC_CMD_SO_PATH,
+     "SO_PATH",
+     "Specifies the path to the new ENGINE shared library",
+     ENGINE_CMD_FLAG_STRING},
+    {DYNAMIC_CMD_NO_VCHECK,
+     "NO_VCHECK",
+     "Specifies to continue even if version checking fails (boolean)",
+     ENGINE_CMD_FLAG_NUMERIC},
+    {DYNAMIC_CMD_ID,
+     "ID",
+     "Specifies an ENGINE id name for loading",
+     ENGINE_CMD_FLAG_STRING},
+    {DYNAMIC_CMD_LIST_ADD,
+     "LIST_ADD",
+     "Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)",
+     ENGINE_CMD_FLAG_NUMERIC},
+    {DYNAMIC_CMD_DIR_LOAD,
+     "DIR_LOAD",
+     "Specifies whether to load from 'DIR_ADD' directories (0=no,1=yes,2=mandatory)",
+     ENGINE_CMD_FLAG_NUMERIC},
+    {DYNAMIC_CMD_DIR_ADD,
+     "DIR_ADD",
+     "Adds a directory from which ENGINEs can be loaded",
+     ENGINE_CMD_FLAG_STRING},
+    {DYNAMIC_CMD_LOAD,
+     "LOAD",
+     "Load up the ENGINE specified by other settings",
+     ENGINE_CMD_FLAG_NO_INPUT},
+    {0, NULL, NULL, 0}
+};
+
+/*
+ * Loading code stores state inside the ENGINE structure via the "ex_data"
+ * element. We load all our state into a single structure and use that as a
+ * single context in the "ex_data" stack.
+ */
+struct st_dynamic_data_ctx {
+    /* The DSO object we load that supplies the ENGINE code */
+    DSO *dynamic_dso;
+    /*
+     * The function pointer to the version checking shared library function
+     */
+    dynamic_v_check_fn v_check;
+    /*
+     * The function pointer to the engine-binding shared library function
+     */
+    dynamic_bind_engine bind_engine;
+    /* The default name/path for loading the shared library */
+    char *DYNAMIC_LIBNAME;
+    /* Whether to continue loading on a version check failure */
+    int no_vcheck;
+    /* If non-NULL, stipulates the 'id' of the ENGINE to be loaded */
+    char *engine_id;
+    /*
+     * If non-zero, a successfully loaded ENGINE should be added to the
+     * internal ENGINE list. If 2, the add must succeed or the entire load
+     * should fail.
+     */
+    int list_add_value;
+    /* The symbol name for the version checking function */
+    const char *DYNAMIC_F1;
+    /* The symbol name for the "initialise ENGINE structure" function */
+    const char *DYNAMIC_F2;
+    /*
+     * Whether to never use 'dirs', use 'dirs' as a fallback, or only use
+     * 'dirs' for loading. Default is to use 'dirs' as a fallback.
+     */
+    int dir_load;
+    /* A stack of directories from which ENGINEs could be loaded */
+    STACK_OF(OPENSSL_STRING) *dirs;
+};
+
+/*
+ * This is the "ex_data" index we obtain and reserve for use with our context
+ * structure.
+ */
+static int dynamic_ex_data_idx = -1;
+
+static void int_free_str(char *s)
+{
+    OPENSSL_free(s);
+}
+
+/*
+ * Because our ex_data element may or may not get allocated depending on
+ * whether a "first-use" occurs before the ENGINE is freed, we have a memory
+ * leak problem to solve. We can't declare a "new" handler for the ex_data as
+ * we don't want a dynamic_data_ctx in *all* ENGINE structures of all types
+ * (this is a bug in the design of CRYPTO_EX_DATA). As such, we just declare
+ * a "free" handler and that will get called if an ENGINE is being destroyed
+ * and there was an ex_data element corresponding to our context type.
+ */
+static void dynamic_data_ctx_free_func(void *parent, void *ptr,
+                                       CRYPTO_EX_DATA *ad, int idx, long argl,
+                                       void *argp)
+{
+    if (ptr) {
+        dynamic_data_ctx *ctx = (dynamic_data_ctx *)ptr;
+        DSO_free(ctx->dynamic_dso);
+        OPENSSL_free(ctx->DYNAMIC_LIBNAME);
+        OPENSSL_free(ctx->engine_id);
+        sk_OPENSSL_STRING_pop_free(ctx->dirs, int_free_str);
+        OPENSSL_free(ctx);
+    }
+}
+
+/*
+ * Construct the per-ENGINE context. We create it blindly and then use a lock
+ * to check for a race - if so, all but one of the threads "racing" will have
+ * wasted their time. The alternative involves creating everything inside the
+ * lock which is far worse.
+ */
+static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
+{
+    dynamic_data_ctx *c = OPENSSL_zalloc(sizeof(*c));
+    int ret = 1;
+
+    if (c == NULL) {
+        ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    c->dirs = sk_OPENSSL_STRING_new_null();
+    if (c->dirs == NULL) {
+        ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(c);
+        return 0;
+    }
+    c->DYNAMIC_F1 = "v_check";
+    c->DYNAMIC_F2 = "bind_engine";
+    c->dir_load = 1;
+    CRYPTO_THREAD_write_lock(global_engine_lock);
+    if ((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e,
+                                                       dynamic_ex_data_idx))
+        == NULL) {
+        /* Good, we're the first */
+        ret = ENGINE_set_ex_data(e, dynamic_ex_data_idx, c);
+        if (ret) {
+            *ctx = c;
+            c = NULL;
+        }
+    }
+    CRYPTO_THREAD_unlock(global_engine_lock);
+    /*
+     * If we lost the race to set the context, c is non-NULL and *ctx is the
+     * context of the thread that won.
+     */
+    if (c)
+        sk_OPENSSL_STRING_free(c->dirs);
+    OPENSSL_free(c);
+    return ret;
+}
+
+/*
+ * This function retrieves the context structure from an ENGINE's "ex_data",
+ * or if it doesn't exist yet, sets it up.
+ */
+static dynamic_data_ctx *dynamic_get_data_ctx(ENGINE *e)
+{
+    dynamic_data_ctx *ctx;
+    if (dynamic_ex_data_idx < 0) {
+        /*
+         * Create and register the ENGINE ex_data, and associate our "free"
+         * function with it to ensure any allocated contexts get freed when
+         * an ENGINE goes underground.
+         */
+        int new_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL,
+                                              dynamic_data_ctx_free_func);
+        if (new_idx == -1) {
+            ENGINEerr(ENGINE_F_DYNAMIC_GET_DATA_CTX, ENGINE_R_NO_INDEX);
+            return NULL;
+        }
+        CRYPTO_THREAD_write_lock(global_engine_lock);
+        /* Avoid a race by checking again inside this lock */
+        if (dynamic_ex_data_idx < 0) {
+            /* Good, someone didn't beat us to it */
+            dynamic_ex_data_idx = new_idx;
+            new_idx = -1;
+        }
+        CRYPTO_THREAD_unlock(global_engine_lock);
+        /*
+         * In theory we could "give back" the index here if (new_idx>-1), but
+         * it's not possible and wouldn't gain us much if it were.
+         */
+    }
+    ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx);
+    /* Check if the context needs to be created */
+    if ((ctx == NULL) && !dynamic_set_data_ctx(e, &ctx))
+        /* "set_data" will set errors if necessary */
+        return NULL;
+    return ctx;
+}
+
+static ENGINE *engine_dynamic(void)
+{
+    ENGINE *ret = ENGINE_new();
+    if (ret == NULL)
+        return NULL;
+    if (!ENGINE_set_id(ret, engine_dynamic_id) ||
+        !ENGINE_set_name(ret, engine_dynamic_name) ||
+        !ENGINE_set_init_function(ret, dynamic_init) ||
+        !ENGINE_set_finish_function(ret, dynamic_finish) ||
+        !ENGINE_set_ctrl_function(ret, dynamic_ctrl) ||
+        !ENGINE_set_flags(ret, ENGINE_FLAGS_BY_ID_COPY) ||
+        !ENGINE_set_cmd_defns(ret, dynamic_cmd_defns)) {
+        ENGINE_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+void engine_load_dynamic_int(void)
+{
+    ENGINE *toadd = engine_dynamic();
+    if (!toadd)
+        return;
+    ENGINE_add(toadd);
+    /*
+     * If the "add" worked, it gets a structural reference. So either way, we
+     * release our just-created reference.
+     */
+    ENGINE_free(toadd);
+    /*
+     * If the "add" didn't work, it was probably a conflict because it was
+     * already added (eg. someone calling ENGINE_load_blah then calling
+     * ENGINE_load_builtin_engines() perhaps).
+     */
+    ERR_clear_error();
+}
+
+static int dynamic_init(ENGINE *e)
+{
+    /*
+     * We always return failure - the "dynamic" engine itself can't be used
+     * for anything.
+     */
+    return 0;
+}
+
+static int dynamic_finish(ENGINE *e)
+{
+    /*
+     * This should never be called on account of "dynamic_init" always
+     * failing.
+     */
+    return 0;
+}
+
+static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
+{
+    dynamic_data_ctx *ctx = dynamic_get_data_ctx(e);
+    int initialised;
+
+    if (!ctx) {
+        ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_NOT_LOADED);
+        return 0;
+    }
+    initialised = ((ctx->dynamic_dso == NULL) ? 0 : 1);
+    /* All our control commands require the ENGINE to be uninitialised */
+    if (initialised) {
+        ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_ALREADY_LOADED);
+        return 0;
+    }
+    switch (cmd) {
+    case DYNAMIC_CMD_SO_PATH:
+        /* a NULL 'p' or a string of zero-length is the same thing */
+        if (p && (strlen((const char *)p) < 1))
+            p = NULL;
+        OPENSSL_free(ctx->DYNAMIC_LIBNAME);
+        if (p)
+            ctx->DYNAMIC_LIBNAME = OPENSSL_strdup(p);
+        else
+            ctx->DYNAMIC_LIBNAME = NULL;
+        return (ctx->DYNAMIC_LIBNAME ? 1 : 0);
+    case DYNAMIC_CMD_NO_VCHECK:
+        ctx->no_vcheck = ((i == 0) ? 0 : 1);
+        return 1;
+    case DYNAMIC_CMD_ID:
+        /* a NULL 'p' or a string of zero-length is the same thing */
+        if (p && (strlen((const char *)p) < 1))
+            p = NULL;
+        OPENSSL_free(ctx->engine_id);
+        if (p)
+            ctx->engine_id = OPENSSL_strdup(p);
+        else
+            ctx->engine_id = NULL;
+        return (ctx->engine_id ? 1 : 0);
+    case DYNAMIC_CMD_LIST_ADD:
+        if ((i < 0) || (i > 2)) {
+            ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_INVALID_ARGUMENT);
+            return 0;
+        }
+        ctx->list_add_value = (int)i;
+        return 1;
+    case DYNAMIC_CMD_LOAD:
+        return dynamic_load(e, ctx);
+    case DYNAMIC_CMD_DIR_LOAD:
+        if ((i < 0) || (i > 2)) {
+            ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_INVALID_ARGUMENT);
+            return 0;
+        }
+        ctx->dir_load = (int)i;
+        return 1;
+    case DYNAMIC_CMD_DIR_ADD:
+        /* a NULL 'p' or a string of zero-length is the same thing */
+        if (!p || (strlen((const char *)p) < 1)) {
+            ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_INVALID_ARGUMENT);
+            return 0;
+        }
+        {
+            char *tmp_str = OPENSSL_strdup(p);
+            if (tmp_str == NULL) {
+                ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ERR_R_MALLOC_FAILURE);
+                return 0;
+            }
+            if (!sk_OPENSSL_STRING_push(ctx->dirs, tmp_str)) {
+                OPENSSL_free(tmp_str);
+                ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ERR_R_MALLOC_FAILURE);
+                return 0;
+            }
+        }
+        return 1;
+    default:
+        break;
+    }
+    ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+    return 0;
+}
+
+static int int_load(dynamic_data_ctx *ctx)
+{
+    int num, loop;
+    /* Unless told not to, try a direct load */
+    if ((ctx->dir_load != 2) && (DSO_load(ctx->dynamic_dso,
+                                          ctx->DYNAMIC_LIBNAME, NULL,
+                                          0)) != NULL)
+        return 1;
+    /* If we're not allowed to use 'dirs' or we have none, fail */
+    if (!ctx->dir_load || (num = sk_OPENSSL_STRING_num(ctx->dirs)) < 1)
+        return 0;
+    for (loop = 0; loop < num; loop++) {
+        const char *s = sk_OPENSSL_STRING_value(ctx->dirs, loop);
+        char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s);
+        if (!merge)
+            return 0;
+        if (DSO_load(ctx->dynamic_dso, merge, NULL, 0)) {
+            /* Found what we're looking for */
+            OPENSSL_free(merge);
+            return 1;
+        }
+        OPENSSL_free(merge);
+    }
+    return 0;
+}
+
+static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx)
+{
+    ENGINE cpy;
+    dynamic_fns fns;
+
+    if (ctx->dynamic_dso == NULL)
+        ctx->dynamic_dso = DSO_new();
+    if (ctx->dynamic_dso == NULL)
+        return 0;
+    if (!ctx->DYNAMIC_LIBNAME) {
+        if (!ctx->engine_id)
+            return 0;
+        DSO_ctrl(ctx->dynamic_dso, DSO_CTRL_SET_FLAGS,
+                 DSO_FLAG_NAME_TRANSLATION_EXT_ONLY, NULL);
+        ctx->DYNAMIC_LIBNAME =
+            DSO_convert_filename(ctx->dynamic_dso, ctx->engine_id);
+    }
+    if (!int_load(ctx)) {
+        ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_DSO_NOT_FOUND);
+        DSO_free(ctx->dynamic_dso);
+        ctx->dynamic_dso = NULL;
+        return 0;
+    }
+    /* We have to find a bind function otherwise it'll always end badly */
+    if (!
+        (ctx->bind_engine =
+         (dynamic_bind_engine) DSO_bind_func(ctx->dynamic_dso,
+                                             ctx->DYNAMIC_F2))) {
+        ctx->bind_engine = NULL;
+        DSO_free(ctx->dynamic_dso);
+        ctx->dynamic_dso = NULL;
+        ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_DSO_FAILURE);
+        return 0;
+    }
+    /* Do we perform version checking? */
+    if (!ctx->no_vcheck) {
+        unsigned long vcheck_res = 0;
+        /*
+         * Now we try to find a version checking function and decide how to
+         * cope with failure if/when it fails.
+         */
+        ctx->v_check =
+            (dynamic_v_check_fn) DSO_bind_func(ctx->dynamic_dso,
+                                               ctx->DYNAMIC_F1);
+        if (ctx->v_check)
+            vcheck_res = ctx->v_check(OSSL_DYNAMIC_VERSION);
+        /*
+         * We fail if the version checker veto'd the load *or* if it is
+         * deferring to us (by returning its version) and we think it is too
+         * old.
+         */
+        if (vcheck_res < OSSL_DYNAMIC_OLDEST) {
+            /* Fail */
+            ctx->bind_engine = NULL;
+            ctx->v_check = NULL;
+            DSO_free(ctx->dynamic_dso);
+            ctx->dynamic_dso = NULL;
+            ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
+                      ENGINE_R_VERSION_INCOMPATIBILITY);
+            return 0;
+        }
+    }
+    /*
+     * First binary copy the ENGINE structure so that we can roll back if the
+     * hand-over fails
+     */
+    memcpy(&cpy, e, sizeof(ENGINE));
+    /*
+     * Provide the ERR, "ex_data", memory, and locking callbacks so the
+     * loaded library uses our state rather than its own. FIXME: As noted in
+     * engine.h, much of this would be simplified if each area of code
+     * provided its own "summary" structure of all related callbacks. It
+     * would also increase opaqueness.
+     */
+    fns.static_state = ENGINE_get_static_state();
+    CRYPTO_get_mem_functions(&fns.mem_fns.malloc_fn, &fns.mem_fns.realloc_fn,
+                             &fns.mem_fns.free_fn);
+    /*
+     * Now that we've loaded the dynamic engine, make sure no "dynamic"
+     * ENGINE elements will show through.
+     */
+    engine_set_all_null(e);
+
+    /* Try to bind the ENGINE onto our own ENGINE structure */
+    if (!ctx->bind_engine(e, ctx->engine_id, &fns)) {
+        ctx->bind_engine = NULL;
+        ctx->v_check = NULL;
+        DSO_free(ctx->dynamic_dso);
+        ctx->dynamic_dso = NULL;
+        ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_INIT_FAILED);
+        /* Copy the original ENGINE structure back */
+        memcpy(e, &cpy, sizeof(ENGINE));
+        return 0;
+    }
+    /* Do we try to add this ENGINE to the internal list too? */
+    if (ctx->list_add_value > 0) {
+        if (!ENGINE_add(e)) {
+            /* Do we tolerate this or fail? */
+            if (ctx->list_add_value > 1) {
+                /*
+                 * Fail - NB: By this time, it's too late to rollback, and
+                 * trying to do so allows the bind_engine() code to have
+                 * created leaks. We just have to fail where we are, after
+                 * the ENGINE has changed.
+                 */
+                ENGINEerr(ENGINE_F_DYNAMIC_LOAD,
+                          ENGINE_R_CONFLICTING_ENGINE_ID);
+                return 0;
+            }
+            /* Tolerate */
+            ERR_clear_error();
+        }
+    }
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_err.c	(revision 331)
@@ -0,0 +1,123 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/engine.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ENGINE,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ENGINE,0,reason)
+
+static ERR_STRING_DATA ENGINE_str_functs[] = {
+    {ERR_FUNC(ENGINE_F_DYNAMIC_CTRL), "dynamic_ctrl"},
+    {ERR_FUNC(ENGINE_F_DYNAMIC_GET_DATA_CTX), "dynamic_get_data_ctx"},
+    {ERR_FUNC(ENGINE_F_DYNAMIC_LOAD), "dynamic_load"},
+    {ERR_FUNC(ENGINE_F_DYNAMIC_SET_DATA_CTX), "dynamic_set_data_ctx"},
+    {ERR_FUNC(ENGINE_F_ENGINE_ADD), "ENGINE_add"},
+    {ERR_FUNC(ENGINE_F_ENGINE_BY_ID), "ENGINE_by_id"},
+    {ERR_FUNC(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE), "ENGINE_cmd_is_executable"},
+    {ERR_FUNC(ENGINE_F_ENGINE_CTRL), "ENGINE_ctrl"},
+    {ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD), "ENGINE_ctrl_cmd"},
+    {ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD_STRING), "ENGINE_ctrl_cmd_string"},
+    {ERR_FUNC(ENGINE_F_ENGINE_FINISH), "ENGINE_finish"},
+    {ERR_FUNC(ENGINE_F_ENGINE_GET_CIPHER), "ENGINE_get_cipher"},
+    {ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST), "ENGINE_get_digest"},
+    {ERR_FUNC(ENGINE_F_ENGINE_GET_FIRST), "ENGINE_get_first"},
+    {ERR_FUNC(ENGINE_F_ENGINE_GET_LAST), "ENGINE_get_last"},
+    {ERR_FUNC(ENGINE_F_ENGINE_GET_NEXT), "ENGINE_get_next"},
+    {ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH),
+     "ENGINE_get_pkey_asn1_meth"},
+    {ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_METH), "ENGINE_get_pkey_meth"},
+    {ERR_FUNC(ENGINE_F_ENGINE_GET_PREV), "ENGINE_get_prev"},
+    {ERR_FUNC(ENGINE_F_ENGINE_INIT), "ENGINE_init"},
+    {ERR_FUNC(ENGINE_F_ENGINE_LIST_ADD), "engine_list_add"},
+    {ERR_FUNC(ENGINE_F_ENGINE_LIST_REMOVE), "engine_list_remove"},
+    {ERR_FUNC(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY), "ENGINE_load_private_key"},
+    {ERR_FUNC(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY), "ENGINE_load_public_key"},
+    {ERR_FUNC(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT),
+     "ENGINE_load_ssl_client_cert"},
+    {ERR_FUNC(ENGINE_F_ENGINE_NEW), "ENGINE_new"},
+    {ERR_FUNC(ENGINE_F_ENGINE_PKEY_ASN1_FIND_STR),
+     "ENGINE_pkey_asn1_find_str"},
+    {ERR_FUNC(ENGINE_F_ENGINE_REMOVE), "ENGINE_remove"},
+    {ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_STRING),
+     "ENGINE_set_default_string"},
+    {ERR_FUNC(ENGINE_F_ENGINE_SET_ID), "ENGINE_set_id"},
+    {ERR_FUNC(ENGINE_F_ENGINE_SET_NAME), "ENGINE_set_name"},
+    {ERR_FUNC(ENGINE_F_ENGINE_TABLE_REGISTER), "engine_table_register"},
+    {ERR_FUNC(ENGINE_F_ENGINE_UNLOCKED_FINISH), "engine_unlocked_finish"},
+    {ERR_FUNC(ENGINE_F_ENGINE_UP_REF), "ENGINE_up_ref"},
+    {ERR_FUNC(ENGINE_F_INT_CTRL_HELPER), "int_ctrl_helper"},
+    {ERR_FUNC(ENGINE_F_INT_ENGINE_CONFIGURE), "int_engine_configure"},
+    {ERR_FUNC(ENGINE_F_INT_ENGINE_MODULE_INIT), "int_engine_module_init"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA ENGINE_str_reasons[] = {
+    {ERR_REASON(ENGINE_R_ALREADY_LOADED), "already loaded"},
+    {ERR_REASON(ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER),
+     "argument is not a number"},
+    {ERR_REASON(ENGINE_R_CMD_NOT_EXECUTABLE), "cmd not executable"},
+    {ERR_REASON(ENGINE_R_COMMAND_TAKES_INPUT), "command takes input"},
+    {ERR_REASON(ENGINE_R_COMMAND_TAKES_NO_INPUT), "command takes no input"},
+    {ERR_REASON(ENGINE_R_CONFLICTING_ENGINE_ID), "conflicting engine id"},
+    {ERR_REASON(ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED),
+     "ctrl command not implemented"},
+    {ERR_REASON(ENGINE_R_DSO_FAILURE), "DSO failure"},
+    {ERR_REASON(ENGINE_R_DSO_NOT_FOUND), "dso not found"},
+    {ERR_REASON(ENGINE_R_ENGINES_SECTION_ERROR), "engines section error"},
+    {ERR_REASON(ENGINE_R_ENGINE_CONFIGURATION_ERROR),
+     "engine configuration error"},
+    {ERR_REASON(ENGINE_R_ENGINE_IS_NOT_IN_LIST), "engine is not in the list"},
+    {ERR_REASON(ENGINE_R_ENGINE_SECTION_ERROR), "engine section error"},
+    {ERR_REASON(ENGINE_R_FAILED_LOADING_PRIVATE_KEY),
+     "failed loading private key"},
+    {ERR_REASON(ENGINE_R_FAILED_LOADING_PUBLIC_KEY),
+     "failed loading public key"},
+    {ERR_REASON(ENGINE_R_FINISH_FAILED), "finish failed"},
+    {ERR_REASON(ENGINE_R_ID_OR_NAME_MISSING), "'id' or 'name' missing"},
+    {ERR_REASON(ENGINE_R_INIT_FAILED), "init failed"},
+    {ERR_REASON(ENGINE_R_INTERNAL_LIST_ERROR), "internal list error"},
+    {ERR_REASON(ENGINE_R_INVALID_ARGUMENT), "invalid argument"},
+    {ERR_REASON(ENGINE_R_INVALID_CMD_NAME), "invalid cmd name"},
+    {ERR_REASON(ENGINE_R_INVALID_CMD_NUMBER), "invalid cmd number"},
+    {ERR_REASON(ENGINE_R_INVALID_INIT_VALUE), "invalid init value"},
+    {ERR_REASON(ENGINE_R_INVALID_STRING), "invalid string"},
+    {ERR_REASON(ENGINE_R_NOT_INITIALISED), "not initialised"},
+    {ERR_REASON(ENGINE_R_NOT_LOADED), "not loaded"},
+    {ERR_REASON(ENGINE_R_NO_CONTROL_FUNCTION), "no control function"},
+    {ERR_REASON(ENGINE_R_NO_INDEX), "no index"},
+    {ERR_REASON(ENGINE_R_NO_LOAD_FUNCTION), "no load function"},
+    {ERR_REASON(ENGINE_R_NO_REFERENCE), "no reference"},
+    {ERR_REASON(ENGINE_R_NO_SUCH_ENGINE), "no such engine"},
+    {ERR_REASON(ENGINE_R_UNIMPLEMENTED_CIPHER), "unimplemented cipher"},
+    {ERR_REASON(ENGINE_R_UNIMPLEMENTED_DIGEST), "unimplemented digest"},
+    {ERR_REASON(ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD),
+     "unimplemented public key method"},
+    {ERR_REASON(ENGINE_R_VERSION_INCOMPATIBILITY), "version incompatibility"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_ENGINE_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(ENGINE_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, ENGINE_str_functs);
+        ERR_load_strings(0, ENGINE_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_fat.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_fat.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_fat.c	(revision 331)
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2001-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include "eng_int.h"
+#include <openssl/conf.h>
+
+int ENGINE_set_default(ENGINE *e, unsigned int flags)
+{
+    if ((flags & ENGINE_METHOD_CIPHERS) && !ENGINE_set_default_ciphers(e))
+        return 0;
+    if ((flags & ENGINE_METHOD_DIGESTS) && !ENGINE_set_default_digests(e))
+        return 0;
+#ifndef OPENSSL_NO_RSA
+    if ((flags & ENGINE_METHOD_RSA) && !ENGINE_set_default_RSA(e))
+        return 0;
+#endif
+#ifndef OPENSSL_NO_DSA
+    if ((flags & ENGINE_METHOD_DSA) && !ENGINE_set_default_DSA(e))
+        return 0;
+#endif
+#ifndef OPENSSL_NO_DH
+    if ((flags & ENGINE_METHOD_DH) && !ENGINE_set_default_DH(e))
+        return 0;
+#endif
+#ifndef OPENSSL_NO_EC
+    if ((flags & ENGINE_METHOD_EC) && !ENGINE_set_default_EC(e))
+        return 0;
+#endif
+    if ((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e))
+        return 0;
+    if ((flags & ENGINE_METHOD_PKEY_METHS)
+        && !ENGINE_set_default_pkey_meths(e))
+        return 0;
+    if ((flags & ENGINE_METHOD_PKEY_ASN1_METHS)
+        && !ENGINE_set_default_pkey_asn1_meths(e))
+        return 0;
+    return 1;
+}
+
+/* Set default algorithms using a string */
+
+static int int_def_cb(const char *alg, int len, void *arg)
+{
+    unsigned int *pflags = arg;
+    if (alg == NULL)
+        return 0;
+    if (strncmp(alg, "ALL", len) == 0)
+        *pflags |= ENGINE_METHOD_ALL;
+    else if (strncmp(alg, "RSA", len) == 0)
+        *pflags |= ENGINE_METHOD_RSA;
+    else if (strncmp(alg, "DSA", len) == 0)
+        *pflags |= ENGINE_METHOD_DSA;
+    else if (strncmp(alg, "DH", len) == 0)
+        *pflags |= ENGINE_METHOD_DH;
+    else if (strncmp(alg, "EC", len) == 0)
+        *pflags |= ENGINE_METHOD_EC;
+    else if (strncmp(alg, "RAND", len) == 0)
+        *pflags |= ENGINE_METHOD_RAND;
+    else if (strncmp(alg, "CIPHERS", len) == 0)
+        *pflags |= ENGINE_METHOD_CIPHERS;
+    else if (strncmp(alg, "DIGESTS", len) == 0)
+        *pflags |= ENGINE_METHOD_DIGESTS;
+    else if (strncmp(alg, "PKEY", len) == 0)
+        *pflags |= ENGINE_METHOD_PKEY_METHS | ENGINE_METHOD_PKEY_ASN1_METHS;
+    else if (strncmp(alg, "PKEY_CRYPTO", len) == 0)
+        *pflags |= ENGINE_METHOD_PKEY_METHS;
+    else if (strncmp(alg, "PKEY_ASN1", len) == 0)
+        *pflags |= ENGINE_METHOD_PKEY_ASN1_METHS;
+    else
+        return 0;
+    return 1;
+}
+
+int ENGINE_set_default_string(ENGINE *e, const char *def_list)
+{
+    unsigned int flags = 0;
+    if (!CONF_parse_list(def_list, ',', 1, int_def_cb, &flags)) {
+        ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_STRING,
+                  ENGINE_R_INVALID_STRING);
+        ERR_add_error_data(2, "str=", def_list);
+        return 0;
+    }
+    return ENGINE_set_default(e, flags);
+}
+
+int ENGINE_register_complete(ENGINE *e)
+{
+    ENGINE_register_ciphers(e);
+    ENGINE_register_digests(e);
+#ifndef OPENSSL_NO_RSA
+    ENGINE_register_RSA(e);
+#endif
+#ifndef OPENSSL_NO_DSA
+    ENGINE_register_DSA(e);
+#endif
+#ifndef OPENSSL_NO_DH
+    ENGINE_register_DH(e);
+#endif
+#ifndef OPENSSL_NO_EC
+    ENGINE_register_EC(e);
+#endif
+    ENGINE_register_RAND(e);
+    ENGINE_register_pkey_meths(e);
+    return 1;
+}
+
+int ENGINE_register_all_complete(void)
+{
+    ENGINE *e;
+
+    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+        if (!(e->flags & ENGINE_FLAGS_NO_REGISTER_ALL))
+            ENGINE_register_complete(e);
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_init.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_init.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_init.c	(revision 331)
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2001-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 "eng_int.h"
+
+/*
+ * Initialise a engine type for use (or up its functional reference count if
+ * it's already in use). This version is only used internally.
+ */
+int engine_unlocked_init(ENGINE *e)
+{
+    int to_return = 1;
+
+    if ((e->funct_ref == 0) && e->init)
+        /*
+         * This is the first functional reference and the engine requires
+         * initialisation so we do it now.
+         */
+        to_return = e->init(e);
+    if (to_return) {
+        /*
+         * OK, we return a functional reference which is also a structural
+         * reference.
+         */
+        e->struct_ref++;
+        e->funct_ref++;
+        engine_ref_debug(e, 0, 1);
+        engine_ref_debug(e, 1, 1);
+    }
+    return to_return;
+}
+
+/*
+ * Free a functional reference to a engine type. This version is only used
+ * internally.
+ */
+int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers)
+{
+    int to_return = 1;
+
+    /*
+     * Reduce the functional reference count here so if it's the terminating
+     * case, we can release the lock safely and call the finish() handler
+     * without risk of a race. We get a race if we leave the count until
+     * after and something else is calling "finish" at the same time -
+     * there's a chance that both threads will together take the count from 2
+     * to 0 without either calling finish().
+     */
+    e->funct_ref--;
+    engine_ref_debug(e, 1, -1);
+    if ((e->funct_ref == 0) && e->finish) {
+        if (unlock_for_handlers)
+            CRYPTO_THREAD_unlock(global_engine_lock);
+        to_return = e->finish(e);
+        if (unlock_for_handlers)
+            CRYPTO_THREAD_write_lock(global_engine_lock);
+        if (!to_return)
+            return 0;
+    }
+    REF_ASSERT_ISNT(e->funct_ref < 0);
+    /* Release the structural reference too */
+    if (!engine_free_util(e, 0)) {
+        ENGINEerr(ENGINE_F_ENGINE_UNLOCKED_FINISH, ENGINE_R_FINISH_FAILED);
+        return 0;
+    }
+    return to_return;
+}
+
+/* The API (locked) version of "init" */
+int ENGINE_init(ENGINE *e)
+{
+    int ret;
+    if (e == NULL) {
+        ENGINEerr(ENGINE_F_ENGINE_INIT, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) {
+        ENGINEerr(ENGINE_F_ENGINE_INIT, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    CRYPTO_THREAD_write_lock(global_engine_lock);
+    ret = engine_unlocked_init(e);
+    CRYPTO_THREAD_unlock(global_engine_lock);
+    return ret;
+}
+
+/* The API (locked) version of "finish" */
+int ENGINE_finish(ENGINE *e)
+{
+    int to_return = 1;
+
+    if (e == NULL)
+        return 1;
+    CRYPTO_THREAD_write_lock(global_engine_lock);
+    to_return = engine_unlocked_finish(e, 1);
+    CRYPTO_THREAD_unlock(global_engine_lock);
+    if (!to_return) {
+        ENGINEerr(ENGINE_F_ENGINE_FINISH, ENGINE_R_FINISH_FAILED);
+        return 0;
+    }
+    return to_return;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_int.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_int.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_int.h	(revision 331)
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2001-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_ENGINE_INT_H
+# define HEADER_ENGINE_INT_H
+
+# include "internal/cryptlib.h"
+# include <internal/engine.h>
+# include <internal/thread_once.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+extern CRYPTO_RWLOCK *global_engine_lock;
+
+/*
+ * If we compile with this symbol defined, then both reference counts in the
+ * ENGINE structure will be monitored with a line of output on stderr for
+ * each change. This prints the engine's pointer address (truncated to
+ * unsigned int), "struct" or "funct" to indicate the reference type, the
+ * before and after reference count, and the file:line-number pair. The
+ * "engine_ref_debug" statements must come *after* the change.
+ */
+# ifdef ENGINE_REF_COUNT_DEBUG
+
+#  define engine_ref_debug(e, isfunct, diff) \
+        fprintf(stderr, "engine: %08x %s from %d to %d (%s:%d)\n", \
+                (unsigned int)(e), (isfunct ? "funct" : "struct"), \
+                ((isfunct) ? ((e)->funct_ref - (diff)) : ((e)->struct_ref - (diff))), \
+                ((isfunct) ? (e)->funct_ref : (e)->struct_ref), \
+                (OPENSSL_FILE), (OPENSSL_LINE))
+
+# else
+
+#  define engine_ref_debug(e, isfunct, diff)
+
+# endif
+
+/*
+ * Any code that will need cleanup operations should use these functions to
+ * register callbacks. engine_cleanup_int() will call all registered
+ * callbacks in order. NB: both the "add" functions assume the engine lock to
+ * already be held (in "write" mode).
+ */
+typedef void (ENGINE_CLEANUP_CB) (void);
+typedef struct st_engine_cleanup_item {
+    ENGINE_CLEANUP_CB *cb;
+} ENGINE_CLEANUP_ITEM;
+DEFINE_STACK_OF(ENGINE_CLEANUP_ITEM)
+void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb);
+void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb);
+
+/* We need stacks of ENGINEs for use in eng_table.c */
+DEFINE_STACK_OF(ENGINE)
+
+/*
+ * If this symbol is defined then engine_table_select(), the function that is
+ * used by RSA, DSA (etc) code to select registered ENGINEs, cache defaults
+ * and functional references (etc), will display debugging summaries to
+ * stderr.
+ */
+/* #define ENGINE_TABLE_DEBUG */
+
+/*
+ * This represents an implementation table. Dependent code should instantiate
+ * it as a (ENGINE_TABLE *) pointer value set initially to NULL.
+ */
+typedef struct st_engine_table ENGINE_TABLE;
+int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
+                          ENGINE *e, const int *nids, int num_nids,
+                          int setdefault);
+void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e);
+void engine_table_cleanup(ENGINE_TABLE **table);
+# ifndef ENGINE_TABLE_DEBUG
+ENGINE *engine_table_select(ENGINE_TABLE **table, int nid);
+# else
+ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f,
+                                int l);
+#  define engine_table_select(t,n) engine_table_select_tmp(t,n,OPENSSL_FILE,OPENSSL_LINE)
+# endif
+typedef void (engine_table_doall_cb) (int nid, STACK_OF(ENGINE) *sk,
+                                      ENGINE *def, void *arg);
+void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb,
+                        void *arg);
+
+/*
+ * Internal versions of API functions that have control over locking. These
+ * are used between C files when functionality needs to be shared but the
+ * caller may already be controlling of the engine lock.
+ */
+int engine_unlocked_init(ENGINE *e);
+int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers);
+int engine_free_util(ENGINE *e, int locked);
+
+/*
+ * This function will reset all "set"able values in an ENGINE to NULL. This
+ * won't touch reference counts or ex_data, but is equivalent to calling all
+ * the ENGINE_set_***() functions with a NULL value.
+ */
+void engine_set_all_null(ENGINE *e);
+
+/*
+ * NB: Bitwise OR-able values for the "flags" variable in ENGINE are now
+ * exposed in engine.h.
+ */
+
+/* Free up dynamically allocated public key methods associated with ENGINE */
+
+void engine_pkey_meths_free(ENGINE *e);
+void engine_pkey_asn1_meths_free(ENGINE *e);
+
+/* Once initialisation function */
+extern CRYPTO_ONCE engine_lock_init;
+DECLARE_RUN_ONCE(do_engine_lock_init)
+
+/*
+ * This is a structure for storing implementations of various crypto
+ * algorithms and functions.
+ */
+struct engine_st {
+    const char *id;
+    const char *name;
+    const RSA_METHOD *rsa_meth;
+    const DSA_METHOD *dsa_meth;
+    const DH_METHOD *dh_meth;
+    const EC_KEY_METHOD *ec_meth;
+    const RAND_METHOD *rand_meth;
+    /* Cipher handling is via this callback */
+    ENGINE_CIPHERS_PTR ciphers;
+    /* Digest handling is via this callback */
+    ENGINE_DIGESTS_PTR digests;
+    /* Public key handling via this callback */
+    ENGINE_PKEY_METHS_PTR pkey_meths;
+    /* ASN1 public key handling via this callback */
+    ENGINE_PKEY_ASN1_METHS_PTR pkey_asn1_meths;
+    ENGINE_GEN_INT_FUNC_PTR destroy;
+    ENGINE_GEN_INT_FUNC_PTR init;
+    ENGINE_GEN_INT_FUNC_PTR finish;
+    ENGINE_CTRL_FUNC_PTR ctrl;
+    ENGINE_LOAD_KEY_PTR load_privkey;
+    ENGINE_LOAD_KEY_PTR load_pubkey;
+    ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert;
+    const ENGINE_CMD_DEFN *cmd_defns;
+    int flags;
+    /* reference count on the structure itself */
+    int struct_ref;
+    /*
+     * reference count on usability of the engine type. NB: This controls the
+     * loading and initialisation of any functionality required by this
+     * engine, whereas the previous count is simply to cope with
+     * (de)allocation of this structure. Hence, running_ref <= struct_ref at
+     * all times.
+     */
+    int funct_ref;
+    /* A place to store per-ENGINE data */
+    CRYPTO_EX_DATA ex_data;
+    /* Used to maintain the linked-list of engines. */
+    struct engine_st *prev;
+    struct engine_st *next;
+};
+
+typedef struct st_engine_pile ENGINE_PILE;
+
+DEFINE_LHASH_OF(ENGINE_PILE);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif                          /* HEADER_ENGINE_INT_H */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_lib.c	(revision 331)
@@ -0,0 +1,295 @@
+/*
+ * Copyright 2001-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 "eng_int.h"
+#include <openssl/rand.h>
+
+CRYPTO_RWLOCK *global_engine_lock;
+
+CRYPTO_ONCE engine_lock_init = CRYPTO_ONCE_STATIC_INIT;
+
+/* The "new"/"free" stuff first */
+
+DEFINE_RUN_ONCE(do_engine_lock_init)
+{
+    OPENSSL_init_crypto(0, NULL);
+    global_engine_lock = CRYPTO_THREAD_lock_new();
+    return global_engine_lock != NULL;
+}
+
+ENGINE *ENGINE_new(void)
+{
+    ENGINE *ret;
+
+    if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)
+        || (ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
+        ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    ret->struct_ref = 1;
+    engine_ref_debug(ret, 0, 1);
+    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data)) {
+        OPENSSL_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+/*
+ * Placed here (close proximity to ENGINE_new) so that modifications to the
+ * elements of the ENGINE structure are more likely to be caught and changed
+ * here.
+ */
+void engine_set_all_null(ENGINE *e)
+{
+    e->id = NULL;
+    e->name = NULL;
+    e->rsa_meth = NULL;
+    e->dsa_meth = NULL;
+    e->dh_meth = NULL;
+    e->rand_meth = NULL;
+    e->ciphers = NULL;
+    e->digests = NULL;
+    e->destroy = NULL;
+    e->init = NULL;
+    e->finish = NULL;
+    e->ctrl = NULL;
+    e->load_privkey = NULL;
+    e->load_pubkey = NULL;
+    e->cmd_defns = NULL;
+    e->flags = 0;
+}
+
+int engine_free_util(ENGINE *e, int locked)
+{
+    int i;
+
+    if (e == NULL)
+        return 1;
+    if (locked)
+        CRYPTO_atomic_add(&e->struct_ref, -1, &i, global_engine_lock);
+    else
+        i = --e->struct_ref;
+    engine_ref_debug(e, 0, -1)
+    if (i > 0)
+        return 1;
+    REF_ASSERT_ISNT(i < 0);
+    /* Free up any dynamically allocated public key methods */
+    engine_pkey_meths_free(e);
+    engine_pkey_asn1_meths_free(e);
+    /*
+     * Give the ENGINE a chance to do any structural cleanup corresponding to
+     * allocation it did in its constructor (eg. unload error strings)
+     */
+    if (e->destroy)
+        e->destroy(e);
+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ENGINE, e, &e->ex_data);
+    OPENSSL_free(e);
+    return 1;
+}
+
+int ENGINE_free(ENGINE *e)
+{
+    return engine_free_util(e, 1);
+}
+
+/* Cleanup stuff */
+
+/*
+ * engine_cleanup_int() is coded such that anything that does work that will
+ * need cleanup can register a "cleanup" callback here. That way we don't get
+ * linker bloat by referring to all *possible* cleanups, but any linker bloat
+ * into code "X" will cause X's cleanup function to end up here.
+ */
+static STACK_OF(ENGINE_CLEANUP_ITEM) *cleanup_stack = NULL;
+static int int_cleanup_check(int create)
+{
+    if (cleanup_stack)
+        return 1;
+    if (!create)
+        return 0;
+    cleanup_stack = sk_ENGINE_CLEANUP_ITEM_new_null();
+    return (cleanup_stack ? 1 : 0);
+}
+
+static ENGINE_CLEANUP_ITEM *int_cleanup_item(ENGINE_CLEANUP_CB *cb)
+{
+    ENGINE_CLEANUP_ITEM *item = OPENSSL_malloc(sizeof(*item));
+    if (item == NULL)
+        return NULL;
+    item->cb = cb;
+    return item;
+}
+
+void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb)
+{
+    ENGINE_CLEANUP_ITEM *item;
+    if (!int_cleanup_check(1))
+        return;
+    item = int_cleanup_item(cb);
+    if (item)
+        sk_ENGINE_CLEANUP_ITEM_insert(cleanup_stack, item, 0);
+}
+
+void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb)
+{
+    ENGINE_CLEANUP_ITEM *item;
+    if (!int_cleanup_check(1))
+        return;
+    item = int_cleanup_item(cb);
+    if (item)
+        sk_ENGINE_CLEANUP_ITEM_push(cleanup_stack, item);
+}
+
+/* The API function that performs all cleanup */
+static void engine_cleanup_cb_free(ENGINE_CLEANUP_ITEM *item)
+{
+    (*(item->cb)) ();
+    OPENSSL_free(item);
+}
+
+void engine_cleanup_int(void)
+{
+    if (int_cleanup_check(0)) {
+        sk_ENGINE_CLEANUP_ITEM_pop_free(cleanup_stack,
+                                        engine_cleanup_cb_free);
+        cleanup_stack = NULL;
+    }
+    /*
+     * FIXME: This should be handled (somehow) through RAND, eg. by it
+     * registering a cleanup callback.
+     */
+    RAND_set_rand_method(NULL);
+    CRYPTO_THREAD_lock_free(global_engine_lock);
+}
+
+/* Now the "ex_data" support */
+
+int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg)
+{
+    return (CRYPTO_set_ex_data(&e->ex_data, idx, arg));
+}
+
+void *ENGINE_get_ex_data(const ENGINE *e, int idx)
+{
+    return (CRYPTO_get_ex_data(&e->ex_data, idx));
+}
+
+/*
+ * Functions to get/set an ENGINE's elements - mainly to avoid exposing the
+ * ENGINE structure itself.
+ */
+
+int ENGINE_set_id(ENGINE *e, const char *id)
+{
+    if (id == NULL) {
+        ENGINEerr(ENGINE_F_ENGINE_SET_ID, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    e->id = id;
+    return 1;
+}
+
+int ENGINE_set_name(ENGINE *e, const char *name)
+{
+    if (name == NULL) {
+        ENGINEerr(ENGINE_F_ENGINE_SET_NAME, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    e->name = name;
+    return 1;
+}
+
+int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f)
+{
+    e->destroy = destroy_f;
+    return 1;
+}
+
+int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f)
+{
+    e->init = init_f;
+    return 1;
+}
+
+int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f)
+{
+    e->finish = finish_f;
+    return 1;
+}
+
+int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f)
+{
+    e->ctrl = ctrl_f;
+    return 1;
+}
+
+int ENGINE_set_flags(ENGINE *e, int flags)
+{
+    e->flags = flags;
+    return 1;
+}
+
+int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns)
+{
+    e->cmd_defns = defns;
+    return 1;
+}
+
+const char *ENGINE_get_id(const ENGINE *e)
+{
+    return e->id;
+}
+
+const char *ENGINE_get_name(const ENGINE *e)
+{
+    return e->name;
+}
+
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e)
+{
+    return e->destroy;
+}
+
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e)
+{
+    return e->init;
+}
+
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e)
+{
+    return e->finish;
+}
+
+ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e)
+{
+    return e->ctrl;
+}
+
+int ENGINE_get_flags(const ENGINE *e)
+{
+    return e->flags;
+}
+
+const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e)
+{
+    return e->cmd_defns;
+}
+
+/*
+ * eng_lib.o is pretty much linked into anything that touches ENGINE already,
+ * so put the "static_state" hack here.
+ */
+
+static int internal_static_hack = 0;
+
+void *ENGINE_get_static_state(void)
+{
+    return &internal_static_hack;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_list.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_list.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_list.c	(revision 331)
@@ -0,0 +1,354 @@
+/*
+ * Copyright 2001-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include "eng_int.h"
+
+/*
+ * The linked-list of pointers to engine types. engine_list_head incorporates
+ * an implicit structural reference but engine_list_tail does not - the
+ * latter is a computational niceity and only points to something that is
+ * already pointed to by its predecessor in the list (or engine_list_head
+ * itself). In the same way, the use of the "prev" pointer in each ENGINE is
+ * to save excessive list iteration, it doesn't correspond to an extra
+ * structural reference. Hence, engine_list_head, and each non-null "next"
+ * pointer account for the list itself assuming exactly 1 structural
+ * reference on each list member.
+ */
+static ENGINE *engine_list_head = NULL;
+static ENGINE *engine_list_tail = NULL;
+
+/*
+ * This cleanup function is only needed internally. If it should be called,
+ * we register it with the "engine_cleanup_int()" stack to be called during
+ * cleanup.
+ */
+
+static void engine_list_cleanup(void)
+{
+    ENGINE *iterator = engine_list_head;
+
+    while (iterator != NULL) {
+        ENGINE_remove(iterator);
+        iterator = engine_list_head;
+    }
+    return;
+}
+
+/*
+ * These static functions starting with a lower case "engine_" always take
+ * place when global_engine_lock has been locked up.
+ */
+static int engine_list_add(ENGINE *e)
+{
+    int conflict = 0;
+    ENGINE *iterator = NULL;
+
+    if (e == NULL) {
+        ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    iterator = engine_list_head;
+    while (iterator && !conflict) {
+        conflict = (strcmp(iterator->id, e->id) == 0);
+        iterator = iterator->next;
+    }
+    if (conflict) {
+        ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ENGINE_R_CONFLICTING_ENGINE_ID);
+        return 0;
+    }
+    if (engine_list_head == NULL) {
+        /* We are adding to an empty list. */
+        if (engine_list_tail) {
+            ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ENGINE_R_INTERNAL_LIST_ERROR);
+            return 0;
+        }
+        engine_list_head = e;
+        e->prev = NULL;
+        /*
+         * The first time the list allocates, we should register the cleanup.
+         */
+        engine_cleanup_add_last(engine_list_cleanup);
+    } else {
+        /* We are adding to the tail of an existing list. */
+        if ((engine_list_tail == NULL) || (engine_list_tail->next != NULL)) {
+            ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ENGINE_R_INTERNAL_LIST_ERROR);
+            return 0;
+        }
+        engine_list_tail->next = e;
+        e->prev = engine_list_tail;
+    }
+    /*
+     * Having the engine in the list assumes a structural reference.
+     */
+    e->struct_ref++;
+    engine_ref_debug(e, 0, 1);
+    /* However it came to be, e is the last item in the list. */
+    engine_list_tail = e;
+    e->next = NULL;
+    return 1;
+}
+
+static int engine_list_remove(ENGINE *e)
+{
+    ENGINE *iterator;
+
+    if (e == NULL) {
+        ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    /* We need to check that e is in our linked list! */
+    iterator = engine_list_head;
+    while (iterator && (iterator != e))
+        iterator = iterator->next;
+    if (iterator == NULL) {
+        ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE,
+                  ENGINE_R_ENGINE_IS_NOT_IN_LIST);
+        return 0;
+    }
+    /* un-link e from the chain. */
+    if (e->next)
+        e->next->prev = e->prev;
+    if (e->prev)
+        e->prev->next = e->next;
+    /* Correct our head/tail if necessary. */
+    if (engine_list_head == e)
+        engine_list_head = e->next;
+    if (engine_list_tail == e)
+        engine_list_tail = e->prev;
+    engine_free_util(e, 0);
+    return 1;
+}
+
+/* Get the first/last "ENGINE" type available. */
+ENGINE *ENGINE_get_first(void)
+{
+    ENGINE *ret;
+
+    if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) {
+        ENGINEerr(ENGINE_F_ENGINE_GET_FIRST, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    CRYPTO_THREAD_write_lock(global_engine_lock);
+    ret = engine_list_head;
+    if (ret) {
+        ret->struct_ref++;
+        engine_ref_debug(ret, 0, 1);
+    }
+    CRYPTO_THREAD_unlock(global_engine_lock);
+    return ret;
+}
+
+ENGINE *ENGINE_get_last(void)
+{
+    ENGINE *ret;
+
+    if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) {
+        ENGINEerr(ENGINE_F_ENGINE_GET_LAST, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    CRYPTO_THREAD_write_lock(global_engine_lock);
+    ret = engine_list_tail;
+    if (ret) {
+        ret->struct_ref++;
+        engine_ref_debug(ret, 0, 1);
+    }
+    CRYPTO_THREAD_unlock(global_engine_lock);
+    return ret;
+}
+
+/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
+ENGINE *ENGINE_get_next(ENGINE *e)
+{
+    ENGINE *ret = NULL;
+    if (e == NULL) {
+        ENGINEerr(ENGINE_F_ENGINE_GET_NEXT, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    CRYPTO_THREAD_write_lock(global_engine_lock);
+    ret = e->next;
+    if (ret) {
+        /* Return a valid structural reference to the next ENGINE */
+        ret->struct_ref++;
+        engine_ref_debug(ret, 0, 1);
+    }
+    CRYPTO_THREAD_unlock(global_engine_lock);
+    /* Release the structural reference to the previous ENGINE */
+    ENGINE_free(e);
+    return ret;
+}
+
+ENGINE *ENGINE_get_prev(ENGINE *e)
+{
+    ENGINE *ret = NULL;
+    if (e == NULL) {
+        ENGINEerr(ENGINE_F_ENGINE_GET_PREV, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    CRYPTO_THREAD_write_lock(global_engine_lock);
+    ret = e->prev;
+    if (ret) {
+        /* Return a valid structural reference to the next ENGINE */
+        ret->struct_ref++;
+        engine_ref_debug(ret, 0, 1);
+    }
+    CRYPTO_THREAD_unlock(global_engine_lock);
+    /* Release the structural reference to the previous ENGINE */
+    ENGINE_free(e);
+    return ret;
+}
+
+/* Add another "ENGINE" type into the list. */
+int ENGINE_add(ENGINE *e)
+{
+    int to_return = 1;
+    if (e == NULL) {
+        ENGINEerr(ENGINE_F_ENGINE_ADD, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    if ((e->id == NULL) || (e->name == NULL)) {
+        ENGINEerr(ENGINE_F_ENGINE_ADD, ENGINE_R_ID_OR_NAME_MISSING);
+        return 0;
+    }
+    CRYPTO_THREAD_write_lock(global_engine_lock);
+    if (!engine_list_add(e)) {
+        ENGINEerr(ENGINE_F_ENGINE_ADD, ENGINE_R_INTERNAL_LIST_ERROR);
+        to_return = 0;
+    }
+    CRYPTO_THREAD_unlock(global_engine_lock);
+    return to_return;
+}
+
+/* Remove an existing "ENGINE" type from the array. */
+int ENGINE_remove(ENGINE *e)
+{
+    int to_return = 1;
+    if (e == NULL) {
+        ENGINEerr(ENGINE_F_ENGINE_REMOVE, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    CRYPTO_THREAD_write_lock(global_engine_lock);
+    if (!engine_list_remove(e)) {
+        ENGINEerr(ENGINE_F_ENGINE_REMOVE, ENGINE_R_INTERNAL_LIST_ERROR);
+        to_return = 0;
+    }
+    CRYPTO_THREAD_unlock(global_engine_lock);
+    return to_return;
+}
+
+static void engine_cpy(ENGINE *dest, const ENGINE *src)
+{
+    dest->id = src->id;
+    dest->name = src->name;
+#ifndef OPENSSL_NO_RSA
+    dest->rsa_meth = src->rsa_meth;
+#endif
+#ifndef OPENSSL_NO_DSA
+    dest->dsa_meth = src->dsa_meth;
+#endif
+#ifndef OPENSSL_NO_DH
+    dest->dh_meth = src->dh_meth;
+#endif
+#ifndef OPENSSL_NO_EC
+    dest->ec_meth = src->ec_meth;
+#endif
+    dest->rand_meth = src->rand_meth;
+    dest->ciphers = src->ciphers;
+    dest->digests = src->digests;
+    dest->pkey_meths = src->pkey_meths;
+    dest->destroy = src->destroy;
+    dest->init = src->init;
+    dest->finish = src->finish;
+    dest->ctrl = src->ctrl;
+    dest->load_privkey = src->load_privkey;
+    dest->load_pubkey = src->load_pubkey;
+    dest->cmd_defns = src->cmd_defns;
+    dest->flags = src->flags;
+}
+
+ENGINE *ENGINE_by_id(const char *id)
+{
+    ENGINE *iterator;
+    char *load_dir = NULL;
+    if (id == NULL) {
+        ENGINEerr(ENGINE_F_ENGINE_BY_ID, ERR_R_PASSED_NULL_PARAMETER);
+        return NULL;
+    }
+    if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) {
+        ENGINEerr(ENGINE_F_ENGINE_BY_ID, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    CRYPTO_THREAD_write_lock(global_engine_lock);
+    iterator = engine_list_head;
+    while (iterator && (strcmp(id, iterator->id) != 0))
+        iterator = iterator->next;
+    if (iterator != NULL) {
+        /*
+         * We need to return a structural reference. If this is an ENGINE
+         * type that returns copies, make a duplicate - otherwise increment
+         * the existing ENGINE's reference count.
+         */
+        if (iterator->flags & ENGINE_FLAGS_BY_ID_COPY) {
+            ENGINE *cp = ENGINE_new();
+            if (cp == NULL)
+                iterator = NULL;
+            else {
+                engine_cpy(cp, iterator);
+                iterator = cp;
+            }
+        } else {
+            iterator->struct_ref++;
+            engine_ref_debug(iterator, 0, 1);
+        }
+    }
+    CRYPTO_THREAD_unlock(global_engine_lock);
+    if (iterator != NULL)
+        return iterator;
+    /*
+     * Prevent infinite recursion if we're looking for the dynamic engine.
+     */
+    if (strcmp(id, "dynamic")) {
+        if ((load_dir = getenv("OPENSSL_ENGINES")) == 0)
+            load_dir = ""ENGINESDIR"";
+        iterator = ENGINE_by_id("dynamic");
+        if (!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) ||
+            !ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) ||
+            !ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
+                                    load_dir, 0) ||
+            !ENGINE_ctrl_cmd_string(iterator, "LIST_ADD", "1", 0) ||
+            !ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
+            goto notfound;
+        return iterator;
+    }
+ notfound:
+    ENGINE_free(iterator);
+    ENGINEerr(ENGINE_F_ENGINE_BY_ID, ENGINE_R_NO_SUCH_ENGINE);
+    ERR_add_error_data(2, "id=", id);
+    return NULL;
+    /* EEK! Experimental code ends */
+}
+
+int ENGINE_up_ref(ENGINE *e)
+{
+    int i;
+    if (e == NULL) {
+        ENGINEerr(ENGINE_F_ENGINE_UP_REF, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    CRYPTO_atomic_add(&e->struct_ref, 1, &i, global_engine_lock);
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_openssl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_openssl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_openssl.c	(revision 331)
@@ -0,0 +1,652 @@
+/*
+ * Copyright 2001-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include <stdio.h>
+#include <openssl/crypto.h>
+#include "internal/cryptlib.h"
+#include <internal/engine.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/dh.h>
+
+#include <openssl/hmac.h>
+#include <openssl/x509v3.h>
+
+/*
+ * This testing gunk is implemented (and explained) lower down. It also
+ * assumes the application explicitly calls "ENGINE_load_openssl()" because
+ * this is no longer automatic in ENGINE_load_builtin_engines().
+ */
+#define TEST_ENG_OPENSSL_RC4
+#ifndef OPENSSL_NO_STDIO
+#define TEST_ENG_OPENSSL_PKEY
+#endif
+/* #define TEST_ENG_OPENSSL_HMAC */
+/* #define TEST_ENG_OPENSSL_HMAC_INIT */
+/* #define TEST_ENG_OPENSSL_RC4_OTHERS */
+#define TEST_ENG_OPENSSL_RC4_P_INIT
+/* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */
+#define TEST_ENG_OPENSSL_SHA
+/* #define TEST_ENG_OPENSSL_SHA_OTHERS */
+/* #define TEST_ENG_OPENSSL_SHA_P_INIT */
+/* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */
+/* #define TEST_ENG_OPENSSL_SHA_P_FINAL */
+
+/* Now check what of those algorithms are actually enabled */
+#ifdef OPENSSL_NO_RC4
+# undef TEST_ENG_OPENSSL_RC4
+# undef TEST_ENG_OPENSSL_RC4_OTHERS
+# undef TEST_ENG_OPENSSL_RC4_P_INIT
+# undef TEST_ENG_OPENSSL_RC4_P_CIPHER
+#endif
+
+static int openssl_destroy(ENGINE *e);
+
+#ifdef TEST_ENG_OPENSSL_RC4
+static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
+                           const int **nids, int nid);
+#endif
+#ifdef TEST_ENG_OPENSSL_SHA
+static int openssl_digests(ENGINE *e, const EVP_MD **digest,
+                           const int **nids, int nid);
+#endif
+
+#ifdef TEST_ENG_OPENSSL_PKEY
+static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
+                                      UI_METHOD *ui_method,
+                                      void *callback_data);
+#endif
+
+#ifdef TEST_ENG_OPENSSL_HMAC
+static int ossl_register_hmac_meth(void);
+static int ossl_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
+                           const int **nids, int nid);
+#endif
+
+/* The constants used when creating the ENGINE */
+static const char *engine_openssl_id = "openssl";
+static const char *engine_openssl_name = "Software engine support";
+
+/*
+ * This internal function is used by ENGINE_openssl() and possibly by the
+ * "dynamic" ENGINE support too
+ */
+static int bind_helper(ENGINE *e)
+{
+    if (!ENGINE_set_id(e, engine_openssl_id)
+        || !ENGINE_set_name(e, engine_openssl_name)
+        || !ENGINE_set_destroy_function(e, openssl_destroy)
+#ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS
+# ifndef OPENSSL_NO_RSA
+        || !ENGINE_set_RSA(e, RSA_get_default_method())
+# endif
+# ifndef OPENSSL_NO_DSA
+        || !ENGINE_set_DSA(e, DSA_get_default_method())
+# endif
+# ifndef OPENSSL_NO_EC
+        || !ENGINE_set_EC(e, EC_KEY_OpenSSL())
+# endif
+# ifndef OPENSSL_NO_DH
+        || !ENGINE_set_DH(e, DH_get_default_method())
+# endif
+        || !ENGINE_set_RAND(e, RAND_OpenSSL())
+# ifdef TEST_ENG_OPENSSL_RC4
+        || !ENGINE_set_ciphers(e, openssl_ciphers)
+# endif
+# ifdef TEST_ENG_OPENSSL_SHA
+        || !ENGINE_set_digests(e, openssl_digests)
+# endif
+#endif
+#ifdef TEST_ENG_OPENSSL_PKEY
+        || !ENGINE_set_load_privkey_function(e, openssl_load_privkey)
+#endif
+#ifdef TEST_ENG_OPENSSL_HMAC
+        || !ossl_register_hmac_meth()
+        || !ENGINE_set_pkey_meths(e, ossl_pkey_meths)
+#endif
+        )
+        return 0;
+    /*
+     * If we add errors to this ENGINE, ensure the error handling is setup
+     * here
+     */
+    /* openssl_load_error_strings(); */
+    return 1;
+}
+
+static ENGINE *engine_openssl(void)
+{
+    ENGINE *ret = ENGINE_new();
+    if (ret == NULL)
+        return NULL;
+    if (!bind_helper(ret)) {
+        ENGINE_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+void engine_load_openssl_int(void)
+{
+    ENGINE *toadd = engine_openssl();
+    if (!toadd)
+        return;
+    ENGINE_add(toadd);
+    /*
+     * If the "add" worked, it gets a structural reference. So either way, we
+     * release our just-created reference.
+     */
+    ENGINE_free(toadd);
+    ERR_clear_error();
+}
+
+/*
+ * This stuff is needed if this ENGINE is being compiled into a
+ * self-contained shared-library.
+ */
+#ifdef ENGINE_DYNAMIC_SUPPORT
+static int bind_fn(ENGINE *e, const char *id)
+{
+    if (id && (strcmp(id, engine_openssl_id) != 0))
+        return 0;
+    if (!bind_helper(e))
+        return 0;
+    return 1;
+}
+
+IMPLEMENT_DYNAMIC_CHECK_FN()
+    IMPLEMENT_DYNAMIC_BIND_FN(bind_fn)
+#endif                          /* ENGINE_DYNAMIC_SUPPORT */
+#ifdef TEST_ENG_OPENSSL_RC4
+/*-
+ * This section of code compiles an "alternative implementation" of two modes of
+ * RC4 into this ENGINE. The result is that EVP_CIPHER operation for "rc4"
+ * should under normal circumstances go via this support rather than the default
+ * EVP support. There are other symbols to tweak the testing;
+ *    TEST_ENC_OPENSSL_RC4_OTHERS - print a one line message to stderr each time
+ *        we're asked for a cipher we don't support (should not happen).
+ *    TEST_ENG_OPENSSL_RC4_P_INIT - print a one line message to stderr each time
+ *        the "init_key" handler is called.
+ *    TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler.
+ */
+# include <openssl/rc4.h>
+# define TEST_RC4_KEY_SIZE               16
+typedef struct {
+    unsigned char key[TEST_RC4_KEY_SIZE];
+    RC4_KEY ks;
+} TEST_RC4_KEY;
+# define test(ctx) ((TEST_RC4_KEY *)EVP_CIPHER_CTX_get_cipher_data(ctx))
+static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                             const unsigned char *iv, int enc)
+{
+# ifdef TEST_ENG_OPENSSL_RC4_P_INIT
+    fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n");
+# endif
+    memcpy(&test(ctx)->key[0], key, EVP_CIPHER_CTX_key_length(ctx));
+    RC4_set_key(&test(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
+                test(ctx)->key);
+    return 1;
+}
+
+static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                           const unsigned char *in, size_t inl)
+{
+# ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER
+    fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n");
+# endif
+    RC4(&test(ctx)->ks, inl, in, out);
+    return 1;
+}
+
+static EVP_CIPHER *r4_cipher = NULL;
+static const EVP_CIPHER *test_r4_cipher(void)
+{
+    if (r4_cipher == NULL) {
+        EVP_CIPHER *cipher;
+
+        if ((cipher = EVP_CIPHER_meth_new(NID_rc4, 1, TEST_RC4_KEY_SIZE)) == NULL
+            || !EVP_CIPHER_meth_set_iv_length(cipher, 0)
+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_VARIABLE_LENGTH)
+            || !EVP_CIPHER_meth_set_init(cipher, test_rc4_init_key)
+            || !EVP_CIPHER_meth_set_do_cipher(cipher, test_rc4_cipher)
+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(TEST_RC4_KEY))) {
+            EVP_CIPHER_meth_free(cipher);
+            cipher = NULL;
+        }
+        r4_cipher = cipher;
+    }
+    return r4_cipher;
+}
+static void test_r4_cipher_destroy(void)
+{
+    EVP_CIPHER_meth_free(r4_cipher);
+    r4_cipher = NULL;
+}
+
+static EVP_CIPHER *r4_40_cipher = NULL;
+static const EVP_CIPHER *test_r4_40_cipher(void)
+{
+    if (r4_40_cipher == NULL) {
+        EVP_CIPHER *cipher;
+
+        if ((cipher = EVP_CIPHER_meth_new(NID_rc4, 1, 5 /* 40 bits */)) == NULL
+            || !EVP_CIPHER_meth_set_iv_length(cipher, 0)
+            || !EVP_CIPHER_meth_set_flags(cipher, EVP_CIPH_VARIABLE_LENGTH)
+            || !EVP_CIPHER_meth_set_init(cipher, test_rc4_init_key)
+            || !EVP_CIPHER_meth_set_do_cipher(cipher, test_rc4_cipher)
+            || !EVP_CIPHER_meth_set_impl_ctx_size(cipher, sizeof(TEST_RC4_KEY))) {
+            EVP_CIPHER_meth_free(cipher);
+            cipher = NULL;
+        }
+        r4_40_cipher = cipher;
+    }
+    return r4_40_cipher;
+}
+static void test_r4_40_cipher_destroy(void)
+{
+    EVP_CIPHER_meth_free(r4_40_cipher);
+    r4_40_cipher = NULL;
+}
+static int test_cipher_nids(const int **nids)
+{
+    static int cipher_nids[4] = { 0, 0, 0, 0 };
+    static int pos = 0;
+    static int init = 0;
+
+    if (!init) {
+        const EVP_CIPHER *cipher;
+        if ((cipher = test_r4_cipher()) != NULL)
+            cipher_nids[pos++] = EVP_CIPHER_nid(cipher);
+        if ((cipher = test_r4_40_cipher()) != NULL)
+            cipher_nids[pos++] = EVP_CIPHER_nid(cipher);
+        cipher_nids[pos] = 0;
+        init = 1;
+    }
+    *nids = cipher_nids;
+    return pos;
+}
+
+static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
+                           const int **nids, int nid)
+{
+    if (!cipher) {
+        /* We are returning a list of supported nids */
+        return test_cipher_nids(nids);
+    }
+    /* We are being asked for a specific cipher */
+    if (nid == NID_rc4)
+        *cipher = test_r4_cipher();
+    else if (nid == NID_rc4_40)
+        *cipher = test_r4_40_cipher();
+    else {
+# ifdef TEST_ENG_OPENSSL_RC4_OTHERS
+        fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) returning NULL for "
+                "nid %d\n", nid);
+# endif
+        *cipher = NULL;
+        return 0;
+    }
+    return 1;
+}
+#endif
+
+#ifdef TEST_ENG_OPENSSL_SHA
+/* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */
+# include <openssl/sha.h>
+
+static int test_sha1_init(EVP_MD_CTX *ctx)
+{
+# ifdef TEST_ENG_OPENSSL_SHA_P_INIT
+    fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n");
+# endif
+    return SHA1_Init(EVP_MD_CTX_md_data(ctx));
+}
+
+static int test_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+# ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE
+    fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n");
+# endif
+    return SHA1_Update(EVP_MD_CTX_md_data(ctx), data, count);
+}
+
+static int test_sha1_final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+# ifdef TEST_ENG_OPENSSL_SHA_P_FINAL
+    fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n");
+# endif
+    return SHA1_Final(md, EVP_MD_CTX_md_data(ctx));
+}
+
+static EVP_MD *sha1_md = NULL;
+static const EVP_MD *test_sha_md(void)
+{
+    if (sha1_md == NULL) {
+        EVP_MD *md;
+
+        if ((md = EVP_MD_meth_new(NID_sha1, NID_sha1WithRSAEncryption)) == NULL
+            || !EVP_MD_meth_set_result_size(md, SHA_DIGEST_LENGTH)
+            || !EVP_MD_meth_set_input_blocksize(md, SHA_CBLOCK)
+            || !EVP_MD_meth_set_app_datasize(md,
+                                             sizeof(EVP_MD *) + sizeof(SHA_CTX))
+            || !EVP_MD_meth_set_flags(md, 0)
+            || !EVP_MD_meth_set_init(md, test_sha1_init)
+            || !EVP_MD_meth_set_update(md, test_sha1_update)
+            || !EVP_MD_meth_set_final(md, test_sha1_final)) {
+            EVP_MD_meth_free(md);
+            md = NULL;
+        }
+        sha1_md = md;
+    }
+    return sha1_md;
+}
+static void test_sha_md_destroy(void)
+{
+    EVP_MD_meth_free(sha1_md);
+    sha1_md = NULL;
+}
+static int test_digest_nids(const int **nids)
+{
+    static int digest_nids[2] = { 0, 0 };
+    static int pos = 0;
+    static int init = 0;
+
+    if (!init) {
+        const EVP_MD *md;
+        if ((md = test_sha_md()) != NULL)
+            digest_nids[pos++] = EVP_MD_type(md);
+        digest_nids[pos] = 0;
+        init = 1;
+    }
+    *nids = digest_nids;
+    return pos;
+}
+
+static int openssl_digests(ENGINE *e, const EVP_MD **digest,
+                           const int **nids, int nid)
+{
+    if (!digest) {
+        /* We are returning a list of supported nids */
+        return test_digest_nids(nids);
+    }
+    /* We are being asked for a specific digest */
+    if (nid == NID_sha1)
+        *digest = test_sha_md();
+    else {
+# ifdef TEST_ENG_OPENSSL_SHA_OTHERS
+        fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) returning NULL for "
+                "nid %d\n", nid);
+# endif
+        *digest = NULL;
+        return 0;
+    }
+    return 1;
+}
+#endif
+
+#ifdef TEST_ENG_OPENSSL_PKEY
+static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id,
+                                      UI_METHOD *ui_method,
+                                      void *callback_data)
+{
+    BIO *in;
+    EVP_PKEY *key;
+    fprintf(stderr, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n",
+            key_id);
+    in = BIO_new_file(key_id, "r");
+    if (!in)
+        return NULL;
+    key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL);
+    BIO_free(in);
+    return key;
+}
+#endif
+
+#ifdef TEST_ENG_OPENSSL_HMAC
+
+/*
+ * Experimental HMAC redirection implementation: mainly copied from
+ * hm_pmeth.c
+ */
+
+/* HMAC pkey context structure */
+
+typedef struct {
+    const EVP_MD *md;           /* MD for HMAC use */
+    ASN1_OCTET_STRING ktmp;     /* Temp storage for key */
+    HMAC_CTX *ctx;
+} OSSL_HMAC_PKEY_CTX;
+
+static int ossl_hmac_init(EVP_PKEY_CTX *ctx)
+{
+    OSSL_HMAC_PKEY_CTX *hctx;
+
+    hctx = OPENSSL_zalloc(sizeof(*hctx));
+    if (hctx == NULL)
+        return 0;
+    hctx->ktmp.type = V_ASN1_OCTET_STRING;
+    hctx->ctx = HMAC_CTX_new();
+    if (hctx->ctx == NULL) {
+        OPENSSL_free(hctx);
+        return 0;
+    }
+    EVP_PKEY_CTX_set_data(ctx, hctx);
+    EVP_PKEY_CTX_set0_keygen_info(ctx, NULL, 0);
+# ifdef TEST_ENG_OPENSSL_HMAC_INIT
+    fprintf(stderr, "(TEST_ENG_OPENSSL_HMAC) ossl_hmac_init() called\n");
+# endif
+    return 1;
+}
+
+static void ossl_hmac_cleanup(EVP_PKEY_CTX *ctx);
+
+static int ossl_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+{
+    OSSL_HMAC_PKEY_CTX *sctx, *dctx;
+
+    /* allocate memory for dst->data and a new HMAC_CTX in dst->data->ctx */
+    if (!ossl_hmac_init(dst))
+        return 0;
+    sctx = EVP_PKEY_CTX_get_data(src);
+    dctx = EVP_PKEY_CTX_get_data(dst);
+    dctx->md = sctx->md;
+    if (!HMAC_CTX_copy(dctx->ctx, sctx->ctx))
+        goto err;
+    if (sctx->ktmp.data) {
+        if (!ASN1_OCTET_STRING_set(&dctx->ktmp,
+                                   sctx->ktmp.data, sctx->ktmp.length))
+            goto err;
+    }
+    return 1;
+err:
+    /* release HMAC_CTX in dst->data->ctx and memory allocated for dst->data */
+    ossl_hmac_cleanup(dst);
+    return 0;
+}
+
+static void ossl_hmac_cleanup(EVP_PKEY_CTX *ctx)
+{
+    OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
+
+    if (hctx) {
+        HMAC_CTX_free(hctx->ctx);
+        OPENSSL_clear_free(hctx->ktmp.data, hctx->ktmp.length);
+        OPENSSL_free(hctx);
+        EVP_PKEY_CTX_set_data(ctx, NULL);
+    }
+}
+
+static int ossl_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+    ASN1_OCTET_STRING *hkey = NULL;
+    OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
+    if (!hctx->ktmp.data)
+        return 0;
+    hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp);
+    if (!hkey)
+        return 0;
+    EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey);
+
+    return 1;
+}
+
+static int ossl_int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+    OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(EVP_MD_CTX_pkey_ctx(ctx));
+    if (!HMAC_Update(hctx->ctx, data, count))
+        return 0;
+    return 1;
+}
+
+static int ossl_hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
+{
+    EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
+    EVP_MD_CTX_set_update_fn(mctx, ossl_int_update);
+    return 1;
+}
+
+static int ossl_hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
+                             size_t *siglen, EVP_MD_CTX *mctx)
+{
+    unsigned int hlen;
+    OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
+    int l = EVP_MD_CTX_size(mctx);
+
+    if (l < 0)
+        return 0;
+    *siglen = l;
+    if (!sig)
+        return 1;
+
+    if (!HMAC_Final(hctx->ctx, sig, &hlen))
+        return 0;
+    *siglen = (size_t)hlen;
+    return 1;
+}
+
+static int ossl_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+    OSSL_HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
+    EVP_PKEY *pk;
+    ASN1_OCTET_STRING *key;
+    switch (type) {
+
+    case EVP_PKEY_CTRL_SET_MAC_KEY:
+        if ((!p2 && p1 > 0) || (p1 < -1))
+            return 0;
+        if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1))
+            return 0;
+        break;
+
+    case EVP_PKEY_CTRL_MD:
+        hctx->md = p2;
+        break;
+
+    case EVP_PKEY_CTRL_DIGESTINIT:
+        pk = EVP_PKEY_CTX_get0_pkey(ctx);
+        key = EVP_PKEY_get0(pk);
+        if (!HMAC_Init_ex(hctx->ctx, key->data, key->length, hctx->md, NULL))
+            return 0;
+        break;
+
+    default:
+        return -2;
+
+    }
+    return 1;
+}
+
+static int ossl_hmac_ctrl_str(EVP_PKEY_CTX *ctx,
+                              const char *type, const char *value)
+{
+    if (!value) {
+        return 0;
+    }
+    if (strcmp(type, "key") == 0) {
+        void *p = (void *)value;
+        return ossl_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, -1, p);
+    }
+    if (strcmp(type, "hexkey") == 0) {
+        unsigned char *key;
+        int r;
+        long keylen;
+        key = OPENSSL_hexstr2buf(value, &keylen);
+        if (!key)
+            return 0;
+        r = ossl_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key);
+        OPENSSL_free(key);
+        return r;
+    }
+    return -2;
+}
+
+static EVP_PKEY_METHOD *ossl_hmac_meth;
+
+static int ossl_register_hmac_meth(void)
+{
+    EVP_PKEY_METHOD *meth;
+    meth = EVP_PKEY_meth_new(EVP_PKEY_HMAC, 0);
+    if (meth == NULL)
+        return 0;
+    EVP_PKEY_meth_set_init(meth, ossl_hmac_init);
+    EVP_PKEY_meth_set_copy(meth, ossl_hmac_copy);
+    EVP_PKEY_meth_set_cleanup(meth, ossl_hmac_cleanup);
+
+    EVP_PKEY_meth_set_keygen(meth, 0, ossl_hmac_keygen);
+
+    EVP_PKEY_meth_set_signctx(meth, ossl_hmac_signctx_init,
+                              ossl_hmac_signctx);
+
+    EVP_PKEY_meth_set_ctrl(meth, ossl_hmac_ctrl, ossl_hmac_ctrl_str);
+    ossl_hmac_meth = meth;
+    return 1;
+}
+
+static int ossl_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
+                           const int **nids, int nid)
+{
+    static int ossl_pkey_nids[] = {
+        EVP_PKEY_HMAC,
+        0
+    };
+    if (!pmeth) {
+        *nids = ossl_pkey_nids;
+        return 1;
+    }
+
+    if (nid == EVP_PKEY_HMAC) {
+        *pmeth = ossl_hmac_meth;
+        return 1;
+    }
+
+    *pmeth = NULL;
+    return 0;
+}
+
+#endif
+
+int openssl_destroy(ENGINE *e)
+{
+    test_sha_md_destroy();
+#ifdef TEST_ENG_OPENSSL_RC4
+    test_r4_cipher_destroy();
+    test_r4_40_cipher_destroy();
+#endif
+    return 1;
+}
+
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_pkey.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_pkey.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_pkey.c	(revision 331)
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2001-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 "eng_int.h"
+
+/* Basic get/set stuff */
+
+int ENGINE_set_load_privkey_function(ENGINE *e,
+                                     ENGINE_LOAD_KEY_PTR loadpriv_f)
+{
+    e->load_privkey = loadpriv_f;
+    return 1;
+}
+
+int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f)
+{
+    e->load_pubkey = loadpub_f;
+    return 1;
+}
+
+int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
+                                             ENGINE_SSL_CLIENT_CERT_PTR
+                                             loadssl_f)
+{
+    e->load_ssl_client_cert = loadssl_f;
+    return 1;
+}
+
+ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e)
+{
+    return e->load_privkey;
+}
+
+ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e)
+{
+    return e->load_pubkey;
+}
+
+ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE
+                                                               *e)
+{
+    return e->load_ssl_client_cert;
+}
+
+/* API functions to load public/private keys */
+
+EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
+                                  UI_METHOD *ui_method, void *callback_data)
+{
+    EVP_PKEY *pkey;
+
+    if (e == NULL) {
+        ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
+                  ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    CRYPTO_THREAD_write_lock(global_engine_lock);
+    if (e->funct_ref == 0) {
+        CRYPTO_THREAD_unlock(global_engine_lock);
+        ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, ENGINE_R_NOT_INITIALISED);
+        return 0;
+    }
+    CRYPTO_THREAD_unlock(global_engine_lock);
+    if (!e->load_privkey) {
+        ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
+                  ENGINE_R_NO_LOAD_FUNCTION);
+        return 0;
+    }
+    pkey = e->load_privkey(e, key_id, ui_method, callback_data);
+    if (!pkey) {
+        ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY,
+                  ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
+        return 0;
+    }
+    return pkey;
+}
+
+EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
+                                 UI_METHOD *ui_method, void *callback_data)
+{
+    EVP_PKEY *pkey;
+
+    if (e == NULL) {
+        ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
+                  ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    CRYPTO_THREAD_write_lock(global_engine_lock);
+    if (e->funct_ref == 0) {
+        CRYPTO_THREAD_unlock(global_engine_lock);
+        ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, ENGINE_R_NOT_INITIALISED);
+        return 0;
+    }
+    CRYPTO_THREAD_unlock(global_engine_lock);
+    if (!e->load_pubkey) {
+        ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, ENGINE_R_NO_LOAD_FUNCTION);
+        return 0;
+    }
+    pkey = e->load_pubkey(e, key_id, ui_method, callback_data);
+    if (!pkey) {
+        ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY,
+                  ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
+        return 0;
+    }
+    return pkey;
+}
+
+int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
+                                STACK_OF(X509_NAME) *ca_dn, X509 **pcert,
+                                EVP_PKEY **ppkey, STACK_OF(X509) **pother,
+                                UI_METHOD *ui_method, void *callback_data)
+{
+
+    if (e == NULL) {
+        ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
+                  ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    CRYPTO_THREAD_write_lock(global_engine_lock);
+    if (e->funct_ref == 0) {
+        CRYPTO_THREAD_unlock(global_engine_lock);
+        ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
+                  ENGINE_R_NOT_INITIALISED);
+        return 0;
+    }
+    CRYPTO_THREAD_unlock(global_engine_lock);
+    if (!e->load_ssl_client_cert) {
+        ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
+                  ENGINE_R_NO_LOAD_FUNCTION);
+        return 0;
+    }
+    return e->load_ssl_client_cert(e, s, ca_dn, pcert, ppkey, pother,
+                                   ui_method, callback_data);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_rdrand.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_rdrand.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_rdrand.c	(revision 331)
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2011-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 <openssl/opensslconf.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <internal/engine.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <openssl/crypto.h>
+
+#if (defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
+     defined(__x86_64) || defined(__x86_64__) || \
+     defined(_M_AMD64) || defined (_M_X64)) && defined(OPENSSL_CPUID_OBJ)
+
+size_t OPENSSL_ia32_rdrand(void);
+
+static int get_random_bytes(unsigned char *buf, int num)
+{
+    size_t rnd;
+
+    while (num >= (int)sizeof(size_t)) {
+        if ((rnd = OPENSSL_ia32_rdrand()) == 0)
+            return 0;
+
+        *((size_t *)buf) = rnd;
+        buf += sizeof(size_t);
+        num -= sizeof(size_t);
+    }
+    if (num) {
+        if ((rnd = OPENSSL_ia32_rdrand()) == 0)
+            return 0;
+
+        memcpy(buf, &rnd, num);
+    }
+
+    return 1;
+}
+
+static int random_status(void)
+{
+    return 1;
+}
+
+static RAND_METHOD rdrand_meth = {
+    NULL,                       /* seed */
+    get_random_bytes,
+    NULL,                       /* cleanup */
+    NULL,                       /* add */
+    get_random_bytes,
+    random_status,
+};
+
+static int rdrand_init(ENGINE *e)
+{
+    return 1;
+}
+
+static const char *engine_e_rdrand_id = "rdrand";
+static const char *engine_e_rdrand_name = "Intel RDRAND engine";
+
+static int bind_helper(ENGINE *e)
+{
+    if (!ENGINE_set_id(e, engine_e_rdrand_id) ||
+        !ENGINE_set_name(e, engine_e_rdrand_name) ||
+        !ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL) ||
+        !ENGINE_set_init_function(e, rdrand_init) ||
+        !ENGINE_set_RAND(e, &rdrand_meth))
+        return 0;
+
+    return 1;
+}
+
+static ENGINE *ENGINE_rdrand(void)
+{
+    ENGINE *ret = ENGINE_new();
+    if (ret == NULL)
+        return NULL;
+    if (!bind_helper(ret)) {
+        ENGINE_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+void engine_load_rdrand_int(void)
+{
+    extern unsigned int OPENSSL_ia32cap_P[];
+
+    if (OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) {
+        ENGINE *toadd = ENGINE_rdrand();
+        if (!toadd)
+            return;
+        ENGINE_add(toadd);
+        ENGINE_free(toadd);
+        ERR_clear_error();
+    }
+}
+#else
+void engine_load_rdrand_int(void)
+{
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_table.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_table.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/eng_table.c	(revision 331)
@@ -0,0 +1,303 @@
+/*
+ * Copyright 2001-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 "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/lhash.h>
+#include "eng_int.h"
+
+/* The type of the items in the table */
+struct st_engine_pile {
+    /* The 'nid' of this algorithm/mode */
+    int nid;
+    /* ENGINEs that implement this algorithm/mode. */
+    STACK_OF(ENGINE) *sk;
+    /* The default ENGINE to perform this algorithm/mode. */
+    ENGINE *funct;
+    /*
+     * Zero if 'sk' is newer than the cached 'funct', non-zero otherwise
+     */
+    int uptodate;
+};
+
+/* The type exposed in eng_int.h */
+struct st_engine_table {
+    LHASH_OF(ENGINE_PILE) piles;
+};                              /* ENGINE_TABLE */
+
+typedef struct st_engine_pile_doall {
+    engine_table_doall_cb *cb;
+    void *arg;
+} ENGINE_PILE_DOALL;
+
+/* Global flags (ENGINE_TABLE_FLAG_***). */
+static unsigned int table_flags = 0;
+
+/* API function manipulating 'table_flags' */
+unsigned int ENGINE_get_table_flags(void)
+{
+    return table_flags;
+}
+
+void ENGINE_set_table_flags(unsigned int flags)
+{
+    table_flags = flags;
+}
+
+/* Internal functions for the "piles" hash table */
+static unsigned long engine_pile_hash(const ENGINE_PILE *c)
+{
+    return c->nid;
+}
+
+static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b)
+{
+    return a->nid - b->nid;
+}
+
+static int int_table_check(ENGINE_TABLE **t, int create)
+{
+    LHASH_OF(ENGINE_PILE) *lh;
+
+    if (*t)
+        return 1;
+    if (!create)
+        return 0;
+    if ((lh = lh_ENGINE_PILE_new(engine_pile_hash, engine_pile_cmp)) == NULL)
+        return 0;
+    *t = (ENGINE_TABLE *)lh;
+    return 1;
+}
+
+/*
+ * Privately exposed (via eng_int.h) functions for adding and/or removing
+ * ENGINEs from the implementation table
+ */
+int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup,
+                          ENGINE *e, const int *nids, int num_nids,
+                          int setdefault)
+{
+    int ret = 0, added = 0;
+    ENGINE_PILE tmplate, *fnd;
+    CRYPTO_THREAD_write_lock(global_engine_lock);
+    if (!(*table))
+        added = 1;
+    if (!int_table_check(table, 1))
+        goto end;
+    if (added)
+        /* The cleanup callback needs to be added */
+        engine_cleanup_add_first(cleanup);
+    while (num_nids--) {
+        tmplate.nid = *nids;
+        fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
+        if (!fnd) {
+            fnd = OPENSSL_malloc(sizeof(*fnd));
+            if (fnd == NULL)
+                goto end;
+            fnd->uptodate = 1;
+            fnd->nid = *nids;
+            fnd->sk = sk_ENGINE_new_null();
+            if (!fnd->sk) {
+                OPENSSL_free(fnd);
+                goto end;
+            }
+            fnd->funct = NULL;
+            (void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd);
+        }
+        /* A registration shouldn't add duplicate entries */
+        (void)sk_ENGINE_delete_ptr(fnd->sk, e);
+        /*
+         * if 'setdefault', this ENGINE goes to the head of the list
+         */
+        if (!sk_ENGINE_push(fnd->sk, e))
+            goto end;
+        /* "touch" this ENGINE_PILE */
+        fnd->uptodate = 0;
+        if (setdefault) {
+            if (!engine_unlocked_init(e)) {
+                ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER,
+                          ENGINE_R_INIT_FAILED);
+                goto end;
+            }
+            if (fnd->funct)
+                engine_unlocked_finish(fnd->funct, 0);
+            fnd->funct = e;
+            fnd->uptodate = 1;
+        }
+        nids++;
+    }
+    ret = 1;
+ end:
+    CRYPTO_THREAD_unlock(global_engine_lock);
+    return ret;
+}
+
+static void int_unregister_cb(ENGINE_PILE *pile, ENGINE *e)
+{
+    int n;
+    /* Iterate the 'c->sk' stack removing any occurrence of 'e' */
+    while ((n = sk_ENGINE_find(pile->sk, e)) >= 0) {
+        (void)sk_ENGINE_delete(pile->sk, n);
+        pile->uptodate = 0;
+    }
+    if (pile->funct == e) {
+        engine_unlocked_finish(e, 0);
+        pile->funct = NULL;
+    }
+}
+
+IMPLEMENT_LHASH_DOALL_ARG(ENGINE_PILE, ENGINE);
+
+void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e)
+{
+    CRYPTO_THREAD_write_lock(global_engine_lock);
+    if (int_table_check(table, 0))
+        lh_ENGINE_PILE_doall_ENGINE(&(*table)->piles, int_unregister_cb, e);
+    CRYPTO_THREAD_unlock(global_engine_lock);
+}
+
+static void int_cleanup_cb_doall(ENGINE_PILE *p)
+{
+    if (!p)
+        return;
+    sk_ENGINE_free(p->sk);
+    if (p->funct)
+        engine_unlocked_finish(p->funct, 0);
+    OPENSSL_free(p);
+}
+
+void engine_table_cleanup(ENGINE_TABLE **table)
+{
+    CRYPTO_THREAD_write_lock(global_engine_lock);
+    if (*table) {
+        lh_ENGINE_PILE_doall(&(*table)->piles, int_cleanup_cb_doall);
+        lh_ENGINE_PILE_free(&(*table)->piles);
+        *table = NULL;
+    }
+    CRYPTO_THREAD_unlock(global_engine_lock);
+}
+
+/* return a functional reference for a given 'nid' */
+#ifndef ENGINE_TABLE_DEBUG
+ENGINE *engine_table_select(ENGINE_TABLE **table, int nid)
+#else
+ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f,
+                                int l)
+#endif
+{
+    ENGINE *ret = NULL;
+    ENGINE_PILE tmplate, *fnd = NULL;
+    int initres, loop = 0;
+
+    if (!(*table)) {
+#ifdef ENGINE_TABLE_DEBUG
+        fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing "
+                "registered!\n", f, l, nid);
+#endif
+        return NULL;
+    }
+    ERR_set_mark();
+    CRYPTO_THREAD_write_lock(global_engine_lock);
+    /*
+     * Check again inside the lock otherwise we could race against cleanup
+     * operations. But don't worry about a fprintf(stderr).
+     */
+    if (!int_table_check(table, 0))
+        goto end;
+    tmplate.nid = nid;
+    fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate);
+    if (!fnd)
+        goto end;
+    if (fnd->funct && engine_unlocked_init(fnd->funct)) {
+#ifdef ENGINE_TABLE_DEBUG
+        fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
+                "ENGINE '%s' cached\n", f, l, nid, fnd->funct->id);
+#endif
+        ret = fnd->funct;
+        goto end;
+    }
+    if (fnd->uptodate) {
+        ret = fnd->funct;
+        goto end;
+    }
+ trynext:
+    ret = sk_ENGINE_value(fnd->sk, loop++);
+    if (!ret) {
+#ifdef ENGINE_TABLE_DEBUG
+        fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no "
+                "registered implementations would initialise\n", f, l, nid);
+#endif
+        goto end;
+    }
+    /* Try to initialise the ENGINE? */
+    if ((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT))
+        initres = engine_unlocked_init(ret);
+    else
+        initres = 0;
+    if (initres) {
+        /* Update 'funct' */
+        if ((fnd->funct != ret) && engine_unlocked_init(ret)) {
+            /* If there was a previous default we release it. */
+            if (fnd->funct)
+                engine_unlocked_finish(fnd->funct, 0);
+            fnd->funct = ret;
+#ifdef ENGINE_TABLE_DEBUG
+            fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, "
+                    "setting default to '%s'\n", f, l, nid, ret->id);
+#endif
+        }
+#ifdef ENGINE_TABLE_DEBUG
+        fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using "
+                "newly initialised '%s'\n", f, l, nid, ret->id);
+#endif
+        goto end;
+    }
+    goto trynext;
+ end:
+    /*
+     * If it failed, it is unlikely to succeed again until some future
+     * registrations have taken place. In all cases, we cache.
+     */
+    if (fnd)
+        fnd->uptodate = 1;
+#ifdef ENGINE_TABLE_DEBUG
+    if (ret)
+        fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
+                "ENGINE '%s'\n", f, l, nid, ret->id);
+    else
+        fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching "
+                "'no matching ENGINE'\n", f, l, nid);
+#endif
+    CRYPTO_THREAD_unlock(global_engine_lock);
+    /*
+     * Whatever happened, any failed init()s are not failures in this
+     * context, so clear our error state.
+     */
+    ERR_pop_to_mark();
+    return ret;
+}
+
+/* Table enumeration */
+
+static void int_dall(const ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall)
+{
+    dall->cb(pile->nid, pile->sk, pile->funct, dall->arg);
+}
+
+IMPLEMENT_LHASH_DOALL_ARG_CONST(ENGINE_PILE, ENGINE_PILE_DOALL);
+
+void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb,
+                        void *arg)
+{
+    ENGINE_PILE_DOALL dall;
+    dall.cb = cb;
+    dall.arg = arg;
+    if (table)
+        lh_ENGINE_PILE_doall_ENGINE_PILE_DOALL(&table->piles, int_dall, &dall);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_asnmth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_asnmth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_asnmth.c	(revision 331)
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2006-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 "eng_int.h"
+#include <openssl/evp.h>
+#include "internal/asn1_int.h"
+
+/*
+ * If this symbol is defined then ENGINE_get_pkey_asn1_meth_engine(), the
+ * function that is used by EVP to hook in pkey_asn1_meth code and cache
+ * defaults (etc), will display brief debugging summaries to stderr with the
+ * 'nid'.
+ */
+/* #define ENGINE_PKEY_ASN1_METH_DEBUG */
+
+static ENGINE_TABLE *pkey_asn1_meth_table = NULL;
+
+void ENGINE_unregister_pkey_asn1_meths(ENGINE *e)
+{
+    engine_table_unregister(&pkey_asn1_meth_table, e);
+}
+
+static void engine_unregister_all_pkey_asn1_meths(void)
+{
+    engine_table_cleanup(&pkey_asn1_meth_table);
+}
+
+int ENGINE_register_pkey_asn1_meths(ENGINE *e)
+{
+    if (e->pkey_asn1_meths) {
+        const int *nids;
+        int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
+        if (num_nids > 0)
+            return engine_table_register(&pkey_asn1_meth_table,
+                                         engine_unregister_all_pkey_asn1_meths,
+                                         e, nids, num_nids, 0);
+    }
+    return 1;
+}
+
+void ENGINE_register_all_pkey_asn1_meths(void)
+{
+    ENGINE *e;
+
+    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+        ENGINE_register_pkey_asn1_meths(e);
+}
+
+int ENGINE_set_default_pkey_asn1_meths(ENGINE *e)
+{
+    if (e->pkey_asn1_meths) {
+        const int *nids;
+        int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0);
+        if (num_nids > 0)
+            return engine_table_register(&pkey_asn1_meth_table,
+                                         engine_unregister_all_pkey_asn1_meths,
+                                         e, nids, num_nids, 1);
+    }
+    return 1;
+}
+
+/*
+ * Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references) for a given pkey_asn1_meth 'nid'
+ */
+ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid)
+{
+    return engine_table_select(&pkey_asn1_meth_table, nid);
+}
+
+/*
+ * Obtains a pkey_asn1_meth implementation from an ENGINE functional
+ * reference
+ */
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid)
+{
+    EVP_PKEY_ASN1_METHOD *ret;
+    ENGINE_PKEY_ASN1_METHS_PTR fn = ENGINE_get_pkey_asn1_meths(e);
+    if (!fn || !fn(e, &ret, NULL, nid)) {
+        ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH,
+                  ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
+        return NULL;
+    }
+    return ret;
+}
+
+/* Gets the pkey_asn1_meth callback from an ENGINE structure */
+ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e)
+{
+    return e->pkey_asn1_meths;
+}
+
+/* Sets the pkey_asn1_meth callback in an ENGINE structure */
+int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f)
+{
+    e->pkey_asn1_meths = f;
+    return 1;
+}
+
+/*
+ * Internal function to free up EVP_PKEY_ASN1_METHOD structures before an
+ * ENGINE is destroyed
+ */
+
+void engine_pkey_asn1_meths_free(ENGINE *e)
+{
+    int i;
+    EVP_PKEY_ASN1_METHOD *pkm;
+    if (e->pkey_asn1_meths) {
+        const int *pknids;
+        int npknids;
+        npknids = e->pkey_asn1_meths(e, NULL, &pknids, 0);
+        for (i = 0; i < npknids; i++) {
+            if (e->pkey_asn1_meths(e, &pkm, NULL, pknids[i])) {
+                EVP_PKEY_asn1_free(pkm);
+            }
+        }
+    }
+}
+
+/*
+ * Find a method based on a string. This does a linear search through all
+ * implemented algorithms. This is OK in practice because only a small number
+ * of algorithms are likely to be implemented in an engine and it is not used
+ * for speed critical operations.
+ */
+
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
+                                                          const char *str,
+                                                          int len)
+{
+    int i, nidcount;
+    const int *nids;
+    EVP_PKEY_ASN1_METHOD *ameth;
+    if (!e->pkey_asn1_meths)
+        return NULL;
+    if (len == -1)
+        len = strlen(str);
+    nidcount = e->pkey_asn1_meths(e, NULL, &nids, 0);
+    for (i = 0; i < nidcount; i++) {
+        e->pkey_asn1_meths(e, &ameth, NULL, nids[i]);
+        if (((int)strlen(ameth->pem_str) == len)
+            && strncasecmp(ameth->pem_str, str, len) == 0)
+            return ameth;
+    }
+    return NULL;
+}
+
+typedef struct {
+    ENGINE *e;
+    const EVP_PKEY_ASN1_METHOD *ameth;
+    const char *str;
+    int len;
+} ENGINE_FIND_STR;
+
+static void look_str_cb(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg)
+{
+    ENGINE_FIND_STR *lk = arg;
+    int i;
+    if (lk->ameth)
+        return;
+    for (i = 0; i < sk_ENGINE_num(sk); i++) {
+        ENGINE *e = sk_ENGINE_value(sk, i);
+        EVP_PKEY_ASN1_METHOD *ameth;
+        e->pkey_asn1_meths(e, &ameth, NULL, nid);
+        if (((int)strlen(ameth->pem_str) == lk->len)
+                && strncasecmp(ameth->pem_str, lk->str, lk->len) == 0) {
+            lk->e = e;
+            lk->ameth = ameth;
+            return;
+        }
+    }
+}
+
+const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
+                                                      const char *str,
+                                                      int len)
+{
+    ENGINE_FIND_STR fstr;
+    fstr.e = NULL;
+    fstr.ameth = NULL;
+    fstr.str = str;
+    fstr.len = len;
+
+    if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) {
+        ENGINEerr(ENGINE_F_ENGINE_PKEY_ASN1_FIND_STR, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    CRYPTO_THREAD_write_lock(global_engine_lock);
+    engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr);
+    /* If found obtain a structural reference to engine */
+    if (fstr.e) {
+        fstr.e->struct_ref++;
+        engine_ref_debug(fstr.e, 0, 1);
+    }
+    *pe = fstr.e;
+    CRYPTO_THREAD_unlock(global_engine_lock);
+    return fstr.ameth;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_cipher.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_cipher.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_cipher.c	(revision 331)
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2001-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 "eng_int.h"
+
+static ENGINE_TABLE *cipher_table = NULL;
+
+void ENGINE_unregister_ciphers(ENGINE *e)
+{
+    engine_table_unregister(&cipher_table, e);
+}
+
+static void engine_unregister_all_ciphers(void)
+{
+    engine_table_cleanup(&cipher_table);
+}
+
+int ENGINE_register_ciphers(ENGINE *e)
+{
+    if (e->ciphers) {
+        const int *nids;
+        int num_nids = e->ciphers(e, NULL, &nids, 0);
+        if (num_nids > 0)
+            return engine_table_register(&cipher_table,
+                                         engine_unregister_all_ciphers, e,
+                                         nids, num_nids, 0);
+    }
+    return 1;
+}
+
+void ENGINE_register_all_ciphers()
+{
+    ENGINE *e;
+
+    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+        ENGINE_register_ciphers(e);
+}
+
+int ENGINE_set_default_ciphers(ENGINE *e)
+{
+    if (e->ciphers) {
+        const int *nids;
+        int num_nids = e->ciphers(e, NULL, &nids, 0);
+        if (num_nids > 0)
+            return engine_table_register(&cipher_table,
+                                         engine_unregister_all_ciphers, e,
+                                         nids, num_nids, 1);
+    }
+    return 1;
+}
+
+/*
+ * Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references) for a given cipher 'nid'
+ */
+ENGINE *ENGINE_get_cipher_engine(int nid)
+{
+    return engine_table_select(&cipher_table, nid);
+}
+
+/* Obtains a cipher implementation from an ENGINE functional reference */
+const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid)
+{
+    const EVP_CIPHER *ret;
+    ENGINE_CIPHERS_PTR fn = ENGINE_get_ciphers(e);
+    if (!fn || !fn(e, &ret, NULL, nid)) {
+        ENGINEerr(ENGINE_F_ENGINE_GET_CIPHER, ENGINE_R_UNIMPLEMENTED_CIPHER);
+        return NULL;
+    }
+    return ret;
+}
+
+/* Gets the cipher callback from an ENGINE structure */
+ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e)
+{
+    return e->ciphers;
+}
+
+/* Sets the cipher callback in an ENGINE structure */
+int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f)
+{
+    e->ciphers = f;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_dh.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_dh.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_dh.c	(revision 331)
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2001-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 "eng_int.h"
+
+static ENGINE_TABLE *dh_table = NULL;
+static const int dummy_nid = 1;
+
+void ENGINE_unregister_DH(ENGINE *e)
+{
+    engine_table_unregister(&dh_table, e);
+}
+
+static void engine_unregister_all_DH(void)
+{
+    engine_table_cleanup(&dh_table);
+}
+
+int ENGINE_register_DH(ENGINE *e)
+{
+    if (e->dh_meth)
+        return engine_table_register(&dh_table,
+                                     engine_unregister_all_DH, e, &dummy_nid,
+                                     1, 0);
+    return 1;
+}
+
+void ENGINE_register_all_DH()
+{
+    ENGINE *e;
+
+    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+        ENGINE_register_DH(e);
+}
+
+int ENGINE_set_default_DH(ENGINE *e)
+{
+    if (e->dh_meth)
+        return engine_table_register(&dh_table,
+                                     engine_unregister_all_DH, e, &dummy_nid,
+                                     1, 1);
+    return 1;
+}
+
+/*
+ * Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references).
+ */
+ENGINE *ENGINE_get_default_DH(void)
+{
+    return engine_table_select(&dh_table, dummy_nid);
+}
+
+/* Obtains an DH implementation from an ENGINE functional reference */
+const DH_METHOD *ENGINE_get_DH(const ENGINE *e)
+{
+    return e->dh_meth;
+}
+
+/* Sets an DH implementation in an ENGINE structure */
+int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth)
+{
+    e->dh_meth = dh_meth;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_digest.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_digest.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_digest.c	(revision 331)
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2001-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 "eng_int.h"
+
+static ENGINE_TABLE *digest_table = NULL;
+
+void ENGINE_unregister_digests(ENGINE *e)
+{
+    engine_table_unregister(&digest_table, e);
+}
+
+static void engine_unregister_all_digests(void)
+{
+    engine_table_cleanup(&digest_table);
+}
+
+int ENGINE_register_digests(ENGINE *e)
+{
+    if (e->digests) {
+        const int *nids;
+        int num_nids = e->digests(e, NULL, &nids, 0);
+        if (num_nids > 0)
+            return engine_table_register(&digest_table,
+                                         engine_unregister_all_digests, e,
+                                         nids, num_nids, 0);
+    }
+    return 1;
+}
+
+void ENGINE_register_all_digests()
+{
+    ENGINE *e;
+
+    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+        ENGINE_register_digests(e);
+}
+
+int ENGINE_set_default_digests(ENGINE *e)
+{
+    if (e->digests) {
+        const int *nids;
+        int num_nids = e->digests(e, NULL, &nids, 0);
+        if (num_nids > 0)
+            return engine_table_register(&digest_table,
+                                         engine_unregister_all_digests, e,
+                                         nids, num_nids, 1);
+    }
+    return 1;
+}
+
+/*
+ * Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references) for a given digest 'nid'
+ */
+ENGINE *ENGINE_get_digest_engine(int nid)
+{
+    return engine_table_select(&digest_table, nid);
+}
+
+/* Obtains a digest implementation from an ENGINE functional reference */
+const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid)
+{
+    const EVP_MD *ret;
+    ENGINE_DIGESTS_PTR fn = ENGINE_get_digests(e);
+    if (!fn || !fn(e, &ret, NULL, nid)) {
+        ENGINEerr(ENGINE_F_ENGINE_GET_DIGEST, ENGINE_R_UNIMPLEMENTED_DIGEST);
+        return NULL;
+    }
+    return ret;
+}
+
+/* Gets the digest callback from an ENGINE structure */
+ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e)
+{
+    return e->digests;
+}
+
+/* Sets the digest callback in an ENGINE structure */
+int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f)
+{
+    e->digests = f;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_dsa.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_dsa.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_dsa.c	(revision 331)
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2001-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 "eng_int.h"
+
+static ENGINE_TABLE *dsa_table = NULL;
+static const int dummy_nid = 1;
+
+void ENGINE_unregister_DSA(ENGINE *e)
+{
+    engine_table_unregister(&dsa_table, e);
+}
+
+static void engine_unregister_all_DSA(void)
+{
+    engine_table_cleanup(&dsa_table);
+}
+
+int ENGINE_register_DSA(ENGINE *e)
+{
+    if (e->dsa_meth)
+        return engine_table_register(&dsa_table,
+                                     engine_unregister_all_DSA, e, &dummy_nid,
+                                     1, 0);
+    return 1;
+}
+
+void ENGINE_register_all_DSA()
+{
+    ENGINE *e;
+
+    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+        ENGINE_register_DSA(e);
+}
+
+int ENGINE_set_default_DSA(ENGINE *e)
+{
+    if (e->dsa_meth)
+        return engine_table_register(&dsa_table,
+                                     engine_unregister_all_DSA, e, &dummy_nid,
+                                     1, 1);
+    return 1;
+}
+
+/*
+ * Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references).
+ */
+ENGINE *ENGINE_get_default_DSA(void)
+{
+    return engine_table_select(&dsa_table, dummy_nid);
+}
+
+/* Obtains an DSA implementation from an ENGINE functional reference */
+const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e)
+{
+    return e->dsa_meth;
+}
+
+/* Sets an DSA implementation in an ENGINE structure */
+int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth)
+{
+    e->dsa_meth = dsa_meth;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_eckey.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_eckey.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_eckey.c	(revision 331)
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2015-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 "eng_int.h"
+
+static ENGINE_TABLE *dh_table = NULL;
+static const int dummy_nid = 1;
+
+void ENGINE_unregister_EC(ENGINE *e)
+{
+    engine_table_unregister(&dh_table, e);
+}
+
+static void engine_unregister_all_EC(void)
+{
+    engine_table_cleanup(&dh_table);
+}
+
+int ENGINE_register_EC(ENGINE *e)
+{
+    if (e->ec_meth != NULL)
+        return engine_table_register(&dh_table,
+                                     engine_unregister_all_EC, e, &dummy_nid,
+                                     1, 0);
+    return 1;
+}
+
+void ENGINE_register_all_EC()
+{
+    ENGINE *e;
+
+    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+        ENGINE_register_EC(e);
+}
+
+int ENGINE_set_default_EC(ENGINE *e)
+{
+    if (e->ec_meth != NULL)
+        return engine_table_register(&dh_table,
+                                     engine_unregister_all_EC, e, &dummy_nid,
+                                     1, 1);
+    return 1;
+}
+
+/*
+ * Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references).
+ */
+ENGINE *ENGINE_get_default_EC(void)
+{
+    return engine_table_select(&dh_table, dummy_nid);
+}
+
+/* Obtains an EC_KEY implementation from an ENGINE functional reference */
+const EC_KEY_METHOD *ENGINE_get_EC(const ENGINE *e)
+{
+    return e->ec_meth;
+}
+
+/* Sets an EC_KEY implementation in an ENGINE structure */
+int ENGINE_set_EC(ENGINE *e, const EC_KEY_METHOD *ec_meth)
+{
+    e->ec_meth = ec_meth;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_pkmeth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_pkmeth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_pkmeth.c	(revision 331)
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2006-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 "eng_int.h"
+#include <openssl/evp.h>
+
+static ENGINE_TABLE *pkey_meth_table = NULL;
+
+void ENGINE_unregister_pkey_meths(ENGINE *e)
+{
+    engine_table_unregister(&pkey_meth_table, e);
+}
+
+static void engine_unregister_all_pkey_meths(void)
+{
+    engine_table_cleanup(&pkey_meth_table);
+}
+
+int ENGINE_register_pkey_meths(ENGINE *e)
+{
+    if (e->pkey_meths) {
+        const int *nids;
+        int num_nids = e->pkey_meths(e, NULL, &nids, 0);
+        if (num_nids > 0)
+            return engine_table_register(&pkey_meth_table,
+                                         engine_unregister_all_pkey_meths, e,
+                                         nids, num_nids, 0);
+    }
+    return 1;
+}
+
+void ENGINE_register_all_pkey_meths()
+{
+    ENGINE *e;
+
+    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+        ENGINE_register_pkey_meths(e);
+}
+
+int ENGINE_set_default_pkey_meths(ENGINE *e)
+{
+    if (e->pkey_meths) {
+        const int *nids;
+        int num_nids = e->pkey_meths(e, NULL, &nids, 0);
+        if (num_nids > 0)
+            return engine_table_register(&pkey_meth_table,
+                                         engine_unregister_all_pkey_meths, e,
+                                         nids, num_nids, 1);
+    }
+    return 1;
+}
+
+/*
+ * Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references) for a given pkey_meth 'nid'
+ */
+ENGINE *ENGINE_get_pkey_meth_engine(int nid)
+{
+    return engine_table_select(&pkey_meth_table, nid);
+}
+
+/* Obtains a pkey_meth implementation from an ENGINE functional reference */
+const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid)
+{
+    EVP_PKEY_METHOD *ret;
+    ENGINE_PKEY_METHS_PTR fn = ENGINE_get_pkey_meths(e);
+    if (!fn || !fn(e, &ret, NULL, nid)) {
+        ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_METH,
+                  ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD);
+        return NULL;
+    }
+    return ret;
+}
+
+/* Gets the pkey_meth callback from an ENGINE structure */
+ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e)
+{
+    return e->pkey_meths;
+}
+
+/* Sets the pkey_meth callback in an ENGINE structure */
+int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f)
+{
+    e->pkey_meths = f;
+    return 1;
+}
+
+/*
+ * Internal function to free up EVP_PKEY_METHOD structures before an ENGINE
+ * is destroyed
+ */
+
+void engine_pkey_meths_free(ENGINE *e)
+{
+    int i;
+    EVP_PKEY_METHOD *pkm;
+    if (e->pkey_meths) {
+        const int *pknids;
+        int npknids;
+        npknids = e->pkey_meths(e, NULL, &pknids, 0);
+        for (i = 0; i < npknids; i++) {
+            if (e->pkey_meths(e, &pkm, NULL, pknids[i])) {
+                EVP_PKEY_meth_free(pkm);
+            }
+        }
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_rand.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_rand.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_rand.c	(revision 331)
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2001-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 "eng_int.h"
+
+static ENGINE_TABLE *rand_table = NULL;
+static const int dummy_nid = 1;
+
+void ENGINE_unregister_RAND(ENGINE *e)
+{
+    engine_table_unregister(&rand_table, e);
+}
+
+static void engine_unregister_all_RAND(void)
+{
+    engine_table_cleanup(&rand_table);
+}
+
+int ENGINE_register_RAND(ENGINE *e)
+{
+    if (e->rand_meth)
+        return engine_table_register(&rand_table,
+                                     engine_unregister_all_RAND, e,
+                                     &dummy_nid, 1, 0);
+    return 1;
+}
+
+void ENGINE_register_all_RAND()
+{
+    ENGINE *e;
+
+    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+        ENGINE_register_RAND(e);
+}
+
+int ENGINE_set_default_RAND(ENGINE *e)
+{
+    if (e->rand_meth)
+        return engine_table_register(&rand_table,
+                                     engine_unregister_all_RAND, e,
+                                     &dummy_nid, 1, 1);
+    return 1;
+}
+
+/*
+ * Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references).
+ */
+ENGINE *ENGINE_get_default_RAND(void)
+{
+    return engine_table_select(&rand_table, dummy_nid);
+}
+
+/* Obtains an RAND implementation from an ENGINE functional reference */
+const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e)
+{
+    return e->rand_meth;
+}
+
+/* Sets an RAND implementation in an ENGINE structure */
+int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth)
+{
+    e->rand_meth = rand_meth;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_rsa.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_rsa.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/engine/tb_rsa.c	(revision 331)
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2001-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 "eng_int.h"
+
+static ENGINE_TABLE *rsa_table = NULL;
+static const int dummy_nid = 1;
+
+void ENGINE_unregister_RSA(ENGINE *e)
+{
+    engine_table_unregister(&rsa_table, e);
+}
+
+static void engine_unregister_all_RSA(void)
+{
+    engine_table_cleanup(&rsa_table);
+}
+
+int ENGINE_register_RSA(ENGINE *e)
+{
+    if (e->rsa_meth)
+        return engine_table_register(&rsa_table,
+                                     engine_unregister_all_RSA, e, &dummy_nid,
+                                     1, 0);
+    return 1;
+}
+
+void ENGINE_register_all_RSA()
+{
+    ENGINE *e;
+
+    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
+        ENGINE_register_RSA(e);
+}
+
+int ENGINE_set_default_RSA(ENGINE *e)
+{
+    if (e->rsa_meth)
+        return engine_table_register(&rsa_table,
+                                     engine_unregister_all_RSA, e, &dummy_nid,
+                                     1, 1);
+    return 1;
+}
+
+/*
+ * Exposed API function to get a functional reference from the implementation
+ * table (ie. try to get a functional reference from the tabled structural
+ * references).
+ */
+ENGINE *ENGINE_get_default_RSA(void)
+{
+    return engine_table_select(&rsa_table, dummy_nid);
+}
+
+/* Obtains an RSA implementation from an ENGINE functional reference */
+const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e)
+{
+    return e->rsa_meth;
+}
+
+/* Sets an RSA implementation in an ENGINE structure */
+int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth)
+{
+    e->rsa_meth = rsa_meth;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/err/err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/err/err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/err/err.c	(revision 331)
@@ -0,0 +1,770 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <internal/cryptlib_int.h>
+#include <internal/err.h>
+#include <internal/err_int.h>
+#include <openssl/lhash.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/bio.h>
+#include <openssl/opensslconf.h>
+#include <internal/thread_once.h>
+
+static void err_load_strings(int lib, ERR_STRING_DATA *str);
+
+static void ERR_STATE_free(ERR_STATE *s);
+#ifndef OPENSSL_NO_ERR
+static ERR_STRING_DATA ERR_str_libraries[] = {
+    {ERR_PACK(ERR_LIB_NONE, 0, 0), "unknown library"},
+    {ERR_PACK(ERR_LIB_SYS, 0, 0), "system library"},
+    {ERR_PACK(ERR_LIB_BN, 0, 0), "bignum routines"},
+    {ERR_PACK(ERR_LIB_RSA, 0, 0), "rsa routines"},
+    {ERR_PACK(ERR_LIB_DH, 0, 0), "Diffie-Hellman routines"},
+    {ERR_PACK(ERR_LIB_EVP, 0, 0), "digital envelope routines"},
+    {ERR_PACK(ERR_LIB_BUF, 0, 0), "memory buffer routines"},
+    {ERR_PACK(ERR_LIB_OBJ, 0, 0), "object identifier routines"},
+    {ERR_PACK(ERR_LIB_PEM, 0, 0), "PEM routines"},
+    {ERR_PACK(ERR_LIB_DSA, 0, 0), "dsa routines"},
+    {ERR_PACK(ERR_LIB_X509, 0, 0), "x509 certificate routines"},
+    {ERR_PACK(ERR_LIB_ASN1, 0, 0), "asn1 encoding routines"},
+    {ERR_PACK(ERR_LIB_CONF, 0, 0), "configuration file routines"},
+    {ERR_PACK(ERR_LIB_CRYPTO, 0, 0), "common libcrypto routines"},
+    {ERR_PACK(ERR_LIB_EC, 0, 0), "elliptic curve routines"},
+    {ERR_PACK(ERR_LIB_ECDSA, 0, 0), "ECDSA routines"},
+    {ERR_PACK(ERR_LIB_ECDH, 0, 0), "ECDH routines"},
+    {ERR_PACK(ERR_LIB_SSL, 0, 0), "SSL routines"},
+    {ERR_PACK(ERR_LIB_BIO, 0, 0), "BIO routines"},
+    {ERR_PACK(ERR_LIB_PKCS7, 0, 0), "PKCS7 routines"},
+    {ERR_PACK(ERR_LIB_X509V3, 0, 0), "X509 V3 routines"},
+    {ERR_PACK(ERR_LIB_PKCS12, 0, 0), "PKCS12 routines"},
+    {ERR_PACK(ERR_LIB_RAND, 0, 0), "random number generator"},
+    {ERR_PACK(ERR_LIB_DSO, 0, 0), "DSO support routines"},
+    {ERR_PACK(ERR_LIB_TS, 0, 0), "time stamp routines"},
+    {ERR_PACK(ERR_LIB_ENGINE, 0, 0), "engine routines"},
+    {ERR_PACK(ERR_LIB_OCSP, 0, 0), "OCSP routines"},
+    {ERR_PACK(ERR_LIB_UI, 0, 0), "UI routines"},
+    {ERR_PACK(ERR_LIB_FIPS, 0, 0), "FIPS routines"},
+    {ERR_PACK(ERR_LIB_CMS, 0, 0), "CMS routines"},
+    {ERR_PACK(ERR_LIB_HMAC, 0, 0), "HMAC routines"},
+    {ERR_PACK(ERR_LIB_CT, 0, 0), "CT routines"},
+    {ERR_PACK(ERR_LIB_ASYNC, 0, 0), "ASYNC routines"},
+    {ERR_PACK(ERR_LIB_KDF, 0, 0), "KDF routines"},
+    {0, NULL},
+};
+
+static ERR_STRING_DATA ERR_str_functs[] = {
+    {ERR_PACK(0, SYS_F_FOPEN, 0), "fopen"},
+    {ERR_PACK(0, SYS_F_CONNECT, 0), "connect"},
+    {ERR_PACK(0, SYS_F_GETSERVBYNAME, 0), "getservbyname"},
+    {ERR_PACK(0, SYS_F_SOCKET, 0), "socket"},
+    {ERR_PACK(0, SYS_F_IOCTLSOCKET, 0), "ioctlsocket"},
+    {ERR_PACK(0, SYS_F_BIND, 0), "bind"},
+    {ERR_PACK(0, SYS_F_LISTEN, 0), "listen"},
+    {ERR_PACK(0, SYS_F_ACCEPT, 0), "accept"},
+# ifdef OPENSSL_SYS_WINDOWS
+    {ERR_PACK(0, SYS_F_WSASTARTUP, 0), "WSAstartup"},
+# endif
+    {ERR_PACK(0, SYS_F_OPENDIR, 0), "opendir"},
+    {ERR_PACK(0, SYS_F_FREAD, 0), "fread"},
+    {ERR_PACK(0, SYS_F_GETADDRINFO, 0), "getaddrinfo"},
+    {ERR_PACK(0, SYS_F_GETNAMEINFO, 0), "getnameinfo"},
+    {ERR_PACK(0, SYS_F_SETSOCKOPT, 0), "setsockopt"},
+    {ERR_PACK(0, SYS_F_GETSOCKOPT, 0), "getsockopt"},
+    {ERR_PACK(0, SYS_F_GETSOCKNAME, 0), "getsockname"},
+    {ERR_PACK(0, SYS_F_GETHOSTBYNAME, 0), "gethostbyname"},
+    {0, NULL},
+};
+
+static ERR_STRING_DATA ERR_str_reasons[] = {
+    {ERR_R_SYS_LIB, "system lib"},
+    {ERR_R_BN_LIB, "BN lib"},
+    {ERR_R_RSA_LIB, "RSA lib"},
+    {ERR_R_DH_LIB, "DH lib"},
+    {ERR_R_EVP_LIB, "EVP lib"},
+    {ERR_R_BUF_LIB, "BUF lib"},
+    {ERR_R_OBJ_LIB, "OBJ lib"},
+    {ERR_R_PEM_LIB, "PEM lib"},
+    {ERR_R_DSA_LIB, "DSA lib"},
+    {ERR_R_X509_LIB, "X509 lib"},
+    {ERR_R_ASN1_LIB, "ASN1 lib"},
+    {ERR_R_EC_LIB, "EC lib"},
+    {ERR_R_BIO_LIB, "BIO lib"},
+    {ERR_R_PKCS7_LIB, "PKCS7 lib"},
+    {ERR_R_X509V3_LIB, "X509V3 lib"},
+    {ERR_R_ENGINE_LIB, "ENGINE lib"},
+    {ERR_R_ECDSA_LIB, "ECDSA lib"},
+
+    {ERR_R_NESTED_ASN1_ERROR, "nested asn1 error"},
+    {ERR_R_MISSING_ASN1_EOS, "missing asn1 eos"},
+
+    {ERR_R_FATAL, "fatal"},
+    {ERR_R_MALLOC_FAILURE, "malloc failure"},
+    {ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED,
+     "called a function you should not call"},
+    {ERR_R_PASSED_NULL_PARAMETER, "passed a null parameter"},
+    {ERR_R_INTERNAL_ERROR, "internal error"},
+    {ERR_R_DISABLED, "called a function that was disabled at compile-time"},
+    {ERR_R_INIT_FAIL, "init fail"},
+
+    {0, NULL},
+};
+#endif
+
+static CRYPTO_ONCE err_init = CRYPTO_ONCE_STATIC_INIT;
+static CRYPTO_THREAD_LOCAL err_thread_local;
+
+static CRYPTO_ONCE err_string_init = CRYPTO_ONCE_STATIC_INIT;
+static CRYPTO_RWLOCK *err_string_lock;
+
+static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);
+
+/*
+ * The internal state
+ */
+
+static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL;
+static int int_err_library_number = ERR_LIB_USER;
+
+static unsigned long get_error_values(int inc, int top, const char **file,
+                                      int *line, const char **data,
+                                      int *flags);
+
+static unsigned long err_string_data_hash(const ERR_STRING_DATA *a)
+{
+    unsigned long ret, l;
+
+    l = a->error;
+    ret = l ^ ERR_GET_LIB(l) ^ ERR_GET_FUNC(l);
+    return (ret ^ ret % 19 * 13);
+}
+
+static int err_string_data_cmp(const ERR_STRING_DATA *a,
+                               const ERR_STRING_DATA *b)
+{
+    return (int)(a->error - b->error);
+}
+
+static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d)
+{
+    ERR_STRING_DATA *p = NULL;
+
+    CRYPTO_THREAD_read_lock(err_string_lock);
+    if (int_error_hash != NULL)
+        p = lh_ERR_STRING_DATA_retrieve(int_error_hash, d);
+    CRYPTO_THREAD_unlock(err_string_lock);
+
+    return p;
+}
+
+#ifndef OPENSSL_NO_ERR
+# define NUM_SYS_STR_REASONS 127
+# define LEN_SYS_STR_REASON 32
+
+static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
+/*
+ * SYS_str_reasons is filled with copies of strerror() results at
+ * initialization. 'errno' values up to 127 should cover all usual errors,
+ * others will be displayed numerically by ERR_error_string. It is crucial
+ * that we have something for each reason code that occurs in
+ * ERR_str_reasons, or bogus reason strings will be returned for SYSerr(),
+ * which always gets an errno value and never one of those 'standard' reason
+ * codes.
+ */
+
+static void build_SYS_str_reasons(void)
+{
+    /* OPENSSL_malloc cannot be used here, use static storage instead */
+    static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON];
+    static int init = 1;
+    int i;
+
+    CRYPTO_THREAD_write_lock(err_string_lock);
+    if (!init) {
+        CRYPTO_THREAD_unlock(err_string_lock);
+        return;
+    }
+
+    for (i = 1; i <= NUM_SYS_STR_REASONS; i++) {
+        ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];
+
+        str->error = (unsigned long)i;
+        if (str->string == NULL) {
+            char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]);
+            if (openssl_strerror_r(i, *dest, sizeof(*dest)))
+                str->string = *dest;
+        }
+        if (str->string == NULL)
+            str->string = "unknown";
+    }
+
+    /*
+     * Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL}, as
+     * required by ERR_load_strings.
+     */
+
+    init = 0;
+
+    CRYPTO_THREAD_unlock(err_string_lock);
+}
+#endif
+
+#define err_clear_data(p,i) \
+        do { \
+        if ((p)->err_data_flags[i] & ERR_TXT_MALLOCED) \
+                {  \
+                OPENSSL_free((p)->err_data[i]); \
+                (p)->err_data[i]=NULL; \
+                } \
+        (p)->err_data_flags[i]=0; \
+        } while(0)
+
+#define err_clear(p,i) \
+        do { \
+        (p)->err_flags[i]=0; \
+        (p)->err_buffer[i]=0; \
+        err_clear_data(p,i); \
+        (p)->err_file[i]=NULL; \
+        (p)->err_line[i]= -1; \
+        } while(0)
+
+static void ERR_STATE_free(ERR_STATE *s)
+{
+    int i;
+
+    if (s == NULL)
+        return;
+
+    for (i = 0; i < ERR_NUM_ERRORS; i++) {
+        err_clear_data(s, i);
+    }
+    OPENSSL_free(s);
+}
+
+DEFINE_RUN_ONCE_STATIC(do_err_strings_init)
+{
+    OPENSSL_init_crypto(0, NULL);
+    err_string_lock = CRYPTO_THREAD_lock_new();
+    return err_string_lock != NULL;
+}
+
+void err_cleanup(void)
+{
+    CRYPTO_THREAD_lock_free(err_string_lock);
+    err_string_lock = NULL;
+}
+
+int ERR_load_ERR_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+    if (!RUN_ONCE(&err_string_init, do_err_strings_init))
+        return 0;
+
+    err_load_strings(0, ERR_str_libraries);
+    err_load_strings(0, ERR_str_reasons);
+    err_load_strings(ERR_LIB_SYS, ERR_str_functs);
+    build_SYS_str_reasons();
+    err_load_strings(ERR_LIB_SYS, SYS_str_reasons);
+#endif
+    return 1;
+}
+
+static void err_load_strings(int lib, ERR_STRING_DATA *str)
+{
+    CRYPTO_THREAD_write_lock(err_string_lock);
+    if (int_error_hash == NULL)
+        int_error_hash = lh_ERR_STRING_DATA_new(err_string_data_hash,
+                                                err_string_data_cmp);
+    if (int_error_hash != NULL) {
+        for (; str->error; str++) {
+            if (lib)
+                str->error |= ERR_PACK(lib, 0, 0);
+            (void)lh_ERR_STRING_DATA_insert(int_error_hash, str);
+        }
+    }
+    CRYPTO_THREAD_unlock(err_string_lock);
+}
+
+int ERR_load_strings(int lib, ERR_STRING_DATA *str)
+{
+    if (ERR_load_ERR_strings() == 0)
+        return 0;
+    err_load_strings(lib, str);
+    return 1;
+}
+
+int ERR_unload_strings(int lib, ERR_STRING_DATA *str)
+{
+    if (!RUN_ONCE(&err_string_init, do_err_strings_init))
+        return 0;
+
+    CRYPTO_THREAD_write_lock(err_string_lock);
+    if (int_error_hash != NULL) {
+        for (; str->error; str++) {
+            if (lib)
+                str->error |= ERR_PACK(lib, 0, 0);
+            (void)lh_ERR_STRING_DATA_delete(int_error_hash, str);
+        }
+    }
+    CRYPTO_THREAD_unlock(err_string_lock);
+
+    return 1;
+}
+
+void err_free_strings_int(void)
+{
+    if (!RUN_ONCE(&err_string_init, do_err_strings_init))
+        return;
+
+    CRYPTO_THREAD_write_lock(err_string_lock);
+    lh_ERR_STRING_DATA_free(int_error_hash);
+    int_error_hash = NULL;
+    CRYPTO_THREAD_unlock(err_string_lock);
+}
+
+/********************************************************/
+
+void ERR_put_error(int lib, int func, int reason, const char *file, int line)
+{
+    ERR_STATE *es;
+
+#ifdef _OSD_POSIX
+    /*
+     * In the BS2000-OSD POSIX subsystem, the compiler generates path names
+     * in the form "*POSIX(/etc/passwd)". This dirty hack strips them to
+     * something sensible. @@@ We shouldn't modify a const string, though.
+     */
+    if (strncmp(file, "*POSIX(", sizeof("*POSIX(") - 1) == 0) {
+        char *end;
+
+        /* Skip the "*POSIX(" prefix */
+        file += sizeof("*POSIX(") - 1;
+        end = &file[strlen(file) - 1];
+        if (*end == ')')
+            *end = '\0';
+        /* Optional: use the basename of the path only. */
+        if ((end = strrchr(file, '/')) != NULL)
+            file = &end[1];
+    }
+#endif
+    es = ERR_get_state();
+
+    es->top = (es->top + 1) % ERR_NUM_ERRORS;
+    if (es->top == es->bottom)
+        es->bottom = (es->bottom + 1) % ERR_NUM_ERRORS;
+    es->err_flags[es->top] = 0;
+    es->err_buffer[es->top] = ERR_PACK(lib, func, reason);
+    es->err_file[es->top] = file;
+    es->err_line[es->top] = line;
+    err_clear_data(es, es->top);
+}
+
+void ERR_clear_error(void)
+{
+    int i;
+    ERR_STATE *es;
+
+    es = ERR_get_state();
+
+    for (i = 0; i < ERR_NUM_ERRORS; i++) {
+        err_clear(es, i);
+    }
+    es->top = es->bottom = 0;
+}
+
+unsigned long ERR_get_error(void)
+{
+    return (get_error_values(1, 0, NULL, NULL, NULL, NULL));
+}
+
+unsigned long ERR_get_error_line(const char **file, int *line)
+{
+    return (get_error_values(1, 0, file, line, NULL, NULL));
+}
+
+unsigned long ERR_get_error_line_data(const char **file, int *line,
+                                      const char **data, int *flags)
+{
+    return (get_error_values(1, 0, file, line, data, flags));
+}
+
+unsigned long ERR_peek_error(void)
+{
+    return (get_error_values(0, 0, NULL, NULL, NULL, NULL));
+}
+
+unsigned long ERR_peek_error_line(const char **file, int *line)
+{
+    return (get_error_values(0, 0, file, line, NULL, NULL));
+}
+
+unsigned long ERR_peek_error_line_data(const char **file, int *line,
+                                       const char **data, int *flags)
+{
+    return (get_error_values(0, 0, file, line, data, flags));
+}
+
+unsigned long ERR_peek_last_error(void)
+{
+    return (get_error_values(0, 1, NULL, NULL, NULL, NULL));
+}
+
+unsigned long ERR_peek_last_error_line(const char **file, int *line)
+{
+    return (get_error_values(0, 1, file, line, NULL, NULL));
+}
+
+unsigned long ERR_peek_last_error_line_data(const char **file, int *line,
+                                            const char **data, int *flags)
+{
+    return (get_error_values(0, 1, file, line, data, flags));
+}
+
+static unsigned long get_error_values(int inc, int top, const char **file,
+                                      int *line, const char **data,
+                                      int *flags)
+{
+    int i = 0;
+    ERR_STATE *es;
+    unsigned long ret;
+
+    es = ERR_get_state();
+
+    if (inc && top) {
+        if (file)
+            *file = "";
+        if (line)
+            *line = 0;
+        if (data)
+            *data = "";
+        if (flags)
+            *flags = 0;
+
+        return ERR_R_INTERNAL_ERROR;
+    }
+
+    if (es->bottom == es->top)
+        return 0;
+    if (top)
+        i = es->top;            /* last error */
+    else
+        i = (es->bottom + 1) % ERR_NUM_ERRORS; /* first error */
+
+    ret = es->err_buffer[i];
+    if (inc) {
+        es->bottom = i;
+        es->err_buffer[i] = 0;
+    }
+
+    if ((file != NULL) && (line != NULL)) {
+        if (es->err_file[i] == NULL) {
+            *file = "NA";
+            if (line != NULL)
+                *line = 0;
+        } else {
+            *file = es->err_file[i];
+            if (line != NULL)
+                *line = es->err_line[i];
+        }
+    }
+
+    if (data == NULL) {
+        if (inc) {
+            err_clear_data(es, i);
+        }
+    } else {
+        if (es->err_data[i] == NULL) {
+            *data = "";
+            if (flags != NULL)
+                *flags = 0;
+        } else {
+            *data = es->err_data[i];
+            if (flags != NULL)
+                *flags = es->err_data_flags[i];
+        }
+    }
+    return ret;
+}
+
+void ERR_error_string_n(unsigned long e, char *buf, size_t len)
+{
+    char lsbuf[64], fsbuf[64], rsbuf[64];
+    const char *ls, *fs, *rs;
+    unsigned long l, f, r;
+
+    if (len == 0)
+        return;
+
+    l = ERR_GET_LIB(e);
+    f = ERR_GET_FUNC(e);
+    r = ERR_GET_REASON(e);
+
+    ls = ERR_lib_error_string(e);
+    fs = ERR_func_error_string(e);
+    rs = ERR_reason_error_string(e);
+
+    if (ls == NULL)
+        BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l);
+    if (fs == NULL)
+        BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f);
+    if (rs == NULL)
+        BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r);
+
+    BIO_snprintf(buf, len, "error:%08lX:%s:%s:%s", e, ls ? ls : lsbuf,
+                 fs ? fs : fsbuf, rs ? rs : rsbuf);
+    if (strlen(buf) == len - 1) {
+        /*
+         * output may be truncated; make sure we always have 5
+         * colon-separated fields, i.e. 4 colons ...
+         */
+#define NUM_COLONS 4
+        if (len > NUM_COLONS) { /* ... if possible */
+            int i;
+            char *s = buf;
+
+            for (i = 0; i < NUM_COLONS; i++) {
+                char *colon = strchr(s, ':');
+                if (colon == NULL || colon > &buf[len - 1] - NUM_COLONS + i) {
+                    /*
+                     * set colon no. i at last possible position (buf[len-1]
+                     * is the terminating 0)
+                     */
+                    colon = &buf[len - 1] - NUM_COLONS + i;
+                    *colon = ':';
+                }
+                s = colon + 1;
+            }
+        }
+    }
+}
+
+/*
+ * ERR_error_string_n should be used instead for ret != NULL as
+ * ERR_error_string cannot know how large the buffer is
+ */
+char *ERR_error_string(unsigned long e, char *ret)
+{
+    static char buf[256];
+
+    if (ret == NULL)
+        ret = buf;
+    ERR_error_string_n(e, ret, 256);
+
+    return ret;
+}
+
+const char *ERR_lib_error_string(unsigned long e)
+{
+    ERR_STRING_DATA d, *p;
+    unsigned long l;
+
+    if (!RUN_ONCE(&err_string_init, do_err_strings_init)) {
+        return NULL;
+    }
+
+    l = ERR_GET_LIB(e);
+    d.error = ERR_PACK(l, 0, 0);
+    p = int_err_get_item(&d);
+    return ((p == NULL) ? NULL : p->string);
+}
+
+const char *ERR_func_error_string(unsigned long e)
+{
+    ERR_STRING_DATA d, *p;
+    unsigned long l, f;
+
+    if (!RUN_ONCE(&err_string_init, do_err_strings_init)) {
+        return NULL;
+    }
+
+    l = ERR_GET_LIB(e);
+    f = ERR_GET_FUNC(e);
+    d.error = ERR_PACK(l, f, 0);
+    p = int_err_get_item(&d);
+    return ((p == NULL) ? NULL : p->string);
+}
+
+const char *ERR_reason_error_string(unsigned long e)
+{
+    ERR_STRING_DATA d, *p = NULL;
+    unsigned long l, r;
+
+    if (!RUN_ONCE(&err_string_init, do_err_strings_init)) {
+        return NULL;
+    }
+
+    l = ERR_GET_LIB(e);
+    r = ERR_GET_REASON(e);
+    d.error = ERR_PACK(l, 0, r);
+    p = int_err_get_item(&d);
+    if (!p) {
+        d.error = ERR_PACK(0, 0, r);
+        p = int_err_get_item(&d);
+    }
+    return ((p == NULL) ? NULL : p->string);
+}
+
+void err_delete_thread_state(void)
+{
+    ERR_STATE *state = ERR_get_state();
+    if (state == NULL)
+        return;
+
+    CRYPTO_THREAD_set_local(&err_thread_local, NULL);
+    ERR_STATE_free(state);
+}
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+void ERR_remove_thread_state(void *dummy)
+{
+}
+#endif
+
+#if OPENSSL_API_COMPAT < 0x10000000L
+void ERR_remove_state(unsigned long pid)
+{
+}
+#endif
+
+DEFINE_RUN_ONCE_STATIC(err_do_init)
+{
+    return CRYPTO_THREAD_init_local(&err_thread_local, NULL);
+}
+
+ERR_STATE *ERR_get_state(void)
+{
+    ERR_STATE *state = NULL;
+
+    if (!RUN_ONCE(&err_init, err_do_init))
+        return NULL;
+
+    state = CRYPTO_THREAD_get_local(&err_thread_local);
+
+    if (state == NULL) {
+        state = OPENSSL_zalloc(sizeof(*state));
+        if (state == NULL)
+            return NULL;
+
+        if (!CRYPTO_THREAD_set_local(&err_thread_local, state)) {
+            ERR_STATE_free(state);
+            return NULL;
+        }
+
+        /* Ignore failures from these */
+        OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
+        ossl_init_thread_start(OPENSSL_INIT_THREAD_ERR_STATE);
+    }
+
+    return state;
+}
+
+int ERR_get_next_error_library(void)
+{
+    int ret;
+
+    if (!RUN_ONCE(&err_string_init, do_err_strings_init)) {
+        return 0;
+    }
+
+    CRYPTO_THREAD_write_lock(err_string_lock);
+    ret = int_err_library_number++;
+    CRYPTO_THREAD_unlock(err_string_lock);
+    return ret;
+}
+
+void ERR_set_error_data(char *data, int flags)
+{
+    ERR_STATE *es;
+    int i;
+
+    es = ERR_get_state();
+
+    i = es->top;
+    if (i == 0)
+        i = ERR_NUM_ERRORS - 1;
+
+    err_clear_data(es, i);
+    es->err_data[i] = data;
+    es->err_data_flags[i] = flags;
+}
+
+void ERR_add_error_data(int num, ...)
+{
+    va_list args;
+    va_start(args, num);
+    ERR_add_error_vdata(num, args);
+    va_end(args);
+}
+
+void ERR_add_error_vdata(int num, va_list args)
+{
+    int i, n, s;
+    char *str, *p, *a;
+
+    s = 80;
+    str = OPENSSL_malloc(s + 1);
+    if (str == NULL)
+        return;
+    str[0] = '\0';
+
+    n = 0;
+    for (i = 0; i < num; i++) {
+        a = va_arg(args, char *);
+        /* ignore NULLs, thanks to Bob Beck <beck@obtuse.com> */
+        if (a != NULL) {
+            n += strlen(a);
+            if (n > s) {
+                s = n + 20;
+                p = OPENSSL_realloc(str, s + 1);
+                if (p == NULL) {
+                    OPENSSL_free(str);
+                    return;
+                }
+                str = p;
+            }
+            OPENSSL_strlcat(str, a, (size_t)s + 1);
+        }
+    }
+    ERR_set_error_data(str, ERR_TXT_MALLOCED | ERR_TXT_STRING);
+}
+
+int ERR_set_mark(void)
+{
+    ERR_STATE *es;
+
+    es = ERR_get_state();
+
+    if (es->bottom == es->top)
+        return 0;
+    es->err_flags[es->top] |= ERR_FLAG_MARK;
+    return 1;
+}
+
+int ERR_pop_to_mark(void)
+{
+    ERR_STATE *es;
+
+    es = ERR_get_state();
+
+    while (es->bottom != es->top
+           && (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) {
+        err_clear(es, es->top);
+        es->top -= 1;
+        if (es->top == -1)
+            es->top = ERR_NUM_ERRORS - 1;
+    }
+
+    if (es->bottom == es->top)
+        return 0;
+    es->err_flags[es->top] &= ~ERR_FLAG_MARK;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/err/err_all.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/err/err_all.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/err/err_all.c	(revision 331)
@@ -0,0 +1,109 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/err_int.h"
+#include <openssl/asn1.h>
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/buffer.h>
+#include <openssl/bio.h>
+#include <openssl/comp.h>
+#include <openssl/rsa.h>
+#include <openssl/dh.h>
+#include <openssl/dsa.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/pem2.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/conf.h>
+#include <openssl/pkcs12.h>
+#include <openssl/rand.h>
+#include "internal/dso.h"
+#include <openssl/engine.h>
+#include <openssl/ui.h>
+#include <openssl/ocsp.h>
+#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+#include <openssl/ts.h>
+#include <openssl/cms.h>
+#include <openssl/ct.h>
+#include <openssl/async.h>
+#include <openssl/kdf.h>
+
+int err_load_crypto_strings_int(void)
+{
+    if (
+#ifdef OPENSSL_FIPS
+        FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata) == 0 ||
+#endif
+#ifndef OPENSSL_NO_ERR
+        ERR_load_ERR_strings() == 0 ||    /* include error strings for SYSerr */
+        ERR_load_BN_strings() == 0 ||
+# ifndef OPENSSL_NO_RSA
+        ERR_load_RSA_strings() == 0 ||
+# endif
+# ifndef OPENSSL_NO_DH
+        ERR_load_DH_strings() == 0 ||
+# endif
+        ERR_load_EVP_strings() == 0 ||
+        ERR_load_BUF_strings() == 0 ||
+        ERR_load_OBJ_strings() == 0 ||
+        ERR_load_PEM_strings() == 0 ||
+# ifndef OPENSSL_NO_DSA
+        ERR_load_DSA_strings() == 0 ||
+# endif
+        ERR_load_X509_strings() == 0 ||
+        ERR_load_ASN1_strings() == 0 ||
+        ERR_load_CONF_strings() == 0 ||
+        ERR_load_CRYPTO_strings() == 0 ||
+# ifndef OPENSSL_NO_COMP
+        ERR_load_COMP_strings() == 0 ||
+# endif
+# ifndef OPENSSL_NO_EC
+        ERR_load_EC_strings() == 0 ||
+# endif
+        /* skip ERR_load_SSL_strings() because it is not in this library */
+        ERR_load_BIO_strings() == 0 ||
+        ERR_load_PKCS7_strings() == 0 ||
+        ERR_load_X509V3_strings() == 0 ||
+        ERR_load_PKCS12_strings() == 0 ||
+        ERR_load_RAND_strings() == 0 ||
+        ERR_load_DSO_strings() == 0 ||
+# ifndef OPENSSL_NO_TS
+        ERR_load_TS_strings() == 0 ||
+# endif
+# ifndef OPENSSL_NO_ENGINE
+        ERR_load_ENGINE_strings() == 0 ||
+# endif
+# ifndef OPENSSL_NO_OCSP
+        ERR_load_OCSP_strings() == 0 ||
+# endif
+#ifndef OPENSSL_NO_UI
+        ERR_load_UI_strings() == 0 ||
+#endif
+# ifdef OPENSSL_FIPS
+        ERR_load_FIPS_strings() == 0 ||
+# endif
+# ifndef OPENSSL_NO_CMS
+        ERR_load_CMS_strings() == 0 ||
+# endif
+# ifndef OPENSSL_NO_CT
+        ERR_load_CT_strings() == 0 ||
+# endif
+        ERR_load_ASYNC_strings() == 0 ||
+#endif
+        ERR_load_KDF_strings() == 0)
+        return 0;
+
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/err/err_prn.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/err/err_prn.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/err/err_prn.c	(revision 331)
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+
+void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u),
+                         void *u)
+{
+    unsigned long l;
+    char buf[256];
+    char buf2[4096];
+    const char *file, *data;
+    int line, flags;
+    /*
+     * We don't know what kind of thing CRYPTO_THREAD_ID is. Here is our best
+     * attempt to convert it into something we can print.
+     */
+    union {
+        CRYPTO_THREAD_ID tid;
+        unsigned long ltid;
+    } tid;
+
+    tid.ltid = 0;
+    tid.tid = CRYPTO_THREAD_get_current_id();
+
+    while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) {
+        ERR_error_string_n(l, buf, sizeof buf);
+        BIO_snprintf(buf2, sizeof(buf2), "%lu:%s:%s:%d:%s\n", tid.ltid, buf,
+                     file, line, (flags & ERR_TXT_STRING) ? data : "");
+        if (cb(buf2, strlen(buf2), u) <= 0)
+            break;              /* abort outputting the error report */
+    }
+}
+
+static int print_bio(const char *str, size_t len, void *bp)
+{
+    return BIO_write((BIO *)bp, str, len);
+}
+
+void ERR_print_errors(BIO *bp)
+{
+    ERR_print_errors_cb(print_bio, bp);
+}
+
+#ifndef OPENSSL_NO_STDIO
+void ERR_print_errors_fp(FILE *fp)
+{
+    BIO *bio = BIO_new_fp(fp, BIO_NOCLOSE);
+    if (bio == NULL)
+        return;
+
+    ERR_print_errors_cb(print_bio, bio);
+    BIO_free(bio);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/bio_b64.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/bio_b64.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/bio_b64.c	(revision 331)
@@ -0,0 +1,542 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <errno.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+#include "internal/bio.h"
+
+static int b64_write(BIO *h, const char *buf, int num);
+static int b64_read(BIO *h, char *buf, int size);
+static int b64_puts(BIO *h, const char *str);
+/*
+ * static int b64_gets(BIO *h, char *str, int size);
+ */
+static long b64_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int b64_new(BIO *h);
+static int b64_free(BIO *data);
+static long b64_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+#define B64_BLOCK_SIZE  1024
+#define B64_BLOCK_SIZE2 768
+#define B64_NONE        0
+#define B64_ENCODE      1
+#define B64_DECODE      2
+
+typedef struct b64_struct {
+    /*
+     * BIO *bio; moved to the BIO structure
+     */
+    int buf_len;
+    int buf_off;
+    int tmp_len;                /* used to find the start when decoding */
+    int tmp_nl;                 /* If true, scan until '\n' */
+    int encode;
+    int start;                  /* have we started decoding yet? */
+    int cont;                   /* <= 0 when finished */
+    EVP_ENCODE_CTX *base64;
+    char buf[EVP_ENCODE_LENGTH(B64_BLOCK_SIZE) + 10];
+    char tmp[B64_BLOCK_SIZE];
+} BIO_B64_CTX;
+
+static const BIO_METHOD methods_b64 = {
+    BIO_TYPE_BASE64, "base64 encoding",
+    b64_write,
+    b64_read,
+    b64_puts,
+    NULL,                       /* b64_gets, */
+    b64_ctrl,
+    b64_new,
+    b64_free,
+    b64_callback_ctrl,
+};
+
+
+const BIO_METHOD *BIO_f_base64(void)
+{
+    return &methods_b64;
+}
+
+static int b64_new(BIO *bi)
+{
+    BIO_B64_CTX *ctx;
+
+    ctx = OPENSSL_zalloc(sizeof(*ctx));
+    if (ctx == NULL)
+        return 0;
+
+    ctx->cont = 1;
+    ctx->start = 1;
+    ctx->base64 = EVP_ENCODE_CTX_new();
+    if (ctx->base64 == NULL) {
+        OPENSSL_free(ctx);
+        return 0;
+    }
+
+    BIO_set_data(bi, ctx);
+    BIO_set_init(bi, 1);
+
+    return 1;
+}
+
+static int b64_free(BIO *a)
+{
+    BIO_B64_CTX *ctx;
+    if (a == NULL)
+        return 0;
+
+    ctx = BIO_get_data(a);
+    if (ctx == NULL)
+        return 0;
+
+    EVP_ENCODE_CTX_free(ctx->base64);
+    OPENSSL_free(ctx);
+    BIO_set_data(a, NULL);
+    BIO_set_init(a, 0);
+
+    return 1;
+}
+
+static int b64_read(BIO *b, char *out, int outl)
+{
+    int ret = 0, i, ii, j, k, x, n, num, ret_code = 0;
+    BIO_B64_CTX *ctx;
+    unsigned char *p, *q;
+    BIO *next;
+
+    if (out == NULL)
+        return (0);
+    ctx = (BIO_B64_CTX *)BIO_get_data(b);
+
+    next = BIO_next(b);
+    if ((ctx == NULL) || (next == NULL))
+        return 0;
+
+    BIO_clear_retry_flags(b);
+
+    if (ctx->encode != B64_DECODE) {
+        ctx->encode = B64_DECODE;
+        ctx->buf_len = 0;
+        ctx->buf_off = 0;
+        ctx->tmp_len = 0;
+        EVP_DecodeInit(ctx->base64);
+    }
+
+    /* First check if there are bytes decoded/encoded */
+    if (ctx->buf_len > 0) {
+        OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+        i = ctx->buf_len - ctx->buf_off;
+        if (i > outl)
+            i = outl;
+        OPENSSL_assert(ctx->buf_off + i < (int)sizeof(ctx->buf));
+        memcpy(out, &(ctx->buf[ctx->buf_off]), i);
+        ret = i;
+        out += i;
+        outl -= i;
+        ctx->buf_off += i;
+        if (ctx->buf_len == ctx->buf_off) {
+            ctx->buf_len = 0;
+            ctx->buf_off = 0;
+        }
+    }
+
+    /*
+     * At this point, we have room of outl bytes and an empty buffer, so we
+     * should read in some more.
+     */
+
+    ret_code = 0;
+    while (outl > 0) {
+        if (ctx->cont <= 0)
+            break;
+
+        i = BIO_read(next, &(ctx->tmp[ctx->tmp_len]),
+                     B64_BLOCK_SIZE - ctx->tmp_len);
+
+        if (i <= 0) {
+            ret_code = i;
+
+            /* Should we continue next time we are called? */
+            if (!BIO_should_retry(next)) {
+                ctx->cont = i;
+                /* If buffer empty break */
+                if (ctx->tmp_len == 0)
+                    break;
+                /* Fall through and process what we have */
+                else
+                    i = 0;
+            }
+            /* else we retry and add more data to buffer */
+            else
+                break;
+        }
+        i += ctx->tmp_len;
+        ctx->tmp_len = i;
+
+        /*
+         * We need to scan, a line at a time until we have a valid line if we
+         * are starting.
+         */
+        if (ctx->start && (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)) {
+            /* ctx->start=1; */
+            ctx->tmp_len = 0;
+        } else if (ctx->start) {
+            q = p = (unsigned char *)ctx->tmp;
+            num = 0;
+            for (j = 0; j < i; j++) {
+                if (*(q++) != '\n')
+                    continue;
+
+                /*
+                 * due to a previous very long line, we need to keep on
+                 * scanning for a '\n' before we even start looking for
+                 * base64 encoded stuff.
+                 */
+                if (ctx->tmp_nl) {
+                    p = q;
+                    ctx->tmp_nl = 0;
+                    continue;
+                }
+
+                k = EVP_DecodeUpdate(ctx->base64,
+                                     (unsigned char *)ctx->buf,
+                                     &num, p, q - p);
+                if ((k <= 0) && (num == 0) && (ctx->start))
+                    EVP_DecodeInit(ctx->base64);
+                else {
+                    if (p != (unsigned char *)
+                        &(ctx->tmp[0])) {
+                        i -= (p - (unsigned char *)
+                              &(ctx->tmp[0]));
+                        for (x = 0; x < i; x++)
+                            ctx->tmp[x] = p[x];
+                    }
+                    EVP_DecodeInit(ctx->base64);
+                    ctx->start = 0;
+                    break;
+                }
+                p = q;
+            }
+
+            /* we fell off the end without starting */
+            if ((j == i) && (num == 0)) {
+                /*
+                 * Is this is one long chunk?, if so, keep on reading until a
+                 * new line.
+                 */
+                if (p == (unsigned char *)&(ctx->tmp[0])) {
+                    /* Check buffer full */
+                    if (i == B64_BLOCK_SIZE) {
+                        ctx->tmp_nl = 1;
+                        ctx->tmp_len = 0;
+                    }
+                } else if (p != q) { /* finished on a '\n' */
+                    n = q - p;
+                    for (ii = 0; ii < n; ii++)
+                        ctx->tmp[ii] = p[ii];
+                    ctx->tmp_len = n;
+                }
+                /* else finished on a '\n' */
+                continue;
+            } else {
+                ctx->tmp_len = 0;
+            }
+        } else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0)) {
+            /*
+             * If buffer isn't full and we can retry then restart to read in
+             * more data.
+             */
+            continue;
+        }
+
+        if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
+            int z, jj;
+
+            jj = i & ~3;        /* process per 4 */
+            z = EVP_DecodeBlock((unsigned char *)ctx->buf,
+                                (unsigned char *)ctx->tmp, jj);
+            if (jj > 2) {
+                if (ctx->tmp[jj - 1] == '=') {
+                    z--;
+                    if (ctx->tmp[jj - 2] == '=')
+                        z--;
+                }
+            }
+            /*
+             * z is now number of output bytes and jj is the number consumed
+             */
+            if (jj != i) {
+                memmove(ctx->tmp, &ctx->tmp[jj], i - jj);
+                ctx->tmp_len = i - jj;
+            }
+            ctx->buf_len = 0;
+            if (z > 0) {
+                ctx->buf_len = z;
+            }
+            i = z;
+        } else {
+            i = EVP_DecodeUpdate(ctx->base64,
+                                 (unsigned char *)ctx->buf, &ctx->buf_len,
+                                 (unsigned char *)ctx->tmp, i);
+            ctx->tmp_len = 0;
+        }
+        ctx->buf_off = 0;
+        if (i < 0) {
+            ret_code = 0;
+            ctx->buf_len = 0;
+            break;
+        }
+
+        if (ctx->buf_len <= outl)
+            i = ctx->buf_len;
+        else
+            i = outl;
+
+        memcpy(out, ctx->buf, i);
+        ret += i;
+        ctx->buf_off = i;
+        if (ctx->buf_off == ctx->buf_len) {
+            ctx->buf_len = 0;
+            ctx->buf_off = 0;
+        }
+        outl -= i;
+        out += i;
+    }
+    /* BIO_clear_retry_flags(b); */
+    BIO_copy_next_retry(b);
+    return ((ret == 0) ? ret_code : ret);
+}
+
+static int b64_write(BIO *b, const char *in, int inl)
+{
+    int ret = 0;
+    int n;
+    int i;
+    BIO_B64_CTX *ctx;
+    BIO *next;
+
+    ctx = (BIO_B64_CTX *)BIO_get_data(b);
+    next = BIO_next(b);
+    if ((ctx == NULL) || (next == NULL))
+        return 0;
+
+    BIO_clear_retry_flags(b);
+
+    if (ctx->encode != B64_ENCODE) {
+        ctx->encode = B64_ENCODE;
+        ctx->buf_len = 0;
+        ctx->buf_off = 0;
+        ctx->tmp_len = 0;
+        EVP_EncodeInit(ctx->base64);
+    }
+
+    OPENSSL_assert(ctx->buf_off < (int)sizeof(ctx->buf));
+    OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+    OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+    n = ctx->buf_len - ctx->buf_off;
+    while (n > 0) {
+        i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n);
+        if (i <= 0) {
+            BIO_copy_next_retry(b);
+            return (i);
+        }
+        OPENSSL_assert(i <= n);
+        ctx->buf_off += i;
+        OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
+        OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+        n -= i;
+    }
+    /* at this point all pending data has been written */
+    ctx->buf_off = 0;
+    ctx->buf_len = 0;
+
+    if ((in == NULL) || (inl <= 0))
+        return (0);
+
+    while (inl > 0) {
+        n = (inl > B64_BLOCK_SIZE) ? B64_BLOCK_SIZE : inl;
+
+        if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
+            if (ctx->tmp_len > 0) {
+                OPENSSL_assert(ctx->tmp_len <= 3);
+                n = 3 - ctx->tmp_len;
+                /*
+                 * There's a theoretical possibility for this
+                 */
+                if (n > inl)
+                    n = inl;
+                memcpy(&(ctx->tmp[ctx->tmp_len]), in, n);
+                ctx->tmp_len += n;
+                ret += n;
+                if (ctx->tmp_len < 3)
+                    break;
+                ctx->buf_len =
+                    EVP_EncodeBlock((unsigned char *)ctx->buf,
+                                    (unsigned char *)ctx->tmp, ctx->tmp_len);
+                OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+                OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+                /*
+                 * Since we're now done using the temporary buffer, the
+                 * length should be 0'd
+                 */
+                ctx->tmp_len = 0;
+            } else {
+                if (n < 3) {
+                    memcpy(ctx->tmp, in, n);
+                    ctx->tmp_len = n;
+                    ret += n;
+                    break;
+                }
+                n -= n % 3;
+                ctx->buf_len =
+                    EVP_EncodeBlock((unsigned char *)ctx->buf,
+                                    (const unsigned char *)in, n);
+                OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+                OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+                ret += n;
+            }
+        } else {
+            if (!EVP_EncodeUpdate(ctx->base64,
+                                 (unsigned char *)ctx->buf, &ctx->buf_len,
+                                 (unsigned char *)in, n))
+                return ((ret == 0) ? -1 : ret);
+            OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+            OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+            ret += n;
+        }
+        inl -= n;
+        in += n;
+
+        ctx->buf_off = 0;
+        n = ctx->buf_len;
+        while (n > 0) {
+            i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n);
+            if (i <= 0) {
+                BIO_copy_next_retry(b);
+                return ((ret == 0) ? i : ret);
+            }
+            OPENSSL_assert(i <= n);
+            n -= i;
+            ctx->buf_off += i;
+            OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
+            OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+        }
+        ctx->buf_len = 0;
+        ctx->buf_off = 0;
+    }
+    return (ret);
+}
+
+static long b64_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    BIO_B64_CTX *ctx;
+    long ret = 1;
+    int i;
+    BIO *next;
+
+    ctx = (BIO_B64_CTX *)BIO_get_data(b);
+    next = BIO_next(b);
+    if ((ctx == NULL) || (next == NULL))
+        return 0;
+
+    switch (cmd) {
+    case BIO_CTRL_RESET:
+        ctx->cont = 1;
+        ctx->start = 1;
+        ctx->encode = B64_NONE;
+        ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+    case BIO_CTRL_EOF:         /* More to read */
+        if (ctx->cont <= 0)
+            ret = 1;
+        else
+            ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+    case BIO_CTRL_WPENDING:    /* More to write in buffer */
+        OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+        ret = ctx->buf_len - ctx->buf_off;
+        if ((ret == 0) && (ctx->encode != B64_NONE)
+            && (EVP_ENCODE_CTX_num(ctx->base64) != 0))
+            ret = 1;
+        else if (ret <= 0)
+            ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+    case BIO_CTRL_PENDING:     /* More to read in buffer */
+        OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
+        ret = ctx->buf_len - ctx->buf_off;
+        if (ret <= 0)
+            ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+    case BIO_CTRL_FLUSH:
+        /* do a final write */
+ again:
+        while (ctx->buf_len != ctx->buf_off) {
+            i = b64_write(b, NULL, 0);
+            if (i < 0)
+                return i;
+        }
+        if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
+            if (ctx->tmp_len != 0) {
+                ctx->buf_len = EVP_EncodeBlock((unsigned char *)ctx->buf,
+                                               (unsigned char *)ctx->tmp,
+                                               ctx->tmp_len);
+                ctx->buf_off = 0;
+                ctx->tmp_len = 0;
+                goto again;
+            }
+        } else if (ctx->encode != B64_NONE
+                   && EVP_ENCODE_CTX_num(ctx->base64) != 0) {
+            ctx->buf_off = 0;
+            EVP_EncodeFinal(ctx->base64,
+                            (unsigned char *)ctx->buf, &(ctx->buf_len));
+            /* push out the bytes */
+            goto again;
+        }
+        /* Finally flush the underlying BIO */
+        ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+
+    case BIO_C_DO_STATE_MACHINE:
+        BIO_clear_retry_flags(b);
+        ret = BIO_ctrl(next, cmd, num, ptr);
+        BIO_copy_next_retry(b);
+        break;
+
+    case BIO_CTRL_DUP:
+        break;
+    case BIO_CTRL_INFO:
+    case BIO_CTRL_GET:
+    case BIO_CTRL_SET:
+    default:
+        ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+    }
+    return ret;
+}
+
+static long b64_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+    long ret = 1;
+    BIO *next = BIO_next(b);
+
+    if (next == NULL)
+        return 0;
+    switch (cmd) {
+    default:
+        ret = BIO_callback_ctrl(next, cmd, fp);
+        break;
+    }
+    return (ret);
+}
+
+static int b64_puts(BIO *b, const char *str)
+{
+    return b64_write(b, str, strlen(str));
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/bio_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/bio_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/bio_enc.c	(revision 331)
@@ -0,0 +1,449 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <errno.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+#include "internal/bio.h"
+
+static int enc_write(BIO *h, const char *buf, int num);
+static int enc_read(BIO *h, char *buf, int size);
+/*
+ * static int enc_puts(BIO *h, const char *str);
+ */
+/*
+ * static int enc_gets(BIO *h, char *str, int size);
+ */
+static long enc_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int enc_new(BIO *h);
+static int enc_free(BIO *data);
+static long enc_callback_ctrl(BIO *h, int cmd, bio_info_cb *fps);
+#define ENC_BLOCK_SIZE  (1024*4)
+#define ENC_MIN_CHUNK   (256)
+#define BUF_OFFSET      (ENC_MIN_CHUNK + EVP_MAX_BLOCK_LENGTH)
+
+typedef struct enc_struct {
+    int buf_len;
+    int buf_off;
+    int cont;                   /* <= 0 when finished */
+    int finished;
+    int ok;                     /* bad decrypt */
+    EVP_CIPHER_CTX *cipher;
+    unsigned char *read_start, *read_end;
+    /*
+     * buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate can return
+     * up to a block more data than is presented to it
+     */
+    unsigned char buf[BUF_OFFSET + ENC_BLOCK_SIZE];
+} BIO_ENC_CTX;
+
+static const BIO_METHOD methods_enc = {
+    BIO_TYPE_CIPHER, "cipher",
+    enc_write,
+    enc_read,
+    NULL,                       /* enc_puts, */
+    NULL,                       /* enc_gets, */
+    enc_ctrl,
+    enc_new,
+    enc_free,
+    enc_callback_ctrl,
+};
+
+const BIO_METHOD *BIO_f_cipher(void)
+{
+    return (&methods_enc);
+}
+
+static int enc_new(BIO *bi)
+{
+    BIO_ENC_CTX *ctx;
+
+    ctx = OPENSSL_zalloc(sizeof(*ctx));
+    if (ctx == NULL)
+        return 0;
+
+    ctx->cipher = EVP_CIPHER_CTX_new();
+    if (ctx->cipher == NULL) {
+        OPENSSL_free(ctx);
+        return 0;
+    }
+    ctx->cont = 1;
+    ctx->ok = 1;
+    ctx->read_end = ctx->read_start = &(ctx->buf[BUF_OFFSET]);
+    BIO_set_data(bi, ctx);
+    BIO_set_init(bi, 1);
+
+    return 1;
+}
+
+static int enc_free(BIO *a)
+{
+    BIO_ENC_CTX *b;
+
+    if (a == NULL)
+        return 0;
+
+    b = BIO_get_data(a);
+    if (b == NULL)
+        return 0;
+
+    EVP_CIPHER_CTX_free(b->cipher);
+    OPENSSL_clear_free(b, sizeof(BIO_ENC_CTX));
+    BIO_set_data(a, NULL);
+    BIO_set_init(a, 0);
+
+    return 1;
+}
+
+static int enc_read(BIO *b, char *out, int outl)
+{
+    int ret = 0, i, blocksize;
+    BIO_ENC_CTX *ctx;
+    BIO *next;
+
+    if (out == NULL)
+        return (0);
+    ctx = BIO_get_data(b);
+
+    next = BIO_next(b);
+    if ((ctx == NULL) || (next == NULL))
+        return 0;
+
+    /* First check if there are bytes decoded/encoded */
+    if (ctx->buf_len > 0) {
+        i = ctx->buf_len - ctx->buf_off;
+        if (i > outl)
+            i = outl;
+        memcpy(out, &(ctx->buf[ctx->buf_off]), i);
+        ret = i;
+        out += i;
+        outl -= i;
+        ctx->buf_off += i;
+        if (ctx->buf_len == ctx->buf_off) {
+            ctx->buf_len = 0;
+            ctx->buf_off = 0;
+        }
+    }
+
+    blocksize = EVP_CIPHER_CTX_block_size(ctx->cipher);
+    if (blocksize == 1)
+        blocksize = 0;
+
+    /*
+     * At this point, we have room of outl bytes and an empty buffer, so we
+     * should read in some more.
+     */
+
+    while (outl > 0) {
+        if (ctx->cont <= 0)
+            break;
+
+        if (ctx->read_start == ctx->read_end) { /* time to read more data */
+            ctx->read_end = ctx->read_start = &(ctx->buf[BUF_OFFSET]);
+            i = BIO_read(next, ctx->read_start, ENC_BLOCK_SIZE);
+            if (i > 0)
+                ctx->read_end += i;
+        } else {
+            i = ctx->read_end - ctx->read_start;
+        }
+
+        if (i <= 0) {
+            /* Should be continue next time we are called? */
+            if (!BIO_should_retry(next)) {
+                ctx->cont = i;
+                i = EVP_CipherFinal_ex(ctx->cipher,
+                                       ctx->buf, &(ctx->buf_len));
+                ctx->ok = i;
+                ctx->buf_off = 0;
+            } else {
+                ret = (ret == 0) ? i : ret;
+                break;
+            }
+        } else {
+            if (outl > ENC_MIN_CHUNK) {
+                /*
+                 * Depending on flags block cipher decrypt can write
+                 * one extra block and then back off, i.e. output buffer
+                 * has to accommodate extra block...
+                 */
+                int j = outl - blocksize, buf_len;
+
+                if (!EVP_CipherUpdate(ctx->cipher,
+                                      (unsigned char *)out, &buf_len,
+                                      ctx->read_start, i > j ? j : i)) {
+                    BIO_clear_retry_flags(b);
+                    return 0;
+                }
+                ret += buf_len;
+                out += buf_len;
+                outl -= buf_len;
+
+                if ((i -= j) <= 0) {
+                    ctx->read_start = ctx->read_end;
+                    continue;
+                }
+                ctx->read_start += j;
+            }
+            if (i > ENC_MIN_CHUNK)
+                i = ENC_MIN_CHUNK;
+            if (!EVP_CipherUpdate(ctx->cipher,
+                                  ctx->buf, &ctx->buf_len,
+                                  ctx->read_start, i)) {
+                BIO_clear_retry_flags(b);
+                ctx->ok = 0;
+                return 0;
+            }
+            ctx->read_start += i;
+            ctx->cont = 1;
+            /*
+             * Note: it is possible for EVP_CipherUpdate to decrypt zero
+             * bytes because this is or looks like the final block: if this
+             * happens we should retry and either read more data or decrypt
+             * the final block
+             */
+            if (ctx->buf_len == 0)
+                continue;
+        }
+
+        if (ctx->buf_len <= outl)
+            i = ctx->buf_len;
+        else
+            i = outl;
+        if (i <= 0)
+            break;
+        memcpy(out, ctx->buf, i);
+        ret += i;
+        ctx->buf_off = i;
+        outl -= i;
+        out += i;
+    }
+
+    BIO_clear_retry_flags(b);
+    BIO_copy_next_retry(b);
+    return ((ret == 0) ? ctx->cont : ret);
+}
+
+static int enc_write(BIO *b, const char *in, int inl)
+{
+    int ret = 0, n, i;
+    BIO_ENC_CTX *ctx;
+    BIO *next;
+
+    ctx = BIO_get_data(b);
+    next = BIO_next(b);
+    if ((ctx == NULL) || (next == NULL))
+        return 0;
+
+    ret = inl;
+
+    BIO_clear_retry_flags(b);
+    n = ctx->buf_len - ctx->buf_off;
+    while (n > 0) {
+        i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n);
+        if (i <= 0) {
+            BIO_copy_next_retry(b);
+            return (i);
+        }
+        ctx->buf_off += i;
+        n -= i;
+    }
+    /* at this point all pending data has been written */
+
+    if ((in == NULL) || (inl <= 0))
+        return (0);
+
+    ctx->buf_off = 0;
+    while (inl > 0) {
+        n = (inl > ENC_BLOCK_SIZE) ? ENC_BLOCK_SIZE : inl;
+        if (!EVP_CipherUpdate(ctx->cipher,
+                              ctx->buf, &ctx->buf_len,
+                              (const unsigned char *)in, n)) {
+            BIO_clear_retry_flags(b);
+            ctx->ok = 0;
+            return 0;
+        }
+        inl -= n;
+        in += n;
+
+        ctx->buf_off = 0;
+        n = ctx->buf_len;
+        while (n > 0) {
+            i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n);
+            if (i <= 0) {
+                BIO_copy_next_retry(b);
+                return (ret == inl) ? i : ret - inl;
+            }
+            n -= i;
+            ctx->buf_off += i;
+        }
+        ctx->buf_len = 0;
+        ctx->buf_off = 0;
+    }
+    BIO_copy_next_retry(b);
+    return (ret);
+}
+
+static long enc_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    BIO *dbio;
+    BIO_ENC_CTX *ctx, *dctx;
+    long ret = 1;
+    int i;
+    EVP_CIPHER_CTX **c_ctx;
+    BIO *next;
+
+    ctx = BIO_get_data(b);
+    next = BIO_next(b);
+    if (ctx == NULL)
+        return 0;
+
+    switch (cmd) {
+    case BIO_CTRL_RESET:
+        ctx->ok = 1;
+        ctx->finished = 0;
+        if (!EVP_CipherInit_ex(ctx->cipher, NULL, NULL, NULL, NULL,
+                               EVP_CIPHER_CTX_encrypting(ctx->cipher)))
+            return 0;
+        ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+    case BIO_CTRL_EOF:         /* More to read */
+        if (ctx->cont <= 0)
+            ret = 1;
+        else
+            ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+    case BIO_CTRL_WPENDING:
+        ret = ctx->buf_len - ctx->buf_off;
+        if (ret <= 0)
+            ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+    case BIO_CTRL_PENDING:     /* More to read in buffer */
+        ret = ctx->buf_len - ctx->buf_off;
+        if (ret <= 0)
+            ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+    case BIO_CTRL_FLUSH:
+        /* do a final write */
+ again:
+        while (ctx->buf_len != ctx->buf_off) {
+            i = enc_write(b, NULL, 0);
+            if (i < 0)
+                return i;
+        }
+
+        if (!ctx->finished) {
+            ctx->finished = 1;
+            ctx->buf_off = 0;
+            ret = EVP_CipherFinal_ex(ctx->cipher,
+                                     (unsigned char *)ctx->buf,
+                                     &(ctx->buf_len));
+            ctx->ok = (int)ret;
+            if (ret <= 0)
+                break;
+
+            /* push out the bytes */
+            goto again;
+        }
+
+        /* Finally flush the underlying BIO */
+        ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+    case BIO_C_GET_CIPHER_STATUS:
+        ret = (long)ctx->ok;
+        break;
+    case BIO_C_DO_STATE_MACHINE:
+        BIO_clear_retry_flags(b);
+        ret = BIO_ctrl(next, cmd, num, ptr);
+        BIO_copy_next_retry(b);
+        break;
+    case BIO_C_GET_CIPHER_CTX:
+        c_ctx = (EVP_CIPHER_CTX **)ptr;
+        *c_ctx = ctx->cipher;
+        BIO_set_init(b, 1);
+        break;
+    case BIO_CTRL_DUP:
+        dbio = (BIO *)ptr;
+        dctx = BIO_get_data(dbio);
+        dctx->cipher = EVP_CIPHER_CTX_new();
+        if (dctx->cipher == NULL)
+            return 0;
+        ret = EVP_CIPHER_CTX_copy(dctx->cipher, ctx->cipher);
+        if (ret)
+            BIO_set_init(dbio, 1);
+        break;
+    default:
+        ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+    }
+    return (ret);
+}
+
+static long enc_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+    long ret = 1;
+    BIO *next = BIO_next(b);
+
+    if (next == NULL)
+        return (0);
+    switch (cmd) {
+    default:
+        ret = BIO_callback_ctrl(next, cmd, fp);
+        break;
+    }
+    return (ret);
+}
+
+/*-
+void BIO_set_cipher_ctx(b,c)
+BIO *b;
+EVP_CIPHER_ctx *c;
+        {
+        if (b == NULL) return;
+
+        if ((b->callback != NULL) &&
+                (b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0))
+                return;
+
+        b->init=1;
+        ctx=(BIO_ENC_CTX *)b->ptr;
+        memcpy(ctx->cipher,c,sizeof(EVP_CIPHER_CTX));
+
+        if (b->callback != NULL)
+                b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L);
+        }
+*/
+
+int BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
+                   const unsigned char *i, int e)
+{
+    BIO_ENC_CTX *ctx;
+    long (*callback) (struct bio_st *, int, const char *, int, long, long);
+
+    ctx = BIO_get_data(b);
+    if (ctx == NULL)
+        return 0;
+
+    callback = BIO_get_callback(b);
+
+    if ((callback != NULL) &&
+            (callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e,
+                      0L) <= 0))
+        return 0;
+
+    BIO_set_init(b, 1);
+
+    if (!EVP_CipherInit_ex(ctx->cipher, c, NULL, k, i, e))
+        return 0;
+
+    if (callback != NULL)
+        return callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 1L);
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/bio_md.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/bio_md.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/bio_md.c	(revision 331)
@@ -0,0 +1,231 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <errno.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+#include "internal/evp_int.h"
+#include "evp_locl.h"
+#include "internal/bio.h"
+
+/*
+ * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest
+ */
+
+static int md_write(BIO *h, char const *buf, int num);
+static int md_read(BIO *h, char *buf, int size);
+/*
+ * static int md_puts(BIO *h, const char *str);
+ */
+static int md_gets(BIO *h, char *str, int size);
+static long md_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int md_new(BIO *h);
+static int md_free(BIO *data);
+static long md_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+
+static const BIO_METHOD methods_md = {
+    BIO_TYPE_MD, "message digest",
+    md_write,
+    md_read,
+    NULL,                       /* md_puts, */
+    md_gets,
+    md_ctrl,
+    md_new,
+    md_free,
+    md_callback_ctrl,
+};
+
+const BIO_METHOD *BIO_f_md(void)
+{
+    return (&methods_md);
+}
+
+static int md_new(BIO *bi)
+{
+    EVP_MD_CTX *ctx;
+
+    ctx = EVP_MD_CTX_new();
+    if (ctx == NULL)
+        return (0);
+
+    BIO_set_init(bi, 1);
+    BIO_set_data(bi, ctx);
+
+    return 1;
+}
+
+static int md_free(BIO *a)
+{
+    if (a == NULL)
+        return (0);
+    EVP_MD_CTX_free(BIO_get_data(a));
+    BIO_set_data(a, NULL);
+    BIO_set_init(a, 0);
+
+    return 1;
+}
+
+static int md_read(BIO *b, char *out, int outl)
+{
+    int ret = 0;
+    EVP_MD_CTX *ctx;
+    BIO *next;
+
+    if (out == NULL)
+        return (0);
+
+    ctx = BIO_get_data(b);
+    next = BIO_next(b);
+
+    if ((ctx == NULL) || (next == NULL))
+        return (0);
+
+    ret = BIO_read(next, out, outl);
+    if (BIO_get_init(b)) {
+        if (ret > 0) {
+            if (EVP_DigestUpdate(ctx, (unsigned char *)out,
+                                 (unsigned int)ret) <= 0)
+                return (-1);
+        }
+    }
+    BIO_clear_retry_flags(b);
+    BIO_copy_next_retry(b);
+    return (ret);
+}
+
+static int md_write(BIO *b, const char *in, int inl)
+{
+    int ret = 0;
+    EVP_MD_CTX *ctx;
+    BIO *next;
+
+    if ((in == NULL) || (inl <= 0))
+        return 0;
+
+    ctx = BIO_get_data(b);
+    next = BIO_next(b);
+    if ((ctx != NULL) && (next != NULL))
+        ret = BIO_write(next, in, inl);
+
+    if (BIO_get_init(b)) {
+        if (ret > 0) {
+            if (!EVP_DigestUpdate(ctx, (const unsigned char *)in,
+                                  (unsigned int)ret)) {
+                BIO_clear_retry_flags(b);
+                return 0;
+            }
+        }
+    }
+    if (next != NULL) {
+        BIO_clear_retry_flags(b);
+        BIO_copy_next_retry(b);
+    }
+    return ret;
+}
+
+static long md_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    EVP_MD_CTX *ctx, *dctx, **pctx;
+    const EVP_MD **ppmd;
+    EVP_MD *md;
+    long ret = 1;
+    BIO *dbio, *next;
+
+
+    ctx = BIO_get_data(b);
+    next = BIO_next(b);
+
+    switch (cmd) {
+    case BIO_CTRL_RESET:
+        if (BIO_get_init(b))
+            ret = EVP_DigestInit_ex(ctx, ctx->digest, NULL);
+        else
+            ret = 0;
+        if (ret > 0)
+            ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+    case BIO_C_GET_MD:
+        if (BIO_get_init(b)) {
+            ppmd = ptr;
+            *ppmd = ctx->digest;
+        } else
+            ret = 0;
+        break;
+    case BIO_C_GET_MD_CTX:
+        pctx = ptr;
+        *pctx = ctx;
+        BIO_set_init(b, 1);
+        break;
+    case BIO_C_SET_MD_CTX:
+        if (BIO_get_init(b))
+            BIO_set_data(b, ptr);
+        else
+            ret = 0;
+        break;
+    case BIO_C_DO_STATE_MACHINE:
+        BIO_clear_retry_flags(b);
+        ret = BIO_ctrl(next, cmd, num, ptr);
+        BIO_copy_next_retry(b);
+        break;
+
+    case BIO_C_SET_MD:
+        md = ptr;
+        ret = EVP_DigestInit_ex(ctx, md, NULL);
+        if (ret > 0)
+            BIO_set_init(b, 1);
+        break;
+    case BIO_CTRL_DUP:
+        dbio = ptr;
+        dctx = BIO_get_data(dbio);
+        if (!EVP_MD_CTX_copy_ex(dctx, ctx))
+            return 0;
+        BIO_set_init(b, 1);
+        break;
+    default:
+        ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+    }
+    return (ret);
+}
+
+static long md_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+    long ret = 1;
+    BIO *next;
+
+    next = BIO_next(b);
+
+    if (next == NULL)
+        return 0;
+
+    switch (cmd) {
+    default:
+        ret = BIO_callback_ctrl(next, cmd, fp);
+        break;
+    }
+    return (ret);
+}
+
+static int md_gets(BIO *bp, char *buf, int size)
+{
+    EVP_MD_CTX *ctx;
+    unsigned int ret;
+
+    ctx = BIO_get_data(bp);
+
+    if (size < ctx->digest->md_size)
+        return 0;
+
+    if (EVP_DigestFinal_ex(ctx, (unsigned char *)buf, &ret) <= 0)
+        return -1;
+
+    return ((int)ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/bio_ok.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/bio_ok.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/bio_ok.c	(revision 331)
@@ -0,0 +1,604 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*-
+        From: Arne Ansper <arne@cyber.ee>
+
+        Why BIO_f_reliable?
+
+        I wrote function which took BIO* as argument, read data from it
+        and processed it. Then I wanted to store the input file in
+        encrypted form. OK I pushed BIO_f_cipher to the BIO stack
+        and everything was OK. BUT if user types wrong password
+        BIO_f_cipher outputs only garbage and my function crashes. Yes
+        I can and I should fix my function, but BIO_f_cipher is
+        easy way to add encryption support to many existing applications
+        and it's hard to debug and fix them all.
+
+        So I wanted another BIO which would catch the incorrect passwords and
+        file damages which cause garbage on BIO_f_cipher's output.
+
+        The easy way is to push the BIO_f_md and save the checksum at
+        the end of the file. However there are several problems with this
+        approach:
+
+        1) you must somehow separate checksum from actual data.
+        2) you need lot's of memory when reading the file, because you
+        must read to the end of the file and verify the checksum before
+        letting the application to read the data.
+
+        BIO_f_reliable tries to solve both problems, so that you can
+        read and write arbitrary long streams using only fixed amount
+        of memory.
+
+        BIO_f_reliable splits data stream into blocks. Each block is prefixed
+        with it's length and suffixed with it's digest. So you need only
+        several Kbytes of memory to buffer single block before verifying
+        it's digest.
+
+        BIO_f_reliable goes further and adds several important capabilities:
+
+        1) the digest of the block is computed over the whole stream
+        -- so nobody can rearrange the blocks or remove or replace them.
+
+        2) to detect invalid passwords right at the start BIO_f_reliable
+        adds special prefix to the stream. In order to avoid known plain-text
+        attacks this prefix is generated as follows:
+
+                *) digest is initialized with random seed instead of
+                standardized one.
+                *) same seed is written to output
+                *) well-known text is then hashed and the output
+                of the digest is also written to output.
+
+        reader can now read the seed from stream, hash the same string
+        and then compare the digest output.
+
+        Bad things: BIO_f_reliable knows what's going on in EVP_Digest. I
+        initially wrote and tested this code on x86 machine and wrote the
+        digests out in machine-dependent order :( There are people using
+        this code and I cannot change this easily without making existing
+        data files unreadable.
+
+*/
+
+#include <stdio.h>
+#include <errno.h>
+#include <assert.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include "internal/bio.h"
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include "internal/evp_int.h"
+
+static int ok_write(BIO *h, const char *buf, int num);
+static int ok_read(BIO *h, char *buf, int size);
+static long ok_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int ok_new(BIO *h);
+static int ok_free(BIO *data);
+static long ok_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+
+static __owur int sig_out(BIO *b);
+static __owur int sig_in(BIO *b);
+static __owur int block_out(BIO *b);
+static __owur int block_in(BIO *b);
+#define OK_BLOCK_SIZE   (1024*4)
+#define OK_BLOCK_BLOCK  4
+#define IOBS            (OK_BLOCK_SIZE+ OK_BLOCK_BLOCK+ 3*EVP_MAX_MD_SIZE)
+#define WELLKNOWN "The quick brown fox jumped over the lazy dog's back."
+
+typedef struct ok_struct {
+    size_t buf_len;
+    size_t buf_off;
+    size_t buf_len_save;
+    size_t buf_off_save;
+    int cont;                   /* <= 0 when finished */
+    int finished;
+    EVP_MD_CTX *md;
+    int blockout;               /* output block is ready */
+    int sigio;                  /* must process signature */
+    unsigned char buf[IOBS];
+} BIO_OK_CTX;
+
+static const BIO_METHOD methods_ok = {
+    BIO_TYPE_CIPHER, "reliable",
+    ok_write,
+    ok_read,
+    NULL,                       /* ok_puts, */
+    NULL,                       /* ok_gets, */
+    ok_ctrl,
+    ok_new,
+    ok_free,
+    ok_callback_ctrl,
+};
+
+const BIO_METHOD *BIO_f_reliable(void)
+{
+    return (&methods_ok);
+}
+
+static int ok_new(BIO *bi)
+{
+    BIO_OK_CTX *ctx;
+
+    ctx = OPENSSL_zalloc(sizeof(*ctx));
+    if (ctx == NULL)
+        return 0;
+
+    ctx->cont = 1;
+    ctx->sigio = 1;
+    ctx->md = EVP_MD_CTX_new();
+    if (ctx->md == NULL) {
+        OPENSSL_free(ctx);
+        return 0;
+    }
+    BIO_set_init(bi, 0);
+    BIO_set_data(bi, ctx);
+
+    return 1;
+}
+
+static int ok_free(BIO *a)
+{
+    BIO_OK_CTX *ctx;
+
+    if (a == NULL)
+        return 0;
+
+    ctx = BIO_get_data(a);
+
+    EVP_MD_CTX_free(ctx->md);
+    OPENSSL_clear_free(ctx, sizeof(BIO_OK_CTX));
+    BIO_set_data(a, NULL);
+    BIO_set_init(a, 0);
+
+    return 1;
+}
+
+static int ok_read(BIO *b, char *out, int outl)
+{
+    int ret = 0, i, n;
+    BIO_OK_CTX *ctx;
+    BIO *next;
+
+    if (out == NULL)
+        return 0;
+
+    ctx = BIO_get_data(b);
+    next = BIO_next(b);
+
+    if ((ctx == NULL) || (next == NULL) || (BIO_get_init(b) == 0))
+        return 0;
+
+    while (outl > 0) {
+
+        /* copy clean bytes to output buffer */
+        if (ctx->blockout) {
+            i = ctx->buf_len - ctx->buf_off;
+            if (i > outl)
+                i = outl;
+            memcpy(out, &(ctx->buf[ctx->buf_off]), i);
+            ret += i;
+            out += i;
+            outl -= i;
+            ctx->buf_off += i;
+
+            /* all clean bytes are out */
+            if (ctx->buf_len == ctx->buf_off) {
+                ctx->buf_off = 0;
+
+                /*
+                 * copy start of the next block into proper place
+                 */
+                if (ctx->buf_len_save - ctx->buf_off_save > 0) {
+                    ctx->buf_len = ctx->buf_len_save - ctx->buf_off_save;
+                    memmove(ctx->buf, &(ctx->buf[ctx->buf_off_save]),
+                            ctx->buf_len);
+                } else {
+                    ctx->buf_len = 0;
+                }
+                ctx->blockout = 0;
+            }
+        }
+
+        /* output buffer full -- cancel */
+        if (outl == 0)
+            break;
+
+        /* no clean bytes in buffer -- fill it */
+        n = IOBS - ctx->buf_len;
+        i = BIO_read(next, &(ctx->buf[ctx->buf_len]), n);
+
+        if (i <= 0)
+            break;              /* nothing new */
+
+        ctx->buf_len += i;
+
+        /* no signature yet -- check if we got one */
+        if (ctx->sigio == 1) {
+            if (!sig_in(b)) {
+                BIO_clear_retry_flags(b);
+                return 0;
+            }
+        }
+
+        /* signature ok -- check if we got block */
+        if (ctx->sigio == 0) {
+            if (!block_in(b)) {
+                BIO_clear_retry_flags(b);
+                return 0;
+            }
+        }
+
+        /* invalid block -- cancel */
+        if (ctx->cont <= 0)
+            break;
+
+    }
+
+    BIO_clear_retry_flags(b);
+    BIO_copy_next_retry(b);
+    return ret;
+}
+
+static int ok_write(BIO *b, const char *in, int inl)
+{
+    int ret = 0, n, i;
+    BIO_OK_CTX *ctx;
+    BIO *next;
+
+    if (inl <= 0)
+        return inl;
+
+    ctx = BIO_get_data(b);
+    next = BIO_next(b);
+    ret = inl;
+
+    if ((ctx == NULL) || (next == NULL) || (BIO_get_init(b) == 0))
+        return (0);
+
+    if (ctx->sigio && !sig_out(b))
+        return 0;
+
+    do {
+        BIO_clear_retry_flags(b);
+        n = ctx->buf_len - ctx->buf_off;
+        while (ctx->blockout && n > 0) {
+            i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n);
+            if (i <= 0) {
+                BIO_copy_next_retry(b);
+                if (!BIO_should_retry(b))
+                    ctx->cont = 0;
+                return (i);
+            }
+            ctx->buf_off += i;
+            n -= i;
+        }
+
+        /* at this point all pending data has been written */
+        ctx->blockout = 0;
+        if (ctx->buf_len == ctx->buf_off) {
+            ctx->buf_len = OK_BLOCK_BLOCK;
+            ctx->buf_off = 0;
+        }
+
+        if ((in == NULL) || (inl <= 0))
+            return (0);
+
+        n = (inl + ctx->buf_len > OK_BLOCK_SIZE + OK_BLOCK_BLOCK) ?
+            (int)(OK_BLOCK_SIZE + OK_BLOCK_BLOCK - ctx->buf_len) : inl;
+
+        memcpy(&ctx->buf[ctx->buf_len], in, n);
+        ctx->buf_len += n;
+        inl -= n;
+        in += n;
+
+        if (ctx->buf_len >= OK_BLOCK_SIZE + OK_BLOCK_BLOCK) {
+            if (!block_out(b)) {
+                BIO_clear_retry_flags(b);
+                return 0;
+            }
+        }
+    } while (inl > 0);
+
+    BIO_clear_retry_flags(b);
+    BIO_copy_next_retry(b);
+    return (ret);
+}
+
+static long ok_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    BIO_OK_CTX *ctx;
+    EVP_MD *md;
+    const EVP_MD **ppmd;
+    long ret = 1;
+    int i;
+    BIO *next;
+
+    ctx = BIO_get_data(b);
+    next = BIO_next(b);
+
+    switch (cmd) {
+    case BIO_CTRL_RESET:
+        ctx->buf_len = 0;
+        ctx->buf_off = 0;
+        ctx->buf_len_save = 0;
+        ctx->buf_off_save = 0;
+        ctx->cont = 1;
+        ctx->finished = 0;
+        ctx->blockout = 0;
+        ctx->sigio = 1;
+        ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+    case BIO_CTRL_EOF:         /* More to read */
+        if (ctx->cont <= 0)
+            ret = 1;
+        else
+            ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+    case BIO_CTRL_PENDING:     /* More to read in buffer */
+    case BIO_CTRL_WPENDING:    /* More to read in buffer */
+        ret = ctx->blockout ? ctx->buf_len - ctx->buf_off : 0;
+        if (ret <= 0)
+            ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+    case BIO_CTRL_FLUSH:
+        /* do a final write */
+        if (ctx->blockout == 0)
+            if (!block_out(b))
+                return 0;
+
+        while (ctx->blockout) {
+            i = ok_write(b, NULL, 0);
+            if (i < 0) {
+                ret = i;
+                break;
+            }
+        }
+
+        ctx->finished = 1;
+        ctx->buf_off = ctx->buf_len = 0;
+        ctx->cont = (int)ret;
+
+        /* Finally flush the underlying BIO */
+        ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+    case BIO_C_DO_STATE_MACHINE:
+        BIO_clear_retry_flags(b);
+        ret = BIO_ctrl(next, cmd, num, ptr);
+        BIO_copy_next_retry(b);
+        break;
+    case BIO_CTRL_INFO:
+        ret = (long)ctx->cont;
+        break;
+    case BIO_C_SET_MD:
+        md = ptr;
+        if (!EVP_DigestInit_ex(ctx->md, md, NULL))
+            return 0;
+        BIO_set_init(b, 1);
+        break;
+    case BIO_C_GET_MD:
+        if (BIO_get_init(b)) {
+            ppmd = ptr;
+            *ppmd = EVP_MD_CTX_md(ctx->md);
+        } else
+            ret = 0;
+        break;
+    default:
+        ret = BIO_ctrl(next, cmd, num, ptr);
+        break;
+    }
+    return ret;
+}
+
+static long ok_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+    long ret = 1;
+    BIO *next;
+
+    next = BIO_next(b);
+
+    if (next == NULL)
+        return 0;
+
+    switch (cmd) {
+    default:
+        ret = BIO_callback_ctrl(next, cmd, fp);
+        break;
+    }
+
+    return ret;
+}
+
+static void longswap(void *_ptr, size_t len)
+{
+    const union {
+        long one;
+        char little;
+    } is_endian = {
+        1
+    };
+
+    if (is_endian.little) {
+        size_t i;
+        unsigned char *p = _ptr, c;
+
+        for (i = 0; i < len; i += 4) {
+            c = p[0], p[0] = p[3], p[3] = c;
+            c = p[1], p[1] = p[2], p[2] = c;
+        }
+    }
+}
+
+static int sig_out(BIO *b)
+{
+    BIO_OK_CTX *ctx;
+    EVP_MD_CTX *md;
+    const EVP_MD *digest;
+    int md_size;
+    void *md_data;
+
+    ctx = BIO_get_data(b);
+    md = ctx->md;
+    digest = EVP_MD_CTX_md(md);
+    md_size = EVP_MD_size(digest);
+    md_data = EVP_MD_CTX_md_data(md);
+
+    if (ctx->buf_len + 2 * md_size > OK_BLOCK_SIZE)
+        return 1;
+
+    if (!EVP_DigestInit_ex(md, digest, NULL))
+        goto berr;
+    /*
+     * FIXME: there's absolutely no guarantee this makes any sense at all,
+     * particularly now EVP_MD_CTX has been restructured.
+     */
+    if (RAND_bytes(md_data, md_size) <= 0)
+        goto berr;
+    memcpy(&(ctx->buf[ctx->buf_len]), md_data, md_size);
+    longswap(&(ctx->buf[ctx->buf_len]), md_size);
+    ctx->buf_len += md_size;
+
+    if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
+        goto berr;
+    if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
+        goto berr;
+    ctx->buf_len += md_size;
+    ctx->blockout = 1;
+    ctx->sigio = 0;
+    return 1;
+ berr:
+    BIO_clear_retry_flags(b);
+    return 0;
+}
+
+static int sig_in(BIO *b)
+{
+    BIO_OK_CTX *ctx;
+    EVP_MD_CTX *md;
+    unsigned char tmp[EVP_MAX_MD_SIZE];
+    int ret = 0;
+    const EVP_MD *digest;
+    int md_size;
+    void *md_data;
+
+    ctx = BIO_get_data(b);
+    md = ctx->md;
+    digest = EVP_MD_CTX_md(md);
+    md_size = EVP_MD_size(digest);
+    md_data = EVP_MD_CTX_md_data(md);
+
+    if ((int)(ctx->buf_len - ctx->buf_off) < 2 * md_size)
+        return 1;
+
+    if (!EVP_DigestInit_ex(md, digest, NULL))
+        goto berr;
+    memcpy(md_data, &(ctx->buf[ctx->buf_off]), md_size);
+    longswap(md_data, md_size);
+    ctx->buf_off += md_size;
+
+    if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
+        goto berr;
+    if (!EVP_DigestFinal_ex(md, tmp, NULL))
+        goto berr;
+    ret = memcmp(&(ctx->buf[ctx->buf_off]), tmp, md_size) == 0;
+    ctx->buf_off += md_size;
+    if (ret == 1) {
+        ctx->sigio = 0;
+        if (ctx->buf_len != ctx->buf_off) {
+            memmove(ctx->buf, &(ctx->buf[ctx->buf_off]),
+                    ctx->buf_len - ctx->buf_off);
+        }
+        ctx->buf_len -= ctx->buf_off;
+        ctx->buf_off = 0;
+    } else {
+        ctx->cont = 0;
+    }
+    return 1;
+ berr:
+    BIO_clear_retry_flags(b);
+    return 0;
+}
+
+static int block_out(BIO *b)
+{
+    BIO_OK_CTX *ctx;
+    EVP_MD_CTX *md;
+    unsigned long tl;
+    const EVP_MD *digest;
+    int md_size;
+
+    ctx = BIO_get_data(b);
+    md = ctx->md;
+    digest = EVP_MD_CTX_md(md);
+    md_size = EVP_MD_size(digest);
+
+    tl = ctx->buf_len - OK_BLOCK_BLOCK;
+    ctx->buf[0] = (unsigned char)(tl >> 24);
+    ctx->buf[1] = (unsigned char)(tl >> 16);
+    ctx->buf[2] = (unsigned char)(tl >> 8);
+    ctx->buf[3] = (unsigned char)(tl);
+    if (!EVP_DigestUpdate(md,
+                          (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl))
+        goto berr;
+    if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
+        goto berr;
+    ctx->buf_len += md_size;
+    ctx->blockout = 1;
+    return 1;
+ berr:
+    BIO_clear_retry_flags(b);
+    return 0;
+}
+
+static int block_in(BIO *b)
+{
+    BIO_OK_CTX *ctx;
+    EVP_MD_CTX *md;
+    unsigned long tl = 0;
+    unsigned char tmp[EVP_MAX_MD_SIZE];
+    int md_size;
+
+    ctx = BIO_get_data(b);
+    md = ctx->md;
+    md_size = EVP_MD_size(EVP_MD_CTX_md(md));
+
+    assert(sizeof(tl) >= OK_BLOCK_BLOCK); /* always true */
+    tl = ctx->buf[0];
+    tl <<= 8;
+    tl |= ctx->buf[1];
+    tl <<= 8;
+    tl |= ctx->buf[2];
+    tl <<= 8;
+    tl |= ctx->buf[3];
+
+    if (ctx->buf_len < tl + OK_BLOCK_BLOCK + md_size)
+        return 1;
+
+    if (!EVP_DigestUpdate(md,
+                          (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl))
+        goto berr;
+    if (!EVP_DigestFinal_ex(md, tmp, NULL))
+        goto berr;
+    if (memcmp(&(ctx->buf[tl + OK_BLOCK_BLOCK]), tmp, md_size) == 0) {
+        /* there might be parts from next block lurking around ! */
+        ctx->buf_off_save = tl + OK_BLOCK_BLOCK + md_size;
+        ctx->buf_len_save = ctx->buf_len;
+        ctx->buf_off = OK_BLOCK_BLOCK;
+        ctx->buf_len = tl + OK_BLOCK_BLOCK;
+        ctx->blockout = 1;
+    } else {
+        ctx->cont = 0;
+    }
+    return 1;
+ berr:
+    BIO_clear_retry_flags(b);
+    return 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/c_allc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/c_allc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/c_allc.c	(revision 331)
@@ -0,0 +1,220 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <internal/evp_int.h>
+#include <openssl/pkcs12.h>
+#include <openssl/objects.h>
+
+void openssl_add_all_ciphers_int(void)
+{
+
+#ifndef OPENSSL_NO_DES
+    EVP_add_cipher(EVP_des_cfb());
+    EVP_add_cipher(EVP_des_cfb1());
+    EVP_add_cipher(EVP_des_cfb8());
+    EVP_add_cipher(EVP_des_ede_cfb());
+    EVP_add_cipher(EVP_des_ede3_cfb());
+    EVP_add_cipher(EVP_des_ede3_cfb1());
+    EVP_add_cipher(EVP_des_ede3_cfb8());
+
+    EVP_add_cipher(EVP_des_ofb());
+    EVP_add_cipher(EVP_des_ede_ofb());
+    EVP_add_cipher(EVP_des_ede3_ofb());
+
+    EVP_add_cipher(EVP_desx_cbc());
+    EVP_add_cipher_alias(SN_desx_cbc, "DESX");
+    EVP_add_cipher_alias(SN_desx_cbc, "desx");
+
+    EVP_add_cipher(EVP_des_cbc());
+    EVP_add_cipher_alias(SN_des_cbc, "DES");
+    EVP_add_cipher_alias(SN_des_cbc, "des");
+    EVP_add_cipher(EVP_des_ede_cbc());
+    EVP_add_cipher(EVP_des_ede3_cbc());
+    EVP_add_cipher_alias(SN_des_ede3_cbc, "DES3");
+    EVP_add_cipher_alias(SN_des_ede3_cbc, "des3");
+
+    EVP_add_cipher(EVP_des_ecb());
+    EVP_add_cipher(EVP_des_ede());
+    EVP_add_cipher_alias(SN_des_ede_ecb, "DES-EDE-ECB");
+    EVP_add_cipher_alias(SN_des_ede_ecb, "des-ede-ecb");
+    EVP_add_cipher(EVP_des_ede3());
+    EVP_add_cipher_alias(SN_des_ede3_ecb, "DES-EDE3-ECB");
+    EVP_add_cipher_alias(SN_des_ede3_ecb, "des-ede3-ecb");
+    EVP_add_cipher(EVP_des_ede3_wrap());
+    EVP_add_cipher_alias(SN_id_smime_alg_CMS3DESwrap, "des3-wrap");
+#endif
+
+#ifndef OPENSSL_NO_RC4
+    EVP_add_cipher(EVP_rc4());
+    EVP_add_cipher(EVP_rc4_40());
+# ifndef OPENSSL_NO_MD5
+    EVP_add_cipher(EVP_rc4_hmac_md5());
+# endif
+#endif
+
+#ifndef OPENSSL_NO_IDEA
+    EVP_add_cipher(EVP_idea_ecb());
+    EVP_add_cipher(EVP_idea_cfb());
+    EVP_add_cipher(EVP_idea_ofb());
+    EVP_add_cipher(EVP_idea_cbc());
+    EVP_add_cipher_alias(SN_idea_cbc, "IDEA");
+    EVP_add_cipher_alias(SN_idea_cbc, "idea");
+#endif
+
+#ifndef OPENSSL_NO_SEED
+    EVP_add_cipher(EVP_seed_ecb());
+    EVP_add_cipher(EVP_seed_cfb());
+    EVP_add_cipher(EVP_seed_ofb());
+    EVP_add_cipher(EVP_seed_cbc());
+    EVP_add_cipher_alias(SN_seed_cbc, "SEED");
+    EVP_add_cipher_alias(SN_seed_cbc, "seed");
+#endif
+
+#ifndef OPENSSL_NO_RC2
+    EVP_add_cipher(EVP_rc2_ecb());
+    EVP_add_cipher(EVP_rc2_cfb());
+    EVP_add_cipher(EVP_rc2_ofb());
+    EVP_add_cipher(EVP_rc2_cbc());
+    EVP_add_cipher(EVP_rc2_40_cbc());
+    EVP_add_cipher(EVP_rc2_64_cbc());
+    EVP_add_cipher_alias(SN_rc2_cbc, "RC2");
+    EVP_add_cipher_alias(SN_rc2_cbc, "rc2");
+    EVP_add_cipher_alias(SN_rc2_cbc, "rc2-128");
+    EVP_add_cipher_alias(SN_rc2_64_cbc, "rc2-64");
+    EVP_add_cipher_alias(SN_rc2_40_cbc, "rc2-40");
+#endif
+
+#ifndef OPENSSL_NO_BF
+    EVP_add_cipher(EVP_bf_ecb());
+    EVP_add_cipher(EVP_bf_cfb());
+    EVP_add_cipher(EVP_bf_ofb());
+    EVP_add_cipher(EVP_bf_cbc());
+    EVP_add_cipher_alias(SN_bf_cbc, "BF");
+    EVP_add_cipher_alias(SN_bf_cbc, "bf");
+    EVP_add_cipher_alias(SN_bf_cbc, "blowfish");
+#endif
+
+#ifndef OPENSSL_NO_CAST
+    EVP_add_cipher(EVP_cast5_ecb());
+    EVP_add_cipher(EVP_cast5_cfb());
+    EVP_add_cipher(EVP_cast5_ofb());
+    EVP_add_cipher(EVP_cast5_cbc());
+    EVP_add_cipher_alias(SN_cast5_cbc, "CAST");
+    EVP_add_cipher_alias(SN_cast5_cbc, "cast");
+    EVP_add_cipher_alias(SN_cast5_cbc, "CAST-cbc");
+    EVP_add_cipher_alias(SN_cast5_cbc, "cast-cbc");
+#endif
+
+#ifndef OPENSSL_NO_RC5
+    EVP_add_cipher(EVP_rc5_32_12_16_ecb());
+    EVP_add_cipher(EVP_rc5_32_12_16_cfb());
+    EVP_add_cipher(EVP_rc5_32_12_16_ofb());
+    EVP_add_cipher(EVP_rc5_32_12_16_cbc());
+    EVP_add_cipher_alias(SN_rc5_cbc, "rc5");
+    EVP_add_cipher_alias(SN_rc5_cbc, "RC5");
+#endif
+
+    EVP_add_cipher(EVP_aes_128_ecb());
+    EVP_add_cipher(EVP_aes_128_cbc());
+    EVP_add_cipher(EVP_aes_128_cfb());
+    EVP_add_cipher(EVP_aes_128_cfb1());
+    EVP_add_cipher(EVP_aes_128_cfb8());
+    EVP_add_cipher(EVP_aes_128_ofb());
+    EVP_add_cipher(EVP_aes_128_ctr());
+    EVP_add_cipher(EVP_aes_128_gcm());
+#ifndef OPENSSL_NO_OCB
+    EVP_add_cipher(EVP_aes_128_ocb());
+#endif
+    EVP_add_cipher(EVP_aes_128_xts());
+    EVP_add_cipher(EVP_aes_128_ccm());
+    EVP_add_cipher(EVP_aes_128_wrap());
+    EVP_add_cipher_alias(SN_id_aes128_wrap, "aes128-wrap");
+    EVP_add_cipher(EVP_aes_128_wrap_pad());
+    EVP_add_cipher_alias(SN_aes_128_cbc, "AES128");
+    EVP_add_cipher_alias(SN_aes_128_cbc, "aes128");
+    EVP_add_cipher(EVP_aes_192_ecb());
+    EVP_add_cipher(EVP_aes_192_cbc());
+    EVP_add_cipher(EVP_aes_192_cfb());
+    EVP_add_cipher(EVP_aes_192_cfb1());
+    EVP_add_cipher(EVP_aes_192_cfb8());
+    EVP_add_cipher(EVP_aes_192_ofb());
+    EVP_add_cipher(EVP_aes_192_ctr());
+    EVP_add_cipher(EVP_aes_192_gcm());
+#ifndef OPENSSL_NO_OCB
+    EVP_add_cipher(EVP_aes_192_ocb());
+#endif
+    EVP_add_cipher(EVP_aes_192_ccm());
+    EVP_add_cipher(EVP_aes_192_wrap());
+    EVP_add_cipher_alias(SN_id_aes192_wrap, "aes192-wrap");
+    EVP_add_cipher(EVP_aes_192_wrap_pad());
+    EVP_add_cipher_alias(SN_aes_192_cbc, "AES192");
+    EVP_add_cipher_alias(SN_aes_192_cbc, "aes192");
+    EVP_add_cipher(EVP_aes_256_ecb());
+    EVP_add_cipher(EVP_aes_256_cbc());
+    EVP_add_cipher(EVP_aes_256_cfb());
+    EVP_add_cipher(EVP_aes_256_cfb1());
+    EVP_add_cipher(EVP_aes_256_cfb8());
+    EVP_add_cipher(EVP_aes_256_ofb());
+    EVP_add_cipher(EVP_aes_256_ctr());
+    EVP_add_cipher(EVP_aes_256_gcm());
+#ifndef OPENSSL_NO_OCB
+    EVP_add_cipher(EVP_aes_256_ocb());
+#endif
+    EVP_add_cipher(EVP_aes_256_xts());
+    EVP_add_cipher(EVP_aes_256_ccm());
+    EVP_add_cipher(EVP_aes_256_wrap());
+    EVP_add_cipher_alias(SN_id_aes256_wrap, "aes256-wrap");
+    EVP_add_cipher(EVP_aes_256_wrap_pad());
+    EVP_add_cipher_alias(SN_aes_256_cbc, "AES256");
+    EVP_add_cipher_alias(SN_aes_256_cbc, "aes256");
+    EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1());
+    EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
+    EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256());
+    EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256());
+
+#ifndef OPENSSL_NO_CAMELLIA
+    EVP_add_cipher(EVP_camellia_128_ecb());
+    EVP_add_cipher(EVP_camellia_128_cbc());
+    EVP_add_cipher(EVP_camellia_128_cfb());
+    EVP_add_cipher(EVP_camellia_128_cfb1());
+    EVP_add_cipher(EVP_camellia_128_cfb8());
+    EVP_add_cipher(EVP_camellia_128_ofb());
+    EVP_add_cipher_alias(SN_camellia_128_cbc, "CAMELLIA128");
+    EVP_add_cipher_alias(SN_camellia_128_cbc, "camellia128");
+    EVP_add_cipher(EVP_camellia_192_ecb());
+    EVP_add_cipher(EVP_camellia_192_cbc());
+    EVP_add_cipher(EVP_camellia_192_cfb());
+    EVP_add_cipher(EVP_camellia_192_cfb1());
+    EVP_add_cipher(EVP_camellia_192_cfb8());
+    EVP_add_cipher(EVP_camellia_192_ofb());
+    EVP_add_cipher_alias(SN_camellia_192_cbc, "CAMELLIA192");
+    EVP_add_cipher_alias(SN_camellia_192_cbc, "camellia192");
+    EVP_add_cipher(EVP_camellia_256_ecb());
+    EVP_add_cipher(EVP_camellia_256_cbc());
+    EVP_add_cipher(EVP_camellia_256_cfb());
+    EVP_add_cipher(EVP_camellia_256_cfb1());
+    EVP_add_cipher(EVP_camellia_256_cfb8());
+    EVP_add_cipher(EVP_camellia_256_ofb());
+    EVP_add_cipher_alias(SN_camellia_256_cbc, "CAMELLIA256");
+    EVP_add_cipher_alias(SN_camellia_256_cbc, "camellia256");
+    EVP_add_cipher(EVP_camellia_128_ctr());
+    EVP_add_cipher(EVP_camellia_192_ctr());
+    EVP_add_cipher(EVP_camellia_256_ctr());
+#endif
+
+#ifndef OPENSSL_NO_CHACHA
+    EVP_add_cipher(EVP_chacha20());
+# ifndef OPENSSL_NO_POLY1305
+    EVP_add_cipher(EVP_chacha20_poly1305());
+# endif
+#endif
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/c_alld.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/c_alld.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/c_alld.c	(revision 331)
@@ -0,0 +1,49 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <internal/evp_int.h>
+#include <openssl/pkcs12.h>
+#include <openssl/objects.h>
+
+void openssl_add_all_digests_int(void)
+{
+#ifndef OPENSSL_NO_MD4
+    EVP_add_digest(EVP_md4());
+#endif
+#ifndef OPENSSL_NO_MD5
+    EVP_add_digest(EVP_md5());
+    EVP_add_digest_alias(SN_md5, "ssl3-md5");
+    EVP_add_digest(EVP_md5_sha1());
+#endif
+    EVP_add_digest(EVP_sha1());
+    EVP_add_digest_alias(SN_sha1, "ssl3-sha1");
+    EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA);
+#if !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES)
+    EVP_add_digest(EVP_mdc2());
+#endif
+#ifndef OPENSSL_NO_RMD160
+    EVP_add_digest(EVP_ripemd160());
+    EVP_add_digest_alias(SN_ripemd160, "ripemd");
+    EVP_add_digest_alias(SN_ripemd160, "rmd160");
+#endif
+    EVP_add_digest(EVP_sha224());
+    EVP_add_digest(EVP_sha256());
+    EVP_add_digest(EVP_sha384());
+    EVP_add_digest(EVP_sha512());
+#ifndef OPENSSL_NO_WHIRLPOOL
+    EVP_add_digest(EVP_whirlpool());
+#endif
+#ifndef OPENSSL_NO_BLAKE2
+    EVP_add_digest(EVP_blake2b512());
+    EVP_add_digest(EVP_blake2s256());
+#endif
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/cmeth_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/cmeth_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/cmeth_lib.c	(revision 331)
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2015-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 <string.h>
+
+#include <openssl/evp.h>
+#include "internal/evp_int.h"
+#include "evp_locl.h"
+
+EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len)
+{
+    EVP_CIPHER *cipher = OPENSSL_zalloc(sizeof(EVP_CIPHER));
+
+    if (cipher != NULL) {
+        cipher->nid = cipher_type;
+        cipher->block_size = block_size;
+        cipher->key_len = key_len;
+    }
+    return cipher;
+}
+
+EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher)
+{
+    EVP_CIPHER *to = EVP_CIPHER_meth_new(cipher->nid, cipher->block_size,
+                                         cipher->key_len);
+
+    if (to != NULL)
+        memcpy(to, cipher, sizeof(*to));
+    return to;
+}
+
+void EVP_CIPHER_meth_free(EVP_CIPHER *cipher)
+{
+    OPENSSL_free(cipher);
+}
+
+int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len)
+{
+    cipher->iv_len = iv_len;
+    return 1;
+}
+
+int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags)
+{
+    cipher->flags = flags;
+    return 1;
+}
+
+int EVP_CIPHER_meth_set_impl_ctx_size(EVP_CIPHER *cipher, int ctx_size)
+{
+    cipher->ctx_size = ctx_size;
+    return 1;
+}
+
+int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher,
+                             int (*init) (EVP_CIPHER_CTX *ctx,
+                                          const unsigned char *key,
+                                          const unsigned char *iv,
+                                          int enc))
+{
+    cipher->init = init;
+    return 1;
+}
+
+int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher,
+                                  int (*do_cipher) (EVP_CIPHER_CTX *ctx,
+                                                    unsigned char *out,
+                                                    const unsigned char *in,
+                                                    size_t inl))
+{
+    cipher->do_cipher = do_cipher;
+    return 1;
+}
+
+int EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher,
+                                int (*cleanup) (EVP_CIPHER_CTX *))
+{
+    cipher->cleanup = cleanup;
+    return 1;
+}
+
+int EVP_CIPHER_meth_set_set_asn1_params(EVP_CIPHER *cipher,
+                                        int (*set_asn1_parameters) (EVP_CIPHER_CTX *,
+                                                                    ASN1_TYPE *))
+{
+    cipher->set_asn1_parameters = set_asn1_parameters;
+    return 1;
+}
+
+int EVP_CIPHER_meth_set_get_asn1_params(EVP_CIPHER *cipher,
+                                        int (*get_asn1_parameters) (EVP_CIPHER_CTX *,
+                                                                    ASN1_TYPE *))
+{
+    cipher->get_asn1_parameters = get_asn1_parameters;
+    return 1;
+}
+
+int EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher,
+                             int (*ctrl) (EVP_CIPHER_CTX *, int type,
+                                          int arg, void *ptr))
+{
+    cipher->ctrl = ctrl;
+    return 1;
+}
+
+
+int (*EVP_CIPHER_meth_get_init(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx,
+                                                          const unsigned char *key,
+                                                          const unsigned char *iv,
+                                                          int enc)
+{
+    return cipher->init;
+}
+int (*EVP_CIPHER_meth_get_do_cipher(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx,
+                                                               unsigned char *out,
+                                                               const unsigned char *in,
+                                                               size_t inl)
+{
+    return cipher->do_cipher;
+}
+
+int (*EVP_CIPHER_meth_get_cleanup(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *)
+{
+    return cipher->cleanup;
+}
+
+int (*EVP_CIPHER_meth_get_set_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
+                                                                     ASN1_TYPE *)
+{
+    return cipher->set_asn1_parameters;
+}
+
+int (*EVP_CIPHER_meth_get_get_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
+                                                               ASN1_TYPE *)
+{
+    return cipher->get_asn1_parameters;
+}
+
+int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
+                                                          int type, int arg,
+                                                          void *ptr)
+{
+    return cipher->ctrl;
+}
+
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/digest.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/digest.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/digest.c	(revision 331)
@@ -0,0 +1,269 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/engine.h>
+#include "internal/evp_int.h"
+#include "evp_locl.h"
+
+/* This call frees resources associated with the context */
+int EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
+{
+    if (ctx == NULL)
+        return 1;
+
+    /*
+     * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
+     * sometimes only copies of the context are ever finalised.
+     */
+    if (ctx->digest && ctx->digest->cleanup
+        && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
+        ctx->digest->cleanup(ctx);
+    if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
+        && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) {
+        OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
+    }
+    EVP_PKEY_CTX_free(ctx->pctx);
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE_finish(ctx->engine);
+#endif
+    OPENSSL_cleanse(ctx, sizeof(*ctx));
+
+    return 1;
+}
+
+EVP_MD_CTX *EVP_MD_CTX_new(void)
+{
+    return OPENSSL_zalloc(sizeof(EVP_MD_CTX));
+}
+
+void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
+{
+    EVP_MD_CTX_reset(ctx);
+    OPENSSL_free(ctx);
+}
+
+int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
+{
+    EVP_MD_CTX_reset(ctx);
+    return EVP_DigestInit_ex(ctx, type, NULL);
+}
+
+int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
+{
+    EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
+#ifndef OPENSSL_NO_ENGINE
+    /*
+     * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so
+     * this context may already have an ENGINE! Try to avoid releasing the
+     * previous handle, re-querying for an ENGINE, and having a
+     * reinitialisation, when it may all be unnecessary.
+     */
+    if (ctx->engine && ctx->digest &&
+        (type == NULL || (type->type == ctx->digest->type)))
+        goto skip_to_init;
+    if (type) {
+        /*
+         * Ensure an ENGINE left lying around from last time is cleared (the
+         * previous check attempted to avoid this if the same ENGINE and
+         * EVP_MD could be used).
+         */
+        ENGINE_finish(ctx->engine);
+        if (impl != NULL) {
+            if (!ENGINE_init(impl)) {
+                EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
+                return 0;
+            }
+        } else {
+            /* Ask if an ENGINE is reserved for this job */
+            impl = ENGINE_get_digest_engine(type->type);
+        }
+        if (impl != NULL) {
+            /* There's an ENGINE for this job ... (apparently) */
+            const EVP_MD *d = ENGINE_get_digest(impl, type->type);
+
+            if (d == NULL) {
+                EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
+                ENGINE_finish(impl);
+                return 0;
+            }
+            /* We'll use the ENGINE's private digest definition */
+            type = d;
+            /*
+             * Store the ENGINE functional reference so we know 'type' came
+             * from an ENGINE and we need to release it when done.
+             */
+            ctx->engine = impl;
+        } else
+            ctx->engine = NULL;
+    } else {
+        if (!ctx->digest) {
+            EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_NO_DIGEST_SET);
+            return 0;
+        }
+        type = ctx->digest;
+    }
+#endif
+    if (ctx->digest != type) {
+        if (ctx->digest && ctx->digest->ctx_size) {
+            OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
+            ctx->md_data = NULL;
+        }
+        ctx->digest = type;
+        if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) {
+            ctx->update = type->update;
+            ctx->md_data = OPENSSL_zalloc(type->ctx_size);
+            if (ctx->md_data == NULL) {
+                EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE);
+                return 0;
+            }
+        }
+    }
+#ifndef OPENSSL_NO_ENGINE
+ skip_to_init:
+#endif
+    if (ctx->pctx) {
+        int r;
+        r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
+                              EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
+        if (r <= 0 && (r != -2))
+            return 0;
+    }
+    if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
+        return 1;
+    return ctx->digest->init(ctx);
+}
+
+int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+    return ctx->update(ctx, data, count);
+}
+
+/* The caller can assume that this removes any secret data from the context */
+int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
+{
+    int ret;
+    ret = EVP_DigestFinal_ex(ctx, md, size);
+    EVP_MD_CTX_reset(ctx);
+    return ret;
+}
+
+/* The caller can assume that this removes any secret data from the context */
+int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
+{
+    int ret;
+
+    OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
+    ret = ctx->digest->final(ctx, md);
+    if (size != NULL)
+        *size = ctx->digest->md_size;
+    if (ctx->digest->cleanup) {
+        ctx->digest->cleanup(ctx);
+        EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
+    }
+    OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size);
+    return ret;
+}
+
+int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
+{
+    EVP_MD_CTX_reset(out);
+    return EVP_MD_CTX_copy_ex(out, in);
+}
+
+int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
+{
+    unsigned char *tmp_buf;
+    if ((in == NULL) || (in->digest == NULL)) {
+        EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_INPUT_NOT_INITIALIZED);
+        return 0;
+    }
+#ifndef OPENSSL_NO_ENGINE
+    /* Make sure it's safe to copy a digest context using an ENGINE */
+    if (in->engine && !ENGINE_init(in->engine)) {
+        EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_ENGINE_LIB);
+        return 0;
+    }
+#endif
+
+    if (out->digest == in->digest) {
+        tmp_buf = out->md_data;
+        EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE);
+    } else
+        tmp_buf = NULL;
+    EVP_MD_CTX_reset(out);
+    memcpy(out, in, sizeof(*out));
+
+    /* Null these variables, since they are getting fixed up
+     * properly below.  Anything else may cause a memleak and/or
+     * double free if any of the memory allocations below fail
+     */
+    out->md_data = NULL;
+    out->pctx = NULL;
+
+    if (in->md_data && out->digest->ctx_size) {
+        if (tmp_buf)
+            out->md_data = tmp_buf;
+        else {
+            out->md_data = OPENSSL_malloc(out->digest->ctx_size);
+            if (out->md_data == NULL) {
+                EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_MALLOC_FAILURE);
+                return 0;
+            }
+        }
+        memcpy(out->md_data, in->md_data, out->digest->ctx_size);
+    }
+
+    out->update = in->update;
+
+    if (in->pctx) {
+        out->pctx = EVP_PKEY_CTX_dup(in->pctx);
+        if (!out->pctx) {
+            EVP_MD_CTX_reset(out);
+            return 0;
+        }
+    }
+
+    if (out->digest->copy)
+        return out->digest->copy(out, in);
+
+    return 1;
+}
+
+int EVP_Digest(const void *data, size_t count,
+               unsigned char *md, unsigned int *size, const EVP_MD *type,
+               ENGINE *impl)
+{
+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+    int ret;
+
+    if (ctx == NULL)
+        return 0;
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_ONESHOT);
+    ret = EVP_DigestInit_ex(ctx, type, impl)
+        && EVP_DigestUpdate(ctx, data, count)
+        && EVP_DigestFinal_ex(ctx, md, size);
+    EVP_MD_CTX_free(ctx);
+
+    return ret;
+}
+
+int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
+{
+    if (ctx->digest && ctx->digest->md_ctrl) {
+        int ret = ctx->digest->md_ctrl(ctx, cmd, p1, p2);
+        if (ret <= 0)
+            return 0;
+        return 1;
+    }
+    return 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_aes.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_aes.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_aes.c	(revision 331)
@@ -0,0 +1,2704 @@
+/*
+ * Copyright 2001-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 <openssl/opensslconf.h>
+#include <openssl/crypto.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <string.h>
+#include <assert.h>
+#include <openssl/aes.h>
+#include "internal/evp_int.h"
+#include "../modes/modes_lcl.h"
+#include <openssl/rand.h>
+#include "evp_locl.h"
+#include <stdint.h>
+typedef unsigned short uint16_t;
+
+typedef struct {
+    union {
+        double align;
+        AES_KEY ks;
+    } ks;
+    block128_f block;
+    union {
+        cbc128_f cbc;
+        ctr128_f ctr;
+    } stream;
+} EVP_AES_KEY;
+
+typedef struct {
+    union {
+        double align;
+        AES_KEY ks;
+    } ks;                       /* AES key schedule to use */
+    int key_set;                /* Set if key initialised */
+    int iv_set;                 /* Set if an iv is set */
+    GCM128_CONTEXT gcm;
+    unsigned char *iv;          /* Temporary IV store */
+    int ivlen;                  /* IV length */
+    int taglen;
+    int iv_gen;                 /* It is OK to generate IVs */
+    int tls_aad_len;            /* TLS AAD length */
+    ctr128_f ctr;
+} EVP_AES_GCM_CTX;
+
+typedef struct {
+    union {
+        double align;
+        AES_KEY ks;
+    } ks1, ks2;                 /* AES key schedules to use */
+    XTS128_CONTEXT xts;
+    void (*stream) (const unsigned char *in,
+                    unsigned char *out, size_t length,
+                    const AES_KEY *key1, const AES_KEY *key2,
+                    const unsigned char iv[16]);
+} EVP_AES_XTS_CTX;
+
+typedef struct {
+    union {
+        double align;
+        AES_KEY ks;
+    } ks;                       /* AES key schedule to use */
+    int key_set;                /* Set if key initialised */
+    int iv_set;                 /* Set if an iv is set */
+    int tag_set;                /* Set if tag is valid */
+    int len_set;                /* Set if message length set */
+    int L, M;                   /* L and M parameters from RFC3610 */
+    int tls_aad_len;            /* TLS AAD length */
+    CCM128_CONTEXT ccm;
+    ccm128_f str;
+} EVP_AES_CCM_CTX;
+
+#ifndef OPENSSL_NO_OCB
+typedef struct {
+    union {
+        double align;
+        AES_KEY ks;
+    } ksenc;                    /* AES key schedule to use for encryption */
+    union {
+        double align;
+        AES_KEY ks;
+    } ksdec;                    /* AES key schedule to use for decryption */
+    int key_set;                /* Set if key initialised */
+    int iv_set;                 /* Set if an iv is set */
+    OCB128_CONTEXT ocb;
+    unsigned char *iv;          /* Temporary IV store */
+    unsigned char tag[16];
+    unsigned char data_buf[16]; /* Store partial data blocks */
+    unsigned char aad_buf[16];  /* Store partial AAD blocks */
+    int data_buf_len;
+    int aad_buf_len;
+    int ivlen;                  /* IV length */
+    int taglen;
+} EVP_AES_OCB_CTX;
+#endif
+
+#define MAXBITCHUNK     ((size_t)1<<(sizeof(size_t)*8-4))
+
+#ifdef VPAES_ASM
+int vpaes_set_encrypt_key(const unsigned char *userKey, int bits,
+                          AES_KEY *key);
+int vpaes_set_decrypt_key(const unsigned char *userKey, int bits,
+                          AES_KEY *key);
+
+void vpaes_encrypt(const unsigned char *in, unsigned char *out,
+                   const AES_KEY *key);
+void vpaes_decrypt(const unsigned char *in, unsigned char *out,
+                   const AES_KEY *key);
+
+void vpaes_cbc_encrypt(const unsigned char *in,
+                       unsigned char *out,
+                       size_t length,
+                       const AES_KEY *key, unsigned char *ivec, int enc);
+#endif
+#ifdef BSAES_ASM
+void bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                       size_t length, const AES_KEY *key,
+                       unsigned char ivec[16], int enc);
+void bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
+                                size_t len, const AES_KEY *key,
+                                const unsigned char ivec[16]);
+void bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out,
+                       size_t len, const AES_KEY *key1,
+                       const AES_KEY *key2, const unsigned char iv[16]);
+void bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out,
+                       size_t len, const AES_KEY *key1,
+                       const AES_KEY *key2, const unsigned char iv[16]);
+#endif
+#ifdef AES_CTR_ASM
+void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+                       size_t blocks, const AES_KEY *key,
+                       const unsigned char ivec[AES_BLOCK_SIZE]);
+#endif
+#ifdef AES_XTS_ASM
+void AES_xts_encrypt(const char *inp, char *out, size_t len,
+                     const AES_KEY *key1, const AES_KEY *key2,
+                     const unsigned char iv[16]);
+void AES_xts_decrypt(const char *inp, char *out, size_t len,
+                     const AES_KEY *key1, const AES_KEY *key2,
+                     const unsigned char iv[16]);
+#endif
+
+#if defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC))
+# include "ppc_arch.h"
+# ifdef VPAES_ASM
+#  define VPAES_CAPABLE (OPENSSL_ppccap_P & PPC_ALTIVEC)
+# endif
+# define HWAES_CAPABLE  (OPENSSL_ppccap_P & PPC_CRYPTO207)
+# define HWAES_set_encrypt_key aes_p8_set_encrypt_key
+# define HWAES_set_decrypt_key aes_p8_set_decrypt_key
+# define HWAES_encrypt aes_p8_encrypt
+# define HWAES_decrypt aes_p8_decrypt
+# define HWAES_cbc_encrypt aes_p8_cbc_encrypt
+# define HWAES_ctr32_encrypt_blocks aes_p8_ctr32_encrypt_blocks
+# define HWAES_xts_encrypt aes_p8_xts_encrypt
+# define HWAES_xts_decrypt aes_p8_xts_decrypt
+#endif
+
+#if     defined(AES_ASM) && !defined(I386_ONLY) &&      (  \
+        ((defined(__i386)       || defined(__i386__)    || \
+          defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \
+        defined(__x86_64)       || defined(__x86_64__)  || \
+        defined(_M_AMD64)       || defined(_M_X64)      )
+
+extern unsigned int OPENSSL_ia32cap_P[];
+
+# ifdef VPAES_ASM
+#  define VPAES_CAPABLE   (OPENSSL_ia32cap_P[1]&(1<<(41-32)))
+# endif
+# ifdef BSAES_ASM
+#  define BSAES_CAPABLE   (OPENSSL_ia32cap_P[1]&(1<<(41-32)))
+# endif
+/*
+ * AES-NI section
+ */
+# define AESNI_CAPABLE   (OPENSSL_ia32cap_P[1]&(1<<(57-32)))
+
+int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
+                          AES_KEY *key);
+int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
+                          AES_KEY *key);
+
+void aesni_encrypt(const unsigned char *in, unsigned char *out,
+                   const AES_KEY *key);
+void aesni_decrypt(const unsigned char *in, unsigned char *out,
+                   const AES_KEY *key);
+
+void aesni_ecb_encrypt(const unsigned char *in,
+                       unsigned char *out,
+                       size_t length, const AES_KEY *key, int enc);
+void aesni_cbc_encrypt(const unsigned char *in,
+                       unsigned char *out,
+                       size_t length,
+                       const AES_KEY *key, unsigned char *ivec, int enc);
+
+void aesni_ctr32_encrypt_blocks(const unsigned char *in,
+                                unsigned char *out,
+                                size_t blocks,
+                                const void *key, const unsigned char *ivec);
+
+void aesni_xts_encrypt(const unsigned char *in,
+                       unsigned char *out,
+                       size_t length,
+                       const AES_KEY *key1, const AES_KEY *key2,
+                       const unsigned char iv[16]);
+
+void aesni_xts_decrypt(const unsigned char *in,
+                       unsigned char *out,
+                       size_t length,
+                       const AES_KEY *key1, const AES_KEY *key2,
+                       const unsigned char iv[16]);
+
+void aesni_ccm64_encrypt_blocks(const unsigned char *in,
+                                unsigned char *out,
+                                size_t blocks,
+                                const void *key,
+                                const unsigned char ivec[16],
+                                unsigned char cmac[16]);
+
+void aesni_ccm64_decrypt_blocks(const unsigned char *in,
+                                unsigned char *out,
+                                size_t blocks,
+                                const void *key,
+                                const unsigned char ivec[16],
+                                unsigned char cmac[16]);
+
+# if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
+size_t aesni_gcm_encrypt(const unsigned char *in,
+                         unsigned char *out,
+                         size_t len,
+                         const void *key, unsigned char ivec[16], u64 *Xi);
+#  define AES_gcm_encrypt aesni_gcm_encrypt
+size_t aesni_gcm_decrypt(const unsigned char *in,
+                         unsigned char *out,
+                         size_t len,
+                         const void *key, unsigned char ivec[16], u64 *Xi);
+#  define AES_gcm_decrypt aesni_gcm_decrypt
+void gcm_ghash_avx(u64 Xi[2], const u128 Htable[16], const u8 *in,
+                   size_t len);
+#  define AES_GCM_ASM(gctx)       (gctx->ctr==aesni_ctr32_encrypt_blocks && \
+                                 gctx->gcm.ghash==gcm_ghash_avx)
+#  define AES_GCM_ASM2(gctx)      (gctx->gcm.block==(block128_f)aesni_encrypt && \
+                                 gctx->gcm.ghash==gcm_ghash_avx)
+#  undef AES_GCM_ASM2          /* minor size optimization */
+# endif
+
+static int aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                          const unsigned char *iv, int enc)
+{
+    int ret, mode;
+    EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx);
+
+    mode = EVP_CIPHER_CTX_mode(ctx);
+    if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
+        && !enc) {
+        ret = aesni_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                    &dat->ks.ks);
+        dat->block = (block128_f) aesni_decrypt;
+        dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+            (cbc128_f) aesni_cbc_encrypt : NULL;
+    } else {
+        ret = aesni_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                    &dat->ks.ks);
+        dat->block = (block128_f) aesni_encrypt;
+        if (mode == EVP_CIPH_CBC_MODE)
+            dat->stream.cbc = (cbc128_f) aesni_cbc_encrypt;
+        else if (mode == EVP_CIPH_CTR_MODE)
+            dat->stream.ctr = (ctr128_f) aesni_ctr32_encrypt_blocks;
+        else
+            dat->stream.cbc = NULL;
+    }
+
+    if (ret < 0) {
+        EVPerr(EVP_F_AESNI_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int aesni_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                            const unsigned char *in, size_t len)
+{
+    aesni_cbc_encrypt(in, out, len, &EVP_C_DATA(EVP_AES_KEY,ctx)->ks.ks,
+                      EVP_CIPHER_CTX_iv_noconst(ctx),
+                      EVP_CIPHER_CTX_encrypting(ctx));
+
+    return 1;
+}
+
+static int aesni_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                            const unsigned char *in, size_t len)
+{
+    size_t bl = EVP_CIPHER_CTX_block_size(ctx);
+
+    if (len < bl)
+        return 1;
+
+    aesni_ecb_encrypt(in, out, len, &EVP_C_DATA(EVP_AES_KEY,ctx)->ks.ks,
+                      EVP_CIPHER_CTX_encrypting(ctx));
+
+    return 1;
+}
+
+# define aesni_ofb_cipher aes_ofb_cipher
+static int aesni_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                            const unsigned char *in, size_t len);
+
+# define aesni_cfb_cipher aes_cfb_cipher
+static int aesni_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                            const unsigned char *in, size_t len);
+
+# define aesni_cfb8_cipher aes_cfb8_cipher
+static int aesni_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                             const unsigned char *in, size_t len);
+
+# define aesni_cfb1_cipher aes_cfb1_cipher
+static int aesni_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                             const unsigned char *in, size_t len);
+
+# define aesni_ctr_cipher aes_ctr_cipher
+static int aesni_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                            const unsigned char *in, size_t len);
+
+static int aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                              const unsigned char *iv, int enc)
+{
+    EVP_AES_GCM_CTX *gctx = EVP_C_DATA(EVP_AES_GCM_CTX,ctx);
+    if (!iv && !key)
+        return 1;
+    if (key) {
+        aesni_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                              &gctx->ks.ks);
+        CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f) aesni_encrypt);
+        gctx->ctr = (ctr128_f) aesni_ctr32_encrypt_blocks;
+        /*
+         * If we have an iv can set it directly, otherwise use saved IV.
+         */
+        if (iv == NULL && gctx->iv_set)
+            iv = gctx->iv;
+        if (iv) {
+            CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+            gctx->iv_set = 1;
+        }
+        gctx->key_set = 1;
+    } else {
+        /* If key set use IV, otherwise copy */
+        if (gctx->key_set)
+            CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+        else
+            memcpy(gctx->iv, iv, gctx->ivlen);
+        gctx->iv_set = 1;
+        gctx->iv_gen = 0;
+    }
+    return 1;
+}
+
+# define aesni_gcm_cipher aes_gcm_cipher
+static int aesni_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                            const unsigned char *in, size_t len);
+
+static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                              const unsigned char *iv, int enc)
+{
+    EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,ctx);
+    if (!iv && !key)
+        return 1;
+
+    if (key) {
+        /* key_len is two AES keys */
+        if (enc) {
+            aesni_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 4,
+                                  &xctx->ks1.ks);
+            xctx->xts.block1 = (block128_f) aesni_encrypt;
+            xctx->stream = aesni_xts_encrypt;
+        } else {
+            aesni_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 4,
+                                  &xctx->ks1.ks);
+            xctx->xts.block1 = (block128_f) aesni_decrypt;
+            xctx->stream = aesni_xts_decrypt;
+        }
+
+        aesni_set_encrypt_key(key + EVP_CIPHER_CTX_key_length(ctx) / 2,
+                              EVP_CIPHER_CTX_key_length(ctx) * 4,
+                              &xctx->ks2.ks);
+        xctx->xts.block2 = (block128_f) aesni_encrypt;
+
+        xctx->xts.key1 = &xctx->ks1;
+    }
+
+    if (iv) {
+        xctx->xts.key2 = &xctx->ks2;
+        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 16);
+    }
+
+    return 1;
+}
+
+# define aesni_xts_cipher aes_xts_cipher
+static int aesni_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                            const unsigned char *in, size_t len);
+
+static int aesni_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                              const unsigned char *iv, int enc)
+{
+    EVP_AES_CCM_CTX *cctx = EVP_C_DATA(EVP_AES_CCM_CTX,ctx);
+    if (!iv && !key)
+        return 1;
+    if (key) {
+        aesni_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                              &cctx->ks.ks);
+        CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+                           &cctx->ks, (block128_f) aesni_encrypt);
+        cctx->str = enc ? (ccm128_f) aesni_ccm64_encrypt_blocks :
+            (ccm128_f) aesni_ccm64_decrypt_blocks;
+        cctx->key_set = 1;
+    }
+    if (iv) {
+        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 15 - cctx->L);
+        cctx->iv_set = 1;
+    }
+    return 1;
+}
+
+# define aesni_ccm_cipher aes_ccm_cipher
+static int aesni_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                            const unsigned char *in, size_t len);
+
+# ifndef OPENSSL_NO_OCB
+void aesni_ocb_encrypt(const unsigned char *in, unsigned char *out,
+                       size_t blocks, const void *key,
+                       size_t start_block_num,
+                       unsigned char offset_i[16],
+                       const unsigned char L_[][16],
+                       unsigned char checksum[16]);
+void aesni_ocb_decrypt(const unsigned char *in, unsigned char *out,
+                       size_t blocks, const void *key,
+                       size_t start_block_num,
+                       unsigned char offset_i[16],
+                       const unsigned char L_[][16],
+                       unsigned char checksum[16]);
+
+static int aesni_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                              const unsigned char *iv, int enc)
+{
+    EVP_AES_OCB_CTX *octx = EVP_C_DATA(EVP_AES_OCB_CTX,ctx);
+    if (!iv && !key)
+        return 1;
+    if (key) {
+        do {
+            /*
+             * We set both the encrypt and decrypt key here because decrypt
+             * needs both. We could possibly optimise to remove setting the
+             * decrypt for an encryption operation.
+             */
+            aesni_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                  &octx->ksenc.ks);
+            aesni_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                  &octx->ksdec.ks);
+            if (!CRYPTO_ocb128_init(&octx->ocb,
+                                    &octx->ksenc.ks, &octx->ksdec.ks,
+                                    (block128_f) aesni_encrypt,
+                                    (block128_f) aesni_decrypt,
+                                    enc ? aesni_ocb_encrypt
+                                        : aesni_ocb_decrypt))
+                return 0;
+        }
+        while (0);
+
+        /*
+         * If we have an iv we can set it directly, otherwise use saved IV.
+         */
+        if (iv == NULL && octx->iv_set)
+            iv = octx->iv;
+        if (iv) {
+            if (CRYPTO_ocb128_setiv(&octx->ocb, iv, octx->ivlen, octx->taglen)
+                != 1)
+                return 0;
+            octx->iv_set = 1;
+        }
+        octx->key_set = 1;
+    } else {
+        /* If key set use IV, otherwise copy */
+        if (octx->key_set)
+            CRYPTO_ocb128_setiv(&octx->ocb, iv, octx->ivlen, octx->taglen);
+        else
+            memcpy(octx->iv, iv, octx->ivlen);
+        octx->iv_set = 1;
+    }
+    return 1;
+}
+
+#  define aesni_ocb_cipher aes_ocb_cipher
+static int aesni_ocb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                            const unsigned char *in, size_t len);
+# endif                        /* OPENSSL_NO_OCB */
+
+# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
+static const EVP_CIPHER aesni_##keylen##_##mode = { \
+        nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
+        flags|EVP_CIPH_##MODE##_MODE,   \
+        aesni_init_key,                 \
+        aesni_##mode##_cipher,          \
+        NULL,                           \
+        sizeof(EVP_AES_KEY),            \
+        NULL,NULL,NULL,NULL }; \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+        nid##_##keylen##_##nmode,blocksize,     \
+        keylen/8,ivlen, \
+        flags|EVP_CIPH_##MODE##_MODE,   \
+        aes_init_key,                   \
+        aes_##mode##_cipher,            \
+        NULL,                           \
+        sizeof(EVP_AES_KEY),            \
+        NULL,NULL,NULL,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; }
+
+# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
+static const EVP_CIPHER aesni_##keylen##_##mode = { \
+        nid##_##keylen##_##mode,blocksize, \
+        (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+        flags|EVP_CIPH_##MODE##_MODE,   \
+        aesni_##mode##_init_key,        \
+        aesni_##mode##_cipher,          \
+        aes_##mode##_cleanup,           \
+        sizeof(EVP_AES_##MODE##_CTX),   \
+        NULL,NULL,aes_##mode##_ctrl,NULL }; \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+        nid##_##keylen##_##mode,blocksize, \
+        (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+        flags|EVP_CIPH_##MODE##_MODE,   \
+        aes_##mode##_init_key,          \
+        aes_##mode##_cipher,            \
+        aes_##mode##_cleanup,           \
+        sizeof(EVP_AES_##MODE##_CTX),   \
+        NULL,NULL,aes_##mode##_ctrl,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; }
+
+#elif   defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
+
+# include "sparc_arch.h"
+
+extern unsigned int OPENSSL_sparcv9cap_P[];
+
+/*
+ * Initial Fujitsu SPARC64 X support
+ */
+# define HWAES_CAPABLE           (OPENSSL_sparcv9cap_P[0] & SPARCV9_FJAESX)
+# define HWAES_set_encrypt_key aes_fx_set_encrypt_key
+# define HWAES_set_decrypt_key aes_fx_set_decrypt_key
+# define HWAES_encrypt aes_fx_encrypt
+# define HWAES_decrypt aes_fx_decrypt
+# define HWAES_cbc_encrypt aes_fx_cbc_encrypt
+# define HWAES_ctr32_encrypt_blocks aes_fx_ctr32_encrypt_blocks
+
+# define SPARC_AES_CAPABLE       (OPENSSL_sparcv9cap_P[1] & CFR_AES)
+
+void aes_t4_set_encrypt_key(const unsigned char *key, int bits, AES_KEY *ks);
+void aes_t4_set_decrypt_key(const unsigned char *key, int bits, AES_KEY *ks);
+void aes_t4_encrypt(const unsigned char *in, unsigned char *out,
+                    const AES_KEY *key);
+void aes_t4_decrypt(const unsigned char *in, unsigned char *out,
+                    const AES_KEY *key);
+/*
+ * Key-length specific subroutines were chosen for following reason.
+ * Each SPARC T4 core can execute up to 8 threads which share core's
+ * resources. Loading as much key material to registers allows to
+ * minimize references to shared memory interface, as well as amount
+ * of instructions in inner loops [much needed on T4]. But then having
+ * non-key-length specific routines would require conditional branches
+ * either in inner loops or on subroutines' entries. Former is hardly
+ * acceptable, while latter means code size increase to size occupied
+ * by multiple key-length specific subroutines, so why fight?
+ */
+void aes128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const AES_KEY *key,
+                           unsigned char *ivec);
+void aes128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const AES_KEY *key,
+                           unsigned char *ivec);
+void aes192_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const AES_KEY *key,
+                           unsigned char *ivec);
+void aes192_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const AES_KEY *key,
+                           unsigned char *ivec);
+void aes256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const AES_KEY *key,
+                           unsigned char *ivec);
+void aes256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const AES_KEY *key,
+                           unsigned char *ivec);
+void aes128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t blocks, const AES_KEY *key,
+                             unsigned char *ivec);
+void aes192_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t blocks, const AES_KEY *key,
+                             unsigned char *ivec);
+void aes256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t blocks, const AES_KEY *key,
+                             unsigned char *ivec);
+void aes128_t4_xts_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t blocks, const AES_KEY *key1,
+                           const AES_KEY *key2, const unsigned char *ivec);
+void aes128_t4_xts_decrypt(const unsigned char *in, unsigned char *out,
+                           size_t blocks, const AES_KEY *key1,
+                           const AES_KEY *key2, const unsigned char *ivec);
+void aes256_t4_xts_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t blocks, const AES_KEY *key1,
+                           const AES_KEY *key2, const unsigned char *ivec);
+void aes256_t4_xts_decrypt(const unsigned char *in, unsigned char *out,
+                           size_t blocks, const AES_KEY *key1,
+                           const AES_KEY *key2, const unsigned char *ivec);
+
+static int aes_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                           const unsigned char *iv, int enc)
+{
+    int ret, mode, bits;
+    EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx);
+
+    mode = EVP_CIPHER_CTX_mode(ctx);
+    bits = EVP_CIPHER_CTX_key_length(ctx) * 8;
+    if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
+        && !enc) {
+        ret = 0;
+        aes_t4_set_decrypt_key(key, bits, &dat->ks.ks);
+        dat->block = (block128_f) aes_t4_decrypt;
+        switch (bits) {
+        case 128:
+            dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+                (cbc128_f) aes128_t4_cbc_decrypt : NULL;
+            break;
+        case 192:
+            dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+                (cbc128_f) aes192_t4_cbc_decrypt : NULL;
+            break;
+        case 256:
+            dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+                (cbc128_f) aes256_t4_cbc_decrypt : NULL;
+            break;
+        default:
+            ret = -1;
+        }
+    } else {
+        ret = 0;
+        aes_t4_set_encrypt_key(key, bits, &dat->ks.ks);
+        dat->block = (block128_f) aes_t4_encrypt;
+        switch (bits) {
+        case 128:
+            if (mode == EVP_CIPH_CBC_MODE)
+                dat->stream.cbc = (cbc128_f) aes128_t4_cbc_encrypt;
+            else if (mode == EVP_CIPH_CTR_MODE)
+                dat->stream.ctr = (ctr128_f) aes128_t4_ctr32_encrypt;
+            else
+                dat->stream.cbc = NULL;
+            break;
+        case 192:
+            if (mode == EVP_CIPH_CBC_MODE)
+                dat->stream.cbc = (cbc128_f) aes192_t4_cbc_encrypt;
+            else if (mode == EVP_CIPH_CTR_MODE)
+                dat->stream.ctr = (ctr128_f) aes192_t4_ctr32_encrypt;
+            else
+                dat->stream.cbc = NULL;
+            break;
+        case 256:
+            if (mode == EVP_CIPH_CBC_MODE)
+                dat->stream.cbc = (cbc128_f) aes256_t4_cbc_encrypt;
+            else if (mode == EVP_CIPH_CTR_MODE)
+                dat->stream.ctr = (ctr128_f) aes256_t4_ctr32_encrypt;
+            else
+                dat->stream.cbc = NULL;
+            break;
+        default:
+            ret = -1;
+        }
+    }
+
+    if (ret < 0) {
+        EVPerr(EVP_F_AES_T4_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED);
+        return 0;
+    }
+
+    return 1;
+}
+
+# define aes_t4_cbc_cipher aes_cbc_cipher
+static int aes_t4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                             const unsigned char *in, size_t len);
+
+# define aes_t4_ecb_cipher aes_ecb_cipher
+static int aes_t4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                             const unsigned char *in, size_t len);
+
+# define aes_t4_ofb_cipher aes_ofb_cipher
+static int aes_t4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                             const unsigned char *in, size_t len);
+
+# define aes_t4_cfb_cipher aes_cfb_cipher
+static int aes_t4_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                             const unsigned char *in, size_t len);
+
+# define aes_t4_cfb8_cipher aes_cfb8_cipher
+static int aes_t4_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                              const unsigned char *in, size_t len);
+
+# define aes_t4_cfb1_cipher aes_cfb1_cipher
+static int aes_t4_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                              const unsigned char *in, size_t len);
+
+# define aes_t4_ctr_cipher aes_ctr_cipher
+static int aes_t4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                             const unsigned char *in, size_t len);
+
+static int aes_t4_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                               const unsigned char *iv, int enc)
+{
+    EVP_AES_GCM_CTX *gctx = EVP_C_DATA(EVP_AES_GCM_CTX,ctx);
+    if (!iv && !key)
+        return 1;
+    if (key) {
+        int bits = EVP_CIPHER_CTX_key_length(ctx) * 8;
+        aes_t4_set_encrypt_key(key, bits, &gctx->ks.ks);
+        CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
+                           (block128_f) aes_t4_encrypt);
+        switch (bits) {
+        case 128:
+            gctx->ctr = (ctr128_f) aes128_t4_ctr32_encrypt;
+            break;
+        case 192:
+            gctx->ctr = (ctr128_f) aes192_t4_ctr32_encrypt;
+            break;
+        case 256:
+            gctx->ctr = (ctr128_f) aes256_t4_ctr32_encrypt;
+            break;
+        default:
+            return 0;
+        }
+        /*
+         * If we have an iv can set it directly, otherwise use saved IV.
+         */
+        if (iv == NULL && gctx->iv_set)
+            iv = gctx->iv;
+        if (iv) {
+            CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+            gctx->iv_set = 1;
+        }
+        gctx->key_set = 1;
+    } else {
+        /* If key set use IV, otherwise copy */
+        if (gctx->key_set)
+            CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+        else
+            memcpy(gctx->iv, iv, gctx->ivlen);
+        gctx->iv_set = 1;
+        gctx->iv_gen = 0;
+    }
+    return 1;
+}
+
+# define aes_t4_gcm_cipher aes_gcm_cipher
+static int aes_t4_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                             const unsigned char *in, size_t len);
+
+static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                               const unsigned char *iv, int enc)
+{
+    EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,ctx);
+    if (!iv && !key)
+        return 1;
+
+    if (key) {
+        int bits = EVP_CIPHER_CTX_key_length(ctx) * 4;
+        xctx->stream = NULL;
+        /* key_len is two AES keys */
+        if (enc) {
+            aes_t4_set_encrypt_key(key, bits, &xctx->ks1.ks);
+            xctx->xts.block1 = (block128_f) aes_t4_encrypt;
+            switch (bits) {
+            case 128:
+                xctx->stream = aes128_t4_xts_encrypt;
+                break;
+            case 256:
+                xctx->stream = aes256_t4_xts_encrypt;
+                break;
+            default:
+                return 0;
+            }
+        } else {
+            aes_t4_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 4,
+                                   &xctx->ks1.ks);
+            xctx->xts.block1 = (block128_f) aes_t4_decrypt;
+            switch (bits) {
+            case 128:
+                xctx->stream = aes128_t4_xts_decrypt;
+                break;
+            case 256:
+                xctx->stream = aes256_t4_xts_decrypt;
+                break;
+            default:
+                return 0;
+            }
+        }
+
+        aes_t4_set_encrypt_key(key + EVP_CIPHER_CTX_key_length(ctx) / 2,
+                               EVP_CIPHER_CTX_key_length(ctx) * 4,
+                               &xctx->ks2.ks);
+        xctx->xts.block2 = (block128_f) aes_t4_encrypt;
+
+        xctx->xts.key1 = &xctx->ks1;
+    }
+
+    if (iv) {
+        xctx->xts.key2 = &xctx->ks2;
+        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 16);
+    }
+
+    return 1;
+}
+
+# define aes_t4_xts_cipher aes_xts_cipher
+static int aes_t4_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                             const unsigned char *in, size_t len);
+
+static int aes_t4_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                               const unsigned char *iv, int enc)
+{
+    EVP_AES_CCM_CTX *cctx = EVP_C_DATA(EVP_AES_CCM_CTX,ctx);
+    if (!iv && !key)
+        return 1;
+    if (key) {
+        int bits = EVP_CIPHER_CTX_key_length(ctx) * 8;
+        aes_t4_set_encrypt_key(key, bits, &cctx->ks.ks);
+        CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+                           &cctx->ks, (block128_f) aes_t4_encrypt);
+        cctx->str = NULL;
+        cctx->key_set = 1;
+    }
+    if (iv) {
+        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 15 - cctx->L);
+        cctx->iv_set = 1;
+    }
+    return 1;
+}
+
+# define aes_t4_ccm_cipher aes_ccm_cipher
+static int aes_t4_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                             const unsigned char *in, size_t len);
+
+# ifndef OPENSSL_NO_OCB
+static int aes_t4_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                               const unsigned char *iv, int enc)
+{
+    EVP_AES_OCB_CTX *octx = EVP_C_DATA(EVP_AES_OCB_CTX,ctx);
+    if (!iv && !key)
+        return 1;
+    if (key) {
+        do {
+            /*
+             * We set both the encrypt and decrypt key here because decrypt
+             * needs both. We could possibly optimise to remove setting the
+             * decrypt for an encryption operation.
+             */
+            aes_t4_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                   &octx->ksenc.ks);
+            aes_t4_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                   &octx->ksdec.ks);
+            if (!CRYPTO_ocb128_init(&octx->ocb,
+                                    &octx->ksenc.ks, &octx->ksdec.ks,
+                                    (block128_f) aes_t4_encrypt,
+                                    (block128_f) aes_t4_decrypt,
+                                    NULL))
+                return 0;
+        }
+        while (0);
+
+        /*
+         * If we have an iv we can set it directly, otherwise use saved IV.
+         */
+        if (iv == NULL && octx->iv_set)
+            iv = octx->iv;
+        if (iv) {
+            if (CRYPTO_ocb128_setiv(&octx->ocb, iv, octx->ivlen, octx->taglen)
+                != 1)
+                return 0;
+            octx->iv_set = 1;
+        }
+        octx->key_set = 1;
+    } else {
+        /* If key set use IV, otherwise copy */
+        if (octx->key_set)
+            CRYPTO_ocb128_setiv(&octx->ocb, iv, octx->ivlen, octx->taglen);
+        else
+            memcpy(octx->iv, iv, octx->ivlen);
+        octx->iv_set = 1;
+    }
+    return 1;
+}
+
+#  define aes_t4_ocb_cipher aes_ocb_cipher
+static int aes_t4_ocb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                             const unsigned char *in, size_t len);
+# endif                        /* OPENSSL_NO_OCB */
+
+# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
+static const EVP_CIPHER aes_t4_##keylen##_##mode = { \
+        nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
+        flags|EVP_CIPH_##MODE##_MODE,   \
+        aes_t4_init_key,                \
+        aes_t4_##mode##_cipher,         \
+        NULL,                           \
+        sizeof(EVP_AES_KEY),            \
+        NULL,NULL,NULL,NULL }; \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+        nid##_##keylen##_##nmode,blocksize,     \
+        keylen/8,ivlen, \
+        flags|EVP_CIPH_##MODE##_MODE,   \
+        aes_init_key,                   \
+        aes_##mode##_cipher,            \
+        NULL,                           \
+        sizeof(EVP_AES_KEY),            \
+        NULL,NULL,NULL,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return SPARC_AES_CAPABLE?&aes_t4_##keylen##_##mode:&aes_##keylen##_##mode; }
+
+# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
+static const EVP_CIPHER aes_t4_##keylen##_##mode = { \
+        nid##_##keylen##_##mode,blocksize, \
+        (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+        flags|EVP_CIPH_##MODE##_MODE,   \
+        aes_t4_##mode##_init_key,       \
+        aes_t4_##mode##_cipher,         \
+        aes_##mode##_cleanup,           \
+        sizeof(EVP_AES_##MODE##_CTX),   \
+        NULL,NULL,aes_##mode##_ctrl,NULL }; \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+        nid##_##keylen##_##mode,blocksize, \
+        (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+        flags|EVP_CIPH_##MODE##_MODE,   \
+        aes_##mode##_init_key,          \
+        aes_##mode##_cipher,            \
+        aes_##mode##_cleanup,           \
+        sizeof(EVP_AES_##MODE##_CTX),   \
+        NULL,NULL,aes_##mode##_ctrl,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return SPARC_AES_CAPABLE?&aes_t4_##keylen##_##mode:&aes_##keylen##_##mode; }
+
+#else
+
+# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+        nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
+        flags|EVP_CIPH_##MODE##_MODE,   \
+        aes_init_key,                   \
+        aes_##mode##_cipher,            \
+        NULL,                           \
+        sizeof(EVP_AES_KEY),            \
+        NULL,NULL,NULL,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return &aes_##keylen##_##mode; }
+
+# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
+static const EVP_CIPHER aes_##keylen##_##mode = { \
+        nid##_##keylen##_##mode,blocksize, \
+        (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
+        flags|EVP_CIPH_##MODE##_MODE,   \
+        aes_##mode##_init_key,          \
+        aes_##mode##_cipher,            \
+        aes_##mode##_cleanup,           \
+        sizeof(EVP_AES_##MODE##_CTX),   \
+        NULL,NULL,aes_##mode##_ctrl,NULL }; \
+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
+{ return &aes_##keylen##_##mode; }
+
+#endif
+
+#if defined(OPENSSL_CPUID_OBJ) && (defined(__arm__) || defined(__arm) || defined(__aarch64__))
+# include "arm_arch.h"
+# if __ARM_MAX_ARCH__>=7
+#  if defined(BSAES_ASM)
+#   define BSAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON)
+#  endif
+#  if defined(VPAES_ASM)
+#   define VPAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON)
+#  endif
+#  define HWAES_CAPABLE (OPENSSL_armcap_P & ARMV8_AES)
+#  define HWAES_set_encrypt_key aes_v8_set_encrypt_key
+#  define HWAES_set_decrypt_key aes_v8_set_decrypt_key
+#  define HWAES_encrypt aes_v8_encrypt
+#  define HWAES_decrypt aes_v8_decrypt
+#  define HWAES_cbc_encrypt aes_v8_cbc_encrypt
+#  define HWAES_ctr32_encrypt_blocks aes_v8_ctr32_encrypt_blocks
+# endif
+#endif
+
+#if defined(HWAES_CAPABLE)
+int HWAES_set_encrypt_key(const unsigned char *userKey, const int bits,
+                          AES_KEY *key);
+int HWAES_set_decrypt_key(const unsigned char *userKey, const int bits,
+                          AES_KEY *key);
+void HWAES_encrypt(const unsigned char *in, unsigned char *out,
+                   const AES_KEY *key);
+void HWAES_decrypt(const unsigned char *in, unsigned char *out,
+                   const AES_KEY *key);
+void HWAES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                       size_t length, const AES_KEY *key,
+                       unsigned char *ivec, const int enc);
+void HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
+                                size_t len, const AES_KEY *key,
+                                const unsigned char ivec[16]);
+void HWAES_xts_encrypt(const unsigned char *inp, unsigned char *out,
+                       size_t len, const AES_KEY *key1,
+                       const AES_KEY *key2, const unsigned char iv[16]);
+void HWAES_xts_decrypt(const unsigned char *inp, unsigned char *out,
+                       size_t len, const AES_KEY *key1,
+                       const AES_KEY *key2, const unsigned char iv[16]);
+#endif
+
+#define BLOCK_CIPHER_generic_pack(nid,keylen,flags)             \
+        BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)     \
+        BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)      \
+        BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)   \
+        BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)   \
+        BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags)       \
+        BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags)       \
+        BLOCK_CIPHER_generic(nid,keylen,1,16,ctr,ctr,CTR,flags)
+
+static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                        const unsigned char *iv, int enc)
+{
+    int ret, mode;
+    EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx);
+
+    mode = EVP_CIPHER_CTX_mode(ctx);
+    if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
+        && !enc) {
+#ifdef HWAES_CAPABLE
+        if (HWAES_CAPABLE) {
+            ret = HWAES_set_decrypt_key(key,
+                                        EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                        &dat->ks.ks);
+            dat->block = (block128_f) HWAES_decrypt;
+            dat->stream.cbc = NULL;
+# ifdef HWAES_cbc_encrypt
+            if (mode == EVP_CIPH_CBC_MODE)
+                dat->stream.cbc = (cbc128_f) HWAES_cbc_encrypt;
+# endif
+        } else
+#endif
+#ifdef BSAES_CAPABLE
+        if (BSAES_CAPABLE && mode == EVP_CIPH_CBC_MODE) {
+            ret = AES_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                      &dat->ks.ks);
+            dat->block = (block128_f) AES_decrypt;
+            dat->stream.cbc = (cbc128_f) bsaes_cbc_encrypt;
+        } else
+#endif
+#ifdef VPAES_CAPABLE
+        if (VPAES_CAPABLE) {
+            ret = vpaes_set_decrypt_key(key,
+                                        EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                        &dat->ks.ks);
+            dat->block = (block128_f) vpaes_decrypt;
+            dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+                (cbc128_f) vpaes_cbc_encrypt : NULL;
+        } else
+#endif
+        {
+            ret = AES_set_decrypt_key(key,
+                                      EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                      &dat->ks.ks);
+            dat->block = (block128_f) AES_decrypt;
+            dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+                (cbc128_f) AES_cbc_encrypt : NULL;
+        }
+    } else
+#ifdef HWAES_CAPABLE
+    if (HWAES_CAPABLE) {
+        ret = HWAES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                    &dat->ks.ks);
+        dat->block = (block128_f) HWAES_encrypt;
+        dat->stream.cbc = NULL;
+# ifdef HWAES_cbc_encrypt
+        if (mode == EVP_CIPH_CBC_MODE)
+            dat->stream.cbc = (cbc128_f) HWAES_cbc_encrypt;
+        else
+# endif
+# ifdef HWAES_ctr32_encrypt_blocks
+        if (mode == EVP_CIPH_CTR_MODE)
+            dat->stream.ctr = (ctr128_f) HWAES_ctr32_encrypt_blocks;
+        else
+# endif
+            (void)0;            /* terminate potentially open 'else' */
+    } else
+#endif
+#ifdef BSAES_CAPABLE
+    if (BSAES_CAPABLE && mode == EVP_CIPH_CTR_MODE) {
+        ret = AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                  &dat->ks.ks);
+        dat->block = (block128_f) AES_encrypt;
+        dat->stream.ctr = (ctr128_f) bsaes_ctr32_encrypt_blocks;
+    } else
+#endif
+#ifdef VPAES_CAPABLE
+    if (VPAES_CAPABLE) {
+        ret = vpaes_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                    &dat->ks.ks);
+        dat->block = (block128_f) vpaes_encrypt;
+        dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+            (cbc128_f) vpaes_cbc_encrypt : NULL;
+    } else
+#endif
+    {
+        ret = AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                  &dat->ks.ks);
+        dat->block = (block128_f) AES_encrypt;
+        dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+            (cbc128_f) AES_cbc_encrypt : NULL;
+#ifdef AES_CTR_ASM
+        if (mode == EVP_CIPH_CTR_MODE)
+            dat->stream.ctr = (ctr128_f) AES_ctr32_encrypt;
+#endif
+    }
+
+    if (ret < 0) {
+        EVPerr(EVP_F_AES_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                          const unsigned char *in, size_t len)
+{
+    EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx);
+
+    if (dat->stream.cbc)
+        (*dat->stream.cbc) (in, out, len, &dat->ks,
+                            EVP_CIPHER_CTX_iv_noconst(ctx),
+                            EVP_CIPHER_CTX_encrypting(ctx));
+    else if (EVP_CIPHER_CTX_encrypting(ctx))
+        CRYPTO_cbc128_encrypt(in, out, len, &dat->ks,
+                              EVP_CIPHER_CTX_iv_noconst(ctx), dat->block);
+    else
+        CRYPTO_cbc128_decrypt(in, out, len, &dat->ks,
+                              EVP_CIPHER_CTX_iv_noconst(ctx), dat->block);
+
+    return 1;
+}
+
+static int aes_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                          const unsigned char *in, size_t len)
+{
+    size_t bl = EVP_CIPHER_CTX_block_size(ctx);
+    size_t i;
+    EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx);
+
+    if (len < bl)
+        return 1;
+
+    for (i = 0, len -= bl; i <= len; i += bl)
+        (*dat->block) (in + i, out + i, &dat->ks);
+
+    return 1;
+}
+
+static int aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                          const unsigned char *in, size_t len)
+{
+    EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx);
+
+    int num = EVP_CIPHER_CTX_num(ctx);
+    CRYPTO_ofb128_encrypt(in, out, len, &dat->ks,
+                          EVP_CIPHER_CTX_iv_noconst(ctx), &num, dat->block);
+    EVP_CIPHER_CTX_set_num(ctx, num);
+    return 1;
+}
+
+static int aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                          const unsigned char *in, size_t len)
+{
+    EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx);
+
+    int num = EVP_CIPHER_CTX_num(ctx);
+    CRYPTO_cfb128_encrypt(in, out, len, &dat->ks,
+                          EVP_CIPHER_CTX_iv_noconst(ctx), &num,
+                          EVP_CIPHER_CTX_encrypting(ctx), dat->block);
+    EVP_CIPHER_CTX_set_num(ctx, num);
+    return 1;
+}
+
+static int aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                           const unsigned char *in, size_t len)
+{
+    EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx);
+
+    int num = EVP_CIPHER_CTX_num(ctx);
+    CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks,
+                            EVP_CIPHER_CTX_iv_noconst(ctx), &num,
+                            EVP_CIPHER_CTX_encrypting(ctx), dat->block);
+    EVP_CIPHER_CTX_set_num(ctx, num);
+    return 1;
+}
+
+static int aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                           const unsigned char *in, size_t len)
+{
+    EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx);
+
+    if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) {
+        int num = EVP_CIPHER_CTX_num(ctx);
+        CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks,
+                                EVP_CIPHER_CTX_iv_noconst(ctx), &num,
+                                EVP_CIPHER_CTX_encrypting(ctx), dat->block);
+        EVP_CIPHER_CTX_set_num(ctx, num);
+        return 1;
+    }
+
+    while (len >= MAXBITCHUNK) {
+        int num = EVP_CIPHER_CTX_num(ctx);
+        CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks,
+                                EVP_CIPHER_CTX_iv_noconst(ctx), &num,
+                                EVP_CIPHER_CTX_encrypting(ctx), dat->block);
+        EVP_CIPHER_CTX_set_num(ctx, num);
+        len -= MAXBITCHUNK;
+    }
+    if (len) {
+        int num = EVP_CIPHER_CTX_num(ctx);
+        CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks,
+                                EVP_CIPHER_CTX_iv_noconst(ctx), &num,
+                                EVP_CIPHER_CTX_encrypting(ctx), dat->block);
+        EVP_CIPHER_CTX_set_num(ctx, num);
+    }
+
+    return 1;
+}
+
+static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                          const unsigned char *in, size_t len)
+{
+    unsigned int num = EVP_CIPHER_CTX_num(ctx);
+    EVP_AES_KEY *dat = EVP_C_DATA(EVP_AES_KEY,ctx);
+
+    if (dat->stream.ctr)
+        CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks,
+                                    EVP_CIPHER_CTX_iv_noconst(ctx),
+                                    EVP_CIPHER_CTX_buf_noconst(ctx),
+                                    &num, dat->stream.ctr);
+    else
+        CRYPTO_ctr128_encrypt(in, out, len, &dat->ks,
+                              EVP_CIPHER_CTX_iv_noconst(ctx),
+                              EVP_CIPHER_CTX_buf_noconst(ctx), &num,
+                              dat->block);
+    EVP_CIPHER_CTX_set_num(ctx, num);
+    return 1;
+}
+
+BLOCK_CIPHER_generic_pack(NID_aes, 128, 0)
+    BLOCK_CIPHER_generic_pack(NID_aes, 192, 0)
+    BLOCK_CIPHER_generic_pack(NID_aes, 256, 0)
+
+static int aes_gcm_cleanup(EVP_CIPHER_CTX *c)
+{
+    EVP_AES_GCM_CTX *gctx = EVP_C_DATA(EVP_AES_GCM_CTX,c);
+    if (gctx == NULL)
+        return 0;
+    OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm));
+    if (gctx->iv != EVP_CIPHER_CTX_iv_noconst(c))
+        OPENSSL_free(gctx->iv);
+    return 1;
+}
+
+/* increment counter (64-bit int) by 1 */
+static void ctr64_inc(unsigned char *counter)
+{
+    int n = 8;
+    unsigned char c;
+
+    do {
+        --n;
+        c = counter[n];
+        ++c;
+        counter[n] = c;
+        if (c)
+            return;
+    } while (n);
+}
+
+static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+    EVP_AES_GCM_CTX *gctx = EVP_C_DATA(EVP_AES_GCM_CTX,c);
+    switch (type) {
+    case EVP_CTRL_INIT:
+        gctx->key_set = 0;
+        gctx->iv_set = 0;
+        gctx->ivlen = EVP_CIPHER_CTX_iv_length(c);
+        gctx->iv = EVP_CIPHER_CTX_iv_noconst(c);
+        gctx->taglen = -1;
+        gctx->iv_gen = 0;
+        gctx->tls_aad_len = -1;
+        return 1;
+
+    case EVP_CTRL_AEAD_SET_IVLEN:
+        if (arg <= 0)
+            return 0;
+        /* Allocate memory for IV if needed */
+        if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) {
+            if (gctx->iv != EVP_CIPHER_CTX_iv_noconst(c))
+                OPENSSL_free(gctx->iv);
+            gctx->iv = OPENSSL_malloc(arg);
+            if (gctx->iv == NULL)
+                return 0;
+        }
+        gctx->ivlen = arg;
+        return 1;
+
+    case EVP_CTRL_AEAD_SET_TAG:
+        if (arg <= 0 || arg > 16 || EVP_CIPHER_CTX_encrypting(c))
+            return 0;
+        memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg);
+        gctx->taglen = arg;
+        return 1;
+
+    case EVP_CTRL_AEAD_GET_TAG:
+        if (arg <= 0 || arg > 16 || !EVP_CIPHER_CTX_encrypting(c)
+            || gctx->taglen < 0)
+            return 0;
+        memcpy(ptr, EVP_CIPHER_CTX_buf_noconst(c), arg);
+        return 1;
+
+    case EVP_CTRL_GCM_SET_IV_FIXED:
+        /* Special case: -1 length restores whole IV */
+        if (arg == -1) {
+            memcpy(gctx->iv, ptr, gctx->ivlen);
+            gctx->iv_gen = 1;
+            return 1;
+        }
+        /*
+         * Fixed field must be at least 4 bytes and invocation field at least
+         * 8.
+         */
+        if ((arg < 4) || (gctx->ivlen - arg) < 8)
+            return 0;
+        if (arg)
+            memcpy(gctx->iv, ptr, arg);
+        if (EVP_CIPHER_CTX_encrypting(c)
+            && RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0)
+            return 0;
+        gctx->iv_gen = 1;
+        return 1;
+
+    case EVP_CTRL_GCM_IV_GEN:
+        if (gctx->iv_gen == 0 || gctx->key_set == 0)
+            return 0;
+        CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
+        if (arg <= 0 || arg > gctx->ivlen)
+            arg = gctx->ivlen;
+        memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg);
+        /*
+         * Invocation field will be at least 8 bytes in size and so no need
+         * to check wrap around or increment more than last 8 bytes.
+         */
+        ctr64_inc(gctx->iv + gctx->ivlen - 8);
+        gctx->iv_set = 1;
+        return 1;
+
+    case EVP_CTRL_GCM_SET_IV_INV:
+        if (gctx->iv_gen == 0 || gctx->key_set == 0
+            || EVP_CIPHER_CTX_encrypting(c))
+            return 0;
+        memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg);
+        CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
+        gctx->iv_set = 1;
+        return 1;
+
+    case EVP_CTRL_AEAD_TLS1_AAD:
+        /* Save the AAD for later use */
+        if (arg != EVP_AEAD_TLS1_AAD_LEN)
+            return 0;
+        memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg);
+        gctx->tls_aad_len = arg;
+        {
+            unsigned int len =
+                EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] << 8
+                | EVP_CIPHER_CTX_buf_noconst(c)[arg - 1];
+            /* Correct length for explicit IV */
+            if (len < EVP_GCM_TLS_EXPLICIT_IV_LEN)
+                return 0;
+            len -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
+            /* If decrypting correct for tag too */
+            if (!EVP_CIPHER_CTX_encrypting(c)) {
+                if (len < EVP_GCM_TLS_TAG_LEN)
+                    return 0;
+                len -= EVP_GCM_TLS_TAG_LEN;
+            }
+            EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] = len >> 8;
+            EVP_CIPHER_CTX_buf_noconst(c)[arg - 1] = len & 0xff;
+        }
+        /* Extra padding: tag appended to record */
+        return EVP_GCM_TLS_TAG_LEN;
+
+    case EVP_CTRL_COPY:
+        {
+            EVP_CIPHER_CTX *out = ptr;
+            EVP_AES_GCM_CTX *gctx_out = EVP_C_DATA(EVP_AES_GCM_CTX,out);
+            if (gctx->gcm.key) {
+                if (gctx->gcm.key != &gctx->ks)
+                    return 0;
+                gctx_out->gcm.key = &gctx_out->ks;
+            }
+            if (gctx->iv == EVP_CIPHER_CTX_iv_noconst(c))
+                gctx_out->iv = EVP_CIPHER_CTX_iv_noconst(out);
+            else {
+                gctx_out->iv = OPENSSL_malloc(gctx->ivlen);
+                if (gctx_out->iv == NULL)
+                    return 0;
+                memcpy(gctx_out->iv, gctx->iv, gctx->ivlen);
+            }
+            return 1;
+        }
+
+    default:
+        return -1;
+
+    }
+}
+
+static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                            const unsigned char *iv, int enc)
+{
+    EVP_AES_GCM_CTX *gctx = EVP_C_DATA(EVP_AES_GCM_CTX,ctx);
+    if (!iv && !key)
+        return 1;
+    if (key) {
+        do {
+#ifdef HWAES_CAPABLE
+            if (HWAES_CAPABLE) {
+                HWAES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                      &gctx->ks.ks);
+                CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
+                                   (block128_f) HWAES_encrypt);
+# ifdef HWAES_ctr32_encrypt_blocks
+                gctx->ctr = (ctr128_f) HWAES_ctr32_encrypt_blocks;
+# else
+                gctx->ctr = NULL;
+# endif
+                break;
+            } else
+#endif
+#ifdef BSAES_CAPABLE
+            if (BSAES_CAPABLE) {
+                AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                    &gctx->ks.ks);
+                CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
+                                   (block128_f) AES_encrypt);
+                gctx->ctr = (ctr128_f) bsaes_ctr32_encrypt_blocks;
+                break;
+            } else
+#endif
+#ifdef VPAES_CAPABLE
+            if (VPAES_CAPABLE) {
+                vpaes_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                      &gctx->ks.ks);
+                CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
+                                   (block128_f) vpaes_encrypt);
+                gctx->ctr = NULL;
+                break;
+            } else
+#endif
+                (void)0;        /* terminate potentially open 'else' */
+
+            AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                &gctx->ks.ks);
+            CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
+                               (block128_f) AES_encrypt);
+#ifdef AES_CTR_ASM
+            gctx->ctr = (ctr128_f) AES_ctr32_encrypt;
+#else
+            gctx->ctr = NULL;
+#endif
+        } while (0);
+
+        /*
+         * If we have an iv can set it directly, otherwise use saved IV.
+         */
+        if (iv == NULL && gctx->iv_set)
+            iv = gctx->iv;
+        if (iv) {
+            CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+            gctx->iv_set = 1;
+        }
+        gctx->key_set = 1;
+    } else {
+        /* If key set use IV, otherwise copy */
+        if (gctx->key_set)
+            CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
+        else
+            memcpy(gctx->iv, iv, gctx->ivlen);
+        gctx->iv_set = 1;
+        gctx->iv_gen = 0;
+    }
+    return 1;
+}
+
+/*
+ * Handle TLS GCM packet format. This consists of the last portion of the IV
+ * followed by the payload and finally the tag. On encrypt generate IV,
+ * encrypt payload and write the tag. On verify retrieve IV, decrypt payload
+ * and verify tag.
+ */
+
+static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                              const unsigned char *in, size_t len)
+{
+    EVP_AES_GCM_CTX *gctx = EVP_C_DATA(EVP_AES_GCM_CTX,ctx);
+    int rv = -1;
+    /* Encrypt/decrypt must be performed in place */
+    if (out != in
+        || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN))
+        return -1;
+    /*
+     * Set IV from start of buffer or generate IV and write to start of
+     * buffer.
+     */
+    if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CIPHER_CTX_encrypting(ctx) ?
+                            EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV,
+                            EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0)
+        goto err;
+    /* Use saved AAD */
+    if (CRYPTO_gcm128_aad(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx),
+                          gctx->tls_aad_len))
+        goto err;
+    /* Fix buffer and length to point to payload */
+    in += EVP_GCM_TLS_EXPLICIT_IV_LEN;
+    out += EVP_GCM_TLS_EXPLICIT_IV_LEN;
+    len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
+    if (EVP_CIPHER_CTX_encrypting(ctx)) {
+        /* Encrypt payload */
+        if (gctx->ctr) {
+            size_t bulk = 0;
+#if defined(AES_GCM_ASM)
+            if (len >= 32 && AES_GCM_ASM(gctx)) {
+                if (CRYPTO_gcm128_encrypt(&gctx->gcm, NULL, NULL, 0))
+                    return -1;
+
+                bulk = AES_gcm_encrypt(in, out, len,
+                                       gctx->gcm.key,
+                                       gctx->gcm.Yi.c, gctx->gcm.Xi.u);
+                gctx->gcm.len.u[1] += bulk;
+            }
+#endif
+            if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
+                                            in + bulk,
+                                            out + bulk,
+                                            len - bulk, gctx->ctr))
+                goto err;
+        } else {
+            size_t bulk = 0;
+#if defined(AES_GCM_ASM2)
+            if (len >= 32 && AES_GCM_ASM2(gctx)) {
+                if (CRYPTO_gcm128_encrypt(&gctx->gcm, NULL, NULL, 0))
+                    return -1;
+
+                bulk = AES_gcm_encrypt(in, out, len,
+                                       gctx->gcm.key,
+                                       gctx->gcm.Yi.c, gctx->gcm.Xi.u);
+                gctx->gcm.len.u[1] += bulk;
+            }
+#endif
+            if (CRYPTO_gcm128_encrypt(&gctx->gcm,
+                                      in + bulk, out + bulk, len - bulk))
+                goto err;
+        }
+        out += len;
+        /* Finally write tag */
+        CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN);
+        rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
+    } else {
+        /* Decrypt */
+        if (gctx->ctr) {
+            size_t bulk = 0;
+#if defined(AES_GCM_ASM)
+            if (len >= 16 && AES_GCM_ASM(gctx)) {
+                if (CRYPTO_gcm128_decrypt(&gctx->gcm, NULL, NULL, 0))
+                    return -1;
+
+                bulk = AES_gcm_decrypt(in, out, len,
+                                       gctx->gcm.key,
+                                       gctx->gcm.Yi.c, gctx->gcm.Xi.u);
+                gctx->gcm.len.u[1] += bulk;
+            }
+#endif
+            if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
+                                            in + bulk,
+                                            out + bulk,
+                                            len - bulk, gctx->ctr))
+                goto err;
+        } else {
+            size_t bulk = 0;
+#if defined(AES_GCM_ASM2)
+            if (len >= 16 && AES_GCM_ASM2(gctx)) {
+                if (CRYPTO_gcm128_decrypt(&gctx->gcm, NULL, NULL, 0))
+                    return -1;
+
+                bulk = AES_gcm_decrypt(in, out, len,
+                                       gctx->gcm.key,
+                                       gctx->gcm.Yi.c, gctx->gcm.Xi.u);
+                gctx->gcm.len.u[1] += bulk;
+            }
+#endif
+            if (CRYPTO_gcm128_decrypt(&gctx->gcm,
+                                      in + bulk, out + bulk, len - bulk))
+                goto err;
+        }
+        /* Retrieve tag */
+        CRYPTO_gcm128_tag(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx),
+                          EVP_GCM_TLS_TAG_LEN);
+        /* If tag mismatch wipe buffer */
+        if (CRYPTO_memcmp(EVP_CIPHER_CTX_buf_noconst(ctx), in + len,
+                          EVP_GCM_TLS_TAG_LEN)) {
+            OPENSSL_cleanse(out, len);
+            goto err;
+        }
+        rv = len;
+    }
+
+ err:
+    gctx->iv_set = 0;
+    gctx->tls_aad_len = -1;
+    return rv;
+}
+
+static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                          const unsigned char *in, size_t len)
+{
+    EVP_AES_GCM_CTX *gctx = EVP_C_DATA(EVP_AES_GCM_CTX,ctx);
+    /* If not set up, return error */
+    if (!gctx->key_set)
+        return -1;
+
+    if (gctx->tls_aad_len >= 0)
+        return aes_gcm_tls_cipher(ctx, out, in, len);
+
+    if (!gctx->iv_set)
+        return -1;
+    if (in) {
+        if (out == NULL) {
+            if (CRYPTO_gcm128_aad(&gctx->gcm, in, len))
+                return -1;
+        } else if (EVP_CIPHER_CTX_encrypting(ctx)) {
+            if (gctx->ctr) {
+                size_t bulk = 0;
+#if defined(AES_GCM_ASM)
+                if (len >= 32 && AES_GCM_ASM(gctx)) {
+                    size_t res = (16 - gctx->gcm.mres) % 16;
+
+                    if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, res))
+                        return -1;
+
+                    bulk = AES_gcm_encrypt(in + res,
+                                           out + res, len - res,
+                                           gctx->gcm.key, gctx->gcm.Yi.c,
+                                           gctx->gcm.Xi.u);
+                    gctx->gcm.len.u[1] += bulk;
+                    bulk += res;
+                }
+#endif
+                if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
+                                                in + bulk,
+                                                out + bulk,
+                                                len - bulk, gctx->ctr))
+                    return -1;
+            } else {
+                size_t bulk = 0;
+#if defined(AES_GCM_ASM2)
+                if (len >= 32 && AES_GCM_ASM2(gctx)) {
+                    size_t res = (16 - gctx->gcm.mres) % 16;
+
+                    if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, res))
+                        return -1;
+
+                    bulk = AES_gcm_encrypt(in + res,
+                                           out + res, len - res,
+                                           gctx->gcm.key, gctx->gcm.Yi.c,
+                                           gctx->gcm.Xi.u);
+                    gctx->gcm.len.u[1] += bulk;
+                    bulk += res;
+                }
+#endif
+                if (CRYPTO_gcm128_encrypt(&gctx->gcm,
+                                          in + bulk, out + bulk, len - bulk))
+                    return -1;
+            }
+        } else {
+            if (gctx->ctr) {
+                size_t bulk = 0;
+#if defined(AES_GCM_ASM)
+                if (len >= 16 && AES_GCM_ASM(gctx)) {
+                    size_t res = (16 - gctx->gcm.mres) % 16;
+
+                    if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, res))
+                        return -1;
+
+                    bulk = AES_gcm_decrypt(in + res,
+                                           out + res, len - res,
+                                           gctx->gcm.key,
+                                           gctx->gcm.Yi.c, gctx->gcm.Xi.u);
+                    gctx->gcm.len.u[1] += bulk;
+                    bulk += res;
+                }
+#endif
+                if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
+                                                in + bulk,
+                                                out + bulk,
+                                                len - bulk, gctx->ctr))
+                    return -1;
+            } else {
+                size_t bulk = 0;
+#if defined(AES_GCM_ASM2)
+                if (len >= 16 && AES_GCM_ASM2(gctx)) {
+                    size_t res = (16 - gctx->gcm.mres) % 16;
+
+                    if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, res))
+                        return -1;
+
+                    bulk = AES_gcm_decrypt(in + res,
+                                           out + res, len - res,
+                                           gctx->gcm.key,
+                                           gctx->gcm.Yi.c, gctx->gcm.Xi.u);
+                    gctx->gcm.len.u[1] += bulk;
+                    bulk += res;
+                }
+#endif
+                if (CRYPTO_gcm128_decrypt(&gctx->gcm,
+                                          in + bulk, out + bulk, len - bulk))
+                    return -1;
+            }
+        }
+        return len;
+    } else {
+        if (!EVP_CIPHER_CTX_encrypting(ctx)) {
+            if (gctx->taglen < 0)
+                return -1;
+            if (CRYPTO_gcm128_finish(&gctx->gcm,
+                                     EVP_CIPHER_CTX_buf_noconst(ctx),
+                                     gctx->taglen) != 0)
+                return -1;
+            gctx->iv_set = 0;
+            return 0;
+        }
+        CRYPTO_gcm128_tag(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx), 16);
+        gctx->taglen = 16;
+        /* Don't reuse the IV */
+        gctx->iv_set = 0;
+        return 0;
+    }
+
+}
+
+#define CUSTOM_FLAGS    (EVP_CIPH_FLAG_DEFAULT_ASN1 \
+                | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
+                | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
+                | EVP_CIPH_CUSTOM_COPY)
+
+BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, gcm, GCM,
+                    EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
+    BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, gcm, GCM,
+                    EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
+    BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, gcm, GCM,
+                    EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
+
+static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+    EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,c);
+    if (type == EVP_CTRL_COPY) {
+        EVP_CIPHER_CTX *out = ptr;
+        EVP_AES_XTS_CTX *xctx_out = EVP_C_DATA(EVP_AES_XTS_CTX,out);
+        if (xctx->xts.key1) {
+            if (xctx->xts.key1 != &xctx->ks1)
+                return 0;
+            xctx_out->xts.key1 = &xctx_out->ks1;
+        }
+        if (xctx->xts.key2) {
+            if (xctx->xts.key2 != &xctx->ks2)
+                return 0;
+            xctx_out->xts.key2 = &xctx_out->ks2;
+        }
+        return 1;
+    } else if (type != EVP_CTRL_INIT)
+        return -1;
+    /* key1 and key2 are used as an indicator both key and IV are set */
+    xctx->xts.key1 = NULL;
+    xctx->xts.key2 = NULL;
+    return 1;
+}
+
+static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                            const unsigned char *iv, int enc)
+{
+    EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,ctx);
+    if (!iv && !key)
+        return 1;
+
+    if (key)
+        do {
+#ifdef AES_XTS_ASM
+            xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt;
+#else
+            xctx->stream = NULL;
+#endif
+            /* key_len is two AES keys */
+#ifdef HWAES_CAPABLE
+            if (HWAES_CAPABLE) {
+                if (enc) {
+                    HWAES_set_encrypt_key(key,
+                                          EVP_CIPHER_CTX_key_length(ctx) * 4,
+                                          &xctx->ks1.ks);
+                    xctx->xts.block1 = (block128_f) HWAES_encrypt;
+# ifdef HWAES_xts_encrypt
+                    xctx->stream = HWAES_xts_encrypt;
+# endif
+                } else {
+                    HWAES_set_decrypt_key(key,
+                                          EVP_CIPHER_CTX_key_length(ctx) * 4,
+                                          &xctx->ks1.ks);
+                    xctx->xts.block1 = (block128_f) HWAES_decrypt;
+# ifdef HWAES_xts_decrypt
+                    xctx->stream = HWAES_xts_decrypt;
+#endif
+                }
+
+                HWAES_set_encrypt_key(key + EVP_CIPHER_CTX_key_length(ctx) / 2,
+                                      EVP_CIPHER_CTX_key_length(ctx) * 4,
+                                      &xctx->ks2.ks);
+                xctx->xts.block2 = (block128_f) HWAES_encrypt;
+
+                xctx->xts.key1 = &xctx->ks1;
+                break;
+            } else
+#endif
+#ifdef BSAES_CAPABLE
+            if (BSAES_CAPABLE)
+                xctx->stream = enc ? bsaes_xts_encrypt : bsaes_xts_decrypt;
+            else
+#endif
+#ifdef VPAES_CAPABLE
+            if (VPAES_CAPABLE) {
+                if (enc) {
+                    vpaes_set_encrypt_key(key,
+                                          EVP_CIPHER_CTX_key_length(ctx) * 4,
+                                          &xctx->ks1.ks);
+                    xctx->xts.block1 = (block128_f) vpaes_encrypt;
+                } else {
+                    vpaes_set_decrypt_key(key,
+                                          EVP_CIPHER_CTX_key_length(ctx) * 4,
+                                          &xctx->ks1.ks);
+                    xctx->xts.block1 = (block128_f) vpaes_decrypt;
+                }
+
+                vpaes_set_encrypt_key(key + EVP_CIPHER_CTX_key_length(ctx) / 2,
+                                      EVP_CIPHER_CTX_key_length(ctx) * 4,
+                                      &xctx->ks2.ks);
+                xctx->xts.block2 = (block128_f) vpaes_encrypt;
+
+                xctx->xts.key1 = &xctx->ks1;
+                break;
+            } else
+#endif
+                (void)0;        /* terminate potentially open 'else' */
+
+            if (enc) {
+                AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 4,
+                                    &xctx->ks1.ks);
+                xctx->xts.block1 = (block128_f) AES_encrypt;
+            } else {
+                AES_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 4,
+                                    &xctx->ks1.ks);
+                xctx->xts.block1 = (block128_f) AES_decrypt;
+            }
+
+            AES_set_encrypt_key(key + EVP_CIPHER_CTX_key_length(ctx) / 2,
+                                EVP_CIPHER_CTX_key_length(ctx) * 4,
+                                &xctx->ks2.ks);
+            xctx->xts.block2 = (block128_f) AES_encrypt;
+
+            xctx->xts.key1 = &xctx->ks1;
+        } while (0);
+
+    if (iv) {
+        xctx->xts.key2 = &xctx->ks2;
+        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 16);
+    }
+
+    return 1;
+}
+
+static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                          const unsigned char *in, size_t len)
+{
+    EVP_AES_XTS_CTX *xctx = EVP_C_DATA(EVP_AES_XTS_CTX,ctx);
+    if (!xctx->xts.key1 || !xctx->xts.key2)
+        return 0;
+    if (!out || !in || len < AES_BLOCK_SIZE)
+        return 0;
+    if (xctx->stream)
+        (*xctx->stream) (in, out, len,
+                         xctx->xts.key1, xctx->xts.key2,
+                         EVP_CIPHER_CTX_iv_noconst(ctx));
+    else if (CRYPTO_xts128_encrypt(&xctx->xts, EVP_CIPHER_CTX_iv_noconst(ctx),
+                                   in, out, len,
+                                   EVP_CIPHER_CTX_encrypting(ctx)))
+        return 0;
+    return 1;
+}
+
+#define aes_xts_cleanup NULL
+
+#define XTS_FLAGS       (EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV \
+                         | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
+                         | EVP_CIPH_CUSTOM_COPY)
+
+BLOCK_CIPHER_custom(NID_aes, 128, 1, 16, xts, XTS, XTS_FLAGS)
+    BLOCK_CIPHER_custom(NID_aes, 256, 1, 16, xts, XTS, XTS_FLAGS)
+
+static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+    EVP_AES_CCM_CTX *cctx = EVP_C_DATA(EVP_AES_CCM_CTX,c);
+    switch (type) {
+    case EVP_CTRL_INIT:
+        cctx->key_set = 0;
+        cctx->iv_set = 0;
+        cctx->L = 8;
+        cctx->M = 12;
+        cctx->tag_set = 0;
+        cctx->len_set = 0;
+        cctx->tls_aad_len = -1;
+        return 1;
+
+    case EVP_CTRL_AEAD_TLS1_AAD:
+        /* Save the AAD for later use */
+        if (arg != EVP_AEAD_TLS1_AAD_LEN)
+            return 0;
+        memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg);
+        cctx->tls_aad_len = arg;
+        {
+            uint16_t len =
+                EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] << 8
+                | EVP_CIPHER_CTX_buf_noconst(c)[arg - 1];
+            /* Correct length for explicit IV */
+            if (len < EVP_CCM_TLS_EXPLICIT_IV_LEN)
+                return 0;
+            len -= EVP_CCM_TLS_EXPLICIT_IV_LEN;
+            /* If decrypting correct for tag too */
+            if (!EVP_CIPHER_CTX_encrypting(c)) {
+                if (len < cctx->M)
+                    return 0;
+                len -= cctx->M;
+            }
+            EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] = len >> 8;
+            EVP_CIPHER_CTX_buf_noconst(c)[arg - 1] = len & 0xff;
+        }
+        /* Extra padding: tag appended to record */
+        return cctx->M;
+
+    case EVP_CTRL_CCM_SET_IV_FIXED:
+        /* Sanity check length */
+        if (arg != EVP_CCM_TLS_FIXED_IV_LEN)
+            return 0;
+        /* Just copy to first part of IV */
+        memcpy(EVP_CIPHER_CTX_iv_noconst(c), ptr, arg);
+        return 1;
+
+    case EVP_CTRL_AEAD_SET_IVLEN:
+        arg = 15 - arg;
+    case EVP_CTRL_CCM_SET_L:
+        if (arg < 2 || arg > 8)
+            return 0;
+        cctx->L = arg;
+        return 1;
+
+    case EVP_CTRL_AEAD_SET_TAG:
+        if ((arg & 1) || arg < 4 || arg > 16)
+            return 0;
+        if (EVP_CIPHER_CTX_encrypting(c) && ptr)
+            return 0;
+        if (ptr) {
+            cctx->tag_set = 1;
+            memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg);
+        }
+        cctx->M = arg;
+        return 1;
+
+    case EVP_CTRL_AEAD_GET_TAG:
+        if (!EVP_CIPHER_CTX_encrypting(c) || !cctx->tag_set)
+            return 0;
+        if (!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg))
+            return 0;
+        cctx->tag_set = 0;
+        cctx->iv_set = 0;
+        cctx->len_set = 0;
+        return 1;
+
+    case EVP_CTRL_COPY:
+        {
+            EVP_CIPHER_CTX *out = ptr;
+            EVP_AES_CCM_CTX *cctx_out = EVP_C_DATA(EVP_AES_CCM_CTX,out);
+            if (cctx->ccm.key) {
+                if (cctx->ccm.key != &cctx->ks)
+                    return 0;
+                cctx_out->ccm.key = &cctx_out->ks;
+            }
+            return 1;
+        }
+
+    default:
+        return -1;
+
+    }
+}
+
+static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                            const unsigned char *iv, int enc)
+{
+    EVP_AES_CCM_CTX *cctx = EVP_C_DATA(EVP_AES_CCM_CTX,ctx);
+    if (!iv && !key)
+        return 1;
+    if (key)
+        do {
+#ifdef HWAES_CAPABLE
+            if (HWAES_CAPABLE) {
+                HWAES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                      &cctx->ks.ks);
+
+                CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+                                   &cctx->ks, (block128_f) HWAES_encrypt);
+                cctx->str = NULL;
+                cctx->key_set = 1;
+                break;
+            } else
+#endif
+#ifdef VPAES_CAPABLE
+            if (VPAES_CAPABLE) {
+                vpaes_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                      &cctx->ks.ks);
+                CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+                                   &cctx->ks, (block128_f) vpaes_encrypt);
+                cctx->str = NULL;
+                cctx->key_set = 1;
+                break;
+            }
+#endif
+            AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                &cctx->ks.ks);
+            CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
+                               &cctx->ks, (block128_f) AES_encrypt);
+            cctx->str = NULL;
+            cctx->key_set = 1;
+        } while (0);
+    if (iv) {
+        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 15 - cctx->L);
+        cctx->iv_set = 1;
+    }
+    return 1;
+}
+
+static int aes_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                              const unsigned char *in, size_t len)
+{
+    EVP_AES_CCM_CTX *cctx = EVP_C_DATA(EVP_AES_CCM_CTX,ctx);
+    CCM128_CONTEXT *ccm = &cctx->ccm;
+    /* Encrypt/decrypt must be performed in place */
+    if (out != in || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + (size_t)cctx->M))
+        return -1;
+    /* If encrypting set explicit IV from sequence number (start of AAD) */
+    if (EVP_CIPHER_CTX_encrypting(ctx))
+        memcpy(out, EVP_CIPHER_CTX_buf_noconst(ctx),
+               EVP_CCM_TLS_EXPLICIT_IV_LEN);
+    /* Get rest of IV from explicit IV */
+    memcpy(EVP_CIPHER_CTX_iv_noconst(ctx) + EVP_CCM_TLS_FIXED_IV_LEN, in,
+           EVP_CCM_TLS_EXPLICIT_IV_LEN);
+    /* Correct length value */
+    len -= EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M;
+    if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), 15 - cctx->L,
+                            len))
+            return -1;
+    /* Use saved AAD */
+    CRYPTO_ccm128_aad(ccm, EVP_CIPHER_CTX_buf_noconst(ctx), cctx->tls_aad_len);
+    /* Fix buffer to point to payload */
+    in += EVP_CCM_TLS_EXPLICIT_IV_LEN;
+    out += EVP_CCM_TLS_EXPLICIT_IV_LEN;
+    if (EVP_CIPHER_CTX_encrypting(ctx)) {
+        if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len,
+                                                    cctx->str) :
+            CRYPTO_ccm128_encrypt(ccm, in, out, len))
+            return -1;
+        if (!CRYPTO_ccm128_tag(ccm, out + len, cctx->M))
+            return -1;
+        return len + EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M;
+    } else {
+        if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len,
+                                                     cctx->str) :
+            !CRYPTO_ccm128_decrypt(ccm, in, out, len)) {
+            unsigned char tag[16];
+            if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) {
+                if (!CRYPTO_memcmp(tag, in + len, cctx->M))
+                    return len;
+            }
+        }
+        OPENSSL_cleanse(out, len);
+        return -1;
+    }
+}
+
+static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                          const unsigned char *in, size_t len)
+{
+    EVP_AES_CCM_CTX *cctx = EVP_C_DATA(EVP_AES_CCM_CTX,ctx);
+    CCM128_CONTEXT *ccm = &cctx->ccm;
+    /* If not set up, return error */
+    if (!cctx->key_set)
+        return -1;
+
+    if (cctx->tls_aad_len >= 0)
+        return aes_ccm_tls_cipher(ctx, out, in, len);
+
+    if (!cctx->iv_set)
+        return -1;
+
+    if (!EVP_CIPHER_CTX_encrypting(ctx) && !cctx->tag_set)
+        return -1;
+    if (!out) {
+        if (!in) {
+            if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx),
+                                    15 - cctx->L, len))
+                return -1;
+            cctx->len_set = 1;
+            return len;
+        }
+        /* If have AAD need message length */
+        if (!cctx->len_set && len)
+            return -1;
+        CRYPTO_ccm128_aad(ccm, in, len);
+        return len;
+    }
+    /* EVP_*Final() doesn't return any data */
+    if (!in)
+        return 0;
+    /* If not set length yet do it */
+    if (!cctx->len_set) {
+        if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx),
+                                15 - cctx->L, len))
+            return -1;
+        cctx->len_set = 1;
+    }
+    if (EVP_CIPHER_CTX_encrypting(ctx)) {
+        if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len,
+                                                    cctx->str) :
+            CRYPTO_ccm128_encrypt(ccm, in, out, len))
+            return -1;
+        cctx->tag_set = 1;
+        return len;
+    } else {
+        int rv = -1;
+        if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len,
+                                                     cctx->str) :
+            !CRYPTO_ccm128_decrypt(ccm, in, out, len)) {
+            unsigned char tag[16];
+            if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) {
+                if (!CRYPTO_memcmp(tag, EVP_CIPHER_CTX_buf_noconst(ctx),
+                                   cctx->M))
+                    rv = len;
+            }
+        }
+        if (rv == -1)
+            OPENSSL_cleanse(out, len);
+        cctx->iv_set = 0;
+        cctx->tag_set = 0;
+        cctx->len_set = 0;
+        return rv;
+    }
+}
+
+#define aes_ccm_cleanup NULL
+
+BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, ccm, CCM,
+                    EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
+    BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, ccm, CCM,
+                        EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
+    BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, ccm, CCM,
+                        EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
+
+typedef struct {
+    union {
+        double align;
+        AES_KEY ks;
+    } ks;
+    /* Indicates if IV has been set */
+    unsigned char *iv;
+} EVP_AES_WRAP_CTX;
+
+static int aes_wrap_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                             const unsigned char *iv, int enc)
+{
+    EVP_AES_WRAP_CTX *wctx = EVP_C_DATA(EVP_AES_WRAP_CTX,ctx);
+    if (!iv && !key)
+        return 1;
+    if (key) {
+        if (EVP_CIPHER_CTX_encrypting(ctx))
+            AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                &wctx->ks.ks);
+        else
+            AES_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                &wctx->ks.ks);
+        if (!iv)
+            wctx->iv = NULL;
+    }
+    if (iv) {
+        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, EVP_CIPHER_CTX_iv_length(ctx));
+        wctx->iv = EVP_CIPHER_CTX_iv_noconst(ctx);
+    }
+    return 1;
+}
+
+static int aes_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                           const unsigned char *in, size_t inlen)
+{
+    EVP_AES_WRAP_CTX *wctx = EVP_C_DATA(EVP_AES_WRAP_CTX,ctx);
+    size_t rv;
+    /* AES wrap with padding has IV length of 4, without padding 8 */
+    int pad = EVP_CIPHER_CTX_iv_length(ctx) == 4;
+    /* No final operation so always return zero length */
+    if (!in)
+        return 0;
+    /* Input length must always be non-zero */
+    if (!inlen)
+        return -1;
+    /* If decrypting need at least 16 bytes and multiple of 8 */
+    if (!EVP_CIPHER_CTX_encrypting(ctx) && (inlen < 16 || inlen & 0x7))
+        return -1;
+    /* If not padding input must be multiple of 8 */
+    if (!pad && inlen & 0x7)
+        return -1;
+    if (is_partially_overlapping(out, in, inlen)) {
+        EVPerr(EVP_F_AES_WRAP_CIPHER, EVP_R_PARTIALLY_OVERLAPPING);
+        return 0;
+    }
+    if (!out) {
+        if (EVP_CIPHER_CTX_encrypting(ctx)) {
+            /* If padding round up to multiple of 8 */
+            if (pad)
+                inlen = (inlen + 7) / 8 * 8;
+            /* 8 byte prefix */
+            return inlen + 8;
+        } else {
+            /*
+             * If not padding output will be exactly 8 bytes smaller than
+             * input. If padding it will be at least 8 bytes smaller but we
+             * don't know how much.
+             */
+            return inlen - 8;
+        }
+    }
+    if (pad) {
+        if (EVP_CIPHER_CTX_encrypting(ctx))
+            rv = CRYPTO_128_wrap_pad(&wctx->ks.ks, wctx->iv,
+                                     out, in, inlen,
+                                     (block128_f) AES_encrypt);
+        else
+            rv = CRYPTO_128_unwrap_pad(&wctx->ks.ks, wctx->iv,
+                                       out, in, inlen,
+                                       (block128_f) AES_decrypt);
+    } else {
+        if (EVP_CIPHER_CTX_encrypting(ctx))
+            rv = CRYPTO_128_wrap(&wctx->ks.ks, wctx->iv,
+                                 out, in, inlen, (block128_f) AES_encrypt);
+        else
+            rv = CRYPTO_128_unwrap(&wctx->ks.ks, wctx->iv,
+                                   out, in, inlen, (block128_f) AES_decrypt);
+    }
+    return rv ? (int)rv : -1;
+}
+
+#define WRAP_FLAGS      (EVP_CIPH_WRAP_MODE \
+                | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
+                | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1)
+
+static const EVP_CIPHER aes_128_wrap = {
+    NID_id_aes128_wrap,
+    8, 16, 8, WRAP_FLAGS,
+    aes_wrap_init_key, aes_wrap_cipher,
+    NULL,
+    sizeof(EVP_AES_WRAP_CTX),
+    NULL, NULL, NULL, NULL
+};
+
+const EVP_CIPHER *EVP_aes_128_wrap(void)
+{
+    return &aes_128_wrap;
+}
+
+static const EVP_CIPHER aes_192_wrap = {
+    NID_id_aes192_wrap,
+    8, 24, 8, WRAP_FLAGS,
+    aes_wrap_init_key, aes_wrap_cipher,
+    NULL,
+    sizeof(EVP_AES_WRAP_CTX),
+    NULL, NULL, NULL, NULL
+};
+
+const EVP_CIPHER *EVP_aes_192_wrap(void)
+{
+    return &aes_192_wrap;
+}
+
+static const EVP_CIPHER aes_256_wrap = {
+    NID_id_aes256_wrap,
+    8, 32, 8, WRAP_FLAGS,
+    aes_wrap_init_key, aes_wrap_cipher,
+    NULL,
+    sizeof(EVP_AES_WRAP_CTX),
+    NULL, NULL, NULL, NULL
+};
+
+const EVP_CIPHER *EVP_aes_256_wrap(void)
+{
+    return &aes_256_wrap;
+}
+
+static const EVP_CIPHER aes_128_wrap_pad = {
+    NID_id_aes128_wrap_pad,
+    8, 16, 4, WRAP_FLAGS,
+    aes_wrap_init_key, aes_wrap_cipher,
+    NULL,
+    sizeof(EVP_AES_WRAP_CTX),
+    NULL, NULL, NULL, NULL
+};
+
+const EVP_CIPHER *EVP_aes_128_wrap_pad(void)
+{
+    return &aes_128_wrap_pad;
+}
+
+static const EVP_CIPHER aes_192_wrap_pad = {
+    NID_id_aes192_wrap_pad,
+    8, 24, 4, WRAP_FLAGS,
+    aes_wrap_init_key, aes_wrap_cipher,
+    NULL,
+    sizeof(EVP_AES_WRAP_CTX),
+    NULL, NULL, NULL, NULL
+};
+
+const EVP_CIPHER *EVP_aes_192_wrap_pad(void)
+{
+    return &aes_192_wrap_pad;
+}
+
+static const EVP_CIPHER aes_256_wrap_pad = {
+    NID_id_aes256_wrap_pad,
+    8, 32, 4, WRAP_FLAGS,
+    aes_wrap_init_key, aes_wrap_cipher,
+    NULL,
+    sizeof(EVP_AES_WRAP_CTX),
+    NULL, NULL, NULL, NULL
+};
+
+const EVP_CIPHER *EVP_aes_256_wrap_pad(void)
+{
+    return &aes_256_wrap_pad;
+}
+
+#ifndef OPENSSL_NO_OCB
+static int aes_ocb_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+    EVP_AES_OCB_CTX *octx = EVP_C_DATA(EVP_AES_OCB_CTX,c);
+    EVP_CIPHER_CTX *newc;
+    EVP_AES_OCB_CTX *new_octx;
+
+    switch (type) {
+    case EVP_CTRL_INIT:
+        octx->key_set = 0;
+        octx->iv_set = 0;
+        octx->ivlen = EVP_CIPHER_CTX_iv_length(c);
+        octx->iv = EVP_CIPHER_CTX_iv_noconst(c);
+        octx->taglen = 16;
+        octx->data_buf_len = 0;
+        octx->aad_buf_len = 0;
+        return 1;
+
+    case EVP_CTRL_AEAD_SET_IVLEN:
+        /* IV len must be 1 to 15 */
+        if (arg <= 0 || arg > 15)
+            return 0;
+
+        octx->ivlen = arg;
+        return 1;
+
+    case EVP_CTRL_AEAD_SET_TAG:
+        if (!ptr) {
+            /* Tag len must be 0 to 16 */
+            if (arg < 0 || arg > 16)
+                return 0;
+
+            octx->taglen = arg;
+            return 1;
+        }
+        if (arg != octx->taglen || EVP_CIPHER_CTX_encrypting(c))
+            return 0;
+        memcpy(octx->tag, ptr, arg);
+        return 1;
+
+    case EVP_CTRL_AEAD_GET_TAG:
+        if (arg != octx->taglen || !EVP_CIPHER_CTX_encrypting(c))
+            return 0;
+
+        memcpy(ptr, octx->tag, arg);
+        return 1;
+
+    case EVP_CTRL_COPY:
+        newc = (EVP_CIPHER_CTX *)ptr;
+        new_octx = EVP_C_DATA(EVP_AES_OCB_CTX,newc);
+        return CRYPTO_ocb128_copy_ctx(&new_octx->ocb, &octx->ocb,
+                                      &new_octx->ksenc.ks,
+                                      &new_octx->ksdec.ks);
+
+    default:
+        return -1;
+
+    }
+}
+
+# ifdef HWAES_CAPABLE
+#  ifdef HWAES_ocb_encrypt
+void HWAES_ocb_encrypt(const unsigned char *in, unsigned char *out,
+                       size_t blocks, const void *key,
+                       size_t start_block_num,
+                       unsigned char offset_i[16],
+                       const unsigned char L_[][16],
+                       unsigned char checksum[16]);
+#  else
+#    define HWAES_ocb_encrypt ((ocb128_f)NULL)
+#  endif
+#  ifdef HWAES_ocb_decrypt
+void HWAES_ocb_decrypt(const unsigned char *in, unsigned char *out,
+                       size_t blocks, const void *key,
+                       size_t start_block_num,
+                       unsigned char offset_i[16],
+                       const unsigned char L_[][16],
+                       unsigned char checksum[16]);
+#  else
+#    define HWAES_ocb_decrypt ((ocb128_f)NULL)
+#  endif
+# endif
+
+static int aes_ocb_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                            const unsigned char *iv, int enc)
+{
+    EVP_AES_OCB_CTX *octx = EVP_C_DATA(EVP_AES_OCB_CTX,ctx);
+    if (!iv && !key)
+        return 1;
+    if (key) {
+        do {
+            /*
+             * We set both the encrypt and decrypt key here because decrypt
+             * needs both. We could possibly optimise to remove setting the
+             * decrypt for an encryption operation.
+             */
+# ifdef HWAES_CAPABLE
+            if (HWAES_CAPABLE) {
+                HWAES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                      &octx->ksenc.ks);
+                HWAES_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                      &octx->ksdec.ks);
+                if (!CRYPTO_ocb128_init(&octx->ocb,
+                                        &octx->ksenc.ks, &octx->ksdec.ks,
+                                        (block128_f) HWAES_encrypt,
+                                        (block128_f) HWAES_decrypt,
+                                        enc ? HWAES_ocb_encrypt
+                                            : HWAES_ocb_decrypt))
+                    return 0;
+                break;
+            }
+# endif
+# ifdef VPAES_CAPABLE
+            if (VPAES_CAPABLE) {
+                vpaes_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                      &octx->ksenc.ks);
+                vpaes_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                      &octx->ksdec.ks);
+                if (!CRYPTO_ocb128_init(&octx->ocb,
+                                        &octx->ksenc.ks, &octx->ksdec.ks,
+                                        (block128_f) vpaes_encrypt,
+                                        (block128_f) vpaes_decrypt,
+                                        NULL))
+                    return 0;
+                break;
+            }
+# endif
+            AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                &octx->ksenc.ks);
+            AES_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                &octx->ksdec.ks);
+            if (!CRYPTO_ocb128_init(&octx->ocb,
+                                    &octx->ksenc.ks, &octx->ksdec.ks,
+                                    (block128_f) AES_encrypt,
+                                    (block128_f) AES_decrypt,
+                                    NULL))
+                return 0;
+        }
+        while (0);
+
+        /*
+         * If we have an iv we can set it directly, otherwise use saved IV.
+         */
+        if (iv == NULL && octx->iv_set)
+            iv = octx->iv;
+        if (iv) {
+            if (CRYPTO_ocb128_setiv(&octx->ocb, iv, octx->ivlen, octx->taglen)
+                != 1)
+                return 0;
+            octx->iv_set = 1;
+        }
+        octx->key_set = 1;
+    } else {
+        /* If key set use IV, otherwise copy */
+        if (octx->key_set)
+            CRYPTO_ocb128_setiv(&octx->ocb, iv, octx->ivlen, octx->taglen);
+        else
+            memcpy(octx->iv, iv, octx->ivlen);
+        octx->iv_set = 1;
+    }
+    return 1;
+}
+
+static int aes_ocb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                          const unsigned char *in, size_t len)
+{
+    unsigned char *buf;
+    int *buf_len;
+    int written_len = 0;
+    size_t trailing_len;
+    EVP_AES_OCB_CTX *octx = EVP_C_DATA(EVP_AES_OCB_CTX,ctx);
+
+    /* If IV or Key not set then return error */
+    if (!octx->iv_set)
+        return -1;
+
+    if (!octx->key_set)
+        return -1;
+
+    if (in != NULL) {
+        /*
+         * Need to ensure we are only passing full blocks to low level OCB
+         * routines. We do it here rather than in EVP_EncryptUpdate/
+         * EVP_DecryptUpdate because we need to pass full blocks of AAD too
+         * and those routines don't support that
+         */
+
+        /* Are we dealing with AAD or normal data here? */
+        if (out == NULL) {
+            buf = octx->aad_buf;
+            buf_len = &(octx->aad_buf_len);
+        } else {
+            buf = octx->data_buf;
+            buf_len = &(octx->data_buf_len);
+
+            if (is_partially_overlapping(out + *buf_len, in, len)) {
+                EVPerr(EVP_F_AES_OCB_CIPHER, EVP_R_PARTIALLY_OVERLAPPING);
+                return 0;
+            }
+        }
+
+        /*
+         * If we've got a partially filled buffer from a previous call then
+         * use that data first
+         */
+        if (*buf_len > 0) {
+            unsigned int remaining;
+
+            remaining = AES_BLOCK_SIZE - (*buf_len);
+            if (remaining > len) {
+                memcpy(buf + (*buf_len), in, len);
+                *(buf_len) += len;
+                return 0;
+            }
+            memcpy(buf + (*buf_len), in, remaining);
+
+            /*
+             * If we get here we've filled the buffer, so process it
+             */
+            len -= remaining;
+            in += remaining;
+            if (out == NULL) {
+                if (!CRYPTO_ocb128_aad(&octx->ocb, buf, AES_BLOCK_SIZE))
+                    return -1;
+            } else if (EVP_CIPHER_CTX_encrypting(ctx)) {
+                if (!CRYPTO_ocb128_encrypt(&octx->ocb, buf, out,
+                                           AES_BLOCK_SIZE))
+                    return -1;
+            } else {
+                if (!CRYPTO_ocb128_decrypt(&octx->ocb, buf, out,
+                                           AES_BLOCK_SIZE))
+                    return -1;
+            }
+            written_len = AES_BLOCK_SIZE;
+            *buf_len = 0;
+            if (out != NULL)
+                out += AES_BLOCK_SIZE;
+        }
+
+        /* Do we have a partial block to handle at the end? */
+        trailing_len = len % AES_BLOCK_SIZE;
+
+        /*
+         * If we've got some full blocks to handle, then process these first
+         */
+        if (len != trailing_len) {
+            if (out == NULL) {
+                if (!CRYPTO_ocb128_aad(&octx->ocb, in, len - trailing_len))
+                    return -1;
+            } else if (EVP_CIPHER_CTX_encrypting(ctx)) {
+                if (!CRYPTO_ocb128_encrypt
+                    (&octx->ocb, in, out, len - trailing_len))
+                    return -1;
+            } else {
+                if (!CRYPTO_ocb128_decrypt
+                    (&octx->ocb, in, out, len - trailing_len))
+                    return -1;
+            }
+            written_len += len - trailing_len;
+            in += len - trailing_len;
+        }
+
+        /* Handle any trailing partial block */
+        if (trailing_len > 0) {
+            memcpy(buf, in, trailing_len);
+            *buf_len = trailing_len;
+        }
+
+        return written_len;
+    } else {
+        /*
+         * First of all empty the buffer of any partial block that we might
+         * have been provided - both for data and AAD
+         */
+        if (octx->data_buf_len > 0) {
+            if (EVP_CIPHER_CTX_encrypting(ctx)) {
+                if (!CRYPTO_ocb128_encrypt(&octx->ocb, octx->data_buf, out,
+                                           octx->data_buf_len))
+                    return -1;
+            } else {
+                if (!CRYPTO_ocb128_decrypt(&octx->ocb, octx->data_buf, out,
+                                           octx->data_buf_len))
+                    return -1;
+            }
+            written_len = octx->data_buf_len;
+            octx->data_buf_len = 0;
+        }
+        if (octx->aad_buf_len > 0) {
+            if (!CRYPTO_ocb128_aad
+                (&octx->ocb, octx->aad_buf, octx->aad_buf_len))
+                return -1;
+            octx->aad_buf_len = 0;
+        }
+        /* If decrypting then verify */
+        if (!EVP_CIPHER_CTX_encrypting(ctx)) {
+            if (octx->taglen < 0)
+                return -1;
+            if (CRYPTO_ocb128_finish(&octx->ocb,
+                                     octx->tag, octx->taglen) != 0)
+                return -1;
+            octx->iv_set = 0;
+            return written_len;
+        }
+        /* If encrypting then just get the tag */
+        if (CRYPTO_ocb128_tag(&octx->ocb, octx->tag, 16) != 1)
+            return -1;
+        /* Don't reuse the IV */
+        octx->iv_set = 0;
+        return written_len;
+    }
+}
+
+static int aes_ocb_cleanup(EVP_CIPHER_CTX *c)
+{
+    EVP_AES_OCB_CTX *octx = EVP_C_DATA(EVP_AES_OCB_CTX,c);
+    CRYPTO_ocb128_cleanup(&octx->ocb);
+    return 1;
+}
+
+BLOCK_CIPHER_custom(NID_aes, 128, 16, 12, ocb, OCB,
+                    EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
+BLOCK_CIPHER_custom(NID_aes, 192, 16, 12, ocb, OCB,
+                    EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
+BLOCK_CIPHER_custom(NID_aes, 256, 16, 12, ocb, OCB,
+                    EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS)
+#endif                         /* OPENSSL_NO_OCB */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_aes_cbc_hmac_sha1.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_aes_cbc_hmac_sha1.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_aes_cbc_hmac_sha1.c	(revision 331)
@@ -0,0 +1,957 @@
+/*
+ * Copyright 2011-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 <openssl/opensslconf.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/aes.h>
+#include <openssl/sha.h>
+#include <openssl/rand.h>
+#include "../modes/modes_lcl.h"
+#include "internal/evp_int.h"
+#include "internal/constant_time_locl.h"
+
+typedef struct {
+    AES_KEY ks;
+    SHA_CTX head, tail, md;
+    size_t payload_length;      /* AAD length in decrypt case */
+    union {
+        unsigned int tls_ver;
+        unsigned char tls_aad[16]; /* 13 used */
+    } aux;
+} EVP_AES_HMAC_SHA1;
+
+#define NO_PAYLOAD_LENGTH       ((size_t)-1)
+
+#if     defined(AES_ASM) &&     ( \
+        defined(__x86_64)       || defined(__x86_64__)  || \
+        defined(_M_AMD64)       || defined(_M_X64)      )
+
+extern unsigned int OPENSSL_ia32cap_P[];
+# define AESNI_CAPABLE   (1<<(57-32))
+
+int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
+                          AES_KEY *key);
+int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
+                          AES_KEY *key);
+
+void aesni_cbc_encrypt(const unsigned char *in,
+                       unsigned char *out,
+                       size_t length,
+                       const AES_KEY *key, unsigned char *ivec, int enc);
+
+void aesni_cbc_sha1_enc(const void *inp, void *out, size_t blocks,
+                        const AES_KEY *key, unsigned char iv[16],
+                        SHA_CTX *ctx, const void *in0);
+
+void aesni256_cbc_sha1_dec(const void *inp, void *out, size_t blocks,
+                           const AES_KEY *key, unsigned char iv[16],
+                           SHA_CTX *ctx, const void *in0);
+
+# define data(ctx) ((EVP_AES_HMAC_SHA1 *)EVP_CIPHER_CTX_get_cipher_data(ctx))
+
+static int aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx,
+                                        const unsigned char *inkey,
+                                        const unsigned char *iv, int enc)
+{
+    EVP_AES_HMAC_SHA1 *key = data(ctx);
+    int ret;
+
+    if (enc)
+        ret = aesni_set_encrypt_key(inkey,
+                                    EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                    &key->ks);
+    else
+        ret = aesni_set_decrypt_key(inkey,
+                                    EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                    &key->ks);
+
+    SHA1_Init(&key->head);      /* handy when benchmarking */
+    key->tail = key->head;
+    key->md = key->head;
+
+    key->payload_length = NO_PAYLOAD_LENGTH;
+
+    return ret < 0 ? 0 : 1;
+}
+
+# define STITCHED_CALL
+# undef  STITCHED_DECRYPT_CALL
+
+# if !defined(STITCHED_CALL)
+#  define aes_off 0
+# endif
+
+void sha1_block_data_order(void *c, const void *p, size_t len);
+
+static void sha1_update(SHA_CTX *c, const void *data, size_t len)
+{
+    const unsigned char *ptr = data;
+    size_t res;
+
+    if ((res = c->num)) {
+        res = SHA_CBLOCK - res;
+        if (len < res)
+            res = len;
+        SHA1_Update(c, ptr, res);
+        ptr += res;
+        len -= res;
+    }
+
+    res = len % SHA_CBLOCK;
+    len -= res;
+
+    if (len) {
+        sha1_block_data_order(c, ptr, len / SHA_CBLOCK);
+
+        ptr += len;
+        c->Nh += len >> 29;
+        c->Nl += len <<= 3;
+        if (c->Nl < (unsigned int)len)
+            c->Nh++;
+    }
+
+    if (res)
+        SHA1_Update(c, ptr, res);
+}
+
+# ifdef SHA1_Update
+#  undef SHA1_Update
+# endif
+# define SHA1_Update sha1_update
+
+# if !defined(OPENSSL_NO_MULTIBLOCK)
+
+typedef struct {
+    unsigned int A[8], B[8], C[8], D[8], E[8];
+} SHA1_MB_CTX;
+typedef struct {
+    const unsigned char *ptr;
+    int blocks;
+} HASH_DESC;
+
+void sha1_multi_block(SHA1_MB_CTX *, const HASH_DESC *, int);
+
+typedef struct {
+    const unsigned char *inp;
+    unsigned char *out;
+    int blocks;
+    u64 iv[2];
+} CIPH_DESC;
+
+void aesni_multi_cbc_encrypt(CIPH_DESC *, void *, int);
+
+static size_t tls1_1_multi_block_encrypt(EVP_AES_HMAC_SHA1 *key,
+                                         unsigned char *out,
+                                         const unsigned char *inp,
+                                         size_t inp_len, int n4x)
+{                               /* n4x is 1 or 2 */
+    HASH_DESC hash_d[8], edges[8];
+    CIPH_DESC ciph_d[8];
+    unsigned char storage[sizeof(SHA1_MB_CTX) + 32];
+    union {
+        u64 q[16];
+        u32 d[32];
+        u8 c[128];
+    } blocks[8];
+    SHA1_MB_CTX *ctx;
+    unsigned int frag, last, packlen, i, x4 = 4 * n4x, minblocks, processed =
+        0;
+    size_t ret = 0;
+    u8 *IVs;
+#  if defined(BSWAP8)
+    u64 seqnum;
+#  endif
+
+    /* ask for IVs in bulk */
+    if (RAND_bytes((IVs = blocks[0].c), 16 * x4) <= 0)
+        return 0;
+
+    ctx = (SHA1_MB_CTX *) (storage + 32 - ((size_t)storage % 32)); /* align */
+
+    frag = (unsigned int)inp_len >> (1 + n4x);
+    last = (unsigned int)inp_len + frag - (frag << (1 + n4x));
+    if (last > frag && ((last + 13 + 9) % 64) < (x4 - 1)) {
+        frag++;
+        last -= x4 - 1;
+    }
+
+    packlen = 5 + 16 + ((frag + 20 + 16) & -16);
+
+    /* populate descriptors with pointers and IVs */
+    hash_d[0].ptr = inp;
+    ciph_d[0].inp = inp;
+    /* 5+16 is place for header and explicit IV */
+    ciph_d[0].out = out + 5 + 16;
+    memcpy(ciph_d[0].out - 16, IVs, 16);
+    memcpy(ciph_d[0].iv, IVs, 16);
+    IVs += 16;
+
+    for (i = 1; i < x4; i++) {
+        ciph_d[i].inp = hash_d[i].ptr = hash_d[i - 1].ptr + frag;
+        ciph_d[i].out = ciph_d[i - 1].out + packlen;
+        memcpy(ciph_d[i].out - 16, IVs, 16);
+        memcpy(ciph_d[i].iv, IVs, 16);
+        IVs += 16;
+    }
+
+#  if defined(BSWAP8)
+    memcpy(blocks[0].c, key->md.data, 8);
+    seqnum = BSWAP8(blocks[0].q[0]);
+#  endif
+    for (i = 0; i < x4; i++) {
+        unsigned int len = (i == (x4 - 1) ? last : frag);
+#  if !defined(BSWAP8)
+        unsigned int carry, j;
+#  endif
+
+        ctx->A[i] = key->md.h0;
+        ctx->B[i] = key->md.h1;
+        ctx->C[i] = key->md.h2;
+        ctx->D[i] = key->md.h3;
+        ctx->E[i] = key->md.h4;
+
+        /* fix seqnum */
+#  if defined(BSWAP8)
+        blocks[i].q[0] = BSWAP8(seqnum + i);
+#  else
+        for (carry = i, j = 8; j--;) {
+            blocks[i].c[j] = ((u8 *)key->md.data)[j] + carry;
+            carry = (blocks[i].c[j] - carry) >> (sizeof(carry) * 8 - 1);
+        }
+#  endif
+        blocks[i].c[8] = ((u8 *)key->md.data)[8];
+        blocks[i].c[9] = ((u8 *)key->md.data)[9];
+        blocks[i].c[10] = ((u8 *)key->md.data)[10];
+        /* fix length */
+        blocks[i].c[11] = (u8)(len >> 8);
+        blocks[i].c[12] = (u8)(len);
+
+        memcpy(blocks[i].c + 13, hash_d[i].ptr, 64 - 13);
+        hash_d[i].ptr += 64 - 13;
+        hash_d[i].blocks = (len - (64 - 13)) / 64;
+
+        edges[i].ptr = blocks[i].c;
+        edges[i].blocks = 1;
+    }
+
+    /* hash 13-byte headers and first 64-13 bytes of inputs */
+    sha1_multi_block(ctx, edges, n4x);
+    /* hash bulk inputs */
+#  define MAXCHUNKSIZE    2048
+#  if     MAXCHUNKSIZE%64
+#   error  "MAXCHUNKSIZE is not divisible by 64"
+#  elif   MAXCHUNKSIZE
+    /*
+     * goal is to minimize pressure on L1 cache by moving in shorter steps,
+     * so that hashed data is still in the cache by the time we encrypt it
+     */
+    minblocks = ((frag <= last ? frag : last) - (64 - 13)) / 64;
+    if (minblocks > MAXCHUNKSIZE / 64) {
+        for (i = 0; i < x4; i++) {
+            edges[i].ptr = hash_d[i].ptr;
+            edges[i].blocks = MAXCHUNKSIZE / 64;
+            ciph_d[i].blocks = MAXCHUNKSIZE / 16;
+        }
+        do {
+            sha1_multi_block(ctx, edges, n4x);
+            aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x);
+
+            for (i = 0; i < x4; i++) {
+                edges[i].ptr = hash_d[i].ptr += MAXCHUNKSIZE;
+                hash_d[i].blocks -= MAXCHUNKSIZE / 64;
+                edges[i].blocks = MAXCHUNKSIZE / 64;
+                ciph_d[i].inp += MAXCHUNKSIZE;
+                ciph_d[i].out += MAXCHUNKSIZE;
+                ciph_d[i].blocks = MAXCHUNKSIZE / 16;
+                memcpy(ciph_d[i].iv, ciph_d[i].out - 16, 16);
+            }
+            processed += MAXCHUNKSIZE;
+            minblocks -= MAXCHUNKSIZE / 64;
+        } while (minblocks > MAXCHUNKSIZE / 64);
+    }
+#  endif
+#  undef  MAXCHUNKSIZE
+    sha1_multi_block(ctx, hash_d, n4x);
+
+    memset(blocks, 0, sizeof(blocks));
+    for (i = 0; i < x4; i++) {
+        unsigned int len = (i == (x4 - 1) ? last : frag),
+            off = hash_d[i].blocks * 64;
+        const unsigned char *ptr = hash_d[i].ptr + off;
+
+        off = (len - processed) - (64 - 13) - off; /* remainder actually */
+        memcpy(blocks[i].c, ptr, off);
+        blocks[i].c[off] = 0x80;
+        len += 64 + 13;         /* 64 is HMAC header */
+        len *= 8;               /* convert to bits */
+        if (off < (64 - 8)) {
+#  ifdef BSWAP4
+            blocks[i].d[15] = BSWAP4(len);
+#  else
+            PUTU32(blocks[i].c + 60, len);
+#  endif
+            edges[i].blocks = 1;
+        } else {
+#  ifdef BSWAP4
+            blocks[i].d[31] = BSWAP4(len);
+#  else
+            PUTU32(blocks[i].c + 124, len);
+#  endif
+            edges[i].blocks = 2;
+        }
+        edges[i].ptr = blocks[i].c;
+    }
+
+    /* hash input tails and finalize */
+    sha1_multi_block(ctx, edges, n4x);
+
+    memset(blocks, 0, sizeof(blocks));
+    for (i = 0; i < x4; i++) {
+#  ifdef BSWAP4
+        blocks[i].d[0] = BSWAP4(ctx->A[i]);
+        ctx->A[i] = key->tail.h0;
+        blocks[i].d[1] = BSWAP4(ctx->B[i]);
+        ctx->B[i] = key->tail.h1;
+        blocks[i].d[2] = BSWAP4(ctx->C[i]);
+        ctx->C[i] = key->tail.h2;
+        blocks[i].d[3] = BSWAP4(ctx->D[i]);
+        ctx->D[i] = key->tail.h3;
+        blocks[i].d[4] = BSWAP4(ctx->E[i]);
+        ctx->E[i] = key->tail.h4;
+        blocks[i].c[20] = 0x80;
+        blocks[i].d[15] = BSWAP4((64 + 20) * 8);
+#  else
+        PUTU32(blocks[i].c + 0, ctx->A[i]);
+        ctx->A[i] = key->tail.h0;
+        PUTU32(blocks[i].c + 4, ctx->B[i]);
+        ctx->B[i] = key->tail.h1;
+        PUTU32(blocks[i].c + 8, ctx->C[i]);
+        ctx->C[i] = key->tail.h2;
+        PUTU32(blocks[i].c + 12, ctx->D[i]);
+        ctx->D[i] = key->tail.h3;
+        PUTU32(blocks[i].c + 16, ctx->E[i]);
+        ctx->E[i] = key->tail.h4;
+        blocks[i].c[20] = 0x80;
+        PUTU32(blocks[i].c + 60, (64 + 20) * 8);
+#  endif
+        edges[i].ptr = blocks[i].c;
+        edges[i].blocks = 1;
+    }
+
+    /* finalize MACs */
+    sha1_multi_block(ctx, edges, n4x);
+
+    for (i = 0; i < x4; i++) {
+        unsigned int len = (i == (x4 - 1) ? last : frag), pad, j;
+        unsigned char *out0 = out;
+
+        memcpy(ciph_d[i].out, ciph_d[i].inp, len - processed);
+        ciph_d[i].inp = ciph_d[i].out;
+
+        out += 5 + 16 + len;
+
+        /* write MAC */
+        PUTU32(out + 0, ctx->A[i]);
+        PUTU32(out + 4, ctx->B[i]);
+        PUTU32(out + 8, ctx->C[i]);
+        PUTU32(out + 12, ctx->D[i]);
+        PUTU32(out + 16, ctx->E[i]);
+        out += 20;
+        len += 20;
+
+        /* pad */
+        pad = 15 - len % 16;
+        for (j = 0; j <= pad; j++)
+            *(out++) = pad;
+        len += pad + 1;
+
+        ciph_d[i].blocks = (len - processed) / 16;
+        len += 16;              /* account for explicit iv */
+
+        /* arrange header */
+        out0[0] = ((u8 *)key->md.data)[8];
+        out0[1] = ((u8 *)key->md.data)[9];
+        out0[2] = ((u8 *)key->md.data)[10];
+        out0[3] = (u8)(len >> 8);
+        out0[4] = (u8)(len);
+
+        ret += len + 5;
+        inp += frag;
+    }
+
+    aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x);
+
+    OPENSSL_cleanse(blocks, sizeof(blocks));
+    OPENSSL_cleanse(ctx, sizeof(*ctx));
+
+    return ret;
+}
+# endif
+
+static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                                      const unsigned char *in, size_t len)
+{
+    EVP_AES_HMAC_SHA1 *key = data(ctx);
+    unsigned int l;
+    size_t plen = key->payload_length, iv = 0, /* explicit IV in TLS 1.1 and
+                                                * later */
+        sha_off = 0;
+# if defined(STITCHED_CALL)
+    size_t aes_off = 0, blocks;
+
+    sha_off = SHA_CBLOCK - key->md.num;
+# endif
+
+    key->payload_length = NO_PAYLOAD_LENGTH;
+
+    if (len % AES_BLOCK_SIZE)
+        return 0;
+
+    if (EVP_CIPHER_CTX_encrypting(ctx)) {
+        if (plen == NO_PAYLOAD_LENGTH)
+            plen = len;
+        else if (len !=
+                 ((plen + SHA_DIGEST_LENGTH +
+                   AES_BLOCK_SIZE) & -AES_BLOCK_SIZE))
+            return 0;
+        else if (key->aux.tls_ver >= TLS1_1_VERSION)
+            iv = AES_BLOCK_SIZE;
+
+# if defined(STITCHED_CALL)
+        if (plen > (sha_off + iv)
+            && (blocks = (plen - (sha_off + iv)) / SHA_CBLOCK)) {
+            SHA1_Update(&key->md, in + iv, sha_off);
+
+            aesni_cbc_sha1_enc(in, out, blocks, &key->ks,
+                               EVP_CIPHER_CTX_iv_noconst(ctx),
+                               &key->md, in + iv + sha_off);
+            blocks *= SHA_CBLOCK;
+            aes_off += blocks;
+            sha_off += blocks;
+            key->md.Nh += blocks >> 29;
+            key->md.Nl += blocks <<= 3;
+            if (key->md.Nl < (unsigned int)blocks)
+                key->md.Nh++;
+        } else {
+            sha_off = 0;
+        }
+# endif
+        sha_off += iv;
+        SHA1_Update(&key->md, in + sha_off, plen - sha_off);
+
+        if (plen != len) {      /* "TLS" mode of operation */
+            if (in != out)
+                memcpy(out + aes_off, in + aes_off, plen - aes_off);
+
+            /* calculate HMAC and append it to payload */
+            SHA1_Final(out + plen, &key->md);
+            key->md = key->tail;
+            SHA1_Update(&key->md, out + plen, SHA_DIGEST_LENGTH);
+            SHA1_Final(out + plen, &key->md);
+
+            /* pad the payload|hmac */
+            plen += SHA_DIGEST_LENGTH;
+            for (l = len - plen - 1; plen < len; plen++)
+                out[plen] = l;
+            /* encrypt HMAC|padding at once */
+            aesni_cbc_encrypt(out + aes_off, out + aes_off, len - aes_off,
+                              &key->ks, EVP_CIPHER_CTX_iv_noconst(ctx), 1);
+        } else {
+            aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off,
+                              &key->ks, EVP_CIPHER_CTX_iv_noconst(ctx), 1);
+        }
+    } else {
+        union {
+            unsigned int u[SHA_DIGEST_LENGTH / sizeof(unsigned int)];
+            unsigned char c[32 + SHA_DIGEST_LENGTH];
+        } mac, *pmac;
+
+        /* arrange cache line alignment */
+        pmac = (void *)(((size_t)mac.c + 31) & ((size_t)0 - 32));
+
+        if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */
+            size_t inp_len, mask, j, i;
+            unsigned int res, maxpad, pad, bitlen;
+            int ret = 1;
+            union {
+                unsigned int u[SHA_LBLOCK];
+                unsigned char c[SHA_CBLOCK];
+            } *data = (void *)key->md.data;
+# if defined(STITCHED_DECRYPT_CALL)
+            unsigned char tail_iv[AES_BLOCK_SIZE];
+            int stitch = 0;
+# endif
+
+            if ((key->aux.tls_aad[plen - 4] << 8 | key->aux.tls_aad[plen - 3])
+                >= TLS1_1_VERSION) {
+                if (len < (AES_BLOCK_SIZE + SHA_DIGEST_LENGTH + 1))
+                    return 0;
+
+                /* omit explicit iv */
+                memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), in, AES_BLOCK_SIZE);
+
+                in += AES_BLOCK_SIZE;
+                out += AES_BLOCK_SIZE;
+                len -= AES_BLOCK_SIZE;
+            } else if (len < (SHA_DIGEST_LENGTH + 1))
+                return 0;
+
+# if defined(STITCHED_DECRYPT_CALL)
+            if (len >= 1024 && ctx->key_len == 32) {
+                /* decrypt last block */
+                memcpy(tail_iv, in + len - 2 * AES_BLOCK_SIZE,
+                       AES_BLOCK_SIZE);
+                aesni_cbc_encrypt(in + len - AES_BLOCK_SIZE,
+                                  out + len - AES_BLOCK_SIZE, AES_BLOCK_SIZE,
+                                  &key->ks, tail_iv, 0);
+                stitch = 1;
+            } else
+# endif
+                /* decrypt HMAC|padding at once */
+                aesni_cbc_encrypt(in, out, len, &key->ks,
+                                  EVP_CIPHER_CTX_iv_noconst(ctx), 0);
+
+            /* figure out payload length */
+            pad = out[len - 1];
+            maxpad = len - (SHA_DIGEST_LENGTH + 1);
+            maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8);
+            maxpad &= 255;
+
+            ret &= constant_time_ge(maxpad, pad);
+
+            inp_len = len - (SHA_DIGEST_LENGTH + pad + 1);
+            mask = (0 - ((inp_len - len) >> (sizeof(inp_len) * 8 - 1)));
+            inp_len &= mask;
+            ret &= (int)mask;
+
+            key->aux.tls_aad[plen - 2] = inp_len >> 8;
+            key->aux.tls_aad[plen - 1] = inp_len;
+
+            /* calculate HMAC */
+            key->md = key->head;
+            SHA1_Update(&key->md, key->aux.tls_aad, plen);
+
+# if defined(STITCHED_DECRYPT_CALL)
+            if (stitch) {
+                blocks = (len - (256 + 32 + SHA_CBLOCK)) / SHA_CBLOCK;
+                aes_off = len - AES_BLOCK_SIZE - blocks * SHA_CBLOCK;
+                sha_off = SHA_CBLOCK - plen;
+
+                aesni_cbc_encrypt(in, out, aes_off, &key->ks, ctx->iv, 0);
+
+                SHA1_Update(&key->md, out, sha_off);
+                aesni256_cbc_sha1_dec(in + aes_off,
+                                      out + aes_off, blocks, &key->ks,
+                                      ctx->iv, &key->md, out + sha_off);
+
+                sha_off += blocks *= SHA_CBLOCK;
+                out += sha_off;
+                len -= sha_off;
+                inp_len -= sha_off;
+
+                key->md.Nl += (blocks << 3); /* at most 18 bits */
+                memcpy(ctx->iv, tail_iv, AES_BLOCK_SIZE);
+            }
+# endif
+
+# if 1
+            len -= SHA_DIGEST_LENGTH; /* amend mac */
+            if (len >= (256 + SHA_CBLOCK)) {
+                j = (len - (256 + SHA_CBLOCK)) & (0 - SHA_CBLOCK);
+                j += SHA_CBLOCK - key->md.num;
+                SHA1_Update(&key->md, out, j);
+                out += j;
+                len -= j;
+                inp_len -= j;
+            }
+
+            /* but pretend as if we hashed padded payload */
+            bitlen = key->md.Nl + (inp_len << 3); /* at most 18 bits */
+#  ifdef BSWAP4
+            bitlen = BSWAP4(bitlen);
+#  else
+            mac.c[0] = 0;
+            mac.c[1] = (unsigned char)(bitlen >> 16);
+            mac.c[2] = (unsigned char)(bitlen >> 8);
+            mac.c[3] = (unsigned char)bitlen;
+            bitlen = mac.u[0];
+#  endif
+
+            pmac->u[0] = 0;
+            pmac->u[1] = 0;
+            pmac->u[2] = 0;
+            pmac->u[3] = 0;
+            pmac->u[4] = 0;
+
+            for (res = key->md.num, j = 0; j < len; j++) {
+                size_t c = out[j];
+                mask = (j - inp_len) >> (sizeof(j) * 8 - 8);
+                c &= mask;
+                c |= 0x80 & ~mask & ~((inp_len - j) >> (sizeof(j) * 8 - 8));
+                data->c[res++] = (unsigned char)c;
+
+                if (res != SHA_CBLOCK)
+                    continue;
+
+                /* j is not incremented yet */
+                mask = 0 - ((inp_len + 7 - j) >> (sizeof(j) * 8 - 1));
+                data->u[SHA_LBLOCK - 1] |= bitlen & mask;
+                sha1_block_data_order(&key->md, data, 1);
+                mask &= 0 - ((j - inp_len - 72) >> (sizeof(j) * 8 - 1));
+                pmac->u[0] |= key->md.h0 & mask;
+                pmac->u[1] |= key->md.h1 & mask;
+                pmac->u[2] |= key->md.h2 & mask;
+                pmac->u[3] |= key->md.h3 & mask;
+                pmac->u[4] |= key->md.h4 & mask;
+                res = 0;
+            }
+
+            for (i = res; i < SHA_CBLOCK; i++, j++)
+                data->c[i] = 0;
+
+            if (res > SHA_CBLOCK - 8) {
+                mask = 0 - ((inp_len + 8 - j) >> (sizeof(j) * 8 - 1));
+                data->u[SHA_LBLOCK - 1] |= bitlen & mask;
+                sha1_block_data_order(&key->md, data, 1);
+                mask &= 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1));
+                pmac->u[0] |= key->md.h0 & mask;
+                pmac->u[1] |= key->md.h1 & mask;
+                pmac->u[2] |= key->md.h2 & mask;
+                pmac->u[3] |= key->md.h3 & mask;
+                pmac->u[4] |= key->md.h4 & mask;
+
+                memset(data, 0, SHA_CBLOCK);
+                j += 64;
+            }
+            data->u[SHA_LBLOCK - 1] = bitlen;
+            sha1_block_data_order(&key->md, data, 1);
+            mask = 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1));
+            pmac->u[0] |= key->md.h0 & mask;
+            pmac->u[1] |= key->md.h1 & mask;
+            pmac->u[2] |= key->md.h2 & mask;
+            pmac->u[3] |= key->md.h3 & mask;
+            pmac->u[4] |= key->md.h4 & mask;
+
+#  ifdef BSWAP4
+            pmac->u[0] = BSWAP4(pmac->u[0]);
+            pmac->u[1] = BSWAP4(pmac->u[1]);
+            pmac->u[2] = BSWAP4(pmac->u[2]);
+            pmac->u[3] = BSWAP4(pmac->u[3]);
+            pmac->u[4] = BSWAP4(pmac->u[4]);
+#  else
+            for (i = 0; i < 5; i++) {
+                res = pmac->u[i];
+                pmac->c[4 * i + 0] = (unsigned char)(res >> 24);
+                pmac->c[4 * i + 1] = (unsigned char)(res >> 16);
+                pmac->c[4 * i + 2] = (unsigned char)(res >> 8);
+                pmac->c[4 * i + 3] = (unsigned char)res;
+            }
+#  endif
+            len += SHA_DIGEST_LENGTH;
+# else
+            SHA1_Update(&key->md, out, inp_len);
+            res = key->md.num;
+            SHA1_Final(pmac->c, &key->md);
+
+            {
+                unsigned int inp_blocks, pad_blocks;
+
+                /* but pretend as if we hashed padded payload */
+                inp_blocks =
+                    1 + ((SHA_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1));
+                res += (unsigned int)(len - inp_len);
+                pad_blocks = res / SHA_CBLOCK;
+                res %= SHA_CBLOCK;
+                pad_blocks +=
+                    1 + ((SHA_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1));
+                for (; inp_blocks < pad_blocks; inp_blocks++)
+                    sha1_block_data_order(&key->md, data, 1);
+            }
+# endif
+            key->md = key->tail;
+            SHA1_Update(&key->md, pmac->c, SHA_DIGEST_LENGTH);
+            SHA1_Final(pmac->c, &key->md);
+
+            /* verify HMAC */
+            out += inp_len;
+            len -= inp_len;
+# if 1
+            {
+                unsigned char *p = out + len - 1 - maxpad - SHA_DIGEST_LENGTH;
+                size_t off = out - p;
+                unsigned int c, cmask;
+
+                maxpad += SHA_DIGEST_LENGTH;
+                for (res = 0, i = 0, j = 0; j < maxpad; j++) {
+                    c = p[j];
+                    cmask =
+                        ((int)(j - off - SHA_DIGEST_LENGTH)) >> (sizeof(int) *
+                                                                 8 - 1);
+                    res |= (c ^ pad) & ~cmask; /* ... and padding */
+                    cmask &= ((int)(off - 1 - j)) >> (sizeof(int) * 8 - 1);
+                    res |= (c ^ pmac->c[i]) & cmask;
+                    i += 1 & cmask;
+                }
+                maxpad -= SHA_DIGEST_LENGTH;
+
+                res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
+                ret &= (int)~res;
+            }
+# else
+            for (res = 0, i = 0; i < SHA_DIGEST_LENGTH; i++)
+                res |= out[i] ^ pmac->c[i];
+            res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
+            ret &= (int)~res;
+
+            /* verify padding */
+            pad = (pad & ~res) | (maxpad & res);
+            out = out + len - 1 - pad;
+            for (res = 0, i = 0; i < pad; i++)
+                res |= out[i] ^ pad;
+
+            res = (0 - res) >> (sizeof(res) * 8 - 1);
+            ret &= (int)~res;
+# endif
+            return ret;
+        } else {
+# if defined(STITCHED_DECRYPT_CALL)
+            if (len >= 1024 && ctx->key_len == 32) {
+                if (sha_off %= SHA_CBLOCK)
+                    blocks = (len - 3 * SHA_CBLOCK) / SHA_CBLOCK;
+                else
+                    blocks = (len - 2 * SHA_CBLOCK) / SHA_CBLOCK;
+                aes_off = len - blocks * SHA_CBLOCK;
+
+                aesni_cbc_encrypt(in, out, aes_off, &key->ks, ctx->iv, 0);
+                SHA1_Update(&key->md, out, sha_off);
+                aesni256_cbc_sha1_dec(in + aes_off,
+                                      out + aes_off, blocks, &key->ks,
+                                      ctx->iv, &key->md, out + sha_off);
+
+                sha_off += blocks *= SHA_CBLOCK;
+                out += sha_off;
+                len -= sha_off;
+
+                key->md.Nh += blocks >> 29;
+                key->md.Nl += blocks <<= 3;
+                if (key->md.Nl < (unsigned int)blocks)
+                    key->md.Nh++;
+            } else
+# endif
+                /* decrypt HMAC|padding at once */
+                aesni_cbc_encrypt(in, out, len, &key->ks,
+                                  EVP_CIPHER_CTX_iv_noconst(ctx), 0);
+
+            SHA1_Update(&key->md, out, len);
+        }
+    }
+
+    return 1;
+}
+
+static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
+                                    void *ptr)
+{
+    EVP_AES_HMAC_SHA1 *key = data(ctx);
+
+    switch (type) {
+    case EVP_CTRL_AEAD_SET_MAC_KEY:
+        {
+            unsigned int i;
+            unsigned char hmac_key[64];
+
+            memset(hmac_key, 0, sizeof(hmac_key));
+
+            if (arg > (int)sizeof(hmac_key)) {
+                SHA1_Init(&key->head);
+                SHA1_Update(&key->head, ptr, arg);
+                SHA1_Final(hmac_key, &key->head);
+            } else {
+                memcpy(hmac_key, ptr, arg);
+            }
+
+            for (i = 0; i < sizeof(hmac_key); i++)
+                hmac_key[i] ^= 0x36; /* ipad */
+            SHA1_Init(&key->head);
+            SHA1_Update(&key->head, hmac_key, sizeof(hmac_key));
+
+            for (i = 0; i < sizeof(hmac_key); i++)
+                hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */
+            SHA1_Init(&key->tail);
+            SHA1_Update(&key->tail, hmac_key, sizeof(hmac_key));
+
+            OPENSSL_cleanse(hmac_key, sizeof(hmac_key));
+
+            return 1;
+        }
+    case EVP_CTRL_AEAD_TLS1_AAD:
+        {
+            unsigned char *p = ptr;
+            unsigned int len;
+
+            if (arg != EVP_AEAD_TLS1_AAD_LEN)
+                return -1;
+
+            len = p[arg - 2] << 8 | p[arg - 1];
+
+            if (EVP_CIPHER_CTX_encrypting(ctx)) {
+                key->payload_length = len;
+                if ((key->aux.tls_ver =
+                     p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) {
+                    len -= AES_BLOCK_SIZE;
+                    p[arg - 2] = len >> 8;
+                    p[arg - 1] = len;
+                }
+                key->md = key->head;
+                SHA1_Update(&key->md, p, arg);
+
+                return (int)(((len + SHA_DIGEST_LENGTH +
+                               AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)
+                             - len);
+            } else {
+                memcpy(key->aux.tls_aad, ptr, arg);
+                key->payload_length = arg;
+
+                return SHA_DIGEST_LENGTH;
+            }
+        }
+# if !defined(OPENSSL_NO_MULTIBLOCK)
+    case EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE:
+        return (int)(5 + 16 + ((arg + 20 + 16) & -16));
+    case EVP_CTRL_TLS1_1_MULTIBLOCK_AAD:
+        {
+            EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param =
+                (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr;
+            unsigned int n4x = 1, x4;
+            unsigned int frag, last, packlen, inp_len;
+
+            if (arg < (int)sizeof(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM))
+                return -1;
+
+            inp_len = param->inp[11] << 8 | param->inp[12];
+
+            if (EVP_CIPHER_CTX_encrypting(ctx)) {
+                if ((param->inp[9] << 8 | param->inp[10]) < TLS1_1_VERSION)
+                    return -1;
+
+                if (inp_len) {
+                    if (inp_len < 4096)
+                        return 0; /* too short */
+
+                    if (inp_len >= 8192 && OPENSSL_ia32cap_P[2] & (1 << 5))
+                        n4x = 2; /* AVX2 */
+                } else if ((n4x = param->interleave / 4) && n4x <= 2)
+                    inp_len = param->len;
+                else
+                    return -1;
+
+                key->md = key->head;
+                SHA1_Update(&key->md, param->inp, 13);
+
+                x4 = 4 * n4x;
+                n4x += 1;
+
+                frag = inp_len >> n4x;
+                last = inp_len + frag - (frag << n4x);
+                if (last > frag && ((last + 13 + 9) % 64 < (x4 - 1))) {
+                    frag++;
+                    last -= x4 - 1;
+                }
+
+                packlen = 5 + 16 + ((frag + 20 + 16) & -16);
+                packlen = (packlen << n4x) - packlen;
+                packlen += 5 + 16 + ((last + 20 + 16) & -16);
+
+                param->interleave = x4;
+
+                return (int)packlen;
+            } else
+                return -1;      /* not yet */
+        }
+    case EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT:
+        {
+            EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param =
+                (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr;
+
+            return (int)tls1_1_multi_block_encrypt(key, param->out,
+                                                   param->inp, param->len,
+                                                   param->interleave / 4);
+        }
+    case EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT:
+# endif
+    default:
+        return -1;
+    }
+}
+
+static EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher = {
+# ifdef NID_aes_128_cbc_hmac_sha1
+    NID_aes_128_cbc_hmac_sha1,
+# else
+    NID_undef,
+# endif
+    AES_BLOCK_SIZE, 16, AES_BLOCK_SIZE,
+    EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
+        EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK,
+    aesni_cbc_hmac_sha1_init_key,
+    aesni_cbc_hmac_sha1_cipher,
+    NULL,
+    sizeof(EVP_AES_HMAC_SHA1),
+    EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv,
+    EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv,
+    aesni_cbc_hmac_sha1_ctrl,
+    NULL
+};
+
+static EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher = {
+# ifdef NID_aes_256_cbc_hmac_sha1
+    NID_aes_256_cbc_hmac_sha1,
+# else
+    NID_undef,
+# endif
+    AES_BLOCK_SIZE, 32, AES_BLOCK_SIZE,
+    EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
+        EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK,
+    aesni_cbc_hmac_sha1_init_key,
+    aesni_cbc_hmac_sha1_cipher,
+    NULL,
+    sizeof(EVP_AES_HMAC_SHA1),
+    EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv,
+    EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv,
+    aesni_cbc_hmac_sha1_ctrl,
+    NULL
+};
+
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
+{
+    return (OPENSSL_ia32cap_P[1] & AESNI_CAPABLE ?
+            &aesni_128_cbc_hmac_sha1_cipher : NULL);
+}
+
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
+{
+    return (OPENSSL_ia32cap_P[1] & AESNI_CAPABLE ?
+            &aesni_256_cbc_hmac_sha1_cipher : NULL);
+}
+#else
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void)
+{
+    return NULL;
+}
+
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void)
+{
+    return NULL;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_aes_cbc_hmac_sha256.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_aes_cbc_hmac_sha256.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_aes_cbc_hmac_sha256.c	(revision 331)
@@ -0,0 +1,939 @@
+/*
+ * Copyright 2013-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 <openssl/opensslconf.h>
+
+#include <stdio.h>
+#include <string.h>
+
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/aes.h>
+#include <openssl/sha.h>
+#include <openssl/rand.h>
+#include "../modes/modes_lcl.h"
+#include "internal/constant_time_locl.h"
+#include "internal/evp_int.h"
+
+typedef struct {
+    AES_KEY ks;
+    SHA256_CTX head, tail, md;
+    size_t payload_length;      /* AAD length in decrypt case */
+    union {
+        unsigned int tls_ver;
+        unsigned char tls_aad[16]; /* 13 used */
+    } aux;
+} EVP_AES_HMAC_SHA256;
+
+# define NO_PAYLOAD_LENGTH       ((size_t)-1)
+
+#if     defined(AES_ASM) &&     ( \
+        defined(__x86_64)       || defined(__x86_64__)  || \
+        defined(_M_AMD64)       || defined(_M_X64)      )
+
+extern unsigned int OPENSSL_ia32cap_P[];
+# define AESNI_CAPABLE   (1<<(57-32))
+
+int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
+                          AES_KEY *key);
+int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
+                          AES_KEY *key);
+
+void aesni_cbc_encrypt(const unsigned char *in,
+                       unsigned char *out,
+                       size_t length,
+                       const AES_KEY *key, unsigned char *ivec, int enc);
+
+int aesni_cbc_sha256_enc(const void *inp, void *out, size_t blocks,
+                         const AES_KEY *key, unsigned char iv[16],
+                         SHA256_CTX *ctx, const void *in0);
+
+# define data(ctx) ((EVP_AES_HMAC_SHA256 *)EVP_CIPHER_CTX_get_cipher_data(ctx))
+
+static int aesni_cbc_hmac_sha256_init_key(EVP_CIPHER_CTX *ctx,
+                                          const unsigned char *inkey,
+                                          const unsigned char *iv, int enc)
+{
+    EVP_AES_HMAC_SHA256 *key = data(ctx);
+    int ret;
+
+    if (enc)
+        ret = aesni_set_encrypt_key(inkey,
+                                    EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                    &key->ks);
+    else
+        ret = aesni_set_decrypt_key(inkey,
+                                    EVP_CIPHER_CTX_key_length(ctx) * 8,
+                                    &key->ks);
+
+    SHA256_Init(&key->head);    /* handy when benchmarking */
+    key->tail = key->head;
+    key->md = key->head;
+
+    key->payload_length = NO_PAYLOAD_LENGTH;
+
+    return ret < 0 ? 0 : 1;
+}
+
+# define STITCHED_CALL
+
+# if !defined(STITCHED_CALL)
+#  define aes_off 0
+# endif
+
+void sha256_block_data_order(void *c, const void *p, size_t len);
+
+static void sha256_update(SHA256_CTX *c, const void *data, size_t len)
+{
+    const unsigned char *ptr = data;
+    size_t res;
+
+    if ((res = c->num)) {
+        res = SHA256_CBLOCK - res;
+        if (len < res)
+            res = len;
+        SHA256_Update(c, ptr, res);
+        ptr += res;
+        len -= res;
+    }
+
+    res = len % SHA256_CBLOCK;
+    len -= res;
+
+    if (len) {
+        sha256_block_data_order(c, ptr, len / SHA256_CBLOCK);
+
+        ptr += len;
+        c->Nh += len >> 29;
+        c->Nl += len <<= 3;
+        if (c->Nl < (unsigned int)len)
+            c->Nh++;
+    }
+
+    if (res)
+        SHA256_Update(c, ptr, res);
+}
+
+# ifdef SHA256_Update
+#  undef SHA256_Update
+# endif
+# define SHA256_Update sha256_update
+
+# if !defined(OPENSSL_NO_MULTIBLOCK)
+
+typedef struct {
+    unsigned int A[8], B[8], C[8], D[8], E[8], F[8], G[8], H[8];
+} SHA256_MB_CTX;
+typedef struct {
+    const unsigned char *ptr;
+    int blocks;
+} HASH_DESC;
+
+void sha256_multi_block(SHA256_MB_CTX *, const HASH_DESC *, int);
+
+typedef struct {
+    const unsigned char *inp;
+    unsigned char *out;
+    int blocks;
+    u64 iv[2];
+} CIPH_DESC;
+
+void aesni_multi_cbc_encrypt(CIPH_DESC *, void *, int);
+
+static size_t tls1_1_multi_block_encrypt(EVP_AES_HMAC_SHA256 *key,
+                                         unsigned char *out,
+                                         const unsigned char *inp,
+                                         size_t inp_len, int n4x)
+{                               /* n4x is 1 or 2 */
+    HASH_DESC hash_d[8], edges[8];
+    CIPH_DESC ciph_d[8];
+    unsigned char storage[sizeof(SHA256_MB_CTX) + 32];
+    union {
+        u64 q[16];
+        u32 d[32];
+        u8 c[128];
+    } blocks[8];
+    SHA256_MB_CTX *ctx;
+    unsigned int frag, last, packlen, i, x4 = 4 * n4x, minblocks, processed =
+        0;
+    size_t ret = 0;
+    u8 *IVs;
+#  if defined(BSWAP8)
+    u64 seqnum;
+#  endif
+
+    /* ask for IVs in bulk */
+    if (RAND_bytes((IVs = blocks[0].c), 16 * x4) <= 0)
+        return 0;
+
+    /* align */
+    ctx = (SHA256_MB_CTX *) (storage + 32 - ((size_t)storage % 32));
+
+    frag = (unsigned int)inp_len >> (1 + n4x);
+    last = (unsigned int)inp_len + frag - (frag << (1 + n4x));
+    if (last > frag && ((last + 13 + 9) % 64) < (x4 - 1)) {
+        frag++;
+        last -= x4 - 1;
+    }
+
+    packlen = 5 + 16 + ((frag + 32 + 16) & -16);
+
+    /* populate descriptors with pointers and IVs */
+    hash_d[0].ptr = inp;
+    ciph_d[0].inp = inp;
+    /* 5+16 is place for header and explicit IV */
+    ciph_d[0].out = out + 5 + 16;
+    memcpy(ciph_d[0].out - 16, IVs, 16);
+    memcpy(ciph_d[0].iv, IVs, 16);
+    IVs += 16;
+
+    for (i = 1; i < x4; i++) {
+        ciph_d[i].inp = hash_d[i].ptr = hash_d[i - 1].ptr + frag;
+        ciph_d[i].out = ciph_d[i - 1].out + packlen;
+        memcpy(ciph_d[i].out - 16, IVs, 16);
+        memcpy(ciph_d[i].iv, IVs, 16);
+        IVs += 16;
+    }
+
+#  if defined(BSWAP8)
+    memcpy(blocks[0].c, key->md.data, 8);
+    seqnum = BSWAP8(blocks[0].q[0]);
+#  endif
+    for (i = 0; i < x4; i++) {
+        unsigned int len = (i == (x4 - 1) ? last : frag);
+#  if !defined(BSWAP8)
+        unsigned int carry, j;
+#  endif
+
+        ctx->A[i] = key->md.h[0];
+        ctx->B[i] = key->md.h[1];
+        ctx->C[i] = key->md.h[2];
+        ctx->D[i] = key->md.h[3];
+        ctx->E[i] = key->md.h[4];
+        ctx->F[i] = key->md.h[5];
+        ctx->G[i] = key->md.h[6];
+        ctx->H[i] = key->md.h[7];
+
+        /* fix seqnum */
+#  if defined(BSWAP8)
+        blocks[i].q[0] = BSWAP8(seqnum + i);
+#  else
+        for (carry = i, j = 8; j--;) {
+            blocks[i].c[j] = ((u8 *)key->md.data)[j] + carry;
+            carry = (blocks[i].c[j] - carry) >> (sizeof(carry) * 8 - 1);
+        }
+#  endif
+        blocks[i].c[8] = ((u8 *)key->md.data)[8];
+        blocks[i].c[9] = ((u8 *)key->md.data)[9];
+        blocks[i].c[10] = ((u8 *)key->md.data)[10];
+        /* fix length */
+        blocks[i].c[11] = (u8)(len >> 8);
+        blocks[i].c[12] = (u8)(len);
+
+        memcpy(blocks[i].c + 13, hash_d[i].ptr, 64 - 13);
+        hash_d[i].ptr += 64 - 13;
+        hash_d[i].blocks = (len - (64 - 13)) / 64;
+
+        edges[i].ptr = blocks[i].c;
+        edges[i].blocks = 1;
+    }
+
+    /* hash 13-byte headers and first 64-13 bytes of inputs */
+    sha256_multi_block(ctx, edges, n4x);
+    /* hash bulk inputs */
+#  define MAXCHUNKSIZE    2048
+#  if     MAXCHUNKSIZE%64
+#   error  "MAXCHUNKSIZE is not divisible by 64"
+#  elif   MAXCHUNKSIZE
+    /*
+     * goal is to minimize pressure on L1 cache by moving in shorter steps,
+     * so that hashed data is still in the cache by the time we encrypt it
+     */
+    minblocks = ((frag <= last ? frag : last) - (64 - 13)) / 64;
+    if (minblocks > MAXCHUNKSIZE / 64) {
+        for (i = 0; i < x4; i++) {
+            edges[i].ptr = hash_d[i].ptr;
+            edges[i].blocks = MAXCHUNKSIZE / 64;
+            ciph_d[i].blocks = MAXCHUNKSIZE / 16;
+        }
+        do {
+            sha256_multi_block(ctx, edges, n4x);
+            aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x);
+
+            for (i = 0; i < x4; i++) {
+                edges[i].ptr = hash_d[i].ptr += MAXCHUNKSIZE;
+                hash_d[i].blocks -= MAXCHUNKSIZE / 64;
+                edges[i].blocks = MAXCHUNKSIZE / 64;
+                ciph_d[i].inp += MAXCHUNKSIZE;
+                ciph_d[i].out += MAXCHUNKSIZE;
+                ciph_d[i].blocks = MAXCHUNKSIZE / 16;
+                memcpy(ciph_d[i].iv, ciph_d[i].out - 16, 16);
+            }
+            processed += MAXCHUNKSIZE;
+            minblocks -= MAXCHUNKSIZE / 64;
+        } while (minblocks > MAXCHUNKSIZE / 64);
+    }
+#  endif
+#  undef  MAXCHUNKSIZE
+    sha256_multi_block(ctx, hash_d, n4x);
+
+    memset(blocks, 0, sizeof(blocks));
+    for (i = 0; i < x4; i++) {
+        unsigned int len = (i == (x4 - 1) ? last : frag),
+            off = hash_d[i].blocks * 64;
+        const unsigned char *ptr = hash_d[i].ptr + off;
+
+        off = (len - processed) - (64 - 13) - off; /* remainder actually */
+        memcpy(blocks[i].c, ptr, off);
+        blocks[i].c[off] = 0x80;
+        len += 64 + 13;         /* 64 is HMAC header */
+        len *= 8;               /* convert to bits */
+        if (off < (64 - 8)) {
+#  ifdef BSWAP4
+            blocks[i].d[15] = BSWAP4(len);
+#  else
+            PUTU32(blocks[i].c + 60, len);
+#  endif
+            edges[i].blocks = 1;
+        } else {
+#  ifdef BSWAP4
+            blocks[i].d[31] = BSWAP4(len);
+#  else
+            PUTU32(blocks[i].c + 124, len);
+#  endif
+            edges[i].blocks = 2;
+        }
+        edges[i].ptr = blocks[i].c;
+    }
+
+    /* hash input tails and finalize */
+    sha256_multi_block(ctx, edges, n4x);
+
+    memset(blocks, 0, sizeof(blocks));
+    for (i = 0; i < x4; i++) {
+#  ifdef BSWAP4
+        blocks[i].d[0] = BSWAP4(ctx->A[i]);
+        ctx->A[i] = key->tail.h[0];
+        blocks[i].d[1] = BSWAP4(ctx->B[i]);
+        ctx->B[i] = key->tail.h[1];
+        blocks[i].d[2] = BSWAP4(ctx->C[i]);
+        ctx->C[i] = key->tail.h[2];
+        blocks[i].d[3] = BSWAP4(ctx->D[i]);
+        ctx->D[i] = key->tail.h[3];
+        blocks[i].d[4] = BSWAP4(ctx->E[i]);
+        ctx->E[i] = key->tail.h[4];
+        blocks[i].d[5] = BSWAP4(ctx->F[i]);
+        ctx->F[i] = key->tail.h[5];
+        blocks[i].d[6] = BSWAP4(ctx->G[i]);
+        ctx->G[i] = key->tail.h[6];
+        blocks[i].d[7] = BSWAP4(ctx->H[i]);
+        ctx->H[i] = key->tail.h[7];
+        blocks[i].c[32] = 0x80;
+        blocks[i].d[15] = BSWAP4((64 + 32) * 8);
+#  else
+        PUTU32(blocks[i].c + 0, ctx->A[i]);
+        ctx->A[i] = key->tail.h[0];
+        PUTU32(blocks[i].c + 4, ctx->B[i]);
+        ctx->B[i] = key->tail.h[1];
+        PUTU32(blocks[i].c + 8, ctx->C[i]);
+        ctx->C[i] = key->tail.h[2];
+        PUTU32(blocks[i].c + 12, ctx->D[i]);
+        ctx->D[i] = key->tail.h[3];
+        PUTU32(blocks[i].c + 16, ctx->E[i]);
+        ctx->E[i] = key->tail.h[4];
+        PUTU32(blocks[i].c + 20, ctx->F[i]);
+        ctx->F[i] = key->tail.h[5];
+        PUTU32(blocks[i].c + 24, ctx->G[i]);
+        ctx->G[i] = key->tail.h[6];
+        PUTU32(blocks[i].c + 28, ctx->H[i]);
+        ctx->H[i] = key->tail.h[7];
+        blocks[i].c[32] = 0x80;
+        PUTU32(blocks[i].c + 60, (64 + 32) * 8);
+#  endif
+        edges[i].ptr = blocks[i].c;
+        edges[i].blocks = 1;
+    }
+
+    /* finalize MACs */
+    sha256_multi_block(ctx, edges, n4x);
+
+    for (i = 0; i < x4; i++) {
+        unsigned int len = (i == (x4 - 1) ? last : frag), pad, j;
+        unsigned char *out0 = out;
+
+        memcpy(ciph_d[i].out, ciph_d[i].inp, len - processed);
+        ciph_d[i].inp = ciph_d[i].out;
+
+        out += 5 + 16 + len;
+
+        /* write MAC */
+        PUTU32(out + 0, ctx->A[i]);
+        PUTU32(out + 4, ctx->B[i]);
+        PUTU32(out + 8, ctx->C[i]);
+        PUTU32(out + 12, ctx->D[i]);
+        PUTU32(out + 16, ctx->E[i]);
+        PUTU32(out + 20, ctx->F[i]);
+        PUTU32(out + 24, ctx->G[i]);
+        PUTU32(out + 28, ctx->H[i]);
+        out += 32;
+        len += 32;
+
+        /* pad */
+        pad = 15 - len % 16;
+        for (j = 0; j <= pad; j++)
+            *(out++) = pad;
+        len += pad + 1;
+
+        ciph_d[i].blocks = (len - processed) / 16;
+        len += 16;              /* account for explicit iv */
+
+        /* arrange header */
+        out0[0] = ((u8 *)key->md.data)[8];
+        out0[1] = ((u8 *)key->md.data)[9];
+        out0[2] = ((u8 *)key->md.data)[10];
+        out0[3] = (u8)(len >> 8);
+        out0[4] = (u8)(len);
+
+        ret += len + 5;
+        inp += frag;
+    }
+
+    aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x);
+
+    OPENSSL_cleanse(blocks, sizeof(blocks));
+    OPENSSL_cleanse(ctx, sizeof(*ctx));
+
+    return ret;
+}
+# endif
+
+static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx,
+                                        unsigned char *out,
+                                        const unsigned char *in, size_t len)
+{
+    EVP_AES_HMAC_SHA256 *key = data(ctx);
+    unsigned int l;
+    size_t plen = key->payload_length, iv = 0, /* explicit IV in TLS 1.1 and
+                                                * later */
+        sha_off = 0;
+# if defined(STITCHED_CALL)
+    size_t aes_off = 0, blocks;
+
+    sha_off = SHA256_CBLOCK - key->md.num;
+# endif
+
+    key->payload_length = NO_PAYLOAD_LENGTH;
+
+    if (len % AES_BLOCK_SIZE)
+        return 0;
+
+    if (EVP_CIPHER_CTX_encrypting(ctx)) {
+        if (plen == NO_PAYLOAD_LENGTH)
+            plen = len;
+        else if (len !=
+                 ((plen + SHA256_DIGEST_LENGTH +
+                   AES_BLOCK_SIZE) & -AES_BLOCK_SIZE))
+            return 0;
+        else if (key->aux.tls_ver >= TLS1_1_VERSION)
+            iv = AES_BLOCK_SIZE;
+
+# if defined(STITCHED_CALL)
+        /*
+         * Assembly stitch handles AVX-capable processors, but its
+         * performance is not optimal on AMD Jaguar, ~40% worse, for
+         * unknown reasons. Incidentally processor in question supports
+         * AVX, but not AMD-specific XOP extension, which can be used
+         * to identify it and avoid stitch invocation. So that after we
+         * establish that current CPU supports AVX, we even see if it's
+         * either even XOP-capable Bulldozer-based or GenuineIntel one.
+         */
+        if (OPENSSL_ia32cap_P[1] & (1 << (60 - 32)) && /* AVX? */
+            ((OPENSSL_ia32cap_P[1] & (1 << (43 - 32))) /* XOP? */
+             | (OPENSSL_ia32cap_P[0] & (1<<30))) &&    /* "Intel CPU"? */
+            plen > (sha_off + iv) &&
+            (blocks = (plen - (sha_off + iv)) / SHA256_CBLOCK)) {
+            SHA256_Update(&key->md, in + iv, sha_off);
+
+            (void)aesni_cbc_sha256_enc(in, out, blocks, &key->ks,
+                                       EVP_CIPHER_CTX_iv_noconst(ctx),
+                                       &key->md, in + iv + sha_off);
+            blocks *= SHA256_CBLOCK;
+            aes_off += blocks;
+            sha_off += blocks;
+            key->md.Nh += blocks >> 29;
+            key->md.Nl += blocks <<= 3;
+            if (key->md.Nl < (unsigned int)blocks)
+                key->md.Nh++;
+        } else {
+            sha_off = 0;
+        }
+# endif
+        sha_off += iv;
+        SHA256_Update(&key->md, in + sha_off, plen - sha_off);
+
+        if (plen != len) {      /* "TLS" mode of operation */
+            if (in != out)
+                memcpy(out + aes_off, in + aes_off, plen - aes_off);
+
+            /* calculate HMAC and append it to payload */
+            SHA256_Final(out + plen, &key->md);
+            key->md = key->tail;
+            SHA256_Update(&key->md, out + plen, SHA256_DIGEST_LENGTH);
+            SHA256_Final(out + plen, &key->md);
+
+            /* pad the payload|hmac */
+            plen += SHA256_DIGEST_LENGTH;
+            for (l = len - plen - 1; plen < len; plen++)
+                out[plen] = l;
+            /* encrypt HMAC|padding at once */
+            aesni_cbc_encrypt(out + aes_off, out + aes_off, len - aes_off,
+                              &key->ks, EVP_CIPHER_CTX_iv_noconst(ctx), 1);
+        } else {
+            aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off,
+                              &key->ks, EVP_CIPHER_CTX_iv_noconst(ctx), 1);
+        }
+    } else {
+        union {
+            unsigned int u[SHA256_DIGEST_LENGTH / sizeof(unsigned int)];
+            unsigned char c[64 + SHA256_DIGEST_LENGTH];
+        } mac, *pmac;
+
+        /* arrange cache line alignment */
+        pmac = (void *)(((size_t)mac.c + 63) & ((size_t)0 - 64));
+
+        /* decrypt HMAC|padding at once */
+        aesni_cbc_encrypt(in, out, len, &key->ks,
+                          EVP_CIPHER_CTX_iv_noconst(ctx), 0);
+
+        if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */
+            size_t inp_len, mask, j, i;
+            unsigned int res, maxpad, pad, bitlen;
+            int ret = 1;
+            union {
+                unsigned int u[SHA_LBLOCK];
+                unsigned char c[SHA256_CBLOCK];
+            } *data = (void *)key->md.data;
+
+            if ((key->aux.tls_aad[plen - 4] << 8 | key->aux.tls_aad[plen - 3])
+                >= TLS1_1_VERSION)
+                iv = AES_BLOCK_SIZE;
+
+            if (len < (iv + SHA256_DIGEST_LENGTH + 1))
+                return 0;
+
+            /* omit explicit iv */
+            out += iv;
+            len -= iv;
+
+            /* figure out payload length */
+            pad = out[len - 1];
+            maxpad = len - (SHA256_DIGEST_LENGTH + 1);
+            maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8);
+            maxpad &= 255;
+
+            ret &= constant_time_ge(maxpad, pad);
+
+            inp_len = len - (SHA256_DIGEST_LENGTH + pad + 1);
+            mask = (0 - ((inp_len - len) >> (sizeof(inp_len) * 8 - 1)));
+            inp_len &= mask;
+            ret &= (int)mask;
+
+            key->aux.tls_aad[plen - 2] = inp_len >> 8;
+            key->aux.tls_aad[plen - 1] = inp_len;
+
+            /* calculate HMAC */
+            key->md = key->head;
+            SHA256_Update(&key->md, key->aux.tls_aad, plen);
+
+# if 1
+            len -= SHA256_DIGEST_LENGTH; /* amend mac */
+            if (len >= (256 + SHA256_CBLOCK)) {
+                j = (len - (256 + SHA256_CBLOCK)) & (0 - SHA256_CBLOCK);
+                j += SHA256_CBLOCK - key->md.num;
+                SHA256_Update(&key->md, out, j);
+                out += j;
+                len -= j;
+                inp_len -= j;
+            }
+
+            /* but pretend as if we hashed padded payload */
+            bitlen = key->md.Nl + (inp_len << 3); /* at most 18 bits */
+#  ifdef BSWAP4
+            bitlen = BSWAP4(bitlen);
+#  else
+            mac.c[0] = 0;
+            mac.c[1] = (unsigned char)(bitlen >> 16);
+            mac.c[2] = (unsigned char)(bitlen >> 8);
+            mac.c[3] = (unsigned char)bitlen;
+            bitlen = mac.u[0];
+#  endif
+
+            pmac->u[0] = 0;
+            pmac->u[1] = 0;
+            pmac->u[2] = 0;
+            pmac->u[3] = 0;
+            pmac->u[4] = 0;
+            pmac->u[5] = 0;
+            pmac->u[6] = 0;
+            pmac->u[7] = 0;
+
+            for (res = key->md.num, j = 0; j < len; j++) {
+                size_t c = out[j];
+                mask = (j - inp_len) >> (sizeof(j) * 8 - 8);
+                c &= mask;
+                c |= 0x80 & ~mask & ~((inp_len - j) >> (sizeof(j) * 8 - 8));
+                data->c[res++] = (unsigned char)c;
+
+                if (res != SHA256_CBLOCK)
+                    continue;
+
+                /* j is not incremented yet */
+                mask = 0 - ((inp_len + 7 - j) >> (sizeof(j) * 8 - 1));
+                data->u[SHA_LBLOCK - 1] |= bitlen & mask;
+                sha256_block_data_order(&key->md, data, 1);
+                mask &= 0 - ((j - inp_len - 72) >> (sizeof(j) * 8 - 1));
+                pmac->u[0] |= key->md.h[0] & mask;
+                pmac->u[1] |= key->md.h[1] & mask;
+                pmac->u[2] |= key->md.h[2] & mask;
+                pmac->u[3] |= key->md.h[3] & mask;
+                pmac->u[4] |= key->md.h[4] & mask;
+                pmac->u[5] |= key->md.h[5] & mask;
+                pmac->u[6] |= key->md.h[6] & mask;
+                pmac->u[7] |= key->md.h[7] & mask;
+                res = 0;
+            }
+
+            for (i = res; i < SHA256_CBLOCK; i++, j++)
+                data->c[i] = 0;
+
+            if (res > SHA256_CBLOCK - 8) {
+                mask = 0 - ((inp_len + 8 - j) >> (sizeof(j) * 8 - 1));
+                data->u[SHA_LBLOCK - 1] |= bitlen & mask;
+                sha256_block_data_order(&key->md, data, 1);
+                mask &= 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1));
+                pmac->u[0] |= key->md.h[0] & mask;
+                pmac->u[1] |= key->md.h[1] & mask;
+                pmac->u[2] |= key->md.h[2] & mask;
+                pmac->u[3] |= key->md.h[3] & mask;
+                pmac->u[4] |= key->md.h[4] & mask;
+                pmac->u[5] |= key->md.h[5] & mask;
+                pmac->u[6] |= key->md.h[6] & mask;
+                pmac->u[7] |= key->md.h[7] & mask;
+
+                memset(data, 0, SHA256_CBLOCK);
+                j += 64;
+            }
+            data->u[SHA_LBLOCK - 1] = bitlen;
+            sha256_block_data_order(&key->md, data, 1);
+            mask = 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1));
+            pmac->u[0] |= key->md.h[0] & mask;
+            pmac->u[1] |= key->md.h[1] & mask;
+            pmac->u[2] |= key->md.h[2] & mask;
+            pmac->u[3] |= key->md.h[3] & mask;
+            pmac->u[4] |= key->md.h[4] & mask;
+            pmac->u[5] |= key->md.h[5] & mask;
+            pmac->u[6] |= key->md.h[6] & mask;
+            pmac->u[7] |= key->md.h[7] & mask;
+
+#  ifdef BSWAP4
+            pmac->u[0] = BSWAP4(pmac->u[0]);
+            pmac->u[1] = BSWAP4(pmac->u[1]);
+            pmac->u[2] = BSWAP4(pmac->u[2]);
+            pmac->u[3] = BSWAP4(pmac->u[3]);
+            pmac->u[4] = BSWAP4(pmac->u[4]);
+            pmac->u[5] = BSWAP4(pmac->u[5]);
+            pmac->u[6] = BSWAP4(pmac->u[6]);
+            pmac->u[7] = BSWAP4(pmac->u[7]);
+#  else
+            for (i = 0; i < 8; i++) {
+                res = pmac->u[i];
+                pmac->c[4 * i + 0] = (unsigned char)(res >> 24);
+                pmac->c[4 * i + 1] = (unsigned char)(res >> 16);
+                pmac->c[4 * i + 2] = (unsigned char)(res >> 8);
+                pmac->c[4 * i + 3] = (unsigned char)res;
+            }
+#  endif
+            len += SHA256_DIGEST_LENGTH;
+# else
+            SHA256_Update(&key->md, out, inp_len);
+            res = key->md.num;
+            SHA256_Final(pmac->c, &key->md);
+
+            {
+                unsigned int inp_blocks, pad_blocks;
+
+                /* but pretend as if we hashed padded payload */
+                inp_blocks =
+                    1 + ((SHA256_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1));
+                res += (unsigned int)(len - inp_len);
+                pad_blocks = res / SHA256_CBLOCK;
+                res %= SHA256_CBLOCK;
+                pad_blocks +=
+                    1 + ((SHA256_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1));
+                for (; inp_blocks < pad_blocks; inp_blocks++)
+                    sha1_block_data_order(&key->md, data, 1);
+            }
+# endif
+            key->md = key->tail;
+            SHA256_Update(&key->md, pmac->c, SHA256_DIGEST_LENGTH);
+            SHA256_Final(pmac->c, &key->md);
+
+            /* verify HMAC */
+            out += inp_len;
+            len -= inp_len;
+# if 1
+            {
+                unsigned char *p =
+                    out + len - 1 - maxpad - SHA256_DIGEST_LENGTH;
+                size_t off = out - p;
+                unsigned int c, cmask;
+
+                maxpad += SHA256_DIGEST_LENGTH;
+                for (res = 0, i = 0, j = 0; j < maxpad; j++) {
+                    c = p[j];
+                    cmask =
+                        ((int)(j - off - SHA256_DIGEST_LENGTH)) >>
+                        (sizeof(int) * 8 - 1);
+                    res |= (c ^ pad) & ~cmask; /* ... and padding */
+                    cmask &= ((int)(off - 1 - j)) >> (sizeof(int) * 8 - 1);
+                    res |= (c ^ pmac->c[i]) & cmask;
+                    i += 1 & cmask;
+                }
+                maxpad -= SHA256_DIGEST_LENGTH;
+
+                res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
+                ret &= (int)~res;
+            }
+# else
+            for (res = 0, i = 0; i < SHA256_DIGEST_LENGTH; i++)
+                res |= out[i] ^ pmac->c[i];
+            res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1));
+            ret &= (int)~res;
+
+            /* verify padding */
+            pad = (pad & ~res) | (maxpad & res);
+            out = out + len - 1 - pad;
+            for (res = 0, i = 0; i < pad; i++)
+                res |= out[i] ^ pad;
+
+            res = (0 - res) >> (sizeof(res) * 8 - 1);
+            ret &= (int)~res;
+# endif
+            return ret;
+        } else {
+            SHA256_Update(&key->md, out, len);
+        }
+    }
+
+    return 1;
+}
+
+static int aesni_cbc_hmac_sha256_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
+                                      void *ptr)
+{
+    EVP_AES_HMAC_SHA256 *key = data(ctx);
+    unsigned int u_arg = (unsigned int)arg;
+
+    switch (type) {
+    case EVP_CTRL_AEAD_SET_MAC_KEY:
+        {
+            unsigned int i;
+            unsigned char hmac_key[64];
+
+            memset(hmac_key, 0, sizeof(hmac_key));
+
+            if (arg < 0)
+                return -1;
+
+            if (u_arg > sizeof(hmac_key)) {
+                SHA256_Init(&key->head);
+                SHA256_Update(&key->head, ptr, arg);
+                SHA256_Final(hmac_key, &key->head);
+            } else {
+                memcpy(hmac_key, ptr, arg);
+            }
+
+            for (i = 0; i < sizeof(hmac_key); i++)
+                hmac_key[i] ^= 0x36; /* ipad */
+            SHA256_Init(&key->head);
+            SHA256_Update(&key->head, hmac_key, sizeof(hmac_key));
+
+            for (i = 0; i < sizeof(hmac_key); i++)
+                hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */
+            SHA256_Init(&key->tail);
+            SHA256_Update(&key->tail, hmac_key, sizeof(hmac_key));
+
+            OPENSSL_cleanse(hmac_key, sizeof(hmac_key));
+
+            return 1;
+        }
+    case EVP_CTRL_AEAD_TLS1_AAD:
+        {
+            unsigned char *p = ptr;
+            unsigned int len = p[arg - 2] << 8 | p[arg - 1];
+
+            if (arg != EVP_AEAD_TLS1_AAD_LEN)
+                return -1;
+
+            if (EVP_CIPHER_CTX_encrypting(ctx)) {
+                key->payload_length = len;
+                if ((key->aux.tls_ver =
+                     p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) {
+                    len -= AES_BLOCK_SIZE;
+                    p[arg - 2] = len >> 8;
+                    p[arg - 1] = len;
+                }
+                key->md = key->head;
+                SHA256_Update(&key->md, p, arg);
+
+                return (int)(((len + SHA256_DIGEST_LENGTH +
+                               AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)
+                             - len);
+            } else {
+                memcpy(key->aux.tls_aad, ptr, arg);
+                key->payload_length = arg;
+
+                return SHA256_DIGEST_LENGTH;
+            }
+        }
+# if !defined(OPENSSL_NO_MULTIBLOCK)
+    case EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE:
+        return (int)(5 + 16 + ((arg + 32 + 16) & -16));
+    case EVP_CTRL_TLS1_1_MULTIBLOCK_AAD:
+        {
+            EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param =
+                (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr;
+            unsigned int n4x = 1, x4;
+            unsigned int frag, last, packlen, inp_len;
+
+            if (arg < 0)
+                return -1;
+
+            if (u_arg < sizeof(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM))
+                return -1;
+
+            inp_len = param->inp[11] << 8 | param->inp[12];
+
+            if (EVP_CIPHER_CTX_encrypting(ctx)) {
+                if ((param->inp[9] << 8 | param->inp[10]) < TLS1_1_VERSION)
+                    return -1;
+
+                if (inp_len) {
+                    if (inp_len < 4096)
+                        return 0; /* too short */
+
+                    if (inp_len >= 8192 && OPENSSL_ia32cap_P[2] & (1 << 5))
+                        n4x = 2; /* AVX2 */
+                } else if ((n4x = param->interleave / 4) && n4x <= 2)
+                    inp_len = param->len;
+                else
+                    return -1;
+
+                key->md = key->head;
+                SHA256_Update(&key->md, param->inp, 13);
+
+                x4 = 4 * n4x;
+                n4x += 1;
+
+                frag = inp_len >> n4x;
+                last = inp_len + frag - (frag << n4x);
+                if (last > frag && ((last + 13 + 9) % 64 < (x4 - 1))) {
+                    frag++;
+                    last -= x4 - 1;
+                }
+
+                packlen = 5 + 16 + ((frag + 32 + 16) & -16);
+                packlen = (packlen << n4x) - packlen;
+                packlen += 5 + 16 + ((last + 32 + 16) & -16);
+
+                param->interleave = x4;
+
+                return (int)packlen;
+            } else
+                return -1;      /* not yet */
+        }
+    case EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT:
+        {
+            EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param =
+                (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr;
+
+            return (int)tls1_1_multi_block_encrypt(key, param->out,
+                                                   param->inp, param->len,
+                                                   param->interleave / 4);
+        }
+    case EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT:
+# endif
+    default:
+        return -1;
+    }
+}
+
+static EVP_CIPHER aesni_128_cbc_hmac_sha256_cipher = {
+# ifdef NID_aes_128_cbc_hmac_sha256
+    NID_aes_128_cbc_hmac_sha256,
+# else
+    NID_undef,
+# endif
+    AES_BLOCK_SIZE, 16, AES_BLOCK_SIZE,
+    EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
+        EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK,
+    aesni_cbc_hmac_sha256_init_key,
+    aesni_cbc_hmac_sha256_cipher,
+    NULL,
+    sizeof(EVP_AES_HMAC_SHA256),
+    EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv,
+    EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv,
+    aesni_cbc_hmac_sha256_ctrl,
+    NULL
+};
+
+static EVP_CIPHER aesni_256_cbc_hmac_sha256_cipher = {
+# ifdef NID_aes_256_cbc_hmac_sha256
+    NID_aes_256_cbc_hmac_sha256,
+# else
+    NID_undef,
+# endif
+    AES_BLOCK_SIZE, 32, AES_BLOCK_SIZE,
+    EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 |
+        EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK,
+    aesni_cbc_hmac_sha256_init_key,
+    aesni_cbc_hmac_sha256_cipher,
+    NULL,
+    sizeof(EVP_AES_HMAC_SHA256),
+    EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv,
+    EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv,
+    aesni_cbc_hmac_sha256_ctrl,
+    NULL
+};
+
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void)
+{
+    return ((OPENSSL_ia32cap_P[1] & AESNI_CAPABLE) &&
+            aesni_cbc_sha256_enc(NULL, NULL, 0, NULL, NULL, NULL, NULL) ?
+            &aesni_128_cbc_hmac_sha256_cipher : NULL);
+}
+
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void)
+{
+    return ((OPENSSL_ia32cap_P[1] & AESNI_CAPABLE) &&
+            aesni_cbc_sha256_enc(NULL, NULL, 0, NULL, NULL, NULL, NULL) ?
+            &aesni_256_cbc_hmac_sha256_cipher : NULL);
+}
+#else
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void)
+{
+    return NULL;
+}
+
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void)
+{
+    return NULL;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_bf.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_bf.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_bf.c	(revision 331)
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#ifndef OPENSSL_NO_BF
+# include <openssl/evp.h>
+# include "internal/evp_int.h"
+# include <openssl/objects.h>
+# include <openssl/blowfish.h>
+
+static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                       const unsigned char *iv, int enc);
+
+typedef struct {
+    BF_KEY ks;
+} EVP_BF_KEY;
+
+# define data(ctx)       EVP_C_DATA(EVP_BF_KEY,ctx)
+
+IMPLEMENT_BLOCK_CIPHER(bf, ks, BF, EVP_BF_KEY, NID_bf, 8, 16, 8, 64,
+                       EVP_CIPH_VARIABLE_LENGTH, bf_init_key, NULL,
+                       EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL)
+
+static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                       const unsigned char *iv, int enc)
+{
+    BF_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key);
+    return 1;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_camellia.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_camellia.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_camellia.c	(revision 331)
@@ -0,0 +1,364 @@
+/*
+ * Copyright 2006-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 <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_CAMELLIA
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <openssl/evp.h>
+# include <openssl/err.h>
+# include <string.h>
+# include <assert.h>
+# include <openssl/camellia.h>
+# include "internal/evp_int.h"
+# include "../modes/modes_lcl.h"
+
+static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                             const unsigned char *iv, int enc);
+
+/* Camellia subkey Structure */
+typedef struct {
+    CAMELLIA_KEY ks;
+    block128_f block;
+    union {
+        cbc128_f cbc;
+        ctr128_f ctr;
+    } stream;
+} EVP_CAMELLIA_KEY;
+
+# define MAXBITCHUNK     ((size_t)1<<(sizeof(size_t)*8-4))
+
+/* Attribute operation for Camellia */
+# define data(ctx)       EVP_C_DATA(EVP_CAMELLIA_KEY,ctx)
+
+# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
+/* ---------^^^ this is not a typo, just a way to detect that
+ * assembler support was in general requested... */
+#  include "sparc_arch.h"
+
+extern unsigned int OPENSSL_sparcv9cap_P[];
+
+#  define SPARC_CMLL_CAPABLE      (OPENSSL_sparcv9cap_P[1] & CFR_CAMELLIA)
+
+void cmll_t4_set_key(const unsigned char *key, int bits, CAMELLIA_KEY *ks);
+void cmll_t4_encrypt(const unsigned char *in, unsigned char *out,
+                     const CAMELLIA_KEY *key);
+void cmll_t4_decrypt(const unsigned char *in, unsigned char *out,
+                     const CAMELLIA_KEY *key);
+
+void cmll128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                            size_t len, const CAMELLIA_KEY *key,
+                            unsigned char *ivec);
+void cmll128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
+                            size_t len, const CAMELLIA_KEY *key,
+                            unsigned char *ivec);
+void cmll256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                            size_t len, const CAMELLIA_KEY *key,
+                            unsigned char *ivec);
+void cmll256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out,
+                            size_t len, const CAMELLIA_KEY *key,
+                            unsigned char *ivec);
+void cmll128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+                              size_t blocks, const CAMELLIA_KEY *key,
+                              unsigned char *ivec);
+void cmll256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out,
+                              size_t blocks, const CAMELLIA_KEY *key,
+                              unsigned char *ivec);
+
+static int cmll_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                            const unsigned char *iv, int enc)
+{
+    int ret, mode, bits;
+    EVP_CAMELLIA_KEY *dat =
+        (EVP_CAMELLIA_KEY *)EVP_CIPHER_CTX_get_cipher_data(ctx);
+
+    mode = EVP_CIPHER_CTX_mode(ctx);
+    bits = EVP_CIPHER_CTX_key_length(ctx) * 8;
+
+    cmll_t4_set_key(key, bits, &dat->ks);
+
+    if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
+        && !enc) {
+        ret = 0;
+        dat->block = (block128_f) cmll_t4_decrypt;
+        switch (bits) {
+        case 128:
+            dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+                (cbc128_f) cmll128_t4_cbc_decrypt : NULL;
+            break;
+        case 192:
+        case 256:
+            dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+                (cbc128_f) cmll256_t4_cbc_decrypt : NULL;
+            break;
+        default:
+            ret = -1;
+        }
+    } else {
+        ret = 0;
+        dat->block = (block128_f) cmll_t4_encrypt;
+        switch (bits) {
+        case 128:
+            if (mode == EVP_CIPH_CBC_MODE)
+                dat->stream.cbc = (cbc128_f) cmll128_t4_cbc_encrypt;
+            else if (mode == EVP_CIPH_CTR_MODE)
+                dat->stream.ctr = (ctr128_f) cmll128_t4_ctr32_encrypt;
+            else
+                dat->stream.cbc = NULL;
+            break;
+        case 192:
+        case 256:
+            if (mode == EVP_CIPH_CBC_MODE)
+                dat->stream.cbc = (cbc128_f) cmll256_t4_cbc_encrypt;
+            else if (mode == EVP_CIPH_CTR_MODE)
+                dat->stream.ctr = (ctr128_f) cmll256_t4_ctr32_encrypt;
+            else
+                dat->stream.cbc = NULL;
+            break;
+        default:
+            ret = -1;
+        }
+    }
+
+    if (ret < 0) {
+        EVPerr(EVP_F_CMLL_T4_INIT_KEY, EVP_R_CAMELLIA_KEY_SETUP_FAILED);
+        return 0;
+    }
+
+    return 1;
+}
+
+#  define cmll_t4_cbc_cipher camellia_cbc_cipher
+static int cmll_t4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                              const unsigned char *in, size_t len);
+
+#  define cmll_t4_ecb_cipher camellia_ecb_cipher
+static int cmll_t4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                              const unsigned char *in, size_t len);
+
+#  define cmll_t4_ofb_cipher camellia_ofb_cipher
+static int cmll_t4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                              const unsigned char *in, size_t len);
+
+#  define cmll_t4_cfb_cipher camellia_cfb_cipher
+static int cmll_t4_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                              const unsigned char *in, size_t len);
+
+#  define cmll_t4_cfb8_cipher camellia_cfb8_cipher
+static int cmll_t4_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                               const unsigned char *in, size_t len);
+
+#  define cmll_t4_cfb1_cipher camellia_cfb1_cipher
+static int cmll_t4_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                               const unsigned char *in, size_t len);
+
+#  define cmll_t4_ctr_cipher camellia_ctr_cipher
+static int cmll_t4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                              const unsigned char *in, size_t len);
+
+#  define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
+static const EVP_CIPHER cmll_t4_##keylen##_##mode = { \
+        nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
+        flags|EVP_CIPH_##MODE##_MODE,   \
+        cmll_t4_init_key,               \
+        cmll_t4_##mode##_cipher,        \
+        NULL,                           \
+        sizeof(EVP_CAMELLIA_KEY),       \
+        NULL,NULL,NULL,NULL }; \
+static const EVP_CIPHER camellia_##keylen##_##mode = { \
+        nid##_##keylen##_##nmode,blocksize,     \
+        keylen/8,ivlen, \
+        flags|EVP_CIPH_##MODE##_MODE,   \
+        camellia_init_key,              \
+        camellia_##mode##_cipher,       \
+        NULL,                           \
+        sizeof(EVP_CAMELLIA_KEY),       \
+        NULL,NULL,NULL,NULL }; \
+const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
+{ return SPARC_CMLL_CAPABLE?&cmll_t4_##keylen##_##mode:&camellia_##keylen##_##mode; }
+
+# else
+
+#  define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
+static const EVP_CIPHER camellia_##keylen##_##mode = { \
+        nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
+        flags|EVP_CIPH_##MODE##_MODE,   \
+        camellia_init_key,              \
+        camellia_##mode##_cipher,       \
+        NULL,                           \
+        sizeof(EVP_CAMELLIA_KEY),       \
+        NULL,NULL,NULL,NULL }; \
+const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \
+{ return &camellia_##keylen##_##mode; }
+
+# endif
+
+# define BLOCK_CIPHER_generic_pack(nid,keylen,flags)             \
+        BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)     \
+        BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)      \
+        BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)   \
+        BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1)   \
+        BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags)       \
+        BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags)       \
+        BLOCK_CIPHER_generic(nid, keylen, 1, 16, ctr, ctr, CTR, flags)
+
+/* The subkey for Camellia is generated. */
+static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                             const unsigned char *iv, int enc)
+{
+    int ret, mode;
+    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
+
+    ret = Camellia_set_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, &dat->ks);
+    if (ret < 0) {
+        EVPerr(EVP_F_CAMELLIA_INIT_KEY, EVP_R_CAMELLIA_KEY_SETUP_FAILED);
+        return 0;
+    }
+
+    mode = EVP_CIPHER_CTX_mode(ctx);
+    if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
+        && !enc) {
+        dat->block = (block128_f) Camellia_decrypt;
+        dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+            (cbc128_f) Camellia_cbc_encrypt : NULL;
+    } else {
+        dat->block = (block128_f) Camellia_encrypt;
+        dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
+            (cbc128_f) Camellia_cbc_encrypt : NULL;
+    }
+
+    return 1;
+}
+
+static int camellia_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                               const unsigned char *in, size_t len)
+{
+    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
+
+    if (dat->stream.cbc)
+        (*dat->stream.cbc) (in, out, len, &dat->ks,
+                            EVP_CIPHER_CTX_iv_noconst(ctx),
+                            EVP_CIPHER_CTX_encrypting(ctx));
+    else if (EVP_CIPHER_CTX_encrypting(ctx))
+        CRYPTO_cbc128_encrypt(in, out, len, &dat->ks,
+                              EVP_CIPHER_CTX_iv_noconst(ctx), dat->block);
+    else
+        CRYPTO_cbc128_decrypt(in, out, len, &dat->ks,
+                              EVP_CIPHER_CTX_iv_noconst(ctx), dat->block);
+
+    return 1;
+}
+
+static int camellia_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                               const unsigned char *in, size_t len)
+{
+    size_t bl = EVP_CIPHER_CTX_block_size(ctx);
+    size_t i;
+    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
+
+    if (len < bl)
+        return 1;
+
+    for (i = 0, len -= bl; i <= len; i += bl)
+        (*dat->block) (in + i, out + i, &dat->ks);
+
+    return 1;
+}
+
+static int camellia_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                               const unsigned char *in, size_t len)
+{
+    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
+
+    int num = EVP_CIPHER_CTX_num(ctx);
+    CRYPTO_ofb128_encrypt(in, out, len, &dat->ks,
+                          EVP_CIPHER_CTX_iv_noconst(ctx), &num, dat->block);
+    EVP_CIPHER_CTX_set_num(ctx, num);
+    return 1;
+}
+
+static int camellia_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                               const unsigned char *in, size_t len)
+{
+    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
+
+    int num = EVP_CIPHER_CTX_num(ctx);
+    CRYPTO_cfb128_encrypt(in, out, len, &dat->ks,
+                          EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block);
+    EVP_CIPHER_CTX_set_num(ctx, num);
+    return 1;
+}
+
+static int camellia_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                                const unsigned char *in, size_t len)
+{
+    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
+
+    int num = EVP_CIPHER_CTX_num(ctx);
+    CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks,
+                            EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block);
+    EVP_CIPHER_CTX_set_num(ctx, num);
+    return 1;
+}
+
+static int camellia_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                                const unsigned char *in, size_t len)
+{
+    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
+
+    if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) {
+        int num = EVP_CIPHER_CTX_num(ctx);
+        CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks,
+                                EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block);
+        EVP_CIPHER_CTX_set_num(ctx, num);
+        return 1;
+    }
+
+    while (len >= MAXBITCHUNK) {
+        int num = EVP_CIPHER_CTX_num(ctx);
+        CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks,
+                                EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block);
+        len -= MAXBITCHUNK;
+        EVP_CIPHER_CTX_set_num(ctx, num);
+    }
+    if (len) {
+        int num = EVP_CIPHER_CTX_num(ctx);
+        CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks,
+                                EVP_CIPHER_CTX_iv_noconst(ctx), &num, EVP_CIPHER_CTX_encrypting(ctx), dat->block);
+        EVP_CIPHER_CTX_set_num(ctx, num);
+    }
+
+    return 1;
+}
+
+static int camellia_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                               const unsigned char *in, size_t len)
+{
+    unsigned int num = EVP_CIPHER_CTX_num(ctx);
+    EVP_CAMELLIA_KEY *dat = EVP_C_DATA(EVP_CAMELLIA_KEY,ctx);
+
+    if (dat->stream.ctr)
+        CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks,
+                                    EVP_CIPHER_CTX_iv_noconst(ctx),
+                                    EVP_CIPHER_CTX_buf_noconst(ctx), &num,
+                                    dat->stream.ctr);
+    else
+        CRYPTO_ctr128_encrypt(in, out, len, &dat->ks,
+                              EVP_CIPHER_CTX_iv_noconst(ctx),
+                              EVP_CIPHER_CTX_buf_noconst(ctx), &num,
+                              dat->block);
+    EVP_CIPHER_CTX_set_num(ctx, num);
+    return 1;
+}
+
+BLOCK_CIPHER_generic_pack(NID_camellia, 128, 0)
+    BLOCK_CIPHER_generic_pack(NID_camellia, 192, 0)
+    BLOCK_CIPHER_generic_pack(NID_camellia, 256, 0)
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_cast.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_cast.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_cast.c	(revision 331)
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+
+#ifndef OPENSSL_NO_CAST
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "internal/evp_int.h"
+# include <openssl/cast.h>
+
+static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                         const unsigned char *iv, int enc);
+
+typedef struct {
+    CAST_KEY ks;
+} EVP_CAST_KEY;
+
+# define data(ctx)       EVP_C_DATA(EVP_CAST_KEY,ctx)
+
+IMPLEMENT_BLOCK_CIPHER(cast5, ks, CAST, EVP_CAST_KEY,
+                       NID_cast5, 8, CAST_KEY_LENGTH, 8, 64,
+                       EVP_CIPH_VARIABLE_LENGTH, cast_init_key, NULL,
+                       EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL)
+
+static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                         const unsigned char *iv, int enc)
+{
+    CAST_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key);
+    return 1;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_chacha20_poly1305.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_chacha20_poly1305.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_chacha20_poly1305.c	(revision 331)
@@ -0,0 +1,454 @@
+/*
+ * Copyright 2015-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 <stdio.h>
+#include "internal/cryptlib.h"
+
+#ifndef OPENSSL_NO_CHACHA
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "evp_locl.h"
+# include "internal/evp_int.h"
+# include "internal/chacha.h"
+
+typedef struct {
+    union {
+        double align;   /* this ensures even sizeof(EVP_CHACHA_KEY)%8==0 */
+        unsigned int d[CHACHA_KEY_SIZE / 4];
+    } key;
+    unsigned int  counter[CHACHA_CTR_SIZE / 4];
+    unsigned char buf[CHACHA_BLK_SIZE];
+    unsigned int  partial_len;
+} EVP_CHACHA_KEY;
+
+#define data(ctx)   ((EVP_CHACHA_KEY *)(ctx)->cipher_data)
+
+static int chacha_init_key(EVP_CIPHER_CTX *ctx,
+                           const unsigned char user_key[CHACHA_KEY_SIZE],
+                           const unsigned char iv[CHACHA_CTR_SIZE], int enc)
+{
+    EVP_CHACHA_KEY *key = data(ctx);
+    unsigned int i;
+
+    if (user_key)
+        for (i = 0; i < CHACHA_KEY_SIZE; i+=4) {
+            key->key.d[i/4] = CHACHA_U8TOU32(user_key+i);
+        }
+
+    if (iv)
+        for (i = 0; i < CHACHA_CTR_SIZE; i+=4) {
+            key->counter[i/4] = CHACHA_U8TOU32(iv+i);
+        }
+
+    key->partial_len = 0;
+
+    return 1;
+}
+
+static int chacha_cipher(EVP_CIPHER_CTX * ctx, unsigned char *out,
+                         const unsigned char *inp, size_t len)
+{
+    EVP_CHACHA_KEY *key = data(ctx);
+    unsigned int n, rem, ctr32;
+
+    if ((n = key->partial_len)) {
+        while (len && n < CHACHA_BLK_SIZE) {
+            *out++ = *inp++ ^ key->buf[n++];
+            len--;
+        }
+        key->partial_len = n;
+
+        if (len == 0)
+            return 1;
+
+        if (n == CHACHA_BLK_SIZE) {
+            key->partial_len = 0;
+            key->counter[0]++;
+            if (key->counter[0] == 0)
+                key->counter[1]++;
+        }
+    }
+
+    rem = (unsigned int)(len % CHACHA_BLK_SIZE);
+    len -= rem;
+    ctr32 = key->counter[0];
+    while (len >= CHACHA_BLK_SIZE) {
+        size_t blocks = len / CHACHA_BLK_SIZE;
+        /*
+         * 1<<28 is just a not-so-small yet not-so-large number...
+         * Below condition is practically never met, but it has to
+         * be checked for code correctness.
+         */
+        if (sizeof(size_t)>sizeof(unsigned int) && blocks>(1U<<28))
+            blocks = (1U<<28);
+
+        /*
+         * As ChaCha20_ctr32 operates on 32-bit counter, caller
+         * has to handle overflow. 'if' below detects the
+         * overflow, which is then handled by limiting the
+         * amount of blocks to the exact overflow point...
+         */
+        ctr32 += (unsigned int)blocks;
+        if (ctr32 < blocks) {
+            blocks -= ctr32;
+            ctr32 = 0;
+        }
+        blocks *= CHACHA_BLK_SIZE;
+        ChaCha20_ctr32(out, inp, blocks, key->key.d, key->counter);
+        len -= blocks;
+        inp += blocks;
+        out += blocks;
+
+        key->counter[0] = ctr32;
+        if (ctr32 == 0) key->counter[1]++;
+    }
+
+    if (rem) {
+        memset(key->buf, 0, sizeof(key->buf));
+        ChaCha20_ctr32(key->buf, key->buf, CHACHA_BLK_SIZE,
+                       key->key.d, key->counter);
+        for (n = 0; n < rem; n++)
+            out[n] = inp[n] ^ key->buf[n];
+        key->partial_len = rem;
+    }
+
+    return 1;
+}
+
+static const EVP_CIPHER chacha20 = {
+    NID_chacha20,
+    1,                      /* block_size */
+    CHACHA_KEY_SIZE,        /* key_len */
+    CHACHA_CTR_SIZE,        /* iv_len, 128-bit counter in the context */
+    EVP_CIPH_CUSTOM_IV | EVP_CIPH_ALWAYS_CALL_INIT,
+    chacha_init_key,
+    chacha_cipher,
+    NULL,
+    sizeof(EVP_CHACHA_KEY),
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
+
+const EVP_CIPHER *EVP_chacha20(void)
+{
+    return (&chacha20);
+}
+
+# ifndef OPENSSL_NO_POLY1305
+#  include "internal/poly1305.h"
+
+typedef struct {
+    EVP_CHACHA_KEY key;
+    unsigned int nonce[12/4];
+    unsigned char tag[POLY1305_BLOCK_SIZE];
+    struct { uint64_t aad, text; } len;
+    int aad, mac_inited, tag_len, nonce_len;
+    size_t tls_payload_length;
+} EVP_CHACHA_AEAD_CTX;
+
+#  define NO_TLS_PAYLOAD_LENGTH ((size_t)-1)
+#  define aead_data(ctx)        ((EVP_CHACHA_AEAD_CTX *)(ctx)->cipher_data)
+#  define POLY1305_ctx(actx)    ((POLY1305 *)(actx + 1))
+
+static int chacha20_poly1305_init_key(EVP_CIPHER_CTX *ctx,
+                                      const unsigned char *inkey,
+                                      const unsigned char *iv, int enc)
+{
+    EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
+
+    if (!inkey && !iv)
+        return 1;
+
+    actx->len.aad = 0;
+    actx->len.text = 0;
+    actx->aad = 0;
+    actx->mac_inited = 0;
+    actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH;
+
+    if (iv != NULL) {
+        unsigned char temp[CHACHA_CTR_SIZE] = { 0 };
+
+        /* pad on the left */
+        if (actx->nonce_len <= CHACHA_CTR_SIZE)
+            memcpy(temp + CHACHA_CTR_SIZE - actx->nonce_len, iv, actx->nonce_len);
+
+        chacha_init_key(ctx, inkey, temp, enc);
+
+        actx->nonce[0] = actx->key.counter[1];
+        actx->nonce[1] = actx->key.counter[2];
+        actx->nonce[2] = actx->key.counter[3];
+    } else {
+        chacha_init_key(ctx, inkey, NULL, enc);
+    }
+
+    return 1;
+}
+
+static int chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                                    const unsigned char *in, size_t len)
+{
+    EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
+    size_t rem, plen = actx->tls_payload_length;
+    static const unsigned char zero[POLY1305_BLOCK_SIZE] = { 0 };
+
+    if (!actx->mac_inited) {
+        actx->key.counter[0] = 0;
+        memset(actx->key.buf, 0, sizeof(actx->key.buf));
+        ChaCha20_ctr32(actx->key.buf, actx->key.buf, CHACHA_BLK_SIZE,
+                       actx->key.key.d, actx->key.counter);
+        Poly1305_Init(POLY1305_ctx(actx), actx->key.buf);
+        actx->key.counter[0] = 1;
+        actx->key.partial_len = 0;
+        actx->len.aad = actx->len.text = 0;
+        actx->mac_inited = 1;
+    }
+
+    if (in) {                                   /* aad or text */
+        if (out == NULL) {                      /* aad */
+            Poly1305_Update(POLY1305_ctx(actx), in, len);
+            actx->len.aad += len;
+            actx->aad = 1;
+            return len;
+        } else {                                /* plain- or ciphertext */
+            if (actx->aad) {                    /* wrap up aad */
+                if ((rem = (size_t)actx->len.aad % POLY1305_BLOCK_SIZE))
+                    Poly1305_Update(POLY1305_ctx(actx), zero,
+                                    POLY1305_BLOCK_SIZE - rem);
+                actx->aad = 0;
+            }
+
+            actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH;
+            if (plen == NO_TLS_PAYLOAD_LENGTH)
+                plen = len;
+            else if (len != plen + POLY1305_BLOCK_SIZE)
+                return -1;
+
+            if (ctx->encrypt) {                 /* plaintext */
+                chacha_cipher(ctx, out, in, plen);
+                Poly1305_Update(POLY1305_ctx(actx), out, plen);
+                in += plen;
+                out += plen;
+                actx->len.text += plen;
+            } else {                            /* ciphertext */
+                Poly1305_Update(POLY1305_ctx(actx), in, plen);
+                chacha_cipher(ctx, out, in, plen);
+                in += plen;
+                out += plen;
+                actx->len.text += plen;
+            }
+        }
+    }
+    if (in == NULL                              /* explicit final */
+        || plen != len) {                       /* or tls mode */
+        const union {
+            long one;
+            char little;
+        } is_endian = { 1 };
+        unsigned char temp[POLY1305_BLOCK_SIZE];
+
+        if (actx->aad) {                        /* wrap up aad */
+            if ((rem = (size_t)actx->len.aad % POLY1305_BLOCK_SIZE))
+                Poly1305_Update(POLY1305_ctx(actx), zero,
+                                POLY1305_BLOCK_SIZE - rem);
+            actx->aad = 0;
+        }
+
+        if ((rem = (size_t)actx->len.text % POLY1305_BLOCK_SIZE))
+            Poly1305_Update(POLY1305_ctx(actx), zero,
+                            POLY1305_BLOCK_SIZE - rem);
+
+        if (is_endian.little) {
+            Poly1305_Update(POLY1305_ctx(actx),
+                            (unsigned char *)&actx->len, POLY1305_BLOCK_SIZE);
+        } else {
+            temp[0]  = (unsigned char)(actx->len.aad);
+            temp[1]  = (unsigned char)(actx->len.aad>>8);
+            temp[2]  = (unsigned char)(actx->len.aad>>16);
+            temp[3]  = (unsigned char)(actx->len.aad>>24);
+            temp[4]  = (unsigned char)(actx->len.aad>>32);
+            temp[5]  = (unsigned char)(actx->len.aad>>40);
+            temp[6]  = (unsigned char)(actx->len.aad>>48);
+            temp[7]  = (unsigned char)(actx->len.aad>>56);
+
+            temp[8]  = (unsigned char)(actx->len.text);
+            temp[9]  = (unsigned char)(actx->len.text>>8);
+            temp[10] = (unsigned char)(actx->len.text>>16);
+            temp[11] = (unsigned char)(actx->len.text>>24);
+            temp[12] = (unsigned char)(actx->len.text>>32);
+            temp[13] = (unsigned char)(actx->len.text>>40);
+            temp[14] = (unsigned char)(actx->len.text>>48);
+            temp[15] = (unsigned char)(actx->len.text>>56);
+
+            Poly1305_Update(POLY1305_ctx(actx), temp, POLY1305_BLOCK_SIZE);
+        }
+        Poly1305_Final(POLY1305_ctx(actx), ctx->encrypt ? actx->tag
+                                                        : temp);
+        actx->mac_inited = 0;
+
+        if (in != NULL && len != plen) {        /* tls mode */
+            if (ctx->encrypt) {
+                memcpy(out, actx->tag, POLY1305_BLOCK_SIZE);
+            } else {
+                if (CRYPTO_memcmp(temp, in, POLY1305_BLOCK_SIZE)) {
+                    memset(out - plen, 0, plen);
+                    return -1;
+                }
+            }
+        }
+        else if (!ctx->encrypt) {
+            if (CRYPTO_memcmp(temp, actx->tag, actx->tag_len))
+                return -1;
+        }
+    }
+    return len;
+}
+
+static int chacha20_poly1305_cleanup(EVP_CIPHER_CTX *ctx)
+{
+    EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
+    if (actx)
+        OPENSSL_cleanse(ctx->cipher_data, sizeof(*actx) + Poly1305_ctx_size());
+    return 1;
+}
+
+static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
+                                  void *ptr)
+{
+    EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
+
+    switch(type) {
+    case EVP_CTRL_INIT:
+        if (actx == NULL)
+            actx = ctx->cipher_data
+                 = OPENSSL_zalloc(sizeof(*actx) + Poly1305_ctx_size());
+        if (actx == NULL) {
+            EVPerr(EVP_F_CHACHA20_POLY1305_CTRL, EVP_R_INITIALIZATION_ERROR);
+            return 0;
+        }
+        actx->len.aad = 0;
+        actx->len.text = 0;
+        actx->aad = 0;
+        actx->mac_inited = 0;
+        actx->tag_len = 0;
+        actx->nonce_len = 12;
+        actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH;
+        return 1;
+
+    case EVP_CTRL_COPY:
+        if (actx) {
+            EVP_CIPHER_CTX *dst = (EVP_CIPHER_CTX *)ptr;
+
+            dst->cipher_data =
+                   OPENSSL_memdup(actx, sizeof(*actx) + Poly1305_ctx_size());
+            if (dst->cipher_data == NULL) {
+                EVPerr(EVP_F_CHACHA20_POLY1305_CTRL, EVP_R_COPY_ERROR);
+                return 0;
+            }
+        }
+        return 1;
+
+    case EVP_CTRL_AEAD_SET_IVLEN:
+        if (arg <= 0 || arg > CHACHA_CTR_SIZE)
+            return 0;
+        actx->nonce_len = arg;
+        return 1;
+
+    case EVP_CTRL_AEAD_SET_IV_FIXED:
+        if (arg != 12)
+            return 0;
+        actx->nonce[0] = actx->key.counter[1]
+                       = CHACHA_U8TOU32((unsigned char *)ptr);
+        actx->nonce[1] = actx->key.counter[2]
+                       = CHACHA_U8TOU32((unsigned char *)ptr+4);
+        actx->nonce[2] = actx->key.counter[3]
+                       = CHACHA_U8TOU32((unsigned char *)ptr+8);
+        return 1;
+
+    case EVP_CTRL_AEAD_SET_TAG:
+        if (arg <= 0 || arg > POLY1305_BLOCK_SIZE)
+            return 0;
+        if (ptr != NULL) {
+            memcpy(actx->tag, ptr, arg);
+            actx->tag_len = arg;
+        }
+        return 1;
+
+    case EVP_CTRL_AEAD_GET_TAG:
+        if (arg <= 0 || arg > POLY1305_BLOCK_SIZE || !ctx->encrypt)
+            return 0;
+        memcpy(ptr, actx->tag, arg);
+        return 1;
+
+    case EVP_CTRL_AEAD_TLS1_AAD:
+        if (arg != EVP_AEAD_TLS1_AAD_LEN)
+            return 0;
+        {
+            unsigned int len;
+            unsigned char *aad = ptr, temp[POLY1305_BLOCK_SIZE];
+
+            len = aad[EVP_AEAD_TLS1_AAD_LEN - 2] << 8 |
+                  aad[EVP_AEAD_TLS1_AAD_LEN - 1];
+            if (!ctx->encrypt) {
+                if (len < POLY1305_BLOCK_SIZE)
+                    return 0;
+                len -= POLY1305_BLOCK_SIZE;     /* discount attached tag */
+                memcpy(temp, aad, EVP_AEAD_TLS1_AAD_LEN - 2);
+                aad = temp;
+                temp[EVP_AEAD_TLS1_AAD_LEN - 2] = (unsigned char)(len >> 8);
+                temp[EVP_AEAD_TLS1_AAD_LEN - 1] = (unsigned char)len;
+            }
+            actx->tls_payload_length = len;
+
+            /*
+             * merge record sequence number as per RFC7905
+             */
+            actx->key.counter[1] = actx->nonce[0];
+            actx->key.counter[2] = actx->nonce[1] ^ CHACHA_U8TOU32(aad);
+            actx->key.counter[3] = actx->nonce[2] ^ CHACHA_U8TOU32(aad+4);
+            actx->mac_inited = 0;
+            chacha20_poly1305_cipher(ctx, NULL, aad, EVP_AEAD_TLS1_AAD_LEN);
+            return POLY1305_BLOCK_SIZE;         /* tag length */
+        }
+
+    case EVP_CTRL_AEAD_SET_MAC_KEY:
+        /* no-op */
+        return 1;
+
+    default:
+        return -1;
+    }
+}
+
+static EVP_CIPHER chacha20_poly1305 = {
+    NID_chacha20_poly1305,
+    1,                  /* block_size */
+    CHACHA_KEY_SIZE,    /* key_len */
+    12,                 /* iv_len, 96-bit nonce in the context */
+    EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_CUSTOM_IV |
+    EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT |
+    EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_CUSTOM_CIPHER,
+    chacha20_poly1305_init_key,
+    chacha20_poly1305_cipher,
+    chacha20_poly1305_cleanup,
+    0,          /* 0 moves context-specific structure allocation to ctrl */
+    NULL,       /* set_asn1_parameters */
+    NULL,       /* get_asn1_parameters */
+    chacha20_poly1305_ctrl,
+    NULL        /* app_data */
+};
+
+const EVP_CIPHER *EVP_chacha20_poly1305(void)
+{
+    return(&chacha20_poly1305);
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_des.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_des.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_des.c	(revision 331)
@@ -0,0 +1,242 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#ifndef OPENSSL_NO_DES
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "internal/evp_int.h"
+# include <openssl/des.h>
+# include <openssl/rand.h>
+
+typedef struct {
+    union {
+        double align;
+        DES_key_schedule ks;
+    } ks;
+    union {
+        void (*cbc) (const void *, void *, size_t,
+                     const DES_key_schedule *, unsigned char *);
+    } stream;
+} EVP_DES_KEY;
+
+# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
+/* ----------^^^ this is not a typo, just a way to detect that
+ * assembler support was in general requested... */
+#  include "sparc_arch.h"
+
+extern unsigned int OPENSSL_sparcv9cap_P[];
+
+#  define SPARC_DES_CAPABLE       (OPENSSL_sparcv9cap_P[1] & CFR_DES)
+
+void des_t4_key_expand(const void *key, DES_key_schedule *ks);
+void des_t4_cbc_encrypt(const void *inp, void *out, size_t len,
+                        const DES_key_schedule *ks, unsigned char iv[8]);
+void des_t4_cbc_decrypt(const void *inp, void *out, size_t len,
+                        const DES_key_schedule *ks, unsigned char iv[8]);
+# endif
+
+static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                        const unsigned char *iv, int enc);
+static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
+
+/*
+ * Because of various casts and different names can't use
+ * IMPLEMENT_BLOCK_CIPHER
+ */
+
+static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                          const unsigned char *in, size_t inl)
+{
+    BLOCK_CIPHER_ecb_loop()
+        DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i),
+                        EVP_CIPHER_CTX_get_cipher_data(ctx),
+                        EVP_CIPHER_CTX_encrypting(ctx));
+    return 1;
+}
+
+static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                          const unsigned char *in, size_t inl)
+{
+    while (inl >= EVP_MAXCHUNK) {
+        int num = EVP_CIPHER_CTX_num(ctx);
+        DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK,
+                          EVP_CIPHER_CTX_get_cipher_data(ctx),
+                          (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num);
+        EVP_CIPHER_CTX_set_num(ctx, num);
+        inl -= EVP_MAXCHUNK;
+        in += EVP_MAXCHUNK;
+        out += EVP_MAXCHUNK;
+    }
+    if (inl) {
+        int num = EVP_CIPHER_CTX_num(ctx);
+        DES_ofb64_encrypt(in, out, (long)inl,
+                          EVP_CIPHER_CTX_get_cipher_data(ctx),
+                          (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num);
+        EVP_CIPHER_CTX_set_num(ctx, num);
+    }
+    return 1;
+}
+
+static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                          const unsigned char *in, size_t inl)
+{
+    EVP_DES_KEY *dat = (EVP_DES_KEY *) EVP_CIPHER_CTX_get_cipher_data(ctx);
+
+    if (dat->stream.cbc != NULL) {
+        (*dat->stream.cbc) (in, out, inl, &dat->ks.ks,
+                            EVP_CIPHER_CTX_iv_noconst(ctx));
+        return 1;
+    }
+    while (inl >= EVP_MAXCHUNK) {
+        DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK,
+                         EVP_CIPHER_CTX_get_cipher_data(ctx),
+                         (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
+                         EVP_CIPHER_CTX_encrypting(ctx));
+        inl -= EVP_MAXCHUNK;
+        in += EVP_MAXCHUNK;
+        out += EVP_MAXCHUNK;
+    }
+    if (inl)
+        DES_ncbc_encrypt(in, out, (long)inl,
+                         EVP_CIPHER_CTX_get_cipher_data(ctx),
+                         (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
+                         EVP_CIPHER_CTX_encrypting(ctx));
+    return 1;
+}
+
+static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                            const unsigned char *in, size_t inl)
+{
+    while (inl >= EVP_MAXCHUNK) {
+        int num = EVP_CIPHER_CTX_num(ctx);
+        DES_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK,
+                          EVP_CIPHER_CTX_get_cipher_data(ctx),
+                          (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num,
+                          EVP_CIPHER_CTX_encrypting(ctx));
+        EVP_CIPHER_CTX_set_num(ctx, num);
+        inl -= EVP_MAXCHUNK;
+        in += EVP_MAXCHUNK;
+        out += EVP_MAXCHUNK;
+    }
+    if (inl) {
+        int num = EVP_CIPHER_CTX_num(ctx);
+        DES_cfb64_encrypt(in, out, (long)inl,
+                          EVP_CIPHER_CTX_get_cipher_data(ctx),
+                          (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx), &num,
+                          EVP_CIPHER_CTX_encrypting(ctx));
+        EVP_CIPHER_CTX_set_num(ctx, num);
+    }
+    return 1;
+}
+
+/*
+ * Although we have a CFB-r implementation for DES, it doesn't pack the right
+ * way, so wrap it here
+ */
+static int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                           const unsigned char *in, size_t inl)
+{
+    size_t n, chunk = EVP_MAXCHUNK / 8;
+    unsigned char c[1], d[1];
+
+    if (inl < chunk)
+        chunk = inl;
+
+    while (inl && inl >= chunk) {
+        for (n = 0; n < chunk * 8; ++n) {
+            c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
+            DES_cfb_encrypt(c, d, 1, 1, EVP_CIPHER_CTX_get_cipher_data(ctx),
+                            (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
+                            EVP_CIPHER_CTX_encrypting(ctx));
+            out[n / 8] =
+                (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) |
+                ((d[0] & 0x80) >> (unsigned int)(n % 8));
+        }
+        inl -= chunk;
+        in += chunk;
+        out += chunk;
+        if (inl < chunk)
+            chunk = inl;
+    }
+
+    return 1;
+}
+
+static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                           const unsigned char *in, size_t inl)
+{
+    while (inl >= EVP_MAXCHUNK) {
+        DES_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK,
+                        EVP_CIPHER_CTX_get_cipher_data(ctx),
+                        (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
+                        EVP_CIPHER_CTX_encrypting(ctx));
+        inl -= EVP_MAXCHUNK;
+        in += EVP_MAXCHUNK;
+        out += EVP_MAXCHUNK;
+    }
+    if (inl)
+        DES_cfb_encrypt(in, out, 8, (long)inl,
+                        EVP_CIPHER_CTX_get_cipher_data(ctx),
+                        (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
+                        EVP_CIPHER_CTX_encrypting(ctx));
+    return 1;
+}
+
+BLOCK_CIPHER_defs(des, EVP_DES_KEY, NID_des, 8, 8, 8, 64,
+                  EVP_CIPH_RAND_KEY, des_init_key, NULL,
+                  EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl)
+
+    BLOCK_CIPHER_def_cfb(des, EVP_DES_KEY, NID_des, 8, 8, 1,
+                     EVP_CIPH_RAND_KEY, des_init_key, NULL,
+                     EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl)
+
+    BLOCK_CIPHER_def_cfb(des, EVP_DES_KEY, NID_des, 8, 8, 8,
+                     EVP_CIPH_RAND_KEY, des_init_key, NULL,
+                     EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl)
+
+static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                        const unsigned char *iv, int enc)
+{
+    DES_cblock *deskey = (DES_cblock *)key;
+    EVP_DES_KEY *dat = (EVP_DES_KEY *) EVP_CIPHER_CTX_get_cipher_data(ctx);
+
+    dat->stream.cbc = NULL;
+# if defined(SPARC_DES_CAPABLE)
+    if (SPARC_DES_CAPABLE) {
+        int mode = EVP_CIPHER_CTX_mode(ctx);
+
+        if (mode == EVP_CIPH_CBC_MODE) {
+            des_t4_key_expand(key, &dat->ks.ks);
+            dat->stream.cbc = enc ? des_t4_cbc_encrypt : des_t4_cbc_decrypt;
+            return 1;
+        }
+    }
+# endif
+    DES_set_key_unchecked(deskey, EVP_CIPHER_CTX_get_cipher_data(ctx));
+    return 1;
+}
+
+static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+
+    switch (type) {
+    case EVP_CTRL_RAND_KEY:
+        if (RAND_bytes(ptr, 8) <= 0)
+            return 0;
+        DES_set_odd_parity((DES_cblock *)ptr);
+        return 1;
+
+    default:
+        return -1;
+    }
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_des3.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_des3.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_des3.c	(revision 331)
@@ -0,0 +1,424 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#ifndef OPENSSL_NO_DES
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "internal/evp_int.h"
+# include <openssl/des.h>
+# include <openssl/rand.h>
+# include "evp_locl.h"
+
+typedef struct {
+    union {
+        double align;
+        DES_key_schedule ks[3];
+    } ks;
+    union {
+        void (*cbc) (const void *, void *, size_t,
+                     const DES_key_schedule *, unsigned char *);
+    } stream;
+} DES_EDE_KEY;
+# define ks1 ks.ks[0]
+# define ks2 ks.ks[1]
+# define ks3 ks.ks[2]
+
+# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
+/* ---------^^^ this is not a typo, just a way to detect that
+ * assembler support was in general requested... */
+#  include "sparc_arch.h"
+
+extern unsigned int OPENSSL_sparcv9cap_P[];
+
+#  define SPARC_DES_CAPABLE       (OPENSSL_sparcv9cap_P[1] & CFR_DES)
+
+void des_t4_key_expand(const void *key, DES_key_schedule *ks);
+void des_t4_ede3_cbc_encrypt(const void *inp, void *out, size_t len,
+                             const DES_key_schedule ks[3], unsigned char iv[8]);
+void des_t4_ede3_cbc_decrypt(const void *inp, void *out, size_t len,
+                             const DES_key_schedule ks[3], unsigned char iv[8]);
+# endif
+
+static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                            const unsigned char *iv, int enc);
+
+static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                             const unsigned char *iv, int enc);
+
+static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
+
+# define data(ctx) EVP_C_DATA(DES_EDE_KEY,ctx)
+
+/*
+ * Because of various casts and different args can't use
+ * IMPLEMENT_BLOCK_CIPHER
+ */
+
+static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                              const unsigned char *in, size_t inl)
+{
+    BLOCK_CIPHER_ecb_loop()
+        DES_ecb3_encrypt((const_DES_cblock *)(in + i),
+                         (DES_cblock *)(out + i),
+                         &data(ctx)->ks1, &data(ctx)->ks2,
+                         &data(ctx)->ks3, EVP_CIPHER_CTX_encrypting(ctx));
+    return 1;
+}
+
+static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                              const unsigned char *in, size_t inl)
+{
+    while (inl >= EVP_MAXCHUNK) {
+        int num = EVP_CIPHER_CTX_num(ctx);
+        DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK,
+                               &data(ctx)->ks1, &data(ctx)->ks2,
+                               &data(ctx)->ks3,
+                               (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
+                               &num);
+        EVP_CIPHER_CTX_set_num(ctx, num);
+        inl -= EVP_MAXCHUNK;
+        in += EVP_MAXCHUNK;
+        out += EVP_MAXCHUNK;
+    }
+    if (inl) {
+        int num = EVP_CIPHER_CTX_num(ctx);
+        DES_ede3_ofb64_encrypt(in, out, (long)inl,
+                               &data(ctx)->ks1, &data(ctx)->ks2,
+                               &data(ctx)->ks3,
+                               (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
+                               &num);
+        EVP_CIPHER_CTX_set_num(ctx, num);
+    }
+    return 1;
+}
+
+static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                              const unsigned char *in, size_t inl)
+{
+    DES_EDE_KEY *dat = data(ctx);
+
+    if (dat->stream.cbc != NULL) {
+        (*dat->stream.cbc) (in, out, inl, dat->ks.ks,
+                            EVP_CIPHER_CTX_iv_noconst(ctx));
+        return 1;
+    }
+
+    while (inl >= EVP_MAXCHUNK) {
+        DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK,
+                             &dat->ks1, &dat->ks2, &dat->ks3,
+                             (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
+                             EVP_CIPHER_CTX_encrypting(ctx));
+        inl -= EVP_MAXCHUNK;
+        in += EVP_MAXCHUNK;
+        out += EVP_MAXCHUNK;
+    }
+    if (inl)
+        DES_ede3_cbc_encrypt(in, out, (long)inl,
+                             &dat->ks1, &dat->ks2, &dat->ks3,
+                             (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
+                             EVP_CIPHER_CTX_encrypting(ctx));
+    return 1;
+}
+
+static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                                const unsigned char *in, size_t inl)
+{
+    while (inl >= EVP_MAXCHUNK) {
+        int num = EVP_CIPHER_CTX_num(ctx);
+        DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK,
+                               &data(ctx)->ks1, &data(ctx)->ks2,
+                               &data(ctx)->ks3,
+                               (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
+                               &num, EVP_CIPHER_CTX_encrypting(ctx));
+        EVP_CIPHER_CTX_set_num(ctx, num);
+        inl -= EVP_MAXCHUNK;
+        in += EVP_MAXCHUNK;
+        out += EVP_MAXCHUNK;
+    }
+    if (inl) {
+        int num = EVP_CIPHER_CTX_num(ctx);
+        DES_ede3_cfb64_encrypt(in, out, (long)inl,
+                               &data(ctx)->ks1, &data(ctx)->ks2,
+                               &data(ctx)->ks3,
+                               (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
+                               &num, EVP_CIPHER_CTX_encrypting(ctx));
+        EVP_CIPHER_CTX_set_num(ctx, num);
+    }
+    return 1;
+}
+
+/*
+ * Although we have a CFB-r implementation for 3-DES, it doesn't pack the
+ * right way, so wrap it here
+ */
+static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                                const unsigned char *in, size_t inl)
+{
+    size_t n;
+    unsigned char c[1], d[1];
+
+    if (!EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS))
+            inl *= 8;
+    for (n = 0; n < inl; ++n) {
+        c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
+        DES_ede3_cfb_encrypt(c, d, 1, 1,
+                             &data(ctx)->ks1, &data(ctx)->ks2,
+                             &data(ctx)->ks3,
+                             (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
+                             EVP_CIPHER_CTX_encrypting(ctx));
+        out[n / 8] = (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8)))
+            | ((d[0] & 0x80) >> (unsigned int)(n % 8));
+    }
+
+    return 1;
+}
+
+static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                                const unsigned char *in, size_t inl)
+{
+    while (inl >= EVP_MAXCHUNK) {
+        DES_ede3_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK,
+                             &data(ctx)->ks1, &data(ctx)->ks2,
+                             &data(ctx)->ks3,
+                             (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
+                             EVP_CIPHER_CTX_encrypting(ctx));
+        inl -= EVP_MAXCHUNK;
+        in += EVP_MAXCHUNK;
+        out += EVP_MAXCHUNK;
+    }
+    if (inl)
+        DES_ede3_cfb_encrypt(in, out, 8, (long)inl,
+                             &data(ctx)->ks1, &data(ctx)->ks2,
+                             &data(ctx)->ks3,
+                             (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
+                             EVP_CIPHER_CTX_encrypting(ctx));
+    return 1;
+}
+
+BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64,
+                  EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_DEFAULT_ASN1,
+                  des_ede_init_key, NULL, NULL, NULL, des3_ctrl)
+# define des_ede3_cfb64_cipher des_ede_cfb64_cipher
+# define des_ede3_ofb_cipher des_ede_ofb_cipher
+# define des_ede3_cbc_cipher des_ede_cbc_cipher
+# define des_ede3_ecb_cipher des_ede_ecb_cipher
+    BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64,
+                  EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_DEFAULT_ASN1,
+                  des_ede3_init_key, NULL, NULL, NULL, des3_ctrl)
+
+    BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 1,
+                     EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_DEFAULT_ASN1,
+                     des_ede3_init_key, NULL, NULL, NULL, des3_ctrl)
+
+    BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 8,
+                     EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_DEFAULT_ASN1,
+                     des_ede3_init_key, NULL, NULL, NULL, des3_ctrl)
+
+static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                            const unsigned char *iv, int enc)
+{
+    DES_cblock *deskey = (DES_cblock *)key;
+    DES_EDE_KEY *dat = data(ctx);
+
+    dat->stream.cbc = NULL;
+# if defined(SPARC_DES_CAPABLE)
+    if (SPARC_DES_CAPABLE) {
+        int mode = EVP_CIPHER_CTX_mode(ctx);
+
+        if (mode == EVP_CIPH_CBC_MODE) {
+            des_t4_key_expand(&deskey[0], &dat->ks1);
+            des_t4_key_expand(&deskey[1], &dat->ks2);
+            memcpy(&dat->ks3, &dat->ks1, sizeof(dat->ks1));
+            dat->stream.cbc = enc ? des_t4_ede3_cbc_encrypt :
+                des_t4_ede3_cbc_decrypt;
+            return 1;
+        }
+    }
+# endif
+    DES_set_key_unchecked(&deskey[0], &dat->ks1);
+    DES_set_key_unchecked(&deskey[1], &dat->ks2);
+    memcpy(&dat->ks3, &dat->ks1, sizeof(dat->ks1));
+    return 1;
+}
+
+static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                             const unsigned char *iv, int enc)
+{
+    DES_cblock *deskey = (DES_cblock *)key;
+    DES_EDE_KEY *dat = data(ctx);
+
+    dat->stream.cbc = NULL;
+# if defined(SPARC_DES_CAPABLE)
+    if (SPARC_DES_CAPABLE) {
+        int mode = EVP_CIPHER_CTX_mode(ctx);
+
+        if (mode == EVP_CIPH_CBC_MODE) {
+            des_t4_key_expand(&deskey[0], &dat->ks1);
+            des_t4_key_expand(&deskey[1], &dat->ks2);
+            des_t4_key_expand(&deskey[2], &dat->ks3);
+            dat->stream.cbc = enc ? des_t4_ede3_cbc_encrypt :
+                des_t4_ede3_cbc_decrypt;
+            return 1;
+        }
+    }
+# endif
+    DES_set_key_unchecked(&deskey[0], &dat->ks1);
+    DES_set_key_unchecked(&deskey[1], &dat->ks2);
+    DES_set_key_unchecked(&deskey[2], &dat->ks3);
+    return 1;
+}
+
+static int des3_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+
+    DES_cblock *deskey = ptr;
+
+    switch (type) {
+    case EVP_CTRL_RAND_KEY:
+        if (RAND_bytes(ptr, EVP_CIPHER_CTX_key_length(ctx)) <= 0)
+            return 0;
+        DES_set_odd_parity(deskey);
+        if (EVP_CIPHER_CTX_key_length(ctx) >= 16)
+            DES_set_odd_parity(deskey + 1);
+        if (EVP_CIPHER_CTX_key_length(ctx) >= 24)
+            DES_set_odd_parity(deskey + 2);
+        return 1;
+
+    default:
+        return -1;
+    }
+}
+
+const EVP_CIPHER *EVP_des_ede(void)
+{
+    return &des_ede_ecb;
+}
+
+const EVP_CIPHER *EVP_des_ede3(void)
+{
+    return &des_ede3_ecb;
+}
+
+
+# include <openssl/sha.h>
+
+static const unsigned char wrap_iv[8] =
+    { 0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05 };
+
+static int des_ede3_unwrap(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                           const unsigned char *in, size_t inl)
+{
+    unsigned char icv[8], iv[8], sha1tmp[SHA_DIGEST_LENGTH];
+    int rv = -1;
+    if (inl < 24)
+        return -1;
+    if (out == NULL)
+        return inl - 16;
+    memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), wrap_iv, 8);
+    /* Decrypt first block which will end up as icv */
+    des_ede_cbc_cipher(ctx, icv, in, 8);
+    /* Decrypt central blocks */
+    /*
+     * If decrypting in place move whole output along a block so the next
+     * des_ede_cbc_cipher is in place.
+     */
+    if (out == in) {
+        memmove(out, out + 8, inl - 8);
+        in -= 8;
+    }
+    des_ede_cbc_cipher(ctx, out, in + 8, inl - 16);
+    /* Decrypt final block which will be IV */
+    des_ede_cbc_cipher(ctx, iv, in + inl - 8, 8);
+    /* Reverse order of everything */
+    BUF_reverse(icv, NULL, 8);
+    BUF_reverse(out, NULL, inl - 16);
+    BUF_reverse(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 8);
+    /* Decrypt again using new IV */
+    des_ede_cbc_cipher(ctx, out, out, inl - 16);
+    des_ede_cbc_cipher(ctx, icv, icv, 8);
+    /* Work out SHA1 hash of first portion */
+    SHA1(out, inl - 16, sha1tmp);
+
+    if (!CRYPTO_memcmp(sha1tmp, icv, 8))
+        rv = inl - 16;
+    OPENSSL_cleanse(icv, 8);
+    OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH);
+    OPENSSL_cleanse(iv, 8);
+    OPENSSL_cleanse(EVP_CIPHER_CTX_iv_noconst(ctx), 8);
+    if (rv == -1)
+        OPENSSL_cleanse(out, inl - 16);
+
+    return rv;
+}
+
+static int des_ede3_wrap(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                         const unsigned char *in, size_t inl)
+{
+    unsigned char sha1tmp[SHA_DIGEST_LENGTH];
+    if (out == NULL)
+        return inl + 16;
+    /* Copy input to output buffer + 8 so we have space for IV */
+    memmove(out + 8, in, inl);
+    /* Work out ICV */
+    SHA1(in, inl, sha1tmp);
+    memcpy(out + inl + 8, sha1tmp, 8);
+    OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH);
+    /* Generate random IV */
+    if (RAND_bytes(EVP_CIPHER_CTX_iv_noconst(ctx), 8) <= 0)
+        return -1;
+    memcpy(out, EVP_CIPHER_CTX_iv_noconst(ctx), 8);
+    /* Encrypt everything after IV in place */
+    des_ede_cbc_cipher(ctx, out + 8, out + 8, inl + 8);
+    BUF_reverse(out, NULL, inl + 16);
+    memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), wrap_iv, 8);
+    des_ede_cbc_cipher(ctx, out, out, inl + 16);
+    return inl + 16;
+}
+
+static int des_ede3_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                                const unsigned char *in, size_t inl)
+{
+    /*
+     * Sanity check input length: we typically only wrap keys so EVP_MAXCHUNK
+     * is more than will ever be needed. Also input length must be a multiple
+     * of 8 bits.
+     */
+    if (inl >= EVP_MAXCHUNK || inl % 8)
+        return -1;
+
+    if (is_partially_overlapping(out, in, inl)) {
+        EVPerr(EVP_F_DES_EDE3_WRAP_CIPHER, EVP_R_PARTIALLY_OVERLAPPING);
+        return 0;
+    }
+
+    if (EVP_CIPHER_CTX_encrypting(ctx))
+        return des_ede3_wrap(ctx, out, in, inl);
+    else
+        return des_ede3_unwrap(ctx, out, in, inl);
+}
+
+static const EVP_CIPHER des3_wrap = {
+    NID_id_smime_alg_CMS3DESwrap,
+    8, 24, 0,
+    EVP_CIPH_WRAP_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER
+        | EVP_CIPH_FLAG_DEFAULT_ASN1,
+    des_ede3_init_key, des_ede3_wrap_cipher,
+    NULL,
+    sizeof(DES_EDE_KEY),
+    NULL, NULL, NULL, NULL
+};
+
+const EVP_CIPHER *EVP_des_ede3_wrap(void)
+{
+    return &des3_wrap;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_idea.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_idea.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_idea.c	(revision 331)
@@ -0,0 +1,70 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+
+#ifndef OPENSSL_NO_IDEA
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "internal/evp_int.h"
+# include <openssl/idea.h>
+
+/* Can't use IMPLEMENT_BLOCK_CIPHER because IDEA_ecb_encrypt is different */
+
+typedef struct {
+    IDEA_KEY_SCHEDULE ks;
+} EVP_IDEA_KEY;
+
+static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                         const unsigned char *iv, int enc);
+
+/*
+ * NB IDEA_ecb_encrypt doesn't take an 'encrypt' argument so we treat it as a
+ * special case
+ */
+
+static int idea_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                           const unsigned char *in, size_t inl)
+{
+    BLOCK_CIPHER_ecb_loop()
+        IDEA_ecb_encrypt(in + i, out + i, &EVP_C_DATA(EVP_IDEA_KEY,ctx)->ks);
+    return 1;
+}
+
+BLOCK_CIPHER_func_cbc(idea, IDEA, EVP_IDEA_KEY, ks)
+BLOCK_CIPHER_func_ofb(idea, IDEA, 64, EVP_IDEA_KEY, ks)
+BLOCK_CIPHER_func_cfb(idea, IDEA, 64, EVP_IDEA_KEY, ks)
+
+BLOCK_CIPHER_defs(idea, IDEA_KEY_SCHEDULE, NID_idea, 8, 16, 8, 64,
+                  0, idea_init_key, NULL,
+                  EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL)
+
+static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                         const unsigned char *iv, int enc)
+{
+    if (!enc) {
+        if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE)
+            enc = 1;
+        else if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE)
+            enc = 1;
+    }
+    if (enc)
+        IDEA_set_encrypt_key(key, &EVP_C_DATA(EVP_IDEA_KEY,ctx)->ks);
+    else {
+        IDEA_KEY_SCHEDULE tmp;
+
+        IDEA_set_encrypt_key(key, &tmp);
+        IDEA_set_decrypt_key(&tmp, &EVP_C_DATA(EVP_IDEA_KEY,ctx)->ks);
+        OPENSSL_cleanse((unsigned char *)&tmp, sizeof(IDEA_KEY_SCHEDULE));
+    }
+    return 1;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_null.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_null.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_null.c	(revision 331)
@@ -0,0 +1,50 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include "internal/evp_int.h"
+
+static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                         const unsigned char *iv, int enc);
+static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                       const unsigned char *in, size_t inl);
+static const EVP_CIPHER n_cipher = {
+    NID_undef,
+    1, 0, 0, 0,
+    null_init_key,
+    null_cipher,
+    NULL,
+    0,
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
+
+const EVP_CIPHER *EVP_enc_null(void)
+{
+    return (&n_cipher);
+}
+
+static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                         const unsigned char *iv, int enc)
+{
+    return 1;
+}
+
+static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                       const unsigned char *in, size_t inl)
+{
+    if (in != out)
+        memcpy(out, in, inl);
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_old.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_old.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_old.c	(revision 331)
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2004-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 <openssl/opensslconf.h>
+#if OPENSSL_API_COMPAT >= 0x00908000L
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <openssl/evp.h>
+
+/*
+ * Define some deprecated functions, so older programs don't crash and burn
+ * too quickly.  On Windows and VMS, these will never be used, since
+ * functions and variables in shared libraries are selected by entry point
+ * location, not by name.
+ */
+
+# ifndef OPENSSL_NO_BF
+#  undef EVP_bf_cfb
+const EVP_CIPHER *EVP_bf_cfb(void);
+const EVP_CIPHER *EVP_bf_cfb(void)
+{
+    return EVP_bf_cfb64();
+}
+# endif
+
+# ifndef OPENSSL_NO_DES
+#  undef EVP_des_cfb
+const EVP_CIPHER *EVP_des_cfb(void);
+const EVP_CIPHER *EVP_des_cfb(void)
+{
+    return EVP_des_cfb64();
+}
+
+#  undef EVP_des_ede3_cfb
+const EVP_CIPHER *EVP_des_ede3_cfb(void);
+const EVP_CIPHER *EVP_des_ede3_cfb(void)
+{
+    return EVP_des_ede3_cfb64();
+}
+
+#  undef EVP_des_ede_cfb
+const EVP_CIPHER *EVP_des_ede_cfb(void);
+const EVP_CIPHER *EVP_des_ede_cfb(void)
+{
+    return EVP_des_ede_cfb64();
+}
+# endif
+
+# ifndef OPENSSL_NO_IDEA
+#  undef EVP_idea_cfb
+const EVP_CIPHER *EVP_idea_cfb(void);
+const EVP_CIPHER *EVP_idea_cfb(void)
+{
+    return EVP_idea_cfb64();
+}
+# endif
+
+# ifndef OPENSSL_NO_RC2
+#  undef EVP_rc2_cfb
+const EVP_CIPHER *EVP_rc2_cfb(void);
+const EVP_CIPHER *EVP_rc2_cfb(void)
+{
+    return EVP_rc2_cfb64();
+}
+# endif
+
+# ifndef OPENSSL_NO_CAST
+#  undef EVP_cast5_cfb
+const EVP_CIPHER *EVP_cast5_cfb(void);
+const EVP_CIPHER *EVP_cast5_cfb(void)
+{
+    return EVP_cast5_cfb64();
+}
+# endif
+
+# ifndef OPENSSL_NO_RC5
+#  undef EVP_rc5_32_12_16_cfb
+const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void);
+const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void)
+{
+    return EVP_rc5_32_12_16_cfb64();
+}
+# endif
+
+# undef EVP_aes_128_cfb
+const EVP_CIPHER *EVP_aes_128_cfb(void);
+const EVP_CIPHER *EVP_aes_128_cfb(void)
+{
+    return EVP_aes_128_cfb128();
+}
+
+# undef EVP_aes_192_cfb
+const EVP_CIPHER *EVP_aes_192_cfb(void);
+const EVP_CIPHER *EVP_aes_192_cfb(void)
+{
+    return EVP_aes_192_cfb128();
+}
+
+# undef EVP_aes_256_cfb
+const EVP_CIPHER *EVP_aes_256_cfb(void);
+const EVP_CIPHER *EVP_aes_256_cfb(void)
+{
+    return EVP_aes_256_cfb128();
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_rc2.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_rc2.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_rc2.c	(revision 331)
@@ -0,0 +1,189 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+
+#ifndef OPENSSL_NO_RC2
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "internal/evp_int.h"
+# include <openssl/rc2.h>
+
+static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                        const unsigned char *iv, int enc);
+static int rc2_meth_to_magic(EVP_CIPHER_CTX *ctx);
+static int rc2_magic_to_meth(int i);
+static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
+
+typedef struct {
+    int key_bits;               /* effective key bits */
+    RC2_KEY ks;                 /* key schedule */
+} EVP_RC2_KEY;
+
+# define data(ctx)       EVP_C_DATA(EVP_RC2_KEY,ctx)
+
+IMPLEMENT_BLOCK_CIPHER(rc2, ks, RC2, EVP_RC2_KEY, NID_rc2,
+                       8,
+                       RC2_KEY_LENGTH, 8, 64,
+                       EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+                       rc2_init_key, NULL,
+                       rc2_set_asn1_type_and_iv, rc2_get_asn1_type_and_iv,
+                       rc2_ctrl)
+# define RC2_40_MAGIC    0xa0
+# define RC2_64_MAGIC    0x78
+# define RC2_128_MAGIC   0x3a
+static const EVP_CIPHER r2_64_cbc_cipher = {
+    NID_rc2_64_cbc,
+    8, 8 /* 64 bit */ , 8,
+    EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+    rc2_init_key,
+    rc2_cbc_cipher,
+    NULL,
+    sizeof(EVP_RC2_KEY),
+    rc2_set_asn1_type_and_iv,
+    rc2_get_asn1_type_and_iv,
+    rc2_ctrl,
+    NULL
+};
+
+static const EVP_CIPHER r2_40_cbc_cipher = {
+    NID_rc2_40_cbc,
+    8, 5 /* 40 bit */ , 8,
+    EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+    rc2_init_key,
+    rc2_cbc_cipher,
+    NULL,
+    sizeof(EVP_RC2_KEY),
+    rc2_set_asn1_type_and_iv,
+    rc2_get_asn1_type_and_iv,
+    rc2_ctrl,
+    NULL
+};
+
+const EVP_CIPHER *EVP_rc2_64_cbc(void)
+{
+    return (&r2_64_cbc_cipher);
+}
+
+const EVP_CIPHER *EVP_rc2_40_cbc(void)
+{
+    return (&r2_40_cbc_cipher);
+}
+
+static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                        const unsigned char *iv, int enc)
+{
+    RC2_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
+                key, data(ctx)->key_bits);
+    return 1;
+}
+
+static int rc2_meth_to_magic(EVP_CIPHER_CTX *e)
+{
+    int i;
+
+    EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i);
+    if (i == 128)
+        return (RC2_128_MAGIC);
+    else if (i == 64)
+        return (RC2_64_MAGIC);
+    else if (i == 40)
+        return (RC2_40_MAGIC);
+    else
+        return (0);
+}
+
+static int rc2_magic_to_meth(int i)
+{
+    if (i == RC2_128_MAGIC)
+        return 128;
+    else if (i == RC2_64_MAGIC)
+        return 64;
+    else if (i == RC2_40_MAGIC)
+        return 40;
+    else {
+        EVPerr(EVP_F_RC2_MAGIC_TO_METH, EVP_R_UNSUPPORTED_KEY_SIZE);
+        return (0);
+    }
+}
+
+static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+    long num = 0;
+    int i = 0;
+    int key_bits;
+    unsigned int l;
+    unsigned char iv[EVP_MAX_IV_LENGTH];
+
+    if (type != NULL) {
+        l = EVP_CIPHER_CTX_iv_length(c);
+        OPENSSL_assert(l <= sizeof(iv));
+        i = ASN1_TYPE_get_int_octetstring(type, &num, iv, l);
+        if (i != (int)l)
+            return -1;
+        key_bits = rc2_magic_to_meth((int)num);
+        if (!key_bits)
+            return -1;
+        if (i > 0 && !EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1))
+            return -1;
+        EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL);
+        if (EVP_CIPHER_CTX_set_key_length(c, key_bits / 8) <= 0)
+            return -1;
+    }
+    return i;
+}
+
+static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+    long num;
+    int i = 0, j;
+
+    if (type != NULL) {
+        num = rc2_meth_to_magic(c);
+        j = EVP_CIPHER_CTX_iv_length(c);
+        i = ASN1_TYPE_set_int_octetstring(type, num,
+                                          (unsigned char *)EVP_CIPHER_CTX_original_iv(c),
+                                          j);
+    }
+    return (i);
+}
+
+static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+    switch (type) {
+    case EVP_CTRL_INIT:
+        data(c)->key_bits = EVP_CIPHER_CTX_key_length(c) * 8;
+        return 1;
+
+    case EVP_CTRL_GET_RC2_KEY_BITS:
+        *(int *)ptr = data(c)->key_bits;
+        return 1;
+
+    case EVP_CTRL_SET_RC2_KEY_BITS:
+        if (arg > 0) {
+            data(c)->key_bits = arg;
+            return 1;
+        }
+        return 0;
+# ifdef PBE_PRF_TEST
+    case EVP_CTRL_PBE_PRF_NID:
+        *(int *)ptr = NID_hmacWithMD5;
+        return 1;
+# endif
+
+    default:
+        return -1;
+    }
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_rc4.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_rc4.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_rc4.c	(revision 331)
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+
+#ifndef OPENSSL_NO_RC4
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/rc4.h>
+
+# include "internal/evp_int.h"
+
+typedef struct {
+    RC4_KEY ks;                 /* working key */
+} EVP_RC4_KEY;
+
+# define data(ctx) ((EVP_RC4_KEY *)EVP_CIPHER_CTX_get_cipher_data(ctx))
+
+static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                        const unsigned char *iv, int enc);
+static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                      const unsigned char *in, size_t inl);
+static const EVP_CIPHER r4_cipher = {
+    NID_rc4,
+    1, EVP_RC4_KEY_SIZE, 0,
+    EVP_CIPH_VARIABLE_LENGTH,
+    rc4_init_key,
+    rc4_cipher,
+    NULL,
+    sizeof(EVP_RC4_KEY),
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
+
+static const EVP_CIPHER r4_40_cipher = {
+    NID_rc4_40,
+    1, 5 /* 40 bit */ , 0,
+    EVP_CIPH_VARIABLE_LENGTH,
+    rc4_init_key,
+    rc4_cipher,
+    NULL,
+    sizeof(EVP_RC4_KEY),
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
+
+const EVP_CIPHER *EVP_rc4(void)
+{
+    return (&r4_cipher);
+}
+
+const EVP_CIPHER *EVP_rc4_40(void)
+{
+    return (&r4_40_cipher);
+}
+
+static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                        const unsigned char *iv, int enc)
+{
+    RC4_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key);
+    return 1;
+}
+
+static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                      const unsigned char *in, size_t inl)
+{
+    RC4(&data(ctx)->ks, inl, in, out);
+    return 1;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_rc4_hmac_md5.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_rc4_hmac_md5.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_rc4_hmac_md5.c	(revision 331)
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2011-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 <openssl/opensslconf.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_MD5)
+
+# include <openssl/crypto.h>
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/rc4.h>
+# include <openssl/md5.h>
+# include "internal/evp_int.h"
+
+typedef struct {
+    RC4_KEY ks;
+    MD5_CTX head, tail, md;
+    size_t payload_length;
+} EVP_RC4_HMAC_MD5;
+
+# define NO_PAYLOAD_LENGTH       ((size_t)-1)
+
+void rc4_md5_enc(RC4_KEY *key, const void *in0, void *out,
+                 MD5_CTX *ctx, const void *inp, size_t blocks);
+
+# define data(ctx) ((EVP_RC4_HMAC_MD5 *)EVP_CIPHER_CTX_get_cipher_data(ctx))
+
+static int rc4_hmac_md5_init_key(EVP_CIPHER_CTX *ctx,
+                                 const unsigned char *inkey,
+                                 const unsigned char *iv, int enc)
+{
+    EVP_RC4_HMAC_MD5 *key = data(ctx);
+
+    RC4_set_key(&key->ks, EVP_CIPHER_CTX_key_length(ctx), inkey);
+
+    MD5_Init(&key->head);       /* handy when benchmarking */
+    key->tail = key->head;
+    key->md = key->head;
+
+    key->payload_length = NO_PAYLOAD_LENGTH;
+
+    return 1;
+}
+
+# if     defined(RC4_ASM) && defined(MD5_ASM) &&     (	   \
+        defined(__x86_64)       || defined(__x86_64__)  || \
+        defined(_M_AMD64)       || defined(_M_X64)      )
+#  define STITCHED_CALL
+# endif
+
+# if !defined(STITCHED_CALL)
+#  define rc4_off 0
+#  define md5_off 0
+# endif
+
+static int rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                               const unsigned char *in, size_t len)
+{
+    EVP_RC4_HMAC_MD5 *key = data(ctx);
+# if defined(STITCHED_CALL)
+    size_t rc4_off = 32 - 1 - (key->ks.x & (32 - 1)), /* 32 is $MOD from
+                                                       * rc4_md5-x86_64.pl */
+        md5_off = MD5_CBLOCK - key->md.num, blocks;
+    unsigned int l;
+    extern unsigned int OPENSSL_ia32cap_P[];
+# endif
+    size_t plen = key->payload_length;
+
+    if (plen != NO_PAYLOAD_LENGTH && len != (plen + MD5_DIGEST_LENGTH))
+        return 0;
+
+    if (EVP_CIPHER_CTX_encrypting(ctx)) {
+        if (plen == NO_PAYLOAD_LENGTH)
+            plen = len;
+# if defined(STITCHED_CALL)
+        /* cipher has to "fall behind" */
+        if (rc4_off > md5_off)
+            md5_off += MD5_CBLOCK;
+
+        if (plen > md5_off && (blocks = (plen - md5_off) / MD5_CBLOCK) &&
+            (OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) {
+            MD5_Update(&key->md, in, md5_off);
+            RC4(&key->ks, rc4_off, in, out);
+
+            rc4_md5_enc(&key->ks, in + rc4_off, out + rc4_off,
+                        &key->md, in + md5_off, blocks);
+            blocks *= MD5_CBLOCK;
+            rc4_off += blocks;
+            md5_off += blocks;
+            key->md.Nh += blocks >> 29;
+            key->md.Nl += blocks <<= 3;
+            if (key->md.Nl < (unsigned int)blocks)
+                key->md.Nh++;
+        } else {
+            rc4_off = 0;
+            md5_off = 0;
+        }
+# endif
+        MD5_Update(&key->md, in + md5_off, plen - md5_off);
+
+        if (plen != len) {      /* "TLS" mode of operation */
+            if (in != out)
+                memcpy(out + rc4_off, in + rc4_off, plen - rc4_off);
+
+            /* calculate HMAC and append it to payload */
+            MD5_Final(out + plen, &key->md);
+            key->md = key->tail;
+            MD5_Update(&key->md, out + plen, MD5_DIGEST_LENGTH);
+            MD5_Final(out + plen, &key->md);
+            /* encrypt HMAC at once */
+            RC4(&key->ks, len - rc4_off, out + rc4_off, out + rc4_off);
+        } else {
+            RC4(&key->ks, len - rc4_off, in + rc4_off, out + rc4_off);
+        }
+    } else {
+        unsigned char mac[MD5_DIGEST_LENGTH];
+# if defined(STITCHED_CALL)
+        /* digest has to "fall behind" */
+        if (md5_off > rc4_off)
+            rc4_off += 2 * MD5_CBLOCK;
+        else
+            rc4_off += MD5_CBLOCK;
+
+        if (len > rc4_off && (blocks = (len - rc4_off) / MD5_CBLOCK) &&
+            (OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) {
+            RC4(&key->ks, rc4_off, in, out);
+            MD5_Update(&key->md, out, md5_off);
+
+            rc4_md5_enc(&key->ks, in + rc4_off, out + rc4_off,
+                        &key->md, out + md5_off, blocks);
+            blocks *= MD5_CBLOCK;
+            rc4_off += blocks;
+            md5_off += blocks;
+            l = (key->md.Nl + (blocks << 3)) & 0xffffffffU;
+            if (l < key->md.Nl)
+                key->md.Nh++;
+            key->md.Nl = l;
+            key->md.Nh += blocks >> 29;
+        } else {
+            md5_off = 0;
+            rc4_off = 0;
+        }
+# endif
+        /* decrypt HMAC at once */
+        RC4(&key->ks, len - rc4_off, in + rc4_off, out + rc4_off);
+        if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */
+            MD5_Update(&key->md, out + md5_off, plen - md5_off);
+
+            /* calculate HMAC and verify it */
+            MD5_Final(mac, &key->md);
+            key->md = key->tail;
+            MD5_Update(&key->md, mac, MD5_DIGEST_LENGTH);
+            MD5_Final(mac, &key->md);
+
+            if (CRYPTO_memcmp(out + plen, mac, MD5_DIGEST_LENGTH))
+                return 0;
+        } else {
+            MD5_Update(&key->md, out + md5_off, len - md5_off);
+        }
+    }
+
+    key->payload_length = NO_PAYLOAD_LENGTH;
+
+    return 1;
+}
+
+static int rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
+                             void *ptr)
+{
+    EVP_RC4_HMAC_MD5 *key = data(ctx);
+
+    switch (type) {
+    case EVP_CTRL_AEAD_SET_MAC_KEY:
+        {
+            unsigned int i;
+            unsigned char hmac_key[64];
+
+            memset(hmac_key, 0, sizeof(hmac_key));
+
+            if (arg > (int)sizeof(hmac_key)) {
+                MD5_Init(&key->head);
+                MD5_Update(&key->head, ptr, arg);
+                MD5_Final(hmac_key, &key->head);
+            } else {
+                memcpy(hmac_key, ptr, arg);
+            }
+
+            for (i = 0; i < sizeof(hmac_key); i++)
+                hmac_key[i] ^= 0x36; /* ipad */
+            MD5_Init(&key->head);
+            MD5_Update(&key->head, hmac_key, sizeof(hmac_key));
+
+            for (i = 0; i < sizeof(hmac_key); i++)
+                hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */
+            MD5_Init(&key->tail);
+            MD5_Update(&key->tail, hmac_key, sizeof(hmac_key));
+
+            OPENSSL_cleanse(hmac_key, sizeof(hmac_key));
+
+            return 1;
+        }
+    case EVP_CTRL_AEAD_TLS1_AAD:
+        {
+            unsigned char *p = ptr;
+            unsigned int len;
+
+            if (arg != EVP_AEAD_TLS1_AAD_LEN)
+                return -1;
+
+            len = p[arg - 2] << 8 | p[arg - 1];
+
+            if (!EVP_CIPHER_CTX_encrypting(ctx)) {
+                if (len < MD5_DIGEST_LENGTH)
+                    return -1;
+                len -= MD5_DIGEST_LENGTH;
+                p[arg - 2] = len >> 8;
+                p[arg - 1] = len;
+            }
+            key->payload_length = len;
+            key->md = key->head;
+            MD5_Update(&key->md, p, arg);
+
+            return MD5_DIGEST_LENGTH;
+        }
+    default:
+        return -1;
+    }
+}
+
+static EVP_CIPHER r4_hmac_md5_cipher = {
+# ifdef NID_rc4_hmac_md5
+    NID_rc4_hmac_md5,
+# else
+    NID_undef,
+# endif
+    1, EVP_RC4_KEY_SIZE, 0,
+    EVP_CIPH_STREAM_CIPHER | EVP_CIPH_VARIABLE_LENGTH |
+        EVP_CIPH_FLAG_AEAD_CIPHER,
+    rc4_hmac_md5_init_key,
+    rc4_hmac_md5_cipher,
+    NULL,
+    sizeof(EVP_RC4_HMAC_MD5),
+    NULL,
+    NULL,
+    rc4_hmac_md5_ctrl,
+    NULL
+};
+
+const EVP_CIPHER *EVP_rc4_hmac_md5(void)
+{
+    return (&r4_hmac_md5_cipher);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_rc5.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_rc5.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_rc5.c	(revision 331)
@@ -0,0 +1,74 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+
+#ifndef OPENSSL_NO_RC5
+
+# include <openssl/evp.h>
+# include <internal/evp_int.h>
+# include <openssl/objects.h>
+# include "evp_locl.h"
+# include <openssl/rc5.h>
+
+static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                               const unsigned char *iv, int enc);
+static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
+
+typedef struct {
+    int rounds;                 /* number of rounds */
+    RC5_32_KEY ks;              /* key schedule */
+} EVP_RC5_KEY;
+
+# define data(ctx)       EVP_C_DATA(EVP_RC5_KEY,ctx)
+
+IMPLEMENT_BLOCK_CIPHER(rc5_32_12_16, ks, RC5_32, EVP_RC5_KEY, NID_rc5,
+                       8, RC5_32_KEY_LENGTH, 8, 64,
+                       EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+                       r_32_12_16_init_key, NULL, NULL, NULL, rc5_ctrl)
+
+static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
+{
+    switch (type) {
+    case EVP_CTRL_INIT:
+        data(c)->rounds = RC5_12_ROUNDS;
+        return 1;
+
+    case EVP_CTRL_GET_RC5_ROUNDS:
+        *(int *)ptr = data(c)->rounds;
+        return 1;
+
+    case EVP_CTRL_SET_RC5_ROUNDS:
+        switch (arg) {
+        case RC5_8_ROUNDS:
+        case RC5_12_ROUNDS:
+        case RC5_16_ROUNDS:
+            data(c)->rounds = arg;
+            return 1;
+
+        default:
+            EVPerr(EVP_F_RC5_CTRL, EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS);
+            return 0;
+        }
+
+    default:
+        return -1;
+    }
+}
+
+static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                               const unsigned char *iv, int enc)
+{
+    RC5_32_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
+                   key, data(ctx)->rounds);
+    return 1;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_seed.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_seed.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_seed.c	(revision 331)
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2007-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 <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_SEED
+NON_EMPTY_TRANSLATION_UNIT
+#else
+# include <openssl/evp.h>
+# include <openssl/err.h>
+# include <string.h>
+# include <assert.h>
+# include <openssl/seed.h>
+# include "internal/evp_int.h"
+
+static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                         const unsigned char *iv, int enc);
+
+typedef struct {
+    SEED_KEY_SCHEDULE ks;
+} EVP_SEED_KEY;
+
+IMPLEMENT_BLOCK_CIPHER(seed, ks, SEED, EVP_SEED_KEY, NID_seed,
+                       16, 16, 16, 128, EVP_CIPH_FLAG_DEFAULT_ASN1,
+                       seed_init_key, 0, 0, 0, 0)
+
+static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                         const unsigned char *iv, int enc)
+{
+    SEED_set_key(key, &EVP_C_DATA(EVP_SEED_KEY,ctx)->ks);
+    return 1;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_xcbc_d.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_xcbc_d.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/e_xcbc_d.c	(revision 331)
@@ -0,0 +1,83 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+
+#ifndef OPENSSL_NO_DES
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include "internal/evp_int.h"
+# include <openssl/des.h>
+
+static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                             const unsigned char *iv, int enc);
+static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                           const unsigned char *in, size_t inl);
+
+typedef struct {
+    DES_key_schedule ks;        /* key schedule */
+    DES_cblock inw;
+    DES_cblock outw;
+} DESX_CBC_KEY;
+
+# define data(ctx) EVP_C_DATA(DESX_CBC_KEY,ctx)
+
+static const EVP_CIPHER d_xcbc_cipher = {
+    NID_desx_cbc,
+    8, 24, 8,
+    EVP_CIPH_CBC_MODE,
+    desx_cbc_init_key,
+    desx_cbc_cipher,
+    NULL,
+    sizeof(DESX_CBC_KEY),
+    EVP_CIPHER_set_asn1_iv,
+    EVP_CIPHER_get_asn1_iv,
+    NULL,
+    NULL
+};
+
+const EVP_CIPHER *EVP_desx_cbc(void)
+{
+    return (&d_xcbc_cipher);
+}
+
+static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                             const unsigned char *iv, int enc)
+{
+    DES_cblock *deskey = (DES_cblock *)key;
+
+    DES_set_key_unchecked(deskey, &data(ctx)->ks);
+    memcpy(&data(ctx)->inw[0], &key[8], 8);
+    memcpy(&data(ctx)->outw[0], &key[16], 8);
+
+    return 1;
+}
+
+static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                           const unsigned char *in, size_t inl)
+{
+    while (inl >= EVP_MAXCHUNK) {
+        DES_xcbc_encrypt(in, out, (long)EVP_MAXCHUNK, &data(ctx)->ks,
+                         (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
+                         &data(ctx)->inw, &data(ctx)->outw,
+                         EVP_CIPHER_CTX_encrypting(ctx));
+        inl -= EVP_MAXCHUNK;
+        in += EVP_MAXCHUNK;
+        out += EVP_MAXCHUNK;
+    }
+    if (inl)
+        DES_xcbc_encrypt(in, out, (long)inl, &data(ctx)->ks,
+                         (DES_cblock *)EVP_CIPHER_CTX_iv_noconst(ctx),
+                         &data(ctx)->inw, &data(ctx)->outw,
+                         EVP_CIPHER_CTX_encrypting(ctx));
+    return 1;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/encode.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/encode.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/encode.c	(revision 331)
@@ -0,0 +1,404 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <limits.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include "evp_locl.h"
+
+static unsigned char conv_ascii2bin(unsigned char a);
+#ifndef CHARSET_EBCDIC
+# define conv_bin2ascii(a)       (data_bin2ascii[(a)&0x3f])
+#else
+/*
+ * We assume that PEM encoded files are EBCDIC files (i.e., printable text
+ * files). Convert them here while decoding. When encoding, output is EBCDIC
+ * (text) format again. (No need for conversion in the conv_bin2ascii macro,
+ * as the underlying textstring data_bin2ascii[] is already EBCDIC)
+ */
+# define conv_bin2ascii(a)       (data_bin2ascii[(a)&0x3f])
+#endif
+
+/*-
+ * 64 char lines
+ * pad input with 0
+ * left over chars are set to =
+ * 1 byte  => xx==
+ * 2 bytes => xxx=
+ * 3 bytes => xxxx
+ */
+#define BIN_PER_LINE    (64/4*3)
+#define CHUNKS_PER_LINE (64/4)
+#define CHAR_PER_LINE   (64+1)
+
+static const unsigned char data_bin2ascii[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\
+abcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/*-
+ * 0xF0 is a EOLN
+ * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing).
+ * 0xF2 is EOF
+ * 0xE0 is ignore at start of line.
+ * 0xFF is error
+ */
+
+#define B64_EOLN                0xF0
+#define B64_CR                  0xF1
+#define B64_EOF                 0xF2
+#define B64_WS                  0xE0
+#define B64_ERROR               0xFF
+#define B64_NOT_BASE64(a)       (((a)|0x13) == 0xF3)
+#define B64_BASE64(a)           (!B64_NOT_BASE64(a))
+
+static const unsigned char data_ascii2bin[128] = {
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xFF, 0xE0, 0xF0, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F,
+    0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
+    0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
+    0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+    0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
+    0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
+    0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+    0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
+    0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+    0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
+    0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+#ifndef CHARSET_EBCDIC
+static unsigned char conv_ascii2bin(unsigned char a)
+{
+    if (a & 0x80)
+        return B64_ERROR;
+    return data_ascii2bin[a];
+}
+#else
+static unsigned char conv_ascii2bin(unsigned char a)
+{
+    a = os_toascii[a];
+    if (a & 0x80)
+        return B64_ERROR;
+    return data_ascii2bin[a];
+}
+#endif
+
+EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void)
+{
+    return OPENSSL_zalloc(sizeof(EVP_ENCODE_CTX));
+}
+
+void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx)
+{
+    OPENSSL_free(ctx);
+}
+
+int EVP_ENCODE_CTX_copy(EVP_ENCODE_CTX *dctx, EVP_ENCODE_CTX *sctx)
+{
+    memcpy(dctx, sctx, sizeof(EVP_ENCODE_CTX));
+
+    return 1;
+}
+
+int EVP_ENCODE_CTX_num(EVP_ENCODE_CTX *ctx)
+{
+    return ctx->num;
+}
+
+void EVP_EncodeInit(EVP_ENCODE_CTX *ctx)
+{
+    ctx->length = 48;
+    ctx->num = 0;
+    ctx->line_num = 0;
+}
+
+int EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
+                      const unsigned char *in, int inl)
+{
+    int i, j;
+    size_t total = 0;
+
+    *outl = 0;
+    if (inl <= 0)
+        return 0;
+    OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data));
+    if (ctx->length - ctx->num > inl) {
+        memcpy(&(ctx->enc_data[ctx->num]), in, inl);
+        ctx->num += inl;
+        return 1;
+    }
+    if (ctx->num != 0) {
+        i = ctx->length - ctx->num;
+        memcpy(&(ctx->enc_data[ctx->num]), in, i);
+        in += i;
+        inl -= i;
+        j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length);
+        ctx->num = 0;
+        out += j;
+        *(out++) = '\n';
+        *out = '\0';
+        total = j + 1;
+    }
+    while (inl >= ctx->length && total <= INT_MAX) {
+        j = EVP_EncodeBlock(out, in, ctx->length);
+        in += ctx->length;
+        inl -= ctx->length;
+        out += j;
+        *(out++) = '\n';
+        *out = '\0';
+        total += j + 1;
+    }
+    if (total > INT_MAX) {
+        /* Too much output data! */
+        *outl = 0;
+        return 0;
+    }
+    if (inl != 0)
+        memcpy(&(ctx->enc_data[0]), in, inl);
+    ctx->num = inl;
+    *outl = total;
+
+    return 1;
+}
+
+void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
+{
+    unsigned int ret = 0;
+
+    if (ctx->num != 0) {
+        ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num);
+        out[ret++] = '\n';
+        out[ret] = '\0';
+        ctx->num = 0;
+    }
+    *outl = ret;
+}
+
+int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen)
+{
+    int i, ret = 0;
+    unsigned long l;
+
+    for (i = dlen; i > 0; i -= 3) {
+        if (i >= 3) {
+            l = (((unsigned long)f[0]) << 16L) |
+                (((unsigned long)f[1]) << 8L) | f[2];
+            *(t++) = conv_bin2ascii(l >> 18L);
+            *(t++) = conv_bin2ascii(l >> 12L);
+            *(t++) = conv_bin2ascii(l >> 6L);
+            *(t++) = conv_bin2ascii(l);
+        } else {
+            l = ((unsigned long)f[0]) << 16L;
+            if (i == 2)
+                l |= ((unsigned long)f[1] << 8L);
+
+            *(t++) = conv_bin2ascii(l >> 18L);
+            *(t++) = conv_bin2ascii(l >> 12L);
+            *(t++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L);
+            *(t++) = '=';
+        }
+        ret += 4;
+        f += 3;
+    }
+
+    *t = '\0';
+    return (ret);
+}
+
+void EVP_DecodeInit(EVP_ENCODE_CTX *ctx)
+{
+    /* Only ctx->num is used during decoding. */
+    ctx->num = 0;
+    ctx->length = 0;
+    ctx->line_num = 0;
+    ctx->expect_nl = 0;
+}
+
+/*-
+ * -1 for error
+ *  0 for last line
+ *  1 for full line
+ *
+ * Note: even though EVP_DecodeUpdate attempts to detect and report end of
+ * content, the context doesn't currently remember it and will accept more data
+ * in the next call. Therefore, the caller is responsible for checking and
+ * rejecting a 0 return value in the middle of content.
+ *
+ * Note: even though EVP_DecodeUpdate has historically tried to detect end of
+ * content based on line length, this has never worked properly. Therefore,
+ * we now return 0 when one of the following is true:
+ *   - Padding or B64_EOF was detected and the last block is complete.
+ *   - Input has zero-length.
+ * -1 is returned if:
+ *   - Invalid characters are detected.
+ *   - There is extra trailing padding, or data after padding.
+ *   - B64_EOF is detected after an incomplete base64 block.
+ */
+int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
+                     const unsigned char *in, int inl)
+{
+    int seof = 0, eof = 0, rv = -1, ret = 0, i, v, tmp, n, decoded_len;
+    unsigned char *d;
+
+    n = ctx->num;
+    d = ctx->enc_data;
+
+    if (n > 0 && d[n - 1] == '=') {
+        eof++;
+        if (n > 1 && d[n - 2] == '=')
+            eof++;
+    }
+
+     /* Legacy behaviour: an empty input chunk signals end of input. */
+    if (inl == 0) {
+        rv = 0;
+        goto end;
+    }
+
+    for (i = 0; i < inl; i++) {
+        tmp = *(in++);
+        v = conv_ascii2bin(tmp);
+        if (v == B64_ERROR) {
+            rv = -1;
+            goto end;
+        }
+
+        if (tmp == '=') {
+            eof++;
+        } else if (eof > 0 && B64_BASE64(v)) {
+            /* More data after padding. */
+            rv = -1;
+            goto end;
+        }
+
+        if (eof > 2) {
+            rv = -1;
+            goto end;
+        }
+
+        if (v == B64_EOF) {
+            seof = 1;
+            goto tail;
+        }
+
+        /* Only save valid base64 characters. */
+        if (B64_BASE64(v)) {
+            if (n >= 64) {
+                /*
+                 * We increment n once per loop, and empty the buffer as soon as
+                 * we reach 64 characters, so this can only happen if someone's
+                 * manually messed with the ctx. Refuse to write any more data.
+                 */
+                rv = -1;
+                goto end;
+            }
+            OPENSSL_assert(n < (int)sizeof(ctx->enc_data));
+            d[n++] = tmp;
+        }
+
+        if (n == 64) {
+            decoded_len = EVP_DecodeBlock(out, d, n);
+            n = 0;
+            if (decoded_len < 0 || eof > decoded_len) {
+                rv = -1;
+                goto end;
+            }
+            ret += decoded_len - eof;
+            out += decoded_len - eof;
+        }
+    }
+
+    /*
+     * Legacy behaviour: if the current line is a full base64-block (i.e., has
+     * 0 mod 4 base64 characters), it is processed immediately. We keep this
+     * behaviour as applications may not be calling EVP_DecodeFinal properly.
+     */
+tail:
+    if (n > 0) {
+        if ((n & 3) == 0) {
+            decoded_len = EVP_DecodeBlock(out, d, n);
+            n = 0;
+            if (decoded_len < 0 || eof > decoded_len) {
+                rv = -1;
+                goto end;
+            }
+            ret += (decoded_len - eof);
+        } else if (seof) {
+            /* EOF in the middle of a base64 block. */
+            rv = -1;
+            goto end;
+        }
+    }
+
+    rv = seof || (n == 0 && eof) ? 0 : 1;
+end:
+    /* Legacy behaviour. This should probably rather be zeroed on error. */
+    *outl = ret;
+    ctx->num = n;
+    return (rv);
+}
+
+int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n)
+{
+    int i, ret = 0, a, b, c, d;
+    unsigned long l;
+
+    /* trim white space from the start of the line. */
+    while ((conv_ascii2bin(*f) == B64_WS) && (n > 0)) {
+        f++;
+        n--;
+    }
+
+    /*
+     * strip off stuff at the end of the line ascii2bin values B64_WS,
+     * B64_EOLN, B64_EOLN and B64_EOF
+     */
+    while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n - 1]))))
+        n--;
+
+    if (n % 4 != 0)
+        return (-1);
+
+    for (i = 0; i < n; i += 4) {
+        a = conv_ascii2bin(*(f++));
+        b = conv_ascii2bin(*(f++));
+        c = conv_ascii2bin(*(f++));
+        d = conv_ascii2bin(*(f++));
+        if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80))
+            return (-1);
+        l = ((((unsigned long)a) << 18L) |
+             (((unsigned long)b) << 12L) |
+             (((unsigned long)c) << 6L) | (((unsigned long)d)));
+        *(t++) = (unsigned char)(l >> 16L) & 0xff;
+        *(t++) = (unsigned char)(l >> 8L) & 0xff;
+        *(t++) = (unsigned char)(l) & 0xff;
+        ret += 3;
+    }
+    return (ret);
+}
+
+int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
+{
+    int i;
+
+    *outl = 0;
+    if (ctx->num != 0) {
+        i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num);
+        if (i < 0)
+            return (-1);
+        ctx->num = 0;
+        *outl = i;
+        return (1);
+    } else
+        return (1);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_cnf.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_cnf.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_cnf.c	(revision 331)
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2012-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 <stdio.h>
+#include <ctype.h>
+#include <openssl/crypto.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+/* Algorithm configuration module. */
+
+static int alg_module_init(CONF_IMODULE *md, const CONF *cnf)
+{
+    int i;
+    const char *oid_section;
+    STACK_OF(CONF_VALUE) *sktmp;
+    CONF_VALUE *oval;
+
+    oid_section = CONF_imodule_get_value(md);
+    if ((sktmp = NCONF_get_section(cnf, oid_section)) == NULL) {
+        EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_LOADING_SECTION);
+        return 0;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
+        oval = sk_CONF_VALUE_value(sktmp, i);
+        if (strcmp(oval->name, "fips_mode") == 0) {
+            int m;
+            if (!X509V3_get_value_bool(oval, &m)) {
+                EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_INVALID_FIPS_MODE);
+                return 0;
+            }
+            if (m > 0) {
+#ifdef OPENSSL_FIPS
+                if (!FIPS_mode() && !FIPS_mode_set(1)) {
+                    EVPerr(EVP_F_ALG_MODULE_INIT,
+                           EVP_R_ERROR_SETTING_FIPS_MODE);
+                    return 0;
+                }
+#else
+                EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_FIPS_MODE_NOT_SUPPORTED);
+                return 0;
+#endif
+            }
+        } else {
+            EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION);
+            ERR_add_error_data(4, "name=", oval->name,
+                               ", value=", oval->value);
+        }
+
+    }
+    return 1;
+}
+
+void EVP_add_alg_module(void)
+{
+    CONF_module_add("alg_section", alg_module_init, 0);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_enc.c	(revision 331)
@@ -0,0 +1,641 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <assert.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include <openssl/engine.h>
+#include "internal/evp_int.h"
+#include "evp_locl.h"
+
+int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c)
+{
+    if (c == NULL)
+        return 1;
+    if (c->cipher != NULL) {
+        if (c->cipher->cleanup && !c->cipher->cleanup(c))
+            return 0;
+        /* Cleanse cipher context data */
+        if (c->cipher_data && c->cipher->ctx_size)
+            OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
+    }
+    OPENSSL_free(c->cipher_data);
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE_finish(c->engine);
+#endif
+    memset(c, 0, sizeof(*c));
+    return 1;
+}
+
+EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
+{
+    return OPENSSL_zalloc(sizeof(EVP_CIPHER_CTX));
+}
+
+void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
+{
+    EVP_CIPHER_CTX_reset(ctx);
+    OPENSSL_free(ctx);
+}
+
+int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+                   const unsigned char *key, const unsigned char *iv, int enc)
+{
+    EVP_CIPHER_CTX_reset(ctx);
+    return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc);
+}
+
+int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+                      ENGINE *impl, const unsigned char *key,
+                      const unsigned char *iv, int enc)
+{
+    if (enc == -1)
+        enc = ctx->encrypt;
+    else {
+        if (enc)
+            enc = 1;
+        ctx->encrypt = enc;
+    }
+#ifndef OPENSSL_NO_ENGINE
+    /*
+     * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so
+     * this context may already have an ENGINE! Try to avoid releasing the
+     * previous handle, re-querying for an ENGINE, and having a
+     * reinitialisation, when it may all be unnecessary.
+     */
+    if (ctx->engine && ctx->cipher
+        && (cipher == NULL || cipher->nid == ctx->cipher->nid))
+        goto skip_to_init;
+#endif
+    if (cipher) {
+        /*
+         * Ensure a context left lying around from last time is cleared (the
+         * previous check attempted to avoid this if the same ENGINE and
+         * EVP_CIPHER could be used).
+         */
+        if (ctx->cipher) {
+            unsigned long flags = ctx->flags;
+            EVP_CIPHER_CTX_reset(ctx);
+            /* Restore encrypt and flags */
+            ctx->encrypt = enc;
+            ctx->flags = flags;
+        }
+#ifndef OPENSSL_NO_ENGINE
+        if (impl) {
+            if (!ENGINE_init(impl)) {
+                EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
+                return 0;
+            }
+        } else
+            /* Ask if an ENGINE is reserved for this job */
+            impl = ENGINE_get_cipher_engine(cipher->nid);
+        if (impl) {
+            /* There's an ENGINE for this job ... (apparently) */
+            const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid);
+            if (!c) {
+                /*
+                 * One positive side-effect of US's export control history,
+                 * is that we should at least be able to avoid using US
+                 * misspellings of "initialisation"?
+                 */
+                EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
+                return 0;
+            }
+            /* We'll use the ENGINE's private cipher definition */
+            cipher = c;
+            /*
+             * Store the ENGINE functional reference so we know 'cipher' came
+             * from an ENGINE and we need to release it when done.
+             */
+            ctx->engine = impl;
+        } else
+            ctx->engine = NULL;
+#endif
+
+        ctx->cipher = cipher;
+        if (ctx->cipher->ctx_size) {
+            ctx->cipher_data = OPENSSL_zalloc(ctx->cipher->ctx_size);
+            if (ctx->cipher_data == NULL) {
+                ctx->cipher = NULL;
+                EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE);
+                return 0;
+            }
+        } else {
+            ctx->cipher_data = NULL;
+        }
+        ctx->key_len = cipher->key_len;
+        /* Preserve wrap enable flag, zero everything else */
+        ctx->flags &= EVP_CIPHER_CTX_FLAG_WRAP_ALLOW;
+        if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) {
+            if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) {
+                ctx->cipher = NULL;
+                EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
+                return 0;
+            }
+        }
+    } else if (!ctx->cipher) {
+        EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET);
+        return 0;
+    }
+#ifndef OPENSSL_NO_ENGINE
+ skip_to_init:
+#endif
+    /* we assume block size is a power of 2 in *cryptUpdate */
+    OPENSSL_assert(ctx->cipher->block_size == 1
+                   || ctx->cipher->block_size == 8
+                   || ctx->cipher->block_size == 16);
+
+    if (!(ctx->flags & EVP_CIPHER_CTX_FLAG_WRAP_ALLOW)
+        && EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_WRAP_MODE) {
+        EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_WRAP_MODE_NOT_ALLOWED);
+        return 0;
+    }
+
+    if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ctx)) & EVP_CIPH_CUSTOM_IV)) {
+        switch (EVP_CIPHER_CTX_mode(ctx)) {
+
+        case EVP_CIPH_STREAM_CIPHER:
+        case EVP_CIPH_ECB_MODE:
+            break;
+
+        case EVP_CIPH_CFB_MODE:
+        case EVP_CIPH_OFB_MODE:
+
+            ctx->num = 0;
+            /* fall-through */
+
+        case EVP_CIPH_CBC_MODE:
+
+            OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <=
+                           (int)sizeof(ctx->iv));
+            if (iv)
+                memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+            memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
+            break;
+
+        case EVP_CIPH_CTR_MODE:
+            ctx->num = 0;
+            /* Don't reuse IV for CTR mode */
+            if (iv)
+                memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+            break;
+
+        default:
+            return 0;
+        }
+    }
+
+    if (key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
+        if (!ctx->cipher->init(ctx, key, iv, enc))
+            return 0;
+    }
+    ctx->buf_len = 0;
+    ctx->final_used = 0;
+    ctx->block_mask = ctx->cipher->block_size - 1;
+    return 1;
+}
+
+int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+                     const unsigned char *in, int inl)
+{
+    if (ctx->encrypt)
+        return EVP_EncryptUpdate(ctx, out, outl, in, inl);
+    else
+        return EVP_DecryptUpdate(ctx, out, outl, in, inl);
+}
+
+int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+    if (ctx->encrypt)
+        return EVP_EncryptFinal_ex(ctx, out, outl);
+    else
+        return EVP_DecryptFinal_ex(ctx, out, outl);
+}
+
+int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+    if (ctx->encrypt)
+        return EVP_EncryptFinal(ctx, out, outl);
+    else
+        return EVP_DecryptFinal(ctx, out, outl);
+}
+
+int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+                    const unsigned char *key, const unsigned char *iv)
+{
+    return EVP_CipherInit(ctx, cipher, key, iv, 1);
+}
+
+int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+                       ENGINE *impl, const unsigned char *key,
+                       const unsigned char *iv)
+{
+    return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1);
+}
+
+int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+                    const unsigned char *key, const unsigned char *iv)
+{
+    return EVP_CipherInit(ctx, cipher, key, iv, 0);
+}
+
+int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+                       ENGINE *impl, const unsigned char *key,
+                       const unsigned char *iv)
+{
+    return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0);
+}
+
+/*
+ * According to the letter of standard difference between pointers
+ * is specified to be valid only within same object. This makes
+ * it formally challenging to determine if input and output buffers
+ * are not partially overlapping with standard pointer arithmetic.
+ */
+#ifdef PTRDIFF_T
+# undef PTRDIFF_T
+#endif
+#if defined(OPENSSL_SYS_VMS) && __INITIAL_POINTER_SIZE==64
+/*
+ * Then we have VMS that distinguishes itself by adhering to
+ * sizeof(size_t)==4 even in 64-bit builds, which means that
+ * difference between two pointers might be truncated to 32 bits.
+ * In the context one can even wonder how comparison for
+ * equality is implemented. To be on the safe side we adhere to
+ * PTRDIFF_T even for comparison for equality.
+ */
+# define PTRDIFF_T uint64_t
+#else
+# define PTRDIFF_T size_t
+#endif
+
+int is_partially_overlapping(const void *ptr1, const void *ptr2, int len)
+{
+    PTRDIFF_T diff = (PTRDIFF_T)ptr1-(PTRDIFF_T)ptr2;
+    /*
+     * Check for partially overlapping buffers. [Binary logical
+     * operations are used instead of boolean to minimize number
+     * of conditional branches.]
+     */
+    int overlapped = (len > 0) & (diff != 0) & ((diff < (PTRDIFF_T)len) |
+                                                (diff > (0 - (PTRDIFF_T)len)));
+
+    return overlapped;
+}
+
+int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+                      const unsigned char *in, int inl)
+{
+    int i, j, bl, cmpl = inl;
+
+    if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS))
+        cmpl = (cmpl + 7) / 8;
+
+    bl = ctx->cipher->block_size;
+
+    if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
+        /* If block size > 1 then the cipher will have to do this check */
+        if (bl == 1 && is_partially_overlapping(out, in, cmpl)) {
+            EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
+            return 0;
+        }
+
+        i = ctx->cipher->do_cipher(ctx, out, in, inl);
+        if (i < 0)
+            return 0;
+        else
+            *outl = i;
+        return 1;
+    }
+
+    if (inl <= 0) {
+        *outl = 0;
+        return inl == 0;
+    }
+    if (is_partially_overlapping(out + ctx->buf_len, in, cmpl)) {
+        EVPerr(EVP_F_EVP_ENCRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
+        return 0;
+    }
+
+    if (ctx->buf_len == 0 && (inl & (ctx->block_mask)) == 0) {
+        if (ctx->cipher->do_cipher(ctx, out, in, inl)) {
+            *outl = inl;
+            return 1;
+        } else {
+            *outl = 0;
+            return 0;
+        }
+    }
+    i = ctx->buf_len;
+    OPENSSL_assert(bl <= (int)sizeof(ctx->buf));
+    if (i != 0) {
+        if (bl - i > inl) {
+            memcpy(&(ctx->buf[i]), in, inl);
+            ctx->buf_len += inl;
+            *outl = 0;
+            return 1;
+        } else {
+            j = bl - i;
+            memcpy(&(ctx->buf[i]), in, j);
+            inl -= j;
+            in += j;
+            if (!ctx->cipher->do_cipher(ctx, out, ctx->buf, bl))
+                return 0;
+            out += bl;
+            *outl = bl;
+        }
+    } else
+        *outl = 0;
+    i = inl & (bl - 1);
+    inl -= i;
+    if (inl > 0) {
+        if (!ctx->cipher->do_cipher(ctx, out, in, inl))
+            return 0;
+        *outl += inl;
+    }
+
+    if (i != 0)
+        memcpy(ctx->buf, &(in[inl]), i);
+    ctx->buf_len = i;
+    return 1;
+}
+
+int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+    int ret;
+    ret = EVP_EncryptFinal_ex(ctx, out, outl);
+    return ret;
+}
+
+int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+    int n, ret;
+    unsigned int i, b, bl;
+
+    if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
+        ret = ctx->cipher->do_cipher(ctx, out, NULL, 0);
+        if (ret < 0)
+            return 0;
+        else
+            *outl = ret;
+        return 1;
+    }
+
+    b = ctx->cipher->block_size;
+    OPENSSL_assert(b <= sizeof ctx->buf);
+    if (b == 1) {
+        *outl = 0;
+        return 1;
+    }
+    bl = ctx->buf_len;
+    if (ctx->flags & EVP_CIPH_NO_PADDING) {
+        if (bl) {
+            EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX,
+                   EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
+            return 0;
+        }
+        *outl = 0;
+        return 1;
+    }
+
+    n = b - bl;
+    for (i = bl; i < b; i++)
+        ctx->buf[i] = n;
+    ret = ctx->cipher->do_cipher(ctx, out, ctx->buf, b);
+
+    if (ret)
+        *outl = b;
+
+    return ret;
+}
+
+int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
+                      const unsigned char *in, int inl)
+{
+    int fix_len, cmpl = inl;
+    unsigned int b;
+
+    b = ctx->cipher->block_size;
+
+    if (EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS))
+        cmpl = (cmpl + 7) / 8;
+
+    if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
+        if (b == 1 && is_partially_overlapping(out, in, cmpl)) {
+            EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
+            return 0;
+        }
+
+        fix_len = ctx->cipher->do_cipher(ctx, out, in, inl);
+        if (fix_len < 0) {
+            *outl = 0;
+            return 0;
+        } else
+            *outl = fix_len;
+        return 1;
+    }
+
+    if (inl <= 0) {
+        *outl = 0;
+        return inl == 0;
+    }
+
+    if (ctx->flags & EVP_CIPH_NO_PADDING)
+        return EVP_EncryptUpdate(ctx, out, outl, in, inl);
+
+    OPENSSL_assert(b <= sizeof ctx->final);
+
+    if (ctx->final_used) {
+        /* see comment about PTRDIFF_T comparison above */
+        if (((PTRDIFF_T)out == (PTRDIFF_T)in)
+            || is_partially_overlapping(out, in, b)) {
+            EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_PARTIALLY_OVERLAPPING);
+            return 0;
+        }
+        memcpy(out, ctx->final, b);
+        out += b;
+        fix_len = 1;
+    } else
+        fix_len = 0;
+
+    if (!EVP_EncryptUpdate(ctx, out, outl, in, inl))
+        return 0;
+
+    /*
+     * if we have 'decrypted' a multiple of block size, make sure we have a
+     * copy of this last block
+     */
+    if (b > 1 && !ctx->buf_len) {
+        *outl -= b;
+        ctx->final_used = 1;
+        memcpy(ctx->final, &out[*outl], b);
+    } else
+        ctx->final_used = 0;
+
+    if (fix_len)
+        *outl += b;
+
+    return 1;
+}
+
+int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+    int ret;
+    ret = EVP_DecryptFinal_ex(ctx, out, outl);
+    return ret;
+}
+
+int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+    int i, n;
+    unsigned int b;
+    *outl = 0;
+
+    if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
+        i = ctx->cipher->do_cipher(ctx, out, NULL, 0);
+        if (i < 0)
+            return 0;
+        else
+            *outl = i;
+        return 1;
+    }
+
+    b = ctx->cipher->block_size;
+    if (ctx->flags & EVP_CIPH_NO_PADDING) {
+        if (ctx->buf_len) {
+            EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,
+                   EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
+            return 0;
+        }
+        *outl = 0;
+        return 1;
+    }
+    if (b > 1) {
+        if (ctx->buf_len || !ctx->final_used) {
+            EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_WRONG_FINAL_BLOCK_LENGTH);
+            return (0);
+        }
+        OPENSSL_assert(b <= sizeof ctx->final);
+
+        /*
+         * The following assumes that the ciphertext has been authenticated.
+         * Otherwise it provides a padding oracle.
+         */
+        n = ctx->final[b - 1];
+        if (n == 0 || n > (int)b) {
+            EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT);
+            return (0);
+        }
+        for (i = 0; i < n; i++) {
+            if (ctx->final[--b] != n) {
+                EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT);
+                return (0);
+            }
+        }
+        n = ctx->cipher->block_size - n;
+        for (i = 0; i < n; i++)
+            out[i] = ctx->final[i];
+        *outl = n;
+    } else
+        *outl = 0;
+    return (1);
+}
+
+int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
+{
+    if (c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH)
+        return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL);
+    if (c->key_len == keylen)
+        return 1;
+    if ((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) {
+        c->key_len = keylen;
+        return 1;
+    }
+    EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH, EVP_R_INVALID_KEY_LENGTH);
+    return 0;
+}
+
+int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
+{
+    if (pad)
+        ctx->flags &= ~EVP_CIPH_NO_PADDING;
+    else
+        ctx->flags |= EVP_CIPH_NO_PADDING;
+    return 1;
+}
+
+int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+    int ret;
+    if (!ctx->cipher) {
+        EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
+        return 0;
+    }
+
+    if (!ctx->cipher->ctrl) {
+        EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
+        return 0;
+    }
+
+    ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
+    if (ret == -1) {
+        EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL,
+               EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
+        return 0;
+    }
+    return ret;
+}
+
+int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
+{
+    if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
+        return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key);
+    if (RAND_bytes(key, ctx->key_len) <= 0)
+        return 0;
+    return 1;
+}
+
+int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
+{
+    if ((in == NULL) || (in->cipher == NULL)) {
+        EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, EVP_R_INPUT_NOT_INITIALIZED);
+        return 0;
+    }
+#ifndef OPENSSL_NO_ENGINE
+    /* Make sure it's safe to copy a cipher context using an ENGINE */
+    if (in->engine && !ENGINE_init(in->engine)) {
+        EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, ERR_R_ENGINE_LIB);
+        return 0;
+    }
+#endif
+
+    EVP_CIPHER_CTX_reset(out);
+    memcpy(out, in, sizeof(*out));
+
+    if (in->cipher_data && in->cipher->ctx_size) {
+        out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size);
+        if (out->cipher_data == NULL) {
+            out->cipher = NULL;
+            EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size);
+    }
+
+    if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY)
+        if (!in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out)) {
+            out->cipher = NULL;
+            EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, EVP_R_INITIALIZATION_ERROR);
+            return 0;
+        }
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_err.c	(revision 331)
@@ -0,0 +1,180 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_EVP,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_EVP,0,reason)
+
+static ERR_STRING_DATA EVP_str_functs[] = {
+    {ERR_FUNC(EVP_F_AESNI_INIT_KEY), "aesni_init_key"},
+    {ERR_FUNC(EVP_F_AES_INIT_KEY), "aes_init_key"},
+    {ERR_FUNC(EVP_F_AES_OCB_CIPHER), "aes_ocb_cipher"},
+    {ERR_FUNC(EVP_F_AES_T4_INIT_KEY), "aes_t4_init_key"},
+    {ERR_FUNC(EVP_F_AES_WRAP_CIPHER), "aes_wrap_cipher"},
+    {ERR_FUNC(EVP_F_ALG_MODULE_INIT), "alg_module_init"},
+    {ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY), "camellia_init_key"},
+    {ERR_FUNC(EVP_F_CHACHA20_POLY1305_CTRL), "chacha20_poly1305_ctrl"},
+    {ERR_FUNC(EVP_F_CMLL_T4_INIT_KEY), "cmll_t4_init_key"},
+    {ERR_FUNC(EVP_F_DES_EDE3_WRAP_CIPHER), "des_ede3_wrap_cipher"},
+    {ERR_FUNC(EVP_F_DO_SIGVER_INIT), "do_sigver_init"},
+    {ERR_FUNC(EVP_F_EVP_CIPHERINIT_EX), "EVP_CipherInit_ex"},
+    {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_COPY), "EVP_CIPHER_CTX_copy"},
+    {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_CTRL), "EVP_CIPHER_CTX_ctrl"},
+    {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH),
+     "EVP_CIPHER_CTX_set_key_length"},
+    {ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX), "EVP_DecryptFinal_ex"},
+    {ERR_FUNC(EVP_F_EVP_DECRYPTUPDATE), "EVP_DecryptUpdate"},
+    {ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"},
+    {ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"},
+    {ERR_FUNC(EVP_F_EVP_ENCRYPTUPDATE), "EVP_EncryptUpdate"},
+    {ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX), "EVP_MD_CTX_copy_ex"},
+    {ERR_FUNC(EVP_F_EVP_MD_SIZE), "EVP_MD_size"},
+    {ERR_FUNC(EVP_F_EVP_OPENINIT), "EVP_OpenInit"},
+    {ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD), "EVP_PBE_alg_add"},
+    {ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD_TYPE), "EVP_PBE_alg_add_type"},
+    {ERR_FUNC(EVP_F_EVP_PBE_CIPHERINIT), "EVP_PBE_CipherInit"},
+    {ERR_FUNC(EVP_F_EVP_PBE_SCRYPT), "EVP_PBE_scrypt"},
+    {ERR_FUNC(EVP_F_EVP_PKCS82PKEY), "EVP_PKCS82PKEY"},
+    {ERR_FUNC(EVP_F_EVP_PKEY2PKCS8), "EVP_PKEY2PKCS8"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_COPY_PARAMETERS), "EVP_PKEY_copy_parameters"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL), "EVP_PKEY_CTX_ctrl"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL_STR), "EVP_PKEY_CTX_ctrl_str"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_CTX_DUP), "EVP_PKEY_CTX_dup"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT), "EVP_PKEY_decrypt"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_INIT), "EVP_PKEY_decrypt_init"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_OLD), "EVP_PKEY_decrypt_old"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_DERIVE), "EVP_PKEY_derive"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_INIT), "EVP_PKEY_derive_init"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_SET_PEER), "EVP_PKEY_derive_set_peer"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT), "EVP_PKEY_encrypt"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_INIT), "EVP_PKEY_encrypt_init"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_OLD), "EVP_PKEY_encrypt_old"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_GET0_DH), "EVP_PKEY_get0_DH"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_GET0_DSA), "EVP_PKEY_get0_DSA"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_GET0_EC_KEY), "EVP_PKEY_get0_EC_KEY"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_GET0_HMAC), "EVP_PKEY_get0_hmac"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_GET0_RSA), "EVP_PKEY_get0_RSA"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN), "EVP_PKEY_keygen"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN_INIT), "EVP_PKEY_keygen_init"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_NEW), "EVP_PKEY_new"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN), "EVP_PKEY_paramgen"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN_INIT), "EVP_PKEY_paramgen_init"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_SIGN), "EVP_PKEY_sign"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_SIGN_INIT), "EVP_PKEY_sign_init"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY), "EVP_PKEY_verify"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_INIT), "EVP_PKEY_verify_init"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER), "EVP_PKEY_verify_recover"},
+    {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT),
+     "EVP_PKEY_verify_recover_init"},
+    {ERR_FUNC(EVP_F_EVP_SIGNFINAL), "EVP_SignFinal"},
+    {ERR_FUNC(EVP_F_EVP_VERIFYFINAL), "EVP_VerifyFinal"},
+    {ERR_FUNC(EVP_F_INT_CTX_NEW), "int_ctx_new"},
+    {ERR_FUNC(EVP_F_PKCS5_PBE_KEYIVGEN), "PKCS5_PBE_keyivgen"},
+    {ERR_FUNC(EVP_F_PKCS5_V2_PBE_KEYIVGEN), "PKCS5_v2_PBE_keyivgen"},
+    {ERR_FUNC(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN), "PKCS5_v2_PBKDF2_keyivgen"},
+    {ERR_FUNC(EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN), "PKCS5_v2_scrypt_keyivgen"},
+    {ERR_FUNC(EVP_F_PKEY_SET_TYPE), "pkey_set_type"},
+    {ERR_FUNC(EVP_F_RC2_MAGIC_TO_METH), "rc2_magic_to_meth"},
+    {ERR_FUNC(EVP_F_RC5_CTRL), "rc5_ctrl"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA EVP_str_reasons[] = {
+    {ERR_REASON(EVP_R_AES_KEY_SETUP_FAILED), "aes key setup failed"},
+    {ERR_REASON(EVP_R_BAD_DECRYPT), "bad decrypt"},
+    {ERR_REASON(EVP_R_BUFFER_TOO_SMALL), "buffer too small"},
+    {ERR_REASON(EVP_R_CAMELLIA_KEY_SETUP_FAILED),
+     "camellia key setup failed"},
+    {ERR_REASON(EVP_R_CIPHER_PARAMETER_ERROR), "cipher parameter error"},
+    {ERR_REASON(EVP_R_COMMAND_NOT_SUPPORTED), "command not supported"},
+    {ERR_REASON(EVP_R_COPY_ERROR), "copy error"},
+    {ERR_REASON(EVP_R_CTRL_NOT_IMPLEMENTED), "ctrl not implemented"},
+    {ERR_REASON(EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED),
+     "ctrl operation not implemented"},
+    {ERR_REASON(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH),
+     "data not multiple of block length"},
+    {ERR_REASON(EVP_R_DECODE_ERROR), "decode error"},
+    {ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES), "different key types"},
+    {ERR_REASON(EVP_R_DIFFERENT_PARAMETERS), "different parameters"},
+    {ERR_REASON(EVP_R_ERROR_LOADING_SECTION), "error loading section"},
+    {ERR_REASON(EVP_R_ERROR_SETTING_FIPS_MODE), "error setting fips mode"},
+    {ERR_REASON(EVP_R_EXPECTING_AN_HMAC_KEY), "expecting an hmac key"},
+    {ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY), "expecting an rsa key"},
+    {ERR_REASON(EVP_R_EXPECTING_A_DH_KEY), "expecting a dh key"},
+    {ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY), "expecting a dsa key"},
+    {ERR_REASON(EVP_R_EXPECTING_A_EC_KEY), "expecting a ec key"},
+    {ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"},
+    {ERR_REASON(EVP_R_ILLEGAL_SCRYPT_PARAMETERS),
+     "illegal scrypt parameters"},
+    {ERR_REASON(EVP_R_INITIALIZATION_ERROR), "initialization error"},
+    {ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED), "input not initialized"},
+    {ERR_REASON(EVP_R_INVALID_DIGEST), "invalid digest"},
+    {ERR_REASON(EVP_R_INVALID_FIPS_MODE), "invalid fips mode"},
+    {ERR_REASON(EVP_R_INVALID_KEY), "invalid key"},
+    {ERR_REASON(EVP_R_INVALID_KEY_LENGTH), "invalid key length"},
+    {ERR_REASON(EVP_R_INVALID_OPERATION), "invalid operation"},
+    {ERR_REASON(EVP_R_KEYGEN_FAILURE), "keygen failure"},
+    {ERR_REASON(EVP_R_MEMORY_LIMIT_EXCEEDED), "memory limit exceeded"},
+    {ERR_REASON(EVP_R_MESSAGE_DIGEST_IS_NULL), "message digest is null"},
+    {ERR_REASON(EVP_R_METHOD_NOT_SUPPORTED), "method not supported"},
+    {ERR_REASON(EVP_R_MISSING_PARAMETERS), "missing parameters"},
+    {ERR_REASON(EVP_R_NO_CIPHER_SET), "no cipher set"},
+    {ERR_REASON(EVP_R_NO_DEFAULT_DIGEST), "no default digest"},
+    {ERR_REASON(EVP_R_NO_DIGEST_SET), "no digest set"},
+    {ERR_REASON(EVP_R_NO_KEY_SET), "no key set"},
+    {ERR_REASON(EVP_R_NO_OPERATION_SET), "no operation set"},
+    {ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),
+     "operation not supported for this keytype"},
+    {ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED), "operaton not initialized"},
+    {ERR_REASON(EVP_R_PARTIALLY_OVERLAPPING),
+     "partially overlapping buffers"},
+    {ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR), "private key decode error"},
+    {ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR), "private key encode error"},
+    {ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"},
+    {ERR_REASON(EVP_R_UNKNOWN_CIPHER), "unknown cipher"},
+    {ERR_REASON(EVP_R_UNKNOWN_DIGEST), "unknown digest"},
+    {ERR_REASON(EVP_R_UNKNOWN_OPTION), "unknown option"},
+    {ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM), "unknown pbe algorithm"},
+    {ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"},
+    {ERR_REASON(EVP_R_UNSUPPORTED_CIPHER), "unsupported cipher"},
+    {ERR_REASON(EVP_R_UNSUPPORTED_KEYLENGTH), "unsupported keylength"},
+    {ERR_REASON(EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION),
+     "unsupported key derivation function"},
+    {ERR_REASON(EVP_R_UNSUPPORTED_KEY_SIZE), "unsupported key size"},
+    {ERR_REASON(EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS),
+     "unsupported number of rounds"},
+    {ERR_REASON(EVP_R_UNSUPPORTED_PRF), "unsupported prf"},
+    {ERR_REASON(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM),
+     "unsupported private key algorithm"},
+    {ERR_REASON(EVP_R_UNSUPPORTED_SALT_TYPE), "unsupported salt type"},
+    {ERR_REASON(EVP_R_WRAP_MODE_NOT_ALLOWED), "wrap mode not allowed"},
+    {ERR_REASON(EVP_R_WRONG_FINAL_BLOCK_LENGTH), "wrong final block length"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_EVP_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(EVP_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, EVP_str_functs);
+        ERR_load_strings(0, EVP_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_key.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_key.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_key.c	(revision 331)
@@ -0,0 +1,150 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/ui.h>
+
+#ifndef OPENSSL_NO_UI
+/* should be init to zeros. */
+static char prompt_string[80];
+
+void EVP_set_pw_prompt(const char *prompt)
+{
+    if (prompt == NULL)
+        prompt_string[0] = '\0';
+    else {
+        strncpy(prompt_string, prompt, 79);
+        prompt_string[79] = '\0';
+    }
+}
+
+char *EVP_get_pw_prompt(void)
+{
+    if (prompt_string[0] == '\0')
+        return (NULL);
+    else
+        return (prompt_string);
+}
+
+/*
+ * For historical reasons, the standard function for reading passwords is in
+ * the DES library -- if someone ever wants to disable DES, this function
+ * will fail
+ */
+int EVP_read_pw_string(char *buf, int len, const char *prompt, int verify)
+{
+    return EVP_read_pw_string_min(buf, 0, len, prompt, verify);
+}
+
+int EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt,
+                           int verify)
+{
+    int ret;
+    char buff[BUFSIZ];
+    UI *ui;
+
+    if ((prompt == NULL) && (prompt_string[0] != '\0'))
+        prompt = prompt_string;
+    ui = UI_new();
+    if (ui == NULL)
+        return -1;
+    UI_add_input_string(ui, prompt, 0, buf, min,
+                        (len >= BUFSIZ) ? BUFSIZ - 1 : len);
+    if (verify)
+        UI_add_verify_string(ui, prompt, 0,
+                             buff, min, (len >= BUFSIZ) ? BUFSIZ - 1 : len,
+                             buf);
+    ret = UI_process(ui);
+    UI_free(ui);
+    OPENSSL_cleanse(buff, BUFSIZ);
+    return ret;
+}
+#endif /* OPENSSL_NO_UI */
+
+int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
+                   const unsigned char *salt, const unsigned char *data,
+                   int datal, int count, unsigned char *key,
+                   unsigned char *iv)
+{
+    EVP_MD_CTX *c;
+    unsigned char md_buf[EVP_MAX_MD_SIZE];
+    int niv, nkey, addmd = 0;
+    unsigned int mds = 0, i;
+    int rv = 0;
+    nkey = EVP_CIPHER_key_length(type);
+    niv = EVP_CIPHER_iv_length(type);
+    OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH);
+    OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH);
+
+    if (data == NULL)
+        return (nkey);
+
+    c = EVP_MD_CTX_new();
+    if (c == NULL)
+        goto err;
+    for (;;) {
+        if (!EVP_DigestInit_ex(c, md, NULL))
+            goto err;
+        if (addmd++)
+            if (!EVP_DigestUpdate(c, &(md_buf[0]), mds))
+                goto err;
+        if (!EVP_DigestUpdate(c, data, datal))
+            goto err;
+        if (salt != NULL)
+            if (!EVP_DigestUpdate(c, salt, PKCS5_SALT_LEN))
+                goto err;
+        if (!EVP_DigestFinal_ex(c, &(md_buf[0]), &mds))
+            goto err;
+
+        for (i = 1; i < (unsigned int)count; i++) {
+            if (!EVP_DigestInit_ex(c, md, NULL))
+                goto err;
+            if (!EVP_DigestUpdate(c, &(md_buf[0]), mds))
+                goto err;
+            if (!EVP_DigestFinal_ex(c, &(md_buf[0]), &mds))
+                goto err;
+        }
+        i = 0;
+        if (nkey) {
+            for (;;) {
+                if (nkey == 0)
+                    break;
+                if (i == mds)
+                    break;
+                if (key != NULL)
+                    *(key++) = md_buf[i];
+                nkey--;
+                i++;
+            }
+        }
+        if (niv && (i != mds)) {
+            for (;;) {
+                if (niv == 0)
+                    break;
+                if (i == mds)
+                    break;
+                if (iv != NULL)
+                    *(iv++) = md_buf[i];
+                niv--;
+                i++;
+            }
+        }
+        if ((nkey == 0) && (niv == 0))
+            break;
+    }
+    rv = EVP_CIPHER_key_length(type);
+ err:
+    EVP_MD_CTX_free(c);
+    OPENSSL_cleanse(md_buf, sizeof(md_buf));
+    return rv;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_lib.c	(revision 331)
@@ -0,0 +1,497 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include "internal/evp_int.h"
+#include "evp_locl.h"
+
+int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+    int ret;
+
+    if (c->cipher->set_asn1_parameters != NULL)
+        ret = c->cipher->set_asn1_parameters(c, type);
+    else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) {
+        switch (EVP_CIPHER_CTX_mode(c)) {
+        case EVP_CIPH_WRAP_MODE:
+            if (EVP_CIPHER_CTX_nid(c) == NID_id_smime_alg_CMS3DESwrap)
+                ASN1_TYPE_set(type, V_ASN1_NULL, NULL);
+            ret = 1;
+            break;
+
+        case EVP_CIPH_GCM_MODE:
+        case EVP_CIPH_CCM_MODE:
+        case EVP_CIPH_XTS_MODE:
+        case EVP_CIPH_OCB_MODE:
+            ret = -1;
+            break;
+
+        default:
+            ret = EVP_CIPHER_set_asn1_iv(c, type);
+        }
+    } else
+        ret = -1;
+    return (ret);
+}
+
+int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+    int ret;
+
+    if (c->cipher->get_asn1_parameters != NULL)
+        ret = c->cipher->get_asn1_parameters(c, type);
+    else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) {
+        switch (EVP_CIPHER_CTX_mode(c)) {
+
+        case EVP_CIPH_WRAP_MODE:
+            ret = 1;
+            break;
+
+        case EVP_CIPH_GCM_MODE:
+        case EVP_CIPH_CCM_MODE:
+        case EVP_CIPH_XTS_MODE:
+        case EVP_CIPH_OCB_MODE:
+            ret = -1;
+            break;
+
+        default:
+            ret = EVP_CIPHER_get_asn1_iv(c, type);
+            break;
+        }
+    } else
+        ret = -1;
+    return (ret);
+}
+
+int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+    int i = 0;
+    unsigned int l;
+
+    if (type != NULL) {
+        l = EVP_CIPHER_CTX_iv_length(c);
+        OPENSSL_assert(l <= sizeof(c->iv));
+        i = ASN1_TYPE_get_octetstring(type, c->oiv, l);
+        if (i != (int)l)
+            return (-1);
+        else if (i > 0)
+            memcpy(c->iv, c->oiv, l);
+    }
+    return (i);
+}
+
+int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
+{
+    int i = 0;
+    unsigned int j;
+
+    if (type != NULL) {
+        j = EVP_CIPHER_CTX_iv_length(c);
+        OPENSSL_assert(j <= sizeof(c->iv));
+        i = ASN1_TYPE_set_octetstring(type, c->oiv, j);
+    }
+    return (i);
+}
+
+/* Convert the various cipher NIDs and dummies to a proper OID NID */
+int EVP_CIPHER_type(const EVP_CIPHER *ctx)
+{
+    int nid;
+    ASN1_OBJECT *otmp;
+    nid = EVP_CIPHER_nid(ctx);
+
+    switch (nid) {
+
+    case NID_rc2_cbc:
+    case NID_rc2_64_cbc:
+    case NID_rc2_40_cbc:
+
+        return NID_rc2_cbc;
+
+    case NID_rc4:
+    case NID_rc4_40:
+
+        return NID_rc4;
+
+    case NID_aes_128_cfb128:
+    case NID_aes_128_cfb8:
+    case NID_aes_128_cfb1:
+
+        return NID_aes_128_cfb128;
+
+    case NID_aes_192_cfb128:
+    case NID_aes_192_cfb8:
+    case NID_aes_192_cfb1:
+
+        return NID_aes_192_cfb128;
+
+    case NID_aes_256_cfb128:
+    case NID_aes_256_cfb8:
+    case NID_aes_256_cfb1:
+
+        return NID_aes_256_cfb128;
+
+    case NID_des_cfb64:
+    case NID_des_cfb8:
+    case NID_des_cfb1:
+
+        return NID_des_cfb64;
+
+    case NID_des_ede3_cfb64:
+    case NID_des_ede3_cfb8:
+    case NID_des_ede3_cfb1:
+
+        return NID_des_cfb64;
+
+    default:
+        /* Check it has an OID and it is valid */
+        otmp = OBJ_nid2obj(nid);
+        if (OBJ_get0_data(otmp) == NULL)
+            nid = NID_undef;
+        ASN1_OBJECT_free(otmp);
+        return nid;
+    }
+}
+
+int EVP_CIPHER_block_size(const EVP_CIPHER *e)
+{
+    return e->block_size;
+}
+
+int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx)
+{
+    return ctx->cipher->block_size;
+}
+
+int EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *e)
+{
+    return e->ctx_size;
+}
+
+int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+               const unsigned char *in, unsigned int inl)
+{
+    return ctx->cipher->do_cipher(ctx, out, in, inl);
+}
+
+const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx)
+{
+    return ctx->cipher;
+}
+
+int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx)
+{
+    return ctx->encrypt;
+}
+
+unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher)
+{
+    return cipher->flags;
+}
+
+void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
+{
+    return ctx->app_data;
+}
+
+void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data)
+{
+    ctx->app_data = data;
+}
+
+void *EVP_CIPHER_CTX_get_cipher_data(const EVP_CIPHER_CTX *ctx)
+{
+    return ctx->cipher_data;
+}
+
+void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data)
+{
+    void *old_cipher_data;
+
+    old_cipher_data = ctx->cipher_data;
+    ctx->cipher_data = cipher_data;
+
+    return old_cipher_data;
+}
+
+int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher)
+{
+    return cipher->iv_len;
+}
+
+int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
+{
+    return ctx->cipher->iv_len;
+}
+
+const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx)
+{
+    return ctx->oiv;
+}
+
+const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx)
+{
+    return ctx->iv;
+}
+
+unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx)
+{
+    return ctx->iv;
+}
+
+unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx)
+{
+    return ctx->buf;
+}
+
+int EVP_CIPHER_CTX_num(const EVP_CIPHER_CTX *ctx)
+{
+    return ctx->num;
+}
+
+void EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num)
+{
+    ctx->num = num;
+}
+
+int EVP_CIPHER_key_length(const EVP_CIPHER *cipher)
+{
+    return cipher->key_len;
+}
+
+int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx)
+{
+    return ctx->key_len;
+}
+
+int EVP_CIPHER_nid(const EVP_CIPHER *cipher)
+{
+    return cipher->nid;
+}
+
+int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
+{
+    return ctx->cipher->nid;
+}
+
+int EVP_MD_block_size(const EVP_MD *md)
+{
+    return md->block_size;
+}
+
+int EVP_MD_type(const EVP_MD *md)
+{
+    return md->type;
+}
+
+int EVP_MD_pkey_type(const EVP_MD *md)
+{
+    return md->pkey_type;
+}
+
+int EVP_MD_size(const EVP_MD *md)
+{
+    if (!md) {
+        EVPerr(EVP_F_EVP_MD_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL);
+        return -1;
+    }
+    return md->md_size;
+}
+
+unsigned long EVP_MD_flags(const EVP_MD *md)
+{
+    return md->flags;
+}
+
+EVP_MD *EVP_MD_meth_new(int md_type, int pkey_type)
+{
+    EVP_MD *md = OPENSSL_zalloc(sizeof(*md));
+
+    if (md != NULL) {
+        md->type = md_type;
+        md->pkey_type = pkey_type;
+    }
+    return md;
+}
+EVP_MD *EVP_MD_meth_dup(const EVP_MD *md)
+{
+    EVP_MD *to = EVP_MD_meth_new(md->type, md->pkey_type);
+
+    if (to != NULL)
+        memcpy(to, md, sizeof(*to));
+    return to;
+}
+void EVP_MD_meth_free(EVP_MD *md)
+{
+    OPENSSL_free(md);
+}
+int EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize)
+{
+    md->block_size = blocksize;
+    return 1;
+}
+int EVP_MD_meth_set_result_size(EVP_MD *md, int resultsize)
+{
+    md->md_size = resultsize;
+    return 1;
+}
+int EVP_MD_meth_set_app_datasize(EVP_MD *md, int datasize)
+{
+    md->ctx_size = datasize;
+    return 1;
+}
+int EVP_MD_meth_set_flags(EVP_MD *md, unsigned long flags)
+{
+    md->flags = flags;
+    return 1;
+}
+int EVP_MD_meth_set_init(EVP_MD *md, int (*init)(EVP_MD_CTX *ctx))
+{
+    md->init = init;
+    return 1;
+}
+int EVP_MD_meth_set_update(EVP_MD *md, int (*update)(EVP_MD_CTX *ctx,
+                                                     const void *data,
+                                                     size_t count))
+{
+    md->update = update;
+    return 1;
+}
+int EVP_MD_meth_set_final(EVP_MD *md, int (*final)(EVP_MD_CTX *ctx,
+                                                   unsigned char *md))
+{
+    md->final = final;
+    return 1;
+}
+int EVP_MD_meth_set_copy(EVP_MD *md, int (*copy)(EVP_MD_CTX *to,
+                                                 const EVP_MD_CTX *from))
+{
+    md->copy = copy;
+    return 1;
+}
+int EVP_MD_meth_set_cleanup(EVP_MD *md, int (*cleanup)(EVP_MD_CTX *ctx))
+{
+    md->cleanup = cleanup;
+    return 1;
+}
+int EVP_MD_meth_set_ctrl(EVP_MD *md, int (*ctrl)(EVP_MD_CTX *ctx, int cmd,
+                                                 int p1, void *p2))
+{
+    md->md_ctrl = ctrl;
+    return 1;
+}
+
+int EVP_MD_meth_get_input_blocksize(const EVP_MD *md)
+{
+    return md->block_size;
+}
+int EVP_MD_meth_get_result_size(const EVP_MD *md)
+{
+    return md->md_size;
+}
+int EVP_MD_meth_get_app_datasize(const EVP_MD *md)
+{
+    return md->ctx_size;
+}
+unsigned long EVP_MD_meth_get_flags(const EVP_MD *md)
+{
+    return md->flags;
+}
+int (*EVP_MD_meth_get_init(const EVP_MD *md))(EVP_MD_CTX *ctx)
+{
+    return md->init;
+}
+int (*EVP_MD_meth_get_update(const EVP_MD *md))(EVP_MD_CTX *ctx,
+                                                const void *data,
+                                                size_t count)
+{
+    return md->update;
+}
+int (*EVP_MD_meth_get_final(const EVP_MD *md))(EVP_MD_CTX *ctx,
+                                               unsigned char *md)
+{
+    return md->final;
+}
+int (*EVP_MD_meth_get_copy(const EVP_MD *md))(EVP_MD_CTX *to,
+                                              const EVP_MD_CTX *from)
+{
+    return md->copy;
+}
+int (*EVP_MD_meth_get_cleanup(const EVP_MD *md))(EVP_MD_CTX *ctx)
+{
+    return md->cleanup;
+}
+int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd,
+                                              int p1, void *p2)
+{
+    return md->md_ctrl;
+}
+
+const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx)
+{
+    if (!ctx)
+        return NULL;
+    return ctx->digest;
+}
+
+EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx)
+{
+    return ctx->pctx;
+}
+
+void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx)
+{
+    return ctx->md_data;
+}
+
+int (*EVP_MD_CTX_update_fn(EVP_MD_CTX *ctx))(EVP_MD_CTX *ctx,
+                                             const void *data, size_t count)
+{
+    return ctx->update;
+}
+
+void EVP_MD_CTX_set_update_fn(EVP_MD_CTX *ctx,
+                              int (*update) (EVP_MD_CTX *ctx,
+                                             const void *data, size_t count))
+{
+    ctx->update = update;
+}
+
+void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags)
+{
+    ctx->flags |= flags;
+}
+
+void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags)
+{
+    ctx->flags &= ~flags;
+}
+
+int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags)
+{
+    return (ctx->flags & flags);
+}
+
+void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags)
+{
+    ctx->flags |= flags;
+}
+
+void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags)
+{
+    ctx->flags &= ~flags;
+}
+
+int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags)
+{
+    return (ctx->flags & flags);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_locl.h	(revision 331)
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2000-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
+ */
+
+/* EVP_MD_CTX related stuff */
+
+struct evp_md_ctx_st {
+    const EVP_MD *digest;
+    ENGINE *engine;             /* functional reference if 'digest' is
+                                 * ENGINE-provided */
+    unsigned long flags;
+    void *md_data;
+    /* Public key context for sign/verify */
+    EVP_PKEY_CTX *pctx;
+    /* Update function: usually copied from EVP_MD */
+    int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
+} /* EVP_MD_CTX */ ;
+
+struct evp_cipher_ctx_st {
+    const EVP_CIPHER *cipher;
+    ENGINE *engine;             /* functional reference if 'cipher' is
+                                 * ENGINE-provided */
+    int encrypt;                /* encrypt or decrypt */
+    int buf_len;                /* number we have left */
+    unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */
+    unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */
+    unsigned char buf[EVP_MAX_BLOCK_LENGTH]; /* saved partial block */
+    int num;                    /* used by cfb/ofb/ctr mode */
+    /* FIXME: Should this even exist? It appears unused */
+    void *app_data;             /* application stuff */
+    int key_len;                /* May change for variable length cipher */
+    unsigned long flags;        /* Various flags */
+    void *cipher_data;          /* per EVP data */
+    int final_used;
+    int block_mask;
+    unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */
+} /* EVP_CIPHER_CTX */ ;
+
+int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
+                             int passlen, ASN1_TYPE *param,
+                             const EVP_CIPHER *c, const EVP_MD *md,
+                             int en_de);
+
+struct evp_Encode_Ctx_st {
+    /* number saved in a partial encode/decode */
+    int num;
+    /*
+     * The length is either the output line length (in input bytes) or the
+     * shortest input line length that is ok.  Once decoding begins, the
+     * length is adjusted up each time a longer line is decoded
+     */
+    int length;
+    /* data to encode */
+    unsigned char enc_data[80];
+    /* number read on current line */
+    int line_num;
+    int expect_nl;
+};
+
+typedef struct evp_pbe_st EVP_PBE_CTL;
+DEFINE_STACK_OF(EVP_PBE_CTL)
+
+int is_partially_overlapping(const void *ptr1, const void *ptr2, int len);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_pbe.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_pbe.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_pbe.c	(revision 331)
@@ -0,0 +1,259 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/pkcs12.h>
+#include <openssl/x509.h>
+#include "evp_locl.h"
+
+/* Password based encryption (PBE) functions */
+
+/* Setup a cipher context from a PBE algorithm */
+
+struct evp_pbe_st {
+    int pbe_type;
+    int pbe_nid;
+    int cipher_nid;
+    int md_nid;
+    EVP_PBE_KEYGEN *keygen;
+};
+
+static STACK_OF(EVP_PBE_CTL) *pbe_algs;
+
+static const EVP_PBE_CTL builtin_pbe[] = {
+    {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC,
+     NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen},
+    {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC,
+     NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen},
+    {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC,
+     NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen},
+
+    {EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen},
+
+    {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4,
+     NID_rc4, NID_sha1, PKCS12_PBE_keyivgen},
+    {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4,
+     NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen},
+    {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
+     NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen},
+    {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC,
+     NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen},
+    {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC,
+     NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen},
+    {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC,
+     NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen},
+
+    {EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen},
+
+    {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC,
+     NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen},
+    {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC,
+     NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen},
+    {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC,
+     NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen},
+
+    {EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0},
+    {EVP_PBE_TYPE_PRF, NID_hmacWithMD5, -1, NID_md5, 0},
+    {EVP_PBE_TYPE_PRF, NID_hmacWithSHA224, -1, NID_sha224, 0},
+    {EVP_PBE_TYPE_PRF, NID_hmacWithSHA256, -1, NID_sha256, 0},
+    {EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0},
+    {EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0},
+    {EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0},
+    {EVP_PBE_TYPE_PRF, NID_id_tc26_hmac_gost_3411_2012_256, -1,
+     NID_id_GostR3411_2012_256, 0},
+    {EVP_PBE_TYPE_PRF, NID_id_tc26_hmac_gost_3411_2012_512, -1,
+     NID_id_GostR3411_2012_512, 0},
+    {EVP_PBE_TYPE_KDF, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen},
+#ifndef OPENSSL_NO_SCRYPT
+    {EVP_PBE_TYPE_KDF, NID_id_scrypt, -1, -1, PKCS5_v2_scrypt_keyivgen}
+#endif
+};
+
+int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
+                       ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de)
+{
+    const EVP_CIPHER *cipher;
+    const EVP_MD *md;
+    int cipher_nid, md_nid;
+    EVP_PBE_KEYGEN *keygen;
+
+    if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj),
+                      &cipher_nid, &md_nid, &keygen)) {
+        char obj_tmp[80];
+        EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_PBE_ALGORITHM);
+        if (!pbe_obj)
+            OPENSSL_strlcpy(obj_tmp, "NULL", sizeof obj_tmp);
+        else
+            i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj);
+        ERR_add_error_data(2, "TYPE=", obj_tmp);
+        return 0;
+    }
+
+    if (!pass)
+        passlen = 0;
+    else if (passlen == -1)
+        passlen = strlen(pass);
+
+    if (cipher_nid == -1)
+        cipher = NULL;
+    else {
+        cipher = EVP_get_cipherbynid(cipher_nid);
+        if (!cipher) {
+            EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_CIPHER);
+            return 0;
+        }
+    }
+
+    if (md_nid == -1)
+        md = NULL;
+    else {
+        md = EVP_get_digestbynid(md_nid);
+        if (!md) {
+            EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_DIGEST);
+            return 0;
+        }
+    }
+
+    if (!keygen(ctx, pass, passlen, param, cipher, md, en_de)) {
+        EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_KEYGEN_FAILURE);
+        return 0;
+    }
+    return 1;
+}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
+
+static int pbe2_cmp(const EVP_PBE_CTL *pbe1, const EVP_PBE_CTL *pbe2)
+{
+    int ret = pbe1->pbe_type - pbe2->pbe_type;
+    if (ret)
+        return ret;
+    else
+        return pbe1->pbe_nid - pbe2->pbe_nid;
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2);
+
+static int pbe_cmp(const EVP_PBE_CTL *const *a, const EVP_PBE_CTL *const *b)
+{
+    int ret = (*a)->pbe_type - (*b)->pbe_type;
+    if (ret)
+        return ret;
+    else
+        return (*a)->pbe_nid - (*b)->pbe_nid;
+}
+
+/* Add a PBE algorithm */
+
+int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid,
+                         int md_nid, EVP_PBE_KEYGEN *keygen)
+{
+    EVP_PBE_CTL *pbe_tmp;
+
+    if (pbe_algs == NULL) {
+        pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp);
+        if (pbe_algs == NULL)
+            goto err;
+    }
+
+    if ((pbe_tmp = OPENSSL_malloc(sizeof(*pbe_tmp))) == NULL)
+        goto err;
+
+    pbe_tmp->pbe_type = pbe_type;
+    pbe_tmp->pbe_nid = pbe_nid;
+    pbe_tmp->cipher_nid = cipher_nid;
+    pbe_tmp->md_nid = md_nid;
+    pbe_tmp->keygen = keygen;
+
+    if (!sk_EVP_PBE_CTL_push(pbe_algs, pbe_tmp)) {
+        OPENSSL_free(pbe_tmp);
+        goto err;
+    }
+    return 1;
+
+ err:
+    EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE, ERR_R_MALLOC_FAILURE);
+    return 0;
+}
+
+int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
+                    EVP_PBE_KEYGEN *keygen)
+{
+    int cipher_nid, md_nid;
+
+    if (cipher)
+        cipher_nid = EVP_CIPHER_nid(cipher);
+    else
+        cipher_nid = -1;
+    if (md)
+        md_nid = EVP_MD_type(md);
+    else
+        md_nid = -1;
+
+    return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid,
+                                cipher_nid, md_nid, keygen);
+}
+
+int EVP_PBE_find(int type, int pbe_nid,
+                 int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen)
+{
+    EVP_PBE_CTL *pbetmp = NULL, pbelu;
+    int i;
+    if (pbe_nid == NID_undef)
+        return 0;
+
+    pbelu.pbe_type = type;
+    pbelu.pbe_nid = pbe_nid;
+
+    if (pbe_algs) {
+        i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu);
+        if (i != -1)
+            pbetmp = sk_EVP_PBE_CTL_value(pbe_algs, i);
+    }
+    if (pbetmp == NULL) {
+        pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe, OSSL_NELEM(builtin_pbe));
+    }
+    if (pbetmp == NULL)
+        return 0;
+    if (pcnid)
+        *pcnid = pbetmp->cipher_nid;
+    if (pmnid)
+        *pmnid = pbetmp->md_nid;
+    if (pkeygen)
+        *pkeygen = pbetmp->keygen;
+    return 1;
+}
+
+static void free_evp_pbe_ctl(EVP_PBE_CTL *pbe)
+{
+    OPENSSL_free(pbe);
+}
+
+void EVP_PBE_cleanup(void)
+{
+    sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl);
+    pbe_algs = NULL;
+}
+
+int EVP_PBE_get(int *ptype, int *ppbe_nid, size_t num)
+{
+    const EVP_PBE_CTL *tpbe;
+
+    if (num >= OSSL_NELEM(builtin_pbe))
+        return 0;
+
+    tpbe = builtin_pbe + num;
+    if (ptype)
+        *ptype = tpbe->pbe_type;
+    if (ppbe_nid)
+        *ppbe_nid = tpbe->pbe_nid;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_pkey.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_pkey.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/evp_pkey.c	(revision 331)
@@ -0,0 +1,150 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include <stdlib.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/rand.h>
+#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
+#include "internal/x509_int.h"
+
+/* Extract a private key from a PKCS8 structure */
+
+EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8)
+{
+    EVP_PKEY *pkey = NULL;
+    const ASN1_OBJECT *algoid;
+    char obj_tmp[80];
+
+    if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8))
+        return NULL;
+
+    if ((pkey = EVP_PKEY_new()) == NULL) {
+        EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) {
+        EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
+        i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
+        ERR_add_error_data(2, "TYPE=", obj_tmp);
+        goto error;
+    }
+
+    if (pkey->ameth->priv_decode) {
+        if (!pkey->ameth->priv_decode(pkey, p8)) {
+            EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_PRIVATE_KEY_DECODE_ERROR);
+            goto error;
+        }
+    } else {
+        EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED);
+        goto error;
+    }
+
+    return pkey;
+
+ error:
+    EVP_PKEY_free(pkey);
+    return NULL;
+}
+
+/* Turn a private key into a PKCS8 structure */
+
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
+{
+    PKCS8_PRIV_KEY_INFO *p8 = PKCS8_PRIV_KEY_INFO_new();
+    if (p8  == NULL) {
+        EVPerr(EVP_F_EVP_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    if (pkey->ameth) {
+        if (pkey->ameth->priv_encode) {
+            if (!pkey->ameth->priv_encode(p8, pkey)) {
+                EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_PRIVATE_KEY_ENCODE_ERROR);
+                goto error;
+            }
+        } else {
+            EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_METHOD_NOT_SUPPORTED);
+            goto error;
+        }
+    } else {
+        EVPerr(EVP_F_EVP_PKEY2PKCS8, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
+        goto error;
+    }
+    RAND_add(p8->pkey->data, p8->pkey->length, 0.0);
+    return p8;
+ error:
+    PKCS8_PRIV_KEY_INFO_free(p8);
+    return NULL;
+}
+
+/* EVP_PKEY attribute functions */
+
+int EVP_PKEY_get_attr_count(const EVP_PKEY *key)
+{
+    return X509at_get_attr_count(key->attributes);
+}
+
+int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos)
+{
+    return X509at_get_attr_by_NID(key->attributes, nid, lastpos);
+}
+
+int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, const ASN1_OBJECT *obj,
+                             int lastpos)
+{
+    return X509at_get_attr_by_OBJ(key->attributes, obj, lastpos);
+}
+
+X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc)
+{
+    return X509at_get_attr(key->attributes, loc);
+}
+
+X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc)
+{
+    return X509at_delete_attr(key->attributes, loc);
+}
+
+int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr)
+{
+    if (X509at_add1_attr(&key->attributes, attr))
+        return 1;
+    return 0;
+}
+
+int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
+                              const ASN1_OBJECT *obj, int type,
+                              const unsigned char *bytes, int len)
+{
+    if (X509at_add1_attr_by_OBJ(&key->attributes, obj, type, bytes, len))
+        return 1;
+    return 0;
+}
+
+int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
+                              int nid, int type,
+                              const unsigned char *bytes, int len)
+{
+    if (X509at_add1_attr_by_NID(&key->attributes, nid, type, bytes, len))
+        return 1;
+    return 0;
+}
+
+int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
+                              const char *attrname, int type,
+                              const unsigned char *bytes, int len)
+{
+    if (X509at_add1_attr_by_txt(&key->attributes, attrname, type, bytes, len))
+        return 1;
+    return 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_md2.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_md2.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_md2.c	(revision 331)
@@ -0,0 +1,56 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+
+#ifndef OPENSSL_NO_MD2
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/md2.h>
+# include <openssl/rsa.h>
+
+#include "internal/evp_int.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+    return MD2_Init(EVP_MD_CTX_md_data(ctx));
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+    return MD2_Update(EVP_MD_CTX_md_data(ctx), data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+    return MD2_Final(md, EVP_MD_CTX_md_data(ctx));
+}
+
+static const EVP_MD md2_md = {
+    NID_md2,
+    NID_md2WithRSAEncryption,
+    MD2_DIGEST_LENGTH,
+    0,
+    init,
+    update,
+    final,
+    NULL,
+    NULL,
+    MD2_BLOCK,
+    sizeof(EVP_MD *) + sizeof(MD2_CTX),
+};
+
+const EVP_MD *EVP_md2(void)
+{
+    return &md2_md;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_md4.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_md4.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_md4.c	(revision 331)
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+
+#ifndef OPENSSL_NO_MD4
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/md4.h>
+# include <openssl/rsa.h>
+# include "internal/evp_int.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+    return MD4_Init(EVP_MD_CTX_md_data(ctx));
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+    return MD4_Update(EVP_MD_CTX_md_data(ctx), data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+    return MD4_Final(md, EVP_MD_CTX_md_data(ctx));
+}
+
+static const EVP_MD md4_md = {
+    NID_md4,
+    NID_md4WithRSAEncryption,
+    MD4_DIGEST_LENGTH,
+    0,
+    init,
+    update,
+    final,
+    NULL,
+    NULL,
+    MD4_CBLOCK,
+    sizeof(EVP_MD *) + sizeof(MD4_CTX),
+};
+
+const EVP_MD *EVP_md4(void)
+{
+    return (&md4_md);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_md5.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_md5.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_md5.c	(revision 331)
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+
+#ifndef OPENSSL_NO_MD5
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/md5.h>
+# include <openssl/rsa.h>
+# include "internal/evp_int.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+    return MD5_Init(EVP_MD_CTX_md_data(ctx));
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+    return MD5_Update(EVP_MD_CTX_md_data(ctx), data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+    return MD5_Final(md, EVP_MD_CTX_md_data(ctx));
+}
+
+static const EVP_MD md5_md = {
+    NID_md5,
+    NID_md5WithRSAEncryption,
+    MD5_DIGEST_LENGTH,
+    0,
+    init,
+    update,
+    final,
+    NULL,
+    NULL,
+    MD5_CBLOCK,
+    sizeof(EVP_MD *) + sizeof(MD5_CTX),
+};
+
+const EVP_MD *EVP_md5(void)
+{
+    return (&md5_md);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_md5_sha1.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_md5_sha1.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_md5_sha1.c	(revision 331)
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2015-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
+ */
+
+#if !defined(OPENSSL_NO_MD5)
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/md5.h>
+# include <openssl/sha.h>
+# include "internal/cryptlib.h"
+# include "internal/evp_int.h"
+# include <openssl/rsa.h>
+
+struct md5_sha1_ctx {
+    MD5_CTX md5;
+    SHA_CTX sha1;
+};
+
+static int init(EVP_MD_CTX *ctx)
+{
+    struct md5_sha1_ctx *mctx = EVP_MD_CTX_md_data(ctx);
+    if (!MD5_Init(&mctx->md5))
+        return 0;
+    return SHA1_Init(&mctx->sha1);
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+    struct md5_sha1_ctx *mctx = EVP_MD_CTX_md_data(ctx);
+    if (!MD5_Update(&mctx->md5, data, count))
+        return 0;
+    return SHA1_Update(&mctx->sha1, data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+    struct md5_sha1_ctx *mctx = EVP_MD_CTX_md_data(ctx);
+    if (!MD5_Final(md, &mctx->md5))
+        return 0;
+    return SHA1_Final(md + MD5_DIGEST_LENGTH, &mctx->sha1);
+}
+
+static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms)
+{
+    unsigned char padtmp[48];
+    unsigned char md5tmp[MD5_DIGEST_LENGTH];
+    unsigned char sha1tmp[SHA_DIGEST_LENGTH];
+    struct md5_sha1_ctx *mctx;
+
+    if (cmd != EVP_CTRL_SSL3_MASTER_SECRET)
+        return -2;
+
+    if (ctx == NULL)
+        return 0;
+
+    mctx = EVP_MD_CTX_md_data(ctx);
+
+    /* SSLv3 client auth handling: see RFC-6101 5.6.8 */
+    if (mslen != 48)
+        return 0;
+
+    /* At this point hash contains all handshake messages, update
+     * with master secret and pad_1.
+     */
+
+    if (update(ctx, ms, mslen) <= 0)
+        return 0;
+
+    /* Set padtmp to pad_1 value */
+    memset(padtmp, 0x36, sizeof(padtmp));
+
+    if (!MD5_Update(&mctx->md5, padtmp, sizeof(padtmp)))
+        return 0;
+
+    if (!MD5_Final(md5tmp, &mctx->md5))
+        return 0;
+
+    if (!SHA1_Update(&mctx->sha1, padtmp, 40))
+        return 0;
+
+    if (!SHA1_Final(sha1tmp, &mctx->sha1))
+        return 0;
+
+    /* Reinitialise context */
+
+    if (!init(ctx))
+        return 0;
+
+    if (update(ctx, ms, mslen) <= 0)
+        return 0;
+
+    /* Set padtmp to pad_2 value */
+    memset(padtmp, 0x5c, sizeof(padtmp));
+
+    if (!MD5_Update(&mctx->md5, padtmp, sizeof(padtmp)))
+        return 0;
+
+    if (!MD5_Update(&mctx->md5, md5tmp, sizeof(md5tmp)))
+        return 0;
+
+    if (!SHA1_Update(&mctx->sha1, padtmp, 40))
+        return 0;
+
+    if (!SHA1_Update(&mctx->sha1, sha1tmp, sizeof(sha1tmp)))
+        return 0;
+
+    /* Now when ctx is finalised it will return the SSL v3 hash value */
+
+    OPENSSL_cleanse(md5tmp, sizeof(md5tmp));
+    OPENSSL_cleanse(sha1tmp, sizeof(sha1tmp));
+
+    return 1;
+
+}
+
+static const EVP_MD md5_sha1_md = {
+    NID_md5_sha1,
+    NID_md5_sha1,
+    MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH,
+    0,
+    init,
+    update,
+    final,
+    NULL,
+    NULL,
+    MD5_CBLOCK,
+    sizeof(EVP_MD *) + sizeof(struct md5_sha1_ctx),
+    ctrl
+};
+
+const EVP_MD *EVP_md5_sha1(void)
+{
+    return &md5_sha1_md;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_mdc2.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_mdc2.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_mdc2.c	(revision 331)
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+
+#ifndef OPENSSL_NO_MDC2
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/mdc2.h>
+# include <openssl/rsa.h>
+# include "internal/evp_int.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+    return MDC2_Init(EVP_MD_CTX_md_data(ctx));
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+    return MDC2_Update(EVP_MD_CTX_md_data(ctx), data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+    return MDC2_Final(md, EVP_MD_CTX_md_data(ctx));
+}
+
+static const EVP_MD mdc2_md = {
+    NID_mdc2,
+    NID_mdc2WithRSA,
+    MDC2_DIGEST_LENGTH,
+    0,
+    init,
+    update,
+    final,
+    NULL,
+    NULL,
+    MDC2_BLOCK,
+    sizeof(EVP_MD *) + sizeof(MDC2_CTX),
+};
+
+const EVP_MD *EVP_mdc2(void)
+{
+    return (&mdc2_md);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_null.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_null.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_null.c	(revision 331)
@@ -0,0 +1,49 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include "internal/evp_int.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+    return 1;
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+    return 1;
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+    return 1;
+}
+
+static const EVP_MD null_md = {
+    NID_undef,
+    NID_undef,
+    0,
+    0,
+    init,
+    update,
+    final,
+    NULL,
+    NULL,
+    0,
+    sizeof(EVP_MD *),
+};
+
+const EVP_MD *EVP_md_null(void)
+{
+    return (&null_md);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_ripemd.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_ripemd.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_ripemd.c	(revision 331)
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+
+#ifndef OPENSSL_NO_RMD160
+
+# include <openssl/ripemd.h>
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/rsa.h>
+# include "internal/evp_int.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+    return RIPEMD160_Init(EVP_MD_CTX_md_data(ctx));
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+    return RIPEMD160_Update(EVP_MD_CTX_md_data(ctx), data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+    return RIPEMD160_Final(md, EVP_MD_CTX_md_data(ctx));
+}
+
+static const EVP_MD ripemd160_md = {
+    NID_ripemd160,
+    NID_ripemd160WithRSA,
+    RIPEMD160_DIGEST_LENGTH,
+    0,
+    init,
+    update,
+    final,
+    NULL,
+    NULL,
+    RIPEMD160_CBLOCK,
+    sizeof(EVP_MD *) + sizeof(RIPEMD160_CTX),
+};
+
+const EVP_MD *EVP_ripemd160(void)
+{
+    return (&ripemd160_md);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_sha1.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_sha1.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_sha1.c	(revision 331)
@@ -0,0 +1,233 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/sha.h>
+#include <openssl/rsa.h>
+#include "internal/evp_int.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+    return SHA1_Init(EVP_MD_CTX_md_data(ctx));
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+    return SHA1_Update(EVP_MD_CTX_md_data(ctx), data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+    return SHA1_Final(md, EVP_MD_CTX_md_data(ctx));
+}
+
+static int ctrl(EVP_MD_CTX *ctx, int cmd, int mslen, void *ms)
+{
+    unsigned char padtmp[40];
+    unsigned char sha1tmp[SHA_DIGEST_LENGTH];
+
+    SHA_CTX *sha1;
+
+    if (cmd != EVP_CTRL_SSL3_MASTER_SECRET)
+        return -2;
+
+    if (ctx == NULL)
+        return 0;
+
+    sha1 = EVP_MD_CTX_md_data(ctx);
+
+    /* SSLv3 client auth handling: see RFC-6101 5.6.8 */
+    if (mslen != 48)
+        return 0;
+
+    /* At this point hash contains all handshake messages, update
+     * with master secret and pad_1.
+     */
+
+    if (SHA1_Update(sha1, ms, mslen) <= 0)
+        return 0;
+
+    /* Set padtmp to pad_1 value */
+    memset(padtmp, 0x36, sizeof(padtmp));
+
+    if (!SHA1_Update(sha1, padtmp, sizeof(padtmp)))
+        return 0;
+
+    if (!SHA1_Final(sha1tmp, sha1))
+        return 0;
+
+    /* Reinitialise context */
+
+    if (!SHA1_Init(sha1))
+        return 0;
+
+    if (SHA1_Update(sha1, ms, mslen) <= 0)
+        return 0;
+
+    /* Set padtmp to pad_2 value */
+    memset(padtmp, 0x5c, sizeof(padtmp));
+
+    if (!SHA1_Update(sha1, padtmp, sizeof(padtmp)))
+        return 0;
+
+    if (!SHA1_Update(sha1, sha1tmp, sizeof(sha1tmp)))
+        return 0;
+
+    /* Now when ctx is finalised it will return the SSL v3 hash value */
+    OPENSSL_cleanse(sha1tmp, sizeof(sha1tmp));
+
+    return 1;
+
+}
+
+static const EVP_MD sha1_md = {
+    NID_sha1,
+    NID_sha1WithRSAEncryption,
+    SHA_DIGEST_LENGTH,
+    EVP_MD_FLAG_DIGALGID_ABSENT,
+    init,
+    update,
+    final,
+    NULL,
+    NULL,
+    SHA_CBLOCK,
+    sizeof(EVP_MD *) + sizeof(SHA_CTX),
+    ctrl
+};
+
+const EVP_MD *EVP_sha1(void)
+{
+    return (&sha1_md);
+}
+
+static int init224(EVP_MD_CTX *ctx)
+{
+    return SHA224_Init(EVP_MD_CTX_md_data(ctx));
+}
+
+static int init256(EVP_MD_CTX *ctx)
+{
+    return SHA256_Init(EVP_MD_CTX_md_data(ctx));
+}
+
+/*
+ * Even though there're separate SHA224_[Update|Final], we call
+ * SHA256 functions even in SHA224 context. This is what happens
+ * there anyway, so we can spare few CPU cycles:-)
+ */
+static int update256(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+    return SHA256_Update(EVP_MD_CTX_md_data(ctx), data, count);
+}
+
+static int final256(EVP_MD_CTX *ctx, unsigned char *md)
+{
+    return SHA256_Final(md, EVP_MD_CTX_md_data(ctx));
+}
+
+static const EVP_MD sha224_md = {
+    NID_sha224,
+    NID_sha224WithRSAEncryption,
+    SHA224_DIGEST_LENGTH,
+    EVP_MD_FLAG_DIGALGID_ABSENT,
+    init224,
+    update256,
+    final256,
+    NULL,
+    NULL,
+    SHA256_CBLOCK,
+    sizeof(EVP_MD *) + sizeof(SHA256_CTX),
+};
+
+const EVP_MD *EVP_sha224(void)
+{
+    return (&sha224_md);
+}
+
+static const EVP_MD sha256_md = {
+    NID_sha256,
+    NID_sha256WithRSAEncryption,
+    SHA256_DIGEST_LENGTH,
+    EVP_MD_FLAG_DIGALGID_ABSENT,
+    init256,
+    update256,
+    final256,
+    NULL,
+    NULL,
+    SHA256_CBLOCK,
+    sizeof(EVP_MD *) + sizeof(SHA256_CTX),
+};
+
+const EVP_MD *EVP_sha256(void)
+{
+    return (&sha256_md);
+}
+
+static int init384(EVP_MD_CTX *ctx)
+{
+    return SHA384_Init(EVP_MD_CTX_md_data(ctx));
+}
+
+static int init512(EVP_MD_CTX *ctx)
+{
+    return SHA512_Init(EVP_MD_CTX_md_data(ctx));
+}
+
+/* See comment in SHA224/256 section */
+static int update512(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+    return SHA512_Update(EVP_MD_CTX_md_data(ctx), data, count);
+}
+
+static int final512(EVP_MD_CTX *ctx, unsigned char *md)
+{
+    return SHA512_Final(md, EVP_MD_CTX_md_data(ctx));
+}
+
+static const EVP_MD sha384_md = {
+    NID_sha384,
+    NID_sha384WithRSAEncryption,
+    SHA384_DIGEST_LENGTH,
+    EVP_MD_FLAG_DIGALGID_ABSENT,
+    init384,
+    update512,
+    final512,
+    NULL,
+    NULL,
+    SHA512_CBLOCK,
+    sizeof(EVP_MD *) + sizeof(SHA512_CTX),
+};
+
+const EVP_MD *EVP_sha384(void)
+{
+    return (&sha384_md);
+}
+
+static const EVP_MD sha512_md = {
+    NID_sha512,
+    NID_sha512WithRSAEncryption,
+    SHA512_DIGEST_LENGTH,
+    EVP_MD_FLAG_DIGALGID_ABSENT,
+    init512,
+    update512,
+    final512,
+    NULL,
+    NULL,
+    SHA512_CBLOCK,
+    sizeof(EVP_MD *) + sizeof(SHA512_CTX),
+};
+
+const EVP_MD *EVP_sha512(void)
+{
+    return (&sha512_md);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_sigver.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_sigver.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_sigver.c	(revision 331)
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include "internal/evp_int.h"
+#include "evp_locl.h"
+
+static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+                          const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey,
+                          int ver)
+{
+    if (ctx->pctx == NULL)
+        ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
+    if (ctx->pctx == NULL)
+        return 0;
+
+    if (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)) {
+
+        if (type == NULL) {
+            int def_nid;
+            if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
+                type = EVP_get_digestbynid(def_nid);
+        }
+
+        if (type == NULL) {
+            EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST);
+            return 0;
+        }
+    }
+
+    if (ver) {
+        if (ctx->pctx->pmeth->verifyctx_init) {
+            if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <= 0)
+                return 0;
+            ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX;
+        } else if (EVP_PKEY_verify_init(ctx->pctx) <= 0)
+            return 0;
+    } else {
+        if (ctx->pctx->pmeth->signctx_init) {
+            if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0)
+                return 0;
+            ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
+        } else if (EVP_PKEY_sign_init(ctx->pctx) <= 0)
+            return 0;
+    }
+    if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0)
+        return 0;
+    if (pctx)
+        *pctx = ctx->pctx;
+    if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)
+        return 1;
+    if (!EVP_DigestInit_ex(ctx, type, e))
+        return 0;
+    return 1;
+}
+
+int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+                       const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
+{
+    return do_sigver_init(ctx, pctx, type, e, pkey, 0);
+}
+
+int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+                         const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
+{
+    return do_sigver_init(ctx, pctx, type, e, pkey, 1);
+}
+
+int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
+                        size_t *siglen)
+{
+    int sctx = 0, r = 0;
+    EVP_PKEY_CTX *pctx = ctx->pctx;
+    if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) {
+        if (!sigret)
+            return pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
+        if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE)
+            r = pctx->pmeth->signctx(pctx, sigret, siglen, ctx);
+        else {
+            EVP_PKEY_CTX *dctx = EVP_PKEY_CTX_dup(ctx->pctx);
+            if (!dctx)
+                return 0;
+            r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx);
+            EVP_PKEY_CTX_free(dctx);
+        }
+        return r;
+    }
+    if (pctx->pmeth->signctx)
+        sctx = 1;
+    else
+        sctx = 0;
+    if (sigret) {
+        unsigned char md[EVP_MAX_MD_SIZE];
+        unsigned int mdlen = 0;
+        if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) {
+            if (sctx)
+                r = ctx->pctx->pmeth->signctx(ctx->pctx, sigret, siglen, ctx);
+            else
+                r = EVP_DigestFinal_ex(ctx, md, &mdlen);
+        } else {
+            EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
+            if (tmp_ctx == NULL || !EVP_MD_CTX_copy_ex(tmp_ctx, ctx))
+                return 0;
+            if (sctx)
+                r = tmp_ctx->pctx->pmeth->signctx(tmp_ctx->pctx,
+                                                  sigret, siglen, tmp_ctx);
+            else
+                r = EVP_DigestFinal_ex(tmp_ctx, md, &mdlen);
+            EVP_MD_CTX_free(tmp_ctx);
+        }
+        if (sctx || !r)
+            return r;
+        if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0)
+            return 0;
+    } else {
+        if (sctx) {
+            if (pctx->pmeth->signctx(pctx, sigret, siglen, ctx) <= 0)
+                return 0;
+        } else {
+            int s = EVP_MD_size(ctx->digest);
+            if (s < 0 || EVP_PKEY_sign(pctx, sigret, siglen, NULL, s) <= 0)
+                return 0;
+        }
+    }
+    return 1;
+}
+
+int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
+                          size_t siglen)
+{
+    unsigned char md[EVP_MAX_MD_SIZE];
+    int r = 0;
+    unsigned int mdlen = 0;
+    int vctx = 0;
+
+    if (ctx->pctx->pmeth->verifyctx)
+        vctx = 1;
+    else
+        vctx = 0;
+    if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) {
+        if (vctx) {
+            r = ctx->pctx->pmeth->verifyctx(ctx->pctx, sig, siglen, ctx);
+        } else
+            r = EVP_DigestFinal_ex(ctx, md, &mdlen);
+    } else {
+        EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
+        if (tmp_ctx == NULL || !EVP_MD_CTX_copy_ex(tmp_ctx, ctx))
+            return -1;
+        if (vctx) {
+            r = tmp_ctx->pctx->pmeth->verifyctx(tmp_ctx->pctx,
+                                                sig, siglen, tmp_ctx);
+        } else
+            r = EVP_DigestFinal_ex(tmp_ctx, md, &mdlen);
+        EVP_MD_CTX_free(tmp_ctx);
+    }
+    if (vctx || !r)
+        return r;
+    return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_wp.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_wp.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/m_wp.c	(revision 331)
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2005-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 <stdio.h>
+#include "internal/cryptlib.h"
+
+#ifndef OPENSSL_NO_WHIRLPOOL
+
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/whrlpool.h>
+# include "internal/evp_int.h"
+
+static int init(EVP_MD_CTX *ctx)
+{
+    return WHIRLPOOL_Init(EVP_MD_CTX_md_data(ctx));
+}
+
+static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+    return WHIRLPOOL_Update(EVP_MD_CTX_md_data(ctx), data, count);
+}
+
+static int final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+    return WHIRLPOOL_Final(md, EVP_MD_CTX_md_data(ctx));
+}
+
+static const EVP_MD whirlpool_md = {
+    NID_whirlpool,
+    0,
+    WHIRLPOOL_DIGEST_LENGTH,
+    0,
+    init,
+    update,
+    final,
+    NULL,
+    NULL,
+    WHIRLPOOL_BBLOCK / 8,
+    sizeof(EVP_MD *) + sizeof(WHIRLPOOL_CTX),
+};
+
+const EVP_MD *EVP_whirlpool(void)
+{
+    return (&whirlpool_md);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/names.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/names.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/names.c	(revision 331)
@@ -0,0 +1,178 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <internal/objects.h>
+#include <openssl/x509.h>
+#include "internal/evp_int.h"
+
+int EVP_add_cipher(const EVP_CIPHER *c)
+{
+    int r;
+
+    if (c == NULL)
+        return 0;
+
+    r = OBJ_NAME_add(OBJ_nid2sn(c->nid), OBJ_NAME_TYPE_CIPHER_METH,
+                     (const char *)c);
+    if (r == 0)
+        return (0);
+    r = OBJ_NAME_add(OBJ_nid2ln(c->nid), OBJ_NAME_TYPE_CIPHER_METH,
+                     (const char *)c);
+    return (r);
+}
+
+int EVP_add_digest(const EVP_MD *md)
+{
+    int r;
+    const char *name;
+
+    name = OBJ_nid2sn(md->type);
+    r = OBJ_NAME_add(name, OBJ_NAME_TYPE_MD_METH, (const char *)md);
+    if (r == 0)
+        return (0);
+    r = OBJ_NAME_add(OBJ_nid2ln(md->type), OBJ_NAME_TYPE_MD_METH,
+                     (const char *)md);
+    if (r == 0)
+        return (0);
+
+    if (md->pkey_type && md->type != md->pkey_type) {
+        r = OBJ_NAME_add(OBJ_nid2sn(md->pkey_type),
+                         OBJ_NAME_TYPE_MD_METH | OBJ_NAME_ALIAS, name);
+        if (r == 0)
+            return (0);
+        r = OBJ_NAME_add(OBJ_nid2ln(md->pkey_type),
+                         OBJ_NAME_TYPE_MD_METH | OBJ_NAME_ALIAS, name);
+    }
+    return (r);
+}
+
+const EVP_CIPHER *EVP_get_cipherbyname(const char *name)
+{
+    const EVP_CIPHER *cp;
+
+    if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL))
+        return NULL;
+
+    cp = (const EVP_CIPHER *)OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH);
+    return (cp);
+}
+
+const EVP_MD *EVP_get_digestbyname(const char *name)
+{
+    const EVP_MD *cp;
+
+    if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL))
+        return NULL;
+
+    cp = (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH);
+    return (cp);
+}
+
+void evp_cleanup_int(void)
+{
+    OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH);
+    OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH);
+    /*
+     * The above calls will only clean out the contents of the name hash
+     * table, but not the hash table itself.  The following line does that
+     * part.  -- Richard Levitte
+     */
+    OBJ_NAME_cleanup(-1);
+
+    EVP_PBE_cleanup();
+    OBJ_sigid_free();
+}
+
+struct doall_cipher {
+    void *arg;
+    void (*fn) (const EVP_CIPHER *ciph,
+                const char *from, const char *to, void *arg);
+};
+
+static void do_all_cipher_fn(const OBJ_NAME *nm, void *arg)
+{
+    struct doall_cipher *dc = arg;
+    if (nm->alias)
+        dc->fn(NULL, nm->name, nm->data, dc->arg);
+    else
+        dc->fn((const EVP_CIPHER *)nm->data, nm->name, NULL, dc->arg);
+}
+
+void EVP_CIPHER_do_all(void (*fn) (const EVP_CIPHER *ciph,
+                                   const char *from, const char *to, void *x),
+                       void *arg)
+{
+    struct doall_cipher dc;
+
+    /* Ignore errors */
+    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL);
+
+    dc.fn = fn;
+    dc.arg = arg;
+    OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc);
+}
+
+void EVP_CIPHER_do_all_sorted(void (*fn) (const EVP_CIPHER *ciph,
+                                          const char *from, const char *to,
+                                          void *x), void *arg)
+{
+    struct doall_cipher dc;
+
+    /* Ignore errors */
+    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL);
+
+    dc.fn = fn;
+    dc.arg = arg;
+    OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc);
+}
+
+struct doall_md {
+    void *arg;
+    void (*fn) (const EVP_MD *ciph,
+                const char *from, const char *to, void *arg);
+};
+
+static void do_all_md_fn(const OBJ_NAME *nm, void *arg)
+{
+    struct doall_md *dc = arg;
+    if (nm->alias)
+        dc->fn(NULL, nm->name, nm->data, dc->arg);
+    else
+        dc->fn((const EVP_MD *)nm->data, nm->name, NULL, dc->arg);
+}
+
+void EVP_MD_do_all(void (*fn) (const EVP_MD *md,
+                               const char *from, const char *to, void *x),
+                   void *arg)
+{
+    struct doall_md dc;
+
+    /* Ignore errors */
+    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);
+
+    dc.fn = fn;
+    dc.arg = arg;
+    OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
+}
+
+void EVP_MD_do_all_sorted(void (*fn) (const EVP_MD *md,
+                                      const char *from, const char *to,
+                                      void *x), void *arg)
+{
+    struct doall_md dc;
+
+    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);
+
+    dc.fn = fn;
+    dc.arg = arg;
+    OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p5_crpt.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p5_crpt.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p5_crpt.c	(revision 331)
@@ -0,0 +1,103 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include <stdlib.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/evp.h>
+
+/*
+ * Doesn't do anything now: Builtin PBE algorithms in static table.
+ */
+
+void PKCS5_PBE_add(void)
+{
+}
+
+int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen,
+                       ASN1_TYPE *param, const EVP_CIPHER *cipher,
+                       const EVP_MD *md, int en_de)
+{
+    EVP_MD_CTX *ctx;
+    unsigned char md_tmp[EVP_MAX_MD_SIZE];
+    unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
+    int i;
+    PBEPARAM *pbe;
+    int saltlen, iter;
+    unsigned char *salt;
+    int mdsize;
+    int rv = 0;
+
+    /* Extract useful info from parameter */
+    if (param == NULL || param->type != V_ASN1_SEQUENCE ||
+        param->value.sequence == NULL) {
+        EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
+        return 0;
+    }
+
+    pbe = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBEPARAM), param);
+    if (pbe == NULL) {
+        EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
+        return 0;
+    }
+
+    if (!pbe->iter)
+        iter = 1;
+    else
+        iter = ASN1_INTEGER_get(pbe->iter);
+    salt = pbe->salt->data;
+    saltlen = pbe->salt->length;
+
+    if (!pass)
+        passlen = 0;
+    else if (passlen == -1)
+        passlen = strlen(pass);
+
+    ctx = EVP_MD_CTX_new();
+    if (ctx == NULL) {
+        EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (!EVP_DigestInit_ex(ctx, md, NULL))
+        goto err;
+    if (!EVP_DigestUpdate(ctx, pass, passlen))
+        goto err;
+    if (!EVP_DigestUpdate(ctx, salt, saltlen))
+        goto err;
+    PBEPARAM_free(pbe);
+    if (!EVP_DigestFinal_ex(ctx, md_tmp, NULL))
+        goto err;
+    mdsize = EVP_MD_size(md);
+    if (mdsize < 0)
+        return 0;
+    for (i = 1; i < iter; i++) {
+        if (!EVP_DigestInit_ex(ctx, md, NULL))
+            goto err;
+        if (!EVP_DigestUpdate(ctx, md_tmp, mdsize))
+            goto err;
+        if (!EVP_DigestFinal_ex(ctx, md_tmp, NULL))
+            goto err;
+    }
+    OPENSSL_assert(EVP_CIPHER_key_length(cipher) <= (int)sizeof(md_tmp));
+    memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher));
+    OPENSSL_assert(EVP_CIPHER_iv_length(cipher) <= 16);
+    memcpy(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)),
+           EVP_CIPHER_iv_length(cipher));
+    if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de))
+        goto err;
+    OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE);
+    OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
+    OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
+    rv = 1;
+ err:
+    EVP_MD_CTX_free(ctx);
+    return rv;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p5_crpt2.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p5_crpt2.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p5_crpt2.c	(revision 331)
@@ -0,0 +1,277 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include <stdlib.h>
+#include "internal/cryptlib.h"
+# include <openssl/x509.h>
+# include <openssl/evp.h>
+# include <openssl/hmac.h>
+# include "evp_locl.h"
+
+/* set this to print out info about the keygen algorithm */
+/* #define OPENSSL_DEBUG_PKCS5V2 */
+
+# ifdef OPENSSL_DEBUG_PKCS5V2
+static void h__dump(const unsigned char *p, int len);
+# endif
+
+/*
+ * This is an implementation of PKCS#5 v2.0 password based encryption key
+ * derivation function PBKDF2. SHA1 version verified against test vectors
+ * posted by Peter Gutmann <pgut001@cs.auckland.ac.nz> to the PKCS-TNG
+ * <pkcs-tng@rsa.com> mailing list.
+ */
+
+int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
+                      const unsigned char *salt, int saltlen, int iter,
+                      const EVP_MD *digest, int keylen, unsigned char *out)
+{
+    unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
+    int cplen, j, k, tkeylen, mdlen;
+    unsigned long i = 1;
+    HMAC_CTX *hctx_tpl = NULL, *hctx = NULL;
+
+    mdlen = EVP_MD_size(digest);
+    if (mdlen < 0)
+        return 0;
+
+    hctx_tpl = HMAC_CTX_new();
+    if (hctx_tpl == NULL)
+        return 0;
+    p = out;
+    tkeylen = keylen;
+    if (!pass)
+        passlen = 0;
+    else if (passlen == -1)
+        passlen = strlen(pass);
+    if (!HMAC_Init_ex(hctx_tpl, pass, passlen, digest, NULL)) {
+        HMAC_CTX_free(hctx_tpl);
+        return 0;
+    }
+    hctx = HMAC_CTX_new();
+    if (hctx == NULL) {
+        HMAC_CTX_free(hctx_tpl);
+        return 0;
+    }
+    while (tkeylen) {
+        if (tkeylen > mdlen)
+            cplen = mdlen;
+        else
+            cplen = tkeylen;
+        /*
+         * We are unlikely to ever use more than 256 blocks (5120 bits!) but
+         * just in case...
+         */
+        itmp[0] = (unsigned char)((i >> 24) & 0xff);
+        itmp[1] = (unsigned char)((i >> 16) & 0xff);
+        itmp[2] = (unsigned char)((i >> 8) & 0xff);
+        itmp[3] = (unsigned char)(i & 0xff);
+        if (!HMAC_CTX_copy(hctx, hctx_tpl)) {
+            HMAC_CTX_free(hctx);
+            HMAC_CTX_free(hctx_tpl);
+            return 0;
+        }
+        if (!HMAC_Update(hctx, salt, saltlen)
+            || !HMAC_Update(hctx, itmp, 4)
+            || !HMAC_Final(hctx, digtmp, NULL)) {
+            HMAC_CTX_free(hctx);
+            HMAC_CTX_free(hctx_tpl);
+            return 0;
+        }
+        HMAC_CTX_reset(hctx);
+        memcpy(p, digtmp, cplen);
+        for (j = 1; j < iter; j++) {
+            if (!HMAC_CTX_copy(hctx, hctx_tpl)) {
+                HMAC_CTX_free(hctx);
+                HMAC_CTX_free(hctx_tpl);
+                return 0;
+            }
+            if (!HMAC_Update(hctx, digtmp, mdlen)
+                || !HMAC_Final(hctx, digtmp, NULL)) {
+                HMAC_CTX_free(hctx);
+                HMAC_CTX_free(hctx_tpl);
+                return 0;
+            }
+            HMAC_CTX_reset(hctx);
+            for (k = 0; k < cplen; k++)
+                p[k] ^= digtmp[k];
+        }
+        tkeylen -= cplen;
+        i++;
+        p += cplen;
+    }
+    HMAC_CTX_free(hctx);
+    HMAC_CTX_free(hctx_tpl);
+# ifdef OPENSSL_DEBUG_PKCS5V2
+    fprintf(stderr, "Password:\n");
+    h__dump(pass, passlen);
+    fprintf(stderr, "Salt:\n");
+    h__dump(salt, saltlen);
+    fprintf(stderr, "Iteration count %d\n", iter);
+    fprintf(stderr, "Key:\n");
+    h__dump(out, keylen);
+# endif
+    return 1;
+}
+
+int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
+                           const unsigned char *salt, int saltlen, int iter,
+                           int keylen, unsigned char *out)
+{
+    return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, EVP_sha1(),
+                             keylen, out);
+}
+
+# ifdef DO_TEST
+main()
+{
+    unsigned char out[4];
+    unsigned char salt[] = { 0x12, 0x34, 0x56, 0x78 };
+    PKCS5_PBKDF2_HMAC_SHA1("password", -1, salt, 4, 5, 4, out);
+    fprintf(stderr, "Out %02X %02X %02X %02X\n",
+            out[0], out[1], out[2], out[3]);
+}
+
+# endif
+
+/*
+ * Now the key derivation function itself. This is a bit evil because it has
+ * to check the ASN1 parameters are valid: and there are quite a few of
+ * them...
+ */
+
+int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+                          ASN1_TYPE *param, const EVP_CIPHER *c,
+                          const EVP_MD *md, int en_de)
+{
+    PBE2PARAM *pbe2 = NULL;
+    const EVP_CIPHER *cipher;
+    EVP_PBE_KEYGEN *kdf;
+
+    int rv = 0;
+
+    pbe2 = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBE2PARAM), param);
+    if (pbe2 == NULL) {
+        EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR);
+        goto err;
+    }
+
+    /* See if we recognise the key derivation function */
+    if (!EVP_PBE_find(EVP_PBE_TYPE_KDF, OBJ_obj2nid(pbe2->keyfunc->algorithm),
+                        NULL, NULL, &kdf)) {
+        EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN,
+               EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION);
+        goto err;
+    }
+
+    /*
+     * lets see if we recognise the encryption algorithm.
+     */
+
+    cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm);
+
+    if (!cipher) {
+        EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_CIPHER);
+        goto err;
+    }
+
+    /* Fixup cipher based on AlgorithmIdentifier */
+    if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de))
+        goto err;
+    if (EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) {
+        EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_CIPHER_PARAMETER_ERROR);
+        goto err;
+    }
+    rv = kdf(ctx, pass, passlen, pbe2->keyfunc->parameter, NULL, NULL, en_de);
+ err:
+    PBE2PARAM_free(pbe2);
+    return rv;
+}
+
+int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
+                             int passlen, ASN1_TYPE *param,
+                             const EVP_CIPHER *c, const EVP_MD *md, int en_de)
+{
+    unsigned char *salt, key[EVP_MAX_KEY_LENGTH];
+    int saltlen, iter;
+    int rv = 0;
+    unsigned int keylen = 0;
+    int prf_nid, hmac_md_nid;
+    PBKDF2PARAM *kdf = NULL;
+    const EVP_MD *prfmd;
+
+    if (EVP_CIPHER_CTX_cipher(ctx) == NULL) {
+        EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_NO_CIPHER_SET);
+        goto err;
+    }
+    keylen = EVP_CIPHER_CTX_key_length(ctx);
+    OPENSSL_assert(keylen <= sizeof key);
+
+    /* Decode parameter */
+
+    kdf = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBKDF2PARAM), param);
+
+    if (kdf == NULL) {
+        EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR);
+        goto err;
+    }
+
+    keylen = EVP_CIPHER_CTX_key_length(ctx);
+
+    /* Now check the parameters of the kdf */
+
+    if (kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)) {
+        EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_KEYLENGTH);
+        goto err;
+    }
+
+    if (kdf->prf)
+        prf_nid = OBJ_obj2nid(kdf->prf->algorithm);
+    else
+        prf_nid = NID_hmacWithSHA1;
+
+    if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0)) {
+        EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
+        goto err;
+    }
+
+    prfmd = EVP_get_digestbynid(hmac_md_nid);
+    if (prfmd == NULL) {
+        EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF);
+        goto err;
+    }
+
+    if (kdf->salt->type != V_ASN1_OCTET_STRING) {
+        EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_SALT_TYPE);
+        goto err;
+    }
+
+    /* it seems that its all OK */
+    salt = kdf->salt->value.octet_string->data;
+    saltlen = kdf->salt->value.octet_string->length;
+    iter = ASN1_INTEGER_get(kdf->iter);
+    if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd,
+                           keylen, key))
+        goto err;
+    rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de);
+ err:
+    OPENSSL_cleanse(key, keylen);
+    PBKDF2PARAM_free(kdf);
+    return rv;
+}
+
+# ifdef OPENSSL_DEBUG_PKCS5V2
+static void h__dump(const unsigned char *p, int len)
+{
+    for (; len--; p++)
+        fprintf(stderr, "%02X ", *p);
+    fprintf(stderr, "\n");
+}
+# endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_dec.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_dec.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_dec.c	(revision 331)
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl,
+                         EVP_PKEY *priv)
+{
+    int ret = -1;
+
+#ifndef OPENSSL_NO_RSA
+    if (EVP_PKEY_id(priv) != EVP_PKEY_RSA) {
+#endif
+        EVPerr(EVP_F_EVP_PKEY_DECRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA);
+#ifndef OPENSSL_NO_RSA
+        goto err;
+    }
+
+    ret =
+        RSA_private_decrypt(ekl, ek, key, EVP_PKEY_get0_RSA(priv),
+                            RSA_PKCS1_PADDING);
+ err:
+#endif
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_enc.c	(revision 331)
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int EVP_PKEY_encrypt_old(unsigned char *ek, const unsigned char *key,
+                         int key_len, EVP_PKEY *pubk)
+{
+    int ret = 0;
+
+#ifndef OPENSSL_NO_RSA
+    if (EVP_PKEY_id(pubk) != EVP_PKEY_RSA) {
+#endif
+        EVPerr(EVP_F_EVP_PKEY_ENCRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA);
+#ifndef OPENSSL_NO_RSA
+        goto err;
+    }
+    ret =
+        RSA_public_encrypt(key_len, key, ek, EVP_PKEY_get0_RSA(pubk),
+                           RSA_PKCS1_PADDING);
+ err:
+#endif
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_lib.c	(revision 331)
@@ -0,0 +1,484 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/dh.h>
+#include <openssl/engine.h>
+
+#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
+
+static void EVP_PKEY_free_it(EVP_PKEY *x);
+
+int EVP_PKEY_bits(const EVP_PKEY *pkey)
+{
+    if (pkey && pkey->ameth && pkey->ameth->pkey_bits)
+        return pkey->ameth->pkey_bits(pkey);
+    return 0;
+}
+
+int EVP_PKEY_security_bits(const EVP_PKEY *pkey)
+{
+    if (pkey == NULL)
+        return 0;
+    if (!pkey->ameth || !pkey->ameth->pkey_security_bits)
+        return -2;
+    return pkey->ameth->pkey_security_bits(pkey);
+}
+
+int EVP_PKEY_size(EVP_PKEY *pkey)
+{
+    if (pkey && pkey->ameth && pkey->ameth->pkey_size)
+        return pkey->ameth->pkey_size(pkey);
+    return 0;
+}
+
+int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
+{
+#ifndef OPENSSL_NO_DSA
+    if (pkey->type == EVP_PKEY_DSA) {
+        int ret = pkey->save_parameters;
+
+        if (mode >= 0)
+            pkey->save_parameters = mode;
+        return (ret);
+    }
+#endif
+#ifndef OPENSSL_NO_EC
+    if (pkey->type == EVP_PKEY_EC) {
+        int ret = pkey->save_parameters;
+
+        if (mode >= 0)
+            pkey->save_parameters = mode;
+        return (ret);
+    }
+#endif
+    return (0);
+}
+
+int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+{
+    if (to->type == EVP_PKEY_NONE) {
+        if (EVP_PKEY_set_type(to, from->type) == 0)
+            return 0;
+    } else if (to->type != from->type) {
+        EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_KEY_TYPES);
+        goto err;
+    }
+
+    if (EVP_PKEY_missing_parameters(from)) {
+        EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_MISSING_PARAMETERS);
+        goto err;
+    }
+
+    if (!EVP_PKEY_missing_parameters(to)) {
+        if (EVP_PKEY_cmp_parameters(to, from) == 1)
+            return 1;
+        EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_PARAMETERS);
+        return 0;
+    }
+
+    if (from->ameth && from->ameth->param_copy)
+        return from->ameth->param_copy(to, from);
+ err:
+    return 0;
+}
+
+int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
+{
+    if (pkey->ameth && pkey->ameth->param_missing)
+        return pkey->ameth->param_missing(pkey);
+    return 0;
+}
+
+int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+    if (a->type != b->type)
+        return -1;
+    if (a->ameth && a->ameth->param_cmp)
+        return a->ameth->param_cmp(a, b);
+    return -2;
+}
+
+int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+    if (a->type != b->type)
+        return -1;
+
+    if (a->ameth) {
+        int ret;
+        /* Compare parameters if the algorithm has them */
+        if (a->ameth->param_cmp) {
+            ret = a->ameth->param_cmp(a, b);
+            if (ret <= 0)
+                return ret;
+        }
+
+        if (a->ameth->pub_cmp)
+            return a->ameth->pub_cmp(a, b);
+    }
+
+    return -2;
+}
+
+EVP_PKEY *EVP_PKEY_new(void)
+{
+    EVP_PKEY *ret = OPENSSL_zalloc(sizeof(*ret));
+
+    if (ret == NULL) {
+        EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    ret->type = EVP_PKEY_NONE;
+    ret->save_type = EVP_PKEY_NONE;
+    ret->references = 1;
+    ret->save_parameters = 1;
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+int EVP_PKEY_up_ref(EVP_PKEY *pkey)
+{
+    int i;
+
+    if (CRYPTO_atomic_add(&pkey->references, 1, &i, pkey->lock) <= 0)
+        return 0;
+
+    REF_PRINT_COUNT("EVP_PKEY", pkey);
+    REF_ASSERT_ISNT(i < 2);
+    return ((i > 1) ? 1 : 0);
+}
+
+/*
+ * Setup a public key ASN1 method and ENGINE from a NID or a string. If pkey
+ * is NULL just return 1 or 0 if the algorithm exists.
+ */
+
+static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
+{
+    const EVP_PKEY_ASN1_METHOD *ameth;
+    ENGINE *e = NULL;
+    if (pkey) {
+        if (pkey->pkey.ptr)
+            EVP_PKEY_free_it(pkey);
+        /*
+         * If key type matches and a method exists then this lookup has
+         * succeeded once so just indicate success.
+         */
+        if ((type == pkey->save_type) && pkey->ameth)
+            return 1;
+#ifndef OPENSSL_NO_ENGINE
+        /* If we have an ENGINE release it */
+        ENGINE_finish(pkey->engine);
+        pkey->engine = NULL;
+#endif
+    }
+    if (str)
+        ameth = EVP_PKEY_asn1_find_str(&e, str, len);
+    else
+        ameth = EVP_PKEY_asn1_find(&e, type);
+#ifndef OPENSSL_NO_ENGINE
+    if (pkey == NULL)
+        ENGINE_finish(e);
+#endif
+    if (ameth == NULL) {
+        EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
+        return 0;
+    }
+    if (pkey) {
+        pkey->ameth = ameth;
+        pkey->engine = e;
+
+        pkey->type = pkey->ameth->pkey_id;
+        pkey->save_type = type;
+    }
+    return 1;
+}
+
+int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
+{
+    return pkey_set_type(pkey, type, NULL, -1);
+}
+
+int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
+{
+    return pkey_set_type(pkey, EVP_PKEY_NONE, str, len);
+}
+
+int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
+{
+    if (pkey == NULL || !EVP_PKEY_set_type(pkey, type))
+        return 0;
+    pkey->pkey.ptr = key;
+    return (key != NULL);
+}
+
+void *EVP_PKEY_get0(const EVP_PKEY *pkey)
+{
+    return pkey->pkey.ptr;
+}
+
+const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len)
+{
+    ASN1_OCTET_STRING *os = NULL;
+    if (pkey->type != EVP_PKEY_HMAC) {
+        EVPerr(EVP_F_EVP_PKEY_GET0_HMAC, EVP_R_EXPECTING_AN_HMAC_KEY);
+        return NULL;
+    }
+    os = EVP_PKEY_get0(pkey);
+    *len = os->length;
+    return os->data;
+}
+
+#ifndef OPENSSL_NO_RSA
+int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
+{
+    int ret = EVP_PKEY_assign_RSA(pkey, key);
+    if (ret)
+        RSA_up_ref(key);
+    return ret;
+}
+
+RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
+{
+    if (pkey->type != EVP_PKEY_RSA) {
+        EVPerr(EVP_F_EVP_PKEY_GET0_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
+        return NULL;
+    }
+    return pkey->pkey.rsa;
+}
+
+RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
+{
+    RSA *ret = EVP_PKEY_get0_RSA(pkey);
+    if (ret != NULL)
+        RSA_up_ref(ret);
+    return ret;
+}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
+{
+    int ret = EVP_PKEY_assign_DSA(pkey, key);
+    if (ret)
+        DSA_up_ref(key);
+    return ret;
+}
+
+DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey)
+{
+    if (pkey->type != EVP_PKEY_DSA) {
+        EVPerr(EVP_F_EVP_PKEY_GET0_DSA, EVP_R_EXPECTING_A_DSA_KEY);
+        return NULL;
+    }
+    return pkey->pkey.dsa;
+}
+
+DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
+{
+    DSA *ret = EVP_PKEY_get0_DSA(pkey);
+    if (ret != NULL)
+        DSA_up_ref(ret);
+    return ret;
+}
+#endif
+
+#ifndef OPENSSL_NO_EC
+
+int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
+{
+    int ret = EVP_PKEY_assign_EC_KEY(pkey, key);
+    if (ret)
+        EC_KEY_up_ref(key);
+    return ret;
+}
+
+EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
+{
+    if (pkey->type != EVP_PKEY_EC) {
+        EVPerr(EVP_F_EVP_PKEY_GET0_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
+        return NULL;
+    }
+    return pkey->pkey.ec;
+}
+
+EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
+{
+    EC_KEY *ret = EVP_PKEY_get0_EC_KEY(pkey);
+    if (ret != NULL)
+        EC_KEY_up_ref(ret);
+    return ret;
+}
+#endif
+
+#ifndef OPENSSL_NO_DH
+
+int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
+{
+    int ret = EVP_PKEY_assign_DH(pkey, key);
+    if (ret)
+        DH_up_ref(key);
+    return ret;
+}
+
+DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey)
+{
+    if (pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) {
+        EVPerr(EVP_F_EVP_PKEY_GET0_DH, EVP_R_EXPECTING_A_DH_KEY);
+        return NULL;
+    }
+    return pkey->pkey.dh;
+}
+
+DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
+{
+    DH *ret = EVP_PKEY_get0_DH(pkey);
+    if (ret != NULL)
+        DH_up_ref(ret);
+    return ret;
+}
+#endif
+
+int EVP_PKEY_type(int type)
+{
+    int ret;
+    const EVP_PKEY_ASN1_METHOD *ameth;
+    ENGINE *e;
+    ameth = EVP_PKEY_asn1_find(&e, type);
+    if (ameth)
+        ret = ameth->pkey_id;
+    else
+        ret = NID_undef;
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE_finish(e);
+#endif
+    return ret;
+}
+
+int EVP_PKEY_id(const EVP_PKEY *pkey)
+{
+    return pkey->type;
+}
+
+int EVP_PKEY_base_id(const EVP_PKEY *pkey)
+{
+    return EVP_PKEY_type(pkey->type);
+}
+
+void EVP_PKEY_free(EVP_PKEY *x)
+{
+    int i;
+
+    if (x == NULL)
+        return;
+
+    CRYPTO_atomic_add(&x->references, -1, &i, x->lock);
+    REF_PRINT_COUNT("EVP_PKEY", x);
+    if (i > 0)
+        return;
+    REF_ASSERT_ISNT(i < 0);
+    EVP_PKEY_free_it(x);
+    CRYPTO_THREAD_lock_free(x->lock);
+    sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
+    OPENSSL_free(x);
+}
+
+static void EVP_PKEY_free_it(EVP_PKEY *x)
+{
+    /* internal function; x is never NULL */
+    if (x->ameth && x->ameth->pkey_free) {
+        x->ameth->pkey_free(x);
+        x->pkey.ptr = NULL;
+    }
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE_finish(x->engine);
+    x->engine = NULL;
+#endif
+}
+
+static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
+                     const char *kstr)
+{
+    BIO_indent(out, indent, 128);
+    BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
+               kstr, OBJ_nid2ln(pkey->type));
+    return 1;
+}
+
+int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
+                          int indent, ASN1_PCTX *pctx)
+{
+    if (pkey->ameth && pkey->ameth->pub_print)
+        return pkey->ameth->pub_print(out, pkey, indent, pctx);
+
+    return unsup_alg(out, pkey, indent, "Public Key");
+}
+
+int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
+                           int indent, ASN1_PCTX *pctx)
+{
+    if (pkey->ameth && pkey->ameth->priv_print)
+        return pkey->ameth->priv_print(out, pkey, indent, pctx);
+
+    return unsup_alg(out, pkey, indent, "Private Key");
+}
+
+int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
+                          int indent, ASN1_PCTX *pctx)
+{
+    if (pkey->ameth && pkey->ameth->param_print)
+        return pkey->ameth->param_print(out, pkey, indent, pctx);
+    return unsup_alg(out, pkey, indent, "Parameters");
+}
+
+static int evp_pkey_asn1_ctrl(EVP_PKEY *pkey, int op, int arg1, void *arg2)
+{
+    if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL)
+        return -2;
+    return pkey->ameth->pkey_ctrl(pkey, op, arg1, arg2);
+}
+
+int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
+{
+    return evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, 0, pnid);
+}
+
+int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey,
+                               const unsigned char *pt, size_t ptlen)
+{
+    if (ptlen > INT_MAX)
+        return 0;
+    if (evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_SET1_TLS_ENCPT, ptlen,
+                           (void *)pt) <= 0)
+        return 0;
+    return 1;
+}
+
+size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt)
+{
+    int rv;
+    rv = evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_GET1_TLS_ENCPT, 0, ppt);
+    if (rv <= 0)
+        return 0;
+    return rv;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_open.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_open.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_open.c	(revision 331)
@@ -0,0 +1,73 @@
+/*
+ * Copyright 1995-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 "internal/cryptlib.h"
+#ifdef OPENSSL_NO_RSA
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <stdio.h>
+# include <openssl/evp.h>
+# include <openssl/objects.h>
+# include <openssl/x509.h>
+# include <openssl/rsa.h>
+
+int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+                 const unsigned char *ek, int ekl, const unsigned char *iv,
+                 EVP_PKEY *priv)
+{
+    unsigned char *key = NULL;
+    int i, size = 0, ret = 0;
+
+    if (type) {
+        EVP_CIPHER_CTX_reset(ctx);
+        if (!EVP_DecryptInit_ex(ctx, type, NULL, NULL, NULL))
+            return 0;
+    }
+
+    if (!priv)
+        return 1;
+
+    if (EVP_PKEY_id(priv) != EVP_PKEY_RSA) {
+        EVPerr(EVP_F_EVP_OPENINIT, EVP_R_PUBLIC_KEY_NOT_RSA);
+        goto err;
+    }
+
+    size = EVP_PKEY_size(priv);
+    key = OPENSSL_malloc(size + 2);
+    if (key == NULL) {
+        /* ERROR */
+        EVPerr(EVP_F_EVP_OPENINIT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    i = EVP_PKEY_decrypt_old(key, ek, ekl, priv);
+    if ((i <= 0) || !EVP_CIPHER_CTX_set_key_length(ctx, i)) {
+        /* ERROR */
+        goto err;
+    }
+    if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv))
+        goto err;
+
+    ret = 1;
+ err:
+    OPENSSL_clear_free(key, size);
+    return (ret);
+}
+
+int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+    int i;
+
+    i = EVP_DecryptFinal_ex(ctx, out, outl);
+    if (i)
+        i = EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL);
+    return (i);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_seal.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_seal.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_seal.c	(revision 331)
@@ -0,0 +1,70 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/rand.h>
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+                 unsigned char **ek, int *ekl, unsigned char *iv,
+                 EVP_PKEY **pubk, int npubk)
+{
+    unsigned char key[EVP_MAX_KEY_LENGTH];
+    int i;
+
+    if (type) {
+        EVP_CIPHER_CTX_reset(ctx);
+        if (!EVP_EncryptInit_ex(ctx, type, NULL, NULL, NULL))
+            return 0;
+    }
+    if ((npubk <= 0) || !pubk)
+        return 1;
+    if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
+        return 0;
+    if (EVP_CIPHER_CTX_iv_length(ctx)
+        && RAND_bytes(iv, EVP_CIPHER_CTX_iv_length(ctx)) <= 0)
+        return 0;
+
+    if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
+        return 0;
+
+    for (i = 0; i < npubk; i++) {
+        ekl[i] =
+            EVP_PKEY_encrypt_old(ek[i], key, EVP_CIPHER_CTX_key_length(ctx),
+                                 pubk[i]);
+        if (ekl[i] <= 0)
+            return (-1);
+    }
+    return (npubk);
+}
+
+/*- MACRO
+void EVP_SealUpdate(ctx,out,outl,in,inl)
+EVP_CIPHER_CTX *ctx;
+unsigned char *out;
+int *outl;
+unsigned char *in;
+int inl;
+        {
+        EVP_EncryptUpdate(ctx,out,outl,in,inl);
+        }
+*/
+
+int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+{
+    int i;
+    i = EVP_EncryptFinal_ex(ctx, out, outl);
+    if (i)
+        i = EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, NULL);
+    return i;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_sign.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_sign.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_sign.c	(revision 331)
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include "internal/evp_int.h"
+
+int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
+                  unsigned int *siglen, EVP_PKEY *pkey)
+{
+    unsigned char m[EVP_MAX_MD_SIZE];
+    unsigned int m_len = 0;
+    int i = 0;
+    size_t sltmp;
+    EVP_PKEY_CTX *pkctx = NULL;
+
+    *siglen = 0;
+    if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_FINALISE)) {
+        if (!EVP_DigestFinal_ex(ctx, m, &m_len))
+            goto err;
+    } else {
+        int rv = 0;
+        EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
+        if (tmp_ctx == NULL) {
+            EVPerr(EVP_F_EVP_SIGNFINAL, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        rv = EVP_MD_CTX_copy_ex(tmp_ctx, ctx);
+        if (rv)
+            rv = EVP_DigestFinal_ex(tmp_ctx, m, &m_len);
+        EVP_MD_CTX_free(tmp_ctx);
+        if (!rv)
+            return 0;
+    }
+
+    sltmp = (size_t)EVP_PKEY_size(pkey);
+    i = 0;
+    pkctx = EVP_PKEY_CTX_new(pkey, NULL);
+    if (pkctx == NULL)
+        goto err;
+    if (EVP_PKEY_sign_init(pkctx) <= 0)
+        goto err;
+    if (EVP_PKEY_CTX_set_signature_md(pkctx, EVP_MD_CTX_md(ctx)) <= 0)
+        goto err;
+    if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0)
+        goto err;
+    *siglen = sltmp;
+    i = 1;
+ err:
+    EVP_PKEY_CTX_free(pkctx);
+    return i;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_verify.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_verify.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/p_verify.c	(revision 331)
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include "internal/evp_int.h"
+
+int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
+                    unsigned int siglen, EVP_PKEY *pkey)
+{
+    unsigned char m[EVP_MAX_MD_SIZE];
+    unsigned int m_len = 0;
+    int i = 0;
+    EVP_PKEY_CTX *pkctx = NULL;
+
+    if (EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_FINALISE)) {
+        if (!EVP_DigestFinal_ex(ctx, m, &m_len))
+            goto err;
+    } else {
+        int rv = 0;
+        EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
+        if (tmp_ctx == NULL) {
+            EVPerr(EVP_F_EVP_VERIFYFINAL, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        rv = EVP_MD_CTX_copy_ex(tmp_ctx, ctx);
+        if (rv)
+            rv = EVP_DigestFinal_ex(tmp_ctx, m, &m_len);
+        EVP_MD_CTX_free(tmp_ctx);
+        if (!rv)
+            return 0;
+    }
+
+    i = -1;
+    pkctx = EVP_PKEY_CTX_new(pkey, NULL);
+    if (pkctx == NULL)
+        goto err;
+    if (EVP_PKEY_verify_init(pkctx) <= 0)
+        goto err;
+    if (EVP_PKEY_CTX_set_signature_md(pkctx, EVP_MD_CTX_md(ctx)) <= 0)
+        goto err;
+    i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len);
+ err:
+    EVP_PKEY_CTX_free(pkctx);
+    return i;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/pmeth_fn.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/pmeth_fn.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/pmeth_fn.c	(revision 331)
@@ -0,0 +1,297 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include <stdlib.h>
+#include "internal/cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include "internal/evp_int.h"
+
+#define M_check_autoarg(ctx, arg, arglen, err) \
+    if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) {           \
+        size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey);         \
+                                                                  \
+        if (pksize == 0) {                                        \
+            EVPerr(err, EVP_R_INVALID_KEY); /*ckerr_ignore*/      \
+            return 0;                                             \
+        }                                                         \
+        if (!arg) {                                               \
+            *arglen = pksize;                                     \
+            return 1;                                             \
+        }                                                         \
+        if (*arglen < pksize) {                                   \
+            EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/ \
+            return 0;                                             \
+        }                                                         \
+    }
+
+int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
+{
+    int ret;
+    if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
+        EVPerr(EVP_F_EVP_PKEY_SIGN_INIT,
+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        return -2;
+    }
+    ctx->operation = EVP_PKEY_OP_SIGN;
+    if (!ctx->pmeth->sign_init)
+        return 1;
+    ret = ctx->pmeth->sign_init(ctx);
+    if (ret <= 0)
+        ctx->operation = EVP_PKEY_OP_UNDEFINED;
+    return ret;
+}
+
+int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
+                  unsigned char *sig, size_t *siglen,
+                  const unsigned char *tbs, size_t tbslen)
+{
+    if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
+        EVPerr(EVP_F_EVP_PKEY_SIGN,
+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        return -2;
+    }
+    if (ctx->operation != EVP_PKEY_OP_SIGN) {
+        EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED);
+        return -1;
+    }
+    M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN)
+        return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen);
+}
+
+int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx)
+{
+    int ret;
+    if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
+        EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT,
+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        return -2;
+    }
+    ctx->operation = EVP_PKEY_OP_VERIFY;
+    if (!ctx->pmeth->verify_init)
+        return 1;
+    ret = ctx->pmeth->verify_init(ctx);
+    if (ret <= 0)
+        ctx->operation = EVP_PKEY_OP_UNDEFINED;
+    return ret;
+}
+
+int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
+                    const unsigned char *sig, size_t siglen,
+                    const unsigned char *tbs, size_t tbslen)
+{
+    if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
+        EVPerr(EVP_F_EVP_PKEY_VERIFY,
+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        return -2;
+    }
+    if (ctx->operation != EVP_PKEY_OP_VERIFY) {
+        EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED);
+        return -1;
+    }
+    return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen);
+}
+
+int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx)
+{
+    int ret;
+    if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
+        EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT,
+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        return -2;
+    }
+    ctx->operation = EVP_PKEY_OP_VERIFYRECOVER;
+    if (!ctx->pmeth->verify_recover_init)
+        return 1;
+    ret = ctx->pmeth->verify_recover_init(ctx);
+    if (ret <= 0)
+        ctx->operation = EVP_PKEY_OP_UNDEFINED;
+    return ret;
+}
+
+int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
+                            unsigned char *rout, size_t *routlen,
+                            const unsigned char *sig, size_t siglen)
+{
+    if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) {
+        EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER,
+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        return -2;
+    }
+    if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) {
+        EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED);
+        return -1;
+    }
+    M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER)
+        return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen);
+}
+
+int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx)
+{
+    int ret;
+    if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
+        EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT,
+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        return -2;
+    }
+    ctx->operation = EVP_PKEY_OP_ENCRYPT;
+    if (!ctx->pmeth->encrypt_init)
+        return 1;
+    ret = ctx->pmeth->encrypt_init(ctx);
+    if (ret <= 0)
+        ctx->operation = EVP_PKEY_OP_UNDEFINED;
+    return ret;
+}
+
+int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
+                     unsigned char *out, size_t *outlen,
+                     const unsigned char *in, size_t inlen)
+{
+    if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
+        EVPerr(EVP_F_EVP_PKEY_ENCRYPT,
+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        return -2;
+    }
+    if (ctx->operation != EVP_PKEY_OP_ENCRYPT) {
+        EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
+        return -1;
+    }
+    M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT)
+        return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
+}
+
+int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx)
+{
+    int ret;
+    if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
+        EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT,
+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        return -2;
+    }
+    ctx->operation = EVP_PKEY_OP_DECRYPT;
+    if (!ctx->pmeth->decrypt_init)
+        return 1;
+    ret = ctx->pmeth->decrypt_init(ctx);
+    if (ret <= 0)
+        ctx->operation = EVP_PKEY_OP_UNDEFINED;
+    return ret;
+}
+
+int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
+                     unsigned char *out, size_t *outlen,
+                     const unsigned char *in, size_t inlen)
+{
+    if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
+        EVPerr(EVP_F_EVP_PKEY_DECRYPT,
+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        return -2;
+    }
+    if (ctx->operation != EVP_PKEY_OP_DECRYPT) {
+        EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED);
+        return -1;
+    }
+    M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT)
+        return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
+}
+
+int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
+{
+    int ret;
+    if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
+        EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT,
+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        return -2;
+    }
+    ctx->operation = EVP_PKEY_OP_DERIVE;
+    if (!ctx->pmeth->derive_init)
+        return 1;
+    ret = ctx->pmeth->derive_init(ctx);
+    if (ret <= 0)
+        ctx->operation = EVP_PKEY_OP_UNDEFINED;
+    return ret;
+}
+
+int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer)
+{
+    int ret;
+    if (!ctx || !ctx->pmeth
+        || !(ctx->pmeth->derive || ctx->pmeth->encrypt || ctx->pmeth->decrypt)
+        || !ctx->pmeth->ctrl) {
+        EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        return -2;
+    }
+    if (ctx->operation != EVP_PKEY_OP_DERIVE
+        && ctx->operation != EVP_PKEY_OP_ENCRYPT
+        && ctx->operation != EVP_PKEY_OP_DECRYPT) {
+        EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER,
+               EVP_R_OPERATON_NOT_INITIALIZED);
+        return -1;
+    }
+
+    ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer);
+
+    if (ret <= 0)
+        return ret;
+
+    if (ret == 2)
+        return 1;
+
+    if (!ctx->pkey) {
+        EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET);
+        return -1;
+    }
+
+    if (ctx->pkey->type != peer->type) {
+        EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_KEY_TYPES);
+        return -1;
+    }
+
+    /*
+     * ran@cryptocom.ru: For clarity.  The error is if parameters in peer are
+     * present (!missing) but don't match.  EVP_PKEY_cmp_parameters may return
+     * 1 (match), 0 (don't match) and -2 (comparison is not defined).  -1
+     * (different key types) is impossible here because it is checked earlier.
+     * -2 is OK for us here, as well as 1, so we can check for 0 only.
+     */
+    if (!EVP_PKEY_missing_parameters(peer) &&
+        !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) {
+        EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_PARAMETERS);
+        return -1;
+    }
+
+    EVP_PKEY_free(ctx->peerkey);
+    ctx->peerkey = peer;
+
+    ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
+
+    if (ret <= 0) {
+        ctx->peerkey = NULL;
+        return ret;
+    }
+
+    EVP_PKEY_up_ref(peer);
+    return 1;
+}
+
+int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
+{
+    if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
+        EVPerr(EVP_F_EVP_PKEY_DERIVE,
+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        return -2;
+    }
+    if (ctx->operation != EVP_PKEY_OP_DERIVE) {
+        EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED);
+        return -1;
+    }
+    M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE)
+        return ctx->pmeth->derive(ctx, key, pkeylen);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/pmeth_gn.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/pmeth_gn.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/pmeth_gn.c	(revision 331)
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include <stdlib.h>
+#include "internal/cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include "internal/bn_int.h"
+#include "internal/evp_int.h"
+
+int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx)
+{
+    int ret;
+    if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) {
+        EVPerr(EVP_F_EVP_PKEY_PARAMGEN_INIT,
+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        return -2;
+    }
+    ctx->operation = EVP_PKEY_OP_PARAMGEN;
+    if (!ctx->pmeth->paramgen_init)
+        return 1;
+    ret = ctx->pmeth->paramgen_init(ctx);
+    if (ret <= 0)
+        ctx->operation = EVP_PKEY_OP_UNDEFINED;
+    return ret;
+}
+
+int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
+{
+    int ret;
+    if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) {
+        EVPerr(EVP_F_EVP_PKEY_PARAMGEN,
+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        return -2;
+    }
+
+    if (ctx->operation != EVP_PKEY_OP_PARAMGEN) {
+        EVPerr(EVP_F_EVP_PKEY_PARAMGEN, EVP_R_OPERATON_NOT_INITIALIZED);
+        return -1;
+    }
+
+    if (ppkey == NULL)
+        return -1;
+
+    if (*ppkey == NULL)
+        *ppkey = EVP_PKEY_new();
+
+    if (*ppkey == NULL) {
+        EVPerr(EVP_F_EVP_PKEY_PARAMGEN, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+
+    ret = ctx->pmeth->paramgen(ctx, *ppkey);
+    if (ret <= 0) {
+        EVP_PKEY_free(*ppkey);
+        *ppkey = NULL;
+    }
+    return ret;
+}
+
+int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx)
+{
+    int ret;
+    if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) {
+        EVPerr(EVP_F_EVP_PKEY_KEYGEN_INIT,
+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        return -2;
+    }
+    ctx->operation = EVP_PKEY_OP_KEYGEN;
+    if (!ctx->pmeth->keygen_init)
+        return 1;
+    ret = ctx->pmeth->keygen_init(ctx);
+    if (ret <= 0)
+        ctx->operation = EVP_PKEY_OP_UNDEFINED;
+    return ret;
+}
+
+int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
+{
+    int ret;
+
+    if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) {
+        EVPerr(EVP_F_EVP_PKEY_KEYGEN,
+               EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        return -2;
+    }
+    if (ctx->operation != EVP_PKEY_OP_KEYGEN) {
+        EVPerr(EVP_F_EVP_PKEY_KEYGEN, EVP_R_OPERATON_NOT_INITIALIZED);
+        return -1;
+    }
+
+    if (ppkey == NULL)
+        return -1;
+
+    if (*ppkey == NULL)
+        *ppkey = EVP_PKEY_new();
+    if (*ppkey == NULL)
+        return -1;
+
+    ret = ctx->pmeth->keygen(ctx, *ppkey);
+    if (ret <= 0) {
+        EVP_PKEY_free(*ppkey);
+        *ppkey = NULL;
+    }
+    return ret;
+}
+
+void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb)
+{
+    ctx->pkey_gencb = cb;
+}
+
+EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx)
+{
+    return ctx->pkey_gencb;
+}
+
+/*
+ * "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB style
+ * callbacks.
+ */
+
+static int trans_cb(int a, int b, BN_GENCB *gcb)
+{
+    EVP_PKEY_CTX *ctx = BN_GENCB_get_arg(gcb);
+    ctx->keygen_info[0] = a;
+    ctx->keygen_info[1] = b;
+    return ctx->pkey_gencb(ctx);
+}
+
+void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx)
+{
+    BN_GENCB_set(cb, trans_cb, ctx);
+}
+
+int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx)
+{
+    if (idx == -1)
+        return ctx->keygen_info_count;
+    if (idx < 0 || idx > ctx->keygen_info_count)
+        return 0;
+    return ctx->keygen_info[idx];
+}
+
+EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
+                               const unsigned char *key, int keylen)
+{
+    EVP_PKEY_CTX *mac_ctx = NULL;
+    EVP_PKEY *mac_key = NULL;
+    mac_ctx = EVP_PKEY_CTX_new_id(type, e);
+    if (!mac_ctx)
+        return NULL;
+    if (EVP_PKEY_keygen_init(mac_ctx) <= 0)
+        goto merr;
+    if (EVP_PKEY_CTX_set_mac_key(mac_ctx, key, keylen) <= 0)
+        goto merr;
+    if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0)
+        goto merr;
+ merr:
+    EVP_PKEY_CTX_free(mac_ctx);
+    return mac_key;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/pmeth_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/pmeth_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/pmeth_lib.c	(revision 331)
@@ -0,0 +1,721 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include <stdlib.h>
+#include "internal/cryptlib.h"
+#include <openssl/engine.h>
+#include <openssl/evp.h>
+#include <openssl/x509v3.h>
+#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
+#include "internal/numbers.h"
+
+typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
+
+static STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL;
+
+static const EVP_PKEY_METHOD *standard_methods[] = {
+#ifndef OPENSSL_NO_RSA
+    &rsa_pkey_meth,
+#endif
+#ifndef OPENSSL_NO_DH
+    &dh_pkey_meth,
+#endif
+#ifndef OPENSSL_NO_DSA
+    &dsa_pkey_meth,
+#endif
+#ifndef OPENSSL_NO_EC
+    &ec_pkey_meth,
+#endif
+    &hmac_pkey_meth,
+#ifndef OPENSSL_NO_CMAC
+    &cmac_pkey_meth,
+#endif
+#ifndef OPENSSL_NO_DH
+    &dhx_pkey_meth,
+#endif
+    &tls1_prf_pkey_meth,
+#ifndef OPENSSL_NO_EC
+    &ecx25519_pkey_meth,
+#endif
+    &hkdf_pkey_meth
+};
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
+                           pmeth);
+
+static int pmeth_cmp(const EVP_PKEY_METHOD *const *a,
+                     const EVP_PKEY_METHOD *const *b)
+{
+    return ((*a)->pkey_id - (*b)->pkey_id);
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *,
+                             pmeth);
+
+const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type)
+{
+    EVP_PKEY_METHOD tmp;
+    const EVP_PKEY_METHOD *t = &tmp, **ret;
+    tmp.pkey_id = type;
+    if (app_pkey_methods) {
+        int idx;
+        idx = sk_EVP_PKEY_METHOD_find(app_pkey_methods, &tmp);
+        if (idx >= 0)
+            return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx);
+    }
+    ret = OBJ_bsearch_pmeth(&t, standard_methods,
+                            sizeof(standard_methods) /
+                            sizeof(EVP_PKEY_METHOD *));
+    if (!ret || !*ret)
+        return NULL;
+    return *ret;
+}
+
+static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
+{
+    EVP_PKEY_CTX *ret;
+    const EVP_PKEY_METHOD *pmeth;
+    if (id == -1) {
+        if (!pkey || !pkey->ameth)
+            return NULL;
+        id = pkey->ameth->pkey_id;
+    }
+#ifndef OPENSSL_NO_ENGINE
+    if (pkey && pkey->engine)
+        e = pkey->engine;
+    /* Try to find an ENGINE which implements this method */
+    if (e) {
+        if (!ENGINE_init(e)) {
+            EVPerr(EVP_F_INT_CTX_NEW, ERR_R_ENGINE_LIB);
+            return NULL;
+        }
+    } else
+        e = ENGINE_get_pkey_meth_engine(id);
+
+    /*
+     * If an ENGINE handled this method look it up. Otherwise use internal
+     * tables.
+     */
+
+    if (e)
+        pmeth = ENGINE_get_pkey_meth(e, id);
+    else
+#endif
+        pmeth = EVP_PKEY_meth_find(id);
+
+    if (pmeth == NULL) {
+        EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM);
+        return NULL;
+    }
+
+    ret = OPENSSL_zalloc(sizeof(*ret));
+    if (ret == NULL) {
+#ifndef OPENSSL_NO_ENGINE
+        ENGINE_finish(e);
+#endif
+        EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    ret->engine = e;
+    ret->pmeth = pmeth;
+    ret->operation = EVP_PKEY_OP_UNDEFINED;
+    ret->pkey = pkey;
+    if (pkey)
+        EVP_PKEY_up_ref(pkey);
+
+    if (pmeth->init) {
+        if (pmeth->init(ret) <= 0) {
+            ret->pmeth = NULL;
+            EVP_PKEY_CTX_free(ret);
+            return NULL;
+        }
+    }
+
+    return ret;
+}
+
+EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags)
+{
+    EVP_PKEY_METHOD *pmeth;
+
+    pmeth = OPENSSL_zalloc(sizeof(*pmeth));
+    if (pmeth == NULL)
+        return NULL;
+
+    pmeth->pkey_id = id;
+    pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
+    return pmeth;
+}
+
+void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
+                             const EVP_PKEY_METHOD *meth)
+{
+    if (ppkey_id)
+        *ppkey_id = meth->pkey_id;
+    if (pflags)
+        *pflags = meth->flags;
+}
+
+void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src)
+{
+
+    dst->init = src->init;
+    dst->copy = src->copy;
+    dst->cleanup = src->cleanup;
+
+    dst->paramgen_init = src->paramgen_init;
+    dst->paramgen = src->paramgen;
+
+    dst->keygen_init = src->keygen_init;
+    dst->keygen = src->keygen;
+
+    dst->sign_init = src->sign_init;
+    dst->sign = src->sign;
+
+    dst->verify_init = src->verify_init;
+    dst->verify = src->verify;
+
+    dst->verify_recover_init = src->verify_recover_init;
+    dst->verify_recover = src->verify_recover;
+
+    dst->signctx_init = src->signctx_init;
+    dst->signctx = src->signctx;
+
+    dst->verifyctx_init = src->verifyctx_init;
+    dst->verifyctx = src->verifyctx;
+
+    dst->encrypt_init = src->encrypt_init;
+    dst->encrypt = src->encrypt;
+
+    dst->decrypt_init = src->decrypt_init;
+    dst->decrypt = src->decrypt;
+
+    dst->derive_init = src->derive_init;
+    dst->derive = src->derive;
+
+    dst->ctrl = src->ctrl;
+    dst->ctrl_str = src->ctrl_str;
+}
+
+void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth)
+{
+    if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC))
+        OPENSSL_free(pmeth);
+}
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e)
+{
+    return int_ctx_new(pkey, e, -1);
+}
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
+{
+    return int_ctx_new(NULL, e, id);
+}
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
+{
+    EVP_PKEY_CTX *rctx;
+    if (!pctx->pmeth || !pctx->pmeth->copy)
+        return NULL;
+#ifndef OPENSSL_NO_ENGINE
+    /* Make sure it's safe to copy a pkey context using an ENGINE */
+    if (pctx->engine && !ENGINE_init(pctx->engine)) {
+        EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_ENGINE_LIB);
+        return 0;
+    }
+#endif
+    rctx = OPENSSL_malloc(sizeof(*rctx));
+    if (rctx == NULL)
+        return NULL;
+
+    rctx->pmeth = pctx->pmeth;
+#ifndef OPENSSL_NO_ENGINE
+    rctx->engine = pctx->engine;
+#endif
+
+    if (pctx->pkey)
+        EVP_PKEY_up_ref(pctx->pkey);
+
+    rctx->pkey = pctx->pkey;
+
+    if (pctx->peerkey)
+        EVP_PKEY_up_ref(pctx->peerkey);
+
+    rctx->peerkey = pctx->peerkey;
+
+    rctx->data = NULL;
+    rctx->app_data = NULL;
+    rctx->operation = pctx->operation;
+
+    if (pctx->pmeth->copy(rctx, pctx) > 0)
+        return rctx;
+
+    rctx->pmeth = NULL;
+    EVP_PKEY_CTX_free(rctx);
+    return NULL;
+
+}
+
+int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth)
+{
+    if (app_pkey_methods == NULL) {
+        app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp);
+        if (app_pkey_methods == NULL)
+            return 0;
+    }
+    if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth))
+        return 0;
+    sk_EVP_PKEY_METHOD_sort(app_pkey_methods);
+    return 1;
+}
+
+void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
+{
+    if (ctx == NULL)
+        return;
+    if (ctx->pmeth && ctx->pmeth->cleanup)
+        ctx->pmeth->cleanup(ctx);
+    EVP_PKEY_free(ctx->pkey);
+    EVP_PKEY_free(ctx->peerkey);
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE_finish(ctx->engine);
+#endif
+    OPENSSL_free(ctx);
+}
+
+int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
+                      int cmd, int p1, void *p2)
+{
+    int ret;
+    if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) {
+        EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
+        return -2;
+    }
+    if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype))
+        return -1;
+
+    if (ctx->operation == EVP_PKEY_OP_UNDEFINED) {
+        EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET);
+        return -1;
+    }
+
+    if ((optype != -1) && !(ctx->operation & optype)) {
+        EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION);
+        return -1;
+    }
+
+    ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2);
+
+    if (ret == -2)
+        EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
+
+    return ret;
+
+}
+
+int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
+                          const char *name, const char *value)
+{
+    if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) {
+        EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
+        return -2;
+    }
+    if (strcmp(name, "digest") == 0) {
+        const EVP_MD *md;
+        if (value == NULL || (md = EVP_get_digestbyname(value)) == NULL) {
+            EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_INVALID_DIGEST);
+            return 0;
+        }
+        return EVP_PKEY_CTX_set_signature_md(ctx, md);
+    }
+    return ctx->pmeth->ctrl_str(ctx, name, value);
+}
+
+/* Utility functions to send a string of hex string to a ctrl */
+
+int EVP_PKEY_CTX_str2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *str)
+{
+    size_t len;
+
+    len = strlen(str);
+    if (len > INT_MAX)
+        return -1;
+    return ctx->pmeth->ctrl(ctx, cmd, len, (void *)str);
+}
+
+int EVP_PKEY_CTX_hex2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *hex)
+{
+    unsigned char *bin;
+    long binlen;
+    int rv = -1;
+
+    bin = OPENSSL_hexstr2buf(hex, &binlen);
+    if (bin == NULL)
+        return 0;
+    if (binlen <= INT_MAX)
+        rv = ctx->pmeth->ctrl(ctx, cmd, binlen, bin);
+    OPENSSL_free(bin);
+    return rv;
+}
+
+int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx)
+{
+    return ctx->operation;
+}
+
+void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen)
+{
+    ctx->keygen_info = dat;
+    ctx->keygen_info_count = datlen;
+}
+
+void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data)
+{
+    ctx->data = data;
+}
+
+void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx)
+{
+    return ctx->data;
+}
+
+EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx)
+{
+    return ctx->pkey;
+}
+
+EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx)
+{
+    return ctx->peerkey;
+}
+
+void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data)
+{
+    ctx->app_data = data;
+}
+
+void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx)
+{
+    return ctx->app_data;
+}
+
+void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
+                            int (*init) (EVP_PKEY_CTX *ctx))
+{
+    pmeth->init = init;
+}
+
+void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
+                            int (*copy) (EVP_PKEY_CTX *dst,
+                                         EVP_PKEY_CTX *src))
+{
+    pmeth->copy = copy;
+}
+
+void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
+                               void (*cleanup) (EVP_PKEY_CTX *ctx))
+{
+    pmeth->cleanup = cleanup;
+}
+
+void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
+                                int (*paramgen_init) (EVP_PKEY_CTX *ctx),
+                                int (*paramgen) (EVP_PKEY_CTX *ctx,
+                                                 EVP_PKEY *pkey))
+{
+    pmeth->paramgen_init = paramgen_init;
+    pmeth->paramgen = paramgen;
+}
+
+void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
+                              int (*keygen_init) (EVP_PKEY_CTX *ctx),
+                              int (*keygen) (EVP_PKEY_CTX *ctx,
+                                             EVP_PKEY *pkey))
+{
+    pmeth->keygen_init = keygen_init;
+    pmeth->keygen = keygen;
+}
+
+void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
+                            int (*sign_init) (EVP_PKEY_CTX *ctx),
+                            int (*sign) (EVP_PKEY_CTX *ctx,
+                                         unsigned char *sig, size_t *siglen,
+                                         const unsigned char *tbs,
+                                         size_t tbslen))
+{
+    pmeth->sign_init = sign_init;
+    pmeth->sign = sign;
+}
+
+void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
+                              int (*verify_init) (EVP_PKEY_CTX *ctx),
+                              int (*verify) (EVP_PKEY_CTX *ctx,
+                                             const unsigned char *sig,
+                                             size_t siglen,
+                                             const unsigned char *tbs,
+                                             size_t tbslen))
+{
+    pmeth->verify_init = verify_init;
+    pmeth->verify = verify;
+}
+
+void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
+                                      int (*verify_recover_init) (EVP_PKEY_CTX
+                                                                  *ctx),
+                                      int (*verify_recover) (EVP_PKEY_CTX
+                                                             *ctx,
+                                                             unsigned char
+                                                             *sig,
+                                                             size_t *siglen,
+                                                             const unsigned
+                                                             char *tbs,
+                                                             size_t tbslen))
+{
+    pmeth->verify_recover_init = verify_recover_init;
+    pmeth->verify_recover = verify_recover;
+}
+
+void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
+                               int (*signctx_init) (EVP_PKEY_CTX *ctx,
+                                                    EVP_MD_CTX *mctx),
+                               int (*signctx) (EVP_PKEY_CTX *ctx,
+                                               unsigned char *sig,
+                                               size_t *siglen,
+                                               EVP_MD_CTX *mctx))
+{
+    pmeth->signctx_init = signctx_init;
+    pmeth->signctx = signctx;
+}
+
+void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
+                                 int (*verifyctx_init) (EVP_PKEY_CTX *ctx,
+                                                        EVP_MD_CTX *mctx),
+                                 int (*verifyctx) (EVP_PKEY_CTX *ctx,
+                                                   const unsigned char *sig,
+                                                   int siglen,
+                                                   EVP_MD_CTX *mctx))
+{
+    pmeth->verifyctx_init = verifyctx_init;
+    pmeth->verifyctx = verifyctx;
+}
+
+void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
+                               int (*encrypt_init) (EVP_PKEY_CTX *ctx),
+                               int (*encryptfn) (EVP_PKEY_CTX *ctx,
+                                                 unsigned char *out,
+                                                 size_t *outlen,
+                                                 const unsigned char *in,
+                                                 size_t inlen))
+{
+    pmeth->encrypt_init = encrypt_init;
+    pmeth->encrypt = encryptfn;
+}
+
+void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
+                               int (*decrypt_init) (EVP_PKEY_CTX *ctx),
+                               int (*decrypt) (EVP_PKEY_CTX *ctx,
+                                               unsigned char *out,
+                                               size_t *outlen,
+                                               const unsigned char *in,
+                                               size_t inlen))
+{
+    pmeth->decrypt_init = decrypt_init;
+    pmeth->decrypt = decrypt;
+}
+
+void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
+                              int (*derive_init) (EVP_PKEY_CTX *ctx),
+                              int (*derive) (EVP_PKEY_CTX *ctx,
+                                             unsigned char *key,
+                                             size_t *keylen))
+{
+    pmeth->derive_init = derive_init;
+    pmeth->derive = derive;
+}
+
+void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
+                            int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1,
+                                         void *p2),
+                            int (*ctrl_str) (EVP_PKEY_CTX *ctx,
+                                             const char *type,
+                                             const char *value))
+{
+    pmeth->ctrl = ctrl;
+    pmeth->ctrl_str = ctrl_str;
+}
+
+void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth,
+                            int (**pinit) (EVP_PKEY_CTX *ctx))
+{
+    *pinit = pmeth->init;
+}
+
+void EVP_PKEY_meth_get_copy(EVP_PKEY_METHOD *pmeth,
+                            int (**pcopy) (EVP_PKEY_CTX *dst,
+                                           EVP_PKEY_CTX *src))
+{
+    *pcopy = pmeth->copy;
+}
+
+void EVP_PKEY_meth_get_cleanup(EVP_PKEY_METHOD *pmeth,
+                               void (**pcleanup) (EVP_PKEY_CTX *ctx))
+{
+    *pcleanup = pmeth->cleanup;
+}
+
+void EVP_PKEY_meth_get_paramgen(EVP_PKEY_METHOD *pmeth,
+                                int (**pparamgen_init) (EVP_PKEY_CTX *ctx),
+                                int (**pparamgen) (EVP_PKEY_CTX *ctx,
+                                                   EVP_PKEY *pkey))
+{
+    if (pparamgen_init)
+        *pparamgen_init = pmeth->paramgen_init;
+    if (pparamgen)
+        *pparamgen = pmeth->paramgen;
+}
+
+void EVP_PKEY_meth_get_keygen(EVP_PKEY_METHOD *pmeth,
+                              int (**pkeygen_init) (EVP_PKEY_CTX *ctx),
+                              int (**pkeygen) (EVP_PKEY_CTX *ctx,
+                                               EVP_PKEY *pkey))
+{
+    if (pkeygen_init)
+        *pkeygen_init = pmeth->keygen_init;
+    if (pkeygen)
+        *pkeygen = pmeth->keygen;
+}
+
+void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth,
+                            int (**psign_init) (EVP_PKEY_CTX *ctx),
+                            int (**psign) (EVP_PKEY_CTX *ctx,
+                                           unsigned char *sig, size_t *siglen,
+                                           const unsigned char *tbs,
+                                           size_t tbslen))
+{
+    if (psign_init)
+        *psign_init = pmeth->sign_init;
+    if (psign)
+        *psign = pmeth->sign;
+}
+
+void EVP_PKEY_meth_get_verify(EVP_PKEY_METHOD *pmeth,
+                              int (**pverify_init) (EVP_PKEY_CTX *ctx),
+                              int (**pverify) (EVP_PKEY_CTX *ctx,
+                                               const unsigned char *sig,
+                                               size_t siglen,
+                                               const unsigned char *tbs,
+                                               size_t tbslen))
+{
+    if (pverify_init)
+        *pverify_init = pmeth->verify_init;
+    if (pverify)
+        *pverify = pmeth->verify;
+}
+
+void EVP_PKEY_meth_get_verify_recover(EVP_PKEY_METHOD *pmeth,
+                                      int (**pverify_recover_init) (EVP_PKEY_CTX
+                                                                    *ctx),
+                                      int (**pverify_recover) (EVP_PKEY_CTX
+                                                               *ctx,
+                                                               unsigned char
+                                                               *sig,
+                                                               size_t *siglen,
+                                                               const unsigned
+                                                               char *tbs,
+                                                               size_t tbslen))
+{
+    if (pverify_recover_init)
+        *pverify_recover_init = pmeth->verify_recover_init;
+    if (pverify_recover)
+        *pverify_recover = pmeth->verify_recover;
+}
+
+void EVP_PKEY_meth_get_signctx(EVP_PKEY_METHOD *pmeth,
+                               int (**psignctx_init) (EVP_PKEY_CTX *ctx,
+                                                      EVP_MD_CTX *mctx),
+                               int (**psignctx) (EVP_PKEY_CTX *ctx,
+                                                 unsigned char *sig,
+                                                 size_t *siglen,
+                                                 EVP_MD_CTX *mctx))
+{
+    if (psignctx_init)
+        *psignctx_init = pmeth->signctx_init;
+    if (psignctx)
+        *psignctx = pmeth->signctx;
+}
+
+void EVP_PKEY_meth_get_verifyctx(EVP_PKEY_METHOD *pmeth,
+                                 int (**pverifyctx_init) (EVP_PKEY_CTX *ctx,
+                                                          EVP_MD_CTX *mctx),
+                                 int (**pverifyctx) (EVP_PKEY_CTX *ctx,
+                                                     const unsigned char *sig,
+                                                     int siglen,
+                                                     EVP_MD_CTX *mctx))
+{
+    if (pverifyctx_init)
+        *pverifyctx_init = pmeth->verifyctx_init;
+    if (pverifyctx)
+        *pverifyctx = pmeth->verifyctx;
+}
+
+void EVP_PKEY_meth_get_encrypt(EVP_PKEY_METHOD *pmeth,
+                               int (**pencrypt_init) (EVP_PKEY_CTX *ctx),
+                               int (**pencryptfn) (EVP_PKEY_CTX *ctx,
+                                                   unsigned char *out,
+                                                   size_t *outlen,
+                                                   const unsigned char *in,
+                                                   size_t inlen))
+{
+    if (pencrypt_init)
+        *pencrypt_init = pmeth->encrypt_init;
+    if (pencryptfn)
+        *pencryptfn = pmeth->encrypt;
+}
+
+void EVP_PKEY_meth_get_decrypt(EVP_PKEY_METHOD *pmeth,
+                               int (**pdecrypt_init) (EVP_PKEY_CTX *ctx),
+                               int (**pdecrypt) (EVP_PKEY_CTX *ctx,
+                                                 unsigned char *out,
+                                                 size_t *outlen,
+                                                 const unsigned char *in,
+                                                 size_t inlen))
+{
+    if (pdecrypt_init)
+        *pdecrypt_init = pmeth->decrypt_init;
+    if (pdecrypt)
+        *pdecrypt = pmeth->decrypt;
+}
+
+void EVP_PKEY_meth_get_derive(EVP_PKEY_METHOD *pmeth,
+                              int (**pderive_init) (EVP_PKEY_CTX *ctx),
+                              int (**pderive) (EVP_PKEY_CTX *ctx,
+                                               unsigned char *key,
+                                               size_t *keylen))
+{
+    if (pderive_init)
+        *pderive_init = pmeth->derive_init;
+    if (pderive)
+        *pderive = pmeth->derive;
+}
+
+void EVP_PKEY_meth_get_ctrl(EVP_PKEY_METHOD *pmeth,
+                            int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1,
+                                           void *p2),
+                            int (**pctrl_str) (EVP_PKEY_CTX *ctx,
+                                               const char *type,
+                                               const char *value))
+{
+    if (pctrl)
+        *pctrl = pmeth->ctrl;
+    if (pctrl_str)
+        *pctrl_str = pmeth->ctrl_str;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/scrypt.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/scrypt.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/evp/scrypt.c	(revision 331)
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2015-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 <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <internal/numbers.h>
+
+#ifndef OPENSSL_NO_SCRYPT
+
+#define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
+static void salsa208_word_specification(uint32_t inout[16])
+{
+    int i;
+    uint32_t x[16];
+    memcpy(x, inout, sizeof(x));
+    for (i = 8; i > 0; i -= 2) {
+        x[4] ^= R(x[0] + x[12], 7);
+        x[8] ^= R(x[4] + x[0], 9);
+        x[12] ^= R(x[8] + x[4], 13);
+        x[0] ^= R(x[12] + x[8], 18);
+        x[9] ^= R(x[5] + x[1], 7);
+        x[13] ^= R(x[9] + x[5], 9);
+        x[1] ^= R(x[13] + x[9], 13);
+        x[5] ^= R(x[1] + x[13], 18);
+        x[14] ^= R(x[10] + x[6], 7);
+        x[2] ^= R(x[14] + x[10], 9);
+        x[6] ^= R(x[2] + x[14], 13);
+        x[10] ^= R(x[6] + x[2], 18);
+        x[3] ^= R(x[15] + x[11], 7);
+        x[7] ^= R(x[3] + x[15], 9);
+        x[11] ^= R(x[7] + x[3], 13);
+        x[15] ^= R(x[11] + x[7], 18);
+        x[1] ^= R(x[0] + x[3], 7);
+        x[2] ^= R(x[1] + x[0], 9);
+        x[3] ^= R(x[2] + x[1], 13);
+        x[0] ^= R(x[3] + x[2], 18);
+        x[6] ^= R(x[5] + x[4], 7);
+        x[7] ^= R(x[6] + x[5], 9);
+        x[4] ^= R(x[7] + x[6], 13);
+        x[5] ^= R(x[4] + x[7], 18);
+        x[11] ^= R(x[10] + x[9], 7);
+        x[8] ^= R(x[11] + x[10], 9);
+        x[9] ^= R(x[8] + x[11], 13);
+        x[10] ^= R(x[9] + x[8], 18);
+        x[12] ^= R(x[15] + x[14], 7);
+        x[13] ^= R(x[12] + x[15], 9);
+        x[14] ^= R(x[13] + x[12], 13);
+        x[15] ^= R(x[14] + x[13], 18);
+    }
+    for (i = 0; i < 16; ++i)
+        inout[i] += x[i];
+    OPENSSL_cleanse(x, sizeof(x));
+}
+
+static void scryptBlockMix(uint32_t *B_, uint32_t *B, uint64_t r)
+{
+    uint64_t i, j;
+    uint32_t X[16], *pB;
+
+    memcpy(X, B + (r * 2 - 1) * 16, sizeof(X));
+    pB = B;
+    for (i = 0; i < r * 2; i++) {
+        for (j = 0; j < 16; j++)
+            X[j] ^= *pB++;
+        salsa208_word_specification(X);
+        memcpy(B_ + (i / 2 + (i & 1) * r) * 16, X, sizeof(X));
+    }
+    OPENSSL_cleanse(X, sizeof(X));
+}
+
+static void scryptROMix(unsigned char *B, uint64_t r, uint64_t N,
+                        uint32_t *X, uint32_t *T, uint32_t *V)
+{
+    unsigned char *pB;
+    uint32_t *pV;
+    uint64_t i, k;
+
+    /* Convert from little endian input */
+    for (pV = V, i = 0, pB = B; i < 32 * r; i++, pV++) {
+        *pV = *pB++;
+        *pV |= *pB++ << 8;
+        *pV |= *pB++ << 16;
+        *pV |= (uint32_t)*pB++ << 24;
+    }
+
+    for (i = 1; i < N; i++, pV += 32 * r)
+        scryptBlockMix(pV, pV - 32 * r, r);
+
+    scryptBlockMix(X, V + (N - 1) * 32 * r, r);
+
+    for (i = 0; i < N; i++) {
+        uint32_t j;
+        j = X[16 * (2 * r - 1)] % N;
+        pV = V + 32 * r * j;
+        for (k = 0; k < 32 * r; k++)
+            T[k] = X[k] ^ *pV++;
+        scryptBlockMix(X, T, r);
+    }
+    /* Convert output to little endian */
+    for (i = 0, pB = B; i < 32 * r; i++) {
+        uint32_t xtmp = X[i];
+        *pB++ = xtmp & 0xff;
+        *pB++ = (xtmp >> 8) & 0xff;
+        *pB++ = (xtmp >> 16) & 0xff;
+        *pB++ = (xtmp >> 24) & 0xff;
+    }
+}
+
+#ifndef SIZE_MAX
+# define SIZE_MAX    ((size_t)-1)
+#endif
+
+/*
+ * Maximum power of two that will fit in uint64_t: this should work on
+ * most (all?) platforms.
+ */
+
+#define LOG2_UINT64_MAX         (sizeof(uint64_t) * 8 - 1)
+
+/*
+ * Maximum value of p * r:
+ * p <= ((2^32-1) * hLen) / MFLen =>
+ * p <= ((2^32-1) * 32) / (128 * r) =>
+ * p * r <= (2^30-1)
+ *
+ */
+
+#define SCRYPT_PR_MAX   ((1 << 30) - 1)
+
+/*
+ * Maximum permitted memory allow this to be overridden with Configuration
+ * option: e.g. -DSCRYPT_MAX_MEM=0 for maximum possible.
+ */
+
+#ifdef SCRYPT_MAX_MEM
+# if SCRYPT_MAX_MEM == 0
+#  undef SCRYPT_MAX_MEM
+/*
+ * Although we could theoretically allocate SIZE_MAX memory that would leave
+ * no memory available for anything else so set limit as half that.
+ */
+#  define SCRYPT_MAX_MEM (SIZE_MAX/2)
+# endif
+#else
+/* Default memory limit: 32 MB */
+# define SCRYPT_MAX_MEM  (1024 * 1024 * 32)
+#endif
+
+int EVP_PBE_scrypt(const char *pass, size_t passlen,
+                   const unsigned char *salt, size_t saltlen,
+                   uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
+                   unsigned char *key, size_t keylen)
+{
+    int rv = 0;
+    unsigned char *B;
+    uint32_t *X, *V, *T;
+    uint64_t i, Blen, Vlen;
+    size_t allocsize;
+
+    /* Sanity check parameters */
+    /* initial check, r,p must be non zero, N >= 2 and a power of 2 */
+    if (r == 0 || p == 0 || N < 2 || (N & (N - 1)))
+        return 0;
+    /* Check p * r < SCRYPT_PR_MAX avoiding overflow */
+    if (p > SCRYPT_PR_MAX / r)
+        return 0;
+
+    /*
+     * Need to check N: if 2^(128 * r / 8) overflows limit this is
+     * automatically satisfied since N <= UINT64_MAX.
+     */
+
+    if (16 * r <= LOG2_UINT64_MAX) {
+        if (N >= (((uint64_t)1) << (16 * r)))
+            return 0;
+    }
+
+    /* Memory checks: check total allocated buffer size fits in uint64_t */
+
+    /*
+     * B size in section 5 step 1.S
+     * Note: we know p * 128 * r < UINT64_MAX because we already checked
+     * p * r < SCRYPT_PR_MAX
+     */
+    Blen = p * 128 * r;
+
+    /*
+     * Check 32 * r * (N + 2) * sizeof(uint32_t) fits in
+     * uint64_t and also size_t (their sizes are unrelated).
+     * This is combined size V, X and T (section 4)
+     */
+    i = UINT64_MAX / (32 * sizeof(uint32_t));
+    if (N + 2 > i / r)
+        return 0;
+    Vlen = 32 * r * (N + 2) * sizeof(uint32_t);
+
+    /* check total allocated size fits in uint64_t */
+    if (Blen > UINT64_MAX - Vlen)
+        return 0;
+    /* check total allocated size fits in size_t */
+    if (Blen > SIZE_MAX - Vlen)
+        return 0;
+
+    allocsize = (size_t)(Blen + Vlen);
+
+    if (maxmem == 0)
+        maxmem = SCRYPT_MAX_MEM;
+
+    if (allocsize > maxmem) {
+        EVPerr(EVP_F_EVP_PBE_SCRYPT, EVP_R_MEMORY_LIMIT_EXCEEDED);
+        return 0;
+    }
+
+    /* If no key return to indicate parameters are OK */
+    if (key == NULL)
+        return 1;
+
+    B = OPENSSL_malloc(allocsize);
+    if (B == NULL)
+        return 0;
+    X = (uint32_t *)(B + Blen);
+    T = X + 32 * r;
+    V = T + 32 * r;
+    if (PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, 1, EVP_sha256(),
+                          Blen, B) == 0)
+        goto err;
+
+    for (i = 0; i < p; i++)
+        scryptROMix(B + 128 * r * i, r, N, X, T, V);
+
+    if (PKCS5_PBKDF2_HMAC(pass, passlen, B, Blen, 1, EVP_sha256(),
+                          keylen, key) == 0)
+        goto err;
+    rv = 1;
+ err:
+    OPENSSL_clear_free(B, allocsize);
+    return rv;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ex_data.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ex_data.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ex_data.c	(revision 331)
@@ -0,0 +1,384 @@
+/*
+ * Copyright 1995-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 "internal/cryptlib_int.h"
+#include "internal/thread_once.h"
+#include <openssl/lhash.h>
+
+/*
+ * Each structure type (sometimes called a class), that supports
+ * exdata has a stack of callbacks for each instance.
+ */
+struct ex_callback_st {
+    long argl;                  /* Arbitrary long */
+    void *argp;                 /* Arbitrary void * */
+    CRYPTO_EX_new *new_func;
+    CRYPTO_EX_free *free_func;
+    CRYPTO_EX_dup *dup_func;
+};
+
+/*
+ * The state for each class.  This could just be a typedef, but
+ * a structure allows future changes.
+ */
+typedef struct ex_callbacks_st {
+    STACK_OF(EX_CALLBACK) *meth;
+} EX_CALLBACKS;
+
+static EX_CALLBACKS ex_data[CRYPTO_EX_INDEX__COUNT];
+
+static CRYPTO_RWLOCK *ex_data_lock = NULL;
+static CRYPTO_ONCE ex_data_init = CRYPTO_ONCE_STATIC_INIT;
+
+DEFINE_RUN_ONCE_STATIC(do_ex_data_init)
+{
+    OPENSSL_init_crypto(0, NULL);
+    ex_data_lock = CRYPTO_THREAD_lock_new();
+    return ex_data_lock != NULL;
+}
+
+/*
+ * Return the EX_CALLBACKS from the |ex_data| array that corresponds to
+ * a given class.  On success, *holds the lock.*
+ */
+static EX_CALLBACKS *get_and_lock(int class_index)
+{
+    EX_CALLBACKS *ip;
+
+    if (class_index < 0 || class_index >= CRYPTO_EX_INDEX__COUNT) {
+        CRYPTOerr(CRYPTO_F_GET_AND_LOCK, ERR_R_PASSED_INVALID_ARGUMENT);
+        return NULL;
+    }
+
+    if (!RUN_ONCE(&ex_data_init, do_ex_data_init)) {
+        CRYPTOerr(CRYPTO_F_GET_AND_LOCK, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    if (ex_data_lock == NULL) {
+        /*
+         * This can happen in normal operation when using CRYPTO_mem_leaks().
+         * The CRYPTO_mem_leaks() function calls OPENSSL_cleanup() which cleans
+         * up the locks. Subsequently the BIO that CRYPTO_mem_leaks() uses gets
+         * freed, which also attempts to free the ex_data. However
+         * CRYPTO_mem_leaks() ensures that the ex_data is freed early (i.e.
+         * before OPENSSL_cleanup() is called), so if we get here we can safely
+         * ignore this operation. We just treat it as an error.
+         */
+         return NULL;
+    }
+
+    ip = &ex_data[class_index];
+    CRYPTO_THREAD_write_lock(ex_data_lock);
+    return ip;
+}
+
+static void cleanup_cb(EX_CALLBACK *funcs)
+{
+    OPENSSL_free(funcs);
+}
+
+/*
+ * Release all "ex_data" state to prevent memory leaks. This can't be made
+ * thread-safe without overhauling a lot of stuff, and shouldn't really be
+ * called under potential race-conditions anyway (it's for program shutdown
+ * after all).
+ */
+void crypto_cleanup_all_ex_data_int(void)
+{
+    int i;
+
+    for (i = 0; i < CRYPTO_EX_INDEX__COUNT; ++i) {
+        EX_CALLBACKS *ip = &ex_data[i];
+
+        sk_EX_CALLBACK_pop_free(ip->meth, cleanup_cb);
+        ip->meth = NULL;
+    }
+
+    CRYPTO_THREAD_lock_free(ex_data_lock);
+    ex_data_lock = NULL;
+}
+
+
+/*
+ * Unregister a new index by replacing the callbacks with no-ops.
+ * Any in-use instances are leaked.
+ */
+static void dummy_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx,
+                     long argl, void *argp)
+{
+}
+
+static void dummy_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx,
+                       long argl, void *argp)
+{
+}
+
+static int dummy_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
+                     void *from_d, int idx,
+                     long argl, void *argp)
+{
+    return 0;
+}
+
+int CRYPTO_free_ex_index(int class_index, int idx)
+{
+    EX_CALLBACKS *ip = get_and_lock(class_index);
+    EX_CALLBACK *a;
+    int toret = 0;
+
+    if (ip == NULL)
+        return 0;
+    if (idx < 0 || idx >= sk_EX_CALLBACK_num(ip->meth))
+        goto err;
+    a = sk_EX_CALLBACK_value(ip->meth, idx);
+    if (a == NULL)
+        goto err;
+    a->new_func = dummy_new;
+    a->dup_func = dummy_dup;
+    a->free_func = dummy_free;
+    toret = 1;
+err:
+    CRYPTO_THREAD_unlock(ex_data_lock);
+    return toret;
+}
+
+/*
+ * Register a new index.
+ */
+int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
+                            CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+                            CRYPTO_EX_free *free_func)
+{
+    int toret = -1;
+    EX_CALLBACK *a;
+    EX_CALLBACKS *ip = get_and_lock(class_index);
+
+    if (ip == NULL)
+        return -1;
+
+    if (ip->meth == NULL) {
+        ip->meth = sk_EX_CALLBACK_new_null();
+        /* We push an initial value on the stack because the SSL
+         * "app_data" routines use ex_data index zero.  See RT 3710. */
+        if (ip->meth == NULL
+            || !sk_EX_CALLBACK_push(ip->meth, NULL)) {
+            CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    }
+
+    a = (EX_CALLBACK *)OPENSSL_malloc(sizeof(*a));
+    if (a == NULL) {
+        CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    a->argl = argl;
+    a->argp = argp;
+    a->new_func = new_func;
+    a->dup_func = dup_func;
+    a->free_func = free_func;
+
+    if (!sk_EX_CALLBACK_push(ip->meth, NULL)) {
+        CRYPTOerr(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(a);
+        goto err;
+    }
+    toret = sk_EX_CALLBACK_num(ip->meth) - 1;
+    (void)sk_EX_CALLBACK_set(ip->meth, toret, a);
+
+ err:
+    CRYPTO_THREAD_unlock(ex_data_lock);
+    return toret;
+}
+
+/*
+ * Initialise a new CRYPTO_EX_DATA for use in a particular class - including
+ * calling new() callbacks for each index in the class used by this variable
+ * Thread-safe by copying a class's array of "EX_CALLBACK" entries
+ * in the lock, then using them outside the lock. Note this only applies
+ * to the global "ex_data" state (ie. class definitions), not 'ad' itself.
+ */
+int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
+{
+    int mx, i;
+    void *ptr;
+    EX_CALLBACK **storage = NULL;
+    EX_CALLBACK *stack[10];
+    EX_CALLBACKS *ip = get_and_lock(class_index);
+
+    if (ip == NULL)
+        return 0;
+
+    ad->sk = NULL;
+
+    mx = sk_EX_CALLBACK_num(ip->meth);
+    if (mx > 0) {
+        if (mx < (int)OSSL_NELEM(stack))
+            storage = stack;
+        else
+            storage = OPENSSL_malloc(sizeof(*storage) * mx);
+        if (storage != NULL)
+            for (i = 0; i < mx; i++)
+                storage[i] = sk_EX_CALLBACK_value(ip->meth, i);
+    }
+    CRYPTO_THREAD_unlock(ex_data_lock);
+
+    if (mx > 0 && storage == NULL) {
+        CRYPTOerr(CRYPTO_F_CRYPTO_NEW_EX_DATA, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    for (i = 0; i < mx; i++) {
+        if (storage[i] && storage[i]->new_func) {
+            ptr = CRYPTO_get_ex_data(ad, i);
+            storage[i]->new_func(obj, ptr, ad, i,
+                                 storage[i]->argl, storage[i]->argp);
+        }
+    }
+    if (storage != stack)
+        OPENSSL_free(storage);
+    return 1;
+}
+
+/*
+ * Duplicate a CRYPTO_EX_DATA variable - including calling dup() callbacks
+ * for each index in the class used by this variable
+ */
+int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
+                       const CRYPTO_EX_DATA *from)
+{
+    int mx, j, i;
+    char *ptr;
+    EX_CALLBACK *stack[10];
+    EX_CALLBACK **storage = NULL;
+    EX_CALLBACKS *ip;
+
+    if (from->sk == NULL)
+        /* Nothing to copy over */
+        return 1;
+    if ((ip = get_and_lock(class_index)) == NULL)
+        return 0;
+
+    mx = sk_EX_CALLBACK_num(ip->meth);
+    j = sk_void_num(from->sk);
+    if (j < mx)
+        mx = j;
+    if (mx > 0) {
+        if (mx < (int)OSSL_NELEM(stack))
+            storage = stack;
+        else
+            storage = OPENSSL_malloc(sizeof(*storage) * mx);
+        if (storage != NULL)
+            for (i = 0; i < mx; i++)
+                storage[i] = sk_EX_CALLBACK_value(ip->meth, i);
+    }
+    CRYPTO_THREAD_unlock(ex_data_lock);
+
+    if (mx > 0 && storage == NULL) {
+        CRYPTOerr(CRYPTO_F_CRYPTO_DUP_EX_DATA, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    for (i = 0; i < mx; i++) {
+        ptr = CRYPTO_get_ex_data(from, i);
+        if (storage[i] && storage[i]->dup_func)
+            storage[i]->dup_func(to, from, &ptr, i,
+                                 storage[i]->argl, storage[i]->argp);
+        CRYPTO_set_ex_data(to, i, ptr);
+    }
+    if (storage != stack)
+        OPENSSL_free(storage);
+    return 1;
+}
+
+
+/*
+ * Cleanup a CRYPTO_EX_DATA variable - including calling free() callbacks for
+ * each index in the class used by this variable
+ */
+void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
+{
+    int mx, i;
+    EX_CALLBACKS *ip;
+    void *ptr;
+    EX_CALLBACK *f;
+    EX_CALLBACK *stack[10];
+    EX_CALLBACK **storage = NULL;
+
+    if ((ip = get_and_lock(class_index)) == NULL)
+        goto err;
+
+    mx = sk_EX_CALLBACK_num(ip->meth);
+    if (mx > 0) {
+        if (mx < (int)OSSL_NELEM(stack))
+            storage = stack;
+        else
+            storage = OPENSSL_malloc(sizeof(*storage) * mx);
+        if (storage != NULL)
+            for (i = 0; i < mx; i++)
+                storage[i] = sk_EX_CALLBACK_value(ip->meth, i);
+    }
+    CRYPTO_THREAD_unlock(ex_data_lock);
+
+    for (i = 0; i < mx; i++) {
+        if (storage != NULL)
+            f = storage[i];
+        else {
+            CRYPTO_THREAD_write_lock(ex_data_lock);
+            f = sk_EX_CALLBACK_value(ip->meth, i);
+            CRYPTO_THREAD_unlock(ex_data_lock);
+        }
+        if (f != NULL && f->free_func != NULL) {
+            ptr = CRYPTO_get_ex_data(ad, i);
+            f->free_func(obj, ptr, ad, i, f->argl, f->argp);
+        }
+    }
+
+    if (storage != stack)
+        OPENSSL_free(storage);
+ err:
+    sk_void_free(ad->sk);
+    ad->sk = NULL;
+}
+
+/*
+ * For a given CRYPTO_EX_DATA variable, set the value corresponding to a
+ * particular index in the class used by this variable
+ */
+int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val)
+{
+    int i;
+
+    if (ad->sk == NULL) {
+        if ((ad->sk = sk_void_new_null()) == NULL) {
+            CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+    }
+
+    for (i = sk_void_num(ad->sk); i <= idx; ++i) {
+        if (!sk_void_push(ad->sk, NULL)) {
+            CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+    }
+    sk_void_set(ad->sk, idx, val);
+    return 1;
+}
+
+/*
+ * For a given CRYPTO_EX_DATA_ variable, get the value corresponding to a
+ * particular index in the class used by this variable
+ */
+void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx)
+{
+    if (ad->sk == NULL || idx >= sk_void_num(ad->sk))
+        return NULL;
+    return sk_void_value(ad->sk, idx);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/hmac/hm_ameth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/hmac/hm_ameth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/hmac/hm_ameth.c	(revision 331)
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2007-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include "internal/asn1_int.h"
+
+#define HMAC_TEST_PRIVATE_KEY_FORMAT
+
+/*
+ * HMAC "ASN1" method. This is just here to indicate the maximum HMAC output
+ * length and to free up an HMAC key.
+ */
+
+static int hmac_size(const EVP_PKEY *pkey)
+{
+    return EVP_MAX_MD_SIZE;
+}
+
+static void hmac_key_free(EVP_PKEY *pkey)
+{
+    ASN1_OCTET_STRING *os = EVP_PKEY_get0(pkey);
+    if (os) {
+        if (os->data)
+            OPENSSL_cleanse(os->data, os->length);
+        ASN1_OCTET_STRING_free(os);
+    }
+}
+
+static int hmac_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+{
+    switch (op) {
+    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+        *(int *)arg2 = NID_sha256;
+        return 1;
+
+    default:
+        return -2;
+    }
+}
+
+static int hmac_pkey_public_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+    return ASN1_OCTET_STRING_cmp(EVP_PKEY_get0(a), EVP_PKEY_get0(b));
+}
+
+#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT
+/*
+ * A bogus private key format for test purposes. This is simply the HMAC key
+ * with "HMAC PRIVATE KEY" in the headers. When enabled the genpkey utility
+ * can be used to "generate" HMAC keys.
+ */
+
+static int old_hmac_decode(EVP_PKEY *pkey,
+                           const unsigned char **pder, int derlen)
+{
+    ASN1_OCTET_STRING *os;
+    os = ASN1_OCTET_STRING_new();
+    if (os == NULL || !ASN1_OCTET_STRING_set(os, *pder, derlen))
+        goto err;
+    if (!EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, os))
+        goto err;
+    return 1;
+
+ err:
+    ASN1_OCTET_STRING_free(os);
+    return 0;
+}
+
+static int old_hmac_encode(const EVP_PKEY *pkey, unsigned char **pder)
+{
+    int inc;
+    ASN1_OCTET_STRING *os = EVP_PKEY_get0(pkey);
+    if (pder) {
+        if (!*pder) {
+            *pder = OPENSSL_malloc(os->length);
+            if (*pder == NULL)
+                return -1;
+            inc = 0;
+        } else
+            inc = 1;
+
+        memcpy(*pder, os->data, os->length);
+
+        if (inc)
+            *pder += os->length;
+    }
+
+    return os->length;
+}
+
+#endif
+
+const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = {
+    EVP_PKEY_HMAC,
+    EVP_PKEY_HMAC,
+    0,
+
+    "HMAC",
+    "OpenSSL HMAC method",
+
+    0, 0, hmac_pkey_public_cmp, 0,
+
+    0, 0, 0,
+
+    hmac_size,
+    0, 0,
+    0, 0, 0, 0, 0, 0, 0,
+
+    hmac_key_free,
+    hmac_pkey_ctrl,
+#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT
+    old_hmac_decode,
+    old_hmac_encode
+#else
+    0, 0
+#endif
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/hmac/hm_pmeth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/hmac/hm_pmeth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/hmac/hm_pmeth.c	(revision 331)
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2007-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include "internal/evp_int.h"
+
+/* HMAC pkey context structure */
+
+typedef struct {
+    const EVP_MD *md;           /* MD for HMAC use */
+    ASN1_OCTET_STRING ktmp;     /* Temp storage for key */
+    HMAC_CTX *ctx;
+} HMAC_PKEY_CTX;
+
+static int pkey_hmac_init(EVP_PKEY_CTX *ctx)
+{
+    HMAC_PKEY_CTX *hctx;
+
+    hctx = OPENSSL_zalloc(sizeof(*hctx));
+    if (hctx == NULL)
+        return 0;
+    hctx->ktmp.type = V_ASN1_OCTET_STRING;
+    hctx->ctx = HMAC_CTX_new();
+    if (hctx->ctx == NULL) {
+        OPENSSL_free(hctx);
+        return 0;
+    }
+
+    ctx->data = hctx;
+    ctx->keygen_info_count = 0;
+
+    return 1;
+}
+
+static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx);
+
+static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+{
+    HMAC_PKEY_CTX *sctx, *dctx;
+
+    /* allocate memory for dst->data and a new HMAC_CTX in dst->data->ctx */
+    if (!pkey_hmac_init(dst))
+        return 0;
+    sctx = EVP_PKEY_CTX_get_data(src);
+    dctx = EVP_PKEY_CTX_get_data(dst);
+    dctx->md = sctx->md;
+    if (!HMAC_CTX_copy(dctx->ctx, sctx->ctx))
+        goto err;
+    if (sctx->ktmp.data) {
+        if (!ASN1_OCTET_STRING_set(&dctx->ktmp,
+                                   sctx->ktmp.data, sctx->ktmp.length))
+            goto err;
+    }
+    return 1;
+err:
+    /* release HMAC_CTX in dst->data->ctx and memory allocated for dst->data */
+    pkey_hmac_cleanup (dst);
+    return 0;
+}
+
+static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx)
+{
+    HMAC_PKEY_CTX *hctx = EVP_PKEY_CTX_get_data(ctx);
+
+    if (hctx != NULL) {
+        HMAC_CTX_free(hctx->ctx);
+        OPENSSL_clear_free(hctx->ktmp.data, hctx->ktmp.length);
+        OPENSSL_free(hctx);
+        EVP_PKEY_CTX_set_data(ctx, NULL);
+    }
+}
+
+static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+    ASN1_OCTET_STRING *hkey = NULL;
+    HMAC_PKEY_CTX *hctx = ctx->data;
+    if (!hctx->ktmp.data)
+        return 0;
+    hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp);
+    if (!hkey)
+        return 0;
+    EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey);
+
+    return 1;
+}
+
+static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+    HMAC_PKEY_CTX *hctx = EVP_MD_CTX_pkey_ctx(ctx)->data;
+    if (!HMAC_Update(hctx->ctx, data, count))
+        return 0;
+    return 1;
+}
+
+static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
+{
+    HMAC_PKEY_CTX *hctx = ctx->data;
+    HMAC_CTX_set_flags(hctx->ctx,
+                       EVP_MD_CTX_test_flags(mctx, ~EVP_MD_CTX_FLAG_NO_INIT));
+    EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
+    EVP_MD_CTX_set_update_fn(mctx, int_update);
+    return 1;
+}
+
+static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+                        EVP_MD_CTX *mctx)
+{
+    unsigned int hlen;
+    HMAC_PKEY_CTX *hctx = ctx->data;
+    int l = EVP_MD_CTX_size(mctx);
+
+    if (l < 0)
+        return 0;
+    *siglen = l;
+    if (!sig)
+        return 1;
+
+    if (!HMAC_Final(hctx->ctx, sig, &hlen))
+        return 0;
+    *siglen = (size_t)hlen;
+    return 1;
+}
+
+static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+    HMAC_PKEY_CTX *hctx = ctx->data;
+    ASN1_OCTET_STRING *key;
+    switch (type) {
+
+    case EVP_PKEY_CTRL_SET_MAC_KEY:
+        if ((!p2 && p1 > 0) || (p1 < -1))
+            return 0;
+        if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1))
+            return 0;
+        break;
+
+    case EVP_PKEY_CTRL_MD:
+        hctx->md = p2;
+        break;
+
+    case EVP_PKEY_CTRL_DIGESTINIT:
+        key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
+        if (!HMAC_Init_ex(hctx->ctx, key->data, key->length, hctx->md,
+                          ctx->engine))
+            return 0;
+        break;
+
+    default:
+        return -2;
+
+    }
+    return 1;
+}
+
+static int pkey_hmac_ctrl_str(EVP_PKEY_CTX *ctx,
+                              const char *type, const char *value)
+{
+    if (!value) {
+        return 0;
+    }
+    if (strcmp(type, "key") == 0)
+        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value);
+    if (strcmp(type, "hexkey") == 0)
+        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, value);
+    return -2;
+}
+
+const EVP_PKEY_METHOD hmac_pkey_meth = {
+    EVP_PKEY_HMAC,
+    0,
+    pkey_hmac_init,
+    pkey_hmac_copy,
+    pkey_hmac_cleanup,
+
+    0, 0,
+
+    0,
+    pkey_hmac_keygen,
+
+    0, 0,
+
+    0, 0,
+
+    0, 0,
+
+    hmac_signctx_init,
+    hmac_signctx,
+
+    0, 0,
+
+    0, 0,
+
+    0, 0,
+
+    0, 0,
+
+    pkey_hmac_ctrl,
+    pkey_hmac_ctrl_str
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/hmac/hmac.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/hmac/hmac.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/hmac/hmac.c	(revision 331)
@@ -0,0 +1,240 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "internal/cryptlib.h"
+#include <openssl/hmac.h>
+#include <openssl/opensslconf.h>
+#include "hmac_lcl.h"
+
+int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
+                 const EVP_MD *md, ENGINE *impl)
+{
+    int i, j, reset = 0;
+    unsigned char pad[HMAC_MAX_MD_CBLOCK];
+
+    /* If we are changing MD then we must have a key */
+    if (md != NULL && md != ctx->md && (key == NULL || len < 0))
+        return 0;
+
+    if (md != NULL) {
+        reset = 1;
+        ctx->md = md;
+    } else if (ctx->md) {
+        md = ctx->md;
+    } else {
+        return 0;
+    }
+
+    if (key != NULL) {
+        reset = 1;
+        j = EVP_MD_block_size(md);
+        OPENSSL_assert(j <= (int)sizeof(ctx->key));
+        if (j < len) {
+            if (!EVP_DigestInit_ex(ctx->md_ctx, md, impl))
+                goto err;
+            if (!EVP_DigestUpdate(ctx->md_ctx, key, len))
+                goto err;
+            if (!EVP_DigestFinal_ex(ctx->md_ctx, ctx->key,
+                                    &ctx->key_length))
+                goto err;
+        } else {
+            if (len < 0 || len > (int)sizeof(ctx->key))
+                return 0;
+            memcpy(ctx->key, key, len);
+            ctx->key_length = len;
+        }
+        if (ctx->key_length != HMAC_MAX_MD_CBLOCK)
+            memset(&ctx->key[ctx->key_length], 0,
+                   HMAC_MAX_MD_CBLOCK - ctx->key_length);
+    }
+
+    if (reset) {
+        for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++)
+            pad[i] = 0x36 ^ ctx->key[i];
+        if (!EVP_DigestInit_ex(ctx->i_ctx, md, impl))
+            goto err;
+        if (!EVP_DigestUpdate(ctx->i_ctx, pad, EVP_MD_block_size(md)))
+            goto err;
+
+        for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++)
+            pad[i] = 0x5c ^ ctx->key[i];
+        if (!EVP_DigestInit_ex(ctx->o_ctx, md, impl))
+            goto err;
+        if (!EVP_DigestUpdate(ctx->o_ctx, pad, EVP_MD_block_size(md)))
+            goto err;
+    }
+    if (!EVP_MD_CTX_copy_ex(ctx->md_ctx, ctx->i_ctx))
+        goto err;
+    return 1;
+ err:
+    return 0;
+}
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md)
+{
+    if (key && md)
+        HMAC_CTX_reset(ctx);
+    return HMAC_Init_ex(ctx, key, len, md, NULL);
+}
+#endif
+
+int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
+{
+    if (!ctx->md)
+        return 0;
+    return EVP_DigestUpdate(ctx->md_ctx, data, len);
+}
+
+int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
+{
+    unsigned int i;
+    unsigned char buf[EVP_MAX_MD_SIZE];
+
+    if (!ctx->md)
+        goto err;
+
+    if (!EVP_DigestFinal_ex(ctx->md_ctx, buf, &i))
+        goto err;
+    if (!EVP_MD_CTX_copy_ex(ctx->md_ctx, ctx->o_ctx))
+        goto err;
+    if (!EVP_DigestUpdate(ctx->md_ctx, buf, i))
+        goto err;
+    if (!EVP_DigestFinal_ex(ctx->md_ctx, md, len))
+        goto err;
+    return 1;
+ err:
+    return 0;
+}
+
+size_t HMAC_size(const HMAC_CTX *ctx)
+{
+    return EVP_MD_size((ctx)->md);
+}
+
+HMAC_CTX *HMAC_CTX_new(void)
+{
+    HMAC_CTX *ctx = OPENSSL_zalloc(sizeof(HMAC_CTX));
+
+    if (ctx != NULL) {
+        if (!HMAC_CTX_reset(ctx)) {
+            HMAC_CTX_free(ctx);
+            return NULL;
+        }
+    }
+    return ctx;
+}
+
+static void hmac_ctx_cleanup(HMAC_CTX *ctx)
+{
+    EVP_MD_CTX_reset(ctx->i_ctx);
+    EVP_MD_CTX_reset(ctx->o_ctx);
+    EVP_MD_CTX_reset(ctx->md_ctx);
+    ctx->md = NULL;
+    ctx->key_length = 0;
+    OPENSSL_cleanse(ctx->key, sizeof(ctx->key));
+}
+
+void HMAC_CTX_free(HMAC_CTX *ctx)
+{
+    if (ctx != NULL) {
+        hmac_ctx_cleanup(ctx);
+        EVP_MD_CTX_free(ctx->i_ctx);
+        EVP_MD_CTX_free(ctx->o_ctx);
+        EVP_MD_CTX_free(ctx->md_ctx);
+        OPENSSL_free(ctx);
+    }
+}
+
+int HMAC_CTX_reset(HMAC_CTX *ctx)
+{
+    hmac_ctx_cleanup(ctx);
+    if (ctx->i_ctx == NULL)
+        ctx->i_ctx = EVP_MD_CTX_new();
+    if (ctx->i_ctx == NULL)
+        goto err;
+    if (ctx->o_ctx == NULL)
+        ctx->o_ctx = EVP_MD_CTX_new();
+    if (ctx->o_ctx == NULL)
+        goto err;
+    if (ctx->md_ctx == NULL)
+        ctx->md_ctx = EVP_MD_CTX_new();
+    if (ctx->md_ctx == NULL)
+        goto err;
+    ctx->md = NULL;
+    return 1;
+ err:
+    hmac_ctx_cleanup(ctx);
+    return 0;
+}
+
+int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx)
+{
+    if (!HMAC_CTX_reset(dctx))
+        goto err;
+    if (!EVP_MD_CTX_copy_ex(dctx->i_ctx, sctx->i_ctx))
+        goto err;
+    if (!EVP_MD_CTX_copy_ex(dctx->o_ctx, sctx->o_ctx))
+        goto err;
+    if (!EVP_MD_CTX_copy_ex(dctx->md_ctx, sctx->md_ctx))
+        goto err;
+    memcpy(dctx->key, sctx->key, HMAC_MAX_MD_CBLOCK);
+    dctx->key_length = sctx->key_length;
+    dctx->md = sctx->md;
+    return 1;
+ err:
+    hmac_ctx_cleanup(dctx);
+    return 0;
+}
+
+unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
+                    const unsigned char *d, size_t n, unsigned char *md,
+                    unsigned int *md_len)
+{
+    HMAC_CTX *c = NULL;
+    static unsigned char m[EVP_MAX_MD_SIZE];
+    static const unsigned char dummy_key[1] = {'\0'};
+
+    if (md == NULL)
+        md = m;
+    if ((c = HMAC_CTX_new()) == NULL)
+        goto err;
+
+    /* For HMAC_Init_ex, NULL key signals reuse. */
+    if (key == NULL && key_len == 0) {
+        key = dummy_key;
+    }
+
+    if (!HMAC_Init_ex(c, key, key_len, evp_md, NULL))
+        goto err;
+    if (!HMAC_Update(c, d, n))
+        goto err;
+    if (!HMAC_Final(c, md, md_len))
+        goto err;
+    HMAC_CTX_free(c);
+    return md;
+ err:
+    HMAC_CTX_free(c);
+    return NULL;
+}
+
+void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags)
+{
+    EVP_MD_CTX_set_flags(ctx->i_ctx, flags);
+    EVP_MD_CTX_set_flags(ctx->o_ctx, flags);
+    EVP_MD_CTX_set_flags(ctx->md_ctx, flags);
+}
+
+const EVP_MD *HMAC_CTX_get_md(const HMAC_CTX *ctx)
+{
+    return ctx->md;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/hmac/hmac_lcl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/hmac/hmac_lcl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/hmac/hmac_lcl.h	(revision 331)
@@ -0,0 +1,33 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_HMAC_LCL_H
+# define HEADER_HMAC_LCL_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+#if 0                            /* emacs indentation fix */
+}
+#endif
+
+struct hmac_ctx_st {
+    const EVP_MD *md;
+    EVP_MD_CTX *md_ctx;
+    EVP_MD_CTX *i_ctx;
+    EVP_MD_CTX *o_ctx;
+    unsigned int key_length;
+    unsigned char key[HMAC_MAX_MD_CBLOCK];
+};
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/idea/i_cbc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/idea/i_cbc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/idea/i_cbc.c	(revision 331)
@@ -0,0 +1,122 @@
+/*
+ * Copyright 1995-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 <openssl/idea.h>
+#include "idea_lcl.h"
+
+void IDEA_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                      long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,
+                      int encrypt)
+{
+    register unsigned long tin0, tin1;
+    register unsigned long tout0, tout1, xor0, xor1;
+    register long l = length;
+    unsigned long tin[2];
+
+    if (encrypt) {
+        n2l(iv, tout0);
+        n2l(iv, tout1);
+        iv -= 8;
+        for (l -= 8; l >= 0; l -= 8) {
+            n2l(in, tin0);
+            n2l(in, tin1);
+            tin0 ^= tout0;
+            tin1 ^= tout1;
+            tin[0] = tin0;
+            tin[1] = tin1;
+            IDEA_encrypt(tin, ks);
+            tout0 = tin[0];
+            l2n(tout0, out);
+            tout1 = tin[1];
+            l2n(tout1, out);
+        }
+        if (l != -8) {
+            n2ln(in, tin0, tin1, l + 8);
+            tin0 ^= tout0;
+            tin1 ^= tout1;
+            tin[0] = tin0;
+            tin[1] = tin1;
+            IDEA_encrypt(tin, ks);
+            tout0 = tin[0];
+            l2n(tout0, out);
+            tout1 = tin[1];
+            l2n(tout1, out);
+        }
+        l2n(tout0, iv);
+        l2n(tout1, iv);
+    } else {
+        n2l(iv, xor0);
+        n2l(iv, xor1);
+        iv -= 8;
+        for (l -= 8; l >= 0; l -= 8) {
+            n2l(in, tin0);
+            tin[0] = tin0;
+            n2l(in, tin1);
+            tin[1] = tin1;
+            IDEA_encrypt(tin, ks);
+            tout0 = tin[0] ^ xor0;
+            tout1 = tin[1] ^ xor1;
+            l2n(tout0, out);
+            l2n(tout1, out);
+            xor0 = tin0;
+            xor1 = tin1;
+        }
+        if (l != -8) {
+            n2l(in, tin0);
+            tin[0] = tin0;
+            n2l(in, tin1);
+            tin[1] = tin1;
+            IDEA_encrypt(tin, ks);
+            tout0 = tin[0] ^ xor0;
+            tout1 = tin[1] ^ xor1;
+            l2nn(tout0, tout1, out, l + 8);
+            xor0 = tin0;
+            xor1 = tin1;
+        }
+        l2n(xor0, iv);
+        l2n(xor1, iv);
+    }
+    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
+    tin[0] = tin[1] = 0;
+}
+
+void IDEA_encrypt(unsigned long *d, IDEA_KEY_SCHEDULE *key)
+{
+    register IDEA_INT *p;
+    register unsigned long x1, x2, x3, x4, t0, t1, ul;
+
+    x2 = d[0];
+    x1 = (x2 >> 16);
+    x4 = d[1];
+    x3 = (x4 >> 16);
+
+    p = &(key->data[0][0]);
+
+    E_IDEA(0);
+    E_IDEA(1);
+    E_IDEA(2);
+    E_IDEA(3);
+    E_IDEA(4);
+    E_IDEA(5);
+    E_IDEA(6);
+    E_IDEA(7);
+
+    x1 &= 0xffff;
+    idea_mul(x1, x1, *p, ul);
+    p++;
+
+    t0 = x3 + *(p++);
+    t1 = x2 + *(p++);
+
+    x4 &= 0xffff;
+    idea_mul(x4, x4, *p, ul);
+
+    d[0] = (t0 & 0xffff) | ((x1 & 0xffff) << 16);
+    d[1] = (x4 & 0xffff) | ((t1 & 0xffff) << 16);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/idea/i_cfb64.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/idea/i_cfb64.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/idea/i_cfb64.c	(revision 331)
@@ -0,0 +1,74 @@
+/*
+ * Copyright 1995-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 <openssl/idea.h>
+#include "idea_lcl.h"
+
+/*
+ * The input and output encrypted as though 64bit cfb mode is being used.
+ * The extra state information to record how much of the 64bit block we have
+ * used is contained in *num;
+ */
+
+void IDEA_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                        long length, IDEA_KEY_SCHEDULE *schedule,
+                        unsigned char *ivec, int *num, int encrypt)
+{
+    register unsigned long v0, v1, t;
+    register int n = *num;
+    register long l = length;
+    unsigned long ti[2];
+    unsigned char *iv, c, cc;
+
+    iv = (unsigned char *)ivec;
+    if (encrypt) {
+        while (l--) {
+            if (n == 0) {
+                n2l(iv, v0);
+                ti[0] = v0;
+                n2l(iv, v1);
+                ti[1] = v1;
+                IDEA_encrypt((unsigned long *)ti, schedule);
+                iv = (unsigned char *)ivec;
+                t = ti[0];
+                l2n(t, iv);
+                t = ti[1];
+                l2n(t, iv);
+                iv = (unsigned char *)ivec;
+            }
+            c = *(in++) ^ iv[n];
+            *(out++) = c;
+            iv[n] = c;
+            n = (n + 1) & 0x07;
+        }
+    } else {
+        while (l--) {
+            if (n == 0) {
+                n2l(iv, v0);
+                ti[0] = v0;
+                n2l(iv, v1);
+                ti[1] = v1;
+                IDEA_encrypt((unsigned long *)ti, schedule);
+                iv = (unsigned char *)ivec;
+                t = ti[0];
+                l2n(t, iv);
+                t = ti[1];
+                l2n(t, iv);
+                iv = (unsigned char *)ivec;
+            }
+            cc = *(in++);
+            c = iv[n];
+            iv[n] = cc;
+            *(out++) = c ^ cc;
+            n = (n + 1) & 0x07;
+        }
+    }
+    v0 = v1 = ti[0] = ti[1] = t = c = cc = 0;
+    *num = n;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/idea/i_ecb.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/idea/i_ecb.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/idea/i_ecb.c	(revision 331)
@@ -0,0 +1,34 @@
+/*
+ * Copyright 1995-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 <openssl/idea.h>
+#include "idea_lcl.h"
+#include <openssl/opensslv.h>
+
+const char *IDEA_options(void)
+{
+    return ("idea(int)");
+}
+
+void IDEA_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                      IDEA_KEY_SCHEDULE *ks)
+{
+    unsigned long l0, l1, d[2];
+
+    n2l(in, l0);
+    d[0] = l0;
+    n2l(in, l1);
+    d[1] = l1;
+    IDEA_encrypt(d, ks);
+    l0 = d[0];
+    l2n(l0, out);
+    l1 = d[1];
+    l2n(l1, out);
+    l0 = l1 = d[0] = d[1] = 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/idea/i_ofb64.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/idea/i_ofb64.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/idea/i_ofb64.c	(revision 331)
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1995-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 <openssl/idea.h>
+#include "idea_lcl.h"
+
+/*
+ * The input and output encrypted as though 64bit ofb mode is being used.
+ * The extra state information to record how much of the 64bit block we have
+ * used is contained in *num;
+ */
+void IDEA_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+                        long length, IDEA_KEY_SCHEDULE *schedule,
+                        unsigned char *ivec, int *num)
+{
+    register unsigned long v0, v1, t;
+    register int n = *num;
+    register long l = length;
+    unsigned char d[8];
+    register char *dp;
+    unsigned long ti[2];
+    unsigned char *iv;
+    int save = 0;
+
+    iv = (unsigned char *)ivec;
+    n2l(iv, v0);
+    n2l(iv, v1);
+    ti[0] = v0;
+    ti[1] = v1;
+    dp = (char *)d;
+    l2n(v0, dp);
+    l2n(v1, dp);
+    while (l--) {
+        if (n == 0) {
+            IDEA_encrypt((unsigned long *)ti, schedule);
+            dp = (char *)d;
+            t = ti[0];
+            l2n(t, dp);
+            t = ti[1];
+            l2n(t, dp);
+            save++;
+        }
+        *(out++) = *(in++) ^ d[n];
+        n = (n + 1) & 0x07;
+    }
+    if (save) {
+        v0 = ti[0];
+        v1 = ti[1];
+        iv = (unsigned char *)ivec;
+        l2n(v0, iv);
+        l2n(v1, iv);
+    }
+    t = v0 = v1 = ti[0] = ti[1] = 0;
+    *num = n;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/idea/i_skey.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/idea/i_skey.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/idea/i_skey.c	(revision 331)
@@ -0,0 +1,112 @@
+/*
+ * Copyright 1995-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 <openssl/idea.h>
+#include "idea_lcl.h"
+
+static IDEA_INT inverse(unsigned int xin);
+void IDEA_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks)
+{
+    int i;
+    register IDEA_INT *kt, *kf, r0, r1, r2;
+
+    kt = &(ks->data[0][0]);
+    n2s(key, kt[0]);
+    n2s(key, kt[1]);
+    n2s(key, kt[2]);
+    n2s(key, kt[3]);
+    n2s(key, kt[4]);
+    n2s(key, kt[5]);
+    n2s(key, kt[6]);
+    n2s(key, kt[7]);
+
+    kf = kt;
+    kt += 8;
+    for (i = 0; i < 6; i++) {
+        r2 = kf[1];
+        r1 = kf[2];
+        *(kt++) = ((r2 << 9) | (r1 >> 7)) & 0xffff;
+        r0 = kf[3];
+        *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff;
+        r1 = kf[4];
+        *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff;
+        r0 = kf[5];
+        *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff;
+        r1 = kf[6];
+        *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff;
+        r0 = kf[7];
+        *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff;
+        r1 = kf[0];
+        if (i >= 5)
+            break;
+        *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff;
+        *(kt++) = ((r1 << 9) | (r2 >> 7)) & 0xffff;
+        kf += 8;
+    }
+}
+
+void IDEA_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk)
+{
+    int r;
+    register IDEA_INT *fp, *tp, t;
+
+    tp = &(dk->data[0][0]);
+    fp = &(ek->data[8][0]);
+    for (r = 0; r < 9; r++) {
+        *(tp++) = inverse(fp[0]);
+        *(tp++) = ((int)(0x10000L - fp[2]) & 0xffff);
+        *(tp++) = ((int)(0x10000L - fp[1]) & 0xffff);
+        *(tp++) = inverse(fp[3]);
+        if (r == 8)
+            break;
+        fp -= 6;
+        *(tp++) = fp[4];
+        *(tp++) = fp[5];
+    }
+
+    tp = &(dk->data[0][0]);
+    t = tp[1];
+    tp[1] = tp[2];
+    tp[2] = t;
+
+    t = tp[49];
+    tp[49] = tp[50];
+    tp[50] = t;
+}
+
+/* taken directly from the 'paper' I'll have a look at it later */
+static IDEA_INT inverse(unsigned int xin)
+{
+    long n1, n2, q, r, b1, b2, t;
+
+    if (xin == 0)
+        b2 = 0;
+    else {
+        n1 = 0x10001;
+        n2 = xin;
+        b2 = 1;
+        b1 = 0;
+
+        do {
+            r = (n1 % n2);
+            q = (n1 - r) / n2;
+            if (r == 0) {
+                if (b2 < 0)
+                    b2 = 0x10001 + b2;
+            } else {
+                n1 = n2;
+                n2 = r;
+                t = b2;
+                b2 = b1 - q * b2;
+                b1 = t;
+            }
+        } while (r != 0);
+    }
+    return ((IDEA_INT) b2);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/idea/idea_lcl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/idea/idea_lcl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/idea/idea_lcl.h	(revision 331)
@@ -0,0 +1,103 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*
+ * The new form of this macro (check if the a*b == 0) was suggested by Colin
+ * Plumb <colin@nyx10.cs.du.edu>
+ */
+/* Removal of the inner if from from Wei Dai 24/4/96 */
+#define idea_mul(r,a,b,ul) \
+ul=(unsigned long)a*b; \
+if (ul != 0) \
+        { \
+        r=(ul&0xffff)-(ul>>16); \
+        r-=((r)>>16); \
+        } \
+else \
+        r=(-(int)a-b+1);        /* assuming a or b is 0 and in range */
+
+/*
+ * 7/12/95 - Many thanks to Rhys Weatherley <rweather@us.oracle.com> for
+ * pointing out that I was assuming little endian byte order for all
+ * quantities what idea actually used bigendian.  No where in the spec does
+ * it mention this, it is all in terms of 16 bit numbers and even the example
+ * does not use byte streams for the input example :-(. If you byte swap each
+ * pair of input, keys and iv, the functions would produce the output as the
+ * old version :-(.
+ */
+
+/* NOTE - c is not incremented as per n2l */
+#define n2ln(c,l1,l2,n) { \
+                        c+=n; \
+                        l1=l2=0; \
+                        switch (n) { \
+                        case 8: l2 =((unsigned long)(*(--(c))))    ; \
+                        case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
+                        case 6: l2|=((unsigned long)(*(--(c))))<<16; \
+                        case 5: l2|=((unsigned long)(*(--(c))))<<24; \
+                        case 4: l1 =((unsigned long)(*(--(c))))    ; \
+                        case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
+                        case 2: l1|=((unsigned long)(*(--(c))))<<16; \
+                        case 1: l1|=((unsigned long)(*(--(c))))<<24; \
+                                } \
+                        }
+
+/* NOTE - c is not incremented as per l2n */
+#define l2nn(l1,l2,c,n) { \
+                        c+=n; \
+                        switch (n) { \
+                        case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
+                        case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+                        case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+                        case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+                        case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
+                        case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+                        case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+                        case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+                                } \
+                        }
+
+#undef n2l
+#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
+                         l|=((unsigned long)(*((c)++)))<<16L, \
+                         l|=((unsigned long)(*((c)++)))<< 8L, \
+                         l|=((unsigned long)(*((c)++))))
+
+#undef l2n
+#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)     )&0xff))
+
+#undef s2n
+#define s2n(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff))
+
+#undef n2s
+#define n2s(c,l)        (l =((IDEA_INT)(*((c)++)))<< 8L, \
+                         l|=((IDEA_INT)(*((c)++)))      )
+
+
+#define E_IDEA(num) \
+        x1&=0xffff; \
+        idea_mul(x1,x1,*p,ul); p++; \
+        x2+= *(p++); \
+        x3+= *(p++); \
+        x4&=0xffff; \
+        idea_mul(x4,x4,*p,ul); p++; \
+        t0=(x1^x3)&0xffff; \
+        idea_mul(t0,t0,*p,ul); p++; \
+        t1=(t0+(x2^x4))&0xffff; \
+        idea_mul(t1,t1,*p,ul); p++; \
+        t0+=t1; \
+        x1^=t1; \
+        x4^=t0; \
+        ul=x2^t0; /* do the swap to x3 */ \
+        x2=x3^t1; \
+        x3=ul;
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/asn1_int.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/asn1_int.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/asn1_int.h	(revision 331)
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2015-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
+ */
+
+/* Internal ASN1 structures and functions: not for application use */
+
+/* ASN1 public key method structure */
+
+struct evp_pkey_asn1_method_st {
+    int pkey_id;
+    int pkey_base_id;
+    unsigned long pkey_flags;
+    char *pem_str;
+    char *info;
+    int (*pub_decode) (EVP_PKEY *pk, X509_PUBKEY *pub);
+    int (*pub_encode) (X509_PUBKEY *pub, const EVP_PKEY *pk);
+    int (*pub_cmp) (const EVP_PKEY *a, const EVP_PKEY *b);
+    int (*pub_print) (BIO *out, const EVP_PKEY *pkey, int indent,
+                      ASN1_PCTX *pctx);
+    int (*priv_decode) (EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf);
+    int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk);
+    int (*priv_print) (BIO *out, const EVP_PKEY *pkey, int indent,
+                       ASN1_PCTX *pctx);
+    int (*pkey_size) (const EVP_PKEY *pk);
+    int (*pkey_bits) (const EVP_PKEY *pk);
+    int (*pkey_security_bits) (const EVP_PKEY *pk);
+    int (*param_decode) (EVP_PKEY *pkey,
+                         const unsigned char **pder, int derlen);
+    int (*param_encode) (const EVP_PKEY *pkey, unsigned char **pder);
+    int (*param_missing) (const EVP_PKEY *pk);
+    int (*param_copy) (EVP_PKEY *to, const EVP_PKEY *from);
+    int (*param_cmp) (const EVP_PKEY *a, const EVP_PKEY *b);
+    int (*param_print) (BIO *out, const EVP_PKEY *pkey, int indent,
+                        ASN1_PCTX *pctx);
+    int (*sig_print) (BIO *out,
+                      const X509_ALGOR *sigalg, const ASN1_STRING *sig,
+                      int indent, ASN1_PCTX *pctx);
+    void (*pkey_free) (EVP_PKEY *pkey);
+    int (*pkey_ctrl) (EVP_PKEY *pkey, int op, long arg1, void *arg2);
+    /* Legacy functions for old PEM */
+    int (*old_priv_decode) (EVP_PKEY *pkey,
+                            const unsigned char **pder, int derlen);
+    int (*old_priv_encode) (const EVP_PKEY *pkey, unsigned char **pder);
+    /* Custom ASN1 signature verification */
+    int (*item_verify) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+                        X509_ALGOR *a, ASN1_BIT_STRING *sig, EVP_PKEY *pkey);
+    int (*item_sign) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+                      X509_ALGOR *alg1, X509_ALGOR *alg2,
+                      ASN1_BIT_STRING *sig);
+} /* EVP_PKEY_ASN1_METHOD */ ;
+
+DEFINE_STACK_OF_CONST(EVP_PKEY_ASN1_METHOD)
+
+extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD dhx_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[5];
+extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[2];
+
+/*
+ * These are used internally in the ASN1_OBJECT to keep track of whether the
+ * names and data need to be free()ed
+ */
+# define ASN1_OBJECT_FLAG_DYNAMIC         0x01/* internal use */
+# define ASN1_OBJECT_FLAG_CRITICAL        0x02/* critical x509v3 object id */
+# define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04/* internal use */
+# define ASN1_OBJECT_FLAG_DYNAMIC_DATA    0x08/* internal use */
+struct asn1_object_st {
+    const char *sn, *ln;
+    int nid;
+    int length;
+    const unsigned char *data;  /* data remains const after init */
+    int flags;                  /* Should we free this one */
+};
+
+/* ASN1 print context structure */
+
+struct asn1_pctx_st {
+    unsigned long flags;
+    unsigned long nm_flags;
+    unsigned long cert_flags;
+    unsigned long oid_flags;
+    unsigned long str_flags;
+} /* ASN1_PCTX */ ;
+
+int asn1_valid_host(const ASN1_STRING *host);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/async.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/async.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/async.h	(revision 331)
@@ -0,0 +1,14 @@
+/*
+ * 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 <openssl/async.h>
+
+int async_init(void);
+void async_deinit(void);
+
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/bn_conf.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/bn_conf.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/bn_conf.h	(revision 331)
@@ -0,0 +1,28 @@
+/* WARNING: do not edit! */
+/* Generated by Makefile from crypto/include/internal/bn_conf.h.in */
+/*
+ * 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
+ */
+
+#ifndef HEADER_BN_CONF_H
+# define HEADER_BN_CONF_H
+
+/*
+ * The contents of this file are not used in the UEFI build, as
+ * both 32-bit and 64-bit builds are supported from a single run
+ * of the Configure script.
+ */
+
+/* Should we define BN_DIV2W here? */
+
+/* Only one for the following should be defined */
+#undef SIXTY_FOUR_BIT_LONG
+#undef SIXTY_FOUR_BIT
+#define THIRTY_TWO_BIT
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/bn_dh.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/bn_dh.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/bn_dh.h	(revision 331)
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2015-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
+ */
+
+#define declare_dh_bn(x) \
+    const extern BIGNUM _bignum_dh##x##_p;              \
+    const extern BIGNUM _bignum_dh##x##_g;              \
+    const extern BIGNUM _bignum_dh##x##_q;
+
+declare_dh_bn(1024_160)
+declare_dh_bn(2048_224)
+declare_dh_bn(2048_256)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/bn_int.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/bn_int.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/bn_int.h	(revision 331)
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2014-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
+ */
+
+#ifndef HEADER_BN_INT_H
+# define HEADER_BN_INT_H
+
+# include <openssl/bn.h>
+# include <limits.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+BIGNUM *bn_wexpand(BIGNUM *a, int words);
+BIGNUM *bn_expand2(BIGNUM *a, int words);
+
+void bn_correct_top(BIGNUM *a);
+
+/*
+ * Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
+ * This is an array r[] of values that are either zero or odd with an
+ * absolute value less than 2^w satisfying scalar = \sum_j r[j]*2^j where at
+ * most one of any w+1 consecutive digits is non-zero with the exception that
+ * the most significant digit may be only w-1 zeros away from that next
+ * non-zero digit.
+ */
+signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len);
+
+int bn_get_top(const BIGNUM *a);
+
+void bn_set_top(BIGNUM *a, int top);
+
+int bn_get_dmax(const BIGNUM *a);
+
+/* Set all words to zero */
+void bn_set_all_zero(BIGNUM *a);
+
+/*
+ * Copy the internal BIGNUM words into out which holds size elements (and size
+ * must be bigger than top)
+ */
+int bn_copy_words(BN_ULONG *out, const BIGNUM *in, int size);
+
+BN_ULONG *bn_get_words(const BIGNUM *a);
+
+/*
+ * Set the internal data words in a to point to words which contains size
+ * elements. The BN_FLG_STATIC_DATA flag is set
+ */
+void bn_set_static_words(BIGNUM *a, BN_ULONG *words, int size);
+
+/*
+ * Copy words into the BIGNUM |a|, reallocating space as necessary.
+ * The negative flag of |a| is not modified.
+ * Returns 1 on success and 0 on failure.
+ */
+/*
+ * |num_words| is int because bn_expand2 takes an int. This is an internal
+ * function so we simply trust callers not to pass negative values.
+ */
+int bn_set_words(BIGNUM *a, BN_ULONG *words, int num_words);
+
+size_t bn_sizeof_BIGNUM(void);
+
+/*
+ * Return element el from an array of BIGNUMs starting at base (required
+ * because callers do not know the size of BIGNUM at compilation time)
+ */
+BIGNUM *bn_array_el(BIGNUM *base, int el);
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/bn_srp.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/bn_srp.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/bn_srp.h	(revision 331)
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2014-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
+ */
+
+#ifndef OPENSSL_NO_SRP
+
+extern const BIGNUM bn_group_1024;
+
+extern const BIGNUM bn_group_1536;
+
+extern const BIGNUM bn_group_2048;
+
+extern const BIGNUM bn_group_3072;
+
+extern const BIGNUM bn_group_4096;
+
+extern const BIGNUM bn_group_6144;
+
+extern const BIGNUM bn_group_8192;
+
+extern const BIGNUM bn_generator_19;
+
+extern const BIGNUM bn_generator_5;
+
+extern const BIGNUM bn_generator_2;
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/chacha.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/chacha.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/chacha.h	(revision 331)
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2015-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
+ */
+
+#ifndef HEADER_CHACHA_H
+#define HEADER_CHACHA_H
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * ChaCha20_ctr32 encrypts |len| bytes from |inp| with the given key and
+ * nonce and writes the result to |out|, which may be equal to |inp|.
+ * The |key| is not 32 bytes of verbatim key material though, but the
+ * said material collected into 8 32-bit elements array in host byte
+ * order. Same approach applies to nonce: the |counter| argument is
+ * pointer to concatenated nonce and counter values collected into 4
+ * 32-bit elements. This, passing crypto material collected into 32-bit
+ * elements as opposite to passing verbatim byte vectors, is chosen for
+ * efficiency in multi-call scenarios.
+ */
+void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp,
+                    size_t len, const unsigned int key[8],
+                    const unsigned int counter[4]);
+/*
+ * You can notice that there is no key setup procedure. Because it's
+ * as trivial as collecting bytes into 32-bit elements, it's reckoned
+ * that below macro is sufficient.
+ */
+#define CHACHA_U8TOU32(p)  ( \
+                ((unsigned int)(p)[0])     | ((unsigned int)(p)[1]<<8) | \
+                ((unsigned int)(p)[2]<<16) | ((unsigned int)(p)[3]<<24)  )
+
+#define CHACHA_KEY_SIZE		32
+#define CHACHA_CTR_SIZE		16
+#define CHACHA_BLK_SIZE		64
+
+#ifdef __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/cryptlib.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/cryptlib.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/cryptlib.h	(revision 331)
@@ -0,0 +1,81 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_CRYPTLIB_H
+# define HEADER_CRYPTLIB_H
+
+# include <stdlib.h>
+# include <string.h>
+
+# include "e_os.h"
+
+# ifdef OPENSSL_USE_APPLINK
+#  undef BIO_FLAGS_UPLINK
+#  define BIO_FLAGS_UPLINK 0x8000
+#  include "ms/uplink.h"
+# endif
+
+# include <openssl/crypto.h>
+# include <openssl/buffer.h>
+# include <openssl/bio.h>
+# include <openssl/err.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct ex_callback_st EX_CALLBACK;
+
+DEFINE_STACK_OF(EX_CALLBACK)
+
+typedef struct app_mem_info_st APP_INFO;
+
+typedef struct mem_st MEM;
+DEFINE_LHASH_OF(MEM);
+
+# ifndef OPENSSL_SYS_VMS
+#  define X509_CERT_AREA          OPENSSLDIR ""
+#  define X509_CERT_DIR           OPENSSLDIR "/certs"
+#  define X509_CERT_FILE          OPENSSLDIR "/cert.pem"
+#  define X509_PRIVATE_DIR        OPENSSLDIR "/private"
+#  define CTLOG_FILE              OPENSSLDIR "/ct_log_list.cnf"
+# else
+#  define X509_CERT_AREA          "OSSL$DATAROOT:[000000]"
+#  define X509_CERT_DIR           "OSSL$DATAROOT:[CERTS]"
+#  define X509_CERT_FILE          "OSSL$DATAROOT:[000000]cert.pem"
+#  define X509_PRIVATE_DIR        "OSSL$DATAROOT:[PRIVATE]"
+#  define CTLOG_FILE              "OSSL$DATAROOT:[000000]ct_log_list.cnf"
+# endif
+
+# define X509_CERT_DIR_EVP        "SSL_CERT_DIR"
+# define X509_CERT_FILE_EVP       "SSL_CERT_FILE"
+# define CTLOG_FILE_EVP           "CTLOG_FILE"
+
+/* size of string representations */
+# define DECIMAL_SIZE(type)      ((sizeof(type)*8+2)/3+1)
+# define HEX_SIZE(type)          (sizeof(type)*2)
+
+void OPENSSL_cpuid_setup(void);
+extern unsigned int OPENSSL_ia32cap_P[];
+void OPENSSL_showfatal(const char *fmta, ...);
+extern int OPENSSL_NONPIC_relocated;
+void crypto_cleanup_all_ex_data_int(void);
+
+int openssl_strerror_r(int errnum, char *buf, size_t buflen);
+# if !defined(OPENSSL_NO_STDIO)
+FILE *openssl_fopen(const char *filename, const char *mode);
+# else
+void *openssl_fopen(const char *filename, const char *mode);
+# endif
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/cryptlib_int.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/cryptlib_int.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/cryptlib_int.h	(revision 331)
@@ -0,0 +1,31 @@
+/*
+ * 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 <internal/cryptlib.h>
+
+/* This file is not scanned by mkdef.pl, whereas cryptlib.h is */
+
+struct thread_local_inits_st {
+    int async;
+    int err_state;
+};
+
+int ossl_init_thread_start(uint64_t opts);
+
+/*
+ * OPENSSL_INIT flags. The primary list of these is in crypto.h. Flags below
+ * are those omitted from crypto.h because they are "reserved for internal
+ * use".
+ */
+# define OPENSSL_INIT_ZLIB                   0x00010000L
+
+/* OPENSSL_INIT_THREAD flags */
+# define OPENSSL_INIT_THREAD_ASYNC           0x01
+# define OPENSSL_INIT_THREAD_ERR_STATE       0x02
+
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/dso_conf.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/dso_conf.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/dso_conf.h	(revision 331)
@@ -0,0 +1,16 @@
+/* WARNING: do not edit! */
+/* Generated by Makefile from crypto/include/internal/dso_conf.h.in */
+/*
+ * 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
+ */
+
+#ifndef HEADER_DSO_CONF_H
+# define HEADER_DSO_CONF_H
+
+# define DSO_EXTENSION ".so"
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/engine.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/engine.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/engine.h	(revision 331)
@@ -0,0 +1,20 @@
+/*
+ * 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 <openssl/engine.h>
+
+void engine_load_openssl_int(void);
+void engine_load_cryptodev_int(void);
+void engine_load_rdrand_int(void);
+void engine_load_dynamic_int(void);
+void engine_load_padlock_int(void);
+void engine_load_capi_int(void);
+void engine_load_dasync_int(void);
+void engine_load_afalg_int(void);
+void engine_cleanup_int(void);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/err_int.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/err_int.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/err_int.h	(revision 331)
@@ -0,0 +1,17 @@
+/*
+ * 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
+ */
+
+#ifndef INTERNAL_ERR_INT_H
+# define INTERNAL_ERR_INT_H
+
+int err_load_crypto_strings_int(void);
+void err_cleanup(void);
+void err_delete_thread_state(void);
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/evp_int.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/evp_int.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/evp_int.h	(revision 331)
@@ -0,0 +1,389 @@
+/*
+ * Copyright 2015-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
+ */
+
+struct evp_pkey_ctx_st {
+    /* Method associated with this operation */
+    const EVP_PKEY_METHOD *pmeth;
+    /* Engine that implements this method or NULL if builtin */
+    ENGINE *engine;
+    /* Key: may be NULL */
+    EVP_PKEY *pkey;
+    /* Peer key for key agreement, may be NULL */
+    EVP_PKEY *peerkey;
+    /* Actual operation */
+    int operation;
+    /* Algorithm specific data */
+    void *data;
+    /* Application specific data */
+    void *app_data;
+    /* Keygen callback */
+    EVP_PKEY_gen_cb *pkey_gencb;
+    /* implementation specific keygen data */
+    int *keygen_info;
+    int keygen_info_count;
+} /* EVP_PKEY_CTX */ ;
+
+#define EVP_PKEY_FLAG_DYNAMIC   1
+
+struct evp_pkey_method_st {
+    int pkey_id;
+    int flags;
+    int (*init) (EVP_PKEY_CTX *ctx);
+    int (*copy) (EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src);
+    void (*cleanup) (EVP_PKEY_CTX *ctx);
+    int (*paramgen_init) (EVP_PKEY_CTX *ctx);
+    int (*paramgen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
+    int (*keygen_init) (EVP_PKEY_CTX *ctx);
+    int (*keygen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
+    int (*sign_init) (EVP_PKEY_CTX *ctx);
+    int (*sign) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+                 const unsigned char *tbs, size_t tbslen);
+    int (*verify_init) (EVP_PKEY_CTX *ctx);
+    int (*verify) (EVP_PKEY_CTX *ctx,
+                   const unsigned char *sig, size_t siglen,
+                   const unsigned char *tbs, size_t tbslen);
+    int (*verify_recover_init) (EVP_PKEY_CTX *ctx);
+    int (*verify_recover) (EVP_PKEY_CTX *ctx,
+                           unsigned char *rout, size_t *routlen,
+                           const unsigned char *sig, size_t siglen);
+    int (*signctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
+    int (*signctx) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+                    EVP_MD_CTX *mctx);
+    int (*verifyctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
+    int (*verifyctx) (EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen,
+                      EVP_MD_CTX *mctx);
+    int (*encrypt_init) (EVP_PKEY_CTX *ctx);
+    int (*encrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+                    const unsigned char *in, size_t inlen);
+    int (*decrypt_init) (EVP_PKEY_CTX *ctx);
+    int (*decrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
+                    const unsigned char *in, size_t inlen);
+    int (*derive_init) (EVP_PKEY_CTX *ctx);
+    int (*derive) (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
+    int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
+    int (*ctrl_str) (EVP_PKEY_CTX *ctx, const char *type, const char *value);
+} /* EVP_PKEY_METHOD */ ;
+
+DEFINE_STACK_OF_CONST(EVP_PKEY_METHOD)
+
+void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx);
+
+extern const EVP_PKEY_METHOD cmac_pkey_meth;
+extern const EVP_PKEY_METHOD dh_pkey_meth;
+extern const EVP_PKEY_METHOD dhx_pkey_meth;
+extern const EVP_PKEY_METHOD dsa_pkey_meth;
+extern const EVP_PKEY_METHOD ec_pkey_meth;
+extern const EVP_PKEY_METHOD ecx25519_pkey_meth;
+extern const EVP_PKEY_METHOD hmac_pkey_meth;
+extern const EVP_PKEY_METHOD rsa_pkey_meth;
+extern const EVP_PKEY_METHOD tls1_prf_pkey_meth;
+extern const EVP_PKEY_METHOD hkdf_pkey_meth;
+
+struct evp_md_st {
+    int type;
+    int pkey_type;
+    int md_size;
+    unsigned long flags;
+    int (*init) (EVP_MD_CTX *ctx);
+    int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
+    int (*final) (EVP_MD_CTX *ctx, unsigned char *md);
+    int (*copy) (EVP_MD_CTX *to, const EVP_MD_CTX *from);
+    int (*cleanup) (EVP_MD_CTX *ctx);
+    int block_size;
+    int ctx_size;               /* how big does the ctx->md_data need to be */
+    /* control function */
+    int (*md_ctrl) (EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
+} /* EVP_MD */ ;
+
+struct evp_cipher_st {
+    int nid;
+    int block_size;
+    /* Default value for variable length ciphers */
+    int key_len;
+    int iv_len;
+    /* Various flags */
+    unsigned long flags;
+    /* init key */
+    int (*init) (EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                 const unsigned char *iv, int enc);
+    /* encrypt/decrypt data */
+    int (*do_cipher) (EVP_CIPHER_CTX *ctx, unsigned char *out,
+                      const unsigned char *in, size_t inl);
+    /* cleanup ctx */
+    int (*cleanup) (EVP_CIPHER_CTX *);
+    /* how big ctx->cipher_data needs to be */
+    int ctx_size;
+    /* Populate a ASN1_TYPE with parameters */
+    int (*set_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *);
+    /* Get parameters from a ASN1_TYPE */
+    int (*get_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *);
+    /* Miscellaneous operations */
+    int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr);
+    /* Application data */
+    void *app_data;
+} /* EVP_CIPHER */ ;
+
+/* Macros to code block cipher wrappers */
+
+/* Wrapper functions for each cipher mode */
+
+#define EVP_C_DATA(kstruct, ctx) \
+        ((kstruct *)EVP_CIPHER_CTX_get_cipher_data(ctx))
+
+#define BLOCK_CIPHER_ecb_loop() \
+        size_t i, bl; \
+        bl = EVP_CIPHER_CTX_cipher(ctx)->block_size;    \
+        if (inl < bl) return 1;\
+        inl -= bl; \
+        for (i=0; i <= inl; i+=bl)
+
+#define BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
+static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
+{\
+        BLOCK_CIPHER_ecb_loop() \
+            cprefix##_ecb_encrypt(in + i, out + i, &EVP_C_DATA(kstruct,ctx)->ksched, EVP_CIPHER_CTX_encrypting(ctx)); \
+        return 1;\
+}
+
+#define EVP_MAXCHUNK ((size_t)1<<(sizeof(long)*8-2))
+
+#define BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched) \
+    static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
+{\
+        while(inl>=EVP_MAXCHUNK) {\
+            int num = EVP_CIPHER_CTX_num(ctx);\
+            cprefix##_ofb##cbits##_encrypt(in, out, (long)EVP_MAXCHUNK, &EVP_C_DATA(kstruct,ctx)->ksched, EVP_CIPHER_CTX_iv_noconst(ctx), &num); \
+            EVP_CIPHER_CTX_set_num(ctx, num);\
+            inl-=EVP_MAXCHUNK;\
+            in +=EVP_MAXCHUNK;\
+            out+=EVP_MAXCHUNK;\
+        }\
+        if (inl) {\
+            int num = EVP_CIPHER_CTX_num(ctx);\
+            cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &EVP_C_DATA(kstruct,ctx)->ksched, EVP_CIPHER_CTX_iv_noconst(ctx), &num); \
+            EVP_CIPHER_CTX_set_num(ctx, num);\
+        }\
+        return 1;\
+}
+
+#define BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
+static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
+{\
+        while(inl>=EVP_MAXCHUNK) \
+            {\
+            cprefix##_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, &EVP_C_DATA(kstruct,ctx)->ksched, EVP_CIPHER_CTX_iv_noconst(ctx), EVP_CIPHER_CTX_encrypting(ctx));\
+            inl-=EVP_MAXCHUNK;\
+            in +=EVP_MAXCHUNK;\
+            out+=EVP_MAXCHUNK;\
+            }\
+        if (inl)\
+            cprefix##_cbc_encrypt(in, out, (long)inl, &EVP_C_DATA(kstruct,ctx)->ksched, EVP_CIPHER_CTX_iv_noconst(ctx), EVP_CIPHER_CTX_encrypting(ctx));\
+        return 1;\
+}
+
+#define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched)  \
+static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \
+{\
+    size_t chunk = EVP_MAXCHUNK;\
+    if (cbits == 1)  chunk >>= 3;\
+    if (inl < chunk) chunk = inl;\
+    while (inl && inl >= chunk)\
+    {\
+        int num = EVP_CIPHER_CTX_num(ctx);\
+        cprefix##_cfb##cbits##_encrypt(in, out, (long) \
+            ((cbits == 1) \
+                && !EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS) \
+                ? inl*8 : inl), \
+            &EVP_C_DATA(kstruct, ctx)->ksched, EVP_CIPHER_CTX_iv_noconst(ctx),\
+            &num, EVP_CIPHER_CTX_encrypting(ctx));\
+        EVP_CIPHER_CTX_set_num(ctx, num);\
+        inl -= chunk;\
+        in += chunk;\
+        out += chunk;\
+        if (inl < chunk) chunk = inl;\
+    }\
+    return 1;\
+}
+
+#define BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \
+        BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \
+        BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
+        BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \
+        BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched)
+
+#define BLOCK_CIPHER_def1(cname, nmode, mode, MODE, kstruct, nid, block_size, \
+                          key_len, iv_len, flags, init_key, cleanup, \
+                          set_asn1, get_asn1, ctrl) \
+static const EVP_CIPHER cname##_##mode = { \
+        nid##_##nmode, block_size, key_len, iv_len, \
+        flags | EVP_CIPH_##MODE##_MODE, \
+        init_key, \
+        cname##_##mode##_cipher, \
+        cleanup, \
+        sizeof(kstruct), \
+        set_asn1, get_asn1,\
+        ctrl, \
+        NULL \
+}; \
+const EVP_CIPHER *EVP_##cname##_##mode(void) { return &cname##_##mode; }
+
+#define BLOCK_CIPHER_def_cbc(cname, kstruct, nid, block_size, key_len, \
+                             iv_len, flags, init_key, cleanup, set_asn1, \
+                             get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, cbc, cbc, CBC, kstruct, nid, block_size, key_len, \
+                  iv_len, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
+
+#define BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, \
+                             iv_len, cbits, flags, init_key, cleanup, \
+                             set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, cfb##cbits, cfb##cbits, CFB, kstruct, nid, 1, \
+                  key_len, iv_len, flags, init_key, cleanup, set_asn1, \
+                  get_asn1, ctrl)
+
+#define BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, \
+                             iv_len, cbits, flags, init_key, cleanup, \
+                             set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, ofb##cbits, ofb, OFB, kstruct, nid, 1, \
+                  key_len, iv_len, flags, init_key, cleanup, set_asn1, \
+                  get_asn1, ctrl)
+
+#define BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, \
+                             flags, init_key, cleanup, set_asn1, \
+                             get_asn1, ctrl) \
+BLOCK_CIPHER_def1(cname, ecb, ecb, ECB, kstruct, nid, block_size, key_len, \
+                  0, flags, init_key, cleanup, set_asn1, get_asn1, ctrl)
+
+#define BLOCK_CIPHER_defs(cname, kstruct, \
+                          nid, block_size, key_len, iv_len, cbits, flags, \
+                          init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_cbc(cname, kstruct, nid, block_size, key_len, iv_len, flags, \
+                     init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_cfb(cname, kstruct, nid, key_len, iv_len, cbits, \
+                     flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_ofb(cname, kstruct, nid, key_len, iv_len, cbits, \
+                     flags, init_key, cleanup, set_asn1, get_asn1, ctrl) \
+BLOCK_CIPHER_def_ecb(cname, kstruct, nid, block_size, key_len, flags, \
+                     init_key, cleanup, set_asn1, get_asn1, ctrl)
+
+/*-
+#define BLOCK_CIPHER_defs(cname, kstruct, \
+                                nid, block_size, key_len, iv_len, flags,\
+                                 init_key, cleanup, set_asn1, get_asn1, ctrl)\
+static const EVP_CIPHER cname##_cbc = {\
+        nid##_cbc, block_size, key_len, iv_len, \
+        flags | EVP_CIPH_CBC_MODE,\
+        init_key,\
+        cname##_cbc_cipher,\
+        cleanup,\
+        sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+                sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+        set_asn1, get_asn1,\
+        ctrl, \
+        NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_cbc(void) { return &cname##_cbc; }\
+static const EVP_CIPHER cname##_cfb = {\
+        nid##_cfb64, 1, key_len, iv_len, \
+        flags | EVP_CIPH_CFB_MODE,\
+        init_key,\
+        cname##_cfb_cipher,\
+        cleanup,\
+        sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+                sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+        set_asn1, get_asn1,\
+        ctrl,\
+        NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_cfb(void) { return &cname##_cfb; }\
+static const EVP_CIPHER cname##_ofb = {\
+        nid##_ofb64, 1, key_len, iv_len, \
+        flags | EVP_CIPH_OFB_MODE,\
+        init_key,\
+        cname##_ofb_cipher,\
+        cleanup,\
+        sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+                sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+        set_asn1, get_asn1,\
+        ctrl,\
+        NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_ofb(void) { return &cname##_ofb; }\
+static const EVP_CIPHER cname##_ecb = {\
+        nid##_ecb, block_size, key_len, iv_len, \
+        flags | EVP_CIPH_ECB_MODE,\
+        init_key,\
+        cname##_ecb_cipher,\
+        cleanup,\
+        sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\
+                sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\
+        set_asn1, get_asn1,\
+        ctrl,\
+        NULL \
+};\
+const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; }
+*/
+
+#define IMPLEMENT_BLOCK_CIPHER(cname, ksched, cprefix, kstruct, nid, \
+                               block_size, key_len, iv_len, cbits, \
+                               flags, init_key, \
+                               cleanup, set_asn1, get_asn1, ctrl) \
+        BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \
+        BLOCK_CIPHER_defs(cname, kstruct, nid, block_size, key_len, iv_len, \
+                          cbits, flags, init_key, cleanup, set_asn1, \
+                          get_asn1, ctrl)
+
+#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len,fl) \
+        BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \
+        BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \
+                             NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \
+                             (fl)|EVP_CIPH_FLAG_DEFAULT_ASN1, \
+                             cipher##_init_key, NULL, NULL, NULL, NULL)
+
+
+/*
+ * Type needs to be a bit field Sub-type needs to be for variations on the
+ * method, as in, can it do arbitrary encryption....
+ */
+struct evp_pkey_st {
+    int type;
+    int save_type;
+    int references;
+    const EVP_PKEY_ASN1_METHOD *ameth;
+    ENGINE *engine;
+    union {
+        void *ptr;
+# ifndef OPENSSL_NO_RSA
+        struct rsa_st *rsa;     /* RSA */
+# endif
+# ifndef OPENSSL_NO_DSA
+        struct dsa_st *dsa;     /* DSA */
+# endif
+# ifndef OPENSSL_NO_DH
+        struct dh_st *dh;       /* DH */
+# endif
+# ifndef OPENSSL_NO_EC
+        struct ec_key_st *ec;   /* ECC */
+# endif
+    } pkey;
+    int save_parameters;
+    STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
+    CRYPTO_RWLOCK *lock;
+} /* EVP_PKEY */ ;
+
+
+void openssl_add_all_ciphers_int(void);
+void openssl_add_all_digests_int(void);
+void evp_cleanup_int(void);
+
+/* Pulling defines out of C soure files */
+
+#define EVP_RC4_KEY_SIZE 16
+#ifndef TLS1_1_VERSION
+# define TLS1_1_VERSION   0x0302
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/md32_common.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/md32_common.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/md32_common.h	(revision 331)
@@ -0,0 +1,383 @@
+/*
+ * Copyright 1999-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
+ */
+
+/*-
+ * This is a generic 32 bit "collector" for message digest algorithms.
+ * Whenever needed it collects input character stream into chunks of
+ * 32 bit values and invokes a block function that performs actual hash
+ * calculations.
+ *
+ * Porting guide.
+ *
+ * Obligatory macros:
+ *
+ * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
+ *      this macro defines byte order of input stream.
+ * HASH_CBLOCK
+ *      size of a unit chunk HASH_BLOCK operates on.
+ * HASH_LONG
+ *      has to be at lest 32 bit wide.
+ * HASH_CTX
+ *      context structure that at least contains following
+ *      members:
+ *              typedef struct {
+ *                      ...
+ *                      HASH_LONG       Nl,Nh;
+ *                      either {
+ *                      HASH_LONG       data[HASH_LBLOCK];
+ *                      unsigned char   data[HASH_CBLOCK];
+ *                      };
+ *                      unsigned int    num;
+ *                      ...
+ *                      } HASH_CTX;
+ *      data[] vector is expected to be zeroed upon first call to
+ *      HASH_UPDATE.
+ * HASH_UPDATE
+ *      name of "Update" function, implemented here.
+ * HASH_TRANSFORM
+ *      name of "Transform" function, implemented here.
+ * HASH_FINAL
+ *      name of "Final" function, implemented here.
+ * HASH_BLOCK_DATA_ORDER
+ *      name of "block" function capable of treating *unaligned* input
+ *      message in original (data) byte order, implemented externally.
+ * HASH_MAKE_STRING
+ *      macro convering context variables to an ASCII hash string.
+ *
+ * MD5 example:
+ *
+ *      #define DATA_ORDER_IS_LITTLE_ENDIAN
+ *
+ *      #define HASH_LONG               MD5_LONG
+ *      #define HASH_CTX                MD5_CTX
+ *      #define HASH_CBLOCK             MD5_CBLOCK
+ *      #define HASH_UPDATE             MD5_Update
+ *      #define HASH_TRANSFORM          MD5_Transform
+ *      #define HASH_FINAL              MD5_Final
+ *      #define HASH_BLOCK_DATA_ORDER   md5_block_data_order
+ *
+ *                                      <appro@fy.chalmers.se>
+ */
+
+#include <openssl/crypto.h>
+
+#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+# error "DATA_ORDER must be defined!"
+#endif
+
+#ifndef HASH_CBLOCK
+# error "HASH_CBLOCK must be defined!"
+#endif
+#ifndef HASH_LONG
+# error "HASH_LONG must be defined!"
+#endif
+#ifndef HASH_CTX
+# error "HASH_CTX must be defined!"
+#endif
+
+#ifndef HASH_UPDATE
+# error "HASH_UPDATE must be defined!"
+#endif
+#ifndef HASH_TRANSFORM
+# error "HASH_TRANSFORM must be defined!"
+#endif
+#ifndef HASH_FINAL
+# error "HASH_FINAL must be defined!"
+#endif
+
+#ifndef HASH_BLOCK_DATA_ORDER
+# error "HASH_BLOCK_DATA_ORDER must be defined!"
+#endif
+
+/*
+ * Engage compiler specific rotate intrinsic function if available.
+ */
+#undef ROTATE
+#ifndef PEDANTIC
+# if defined(_MSC_VER)
+#  define ROTATE(a,n)   _lrotl(a,n)
+# elif defined(__ICC)
+#  define ROTATE(a,n)   _rotl(a,n)
+# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+  /*
+   * Some GNU C inline assembler templates. Note that these are
+   * rotates by *constant* number of bits! But that's exactly
+   * what we need here...
+   *                                    <appro@fy.chalmers.se>
+   */
+#  if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
+#   define ROTATE(a,n)  ({ register unsigned int ret;   \
+                                asm (                   \
+                                "roll %1,%0"            \
+                                : "=r"(ret)             \
+                                : "I"(n), "0"((unsigned int)(a))        \
+                                : "cc");                \
+                           ret;                         \
+                        })
+#  elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
+        defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__)
+#   define ROTATE(a,n)  ({ register unsigned int ret;   \
+                                asm (                   \
+                                "rlwinm %0,%1,%2,0,31"  \
+                                : "=r"(ret)             \
+                                : "r"(a), "I"(n));      \
+                           ret;                         \
+                        })
+#  elif defined(__s390x__)
+#   define ROTATE(a,n) ({ register unsigned int ret;    \
+                                asm ("rll %0,%1,%2"     \
+                                : "=r"(ret)             \
+                                : "r"(a), "I"(n));      \
+                          ret;                          \
+                        })
+#  endif
+# endif
+#endif                          /* PEDANTIC */
+
+#ifndef ROTATE
+# define ROTATE(a,n)     (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
+#endif
+
+#if defined(DATA_ORDER_IS_BIG_ENDIAN)
+
+# ifndef PEDANTIC
+#  if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+#   if ((defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)) || \
+      (defined(__x86_64) || defined(__x86_64__))
+#    if !defined(B_ENDIAN)
+    /*
+     * This gives ~30-40% performance improvement in SHA-256 compiled
+     * with gcc [on P4]. Well, first macro to be frank. We can pull
+     * this trick on x86* platforms only, because these CPUs can fetch
+     * unaligned data without raising an exception.
+     */
+#     define HOST_c2l(c,l)        ({ unsigned int r=*((const unsigned int *)(c)); \
+                                   asm ("bswapl %0":"=r"(r):"0"(r));    \
+                                   (c)+=4; (l)=r;                       })
+#     define HOST_l2c(l,c)        ({ unsigned int r=(l);                  \
+                                   asm ("bswapl %0":"=r"(r):"0"(r));    \
+                                   *((unsigned int *)(c))=r; (c)+=4; r; })
+#    endif
+#   elif defined(__aarch64__)
+#    if defined(__BYTE_ORDER__)
+#     if defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
+#      define HOST_c2l(c,l)      ({ unsigned int r;              \
+                                   asm ("rev    %w0,%w1"        \
+                                        :"=r"(r)                \
+                                        :"r"(*((const unsigned int *)(c))));\
+                                   (c)+=4; (l)=r;               })
+#      define HOST_l2c(l,c)      ({ unsigned int r;              \
+                                   asm ("rev    %w0,%w1"        \
+                                        :"=r"(r)                \
+                                        :"r"((unsigned int)(l)));\
+                                   *((unsigned int *)(c))=r; (c)+=4; r; })
+#     elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
+#      define HOST_c2l(c,l)      ((l)=*((const unsigned int *)(c)), (c)+=4, (l))
+#      define HOST_l2c(l,c)      (*((unsigned int *)(c))=(l), (c)+=4, (l))
+#     endif
+#    endif
+#   endif
+#  endif
+#  if defined(__s390__) || defined(__s390x__)
+#   define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l))
+#   define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l))
+#  endif
+# endif
+
+# ifndef HOST_c2l
+#  define HOST_c2l(c,l)   (l =(((unsigned long)(*((c)++)))<<24),          \
+                         l|=(((unsigned long)(*((c)++)))<<16),          \
+                         l|=(((unsigned long)(*((c)++)))<< 8),          \
+                         l|=(((unsigned long)(*((c)++)))    )           )
+# endif
+# ifndef HOST_l2c
+#  define HOST_l2c(l,c)   (*((c)++)=(unsigned char)(((l)>>24)&0xff),      \
+                         *((c)++)=(unsigned char)(((l)>>16)&0xff),      \
+                         *((c)++)=(unsigned char)(((l)>> 8)&0xff),      \
+                         *((c)++)=(unsigned char)(((l)    )&0xff),      \
+                         l)
+# endif
+
+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+
+# ifndef PEDANTIC
+#  if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+#   if defined(__s390x__)
+#    define HOST_c2l(c,l)        ({ asm ("lrv    %0,%1"                  \
+                                   :"=d"(l) :"m"(*(const unsigned int *)(c)));\
+                                   (c)+=4; (l);                         })
+#    define HOST_l2c(l,c)        ({ asm ("strv   %1,%0"                  \
+                                   :"=m"(*(unsigned int *)(c)) :"d"(l));\
+                                   (c)+=4; (l);                         })
+#   endif
+#  endif
+#  if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
+#   ifndef B_ENDIAN
+    /* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
+#    define HOST_c2l(c,l)        ((l)=*((const unsigned int *)(c)), (c)+=4, l)
+#    define HOST_l2c(l,c)        (*((unsigned int *)(c))=(l), (c)+=4, l)
+#   endif
+#  endif
+# endif
+
+# ifndef HOST_c2l
+#  define HOST_c2l(c,l)   (l =(((unsigned long)(*((c)++)))    ),          \
+                         l|=(((unsigned long)(*((c)++)))<< 8),          \
+                         l|=(((unsigned long)(*((c)++)))<<16),          \
+                         l|=(((unsigned long)(*((c)++)))<<24)           )
+# endif
+# ifndef HOST_l2c
+#  define HOST_l2c(l,c)   (*((c)++)=(unsigned char)(((l)    )&0xff),      \
+                         *((c)++)=(unsigned char)(((l)>> 8)&0xff),      \
+                         *((c)++)=(unsigned char)(((l)>>16)&0xff),      \
+                         *((c)++)=(unsigned char)(((l)>>24)&0xff),      \
+                         l)
+# endif
+
+#endif
+
+/*
+ * Time for some action:-)
+ */
+
+int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len)
+{
+    const unsigned char *data = data_;
+    unsigned char *p;
+    HASH_LONG l;
+    size_t n;
+
+    if (len == 0)
+        return 1;
+
+    l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL;
+    /*
+     * 95-05-24 eay Fixed a bug with the overflow handling, thanks to Wei Dai
+     * <weidai@eskimo.com> for pointing it out.
+     */
+    if (l < c->Nl)              /* overflow */
+        c->Nh++;
+    c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on
+                                       * 16-bit */
+    c->Nl = l;
+
+    n = c->num;
+    if (n != 0) {
+        p = (unsigned char *)c->data;
+
+        if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) {
+            memcpy(p + n, data, HASH_CBLOCK - n);
+            HASH_BLOCK_DATA_ORDER(c, p, 1);
+            n = HASH_CBLOCK - n;
+            data += n;
+            len -= n;
+            c->num = 0;
+            /*
+             * We use memset rather than OPENSSL_cleanse() here deliberately.
+             * Using OPENSSL_cleanse() here could be a performance issue. It
+             * will get properly cleansed on finalisation so this isn't a
+             * security problem.
+             */
+            memset(p, 0, HASH_CBLOCK); /* keep it zeroed */
+        } else {
+            memcpy(p + n, data, len);
+            c->num += (unsigned int)len;
+            return 1;
+        }
+    }
+
+    n = len / HASH_CBLOCK;
+    if (n > 0) {
+        HASH_BLOCK_DATA_ORDER(c, data, n);
+        n *= HASH_CBLOCK;
+        data += n;
+        len -= n;
+    }
+
+    if (len != 0) {
+        p = (unsigned char *)c->data;
+        c->num = (unsigned int)len;
+        memcpy(p, data, len);
+    }
+    return 1;
+}
+
+void HASH_TRANSFORM(HASH_CTX *c, const unsigned char *data)
+{
+    HASH_BLOCK_DATA_ORDER(c, data, 1);
+}
+
+int HASH_FINAL(unsigned char *md, HASH_CTX *c)
+{
+    unsigned char *p = (unsigned char *)c->data;
+    size_t n = c->num;
+
+    p[n] = 0x80;                /* there is always room for one */
+    n++;
+
+    if (n > (HASH_CBLOCK - 8)) {
+        memset(p + n, 0, HASH_CBLOCK - n);
+        n = 0;
+        HASH_BLOCK_DATA_ORDER(c, p, 1);
+    }
+    memset(p + n, 0, HASH_CBLOCK - 8 - n);
+
+    p += HASH_CBLOCK - 8;
+#if   defined(DATA_ORDER_IS_BIG_ENDIAN)
+    (void)HOST_l2c(c->Nh, p);
+    (void)HOST_l2c(c->Nl, p);
+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+    (void)HOST_l2c(c->Nl, p);
+    (void)HOST_l2c(c->Nh, p);
+#endif
+    p -= HASH_CBLOCK;
+    HASH_BLOCK_DATA_ORDER(c, p, 1);
+    c->num = 0;
+    OPENSSL_cleanse(p, HASH_CBLOCK);
+
+#ifndef HASH_MAKE_STRING
+# error "HASH_MAKE_STRING must be defined!"
+#else
+    HASH_MAKE_STRING(c, md);
+#endif
+
+    return 1;
+}
+
+#ifndef MD32_REG_T
+# if defined(__alpha) || defined(__sparcv9) || defined(__mips)
+#  define MD32_REG_T long
+/*
+ * This comment was originally written for MD5, which is why it
+ * discusses A-D. But it basically applies to all 32-bit digests,
+ * which is why it was moved to common header file.
+ *
+ * In case you wonder why A-D are declared as long and not
+ * as MD5_LONG. Doing so results in slight performance
+ * boost on LP64 architectures. The catch is we don't
+ * really care if 32 MSBs of a 64-bit register get polluted
+ * with eventual overflows as we *save* only 32 LSBs in
+ * *either* case. Now declaring 'em long excuses the compiler
+ * from keeping 32 MSBs zeroed resulting in 13% performance
+ * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
+ * Well, to be honest it should say that this *prevents*
+ * performance degradation.
+ *                              <appro@fy.chalmers.se>
+ */
+# else
+/*
+ * Above is not absolute and there are LP64 compilers that
+ * generate better code if MD32_REG_T is defined int. The above
+ * pre-processor condition reflects the circumstances under which
+ * the conclusion was made and is subject to further extension.
+ *                              <appro@fy.chalmers.se>
+ */
+#  define MD32_REG_T int
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/objects.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/objects.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/objects.h	(revision 331)
@@ -0,0 +1,12 @@
+/*
+ * 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 <openssl/objects.h>
+
+void obj_cleanup_int(void);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/poly1305.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/poly1305.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/poly1305.h	(revision 331)
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2015-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 <stddef.h>
+
+#define POLY1305_BLOCK_SIZE 16
+
+typedef struct poly1305_context POLY1305;
+
+size_t Poly1305_ctx_size(void);
+void Poly1305_Init(POLY1305 *ctx, const unsigned char key[32]);
+void Poly1305_Update(POLY1305 *ctx, const unsigned char *inp, size_t len);
+void Poly1305_Final(POLY1305 *ctx, unsigned char mac[16]);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/rand.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/rand.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/rand.h	(revision 331)
@@ -0,0 +1,20 @@
+/*
+ * 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
+ */
+
+/*
+ * Licensed under the OpenSSL licenses, (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * https://www.openssl.org/source/license.html
+ * or in the file LICENSE in the source distribution.
+ */
+
+#include <openssl/rand.h>
+
+void rand_cleanup_int(void);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/x509_int.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/x509_int.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/include/internal/x509_int.h	(revision 331)
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2015-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
+ */
+
+/* Internal X509 structures and functions: not for application use */
+
+/* Note: unless otherwise stated a field pointer is mandatory and should
+ * never be set to NULL: the ASN.1 code and accessors rely on mandatory
+ * fields never being NULL.
+ */
+
+/*
+ * name entry structure, equivalent to AttributeTypeAndValue defined
+ * in RFC5280 et al.
+ */
+struct X509_name_entry_st {
+    ASN1_OBJECT *object;        /* AttributeType */
+    ASN1_STRING *value;         /* AttributeValue */
+    int set;                    /* index of RDNSequence for this entry */
+    int size;                   /* temp variable */
+};
+
+/* Name from RFC 5280. */
+struct X509_name_st {
+    STACK_OF(X509_NAME_ENTRY) *entries; /* DN components */
+    int modified;               /* true if 'bytes' needs to be built */
+    BUF_MEM *bytes;             /* cached encoding: cannot be NULL */
+    /* canonical encoding used for rapid Name comparison */
+    unsigned char *canon_enc;
+    int canon_enclen;
+} /* X509_NAME */ ;
+
+/* PKCS#10 certificate request */
+
+struct X509_req_info_st {
+    ASN1_ENCODING enc;          /* cached encoding of signed part */
+    ASN1_INTEGER *version;      /* version, defaults to v1(0) so can be NULL */
+    X509_NAME *subject;         /* certificate request DN */
+    X509_PUBKEY *pubkey;        /* public key of request */
+    /*
+     * Zero or more attributes.
+     * NB: although attributes is a mandatory field some broken
+     * encodings omit it so this may be NULL in that case.
+     */
+    STACK_OF(X509_ATTRIBUTE) *attributes;
+};
+
+struct X509_req_st {
+    X509_REQ_INFO req_info;     /* signed certificate request data */
+    X509_ALGOR sig_alg;         /* signature algorithm */
+    ASN1_BIT_STRING *signature; /* signature */
+    int references;
+    CRYPTO_RWLOCK *lock;
+};
+
+struct X509_crl_info_st {
+    ASN1_INTEGER *version;      /* version: defaults to v1(0) so may be NULL */
+    X509_ALGOR sig_alg;         /* signature algorithm */
+    X509_NAME *issuer;          /* CRL issuer name */
+    ASN1_TIME *lastUpdate;      /* lastUpdate field */
+    ASN1_TIME *nextUpdate;      /* nextUpdate field: optional */
+    STACK_OF(X509_REVOKED) *revoked;        /* revoked entries: optional */
+    STACK_OF(X509_EXTENSION) *extensions;   /* extensions: optional */
+    ASN1_ENCODING enc;                      /* encoding of signed portion of CRL */
+};
+
+struct X509_crl_st {
+    X509_CRL_INFO crl;          /* signed CRL data */
+    X509_ALGOR sig_alg;         /* CRL signature algorithm */
+    ASN1_BIT_STRING signature;  /* CRL signature */
+    int references;
+    int flags;
+    /*
+     * Cached copies of decoded extension values, since extensions
+     * are optional any of these can be NULL.
+     */
+    AUTHORITY_KEYID *akid;
+    ISSUING_DIST_POINT *idp;
+    /* Convenient breakdown of IDP */
+    int idp_flags;
+    int idp_reasons;
+    /* CRL and base CRL numbers for delta processing */
+    ASN1_INTEGER *crl_number;
+    ASN1_INTEGER *base_crl_number;
+    STACK_OF(GENERAL_NAMES) *issuers;
+    /* hash of CRL */
+    unsigned char sha1_hash[SHA_DIGEST_LENGTH];
+    /* alternative method to handle this CRL */
+    const X509_CRL_METHOD *meth;
+    void *meth_data;
+    CRYPTO_RWLOCK *lock;
+};
+
+struct x509_revoked_st {
+    ASN1_INTEGER serialNumber; /* revoked entry serial number */
+    ASN1_TIME *revocationDate;  /* revocation date */
+    STACK_OF(X509_EXTENSION) *extensions;   /* CRL entry extensions: optional */
+    /* decoded value of CRLissuer extension: set if indirect CRL */
+    STACK_OF(GENERAL_NAME) *issuer;
+    /* revocation reason: set to CRL_REASON_NONE if reason extension absent */
+    int reason;
+    /*
+     * CRL entries are reordered for faster lookup of serial numbers. This
+     * field contains the original load sequence for this entry.
+     */
+    int sequence;
+};
+
+/*
+ * This stuff is certificate "auxiliary info": it contains details which are
+ * useful in certificate stores and databases. When used this is tagged onto
+ * the end of the certificate itself. OpenSSL specific structure not defined
+ * in any RFC.
+ */
+
+struct x509_cert_aux_st {
+    STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */
+    STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */
+    ASN1_UTF8STRING *alias;     /* "friendly name" */
+    ASN1_OCTET_STRING *keyid;   /* key id of private key */
+    STACK_OF(X509_ALGOR) *other; /* other unspecified info */
+};
+
+struct x509_cinf_st {
+    ASN1_INTEGER *version;      /* [ 0 ] default of v1 */
+    ASN1_INTEGER serialNumber;
+    X509_ALGOR signature;
+    X509_NAME *issuer;
+    X509_VAL validity;
+    X509_NAME *subject;
+    X509_PUBKEY *key;
+    ASN1_BIT_STRING *issuerUID; /* [ 1 ] optional in v2 */
+    ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */
+    STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */
+    ASN1_ENCODING enc;
+};
+
+struct x509_st {
+    X509_CINF cert_info;
+    X509_ALGOR sig_alg;
+    ASN1_BIT_STRING signature;
+    int references;
+    CRYPTO_EX_DATA ex_data;
+    /* These contain copies of various extension values */
+    long ex_pathlen;
+    long ex_pcpathlen;
+    uint32_t ex_flags;
+    uint32_t ex_kusage;
+    uint32_t ex_xkusage;
+    uint32_t ex_nscert;
+    ASN1_OCTET_STRING *skid;
+    AUTHORITY_KEYID *akid;
+    X509_POLICY_CACHE *policy_cache;
+    STACK_OF(DIST_POINT) *crldp;
+    STACK_OF(GENERAL_NAME) *altname;
+    NAME_CONSTRAINTS *nc;
+#ifndef OPENSSL_NO_RFC3779
+    STACK_OF(IPAddressFamily) *rfc3779_addr;
+    struct ASIdentifiers_st *rfc3779_asid;
+# endif
+    unsigned char sha1_hash[SHA_DIGEST_LENGTH];
+    X509_CERT_AUX *aux;
+    CRYPTO_RWLOCK *lock;
+} /* X509 */ ;
+
+/*
+ * This is a used when verifying cert chains.  Since the gathering of the
+ * cert chain can take some time (and have to be 'retried', this needs to be
+ * kept and passed around.
+ */
+struct x509_store_ctx_st {      /* X509_STORE_CTX */
+    X509_STORE *ctx;
+    /* The following are set by the caller */
+    /* The cert to check */
+    X509 *cert;
+    /* chain of X509s - untrusted - passed in */
+    STACK_OF(X509) *untrusted;
+    /* set of CRLs passed in */
+    STACK_OF(X509_CRL) *crls;
+    X509_VERIFY_PARAM *param;
+    /* Other info for use with get_issuer() */
+    void *other_ctx;
+    /* Callbacks for various operations */
+    /* called to verify a certificate */
+    int (*verify) (X509_STORE_CTX *ctx);
+    /* error callback */
+    int (*verify_cb) (int ok, X509_STORE_CTX *ctx);
+    /* get issuers cert from ctx */
+    int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
+    /* check issued */
+    int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
+    /* Check revocation status of chain */
+    int (*check_revocation) (X509_STORE_CTX *ctx);
+    /* retrieve CRL */
+    int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x);
+    /* Check CRL validity */
+    int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl);
+    /* Check certificate against CRL */
+    int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x);
+    /* Check policy status of the chain */
+    int (*check_policy) (X509_STORE_CTX *ctx);
+    STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm);
+    STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm);
+    int (*cleanup) (X509_STORE_CTX *ctx);
+    /* The following is built up */
+    /* if 0, rebuild chain */
+    int valid;
+    /* number of untrusted certs */
+    int num_untrusted;
+    /* chain of X509s - built up and trusted */
+    STACK_OF(X509) *chain;
+    /* Valid policy tree */
+    X509_POLICY_TREE *tree;
+    /* Require explicit policy value */
+    int explicit_policy;
+    /* When something goes wrong, this is why */
+    int error_depth;
+    int error;
+    X509 *current_cert;
+    /* cert currently being tested as valid issuer */
+    X509 *current_issuer;
+    /* current CRL */
+    X509_CRL *current_crl;
+    /* score of current CRL */
+    int current_crl_score;
+    /* Reason mask */
+    unsigned int current_reasons;
+    /* For CRL path validation: parent context */
+    X509_STORE_CTX *parent;
+    CRYPTO_EX_DATA ex_data;
+    SSL_DANE *dane;
+    /* signed via bare TA public key, rather than CA certificate */
+    int bare_ta_signed;
+};
+
+/* PKCS#8 private key info structure */
+
+struct pkcs8_priv_key_info_st {
+    ASN1_INTEGER *version;
+    X509_ALGOR *pkeyalg;
+    ASN1_OCTET_STRING *pkey;
+    STACK_OF(X509_ATTRIBUTE) *attributes;
+};
+
+struct X509_sig_st {
+    X509_ALGOR *algor;
+    ASN1_OCTET_STRING *digest;
+};
+
+struct x509_object_st {
+    /* one of the above types */
+    X509_LOOKUP_TYPE type;
+    union {
+        char *ptr;
+        X509 *x509;
+        X509_CRL *crl;
+        EVP_PKEY *pkey;
+    } data;
+};
+
+int a2i_ipadd(unsigned char *ipout, const char *ipasc);
+int x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/init.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/init.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/init.c	(revision 331)
@@ -0,0 +1,664 @@
+/*
+ * 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 <internal/cryptlib_int.h>
+#include <openssl/err.h>
+#include <internal/rand.h>
+#include <internal/bio.h>
+#include <openssl/evp.h>
+#include <internal/evp_int.h>
+#include <internal/conf.h>
+#include <internal/async.h>
+#include <internal/engine.h>
+#include <internal/comp.h>
+#include <internal/err.h>
+#include <internal/err_int.h>
+#include <internal/objects.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <internal/thread_once.h>
+#include <internal/dso.h>
+
+static int stopped = 0;
+
+static void ossl_init_thread_stop(struct thread_local_inits_st *locals);
+
+static CRYPTO_THREAD_LOCAL threadstopkey;
+
+static void ossl_init_thread_stop_wrap(void *local)
+{
+    ossl_init_thread_stop((struct thread_local_inits_st *)local);
+}
+
+static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc)
+{
+    struct thread_local_inits_st *local =
+        CRYPTO_THREAD_get_local(&threadstopkey);
+
+    if (local == NULL && alloc) {
+        local = OPENSSL_zalloc(sizeof *local);
+        CRYPTO_THREAD_set_local(&threadstopkey, local);
+    }
+    if (!alloc) {
+        CRYPTO_THREAD_set_local(&threadstopkey, NULL);
+    }
+
+    return local;
+}
+
+typedef struct ossl_init_stop_st OPENSSL_INIT_STOP;
+struct ossl_init_stop_st {
+    void (*handler)(void);
+    OPENSSL_INIT_STOP *next;
+};
+
+static OPENSSL_INIT_STOP *stop_handlers = NULL;
+static CRYPTO_RWLOCK *init_lock = NULL;
+
+static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT;
+static int base_inited = 0;
+DEFINE_RUN_ONCE_STATIC(ossl_init_base)
+{
+#ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr, "OPENSSL_INIT: ossl_init_base: Setting up stop handlers\n");
+#endif
+    /*
+     * We use a dummy thread local key here. We use the destructor to detect
+     * when the thread is going to stop (where that feature is available)
+     */
+    CRYPTO_THREAD_init_local(&threadstopkey, ossl_init_thread_stop_wrap);
+#ifndef OPENSSL_SYS_UEFI
+    atexit(OPENSSL_cleanup);
+#endif
+    if ((init_lock = CRYPTO_THREAD_lock_new()) == NULL)
+        return 0;
+    OPENSSL_cpuid_setup();
+
+    /*
+     * BIG FAT WARNING!
+     * Everything needed to be initialized in this function before threads
+     * come along MUST happen before base_inited is set to 1, or we will
+     * see race conditions.
+     */
+    base_inited = 1;
+
+#if !defined(OPENSSL_NO_DSO) && !defined(OPENSSL_USE_NODELETE)
+# ifdef DSO_WIN32
+    {
+        HMODULE handle = NULL;
+        BOOL ret;
+
+        /* We don't use the DSO route for WIN32 because there is a better way */
+        ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
+                                | GET_MODULE_HANDLE_EX_FLAG_PIN,
+                                (void *)&base_inited, &handle);
+
+        return (ret == TRUE) ? 1 : 0;
+    }
+# else
+    /*
+     * Deliberately leak a reference to ourselves. This will force the library
+     * to remain loaded until the atexit() handler is run a process exit.
+     */
+    {
+        DSO *dso = NULL;
+
+        dso = DSO_dsobyaddr(&base_inited, DSO_FLAG_NO_UNLOAD_ON_FREE);
+        DSO_free(dso);
+    }
+# endif
+#endif
+
+    return 1;
+}
+
+static CRYPTO_ONCE load_crypto_strings = CRYPTO_ONCE_STATIC_INIT;
+static int load_crypto_strings_inited = 0;
+DEFINE_RUN_ONCE_STATIC(ossl_init_no_load_crypto_strings)
+{
+    /* Do nothing in this case */
+    return 1;
+}
+
+DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_strings)
+{
+    int ret = 1;
+    /*
+     * OPENSSL_NO_AUTOERRINIT is provided here to prevent at compile time
+     * pulling in all the error strings during static linking
+     */
+#if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT)
+# ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr, "OPENSSL_INIT: ossl_init_load_crypto_strings: "
+                    "err_load_crypto_strings_int()\n");
+# endif
+    ret = err_load_crypto_strings_int();
+    load_crypto_strings_inited = 1;
+#endif    
+    return ret;
+}
+
+static CRYPTO_ONCE add_all_ciphers = CRYPTO_ONCE_STATIC_INIT;
+DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_ciphers)
+{
+    /*
+     * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
+     * pulling in all the ciphers during static linking
+     */
+#ifndef OPENSSL_NO_AUTOALGINIT
+# ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_ciphers: "
+                    "openssl_add_all_ciphers_int()\n");
+# endif
+    openssl_add_all_ciphers_int();
+#endif
+    return 1;
+}
+
+static CRYPTO_ONCE add_all_digests = CRYPTO_ONCE_STATIC_INIT;
+DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests)
+{
+    /*
+     * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
+     * pulling in all the ciphers during static linking
+     */
+#ifndef OPENSSL_NO_AUTOALGINIT
+# ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_digests: "
+                    "openssl_add_all_digests()\n");
+# endif
+    openssl_add_all_digests_int();
+#endif
+    return 1;
+}
+
+DEFINE_RUN_ONCE_STATIC(ossl_init_no_add_algs)
+{
+    /* Do nothing */
+    return 1;
+}
+
+static CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT;
+static int config_inited = 0;
+static const char *appname;
+DEFINE_RUN_ONCE_STATIC(ossl_init_config)
+{
+#ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr,
+            "OPENSSL_INIT: ossl_init_config: openssl_config(%s)\n",
+            appname == NULL ? "NULL" : appname);
+#endif
+    openssl_config_int(appname);
+    config_inited = 1;
+    return 1;
+}
+DEFINE_RUN_ONCE_STATIC(ossl_init_no_config)
+{
+#ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr,
+            "OPENSSL_INIT: ossl_init_config: openssl_no_config_int()\n");
+#endif
+    openssl_no_config_int();
+    config_inited = 1;
+    return 1;
+}
+
+static CRYPTO_ONCE async = CRYPTO_ONCE_STATIC_INIT;
+static int async_inited = 0;
+DEFINE_RUN_ONCE_STATIC(ossl_init_async)
+{
+#ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr, "OPENSSL_INIT: ossl_init_async: async_init()\n");
+#endif
+    if (!async_init())
+        return 0;
+    async_inited = 1;
+    return 1;
+}
+
+#ifndef OPENSSL_NO_ENGINE
+static CRYPTO_ONCE engine_openssl = CRYPTO_ONCE_STATIC_INIT;
+DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl)
+{
+# ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_openssl: "
+                    "engine_load_openssl_int()\n");
+# endif
+    engine_load_openssl_int();
+    return 1;
+}
+# if !defined(OPENSSL_NO_HW) && \
+    (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
+static CRYPTO_ONCE engine_cryptodev = CRYPTO_ONCE_STATIC_INIT;
+DEFINE_RUN_ONCE_STATIC(ossl_init_engine_cryptodev)
+{
+#  ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_cryptodev: "
+                    "engine_load_cryptodev_int()\n");
+#  endif
+    engine_load_cryptodev_int();
+    return 1;
+}
+# endif
+
+# ifndef OPENSSL_NO_RDRAND
+static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT;
+DEFINE_RUN_ONCE_STATIC(ossl_init_engine_rdrand)
+{
+#  ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_rdrand: "
+                    "engine_load_rdrand_int()\n");
+#  endif
+    engine_load_rdrand_int();
+    return 1;
+}
+# endif
+static CRYPTO_ONCE engine_dynamic = CRYPTO_ONCE_STATIC_INIT;
+DEFINE_RUN_ONCE_STATIC(ossl_init_engine_dynamic)
+{
+# ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_dynamic: "
+                    "engine_load_dynamic_int()\n");
+# endif
+    engine_load_dynamic_int();
+    return 1;
+}
+# ifndef OPENSSL_NO_STATIC_ENGINE
+#  if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
+static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT;
+DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock)
+{
+#   ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_padlock: "
+                    "engine_load_padlock_int()\n");
+#   endif
+    engine_load_padlock_int();
+    return 1;
+}
+#  endif
+#  if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
+static CRYPTO_ONCE engine_capi = CRYPTO_ONCE_STATIC_INIT;
+DEFINE_RUN_ONCE_STATIC(ossl_init_engine_capi)
+{
+#   ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_capi: "
+                    "engine_load_capi_int()\n");
+#   endif
+    engine_load_capi_int();
+    return 1;
+}
+#  endif
+#  if !defined(OPENSSL_NO_AFALGENG)
+static CRYPTO_ONCE engine_afalg = CRYPTO_ONCE_STATIC_INIT;
+DEFINE_RUN_ONCE_STATIC(ossl_init_engine_afalg)
+{
+#   ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_afalg: "
+                    "engine_load_afalg_int()\n");
+#   endif
+    engine_load_afalg_int();
+    return 1;
+}
+#  endif
+# endif
+#endif
+
+#ifndef OPENSSL_NO_COMP
+static CRYPTO_ONCE zlib = CRYPTO_ONCE_STATIC_INIT;
+
+static int zlib_inited = 0;
+DEFINE_RUN_ONCE_STATIC(ossl_init_zlib)
+{
+    /* Do nothing - we need to know about this for the later cleanup */
+    zlib_inited = 1;
+    return 1;
+}
+#endif
+
+static void ossl_init_thread_stop(struct thread_local_inits_st *locals)
+{
+    /* Can't do much about this */
+    if (locals == NULL)
+        return;
+
+    if (locals->async) {
+#ifdef OPENSSL_INIT_DEBUG
+        fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
+                        "ASYNC_cleanup_thread()\n");
+#endif
+        ASYNC_cleanup_thread();
+    }
+
+    if (locals->err_state) {
+#ifdef OPENSSL_INIT_DEBUG
+        fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
+                        "err_delete_thread_state()\n");
+#endif
+        err_delete_thread_state();
+    }
+
+    OPENSSL_free(locals);
+}
+
+void OPENSSL_thread_stop(void)
+{
+    ossl_init_thread_stop(
+        (struct thread_local_inits_st *)ossl_init_get_thread_local(0));
+}
+
+int ossl_init_thread_start(uint64_t opts)
+{
+    struct thread_local_inits_st *locals = ossl_init_get_thread_local(1);
+
+    if (locals == NULL)
+        return 0;
+
+    if (opts & OPENSSL_INIT_THREAD_ASYNC) {
+#ifdef OPENSSL_INIT_DEBUG
+        fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: "
+                        "marking thread for async\n");
+#endif
+        locals->async = 1;
+    }
+
+    if (opts & OPENSSL_INIT_THREAD_ERR_STATE) {
+#ifdef OPENSSL_INIT_DEBUG
+        fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: "
+                        "marking thread for err_state\n");
+#endif
+        locals->err_state = 1;
+    }
+
+    return 1;
+}
+
+void OPENSSL_cleanup(void)
+{
+    OPENSSL_INIT_STOP *currhandler, *lasthandler;
+
+    /* If we've not been inited then no need to deinit */
+    if (!base_inited)
+        return;
+
+    /* Might be explicitly called and also by atexit */
+    if (stopped)
+        return;
+    stopped = 1;
+
+    /*
+     * Thread stop may not get automatically called by the thread library for
+     * the very last thread in some situations, so call it directly.
+     */
+    ossl_init_thread_stop(ossl_init_get_thread_local(0));
+
+    currhandler = stop_handlers;
+    while (currhandler != NULL) {
+        currhandler->handler();
+        lasthandler = currhandler;
+        currhandler = currhandler->next;
+        OPENSSL_free(lasthandler);
+    }
+    stop_handlers = NULL;
+
+    CRYPTO_THREAD_lock_free(init_lock);
+
+    /*
+     * We assume we are single-threaded for this function, i.e. no race
+     * conditions for the various "*_inited" vars below.
+     */
+
+#ifndef OPENSSL_NO_COMP
+    if (zlib_inited) {
+#ifdef OPENSSL_INIT_DEBUG
+        fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
+                        "comp_zlib_cleanup_int()\n");
+#endif
+        comp_zlib_cleanup_int();
+    }
+#endif
+
+    if (async_inited) {
+# ifdef OPENSSL_INIT_DEBUG
+        fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
+                        "async_deinit()\n");
+# endif
+        async_deinit();
+    }
+
+    if (load_crypto_strings_inited) {
+#ifdef OPENSSL_INIT_DEBUG
+        fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
+                        "err_free_strings_int()\n");
+#endif
+        err_free_strings_int();
+    }
+
+    CRYPTO_THREAD_cleanup_local(&threadstopkey);
+
+#ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
+                    "rand_cleanup_int()\n");
+    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
+                    "conf_modules_free_int()\n");
+#ifndef OPENSSL_NO_ENGINE
+    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
+                    "engine_cleanup_int()\n");
+#endif
+    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
+                    "crypto_cleanup_all_ex_data_int()\n");
+    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
+                    "bio_sock_cleanup_int()\n");
+    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
+                    "bio_cleanup()\n");
+    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
+                    "evp_cleanup_int()\n");
+    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
+                    "obj_cleanup_int()\n");
+    fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
+                    "err_cleanup()\n");
+#endif
+    /*
+     * Note that cleanup order is important:
+     * - rand_cleanup_int could call an ENGINE's RAND cleanup function so
+     * must be called before engine_cleanup_int()
+     * - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up
+     * before the ex data handlers are wiped in CRYPTO_cleanup_all_ex_data().
+     * - conf_modules_free_int() can end up in ENGINE code so must be called
+     * before engine_cleanup_int()
+     * - ENGINEs and additional EVP algorithms might use added OIDs names so
+     * obj_cleanup_int() must be called last
+     */
+    rand_cleanup_int();
+    conf_modules_free_int();
+#ifndef OPENSSL_NO_ENGINE
+    engine_cleanup_int();
+#endif
+    crypto_cleanup_all_ex_data_int();
+    bio_cleanup();
+    evp_cleanup_int();
+    obj_cleanup_int();
+    err_cleanup();
+
+    base_inited = 0;
+}
+
+/*
+ * If this function is called with a non NULL settings value then it must be
+ * called prior to any threads making calls to any OpenSSL functions,
+ * i.e. passing a non-null settings value is assumed to be single-threaded.
+ */
+int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
+{
+    static int stoperrset = 0;
+
+    if (stopped) {
+        if (!stoperrset) {
+            /*
+             * We only ever set this once to avoid getting into an infinite
+             * loop where the error system keeps trying to init and fails so
+             * sets an error etc
+             */
+            stoperrset = 1;
+            CRYPTOerr(CRYPTO_F_OPENSSL_INIT_CRYPTO, ERR_R_INIT_FAIL);
+        }
+        return 0;
+    }
+
+    if (!base_inited && !RUN_ONCE(&base, ossl_init_base))
+        return 0;
+
+    if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS)
+            && !RUN_ONCE(&load_crypto_strings,
+                         ossl_init_no_load_crypto_strings))
+        return 0;
+
+    if ((opts & OPENSSL_INIT_LOAD_CRYPTO_STRINGS)
+            && !RUN_ONCE(&load_crypto_strings, ossl_init_load_crypto_strings))
+        return 0;
+
+    if ((opts & OPENSSL_INIT_NO_ADD_ALL_CIPHERS)
+            && !RUN_ONCE(&add_all_ciphers, ossl_init_no_add_algs))
+        return 0;
+
+    if ((opts & OPENSSL_INIT_ADD_ALL_CIPHERS)
+            && !RUN_ONCE(&add_all_ciphers, ossl_init_add_all_ciphers))
+        return 0;
+
+    if ((opts & OPENSSL_INIT_NO_ADD_ALL_DIGESTS)
+            && !RUN_ONCE(&add_all_digests, ossl_init_no_add_algs))
+        return 0;
+
+    if ((opts & OPENSSL_INIT_ADD_ALL_DIGESTS)
+            && !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests))
+        return 0;
+
+    if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG)
+            && !RUN_ONCE(&config, ossl_init_no_config))
+        return 0;
+
+    if (opts & OPENSSL_INIT_LOAD_CONFIG) {
+        int ret;
+        CRYPTO_THREAD_write_lock(init_lock);
+        appname = (settings == NULL) ? NULL : settings->appname;
+        ret = RUN_ONCE(&config, ossl_init_config);
+        CRYPTO_THREAD_unlock(init_lock);
+        if (!ret)
+            return 0;
+    }
+
+    if ((opts & OPENSSL_INIT_ASYNC)
+            && !RUN_ONCE(&async, ossl_init_async))
+        return 0;
+
+#ifndef OPENSSL_NO_ENGINE
+    if ((opts & OPENSSL_INIT_ENGINE_OPENSSL)
+            && !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl))
+        return 0;
+# if !defined(OPENSSL_NO_HW) && \
+    (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV))
+    if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
+            && !RUN_ONCE(&engine_cryptodev, ossl_init_engine_cryptodev))
+        return 0;
+# endif
+# ifndef OPENSSL_NO_RDRAND
+    if ((opts & OPENSSL_INIT_ENGINE_RDRAND)
+            && !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand))
+        return 0;
+# endif
+    if ((opts & OPENSSL_INIT_ENGINE_DYNAMIC)
+            && !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic))
+        return 0;
+# ifndef OPENSSL_NO_STATIC_ENGINE
+#  if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
+    if ((opts & OPENSSL_INIT_ENGINE_PADLOCK)
+            && !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock))
+        return 0;
+#  endif
+#  if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
+    if ((opts & OPENSSL_INIT_ENGINE_CAPI)
+            && !RUN_ONCE(&engine_capi, ossl_init_engine_capi))
+        return 0;
+#  endif
+#  if !defined(OPENSSL_NO_AFALGENG)
+    if ((opts & OPENSSL_INIT_ENGINE_AFALG)
+            && !RUN_ONCE(&engine_afalg, ossl_init_engine_afalg))
+        return 0;
+#  endif
+# endif
+    if (opts & (OPENSSL_INIT_ENGINE_ALL_BUILTIN
+                | OPENSSL_INIT_ENGINE_OPENSSL
+                | OPENSSL_INIT_ENGINE_AFALG)) {
+        ENGINE_register_all_complete();
+    }
+#endif
+
+#ifndef OPENSSL_NO_COMP
+    if ((opts & OPENSSL_INIT_ZLIB)
+            && !RUN_ONCE(&zlib, ossl_init_zlib))
+        return 0;
+#endif
+
+    return 1;
+}
+
+int OPENSSL_atexit(void (*handler)(void))
+{
+    OPENSSL_INIT_STOP *newhand;
+
+#if !defined(OPENSSL_NO_DSO) && !defined(OPENSSL_USE_NODELETE)
+    {
+        union {
+            void *sym;
+            void (*func)(void);
+        } handlersym;
+
+        handlersym.func = handler;
+# ifdef DSO_WIN32
+        {
+            HMODULE handle = NULL;
+            BOOL ret;
+
+            /*
+             * We don't use the DSO route for WIN32 because there is a better
+             * way
+             */
+            ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
+                                    | GET_MODULE_HANDLE_EX_FLAG_PIN,
+                                    handlersym.sym, &handle);
+
+            if (!ret)
+                return 0;
+        }
+# else
+        /*
+         * Deliberately leak a reference to the handler. This will force the
+         * library/code containing the handler to remain loaded until we run the
+         * atexit handler. If -znodelete has been used then this is
+         * unneccessary.
+         */
+        {
+            DSO *dso = NULL;
+
+            dso = DSO_dsobyaddr(handlersym.sym, DSO_FLAG_NO_UNLOAD_ON_FREE);
+            DSO_free(dso);
+        }
+# endif
+    }
+#endif
+
+    newhand = OPENSSL_malloc(sizeof(*newhand));
+    if (newhand == NULL)
+        return 0;
+
+    newhand->handler = handler;
+    newhand->next = stop_handlers;
+    stop_handlers = newhand;
+
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/kdf/hkdf.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/kdf/hkdf.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/kdf/hkdf.c	(revision 331)
@@ -0,0 +1,293 @@
+/*
+ * 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 <stdlib.h>
+#include <string.h>
+#include <openssl/hmac.h>
+#include <openssl/kdf.h>
+#include <openssl/evp.h>
+#include "internal/cryptlib.h"
+#include "internal/evp_int.h"
+
+#define HKDF_MAXBUF 1024
+
+static unsigned char *HKDF(const EVP_MD *evp_md,
+                           const unsigned char *salt, size_t salt_len,
+                           const unsigned char *key, size_t key_len,
+                           const unsigned char *info, size_t info_len,
+                           unsigned char *okm, size_t okm_len);
+
+static unsigned char *HKDF_Extract(const EVP_MD *evp_md,
+                                   const unsigned char *salt, size_t salt_len,
+                                   const unsigned char *key, size_t key_len,
+                                   unsigned char *prk, size_t *prk_len);
+
+static unsigned char *HKDF_Expand(const EVP_MD *evp_md,
+                                  const unsigned char *prk, size_t prk_len,
+                                  const unsigned char *info, size_t info_len,
+                                  unsigned char *okm, size_t okm_len);
+
+typedef struct {
+    const EVP_MD *md;
+    unsigned char *salt;
+    size_t salt_len;
+    unsigned char *key;
+    size_t key_len;
+    unsigned char info[HKDF_MAXBUF];
+    size_t info_len;
+} HKDF_PKEY_CTX;
+
+static int pkey_hkdf_init(EVP_PKEY_CTX *ctx)
+{
+    HKDF_PKEY_CTX *kctx;
+
+    kctx = OPENSSL_zalloc(sizeof(*kctx));
+    if (kctx == NULL)
+        return 0;
+
+    ctx->data = kctx;
+
+    return 1;
+}
+
+static void pkey_hkdf_cleanup(EVP_PKEY_CTX *ctx)
+{
+    HKDF_PKEY_CTX *kctx = ctx->data;
+    OPENSSL_clear_free(kctx->salt, kctx->salt_len);
+    OPENSSL_clear_free(kctx->key, kctx->key_len);
+    OPENSSL_cleanse(kctx->info, kctx->info_len);
+    OPENSSL_free(kctx);
+}
+
+static int pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+    HKDF_PKEY_CTX *kctx = ctx->data;
+
+    switch (type) {
+    case EVP_PKEY_CTRL_HKDF_MD:
+        if (p2 == NULL)
+            return 0;
+
+        kctx->md = p2;
+        return 1;
+
+    case EVP_PKEY_CTRL_HKDF_SALT:
+        if (p1 == 0 || p2 == NULL)
+            return 1;
+
+        if (p1 < 0)
+            return 0;
+
+        if (kctx->salt != NULL)
+            OPENSSL_clear_free(kctx->salt, kctx->salt_len);
+
+        kctx->salt = OPENSSL_memdup(p2, p1);
+        if (kctx->salt == NULL)
+            return 0;
+
+        kctx->salt_len = p1;
+        return 1;
+
+    case EVP_PKEY_CTRL_HKDF_KEY:
+        if (p1 < 0)
+            return 0;
+
+        if (kctx->key != NULL)
+            OPENSSL_clear_free(kctx->key, kctx->key_len);
+
+        kctx->key = OPENSSL_memdup(p2, p1);
+        if (kctx->key == NULL)
+            return 0;
+
+        kctx->key_len  = p1;
+        return 1;
+
+    case EVP_PKEY_CTRL_HKDF_INFO:
+        if (p1 == 0 || p2 == NULL)
+            return 1;
+
+        if (p1 < 0 || p1 > (int)(HKDF_MAXBUF - kctx->info_len))
+            return 0;
+
+        memcpy(kctx->info + kctx->info_len, p2, p1);
+        kctx->info_len += p1;
+        return 1;
+
+    default:
+        return -2;
+
+    }
+}
+
+static int pkey_hkdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
+                              const char *value)
+{
+    if (strcmp(type, "md") == 0)
+        return EVP_PKEY_CTX_set_hkdf_md(ctx, EVP_get_digestbyname(value));
+
+    if (strcmp(type, "salt") == 0)
+        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value);
+
+    if (strcmp(type, "hexsalt") == 0)
+        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_SALT, value);
+
+    if (strcmp(type, "key") == 0)
+        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value);
+
+    if (strcmp(type, "hexkey") == 0)
+        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_KEY, value);
+
+    if (strcmp(type, "info") == 0)
+        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value);
+
+    if (strcmp(type, "hexinfo") == 0)
+        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_HKDF_INFO, value);
+
+    return -2;
+}
+
+static int pkey_hkdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
+                            size_t *keylen)
+{
+    HKDF_PKEY_CTX *kctx = ctx->data;
+
+    if (kctx->md == NULL || kctx->key == NULL)
+        return 0;
+
+    if (HKDF(kctx->md, kctx->salt, kctx->salt_len, kctx->key, kctx->key_len,
+             kctx->info, kctx->info_len, key, *keylen) == NULL)
+    {
+        return 0;
+    }
+
+    return 1;
+}
+
+const EVP_PKEY_METHOD hkdf_pkey_meth = {
+    EVP_PKEY_HKDF,
+    0,
+    pkey_hkdf_init,
+    0,
+    pkey_hkdf_cleanup,
+
+    0, 0,
+    0, 0,
+
+    0,
+    0,
+
+    0,
+    0,
+
+    0, 0,
+
+    0, 0, 0, 0,
+
+    0, 0,
+
+    0, 0,
+
+    0,
+    pkey_hkdf_derive,
+    pkey_hkdf_ctrl,
+    pkey_hkdf_ctrl_str
+};
+
+static unsigned char *HKDF(const EVP_MD *evp_md,
+                           const unsigned char *salt, size_t salt_len,
+                           const unsigned char *key, size_t key_len,
+                           const unsigned char *info, size_t info_len,
+                           unsigned char *okm, size_t okm_len)
+{
+    unsigned char prk[EVP_MAX_MD_SIZE];
+    size_t prk_len;
+
+    if (!HKDF_Extract(evp_md, salt, salt_len, key, key_len, prk, &prk_len))
+        return NULL;
+
+    return HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len);
+}
+
+static unsigned char *HKDF_Extract(const EVP_MD *evp_md,
+                                   const unsigned char *salt, size_t salt_len,
+                                   const unsigned char *key, size_t key_len,
+                                   unsigned char *prk, size_t *prk_len)
+{
+    unsigned int tmp_len;
+
+    if (!HMAC(evp_md, salt, salt_len, key, key_len, prk, &tmp_len))
+        return NULL;
+
+    *prk_len = tmp_len;
+    return prk;
+}
+
+static unsigned char *HKDF_Expand(const EVP_MD *evp_md,
+                                  const unsigned char *prk, size_t prk_len,
+                                  const unsigned char *info, size_t info_len,
+                                  unsigned char *okm, size_t okm_len)
+{
+    HMAC_CTX *hmac;
+
+    unsigned int i;
+
+    unsigned char prev[EVP_MAX_MD_SIZE];
+
+    size_t done_len = 0, dig_len = EVP_MD_size(evp_md);
+
+    size_t n = okm_len / dig_len;
+    if (okm_len % dig_len)
+        n++;
+
+    if (n > 255)
+        return NULL;
+
+    if ((hmac = HMAC_CTX_new()) == NULL)
+        return NULL;
+
+    if (!HMAC_Init_ex(hmac, prk, prk_len, evp_md, NULL))
+        goto err;
+
+    for (i = 1; i <= n; i++) {
+        size_t copy_len;
+        const unsigned char ctr = i;
+
+        if (i > 1) {
+            if (!HMAC_Init_ex(hmac, NULL, 0, NULL, NULL))
+                goto err;
+
+            if (!HMAC_Update(hmac, prev, dig_len))
+                goto err;
+        }
+
+        if (!HMAC_Update(hmac, info, info_len))
+            goto err;
+
+        if (!HMAC_Update(hmac, &ctr, 1))
+            goto err;
+
+        if (!HMAC_Final(hmac, prev, NULL))
+            goto err;
+
+        copy_len = (done_len + dig_len > okm_len) ?
+                       okm_len - done_len :
+                       dig_len;
+
+        memcpy(okm + done_len, prev, copy_len);
+
+        done_len += copy_len;
+    }
+
+    HMAC_CTX_free(hmac);
+    return okm;
+
+ err:
+    HMAC_CTX_free(hmac);
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/kdf/kdf_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/kdf/kdf_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/kdf/kdf_err.c	(revision 331)
@@ -0,0 +1,46 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/kdf.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_KDF,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_KDF,0,reason)
+
+static ERR_STRING_DATA KDF_str_functs[] = {
+    {ERR_FUNC(KDF_F_PKEY_TLS1_PRF_CTRL_STR), "pkey_tls1_prf_ctrl_str"},
+    {ERR_FUNC(KDF_F_PKEY_TLS1_PRF_DERIVE), "pkey_tls1_prf_derive"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA KDF_str_reasons[] = {
+    {ERR_REASON(KDF_R_INVALID_DIGEST), "invalid digest"},
+    {ERR_REASON(KDF_R_MISSING_PARAMETER), "missing parameter"},
+    {ERR_REASON(KDF_R_VALUE_MISSING), "value missing"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_KDF_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(KDF_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, KDF_str_functs);
+        ERR_load_strings(0, KDF_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/kdf/tls1_prf.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/kdf/tls1_prf.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/kdf/tls1_prf.c	(revision 331)
@@ -0,0 +1,265 @@
+/*
+ * 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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/kdf.h>
+#include <openssl/evp.h>
+#include "internal/evp_int.h"
+
+static int tls1_prf_alg(const EVP_MD *md,
+                        const unsigned char *sec, size_t slen,
+                        const unsigned char *seed, size_t seed_len,
+                        unsigned char *out, size_t olen);
+
+#define TLS1_PRF_MAXBUF 1024
+
+/* TLS KDF pkey context structure */
+
+typedef struct {
+    /* Digest to use for PRF */
+    const EVP_MD *md;
+    /* Secret value to use for PRF */
+    unsigned char *sec;
+    size_t seclen;
+    /* Buffer of concatenated seed data */
+    unsigned char seed[TLS1_PRF_MAXBUF];
+    size_t seedlen;
+} TLS1_PRF_PKEY_CTX;
+
+static int pkey_tls1_prf_init(EVP_PKEY_CTX *ctx)
+{
+    TLS1_PRF_PKEY_CTX *kctx;
+
+    kctx = OPENSSL_zalloc(sizeof(*kctx));
+    if (kctx == NULL)
+        return 0;
+    ctx->data = kctx;
+
+    return 1;
+}
+
+static void pkey_tls1_prf_cleanup(EVP_PKEY_CTX *ctx)
+{
+    TLS1_PRF_PKEY_CTX *kctx = ctx->data;
+    OPENSSL_clear_free(kctx->sec, kctx->seclen);
+    OPENSSL_cleanse(kctx->seed, kctx->seedlen);
+    OPENSSL_free(kctx);
+}
+
+static int pkey_tls1_prf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+    TLS1_PRF_PKEY_CTX *kctx = ctx->data;
+    switch (type) {
+    case EVP_PKEY_CTRL_TLS_MD:
+        kctx->md = p2;
+        return 1;
+
+    case EVP_PKEY_CTRL_TLS_SECRET:
+        if (p1 < 0)
+            return 0;
+        if (kctx->sec != NULL)
+            OPENSSL_clear_free(kctx->sec, kctx->seclen);
+        OPENSSL_cleanse(kctx->seed, kctx->seedlen);
+        kctx->seedlen = 0;
+        kctx->sec = OPENSSL_memdup(p2, p1);
+        if (kctx->sec == NULL)
+            return 0;
+        kctx->seclen  = p1;
+        return 1;
+
+    case EVP_PKEY_CTRL_TLS_SEED:
+        if (p1 == 0 || p2 == NULL)
+            return 1;
+        if (p1 < 0 || p1 > (int)(TLS1_PRF_MAXBUF - kctx->seedlen))
+            return 0;
+        memcpy(kctx->seed + kctx->seedlen, p2, p1);
+        kctx->seedlen += p1;
+        return 1;
+
+    default:
+        return -2;
+
+    }
+}
+
+static int pkey_tls1_prf_ctrl_str(EVP_PKEY_CTX *ctx,
+                                  const char *type, const char *value)
+{
+    if (value == NULL) {
+        KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_VALUE_MISSING);
+        return 0;
+    }
+    if (strcmp(type, "md") == 0) {
+        TLS1_PRF_PKEY_CTX *kctx = ctx->data;
+
+        const EVP_MD *md = EVP_get_digestbyname(value);
+        if (md == NULL) {
+            KDFerr(KDF_F_PKEY_TLS1_PRF_CTRL_STR, KDF_R_INVALID_DIGEST);
+            return 0;
+        }
+        kctx->md = md;
+        return 1;
+    }
+    if (strcmp(type, "secret") == 0)
+        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_TLS_SECRET, value);
+    if (strcmp(type, "hexsecret") == 0)
+        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_TLS_SECRET, value);
+    if (strcmp(type, "seed") == 0)
+        return EVP_PKEY_CTX_str2ctrl(ctx, EVP_PKEY_CTRL_TLS_SEED, value);
+    if (strcmp(type, "hexseed") == 0)
+        return EVP_PKEY_CTX_hex2ctrl(ctx, EVP_PKEY_CTRL_TLS_SEED, value);
+    return -2;
+}
+
+static int pkey_tls1_prf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
+                                size_t *keylen)
+{
+    TLS1_PRF_PKEY_CTX *kctx = ctx->data;
+    if (kctx->md == NULL || kctx->sec == NULL || kctx->seedlen == 0) {
+        KDFerr(KDF_F_PKEY_TLS1_PRF_DERIVE, KDF_R_MISSING_PARAMETER);
+        return 0;
+    }
+    return tls1_prf_alg(kctx->md, kctx->sec, kctx->seclen,
+                        kctx->seed, kctx->seedlen,
+                        key, *keylen);
+}
+
+const EVP_PKEY_METHOD tls1_prf_pkey_meth = {
+    EVP_PKEY_TLS1_PRF,
+    0,
+    pkey_tls1_prf_init,
+    0,
+    pkey_tls1_prf_cleanup,
+
+    0, 0,
+    0, 0,
+
+    0,
+    0,
+
+    0,
+    0,
+
+    0, 0,
+
+    0, 0, 0, 0,
+
+    0, 0,
+
+    0, 0,
+
+    0,
+    pkey_tls1_prf_derive,
+    pkey_tls1_prf_ctrl,
+    pkey_tls1_prf_ctrl_str
+};
+
+static int tls1_prf_P_hash(const EVP_MD *md,
+                           const unsigned char *sec, size_t sec_len,
+                           const unsigned char *seed, size_t seed_len,
+                           unsigned char *out, size_t olen)
+{
+    int chunk;
+    EVP_MD_CTX *ctx = NULL, *ctx_tmp = NULL, *ctx_init = NULL;
+    EVP_PKEY *mac_key = NULL;
+    unsigned char A1[EVP_MAX_MD_SIZE];
+    size_t A1_len;
+    int ret = 0;
+
+    chunk = EVP_MD_size(md);
+    OPENSSL_assert(chunk >= 0);
+
+    ctx = EVP_MD_CTX_new();
+    ctx_tmp = EVP_MD_CTX_new();
+    ctx_init = EVP_MD_CTX_new();
+    if (ctx == NULL || ctx_tmp == NULL || ctx_init == NULL)
+        goto err;
+    EVP_MD_CTX_set_flags(ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+    mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
+    if (mac_key == NULL)
+        goto err;
+    if (!EVP_DigestSignInit(ctx_init, NULL, md, NULL, mac_key))
+        goto err;
+    if (!EVP_MD_CTX_copy_ex(ctx, ctx_init))
+        goto err;
+    if (seed != NULL && !EVP_DigestSignUpdate(ctx, seed, seed_len))
+        goto err;
+    if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
+        goto err;
+
+    for (;;) {
+        /* Reinit mac contexts */
+        if (!EVP_MD_CTX_copy_ex(ctx, ctx_init))
+            goto err;
+        if (!EVP_DigestSignUpdate(ctx, A1, A1_len))
+            goto err;
+        if (olen > (size_t)chunk && !EVP_MD_CTX_copy_ex(ctx_tmp, ctx))
+            goto err;
+        if (seed && !EVP_DigestSignUpdate(ctx, seed, seed_len))
+            goto err;
+
+        if (olen > (size_t)chunk) {
+            size_t mac_len;
+            if (!EVP_DigestSignFinal(ctx, out, &mac_len))
+                goto err;
+            out += mac_len;
+            olen -= mac_len;
+            /* calc the next A1 value */
+            if (!EVP_DigestSignFinal(ctx_tmp, A1, &A1_len))
+                goto err;
+        } else {                /* last one */
+
+            if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
+                goto err;
+            memcpy(out, A1, olen);
+            break;
+        }
+    }
+    ret = 1;
+ err:
+    EVP_PKEY_free(mac_key);
+    EVP_MD_CTX_free(ctx);
+    EVP_MD_CTX_free(ctx_tmp);
+    EVP_MD_CTX_free(ctx_init);
+    OPENSSL_cleanse(A1, sizeof(A1));
+    return ret;
+}
+
+static int tls1_prf_alg(const EVP_MD *md,
+                        const unsigned char *sec, size_t slen,
+                        const unsigned char *seed, size_t seed_len,
+                        unsigned char *out, size_t olen)
+{
+
+    if (EVP_MD_type(md) == NID_md5_sha1) {
+        size_t i;
+        unsigned char *tmp;
+        if (!tls1_prf_P_hash(EVP_md5(), sec, slen/2 + (slen & 1),
+                         seed, seed_len, out, olen))
+            return 0;
+
+        tmp = OPENSSL_malloc(olen);
+        if (tmp == NULL)
+            return 0;
+        if (!tls1_prf_P_hash(EVP_sha1(), sec + slen/2, slen/2 + (slen & 1),
+                         seed, seed_len, tmp, olen)) {
+            OPENSSL_clear_free(tmp, olen);
+            return 0;
+        }
+        for (i = 0; i < olen; i++)
+            out[i] ^= tmp[i];
+        OPENSSL_clear_free(tmp, olen);
+        return 1;
+    }
+    if (!tls1_prf_P_hash(md, sec, slen, seed, seed_len, out, olen))
+        return 0;
+
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/lhash/lh_stats.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/lhash/lh_stats.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/lhash/lh_stats.c	(revision 331)
@@ -0,0 +1,118 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+/*
+ * If you wish to build this outside of OpenSSL, remove the following lines
+ * and things should work as expected
+ */
+#include "internal/cryptlib.h"
+
+#include <openssl/bio.h>
+#include <openssl/lhash.h>
+#include "lhash_lcl.h"
+
+# ifndef OPENSSL_NO_STDIO
+void OPENSSL_LH_stats(const OPENSSL_LHASH *lh, FILE *fp)
+{
+    BIO *bp;
+
+    bp = BIO_new(BIO_s_file());
+    if (bp == NULL)
+        return;
+    BIO_set_fp(bp, fp, BIO_NOCLOSE);
+    OPENSSL_LH_stats_bio(lh, bp);
+    BIO_free(bp);
+}
+
+void OPENSSL_LH_node_stats(const OPENSSL_LHASH *lh, FILE *fp)
+{
+    BIO *bp;
+
+    bp = BIO_new(BIO_s_file());
+    if (bp == NULL)
+        return;
+    BIO_set_fp(bp, fp, BIO_NOCLOSE);
+    OPENSSL_LH_node_stats_bio(lh, bp);
+    BIO_free(bp);
+}
+
+void OPENSSL_LH_node_usage_stats(const OPENSSL_LHASH *lh, FILE *fp)
+{
+    BIO *bp;
+
+    bp = BIO_new(BIO_s_file());
+    if (bp == NULL)
+        return;
+    BIO_set_fp(bp, fp, BIO_NOCLOSE);
+    OPENSSL_LH_node_usage_stats_bio(lh, bp);
+    BIO_free(bp);
+}
+
+# endif
+
+void OPENSSL_LH_stats_bio(const OPENSSL_LHASH *lh, BIO *out)
+{
+    BIO_printf(out, "num_items             = %lu\n", lh->num_items);
+    BIO_printf(out, "num_nodes             = %u\n", lh->num_nodes);
+    BIO_printf(out, "num_alloc_nodes       = %u\n", lh->num_alloc_nodes);
+    BIO_printf(out, "num_expands           = %lu\n", lh->num_expands);
+    BIO_printf(out, "num_expand_reallocs   = %lu\n", lh->num_expand_reallocs);
+    BIO_printf(out, "num_contracts         = %lu\n", lh->num_contracts);
+    BIO_printf(out, "num_contract_reallocs = %lu\n",
+               lh->num_contract_reallocs);
+    BIO_printf(out, "num_hash_calls        = %lu\n", lh->num_hash_calls);
+    BIO_printf(out, "num_comp_calls        = %lu\n", lh->num_comp_calls);
+    BIO_printf(out, "num_insert            = %lu\n", lh->num_insert);
+    BIO_printf(out, "num_replace           = %lu\n", lh->num_replace);
+    BIO_printf(out, "num_delete            = %lu\n", lh->num_delete);
+    BIO_printf(out, "num_no_delete         = %lu\n", lh->num_no_delete);
+    BIO_printf(out, "num_retrieve          = %lu\n", lh->num_retrieve);
+    BIO_printf(out, "num_retrieve_miss     = %lu\n", lh->num_retrieve_miss);
+    BIO_printf(out, "num_hash_comps        = %lu\n", lh->num_hash_comps);
+}
+
+void OPENSSL_LH_node_stats_bio(const OPENSSL_LHASH *lh, BIO *out)
+{
+    OPENSSL_LH_NODE *n;
+    unsigned int i, num;
+
+    for (i = 0; i < lh->num_nodes; i++) {
+        for (n = lh->b[i], num = 0; n != NULL; n = n->next)
+            num++;
+        BIO_printf(out, "node %6u -> %3u\n", i, num);
+    }
+}
+
+void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH *lh, BIO *out)
+{
+    OPENSSL_LH_NODE *n;
+    unsigned long num;
+    unsigned int i;
+    unsigned long total = 0, n_used = 0;
+
+    for (i = 0; i < lh->num_nodes; i++) {
+        for (n = lh->b[i], num = 0; n != NULL; n = n->next)
+            num++;
+        if (num != 0) {
+            n_used++;
+            total += num;
+        }
+    }
+    BIO_printf(out, "%lu nodes used out of %u\n", n_used, lh->num_nodes);
+    BIO_printf(out, "%lu items\n", total);
+    if (n_used == 0)
+        return;
+    BIO_printf(out, "load %d.%02d  actual load %d.%02d\n",
+               (int)(total / lh->num_nodes),
+               (int)((total % lh->num_nodes) * 100 / lh->num_nodes),
+               (int)(total / n_used), (int)((total % n_used) * 100 / n_used));
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/lhash/lhash.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/lhash/lhash.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/lhash/lhash.c	(revision 331)
@@ -0,0 +1,349 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <openssl/crypto.h>
+#include <openssl/lhash.h>
+#include "lhash_lcl.h"
+
+
+#undef MIN_NODES
+#define MIN_NODES       16
+#define UP_LOAD         (2*LH_LOAD_MULT) /* load times 256 (default 2) */
+#define DOWN_LOAD       (LH_LOAD_MULT) /* load times 256 (default 1) */
+
+static int expand(OPENSSL_LHASH *lh);
+static void contract(OPENSSL_LHASH *lh);
+static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh, const void *data, unsigned long *rhash);
+
+OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c)
+{
+    OPENSSL_LHASH *ret;
+
+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
+        goto err0;
+    if ((ret->b = OPENSSL_zalloc(sizeof(*ret->b) * MIN_NODES)) == NULL)
+        goto err1;
+    ret->comp = ((c == NULL) ? (OPENSSL_LH_COMPFUNC)strcmp : c);
+    ret->hash = ((h == NULL) ? (OPENSSL_LH_HASHFUNC)OPENSSL_LH_strhash : h);
+    ret->num_nodes = MIN_NODES / 2;
+    ret->num_alloc_nodes = MIN_NODES;
+    ret->pmax = MIN_NODES / 2;
+    ret->up_load = UP_LOAD;
+    ret->down_load = DOWN_LOAD;
+    return (ret);
+
+ err1:
+    OPENSSL_free(ret);
+ err0:
+    return (NULL);
+}
+
+void OPENSSL_LH_free(OPENSSL_LHASH *lh)
+{
+    unsigned int i;
+    OPENSSL_LH_NODE *n, *nn;
+
+    if (lh == NULL)
+        return;
+
+    for (i = 0; i < lh->num_nodes; i++) {
+        n = lh->b[i];
+        while (n != NULL) {
+            nn = n->next;
+            OPENSSL_free(n);
+            n = nn;
+        }
+    }
+    OPENSSL_free(lh->b);
+    OPENSSL_free(lh);
+}
+
+void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data)
+{
+    unsigned long hash;
+    OPENSSL_LH_NODE *nn, **rn;
+    void *ret;
+
+    lh->error = 0;
+    if ((lh->up_load <= (lh->num_items * LH_LOAD_MULT / lh->num_nodes)) && !expand(lh))
+        return NULL;        /* 'lh->error++' already done in 'expand' */
+
+    rn = getrn(lh, data, &hash);
+
+    if (*rn == NULL) {
+        if ((nn = OPENSSL_malloc(sizeof(*nn))) == NULL) {
+            lh->error++;
+            return (NULL);
+        }
+        nn->data = data;
+        nn->next = NULL;
+        nn->hash = hash;
+        *rn = nn;
+        ret = NULL;
+        lh->num_insert++;
+        lh->num_items++;
+    } else {                    /* replace same key */
+
+        ret = (*rn)->data;
+        (*rn)->data = data;
+        lh->num_replace++;
+    }
+    return (ret);
+}
+
+void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data)
+{
+    unsigned long hash;
+    OPENSSL_LH_NODE *nn, **rn;
+    void *ret;
+
+    lh->error = 0;
+    rn = getrn(lh, data, &hash);
+
+    if (*rn == NULL) {
+        lh->num_no_delete++;
+        return (NULL);
+    } else {
+        nn = *rn;
+        *rn = nn->next;
+        ret = nn->data;
+        OPENSSL_free(nn);
+        lh->num_delete++;
+    }
+
+    lh->num_items--;
+    if ((lh->num_nodes > MIN_NODES) &&
+        (lh->down_load >= (lh->num_items * LH_LOAD_MULT / lh->num_nodes)))
+        contract(lh);
+
+    return (ret);
+}
+
+void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data)
+{
+    unsigned long hash;
+    OPENSSL_LH_NODE **rn;
+    void *ret;
+
+    lh->error = 0;
+    rn = getrn(lh, data, &hash);
+
+    if (*rn == NULL) {
+        lh->num_retrieve_miss++;
+        return (NULL);
+    } else {
+        ret = (*rn)->data;
+        lh->num_retrieve++;
+    }
+    return (ret);
+}
+
+static void doall_util_fn(OPENSSL_LHASH *lh, int use_arg,
+                          OPENSSL_LH_DOALL_FUNC func,
+                          OPENSSL_LH_DOALL_FUNCARG func_arg, void *arg)
+{
+    int i;
+    OPENSSL_LH_NODE *a, *n;
+
+    if (lh == NULL)
+        return;
+
+    /*
+     * reverse the order so we search from 'top to bottom' We were having
+     * memory leaks otherwise
+     */
+    for (i = lh->num_nodes - 1; i >= 0; i--) {
+        a = lh->b[i];
+        while (a != NULL) {
+            n = a->next;
+            if (use_arg)
+                func_arg(a->data, arg);
+            else
+                func(a->data);
+            a = n;
+        }
+    }
+}
+
+void OPENSSL_LH_doall(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNC func)
+{
+    doall_util_fn(lh, 0, func, (OPENSSL_LH_DOALL_FUNCARG)0, NULL);
+}
+
+void OPENSSL_LH_doall_arg(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNCARG func, void *arg)
+{
+    doall_util_fn(lh, 1, (OPENSSL_LH_DOALL_FUNC)0, func, arg);
+}
+
+static int expand(OPENSSL_LHASH *lh)
+{
+    OPENSSL_LH_NODE **n, **n1, **n2, *np;
+    unsigned int p, i, j;
+    unsigned long hash, nni;
+
+    lh->num_nodes++;
+    lh->num_expands++;
+    p = (int)lh->p++;
+    n1 = &(lh->b[p]);
+    n2 = &(lh->b[p + (int)lh->pmax]);
+    *n2 = NULL;
+    nni = lh->num_alloc_nodes;
+
+    for (np = *n1; np != NULL;) {
+        hash = np->hash;
+        if ((hash % nni) != p) { /* move it */
+            *n1 = (*n1)->next;
+            np->next = *n2;
+            *n2 = np;
+        } else
+            n1 = &((*n1)->next);
+        np = *n1;
+    }
+
+    if ((lh->p) >= lh->pmax) {
+        j = (int)lh->num_alloc_nodes * 2;
+        n = OPENSSL_realloc(lh->b, (int)(sizeof(OPENSSL_LH_NODE *) * j));
+        if (n == NULL) {
+            lh->error++;
+            lh->num_nodes--;
+            lh->p = 0;
+            return 0;
+        }
+        for (i = (int)lh->num_alloc_nodes; i < j; i++) /* 26/02/92 eay */
+            n[i] = NULL;        /* 02/03/92 eay */
+        lh->pmax = lh->num_alloc_nodes;
+        lh->num_alloc_nodes = j;
+        lh->num_expand_reallocs++;
+        lh->p = 0;
+        lh->b = n;
+    }
+    return 1;
+}
+
+static void contract(OPENSSL_LHASH *lh)
+{
+    OPENSSL_LH_NODE **n, *n1, *np;
+
+    np = lh->b[lh->p + lh->pmax - 1];
+    lh->b[lh->p + lh->pmax - 1] = NULL; /* 24/07-92 - eay - weird but :-( */
+    if (lh->p == 0) {
+        n = OPENSSL_realloc(lh->b,
+                            (unsigned int)(sizeof(OPENSSL_LH_NODE *) * lh->pmax));
+        if (n == NULL) {
+            /* fputs("realloc error in lhash",stderr); */
+            lh->error++;
+            return;
+        }
+        lh->num_contract_reallocs++;
+        lh->num_alloc_nodes /= 2;
+        lh->pmax /= 2;
+        lh->p = lh->pmax - 1;
+        lh->b = n;
+    } else
+        lh->p--;
+
+    lh->num_nodes--;
+    lh->num_contracts++;
+
+    n1 = lh->b[(int)lh->p];
+    if (n1 == NULL)
+        lh->b[(int)lh->p] = np;
+    else {
+        while (n1->next != NULL)
+            n1 = n1->next;
+        n1->next = np;
+    }
+}
+
+static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh,
+                               const void *data, unsigned long *rhash)
+{
+    OPENSSL_LH_NODE **ret, *n1;
+    unsigned long hash, nn;
+    OPENSSL_LH_COMPFUNC cf;
+
+    hash = (*(lh->hash)) (data);
+    lh->num_hash_calls++;
+    *rhash = hash;
+
+    nn = hash % lh->pmax;
+    if (nn < lh->p)
+        nn = hash % lh->num_alloc_nodes;
+
+    cf = lh->comp;
+    ret = &(lh->b[(int)nn]);
+    for (n1 = *ret; n1 != NULL; n1 = n1->next) {
+        lh->num_hash_comps++;
+        if (n1->hash != hash) {
+            ret = &(n1->next);
+            continue;
+        }
+        lh->num_comp_calls++;
+        if (cf(n1->data, data) == 0)
+            break;
+        ret = &(n1->next);
+    }
+    return (ret);
+}
+
+/*
+ * The following hash seems to work very well on normal text strings no
+ * collisions on /usr/dict/words and it distributes on %2^n quite well, not
+ * as good as MD5, but still good.
+ */
+unsigned long OPENSSL_LH_strhash(const char *c)
+{
+    unsigned long ret = 0;
+    long n;
+    unsigned long v;
+    int r;
+
+    if ((c == NULL) || (*c == '\0'))
+        return (ret);
+/*-
+    unsigned char b[16];
+    MD5(c,strlen(c),b);
+    return(b[0]|(b[1]<<8)|(b[2]<<16)|(b[3]<<24));
+*/
+
+    n = 0x100;
+    while (*c) {
+        v = n | (*c);
+        n += 0x100;
+        r = (int)((v >> 2) ^ v) & 0x0f;
+        ret = (ret << r) | (ret >> (32 - r));
+        ret &= 0xFFFFFFFFL;
+        ret ^= v * v;
+        c++;
+    }
+    return ((ret >> 16) ^ ret);
+}
+
+unsigned long OPENSSL_LH_num_items(const OPENSSL_LHASH *lh)
+{
+    return lh ? lh->num_items : 0;
+}
+
+unsigned long OPENSSL_LH_get_down_load(const OPENSSL_LHASH *lh)
+{
+    return lh->down_load;
+}
+
+void OPENSSL_LH_set_down_load(OPENSSL_LHASH *lh, unsigned long down_load)
+{
+    lh->down_load = down_load;
+}
+
+int OPENSSL_LH_error(OPENSSL_LHASH *lh)
+{
+    return lh->error;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/lhash/lhash_lcl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/lhash/lhash_lcl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/lhash/lhash_lcl.h	(revision 331)
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1995-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
+ */
+
+
+struct lhash_node_st {
+    void *data;
+    struct lhash_node_st *next;
+    unsigned long hash;
+};
+
+struct lhash_st {
+    OPENSSL_LH_NODE **b;
+    OPENSSL_LH_COMPFUNC comp;
+    OPENSSL_LH_HASHFUNC hash;
+    unsigned int num_nodes;
+    unsigned int num_alloc_nodes;
+    unsigned int p;
+    unsigned int pmax;
+    unsigned long up_load;      /* load times 256 */
+    unsigned long down_load;    /* load times 256 */
+    unsigned long num_items;
+    unsigned long num_expands;
+    unsigned long num_expand_reallocs;
+    unsigned long num_contracts;
+    unsigned long num_contract_reallocs;
+    unsigned long num_hash_calls;
+    unsigned long num_comp_calls;
+    unsigned long num_insert;
+    unsigned long num_replace;
+    unsigned long num_delete;
+    unsigned long num_no_delete;
+    unsigned long num_retrieve;
+    unsigned long num_retrieve_miss;
+    unsigned long num_hash_comps;
+    int error;
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/md4/md4_dgst.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/md4/md4_dgst.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/md4/md4_dgst.c	(revision 331)
@@ -0,0 +1,147 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/opensslv.h>
+#include "md4_locl.h"
+
+/*
+ * Implemented from RFC1186 The MD4 Message-Digest Algorithm
+ */
+
+#define INIT_DATA_A (unsigned long)0x67452301L
+#define INIT_DATA_B (unsigned long)0xefcdab89L
+#define INIT_DATA_C (unsigned long)0x98badcfeL
+#define INIT_DATA_D (unsigned long)0x10325476L
+
+int MD4_Init(MD4_CTX *c)
+{
+    memset(c, 0, sizeof(*c));
+    c->A = INIT_DATA_A;
+    c->B = INIT_DATA_B;
+    c->C = INIT_DATA_C;
+    c->D = INIT_DATA_D;
+    return 1;
+}
+
+#ifndef md4_block_data_order
+# ifdef X
+#  undef X
+# endif
+void md4_block_data_order(MD4_CTX *c, const void *data_, size_t num)
+{
+    const unsigned char *data = data_;
+    register unsigned MD32_REG_T A, B, C, D, l;
+# ifndef MD32_XARRAY
+    /* See comment in crypto/sha/sha_locl.h for details. */
+    unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+        XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15;
+#  define X(i)   XX##i
+# else
+    MD4_LONG XX[MD4_LBLOCK];
+#  define X(i)   XX[i]
+# endif
+
+    A = c->A;
+    B = c->B;
+    C = c->C;
+    D = c->D;
+
+    for (; num--;) {
+        (void)HOST_c2l(data, l);
+        X(0) = l;
+        (void)HOST_c2l(data, l);
+        X(1) = l;
+        /* Round 0 */
+        R0(A, B, C, D, X(0), 3, 0);
+        (void)HOST_c2l(data, l);
+        X(2) = l;
+        R0(D, A, B, C, X(1), 7, 0);
+        (void)HOST_c2l(data, l);
+        X(3) = l;
+        R0(C, D, A, B, X(2), 11, 0);
+        (void)HOST_c2l(data, l);
+        X(4) = l;
+        R0(B, C, D, A, X(3), 19, 0);
+        (void)HOST_c2l(data, l);
+        X(5) = l;
+        R0(A, B, C, D, X(4), 3, 0);
+        (void)HOST_c2l(data, l);
+        X(6) = l;
+        R0(D, A, B, C, X(5), 7, 0);
+        (void)HOST_c2l(data, l);
+        X(7) = l;
+        R0(C, D, A, B, X(6), 11, 0);
+        (void)HOST_c2l(data, l);
+        X(8) = l;
+        R0(B, C, D, A, X(7), 19, 0);
+        (void)HOST_c2l(data, l);
+        X(9) = l;
+        R0(A, B, C, D, X(8), 3, 0);
+        (void)HOST_c2l(data, l);
+        X(10) = l;
+        R0(D, A, B, C, X(9), 7, 0);
+        (void)HOST_c2l(data, l);
+        X(11) = l;
+        R0(C, D, A, B, X(10), 11, 0);
+        (void)HOST_c2l(data, l);
+        X(12) = l;
+        R0(B, C, D, A, X(11), 19, 0);
+        (void)HOST_c2l(data, l);
+        X(13) = l;
+        R0(A, B, C, D, X(12), 3, 0);
+        (void)HOST_c2l(data, l);
+        X(14) = l;
+        R0(D, A, B, C, X(13), 7, 0);
+        (void)HOST_c2l(data, l);
+        X(15) = l;
+        R0(C, D, A, B, X(14), 11, 0);
+        R0(B, C, D, A, X(15), 19, 0);
+        /* Round 1 */
+        R1(A, B, C, D, X(0), 3, 0x5A827999L);
+        R1(D, A, B, C, X(4), 5, 0x5A827999L);
+        R1(C, D, A, B, X(8), 9, 0x5A827999L);
+        R1(B, C, D, A, X(12), 13, 0x5A827999L);
+        R1(A, B, C, D, X(1), 3, 0x5A827999L);
+        R1(D, A, B, C, X(5), 5, 0x5A827999L);
+        R1(C, D, A, B, X(9), 9, 0x5A827999L);
+        R1(B, C, D, A, X(13), 13, 0x5A827999L);
+        R1(A, B, C, D, X(2), 3, 0x5A827999L);
+        R1(D, A, B, C, X(6), 5, 0x5A827999L);
+        R1(C, D, A, B, X(10), 9, 0x5A827999L);
+        R1(B, C, D, A, X(14), 13, 0x5A827999L);
+        R1(A, B, C, D, X(3), 3, 0x5A827999L);
+        R1(D, A, B, C, X(7), 5, 0x5A827999L);
+        R1(C, D, A, B, X(11), 9, 0x5A827999L);
+        R1(B, C, D, A, X(15), 13, 0x5A827999L);
+        /* Round 2 */
+        R2(A, B, C, D, X(0), 3, 0x6ED9EBA1L);
+        R2(D, A, B, C, X(8), 9, 0x6ED9EBA1L);
+        R2(C, D, A, B, X(4), 11, 0x6ED9EBA1L);
+        R2(B, C, D, A, X(12), 15, 0x6ED9EBA1L);
+        R2(A, B, C, D, X(2), 3, 0x6ED9EBA1L);
+        R2(D, A, B, C, X(10), 9, 0x6ED9EBA1L);
+        R2(C, D, A, B, X(6), 11, 0x6ED9EBA1L);
+        R2(B, C, D, A, X(14), 15, 0x6ED9EBA1L);
+        R2(A, B, C, D, X(1), 3, 0x6ED9EBA1L);
+        R2(D, A, B, C, X(9), 9, 0x6ED9EBA1L);
+        R2(C, D, A, B, X(5), 11, 0x6ED9EBA1L);
+        R2(B, C, D, A, X(13), 15, 0x6ED9EBA1L);
+        R2(A, B, C, D, X(3), 3, 0x6ED9EBA1L);
+        R2(D, A, B, C, X(11), 9, 0x6ED9EBA1L);
+        R2(C, D, A, B, X(7), 11, 0x6ED9EBA1L);
+        R2(B, C, D, A, X(15), 15, 0x6ED9EBA1L);
+
+        A = c->A += A;
+        B = c->B += B;
+        C = c->C += C;
+        D = c->D += D;
+    }
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/md4/md4_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/md4/md4_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/md4/md4_locl.h	(revision 331)
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1995-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 <stdlib.h>
+#include <string.h>
+#include <openssl/opensslconf.h>
+#include <openssl/md4.h>
+
+void md4_block_data_order(MD4_CTX *c, const void *p, size_t num);
+
+#define DATA_ORDER_IS_LITTLE_ENDIAN
+
+#define HASH_LONG               MD4_LONG
+#define HASH_CTX                MD4_CTX
+#define HASH_CBLOCK             MD4_CBLOCK
+#define HASH_UPDATE             MD4_Update
+#define HASH_TRANSFORM          MD4_Transform
+#define HASH_FINAL              MD4_Final
+#define HASH_MAKE_STRING(c,s)   do {    \
+        unsigned long ll;               \
+        ll=(c)->A; (void)HOST_l2c(ll,(s));      \
+        ll=(c)->B; (void)HOST_l2c(ll,(s));      \
+        ll=(c)->C; (void)HOST_l2c(ll,(s));      \
+        ll=(c)->D; (void)HOST_l2c(ll,(s));      \
+        } while (0)
+#define HASH_BLOCK_DATA_ORDER   md4_block_data_order
+
+#include "internal/md32_common.h"
+
+/*-
+#define F(x,y,z)        (((x) & (y))  |  ((~(x)) & (z)))
+#define G(x,y,z)        (((x) & (y))  |  ((x) & ((z))) | ((y) & ((z))))
+*/
+
+/*
+ * As pointed out by Wei Dai <weidai@eskimo.com>, the above can be simplified
+ * to the code below.  Wei attributes these optimizations to Peter Gutmann's
+ * SHS code, and he attributes it to Rich Schroeppel.
+ */
+#define F(b,c,d)        ((((c) ^ (d)) & (b)) ^ (d))
+#define G(b,c,d)        (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
+#define H(b,c,d)        ((b) ^ (c) ^ (d))
+
+#define R0(a,b,c,d,k,s,t) { \
+        a+=((k)+(t)+F((b),(c),(d))); \
+        a=ROTATE(a,s); };
+
+#define R1(a,b,c,d,k,s,t) { \
+        a+=((k)+(t)+G((b),(c),(d))); \
+        a=ROTATE(a,s); };\
+
+#define R2(a,b,c,d,k,s,t) { \
+        a+=((k)+(t)+H((b),(c),(d))); \
+        a=ROTATE(a,s); };
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/md4/md4_one.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/md4/md4_one.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/md4/md4_one.c	(revision 331)
@@ -0,0 +1,47 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <string.h>
+#include <openssl/md4.h>
+#include <openssl/crypto.h>
+
+#ifdef CHARSET_EBCDIC
+# include <openssl/ebcdic.h>
+#endif
+
+unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md)
+{
+    MD4_CTX c;
+    static unsigned char m[MD4_DIGEST_LENGTH];
+
+    if (md == NULL)
+        md = m;
+    if (!MD4_Init(&c))
+        return NULL;
+#ifndef CHARSET_EBCDIC
+    MD4_Update(&c, d, n);
+#else
+    {
+        char temp[1024];
+        unsigned long chunk;
+
+        while (n > 0) {
+            chunk = (n > sizeof(temp)) ? sizeof(temp) : n;
+            ebcdic2ascii(temp, d, chunk);
+            MD4_Update(&c, temp, chunk);
+            n -= chunk;
+            d += chunk;
+        }
+    }
+#endif
+    MD4_Final(md, &c);
+    OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */
+    return (md);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/md5/md5_dgst.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/md5/md5_dgst.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/md5/md5_dgst.c	(revision 331)
@@ -0,0 +1,164 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "md5_locl.h"
+#include <openssl/opensslv.h>
+
+/*
+ * Implemented from RFC1321 The MD5 Message-Digest Algorithm
+ */
+
+#define INIT_DATA_A (unsigned long)0x67452301L
+#define INIT_DATA_B (unsigned long)0xefcdab89L
+#define INIT_DATA_C (unsigned long)0x98badcfeL
+#define INIT_DATA_D (unsigned long)0x10325476L
+
+int MD5_Init(MD5_CTX *c)
+{
+    memset(c, 0, sizeof(*c));
+    c->A = INIT_DATA_A;
+    c->B = INIT_DATA_B;
+    c->C = INIT_DATA_C;
+    c->D = INIT_DATA_D;
+    return 1;
+}
+
+#ifndef md5_block_data_order
+# ifdef X
+#  undef X
+# endif
+void md5_block_data_order(MD5_CTX *c, const void *data_, size_t num)
+{
+    const unsigned char *data = data_;
+    register unsigned MD32_REG_T A, B, C, D, l;
+# ifndef MD32_XARRAY
+    /* See comment in crypto/sha/sha_locl.h for details. */
+    unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+        XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15;
+#  define X(i)   XX##i
+# else
+    MD5_LONG XX[MD5_LBLOCK];
+#  define X(i)   XX[i]
+# endif
+
+    A = c->A;
+    B = c->B;
+    C = c->C;
+    D = c->D;
+
+    for (; num--;) {
+        (void)HOST_c2l(data, l);
+        X(0) = l;
+        (void)HOST_c2l(data, l);
+        X(1) = l;
+        /* Round 0 */
+        R0(A, B, C, D, X(0), 7, 0xd76aa478L);
+        (void)HOST_c2l(data, l);
+        X(2) = l;
+        R0(D, A, B, C, X(1), 12, 0xe8c7b756L);
+        (void)HOST_c2l(data, l);
+        X(3) = l;
+        R0(C, D, A, B, X(2), 17, 0x242070dbL);
+        (void)HOST_c2l(data, l);
+        X(4) = l;
+        R0(B, C, D, A, X(3), 22, 0xc1bdceeeL);
+        (void)HOST_c2l(data, l);
+        X(5) = l;
+        R0(A, B, C, D, X(4), 7, 0xf57c0fafL);
+        (void)HOST_c2l(data, l);
+        X(6) = l;
+        R0(D, A, B, C, X(5), 12, 0x4787c62aL);
+        (void)HOST_c2l(data, l);
+        X(7) = l;
+        R0(C, D, A, B, X(6), 17, 0xa8304613L);
+        (void)HOST_c2l(data, l);
+        X(8) = l;
+        R0(B, C, D, A, X(7), 22, 0xfd469501L);
+        (void)HOST_c2l(data, l);
+        X(9) = l;
+        R0(A, B, C, D, X(8), 7, 0x698098d8L);
+        (void)HOST_c2l(data, l);
+        X(10) = l;
+        R0(D, A, B, C, X(9), 12, 0x8b44f7afL);
+        (void)HOST_c2l(data, l);
+        X(11) = l;
+        R0(C, D, A, B, X(10), 17, 0xffff5bb1L);
+        (void)HOST_c2l(data, l);
+        X(12) = l;
+        R0(B, C, D, A, X(11), 22, 0x895cd7beL);
+        (void)HOST_c2l(data, l);
+        X(13) = l;
+        R0(A, B, C, D, X(12), 7, 0x6b901122L);
+        (void)HOST_c2l(data, l);
+        X(14) = l;
+        R0(D, A, B, C, X(13), 12, 0xfd987193L);
+        (void)HOST_c2l(data, l);
+        X(15) = l;
+        R0(C, D, A, B, X(14), 17, 0xa679438eL);
+        R0(B, C, D, A, X(15), 22, 0x49b40821L);
+        /* Round 1 */
+        R1(A, B, C, D, X(1), 5, 0xf61e2562L);
+        R1(D, A, B, C, X(6), 9, 0xc040b340L);
+        R1(C, D, A, B, X(11), 14, 0x265e5a51L);
+        R1(B, C, D, A, X(0), 20, 0xe9b6c7aaL);
+        R1(A, B, C, D, X(5), 5, 0xd62f105dL);
+        R1(D, A, B, C, X(10), 9, 0x02441453L);
+        R1(C, D, A, B, X(15), 14, 0xd8a1e681L);
+        R1(B, C, D, A, X(4), 20, 0xe7d3fbc8L);
+        R1(A, B, C, D, X(9), 5, 0x21e1cde6L);
+        R1(D, A, B, C, X(14), 9, 0xc33707d6L);
+        R1(C, D, A, B, X(3), 14, 0xf4d50d87L);
+        R1(B, C, D, A, X(8), 20, 0x455a14edL);
+        R1(A, B, C, D, X(13), 5, 0xa9e3e905L);
+        R1(D, A, B, C, X(2), 9, 0xfcefa3f8L);
+        R1(C, D, A, B, X(7), 14, 0x676f02d9L);
+        R1(B, C, D, A, X(12), 20, 0x8d2a4c8aL);
+        /* Round 2 */
+        R2(A, B, C, D, X(5), 4, 0xfffa3942L);
+        R2(D, A, B, C, X(8), 11, 0x8771f681L);
+        R2(C, D, A, B, X(11), 16, 0x6d9d6122L);
+        R2(B, C, D, A, X(14), 23, 0xfde5380cL);
+        R2(A, B, C, D, X(1), 4, 0xa4beea44L);
+        R2(D, A, B, C, X(4), 11, 0x4bdecfa9L);
+        R2(C, D, A, B, X(7), 16, 0xf6bb4b60L);
+        R2(B, C, D, A, X(10), 23, 0xbebfbc70L);
+        R2(A, B, C, D, X(13), 4, 0x289b7ec6L);
+        R2(D, A, B, C, X(0), 11, 0xeaa127faL);
+        R2(C, D, A, B, X(3), 16, 0xd4ef3085L);
+        R2(B, C, D, A, X(6), 23, 0x04881d05L);
+        R2(A, B, C, D, X(9), 4, 0xd9d4d039L);
+        R2(D, A, B, C, X(12), 11, 0xe6db99e5L);
+        R2(C, D, A, B, X(15), 16, 0x1fa27cf8L);
+        R2(B, C, D, A, X(2), 23, 0xc4ac5665L);
+        /* Round 3 */
+        R3(A, B, C, D, X(0), 6, 0xf4292244L);
+        R3(D, A, B, C, X(7), 10, 0x432aff97L);
+        R3(C, D, A, B, X(14), 15, 0xab9423a7L);
+        R3(B, C, D, A, X(5), 21, 0xfc93a039L);
+        R3(A, B, C, D, X(12), 6, 0x655b59c3L);
+        R3(D, A, B, C, X(3), 10, 0x8f0ccc92L);
+        R3(C, D, A, B, X(10), 15, 0xffeff47dL);
+        R3(B, C, D, A, X(1), 21, 0x85845dd1L);
+        R3(A, B, C, D, X(8), 6, 0x6fa87e4fL);
+        R3(D, A, B, C, X(15), 10, 0xfe2ce6e0L);
+        R3(C, D, A, B, X(6), 15, 0xa3014314L);
+        R3(B, C, D, A, X(13), 21, 0x4e0811a1L);
+        R3(A, B, C, D, X(4), 6, 0xf7537e82L);
+        R3(D, A, B, C, X(11), 10, 0xbd3af235L);
+        R3(C, D, A, B, X(2), 15, 0x2ad7d2bbL);
+        R3(B, C, D, A, X(9), 21, 0xeb86d391L);
+
+        A = c->A += A;
+        B = c->B += B;
+        C = c->C += C;
+        D = c->D += D;
+    }
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/md5/md5_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/md5/md5_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/md5/md5_locl.h	(revision 331)
@@ -0,0 +1,80 @@
+/*
+ * Copyright 1995-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 <stdlib.h>
+#include <string.h>
+#include <openssl/e_os2.h>
+#include <openssl/md5.h>
+
+#ifdef MD5_ASM
+# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
+     defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
+#  define md5_block_data_order md5_block_asm_data_order
+# elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
+#  define md5_block_data_order md5_block_asm_data_order
+# elif defined(__sparc) || defined(__sparc__)
+#  define md5_block_data_order md5_block_asm_data_order
+# endif
+#endif
+
+void md5_block_data_order(MD5_CTX *c, const void *p, size_t num);
+
+#define DATA_ORDER_IS_LITTLE_ENDIAN
+
+#define HASH_LONG               MD5_LONG
+#define HASH_CTX                MD5_CTX
+#define HASH_CBLOCK             MD5_CBLOCK
+#define HASH_UPDATE             MD5_Update
+#define HASH_TRANSFORM          MD5_Transform
+#define HASH_FINAL              MD5_Final
+#define HASH_MAKE_STRING(c,s)   do {    \
+        unsigned long ll;               \
+        ll=(c)->A; (void)HOST_l2c(ll,(s));      \
+        ll=(c)->B; (void)HOST_l2c(ll,(s));      \
+        ll=(c)->C; (void)HOST_l2c(ll,(s));      \
+        ll=(c)->D; (void)HOST_l2c(ll,(s));      \
+        } while (0)
+#define HASH_BLOCK_DATA_ORDER   md5_block_data_order
+
+#include "internal/md32_common.h"
+
+/*-
+#define F(x,y,z)        (((x) & (y))  |  ((~(x)) & (z)))
+#define G(x,y,z)        (((x) & (z))  |  ((y) & (~(z))))
+*/
+
+/*
+ * As pointed out by Wei Dai <weidai@eskimo.com>, the above can be simplified
+ * to the code below.  Wei attributes these optimizations to Peter Gutmann's
+ * SHS code, and he attributes it to Rich Schroeppel.
+ */
+#define F(b,c,d)        ((((c) ^ (d)) & (b)) ^ (d))
+#define G(b,c,d)        ((((b) ^ (c)) & (d)) ^ (c))
+#define H(b,c,d)        ((b) ^ (c) ^ (d))
+#define I(b,c,d)        (((~(d)) | (b)) ^ (c))
+
+#define R0(a,b,c,d,k,s,t) { \
+        a+=((k)+(t)+F((b),(c),(d))); \
+        a=ROTATE(a,s); \
+        a+=b; };\
+
+#define R1(a,b,c,d,k,s,t) { \
+        a+=((k)+(t)+G((b),(c),(d))); \
+        a=ROTATE(a,s); \
+        a+=b; };
+
+#define R2(a,b,c,d,k,s,t) { \
+        a+=((k)+(t)+H((b),(c),(d))); \
+        a=ROTATE(a,s); \
+        a+=b; };
+
+#define R3(a,b,c,d,k,s,t) { \
+        a+=((k)+(t)+I((b),(c),(d))); \
+        a=ROTATE(a,s); \
+        a+=b; };
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/md5/md5_one.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/md5/md5_one.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/md5/md5_one.c	(revision 331)
@@ -0,0 +1,47 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <string.h>
+#include <openssl/md5.h>
+#include <openssl/crypto.h>
+
+#ifdef CHARSET_EBCDIC
+# include <openssl/ebcdic.h>
+#endif
+
+unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md)
+{
+    MD5_CTX c;
+    static unsigned char m[MD5_DIGEST_LENGTH];
+
+    if (md == NULL)
+        md = m;
+    if (!MD5_Init(&c))
+        return NULL;
+#ifndef CHARSET_EBCDIC
+    MD5_Update(&c, d, n);
+#else
+    {
+        char temp[1024];
+        unsigned long chunk;
+
+        while (n > 0) {
+            chunk = (n > sizeof(temp)) ? sizeof(temp) : n;
+            ebcdic2ascii(temp, d, chunk);
+            MD5_Update(&c, temp, chunk);
+            n -= chunk;
+            d += chunk;
+        }
+    }
+#endif
+    MD5_Final(md, &c);
+    OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */
+    return (md);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/mdc2/mdc2_one.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/mdc2/mdc2_one.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/mdc2/mdc2_one.c	(revision 331)
@@ -0,0 +1,27 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/mdc2.h>
+
+unsigned char *MDC2(const unsigned char *d, size_t n, unsigned char *md)
+{
+    MDC2_CTX c;
+    static unsigned char m[MDC2_DIGEST_LENGTH];
+
+    if (md == NULL)
+        md = m;
+    if (!MDC2_Init(&c))
+        return NULL;
+    MDC2_Update(&c, d, n);
+    MDC2_Final(md, &c);
+    OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */
+    return (md);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/mdc2/mdc2dgst.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/mdc2/mdc2dgst.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/mdc2/mdc2dgst.c	(revision 331)
@@ -0,0 +1,147 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/des.h>
+#include <openssl/mdc2.h>
+
+#undef c2l
+#define c2l(c,l)        (l =((DES_LONG)(*((c)++)))    , \
+                         l|=((DES_LONG)(*((c)++)))<< 8L, \
+                         l|=((DES_LONG)(*((c)++)))<<16L, \
+                         l|=((DES_LONG)(*((c)++)))<<24L)
+
+#undef l2c
+#define l2c(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
+                        *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                        *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                        *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len);
+int MDC2_Init(MDC2_CTX *c)
+{
+    c->num = 0;
+    c->pad_type = 1;
+    memset(&(c->h[0]), 0x52, MDC2_BLOCK);
+    memset(&(c->hh[0]), 0x25, MDC2_BLOCK);
+    return 1;
+}
+
+int MDC2_Update(MDC2_CTX *c, const unsigned char *in, size_t len)
+{
+    size_t i, j;
+
+    i = c->num;
+    if (i != 0) {
+        if (len < MDC2_BLOCK - i) {
+            /* partial block */
+            memcpy(&(c->data[i]), in, len);
+            c->num += (int)len;
+            return 1;
+        } else {
+            /* filled one */
+            j = MDC2_BLOCK - i;
+            memcpy(&(c->data[i]), in, j);
+            len -= j;
+            in += j;
+            c->num = 0;
+            mdc2_body(c, &(c->data[0]), MDC2_BLOCK);
+        }
+    }
+    i = len & ~((size_t)MDC2_BLOCK - 1);
+    if (i > 0)
+        mdc2_body(c, in, i);
+    j = len - i;
+    if (j > 0) {
+        memcpy(&(c->data[0]), &(in[i]), j);
+        c->num = (int)j;
+    }
+    return 1;
+}
+
+static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len)
+{
+    register DES_LONG tin0, tin1;
+    register DES_LONG ttin0, ttin1;
+    DES_LONG d[2], dd[2];
+    DES_key_schedule k;
+    unsigned char *p;
+    size_t i;
+
+    for (i = 0; i < len; i += 8) {
+        c2l(in, tin0);
+        d[0] = dd[0] = tin0;
+        c2l(in, tin1);
+        d[1] = dd[1] = tin1;
+        c->h[0] = (c->h[0] & 0x9f) | 0x40;
+        c->hh[0] = (c->hh[0] & 0x9f) | 0x20;
+
+        DES_set_odd_parity(&c->h);
+        DES_set_key_unchecked(&c->h, &k);
+        DES_encrypt1(d, &k, 1);
+
+        DES_set_odd_parity(&c->hh);
+        DES_set_key_unchecked(&c->hh, &k);
+        DES_encrypt1(dd, &k, 1);
+
+        ttin0 = tin0 ^ dd[0];
+        ttin1 = tin1 ^ dd[1];
+        tin0 ^= d[0];
+        tin1 ^= d[1];
+
+        p = c->h;
+        l2c(tin0, p);
+        l2c(ttin1, p);
+        p = c->hh;
+        l2c(ttin0, p);
+        l2c(tin1, p);
+    }
+}
+
+int MDC2_Final(unsigned char *md, MDC2_CTX *c)
+{
+    unsigned int i;
+    int j;
+
+    i = c->num;
+    j = c->pad_type;
+    if ((i > 0) || (j == 2)) {
+        if (j == 2)
+            c->data[i++] = 0x80;
+        memset(&(c->data[i]), 0, MDC2_BLOCK - i);
+        mdc2_body(c, c->data, MDC2_BLOCK);
+    }
+    memcpy(md, (char *)c->h, MDC2_BLOCK);
+    memcpy(&(md[MDC2_BLOCK]), (char *)c->hh, MDC2_BLOCK);
+    return 1;
+}
+
+#undef TEST
+
+#ifdef TEST
+main()
+{
+    unsigned char md[MDC2_DIGEST_LENGTH];
+    int i;
+    MDC2_CTX c;
+    static char *text = "Now is the time for all ";
+
+    MDC2_Init(&c);
+    MDC2_Update(&c, text, strlen(text));
+    MDC2_Final(&(md[0]), &c);
+
+    for (i = 0; i < MDC2_DIGEST_LENGTH; i++)
+        printf("%02X", md[i]);
+    printf("\n");
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/mem.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/mem.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/mem.c	(revision 331)
@@ -0,0 +1,190 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <openssl/crypto.h>
+#include "internal/cryptlib.h"
+
+/*
+ * the following pointers may be changed as long as 'allow_customize' is set
+ */
+static int allow_customize = 1;
+
+static void *(*malloc_impl)(size_t, const char *, int)
+    = CRYPTO_malloc;
+static void *(*realloc_impl)(void *, size_t, const char *, int)
+    = CRYPTO_realloc;
+static void (*free_impl)(void *, const char *, int)
+    = CRYPTO_free;
+
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+static int call_malloc_debug = 1;
+#else
+static int call_malloc_debug = 0;
+#endif
+
+int CRYPTO_set_mem_functions(
+        void *(*m)(size_t, const char *, int),
+        void *(*r)(void *, size_t, const char *, int),
+        void (*f)(void *, const char *, int))
+{
+    if (!allow_customize)
+        return 0;
+    if (m)
+        malloc_impl = m;
+    if (r)
+        realloc_impl = r;
+    if (f)
+        free_impl = f;
+    return 1;
+}
+
+int CRYPTO_set_mem_debug(int flag)
+{
+    if (!allow_customize)
+        return 0;
+    call_malloc_debug = flag;
+    return 1;
+}
+
+void CRYPTO_get_mem_functions(
+        void *(**m)(size_t, const char *, int),
+        void *(**r)(void *, size_t, const char *, int),
+        void (**f)(void *, const char *, int))
+{
+    if (m != NULL)
+        *m = malloc_impl;
+    if (r != NULL)
+        *r = realloc_impl;
+    if (f != NULL)
+        *f = free_impl;
+}
+
+void *CRYPTO_malloc(size_t num, const char *file, int line)
+{
+    void *ret = NULL;
+
+    if (malloc_impl != NULL && malloc_impl != CRYPTO_malloc)
+        return malloc_impl(num, file, line);
+
+    if (num <= 0)
+        return NULL;
+
+    allow_customize = 0;
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+    if (call_malloc_debug) {
+        CRYPTO_mem_debug_malloc(NULL, num, 0, file, line);
+        ret = malloc(num);
+        CRYPTO_mem_debug_malloc(ret, num, 1, file, line);
+    } else {
+        ret = malloc(num);
+    }
+#else
+    osslargused(file); osslargused(line);
+    ret = malloc(num);
+#endif
+
+    return ret;
+}
+
+void *CRYPTO_zalloc(size_t num, const char *file, int line)
+{
+    void *ret = CRYPTO_malloc(num, file, line);
+
+    if (ret != NULL)
+        memset(ret, 0, num);
+    return ret;
+}
+
+void *CRYPTO_realloc(void *str, size_t num, const char *file, int line)
+{
+    if (realloc_impl != NULL && realloc_impl != &CRYPTO_realloc)
+        return realloc_impl(str, num, file, line);
+
+    if (str == NULL)
+        return CRYPTO_malloc(num, file, line);
+
+    if (num == 0) {
+        CRYPTO_free(str, file, line);
+        return NULL;
+    }
+
+    allow_customize = 0;
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+    if (call_malloc_debug) {
+        void *ret;
+        CRYPTO_mem_debug_realloc(str, NULL, num, 0, file, line);
+        ret = realloc(str, num);
+        CRYPTO_mem_debug_realloc(str, ret, num, 1, file, line);
+        return ret;
+    }
+#else
+    osslargused(file); osslargused(line);
+#endif
+    return realloc(str, num);
+
+}
+
+void *CRYPTO_clear_realloc(void *str, size_t old_len, size_t num,
+                           const char *file, int line)
+{
+    void *ret = NULL;
+
+    if (str == NULL)
+        return CRYPTO_malloc(num, file, line);
+
+    if (num == 0) {
+        CRYPTO_clear_free(str, old_len, file, line);
+        return NULL;
+    }
+
+    /* Can't shrink the buffer since memcpy below copies |old_len| bytes. */
+    if (num < old_len) {
+        OPENSSL_cleanse((char*)str + num, old_len - num);
+        return str;
+    }
+
+    ret = CRYPTO_malloc(num, file, line);
+    if (ret != NULL) {
+        memcpy(ret, str, old_len);
+        CRYPTO_clear_free(str, old_len, file, line);
+    }
+    return ret;
+}
+
+void CRYPTO_free(void *str, const char *file, int line)
+{
+    if (free_impl != NULL && free_impl != &CRYPTO_free) {
+        free_impl(str, file, line);
+        return;
+    }
+
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+    if (call_malloc_debug) {
+        CRYPTO_mem_debug_free(str, 0, file, line);
+        free(str);
+        CRYPTO_mem_debug_free(str, 1, file, line);
+    } else {
+        free(str);
+    }
+#else
+    free(str);
+#endif
+}
+
+void CRYPTO_clear_free(void *str, size_t num, const char *file, int line)
+{
+    if (str == NULL)
+        return;
+    if (num)
+        OPENSSL_cleanse(str, num);
+    CRYPTO_free(str, file, line);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/mem_clr.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/mem_clr.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/mem_clr.c	(revision 331)
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2002-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 <string.h>
+#include <openssl/crypto.h>
+
+/*
+ * Pointer to memset is volatile so that compiler must de-reference
+ * the pointer and can't assume that it points to any function in
+ * particular (such as memset, which it then might further "optimize")
+ */
+typedef void *(*memset_t)(void *, int, size_t);
+
+static volatile memset_t memset_func = memset;
+
+void OPENSSL_cleanse(void *ptr, size_t len)
+{
+    memset_func(ptr, 0, len);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/mem_dbg.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/mem_dbg.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/mem_dbg.c	(revision 331)
@@ -0,0 +1,629 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include "internal/cryptlib.h"
+#include "internal/thread_once.h"
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include "internal/bio.h"
+#include <openssl/lhash.h>
+
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
+# include <execinfo.h>
+#endif
+
+/*
+ * The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE when
+ * the application asks for it (usually after library initialisation for
+ * which no book-keeping is desired). State CRYPTO_MEM_CHECK_ON exists only
+ * temporarily when the library thinks that certain allocations should not be
+ * checked (e.g. the data structures used for memory checking).  It is not
+ * suitable as an initial state: the library will unexpectedly enable memory
+ * checking when it executes one of those sections that want to disable
+ * checking temporarily. State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes
+ * no sense whatsoever.
+ */
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+static int mh_mode = CRYPTO_MEM_CHECK_OFF;
+#endif
+
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+static unsigned long order = 0; /* number of memory requests */
+
+/*-
+ * For application-defined information (static C-string `info')
+ * to be displayed in memory leak list.
+ * Each thread has its own stack.  For applications, there is
+ *   OPENSSL_mem_debug_push("...")     to push an entry,
+ *   OPENSSL_mem_debug_pop()     to pop an entry,
+ */
+struct app_mem_info_st {
+    CRYPTO_THREAD_ID threadid;
+    const char *file;
+    int line;
+    const char *info;
+    struct app_mem_info_st *next; /* tail of thread's stack */
+    int references;
+};
+
+static CRYPTO_ONCE memdbg_init = CRYPTO_ONCE_STATIC_INIT;
+static CRYPTO_RWLOCK *malloc_lock = NULL;
+static CRYPTO_RWLOCK *long_malloc_lock = NULL;
+static CRYPTO_THREAD_LOCAL appinfokey;
+
+/* memory-block description */
+struct mem_st {
+    void *addr;
+    int num;
+    const char *file;
+    int line;
+    CRYPTO_THREAD_ID threadid;
+    unsigned long order;
+    time_t time;
+    APP_INFO *app_info;
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
+    void *array[30];
+    size_t array_siz;
+#endif
+};
+
+static LHASH_OF(MEM) *mh = NULL; /* hash-table of memory requests (address as
+                                  * key); access requires MALLOC2 lock */
+
+/* num_disable > 0 iff mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE) */
+static unsigned int num_disable = 0;
+
+/*
+ * Valid iff num_disable > 0.  long_malloc_lock is locked exactly in this
+ * case (by the thread named in disabling_thread).
+ */
+static CRYPTO_THREAD_ID disabling_threadid;
+
+DEFINE_RUN_ONCE_STATIC(do_memdbg_init)
+{
+    malloc_lock = CRYPTO_THREAD_lock_new();
+    long_malloc_lock = CRYPTO_THREAD_lock_new();
+    if (malloc_lock == NULL || long_malloc_lock == NULL
+        || !CRYPTO_THREAD_init_local(&appinfokey, NULL)) {
+        CRYPTO_THREAD_lock_free(malloc_lock);
+        malloc_lock = NULL;
+        CRYPTO_THREAD_lock_free(long_malloc_lock);
+        long_malloc_lock = NULL;
+        return 0;
+    }
+    return 1;
+}
+
+static void app_info_free(APP_INFO *inf)
+{
+    if (!inf)
+        return;
+    if (--(inf->references) <= 0) {
+        app_info_free(inf->next);
+        OPENSSL_free(inf);
+    }
+}
+#endif
+
+int CRYPTO_mem_ctrl(int mode)
+{
+#ifdef OPENSSL_NO_CRYPTO_MDEBUG
+    return mode - mode;
+#else
+    int ret = mh_mode;
+
+    if (!RUN_ONCE(&memdbg_init, do_memdbg_init))
+        return -1;
+
+    CRYPTO_THREAD_write_lock(malloc_lock);
+    switch (mode) {
+    default:
+        break;
+
+    case CRYPTO_MEM_CHECK_ON:
+        mh_mode = CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE;
+        num_disable = 0;
+        break;
+
+    case CRYPTO_MEM_CHECK_OFF:
+        mh_mode = 0;
+        num_disable = 0;
+        break;
+
+    /* switch off temporarily (for library-internal use): */
+    case CRYPTO_MEM_CHECK_DISABLE:
+        if (mh_mode & CRYPTO_MEM_CHECK_ON) {
+            CRYPTO_THREAD_ID cur = CRYPTO_THREAD_get_current_id();
+            /* see if we don't have long_malloc_lock already */
+            if (!num_disable
+                || !CRYPTO_THREAD_compare_id(disabling_threadid, cur)) {
+                /*
+                 * Long-time lock long_malloc_lock must not be claimed
+                 * while we're holding malloc_lock, or we'll deadlock
+                 * if somebody else holds long_malloc_lock (and cannot
+                 * release it because we block entry to this function). Give
+                 * them a chance, first, and then claim the locks in
+                 * appropriate order (long-time lock first).
+                 */
+                CRYPTO_THREAD_unlock(malloc_lock);
+                /*
+                 * Note that after we have waited for long_malloc_lock and
+                 * malloc_lock, we'll still be in the right "case" and
+                 * "if" branch because MemCheck_start and MemCheck_stop may
+                 * never be used while there are multiple OpenSSL threads.
+                 */
+                CRYPTO_THREAD_write_lock(long_malloc_lock);
+                CRYPTO_THREAD_write_lock(malloc_lock);
+                mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
+                disabling_threadid = cur;
+            }
+            num_disable++;
+        }
+        break;
+
+    case CRYPTO_MEM_CHECK_ENABLE:
+        if (mh_mode & CRYPTO_MEM_CHECK_ON) {
+            if (num_disable) {  /* always true, or something is going wrong */
+                num_disable--;
+                if (num_disable == 0) {
+                    mh_mode |= CRYPTO_MEM_CHECK_ENABLE;
+                    CRYPTO_THREAD_unlock(long_malloc_lock);
+                }
+            }
+        }
+        break;
+    }
+    CRYPTO_THREAD_unlock(malloc_lock);
+    return (ret);
+#endif
+}
+
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+
+static int mem_check_on(void)
+{
+    int ret = 0;
+    CRYPTO_THREAD_ID cur;
+
+    if (mh_mode & CRYPTO_MEM_CHECK_ON) {
+        if (!RUN_ONCE(&memdbg_init, do_memdbg_init))
+            return 0;
+
+        cur = CRYPTO_THREAD_get_current_id();
+        CRYPTO_THREAD_read_lock(malloc_lock);
+
+        ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
+            || !CRYPTO_THREAD_compare_id(disabling_threadid, cur);
+
+        CRYPTO_THREAD_unlock(malloc_lock);
+    }
+    return (ret);
+}
+
+static int mem_cmp(const MEM *a, const MEM *b)
+{
+#ifdef _WIN64
+    const char *ap = (const char *)a->addr, *bp = (const char *)b->addr;
+    if (ap == bp)
+        return 0;
+    else if (ap > bp)
+        return 1;
+    else
+        return -1;
+#else
+    return (const char *)a->addr - (const char *)b->addr;
+#endif
+}
+
+static unsigned long mem_hash(const MEM *a)
+{
+    size_t ret;
+
+    ret = (size_t)a->addr;
+
+    ret = ret * 17851 + (ret >> 14) * 7 + (ret >> 4) * 251;
+    return (ret);
+}
+
+/* returns 1 if there was an info to pop, 0 if the stack was empty. */
+static int pop_info(void)
+{
+    APP_INFO *current = NULL;
+
+    if (!RUN_ONCE(&memdbg_init, do_memdbg_init))
+        return 0;
+
+    current = (APP_INFO *)CRYPTO_THREAD_get_local(&appinfokey);
+    if (current != NULL) {
+        APP_INFO *next = current->next;
+
+        if (next != NULL) {
+            next->references++;
+            CRYPTO_THREAD_set_local(&appinfokey, next);
+        } else {
+            CRYPTO_THREAD_set_local(&appinfokey, NULL);
+        }
+        if (--(current->references) <= 0) {
+            current->next = NULL;
+            if (next != NULL)
+                next->references--;
+            OPENSSL_free(current);
+        }
+        return 1;
+    }
+    return 0;
+}
+
+int CRYPTO_mem_debug_push(const char *info, const char *file, int line)
+{
+    APP_INFO *ami, *amim;
+    int ret = 0;
+
+    if (mem_check_on()) {
+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
+
+        if (!RUN_ONCE(&memdbg_init, do_memdbg_init)
+            || (ami = OPENSSL_malloc(sizeof(*ami))) == NULL)
+            goto err;
+
+        ami->threadid = CRYPTO_THREAD_get_current_id();
+        ami->file = file;
+        ami->line = line;
+        ami->info = info;
+        ami->references = 1;
+        ami->next = NULL;
+
+        amim = (APP_INFO *)CRYPTO_THREAD_get_local(&appinfokey);
+        CRYPTO_THREAD_set_local(&appinfokey, ami);
+
+        if (amim != NULL)
+            ami->next = amim;
+        ret = 1;
+ err:
+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
+    }
+
+    return (ret);
+}
+
+int CRYPTO_mem_debug_pop(void)
+{
+    int ret = 0;
+
+    if (mem_check_on()) {
+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
+        ret = pop_info();
+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
+    }
+    return (ret);
+}
+
+static unsigned long break_order_num = 0;
+
+void CRYPTO_mem_debug_malloc(void *addr, size_t num, int before_p,
+                             const char *file, int line)
+{
+    MEM *m, *mm;
+    APP_INFO *amim;
+
+    switch (before_p & 127) {
+    case 0:
+        break;
+    case 1:
+        if (addr == NULL)
+            break;
+
+        if (mem_check_on()) {
+            CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
+
+            if (!RUN_ONCE(&memdbg_init, do_memdbg_init)
+                || (m = OPENSSL_malloc(sizeof(*m))) == NULL) {
+                OPENSSL_free(addr);
+                CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
+                return;
+            }
+            if (mh == NULL) {
+                if ((mh = lh_MEM_new(mem_hash, mem_cmp)) == NULL) {
+                    OPENSSL_free(addr);
+                    OPENSSL_free(m);
+                    addr = NULL;
+                    goto err;
+                }
+            }
+
+            m->addr = addr;
+            m->file = file;
+            m->line = line;
+            m->num = num;
+            m->threadid = CRYPTO_THREAD_get_current_id();
+
+            if (order == break_order_num) {
+                /* BREAK HERE */
+                m->order = order;
+            }
+            m->order = order++;
+# ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
+            m->array_siz = backtrace(m->array, OSSL_NELEM(m->array));
+# endif
+            m->time = time(NULL);
+
+            amim = (APP_INFO *)CRYPTO_THREAD_get_local(&appinfokey);
+            m->app_info = amim;
+            if (amim != NULL)
+                amim->references++;
+
+            if ((mm = lh_MEM_insert(mh, m)) != NULL) {
+                /* Not good, but don't sweat it */
+                if (mm->app_info != NULL) {
+                    mm->app_info->references--;
+                }
+                OPENSSL_free(mm);
+            }
+ err:
+            CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
+        }
+        break;
+    }
+    return;
+}
+
+void CRYPTO_mem_debug_free(void *addr, int before_p,
+        const char *file, int line)
+{
+    MEM m, *mp;
+
+    switch (before_p) {
+    case 0:
+        if (addr == NULL)
+            break;
+
+        if (mem_check_on() && (mh != NULL)) {
+            CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
+
+            m.addr = addr;
+            mp = lh_MEM_delete(mh, &m);
+            if (mp != NULL) {
+                app_info_free(mp->app_info);
+                OPENSSL_free(mp);
+            }
+
+            CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
+        }
+        break;
+    case 1:
+        break;
+    }
+}
+
+void CRYPTO_mem_debug_realloc(void *addr1, void *addr2, size_t num,
+                              int before_p, const char *file, int line)
+{
+    MEM m, *mp;
+
+    switch (before_p) {
+    case 0:
+        break;
+    case 1:
+        if (addr2 == NULL)
+            break;
+
+        if (addr1 == NULL) {
+            CRYPTO_mem_debug_malloc(addr2, num, 128 | before_p, file, line);
+            break;
+        }
+
+        if (mem_check_on()) {
+            CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
+
+            m.addr = addr1;
+            mp = lh_MEM_delete(mh, &m);
+            if (mp != NULL) {
+                mp->addr = addr2;
+                mp->num = num;
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
+                mp->array_siz = backtrace(mp->array, OSSL_NELEM(mp->array));
+#endif
+                (void)lh_MEM_insert(mh, mp);
+            }
+
+            CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
+        }
+        break;
+    }
+    return;
+}
+
+typedef struct mem_leak_st {
+    BIO *bio;
+    int chunks;
+    long bytes;
+} MEM_LEAK;
+
+static void print_leak(const MEM *m, MEM_LEAK *l)
+{
+    char buf[1024];
+    char *bufp = buf;
+    APP_INFO *amip;
+    int ami_cnt;
+    struct tm *lcl = NULL;
+    /*
+     * Convert between CRYPTO_THREAD_ID (which could be anything at all) and
+     * a long. This may not be meaningful depending on what CRYPTO_THREAD_ID is
+     * but hopefully should give something sensible on most platforms
+     */
+    union {
+        CRYPTO_THREAD_ID tid;
+        unsigned long ltid;
+    } tid;
+    CRYPTO_THREAD_ID ti;
+
+#define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
+
+    lcl = localtime(&m->time);
+    BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ",
+                 lcl->tm_hour, lcl->tm_min, lcl->tm_sec);
+    bufp += strlen(bufp);
+
+    BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ",
+                 m->order, m->file, m->line);
+    bufp += strlen(bufp);
+
+    tid.ltid = 0;
+    tid.tid = m->threadid;
+    BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ", tid.ltid);
+    bufp += strlen(bufp);
+
+    BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%p\n",
+                 m->num, m->addr);
+    bufp += strlen(bufp);
+
+    BIO_puts(l->bio, buf);
+
+    l->chunks++;
+    l->bytes += m->num;
+
+    amip = m->app_info;
+    ami_cnt = 0;
+
+    if (amip) {
+        ti = amip->threadid;
+
+        do {
+            int buf_len;
+            int info_len;
+
+            ami_cnt++;
+            memset(buf, '>', ami_cnt);
+            tid.ltid = 0;
+            tid.tid = amip->threadid;
+            BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
+                         " thread=%lu, file=%s, line=%d, info=\"",
+                         tid.ltid, amip->file,
+                         amip->line);
+            buf_len = strlen(buf);
+            info_len = strlen(amip->info);
+            if (128 - buf_len - 3 < info_len) {
+                memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
+                buf_len = 128 - 3;
+            } else {
+                OPENSSL_strlcpy(buf + buf_len, amip->info, sizeof buf - buf_len);
+                buf_len = strlen(buf);
+            }
+            BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n");
+
+            BIO_puts(l->bio, buf);
+
+            amip = amip->next;
+        }
+        while (amip && CRYPTO_THREAD_compare_id(amip->threadid, ti));
+    }
+
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
+    {
+        size_t i;
+        char **strings = backtrace_symbols(m->array, m->array_siz);
+
+        for (i = 0; i < m->array_siz; i++)
+            fprintf(stderr, "##> %s\n", strings[i]);
+        free(strings);
+    }
+#endif
+}
+
+IMPLEMENT_LHASH_DOALL_ARG_CONST(MEM, MEM_LEAK);
+
+int CRYPTO_mem_leaks(BIO *b)
+{
+    MEM_LEAK ml;
+
+    /*
+     * OPENSSL_cleanup() will free the ex_data locks so we can't have any
+     * ex_data hanging around
+     */
+    bio_free_ex_data(b);
+
+    /* Ensure all resources are released */
+    OPENSSL_cleanup();
+
+    if (!RUN_ONCE(&memdbg_init, do_memdbg_init))
+        return -1;
+
+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
+
+    ml.bio = b;
+    ml.bytes = 0;
+    ml.chunks = 0;
+    if (mh != NULL)
+        lh_MEM_doall_MEM_LEAK(mh, print_leak, &ml);
+
+    if (ml.chunks != 0) {
+        BIO_printf(b, "%ld bytes leaked in %d chunks\n", ml.bytes, ml.chunks);
+    } else {
+        /*
+         * Make sure that, if we found no leaks, memory-leak debugging itself
+         * does not introduce memory leaks (which might irritate external
+         * debugging tools). (When someone enables leak checking, but does not
+         * call this function, we declare it to be their fault.)
+         */
+        int old_mh_mode;
+
+        CRYPTO_THREAD_write_lock(malloc_lock);
+
+        /*
+         * avoid deadlock when lh_free() uses CRYPTO_mem_debug_free(), which uses
+         * mem_check_on
+         */
+        old_mh_mode = mh_mode;
+        mh_mode = CRYPTO_MEM_CHECK_OFF;
+
+        lh_MEM_free(mh);
+        mh = NULL;
+
+        mh_mode = old_mh_mode;
+        CRYPTO_THREAD_unlock(malloc_lock);
+    }
+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);
+
+    /* Clean up locks etc */
+    CRYPTO_THREAD_cleanup_local(&appinfokey);
+    CRYPTO_THREAD_lock_free(malloc_lock);
+    CRYPTO_THREAD_lock_free(long_malloc_lock);
+    malloc_lock = NULL;
+    long_malloc_lock = NULL;
+
+    return ml.chunks == 0 ? 1 : 0;
+}
+
+# ifndef OPENSSL_NO_STDIO
+int CRYPTO_mem_leaks_fp(FILE *fp)
+{
+    BIO *b;
+    int ret;
+
+    /*
+     * Need to turn off memory checking when allocated BIOs ... especially as
+     * we're creating them at a time when we're trying to check we've not
+     * left anything un-free()'d!!
+     */
+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
+    b = BIO_new(BIO_s_file());
+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
+    if (b == NULL)
+        return -1;
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = CRYPTO_mem_leaks(b);
+    BIO_free(b);
+    return ret;
+}
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/mem_sec.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/mem_sec.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/mem_sec.c	(revision 331)
@@ -0,0 +1,585 @@
+/*
+ * Copyright 2015-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
+ */
+
+/*
+ * Copyright 2004-2014, Akamai Technologies. All Rights Reserved.
+ * This file is distributed under the terms of the OpenSSL license.
+ */
+
+/*
+ * This file is in two halves. The first half implements the public API
+ * to be used by external consumers, and to be used by OpenSSL to store
+ * data in a "secure arena." The second half implements the secure arena.
+ * For details on that implementation, see below (look for uppercase
+ * "SECURE HEAP IMPLEMENTATION").
+ */
+#include <openssl/crypto.h>
+#include <e_os.h>
+
+#include <string.h>
+
+#if defined(OPENSSL_SYS_LINUX) || defined(OPENSSL_SYS_UNIX)
+//# define IMPLEMENTED
+# include <stdlib.h>
+# include <assert.h>
+# include <unistd.h>
+# include <sys/types.h>
+# include <sys/mman.h>
+# include <sys/param.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+#endif
+
+#define CLEAR(p, s) OPENSSL_cleanse(p, s)
+#ifndef PAGE_SIZE
+# define PAGE_SIZE    4096
+#endif
+
+#ifdef IMPLEMENTED
+static size_t secure_mem_used;
+
+static int secure_mem_initialized;
+
+static CRYPTO_RWLOCK *sec_malloc_lock = NULL;
+
+/*
+ * These are the functions that must be implemented by a secure heap (sh).
+ */
+static int sh_init(size_t size, int minsize);
+static char *sh_malloc(size_t size);
+static void sh_free(char *ptr);
+static void sh_done(void);
+static size_t sh_actual_size(char *ptr);
+static int sh_allocated(const char *ptr);
+#endif
+
+int CRYPTO_secure_malloc_init(size_t size, int minsize)
+{
+#ifdef IMPLEMENTED
+    int ret = 0;
+
+    if (!secure_mem_initialized) {
+        sec_malloc_lock = CRYPTO_THREAD_lock_new();
+        if (sec_malloc_lock == NULL)
+            return 0;
+        ret = sh_init(size, minsize);
+        secure_mem_initialized = 1;
+    }
+
+    return ret;
+#else
+    return 0;
+#endif /* IMPLEMENTED */
+}
+
+int CRYPTO_secure_malloc_done()
+{
+#ifdef IMPLEMENTED
+    if (secure_mem_used == 0) {
+        sh_done();
+        secure_mem_initialized = 0;
+        CRYPTO_THREAD_lock_free(sec_malloc_lock);
+        return 1;
+    }
+#endif /* IMPLEMENTED */
+    return 0;
+}
+
+int CRYPTO_secure_malloc_initialized()
+{
+#ifdef IMPLEMENTED
+    return secure_mem_initialized;
+#else
+    return 0;
+#endif /* IMPLEMENTED */
+}
+
+void *CRYPTO_secure_malloc(size_t num, const char *file, int line)
+{
+#ifdef IMPLEMENTED
+    void *ret;
+    size_t actual_size;
+
+    if (!secure_mem_initialized) {
+        return CRYPTO_malloc(num, file, line);
+    }
+    CRYPTO_THREAD_write_lock(sec_malloc_lock);
+    ret = sh_malloc(num);
+    actual_size = ret ? sh_actual_size(ret) : 0;
+    secure_mem_used += actual_size;
+    CRYPTO_THREAD_unlock(sec_malloc_lock);
+    return ret;
+#else
+    return CRYPTO_malloc(num, file, line);
+#endif /* IMPLEMENTED */
+}
+
+void *CRYPTO_secure_zalloc(size_t num, const char *file, int line)
+{
+    void *ret = CRYPTO_secure_malloc(num, file, line);
+
+    if (ret != NULL)
+        memset(ret, 0, num);
+    return ret;
+}
+
+void CRYPTO_secure_free(void *ptr, const char *file, int line)
+{
+#ifdef IMPLEMENTED
+    size_t actual_size;
+
+    if (ptr == NULL)
+        return;
+    if (!CRYPTO_secure_allocated(ptr)) {
+        CRYPTO_free(ptr, file, line);
+        return;
+    }
+    CRYPTO_THREAD_write_lock(sec_malloc_lock);
+    actual_size = sh_actual_size(ptr);
+    CLEAR(ptr, actual_size);
+    secure_mem_used -= actual_size;
+    sh_free(ptr);
+    CRYPTO_THREAD_unlock(sec_malloc_lock);
+#else
+    CRYPTO_free(ptr, file, line);
+#endif /* IMPLEMENTED */
+}
+
+int CRYPTO_secure_allocated(const void *ptr)
+{
+#ifdef IMPLEMENTED
+    int ret;
+
+    if (!secure_mem_initialized)
+        return 0;
+    CRYPTO_THREAD_write_lock(sec_malloc_lock);
+    ret = sh_allocated(ptr);
+    CRYPTO_THREAD_unlock(sec_malloc_lock);
+    return ret;
+#else
+    return 0;
+#endif /* IMPLEMENTED */
+}
+
+size_t CRYPTO_secure_used()
+{
+#ifdef IMPLEMENTED
+    return secure_mem_used;
+#else
+    return 0;
+#endif /* IMPLEMENTED */
+}
+
+size_t CRYPTO_secure_actual_size(void *ptr)
+{
+#ifdef IMPLEMENTED
+    size_t actual_size;
+
+    CRYPTO_THREAD_write_lock(sec_malloc_lock);
+    actual_size = sh_actual_size(ptr);
+    CRYPTO_THREAD_unlock(sec_malloc_lock);
+    return actual_size;
+#else
+    return 0;
+#endif
+}
+/* END OF PAGE ...
+
+   ... START OF PAGE */
+
+/*
+ * SECURE HEAP IMPLEMENTATION
+ */
+#ifdef IMPLEMENTED
+
+
+/*
+ * The implementation provided here uses a fixed-sized mmap() heap,
+ * which is locked into memory, not written to core files, and protected
+ * on either side by an unmapped page, which will catch pointer overruns
+ * (or underruns) and an attempt to read data out of the secure heap.
+ * Free'd memory is zero'd or otherwise cleansed.
+ *
+ * This is a pretty standard buddy allocator.  We keep areas in a multiple
+ * of "sh.minsize" units.  The freelist and bitmaps are kept separately,
+ * so all (and only) data is kept in the mmap'd heap.
+ *
+ * This code assumes eight-bit bytes.  The numbers 3 and 7 are all over the
+ * place.
+ */
+
+#define ONE ((size_t)1)
+
+# define TESTBIT(t, b)  (t[(b) >> 3] &  (ONE << ((b) & 7)))
+# define SETBIT(t, b)   (t[(b) >> 3] |= (ONE << ((b) & 7)))
+# define CLEARBIT(t, b) (t[(b) >> 3] &= (0xFF & ~(ONE << ((b) & 7))))
+
+#define WITHIN_ARENA(p) \
+    ((char*)(p) >= sh.arena && (char*)(p) < &sh.arena[sh.arena_size])
+#define WITHIN_FREELIST(p) \
+    ((char*)(p) >= (char*)sh.freelist && (char*)(p) < (char*)&sh.freelist[sh.freelist_size])
+
+
+typedef struct sh_list_st
+{
+    struct sh_list_st *next;
+    struct sh_list_st **p_next;
+} SH_LIST;
+
+typedef struct sh_st
+{
+    char* map_result;
+    size_t map_size;
+    char *arena;
+    size_t arena_size;
+    char **freelist;
+    ossl_ssize_t freelist_size;
+    size_t minsize;
+    unsigned char *bittable;
+    unsigned char *bitmalloc;
+    size_t bittable_size; /* size in bits */
+} SH;
+
+static SH sh;
+
+static size_t sh_getlist(char *ptr)
+{
+    ossl_ssize_t list = sh.freelist_size - 1;
+    size_t bit = (sh.arena_size + ptr - sh.arena) / sh.minsize;
+
+    for (; bit; bit >>= 1, list--) {
+        if (TESTBIT(sh.bittable, bit))
+            break;
+        OPENSSL_assert((bit & 1) == 0);
+    }
+
+    return list;
+}
+
+
+static int sh_testbit(char *ptr, int list, unsigned char *table)
+{
+    size_t bit;
+
+    OPENSSL_assert(list >= 0 && list < sh.freelist_size);
+    OPENSSL_assert(((ptr - sh.arena) & ((sh.arena_size >> list) - 1)) == 0);
+    bit = (ONE << list) + ((ptr - sh.arena) / (sh.arena_size >> list));
+    OPENSSL_assert(bit > 0 && bit < sh.bittable_size);
+    return TESTBIT(table, bit);
+}
+
+static void sh_clearbit(char *ptr, int list, unsigned char *table)
+{
+    size_t bit;
+
+    OPENSSL_assert(list >= 0 && list < sh.freelist_size);
+    OPENSSL_assert(((ptr - sh.arena) & ((sh.arena_size >> list) - 1)) == 0);
+    bit = (ONE << list) + ((ptr - sh.arena) / (sh.arena_size >> list));
+    OPENSSL_assert(bit > 0 && bit < sh.bittable_size);
+    OPENSSL_assert(TESTBIT(table, bit));
+    CLEARBIT(table, bit);
+}
+
+static void sh_setbit(char *ptr, int list, unsigned char *table)
+{
+    size_t bit;
+
+    OPENSSL_assert(list >= 0 && list < sh.freelist_size);
+    OPENSSL_assert(((ptr - sh.arena) & ((sh.arena_size >> list) - 1)) == 0);
+    bit = (ONE << list) + ((ptr - sh.arena) / (sh.arena_size >> list));
+    OPENSSL_assert(bit > 0 && bit < sh.bittable_size);
+    OPENSSL_assert(!TESTBIT(table, bit));
+    SETBIT(table, bit);
+}
+
+static void sh_add_to_list(char **list, char *ptr)
+{
+    SH_LIST *temp;
+
+    OPENSSL_assert(WITHIN_FREELIST(list));
+    OPENSSL_assert(WITHIN_ARENA(ptr));
+
+    temp = (SH_LIST *)ptr;
+    temp->next = *(SH_LIST **)list;
+    OPENSSL_assert(temp->next == NULL || WITHIN_ARENA(temp->next));
+    temp->p_next = (SH_LIST **)list;
+
+    if (temp->next != NULL) {
+        OPENSSL_assert((char **)temp->next->p_next == list);
+        temp->next->p_next = &(temp->next);
+    }
+
+    *list = ptr;
+}
+
+static void sh_remove_from_list(char *ptr)
+{
+    SH_LIST *temp, *temp2;
+
+    temp = (SH_LIST *)ptr;
+    if (temp->next != NULL)
+        temp->next->p_next = temp->p_next;
+    *temp->p_next = temp->next;
+    if (temp->next == NULL)
+        return;
+
+    temp2 = temp->next;
+    OPENSSL_assert(WITHIN_FREELIST(temp2->p_next) || WITHIN_ARENA(temp2->p_next));
+}
+
+
+static int sh_init(size_t size, int minsize)
+{
+    int i, ret;
+    size_t pgsize;
+    size_t aligned;
+
+    memset(&sh, 0, sizeof sh);
+
+    /* make sure size and minsize are powers of 2 */
+    OPENSSL_assert(size > 0);
+    OPENSSL_assert((size & (size - 1)) == 0);
+    OPENSSL_assert(minsize > 0);
+    OPENSSL_assert((minsize & (minsize - 1)) == 0);
+    if (size <= 0 || (size & (size - 1)) != 0)
+        goto err;
+    if (minsize <= 0 || (minsize & (minsize - 1)) != 0)
+        goto err;
+
+    sh.arena_size = size;
+    sh.minsize = minsize;
+    sh.bittable_size = (sh.arena_size / sh.minsize) * 2;
+
+    /* Prevent allocations of size 0 later on */
+    if (sh.bittable_size >> 3 == 0)
+        goto err;
+
+    sh.freelist_size = -1;
+    for (i = sh.bittable_size; i; i >>= 1)
+        sh.freelist_size++;
+
+    sh.freelist = OPENSSL_zalloc(sh.freelist_size * sizeof (char *));
+    OPENSSL_assert(sh.freelist != NULL);
+    if (sh.freelist == NULL)
+        goto err;
+
+    sh.bittable = OPENSSL_zalloc(sh.bittable_size >> 3);
+    OPENSSL_assert(sh.bittable != NULL);
+    if (sh.bittable == NULL)
+        goto err;
+
+    sh.bitmalloc = OPENSSL_zalloc(sh.bittable_size >> 3);
+    OPENSSL_assert(sh.bitmalloc != NULL);
+    if (sh.bitmalloc == NULL)
+        goto err;
+
+    /* Allocate space for heap, and two extra pages as guards */
+#if defined(_SC_PAGE_SIZE) || defined (_SC_PAGESIZE)
+    {
+# if defined(_SC_PAGE_SIZE)
+        long tmppgsize = sysconf(_SC_PAGE_SIZE);
+# else
+        long tmppgsize = sysconf(_SC_PAGESIZE);
+# endif
+        if (tmppgsize < 1)
+            pgsize = PAGE_SIZE;
+        else
+            pgsize = (size_t)tmppgsize;
+    }
+#else
+    pgsize = PAGE_SIZE;
+#endif
+    sh.map_size = pgsize + sh.arena_size + pgsize;
+    if (1) {
+#ifdef MAP_ANON
+        sh.map_result = mmap(NULL, sh.map_size,
+                             PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
+    } else {
+#endif
+        int fd;
+
+        sh.map_result = MAP_FAILED;
+        if ((fd = open("/dev/zero", O_RDWR)) >= 0) {
+            sh.map_result = mmap(NULL, sh.map_size,
+                                 PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+            close(fd);
+        }
+    }
+    OPENSSL_assert(sh.map_result != MAP_FAILED);
+    if (sh.map_result == MAP_FAILED)
+        goto err;
+    sh.arena = (char *)(sh.map_result + pgsize);
+    sh_setbit(sh.arena, 0, sh.bittable);
+    sh_add_to_list(&sh.freelist[0], sh.arena);
+
+    /* Now try to add guard pages and lock into memory. */
+    ret = 1;
+
+    /* Starting guard is already aligned from mmap. */
+    if (mprotect(sh.map_result, pgsize, PROT_NONE) < 0)
+        ret = 2;
+
+    /* Ending guard page - need to round up to page boundary */
+    aligned = (pgsize + sh.arena_size + (pgsize - 1)) & ~(pgsize - 1);
+    if (mprotect(sh.map_result + aligned, pgsize, PROT_NONE) < 0)
+        ret = 2;
+
+    if (mlock(sh.arena, sh.arena_size) < 0)
+        ret = 2;
+#ifdef MADV_DONTDUMP
+    if (madvise(sh.arena, sh.arena_size, MADV_DONTDUMP) < 0)
+        ret = 2;
+#endif
+
+    return ret;
+
+ err:
+    sh_done();
+    return 0;
+}
+
+static void sh_done()
+{
+    OPENSSL_free(sh.freelist);
+    OPENSSL_free(sh.bittable);
+    OPENSSL_free(sh.bitmalloc);
+    if (sh.map_result != NULL && sh.map_size)
+        munmap(sh.map_result, sh.map_size);
+    memset(&sh, 0, sizeof sh);
+}
+
+static int sh_allocated(const char *ptr)
+{
+    return WITHIN_ARENA(ptr) ? 1 : 0;
+}
+
+static char *sh_find_my_buddy(char *ptr, int list)
+{
+    size_t bit;
+    char *chunk = NULL;
+
+    bit = (ONE << list) + (ptr - sh.arena) / (sh.arena_size >> list);
+    bit ^= 1;
+
+    if (TESTBIT(sh.bittable, bit) && !TESTBIT(sh.bitmalloc, bit))
+        chunk = sh.arena + ((bit & ((ONE << list) - 1)) * (sh.arena_size >> list));
+
+    return chunk;
+}
+
+static char *sh_malloc(size_t size)
+{
+    ossl_ssize_t list, slist;
+    size_t i;
+    char *chunk;
+
+    list = sh.freelist_size - 1;
+    for (i = sh.minsize; i < size; i <<= 1)
+        list--;
+    if (list < 0)
+        return NULL;
+
+    /* try to find a larger entry to split */
+    for (slist = list; slist >= 0; slist--)
+        if (sh.freelist[slist] != NULL)
+            break;
+    if (slist < 0)
+        return NULL;
+
+    /* split larger entry */
+    while (slist != list) {
+        char *temp = sh.freelist[slist];
+
+        /* remove from bigger list */
+        OPENSSL_assert(!sh_testbit(temp, slist, sh.bitmalloc));
+        sh_clearbit(temp, slist, sh.bittable);
+        sh_remove_from_list(temp);
+        OPENSSL_assert(temp != sh.freelist[slist]);
+
+        /* done with bigger list */
+        slist++;
+
+        /* add to smaller list */
+        OPENSSL_assert(!sh_testbit(temp, slist, sh.bitmalloc));
+        sh_setbit(temp, slist, sh.bittable);
+        sh_add_to_list(&sh.freelist[slist], temp);
+        OPENSSL_assert(sh.freelist[slist] == temp);
+
+        /* split in 2 */
+        temp += sh.arena_size >> slist;
+        OPENSSL_assert(!sh_testbit(temp, slist, sh.bitmalloc));
+        sh_setbit(temp, slist, sh.bittable);
+        sh_add_to_list(&sh.freelist[slist], temp);
+        OPENSSL_assert(sh.freelist[slist] == temp);
+
+        OPENSSL_assert(temp-(sh.arena_size >> slist) == sh_find_my_buddy(temp, slist));
+    }
+
+    /* peel off memory to hand back */
+    chunk = sh.freelist[list];
+    OPENSSL_assert(sh_testbit(chunk, list, sh.bittable));
+    sh_setbit(chunk, list, sh.bitmalloc);
+    sh_remove_from_list(chunk);
+
+    OPENSSL_assert(WITHIN_ARENA(chunk));
+
+    return chunk;
+}
+
+static void sh_free(char *ptr)
+{
+    size_t list;
+    char *buddy;
+
+    if (ptr == NULL)
+        return;
+    OPENSSL_assert(WITHIN_ARENA(ptr));
+    if (!WITHIN_ARENA(ptr))
+        return;
+
+    list = sh_getlist(ptr);
+    OPENSSL_assert(sh_testbit(ptr, list, sh.bittable));
+    sh_clearbit(ptr, list, sh.bitmalloc);
+    sh_add_to_list(&sh.freelist[list], ptr);
+
+    /* Try to coalesce two adjacent free areas. */
+    while ((buddy = sh_find_my_buddy(ptr, list)) != NULL) {
+        OPENSSL_assert(ptr == sh_find_my_buddy(buddy, list));
+        OPENSSL_assert(ptr != NULL);
+        OPENSSL_assert(!sh_testbit(ptr, list, sh.bitmalloc));
+        sh_clearbit(ptr, list, sh.bittable);
+        sh_remove_from_list(ptr);
+        OPENSSL_assert(!sh_testbit(ptr, list, sh.bitmalloc));
+        sh_clearbit(buddy, list, sh.bittable);
+        sh_remove_from_list(buddy);
+
+        list--;
+
+        if (ptr > buddy)
+            ptr = buddy;
+
+        OPENSSL_assert(!sh_testbit(ptr, list, sh.bitmalloc));
+        sh_setbit(ptr, list, sh.bittable);
+        sh_add_to_list(&sh.freelist[list], ptr);
+        OPENSSL_assert(sh.freelist[list] == ptr);
+    }
+}
+
+static size_t sh_actual_size(char *ptr)
+{
+    int list;
+
+    OPENSSL_assert(WITHIN_ARENA(ptr));
+    if (!WITHIN_ARENA(ptr))
+        return 0;
+    list = sh_getlist(ptr);
+    OPENSSL_assert(sh_testbit(ptr, list, sh.bittable));
+    return sh.arena_size / (ONE << list);
+}
+#endif /* IMPLEMENTED */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/cbc128.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/cbc128.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/cbc128.c	(revision 331)
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2008-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 <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+#if !defined(STRICT_ALIGNMENT) && !defined(PEDANTIC)
+# define STRICT_ALIGNMENT 0
+#endif
+
+void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const void *key,
+                           unsigned char ivec[16], block128_f block)
+{
+    size_t n;
+    const unsigned char *iv = ivec;
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+    if (STRICT_ALIGNMENT &&
+        ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
+        while (len >= 16) {
+            for (n = 0; n < 16; ++n)
+                out[n] = in[n] ^ iv[n];
+            (*block) (out, out, key);
+            iv = out;
+            len -= 16;
+            in += 16;
+            out += 16;
+        }
+    } else {
+        while (len >= 16) {
+            for (n = 0; n < 16; n += sizeof(size_t))
+                *(size_t *)(out + n) =
+                    *(size_t *)(in + n) ^ *(size_t *)(iv + n);
+            (*block) (out, out, key);
+            iv = out;
+            len -= 16;
+            in += 16;
+            out += 16;
+        }
+    }
+#endif
+    while (len) {
+        for (n = 0; n < 16 && n < len; ++n)
+            out[n] = in[n] ^ iv[n];
+        for (; n < 16; ++n)
+            out[n] = iv[n];
+        (*block) (out, out, key);
+        iv = out;
+        if (len <= 16)
+            break;
+        len -= 16;
+        in += 16;
+        out += 16;
+    }
+    memcpy(ivec, iv, 16);
+}
+
+void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const void *key,
+                           unsigned char ivec[16], block128_f block)
+{
+    size_t n;
+    union {
+        size_t t[16 / sizeof(size_t)];
+        unsigned char c[16];
+    } tmp;
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+    if (in != out) {
+        const unsigned char *iv = ivec;
+
+        if (STRICT_ALIGNMENT &&
+            ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
+            while (len >= 16) {
+                (*block) (in, out, key);
+                for (n = 0; n < 16; ++n)
+                    out[n] ^= iv[n];
+                iv = in;
+                len -= 16;
+                in += 16;
+                out += 16;
+            }
+        } else if (16 % sizeof(size_t) == 0) { /* always true */
+            while (len >= 16) {
+                size_t *out_t = (size_t *)out, *iv_t = (size_t *)iv;
+
+                (*block) (in, out, key);
+                for (n = 0; n < 16 / sizeof(size_t); n++)
+                    out_t[n] ^= iv_t[n];
+                iv = in;
+                len -= 16;
+                in += 16;
+                out += 16;
+            }
+        }
+        memcpy(ivec, iv, 16);
+    } else {
+        if (STRICT_ALIGNMENT &&
+            ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) {
+            unsigned char c;
+            while (len >= 16) {
+                (*block) (in, tmp.c, key);
+                for (n = 0; n < 16; ++n) {
+                    c = in[n];
+                    out[n] = tmp.c[n] ^ ivec[n];
+                    ivec[n] = c;
+                }
+                len -= 16;
+                in += 16;
+                out += 16;
+            }
+        } else if (16 % sizeof(size_t) == 0) { /* always true */
+            while (len >= 16) {
+                size_t c, *out_t = (size_t *)out, *ivec_t = (size_t *)ivec;
+                const size_t *in_t = (const size_t *)in;
+
+                (*block) (in, tmp.c, key);
+                for (n = 0; n < 16 / sizeof(size_t); n++) {
+                    c = in_t[n];
+                    out_t[n] = tmp.t[n] ^ ivec_t[n];
+                    ivec_t[n] = c;
+                }
+                len -= 16;
+                in += 16;
+                out += 16;
+            }
+        }
+    }
+#endif
+    while (len) {
+        unsigned char c;
+        (*block) (in, tmp.c, key);
+        for (n = 0; n < 16 && n < len; ++n) {
+            c = in[n];
+            out[n] = tmp.c[n] ^ ivec[n];
+            ivec[n] = c;
+        }
+        if (len <= 16) {
+            for (; n < 16; ++n)
+                ivec[n] = in[n];
+            break;
+        }
+        len -= 16;
+        in += 16;
+        out += 16;
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/ccm128.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/ccm128.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/ccm128.c	(revision 331)
@@ -0,0 +1,432 @@
+/*
+ * Copyright 2011-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 <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+/*
+ * First you setup M and L parameters and pass the key schedule. This is
+ * called once per session setup...
+ */
+void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx,
+                        unsigned int M, unsigned int L, void *key,
+                        block128_f block)
+{
+    memset(ctx->nonce.c, 0, sizeof(ctx->nonce.c));
+    ctx->nonce.c[0] = ((u8)(L - 1) & 7) | (u8)(((M - 2) / 2) & 7) << 3;
+    ctx->blocks = 0;
+    ctx->block = block;
+    ctx->key = key;
+}
+
+/* !!! Following interfaces are to be called *once* per packet !!! */
+
+/* Then you setup per-message nonce and pass the length of the message */
+int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx,
+                        const unsigned char *nonce, size_t nlen, size_t mlen)
+{
+    unsigned int L = ctx->nonce.c[0] & 7; /* the L parameter */
+
+    if (nlen < (14 - L))
+        return -1;              /* nonce is too short */
+
+    if (sizeof(mlen) == 8 && L >= 3) {
+        ctx->nonce.c[8] = (u8)(mlen >> (56 % (sizeof(mlen) * 8)));
+        ctx->nonce.c[9] = (u8)(mlen >> (48 % (sizeof(mlen) * 8)));
+        ctx->nonce.c[10] = (u8)(mlen >> (40 % (sizeof(mlen) * 8)));
+        ctx->nonce.c[11] = (u8)(mlen >> (32 % (sizeof(mlen) * 8)));
+    } else
+        ctx->nonce.u[1] = 0;
+
+    ctx->nonce.c[12] = (u8)(mlen >> 24);
+    ctx->nonce.c[13] = (u8)(mlen >> 16);
+    ctx->nonce.c[14] = (u8)(mlen >> 8);
+    ctx->nonce.c[15] = (u8)mlen;
+
+    ctx->nonce.c[0] &= ~0x40;   /* clear Adata flag */
+    memcpy(&ctx->nonce.c[1], nonce, 14 - L);
+
+    return 0;
+}
+
+/* Then you pass additional authentication data, this is optional */
+void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx,
+                       const unsigned char *aad, size_t alen)
+{
+    unsigned int i;
+    block128_f block = ctx->block;
+
+    if (alen == 0)
+        return;
+
+    ctx->nonce.c[0] |= 0x40;    /* set Adata flag */
+    (*block) (ctx->nonce.c, ctx->cmac.c, ctx->key), ctx->blocks++;
+
+    if (alen < (0x10000 - 0x100)) {
+        ctx->cmac.c[0] ^= (u8)(alen >> 8);
+        ctx->cmac.c[1] ^= (u8)alen;
+        i = 2;
+    } else if (sizeof(alen) == 8
+               && alen >= (size_t)1 << (32 % (sizeof(alen) * 8))) {
+        ctx->cmac.c[0] ^= 0xFF;
+        ctx->cmac.c[1] ^= 0xFF;
+        ctx->cmac.c[2] ^= (u8)(alen >> (56 % (sizeof(alen) * 8)));
+        ctx->cmac.c[3] ^= (u8)(alen >> (48 % (sizeof(alen) * 8)));
+        ctx->cmac.c[4] ^= (u8)(alen >> (40 % (sizeof(alen) * 8)));
+        ctx->cmac.c[5] ^= (u8)(alen >> (32 % (sizeof(alen) * 8)));
+        ctx->cmac.c[6] ^= (u8)(alen >> 24);
+        ctx->cmac.c[7] ^= (u8)(alen >> 16);
+        ctx->cmac.c[8] ^= (u8)(alen >> 8);
+        ctx->cmac.c[9] ^= (u8)alen;
+        i = 10;
+    } else {
+        ctx->cmac.c[0] ^= 0xFF;
+        ctx->cmac.c[1] ^= 0xFE;
+        ctx->cmac.c[2] ^= (u8)(alen >> 24);
+        ctx->cmac.c[3] ^= (u8)(alen >> 16);
+        ctx->cmac.c[4] ^= (u8)(alen >> 8);
+        ctx->cmac.c[5] ^= (u8)alen;
+        i = 6;
+    }
+
+    do {
+        for (; i < 16 && alen; ++i, ++aad, --alen)
+            ctx->cmac.c[i] ^= *aad;
+        (*block) (ctx->cmac.c, ctx->cmac.c, ctx->key), ctx->blocks++;
+        i = 0;
+    } while (alen);
+}
+
+/* Finally you encrypt or decrypt the message */
+
+/*
+ * counter part of nonce may not be larger than L*8 bits, L is not larger
+ * than 8, therefore 64-bit counter...
+ */
+static void ctr64_inc(unsigned char *counter)
+{
+    unsigned int n = 8;
+    u8 c;
+
+    counter += 8;
+    do {
+        --n;
+        c = counter[n];
+        ++c;
+        counter[n] = c;
+        if (c)
+            return;
+    } while (n);
+}
+
+int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx,
+                          const unsigned char *inp, unsigned char *out,
+                          size_t len)
+{
+    size_t n;
+    unsigned int i, L;
+    unsigned char flags0 = ctx->nonce.c[0];
+    block128_f block = ctx->block;
+    void *key = ctx->key;
+    union {
+        u64 u[2];
+        u8 c[16];
+    } scratch;
+
+    if (!(flags0 & 0x40))
+        (*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++;
+
+    ctx->nonce.c[0] = L = flags0 & 7;
+    for (n = 0, i = 15 - L; i < 15; ++i) {
+        n |= ctx->nonce.c[i];
+        ctx->nonce.c[i] = 0;
+        n <<= 8;
+    }
+    n |= ctx->nonce.c[15];      /* reconstructed length */
+    ctx->nonce.c[15] = 1;
+
+    if (n != len)
+        return -1;              /* length mismatch */
+
+    ctx->blocks += ((len + 15) >> 3) | 1;
+    if (ctx->blocks > (U64(1) << 61))
+        return -2;              /* too much data */
+
+    while (len >= 16) {
+#if defined(STRICT_ALIGNMENT)
+        union {
+            u64 u[2];
+            u8 c[16];
+        } temp;
+
+        memcpy(temp.c, inp, 16);
+        ctx->cmac.u[0] ^= temp.u[0];
+        ctx->cmac.u[1] ^= temp.u[1];
+#else
+        ctx->cmac.u[0] ^= ((u64 *)inp)[0];
+        ctx->cmac.u[1] ^= ((u64 *)inp)[1];
+#endif
+        (*block) (ctx->cmac.c, ctx->cmac.c, key);
+        (*block) (ctx->nonce.c, scratch.c, key);
+        ctr64_inc(ctx->nonce.c);
+#if defined(STRICT_ALIGNMENT)
+        temp.u[0] ^= scratch.u[0];
+        temp.u[1] ^= scratch.u[1];
+        memcpy(out, temp.c, 16);
+#else
+        ((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0];
+        ((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1];
+#endif
+        inp += 16;
+        out += 16;
+        len -= 16;
+    }
+
+    if (len) {
+        for (i = 0; i < len; ++i)
+            ctx->cmac.c[i] ^= inp[i];
+        (*block) (ctx->cmac.c, ctx->cmac.c, key);
+        (*block) (ctx->nonce.c, scratch.c, key);
+        for (i = 0; i < len; ++i)
+            out[i] = scratch.c[i] ^ inp[i];
+    }
+
+    for (i = 15 - L; i < 16; ++i)
+        ctx->nonce.c[i] = 0;
+
+    (*block) (ctx->nonce.c, scratch.c, key);
+    ctx->cmac.u[0] ^= scratch.u[0];
+    ctx->cmac.u[1] ^= scratch.u[1];
+
+    ctx->nonce.c[0] = flags0;
+
+    return 0;
+}
+
+int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx,
+                          const unsigned char *inp, unsigned char *out,
+                          size_t len)
+{
+    size_t n;
+    unsigned int i, L;
+    unsigned char flags0 = ctx->nonce.c[0];
+    block128_f block = ctx->block;
+    void *key = ctx->key;
+    union {
+        u64 u[2];
+        u8 c[16];
+    } scratch;
+
+    if (!(flags0 & 0x40))
+        (*block) (ctx->nonce.c, ctx->cmac.c, key);
+
+    ctx->nonce.c[0] = L = flags0 & 7;
+    for (n = 0, i = 15 - L; i < 15; ++i) {
+        n |= ctx->nonce.c[i];
+        ctx->nonce.c[i] = 0;
+        n <<= 8;
+    }
+    n |= ctx->nonce.c[15];      /* reconstructed length */
+    ctx->nonce.c[15] = 1;
+
+    if (n != len)
+        return -1;
+
+    while (len >= 16) {
+#if defined(STRICT_ALIGNMENT)
+        union {
+            u64 u[2];
+            u8 c[16];
+        } temp;
+#endif
+        (*block) (ctx->nonce.c, scratch.c, key);
+        ctr64_inc(ctx->nonce.c);
+#if defined(STRICT_ALIGNMENT)
+        memcpy(temp.c, inp, 16);
+        ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]);
+        ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]);
+        memcpy(out, scratch.c, 16);
+#else
+        ctx->cmac.u[0] ^= (((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0]);
+        ctx->cmac.u[1] ^= (((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1]);
+#endif
+        (*block) (ctx->cmac.c, ctx->cmac.c, key);
+
+        inp += 16;
+        out += 16;
+        len -= 16;
+    }
+
+    if (len) {
+        (*block) (ctx->nonce.c, scratch.c, key);
+        for (i = 0; i < len; ++i)
+            ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]);
+        (*block) (ctx->cmac.c, ctx->cmac.c, key);
+    }
+
+    for (i = 15 - L; i < 16; ++i)
+        ctx->nonce.c[i] = 0;
+
+    (*block) (ctx->nonce.c, scratch.c, key);
+    ctx->cmac.u[0] ^= scratch.u[0];
+    ctx->cmac.u[1] ^= scratch.u[1];
+
+    ctx->nonce.c[0] = flags0;
+
+    return 0;
+}
+
+static void ctr64_add(unsigned char *counter, size_t inc)
+{
+    size_t n = 8, val = 0;
+
+    counter += 8;
+    do {
+        --n;
+        val += counter[n] + (inc & 0xff);
+        counter[n] = (unsigned char)val;
+        val >>= 8;              /* carry bit */
+        inc >>= 8;
+    } while (n && (inc || val));
+}
+
+int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx,
+                                const unsigned char *inp, unsigned char *out,
+                                size_t len, ccm128_f stream)
+{
+    size_t n;
+    unsigned int i, L;
+    unsigned char flags0 = ctx->nonce.c[0];
+    block128_f block = ctx->block;
+    void *key = ctx->key;
+    union {
+        u64 u[2];
+        u8 c[16];
+    } scratch;
+
+    if (!(flags0 & 0x40))
+        (*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++;
+
+    ctx->nonce.c[0] = L = flags0 & 7;
+    for (n = 0, i = 15 - L; i < 15; ++i) {
+        n |= ctx->nonce.c[i];
+        ctx->nonce.c[i] = 0;
+        n <<= 8;
+    }
+    n |= ctx->nonce.c[15];      /* reconstructed length */
+    ctx->nonce.c[15] = 1;
+
+    if (n != len)
+        return -1;              /* length mismatch */
+
+    ctx->blocks += ((len + 15) >> 3) | 1;
+    if (ctx->blocks > (U64(1) << 61))
+        return -2;              /* too much data */
+
+    if ((n = len / 16)) {
+        (*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c);
+        n *= 16;
+        inp += n;
+        out += n;
+        len -= n;
+        if (len)
+            ctr64_add(ctx->nonce.c, n / 16);
+    }
+
+    if (len) {
+        for (i = 0; i < len; ++i)
+            ctx->cmac.c[i] ^= inp[i];
+        (*block) (ctx->cmac.c, ctx->cmac.c, key);
+        (*block) (ctx->nonce.c, scratch.c, key);
+        for (i = 0; i < len; ++i)
+            out[i] = scratch.c[i] ^ inp[i];
+    }
+
+    for (i = 15 - L; i < 16; ++i)
+        ctx->nonce.c[i] = 0;
+
+    (*block) (ctx->nonce.c, scratch.c, key);
+    ctx->cmac.u[0] ^= scratch.u[0];
+    ctx->cmac.u[1] ^= scratch.u[1];
+
+    ctx->nonce.c[0] = flags0;
+
+    return 0;
+}
+
+int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx,
+                                const unsigned char *inp, unsigned char *out,
+                                size_t len, ccm128_f stream)
+{
+    size_t n;
+    unsigned int i, L;
+    unsigned char flags0 = ctx->nonce.c[0];
+    block128_f block = ctx->block;
+    void *key = ctx->key;
+    union {
+        u64 u[2];
+        u8 c[16];
+    } scratch;
+
+    if (!(flags0 & 0x40))
+        (*block) (ctx->nonce.c, ctx->cmac.c, key);
+
+    ctx->nonce.c[0] = L = flags0 & 7;
+    for (n = 0, i = 15 - L; i < 15; ++i) {
+        n |= ctx->nonce.c[i];
+        ctx->nonce.c[i] = 0;
+        n <<= 8;
+    }
+    n |= ctx->nonce.c[15];      /* reconstructed length */
+    ctx->nonce.c[15] = 1;
+
+    if (n != len)
+        return -1;
+
+    if ((n = len / 16)) {
+        (*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c);
+        n *= 16;
+        inp += n;
+        out += n;
+        len -= n;
+        if (len)
+            ctr64_add(ctx->nonce.c, n / 16);
+    }
+
+    if (len) {
+        (*block) (ctx->nonce.c, scratch.c, key);
+        for (i = 0; i < len; ++i)
+            ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]);
+        (*block) (ctx->cmac.c, ctx->cmac.c, key);
+    }
+
+    for (i = 15 - L; i < 16; ++i)
+        ctx->nonce.c[i] = 0;
+
+    (*block) (ctx->nonce.c, scratch.c, key);
+    ctx->cmac.u[0] ^= scratch.u[0];
+    ctx->cmac.u[1] ^= scratch.u[1];
+
+    ctx->nonce.c[0] = flags0;
+
+    return 0;
+}
+
+size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len)
+{
+    unsigned int M = (ctx->nonce.c[0] >> 3) & 7; /* the M parameter */
+
+    M *= 2;
+    M += 2;
+    if (len < M)
+        return 0;
+    memcpy(tag, ctx->cmac.c, M);
+    return M;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/cfb128.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/cfb128.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/cfb128.c	(revision 331)
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2008-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 <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+/*
+ * The input and output encrypted as though 128bit cfb mode is being used.
+ * The extra state information to record how much of the 128bit block we have
+ * used is contained in *num;
+ */
+void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const void *key,
+                           unsigned char ivec[16], int *num,
+                           int enc, block128_f block)
+{
+    unsigned int n;
+    size_t l = 0;
+
+    n = *num;
+
+    if (enc) {
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+        if (16 % sizeof(size_t) == 0) { /* always true actually */
+            do {
+                while (n && len) {
+                    *(out++) = ivec[n] ^= *(in++);
+                    --len;
+                    n = (n + 1) % 16;
+                }
+# if defined(STRICT_ALIGNMENT)
+                if (((size_t)in | (size_t)out | (size_t)ivec) %
+                    sizeof(size_t) != 0)
+                    break;
+# endif
+                while (len >= 16) {
+                    (*block) (ivec, ivec, key);
+                    for (; n < 16; n += sizeof(size_t)) {
+                        *(size_t *)(out + n) =
+                            *(size_t *)(ivec + n) ^= *(size_t *)(in + n);
+                    }
+                    len -= 16;
+                    out += 16;
+                    in += 16;
+                    n = 0;
+                }
+                if (len) {
+                    (*block) (ivec, ivec, key);
+                    while (len--) {
+                        out[n] = ivec[n] ^= in[n];
+                        ++n;
+                    }
+                }
+                *num = n;
+                return;
+            } while (0);
+        }
+        /* the rest would be commonly eliminated by x86* compiler */
+#endif
+        while (l < len) {
+            if (n == 0) {
+                (*block) (ivec, ivec, key);
+            }
+            out[l] = ivec[n] ^= in[l];
+            ++l;
+            n = (n + 1) % 16;
+        }
+        *num = n;
+    } else {
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+        if (16 % sizeof(size_t) == 0) { /* always true actually */
+            do {
+                while (n && len) {
+                    unsigned char c;
+                    *(out++) = ivec[n] ^ (c = *(in++));
+                    ivec[n] = c;
+                    --len;
+                    n = (n + 1) % 16;
+                }
+# if defined(STRICT_ALIGNMENT)
+                if (((size_t)in | (size_t)out | (size_t)ivec) %
+                    sizeof(size_t) != 0)
+                    break;
+# endif
+                while (len >= 16) {
+                    (*block) (ivec, ivec, key);
+                    for (; n < 16; n += sizeof(size_t)) {
+                        size_t t = *(size_t *)(in + n);
+                        *(size_t *)(out + n) = *(size_t *)(ivec + n) ^ t;
+                        *(size_t *)(ivec + n) = t;
+                    }
+                    len -= 16;
+                    out += 16;
+                    in += 16;
+                    n = 0;
+                }
+                if (len) {
+                    (*block) (ivec, ivec, key);
+                    while (len--) {
+                        unsigned char c;
+                        out[n] = ivec[n] ^ (c = in[n]);
+                        ivec[n] = c;
+                        ++n;
+                    }
+                }
+                *num = n;
+                return;
+            } while (0);
+        }
+        /* the rest would be commonly eliminated by x86* compiler */
+#endif
+        while (l < len) {
+            unsigned char c;
+            if (n == 0) {
+                (*block) (ivec, ivec, key);
+            }
+            out[l] = ivec[n] ^ (c = in[l]);
+            ivec[n] = c;
+            ++l;
+            n = (n + 1) % 16;
+        }
+        *num = n;
+    }
+}
+
+/*
+ * This expects a single block of size nbits for both in and out. Note that
+ * it corrupts any extra bits in the last byte of out
+ */
+static void cfbr_encrypt_block(const unsigned char *in, unsigned char *out,
+                               int nbits, const void *key,
+                               unsigned char ivec[16], int enc,
+                               block128_f block)
+{
+    int n, rem, num;
+    unsigned char ovec[16 * 2 + 1]; /* +1 because we dereference (but don't
+                                     * use) one byte off the end */
+
+    if (nbits <= 0 || nbits > 128)
+        return;
+
+    /* fill in the first half of the new IV with the current IV */
+    memcpy(ovec, ivec, 16);
+    /* construct the new IV */
+    (*block) (ivec, ivec, key);
+    num = (nbits + 7) / 8;
+    if (enc)                    /* encrypt the input */
+        for (n = 0; n < num; ++n)
+            out[n] = (ovec[16 + n] = in[n] ^ ivec[n]);
+    else                        /* decrypt the input */
+        for (n = 0; n < num; ++n)
+            out[n] = (ovec[16 + n] = in[n]) ^ ivec[n];
+    /* shift ovec left... */
+    rem = nbits % 8;
+    num = nbits / 8;
+    if (rem == 0)
+        memcpy(ivec, ovec + num, 16);
+    else
+        for (n = 0; n < 16; ++n)
+            ivec[n] = ovec[n + num] << rem | ovec[n + num + 1] >> (8 - rem);
+
+    /* it is not necessary to cleanse ovec, since the IV is not secret */
+}
+
+/* N.B. This expects the input to be packed, MS bit first */
+void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t bits, const void *key,
+                             unsigned char ivec[16], int *num,
+                             int enc, block128_f block)
+{
+    size_t n;
+    unsigned char c[1], d[1];
+
+    for (n = 0; n < bits; ++n) {
+        c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
+        cfbr_encrypt_block(c, d, 1, key, ivec, enc, block);
+        out[n / 8] = (out[n / 8] & ~(1 << (unsigned int)(7 - n % 8))) |
+            ((d[0] & 0x80) >> (unsigned int)(n % 8));
+    }
+}
+
+void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t length, const void *key,
+                             unsigned char ivec[16], int *num,
+                             int enc, block128_f block)
+{
+    size_t n;
+
+    for (n = 0; n < length; ++n)
+        cfbr_encrypt_block(&in[n], &out[n], 8, key, ivec, enc, block);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/ctr128.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/ctr128.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/ctr128.c	(revision 331)
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2008-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 <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+/*
+ * NOTE: the IV/counter CTR mode is big-endian.  The code itself is
+ * endian-neutral.
+ */
+
+/* increment counter (128-bit int) by 1 */
+static void ctr128_inc(unsigned char *counter)
+{
+    u32 n = 16, c = 1;
+
+    do {
+        --n;
+        c += counter[n];
+        counter[n] = (u8)c;
+        c >>= 8;
+    } while (n);
+}
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+static void ctr128_inc_aligned(unsigned char *counter)
+{
+    size_t *data, c, d, n;
+    const union {
+        long one;
+        char little;
+    } is_endian = {
+        1
+    };
+
+    if (is_endian.little || ((size_t)counter % sizeof(size_t)) != 0) {
+        ctr128_inc(counter);
+        return;
+    }
+
+    data = (size_t *)counter;
+    c = 1;
+    n = 16 / sizeof(size_t);
+    do {
+        --n;
+        d = data[n] += c;
+        /* did addition carry? */
+        c = ((d - c) & ~d) >> (sizeof(size_t) * 8 - 1);
+    } while (n);
+}
+#endif
+
+/*
+ * The input encrypted as though 128bit counter mode is being used.  The
+ * extra state information to record how much of the 128bit block we have
+ * used is contained in *num, and the encrypted counter is kept in
+ * ecount_buf.  Both *num and ecount_buf must be initialised with zeros
+ * before the first call to CRYPTO_ctr128_encrypt(). This algorithm assumes
+ * that the counter is in the x lower bits of the IV (ivec), and that the
+ * application has full control over overflow and the rest of the IV.  This
+ * implementation takes NO responsibility for checking that the counter
+ * doesn't overflow into the rest of the IV when incremented.
+ */
+void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const void *key,
+                           unsigned char ivec[16],
+                           unsigned char ecount_buf[16], unsigned int *num,
+                           block128_f block)
+{
+    unsigned int n;
+    size_t l = 0;
+
+    n = *num;
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+    if (16 % sizeof(size_t) == 0) { /* always true actually */
+        do {
+            while (n && len) {
+                *(out++) = *(in++) ^ ecount_buf[n];
+                --len;
+                n = (n + 1) % 16;
+            }
+
+# if defined(STRICT_ALIGNMENT)
+            if (((size_t)in | (size_t)out | (size_t)ecount_buf)
+                % sizeof(size_t) != 0)
+                break;
+# endif
+            while (len >= 16) {
+                (*block) (ivec, ecount_buf, key);
+                ctr128_inc_aligned(ivec);
+                for (n = 0; n < 16; n += sizeof(size_t))
+                    *(size_t *)(out + n) =
+                        *(size_t *)(in + n) ^ *(size_t *)(ecount_buf + n);
+                len -= 16;
+                out += 16;
+                in += 16;
+                n = 0;
+            }
+            if (len) {
+                (*block) (ivec, ecount_buf, key);
+                ctr128_inc_aligned(ivec);
+                while (len--) {
+                    out[n] = in[n] ^ ecount_buf[n];
+                    ++n;
+                }
+            }
+            *num = n;
+            return;
+        } while (0);
+    }
+    /* the rest would be commonly eliminated by x86* compiler */
+#endif
+    while (l < len) {
+        if (n == 0) {
+            (*block) (ivec, ecount_buf, key);
+            ctr128_inc(ivec);
+        }
+        out[l] = in[l] ^ ecount_buf[n];
+        ++l;
+        n = (n + 1) % 16;
+    }
+
+    *num = n;
+}
+
+/* increment upper 96 bits of 128-bit counter by 1 */
+static void ctr96_inc(unsigned char *counter)
+{
+    u32 n = 12, c = 1;
+
+    do {
+        --n;
+        c += counter[n];
+        counter[n] = (u8)c;
+        c >>= 8;
+    } while (n);
+}
+
+void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out,
+                                 size_t len, const void *key,
+                                 unsigned char ivec[16],
+                                 unsigned char ecount_buf[16],
+                                 unsigned int *num, ctr128_f func)
+{
+    unsigned int n, ctr32;
+
+    n = *num;
+
+    while (n && len) {
+        *(out++) = *(in++) ^ ecount_buf[n];
+        --len;
+        n = (n + 1) % 16;
+    }
+
+    ctr32 = GETU32(ivec + 12);
+    while (len >= 16) {
+        size_t blocks = len / 16;
+        /*
+         * 1<<28 is just a not-so-small yet not-so-large number...
+         * Below condition is practically never met, but it has to
+         * be checked for code correctness.
+         */
+        if (sizeof(size_t) > sizeof(unsigned int) && blocks > (1U << 28))
+            blocks = (1U << 28);
+        /*
+         * As (*func) operates on 32-bit counter, caller
+         * has to handle overflow. 'if' below detects the
+         * overflow, which is then handled by limiting the
+         * amount of blocks to the exact overflow point...
+         */
+        ctr32 += (u32)blocks;
+        if (ctr32 < blocks) {
+            blocks -= ctr32;
+            ctr32 = 0;
+        }
+        (*func) (in, out, blocks, key, ivec);
+        /* (*ctr) does not update ivec, caller does: */
+        PUTU32(ivec + 12, ctr32);
+        /* ... overflow was detected, propagate carry. */
+        if (ctr32 == 0)
+            ctr96_inc(ivec);
+        blocks *= 16;
+        len -= blocks;
+        out += blocks;
+        in += blocks;
+    }
+    if (len) {
+        memset(ecount_buf, 0, 16);
+        (*func) (ecount_buf, ecount_buf, 1, key, ivec);
+        ++ctr32;
+        PUTU32(ivec + 12, ctr32);
+        if (ctr32 == 0)
+            ctr96_inc(ivec);
+        while (len--) {
+            out[n] = in[n] ^ ecount_buf[n];
+            ++n;
+        }
+    }
+
+    *num = n;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/cts128.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/cts128.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/cts128.c	(revision 331)
@@ -0,0 +1,523 @@
+/*
+ * Copyright 2008-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 <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+/*
+ * Trouble with Ciphertext Stealing, CTS, mode is that there is no
+ * common official specification, but couple of cipher/application
+ * specific ones: RFC2040 and RFC3962. Then there is 'Proposal to
+ * Extend CBC Mode By "Ciphertext Stealing"' at NIST site, which
+ * deviates from mentioned RFCs. Most notably it allows input to be
+ * of block length and it doesn't flip the order of the last two
+ * blocks. CTS is being discussed even in ECB context, but it's not
+ * adopted for any known application. This implementation provides
+ * two interfaces: one compliant with above mentioned RFCs and one
+ * compliant with the NIST proposal, both extending CBC mode.
+ */
+
+size_t CRYPTO_cts128_encrypt_block(const unsigned char *in,
+                                   unsigned char *out, size_t len,
+                                   const void *key, unsigned char ivec[16],
+                                   block128_f block)
+{
+    size_t residue, n;
+
+    if (len <= 16)
+        return 0;
+
+    if ((residue = len % 16) == 0)
+        residue = 16;
+
+    len -= residue;
+
+    CRYPTO_cbc128_encrypt(in, out, len, key, ivec, block);
+
+    in += len;
+    out += len;
+
+    for (n = 0; n < residue; ++n)
+        ivec[n] ^= in[n];
+    (*block) (ivec, ivec, key);
+    memcpy(out, out - 16, residue);
+    memcpy(out - 16, ivec, 16);
+
+    return len + residue;
+}
+
+size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in,
+                                       unsigned char *out, size_t len,
+                                       const void *key,
+                                       unsigned char ivec[16],
+                                       block128_f block)
+{
+    size_t residue, n;
+
+    if (len < 16)
+        return 0;
+
+    residue = len % 16;
+
+    len -= residue;
+
+    CRYPTO_cbc128_encrypt(in, out, len, key, ivec, block);
+
+    if (residue == 0)
+        return len;
+
+    in += len;
+    out += len;
+
+    for (n = 0; n < residue; ++n)
+        ivec[n] ^= in[n];
+    (*block) (ivec, ivec, key);
+    memcpy(out - 16 + residue, ivec, 16);
+
+    return len + residue;
+}
+
+size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t len, const void *key,
+                             unsigned char ivec[16], cbc128_f cbc)
+{
+    size_t residue;
+    union {
+        size_t align;
+        unsigned char c[16];
+    } tmp;
+
+    if (len <= 16)
+        return 0;
+
+    if ((residue = len % 16) == 0)
+        residue = 16;
+
+    len -= residue;
+
+    (*cbc) (in, out, len, key, ivec, 1);
+
+    in += len;
+    out += len;
+
+#if defined(CBC_HANDLES_TRUNCATED_IO)
+    memcpy(tmp.c, out - 16, 16);
+    (*cbc) (in, out - 16, residue, key, ivec, 1);
+    memcpy(out, tmp.c, residue);
+#else
+    memset(tmp.c, 0, sizeof(tmp));
+    memcpy(tmp.c, in, residue);
+    memcpy(out, out - 16, residue);
+    (*cbc) (tmp.c, out - 16, 16, key, ivec, 1);
+#endif
+    return len + residue;
+}
+
+size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out,
+                                 size_t len, const void *key,
+                                 unsigned char ivec[16], cbc128_f cbc)
+{
+    size_t residue;
+    union {
+        size_t align;
+        unsigned char c[16];
+    } tmp;
+
+    if (len < 16)
+        return 0;
+
+    residue = len % 16;
+
+    len -= residue;
+
+    (*cbc) (in, out, len, key, ivec, 1);
+
+    if (residue == 0)
+        return len;
+
+    in += len;
+    out += len;
+
+#if defined(CBC_HANDLES_TRUNCATED_IO)
+    (*cbc) (in, out - 16 + residue, residue, key, ivec, 1);
+#else
+    memset(tmp.c, 0, sizeof(tmp));
+    memcpy(tmp.c, in, residue);
+    (*cbc) (tmp.c, out - 16 + residue, 16, key, ivec, 1);
+#endif
+    return len + residue;
+}
+
+size_t CRYPTO_cts128_decrypt_block(const unsigned char *in,
+                                   unsigned char *out, size_t len,
+                                   const void *key, unsigned char ivec[16],
+                                   block128_f block)
+{
+    size_t residue, n;
+    union {
+        size_t align;
+        unsigned char c[32];
+    } tmp;
+
+    if (len <= 16)
+        return 0;
+
+    if ((residue = len % 16) == 0)
+        residue = 16;
+
+    len -= 16 + residue;
+
+    if (len) {
+        CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block);
+        in += len;
+        out += len;
+    }
+
+    (*block) (in, tmp.c + 16, key);
+
+    memcpy(tmp.c, tmp.c + 16, 16);
+    memcpy(tmp.c, in + 16, residue);
+    (*block) (tmp.c, tmp.c, key);
+
+    for (n = 0; n < 16; ++n) {
+        unsigned char c = in[n];
+        out[n] = tmp.c[n] ^ ivec[n];
+        ivec[n] = c;
+    }
+    for (residue += 16; n < residue; ++n)
+        out[n] = tmp.c[n] ^ in[n];
+
+    return 16 + len + residue;
+}
+
+size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in,
+                                       unsigned char *out, size_t len,
+                                       const void *key,
+                                       unsigned char ivec[16],
+                                       block128_f block)
+{
+    size_t residue, n;
+    union {
+        size_t align;
+        unsigned char c[32];
+    } tmp;
+
+    if (len < 16)
+        return 0;
+
+    residue = len % 16;
+
+    if (residue == 0) {
+        CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block);
+        return len;
+    }
+
+    len -= 16 + residue;
+
+    if (len) {
+        CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block);
+        in += len;
+        out += len;
+    }
+
+    (*block) (in + residue, tmp.c + 16, key);
+
+    memcpy(tmp.c, tmp.c + 16, 16);
+    memcpy(tmp.c, in, residue);
+    (*block) (tmp.c, tmp.c, key);
+
+    for (n = 0; n < 16; ++n) {
+        unsigned char c = in[n];
+        out[n] = tmp.c[n] ^ ivec[n];
+        ivec[n] = in[n + residue];
+        tmp.c[n] = c;
+    }
+    for (residue += 16; n < residue; ++n)
+        out[n] = tmp.c[n] ^ tmp.c[n - 16];
+
+    return 16 + len + residue;
+}
+
+size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
+                             size_t len, const void *key,
+                             unsigned char ivec[16], cbc128_f cbc)
+{
+    size_t residue;
+    union {
+        size_t align;
+        unsigned char c[32];
+    } tmp;
+
+    if (len <= 16)
+        return 0;
+
+    if ((residue = len % 16) == 0)
+        residue = 16;
+
+    len -= 16 + residue;
+
+    if (len) {
+        (*cbc) (in, out, len, key, ivec, 0);
+        in += len;
+        out += len;
+    }
+
+    memset(tmp.c, 0, sizeof(tmp));
+    /*
+     * this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0]
+     */
+    (*cbc) (in, tmp.c, 16, key, tmp.c + 16, 0);
+
+    memcpy(tmp.c, in + 16, residue);
+#if defined(CBC_HANDLES_TRUNCATED_IO)
+    (*cbc) (tmp.c, out, 16 + residue, key, ivec, 0);
+#else
+    (*cbc) (tmp.c, tmp.c, 32, key, ivec, 0);
+    memcpy(out, tmp.c, 16 + residue);
+#endif
+    return 16 + len + residue;
+}
+
+size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out,
+                                 size_t len, const void *key,
+                                 unsigned char ivec[16], cbc128_f cbc)
+{
+    size_t residue;
+    union {
+        size_t align;
+        unsigned char c[32];
+    } tmp;
+
+    if (len < 16)
+        return 0;
+
+    residue = len % 16;
+
+    if (residue == 0) {
+        (*cbc) (in, out, len, key, ivec, 0);
+        return len;
+    }
+
+    len -= 16 + residue;
+
+    if (len) {
+        (*cbc) (in, out, len, key, ivec, 0);
+        in += len;
+        out += len;
+    }
+
+    memset(tmp.c, 0, sizeof(tmp));
+    /*
+     * this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0]
+     */
+    (*cbc) (in + residue, tmp.c, 16, key, tmp.c + 16, 0);
+
+    memcpy(tmp.c, in, residue);
+#if defined(CBC_HANDLES_TRUNCATED_IO)
+    (*cbc) (tmp.c, out, 16 + residue, key, ivec, 0);
+#else
+    (*cbc) (tmp.c, tmp.c, 32, key, ivec, 0);
+    memcpy(out, tmp.c, 16 + residue);
+#endif
+    return 16 + len + residue;
+}
+
+#if defined(SELFTEST)
+# include <stdio.h>
+# include <openssl/aes.h>
+
+/* test vectors from RFC 3962 */
+static const unsigned char test_key[16] = "chicken teriyaki";
+static const unsigned char test_input[64] =
+    "I would like the" " General Gau's C"
+    "hicken, please, " "and wonton soup.";
+static const unsigned char test_iv[16] =
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+static const unsigned char vector_17[17] = {
+    0xc6, 0x35, 0x35, 0x68, 0xf2, 0xbf, 0x8c, 0xb4,
+    0xd8, 0xa5, 0x80, 0x36, 0x2d, 0xa7, 0xff, 0x7f,
+    0x97
+};
+
+static const unsigned char vector_31[31] = {
+    0xfc, 0x00, 0x78, 0x3e, 0x0e, 0xfd, 0xb2, 0xc1,
+    0xd4, 0x45, 0xd4, 0xc8, 0xef, 0xf7, 0xed, 0x22,
+    0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
+    0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5
+};
+
+static const unsigned char vector_32[32] = {
+    0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
+    0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8,
+    0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
+    0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84
+};
+
+static const unsigned char vector_47[47] = {
+    0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
+    0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84,
+    0xb3, 0xff, 0xfd, 0x94, 0x0c, 0x16, 0xa1, 0x8c,
+    0x1b, 0x55, 0x49, 0xd2, 0xf8, 0x38, 0x02, 0x9e,
+    0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
+    0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5
+};
+
+static const unsigned char vector_48[48] = {
+    0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
+    0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84,
+    0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0,
+    0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8,
+    0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
+    0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8
+};
+
+static const unsigned char vector_64[64] = {
+    0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0,
+    0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84,
+    0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5,
+    0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8,
+    0x48, 0x07, 0xef, 0xe8, 0x36, 0xee, 0x89, 0xa5,
+    0x26, 0x73, 0x0d, 0xbc, 0x2f, 0x7b, 0xc8, 0x40,
+    0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0,
+    0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8
+};
+
+static AES_KEY encks, decks;
+
+void test_vector(const unsigned char *vector, size_t len)
+{
+    unsigned char iv[sizeof(test_iv)];
+    unsigned char cleartext[64], ciphertext[64];
+    size_t tail;
+
+    printf("vector_%d\n", len);
+    fflush(stdout);
+
+    if ((tail = len % 16) == 0)
+        tail = 16;
+    tail += 16;
+
+    /* test block-based encryption */
+    memcpy(iv, test_iv, sizeof(test_iv));
+    CRYPTO_cts128_encrypt_block(test_input, ciphertext, len, &encks, iv,
+                                (block128_f) AES_encrypt);
+    if (memcmp(ciphertext, vector, len))
+        fprintf(stderr, "output_%d mismatch\n", len), exit(1);
+    if (memcmp(iv, vector + len - tail, sizeof(iv)))
+        fprintf(stderr, "iv_%d mismatch\n", len), exit(1);
+
+    /* test block-based decryption */
+    memcpy(iv, test_iv, sizeof(test_iv));
+    CRYPTO_cts128_decrypt_block(ciphertext, cleartext, len, &decks, iv,
+                                (block128_f) AES_decrypt);
+    if (memcmp(cleartext, test_input, len))
+        fprintf(stderr, "input_%d mismatch\n", len), exit(2);
+    if (memcmp(iv, vector + len - tail, sizeof(iv)))
+        fprintf(stderr, "iv_%d mismatch\n", len), exit(2);
+
+    /* test streamed encryption */
+    memcpy(iv, test_iv, sizeof(test_iv));
+    CRYPTO_cts128_encrypt(test_input, ciphertext, len, &encks, iv,
+                          (cbc128_f) AES_cbc_encrypt);
+    if (memcmp(ciphertext, vector, len))
+        fprintf(stderr, "output_%d mismatch\n", len), exit(3);
+    if (memcmp(iv, vector + len - tail, sizeof(iv)))
+        fprintf(stderr, "iv_%d mismatch\n", len), exit(3);
+
+    /* test streamed decryption */
+    memcpy(iv, test_iv, sizeof(test_iv));
+    CRYPTO_cts128_decrypt(ciphertext, cleartext, len, &decks, iv,
+                          (cbc128_f) AES_cbc_encrypt);
+    if (memcmp(cleartext, test_input, len))
+        fprintf(stderr, "input_%d mismatch\n", len), exit(4);
+    if (memcmp(iv, vector + len - tail, sizeof(iv)))
+        fprintf(stderr, "iv_%d mismatch\n", len), exit(4);
+}
+
+void test_nistvector(const unsigned char *vector, size_t len)
+{
+    unsigned char iv[sizeof(test_iv)];
+    unsigned char cleartext[64], ciphertext[64], nistvector[64];
+    size_t tail;
+
+    printf("nistvector_%d\n", len);
+    fflush(stdout);
+
+    if ((tail = len % 16) == 0)
+        tail = 16;
+
+    len -= 16 + tail;
+    memcpy(nistvector, vector, len);
+    /* flip two last blocks */
+    memcpy(nistvector + len, vector + len + 16, tail);
+    memcpy(nistvector + len + tail, vector + len, 16);
+    len += 16 + tail;
+    tail = 16;
+
+    /* test block-based encryption */
+    memcpy(iv, test_iv, sizeof(test_iv));
+    CRYPTO_nistcts128_encrypt_block(test_input, ciphertext, len, &encks, iv,
+                                    (block128_f) AES_encrypt);
+    if (memcmp(ciphertext, nistvector, len))
+        fprintf(stderr, "output_%d mismatch\n", len), exit(1);
+    if (memcmp(iv, nistvector + len - tail, sizeof(iv)))
+        fprintf(stderr, "iv_%d mismatch\n", len), exit(1);
+
+    /* test block-based decryption */
+    memcpy(iv, test_iv, sizeof(test_iv));
+    CRYPTO_nistcts128_decrypt_block(ciphertext, cleartext, len, &decks, iv,
+                                    (block128_f) AES_decrypt);
+    if (memcmp(cleartext, test_input, len))
+        fprintf(stderr, "input_%d mismatch\n", len), exit(2);
+    if (memcmp(iv, nistvector + len - tail, sizeof(iv)))
+        fprintf(stderr, "iv_%d mismatch\n", len), exit(2);
+
+    /* test streamed encryption */
+    memcpy(iv, test_iv, sizeof(test_iv));
+    CRYPTO_nistcts128_encrypt(test_input, ciphertext, len, &encks, iv,
+                              (cbc128_f) AES_cbc_encrypt);
+    if (memcmp(ciphertext, nistvector, len))
+        fprintf(stderr, "output_%d mismatch\n", len), exit(3);
+    if (memcmp(iv, nistvector + len - tail, sizeof(iv)))
+        fprintf(stderr, "iv_%d mismatch\n", len), exit(3);
+
+    /* test streamed decryption */
+    memcpy(iv, test_iv, sizeof(test_iv));
+    CRYPTO_nistcts128_decrypt(ciphertext, cleartext, len, &decks, iv,
+                              (cbc128_f) AES_cbc_encrypt);
+    if (memcmp(cleartext, test_input, len))
+        fprintf(stderr, "input_%d mismatch\n", len), exit(4);
+    if (memcmp(iv, nistvector + len - tail, sizeof(iv)))
+        fprintf(stderr, "iv_%d mismatch\n", len), exit(4);
+}
+
+int main()
+{
+    AES_set_encrypt_key(test_key, 128, &encks);
+    AES_set_decrypt_key(test_key, 128, &decks);
+
+    test_vector(vector_17, sizeof(vector_17));
+    test_vector(vector_31, sizeof(vector_31));
+    test_vector(vector_32, sizeof(vector_32));
+    test_vector(vector_47, sizeof(vector_47));
+    test_vector(vector_48, sizeof(vector_48));
+    test_vector(vector_64, sizeof(vector_64));
+
+    test_nistvector(vector_17, sizeof(vector_17));
+    test_nistvector(vector_31, sizeof(vector_31));
+    test_nistvector(vector_32, sizeof(vector_32));
+    test_nistvector(vector_47, sizeof(vector_47));
+    test_nistvector(vector_48, sizeof(vector_48));
+    test_nistvector(vector_64, sizeof(vector_64));
+
+    return 0;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/gcm128.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/gcm128.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/gcm128.c	(revision 331)
@@ -0,0 +1,2302 @@
+/*
+ * Copyright 2010-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 <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+#if defined(BSWAP4) && defined(STRICT_ALIGNMENT)
+/* redefine, because alignment is ensured */
+# undef  GETU32
+# define GETU32(p)       BSWAP4(*(const u32 *)(p))
+# undef  PUTU32
+# define PUTU32(p,v)     *(u32 *)(p) = BSWAP4(v)
+#endif
+
+#define PACK(s)         ((size_t)(s)<<(sizeof(size_t)*8-16))
+#define REDUCE1BIT(V)   do { \
+        if (sizeof(size_t)==8) { \
+                u64 T = U64(0xe100000000000000) & (0-(V.lo&1)); \
+                V.lo  = (V.hi<<63)|(V.lo>>1); \
+                V.hi  = (V.hi>>1 )^T; \
+        } \
+        else { \
+                u32 T = 0xe1000000U & (0-(u32)(V.lo&1)); \
+                V.lo  = (V.hi<<63)|(V.lo>>1); \
+                V.hi  = (V.hi>>1 )^((u64)T<<32); \
+        } \
+} while(0)
+
+/*-
+ * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should
+ * never be set to 8. 8 is effectively reserved for testing purposes.
+ * TABLE_BITS>1 are lookup-table-driven implementations referred to as
+ * "Shoup's" in GCM specification. In other words OpenSSL does not cover
+ * whole spectrum of possible table driven implementations. Why? In
+ * non-"Shoup's" case memory access pattern is segmented in such manner,
+ * that it's trivial to see that cache timing information can reveal
+ * fair portion of intermediate hash value. Given that ciphertext is
+ * always available to attacker, it's possible for him to attempt to
+ * deduce secret parameter H and if successful, tamper with messages
+ * [which is nothing but trivial in CTR mode]. In "Shoup's" case it's
+ * not as trivial, but there is no reason to believe that it's resistant
+ * to cache-timing attack. And the thing about "8-bit" implementation is
+ * that it consumes 16 (sixteen) times more memory, 4KB per individual
+ * key + 1KB shared. Well, on pros side it should be twice as fast as
+ * "4-bit" version. And for gcc-generated x86[_64] code, "8-bit" version
+ * was observed to run ~75% faster, closer to 100% for commercial
+ * compilers... Yet "4-bit" procedure is preferred, because it's
+ * believed to provide better security-performance balance and adequate
+ * all-round performance. "All-round" refers to things like:
+ *
+ * - shorter setup time effectively improves overall timing for
+ *   handling short messages;
+ * - larger table allocation can become unbearable because of VM
+ *   subsystem penalties (for example on Windows large enough free
+ *   results in VM working set trimming, meaning that consequent
+ *   malloc would immediately incur working set expansion);
+ * - larger table has larger cache footprint, which can affect
+ *   performance of other code paths (not necessarily even from same
+ *   thread in Hyper-Threading world);
+ *
+ * Value of 1 is not appropriate for performance reasons.
+ */
+#if     TABLE_BITS==8
+
+static void gcm_init_8bit(u128 Htable[256], u64 H[2])
+{
+    int i, j;
+    u128 V;
+
+    Htable[0].hi = 0;
+    Htable[0].lo = 0;
+    V.hi = H[0];
+    V.lo = H[1];
+
+    for (Htable[128] = V, i = 64; i > 0; i >>= 1) {
+        REDUCE1BIT(V);
+        Htable[i] = V;
+    }
+
+    for (i = 2; i < 256; i <<= 1) {
+        u128 *Hi = Htable + i, H0 = *Hi;
+        for (j = 1; j < i; ++j) {
+            Hi[j].hi = H0.hi ^ Htable[j].hi;
+            Hi[j].lo = H0.lo ^ Htable[j].lo;
+        }
+    }
+}
+
+static void gcm_gmult_8bit(u64 Xi[2], const u128 Htable[256])
+{
+    u128 Z = { 0, 0 };
+    const u8 *xi = (const u8 *)Xi + 15;
+    size_t rem, n = *xi;
+    const union {
+        long one;
+        char little;
+    } is_endian = { 1 };
+    static const size_t rem_8bit[256] = {
+        PACK(0x0000), PACK(0x01C2), PACK(0x0384), PACK(0x0246),
+        PACK(0x0708), PACK(0x06CA), PACK(0x048C), PACK(0x054E),
+        PACK(0x0E10), PACK(0x0FD2), PACK(0x0D94), PACK(0x0C56),
+        PACK(0x0918), PACK(0x08DA), PACK(0x0A9C), PACK(0x0B5E),
+        PACK(0x1C20), PACK(0x1DE2), PACK(0x1FA4), PACK(0x1E66),
+        PACK(0x1B28), PACK(0x1AEA), PACK(0x18AC), PACK(0x196E),
+        PACK(0x1230), PACK(0x13F2), PACK(0x11B4), PACK(0x1076),
+        PACK(0x1538), PACK(0x14FA), PACK(0x16BC), PACK(0x177E),
+        PACK(0x3840), PACK(0x3982), PACK(0x3BC4), PACK(0x3A06),
+        PACK(0x3F48), PACK(0x3E8A), PACK(0x3CCC), PACK(0x3D0E),
+        PACK(0x3650), PACK(0x3792), PACK(0x35D4), PACK(0x3416),
+        PACK(0x3158), PACK(0x309A), PACK(0x32DC), PACK(0x331E),
+        PACK(0x2460), PACK(0x25A2), PACK(0x27E4), PACK(0x2626),
+        PACK(0x2368), PACK(0x22AA), PACK(0x20EC), PACK(0x212E),
+        PACK(0x2A70), PACK(0x2BB2), PACK(0x29F4), PACK(0x2836),
+        PACK(0x2D78), PACK(0x2CBA), PACK(0x2EFC), PACK(0x2F3E),
+        PACK(0x7080), PACK(0x7142), PACK(0x7304), PACK(0x72C6),
+        PACK(0x7788), PACK(0x764A), PACK(0x740C), PACK(0x75CE),
+        PACK(0x7E90), PACK(0x7F52), PACK(0x7D14), PACK(0x7CD6),
+        PACK(0x7998), PACK(0x785A), PACK(0x7A1C), PACK(0x7BDE),
+        PACK(0x6CA0), PACK(0x6D62), PACK(0x6F24), PACK(0x6EE6),
+        PACK(0x6BA8), PACK(0x6A6A), PACK(0x682C), PACK(0x69EE),
+        PACK(0x62B0), PACK(0x6372), PACK(0x6134), PACK(0x60F6),
+        PACK(0x65B8), PACK(0x647A), PACK(0x663C), PACK(0x67FE),
+        PACK(0x48C0), PACK(0x4902), PACK(0x4B44), PACK(0x4A86),
+        PACK(0x4FC8), PACK(0x4E0A), PACK(0x4C4C), PACK(0x4D8E),
+        PACK(0x46D0), PACK(0x4712), PACK(0x4554), PACK(0x4496),
+        PACK(0x41D8), PACK(0x401A), PACK(0x425C), PACK(0x439E),
+        PACK(0x54E0), PACK(0x5522), PACK(0x5764), PACK(0x56A6),
+        PACK(0x53E8), PACK(0x522A), PACK(0x506C), PACK(0x51AE),
+        PACK(0x5AF0), PACK(0x5B32), PACK(0x5974), PACK(0x58B6),
+        PACK(0x5DF8), PACK(0x5C3A), PACK(0x5E7C), PACK(0x5FBE),
+        PACK(0xE100), PACK(0xE0C2), PACK(0xE284), PACK(0xE346),
+        PACK(0xE608), PACK(0xE7CA), PACK(0xE58C), PACK(0xE44E),
+        PACK(0xEF10), PACK(0xEED2), PACK(0xEC94), PACK(0xED56),
+        PACK(0xE818), PACK(0xE9DA), PACK(0xEB9C), PACK(0xEA5E),
+        PACK(0xFD20), PACK(0xFCE2), PACK(0xFEA4), PACK(0xFF66),
+        PACK(0xFA28), PACK(0xFBEA), PACK(0xF9AC), PACK(0xF86E),
+        PACK(0xF330), PACK(0xF2F2), PACK(0xF0B4), PACK(0xF176),
+        PACK(0xF438), PACK(0xF5FA), PACK(0xF7BC), PACK(0xF67E),
+        PACK(0xD940), PACK(0xD882), PACK(0xDAC4), PACK(0xDB06),
+        PACK(0xDE48), PACK(0xDF8A), PACK(0xDDCC), PACK(0xDC0E),
+        PACK(0xD750), PACK(0xD692), PACK(0xD4D4), PACK(0xD516),
+        PACK(0xD058), PACK(0xD19A), PACK(0xD3DC), PACK(0xD21E),
+        PACK(0xC560), PACK(0xC4A2), PACK(0xC6E4), PACK(0xC726),
+        PACK(0xC268), PACK(0xC3AA), PACK(0xC1EC), PACK(0xC02E),
+        PACK(0xCB70), PACK(0xCAB2), PACK(0xC8F4), PACK(0xC936),
+        PACK(0xCC78), PACK(0xCDBA), PACK(0xCFFC), PACK(0xCE3E),
+        PACK(0x9180), PACK(0x9042), PACK(0x9204), PACK(0x93C6),
+        PACK(0x9688), PACK(0x974A), PACK(0x950C), PACK(0x94CE),
+        PACK(0x9F90), PACK(0x9E52), PACK(0x9C14), PACK(0x9DD6),
+        PACK(0x9898), PACK(0x995A), PACK(0x9B1C), PACK(0x9ADE),
+        PACK(0x8DA0), PACK(0x8C62), PACK(0x8E24), PACK(0x8FE6),
+        PACK(0x8AA8), PACK(0x8B6A), PACK(0x892C), PACK(0x88EE),
+        PACK(0x83B0), PACK(0x8272), PACK(0x8034), PACK(0x81F6),
+        PACK(0x84B8), PACK(0x857A), PACK(0x873C), PACK(0x86FE),
+        PACK(0xA9C0), PACK(0xA802), PACK(0xAA44), PACK(0xAB86),
+        PACK(0xAEC8), PACK(0xAF0A), PACK(0xAD4C), PACK(0xAC8E),
+        PACK(0xA7D0), PACK(0xA612), PACK(0xA454), PACK(0xA596),
+        PACK(0xA0D8), PACK(0xA11A), PACK(0xA35C), PACK(0xA29E),
+        PACK(0xB5E0), PACK(0xB422), PACK(0xB664), PACK(0xB7A6),
+        PACK(0xB2E8), PACK(0xB32A), PACK(0xB16C), PACK(0xB0AE),
+        PACK(0xBBF0), PACK(0xBA32), PACK(0xB874), PACK(0xB9B6),
+        PACK(0xBCF8), PACK(0xBD3A), PACK(0xBF7C), PACK(0xBEBE)
+    };
+
+    while (1) {
+        Z.hi ^= Htable[n].hi;
+        Z.lo ^= Htable[n].lo;
+
+        if ((u8 *)Xi == xi)
+            break;
+
+        n = *(--xi);
+
+        rem = (size_t)Z.lo & 0xff;
+        Z.lo = (Z.hi << 56) | (Z.lo >> 8);
+        Z.hi = (Z.hi >> 8);
+        if (sizeof(size_t) == 8)
+            Z.hi ^= rem_8bit[rem];
+        else
+            Z.hi ^= (u64)rem_8bit[rem] << 32;
+    }
+
+    if (is_endian.little) {
+# ifdef BSWAP8
+        Xi[0] = BSWAP8(Z.hi);
+        Xi[1] = BSWAP8(Z.lo);
+# else
+        u8 *p = (u8 *)Xi;
+        u32 v;
+        v = (u32)(Z.hi >> 32);
+        PUTU32(p, v);
+        v = (u32)(Z.hi);
+        PUTU32(p + 4, v);
+        v = (u32)(Z.lo >> 32);
+        PUTU32(p + 8, v);
+        v = (u32)(Z.lo);
+        PUTU32(p + 12, v);
+# endif
+    } else {
+        Xi[0] = Z.hi;
+        Xi[1] = Z.lo;
+    }
+}
+
+# define GCM_MUL(ctx,Xi)   gcm_gmult_8bit(ctx->Xi.u,ctx->Htable)
+
+#elif   TABLE_BITS==4
+
+static void gcm_init_4bit(u128 Htable[16], u64 H[2])
+{
+    u128 V;
+# if defined(OPENSSL_SMALL_FOOTPRINT)
+    int i;
+# endif
+
+    Htable[0].hi = 0;
+    Htable[0].lo = 0;
+    V.hi = H[0];
+    V.lo = H[1];
+
+# if defined(OPENSSL_SMALL_FOOTPRINT)
+    for (Htable[8] = V, i = 4; i > 0; i >>= 1) {
+        REDUCE1BIT(V);
+        Htable[i] = V;
+    }
+
+    for (i = 2; i < 16; i <<= 1) {
+        u128 *Hi = Htable + i;
+        int j;
+        for (V = *Hi, j = 1; j < i; ++j) {
+            Hi[j].hi = V.hi ^ Htable[j].hi;
+            Hi[j].lo = V.lo ^ Htable[j].lo;
+        }
+    }
+# else
+    Htable[8] = V;
+    REDUCE1BIT(V);
+    Htable[4] = V;
+    REDUCE1BIT(V);
+    Htable[2] = V;
+    REDUCE1BIT(V);
+    Htable[1] = V;
+    Htable[3].hi = V.hi ^ Htable[2].hi, Htable[3].lo = V.lo ^ Htable[2].lo;
+    V = Htable[4];
+    Htable[5].hi = V.hi ^ Htable[1].hi, Htable[5].lo = V.lo ^ Htable[1].lo;
+    Htable[6].hi = V.hi ^ Htable[2].hi, Htable[6].lo = V.lo ^ Htable[2].lo;
+    Htable[7].hi = V.hi ^ Htable[3].hi, Htable[7].lo = V.lo ^ Htable[3].lo;
+    V = Htable[8];
+    Htable[9].hi = V.hi ^ Htable[1].hi, Htable[9].lo = V.lo ^ Htable[1].lo;
+    Htable[10].hi = V.hi ^ Htable[2].hi, Htable[10].lo = V.lo ^ Htable[2].lo;
+    Htable[11].hi = V.hi ^ Htable[3].hi, Htable[11].lo = V.lo ^ Htable[3].lo;
+    Htable[12].hi = V.hi ^ Htable[4].hi, Htable[12].lo = V.lo ^ Htable[4].lo;
+    Htable[13].hi = V.hi ^ Htable[5].hi, Htable[13].lo = V.lo ^ Htable[5].lo;
+    Htable[14].hi = V.hi ^ Htable[6].hi, Htable[14].lo = V.lo ^ Htable[6].lo;
+    Htable[15].hi = V.hi ^ Htable[7].hi, Htable[15].lo = V.lo ^ Htable[7].lo;
+# endif
+# if defined(GHASH_ASM) && (defined(__arm__) || defined(__arm))
+    /*
+     * ARM assembler expects specific dword order in Htable.
+     */
+    {
+        int j;
+        const union {
+            long one;
+            char little;
+        } is_endian = { 1 };
+
+        if (is_endian.little)
+            for (j = 0; j < 16; ++j) {
+                V = Htable[j];
+                Htable[j].hi = V.lo;
+                Htable[j].lo = V.hi;
+        } else
+            for (j = 0; j < 16; ++j) {
+                V = Htable[j];
+                Htable[j].hi = V.lo << 32 | V.lo >> 32;
+                Htable[j].lo = V.hi << 32 | V.hi >> 32;
+            }
+    }
+# endif
+}
+
+# ifndef GHASH_ASM
+static const size_t rem_4bit[16] = {
+    PACK(0x0000), PACK(0x1C20), PACK(0x3840), PACK(0x2460),
+    PACK(0x7080), PACK(0x6CA0), PACK(0x48C0), PACK(0x54E0),
+    PACK(0xE100), PACK(0xFD20), PACK(0xD940), PACK(0xC560),
+    PACK(0x9180), PACK(0x8DA0), PACK(0xA9C0), PACK(0xB5E0)
+};
+
+static void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16])
+{
+    u128 Z;
+    int cnt = 15;
+    size_t rem, nlo, nhi;
+    const union {
+        long one;
+        char little;
+    } is_endian = { 1 };
+
+    nlo = ((const u8 *)Xi)[15];
+    nhi = nlo >> 4;
+    nlo &= 0xf;
+
+    Z.hi = Htable[nlo].hi;
+    Z.lo = Htable[nlo].lo;
+
+    while (1) {
+        rem = (size_t)Z.lo & 0xf;
+        Z.lo = (Z.hi << 60) | (Z.lo >> 4);
+        Z.hi = (Z.hi >> 4);
+        if (sizeof(size_t) == 8)
+            Z.hi ^= rem_4bit[rem];
+        else
+            Z.hi ^= (u64)rem_4bit[rem] << 32;
+
+        Z.hi ^= Htable[nhi].hi;
+        Z.lo ^= Htable[nhi].lo;
+
+        if (--cnt < 0)
+            break;
+
+        nlo = ((const u8 *)Xi)[cnt];
+        nhi = nlo >> 4;
+        nlo &= 0xf;
+
+        rem = (size_t)Z.lo & 0xf;
+        Z.lo = (Z.hi << 60) | (Z.lo >> 4);
+        Z.hi = (Z.hi >> 4);
+        if (sizeof(size_t) == 8)
+            Z.hi ^= rem_4bit[rem];
+        else
+            Z.hi ^= (u64)rem_4bit[rem] << 32;
+
+        Z.hi ^= Htable[nlo].hi;
+        Z.lo ^= Htable[nlo].lo;
+    }
+
+    if (is_endian.little) {
+#  ifdef BSWAP8
+        Xi[0] = BSWAP8(Z.hi);
+        Xi[1] = BSWAP8(Z.lo);
+#  else
+        u8 *p = (u8 *)Xi;
+        u32 v;
+        v = (u32)(Z.hi >> 32);
+        PUTU32(p, v);
+        v = (u32)(Z.hi);
+        PUTU32(p + 4, v);
+        v = (u32)(Z.lo >> 32);
+        PUTU32(p + 8, v);
+        v = (u32)(Z.lo);
+        PUTU32(p + 12, v);
+#  endif
+    } else {
+        Xi[0] = Z.hi;
+        Xi[1] = Z.lo;
+    }
+}
+
+#  if !defined(OPENSSL_SMALL_FOOTPRINT)
+/*
+ * Streamed gcm_mult_4bit, see CRYPTO_gcm128_[en|de]crypt for
+ * details... Compiler-generated code doesn't seem to give any
+ * performance improvement, at least not on x86[_64]. It's here
+ * mostly as reference and a placeholder for possible future
+ * non-trivial optimization[s]...
+ */
+static void gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16],
+                           const u8 *inp, size_t len)
+{
+    u128 Z;
+    int cnt;
+    size_t rem, nlo, nhi;
+    const union {
+        long one;
+        char little;
+    } is_endian = { 1 };
+
+#   if 1
+    do {
+        cnt = 15;
+        nlo = ((const u8 *)Xi)[15];
+        nlo ^= inp[15];
+        nhi = nlo >> 4;
+        nlo &= 0xf;
+
+        Z.hi = Htable[nlo].hi;
+        Z.lo = Htable[nlo].lo;
+
+        while (1) {
+            rem = (size_t)Z.lo & 0xf;
+            Z.lo = (Z.hi << 60) | (Z.lo >> 4);
+            Z.hi = (Z.hi >> 4);
+            if (sizeof(size_t) == 8)
+                Z.hi ^= rem_4bit[rem];
+            else
+                Z.hi ^= (u64)rem_4bit[rem] << 32;
+
+            Z.hi ^= Htable[nhi].hi;
+            Z.lo ^= Htable[nhi].lo;
+
+            if (--cnt < 0)
+                break;
+
+            nlo = ((const u8 *)Xi)[cnt];
+            nlo ^= inp[cnt];
+            nhi = nlo >> 4;
+            nlo &= 0xf;
+
+            rem = (size_t)Z.lo & 0xf;
+            Z.lo = (Z.hi << 60) | (Z.lo >> 4);
+            Z.hi = (Z.hi >> 4);
+            if (sizeof(size_t) == 8)
+                Z.hi ^= rem_4bit[rem];
+            else
+                Z.hi ^= (u64)rem_4bit[rem] << 32;
+
+            Z.hi ^= Htable[nlo].hi;
+            Z.lo ^= Htable[nlo].lo;
+        }
+#   else
+    /*
+     * Extra 256+16 bytes per-key plus 512 bytes shared tables
+     * [should] give ~50% improvement... One could have PACK()-ed
+     * the rem_8bit even here, but the priority is to minimize
+     * cache footprint...
+     */
+    u128 Hshr4[16];             /* Htable shifted right by 4 bits */
+    u8 Hshl4[16];               /* Htable shifted left by 4 bits */
+    static const unsigned short rem_8bit[256] = {
+        0x0000, 0x01C2, 0x0384, 0x0246, 0x0708, 0x06CA, 0x048C, 0x054E,
+        0x0E10, 0x0FD2, 0x0D94, 0x0C56, 0x0918, 0x08DA, 0x0A9C, 0x0B5E,
+        0x1C20, 0x1DE2, 0x1FA4, 0x1E66, 0x1B28, 0x1AEA, 0x18AC, 0x196E,
+        0x1230, 0x13F2, 0x11B4, 0x1076, 0x1538, 0x14FA, 0x16BC, 0x177E,
+        0x3840, 0x3982, 0x3BC4, 0x3A06, 0x3F48, 0x3E8A, 0x3CCC, 0x3D0E,
+        0x3650, 0x3792, 0x35D4, 0x3416, 0x3158, 0x309A, 0x32DC, 0x331E,
+        0x2460, 0x25A2, 0x27E4, 0x2626, 0x2368, 0x22AA, 0x20EC, 0x212E,
+        0x2A70, 0x2BB2, 0x29F4, 0x2836, 0x2D78, 0x2CBA, 0x2EFC, 0x2F3E,
+        0x7080, 0x7142, 0x7304, 0x72C6, 0x7788, 0x764A, 0x740C, 0x75CE,
+        0x7E90, 0x7F52, 0x7D14, 0x7CD6, 0x7998, 0x785A, 0x7A1C, 0x7BDE,
+        0x6CA0, 0x6D62, 0x6F24, 0x6EE6, 0x6BA8, 0x6A6A, 0x682C, 0x69EE,
+        0x62B0, 0x6372, 0x6134, 0x60F6, 0x65B8, 0x647A, 0x663C, 0x67FE,
+        0x48C0, 0x4902, 0x4B44, 0x4A86, 0x4FC8, 0x4E0A, 0x4C4C, 0x4D8E,
+        0x46D0, 0x4712, 0x4554, 0x4496, 0x41D8, 0x401A, 0x425C, 0x439E,
+        0x54E0, 0x5522, 0x5764, 0x56A6, 0x53E8, 0x522A, 0x506C, 0x51AE,
+        0x5AF0, 0x5B32, 0x5974, 0x58B6, 0x5DF8, 0x5C3A, 0x5E7C, 0x5FBE,
+        0xE100, 0xE0C2, 0xE284, 0xE346, 0xE608, 0xE7CA, 0xE58C, 0xE44E,
+        0xEF10, 0xEED2, 0xEC94, 0xED56, 0xE818, 0xE9DA, 0xEB9C, 0xEA5E,
+        0xFD20, 0xFCE2, 0xFEA4, 0xFF66, 0xFA28, 0xFBEA, 0xF9AC, 0xF86E,
+        0xF330, 0xF2F2, 0xF0B4, 0xF176, 0xF438, 0xF5FA, 0xF7BC, 0xF67E,
+        0xD940, 0xD882, 0xDAC4, 0xDB06, 0xDE48, 0xDF8A, 0xDDCC, 0xDC0E,
+        0xD750, 0xD692, 0xD4D4, 0xD516, 0xD058, 0xD19A, 0xD3DC, 0xD21E,
+        0xC560, 0xC4A2, 0xC6E4, 0xC726, 0xC268, 0xC3AA, 0xC1EC, 0xC02E,
+        0xCB70, 0xCAB2, 0xC8F4, 0xC936, 0xCC78, 0xCDBA, 0xCFFC, 0xCE3E,
+        0x9180, 0x9042, 0x9204, 0x93C6, 0x9688, 0x974A, 0x950C, 0x94CE,
+        0x9F90, 0x9E52, 0x9C14, 0x9DD6, 0x9898, 0x995A, 0x9B1C, 0x9ADE,
+        0x8DA0, 0x8C62, 0x8E24, 0x8FE6, 0x8AA8, 0x8B6A, 0x892C, 0x88EE,
+        0x83B0, 0x8272, 0x8034, 0x81F6, 0x84B8, 0x857A, 0x873C, 0x86FE,
+        0xA9C0, 0xA802, 0xAA44, 0xAB86, 0xAEC8, 0xAF0A, 0xAD4C, 0xAC8E,
+        0xA7D0, 0xA612, 0xA454, 0xA596, 0xA0D8, 0xA11A, 0xA35C, 0xA29E,
+        0xB5E0, 0xB422, 0xB664, 0xB7A6, 0xB2E8, 0xB32A, 0xB16C, 0xB0AE,
+        0xBBF0, 0xBA32, 0xB874, 0xB9B6, 0xBCF8, 0xBD3A, 0xBF7C, 0xBEBE
+    };
+    /*
+     * This pre-processing phase slows down procedure by approximately
+     * same time as it makes each loop spin faster. In other words
+     * single block performance is approximately same as straightforward
+     * "4-bit" implementation, and then it goes only faster...
+     */
+    for (cnt = 0; cnt < 16; ++cnt) {
+        Z.hi = Htable[cnt].hi;
+        Z.lo = Htable[cnt].lo;
+        Hshr4[cnt].lo = (Z.hi << 60) | (Z.lo >> 4);
+        Hshr4[cnt].hi = (Z.hi >> 4);
+        Hshl4[cnt] = (u8)(Z.lo << 4);
+    }
+
+    do {
+        for (Z.lo = 0, Z.hi = 0, cnt = 15; cnt; --cnt) {
+            nlo = ((const u8 *)Xi)[cnt];
+            nlo ^= inp[cnt];
+            nhi = nlo >> 4;
+            nlo &= 0xf;
+
+            Z.hi ^= Htable[nlo].hi;
+            Z.lo ^= Htable[nlo].lo;
+
+            rem = (size_t)Z.lo & 0xff;
+
+            Z.lo = (Z.hi << 56) | (Z.lo >> 8);
+            Z.hi = (Z.hi >> 8);
+
+            Z.hi ^= Hshr4[nhi].hi;
+            Z.lo ^= Hshr4[nhi].lo;
+            Z.hi ^= (u64)rem_8bit[rem ^ Hshl4[nhi]] << 48;
+        }
+
+        nlo = ((const u8 *)Xi)[0];
+        nlo ^= inp[0];
+        nhi = nlo >> 4;
+        nlo &= 0xf;
+
+        Z.hi ^= Htable[nlo].hi;
+        Z.lo ^= Htable[nlo].lo;
+
+        rem = (size_t)Z.lo & 0xf;
+
+        Z.lo = (Z.hi << 60) | (Z.lo >> 4);
+        Z.hi = (Z.hi >> 4);
+
+        Z.hi ^= Htable[nhi].hi;
+        Z.lo ^= Htable[nhi].lo;
+        Z.hi ^= ((u64)rem_8bit[rem << 4]) << 48;
+#   endif
+
+        if (is_endian.little) {
+#   ifdef BSWAP8
+            Xi[0] = BSWAP8(Z.hi);
+            Xi[1] = BSWAP8(Z.lo);
+#   else
+            u8 *p = (u8 *)Xi;
+            u32 v;
+            v = (u32)(Z.hi >> 32);
+            PUTU32(p, v);
+            v = (u32)(Z.hi);
+            PUTU32(p + 4, v);
+            v = (u32)(Z.lo >> 32);
+            PUTU32(p + 8, v);
+            v = (u32)(Z.lo);
+            PUTU32(p + 12, v);
+#   endif
+        } else {
+            Xi[0] = Z.hi;
+            Xi[1] = Z.lo;
+        }
+    } while (inp += 16, len -= 16);
+}
+#  endif
+# else
+void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16]);
+void gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], const u8 *inp,
+                    size_t len);
+# endif
+
+# define GCM_MUL(ctx,Xi)   gcm_gmult_4bit(ctx->Xi.u,ctx->Htable)
+# if defined(GHASH_ASM) || !defined(OPENSSL_SMALL_FOOTPRINT)
+#  define GHASH(ctx,in,len) gcm_ghash_4bit((ctx)->Xi.u,(ctx)->Htable,in,len)
+/*
+ * GHASH_CHUNK is "stride parameter" missioned to mitigate cache trashing
+ * effect. In other words idea is to hash data while it's still in L1 cache
+ * after encryption pass...
+ */
+#  define GHASH_CHUNK       (3*1024)
+# endif
+
+#else                           /* TABLE_BITS */
+
+static void gcm_gmult_1bit(u64 Xi[2], const u64 H[2])
+{
+    u128 V, Z = { 0, 0 };
+    long X;
+    int i, j;
+    const long *xi = (const long *)Xi;
+    const union {
+        long one;
+        char little;
+    } is_endian = { 1 };
+
+    V.hi = H[0];                /* H is in host byte order, no byte swapping */
+    V.lo = H[1];
+
+    for (j = 0; j < 16 / sizeof(long); ++j) {
+        if (is_endian.little) {
+            if (sizeof(long) == 8) {
+# ifdef BSWAP8
+                X = (long)(BSWAP8(xi[j]));
+# else
+                const u8 *p = (const u8 *)(xi + j);
+                X = (long)((u64)GETU32(p) << 32 | GETU32(p + 4));
+# endif
+            } else {
+                const u8 *p = (const u8 *)(xi + j);
+                X = (long)GETU32(p);
+            }
+        } else
+            X = xi[j];
+
+        for (i = 0; i < 8 * sizeof(long); ++i, X <<= 1) {
+            u64 M = (u64)(X >> (8 * sizeof(long) - 1));
+            Z.hi ^= V.hi & M;
+            Z.lo ^= V.lo & M;
+
+            REDUCE1BIT(V);
+        }
+    }
+
+    if (is_endian.little) {
+# ifdef BSWAP8
+        Xi[0] = BSWAP8(Z.hi);
+        Xi[1] = BSWAP8(Z.lo);
+# else
+        u8 *p = (u8 *)Xi;
+        u32 v;
+        v = (u32)(Z.hi >> 32);
+        PUTU32(p, v);
+        v = (u32)(Z.hi);
+        PUTU32(p + 4, v);
+        v = (u32)(Z.lo >> 32);
+        PUTU32(p + 8, v);
+        v = (u32)(Z.lo);
+        PUTU32(p + 12, v);
+# endif
+    } else {
+        Xi[0] = Z.hi;
+        Xi[1] = Z.lo;
+    }
+}
+
+# define GCM_MUL(ctx,Xi)   gcm_gmult_1bit(ctx->Xi.u,ctx->H.u)
+
+#endif
+
+#if     TABLE_BITS==4 && (defined(GHASH_ASM) || defined(OPENSSL_CPUID_OBJ))
+# if    !defined(I386_ONLY) && \
+        (defined(__i386)        || defined(__i386__)    || \
+         defined(__x86_64)      || defined(__x86_64__)  || \
+         defined(_M_IX86)       || defined(_M_AMD64)    || defined(_M_X64))
+#  define GHASH_ASM_X86_OR_64
+#  define GCM_FUNCREF_4BIT
+extern unsigned int OPENSSL_ia32cap_P[];
+
+void gcm_init_clmul(u128 Htable[16], const u64 Xi[2]);
+void gcm_gmult_clmul(u64 Xi[2], const u128 Htable[16]);
+void gcm_ghash_clmul(u64 Xi[2], const u128 Htable[16], const u8 *inp,
+                     size_t len);
+
+#  if defined(__i386) || defined(__i386__) || defined(_M_IX86)
+#   define gcm_init_avx   gcm_init_clmul
+#   define gcm_gmult_avx  gcm_gmult_clmul
+#   define gcm_ghash_avx  gcm_ghash_clmul
+#  else
+void gcm_init_avx(u128 Htable[16], const u64 Xi[2]);
+void gcm_gmult_avx(u64 Xi[2], const u128 Htable[16]);
+void gcm_ghash_avx(u64 Xi[2], const u128 Htable[16], const u8 *inp,
+                   size_t len);
+#  endif
+
+#  if   defined(__i386) || defined(__i386__) || defined(_M_IX86)
+#   define GHASH_ASM_X86
+void gcm_gmult_4bit_mmx(u64 Xi[2], const u128 Htable[16]);
+void gcm_ghash_4bit_mmx(u64 Xi[2], const u128 Htable[16], const u8 *inp,
+                        size_t len);
+
+void gcm_gmult_4bit_x86(u64 Xi[2], const u128 Htable[16]);
+void gcm_ghash_4bit_x86(u64 Xi[2], const u128 Htable[16], const u8 *inp,
+                        size_t len);
+#  endif
+# elif defined(__arm__) || defined(__arm) || defined(__aarch64__)
+#  include "arm_arch.h"
+#  if __ARM_MAX_ARCH__>=7
+#   define GHASH_ASM_ARM
+#   define GCM_FUNCREF_4BIT
+#   define PMULL_CAPABLE        (OPENSSL_armcap_P & ARMV8_PMULL)
+#   if defined(__arm__) || defined(__arm)
+#    define NEON_CAPABLE        (OPENSSL_armcap_P & ARMV7_NEON)
+#   endif
+void gcm_init_neon(u128 Htable[16], const u64 Xi[2]);
+void gcm_gmult_neon(u64 Xi[2], const u128 Htable[16]);
+void gcm_ghash_neon(u64 Xi[2], const u128 Htable[16], const u8 *inp,
+                    size_t len);
+void gcm_init_v8(u128 Htable[16], const u64 Xi[2]);
+void gcm_gmult_v8(u64 Xi[2], const u128 Htable[16]);
+void gcm_ghash_v8(u64 Xi[2], const u128 Htable[16], const u8 *inp,
+                  size_t len);
+#  endif
+# elif defined(__sparc__) || defined(__sparc)
+#  include "sparc_arch.h"
+#  define GHASH_ASM_SPARC
+#  define GCM_FUNCREF_4BIT
+extern unsigned int OPENSSL_sparcv9cap_P[];
+void gcm_init_vis3(u128 Htable[16], const u64 Xi[2]);
+void gcm_gmult_vis3(u64 Xi[2], const u128 Htable[16]);
+void gcm_ghash_vis3(u64 Xi[2], const u128 Htable[16], const u8 *inp,
+                    size_t len);
+# elif defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC))
+#  include "ppc_arch.h"
+#  define GHASH_ASM_PPC
+#  define GCM_FUNCREF_4BIT
+void gcm_init_p8(u128 Htable[16], const u64 Xi[2]);
+void gcm_gmult_p8(u64 Xi[2], const u128 Htable[16]);
+void gcm_ghash_p8(u64 Xi[2], const u128 Htable[16], const u8 *inp,
+                  size_t len);
+# endif
+#endif
+
+#ifdef GCM_FUNCREF_4BIT
+# undef  GCM_MUL
+# define GCM_MUL(ctx,Xi)        (*gcm_gmult_p)(ctx->Xi.u,ctx->Htable)
+# ifdef GHASH
+#  undef  GHASH
+#  define GHASH(ctx,in,len)     (*gcm_ghash_p)(ctx->Xi.u,ctx->Htable,in,len)
+# endif
+#endif
+
+void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block)
+{
+    const union {
+        long one;
+        char little;
+    } is_endian = { 1 };
+
+    memset(ctx, 0, sizeof(*ctx));
+    ctx->block = block;
+    ctx->key = key;
+
+    (*block) (ctx->H.c, ctx->H.c, key);
+
+    if (is_endian.little) {
+        /* H is stored in host byte order */
+#ifdef BSWAP8
+        ctx->H.u[0] = BSWAP8(ctx->H.u[0]);
+        ctx->H.u[1] = BSWAP8(ctx->H.u[1]);
+#else
+        u8 *p = ctx->H.c;
+        u64 hi, lo;
+        hi = (u64)GETU32(p) << 32 | GETU32(p + 4);
+        lo = (u64)GETU32(p + 8) << 32 | GETU32(p + 12);
+        ctx->H.u[0] = hi;
+        ctx->H.u[1] = lo;
+#endif
+    }
+#if     TABLE_BITS==8
+    gcm_init_8bit(ctx->Htable, ctx->H.u);
+#elif   TABLE_BITS==4
+# if    defined(GHASH)
+#  define CTX__GHASH(f) (ctx->ghash = (f))
+# else
+#  define CTX__GHASH(f) (ctx->ghash = NULL)
+# endif
+# if    defined(GHASH_ASM_X86_OR_64)
+#  if   !defined(GHASH_ASM_X86) || defined(OPENSSL_IA32_SSE2)
+    if (OPENSSL_ia32cap_P[0] & (1 << 24) && /* check FXSR bit */
+        OPENSSL_ia32cap_P[1] & (1 << 1)) { /* check PCLMULQDQ bit */
+        if (((OPENSSL_ia32cap_P[1] >> 22) & 0x41) == 0x41) { /* AVX+MOVBE */
+            gcm_init_avx(ctx->Htable, ctx->H.u);
+            ctx->gmult = gcm_gmult_avx;
+            CTX__GHASH(gcm_ghash_avx);
+        } else {
+            gcm_init_clmul(ctx->Htable, ctx->H.u);
+            ctx->gmult = gcm_gmult_clmul;
+            CTX__GHASH(gcm_ghash_clmul);
+        }
+        return;
+    }
+#  endif
+    gcm_init_4bit(ctx->Htable, ctx->H.u);
+#  if   defined(GHASH_ASM_X86)  /* x86 only */
+#   if  defined(OPENSSL_IA32_SSE2)
+    if (OPENSSL_ia32cap_P[0] & (1 << 25)) { /* check SSE bit */
+#   else
+    if (OPENSSL_ia32cap_P[0] & (1 << 23)) { /* check MMX bit */
+#   endif
+        ctx->gmult = gcm_gmult_4bit_mmx;
+        CTX__GHASH(gcm_ghash_4bit_mmx);
+    } else {
+        ctx->gmult = gcm_gmult_4bit_x86;
+        CTX__GHASH(gcm_ghash_4bit_x86);
+    }
+#  else
+    ctx->gmult = gcm_gmult_4bit;
+    CTX__GHASH(gcm_ghash_4bit);
+#  endif
+# elif  defined(GHASH_ASM_ARM)
+#  ifdef PMULL_CAPABLE
+    if (PMULL_CAPABLE) {
+        gcm_init_v8(ctx->Htable, ctx->H.u);
+        ctx->gmult = gcm_gmult_v8;
+        CTX__GHASH(gcm_ghash_v8);
+    } else
+#  endif
+#  ifdef NEON_CAPABLE
+    if (NEON_CAPABLE) {
+        gcm_init_neon(ctx->Htable, ctx->H.u);
+        ctx->gmult = gcm_gmult_neon;
+        CTX__GHASH(gcm_ghash_neon);
+    } else
+#  endif
+    {
+        gcm_init_4bit(ctx->Htable, ctx->H.u);
+        ctx->gmult = gcm_gmult_4bit;
+        CTX__GHASH(gcm_ghash_4bit);
+    }
+# elif  defined(GHASH_ASM_SPARC)
+    if (OPENSSL_sparcv9cap_P[0] & SPARCV9_VIS3) {
+        gcm_init_vis3(ctx->Htable, ctx->H.u);
+        ctx->gmult = gcm_gmult_vis3;
+        CTX__GHASH(gcm_ghash_vis3);
+    } else {
+        gcm_init_4bit(ctx->Htable, ctx->H.u);
+        ctx->gmult = gcm_gmult_4bit;
+        CTX__GHASH(gcm_ghash_4bit);
+    }
+# elif  defined(GHASH_ASM_PPC)
+    if (OPENSSL_ppccap_P & PPC_CRYPTO207) {
+        gcm_init_p8(ctx->Htable, ctx->H.u);
+        ctx->gmult = gcm_gmult_p8;
+        CTX__GHASH(gcm_ghash_p8);
+    } else {
+        gcm_init_4bit(ctx->Htable, ctx->H.u);
+        ctx->gmult = gcm_gmult_4bit;
+        CTX__GHASH(gcm_ghash_4bit);
+    }
+# else
+    gcm_init_4bit(ctx->Htable, ctx->H.u);
+# endif
+# undef CTX__GHASH
+#endif
+}
+
+void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv,
+                         size_t len)
+{
+    const union {
+        long one;
+        char little;
+    } is_endian = { 1 };
+    unsigned int ctr;
+#ifdef GCM_FUNCREF_4BIT
+    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
+#endif
+
+    ctx->Yi.u[0] = 0;
+    ctx->Yi.u[1] = 0;
+    ctx->Xi.u[0] = 0;
+    ctx->Xi.u[1] = 0;
+    ctx->len.u[0] = 0;          /* AAD length */
+    ctx->len.u[1] = 0;          /* message length */
+    ctx->ares = 0;
+    ctx->mres = 0;
+
+    if (len == 12) {
+        memcpy(ctx->Yi.c, iv, 12);
+        ctx->Yi.c[15] = 1;
+        ctr = 1;
+    } else {
+        size_t i;
+        u64 len0 = len;
+
+        while (len >= 16) {
+            for (i = 0; i < 16; ++i)
+                ctx->Yi.c[i] ^= iv[i];
+            GCM_MUL(ctx, Yi);
+            iv += 16;
+            len -= 16;
+        }
+        if (len) {
+            for (i = 0; i < len; ++i)
+                ctx->Yi.c[i] ^= iv[i];
+            GCM_MUL(ctx, Yi);
+        }
+        len0 <<= 3;
+        if (is_endian.little) {
+#ifdef BSWAP8
+            ctx->Yi.u[1] ^= BSWAP8(len0);
+#else
+            ctx->Yi.c[8] ^= (u8)(len0 >> 56);
+            ctx->Yi.c[9] ^= (u8)(len0 >> 48);
+            ctx->Yi.c[10] ^= (u8)(len0 >> 40);
+            ctx->Yi.c[11] ^= (u8)(len0 >> 32);
+            ctx->Yi.c[12] ^= (u8)(len0 >> 24);
+            ctx->Yi.c[13] ^= (u8)(len0 >> 16);
+            ctx->Yi.c[14] ^= (u8)(len0 >> 8);
+            ctx->Yi.c[15] ^= (u8)(len0);
+#endif
+        } else
+            ctx->Yi.u[1] ^= len0;
+
+        GCM_MUL(ctx, Yi);
+
+        if (is_endian.little)
+#ifdef BSWAP4
+            ctr = BSWAP4(ctx->Yi.d[3]);
+#else
+            ctr = GETU32(ctx->Yi.c + 12);
+#endif
+        else
+            ctr = ctx->Yi.d[3];
+    }
+
+    (*ctx->block) (ctx->Yi.c, ctx->EK0.c, ctx->key);
+    ++ctr;
+    if (is_endian.little)
+#ifdef BSWAP4
+        ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+        PUTU32(ctx->Yi.c + 12, ctr);
+#endif
+    else
+        ctx->Yi.d[3] = ctr;
+}
+
+int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad,
+                      size_t len)
+{
+    size_t i;
+    unsigned int n;
+    u64 alen = ctx->len.u[0];
+#ifdef GCM_FUNCREF_4BIT
+    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
+# ifdef GHASH
+    void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
+                         const u8 *inp, size_t len) = ctx->ghash;
+# endif
+#endif
+
+    if (ctx->len.u[1])
+        return -2;
+
+    alen += len;
+    if (alen > (U64(1) << 61) || (sizeof(len) == 8 && alen < len))
+        return -1;
+    ctx->len.u[0] = alen;
+
+    n = ctx->ares;
+    if (n) {
+        while (n && len) {
+            ctx->Xi.c[n] ^= *(aad++);
+            --len;
+            n = (n + 1) % 16;
+        }
+        if (n == 0)
+            GCM_MUL(ctx, Xi);
+        else {
+            ctx->ares = n;
+            return 0;
+        }
+    }
+#ifdef GHASH
+    if ((i = (len & (size_t)-16))) {
+        GHASH(ctx, aad, i);
+        aad += i;
+        len -= i;
+    }
+#else
+    while (len >= 16) {
+        for (i = 0; i < 16; ++i)
+            ctx->Xi.c[i] ^= aad[i];
+        GCM_MUL(ctx, Xi);
+        aad += 16;
+        len -= 16;
+    }
+#endif
+    if (len) {
+        n = (unsigned int)len;
+        for (i = 0; i < len; ++i)
+            ctx->Xi.c[i] ^= aad[i];
+    }
+
+    ctx->ares = n;
+    return 0;
+}
+
+int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
+                          const unsigned char *in, unsigned char *out,
+                          size_t len)
+{
+    const union {
+        long one;
+        char little;
+    } is_endian = { 1 };
+    unsigned int n, ctr;
+    size_t i;
+    u64 mlen = ctx->len.u[1];
+    block128_f block = ctx->block;
+    void *key = ctx->key;
+#ifdef GCM_FUNCREF_4BIT
+    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
+# if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)
+    void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
+                         const u8 *inp, size_t len) = ctx->ghash;
+# endif
+#endif
+
+    mlen += len;
+    if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
+        return -1;
+    ctx->len.u[1] = mlen;
+
+    if (ctx->ares) {
+        /* First call to encrypt finalizes GHASH(AAD) */
+        GCM_MUL(ctx, Xi);
+        ctx->ares = 0;
+    }
+
+    if (is_endian.little)
+#ifdef BSWAP4
+        ctr = BSWAP4(ctx->Yi.d[3]);
+#else
+        ctr = GETU32(ctx->Yi.c + 12);
+#endif
+    else
+        ctr = ctx->Yi.d[3];
+
+    n = ctx->mres;
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+    if (16 % sizeof(size_t) == 0) { /* always true actually */
+        do {
+            if (n) {
+                while (n && len) {
+                    ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n];
+                    --len;
+                    n = (n + 1) % 16;
+                }
+                if (n == 0)
+                    GCM_MUL(ctx, Xi);
+                else {
+                    ctx->mres = n;
+                    return 0;
+                }
+            }
+# if defined(STRICT_ALIGNMENT)
+            if (((size_t)in | (size_t)out) % sizeof(size_t) != 0)
+                break;
+# endif
+# if defined(GHASH)
+#  if defined(GHASH_CHUNK)
+            while (len >= GHASH_CHUNK) {
+                size_t j = GHASH_CHUNK;
+
+                while (j) {
+                    size_t *out_t = (size_t *)out;
+                    const size_t *in_t = (const size_t *)in;
+
+                    (*block) (ctx->Yi.c, ctx->EKi.c, key);
+                    ++ctr;
+                    if (is_endian.little)
+#   ifdef BSWAP4
+                        ctx->Yi.d[3] = BSWAP4(ctr);
+#   else
+                        PUTU32(ctx->Yi.c + 12, ctr);
+#   endif
+                    else
+                        ctx->Yi.d[3] = ctr;
+                    for (i = 0; i < 16 / sizeof(size_t); ++i)
+                        out_t[i] = in_t[i] ^ ctx->EKi.t[i];
+                    out += 16;
+                    in += 16;
+                    j -= 16;
+                }
+                GHASH(ctx, out - GHASH_CHUNK, GHASH_CHUNK);
+                len -= GHASH_CHUNK;
+            }
+#  endif
+            if ((i = (len & (size_t)-16))) {
+                size_t j = i;
+
+                while (len >= 16) {
+                    size_t *out_t = (size_t *)out;
+                    const size_t *in_t = (const size_t *)in;
+
+                    (*block) (ctx->Yi.c, ctx->EKi.c, key);
+                    ++ctr;
+                    if (is_endian.little)
+#  ifdef BSWAP4
+                        ctx->Yi.d[3] = BSWAP4(ctr);
+#  else
+                        PUTU32(ctx->Yi.c + 12, ctr);
+#  endif
+                    else
+                        ctx->Yi.d[3] = ctr;
+                    for (i = 0; i < 16 / sizeof(size_t); ++i)
+                        out_t[i] = in_t[i] ^ ctx->EKi.t[i];
+                    out += 16;
+                    in += 16;
+                    len -= 16;
+                }
+                GHASH(ctx, out - j, j);
+            }
+# else
+            while (len >= 16) {
+                size_t *out_t = (size_t *)out;
+                const size_t *in_t = (const size_t *)in;
+
+                (*block) (ctx->Yi.c, ctx->EKi.c, key);
+                ++ctr;
+                if (is_endian.little)
+#  ifdef BSWAP4
+                    ctx->Yi.d[3] = BSWAP4(ctr);
+#  else
+                    PUTU32(ctx->Yi.c + 12, ctr);
+#  endif
+                else
+                    ctx->Yi.d[3] = ctr;
+                for (i = 0; i < 16 / sizeof(size_t); ++i)
+                    ctx->Xi.t[i] ^= out_t[i] = in_t[i] ^ ctx->EKi.t[i];
+                GCM_MUL(ctx, Xi);
+                out += 16;
+                in += 16;
+                len -= 16;
+            }
+# endif
+            if (len) {
+                (*block) (ctx->Yi.c, ctx->EKi.c, key);
+                ++ctr;
+                if (is_endian.little)
+# ifdef BSWAP4
+                    ctx->Yi.d[3] = BSWAP4(ctr);
+# else
+                    PUTU32(ctx->Yi.c + 12, ctr);
+# endif
+                else
+                    ctx->Yi.d[3] = ctr;
+                while (len--) {
+                    ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n];
+                    ++n;
+                }
+            }
+
+            ctx->mres = n;
+            return 0;
+        } while (0);
+    }
+#endif
+    for (i = 0; i < len; ++i) {
+        if (n == 0) {
+            (*block) (ctx->Yi.c, ctx->EKi.c, key);
+            ++ctr;
+            if (is_endian.little)
+#ifdef BSWAP4
+                ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+                PUTU32(ctx->Yi.c + 12, ctr);
+#endif
+            else
+                ctx->Yi.d[3] = ctr;
+        }
+        ctx->Xi.c[n] ^= out[i] = in[i] ^ ctx->EKi.c[n];
+        n = (n + 1) % 16;
+        if (n == 0)
+            GCM_MUL(ctx, Xi);
+    }
+
+    ctx->mres = n;
+    return 0;
+}
+
+int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
+                          const unsigned char *in, unsigned char *out,
+                          size_t len)
+{
+    const union {
+        long one;
+        char little;
+    } is_endian = { 1 };
+    unsigned int n, ctr;
+    size_t i;
+    u64 mlen = ctx->len.u[1];
+    block128_f block = ctx->block;
+    void *key = ctx->key;
+#ifdef GCM_FUNCREF_4BIT
+    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
+# if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT)
+    void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
+                         const u8 *inp, size_t len) = ctx->ghash;
+# endif
+#endif
+
+    mlen += len;
+    if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
+        return -1;
+    ctx->len.u[1] = mlen;
+
+    if (ctx->ares) {
+        /* First call to decrypt finalizes GHASH(AAD) */
+        GCM_MUL(ctx, Xi);
+        ctx->ares = 0;
+    }
+
+    if (is_endian.little)
+#ifdef BSWAP4
+        ctr = BSWAP4(ctx->Yi.d[3]);
+#else
+        ctr = GETU32(ctx->Yi.c + 12);
+#endif
+    else
+        ctr = ctx->Yi.d[3];
+
+    n = ctx->mres;
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+    if (16 % sizeof(size_t) == 0) { /* always true actually */
+        do {
+            if (n) {
+                while (n && len) {
+                    u8 c = *(in++);
+                    *(out++) = c ^ ctx->EKi.c[n];
+                    ctx->Xi.c[n] ^= c;
+                    --len;
+                    n = (n + 1) % 16;
+                }
+                if (n == 0)
+                    GCM_MUL(ctx, Xi);
+                else {
+                    ctx->mres = n;
+                    return 0;
+                }
+            }
+# if defined(STRICT_ALIGNMENT)
+            if (((size_t)in | (size_t)out) % sizeof(size_t) != 0)
+                break;
+# endif
+# if defined(GHASH)
+#  if defined(GHASH_CHUNK)
+            while (len >= GHASH_CHUNK) {
+                size_t j = GHASH_CHUNK;
+
+                GHASH(ctx, in, GHASH_CHUNK);
+                while (j) {
+                    size_t *out_t = (size_t *)out;
+                    const size_t *in_t = (const size_t *)in;
+
+                    (*block) (ctx->Yi.c, ctx->EKi.c, key);
+                    ++ctr;
+                    if (is_endian.little)
+#   ifdef BSWAP4
+                        ctx->Yi.d[3] = BSWAP4(ctr);
+#   else
+                        PUTU32(ctx->Yi.c + 12, ctr);
+#   endif
+                    else
+                        ctx->Yi.d[3] = ctr;
+                    for (i = 0; i < 16 / sizeof(size_t); ++i)
+                        out_t[i] = in_t[i] ^ ctx->EKi.t[i];
+                    out += 16;
+                    in += 16;
+                    j -= 16;
+                }
+                len -= GHASH_CHUNK;
+            }
+#  endif
+            if ((i = (len & (size_t)-16))) {
+                GHASH(ctx, in, i);
+                while (len >= 16) {
+                    size_t *out_t = (size_t *)out;
+                    const size_t *in_t = (const size_t *)in;
+
+                    (*block) (ctx->Yi.c, ctx->EKi.c, key);
+                    ++ctr;
+                    if (is_endian.little)
+#  ifdef BSWAP4
+                        ctx->Yi.d[3] = BSWAP4(ctr);
+#  else
+                        PUTU32(ctx->Yi.c + 12, ctr);
+#  endif
+                    else
+                        ctx->Yi.d[3] = ctr;
+                    for (i = 0; i < 16 / sizeof(size_t); ++i)
+                        out_t[i] = in_t[i] ^ ctx->EKi.t[i];
+                    out += 16;
+                    in += 16;
+                    len -= 16;
+                }
+            }
+# else
+            while (len >= 16) {
+                size_t *out_t = (size_t *)out;
+                const size_t *in_t = (const size_t *)in;
+
+                (*block) (ctx->Yi.c, ctx->EKi.c, key);
+                ++ctr;
+                if (is_endian.little)
+#  ifdef BSWAP4
+                    ctx->Yi.d[3] = BSWAP4(ctr);
+#  else
+                    PUTU32(ctx->Yi.c + 12, ctr);
+#  endif
+                else
+                    ctx->Yi.d[3] = ctr;
+                for (i = 0; i < 16 / sizeof(size_t); ++i) {
+                    size_t c = in[i];
+                    out[i] = c ^ ctx->EKi.t[i];
+                    ctx->Xi.t[i] ^= c;
+                }
+                GCM_MUL(ctx, Xi);
+                out += 16;
+                in += 16;
+                len -= 16;
+            }
+# endif
+            if (len) {
+                (*block) (ctx->Yi.c, ctx->EKi.c, key);
+                ++ctr;
+                if (is_endian.little)
+# ifdef BSWAP4
+                    ctx->Yi.d[3] = BSWAP4(ctr);
+# else
+                    PUTU32(ctx->Yi.c + 12, ctr);
+# endif
+                else
+                    ctx->Yi.d[3] = ctr;
+                while (len--) {
+                    u8 c = in[n];
+                    ctx->Xi.c[n] ^= c;
+                    out[n] = c ^ ctx->EKi.c[n];
+                    ++n;
+                }
+            }
+
+            ctx->mres = n;
+            return 0;
+        } while (0);
+    }
+#endif
+    for (i = 0; i < len; ++i) {
+        u8 c;
+        if (n == 0) {
+            (*block) (ctx->Yi.c, ctx->EKi.c, key);
+            ++ctr;
+            if (is_endian.little)
+#ifdef BSWAP4
+                ctx->Yi.d[3] = BSWAP4(ctr);
+#else
+                PUTU32(ctx->Yi.c + 12, ctr);
+#endif
+            else
+                ctx->Yi.d[3] = ctr;
+        }
+        c = in[i];
+        out[i] = c ^ ctx->EKi.c[n];
+        ctx->Xi.c[n] ^= c;
+        n = (n + 1) % 16;
+        if (n == 0)
+            GCM_MUL(ctx, Xi);
+    }
+
+    ctx->mres = n;
+    return 0;
+}
+
+int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
+                                const unsigned char *in, unsigned char *out,
+                                size_t len, ctr128_f stream)
+{
+#if defined(OPENSSL_SMALL_FOOTPRINT)
+    return CRYPTO_gcm128_encrypt(ctx, in, out, len);
+#else
+    const union {
+        long one;
+        char little;
+    } is_endian = { 1 };
+    unsigned int n, ctr;
+    size_t i;
+    u64 mlen = ctx->len.u[1];
+    void *key = ctx->key;
+# ifdef GCM_FUNCREF_4BIT
+    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
+#  ifdef GHASH
+    void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
+                         const u8 *inp, size_t len) = ctx->ghash;
+#  endif
+# endif
+
+    mlen += len;
+    if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
+        return -1;
+    ctx->len.u[1] = mlen;
+
+    if (ctx->ares) {
+        /* First call to encrypt finalizes GHASH(AAD) */
+        GCM_MUL(ctx, Xi);
+        ctx->ares = 0;
+    }
+
+    if (is_endian.little)
+# ifdef BSWAP4
+        ctr = BSWAP4(ctx->Yi.d[3]);
+# else
+        ctr = GETU32(ctx->Yi.c + 12);
+# endif
+    else
+        ctr = ctx->Yi.d[3];
+
+    n = ctx->mres;
+    if (n) {
+        while (n && len) {
+            ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n];
+            --len;
+            n = (n + 1) % 16;
+        }
+        if (n == 0)
+            GCM_MUL(ctx, Xi);
+        else {
+            ctx->mres = n;
+            return 0;
+        }
+    }
+# if defined(GHASH) && defined(GHASH_CHUNK)
+    while (len >= GHASH_CHUNK) {
+        (*stream) (in, out, GHASH_CHUNK / 16, key, ctx->Yi.c);
+        ctr += GHASH_CHUNK / 16;
+        if (is_endian.little)
+#  ifdef BSWAP4
+            ctx->Yi.d[3] = BSWAP4(ctr);
+#  else
+            PUTU32(ctx->Yi.c + 12, ctr);
+#  endif
+        else
+            ctx->Yi.d[3] = ctr;
+        GHASH(ctx, out, GHASH_CHUNK);
+        out += GHASH_CHUNK;
+        in += GHASH_CHUNK;
+        len -= GHASH_CHUNK;
+    }
+# endif
+    if ((i = (len & (size_t)-16))) {
+        size_t j = i / 16;
+
+        (*stream) (in, out, j, key, ctx->Yi.c);
+        ctr += (unsigned int)j;
+        if (is_endian.little)
+# ifdef BSWAP4
+            ctx->Yi.d[3] = BSWAP4(ctr);
+# else
+            PUTU32(ctx->Yi.c + 12, ctr);
+# endif
+        else
+            ctx->Yi.d[3] = ctr;
+        in += i;
+        len -= i;
+# if defined(GHASH)
+        GHASH(ctx, out, i);
+        out += i;
+# else
+        while (j--) {
+            for (i = 0; i < 16; ++i)
+                ctx->Xi.c[i] ^= out[i];
+            GCM_MUL(ctx, Xi);
+            out += 16;
+        }
+# endif
+    }
+    if (len) {
+        (*ctx->block) (ctx->Yi.c, ctx->EKi.c, key);
+        ++ctr;
+        if (is_endian.little)
+# ifdef BSWAP4
+            ctx->Yi.d[3] = BSWAP4(ctr);
+# else
+            PUTU32(ctx->Yi.c + 12, ctr);
+# endif
+        else
+            ctx->Yi.d[3] = ctr;
+        while (len--) {
+            ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n];
+            ++n;
+        }
+    }
+
+    ctx->mres = n;
+    return 0;
+#endif
+}
+
+int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
+                                const unsigned char *in, unsigned char *out,
+                                size_t len, ctr128_f stream)
+{
+#if defined(OPENSSL_SMALL_FOOTPRINT)
+    return CRYPTO_gcm128_decrypt(ctx, in, out, len);
+#else
+    const union {
+        long one;
+        char little;
+    } is_endian = { 1 };
+    unsigned int n, ctr;
+    size_t i;
+    u64 mlen = ctx->len.u[1];
+    void *key = ctx->key;
+# ifdef GCM_FUNCREF_4BIT
+    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
+#  ifdef GHASH
+    void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
+                         const u8 *inp, size_t len) = ctx->ghash;
+#  endif
+# endif
+
+    mlen += len;
+    if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len))
+        return -1;
+    ctx->len.u[1] = mlen;
+
+    if (ctx->ares) {
+        /* First call to decrypt finalizes GHASH(AAD) */
+        GCM_MUL(ctx, Xi);
+        ctx->ares = 0;
+    }
+
+    if (is_endian.little)
+# ifdef BSWAP4
+        ctr = BSWAP4(ctx->Yi.d[3]);
+# else
+        ctr = GETU32(ctx->Yi.c + 12);
+# endif
+    else
+        ctr = ctx->Yi.d[3];
+
+    n = ctx->mres;
+    if (n) {
+        while (n && len) {
+            u8 c = *(in++);
+            *(out++) = c ^ ctx->EKi.c[n];
+            ctx->Xi.c[n] ^= c;
+            --len;
+            n = (n + 1) % 16;
+        }
+        if (n == 0)
+            GCM_MUL(ctx, Xi);
+        else {
+            ctx->mres = n;
+            return 0;
+        }
+    }
+# if defined(GHASH) && defined(GHASH_CHUNK)
+    while (len >= GHASH_CHUNK) {
+        GHASH(ctx, in, GHASH_CHUNK);
+        (*stream) (in, out, GHASH_CHUNK / 16, key, ctx->Yi.c);
+        ctr += GHASH_CHUNK / 16;
+        if (is_endian.little)
+#  ifdef BSWAP4
+            ctx->Yi.d[3] = BSWAP4(ctr);
+#  else
+            PUTU32(ctx->Yi.c + 12, ctr);
+#  endif
+        else
+            ctx->Yi.d[3] = ctr;
+        out += GHASH_CHUNK;
+        in += GHASH_CHUNK;
+        len -= GHASH_CHUNK;
+    }
+# endif
+    if ((i = (len & (size_t)-16))) {
+        size_t j = i / 16;
+
+# if defined(GHASH)
+        GHASH(ctx, in, i);
+# else
+        while (j--) {
+            size_t k;
+            for (k = 0; k < 16; ++k)
+                ctx->Xi.c[k] ^= in[k];
+            GCM_MUL(ctx, Xi);
+            in += 16;
+        }
+        j = i / 16;
+        in -= i;
+# endif
+        (*stream) (in, out, j, key, ctx->Yi.c);
+        ctr += (unsigned int)j;
+        if (is_endian.little)
+# ifdef BSWAP4
+            ctx->Yi.d[3] = BSWAP4(ctr);
+# else
+            PUTU32(ctx->Yi.c + 12, ctr);
+# endif
+        else
+            ctx->Yi.d[3] = ctr;
+        out += i;
+        in += i;
+        len -= i;
+    }
+    if (len) {
+        (*ctx->block) (ctx->Yi.c, ctx->EKi.c, key);
+        ++ctr;
+        if (is_endian.little)
+# ifdef BSWAP4
+            ctx->Yi.d[3] = BSWAP4(ctr);
+# else
+            PUTU32(ctx->Yi.c + 12, ctr);
+# endif
+        else
+            ctx->Yi.d[3] = ctr;
+        while (len--) {
+            u8 c = in[n];
+            ctx->Xi.c[n] ^= c;
+            out[n] = c ^ ctx->EKi.c[n];
+            ++n;
+        }
+    }
+
+    ctx->mres = n;
+    return 0;
+#endif
+}
+
+int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag,
+                         size_t len)
+{
+    const union {
+        long one;
+        char little;
+    } is_endian = { 1 };
+    u64 alen = ctx->len.u[0] << 3;
+    u64 clen = ctx->len.u[1] << 3;
+#ifdef GCM_FUNCREF_4BIT
+    void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult;
+#endif
+
+    if (ctx->mres || ctx->ares)
+        GCM_MUL(ctx, Xi);
+
+    if (is_endian.little) {
+#ifdef BSWAP8
+        alen = BSWAP8(alen);
+        clen = BSWAP8(clen);
+#else
+        u8 *p = ctx->len.c;
+
+        ctx->len.u[0] = alen;
+        ctx->len.u[1] = clen;
+
+        alen = (u64)GETU32(p) << 32 | GETU32(p + 4);
+        clen = (u64)GETU32(p + 8) << 32 | GETU32(p + 12);
+#endif
+    }
+
+    ctx->Xi.u[0] ^= alen;
+    ctx->Xi.u[1] ^= clen;
+    GCM_MUL(ctx, Xi);
+
+    ctx->Xi.u[0] ^= ctx->EK0.u[0];
+    ctx->Xi.u[1] ^= ctx->EK0.u[1];
+
+    if (tag && len <= sizeof(ctx->Xi))
+        return CRYPTO_memcmp(ctx->Xi.c, tag, len);
+    else
+        return -1;
+}
+
+void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len)
+{
+    CRYPTO_gcm128_finish(ctx, NULL, 0);
+    memcpy(tag, ctx->Xi.c,
+           len <= sizeof(ctx->Xi.c) ? len : sizeof(ctx->Xi.c));
+}
+
+GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block)
+{
+    GCM128_CONTEXT *ret;
+
+    if ((ret = OPENSSL_malloc(sizeof(*ret))) != NULL)
+        CRYPTO_gcm128_init(ret, key, block);
+
+    return ret;
+}
+
+void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx)
+{
+    OPENSSL_clear_free(ctx, sizeof(*ctx));
+}
+
+#if defined(SELFTEST)
+# include <stdio.h>
+# include <openssl/aes.h>
+
+/* Test Case 1 */
+static const u8 K1[16], *P1 = NULL, *A1 = NULL, IV1[12], *C1 = NULL;
+static const u8 T1[] = {
+    0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
+    0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a
+};
+
+/* Test Case 2 */
+# define K2 K1
+# define A2 A1
+# define IV2 IV1
+static const u8 P2[16];
+static const u8 C2[] = {
+    0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
+    0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78
+};
+
+static const u8 T2[] = {
+    0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
+    0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf
+};
+
+/* Test Case 3 */
+# define A3 A2
+static const u8 K3[] = {
+    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08
+};
+
+static const u8 P3[] = {
+    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+    0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55
+};
+
+static const u8 IV3[] = {
+    0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+    0xde, 0xca, 0xf8, 0x88
+};
+
+static const u8 C3[] = {
+    0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
+    0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
+    0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
+    0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
+    0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
+    0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
+    0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
+    0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85
+};
+
+static const u8 T3[] = {
+    0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
+    0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4
+};
+
+/* Test Case 4 */
+# define K4 K3
+# define IV4 IV3
+static const u8 P4[] = {
+    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+    0xba, 0x63, 0x7b, 0x39
+};
+
+static const u8 A4[] = {
+    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+    0xab, 0xad, 0xda, 0xd2
+};
+
+static const u8 C4[] = {
+    0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
+    0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
+    0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
+    0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
+    0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
+    0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
+    0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
+    0x3d, 0x58, 0xe0, 0x91
+};
+
+static const u8 T4[] = {
+    0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
+    0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47
+};
+
+/* Test Case 5 */
+# define K5 K4
+# define P5 P4
+# define A5 A4
+static const u8 IV5[] = {
+    0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad
+};
+
+static const u8 C5[] = {
+    0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
+    0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
+    0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
+    0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
+    0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
+    0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
+    0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
+    0xc2, 0x3f, 0x45, 0x98
+};
+
+static const u8 T5[] = {
+    0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
+    0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb
+};
+
+/* Test Case 6 */
+# define K6 K5
+# define P6 P5
+# define A6 A5
+static const u8 IV6[] = {
+    0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
+    0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
+    0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
+    0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
+    0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
+    0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
+    0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
+    0xa6, 0x37, 0xb3, 0x9b
+};
+
+static const u8 C6[] = {
+    0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
+    0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
+    0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
+    0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
+    0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
+    0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
+    0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
+    0x4c, 0x34, 0xae, 0xe5
+};
+
+static const u8 T6[] = {
+    0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
+    0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50
+};
+
+/* Test Case 7 */
+static const u8 K7[24], *P7 = NULL, *A7 = NULL, IV7[12], *C7 = NULL;
+static const u8 T7[] = {
+    0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b,
+    0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35
+};
+
+/* Test Case 8 */
+# define K8 K7
+# define IV8 IV7
+# define A8 A7
+static const u8 P8[16];
+static const u8 C8[] = {
+    0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41,
+    0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00
+};
+
+static const u8 T8[] = {
+    0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab,
+    0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb
+};
+
+/* Test Case 9 */
+# define A9 A8
+static const u8 K9[] = {
+    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c
+};
+
+static const u8 P9[] = {
+    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+    0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55
+};
+
+static const u8 IV9[] = {
+    0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+    0xde, 0xca, 0xf8, 0x88
+};
+
+static const u8 C9[] = {
+    0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
+    0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
+    0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
+    0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
+    0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
+    0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
+    0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
+    0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56
+};
+
+static const u8 T9[] = {
+    0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf,
+    0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14
+};
+
+/* Test Case 10 */
+# define K10 K9
+# define IV10 IV9
+static const u8 P10[] = {
+    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+    0xba, 0x63, 0x7b, 0x39
+};
+
+static const u8 A10[] = {
+    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+    0xab, 0xad, 0xda, 0xd2
+};
+
+static const u8 C10[] = {
+    0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41,
+    0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57,
+    0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84,
+    0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c,
+    0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25,
+    0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47,
+    0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9,
+    0xcc, 0xda, 0x27, 0x10
+};
+
+static const u8 T10[] = {
+    0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f,
+    0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c
+};
+
+/* Test Case 11 */
+# define K11 K10
+# define P11 P10
+# define A11 A10
+static const u8 IV11[] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad };
+
+static const u8 C11[] = {
+    0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54,
+    0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8,
+    0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f,
+    0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57,
+    0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75,
+    0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9,
+    0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f,
+    0xa0, 0xf0, 0x62, 0xf7
+};
+
+static const u8 T11[] = {
+    0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24,
+    0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8
+};
+
+/* Test Case 12 */
+# define K12 K11
+# define P12 P11
+# define A12 A11
+static const u8 IV12[] = {
+    0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
+    0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
+    0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
+    0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
+    0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
+    0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
+    0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
+    0xa6, 0x37, 0xb3, 0x9b
+};
+
+static const u8 C12[] = {
+    0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c,
+    0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff,
+    0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef,
+    0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45,
+    0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9,
+    0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3,
+    0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7,
+    0xe9, 0xb7, 0x37, 0x3b
+};
+
+static const u8 T12[] = {
+    0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb,
+    0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9
+};
+
+/* Test Case 13 */
+static const u8 K13[32], *P13 = NULL, *A13 = NULL, IV13[12], *C13 = NULL;
+static const u8 T13[] = {
+    0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9,
+    0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b
+};
+
+/* Test Case 14 */
+# define K14 K13
+# define A14 A13
+static const u8 P14[16], IV14[12];
+static const u8 C14[] = {
+    0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e,
+    0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18
+};
+
+static const u8 T14[] = {
+    0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0,
+    0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19
+};
+
+/* Test Case 15 */
+# define A15 A14
+static const u8 K15[] = {
+    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
+    0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+    0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08
+};
+
+static const u8 P15[] = {
+    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+    0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55
+};
+
+static const u8 IV15[] = {
+    0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+    0xde, 0xca, 0xf8, 0x88
+};
+
+static const u8 C15[] = {
+    0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
+    0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
+    0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
+    0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
+    0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
+    0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
+    0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
+    0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad
+};
+
+static const u8 T15[] = {
+    0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd,
+    0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c
+};
+
+/* Test Case 16 */
+# define K16 K15
+# define IV16 IV15
+static const u8 P16[] = {
+    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+    0xba, 0x63, 0x7b, 0x39
+};
+
+static const u8 A16[] = {
+    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+    0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
+    0xab, 0xad, 0xda, 0xd2
+};
+
+static const u8 C16[] = {
+    0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
+    0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
+    0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
+    0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
+    0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
+    0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
+    0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
+    0xbc, 0xc9, 0xf6, 0x62
+};
+
+static const u8 T16[] = {
+    0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68,
+    0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b
+};
+
+/* Test Case 17 */
+# define K17 K16
+# define P17 P16
+# define A17 A16
+static const u8 IV17[] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad };
+
+static const u8 C17[] = {
+    0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32,
+    0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb,
+    0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa,
+    0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0,
+    0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0,
+    0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78,
+    0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99,
+    0xf4, 0x7c, 0x9b, 0x1f
+};
+
+static const u8 T17[] = {
+    0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4,
+    0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2
+};
+
+/* Test Case 18 */
+# define K18 K17
+# define P18 P17
+# define A18 A17
+static const u8 IV18[] = {
+    0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
+    0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
+    0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
+    0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
+    0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
+    0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
+    0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
+    0xa6, 0x37, 0xb3, 0x9b
+};
+
+static const u8 C18[] = {
+    0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1,
+    0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20,
+    0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19,
+    0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4,
+    0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45,
+    0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde,
+    0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e,
+    0x44, 0xae, 0x7e, 0x3f
+};
+
+static const u8 T18[] = {
+    0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0,
+    0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a
+};
+
+/* Test Case 19 */
+# define K19 K1
+# define P19 P1
+# define IV19 IV1
+# define C19 C1
+static const u8 A19[] = {
+    0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
+    0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
+    0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
+    0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
+    0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
+    0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
+    0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
+    0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55,
+    0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07,
+    0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d,
+    0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9,
+    0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa,
+    0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d,
+    0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38,
+    0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a,
+    0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad
+};
+
+static const u8 T19[] = {
+    0x5f, 0xea, 0x79, 0x3a, 0x2d, 0x6f, 0x97, 0x4d,
+    0x37, 0xe6, 0x8e, 0x0c, 0xb8, 0xff, 0x94, 0x92
+};
+
+/* Test Case 20 */
+# define K20 K1
+# define A20 A1
+/* this results in 0xff in counter LSB */
+static const u8 IV20[64] = { 0xff, 0xff, 0xff, 0xff };
+
+static const u8 P20[288];
+static const u8 C20[] = {
+    0x56, 0xb3, 0x37, 0x3c, 0xa9, 0xef, 0x6e, 0x4a,
+    0x2b, 0x64, 0xfe, 0x1e, 0x9a, 0x17, 0xb6, 0x14,
+    0x25, 0xf1, 0x0d, 0x47, 0xa7, 0x5a, 0x5f, 0xce,
+    0x13, 0xef, 0xc6, 0xbc, 0x78, 0x4a, 0xf2, 0x4f,
+    0x41, 0x41, 0xbd, 0xd4, 0x8c, 0xf7, 0xc7, 0x70,
+    0x88, 0x7a, 0xfd, 0x57, 0x3c, 0xca, 0x54, 0x18,
+    0xa9, 0xae, 0xff, 0xcd, 0x7c, 0x5c, 0xed, 0xdf,
+    0xc6, 0xa7, 0x83, 0x97, 0xb9, 0xa8, 0x5b, 0x49,
+    0x9d, 0xa5, 0x58, 0x25, 0x72, 0x67, 0xca, 0xab,
+    0x2a, 0xd0, 0xb2, 0x3c, 0xa4, 0x76, 0xa5, 0x3c,
+    0xb1, 0x7f, 0xb4, 0x1c, 0x4b, 0x8b, 0x47, 0x5c,
+    0xb4, 0xf3, 0xf7, 0x16, 0x50, 0x94, 0xc2, 0x29,
+    0xc9, 0xe8, 0xc4, 0xdc, 0x0a, 0x2a, 0x5f, 0xf1,
+    0x90, 0x3e, 0x50, 0x15, 0x11, 0x22, 0x13, 0x76,
+    0xa1, 0xcd, 0xb8, 0x36, 0x4c, 0x50, 0x61, 0xa2,
+    0x0c, 0xae, 0x74, 0xbc, 0x4a, 0xcd, 0x76, 0xce,
+    0xb0, 0xab, 0xc9, 0xfd, 0x32, 0x17, 0xef, 0x9f,
+    0x8c, 0x90, 0xbe, 0x40, 0x2d, 0xdf, 0x6d, 0x86,
+    0x97, 0xf4, 0xf8, 0x80, 0xdf, 0xf1, 0x5b, 0xfb,
+    0x7a, 0x6b, 0x28, 0x24, 0x1e, 0xc8, 0xfe, 0x18,
+    0x3c, 0x2d, 0x59, 0xe3, 0xf9, 0xdf, 0xff, 0x65,
+    0x3c, 0x71, 0x26, 0xf0, 0xac, 0xb9, 0xe6, 0x42,
+    0x11, 0xf4, 0x2b, 0xae, 0x12, 0xaf, 0x46, 0x2b,
+    0x10, 0x70, 0xbe, 0xf1, 0xab, 0x5e, 0x36, 0x06,
+    0x87, 0x2c, 0xa1, 0x0d, 0xee, 0x15, 0xb3, 0x24,
+    0x9b, 0x1a, 0x1b, 0x95, 0x8f, 0x23, 0x13, 0x4c,
+    0x4b, 0xcc, 0xb7, 0xd0, 0x32, 0x00, 0xbc, 0xe4,
+    0x20, 0xa2, 0xf8, 0xeb, 0x66, 0xdc, 0xf3, 0x64,
+    0x4d, 0x14, 0x23, 0xc1, 0xb5, 0x69, 0x90, 0x03,
+    0xc1, 0x3e, 0xce, 0xf4, 0xbf, 0x38, 0xa3, 0xb6,
+    0x0e, 0xed, 0xc3, 0x40, 0x33, 0xba, 0xc1, 0x90,
+    0x27, 0x83, 0xdc, 0x6d, 0x89, 0xe2, 0xe7, 0x74,
+    0x18, 0x8a, 0x43, 0x9c, 0x7e, 0xbc, 0xc0, 0x67,
+    0x2d, 0xbd, 0xa4, 0xdd, 0xcf, 0xb2, 0x79, 0x46,
+    0x13, 0xb0, 0xbe, 0x41, 0x31, 0x5e, 0xf7, 0x78,
+    0x70, 0x8a, 0x70, 0xee, 0x7d, 0x75, 0x16, 0x5c
+};
+
+static const u8 T20[] = {
+    0x8b, 0x30, 0x7f, 0x6b, 0x33, 0x28, 0x6d, 0x0a,
+    0xb0, 0x26, 0xa9, 0xed, 0x3f, 0xe1, 0xe8, 0x5f
+};
+
+# define TEST_CASE(n)    do {                                    \
+        u8 out[sizeof(P##n)];                                   \
+        AES_set_encrypt_key(K##n,sizeof(K##n)*8,&key);          \
+        CRYPTO_gcm128_init(&ctx,&key,(block128_f)AES_encrypt);  \
+        CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n));          \
+        memset(out,0,sizeof(out));                              \
+        if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n));    \
+        if (P##n) CRYPTO_gcm128_encrypt(&ctx,P##n,out,sizeof(out));     \
+        if (CRYPTO_gcm128_finish(&ctx,T##n,16) ||               \
+            (C##n && memcmp(out,C##n,sizeof(out))))             \
+                ret++, printf ("encrypt test#%d failed.\n",n);  \
+        CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n));          \
+        memset(out,0,sizeof(out));                              \
+        if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n));    \
+        if (C##n) CRYPTO_gcm128_decrypt(&ctx,C##n,out,sizeof(out));     \
+        if (CRYPTO_gcm128_finish(&ctx,T##n,16) ||               \
+            (P##n && memcmp(out,P##n,sizeof(out))))             \
+                ret++, printf ("decrypt test#%d failed.\n",n);  \
+        } while(0)
+
+int main()
+{
+    GCM128_CONTEXT ctx;
+    AES_KEY key;
+    int ret = 0;
+
+    TEST_CASE(1);
+    TEST_CASE(2);
+    TEST_CASE(3);
+    TEST_CASE(4);
+    TEST_CASE(5);
+    TEST_CASE(6);
+    TEST_CASE(7);
+    TEST_CASE(8);
+    TEST_CASE(9);
+    TEST_CASE(10);
+    TEST_CASE(11);
+    TEST_CASE(12);
+    TEST_CASE(13);
+    TEST_CASE(14);
+    TEST_CASE(15);
+    TEST_CASE(16);
+    TEST_CASE(17);
+    TEST_CASE(18);
+    TEST_CASE(19);
+    TEST_CASE(20);
+
+# ifdef OPENSSL_CPUID_OBJ
+    {
+        size_t start, stop, gcm_t, ctr_t, OPENSSL_rdtsc();
+        union {
+            u64 u;
+            u8 c[1024];
+        } buf;
+        int i;
+
+        AES_set_encrypt_key(K1, sizeof(K1) * 8, &key);
+        CRYPTO_gcm128_init(&ctx, &key, (block128_f) AES_encrypt);
+        CRYPTO_gcm128_setiv(&ctx, IV1, sizeof(IV1));
+
+        CRYPTO_gcm128_encrypt(&ctx, buf.c, buf.c, sizeof(buf));
+        start = OPENSSL_rdtsc();
+        CRYPTO_gcm128_encrypt(&ctx, buf.c, buf.c, sizeof(buf));
+        gcm_t = OPENSSL_rdtsc() - start;
+
+        CRYPTO_ctr128_encrypt(buf.c, buf.c, sizeof(buf),
+                              &key, ctx.Yi.c, ctx.EKi.c, &ctx.mres,
+                              (block128_f) AES_encrypt);
+        start = OPENSSL_rdtsc();
+        CRYPTO_ctr128_encrypt(buf.c, buf.c, sizeof(buf),
+                              &key, ctx.Yi.c, ctx.EKi.c, &ctx.mres,
+                              (block128_f) AES_encrypt);
+        ctr_t = OPENSSL_rdtsc() - start;
+
+        printf("%.2f-%.2f=%.2f\n",
+               gcm_t / (double)sizeof(buf),
+               ctr_t / (double)sizeof(buf),
+               (gcm_t - ctr_t) / (double)sizeof(buf));
+#  ifdef GHASH
+        {
+            void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16],
+                                 const u8 *inp, size_t len) = ctx.ghash;
+
+            GHASH((&ctx), buf.c, sizeof(buf));
+            start = OPENSSL_rdtsc();
+            for (i = 0; i < 100; ++i)
+                GHASH((&ctx), buf.c, sizeof(buf));
+            gcm_t = OPENSSL_rdtsc() - start;
+            printf("%.2f\n", gcm_t / (double)sizeof(buf) / (double)i);
+        }
+#  endif
+    }
+# endif
+
+    return ret;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/modes_lcl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/modes_lcl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/modes_lcl.h	(revision 331)
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2010-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 <openssl/modes.h>
+
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
+typedef __int64 i64;
+typedef unsigned __int64 u64;
+# define U64(C) C##UI64
+#elif defined(__arch64__)
+typedef long i64;
+typedef unsigned long u64;
+# define U64(C) C##UL
+#else
+typedef long long i64;
+typedef unsigned long long u64;
+# define U64(C) C##ULL
+#endif
+
+typedef unsigned int u32;
+typedef unsigned char u8;
+
+#define STRICT_ALIGNMENT 1
+#ifndef PEDANTIC
+# if defined(__i386)    || defined(__i386__)    || \
+     defined(__x86_64)  || defined(__x86_64__)  || \
+     defined(_M_IX86)   || defined(_M_AMD64)    || defined(_M_X64) || \
+     defined(__aarch64__)                       || \
+     defined(__s390__)  || defined(__s390x__)
+#  undef STRICT_ALIGNMENT
+# endif
+#endif
+
+#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+# if defined(__GNUC__) && __GNUC__>=2
+#  if defined(__x86_64) || defined(__x86_64__)
+#   define BSWAP8(x) ({ u64 ret_=(x);                   \
+                        asm ("bswapq %0"                \
+                        : "+r"(ret_));   ret_;          })
+#   define BSWAP4(x) ({ u32 ret_=(x);                   \
+                        asm ("bswapl %0"                \
+                        : "+r"(ret_));   ret_;          })
+#  elif (defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)
+#   define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x);   \
+                        asm ("bswapl %0; bswapl %1"     \
+                        : "+r"(hi_),"+r"(lo_));         \
+                        (u64)hi_<<32|lo_;               })
+#   define BSWAP4(x) ({ u32 ret_=(x);                   \
+                        asm ("bswapl %0"                \
+                        : "+r"(ret_));   ret_;          })
+#  elif defined(__aarch64__)
+#   define BSWAP8(x) ({ u64 ret_;                       \
+                        asm ("rev %0,%1"                \
+                        : "=r"(ret_) : "r"(x)); ret_;   })
+#   define BSWAP4(x) ({ u32 ret_;                       \
+                        asm ("rev %w0,%w1"              \
+                        : "=r"(ret_) : "r"(x)); ret_;   })
+#  elif (defined(__arm__) || defined(__arm)) && !defined(STRICT_ALIGNMENT)
+#   define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x);   \
+                        asm ("rev %0,%0; rev %1,%1"     \
+                        : "+r"(hi_),"+r"(lo_));         \
+                        (u64)hi_<<32|lo_;               })
+#   define BSWAP4(x) ({ u32 ret_;                       \
+                        asm ("rev %0,%1"                \
+                        : "=r"(ret_) : "r"((u32)(x)));  \
+                        ret_;                           })
+#  endif
+# elif defined(_MSC_VER)
+#  if _MSC_VER>=1300
+#   pragma intrinsic(_byteswap_uint64,_byteswap_ulong)
+#   define BSWAP8(x)    _byteswap_uint64((u64)(x))
+#   define BSWAP4(x)    _byteswap_ulong((u32)(x))
+#  elif defined(_M_IX86)
+__inline u32 _bswap4(u32 val)
+{
+_asm mov eax, val _asm bswap eax}
+#   define BSWAP4(x)    _bswap4(x)
+#  endif
+# endif
+#endif
+#if defined(BSWAP4) && !defined(STRICT_ALIGNMENT)
+# define GETU32(p)       BSWAP4(*(const u32 *)(p))
+# define PUTU32(p,v)     *(u32 *)(p) = BSWAP4(v)
+#else
+# define GETU32(p)       ((u32)(p)[0]<<24|(u32)(p)[1]<<16|(u32)(p)[2]<<8|(u32)(p)[3])
+# define PUTU32(p,v)     ((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v))
+#endif
+/*- GCM definitions */ typedef struct {
+    u64 hi, lo;
+} u128;
+
+#ifdef  TABLE_BITS
+# undef  TABLE_BITS
+#endif
+/*
+ * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should
+ * never be set to 8 [or 1]. For further information see gcm128.c.
+ */
+#define TABLE_BITS 4
+
+struct gcm128_context {
+    /* Following 6 names follow names in GCM specification */
+    union {
+        u64 u[2];
+        u32 d[4];
+        u8 c[16];
+        size_t t[16 / sizeof(size_t)];
+    } Yi, EKi, EK0, len, Xi, H;
+    /*
+     * Relative position of Xi, H and pre-computed Htable is used in some
+     * assembler modules, i.e. don't change the order!
+     */
+#if TABLE_BITS==8
+    u128 Htable[256];
+#else
+    u128 Htable[16];
+    void (*gmult) (u64 Xi[2], const u128 Htable[16]);
+    void (*ghash) (u64 Xi[2], const u128 Htable[16], const u8 *inp,
+                   size_t len);
+#endif
+    unsigned int mres, ares;
+    block128_f block;
+    void *key;
+};
+
+struct xts128_context {
+    void *key1, *key2;
+    block128_f block1, block2;
+};
+
+struct ccm128_context {
+    union {
+        u64 u[2];
+        u8 c[16];
+    } nonce, cmac;
+    u64 blocks;
+    block128_f block;
+    void *key;
+};
+
+#ifndef OPENSSL_NO_OCB
+
+typedef union {
+    u64 a[2];
+    unsigned char c[16];
+} OCB_BLOCK;
+# define ocb_block16_xor(in1,in2,out) \
+    ( (out)->a[0]=(in1)->a[0]^(in2)->a[0], \
+      (out)->a[1]=(in1)->a[1]^(in2)->a[1] )
+# if STRICT_ALIGNMENT
+#  define ocb_block16_xor_misaligned(in1,in2,out) \
+    ocb_block_xor((in1)->c,(in2)->c,16,(out)->c)
+# else
+#  define ocb_block16_xor_misaligned ocb_block16_xor
+# endif
+
+struct ocb128_context {
+    /* Need both encrypt and decrypt key schedules for decryption */
+    block128_f encrypt;
+    block128_f decrypt;
+    void *keyenc;
+    void *keydec;
+    ocb128_f stream;    /* direction dependent */
+    /* Key dependent variables. Can be reused if key remains the same */
+    size_t l_index;
+    size_t max_l_index;
+    OCB_BLOCK l_star;
+    OCB_BLOCK l_dollar;
+    OCB_BLOCK *l;
+    /* Must be reset for each session */
+    u64 blocks_hashed;
+    u64 blocks_processed;
+    OCB_BLOCK tag;
+    OCB_BLOCK offset_aad;
+    OCB_BLOCK sum;
+    OCB_BLOCK offset;
+    OCB_BLOCK checksum;
+};
+#endif                          /* OPENSSL_NO_OCB */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/ocb128.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/ocb128.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/ocb128.c	(revision 331)
@@ -0,0 +1,568 @@
+/*
+ * Copyright 2014-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 <string.h>
+#include <openssl/crypto.h>
+#include "modes_lcl.h"
+
+#ifndef OPENSSL_NO_OCB
+
+/*
+ * Calculate the number of binary trailing zero's in any given number
+ */
+static u32 ocb_ntz(u64 n)
+{
+    u32 cnt = 0;
+
+    /*
+     * We do a right-to-left simple sequential search. This is surprisingly
+     * efficient as the distribution of trailing zeros is not uniform,
+     * e.g. the number of possible inputs with no trailing zeros is equal to
+     * the number with 1 or more; the number with exactly 1 is equal to the
+     * number with 2 or more, etc. Checking the last two bits covers 75% of
+     * all numbers. Checking the last three covers 87.5%
+     */
+    while (!(n & 1)) {
+        n >>= 1;
+        cnt++;
+    }
+    return cnt;
+}
+
+/*
+ * Shift a block of 16 bytes left by shift bits
+ */
+static void ocb_block_lshift(const unsigned char *in, size_t shift,
+                             unsigned char *out)
+{
+    unsigned char shift_mask;
+    int i;
+    unsigned char mask[15];
+
+    shift_mask = 0xff;
+    shift_mask <<= (8 - shift);
+    for (i = 15; i >= 0; i--) {
+        if (i > 0) {
+            mask[i - 1] = in[i] & shift_mask;
+            mask[i - 1] >>= 8 - shift;
+        }
+        out[i] = in[i] << shift;
+
+        if (i != 15) {
+            out[i] ^= mask[i];
+        }
+    }
+}
+
+/*
+ * Perform a "double" operation as per OCB spec
+ */
+static void ocb_double(OCB_BLOCK *in, OCB_BLOCK *out)
+{
+    unsigned char mask;
+
+    /*
+     * Calculate the mask based on the most significant bit. There are more
+     * efficient ways to do this - but this way is constant time
+     */
+    mask = in->c[0] & 0x80;
+    mask >>= 7;
+    mask *= 135;
+
+    ocb_block_lshift(in->c, 1, out->c);
+
+    out->c[15] ^= mask;
+}
+
+/*
+ * Perform an xor on in1 and in2 - each of len bytes. Store result in out
+ */
+static void ocb_block_xor(const unsigned char *in1,
+                          const unsigned char *in2, size_t len,
+                          unsigned char *out)
+{
+    size_t i;
+    for (i = 0; i < len; i++) {
+        out[i] = in1[i] ^ in2[i];
+    }
+}
+
+/*
+ * Lookup L_index in our lookup table. If we haven't already got it we need to
+ * calculate it
+ */
+static OCB_BLOCK *ocb_lookup_l(OCB128_CONTEXT *ctx, size_t idx)
+{
+    size_t l_index = ctx->l_index;
+
+    if (idx <= l_index) {
+        return ctx->l + idx;
+    }
+
+    /* We don't have it - so calculate it */
+    if (idx >= ctx->max_l_index) {
+        void *tmp_ptr;
+        /*
+         * Each additional entry allows to process almost double as
+         * much data, so that in linear world the table will need to
+         * be expanded with smaller and smaller increments. Originally
+         * it was doubling in size, which was a waste. Growing it
+         * linearly is not formally optimal, but is simpler to implement.
+         * We grow table by minimally required 4*n that would accommodate
+         * the index.
+         */
+        ctx->max_l_index += (idx - ctx->max_l_index + 4) & ~3;
+        tmp_ptr =
+            OPENSSL_realloc(ctx->l, ctx->max_l_index * sizeof(OCB_BLOCK));
+        if (tmp_ptr == NULL) /* prevent ctx->l from being clobbered */
+            return NULL;
+        ctx->l = tmp_ptr;
+    }
+    while (l_index < idx) {
+        ocb_double(ctx->l + l_index, ctx->l + l_index + 1);
+        l_index++;
+    }
+    ctx->l_index = l_index;
+
+    return ctx->l + idx;
+}
+
+/*
+ * Create a new OCB128_CONTEXT
+ */
+OCB128_CONTEXT *CRYPTO_ocb128_new(void *keyenc, void *keydec,
+                                  block128_f encrypt, block128_f decrypt,
+                                  ocb128_f stream)
+{
+    OCB128_CONTEXT *octx;
+    int ret;
+
+    if ((octx = OPENSSL_malloc(sizeof(*octx))) != NULL) {
+        ret = CRYPTO_ocb128_init(octx, keyenc, keydec, encrypt, decrypt,
+                                 stream);
+        if (ret)
+            return octx;
+        OPENSSL_free(octx);
+    }
+
+    return NULL;
+}
+
+/*
+ * Initialise an existing OCB128_CONTEXT
+ */
+int CRYPTO_ocb128_init(OCB128_CONTEXT *ctx, void *keyenc, void *keydec,
+                       block128_f encrypt, block128_f decrypt,
+                       ocb128_f stream)
+{
+    memset(ctx, 0, sizeof(*ctx));
+    ctx->l_index = 0;
+    ctx->max_l_index = 5;
+    ctx->l = OPENSSL_malloc(ctx->max_l_index * 16);
+    if (ctx->l == NULL)
+        return 0;
+
+    /*
+     * We set both the encryption and decryption key schedules - decryption
+     * needs both. Don't really need decryption schedule if only doing
+     * encryption - but it simplifies things to take it anyway
+     */
+    ctx->encrypt = encrypt;
+    ctx->decrypt = decrypt;
+    ctx->stream = stream;
+    ctx->keyenc = keyenc;
+    ctx->keydec = keydec;
+
+    /* L_* = ENCIPHER(K, zeros(128)) */
+    ctx->encrypt(ctx->l_star.c, ctx->l_star.c, ctx->keyenc);
+
+    /* L_$ = double(L_*) */
+    ocb_double(&ctx->l_star, &ctx->l_dollar);
+
+    /* L_0 = double(L_$) */
+    ocb_double(&ctx->l_dollar, ctx->l);
+
+    /* L_{i} = double(L_{i-1}) */
+    ocb_double(ctx->l, ctx->l+1);
+    ocb_double(ctx->l+1, ctx->l+2);
+    ocb_double(ctx->l+2, ctx->l+3);
+    ocb_double(ctx->l+3, ctx->l+4);
+    ctx->l_index = 4;   /* enough to process up to 496 bytes */
+
+    return 1;
+}
+
+/*
+ * Copy an OCB128_CONTEXT object
+ */
+int CRYPTO_ocb128_copy_ctx(OCB128_CONTEXT *dest, OCB128_CONTEXT *src,
+                           void *keyenc, void *keydec)
+{
+    memcpy(dest, src, sizeof(OCB128_CONTEXT));
+    if (keyenc)
+        dest->keyenc = keyenc;
+    if (keydec)
+        dest->keydec = keydec;
+    if (src->l) {
+        dest->l = OPENSSL_malloc(src->max_l_index * 16);
+        if (dest->l == NULL)
+            return 0;
+        memcpy(dest->l, src->l, (src->l_index + 1) * 16);
+    }
+    return 1;
+}
+
+/*
+ * Set the IV to be used for this operation. Must be 1 - 15 bytes.
+ */
+int CRYPTO_ocb128_setiv(OCB128_CONTEXT *ctx, const unsigned char *iv,
+                        size_t len, size_t taglen)
+{
+    unsigned char ktop[16], tmp[16], mask;
+    unsigned char stretch[24], nonce[16];
+    size_t bottom, shift;
+
+    /*
+     * Spec says IV is 120 bits or fewer - it allows non byte aligned lengths.
+     * We don't support this at this stage
+     */
+    if ((len > 15) || (len < 1) || (taglen > 16) || (taglen < 1)) {
+        return -1;
+    }
+
+    /* Nonce = num2str(TAGLEN mod 128,7) || zeros(120-bitlen(N)) || 1 || N */
+    nonce[0] = ((taglen * 8) % 128) << 1;
+    memset(nonce + 1, 0, 15);
+    memcpy(nonce + 16 - len, iv, len);
+    nonce[15 - len] |= 1;
+
+    /* Ktop = ENCIPHER(K, Nonce[1..122] || zeros(6)) */
+    memcpy(tmp, nonce, 16);
+    tmp[15] &= 0xc0;
+    ctx->encrypt(tmp, ktop, ctx->keyenc);
+
+    /* Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) */
+    memcpy(stretch, ktop, 16);
+    ocb_block_xor(ktop, ktop + 1, 8, stretch + 16);
+
+    /* bottom = str2num(Nonce[123..128]) */
+    bottom = nonce[15] & 0x3f;
+
+    /* Offset_0 = Stretch[1+bottom..128+bottom] */
+    shift = bottom % 8;
+    ocb_block_lshift(stretch + (bottom / 8), shift, ctx->offset.c);
+    mask = 0xff;
+    mask <<= 8 - shift;
+    ctx->offset.c[15] |=
+        (*(stretch + (bottom / 8) + 16) & mask) >> (8 - shift);
+
+    return 1;
+}
+
+/*
+ * Provide any AAD. This can be called multiple times. Only the final time can
+ * have a partial block
+ */
+int CRYPTO_ocb128_aad(OCB128_CONTEXT *ctx, const unsigned char *aad,
+                      size_t len)
+{
+    u64 i, all_num_blocks;
+    size_t num_blocks, last_len;
+    OCB_BLOCK tmp1;
+    OCB_BLOCK tmp2;
+
+    /* Calculate the number of blocks of AAD provided now, and so far */
+    num_blocks = len / 16;
+    all_num_blocks = num_blocks + ctx->blocks_hashed;
+
+    /* Loop through all full blocks of AAD */
+    for (i = ctx->blocks_hashed + 1; i <= all_num_blocks; i++) {
+        OCB_BLOCK *lookup;
+        OCB_BLOCK *aad_block;
+
+        /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+        lookup = ocb_lookup_l(ctx, ocb_ntz(i));
+        if (lookup == NULL)
+            return 0;
+        ocb_block16_xor(&ctx->offset_aad, lookup, &ctx->offset_aad);
+
+        /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
+        aad_block = (OCB_BLOCK *)(aad + ((i - ctx->blocks_hashed - 1) * 16));
+        ocb_block16_xor(&ctx->offset_aad, aad_block, &tmp1);
+        ctx->encrypt(tmp1.c, tmp2.c, ctx->keyenc);
+        ocb_block16_xor(&ctx->sum, &tmp2, &ctx->sum);
+    }
+
+    /*
+     * Check if we have any partial blocks left over. This is only valid in the
+     * last call to this function
+     */
+    last_len = len % 16;
+
+    if (last_len > 0) {
+        /* Offset_* = Offset_m xor L_* */
+        ocb_block16_xor(&ctx->offset_aad, &ctx->l_star, &ctx->offset_aad);
+
+        /* CipherInput = (A_* || 1 || zeros(127-bitlen(A_*))) xor Offset_* */
+        memset(&tmp1, 0, 16);
+        memcpy(&tmp1, aad + (num_blocks * 16), last_len);
+        ((unsigned char *)&tmp1)[last_len] = 0x80;
+        ocb_block16_xor(&ctx->offset_aad, &tmp1, &tmp2);
+
+        /* Sum = Sum_m xor ENCIPHER(K, CipherInput) */
+        ctx->encrypt(tmp2.c, tmp1.c, ctx->keyenc);
+        ocb_block16_xor(&ctx->sum, &tmp1, &ctx->sum);
+    }
+
+    ctx->blocks_hashed = all_num_blocks;
+
+    return 1;
+}
+
+/*
+ * Provide any data to be encrypted. This can be called multiple times. Only
+ * the final time can have a partial block
+ */
+int CRYPTO_ocb128_encrypt(OCB128_CONTEXT *ctx,
+                          const unsigned char *in, unsigned char *out,
+                          size_t len)
+{
+    u64 i, all_num_blocks;
+    size_t num_blocks, last_len;
+    OCB_BLOCK tmp1;
+    OCB_BLOCK tmp2;
+    OCB_BLOCK pad;
+
+    /*
+     * Calculate the number of blocks of data to be encrypted provided now, and
+     * so far
+     */
+    num_blocks = len / 16;
+    all_num_blocks = num_blocks + ctx->blocks_processed;
+
+    if (num_blocks && all_num_blocks == (size_t)all_num_blocks
+        && ctx->stream != NULL) {
+        size_t max_idx = 0, top = (size_t)all_num_blocks;
+
+        /*
+         * See how many L_{i} entries we need to process data at hand
+         * and pre-compute missing entries in the table [if any]...
+         */
+        while (top >>= 1)
+            max_idx++;
+        if (ocb_lookup_l(ctx, max_idx) == NULL)
+            return 0;
+
+        ctx->stream(in, out, num_blocks, ctx->keyenc,
+                    (size_t)ctx->blocks_processed + 1, ctx->offset.c,
+                    (const unsigned char (*)[16])ctx->l, ctx->checksum.c);
+    } else {
+        /* Loop through all full blocks to be encrypted */
+        for (i = ctx->blocks_processed + 1; i <= all_num_blocks; i++) {
+            OCB_BLOCK *lookup;
+            OCB_BLOCK *inblock;
+            OCB_BLOCK *outblock;
+
+            /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+            lookup = ocb_lookup_l(ctx, ocb_ntz(i));
+            if (lookup == NULL)
+                return 0;
+            ocb_block16_xor(&ctx->offset, lookup, &ctx->offset);
+
+            /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */
+            inblock =
+                (OCB_BLOCK *)(in + ((i - ctx->blocks_processed - 1) * 16));
+            ocb_block16_xor_misaligned(&ctx->offset, inblock, &tmp1);
+            /* Checksum_i = Checksum_{i-1} xor P_i */
+            ocb_block16_xor_misaligned(&ctx->checksum, inblock, &ctx->checksum);
+            ctx->encrypt(tmp1.c, tmp2.c, ctx->keyenc);
+            outblock =
+                (OCB_BLOCK *)(out + ((i - ctx->blocks_processed - 1) * 16));
+            ocb_block16_xor_misaligned(&ctx->offset, &tmp2, outblock);
+        }
+    }
+
+    /*
+     * Check if we have any partial blocks left over. This is only valid in the
+     * last call to this function
+     */
+    last_len = len % 16;
+
+    if (last_len > 0) {
+        /* Offset_* = Offset_m xor L_* */
+        ocb_block16_xor(&ctx->offset, &ctx->l_star, &ctx->offset);
+
+        /* Pad = ENCIPHER(K, Offset_*) */
+        ctx->encrypt(ctx->offset.c, pad.c, ctx->keyenc);
+
+        /* C_* = P_* xor Pad[1..bitlen(P_*)] */
+        ocb_block_xor(in + (len / 16) * 16, (unsigned char *)&pad, last_len,
+                      out + (num_blocks * 16));
+
+        /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */
+        memset(&tmp1, 0, 16);
+        memcpy(&tmp1, in + (len / 16) * 16, last_len);
+        ((unsigned char *)(&tmp1))[last_len] = 0x80;
+        ocb_block16_xor(&ctx->checksum, &tmp1, &ctx->checksum);
+    }
+
+    ctx->blocks_processed = all_num_blocks;
+
+    return 1;
+}
+
+/*
+ * Provide any data to be decrypted. This can be called multiple times. Only
+ * the final time can have a partial block
+ */
+int CRYPTO_ocb128_decrypt(OCB128_CONTEXT *ctx,
+                          const unsigned char *in, unsigned char *out,
+                          size_t len)
+{
+    u64 i, all_num_blocks;
+    size_t num_blocks, last_len;
+    OCB_BLOCK tmp1;
+    OCB_BLOCK tmp2;
+    OCB_BLOCK pad;
+
+    /*
+     * Calculate the number of blocks of data to be decrypted provided now, and
+     * so far
+     */
+    num_blocks = len / 16;
+    all_num_blocks = num_blocks + ctx->blocks_processed;
+
+    if (num_blocks && all_num_blocks == (size_t)all_num_blocks
+        && ctx->stream != NULL) {
+        size_t max_idx = 0, top = (size_t)all_num_blocks;
+
+        /*
+         * See how many L_{i} entries we need to process data at hand
+         * and pre-compute missing entries in the table [if any]...
+         */
+        while (top >>= 1)
+            max_idx++;
+        if (ocb_lookup_l(ctx, max_idx) == NULL)
+            return 0;
+
+        ctx->stream(in, out, num_blocks, ctx->keydec,
+                    (size_t)ctx->blocks_processed + 1, ctx->offset.c,
+                    (const unsigned char (*)[16])ctx->l, ctx->checksum.c);
+    } else {
+        /* Loop through all full blocks to be decrypted */
+        for (i = ctx->blocks_processed + 1; i <= all_num_blocks; i++) {
+            OCB_BLOCK *inblock;
+            OCB_BLOCK *outblock;
+
+            /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
+            OCB_BLOCK *lookup = ocb_lookup_l(ctx, ocb_ntz(i));
+            if (lookup == NULL)
+                return 0;
+            ocb_block16_xor(&ctx->offset, lookup, &ctx->offset);
+
+            /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */
+            inblock =
+                (OCB_BLOCK *)(in + ((i - ctx->blocks_processed - 1) * 16));
+            ocb_block16_xor_misaligned(&ctx->offset, inblock, &tmp1);
+            ctx->decrypt(tmp1.c, tmp2.c, ctx->keydec);
+            outblock =
+                (OCB_BLOCK *)(out + ((i - ctx->blocks_processed - 1) * 16));
+            ocb_block16_xor_misaligned(&ctx->offset, &tmp2, outblock);
+
+            /* Checksum_i = Checksum_{i-1} xor P_i */
+            ocb_block16_xor_misaligned(&ctx->checksum, outblock, &ctx->checksum);
+        }
+    }
+
+    /*
+     * Check if we have any partial blocks left over. This is only valid in the
+     * last call to this function
+     */
+    last_len = len % 16;
+
+    if (last_len > 0) {
+        /* Offset_* = Offset_m xor L_* */
+        ocb_block16_xor(&ctx->offset, &ctx->l_star, &ctx->offset);
+
+        /* Pad = ENCIPHER(K, Offset_*) */
+        ctx->encrypt(ctx->offset.c, pad.c, ctx->keyenc);
+
+        /* P_* = C_* xor Pad[1..bitlen(C_*)] */
+        ocb_block_xor(in + (len / 16) * 16, (unsigned char *)&pad, last_len,
+                      out + (num_blocks * 16));
+
+        /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */
+        memset(&tmp1, 0, 16);
+        memcpy(&tmp1, out + (len / 16) * 16, last_len);
+        ((unsigned char *)(&tmp1))[last_len] = 0x80;
+        ocb_block16_xor(&ctx->checksum, &tmp1, &ctx->checksum);
+    }
+
+    ctx->blocks_processed = all_num_blocks;
+
+    return 1;
+}
+
+/*
+ * Calculate the tag and verify it against the supplied tag
+ */
+int CRYPTO_ocb128_finish(OCB128_CONTEXT *ctx, const unsigned char *tag,
+                         size_t len)
+{
+    OCB_BLOCK tmp1, tmp2;
+
+    /*
+     * Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A)
+     */
+    ocb_block16_xor(&ctx->checksum, &ctx->offset, &tmp1);
+    ocb_block16_xor(&tmp1, &ctx->l_dollar, &tmp2);
+    ctx->encrypt(tmp2.c, tmp1.c, ctx->keyenc);
+    ocb_block16_xor(&tmp1, &ctx->sum, &ctx->tag);
+
+    if (len > 16 || len < 1) {
+        return -1;
+    }
+
+    /* Compare the tag if we've been given one */
+    if (tag)
+        return CRYPTO_memcmp(&ctx->tag, tag, len);
+    else
+        return -1;
+}
+
+/*
+ * Retrieve the calculated tag
+ */
+int CRYPTO_ocb128_tag(OCB128_CONTEXT *ctx, unsigned char *tag, size_t len)
+{
+    if (len > 16 || len < 1) {
+        return -1;
+    }
+
+    /* Calculate the tag */
+    CRYPTO_ocb128_finish(ctx, NULL, 0);
+
+    /* Copy the tag into the supplied buffer */
+    memcpy(tag, &ctx->tag, len);
+
+    return 1;
+}
+
+/*
+ * Release all resources
+ */
+void CRYPTO_ocb128_cleanup(OCB128_CONTEXT *ctx)
+{
+    if (ctx) {
+        OPENSSL_clear_free(ctx->l, ctx->max_l_index * 16);
+        OPENSSL_cleanse(ctx, sizeof(*ctx));
+    }
+}
+
+#endif                          /* OPENSSL_NO_OCB */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/ofb128.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/ofb128.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/ofb128.c	(revision 331)
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2008-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 <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+/*
+ * The input and output encrypted as though 128bit ofb mode is being used.
+ * The extra state information to record how much of the 128bit block we have
+ * used is contained in *num;
+ */
+void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const void *key,
+                           unsigned char ivec[16], int *num, block128_f block)
+{
+    unsigned int n;
+    size_t l = 0;
+
+    n = *num;
+
+#if !defined(OPENSSL_SMALL_FOOTPRINT)
+    if (16 % sizeof(size_t) == 0) { /* always true actually */
+        do {
+            while (n && len) {
+                *(out++) = *(in++) ^ ivec[n];
+                --len;
+                n = (n + 1) % 16;
+            }
+# if defined(STRICT_ALIGNMENT)
+            if (((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) !=
+                0)
+                break;
+# endif
+            while (len >= 16) {
+                (*block) (ivec, ivec, key);
+                for (; n < 16; n += sizeof(size_t))
+                    *(size_t *)(out + n) =
+                        *(size_t *)(in + n) ^ *(size_t *)(ivec + n);
+                len -= 16;
+                out += 16;
+                in += 16;
+                n = 0;
+            }
+            if (len) {
+                (*block) (ivec, ivec, key);
+                while (len--) {
+                    out[n] = in[n] ^ ivec[n];
+                    ++n;
+                }
+            }
+            *num = n;
+            return;
+        } while (0);
+    }
+    /* the rest would be commonly eliminated by x86* compiler */
+#endif
+    while (l < len) {
+        if (n == 0) {
+            (*block) (ivec, ivec, key);
+        }
+        out[l] = in[l] ^ ivec[n];
+        ++l;
+        n = (n + 1) % 16;
+    }
+
+    *num = n;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/wrap128.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/wrap128.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/wrap128.c	(revision 331)
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2013-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
+ */
+
+/**  Beware!
+ *
+ *  Following wrapping modes were designed for AES but this implementation
+ *  allows you to use them for any 128 bit block cipher.
+ */
+
+#include "internal/cryptlib.h"
+#include <openssl/modes.h>
+
+/** RFC 3394 section 2.2.3.1 Default Initial Value */
+static const unsigned char default_iv[] = {
+    0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
+};
+
+/** RFC 5649 section 3 Alternative Initial Value 32-bit constant */
+static const unsigned char default_aiv[] = {
+    0xA6, 0x59, 0x59, 0xA6
+};
+
+/** Input size limit: lower than maximum of standards but far larger than
+ *  anything that will be used in practice.
+ */
+#define CRYPTO128_WRAP_MAX (1UL << 31)
+
+/** Wrapping according to RFC 3394 section 2.2.1.
+ *
+ *  @param[in]  key    Key value.
+ *  @param[in]  iv     IV value. Length = 8 bytes. NULL = use default_iv.
+ *  @param[in]  in     Plaintext as n 64-bit blocks, n >= 2.
+ *  @param[in]  inlen  Length of in.
+ *  @param[out] out    Ciphertext. Minimal buffer length = (inlen + 8) bytes.
+ *                     Input and output buffers can overlap if block function
+ *                     supports that.
+ *  @param[in]  block  Block processing function.
+ *  @return            0 if inlen does not consist of n 64-bit blocks, n >= 2.
+ *                     or if inlen > CRYPTO128_WRAP_MAX.
+ *                     Output length if wrapping succeeded.
+ */
+size_t CRYPTO_128_wrap(void *key, const unsigned char *iv,
+                       unsigned char *out,
+                       const unsigned char *in, size_t inlen,
+                       block128_f block)
+{
+    unsigned char *A, B[16], *R;
+    size_t i, j, t;
+    if ((inlen & 0x7) || (inlen < 16) || (inlen > CRYPTO128_WRAP_MAX))
+        return 0;
+    A = B;
+    t = 1;
+    memmove(out + 8, in, inlen);
+    if (!iv)
+        iv = default_iv;
+
+    memcpy(A, iv, 8);
+
+    for (j = 0; j < 6; j++) {
+        R = out + 8;
+        for (i = 0; i < inlen; i += 8, t++, R += 8) {
+            memcpy(B + 8, R, 8);
+            block(B, B, key);
+            A[7] ^= (unsigned char)(t & 0xff);
+            if (t > 0xff) {
+                A[6] ^= (unsigned char)((t >> 8) & 0xff);
+                A[5] ^= (unsigned char)((t >> 16) & 0xff);
+                A[4] ^= (unsigned char)((t >> 24) & 0xff);
+            }
+            memcpy(R, B + 8, 8);
+        }
+    }
+    memcpy(out, A, 8);
+    return inlen + 8;
+}
+
+/** Unwrapping according to RFC 3394 section 2.2.2 steps 1-2.
+ *  The IV check (step 3) is responsibility of the caller.
+ *
+ *  @param[in]  key    Key value.
+ *  @param[out] iv     Unchecked IV value. Minimal buffer length = 8 bytes.
+ *  @param[out] out    Plaintext without IV.
+ *                     Minimal buffer length = (inlen - 8) bytes.
+ *                     Input and output buffers can overlap if block function
+ *                     supports that.
+ *  @param[in]  in     Ciphertext as n 64-bit blocks.
+ *  @param[in]  inlen  Length of in.
+ *  @param[in]  block  Block processing function.
+ *  @return            0 if inlen is out of range [24, CRYPTO128_WRAP_MAX]
+ *                     or if inlen is not a multiple of 8.
+ *                     Output length otherwise.
+ */
+static size_t crypto_128_unwrap_raw(void *key, unsigned char *iv,
+                                    unsigned char *out,
+                                    const unsigned char *in, size_t inlen,
+                                    block128_f block)
+{
+    unsigned char *A, B[16], *R;
+    size_t i, j, t;
+    inlen -= 8;
+    if ((inlen & 0x7) || (inlen < 16) || (inlen > CRYPTO128_WRAP_MAX))
+        return 0;
+    A = B;
+    t = 6 * (inlen >> 3);
+    memcpy(A, in, 8);
+    memmove(out, in + 8, inlen);
+    for (j = 0; j < 6; j++) {
+        R = out + inlen - 8;
+        for (i = 0; i < inlen; i += 8, t--, R -= 8) {
+            A[7] ^= (unsigned char)(t & 0xff);
+            if (t > 0xff) {
+                A[6] ^= (unsigned char)((t >> 8) & 0xff);
+                A[5] ^= (unsigned char)((t >> 16) & 0xff);
+                A[4] ^= (unsigned char)((t >> 24) & 0xff);
+            }
+            memcpy(B + 8, R, 8);
+            block(B, B, key);
+            memcpy(R, B + 8, 8);
+        }
+    }
+    memcpy(iv, A, 8);
+    return inlen;
+}
+
+/** Unwrapping according to RFC 3394 section 2.2.2, including the IV check.
+ *  The first block of plaintext has to match the supplied IV, otherwise an
+ *  error is returned.
+ *
+ *  @param[in]  key    Key value.
+ *  @param[out] iv     IV value to match against. Length = 8 bytes.
+ *                     NULL = use default_iv.
+ *  @param[out] out    Plaintext without IV.
+ *                     Minimal buffer length = (inlen - 8) bytes.
+ *                     Input and output buffers can overlap if block function
+ *                     supports that.
+ *  @param[in]  in     Ciphertext as n 64-bit blocks.
+ *  @param[in]  inlen  Length of in.
+ *  @param[in]  block  Block processing function.
+ *  @return            0 if inlen is out of range [24, CRYPTO128_WRAP_MAX]
+ *                     or if inlen is not a multiple of 8
+ *                     or if IV doesn't match expected value.
+ *                     Output length otherwise.
+ */
+size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv,
+                         unsigned char *out, const unsigned char *in,
+                         size_t inlen, block128_f block)
+{
+    size_t ret;
+    unsigned char got_iv[8];
+
+    ret = crypto_128_unwrap_raw(key, got_iv, out, in, inlen, block);
+    if (ret == 0)
+        return 0;
+
+    if (!iv)
+        iv = default_iv;
+    if (CRYPTO_memcmp(got_iv, iv, 8)) {
+        OPENSSL_cleanse(out, ret);
+        return 0;
+    }
+    return ret;
+}
+
+/** Wrapping according to RFC 5649 section 4.1.
+ *
+ *  @param[in]  key    Key value.
+ *  @param[in]  icv    (Non-standard) IV, 4 bytes. NULL = use default_aiv.
+ *  @param[out] out    Ciphertext. Minimal buffer length = (inlen + 15) bytes.
+ *                     Input and output buffers can overlap if block function
+ *                     supports that.
+ *  @param[in]  in     Plaintext as n 64-bit blocks, n >= 2.
+ *  @param[in]  inlen  Length of in.
+ *  @param[in]  block  Block processing function.
+ *  @return            0 if inlen is out of range [1, CRYPTO128_WRAP_MAX].
+ *                     Output length if wrapping succeeded.
+ */
+size_t CRYPTO_128_wrap_pad(void *key, const unsigned char *icv,
+                           unsigned char *out,
+                           const unsigned char *in, size_t inlen,
+                           block128_f block)
+{
+    /* n: number of 64-bit blocks in the padded key data
+     *
+     * If length of plain text is not a multiple of 8, pad the plain text octet
+     * string on the right with octets of zeros, where final length is the
+     * smallest multiple of 8 that is greater than length of plain text.
+     * If length of plain text is a multiple of 8, then there is no padding. */
+    const size_t blocks_padded = (inlen + 7) / 8; /* CEILING(m/8) */
+    const size_t padded_len = blocks_padded * 8;
+    const size_t padding_len = padded_len - inlen;
+    /* RFC 5649 section 3: Alternative Initial Value */
+    unsigned char aiv[8];
+    int ret;
+
+    /* Section 1: use 32-bit fixed field for plaintext octet length */
+    if (inlen == 0 || inlen >= CRYPTO128_WRAP_MAX)
+        return 0;
+
+    /* Section 3: Alternative Initial Value */
+    if (!icv)
+        memcpy(aiv, default_aiv, 4);
+    else
+        memcpy(aiv, icv, 4);    /* Standard doesn't mention this. */
+
+    aiv[4] = (inlen >> 24) & 0xFF;
+    aiv[5] = (inlen >> 16) & 0xFF;
+    aiv[6] = (inlen >> 8) & 0xFF;
+    aiv[7] = inlen & 0xFF;
+
+    if (padded_len == 8) {
+        /*
+         * Section 4.1 - special case in step 2: If the padded plaintext
+         * contains exactly eight octets, then prepend the AIV and encrypt
+         * the resulting 128-bit block using AES in ECB mode.
+         */
+        memmove(out + 8, in, inlen);
+        memcpy(out, aiv, 8);
+        memset(out + 8 + inlen, 0, padding_len);
+        block(out, out, key);
+        ret = 16;               /* AIV + padded input */
+    } else {
+        memmove(out, in, inlen);
+        memset(out + inlen, 0, padding_len); /* Section 4.1 step 1 */
+        ret = CRYPTO_128_wrap(key, aiv, out, out, padded_len, block);
+    }
+
+    return ret;
+}
+
+/** Unwrapping according to RFC 5649 section 4.2.
+ *
+ *  @param[in]  key    Key value.
+ *  @param[in]  icv    (Non-standard) IV, 4 bytes. NULL = use default_aiv.
+ *  @param[out] out    Plaintext. Minimal buffer length = inlen bytes.
+ *                     Input and output buffers can overlap if block function
+ *                     supports that.
+ *  @param[in]  in     Ciphertext as n 64-bit blocks.
+ *  @param[in]  inlen  Length of in.
+ *  @param[in]  block  Block processing function.
+ *  @return            0 if inlen is out of range [16, CRYPTO128_WRAP_MAX],
+ *                     or if inlen is not a multiple of 8
+ *                     or if IV and message length indicator doesn't match.
+ *                     Output length if unwrapping succeeded and IV matches.
+ */
+size_t CRYPTO_128_unwrap_pad(void *key, const unsigned char *icv,
+                             unsigned char *out,
+                             const unsigned char *in, size_t inlen,
+                             block128_f block)
+{
+    /* n: number of 64-bit blocks in the padded key data */
+    size_t n = inlen / 8 - 1;
+    size_t padded_len;
+    size_t padding_len;
+    size_t ptext_len;
+    /* RFC 5649 section 3: Alternative Initial Value */
+    unsigned char aiv[8];
+    static unsigned char zeros[8] = { 0x0 };
+    size_t ret;
+
+    /* Section 4.2: Ciphertext length has to be (n+1) 64-bit blocks. */
+    if ((inlen & 0x7) != 0 || inlen < 16 || inlen >= CRYPTO128_WRAP_MAX)
+        return 0;
+
+    memmove(out, in, inlen);
+    if (inlen == 16) {
+        /*
+         * Section 4.2 - special case in step 1: When n=1, the ciphertext
+         * contains exactly two 64-bit blocks and they are decrypted as a
+         * single AES block using AES in ECB mode: AIV | P[1] = DEC(K, C[0] |
+         * C[1])
+         */
+        block(out, out, key);
+        memcpy(aiv, out, 8);
+        /* Remove AIV */
+        memmove(out, out + 8, 8);
+        padded_len = 8;
+    } else {
+        padded_len = inlen - 8;
+        ret = crypto_128_unwrap_raw(key, aiv, out, out, inlen, block);
+        if (padded_len != ret) {
+            OPENSSL_cleanse(out, inlen);
+            return 0;
+        }
+    }
+
+    /*
+     * Section 3: AIV checks: Check that MSB(32,A) = A65959A6. Optionally a
+     * user-supplied value can be used (even if standard doesn't mention
+     * this).
+     */
+    if ((!icv && CRYPTO_memcmp(aiv, default_aiv, 4))
+        || (icv && CRYPTO_memcmp(aiv, icv, 4))) {
+        OPENSSL_cleanse(out, inlen);
+        return 0;
+    }
+
+    /*
+     * Check that 8*(n-1) < LSB(32,AIV) <= 8*n. If so, let ptext_len =
+     * LSB(32,AIV).
+     */
+
+    ptext_len =   ((unsigned int)aiv[4] << 24)
+                | ((unsigned int)aiv[5] << 16)
+                | ((unsigned int)aiv[6] <<  8)
+                |  (unsigned int)aiv[7];
+    if (8 * (n - 1) >= ptext_len || ptext_len > 8 * n) {
+        OPENSSL_cleanse(out, inlen);
+        return 0;
+    }
+
+    /*
+     * Check that the rightmost padding_len octets of the output data are
+     * zero.
+     */
+    padding_len = padded_len - ptext_len;
+    if (CRYPTO_memcmp(out + ptext_len, zeros, padding_len) != 0) {
+        OPENSSL_cleanse(out, inlen);
+        return 0;
+    }
+
+    /* Section 4.2 step 3: Remove padding */
+    return ptext_len;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/xts128.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/xts128.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/modes/xts128.c	(revision 331)
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2011-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 <openssl/crypto.h>
+#include "modes_lcl.h"
+#include <string.h>
+
+int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
+                          const unsigned char iv[16],
+                          const unsigned char *inp, unsigned char *out,
+                          size_t len, int enc)
+{
+    const union {
+        long one;
+        char little;
+    } is_endian = {
+        1
+    };
+    union {
+        u64 u[2];
+        u32 d[4];
+        u8 c[16];
+    } tweak, scratch;
+    unsigned int i;
+
+    if (len < 16)
+        return -1;
+
+    memcpy(tweak.c, iv, 16);
+
+    (*ctx->block2) (tweak.c, tweak.c, ctx->key2);
+
+    if (!enc && (len % 16))
+        len -= 16;
+
+    while (len >= 16) {
+#if defined(STRICT_ALIGNMENT)
+        memcpy(scratch.c, inp, 16);
+        scratch.u[0] ^= tweak.u[0];
+        scratch.u[1] ^= tweak.u[1];
+#else
+        scratch.u[0] = ((u64 *)inp)[0] ^ tweak.u[0];
+        scratch.u[1] = ((u64 *)inp)[1] ^ tweak.u[1];
+#endif
+        (*ctx->block1) (scratch.c, scratch.c, ctx->key1);
+#if defined(STRICT_ALIGNMENT)
+        scratch.u[0] ^= tweak.u[0];
+        scratch.u[1] ^= tweak.u[1];
+        memcpy(out, scratch.c, 16);
+#else
+        ((u64 *)out)[0] = scratch.u[0] ^= tweak.u[0];
+        ((u64 *)out)[1] = scratch.u[1] ^= tweak.u[1];
+#endif
+        inp += 16;
+        out += 16;
+        len -= 16;
+
+        if (len == 0)
+            return 0;
+
+        if (is_endian.little) {
+            unsigned int carry, res;
+
+            res = 0x87 & (((int)tweak.d[3]) >> 31);
+            carry = (unsigned int)(tweak.u[0] >> 63);
+            tweak.u[0] = (tweak.u[0] << 1) ^ res;
+            tweak.u[1] = (tweak.u[1] << 1) | carry;
+        } else {
+            size_t c;
+
+            for (c = 0, i = 0; i < 16; ++i) {
+                /*
+                 * + substitutes for |, because c is 1 bit
+                 */
+                c += ((size_t)tweak.c[i]) << 1;
+                tweak.c[i] = (u8)c;
+                c = c >> 8;
+            }
+            tweak.c[0] ^= (u8)(0x87 & (0 - c));
+        }
+    }
+    if (enc) {
+        for (i = 0; i < len; ++i) {
+            u8 c = inp[i];
+            out[i] = scratch.c[i];
+            scratch.c[i] = c;
+        }
+        scratch.u[0] ^= tweak.u[0];
+        scratch.u[1] ^= tweak.u[1];
+        (*ctx->block1) (scratch.c, scratch.c, ctx->key1);
+        scratch.u[0] ^= tweak.u[0];
+        scratch.u[1] ^= tweak.u[1];
+        memcpy(out - 16, scratch.c, 16);
+    } else {
+        union {
+            u64 u[2];
+            u8 c[16];
+        } tweak1;
+
+        if (is_endian.little) {
+            unsigned int carry, res;
+
+            res = 0x87 & (((int)tweak.d[3]) >> 31);
+            carry = (unsigned int)(tweak.u[0] >> 63);
+            tweak1.u[0] = (tweak.u[0] << 1) ^ res;
+            tweak1.u[1] = (tweak.u[1] << 1) | carry;
+        } else {
+            size_t c;
+
+            for (c = 0, i = 0; i < 16; ++i) {
+                /*
+                 * + substitutes for |, because c is 1 bit
+                 */
+                c += ((size_t)tweak.c[i]) << 1;
+                tweak1.c[i] = (u8)c;
+                c = c >> 8;
+            }
+            tweak1.c[0] ^= (u8)(0x87 & (0 - c));
+        }
+#if defined(STRICT_ALIGNMENT)
+        memcpy(scratch.c, inp, 16);
+        scratch.u[0] ^= tweak1.u[0];
+        scratch.u[1] ^= tweak1.u[1];
+#else
+        scratch.u[0] = ((u64 *)inp)[0] ^ tweak1.u[0];
+        scratch.u[1] = ((u64 *)inp)[1] ^ tweak1.u[1];
+#endif
+        (*ctx->block1) (scratch.c, scratch.c, ctx->key1);
+        scratch.u[0] ^= tweak1.u[0];
+        scratch.u[1] ^= tweak1.u[1];
+
+        for (i = 0; i < len; ++i) {
+            u8 c = inp[16 + i];
+            out[16 + i] = scratch.c[i];
+            scratch.c[i] = c;
+        }
+        scratch.u[0] ^= tweak.u[0];
+        scratch.u[1] ^= tweak.u[1];
+        (*ctx->block1) (scratch.c, scratch.c, ctx->key1);
+#if defined(STRICT_ALIGNMENT)
+        scratch.u[0] ^= tweak.u[0];
+        scratch.u[1] ^= tweak.u[1];
+        memcpy(out, scratch.c, 16);
+#else
+        ((u64 *)out)[0] = scratch.u[0] ^ tweak.u[0];
+        ((u64 *)out)[1] = scratch.u[1] ^ tweak.u[1];
+#endif
+    }
+
+    return 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/o_dir.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/o_dir.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/o_dir.c	(revision 331)
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2004-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 <errno.h>
+#include <e_os.h>
+
+/*
+ * The routines really come from the Levitte Programming, so to make life
+ * simple, let's just use the raw files and hack the symbols to fit our
+ * namespace.
+ */
+#define LP_DIR_CTX OPENSSL_DIR_CTX
+#define LP_dir_context_st OPENSSL_dir_context_st
+#define LP_find_file OPENSSL_DIR_read
+#define LP_find_file_end OPENSSL_DIR_end
+
+#include "internal/o_dir.h"
+
+#define LPDIR_H
+#if defined OPENSSL_SYS_UNIX || defined DJGPP
+# include "LPdir_unix.c"
+#elif defined OPENSSL_SYS_VMS
+# include "LPdir_vms.c"
+#elif defined OPENSSL_SYS_WIN32
+# include "LPdir_win32.c"
+#elif defined OPENSSL_SYS_WINCE
+# include "LPdir_wince.c"
+#else
+# include "LPdir_nyi.c"
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/o_fips.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/o_fips.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/o_fips.c	(revision 331)
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2011-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 "internal/cryptlib.h"
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+
+int FIPS_mode(void)
+{
+#ifdef OPENSSL_FIPS
+    return FIPS_module_mode();
+#else
+    return 0;
+#endif
+}
+
+int FIPS_mode_set(int r)
+{
+#ifdef OPENSSL_FIPS
+    return FIPS_module_mode_set(r);
+#else
+    if (r == 0)
+        return 1;
+    CRYPTOerr(CRYPTO_F_FIPS_MODE_SET, CRYPTO_R_FIPS_MODE_NOT_SUPPORTED);
+    return 0;
+#endif
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/o_fopen.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/o_fopen.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/o_fopen.c	(revision 331)
@@ -0,0 +1,103 @@
+/*
+ * 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 "internal/cryptlib.h"
+
+#if !defined(OPENSSL_NO_STDIO)
+
+# include <stdio.h>
+
+FILE *openssl_fopen(const char *filename, const char *mode)
+{
+    FILE *file = NULL;
+# if defined(_WIN32) && defined(CP_UTF8)
+    int sz, len_0 = (int)strlen(filename) + 1;
+    DWORD flags;
+
+    /*
+     * Basically there are three cases to cover: a) filename is
+     * pure ASCII string; b) actual UTF-8 encoded string and
+     * c) locale-ized string, i.e. one containing 8-bit
+     * characters that are meaningful in current system locale.
+     * If filename is pure ASCII or real UTF-8 encoded string,
+     * MultiByteToWideChar succeeds and _wfopen works. If
+     * filename is locale-ized string, chances are that
+     * MultiByteToWideChar fails reporting
+     * ERROR_NO_UNICODE_TRANSLATION, in which case we fall
+     * back to fopen...
+     */
+    if ((sz = MultiByteToWideChar(CP_UTF8, (flags = MB_ERR_INVALID_CHARS),
+                                  filename, len_0, NULL, 0)) > 0 ||
+        (GetLastError() == ERROR_INVALID_FLAGS &&
+         (sz = MultiByteToWideChar(CP_UTF8, (flags = 0),
+                                   filename, len_0, NULL, 0)) > 0)
+        ) {
+        WCHAR wmode[8];
+        WCHAR *wfilename = _alloca(sz * sizeof(WCHAR));
+
+        if (MultiByteToWideChar(CP_UTF8, flags,
+                                filename, len_0, wfilename, sz) &&
+            MultiByteToWideChar(CP_UTF8, 0, mode, strlen(mode) + 1,
+                                wmode, OSSL_NELEM(wmode)) &&
+            (file = _wfopen(wfilename, wmode)) == NULL &&
+            (errno == ENOENT || errno == EBADF)
+            ) {
+            /*
+             * UTF-8 decode succeeded, but no file, filename
+             * could still have been locale-ized...
+             */
+            file = fopen(filename, mode);
+        }
+    } else if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) {
+        file = fopen(filename, mode);
+    }
+# elif defined(__DJGPP__)
+    {
+        char *newname = NULL;
+
+        if (!HAS_LFN_SUPPORT(filename)) {
+            char *iterator;
+            char lastchar;
+
+            newname = OPENSSL_malloc(strlen(filename) + 1);
+            if (newname == NULL)
+                return NULL;
+
+            for (iterator = newname, lastchar = '\0';
+                *filename; filename++, iterator++) {
+                if (lastchar == '/' && filename[0] == '.'
+                    && filename[1] != '.' && filename[1] != '/') {
+                    /* Leading dots are not permitted in plain DOS. */
+                    *iterator = '_';
+                } else {
+                    *iterator = *filename;
+                }
+                lastchar = *filename;
+            }
+            *iterator = '\0';
+            filename = newname;
+        }
+        file = fopen(filename, mode);
+
+        OPENSSL_free(newname);
+    }
+# else
+    file = fopen(filename, mode);
+# endif
+    return file;
+}
+
+#else
+
+void *openssl_fopen(const char *filename, const char *mode)
+{
+    return NULL;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/o_init.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/o_init.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/o_init.c	(revision 331)
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2011-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 <e_os.h>
+#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+# include <openssl/rand.h>
+#endif
+
+/*
+ * Perform any essential OpenSSL initialization operations. Currently only
+ * sets FIPS callbacks
+ */
+
+void OPENSSL_init(void)
+{
+    static int done = 0;
+    if (done)
+        return;
+    done = 1;
+#ifdef OPENSSL_FIPS
+    FIPS_set_locking_callbacks(CRYPTO_lock, CRYPTO_add_lock);
+    FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata);
+    FIPS_set_malloc_callbacks(CRYPTO_malloc, CRYPTO_free);
+    RAND_init_fips();
+#endif
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/o_str.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/o_str.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/o_str.c	(revision 331)
@@ -0,0 +1,250 @@
+/*
+ * Copyright 2003-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 <ctype.h>
+#include <limits.h>
+#include <e_os.h>
+#include <openssl/crypto.h>
+#include "internal/cryptlib.h"
+#include "internal/o_str.h"
+
+int OPENSSL_memcmp(const void *v1, const void *v2, size_t n)
+{
+    const unsigned char *c1 = v1, *c2 = v2;
+    int ret = 0;
+
+    while (n && (ret = *c1 - *c2) == 0)
+        n--, c1++, c2++;
+
+    return ret;
+}
+
+char *CRYPTO_strdup(const char *str, const char* file, int line)
+{
+    char *ret;
+    size_t size;
+
+    if (str == NULL)
+        return NULL;
+    size = strlen(str) + 1;
+    ret = CRYPTO_malloc(size, file, line);
+    if (ret != NULL)
+        memcpy(ret, str, size);
+    return ret;
+}
+
+char *CRYPTO_strndup(const char *str, size_t s, const char* file, int line)
+{
+    size_t maxlen;
+    char *ret;
+
+    if (str == NULL)
+        return NULL;
+
+    maxlen = OPENSSL_strnlen(str, s);
+
+    ret = CRYPTO_malloc(maxlen + 1, file, line);
+    if (ret) {
+        memcpy(ret, str, maxlen);
+        ret[maxlen] = '\0';
+    }
+    return ret;
+}
+
+void *CRYPTO_memdup(const void *data, size_t siz, const char* file, int line)
+{
+    void *ret;
+
+    if (data == NULL || siz >= INT_MAX)
+        return NULL;
+
+    ret = CRYPTO_malloc(siz, file, line);
+    if (ret == NULL) {
+        CRYPTOerr(CRYPTO_F_CRYPTO_MEMDUP, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    return memcpy(ret, data, siz);
+}
+
+size_t OPENSSL_strnlen(const char *str, size_t maxlen)
+{
+    const char *p;
+
+    for (p = str; maxlen-- != 0 && *p != '\0'; ++p) ;
+
+    return p - str;
+}
+
+size_t OPENSSL_strlcpy(char *dst, const char *src, size_t size)
+{
+    size_t l = 0;
+    for (; size > 1 && *src; size--) {
+        *dst++ = *src++;
+        l++;
+    }
+    if (size)
+        *dst = '\0';
+    return l + strlen(src);
+}
+
+size_t OPENSSL_strlcat(char *dst, const char *src, size_t size)
+{
+    size_t l = 0;
+    for (; size > 0 && *dst; size--, dst++)
+        l++;
+    return l + OPENSSL_strlcpy(dst, src, size);
+}
+
+int OPENSSL_hexchar2int(unsigned char c)
+{
+#ifdef CHARSET_EBCDIC
+    c = os_toebcdic[c];
+#endif
+
+    switch (c) {
+    case '0':
+        return 0;
+    case '1':
+        return 1;
+    case '2':
+        return 2;
+    case '3':
+        return 3;
+    case '4':
+          return 4;
+    case '5':
+          return 5;
+    case '6':
+          return 6;
+    case '7':
+          return 7;
+    case '8':
+          return 8;
+    case '9':
+          return 9;
+    case 'a': case 'A':
+          return 0x0A;
+    case 'b': case 'B':
+          return 0x0B;
+    case 'c': case 'C':
+          return 0x0C;
+    case 'd': case 'D':
+          return 0x0D;
+    case 'e': case 'E':
+          return 0x0E;
+    case 'f': case 'F':
+          return 0x0F;
+    }
+    return -1;
+}
+
+/*
+ * Give a string of hex digits convert to a buffer
+ */
+unsigned char *OPENSSL_hexstr2buf(const char *str, long *len)
+{
+    unsigned char *hexbuf, *q;
+    unsigned char ch, cl;
+    int chi, cli;
+    const unsigned char *p;
+    size_t s;
+
+    s = strlen(str);
+    if ((hexbuf = OPENSSL_malloc(s >> 1)) == NULL) {
+        CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    for (p = (const unsigned char *)str, q = hexbuf; *p; ) {
+        ch = *p++;
+        if (ch == ':')
+            continue;
+        cl = *p++;
+        if (!cl) {
+            CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF,
+                      CRYPTO_R_ODD_NUMBER_OF_DIGITS);
+            OPENSSL_free(hexbuf);
+            return NULL;
+        }
+        cli = OPENSSL_hexchar2int(cl);
+        chi = OPENSSL_hexchar2int(ch);
+        if (cli < 0 || chi < 0) {
+            OPENSSL_free(hexbuf);
+            CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, CRYPTO_R_ILLEGAL_HEX_DIGIT);
+            return NULL;
+        }
+        *q++ = (unsigned char)((chi << 4) | cli);
+    }
+
+    if (len)
+        *len = q - hexbuf;
+    return hexbuf;
+}
+
+/*
+ * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its
+ * hex representation @@@ (Contents of buffer are always kept in ASCII, also
+ * on EBCDIC machines)
+ */
+char *OPENSSL_buf2hexstr(const unsigned char *buffer, long len)
+{
+    const static char hexdig[] = "0123456789ABCDEF";
+    char *tmp, *q;
+    const unsigned char *p;
+    int i;
+
+    if (len == 0)
+    {
+        return OPENSSL_zalloc(1);
+    }
+
+    if ((tmp = OPENSSL_malloc(len * 3)) == NULL) {
+        CRYPTOerr(CRYPTO_F_OPENSSL_BUF2HEXSTR, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    q = tmp;
+    for (i = 0, p = buffer; i < len; i++, p++) {
+        *q++ = hexdig[(*p >> 4) & 0xf];
+        *q++ = hexdig[*p & 0xf];
+        *q++ = ':';
+    }
+    q[-1] = 0;
+#ifdef CHARSET_EBCDIC
+    ebcdic2ascii(tmp, tmp, q - tmp - 1);
+#endif
+
+    return tmp;
+}
+
+int openssl_strerror_r(int errnum, char *buf, size_t buflen)
+{
+#if defined(_MSC_VER) && _MSC_VER>=1400
+    return !strerror_s(buf, buflen, errnum);
+#elif defined(_GNU_SOURCE)
+    return strerror_r(errnum, buf, buflen) != NULL;
+#elif (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)
+    /*
+     * We can use "real" strerror_r. The OpenSSL version differs in that it
+     * gives 1 on success and 0 on failure for consistency with other OpenSSL
+     * functions. Real strerror_r does it the other way around
+     */
+    return !strerror_r(errnum, buf, buflen);
+#else
+    char *err;
+    /* Fall back to non-thread safe strerror()...its all we can do */
+    if (buflen < 2)
+        return 0;
+    err = strerror(errnum);
+    /* Can this ever happen? */
+    if (err == NULL)
+        return 0;
+    strncpy(buf, err, buflen - 1);
+    buf[buflen - 1] = '\0';
+    return 1;
+#endif
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/o_time.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/o_time.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/o_time.c	(revision 331)
@@ -0,0 +1,360 @@
+/*
+ * Copyright 2001-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 <openssl/e_os2.h>
+#include <string.h>
+#include <openssl/crypto.h>
+
+#ifdef OPENSSL_SYS_VMS
+# if __CRTL_VER >= 70000000 && \
+     (defined _POSIX_C_SOURCE || !defined _ANSI_C_SOURCE)
+#  define VMS_GMTIME_OK
+# endif
+# ifndef VMS_GMTIME_OK
+#  include <libdtdef.h>
+#  include <lib$routines.h>
+#  include <lnmdef.h>
+#  include <starlet.h>
+#  include <descrip.h>
+#  include <stdlib.h>
+# endif                         /* ndef VMS_GMTIME_OK */
+
+
+/*
+ * Needed to pick up the correct definitions and declarations in some of the
+ * DEC C Header Files (*.H).
+ */
+# define __NEW_STARLET 1
+
+# if (defined(__alpha) || defined(__ia64))
+#  include <iledef.h>
+# else
+
+/* VAX */
+typedef struct _ile3 {          /* Copied from ILEDEF.H for Alpha   */
+#  pragma __nomember_alignment
+    unsigned short int ile3$w_length;        /* Length of buffer in bytes */
+    unsigned short int ile3$w_code;          /* Item code value */
+    void *ile3$ps_bufaddr;                   /* Buffer address */
+    unsigned short int *ile3$ps_retlen_addr; /* Address of word for returned length */
+} ILE3;
+# endif   /* alpha || ia64    */
+#endif    /* OPENSSL_SYS_VMS  */
+
+struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result)
+{
+    struct tm *ts = NULL;
+
+#if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && (!defined(OPENSSL_SYS_VMS) || defined(gmtime_r)) && !defined(OPENSSL_SYS_MACOSX)
+    if (gmtime_r(timer, result) == NULL)
+        return NULL;
+    ts = result;
+#elif !defined(OPENSSL_SYS_VMS) || defined(VMS_GMTIME_OK)
+    ts = gmtime(timer);
+    if (ts == NULL)
+        return NULL;
+
+    memcpy(result, ts, sizeof(struct tm));
+    ts = result;
+#endif
+#if defined( OPENSSL_SYS_VMS) && !defined( VMS_GMTIME_OK)
+    if (ts == NULL) {
+        static $DESCRIPTOR(tabnam, "LNM$DCL_LOGICAL");
+        static $DESCRIPTOR(lognam, "SYS$TIMEZONE_DIFFERENTIAL");
+        char logvalue[256];
+        unsigned int reslen = 0;
+# if __INITIAL_POINTER_SIZE == 64
+        ILEB_64 itemlist[2], *pitem;
+# else
+        ILE3 itemlist[2], *pitem;
+# endif
+        int status;
+        time_t t;
+
+
+        /*
+         * Setup an itemlist for the call to $TRNLNM - Translate Logical Name.
+         */
+        pitem = itemlist;
+
+# if __INITIAL_POINTER_SIZE == 64
+        pitem->ileb_64$w_mbo = 1;
+        pitem->ileb_64$w_code = LNM$_STRING;
+        pitem->ileb_64$l_mbmo = -1;
+        pitem->ileb_64$q_length = sizeof (logvalue);
+        pitem->ileb_64$pq_bufaddr = logvalue;
+        pitem->ileb_64$pq_retlen_addr = (unsigned __int64 *) &reslen;
+        pitem++;
+        /* Last item of the item list is null terminated */
+        pitem->ileb_64$q_length = pitem->ileb_64$w_code = 0;
+# else
+        pitem->ile3$w_length = sizeof (logvalue);
+        pitem->ile3$w_code = LNM$_STRING;
+        pitem->ile3$ps_bufaddr = logvalue;
+        pitem->ile3$ps_retlen_addr = (unsigned short int *) &reslen;
+        pitem++;
+        /* Last item of the item list is null terminated */
+        pitem->ile3$w_length = pitem->ile3$w_code = 0;
+# endif
+
+
+        /* Get the value for SYS$TIMEZONE_DIFFERENTIAL */
+        status = sys$trnlnm(0, &tabnam, &lognam, 0, itemlist);
+        if (!(status & 1))
+            return NULL;
+        logvalue[reslen] = '\0';
+
+        t = *timer;
+
+        /* The following is extracted from the DEC C header time.h */
+        /*
+         **  Beginning in OpenVMS Version 7.0 mktime, time, ctime, strftime
+         **  have two implementations.  One implementation is provided
+         **  for compatibility and deals with time in terms of local time,
+         **  the other __utc_* deals with time in terms of UTC.
+         */
+        /*
+         * We use the same conditions as in said time.h to check if we should
+         * assume that t contains local time (and should therefore be
+         * adjusted) or UTC (and should therefore be left untouched).
+         */
+# if __CRTL_VER < 70000000 || defined _VMS_V6_SOURCE
+        /* Get the numerical value of the equivalence string */
+        status = atoi(logvalue);
+
+        /* and use it to move time to GMT */
+        t -= status;
+# endif
+
+        /* then convert the result to the time structure */
+
+        /*
+         * Since there was no gmtime_r() to do this stuff for us, we have to
+         * do it the hard way.
+         */
+        {
+            /*-
+             * The VMS epoch is the astronomical Smithsonian date,
+               if I remember correctly, which is November 17, 1858.
+               Furthermore, time is measure in tenths of microseconds
+               and stored in quadwords (64 bit integers).  unix_epoch
+               below is January 1st 1970 expressed as a VMS time.  The
+               following code was used to get this number:
+
+               #include <stdio.h>
+               #include <stdlib.h>
+               #include <lib$routines.h>
+               #include <starlet.h>
+
+               main()
+               {
+                 unsigned long systime[2];
+                 unsigned short epoch_values[7] =
+                   { 1970, 1, 1, 0, 0, 0, 0 };
+
+                 lib$cvt_vectim(epoch_values, systime);
+
+                 printf("%u %u", systime[0], systime[1]);
+               }
+            */
+            unsigned long unix_epoch[2] = { 1273708544, 8164711 };
+            unsigned long deltatime[2];
+            unsigned long systime[2];
+            struct vms_vectime {
+                short year, month, day, hour, minute, second, centi_second;
+            } time_values;
+            long operation;
+
+            /*
+             * Turn the number of seconds since January 1st 1970 to an
+             * internal delta time. Note that lib$cvt_to_internal_time() will
+             * assume that t is signed, and will therefore break on 32-bit
+             * systems some time in 2038.
+             */
+            operation = LIB$K_DELTA_SECONDS;
+            status = lib$cvt_to_internal_time(&operation, &t, deltatime);
+
+            /*
+             * Add the delta time with the Unix epoch and we have the current
+             * UTC time in internal format
+             */
+            status = lib$add_times(unix_epoch, deltatime, systime);
+
+            /* Turn the internal time into a time vector */
+            status = sys$numtim(&time_values, systime);
+
+            /* Fill in the struct tm with the result */
+            result->tm_sec = time_values.second;
+            result->tm_min = time_values.minute;
+            result->tm_hour = time_values.hour;
+            result->tm_mday = time_values.day;
+            result->tm_mon = time_values.month - 1;
+            result->tm_year = time_values.year - 1900;
+
+            operation = LIB$K_DAY_OF_WEEK;
+            status = lib$cvt_from_internal_time(&operation,
+                                                &result->tm_wday, systime);
+            result->tm_wday %= 7;
+
+            operation = LIB$K_DAY_OF_YEAR;
+            status = lib$cvt_from_internal_time(&operation,
+                                                &result->tm_yday, systime);
+            result->tm_yday--;
+
+            result->tm_isdst = 0; /* There's no way to know... */
+
+            ts = result;
+        }
+    }
+#endif
+    return ts;
+}
+
+/*
+ * Take a tm structure and add an offset to it. This avoids any OS issues
+ * with restricted date types and overflows which cause the year 2038
+ * problem.
+ */
+
+#define SECS_PER_DAY (24 * 60 * 60)
+
+static long date_to_julian(int y, int m, int d);
+static void julian_to_date(long jd, int *y, int *m, int *d);
+static int julian_adj(const struct tm *tm, int off_day, long offset_sec,
+                      long *pday, int *psec);
+
+int OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec)
+{
+    int time_sec, time_year, time_month, time_day;
+    long time_jd;
+
+    /* Convert time and offset into Julian day and seconds */
+    if (!julian_adj(tm, off_day, offset_sec, &time_jd, &time_sec))
+        return 0;
+
+    /* Convert Julian day back to date */
+
+    julian_to_date(time_jd, &time_year, &time_month, &time_day);
+
+    if (time_year < 1900 || time_year > 9999)
+        return 0;
+
+    /* Update tm structure */
+
+    tm->tm_year = time_year - 1900;
+    tm->tm_mon = time_month - 1;
+    tm->tm_mday = time_day;
+
+    tm->tm_hour = time_sec / 3600;
+    tm->tm_min = (time_sec / 60) % 60;
+    tm->tm_sec = time_sec % 60;
+
+    return 1;
+
+}
+
+int OPENSSL_gmtime_diff(int *pday, int *psec,
+                        const struct tm *from, const struct tm *to)
+{
+    int from_sec, to_sec, diff_sec;
+    long from_jd, to_jd, diff_day;
+    if (!julian_adj(from, 0, 0, &from_jd, &from_sec))
+        return 0;
+    if (!julian_adj(to, 0, 0, &to_jd, &to_sec))
+        return 0;
+    diff_day = to_jd - from_jd;
+    diff_sec = to_sec - from_sec;
+    /* Adjust differences so both positive or both negative */
+    if (diff_day > 0 && diff_sec < 0) {
+        diff_day--;
+        diff_sec += SECS_PER_DAY;
+    }
+    if (diff_day < 0 && diff_sec > 0) {
+        diff_day++;
+        diff_sec -= SECS_PER_DAY;
+    }
+
+    if (pday)
+        *pday = (int)diff_day;
+    if (psec)
+        *psec = diff_sec;
+
+    return 1;
+
+}
+
+/* Convert tm structure and offset into julian day and seconds */
+static int julian_adj(const struct tm *tm, int off_day, long offset_sec,
+                      long *pday, int *psec)
+{
+    int offset_hms, offset_day;
+    long time_jd;
+    int time_year, time_month, time_day;
+    /* split offset into days and day seconds */
+    offset_day = offset_sec / SECS_PER_DAY;
+    /* Avoid sign issues with % operator */
+    offset_hms = offset_sec - (offset_day * SECS_PER_DAY);
+    offset_day += off_day;
+    /* Add current time seconds to offset */
+    offset_hms += tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec;
+    /* Adjust day seconds if overflow */
+    if (offset_hms >= SECS_PER_DAY) {
+        offset_day++;
+        offset_hms -= SECS_PER_DAY;
+    } else if (offset_hms < 0) {
+        offset_day--;
+        offset_hms += SECS_PER_DAY;
+    }
+
+    /*
+     * Convert date of time structure into a Julian day number.
+     */
+
+    time_year = tm->tm_year + 1900;
+    time_month = tm->tm_mon + 1;
+    time_day = tm->tm_mday;
+
+    time_jd = date_to_julian(time_year, time_month, time_day);
+
+    /* Work out Julian day of new date */
+    time_jd += offset_day;
+
+    if (time_jd < 0)
+        return 0;
+
+    *pday = time_jd;
+    *psec = offset_hms;
+    return 1;
+}
+
+/*
+ * Convert date to and from julian day Uses Fliegel & Van Flandern algorithm
+ */
+static long date_to_julian(int y, int m, int d)
+{
+    return (1461 * (y + 4800 + (m - 14) / 12)) / 4 +
+        (367 * (m - 2 - 12 * ((m - 14) / 12))) / 12 -
+        (3 * ((y + 4900 + (m - 14) / 12) / 100)) / 4 + d - 32075;
+}
+
+static void julian_to_date(long jd, int *y, int *m, int *d)
+{
+    long L = jd + 68569;
+    long n = (4 * L) / 146097;
+    long i, j;
+
+    L = L - (146097 * n + 3) / 4;
+    i = (4000 * (L + 1)) / 1461001;
+    L = L - (1461 * i) / 4 + 31;
+    j = (80 * L) / 2447;
+    *d = L - (2447 * j) / 80;
+    L = j / 11;
+    *m = j + 2 - (12 * L);
+    *y = 100 * (n - 49) + i + L;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/o_names.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/o_names.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/o_names.c	(revision 331)
@@ -0,0 +1,370 @@
+/*
+ * Copyright 1998-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/err.h>
+#include <openssl/lhash.h>
+#include <openssl/objects.h>
+#include <openssl/safestack.h>
+#include <openssl/e_os2.h>
+#include "obj_lcl.h"
+
+/*
+ * We define this wrapper for two reasons. Firstly, later versions of
+ * DEC C add linkage information to certain functions, which makes it
+ * tricky to use them as values to regular function pointers.
+ * Secondly, in the EDK2 build environment, the strcmp function is
+ * actually an external function (AsciiStrCmp) with the Microsoft ABI,
+ * so we can't transparently assign function pointers to it.
+ * Arguably the latter is a stupidity of the UEFI environment, but
+ * since the wrapper solves the DEC C issue too, let's just use the
+ * same solution.
+ */
+#if defined(OPENSSL_SYS_VMS_DECC) || defined(OPENSSL_SYS_UEFI)
+static int obj_strcmp(const char *a, const char *b)
+{
+    return strcmp(a, b);
+}
+#else
+#define obj_strcmp strcmp
+#endif
+
+/*
+ * I use the ex_data stuff to manage the identifiers for the obj_name_types
+ * that applications may define.  I only really use the free function field.
+ */
+static LHASH_OF(OBJ_NAME) *names_lh = NULL;
+static int names_type_num = OBJ_NAME_TYPE_NUM;
+
+struct name_funcs_st {
+    unsigned long (*hash_func) (const char *name);
+    int (*cmp_func) (const char *a, const char *b);
+    void (*free_func) (const char *, int, const char *);
+};
+
+static STACK_OF(NAME_FUNCS) *name_funcs_stack;
+
+/*
+ * The LHASH callbacks now use the raw "void *" prototypes and do
+ * per-variable casting in the functions. This prevents function pointer
+ * casting without the need for macro-generated wrapper functions.
+ */
+
+static unsigned long obj_name_hash(const OBJ_NAME *a);
+static int obj_name_cmp(const OBJ_NAME *a, const OBJ_NAME *b);
+
+int OBJ_NAME_init(void)
+{
+    if (names_lh != NULL)
+        return (1);
+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
+    names_lh = lh_OBJ_NAME_new(obj_name_hash, obj_name_cmp);
+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
+    return (names_lh != NULL);
+}
+
+int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *),
+                       int (*cmp_func) (const char *, const char *),
+                       void (*free_func) (const char *, int, const char *))
+{
+    int ret, i, push;
+    NAME_FUNCS *name_funcs;
+
+    if (name_funcs_stack == NULL) {
+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
+        name_funcs_stack = sk_NAME_FUNCS_new_null();
+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
+    }
+    if (name_funcs_stack == NULL) {
+        /* ERROR */
+        return (0);
+    }
+    ret = names_type_num;
+    names_type_num++;
+    for (i = sk_NAME_FUNCS_num(name_funcs_stack); i < names_type_num; i++) {
+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
+        name_funcs = OPENSSL_zalloc(sizeof(*name_funcs));
+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
+        if (name_funcs == NULL) {
+            OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX, ERR_R_MALLOC_FAILURE);
+            return (0);
+        }
+        name_funcs->hash_func = OPENSSL_LH_strhash;
+        name_funcs->cmp_func = obj_strcmp;
+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
+
+        push = sk_NAME_FUNCS_push(name_funcs_stack, name_funcs);
+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
+
+        if (!push) {
+            OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX, ERR_R_MALLOC_FAILURE);
+            OPENSSL_free(name_funcs);
+            return 0;
+        }
+    }
+    name_funcs = sk_NAME_FUNCS_value(name_funcs_stack, ret);
+    if (hash_func != NULL)
+        name_funcs->hash_func = hash_func;
+    if (cmp_func != NULL)
+        name_funcs->cmp_func = cmp_func;
+    if (free_func != NULL)
+        name_funcs->free_func = free_func;
+    return (ret);
+}
+
+static int obj_name_cmp(const OBJ_NAME *a, const OBJ_NAME *b)
+{
+    int ret;
+
+    ret = a->type - b->type;
+    if (ret == 0) {
+        if ((name_funcs_stack != NULL)
+            && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) {
+            ret = sk_NAME_FUNCS_value(name_funcs_stack,
+                                      a->type)->cmp_func(a->name, b->name);
+        } else
+            ret = strcmp(a->name, b->name);
+    }
+    return (ret);
+}
+
+static unsigned long obj_name_hash(const OBJ_NAME *a)
+{
+    unsigned long ret;
+
+    if ((name_funcs_stack != NULL)
+        && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) {
+        ret =
+            sk_NAME_FUNCS_value(name_funcs_stack,
+                                a->type)->hash_func(a->name);
+    } else {
+        ret = OPENSSL_LH_strhash(a->name);
+    }
+    ret ^= a->type;
+    return (ret);
+}
+
+const char *OBJ_NAME_get(const char *name, int type)
+{
+    OBJ_NAME on, *ret;
+    int num = 0, alias;
+
+    if (name == NULL)
+        return (NULL);
+    if ((names_lh == NULL) && !OBJ_NAME_init())
+        return (NULL);
+
+    alias = type & OBJ_NAME_ALIAS;
+    type &= ~OBJ_NAME_ALIAS;
+
+    on.name = name;
+    on.type = type;
+
+    for (;;) {
+        ret = lh_OBJ_NAME_retrieve(names_lh, &on);
+        if (ret == NULL)
+            return (NULL);
+        if ((ret->alias) && !alias) {
+            if (++num > 10)
+                return (NULL);
+            on.name = ret->data;
+        } else {
+            return (ret->data);
+        }
+    }
+}
+
+int OBJ_NAME_add(const char *name, int type, const char *data)
+{
+    OBJ_NAME *onp, *ret;
+    int alias;
+
+    if ((names_lh == NULL) && !OBJ_NAME_init())
+        return (0);
+
+    alias = type & OBJ_NAME_ALIAS;
+    type &= ~OBJ_NAME_ALIAS;
+
+    onp = OPENSSL_malloc(sizeof(*onp));
+    if (onp == NULL) {
+        /* ERROR */
+        return 0;
+    }
+
+    onp->name = name;
+    onp->alias = alias;
+    onp->type = type;
+    onp->data = data;
+
+    ret = lh_OBJ_NAME_insert(names_lh, onp);
+    if (ret != NULL) {
+        /* free things */
+        if ((name_funcs_stack != NULL)
+            && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) {
+            /*
+             * XXX: I'm not sure I understand why the free function should
+             * get three arguments... -- Richard Levitte
+             */
+            sk_NAME_FUNCS_value(name_funcs_stack,
+                                ret->type)->free_func(ret->name, ret->type,
+                                                      ret->data);
+        }
+        OPENSSL_free(ret);
+    } else {
+        if (lh_OBJ_NAME_error(names_lh)) {
+            /* ERROR */
+            OPENSSL_free(onp);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+int OBJ_NAME_remove(const char *name, int type)
+{
+    OBJ_NAME on, *ret;
+
+    if (names_lh == NULL)
+        return (0);
+
+    type &= ~OBJ_NAME_ALIAS;
+    on.name = name;
+    on.type = type;
+    ret = lh_OBJ_NAME_delete(names_lh, &on);
+    if (ret != NULL) {
+        /* free things */
+        if ((name_funcs_stack != NULL)
+            && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) {
+            /*
+             * XXX: I'm not sure I understand why the free function should
+             * get three arguments... -- Richard Levitte
+             */
+            sk_NAME_FUNCS_value(name_funcs_stack,
+                                ret->type)->free_func(ret->name, ret->type,
+                                                      ret->data);
+        }
+        OPENSSL_free(ret);
+        return (1);
+    } else
+        return (0);
+}
+
+typedef struct {
+    int type;
+    void (*fn) (const OBJ_NAME *, void *arg);
+    void *arg;
+} OBJ_DOALL;
+
+static void do_all_fn(const OBJ_NAME *name, OBJ_DOALL *d)
+{
+    if (name->type == d->type)
+        d->fn(name, d->arg);
+}
+
+IMPLEMENT_LHASH_DOALL_ARG_CONST(OBJ_NAME, OBJ_DOALL);
+
+void OBJ_NAME_do_all(int type, void (*fn) (const OBJ_NAME *, void *arg),
+                     void *arg)
+{
+    OBJ_DOALL d;
+
+    d.type = type;
+    d.fn = fn;
+    d.arg = arg;
+
+    lh_OBJ_NAME_doall_OBJ_DOALL(names_lh, do_all_fn, &d);
+}
+
+struct doall_sorted {
+    int type;
+    int n;
+    const OBJ_NAME **names;
+};
+
+static void do_all_sorted_fn(const OBJ_NAME *name, void *d_)
+{
+    struct doall_sorted *d = d_;
+
+    if (name->type != d->type)
+        return;
+
+    d->names[d->n++] = name;
+}
+
+static int do_all_sorted_cmp(const void *n1_, const void *n2_)
+{
+    const OBJ_NAME *const *n1 = n1_;
+    const OBJ_NAME *const *n2 = n2_;
+
+    return strcmp((*n1)->name, (*n2)->name);
+}
+
+void OBJ_NAME_do_all_sorted(int type,
+                            void (*fn) (const OBJ_NAME *, void *arg),
+                            void *arg)
+{
+    struct doall_sorted d;
+    int n;
+
+    d.type = type;
+    d.names =
+        OPENSSL_malloc(sizeof(*d.names) * lh_OBJ_NAME_num_items(names_lh));
+    /* Really should return an error if !d.names...but its a void function! */
+    if (d.names != NULL) {
+        d.n = 0;
+        OBJ_NAME_do_all(type, do_all_sorted_fn, &d);
+
+        qsort((void *)d.names, d.n, sizeof(*d.names), do_all_sorted_cmp);
+
+        for (n = 0; n < d.n; ++n)
+            fn(d.names[n], arg);
+
+        OPENSSL_free((void *)d.names);
+    }
+}
+
+static int free_type;
+
+static void names_lh_free_doall(OBJ_NAME *onp)
+{
+    if (onp == NULL)
+        return;
+
+    if (free_type < 0 || free_type == onp->type)
+        OBJ_NAME_remove(onp->name, onp->type);
+}
+
+static void name_funcs_free(NAME_FUNCS *ptr)
+{
+    OPENSSL_free(ptr);
+}
+
+void OBJ_NAME_cleanup(int type)
+{
+    unsigned long down_load;
+
+    if (names_lh == NULL)
+        return;
+
+    free_type = type;
+    down_load = lh_OBJ_NAME_get_down_load(names_lh);
+    lh_OBJ_NAME_set_down_load(names_lh, 0);
+
+    lh_OBJ_NAME_doall(names_lh, names_lh_free_doall);
+    if (type < 0) {
+        lh_OBJ_NAME_free(names_lh);
+        sk_NAME_FUNCS_pop_free(name_funcs_stack, name_funcs_free);
+        names_lh = NULL;
+        name_funcs_stack = NULL;
+    } else
+        lh_OBJ_NAME_set_down_load(names_lh, down_load);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_dat.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_dat.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_dat.c	(revision 331)
@@ -0,0 +1,728 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <ctype.h>
+#include <limits.h>
+#include "internal/cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/asn1.h>
+#include "internal/objects.h"
+#include <openssl/bn.h>
+#include "internal/asn1_int.h"
+#include "obj_lcl.h"
+
+/* obj_dat.h is generated from objects.h by obj_dat.pl */
+#include "obj_dat.h"
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
+DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
+DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
+
+#define ADDED_DATA      0
+#define ADDED_SNAME     1
+#define ADDED_LNAME     2
+#define ADDED_NID       3
+
+struct added_obj_st {
+    int type;
+    ASN1_OBJECT *obj;
+};
+
+static int new_nid = NUM_NID;
+static LHASH_OF(ADDED_OBJ) *added = NULL;
+
+static int sn_cmp(const ASN1_OBJECT *const *a, const unsigned int *b)
+{
+    return (strcmp((*a)->sn, nid_objs[*b].sn));
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn);
+
+static int ln_cmp(const ASN1_OBJECT *const *a, const unsigned int *b)
+{
+    return (strcmp((*a)->ln, nid_objs[*b].ln));
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln);
+
+static unsigned long added_obj_hash(const ADDED_OBJ *ca)
+{
+    const ASN1_OBJECT *a;
+    int i;
+    unsigned long ret = 0;
+    unsigned char *p;
+
+    a = ca->obj;
+    switch (ca->type) {
+    case ADDED_DATA:
+        ret = a->length << 20L;
+        p = (unsigned char *)a->data;
+        for (i = 0; i < a->length; i++)
+            ret ^= p[i] << ((i * 3) % 24);
+        break;
+    case ADDED_SNAME:
+        ret = OPENSSL_LH_strhash(a->sn);
+        break;
+    case ADDED_LNAME:
+        ret = OPENSSL_LH_strhash(a->ln);
+        break;
+    case ADDED_NID:
+        ret = a->nid;
+        break;
+    default:
+        /* abort(); */
+        return 0;
+    }
+    ret &= 0x3fffffffL;
+    ret |= ((unsigned long)ca->type) << 30L;
+    return (ret);
+}
+
+static int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb)
+{
+    ASN1_OBJECT *a, *b;
+    int i;
+
+    i = ca->type - cb->type;
+    if (i)
+        return (i);
+    a = ca->obj;
+    b = cb->obj;
+    switch (ca->type) {
+    case ADDED_DATA:
+        i = (a->length - b->length);
+        if (i)
+            return (i);
+        return (memcmp(a->data, b->data, (size_t)a->length));
+    case ADDED_SNAME:
+        if (a->sn == NULL)
+            return (-1);
+        else if (b->sn == NULL)
+            return (1);
+        else
+            return (strcmp(a->sn, b->sn));
+    case ADDED_LNAME:
+        if (a->ln == NULL)
+            return (-1);
+        else if (b->ln == NULL)
+            return (1);
+        else
+            return (strcmp(a->ln, b->ln));
+    case ADDED_NID:
+        return (a->nid - b->nid);
+    default:
+        /* abort(); */
+        return 0;
+    }
+}
+
+static int init_added(void)
+{
+    if (added != NULL)
+        return (1);
+    added = lh_ADDED_OBJ_new(added_obj_hash, added_obj_cmp);
+    return (added != NULL);
+}
+
+static void cleanup1_doall(ADDED_OBJ *a)
+{
+    a->obj->nid = 0;
+    a->obj->flags |= ASN1_OBJECT_FLAG_DYNAMIC |
+        ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+}
+
+static void cleanup2_doall(ADDED_OBJ *a)
+{
+    a->obj->nid++;
+}
+
+static void cleanup3_doall(ADDED_OBJ *a)
+{
+    if (--a->obj->nid == 0)
+        ASN1_OBJECT_free(a->obj);
+    OPENSSL_free(a);
+}
+
+void obj_cleanup_int(void)
+{
+    if (added == NULL)
+        return;
+    lh_ADDED_OBJ_set_down_load(added, 0);
+    lh_ADDED_OBJ_doall(added, cleanup1_doall); /* zero counters */
+    lh_ADDED_OBJ_doall(added, cleanup2_doall); /* set counters */
+    lh_ADDED_OBJ_doall(added, cleanup3_doall); /* free objects */
+    lh_ADDED_OBJ_free(added);
+    added = NULL;
+}
+
+int OBJ_new_nid(int num)
+{
+    int i;
+
+    i = new_nid;
+    new_nid += num;
+    return (i);
+}
+
+int OBJ_add_object(const ASN1_OBJECT *obj)
+{
+    ASN1_OBJECT *o;
+    ADDED_OBJ *ao[4] = { NULL, NULL, NULL, NULL }, *aop;
+    int i;
+
+    if (added == NULL)
+        if (!init_added())
+            return (0);
+    if ((o = OBJ_dup(obj)) == NULL)
+        goto err;
+    if ((ao[ADDED_NID] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)
+        goto err2;
+    if ((o->length != 0) && (obj->data != NULL))
+        if ((ao[ADDED_DATA] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)
+            goto err2;
+    if (o->sn != NULL)
+        if ((ao[ADDED_SNAME] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)
+            goto err2;
+    if (o->ln != NULL)
+        if ((ao[ADDED_LNAME] = OPENSSL_malloc(sizeof(*ao[0]))) == NULL)
+            goto err2;
+
+    for (i = ADDED_DATA; i <= ADDED_NID; i++) {
+        if (ao[i] != NULL) {
+            ao[i]->type = i;
+            ao[i]->obj = o;
+            aop = lh_ADDED_OBJ_insert(added, ao[i]);
+            /* memory leak, but should not normally matter */
+            OPENSSL_free(aop);
+        }
+    }
+    o->flags &=
+        ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
+          ASN1_OBJECT_FLAG_DYNAMIC_DATA);
+
+    return (o->nid);
+ err2:
+    OBJerr(OBJ_F_OBJ_ADD_OBJECT, ERR_R_MALLOC_FAILURE);
+ err:
+    for (i = ADDED_DATA; i <= ADDED_NID; i++)
+        OPENSSL_free(ao[i]);
+    OPENSSL_free(o);
+    return (NID_undef);
+}
+
+ASN1_OBJECT *OBJ_nid2obj(int n)
+{
+    ADDED_OBJ ad, *adp;
+    ASN1_OBJECT ob;
+
+    if ((n >= 0) && (n < NUM_NID)) {
+        if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
+            OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID);
+            return (NULL);
+        }
+        return ((ASN1_OBJECT *)&(nid_objs[n]));
+    } else if (added == NULL)
+        return (NULL);
+    else {
+        ad.type = ADDED_NID;
+        ad.obj = &ob;
+        ob.nid = n;
+        adp = lh_ADDED_OBJ_retrieve(added, &ad);
+        if (adp != NULL)
+            return (adp->obj);
+        else {
+            OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID);
+            return (NULL);
+        }
+    }
+}
+
+const char *OBJ_nid2sn(int n)
+{
+    ADDED_OBJ ad, *adp;
+    ASN1_OBJECT ob;
+
+    if ((n >= 0) && (n < NUM_NID)) {
+        if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
+            OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID);
+            return (NULL);
+        }
+        return (nid_objs[n].sn);
+    } else if (added == NULL)
+        return (NULL);
+    else {
+        ad.type = ADDED_NID;
+        ad.obj = &ob;
+        ob.nid = n;
+        adp = lh_ADDED_OBJ_retrieve(added, &ad);
+        if (adp != NULL)
+            return (adp->obj->sn);
+        else {
+            OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID);
+            return (NULL);
+        }
+    }
+}
+
+const char *OBJ_nid2ln(int n)
+{
+    ADDED_OBJ ad, *adp;
+    ASN1_OBJECT ob;
+
+    if ((n >= 0) && (n < NUM_NID)) {
+        if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) {
+            OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID);
+            return (NULL);
+        }
+        return (nid_objs[n].ln);
+    } else if (added == NULL)
+        return (NULL);
+    else {
+        ad.type = ADDED_NID;
+        ad.obj = &ob;
+        ob.nid = n;
+        adp = lh_ADDED_OBJ_retrieve(added, &ad);
+        if (adp != NULL)
+            return (adp->obj->ln);
+        else {
+            OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID);
+            return (NULL);
+        }
+    }
+}
+
+static int obj_cmp(const ASN1_OBJECT *const *ap, const unsigned int *bp)
+{
+    int j;
+    const ASN1_OBJECT *a = *ap;
+    const ASN1_OBJECT *b = &nid_objs[*bp];
+
+    j = (a->length - b->length);
+    if (j)
+        return (j);
+    if (a->length == 0)
+        return 0;
+    return (memcmp(a->data, b->data, a->length));
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
+
+int OBJ_obj2nid(const ASN1_OBJECT *a)
+{
+    const unsigned int *op;
+    ADDED_OBJ ad, *adp;
+
+    if (a == NULL)
+        return (NID_undef);
+    if (a->nid != 0)
+        return (a->nid);
+
+    if (a->length == 0)
+        return NID_undef;
+
+    if (added != NULL) {
+        ad.type = ADDED_DATA;
+        ad.obj = (ASN1_OBJECT *)a; /* XXX: ugly but harmless */
+        adp = lh_ADDED_OBJ_retrieve(added, &ad);
+        if (adp != NULL)
+            return (adp->obj->nid);
+    }
+    op = OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ);
+    if (op == NULL)
+        return (NID_undef);
+    return (nid_objs[*op].nid);
+}
+
+/*
+ * Convert an object name into an ASN1_OBJECT if "noname" is not set then
+ * search for short and long names first. This will convert the "dotted" form
+ * into an object: unlike OBJ_txt2nid it can be used with any objects, not
+ * just registered ones.
+ */
+
+ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name)
+{
+    int nid = NID_undef;
+    ASN1_OBJECT *op = NULL;
+    unsigned char *buf;
+    unsigned char *p;
+    const unsigned char *cp;
+    int i, j;
+
+    if (!no_name) {
+        if (((nid = OBJ_sn2nid(s)) != NID_undef) ||
+            ((nid = OBJ_ln2nid(s)) != NID_undef))
+            return OBJ_nid2obj(nid);
+    }
+
+    /* Work out size of content octets */
+    i = a2d_ASN1_OBJECT(NULL, 0, s, -1);
+    if (i <= 0) {
+        /* Don't clear the error */
+        /*
+         * ERR_clear_error();
+         */
+        return NULL;
+    }
+    /* Work out total size */
+    j = ASN1_object_size(0, i, V_ASN1_OBJECT);
+    if (j < 0)
+        return NULL;
+
+    if ((buf = OPENSSL_malloc(j)) == NULL)
+        return NULL;
+
+    p = buf;
+    /* Write out tag+length */
+    ASN1_put_object(&p, 0, i, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
+    /* Write out contents */
+    a2d_ASN1_OBJECT(p, i, s, -1);
+
+    cp = buf;
+    op = d2i_ASN1_OBJECT(NULL, &cp, j);
+    OPENSSL_free(buf);
+    return op;
+}
+
+int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
+{
+    int i, n = 0, len, nid, first, use_bn;
+    BIGNUM *bl;
+    unsigned long l;
+    const unsigned char *p;
+    char tbuf[DECIMAL_SIZE(i) + DECIMAL_SIZE(l) + 2];
+
+    /* Ensure that, at every state, |buf| is NUL-terminated. */
+    if (buf && buf_len > 0)
+        buf[0] = '\0';
+
+    if ((a == NULL) || (a->data == NULL))
+        return (0);
+
+    if (!no_name && (nid = OBJ_obj2nid(a)) != NID_undef) {
+        const char *s;
+        s = OBJ_nid2ln(nid);
+        if (s == NULL)
+            s = OBJ_nid2sn(nid);
+        if (s) {
+            if (buf)
+                OPENSSL_strlcpy(buf, s, buf_len);
+            n = strlen(s);
+            return n;
+        }
+    }
+
+    len = a->length;
+    p = a->data;
+
+    first = 1;
+    bl = NULL;
+
+    while (len > 0) {
+        l = 0;
+        use_bn = 0;
+        for (;;) {
+            unsigned char c = *p++;
+            len--;
+            if ((len == 0) && (c & 0x80))
+                goto err;
+            if (use_bn) {
+                if (!BN_add_word(bl, c & 0x7f))
+                    goto err;
+            } else
+                l |= c & 0x7f;
+            if (!(c & 0x80))
+                break;
+            if (!use_bn && (l > (ULONG_MAX >> 7L))) {
+                if (bl == NULL && (bl = BN_new()) == NULL)
+                    goto err;
+                if (!BN_set_word(bl, l))
+                    goto err;
+                use_bn = 1;
+            }
+            if (use_bn) {
+                if (!BN_lshift(bl, bl, 7))
+                    goto err;
+            } else
+                l <<= 7L;
+        }
+
+        if (first) {
+            first = 0;
+            if (l >= 80) {
+                i = 2;
+                if (use_bn) {
+                    if (!BN_sub_word(bl, 80))
+                        goto err;
+                } else
+                    l -= 80;
+            } else {
+                i = (int)(l / 40);
+                l -= (long)(i * 40);
+            }
+            if (buf && (buf_len > 1)) {
+                *buf++ = i + '0';
+                *buf = '\0';
+                buf_len--;
+            }
+            n++;
+        }
+
+        if (use_bn) {
+            char *bndec;
+            bndec = BN_bn2dec(bl);
+            if (!bndec)
+                goto err;
+            i = strlen(bndec);
+            if (buf) {
+                if (buf_len > 1) {
+                    *buf++ = '.';
+                    *buf = '\0';
+                    buf_len--;
+                }
+                OPENSSL_strlcpy(buf, bndec, buf_len);
+                if (i > buf_len) {
+                    buf += buf_len;
+                    buf_len = 0;
+                } else {
+                    buf += i;
+                    buf_len -= i;
+                }
+            }
+            n++;
+            n += i;
+            OPENSSL_free(bndec);
+        } else {
+            BIO_snprintf(tbuf, sizeof tbuf, ".%lu", l);
+            i = strlen(tbuf);
+            if (buf && (buf_len > 0)) {
+                OPENSSL_strlcpy(buf, tbuf, buf_len);
+                if (i > buf_len) {
+                    buf += buf_len;
+                    buf_len = 0;
+                } else {
+                    buf += i;
+                    buf_len -= i;
+                }
+            }
+            n += i;
+            l = 0;
+        }
+    }
+
+    BN_free(bl);
+    return n;
+
+ err:
+    BN_free(bl);
+    return -1;
+}
+
+int OBJ_txt2nid(const char *s)
+{
+    ASN1_OBJECT *obj;
+    int nid;
+    obj = OBJ_txt2obj(s, 0);
+    nid = OBJ_obj2nid(obj);
+    ASN1_OBJECT_free(obj);
+    return nid;
+}
+
+int OBJ_ln2nid(const char *s)
+{
+    ASN1_OBJECT o;
+    const ASN1_OBJECT *oo = &o;
+    ADDED_OBJ ad, *adp;
+    const unsigned int *op;
+
+    o.ln = s;
+    if (added != NULL) {
+        ad.type = ADDED_LNAME;
+        ad.obj = &o;
+        adp = lh_ADDED_OBJ_retrieve(added, &ad);
+        if (adp != NULL)
+            return (adp->obj->nid);
+    }
+    op = OBJ_bsearch_ln(&oo, ln_objs, NUM_LN);
+    if (op == NULL)
+        return (NID_undef);
+    return (nid_objs[*op].nid);
+}
+
+int OBJ_sn2nid(const char *s)
+{
+    ASN1_OBJECT o;
+    const ASN1_OBJECT *oo = &o;
+    ADDED_OBJ ad, *adp;
+    const unsigned int *op;
+
+    o.sn = s;
+    if (added != NULL) {
+        ad.type = ADDED_SNAME;
+        ad.obj = &o;
+        adp = lh_ADDED_OBJ_retrieve(added, &ad);
+        if (adp != NULL)
+            return (adp->obj->nid);
+    }
+    op = OBJ_bsearch_sn(&oo, sn_objs, NUM_SN);
+    if (op == NULL)
+        return (NID_undef);
+    return (nid_objs[*op].nid);
+}
+
+const void *OBJ_bsearch_(const void *key, const void *base, int num, int size,
+                         int (*cmp) (const void *, const void *))
+{
+    return OBJ_bsearch_ex_(key, base, num, size, cmp, 0);
+}
+
+const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num,
+                            int size,
+                            int (*cmp) (const void *, const void *),
+                            int flags)
+{
+    const char *base = base_;
+    int l, h, i = 0, c = 0;
+    const char *p = NULL;
+
+    if (num == 0)
+        return (NULL);
+    l = 0;
+    h = num;
+    while (l < h) {
+        i = (l + h) / 2;
+        p = &(base[i * size]);
+        c = (*cmp) (key, p);
+        if (c < 0)
+            h = i;
+        else if (c > 0)
+            l = i + 1;
+        else
+            break;
+    }
+#ifdef CHARSET_EBCDIC
+    /*
+     * THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and I
+     * don't have perl (yet), we revert to a *LINEAR* search when the object
+     * wasn't found in the binary search.
+     */
+    if (c != 0) {
+        for (i = 0; i < num; ++i) {
+            p = &(base[i * size]);
+            c = (*cmp) (key, p);
+            if (c == 0 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
+                return p;
+        }
+    }
+#endif
+    if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))
+        p = NULL;
+    else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH)) {
+        while (i > 0 && (*cmp) (key, &(base[(i - 1) * size])) == 0)
+            i--;
+        p = &(base[i * size]);
+    }
+    return (p);
+}
+
+int OBJ_create_objects(BIO *in)
+{
+    char buf[512];
+    int i, num = 0;
+    char *o, *s, *l = NULL;
+
+    for (;;) {
+        s = o = NULL;
+        i = BIO_gets(in, buf, 512);
+        if (i <= 0)
+            return (num);
+        buf[i - 1] = '\0';
+        if (!isalnum((unsigned char)buf[0]))
+            return (num);
+        o = s = buf;
+        while (isdigit((unsigned char)*s) || (*s == '.'))
+            s++;
+        if (*s != '\0') {
+            *(s++) = '\0';
+            while (isspace((unsigned char)*s))
+                s++;
+            if (*s == '\0')
+                s = NULL;
+            else {
+                l = s;
+                while ((*l != '\0') && !isspace((unsigned char)*l))
+                    l++;
+                if (*l != '\0') {
+                    *(l++) = '\0';
+                    while (isspace((unsigned char)*l))
+                        l++;
+                    if (*l == '\0')
+                        l = NULL;
+                } else
+                    l = NULL;
+            }
+        } else
+            s = NULL;
+        if ((o == NULL) || (*o == '\0'))
+            return (num);
+        if (!OBJ_create(o, s, l))
+            return (num);
+        num++;
+    }
+    /* return(num); */
+}
+
+int OBJ_create(const char *oid, const char *sn, const char *ln)
+{
+    ASN1_OBJECT *tmpoid = NULL;
+    int ok = 0;
+
+    /* Check to see if short or long name already present */
+    if (OBJ_sn2nid(sn) != NID_undef || OBJ_ln2nid(ln) != NID_undef) {
+        OBJerr(OBJ_F_OBJ_CREATE, OBJ_R_OID_EXISTS);
+        return 0;
+    }
+
+    /* Convert numerical OID string to an ASN1_OBJECT structure */
+    tmpoid = OBJ_txt2obj(oid, 1);
+
+    /* If NID is not NID_undef then object already exists */
+    if (OBJ_obj2nid(tmpoid) != NID_undef) {
+        OBJerr(OBJ_F_OBJ_CREATE, OBJ_R_OID_EXISTS);
+        goto err;
+    }
+
+    tmpoid->nid = OBJ_new_nid(1);
+    tmpoid->sn = (char *)sn;
+    tmpoid->ln = (char *)ln;
+
+    ok = OBJ_add_object(tmpoid);
+
+    tmpoid->sn = NULL;
+    tmpoid->ln = NULL;
+
+ err:
+    ASN1_OBJECT_free(tmpoid);
+    return ok;
+}
+
+size_t OBJ_length(const ASN1_OBJECT *obj)
+{
+    if (obj == NULL)
+        return 0;
+    return obj->length;
+}
+
+const unsigned char *OBJ_get0_data(const ASN1_OBJECT *obj)
+{
+    if (obj == NULL)
+        return NULL;
+    return obj->data;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_dat.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_dat.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_dat.h	(revision 331)
@@ -0,0 +1,5101 @@
+/*
+ * WARNING: do not edit!
+ * Generated by crypto/objects/obj_dat.pl
+ *
+ * Copyright 1995-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
+ */
+
+/* Serialized OID's */
+static const unsigned char so[6765] = {
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,                 /* [    0] OBJ_rsadsi */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,            /* [    6] OBJ_pkcs */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02,       /* [   13] OBJ_md2 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x05,       /* [   21] OBJ_md5 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x04,       /* [   29] OBJ_rc4 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,  /* [   37] OBJ_rsaEncryption */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x02,  /* [   46] OBJ_md2WithRSAEncryption */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,  /* [   55] OBJ_md5WithRSAEncryption */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x01,  /* [   64] OBJ_pbeWithMD2AndDES_CBC */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x03,  /* [   73] OBJ_pbeWithMD5AndDES_CBC */
+    0x55,                                          /* [   82] OBJ_X500 */
+    0x55,0x04,                                     /* [   83] OBJ_X509 */
+    0x55,0x04,0x03,                                /* [   85] OBJ_commonName */
+    0x55,0x04,0x06,                                /* [   88] OBJ_countryName */
+    0x55,0x04,0x07,                                /* [   91] OBJ_localityName */
+    0x55,0x04,0x08,                                /* [   94] OBJ_stateOrProvinceName */
+    0x55,0x04,0x0A,                                /* [   97] OBJ_organizationName */
+    0x55,0x04,0x0B,                                /* [  100] OBJ_organizationalUnitName */
+    0x55,0x08,0x01,0x01,                           /* [  103] OBJ_rsa */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,       /* [  107] OBJ_pkcs7 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x01,  /* [  115] OBJ_pkcs7_data */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x02,  /* [  124] OBJ_pkcs7_signed */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x03,  /* [  133] OBJ_pkcs7_enveloped */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x04,  /* [  142] OBJ_pkcs7_signedAndEnveloped */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x05,  /* [  151] OBJ_pkcs7_digest */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x06,  /* [  160] OBJ_pkcs7_encrypted */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03,       /* [  169] OBJ_pkcs3 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03,0x01,  /* [  177] OBJ_dhKeyAgreement */
+    0x2B,0x0E,0x03,0x02,0x06,                      /* [  186] OBJ_des_ecb */
+    0x2B,0x0E,0x03,0x02,0x09,                      /* [  191] OBJ_des_cfb64 */
+    0x2B,0x0E,0x03,0x02,0x07,                      /* [  196] OBJ_des_cbc */
+    0x2B,0x0E,0x03,0x02,0x11,                      /* [  201] OBJ_des_ede_ecb */
+    0x2B,0x06,0x01,0x04,0x01,0x81,0x3C,0x07,0x01,0x01,0x02,  /* [  206] OBJ_idea_cbc */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x02,       /* [  217] OBJ_rc2_cbc */
+    0x2B,0x0E,0x03,0x02,0x12,                      /* [  225] OBJ_sha */
+    0x2B,0x0E,0x03,0x02,0x0F,                      /* [  230] OBJ_shaWithRSAEncryption */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x07,       /* [  235] OBJ_des_ede3_cbc */
+    0x2B,0x0E,0x03,0x02,0x08,                      /* [  243] OBJ_des_ofb64 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,       /* [  248] OBJ_pkcs9 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,  /* [  256] OBJ_pkcs9_emailAddress */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x02,  /* [  265] OBJ_pkcs9_unstructuredName */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x03,  /* [  274] OBJ_pkcs9_contentType */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x04,  /* [  283] OBJ_pkcs9_messageDigest */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x05,  /* [  292] OBJ_pkcs9_signingTime */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x06,  /* [  301] OBJ_pkcs9_countersignature */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x07,  /* [  310] OBJ_pkcs9_challengePassword */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x08,  /* [  319] OBJ_pkcs9_unstructuredAddress */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x09,  /* [  328] OBJ_pkcs9_extCertAttributes */
+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,            /* [  337] OBJ_netscape */
+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,       /* [  344] OBJ_netscape_cert_extension */
+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02,       /* [  352] OBJ_netscape_data_type */
+    0x2B,0x0E,0x03,0x02,0x1A,                      /* [  360] OBJ_sha1 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,  /* [  365] OBJ_sha1WithRSAEncryption */
+    0x2B,0x0E,0x03,0x02,0x0D,                      /* [  374] OBJ_dsaWithSHA */
+    0x2B,0x0E,0x03,0x02,0x0C,                      /* [  379] OBJ_dsa_2 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0B,  /* [  384] OBJ_pbeWithSHA1AndRC2_CBC */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0C,  /* [  393] OBJ_id_pbkdf2 */
+    0x2B,0x0E,0x03,0x02,0x1B,                      /* [  402] OBJ_dsaWithSHA1_2 */
+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,  /* [  407] OBJ_netscape_cert_type */
+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x02,  /* [  416] OBJ_netscape_base_url */
+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x03,  /* [  425] OBJ_netscape_revocation_url */
+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x04,  /* [  434] OBJ_netscape_ca_revocation_url */
+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x07,  /* [  443] OBJ_netscape_renewal_url */
+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x08,  /* [  452] OBJ_netscape_ca_policy_url */
+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0C,  /* [  461] OBJ_netscape_ssl_server_name */
+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0D,  /* [  470] OBJ_netscape_comment */
+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02,0x05,  /* [  479] OBJ_netscape_cert_sequence */
+    0x55,0x1D,                                     /* [  488] OBJ_id_ce */
+    0x55,0x1D,0x0E,                                /* [  490] OBJ_subject_key_identifier */
+    0x55,0x1D,0x0F,                                /* [  493] OBJ_key_usage */
+    0x55,0x1D,0x10,                                /* [  496] OBJ_private_key_usage_period */
+    0x55,0x1D,0x11,                                /* [  499] OBJ_subject_alt_name */
+    0x55,0x1D,0x12,                                /* [  502] OBJ_issuer_alt_name */
+    0x55,0x1D,0x13,                                /* [  505] OBJ_basic_constraints */
+    0x55,0x1D,0x14,                                /* [  508] OBJ_crl_number */
+    0x55,0x1D,0x20,                                /* [  511] OBJ_certificate_policies */
+    0x55,0x1D,0x23,                                /* [  514] OBJ_authority_key_identifier */
+    0x2B,0x06,0x01,0x04,0x01,0x97,0x55,0x01,0x02,  /* [  517] OBJ_bf_cbc */
+    0x55,0x08,0x03,0x65,                           /* [  526] OBJ_mdc2 */
+    0x55,0x08,0x03,0x64,                           /* [  530] OBJ_mdc2WithRSA */
+    0x55,0x04,0x2A,                                /* [  534] OBJ_givenName */
+    0x55,0x04,0x04,                                /* [  537] OBJ_surname */
+    0x55,0x04,0x2B,                                /* [  540] OBJ_initials */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2C,  /* [  543] OBJ_uniqueIdentifier */
+    0x55,0x1D,0x1F,                                /* [  553] OBJ_crl_distribution_points */
+    0x2B,0x0E,0x03,0x02,0x03,                      /* [  556] OBJ_md5WithRSA */
+    0x55,0x04,0x05,                                /* [  561] OBJ_serialNumber */
+    0x55,0x04,0x0C,                                /* [  564] OBJ_title */
+    0x55,0x04,0x0D,                                /* [  567] OBJ_description */
+    0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0A,  /* [  570] OBJ_cast5_cbc */
+    0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0C,  /* [  579] OBJ_pbeWithMD5AndCast5_CBC */
+    0x2A,0x86,0x48,0xCE,0x38,0x04,0x03,            /* [  588] OBJ_dsaWithSHA1 */
+    0x2B,0x0E,0x03,0x02,0x1D,                      /* [  595] OBJ_sha1WithRSA */
+    0x2A,0x86,0x48,0xCE,0x38,0x04,0x01,            /* [  600] OBJ_dsa */
+    0x2B,0x24,0x03,0x02,0x01,                      /* [  607] OBJ_ripemd160 */
+    0x2B,0x24,0x03,0x03,0x01,0x02,                 /* [  612] OBJ_ripemd160WithRSA */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x08,       /* [  618] OBJ_rc5_cbc */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x08,  /* [  626] OBJ_zlib_compression */
+    0x55,0x1D,0x25,                                /* [  637] OBJ_ext_key_usage */
+    0x2B,0x06,0x01,0x05,0x05,0x07,                 /* [  640] OBJ_id_pkix */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,            /* [  646] OBJ_id_kp */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01,       /* [  653] OBJ_server_auth */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,       /* [  661] OBJ_client_auth */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x03,       /* [  669] OBJ_code_sign */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x04,       /* [  677] OBJ_email_protect */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x08,       /* [  685] OBJ_time_stamp */
+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x15,  /* [  693] OBJ_ms_code_ind */
+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x16,  /* [  703] OBJ_ms_code_com */
+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x01,  /* [  713] OBJ_ms_ctl_sign */
+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x03,  /* [  723] OBJ_ms_sgc */
+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x04,  /* [  733] OBJ_ms_efs */
+    0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,  /* [  743] OBJ_ns_sgc */
+    0x55,0x1D,0x1B,                                /* [  752] OBJ_delta_crl */
+    0x55,0x1D,0x15,                                /* [  755] OBJ_crl_reason */
+    0x55,0x1D,0x18,                                /* [  758] OBJ_invalidity_date */
+    0x2B,0x65,0x01,0x04,0x01,                      /* [  761] OBJ_sxnet */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x01,  /* [  766] OBJ_pbe_WithSHA1And128BitRC4 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x02,  /* [  776] OBJ_pbe_WithSHA1And40BitRC4 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x03,  /* [  786] OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x04,  /* [  796] OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x05,  /* [  806] OBJ_pbe_WithSHA1And128BitRC2_CBC */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x06,  /* [  816] OBJ_pbe_WithSHA1And40BitRC2_CBC */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x01,  /* [  826] OBJ_keyBag */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x02,  /* [  837] OBJ_pkcs8ShroudedKeyBag */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x03,  /* [  848] OBJ_certBag */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x04,  /* [  859] OBJ_crlBag */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x05,  /* [  870] OBJ_secretBag */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x06,  /* [  881] OBJ_safeContentsBag */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x14,  /* [  892] OBJ_friendlyName */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x15,  /* [  901] OBJ_localKeyID */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x01,  /* [  910] OBJ_x509Certificate */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x02,  /* [  920] OBJ_sdsiCertificate */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x17,0x01,  /* [  930] OBJ_x509Crl */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0D,  /* [  940] OBJ_pbes2 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0E,  /* [  949] OBJ_pbmac1 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x07,       /* [  958] OBJ_hmacWithSHA1 */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01,       /* [  966] OBJ_id_qt_cps */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02,       /* [  974] OBJ_id_qt_unotice */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0F,  /* [  982] OBJ_SMIMECapabilities */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x04,  /* [  991] OBJ_pbeWithMD2AndRC2_CBC */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x06,  /* [ 1000] OBJ_pbeWithMD5AndRC2_CBC */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0A,  /* [ 1009] OBJ_pbeWithSHA1AndDES_CBC */
+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x0E,  /* [ 1018] OBJ_ms_ext_req */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0E,  /* [ 1028] OBJ_ext_req */
+    0x55,0x04,0x29,                                /* [ 1037] OBJ_name */
+    0x55,0x04,0x2E,                                /* [ 1040] OBJ_dnQualifier */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,            /* [ 1043] OBJ_id_pe */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,            /* [ 1050] OBJ_id_ad */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,       /* [ 1057] OBJ_info_access */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,       /* [ 1065] OBJ_ad_OCSP */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,       /* [ 1073] OBJ_ad_ca_issuers */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x09,       /* [ 1081] OBJ_OCSP_sign */
+    0x2A,                                          /* [ 1089] OBJ_member_body */
+    0x2A,0x86,0x48,                                /* [ 1090] OBJ_ISO_US */
+    0x2A,0x86,0x48,0xCE,0x38,                      /* [ 1093] OBJ_X9_57 */
+    0x2A,0x86,0x48,0xCE,0x38,0x04,                 /* [ 1098] OBJ_X9cm */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,       /* [ 1104] OBJ_pkcs1 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,       /* [ 1112] OBJ_pkcs5 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,  /* [ 1120] OBJ_SMIME */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,  /* [ 1129] OBJ_id_smime_mod */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,  /* [ 1139] OBJ_id_smime_ct */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,  /* [ 1149] OBJ_id_smime_aa */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,  /* [ 1159] OBJ_id_smime_alg */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,  /* [ 1169] OBJ_id_smime_cd */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,  /* [ 1179] OBJ_id_smime_spq */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,  /* [ 1189] OBJ_id_smime_cti */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x01,  /* [ 1199] OBJ_id_smime_mod_cms */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x02,  /* [ 1210] OBJ_id_smime_mod_ess */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x03,  /* [ 1221] OBJ_id_smime_mod_oid */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x04,  /* [ 1232] OBJ_id_smime_mod_msg_v3 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x05,  /* [ 1243] OBJ_id_smime_mod_ets_eSignature_88 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x06,  /* [ 1254] OBJ_id_smime_mod_ets_eSignature_97 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x07,  /* [ 1265] OBJ_id_smime_mod_ets_eSigPolicy_88 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x08,  /* [ 1276] OBJ_id_smime_mod_ets_eSigPolicy_97 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x01,  /* [ 1287] OBJ_id_smime_ct_receipt */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x02,  /* [ 1298] OBJ_id_smime_ct_authData */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x03,  /* [ 1309] OBJ_id_smime_ct_publishCert */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x04,  /* [ 1320] OBJ_id_smime_ct_TSTInfo */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x05,  /* [ 1331] OBJ_id_smime_ct_TDTInfo */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x06,  /* [ 1342] OBJ_id_smime_ct_contentInfo */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x07,  /* [ 1353] OBJ_id_smime_ct_DVCSRequestData */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x08,  /* [ 1364] OBJ_id_smime_ct_DVCSResponseData */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x01,  /* [ 1375] OBJ_id_smime_aa_receiptRequest */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x02,  /* [ 1386] OBJ_id_smime_aa_securityLabel */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x03,  /* [ 1397] OBJ_id_smime_aa_mlExpandHistory */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x04,  /* [ 1408] OBJ_id_smime_aa_contentHint */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x05,  /* [ 1419] OBJ_id_smime_aa_msgSigDigest */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x06,  /* [ 1430] OBJ_id_smime_aa_encapContentType */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x07,  /* [ 1441] OBJ_id_smime_aa_contentIdentifier */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x08,  /* [ 1452] OBJ_id_smime_aa_macValue */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x09,  /* [ 1463] OBJ_id_smime_aa_equivalentLabels */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0A,  /* [ 1474] OBJ_id_smime_aa_contentReference */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0B,  /* [ 1485] OBJ_id_smime_aa_encrypKeyPref */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0C,  /* [ 1496] OBJ_id_smime_aa_signingCertificate */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0D,  /* [ 1507] OBJ_id_smime_aa_smimeEncryptCerts */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0E,  /* [ 1518] OBJ_id_smime_aa_timeStampToken */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0F,  /* [ 1529] OBJ_id_smime_aa_ets_sigPolicyId */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x10,  /* [ 1540] OBJ_id_smime_aa_ets_commitmentType */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x11,  /* [ 1551] OBJ_id_smime_aa_ets_signerLocation */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x12,  /* [ 1562] OBJ_id_smime_aa_ets_signerAttr */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x13,  /* [ 1573] OBJ_id_smime_aa_ets_otherSigCert */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x14,  /* [ 1584] OBJ_id_smime_aa_ets_contentTimestamp */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x15,  /* [ 1595] OBJ_id_smime_aa_ets_CertificateRefs */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x16,  /* [ 1606] OBJ_id_smime_aa_ets_RevocationRefs */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x17,  /* [ 1617] OBJ_id_smime_aa_ets_certValues */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x18,  /* [ 1628] OBJ_id_smime_aa_ets_revocationValues */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x19,  /* [ 1639] OBJ_id_smime_aa_ets_escTimeStamp */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1A,  /* [ 1650] OBJ_id_smime_aa_ets_certCRLTimestamp */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1B,  /* [ 1661] OBJ_id_smime_aa_ets_archiveTimeStamp */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1C,  /* [ 1672] OBJ_id_smime_aa_signatureType */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1D,  /* [ 1683] OBJ_id_smime_aa_dvcs_dvc */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x01,  /* [ 1694] OBJ_id_smime_alg_ESDHwith3DES */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x02,  /* [ 1705] OBJ_id_smime_alg_ESDHwithRC2 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x03,  /* [ 1716] OBJ_id_smime_alg_3DESwrap */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x04,  /* [ 1727] OBJ_id_smime_alg_RC2wrap */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x05,  /* [ 1738] OBJ_id_smime_alg_ESDH */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x06,  /* [ 1749] OBJ_id_smime_alg_CMS3DESwrap */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x07,  /* [ 1760] OBJ_id_smime_alg_CMSRC2wrap */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,0x01,  /* [ 1771] OBJ_id_smime_cd_ldap */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x01,  /* [ 1782] OBJ_id_smime_spq_ets_sqt_uri */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x02,  /* [ 1793] OBJ_id_smime_spq_ets_sqt_unotice */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x01,  /* [ 1804] OBJ_id_smime_cti_ets_proofOfOrigin */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x02,  /* [ 1815] OBJ_id_smime_cti_ets_proofOfReceipt */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x03,  /* [ 1826] OBJ_id_smime_cti_ets_proofOfDelivery */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x04,  /* [ 1837] OBJ_id_smime_cti_ets_proofOfSender */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x05,  /* [ 1848] OBJ_id_smime_cti_ets_proofOfApproval */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x06,  /* [ 1859] OBJ_id_smime_cti_ets_proofOfCreation */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x04,       /* [ 1870] OBJ_md4 */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,            /* [ 1878] OBJ_id_pkix_mod */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x02,            /* [ 1885] OBJ_id_qt */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,            /* [ 1892] OBJ_id_it */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,            /* [ 1899] OBJ_id_pkip */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x06,            /* [ 1906] OBJ_id_alg */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,            /* [ 1913] OBJ_id_cmc */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x08,            /* [ 1920] OBJ_id_on */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x09,            /* [ 1927] OBJ_id_pda */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,            /* [ 1934] OBJ_id_aca */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0B,            /* [ 1941] OBJ_id_qcs */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,            /* [ 1948] OBJ_id_cct */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x01,       /* [ 1955] OBJ_id_pkix1_explicit_88 */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x02,       /* [ 1963] OBJ_id_pkix1_implicit_88 */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x03,       /* [ 1971] OBJ_id_pkix1_explicit_93 */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x04,       /* [ 1979] OBJ_id_pkix1_implicit_93 */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x05,       /* [ 1987] OBJ_id_mod_crmf */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x06,       /* [ 1995] OBJ_id_mod_cmc */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x07,       /* [ 2003] OBJ_id_mod_kea_profile_88 */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x08,       /* [ 2011] OBJ_id_mod_kea_profile_93 */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x09,       /* [ 2019] OBJ_id_mod_cmp */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0A,       /* [ 2027] OBJ_id_mod_qualified_cert_88 */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0B,       /* [ 2035] OBJ_id_mod_qualified_cert_93 */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0C,       /* [ 2043] OBJ_id_mod_attribute_cert */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0D,       /* [ 2051] OBJ_id_mod_timestamp_protocol */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0E,       /* [ 2059] OBJ_id_mod_ocsp */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0F,       /* [ 2067] OBJ_id_mod_dvcs */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x10,       /* [ 2075] OBJ_id_mod_cmp2000 */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x02,       /* [ 2083] OBJ_biometricInfo */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x03,       /* [ 2091] OBJ_qcStatements */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x04,       /* [ 2099] OBJ_ac_auditEntity */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x05,       /* [ 2107] OBJ_ac_targeting */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x06,       /* [ 2115] OBJ_aaControls */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x07,       /* [ 2123] OBJ_sbgp_ipAddrBlock */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x08,       /* [ 2131] OBJ_sbgp_autonomousSysNum */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x09,       /* [ 2139] OBJ_sbgp_routerIdentifier */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x03,       /* [ 2147] OBJ_textNotice */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x05,       /* [ 2155] OBJ_ipsecEndSystem */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x06,       /* [ 2163] OBJ_ipsecTunnel */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x07,       /* [ 2171] OBJ_ipsecUser */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x0A,       /* [ 2179] OBJ_dvcs */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x01,       /* [ 2187] OBJ_id_it_caProtEncCert */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x02,       /* [ 2195] OBJ_id_it_signKeyPairTypes */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x03,       /* [ 2203] OBJ_id_it_encKeyPairTypes */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x04,       /* [ 2211] OBJ_id_it_preferredSymmAlg */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x05,       /* [ 2219] OBJ_id_it_caKeyUpdateInfo */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x06,       /* [ 2227] OBJ_id_it_currentCRL */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x07,       /* [ 2235] OBJ_id_it_unsupportedOIDs */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x08,       /* [ 2243] OBJ_id_it_subscriptionRequest */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x09,       /* [ 2251] OBJ_id_it_subscriptionResponse */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0A,       /* [ 2259] OBJ_id_it_keyPairParamReq */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0B,       /* [ 2267] OBJ_id_it_keyPairParamRep */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0C,       /* [ 2275] OBJ_id_it_revPassphrase */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0D,       /* [ 2283] OBJ_id_it_implicitConfirm */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0E,       /* [ 2291] OBJ_id_it_confirmWaitTime */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0F,       /* [ 2299] OBJ_id_it_origPKIMessage */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,       /* [ 2307] OBJ_id_regCtrl */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,       /* [ 2315] OBJ_id_regInfo */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x01,  /* [ 2323] OBJ_id_regCtrl_regToken */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x02,  /* [ 2332] OBJ_id_regCtrl_authenticator */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x03,  /* [ 2341] OBJ_id_regCtrl_pkiPublicationInfo */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x04,  /* [ 2350] OBJ_id_regCtrl_pkiArchiveOptions */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x05,  /* [ 2359] OBJ_id_regCtrl_oldCertID */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x06,  /* [ 2368] OBJ_id_regCtrl_protocolEncrKey */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x01,  /* [ 2377] OBJ_id_regInfo_utf8Pairs */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x02,  /* [ 2386] OBJ_id_regInfo_certReq */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x01,       /* [ 2395] OBJ_id_alg_des40 */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x02,       /* [ 2403] OBJ_id_alg_noSignature */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x03,       /* [ 2411] OBJ_id_alg_dh_sig_hmac_sha1 */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x04,       /* [ 2419] OBJ_id_alg_dh_pop */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x01,       /* [ 2427] OBJ_id_cmc_statusInfo */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x02,       /* [ 2435] OBJ_id_cmc_identification */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x03,       /* [ 2443] OBJ_id_cmc_identityProof */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x04,       /* [ 2451] OBJ_id_cmc_dataReturn */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x05,       /* [ 2459] OBJ_id_cmc_transactionId */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x06,       /* [ 2467] OBJ_id_cmc_senderNonce */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x07,       /* [ 2475] OBJ_id_cmc_recipientNonce */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x08,       /* [ 2483] OBJ_id_cmc_addExtensions */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x09,       /* [ 2491] OBJ_id_cmc_encryptedPOP */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0A,       /* [ 2499] OBJ_id_cmc_decryptedPOP */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0B,       /* [ 2507] OBJ_id_cmc_lraPOPWitness */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0F,       /* [ 2515] OBJ_id_cmc_getCert */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x10,       /* [ 2523] OBJ_id_cmc_getCRL */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x11,       /* [ 2531] OBJ_id_cmc_revokeRequest */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x12,       /* [ 2539] OBJ_id_cmc_regInfo */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x13,       /* [ 2547] OBJ_id_cmc_responseInfo */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x15,       /* [ 2555] OBJ_id_cmc_queryPending */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x16,       /* [ 2563] OBJ_id_cmc_popLinkRandom */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x17,       /* [ 2571] OBJ_id_cmc_popLinkWitness */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x18,       /* [ 2579] OBJ_id_cmc_confirmCertAcceptance */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x01,       /* [ 2587] OBJ_id_on_personalData */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x01,       /* [ 2595] OBJ_id_pda_dateOfBirth */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x02,       /* [ 2603] OBJ_id_pda_placeOfBirth */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x03,       /* [ 2611] OBJ_id_pda_gender */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x04,       /* [ 2619] OBJ_id_pda_countryOfCitizenship */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x05,       /* [ 2627] OBJ_id_pda_countryOfResidence */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x01,       /* [ 2635] OBJ_id_aca_authenticationInfo */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x02,       /* [ 2643] OBJ_id_aca_accessIdentity */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x03,       /* [ 2651] OBJ_id_aca_chargingIdentity */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x04,       /* [ 2659] OBJ_id_aca_group */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x05,       /* [ 2667] OBJ_id_aca_role */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0B,0x01,       /* [ 2675] OBJ_id_qcs_pkixQCSyntax_v1 */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x01,       /* [ 2683] OBJ_id_cct_crs */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x02,       /* [ 2691] OBJ_id_cct_PKIData */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x03,       /* [ 2699] OBJ_id_cct_PKIResponse */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x03,       /* [ 2707] OBJ_ad_timeStamping */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x04,       /* [ 2715] OBJ_ad_dvcs */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x01,  /* [ 2723] OBJ_id_pkix_OCSP_basic */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x02,  /* [ 2732] OBJ_id_pkix_OCSP_Nonce */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x03,  /* [ 2741] OBJ_id_pkix_OCSP_CrlID */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x04,  /* [ 2750] OBJ_id_pkix_OCSP_acceptableResponses */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x05,  /* [ 2759] OBJ_id_pkix_OCSP_noCheck */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x06,  /* [ 2768] OBJ_id_pkix_OCSP_archiveCutoff */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x07,  /* [ 2777] OBJ_id_pkix_OCSP_serviceLocator */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x08,  /* [ 2786] OBJ_id_pkix_OCSP_extendedStatus */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x09,  /* [ 2795] OBJ_id_pkix_OCSP_valid */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0A,  /* [ 2804] OBJ_id_pkix_OCSP_path */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0B,  /* [ 2813] OBJ_id_pkix_OCSP_trustRoot */
+    0x2B,0x0E,0x03,0x02,                           /* [ 2822] OBJ_algorithm */
+    0x2B,0x0E,0x03,0x02,0x0B,                      /* [ 2826] OBJ_rsaSignature */
+    0x55,0x08,                                     /* [ 2831] OBJ_X500algorithms */
+    0x2B,                                          /* [ 2833] OBJ_org */
+    0x2B,0x06,                                     /* [ 2834] OBJ_dod */
+    0x2B,0x06,0x01,                                /* [ 2836] OBJ_iana */
+    0x2B,0x06,0x01,0x01,                           /* [ 2839] OBJ_Directory */
+    0x2B,0x06,0x01,0x02,                           /* [ 2843] OBJ_Management */
+    0x2B,0x06,0x01,0x03,                           /* [ 2847] OBJ_Experimental */
+    0x2B,0x06,0x01,0x04,                           /* [ 2851] OBJ_Private */
+    0x2B,0x06,0x01,0x05,                           /* [ 2855] OBJ_Security */
+    0x2B,0x06,0x01,0x06,                           /* [ 2859] OBJ_SNMPv2 */
+    0x2B,0x06,0x01,0x07,                           /* [ 2863] OBJ_Mail */
+    0x2B,0x06,0x01,0x04,0x01,                      /* [ 2867] OBJ_Enterprises */
+    0x2B,0x06,0x01,0x04,0x01,0x8B,0x3A,0x82,0x58,  /* [ 2872] OBJ_dcObject */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x19,  /* [ 2881] OBJ_domainComponent */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0D,  /* [ 2891] OBJ_Domain */
+    0x55,0x01,0x05,                                /* [ 2901] OBJ_selected_attribute_types */
+    0x55,0x01,0x05,0x37,                           /* [ 2904] OBJ_clearance */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x03,  /* [ 2908] OBJ_md4WithRSAEncryption */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0A,       /* [ 2917] OBJ_ac_proxying */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0B,       /* [ 2925] OBJ_sinfo_access */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x06,       /* [ 2933] OBJ_id_aca_encAttrs */
+    0x55,0x04,0x48,                                /* [ 2941] OBJ_role */
+    0x55,0x1D,0x24,                                /* [ 2944] OBJ_policy_constraints */
+    0x55,0x1D,0x37,                                /* [ 2947] OBJ_target_information */
+    0x55,0x1D,0x38,                                /* [ 2950] OBJ_no_rev_avail */
+    0x2A,0x86,0x48,0xCE,0x3D,                      /* [ 2953] OBJ_ansi_X9_62 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x01,0x01,            /* [ 2958] OBJ_X9_62_prime_field */
+    0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,            /* [ 2965] OBJ_X9_62_characteristic_two_field */
+    0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,            /* [ 2972] OBJ_X9_62_id_ecPublicKey */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01,       /* [ 2979] OBJ_X9_62_prime192v1 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02,       /* [ 2987] OBJ_X9_62_prime192v2 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03,       /* [ 2995] OBJ_X9_62_prime192v3 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04,       /* [ 3003] OBJ_X9_62_prime239v1 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05,       /* [ 3011] OBJ_X9_62_prime239v2 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06,       /* [ 3019] OBJ_X9_62_prime239v3 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07,       /* [ 3027] OBJ_X9_62_prime256v1 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,            /* [ 3035] OBJ_ecdsa_with_SHA1 */
+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x01,  /* [ 3042] OBJ_ms_csp_name */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x01,  /* [ 3051] OBJ_aes_128_ecb */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x02,  /* [ 3060] OBJ_aes_128_cbc */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x03,  /* [ 3069] OBJ_aes_128_ofb128 */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x04,  /* [ 3078] OBJ_aes_128_cfb128 */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x15,  /* [ 3087] OBJ_aes_192_ecb */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x16,  /* [ 3096] OBJ_aes_192_cbc */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x17,  /* [ 3105] OBJ_aes_192_ofb128 */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x18,  /* [ 3114] OBJ_aes_192_cfb128 */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x29,  /* [ 3123] OBJ_aes_256_ecb */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2A,  /* [ 3132] OBJ_aes_256_cbc */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2B,  /* [ 3141] OBJ_aes_256_ofb128 */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2C,  /* [ 3150] OBJ_aes_256_cfb128 */
+    0x55,0x1D,0x17,                                /* [ 3159] OBJ_hold_instruction_code */
+    0x2A,0x86,0x48,0xCE,0x38,0x02,0x01,            /* [ 3162] OBJ_hold_instruction_none */
+    0x2A,0x86,0x48,0xCE,0x38,0x02,0x02,            /* [ 3169] OBJ_hold_instruction_call_issuer */
+    0x2A,0x86,0x48,0xCE,0x38,0x02,0x03,            /* [ 3176] OBJ_hold_instruction_reject */
+    0x09,                                          /* [ 3183] OBJ_data */
+    0x09,0x92,0x26,                                /* [ 3184] OBJ_pss */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,            /* [ 3187] OBJ_ucl */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,       /* [ 3194] OBJ_pilot */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,  /* [ 3202] OBJ_pilotAttributeType */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,  /* [ 3211] OBJ_pilotAttributeSyntax */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,  /* [ 3220] OBJ_pilotObjectClass */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x0A,  /* [ 3229] OBJ_pilotGroups */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x04,  /* [ 3238] OBJ_iA5StringSyntax */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x05,  /* [ 3248] OBJ_caseIgnoreIA5StringSyntax */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x03,  /* [ 3258] OBJ_pilotObject */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x04,  /* [ 3268] OBJ_pilotPerson */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x05,  /* [ 3278] OBJ_account */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x06,  /* [ 3288] OBJ_document */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x07,  /* [ 3298] OBJ_room */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x09,  /* [ 3308] OBJ_documentSeries */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0E,  /* [ 3318] OBJ_rFC822localPart */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0F,  /* [ 3328] OBJ_dNSDomain */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x11,  /* [ 3338] OBJ_domainRelatedObject */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x12,  /* [ 3348] OBJ_friendlyCountry */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x13,  /* [ 3358] OBJ_simpleSecurityObject */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x14,  /* [ 3368] OBJ_pilotOrganization */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x15,  /* [ 3378] OBJ_pilotDSA */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x16,  /* [ 3388] OBJ_qualityLabelledData */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x01,  /* [ 3398] OBJ_userId */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x02,  /* [ 3408] OBJ_textEncodedORAddress */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x03,  /* [ 3418] OBJ_rfc822Mailbox */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x04,  /* [ 3428] OBJ_info */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x05,  /* [ 3438] OBJ_favouriteDrink */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x06,  /* [ 3448] OBJ_roomNumber */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x07,  /* [ 3458] OBJ_photo */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x08,  /* [ 3468] OBJ_userClass */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x09,  /* [ 3478] OBJ_host */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0A,  /* [ 3488] OBJ_manager */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0B,  /* [ 3498] OBJ_documentIdentifier */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0C,  /* [ 3508] OBJ_documentTitle */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0D,  /* [ 3518] OBJ_documentVersion */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0E,  /* [ 3528] OBJ_documentAuthor */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0F,  /* [ 3538] OBJ_documentLocation */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x14,  /* [ 3548] OBJ_homeTelephoneNumber */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x15,  /* [ 3558] OBJ_secretary */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x16,  /* [ 3568] OBJ_otherMailbox */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x17,  /* [ 3578] OBJ_lastModifiedTime */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x18,  /* [ 3588] OBJ_lastModifiedBy */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1A,  /* [ 3598] OBJ_aRecord */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1B,  /* [ 3608] OBJ_pilotAttributeType27 */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1C,  /* [ 3618] OBJ_mXRecord */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1D,  /* [ 3628] OBJ_nSRecord */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1E,  /* [ 3638] OBJ_sOARecord */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1F,  /* [ 3648] OBJ_cNAMERecord */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x25,  /* [ 3658] OBJ_associatedDomain */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x26,  /* [ 3668] OBJ_associatedName */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x27,  /* [ 3678] OBJ_homePostalAddress */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x28,  /* [ 3688] OBJ_personalTitle */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x29,  /* [ 3698] OBJ_mobileTelephoneNumber */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2A,  /* [ 3708] OBJ_pagerTelephoneNumber */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2B,  /* [ 3718] OBJ_friendlyCountryName */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2D,  /* [ 3728] OBJ_organizationalStatus */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2E,  /* [ 3738] OBJ_janetMailbox */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2F,  /* [ 3748] OBJ_mailPreferenceOption */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x30,  /* [ 3758] OBJ_buildingName */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x31,  /* [ 3768] OBJ_dSAQuality */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x32,  /* [ 3778] OBJ_singleLevelQuality */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x33,  /* [ 3788] OBJ_subtreeMinimumQuality */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x34,  /* [ 3798] OBJ_subtreeMaximumQuality */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x35,  /* [ 3808] OBJ_personalSignature */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x36,  /* [ 3818] OBJ_dITRedirect */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x37,  /* [ 3828] OBJ_audio */
+    0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x38,  /* [ 3838] OBJ_documentPublisher */
+    0x55,0x04,0x2D,                                /* [ 3848] OBJ_x500UniqueIdentifier */
+    0x2B,0x06,0x01,0x07,0x01,                      /* [ 3851] OBJ_mime_mhs */
+    0x2B,0x06,0x01,0x07,0x01,0x01,                 /* [ 3856] OBJ_mime_mhs_headings */
+    0x2B,0x06,0x01,0x07,0x01,0x02,                 /* [ 3862] OBJ_mime_mhs_bodies */
+    0x2B,0x06,0x01,0x07,0x01,0x01,0x01,            /* [ 3868] OBJ_id_hex_partial_message */
+    0x2B,0x06,0x01,0x07,0x01,0x01,0x02,            /* [ 3875] OBJ_id_hex_multipart_message */
+    0x55,0x04,0x2C,                                /* [ 3882] OBJ_generationQualifier */
+    0x55,0x04,0x41,                                /* [ 3885] OBJ_pseudonym */
+    0x67,0x2A,                                     /* [ 3888] OBJ_id_set */
+    0x67,0x2A,0x00,                                /* [ 3890] OBJ_set_ctype */
+    0x67,0x2A,0x01,                                /* [ 3893] OBJ_set_msgExt */
+    0x67,0x2A,0x03,                                /* [ 3896] OBJ_set_attr */
+    0x67,0x2A,0x05,                                /* [ 3899] OBJ_set_policy */
+    0x67,0x2A,0x07,                                /* [ 3902] OBJ_set_certExt */
+    0x67,0x2A,0x08,                                /* [ 3905] OBJ_set_brand */
+    0x67,0x2A,0x00,0x00,                           /* [ 3908] OBJ_setct_PANData */
+    0x67,0x2A,0x00,0x01,                           /* [ 3912] OBJ_setct_PANToken */
+    0x67,0x2A,0x00,0x02,                           /* [ 3916] OBJ_setct_PANOnly */
+    0x67,0x2A,0x00,0x03,                           /* [ 3920] OBJ_setct_OIData */
+    0x67,0x2A,0x00,0x04,                           /* [ 3924] OBJ_setct_PI */
+    0x67,0x2A,0x00,0x05,                           /* [ 3928] OBJ_setct_PIData */
+    0x67,0x2A,0x00,0x06,                           /* [ 3932] OBJ_setct_PIDataUnsigned */
+    0x67,0x2A,0x00,0x07,                           /* [ 3936] OBJ_setct_HODInput */
+    0x67,0x2A,0x00,0x08,                           /* [ 3940] OBJ_setct_AuthResBaggage */
+    0x67,0x2A,0x00,0x09,                           /* [ 3944] OBJ_setct_AuthRevReqBaggage */
+    0x67,0x2A,0x00,0x0A,                           /* [ 3948] OBJ_setct_AuthRevResBaggage */
+    0x67,0x2A,0x00,0x0B,                           /* [ 3952] OBJ_setct_CapTokenSeq */
+    0x67,0x2A,0x00,0x0C,                           /* [ 3956] OBJ_setct_PInitResData */
+    0x67,0x2A,0x00,0x0D,                           /* [ 3960] OBJ_setct_PI_TBS */
+    0x67,0x2A,0x00,0x0E,                           /* [ 3964] OBJ_setct_PResData */
+    0x67,0x2A,0x00,0x10,                           /* [ 3968] OBJ_setct_AuthReqTBS */
+    0x67,0x2A,0x00,0x11,                           /* [ 3972] OBJ_setct_AuthResTBS */
+    0x67,0x2A,0x00,0x12,                           /* [ 3976] OBJ_setct_AuthResTBSX */
+    0x67,0x2A,0x00,0x13,                           /* [ 3980] OBJ_setct_AuthTokenTBS */
+    0x67,0x2A,0x00,0x14,                           /* [ 3984] OBJ_setct_CapTokenData */
+    0x67,0x2A,0x00,0x15,                           /* [ 3988] OBJ_setct_CapTokenTBS */
+    0x67,0x2A,0x00,0x16,                           /* [ 3992] OBJ_setct_AcqCardCodeMsg */
+    0x67,0x2A,0x00,0x17,                           /* [ 3996] OBJ_setct_AuthRevReqTBS */
+    0x67,0x2A,0x00,0x18,                           /* [ 4000] OBJ_setct_AuthRevResData */
+    0x67,0x2A,0x00,0x19,                           /* [ 4004] OBJ_setct_AuthRevResTBS */
+    0x67,0x2A,0x00,0x1A,                           /* [ 4008] OBJ_setct_CapReqTBS */
+    0x67,0x2A,0x00,0x1B,                           /* [ 4012] OBJ_setct_CapReqTBSX */
+    0x67,0x2A,0x00,0x1C,                           /* [ 4016] OBJ_setct_CapResData */
+    0x67,0x2A,0x00,0x1D,                           /* [ 4020] OBJ_setct_CapRevReqTBS */
+    0x67,0x2A,0x00,0x1E,                           /* [ 4024] OBJ_setct_CapRevReqTBSX */
+    0x67,0x2A,0x00,0x1F,                           /* [ 4028] OBJ_setct_CapRevResData */
+    0x67,0x2A,0x00,0x20,                           /* [ 4032] OBJ_setct_CredReqTBS */
+    0x67,0x2A,0x00,0x21,                           /* [ 4036] OBJ_setct_CredReqTBSX */
+    0x67,0x2A,0x00,0x22,                           /* [ 4040] OBJ_setct_CredResData */
+    0x67,0x2A,0x00,0x23,                           /* [ 4044] OBJ_setct_CredRevReqTBS */
+    0x67,0x2A,0x00,0x24,                           /* [ 4048] OBJ_setct_CredRevReqTBSX */
+    0x67,0x2A,0x00,0x25,                           /* [ 4052] OBJ_setct_CredRevResData */
+    0x67,0x2A,0x00,0x26,                           /* [ 4056] OBJ_setct_PCertReqData */
+    0x67,0x2A,0x00,0x27,                           /* [ 4060] OBJ_setct_PCertResTBS */
+    0x67,0x2A,0x00,0x28,                           /* [ 4064] OBJ_setct_BatchAdminReqData */
+    0x67,0x2A,0x00,0x29,                           /* [ 4068] OBJ_setct_BatchAdminResData */
+    0x67,0x2A,0x00,0x2A,                           /* [ 4072] OBJ_setct_CardCInitResTBS */
+    0x67,0x2A,0x00,0x2B,                           /* [ 4076] OBJ_setct_MeAqCInitResTBS */
+    0x67,0x2A,0x00,0x2C,                           /* [ 4080] OBJ_setct_RegFormResTBS */
+    0x67,0x2A,0x00,0x2D,                           /* [ 4084] OBJ_setct_CertReqData */
+    0x67,0x2A,0x00,0x2E,                           /* [ 4088] OBJ_setct_CertReqTBS */
+    0x67,0x2A,0x00,0x2F,                           /* [ 4092] OBJ_setct_CertResData */
+    0x67,0x2A,0x00,0x30,                           /* [ 4096] OBJ_setct_CertInqReqTBS */
+    0x67,0x2A,0x00,0x31,                           /* [ 4100] OBJ_setct_ErrorTBS */
+    0x67,0x2A,0x00,0x32,                           /* [ 4104] OBJ_setct_PIDualSignedTBE */
+    0x67,0x2A,0x00,0x33,                           /* [ 4108] OBJ_setct_PIUnsignedTBE */
+    0x67,0x2A,0x00,0x34,                           /* [ 4112] OBJ_setct_AuthReqTBE */
+    0x67,0x2A,0x00,0x35,                           /* [ 4116] OBJ_setct_AuthResTBE */
+    0x67,0x2A,0x00,0x36,                           /* [ 4120] OBJ_setct_AuthResTBEX */
+    0x67,0x2A,0x00,0x37,                           /* [ 4124] OBJ_setct_AuthTokenTBE */
+    0x67,0x2A,0x00,0x38,                           /* [ 4128] OBJ_setct_CapTokenTBE */
+    0x67,0x2A,0x00,0x39,                           /* [ 4132] OBJ_setct_CapTokenTBEX */
+    0x67,0x2A,0x00,0x3A,                           /* [ 4136] OBJ_setct_AcqCardCodeMsgTBE */
+    0x67,0x2A,0x00,0x3B,                           /* [ 4140] OBJ_setct_AuthRevReqTBE */
+    0x67,0x2A,0x00,0x3C,                           /* [ 4144] OBJ_setct_AuthRevResTBE */
+    0x67,0x2A,0x00,0x3D,                           /* [ 4148] OBJ_setct_AuthRevResTBEB */
+    0x67,0x2A,0x00,0x3E,                           /* [ 4152] OBJ_setct_CapReqTBE */
+    0x67,0x2A,0x00,0x3F,                           /* [ 4156] OBJ_setct_CapReqTBEX */
+    0x67,0x2A,0x00,0x40,                           /* [ 4160] OBJ_setct_CapResTBE */
+    0x67,0x2A,0x00,0x41,                           /* [ 4164] OBJ_setct_CapRevReqTBE */
+    0x67,0x2A,0x00,0x42,                           /* [ 4168] OBJ_setct_CapRevReqTBEX */
+    0x67,0x2A,0x00,0x43,                           /* [ 4172] OBJ_setct_CapRevResTBE */
+    0x67,0x2A,0x00,0x44,                           /* [ 4176] OBJ_setct_CredReqTBE */
+    0x67,0x2A,0x00,0x45,                           /* [ 4180] OBJ_setct_CredReqTBEX */
+    0x67,0x2A,0x00,0x46,                           /* [ 4184] OBJ_setct_CredResTBE */
+    0x67,0x2A,0x00,0x47,                           /* [ 4188] OBJ_setct_CredRevReqTBE */
+    0x67,0x2A,0x00,0x48,                           /* [ 4192] OBJ_setct_CredRevReqTBEX */
+    0x67,0x2A,0x00,0x49,                           /* [ 4196] OBJ_setct_CredRevResTBE */
+    0x67,0x2A,0x00,0x4A,                           /* [ 4200] OBJ_setct_BatchAdminReqTBE */
+    0x67,0x2A,0x00,0x4B,                           /* [ 4204] OBJ_setct_BatchAdminResTBE */
+    0x67,0x2A,0x00,0x4C,                           /* [ 4208] OBJ_setct_RegFormReqTBE */
+    0x67,0x2A,0x00,0x4D,                           /* [ 4212] OBJ_setct_CertReqTBE */
+    0x67,0x2A,0x00,0x4E,                           /* [ 4216] OBJ_setct_CertReqTBEX */
+    0x67,0x2A,0x00,0x4F,                           /* [ 4220] OBJ_setct_CertResTBE */
+    0x67,0x2A,0x00,0x50,                           /* [ 4224] OBJ_setct_CRLNotificationTBS */
+    0x67,0x2A,0x00,0x51,                           /* [ 4228] OBJ_setct_CRLNotificationResTBS */
+    0x67,0x2A,0x00,0x52,                           /* [ 4232] OBJ_setct_BCIDistributionTBS */
+    0x67,0x2A,0x01,0x01,                           /* [ 4236] OBJ_setext_genCrypt */
+    0x67,0x2A,0x01,0x03,                           /* [ 4240] OBJ_setext_miAuth */
+    0x67,0x2A,0x01,0x04,                           /* [ 4244] OBJ_setext_pinSecure */
+    0x67,0x2A,0x01,0x05,                           /* [ 4248] OBJ_setext_pinAny */
+    0x67,0x2A,0x01,0x07,                           /* [ 4252] OBJ_setext_track2 */
+    0x67,0x2A,0x01,0x08,                           /* [ 4256] OBJ_setext_cv */
+    0x67,0x2A,0x05,0x00,                           /* [ 4260] OBJ_set_policy_root */
+    0x67,0x2A,0x07,0x00,                           /* [ 4264] OBJ_setCext_hashedRoot */
+    0x67,0x2A,0x07,0x01,                           /* [ 4268] OBJ_setCext_certType */
+    0x67,0x2A,0x07,0x02,                           /* [ 4272] OBJ_setCext_merchData */
+    0x67,0x2A,0x07,0x03,                           /* [ 4276] OBJ_setCext_cCertRequired */
+    0x67,0x2A,0x07,0x04,                           /* [ 4280] OBJ_setCext_tunneling */
+    0x67,0x2A,0x07,0x05,                           /* [ 4284] OBJ_setCext_setExt */
+    0x67,0x2A,0x07,0x06,                           /* [ 4288] OBJ_setCext_setQualf */
+    0x67,0x2A,0x07,0x07,                           /* [ 4292] OBJ_setCext_PGWYcapabilities */
+    0x67,0x2A,0x07,0x08,                           /* [ 4296] OBJ_setCext_TokenIdentifier */
+    0x67,0x2A,0x07,0x09,                           /* [ 4300] OBJ_setCext_Track2Data */
+    0x67,0x2A,0x07,0x0A,                           /* [ 4304] OBJ_setCext_TokenType */
+    0x67,0x2A,0x07,0x0B,                           /* [ 4308] OBJ_setCext_IssuerCapabilities */
+    0x67,0x2A,0x03,0x00,                           /* [ 4312] OBJ_setAttr_Cert */
+    0x67,0x2A,0x03,0x01,                           /* [ 4316] OBJ_setAttr_PGWYcap */
+    0x67,0x2A,0x03,0x02,                           /* [ 4320] OBJ_setAttr_TokenType */
+    0x67,0x2A,0x03,0x03,                           /* [ 4324] OBJ_setAttr_IssCap */
+    0x67,0x2A,0x03,0x00,0x00,                      /* [ 4328] OBJ_set_rootKeyThumb */
+    0x67,0x2A,0x03,0x00,0x01,                      /* [ 4333] OBJ_set_addPolicy */
+    0x67,0x2A,0x03,0x02,0x01,                      /* [ 4338] OBJ_setAttr_Token_EMV */
+    0x67,0x2A,0x03,0x02,0x02,                      /* [ 4343] OBJ_setAttr_Token_B0Prime */
+    0x67,0x2A,0x03,0x03,0x03,                      /* [ 4348] OBJ_setAttr_IssCap_CVM */
+    0x67,0x2A,0x03,0x03,0x04,                      /* [ 4353] OBJ_setAttr_IssCap_T2 */
+    0x67,0x2A,0x03,0x03,0x05,                      /* [ 4358] OBJ_setAttr_IssCap_Sig */
+    0x67,0x2A,0x03,0x03,0x03,0x01,                 /* [ 4363] OBJ_setAttr_GenCryptgrm */
+    0x67,0x2A,0x03,0x03,0x04,0x01,                 /* [ 4369] OBJ_setAttr_T2Enc */
+    0x67,0x2A,0x03,0x03,0x04,0x02,                 /* [ 4375] OBJ_setAttr_T2cleartxt */
+    0x67,0x2A,0x03,0x03,0x05,0x01,                 /* [ 4381] OBJ_setAttr_TokICCsig */
+    0x67,0x2A,0x03,0x03,0x05,0x02,                 /* [ 4387] OBJ_setAttr_SecDevSig */
+    0x67,0x2A,0x08,0x01,                           /* [ 4393] OBJ_set_brand_IATA_ATA */
+    0x67,0x2A,0x08,0x1E,                           /* [ 4397] OBJ_set_brand_Diners */
+    0x67,0x2A,0x08,0x22,                           /* [ 4401] OBJ_set_brand_AmericanExpress */
+    0x67,0x2A,0x08,0x23,                           /* [ 4405] OBJ_set_brand_JCB */
+    0x67,0x2A,0x08,0x04,                           /* [ 4409] OBJ_set_brand_Visa */
+    0x67,0x2A,0x08,0x05,                           /* [ 4413] OBJ_set_brand_MasterCard */
+    0x67,0x2A,0x08,0xAE,0x7B,                      /* [ 4417] OBJ_set_brand_Novus */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x0A,       /* [ 4422] OBJ_des_cdmf */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x06,  /* [ 4430] OBJ_rsaOAEPEncryptionSET */
+    0x67,                                          /* [ 4439] OBJ_international_organizations */
+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x02,  /* [ 4440] OBJ_ms_smartcard_login */
+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x03,  /* [ 4450] OBJ_ms_upn */
+    0x55,0x04,0x09,                                /* [ 4460] OBJ_streetAddress */
+    0x55,0x04,0x11,                                /* [ 4463] OBJ_postalCode */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x15,            /* [ 4466] OBJ_id_ppl */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0E,       /* [ 4473] OBJ_proxyCertInfo */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x00,       /* [ 4481] OBJ_id_ppl_anyLanguage */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x01,       /* [ 4489] OBJ_id_ppl_inheritAll */
+    0x55,0x1D,0x1E,                                /* [ 4497] OBJ_name_constraints */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x02,       /* [ 4500] OBJ_Independent */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,  /* [ 4508] OBJ_sha256WithRSAEncryption */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C,  /* [ 4517] OBJ_sha384WithRSAEncryption */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0D,  /* [ 4526] OBJ_sha512WithRSAEncryption */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0E,  /* [ 4535] OBJ_sha224WithRSAEncryption */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,  /* [ 4544] OBJ_sha256 */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,  /* [ 4553] OBJ_sha384 */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,  /* [ 4562] OBJ_sha512 */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,  /* [ 4571] OBJ_sha224 */
+    0x2B,                                          /* [ 4580] OBJ_identified_organization */
+    0x2B,0x81,0x04,                                /* [ 4581] OBJ_certicom_arc */
+    0x67,0x2B,                                     /* [ 4584] OBJ_wap */
+    0x67,0x2B,0x01,                                /* [ 4586] OBJ_wap_wsg */
+    0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,       /* [ 4589] OBJ_X9_62_id_characteristic_two_basis */
+    0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x01,  /* [ 4597] OBJ_X9_62_onBasis */
+    0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x02,  /* [ 4606] OBJ_X9_62_tpBasis */
+    0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x03,  /* [ 4615] OBJ_X9_62_ppBasis */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x01,       /* [ 4624] OBJ_X9_62_c2pnb163v1 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x02,       /* [ 4632] OBJ_X9_62_c2pnb163v2 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x03,       /* [ 4640] OBJ_X9_62_c2pnb163v3 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x04,       /* [ 4648] OBJ_X9_62_c2pnb176v1 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x05,       /* [ 4656] OBJ_X9_62_c2tnb191v1 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x06,       /* [ 4664] OBJ_X9_62_c2tnb191v2 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x07,       /* [ 4672] OBJ_X9_62_c2tnb191v3 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x08,       /* [ 4680] OBJ_X9_62_c2onb191v4 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x09,       /* [ 4688] OBJ_X9_62_c2onb191v5 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0A,       /* [ 4696] OBJ_X9_62_c2pnb208w1 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0B,       /* [ 4704] OBJ_X9_62_c2tnb239v1 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0C,       /* [ 4712] OBJ_X9_62_c2tnb239v2 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0D,       /* [ 4720] OBJ_X9_62_c2tnb239v3 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0E,       /* [ 4728] OBJ_X9_62_c2onb239v4 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0F,       /* [ 4736] OBJ_X9_62_c2onb239v5 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x10,       /* [ 4744] OBJ_X9_62_c2pnb272w1 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x11,       /* [ 4752] OBJ_X9_62_c2pnb304w1 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x12,       /* [ 4760] OBJ_X9_62_c2tnb359v1 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x13,       /* [ 4768] OBJ_X9_62_c2pnb368w1 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x14,       /* [ 4776] OBJ_X9_62_c2tnb431r1 */
+    0x2B,0x81,0x04,0x00,0x06,                      /* [ 4784] OBJ_secp112r1 */
+    0x2B,0x81,0x04,0x00,0x07,                      /* [ 4789] OBJ_secp112r2 */
+    0x2B,0x81,0x04,0x00,0x1C,                      /* [ 4794] OBJ_secp128r1 */
+    0x2B,0x81,0x04,0x00,0x1D,                      /* [ 4799] OBJ_secp128r2 */
+    0x2B,0x81,0x04,0x00,0x09,                      /* [ 4804] OBJ_secp160k1 */
+    0x2B,0x81,0x04,0x00,0x08,                      /* [ 4809] OBJ_secp160r1 */
+    0x2B,0x81,0x04,0x00,0x1E,                      /* [ 4814] OBJ_secp160r2 */
+    0x2B,0x81,0x04,0x00,0x1F,                      /* [ 4819] OBJ_secp192k1 */
+    0x2B,0x81,0x04,0x00,0x20,                      /* [ 4824] OBJ_secp224k1 */
+    0x2B,0x81,0x04,0x00,0x21,                      /* [ 4829] OBJ_secp224r1 */
+    0x2B,0x81,0x04,0x00,0x0A,                      /* [ 4834] OBJ_secp256k1 */
+    0x2B,0x81,0x04,0x00,0x22,                      /* [ 4839] OBJ_secp384r1 */
+    0x2B,0x81,0x04,0x00,0x23,                      /* [ 4844] OBJ_secp521r1 */
+    0x2B,0x81,0x04,0x00,0x04,                      /* [ 4849] OBJ_sect113r1 */
+    0x2B,0x81,0x04,0x00,0x05,                      /* [ 4854] OBJ_sect113r2 */
+    0x2B,0x81,0x04,0x00,0x16,                      /* [ 4859] OBJ_sect131r1 */
+    0x2B,0x81,0x04,0x00,0x17,                      /* [ 4864] OBJ_sect131r2 */
+    0x2B,0x81,0x04,0x00,0x01,                      /* [ 4869] OBJ_sect163k1 */
+    0x2B,0x81,0x04,0x00,0x02,                      /* [ 4874] OBJ_sect163r1 */
+    0x2B,0x81,0x04,0x00,0x0F,                      /* [ 4879] OBJ_sect163r2 */
+    0x2B,0x81,0x04,0x00,0x18,                      /* [ 4884] OBJ_sect193r1 */
+    0x2B,0x81,0x04,0x00,0x19,                      /* [ 4889] OBJ_sect193r2 */
+    0x2B,0x81,0x04,0x00,0x1A,                      /* [ 4894] OBJ_sect233k1 */
+    0x2B,0x81,0x04,0x00,0x1B,                      /* [ 4899] OBJ_sect233r1 */
+    0x2B,0x81,0x04,0x00,0x03,                      /* [ 4904] OBJ_sect239k1 */
+    0x2B,0x81,0x04,0x00,0x10,                      /* [ 4909] OBJ_sect283k1 */
+    0x2B,0x81,0x04,0x00,0x11,                      /* [ 4914] OBJ_sect283r1 */
+    0x2B,0x81,0x04,0x00,0x24,                      /* [ 4919] OBJ_sect409k1 */
+    0x2B,0x81,0x04,0x00,0x25,                      /* [ 4924] OBJ_sect409r1 */
+    0x2B,0x81,0x04,0x00,0x26,                      /* [ 4929] OBJ_sect571k1 */
+    0x2B,0x81,0x04,0x00,0x27,                      /* [ 4934] OBJ_sect571r1 */
+    0x67,0x2B,0x01,0x04,0x01,                      /* [ 4939] OBJ_wap_wsg_idm_ecid_wtls1 */
+    0x67,0x2B,0x01,0x04,0x03,                      /* [ 4944] OBJ_wap_wsg_idm_ecid_wtls3 */
+    0x67,0x2B,0x01,0x04,0x04,                      /* [ 4949] OBJ_wap_wsg_idm_ecid_wtls4 */
+    0x67,0x2B,0x01,0x04,0x05,                      /* [ 4954] OBJ_wap_wsg_idm_ecid_wtls5 */
+    0x67,0x2B,0x01,0x04,0x06,                      /* [ 4959] OBJ_wap_wsg_idm_ecid_wtls6 */
+    0x67,0x2B,0x01,0x04,0x07,                      /* [ 4964] OBJ_wap_wsg_idm_ecid_wtls7 */
+    0x67,0x2B,0x01,0x04,0x08,                      /* [ 4969] OBJ_wap_wsg_idm_ecid_wtls8 */
+    0x67,0x2B,0x01,0x04,0x09,                      /* [ 4974] OBJ_wap_wsg_idm_ecid_wtls9 */
+    0x67,0x2B,0x01,0x04,0x0A,                      /* [ 4979] OBJ_wap_wsg_idm_ecid_wtls10 */
+    0x67,0x2B,0x01,0x04,0x0B,                      /* [ 4984] OBJ_wap_wsg_idm_ecid_wtls11 */
+    0x67,0x2B,0x01,0x04,0x0C,                      /* [ 4989] OBJ_wap_wsg_idm_ecid_wtls12 */
+    0x55,0x1D,0x20,0x00,                           /* [ 4994] OBJ_any_policy */
+    0x55,0x1D,0x21,                                /* [ 4998] OBJ_policy_mappings */
+    0x55,0x1D,0x36,                                /* [ 5001] OBJ_inhibit_any_policy */
+    0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x02,  /* [ 5004] OBJ_camellia_128_cbc */
+    0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x03,  /* [ 5015] OBJ_camellia_192_cbc */
+    0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x04,  /* [ 5026] OBJ_camellia_256_cbc */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x01,       /* [ 5037] OBJ_camellia_128_ecb */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x15,       /* [ 5045] OBJ_camellia_192_ecb */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x29,       /* [ 5053] OBJ_camellia_256_ecb */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x04,       /* [ 5061] OBJ_camellia_128_cfb128 */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x18,       /* [ 5069] OBJ_camellia_192_cfb128 */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2C,       /* [ 5077] OBJ_camellia_256_cfb128 */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x03,       /* [ 5085] OBJ_camellia_128_ofb128 */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x17,       /* [ 5093] OBJ_camellia_192_ofb128 */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2B,       /* [ 5101] OBJ_camellia_256_ofb128 */
+    0x55,0x1D,0x09,                                /* [ 5109] OBJ_subject_directory_attributes */
+    0x55,0x1D,0x1C,                                /* [ 5112] OBJ_issuing_distribution_point */
+    0x55,0x1D,0x1D,                                /* [ 5115] OBJ_certificate_issuer */
+    0x2A,0x83,0x1A,0x8C,0x9A,0x44,                 /* [ 5118] OBJ_kisa */
+    0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x03,       /* [ 5124] OBJ_seed_ecb */
+    0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x04,       /* [ 5132] OBJ_seed_cbc */
+    0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x06,       /* [ 5140] OBJ_seed_ofb128 */
+    0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x05,       /* [ 5148] OBJ_seed_cfb128 */
+    0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x01,       /* [ 5156] OBJ_hmac_md5 */
+    0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x02,       /* [ 5164] OBJ_hmac_sha1 */
+    0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0D,  /* [ 5172] OBJ_id_PasswordBasedMAC */
+    0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x1E,  /* [ 5181] OBJ_id_DHBasedMac */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x10,       /* [ 5190] OBJ_id_it_suppLangTags */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x05,       /* [ 5198] OBJ_caRepository */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x09,  /* [ 5206] OBJ_id_smime_ct_compressedData */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x1B,  /* [ 5217] OBJ_id_ct_asciiTextWithCRLF */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x05,  /* [ 5228] OBJ_id_aes128_wrap */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x19,  /* [ 5237] OBJ_id_aes192_wrap */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2D,  /* [ 5246] OBJ_id_aes256_wrap */
+    0x2A,0x86,0x48,0xCE,0x3D,0x04,0x02,            /* [ 5255] OBJ_ecdsa_with_Recommended */
+    0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,            /* [ 5262] OBJ_ecdsa_with_Specified */
+    0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x01,       /* [ 5269] OBJ_ecdsa_with_SHA224 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,       /* [ 5277] OBJ_ecdsa_with_SHA256 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,       /* [ 5285] OBJ_ecdsa_with_SHA384 */
+    0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x04,       /* [ 5293] OBJ_ecdsa_with_SHA512 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x06,       /* [ 5301] OBJ_hmacWithMD5 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x08,       /* [ 5309] OBJ_hmacWithSHA224 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x09,       /* [ 5317] OBJ_hmacWithSHA256 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0A,       /* [ 5325] OBJ_hmacWithSHA384 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0B,       /* [ 5333] OBJ_hmacWithSHA512 */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x01,  /* [ 5341] OBJ_dsa_with_SHA224 */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x02,  /* [ 5350] OBJ_dsa_with_SHA256 */
+    0x28,0xCF,0x06,0x03,0x00,0x37,                 /* [ 5359] OBJ_whirlpool */
+    0x2A,0x85,0x03,0x02,0x02,                      /* [ 5365] OBJ_cryptopro */
+    0x2A,0x85,0x03,0x02,0x09,                      /* [ 5370] OBJ_cryptocom */
+    0x2A,0x85,0x03,0x02,0x02,0x03,                 /* [ 5375] OBJ_id_GostR3411_94_with_GostR3410_2001 */
+    0x2A,0x85,0x03,0x02,0x02,0x04,                 /* [ 5381] OBJ_id_GostR3411_94_with_GostR3410_94 */
+    0x2A,0x85,0x03,0x02,0x02,0x09,                 /* [ 5387] OBJ_id_GostR3411_94 */
+    0x2A,0x85,0x03,0x02,0x02,0x0A,                 /* [ 5393] OBJ_id_HMACGostR3411_94 */
+    0x2A,0x85,0x03,0x02,0x02,0x13,                 /* [ 5399] OBJ_id_GostR3410_2001 */
+    0x2A,0x85,0x03,0x02,0x02,0x14,                 /* [ 5405] OBJ_id_GostR3410_94 */
+    0x2A,0x85,0x03,0x02,0x02,0x15,                 /* [ 5411] OBJ_id_Gost28147_89 */
+    0x2A,0x85,0x03,0x02,0x02,0x16,                 /* [ 5417] OBJ_id_Gost28147_89_MAC */
+    0x2A,0x85,0x03,0x02,0x02,0x17,                 /* [ 5423] OBJ_id_GostR3411_94_prf */
+    0x2A,0x85,0x03,0x02,0x02,0x62,                 /* [ 5429] OBJ_id_GostR3410_2001DH */
+    0x2A,0x85,0x03,0x02,0x02,0x63,                 /* [ 5435] OBJ_id_GostR3410_94DH */
+    0x2A,0x85,0x03,0x02,0x02,0x0E,0x01,            /* [ 5441] OBJ_id_Gost28147_89_CryptoPro_KeyMeshing */
+    0x2A,0x85,0x03,0x02,0x02,0x0E,0x00,            /* [ 5448] OBJ_id_Gost28147_89_None_KeyMeshing */
+    0x2A,0x85,0x03,0x02,0x02,0x1E,0x00,            /* [ 5455] OBJ_id_GostR3411_94_TestParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x1E,0x01,            /* [ 5462] OBJ_id_GostR3411_94_CryptoProParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x1F,0x00,            /* [ 5469] OBJ_id_Gost28147_89_TestParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x1F,0x01,            /* [ 5476] OBJ_id_Gost28147_89_CryptoPro_A_ParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x1F,0x02,            /* [ 5483] OBJ_id_Gost28147_89_CryptoPro_B_ParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x1F,0x03,            /* [ 5490] OBJ_id_Gost28147_89_CryptoPro_C_ParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x1F,0x04,            /* [ 5497] OBJ_id_Gost28147_89_CryptoPro_D_ParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x1F,0x05,            /* [ 5504] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x1F,0x06,            /* [ 5511] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x1F,0x07,            /* [ 5518] OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x20,0x00,            /* [ 5525] OBJ_id_GostR3410_94_TestParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x20,0x02,            /* [ 5532] OBJ_id_GostR3410_94_CryptoPro_A_ParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x20,0x03,            /* [ 5539] OBJ_id_GostR3410_94_CryptoPro_B_ParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x20,0x04,            /* [ 5546] OBJ_id_GostR3410_94_CryptoPro_C_ParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x20,0x05,            /* [ 5553] OBJ_id_GostR3410_94_CryptoPro_D_ParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x21,0x01,            /* [ 5560] OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x21,0x02,            /* [ 5567] OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x21,0x03,            /* [ 5574] OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x23,0x00,            /* [ 5581] OBJ_id_GostR3410_2001_TestParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x23,0x01,            /* [ 5588] OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x23,0x02,            /* [ 5595] OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x23,0x03,            /* [ 5602] OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x24,0x00,            /* [ 5609] OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x24,0x01,            /* [ 5616] OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet */
+    0x2A,0x85,0x03,0x02,0x02,0x14,0x01,            /* [ 5623] OBJ_id_GostR3410_94_a */
+    0x2A,0x85,0x03,0x02,0x02,0x14,0x02,            /* [ 5630] OBJ_id_GostR3410_94_aBis */
+    0x2A,0x85,0x03,0x02,0x02,0x14,0x03,            /* [ 5637] OBJ_id_GostR3410_94_b */
+    0x2A,0x85,0x03,0x02,0x02,0x14,0x04,            /* [ 5644] OBJ_id_GostR3410_94_bBis */
+    0x2A,0x85,0x03,0x02,0x09,0x01,0x06,0x01,       /* [ 5651] OBJ_id_Gost28147_89_cc */
+    0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x03,       /* [ 5659] OBJ_id_GostR3410_94_cc */
+    0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x04,       /* [ 5667] OBJ_id_GostR3410_2001_cc */
+    0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x03,       /* [ 5675] OBJ_id_GostR3411_94_with_GostR3410_94_cc */
+    0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x04,       /* [ 5683] OBJ_id_GostR3411_94_with_GostR3410_2001_cc */
+    0x2A,0x85,0x03,0x02,0x09,0x01,0x08,0x01,       /* [ 5691] OBJ_id_GostR3410_2001_ParamSet_cc */
+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x02,  /* [ 5699] OBJ_LocalKeySet */
+    0x55,0x1D,0x2E,                                /* [ 5708] OBJ_freshest_crl */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x03,       /* [ 5711] OBJ_id_on_permanentIdentifier */
+    0x55,0x04,0x0E,                                /* [ 5719] OBJ_searchGuide */
+    0x55,0x04,0x0F,                                /* [ 5722] OBJ_businessCategory */
+    0x55,0x04,0x10,                                /* [ 5725] OBJ_postalAddress */
+    0x55,0x04,0x12,                                /* [ 5728] OBJ_postOfficeBox */
+    0x55,0x04,0x13,                                /* [ 5731] OBJ_physicalDeliveryOfficeName */
+    0x55,0x04,0x14,                                /* [ 5734] OBJ_telephoneNumber */
+    0x55,0x04,0x15,                                /* [ 5737] OBJ_telexNumber */
+    0x55,0x04,0x16,                                /* [ 5740] OBJ_teletexTerminalIdentifier */
+    0x55,0x04,0x17,                                /* [ 5743] OBJ_facsimileTelephoneNumber */
+    0x55,0x04,0x18,                                /* [ 5746] OBJ_x121Address */
+    0x55,0x04,0x19,                                /* [ 5749] OBJ_internationaliSDNNumber */
+    0x55,0x04,0x1A,                                /* [ 5752] OBJ_registeredAddress */
+    0x55,0x04,0x1B,                                /* [ 5755] OBJ_destinationIndicator */
+    0x55,0x04,0x1C,                                /* [ 5758] OBJ_preferredDeliveryMethod */
+    0x55,0x04,0x1D,                                /* [ 5761] OBJ_presentationAddress */
+    0x55,0x04,0x1E,                                /* [ 5764] OBJ_supportedApplicationContext */
+    0x55,0x04,0x1F,                                /* [ 5767] OBJ_member */
+    0x55,0x04,0x20,                                /* [ 5770] OBJ_owner */
+    0x55,0x04,0x21,                                /* [ 5773] OBJ_roleOccupant */
+    0x55,0x04,0x22,                                /* [ 5776] OBJ_seeAlso */
+    0x55,0x04,0x23,                                /* [ 5779] OBJ_userPassword */
+    0x55,0x04,0x24,                                /* [ 5782] OBJ_userCertificate */
+    0x55,0x04,0x25,                                /* [ 5785] OBJ_cACertificate */
+    0x55,0x04,0x26,                                /* [ 5788] OBJ_authorityRevocationList */
+    0x55,0x04,0x27,                                /* [ 5791] OBJ_certificateRevocationList */
+    0x55,0x04,0x28,                                /* [ 5794] OBJ_crossCertificatePair */
+    0x55,0x04,0x2F,                                /* [ 5797] OBJ_enhancedSearchGuide */
+    0x55,0x04,0x30,                                /* [ 5800] OBJ_protocolInformation */
+    0x55,0x04,0x31,                                /* [ 5803] OBJ_distinguishedName */
+    0x55,0x04,0x32,                                /* [ 5806] OBJ_uniqueMember */
+    0x55,0x04,0x33,                                /* [ 5809] OBJ_houseIdentifier */
+    0x55,0x04,0x34,                                /* [ 5812] OBJ_supportedAlgorithms */
+    0x55,0x04,0x35,                                /* [ 5815] OBJ_deltaRevocationList */
+    0x55,0x04,0x36,                                /* [ 5818] OBJ_dmdName */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x09,  /* [ 5821] OBJ_id_alg_PWRI_KEK */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x06,  /* [ 5832] OBJ_aes_128_gcm */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x07,  /* [ 5841] OBJ_aes_128_ccm */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x08,  /* [ 5850] OBJ_id_aes128_wrap_pad */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1A,  /* [ 5859] OBJ_aes_192_gcm */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1B,  /* [ 5868] OBJ_aes_192_ccm */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1C,  /* [ 5877] OBJ_id_aes192_wrap_pad */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2E,  /* [ 5886] OBJ_aes_256_gcm */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2F,  /* [ 5895] OBJ_aes_256_ccm */
+    0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x30,  /* [ 5904] OBJ_id_aes256_wrap_pad */
+    0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x02,  /* [ 5913] OBJ_id_camellia128_wrap */
+    0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x03,  /* [ 5924] OBJ_id_camellia192_wrap */
+    0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x04,  /* [ 5935] OBJ_id_camellia256_wrap */
+    0x55,0x1D,0x25,0x00,                           /* [ 5946] OBJ_anyExtendedKeyUsage */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x08,  /* [ 5950] OBJ_mgf1 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0A,  /* [ 5959] OBJ_rsassaPss */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x07,  /* [ 5968] OBJ_rsaesOaep */
+    0x2A,0x86,0x48,0xCE,0x3E,0x02,0x01,            /* [ 5977] OBJ_dhpublicnumber */
+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01,  /* [ 5984] OBJ_brainpoolP160r1 */
+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x02,  /* [ 5993] OBJ_brainpoolP160t1 */
+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03,  /* [ 6002] OBJ_brainpoolP192r1 */
+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x04,  /* [ 6011] OBJ_brainpoolP192t1 */
+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05,  /* [ 6020] OBJ_brainpoolP224r1 */
+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x06,  /* [ 6029] OBJ_brainpoolP224t1 */
+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07,  /* [ 6038] OBJ_brainpoolP256r1 */
+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x08,  /* [ 6047] OBJ_brainpoolP256t1 */
+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09,  /* [ 6056] OBJ_brainpoolP320r1 */
+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0A,  /* [ 6065] OBJ_brainpoolP320t1 */
+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B,  /* [ 6074] OBJ_brainpoolP384r1 */
+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0C,  /* [ 6083] OBJ_brainpoolP384t1 */
+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D,  /* [ 6092] OBJ_brainpoolP512r1 */
+    0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0E,  /* [ 6101] OBJ_brainpoolP512t1 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x09,  /* [ 6110] OBJ_pSpecified */
+    0x2B,0x81,0x05,0x10,0x86,0x48,0x3F,0x00,0x02,  /* [ 6119] OBJ_dhSinglePass_stdDH_sha1kdf_scheme */
+    0x2B,0x81,0x04,0x01,0x0B,0x00,                 /* [ 6128] OBJ_dhSinglePass_stdDH_sha224kdf_scheme */
+    0x2B,0x81,0x04,0x01,0x0B,0x01,                 /* [ 6134] OBJ_dhSinglePass_stdDH_sha256kdf_scheme */
+    0x2B,0x81,0x04,0x01,0x0B,0x02,                 /* [ 6140] OBJ_dhSinglePass_stdDH_sha384kdf_scheme */
+    0x2B,0x81,0x04,0x01,0x0B,0x03,                 /* [ 6146] OBJ_dhSinglePass_stdDH_sha512kdf_scheme */
+    0x2B,0x81,0x05,0x10,0x86,0x48,0x3F,0x00,0x03,  /* [ 6152] OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme */
+    0x2B,0x81,0x04,0x01,0x0E,0x00,                 /* [ 6161] OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme */
+    0x2B,0x81,0x04,0x01,0x0E,0x01,                 /* [ 6167] OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme */
+    0x2B,0x81,0x04,0x01,0x0E,0x02,                 /* [ 6173] OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme */
+    0x2B,0x81,0x04,0x01,0x0E,0x03,                 /* [ 6179] OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme */
+    0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x02,  /* [ 6185] OBJ_ct_precert_scts */
+    0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x03,  /* [ 6195] OBJ_ct_precert_poison */
+    0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x04,  /* [ 6205] OBJ_ct_precert_signer */
+    0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x05,  /* [ 6215] OBJ_ct_cert_scts */
+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x01,  /* [ 6225] OBJ_jurisdictionLocalityName */
+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x02,  /* [ 6236] OBJ_jurisdictionStateOrProvinceName */
+    0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x03,  /* [ 6247] OBJ_jurisdictionCountryName */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x06,       /* [ 6258] OBJ_camellia_128_gcm */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x07,       /* [ 6266] OBJ_camellia_128_ccm */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x09,       /* [ 6274] OBJ_camellia_128_ctr */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x0A,       /* [ 6282] OBJ_camellia_128_cmac */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x1A,       /* [ 6290] OBJ_camellia_192_gcm */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x1B,       /* [ 6298] OBJ_camellia_192_ccm */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x1D,       /* [ 6306] OBJ_camellia_192_ctr */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x1E,       /* [ 6314] OBJ_camellia_192_cmac */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2E,       /* [ 6322] OBJ_camellia_256_gcm */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2F,       /* [ 6330] OBJ_camellia_256_ccm */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x31,       /* [ 6338] OBJ_camellia_256_ctr */
+    0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x32,       /* [ 6346] OBJ_camellia_256_cmac */
+    0x2B,0x06,0x01,0x04,0x01,0xDA,0x47,0x04,0x0B,  /* [ 6354] OBJ_id_scrypt */
+    0x2A,0x85,0x03,0x07,0x01,                      /* [ 6363] OBJ_id_tc26 */
+    0x2A,0x85,0x03,0x07,0x01,0x01,                 /* [ 6368] OBJ_id_tc26_algorithms */
+    0x2A,0x85,0x03,0x07,0x01,0x01,0x01,            /* [ 6374] OBJ_id_tc26_sign */
+    0x2A,0x85,0x03,0x07,0x01,0x01,0x01,0x01,       /* [ 6381] OBJ_id_GostR3410_2012_256 */
+    0x2A,0x85,0x03,0x07,0x01,0x01,0x01,0x02,       /* [ 6389] OBJ_id_GostR3410_2012_512 */
+    0x2A,0x85,0x03,0x07,0x01,0x01,0x02,            /* [ 6397] OBJ_id_tc26_digest */
+    0x2A,0x85,0x03,0x07,0x01,0x01,0x02,0x02,       /* [ 6404] OBJ_id_GostR3411_2012_256 */
+    0x2A,0x85,0x03,0x07,0x01,0x01,0x02,0x03,       /* [ 6412] OBJ_id_GostR3411_2012_512 */
+    0x2A,0x85,0x03,0x07,0x01,0x01,0x03,            /* [ 6420] OBJ_id_tc26_signwithdigest */
+    0x2A,0x85,0x03,0x07,0x01,0x01,0x03,0x02,       /* [ 6427] OBJ_id_tc26_signwithdigest_gost3410_2012_256 */
+    0x2A,0x85,0x03,0x07,0x01,0x01,0x03,0x03,       /* [ 6435] OBJ_id_tc26_signwithdigest_gost3410_2012_512 */
+    0x2A,0x85,0x03,0x07,0x01,0x01,0x04,            /* [ 6443] OBJ_id_tc26_mac */
+    0x2A,0x85,0x03,0x07,0x01,0x01,0x04,0x01,       /* [ 6450] OBJ_id_tc26_hmac_gost_3411_2012_256 */
+    0x2A,0x85,0x03,0x07,0x01,0x01,0x04,0x02,       /* [ 6458] OBJ_id_tc26_hmac_gost_3411_2012_512 */
+    0x2A,0x85,0x03,0x07,0x01,0x01,0x05,            /* [ 6466] OBJ_id_tc26_cipher */
+    0x2A,0x85,0x03,0x07,0x01,0x01,0x06,            /* [ 6473] OBJ_id_tc26_agreement */
+    0x2A,0x85,0x03,0x07,0x01,0x01,0x06,0x01,       /* [ 6480] OBJ_id_tc26_agreement_gost_3410_2012_256 */
+    0x2A,0x85,0x03,0x07,0x01,0x01,0x06,0x02,       /* [ 6488] OBJ_id_tc26_agreement_gost_3410_2012_512 */
+    0x2A,0x85,0x03,0x07,0x01,0x02,                 /* [ 6496] OBJ_id_tc26_constants */
+    0x2A,0x85,0x03,0x07,0x01,0x02,0x01,            /* [ 6502] OBJ_id_tc26_sign_constants */
+    0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x02,       /* [ 6509] OBJ_id_tc26_gost_3410_2012_512_constants */
+    0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x02,0x00,  /* [ 6517] OBJ_id_tc26_gost_3410_2012_512_paramSetTest */
+    0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x02,0x01,  /* [ 6526] OBJ_id_tc26_gost_3410_2012_512_paramSetA */
+    0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x02,0x02,  /* [ 6535] OBJ_id_tc26_gost_3410_2012_512_paramSetB */
+    0x2A,0x85,0x03,0x07,0x01,0x02,0x02,            /* [ 6544] OBJ_id_tc26_digest_constants */
+    0x2A,0x85,0x03,0x07,0x01,0x02,0x05,            /* [ 6551] OBJ_id_tc26_cipher_constants */
+    0x2A,0x85,0x03,0x07,0x01,0x02,0x05,0x01,       /* [ 6558] OBJ_id_tc26_gost_28147_constants */
+    0x2A,0x85,0x03,0x07,0x01,0x02,0x05,0x01,0x01,  /* [ 6566] OBJ_id_tc26_gost_28147_param_Z */
+    0x2A,0x85,0x03,0x03,0x81,0x03,0x01,0x01,       /* [ 6575] OBJ_INN */
+    0x2A,0x85,0x03,0x64,0x01,                      /* [ 6583] OBJ_OGRN */
+    0x2A,0x85,0x03,0x64,0x03,                      /* [ 6588] OBJ_SNILS */
+    0x2A,0x85,0x03,0x64,0x6F,                      /* [ 6593] OBJ_subjectSignTool */
+    0x2A,0x85,0x03,0x64,0x70,                      /* [ 6598] OBJ_issuerSignTool */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x18,       /* [ 6603] OBJ_tlsfeature */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x11,       /* [ 6611] OBJ_ipsec_IKE */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x12,       /* [ 6619] OBJ_capwapAC */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x13,       /* [ 6627] OBJ_capwapWTP */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x15,       /* [ 6635] OBJ_sshClient */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x16,       /* [ 6643] OBJ_sshServer */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x17,       /* [ 6651] OBJ_sendRouter */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x18,       /* [ 6659] OBJ_sendProxiedRouter */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x19,       /* [ 6667] OBJ_sendOwner */
+    0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x1A,       /* [ 6675] OBJ_sendProxiedOwner */
+    0x2B,0x06,0x01,0x05,0x02,0x03,                 /* [ 6683] OBJ_id_pkinit */
+    0x2B,0x06,0x01,0x05,0x02,0x03,0x04,            /* [ 6689] OBJ_pkInitClientAuth */
+    0x2B,0x06,0x01,0x05,0x02,0x03,0x05,            /* [ 6696] OBJ_pkInitKDC */
+    0x2B,0x65,0x6E,                                /* [ 6703] OBJ_X25519 */
+    0x2B,0x65,0x6F,                                /* [ 6706] OBJ_X448 */
+    0x2B,0x06,0x01,0x04,0x01,0x8D,0x3A,0x0C,0x02,0x01,0x10,  /* [ 6709] OBJ_blake2b512 */
+    0x2B,0x06,0x01,0x04,0x01,0x8D,0x3A,0x0C,0x02,0x02,0x08,  /* [ 6720] OBJ_blake2s256 */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x13,  /* [ 6731] OBJ_id_smime_ct_contentCollection */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x17,  /* [ 6742] OBJ_id_smime_ct_authEnvelopedData */
+    0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x1C,  /* [ 6753] OBJ_id_ct_xml */
+};
+
+#define NUM_NID 1061
+static const ASN1_OBJECT nid_objs[NUM_NID] = {
+    {"UNDEF", "undefined", NID_undef},
+    {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
+    {"pkcs", "RSA Data Security, Inc. PKCS", NID_pkcs, 7, &so[6]},
+    {"MD2", "md2", NID_md2, 8, &so[13]},
+    {"MD5", "md5", NID_md5, 8, &so[21]},
+    {"RC4", "rc4", NID_rc4, 8, &so[29]},
+    {"rsaEncryption", "rsaEncryption", NID_rsaEncryption, 9, &so[37]},
+    {"RSA-MD2", "md2WithRSAEncryption", NID_md2WithRSAEncryption, 9, &so[46]},
+    {"RSA-MD5", "md5WithRSAEncryption", NID_md5WithRSAEncryption, 9, &so[55]},
+    {"PBE-MD2-DES", "pbeWithMD2AndDES-CBC", NID_pbeWithMD2AndDES_CBC, 9, &so[64]},
+    {"PBE-MD5-DES", "pbeWithMD5AndDES-CBC", NID_pbeWithMD5AndDES_CBC, 9, &so[73]},
+    {"X500", "directory services (X.500)", NID_X500, 1, &so[82]},
+    {"X509", "X509", NID_X509, 2, &so[83]},
+    {"CN", "commonName", NID_commonName, 3, &so[85]},
+    {"C", "countryName", NID_countryName, 3, &so[88]},
+    {"L", "localityName", NID_localityName, 3, &so[91]},
+    {"ST", "stateOrProvinceName", NID_stateOrProvinceName, 3, &so[94]},
+    {"O", "organizationName", NID_organizationName, 3, &so[97]},
+    {"OU", "organizationalUnitName", NID_organizationalUnitName, 3, &so[100]},
+    {"RSA", "rsa", NID_rsa, 4, &so[103]},
+    {"pkcs7", "pkcs7", NID_pkcs7, 8, &so[107]},
+    {"pkcs7-data", "pkcs7-data", NID_pkcs7_data, 9, &so[115]},
+    {"pkcs7-signedData", "pkcs7-signedData", NID_pkcs7_signed, 9, &so[124]},
+    {"pkcs7-envelopedData", "pkcs7-envelopedData", NID_pkcs7_enveloped, 9, &so[133]},
+    {"pkcs7-signedAndEnvelopedData", "pkcs7-signedAndEnvelopedData", NID_pkcs7_signedAndEnveloped, 9, &so[142]},
+    {"pkcs7-digestData", "pkcs7-digestData", NID_pkcs7_digest, 9, &so[151]},
+    {"pkcs7-encryptedData", "pkcs7-encryptedData", NID_pkcs7_encrypted, 9, &so[160]},
+    {"pkcs3", "pkcs3", NID_pkcs3, 8, &so[169]},
+    {"dhKeyAgreement", "dhKeyAgreement", NID_dhKeyAgreement, 9, &so[177]},
+    {"DES-ECB", "des-ecb", NID_des_ecb, 5, &so[186]},
+    {"DES-CFB", "des-cfb", NID_des_cfb64, 5, &so[191]},
+    {"DES-CBC", "des-cbc", NID_des_cbc, 5, &so[196]},
+    {"DES-EDE", "des-ede", NID_des_ede_ecb, 5, &so[201]},
+    {"DES-EDE3", "des-ede3", NID_des_ede3_ecb},
+    {"IDEA-CBC", "idea-cbc", NID_idea_cbc, 11, &so[206]},
+    {"IDEA-CFB", "idea-cfb", NID_idea_cfb64},
+    {"IDEA-ECB", "idea-ecb", NID_idea_ecb},
+    {"RC2-CBC", "rc2-cbc", NID_rc2_cbc, 8, &so[217]},
+    {"RC2-ECB", "rc2-ecb", NID_rc2_ecb},
+    {"RC2-CFB", "rc2-cfb", NID_rc2_cfb64},
+    {"RC2-OFB", "rc2-ofb", NID_rc2_ofb64},
+    {"SHA", "sha", NID_sha, 5, &so[225]},
+    {"RSA-SHA", "shaWithRSAEncryption", NID_shaWithRSAEncryption, 5, &so[230]},
+    {"DES-EDE-CBC", "des-ede-cbc", NID_des_ede_cbc},
+    {"DES-EDE3-CBC", "des-ede3-cbc", NID_des_ede3_cbc, 8, &so[235]},
+    {"DES-OFB", "des-ofb", NID_des_ofb64, 5, &so[243]},
+    {"IDEA-OFB", "idea-ofb", NID_idea_ofb64},
+    {"pkcs9", "pkcs9", NID_pkcs9, 8, &so[248]},
+    {"emailAddress", "emailAddress", NID_pkcs9_emailAddress, 9, &so[256]},
+    {"unstructuredName", "unstructuredName", NID_pkcs9_unstructuredName, 9, &so[265]},
+    {"contentType", "contentType", NID_pkcs9_contentType, 9, &so[274]},
+    {"messageDigest", "messageDigest", NID_pkcs9_messageDigest, 9, &so[283]},
+    {"signingTime", "signingTime", NID_pkcs9_signingTime, 9, &so[292]},
+    {"countersignature", "countersignature", NID_pkcs9_countersignature, 9, &so[301]},
+    {"challengePassword", "challengePassword", NID_pkcs9_challengePassword, 9, &so[310]},
+    {"unstructuredAddress", "unstructuredAddress", NID_pkcs9_unstructuredAddress, 9, &so[319]},
+    {"extendedCertificateAttributes", "extendedCertificateAttributes", NID_pkcs9_extCertAttributes, 9, &so[328]},
+    {"Netscape", "Netscape Communications Corp.", NID_netscape, 7, &so[337]},
+    {"nsCertExt", "Netscape Certificate Extension", NID_netscape_cert_extension, 8, &so[344]},
+    {"nsDataType", "Netscape Data Type", NID_netscape_data_type, 8, &so[352]},
+    {"DES-EDE-CFB", "des-ede-cfb", NID_des_ede_cfb64},
+    {"DES-EDE3-CFB", "des-ede3-cfb", NID_des_ede3_cfb64},
+    {"DES-EDE-OFB", "des-ede-ofb", NID_des_ede_ofb64},
+    {"DES-EDE3-OFB", "des-ede3-ofb", NID_des_ede3_ofb64},
+    {"SHA1", "sha1", NID_sha1, 5, &so[360]},
+    {"RSA-SHA1", "sha1WithRSAEncryption", NID_sha1WithRSAEncryption, 9, &so[365]},
+    {"DSA-SHA", "dsaWithSHA", NID_dsaWithSHA, 5, &so[374]},
+    {"DSA-old", "dsaEncryption-old", NID_dsa_2, 5, &so[379]},
+    {"PBE-SHA1-RC2-64", "pbeWithSHA1AndRC2-CBC", NID_pbeWithSHA1AndRC2_CBC, 9, &so[384]},
+    {"PBKDF2", "PBKDF2", NID_id_pbkdf2, 9, &so[393]},
+    {"DSA-SHA1-old", "dsaWithSHA1-old", NID_dsaWithSHA1_2, 5, &so[402]},
+    {"nsCertType", "Netscape Cert Type", NID_netscape_cert_type, 9, &so[407]},
+    {"nsBaseUrl", "Netscape Base Url", NID_netscape_base_url, 9, &so[416]},
+    {"nsRevocationUrl", "Netscape Revocation Url", NID_netscape_revocation_url, 9, &so[425]},
+    {"nsCaRevocationUrl", "Netscape CA Revocation Url", NID_netscape_ca_revocation_url, 9, &so[434]},
+    {"nsRenewalUrl", "Netscape Renewal Url", NID_netscape_renewal_url, 9, &so[443]},
+    {"nsCaPolicyUrl", "Netscape CA Policy Url", NID_netscape_ca_policy_url, 9, &so[452]},
+    {"nsSslServerName", "Netscape SSL Server Name", NID_netscape_ssl_server_name, 9, &so[461]},
+    {"nsComment", "Netscape Comment", NID_netscape_comment, 9, &so[470]},
+    {"nsCertSequence", "Netscape Certificate Sequence", NID_netscape_cert_sequence, 9, &so[479]},
+    {"DESX-CBC", "desx-cbc", NID_desx_cbc},
+    {"id-ce", "id-ce", NID_id_ce, 2, &so[488]},
+    {"subjectKeyIdentifier", "X509v3 Subject Key Identifier", NID_subject_key_identifier, 3, &so[490]},
+    {"keyUsage", "X509v3 Key Usage", NID_key_usage, 3, &so[493]},
+    {"privateKeyUsagePeriod", "X509v3 Private Key Usage Period", NID_private_key_usage_period, 3, &so[496]},
+    {"subjectAltName", "X509v3 Subject Alternative Name", NID_subject_alt_name, 3, &so[499]},
+    {"issuerAltName", "X509v3 Issuer Alternative Name", NID_issuer_alt_name, 3, &so[502]},
+    {"basicConstraints", "X509v3 Basic Constraints", NID_basic_constraints, 3, &so[505]},
+    {"crlNumber", "X509v3 CRL Number", NID_crl_number, 3, &so[508]},
+    {"certificatePolicies", "X509v3 Certificate Policies", NID_certificate_policies, 3, &so[511]},
+    {"authorityKeyIdentifier", "X509v3 Authority Key Identifier", NID_authority_key_identifier, 3, &so[514]},
+    {"BF-CBC", "bf-cbc", NID_bf_cbc, 9, &so[517]},
+    {"BF-ECB", "bf-ecb", NID_bf_ecb},
+    {"BF-CFB", "bf-cfb", NID_bf_cfb64},
+    {"BF-OFB", "bf-ofb", NID_bf_ofb64},
+    {"MDC2", "mdc2", NID_mdc2, 4, &so[526]},
+    {"RSA-MDC2", "mdc2WithRSA", NID_mdc2WithRSA, 4, &so[530]},
+    {"RC4-40", "rc4-40", NID_rc4_40},
+    {"RC2-40-CBC", "rc2-40-cbc", NID_rc2_40_cbc},
+    {"GN", "givenName", NID_givenName, 3, &so[534]},
+    {"SN", "surname", NID_surname, 3, &so[537]},
+    {"initials", "initials", NID_initials, 3, &so[540]},
+    {"uid", "uniqueIdentifier", NID_uniqueIdentifier, 10, &so[543]},
+    {"crlDistributionPoints", "X509v3 CRL Distribution Points", NID_crl_distribution_points, 3, &so[553]},
+    {"RSA-NP-MD5", "md5WithRSA", NID_md5WithRSA, 5, &so[556]},
+    {"serialNumber", "serialNumber", NID_serialNumber, 3, &so[561]},
+    {"title", "title", NID_title, 3, &so[564]},
+    {"description", "description", NID_description, 3, &so[567]},
+    {"CAST5-CBC", "cast5-cbc", NID_cast5_cbc, 9, &so[570]},
+    {"CAST5-ECB", "cast5-ecb", NID_cast5_ecb},
+    {"CAST5-CFB", "cast5-cfb", NID_cast5_cfb64},
+    {"CAST5-OFB", "cast5-ofb", NID_cast5_ofb64},
+    {"pbeWithMD5AndCast5CBC", "pbeWithMD5AndCast5CBC", NID_pbeWithMD5AndCast5_CBC, 9, &so[579]},
+    {"DSA-SHA1", "dsaWithSHA1", NID_dsaWithSHA1, 7, &so[588]},
+    {"MD5-SHA1", "md5-sha1", NID_md5_sha1},
+    {"RSA-SHA1-2", "sha1WithRSA", NID_sha1WithRSA, 5, &so[595]},
+    {"DSA", "dsaEncryption", NID_dsa, 7, &so[600]},
+    {"RIPEMD160", "ripemd160", NID_ripemd160, 5, &so[607]},
+    { NULL, NULL, NID_undef },
+    {"RSA-RIPEMD160", "ripemd160WithRSA", NID_ripemd160WithRSA, 6, &so[612]},
+    {"RC5-CBC", "rc5-cbc", NID_rc5_cbc, 8, &so[618]},
+    {"RC5-ECB", "rc5-ecb", NID_rc5_ecb},
+    {"RC5-CFB", "rc5-cfb", NID_rc5_cfb64},
+    {"RC5-OFB", "rc5-ofb", NID_rc5_ofb64},
+    { NULL, NULL, NID_undef },
+    {"ZLIB", "zlib compression", NID_zlib_compression, 11, &so[626]},
+    {"extendedKeyUsage", "X509v3 Extended Key Usage", NID_ext_key_usage, 3, &so[637]},
+    {"PKIX", "PKIX", NID_id_pkix, 6, &so[640]},
+    {"id-kp", "id-kp", NID_id_kp, 7, &so[646]},
+    {"serverAuth", "TLS Web Server Authentication", NID_server_auth, 8, &so[653]},
+    {"clientAuth", "TLS Web Client Authentication", NID_client_auth, 8, &so[661]},
+    {"codeSigning", "Code Signing", NID_code_sign, 8, &so[669]},
+    {"emailProtection", "E-mail Protection", NID_email_protect, 8, &so[677]},
+    {"timeStamping", "Time Stamping", NID_time_stamp, 8, &so[685]},
+    {"msCodeInd", "Microsoft Individual Code Signing", NID_ms_code_ind, 10, &so[693]},
+    {"msCodeCom", "Microsoft Commercial Code Signing", NID_ms_code_com, 10, &so[703]},
+    {"msCTLSign", "Microsoft Trust List Signing", NID_ms_ctl_sign, 10, &so[713]},
+    {"msSGC", "Microsoft Server Gated Crypto", NID_ms_sgc, 10, &so[723]},
+    {"msEFS", "Microsoft Encrypted File System", NID_ms_efs, 10, &so[733]},
+    {"nsSGC", "Netscape Server Gated Crypto", NID_ns_sgc, 9, &so[743]},
+    {"deltaCRL", "X509v3 Delta CRL Indicator", NID_delta_crl, 3, &so[752]},
+    {"CRLReason", "X509v3 CRL Reason Code", NID_crl_reason, 3, &so[755]},
+    {"invalidityDate", "Invalidity Date", NID_invalidity_date, 3, &so[758]},
+    {"SXNetID", "Strong Extranet ID", NID_sxnet, 5, &so[761]},
+    {"PBE-SHA1-RC4-128", "pbeWithSHA1And128BitRC4", NID_pbe_WithSHA1And128BitRC4, 10, &so[766]},
+    {"PBE-SHA1-RC4-40", "pbeWithSHA1And40BitRC4", NID_pbe_WithSHA1And40BitRC4, 10, &so[776]},
+    {"PBE-SHA1-3DES", "pbeWithSHA1And3-KeyTripleDES-CBC", NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 10, &so[786]},
+    {"PBE-SHA1-2DES", "pbeWithSHA1And2-KeyTripleDES-CBC", NID_pbe_WithSHA1And2_Key_TripleDES_CBC, 10, &so[796]},
+    {"PBE-SHA1-RC2-128", "pbeWithSHA1And128BitRC2-CBC", NID_pbe_WithSHA1And128BitRC2_CBC, 10, &so[806]},
+    {"PBE-SHA1-RC2-40", "pbeWithSHA1And40BitRC2-CBC", NID_pbe_WithSHA1And40BitRC2_CBC, 10, &so[816]},
+    {"keyBag", "keyBag", NID_keyBag, 11, &so[826]},
+    {"pkcs8ShroudedKeyBag", "pkcs8ShroudedKeyBag", NID_pkcs8ShroudedKeyBag, 11, &so[837]},
+    {"certBag", "certBag", NID_certBag, 11, &so[848]},
+    {"crlBag", "crlBag", NID_crlBag, 11, &so[859]},
+    {"secretBag", "secretBag", NID_secretBag, 11, &so[870]},
+    {"safeContentsBag", "safeContentsBag", NID_safeContentsBag, 11, &so[881]},
+    {"friendlyName", "friendlyName", NID_friendlyName, 9, &so[892]},
+    {"localKeyID", "localKeyID", NID_localKeyID, 9, &so[901]},
+    {"x509Certificate", "x509Certificate", NID_x509Certificate, 10, &so[910]},
+    {"sdsiCertificate", "sdsiCertificate", NID_sdsiCertificate, 10, &so[920]},
+    {"x509Crl", "x509Crl", NID_x509Crl, 10, &so[930]},
+    {"PBES2", "PBES2", NID_pbes2, 9, &so[940]},
+    {"PBMAC1", "PBMAC1", NID_pbmac1, 9, &so[949]},
+    {"hmacWithSHA1", "hmacWithSHA1", NID_hmacWithSHA1, 8, &so[958]},
+    {"id-qt-cps", "Policy Qualifier CPS", NID_id_qt_cps, 8, &so[966]},
+    {"id-qt-unotice", "Policy Qualifier User Notice", NID_id_qt_unotice, 8, &so[974]},
+    {"RC2-64-CBC", "rc2-64-cbc", NID_rc2_64_cbc},
+    {"SMIME-CAPS", "S/MIME Capabilities", NID_SMIMECapabilities, 9, &so[982]},
+    {"PBE-MD2-RC2-64", "pbeWithMD2AndRC2-CBC", NID_pbeWithMD2AndRC2_CBC, 9, &so[991]},
+    {"PBE-MD5-RC2-64", "pbeWithMD5AndRC2-CBC", NID_pbeWithMD5AndRC2_CBC, 9, &so[1000]},
+    {"PBE-SHA1-DES", "pbeWithSHA1AndDES-CBC", NID_pbeWithSHA1AndDES_CBC, 9, &so[1009]},
+    {"msExtReq", "Microsoft Extension Request", NID_ms_ext_req, 10, &so[1018]},
+    {"extReq", "Extension Request", NID_ext_req, 9, &so[1028]},
+    {"name", "name", NID_name, 3, &so[1037]},
+    {"dnQualifier", "dnQualifier", NID_dnQualifier, 3, &so[1040]},
+    {"id-pe", "id-pe", NID_id_pe, 7, &so[1043]},
+    {"id-ad", "id-ad", NID_id_ad, 7, &so[1050]},
+    {"authorityInfoAccess", "Authority Information Access", NID_info_access, 8, &so[1057]},
+    {"OCSP", "OCSP", NID_ad_OCSP, 8, &so[1065]},
+    {"caIssuers", "CA Issuers", NID_ad_ca_issuers, 8, &so[1073]},
+    {"OCSPSigning", "OCSP Signing", NID_OCSP_sign, 8, &so[1081]},
+    {"ISO", "iso", NID_iso},
+    {"member-body", "ISO Member Body", NID_member_body, 1, &so[1089]},
+    {"ISO-US", "ISO US Member Body", NID_ISO_US, 3, &so[1090]},
+    {"X9-57", "X9.57", NID_X9_57, 5, &so[1093]},
+    {"X9cm", "X9.57 CM ?", NID_X9cm, 6, &so[1098]},
+    {"pkcs1", "pkcs1", NID_pkcs1, 8, &so[1104]},
+    {"pkcs5", "pkcs5", NID_pkcs5, 8, &so[1112]},
+    {"SMIME", "S/MIME", NID_SMIME, 9, &so[1120]},
+    {"id-smime-mod", "id-smime-mod", NID_id_smime_mod, 10, &so[1129]},
+    {"id-smime-ct", "id-smime-ct", NID_id_smime_ct, 10, &so[1139]},
+    {"id-smime-aa", "id-smime-aa", NID_id_smime_aa, 10, &so[1149]},
+    {"id-smime-alg", "id-smime-alg", NID_id_smime_alg, 10, &so[1159]},
+    {"id-smime-cd", "id-smime-cd", NID_id_smime_cd, 10, &so[1169]},
+    {"id-smime-spq", "id-smime-spq", NID_id_smime_spq, 10, &so[1179]},
+    {"id-smime-cti", "id-smime-cti", NID_id_smime_cti, 10, &so[1189]},
+    {"id-smime-mod-cms", "id-smime-mod-cms", NID_id_smime_mod_cms, 11, &so[1199]},
+    {"id-smime-mod-ess", "id-smime-mod-ess", NID_id_smime_mod_ess, 11, &so[1210]},
+    {"id-smime-mod-oid", "id-smime-mod-oid", NID_id_smime_mod_oid, 11, &so[1221]},
+    {"id-smime-mod-msg-v3", "id-smime-mod-msg-v3", NID_id_smime_mod_msg_v3, 11, &so[1232]},
+    {"id-smime-mod-ets-eSignature-88", "id-smime-mod-ets-eSignature-88", NID_id_smime_mod_ets_eSignature_88, 11, &so[1243]},
+    {"id-smime-mod-ets-eSignature-97", "id-smime-mod-ets-eSignature-97", NID_id_smime_mod_ets_eSignature_97, 11, &so[1254]},
+    {"id-smime-mod-ets-eSigPolicy-88", "id-smime-mod-ets-eSigPolicy-88", NID_id_smime_mod_ets_eSigPolicy_88, 11, &so[1265]},
+    {"id-smime-mod-ets-eSigPolicy-97", "id-smime-mod-ets-eSigPolicy-97", NID_id_smime_mod_ets_eSigPolicy_97, 11, &so[1276]},
+    {"id-smime-ct-receipt", "id-smime-ct-receipt", NID_id_smime_ct_receipt, 11, &so[1287]},
+    {"id-smime-ct-authData", "id-smime-ct-authData", NID_id_smime_ct_authData, 11, &so[1298]},
+    {"id-smime-ct-publishCert", "id-smime-ct-publishCert", NID_id_smime_ct_publishCert, 11, &so[1309]},
+    {"id-smime-ct-TSTInfo", "id-smime-ct-TSTInfo", NID_id_smime_ct_TSTInfo, 11, &so[1320]},
+    {"id-smime-ct-TDTInfo", "id-smime-ct-TDTInfo", NID_id_smime_ct_TDTInfo, 11, &so[1331]},
+    {"id-smime-ct-contentInfo", "id-smime-ct-contentInfo", NID_id_smime_ct_contentInfo, 11, &so[1342]},
+    {"id-smime-ct-DVCSRequestData", "id-smime-ct-DVCSRequestData", NID_id_smime_ct_DVCSRequestData, 11, &so[1353]},
+    {"id-smime-ct-DVCSResponseData", "id-smime-ct-DVCSResponseData", NID_id_smime_ct_DVCSResponseData, 11, &so[1364]},
+    {"id-smime-aa-receiptRequest", "id-smime-aa-receiptRequest", NID_id_smime_aa_receiptRequest, 11, &so[1375]},
+    {"id-smime-aa-securityLabel", "id-smime-aa-securityLabel", NID_id_smime_aa_securityLabel, 11, &so[1386]},
+    {"id-smime-aa-mlExpandHistory", "id-smime-aa-mlExpandHistory", NID_id_smime_aa_mlExpandHistory, 11, &so[1397]},
+    {"id-smime-aa-contentHint", "id-smime-aa-contentHint", NID_id_smime_aa_contentHint, 11, &so[1408]},
+    {"id-smime-aa-msgSigDigest", "id-smime-aa-msgSigDigest", NID_id_smime_aa_msgSigDigest, 11, &so[1419]},
+    {"id-smime-aa-encapContentType", "id-smime-aa-encapContentType", NID_id_smime_aa_encapContentType, 11, &so[1430]},
+    {"id-smime-aa-contentIdentifier", "id-smime-aa-contentIdentifier", NID_id_smime_aa_contentIdentifier, 11, &so[1441]},
+    {"id-smime-aa-macValue", "id-smime-aa-macValue", NID_id_smime_aa_macValue, 11, &so[1452]},
+    {"id-smime-aa-equivalentLabels", "id-smime-aa-equivalentLabels", NID_id_smime_aa_equivalentLabels, 11, &so[1463]},
+    {"id-smime-aa-contentReference", "id-smime-aa-contentReference", NID_id_smime_aa_contentReference, 11, &so[1474]},
+    {"id-smime-aa-encrypKeyPref", "id-smime-aa-encrypKeyPref", NID_id_smime_aa_encrypKeyPref, 11, &so[1485]},
+    {"id-smime-aa-signingCertificate", "id-smime-aa-signingCertificate", NID_id_smime_aa_signingCertificate, 11, &so[1496]},
+    {"id-smime-aa-smimeEncryptCerts", "id-smime-aa-smimeEncryptCerts", NID_id_smime_aa_smimeEncryptCerts, 11, &so[1507]},
+    {"id-smime-aa-timeStampToken", "id-smime-aa-timeStampToken", NID_id_smime_aa_timeStampToken, 11, &so[1518]},
+    {"id-smime-aa-ets-sigPolicyId", "id-smime-aa-ets-sigPolicyId", NID_id_smime_aa_ets_sigPolicyId, 11, &so[1529]},
+    {"id-smime-aa-ets-commitmentType", "id-smime-aa-ets-commitmentType", NID_id_smime_aa_ets_commitmentType, 11, &so[1540]},
+    {"id-smime-aa-ets-signerLocation", "id-smime-aa-ets-signerLocation", NID_id_smime_aa_ets_signerLocation, 11, &so[1551]},
+    {"id-smime-aa-ets-signerAttr", "id-smime-aa-ets-signerAttr", NID_id_smime_aa_ets_signerAttr, 11, &so[1562]},
+    {"id-smime-aa-ets-otherSigCert", "id-smime-aa-ets-otherSigCert", NID_id_smime_aa_ets_otherSigCert, 11, &so[1573]},
+    {"id-smime-aa-ets-contentTimestamp", "id-smime-aa-ets-contentTimestamp", NID_id_smime_aa_ets_contentTimestamp, 11, &so[1584]},
+    {"id-smime-aa-ets-CertificateRefs", "id-smime-aa-ets-CertificateRefs", NID_id_smime_aa_ets_CertificateRefs, 11, &so[1595]},
+    {"id-smime-aa-ets-RevocationRefs", "id-smime-aa-ets-RevocationRefs", NID_id_smime_aa_ets_RevocationRefs, 11, &so[1606]},
+    {"id-smime-aa-ets-certValues", "id-smime-aa-ets-certValues", NID_id_smime_aa_ets_certValues, 11, &so[1617]},
+    {"id-smime-aa-ets-revocationValues", "id-smime-aa-ets-revocationValues", NID_id_smime_aa_ets_revocationValues, 11, &so[1628]},
+    {"id-smime-aa-ets-escTimeStamp", "id-smime-aa-ets-escTimeStamp", NID_id_smime_aa_ets_escTimeStamp, 11, &so[1639]},
+    {"id-smime-aa-ets-certCRLTimestamp", "id-smime-aa-ets-certCRLTimestamp", NID_id_smime_aa_ets_certCRLTimestamp, 11, &so[1650]},
+    {"id-smime-aa-ets-archiveTimeStamp", "id-smime-aa-ets-archiveTimeStamp", NID_id_smime_aa_ets_archiveTimeStamp, 11, &so[1661]},
+    {"id-smime-aa-signatureType", "id-smime-aa-signatureType", NID_id_smime_aa_signatureType, 11, &so[1672]},
+    {"id-smime-aa-dvcs-dvc", "id-smime-aa-dvcs-dvc", NID_id_smime_aa_dvcs_dvc, 11, &so[1683]},
+    {"id-smime-alg-ESDHwith3DES", "id-smime-alg-ESDHwith3DES", NID_id_smime_alg_ESDHwith3DES, 11, &so[1694]},
+    {"id-smime-alg-ESDHwithRC2", "id-smime-alg-ESDHwithRC2", NID_id_smime_alg_ESDHwithRC2, 11, &so[1705]},
+    {"id-smime-alg-3DESwrap", "id-smime-alg-3DESwrap", NID_id_smime_alg_3DESwrap, 11, &so[1716]},
+    {"id-smime-alg-RC2wrap", "id-smime-alg-RC2wrap", NID_id_smime_alg_RC2wrap, 11, &so[1727]},
+    {"id-smime-alg-ESDH", "id-smime-alg-ESDH", NID_id_smime_alg_ESDH, 11, &so[1738]},
+    {"id-smime-alg-CMS3DESwrap", "id-smime-alg-CMS3DESwrap", NID_id_smime_alg_CMS3DESwrap, 11, &so[1749]},
+    {"id-smime-alg-CMSRC2wrap", "id-smime-alg-CMSRC2wrap", NID_id_smime_alg_CMSRC2wrap, 11, &so[1760]},
+    {"id-smime-cd-ldap", "id-smime-cd-ldap", NID_id_smime_cd_ldap, 11, &so[1771]},
+    {"id-smime-spq-ets-sqt-uri", "id-smime-spq-ets-sqt-uri", NID_id_smime_spq_ets_sqt_uri, 11, &so[1782]},
+    {"id-smime-spq-ets-sqt-unotice", "id-smime-spq-ets-sqt-unotice", NID_id_smime_spq_ets_sqt_unotice, 11, &so[1793]},
+    {"id-smime-cti-ets-proofOfOrigin", "id-smime-cti-ets-proofOfOrigin", NID_id_smime_cti_ets_proofOfOrigin, 11, &so[1804]},
+    {"id-smime-cti-ets-proofOfReceipt", "id-smime-cti-ets-proofOfReceipt", NID_id_smime_cti_ets_proofOfReceipt, 11, &so[1815]},
+    {"id-smime-cti-ets-proofOfDelivery", "id-smime-cti-ets-proofOfDelivery", NID_id_smime_cti_ets_proofOfDelivery, 11, &so[1826]},
+    {"id-smime-cti-ets-proofOfSender", "id-smime-cti-ets-proofOfSender", NID_id_smime_cti_ets_proofOfSender, 11, &so[1837]},
+    {"id-smime-cti-ets-proofOfApproval", "id-smime-cti-ets-proofOfApproval", NID_id_smime_cti_ets_proofOfApproval, 11, &so[1848]},
+    {"id-smime-cti-ets-proofOfCreation", "id-smime-cti-ets-proofOfCreation", NID_id_smime_cti_ets_proofOfCreation, 11, &so[1859]},
+    {"MD4", "md4", NID_md4, 8, &so[1870]},
+    {"id-pkix-mod", "id-pkix-mod", NID_id_pkix_mod, 7, &so[1878]},
+    {"id-qt", "id-qt", NID_id_qt, 7, &so[1885]},
+    {"id-it", "id-it", NID_id_it, 7, &so[1892]},
+    {"id-pkip", "id-pkip", NID_id_pkip, 7, &so[1899]},
+    {"id-alg", "id-alg", NID_id_alg, 7, &so[1906]},
+    {"id-cmc", "id-cmc", NID_id_cmc, 7, &so[1913]},
+    {"id-on", "id-on", NID_id_on, 7, &so[1920]},
+    {"id-pda", "id-pda", NID_id_pda, 7, &so[1927]},
+    {"id-aca", "id-aca", NID_id_aca, 7, &so[1934]},
+    {"id-qcs", "id-qcs", NID_id_qcs, 7, &so[1941]},
+    {"id-cct", "id-cct", NID_id_cct, 7, &so[1948]},
+    {"id-pkix1-explicit-88", "id-pkix1-explicit-88", NID_id_pkix1_explicit_88, 8, &so[1955]},
+    {"id-pkix1-implicit-88", "id-pkix1-implicit-88", NID_id_pkix1_implicit_88, 8, &so[1963]},
+    {"id-pkix1-explicit-93", "id-pkix1-explicit-93", NID_id_pkix1_explicit_93, 8, &so[1971]},
+    {"id-pkix1-implicit-93", "id-pkix1-implicit-93", NID_id_pkix1_implicit_93, 8, &so[1979]},
+    {"id-mod-crmf", "id-mod-crmf", NID_id_mod_crmf, 8, &so[1987]},
+    {"id-mod-cmc", "id-mod-cmc", NID_id_mod_cmc, 8, &so[1995]},
+    {"id-mod-kea-profile-88", "id-mod-kea-profile-88", NID_id_mod_kea_profile_88, 8, &so[2003]},
+    {"id-mod-kea-profile-93", "id-mod-kea-profile-93", NID_id_mod_kea_profile_93, 8, &so[2011]},
+    {"id-mod-cmp", "id-mod-cmp", NID_id_mod_cmp, 8, &so[2019]},
+    {"id-mod-qualified-cert-88", "id-mod-qualified-cert-88", NID_id_mod_qualified_cert_88, 8, &so[2027]},
+    {"id-mod-qualified-cert-93", "id-mod-qualified-cert-93", NID_id_mod_qualified_cert_93, 8, &so[2035]},
+    {"id-mod-attribute-cert", "id-mod-attribute-cert", NID_id_mod_attribute_cert, 8, &so[2043]},
+    {"id-mod-timestamp-protocol", "id-mod-timestamp-protocol", NID_id_mod_timestamp_protocol, 8, &so[2051]},
+    {"id-mod-ocsp", "id-mod-ocsp", NID_id_mod_ocsp, 8, &so[2059]},
+    {"id-mod-dvcs", "id-mod-dvcs", NID_id_mod_dvcs, 8, &so[2067]},
+    {"id-mod-cmp2000", "id-mod-cmp2000", NID_id_mod_cmp2000, 8, &so[2075]},
+    {"biometricInfo", "Biometric Info", NID_biometricInfo, 8, &so[2083]},
+    {"qcStatements", "qcStatements", NID_qcStatements, 8, &so[2091]},
+    {"ac-auditEntity", "ac-auditEntity", NID_ac_auditEntity, 8, &so[2099]},
+    {"ac-targeting", "ac-targeting", NID_ac_targeting, 8, &so[2107]},
+    {"aaControls", "aaControls", NID_aaControls, 8, &so[2115]},
+    {"sbgp-ipAddrBlock", "sbgp-ipAddrBlock", NID_sbgp_ipAddrBlock, 8, &so[2123]},
+    {"sbgp-autonomousSysNum", "sbgp-autonomousSysNum", NID_sbgp_autonomousSysNum, 8, &so[2131]},
+    {"sbgp-routerIdentifier", "sbgp-routerIdentifier", NID_sbgp_routerIdentifier, 8, &so[2139]},
+    {"textNotice", "textNotice", NID_textNotice, 8, &so[2147]},
+    {"ipsecEndSystem", "IPSec End System", NID_ipsecEndSystem, 8, &so[2155]},
+    {"ipsecTunnel", "IPSec Tunnel", NID_ipsecTunnel, 8, &so[2163]},
+    {"ipsecUser", "IPSec User", NID_ipsecUser, 8, &so[2171]},
+    {"DVCS", "dvcs", NID_dvcs, 8, &so[2179]},
+    {"id-it-caProtEncCert", "id-it-caProtEncCert", NID_id_it_caProtEncCert, 8, &so[2187]},
+    {"id-it-signKeyPairTypes", "id-it-signKeyPairTypes", NID_id_it_signKeyPairTypes, 8, &so[2195]},
+    {"id-it-encKeyPairTypes", "id-it-encKeyPairTypes", NID_id_it_encKeyPairTypes, 8, &so[2203]},
+    {"id-it-preferredSymmAlg", "id-it-preferredSymmAlg", NID_id_it_preferredSymmAlg, 8, &so[2211]},
+    {"id-it-caKeyUpdateInfo", "id-it-caKeyUpdateInfo", NID_id_it_caKeyUpdateInfo, 8, &so[2219]},
+    {"id-it-currentCRL", "id-it-currentCRL", NID_id_it_currentCRL, 8, &so[2227]},
+    {"id-it-unsupportedOIDs", "id-it-unsupportedOIDs", NID_id_it_unsupportedOIDs, 8, &so[2235]},
+    {"id-it-subscriptionRequest", "id-it-subscriptionRequest", NID_id_it_subscriptionRequest, 8, &so[2243]},
+    {"id-it-subscriptionResponse", "id-it-subscriptionResponse", NID_id_it_subscriptionResponse, 8, &so[2251]},
+    {"id-it-keyPairParamReq", "id-it-keyPairParamReq", NID_id_it_keyPairParamReq, 8, &so[2259]},
+    {"id-it-keyPairParamRep", "id-it-keyPairParamRep", NID_id_it_keyPairParamRep, 8, &so[2267]},
+    {"id-it-revPassphrase", "id-it-revPassphrase", NID_id_it_revPassphrase, 8, &so[2275]},
+    {"id-it-implicitConfirm", "id-it-implicitConfirm", NID_id_it_implicitConfirm, 8, &so[2283]},
+    {"id-it-confirmWaitTime", "id-it-confirmWaitTime", NID_id_it_confirmWaitTime, 8, &so[2291]},
+    {"id-it-origPKIMessage", "id-it-origPKIMessage", NID_id_it_origPKIMessage, 8, &so[2299]},
+    {"id-regCtrl", "id-regCtrl", NID_id_regCtrl, 8, &so[2307]},
+    {"id-regInfo", "id-regInfo", NID_id_regInfo, 8, &so[2315]},
+    {"id-regCtrl-regToken", "id-regCtrl-regToken", NID_id_regCtrl_regToken, 9, &so[2323]},
+    {"id-regCtrl-authenticator", "id-regCtrl-authenticator", NID_id_regCtrl_authenticator, 9, &so[2332]},
+    {"id-regCtrl-pkiPublicationInfo", "id-regCtrl-pkiPublicationInfo", NID_id_regCtrl_pkiPublicationInfo, 9, &so[2341]},
+    {"id-regCtrl-pkiArchiveOptions", "id-regCtrl-pkiArchiveOptions", NID_id_regCtrl_pkiArchiveOptions, 9, &so[2350]},
+    {"id-regCtrl-oldCertID", "id-regCtrl-oldCertID", NID_id_regCtrl_oldCertID, 9, &so[2359]},
+    {"id-regCtrl-protocolEncrKey", "id-regCtrl-protocolEncrKey", NID_id_regCtrl_protocolEncrKey, 9, &so[2368]},
+    {"id-regInfo-utf8Pairs", "id-regInfo-utf8Pairs", NID_id_regInfo_utf8Pairs, 9, &so[2377]},
+    {"id-regInfo-certReq", "id-regInfo-certReq", NID_id_regInfo_certReq, 9, &so[2386]},
+    {"id-alg-des40", "id-alg-des40", NID_id_alg_des40, 8, &so[2395]},
+    {"id-alg-noSignature", "id-alg-noSignature", NID_id_alg_noSignature, 8, &so[2403]},
+    {"id-alg-dh-sig-hmac-sha1", "id-alg-dh-sig-hmac-sha1", NID_id_alg_dh_sig_hmac_sha1, 8, &so[2411]},
+    {"id-alg-dh-pop", "id-alg-dh-pop", NID_id_alg_dh_pop, 8, &so[2419]},
+    {"id-cmc-statusInfo", "id-cmc-statusInfo", NID_id_cmc_statusInfo, 8, &so[2427]},
+    {"id-cmc-identification", "id-cmc-identification", NID_id_cmc_identification, 8, &so[2435]},
+    {"id-cmc-identityProof", "id-cmc-identityProof", NID_id_cmc_identityProof, 8, &so[2443]},
+    {"id-cmc-dataReturn", "id-cmc-dataReturn", NID_id_cmc_dataReturn, 8, &so[2451]},
+    {"id-cmc-transactionId", "id-cmc-transactionId", NID_id_cmc_transactionId, 8, &so[2459]},
+    {"id-cmc-senderNonce", "id-cmc-senderNonce", NID_id_cmc_senderNonce, 8, &so[2467]},
+    {"id-cmc-recipientNonce", "id-cmc-recipientNonce", NID_id_cmc_recipientNonce, 8, &so[2475]},
+    {"id-cmc-addExtensions", "id-cmc-addExtensions", NID_id_cmc_addExtensions, 8, &so[2483]},
+    {"id-cmc-encryptedPOP", "id-cmc-encryptedPOP", NID_id_cmc_encryptedPOP, 8, &so[2491]},
+    {"id-cmc-decryptedPOP", "id-cmc-decryptedPOP", NID_id_cmc_decryptedPOP, 8, &so[2499]},
+    {"id-cmc-lraPOPWitness", "id-cmc-lraPOPWitness", NID_id_cmc_lraPOPWitness, 8, &so[2507]},
+    {"id-cmc-getCert", "id-cmc-getCert", NID_id_cmc_getCert, 8, &so[2515]},
+    {"id-cmc-getCRL", "id-cmc-getCRL", NID_id_cmc_getCRL, 8, &so[2523]},
+    {"id-cmc-revokeRequest", "id-cmc-revokeRequest", NID_id_cmc_revokeRequest, 8, &so[2531]},
+    {"id-cmc-regInfo", "id-cmc-regInfo", NID_id_cmc_regInfo, 8, &so[2539]},
+    {"id-cmc-responseInfo", "id-cmc-responseInfo", NID_id_cmc_responseInfo, 8, &so[2547]},
+    {"id-cmc-queryPending", "id-cmc-queryPending", NID_id_cmc_queryPending, 8, &so[2555]},
+    {"id-cmc-popLinkRandom", "id-cmc-popLinkRandom", NID_id_cmc_popLinkRandom, 8, &so[2563]},
+    {"id-cmc-popLinkWitness", "id-cmc-popLinkWitness", NID_id_cmc_popLinkWitness, 8, &so[2571]},
+    {"id-cmc-confirmCertAcceptance", "id-cmc-confirmCertAcceptance", NID_id_cmc_confirmCertAcceptance, 8, &so[2579]},
+    {"id-on-personalData", "id-on-personalData", NID_id_on_personalData, 8, &so[2587]},
+    {"id-pda-dateOfBirth", "id-pda-dateOfBirth", NID_id_pda_dateOfBirth, 8, &so[2595]},
+    {"id-pda-placeOfBirth", "id-pda-placeOfBirth", NID_id_pda_placeOfBirth, 8, &so[2603]},
+    { NULL, NULL, NID_undef },
+    {"id-pda-gender", "id-pda-gender", NID_id_pda_gender, 8, &so[2611]},
+    {"id-pda-countryOfCitizenship", "id-pda-countryOfCitizenship", NID_id_pda_countryOfCitizenship, 8, &so[2619]},
+    {"id-pda-countryOfResidence", "id-pda-countryOfResidence", NID_id_pda_countryOfResidence, 8, &so[2627]},
+    {"id-aca-authenticationInfo", "id-aca-authenticationInfo", NID_id_aca_authenticationInfo, 8, &so[2635]},
+    {"id-aca-accessIdentity", "id-aca-accessIdentity", NID_id_aca_accessIdentity, 8, &so[2643]},
+    {"id-aca-chargingIdentity", "id-aca-chargingIdentity", NID_id_aca_chargingIdentity, 8, &so[2651]},
+    {"id-aca-group", "id-aca-group", NID_id_aca_group, 8, &so[2659]},
+    {"id-aca-role", "id-aca-role", NID_id_aca_role, 8, &so[2667]},
+    {"id-qcs-pkixQCSyntax-v1", "id-qcs-pkixQCSyntax-v1", NID_id_qcs_pkixQCSyntax_v1, 8, &so[2675]},
+    {"id-cct-crs", "id-cct-crs", NID_id_cct_crs, 8, &so[2683]},
+    {"id-cct-PKIData", "id-cct-PKIData", NID_id_cct_PKIData, 8, &so[2691]},
+    {"id-cct-PKIResponse", "id-cct-PKIResponse", NID_id_cct_PKIResponse, 8, &so[2699]},
+    {"ad_timestamping", "AD Time Stamping", NID_ad_timeStamping, 8, &so[2707]},
+    {"AD_DVCS", "ad dvcs", NID_ad_dvcs, 8, &so[2715]},
+    {"basicOCSPResponse", "Basic OCSP Response", NID_id_pkix_OCSP_basic, 9, &so[2723]},
+    {"Nonce", "OCSP Nonce", NID_id_pkix_OCSP_Nonce, 9, &so[2732]},
+    {"CrlID", "OCSP CRL ID", NID_id_pkix_OCSP_CrlID, 9, &so[2741]},
+    {"acceptableResponses", "Acceptable OCSP Responses", NID_id_pkix_OCSP_acceptableResponses, 9, &so[2750]},
+    {"noCheck", "OCSP No Check", NID_id_pkix_OCSP_noCheck, 9, &so[2759]},
+    {"archiveCutoff", "OCSP Archive Cutoff", NID_id_pkix_OCSP_archiveCutoff, 9, &so[2768]},
+    {"serviceLocator", "OCSP Service Locator", NID_id_pkix_OCSP_serviceLocator, 9, &so[2777]},
+    {"extendedStatus", "Extended OCSP Status", NID_id_pkix_OCSP_extendedStatus, 9, &so[2786]},
+    {"valid", "valid", NID_id_pkix_OCSP_valid, 9, &so[2795]},
+    {"path", "path", NID_id_pkix_OCSP_path, 9, &so[2804]},
+    {"trustRoot", "Trust Root", NID_id_pkix_OCSP_trustRoot, 9, &so[2813]},
+    {"algorithm", "algorithm", NID_algorithm, 4, &so[2822]},
+    {"rsaSignature", "rsaSignature", NID_rsaSignature, 5, &so[2826]},
+    {"X500algorithms", "directory services - algorithms", NID_X500algorithms, 2, &so[2831]},
+    {"ORG", "org", NID_org, 1, &so[2833]},
+    {"DOD", "dod", NID_dod, 2, &so[2834]},
+    {"IANA", "iana", NID_iana, 3, &so[2836]},
+    {"directory", "Directory", NID_Directory, 4, &so[2839]},
+    {"mgmt", "Management", NID_Management, 4, &so[2843]},
+    {"experimental", "Experimental", NID_Experimental, 4, &so[2847]},
+    {"private", "Private", NID_Private, 4, &so[2851]},
+    {"security", "Security", NID_Security, 4, &so[2855]},
+    {"snmpv2", "SNMPv2", NID_SNMPv2, 4, &so[2859]},
+    {"Mail", "Mail", NID_Mail, 4, &so[2863]},
+    {"enterprises", "Enterprises", NID_Enterprises, 5, &so[2867]},
+    {"dcobject", "dcObject", NID_dcObject, 9, &so[2872]},
+    {"DC", "domainComponent", NID_domainComponent, 10, &so[2881]},
+    {"domain", "Domain", NID_Domain, 10, &so[2891]},
+    {"NULL", "NULL", NID_joint_iso_ccitt},
+    {"selected-attribute-types", "Selected Attribute Types", NID_selected_attribute_types, 3, &so[2901]},
+    {"clearance", "clearance", NID_clearance, 4, &so[2904]},
+    {"RSA-MD4", "md4WithRSAEncryption", NID_md4WithRSAEncryption, 9, &so[2908]},
+    {"ac-proxying", "ac-proxying", NID_ac_proxying, 8, &so[2917]},
+    {"subjectInfoAccess", "Subject Information Access", NID_sinfo_access, 8, &so[2925]},
+    {"id-aca-encAttrs", "id-aca-encAttrs", NID_id_aca_encAttrs, 8, &so[2933]},
+    {"role", "role", NID_role, 3, &so[2941]},
+    {"policyConstraints", "X509v3 Policy Constraints", NID_policy_constraints, 3, &so[2944]},
+    {"targetInformation", "X509v3 AC Targeting", NID_target_information, 3, &so[2947]},
+    {"noRevAvail", "X509v3 No Revocation Available", NID_no_rev_avail, 3, &so[2950]},
+    {"NULL", "NULL", NID_ccitt},
+    {"ansi-X9-62", "ANSI X9.62", NID_ansi_X9_62, 5, &so[2953]},
+    {"prime-field", "prime-field", NID_X9_62_prime_field, 7, &so[2958]},
+    {"characteristic-two-field", "characteristic-two-field", NID_X9_62_characteristic_two_field, 7, &so[2965]},
+    {"id-ecPublicKey", "id-ecPublicKey", NID_X9_62_id_ecPublicKey, 7, &so[2972]},
+    {"prime192v1", "prime192v1", NID_X9_62_prime192v1, 8, &so[2979]},
+    {"prime192v2", "prime192v2", NID_X9_62_prime192v2, 8, &so[2987]},
+    {"prime192v3", "prime192v3", NID_X9_62_prime192v3, 8, &so[2995]},
+    {"prime239v1", "prime239v1", NID_X9_62_prime239v1, 8, &so[3003]},
+    {"prime239v2", "prime239v2", NID_X9_62_prime239v2, 8, &so[3011]},
+    {"prime239v3", "prime239v3", NID_X9_62_prime239v3, 8, &so[3019]},
+    {"prime256v1", "prime256v1", NID_X9_62_prime256v1, 8, &so[3027]},
+    {"ecdsa-with-SHA1", "ecdsa-with-SHA1", NID_ecdsa_with_SHA1, 7, &so[3035]},
+    {"CSPName", "Microsoft CSP Name", NID_ms_csp_name, 9, &so[3042]},
+    {"AES-128-ECB", "aes-128-ecb", NID_aes_128_ecb, 9, &so[3051]},
+    {"AES-128-CBC", "aes-128-cbc", NID_aes_128_cbc, 9, &so[3060]},
+    {"AES-128-OFB", "aes-128-ofb", NID_aes_128_ofb128, 9, &so[3069]},
+    {"AES-128-CFB", "aes-128-cfb", NID_aes_128_cfb128, 9, &so[3078]},
+    {"AES-192-ECB", "aes-192-ecb", NID_aes_192_ecb, 9, &so[3087]},
+    {"AES-192-CBC", "aes-192-cbc", NID_aes_192_cbc, 9, &so[3096]},
+    {"AES-192-OFB", "aes-192-ofb", NID_aes_192_ofb128, 9, &so[3105]},
+    {"AES-192-CFB", "aes-192-cfb", NID_aes_192_cfb128, 9, &so[3114]},
+    {"AES-256-ECB", "aes-256-ecb", NID_aes_256_ecb, 9, &so[3123]},
+    {"AES-256-CBC", "aes-256-cbc", NID_aes_256_cbc, 9, &so[3132]},
+    {"AES-256-OFB", "aes-256-ofb", NID_aes_256_ofb128, 9, &so[3141]},
+    {"AES-256-CFB", "aes-256-cfb", NID_aes_256_cfb128, 9, &so[3150]},
+    {"holdInstructionCode", "Hold Instruction Code", NID_hold_instruction_code, 3, &so[3159]},
+    {"holdInstructionNone", "Hold Instruction None", NID_hold_instruction_none, 7, &so[3162]},
+    {"holdInstructionCallIssuer", "Hold Instruction Call Issuer", NID_hold_instruction_call_issuer, 7, &so[3169]},
+    {"holdInstructionReject", "Hold Instruction Reject", NID_hold_instruction_reject, 7, &so[3176]},
+    {"data", "data", NID_data, 1, &so[3183]},
+    {"pss", "pss", NID_pss, 3, &so[3184]},
+    {"ucl", "ucl", NID_ucl, 7, &so[3187]},
+    {"pilot", "pilot", NID_pilot, 8, &so[3194]},
+    {"pilotAttributeType", "pilotAttributeType", NID_pilotAttributeType, 9, &so[3202]},
+    {"pilotAttributeSyntax", "pilotAttributeSyntax", NID_pilotAttributeSyntax, 9, &so[3211]},
+    {"pilotObjectClass", "pilotObjectClass", NID_pilotObjectClass, 9, &so[3220]},
+    {"pilotGroups", "pilotGroups", NID_pilotGroups, 9, &so[3229]},
+    {"iA5StringSyntax", "iA5StringSyntax", NID_iA5StringSyntax, 10, &so[3238]},
+    {"caseIgnoreIA5StringSyntax", "caseIgnoreIA5StringSyntax", NID_caseIgnoreIA5StringSyntax, 10, &so[3248]},
+    {"pilotObject", "pilotObject", NID_pilotObject, 10, &so[3258]},
+    {"pilotPerson", "pilotPerson", NID_pilotPerson, 10, &so[3268]},
+    {"account", "account", NID_account, 10, &so[3278]},
+    {"document", "document", NID_document, 10, &so[3288]},
+    {"room", "room", NID_room, 10, &so[3298]},
+    {"documentSeries", "documentSeries", NID_documentSeries, 10, &so[3308]},
+    {"rFC822localPart", "rFC822localPart", NID_rFC822localPart, 10, &so[3318]},
+    {"dNSDomain", "dNSDomain", NID_dNSDomain, 10, &so[3328]},
+    {"domainRelatedObject", "domainRelatedObject", NID_domainRelatedObject, 10, &so[3338]},
+    {"friendlyCountry", "friendlyCountry", NID_friendlyCountry, 10, &so[3348]},
+    {"simpleSecurityObject", "simpleSecurityObject", NID_simpleSecurityObject, 10, &so[3358]},
+    {"pilotOrganization", "pilotOrganization", NID_pilotOrganization, 10, &so[3368]},
+    {"pilotDSA", "pilotDSA", NID_pilotDSA, 10, &so[3378]},
+    {"qualityLabelledData", "qualityLabelledData", NID_qualityLabelledData, 10, &so[3388]},
+    {"UID", "userId", NID_userId, 10, &so[3398]},
+    {"textEncodedORAddress", "textEncodedORAddress", NID_textEncodedORAddress, 10, &so[3408]},
+    {"mail", "rfc822Mailbox", NID_rfc822Mailbox, 10, &so[3418]},
+    {"info", "info", NID_info, 10, &so[3428]},
+    {"favouriteDrink", "favouriteDrink", NID_favouriteDrink, 10, &so[3438]},
+    {"roomNumber", "roomNumber", NID_roomNumber, 10, &so[3448]},
+    {"photo", "photo", NID_photo, 10, &so[3458]},
+    {"userClass", "userClass", NID_userClass, 10, &so[3468]},
+    {"host", "host", NID_host, 10, &so[3478]},
+    {"manager", "manager", NID_manager, 10, &so[3488]},
+    {"documentIdentifier", "documentIdentifier", NID_documentIdentifier, 10, &so[3498]},
+    {"documentTitle", "documentTitle", NID_documentTitle, 10, &so[3508]},
+    {"documentVersion", "documentVersion", NID_documentVersion, 10, &so[3518]},
+    {"documentAuthor", "documentAuthor", NID_documentAuthor, 10, &so[3528]},
+    {"documentLocation", "documentLocation", NID_documentLocation, 10, &so[3538]},
+    {"homeTelephoneNumber", "homeTelephoneNumber", NID_homeTelephoneNumber, 10, &so[3548]},
+    {"secretary", "secretary", NID_secretary, 10, &so[3558]},
+    {"otherMailbox", "otherMailbox", NID_otherMailbox, 10, &so[3568]},
+    {"lastModifiedTime", "lastModifiedTime", NID_lastModifiedTime, 10, &so[3578]},
+    {"lastModifiedBy", "lastModifiedBy", NID_lastModifiedBy, 10, &so[3588]},
+    {"aRecord", "aRecord", NID_aRecord, 10, &so[3598]},
+    {"pilotAttributeType27", "pilotAttributeType27", NID_pilotAttributeType27, 10, &so[3608]},
+    {"mXRecord", "mXRecord", NID_mXRecord, 10, &so[3618]},
+    {"nSRecord", "nSRecord", NID_nSRecord, 10, &so[3628]},
+    {"sOARecord", "sOARecord", NID_sOARecord, 10, &so[3638]},
+    {"cNAMERecord", "cNAMERecord", NID_cNAMERecord, 10, &so[3648]},
+    {"associatedDomain", "associatedDomain", NID_associatedDomain, 10, &so[3658]},
+    {"associatedName", "associatedName", NID_associatedName, 10, &so[3668]},
+    {"homePostalAddress", "homePostalAddress", NID_homePostalAddress, 10, &so[3678]},
+    {"personalTitle", "personalTitle", NID_personalTitle, 10, &so[3688]},
+    {"mobileTelephoneNumber", "mobileTelephoneNumber", NID_mobileTelephoneNumber, 10, &so[3698]},
+    {"pagerTelephoneNumber", "pagerTelephoneNumber", NID_pagerTelephoneNumber, 10, &so[3708]},
+    {"friendlyCountryName", "friendlyCountryName", NID_friendlyCountryName, 10, &so[3718]},
+    {"organizationalStatus", "organizationalStatus", NID_organizationalStatus, 10, &so[3728]},
+    {"janetMailbox", "janetMailbox", NID_janetMailbox, 10, &so[3738]},
+    {"mailPreferenceOption", "mailPreferenceOption", NID_mailPreferenceOption, 10, &so[3748]},
+    {"buildingName", "buildingName", NID_buildingName, 10, &so[3758]},
+    {"dSAQuality", "dSAQuality", NID_dSAQuality, 10, &so[3768]},
+    {"singleLevelQuality", "singleLevelQuality", NID_singleLevelQuality, 10, &so[3778]},
+    {"subtreeMinimumQuality", "subtreeMinimumQuality", NID_subtreeMinimumQuality, 10, &so[3788]},
+    {"subtreeMaximumQuality", "subtreeMaximumQuality", NID_subtreeMaximumQuality, 10, &so[3798]},
+    {"personalSignature", "personalSignature", NID_personalSignature, 10, &so[3808]},
+    {"dITRedirect", "dITRedirect", NID_dITRedirect, 10, &so[3818]},
+    {"audio", "audio", NID_audio, 10, &so[3828]},
+    {"documentPublisher", "documentPublisher", NID_documentPublisher, 10, &so[3838]},
+    {"x500UniqueIdentifier", "x500UniqueIdentifier", NID_x500UniqueIdentifier, 3, &so[3848]},
+    {"mime-mhs", "MIME MHS", NID_mime_mhs, 5, &so[3851]},
+    {"mime-mhs-headings", "mime-mhs-headings", NID_mime_mhs_headings, 6, &so[3856]},
+    {"mime-mhs-bodies", "mime-mhs-bodies", NID_mime_mhs_bodies, 6, &so[3862]},
+    {"id-hex-partial-message", "id-hex-partial-message", NID_id_hex_partial_message, 7, &so[3868]},
+    {"id-hex-multipart-message", "id-hex-multipart-message", NID_id_hex_multipart_message, 7, &so[3875]},
+    {"generationQualifier", "generationQualifier", NID_generationQualifier, 3, &so[3882]},
+    {"pseudonym", "pseudonym", NID_pseudonym, 3, &so[3885]},
+    { NULL, NULL, NID_undef },
+    {"id-set", "Secure Electronic Transactions", NID_id_set, 2, &so[3888]},
+    {"set-ctype", "content types", NID_set_ctype, 3, &so[3890]},
+    {"set-msgExt", "message extensions", NID_set_msgExt, 3, &so[3893]},
+    {"set-attr", "set-attr", NID_set_attr, 3, &so[3896]},
+    {"set-policy", "set-policy", NID_set_policy, 3, &so[3899]},
+    {"set-certExt", "certificate extensions", NID_set_certExt, 3, &so[3902]},
+    {"set-brand", "set-brand", NID_set_brand, 3, &so[3905]},
+    {"setct-PANData", "setct-PANData", NID_setct_PANData, 4, &so[3908]},
+    {"setct-PANToken", "setct-PANToken", NID_setct_PANToken, 4, &so[3912]},
+    {"setct-PANOnly", "setct-PANOnly", NID_setct_PANOnly, 4, &so[3916]},
+    {"setct-OIData", "setct-OIData", NID_setct_OIData, 4, &so[3920]},
+    {"setct-PI", "setct-PI", NID_setct_PI, 4, &so[3924]},
+    {"setct-PIData", "setct-PIData", NID_setct_PIData, 4, &so[3928]},
+    {"setct-PIDataUnsigned", "setct-PIDataUnsigned", NID_setct_PIDataUnsigned, 4, &so[3932]},
+    {"setct-HODInput", "setct-HODInput", NID_setct_HODInput, 4, &so[3936]},
+    {"setct-AuthResBaggage", "setct-AuthResBaggage", NID_setct_AuthResBaggage, 4, &so[3940]},
+    {"setct-AuthRevReqBaggage", "setct-AuthRevReqBaggage", NID_setct_AuthRevReqBaggage, 4, &so[3944]},
+    {"setct-AuthRevResBaggage", "setct-AuthRevResBaggage", NID_setct_AuthRevResBaggage, 4, &so[3948]},
+    {"setct-CapTokenSeq", "setct-CapTokenSeq", NID_setct_CapTokenSeq, 4, &so[3952]},
+    {"setct-PInitResData", "setct-PInitResData", NID_setct_PInitResData, 4, &so[3956]},
+    {"setct-PI-TBS", "setct-PI-TBS", NID_setct_PI_TBS, 4, &so[3960]},
+    {"setct-PResData", "setct-PResData", NID_setct_PResData, 4, &so[3964]},
+    {"setct-AuthReqTBS", "setct-AuthReqTBS", NID_setct_AuthReqTBS, 4, &so[3968]},
+    {"setct-AuthResTBS", "setct-AuthResTBS", NID_setct_AuthResTBS, 4, &so[3972]},
+    {"setct-AuthResTBSX", "setct-AuthResTBSX", NID_setct_AuthResTBSX, 4, &so[3976]},
+    {"setct-AuthTokenTBS", "setct-AuthTokenTBS", NID_setct_AuthTokenTBS, 4, &so[3980]},
+    {"setct-CapTokenData", "setct-CapTokenData", NID_setct_CapTokenData, 4, &so[3984]},
+    {"setct-CapTokenTBS", "setct-CapTokenTBS", NID_setct_CapTokenTBS, 4, &so[3988]},
+    {"setct-AcqCardCodeMsg", "setct-AcqCardCodeMsg", NID_setct_AcqCardCodeMsg, 4, &so[3992]},
+    {"setct-AuthRevReqTBS", "setct-AuthRevReqTBS", NID_setct_AuthRevReqTBS, 4, &so[3996]},
+    {"setct-AuthRevResData", "setct-AuthRevResData", NID_setct_AuthRevResData, 4, &so[4000]},
+    {"setct-AuthRevResTBS", "setct-AuthRevResTBS", NID_setct_AuthRevResTBS, 4, &so[4004]},
+    {"setct-CapReqTBS", "setct-CapReqTBS", NID_setct_CapReqTBS, 4, &so[4008]},
+    {"setct-CapReqTBSX", "setct-CapReqTBSX", NID_setct_CapReqTBSX, 4, &so[4012]},
+    {"setct-CapResData", "setct-CapResData", NID_setct_CapResData, 4, &so[4016]},
+    {"setct-CapRevReqTBS", "setct-CapRevReqTBS", NID_setct_CapRevReqTBS, 4, &so[4020]},
+    {"setct-CapRevReqTBSX", "setct-CapRevReqTBSX", NID_setct_CapRevReqTBSX, 4, &so[4024]},
+    {"setct-CapRevResData", "setct-CapRevResData", NID_setct_CapRevResData, 4, &so[4028]},
+    {"setct-CredReqTBS", "setct-CredReqTBS", NID_setct_CredReqTBS, 4, &so[4032]},
+    {"setct-CredReqTBSX", "setct-CredReqTBSX", NID_setct_CredReqTBSX, 4, &so[4036]},
+    {"setct-CredResData", "setct-CredResData", NID_setct_CredResData, 4, &so[4040]},
+    {"setct-CredRevReqTBS", "setct-CredRevReqTBS", NID_setct_CredRevReqTBS, 4, &so[4044]},
+    {"setct-CredRevReqTBSX", "setct-CredRevReqTBSX", NID_setct_CredRevReqTBSX, 4, &so[4048]},
+    {"setct-CredRevResData", "setct-CredRevResData", NID_setct_CredRevResData, 4, &so[4052]},
+    {"setct-PCertReqData", "setct-PCertReqData", NID_setct_PCertReqData, 4, &so[4056]},
+    {"setct-PCertResTBS", "setct-PCertResTBS", NID_setct_PCertResTBS, 4, &so[4060]},
+    {"setct-BatchAdminReqData", "setct-BatchAdminReqData", NID_setct_BatchAdminReqData, 4, &so[4064]},
+    {"setct-BatchAdminResData", "setct-BatchAdminResData", NID_setct_BatchAdminResData, 4, &so[4068]},
+    {"setct-CardCInitResTBS", "setct-CardCInitResTBS", NID_setct_CardCInitResTBS, 4, &so[4072]},
+    {"setct-MeAqCInitResTBS", "setct-MeAqCInitResTBS", NID_setct_MeAqCInitResTBS, 4, &so[4076]},
+    {"setct-RegFormResTBS", "setct-RegFormResTBS", NID_setct_RegFormResTBS, 4, &so[4080]},
+    {"setct-CertReqData", "setct-CertReqData", NID_setct_CertReqData, 4, &so[4084]},
+    {"setct-CertReqTBS", "setct-CertReqTBS", NID_setct_CertReqTBS, 4, &so[4088]},
+    {"setct-CertResData", "setct-CertResData", NID_setct_CertResData, 4, &so[4092]},
+    {"setct-CertInqReqTBS", "setct-CertInqReqTBS", NID_setct_CertInqReqTBS, 4, &so[4096]},
+    {"setct-ErrorTBS", "setct-ErrorTBS", NID_setct_ErrorTBS, 4, &so[4100]},
+    {"setct-PIDualSignedTBE", "setct-PIDualSignedTBE", NID_setct_PIDualSignedTBE, 4, &so[4104]},
+    {"setct-PIUnsignedTBE", "setct-PIUnsignedTBE", NID_setct_PIUnsignedTBE, 4, &so[4108]},
+    {"setct-AuthReqTBE", "setct-AuthReqTBE", NID_setct_AuthReqTBE, 4, &so[4112]},
+    {"setct-AuthResTBE", "setct-AuthResTBE", NID_setct_AuthResTBE, 4, &so[4116]},
+    {"setct-AuthResTBEX", "setct-AuthResTBEX", NID_setct_AuthResTBEX, 4, &so[4120]},
+    {"setct-AuthTokenTBE", "setct-AuthTokenTBE", NID_setct_AuthTokenTBE, 4, &so[4124]},
+    {"setct-CapTokenTBE", "setct-CapTokenTBE", NID_setct_CapTokenTBE, 4, &so[4128]},
+    {"setct-CapTokenTBEX", "setct-CapTokenTBEX", NID_setct_CapTokenTBEX, 4, &so[4132]},
+    {"setct-AcqCardCodeMsgTBE", "setct-AcqCardCodeMsgTBE", NID_setct_AcqCardCodeMsgTBE, 4, &so[4136]},
+    {"setct-AuthRevReqTBE", "setct-AuthRevReqTBE", NID_setct_AuthRevReqTBE, 4, &so[4140]},
+    {"setct-AuthRevResTBE", "setct-AuthRevResTBE", NID_setct_AuthRevResTBE, 4, &so[4144]},
+    {"setct-AuthRevResTBEB", "setct-AuthRevResTBEB", NID_setct_AuthRevResTBEB, 4, &so[4148]},
+    {"setct-CapReqTBE", "setct-CapReqTBE", NID_setct_CapReqTBE, 4, &so[4152]},
+    {"setct-CapReqTBEX", "setct-CapReqTBEX", NID_setct_CapReqTBEX, 4, &so[4156]},
+    {"setct-CapResTBE", "setct-CapResTBE", NID_setct_CapResTBE, 4, &so[4160]},
+    {"setct-CapRevReqTBE", "setct-CapRevReqTBE", NID_setct_CapRevReqTBE, 4, &so[4164]},
+    {"setct-CapRevReqTBEX", "setct-CapRevReqTBEX", NID_setct_CapRevReqTBEX, 4, &so[4168]},
+    {"setct-CapRevResTBE", "setct-CapRevResTBE", NID_setct_CapRevResTBE, 4, &so[4172]},
+    {"setct-CredReqTBE", "setct-CredReqTBE", NID_setct_CredReqTBE, 4, &so[4176]},
+    {"setct-CredReqTBEX", "setct-CredReqTBEX", NID_setct_CredReqTBEX, 4, &so[4180]},
+    {"setct-CredResTBE", "setct-CredResTBE", NID_setct_CredResTBE, 4, &so[4184]},
+    {"setct-CredRevReqTBE", "setct-CredRevReqTBE", NID_setct_CredRevReqTBE, 4, &so[4188]},
+    {"setct-CredRevReqTBEX", "setct-CredRevReqTBEX", NID_setct_CredRevReqTBEX, 4, &so[4192]},
+    {"setct-CredRevResTBE", "setct-CredRevResTBE", NID_setct_CredRevResTBE, 4, &so[4196]},
+    {"setct-BatchAdminReqTBE", "setct-BatchAdminReqTBE", NID_setct_BatchAdminReqTBE, 4, &so[4200]},
+    {"setct-BatchAdminResTBE", "setct-BatchAdminResTBE", NID_setct_BatchAdminResTBE, 4, &so[4204]},
+    {"setct-RegFormReqTBE", "setct-RegFormReqTBE", NID_setct_RegFormReqTBE, 4, &so[4208]},
+    {"setct-CertReqTBE", "setct-CertReqTBE", NID_setct_CertReqTBE, 4, &so[4212]},
+    {"setct-CertReqTBEX", "setct-CertReqTBEX", NID_setct_CertReqTBEX, 4, &so[4216]},
+    {"setct-CertResTBE", "setct-CertResTBE", NID_setct_CertResTBE, 4, &so[4220]},
+    {"setct-CRLNotificationTBS", "setct-CRLNotificationTBS", NID_setct_CRLNotificationTBS, 4, &so[4224]},
+    {"setct-CRLNotificationResTBS", "setct-CRLNotificationResTBS", NID_setct_CRLNotificationResTBS, 4, &so[4228]},
+    {"setct-BCIDistributionTBS", "setct-BCIDistributionTBS", NID_setct_BCIDistributionTBS, 4, &so[4232]},
+    {"setext-genCrypt", "generic cryptogram", NID_setext_genCrypt, 4, &so[4236]},
+    {"setext-miAuth", "merchant initiated auth", NID_setext_miAuth, 4, &so[4240]},
+    {"setext-pinSecure", "setext-pinSecure", NID_setext_pinSecure, 4, &so[4244]},
+    {"setext-pinAny", "setext-pinAny", NID_setext_pinAny, 4, &so[4248]},
+    {"setext-track2", "setext-track2", NID_setext_track2, 4, &so[4252]},
+    {"setext-cv", "additional verification", NID_setext_cv, 4, &so[4256]},
+    {"set-policy-root", "set-policy-root", NID_set_policy_root, 4, &so[4260]},
+    {"setCext-hashedRoot", "setCext-hashedRoot", NID_setCext_hashedRoot, 4, &so[4264]},
+    {"setCext-certType", "setCext-certType", NID_setCext_certType, 4, &so[4268]},
+    {"setCext-merchData", "setCext-merchData", NID_setCext_merchData, 4, &so[4272]},
+    {"setCext-cCertRequired", "setCext-cCertRequired", NID_setCext_cCertRequired, 4, &so[4276]},
+    {"setCext-tunneling", "setCext-tunneling", NID_setCext_tunneling, 4, &so[4280]},
+    {"setCext-setExt", "setCext-setExt", NID_setCext_setExt, 4, &so[4284]},
+    {"setCext-setQualf", "setCext-setQualf", NID_setCext_setQualf, 4, &so[4288]},
+    {"setCext-PGWYcapabilities", "setCext-PGWYcapabilities", NID_setCext_PGWYcapabilities, 4, &so[4292]},
+    {"setCext-TokenIdentifier", "setCext-TokenIdentifier", NID_setCext_TokenIdentifier, 4, &so[4296]},
+    {"setCext-Track2Data", "setCext-Track2Data", NID_setCext_Track2Data, 4, &so[4300]},
+    {"setCext-TokenType", "setCext-TokenType", NID_setCext_TokenType, 4, &so[4304]},
+    {"setCext-IssuerCapabilities", "setCext-IssuerCapabilities", NID_setCext_IssuerCapabilities, 4, &so[4308]},
+    {"setAttr-Cert", "setAttr-Cert", NID_setAttr_Cert, 4, &so[4312]},
+    {"setAttr-PGWYcap", "payment gateway capabilities", NID_setAttr_PGWYcap, 4, &so[4316]},
+    {"setAttr-TokenType", "setAttr-TokenType", NID_setAttr_TokenType, 4, &so[4320]},
+    {"setAttr-IssCap", "issuer capabilities", NID_setAttr_IssCap, 4, &so[4324]},
+    {"set-rootKeyThumb", "set-rootKeyThumb", NID_set_rootKeyThumb, 5, &so[4328]},
+    {"set-addPolicy", "set-addPolicy", NID_set_addPolicy, 5, &so[4333]},
+    {"setAttr-Token-EMV", "setAttr-Token-EMV", NID_setAttr_Token_EMV, 5, &so[4338]},
+    {"setAttr-Token-B0Prime", "setAttr-Token-B0Prime", NID_setAttr_Token_B0Prime, 5, &so[4343]},
+    {"setAttr-IssCap-CVM", "setAttr-IssCap-CVM", NID_setAttr_IssCap_CVM, 5, &so[4348]},
+    {"setAttr-IssCap-T2", "setAttr-IssCap-T2", NID_setAttr_IssCap_T2, 5, &so[4353]},
+    {"setAttr-IssCap-Sig", "setAttr-IssCap-Sig", NID_setAttr_IssCap_Sig, 5, &so[4358]},
+    {"setAttr-GenCryptgrm", "generate cryptogram", NID_setAttr_GenCryptgrm, 6, &so[4363]},
+    {"setAttr-T2Enc", "encrypted track 2", NID_setAttr_T2Enc, 6, &so[4369]},
+    {"setAttr-T2cleartxt", "cleartext track 2", NID_setAttr_T2cleartxt, 6, &so[4375]},
+    {"setAttr-TokICCsig", "ICC or token signature", NID_setAttr_TokICCsig, 6, &so[4381]},
+    {"setAttr-SecDevSig", "secure device signature", NID_setAttr_SecDevSig, 6, &so[4387]},
+    {"set-brand-IATA-ATA", "set-brand-IATA-ATA", NID_set_brand_IATA_ATA, 4, &so[4393]},
+    {"set-brand-Diners", "set-brand-Diners", NID_set_brand_Diners, 4, &so[4397]},
+    {"set-brand-AmericanExpress", "set-brand-AmericanExpress", NID_set_brand_AmericanExpress, 4, &so[4401]},
+    {"set-brand-JCB", "set-brand-JCB", NID_set_brand_JCB, 4, &so[4405]},
+    {"set-brand-Visa", "set-brand-Visa", NID_set_brand_Visa, 4, &so[4409]},
+    {"set-brand-MasterCard", "set-brand-MasterCard", NID_set_brand_MasterCard, 4, &so[4413]},
+    {"set-brand-Novus", "set-brand-Novus", NID_set_brand_Novus, 5, &so[4417]},
+    {"DES-CDMF", "des-cdmf", NID_des_cdmf, 8, &so[4422]},
+    {"rsaOAEPEncryptionSET", "rsaOAEPEncryptionSET", NID_rsaOAEPEncryptionSET, 9, &so[4430]},
+    {"ITU-T", "itu-t", NID_itu_t},
+    {"JOINT-ISO-ITU-T", "joint-iso-itu-t", NID_joint_iso_itu_t},
+    {"international-organizations", "International Organizations", NID_international_organizations, 1, &so[4439]},
+    {"msSmartcardLogin", "Microsoft Smartcardlogin", NID_ms_smartcard_login, 10, &so[4440]},
+    {"msUPN", "Microsoft Universal Principal Name", NID_ms_upn, 10, &so[4450]},
+    {"AES-128-CFB1", "aes-128-cfb1", NID_aes_128_cfb1},
+    {"AES-192-CFB1", "aes-192-cfb1", NID_aes_192_cfb1},
+    {"AES-256-CFB1", "aes-256-cfb1", NID_aes_256_cfb1},
+    {"AES-128-CFB8", "aes-128-cfb8", NID_aes_128_cfb8},
+    {"AES-192-CFB8", "aes-192-cfb8", NID_aes_192_cfb8},
+    {"AES-256-CFB8", "aes-256-cfb8", NID_aes_256_cfb8},
+    {"DES-CFB1", "des-cfb1", NID_des_cfb1},
+    {"DES-CFB8", "des-cfb8", NID_des_cfb8},
+    {"DES-EDE3-CFB1", "des-ede3-cfb1", NID_des_ede3_cfb1},
+    {"DES-EDE3-CFB8", "des-ede3-cfb8", NID_des_ede3_cfb8},
+    {"street", "streetAddress", NID_streetAddress, 3, &so[4460]},
+    {"postalCode", "postalCode", NID_postalCode, 3, &so[4463]},
+    {"id-ppl", "id-ppl", NID_id_ppl, 7, &so[4466]},
+    {"proxyCertInfo", "Proxy Certificate Information", NID_proxyCertInfo, 8, &so[4473]},
+    {"id-ppl-anyLanguage", "Any language", NID_id_ppl_anyLanguage, 8, &so[4481]},
+    {"id-ppl-inheritAll", "Inherit all", NID_id_ppl_inheritAll, 8, &so[4489]},
+    {"nameConstraints", "X509v3 Name Constraints", NID_name_constraints, 3, &so[4497]},
+    {"id-ppl-independent", "Independent", NID_Independent, 8, &so[4500]},
+    {"RSA-SHA256", "sha256WithRSAEncryption", NID_sha256WithRSAEncryption, 9, &so[4508]},
+    {"RSA-SHA384", "sha384WithRSAEncryption", NID_sha384WithRSAEncryption, 9, &so[4517]},
+    {"RSA-SHA512", "sha512WithRSAEncryption", NID_sha512WithRSAEncryption, 9, &so[4526]},
+    {"RSA-SHA224", "sha224WithRSAEncryption", NID_sha224WithRSAEncryption, 9, &so[4535]},
+    {"SHA256", "sha256", NID_sha256, 9, &so[4544]},
+    {"SHA384", "sha384", NID_sha384, 9, &so[4553]},
+    {"SHA512", "sha512", NID_sha512, 9, &so[4562]},
+    {"SHA224", "sha224", NID_sha224, 9, &so[4571]},
+    {"identified-organization", "identified-organization", NID_identified_organization, 1, &so[4580]},
+    {"certicom-arc", "certicom-arc", NID_certicom_arc, 3, &so[4581]},
+    {"wap", "wap", NID_wap, 2, &so[4584]},
+    {"wap-wsg", "wap-wsg", NID_wap_wsg, 3, &so[4586]},
+    {"id-characteristic-two-basis", "id-characteristic-two-basis", NID_X9_62_id_characteristic_two_basis, 8, &so[4589]},
+    {"onBasis", "onBasis", NID_X9_62_onBasis, 9, &so[4597]},
+    {"tpBasis", "tpBasis", NID_X9_62_tpBasis, 9, &so[4606]},
+    {"ppBasis", "ppBasis", NID_X9_62_ppBasis, 9, &so[4615]},
+    {"c2pnb163v1", "c2pnb163v1", NID_X9_62_c2pnb163v1, 8, &so[4624]},
+    {"c2pnb163v2", "c2pnb163v2", NID_X9_62_c2pnb163v2, 8, &so[4632]},
+    {"c2pnb163v3", "c2pnb163v3", NID_X9_62_c2pnb163v3, 8, &so[4640]},
+    {"c2pnb176v1", "c2pnb176v1", NID_X9_62_c2pnb176v1, 8, &so[4648]},
+    {"c2tnb191v1", "c2tnb191v1", NID_X9_62_c2tnb191v1, 8, &so[4656]},
+    {"c2tnb191v2", "c2tnb191v2", NID_X9_62_c2tnb191v2, 8, &so[4664]},
+    {"c2tnb191v3", "c2tnb191v3", NID_X9_62_c2tnb191v3, 8, &so[4672]},
+    {"c2onb191v4", "c2onb191v4", NID_X9_62_c2onb191v4, 8, &so[4680]},
+    {"c2onb191v5", "c2onb191v5", NID_X9_62_c2onb191v5, 8, &so[4688]},
+    {"c2pnb208w1", "c2pnb208w1", NID_X9_62_c2pnb208w1, 8, &so[4696]},
+    {"c2tnb239v1", "c2tnb239v1", NID_X9_62_c2tnb239v1, 8, &so[4704]},
+    {"c2tnb239v2", "c2tnb239v2", NID_X9_62_c2tnb239v2, 8, &so[4712]},
+    {"c2tnb239v3", "c2tnb239v3", NID_X9_62_c2tnb239v3, 8, &so[4720]},
+    {"c2onb239v4", "c2onb239v4", NID_X9_62_c2onb239v4, 8, &so[4728]},
+    {"c2onb239v5", "c2onb239v5", NID_X9_62_c2onb239v5, 8, &so[4736]},
+    {"c2pnb272w1", "c2pnb272w1", NID_X9_62_c2pnb272w1, 8, &so[4744]},
+    {"c2pnb304w1", "c2pnb304w1", NID_X9_62_c2pnb304w1, 8, &so[4752]},
+    {"c2tnb359v1", "c2tnb359v1", NID_X9_62_c2tnb359v1, 8, &so[4760]},
+    {"c2pnb368w1", "c2pnb368w1", NID_X9_62_c2pnb368w1, 8, &so[4768]},
+    {"c2tnb431r1", "c2tnb431r1", NID_X9_62_c2tnb431r1, 8, &so[4776]},
+    {"secp112r1", "secp112r1", NID_secp112r1, 5, &so[4784]},
+    {"secp112r2", "secp112r2", NID_secp112r2, 5, &so[4789]},
+    {"secp128r1", "secp128r1", NID_secp128r1, 5, &so[4794]},
+    {"secp128r2", "secp128r2", NID_secp128r2, 5, &so[4799]},
+    {"secp160k1", "secp160k1", NID_secp160k1, 5, &so[4804]},
+    {"secp160r1", "secp160r1", NID_secp160r1, 5, &so[4809]},
+    {"secp160r2", "secp160r2", NID_secp160r2, 5, &so[4814]},
+    {"secp192k1", "secp192k1", NID_secp192k1, 5, &so[4819]},
+    {"secp224k1", "secp224k1", NID_secp224k1, 5, &so[4824]},
+    {"secp224r1", "secp224r1", NID_secp224r1, 5, &so[4829]},
+    {"secp256k1", "secp256k1", NID_secp256k1, 5, &so[4834]},
+    {"secp384r1", "secp384r1", NID_secp384r1, 5, &so[4839]},
+    {"secp521r1", "secp521r1", NID_secp521r1, 5, &so[4844]},
+    {"sect113r1", "sect113r1", NID_sect113r1, 5, &so[4849]},
+    {"sect113r2", "sect113r2", NID_sect113r2, 5, &so[4854]},
+    {"sect131r1", "sect131r1", NID_sect131r1, 5, &so[4859]},
+    {"sect131r2", "sect131r2", NID_sect131r2, 5, &so[4864]},
+    {"sect163k1", "sect163k1", NID_sect163k1, 5, &so[4869]},
+    {"sect163r1", "sect163r1", NID_sect163r1, 5, &so[4874]},
+    {"sect163r2", "sect163r2", NID_sect163r2, 5, &so[4879]},
+    {"sect193r1", "sect193r1", NID_sect193r1, 5, &so[4884]},
+    {"sect193r2", "sect193r2", NID_sect193r2, 5, &so[4889]},
+    {"sect233k1", "sect233k1", NID_sect233k1, 5, &so[4894]},
+    {"sect233r1", "sect233r1", NID_sect233r1, 5, &so[4899]},
+    {"sect239k1", "sect239k1", NID_sect239k1, 5, &so[4904]},
+    {"sect283k1", "sect283k1", NID_sect283k1, 5, &so[4909]},
+    {"sect283r1", "sect283r1", NID_sect283r1, 5, &so[4914]},
+    {"sect409k1", "sect409k1", NID_sect409k1, 5, &so[4919]},
+    {"sect409r1", "sect409r1", NID_sect409r1, 5, &so[4924]},
+    {"sect571k1", "sect571k1", NID_sect571k1, 5, &so[4929]},
+    {"sect571r1", "sect571r1", NID_sect571r1, 5, &so[4934]},
+    {"wap-wsg-idm-ecid-wtls1", "wap-wsg-idm-ecid-wtls1", NID_wap_wsg_idm_ecid_wtls1, 5, &so[4939]},
+    {"wap-wsg-idm-ecid-wtls3", "wap-wsg-idm-ecid-wtls3", NID_wap_wsg_idm_ecid_wtls3, 5, &so[4944]},
+    {"wap-wsg-idm-ecid-wtls4", "wap-wsg-idm-ecid-wtls4", NID_wap_wsg_idm_ecid_wtls4, 5, &so[4949]},
+    {"wap-wsg-idm-ecid-wtls5", "wap-wsg-idm-ecid-wtls5", NID_wap_wsg_idm_ecid_wtls5, 5, &so[4954]},
+    {"wap-wsg-idm-ecid-wtls6", "wap-wsg-idm-ecid-wtls6", NID_wap_wsg_idm_ecid_wtls6, 5, &so[4959]},
+    {"wap-wsg-idm-ecid-wtls7", "wap-wsg-idm-ecid-wtls7", NID_wap_wsg_idm_ecid_wtls7, 5, &so[4964]},
+    {"wap-wsg-idm-ecid-wtls8", "wap-wsg-idm-ecid-wtls8", NID_wap_wsg_idm_ecid_wtls8, 5, &so[4969]},
+    {"wap-wsg-idm-ecid-wtls9", "wap-wsg-idm-ecid-wtls9", NID_wap_wsg_idm_ecid_wtls9, 5, &so[4974]},
+    {"wap-wsg-idm-ecid-wtls10", "wap-wsg-idm-ecid-wtls10", NID_wap_wsg_idm_ecid_wtls10, 5, &so[4979]},
+    {"wap-wsg-idm-ecid-wtls11", "wap-wsg-idm-ecid-wtls11", NID_wap_wsg_idm_ecid_wtls11, 5, &so[4984]},
+    {"wap-wsg-idm-ecid-wtls12", "wap-wsg-idm-ecid-wtls12", NID_wap_wsg_idm_ecid_wtls12, 5, &so[4989]},
+    {"anyPolicy", "X509v3 Any Policy", NID_any_policy, 4, &so[4994]},
+    {"policyMappings", "X509v3 Policy Mappings", NID_policy_mappings, 3, &so[4998]},
+    {"inhibitAnyPolicy", "X509v3 Inhibit Any Policy", NID_inhibit_any_policy, 3, &so[5001]},
+    {"Oakley-EC2N-3", "ipsec3", NID_ipsec3},
+    {"Oakley-EC2N-4", "ipsec4", NID_ipsec4},
+    {"CAMELLIA-128-CBC", "camellia-128-cbc", NID_camellia_128_cbc, 11, &so[5004]},
+    {"CAMELLIA-192-CBC", "camellia-192-cbc", NID_camellia_192_cbc, 11, &so[5015]},
+    {"CAMELLIA-256-CBC", "camellia-256-cbc", NID_camellia_256_cbc, 11, &so[5026]},
+    {"CAMELLIA-128-ECB", "camellia-128-ecb", NID_camellia_128_ecb, 8, &so[5037]},
+    {"CAMELLIA-192-ECB", "camellia-192-ecb", NID_camellia_192_ecb, 8, &so[5045]},
+    {"CAMELLIA-256-ECB", "camellia-256-ecb", NID_camellia_256_ecb, 8, &so[5053]},
+    {"CAMELLIA-128-CFB", "camellia-128-cfb", NID_camellia_128_cfb128, 8, &so[5061]},
+    {"CAMELLIA-192-CFB", "camellia-192-cfb", NID_camellia_192_cfb128, 8, &so[5069]},
+    {"CAMELLIA-256-CFB", "camellia-256-cfb", NID_camellia_256_cfb128, 8, &so[5077]},
+    {"CAMELLIA-128-CFB1", "camellia-128-cfb1", NID_camellia_128_cfb1},
+    {"CAMELLIA-192-CFB1", "camellia-192-cfb1", NID_camellia_192_cfb1},
+    {"CAMELLIA-256-CFB1", "camellia-256-cfb1", NID_camellia_256_cfb1},
+    {"CAMELLIA-128-CFB8", "camellia-128-cfb8", NID_camellia_128_cfb8},
+    {"CAMELLIA-192-CFB8", "camellia-192-cfb8", NID_camellia_192_cfb8},
+    {"CAMELLIA-256-CFB8", "camellia-256-cfb8", NID_camellia_256_cfb8},
+    {"CAMELLIA-128-OFB", "camellia-128-ofb", NID_camellia_128_ofb128, 8, &so[5085]},
+    {"CAMELLIA-192-OFB", "camellia-192-ofb", NID_camellia_192_ofb128, 8, &so[5093]},
+    {"CAMELLIA-256-OFB", "camellia-256-ofb", NID_camellia_256_ofb128, 8, &so[5101]},
+    {"subjectDirectoryAttributes", "X509v3 Subject Directory Attributes", NID_subject_directory_attributes, 3, &so[5109]},
+    {"issuingDistributionPoint", "X509v3 Issuing Distribution Point", NID_issuing_distribution_point, 3, &so[5112]},
+    {"certificateIssuer", "X509v3 Certificate Issuer", NID_certificate_issuer, 3, &so[5115]},
+    { NULL, NULL, NID_undef },
+    {"KISA", "kisa", NID_kisa, 6, &so[5118]},
+    { NULL, NULL, NID_undef },
+    { NULL, NULL, NID_undef },
+    {"SEED-ECB", "seed-ecb", NID_seed_ecb, 8, &so[5124]},
+    {"SEED-CBC", "seed-cbc", NID_seed_cbc, 8, &so[5132]},
+    {"SEED-OFB", "seed-ofb", NID_seed_ofb128, 8, &so[5140]},
+    {"SEED-CFB", "seed-cfb", NID_seed_cfb128, 8, &so[5148]},
+    {"HMAC-MD5", "hmac-md5", NID_hmac_md5, 8, &so[5156]},
+    {"HMAC-SHA1", "hmac-sha1", NID_hmac_sha1, 8, &so[5164]},
+    {"id-PasswordBasedMAC", "password based MAC", NID_id_PasswordBasedMAC, 9, &so[5172]},
+    {"id-DHBasedMac", "Diffie-Hellman based MAC", NID_id_DHBasedMac, 9, &so[5181]},
+    {"id-it-suppLangTags", "id-it-suppLangTags", NID_id_it_suppLangTags, 8, &so[5190]},
+    {"caRepository", "CA Repository", NID_caRepository, 8, &so[5198]},
+    {"id-smime-ct-compressedData", "id-smime-ct-compressedData", NID_id_smime_ct_compressedData, 11, &so[5206]},
+    {"id-ct-asciiTextWithCRLF", "id-ct-asciiTextWithCRLF", NID_id_ct_asciiTextWithCRLF, 11, &so[5217]},
+    {"id-aes128-wrap", "id-aes128-wrap", NID_id_aes128_wrap, 9, &so[5228]},
+    {"id-aes192-wrap", "id-aes192-wrap", NID_id_aes192_wrap, 9, &so[5237]},
+    {"id-aes256-wrap", "id-aes256-wrap", NID_id_aes256_wrap, 9, &so[5246]},
+    {"ecdsa-with-Recommended", "ecdsa-with-Recommended", NID_ecdsa_with_Recommended, 7, &so[5255]},
+    {"ecdsa-with-Specified", "ecdsa-with-Specified", NID_ecdsa_with_Specified, 7, &so[5262]},
+    {"ecdsa-with-SHA224", "ecdsa-with-SHA224", NID_ecdsa_with_SHA224, 8, &so[5269]},
+    {"ecdsa-with-SHA256", "ecdsa-with-SHA256", NID_ecdsa_with_SHA256, 8, &so[5277]},
+    {"ecdsa-with-SHA384", "ecdsa-with-SHA384", NID_ecdsa_with_SHA384, 8, &so[5285]},
+    {"ecdsa-with-SHA512", "ecdsa-with-SHA512", NID_ecdsa_with_SHA512, 8, &so[5293]},
+    {"hmacWithMD5", "hmacWithMD5", NID_hmacWithMD5, 8, &so[5301]},
+    {"hmacWithSHA224", "hmacWithSHA224", NID_hmacWithSHA224, 8, &so[5309]},
+    {"hmacWithSHA256", "hmacWithSHA256", NID_hmacWithSHA256, 8, &so[5317]},
+    {"hmacWithSHA384", "hmacWithSHA384", NID_hmacWithSHA384, 8, &so[5325]},
+    {"hmacWithSHA512", "hmacWithSHA512", NID_hmacWithSHA512, 8, &so[5333]},
+    {"dsa_with_SHA224", "dsa_with_SHA224", NID_dsa_with_SHA224, 9, &so[5341]},
+    {"dsa_with_SHA256", "dsa_with_SHA256", NID_dsa_with_SHA256, 9, &so[5350]},
+    {"whirlpool", "whirlpool", NID_whirlpool, 6, &so[5359]},
+    {"cryptopro", "cryptopro", NID_cryptopro, 5, &so[5365]},
+    {"cryptocom", "cryptocom", NID_cryptocom, 5, &so[5370]},
+    {"id-GostR3411-94-with-GostR3410-2001", "GOST R 34.11-94 with GOST R 34.10-2001", NID_id_GostR3411_94_with_GostR3410_2001, 6, &so[5375]},
+    {"id-GostR3411-94-with-GostR3410-94", "GOST R 34.11-94 with GOST R 34.10-94", NID_id_GostR3411_94_with_GostR3410_94, 6, &so[5381]},
+    {"md_gost94", "GOST R 34.11-94", NID_id_GostR3411_94, 6, &so[5387]},
+    {"id-HMACGostR3411-94", "HMAC GOST 34.11-94", NID_id_HMACGostR3411_94, 6, &so[5393]},
+    {"gost2001", "GOST R 34.10-2001", NID_id_GostR3410_2001, 6, &so[5399]},
+    {"gost94", "GOST R 34.10-94", NID_id_GostR3410_94, 6, &so[5405]},
+    {"gost89", "GOST 28147-89", NID_id_Gost28147_89, 6, &so[5411]},
+    {"gost89-cnt", "gost89-cnt", NID_gost89_cnt},
+    {"gost-mac", "GOST 28147-89 MAC", NID_id_Gost28147_89_MAC, 6, &so[5417]},
+    {"prf-gostr3411-94", "GOST R 34.11-94 PRF", NID_id_GostR3411_94_prf, 6, &so[5423]},
+    {"id-GostR3410-2001DH", "GOST R 34.10-2001 DH", NID_id_GostR3410_2001DH, 6, &so[5429]},
+    {"id-GostR3410-94DH", "GOST R 34.10-94 DH", NID_id_GostR3410_94DH, 6, &so[5435]},
+    {"id-Gost28147-89-CryptoPro-KeyMeshing", "id-Gost28147-89-CryptoPro-KeyMeshing", NID_id_Gost28147_89_CryptoPro_KeyMeshing, 7, &so[5441]},
+    {"id-Gost28147-89-None-KeyMeshing", "id-Gost28147-89-None-KeyMeshing", NID_id_Gost28147_89_None_KeyMeshing, 7, &so[5448]},
+    {"id-GostR3411-94-TestParamSet", "id-GostR3411-94-TestParamSet", NID_id_GostR3411_94_TestParamSet, 7, &so[5455]},
+    {"id-GostR3411-94-CryptoProParamSet", "id-GostR3411-94-CryptoProParamSet", NID_id_GostR3411_94_CryptoProParamSet, 7, &so[5462]},
+    {"id-Gost28147-89-TestParamSet", "id-Gost28147-89-TestParamSet", NID_id_Gost28147_89_TestParamSet, 7, &so[5469]},
+    {"id-Gost28147-89-CryptoPro-A-ParamSet", "id-Gost28147-89-CryptoPro-A-ParamSet", NID_id_Gost28147_89_CryptoPro_A_ParamSet, 7, &so[5476]},
+    {"id-Gost28147-89-CryptoPro-B-ParamSet", "id-Gost28147-89-CryptoPro-B-ParamSet", NID_id_Gost28147_89_CryptoPro_B_ParamSet, 7, &so[5483]},
+    {"id-Gost28147-89-CryptoPro-C-ParamSet", "id-Gost28147-89-CryptoPro-C-ParamSet", NID_id_Gost28147_89_CryptoPro_C_ParamSet, 7, &so[5490]},
+    {"id-Gost28147-89-CryptoPro-D-ParamSet", "id-Gost28147-89-CryptoPro-D-ParamSet", NID_id_Gost28147_89_CryptoPro_D_ParamSet, 7, &so[5497]},
+    {"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet", "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet", NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet, 7, &so[5504]},
+    {"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet", "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet", NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet, 7, &so[5511]},
+    {"id-Gost28147-89-CryptoPro-RIC-1-ParamSet", "id-Gost28147-89-CryptoPro-RIC-1-ParamSet", NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet, 7, &so[5518]},
+    {"id-GostR3410-94-TestParamSet", "id-GostR3410-94-TestParamSet", NID_id_GostR3410_94_TestParamSet, 7, &so[5525]},
+    {"id-GostR3410-94-CryptoPro-A-ParamSet", "id-GostR3410-94-CryptoPro-A-ParamSet", NID_id_GostR3410_94_CryptoPro_A_ParamSet, 7, &so[5532]},
+    {"id-GostR3410-94-CryptoPro-B-ParamSet", "id-GostR3410-94-CryptoPro-B-ParamSet", NID_id_GostR3410_94_CryptoPro_B_ParamSet, 7, &so[5539]},
+    {"id-GostR3410-94-CryptoPro-C-ParamSet", "id-GostR3410-94-CryptoPro-C-ParamSet", NID_id_GostR3410_94_CryptoPro_C_ParamSet, 7, &so[5546]},
+    {"id-GostR3410-94-CryptoPro-D-ParamSet", "id-GostR3410-94-CryptoPro-D-ParamSet", NID_id_GostR3410_94_CryptoPro_D_ParamSet, 7, &so[5553]},
+    {"id-GostR3410-94-CryptoPro-XchA-ParamSet", "id-GostR3410-94-CryptoPro-XchA-ParamSet", NID_id_GostR3410_94_CryptoPro_XchA_ParamSet, 7, &so[5560]},
+    {"id-GostR3410-94-CryptoPro-XchB-ParamSet", "id-GostR3410-94-CryptoPro-XchB-ParamSet", NID_id_GostR3410_94_CryptoPro_XchB_ParamSet, 7, &so[5567]},
+    {"id-GostR3410-94-CryptoPro-XchC-ParamSet", "id-GostR3410-94-CryptoPro-XchC-ParamSet", NID_id_GostR3410_94_CryptoPro_XchC_ParamSet, 7, &so[5574]},
+    {"id-GostR3410-2001-TestParamSet", "id-GostR3410-2001-TestParamSet", NID_id_GostR3410_2001_TestParamSet, 7, &so[5581]},
+    {"id-GostR3410-2001-CryptoPro-A-ParamSet", "id-GostR3410-2001-CryptoPro-A-ParamSet", NID_id_GostR3410_2001_CryptoPro_A_ParamSet, 7, &so[5588]},
+    {"id-GostR3410-2001-CryptoPro-B-ParamSet", "id-GostR3410-2001-CryptoPro-B-ParamSet", NID_id_GostR3410_2001_CryptoPro_B_ParamSet, 7, &so[5595]},
+    {"id-GostR3410-2001-CryptoPro-C-ParamSet", "id-GostR3410-2001-CryptoPro-C-ParamSet", NID_id_GostR3410_2001_CryptoPro_C_ParamSet, 7, &so[5602]},
+    {"id-GostR3410-2001-CryptoPro-XchA-ParamSet", "id-GostR3410-2001-CryptoPro-XchA-ParamSet", NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet, 7, &so[5609]},
+    {"id-GostR3410-2001-CryptoPro-XchB-ParamSet", "id-GostR3410-2001-CryptoPro-XchB-ParamSet", NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet, 7, &so[5616]},
+    {"id-GostR3410-94-a", "id-GostR3410-94-a", NID_id_GostR3410_94_a, 7, &so[5623]},
+    {"id-GostR3410-94-aBis", "id-GostR3410-94-aBis", NID_id_GostR3410_94_aBis, 7, &so[5630]},
+    {"id-GostR3410-94-b", "id-GostR3410-94-b", NID_id_GostR3410_94_b, 7, &so[5637]},
+    {"id-GostR3410-94-bBis", "id-GostR3410-94-bBis", NID_id_GostR3410_94_bBis, 7, &so[5644]},
+    {"id-Gost28147-89-cc", "GOST 28147-89 Cryptocom ParamSet", NID_id_Gost28147_89_cc, 8, &so[5651]},
+    {"gost94cc", "GOST 34.10-94 Cryptocom", NID_id_GostR3410_94_cc, 8, &so[5659]},
+    {"gost2001cc", "GOST 34.10-2001 Cryptocom", NID_id_GostR3410_2001_cc, 8, &so[5667]},
+    {"id-GostR3411-94-with-GostR3410-94-cc", "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom", NID_id_GostR3411_94_with_GostR3410_94_cc, 8, &so[5675]},
+    {"id-GostR3411-94-with-GostR3410-2001-cc", "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom", NID_id_GostR3411_94_with_GostR3410_2001_cc, 8, &so[5683]},
+    {"id-GostR3410-2001-ParamSet-cc", "GOST R 3410-2001 Parameter Set Cryptocom", NID_id_GostR3410_2001_ParamSet_cc, 8, &so[5691]},
+    {"HMAC", "hmac", NID_hmac},
+    {"LocalKeySet", "Microsoft Local Key set", NID_LocalKeySet, 9, &so[5699]},
+    {"freshestCRL", "X509v3 Freshest CRL", NID_freshest_crl, 3, &so[5708]},
+    {"id-on-permanentIdentifier", "Permanent Identifier", NID_id_on_permanentIdentifier, 8, &so[5711]},
+    {"searchGuide", "searchGuide", NID_searchGuide, 3, &so[5719]},
+    {"businessCategory", "businessCategory", NID_businessCategory, 3, &so[5722]},
+    {"postalAddress", "postalAddress", NID_postalAddress, 3, &so[5725]},
+    {"postOfficeBox", "postOfficeBox", NID_postOfficeBox, 3, &so[5728]},
+    {"physicalDeliveryOfficeName", "physicalDeliveryOfficeName", NID_physicalDeliveryOfficeName, 3, &so[5731]},
+    {"telephoneNumber", "telephoneNumber", NID_telephoneNumber, 3, &so[5734]},
+    {"telexNumber", "telexNumber", NID_telexNumber, 3, &so[5737]},
+    {"teletexTerminalIdentifier", "teletexTerminalIdentifier", NID_teletexTerminalIdentifier, 3, &so[5740]},
+    {"facsimileTelephoneNumber", "facsimileTelephoneNumber", NID_facsimileTelephoneNumber, 3, &so[5743]},
+    {"x121Address", "x121Address", NID_x121Address, 3, &so[5746]},
+    {"internationaliSDNNumber", "internationaliSDNNumber", NID_internationaliSDNNumber, 3, &so[5749]},
+    {"registeredAddress", "registeredAddress", NID_registeredAddress, 3, &so[5752]},
+    {"destinationIndicator", "destinationIndicator", NID_destinationIndicator, 3, &so[5755]},
+    {"preferredDeliveryMethod", "preferredDeliveryMethod", NID_preferredDeliveryMethod, 3, &so[5758]},
+    {"presentationAddress", "presentationAddress", NID_presentationAddress, 3, &so[5761]},
+    {"supportedApplicationContext", "supportedApplicationContext", NID_supportedApplicationContext, 3, &so[5764]},
+    {"member", "member", NID_member, 3, &so[5767]},
+    {"owner", "owner", NID_owner, 3, &so[5770]},
+    {"roleOccupant", "roleOccupant", NID_roleOccupant, 3, &so[5773]},
+    {"seeAlso", "seeAlso", NID_seeAlso, 3, &so[5776]},
+    {"userPassword", "userPassword", NID_userPassword, 3, &so[5779]},
+    {"userCertificate", "userCertificate", NID_userCertificate, 3, &so[5782]},
+    {"cACertificate", "cACertificate", NID_cACertificate, 3, &so[5785]},
+    {"authorityRevocationList", "authorityRevocationList", NID_authorityRevocationList, 3, &so[5788]},
+    {"certificateRevocationList", "certificateRevocationList", NID_certificateRevocationList, 3, &so[5791]},
+    {"crossCertificatePair", "crossCertificatePair", NID_crossCertificatePair, 3, &so[5794]},
+    {"enhancedSearchGuide", "enhancedSearchGuide", NID_enhancedSearchGuide, 3, &so[5797]},
+    {"protocolInformation", "protocolInformation", NID_protocolInformation, 3, &so[5800]},
+    {"distinguishedName", "distinguishedName", NID_distinguishedName, 3, &so[5803]},
+    {"uniqueMember", "uniqueMember", NID_uniqueMember, 3, &so[5806]},
+    {"houseIdentifier", "houseIdentifier", NID_houseIdentifier, 3, &so[5809]},
+    {"supportedAlgorithms", "supportedAlgorithms", NID_supportedAlgorithms, 3, &so[5812]},
+    {"deltaRevocationList", "deltaRevocationList", NID_deltaRevocationList, 3, &so[5815]},
+    {"dmdName", "dmdName", NID_dmdName, 3, &so[5818]},
+    {"id-alg-PWRI-KEK", "id-alg-PWRI-KEK", NID_id_alg_PWRI_KEK, 11, &so[5821]},
+    {"CMAC", "cmac", NID_cmac},
+    {"id-aes128-GCM", "aes-128-gcm", NID_aes_128_gcm, 9, &so[5832]},
+    {"id-aes128-CCM", "aes-128-ccm", NID_aes_128_ccm, 9, &so[5841]},
+    {"id-aes128-wrap-pad", "id-aes128-wrap-pad", NID_id_aes128_wrap_pad, 9, &so[5850]},
+    {"id-aes192-GCM", "aes-192-gcm", NID_aes_192_gcm, 9, &so[5859]},
+    {"id-aes192-CCM", "aes-192-ccm", NID_aes_192_ccm, 9, &so[5868]},
+    {"id-aes192-wrap-pad", "id-aes192-wrap-pad", NID_id_aes192_wrap_pad, 9, &so[5877]},
+    {"id-aes256-GCM", "aes-256-gcm", NID_aes_256_gcm, 9, &so[5886]},
+    {"id-aes256-CCM", "aes-256-ccm", NID_aes_256_ccm, 9, &so[5895]},
+    {"id-aes256-wrap-pad", "id-aes256-wrap-pad", NID_id_aes256_wrap_pad, 9, &so[5904]},
+    {"AES-128-CTR", "aes-128-ctr", NID_aes_128_ctr},
+    {"AES-192-CTR", "aes-192-ctr", NID_aes_192_ctr},
+    {"AES-256-CTR", "aes-256-ctr", NID_aes_256_ctr},
+    {"id-camellia128-wrap", "id-camellia128-wrap", NID_id_camellia128_wrap, 11, &so[5913]},
+    {"id-camellia192-wrap", "id-camellia192-wrap", NID_id_camellia192_wrap, 11, &so[5924]},
+    {"id-camellia256-wrap", "id-camellia256-wrap", NID_id_camellia256_wrap, 11, &so[5935]},
+    {"anyExtendedKeyUsage", "Any Extended Key Usage", NID_anyExtendedKeyUsage, 4, &so[5946]},
+    {"MGF1", "mgf1", NID_mgf1, 9, &so[5950]},
+    {"RSASSA-PSS", "rsassaPss", NID_rsassaPss, 9, &so[5959]},
+    {"AES-128-XTS", "aes-128-xts", NID_aes_128_xts},
+    {"AES-256-XTS", "aes-256-xts", NID_aes_256_xts},
+    {"RC4-HMAC-MD5", "rc4-hmac-md5", NID_rc4_hmac_md5},
+    {"AES-128-CBC-HMAC-SHA1", "aes-128-cbc-hmac-sha1", NID_aes_128_cbc_hmac_sha1},
+    {"AES-192-CBC-HMAC-SHA1", "aes-192-cbc-hmac-sha1", NID_aes_192_cbc_hmac_sha1},
+    {"AES-256-CBC-HMAC-SHA1", "aes-256-cbc-hmac-sha1", NID_aes_256_cbc_hmac_sha1},
+    {"RSAES-OAEP", "rsaesOaep", NID_rsaesOaep, 9, &so[5968]},
+    {"dhpublicnumber", "X9.42 DH", NID_dhpublicnumber, 7, &so[5977]},
+    {"brainpoolP160r1", "brainpoolP160r1", NID_brainpoolP160r1, 9, &so[5984]},
+    {"brainpoolP160t1", "brainpoolP160t1", NID_brainpoolP160t1, 9, &so[5993]},
+    {"brainpoolP192r1", "brainpoolP192r1", NID_brainpoolP192r1, 9, &so[6002]},
+    {"brainpoolP192t1", "brainpoolP192t1", NID_brainpoolP192t1, 9, &so[6011]},
+    {"brainpoolP224r1", "brainpoolP224r1", NID_brainpoolP224r1, 9, &so[6020]},
+    {"brainpoolP224t1", "brainpoolP224t1", NID_brainpoolP224t1, 9, &so[6029]},
+    {"brainpoolP256r1", "brainpoolP256r1", NID_brainpoolP256r1, 9, &so[6038]},
+    {"brainpoolP256t1", "brainpoolP256t1", NID_brainpoolP256t1, 9, &so[6047]},
+    {"brainpoolP320r1", "brainpoolP320r1", NID_brainpoolP320r1, 9, &so[6056]},
+    {"brainpoolP320t1", "brainpoolP320t1", NID_brainpoolP320t1, 9, &so[6065]},
+    {"brainpoolP384r1", "brainpoolP384r1", NID_brainpoolP384r1, 9, &so[6074]},
+    {"brainpoolP384t1", "brainpoolP384t1", NID_brainpoolP384t1, 9, &so[6083]},
+    {"brainpoolP512r1", "brainpoolP512r1", NID_brainpoolP512r1, 9, &so[6092]},
+    {"brainpoolP512t1", "brainpoolP512t1", NID_brainpoolP512t1, 9, &so[6101]},
+    {"PSPECIFIED", "pSpecified", NID_pSpecified, 9, &so[6110]},
+    {"dhSinglePass-stdDH-sha1kdf-scheme", "dhSinglePass-stdDH-sha1kdf-scheme", NID_dhSinglePass_stdDH_sha1kdf_scheme, 9, &so[6119]},
+    {"dhSinglePass-stdDH-sha224kdf-scheme", "dhSinglePass-stdDH-sha224kdf-scheme", NID_dhSinglePass_stdDH_sha224kdf_scheme, 6, &so[6128]},
+    {"dhSinglePass-stdDH-sha256kdf-scheme", "dhSinglePass-stdDH-sha256kdf-scheme", NID_dhSinglePass_stdDH_sha256kdf_scheme, 6, &so[6134]},
+    {"dhSinglePass-stdDH-sha384kdf-scheme", "dhSinglePass-stdDH-sha384kdf-scheme", NID_dhSinglePass_stdDH_sha384kdf_scheme, 6, &so[6140]},
+    {"dhSinglePass-stdDH-sha512kdf-scheme", "dhSinglePass-stdDH-sha512kdf-scheme", NID_dhSinglePass_stdDH_sha512kdf_scheme, 6, &so[6146]},
+    {"dhSinglePass-cofactorDH-sha1kdf-scheme", "dhSinglePass-cofactorDH-sha1kdf-scheme", NID_dhSinglePass_cofactorDH_sha1kdf_scheme, 9, &so[6152]},
+    {"dhSinglePass-cofactorDH-sha224kdf-scheme", "dhSinglePass-cofactorDH-sha224kdf-scheme", NID_dhSinglePass_cofactorDH_sha224kdf_scheme, 6, &so[6161]},
+    {"dhSinglePass-cofactorDH-sha256kdf-scheme", "dhSinglePass-cofactorDH-sha256kdf-scheme", NID_dhSinglePass_cofactorDH_sha256kdf_scheme, 6, &so[6167]},
+    {"dhSinglePass-cofactorDH-sha384kdf-scheme", "dhSinglePass-cofactorDH-sha384kdf-scheme", NID_dhSinglePass_cofactorDH_sha384kdf_scheme, 6, &so[6173]},
+    {"dhSinglePass-cofactorDH-sha512kdf-scheme", "dhSinglePass-cofactorDH-sha512kdf-scheme", NID_dhSinglePass_cofactorDH_sha512kdf_scheme, 6, &so[6179]},
+    {"dh-std-kdf", "dh-std-kdf", NID_dh_std_kdf},
+    {"dh-cofactor-kdf", "dh-cofactor-kdf", NID_dh_cofactor_kdf},
+    {"AES-128-CBC-HMAC-SHA256", "aes-128-cbc-hmac-sha256", NID_aes_128_cbc_hmac_sha256},
+    {"AES-192-CBC-HMAC-SHA256", "aes-192-cbc-hmac-sha256", NID_aes_192_cbc_hmac_sha256},
+    {"AES-256-CBC-HMAC-SHA256", "aes-256-cbc-hmac-sha256", NID_aes_256_cbc_hmac_sha256},
+    {"ct_precert_scts", "CT Precertificate SCTs", NID_ct_precert_scts, 10, &so[6185]},
+    {"ct_precert_poison", "CT Precertificate Poison", NID_ct_precert_poison, 10, &so[6195]},
+    {"ct_precert_signer", "CT Precertificate Signer", NID_ct_precert_signer, 10, &so[6205]},
+    {"ct_cert_scts", "CT Certificate SCTs", NID_ct_cert_scts, 10, &so[6215]},
+    {"jurisdictionL", "jurisdictionLocalityName", NID_jurisdictionLocalityName, 11, &so[6225]},
+    {"jurisdictionST", "jurisdictionStateOrProvinceName", NID_jurisdictionStateOrProvinceName, 11, &so[6236]},
+    {"jurisdictionC", "jurisdictionCountryName", NID_jurisdictionCountryName, 11, &so[6247]},
+    {"AES-128-OCB", "aes-128-ocb", NID_aes_128_ocb},
+    {"AES-192-OCB", "aes-192-ocb", NID_aes_192_ocb},
+    {"AES-256-OCB", "aes-256-ocb", NID_aes_256_ocb},
+    {"CAMELLIA-128-GCM", "camellia-128-gcm", NID_camellia_128_gcm, 8, &so[6258]},
+    {"CAMELLIA-128-CCM", "camellia-128-ccm", NID_camellia_128_ccm, 8, &so[6266]},
+    {"CAMELLIA-128-CTR", "camellia-128-ctr", NID_camellia_128_ctr, 8, &so[6274]},
+    {"CAMELLIA-128-CMAC", "camellia-128-cmac", NID_camellia_128_cmac, 8, &so[6282]},
+    {"CAMELLIA-192-GCM", "camellia-192-gcm", NID_camellia_192_gcm, 8, &so[6290]},
+    {"CAMELLIA-192-CCM", "camellia-192-ccm", NID_camellia_192_ccm, 8, &so[6298]},
+    {"CAMELLIA-192-CTR", "camellia-192-ctr", NID_camellia_192_ctr, 8, &so[6306]},
+    {"CAMELLIA-192-CMAC", "camellia-192-cmac", NID_camellia_192_cmac, 8, &so[6314]},
+    {"CAMELLIA-256-GCM", "camellia-256-gcm", NID_camellia_256_gcm, 8, &so[6322]},
+    {"CAMELLIA-256-CCM", "camellia-256-ccm", NID_camellia_256_ccm, 8, &so[6330]},
+    {"CAMELLIA-256-CTR", "camellia-256-ctr", NID_camellia_256_ctr, 8, &so[6338]},
+    {"CAMELLIA-256-CMAC", "camellia-256-cmac", NID_camellia_256_cmac, 8, &so[6346]},
+    {"id-scrypt", "id-scrypt", NID_id_scrypt, 9, &so[6354]},
+    {"id-tc26", "id-tc26", NID_id_tc26, 5, &so[6363]},
+    {"gost89-cnt-12", "gost89-cnt-12", NID_gost89_cnt_12},
+    {"gost-mac-12", "gost-mac-12", NID_gost_mac_12},
+    {"id-tc26-algorithms", "id-tc26-algorithms", NID_id_tc26_algorithms, 6, &so[6368]},
+    {"id-tc26-sign", "id-tc26-sign", NID_id_tc26_sign, 7, &so[6374]},
+    {"gost2012_256", "GOST R 34.10-2012 with 256 bit modulus", NID_id_GostR3410_2012_256, 8, &so[6381]},
+    {"gost2012_512", "GOST R 34.10-2012 with 512 bit modulus", NID_id_GostR3410_2012_512, 8, &so[6389]},
+    {"id-tc26-digest", "id-tc26-digest", NID_id_tc26_digest, 7, &so[6397]},
+    {"md_gost12_256", "GOST R 34.11-2012 with 256 bit hash", NID_id_GostR3411_2012_256, 8, &so[6404]},
+    {"md_gost12_512", "GOST R 34.11-2012 with 512 bit hash", NID_id_GostR3411_2012_512, 8, &so[6412]},
+    {"id-tc26-signwithdigest", "id-tc26-signwithdigest", NID_id_tc26_signwithdigest, 7, &so[6420]},
+    {"id-tc26-signwithdigest-gost3410-2012-256", "GOST R 34.10-2012 with GOST R 34.11-2012 (256 bit)", NID_id_tc26_signwithdigest_gost3410_2012_256, 8, &so[6427]},
+    {"id-tc26-signwithdigest-gost3410-2012-512", "GOST R 34.10-2012 with GOST R 34.11-2012 (512 bit)", NID_id_tc26_signwithdigest_gost3410_2012_512, 8, &so[6435]},
+    {"id-tc26-mac", "id-tc26-mac", NID_id_tc26_mac, 7, &so[6443]},
+    {"id-tc26-hmac-gost-3411-2012-256", "HMAC GOST 34.11-2012 256 bit", NID_id_tc26_hmac_gost_3411_2012_256, 8, &so[6450]},
+    {"id-tc26-hmac-gost-3411-2012-512", "HMAC GOST 34.11-2012 512 bit", NID_id_tc26_hmac_gost_3411_2012_512, 8, &so[6458]},
+    {"id-tc26-cipher", "id-tc26-cipher", NID_id_tc26_cipher, 7, &so[6466]},
+    {"id-tc26-agreement", "id-tc26-agreement", NID_id_tc26_agreement, 7, &so[6473]},
+    {"id-tc26-agreement-gost-3410-2012-256", "id-tc26-agreement-gost-3410-2012-256", NID_id_tc26_agreement_gost_3410_2012_256, 8, &so[6480]},
+    {"id-tc26-agreement-gost-3410-2012-512", "id-tc26-agreement-gost-3410-2012-512", NID_id_tc26_agreement_gost_3410_2012_512, 8, &so[6488]},
+    {"id-tc26-constants", "id-tc26-constants", NID_id_tc26_constants, 6, &so[6496]},
+    {"id-tc26-sign-constants", "id-tc26-sign-constants", NID_id_tc26_sign_constants, 7, &so[6502]},
+    {"id-tc26-gost-3410-2012-512-constants", "id-tc26-gost-3410-2012-512-constants", NID_id_tc26_gost_3410_2012_512_constants, 8, &so[6509]},
+    {"id-tc26-gost-3410-2012-512-paramSetTest", "GOST R 34.10-2012 (512 bit) testing parameter set", NID_id_tc26_gost_3410_2012_512_paramSetTest, 9, &so[6517]},
+    {"id-tc26-gost-3410-2012-512-paramSetA", "GOST R 34.10-2012 (512 bit) ParamSet A", NID_id_tc26_gost_3410_2012_512_paramSetA, 9, &so[6526]},
+    {"id-tc26-gost-3410-2012-512-paramSetB", "GOST R 34.10-2012 (512 bit) ParamSet B", NID_id_tc26_gost_3410_2012_512_paramSetB, 9, &so[6535]},
+    {"id-tc26-digest-constants", "id-tc26-digest-constants", NID_id_tc26_digest_constants, 7, &so[6544]},
+    {"id-tc26-cipher-constants", "id-tc26-cipher-constants", NID_id_tc26_cipher_constants, 7, &so[6551]},
+    {"id-tc26-gost-28147-constants", "id-tc26-gost-28147-constants", NID_id_tc26_gost_28147_constants, 8, &so[6558]},
+    {"id-tc26-gost-28147-param-Z", "GOST 28147-89 TC26 parameter set", NID_id_tc26_gost_28147_param_Z, 9, &so[6566]},
+    {"INN", "INN", NID_INN, 8, &so[6575]},
+    {"OGRN", "OGRN", NID_OGRN, 5, &so[6583]},
+    {"SNILS", "SNILS", NID_SNILS, 5, &so[6588]},
+    {"subjectSignTool", "Signing Tool of Subject", NID_subjectSignTool, 5, &so[6593]},
+    {"issuerSignTool", "Signing Tool of Issuer", NID_issuerSignTool, 5, &so[6598]},
+    {"gost89-cbc", "gost89-cbc", NID_gost89_cbc},
+    {"gost89-ecb", "gost89-ecb", NID_gost89_ecb},
+    {"gost89-ctr", "gost89-ctr", NID_gost89_ctr},
+    {"grasshopper-ecb", "grasshopper-ecb", NID_grasshopper_ecb},
+    {"grasshopper-ctr", "grasshopper-ctr", NID_grasshopper_ctr},
+    {"grasshopper-ofb", "grasshopper-ofb", NID_grasshopper_ofb},
+    {"grasshopper-cbc", "grasshopper-cbc", NID_grasshopper_cbc},
+    {"grasshopper-cfb", "grasshopper-cfb", NID_grasshopper_cfb},
+    {"grasshopper-mac", "grasshopper-mac", NID_grasshopper_mac},
+    {"ChaCha20-Poly1305", "chacha20-poly1305", NID_chacha20_poly1305},
+    {"ChaCha20", "chacha20", NID_chacha20},
+    {"tlsfeature", "TLS Feature", NID_tlsfeature, 8, &so[6603]},
+    {"TLS1-PRF", "tls1-prf", NID_tls1_prf},
+    {"ipsecIKE", "ipsec Internet Key Exchange", NID_ipsec_IKE, 8, &so[6611]},
+    {"capwapAC", "Ctrl/provision WAP Access", NID_capwapAC, 8, &so[6619]},
+    {"capwapWTP", "Ctrl/Provision WAP Termination", NID_capwapWTP, 8, &so[6627]},
+    {"secureShellClient", "SSH Client", NID_sshClient, 8, &so[6635]},
+    {"secureShellServer", "SSH Server", NID_sshServer, 8, &so[6643]},
+    {"sendRouter", "Send Router", NID_sendRouter, 8, &so[6651]},
+    {"sendProxiedRouter", "Send Proxied Router", NID_sendProxiedRouter, 8, &so[6659]},
+    {"sendOwner", "Send Owner", NID_sendOwner, 8, &so[6667]},
+    {"sendProxiedOwner", "Send Proxied Owner", NID_sendProxiedOwner, 8, &so[6675]},
+    {"id-pkinit", "id-pkinit", NID_id_pkinit, 6, &so[6683]},
+    {"pkInitClientAuth", "PKINIT Client Auth", NID_pkInitClientAuth, 7, &so[6689]},
+    {"pkInitKDC", "Signing KDC Response", NID_pkInitKDC, 7, &so[6696]},
+    {"X25519", "X25519", NID_X25519, 3, &so[6703]},
+    {"X448", "X448", NID_X448, 3, &so[6706]},
+    {"HKDF", "hkdf", NID_hkdf},
+    {"KxRSA", "kx-rsa", NID_kx_rsa},
+    {"KxECDHE", "kx-ecdhe", NID_kx_ecdhe},
+    {"KxDHE", "kx-dhe", NID_kx_dhe},
+    {"KxECDHE-PSK", "kx-ecdhe-psk", NID_kx_ecdhe_psk},
+    {"KxDHE-PSK", "kx-dhe-psk", NID_kx_dhe_psk},
+    {"KxRSA_PSK", "kx-rsa-psk", NID_kx_rsa_psk},
+    {"KxPSK", "kx-psk", NID_kx_psk},
+    {"KxSRP", "kx-srp", NID_kx_srp},
+    {"KxGOST", "kx-gost", NID_kx_gost},
+    {"AuthRSA", "auth-rsa", NID_auth_rsa},
+    {"AuthECDSA", "auth-ecdsa", NID_auth_ecdsa},
+    {"AuthPSK", "auth-psk", NID_auth_psk},
+    {"AuthDSS", "auth-dss", NID_auth_dss},
+    {"AuthGOST01", "auth-gost01", NID_auth_gost01},
+    {"AuthGOST12", "auth-gost12", NID_auth_gost12},
+    {"AuthSRP", "auth-srp", NID_auth_srp},
+    {"AuthNULL", "auth-null", NID_auth_null},
+    { NULL, NULL, NID_undef },
+    { NULL, NULL, NID_undef },
+    {"BLAKE2b512", "blake2b512", NID_blake2b512, 11, &so[6709]},
+    {"BLAKE2s256", "blake2s256", NID_blake2s256, 11, &so[6720]},
+    {"id-smime-ct-contentCollection", "id-smime-ct-contentCollection", NID_id_smime_ct_contentCollection, 11, &so[6731]},
+    {"id-smime-ct-authEnvelopedData", "id-smime-ct-authEnvelopedData", NID_id_smime_ct_authEnvelopedData, 11, &so[6742]},
+    {"id-ct-xml", "id-ct-xml", NID_id_ct_xml, 11, &so[6753]},
+};
+
+#define NUM_SN 1052
+static const unsigned int sn_objs[NUM_SN] = {
+     364,    /* "AD_DVCS" */
+     419,    /* "AES-128-CBC" */
+     916,    /* "AES-128-CBC-HMAC-SHA1" */
+     948,    /* "AES-128-CBC-HMAC-SHA256" */
+     421,    /* "AES-128-CFB" */
+     650,    /* "AES-128-CFB1" */
+     653,    /* "AES-128-CFB8" */
+     904,    /* "AES-128-CTR" */
+     418,    /* "AES-128-ECB" */
+     958,    /* "AES-128-OCB" */
+     420,    /* "AES-128-OFB" */
+     913,    /* "AES-128-XTS" */
+     423,    /* "AES-192-CBC" */
+     917,    /* "AES-192-CBC-HMAC-SHA1" */
+     949,    /* "AES-192-CBC-HMAC-SHA256" */
+     425,    /* "AES-192-CFB" */
+     651,    /* "AES-192-CFB1" */
+     654,    /* "AES-192-CFB8" */
+     905,    /* "AES-192-CTR" */
+     422,    /* "AES-192-ECB" */
+     959,    /* "AES-192-OCB" */
+     424,    /* "AES-192-OFB" */
+     427,    /* "AES-256-CBC" */
+     918,    /* "AES-256-CBC-HMAC-SHA1" */
+     950,    /* "AES-256-CBC-HMAC-SHA256" */
+     429,    /* "AES-256-CFB" */
+     652,    /* "AES-256-CFB1" */
+     655,    /* "AES-256-CFB8" */
+     906,    /* "AES-256-CTR" */
+     426,    /* "AES-256-ECB" */
+     960,    /* "AES-256-OCB" */
+     428,    /* "AES-256-OFB" */
+     914,    /* "AES-256-XTS" */
+    1049,    /* "AuthDSS" */
+    1047,    /* "AuthECDSA" */
+    1050,    /* "AuthGOST01" */
+    1051,    /* "AuthGOST12" */
+    1053,    /* "AuthNULL" */
+    1048,    /* "AuthPSK" */
+    1046,    /* "AuthRSA" */
+    1052,    /* "AuthSRP" */
+      91,    /* "BF-CBC" */
+      93,    /* "BF-CFB" */
+      92,    /* "BF-ECB" */
+      94,    /* "BF-OFB" */
+    1056,    /* "BLAKE2b512" */
+    1057,    /* "BLAKE2s256" */
+      14,    /* "C" */
+     751,    /* "CAMELLIA-128-CBC" */
+     962,    /* "CAMELLIA-128-CCM" */
+     757,    /* "CAMELLIA-128-CFB" */
+     760,    /* "CAMELLIA-128-CFB1" */
+     763,    /* "CAMELLIA-128-CFB8" */
+     964,    /* "CAMELLIA-128-CMAC" */
+     963,    /* "CAMELLIA-128-CTR" */
+     754,    /* "CAMELLIA-128-ECB" */
+     961,    /* "CAMELLIA-128-GCM" */
+     766,    /* "CAMELLIA-128-OFB" */
+     752,    /* "CAMELLIA-192-CBC" */
+     966,    /* "CAMELLIA-192-CCM" */
+     758,    /* "CAMELLIA-192-CFB" */
+     761,    /* "CAMELLIA-192-CFB1" */
+     764,    /* "CAMELLIA-192-CFB8" */
+     968,    /* "CAMELLIA-192-CMAC" */
+     967,    /* "CAMELLIA-192-CTR" */
+     755,    /* "CAMELLIA-192-ECB" */
+     965,    /* "CAMELLIA-192-GCM" */
+     767,    /* "CAMELLIA-192-OFB" */
+     753,    /* "CAMELLIA-256-CBC" */
+     970,    /* "CAMELLIA-256-CCM" */
+     759,    /* "CAMELLIA-256-CFB" */
+     762,    /* "CAMELLIA-256-CFB1" */
+     765,    /* "CAMELLIA-256-CFB8" */
+     972,    /* "CAMELLIA-256-CMAC" */
+     971,    /* "CAMELLIA-256-CTR" */
+     756,    /* "CAMELLIA-256-ECB" */
+     969,    /* "CAMELLIA-256-GCM" */
+     768,    /* "CAMELLIA-256-OFB" */
+     108,    /* "CAST5-CBC" */
+     110,    /* "CAST5-CFB" */
+     109,    /* "CAST5-ECB" */
+     111,    /* "CAST5-OFB" */
+     894,    /* "CMAC" */
+      13,    /* "CN" */
+     141,    /* "CRLReason" */
+     417,    /* "CSPName" */
+    1019,    /* "ChaCha20" */
+    1018,    /* "ChaCha20-Poly1305" */
+     367,    /* "CrlID" */
+     391,    /* "DC" */
+      31,    /* "DES-CBC" */
+     643,    /* "DES-CDMF" */
+      30,    /* "DES-CFB" */
+     656,    /* "DES-CFB1" */
+     657,    /* "DES-CFB8" */
+      29,    /* "DES-ECB" */
+      32,    /* "DES-EDE" */
+      43,    /* "DES-EDE-CBC" */
+      60,    /* "DES-EDE-CFB" */
+      62,    /* "DES-EDE-OFB" */
+      33,    /* "DES-EDE3" */
+      44,    /* "DES-EDE3-CBC" */
+      61,    /* "DES-EDE3-CFB" */
+     658,    /* "DES-EDE3-CFB1" */
+     659,    /* "DES-EDE3-CFB8" */
+      63,    /* "DES-EDE3-OFB" */
+      45,    /* "DES-OFB" */
+      80,    /* "DESX-CBC" */
+     380,    /* "DOD" */
+     116,    /* "DSA" */
+      66,    /* "DSA-SHA" */
+     113,    /* "DSA-SHA1" */
+      70,    /* "DSA-SHA1-old" */
+      67,    /* "DSA-old" */
+     297,    /* "DVCS" */
+      99,    /* "GN" */
+    1036,    /* "HKDF" */
+     855,    /* "HMAC" */
+     780,    /* "HMAC-MD5" */
+     781,    /* "HMAC-SHA1" */
+     381,    /* "IANA" */
+      34,    /* "IDEA-CBC" */
+      35,    /* "IDEA-CFB" */
+      36,    /* "IDEA-ECB" */
+      46,    /* "IDEA-OFB" */
+    1004,    /* "INN" */
+     181,    /* "ISO" */
+     183,    /* "ISO-US" */
+     645,    /* "ITU-T" */
+     646,    /* "JOINT-ISO-ITU-T" */
+     773,    /* "KISA" */
+    1039,    /* "KxDHE" */
+    1041,    /* "KxDHE-PSK" */
+    1038,    /* "KxECDHE" */
+    1040,    /* "KxECDHE-PSK" */
+    1045,    /* "KxGOST" */
+    1043,    /* "KxPSK" */
+    1037,    /* "KxRSA" */
+    1042,    /* "KxRSA_PSK" */
+    1044,    /* "KxSRP" */
+      15,    /* "L" */
+     856,    /* "LocalKeySet" */
+       3,    /* "MD2" */
+     257,    /* "MD4" */
+       4,    /* "MD5" */
+     114,    /* "MD5-SHA1" */
+      95,    /* "MDC2" */
+     911,    /* "MGF1" */
+     388,    /* "Mail" */
+     393,    /* "NULL" */
+     404,    /* "NULL" */
+      57,    /* "Netscape" */
+     366,    /* "Nonce" */
+      17,    /* "O" */
+     178,    /* "OCSP" */
+     180,    /* "OCSPSigning" */
+    1005,    /* "OGRN" */
+     379,    /* "ORG" */
+      18,    /* "OU" */
+     749,    /* "Oakley-EC2N-3" */
+     750,    /* "Oakley-EC2N-4" */
+       9,    /* "PBE-MD2-DES" */
+     168,    /* "PBE-MD2-RC2-64" */
+      10,    /* "PBE-MD5-DES" */
+     169,    /* "PBE-MD5-RC2-64" */
+     147,    /* "PBE-SHA1-2DES" */
+     146,    /* "PBE-SHA1-3DES" */
+     170,    /* "PBE-SHA1-DES" */
+     148,    /* "PBE-SHA1-RC2-128" */
+     149,    /* "PBE-SHA1-RC2-40" */
+      68,    /* "PBE-SHA1-RC2-64" */
+     144,    /* "PBE-SHA1-RC4-128" */
+     145,    /* "PBE-SHA1-RC4-40" */
+     161,    /* "PBES2" */
+      69,    /* "PBKDF2" */
+     162,    /* "PBMAC1" */
+     127,    /* "PKIX" */
+     935,    /* "PSPECIFIED" */
+      98,    /* "RC2-40-CBC" */
+     166,    /* "RC2-64-CBC" */
+      37,    /* "RC2-CBC" */
+      39,    /* "RC2-CFB" */
+      38,    /* "RC2-ECB" */
+      40,    /* "RC2-OFB" */
+       5,    /* "RC4" */
+      97,    /* "RC4-40" */
+     915,    /* "RC4-HMAC-MD5" */
+     120,    /* "RC5-CBC" */
+     122,    /* "RC5-CFB" */
+     121,    /* "RC5-ECB" */
+     123,    /* "RC5-OFB" */
+     117,    /* "RIPEMD160" */
+      19,    /* "RSA" */
+       7,    /* "RSA-MD2" */
+     396,    /* "RSA-MD4" */
+       8,    /* "RSA-MD5" */
+      96,    /* "RSA-MDC2" */
+     104,    /* "RSA-NP-MD5" */
+     119,    /* "RSA-RIPEMD160" */
+      42,    /* "RSA-SHA" */
+      65,    /* "RSA-SHA1" */
+     115,    /* "RSA-SHA1-2" */
+     671,    /* "RSA-SHA224" */
+     668,    /* "RSA-SHA256" */
+     669,    /* "RSA-SHA384" */
+     670,    /* "RSA-SHA512" */
+     919,    /* "RSAES-OAEP" */
+     912,    /* "RSASSA-PSS" */
+     777,    /* "SEED-CBC" */
+     779,    /* "SEED-CFB" */
+     776,    /* "SEED-ECB" */
+     778,    /* "SEED-OFB" */
+      41,    /* "SHA" */
+      64,    /* "SHA1" */
+     675,    /* "SHA224" */
+     672,    /* "SHA256" */
+     673,    /* "SHA384" */
+     674,    /* "SHA512" */
+     188,    /* "SMIME" */
+     167,    /* "SMIME-CAPS" */
+     100,    /* "SN" */
+    1006,    /* "SNILS" */
+      16,    /* "ST" */
+     143,    /* "SXNetID" */
+    1021,    /* "TLS1-PRF" */
+     458,    /* "UID" */
+       0,    /* "UNDEF" */
+    1034,    /* "X25519" */
+    1035,    /* "X448" */
+      11,    /* "X500" */
+     378,    /* "X500algorithms" */
+      12,    /* "X509" */
+     184,    /* "X9-57" */
+     185,    /* "X9cm" */
+     125,    /* "ZLIB" */
+     478,    /* "aRecord" */
+     289,    /* "aaControls" */
+     287,    /* "ac-auditEntity" */
+     397,    /* "ac-proxying" */
+     288,    /* "ac-targeting" */
+     368,    /* "acceptableResponses" */
+     446,    /* "account" */
+     363,    /* "ad_timestamping" */
+     376,    /* "algorithm" */
+     405,    /* "ansi-X9-62" */
+     910,    /* "anyExtendedKeyUsage" */
+     746,    /* "anyPolicy" */
+     370,    /* "archiveCutoff" */
+     484,    /* "associatedDomain" */
+     485,    /* "associatedName" */
+     501,    /* "audio" */
+     177,    /* "authorityInfoAccess" */
+      90,    /* "authorityKeyIdentifier" */
+     882,    /* "authorityRevocationList" */
+      87,    /* "basicConstraints" */
+     365,    /* "basicOCSPResponse" */
+     285,    /* "biometricInfo" */
+     921,    /* "brainpoolP160r1" */
+     922,    /* "brainpoolP160t1" */
+     923,    /* "brainpoolP192r1" */
+     924,    /* "brainpoolP192t1" */
+     925,    /* "brainpoolP224r1" */
+     926,    /* "brainpoolP224t1" */
+     927,    /* "brainpoolP256r1" */
+     928,    /* "brainpoolP256t1" */
+     929,    /* "brainpoolP320r1" */
+     930,    /* "brainpoolP320t1" */
+     931,    /* "brainpoolP384r1" */
+     932,    /* "brainpoolP384t1" */
+     933,    /* "brainpoolP512r1" */
+     934,    /* "brainpoolP512t1" */
+     494,    /* "buildingName" */
+     860,    /* "businessCategory" */
+     691,    /* "c2onb191v4" */
+     692,    /* "c2onb191v5" */
+     697,    /* "c2onb239v4" */
+     698,    /* "c2onb239v5" */
+     684,    /* "c2pnb163v1" */
+     685,    /* "c2pnb163v2" */
+     686,    /* "c2pnb163v3" */
+     687,    /* "c2pnb176v1" */
+     693,    /* "c2pnb208w1" */
+     699,    /* "c2pnb272w1" */
+     700,    /* "c2pnb304w1" */
+     702,    /* "c2pnb368w1" */
+     688,    /* "c2tnb191v1" */
+     689,    /* "c2tnb191v2" */
+     690,    /* "c2tnb191v3" */
+     694,    /* "c2tnb239v1" */
+     695,    /* "c2tnb239v2" */
+     696,    /* "c2tnb239v3" */
+     701,    /* "c2tnb359v1" */
+     703,    /* "c2tnb431r1" */
+     881,    /* "cACertificate" */
+     483,    /* "cNAMERecord" */
+     179,    /* "caIssuers" */
+     785,    /* "caRepository" */
+    1023,    /* "capwapAC" */
+    1024,    /* "capwapWTP" */
+     443,    /* "caseIgnoreIA5StringSyntax" */
+     152,    /* "certBag" */
+     677,    /* "certicom-arc" */
+     771,    /* "certificateIssuer" */
+      89,    /* "certificatePolicies" */
+     883,    /* "certificateRevocationList" */
+      54,    /* "challengePassword" */
+     407,    /* "characteristic-two-field" */
+     395,    /* "clearance" */
+     130,    /* "clientAuth" */
+     131,    /* "codeSigning" */
+      50,    /* "contentType" */
+      53,    /* "countersignature" */
+     153,    /* "crlBag" */
+     103,    /* "crlDistributionPoints" */
+      88,    /* "crlNumber" */
+     884,    /* "crossCertificatePair" */
+     806,    /* "cryptocom" */
+     805,    /* "cryptopro" */
+     954,    /* "ct_cert_scts" */
+     952,    /* "ct_precert_poison" */
+     951,    /* "ct_precert_scts" */
+     953,    /* "ct_precert_signer" */
+     500,    /* "dITRedirect" */
+     451,    /* "dNSDomain" */
+     495,    /* "dSAQuality" */
+     434,    /* "data" */
+     390,    /* "dcobject" */
+     140,    /* "deltaCRL" */
+     891,    /* "deltaRevocationList" */
+     107,    /* "description" */
+     871,    /* "destinationIndicator" */
+     947,    /* "dh-cofactor-kdf" */
+     946,    /* "dh-std-kdf" */
+      28,    /* "dhKeyAgreement" */
+     941,    /* "dhSinglePass-cofactorDH-sha1kdf-scheme" */
+     942,    /* "dhSinglePass-cofactorDH-sha224kdf-scheme" */
+     943,    /* "dhSinglePass-cofactorDH-sha256kdf-scheme" */
+     944,    /* "dhSinglePass-cofactorDH-sha384kdf-scheme" */
+     945,    /* "dhSinglePass-cofactorDH-sha512kdf-scheme" */
+     936,    /* "dhSinglePass-stdDH-sha1kdf-scheme" */
+     937,    /* "dhSinglePass-stdDH-sha224kdf-scheme" */
+     938,    /* "dhSinglePass-stdDH-sha256kdf-scheme" */
+     939,    /* "dhSinglePass-stdDH-sha384kdf-scheme" */
+     940,    /* "dhSinglePass-stdDH-sha512kdf-scheme" */
+     920,    /* "dhpublicnumber" */
+     382,    /* "directory" */
+     887,    /* "distinguishedName" */
+     892,    /* "dmdName" */
+     174,    /* "dnQualifier" */
+     447,    /* "document" */
+     471,    /* "documentAuthor" */
+     468,    /* "documentIdentifier" */
+     472,    /* "documentLocation" */
+     502,    /* "documentPublisher" */
+     449,    /* "documentSeries" */
+     469,    /* "documentTitle" */
+     470,    /* "documentVersion" */
+     392,    /* "domain" */
+     452,    /* "domainRelatedObject" */
+     802,    /* "dsa_with_SHA224" */
+     803,    /* "dsa_with_SHA256" */
+     791,    /* "ecdsa-with-Recommended" */
+     416,    /* "ecdsa-with-SHA1" */
+     793,    /* "ecdsa-with-SHA224" */
+     794,    /* "ecdsa-with-SHA256" */
+     795,    /* "ecdsa-with-SHA384" */
+     796,    /* "ecdsa-with-SHA512" */
+     792,    /* "ecdsa-with-Specified" */
+      48,    /* "emailAddress" */
+     132,    /* "emailProtection" */
+     885,    /* "enhancedSearchGuide" */
+     389,    /* "enterprises" */
+     384,    /* "experimental" */
+     172,    /* "extReq" */
+      56,    /* "extendedCertificateAttributes" */
+     126,    /* "extendedKeyUsage" */
+     372,    /* "extendedStatus" */
+     867,    /* "facsimileTelephoneNumber" */
+     462,    /* "favouriteDrink" */
+     857,    /* "freshestCRL" */
+     453,    /* "friendlyCountry" */
+     490,    /* "friendlyCountryName" */
+     156,    /* "friendlyName" */
+     509,    /* "generationQualifier" */
+     815,    /* "gost-mac" */
+     976,    /* "gost-mac-12" */
+     811,    /* "gost2001" */
+     851,    /* "gost2001cc" */
+     979,    /* "gost2012_256" */
+     980,    /* "gost2012_512" */
+     813,    /* "gost89" */
+    1009,    /* "gost89-cbc" */
+     814,    /* "gost89-cnt" */
+     975,    /* "gost89-cnt-12" */
+    1011,    /* "gost89-ctr" */
+    1010,    /* "gost89-ecb" */
+     812,    /* "gost94" */
+     850,    /* "gost94cc" */
+    1015,    /* "grasshopper-cbc" */
+    1016,    /* "grasshopper-cfb" */
+    1013,    /* "grasshopper-ctr" */
+    1012,    /* "grasshopper-ecb" */
+    1017,    /* "grasshopper-mac" */
+    1014,    /* "grasshopper-ofb" */
+     797,    /* "hmacWithMD5" */
+     163,    /* "hmacWithSHA1" */
+     798,    /* "hmacWithSHA224" */
+     799,    /* "hmacWithSHA256" */
+     800,    /* "hmacWithSHA384" */
+     801,    /* "hmacWithSHA512" */
+     432,    /* "holdInstructionCallIssuer" */
+     430,    /* "holdInstructionCode" */
+     431,    /* "holdInstructionNone" */
+     433,    /* "holdInstructionReject" */
+     486,    /* "homePostalAddress" */
+     473,    /* "homeTelephoneNumber" */
+     466,    /* "host" */
+     889,    /* "houseIdentifier" */
+     442,    /* "iA5StringSyntax" */
+     783,    /* "id-DHBasedMac" */
+     824,    /* "id-Gost28147-89-CryptoPro-A-ParamSet" */
+     825,    /* "id-Gost28147-89-CryptoPro-B-ParamSet" */
+     826,    /* "id-Gost28147-89-CryptoPro-C-ParamSet" */
+     827,    /* "id-Gost28147-89-CryptoPro-D-ParamSet" */
+     819,    /* "id-Gost28147-89-CryptoPro-KeyMeshing" */
+     829,    /* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */
+     828,    /* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */
+     830,    /* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */
+     820,    /* "id-Gost28147-89-None-KeyMeshing" */
+     823,    /* "id-Gost28147-89-TestParamSet" */
+     849,    /* "id-Gost28147-89-cc" */
+     840,    /* "id-GostR3410-2001-CryptoPro-A-ParamSet" */
+     841,    /* "id-GostR3410-2001-CryptoPro-B-ParamSet" */
+     842,    /* "id-GostR3410-2001-CryptoPro-C-ParamSet" */
+     843,    /* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */
+     844,    /* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */
+     854,    /* "id-GostR3410-2001-ParamSet-cc" */
+     839,    /* "id-GostR3410-2001-TestParamSet" */
+     817,    /* "id-GostR3410-2001DH" */
+     832,    /* "id-GostR3410-94-CryptoPro-A-ParamSet" */
+     833,    /* "id-GostR3410-94-CryptoPro-B-ParamSet" */
+     834,    /* "id-GostR3410-94-CryptoPro-C-ParamSet" */
+     835,    /* "id-GostR3410-94-CryptoPro-D-ParamSet" */
+     836,    /* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */
+     837,    /* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */
+     838,    /* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */
+     831,    /* "id-GostR3410-94-TestParamSet" */
+     845,    /* "id-GostR3410-94-a" */
+     846,    /* "id-GostR3410-94-aBis" */
+     847,    /* "id-GostR3410-94-b" */
+     848,    /* "id-GostR3410-94-bBis" */
+     818,    /* "id-GostR3410-94DH" */
+     822,    /* "id-GostR3411-94-CryptoProParamSet" */
+     821,    /* "id-GostR3411-94-TestParamSet" */
+     807,    /* "id-GostR3411-94-with-GostR3410-2001" */
+     853,    /* "id-GostR3411-94-with-GostR3410-2001-cc" */
+     808,    /* "id-GostR3411-94-with-GostR3410-94" */
+     852,    /* "id-GostR3411-94-with-GostR3410-94-cc" */
+     810,    /* "id-HMACGostR3411-94" */
+     782,    /* "id-PasswordBasedMAC" */
+     266,    /* "id-aca" */
+     355,    /* "id-aca-accessIdentity" */
+     354,    /* "id-aca-authenticationInfo" */
+     356,    /* "id-aca-chargingIdentity" */
+     399,    /* "id-aca-encAttrs" */
+     357,    /* "id-aca-group" */
+     358,    /* "id-aca-role" */
+     176,    /* "id-ad" */
+     896,    /* "id-aes128-CCM" */
+     895,    /* "id-aes128-GCM" */
+     788,    /* "id-aes128-wrap" */
+     897,    /* "id-aes128-wrap-pad" */
+     899,    /* "id-aes192-CCM" */
+     898,    /* "id-aes192-GCM" */
+     789,    /* "id-aes192-wrap" */
+     900,    /* "id-aes192-wrap-pad" */
+     902,    /* "id-aes256-CCM" */
+     901,    /* "id-aes256-GCM" */
+     790,    /* "id-aes256-wrap" */
+     903,    /* "id-aes256-wrap-pad" */
+     262,    /* "id-alg" */
+     893,    /* "id-alg-PWRI-KEK" */
+     323,    /* "id-alg-des40" */
+     326,    /* "id-alg-dh-pop" */
+     325,    /* "id-alg-dh-sig-hmac-sha1" */
+     324,    /* "id-alg-noSignature" */
+     907,    /* "id-camellia128-wrap" */
+     908,    /* "id-camellia192-wrap" */
+     909,    /* "id-camellia256-wrap" */
+     268,    /* "id-cct" */
+     361,    /* "id-cct-PKIData" */
+     362,    /* "id-cct-PKIResponse" */
+     360,    /* "id-cct-crs" */
+      81,    /* "id-ce" */
+     680,    /* "id-characteristic-two-basis" */
+     263,    /* "id-cmc" */
+     334,    /* "id-cmc-addExtensions" */
+     346,    /* "id-cmc-confirmCertAcceptance" */
+     330,    /* "id-cmc-dataReturn" */
+     336,    /* "id-cmc-decryptedPOP" */
+     335,    /* "id-cmc-encryptedPOP" */
+     339,    /* "id-cmc-getCRL" */
+     338,    /* "id-cmc-getCert" */
+     328,    /* "id-cmc-identification" */
+     329,    /* "id-cmc-identityProof" */
+     337,    /* "id-cmc-lraPOPWitness" */
+     344,    /* "id-cmc-popLinkRandom" */
+     345,    /* "id-cmc-popLinkWitness" */
+     343,    /* "id-cmc-queryPending" */
+     333,    /* "id-cmc-recipientNonce" */
+     341,    /* "id-cmc-regInfo" */
+     342,    /* "id-cmc-responseInfo" */
+     340,    /* "id-cmc-revokeRequest" */
+     332,    /* "id-cmc-senderNonce" */
+     327,    /* "id-cmc-statusInfo" */
+     331,    /* "id-cmc-transactionId" */
+     787,    /* "id-ct-asciiTextWithCRLF" */
+    1060,    /* "id-ct-xml" */
+     408,    /* "id-ecPublicKey" */
+     508,    /* "id-hex-multipart-message" */
+     507,    /* "id-hex-partial-message" */
+     260,    /* "id-it" */
+     302,    /* "id-it-caKeyUpdateInfo" */
+     298,    /* "id-it-caProtEncCert" */
+     311,    /* "id-it-confirmWaitTime" */
+     303,    /* "id-it-currentCRL" */
+     300,    /* "id-it-encKeyPairTypes" */
+     310,    /* "id-it-implicitConfirm" */
+     308,    /* "id-it-keyPairParamRep" */
+     307,    /* "id-it-keyPairParamReq" */
+     312,    /* "id-it-origPKIMessage" */
+     301,    /* "id-it-preferredSymmAlg" */
+     309,    /* "id-it-revPassphrase" */
+     299,    /* "id-it-signKeyPairTypes" */
+     305,    /* "id-it-subscriptionRequest" */
+     306,    /* "id-it-subscriptionResponse" */
+     784,    /* "id-it-suppLangTags" */
+     304,    /* "id-it-unsupportedOIDs" */
+     128,    /* "id-kp" */
+     280,    /* "id-mod-attribute-cert" */
+     274,    /* "id-mod-cmc" */
+     277,    /* "id-mod-cmp" */
+     284,    /* "id-mod-cmp2000" */
+     273,    /* "id-mod-crmf" */
+     283,    /* "id-mod-dvcs" */
+     275,    /* "id-mod-kea-profile-88" */
+     276,    /* "id-mod-kea-profile-93" */
+     282,    /* "id-mod-ocsp" */
+     278,    /* "id-mod-qualified-cert-88" */
+     279,    /* "id-mod-qualified-cert-93" */
+     281,    /* "id-mod-timestamp-protocol" */
+     264,    /* "id-on" */
+     858,    /* "id-on-permanentIdentifier" */
+     347,    /* "id-on-personalData" */
+     265,    /* "id-pda" */
+     352,    /* "id-pda-countryOfCitizenship" */
+     353,    /* "id-pda-countryOfResidence" */
+     348,    /* "id-pda-dateOfBirth" */
+     351,    /* "id-pda-gender" */
+     349,    /* "id-pda-placeOfBirth" */
+     175,    /* "id-pe" */
+    1031,    /* "id-pkinit" */
+     261,    /* "id-pkip" */
+     258,    /* "id-pkix-mod" */
+     269,    /* "id-pkix1-explicit-88" */
+     271,    /* "id-pkix1-explicit-93" */
+     270,    /* "id-pkix1-implicit-88" */
+     272,    /* "id-pkix1-implicit-93" */
+     662,    /* "id-ppl" */
+     664,    /* "id-ppl-anyLanguage" */
+     667,    /* "id-ppl-independent" */
+     665,    /* "id-ppl-inheritAll" */
+     267,    /* "id-qcs" */
+     359,    /* "id-qcs-pkixQCSyntax-v1" */
+     259,    /* "id-qt" */
+     164,    /* "id-qt-cps" */
+     165,    /* "id-qt-unotice" */
+     313,    /* "id-regCtrl" */
+     316,    /* "id-regCtrl-authenticator" */
+     319,    /* "id-regCtrl-oldCertID" */
+     318,    /* "id-regCtrl-pkiArchiveOptions" */
+     317,    /* "id-regCtrl-pkiPublicationInfo" */
+     320,    /* "id-regCtrl-protocolEncrKey" */
+     315,    /* "id-regCtrl-regToken" */
+     314,    /* "id-regInfo" */
+     322,    /* "id-regInfo-certReq" */
+     321,    /* "id-regInfo-utf8Pairs" */
+     973,    /* "id-scrypt" */
+     512,    /* "id-set" */
+     191,    /* "id-smime-aa" */
+     215,    /* "id-smime-aa-contentHint" */
+     218,    /* "id-smime-aa-contentIdentifier" */
+     221,    /* "id-smime-aa-contentReference" */
+     240,    /* "id-smime-aa-dvcs-dvc" */
+     217,    /* "id-smime-aa-encapContentType" */
+     222,    /* "id-smime-aa-encrypKeyPref" */
+     220,    /* "id-smime-aa-equivalentLabels" */
+     232,    /* "id-smime-aa-ets-CertificateRefs" */
+     233,    /* "id-smime-aa-ets-RevocationRefs" */
+     238,    /* "id-smime-aa-ets-archiveTimeStamp" */
+     237,    /* "id-smime-aa-ets-certCRLTimestamp" */
+     234,    /* "id-smime-aa-ets-certValues" */
+     227,    /* "id-smime-aa-ets-commitmentType" */
+     231,    /* "id-smime-aa-ets-contentTimestamp" */
+     236,    /* "id-smime-aa-ets-escTimeStamp" */
+     230,    /* "id-smime-aa-ets-otherSigCert" */
+     235,    /* "id-smime-aa-ets-revocationValues" */
+     226,    /* "id-smime-aa-ets-sigPolicyId" */
+     229,    /* "id-smime-aa-ets-signerAttr" */
+     228,    /* "id-smime-aa-ets-signerLocation" */
+     219,    /* "id-smime-aa-macValue" */
+     214,    /* "id-smime-aa-mlExpandHistory" */
+     216,    /* "id-smime-aa-msgSigDigest" */
+     212,    /* "id-smime-aa-receiptRequest" */
+     213,    /* "id-smime-aa-securityLabel" */
+     239,    /* "id-smime-aa-signatureType" */
+     223,    /* "id-smime-aa-signingCertificate" */
+     224,    /* "id-smime-aa-smimeEncryptCerts" */
+     225,    /* "id-smime-aa-timeStampToken" */
+     192,    /* "id-smime-alg" */
+     243,    /* "id-smime-alg-3DESwrap" */
+     246,    /* "id-smime-alg-CMS3DESwrap" */
+     247,    /* "id-smime-alg-CMSRC2wrap" */
+     245,    /* "id-smime-alg-ESDH" */
+     241,    /* "id-smime-alg-ESDHwith3DES" */
+     242,    /* "id-smime-alg-ESDHwithRC2" */
+     244,    /* "id-smime-alg-RC2wrap" */
+     193,    /* "id-smime-cd" */
+     248,    /* "id-smime-cd-ldap" */
+     190,    /* "id-smime-ct" */
+     210,    /* "id-smime-ct-DVCSRequestData" */
+     211,    /* "id-smime-ct-DVCSResponseData" */
+     208,    /* "id-smime-ct-TDTInfo" */
+     207,    /* "id-smime-ct-TSTInfo" */
+     205,    /* "id-smime-ct-authData" */
+    1059,    /* "id-smime-ct-authEnvelopedData" */
+     786,    /* "id-smime-ct-compressedData" */
+    1058,    /* "id-smime-ct-contentCollection" */
+     209,    /* "id-smime-ct-contentInfo" */
+     206,    /* "id-smime-ct-publishCert" */
+     204,    /* "id-smime-ct-receipt" */
+     195,    /* "id-smime-cti" */
+     255,    /* "id-smime-cti-ets-proofOfApproval" */
+     256,    /* "id-smime-cti-ets-proofOfCreation" */
+     253,    /* "id-smime-cti-ets-proofOfDelivery" */
+     251,    /* "id-smime-cti-ets-proofOfOrigin" */
+     252,    /* "id-smime-cti-ets-proofOfReceipt" */
+     254,    /* "id-smime-cti-ets-proofOfSender" */
+     189,    /* "id-smime-mod" */
+     196,    /* "id-smime-mod-cms" */
+     197,    /* "id-smime-mod-ess" */
+     202,    /* "id-smime-mod-ets-eSigPolicy-88" */
+     203,    /* "id-smime-mod-ets-eSigPolicy-97" */
+     200,    /* "id-smime-mod-ets-eSignature-88" */
+     201,    /* "id-smime-mod-ets-eSignature-97" */
+     199,    /* "id-smime-mod-msg-v3" */
+     198,    /* "id-smime-mod-oid" */
+     194,    /* "id-smime-spq" */
+     250,    /* "id-smime-spq-ets-sqt-unotice" */
+     249,    /* "id-smime-spq-ets-sqt-uri" */
+     974,    /* "id-tc26" */
+     991,    /* "id-tc26-agreement" */
+     992,    /* "id-tc26-agreement-gost-3410-2012-256" */
+     993,    /* "id-tc26-agreement-gost-3410-2012-512" */
+     977,    /* "id-tc26-algorithms" */
+     990,    /* "id-tc26-cipher" */
+    1001,    /* "id-tc26-cipher-constants" */
+     994,    /* "id-tc26-constants" */
+     981,    /* "id-tc26-digest" */
+    1000,    /* "id-tc26-digest-constants" */
+    1002,    /* "id-tc26-gost-28147-constants" */
+    1003,    /* "id-tc26-gost-28147-param-Z" */
+     996,    /* "id-tc26-gost-3410-2012-512-constants" */
+     998,    /* "id-tc26-gost-3410-2012-512-paramSetA" */
+     999,    /* "id-tc26-gost-3410-2012-512-paramSetB" */
+     997,    /* "id-tc26-gost-3410-2012-512-paramSetTest" */
+     988,    /* "id-tc26-hmac-gost-3411-2012-256" */
+     989,    /* "id-tc26-hmac-gost-3411-2012-512" */
+     987,    /* "id-tc26-mac" */
+     978,    /* "id-tc26-sign" */
+     995,    /* "id-tc26-sign-constants" */
+     984,    /* "id-tc26-signwithdigest" */
+     985,    /* "id-tc26-signwithdigest-gost3410-2012-256" */
+     986,    /* "id-tc26-signwithdigest-gost3410-2012-512" */
+     676,    /* "identified-organization" */
+     461,    /* "info" */
+     748,    /* "inhibitAnyPolicy" */
+     101,    /* "initials" */
+     647,    /* "international-organizations" */
+     869,    /* "internationaliSDNNumber" */
+     142,    /* "invalidityDate" */
+     294,    /* "ipsecEndSystem" */
+    1022,    /* "ipsecIKE" */
+     295,    /* "ipsecTunnel" */
+     296,    /* "ipsecUser" */
+      86,    /* "issuerAltName" */
+    1008,    /* "issuerSignTool" */
+     770,    /* "issuingDistributionPoint" */
+     492,    /* "janetMailbox" */
+     957,    /* "jurisdictionC" */
+     955,    /* "jurisdictionL" */
+     956,    /* "jurisdictionST" */
+     150,    /* "keyBag" */
+      83,    /* "keyUsage" */
+     477,    /* "lastModifiedBy" */
+     476,    /* "lastModifiedTime" */
+     157,    /* "localKeyID" */
+     480,    /* "mXRecord" */
+     460,    /* "mail" */
+     493,    /* "mailPreferenceOption" */
+     467,    /* "manager" */
+     982,    /* "md_gost12_256" */
+     983,    /* "md_gost12_512" */
+     809,    /* "md_gost94" */
+     875,    /* "member" */
+     182,    /* "member-body" */
+      51,    /* "messageDigest" */
+     383,    /* "mgmt" */
+     504,    /* "mime-mhs" */
+     506,    /* "mime-mhs-bodies" */
+     505,    /* "mime-mhs-headings" */
+     488,    /* "mobileTelephoneNumber" */
+     136,    /* "msCTLSign" */
+     135,    /* "msCodeCom" */
+     134,    /* "msCodeInd" */
+     138,    /* "msEFS" */
+     171,    /* "msExtReq" */
+     137,    /* "msSGC" */
+     648,    /* "msSmartcardLogin" */
+     649,    /* "msUPN" */
+     481,    /* "nSRecord" */
+     173,    /* "name" */
+     666,    /* "nameConstraints" */
+     369,    /* "noCheck" */
+     403,    /* "noRevAvail" */
+      72,    /* "nsBaseUrl" */
+      76,    /* "nsCaPolicyUrl" */
+      74,    /* "nsCaRevocationUrl" */
+      58,    /* "nsCertExt" */
+      79,    /* "nsCertSequence" */
+      71,    /* "nsCertType" */
+      78,    /* "nsComment" */
+      59,    /* "nsDataType" */
+      75,    /* "nsRenewalUrl" */
+      73,    /* "nsRevocationUrl" */
+     139,    /* "nsSGC" */
+      77,    /* "nsSslServerName" */
+     681,    /* "onBasis" */
+     491,    /* "organizationalStatus" */
+     475,    /* "otherMailbox" */
+     876,    /* "owner" */
+     489,    /* "pagerTelephoneNumber" */
+     374,    /* "path" */
+     112,    /* "pbeWithMD5AndCast5CBC" */
+     499,    /* "personalSignature" */
+     487,    /* "personalTitle" */
+     464,    /* "photo" */
+     863,    /* "physicalDeliveryOfficeName" */
+     437,    /* "pilot" */
+     439,    /* "pilotAttributeSyntax" */
+     438,    /* "pilotAttributeType" */
+     479,    /* "pilotAttributeType27" */
+     456,    /* "pilotDSA" */
+     441,    /* "pilotGroups" */
+     444,    /* "pilotObject" */
+     440,    /* "pilotObjectClass" */
+     455,    /* "pilotOrganization" */
+     445,    /* "pilotPerson" */
+    1032,    /* "pkInitClientAuth" */
+    1033,    /* "pkInitKDC" */
+       2,    /* "pkcs" */
+     186,    /* "pkcs1" */
+      27,    /* "pkcs3" */
+     187,    /* "pkcs5" */
+      20,    /* "pkcs7" */
+      21,    /* "pkcs7-data" */
+      25,    /* "pkcs7-digestData" */
+      26,    /* "pkcs7-encryptedData" */
+      23,    /* "pkcs7-envelopedData" */
+      24,    /* "pkcs7-signedAndEnvelopedData" */
+      22,    /* "pkcs7-signedData" */
+     151,    /* "pkcs8ShroudedKeyBag" */
+      47,    /* "pkcs9" */
+     401,    /* "policyConstraints" */
+     747,    /* "policyMappings" */
+     862,    /* "postOfficeBox" */
+     861,    /* "postalAddress" */
+     661,    /* "postalCode" */
+     683,    /* "ppBasis" */
+     872,    /* "preferredDeliveryMethod" */
+     873,    /* "presentationAddress" */
+     816,    /* "prf-gostr3411-94" */
+     406,    /* "prime-field" */
+     409,    /* "prime192v1" */
+     410,    /* "prime192v2" */
+     411,    /* "prime192v3" */
+     412,    /* "prime239v1" */
+     413,    /* "prime239v2" */
+     414,    /* "prime239v3" */
+     415,    /* "prime256v1" */
+     385,    /* "private" */
+      84,    /* "privateKeyUsagePeriod" */
+     886,    /* "protocolInformation" */
+     663,    /* "proxyCertInfo" */
+     510,    /* "pseudonym" */
+     435,    /* "pss" */
+     286,    /* "qcStatements" */
+     457,    /* "qualityLabelledData" */
+     450,    /* "rFC822localPart" */
+     870,    /* "registeredAddress" */
+     400,    /* "role" */
+     877,    /* "roleOccupant" */
+     448,    /* "room" */
+     463,    /* "roomNumber" */
+       6,    /* "rsaEncryption" */
+     644,    /* "rsaOAEPEncryptionSET" */
+     377,    /* "rsaSignature" */
+       1,    /* "rsadsi" */
+     482,    /* "sOARecord" */
+     155,    /* "safeContentsBag" */
+     291,    /* "sbgp-autonomousSysNum" */
+     290,    /* "sbgp-ipAddrBlock" */
+     292,    /* "sbgp-routerIdentifier" */
+     159,    /* "sdsiCertificate" */
+     859,    /* "searchGuide" */
+     704,    /* "secp112r1" */
+     705,    /* "secp112r2" */
+     706,    /* "secp128r1" */
+     707,    /* "secp128r2" */
+     708,    /* "secp160k1" */
+     709,    /* "secp160r1" */
+     710,    /* "secp160r2" */
+     711,    /* "secp192k1" */
+     712,    /* "secp224k1" */
+     713,    /* "secp224r1" */
+     714,    /* "secp256k1" */
+     715,    /* "secp384r1" */
+     716,    /* "secp521r1" */
+     154,    /* "secretBag" */
+     474,    /* "secretary" */
+     717,    /* "sect113r1" */
+     718,    /* "sect113r2" */
+     719,    /* "sect131r1" */
+     720,    /* "sect131r2" */
+     721,    /* "sect163k1" */
+     722,    /* "sect163r1" */
+     723,    /* "sect163r2" */
+     724,    /* "sect193r1" */
+     725,    /* "sect193r2" */
+     726,    /* "sect233k1" */
+     727,    /* "sect233r1" */
+     728,    /* "sect239k1" */
+     729,    /* "sect283k1" */
+     730,    /* "sect283r1" */
+     731,    /* "sect409k1" */
+     732,    /* "sect409r1" */
+     733,    /* "sect571k1" */
+     734,    /* "sect571r1" */
+    1025,    /* "secureShellClient" */
+    1026,    /* "secureShellServer" */
+     386,    /* "security" */
+     878,    /* "seeAlso" */
+     394,    /* "selected-attribute-types" */
+    1029,    /* "sendOwner" */
+    1030,    /* "sendProxiedOwner" */
+    1028,    /* "sendProxiedRouter" */
+    1027,    /* "sendRouter" */
+     105,    /* "serialNumber" */
+     129,    /* "serverAuth" */
+     371,    /* "serviceLocator" */
+     625,    /* "set-addPolicy" */
+     515,    /* "set-attr" */
+     518,    /* "set-brand" */
+     638,    /* "set-brand-AmericanExpress" */
+     637,    /* "set-brand-Diners" */
+     636,    /* "set-brand-IATA-ATA" */
+     639,    /* "set-brand-JCB" */
+     641,    /* "set-brand-MasterCard" */
+     642,    /* "set-brand-Novus" */
+     640,    /* "set-brand-Visa" */
+     517,    /* "set-certExt" */
+     513,    /* "set-ctype" */
+     514,    /* "set-msgExt" */
+     516,    /* "set-policy" */
+     607,    /* "set-policy-root" */
+     624,    /* "set-rootKeyThumb" */
+     620,    /* "setAttr-Cert" */
+     631,    /* "setAttr-GenCryptgrm" */
+     623,    /* "setAttr-IssCap" */
+     628,    /* "setAttr-IssCap-CVM" */
+     630,    /* "setAttr-IssCap-Sig" */
+     629,    /* "setAttr-IssCap-T2" */
+     621,    /* "setAttr-PGWYcap" */
+     635,    /* "setAttr-SecDevSig" */
+     632,    /* "setAttr-T2Enc" */
+     633,    /* "setAttr-T2cleartxt" */
+     634,    /* "setAttr-TokICCsig" */
+     627,    /* "setAttr-Token-B0Prime" */
+     626,    /* "setAttr-Token-EMV" */
+     622,    /* "setAttr-TokenType" */
+     619,    /* "setCext-IssuerCapabilities" */
+     615,    /* "setCext-PGWYcapabilities" */
+     616,    /* "setCext-TokenIdentifier" */
+     618,    /* "setCext-TokenType" */
+     617,    /* "setCext-Track2Data" */
+     611,    /* "setCext-cCertRequired" */
+     609,    /* "setCext-certType" */
+     608,    /* "setCext-hashedRoot" */
+     610,    /* "setCext-merchData" */
+     613,    /* "setCext-setExt" */
+     614,    /* "setCext-setQualf" */
+     612,    /* "setCext-tunneling" */
+     540,    /* "setct-AcqCardCodeMsg" */
+     576,    /* "setct-AcqCardCodeMsgTBE" */
+     570,    /* "setct-AuthReqTBE" */
+     534,    /* "setct-AuthReqTBS" */
+     527,    /* "setct-AuthResBaggage" */
+     571,    /* "setct-AuthResTBE" */
+     572,    /* "setct-AuthResTBEX" */
+     535,    /* "setct-AuthResTBS" */
+     536,    /* "setct-AuthResTBSX" */
+     528,    /* "setct-AuthRevReqBaggage" */
+     577,    /* "setct-AuthRevReqTBE" */
+     541,    /* "setct-AuthRevReqTBS" */
+     529,    /* "setct-AuthRevResBaggage" */
+     542,    /* "setct-AuthRevResData" */
+     578,    /* "setct-AuthRevResTBE" */
+     579,    /* "setct-AuthRevResTBEB" */
+     543,    /* "setct-AuthRevResTBS" */
+     573,    /* "setct-AuthTokenTBE" */
+     537,    /* "setct-AuthTokenTBS" */
+     600,    /* "setct-BCIDistributionTBS" */
+     558,    /* "setct-BatchAdminReqData" */
+     592,    /* "setct-BatchAdminReqTBE" */
+     559,    /* "setct-BatchAdminResData" */
+     593,    /* "setct-BatchAdminResTBE" */
+     599,    /* "setct-CRLNotificationResTBS" */
+     598,    /* "setct-CRLNotificationTBS" */
+     580,    /* "setct-CapReqTBE" */
+     581,    /* "setct-CapReqTBEX" */
+     544,    /* "setct-CapReqTBS" */
+     545,    /* "setct-CapReqTBSX" */
+     546,    /* "setct-CapResData" */
+     582,    /* "setct-CapResTBE" */
+     583,    /* "setct-CapRevReqTBE" */
+     584,    /* "setct-CapRevReqTBEX" */
+     547,    /* "setct-CapRevReqTBS" */
+     548,    /* "setct-CapRevReqTBSX" */
+     549,    /* "setct-CapRevResData" */
+     585,    /* "setct-CapRevResTBE" */
+     538,    /* "setct-CapTokenData" */
+     530,    /* "setct-CapTokenSeq" */
+     574,    /* "setct-CapTokenTBE" */
+     575,    /* "setct-CapTokenTBEX" */
+     539,    /* "setct-CapTokenTBS" */
+     560,    /* "setct-CardCInitResTBS" */
+     566,    /* "setct-CertInqReqTBS" */
+     563,    /* "setct-CertReqData" */
+     595,    /* "setct-CertReqTBE" */
+     596,    /* "setct-CertReqTBEX" */
+     564,    /* "setct-CertReqTBS" */
+     565,    /* "setct-CertResData" */
+     597,    /* "setct-CertResTBE" */
+     586,    /* "setct-CredReqTBE" */
+     587,    /* "setct-CredReqTBEX" */
+     550,    /* "setct-CredReqTBS" */
+     551,    /* "setct-CredReqTBSX" */
+     552,    /* "setct-CredResData" */
+     588,    /* "setct-CredResTBE" */
+     589,    /* "setct-CredRevReqTBE" */
+     590,    /* "setct-CredRevReqTBEX" */
+     553,    /* "setct-CredRevReqTBS" */
+     554,    /* "setct-CredRevReqTBSX" */
+     555,    /* "setct-CredRevResData" */
+     591,    /* "setct-CredRevResTBE" */
+     567,    /* "setct-ErrorTBS" */
+     526,    /* "setct-HODInput" */
+     561,    /* "setct-MeAqCInitResTBS" */
+     522,    /* "setct-OIData" */
+     519,    /* "setct-PANData" */
+     521,    /* "setct-PANOnly" */
+     520,    /* "setct-PANToken" */
+     556,    /* "setct-PCertReqData" */
+     557,    /* "setct-PCertResTBS" */
+     523,    /* "setct-PI" */
+     532,    /* "setct-PI-TBS" */
+     524,    /* "setct-PIData" */
+     525,    /* "setct-PIDataUnsigned" */
+     568,    /* "setct-PIDualSignedTBE" */
+     569,    /* "setct-PIUnsignedTBE" */
+     531,    /* "setct-PInitResData" */
+     533,    /* "setct-PResData" */
+     594,    /* "setct-RegFormReqTBE" */
+     562,    /* "setct-RegFormResTBS" */
+     606,    /* "setext-cv" */
+     601,    /* "setext-genCrypt" */
+     602,    /* "setext-miAuth" */
+     604,    /* "setext-pinAny" */
+     603,    /* "setext-pinSecure" */
+     605,    /* "setext-track2" */
+      52,    /* "signingTime" */
+     454,    /* "simpleSecurityObject" */
+     496,    /* "singleLevelQuality" */
+     387,    /* "snmpv2" */
+     660,    /* "street" */
+      85,    /* "subjectAltName" */
+     769,    /* "subjectDirectoryAttributes" */
+     398,    /* "subjectInfoAccess" */
+      82,    /* "subjectKeyIdentifier" */
+    1007,    /* "subjectSignTool" */
+     498,    /* "subtreeMaximumQuality" */
+     497,    /* "subtreeMinimumQuality" */
+     890,    /* "supportedAlgorithms" */
+     874,    /* "supportedApplicationContext" */
+     402,    /* "targetInformation" */
+     864,    /* "telephoneNumber" */
+     866,    /* "teletexTerminalIdentifier" */
+     865,    /* "telexNumber" */
+     459,    /* "textEncodedORAddress" */
+     293,    /* "textNotice" */
+     133,    /* "timeStamping" */
+     106,    /* "title" */
+    1020,    /* "tlsfeature" */
+     682,    /* "tpBasis" */
+     375,    /* "trustRoot" */
+     436,    /* "ucl" */
+     102,    /* "uid" */
+     888,    /* "uniqueMember" */
+      55,    /* "unstructuredAddress" */
+      49,    /* "unstructuredName" */
+     880,    /* "userCertificate" */
+     465,    /* "userClass" */
+     879,    /* "userPassword" */
+     373,    /* "valid" */
+     678,    /* "wap" */
+     679,    /* "wap-wsg" */
+     735,    /* "wap-wsg-idm-ecid-wtls1" */
+     743,    /* "wap-wsg-idm-ecid-wtls10" */
+     744,    /* "wap-wsg-idm-ecid-wtls11" */
+     745,    /* "wap-wsg-idm-ecid-wtls12" */
+     736,    /* "wap-wsg-idm-ecid-wtls3" */
+     737,    /* "wap-wsg-idm-ecid-wtls4" */
+     738,    /* "wap-wsg-idm-ecid-wtls5" */
+     739,    /* "wap-wsg-idm-ecid-wtls6" */
+     740,    /* "wap-wsg-idm-ecid-wtls7" */
+     741,    /* "wap-wsg-idm-ecid-wtls8" */
+     742,    /* "wap-wsg-idm-ecid-wtls9" */
+     804,    /* "whirlpool" */
+     868,    /* "x121Address" */
+     503,    /* "x500UniqueIdentifier" */
+     158,    /* "x509Certificate" */
+     160,    /* "x509Crl" */
+};
+
+#define NUM_LN 1052
+static const unsigned int ln_objs[NUM_LN] = {
+     363,    /* "AD Time Stamping" */
+     405,    /* "ANSI X9.62" */
+     368,    /* "Acceptable OCSP Responses" */
+     910,    /* "Any Extended Key Usage" */
+     664,    /* "Any language" */
+     177,    /* "Authority Information Access" */
+     365,    /* "Basic OCSP Response" */
+     285,    /* "Biometric Info" */
+     179,    /* "CA Issuers" */
+     785,    /* "CA Repository" */
+     954,    /* "CT Certificate SCTs" */
+     952,    /* "CT Precertificate Poison" */
+     951,    /* "CT Precertificate SCTs" */
+     953,    /* "CT Precertificate Signer" */
+     131,    /* "Code Signing" */
+    1024,    /* "Ctrl/Provision WAP Termination" */
+    1023,    /* "Ctrl/provision WAP Access" */
+     783,    /* "Diffie-Hellman based MAC" */
+     382,    /* "Directory" */
+     392,    /* "Domain" */
+     132,    /* "E-mail Protection" */
+     389,    /* "Enterprises" */
+     384,    /* "Experimental" */
+     372,    /* "Extended OCSP Status" */
+     172,    /* "Extension Request" */
+     813,    /* "GOST 28147-89" */
+     849,    /* "GOST 28147-89 Cryptocom ParamSet" */
+     815,    /* "GOST 28147-89 MAC" */
+    1003,    /* "GOST 28147-89 TC26 parameter set" */
+     851,    /* "GOST 34.10-2001 Cryptocom" */
+     850,    /* "GOST 34.10-94 Cryptocom" */
+     811,    /* "GOST R 34.10-2001" */
+     817,    /* "GOST R 34.10-2001 DH" */
+     998,    /* "GOST R 34.10-2012 (512 bit) ParamSet A" */
+     999,    /* "GOST R 34.10-2012 (512 bit) ParamSet B" */
+     997,    /* "GOST R 34.10-2012 (512 bit) testing parameter set" */
+     979,    /* "GOST R 34.10-2012 with 256 bit modulus" */
+     980,    /* "GOST R 34.10-2012 with 512 bit modulus" */
+     985,    /* "GOST R 34.10-2012 with GOST R 34.11-2012 (256 bit)" */
+     986,    /* "GOST R 34.10-2012 with GOST R 34.11-2012 (512 bit)" */
+     812,    /* "GOST R 34.10-94" */
+     818,    /* "GOST R 34.10-94 DH" */
+     982,    /* "GOST R 34.11-2012 with 256 bit hash" */
+     983,    /* "GOST R 34.11-2012 with 512 bit hash" */
+     809,    /* "GOST R 34.11-94" */
+     816,    /* "GOST R 34.11-94 PRF" */
+     807,    /* "GOST R 34.11-94 with GOST R 34.10-2001" */
+     853,    /* "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" */
+     808,    /* "GOST R 34.11-94 with GOST R 34.10-94" */
+     852,    /* "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" */
+     854,    /* "GOST R 3410-2001 Parameter Set Cryptocom" */
+     988,    /* "HMAC GOST 34.11-2012 256 bit" */
+     989,    /* "HMAC GOST 34.11-2012 512 bit" */
+     810,    /* "HMAC GOST 34.11-94" */
+     432,    /* "Hold Instruction Call Issuer" */
+     430,    /* "Hold Instruction Code" */
+     431,    /* "Hold Instruction None" */
+     433,    /* "Hold Instruction Reject" */
+     634,    /* "ICC or token signature" */
+    1004,    /* "INN" */
+     294,    /* "IPSec End System" */
+     295,    /* "IPSec Tunnel" */
+     296,    /* "IPSec User" */
+     182,    /* "ISO Member Body" */
+     183,    /* "ISO US Member Body" */
+     667,    /* "Independent" */
+     665,    /* "Inherit all" */
+     647,    /* "International Organizations" */
+     142,    /* "Invalidity Date" */
+     504,    /* "MIME MHS" */
+     388,    /* "Mail" */
+     383,    /* "Management" */
+     417,    /* "Microsoft CSP Name" */
+     135,    /* "Microsoft Commercial Code Signing" */
+     138,    /* "Microsoft Encrypted File System" */
+     171,    /* "Microsoft Extension Request" */
+     134,    /* "Microsoft Individual Code Signing" */
+     856,    /* "Microsoft Local Key set" */
+     137,    /* "Microsoft Server Gated Crypto" */
+     648,    /* "Microsoft Smartcardlogin" */
+     136,    /* "Microsoft Trust List Signing" */
+     649,    /* "Microsoft Universal Principal Name" */
+     393,    /* "NULL" */
+     404,    /* "NULL" */
+      72,    /* "Netscape Base Url" */
+      76,    /* "Netscape CA Policy Url" */
+      74,    /* "Netscape CA Revocation Url" */
+      71,    /* "Netscape Cert Type" */
+      58,    /* "Netscape Certificate Extension" */
+      79,    /* "Netscape Certificate Sequence" */
+      78,    /* "Netscape Comment" */
+      57,    /* "Netscape Communications Corp." */
+      59,    /* "Netscape Data Type" */
+      75,    /* "Netscape Renewal Url" */
+      73,    /* "Netscape Revocation Url" */
+      77,    /* "Netscape SSL Server Name" */
+     139,    /* "Netscape Server Gated Crypto" */
+     178,    /* "OCSP" */
+     370,    /* "OCSP Archive Cutoff" */
+     367,    /* "OCSP CRL ID" */
+     369,    /* "OCSP No Check" */
+     366,    /* "OCSP Nonce" */
+     371,    /* "OCSP Service Locator" */
+     180,    /* "OCSP Signing" */
+    1005,    /* "OGRN" */
+     161,    /* "PBES2" */
+      69,    /* "PBKDF2" */
+     162,    /* "PBMAC1" */
+    1032,    /* "PKINIT Client Auth" */
+     127,    /* "PKIX" */
+     858,    /* "Permanent Identifier" */
+     164,    /* "Policy Qualifier CPS" */
+     165,    /* "Policy Qualifier User Notice" */
+     385,    /* "Private" */
+     663,    /* "Proxy Certificate Information" */
+       1,    /* "RSA Data Security, Inc." */
+       2,    /* "RSA Data Security, Inc. PKCS" */
+     188,    /* "S/MIME" */
+     167,    /* "S/MIME Capabilities" */
+    1006,    /* "SNILS" */
+     387,    /* "SNMPv2" */
+    1025,    /* "SSH Client" */
+    1026,    /* "SSH Server" */
+     512,    /* "Secure Electronic Transactions" */
+     386,    /* "Security" */
+     394,    /* "Selected Attribute Types" */
+    1029,    /* "Send Owner" */
+    1030,    /* "Send Proxied Owner" */
+    1028,    /* "Send Proxied Router" */
+    1027,    /* "Send Router" */
+    1033,    /* "Signing KDC Response" */
+    1008,    /* "Signing Tool of Issuer" */
+    1007,    /* "Signing Tool of Subject" */
+     143,    /* "Strong Extranet ID" */
+     398,    /* "Subject Information Access" */
+    1020,    /* "TLS Feature" */
+     130,    /* "TLS Web Client Authentication" */
+     129,    /* "TLS Web Server Authentication" */
+     133,    /* "Time Stamping" */
+     375,    /* "Trust Root" */
+    1034,    /* "X25519" */
+    1035,    /* "X448" */
+      12,    /* "X509" */
+     402,    /* "X509v3 AC Targeting" */
+     746,    /* "X509v3 Any Policy" */
+      90,    /* "X509v3 Authority Key Identifier" */
+      87,    /* "X509v3 Basic Constraints" */
+     103,    /* "X509v3 CRL Distribution Points" */
+      88,    /* "X509v3 CRL Number" */
+     141,    /* "X509v3 CRL Reason Code" */
+     771,    /* "X509v3 Certificate Issuer" */
+      89,    /* "X509v3 Certificate Policies" */
+     140,    /* "X509v3 Delta CRL Indicator" */
+     126,    /* "X509v3 Extended Key Usage" */
+     857,    /* "X509v3 Freshest CRL" */
+     748,    /* "X509v3 Inhibit Any Policy" */
+      86,    /* "X509v3 Issuer Alternative Name" */
+     770,    /* "X509v3 Issuing Distribution Point" */
+      83,    /* "X509v3 Key Usage" */
+     666,    /* "X509v3 Name Constraints" */
+     403,    /* "X509v3 No Revocation Available" */
+     401,    /* "X509v3 Policy Constraints" */
+     747,    /* "X509v3 Policy Mappings" */
+      84,    /* "X509v3 Private Key Usage Period" */
+      85,    /* "X509v3 Subject Alternative Name" */
+     769,    /* "X509v3 Subject Directory Attributes" */
+      82,    /* "X509v3 Subject Key Identifier" */
+     920,    /* "X9.42 DH" */
+     184,    /* "X9.57" */
+     185,    /* "X9.57 CM ?" */
+     478,    /* "aRecord" */
+     289,    /* "aaControls" */
+     287,    /* "ac-auditEntity" */
+     397,    /* "ac-proxying" */
+     288,    /* "ac-targeting" */
+     446,    /* "account" */
+     364,    /* "ad dvcs" */
+     606,    /* "additional verification" */
+     419,    /* "aes-128-cbc" */
+     916,    /* "aes-128-cbc-hmac-sha1" */
+     948,    /* "aes-128-cbc-hmac-sha256" */
+     896,    /* "aes-128-ccm" */
+     421,    /* "aes-128-cfb" */
+     650,    /* "aes-128-cfb1" */
+     653,    /* "aes-128-cfb8" */
+     904,    /* "aes-128-ctr" */
+     418,    /* "aes-128-ecb" */
+     895,    /* "aes-128-gcm" */
+     958,    /* "aes-128-ocb" */
+     420,    /* "aes-128-ofb" */
+     913,    /* "aes-128-xts" */
+     423,    /* "aes-192-cbc" */
+     917,    /* "aes-192-cbc-hmac-sha1" */
+     949,    /* "aes-192-cbc-hmac-sha256" */
+     899,    /* "aes-192-ccm" */
+     425,    /* "aes-192-cfb" */
+     651,    /* "aes-192-cfb1" */
+     654,    /* "aes-192-cfb8" */
+     905,    /* "aes-192-ctr" */
+     422,    /* "aes-192-ecb" */
+     898,    /* "aes-192-gcm" */
+     959,    /* "aes-192-ocb" */
+     424,    /* "aes-192-ofb" */
+     427,    /* "aes-256-cbc" */
+     918,    /* "aes-256-cbc-hmac-sha1" */
+     950,    /* "aes-256-cbc-hmac-sha256" */
+     902,    /* "aes-256-ccm" */
+     429,    /* "aes-256-cfb" */
+     652,    /* "aes-256-cfb1" */
+     655,    /* "aes-256-cfb8" */
+     906,    /* "aes-256-ctr" */
+     426,    /* "aes-256-ecb" */
+     901,    /* "aes-256-gcm" */
+     960,    /* "aes-256-ocb" */
+     428,    /* "aes-256-ofb" */
+     914,    /* "aes-256-xts" */
+     376,    /* "algorithm" */
+     484,    /* "associatedDomain" */
+     485,    /* "associatedName" */
+     501,    /* "audio" */
+    1049,    /* "auth-dss" */
+    1047,    /* "auth-ecdsa" */
+    1050,    /* "auth-gost01" */
+    1051,    /* "auth-gost12" */
+    1053,    /* "auth-null" */
+    1048,    /* "auth-psk" */
+    1046,    /* "auth-rsa" */
+    1052,    /* "auth-srp" */
+     882,    /* "authorityRevocationList" */
+      91,    /* "bf-cbc" */
+      93,    /* "bf-cfb" */
+      92,    /* "bf-ecb" */
+      94,    /* "bf-ofb" */
+    1056,    /* "blake2b512" */
+    1057,    /* "blake2s256" */
+     921,    /* "brainpoolP160r1" */
+     922,    /* "brainpoolP160t1" */
+     923,    /* "brainpoolP192r1" */
+     924,    /* "brainpoolP192t1" */
+     925,    /* "brainpoolP224r1" */
+     926,    /* "brainpoolP224t1" */
+     927,    /* "brainpoolP256r1" */
+     928,    /* "brainpoolP256t1" */
+     929,    /* "brainpoolP320r1" */
+     930,    /* "brainpoolP320t1" */
+     931,    /* "brainpoolP384r1" */
+     932,    /* "brainpoolP384t1" */
+     933,    /* "brainpoolP512r1" */
+     934,    /* "brainpoolP512t1" */
+     494,    /* "buildingName" */
+     860,    /* "businessCategory" */
+     691,    /* "c2onb191v4" */
+     692,    /* "c2onb191v5" */
+     697,    /* "c2onb239v4" */
+     698,    /* "c2onb239v5" */
+     684,    /* "c2pnb163v1" */
+     685,    /* "c2pnb163v2" */
+     686,    /* "c2pnb163v3" */
+     687,    /* "c2pnb176v1" */
+     693,    /* "c2pnb208w1" */
+     699,    /* "c2pnb272w1" */
+     700,    /* "c2pnb304w1" */
+     702,    /* "c2pnb368w1" */
+     688,    /* "c2tnb191v1" */
+     689,    /* "c2tnb191v2" */
+     690,    /* "c2tnb191v3" */
+     694,    /* "c2tnb239v1" */
+     695,    /* "c2tnb239v2" */
+     696,    /* "c2tnb239v3" */
+     701,    /* "c2tnb359v1" */
+     703,    /* "c2tnb431r1" */
+     881,    /* "cACertificate" */
+     483,    /* "cNAMERecord" */
+     751,    /* "camellia-128-cbc" */
+     962,    /* "camellia-128-ccm" */
+     757,    /* "camellia-128-cfb" */
+     760,    /* "camellia-128-cfb1" */
+     763,    /* "camellia-128-cfb8" */
+     964,    /* "camellia-128-cmac" */
+     963,    /* "camellia-128-ctr" */
+     754,    /* "camellia-128-ecb" */
+     961,    /* "camellia-128-gcm" */
+     766,    /* "camellia-128-ofb" */
+     752,    /* "camellia-192-cbc" */
+     966,    /* "camellia-192-ccm" */
+     758,    /* "camellia-192-cfb" */
+     761,    /* "camellia-192-cfb1" */
+     764,    /* "camellia-192-cfb8" */
+     968,    /* "camellia-192-cmac" */
+     967,    /* "camellia-192-ctr" */
+     755,    /* "camellia-192-ecb" */
+     965,    /* "camellia-192-gcm" */
+     767,    /* "camellia-192-ofb" */
+     753,    /* "camellia-256-cbc" */
+     970,    /* "camellia-256-ccm" */
+     759,    /* "camellia-256-cfb" */
+     762,    /* "camellia-256-cfb1" */
+     765,    /* "camellia-256-cfb8" */
+     972,    /* "camellia-256-cmac" */
+     971,    /* "camellia-256-ctr" */
+     756,    /* "camellia-256-ecb" */
+     969,    /* "camellia-256-gcm" */
+     768,    /* "camellia-256-ofb" */
+     443,    /* "caseIgnoreIA5StringSyntax" */
+     108,    /* "cast5-cbc" */
+     110,    /* "cast5-cfb" */
+     109,    /* "cast5-ecb" */
+     111,    /* "cast5-ofb" */
+     152,    /* "certBag" */
+     677,    /* "certicom-arc" */
+     517,    /* "certificate extensions" */
+     883,    /* "certificateRevocationList" */
+    1019,    /* "chacha20" */
+    1018,    /* "chacha20-poly1305" */
+      54,    /* "challengePassword" */
+     407,    /* "characteristic-two-field" */
+     395,    /* "clearance" */
+     633,    /* "cleartext track 2" */
+     894,    /* "cmac" */
+      13,    /* "commonName" */
+     513,    /* "content types" */
+      50,    /* "contentType" */
+      53,    /* "countersignature" */
+      14,    /* "countryName" */
+     153,    /* "crlBag" */
+     884,    /* "crossCertificatePair" */
+     806,    /* "cryptocom" */
+     805,    /* "cryptopro" */
+     500,    /* "dITRedirect" */
+     451,    /* "dNSDomain" */
+     495,    /* "dSAQuality" */
+     434,    /* "data" */
+     390,    /* "dcObject" */
+     891,    /* "deltaRevocationList" */
+      31,    /* "des-cbc" */
+     643,    /* "des-cdmf" */
+      30,    /* "des-cfb" */
+     656,    /* "des-cfb1" */
+     657,    /* "des-cfb8" */
+      29,    /* "des-ecb" */
+      32,    /* "des-ede" */
+      43,    /* "des-ede-cbc" */
+      60,    /* "des-ede-cfb" */
+      62,    /* "des-ede-ofb" */
+      33,    /* "des-ede3" */
+      44,    /* "des-ede3-cbc" */
+      61,    /* "des-ede3-cfb" */
+     658,    /* "des-ede3-cfb1" */
+     659,    /* "des-ede3-cfb8" */
+      63,    /* "des-ede3-ofb" */
+      45,    /* "des-ofb" */
+     107,    /* "description" */
+     871,    /* "destinationIndicator" */
+      80,    /* "desx-cbc" */
+     947,    /* "dh-cofactor-kdf" */
+     946,    /* "dh-std-kdf" */
+      28,    /* "dhKeyAgreement" */
+     941,    /* "dhSinglePass-cofactorDH-sha1kdf-scheme" */
+     942,    /* "dhSinglePass-cofactorDH-sha224kdf-scheme" */
+     943,    /* "dhSinglePass-cofactorDH-sha256kdf-scheme" */
+     944,    /* "dhSinglePass-cofactorDH-sha384kdf-scheme" */
+     945,    /* "dhSinglePass-cofactorDH-sha512kdf-scheme" */
+     936,    /* "dhSinglePass-stdDH-sha1kdf-scheme" */
+     937,    /* "dhSinglePass-stdDH-sha224kdf-scheme" */
+     938,    /* "dhSinglePass-stdDH-sha256kdf-scheme" */
+     939,    /* "dhSinglePass-stdDH-sha384kdf-scheme" */
+     940,    /* "dhSinglePass-stdDH-sha512kdf-scheme" */
+      11,    /* "directory services (X.500)" */
+     378,    /* "directory services - algorithms" */
+     887,    /* "distinguishedName" */
+     892,    /* "dmdName" */
+     174,    /* "dnQualifier" */
+     447,    /* "document" */
+     471,    /* "documentAuthor" */
+     468,    /* "documentIdentifier" */
+     472,    /* "documentLocation" */
+     502,    /* "documentPublisher" */
+     449,    /* "documentSeries" */
+     469,    /* "documentTitle" */
+     470,    /* "documentVersion" */
+     380,    /* "dod" */
+     391,    /* "domainComponent" */
+     452,    /* "domainRelatedObject" */
+     116,    /* "dsaEncryption" */
+      67,    /* "dsaEncryption-old" */
+      66,    /* "dsaWithSHA" */
+     113,    /* "dsaWithSHA1" */
+      70,    /* "dsaWithSHA1-old" */
+     802,    /* "dsa_with_SHA224" */
+     803,    /* "dsa_with_SHA256" */
+     297,    /* "dvcs" */
+     791,    /* "ecdsa-with-Recommended" */
+     416,    /* "ecdsa-with-SHA1" */
+     793,    /* "ecdsa-with-SHA224" */
+     794,    /* "ecdsa-with-SHA256" */
+     795,    /* "ecdsa-with-SHA384" */
+     796,    /* "ecdsa-with-SHA512" */
+     792,    /* "ecdsa-with-Specified" */
+      48,    /* "emailAddress" */
+     632,    /* "encrypted track 2" */
+     885,    /* "enhancedSearchGuide" */
+      56,    /* "extendedCertificateAttributes" */
+     867,    /* "facsimileTelephoneNumber" */
+     462,    /* "favouriteDrink" */
+     453,    /* "friendlyCountry" */
+     490,    /* "friendlyCountryName" */
+     156,    /* "friendlyName" */
+     631,    /* "generate cryptogram" */
+     509,    /* "generationQualifier" */
+     601,    /* "generic cryptogram" */
+      99,    /* "givenName" */
+     976,    /* "gost-mac-12" */
+    1009,    /* "gost89-cbc" */
+     814,    /* "gost89-cnt" */
+     975,    /* "gost89-cnt-12" */
+    1011,    /* "gost89-ctr" */
+    1010,    /* "gost89-ecb" */
+    1015,    /* "grasshopper-cbc" */
+    1016,    /* "grasshopper-cfb" */
+    1013,    /* "grasshopper-ctr" */
+    1012,    /* "grasshopper-ecb" */
+    1017,    /* "grasshopper-mac" */
+    1014,    /* "grasshopper-ofb" */
+    1036,    /* "hkdf" */
+     855,    /* "hmac" */
+     780,    /* "hmac-md5" */
+     781,    /* "hmac-sha1" */
+     797,    /* "hmacWithMD5" */
+     163,    /* "hmacWithSHA1" */
+     798,    /* "hmacWithSHA224" */
+     799,    /* "hmacWithSHA256" */
+     800,    /* "hmacWithSHA384" */
+     801,    /* "hmacWithSHA512" */
+     486,    /* "homePostalAddress" */
+     473,    /* "homeTelephoneNumber" */
+     466,    /* "host" */
+     889,    /* "houseIdentifier" */
+     442,    /* "iA5StringSyntax" */
+     381,    /* "iana" */
+     824,    /* "id-Gost28147-89-CryptoPro-A-ParamSet" */
+     825,    /* "id-Gost28147-89-CryptoPro-B-ParamSet" */
+     826,    /* "id-Gost28147-89-CryptoPro-C-ParamSet" */
+     827,    /* "id-Gost28147-89-CryptoPro-D-ParamSet" */
+     819,    /* "id-Gost28147-89-CryptoPro-KeyMeshing" */
+     829,    /* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */
+     828,    /* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */
+     830,    /* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */
+     820,    /* "id-Gost28147-89-None-KeyMeshing" */
+     823,    /* "id-Gost28147-89-TestParamSet" */
+     840,    /* "id-GostR3410-2001-CryptoPro-A-ParamSet" */
+     841,    /* "id-GostR3410-2001-CryptoPro-B-ParamSet" */
+     842,    /* "id-GostR3410-2001-CryptoPro-C-ParamSet" */
+     843,    /* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */
+     844,    /* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */
+     839,    /* "id-GostR3410-2001-TestParamSet" */
+     832,    /* "id-GostR3410-94-CryptoPro-A-ParamSet" */
+     833,    /* "id-GostR3410-94-CryptoPro-B-ParamSet" */
+     834,    /* "id-GostR3410-94-CryptoPro-C-ParamSet" */
+     835,    /* "id-GostR3410-94-CryptoPro-D-ParamSet" */
+     836,    /* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */
+     837,    /* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */
+     838,    /* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */
+     831,    /* "id-GostR3410-94-TestParamSet" */
+     845,    /* "id-GostR3410-94-a" */
+     846,    /* "id-GostR3410-94-aBis" */
+     847,    /* "id-GostR3410-94-b" */
+     848,    /* "id-GostR3410-94-bBis" */
+     822,    /* "id-GostR3411-94-CryptoProParamSet" */
+     821,    /* "id-GostR3411-94-TestParamSet" */
+     266,    /* "id-aca" */
+     355,    /* "id-aca-accessIdentity" */
+     354,    /* "id-aca-authenticationInfo" */
+     356,    /* "id-aca-chargingIdentity" */
+     399,    /* "id-aca-encAttrs" */
+     357,    /* "id-aca-group" */
+     358,    /* "id-aca-role" */
+     176,    /* "id-ad" */
+     788,    /* "id-aes128-wrap" */
+     897,    /* "id-aes128-wrap-pad" */
+     789,    /* "id-aes192-wrap" */
+     900,    /* "id-aes192-wrap-pad" */
+     790,    /* "id-aes256-wrap" */
+     903,    /* "id-aes256-wrap-pad" */
+     262,    /* "id-alg" */
+     893,    /* "id-alg-PWRI-KEK" */
+     323,    /* "id-alg-des40" */
+     326,    /* "id-alg-dh-pop" */
+     325,    /* "id-alg-dh-sig-hmac-sha1" */
+     324,    /* "id-alg-noSignature" */
+     907,    /* "id-camellia128-wrap" */
+     908,    /* "id-camellia192-wrap" */
+     909,    /* "id-camellia256-wrap" */
+     268,    /* "id-cct" */
+     361,    /* "id-cct-PKIData" */
+     362,    /* "id-cct-PKIResponse" */
+     360,    /* "id-cct-crs" */
+      81,    /* "id-ce" */
+     680,    /* "id-characteristic-two-basis" */
+     263,    /* "id-cmc" */
+     334,    /* "id-cmc-addExtensions" */
+     346,    /* "id-cmc-confirmCertAcceptance" */
+     330,    /* "id-cmc-dataReturn" */
+     336,    /* "id-cmc-decryptedPOP" */
+     335,    /* "id-cmc-encryptedPOP" */
+     339,    /* "id-cmc-getCRL" */
+     338,    /* "id-cmc-getCert" */
+     328,    /* "id-cmc-identification" */
+     329,    /* "id-cmc-identityProof" */
+     337,    /* "id-cmc-lraPOPWitness" */
+     344,    /* "id-cmc-popLinkRandom" */
+     345,    /* "id-cmc-popLinkWitness" */
+     343,    /* "id-cmc-queryPending" */
+     333,    /* "id-cmc-recipientNonce" */
+     341,    /* "id-cmc-regInfo" */
+     342,    /* "id-cmc-responseInfo" */
+     340,    /* "id-cmc-revokeRequest" */
+     332,    /* "id-cmc-senderNonce" */
+     327,    /* "id-cmc-statusInfo" */
+     331,    /* "id-cmc-transactionId" */
+     787,    /* "id-ct-asciiTextWithCRLF" */
+    1060,    /* "id-ct-xml" */
+     408,    /* "id-ecPublicKey" */
+     508,    /* "id-hex-multipart-message" */
+     507,    /* "id-hex-partial-message" */
+     260,    /* "id-it" */
+     302,    /* "id-it-caKeyUpdateInfo" */
+     298,    /* "id-it-caProtEncCert" */
+     311,    /* "id-it-confirmWaitTime" */
+     303,    /* "id-it-currentCRL" */
+     300,    /* "id-it-encKeyPairTypes" */
+     310,    /* "id-it-implicitConfirm" */
+     308,    /* "id-it-keyPairParamRep" */
+     307,    /* "id-it-keyPairParamReq" */
+     312,    /* "id-it-origPKIMessage" */
+     301,    /* "id-it-preferredSymmAlg" */
+     309,    /* "id-it-revPassphrase" */
+     299,    /* "id-it-signKeyPairTypes" */
+     305,    /* "id-it-subscriptionRequest" */
+     306,    /* "id-it-subscriptionResponse" */
+     784,    /* "id-it-suppLangTags" */
+     304,    /* "id-it-unsupportedOIDs" */
+     128,    /* "id-kp" */
+     280,    /* "id-mod-attribute-cert" */
+     274,    /* "id-mod-cmc" */
+     277,    /* "id-mod-cmp" */
+     284,    /* "id-mod-cmp2000" */
+     273,    /* "id-mod-crmf" */
+     283,    /* "id-mod-dvcs" */
+     275,    /* "id-mod-kea-profile-88" */
+     276,    /* "id-mod-kea-profile-93" */
+     282,    /* "id-mod-ocsp" */
+     278,    /* "id-mod-qualified-cert-88" */
+     279,    /* "id-mod-qualified-cert-93" */
+     281,    /* "id-mod-timestamp-protocol" */
+     264,    /* "id-on" */
+     347,    /* "id-on-personalData" */
+     265,    /* "id-pda" */
+     352,    /* "id-pda-countryOfCitizenship" */
+     353,    /* "id-pda-countryOfResidence" */
+     348,    /* "id-pda-dateOfBirth" */
+     351,    /* "id-pda-gender" */
+     349,    /* "id-pda-placeOfBirth" */
+     175,    /* "id-pe" */
+    1031,    /* "id-pkinit" */
+     261,    /* "id-pkip" */
+     258,    /* "id-pkix-mod" */
+     269,    /* "id-pkix1-explicit-88" */
+     271,    /* "id-pkix1-explicit-93" */
+     270,    /* "id-pkix1-implicit-88" */
+     272,    /* "id-pkix1-implicit-93" */
+     662,    /* "id-ppl" */
+     267,    /* "id-qcs" */
+     359,    /* "id-qcs-pkixQCSyntax-v1" */
+     259,    /* "id-qt" */
+     313,    /* "id-regCtrl" */
+     316,    /* "id-regCtrl-authenticator" */
+     319,    /* "id-regCtrl-oldCertID" */
+     318,    /* "id-regCtrl-pkiArchiveOptions" */
+     317,    /* "id-regCtrl-pkiPublicationInfo" */
+     320,    /* "id-regCtrl-protocolEncrKey" */
+     315,    /* "id-regCtrl-regToken" */
+     314,    /* "id-regInfo" */
+     322,    /* "id-regInfo-certReq" */
+     321,    /* "id-regInfo-utf8Pairs" */
+     973,    /* "id-scrypt" */
+     191,    /* "id-smime-aa" */
+     215,    /* "id-smime-aa-contentHint" */
+     218,    /* "id-smime-aa-contentIdentifier" */
+     221,    /* "id-smime-aa-contentReference" */
+     240,    /* "id-smime-aa-dvcs-dvc" */
+     217,    /* "id-smime-aa-encapContentType" */
+     222,    /* "id-smime-aa-encrypKeyPref" */
+     220,    /* "id-smime-aa-equivalentLabels" */
+     232,    /* "id-smime-aa-ets-CertificateRefs" */
+     233,    /* "id-smime-aa-ets-RevocationRefs" */
+     238,    /* "id-smime-aa-ets-archiveTimeStamp" */
+     237,    /* "id-smime-aa-ets-certCRLTimestamp" */
+     234,    /* "id-smime-aa-ets-certValues" */
+     227,    /* "id-smime-aa-ets-commitmentType" */
+     231,    /* "id-smime-aa-ets-contentTimestamp" */
+     236,    /* "id-smime-aa-ets-escTimeStamp" */
+     230,    /* "id-smime-aa-ets-otherSigCert" */
+     235,    /* "id-smime-aa-ets-revocationValues" */
+     226,    /* "id-smime-aa-ets-sigPolicyId" */
+     229,    /* "id-smime-aa-ets-signerAttr" */
+     228,    /* "id-smime-aa-ets-signerLocation" */
+     219,    /* "id-smime-aa-macValue" */
+     214,    /* "id-smime-aa-mlExpandHistory" */
+     216,    /* "id-smime-aa-msgSigDigest" */
+     212,    /* "id-smime-aa-receiptRequest" */
+     213,    /* "id-smime-aa-securityLabel" */
+     239,    /* "id-smime-aa-signatureType" */
+     223,    /* "id-smime-aa-signingCertificate" */
+     224,    /* "id-smime-aa-smimeEncryptCerts" */
+     225,    /* "id-smime-aa-timeStampToken" */
+     192,    /* "id-smime-alg" */
+     243,    /* "id-smime-alg-3DESwrap" */
+     246,    /* "id-smime-alg-CMS3DESwrap" */
+     247,    /* "id-smime-alg-CMSRC2wrap" */
+     245,    /* "id-smime-alg-ESDH" */
+     241,    /* "id-smime-alg-ESDHwith3DES" */
+     242,    /* "id-smime-alg-ESDHwithRC2" */
+     244,    /* "id-smime-alg-RC2wrap" */
+     193,    /* "id-smime-cd" */
+     248,    /* "id-smime-cd-ldap" */
+     190,    /* "id-smime-ct" */
+     210,    /* "id-smime-ct-DVCSRequestData" */
+     211,    /* "id-smime-ct-DVCSResponseData" */
+     208,    /* "id-smime-ct-TDTInfo" */
+     207,    /* "id-smime-ct-TSTInfo" */
+     205,    /* "id-smime-ct-authData" */
+    1059,    /* "id-smime-ct-authEnvelopedData" */
+     786,    /* "id-smime-ct-compressedData" */
+    1058,    /* "id-smime-ct-contentCollection" */
+     209,    /* "id-smime-ct-contentInfo" */
+     206,    /* "id-smime-ct-publishCert" */
+     204,    /* "id-smime-ct-receipt" */
+     195,    /* "id-smime-cti" */
+     255,    /* "id-smime-cti-ets-proofOfApproval" */
+     256,    /* "id-smime-cti-ets-proofOfCreation" */
+     253,    /* "id-smime-cti-ets-proofOfDelivery" */
+     251,    /* "id-smime-cti-ets-proofOfOrigin" */
+     252,    /* "id-smime-cti-ets-proofOfReceipt" */
+     254,    /* "id-smime-cti-ets-proofOfSender" */
+     189,    /* "id-smime-mod" */
+     196,    /* "id-smime-mod-cms" */
+     197,    /* "id-smime-mod-ess" */
+     202,    /* "id-smime-mod-ets-eSigPolicy-88" */
+     203,    /* "id-smime-mod-ets-eSigPolicy-97" */
+     200,    /* "id-smime-mod-ets-eSignature-88" */
+     201,    /* "id-smime-mod-ets-eSignature-97" */
+     199,    /* "id-smime-mod-msg-v3" */
+     198,    /* "id-smime-mod-oid" */
+     194,    /* "id-smime-spq" */
+     250,    /* "id-smime-spq-ets-sqt-unotice" */
+     249,    /* "id-smime-spq-ets-sqt-uri" */
+     974,    /* "id-tc26" */
+     991,    /* "id-tc26-agreement" */
+     992,    /* "id-tc26-agreement-gost-3410-2012-256" */
+     993,    /* "id-tc26-agreement-gost-3410-2012-512" */
+     977,    /* "id-tc26-algorithms" */
+     990,    /* "id-tc26-cipher" */
+    1001,    /* "id-tc26-cipher-constants" */
+     994,    /* "id-tc26-constants" */
+     981,    /* "id-tc26-digest" */
+    1000,    /* "id-tc26-digest-constants" */
+    1002,    /* "id-tc26-gost-28147-constants" */
+     996,    /* "id-tc26-gost-3410-2012-512-constants" */
+     987,    /* "id-tc26-mac" */
+     978,    /* "id-tc26-sign" */
+     995,    /* "id-tc26-sign-constants" */
+     984,    /* "id-tc26-signwithdigest" */
+      34,    /* "idea-cbc" */
+      35,    /* "idea-cfb" */
+      36,    /* "idea-ecb" */
+      46,    /* "idea-ofb" */
+     676,    /* "identified-organization" */
+     461,    /* "info" */
+     101,    /* "initials" */
+     869,    /* "internationaliSDNNumber" */
+    1022,    /* "ipsec Internet Key Exchange" */
+     749,    /* "ipsec3" */
+     750,    /* "ipsec4" */
+     181,    /* "iso" */
+     623,    /* "issuer capabilities" */
+     645,    /* "itu-t" */
+     492,    /* "janetMailbox" */
+     646,    /* "joint-iso-itu-t" */
+     957,    /* "jurisdictionCountryName" */
+     955,    /* "jurisdictionLocalityName" */
+     956,    /* "jurisdictionStateOrProvinceName" */
+     150,    /* "keyBag" */
+     773,    /* "kisa" */
+    1039,    /* "kx-dhe" */
+    1041,    /* "kx-dhe-psk" */
+    1038,    /* "kx-ecdhe" */
+    1040,    /* "kx-ecdhe-psk" */
+    1045,    /* "kx-gost" */
+    1043,    /* "kx-psk" */
+    1037,    /* "kx-rsa" */
+    1042,    /* "kx-rsa-psk" */
+    1044,    /* "kx-srp" */
+     477,    /* "lastModifiedBy" */
+     476,    /* "lastModifiedTime" */
+     157,    /* "localKeyID" */
+      15,    /* "localityName" */
+     480,    /* "mXRecord" */
+     493,    /* "mailPreferenceOption" */
+     467,    /* "manager" */
+       3,    /* "md2" */
+       7,    /* "md2WithRSAEncryption" */
+     257,    /* "md4" */
+     396,    /* "md4WithRSAEncryption" */
+       4,    /* "md5" */
+     114,    /* "md5-sha1" */
+     104,    /* "md5WithRSA" */
+       8,    /* "md5WithRSAEncryption" */
+      95,    /* "mdc2" */
+      96,    /* "mdc2WithRSA" */
+     875,    /* "member" */
+     602,    /* "merchant initiated auth" */
+     514,    /* "message extensions" */
+      51,    /* "messageDigest" */
+     911,    /* "mgf1" */
+     506,    /* "mime-mhs-bodies" */
+     505,    /* "mime-mhs-headings" */
+     488,    /* "mobileTelephoneNumber" */
+     481,    /* "nSRecord" */
+     173,    /* "name" */
+     681,    /* "onBasis" */
+     379,    /* "org" */
+      17,    /* "organizationName" */
+     491,    /* "organizationalStatus" */
+      18,    /* "organizationalUnitName" */
+     475,    /* "otherMailbox" */
+     876,    /* "owner" */
+     935,    /* "pSpecified" */
+     489,    /* "pagerTelephoneNumber" */
+     782,    /* "password based MAC" */
+     374,    /* "path" */
+     621,    /* "payment gateway capabilities" */
+       9,    /* "pbeWithMD2AndDES-CBC" */
+     168,    /* "pbeWithMD2AndRC2-CBC" */
+     112,    /* "pbeWithMD5AndCast5CBC" */
+      10,    /* "pbeWithMD5AndDES-CBC" */
+     169,    /* "pbeWithMD5AndRC2-CBC" */
+     148,    /* "pbeWithSHA1And128BitRC2-CBC" */
+     144,    /* "pbeWithSHA1And128BitRC4" */
+     147,    /* "pbeWithSHA1And2-KeyTripleDES-CBC" */
+     146,    /* "pbeWithSHA1And3-KeyTripleDES-CBC" */
+     149,    /* "pbeWithSHA1And40BitRC2-CBC" */
+     145,    /* "pbeWithSHA1And40BitRC4" */
+     170,    /* "pbeWithSHA1AndDES-CBC" */
+      68,    /* "pbeWithSHA1AndRC2-CBC" */
+     499,    /* "personalSignature" */
+     487,    /* "personalTitle" */
+     464,    /* "photo" */
+     863,    /* "physicalDeliveryOfficeName" */
+     437,    /* "pilot" */
+     439,    /* "pilotAttributeSyntax" */
+     438,    /* "pilotAttributeType" */
+     479,    /* "pilotAttributeType27" */
+     456,    /* "pilotDSA" */
+     441,    /* "pilotGroups" */
+     444,    /* "pilotObject" */
+     440,    /* "pilotObjectClass" */
+     455,    /* "pilotOrganization" */
+     445,    /* "pilotPerson" */
+     186,    /* "pkcs1" */
+      27,    /* "pkcs3" */
+     187,    /* "pkcs5" */
+      20,    /* "pkcs7" */
+      21,    /* "pkcs7-data" */
+      25,    /* "pkcs7-digestData" */
+      26,    /* "pkcs7-encryptedData" */
+      23,    /* "pkcs7-envelopedData" */
+      24,    /* "pkcs7-signedAndEnvelopedData" */
+      22,    /* "pkcs7-signedData" */
+     151,    /* "pkcs8ShroudedKeyBag" */
+      47,    /* "pkcs9" */
+     862,    /* "postOfficeBox" */
+     861,    /* "postalAddress" */
+     661,    /* "postalCode" */
+     683,    /* "ppBasis" */
+     872,    /* "preferredDeliveryMethod" */
+     873,    /* "presentationAddress" */
+     406,    /* "prime-field" */
+     409,    /* "prime192v1" */
+     410,    /* "prime192v2" */
+     411,    /* "prime192v3" */
+     412,    /* "prime239v1" */
+     413,    /* "prime239v2" */
+     414,    /* "prime239v3" */
+     415,    /* "prime256v1" */
+     886,    /* "protocolInformation" */
+     510,    /* "pseudonym" */
+     435,    /* "pss" */
+     286,    /* "qcStatements" */
+     457,    /* "qualityLabelledData" */
+     450,    /* "rFC822localPart" */
+      98,    /* "rc2-40-cbc" */
+     166,    /* "rc2-64-cbc" */
+      37,    /* "rc2-cbc" */
+      39,    /* "rc2-cfb" */
+      38,    /* "rc2-ecb" */
+      40,    /* "rc2-ofb" */
+       5,    /* "rc4" */
+      97,    /* "rc4-40" */
+     915,    /* "rc4-hmac-md5" */
+     120,    /* "rc5-cbc" */
+     122,    /* "rc5-cfb" */
+     121,    /* "rc5-ecb" */
+     123,    /* "rc5-ofb" */
+     870,    /* "registeredAddress" */
+     460,    /* "rfc822Mailbox" */
+     117,    /* "ripemd160" */
+     119,    /* "ripemd160WithRSA" */
+     400,    /* "role" */
+     877,    /* "roleOccupant" */
+     448,    /* "room" */
+     463,    /* "roomNumber" */
+      19,    /* "rsa" */
+       6,    /* "rsaEncryption" */
+     644,    /* "rsaOAEPEncryptionSET" */
+     377,    /* "rsaSignature" */
+     919,    /* "rsaesOaep" */
+     912,    /* "rsassaPss" */
+     482,    /* "sOARecord" */
+     155,    /* "safeContentsBag" */
+     291,    /* "sbgp-autonomousSysNum" */
+     290,    /* "sbgp-ipAddrBlock" */
+     292,    /* "sbgp-routerIdentifier" */
+     159,    /* "sdsiCertificate" */
+     859,    /* "searchGuide" */
+     704,    /* "secp112r1" */
+     705,    /* "secp112r2" */
+     706,    /* "secp128r1" */
+     707,    /* "secp128r2" */
+     708,    /* "secp160k1" */
+     709,    /* "secp160r1" */
+     710,    /* "secp160r2" */
+     711,    /* "secp192k1" */
+     712,    /* "secp224k1" */
+     713,    /* "secp224r1" */
+     714,    /* "secp256k1" */
+     715,    /* "secp384r1" */
+     716,    /* "secp521r1" */
+     154,    /* "secretBag" */
+     474,    /* "secretary" */
+     717,    /* "sect113r1" */
+     718,    /* "sect113r2" */
+     719,    /* "sect131r1" */
+     720,    /* "sect131r2" */
+     721,    /* "sect163k1" */
+     722,    /* "sect163r1" */
+     723,    /* "sect163r2" */
+     724,    /* "sect193r1" */
+     725,    /* "sect193r2" */
+     726,    /* "sect233k1" */
+     727,    /* "sect233r1" */
+     728,    /* "sect239k1" */
+     729,    /* "sect283k1" */
+     730,    /* "sect283r1" */
+     731,    /* "sect409k1" */
+     732,    /* "sect409r1" */
+     733,    /* "sect571k1" */
+     734,    /* "sect571r1" */
+     635,    /* "secure device signature" */
+     878,    /* "seeAlso" */
+     777,    /* "seed-cbc" */
+     779,    /* "seed-cfb" */
+     776,    /* "seed-ecb" */
+     778,    /* "seed-ofb" */
+     105,    /* "serialNumber" */
+     625,    /* "set-addPolicy" */
+     515,    /* "set-attr" */
+     518,    /* "set-brand" */
+     638,    /* "set-brand-AmericanExpress" */
+     637,    /* "set-brand-Diners" */
+     636,    /* "set-brand-IATA-ATA" */
+     639,    /* "set-brand-JCB" */
+     641,    /* "set-brand-MasterCard" */
+     642,    /* "set-brand-Novus" */
+     640,    /* "set-brand-Visa" */
+     516,    /* "set-policy" */
+     607,    /* "set-policy-root" */
+     624,    /* "set-rootKeyThumb" */
+     620,    /* "setAttr-Cert" */
+     628,    /* "setAttr-IssCap-CVM" */
+     630,    /* "setAttr-IssCap-Sig" */
+     629,    /* "setAttr-IssCap-T2" */
+     627,    /* "setAttr-Token-B0Prime" */
+     626,    /* "setAttr-Token-EMV" */
+     622,    /* "setAttr-TokenType" */
+     619,    /* "setCext-IssuerCapabilities" */
+     615,    /* "setCext-PGWYcapabilities" */
+     616,    /* "setCext-TokenIdentifier" */
+     618,    /* "setCext-TokenType" */
+     617,    /* "setCext-Track2Data" */
+     611,    /* "setCext-cCertRequired" */
+     609,    /* "setCext-certType" */
+     608,    /* "setCext-hashedRoot" */
+     610,    /* "setCext-merchData" */
+     613,    /* "setCext-setExt" */
+     614,    /* "setCext-setQualf" */
+     612,    /* "setCext-tunneling" */
+     540,    /* "setct-AcqCardCodeMsg" */
+     576,    /* "setct-AcqCardCodeMsgTBE" */
+     570,    /* "setct-AuthReqTBE" */
+     534,    /* "setct-AuthReqTBS" */
+     527,    /* "setct-AuthResBaggage" */
+     571,    /* "setct-AuthResTBE" */
+     572,    /* "setct-AuthResTBEX" */
+     535,    /* "setct-AuthResTBS" */
+     536,    /* "setct-AuthResTBSX" */
+     528,    /* "setct-AuthRevReqBaggage" */
+     577,    /* "setct-AuthRevReqTBE" */
+     541,    /* "setct-AuthRevReqTBS" */
+     529,    /* "setct-AuthRevResBaggage" */
+     542,    /* "setct-AuthRevResData" */
+     578,    /* "setct-AuthRevResTBE" */
+     579,    /* "setct-AuthRevResTBEB" */
+     543,    /* "setct-AuthRevResTBS" */
+     573,    /* "setct-AuthTokenTBE" */
+     537,    /* "setct-AuthTokenTBS" */
+     600,    /* "setct-BCIDistributionTBS" */
+     558,    /* "setct-BatchAdminReqData" */
+     592,    /* "setct-BatchAdminReqTBE" */
+     559,    /* "setct-BatchAdminResData" */
+     593,    /* "setct-BatchAdminResTBE" */
+     599,    /* "setct-CRLNotificationResTBS" */
+     598,    /* "setct-CRLNotificationTBS" */
+     580,    /* "setct-CapReqTBE" */
+     581,    /* "setct-CapReqTBEX" */
+     544,    /* "setct-CapReqTBS" */
+     545,    /* "setct-CapReqTBSX" */
+     546,    /* "setct-CapResData" */
+     582,    /* "setct-CapResTBE" */
+     583,    /* "setct-CapRevReqTBE" */
+     584,    /* "setct-CapRevReqTBEX" */
+     547,    /* "setct-CapRevReqTBS" */
+     548,    /* "setct-CapRevReqTBSX" */
+     549,    /* "setct-CapRevResData" */
+     585,    /* "setct-CapRevResTBE" */
+     538,    /* "setct-CapTokenData" */
+     530,    /* "setct-CapTokenSeq" */
+     574,    /* "setct-CapTokenTBE" */
+     575,    /* "setct-CapTokenTBEX" */
+     539,    /* "setct-CapTokenTBS" */
+     560,    /* "setct-CardCInitResTBS" */
+     566,    /* "setct-CertInqReqTBS" */
+     563,    /* "setct-CertReqData" */
+     595,    /* "setct-CertReqTBE" */
+     596,    /* "setct-CertReqTBEX" */
+     564,    /* "setct-CertReqTBS" */
+     565,    /* "setct-CertResData" */
+     597,    /* "setct-CertResTBE" */
+     586,    /* "setct-CredReqTBE" */
+     587,    /* "setct-CredReqTBEX" */
+     550,    /* "setct-CredReqTBS" */
+     551,    /* "setct-CredReqTBSX" */
+     552,    /* "setct-CredResData" */
+     588,    /* "setct-CredResTBE" */
+     589,    /* "setct-CredRevReqTBE" */
+     590,    /* "setct-CredRevReqTBEX" */
+     553,    /* "setct-CredRevReqTBS" */
+     554,    /* "setct-CredRevReqTBSX" */
+     555,    /* "setct-CredRevResData" */
+     591,    /* "setct-CredRevResTBE" */
+     567,    /* "setct-ErrorTBS" */
+     526,    /* "setct-HODInput" */
+     561,    /* "setct-MeAqCInitResTBS" */
+     522,    /* "setct-OIData" */
+     519,    /* "setct-PANData" */
+     521,    /* "setct-PANOnly" */
+     520,    /* "setct-PANToken" */
+     556,    /* "setct-PCertReqData" */
+     557,    /* "setct-PCertResTBS" */
+     523,    /* "setct-PI" */
+     532,    /* "setct-PI-TBS" */
+     524,    /* "setct-PIData" */
+     525,    /* "setct-PIDataUnsigned" */
+     568,    /* "setct-PIDualSignedTBE" */
+     569,    /* "setct-PIUnsignedTBE" */
+     531,    /* "setct-PInitResData" */
+     533,    /* "setct-PResData" */
+     594,    /* "setct-RegFormReqTBE" */
+     562,    /* "setct-RegFormResTBS" */
+     604,    /* "setext-pinAny" */
+     603,    /* "setext-pinSecure" */
+     605,    /* "setext-track2" */
+      41,    /* "sha" */
+      64,    /* "sha1" */
+     115,    /* "sha1WithRSA" */
+      65,    /* "sha1WithRSAEncryption" */
+     675,    /* "sha224" */
+     671,    /* "sha224WithRSAEncryption" */
+     672,    /* "sha256" */
+     668,    /* "sha256WithRSAEncryption" */
+     673,    /* "sha384" */
+     669,    /* "sha384WithRSAEncryption" */
+     674,    /* "sha512" */
+     670,    /* "sha512WithRSAEncryption" */
+      42,    /* "shaWithRSAEncryption" */
+      52,    /* "signingTime" */
+     454,    /* "simpleSecurityObject" */
+     496,    /* "singleLevelQuality" */
+      16,    /* "stateOrProvinceName" */
+     660,    /* "streetAddress" */
+     498,    /* "subtreeMaximumQuality" */
+     497,    /* "subtreeMinimumQuality" */
+     890,    /* "supportedAlgorithms" */
+     874,    /* "supportedApplicationContext" */
+     100,    /* "surname" */
+     864,    /* "telephoneNumber" */
+     866,    /* "teletexTerminalIdentifier" */
+     865,    /* "telexNumber" */
+     459,    /* "textEncodedORAddress" */
+     293,    /* "textNotice" */
+     106,    /* "title" */
+    1021,    /* "tls1-prf" */
+     682,    /* "tpBasis" */
+     436,    /* "ucl" */
+       0,    /* "undefined" */
+     102,    /* "uniqueIdentifier" */
+     888,    /* "uniqueMember" */
+      55,    /* "unstructuredAddress" */
+      49,    /* "unstructuredName" */
+     880,    /* "userCertificate" */
+     465,    /* "userClass" */
+     458,    /* "userId" */
+     879,    /* "userPassword" */
+     373,    /* "valid" */
+     678,    /* "wap" */
+     679,    /* "wap-wsg" */
+     735,    /* "wap-wsg-idm-ecid-wtls1" */
+     743,    /* "wap-wsg-idm-ecid-wtls10" */
+     744,    /* "wap-wsg-idm-ecid-wtls11" */
+     745,    /* "wap-wsg-idm-ecid-wtls12" */
+     736,    /* "wap-wsg-idm-ecid-wtls3" */
+     737,    /* "wap-wsg-idm-ecid-wtls4" */
+     738,    /* "wap-wsg-idm-ecid-wtls5" */
+     739,    /* "wap-wsg-idm-ecid-wtls6" */
+     740,    /* "wap-wsg-idm-ecid-wtls7" */
+     741,    /* "wap-wsg-idm-ecid-wtls8" */
+     742,    /* "wap-wsg-idm-ecid-wtls9" */
+     804,    /* "whirlpool" */
+     868,    /* "x121Address" */
+     503,    /* "x500UniqueIdentifier" */
+     158,    /* "x509Certificate" */
+     160,    /* "x509Crl" */
+     125,    /* "zlib compression" */
+};
+
+#define NUM_OBJ 956
+static const unsigned int obj_objs[NUM_OBJ] = {
+       0,    /* OBJ_undef                        0 */
+     181,    /* OBJ_iso                          1 */
+     393,    /* OBJ_joint_iso_ccitt              OBJ_joint_iso_itu_t */
+     404,    /* OBJ_ccitt                        OBJ_itu_t */
+     645,    /* OBJ_itu_t                        0 */
+     646,    /* OBJ_joint_iso_itu_t              2 */
+     434,    /* OBJ_data                         0 9 */
+     182,    /* OBJ_member_body                  1 2 */
+     379,    /* OBJ_org                          1 3 */
+     676,    /* OBJ_identified_organization      1 3 */
+      11,    /* OBJ_X500                         2 5 */
+     647,    /* OBJ_international_organizations  2 23 */
+     380,    /* OBJ_dod                          1 3 6 */
+      12,    /* OBJ_X509                         2 5 4 */
+     378,    /* OBJ_X500algorithms               2 5 8 */
+      81,    /* OBJ_id_ce                        2 5 29 */
+     512,    /* OBJ_id_set                       2 23 42 */
+     678,    /* OBJ_wap                          2 23 43 */
+     435,    /* OBJ_pss                          0 9 2342 */
+     183,    /* OBJ_ISO_US                       1 2 840 */
+     381,    /* OBJ_iana                         1 3 6 1 */
+    1034,    /* OBJ_X25519                       1 3 101 110 */
+    1035,    /* OBJ_X448                         1 3 101 111 */
+     677,    /* OBJ_certicom_arc                 1 3 132 */
+     394,    /* OBJ_selected_attribute_types     2 5 1 5 */
+      13,    /* OBJ_commonName                   2 5 4 3 */
+     100,    /* OBJ_surname                      2 5 4 4 */
+     105,    /* OBJ_serialNumber                 2 5 4 5 */
+      14,    /* OBJ_countryName                  2 5 4 6 */
+      15,    /* OBJ_localityName                 2 5 4 7 */
+      16,    /* OBJ_stateOrProvinceName          2 5 4 8 */
+     660,    /* OBJ_streetAddress                2 5 4 9 */
+      17,    /* OBJ_organizationName             2 5 4 10 */
+      18,    /* OBJ_organizationalUnitName       2 5 4 11 */
+     106,    /* OBJ_title                        2 5 4 12 */
+     107,    /* OBJ_description                  2 5 4 13 */
+     859,    /* OBJ_searchGuide                  2 5 4 14 */
+     860,    /* OBJ_businessCategory             2 5 4 15 */
+     861,    /* OBJ_postalAddress                2 5 4 16 */
+     661,    /* OBJ_postalCode                   2 5 4 17 */
+     862,    /* OBJ_postOfficeBox                2 5 4 18 */
+     863,    /* OBJ_physicalDeliveryOfficeName   2 5 4 19 */
+     864,    /* OBJ_telephoneNumber              2 5 4 20 */
+     865,    /* OBJ_telexNumber                  2 5 4 21 */
+     866,    /* OBJ_teletexTerminalIdentifier    2 5 4 22 */
+     867,    /* OBJ_facsimileTelephoneNumber     2 5 4 23 */
+     868,    /* OBJ_x121Address                  2 5 4 24 */
+     869,    /* OBJ_internationaliSDNNumber      2 5 4 25 */
+     870,    /* OBJ_registeredAddress            2 5 4 26 */
+     871,    /* OBJ_destinationIndicator         2 5 4 27 */
+     872,    /* OBJ_preferredDeliveryMethod      2 5 4 28 */
+     873,    /* OBJ_presentationAddress          2 5 4 29 */
+     874,    /* OBJ_supportedApplicationContext  2 5 4 30 */
+     875,    /* OBJ_member                       2 5 4 31 */
+     876,    /* OBJ_owner                        2 5 4 32 */
+     877,    /* OBJ_roleOccupant                 2 5 4 33 */
+     878,    /* OBJ_seeAlso                      2 5 4 34 */
+     879,    /* OBJ_userPassword                 2 5 4 35 */
+     880,    /* OBJ_userCertificate              2 5 4 36 */
+     881,    /* OBJ_cACertificate                2 5 4 37 */
+     882,    /* OBJ_authorityRevocationList      2 5 4 38 */
+     883,    /* OBJ_certificateRevocationList    2 5 4 39 */
+     884,    /* OBJ_crossCertificatePair         2 5 4 40 */
+     173,    /* OBJ_name                         2 5 4 41 */
+      99,    /* OBJ_givenName                    2 5 4 42 */
+     101,    /* OBJ_initials                     2 5 4 43 */
+     509,    /* OBJ_generationQualifier          2 5 4 44 */
+     503,    /* OBJ_x500UniqueIdentifier         2 5 4 45 */
+     174,    /* OBJ_dnQualifier                  2 5 4 46 */
+     885,    /* OBJ_enhancedSearchGuide          2 5 4 47 */
+     886,    /* OBJ_protocolInformation          2 5 4 48 */
+     887,    /* OBJ_distinguishedName            2 5 4 49 */
+     888,    /* OBJ_uniqueMember                 2 5 4 50 */
+     889,    /* OBJ_houseIdentifier              2 5 4 51 */
+     890,    /* OBJ_supportedAlgorithms          2 5 4 52 */
+     891,    /* OBJ_deltaRevocationList          2 5 4 53 */
+     892,    /* OBJ_dmdName                      2 5 4 54 */
+     510,    /* OBJ_pseudonym                    2 5 4 65 */
+     400,    /* OBJ_role                         2 5 4 72 */
+     769,    /* OBJ_subject_directory_attributes 2 5 29 9 */
+      82,    /* OBJ_subject_key_identifier       2 5 29 14 */
+      83,    /* OBJ_key_usage                    2 5 29 15 */
+      84,    /* OBJ_private_key_usage_period     2 5 29 16 */
+      85,    /* OBJ_subject_alt_name             2 5 29 17 */
+      86,    /* OBJ_issuer_alt_name              2 5 29 18 */
+      87,    /* OBJ_basic_constraints            2 5 29 19 */
+      88,    /* OBJ_crl_number                   2 5 29 20 */
+     141,    /* OBJ_crl_reason                   2 5 29 21 */
+     430,    /* OBJ_hold_instruction_code        2 5 29 23 */
+     142,    /* OBJ_invalidity_date              2 5 29 24 */
+     140,    /* OBJ_delta_crl                    2 5 29 27 */
+     770,    /* OBJ_issuing_distribution_point   2 5 29 28 */
+     771,    /* OBJ_certificate_issuer           2 5 29 29 */
+     666,    /* OBJ_name_constraints             2 5 29 30 */
+     103,    /* OBJ_crl_distribution_points      2 5 29 31 */
+      89,    /* OBJ_certificate_policies         2 5 29 32 */
+     747,    /* OBJ_policy_mappings              2 5 29 33 */
+      90,    /* OBJ_authority_key_identifier     2 5 29 35 */
+     401,    /* OBJ_policy_constraints           2 5 29 36 */
+     126,    /* OBJ_ext_key_usage                2 5 29 37 */
+     857,    /* OBJ_freshest_crl                 2 5 29 46 */
+     748,    /* OBJ_inhibit_any_policy           2 5 29 54 */
+     402,    /* OBJ_target_information           2 5 29 55 */
+     403,    /* OBJ_no_rev_avail                 2 5 29 56 */
+     513,    /* OBJ_set_ctype                    2 23 42 0 */
+     514,    /* OBJ_set_msgExt                   2 23 42 1 */
+     515,    /* OBJ_set_attr                     2 23 42 3 */
+     516,    /* OBJ_set_policy                   2 23 42 5 */
+     517,    /* OBJ_set_certExt                  2 23 42 7 */
+     518,    /* OBJ_set_brand                    2 23 42 8 */
+     679,    /* OBJ_wap_wsg                      2 23 43 1 */
+     382,    /* OBJ_Directory                    1 3 6 1 1 */
+     383,    /* OBJ_Management                   1 3 6 1 2 */
+     384,    /* OBJ_Experimental                 1 3 6 1 3 */
+     385,    /* OBJ_Private                      1 3 6 1 4 */
+     386,    /* OBJ_Security                     1 3 6 1 5 */
+     387,    /* OBJ_SNMPv2                       1 3 6 1 6 */
+     388,    /* OBJ_Mail                         1 3 6 1 7 */
+     376,    /* OBJ_algorithm                    1 3 14 3 2 */
+     395,    /* OBJ_clearance                    2 5 1 5 55 */
+      19,    /* OBJ_rsa                          2 5 8 1 1 */
+      96,    /* OBJ_mdc2WithRSA                  2 5 8 3 100 */
+      95,    /* OBJ_mdc2                         2 5 8 3 101 */
+     746,    /* OBJ_any_policy                   2 5 29 32 0 */
+     910,    /* OBJ_anyExtendedKeyUsage          2 5 29 37 0 */
+     519,    /* OBJ_setct_PANData                2 23 42 0 0 */
+     520,    /* OBJ_setct_PANToken               2 23 42 0 1 */
+     521,    /* OBJ_setct_PANOnly                2 23 42 0 2 */
+     522,    /* OBJ_setct_OIData                 2 23 42 0 3 */
+     523,    /* OBJ_setct_PI                     2 23 42 0 4 */
+     524,    /* OBJ_setct_PIData                 2 23 42 0 5 */
+     525,    /* OBJ_setct_PIDataUnsigned         2 23 42 0 6 */
+     526,    /* OBJ_setct_HODInput               2 23 42 0 7 */
+     527,    /* OBJ_setct_AuthResBaggage         2 23 42 0 8 */
+     528,    /* OBJ_setct_AuthRevReqBaggage      2 23 42 0 9 */
+     529,    /* OBJ_setct_AuthRevResBaggage      2 23 42 0 10 */
+     530,    /* OBJ_setct_CapTokenSeq            2 23 42 0 11 */
+     531,    /* OBJ_setct_PInitResData           2 23 42 0 12 */
+     532,    /* OBJ_setct_PI_TBS                 2 23 42 0 13 */
+     533,    /* OBJ_setct_PResData               2 23 42 0 14 */
+     534,    /* OBJ_setct_AuthReqTBS             2 23 42 0 16 */
+     535,    /* OBJ_setct_AuthResTBS             2 23 42 0 17 */
+     536,    /* OBJ_setct_AuthResTBSX            2 23 42 0 18 */
+     537,    /* OBJ_setct_AuthTokenTBS           2 23 42 0 19 */
+     538,    /* OBJ_setct_CapTokenData           2 23 42 0 20 */
+     539,    /* OBJ_setct_CapTokenTBS            2 23 42 0 21 */
+     540,    /* OBJ_setct_AcqCardCodeMsg         2 23 42 0 22 */
+     541,    /* OBJ_setct_AuthRevReqTBS          2 23 42 0 23 */
+     542,    /* OBJ_setct_AuthRevResData         2 23 42 0 24 */
+     543,    /* OBJ_setct_AuthRevResTBS          2 23 42 0 25 */
+     544,    /* OBJ_setct_CapReqTBS              2 23 42 0 26 */
+     545,    /* OBJ_setct_CapReqTBSX             2 23 42 0 27 */
+     546,    /* OBJ_setct_CapResData             2 23 42 0 28 */
+     547,    /* OBJ_setct_CapRevReqTBS           2 23 42 0 29 */
+     548,    /* OBJ_setct_CapRevReqTBSX          2 23 42 0 30 */
+     549,    /* OBJ_setct_CapRevResData          2 23 42 0 31 */
+     550,    /* OBJ_setct_CredReqTBS             2 23 42 0 32 */
+     551,    /* OBJ_setct_CredReqTBSX            2 23 42 0 33 */
+     552,    /* OBJ_setct_CredResData            2 23 42 0 34 */
+     553,    /* OBJ_setct_CredRevReqTBS          2 23 42 0 35 */
+     554,    /* OBJ_setct_CredRevReqTBSX         2 23 42 0 36 */
+     555,    /* OBJ_setct_CredRevResData         2 23 42 0 37 */
+     556,    /* OBJ_setct_PCertReqData           2 23 42 0 38 */
+     557,    /* OBJ_setct_PCertResTBS            2 23 42 0 39 */
+     558,    /* OBJ_setct_BatchAdminReqData      2 23 42 0 40 */
+     559,    /* OBJ_setct_BatchAdminResData      2 23 42 0 41 */
+     560,    /* OBJ_setct_CardCInitResTBS        2 23 42 0 42 */
+     561,    /* OBJ_setct_MeAqCInitResTBS        2 23 42 0 43 */
+     562,    /* OBJ_setct_RegFormResTBS          2 23 42 0 44 */
+     563,    /* OBJ_setct_CertReqData            2 23 42 0 45 */
+     564,    /* OBJ_setct_CertReqTBS             2 23 42 0 46 */
+     565,    /* OBJ_setct_CertResData            2 23 42 0 47 */
+     566,    /* OBJ_setct_CertInqReqTBS          2 23 42 0 48 */
+     567,    /* OBJ_setct_ErrorTBS               2 23 42 0 49 */
+     568,    /* OBJ_setct_PIDualSignedTBE        2 23 42 0 50 */
+     569,    /* OBJ_setct_PIUnsignedTBE          2 23 42 0 51 */
+     570,    /* OBJ_setct_AuthReqTBE             2 23 42 0 52 */
+     571,    /* OBJ_setct_AuthResTBE             2 23 42 0 53 */
+     572,    /* OBJ_setct_AuthResTBEX            2 23 42 0 54 */
+     573,    /* OBJ_setct_AuthTokenTBE           2 23 42 0 55 */
+     574,    /* OBJ_setct_CapTokenTBE            2 23 42 0 56 */
+     575,    /* OBJ_setct_CapTokenTBEX           2 23 42 0 57 */
+     576,    /* OBJ_setct_AcqCardCodeMsgTBE      2 23 42 0 58 */
+     577,    /* OBJ_setct_AuthRevReqTBE          2 23 42 0 59 */
+     578,    /* OBJ_setct_AuthRevResTBE          2 23 42 0 60 */
+     579,    /* OBJ_setct_AuthRevResTBEB         2 23 42 0 61 */
+     580,    /* OBJ_setct_CapReqTBE              2 23 42 0 62 */
+     581,    /* OBJ_setct_CapReqTBEX             2 23 42 0 63 */
+     582,    /* OBJ_setct_CapResTBE              2 23 42 0 64 */
+     583,    /* OBJ_setct_CapRevReqTBE           2 23 42 0 65 */
+     584,    /* OBJ_setct_CapRevReqTBEX          2 23 42 0 66 */
+     585,    /* OBJ_setct_CapRevResTBE           2 23 42 0 67 */
+     586,    /* OBJ_setct_CredReqTBE             2 23 42 0 68 */
+     587,    /* OBJ_setct_CredReqTBEX            2 23 42 0 69 */
+     588,    /* OBJ_setct_CredResTBE             2 23 42 0 70 */
+     589,    /* OBJ_setct_CredRevReqTBE          2 23 42 0 71 */
+     590,    /* OBJ_setct_CredRevReqTBEX         2 23 42 0 72 */
+     591,    /* OBJ_setct_CredRevResTBE          2 23 42 0 73 */
+     592,    /* OBJ_setct_BatchAdminReqTBE       2 23 42 0 74 */
+     593,    /* OBJ_setct_BatchAdminResTBE       2 23 42 0 75 */
+     594,    /* OBJ_setct_RegFormReqTBE          2 23 42 0 76 */
+     595,    /* OBJ_setct_CertReqTBE             2 23 42 0 77 */
+     596,    /* OBJ_setct_CertReqTBEX            2 23 42 0 78 */
+     597,    /* OBJ_setct_CertResTBE             2 23 42 0 79 */
+     598,    /* OBJ_setct_CRLNotificationTBS     2 23 42 0 80 */
+     599,    /* OBJ_setct_CRLNotificationResTBS  2 23 42 0 81 */
+     600,    /* OBJ_setct_BCIDistributionTBS     2 23 42 0 82 */
+     601,    /* OBJ_setext_genCrypt              2 23 42 1 1 */
+     602,    /* OBJ_setext_miAuth                2 23 42 1 3 */
+     603,    /* OBJ_setext_pinSecure             2 23 42 1 4 */
+     604,    /* OBJ_setext_pinAny                2 23 42 1 5 */
+     605,    /* OBJ_setext_track2                2 23 42 1 7 */
+     606,    /* OBJ_setext_cv                    2 23 42 1 8 */
+     620,    /* OBJ_setAttr_Cert                 2 23 42 3 0 */
+     621,    /* OBJ_setAttr_PGWYcap              2 23 42 3 1 */
+     622,    /* OBJ_setAttr_TokenType            2 23 42 3 2 */
+     623,    /* OBJ_setAttr_IssCap               2 23 42 3 3 */
+     607,    /* OBJ_set_policy_root              2 23 42 5 0 */
+     608,    /* OBJ_setCext_hashedRoot           2 23 42 7 0 */
+     609,    /* OBJ_setCext_certType             2 23 42 7 1 */
+     610,    /* OBJ_setCext_merchData            2 23 42 7 2 */
+     611,    /* OBJ_setCext_cCertRequired        2 23 42 7 3 */
+     612,    /* OBJ_setCext_tunneling            2 23 42 7 4 */
+     613,    /* OBJ_setCext_setExt               2 23 42 7 5 */
+     614,    /* OBJ_setCext_setQualf             2 23 42 7 6 */
+     615,    /* OBJ_setCext_PGWYcapabilities     2 23 42 7 7 */
+     616,    /* OBJ_setCext_TokenIdentifier      2 23 42 7 8 */
+     617,    /* OBJ_setCext_Track2Data           2 23 42 7 9 */
+     618,    /* OBJ_setCext_TokenType            2 23 42 7 10 */
+     619,    /* OBJ_setCext_IssuerCapabilities   2 23 42 7 11 */
+     636,    /* OBJ_set_brand_IATA_ATA           2 23 42 8 1 */
+     640,    /* OBJ_set_brand_Visa               2 23 42 8 4 */
+     641,    /* OBJ_set_brand_MasterCard         2 23 42 8 5 */
+     637,    /* OBJ_set_brand_Diners             2 23 42 8 30 */
+     638,    /* OBJ_set_brand_AmericanExpress    2 23 42 8 34 */
+     639,    /* OBJ_set_brand_JCB                2 23 42 8 35 */
+     805,    /* OBJ_cryptopro                    1 2 643 2 2 */
+     806,    /* OBJ_cryptocom                    1 2 643 2 9 */
+     974,    /* OBJ_id_tc26                      1 2 643 7 1 */
+    1005,    /* OBJ_OGRN                         1 2 643 100 1 */
+    1006,    /* OBJ_SNILS                        1 2 643 100 3 */
+    1007,    /* OBJ_subjectSignTool              1 2 643 100 111 */
+    1008,    /* OBJ_issuerSignTool               1 2 643 100 112 */
+     184,    /* OBJ_X9_57                        1 2 840 10040 */
+     405,    /* OBJ_ansi_X9_62                   1 2 840 10045 */
+     389,    /* OBJ_Enterprises                  1 3 6 1 4 1 */
+     504,    /* OBJ_mime_mhs                     1 3 6 1 7 1 */
+     104,    /* OBJ_md5WithRSA                   1 3 14 3 2 3 */
+      29,    /* OBJ_des_ecb                      1 3 14 3 2 6 */
+      31,    /* OBJ_des_cbc                      1 3 14 3 2 7 */
+      45,    /* OBJ_des_ofb64                    1 3 14 3 2 8 */
+      30,    /* OBJ_des_cfb64                    1 3 14 3 2 9 */
+     377,    /* OBJ_rsaSignature                 1 3 14 3 2 11 */
+      67,    /* OBJ_dsa_2                        1 3 14 3 2 12 */
+      66,    /* OBJ_dsaWithSHA                   1 3 14 3 2 13 */
+      42,    /* OBJ_shaWithRSAEncryption         1 3 14 3 2 15 */
+      32,    /* OBJ_des_ede_ecb                  1 3 14 3 2 17 */
+      41,    /* OBJ_sha                          1 3 14 3 2 18 */
+      64,    /* OBJ_sha1                         1 3 14 3 2 26 */
+      70,    /* OBJ_dsaWithSHA1_2                1 3 14 3 2 27 */
+     115,    /* OBJ_sha1WithRSA                  1 3 14 3 2 29 */
+     117,    /* OBJ_ripemd160                    1 3 36 3 2 1 */
+     143,    /* OBJ_sxnet                        1 3 101 1 4 1 */
+     721,    /* OBJ_sect163k1                    1 3 132 0 1 */
+     722,    /* OBJ_sect163r1                    1 3 132 0 2 */
+     728,    /* OBJ_sect239k1                    1 3 132 0 3 */
+     717,    /* OBJ_sect113r1                    1 3 132 0 4 */
+     718,    /* OBJ_sect113r2                    1 3 132 0 5 */
+     704,    /* OBJ_secp112r1                    1 3 132 0 6 */
+     705,    /* OBJ_secp112r2                    1 3 132 0 7 */
+     709,    /* OBJ_secp160r1                    1 3 132 0 8 */
+     708,    /* OBJ_secp160k1                    1 3 132 0 9 */
+     714,    /* OBJ_secp256k1                    1 3 132 0 10 */
+     723,    /* OBJ_sect163r2                    1 3 132 0 15 */
+     729,    /* OBJ_sect283k1                    1 3 132 0 16 */
+     730,    /* OBJ_sect283r1                    1 3 132 0 17 */
+     719,    /* OBJ_sect131r1                    1 3 132 0 22 */
+     720,    /* OBJ_sect131r2                    1 3 132 0 23 */
+     724,    /* OBJ_sect193r1                    1 3 132 0 24 */
+     725,    /* OBJ_sect193r2                    1 3 132 0 25 */
+     726,    /* OBJ_sect233k1                    1 3 132 0 26 */
+     727,    /* OBJ_sect233r1                    1 3 132 0 27 */
+     706,    /* OBJ_secp128r1                    1 3 132 0 28 */
+     707,    /* OBJ_secp128r2                    1 3 132 0 29 */
+     710,    /* OBJ_secp160r2                    1 3 132 0 30 */
+     711,    /* OBJ_secp192k1                    1 3 132 0 31 */
+     712,    /* OBJ_secp224k1                    1 3 132 0 32 */
+     713,    /* OBJ_secp224r1                    1 3 132 0 33 */
+     715,    /* OBJ_secp384r1                    1 3 132 0 34 */
+     716,    /* OBJ_secp521r1                    1 3 132 0 35 */
+     731,    /* OBJ_sect409k1                    1 3 132 0 36 */
+     732,    /* OBJ_sect409r1                    1 3 132 0 37 */
+     733,    /* OBJ_sect571k1                    1 3 132 0 38 */
+     734,    /* OBJ_sect571r1                    1 3 132 0 39 */
+     624,    /* OBJ_set_rootKeyThumb             2 23 42 3 0 0 */
+     625,    /* OBJ_set_addPolicy                2 23 42 3 0 1 */
+     626,    /* OBJ_setAttr_Token_EMV            2 23 42 3 2 1 */
+     627,    /* OBJ_setAttr_Token_B0Prime        2 23 42 3 2 2 */
+     628,    /* OBJ_setAttr_IssCap_CVM           2 23 42 3 3 3 */
+     629,    /* OBJ_setAttr_IssCap_T2            2 23 42 3 3 4 */
+     630,    /* OBJ_setAttr_IssCap_Sig           2 23 42 3 3 5 */
+     642,    /* OBJ_set_brand_Novus              2 23 42 8 6011 */
+     735,    /* OBJ_wap_wsg_idm_ecid_wtls1       2 23 43 1 4 1 */
+     736,    /* OBJ_wap_wsg_idm_ecid_wtls3       2 23 43 1 4 3 */
+     737,    /* OBJ_wap_wsg_idm_ecid_wtls4       2 23 43 1 4 4 */
+     738,    /* OBJ_wap_wsg_idm_ecid_wtls5       2 23 43 1 4 5 */
+     739,    /* OBJ_wap_wsg_idm_ecid_wtls6       2 23 43 1 4 6 */
+     740,    /* OBJ_wap_wsg_idm_ecid_wtls7       2 23 43 1 4 7 */
+     741,    /* OBJ_wap_wsg_idm_ecid_wtls8       2 23 43 1 4 8 */
+     742,    /* OBJ_wap_wsg_idm_ecid_wtls9       2 23 43 1 4 9 */
+     743,    /* OBJ_wap_wsg_idm_ecid_wtls10      2 23 43 1 4 10 */
+     744,    /* OBJ_wap_wsg_idm_ecid_wtls11      2 23 43 1 4 11 */
+     745,    /* OBJ_wap_wsg_idm_ecid_wtls12      2 23 43 1 4 12 */
+     804,    /* OBJ_whirlpool                    1 0 10118 3 0 55 */
+     773,    /* OBJ_kisa                         1 2 410 200004 */
+     807,    /* OBJ_id_GostR3411_94_with_GostR3410_2001 1 2 643 2 2 3 */
+     808,    /* OBJ_id_GostR3411_94_with_GostR3410_94 1 2 643 2 2 4 */
+     809,    /* OBJ_id_GostR3411_94              1 2 643 2 2 9 */
+     810,    /* OBJ_id_HMACGostR3411_94          1 2 643 2 2 10 */
+     811,    /* OBJ_id_GostR3410_2001            1 2 643 2 2 19 */
+     812,    /* OBJ_id_GostR3410_94              1 2 643 2 2 20 */
+     813,    /* OBJ_id_Gost28147_89              1 2 643 2 2 21 */
+     815,    /* OBJ_id_Gost28147_89_MAC          1 2 643 2 2 22 */
+     816,    /* OBJ_id_GostR3411_94_prf          1 2 643 2 2 23 */
+     817,    /* OBJ_id_GostR3410_2001DH          1 2 643 2 2 98 */
+     818,    /* OBJ_id_GostR3410_94DH            1 2 643 2 2 99 */
+     977,    /* OBJ_id_tc26_algorithms           1 2 643 7 1 1 */
+     994,    /* OBJ_id_tc26_constants            1 2 643 7 1 2 */
+       1,    /* OBJ_rsadsi                       1 2 840 113549 */
+     185,    /* OBJ_X9cm                         1 2 840 10040 4 */
+    1031,    /* OBJ_id_pkinit                    1 3 6 1 5 2 3 */
+     127,    /* OBJ_id_pkix                      1 3 6 1 5 5 7 */
+     505,    /* OBJ_mime_mhs_headings            1 3 6 1 7 1 1 */
+     506,    /* OBJ_mime_mhs_bodies              1 3 6 1 7 1 2 */
+     119,    /* OBJ_ripemd160WithRSA             1 3 36 3 3 1 2 */
+     937,    /* OBJ_dhSinglePass_stdDH_sha224kdf_scheme 1 3 132 1 11 0 */
+     938,    /* OBJ_dhSinglePass_stdDH_sha256kdf_scheme 1 3 132 1 11 1 */
+     939,    /* OBJ_dhSinglePass_stdDH_sha384kdf_scheme 1 3 132 1 11 2 */
+     940,    /* OBJ_dhSinglePass_stdDH_sha512kdf_scheme 1 3 132 1 11 3 */
+     942,    /* OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme 1 3 132 1 14 0 */
+     943,    /* OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme 1 3 132 1 14 1 */
+     944,    /* OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme 1 3 132 1 14 2 */
+     945,    /* OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme 1 3 132 1 14 3 */
+     631,    /* OBJ_setAttr_GenCryptgrm          2 23 42 3 3 3 1 */
+     632,    /* OBJ_setAttr_T2Enc                2 23 42 3 3 4 1 */
+     633,    /* OBJ_setAttr_T2cleartxt           2 23 42 3 3 4 2 */
+     634,    /* OBJ_setAttr_TokICCsig            2 23 42 3 3 5 1 */
+     635,    /* OBJ_setAttr_SecDevSig            2 23 42 3 3 5 2 */
+     436,    /* OBJ_ucl                          0 9 2342 19200300 */
+     820,    /* OBJ_id_Gost28147_89_None_KeyMeshing 1 2 643 2 2 14 0 */
+     819,    /* OBJ_id_Gost28147_89_CryptoPro_KeyMeshing 1 2 643 2 2 14 1 */
+     845,    /* OBJ_id_GostR3410_94_a            1 2 643 2 2 20 1 */
+     846,    /* OBJ_id_GostR3410_94_aBis         1 2 643 2 2 20 2 */
+     847,    /* OBJ_id_GostR3410_94_b            1 2 643 2 2 20 3 */
+     848,    /* OBJ_id_GostR3410_94_bBis         1 2 643 2 2 20 4 */
+     821,    /* OBJ_id_GostR3411_94_TestParamSet 1 2 643 2 2 30 0 */
+     822,    /* OBJ_id_GostR3411_94_CryptoProParamSet 1 2 643 2 2 30 1 */
+     823,    /* OBJ_id_Gost28147_89_TestParamSet 1 2 643 2 2 31 0 */
+     824,    /* OBJ_id_Gost28147_89_CryptoPro_A_ParamSet 1 2 643 2 2 31 1 */
+     825,    /* OBJ_id_Gost28147_89_CryptoPro_B_ParamSet 1 2 643 2 2 31 2 */
+     826,    /* OBJ_id_Gost28147_89_CryptoPro_C_ParamSet 1 2 643 2 2 31 3 */
+     827,    /* OBJ_id_Gost28147_89_CryptoPro_D_ParamSet 1 2 643 2 2 31 4 */
+     828,    /* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 1 2 643 2 2 31 5 */
+     829,    /* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 1 2 643 2 2 31 6 */
+     830,    /* OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 1 2 643 2 2 31 7 */
+     831,    /* OBJ_id_GostR3410_94_TestParamSet 1 2 643 2 2 32 0 */
+     832,    /* OBJ_id_GostR3410_94_CryptoPro_A_ParamSet 1 2 643 2 2 32 2 */
+     833,    /* OBJ_id_GostR3410_94_CryptoPro_B_ParamSet 1 2 643 2 2 32 3 */
+     834,    /* OBJ_id_GostR3410_94_CryptoPro_C_ParamSet 1 2 643 2 2 32 4 */
+     835,    /* OBJ_id_GostR3410_94_CryptoPro_D_ParamSet 1 2 643 2 2 32 5 */
+     836,    /* OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet 1 2 643 2 2 33 1 */
+     837,    /* OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet 1 2 643 2 2 33 2 */
+     838,    /* OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet 1 2 643 2 2 33 3 */
+     839,    /* OBJ_id_GostR3410_2001_TestParamSet 1 2 643 2 2 35 0 */
+     840,    /* OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet 1 2 643 2 2 35 1 */
+     841,    /* OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet 1 2 643 2 2 35 2 */
+     842,    /* OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet 1 2 643 2 2 35 3 */
+     843,    /* OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet 1 2 643 2 2 36 0 */
+     844,    /* OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet 1 2 643 2 2 36 1 */
+     978,    /* OBJ_id_tc26_sign                 1 2 643 7 1 1 1 */
+     981,    /* OBJ_id_tc26_digest               1 2 643 7 1 1 2 */
+     984,    /* OBJ_id_tc26_signwithdigest       1 2 643 7 1 1 3 */
+     987,    /* OBJ_id_tc26_mac                  1 2 643 7 1 1 4 */
+     990,    /* OBJ_id_tc26_cipher               1 2 643 7 1 1 5 */
+     991,    /* OBJ_id_tc26_agreement            1 2 643 7 1 1 6 */
+     995,    /* OBJ_id_tc26_sign_constants       1 2 643 7 1 2 1 */
+    1000,    /* OBJ_id_tc26_digest_constants     1 2 643 7 1 2 2 */
+    1001,    /* OBJ_id_tc26_cipher_constants     1 2 643 7 1 2 5 */
+       2,    /* OBJ_pkcs                         1 2 840 113549 1 */
+     431,    /* OBJ_hold_instruction_none        1 2 840 10040 2 1 */
+     432,    /* OBJ_hold_instruction_call_issuer 1 2 840 10040 2 2 */
+     433,    /* OBJ_hold_instruction_reject      1 2 840 10040 2 3 */
+     116,    /* OBJ_dsa                          1 2 840 10040 4 1 */
+     113,    /* OBJ_dsaWithSHA1                  1 2 840 10040 4 3 */
+     406,    /* OBJ_X9_62_prime_field            1 2 840 10045 1 1 */
+     407,    /* OBJ_X9_62_characteristic_two_field 1 2 840 10045 1 2 */
+     408,    /* OBJ_X9_62_id_ecPublicKey         1 2 840 10045 2 1 */
+     416,    /* OBJ_ecdsa_with_SHA1              1 2 840 10045 4 1 */
+     791,    /* OBJ_ecdsa_with_Recommended       1 2 840 10045 4 2 */
+     792,    /* OBJ_ecdsa_with_Specified         1 2 840 10045 4 3 */
+     920,    /* OBJ_dhpublicnumber               1 2 840 10046 2 1 */
+    1032,    /* OBJ_pkInitClientAuth             1 3 6 1 5 2 3 4 */
+    1033,    /* OBJ_pkInitKDC                    1 3 6 1 5 2 3 5 */
+     258,    /* OBJ_id_pkix_mod                  1 3 6 1 5 5 7 0 */
+     175,    /* OBJ_id_pe                        1 3 6 1 5 5 7 1 */
+     259,    /* OBJ_id_qt                        1 3 6 1 5 5 7 2 */
+     128,    /* OBJ_id_kp                        1 3 6 1 5 5 7 3 */
+     260,    /* OBJ_id_it                        1 3 6 1 5 5 7 4 */
+     261,    /* OBJ_id_pkip                      1 3 6 1 5 5 7 5 */
+     262,    /* OBJ_id_alg                       1 3 6 1 5 5 7 6 */
+     263,    /* OBJ_id_cmc                       1 3 6 1 5 5 7 7 */
+     264,    /* OBJ_id_on                        1 3 6 1 5 5 7 8 */
+     265,    /* OBJ_id_pda                       1 3 6 1 5 5 7 9 */
+     266,    /* OBJ_id_aca                       1 3 6 1 5 5 7 10 */
+     267,    /* OBJ_id_qcs                       1 3 6 1 5 5 7 11 */
+     268,    /* OBJ_id_cct                       1 3 6 1 5 5 7 12 */
+     662,    /* OBJ_id_ppl                       1 3 6 1 5 5 7 21 */
+     176,    /* OBJ_id_ad                        1 3 6 1 5 5 7 48 */
+     507,    /* OBJ_id_hex_partial_message       1 3 6 1 7 1 1 1 */
+     508,    /* OBJ_id_hex_multipart_message     1 3 6 1 7 1 1 2 */
+      57,    /* OBJ_netscape                     2 16 840 1 113730 */
+     754,    /* OBJ_camellia_128_ecb             0 3 4401 5 3 1 9 1 */
+     766,    /* OBJ_camellia_128_ofb128          0 3 4401 5 3 1 9 3 */
+     757,    /* OBJ_camellia_128_cfb128          0 3 4401 5 3 1 9 4 */
+     961,    /* OBJ_camellia_128_gcm             0 3 4401 5 3 1 9 6 */
+     962,    /* OBJ_camellia_128_ccm             0 3 4401 5 3 1 9 7 */
+     963,    /* OBJ_camellia_128_ctr             0 3 4401 5 3 1 9 9 */
+     964,    /* OBJ_camellia_128_cmac            0 3 4401 5 3 1 9 10 */
+     755,    /* OBJ_camellia_192_ecb             0 3 4401 5 3 1 9 21 */
+     767,    /* OBJ_camellia_192_ofb128          0 3 4401 5 3 1 9 23 */
+     758,    /* OBJ_camellia_192_cfb128          0 3 4401 5 3 1 9 24 */
+     965,    /* OBJ_camellia_192_gcm             0 3 4401 5 3 1 9 26 */
+     966,    /* OBJ_camellia_192_ccm             0 3 4401 5 3 1 9 27 */
+     967,    /* OBJ_camellia_192_ctr             0 3 4401 5 3 1 9 29 */
+     968,    /* OBJ_camellia_192_cmac            0 3 4401 5 3 1 9 30 */
+     756,    /* OBJ_camellia_256_ecb             0 3 4401 5 3 1 9 41 */
+     768,    /* OBJ_camellia_256_ofb128          0 3 4401 5 3 1 9 43 */
+     759,    /* OBJ_camellia_256_cfb128          0 3 4401 5 3 1 9 44 */
+     969,    /* OBJ_camellia_256_gcm             0 3 4401 5 3 1 9 46 */
+     970,    /* OBJ_camellia_256_ccm             0 3 4401 5 3 1 9 47 */
+     971,    /* OBJ_camellia_256_ctr             0 3 4401 5 3 1 9 49 */
+     972,    /* OBJ_camellia_256_cmac            0 3 4401 5 3 1 9 50 */
+     437,    /* OBJ_pilot                        0 9 2342 19200300 100 */
+     776,    /* OBJ_seed_ecb                     1 2 410 200004 1 3 */
+     777,    /* OBJ_seed_cbc                     1 2 410 200004 1 4 */
+     779,    /* OBJ_seed_cfb128                  1 2 410 200004 1 5 */
+     778,    /* OBJ_seed_ofb128                  1 2 410 200004 1 6 */
+     852,    /* OBJ_id_GostR3411_94_with_GostR3410_94_cc 1 2 643 2 9 1 3 3 */
+     853,    /* OBJ_id_GostR3411_94_with_GostR3410_2001_cc 1 2 643 2 9 1 3 4 */
+     850,    /* OBJ_id_GostR3410_94_cc           1 2 643 2 9 1 5 3 */
+     851,    /* OBJ_id_GostR3410_2001_cc         1 2 643 2 9 1 5 4 */
+     849,    /* OBJ_id_Gost28147_89_cc           1 2 643 2 9 1 6 1 */
+     854,    /* OBJ_id_GostR3410_2001_ParamSet_cc 1 2 643 2 9 1 8 1 */
+    1004,    /* OBJ_INN                          1 2 643 3 131 1 1 */
+     979,    /* OBJ_id_GostR3410_2012_256        1 2 643 7 1 1 1 1 */
+     980,    /* OBJ_id_GostR3410_2012_512        1 2 643 7 1 1 1 2 */
+     982,    /* OBJ_id_GostR3411_2012_256        1 2 643 7 1 1 2 2 */
+     983,    /* OBJ_id_GostR3411_2012_512        1 2 643 7 1 1 2 3 */
+     985,    /* OBJ_id_tc26_signwithdigest_gost3410_2012_256 1 2 643 7 1 1 3 2 */
+     986,    /* OBJ_id_tc26_signwithdigest_gost3410_2012_512 1 2 643 7 1 1 3 3 */
+     988,    /* OBJ_id_tc26_hmac_gost_3411_2012_256 1 2 643 7 1 1 4 1 */
+     989,    /* OBJ_id_tc26_hmac_gost_3411_2012_512 1 2 643 7 1 1 4 2 */
+     992,    /* OBJ_id_tc26_agreement_gost_3410_2012_256 1 2 643 7 1 1 6 1 */
+     993,    /* OBJ_id_tc26_agreement_gost_3410_2012_512 1 2 643 7 1 1 6 2 */
+     996,    /* OBJ_id_tc26_gost_3410_2012_512_constants 1 2 643 7 1 2 1 2 */
+    1002,    /* OBJ_id_tc26_gost_28147_constants 1 2 643 7 1 2 5 1 */
+     186,    /* OBJ_pkcs1                        1 2 840 113549 1 1 */
+      27,    /* OBJ_pkcs3                        1 2 840 113549 1 3 */
+     187,    /* OBJ_pkcs5                        1 2 840 113549 1 5 */
+      20,    /* OBJ_pkcs7                        1 2 840 113549 1 7 */
+      47,    /* OBJ_pkcs9                        1 2 840 113549 1 9 */
+       3,    /* OBJ_md2                          1 2 840 113549 2 2 */
+     257,    /* OBJ_md4                          1 2 840 113549 2 4 */
+       4,    /* OBJ_md5                          1 2 840 113549 2 5 */
+     797,    /* OBJ_hmacWithMD5                  1 2 840 113549 2 6 */
+     163,    /* OBJ_hmacWithSHA1                 1 2 840 113549 2 7 */
+     798,    /* OBJ_hmacWithSHA224               1 2 840 113549 2 8 */
+     799,    /* OBJ_hmacWithSHA256               1 2 840 113549 2 9 */
+     800,    /* OBJ_hmacWithSHA384               1 2 840 113549 2 10 */
+     801,    /* OBJ_hmacWithSHA512               1 2 840 113549 2 11 */
+      37,    /* OBJ_rc2_cbc                      1 2 840 113549 3 2 */
+       5,    /* OBJ_rc4                          1 2 840 113549 3 4 */
+      44,    /* OBJ_des_ede3_cbc                 1 2 840 113549 3 7 */
+     120,    /* OBJ_rc5_cbc                      1 2 840 113549 3 8 */
+     643,    /* OBJ_des_cdmf                     1 2 840 113549 3 10 */
+     680,    /* OBJ_X9_62_id_characteristic_two_basis 1 2 840 10045 1 2 3 */
+     684,    /* OBJ_X9_62_c2pnb163v1             1 2 840 10045 3 0 1 */
+     685,    /* OBJ_X9_62_c2pnb163v2             1 2 840 10045 3 0 2 */
+     686,    /* OBJ_X9_62_c2pnb163v3             1 2 840 10045 3 0 3 */
+     687,    /* OBJ_X9_62_c2pnb176v1             1 2 840 10045 3 0 4 */
+     688,    /* OBJ_X9_62_c2tnb191v1             1 2 840 10045 3 0 5 */
+     689,    /* OBJ_X9_62_c2tnb191v2             1 2 840 10045 3 0 6 */
+     690,    /* OBJ_X9_62_c2tnb191v3             1 2 840 10045 3 0 7 */
+     691,    /* OBJ_X9_62_c2onb191v4             1 2 840 10045 3 0 8 */
+     692,    /* OBJ_X9_62_c2onb191v5             1 2 840 10045 3 0 9 */
+     693,    /* OBJ_X9_62_c2pnb208w1             1 2 840 10045 3 0 10 */
+     694,    /* OBJ_X9_62_c2tnb239v1             1 2 840 10045 3 0 11 */
+     695,    /* OBJ_X9_62_c2tnb239v2             1 2 840 10045 3 0 12 */
+     696,    /* OBJ_X9_62_c2tnb239v3             1 2 840 10045 3 0 13 */
+     697,    /* OBJ_X9_62_c2onb239v4             1 2 840 10045 3 0 14 */
+     698,    /* OBJ_X9_62_c2onb239v5             1 2 840 10045 3 0 15 */
+     699,    /* OBJ_X9_62_c2pnb272w1             1 2 840 10045 3 0 16 */
+     700,    /* OBJ_X9_62_c2pnb304w1             1 2 840 10045 3 0 17 */
+     701,    /* OBJ_X9_62_c2tnb359v1             1 2 840 10045 3 0 18 */
+     702,    /* OBJ_X9_62_c2pnb368w1             1 2 840 10045 3 0 19 */
+     703,    /* OBJ_X9_62_c2tnb431r1             1 2 840 10045 3 0 20 */
+     409,    /* OBJ_X9_62_prime192v1             1 2 840 10045 3 1 1 */
+     410,    /* OBJ_X9_62_prime192v2             1 2 840 10045 3 1 2 */
+     411,    /* OBJ_X9_62_prime192v3             1 2 840 10045 3 1 3 */
+     412,    /* OBJ_X9_62_prime239v1             1 2 840 10045 3 1 4 */
+     413,    /* OBJ_X9_62_prime239v2             1 2 840 10045 3 1 5 */
+     414,    /* OBJ_X9_62_prime239v3             1 2 840 10045 3 1 6 */
+     415,    /* OBJ_X9_62_prime256v1             1 2 840 10045 3 1 7 */
+     793,    /* OBJ_ecdsa_with_SHA224            1 2 840 10045 4 3 1 */
+     794,    /* OBJ_ecdsa_with_SHA256            1 2 840 10045 4 3 2 */
+     795,    /* OBJ_ecdsa_with_SHA384            1 2 840 10045 4 3 3 */
+     796,    /* OBJ_ecdsa_with_SHA512            1 2 840 10045 4 3 4 */
+     269,    /* OBJ_id_pkix1_explicit_88         1 3 6 1 5 5 7 0 1 */
+     270,    /* OBJ_id_pkix1_implicit_88         1 3 6 1 5 5 7 0 2 */
+     271,    /* OBJ_id_pkix1_explicit_93         1 3 6 1 5 5 7 0 3 */
+     272,    /* OBJ_id_pkix1_implicit_93         1 3 6 1 5 5 7 0 4 */
+     273,    /* OBJ_id_mod_crmf                  1 3 6 1 5 5 7 0 5 */
+     274,    /* OBJ_id_mod_cmc                   1 3 6 1 5 5 7 0 6 */
+     275,    /* OBJ_id_mod_kea_profile_88        1 3 6 1 5 5 7 0 7 */
+     276,    /* OBJ_id_mod_kea_profile_93        1 3 6 1 5 5 7 0 8 */
+     277,    /* OBJ_id_mod_cmp                   1 3 6 1 5 5 7 0 9 */
+     278,    /* OBJ_id_mod_qualified_cert_88     1 3 6 1 5 5 7 0 10 */
+     279,    /* OBJ_id_mod_qualified_cert_93     1 3 6 1 5 5 7 0 11 */
+     280,    /* OBJ_id_mod_attribute_cert        1 3 6 1 5 5 7 0 12 */
+     281,    /* OBJ_id_mod_timestamp_protocol    1 3 6 1 5 5 7 0 13 */
+     282,    /* OBJ_id_mod_ocsp                  1 3 6 1 5 5 7 0 14 */
+     283,    /* OBJ_id_mod_dvcs                  1 3 6 1 5 5 7 0 15 */
+     284,    /* OBJ_id_mod_cmp2000               1 3 6 1 5 5 7 0 16 */
+     177,    /* OBJ_info_access                  1 3 6 1 5 5 7 1 1 */
+     285,    /* OBJ_biometricInfo                1 3 6 1 5 5 7 1 2 */
+     286,    /* OBJ_qcStatements                 1 3 6 1 5 5 7 1 3 */
+     287,    /* OBJ_ac_auditEntity               1 3 6 1 5 5 7 1 4 */
+     288,    /* OBJ_ac_targeting                 1 3 6 1 5 5 7 1 5 */
+     289,    /* OBJ_aaControls                   1 3 6 1 5 5 7 1 6 */
+     290,    /* OBJ_sbgp_ipAddrBlock             1 3 6 1 5 5 7 1 7 */
+     291,    /* OBJ_sbgp_autonomousSysNum        1 3 6 1 5 5 7 1 8 */
+     292,    /* OBJ_sbgp_routerIdentifier        1 3 6 1 5 5 7 1 9 */
+     397,    /* OBJ_ac_proxying                  1 3 6 1 5 5 7 1 10 */
+     398,    /* OBJ_sinfo_access                 1 3 6 1 5 5 7 1 11 */
+     663,    /* OBJ_proxyCertInfo                1 3 6 1 5 5 7 1 14 */
+    1020,    /* OBJ_tlsfeature                   1 3 6 1 5 5 7 1 24 */
+     164,    /* OBJ_id_qt_cps                    1 3 6 1 5 5 7 2 1 */
+     165,    /* OBJ_id_qt_unotice                1 3 6 1 5 5 7 2 2 */
+     293,    /* OBJ_textNotice                   1 3 6 1 5 5 7 2 3 */
+     129,    /* OBJ_server_auth                  1 3 6 1 5 5 7 3 1 */
+     130,    /* OBJ_client_auth                  1 3 6 1 5 5 7 3 2 */
+     131,    /* OBJ_code_sign                    1 3 6 1 5 5 7 3 3 */
+     132,    /* OBJ_email_protect                1 3 6 1 5 5 7 3 4 */
+     294,    /* OBJ_ipsecEndSystem               1 3 6 1 5 5 7 3 5 */
+     295,    /* OBJ_ipsecTunnel                  1 3 6 1 5 5 7 3 6 */
+     296,    /* OBJ_ipsecUser                    1 3 6 1 5 5 7 3 7 */
+     133,    /* OBJ_time_stamp                   1 3 6 1 5 5 7 3 8 */
+     180,    /* OBJ_OCSP_sign                    1 3 6 1 5 5 7 3 9 */
+     297,    /* OBJ_dvcs                         1 3 6 1 5 5 7 3 10 */
+    1022,    /* OBJ_ipsec_IKE                    1 3 6 1 5 5 7 3 17 */
+    1023,    /* OBJ_capwapAC                     1 3 6 1 5 5 7 3 18 */
+    1024,    /* OBJ_capwapWTP                    1 3 6 1 5 5 7 3 19 */
+    1025,    /* OBJ_sshClient                    1 3 6 1 5 5 7 3 21 */
+    1026,    /* OBJ_sshServer                    1 3 6 1 5 5 7 3 22 */
+    1027,    /* OBJ_sendRouter                   1 3 6 1 5 5 7 3 23 */
+    1028,    /* OBJ_sendProxiedRouter            1 3 6 1 5 5 7 3 24 */
+    1029,    /* OBJ_sendOwner                    1 3 6 1 5 5 7 3 25 */
+    1030,    /* OBJ_sendProxiedOwner             1 3 6 1 5 5 7 3 26 */
+     298,    /* OBJ_id_it_caProtEncCert          1 3 6 1 5 5 7 4 1 */
+     299,    /* OBJ_id_it_signKeyPairTypes       1 3 6 1 5 5 7 4 2 */
+     300,    /* OBJ_id_it_encKeyPairTypes        1 3 6 1 5 5 7 4 3 */
+     301,    /* OBJ_id_it_preferredSymmAlg       1 3 6 1 5 5 7 4 4 */
+     302,    /* OBJ_id_it_caKeyUpdateInfo        1 3 6 1 5 5 7 4 5 */
+     303,    /* OBJ_id_it_currentCRL             1 3 6 1 5 5 7 4 6 */
+     304,    /* OBJ_id_it_unsupportedOIDs        1 3 6 1 5 5 7 4 7 */
+     305,    /* OBJ_id_it_subscriptionRequest    1 3 6 1 5 5 7 4 8 */
+     306,    /* OBJ_id_it_subscriptionResponse   1 3 6 1 5 5 7 4 9 */
+     307,    /* OBJ_id_it_keyPairParamReq        1 3 6 1 5 5 7 4 10 */
+     308,    /* OBJ_id_it_keyPairParamRep        1 3 6 1 5 5 7 4 11 */
+     309,    /* OBJ_id_it_revPassphrase          1 3 6 1 5 5 7 4 12 */
+     310,    /* OBJ_id_it_implicitConfirm        1 3 6 1 5 5 7 4 13 */
+     311,    /* OBJ_id_it_confirmWaitTime        1 3 6 1 5 5 7 4 14 */
+     312,    /* OBJ_id_it_origPKIMessage         1 3 6 1 5 5 7 4 15 */
+     784,    /* OBJ_id_it_suppLangTags           1 3 6 1 5 5 7 4 16 */
+     313,    /* OBJ_id_regCtrl                   1 3 6 1 5 5 7 5 1 */
+     314,    /* OBJ_id_regInfo                   1 3 6 1 5 5 7 5 2 */
+     323,    /* OBJ_id_alg_des40                 1 3 6 1 5 5 7 6 1 */
+     324,    /* OBJ_id_alg_noSignature           1 3 6 1 5 5 7 6 2 */
+     325,    /* OBJ_id_alg_dh_sig_hmac_sha1      1 3 6 1 5 5 7 6 3 */
+     326,    /* OBJ_id_alg_dh_pop                1 3 6 1 5 5 7 6 4 */
+     327,    /* OBJ_id_cmc_statusInfo            1 3 6 1 5 5 7 7 1 */
+     328,    /* OBJ_id_cmc_identification        1 3 6 1 5 5 7 7 2 */
+     329,    /* OBJ_id_cmc_identityProof         1 3 6 1 5 5 7 7 3 */
+     330,    /* OBJ_id_cmc_dataReturn            1 3 6 1 5 5 7 7 4 */
+     331,    /* OBJ_id_cmc_transactionId         1 3 6 1 5 5 7 7 5 */
+     332,    /* OBJ_id_cmc_senderNonce           1 3 6 1 5 5 7 7 6 */
+     333,    /* OBJ_id_cmc_recipientNonce        1 3 6 1 5 5 7 7 7 */
+     334,    /* OBJ_id_cmc_addExtensions         1 3 6 1 5 5 7 7 8 */
+     335,    /* OBJ_id_cmc_encryptedPOP          1 3 6 1 5 5 7 7 9 */
+     336,    /* OBJ_id_cmc_decryptedPOP          1 3 6 1 5 5 7 7 10 */
+     337,    /* OBJ_id_cmc_lraPOPWitness         1 3 6 1 5 5 7 7 11 */
+     338,    /* OBJ_id_cmc_getCert               1 3 6 1 5 5 7 7 15 */
+     339,    /* OBJ_id_cmc_getCRL                1 3 6 1 5 5 7 7 16 */
+     340,    /* OBJ_id_cmc_revokeRequest         1 3 6 1 5 5 7 7 17 */
+     341,    /* OBJ_id_cmc_regInfo               1 3 6 1 5 5 7 7 18 */
+     342,    /* OBJ_id_cmc_responseInfo          1 3 6 1 5 5 7 7 19 */
+     343,    /* OBJ_id_cmc_queryPending          1 3 6 1 5 5 7 7 21 */
+     344,    /* OBJ_id_cmc_popLinkRandom         1 3 6 1 5 5 7 7 22 */
+     345,    /* OBJ_id_cmc_popLinkWitness        1 3 6 1 5 5 7 7 23 */
+     346,    /* OBJ_id_cmc_confirmCertAcceptance 1 3 6 1 5 5 7 7 24 */
+     347,    /* OBJ_id_on_personalData           1 3 6 1 5 5 7 8 1 */
+     858,    /* OBJ_id_on_permanentIdentifier    1 3 6 1 5 5 7 8 3 */
+     348,    /* OBJ_id_pda_dateOfBirth           1 3 6 1 5 5 7 9 1 */
+     349,    /* OBJ_id_pda_placeOfBirth          1 3 6 1 5 5 7 9 2 */
+     351,    /* OBJ_id_pda_gender                1 3 6 1 5 5 7 9 3 */
+     352,    /* OBJ_id_pda_countryOfCitizenship  1 3 6 1 5 5 7 9 4 */
+     353,    /* OBJ_id_pda_countryOfResidence    1 3 6 1 5 5 7 9 5 */
+     354,    /* OBJ_id_aca_authenticationInfo    1 3 6 1 5 5 7 10 1 */
+     355,    /* OBJ_id_aca_accessIdentity        1 3 6 1 5 5 7 10 2 */
+     356,    /* OBJ_id_aca_chargingIdentity      1 3 6 1 5 5 7 10 3 */
+     357,    /* OBJ_id_aca_group                 1 3 6 1 5 5 7 10 4 */
+     358,    /* OBJ_id_aca_role                  1 3 6 1 5 5 7 10 5 */
+     399,    /* OBJ_id_aca_encAttrs              1 3 6 1 5 5 7 10 6 */
+     359,    /* OBJ_id_qcs_pkixQCSyntax_v1       1 3 6 1 5 5 7 11 1 */
+     360,    /* OBJ_id_cct_crs                   1 3 6 1 5 5 7 12 1 */
+     361,    /* OBJ_id_cct_PKIData               1 3 6 1 5 5 7 12 2 */
+     362,    /* OBJ_id_cct_PKIResponse           1 3 6 1 5 5 7 12 3 */
+     664,    /* OBJ_id_ppl_anyLanguage           1 3 6 1 5 5 7 21 0 */
+     665,    /* OBJ_id_ppl_inheritAll            1 3 6 1 5 5 7 21 1 */
+     667,    /* OBJ_Independent                  1 3 6 1 5 5 7 21 2 */
+     178,    /* OBJ_ad_OCSP                      1 3 6 1 5 5 7 48 1 */
+     179,    /* OBJ_ad_ca_issuers                1 3 6 1 5 5 7 48 2 */
+     363,    /* OBJ_ad_timeStamping              1 3 6 1 5 5 7 48 3 */
+     364,    /* OBJ_ad_dvcs                      1 3 6 1 5 5 7 48 4 */
+     785,    /* OBJ_caRepository                 1 3 6 1 5 5 7 48 5 */
+     780,    /* OBJ_hmac_md5                     1 3 6 1 5 5 8 1 1 */
+     781,    /* OBJ_hmac_sha1                    1 3 6 1 5 5 8 1 2 */
+      58,    /* OBJ_netscape_cert_extension      2 16 840 1 113730 1 */
+      59,    /* OBJ_netscape_data_type           2 16 840 1 113730 2 */
+     438,    /* OBJ_pilotAttributeType           0 9 2342 19200300 100 1 */
+     439,    /* OBJ_pilotAttributeSyntax         0 9 2342 19200300 100 3 */
+     440,    /* OBJ_pilotObjectClass             0 9 2342 19200300 100 4 */
+     441,    /* OBJ_pilotGroups                  0 9 2342 19200300 100 10 */
+     997,    /* OBJ_id_tc26_gost_3410_2012_512_paramSetTest 1 2 643 7 1 2 1 2 0 */
+     998,    /* OBJ_id_tc26_gost_3410_2012_512_paramSetA 1 2 643 7 1 2 1 2 1 */
+     999,    /* OBJ_id_tc26_gost_3410_2012_512_paramSetB 1 2 643 7 1 2 1 2 2 */
+    1003,    /* OBJ_id_tc26_gost_28147_param_Z   1 2 643 7 1 2 5 1 1 */
+     108,    /* OBJ_cast5_cbc                    1 2 840 113533 7 66 10 */
+     112,    /* OBJ_pbeWithMD5AndCast5_CBC       1 2 840 113533 7 66 12 */
+     782,    /* OBJ_id_PasswordBasedMAC          1 2 840 113533 7 66 13 */
+     783,    /* OBJ_id_DHBasedMac                1 2 840 113533 7 66 30 */
+       6,    /* OBJ_rsaEncryption                1 2 840 113549 1 1 1 */
+       7,    /* OBJ_md2WithRSAEncryption         1 2 840 113549 1 1 2 */
+     396,    /* OBJ_md4WithRSAEncryption         1 2 840 113549 1 1 3 */
+       8,    /* OBJ_md5WithRSAEncryption         1 2 840 113549 1 1 4 */
+      65,    /* OBJ_sha1WithRSAEncryption        1 2 840 113549 1 1 5 */
+     644,    /* OBJ_rsaOAEPEncryptionSET         1 2 840 113549 1 1 6 */
+     919,    /* OBJ_rsaesOaep                    1 2 840 113549 1 1 7 */
+     911,    /* OBJ_mgf1                         1 2 840 113549 1 1 8 */
+     935,    /* OBJ_pSpecified                   1 2 840 113549 1 1 9 */
+     912,    /* OBJ_rsassaPss                    1 2 840 113549 1 1 10 */
+     668,    /* OBJ_sha256WithRSAEncryption      1 2 840 113549 1 1 11 */
+     669,    /* OBJ_sha384WithRSAEncryption      1 2 840 113549 1 1 12 */
+     670,    /* OBJ_sha512WithRSAEncryption      1 2 840 113549 1 1 13 */
+     671,    /* OBJ_sha224WithRSAEncryption      1 2 840 113549 1 1 14 */
+      28,    /* OBJ_dhKeyAgreement               1 2 840 113549 1 3 1 */
+       9,    /* OBJ_pbeWithMD2AndDES_CBC         1 2 840 113549 1 5 1 */
+      10,    /* OBJ_pbeWithMD5AndDES_CBC         1 2 840 113549 1 5 3 */
+     168,    /* OBJ_pbeWithMD2AndRC2_CBC         1 2 840 113549 1 5 4 */
+     169,    /* OBJ_pbeWithMD5AndRC2_CBC         1 2 840 113549 1 5 6 */
+     170,    /* OBJ_pbeWithSHA1AndDES_CBC        1 2 840 113549 1 5 10 */
+      68,    /* OBJ_pbeWithSHA1AndRC2_CBC        1 2 840 113549 1 5 11 */
+      69,    /* OBJ_id_pbkdf2                    1 2 840 113549 1 5 12 */
+     161,    /* OBJ_pbes2                        1 2 840 113549 1 5 13 */
+     162,    /* OBJ_pbmac1                       1 2 840 113549 1 5 14 */
+      21,    /* OBJ_pkcs7_data                   1 2 840 113549 1 7 1 */
+      22,    /* OBJ_pkcs7_signed                 1 2 840 113549 1 7 2 */
+      23,    /* OBJ_pkcs7_enveloped              1 2 840 113549 1 7 3 */
+      24,    /* OBJ_pkcs7_signedAndEnveloped     1 2 840 113549 1 7 4 */
+      25,    /* OBJ_pkcs7_digest                 1 2 840 113549 1 7 5 */
+      26,    /* OBJ_pkcs7_encrypted              1 2 840 113549 1 7 6 */
+      48,    /* OBJ_pkcs9_emailAddress           1 2 840 113549 1 9 1 */
+      49,    /* OBJ_pkcs9_unstructuredName       1 2 840 113549 1 9 2 */
+      50,    /* OBJ_pkcs9_contentType            1 2 840 113549 1 9 3 */
+      51,    /* OBJ_pkcs9_messageDigest          1 2 840 113549 1 9 4 */
+      52,    /* OBJ_pkcs9_signingTime            1 2 840 113549 1 9 5 */
+      53,    /* OBJ_pkcs9_countersignature       1 2 840 113549 1 9 6 */
+      54,    /* OBJ_pkcs9_challengePassword      1 2 840 113549 1 9 7 */
+      55,    /* OBJ_pkcs9_unstructuredAddress    1 2 840 113549 1 9 8 */
+      56,    /* OBJ_pkcs9_extCertAttributes      1 2 840 113549 1 9 9 */
+     172,    /* OBJ_ext_req                      1 2 840 113549 1 9 14 */
+     167,    /* OBJ_SMIMECapabilities            1 2 840 113549 1 9 15 */
+     188,    /* OBJ_SMIME                        1 2 840 113549 1 9 16 */
+     156,    /* OBJ_friendlyName                 1 2 840 113549 1 9 20 */
+     157,    /* OBJ_localKeyID                   1 2 840 113549 1 9 21 */
+     681,    /* OBJ_X9_62_onBasis                1 2 840 10045 1 2 3 1 */
+     682,    /* OBJ_X9_62_tpBasis                1 2 840 10045 1 2 3 2 */
+     683,    /* OBJ_X9_62_ppBasis                1 2 840 10045 1 2 3 3 */
+     417,    /* OBJ_ms_csp_name                  1 3 6 1 4 1 311 17 1 */
+     856,    /* OBJ_LocalKeySet                  1 3 6 1 4 1 311 17 2 */
+     390,    /* OBJ_dcObject                     1 3 6 1 4 1 1466 344 */
+      91,    /* OBJ_bf_cbc                       1 3 6 1 4 1 3029 1 2 */
+     973,    /* OBJ_id_scrypt                    1 3 6 1 4 1 11591 4 11 */
+     315,    /* OBJ_id_regCtrl_regToken          1 3 6 1 5 5 7 5 1 1 */
+     316,    /* OBJ_id_regCtrl_authenticator     1 3 6 1 5 5 7 5 1 2 */
+     317,    /* OBJ_id_regCtrl_pkiPublicationInfo 1 3 6 1 5 5 7 5 1 3 */
+     318,    /* OBJ_id_regCtrl_pkiArchiveOptions 1 3 6 1 5 5 7 5 1 4 */
+     319,    /* OBJ_id_regCtrl_oldCertID         1 3 6 1 5 5 7 5 1 5 */
+     320,    /* OBJ_id_regCtrl_protocolEncrKey   1 3 6 1 5 5 7 5 1 6 */
+     321,    /* OBJ_id_regInfo_utf8Pairs         1 3 6 1 5 5 7 5 2 1 */
+     322,    /* OBJ_id_regInfo_certReq           1 3 6 1 5 5 7 5 2 2 */
+     365,    /* OBJ_id_pkix_OCSP_basic           1 3 6 1 5 5 7 48 1 1 */
+     366,    /* OBJ_id_pkix_OCSP_Nonce           1 3 6 1 5 5 7 48 1 2 */
+     367,    /* OBJ_id_pkix_OCSP_CrlID           1 3 6 1 5 5 7 48 1 3 */
+     368,    /* OBJ_id_pkix_OCSP_acceptableResponses 1 3 6 1 5 5 7 48 1 4 */
+     369,    /* OBJ_id_pkix_OCSP_noCheck         1 3 6 1 5 5 7 48 1 5 */
+     370,    /* OBJ_id_pkix_OCSP_archiveCutoff   1 3 6 1 5 5 7 48 1 6 */
+     371,    /* OBJ_id_pkix_OCSP_serviceLocator  1 3 6 1 5 5 7 48 1 7 */
+     372,    /* OBJ_id_pkix_OCSP_extendedStatus  1 3 6 1 5 5 7 48 1 8 */
+     373,    /* OBJ_id_pkix_OCSP_valid           1 3 6 1 5 5 7 48 1 9 */
+     374,    /* OBJ_id_pkix_OCSP_path            1 3 6 1 5 5 7 48 1 10 */
+     375,    /* OBJ_id_pkix_OCSP_trustRoot       1 3 6 1 5 5 7 48 1 11 */
+     921,    /* OBJ_brainpoolP160r1              1 3 36 3 3 2 8 1 1 1 */
+     922,    /* OBJ_brainpoolP160t1              1 3 36 3 3 2 8 1 1 2 */
+     923,    /* OBJ_brainpoolP192r1              1 3 36 3 3 2 8 1 1 3 */
+     924,    /* OBJ_brainpoolP192t1              1 3 36 3 3 2 8 1 1 4 */
+     925,    /* OBJ_brainpoolP224r1              1 3 36 3 3 2 8 1 1 5 */
+     926,    /* OBJ_brainpoolP224t1              1 3 36 3 3 2 8 1 1 6 */
+     927,    /* OBJ_brainpoolP256r1              1 3 36 3 3 2 8 1 1 7 */
+     928,    /* OBJ_brainpoolP256t1              1 3 36 3 3 2 8 1 1 8 */
+     929,    /* OBJ_brainpoolP320r1              1 3 36 3 3 2 8 1 1 9 */
+     930,    /* OBJ_brainpoolP320t1              1 3 36 3 3 2 8 1 1 10 */
+     931,    /* OBJ_brainpoolP384r1              1 3 36 3 3 2 8 1 1 11 */
+     932,    /* OBJ_brainpoolP384t1              1 3 36 3 3 2 8 1 1 12 */
+     933,    /* OBJ_brainpoolP512r1              1 3 36 3 3 2 8 1 1 13 */
+     934,    /* OBJ_brainpoolP512t1              1 3 36 3 3 2 8 1 1 14 */
+     936,    /* OBJ_dhSinglePass_stdDH_sha1kdf_scheme 1 3 133 16 840 63 0 2 */
+     941,    /* OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme 1 3 133 16 840 63 0 3 */
+     418,    /* OBJ_aes_128_ecb                  2 16 840 1 101 3 4 1 1 */
+     419,    /* OBJ_aes_128_cbc                  2 16 840 1 101 3 4 1 2 */
+     420,    /* OBJ_aes_128_ofb128               2 16 840 1 101 3 4 1 3 */
+     421,    /* OBJ_aes_128_cfb128               2 16 840 1 101 3 4 1 4 */
+     788,    /* OBJ_id_aes128_wrap               2 16 840 1 101 3 4 1 5 */
+     895,    /* OBJ_aes_128_gcm                  2 16 840 1 101 3 4 1 6 */
+     896,    /* OBJ_aes_128_ccm                  2 16 840 1 101 3 4 1 7 */
+     897,    /* OBJ_id_aes128_wrap_pad           2 16 840 1 101 3 4 1 8 */
+     422,    /* OBJ_aes_192_ecb                  2 16 840 1 101 3 4 1 21 */
+     423,    /* OBJ_aes_192_cbc                  2 16 840 1 101 3 4 1 22 */
+     424,    /* OBJ_aes_192_ofb128               2 16 840 1 101 3 4 1 23 */
+     425,    /* OBJ_aes_192_cfb128               2 16 840 1 101 3 4 1 24 */
+     789,    /* OBJ_id_aes192_wrap               2 16 840 1 101 3 4 1 25 */
+     898,    /* OBJ_aes_192_gcm                  2 16 840 1 101 3 4 1 26 */
+     899,    /* OBJ_aes_192_ccm                  2 16 840 1 101 3 4 1 27 */
+     900,    /* OBJ_id_aes192_wrap_pad           2 16 840 1 101 3 4 1 28 */
+     426,    /* OBJ_aes_256_ecb                  2 16 840 1 101 3 4 1 41 */
+     427,    /* OBJ_aes_256_cbc                  2 16 840 1 101 3 4 1 42 */
+     428,    /* OBJ_aes_256_ofb128               2 16 840 1 101 3 4 1 43 */
+     429,    /* OBJ_aes_256_cfb128               2 16 840 1 101 3 4 1 44 */
+     790,    /* OBJ_id_aes256_wrap               2 16 840 1 101 3 4 1 45 */
+     901,    /* OBJ_aes_256_gcm                  2 16 840 1 101 3 4 1 46 */
+     902,    /* OBJ_aes_256_ccm                  2 16 840 1 101 3 4 1 47 */
+     903,    /* OBJ_id_aes256_wrap_pad           2 16 840 1 101 3 4 1 48 */
+     672,    /* OBJ_sha256                       2 16 840 1 101 3 4 2 1 */
+     673,    /* OBJ_sha384                       2 16 840 1 101 3 4 2 2 */
+     674,    /* OBJ_sha512                       2 16 840 1 101 3 4 2 3 */
+     675,    /* OBJ_sha224                       2 16 840 1 101 3 4 2 4 */
+     802,    /* OBJ_dsa_with_SHA224              2 16 840 1 101 3 4 3 1 */
+     803,    /* OBJ_dsa_with_SHA256              2 16 840 1 101 3 4 3 2 */
+      71,    /* OBJ_netscape_cert_type           2 16 840 1 113730 1 1 */
+      72,    /* OBJ_netscape_base_url            2 16 840 1 113730 1 2 */
+      73,    /* OBJ_netscape_revocation_url      2 16 840 1 113730 1 3 */
+      74,    /* OBJ_netscape_ca_revocation_url   2 16 840 1 113730 1 4 */
+      75,    /* OBJ_netscape_renewal_url         2 16 840 1 113730 1 7 */
+      76,    /* OBJ_netscape_ca_policy_url       2 16 840 1 113730 1 8 */
+      77,    /* OBJ_netscape_ssl_server_name     2 16 840 1 113730 1 12 */
+      78,    /* OBJ_netscape_comment             2 16 840 1 113730 1 13 */
+      79,    /* OBJ_netscape_cert_sequence       2 16 840 1 113730 2 5 */
+     139,    /* OBJ_ns_sgc                       2 16 840 1 113730 4 1 */
+     458,    /* OBJ_userId                       0 9 2342 19200300 100 1 1 */
+     459,    /* OBJ_textEncodedORAddress         0 9 2342 19200300 100 1 2 */
+     460,    /* OBJ_rfc822Mailbox                0 9 2342 19200300 100 1 3 */
+     461,    /* OBJ_info                         0 9 2342 19200300 100 1 4 */
+     462,    /* OBJ_favouriteDrink               0 9 2342 19200300 100 1 5 */
+     463,    /* OBJ_roomNumber                   0 9 2342 19200300 100 1 6 */
+     464,    /* OBJ_photo                        0 9 2342 19200300 100 1 7 */
+     465,    /* OBJ_userClass                    0 9 2342 19200300 100 1 8 */
+     466,    /* OBJ_host                         0 9 2342 19200300 100 1 9 */
+     467,    /* OBJ_manager                      0 9 2342 19200300 100 1 10 */
+     468,    /* OBJ_documentIdentifier           0 9 2342 19200300 100 1 11 */
+     469,    /* OBJ_documentTitle                0 9 2342 19200300 100 1 12 */
+     470,    /* OBJ_documentVersion              0 9 2342 19200300 100 1 13 */
+     471,    /* OBJ_documentAuthor               0 9 2342 19200300 100 1 14 */
+     472,    /* OBJ_documentLocation             0 9 2342 19200300 100 1 15 */
+     473,    /* OBJ_homeTelephoneNumber          0 9 2342 19200300 100 1 20 */
+     474,    /* OBJ_secretary                    0 9 2342 19200300 100 1 21 */
+     475,    /* OBJ_otherMailbox                 0 9 2342 19200300 100 1 22 */
+     476,    /* OBJ_lastModifiedTime             0 9 2342 19200300 100 1 23 */
+     477,    /* OBJ_lastModifiedBy               0 9 2342 19200300 100 1 24 */
+     391,    /* OBJ_domainComponent              0 9 2342 19200300 100 1 25 */
+     478,    /* OBJ_aRecord                      0 9 2342 19200300 100 1 26 */
+     479,    /* OBJ_pilotAttributeType27         0 9 2342 19200300 100 1 27 */
+     480,    /* OBJ_mXRecord                     0 9 2342 19200300 100 1 28 */
+     481,    /* OBJ_nSRecord                     0 9 2342 19200300 100 1 29 */
+     482,    /* OBJ_sOARecord                    0 9 2342 19200300 100 1 30 */
+     483,    /* OBJ_cNAMERecord                  0 9 2342 19200300 100 1 31 */
+     484,    /* OBJ_associatedDomain             0 9 2342 19200300 100 1 37 */
+     485,    /* OBJ_associatedName               0 9 2342 19200300 100 1 38 */
+     486,    /* OBJ_homePostalAddress            0 9 2342 19200300 100 1 39 */
+     487,    /* OBJ_personalTitle                0 9 2342 19200300 100 1 40 */
+     488,    /* OBJ_mobileTelephoneNumber        0 9 2342 19200300 100 1 41 */
+     489,    /* OBJ_pagerTelephoneNumber         0 9 2342 19200300 100 1 42 */
+     490,    /* OBJ_friendlyCountryName          0 9 2342 19200300 100 1 43 */
+     102,    /* OBJ_uniqueIdentifier             0 9 2342 19200300 100 1 44 */
+     491,    /* OBJ_organizationalStatus         0 9 2342 19200300 100 1 45 */
+     492,    /* OBJ_janetMailbox                 0 9 2342 19200300 100 1 46 */
+     493,    /* OBJ_mailPreferenceOption         0 9 2342 19200300 100 1 47 */
+     494,    /* OBJ_buildingName                 0 9 2342 19200300 100 1 48 */
+     495,    /* OBJ_dSAQuality                   0 9 2342 19200300 100 1 49 */
+     496,    /* OBJ_singleLevelQuality           0 9 2342 19200300 100 1 50 */
+     497,    /* OBJ_subtreeMinimumQuality        0 9 2342 19200300 100 1 51 */
+     498,    /* OBJ_subtreeMaximumQuality        0 9 2342 19200300 100 1 52 */
+     499,    /* OBJ_personalSignature            0 9 2342 19200300 100 1 53 */
+     500,    /* OBJ_dITRedirect                  0 9 2342 19200300 100 1 54 */
+     501,    /* OBJ_audio                        0 9 2342 19200300 100 1 55 */
+     502,    /* OBJ_documentPublisher            0 9 2342 19200300 100 1 56 */
+     442,    /* OBJ_iA5StringSyntax              0 9 2342 19200300 100 3 4 */
+     443,    /* OBJ_caseIgnoreIA5StringSyntax    0 9 2342 19200300 100 3 5 */
+     444,    /* OBJ_pilotObject                  0 9 2342 19200300 100 4 3 */
+     445,    /* OBJ_pilotPerson                  0 9 2342 19200300 100 4 4 */
+     446,    /* OBJ_account                      0 9 2342 19200300 100 4 5 */
+     447,    /* OBJ_document                     0 9 2342 19200300 100 4 6 */
+     448,    /* OBJ_room                         0 9 2342 19200300 100 4 7 */
+     449,    /* OBJ_documentSeries               0 9 2342 19200300 100 4 9 */
+     392,    /* OBJ_Domain                       0 9 2342 19200300 100 4 13 */
+     450,    /* OBJ_rFC822localPart              0 9 2342 19200300 100 4 14 */
+     451,    /* OBJ_dNSDomain                    0 9 2342 19200300 100 4 15 */
+     452,    /* OBJ_domainRelatedObject          0 9 2342 19200300 100 4 17 */
+     453,    /* OBJ_friendlyCountry              0 9 2342 19200300 100 4 18 */
+     454,    /* OBJ_simpleSecurityObject         0 9 2342 19200300 100 4 19 */
+     455,    /* OBJ_pilotOrganization            0 9 2342 19200300 100 4 20 */
+     456,    /* OBJ_pilotDSA                     0 9 2342 19200300 100 4 21 */
+     457,    /* OBJ_qualityLabelledData          0 9 2342 19200300 100 4 22 */
+     189,    /* OBJ_id_smime_mod                 1 2 840 113549 1 9 16 0 */
+     190,    /* OBJ_id_smime_ct                  1 2 840 113549 1 9 16 1 */
+     191,    /* OBJ_id_smime_aa                  1 2 840 113549 1 9 16 2 */
+     192,    /* OBJ_id_smime_alg                 1 2 840 113549 1 9 16 3 */
+     193,    /* OBJ_id_smime_cd                  1 2 840 113549 1 9 16 4 */
+     194,    /* OBJ_id_smime_spq                 1 2 840 113549 1 9 16 5 */
+     195,    /* OBJ_id_smime_cti                 1 2 840 113549 1 9 16 6 */
+     158,    /* OBJ_x509Certificate              1 2 840 113549 1 9 22 1 */
+     159,    /* OBJ_sdsiCertificate              1 2 840 113549 1 9 22 2 */
+     160,    /* OBJ_x509Crl                      1 2 840 113549 1 9 23 1 */
+     144,    /* OBJ_pbe_WithSHA1And128BitRC4     1 2 840 113549 1 12 1 1 */
+     145,    /* OBJ_pbe_WithSHA1And40BitRC4      1 2 840 113549 1 12 1 2 */
+     146,    /* OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC 1 2 840 113549 1 12 1 3 */
+     147,    /* OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC 1 2 840 113549 1 12 1 4 */
+     148,    /* OBJ_pbe_WithSHA1And128BitRC2_CBC 1 2 840 113549 1 12 1 5 */
+     149,    /* OBJ_pbe_WithSHA1And40BitRC2_CBC  1 2 840 113549 1 12 1 6 */
+     171,    /* OBJ_ms_ext_req                   1 3 6 1 4 1 311 2 1 14 */
+     134,    /* OBJ_ms_code_ind                  1 3 6 1 4 1 311 2 1 21 */
+     135,    /* OBJ_ms_code_com                  1 3 6 1 4 1 311 2 1 22 */
+     136,    /* OBJ_ms_ctl_sign                  1 3 6 1 4 1 311 10 3 1 */
+     137,    /* OBJ_ms_sgc                       1 3 6 1 4 1 311 10 3 3 */
+     138,    /* OBJ_ms_efs                       1 3 6 1 4 1 311 10 3 4 */
+     648,    /* OBJ_ms_smartcard_login           1 3 6 1 4 1 311 20 2 2 */
+     649,    /* OBJ_ms_upn                       1 3 6 1 4 1 311 20 2 3 */
+     951,    /* OBJ_ct_precert_scts              1 3 6 1 4 1 11129 2 4 2 */
+     952,    /* OBJ_ct_precert_poison            1 3 6 1 4 1 11129 2 4 3 */
+     953,    /* OBJ_ct_precert_signer            1 3 6 1 4 1 11129 2 4 4 */
+     954,    /* OBJ_ct_cert_scts                 1 3 6 1 4 1 11129 2 4 5 */
+     751,    /* OBJ_camellia_128_cbc             1 2 392 200011 61 1 1 1 2 */
+     752,    /* OBJ_camellia_192_cbc             1 2 392 200011 61 1 1 1 3 */
+     753,    /* OBJ_camellia_256_cbc             1 2 392 200011 61 1 1 1 4 */
+     907,    /* OBJ_id_camellia128_wrap          1 2 392 200011 61 1 1 3 2 */
+     908,    /* OBJ_id_camellia192_wrap          1 2 392 200011 61 1 1 3 3 */
+     909,    /* OBJ_id_camellia256_wrap          1 2 392 200011 61 1 1 3 4 */
+     196,    /* OBJ_id_smime_mod_cms             1 2 840 113549 1 9 16 0 1 */
+     197,    /* OBJ_id_smime_mod_ess             1 2 840 113549 1 9 16 0 2 */
+     198,    /* OBJ_id_smime_mod_oid             1 2 840 113549 1 9 16 0 3 */
+     199,    /* OBJ_id_smime_mod_msg_v3          1 2 840 113549 1 9 16 0 4 */
+     200,    /* OBJ_id_smime_mod_ets_eSignature_88 1 2 840 113549 1 9 16 0 5 */
+     201,    /* OBJ_id_smime_mod_ets_eSignature_97 1 2 840 113549 1 9 16 0 6 */
+     202,    /* OBJ_id_smime_mod_ets_eSigPolicy_88 1 2 840 113549 1 9 16 0 7 */
+     203,    /* OBJ_id_smime_mod_ets_eSigPolicy_97 1 2 840 113549 1 9 16 0 8 */
+     204,    /* OBJ_id_smime_ct_receipt          1 2 840 113549 1 9 16 1 1 */
+     205,    /* OBJ_id_smime_ct_authData         1 2 840 113549 1 9 16 1 2 */
+     206,    /* OBJ_id_smime_ct_publishCert      1 2 840 113549 1 9 16 1 3 */
+     207,    /* OBJ_id_smime_ct_TSTInfo          1 2 840 113549 1 9 16 1 4 */
+     208,    /* OBJ_id_smime_ct_TDTInfo          1 2 840 113549 1 9 16 1 5 */
+     209,    /* OBJ_id_smime_ct_contentInfo      1 2 840 113549 1 9 16 1 6 */
+     210,    /* OBJ_id_smime_ct_DVCSRequestData  1 2 840 113549 1 9 16 1 7 */
+     211,    /* OBJ_id_smime_ct_DVCSResponseData 1 2 840 113549 1 9 16 1 8 */
+     786,    /* OBJ_id_smime_ct_compressedData   1 2 840 113549 1 9 16 1 9 */
+    1058,    /* OBJ_id_smime_ct_contentCollection 1 2 840 113549 1 9 16 1 19 */
+    1059,    /* OBJ_id_smime_ct_authEnvelopedData 1 2 840 113549 1 9 16 1 23 */
+     787,    /* OBJ_id_ct_asciiTextWithCRLF      1 2 840 113549 1 9 16 1 27 */
+    1060,    /* OBJ_id_ct_xml                    1 2 840 113549 1 9 16 1 28 */
+     212,    /* OBJ_id_smime_aa_receiptRequest   1 2 840 113549 1 9 16 2 1 */
+     213,    /* OBJ_id_smime_aa_securityLabel    1 2 840 113549 1 9 16 2 2 */
+     214,    /* OBJ_id_smime_aa_mlExpandHistory  1 2 840 113549 1 9 16 2 3 */
+     215,    /* OBJ_id_smime_aa_contentHint      1 2 840 113549 1 9 16 2 4 */
+     216,    /* OBJ_id_smime_aa_msgSigDigest     1 2 840 113549 1 9 16 2 5 */
+     217,    /* OBJ_id_smime_aa_encapContentType 1 2 840 113549 1 9 16 2 6 */
+     218,    /* OBJ_id_smime_aa_contentIdentifier 1 2 840 113549 1 9 16 2 7 */
+     219,    /* OBJ_id_smime_aa_macValue         1 2 840 113549 1 9 16 2 8 */
+     220,    /* OBJ_id_smime_aa_equivalentLabels 1 2 840 113549 1 9 16 2 9 */
+     221,    /* OBJ_id_smime_aa_contentReference 1 2 840 113549 1 9 16 2 10 */
+     222,    /* OBJ_id_smime_aa_encrypKeyPref    1 2 840 113549 1 9 16 2 11 */
+     223,    /* OBJ_id_smime_aa_signingCertificate 1 2 840 113549 1 9 16 2 12 */
+     224,    /* OBJ_id_smime_aa_smimeEncryptCerts 1 2 840 113549 1 9 16 2 13 */
+     225,    /* OBJ_id_smime_aa_timeStampToken   1 2 840 113549 1 9 16 2 14 */
+     226,    /* OBJ_id_smime_aa_ets_sigPolicyId  1 2 840 113549 1 9 16 2 15 */
+     227,    /* OBJ_id_smime_aa_ets_commitmentType 1 2 840 113549 1 9 16 2 16 */
+     228,    /* OBJ_id_smime_aa_ets_signerLocation 1 2 840 113549 1 9 16 2 17 */
+     229,    /* OBJ_id_smime_aa_ets_signerAttr   1 2 840 113549 1 9 16 2 18 */
+     230,    /* OBJ_id_smime_aa_ets_otherSigCert 1 2 840 113549 1 9 16 2 19 */
+     231,    /* OBJ_id_smime_aa_ets_contentTimestamp 1 2 840 113549 1 9 16 2 20 */
+     232,    /* OBJ_id_smime_aa_ets_CertificateRefs 1 2 840 113549 1 9 16 2 21 */
+     233,    /* OBJ_id_smime_aa_ets_RevocationRefs 1 2 840 113549 1 9 16 2 22 */
+     234,    /* OBJ_id_smime_aa_ets_certValues   1 2 840 113549 1 9 16 2 23 */
+     235,    /* OBJ_id_smime_aa_ets_revocationValues 1 2 840 113549 1 9 16 2 24 */
+     236,    /* OBJ_id_smime_aa_ets_escTimeStamp 1 2 840 113549 1 9 16 2 25 */
+     237,    /* OBJ_id_smime_aa_ets_certCRLTimestamp 1 2 840 113549 1 9 16 2 26 */
+     238,    /* OBJ_id_smime_aa_ets_archiveTimeStamp 1 2 840 113549 1 9 16 2 27 */
+     239,    /* OBJ_id_smime_aa_signatureType    1 2 840 113549 1 9 16 2 28 */
+     240,    /* OBJ_id_smime_aa_dvcs_dvc         1 2 840 113549 1 9 16 2 29 */
+     241,    /* OBJ_id_smime_alg_ESDHwith3DES    1 2 840 113549 1 9 16 3 1 */
+     242,    /* OBJ_id_smime_alg_ESDHwithRC2     1 2 840 113549 1 9 16 3 2 */
+     243,    /* OBJ_id_smime_alg_3DESwrap        1 2 840 113549 1 9 16 3 3 */
+     244,    /* OBJ_id_smime_alg_RC2wrap         1 2 840 113549 1 9 16 3 4 */
+     245,    /* OBJ_id_smime_alg_ESDH            1 2 840 113549 1 9 16 3 5 */
+     246,    /* OBJ_id_smime_alg_CMS3DESwrap     1 2 840 113549 1 9 16 3 6 */
+     247,    /* OBJ_id_smime_alg_CMSRC2wrap      1 2 840 113549 1 9 16 3 7 */
+     125,    /* OBJ_zlib_compression             1 2 840 113549 1 9 16 3 8 */
+     893,    /* OBJ_id_alg_PWRI_KEK              1 2 840 113549 1 9 16 3 9 */
+     248,    /* OBJ_id_smime_cd_ldap             1 2 840 113549 1 9 16 4 1 */
+     249,    /* OBJ_id_smime_spq_ets_sqt_uri     1 2 840 113549 1 9 16 5 1 */
+     250,    /* OBJ_id_smime_spq_ets_sqt_unotice 1 2 840 113549 1 9 16 5 2 */
+     251,    /* OBJ_id_smime_cti_ets_proofOfOrigin 1 2 840 113549 1 9 16 6 1 */
+     252,    /* OBJ_id_smime_cti_ets_proofOfReceipt 1 2 840 113549 1 9 16 6 2 */
+     253,    /* OBJ_id_smime_cti_ets_proofOfDelivery 1 2 840 113549 1 9 16 6 3 */
+     254,    /* OBJ_id_smime_cti_ets_proofOfSender 1 2 840 113549 1 9 16 6 4 */
+     255,    /* OBJ_id_smime_cti_ets_proofOfApproval 1 2 840 113549 1 9 16 6 5 */
+     256,    /* OBJ_id_smime_cti_ets_proofOfCreation 1 2 840 113549 1 9 16 6 6 */
+     150,    /* OBJ_keyBag                       1 2 840 113549 1 12 10 1 1 */
+     151,    /* OBJ_pkcs8ShroudedKeyBag          1 2 840 113549 1 12 10 1 2 */
+     152,    /* OBJ_certBag                      1 2 840 113549 1 12 10 1 3 */
+     153,    /* OBJ_crlBag                       1 2 840 113549 1 12 10 1 4 */
+     154,    /* OBJ_secretBag                    1 2 840 113549 1 12 10 1 5 */
+     155,    /* OBJ_safeContentsBag              1 2 840 113549 1 12 10 1 6 */
+      34,    /* OBJ_idea_cbc                     1 3 6 1 4 1 188 7 1 1 2 */
+     955,    /* OBJ_jurisdictionLocalityName     1 3 6 1 4 1 311 60 2 1 1 */
+     956,    /* OBJ_jurisdictionStateOrProvinceName 1 3 6 1 4 1 311 60 2 1 2 */
+     957,    /* OBJ_jurisdictionCountryName      1 3 6 1 4 1 311 60 2 1 3 */
+    1056,    /* OBJ_blake2b512                   1 3 6 1 4 1 1722 12 2 1 16 */
+    1057,    /* OBJ_blake2s256                   1 3 6 1 4 1 1722 12 2 2 8 */
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_err.c	(revision 331)
@@ -0,0 +1,50 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/objects.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_OBJ,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_OBJ,0,reason)
+
+static ERR_STRING_DATA OBJ_str_functs[] = {
+    {ERR_FUNC(OBJ_F_OBJ_ADD_OBJECT), "OBJ_add_object"},
+    {ERR_FUNC(OBJ_F_OBJ_CREATE), "OBJ_create"},
+    {ERR_FUNC(OBJ_F_OBJ_DUP), "OBJ_dup"},
+    {ERR_FUNC(OBJ_F_OBJ_NAME_NEW_INDEX), "OBJ_NAME_new_index"},
+    {ERR_FUNC(OBJ_F_OBJ_NID2LN), "OBJ_nid2ln"},
+    {ERR_FUNC(OBJ_F_OBJ_NID2OBJ), "OBJ_nid2obj"},
+    {ERR_FUNC(OBJ_F_OBJ_NID2SN), "OBJ_nid2sn"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA OBJ_str_reasons[] = {
+    {ERR_REASON(OBJ_R_OID_EXISTS), "oid exists"},
+    {ERR_REASON(OBJ_R_UNKNOWN_NID), "unknown nid"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_OBJ_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(OBJ_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, OBJ_str_functs);
+        ERR_load_strings(0, OBJ_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_lcl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_lcl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_lcl.h	(revision 331)
@@ -0,0 +1,14 @@
+/*
+ * 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
+ */
+
+typedef struct name_funcs_st NAME_FUNCS;
+DEFINE_STACK_OF(NAME_FUNCS)
+DEFINE_LHASH_OF(OBJ_NAME);
+typedef struct added_obj_st ADDED_OBJ;
+DEFINE_LHASH_OF(ADDED_OBJ);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_lib.c	(revision 331)
@@ -0,0 +1,66 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include "internal/asn1_int.h"
+
+ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o)
+{
+    ASN1_OBJECT *r;
+
+    if (o == NULL)
+        return NULL;
+    /* If object isn't dynamic it's an internal OID which is never freed */
+    if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC))
+        return ((ASN1_OBJECT *)o);
+
+    r = ASN1_OBJECT_new();
+    if (r == NULL) {
+        OBJerr(OBJ_F_OBJ_DUP, ERR_R_ASN1_LIB);
+        return (NULL);
+    }
+
+    /* Set dynamic flags so everything gets freed up on error */
+
+    r->flags = o->flags | (ASN1_OBJECT_FLAG_DYNAMIC |
+                           ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
+                           ASN1_OBJECT_FLAG_DYNAMIC_DATA);
+
+    if (o->length > 0 && (r->data = OPENSSL_memdup(o->data, o->length)) == NULL)
+        goto err;
+
+    r->length = o->length;
+    r->nid = o->nid;
+
+    if (o->ln != NULL && (r->ln = OPENSSL_strdup(o->ln)) == NULL)
+        goto err;
+
+    if (o->sn != NULL && (r->sn = OPENSSL_strdup(o->sn)) == NULL)
+        goto err;
+
+    return r;
+ err:
+    ASN1_OBJECT_free(r);
+    OBJerr(OBJ_F_OBJ_DUP, ERR_R_MALLOC_FAILURE);
+    return NULL;
+}
+
+int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b)
+{
+    int ret;
+
+    ret = (a->length - b->length);
+    if (ret)
+        return (ret);
+    return (memcmp(a->data, b->data, a->length));
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_xref.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_xref.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_xref.c	(revision 331)
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2006-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 <openssl/objects.h>
+#include "obj_xref.h"
+#include "e_os.h"
+
+static STACK_OF(nid_triple) *sig_app, *sigx_app;
+
+static int sig_cmp(const nid_triple *a, const nid_triple *b)
+{
+    return a->sign_id - b->sign_id;
+}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig);
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig);
+
+static int sig_sk_cmp(const nid_triple *const *a, const nid_triple *const *b)
+{
+    return (*a)->sign_id - (*b)->sign_id;
+}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx);
+
+static int sigx_cmp(const nid_triple *const *a, const nid_triple *const *b)
+{
+    int ret;
+    ret = (*a)->hash_id - (*b)->hash_id;
+    if (ret)
+        return ret;
+    return (*a)->pkey_id - (*b)->pkey_id;
+}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx);
+
+int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid)
+{
+    nid_triple tmp;
+    const nid_triple *rv = NULL;
+    tmp.sign_id = signid;
+
+    if (sig_app) {
+        int idx = sk_nid_triple_find(sig_app, &tmp);
+        if (idx >= 0)
+            rv = sk_nid_triple_value(sig_app, idx);
+    }
+#ifndef OBJ_XREF_TEST2
+    if (rv == NULL) {
+        rv = OBJ_bsearch_sig(&tmp, sigoid_srt, OSSL_NELEM(sigoid_srt));
+    }
+#endif
+    if (rv == NULL)
+        return 0;
+    if (pdig_nid)
+        *pdig_nid = rv->hash_id;
+    if (ppkey_nid)
+        *ppkey_nid = rv->pkey_id;
+    return 1;
+}
+
+int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid)
+{
+    nid_triple tmp;
+    const nid_triple *t = &tmp;
+    const nid_triple **rv = NULL;
+
+    tmp.hash_id = dig_nid;
+    tmp.pkey_id = pkey_nid;
+
+    if (sigx_app) {
+        int idx = sk_nid_triple_find(sigx_app, &tmp);
+        if (idx >= 0) {
+            t = sk_nid_triple_value(sigx_app, idx);
+            rv = &t;
+        }
+    }
+#ifndef OBJ_XREF_TEST2
+    if (rv == NULL) {
+        rv = OBJ_bsearch_sigx(&t, sigoid_srt_xref, OSSL_NELEM(sigoid_srt_xref));
+    }
+#endif
+    if (rv == NULL)
+        return 0;
+    if (psignid)
+        *psignid = (*rv)->sign_id;
+    return 1;
+}
+
+int OBJ_add_sigid(int signid, int dig_id, int pkey_id)
+{
+    nid_triple *ntr;
+    if (sig_app == NULL)
+        sig_app = sk_nid_triple_new(sig_sk_cmp);
+    if (sig_app == NULL)
+        return 0;
+    if (sigx_app == NULL)
+        sigx_app = sk_nid_triple_new(sigx_cmp);
+    if (sigx_app == NULL)
+        return 0;
+    ntr = OPENSSL_malloc(sizeof(*ntr));
+    if (ntr == NULL)
+        return 0;
+    ntr->sign_id = signid;
+    ntr->hash_id = dig_id;
+    ntr->pkey_id = pkey_id;
+
+    if (!sk_nid_triple_push(sig_app, ntr)) {
+        OPENSSL_free(ntr);
+        return 0;
+    }
+
+    if (!sk_nid_triple_push(sigx_app, ntr))
+        return 0;
+
+    sk_nid_triple_sort(sig_app);
+    sk_nid_triple_sort(sigx_app);
+
+    return 1;
+}
+
+static void sid_free(nid_triple *tt)
+{
+    OPENSSL_free(tt);
+}
+
+void OBJ_sigid_free(void)
+{
+    sk_nid_triple_pop_free(sig_app, sid_free);
+    sig_app = NULL;
+    sk_nid_triple_free(sigx_app);
+    sigx_app = NULL;
+}
+
+#ifdef OBJ_XREF_TEST
+
+main()
+{
+    int n1, n2, n3;
+
+    int i, rv;
+# ifdef OBJ_XREF_TEST2
+    for (i = 0; i < OSSL_NELEM(sigoid_srt); i++) {
+        OBJ_add_sigid(sigoid_srt[i][0], sigoid_srt[i][1], sigoid_srt[i][2]);
+    }
+# endif
+
+    for (i = 0; i < OSSL_NELEM(sigoid_srt); i++) {
+        n1 = sigoid_srt[i][0];
+        rv = OBJ_find_sigid_algs(n1, &n2, &n3);
+        printf("Forward: %d, %s %s %s\n", rv,
+               OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3));
+        n1 = 0;
+        rv = OBJ_find_sigid_by_algs(&n1, n2, n3);
+        printf("Reverse: %d, %s %s %s\n", rv,
+               OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3));
+    }
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_xref.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_xref.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/objects/obj_xref.h	(revision 331)
@@ -0,0 +1,118 @@
+/*
+ * WARNING: do not edit!
+ * Generated by objxref.pl
+ *
+ * Copyright 1998-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
+ */
+
+
+typedef struct {
+    int sign_id;
+    int hash_id;
+    int pkey_id;
+} nid_triple;
+
+DEFINE_STACK_OF(nid_triple)
+
+static const nid_triple sigoid_srt[] = {
+    {NID_md2WithRSAEncryption, NID_md2, NID_rsaEncryption},
+    {NID_md5WithRSAEncryption, NID_md5, NID_rsaEncryption},
+    {NID_shaWithRSAEncryption, NID_sha, NID_rsaEncryption},
+    {NID_sha1WithRSAEncryption, NID_sha1, NID_rsaEncryption},
+    {NID_dsaWithSHA, NID_sha, NID_dsa},
+    {NID_dsaWithSHA1_2, NID_sha1, NID_dsa_2},
+    {NID_mdc2WithRSA, NID_mdc2, NID_rsaEncryption},
+    {NID_md5WithRSA, NID_md5, NID_rsa},
+    {NID_dsaWithSHA1, NID_sha1, NID_dsa},
+    {NID_sha1WithRSA, NID_sha1, NID_rsa},
+    {NID_ripemd160WithRSA, NID_ripemd160, NID_rsaEncryption},
+    {NID_md4WithRSAEncryption, NID_md4, NID_rsaEncryption},
+    {NID_ecdsa_with_SHA1, NID_sha1, NID_X9_62_id_ecPublicKey},
+    {NID_sha256WithRSAEncryption, NID_sha256, NID_rsaEncryption},
+    {NID_sha384WithRSAEncryption, NID_sha384, NID_rsaEncryption},
+    {NID_sha512WithRSAEncryption, NID_sha512, NID_rsaEncryption},
+    {NID_sha224WithRSAEncryption, NID_sha224, NID_rsaEncryption},
+    {NID_ecdsa_with_Recommended, NID_undef, NID_X9_62_id_ecPublicKey},
+    {NID_ecdsa_with_Specified, NID_undef, NID_X9_62_id_ecPublicKey},
+    {NID_ecdsa_with_SHA224, NID_sha224, NID_X9_62_id_ecPublicKey},
+    {NID_ecdsa_with_SHA256, NID_sha256, NID_X9_62_id_ecPublicKey},
+    {NID_ecdsa_with_SHA384, NID_sha384, NID_X9_62_id_ecPublicKey},
+    {NID_ecdsa_with_SHA512, NID_sha512, NID_X9_62_id_ecPublicKey},
+    {NID_dsa_with_SHA224, NID_sha224, NID_dsa},
+    {NID_dsa_with_SHA256, NID_sha256, NID_dsa},
+    {NID_id_GostR3411_94_with_GostR3410_2001, NID_id_GostR3411_94,
+     NID_id_GostR3410_2001},
+    {NID_id_GostR3411_94_with_GostR3410_94, NID_id_GostR3411_94,
+     NID_id_GostR3410_94},
+    {NID_id_GostR3411_94_with_GostR3410_94_cc, NID_id_GostR3411_94,
+     NID_id_GostR3410_94_cc},
+    {NID_id_GostR3411_94_with_GostR3410_2001_cc, NID_id_GostR3411_94,
+     NID_id_GostR3410_2001_cc},
+    {NID_rsassaPss, NID_undef, NID_rsaEncryption},
+    {NID_dhSinglePass_stdDH_sha1kdf_scheme, NID_sha1, NID_dh_std_kdf},
+    {NID_dhSinglePass_stdDH_sha224kdf_scheme, NID_sha224, NID_dh_std_kdf},
+    {NID_dhSinglePass_stdDH_sha256kdf_scheme, NID_sha256, NID_dh_std_kdf},
+    {NID_dhSinglePass_stdDH_sha384kdf_scheme, NID_sha384, NID_dh_std_kdf},
+    {NID_dhSinglePass_stdDH_sha512kdf_scheme, NID_sha512, NID_dh_std_kdf},
+    {NID_dhSinglePass_cofactorDH_sha1kdf_scheme, NID_sha1,
+     NID_dh_cofactor_kdf},
+    {NID_dhSinglePass_cofactorDH_sha224kdf_scheme, NID_sha224,
+     NID_dh_cofactor_kdf},
+    {NID_dhSinglePass_cofactorDH_sha256kdf_scheme, NID_sha256,
+     NID_dh_cofactor_kdf},
+    {NID_dhSinglePass_cofactorDH_sha384kdf_scheme, NID_sha384,
+     NID_dh_cofactor_kdf},
+    {NID_dhSinglePass_cofactorDH_sha512kdf_scheme, NID_sha512,
+     NID_dh_cofactor_kdf},
+    {NID_id_tc26_signwithdigest_gost3410_2012_256, NID_id_GostR3411_2012_256,
+     NID_id_GostR3410_2012_256},
+    {NID_id_tc26_signwithdigest_gost3410_2012_512, NID_id_GostR3411_2012_512,
+     NID_id_GostR3410_2012_512},
+};
+
+static const nid_triple *const sigoid_srt_xref[] = {
+    &sigoid_srt[0],
+    &sigoid_srt[1],
+    &sigoid_srt[7],
+    &sigoid_srt[2],
+    &sigoid_srt[4],
+    &sigoid_srt[3],
+    &sigoid_srt[9],
+    &sigoid_srt[5],
+    &sigoid_srt[8],
+    &sigoid_srt[12],
+    &sigoid_srt[30],
+    &sigoid_srt[35],
+    &sigoid_srt[6],
+    &sigoid_srt[10],
+    &sigoid_srt[11],
+    &sigoid_srt[13],
+    &sigoid_srt[24],
+    &sigoid_srt[20],
+    &sigoid_srt[32],
+    &sigoid_srt[37],
+    &sigoid_srt[14],
+    &sigoid_srt[21],
+    &sigoid_srt[33],
+    &sigoid_srt[38],
+    &sigoid_srt[15],
+    &sigoid_srt[22],
+    &sigoid_srt[34],
+    &sigoid_srt[39],
+    &sigoid_srt[16],
+    &sigoid_srt[23],
+    &sigoid_srt[19],
+    &sigoid_srt[31],
+    &sigoid_srt[36],
+    &sigoid_srt[25],
+    &sigoid_srt[26],
+    &sigoid_srt[27],
+    &sigoid_srt[28],
+    &sigoid_srt[40],
+    &sigoid_srt[41],
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_asn.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_asn.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_asn.c	(revision 331)
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2000-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 <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/ocsp.h>
+#include "ocsp_lcl.h"
+
+ASN1_SEQUENCE(OCSP_SIGNATURE) = {
+        ASN1_EMBED(OCSP_SIGNATURE, signatureAlgorithm, X509_ALGOR),
+        ASN1_SIMPLE(OCSP_SIGNATURE, signature, ASN1_BIT_STRING),
+        ASN1_EXP_SEQUENCE_OF_OPT(OCSP_SIGNATURE, certs, X509, 0)
+} ASN1_SEQUENCE_END(OCSP_SIGNATURE)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_SIGNATURE)
+
+ASN1_SEQUENCE(OCSP_CERTID) = {
+        ASN1_EMBED(OCSP_CERTID, hashAlgorithm, X509_ALGOR),
+        ASN1_EMBED(OCSP_CERTID, issuerNameHash, ASN1_OCTET_STRING),
+        ASN1_EMBED(OCSP_CERTID, issuerKeyHash, ASN1_OCTET_STRING),
+        ASN1_EMBED(OCSP_CERTID, serialNumber, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(OCSP_CERTID)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_CERTID)
+
+ASN1_SEQUENCE(OCSP_ONEREQ) = {
+        ASN1_SIMPLE(OCSP_ONEREQ, reqCert, OCSP_CERTID),
+        ASN1_EXP_SEQUENCE_OF_OPT(OCSP_ONEREQ, singleRequestExtensions, X509_EXTENSION, 0)
+} ASN1_SEQUENCE_END(OCSP_ONEREQ)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_ONEREQ)
+
+ASN1_SEQUENCE(OCSP_REQINFO) = {
+        ASN1_EXP_OPT(OCSP_REQINFO, version, ASN1_INTEGER, 0),
+        ASN1_EXP_OPT(OCSP_REQINFO, requestorName, GENERAL_NAME, 1),
+        ASN1_SEQUENCE_OF(OCSP_REQINFO, requestList, OCSP_ONEREQ),
+        ASN1_EXP_SEQUENCE_OF_OPT(OCSP_REQINFO, requestExtensions, X509_EXTENSION, 2)
+} ASN1_SEQUENCE_END(OCSP_REQINFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_REQINFO)
+
+ASN1_SEQUENCE(OCSP_REQUEST) = {
+        ASN1_EMBED(OCSP_REQUEST, tbsRequest, OCSP_REQINFO),
+        ASN1_EXP_OPT(OCSP_REQUEST, optionalSignature, OCSP_SIGNATURE, 0)
+} ASN1_SEQUENCE_END(OCSP_REQUEST)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_REQUEST)
+
+/* OCSP_RESPONSE templates */
+
+ASN1_SEQUENCE(OCSP_RESPBYTES) = {
+            ASN1_SIMPLE(OCSP_RESPBYTES, responseType, ASN1_OBJECT),
+            ASN1_SIMPLE(OCSP_RESPBYTES, response, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(OCSP_RESPBYTES)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPBYTES)
+
+ASN1_SEQUENCE(OCSP_RESPONSE) = {
+        ASN1_SIMPLE(OCSP_RESPONSE, responseStatus, ASN1_ENUMERATED),
+        ASN1_EXP_OPT(OCSP_RESPONSE, responseBytes, OCSP_RESPBYTES, 0)
+} ASN1_SEQUENCE_END(OCSP_RESPONSE)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPONSE)
+
+ASN1_CHOICE(OCSP_RESPID) = {
+           ASN1_EXP(OCSP_RESPID, value.byName, X509_NAME, 1),
+           ASN1_EXP(OCSP_RESPID, value.byKey, ASN1_OCTET_STRING, 2)
+} ASN1_CHOICE_END(OCSP_RESPID)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPID)
+
+ASN1_SEQUENCE(OCSP_REVOKEDINFO) = {
+        ASN1_SIMPLE(OCSP_REVOKEDINFO, revocationTime, ASN1_GENERALIZEDTIME),
+        ASN1_EXP_OPT(OCSP_REVOKEDINFO, revocationReason, ASN1_ENUMERATED, 0)
+} ASN1_SEQUENCE_END(OCSP_REVOKEDINFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_REVOKEDINFO)
+
+ASN1_CHOICE(OCSP_CERTSTATUS) = {
+        ASN1_IMP(OCSP_CERTSTATUS, value.good, ASN1_NULL, 0),
+        ASN1_IMP(OCSP_CERTSTATUS, value.revoked, OCSP_REVOKEDINFO, 1),
+        ASN1_IMP(OCSP_CERTSTATUS, value.unknown, ASN1_NULL, 2)
+} ASN1_CHOICE_END(OCSP_CERTSTATUS)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_CERTSTATUS)
+
+ASN1_SEQUENCE(OCSP_SINGLERESP) = {
+           ASN1_SIMPLE(OCSP_SINGLERESP, certId, OCSP_CERTID),
+           ASN1_SIMPLE(OCSP_SINGLERESP, certStatus, OCSP_CERTSTATUS),
+           ASN1_SIMPLE(OCSP_SINGLERESP, thisUpdate, ASN1_GENERALIZEDTIME),
+           ASN1_EXP_OPT(OCSP_SINGLERESP, nextUpdate, ASN1_GENERALIZEDTIME, 0),
+           ASN1_EXP_SEQUENCE_OF_OPT(OCSP_SINGLERESP, singleExtensions, X509_EXTENSION, 1)
+} ASN1_SEQUENCE_END(OCSP_SINGLERESP)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_SINGLERESP)
+
+ASN1_SEQUENCE(OCSP_RESPDATA) = {
+           ASN1_EXP_OPT(OCSP_RESPDATA, version, ASN1_INTEGER, 0),
+           ASN1_EMBED(OCSP_RESPDATA, responderId, OCSP_RESPID),
+           ASN1_SIMPLE(OCSP_RESPDATA, producedAt, ASN1_GENERALIZEDTIME),
+           ASN1_SEQUENCE_OF(OCSP_RESPDATA, responses, OCSP_SINGLERESP),
+           ASN1_EXP_SEQUENCE_OF_OPT(OCSP_RESPDATA, responseExtensions, X509_EXTENSION, 1)
+} ASN1_SEQUENCE_END(OCSP_RESPDATA)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPDATA)
+
+ASN1_SEQUENCE(OCSP_BASICRESP) = {
+           ASN1_EMBED(OCSP_BASICRESP, tbsResponseData, OCSP_RESPDATA),
+           ASN1_EMBED(OCSP_BASICRESP, signatureAlgorithm, X509_ALGOR),
+           ASN1_SIMPLE(OCSP_BASICRESP, signature, ASN1_BIT_STRING),
+           ASN1_EXP_SEQUENCE_OF_OPT(OCSP_BASICRESP, certs, X509, 0)
+} ASN1_SEQUENCE_END(OCSP_BASICRESP)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_BASICRESP)
+
+ASN1_SEQUENCE(OCSP_CRLID) = {
+           ASN1_EXP_OPT(OCSP_CRLID, crlUrl, ASN1_IA5STRING, 0),
+           ASN1_EXP_OPT(OCSP_CRLID, crlNum, ASN1_INTEGER, 1),
+           ASN1_EXP_OPT(OCSP_CRLID, crlTime, ASN1_GENERALIZEDTIME, 2)
+} ASN1_SEQUENCE_END(OCSP_CRLID)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_CRLID)
+
+ASN1_SEQUENCE(OCSP_SERVICELOC) = {
+        ASN1_SIMPLE(OCSP_SERVICELOC, issuer, X509_NAME),
+        ASN1_SEQUENCE_OF_OPT(OCSP_SERVICELOC, locator, ACCESS_DESCRIPTION)
+} ASN1_SEQUENCE_END(OCSP_SERVICELOC)
+
+IMPLEMENT_ASN1_FUNCTIONS(OCSP_SERVICELOC)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_cl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_cl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_cl.c	(revision 331)
@@ -0,0 +1,365 @@
+/*
+ * Copyright 2001-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 <stdio.h>
+#include <time.h>
+#include "internal/cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/ocsp.h>
+#include "ocsp_lcl.h"
+
+/*
+ * Utility functions related to sending OCSP requests and extracting relevant
+ * information from the response.
+ */
+
+/*
+ * Add an OCSP_CERTID to an OCSP request. Return new OCSP_ONEREQ pointer:
+ * useful if we want to add extensions.
+ */
+
+OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid)
+{
+    OCSP_ONEREQ *one = NULL;
+
+    if ((one = OCSP_ONEREQ_new()) == NULL)
+        return NULL;
+    OCSP_CERTID_free(one->reqCert);
+    one->reqCert = cid;
+    if (req && !sk_OCSP_ONEREQ_push(req->tbsRequest.requestList, one)) {
+        one->reqCert = NULL; /* do not free on error */
+        goto err;
+    }
+    return one;
+ err:
+    OCSP_ONEREQ_free(one);
+    return NULL;
+}
+
+/* Set requestorName from an X509_NAME structure */
+
+int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm)
+{
+    GENERAL_NAME *gen;
+
+    gen = GENERAL_NAME_new();
+    if (gen == NULL)
+        return 0;
+    if (!X509_NAME_set(&gen->d.directoryName, nm)) {
+        GENERAL_NAME_free(gen);
+        return 0;
+    }
+    gen->type = GEN_DIRNAME;
+    GENERAL_NAME_free(req->tbsRequest.requestorName);
+    req->tbsRequest.requestorName = gen;
+    return 1;
+}
+
+/* Add a certificate to an OCSP request */
+
+int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert)
+{
+    OCSP_SIGNATURE *sig;
+    if (req->optionalSignature == NULL)
+        req->optionalSignature = OCSP_SIGNATURE_new();
+    sig = req->optionalSignature;
+    if (sig == NULL)
+        return 0;
+    if (cert == NULL)
+        return 1;
+    if (sig->certs == NULL
+        && (sig->certs = sk_X509_new_null()) == NULL)
+        return 0;
+
+    if (!sk_X509_push(sig->certs, cert))
+        return 0;
+    X509_up_ref(cert);
+    return 1;
+}
+
+/*
+ * Sign an OCSP request set the requestorName to the subject name of an
+ * optional signers certificate and include one or more optional certificates
+ * in the request. Behaves like PKCS7_sign().
+ */
+
+int OCSP_request_sign(OCSP_REQUEST *req,
+                      X509 *signer,
+                      EVP_PKEY *key,
+                      const EVP_MD *dgst,
+                      STACK_OF(X509) *certs, unsigned long flags)
+{
+    int i;
+    X509 *x;
+
+    if (!OCSP_request_set1_name(req, X509_get_subject_name(signer)))
+        goto err;
+
+    if ((req->optionalSignature = OCSP_SIGNATURE_new()) == NULL)
+        goto err;
+    if (key) {
+        if (!X509_check_private_key(signer, key)) {
+            OCSPerr(OCSP_F_OCSP_REQUEST_SIGN,
+                    OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+            goto err;
+        }
+        if (!OCSP_REQUEST_sign(req, key, dgst))
+            goto err;
+    }
+
+    if (!(flags & OCSP_NOCERTS)) {
+        if (!OCSP_request_add1_cert(req, signer))
+            goto err;
+        for (i = 0; i < sk_X509_num(certs); i++) {
+            x = sk_X509_value(certs, i);
+            if (!OCSP_request_add1_cert(req, x))
+                goto err;
+        }
+    }
+
+    return 1;
+ err:
+    OCSP_SIGNATURE_free(req->optionalSignature);
+    req->optionalSignature = NULL;
+    return 0;
+}
+
+/* Get response status */
+
+int OCSP_response_status(OCSP_RESPONSE *resp)
+{
+    return ASN1_ENUMERATED_get(resp->responseStatus);
+}
+
+/*
+ * Extract basic response from OCSP_RESPONSE or NULL if no basic response
+ * present.
+ */
+
+OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp)
+{
+    OCSP_RESPBYTES *rb;
+    rb = resp->responseBytes;
+    if (!rb) {
+        OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NO_RESPONSE_DATA);
+        return NULL;
+    }
+    if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) {
+        OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NOT_BASIC_RESPONSE);
+        return NULL;
+    }
+
+    return ASN1_item_unpack(rb->response, ASN1_ITEM_rptr(OCSP_BASICRESP));
+}
+
+const ASN1_OCTET_STRING *OCSP_resp_get0_signature(const OCSP_BASICRESP *bs)
+{
+    return bs->signature;
+}
+
+/*
+ * Return number of OCSP_SINGLERESP responses present in a basic response.
+ */
+
+int OCSP_resp_count(OCSP_BASICRESP *bs)
+{
+    if (!bs)
+        return -1;
+    return sk_OCSP_SINGLERESP_num(bs->tbsResponseData.responses);
+}
+
+/* Extract an OCSP_SINGLERESP response with a given index */
+
+OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx)
+{
+    if (!bs)
+        return NULL;
+    return sk_OCSP_SINGLERESP_value(bs->tbsResponseData.responses, idx);
+}
+
+const ASN1_GENERALIZEDTIME *OCSP_resp_get0_produced_at(const OCSP_BASICRESP* bs)
+{
+    return bs->tbsResponseData.producedAt;
+}
+
+const STACK_OF(X509) *OCSP_resp_get0_certs(const OCSP_BASICRESP *bs)
+{
+    return bs->certs;
+}
+
+int OCSP_resp_get0_id(const OCSP_BASICRESP *bs,
+                      const ASN1_OCTET_STRING **pid,
+                      const X509_NAME **pname)
+
+{
+    const OCSP_RESPID *rid = &bs->tbsResponseData.responderId;
+    if (rid->type == V_OCSP_RESPID_NAME) {
+        *pname = rid->value.byName;
+        *pid = NULL;
+    } else if (rid->type == V_OCSP_RESPID_KEY) {
+        *pid = rid->value.byKey;
+        *pname = NULL;
+    } else {
+        return 0;
+    }
+    return 1;
+}
+
+/* Look single response matching a given certificate ID */
+
+int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last)
+{
+    int i;
+    STACK_OF(OCSP_SINGLERESP) *sresp;
+    OCSP_SINGLERESP *single;
+    if (!bs)
+        return -1;
+    if (last < 0)
+        last = 0;
+    else
+        last++;
+    sresp = bs->tbsResponseData.responses;
+    for (i = last; i < sk_OCSP_SINGLERESP_num(sresp); i++) {
+        single = sk_OCSP_SINGLERESP_value(sresp, i);
+        if (!OCSP_id_cmp(id, single->certId))
+            return i;
+    }
+    return -1;
+}
+
+/*
+ * Extract status information from an OCSP_SINGLERESP structure. Note: the
+ * revtime and reason values are only set if the certificate status is
+ * revoked. Returns numerical value of status.
+ */
+
+int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason,
+                            ASN1_GENERALIZEDTIME **revtime,
+                            ASN1_GENERALIZEDTIME **thisupd,
+                            ASN1_GENERALIZEDTIME **nextupd)
+{
+    int ret;
+    OCSP_CERTSTATUS *cst;
+    if (!single)
+        return -1;
+    cst = single->certStatus;
+    ret = cst->type;
+    if (ret == V_OCSP_CERTSTATUS_REVOKED) {
+        OCSP_REVOKEDINFO *rev = cst->value.revoked;
+        if (revtime)
+            *revtime = rev->revocationTime;
+        if (reason) {
+            if (rev->revocationReason)
+                *reason = ASN1_ENUMERATED_get(rev->revocationReason);
+            else
+                *reason = -1;
+        }
+    }
+    if (thisupd)
+        *thisupd = single->thisUpdate;
+    if (nextupd)
+        *nextupd = single->nextUpdate;
+    return ret;
+}
+
+/*
+ * This function combines the previous ones: look up a certificate ID and if
+ * found extract status information. Return 0 is successful.
+ */
+
+int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status,
+                          int *reason,
+                          ASN1_GENERALIZEDTIME **revtime,
+                          ASN1_GENERALIZEDTIME **thisupd,
+                          ASN1_GENERALIZEDTIME **nextupd)
+{
+    int i;
+    OCSP_SINGLERESP *single;
+    i = OCSP_resp_find(bs, id, -1);
+    /* Maybe check for multiple responses and give an error? */
+    if (i < 0)
+        return 0;
+    single = OCSP_resp_get0(bs, i);
+    i = OCSP_single_get0_status(single, reason, revtime, thisupd, nextupd);
+    if (status)
+        *status = i;
+    return 1;
+}
+
+/*
+ * Check validity of thisUpdate and nextUpdate fields. It is possible that
+ * the request will take a few seconds to process and/or the time won't be
+ * totally accurate. Therefore to avoid rejecting otherwise valid time we
+ * allow the times to be within 'nsec' of the current time. Also to avoid
+ * accepting very old responses without a nextUpdate field an optional maxage
+ * parameter specifies the maximum age the thisUpdate field can be.
+ */
+
+int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd,
+                        ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec)
+{
+    int ret = 1;
+    time_t t_now, t_tmp;
+    time(&t_now);
+    /* Check thisUpdate is valid and not more than nsec in the future */
+    if (!ASN1_GENERALIZEDTIME_check(thisupd)) {
+        OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_THISUPDATE_FIELD);
+        ret = 0;
+    } else {
+        t_tmp = t_now + nsec;
+        if (X509_cmp_time(thisupd, &t_tmp) > 0) {
+            OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_NOT_YET_VALID);
+            ret = 0;
+        }
+
+        /*
+         * If maxsec specified check thisUpdate is not more than maxsec in
+         * the past
+         */
+        if (maxsec >= 0) {
+            t_tmp = t_now - maxsec;
+            if (X509_cmp_time(thisupd, &t_tmp) < 0) {
+                OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_TOO_OLD);
+                ret = 0;
+            }
+        }
+    }
+
+    if (!nextupd)
+        return ret;
+
+    /* Check nextUpdate is valid and not more than nsec in the past */
+    if (!ASN1_GENERALIZEDTIME_check(nextupd)) {
+        OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD);
+        ret = 0;
+    } else {
+        t_tmp = t_now - nsec;
+        if (X509_cmp_time(nextupd, &t_tmp) < 0) {
+            OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_EXPIRED);
+            ret = 0;
+        }
+    }
+
+    /* Also don't allow nextUpdate to precede thisUpdate */
+    if (ASN1_STRING_cmp(nextupd, thisupd) < 0) {
+        OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY,
+                OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE);
+        ret = 0;
+    }
+
+    return ret;
+}
+
+const OCSP_CERTID *OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *single)
+{
+    return single->certId;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_err.c	(revision 331)
@@ -0,0 +1,91 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/ocsp.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_OCSP,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_OCSP,0,reason)
+
+static ERR_STRING_DATA OCSP_str_functs[] = {
+    {ERR_FUNC(OCSP_F_D2I_OCSP_NONCE), "d2i_ocsp_nonce"},
+    {ERR_FUNC(OCSP_F_OCSP_BASIC_ADD1_STATUS), "OCSP_basic_add1_status"},
+    {ERR_FUNC(OCSP_F_OCSP_BASIC_SIGN), "OCSP_basic_sign"},
+    {ERR_FUNC(OCSP_F_OCSP_BASIC_VERIFY), "OCSP_basic_verify"},
+    {ERR_FUNC(OCSP_F_OCSP_CERT_ID_NEW), "OCSP_cert_id_new"},
+    {ERR_FUNC(OCSP_F_OCSP_CHECK_DELEGATED), "ocsp_check_delegated"},
+    {ERR_FUNC(OCSP_F_OCSP_CHECK_IDS), "ocsp_check_ids"},
+    {ERR_FUNC(OCSP_F_OCSP_CHECK_ISSUER), "ocsp_check_issuer"},
+    {ERR_FUNC(OCSP_F_OCSP_CHECK_VALIDITY), "OCSP_check_validity"},
+    {ERR_FUNC(OCSP_F_OCSP_MATCH_ISSUERID), "ocsp_match_issuerid"},
+    {ERR_FUNC(OCSP_F_OCSP_PARSE_URL), "OCSP_parse_url"},
+    {ERR_FUNC(OCSP_F_OCSP_REQUEST_SIGN), "OCSP_request_sign"},
+    {ERR_FUNC(OCSP_F_OCSP_REQUEST_VERIFY), "OCSP_request_verify"},
+    {ERR_FUNC(OCSP_F_OCSP_RESPONSE_GET1_BASIC), "OCSP_response_get1_basic"},
+    {ERR_FUNC(OCSP_F_PARSE_HTTP_LINE1), "parse_http_line1"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA OCSP_str_reasons[] = {
+    {ERR_REASON(OCSP_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"},
+    {ERR_REASON(OCSP_R_DIGEST_ERR), "digest err"},
+    {ERR_REASON(OCSP_R_ERROR_IN_NEXTUPDATE_FIELD),
+     "error in nextupdate field"},
+    {ERR_REASON(OCSP_R_ERROR_IN_THISUPDATE_FIELD),
+     "error in thisupdate field"},
+    {ERR_REASON(OCSP_R_ERROR_PARSING_URL), "error parsing url"},
+    {ERR_REASON(OCSP_R_MISSING_OCSPSIGNING_USAGE),
+     "missing ocspsigning usage"},
+    {ERR_REASON(OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE),
+     "nextupdate before thisupdate"},
+    {ERR_REASON(OCSP_R_NOT_BASIC_RESPONSE), "not basic response"},
+    {ERR_REASON(OCSP_R_NO_CERTIFICATES_IN_CHAIN), "no certificates in chain"},
+    {ERR_REASON(OCSP_R_NO_RESPONSE_DATA), "no response data"},
+    {ERR_REASON(OCSP_R_NO_REVOKED_TIME), "no revoked time"},
+    {ERR_REASON(OCSP_R_NO_SIGNER_KEY), "no signer key"},
+    {ERR_REASON(OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),
+     "private key does not match certificate"},
+    {ERR_REASON(OCSP_R_REQUEST_NOT_SIGNED), "request not signed"},
+    {ERR_REASON(OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA),
+     "response contains no revocation data"},
+    {ERR_REASON(OCSP_R_ROOT_CA_NOT_TRUSTED), "root ca not trusted"},
+    {ERR_REASON(OCSP_R_SERVER_RESPONSE_ERROR), "server response error"},
+    {ERR_REASON(OCSP_R_SERVER_RESPONSE_PARSE_ERROR),
+     "server response parse error"},
+    {ERR_REASON(OCSP_R_SIGNATURE_FAILURE), "signature failure"},
+    {ERR_REASON(OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND),
+     "signer certificate not found"},
+    {ERR_REASON(OCSP_R_STATUS_EXPIRED), "status expired"},
+    {ERR_REASON(OCSP_R_STATUS_NOT_YET_VALID), "status not yet valid"},
+    {ERR_REASON(OCSP_R_STATUS_TOO_OLD), "status too old"},
+    {ERR_REASON(OCSP_R_UNKNOWN_MESSAGE_DIGEST), "unknown message digest"},
+    {ERR_REASON(OCSP_R_UNKNOWN_NID), "unknown nid"},
+    {ERR_REASON(OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE),
+     "unsupported requestorname type"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_OCSP_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(OCSP_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, OCSP_str_functs);
+        ERR_load_strings(0, OCSP_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_ext.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_ext.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_ext.c	(revision 331)
@@ -0,0 +1,472 @@
+/*
+ * Copyright 2000-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/ocsp.h>
+#include "ocsp_lcl.h"
+#include <openssl/rand.h>
+#include <openssl/x509v3.h>
+
+/* Standard wrapper functions for extensions */
+
+/* OCSP request extensions */
+
+int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x)
+{
+    return (X509v3_get_ext_count(x->tbsRequest.requestExtensions));
+}
+
+int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos)
+{
+    return (X509v3_get_ext_by_NID
+            (x->tbsRequest.requestExtensions, nid, lastpos));
+}
+
+int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, const ASN1_OBJECT *obj,
+                                int lastpos)
+{
+    return (X509v3_get_ext_by_OBJ
+            (x->tbsRequest.requestExtensions, obj, lastpos));
+}
+
+int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos)
+{
+    return (X509v3_get_ext_by_critical
+            (x->tbsRequest.requestExtensions, crit, lastpos));
+}
+
+X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc)
+{
+    return (X509v3_get_ext(x->tbsRequest.requestExtensions, loc));
+}
+
+X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc)
+{
+    return (X509v3_delete_ext(x->tbsRequest.requestExtensions, loc));
+}
+
+void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx)
+{
+    return X509V3_get_d2i(x->tbsRequest.requestExtensions, nid, crit, idx);
+}
+
+int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit,
+                              unsigned long flags)
+{
+    return X509V3_add1_i2d(&x->tbsRequest.requestExtensions, nid, value,
+                           crit, flags);
+}
+
+int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc)
+{
+    return (X509v3_add_ext(&(x->tbsRequest.requestExtensions), ex, loc) !=
+            NULL);
+}
+
+/* Single extensions */
+
+int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x)
+{
+    return (X509v3_get_ext_count(x->singleRequestExtensions));
+}
+
+int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos)
+{
+    return (X509v3_get_ext_by_NID(x->singleRequestExtensions, nid, lastpos));
+}
+
+int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, const ASN1_OBJECT *obj,
+                               int lastpos)
+{
+    return (X509v3_get_ext_by_OBJ(x->singleRequestExtensions, obj, lastpos));
+}
+
+int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos)
+{
+    return (X509v3_get_ext_by_critical
+            (x->singleRequestExtensions, crit, lastpos));
+}
+
+X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc)
+{
+    return (X509v3_get_ext(x->singleRequestExtensions, loc));
+}
+
+X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc)
+{
+    return (X509v3_delete_ext(x->singleRequestExtensions, loc));
+}
+
+void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx)
+{
+    return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx);
+}
+
+int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit,
+                             unsigned long flags)
+{
+    return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit,
+                           flags);
+}
+
+int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc)
+{
+    return (X509v3_add_ext(&(x->singleRequestExtensions), ex, loc) != NULL);
+}
+
+/* OCSP Basic response */
+
+int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x)
+{
+    return (X509v3_get_ext_count(x->tbsResponseData.responseExtensions));
+}
+
+int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos)
+{
+    return (X509v3_get_ext_by_NID
+            (x->tbsResponseData.responseExtensions, nid, lastpos));
+}
+
+int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, const ASN1_OBJECT *obj,
+                                  int lastpos)
+{
+    return (X509v3_get_ext_by_OBJ
+            (x->tbsResponseData.responseExtensions, obj, lastpos));
+}
+
+int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit,
+                                       int lastpos)
+{
+    return (X509v3_get_ext_by_critical
+            (x->tbsResponseData.responseExtensions, crit, lastpos));
+}
+
+X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc)
+{
+    return (X509v3_get_ext(x->tbsResponseData.responseExtensions, loc));
+}
+
+X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc)
+{
+    return (X509v3_delete_ext(x->tbsResponseData.responseExtensions, loc));
+}
+
+void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit,
+                                  int *idx)
+{
+    return X509V3_get_d2i(x->tbsResponseData.responseExtensions, nid, crit,
+                          idx);
+}
+
+int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value,
+                                int crit, unsigned long flags)
+{
+    return X509V3_add1_i2d(&x->tbsResponseData.responseExtensions, nid,
+                           value, crit, flags);
+}
+
+int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc)
+{
+    return (X509v3_add_ext(&(x->tbsResponseData.responseExtensions), ex, loc)
+            != NULL);
+}
+
+/* OCSP single response extensions */
+
+int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x)
+{
+    return (X509v3_get_ext_count(x->singleExtensions));
+}
+
+int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos)
+{
+    return (X509v3_get_ext_by_NID(x->singleExtensions, nid, lastpos));
+}
+
+int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, const ASN1_OBJECT *obj,
+                                   int lastpos)
+{
+    return (X509v3_get_ext_by_OBJ(x->singleExtensions, obj, lastpos));
+}
+
+int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit,
+                                        int lastpos)
+{
+    return (X509v3_get_ext_by_critical(x->singleExtensions, crit, lastpos));
+}
+
+X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc)
+{
+    return (X509v3_get_ext(x->singleExtensions, loc));
+}
+
+X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc)
+{
+    return (X509v3_delete_ext(x->singleExtensions, loc));
+}
+
+void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit,
+                                   int *idx)
+{
+    return X509V3_get_d2i(x->singleExtensions, nid, crit, idx);
+}
+
+int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value,
+                                 int crit, unsigned long flags)
+{
+    return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags);
+}
+
+int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc)
+{
+    return (X509v3_add_ext(&(x->singleExtensions), ex, loc) != NULL);
+}
+
+/* also CRL Entry Extensions */
+
+/* Nonce handling functions */
+
+/*
+ * Add a nonce to an extension stack. A nonce can be specified or if NULL a
+ * random nonce will be generated. Note: OpenSSL 0.9.7d and later create an
+ * OCTET STRING containing the nonce, previous versions used the raw nonce.
+ */
+
+static int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts,
+                           unsigned char *val, int len)
+{
+    unsigned char *tmpval;
+    ASN1_OCTET_STRING os;
+    int ret = 0;
+    if (len <= 0)
+        len = OCSP_DEFAULT_NONCE_LENGTH;
+    /*
+     * Create the OCTET STRING manually by writing out the header and
+     * appending the content octets. This avoids an extra memory allocation
+     * operation in some cases. Applications should *NOT* do this because it
+     * relies on library internals.
+     */
+    os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING);
+    if (os.length < 0)
+        return 0;
+
+    os.data = OPENSSL_malloc(os.length);
+    if (os.data == NULL)
+        goto err;
+    tmpval = os.data;
+    ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL);
+    if (val)
+        memcpy(tmpval, val, len);
+    else if (RAND_bytes(tmpval, len) <= 0)
+        goto err;
+    if (!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce,
+                         &os, 0, X509V3_ADD_REPLACE))
+        goto err;
+    ret = 1;
+ err:
+    OPENSSL_free(os.data);
+    return ret;
+}
+
+/* Add nonce to an OCSP request */
+
+int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len)
+{
+    return ocsp_add1_nonce(&req->tbsRequest.requestExtensions, val, len);
+}
+
+/* Same as above but for a response */
+
+int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len)
+{
+    return ocsp_add1_nonce(&resp->tbsResponseData.responseExtensions, val,
+                           len);
+}
+
+/*-
+ * Check nonce validity in a request and response.
+ * Return value reflects result:
+ *  1: nonces present and equal.
+ *  2: nonces both absent.
+ *  3: nonce present in response only.
+ *  0: nonces both present and not equal.
+ * -1: nonce in request only.
+ *
+ *  For most responders clients can check return > 0.
+ *  If responder doesn't handle nonces return != 0 may be
+ *  necessary. return == 0 is always an error.
+ */
+
+int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs)
+{
+    /*
+     * Since we are only interested in the presence or absence of
+     * the nonce and comparing its value there is no need to use
+     * the X509V3 routines: this way we can avoid them allocating an
+     * ASN1_OCTET_STRING structure for the value which would be
+     * freed immediately anyway.
+     */
+
+    int req_idx, resp_idx;
+    X509_EXTENSION *req_ext, *resp_ext;
+    req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
+    resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1);
+    /* Check both absent */
+    if ((req_idx < 0) && (resp_idx < 0))
+        return 2;
+    /* Check in request only */
+    if ((req_idx >= 0) && (resp_idx < 0))
+        return -1;
+    /* Check in response but not request */
+    if ((req_idx < 0) && (resp_idx >= 0))
+        return 3;
+    /*
+     * Otherwise nonce in request and response so retrieve the extensions
+     */
+    req_ext = OCSP_REQUEST_get_ext(req, req_idx);
+    resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx);
+    if (ASN1_OCTET_STRING_cmp(X509_EXTENSION_get_data(req_ext),
+                              X509_EXTENSION_get_data(resp_ext)))
+        return 0;
+    return 1;
+}
+
+/*
+ * Copy the nonce value (if any) from an OCSP request to a response.
+ */
+
+int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req)
+{
+    X509_EXTENSION *req_ext;
+    int req_idx;
+    /* Check for nonce in request */
+    req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
+    /* If no nonce that's OK */
+    if (req_idx < 0)
+        return 2;
+    req_ext = OCSP_REQUEST_get_ext(req, req_idx);
+    return OCSP_BASICRESP_add_ext(resp, req_ext, -1);
+}
+
+X509_EXTENSION *OCSP_crlID_new(const char *url, long *n, char *tim)
+{
+    X509_EXTENSION *x = NULL;
+    OCSP_CRLID *cid = NULL;
+
+    if ((cid = OCSP_CRLID_new()) == NULL)
+        goto err;
+    if (url) {
+        if ((cid->crlUrl = ASN1_IA5STRING_new()) == NULL)
+            goto err;
+        if (!(ASN1_STRING_set(cid->crlUrl, url, -1)))
+            goto err;
+    }
+    if (n) {
+        if ((cid->crlNum = ASN1_INTEGER_new()) == NULL)
+            goto err;
+        if (!(ASN1_INTEGER_set(cid->crlNum, *n)))
+            goto err;
+    }
+    if (tim) {
+        if ((cid->crlTime = ASN1_GENERALIZEDTIME_new()) == NULL)
+            goto err;
+        if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim)))
+            goto err;
+    }
+    x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid);
+ err:
+    OCSP_CRLID_free(cid);
+    return x;
+}
+
+/*   AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */
+X509_EXTENSION *OCSP_accept_responses_new(char **oids)
+{
+    int nid;
+    STACK_OF(ASN1_OBJECT) *sk = NULL;
+    ASN1_OBJECT *o = NULL;
+    X509_EXTENSION *x = NULL;
+
+    if ((sk = sk_ASN1_OBJECT_new_null()) == NULL)
+        goto err;
+    while (oids && *oids) {
+        if ((nid = OBJ_txt2nid(*oids)) != NID_undef && (o = OBJ_nid2obj(nid)))
+            sk_ASN1_OBJECT_push(sk, o);
+        oids++;
+    }
+    x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk);
+ err:
+    sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free);
+    return x;
+}
+
+/*  ArchiveCutoff ::= GeneralizedTime */
+X509_EXTENSION *OCSP_archive_cutoff_new(char *tim)
+{
+    X509_EXTENSION *x = NULL;
+    ASN1_GENERALIZEDTIME *gt = NULL;
+
+    if ((gt = ASN1_GENERALIZEDTIME_new()) == NULL)
+        goto err;
+    if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim)))
+        goto err;
+    x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt);
+ err:
+    ASN1_GENERALIZEDTIME_free(gt);
+    return x;
+}
+
+/*
+ * per ACCESS_DESCRIPTION parameter are oids, of which there are currently
+ * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value.  This method
+ * forces NID_ad_ocsp and uniformResourceLocator [6] IA5String.
+ */
+X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, const char **urls)
+{
+    X509_EXTENSION *x = NULL;
+    ASN1_IA5STRING *ia5 = NULL;
+    OCSP_SERVICELOC *sloc = NULL;
+    ACCESS_DESCRIPTION *ad = NULL;
+
+    if ((sloc = OCSP_SERVICELOC_new()) == NULL)
+        goto err;
+    if ((sloc->issuer = X509_NAME_dup(issuer)) == NULL)
+        goto err;
+    if (urls && *urls
+        && (sloc->locator = sk_ACCESS_DESCRIPTION_new_null()) == NULL)
+        goto err;
+    while (urls && *urls) {
+        if ((ad = ACCESS_DESCRIPTION_new()) == NULL)
+            goto err;
+        if ((ad->method = OBJ_nid2obj(NID_ad_OCSP)) == NULL)
+            goto err;
+        if ((ad->location = GENERAL_NAME_new()) == NULL)
+            goto err;
+        if ((ia5 = ASN1_IA5STRING_new()) == NULL)
+            goto err;
+        if (!ASN1_STRING_set((ASN1_STRING *)ia5, *urls, -1))
+            goto err;
+        ad->location->type = GEN_URI;
+        ad->location->d.ia5 = ia5;
+        ia5 = NULL;
+        if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad))
+            goto err;
+        ad = NULL;
+        urls++;
+    }
+    x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc);
+ err:
+    ASN1_IA5STRING_free(ia5);
+    ACCESS_DESCRIPTION_free(ad);
+    OCSP_SERVICELOC_free(sloc);
+    return x;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_ht.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_ht.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_ht.c	(revision 331)
@@ -0,0 +1,499 @@
+/*
+ * Copyright 2001-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 <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include "e_os.h"
+#include <openssl/asn1.h>
+#include <openssl/ocsp.h>
+#include <openssl/err.h>
+#include <openssl/buffer.h>
+
+/* Stateful OCSP request code, supporting non-blocking I/O */
+
+/* Opaque OCSP request status structure */
+
+struct ocsp_req_ctx_st {
+    int state;                  /* Current I/O state */
+    unsigned char *iobuf;       /* Line buffer */
+    int iobuflen;               /* Line buffer length */
+    BIO *io;                    /* BIO to perform I/O with */
+    BIO *mem;                   /* Memory BIO response is built into */
+    unsigned long asn1_len;     /* ASN1 length of response */
+    unsigned long max_resp_len; /* Maximum length of response */
+};
+
+#define OCSP_MAX_RESP_LENGTH    (100 * 1024)
+#define OCSP_MAX_LINE_LEN       4096;
+
+/* OCSP states */
+
+/* If set no reading should be performed */
+#define OHS_NOREAD              0x1000
+/* Error condition */
+#define OHS_ERROR               (0 | OHS_NOREAD)
+/* First line being read */
+#define OHS_FIRSTLINE           1
+/* MIME headers being read */
+#define OHS_HEADERS             2
+/* OCSP initial header (tag + length) being read */
+#define OHS_ASN1_HEADER         3
+/* OCSP content octets being read */
+#define OHS_ASN1_CONTENT        4
+/* First call: ready to start I/O */
+#define OHS_ASN1_WRITE_INIT     (5 | OHS_NOREAD)
+/* Request being sent */
+#define OHS_ASN1_WRITE          (6 | OHS_NOREAD)
+/* Request being flushed */
+#define OHS_ASN1_FLUSH          (7 | OHS_NOREAD)
+/* Completed */
+#define OHS_DONE                (8 | OHS_NOREAD)
+/* Headers set, no final \r\n included */
+#define OHS_HTTP_HEADER         (9 | OHS_NOREAD)
+
+static int parse_http_line1(char *line);
+
+OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *io, int maxline)
+{
+    OCSP_REQ_CTX *rctx = OPENSSL_zalloc(sizeof(*rctx));
+
+    if (rctx == NULL)
+        return NULL;
+    rctx->state = OHS_ERROR;
+    rctx->max_resp_len = OCSP_MAX_RESP_LENGTH;
+    rctx->mem = BIO_new(BIO_s_mem());
+    rctx->io = io;
+    if (maxline > 0)
+        rctx->iobuflen = maxline;
+    else
+        rctx->iobuflen = OCSP_MAX_LINE_LEN;
+    rctx->iobuf = OPENSSL_malloc(rctx->iobuflen);
+    if (rctx->iobuf == NULL || rctx->mem == NULL) {
+        OCSP_REQ_CTX_free(rctx);
+        return NULL;
+    }
+    return rctx;
+}
+
+void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx)
+{
+    if (!rctx)
+        return;
+    BIO_free(rctx->mem);
+    OPENSSL_free(rctx->iobuf);
+    OPENSSL_free(rctx);
+}
+
+BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx)
+{
+    return rctx->mem;
+}
+
+void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len)
+{
+    if (len == 0)
+        rctx->max_resp_len = OCSP_MAX_RESP_LENGTH;
+    else
+        rctx->max_resp_len = len;
+}
+
+int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it, ASN1_VALUE *val)
+{
+    static const char req_hdr[] =
+        "Content-Type: application/ocsp-request\r\n"
+        "Content-Length: %d\r\n\r\n";
+    int reqlen = ASN1_item_i2d(val, NULL, it);
+    if (BIO_printf(rctx->mem, req_hdr, reqlen) <= 0)
+        return 0;
+    if (ASN1_item_i2d_bio(it, rctx->mem, val) <= 0)
+        return 0;
+    rctx->state = OHS_ASN1_WRITE_INIT;
+    return 1;
+}
+
+int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx,
+                          ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    int rv, len;
+    const unsigned char *p;
+
+    rv = OCSP_REQ_CTX_nbio(rctx);
+    if (rv != 1)
+        return rv;
+
+    len = BIO_get_mem_data(rctx->mem, &p);
+    *pval = ASN1_item_d2i(NULL, &p, len, it);
+    if (*pval == NULL) {
+        rctx->state = OHS_ERROR;
+        return 0;
+    }
+    return 1;
+}
+
+int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, const char *op, const char *path)
+{
+    static const char http_hdr[] = "%s %s HTTP/1.0\r\n";
+
+    if (!path)
+        path = "/";
+
+    if (BIO_printf(rctx->mem, http_hdr, op, path) <= 0)
+        return 0;
+    rctx->state = OHS_HTTP_HEADER;
+    return 1;
+}
+
+int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req)
+{
+    return OCSP_REQ_CTX_i2d(rctx, ASN1_ITEM_rptr(OCSP_REQUEST),
+                            (ASN1_VALUE *)req);
+}
+
+int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx,
+                             const char *name, const char *value)
+{
+    if (!name)
+        return 0;
+    if (BIO_puts(rctx->mem, name) <= 0)
+        return 0;
+    if (value) {
+        if (BIO_write(rctx->mem, ": ", 2) != 2)
+            return 0;
+        if (BIO_puts(rctx->mem, value) <= 0)
+            return 0;
+    }
+    if (BIO_write(rctx->mem, "\r\n", 2) != 2)
+        return 0;
+    rctx->state = OHS_HTTP_HEADER;
+    return 1;
+}
+
+OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req,
+                               int maxline)
+{
+
+    OCSP_REQ_CTX *rctx = NULL;
+    rctx = OCSP_REQ_CTX_new(io, maxline);
+    if (rctx == NULL)
+        return NULL;
+
+    if (!OCSP_REQ_CTX_http(rctx, "POST", path))
+        goto err;
+
+    if (req && !OCSP_REQ_CTX_set1_req(rctx, req))
+        goto err;
+
+    return rctx;
+
+ err:
+    OCSP_REQ_CTX_free(rctx);
+    return NULL;
+}
+
+/*
+ * Parse the HTTP response. This will look like this: "HTTP/1.0 200 OK". We
+ * need to obtain the numeric code and (optional) informational message.
+ */
+
+static int parse_http_line1(char *line)
+{
+    int retcode;
+    char *p, *q, *r;
+    /* Skip to first white space (passed protocol info) */
+
+    for (p = line; *p && !isspace((unsigned char)*p); p++)
+        continue;
+    if (!*p) {
+        OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
+        return 0;
+    }
+
+    /* Skip past white space to start of response code */
+    while (*p && isspace((unsigned char)*p))
+        p++;
+
+    if (!*p) {
+        OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
+        return 0;
+    }
+
+    /* Find end of response code: first whitespace after start of code */
+    for (q = p; *q && !isspace((unsigned char)*q); q++)
+        continue;
+
+    if (!*q) {
+        OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
+        return 0;
+    }
+
+    /* Set end of response code and start of message */
+    *q++ = 0;
+
+    /* Attempt to parse numeric code */
+    retcode = strtoul(p, &r, 10);
+
+    if (*r)
+        return 0;
+
+    /* Skip over any leading white space in message */
+    while (*q && isspace((unsigned char)*q))
+        q++;
+
+    if (*q) {
+        /*
+         * Finally zap any trailing white space in message (include CRLF)
+         */
+
+        /* We know q has a non white space character so this is OK */
+        for (r = q + strlen(q) - 1; isspace((unsigned char)*r); r--)
+            *r = 0;
+    }
+    if (retcode != 200) {
+        OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_ERROR);
+        if (!*q)
+            ERR_add_error_data(2, "Code=", p);
+        else
+            ERR_add_error_data(4, "Code=", p, ",Reason=", q);
+        return 0;
+    }
+
+    return 1;
+
+}
+
+int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx)
+{
+    int i, n;
+    const unsigned char *p;
+ next_io:
+    if (!(rctx->state & OHS_NOREAD)) {
+        n = BIO_read(rctx->io, rctx->iobuf, rctx->iobuflen);
+
+        if (n <= 0) {
+            if (BIO_should_retry(rctx->io))
+                return -1;
+            return 0;
+        }
+
+        /* Write data to memory BIO */
+
+        if (BIO_write(rctx->mem, rctx->iobuf, n) != n)
+            return 0;
+    }
+
+    switch (rctx->state) {
+    case OHS_HTTP_HEADER:
+        /* Last operation was adding headers: need a final \r\n */
+        if (BIO_write(rctx->mem, "\r\n", 2) != 2) {
+            rctx->state = OHS_ERROR;
+            return 0;
+        }
+        rctx->state = OHS_ASN1_WRITE_INIT;
+
+    case OHS_ASN1_WRITE_INIT:
+        rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL);
+        rctx->state = OHS_ASN1_WRITE;
+
+    case OHS_ASN1_WRITE:
+        n = BIO_get_mem_data(rctx->mem, &p);
+
+        i = BIO_write(rctx->io, p + (n - rctx->asn1_len), rctx->asn1_len);
+
+        if (i <= 0) {
+            if (BIO_should_retry(rctx->io))
+                return -1;
+            rctx->state = OHS_ERROR;
+            return 0;
+        }
+
+        rctx->asn1_len -= i;
+
+        if (rctx->asn1_len > 0)
+            goto next_io;
+
+        rctx->state = OHS_ASN1_FLUSH;
+
+        (void)BIO_reset(rctx->mem);
+
+    case OHS_ASN1_FLUSH:
+
+        i = BIO_flush(rctx->io);
+
+        if (i > 0) {
+            rctx->state = OHS_FIRSTLINE;
+            goto next_io;
+        }
+
+        if (BIO_should_retry(rctx->io))
+            return -1;
+
+        rctx->state = OHS_ERROR;
+        return 0;
+
+    case OHS_ERROR:
+        return 0;
+
+    case OHS_FIRSTLINE:
+    case OHS_HEADERS:
+
+        /* Attempt to read a line in */
+
+ next_line:
+        /*
+         * Due to &%^*$" memory BIO behaviour with BIO_gets we have to check
+         * there's a complete line in there before calling BIO_gets or we'll
+         * just get a partial read.
+         */
+        n = BIO_get_mem_data(rctx->mem, &p);
+        if ((n <= 0) || !memchr(p, '\n', n)) {
+            if (n >= rctx->iobuflen) {
+                rctx->state = OHS_ERROR;
+                return 0;
+            }
+            goto next_io;
+        }
+        n = BIO_gets(rctx->mem, (char *)rctx->iobuf, rctx->iobuflen);
+
+        if (n <= 0) {
+            if (BIO_should_retry(rctx->mem))
+                goto next_io;
+            rctx->state = OHS_ERROR;
+            return 0;
+        }
+
+        /* Don't allow excessive lines */
+        if (n == rctx->iobuflen) {
+            rctx->state = OHS_ERROR;
+            return 0;
+        }
+
+        /* First line */
+        if (rctx->state == OHS_FIRSTLINE) {
+            if (parse_http_line1((char *)rctx->iobuf)) {
+                rctx->state = OHS_HEADERS;
+                goto next_line;
+            } else {
+                rctx->state = OHS_ERROR;
+                return 0;
+            }
+        } else {
+            /* Look for blank line: end of headers */
+            for (p = rctx->iobuf; *p; p++) {
+                if ((*p != '\r') && (*p != '\n'))
+                    break;
+            }
+            if (*p)
+                goto next_line;
+
+            rctx->state = OHS_ASN1_HEADER;
+
+        }
+
+        /* Fall thru */
+
+    case OHS_ASN1_HEADER:
+        /*
+         * Now reading ASN1 header: can read at least 2 bytes which is enough
+         * for ASN1 SEQUENCE header and either length field or at least the
+         * length of the length field.
+         */
+        n = BIO_get_mem_data(rctx->mem, &p);
+        if (n < 2)
+            goto next_io;
+
+        /* Check it is an ASN1 SEQUENCE */
+        if (*p++ != (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) {
+            rctx->state = OHS_ERROR;
+            return 0;
+        }
+
+        /* Check out length field */
+        if (*p & 0x80) {
+            /*
+             * If MSB set on initial length octet we can now always read 6
+             * octets: make sure we have them.
+             */
+            if (n < 6)
+                goto next_io;
+            n = *p & 0x7F;
+            /* Not NDEF or excessive length */
+            if (!n || (n > 4)) {
+                rctx->state = OHS_ERROR;
+                return 0;
+            }
+            p++;
+            rctx->asn1_len = 0;
+            for (i = 0; i < n; i++) {
+                rctx->asn1_len <<= 8;
+                rctx->asn1_len |= *p++;
+            }
+
+            if (rctx->asn1_len > rctx->max_resp_len) {
+                rctx->state = OHS_ERROR;
+                return 0;
+            }
+
+            rctx->asn1_len += n + 2;
+        } else
+            rctx->asn1_len = *p + 2;
+
+        rctx->state = OHS_ASN1_CONTENT;
+
+        /* Fall thru */
+
+    case OHS_ASN1_CONTENT:
+        n = BIO_get_mem_data(rctx->mem, NULL);
+        if (n < (int)rctx->asn1_len)
+            goto next_io;
+
+        rctx->state = OHS_DONE;
+        return 1;
+
+    case OHS_DONE:
+        return 1;
+
+    }
+
+    return 0;
+
+}
+
+int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx)
+{
+    return OCSP_REQ_CTX_nbio_d2i(rctx,
+                                 (ASN1_VALUE **)presp,
+                                 ASN1_ITEM_rptr(OCSP_RESPONSE));
+}
+
+/* Blocking OCSP request handler: now a special case of non-blocking I/O */
+
+OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req)
+{
+    OCSP_RESPONSE *resp = NULL;
+    OCSP_REQ_CTX *ctx;
+    int rv;
+
+    ctx = OCSP_sendreq_new(b, path, req, -1);
+
+    if (ctx == NULL)
+        return NULL;
+
+    do {
+        rv = OCSP_sendreq_nbio(&resp, ctx);
+    } while ((rv == -1) && BIO_should_retry(b));
+
+    OCSP_REQ_CTX_free(ctx);
+
+    if (rv)
+        return resp;
+
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_lcl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_lcl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_lcl.h	(revision 331)
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2015-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
+ */
+
+/*-  CertID ::= SEQUENCE {
+ *       hashAlgorithm            AlgorithmIdentifier,
+ *       issuerNameHash     OCTET STRING, -- Hash of Issuer's DN
+ *       issuerKeyHash      OCTET STRING, -- Hash of Issuers public key (excluding the tag & length fields)
+ *       serialNumber       CertificateSerialNumber }
+ */
+struct ocsp_cert_id_st {
+    X509_ALGOR hashAlgorithm;
+    ASN1_OCTET_STRING issuerNameHash;
+    ASN1_OCTET_STRING issuerKeyHash;
+    ASN1_INTEGER serialNumber;
+};
+
+/*-  Request ::=     SEQUENCE {
+ *       reqCert                    CertID,
+ *       singleRequestExtensions    [0] EXPLICIT Extensions OPTIONAL }
+ */
+struct ocsp_one_request_st {
+    OCSP_CERTID *reqCert;
+    STACK_OF(X509_EXTENSION) *singleRequestExtensions;
+};
+
+/*-  TBSRequest      ::=     SEQUENCE {
+ *       version             [0] EXPLICIT Version DEFAULT v1,
+ *       requestorName       [1] EXPLICIT GeneralName OPTIONAL,
+ *       requestList             SEQUENCE OF Request,
+ *       requestExtensions   [2] EXPLICIT Extensions OPTIONAL }
+ */
+struct ocsp_req_info_st {
+    ASN1_INTEGER *version;
+    GENERAL_NAME *requestorName;
+    STACK_OF(OCSP_ONEREQ) *requestList;
+    STACK_OF(X509_EXTENSION) *requestExtensions;
+};
+
+/*-  Signature       ::=     SEQUENCE {
+ *       signatureAlgorithm   AlgorithmIdentifier,
+ *       signature            BIT STRING,
+ *       certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ */
+struct ocsp_signature_st {
+    X509_ALGOR signatureAlgorithm;
+    ASN1_BIT_STRING *signature;
+    STACK_OF(X509) *certs;
+};
+
+/*-  OCSPRequest     ::=     SEQUENCE {
+ *       tbsRequest                  TBSRequest,
+ *       optionalSignature   [0]     EXPLICIT Signature OPTIONAL }
+ */
+struct ocsp_request_st {
+    OCSP_REQINFO tbsRequest;
+    OCSP_SIGNATURE *optionalSignature; /* OPTIONAL */
+};
+
+/*-  OCSPResponseStatus ::= ENUMERATED {
+ *       successful            (0),      --Response has valid confirmations
+ *       malformedRequest      (1),      --Illegal confirmation request
+ *       internalError         (2),      --Internal error in issuer
+ *       tryLater              (3),      --Try again later
+ *                                       --(4) is not used
+ *       sigRequired           (5),      --Must sign the request
+ *       unauthorized          (6)       --Request unauthorized
+ *   }
+ */
+
+/*-  ResponseBytes ::=       SEQUENCE {
+ *       responseType   OBJECT IDENTIFIER,
+ *       response       OCTET STRING }
+ */
+struct ocsp_resp_bytes_st {
+    ASN1_OBJECT *responseType;
+    ASN1_OCTET_STRING *response;
+};
+
+/*-  OCSPResponse ::= SEQUENCE {
+ *      responseStatus         OCSPResponseStatus,
+ *      responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL }
+ */
+struct ocsp_response_st {
+    ASN1_ENUMERATED *responseStatus;
+    OCSP_RESPBYTES *responseBytes;
+};
+
+/*-  ResponderID ::= CHOICE {
+ *      byName   [1] Name,
+ *      byKey    [2] KeyHash }
+ */
+struct ocsp_responder_id_st {
+    int type;
+    union {
+        X509_NAME *byName;
+        ASN1_OCTET_STRING *byKey;
+    } value;
+};
+
+/*-  KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key
+ *                            --(excluding the tag and length fields)
+ */
+
+/*-  RevokedInfo ::= SEQUENCE {
+ *       revocationTime              GeneralizedTime,
+ *       revocationReason    [0]     EXPLICIT CRLReason OPTIONAL }
+ */
+struct ocsp_revoked_info_st {
+    ASN1_GENERALIZEDTIME *revocationTime;
+    ASN1_ENUMERATED *revocationReason;
+};
+
+/*-  CertStatus ::= CHOICE {
+ *       good                [0]     IMPLICIT NULL,
+ *       revoked             [1]     IMPLICIT RevokedInfo,
+ *       unknown             [2]     IMPLICIT UnknownInfo }
+ */
+struct ocsp_cert_status_st {
+    int type;
+    union {
+        ASN1_NULL *good;
+        OCSP_REVOKEDINFO *revoked;
+        ASN1_NULL *unknown;
+    } value;
+};
+
+/*-  SingleResponse ::= SEQUENCE {
+ *      certID                       CertID,
+ *      certStatus                   CertStatus,
+ *      thisUpdate                   GeneralizedTime,
+ *      nextUpdate           [0]     EXPLICIT GeneralizedTime OPTIONAL,
+ *      singleExtensions     [1]     EXPLICIT Extensions OPTIONAL }
+ */
+struct ocsp_single_response_st {
+    OCSP_CERTID *certId;
+    OCSP_CERTSTATUS *certStatus;
+    ASN1_GENERALIZEDTIME *thisUpdate;
+    ASN1_GENERALIZEDTIME *nextUpdate;
+    STACK_OF(X509_EXTENSION) *singleExtensions;
+};
+
+/*-  ResponseData ::= SEQUENCE {
+ *      version              [0] EXPLICIT Version DEFAULT v1,
+ *      responderID              ResponderID,
+ *      producedAt               GeneralizedTime,
+ *      responses                SEQUENCE OF SingleResponse,
+ *      responseExtensions   [1] EXPLICIT Extensions OPTIONAL }
+ */
+struct ocsp_response_data_st {
+    ASN1_INTEGER *version;
+    OCSP_RESPID responderId;
+    ASN1_GENERALIZEDTIME *producedAt;
+    STACK_OF(OCSP_SINGLERESP) *responses;
+    STACK_OF(X509_EXTENSION) *responseExtensions;
+};
+
+/*-  BasicOCSPResponse       ::= SEQUENCE {
+ *      tbsResponseData      ResponseData,
+ *      signatureAlgorithm   AlgorithmIdentifier,
+ *      signature            BIT STRING,
+ *      certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ */
+  /*
+   * Note 1: The value for "signature" is specified in the OCSP rfc2560 as
+   * follows: "The value for the signature SHALL be computed on the hash of
+   * the DER encoding ResponseData." This means that you must hash the
+   * DER-encoded tbsResponseData, and then run it through a crypto-signing
+   * function, which will (at least w/RSA) do a hash-'n'-private-encrypt
+   * operation.  This seems a bit odd, but that's the spec.  Also note that
+   * the data structures do not leave anywhere to independently specify the
+   * algorithm used for the initial hash. So, we look at the
+   * signature-specification algorithm, and try to do something intelligent.
+   * -- Kathy Weinhold, CertCo
+   */
+  /*
+   * Note 2: It seems that the mentioned passage from RFC 2560 (section
+   * 4.2.1) is open for interpretation.  I've done tests against another
+   * responder, and found that it doesn't do the double hashing that the RFC
+   * seems to say one should.  Therefore, all relevant functions take a flag
+   * saying which variant should be used.  -- Richard Levitte, OpenSSL team
+   * and CeloCom
+   */
+struct ocsp_basic_response_st {
+    OCSP_RESPDATA tbsResponseData;
+    X509_ALGOR signatureAlgorithm;
+    ASN1_BIT_STRING *signature;
+    STACK_OF(X509) *certs;
+};
+
+/*-
+ * CrlID ::= SEQUENCE {
+ *     crlUrl               [0]     EXPLICIT IA5String OPTIONAL,
+ *     crlNum               [1]     EXPLICIT INTEGER OPTIONAL,
+ *     crlTime              [2]     EXPLICIT GeneralizedTime OPTIONAL }
+ */
+struct ocsp_crl_id_st {
+    ASN1_IA5STRING *crlUrl;
+    ASN1_INTEGER *crlNum;
+    ASN1_GENERALIZEDTIME *crlTime;
+};
+
+/*-
+ * ServiceLocator ::= SEQUENCE {
+ *      issuer    Name,
+ *      locator   AuthorityInfoAccessSyntax OPTIONAL }
+ */
+struct ocsp_service_locator_st {
+    X509_NAME *issuer;
+    STACK_OF(ACCESS_DESCRIPTION) *locator;
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_lib.c	(revision 331)
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2000-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/ocsp.h>
+#include "ocsp_lcl.h"
+#include <openssl/asn1t.h>
+
+/* Convert a certificate and its issuer to an OCSP_CERTID */
+
+OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, const X509 *subject,
+                             const X509 *issuer)
+{
+    X509_NAME *iname;
+    const ASN1_INTEGER *serial;
+    ASN1_BIT_STRING *ikey;
+    if (!dgst)
+        dgst = EVP_sha1();
+    if (subject) {
+        iname = X509_get_issuer_name(subject);
+        serial = X509_get0_serialNumber(subject);
+    } else {
+        iname = X509_get_subject_name(issuer);
+        serial = NULL;
+    }
+    ikey = X509_get0_pubkey_bitstr(issuer);
+    return OCSP_cert_id_new(dgst, iname, ikey, serial);
+}
+
+OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst,
+                              const X509_NAME *issuerName,
+                              const ASN1_BIT_STRING *issuerKey,
+                              const ASN1_INTEGER *serialNumber)
+{
+    int nid;
+    unsigned int i;
+    X509_ALGOR *alg;
+    OCSP_CERTID *cid = NULL;
+    unsigned char md[EVP_MAX_MD_SIZE];
+
+    if ((cid = OCSP_CERTID_new()) == NULL)
+        goto err;
+
+    alg = &cid->hashAlgorithm;
+    ASN1_OBJECT_free(alg->algorithm);
+    if ((nid = EVP_MD_type(dgst)) == NID_undef) {
+        OCSPerr(OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_UNKNOWN_NID);
+        goto err;
+    }
+    if ((alg->algorithm = OBJ_nid2obj(nid)) == NULL)
+        goto err;
+    if ((alg->parameter = ASN1_TYPE_new()) == NULL)
+        goto err;
+    alg->parameter->type = V_ASN1_NULL;
+
+    if (!X509_NAME_digest(issuerName, dgst, md, &i))
+        goto digerr;
+    if (!(ASN1_OCTET_STRING_set(&cid->issuerNameHash, md, i)))
+        goto err;
+
+    /* Calculate the issuerKey hash, excluding tag and length */
+    if (!EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst, NULL))
+        goto err;
+
+    if (!(ASN1_OCTET_STRING_set(&cid->issuerKeyHash, md, i)))
+        goto err;
+
+    if (serialNumber) {
+        if (ASN1_STRING_copy(&cid->serialNumber, serialNumber) == 0)
+            goto err;
+    }
+    return cid;
+ digerr:
+    OCSPerr(OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_DIGEST_ERR);
+ err:
+    OCSP_CERTID_free(cid);
+    return NULL;
+}
+
+int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
+{
+    int ret;
+    ret = OBJ_cmp(a->hashAlgorithm.algorithm, b->hashAlgorithm.algorithm);
+    if (ret)
+        return ret;
+    ret = ASN1_OCTET_STRING_cmp(&a->issuerNameHash, &b->issuerNameHash);
+    if (ret)
+        return ret;
+    return ASN1_OCTET_STRING_cmp(&a->issuerKeyHash, &b->issuerKeyHash);
+}
+
+int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
+{
+    int ret;
+    ret = OCSP_id_issuer_cmp(a, b);
+    if (ret)
+        return ret;
+    return ASN1_INTEGER_cmp(&a->serialNumber, &b->serialNumber);
+}
+
+/*
+ * Parse a URL and split it up into host, port and path components and
+ * whether it is SSL.
+ */
+
+int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath,
+                   int *pssl)
+{
+    char *p, *buf;
+
+    char *host, *port;
+
+    *phost = NULL;
+    *pport = NULL;
+    *ppath = NULL;
+
+    /* dup the buffer since we are going to mess with it */
+    buf = OPENSSL_strdup(url);
+    if (!buf)
+        goto mem_err;
+
+    /* Check for initial colon */
+    p = strchr(buf, ':');
+
+    if (!p)
+        goto parse_err;
+
+    *(p++) = '\0';
+
+    if (strcmp(buf, "http") == 0) {
+        *pssl = 0;
+        port = "80";
+    } else if (strcmp(buf, "https") == 0) {
+        *pssl = 1;
+        port = "443";
+    } else
+        goto parse_err;
+
+    /* Check for double slash */
+    if ((p[0] != '/') || (p[1] != '/'))
+        goto parse_err;
+
+    p += 2;
+
+    host = p;
+
+    /* Check for trailing part of path */
+
+    p = strchr(p, '/');
+
+    if (!p)
+        *ppath = OPENSSL_strdup("/");
+    else {
+        *ppath = OPENSSL_strdup(p);
+        /* Set start of path to 0 so hostname is valid */
+        *p = '\0';
+    }
+
+    if (!*ppath)
+        goto mem_err;
+
+    p = host;
+    if (host[0] == '[') {
+        /* ipv6 literal */
+        host++;
+        p = strchr(host, ']');
+        if (!p)
+            goto parse_err;
+        *p = '\0';
+        p++;
+    }
+
+    /* Look for optional ':' for port number */
+    if ((p = strchr(p, ':'))) {
+        *p = 0;
+        port = p + 1;
+    }
+
+    *pport = OPENSSL_strdup(port);
+    if (!*pport)
+        goto mem_err;
+
+    *phost = OPENSSL_strdup(host);
+
+    if (!*phost)
+        goto mem_err;
+
+    OPENSSL_free(buf);
+
+    return 1;
+
+ mem_err:
+    OCSPerr(OCSP_F_OCSP_PARSE_URL, ERR_R_MALLOC_FAILURE);
+    goto err;
+
+ parse_err:
+    OCSPerr(OCSP_F_OCSP_PARSE_URL, OCSP_R_ERROR_PARSING_URL);
+
+ err:
+    OPENSSL_free(buf);
+    OPENSSL_free(*ppath);
+    *ppath = NULL;
+    OPENSSL_free(*pport);
+    *pport = NULL;
+    OPENSSL_free(*phost);
+    *phost = NULL;
+    return 0;
+
+}
+
+IMPLEMENT_ASN1_DUP_FUNCTION(OCSP_CERTID)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_prn.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_prn.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_prn.c	(revision 331)
@@ -0,0 +1,246 @@
+/*
+ * Copyright 2000-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 <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/ocsp.h>
+#include "ocsp_lcl.h"
+#include "internal/cryptlib.h"
+#include <openssl/pem.h>
+
+static int ocsp_certid_print(BIO *bp, OCSP_CERTID *a, int indent)
+{
+    BIO_printf(bp, "%*sCertificate ID:\n", indent, "");
+    indent += 2;
+    BIO_printf(bp, "%*sHash Algorithm: ", indent, "");
+    i2a_ASN1_OBJECT(bp, a->hashAlgorithm.algorithm);
+    BIO_printf(bp, "\n%*sIssuer Name Hash: ", indent, "");
+    i2a_ASN1_STRING(bp, &a->issuerNameHash, 0);
+    BIO_printf(bp, "\n%*sIssuer Key Hash: ", indent, "");
+    i2a_ASN1_STRING(bp, &a->issuerKeyHash, 0);
+    BIO_printf(bp, "\n%*sSerial Number: ", indent, "");
+    i2a_ASN1_INTEGER(bp, &a->serialNumber);
+    BIO_printf(bp, "\n");
+    return 1;
+}
+
+typedef struct {
+    long t;
+    const char *m;
+} OCSP_TBLSTR;
+
+static const char *do_table2string(long s, const OCSP_TBLSTR *ts, size_t len)
+{
+    size_t i;
+    for (i = 0; i < len; i++, ts++)
+        if (ts->t == s)
+            return ts->m;
+    return "(UNKNOWN)";
+}
+
+#define table2string(s, tbl) do_table2string(s, tbl, OSSL_NELEM(tbl))
+
+const char *OCSP_response_status_str(long s)
+{
+    static const OCSP_TBLSTR rstat_tbl[] = {
+        {OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful"},
+        {OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest"},
+        {OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror"},
+        {OCSP_RESPONSE_STATUS_TRYLATER, "trylater"},
+        {OCSP_RESPONSE_STATUS_SIGREQUIRED, "sigrequired"},
+        {OCSP_RESPONSE_STATUS_UNAUTHORIZED, "unauthorized"}
+    };
+    return table2string(s, rstat_tbl);
+}
+
+const char *OCSP_cert_status_str(long s)
+{
+    static const OCSP_TBLSTR cstat_tbl[] = {
+        {V_OCSP_CERTSTATUS_GOOD, "good"},
+        {V_OCSP_CERTSTATUS_REVOKED, "revoked"},
+        {V_OCSP_CERTSTATUS_UNKNOWN, "unknown"}
+    };
+    return table2string(s, cstat_tbl);
+}
+
+const char *OCSP_crl_reason_str(long s)
+{
+    static const OCSP_TBLSTR reason_tbl[] = {
+        {OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified"},
+        {OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise"},
+        {OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise"},
+        {OCSP_REVOKED_STATUS_AFFILIATIONCHANGED, "affiliationChanged"},
+        {OCSP_REVOKED_STATUS_SUPERSEDED, "superseded"},
+        {OCSP_REVOKED_STATUS_CESSATIONOFOPERATION, "cessationOfOperation"},
+        {OCSP_REVOKED_STATUS_CERTIFICATEHOLD, "certificateHold"},
+        {OCSP_REVOKED_STATUS_REMOVEFROMCRL, "removeFromCRL"}
+    };
+    return table2string(s, reason_tbl);
+}
+
+int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *o, unsigned long flags)
+{
+    int i;
+    long l;
+    OCSP_CERTID *cid = NULL;
+    OCSP_ONEREQ *one = NULL;
+    OCSP_REQINFO *inf = &o->tbsRequest;
+    OCSP_SIGNATURE *sig = o->optionalSignature;
+
+    if (BIO_write(bp, "OCSP Request Data:\n", 19) <= 0)
+        goto err;
+    l = ASN1_INTEGER_get(inf->version);
+    if (BIO_printf(bp, "    Version: %lu (0x%lx)", l + 1, l) <= 0)
+        goto err;
+    if (inf->requestorName != NULL) {
+        if (BIO_write(bp, "\n    Requestor Name: ", 21) <= 0)
+            goto err;
+        GENERAL_NAME_print(bp, inf->requestorName);
+    }
+    if (BIO_write(bp, "\n    Requestor List:\n", 21) <= 0)
+        goto err;
+    for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++) {
+        one = sk_OCSP_ONEREQ_value(inf->requestList, i);
+        cid = one->reqCert;
+        ocsp_certid_print(bp, cid, 8);
+        if (!X509V3_extensions_print(bp,
+                                     "Request Single Extensions",
+                                     one->singleRequestExtensions, flags, 8))
+            goto err;
+    }
+    if (!X509V3_extensions_print(bp, "Request Extensions",
+                                 inf->requestExtensions, flags, 4))
+        goto err;
+    if (sig) {
+        X509_signature_print(bp, &sig->signatureAlgorithm, sig->signature);
+        for (i = 0; i < sk_X509_num(sig->certs); i++) {
+            X509_print(bp, sk_X509_value(sig->certs, i));
+            PEM_write_bio_X509(bp, sk_X509_value(sig->certs, i));
+        }
+    }
+    return 1;
+ err:
+    return 0;
+}
+
+int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags)
+{
+    int i, ret = 0;
+    long l;
+    OCSP_CERTID *cid = NULL;
+    OCSP_BASICRESP *br = NULL;
+    OCSP_RESPID *rid = NULL;
+    OCSP_RESPDATA *rd = NULL;
+    OCSP_CERTSTATUS *cst = NULL;
+    OCSP_REVOKEDINFO *rev = NULL;
+    OCSP_SINGLERESP *single = NULL;
+    OCSP_RESPBYTES *rb = o->responseBytes;
+
+    if (BIO_puts(bp, "OCSP Response Data:\n") <= 0)
+        goto err;
+    l = ASN1_ENUMERATED_get(o->responseStatus);
+    if (BIO_printf(bp, "    OCSP Response Status: %s (0x%lx)\n",
+                   OCSP_response_status_str(l), l) <= 0)
+        goto err;
+    if (rb == NULL)
+        return 1;
+    if (BIO_puts(bp, "    Response Type: ") <= 0)
+        goto err;
+    if (i2a_ASN1_OBJECT(bp, rb->responseType) <= 0)
+        goto err;
+    if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) {
+        BIO_puts(bp, " (unknown response type)\n");
+        return 1;
+    }
+
+    if ((br = OCSP_response_get1_basic(o)) == NULL)
+        goto err;
+    rd = &br->tbsResponseData;
+    l = ASN1_INTEGER_get(rd->version);
+    if (BIO_printf(bp, "\n    Version: %lu (0x%lx)\n", l + 1, l) <= 0)
+        goto err;
+    if (BIO_puts(bp, "    Responder Id: ") <= 0)
+        goto err;
+
+    rid = &rd->responderId;
+    switch (rid->type) {
+    case V_OCSP_RESPID_NAME:
+        X509_NAME_print_ex(bp, rid->value.byName, 0, XN_FLAG_ONELINE);
+        break;
+    case V_OCSP_RESPID_KEY:
+        i2a_ASN1_STRING(bp, rid->value.byKey, 0);
+        break;
+    }
+
+    if (BIO_printf(bp, "\n    Produced At: ") <= 0)
+        goto err;
+    if (!ASN1_GENERALIZEDTIME_print(bp, rd->producedAt))
+        goto err;
+    if (BIO_printf(bp, "\n    Responses:\n") <= 0)
+        goto err;
+    for (i = 0; i < sk_OCSP_SINGLERESP_num(rd->responses); i++) {
+        if (!sk_OCSP_SINGLERESP_value(rd->responses, i))
+            continue;
+        single = sk_OCSP_SINGLERESP_value(rd->responses, i);
+        cid = single->certId;
+        if (ocsp_certid_print(bp, cid, 4) <= 0)
+            goto err;
+        cst = single->certStatus;
+        if (BIO_printf(bp, "    Cert Status: %s",
+                       OCSP_cert_status_str(cst->type)) <= 0)
+            goto err;
+        if (cst->type == V_OCSP_CERTSTATUS_REVOKED) {
+            rev = cst->value.revoked;
+            if (BIO_printf(bp, "\n    Revocation Time: ") <= 0)
+                goto err;
+            if (!ASN1_GENERALIZEDTIME_print(bp, rev->revocationTime))
+                goto err;
+            if (rev->revocationReason) {
+                l = ASN1_ENUMERATED_get(rev->revocationReason);
+                if (BIO_printf(bp,
+                               "\n    Revocation Reason: %s (0x%lx)",
+                               OCSP_crl_reason_str(l), l) <= 0)
+                    goto err;
+            }
+        }
+        if (BIO_printf(bp, "\n    This Update: ") <= 0)
+            goto err;
+        if (!ASN1_GENERALIZEDTIME_print(bp, single->thisUpdate))
+            goto err;
+        if (single->nextUpdate) {
+            if (BIO_printf(bp, "\n    Next Update: ") <= 0)
+                goto err;
+            if (!ASN1_GENERALIZEDTIME_print(bp, single->nextUpdate))
+                goto err;
+        }
+        if (BIO_write(bp, "\n", 1) <= 0)
+            goto err;
+        if (!X509V3_extensions_print(bp,
+                                     "Response Single Extensions",
+                                     single->singleExtensions, flags, 8))
+            goto err;
+        if (BIO_write(bp, "\n", 1) <= 0)
+            goto err;
+    }
+    if (!X509V3_extensions_print(bp, "Response Extensions",
+                                 rd->responseExtensions, flags, 4))
+        goto err;
+    if (X509_signature_print(bp, &br->signatureAlgorithm, br->signature) <= 0)
+        goto err;
+
+    for (i = 0; i < sk_X509_num(br->certs); i++) {
+        X509_print(bp, sk_X509_value(br->certs, i));
+        PEM_write_bio_X509(bp, sk_X509_value(br->certs, i));
+    }
+
+    ret = 1;
+ err:
+    OCSP_BASICRESP_free(br);
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_srv.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_srv.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_srv.c	(revision 331)
@@ -0,0 +1,277 @@
+/*
+ * Copyright 2001-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/ocsp.h>
+#include "ocsp_lcl.h"
+
+/*
+ * Utility functions related to sending OCSP responses and extracting
+ * relevant information from the request.
+ */
+
+int OCSP_request_onereq_count(OCSP_REQUEST *req)
+{
+    return sk_OCSP_ONEREQ_num(req->tbsRequest.requestList);
+}
+
+OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i)
+{
+    return sk_OCSP_ONEREQ_value(req->tbsRequest.requestList, i);
+}
+
+OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one)
+{
+    return one->reqCert;
+}
+
+int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd,
+                      ASN1_OCTET_STRING **pikeyHash,
+                      ASN1_INTEGER **pserial, OCSP_CERTID *cid)
+{
+    if (!cid)
+        return 0;
+    if (pmd)
+        *pmd = cid->hashAlgorithm.algorithm;
+    if (piNameHash)
+        *piNameHash = &cid->issuerNameHash;
+    if (pikeyHash)
+        *pikeyHash = &cid->issuerKeyHash;
+    if (pserial)
+        *pserial = &cid->serialNumber;
+    return 1;
+}
+
+int OCSP_request_is_signed(OCSP_REQUEST *req)
+{
+    if (req->optionalSignature)
+        return 1;
+    return 0;
+}
+
+/* Create an OCSP response and encode an optional basic response */
+OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs)
+{
+    OCSP_RESPONSE *rsp = NULL;
+
+    if ((rsp = OCSP_RESPONSE_new()) == NULL)
+        goto err;
+    if (!(ASN1_ENUMERATED_set(rsp->responseStatus, status)))
+        goto err;
+    if (!bs)
+        return rsp;
+    if ((rsp->responseBytes = OCSP_RESPBYTES_new()) == NULL)
+        goto err;
+    rsp->responseBytes->responseType = OBJ_nid2obj(NID_id_pkix_OCSP_basic);
+    if (!ASN1_item_pack
+        (bs, ASN1_ITEM_rptr(OCSP_BASICRESP), &rsp->responseBytes->response))
+         goto err;
+    return rsp;
+ err:
+    OCSP_RESPONSE_free(rsp);
+    return NULL;
+}
+
+OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp,
+                                        OCSP_CERTID *cid,
+                                        int status, int reason,
+                                        ASN1_TIME *revtime,
+                                        ASN1_TIME *thisupd,
+                                        ASN1_TIME *nextupd)
+{
+    OCSP_SINGLERESP *single = NULL;
+    OCSP_CERTSTATUS *cs;
+    OCSP_REVOKEDINFO *ri;
+
+    if (rsp->tbsResponseData.responses == NULL
+        && (rsp->tbsResponseData.responses
+                = sk_OCSP_SINGLERESP_new_null()) == NULL)
+        goto err;
+
+    if ((single = OCSP_SINGLERESP_new()) == NULL)
+        goto err;
+
+    if (!ASN1_TIME_to_generalizedtime(thisupd, &single->thisUpdate))
+        goto err;
+    if (nextupd &&
+        !ASN1_TIME_to_generalizedtime(nextupd, &single->nextUpdate))
+        goto err;
+
+    OCSP_CERTID_free(single->certId);
+
+    if ((single->certId = OCSP_CERTID_dup(cid)) == NULL)
+        goto err;
+
+    cs = single->certStatus;
+    switch (cs->type = status) {
+    case V_OCSP_CERTSTATUS_REVOKED:
+        if (!revtime) {
+            OCSPerr(OCSP_F_OCSP_BASIC_ADD1_STATUS, OCSP_R_NO_REVOKED_TIME);
+            goto err;
+        }
+        if ((cs->value.revoked = ri = OCSP_REVOKEDINFO_new()) == NULL)
+            goto err;
+        if (!ASN1_TIME_to_generalizedtime(revtime, &ri->revocationTime))
+            goto err;
+        if (reason != OCSP_REVOKED_STATUS_NOSTATUS) {
+            if ((ri->revocationReason = ASN1_ENUMERATED_new()) == NULL)
+                goto err;
+            if (!(ASN1_ENUMERATED_set(ri->revocationReason, reason)))
+                goto err;
+        }
+        break;
+
+    case V_OCSP_CERTSTATUS_GOOD:
+        if ((cs->value.good = ASN1_NULL_new()) == NULL)
+            goto err;
+        break;
+
+    case V_OCSP_CERTSTATUS_UNKNOWN:
+        if ((cs->value.unknown = ASN1_NULL_new()) == NULL)
+            goto err;
+        break;
+
+    default:
+        goto err;
+
+    }
+    if (!(sk_OCSP_SINGLERESP_push(rsp->tbsResponseData.responses, single)))
+        goto err;
+    return single;
+ err:
+    OCSP_SINGLERESP_free(single);
+    return NULL;
+}
+
+/* Add a certificate to an OCSP request */
+
+int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert)
+{
+    if (resp->certs == NULL
+        && (resp->certs = sk_X509_new_null()) == NULL)
+        return 0;
+
+    if (!sk_X509_push(resp->certs, cert))
+        return 0;
+    X509_up_ref(cert);
+    return 1;
+}
+
+int OCSP_basic_sign(OCSP_BASICRESP *brsp,
+                    X509 *signer, EVP_PKEY *key, const EVP_MD *dgst,
+                    STACK_OF(X509) *certs, unsigned long flags)
+{
+    int i;
+    OCSP_RESPID *rid;
+
+    if (!X509_check_private_key(signer, key)) {
+        OCSPerr(OCSP_F_OCSP_BASIC_SIGN,
+                OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+        goto err;
+    }
+
+    if (!(flags & OCSP_NOCERTS)) {
+        if (!OCSP_basic_add1_cert(brsp, signer))
+            goto err;
+        for (i = 0; i < sk_X509_num(certs); i++) {
+            X509 *tmpcert = sk_X509_value(certs, i);
+            if (!OCSP_basic_add1_cert(brsp, tmpcert))
+                goto err;
+        }
+    }
+
+    rid = &brsp->tbsResponseData.responderId;
+    if (flags & OCSP_RESPID_KEY) {
+        if (!OCSP_RESPID_set_by_key(rid, signer))
+            goto err;
+    } else if (!OCSP_RESPID_set_by_name(rid, signer)) {
+        goto err;
+    }
+
+    if (!(flags & OCSP_NOTIME) &&
+        !X509_gmtime_adj(brsp->tbsResponseData.producedAt, 0))
+        goto err;
+
+    /*
+     * Right now, I think that not doing double hashing is the right thing.
+     * -- Richard Levitte
+     */
+
+    if (!OCSP_BASICRESP_sign(brsp, key, dgst, 0))
+        goto err;
+
+    return 1;
+ err:
+    return 0;
+}
+
+int OCSP_RESPID_set_by_name(OCSP_RESPID *respid, X509 *cert)
+{
+    if (!X509_NAME_set(&respid->value.byName, X509_get_subject_name(cert)))
+        return 0;
+
+    respid->type = V_OCSP_RESPID_NAME;
+
+    return 1;
+}
+
+int OCSP_RESPID_set_by_key(OCSP_RESPID *respid, X509 *cert)
+{
+    ASN1_OCTET_STRING *byKey = NULL;
+    unsigned char md[SHA_DIGEST_LENGTH];
+
+    /* RFC2560 requires SHA1 */
+    if (!X509_pubkey_digest(cert, EVP_sha1(), md, NULL))
+        return 0;
+
+    byKey = ASN1_OCTET_STRING_new();
+    if (byKey == NULL)
+        return 0;
+
+    if (!(ASN1_OCTET_STRING_set(byKey, md, SHA_DIGEST_LENGTH))) {
+        ASN1_OCTET_STRING_free(byKey);
+        return 0;
+    }
+
+    respid->type = V_OCSP_RESPID_KEY;
+    respid->value.byKey = byKey;
+
+    return 1;
+}
+
+int OCSP_RESPID_match(OCSP_RESPID *respid, X509 *cert)
+{
+    if (respid->type == V_OCSP_RESPID_KEY) {
+        unsigned char md[SHA_DIGEST_LENGTH];
+
+        if (respid->value.byKey == NULL)
+            return 0;
+
+        /* RFC2560 requires SHA1 */
+        if (!X509_pubkey_digest(cert, EVP_sha1(), md, NULL))
+            return 0;
+
+        return (ASN1_STRING_length(respid->value.byKey) == SHA_DIGEST_LENGTH)
+            && (memcmp(ASN1_STRING_get0_data(respid->value.byKey), md,
+                       SHA_DIGEST_LENGTH) == 0);
+    } else if(respid->type == V_OCSP_RESPID_NAME) {
+        if (respid->value.byName == NULL)
+            return 0;
+
+        return X509_NAME_cmp(respid->value.byName,
+                             X509_get_subject_name(cert)) == 0;
+    }
+
+    return 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_vfy.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_vfy.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/ocsp_vfy.c	(revision 331)
@@ -0,0 +1,424 @@
+/*
+ * Copyright 2001-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 <openssl/ocsp.h>
+#include "ocsp_lcl.h"
+#include <openssl/err.h>
+#include <string.h>
+
+static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs,
+                            STACK_OF(X509) *certs, unsigned long flags);
+static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id);
+static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain);
+static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp,
+                          OCSP_CERTID **ret);
+static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
+                               STACK_OF(OCSP_SINGLERESP) *sresp);
+static int ocsp_check_delegated(X509 *x);
+static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req,
+                                X509_NAME *nm, STACK_OF(X509) *certs,
+                                unsigned long flags);
+
+/* Verify a basic response message */
+
+int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
+                      X509_STORE *st, unsigned long flags)
+{
+    X509 *signer, *x;
+    STACK_OF(X509) *chain = NULL;
+    STACK_OF(X509) *untrusted = NULL;
+    X509_STORE_CTX *ctx = NULL;
+    int i, ret = ocsp_find_signer(&signer, bs, certs, flags);
+
+    if (!ret) {
+        OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,
+                OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
+        goto end;
+    }
+    ctx = X509_STORE_CTX_new();
+    if (ctx == NULL) {
+        OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE);
+        goto f_err;
+    }
+    if ((ret == 2) && (flags & OCSP_TRUSTOTHER))
+        flags |= OCSP_NOVERIFY;
+    if (!(flags & OCSP_NOSIGS)) {
+        EVP_PKEY *skey;
+        skey = X509_get0_pubkey(signer);
+        if (skey == NULL) {
+            OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_NO_SIGNER_KEY);
+            goto err;
+        }
+        ret = OCSP_BASICRESP_verify(bs, skey, 0);
+        if (ret <= 0) {
+            OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE);
+            goto end;
+        }
+    }
+    if (!(flags & OCSP_NOVERIFY)) {
+        int init_res;
+        if (flags & OCSP_NOCHAIN) {
+            untrusted = NULL;
+        } else if (bs->certs && certs) {
+            untrusted = sk_X509_dup(bs->certs);
+            for (i = 0; i < sk_X509_num(certs); i++) {
+                if (!sk_X509_push(untrusted, sk_X509_value(certs, i))) {
+                    OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE);
+                    goto f_err;
+                }
+            }
+        } else {
+            untrusted = bs->certs;
+        }
+        init_res = X509_STORE_CTX_init(ctx, st, signer, untrusted);
+        if (!init_res) {
+            OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_X509_LIB);
+            goto f_err;
+        }
+
+        X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_OCSP_HELPER);
+        ret = X509_verify_cert(ctx);
+        chain = X509_STORE_CTX_get1_chain(ctx);
+        if (ret <= 0) {
+            i = X509_STORE_CTX_get_error(ctx);
+            OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,
+                    OCSP_R_CERTIFICATE_VERIFY_ERROR);
+            ERR_add_error_data(2, "Verify error:",
+                               X509_verify_cert_error_string(i));
+            goto end;
+        }
+        if (flags & OCSP_NOCHECKS) {
+            ret = 1;
+            goto end;
+        }
+        /*
+         * At this point we have a valid certificate chain need to verify it
+         * against the OCSP issuer criteria.
+         */
+        ret = ocsp_check_issuer(bs, chain);
+
+        /* If fatal error or valid match then finish */
+        if (ret != 0)
+            goto end;
+
+        /*
+         * Easy case: explicitly trusted. Get root CA and check for explicit
+         * trust
+         */
+        if (flags & OCSP_NOEXPLICIT)
+            goto end;
+
+        x = sk_X509_value(chain, sk_X509_num(chain) - 1);
+        if (X509_check_trust(x, NID_OCSP_sign, 0) != X509_TRUST_TRUSTED) {
+            OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_ROOT_CA_NOT_TRUSTED);
+            goto err;
+        }
+        ret = 1;
+    }
+ end:
+    X509_STORE_CTX_free(ctx);
+    sk_X509_pop_free(chain, X509_free);
+    if (bs->certs && certs)
+        sk_X509_free(untrusted);
+    return ret;
+
+ err:
+    ret = 0;
+    goto end;
+ f_err:
+    ret = -1;
+    goto end;
+}
+
+static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs,
+                            STACK_OF(X509) *certs, unsigned long flags)
+{
+    X509 *signer;
+    OCSP_RESPID *rid = &bs->tbsResponseData.responderId;
+    if ((signer = ocsp_find_signer_sk(certs, rid))) {
+        *psigner = signer;
+        return 2;
+    }
+    if (!(flags & OCSP_NOINTERN) &&
+        (signer = ocsp_find_signer_sk(bs->certs, rid))) {
+        *psigner = signer;
+        return 1;
+    }
+    /* Maybe lookup from store if by subject name */
+
+    *psigner = NULL;
+    return 0;
+}
+
+static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
+{
+    int i;
+    unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
+    X509 *x;
+
+    /* Easy if lookup by name */
+    if (id->type == V_OCSP_RESPID_NAME)
+        return X509_find_by_subject(certs, id->value.byName);
+
+    /* Lookup by key hash */
+
+    /* If key hash isn't SHA1 length then forget it */
+    if (id->value.byKey->length != SHA_DIGEST_LENGTH)
+        return NULL;
+    keyhash = id->value.byKey->data;
+    /* Calculate hash of each key and compare */
+    for (i = 0; i < sk_X509_num(certs); i++) {
+        x = sk_X509_value(certs, i);
+        X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
+        if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
+            return x;
+    }
+    return NULL;
+}
+
+static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain)
+{
+    STACK_OF(OCSP_SINGLERESP) *sresp;
+    X509 *signer, *sca;
+    OCSP_CERTID *caid = NULL;
+    int i;
+    sresp = bs->tbsResponseData.responses;
+
+    if (sk_X509_num(chain) <= 0) {
+        OCSPerr(OCSP_F_OCSP_CHECK_ISSUER, OCSP_R_NO_CERTIFICATES_IN_CHAIN);
+        return -1;
+    }
+
+    /* See if the issuer IDs match. */
+    i = ocsp_check_ids(sresp, &caid);
+
+    /* If ID mismatch or other error then return */
+    if (i <= 0)
+        return i;
+
+    signer = sk_X509_value(chain, 0);
+    /* Check to see if OCSP responder CA matches request CA */
+    if (sk_X509_num(chain) > 1) {
+        sca = sk_X509_value(chain, 1);
+        i = ocsp_match_issuerid(sca, caid, sresp);
+        if (i < 0)
+            return i;
+        if (i) {
+            /* We have a match, if extensions OK then success */
+            if (ocsp_check_delegated(signer))
+                return 1;
+            return 0;
+        }
+    }
+
+    /* Otherwise check if OCSP request signed directly by request CA */
+    return ocsp_match_issuerid(signer, caid, sresp);
+}
+
+/*
+ * Check the issuer certificate IDs for equality. If there is a mismatch with
+ * the same algorithm then there's no point trying to match any certificates
+ * against the issuer. If the issuer IDs all match then we just need to check
+ * equality against one of them.
+ */
+
+static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret)
+{
+    OCSP_CERTID *tmpid, *cid;
+    int i, idcount;
+
+    idcount = sk_OCSP_SINGLERESP_num(sresp);
+    if (idcount <= 0) {
+        OCSPerr(OCSP_F_OCSP_CHECK_IDS,
+                OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA);
+        return -1;
+    }
+
+    cid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId;
+
+    *ret = NULL;
+
+    for (i = 1; i < idcount; i++) {
+        tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId;
+        /* Check to see if IDs match */
+        if (OCSP_id_issuer_cmp(cid, tmpid)) {
+            /* If algorithm mismatch let caller deal with it */
+            if (OBJ_cmp(tmpid->hashAlgorithm.algorithm,
+                        cid->hashAlgorithm.algorithm))
+                return 2;
+            /* Else mismatch */
+            return 0;
+        }
+    }
+
+    /* All IDs match: only need to check one ID */
+    *ret = cid;
+    return 1;
+}
+
+static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid,
+                               STACK_OF(OCSP_SINGLERESP) *sresp)
+{
+    /* If only one ID to match then do it */
+    if (cid) {
+        const EVP_MD *dgst;
+        X509_NAME *iname;
+        int mdlen;
+        unsigned char md[EVP_MAX_MD_SIZE];
+        if ((dgst = EVP_get_digestbyobj(cid->hashAlgorithm.algorithm))
+                == NULL) {
+            OCSPerr(OCSP_F_OCSP_MATCH_ISSUERID,
+                    OCSP_R_UNKNOWN_MESSAGE_DIGEST);
+            return -1;
+        }
+
+        mdlen = EVP_MD_size(dgst);
+        if (mdlen < 0)
+            return -1;
+        if ((cid->issuerNameHash.length != mdlen) ||
+            (cid->issuerKeyHash.length != mdlen))
+            return 0;
+        iname = X509_get_subject_name(cert);
+        if (!X509_NAME_digest(iname, dgst, md, NULL))
+            return -1;
+        if (memcmp(md, cid->issuerNameHash.data, mdlen))
+            return 0;
+        X509_pubkey_digest(cert, dgst, md, NULL);
+        if (memcmp(md, cid->issuerKeyHash.data, mdlen))
+            return 0;
+
+        return 1;
+
+    } else {
+        /* We have to match the whole lot */
+        int i, ret;
+        OCSP_CERTID *tmpid;
+        for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++) {
+            tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId;
+            ret = ocsp_match_issuerid(cert, tmpid, NULL);
+            if (ret <= 0)
+                return ret;
+        }
+        return 1;
+    }
+
+}
+
+static int ocsp_check_delegated(X509 *x)
+{
+    if ((X509_get_extension_flags(x) & EXFLAG_XKUSAGE)
+        && (X509_get_extended_key_usage(x) & XKU_OCSP_SIGN))
+        return 1;
+    OCSPerr(OCSP_F_OCSP_CHECK_DELEGATED, OCSP_R_MISSING_OCSPSIGNING_USAGE);
+    return 0;
+}
+
+/*
+ * Verify an OCSP request. This is fortunately much easier than OCSP response
+ * verify. Just find the signers certificate and verify it against a given
+ * trust value.
+ */
+
+int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs,
+                        X509_STORE *store, unsigned long flags)
+{
+    X509 *signer;
+    X509_NAME *nm;
+    GENERAL_NAME *gen;
+    int ret = 0;
+    X509_STORE_CTX *ctx = X509_STORE_CTX_new();
+
+    if (ctx == NULL) {
+        OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (!req->optionalSignature) {
+        OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_REQUEST_NOT_SIGNED);
+        goto err;
+    }
+    gen = req->tbsRequest.requestorName;
+    if (!gen || gen->type != GEN_DIRNAME) {
+        OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,
+                OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE);
+        goto err;
+    }
+    nm = gen->d.directoryName;
+    ret = ocsp_req_find_signer(&signer, req, nm, certs, flags);
+    if (ret <= 0) {
+        OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,
+                OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND);
+        goto err;
+    }
+    if ((ret == 2) && (flags & OCSP_TRUSTOTHER))
+        flags |= OCSP_NOVERIFY;
+    if (!(flags & OCSP_NOSIGS)) {
+        EVP_PKEY *skey;
+        skey = X509_get0_pubkey(signer);
+        ret = OCSP_REQUEST_verify(req, skey);
+        if (ret <= 0) {
+            OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNATURE_FAILURE);
+            goto err;
+        }
+    }
+    if (!(flags & OCSP_NOVERIFY)) {
+        int init_res;
+        if (flags & OCSP_NOCHAIN)
+            init_res = X509_STORE_CTX_init(ctx, store, signer, NULL);
+        else
+            init_res = X509_STORE_CTX_init(ctx, store, signer,
+                                           req->optionalSignature->certs);
+        if (!init_res) {
+            OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, ERR_R_X509_LIB);
+            goto err;
+        }
+
+        X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_OCSP_HELPER);
+        X509_STORE_CTX_set_trust(ctx, X509_TRUST_OCSP_REQUEST);
+        ret = X509_verify_cert(ctx);
+        if (ret <= 0) {
+            ret = X509_STORE_CTX_get_error(ctx);
+            OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY,
+                    OCSP_R_CERTIFICATE_VERIFY_ERROR);
+            ERR_add_error_data(2, "Verify error:",
+                               X509_verify_cert_error_string(ret));
+            goto err;
+        }
+    }
+    ret = 1;
+    goto end;
+
+err:
+    ret = 0;
+end:
+    X509_STORE_CTX_free(ctx);
+    return ret;
+
+}
+
+static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req,
+                                X509_NAME *nm, STACK_OF(X509) *certs,
+                                unsigned long flags)
+{
+    X509 *signer;
+    if (!(flags & OCSP_NOINTERN)) {
+        signer = X509_find_by_subject(req->optionalSignature->certs, nm);
+        if (signer) {
+            *psigner = signer;
+            return 1;
+        }
+    }
+
+    signer = X509_find_by_subject(certs, nm);
+    if (signer) {
+        *psigner = signer;
+        return 2;
+    }
+    return 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/v3_ocsp.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/v3_ocsp.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ocsp/v3_ocsp.c	(revision 331)
@@ -0,0 +1,264 @@
+/*
+ * Copyright 2000-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 <stdio.h>
+# include "internal/cryptlib.h"
+# include <openssl/conf.h>
+# include <openssl/asn1.h>
+# include <openssl/ocsp.h>
+# include "ocsp_lcl.h"
+# include <openssl/x509v3.h>
+# include "../x509v3/ext_dat.h"
+
+/*
+ * OCSP extensions and a couple of CRL entry extensions
+ */
+
+static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *nonce,
+                          BIO *out, int indent);
+static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce,
+                            BIO *out, int indent);
+static int i2r_object(const X509V3_EXT_METHOD *method, void *obj, BIO *out,
+                      int indent);
+
+static void *ocsp_nonce_new(void);
+static int i2d_ocsp_nonce(void *a, unsigned char **pp);
+static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length);
+static void ocsp_nonce_free(void *a);
+static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
+                          BIO *out, int indent);
+
+static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method,
+                            void *nocheck, BIO *out, int indent);
+static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method,
+                              X509V3_CTX *ctx, const char *str);
+static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in,
+                               BIO *bp, int ind);
+
+const X509V3_EXT_METHOD v3_ocsp_crlid = {
+    NID_id_pkix_OCSP_CrlID, 0, ASN1_ITEM_ref(OCSP_CRLID),
+    0, 0, 0, 0,
+    0, 0,
+    0, 0,
+    i2r_ocsp_crlid, 0,
+    NULL
+};
+
+const X509V3_EXT_METHOD v3_ocsp_acutoff = {
+    NID_id_pkix_OCSP_archiveCutoff, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
+    0, 0, 0, 0,
+    0, 0,
+    0, 0,
+    i2r_ocsp_acutoff, 0,
+    NULL
+};
+
+const X509V3_EXT_METHOD v3_crl_invdate = {
+    NID_invalidity_date, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME),
+    0, 0, 0, 0,
+    0, 0,
+    0, 0,
+    i2r_ocsp_acutoff, 0,
+    NULL
+};
+
+const X509V3_EXT_METHOD v3_crl_hold = {
+    NID_hold_instruction_code, 0, ASN1_ITEM_ref(ASN1_OBJECT),
+    0, 0, 0, 0,
+    0, 0,
+    0, 0,
+    i2r_object, 0,
+    NULL
+};
+
+const X509V3_EXT_METHOD v3_ocsp_nonce = {
+    NID_id_pkix_OCSP_Nonce, 0, NULL,
+    ocsp_nonce_new,
+    ocsp_nonce_free,
+    d2i_ocsp_nonce,
+    i2d_ocsp_nonce,
+    0, 0,
+    0, 0,
+    i2r_ocsp_nonce, 0,
+    NULL
+};
+
+const X509V3_EXT_METHOD v3_ocsp_nocheck = {
+    NID_id_pkix_OCSP_noCheck, 0, ASN1_ITEM_ref(ASN1_NULL),
+    0, 0, 0, 0,
+    0, s2i_ocsp_nocheck,
+    0, 0,
+    i2r_ocsp_nocheck, 0,
+    NULL
+};
+
+const X509V3_EXT_METHOD v3_ocsp_serviceloc = {
+    NID_id_pkix_OCSP_serviceLocator, 0, ASN1_ITEM_ref(OCSP_SERVICELOC),
+    0, 0, 0, 0,
+    0, 0,
+    0, 0,
+    i2r_ocsp_serviceloc, 0,
+    NULL
+};
+
+static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *in, BIO *bp,
+                          int ind)
+{
+    OCSP_CRLID *a = in;
+    if (a->crlUrl) {
+        if (BIO_printf(bp, "%*scrlUrl: ", ind, "") <= 0)
+            goto err;
+        if (!ASN1_STRING_print(bp, (ASN1_STRING *)a->crlUrl))
+            goto err;
+        if (BIO_write(bp, "\n", 1) <= 0)
+            goto err;
+    }
+    if (a->crlNum) {
+        if (BIO_printf(bp, "%*scrlNum: ", ind, "") <= 0)
+            goto err;
+        if (i2a_ASN1_INTEGER(bp, a->crlNum) <= 0)
+            goto err;
+        if (BIO_write(bp, "\n", 1) <= 0)
+            goto err;
+    }
+    if (a->crlTime) {
+        if (BIO_printf(bp, "%*scrlTime: ", ind, "") <= 0)
+            goto err;
+        if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime))
+            goto err;
+        if (BIO_write(bp, "\n", 1) <= 0)
+            goto err;
+    }
+    return 1;
+ err:
+    return 0;
+}
+
+static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *cutoff,
+                            BIO *bp, int ind)
+{
+    if (BIO_printf(bp, "%*s", ind, "") <= 0)
+        return 0;
+    if (!ASN1_GENERALIZEDTIME_print(bp, cutoff))
+        return 0;
+    return 1;
+}
+
+static int i2r_object(const X509V3_EXT_METHOD *method, void *oid, BIO *bp,
+                      int ind)
+{
+    if (BIO_printf(bp, "%*s", ind, "") <= 0)
+        return 0;
+    if (i2a_ASN1_OBJECT(bp, oid) <= 0)
+        return 0;
+    return 1;
+}
+
+/*
+ * OCSP nonce. This is needs special treatment because it doesn't have an
+ * ASN1 encoding at all: it just contains arbitrary data.
+ */
+
+static void *ocsp_nonce_new(void)
+{
+    return ASN1_OCTET_STRING_new();
+}
+
+static int i2d_ocsp_nonce(void *a, unsigned char **pp)
+{
+    ASN1_OCTET_STRING *os = a;
+    if (pp) {
+        memcpy(*pp, os->data, os->length);
+        *pp += os->length;
+    }
+    return os->length;
+}
+
+static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length)
+{
+    ASN1_OCTET_STRING *os, **pos;
+    pos = a;
+    if (pos == NULL || *pos == NULL) {
+        os = ASN1_OCTET_STRING_new();
+        if (os == NULL)
+            goto err;
+    } else {
+        os = *pos;
+    }
+    if (!ASN1_OCTET_STRING_set(os, *pp, length))
+        goto err;
+
+    *pp += length;
+
+    if (pos)
+        *pos = os;
+    return os;
+
+ err:
+    if ((pos == NULL) || (*pos != os))
+        ASN1_OCTET_STRING_free(os);
+    OCSPerr(OCSP_F_D2I_OCSP_NONCE, ERR_R_MALLOC_FAILURE);
+    return NULL;
+}
+
+static void ocsp_nonce_free(void *a)
+{
+    ASN1_OCTET_STRING_free(a);
+}
+
+static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce,
+                          BIO *out, int indent)
+{
+    if (BIO_printf(out, "%*s", indent, "") <= 0)
+        return 0;
+    if (i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0)
+        return 0;
+    return 1;
+}
+
+/* Nocheck is just a single NULL. Don't print anything and always set it */
+
+static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck,
+                            BIO *out, int indent)
+{
+    return 1;
+}
+
+static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method,
+                              X509V3_CTX *ctx, const char *str)
+{
+    return ASN1_NULL_new();
+}
+
+static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in,
+                               BIO *bp, int ind)
+{
+    int i;
+    OCSP_SERVICELOC *a = in;
+    ACCESS_DESCRIPTION *ad;
+
+    if (BIO_printf(bp, "%*sIssuer: ", ind, "") <= 0)
+        goto err;
+    if (X509_NAME_print_ex(bp, a->issuer, 0, XN_FLAG_ONELINE) <= 0)
+        goto err;
+    for (i = 0; i < sk_ACCESS_DESCRIPTION_num(a->locator); i++) {
+        ad = sk_ACCESS_DESCRIPTION_value(a->locator, i);
+        if (BIO_printf(bp, "\n%*s", (2 * ind), "") <= 0)
+            goto err;
+        if (i2a_ASN1_OBJECT(bp, ad->method) <= 0)
+            goto err;
+        if (BIO_puts(bp, " - ") <= 0)
+            goto err;
+        if (GENERAL_NAME_print(bp, ad->location) <= 0)
+            goto err;
+    }
+    return 1;
+ err:
+    return 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_all.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_all.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_all.c	(revision 331)
@@ -0,0 +1,181 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pem.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/dh.h>
+
+#ifndef OPENSSL_NO_RSA
+static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa);
+#endif
+#ifndef OPENSSL_NO_DSA
+static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa);
+#endif
+
+#ifndef OPENSSL_NO_EC
+static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey);
+#endif
+
+IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ)
+
+IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ)
+IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL)
+IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7)
+
+IMPLEMENT_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE,
+                 PEM_STRING_X509, NETSCAPE_CERT_SEQUENCE)
+#ifndef OPENSSL_NO_RSA
+/*
+ * We treat RSA or DSA private keys as a special case. For private keys we
+ * read in an EVP_PKEY structure with PEM_read_bio_PrivateKey() and extract
+ * the relevant private key: this means can handle "traditional" and PKCS#8
+ * formats transparently.
+ */
+static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa)
+{
+    RSA *rtmp;
+    if (!key)
+        return NULL;
+    rtmp = EVP_PKEY_get1_RSA(key);
+    EVP_PKEY_free(key);
+    if (!rtmp)
+        return NULL;
+    if (rsa) {
+        RSA_free(*rsa);
+        *rsa = rtmp;
+    }
+    return rtmp;
+}
+
+RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb,
+                                void *u)
+{
+    EVP_PKEY *pktmp;
+    pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
+    return pkey_get_rsa(pktmp, rsa);
+}
+
+# ifndef OPENSSL_NO_STDIO
+
+RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u)
+{
+    EVP_PKEY *pktmp;
+    pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
+    return pkey_get_rsa(pktmp, rsa);
+}
+
+# endif
+
+IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA,
+                             RSAPrivateKey)
+
+
+IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC,
+                       RSAPublicKey) IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA,
+                                                      PEM_STRING_PUBLIC,
+                                                      RSA_PUBKEY)
+#endif
+#ifndef OPENSSL_NO_DSA
+static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa)
+{
+    DSA *dtmp;
+    if (!key)
+        return NULL;
+    dtmp = EVP_PKEY_get1_DSA(key);
+    EVP_PKEY_free(key);
+    if (!dtmp)
+        return NULL;
+    if (dsa) {
+        DSA_free(*dsa);
+        *dsa = dtmp;
+    }
+    return dtmp;
+}
+
+DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb,
+                                void *u)
+{
+    EVP_PKEY *pktmp;
+    pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
+    return pkey_get_dsa(pktmp, dsa); /* will free pktmp */
+}
+
+IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA,
+                             DSAPrivateKey)
+    IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY)
+# ifndef OPENSSL_NO_STDIO
+DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u)
+{
+    EVP_PKEY *pktmp;
+    pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
+    return pkey_get_dsa(pktmp, dsa); /* will free pktmp */
+}
+
+# endif
+
+IMPLEMENT_PEM_rw_const(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams)
+#endif
+#ifndef OPENSSL_NO_EC
+static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey)
+{
+    EC_KEY *dtmp;
+    if (!key)
+        return NULL;
+    dtmp = EVP_PKEY_get1_EC_KEY(key);
+    EVP_PKEY_free(key);
+    if (!dtmp)
+        return NULL;
+    if (eckey) {
+        EC_KEY_free(*eckey);
+        *eckey = dtmp;
+    }
+    return dtmp;
+}
+
+EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb,
+                                  void *u)
+{
+    EVP_PKEY *pktmp;
+    pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u);
+    return pkey_get_eckey(pktmp, key); /* will free pktmp */
+}
+
+IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS,
+                       ECPKParameters)
+
+
+IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY,
+                       ECPrivateKey)
+IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY)
+# ifndef OPENSSL_NO_STDIO
+EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb,
+                              void *u)
+{
+    EVP_PKEY *pktmp;
+    pktmp = PEM_read_PrivateKey(fp, NULL, cb, u);
+    return pkey_get_eckey(pktmp, eckey); /* will free pktmp */
+}
+
+# endif
+
+#endif
+
+#ifndef OPENSSL_NO_DH
+
+IMPLEMENT_PEM_write_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams)
+    IMPLEMENT_PEM_write_const(DHxparams, DH, PEM_STRING_DHXPARAMS, DHxparams)
+#endif
+IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_err.c	(revision 331)
@@ -0,0 +1,115 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_PEM,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_PEM,0,reason)
+
+static ERR_STRING_DATA PEM_str_functs[] = {
+    {ERR_FUNC(PEM_F_B2I_DSS), "b2i_dss"},
+    {ERR_FUNC(PEM_F_B2I_PVK_BIO), "b2i_PVK_bio"},
+    {ERR_FUNC(PEM_F_B2I_RSA), "b2i_rsa"},
+    {ERR_FUNC(PEM_F_CHECK_BITLEN_DSA), "check_bitlen_dsa"},
+    {ERR_FUNC(PEM_F_CHECK_BITLEN_RSA), "check_bitlen_rsa"},
+    {ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_BIO), "d2i_PKCS8PrivateKey_bio"},
+    {ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_FP), "d2i_PKCS8PrivateKey_fp"},
+    {ERR_FUNC(PEM_F_DO_B2I), "do_b2i"},
+    {ERR_FUNC(PEM_F_DO_B2I_BIO), "do_b2i_bio"},
+    {ERR_FUNC(PEM_F_DO_BLOB_HEADER), "do_blob_header"},
+    {ERR_FUNC(PEM_F_DO_PK8PKEY), "do_pk8pkey"},
+    {ERR_FUNC(PEM_F_DO_PK8PKEY_FP), "do_pk8pkey_fp"},
+    {ERR_FUNC(PEM_F_DO_PVK_BODY), "do_PVK_body"},
+    {ERR_FUNC(PEM_F_DO_PVK_HEADER), "do_PVK_header"},
+    {ERR_FUNC(PEM_F_I2B_PVK), "i2b_PVK"},
+    {ERR_FUNC(PEM_F_I2B_PVK_BIO), "i2b_PVK_bio"},
+    {ERR_FUNC(PEM_F_LOAD_IV), "load_iv"},
+    {ERR_FUNC(PEM_F_PEM_ASN1_READ), "PEM_ASN1_read"},
+    {ERR_FUNC(PEM_F_PEM_ASN1_READ_BIO), "PEM_ASN1_read_bio"},
+    {ERR_FUNC(PEM_F_PEM_ASN1_WRITE), "PEM_ASN1_write"},
+    {ERR_FUNC(PEM_F_PEM_ASN1_WRITE_BIO), "PEM_ASN1_write_bio"},
+    {ERR_FUNC(PEM_F_PEM_DEF_CALLBACK), "PEM_def_callback"},
+    {ERR_FUNC(PEM_F_PEM_DO_HEADER), "PEM_do_header"},
+    {ERR_FUNC(PEM_F_PEM_GET_EVP_CIPHER_INFO), "PEM_get_EVP_CIPHER_INFO"},
+    {ERR_FUNC(PEM_F_PEM_READ), "PEM_read"},
+    {ERR_FUNC(PEM_F_PEM_READ_BIO), "PEM_read_bio"},
+    {ERR_FUNC(PEM_F_PEM_READ_BIO_DHPARAMS), "PEM_read_bio_DHparams"},
+    {ERR_FUNC(PEM_F_PEM_READ_BIO_PARAMETERS), "PEM_read_bio_Parameters"},
+    {ERR_FUNC(PEM_F_PEM_READ_BIO_PRIVATEKEY), "PEM_read_bio_PrivateKey"},
+    {ERR_FUNC(PEM_F_PEM_READ_DHPARAMS), "PEM_read_DHparams"},
+    {ERR_FUNC(PEM_F_PEM_READ_PRIVATEKEY), "PEM_read_PrivateKey"},
+    {ERR_FUNC(PEM_F_PEM_SIGNFINAL), "PEM_SignFinal"},
+    {ERR_FUNC(PEM_F_PEM_WRITE), "PEM_write"},
+    {ERR_FUNC(PEM_F_PEM_WRITE_BIO), "PEM_write_bio"},
+    {ERR_FUNC(PEM_F_PEM_WRITE_PRIVATEKEY), "PEM_write_PrivateKey"},
+    {ERR_FUNC(PEM_F_PEM_X509_INFO_READ), "PEM_X509_INFO_read"},
+    {ERR_FUNC(PEM_F_PEM_X509_INFO_READ_BIO), "PEM_X509_INFO_read_bio"},
+    {ERR_FUNC(PEM_F_PEM_X509_INFO_WRITE_BIO), "PEM_X509_INFO_write_bio"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA PEM_str_reasons[] = {
+    {ERR_REASON(PEM_R_BAD_BASE64_DECODE), "bad base64 decode"},
+    {ERR_REASON(PEM_R_BAD_DECRYPT), "bad decrypt"},
+    {ERR_REASON(PEM_R_BAD_END_LINE), "bad end line"},
+    {ERR_REASON(PEM_R_BAD_IV_CHARS), "bad iv chars"},
+    {ERR_REASON(PEM_R_BAD_MAGIC_NUMBER), "bad magic number"},
+    {ERR_REASON(PEM_R_BAD_PASSWORD_READ), "bad password read"},
+    {ERR_REASON(PEM_R_BAD_VERSION_NUMBER), "bad version number"},
+    {ERR_REASON(PEM_R_BIO_WRITE_FAILURE), "bio write failure"},
+    {ERR_REASON(PEM_R_CIPHER_IS_NULL), "cipher is null"},
+    {ERR_REASON(PEM_R_ERROR_CONVERTING_PRIVATE_KEY),
+     "error converting private key"},
+    {ERR_REASON(PEM_R_EXPECTING_PRIVATE_KEY_BLOB),
+     "expecting private key blob"},
+    {ERR_REASON(PEM_R_EXPECTING_PUBLIC_KEY_BLOB),
+     "expecting public key blob"},
+    {ERR_REASON(PEM_R_HEADER_TOO_LONG), "header too long"},
+    {ERR_REASON(PEM_R_INCONSISTENT_HEADER), "inconsistent header"},
+    {ERR_REASON(PEM_R_KEYBLOB_HEADER_PARSE_ERROR),
+     "keyblob header parse error"},
+    {ERR_REASON(PEM_R_KEYBLOB_TOO_SHORT), "keyblob too short"},
+    {ERR_REASON(PEM_R_MISSING_DEK_IV), "missing dek iv"},
+    {ERR_REASON(PEM_R_NOT_DEK_INFO), "not dek info"},
+    {ERR_REASON(PEM_R_NOT_ENCRYPTED), "not encrypted"},
+    {ERR_REASON(PEM_R_NOT_PROC_TYPE), "not proc type"},
+    {ERR_REASON(PEM_R_NO_START_LINE), "no start line"},
+    {ERR_REASON(PEM_R_PROBLEMS_GETTING_PASSWORD),
+     "problems getting password"},
+    {ERR_REASON(PEM_R_PVK_DATA_TOO_SHORT), "pvk data too short"},
+    {ERR_REASON(PEM_R_PVK_TOO_SHORT), "pvk too short"},
+    {ERR_REASON(PEM_R_READ_KEY), "read key"},
+    {ERR_REASON(PEM_R_SHORT_HEADER), "short header"},
+    {ERR_REASON(PEM_R_UNEXPECTED_DEK_IV), "unexpected dek iv"},
+    {ERR_REASON(PEM_R_UNSUPPORTED_CIPHER), "unsupported cipher"},
+    {ERR_REASON(PEM_R_UNSUPPORTED_ENCRYPTION), "unsupported encryption"},
+    {ERR_REASON(PEM_R_UNSUPPORTED_KEY_COMPONENTS),
+     "unsupported key components"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_PEM_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(PEM_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, PEM_str_functs);
+        ERR_load_strings(0, PEM_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_info.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_info.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_info.c	(revision 331)
@@ -0,0 +1,334 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+
+#ifndef OPENSSL_NO_STDIO
+STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
+                                        pem_password_cb *cb, void *u)
+{
+    BIO *b;
+    STACK_OF(X509_INFO) *ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        PEMerr(PEM_F_PEM_X509_INFO_READ, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = PEM_X509_INFO_read_bio(b, sk, cb, u);
+    BIO_free(b);
+    return (ret);
+}
+#endif
+
+STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk,
+                                            pem_password_cb *cb, void *u)
+{
+    X509_INFO *xi = NULL;
+    char *name = NULL, *header = NULL;
+    void *pp;
+    unsigned char *data = NULL;
+    const unsigned char *p;
+    long len, error = 0;
+    int ok = 0;
+    STACK_OF(X509_INFO) *ret = NULL;
+    unsigned int i, raw, ptype;
+    d2i_of_void *d2i = 0;
+
+    if (sk == NULL) {
+        if ((ret = sk_X509_INFO_new_null()) == NULL) {
+            PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    } else
+        ret = sk;
+
+    if ((xi = X509_INFO_new()) == NULL)
+        goto err;
+    for (;;) {
+        raw = 0;
+        ptype = 0;
+        i = PEM_read_bio(bp, &name, &header, &data, &len);
+        if (i == 0) {
+            error = ERR_GET_REASON(ERR_peek_last_error());
+            if (error == PEM_R_NO_START_LINE) {
+                ERR_clear_error();
+                break;
+            }
+            goto err;
+        }
+ start:
+        if ((strcmp(name, PEM_STRING_X509) == 0) ||
+            (strcmp(name, PEM_STRING_X509_OLD) == 0)) {
+            d2i = (D2I_OF(void)) d2i_X509;
+            if (xi->x509 != NULL) {
+                if (!sk_X509_INFO_push(ret, xi))
+                    goto err;
+                if ((xi = X509_INFO_new()) == NULL)
+                    goto err;
+                goto start;
+            }
+            pp = &(xi->x509);
+        } else if ((strcmp(name, PEM_STRING_X509_TRUSTED) == 0)) {
+            d2i = (D2I_OF(void)) d2i_X509_AUX;
+            if (xi->x509 != NULL) {
+                if (!sk_X509_INFO_push(ret, xi))
+                    goto err;
+                if ((xi = X509_INFO_new()) == NULL)
+                    goto err;
+                goto start;
+            }
+            pp = &(xi->x509);
+        } else if (strcmp(name, PEM_STRING_X509_CRL) == 0) {
+            d2i = (D2I_OF(void)) d2i_X509_CRL;
+            if (xi->crl != NULL) {
+                if (!sk_X509_INFO_push(ret, xi))
+                    goto err;
+                if ((xi = X509_INFO_new()) == NULL)
+                    goto err;
+                goto start;
+            }
+            pp = &(xi->crl);
+        } else
+#ifndef OPENSSL_NO_RSA
+        if (strcmp(name, PEM_STRING_RSA) == 0) {
+            d2i = (D2I_OF(void)) d2i_RSAPrivateKey;
+            if (xi->x_pkey != NULL) {
+                if (!sk_X509_INFO_push(ret, xi))
+                    goto err;
+                if ((xi = X509_INFO_new()) == NULL)
+                    goto err;
+                goto start;
+            }
+
+            xi->enc_data = NULL;
+            xi->enc_len = 0;
+
+            xi->x_pkey = X509_PKEY_new();
+            if (xi->x_pkey == NULL)
+                goto err;
+            ptype = EVP_PKEY_RSA;
+            pp = &xi->x_pkey->dec_pkey;
+            if ((int)strlen(header) > 10) /* assume encrypted */
+                raw = 1;
+        } else
+#endif
+#ifndef OPENSSL_NO_DSA
+        if (strcmp(name, PEM_STRING_DSA) == 0) {
+            d2i = (D2I_OF(void)) d2i_DSAPrivateKey;
+            if (xi->x_pkey != NULL) {
+                if (!sk_X509_INFO_push(ret, xi))
+                    goto err;
+                if ((xi = X509_INFO_new()) == NULL)
+                    goto err;
+                goto start;
+            }
+
+            xi->enc_data = NULL;
+            xi->enc_len = 0;
+
+            xi->x_pkey = X509_PKEY_new();
+            if (xi->x_pkey == NULL)
+                goto err;
+            ptype = EVP_PKEY_DSA;
+            pp = &xi->x_pkey->dec_pkey;
+            if ((int)strlen(header) > 10) /* assume encrypted */
+                raw = 1;
+        } else
+#endif
+#ifndef OPENSSL_NO_EC
+        if (strcmp(name, PEM_STRING_ECPRIVATEKEY) == 0) {
+            d2i = (D2I_OF(void)) d2i_ECPrivateKey;
+            if (xi->x_pkey != NULL) {
+                if (!sk_X509_INFO_push(ret, xi))
+                    goto err;
+                if ((xi = X509_INFO_new()) == NULL)
+                    goto err;
+                goto start;
+            }
+
+            xi->enc_data = NULL;
+            xi->enc_len = 0;
+
+            xi->x_pkey = X509_PKEY_new();
+            if (xi->x_pkey == NULL)
+                goto err;
+            ptype = EVP_PKEY_EC;
+            pp = &xi->x_pkey->dec_pkey;
+            if ((int)strlen(header) > 10) /* assume encrypted */
+                raw = 1;
+        } else
+#endif
+        {
+            d2i = NULL;
+            pp = NULL;
+        }
+
+        if (d2i != NULL) {
+            if (!raw) {
+                EVP_CIPHER_INFO cipher;
+
+                if (!PEM_get_EVP_CIPHER_INFO(header, &cipher))
+                    goto err;
+                if (!PEM_do_header(&cipher, data, &len, cb, u))
+                    goto err;
+                p = data;
+                if (ptype) {
+                    if (!d2i_PrivateKey(ptype, pp, &p, len)) {
+                        PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_ASN1_LIB);
+                        goto err;
+                    }
+                } else if (d2i(pp, &p, len) == NULL) {
+                    PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_ASN1_LIB);
+                    goto err;
+                }
+            } else {            /* encrypted RSA data */
+                if (!PEM_get_EVP_CIPHER_INFO(header, &xi->enc_cipher))
+                    goto err;
+                xi->enc_data = (char *)data;
+                xi->enc_len = (int)len;
+                data = NULL;
+            }
+        } else {
+            /* unknown */
+        }
+        OPENSSL_free(name);
+        name = NULL;
+        OPENSSL_free(header);
+        header = NULL;
+        OPENSSL_free(data);
+        data = NULL;
+    }
+
+    /*
+     * if the last one hasn't been pushed yet and there is anything in it
+     * then add it to the stack ...
+     */
+    if ((xi->x509 != NULL) || (xi->crl != NULL) ||
+        (xi->x_pkey != NULL) || (xi->enc_data != NULL)) {
+        if (!sk_X509_INFO_push(ret, xi))
+            goto err;
+        xi = NULL;
+    }
+    ok = 1;
+ err:
+    X509_INFO_free(xi);
+    if (!ok) {
+        for (i = 0; ((int)i) < sk_X509_INFO_num(ret); i++) {
+            xi = sk_X509_INFO_value(ret, i);
+            X509_INFO_free(xi);
+        }
+        if (ret != sk)
+            sk_X509_INFO_free(ret);
+        ret = NULL;
+    }
+
+    OPENSSL_free(name);
+    OPENSSL_free(header);
+    OPENSSL_free(data);
+    return (ret);
+}
+
+/* A TJH addition */
+int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
+                            unsigned char *kstr, int klen,
+                            pem_password_cb *cb, void *u)
+{
+    int i, ret = 0;
+    unsigned char *data = NULL;
+    const char *objstr = NULL;
+    char buf[PEM_BUFSIZE];
+    unsigned char *iv = NULL;
+
+    if (enc != NULL) {
+        objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
+        if (objstr == NULL) {
+            PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER);
+            goto err;
+        }
+    }
+
+    /*
+     * now for the fun part ... if we have a private key then we have to be
+     * able to handle a not-yet-decrypted key being written out correctly ...
+     * if it is decrypted or it is non-encrypted then we use the base code
+     */
+    if (xi->x_pkey != NULL) {
+        if ((xi->enc_data != NULL) && (xi->enc_len > 0)) {
+            if (enc == NULL) {
+                PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, PEM_R_CIPHER_IS_NULL);
+                goto err;
+            }
+
+            /* copy from weirdo names into more normal things */
+            iv = xi->enc_cipher.iv;
+            data = (unsigned char *)xi->enc_data;
+            i = xi->enc_len;
+
+            /*
+             * we take the encryption data from the internal stuff rather
+             * than what the user has passed us ... as we have to match
+             * exactly for some strange reason
+             */
+            objstr = OBJ_nid2sn(EVP_CIPHER_nid(xi->enc_cipher.cipher));
+            if (objstr == NULL) {
+                PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,
+                       PEM_R_UNSUPPORTED_CIPHER);
+                goto err;
+            }
+
+            /* create the right magic header stuff */
+            OPENSSL_assert(strlen(objstr) + 23
+                           + 2 * EVP_CIPHER_iv_length(enc) + 13 <=
+                           sizeof buf);
+            buf[0] = '\0';
+            PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
+            PEM_dek_info(buf, objstr, EVP_CIPHER_iv_length(enc),
+                         (char *)iv);
+
+            /* use the normal code to write things out */
+            i = PEM_write_bio(bp, PEM_STRING_RSA, buf, data, i);
+            if (i <= 0)
+                goto err;
+        } else {
+            /* Add DSA/DH */
+#ifndef OPENSSL_NO_RSA
+            /* normal optionally encrypted stuff */
+            if (PEM_write_bio_RSAPrivateKey(bp,
+                                            EVP_PKEY_get0_RSA(xi->x_pkey->dec_pkey),
+                                            enc, kstr, klen, cb, u) <= 0)
+                goto err;
+#endif
+        }
+    }
+
+    /* if we have a certificate then write it out now */
+    if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp, xi->x509) <= 0))
+        goto err;
+
+    /*
+     * we are ignoring anything else that is loaded into the X509_INFO
+     * structure for the moment ... as I don't need it so I'm not coding it
+     * here and Eric can do it when this makes it into the base library --tjh
+     */
+
+    ret = 1;
+
+ err:
+    OPENSSL_cleanse(buf, PEM_BUFSIZE);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_lib.c	(revision 331)
@@ -0,0 +1,857 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/pkcs12.h>
+#include "internal/asn1_int.h"
+#include <openssl/des.h>
+#include <openssl/engine.h>
+
+#define MIN_LENGTH      4
+
+static int load_iv(char **fromp, unsigned char *to, int num);
+static int check_pem(const char *nm, const char *name);
+int pem_check_suffix(const char *pem_str, const char *suffix);
+
+int PEM_def_callback(char *buf, int num, int w, void *key)
+{
+#if defined(OPENSSL_NO_STDIO) || defined(OPENSSL_NO_UI)
+    int i;
+#else
+    int i, j;
+    const char *prompt;
+#endif
+
+    if (key) {
+        i = strlen(key);
+        i = (i > num) ? num : i;
+        memcpy(buf, key, i);
+        return i;
+    }
+
+#if defined(OPENSSL_NO_STDIO) || defined(OPENSSL_NO_UI)
+    PEMerr(PEM_F_PEM_DEF_CALLBACK, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    return -1;
+#else
+    prompt = EVP_get_pw_prompt();
+    if (prompt == NULL)
+        prompt = "Enter PEM pass phrase:";
+
+    for (;;) {
+        /*
+         * We assume that w == 0 means decryption,
+         * while w == 1 means encryption
+         */
+        int min_len = w ? MIN_LENGTH : 0;
+
+        i = EVP_read_pw_string_min(buf, min_len, num, prompt, w);
+        if (i != 0) {
+            PEMerr(PEM_F_PEM_DEF_CALLBACK, PEM_R_PROBLEMS_GETTING_PASSWORD);
+            memset(buf, 0, (unsigned int)num);
+            return -1;
+        }
+        j = strlen(buf);
+        if (min_len && j < min_len) {
+            fprintf(stderr,
+                    "phrase is too short, needs to be at least %d chars\n",
+                    min_len);
+        } else
+            break;
+    }
+    return j;
+#endif
+}
+
+void PEM_proc_type(char *buf, int type)
+{
+    const char *str;
+
+    if (type == PEM_TYPE_ENCRYPTED)
+        str = "ENCRYPTED";
+    else if (type == PEM_TYPE_MIC_CLEAR)
+        str = "MIC-CLEAR";
+    else if (type == PEM_TYPE_MIC_ONLY)
+        str = "MIC-ONLY";
+    else
+        str = "BAD-TYPE";
+
+    OPENSSL_strlcat(buf, "Proc-Type: 4,", PEM_BUFSIZE);
+    OPENSSL_strlcat(buf, str, PEM_BUFSIZE);
+    OPENSSL_strlcat(buf, "\n", PEM_BUFSIZE);
+}
+
+void PEM_dek_info(char *buf, const char *type, int len, char *str)
+{
+    static const unsigned char map[17] = "0123456789ABCDEF";
+    long i;
+    int j;
+
+    OPENSSL_strlcat(buf, "DEK-Info: ", PEM_BUFSIZE);
+    OPENSSL_strlcat(buf, type, PEM_BUFSIZE);
+    OPENSSL_strlcat(buf, ",", PEM_BUFSIZE);
+    j = strlen(buf);
+    if (j + (len * 2) + 1 > PEM_BUFSIZE)
+        return;
+    for (i = 0; i < len; i++) {
+        buf[j + i * 2] = map[(str[i] >> 4) & 0x0f];
+        buf[j + i * 2 + 1] = map[(str[i]) & 0x0f];
+    }
+    buf[j + i * 2] = '\n';
+    buf[j + i * 2 + 1] = '\0';
+}
+
+#ifndef OPENSSL_NO_STDIO
+void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
+                    pem_password_cb *cb, void *u)
+{
+    BIO *b;
+    void *ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        PEMerr(PEM_F_PEM_ASN1_READ, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = PEM_ASN1_read_bio(d2i, name, b, x, cb, u);
+    BIO_free(b);
+    return (ret);
+}
+#endif
+
+static int check_pem(const char *nm, const char *name)
+{
+    /* Normal matching nm and name */
+    if (strcmp(nm, name) == 0)
+        return 1;
+
+    /* Make PEM_STRING_EVP_PKEY match any private key */
+
+    if (strcmp(name, PEM_STRING_EVP_PKEY) == 0) {
+        int slen;
+        const EVP_PKEY_ASN1_METHOD *ameth;
+        if (strcmp(nm, PEM_STRING_PKCS8) == 0)
+            return 1;
+        if (strcmp(nm, PEM_STRING_PKCS8INF) == 0)
+            return 1;
+        slen = pem_check_suffix(nm, "PRIVATE KEY");
+        if (slen > 0) {
+            /*
+             * NB: ENGINE implementations won't contain a deprecated old
+             * private key decode function so don't look for them.
+             */
+            ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
+            if (ameth && ameth->old_priv_decode)
+                return 1;
+        }
+        return 0;
+    }
+
+    if (strcmp(name, PEM_STRING_PARAMETERS) == 0) {
+        int slen;
+        const EVP_PKEY_ASN1_METHOD *ameth;
+        slen = pem_check_suffix(nm, "PARAMETERS");
+        if (slen > 0) {
+            ENGINE *e;
+            ameth = EVP_PKEY_asn1_find_str(&e, nm, slen);
+            if (ameth) {
+                int r;
+                if (ameth->param_decode)
+                    r = 1;
+                else
+                    r = 0;
+#ifndef OPENSSL_NO_ENGINE
+                ENGINE_finish(e);
+#endif
+                return r;
+            }
+        }
+        return 0;
+    }
+    /* If reading DH parameters handle X9.42 DH format too */
+    if (strcmp(nm, PEM_STRING_DHXPARAMS) == 0
+        && strcmp(name, PEM_STRING_DHPARAMS) == 0)
+        return 1;
+
+    /* Permit older strings */
+
+    if (strcmp(nm, PEM_STRING_X509_OLD) == 0
+        && strcmp(name, PEM_STRING_X509) == 0)
+        return 1;
+
+    if (strcmp(nm, PEM_STRING_X509_REQ_OLD) == 0
+        && strcmp(name, PEM_STRING_X509_REQ) == 0)
+        return 1;
+
+    /* Allow normal certs to be read as trusted certs */
+    if (strcmp(nm, PEM_STRING_X509) == 0
+        && strcmp(name, PEM_STRING_X509_TRUSTED) == 0)
+        return 1;
+
+    if (strcmp(nm, PEM_STRING_X509_OLD) == 0
+        && strcmp(name, PEM_STRING_X509_TRUSTED) == 0)
+        return 1;
+
+    /* Some CAs use PKCS#7 with CERTIFICATE headers */
+    if (strcmp(nm, PEM_STRING_X509) == 0
+        && strcmp(name, PEM_STRING_PKCS7) == 0)
+        return 1;
+
+    if (strcmp(nm, PEM_STRING_PKCS7_SIGNED) == 0
+        && strcmp(name, PEM_STRING_PKCS7) == 0)
+        return 1;
+
+#ifndef OPENSSL_NO_CMS
+    if (strcmp(nm, PEM_STRING_X509) == 0
+        && strcmp(name, PEM_STRING_CMS) == 0)
+        return 1;
+    /* Allow CMS to be read from PKCS#7 headers */
+    if (strcmp(nm, PEM_STRING_PKCS7) == 0
+        && strcmp(name, PEM_STRING_CMS) == 0)
+        return 1;
+#endif
+
+    return 0;
+}
+
+int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm,
+                       const char *name, BIO *bp, pem_password_cb *cb,
+                       void *u)
+{
+    EVP_CIPHER_INFO cipher;
+    char *nm = NULL, *header = NULL;
+    unsigned char *data = NULL;
+    long len;
+    int ret = 0;
+
+    for (;;) {
+        if (!PEM_read_bio(bp, &nm, &header, &data, &len)) {
+            if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE)
+                ERR_add_error_data(2, "Expecting: ", name);
+            return 0;
+        }
+        if (check_pem(nm, name))
+            break;
+        OPENSSL_free(nm);
+        OPENSSL_free(header);
+        OPENSSL_free(data);
+    }
+    if (!PEM_get_EVP_CIPHER_INFO(header, &cipher))
+        goto err;
+    if (!PEM_do_header(&cipher, data, &len, cb, u))
+        goto err;
+
+    *pdata = data;
+    *plen = len;
+
+    if (pnm)
+        *pnm = nm;
+
+    ret = 1;
+
+ err:
+    if (!ret || !pnm)
+        OPENSSL_free(nm);
+    OPENSSL_free(header);
+    if (!ret)
+        OPENSSL_free(data);
+    return ret;
+}
+
+#ifndef OPENSSL_NO_STDIO
+int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
+                   void *x, const EVP_CIPHER *enc, unsigned char *kstr,
+                   int klen, pem_password_cb *callback, void *u)
+{
+    BIO *b;
+    int ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        PEMerr(PEM_F_PEM_ASN1_WRITE, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = PEM_ASN1_write_bio(i2d, name, b, x, enc, kstr, klen, callback, u);
+    BIO_free(b);
+    return (ret);
+}
+#endif
+
+int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
+                       void *x, const EVP_CIPHER *enc, unsigned char *kstr,
+                       int klen, pem_password_cb *callback, void *u)
+{
+    EVP_CIPHER_CTX *ctx = NULL;
+    int dsize = 0, i = 0, j = 0, ret = 0;
+    unsigned char *p, *data = NULL;
+    const char *objstr = NULL;
+    char buf[PEM_BUFSIZE];
+    unsigned char key[EVP_MAX_KEY_LENGTH];
+    unsigned char iv[EVP_MAX_IV_LENGTH];
+
+    if (enc != NULL) {
+        objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
+        if (objstr == NULL || EVP_CIPHER_iv_length(enc) == 0) {
+            PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER);
+            goto err;
+        }
+    }
+
+    if ((dsize = i2d(x, NULL)) < 0) {
+        PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_ASN1_LIB);
+        dsize = 0;
+        goto err;
+    }
+    /* dzise + 8 bytes are needed */
+    /* actually it needs the cipher block size extra... */
+    data = OPENSSL_malloc((unsigned int)dsize + 20);
+    if (data == NULL) {
+        PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    p = data;
+    i = i2d(x, &p);
+
+    if (enc != NULL) {
+        if (kstr == NULL) {
+            if (callback == NULL)
+                klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u);
+            else
+                klen = (*callback) (buf, PEM_BUFSIZE, 1, u);
+            if (klen <= 0) {
+                PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_READ_KEY);
+                goto err;
+            }
+#ifdef CHARSET_EBCDIC
+            /* Convert the pass phrase from EBCDIC */
+            ebcdic2ascii(buf, buf, klen);
+#endif
+            kstr = (unsigned char *)buf;
+        }
+        RAND_add(data, i, 0);   /* put in the RSA key. */
+        OPENSSL_assert(EVP_CIPHER_iv_length(enc) <= (int)sizeof(iv));
+        if (RAND_bytes(iv, EVP_CIPHER_iv_length(enc)) <= 0) /* Generate a salt */
+            goto err;
+        /*
+         * The 'iv' is used as the iv and as a salt.  It is NOT taken from
+         * the BytesToKey function
+         */
+        if (!EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1, key, NULL))
+            goto err;
+
+        if (kstr == (unsigned char *)buf)
+            OPENSSL_cleanse(buf, PEM_BUFSIZE);
+
+        OPENSSL_assert(strlen(objstr) + 23 + 2 * EVP_CIPHER_iv_length(enc) + 13
+                       <= sizeof buf);
+
+        buf[0] = '\0';
+        PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
+        PEM_dek_info(buf, objstr, EVP_CIPHER_iv_length(enc), (char *)iv);
+        /* k=strlen(buf); */
+
+        ret = 1;
+        if ((ctx = EVP_CIPHER_CTX_new()) == NULL
+            || !EVP_EncryptInit_ex(ctx, enc, NULL, key, iv)
+            || !EVP_EncryptUpdate(ctx, data, &j, data, i)
+            || !EVP_EncryptFinal_ex(ctx, &(data[j]), &i))
+            ret = 0;
+        if (ret == 0)
+            goto err;
+        i += j;
+    } else {
+        ret = 1;
+        buf[0] = '\0';
+    }
+    i = PEM_write_bio(bp, name, buf, data, i);
+    if (i <= 0)
+        ret = 0;
+ err:
+    OPENSSL_cleanse(key, sizeof(key));
+    OPENSSL_cleanse(iv, sizeof(iv));
+    EVP_CIPHER_CTX_free(ctx);
+    OPENSSL_cleanse(buf, PEM_BUFSIZE);
+    OPENSSL_clear_free(data, (unsigned int)dsize);
+    return (ret);
+}
+
+int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
+                  pem_password_cb *callback, void *u)
+{
+    int ok;
+    int keylen;
+    long len = *plen;
+    int ilen = (int) len;       /* EVP_DecryptUpdate etc. take int lengths */
+    EVP_CIPHER_CTX *ctx;
+    unsigned char key[EVP_MAX_KEY_LENGTH];
+    char buf[PEM_BUFSIZE];
+
+#if LONG_MAX > INT_MAX
+    /* Check that we did not truncate the length */
+    if (len > INT_MAX) {
+        PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_HEADER_TOO_LONG);
+        return 0;
+    }
+#endif
+
+    if (cipher->cipher == NULL)
+        return 1;
+    if (callback == NULL)
+        keylen = PEM_def_callback(buf, PEM_BUFSIZE, 0, u);
+    else
+        keylen = callback(buf, PEM_BUFSIZE, 0, u);
+    if (keylen <= 0) {
+        PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_BAD_PASSWORD_READ);
+        return 0;
+    }
+#ifdef CHARSET_EBCDIC
+    /* Convert the pass phrase from EBCDIC */
+    ebcdic2ascii(buf, buf, keylen);
+#endif
+
+    if (!EVP_BytesToKey(cipher->cipher, EVP_md5(), &(cipher->iv[0]),
+                        (unsigned char *)buf, keylen, 1, key, NULL))
+        return 0;
+
+    ctx = EVP_CIPHER_CTX_new();
+    if (ctx == NULL)
+        return 0;
+
+    ok = EVP_DecryptInit_ex(ctx, cipher->cipher, NULL, key, &(cipher->iv[0]));
+    if (ok)
+        ok = EVP_DecryptUpdate(ctx, data, &ilen, data, ilen);
+    if (ok) {
+        /* Squirrel away the length of data decrypted so far. */
+        *plen = ilen;
+        ok = EVP_DecryptFinal_ex(ctx, &(data[ilen]), &ilen);
+    }
+    if (ok)
+        *plen += ilen;
+    else
+        PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_BAD_DECRYPT);
+
+    EVP_CIPHER_CTX_free(ctx);
+    OPENSSL_cleanse((char *)buf, sizeof(buf));
+    OPENSSL_cleanse((char *)key, sizeof(key));
+    return ok;
+}
+
+/*
+ * This implements a very limited PEM header parser that does not support the
+ * full grammar of rfc1421.  In particular, folded headers are not supported,
+ * nor is additional whitespace.
+ *
+ * A robust implementation would make use of a library that turns the headers
+ * into a BIO from which one folded line is read at a time, and is then split
+ * into a header label and content.  We would then parse the content of the
+ * headers we care about.  This is overkill for just this limited use-case, but
+ * presumably we also parse rfc822-style headers for S/MIME, so a common
+ * abstraction might well be more generally useful.
+ */
+int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
+{
+    static const char ProcType[] = "Proc-Type:";
+    static const char ENCRYPTED[] = "ENCRYPTED";
+    static const char DEKInfo[] = "DEK-Info:";
+    const EVP_CIPHER *enc = NULL;
+    int ivlen;
+    char *dekinfostart, c;
+
+    cipher->cipher = NULL;
+    if ((header == NULL) || (*header == '\0') || (*header == '\n'))
+        return 1;
+
+    if (strncmp(header, ProcType, sizeof(ProcType)-1) != 0) {
+        PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_PROC_TYPE);
+        return 0;
+    }
+    header += sizeof(ProcType)-1;
+    header += strspn(header, " \t");
+
+    if (*header++ != '4' || *header++ != ',')
+        return 0;
+    header += strspn(header, " \t");
+
+    /* We expect "ENCRYPTED" followed by optional white-space + line break */
+    if (strncmp(header, ENCRYPTED, sizeof(ENCRYPTED)-1) != 0 ||
+        strspn(header+sizeof(ENCRYPTED)-1, " \t\r\n") == 0) {
+        PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_ENCRYPTED);
+        return 0;
+    }
+    header += sizeof(ENCRYPTED)-1;
+    header += strspn(header, " \t\r");
+    if (*header++ != '\n') {
+        PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_SHORT_HEADER);
+        return 0;
+    }
+
+    /*-
+     * https://tools.ietf.org/html/rfc1421#section-4.6.1.3
+     * We expect "DEK-Info: algo[,hex-parameters]"
+     */
+    if (strncmp(header, DEKInfo, sizeof(DEKInfo)-1) != 0) {
+        PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_DEK_INFO);
+        return 0;
+    }
+    header += sizeof(DEKInfo)-1;
+    header += strspn(header, " \t");
+
+    /*
+     * DEK-INFO is a comma-separated combination of algorithm name and optional
+     * parameters.
+     */
+    dekinfostart = header;
+    header += strcspn(header, " \t,");
+    c = *header;
+    *header = '\0';
+    cipher->cipher = enc = EVP_get_cipherbyname(dekinfostart);
+    *header = c;
+    header += strspn(header, " \t");
+
+    if (enc == NULL) {
+        PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_UNSUPPORTED_ENCRYPTION);
+        return 0;
+    }
+    ivlen = EVP_CIPHER_iv_length(enc);
+    if (ivlen > 0 && *header++ != ',') {
+        PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_MISSING_DEK_IV);
+        return 0;
+    } else if (ivlen == 0 && *header == ',') {
+        PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_UNEXPECTED_DEK_IV);
+        return 0;
+    }
+
+    if (!load_iv(&header, cipher->iv, EVP_CIPHER_iv_length(enc)))
+        return 0;
+
+    return 1;
+}
+
+static int load_iv(char **fromp, unsigned char *to, int num)
+{
+    int v, i;
+    char *from;
+
+    from = *fromp;
+    for (i = 0; i < num; i++)
+        to[i] = 0;
+    num *= 2;
+    for (i = 0; i < num; i++) {
+        v = OPENSSL_hexchar2int(*from);
+        if (v < 0) {
+            PEMerr(PEM_F_LOAD_IV, PEM_R_BAD_IV_CHARS);
+            return (0);
+        }
+        from++;
+        to[i / 2] |= v << (long)((!(i & 1)) * 4);
+    }
+
+    *fromp = from;
+    return (1);
+}
+
+#ifndef OPENSSL_NO_STDIO
+int PEM_write(FILE *fp, const char *name, const char *header,
+              const unsigned char *data, long len)
+{
+    BIO *b;
+    int ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        PEMerr(PEM_F_PEM_WRITE, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = PEM_write_bio(b, name, header, data, len);
+    BIO_free(b);
+    return (ret);
+}
+#endif
+
+int PEM_write_bio(BIO *bp, const char *name, const char *header,
+                  const unsigned char *data, long len)
+{
+    int nlen, n, i, j, outl;
+    unsigned char *buf = NULL;
+    EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
+    int reason = ERR_R_BUF_LIB;
+
+    if (ctx == NULL) {
+        reason = ERR_R_MALLOC_FAILURE;
+        goto err;
+    }
+
+    EVP_EncodeInit(ctx);
+    nlen = strlen(name);
+
+    if ((BIO_write(bp, "-----BEGIN ", 11) != 11) ||
+        (BIO_write(bp, name, nlen) != nlen) ||
+        (BIO_write(bp, "-----\n", 6) != 6))
+        goto err;
+
+    i = strlen(header);
+    if (i > 0) {
+        if ((BIO_write(bp, header, i) != i) || (BIO_write(bp, "\n", 1) != 1))
+            goto err;
+    }
+
+    buf = OPENSSL_malloc(PEM_BUFSIZE * 8);
+    if (buf == NULL) {
+        reason = ERR_R_MALLOC_FAILURE;
+        goto err;
+    }
+
+    i = j = 0;
+    while (len > 0) {
+        n = (int)((len > (PEM_BUFSIZE * 5)) ? (PEM_BUFSIZE * 5) : len);
+        if (!EVP_EncodeUpdate(ctx, buf, &outl, &(data[j]), n))
+            goto err;
+        if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl))
+            goto err;
+        i += outl;
+        len -= n;
+        j += n;
+    }
+    EVP_EncodeFinal(ctx, buf, &outl);
+    if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl))
+        goto err;
+    if ((BIO_write(bp, "-----END ", 9) != 9) ||
+        (BIO_write(bp, name, nlen) != nlen) ||
+        (BIO_write(bp, "-----\n", 6) != 6))
+        goto err;
+    OPENSSL_clear_free(buf, PEM_BUFSIZE * 8);
+    EVP_ENCODE_CTX_free(ctx);
+    return (i + outl);
+ err:
+    OPENSSL_clear_free(buf, PEM_BUFSIZE * 8);
+    EVP_ENCODE_CTX_free(ctx);
+    PEMerr(PEM_F_PEM_WRITE_BIO, reason);
+    return (0);
+}
+
+#ifndef OPENSSL_NO_STDIO
+int PEM_read(FILE *fp, char **name, char **header, unsigned char **data,
+             long *len)
+{
+    BIO *b;
+    int ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        PEMerr(PEM_F_PEM_READ, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = PEM_read_bio(b, name, header, data, len);
+    BIO_free(b);
+    return (ret);
+}
+#endif
+
+int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
+                 long *len)
+{
+    EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
+    int end = 0, i, k, bl = 0, hl = 0, nohead = 0;
+    char buf[256];
+    BUF_MEM *nameB;
+    BUF_MEM *headerB;
+    BUF_MEM *dataB, *tmpB;
+
+    if (ctx == NULL) {
+        PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
+        return (0);
+    }
+
+    nameB = BUF_MEM_new();
+    headerB = BUF_MEM_new();
+    dataB = BUF_MEM_new();
+    if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL)) {
+        goto err;
+    }
+
+    buf[254] = '\0';
+    for (;;) {
+        i = BIO_gets(bp, buf, 254);
+
+        if (i <= 0) {
+            PEMerr(PEM_F_PEM_READ_BIO, PEM_R_NO_START_LINE);
+            goto err;
+        }
+
+        while ((i >= 0) && (buf[i] <= ' '))
+            i--;
+        buf[++i] = '\n';
+        buf[++i] = '\0';
+
+        if (strncmp(buf, "-----BEGIN ", 11) == 0) {
+            i = strlen(&(buf[11]));
+
+            if (strncmp(&(buf[11 + i - 6]), "-----\n", 6) != 0)
+                continue;
+            if (!BUF_MEM_grow(nameB, i + 9)) {
+                PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            memcpy(nameB->data, &(buf[11]), i - 6);
+            nameB->data[i - 6] = '\0';
+            break;
+        }
+    }
+    hl = 0;
+    if (!BUF_MEM_grow(headerB, 256)) {
+        PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    headerB->data[0] = '\0';
+    for (;;) {
+        i = BIO_gets(bp, buf, 254);
+        if (i <= 0)
+            break;
+
+        while ((i >= 0) && (buf[i] <= ' '))
+            i--;
+        buf[++i] = '\n';
+        buf[++i] = '\0';
+
+        if (buf[0] == '\n')
+            break;
+        if (!BUF_MEM_grow(headerB, hl + i + 9)) {
+            PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        if (strncmp(buf, "-----END ", 9) == 0) {
+            nohead = 1;
+            break;
+        }
+        memcpy(&(headerB->data[hl]), buf, i);
+        headerB->data[hl + i] = '\0';
+        hl += i;
+    }
+
+    bl = 0;
+    if (!BUF_MEM_grow(dataB, 1024)) {
+        PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    dataB->data[0] = '\0';
+    if (!nohead) {
+        for (;;) {
+            i = BIO_gets(bp, buf, 254);
+            if (i <= 0)
+                break;
+
+            while ((i >= 0) && (buf[i] <= ' '))
+                i--;
+            buf[++i] = '\n';
+            buf[++i] = '\0';
+
+            if (i != 65)
+                end = 1;
+            if (strncmp(buf, "-----END ", 9) == 0)
+                break;
+            if (i > 65)
+                break;
+            if (!BUF_MEM_grow_clean(dataB, i + bl + 9)) {
+                PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            memcpy(&(dataB->data[bl]), buf, i);
+            dataB->data[bl + i] = '\0';
+            bl += i;
+            if (end) {
+                buf[0] = '\0';
+                i = BIO_gets(bp, buf, 254);
+                if (i <= 0)
+                    break;
+
+                while ((i >= 0) && (buf[i] <= ' '))
+                    i--;
+                buf[++i] = '\n';
+                buf[++i] = '\0';
+
+                break;
+            }
+        }
+    } else {
+        tmpB = headerB;
+        headerB = dataB;
+        dataB = tmpB;
+        bl = hl;
+    }
+    i = strlen(nameB->data);
+    if ((strncmp(buf, "-----END ", 9) != 0) ||
+        (strncmp(nameB->data, &(buf[9]), i) != 0) ||
+        (strncmp(&(buf[9 + i]), "-----\n", 6) != 0)) {
+        PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_END_LINE);
+        goto err;
+    }
+
+    EVP_DecodeInit(ctx);
+    i = EVP_DecodeUpdate(ctx,
+                         (unsigned char *)dataB->data, &bl,
+                         (unsigned char *)dataB->data, bl);
+    if (i < 0) {
+        PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_BASE64_DECODE);
+        goto err;
+    }
+    i = EVP_DecodeFinal(ctx, (unsigned char *)&(dataB->data[bl]), &k);
+    if (i < 0) {
+        PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_BASE64_DECODE);
+        goto err;
+    }
+    bl += k;
+
+    if (bl == 0)
+        goto err;
+    *name = nameB->data;
+    *header = headerB->data;
+    *data = (unsigned char *)dataB->data;
+    *len = bl;
+    OPENSSL_free(nameB);
+    OPENSSL_free(headerB);
+    OPENSSL_free(dataB);
+    EVP_ENCODE_CTX_free(ctx);
+    return (1);
+ err:
+    BUF_MEM_free(nameB);
+    BUF_MEM_free(headerB);
+    BUF_MEM_free(dataB);
+    EVP_ENCODE_CTX_free(ctx);
+    return (0);
+}
+
+/*
+ * Check pem string and return prefix length. If for example the pem_str ==
+ * "RSA PRIVATE KEY" and suffix = "PRIVATE KEY" the return value is 3 for the
+ * string "RSA".
+ */
+
+int pem_check_suffix(const char *pem_str, const char *suffix)
+{
+    int pem_len = strlen(pem_str);
+    int suffix_len = strlen(suffix);
+    const char *p;
+    if (suffix_len + 1 >= pem_len)
+        return 0;
+    p = pem_str + pem_len - suffix_len;
+    if (strcmp(p, suffix))
+        return 0;
+    p--;
+    if (*p != ' ')
+        return 0;
+    return p - pem_str;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_oth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_oth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_oth.c	(revision 331)
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+/* Handle 'other' PEMs: not private keys */
+
+void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x,
+                        pem_password_cb *cb, void *u)
+{
+    const unsigned char *p = NULL;
+    unsigned char *data = NULL;
+    long len;
+    char *ret = NULL;
+
+    if (!PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u))
+        return NULL;
+    p = data;
+    ret = d2i(x, &p, len);
+    if (ret == NULL)
+        PEMerr(PEM_F_PEM_ASN1_READ_BIO, ERR_R_ASN1_LIB);
+    OPENSSL_free(data);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_pk8.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_pk8.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_pk8.c	(revision 331)
@@ -0,0 +1,213 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs12.h>
+#include <openssl/pem.h>
+
+static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder,
+                      int nid, const EVP_CIPHER *enc,
+                      char *kstr, int klen, pem_password_cb *cb, void *u);
+
+#ifndef OPENSSL_NO_STDIO
+static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder,
+                         int nid, const EVP_CIPHER *enc,
+                         char *kstr, int klen, pem_password_cb *cb, void *u);
+#endif
+/*
+ * These functions write a private key in PKCS#8 format: it is a "drop in"
+ * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc'
+ * is NULL then it uses the unencrypted private key form. The 'nid' versions
+ * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0.
+ */
+
+int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
+                                      char *kstr, int klen,
+                                      pem_password_cb *cb, void *u)
+{
+    return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u);
+}
+
+int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+                                  char *kstr, int klen,
+                                  pem_password_cb *cb, void *u)
+{
+    return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u);
+}
+
+int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+                            char *kstr, int klen,
+                            pem_password_cb *cb, void *u)
+{
+    return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u);
+}
+
+int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
+                                char *kstr, int klen,
+                                pem_password_cb *cb, void *u)
+{
+    return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u);
+}
+
+static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid,
+                      const EVP_CIPHER *enc, char *kstr, int klen,
+                      pem_password_cb *cb, void *u)
+{
+    X509_SIG *p8;
+    PKCS8_PRIV_KEY_INFO *p8inf;
+    char buf[PEM_BUFSIZE];
+    int ret;
+
+    if ((p8inf = EVP_PKEY2PKCS8(x)) == NULL) {
+        PEMerr(PEM_F_DO_PK8PKEY, PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
+        return 0;
+    }
+    if (enc || (nid != -1)) {
+        if (!kstr) {
+            if (!cb)
+                klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u);
+            else
+                klen = cb(buf, PEM_BUFSIZE, 1, u);
+            if (klen <= 0) {
+                PEMerr(PEM_F_DO_PK8PKEY, PEM_R_READ_KEY);
+                PKCS8_PRIV_KEY_INFO_free(p8inf);
+                return 0;
+            }
+
+            kstr = buf;
+        }
+        p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf);
+        if (kstr == buf)
+            OPENSSL_cleanse(buf, klen);
+        PKCS8_PRIV_KEY_INFO_free(p8inf);
+        if (p8 == NULL)
+            return 0;
+        if (isder)
+            ret = i2d_PKCS8_bio(bp, p8);
+        else
+            ret = PEM_write_bio_PKCS8(bp, p8);
+        X509_SIG_free(p8);
+        return ret;
+    } else {
+        if (isder)
+            ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
+        else
+            ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf);
+        PKCS8_PRIV_KEY_INFO_free(p8inf);
+        return ret;
+    }
+}
+
+EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
+                                  void *u)
+{
+    PKCS8_PRIV_KEY_INFO *p8inf = NULL;
+    X509_SIG *p8 = NULL;
+    int klen;
+    EVP_PKEY *ret;
+    char psbuf[PEM_BUFSIZE];
+    p8 = d2i_PKCS8_bio(bp, NULL);
+    if (!p8)
+        return NULL;
+    if (cb)
+        klen = cb(psbuf, PEM_BUFSIZE, 0, u);
+    else
+        klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
+    if (klen <= 0) {
+        PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ);
+        X509_SIG_free(p8);
+        return NULL;
+    }
+    p8inf = PKCS8_decrypt(p8, psbuf, klen);
+    X509_SIG_free(p8);
+    if (!p8inf)
+        return NULL;
+    ret = EVP_PKCS82PKEY(p8inf);
+    PKCS8_PRIV_KEY_INFO_free(p8inf);
+    if (!ret)
+        return NULL;
+    if (x) {
+        EVP_PKEY_free(*x);
+        *x = ret;
+    }
+    return ret;
+}
+
+#ifndef OPENSSL_NO_STDIO
+
+int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+                           char *kstr, int klen, pem_password_cb *cb, void *u)
+{
+    return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u);
+}
+
+int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
+                               char *kstr, int klen,
+                               pem_password_cb *cb, void *u)
+{
+    return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u);
+}
+
+int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
+                                  char *kstr, int klen,
+                                  pem_password_cb *cb, void *u)
+{
+    return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u);
+}
+
+int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+                              char *kstr, int klen, pem_password_cb *cb,
+                              void *u)
+{
+    return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u);
+}
+
+static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid,
+                         const EVP_CIPHER *enc, char *kstr, int klen,
+                         pem_password_cb *cb, void *u)
+{
+    BIO *bp;
+    int ret;
+
+    if ((bp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) {
+        PEMerr(PEM_F_DO_PK8PKEY_FP, ERR_R_BUF_LIB);
+        return (0);
+    }
+    ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u);
+    BIO_free(bp);
+    return ret;
+}
+
+EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb,
+                                 void *u)
+{
+    BIO *bp;
+    EVP_PKEY *ret;
+
+    if ((bp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) {
+        PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_FP, ERR_R_BUF_LIB);
+        return NULL;
+    }
+    ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u);
+    BIO_free(bp);
+    return ret;
+}
+
+#endif
+
+IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG)
+
+
+IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF,
+             PKCS8_PRIV_KEY_INFO)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_pkey.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_pkey.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_pkey.c	(revision 331)
@@ -0,0 +1,243 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs12.h>
+#include <openssl/pem.h>
+#include <openssl/engine.h>
+#include <openssl/dh.h>
+#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
+
+int pem_check_suffix(const char *pem_str, const char *suffix);
+
+EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
+                                  void *u)
+{
+    char *nm = NULL;
+    const unsigned char *p = NULL;
+    unsigned char *data = NULL;
+    long len;
+    int slen;
+    EVP_PKEY *ret = NULL;
+
+    if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u))
+        return NULL;
+    p = data;
+
+    if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) {
+        PKCS8_PRIV_KEY_INFO *p8inf;
+        p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
+        if (!p8inf)
+            goto p8err;
+        ret = EVP_PKCS82PKEY(p8inf);
+        if (x) {
+            EVP_PKEY_free((EVP_PKEY *)*x);
+            *x = ret;
+        }
+        PKCS8_PRIV_KEY_INFO_free(p8inf);
+    } else if (strcmp(nm, PEM_STRING_PKCS8) == 0) {
+        PKCS8_PRIV_KEY_INFO *p8inf;
+        X509_SIG *p8;
+        int klen;
+        char psbuf[PEM_BUFSIZE];
+        p8 = d2i_X509_SIG(NULL, &p, len);
+        if (!p8)
+            goto p8err;
+        if (cb)
+            klen = cb(psbuf, PEM_BUFSIZE, 0, u);
+        else
+            klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
+        if (klen <= 0) {
+            PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, PEM_R_BAD_PASSWORD_READ);
+            X509_SIG_free(p8);
+            goto err;
+        }
+        p8inf = PKCS8_decrypt(p8, psbuf, klen);
+        X509_SIG_free(p8);
+        if (!p8inf)
+            goto p8err;
+        ret = EVP_PKCS82PKEY(p8inf);
+        if (x) {
+            EVP_PKEY_free((EVP_PKEY *)*x);
+            *x = ret;
+        }
+        PKCS8_PRIV_KEY_INFO_free(p8inf);
+    } else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0) {
+        const EVP_PKEY_ASN1_METHOD *ameth;
+        ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
+        if (!ameth || !ameth->old_priv_decode)
+            goto p8err;
+        ret = d2i_PrivateKey(ameth->pkey_id, x, &p, len);
+    }
+ p8err:
+    if (ret == NULL)
+        PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, ERR_R_ASN1_LIB);
+ err:
+    OPENSSL_free(nm);
+    OPENSSL_clear_free(data, len);
+    return (ret);
+}
+
+int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+                             unsigned char *kstr, int klen,
+                             pem_password_cb *cb, void *u)
+{
+    if (x->ameth == NULL || x->ameth->priv_encode != NULL)
+        return PEM_write_bio_PKCS8PrivateKey(bp, x, enc,
+                                             (char *)kstr, klen, cb, u);
+    return PEM_write_bio_PrivateKey_traditional(bp, x, enc, kstr, klen, cb, u);
+}
+
+int PEM_write_bio_PrivateKey_traditional(BIO *bp, EVP_PKEY *x,
+                                         const EVP_CIPHER *enc,
+                                         unsigned char *kstr, int klen,
+                                         pem_password_cb *cb, void *u)
+{
+    char pem_str[80];
+    BIO_snprintf(pem_str, 80, "%s PRIVATE KEY", x->ameth->pem_str);
+    return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey,
+                              pem_str, bp, x, enc, kstr, klen, cb, u);
+}
+
+EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x)
+{
+    char *nm = NULL;
+    const unsigned char *p = NULL;
+    unsigned char *data = NULL;
+    long len;
+    int slen;
+    EVP_PKEY *ret = NULL;
+
+    if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_PARAMETERS,
+                            bp, 0, NULL))
+        return NULL;
+    p = data;
+
+    if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0) {
+        ret = EVP_PKEY_new();
+        if (ret == NULL)
+            goto err;
+        if (!EVP_PKEY_set_type_str(ret, nm, slen)
+            || !ret->ameth->param_decode
+            || !ret->ameth->param_decode(ret, &p, len)) {
+            EVP_PKEY_free(ret);
+            ret = NULL;
+            goto err;
+        }
+        if (x) {
+            EVP_PKEY_free((EVP_PKEY *)*x);
+            *x = ret;
+        }
+    }
+ err:
+    if (ret == NULL)
+        PEMerr(PEM_F_PEM_READ_BIO_PARAMETERS, ERR_R_ASN1_LIB);
+    OPENSSL_free(nm);
+    OPENSSL_free(data);
+    return (ret);
+}
+
+int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x)
+{
+    char pem_str[80];
+    if (!x->ameth || !x->ameth->param_encode)
+        return 0;
+
+    BIO_snprintf(pem_str, 80, "%s PARAMETERS", x->ameth->pem_str);
+    return PEM_ASN1_write_bio((i2d_of_void *)x->ameth->param_encode,
+                              pem_str, bp, x, NULL, NULL, 0, 0, NULL);
+}
+
+#ifndef OPENSSL_NO_STDIO
+EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb,
+                              void *u)
+{
+    BIO *b;
+    EVP_PKEY *ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        PEMerr(PEM_F_PEM_READ_PRIVATEKEY, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = PEM_read_bio_PrivateKey(b, x, cb, u);
+    BIO_free(b);
+    return (ret);
+}
+
+int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+                         unsigned char *kstr, int klen,
+                         pem_password_cb *cb, void *u)
+{
+    BIO *b;
+    int ret;
+
+    if ((b = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) {
+        PEMerr(PEM_F_PEM_WRITE_PRIVATEKEY, ERR_R_BUF_LIB);
+        return 0;
+    }
+    ret = PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u);
+    BIO_free(b);
+    return ret;
+}
+
+#endif
+
+#ifndef OPENSSL_NO_DH
+
+/* Transparently read in PKCS#3 or X9.42 DH parameters */
+
+DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u)
+{
+    char *nm = NULL;
+    const unsigned char *p = NULL;
+    unsigned char *data = NULL;
+    long len;
+    DH *ret = NULL;
+
+    if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_DHPARAMS, bp, cb, u))
+        return NULL;
+    p = data;
+
+    if (strcmp(nm, PEM_STRING_DHXPARAMS) == 0)
+        ret = d2i_DHxparams(x, &p, len);
+    else
+        ret = d2i_DHparams(x, &p, len);
+
+    if (ret == NULL)
+        PEMerr(PEM_F_PEM_READ_BIO_DHPARAMS, ERR_R_ASN1_LIB);
+    OPENSSL_free(nm);
+    OPENSSL_free(data);
+    return ret;
+}
+
+# ifndef OPENSSL_NO_STDIO
+DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u)
+{
+    BIO *b;
+    DH *ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        PEMerr(PEM_F_PEM_READ_DHPARAMS, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = PEM_read_bio_DHparams(b, x, cb, u);
+    BIO_free(b);
+    return (ret);
+}
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_sign.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_sign.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_sign.c	(revision 331)
@@ -0,0 +1,50 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+int PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type)
+{
+    return EVP_DigestInit_ex(ctx, type, NULL);
+}
+
+int PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data, unsigned int count)
+{
+    return EVP_DigestUpdate(ctx, data, count);
+}
+
+int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
+                  unsigned int *siglen, EVP_PKEY *pkey)
+{
+    unsigned char *m;
+    int i, ret = 0;
+    unsigned int m_len;
+
+    m = OPENSSL_malloc(EVP_PKEY_size(pkey) + 2);
+    if (m == NULL) {
+        PEMerr(PEM_F_PEM_SIGNFINAL, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (EVP_SignFinal(ctx, m, &m_len, pkey) <= 0)
+        goto err;
+
+    i = EVP_EncodeBlock(sigret, m, m_len);
+    *siglen = i;
+    ret = 1;
+ err:
+    /* ctx has been zeroed by EVP_SignFinal() */
+    OPENSSL_free(m);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_x509.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_x509.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_x509.c	(revision 331)
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2001-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pem.h>
+
+IMPLEMENT_PEM_rw(X509, X509, PEM_STRING_X509, X509)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_xaux.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_xaux.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pem_xaux.c	(revision 331)
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2001-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pem.h>
+
+IMPLEMENT_PEM_rw(X509_AUX, X509, PEM_STRING_X509_TRUSTED, X509_AUX)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pvkfmt.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pvkfmt.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pem/pvkfmt.c	(revision 331)
@@ -0,0 +1,869 @@
+/*
+ * Copyright 2005-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
+ */
+
+/*
+ * Support for PVK format keys and related structures (such a PUBLICKEYBLOB
+ * and PRIVATEKEYBLOB).
+ */
+
+#include "internal/cryptlib.h"
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
+# include <openssl/dsa.h>
+# include <openssl/rsa.h>
+
+/*
+ * Utility function: read a DWORD (4 byte unsigned integer) in little endian
+ * format
+ */
+
+static unsigned int read_ledword(const unsigned char **in)
+{
+    const unsigned char *p = *in;
+    unsigned int ret;
+    ret = *p++;
+    ret |= (*p++ << 8);
+    ret |= (*p++ << 16);
+    ret |= (*p++ << 24);
+    *in = p;
+    return ret;
+}
+
+/*
+ * Read a BIGNUM in little endian format. The docs say that this should take
+ * up bitlen/8 bytes.
+ */
+
+static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r)
+{
+    *r = BN_lebin2bn(*in, nbyte, NULL);
+    if (*r == NULL)
+        return 0;
+    *in += nbyte;
+    return 1;
+}
+
+/* Convert private key blob to EVP_PKEY: RSA and DSA keys supported */
+
+# define MS_PUBLICKEYBLOB        0x6
+# define MS_PRIVATEKEYBLOB       0x7
+# define MS_RSA1MAGIC            0x31415352L
+# define MS_RSA2MAGIC            0x32415352L
+# define MS_DSS1MAGIC            0x31535344L
+# define MS_DSS2MAGIC            0x32535344L
+
+# define MS_KEYALG_RSA_KEYX      0xa400
+# define MS_KEYALG_DSS_SIGN      0x2200
+
+# define MS_KEYTYPE_KEYX         0x1
+# define MS_KEYTYPE_SIGN         0x2
+
+/* Maximum length of a blob after header */
+# define BLOB_MAX_LENGTH          102400
+
+/* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */
+# define MS_PVKMAGIC             0xb0b5f11eL
+/* Salt length for PVK files */
+# define PVK_SALTLEN             0x10
+/* Maximum length in PVK header */
+# define PVK_MAX_KEYLEN          102400
+/* Maximum salt length */
+# define PVK_MAX_SALTLEN         10240
+
+static EVP_PKEY *b2i_rsa(const unsigned char **in,
+                         unsigned int bitlen, int ispub);
+static EVP_PKEY *b2i_dss(const unsigned char **in,
+                         unsigned int bitlen, int ispub);
+
+static int do_blob_header(const unsigned char **in, unsigned int length,
+                          unsigned int *pmagic, unsigned int *pbitlen,
+                          int *pisdss, int *pispub)
+{
+    const unsigned char *p = *in;
+    if (length < 16)
+        return 0;
+    /* bType */
+    if (*p == MS_PUBLICKEYBLOB) {
+        if (*pispub == 0) {
+            PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
+            return 0;
+        }
+        *pispub = 1;
+    } else if (*p == MS_PRIVATEKEYBLOB) {
+        if (*pispub == 1) {
+            PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
+            return 0;
+        }
+        *pispub = 0;
+    } else
+        return 0;
+    p++;
+    /* Version */
+    if (*p++ != 0x2) {
+        PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_VERSION_NUMBER);
+        return 0;
+    }
+    /* Ignore reserved, aiKeyAlg */
+    p += 6;
+    *pmagic = read_ledword(&p);
+    *pbitlen = read_ledword(&p);
+    *pisdss = 0;
+    switch (*pmagic) {
+
+    case MS_DSS1MAGIC:
+        *pisdss = 1;
+    case MS_RSA1MAGIC:
+        if (*pispub == 0) {
+            PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
+            return 0;
+        }
+        break;
+
+    case MS_DSS2MAGIC:
+        *pisdss = 1;
+    case MS_RSA2MAGIC:
+        if (*pispub == 1) {
+            PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
+            return 0;
+        }
+        break;
+
+    default:
+        PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_MAGIC_NUMBER);
+        return -1;
+    }
+    *in = p;
+    return 1;
+}
+
+static unsigned int blob_length(unsigned bitlen, int isdss, int ispub)
+{
+    unsigned int nbyte, hnbyte;
+    nbyte = (bitlen + 7) >> 3;
+    hnbyte = (bitlen + 15) >> 4;
+    if (isdss) {
+
+        /*
+         * Expected length: 20 for q + 3 components bitlen each + 24 for seed
+         * structure.
+         */
+        if (ispub)
+            return 44 + 3 * nbyte;
+        /*
+         * Expected length: 20 for q, priv, 2 bitlen components + 24 for seed
+         * structure.
+         */
+        else
+            return 64 + 2 * nbyte;
+    } else {
+        /* Expected length: 4 for 'e' + 'n' */
+        if (ispub)
+            return 4 + nbyte;
+        else
+            /*
+             * Expected length: 4 for 'e' and 7 other components. 2
+             * components are bitlen size, 5 are bitlen/2
+             */
+            return 4 + 2 * nbyte + 5 * hnbyte;
+    }
+
+}
+
+static EVP_PKEY *do_b2i(const unsigned char **in, unsigned int length,
+                        int ispub)
+{
+    const unsigned char *p = *in;
+    unsigned int bitlen, magic;
+    int isdss;
+    if (do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0) {
+        PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_HEADER_PARSE_ERROR);
+        return NULL;
+    }
+    length -= 16;
+    if (length < blob_length(bitlen, isdss, ispub)) {
+        PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_TOO_SHORT);
+        return NULL;
+    }
+    if (isdss)
+        return b2i_dss(&p, bitlen, ispub);
+    else
+        return b2i_rsa(&p, bitlen, ispub);
+}
+
+static EVP_PKEY *do_b2i_bio(BIO *in, int ispub)
+{
+    const unsigned char *p;
+    unsigned char hdr_buf[16], *buf = NULL;
+    unsigned int bitlen, magic, length;
+    int isdss;
+    EVP_PKEY *ret = NULL;
+    if (BIO_read(in, hdr_buf, 16) != 16) {
+        PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT);
+        return NULL;
+    }
+    p = hdr_buf;
+    if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0)
+        return NULL;
+
+    length = blob_length(bitlen, isdss, ispub);
+    if (length > BLOB_MAX_LENGTH) {
+        PEMerr(PEM_F_DO_B2I_BIO, PEM_R_HEADER_TOO_LONG);
+        return NULL;
+    }
+    buf = OPENSSL_malloc(length);
+    if (buf == NULL) {
+        PEMerr(PEM_F_DO_B2I_BIO, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    p = buf;
+    if (BIO_read(in, buf, length) != (int)length) {
+        PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT);
+        goto err;
+    }
+
+    if (isdss)
+        ret = b2i_dss(&p, bitlen, ispub);
+    else
+        ret = b2i_rsa(&p, bitlen, ispub);
+
+ err:
+    OPENSSL_free(buf);
+    return ret;
+}
+
+static EVP_PKEY *b2i_dss(const unsigned char **in,
+                         unsigned int bitlen, int ispub)
+{
+    const unsigned char *p = *in;
+    EVP_PKEY *ret = NULL;
+    DSA *dsa = NULL;
+    BN_CTX *ctx = NULL;
+    unsigned int nbyte;
+    BIGNUM *pbn = NULL, *qbn = NULL, *gbn = NULL, *priv_key = NULL;
+    BIGNUM *pub_key = NULL;
+
+    nbyte = (bitlen + 7) >> 3;
+
+    dsa = DSA_new();
+    ret = EVP_PKEY_new();
+    if (dsa == NULL || ret == NULL)
+        goto memerr;
+    if (!read_lebn(&p, nbyte, &pbn))
+        goto memerr;
+
+    if (!read_lebn(&p, 20, &qbn))
+        goto memerr;
+
+    if (!read_lebn(&p, nbyte, &gbn))
+        goto memerr;
+
+    if (ispub) {
+        if (!read_lebn(&p, nbyte, &pub_key))
+            goto memerr;
+    } else {
+        if (!read_lebn(&p, 20, &priv_key))
+            goto memerr;
+
+        /* Calculate public key */
+        pub_key = BN_new();
+        if (pub_key == NULL)
+            goto memerr;
+        if ((ctx = BN_CTX_new()) == NULL)
+            goto memerr;
+
+        if (!BN_mod_exp(pub_key, gbn, priv_key, pbn, ctx))
+            goto memerr;
+
+        BN_CTX_free(ctx);
+    }
+    if (!DSA_set0_pqg(dsa, pbn, qbn, gbn))
+        goto memerr;
+    pbn = qbn = gbn = NULL;
+    if (!DSA_set0_key(dsa, pub_key, priv_key))
+        goto memerr;
+
+    EVP_PKEY_set1_DSA(ret, dsa);
+    DSA_free(dsa);
+    *in = p;
+    return ret;
+
+ memerr:
+    PEMerr(PEM_F_B2I_DSS, ERR_R_MALLOC_FAILURE);
+    DSA_free(dsa);
+    BN_free(pbn);
+    BN_free(qbn);
+    BN_free(gbn);
+    BN_free(pub_key);
+    BN_free(priv_key);
+    EVP_PKEY_free(ret);
+    BN_CTX_free(ctx);
+    return NULL;
+}
+
+static EVP_PKEY *b2i_rsa(const unsigned char **in,
+                         unsigned int bitlen, int ispub)
+{
+    const unsigned char *pin = *in;
+    EVP_PKEY *ret = NULL;
+    BIGNUM *e = NULL, *n = NULL, *d = NULL;
+    BIGNUM *p = NULL, *q = NULL, *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL;
+    RSA *rsa = NULL;
+    unsigned int nbyte, hnbyte;
+    nbyte = (bitlen + 7) >> 3;
+    hnbyte = (bitlen + 15) >> 4;
+    rsa = RSA_new();
+    ret = EVP_PKEY_new();
+    if (rsa == NULL || ret == NULL)
+        goto memerr;
+    e = BN_new();
+    if (e == NULL)
+        goto memerr;
+    if (!BN_set_word(e, read_ledword(&pin)))
+        goto memerr;
+    if (!read_lebn(&pin, nbyte, &n))
+        goto memerr;
+    if (!ispub) {
+        if (!read_lebn(&pin, hnbyte, &p))
+            goto memerr;
+        if (!read_lebn(&pin, hnbyte, &q))
+            goto memerr;
+        if (!read_lebn(&pin, hnbyte, &dmp1))
+            goto memerr;
+        if (!read_lebn(&pin, hnbyte, &dmq1))
+            goto memerr;
+        if (!read_lebn(&pin, hnbyte, &iqmp))
+            goto memerr;
+        if (!read_lebn(&pin, nbyte, &d))
+            goto memerr;
+        RSA_set0_factors(rsa, p, q);
+        RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp);
+    }
+    RSA_set0_key(rsa, n, e, d);
+
+    EVP_PKEY_set1_RSA(ret, rsa);
+    RSA_free(rsa);
+    *in = pin;
+    return ret;
+ memerr:
+    PEMerr(PEM_F_B2I_RSA, ERR_R_MALLOC_FAILURE);
+    BN_free(e);
+    BN_free(n);
+    BN_free(p);
+    BN_free(q);
+    BN_free(dmp1);
+    BN_free(dmq1);
+    BN_free(iqmp);
+    BN_free(d);
+    RSA_free(rsa);
+    EVP_PKEY_free(ret);
+    return NULL;
+}
+
+EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length)
+{
+    return do_b2i(in, length, 0);
+}
+
+EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length)
+{
+    return do_b2i(in, length, 1);
+}
+
+EVP_PKEY *b2i_PrivateKey_bio(BIO *in)
+{
+    return do_b2i_bio(in, 0);
+}
+
+EVP_PKEY *b2i_PublicKey_bio(BIO *in)
+{
+    return do_b2i_bio(in, 1);
+}
+
+static void write_ledword(unsigned char **out, unsigned int dw)
+{
+    unsigned char *p = *out;
+    *p++ = dw & 0xff;
+    *p++ = (dw >> 8) & 0xff;
+    *p++ = (dw >> 16) & 0xff;
+    *p++ = (dw >> 24) & 0xff;
+    *out = p;
+}
+
+static void write_lebn(unsigned char **out, const BIGNUM *bn, int len)
+{
+    BN_bn2lebinpad(bn, *out, len);
+    *out += len;
+}
+
+static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *magic);
+static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *magic);
+
+static void write_rsa(unsigned char **out, RSA *rsa, int ispub);
+static void write_dsa(unsigned char **out, DSA *dsa, int ispub);
+
+static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub)
+{
+    unsigned char *p;
+    unsigned int bitlen, magic = 0, keyalg;
+    int outlen, noinc = 0;
+    int pktype = EVP_PKEY_id(pk);
+    if (pktype == EVP_PKEY_DSA) {
+        bitlen = check_bitlen_dsa(EVP_PKEY_get0_DSA(pk), ispub, &magic);
+        keyalg = MS_KEYALG_DSS_SIGN;
+    } else if (pktype == EVP_PKEY_RSA) {
+        bitlen = check_bitlen_rsa(EVP_PKEY_get0_RSA(pk), ispub, &magic);
+        keyalg = MS_KEYALG_RSA_KEYX;
+    } else
+        return -1;
+    if (bitlen == 0)
+        return -1;
+    outlen = 16 + blob_length(bitlen,
+                              keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub);
+    if (out == NULL)
+        return outlen;
+    if (*out)
+        p = *out;
+    else {
+        p = OPENSSL_malloc(outlen);
+        if (p == NULL)
+            return -1;
+        *out = p;
+        noinc = 1;
+    }
+    if (ispub)
+        *p++ = MS_PUBLICKEYBLOB;
+    else
+        *p++ = MS_PRIVATEKEYBLOB;
+    *p++ = 0x2;
+    *p++ = 0;
+    *p++ = 0;
+    write_ledword(&p, keyalg);
+    write_ledword(&p, magic);
+    write_ledword(&p, bitlen);
+    if (keyalg == MS_KEYALG_DSS_SIGN)
+        write_dsa(&p, EVP_PKEY_get0_DSA(pk), ispub);
+    else
+        write_rsa(&p, EVP_PKEY_get0_RSA(pk), ispub);
+    if (!noinc)
+        *out += outlen;
+    return outlen;
+}
+
+static int do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub)
+{
+    unsigned char *tmp = NULL;
+    int outlen, wrlen;
+    outlen = do_i2b(&tmp, pk, ispub);
+    if (outlen < 0)
+        return -1;
+    wrlen = BIO_write(out, tmp, outlen);
+    OPENSSL_free(tmp);
+    if (wrlen == outlen)
+        return outlen;
+    return -1;
+}
+
+static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic)
+{
+    int bitlen;
+    const BIGNUM *p = NULL, *q = NULL, *g = NULL;
+    const BIGNUM *pub_key = NULL, *priv_key = NULL;
+
+    DSA_get0_pqg(dsa, &p, &q, &g);
+    DSA_get0_key(dsa, &pub_key, &priv_key);
+    bitlen = BN_num_bits(p);
+    if ((bitlen & 7) || (BN_num_bits(q) != 160)
+        || (BN_num_bits(g) > bitlen))
+        goto badkey;
+    if (ispub) {
+        if (BN_num_bits(pub_key) > bitlen)
+            goto badkey;
+        *pmagic = MS_DSS1MAGIC;
+    } else {
+        if (BN_num_bits(priv_key) > 160)
+            goto badkey;
+        *pmagic = MS_DSS2MAGIC;
+    }
+
+    return bitlen;
+ badkey:
+    PEMerr(PEM_F_CHECK_BITLEN_DSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS);
+    return 0;
+}
+
+static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic)
+{
+    int nbyte, hnbyte, bitlen;
+    const BIGNUM *e;
+
+    RSA_get0_key(rsa, NULL, &e, NULL);
+    if (BN_num_bits(e) > 32)
+        goto badkey;
+    bitlen = RSA_bits(rsa);
+    nbyte = RSA_size(rsa);
+    hnbyte = (bitlen + 15) >> 4;
+    if (ispub) {
+        *pmagic = MS_RSA1MAGIC;
+        return bitlen;
+    } else {
+        const BIGNUM *d, *p, *q, *iqmp, *dmp1, *dmq1;
+
+        *pmagic = MS_RSA2MAGIC;
+
+        /*
+         * For private key each component must fit within nbyte or hnbyte.
+         */
+        RSA_get0_key(rsa, NULL, NULL, &d);
+        if (BN_num_bytes(d) > nbyte)
+            goto badkey;
+        RSA_get0_factors(rsa, &p, &q);
+        RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
+        if ((BN_num_bytes(iqmp) > hnbyte)
+            || (BN_num_bytes(p) > hnbyte)
+            || (BN_num_bytes(q) > hnbyte)
+            || (BN_num_bytes(dmp1) > hnbyte)
+            || (BN_num_bytes(dmq1) > hnbyte))
+            goto badkey;
+    }
+    return bitlen;
+ badkey:
+    PEMerr(PEM_F_CHECK_BITLEN_RSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS);
+    return 0;
+}
+
+static void write_rsa(unsigned char **out, RSA *rsa, int ispub)
+{
+    int nbyte, hnbyte;
+    const BIGNUM *n, *d, *e, *p, *q, *iqmp, *dmp1, *dmq1;
+
+    nbyte = RSA_size(rsa);
+    hnbyte = (RSA_bits(rsa) + 15) >> 4;
+    RSA_get0_key(rsa, &n, &e, &d);
+    write_lebn(out, e, 4);
+    write_lebn(out, n, nbyte);
+    if (ispub)
+        return;
+    RSA_get0_factors(rsa, &p, &q);
+    RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
+    write_lebn(out, p, hnbyte);
+    write_lebn(out, q, hnbyte);
+    write_lebn(out, dmp1, hnbyte);
+    write_lebn(out, dmq1, hnbyte);
+    write_lebn(out, iqmp, hnbyte);
+    write_lebn(out, d, nbyte);
+}
+
+static void write_dsa(unsigned char **out, DSA *dsa, int ispub)
+{
+    int nbyte;
+    const BIGNUM *p = NULL, *q = NULL, *g = NULL;
+    const BIGNUM *pub_key = NULL, *priv_key = NULL;
+
+    DSA_get0_pqg(dsa, &p, &q, &g);
+    DSA_get0_key(dsa, &pub_key, &priv_key);
+    nbyte = BN_num_bytes(p);
+    write_lebn(out, p, nbyte);
+    write_lebn(out, q, 20);
+    write_lebn(out, g, nbyte);
+    if (ispub)
+        write_lebn(out, pub_key, nbyte);
+    else
+        write_lebn(out, priv_key, 20);
+    /* Set "invalid" for seed structure values */
+    memset(*out, 0xff, 24);
+    *out += 24;
+    return;
+}
+
+int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk)
+{
+    return do_i2b_bio(out, pk, 0);
+}
+
+int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk)
+{
+    return do_i2b_bio(out, pk, 1);
+}
+
+# ifndef OPENSSL_NO_RC4
+
+static int do_PVK_header(const unsigned char **in, unsigned int length,
+                         int skip_magic,
+                         unsigned int *psaltlen, unsigned int *pkeylen)
+{
+    const unsigned char *p = *in;
+    unsigned int pvk_magic, is_encrypted;
+    if (skip_magic) {
+        if (length < 20) {
+            PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
+            return 0;
+        }
+    } else {
+        if (length < 24) {
+            PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
+            return 0;
+        }
+        pvk_magic = read_ledword(&p);
+        if (pvk_magic != MS_PVKMAGIC) {
+            PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_BAD_MAGIC_NUMBER);
+            return 0;
+        }
+    }
+    /* Skip reserved */
+    p += 4;
+    /*
+     * keytype =
+     */ read_ledword(&p);
+    is_encrypted = read_ledword(&p);
+    *psaltlen = read_ledword(&p);
+    *pkeylen = read_ledword(&p);
+
+    if (*pkeylen > PVK_MAX_KEYLEN || *psaltlen > PVK_MAX_SALTLEN)
+        return 0;
+
+    if (is_encrypted && !*psaltlen) {
+        PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_INCONSISTENT_HEADER);
+        return 0;
+    }
+
+    *in = p;
+    return 1;
+}
+
+static int derive_pvk_key(unsigned char *key,
+                          const unsigned char *salt, unsigned int saltlen,
+                          const unsigned char *pass, int passlen)
+{
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+    int rv = 1;
+    if (mctx == NULL
+        || !EVP_DigestInit_ex(mctx, EVP_sha1(), NULL)
+        || !EVP_DigestUpdate(mctx, salt, saltlen)
+        || !EVP_DigestUpdate(mctx, pass, passlen)
+        || !EVP_DigestFinal_ex(mctx, key, NULL))
+        rv = 0;
+
+    EVP_MD_CTX_free(mctx);
+    return rv;
+}
+
+static EVP_PKEY *do_PVK_body(const unsigned char **in,
+                             unsigned int saltlen, unsigned int keylen,
+                             pem_password_cb *cb, void *u)
+{
+    EVP_PKEY *ret = NULL;
+    const unsigned char *p = *in;
+    unsigned int magic;
+    unsigned char *enctmp = NULL, *q;
+
+    EVP_CIPHER_CTX *cctx = EVP_CIPHER_CTX_new();
+    if (saltlen) {
+        char psbuf[PEM_BUFSIZE];
+        unsigned char keybuf[20];
+        int enctmplen, inlen;
+        if (cb)
+            inlen = cb(psbuf, PEM_BUFSIZE, 0, u);
+        else
+            inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
+        if (inlen <= 0) {
+            PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_PASSWORD_READ);
+            goto err;
+        }
+        enctmp = OPENSSL_malloc(keylen + 8);
+        if (enctmp == NULL) {
+            PEMerr(PEM_F_DO_PVK_BODY, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        if (!derive_pvk_key(keybuf, p, saltlen,
+                            (unsigned char *)psbuf, inlen))
+            goto err;
+        p += saltlen;
+        /* Copy BLOBHEADER across, decrypt rest */
+        memcpy(enctmp, p, 8);
+        p += 8;
+        if (keylen < 8) {
+            PEMerr(PEM_F_DO_PVK_BODY, PEM_R_PVK_TOO_SHORT);
+            goto err;
+        }
+        inlen = keylen - 8;
+        q = enctmp + 8;
+        if (!EVP_DecryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, NULL))
+            goto err;
+        if (!EVP_DecryptUpdate(cctx, q, &enctmplen, p, inlen))
+            goto err;
+        if (!EVP_DecryptFinal_ex(cctx, q + enctmplen, &enctmplen))
+            goto err;
+        magic = read_ledword((const unsigned char **)&q);
+        if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
+            q = enctmp + 8;
+            memset(keybuf + 5, 0, 11);
+            if (!EVP_DecryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, NULL))
+                goto err;
+            OPENSSL_cleanse(keybuf, 20);
+            if (!EVP_DecryptUpdate(cctx, q, &enctmplen, p, inlen))
+                goto err;
+            if (!EVP_DecryptFinal_ex(cctx, q + enctmplen, &enctmplen))
+                goto err;
+            magic = read_ledword((const unsigned char **)&q);
+            if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
+                PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT);
+                goto err;
+            }
+        } else
+            OPENSSL_cleanse(keybuf, 20);
+        p = enctmp;
+    }
+
+    ret = b2i_PrivateKey(&p, keylen);
+ err:
+    EVP_CIPHER_CTX_free(cctx);
+    OPENSSL_free(enctmp);
+    return ret;
+}
+
+EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u)
+{
+    unsigned char pvk_hdr[24], *buf = NULL;
+    const unsigned char *p;
+    int buflen;
+    EVP_PKEY *ret = NULL;
+    unsigned int saltlen, keylen;
+    if (BIO_read(in, pvk_hdr, 24) != 24) {
+        PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT);
+        return NULL;
+    }
+    p = pvk_hdr;
+
+    if (!do_PVK_header(&p, 24, 0, &saltlen, &keylen))
+        return 0;
+    buflen = (int)keylen + saltlen;
+    buf = OPENSSL_malloc(buflen);
+    if (buf == NULL) {
+        PEMerr(PEM_F_B2I_PVK_BIO, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    p = buf;
+    if (BIO_read(in, buf, buflen) != buflen) {
+        PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT);
+        goto err;
+    }
+    ret = do_PVK_body(&p, saltlen, keylen, cb, u);
+
+ err:
+    OPENSSL_clear_free(buf, buflen);
+    return ret;
+}
+
+static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel,
+                   pem_password_cb *cb, void *u)
+{
+    int outlen = 24, pklen;
+    unsigned char *p = NULL, *start = NULL, *salt = NULL;
+    EVP_CIPHER_CTX *cctx = NULL;
+    if (enclevel)
+        outlen += PVK_SALTLEN;
+    pklen = do_i2b(NULL, pk, 0);
+    if (pklen < 0)
+        return -1;
+    outlen += pklen;
+    if (out == NULL)
+        return outlen;
+    if (*out != NULL) {
+        p = *out;
+    } else {
+        start = p = OPENSSL_malloc(outlen);
+        if (p == NULL) {
+            PEMerr(PEM_F_I2B_PVK, ERR_R_MALLOC_FAILURE);
+            return -1;
+        }
+    }
+
+    cctx = EVP_CIPHER_CTX_new();
+    if (cctx == NULL)
+        goto error;
+
+    write_ledword(&p, MS_PVKMAGIC);
+    write_ledword(&p, 0);
+    if (EVP_PKEY_id(pk) == EVP_PKEY_DSA)
+        write_ledword(&p, MS_KEYTYPE_SIGN);
+    else
+        write_ledword(&p, MS_KEYTYPE_KEYX);
+    write_ledword(&p, enclevel ? 1 : 0);
+    write_ledword(&p, enclevel ? PVK_SALTLEN : 0);
+    write_ledword(&p, pklen);
+    if (enclevel) {
+        if (RAND_bytes(p, PVK_SALTLEN) <= 0)
+            goto error;
+        salt = p;
+        p += PVK_SALTLEN;
+    }
+    do_i2b(&p, pk, 0);
+    if (enclevel != 0) {
+        char psbuf[PEM_BUFSIZE];
+        unsigned char keybuf[20];
+        int enctmplen, inlen;
+        if (cb)
+            inlen = cb(psbuf, PEM_BUFSIZE, 1, u);
+        else
+            inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 1, u);
+        if (inlen <= 0) {
+            PEMerr(PEM_F_I2B_PVK, PEM_R_BAD_PASSWORD_READ);
+            goto error;
+        }
+        if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN,
+                            (unsigned char *)psbuf, inlen))
+            goto error;
+        if (enclevel == 1)
+            memset(keybuf + 5, 0, 11);
+        p = salt + PVK_SALTLEN + 8;
+        if (!EVP_EncryptInit_ex(cctx, EVP_rc4(), NULL, keybuf, NULL))
+            goto error;
+        OPENSSL_cleanse(keybuf, 20);
+        if (!EVP_DecryptUpdate(cctx, p, &enctmplen, p, pklen - 8))
+            goto error;
+        if (!EVP_DecryptFinal_ex(cctx, p + enctmplen, &enctmplen))
+            goto error;
+    }
+
+    EVP_CIPHER_CTX_free(cctx);
+
+    if (*out == NULL)
+        *out = start;
+
+    return outlen;
+
+ error:
+    EVP_CIPHER_CTX_free(cctx);
+    if (*out == NULL)
+        OPENSSL_free(start);
+    return -1;
+}
+
+int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
+                pem_password_cb *cb, void *u)
+{
+    unsigned char *tmp = NULL;
+    int outlen, wrlen;
+    outlen = i2b_PVK(&tmp, pk, enclevel, cb, u);
+    if (outlen < 0)
+        return -1;
+    wrlen = BIO_write(out, tmp, outlen);
+    OPENSSL_free(tmp);
+    if (wrlen == outlen) {
+        PEMerr(PEM_F_I2B_PVK_BIO, PEM_R_BIO_WRITE_FAILURE);
+        return outlen;
+    }
+    return -1;
+}
+
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_add.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_add.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_add.c	(revision 331)
@@ -0,0 +1,164 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/pkcs12.h>
+#include "p12_lcl.h"
+
+/* Pack an object into an OCTET STRING and turn into a safebag */
+
+PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it,
+                                         int nid1, int nid2)
+{
+    PKCS12_BAGS *bag;
+    PKCS12_SAFEBAG *safebag;
+
+    if ((bag = PKCS12_BAGS_new()) == NULL) {
+        PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    bag->type = OBJ_nid2obj(nid1);
+    if (!ASN1_item_pack(obj, it, &bag->value.octet)) {
+        PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if ((safebag = PKCS12_SAFEBAG_new()) == NULL) {
+        PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    safebag->value.bag = bag;
+    safebag->type = OBJ_nid2obj(nid2);
+    return safebag;
+
+ err:
+    PKCS12_BAGS_free(bag);
+    return NULL;
+}
+
+/* Turn a stack of SAFEBAGS into a PKCS#7 data Contentinfo */
+PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk)
+{
+    PKCS7 *p7;
+
+    if ((p7 = PKCS7_new()) == NULL) {
+        PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    p7->type = OBJ_nid2obj(NID_pkcs7_data);
+    if ((p7->d.data = ASN1_OCTET_STRING_new()) == NULL) {
+        PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (!ASN1_item_pack(sk, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), &p7->d.data)) {
+        PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, PKCS12_R_CANT_PACK_STRUCTURE);
+        goto err;
+    }
+    return p7;
+
+ err:
+    PKCS7_free(p7);
+    return NULL;
+}
+
+/* Unpack SAFEBAGS from PKCS#7 data ContentInfo */
+STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7)
+{
+    if (!PKCS7_type_is_data(p7)) {
+        PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA,
+                  PKCS12_R_CONTENT_TYPE_NOT_DATA);
+        return NULL;
+    }
+    return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS));
+}
+
+/* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */
+
+PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
+                             unsigned char *salt, int saltlen, int iter,
+                             STACK_OF(PKCS12_SAFEBAG) *bags)
+{
+    PKCS7 *p7;
+    X509_ALGOR *pbe;
+    const EVP_CIPHER *pbe_ciph;
+
+    if ((p7 = PKCS7_new()) == NULL) {
+        PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    if (!PKCS7_set_type(p7, NID_pkcs7_encrypted)) {
+        PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA,
+                  PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE);
+        goto err;
+    }
+
+    pbe_ciph = EVP_get_cipherbynid(pbe_nid);
+
+    if (pbe_ciph)
+        pbe = PKCS5_pbe2_set(pbe_ciph, iter, salt, saltlen);
+    else
+        pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen);
+
+    if (!pbe) {
+        PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    X509_ALGOR_free(p7->d.encrypted->enc_data->algorithm);
+    p7->d.encrypted->enc_data->algorithm = pbe;
+    ASN1_OCTET_STRING_free(p7->d.encrypted->enc_data->enc_data);
+    if (!(p7->d.encrypted->enc_data->enc_data =
+          PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass,
+                                  passlen, bags, 1))) {
+        PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, PKCS12_R_ENCRYPT_ERROR);
+        goto err;
+    }
+
+    return p7;
+
+ err:
+    PKCS7_free(p7);
+    return NULL;
+}
+
+STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass,
+                                                  int passlen)
+{
+    if (!PKCS7_type_is_encrypted(p7))
+        return NULL;
+    return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm,
+                                   ASN1_ITEM_rptr(PKCS12_SAFEBAGS),
+                                   pass, passlen,
+                                   p7->d.encrypted->enc_data->enc_data, 1);
+}
+
+PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(const PKCS12_SAFEBAG *bag,
+                                         const char *pass, int passlen)
+{
+    return PKCS8_decrypt(bag->value.shkeybag, pass, passlen);
+}
+
+int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes)
+{
+    if (ASN1_item_pack(safes, ASN1_ITEM_rptr(PKCS12_AUTHSAFES),
+                       &p12->authsafes->d.data))
+        return 1;
+    return 0;
+}
+
+STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12)
+{
+    if (!PKCS7_type_is_data(p12->authsafes)) {
+        PKCS12err(PKCS12_F_PKCS12_UNPACK_AUTHSAFES,
+                  PKCS12_R_CONTENT_TYPE_NOT_DATA);
+        return NULL;
+    }
+    return ASN1_item_unpack(p12->authsafes->d.data,
+                            ASN1_ITEM_rptr(PKCS12_AUTHSAFES));
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_asn.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_asn.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_asn.c	(revision 331)
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2000-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pkcs12.h>
+#include "p12_lcl.h"
+
+/* PKCS#12 ASN1 module */
+
+ASN1_SEQUENCE(PKCS12) = {
+        ASN1_SIMPLE(PKCS12, version, ASN1_INTEGER),
+        ASN1_SIMPLE(PKCS12, authsafes, PKCS7),
+        ASN1_OPT(PKCS12, mac, PKCS12_MAC_DATA)
+} ASN1_SEQUENCE_END(PKCS12)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS12)
+
+ASN1_SEQUENCE(PKCS12_MAC_DATA) = {
+        ASN1_SIMPLE(PKCS12_MAC_DATA, dinfo, X509_SIG),
+        ASN1_SIMPLE(PKCS12_MAC_DATA, salt, ASN1_OCTET_STRING),
+        ASN1_OPT(PKCS12_MAC_DATA, iter, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(PKCS12_MAC_DATA)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS12_MAC_DATA)
+
+ASN1_ADB_TEMPLATE(bag_default) = ASN1_EXP(PKCS12_BAGS, value.other, ASN1_ANY, 0);
+
+ASN1_ADB(PKCS12_BAGS) = {
+        ADB_ENTRY(NID_x509Certificate, ASN1_EXP(PKCS12_BAGS, value.x509cert, ASN1_OCTET_STRING, 0)),
+        ADB_ENTRY(NID_x509Crl, ASN1_EXP(PKCS12_BAGS, value.x509crl, ASN1_OCTET_STRING, 0)),
+        ADB_ENTRY(NID_sdsiCertificate, ASN1_EXP(PKCS12_BAGS, value.sdsicert, ASN1_IA5STRING, 0)),
+} ASN1_ADB_END(PKCS12_BAGS, 0, type, 0, &bag_default_tt, NULL);
+
+ASN1_SEQUENCE(PKCS12_BAGS) = {
+        ASN1_SIMPLE(PKCS12_BAGS, type, ASN1_OBJECT),
+        ASN1_ADB_OBJECT(PKCS12_BAGS),
+} ASN1_SEQUENCE_END(PKCS12_BAGS)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS12_BAGS)
+
+ASN1_ADB_TEMPLATE(safebag_default) = ASN1_EXP(PKCS12_SAFEBAG, value.other, ASN1_ANY, 0);
+
+ASN1_ADB(PKCS12_SAFEBAG) = {
+        ADB_ENTRY(NID_keyBag, ASN1_EXP(PKCS12_SAFEBAG, value.keybag, PKCS8_PRIV_KEY_INFO, 0)),
+        ADB_ENTRY(NID_pkcs8ShroudedKeyBag, ASN1_EXP(PKCS12_SAFEBAG, value.shkeybag, X509_SIG, 0)),
+        ADB_ENTRY(NID_safeContentsBag, ASN1_EXP_SET_OF(PKCS12_SAFEBAG, value.safes, PKCS12_SAFEBAG, 0)),
+        ADB_ENTRY(NID_certBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)),
+        ADB_ENTRY(NID_crlBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)),
+        ADB_ENTRY(NID_secretBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0))
+} ASN1_ADB_END(PKCS12_SAFEBAG, 0, type, 0, &safebag_default_tt, NULL);
+
+ASN1_SEQUENCE(PKCS12_SAFEBAG) = {
+        ASN1_SIMPLE(PKCS12_SAFEBAG, type, ASN1_OBJECT),
+        ASN1_ADB_OBJECT(PKCS12_SAFEBAG),
+        ASN1_SET_OF_OPT(PKCS12_SAFEBAG, attrib, X509_ATTRIBUTE)
+} ASN1_SEQUENCE_END(PKCS12_SAFEBAG)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS12_SAFEBAG)
+
+/* SEQUENCE OF SafeBag */
+ASN1_ITEM_TEMPLATE(PKCS12_SAFEBAGS) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PKCS12_SAFEBAGS, PKCS12_SAFEBAG)
+ASN1_ITEM_TEMPLATE_END(PKCS12_SAFEBAGS)
+
+/* Authsafes: SEQUENCE OF PKCS7 */
+ASN1_ITEM_TEMPLATE(PKCS12_AUTHSAFES) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PKCS12_AUTHSAFES, PKCS7)
+ASN1_ITEM_TEMPLATE_END(PKCS12_AUTHSAFES)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_attr.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_attr.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_attr.c	(revision 331)
@@ -0,0 +1,103 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/pkcs12.h>
+#include "p12_lcl.h"
+
+/* Add a local keyid to a safebag */
+
+int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name,
+                          int namelen)
+{
+    if (X509at_add1_attr_by_NID(&bag->attrib, NID_localKeyID,
+                                V_ASN1_OCTET_STRING, name, namelen))
+        return 1;
+    else
+        return 0;
+}
+
+/* Add key usage to PKCS#8 structure */
+
+int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage)
+{
+    unsigned char us_val = (unsigned char)usage;
+    return PKCS8_pkey_add1_attr_by_NID(p8, NID_key_usage,
+                                       V_ASN1_BIT_STRING, &us_val, 1);
+}
+
+/* Add a friendlyname to a safebag */
+
+int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name,
+                                int namelen)
+{
+    if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName,
+                                MBSTRING_ASC, (unsigned char *)name, namelen))
+        return 1;
+    else
+        return 0;
+}
+
+int PKCS12_add_friendlyname_utf8(PKCS12_SAFEBAG *bag, const char *name,
+                                int namelen)
+{
+    if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName,
+                                MBSTRING_UTF8, (unsigned char *)name, namelen))
+        return 1;
+    else
+        return 0;
+}
+
+int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag,
+                                const unsigned char *name, int namelen)
+{
+    if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName,
+                                MBSTRING_BMP, name, namelen))
+        return 1;
+    else
+        return 0;
+}
+
+int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, int namelen)
+{
+    if (X509at_add1_attr_by_NID(&bag->attrib, NID_ms_csp_name,
+                                MBSTRING_ASC, (unsigned char *)name, namelen))
+        return 1;
+    else
+        return 0;
+}
+
+ASN1_TYPE *PKCS12_get_attr_gen(const STACK_OF(X509_ATTRIBUTE) *attrs,
+                               int attr_nid)
+{
+    X509_ATTRIBUTE *attrib;
+    int i;
+    i = X509at_get_attr_by_NID(attrs, attr_nid, -1);
+    attrib = X509at_get_attr(attrs, i);
+    return X509_ATTRIBUTE_get0_type(attrib, 0);
+}
+
+char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag)
+{
+    const ASN1_TYPE *atype;
+
+    if ((atype = PKCS12_SAFEBAG_get0_attr(bag, NID_friendlyName)) == NULL)
+        return NULL;
+    if (atype->type != V_ASN1_BMPSTRING)
+        return NULL;
+    return OPENSSL_uni2utf8(atype->value.bmpstring->data,
+                            atype->value.bmpstring->length);
+}
+
+const STACK_OF(X509_ATTRIBUTE) *
+PKCS12_SAFEBAG_get0_attrs(const PKCS12_SAFEBAG *bag)
+{
+    return bag->attrib;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_crpt.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_crpt.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_crpt.c	(revision 331)
@@ -0,0 +1,70 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/pkcs12.h>
+
+/* PKCS#12 PBE algorithms now in static table */
+
+void PKCS12_PBE_add(void)
+{
+}
+
+int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+                        ASN1_TYPE *param, const EVP_CIPHER *cipher,
+                        const EVP_MD *md, int en_de)
+{
+    PBEPARAM *pbe;
+    int saltlen, iter, ret;
+    unsigned char *salt;
+    unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
+    int (*pkcs12_key_gen)(const char *pass, int passlen,
+                          unsigned char *salt, int slen,
+                          int id, int iter, int n,
+                          unsigned char *out,
+                          const EVP_MD *md_type);
+
+    pkcs12_key_gen = PKCS12_key_gen_utf8;
+
+    if (cipher == NULL)
+        return 0;
+
+    /* Extract useful info from parameter */
+
+    pbe = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBEPARAM), param);
+    if (pbe == NULL) {
+        PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_DECODE_ERROR);
+        return 0;
+    }
+
+    if (!pbe->iter)
+        iter = 1;
+    else
+        iter = ASN1_INTEGER_get(pbe->iter);
+    salt = pbe->salt->data;
+    saltlen = pbe->salt->length;
+    if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_KEY_ID,
+                           iter, EVP_CIPHER_key_length(cipher), key, md)) {
+        PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_KEY_GEN_ERROR);
+        PBEPARAM_free(pbe);
+        return 0;
+    }
+    if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_IV_ID,
+                           iter, EVP_CIPHER_iv_length(cipher), iv, md)) {
+        PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_IV_GEN_ERROR);
+        PBEPARAM_free(pbe);
+        return 0;
+    }
+    PBEPARAM_free(pbe);
+    ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, en_de);
+    OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
+    OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_crt.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_crt.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_crt.c	(revision 331)
@@ -0,0 +1,291 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/pkcs12.h>
+#include "p12_lcl.h"
+
+static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
+                          PKCS12_SAFEBAG *bag);
+
+static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid)
+{
+    int idx;
+    X509_ATTRIBUTE *attr;
+    idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1);
+    if (idx < 0)
+        return 1;
+    attr = EVP_PKEY_get_attr(pkey, idx);
+    if (!X509at_add1_attr(&bag->attrib, attr))
+        return 0;
+    return 1;
+}
+
+PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert,
+                      STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter,
+                      int mac_iter, int keytype)
+{
+    PKCS12 *p12 = NULL;
+    STACK_OF(PKCS7) *safes = NULL;
+    STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
+    PKCS12_SAFEBAG *bag = NULL;
+    int i;
+    unsigned char keyid[EVP_MAX_MD_SIZE];
+    unsigned int keyidlen = 0;
+
+    /* Set defaults */
+    if (!nid_cert)
+#ifdef OPENSSL_NO_RC2
+        nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+#else
+        nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC;
+#endif
+    if (!nid_key)
+        nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+    if (!iter)
+        iter = PKCS12_DEFAULT_ITER;
+    if (!mac_iter)
+        mac_iter = 1;
+
+    if (!pkey && !cert && !ca) {
+        PKCS12err(PKCS12_F_PKCS12_CREATE, PKCS12_R_INVALID_NULL_ARGUMENT);
+        return NULL;
+    }
+
+    if (pkey && cert) {
+        if (!X509_check_private_key(cert, pkey))
+            return NULL;
+        X509_digest(cert, EVP_sha1(), keyid, &keyidlen);
+    }
+
+    if (cert) {
+        bag = PKCS12_add_cert(&bags, cert);
+        if (name && !PKCS12_add_friendlyname(bag, name, -1))
+            goto err;
+        if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
+            goto err;
+    }
+
+    /* Add all other certificates */
+    for (i = 0; i < sk_X509_num(ca); i++) {
+        if (!PKCS12_add_cert(&bags, sk_X509_value(ca, i)))
+            goto err;
+    }
+
+    if (bags && !PKCS12_add_safe(&safes, bags, nid_cert, iter, pass))
+        goto err;
+
+    sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+    bags = NULL;
+
+    if (pkey) {
+        bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass);
+
+        if (!bag)
+            goto err;
+
+        if (!copy_bag_attr(bag, pkey, NID_ms_csp_name))
+            goto err;
+        if (!copy_bag_attr(bag, pkey, NID_LocalKeySet))
+            goto err;
+
+        if (name && !PKCS12_add_friendlyname(bag, name, -1))
+            goto err;
+        if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
+            goto err;
+    }
+
+    if (bags && !PKCS12_add_safe(&safes, bags, -1, 0, NULL))
+        goto err;
+
+    sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+    bags = NULL;
+
+    p12 = PKCS12_add_safes(safes, 0);
+
+    if (!p12)
+        goto err;
+
+    sk_PKCS7_pop_free(safes, PKCS7_free);
+
+    safes = NULL;
+
+    if ((mac_iter != -1) &&
+        !PKCS12_set_mac(p12, pass, -1, NULL, 0, mac_iter, NULL))
+        goto err;
+
+    return p12;
+
+ err:
+    PKCS12_free(p12);
+    sk_PKCS7_pop_free(safes, PKCS7_free);
+    sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+    return NULL;
+
+}
+
+PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert)
+{
+    PKCS12_SAFEBAG *bag = NULL;
+    char *name;
+    int namelen = -1;
+    unsigned char *keyid;
+    int keyidlen = -1;
+
+    /* Add user certificate */
+    if ((bag = PKCS12_SAFEBAG_create_cert(cert)) == NULL)
+        goto err;
+
+    /*
+     * Use friendlyName and localKeyID in certificate. (if present)
+     */
+
+    name = (char *)X509_alias_get0(cert, &namelen);
+
+    if (name && !PKCS12_add_friendlyname(bag, name, namelen))
+        goto err;
+
+    keyid = X509_keyid_get0(cert, &keyidlen);
+
+    if (keyid && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
+        goto err;
+
+    if (!pkcs12_add_bag(pbags, bag))
+        goto err;
+
+    return bag;
+
+ err:
+    PKCS12_SAFEBAG_free(bag);
+    return NULL;
+
+}
+
+PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags,
+                               EVP_PKEY *key, int key_usage, int iter,
+                               int nid_key, const char *pass)
+{
+
+    PKCS12_SAFEBAG *bag = NULL;
+    PKCS8_PRIV_KEY_INFO *p8 = NULL;
+
+    /* Make a PKCS#8 structure */
+    if ((p8 = EVP_PKEY2PKCS8(key)) == NULL)
+        goto err;
+    if (key_usage && !PKCS8_add_keyusage(p8, key_usage))
+        goto err;
+    if (nid_key != -1) {
+        bag = PKCS12_SAFEBAG_create_pkcs8_encrypt(nid_key, pass, -1, NULL, 0,
+                                                  iter, p8);
+        PKCS8_PRIV_KEY_INFO_free(p8);
+    } else
+        bag = PKCS12_SAFEBAG_create0_p8inf(p8);
+
+    if (!bag)
+        goto err;
+
+    if (!pkcs12_add_bag(pbags, bag))
+        goto err;
+
+    return bag;
+
+ err:
+    PKCS12_SAFEBAG_free(bag);
+    return NULL;
+
+}
+
+int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
+                    int nid_safe, int iter, const char *pass)
+{
+    PKCS7 *p7 = NULL;
+    int free_safes = 0;
+
+    if (!*psafes) {
+        *psafes = sk_PKCS7_new_null();
+        if (!*psafes)
+            return 0;
+        free_safes = 1;
+    } else
+        free_safes = 0;
+
+    if (nid_safe == 0)
+#ifdef OPENSSL_NO_RC2
+        nid_safe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+#else
+        nid_safe = NID_pbe_WithSHA1And40BitRC2_CBC;
+#endif
+
+    if (nid_safe == -1)
+        p7 = PKCS12_pack_p7data(bags);
+    else
+        p7 = PKCS12_pack_p7encdata(nid_safe, pass, -1, NULL, 0, iter, bags);
+    if (!p7)
+        goto err;
+
+    if (!sk_PKCS7_push(*psafes, p7))
+        goto err;
+
+    return 1;
+
+ err:
+    if (free_safes) {
+        sk_PKCS7_free(*psafes);
+        *psafes = NULL;
+    }
+    PKCS7_free(p7);
+    return 0;
+
+}
+
+static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
+                          PKCS12_SAFEBAG *bag)
+{
+    int free_bags;
+    if (!pbags)
+        return 1;
+    if (!*pbags) {
+        *pbags = sk_PKCS12_SAFEBAG_new_null();
+        if (!*pbags)
+            return 0;
+        free_bags = 1;
+    } else
+        free_bags = 0;
+
+    if (!sk_PKCS12_SAFEBAG_push(*pbags, bag)) {
+        if (free_bags) {
+            sk_PKCS12_SAFEBAG_free(*pbags);
+            *pbags = NULL;
+        }
+        return 0;
+    }
+
+    return 1;
+
+}
+
+PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7)
+{
+    PKCS12 *p12;
+    if (nid_p7 <= 0)
+        nid_p7 = NID_pkcs7_data;
+    p12 = PKCS12_init(nid_p7);
+
+    if (!p12)
+        return NULL;
+
+    if (!PKCS12_pack_authsafes(p12, safes)) {
+        PKCS12_free(p12);
+        return NULL;
+    }
+
+    return p12;
+
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_decr.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_decr.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_decr.c	(revision 331)
@@ -0,0 +1,155 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/pkcs12.h>
+
+/* Define this to dump decrypted output to files called DERnnn */
+/*
+ * #define OPENSSL_DEBUG_DECRYPT
+ */
+
+/*
+ * Encrypt/Decrypt a buffer based on password and algor, result in a
+ * OPENSSL_malloc'ed buffer
+ */
+unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor,
+                                const char *pass, int passlen,
+                                const unsigned char *in, int inlen,
+                                unsigned char **data, int *datalen, int en_de)
+{
+    unsigned char *out = NULL;
+    int outlen, i;
+    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
+
+    if (ctx == NULL) {
+        PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    /* Decrypt data */
+    if (!EVP_PBE_CipherInit(algor->algorithm, pass, passlen,
+                            algor->parameter, ctx, en_de)) {
+        PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,
+                  PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR);
+        goto err;
+    }
+
+    if ((out = OPENSSL_malloc(inlen + EVP_CIPHER_CTX_block_size(ctx)))
+            == NULL) {
+        PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (!EVP_CipherUpdate(ctx, out, &i, in, inlen)) {
+        OPENSSL_free(out);
+        out = NULL;
+        PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_EVP_LIB);
+        goto err;
+    }
+
+    outlen = i;
+    if (!EVP_CipherFinal_ex(ctx, out + i, &i)) {
+        OPENSSL_free(out);
+        out = NULL;
+        PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT,
+                  PKCS12_R_PKCS12_CIPHERFINAL_ERROR);
+        goto err;
+    }
+    outlen += i;
+    if (datalen)
+        *datalen = outlen;
+    if (data)
+        *data = out;
+ err:
+    EVP_CIPHER_CTX_free(ctx);
+    return out;
+
+}
+
+/*
+ * Decrypt an OCTET STRING and decode ASN1 structure if zbuf set zero buffer
+ * after use.
+ */
+
+void *PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it,
+                              const char *pass, int passlen,
+                              const ASN1_OCTET_STRING *oct, int zbuf)
+{
+    unsigned char *out;
+    const unsigned char *p;
+    void *ret;
+    int outlen;
+
+    if (!PKCS12_pbe_crypt(algor, pass, passlen, oct->data, oct->length,
+                          &out, &outlen, 0)) {
+        PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I,
+                  PKCS12_R_PKCS12_PBE_CRYPT_ERROR);
+        return NULL;
+    }
+    p = out;
+#ifdef OPENSSL_DEBUG_DECRYPT
+    {
+        FILE *op;
+
+        char fname[30];
+        static int fnm = 1;
+        sprintf(fname, "DER%d", fnm++);
+        op = fopen(fname, "wb");
+        fwrite(p, 1, outlen, op);
+        fclose(op);
+    }
+#endif
+    ret = ASN1_item_d2i(NULL, &p, outlen, it);
+    if (zbuf)
+        OPENSSL_cleanse(out, outlen);
+    if (!ret)
+        PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I, PKCS12_R_DECODE_ERROR);
+    OPENSSL_free(out);
+    return ret;
+}
+
+/*
+ * Encode ASN1 structure and encrypt, return OCTET STRING if zbuf set zero
+ * encoding.
+ */
+
+ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor,
+                                           const ASN1_ITEM *it,
+                                           const char *pass, int passlen,
+                                           void *obj, int zbuf)
+{
+    ASN1_OCTET_STRING *oct = NULL;
+    unsigned char *in = NULL;
+    int inlen;
+
+    if ((oct = ASN1_OCTET_STRING_new()) == NULL) {
+        PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    inlen = ASN1_item_i2d(obj, &in, it);
+    if (!in) {
+        PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, PKCS12_R_ENCODE_ERROR);
+        goto err;
+    }
+    if (!PKCS12_pbe_crypt(algor, pass, passlen, in, inlen, &oct->data,
+                          &oct->length, 1)) {
+        PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, PKCS12_R_ENCRYPT_ERROR);
+        OPENSSL_free(in);
+        goto err;
+    }
+    if (zbuf)
+        OPENSSL_cleanse(in, inlen);
+    OPENSSL_free(in);
+    return oct;
+ err:
+    ASN1_OCTET_STRING_free(oct);
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_init.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_init.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_init.c	(revision 331)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/pkcs12.h>
+#include "p12_lcl.h"
+
+/* Initialise a PKCS12 structure to take data */
+
+PKCS12 *PKCS12_init(int mode)
+{
+    PKCS12 *pkcs12;
+
+    if ((pkcs12 = PKCS12_new()) == NULL) {
+        PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    ASN1_INTEGER_set(pkcs12->version, 3);
+    pkcs12->authsafes->type = OBJ_nid2obj(mode);
+    switch (mode) {
+    case NID_pkcs7_data:
+        if ((pkcs12->authsafes->d.data = ASN1_OCTET_STRING_new()) == NULL) {
+            PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        break;
+    default:
+        PKCS12err(PKCS12_F_PKCS12_INIT, PKCS12_R_UNSUPPORTED_PKCS12_MODE);
+        goto err;
+    }
+    return pkcs12;
+
+ err:
+    PKCS12_free(pkcs12);
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_key.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_key.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_key.c	(revision 331)
@@ -0,0 +1,205 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/pkcs12.h>
+#include <openssl/bn.h>
+
+/* Uncomment out this line to get debugging info about key generation */
+/*
+ * #define OPENSSL_DEBUG_KEYGEN
+ */
+#ifdef OPENSSL_DEBUG_KEYGEN
+# include <openssl/bio.h>
+extern BIO *bio_err;
+void h__dump(unsigned char *p, int len);
+#endif
+
+/* PKCS12 compatible key/IV generation */
+#ifndef min
+# define min(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
+                       int saltlen, int id, int iter, int n,
+                       unsigned char *out, const EVP_MD *md_type)
+{
+    int ret;
+    unsigned char *unipass;
+    int uniplen;
+
+    if (!pass) {
+        unipass = NULL;
+        uniplen = 0;
+    } else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) {
+        PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen,
+                             id, iter, n, out, md_type);
+    if (ret <= 0)
+        return 0;
+    OPENSSL_clear_free(unipass, uniplen);
+    return ret;
+}
+
+int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt,
+                        int saltlen, int id, int iter, int n,
+                        unsigned char *out, const EVP_MD *md_type)
+{
+    int ret;
+    unsigned char *unipass;
+    int uniplen;
+
+    if (!pass) {
+        unipass = NULL;
+        uniplen = 0;
+    } else if (!OPENSSL_utf82uni(pass, passlen, &unipass, &uniplen)) {
+        PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UTF8, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen,
+                             id, iter, n, out, md_type);
+    if (ret <= 0)
+        return 0;
+    OPENSSL_clear_free(unipass, uniplen);
+    return ret;
+}
+
+int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
+                       int saltlen, int id, int iter, int n,
+                       unsigned char *out, const EVP_MD *md_type)
+{
+    unsigned char *B = NULL, *D = NULL, *I = NULL, *p = NULL, *Ai = NULL;
+    int Slen, Plen, Ilen, Ijlen;
+    int i, j, u, v;
+    int ret = 0;
+    BIGNUM *Ij = NULL, *Bpl1 = NULL; /* These hold Ij and B + 1 */
+    EVP_MD_CTX *ctx = NULL;
+#ifdef  OPENSSL_DEBUG_KEYGEN
+    unsigned char *tmpout = out;
+    int tmpn = n;
+#endif
+
+    ctx = EVP_MD_CTX_new();
+    if (ctx == NULL)
+        goto err;
+
+#ifdef  OPENSSL_DEBUG_KEYGEN
+    fprintf(stderr, "KEYGEN DEBUG\n");
+    fprintf(stderr, "ID %d, ITER %d\n", id, iter);
+    fprintf(stderr, "Password (length %d):\n", passlen);
+    h__dump(pass, passlen);
+    fprintf(stderr, "Salt (length %d):\n", saltlen);
+    h__dump(salt, saltlen);
+#endif
+    v = EVP_MD_block_size(md_type);
+    u = EVP_MD_size(md_type);
+    if (u < 0 || v <= 0)
+        goto err;
+    D = OPENSSL_malloc(v);
+    Ai = OPENSSL_malloc(u);
+    B = OPENSSL_malloc(v + 1);
+    Slen = v * ((saltlen + v - 1) / v);
+    if (passlen)
+        Plen = v * ((passlen + v - 1) / v);
+    else
+        Plen = 0;
+    Ilen = Slen + Plen;
+    I = OPENSSL_malloc(Ilen);
+    Ij = BN_new();
+    Bpl1 = BN_new();
+    if (D == NULL || Ai == NULL || B == NULL || I == NULL || Ij == NULL
+            || Bpl1 == NULL)
+        goto err;
+    for (i = 0; i < v; i++)
+        D[i] = id;
+    p = I;
+    for (i = 0; i < Slen; i++)
+        *p++ = salt[i % saltlen];
+    for (i = 0; i < Plen; i++)
+        *p++ = pass[i % passlen];
+    for (;;) {
+        if (!EVP_DigestInit_ex(ctx, md_type, NULL)
+            || !EVP_DigestUpdate(ctx, D, v)
+            || !EVP_DigestUpdate(ctx, I, Ilen)
+            || !EVP_DigestFinal_ex(ctx, Ai, NULL))
+            goto err;
+        for (j = 1; j < iter; j++) {
+            if (!EVP_DigestInit_ex(ctx, md_type, NULL)
+                || !EVP_DigestUpdate(ctx, Ai, u)
+                || !EVP_DigestFinal_ex(ctx, Ai, NULL))
+                goto err;
+        }
+        memcpy(out, Ai, min(n, u));
+        if (u >= n) {
+#ifdef OPENSSL_DEBUG_KEYGEN
+            fprintf(stderr, "Output KEY (length %d)\n", tmpn);
+            h__dump(tmpout, tmpn);
+#endif
+            ret = 1;
+            goto end;
+        }
+        n -= u;
+        out += u;
+        for (j = 0; j < v; j++)
+            B[j] = Ai[j % u];
+        /* Work out B + 1 first then can use B as tmp space */
+        if (!BN_bin2bn(B, v, Bpl1))
+            goto err;
+        if (!BN_add_word(Bpl1, 1))
+            goto err;
+        for (j = 0; j < Ilen; j += v) {
+            if (!BN_bin2bn(I + j, v, Ij))
+                goto err;
+            if (!BN_add(Ij, Ij, Bpl1))
+                goto err;
+            if (!BN_bn2bin(Ij, B))
+                goto err;
+            Ijlen = BN_num_bytes(Ij);
+            /* If more than 2^(v*8) - 1 cut off MSB */
+            if (Ijlen > v) {
+                if (!BN_bn2bin(Ij, B))
+                    goto err;
+                memcpy(I + j, B + 1, v);
+#ifndef PKCS12_BROKEN_KEYGEN
+                /* If less than v bytes pad with zeroes */
+            } else if (Ijlen < v) {
+                memset(I + j, 0, v - Ijlen);
+                if (!BN_bn2bin(Ij, I + j + v - Ijlen))
+                    goto err;
+#endif
+            } else if (!BN_bn2bin(Ij, I + j))
+                goto err;
+        }
+    }
+
+ err:
+    PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_MALLOC_FAILURE);
+
+ end:
+    OPENSSL_free(Ai);
+    OPENSSL_free(B);
+    OPENSSL_free(D);
+    OPENSSL_free(I);
+    BN_free(Ij);
+    BN_free(Bpl1);
+    EVP_MD_CTX_free(ctx);
+    return ret;
+}
+
+#ifdef OPENSSL_DEBUG_KEYGEN
+void h__dump(unsigned char *p, int len)
+{
+    for (; len--; p++)
+        fprintf(stderr, "%02X", *p);
+    fprintf(stderr, "\n");
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_kiss.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_kiss.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_kiss.c	(revision 331)
@@ -0,0 +1,245 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/pkcs12.h>
+
+/* Simplified PKCS#12 routines */
+
+static int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
+                      EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
+
+static int parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
+                      int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
+
+static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
+                     EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
+
+/*
+ * Parse and decrypt a PKCS#12 structure returning user key, user cert and
+ * other (CA) certs. Note either ca should be NULL, *ca should be NULL, or it
+ * should point to a valid STACK structure. pkey and cert can be passed
+ * uninitialised.
+ */
+
+int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
+                 STACK_OF(X509) **ca)
+{
+    STACK_OF(X509) *ocerts = NULL;
+    X509 *x = NULL;
+    /* Check for NULL PKCS12 structure */
+
+    if (!p12) {
+        PKCS12err(PKCS12_F_PKCS12_PARSE,
+                  PKCS12_R_INVALID_NULL_PKCS12_POINTER);
+        return 0;
+    }
+
+    if (pkey)
+        *pkey = NULL;
+    if (cert)
+        *cert = NULL;
+
+    /* Check the mac */
+
+    /*
+     * If password is zero length or NULL then try verifying both cases to
+     * determine which password is correct. The reason for this is that under
+     * PKCS#12 password based encryption no password and a zero length
+     * password are two different things...
+     */
+
+    if (!pass || !*pass) {
+        if (PKCS12_verify_mac(p12, NULL, 0))
+            pass = NULL;
+        else if (PKCS12_verify_mac(p12, "", 0))
+            pass = "";
+        else {
+            PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE);
+            goto err;
+        }
+    } else if (!PKCS12_verify_mac(p12, pass, -1)) {
+        PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE);
+        goto err;
+    }
+
+    /* Allocate stack for other certificates */
+    ocerts = sk_X509_new_null();
+
+    if (!ocerts) {
+        PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    if (!parse_pk12(p12, pass, -1, pkey, ocerts)) {
+        PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_PARSE_ERROR);
+        goto err;
+    }
+
+    while ((x = sk_X509_pop(ocerts))) {
+        if (pkey && *pkey && cert && !*cert) {
+            ERR_set_mark();
+            if (X509_check_private_key(x, *pkey)) {
+                *cert = x;
+                x = NULL;
+            }
+            ERR_pop_to_mark();
+        }
+
+        if (ca && x) {
+            if (!*ca)
+                *ca = sk_X509_new_null();
+            if (!*ca)
+                goto err;
+            if (!sk_X509_push(*ca, x))
+                goto err;
+            x = NULL;
+        }
+        X509_free(x);
+    }
+
+    sk_X509_pop_free(ocerts, X509_free);
+
+    return 1;
+
+ err:
+
+    if (pkey)
+        EVP_PKEY_free(*pkey);
+    if (cert)
+        X509_free(*cert);
+    X509_free(x);
+    sk_X509_pop_free(ocerts, X509_free);
+    return 0;
+
+}
+
+/* Parse the outer PKCS#12 structure */
+
+static int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
+                      EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
+{
+    STACK_OF(PKCS7) *asafes;
+    STACK_OF(PKCS12_SAFEBAG) *bags;
+    int i, bagnid;
+    PKCS7 *p7;
+
+    if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
+        return 0;
+    for (i = 0; i < sk_PKCS7_num(asafes); i++) {
+        p7 = sk_PKCS7_value(asafes, i);
+        bagnid = OBJ_obj2nid(p7->type);
+        if (bagnid == NID_pkcs7_data) {
+            bags = PKCS12_unpack_p7data(p7);
+        } else if (bagnid == NID_pkcs7_encrypted) {
+            bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
+        } else
+            continue;
+        if (!bags) {
+            sk_PKCS7_pop_free(asafes, PKCS7_free);
+            return 0;
+        }
+        if (!parse_bags(bags, pass, passlen, pkey, ocerts)) {
+            sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+            sk_PKCS7_pop_free(asafes, PKCS7_free);
+            return 0;
+        }
+        sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+    }
+    sk_PKCS7_pop_free(asafes, PKCS7_free);
+    return 1;
+}
+
+static int parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
+                      int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
+{
+    int i;
+    for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
+        if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i),
+                       pass, passlen, pkey, ocerts))
+            return 0;
+    }
+    return 1;
+}
+
+static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
+                     EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
+{
+    PKCS8_PRIV_KEY_INFO *p8;
+    X509 *x509;
+    const ASN1_TYPE *attrib;
+    ASN1_BMPSTRING *fname = NULL;
+    ASN1_OCTET_STRING *lkid = NULL;
+
+    if ((attrib = PKCS12_SAFEBAG_get0_attr(bag, NID_friendlyName)))
+        fname = attrib->value.bmpstring;
+
+    if ((attrib = PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID)))
+        lkid = attrib->value.octet_string;
+
+    switch (PKCS12_SAFEBAG_get_nid(bag)) {
+    case NID_keyBag:
+        if (!pkey || *pkey)
+            return 1;
+        *pkey = EVP_PKCS82PKEY(PKCS12_SAFEBAG_get0_p8inf(bag));
+        if (*pkey == NULL)
+            return 0;
+        break;
+
+    case NID_pkcs8ShroudedKeyBag:
+        if (!pkey || *pkey)
+            return 1;
+        if ((p8 = PKCS12_decrypt_skey(bag, pass, passlen)) == NULL)
+            return 0;
+        *pkey = EVP_PKCS82PKEY(p8);
+        PKCS8_PRIV_KEY_INFO_free(p8);
+        if (!(*pkey))
+            return 0;
+        break;
+
+    case NID_certBag:
+        if (PKCS12_SAFEBAG_get_bag_nid(bag) != NID_x509Certificate)
+            return 1;
+        if ((x509 = PKCS12_SAFEBAG_get1_cert(bag)) == NULL)
+            return 0;
+        if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) {
+            X509_free(x509);
+            return 0;
+        }
+        if (fname) {
+            int len, r;
+            unsigned char *data;
+            len = ASN1_STRING_to_UTF8(&data, fname);
+            if (len >= 0) {
+                r = X509_alias_set1(x509, data, len);
+                OPENSSL_free(data);
+                if (!r) {
+                    X509_free(x509);
+                    return 0;
+                }
+            }
+        }
+
+        if (!sk_X509_push(ocerts, x509)) {
+            X509_free(x509);
+            return 0;
+        }
+
+        break;
+
+    case NID_safeContentsBag:
+        return parse_bags(PKCS12_SAFEBAG_get0_safes(bag), pass, passlen, pkey,
+                          ocerts);
+
+    default:
+        return 1;
+    }
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_lcl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_lcl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_lcl.h	(revision 331)
@@ -0,0 +1,43 @@
+/*
+ * 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
+ */
+
+struct PKCS12_MAC_DATA_st {
+    X509_SIG *dinfo;
+    ASN1_OCTET_STRING *salt;
+    ASN1_INTEGER *iter;         /* defaults to 1 */
+};
+
+struct PKCS12_st {
+    ASN1_INTEGER *version;
+    PKCS12_MAC_DATA *mac;
+    PKCS7 *authsafes;
+};
+
+struct PKCS12_SAFEBAG_st {
+    ASN1_OBJECT *type;
+    union {
+        struct pkcs12_bag_st *bag; /* secret, crl and certbag */
+        struct pkcs8_priv_key_info_st *keybag; /* keybag */
+        X509_SIG *shkeybag;     /* shrouded key bag */
+        STACK_OF(PKCS12_SAFEBAG) *safes;
+        ASN1_TYPE *other;
+    } value;
+    STACK_OF(X509_ATTRIBUTE) *attrib;
+};
+
+struct pkcs12_bag_st {
+    ASN1_OBJECT *type;
+    union {
+        ASN1_OCTET_STRING *x509cert;
+        ASN1_OCTET_STRING *x509crl;
+        ASN1_OCTET_STRING *octet;
+        ASN1_IA5STRING *sdsicert;
+        ASN1_TYPE *other;       /* Secret or other bag */
+    } value;
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_mutl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_mutl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_mutl.c	(revision 331)
@@ -0,0 +1,239 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+# include "internal/cryptlib.h"
+# include <openssl/crypto.h>
+# include <openssl/hmac.h>
+# include <openssl/rand.h>
+# include <openssl/pkcs12.h>
+# include "p12_lcl.h"
+
+int PKCS12_mac_present(const PKCS12 *p12)
+{
+    return p12->mac ? 1 : 0;
+}
+
+void PKCS12_get0_mac(const ASN1_OCTET_STRING **pmac,
+                     const X509_ALGOR **pmacalg,
+                     const ASN1_OCTET_STRING **psalt,
+                     const ASN1_INTEGER **piter,
+                     const PKCS12 *p12)
+{
+    if (p12->mac) {
+        X509_SIG_get0(p12->mac->dinfo, pmacalg, pmac);
+        if (psalt)
+            *psalt = p12->mac->salt;
+        if (piter)
+            *piter = p12->mac->iter;
+    } else {
+        if (pmac)
+            *pmac = NULL;
+        if (pmacalg)
+            *pmacalg = NULL;
+        if (psalt)
+            *psalt = NULL;
+        if (piter)
+            *piter = NULL;
+    }
+}
+
+# define TK26_MAC_KEY_LEN 32
+
+static int pkcs12_gen_gost_mac_key(const char *pass, int passlen,
+                                   const unsigned char *salt, int saltlen,
+                                   int iter, int keylen, unsigned char *key,
+                                   const EVP_MD *digest)
+{
+    unsigned char out[96];
+
+    if (keylen != TK26_MAC_KEY_LEN) {
+        return 0;
+    }
+
+    if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter,
+                           digest, sizeof(out), out)) {
+        return 0;
+    }
+    memcpy(key, out + sizeof(out) - TK26_MAC_KEY_LEN, TK26_MAC_KEY_LEN);
+    OPENSSL_cleanse(out, sizeof(out));
+    return 1;
+}
+
+/* Generate a MAC */
+static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
+                          unsigned char *mac, unsigned int *maclen,
+                          int (*pkcs12_key_gen)(const char *pass, int passlen,
+                                                unsigned char *salt, int slen,
+                                                int id, int iter, int n,
+                                                unsigned char *out,
+                                                const EVP_MD *md_type))
+{
+    const EVP_MD *md_type;
+    HMAC_CTX *hmac = NULL;
+    unsigned char key[EVP_MAX_MD_SIZE], *salt;
+    int saltlen, iter;
+    int md_size = 0;
+    int md_type_nid;
+    const X509_ALGOR *macalg;
+    const ASN1_OBJECT *macoid;
+
+    if (pkcs12_key_gen == NULL)
+        pkcs12_key_gen = PKCS12_key_gen_utf8;
+
+    if (!PKCS7_type_is_data(p12->authsafes)) {
+        PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_CONTENT_TYPE_NOT_DATA);
+        return 0;
+    }
+
+    salt = p12->mac->salt->data;
+    saltlen = p12->mac->salt->length;
+    if (!p12->mac->iter)
+        iter = 1;
+    else
+        iter = ASN1_INTEGER_get(p12->mac->iter);
+    X509_SIG_get0(p12->mac->dinfo, &macalg, NULL);
+    X509_ALGOR_get0(&macoid, NULL, NULL, macalg);
+    if ((md_type = EVP_get_digestbyobj(macoid)) == NULL) {
+        PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM);
+        return 0;
+    }
+    md_size = EVP_MD_size(md_type);
+    md_type_nid = EVP_MD_type(md_type);
+    if (md_size < 0)
+        return 0;
+    if ((md_type_nid == NID_id_GostR3411_94
+         || md_type_nid == NID_id_GostR3411_2012_256
+         || md_type_nid == NID_id_GostR3411_2012_512)
+        && !getenv("LEGACY_GOST_PKCS12")) {
+        md_size = TK26_MAC_KEY_LEN;
+        if (!pkcs12_gen_gost_mac_key(pass, passlen, salt, saltlen, iter,
+                                     md_size, key, md_type)) {
+            PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR);
+            return 0;
+        }
+    } else
+        if (!(*pkcs12_key_gen)(pass, passlen, salt, saltlen, PKCS12_MAC_ID,
+                               iter, md_size, key, md_type)) {
+        PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR);
+        return 0;
+    }
+    hmac = HMAC_CTX_new();
+    if (!HMAC_Init_ex(hmac, key, md_size, md_type, NULL)
+        || !HMAC_Update(hmac, p12->authsafes->d.data->data,
+                        p12->authsafes->d.data->length)
+        || !HMAC_Final(hmac, mac, maclen)) {
+        HMAC_CTX_free(hmac);
+        return 0;
+    }
+    HMAC_CTX_free(hmac);
+    return 1;
+}
+
+int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
+                   unsigned char *mac, unsigned int *maclen)
+{
+    return pkcs12_gen_mac(p12, pass, passlen, mac, maclen, NULL);
+}
+
+/* Verify the mac */
+int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen)
+{
+    unsigned char mac[EVP_MAX_MD_SIZE];
+    unsigned int maclen;
+    const ASN1_OCTET_STRING *macoct;
+
+    if (p12->mac == NULL) {
+        PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_ABSENT);
+        return 0;
+    }
+    if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen,
+                        PKCS12_key_gen_utf8)) {
+        PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_GENERATION_ERROR);
+        return 0;
+    }
+    X509_SIG_get0(p12->mac->dinfo, NULL, &macoct);
+    if ((maclen != (unsigned int)ASN1_STRING_length(macoct))
+        || CRYPTO_memcmp(mac, ASN1_STRING_get0_data(macoct), maclen) != 0)
+        return 0;
+
+    return 1;
+}
+
+/* Set a mac */
+
+int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
+                   unsigned char *salt, int saltlen, int iter,
+                   const EVP_MD *md_type)
+{
+    unsigned char mac[EVP_MAX_MD_SIZE];
+    unsigned int maclen;
+    ASN1_OCTET_STRING *macoct;
+
+    if (!md_type)
+        md_type = EVP_sha1();
+    if (PKCS12_setup_mac(p12, iter, salt, saltlen, md_type) == PKCS12_ERROR) {
+        PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_SETUP_ERROR);
+        return 0;
+    }
+    /*
+     * Note that output mac is forced to UTF-8...
+     */
+    if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen,
+                        PKCS12_key_gen_utf8)) {
+        PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_GENERATION_ERROR);
+        return 0;
+    }
+    X509_SIG_getm(p12->mac->dinfo, NULL, &macoct);
+    if (!ASN1_OCTET_STRING_set(macoct, mac, maclen)) {
+        PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_STRING_SET_ERROR);
+        return 0;
+    }
+    return 1;
+}
+
+/* Set up a mac structure */
+int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen,
+                     const EVP_MD *md_type)
+{
+    X509_ALGOR *macalg;
+
+    if ((p12->mac = PKCS12_MAC_DATA_new()) == NULL)
+        return PKCS12_ERROR;
+    if (iter > 1) {
+        if ((p12->mac->iter = ASN1_INTEGER_new()) == NULL) {
+            PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        if (!ASN1_INTEGER_set(p12->mac->iter, iter)) {
+            PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+    }
+    if (!saltlen)
+        saltlen = PKCS12_SALT_LEN;
+    if ((p12->mac->salt->data = OPENSSL_malloc(saltlen)) == NULL) {
+        PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    p12->mac->salt->length = saltlen;
+    if (!salt) {
+        if (RAND_bytes(p12->mac->salt->data, saltlen) <= 0)
+            return 0;
+    } else
+        memcpy(p12->mac->salt->data, salt, saltlen);
+    X509_SIG_getm(p12->mac->dinfo, &macalg, NULL);
+    if (!X509_ALGOR_set0(macalg, OBJ_nid2obj(EVP_MD_type(md_type)),
+                         V_ASN1_NULL, NULL)) {
+        PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_npas.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_npas.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_npas.c	(revision 331)
@@ -0,0 +1,184 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/pkcs12.h>
+#include "p12_lcl.h"
+
+/* PKCS#12 password change routine */
+
+static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass);
+static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass,
+                        const char *newpass);
+static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass,
+                        const char *newpass);
+static int alg_get(const X509_ALGOR *alg, int *pnid, int *piter,
+                   int *psaltlen);
+
+/*
+ * Change the password on a PKCS#12 structure.
+ */
+
+int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass)
+{
+    /* Check for NULL PKCS12 structure */
+
+    if (!p12) {
+        PKCS12err(PKCS12_F_PKCS12_NEWPASS,
+                  PKCS12_R_INVALID_NULL_PKCS12_POINTER);
+        return 0;
+    }
+
+    /* Check the mac */
+
+    if (!PKCS12_verify_mac(p12, oldpass, -1)) {
+        PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_MAC_VERIFY_FAILURE);
+        return 0;
+    }
+
+    if (!newpass_p12(p12, oldpass, newpass)) {
+        PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_PARSE_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+
+/* Parse the outer PKCS#12 structure */
+
+static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass)
+{
+    STACK_OF(PKCS7) *asafes = NULL, *newsafes = NULL;
+    STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
+    int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0;
+    PKCS7 *p7, *p7new;
+    ASN1_OCTET_STRING *p12_data_tmp = NULL, *macoct = NULL;
+    unsigned char mac[EVP_MAX_MD_SIZE];
+    unsigned int maclen;
+    int rv = 0;
+
+    if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
+        goto err;
+    if ((newsafes = sk_PKCS7_new_null()) == NULL)
+        goto err;
+    for (i = 0; i < sk_PKCS7_num(asafes); i++) {
+        p7 = sk_PKCS7_value(asafes, i);
+        bagnid = OBJ_obj2nid(p7->type);
+        if (bagnid == NID_pkcs7_data) {
+            bags = PKCS12_unpack_p7data(p7);
+        } else if (bagnid == NID_pkcs7_encrypted) {
+            bags = PKCS12_unpack_p7encdata(p7, oldpass, -1);
+            if (!alg_get(p7->d.encrypted->enc_data->algorithm,
+                         &pbe_nid, &pbe_iter, &pbe_saltlen))
+                goto err;
+        } else {
+            continue;
+        }
+        if (bags == NULL)
+            goto err;
+        if (!newpass_bags(bags, oldpass, newpass))
+            goto err;
+        /* Repack bag in same form with new password */
+        if (bagnid == NID_pkcs7_data)
+            p7new = PKCS12_pack_p7data(bags);
+        else
+            p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, NULL,
+                                          pbe_saltlen, pbe_iter, bags);
+        if (!p7new || !sk_PKCS7_push(newsafes, p7new))
+            goto err;
+        sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+        bags = NULL;
+    }
+
+    /* Repack safe: save old safe in case of error */
+
+    p12_data_tmp = p12->authsafes->d.data;
+    if ((p12->authsafes->d.data = ASN1_OCTET_STRING_new()) == NULL)
+        goto err;
+    if (!PKCS12_pack_authsafes(p12, newsafes))
+        goto err;
+
+    if (!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen))
+        goto err;
+    X509_SIG_getm(p12->mac->dinfo, NULL, &macoct);
+    if (!ASN1_OCTET_STRING_set(macoct, mac, maclen))
+        goto err;
+
+    rv = 1;
+
+err:
+    /* Restore old safe if necessary */
+    if (rv == 1) {
+        ASN1_OCTET_STRING_free(p12_data_tmp);
+    } else if (p12_data_tmp != NULL) {
+        ASN1_OCTET_STRING_free(p12->authsafes->d.data);
+        p12->authsafes->d.data = p12_data_tmp;
+    }
+    sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+    sk_PKCS7_pop_free(asafes, PKCS7_free);
+    sk_PKCS7_pop_free(newsafes, PKCS7_free);
+    return rv;
+}
+
+static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass,
+                        const char *newpass)
+{
+    int i;
+    for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
+        if (!newpass_bag(sk_PKCS12_SAFEBAG_value(bags, i), oldpass, newpass))
+            return 0;
+    }
+    return 1;
+}
+
+/* Change password of safebag: only needs handle shrouded keybags */
+
+static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass,
+                       const char *newpass)
+{
+    PKCS8_PRIV_KEY_INFO *p8;
+    X509_SIG *p8new;
+    int p8_nid, p8_saltlen, p8_iter;
+    const X509_ALGOR *shalg;
+
+    if (PKCS12_SAFEBAG_get_nid(bag) != NID_pkcs8ShroudedKeyBag)
+        return 1;
+
+    if ((p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1)) == NULL)
+        return 0;
+    X509_SIG_get0(bag->value.shkeybag, &shalg, NULL);
+    if (!alg_get(shalg, &p8_nid, &p8_iter, &p8_saltlen))
+        return 0;
+    p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen,
+                          p8_iter, p8);
+    PKCS8_PRIV_KEY_INFO_free(p8);
+    if (p8new == NULL)
+        return 0;
+    X509_SIG_free(bag->value.shkeybag);
+    bag->value.shkeybag = p8new;
+    return 1;
+}
+
+static int alg_get(const X509_ALGOR *alg, int *pnid, int *piter,
+                   int *psaltlen)
+{
+    PBEPARAM *pbe;
+    pbe = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(PBEPARAM), alg->parameter);
+    if (!pbe)
+        return 0;
+    *pnid = OBJ_obj2nid(alg->algorithm);
+    *piter = ASN1_INTEGER_get(pbe->iter);
+    *psaltlen = pbe->salt->length;
+    PBEPARAM_free(pbe);
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_p8d.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_p8d.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_p8d.c	(revision 331)
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2001-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/pkcs12.h>
+
+PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(const X509_SIG *p8, const char *pass,
+                                   int passlen)
+{
+    const X509_ALGOR *dalg;
+    const ASN1_OCTET_STRING *doct;
+    X509_SIG_get0(p8, &dalg, &doct);
+    return PKCS12_item_decrypt_d2i(dalg,
+                                   ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), pass,
+                                   passlen, doct, 1);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_p8e.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_p8e.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_p8e.c	(revision 331)
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2001-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/pkcs12.h>
+#include "internal/x509_int.h"
+
+X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
+                        const char *pass, int passlen,
+                        unsigned char *salt, int saltlen, int iter,
+                        PKCS8_PRIV_KEY_INFO *p8inf)
+{
+    X509_SIG *p8 = NULL;
+    X509_ALGOR *pbe;
+
+    if (pbe_nid == -1)
+        pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen);
+    else if (EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0))
+        pbe = PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, pbe_nid);
+    else {
+        ERR_clear_error();
+        pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen);
+    }
+    if (!pbe) {
+        PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_ASN1_LIB);
+        return NULL;
+    }
+    p8 = PKCS8_set0_pbe(pass, passlen, p8inf, pbe);
+    if (p8 == NULL) {
+        X509_ALGOR_free(pbe);
+        return NULL;
+    }
+
+    return p8;
+}
+
+X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen,
+                         PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe)
+{
+    X509_SIG *p8;
+    ASN1_OCTET_STRING *enckey;
+
+    enckey =
+        PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO),
+                                pass, passlen, p8inf, 1);
+    if (!enckey) {
+        PKCS12err(PKCS12_F_PKCS8_SET0_PBE, PKCS12_R_ENCRYPT_ERROR);
+        return NULL;
+    }
+
+    p8 = OPENSSL_zalloc(sizeof(*p8));
+
+    if (p8 == NULL) {
+        PKCS12err(PKCS12_F_PKCS8_SET0_PBE, ERR_R_MALLOC_FAILURE);
+        ASN1_OCTET_STRING_free(enckey);
+        return NULL;
+    }
+    p8->algor = pbe;
+    p8->digest = enckey;
+
+    return p8;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_sbag.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_sbag.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_sbag.c	(revision 331)
@@ -0,0 +1,170 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/pkcs12.h>
+#include "p12_lcl.h"
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+ASN1_TYPE *PKCS12_get_attr(const PKCS12_SAFEBAG *bag, int attr_nid)
+{
+    return PKCS12_get_attr_gen(bag->attrib, attr_nid);
+}
+#endif
+
+const ASN1_TYPE *PKCS12_SAFEBAG_get0_attr(const PKCS12_SAFEBAG *bag,
+                                          int attr_nid)
+{
+    return PKCS12_get_attr_gen(bag->attrib, attr_nid);
+}
+
+ASN1_TYPE *PKCS8_get_attr(PKCS8_PRIV_KEY_INFO *p8, int attr_nid)
+{
+    return PKCS12_get_attr_gen(PKCS8_pkey_get0_attrs(p8), attr_nid);
+}
+
+const PKCS8_PRIV_KEY_INFO *PKCS12_SAFEBAG_get0_p8inf(const PKCS12_SAFEBAG *bag)
+{
+    if (PKCS12_SAFEBAG_get_nid(bag) != NID_keyBag)
+        return NULL;
+    return bag->value.keybag;
+}
+
+const X509_SIG *PKCS12_SAFEBAG_get0_pkcs8(const PKCS12_SAFEBAG *bag)
+{
+    if (OBJ_obj2nid(bag->type) != NID_pkcs8ShroudedKeyBag)
+        return NULL;
+    return bag->value.shkeybag;
+}
+
+const STACK_OF(PKCS12_SAFEBAG) *
+PKCS12_SAFEBAG_get0_safes(const PKCS12_SAFEBAG *bag)
+{
+    if (OBJ_obj2nid(bag->type) != NID_safeContentsBag)
+        return NULL;
+    return bag->value.safes;
+}
+
+const ASN1_OBJECT *PKCS12_SAFEBAG_get0_type(const PKCS12_SAFEBAG *bag)
+{
+    return bag->type;
+}
+
+int PKCS12_SAFEBAG_get_nid(const PKCS12_SAFEBAG *bag)
+{
+    return OBJ_obj2nid(bag->type);
+}
+
+int PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag)
+{
+    int btype = PKCS12_SAFEBAG_get_nid(bag);
+
+    if (btype != NID_certBag && btype != NID_crlBag && btype != NID_secretBag)
+        return -1;
+    return OBJ_obj2nid(bag->value.bag->type);
+}
+
+X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag)
+{
+    if (PKCS12_SAFEBAG_get_nid(bag) != NID_certBag)
+        return NULL;
+    if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Certificate)
+        return NULL;
+    return ASN1_item_unpack(bag->value.bag->value.octet,
+                            ASN1_ITEM_rptr(X509));
+}
+
+X509_CRL *PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag)
+{
+    if (PKCS12_SAFEBAG_get_nid(bag) != NID_crlBag)
+        return NULL;
+    if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Crl)
+        return NULL;
+    return ASN1_item_unpack(bag->value.bag->value.octet,
+                            ASN1_ITEM_rptr(X509_CRL));
+}
+
+PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_cert(X509 *x509)
+{
+    return PKCS12_item_pack_safebag(x509, ASN1_ITEM_rptr(X509),
+                                    NID_x509Certificate, NID_certBag);
+}
+
+PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_crl(X509_CRL *crl)
+{
+    return PKCS12_item_pack_safebag(crl, ASN1_ITEM_rptr(X509_CRL),
+                                    NID_x509Crl, NID_crlBag);
+}
+
+/* Turn PKCS8 object into a keybag */
+
+PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8)
+{
+    PKCS12_SAFEBAG *bag = PKCS12_SAFEBAG_new();
+
+    if (bag == NULL) {
+        PKCS12err(PKCS12_F_PKCS12_SAFEBAG_CREATE0_P8INF, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    bag->type = OBJ_nid2obj(NID_keyBag);
+    bag->value.keybag = p8;
+    return bag;
+}
+
+/* Turn PKCS8 object into a shrouded keybag */
+
+PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8)
+{
+    PKCS12_SAFEBAG *bag = PKCS12_SAFEBAG_new();
+
+    /* Set up the safe bag */
+    if (bag == NULL) {
+        PKCS12err(PKCS12_F_PKCS12_SAFEBAG_CREATE0_PKCS8, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag);
+    bag->value.shkeybag = p8;
+    return bag;
+}
+
+PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid,
+                                                    const char *pass,
+                                                    int passlen,
+                                                    unsigned char *salt,
+                                                    int saltlen, int iter,
+                                                    PKCS8_PRIV_KEY_INFO *p8inf)
+{
+    PKCS12_SAFEBAG *bag;
+    const EVP_CIPHER *pbe_ciph;
+    X509_SIG *p8;
+
+    pbe_ciph = EVP_get_cipherbynid(pbe_nid);
+
+    if (pbe_ciph)
+        pbe_nid = -1;
+
+    p8 = PKCS8_encrypt(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter,
+                       p8inf);
+
+    if (p8 == NULL) {
+        PKCS12err(PKCS12_F_PKCS12_SAFEBAG_CREATE_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    bag = PKCS12_SAFEBAG_create0_pkcs8(p8);
+
+    if (bag == NULL) {
+        PKCS12err(PKCS12_F_PKCS12_SAFEBAG_CREATE_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE);
+        X509_SIG_free(p8);
+        return NULL;
+    }
+
+    return bag;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_utl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_utl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/p12_utl.c	(revision 331)
@@ -0,0 +1,237 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/pkcs12.h>
+
+/* Cheap and nasty Unicode stuff */
+
+unsigned char *OPENSSL_asc2uni(const char *asc, int asclen,
+                               unsigned char **uni, int *unilen)
+{
+    int ulen, i;
+    unsigned char *unitmp;
+
+    if (asclen == -1)
+        asclen = strlen(asc);
+    ulen = asclen * 2 + 2;
+    if ((unitmp = OPENSSL_malloc(ulen)) == NULL)
+        return NULL;
+    for (i = 0; i < ulen - 2; i += 2) {
+        unitmp[i] = 0;
+        unitmp[i + 1] = asc[i >> 1];
+    }
+    /* Make result double null terminated */
+    unitmp[ulen - 2] = 0;
+    unitmp[ulen - 1] = 0;
+    if (unilen)
+        *unilen = ulen;
+    if (uni)
+        *uni = unitmp;
+    return unitmp;
+}
+
+char *OPENSSL_uni2asc(const unsigned char *uni, int unilen)
+{
+    int asclen, i;
+    char *asctmp;
+    /* string must contain an even number of bytes */
+    if (unilen & 1)
+        return NULL;
+    asclen = unilen / 2;
+    /* If no terminating zero allow for one */
+    if (!unilen || uni[unilen - 1])
+        asclen++;
+    uni++;
+    if ((asctmp = OPENSSL_malloc(asclen)) == NULL)
+        return NULL;
+    for (i = 0; i < unilen; i += 2)
+        asctmp[i >> 1] = uni[i];
+    asctmp[asclen - 1] = 0;
+    return asctmp;
+}
+
+/*
+ * OPENSSL_{utf82uni|uni2utf8} perform conversion between UTF-8 and
+ * PKCS#12 BMPString format, which is specified as big-endian UTF-16.
+ * One should keep in mind that even though BMPString is passed as
+ * unsigned char *, it's not the kind of string you can exercise e.g.
+ * strlen on. Caller also has to keep in mind that its length is
+ * expressed not in number of UTF-16 characters, but in number of
+ * bytes the string occupies, and treat it, the length, accordingly.
+ */
+unsigned char *OPENSSL_utf82uni(const char *asc, int asclen,
+                                unsigned char **uni, int *unilen)
+{
+    int ulen, i, j;
+    unsigned char *unitmp, *ret;
+    unsigned long utf32chr = 0;
+
+    if (asclen == -1)
+        asclen = strlen(asc);
+
+    for (ulen = 0, i = 0; i < asclen; i += j) {
+        j = UTF8_getc((const unsigned char *)asc+i, asclen-i, &utf32chr);
+
+        /*
+         * Following condition is somewhat opportunistic is sense that
+         * decoding failure is used as *indirect* indication that input
+         * string might in fact be extended ASCII/ANSI/ISO-8859-X. The
+         * fallback is taken in hope that it would allow to process
+         * files created with previous OpenSSL version, which used the
+         * naive OPENSSL_asc2uni all along. It might be worth noting
+         * that probability of false positive depends on language. In
+         * cases covered by ISO Latin 1 probability is very low, because
+         * any printable non-ASCII alphabet letter followed by another
+         * or any ASCII character will trigger failure and fallback.
+         * In other cases situation can be intensified by the fact that
+         * English letters are not part of alternative keyboard layout,
+         * but even then there should be plenty of pairs that trigger
+         * decoding failure...
+         */
+        if (j < 0)
+	    return OPENSSL_asc2uni(asc, asclen, uni, unilen);
+
+        if (utf32chr > 0x10FFFF)        /* UTF-16 cap */
+	    return NULL;
+
+        if (utf32chr >= 0x10000)        /* pair of UTF-16 characters */
+            ulen += 2*2;
+        else                            /* or just one */
+            ulen += 2;
+    }
+
+    ulen += 2;  /* for trailing UTF16 zero */
+
+    if ((ret = OPENSSL_malloc(ulen)) == NULL)
+        return NULL;
+
+    /* re-run the loop writing down UTF-16 characters in big-endian order */
+    for (unitmp = ret, i = 0; i < asclen; i += j) {
+        j = UTF8_getc((const unsigned char *)asc+i, asclen-i, &utf32chr);
+        if (utf32chr >= 0x10000) {      /* pair if UTF-16 characters */
+            unsigned int hi, lo;
+
+            utf32chr -= 0x10000;
+            hi = 0xD800 + (utf32chr>>10);
+            lo = 0xDC00 + (utf32chr&0x3ff);
+            *unitmp++ = (unsigned char)(hi>>8);
+            *unitmp++ = (unsigned char)(hi);
+            *unitmp++ = (unsigned char)(lo>>8);
+            *unitmp++ = (unsigned char)(lo);
+        } else {                        /* or just one */
+            *unitmp++ = (unsigned char)(utf32chr>>8);
+            *unitmp++ = (unsigned char)(utf32chr);
+        }
+    }
+    /* Make result double null terminated */
+    *unitmp++ = 0;
+    *unitmp++ = 0;
+    if (unilen)
+        *unilen = ulen;
+    if (uni)
+        *uni = ret;
+    return ret;
+}
+
+static int bmp_to_utf8(char *str, const unsigned char *utf16, int len)
+{
+    unsigned long utf32chr;
+
+    if (len == 0) return 0;
+
+    if (len < 2) return -1;
+
+    /* pull UTF-16 character in big-endian order */
+    utf32chr = (utf16[0]<<8) | utf16[1];
+
+    if (utf32chr >= 0xD800 && utf32chr < 0xE000) {   /* two chars */
+        unsigned int lo;
+
+        if (len < 4) return -1;
+
+        utf32chr -= 0xD800;
+        utf32chr <<= 10;
+        lo = (utf16[2]<<8) | utf16[3];
+        if (lo < 0xDC00 || lo >= 0xE000) return -1;
+        utf32chr |= lo-0xDC00;
+        utf32chr += 0x10000;
+    }
+
+    return UTF8_putc((unsigned char *)str, len > 4 ? 4 : len, utf32chr);
+}
+
+char *OPENSSL_uni2utf8(const unsigned char *uni, int unilen)
+{
+    int asclen, i, j;
+    char *asctmp;
+
+    /* string must contain an even number of bytes */
+    if (unilen & 1)
+        return NULL;
+
+    for (asclen = 0, i = 0; i < unilen; ) {
+        j = bmp_to_utf8(NULL, uni+i, unilen-i);
+        /*
+         * falling back to OPENSSL_uni2asc makes lesser sense [than
+         * falling back to OPENSSL_asc2uni in OPENSSL_utf82uni above],
+         * it's done rather to maintain symmetry...
+         */
+        if (j < 0) return OPENSSL_uni2asc(uni, unilen);
+        if (j == 4) i += 4;
+        else        i += 2;
+        asclen += j;
+    }
+
+    /* If no terminating zero allow for one */
+    if (!unilen || (uni[unilen-2]||uni[unilen - 1]))
+        asclen++;
+
+    if ((asctmp = OPENSSL_malloc(asclen)) == NULL)
+        return NULL;
+
+    /* re-run the loop emitting UTF-8 string */
+    for (asclen = 0, i = 0; i < unilen; ) {
+        j = bmp_to_utf8(asctmp+asclen, uni+i, unilen-i);
+        if (j == 4) i += 4;
+        else        i += 2;
+        asclen += j;
+    }
+
+    /* If no terminating zero write one */
+    if (!unilen || (uni[unilen-2]||uni[unilen - 1]))
+        asctmp[asclen] = '\0';
+
+    return asctmp;
+}
+
+int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12)
+{
+    return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS12), bp, p12);
+}
+
+#ifndef OPENSSL_NO_STDIO
+int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12)
+{
+    return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS12), fp, p12);
+}
+#endif
+
+PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12)
+{
+    return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS12), bp, p12);
+}
+
+#ifndef OPENSSL_NO_STDIO
+PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12)
+{
+    return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS12), fp, p12);
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/pk12err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/pk12err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs12/pk12err.c	(revision 331)
@@ -0,0 +1,95 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/pkcs12.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS12,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS12,0,reason)
+
+static ERR_STRING_DATA PKCS12_str_functs[] = {
+    {ERR_FUNC(PKCS12_F_PKCS12_CREATE), "PKCS12_create"},
+    {ERR_FUNC(PKCS12_F_PKCS12_GEN_MAC), "PKCS12_gen_mac"},
+    {ERR_FUNC(PKCS12_F_PKCS12_INIT), "PKCS12_init"},
+    {ERR_FUNC(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I), "PKCS12_item_decrypt_d2i"},
+    {ERR_FUNC(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT), "PKCS12_item_i2d_encrypt"},
+    {ERR_FUNC(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG), "PKCS12_item_pack_safebag"},
+    {ERR_FUNC(PKCS12_F_PKCS12_KEY_GEN_ASC), "PKCS12_key_gen_asc"},
+    {ERR_FUNC(PKCS12_F_PKCS12_KEY_GEN_UNI), "PKCS12_key_gen_uni"},
+    {ERR_FUNC(PKCS12_F_PKCS12_KEY_GEN_UTF8), "PKCS12_key_gen_utf8"},
+    {ERR_FUNC(PKCS12_F_PKCS12_NEWPASS), "PKCS12_newpass"},
+    {ERR_FUNC(PKCS12_F_PKCS12_PACK_P7DATA), "PKCS12_pack_p7data"},
+    {ERR_FUNC(PKCS12_F_PKCS12_PACK_P7ENCDATA), "PKCS12_pack_p7encdata"},
+    {ERR_FUNC(PKCS12_F_PKCS12_PARSE), "PKCS12_parse"},
+    {ERR_FUNC(PKCS12_F_PKCS12_PBE_CRYPT), "PKCS12_pbe_crypt"},
+    {ERR_FUNC(PKCS12_F_PKCS12_PBE_KEYIVGEN), "PKCS12_PBE_keyivgen"},
+    {ERR_FUNC(PKCS12_F_PKCS12_SAFEBAG_CREATE0_P8INF),
+     "PKCS12_SAFEBAG_create0_p8inf"},
+    {ERR_FUNC(PKCS12_F_PKCS12_SAFEBAG_CREATE0_PKCS8),
+     "PKCS12_SAFEBAG_create0_pkcs8"},
+    {ERR_FUNC(PKCS12_F_PKCS12_SAFEBAG_CREATE_PKCS8_ENCRYPT),
+     "PKCS12_SAFEBAG_create_pkcs8_encrypt"},
+    {ERR_FUNC(PKCS12_F_PKCS12_SETUP_MAC), "PKCS12_setup_mac"},
+    {ERR_FUNC(PKCS12_F_PKCS12_SET_MAC), "PKCS12_set_mac"},
+    {ERR_FUNC(PKCS12_F_PKCS12_UNPACK_AUTHSAFES), "PKCS12_unpack_authsafes"},
+    {ERR_FUNC(PKCS12_F_PKCS12_UNPACK_P7DATA), "PKCS12_unpack_p7data"},
+    {ERR_FUNC(PKCS12_F_PKCS12_VERIFY_MAC), "PKCS12_verify_mac"},
+    {ERR_FUNC(PKCS12_F_PKCS8_ENCRYPT), "PKCS8_encrypt"},
+    {ERR_FUNC(PKCS12_F_PKCS8_SET0_PBE), "PKCS8_set0_pbe"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA PKCS12_str_reasons[] = {
+    {ERR_REASON(PKCS12_R_CANT_PACK_STRUCTURE), "cant pack structure"},
+    {ERR_REASON(PKCS12_R_CONTENT_TYPE_NOT_DATA), "content type not data"},
+    {ERR_REASON(PKCS12_R_DECODE_ERROR), "decode error"},
+    {ERR_REASON(PKCS12_R_ENCODE_ERROR), "encode error"},
+    {ERR_REASON(PKCS12_R_ENCRYPT_ERROR), "encrypt error"},
+    {ERR_REASON(PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE),
+     "error setting encrypted data type"},
+    {ERR_REASON(PKCS12_R_INVALID_NULL_ARGUMENT), "invalid null argument"},
+    {ERR_REASON(PKCS12_R_INVALID_NULL_PKCS12_POINTER),
+     "invalid null pkcs12 pointer"},
+    {ERR_REASON(PKCS12_R_IV_GEN_ERROR), "iv gen error"},
+    {ERR_REASON(PKCS12_R_KEY_GEN_ERROR), "key gen error"},
+    {ERR_REASON(PKCS12_R_MAC_ABSENT), "mac absent"},
+    {ERR_REASON(PKCS12_R_MAC_GENERATION_ERROR), "mac generation error"},
+    {ERR_REASON(PKCS12_R_MAC_SETUP_ERROR), "mac setup error"},
+    {ERR_REASON(PKCS12_R_MAC_STRING_SET_ERROR), "mac string set error"},
+    {ERR_REASON(PKCS12_R_MAC_VERIFY_FAILURE), "mac verify failure"},
+    {ERR_REASON(PKCS12_R_PARSE_ERROR), "parse error"},
+    {ERR_REASON(PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR),
+     "pkcs12 algor cipherinit error"},
+    {ERR_REASON(PKCS12_R_PKCS12_CIPHERFINAL_ERROR),
+     "pkcs12 cipherfinal error"},
+    {ERR_REASON(PKCS12_R_PKCS12_PBE_CRYPT_ERROR), "pkcs12 pbe crypt error"},
+    {ERR_REASON(PKCS12_R_UNKNOWN_DIGEST_ALGORITHM),
+     "unknown digest algorithm"},
+    {ERR_REASON(PKCS12_R_UNSUPPORTED_PKCS12_MODE), "unsupported pkcs12 mode"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_PKCS12_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(PKCS12_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, PKCS12_str_functs);
+        ERR_load_strings(0, PKCS12_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/bio_pk7.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/bio_pk7.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/bio_pk7.c	(revision 331)
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2006-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 <openssl/asn1.h>
+#include <openssl/pkcs7.h>
+#include <openssl/bio.h>
+
+#if 0/*!defined(OPENSSL_SYS_VXWORKS)*/
+# include <memory.h>
+#endif
+#include <stdio.h>
+
+/* Streaming encode support for PKCS#7 */
+
+BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7)
+{
+    return BIO_new_NDEF(out, (ASN1_VALUE *)p7, ASN1_ITEM_rptr(PKCS7));
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pk7_asn1.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pk7_asn1.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pk7_asn1.c	(revision 331)
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2000-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pkcs7.h>
+#include <openssl/x509.h>
+
+/* PKCS#7 ASN1 module */
+
+/* This is the ANY DEFINED BY table for the top level PKCS#7 structure */
+
+ASN1_ADB_TEMPLATE(p7default) = ASN1_EXP_OPT(PKCS7, d.other, ASN1_ANY, 0);
+
+ASN1_ADB(PKCS7) = {
+        ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP_OPT(PKCS7, d.data, ASN1_OCTET_STRING_NDEF, 0)),
+        ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP_OPT(PKCS7, d.sign, PKCS7_SIGNED, 0)),
+        ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP_OPT(PKCS7, d.enveloped, PKCS7_ENVELOPE, 0)),
+        ADB_ENTRY(NID_pkcs7_signedAndEnveloped, ASN1_NDEF_EXP_OPT(PKCS7, d.signed_and_enveloped, PKCS7_SIGN_ENVELOPE, 0)),
+        ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP_OPT(PKCS7, d.digest, PKCS7_DIGEST, 0)),
+        ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP_OPT(PKCS7, d.encrypted, PKCS7_ENCRYPT, 0))
+} ASN1_ADB_END(PKCS7, 0, type, 0, &p7default_tt, NULL);
+
+/* PKCS#7 streaming support */
+static int pk7_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                  void *exarg)
+{
+    ASN1_STREAM_ARG *sarg = exarg;
+    PKCS7 **pp7 = (PKCS7 **)pval;
+
+    switch (operation) {
+
+    case ASN1_OP_STREAM_PRE:
+        if (PKCS7_stream(&sarg->boundary, *pp7) <= 0)
+            return 0;
+    case ASN1_OP_DETACHED_PRE:
+        sarg->ndef_bio = PKCS7_dataInit(*pp7, sarg->out);
+        if (!sarg->ndef_bio)
+            return 0;
+        break;
+
+    case ASN1_OP_STREAM_POST:
+    case ASN1_OP_DETACHED_POST:
+        if (PKCS7_dataFinal(*pp7, sarg->ndef_bio) <= 0)
+            return 0;
+        break;
+
+    }
+    return 1;
+}
+
+ASN1_NDEF_SEQUENCE_cb(PKCS7, pk7_cb) = {
+        ASN1_SIMPLE(PKCS7, type, ASN1_OBJECT),
+        ASN1_ADB_OBJECT(PKCS7)
+}ASN1_NDEF_SEQUENCE_END_cb(PKCS7, PKCS7)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7)
+
+IMPLEMENT_ASN1_NDEF_FUNCTION(PKCS7)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(PKCS7)
+
+ASN1_NDEF_SEQUENCE(PKCS7_SIGNED) = {
+        ASN1_SIMPLE(PKCS7_SIGNED, version, ASN1_INTEGER),
+        ASN1_SET_OF(PKCS7_SIGNED, md_algs, X509_ALGOR),
+        ASN1_SIMPLE(PKCS7_SIGNED, contents, PKCS7),
+        ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNED, cert, X509, 0),
+        ASN1_IMP_SET_OF_OPT(PKCS7_SIGNED, crl, X509_CRL, 1),
+        ASN1_SET_OF(PKCS7_SIGNED, signer_info, PKCS7_SIGNER_INFO)
+} ASN1_NDEF_SEQUENCE_END(PKCS7_SIGNED)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNED)
+
+/* Minor tweak to operation: free up EVP_PKEY */
+static int si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                 void *exarg)
+{
+    if (operation == ASN1_OP_FREE_POST) {
+        PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval;
+        EVP_PKEY_free(si->pkey);
+    }
+    return 1;
+}
+
+ASN1_SEQUENCE_cb(PKCS7_SIGNER_INFO, si_cb) = {
+        ASN1_SIMPLE(PKCS7_SIGNER_INFO, version, ASN1_INTEGER),
+        ASN1_SIMPLE(PKCS7_SIGNER_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL),
+        ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_alg, X509_ALGOR),
+        /* NB this should be a SET OF but we use a SEQUENCE OF so the
+         * original order * is retained when the structure is reencoded.
+         * Since the attributes are implicitly tagged this will not affect
+         * the encoding.
+         */
+        ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNER_INFO, auth_attr, X509_ATTRIBUTE, 0),
+        ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_enc_alg, X509_ALGOR),
+        ASN1_SIMPLE(PKCS7_SIGNER_INFO, enc_digest, ASN1_OCTET_STRING),
+        ASN1_IMP_SET_OF_OPT(PKCS7_SIGNER_INFO, unauth_attr, X509_ATTRIBUTE, 1)
+} ASN1_SEQUENCE_END_cb(PKCS7_SIGNER_INFO, PKCS7_SIGNER_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO)
+
+ASN1_SEQUENCE(PKCS7_ISSUER_AND_SERIAL) = {
+        ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, issuer, X509_NAME),
+        ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, serial, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(PKCS7_ISSUER_AND_SERIAL)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
+
+ASN1_NDEF_SEQUENCE(PKCS7_ENVELOPE) = {
+        ASN1_SIMPLE(PKCS7_ENVELOPE, version, ASN1_INTEGER),
+        ASN1_SET_OF(PKCS7_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO),
+        ASN1_SIMPLE(PKCS7_ENVELOPE, enc_data, PKCS7_ENC_CONTENT)
+} ASN1_NDEF_SEQUENCE_END(PKCS7_ENVELOPE)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENVELOPE)
+
+/* Minor tweak to operation: free up X509 */
+static int ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                 void *exarg)
+{
+    if (operation == ASN1_OP_FREE_POST) {
+        PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval;
+        X509_free(ri->cert);
+    }
+    return 1;
+}
+
+ASN1_SEQUENCE_cb(PKCS7_RECIP_INFO, ri_cb) = {
+        ASN1_SIMPLE(PKCS7_RECIP_INFO, version, ASN1_INTEGER),
+        ASN1_SIMPLE(PKCS7_RECIP_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL),
+        ASN1_SIMPLE(PKCS7_RECIP_INFO, key_enc_algor, X509_ALGOR),
+        ASN1_SIMPLE(PKCS7_RECIP_INFO, enc_key, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END_cb(PKCS7_RECIP_INFO, PKCS7_RECIP_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
+
+ASN1_NDEF_SEQUENCE(PKCS7_ENC_CONTENT) = {
+        ASN1_SIMPLE(PKCS7_ENC_CONTENT, content_type, ASN1_OBJECT),
+        ASN1_SIMPLE(PKCS7_ENC_CONTENT, algorithm, X509_ALGOR),
+        ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING_NDEF, 0)
+} ASN1_NDEF_SEQUENCE_END(PKCS7_ENC_CONTENT)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT)
+
+ASN1_NDEF_SEQUENCE(PKCS7_SIGN_ENVELOPE) = {
+        ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, version, ASN1_INTEGER),
+        ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO),
+        ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, md_algs, X509_ALGOR),
+        ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, enc_data, PKCS7_ENC_CONTENT),
+        ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, cert, X509, 0),
+        ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, crl, X509_CRL, 1),
+        ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, signer_info, PKCS7_SIGNER_INFO)
+} ASN1_NDEF_SEQUENCE_END(PKCS7_SIGN_ENVELOPE)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE)
+
+ASN1_NDEF_SEQUENCE(PKCS7_ENCRYPT) = {
+        ASN1_SIMPLE(PKCS7_ENCRYPT, version, ASN1_INTEGER),
+        ASN1_SIMPLE(PKCS7_ENCRYPT, enc_data, PKCS7_ENC_CONTENT)
+} ASN1_NDEF_SEQUENCE_END(PKCS7_ENCRYPT)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENCRYPT)
+
+ASN1_NDEF_SEQUENCE(PKCS7_DIGEST) = {
+        ASN1_SIMPLE(PKCS7_DIGEST, version, ASN1_INTEGER),
+        ASN1_SIMPLE(PKCS7_DIGEST, md, X509_ALGOR),
+        ASN1_SIMPLE(PKCS7_DIGEST, contents, PKCS7),
+        ASN1_SIMPLE(PKCS7_DIGEST, digest, ASN1_OCTET_STRING)
+} ASN1_NDEF_SEQUENCE_END(PKCS7_DIGEST)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKCS7_DIGEST)
+
+/* Specials for authenticated attributes */
+
+/*
+ * When signing attributes we want to reorder them to match the sorted
+ * encoding.
+ */
+
+ASN1_ITEM_TEMPLATE(PKCS7_ATTR_SIGN) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, PKCS7_ATTRIBUTES, X509_ATTRIBUTE)
+ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_SIGN)
+
+/*
+ * When verifying attributes we need to use the received order. So we use
+ * SEQUENCE OF and tag it to SET OF
+ */
+
+ASN1_ITEM_TEMPLATE(PKCS7_ATTR_VERIFY) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
+                                V_ASN1_SET, PKCS7_ATTRIBUTES, X509_ATTRIBUTE)
+ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_VERIFY)
+
+IMPLEMENT_ASN1_PRINT_FUNCTION(PKCS7)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pk7_attr.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pk7_attr.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pk7_attr.c	(revision 331)
@@ -0,0 +1,121 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include <stdlib.h>
+#include <openssl/bio.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/pkcs7.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+
+int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si,
+                              STACK_OF(X509_ALGOR) *cap)
+{
+    ASN1_STRING *seq;
+
+    if ((seq = ASN1_STRING_new()) == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    seq->length = ASN1_item_i2d((ASN1_VALUE *)cap, &seq->data,
+                                ASN1_ITEM_rptr(X509_ALGORS));
+    return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities,
+                                      V_ASN1_SEQUENCE, seq);
+}
+
+STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si)
+{
+    ASN1_TYPE *cap;
+    const unsigned char *p;
+
+    cap = PKCS7_get_signed_attribute(si, NID_SMIMECapabilities);
+    if (cap == NULL || (cap->type != V_ASN1_SEQUENCE))
+        return NULL;
+    p = cap->value.sequence->data;
+    return (STACK_OF(X509_ALGOR) *)
+        ASN1_item_d2i(NULL, &p, cap->value.sequence->length,
+                      ASN1_ITEM_rptr(X509_ALGORS));
+}
+
+/* Basic smime-capabilities OID and optional integer arg */
+int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
+{
+    ASN1_INTEGER *nbit = NULL;
+    X509_ALGOR *alg;
+
+    if ((alg = X509_ALGOR_new()) == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    ASN1_OBJECT_free(alg->algorithm);
+    alg->algorithm = OBJ_nid2obj(nid);
+    if (arg > 0) {
+        if ((alg->parameter = ASN1_TYPE_new()) == NULL) {
+            goto err;
+        }
+        if ((nbit = ASN1_INTEGER_new()) == NULL) {
+            goto err;
+        }
+        if (!ASN1_INTEGER_set(nbit, arg)) {
+            goto err;
+        }
+        alg->parameter->value.integer = nbit;
+        alg->parameter->type = V_ASN1_INTEGER;
+        nbit = NULL;
+    }
+    if (!sk_X509_ALGOR_push(sk, alg)) {
+        goto err;
+    }
+    return 1;
+err:
+    PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE);
+    ASN1_INTEGER_free(nbit);
+    X509_ALGOR_free(alg);
+    return 0;
+}
+
+int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid)
+{
+    if (PKCS7_get_signed_attribute(si, NID_pkcs9_contentType))
+        return 0;
+    if (!coid)
+        coid = OBJ_nid2obj(NID_pkcs7_data);
+    return PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
+                                      V_ASN1_OBJECT, coid);
+}
+
+int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t)
+{
+    if (t == NULL && (t = X509_gmtime_adj(NULL, 0)) == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME,
+                 ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime,
+                                      V_ASN1_UTCTIME, t);
+}
+
+int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
+                             const unsigned char *md, int mdlen)
+{
+    ASN1_OCTET_STRING *os;
+    os = ASN1_OCTET_STRING_new();
+    if (os == NULL)
+        return 0;
+    if (!ASN1_STRING_set(os, md, mdlen)
+        || !PKCS7_add_signed_attribute(si, NID_pkcs9_messageDigest,
+                                       V_ASN1_OCTET_STRING, os)) {
+        ASN1_OCTET_STRING_free(os);
+        return 0;
+    }
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pk7_doit.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pk7_doit.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pk7_doit.c	(revision 331)
@@ -0,0 +1,1178 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+
+static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
+                         void *value);
+static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid);
+
+static int PKCS7_type_is_other(PKCS7 *p7)
+{
+    int isOther = 1;
+
+    int nid = OBJ_obj2nid(p7->type);
+
+    switch (nid) {
+    case NID_pkcs7_data:
+    case NID_pkcs7_signed:
+    case NID_pkcs7_enveloped:
+    case NID_pkcs7_signedAndEnveloped:
+    case NID_pkcs7_digest:
+    case NID_pkcs7_encrypted:
+        isOther = 0;
+        break;
+    default:
+        isOther = 1;
+    }
+
+    return isOther;
+
+}
+
+static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7)
+{
+    if (PKCS7_type_is_data(p7))
+        return p7->d.data;
+    if (PKCS7_type_is_other(p7) && p7->d.other
+        && (p7->d.other->type == V_ASN1_OCTET_STRING))
+        return p7->d.other->value.octet_string;
+    return NULL;
+}
+
+static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg)
+{
+    BIO *btmp;
+    const EVP_MD *md;
+    if ((btmp = BIO_new(BIO_f_md())) == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB);
+        goto err;
+    }
+
+    md = EVP_get_digestbyobj(alg->algorithm);
+    if (md == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, PKCS7_R_UNKNOWN_DIGEST_TYPE);
+        goto err;
+    }
+
+    BIO_set_md(btmp, md);
+    if (*pbio == NULL)
+        *pbio = btmp;
+    else if (!BIO_push(*pbio, btmp)) {
+        PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB);
+        goto err;
+    }
+    btmp = NULL;
+
+    return 1;
+
+ err:
+    BIO_free(btmp);
+    return 0;
+
+}
+
+static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
+                              unsigned char *key, int keylen)
+{
+    EVP_PKEY_CTX *pctx = NULL;
+    EVP_PKEY *pkey = NULL;
+    unsigned char *ek = NULL;
+    int ret = 0;
+    size_t eklen;
+
+    pkey = X509_get0_pubkey(ri->cert);
+
+    if (!pkey)
+        return 0;
+
+    pctx = EVP_PKEY_CTX_new(pkey, NULL);
+    if (!pctx)
+        return 0;
+
+    if (EVP_PKEY_encrypt_init(pctx) <= 0)
+        goto err;
+
+    if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
+                          EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0) {
+        PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR);
+        goto err;
+    }
+
+    if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0)
+        goto err;
+
+    ek = OPENSSL_malloc(eklen);
+
+    if (ek == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0)
+        goto err;
+
+    ASN1_STRING_set0(ri->enc_key, ek, eklen);
+    ek = NULL;
+
+    ret = 1;
+
+ err:
+    EVP_PKEY_CTX_free(pctx);
+    OPENSSL_free(ek);
+    return ret;
+
+}
+
+static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
+                               PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey)
+{
+    EVP_PKEY_CTX *pctx = NULL;
+    unsigned char *ek = NULL;
+    size_t eklen;
+
+    int ret = -1;
+
+    pctx = EVP_PKEY_CTX_new(pkey, NULL);
+    if (!pctx)
+        return -1;
+
+    if (EVP_PKEY_decrypt_init(pctx) <= 0)
+        goto err;
+
+    if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
+                          EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0) {
+        PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR);
+        goto err;
+    }
+
+    if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
+                         ri->enc_key->data, ri->enc_key->length) <= 0)
+        goto err;
+
+    ek = OPENSSL_malloc(eklen);
+
+    if (ek == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (EVP_PKEY_decrypt(pctx, ek, &eklen,
+                         ri->enc_key->data, ri->enc_key->length) <= 0) {
+        ret = 0;
+        PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
+        goto err;
+    }
+
+    ret = 1;
+
+    OPENSSL_clear_free(*pek, *peklen);
+    *pek = ek;
+    *peklen = eklen;
+
+ err:
+    EVP_PKEY_CTX_free(pctx);
+    if (!ret)
+        OPENSSL_free(ek);
+
+    return ret;
+}
+
+BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
+{
+    int i;
+    BIO *out = NULL, *btmp = NULL;
+    X509_ALGOR *xa = NULL;
+    const EVP_CIPHER *evp_cipher = NULL;
+    STACK_OF(X509_ALGOR) *md_sk = NULL;
+    STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
+    X509_ALGOR *xalg = NULL;
+    PKCS7_RECIP_INFO *ri = NULL;
+    ASN1_OCTET_STRING *os = NULL;
+
+    if (p7 == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER);
+        return NULL;
+    }
+    /*
+     * The content field in the PKCS7 ContentInfo is optional, but that really
+     * only applies to inner content (precisely, detached signatures).
+     *
+     * When reading content, missing outer content is therefore treated as an
+     * error.
+     *
+     * When creating content, PKCS7_content_new() must be called before
+     * calling this method, so a NULL p7->d is always an error.
+     */
+    if (p7->d.ptr == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT);
+        return NULL;
+    }
+
+    i = OBJ_obj2nid(p7->type);
+    p7->state = PKCS7_S_HEADER;
+
+    switch (i) {
+    case NID_pkcs7_signed:
+        md_sk = p7->d.sign->md_algs;
+        os = PKCS7_get_octet_string(p7->d.sign->contents);
+        break;
+    case NID_pkcs7_signedAndEnveloped:
+        rsk = p7->d.signed_and_enveloped->recipientinfo;
+        md_sk = p7->d.signed_and_enveloped->md_algs;
+        xalg = p7->d.signed_and_enveloped->enc_data->algorithm;
+        evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher;
+        if (evp_cipher == NULL) {
+            PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED);
+            goto err;
+        }
+        break;
+    case NID_pkcs7_enveloped:
+        rsk = p7->d.enveloped->recipientinfo;
+        xalg = p7->d.enveloped->enc_data->algorithm;
+        evp_cipher = p7->d.enveloped->enc_data->cipher;
+        if (evp_cipher == NULL) {
+            PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED);
+            goto err;
+        }
+        break;
+    case NID_pkcs7_digest:
+        xa = p7->d.digest->md;
+        os = PKCS7_get_octet_string(p7->d.digest->contents);
+        break;
+    case NID_pkcs7_data:
+        break;
+    default:
+        PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+        goto err;
+    }
+
+    for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++)
+        if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i)))
+            goto err;
+
+    if (xa && !PKCS7_bio_add_digest(&out, xa))
+        goto err;
+
+    if (evp_cipher != NULL) {
+        unsigned char key[EVP_MAX_KEY_LENGTH];
+        unsigned char iv[EVP_MAX_IV_LENGTH];
+        int keylen, ivlen;
+        EVP_CIPHER_CTX *ctx;
+
+        if ((btmp = BIO_new(BIO_f_cipher())) == NULL) {
+            PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB);
+            goto err;
+        }
+        BIO_get_cipher_ctx(btmp, &ctx);
+        keylen = EVP_CIPHER_key_length(evp_cipher);
+        ivlen = EVP_CIPHER_iv_length(evp_cipher);
+        xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
+        if (ivlen > 0)
+            if (RAND_bytes(iv, ivlen) <= 0)
+                goto err;
+        if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0)
+            goto err;
+        if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
+            goto err;
+        if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
+            goto err;
+
+        if (ivlen > 0) {
+            if (xalg->parameter == NULL) {
+                xalg->parameter = ASN1_TYPE_new();
+                if (xalg->parameter == NULL)
+                    goto err;
+            }
+            if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
+                goto err;
+        }
+
+        /* Lets do the pub key stuff :-) */
+        for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
+            ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
+            if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
+                goto err;
+        }
+        OPENSSL_cleanse(key, keylen);
+
+        if (out == NULL)
+            out = btmp;
+        else
+            BIO_push(out, btmp);
+        btmp = NULL;
+    }
+
+    if (bio == NULL) {
+        if (PKCS7_is_detached(p7))
+            bio = BIO_new(BIO_s_null());
+        else if (os && os->length > 0)
+            bio = BIO_new_mem_buf(os->data, os->length);
+        if (bio == NULL) {
+            bio = BIO_new(BIO_s_mem());
+            if (bio == NULL)
+                goto err;
+            BIO_set_mem_eof_return(bio, 0);
+        }
+    }
+    if (out)
+        BIO_push(out, bio);
+    else
+        out = bio;
+    return out;
+
+ err:
+    BIO_free_all(out);
+    BIO_free_all(btmp);
+    return NULL;
+}
+
+static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert)
+{
+    int ret;
+    ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
+                        X509_get_issuer_name(pcert));
+    if (ret)
+        return ret;
+    return ASN1_INTEGER_cmp(X509_get_serialNumber(pcert),
+                            ri->issuer_and_serial->serial);
+}
+
+/* int */
+BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
+{
+    int i, j;
+    BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL;
+    X509_ALGOR *xa;
+    ASN1_OCTET_STRING *data_body = NULL;
+    const EVP_MD *evp_md;
+    const EVP_CIPHER *evp_cipher = NULL;
+    EVP_CIPHER_CTX *evp_ctx = NULL;
+    X509_ALGOR *enc_alg = NULL;
+    STACK_OF(X509_ALGOR) *md_sk = NULL;
+    STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
+    PKCS7_RECIP_INFO *ri = NULL;
+    unsigned char *ek = NULL, *tkey = NULL;
+    int eklen = 0, tkeylen = 0;
+
+    if (p7 == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER);
+        return NULL;
+    }
+
+    if (p7->d.ptr == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
+        return NULL;
+    }
+
+    i = OBJ_obj2nid(p7->type);
+    p7->state = PKCS7_S_HEADER;
+
+    switch (i) {
+    case NID_pkcs7_signed:
+        /*
+         * p7->d.sign->contents is a PKCS7 structure consisting of a contentType
+         * field and optional content.
+         * data_body is NULL if that structure has no (=detached) content
+         * or if the contentType is wrong (i.e., not "data").
+         */
+        data_body = PKCS7_get_octet_string(p7->d.sign->contents);
+        if (!PKCS7_is_detached(p7) && data_body == NULL) {
+            PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+                     PKCS7_R_INVALID_SIGNED_DATA_TYPE);
+            goto err;
+        }
+        md_sk = p7->d.sign->md_algs;
+        break;
+    case NID_pkcs7_signedAndEnveloped:
+        rsk = p7->d.signed_and_enveloped->recipientinfo;
+        md_sk = p7->d.signed_and_enveloped->md_algs;
+        /* data_body is NULL if the optional EncryptedContent is missing. */
+        data_body = p7->d.signed_and_enveloped->enc_data->enc_data;
+        enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm;
+        evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
+        if (evp_cipher == NULL) {
+            PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+                     PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
+            goto err;
+        }
+        break;
+    case NID_pkcs7_enveloped:
+        rsk = p7->d.enveloped->recipientinfo;
+        enc_alg = p7->d.enveloped->enc_data->algorithm;
+        /* data_body is NULL if the optional EncryptedContent is missing. */
+        data_body = p7->d.enveloped->enc_data->enc_data;
+        evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
+        if (evp_cipher == NULL) {
+            PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+                     PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
+            goto err;
+        }
+        break;
+    default:
+        PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+        goto err;
+    }
+
+    /* Detached content must be supplied via in_bio instead. */
+    if (data_body == NULL && in_bio == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
+        goto err;
+    }
+
+    /* We will be checking the signature */
+    if (md_sk != NULL) {
+        for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
+            xa = sk_X509_ALGOR_value(md_sk, i);
+            if ((btmp = BIO_new(BIO_f_md())) == NULL) {
+                PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB);
+                goto err;
+            }
+
+            j = OBJ_obj2nid(xa->algorithm);
+            evp_md = EVP_get_digestbynid(j);
+            if (evp_md == NULL) {
+                PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+                         PKCS7_R_UNKNOWN_DIGEST_TYPE);
+                goto err;
+            }
+
+            BIO_set_md(btmp, evp_md);
+            if (out == NULL)
+                out = btmp;
+            else
+                BIO_push(out, btmp);
+            btmp = NULL;
+        }
+    }
+
+    if (evp_cipher != NULL) {
+        if ((etmp = BIO_new(BIO_f_cipher())) == NULL) {
+            PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB);
+            goto err;
+        }
+
+        /*
+         * It was encrypted, we need to decrypt the secret key with the
+         * private key
+         */
+
+        /*
+         * Find the recipientInfo which matches the passed certificate (if
+         * any)
+         */
+
+        if (pcert) {
+            for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
+                ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
+                if (!pkcs7_cmp_ri(ri, pcert))
+                    break;
+                ri = NULL;
+            }
+            if (ri == NULL) {
+                PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+                         PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
+                goto err;
+            }
+        }
+
+        /* If we haven't got a certificate try each ri in turn */
+        if (pcert == NULL) {
+            /*
+             * Always attempt to decrypt all rinfo even after success as a
+             * defence against MMA timing attacks.
+             */
+            for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
+                ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
+
+                if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
+                    goto err;
+                ERR_clear_error();
+            }
+        } else {
+            /* Only exit on fatal errors, not decrypt failure */
+            if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
+                goto err;
+            ERR_clear_error();
+        }
+
+        evp_ctx = NULL;
+        BIO_get_cipher_ctx(etmp, &evp_ctx);
+        if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, NULL, 0) <= 0)
+            goto err;
+        if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0)
+            goto err;
+        /* Generate random key as MMA defence */
+        tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx);
+        tkey = OPENSSL_malloc(tkeylen);
+        if (tkey == NULL)
+            goto err;
+        if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0)
+            goto err;
+        if (ek == NULL) {
+            ek = tkey;
+            eklen = tkeylen;
+            tkey = NULL;
+        }
+
+        if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) {
+            /*
+             * Some S/MIME clients don't use the same key and effective key
+             * length. The key length is determined by the size of the
+             * decrypted RSA key.
+             */
+            if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) {
+                /* Use random key as MMA defence */
+                OPENSSL_clear_free(ek, eklen);
+                ek = tkey;
+                eklen = tkeylen;
+                tkey = NULL;
+            }
+        }
+        /* Clear errors so we don't leak information useful in MMA */
+        ERR_clear_error();
+        if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, ek, NULL, 0) <= 0)
+            goto err;
+
+        OPENSSL_clear_free(ek, eklen);
+        ek = NULL;
+        OPENSSL_clear_free(tkey, tkeylen);
+        tkey = NULL;
+
+        if (out == NULL)
+            out = etmp;
+        else
+            BIO_push(out, etmp);
+        etmp = NULL;
+    }
+    if (in_bio != NULL) {
+        bio = in_bio;
+    } else {
+        if (data_body->length > 0)
+            bio = BIO_new_mem_buf(data_body->data, data_body->length);
+        else {
+            bio = BIO_new(BIO_s_mem());
+            if (bio == NULL)
+                goto err;
+            BIO_set_mem_eof_return(bio, 0);
+        }
+        if (bio == NULL)
+            goto err;
+    }
+    BIO_push(out, bio);
+    bio = NULL;
+    return out;
+
+ err:
+    OPENSSL_clear_free(ek, eklen);
+    OPENSSL_clear_free(tkey, tkeylen);
+    BIO_free_all(out);
+    BIO_free_all(btmp);
+    BIO_free_all(etmp);
+    BIO_free_all(bio);
+    return NULL;
+}
+
+static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid)
+{
+    for (;;) {
+        bio = BIO_find_type(bio, BIO_TYPE_MD);
+        if (bio == NULL) {
+            PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,
+                     PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
+            return NULL;
+        }
+        BIO_get_md_ctx(bio, pmd);
+        if (*pmd == NULL) {
+            PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, ERR_R_INTERNAL_ERROR);
+            return NULL;
+        }
+        if (EVP_MD_CTX_type(*pmd) == nid)
+            return bio;
+        bio = BIO_next(bio);
+    }
+    return NULL;
+}
+
+static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx)
+{
+    unsigned char md_data[EVP_MAX_MD_SIZE];
+    unsigned int md_len;
+
+    /* Add signing time if not already present */
+    if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) {
+        if (!PKCS7_add0_attrib_signing_time(si, NULL)) {
+            PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+    }
+
+    /* Add digest */
+    if (!EVP_DigestFinal_ex(mctx, md_data, &md_len)) {
+        PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_EVP_LIB);
+        return 0;
+    }
+    if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) {
+        PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    /* Now sign the attributes */
+    if (!PKCS7_SIGNER_INFO_sign(si))
+        return 0;
+
+    return 1;
+}
+
+int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
+{
+    int ret = 0;
+    int i, j;
+    BIO *btmp;
+    PKCS7_SIGNER_INFO *si;
+    EVP_MD_CTX *mdc, *ctx_tmp;
+    STACK_OF(X509_ATTRIBUTE) *sk;
+    STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
+    ASN1_OCTET_STRING *os = NULL;
+
+    if (p7 == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER);
+        return 0;
+    }
+
+    if (p7->d.ptr == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT);
+        return 0;
+    }
+
+    ctx_tmp = EVP_MD_CTX_new();
+    if (ctx_tmp == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    i = OBJ_obj2nid(p7->type);
+    p7->state = PKCS7_S_HEADER;
+
+    switch (i) {
+    case NID_pkcs7_data:
+        os = p7->d.data;
+        break;
+    case NID_pkcs7_signedAndEnveloped:
+        /* XXXXXXXXXXXXXXXX */
+        si_sk = p7->d.signed_and_enveloped->signer_info;
+        os = p7->d.signed_and_enveloped->enc_data->enc_data;
+        if (os == NULL) {
+            os = ASN1_OCTET_STRING_new();
+            if (os == NULL) {
+                PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            p7->d.signed_and_enveloped->enc_data->enc_data = os;
+        }
+        break;
+    case NID_pkcs7_enveloped:
+        /* XXXXXXXXXXXXXXXX */
+        os = p7->d.enveloped->enc_data->enc_data;
+        if (os == NULL) {
+            os = ASN1_OCTET_STRING_new();
+            if (os == NULL) {
+                PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            p7->d.enveloped->enc_data->enc_data = os;
+        }
+        break;
+    case NID_pkcs7_signed:
+        si_sk = p7->d.sign->signer_info;
+        os = PKCS7_get_octet_string(p7->d.sign->contents);
+        /* If detached data then the content is excluded */
+        if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
+            ASN1_OCTET_STRING_free(os);
+            os = NULL;
+            p7->d.sign->contents->d.data = NULL;
+        }
+        break;
+
+    case NID_pkcs7_digest:
+        os = PKCS7_get_octet_string(p7->d.digest->contents);
+        /* If detached data then the content is excluded */
+        if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) {
+            ASN1_OCTET_STRING_free(os);
+            os = NULL;
+            p7->d.digest->contents->d.data = NULL;
+        }
+        break;
+
+    default:
+        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+        goto err;
+    }
+
+    if (si_sk != NULL) {
+        for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) {
+            si = sk_PKCS7_SIGNER_INFO_value(si_sk, i);
+            if (si->pkey == NULL)
+                continue;
+
+            j = OBJ_obj2nid(si->digest_alg->algorithm);
+
+            btmp = bio;
+
+            btmp = PKCS7_find_digest(&mdc, btmp, j);
+
+            if (btmp == NULL)
+                goto err;
+
+            /*
+             * We now have the EVP_MD_CTX, lets do the signing.
+             */
+            if (!EVP_MD_CTX_copy_ex(ctx_tmp, mdc))
+                goto err;
+
+            sk = si->auth_attr;
+
+            /*
+             * If there are attributes, we add the digest attribute and only
+             * sign the attributes
+             */
+            if (sk_X509_ATTRIBUTE_num(sk) > 0) {
+                if (!do_pkcs7_signed_attrib(si, ctx_tmp))
+                    goto err;
+            } else {
+                unsigned char *abuf = NULL;
+                unsigned int abuflen;
+                abuflen = EVP_PKEY_size(si->pkey);
+                abuf = OPENSSL_malloc(abuflen);
+                if (abuf == NULL)
+                    goto err;
+
+                if (!EVP_SignFinal(ctx_tmp, abuf, &abuflen, si->pkey)) {
+                    OPENSSL_free(abuf);
+                    PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB);
+                    goto err;
+                }
+                ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
+            }
+        }
+    } else if (i == NID_pkcs7_digest) {
+        unsigned char md_data[EVP_MAX_MD_SIZE];
+        unsigned int md_len;
+        if (!PKCS7_find_digest(&mdc, bio,
+                               OBJ_obj2nid(p7->d.digest->md->algorithm)))
+            goto err;
+        if (!EVP_DigestFinal_ex(mdc, md_data, &md_len))
+            goto err;
+        if (!ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len))
+            goto err;
+    }
+
+    if (!PKCS7_is_detached(p7)) {
+        /*
+         * NOTE(emilia): I think we only reach os == NULL here because detached
+         * digested data support is broken.
+         */
+        if (os == NULL)
+            goto err;
+        if (!(os->flags & ASN1_STRING_FLAG_NDEF)) {
+            char *cont;
+            long contlen;
+            btmp = BIO_find_type(bio, BIO_TYPE_MEM);
+            if (btmp == NULL) {
+                PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
+                goto err;
+            }
+            contlen = BIO_get_mem_data(btmp, &cont);
+            /*
+             * Mark the BIO read only then we can use its copy of the data
+             * instead of making an extra copy.
+             */
+            BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
+            BIO_set_mem_eof_return(btmp, 0);
+            ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
+        }
+    }
+    ret = 1;
+ err:
+    EVP_MD_CTX_free(ctx_tmp);
+    return (ret);
+}
+
+int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
+{
+    EVP_MD_CTX *mctx;
+    EVP_PKEY_CTX *pctx;
+    unsigned char *abuf = NULL;
+    int alen;
+    size_t siglen;
+    const EVP_MD *md = NULL;
+
+    md = EVP_get_digestbyobj(si->digest_alg->algorithm);
+    if (md == NULL)
+        return 0;
+
+    mctx = EVP_MD_CTX_new();
+    if (mctx == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0)
+        goto err;
+
+    if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
+                          EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) {
+        PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
+        goto err;
+    }
+
+    alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf,
+                         ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
+    if (!abuf)
+        goto err;
+    if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0)
+        goto err;
+    OPENSSL_free(abuf);
+    abuf = NULL;
+    if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0)
+        goto err;
+    abuf = OPENSSL_malloc(siglen);
+    if (abuf == NULL)
+        goto err;
+    if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0)
+        goto err;
+
+    if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
+                          EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) {
+        PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
+        goto err;
+    }
+
+    EVP_MD_CTX_free(mctx);
+
+    ASN1_STRING_set0(si->enc_digest, abuf, siglen);
+
+    return 1;
+
+ err:
+    OPENSSL_free(abuf);
+    EVP_MD_CTX_free(mctx);
+    return 0;
+
+}
+
+int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
+                     PKCS7 *p7, PKCS7_SIGNER_INFO *si)
+{
+    PKCS7_ISSUER_AND_SERIAL *ias;
+    int ret = 0, i;
+    STACK_OF(X509) *cert;
+    X509 *x509;
+
+    if (p7 == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_INVALID_NULL_POINTER);
+        return 0;
+    }
+
+    if (p7->d.ptr == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT);
+        return 0;
+    }
+
+    if (PKCS7_type_is_signed(p7)) {
+        cert = p7->d.sign->cert;
+    } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
+        cert = p7->d.signed_and_enveloped->cert;
+    } else {
+        PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_WRONG_PKCS7_TYPE);
+        goto err;
+    }
+    /* XXXXXXXXXXXXXXXXXXXXXXX */
+    ias = si->issuer_and_serial;
+
+    x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial);
+
+    /* were we able to find the cert in passed to us */
+    if (x509 == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,
+                 PKCS7_R_UNABLE_TO_FIND_CERTIFICATE);
+        goto err;
+    }
+
+    /* Lets verify */
+    if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) {
+        PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB);
+        goto err;
+    }
+    X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN);
+    i = X509_verify_cert(ctx);
+    if (i <= 0) {
+        PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB);
+        X509_STORE_CTX_cleanup(ctx);
+        goto err;
+    }
+    X509_STORE_CTX_cleanup(ctx);
+
+    return PKCS7_signatureVerify(bio, p7, si, x509);
+ err:
+    return ret;
+}
+
+int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
+                          X509 *x509)
+{
+    ASN1_OCTET_STRING *os;
+    EVP_MD_CTX *mdc_tmp, *mdc;
+    int ret = 0, i;
+    int md_type;
+    STACK_OF(X509_ATTRIBUTE) *sk;
+    BIO *btmp;
+    EVP_PKEY *pkey;
+
+    mdc_tmp = EVP_MD_CTX_new();
+    if (mdc_tmp == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) {
+        PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_WRONG_PKCS7_TYPE);
+        goto err;
+    }
+
+    md_type = OBJ_obj2nid(si->digest_alg->algorithm);
+
+    btmp = bio;
+    for (;;) {
+        if ((btmp == NULL) ||
+            ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) {
+            PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+                     PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
+            goto err;
+        }
+        BIO_get_md_ctx(btmp, &mdc);
+        if (mdc == NULL) {
+            PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+        if (EVP_MD_CTX_type(mdc) == md_type)
+            break;
+        /*
+         * Workaround for some broken clients that put the signature OID
+         * instead of the digest OID in digest_alg->algorithm
+         */
+        if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type)
+            break;
+        btmp = BIO_next(btmp);
+    }
+
+    /*
+     * mdc is the digest ctx that we want, unless there are attributes, in
+     * which case the digest is the signed attributes
+     */
+    if (!EVP_MD_CTX_copy_ex(mdc_tmp, mdc))
+        goto err;
+
+    sk = si->auth_attr;
+    if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) {
+        unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
+        unsigned int md_len;
+        int alen;
+        ASN1_OCTET_STRING *message_digest;
+
+        if (!EVP_DigestFinal_ex(mdc_tmp, md_dat, &md_len))
+            goto err;
+        message_digest = PKCS7_digest_from_attributes(sk);
+        if (!message_digest) {
+            PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
+                     PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
+            goto err;
+        }
+        if ((message_digest->length != (int)md_len) ||
+            (memcmp(message_digest->data, md_dat, md_len))) {
+            PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_DIGEST_FAILURE);
+            ret = -1;
+            goto err;
+        }
+
+        if (!EVP_VerifyInit_ex(mdc_tmp, EVP_get_digestbynid(md_type), NULL))
+            goto err;
+
+        alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
+                             ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
+        if (alen <= 0) {
+            PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_ASN1_LIB);
+            ret = -1;
+            goto err;
+        }
+        if (!EVP_VerifyUpdate(mdc_tmp, abuf, alen))
+            goto err;
+
+        OPENSSL_free(abuf);
+    }
+
+    os = si->enc_digest;
+    pkey = X509_get0_pubkey(x509);
+    if (!pkey) {
+        ret = -1;
+        goto err;
+    }
+
+    i = EVP_VerifyFinal(mdc_tmp, os->data, os->length, pkey);
+    if (i <= 0) {
+        PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE);
+        ret = -1;
+        goto err;
+    }
+    ret = 1;
+ err:
+    EVP_MD_CTX_free(mdc_tmp);
+    return (ret);
+}
+
+PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
+{
+    STACK_OF(PKCS7_RECIP_INFO) *rsk;
+    PKCS7_RECIP_INFO *ri;
+    int i;
+
+    i = OBJ_obj2nid(p7->type);
+    if (i != NID_pkcs7_signedAndEnveloped)
+        return NULL;
+    if (p7->d.signed_and_enveloped == NULL)
+        return NULL;
+    rsk = p7->d.signed_and_enveloped->recipientinfo;
+    if (rsk == NULL)
+        return NULL;
+    if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx)
+        return (NULL);
+    ri = sk_PKCS7_RECIP_INFO_value(rsk, idx);
+    return (ri->issuer_and_serial);
+}
+
+ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid)
+{
+    return (get_attribute(si->auth_attr, nid));
+}
+
+ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid)
+{
+    return (get_attribute(si->unauth_attr, nid));
+}
+
+static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid)
+{
+    int idx;
+    X509_ATTRIBUTE *xa;
+    idx = X509at_get_attr_by_NID(sk, nid, -1);
+    xa = X509at_get_attr(sk, idx);
+    return X509_ATTRIBUTE_get0_type(xa, 0);
+}
+
+ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk)
+{
+    ASN1_TYPE *astype;
+    if ((astype = get_attribute(sk, NID_pkcs9_messageDigest)) == NULL)
+        return NULL;
+    return astype->value.octet_string;
+}
+
+int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
+                                STACK_OF(X509_ATTRIBUTE) *sk)
+{
+    int i;
+
+    sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr, X509_ATTRIBUTE_free);
+    p7si->auth_attr = sk_X509_ATTRIBUTE_dup(sk);
+    if (p7si->auth_attr == NULL)
+        return 0;
+    for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
+        if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr, i,
+                                   X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value
+                                                      (sk, i))))
+            == NULL)
+            return (0);
+    }
+    return (1);
+}
+
+int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,
+                         STACK_OF(X509_ATTRIBUTE) *sk)
+{
+    int i;
+
+    sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, X509_ATTRIBUTE_free);
+    p7si->unauth_attr = sk_X509_ATTRIBUTE_dup(sk);
+    if (p7si->unauth_attr == NULL)
+        return 0;
+    for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
+        if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr, i,
+                                   X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value
+                                                      (sk, i))))
+            == NULL)
+            return (0);
+    }
+    return (1);
+}
+
+int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
+                               void *value)
+{
+    return (add_attribute(&(p7si->auth_attr), nid, atrtype, value));
+}
+
+int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
+                        void *value)
+{
+    return (add_attribute(&(p7si->unauth_attr), nid, atrtype, value));
+}
+
+static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
+                         void *value)
+{
+    X509_ATTRIBUTE *attr = NULL;
+
+    if (*sk == NULL) {
+        if ((*sk = sk_X509_ATTRIBUTE_new_null()) == NULL)
+            return 0;
+ new_attrib:
+        if ((attr = X509_ATTRIBUTE_create(nid, atrtype, value)) == NULL)
+            return 0;
+        if (!sk_X509_ATTRIBUTE_push(*sk, attr)) {
+            X509_ATTRIBUTE_free(attr);
+            return 0;
+        }
+    } else {
+        int i;
+
+        for (i = 0; i < sk_X509_ATTRIBUTE_num(*sk); i++) {
+            attr = sk_X509_ATTRIBUTE_value(*sk, i);
+            if (OBJ_obj2nid(X509_ATTRIBUTE_get0_object(attr)) == nid) {
+                X509_ATTRIBUTE_free(attr);
+                attr = X509_ATTRIBUTE_create(nid, atrtype, value);
+                if (attr == NULL)
+                    return 0;
+                if (!sk_X509_ATTRIBUTE_set(*sk, i, attr)) {
+                    X509_ATTRIBUTE_free(attr);
+                    return 0;
+                }
+                goto end;
+            }
+        }
+        goto new_attrib;
+    }
+ end:
+    return (1);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pk7_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pk7_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pk7_lib.c	(revision 331)
@@ -0,0 +1,589 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
+
+long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg)
+{
+    int nid;
+    long ret;
+
+    nid = OBJ_obj2nid(p7->type);
+
+    switch (cmd) {
+    /* NOTE(emilia): does not support detached digested data. */
+    case PKCS7_OP_SET_DETACHED_SIGNATURE:
+        if (nid == NID_pkcs7_signed) {
+            ret = p7->detached = (int)larg;
+            if (ret && PKCS7_type_is_data(p7->d.sign->contents)) {
+                ASN1_OCTET_STRING *os;
+                os = p7->d.sign->contents->d.data;
+                ASN1_OCTET_STRING_free(os);
+                p7->d.sign->contents->d.data = NULL;
+            }
+        } else {
+            PKCS7err(PKCS7_F_PKCS7_CTRL,
+                     PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
+            ret = 0;
+        }
+        break;
+    case PKCS7_OP_GET_DETACHED_SIGNATURE:
+        if (nid == NID_pkcs7_signed) {
+            if (!p7->d.sign || !p7->d.sign->contents->d.ptr)
+                ret = 1;
+            else
+                ret = 0;
+
+            p7->detached = ret;
+        } else {
+            PKCS7err(PKCS7_F_PKCS7_CTRL,
+                     PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
+            ret = 0;
+        }
+
+        break;
+    default:
+        PKCS7err(PKCS7_F_PKCS7_CTRL, PKCS7_R_UNKNOWN_OPERATION);
+        ret = 0;
+    }
+    return (ret);
+}
+
+int PKCS7_content_new(PKCS7 *p7, int type)
+{
+    PKCS7 *ret = NULL;
+
+    if ((ret = PKCS7_new()) == NULL)
+        goto err;
+    if (!PKCS7_set_type(ret, type))
+        goto err;
+    if (!PKCS7_set_content(p7, ret))
+        goto err;
+
+    return (1);
+ err:
+    PKCS7_free(ret);
+    return (0);
+}
+
+int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data)
+{
+    int i;
+
+    i = OBJ_obj2nid(p7->type);
+    switch (i) {
+    case NID_pkcs7_signed:
+        PKCS7_free(p7->d.sign->contents);
+        p7->d.sign->contents = p7_data;
+        break;
+    case NID_pkcs7_digest:
+        PKCS7_free(p7->d.digest->contents);
+        p7->d.digest->contents = p7_data;
+        break;
+    case NID_pkcs7_data:
+    case NID_pkcs7_enveloped:
+    case NID_pkcs7_signedAndEnveloped:
+    case NID_pkcs7_encrypted:
+    default:
+        PKCS7err(PKCS7_F_PKCS7_SET_CONTENT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+        goto err;
+    }
+    return (1);
+ err:
+    return (0);
+}
+
+int PKCS7_set_type(PKCS7 *p7, int type)
+{
+    ASN1_OBJECT *obj;
+
+    /*
+     * PKCS7_content_free(p7);
+     */
+    obj = OBJ_nid2obj(type);    /* will not fail */
+
+    switch (type) {
+    case NID_pkcs7_signed:
+        p7->type = obj;
+        if ((p7->d.sign = PKCS7_SIGNED_new()) == NULL)
+            goto err;
+        if (!ASN1_INTEGER_set(p7->d.sign->version, 1)) {
+            PKCS7_SIGNED_free(p7->d.sign);
+            p7->d.sign = NULL;
+            goto err;
+        }
+        break;
+    case NID_pkcs7_data:
+        p7->type = obj;
+        if ((p7->d.data = ASN1_OCTET_STRING_new()) == NULL)
+            goto err;
+        break;
+    case NID_pkcs7_signedAndEnveloped:
+        p7->type = obj;
+        if ((p7->d.signed_and_enveloped = PKCS7_SIGN_ENVELOPE_new())
+            == NULL)
+            goto err;
+        ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1);
+        if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1))
+            goto err;
+        p7->d.signed_and_enveloped->enc_data->content_type
+            = OBJ_nid2obj(NID_pkcs7_data);
+        break;
+    case NID_pkcs7_enveloped:
+        p7->type = obj;
+        if ((p7->d.enveloped = PKCS7_ENVELOPE_new())
+            == NULL)
+            goto err;
+        if (!ASN1_INTEGER_set(p7->d.enveloped->version, 0))
+            goto err;
+        p7->d.enveloped->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data);
+        break;
+    case NID_pkcs7_encrypted:
+        p7->type = obj;
+        if ((p7->d.encrypted = PKCS7_ENCRYPT_new())
+            == NULL)
+            goto err;
+        if (!ASN1_INTEGER_set(p7->d.encrypted->version, 0))
+            goto err;
+        p7->d.encrypted->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data);
+        break;
+
+    case NID_pkcs7_digest:
+        p7->type = obj;
+        if ((p7->d.digest = PKCS7_DIGEST_new())
+            == NULL)
+            goto err;
+        if (!ASN1_INTEGER_set(p7->d.digest->version, 0))
+            goto err;
+        break;
+    default:
+        PKCS7err(PKCS7_F_PKCS7_SET_TYPE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+        goto err;
+    }
+    return (1);
+ err:
+    return (0);
+}
+
+int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other)
+{
+    p7->type = OBJ_nid2obj(type);
+    p7->d.other = other;
+    return 1;
+}
+
+int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
+{
+    int i, j, nid;
+    X509_ALGOR *alg;
+    STACK_OF(PKCS7_SIGNER_INFO) *signer_sk;
+    STACK_OF(X509_ALGOR) *md_sk;
+
+    i = OBJ_obj2nid(p7->type);
+    switch (i) {
+    case NID_pkcs7_signed:
+        signer_sk = p7->d.sign->signer_info;
+        md_sk = p7->d.sign->md_algs;
+        break;
+    case NID_pkcs7_signedAndEnveloped:
+        signer_sk = p7->d.signed_and_enveloped->signer_info;
+        md_sk = p7->d.signed_and_enveloped->md_algs;
+        break;
+    default:
+        PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, PKCS7_R_WRONG_CONTENT_TYPE);
+        return (0);
+    }
+
+    nid = OBJ_obj2nid(psi->digest_alg->algorithm);
+
+    /* If the digest is not currently listed, add it */
+    j = 0;
+    for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
+        alg = sk_X509_ALGOR_value(md_sk, i);
+        if (OBJ_obj2nid(alg->algorithm) == nid) {
+            j = 1;
+            break;
+        }
+    }
+    if (!j) {                   /* we need to add another algorithm */
+        if ((alg = X509_ALGOR_new()) == NULL
+            || (alg->parameter = ASN1_TYPE_new()) == NULL) {
+            X509_ALGOR_free(alg);
+            PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, ERR_R_MALLOC_FAILURE);
+            return (0);
+        }
+        alg->algorithm = OBJ_nid2obj(nid);
+        alg->parameter->type = V_ASN1_NULL;
+        if (!sk_X509_ALGOR_push(md_sk, alg)) {
+            X509_ALGOR_free(alg);
+            return 0;
+        }
+    }
+
+    if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi))
+        return 0;
+    return (1);
+}
+
+int PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
+{
+    int i;
+    STACK_OF(X509) **sk;
+
+    i = OBJ_obj2nid(p7->type);
+    switch (i) {
+    case NID_pkcs7_signed:
+        sk = &(p7->d.sign->cert);
+        break;
+    case NID_pkcs7_signedAndEnveloped:
+        sk = &(p7->d.signed_and_enveloped->cert);
+        break;
+    default:
+        PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, PKCS7_R_WRONG_CONTENT_TYPE);
+        return (0);
+    }
+
+    if (*sk == NULL)
+        *sk = sk_X509_new_null();
+    if (*sk == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    X509_up_ref(x509);
+    if (!sk_X509_push(*sk, x509)) {
+        X509_free(x509);
+        return 0;
+    }
+    return (1);
+}
+
+int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
+{
+    int i;
+    STACK_OF(X509_CRL) **sk;
+
+    i = OBJ_obj2nid(p7->type);
+    switch (i) {
+    case NID_pkcs7_signed:
+        sk = &(p7->d.sign->crl);
+        break;
+    case NID_pkcs7_signedAndEnveloped:
+        sk = &(p7->d.signed_and_enveloped->crl);
+        break;
+    default:
+        PKCS7err(PKCS7_F_PKCS7_ADD_CRL, PKCS7_R_WRONG_CONTENT_TYPE);
+        return (0);
+    }
+
+    if (*sk == NULL)
+        *sk = sk_X509_CRL_new_null();
+    if (*sk == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_ADD_CRL, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    X509_CRL_up_ref(crl);
+    if (!sk_X509_CRL_push(*sk, crl)) {
+        X509_CRL_free(crl);
+        return 0;
+    }
+    return (1);
+}
+
+int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
+                          const EVP_MD *dgst)
+{
+    int ret;
+
+    /* We now need to add another PKCS7_SIGNER_INFO entry */
+    if (!ASN1_INTEGER_set(p7i->version, 1))
+        goto err;
+    if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
+                       X509_get_issuer_name(x509)))
+        goto err;
+
+    /*
+     * because ASN1_INTEGER_set is used to set a 'long' we will do things the
+     * ugly way.
+     */
+    ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
+    if (!(p7i->issuer_and_serial->serial =
+          ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
+        goto err;
+
+    /* lets keep the pkey around for a while */
+    EVP_PKEY_up_ref(pkey);
+    p7i->pkey = pkey;
+
+    /* Set the algorithms */
+
+    X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)),
+                    V_ASN1_NULL, NULL);
+
+    if (pkey->ameth && pkey->ameth->pkey_ctrl) {
+        ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN, 0, p7i);
+        if (ret > 0)
+            return 1;
+        if (ret != -2) {
+            PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
+                     PKCS7_R_SIGNING_CTRL_FAILURE);
+            return 0;
+        }
+    }
+    PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
+             PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+ err:
+    return 0;
+}
+
+PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
+                                       const EVP_MD *dgst)
+{
+    PKCS7_SIGNER_INFO *si = NULL;
+
+    if (dgst == NULL) {
+        int def_nid;
+        if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
+            goto err;
+        dgst = EVP_get_digestbynid(def_nid);
+        if (dgst == NULL) {
+            PKCS7err(PKCS7_F_PKCS7_ADD_SIGNATURE, PKCS7_R_NO_DEFAULT_DIGEST);
+            goto err;
+        }
+    }
+
+    if ((si = PKCS7_SIGNER_INFO_new()) == NULL)
+        goto err;
+    if (!PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst))
+        goto err;
+    if (!PKCS7_add_signer(p7, si))
+        goto err;
+    return (si);
+ err:
+    PKCS7_SIGNER_INFO_free(si);
+    return (NULL);
+}
+
+int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
+{
+    if (PKCS7_type_is_digest(p7)) {
+        if ((p7->d.digest->md->parameter = ASN1_TYPE_new()) == NULL) {
+            PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        p7->d.digest->md->parameter->type = V_ASN1_NULL;
+        p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md));
+        return 1;
+    }
+
+    PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, PKCS7_R_WRONG_CONTENT_TYPE);
+    return 1;
+}
+
+STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
+{
+    if (p7 == NULL || p7->d.ptr == NULL)
+        return NULL;
+    if (PKCS7_type_is_signed(p7)) {
+        return (p7->d.sign->signer_info);
+    } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
+        return (p7->d.signed_and_enveloped->signer_info);
+    } else
+        return (NULL);
+}
+
+void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
+                                 X509_ALGOR **pdig, X509_ALGOR **psig)
+{
+    if (pk)
+        *pk = si->pkey;
+    if (pdig)
+        *pdig = si->digest_alg;
+    if (psig)
+        *psig = si->digest_enc_alg;
+}
+
+void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc)
+{
+    if (penc)
+        *penc = ri->key_enc_algor;
+}
+
+PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
+{
+    PKCS7_RECIP_INFO *ri;
+
+    if ((ri = PKCS7_RECIP_INFO_new()) == NULL)
+        goto err;
+    if (!PKCS7_RECIP_INFO_set(ri, x509))
+        goto err;
+    if (!PKCS7_add_recipient_info(p7, ri))
+        goto err;
+    return ri;
+ err:
+    PKCS7_RECIP_INFO_free(ri);
+    return NULL;
+}
+
+int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
+{
+    int i;
+    STACK_OF(PKCS7_RECIP_INFO) *sk;
+
+    i = OBJ_obj2nid(p7->type);
+    switch (i) {
+    case NID_pkcs7_signedAndEnveloped:
+        sk = p7->d.signed_and_enveloped->recipientinfo;
+        break;
+    case NID_pkcs7_enveloped:
+        sk = p7->d.enveloped->recipientinfo;
+        break;
+    default:
+        PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,
+                 PKCS7_R_WRONG_CONTENT_TYPE);
+        return (0);
+    }
+
+    if (!sk_PKCS7_RECIP_INFO_push(sk, ri))
+        return 0;
+    return (1);
+}
+
+int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
+{
+    int ret;
+    EVP_PKEY *pkey = NULL;
+    if (!ASN1_INTEGER_set(p7i->version, 0))
+        return 0;
+    if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
+                       X509_get_issuer_name(x509)))
+        return 0;
+
+    ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
+    if (!(p7i->issuer_and_serial->serial =
+          ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
+        return 0;
+
+    pkey = X509_get0_pubkey(x509);
+
+    if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl) {
+        PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
+                 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+        goto err;
+    }
+
+    ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT, 0, p7i);
+    if (ret == -2) {
+        PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
+                 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+        goto err;
+    }
+    if (ret <= 0) {
+        PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
+                 PKCS7_R_ENCRYPTION_CTRL_FAILURE);
+        goto err;
+    }
+
+    X509_up_ref(x509);
+    p7i->cert = x509;
+
+    return 1;
+
+ err:
+    return 0;
+}
+
+X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
+{
+    if (PKCS7_type_is_signed(p7))
+        return (X509_find_by_issuer_and_serial(p7->d.sign->cert,
+                                               si->issuer_and_serial->issuer,
+                                               si->
+                                               issuer_and_serial->serial));
+    else
+        return (NULL);
+}
+
+int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
+{
+    int i;
+    PKCS7_ENC_CONTENT *ec;
+
+    i = OBJ_obj2nid(p7->type);
+    switch (i) {
+    case NID_pkcs7_signedAndEnveloped:
+        ec = p7->d.signed_and_enveloped->enc_data;
+        break;
+    case NID_pkcs7_enveloped:
+        ec = p7->d.enveloped->enc_data;
+        break;
+    default:
+        PKCS7err(PKCS7_F_PKCS7_SET_CIPHER, PKCS7_R_WRONG_CONTENT_TYPE);
+        return (0);
+    }
+
+    /* Check cipher OID exists and has data in it */
+    i = EVP_CIPHER_type(cipher);
+    if (i == NID_undef) {
+        PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,
+                 PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
+        return (0);
+    }
+
+    ec->cipher = cipher;
+    return 1;
+}
+
+int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
+{
+    ASN1_OCTET_STRING *os = NULL;
+
+    switch (OBJ_obj2nid(p7->type)) {
+    case NID_pkcs7_data:
+        os = p7->d.data;
+        break;
+
+    case NID_pkcs7_signedAndEnveloped:
+        os = p7->d.signed_and_enveloped->enc_data->enc_data;
+        if (os == NULL) {
+            os = ASN1_OCTET_STRING_new();
+            p7->d.signed_and_enveloped->enc_data->enc_data = os;
+        }
+        break;
+
+    case NID_pkcs7_enveloped:
+        os = p7->d.enveloped->enc_data->enc_data;
+        if (os == NULL) {
+            os = ASN1_OCTET_STRING_new();
+            p7->d.enveloped->enc_data->enc_data = os;
+        }
+        break;
+
+    case NID_pkcs7_signed:
+        os = p7->d.sign->contents->d.data;
+        break;
+
+    default:
+        os = NULL;
+        break;
+    }
+
+    if (os == NULL)
+        return 0;
+
+    os->flags |= ASN1_STRING_FLAG_NDEF;
+    *boundary = &os->data;
+
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pk7_mime.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pk7_mime.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pk7_mime.c	(revision 331)
@@ -0,0 +1,49 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include <ctype.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+
+/* PKCS#7 wrappers round generalised stream and MIME routines */
+
+int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags)
+{
+    return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)p7, in, flags,
+                               ASN1_ITEM_rptr(PKCS7));
+}
+
+int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags)
+{
+    return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *)p7, in, flags,
+                                     "PKCS7", ASN1_ITEM_rptr(PKCS7));
+}
+
+int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
+{
+    STACK_OF(X509_ALGOR) *mdalgs;
+    int ctype_nid = OBJ_obj2nid(p7->type);
+    if (ctype_nid == NID_pkcs7_signed)
+        mdalgs = p7->d.sign->md_algs;
+    else
+        mdalgs = NULL;
+
+    flags ^= SMIME_OLDMIME;
+
+    return SMIME_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags,
+                            ctype_nid, NID_undef, mdalgs,
+                            ASN1_ITEM_rptr(PKCS7));
+}
+
+PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont)
+{
+    return (PKCS7 *)SMIME_read_ASN1(bio, bcont, ASN1_ITEM_rptr(PKCS7));
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pk7_smime.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pk7_smime.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pk7_smime.c	(revision 331)
@@ -0,0 +1,549 @@
+/*
+ * Copyright 1999-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
+ */
+
+/* Simple PKCS#7 processing functions */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+
+#define BUFFERSIZE 4096
+
+static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
+
+PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
+                  BIO *data, int flags)
+{
+    PKCS7 *p7;
+    int i;
+
+    if ((p7 = PKCS7_new()) == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_SIGN, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    if (!PKCS7_set_type(p7, NID_pkcs7_signed))
+        goto err;
+
+    if (!PKCS7_content_new(p7, NID_pkcs7_data))
+        goto err;
+
+    if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags)) {
+        PKCS7err(PKCS7_F_PKCS7_SIGN, PKCS7_R_PKCS7_ADD_SIGNER_ERROR);
+        goto err;
+    }
+
+    if (!(flags & PKCS7_NOCERTS)) {
+        for (i = 0; i < sk_X509_num(certs); i++) {
+            if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i)))
+                goto err;
+        }
+    }
+
+    if (flags & PKCS7_DETACHED)
+        PKCS7_set_detached(p7, 1);
+
+    if (flags & (PKCS7_STREAM | PKCS7_PARTIAL))
+        return p7;
+
+    if (PKCS7_final(p7, data, flags))
+        return p7;
+
+ err:
+    PKCS7_free(p7);
+    return NULL;
+}
+
+int PKCS7_final(PKCS7 *p7, BIO *data, int flags)
+{
+    BIO *p7bio;
+    int ret = 0;
+
+    if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_FINAL, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    SMIME_crlf_copy(data, p7bio, flags);
+
+    (void)BIO_flush(p7bio);
+
+    if (!PKCS7_dataFinal(p7, p7bio)) {
+        PKCS7err(PKCS7_F_PKCS7_FINAL, PKCS7_R_PKCS7_DATASIGN);
+        goto err;
+    }
+
+    ret = 1;
+
+ err:
+    BIO_free_all(p7bio);
+
+    return ret;
+
+}
+
+/* Check to see if a cipher exists and if so add S/MIME capabilities */
+
+static int add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
+{
+    if (EVP_get_cipherbynid(nid))
+        return PKCS7_simple_smimecap(sk, nid, arg);
+    return 1;
+}
+
+static int add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
+{
+    if (EVP_get_digestbynid(nid))
+        return PKCS7_simple_smimecap(sk, nid, arg);
+    return 1;
+}
+
+PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert,
+                                         EVP_PKEY *pkey, const EVP_MD *md,
+                                         int flags)
+{
+    PKCS7_SIGNER_INFO *si = NULL;
+    STACK_OF(X509_ALGOR) *smcap = NULL;
+    if (!X509_check_private_key(signcert, pkey)) {
+        PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
+                 PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+        return NULL;
+    }
+
+    if ((si = PKCS7_add_signature(p7, signcert, pkey, md)) == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
+                 PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR);
+        return NULL;
+    }
+
+    if (!(flags & PKCS7_NOCERTS)) {
+        if (!PKCS7_add_certificate(p7, signcert))
+            goto err;
+    }
+
+    if (!(flags & PKCS7_NOATTR)) {
+        if (!PKCS7_add_attrib_content_type(si, NULL))
+            goto err;
+        /* Add SMIMECapabilities */
+        if (!(flags & PKCS7_NOSMIMECAP)) {
+            if ((smcap = sk_X509_ALGOR_new_null()) == NULL) {
+                PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
+                || !add_digest_smcap(smcap, NID_id_GostR3411_2012_256, -1)
+                || !add_digest_smcap(smcap, NID_id_GostR3411_2012_512, -1)
+                || !add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
+                || !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
+                || !add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
+                || !add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
+                || !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
+                || !add_cipher_smcap(smcap, NID_rc2_cbc, 128)
+                || !add_cipher_smcap(smcap, NID_rc2_cbc, 64)
+                || !add_cipher_smcap(smcap, NID_des_cbc, -1)
+                || !add_cipher_smcap(smcap, NID_rc2_cbc, 40)
+                || !PKCS7_add_attrib_smimecap(si, smcap))
+                goto err;
+            sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
+            smcap = NULL;
+        }
+        if (flags & PKCS7_REUSE_DIGEST) {
+            if (!pkcs7_copy_existing_digest(p7, si))
+                goto err;
+            if (!(flags & PKCS7_PARTIAL) && !PKCS7_SIGNER_INFO_sign(si))
+                goto err;
+        }
+    }
+    return si;
+ err:
+    sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
+    return NULL;
+}
+
+/*
+ * Search for a digest matching SignerInfo digest type and if found copy
+ * across.
+ */
+
+static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
+{
+    int i;
+    STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
+    PKCS7_SIGNER_INFO *sitmp;
+    ASN1_OCTET_STRING *osdig = NULL;
+    sinfos = PKCS7_get_signer_info(p7);
+    for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
+        sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
+        if (si == sitmp)
+            break;
+        if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0)
+            continue;
+        if (!OBJ_cmp(si->digest_alg->algorithm, sitmp->digest_alg->algorithm)) {
+            osdig = PKCS7_digest_from_attributes(sitmp->auth_attr);
+            break;
+        }
+
+    }
+
+    if (osdig)
+        return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length);
+
+    PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST,
+             PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND);
+    return 0;
+}
+
+int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
+                 BIO *indata, BIO *out, int flags)
+{
+    STACK_OF(X509) *signers;
+    X509 *signer;
+    STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
+    PKCS7_SIGNER_INFO *si;
+    X509_STORE_CTX *cert_ctx = NULL;
+    char *buf = NULL;
+    int i, j = 0, k, ret = 0;
+    BIO *p7bio = NULL;
+    BIO *tmpin = NULL, *tmpout = NULL;
+
+    if (!p7) {
+        PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_INVALID_NULL_POINTER);
+        return 0;
+    }
+
+    if (!PKCS7_type_is_signed(p7)) {
+        PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_WRONG_CONTENT_TYPE);
+        return 0;
+    }
+
+    /* Check for no data and no content: no data to verify signature */
+    if (PKCS7_get_detached(p7) && !indata) {
+        PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_CONTENT);
+        return 0;
+    }
+
+    if (flags & PKCS7_NO_DUAL_CONTENT) {
+        /*
+         * This was originally "#if 0" because we thought that only old broken
+         * Netscape did this.  It turns out that Authenticode uses this kind
+         * of "extended" PKCS7 format, and things like UEFI secure boot and
+         * tools like osslsigncode need it.  In Authenticode the verification
+         * process is different, but the existing PKCs7 verification works.
+         */
+        if (!PKCS7_get_detached(p7) && indata) {
+            PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_CONTENT_AND_DATA_PRESENT);
+            return 0;
+        }
+    }
+
+    sinfos = PKCS7_get_signer_info(p7);
+
+    if (!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) {
+        PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_SIGNATURES_ON_DATA);
+        return 0;
+    }
+
+    signers = PKCS7_get0_signers(p7, certs, flags);
+    if (!signers)
+        return 0;
+
+    /* Now verify the certificates */
+
+    cert_ctx = X509_STORE_CTX_new();
+    if (cert_ctx == NULL)
+        goto err;
+    if (!(flags & PKCS7_NOVERIFY))
+        for (k = 0; k < sk_X509_num(signers); k++) {
+            signer = sk_X509_value(signers, k);
+            if (!(flags & PKCS7_NOCHAIN)) {
+                if (!X509_STORE_CTX_init(cert_ctx, store, signer,
+                                         p7->d.sign->cert)) {
+                    PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB);
+                    goto err;
+                }
+                X509_STORE_CTX_set_default(cert_ctx, "smime_sign");
+            } else if (!X509_STORE_CTX_init(cert_ctx, store, signer, NULL)) {
+                PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB);
+                goto err;
+            }
+            if (!(flags & PKCS7_NOCRL))
+                X509_STORE_CTX_set0_crls(cert_ctx, p7->d.sign->crl);
+            i = X509_verify_cert(cert_ctx);
+            if (i <= 0)
+                j = X509_STORE_CTX_get_error(cert_ctx);
+            X509_STORE_CTX_cleanup(cert_ctx);
+            if (i <= 0) {
+                PKCS7err(PKCS7_F_PKCS7_VERIFY,
+                         PKCS7_R_CERTIFICATE_VERIFY_ERROR);
+                ERR_add_error_data(2, "Verify error:",
+                                   X509_verify_cert_error_string(j));
+                goto err;
+            }
+            /* Check for revocation status here */
+        }
+
+    /*
+     * Performance optimization: if the content is a memory BIO then store
+     * its contents in a temporary read only memory BIO. This avoids
+     * potentially large numbers of slow copies of data which will occur when
+     * reading from a read write memory BIO when signatures are calculated.
+     */
+
+    if (indata && (BIO_method_type(indata) == BIO_TYPE_MEM)) {
+        char *ptr;
+        long len;
+        len = BIO_get_mem_data(indata, &ptr);
+        tmpin = BIO_new_mem_buf(ptr, len);
+        if (tmpin == NULL) {
+            PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    } else
+        tmpin = indata;
+
+    if ((p7bio = PKCS7_dataInit(p7, tmpin)) == NULL)
+        goto err;
+
+    if (flags & PKCS7_TEXT) {
+        if ((tmpout = BIO_new(BIO_s_mem())) == NULL) {
+            PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        BIO_set_mem_eof_return(tmpout, 0);
+    } else
+        tmpout = out;
+
+    /* We now have to 'read' from p7bio to calculate digests etc. */
+    if ((buf = OPENSSL_malloc(BUFFERSIZE)) == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    for (;;) {
+        i = BIO_read(p7bio, buf, BUFFERSIZE);
+        if (i <= 0)
+            break;
+        if (tmpout)
+            BIO_write(tmpout, buf, i);
+    }
+
+    if (flags & PKCS7_TEXT) {
+        if (!SMIME_text(tmpout, out)) {
+            PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SMIME_TEXT_ERROR);
+            BIO_free(tmpout);
+            goto err;
+        }
+        BIO_free(tmpout);
+    }
+
+    /* Now Verify All Signatures */
+    if (!(flags & PKCS7_NOSIGS))
+        for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
+            si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
+            signer = sk_X509_value(signers, i);
+            j = PKCS7_signatureVerify(p7bio, p7, si, signer);
+            if (j <= 0) {
+                PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SIGNATURE_FAILURE);
+                goto err;
+            }
+        }
+
+    ret = 1;
+
+ err:
+    X509_STORE_CTX_free(cert_ctx);
+    OPENSSL_free(buf);
+    if (tmpin == indata) {
+        if (indata)
+            BIO_pop(p7bio);
+    }
+    BIO_free_all(p7bio);
+    sk_X509_free(signers);
+    return ret;
+}
+
+STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs,
+                                   int flags)
+{
+    STACK_OF(X509) *signers;
+    STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
+    PKCS7_SIGNER_INFO *si;
+    PKCS7_ISSUER_AND_SERIAL *ias;
+    X509 *signer;
+    int i;
+
+    if (!p7) {
+        PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_INVALID_NULL_POINTER);
+        return NULL;
+    }
+
+    if (!PKCS7_type_is_signed(p7)) {
+        PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_WRONG_CONTENT_TYPE);
+        return NULL;
+    }
+
+    /* Collect all the signers together */
+
+    sinfos = PKCS7_get_signer_info(p7);
+
+    if (sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) {
+        PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_NO_SIGNERS);
+        return 0;
+    }
+
+    if ((signers = sk_X509_new_null()) == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
+        si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
+        ias = si->issuer_and_serial;
+        signer = NULL;
+        /* If any certificates passed they take priority */
+        if (certs)
+            signer = X509_find_by_issuer_and_serial(certs,
+                                                    ias->issuer, ias->serial);
+        if (!signer && !(flags & PKCS7_NOINTERN)
+            && p7->d.sign->cert)
+            signer =
+                X509_find_by_issuer_and_serial(p7->d.sign->cert,
+                                               ias->issuer, ias->serial);
+        if (!signer) {
+            PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,
+                     PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND);
+            sk_X509_free(signers);
+            return 0;
+        }
+
+        if (!sk_X509_push(signers, signer)) {
+            sk_X509_free(signers);
+            return NULL;
+        }
+    }
+    return signers;
+}
+
+/* Build a complete PKCS#7 enveloped data */
+
+PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
+                     int flags)
+{
+    PKCS7 *p7;
+    BIO *p7bio = NULL;
+    int i;
+    X509 *x509;
+    if ((p7 = PKCS7_new()) == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_ENCRYPT, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    if (!PKCS7_set_type(p7, NID_pkcs7_enveloped))
+        goto err;
+    if (!PKCS7_set_cipher(p7, cipher)) {
+        PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_SETTING_CIPHER);
+        goto err;
+    }
+
+    for (i = 0; i < sk_X509_num(certs); i++) {
+        x509 = sk_X509_value(certs, i);
+        if (!PKCS7_add_recipient(p7, x509)) {
+            PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_ADDING_RECIPIENT);
+            goto err;
+        }
+    }
+
+    if (flags & PKCS7_STREAM)
+        return p7;
+
+    if (PKCS7_final(p7, in, flags))
+        return p7;
+
+ err:
+
+    BIO_free_all(p7bio);
+    PKCS7_free(p7);
+    return NULL;
+
+}
+
+int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags)
+{
+    BIO *tmpmem;
+    int ret = 0, i;
+    char *buf = NULL;
+
+    if (!p7) {
+        PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_INVALID_NULL_POINTER);
+        return 0;
+    }
+
+    if (!PKCS7_type_is_enveloped(p7)) {
+        PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_WRONG_CONTENT_TYPE);
+        return 0;
+    }
+
+    if (cert && !X509_check_private_key(cert, pkey)) {
+        PKCS7err(PKCS7_F_PKCS7_DECRYPT,
+                 PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+        return 0;
+    }
+
+    if ((tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert)) == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_DECRYPT_ERROR);
+        return 0;
+    }
+
+    if (flags & PKCS7_TEXT) {
+        BIO *tmpbuf, *bread;
+        /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */
+        if ((tmpbuf = BIO_new(BIO_f_buffer())) == NULL) {
+            PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
+            BIO_free_all(tmpmem);
+            return 0;
+        }
+        if ((bread = BIO_push(tmpbuf, tmpmem)) == NULL) {
+            PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
+            BIO_free_all(tmpbuf);
+            BIO_free_all(tmpmem);
+            return 0;
+        }
+        ret = SMIME_text(bread, data);
+        if (ret > 0 && BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) {
+            if (!BIO_get_cipher_status(tmpmem))
+                ret = 0;
+        }
+        BIO_free_all(bread);
+        return ret;
+    }
+    if ((buf = OPENSSL_malloc(BUFFERSIZE)) == NULL) {
+        PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    for (;;) {
+        i = BIO_read(tmpmem, buf, BUFFERSIZE);
+        if (i <= 0) {
+            ret = 1;
+            if (BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) {
+                if (!BIO_get_cipher_status(tmpmem))
+                    ret = 0;
+            }
+
+            break;
+        }
+        if (BIO_write(data, buf, i) != i) {
+            break;
+        }
+    }
+err:
+    OPENSSL_free(buf);
+    BIO_free_all(tmpmem);
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pkcs7err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pkcs7err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/pkcs7/pkcs7err.c	(revision 331)
@@ -0,0 +1,131 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/pkcs7.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS7,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS7,0,reason)
+
+static ERR_STRING_DATA PKCS7_str_functs[] = {
+    {ERR_FUNC(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB), "do_pkcs7_signed_attrib"},
+    {ERR_FUNC(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME),
+     "PKCS7_add0_attrib_signing_time"},
+    {ERR_FUNC(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP),
+     "PKCS7_add_attrib_smimecap"},
+    {ERR_FUNC(PKCS7_F_PKCS7_ADD_CERTIFICATE), "PKCS7_add_certificate"},
+    {ERR_FUNC(PKCS7_F_PKCS7_ADD_CRL), "PKCS7_add_crl"},
+    {ERR_FUNC(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO), "PKCS7_add_recipient_info"},
+    {ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNATURE), "PKCS7_add_signature"},
+    {ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNER), "PKCS7_add_signer"},
+    {ERR_FUNC(PKCS7_F_PKCS7_BIO_ADD_DIGEST), "PKCS7_bio_add_digest"},
+    {ERR_FUNC(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST),
+     "pkcs7_copy_existing_digest"},
+    {ERR_FUNC(PKCS7_F_PKCS7_CTRL), "PKCS7_ctrl"},
+    {ERR_FUNC(PKCS7_F_PKCS7_DATADECODE), "PKCS7_dataDecode"},
+    {ERR_FUNC(PKCS7_F_PKCS7_DATAFINAL), "PKCS7_dataFinal"},
+    {ERR_FUNC(PKCS7_F_PKCS7_DATAINIT), "PKCS7_dataInit"},
+    {ERR_FUNC(PKCS7_F_PKCS7_DATAVERIFY), "PKCS7_dataVerify"},
+    {ERR_FUNC(PKCS7_F_PKCS7_DECRYPT), "PKCS7_decrypt"},
+    {ERR_FUNC(PKCS7_F_PKCS7_DECRYPT_RINFO), "pkcs7_decrypt_rinfo"},
+    {ERR_FUNC(PKCS7_F_PKCS7_ENCODE_RINFO), "pkcs7_encode_rinfo"},
+    {ERR_FUNC(PKCS7_F_PKCS7_ENCRYPT), "PKCS7_encrypt"},
+    {ERR_FUNC(PKCS7_F_PKCS7_FINAL), "PKCS7_final"},
+    {ERR_FUNC(PKCS7_F_PKCS7_FIND_DIGEST), "PKCS7_find_digest"},
+    {ERR_FUNC(PKCS7_F_PKCS7_GET0_SIGNERS), "PKCS7_get0_signers"},
+    {ERR_FUNC(PKCS7_F_PKCS7_RECIP_INFO_SET), "PKCS7_RECIP_INFO_set"},
+    {ERR_FUNC(PKCS7_F_PKCS7_SET_CIPHER), "PKCS7_set_cipher"},
+    {ERR_FUNC(PKCS7_F_PKCS7_SET_CONTENT), "PKCS7_set_content"},
+    {ERR_FUNC(PKCS7_F_PKCS7_SET_DIGEST), "PKCS7_set_digest"},
+    {ERR_FUNC(PKCS7_F_PKCS7_SET_TYPE), "PKCS7_set_type"},
+    {ERR_FUNC(PKCS7_F_PKCS7_SIGN), "PKCS7_sign"},
+    {ERR_FUNC(PKCS7_F_PKCS7_SIGNATUREVERIFY), "PKCS7_signatureVerify"},
+    {ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SET), "PKCS7_SIGNER_INFO_set"},
+    {ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SIGN), "PKCS7_SIGNER_INFO_sign"},
+    {ERR_FUNC(PKCS7_F_PKCS7_SIGN_ADD_SIGNER), "PKCS7_sign_add_signer"},
+    {ERR_FUNC(PKCS7_F_PKCS7_SIMPLE_SMIMECAP), "PKCS7_simple_smimecap"},
+    {ERR_FUNC(PKCS7_F_PKCS7_VERIFY), "PKCS7_verify"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA PKCS7_str_reasons[] = {
+    {ERR_REASON(PKCS7_R_CERTIFICATE_VERIFY_ERROR),
+     "certificate verify error"},
+    {ERR_REASON(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),
+     "cipher has no object identifier"},
+    {ERR_REASON(PKCS7_R_CIPHER_NOT_INITIALIZED), "cipher not initialized"},
+    {ERR_REASON(PKCS7_R_CONTENT_AND_DATA_PRESENT),
+     "content and data present"},
+    {ERR_REASON(PKCS7_R_CTRL_ERROR), "ctrl error"},
+    {ERR_REASON(PKCS7_R_DECRYPT_ERROR), "decrypt error"},
+    {ERR_REASON(PKCS7_R_DIGEST_FAILURE), "digest failure"},
+    {ERR_REASON(PKCS7_R_ENCRYPTION_CTRL_FAILURE), "encryption ctrl failure"},
+    {ERR_REASON(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),
+     "encryption not supported for this key type"},
+    {ERR_REASON(PKCS7_R_ERROR_ADDING_RECIPIENT), "error adding recipient"},
+    {ERR_REASON(PKCS7_R_ERROR_SETTING_CIPHER), "error setting cipher"},
+    {ERR_REASON(PKCS7_R_INVALID_NULL_POINTER), "invalid null pointer"},
+    {ERR_REASON(PKCS7_R_INVALID_SIGNED_DATA_TYPE),
+     "invalid signed data type"},
+    {ERR_REASON(PKCS7_R_NO_CONTENT), "no content"},
+    {ERR_REASON(PKCS7_R_NO_DEFAULT_DIGEST), "no default digest"},
+    {ERR_REASON(PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND),
+     "no matching digest type found"},
+    {ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE),
+     "no recipient matches certificate"},
+    {ERR_REASON(PKCS7_R_NO_SIGNATURES_ON_DATA), "no signatures on data"},
+    {ERR_REASON(PKCS7_R_NO_SIGNERS), "no signers"},
+    {ERR_REASON(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE),
+     "operation not supported on this type"},
+    {ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR),
+     "pkcs7 add signature error"},
+    {ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNER_ERROR), "pkcs7 add signer error"},
+    {ERR_REASON(PKCS7_R_PKCS7_DATASIGN), "pkcs7 datasign"},
+    {ERR_REASON(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),
+     "private key does not match certificate"},
+    {ERR_REASON(PKCS7_R_SIGNATURE_FAILURE), "signature failure"},
+    {ERR_REASON(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND),
+     "signer certificate not found"},
+    {ERR_REASON(PKCS7_R_SIGNING_CTRL_FAILURE), "signing ctrl failure"},
+    {ERR_REASON(PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),
+     "signing not supported for this key type"},
+    {ERR_REASON(PKCS7_R_SMIME_TEXT_ERROR), "smime text error"},
+    {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE),
+     "unable to find certificate"},
+    {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MEM_BIO), "unable to find mem bio"},
+    {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST),
+     "unable to find message digest"},
+    {ERR_REASON(PKCS7_R_UNKNOWN_DIGEST_TYPE), "unknown digest type"},
+    {ERR_REASON(PKCS7_R_UNKNOWN_OPERATION), "unknown operation"},
+    {ERR_REASON(PKCS7_R_UNSUPPORTED_CIPHER_TYPE), "unsupported cipher type"},
+    {ERR_REASON(PKCS7_R_UNSUPPORTED_CONTENT_TYPE),
+     "unsupported content type"},
+    {ERR_REASON(PKCS7_R_WRONG_CONTENT_TYPE), "wrong content type"},
+    {ERR_REASON(PKCS7_R_WRONG_PKCS7_TYPE), "wrong pkcs7 type"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_PKCS7_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(PKCS7_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, PKCS7_str_functs);
+        ERR_load_strings(0, PKCS7_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/poly1305/poly1305.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/poly1305/poly1305.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/poly1305/poly1305.c	(revision 331)
@@ -0,0 +1,1037 @@
+/*
+ * Copyright 2015-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 <stdlib.h>
+#include <string.h>
+#include <openssl/crypto.h>
+
+#include "internal/poly1305.h"
+
+typedef void (*poly1305_blocks_f) (void *ctx, const unsigned char *inp,
+                                   size_t len, unsigned int padbit);
+typedef void (*poly1305_emit_f) (void *ctx, unsigned char mac[16],
+                                 const unsigned int nonce[4]);
+
+struct poly1305_context {
+    double opaque[24];  /* large enough to hold internal state, declared
+                         * 'double' to ensure at least 64-bit invariant
+                         * alignment across all platforms and
+                         * configurations */
+    unsigned int nonce[4];
+    unsigned char data[POLY1305_BLOCK_SIZE];
+    size_t num;
+    struct {
+        poly1305_blocks_f blocks;
+        poly1305_emit_f emit;
+    } func;
+};
+
+size_t Poly1305_ctx_size ()
+{
+    return sizeof(struct poly1305_context);
+}
+
+/* pick 32-bit unsigned integer in little endian order */
+static unsigned int U8TOU32(const unsigned char *p)
+{
+    return (((unsigned int)(p[0] & 0xff)) |
+            ((unsigned int)(p[1] & 0xff) << 8) |
+            ((unsigned int)(p[2] & 0xff) << 16) |
+            ((unsigned int)(p[3] & 0xff) << 24));
+}
+
+/*
+ * Implementations can be classified by amount of significant bits in
+ * words making up the multi-precision value, or in other words radix
+ * or base of numerical representation, e.g. base 2^64, base 2^32,
+ * base 2^26. Complementary characteristic is how wide is the result of
+ * multiplication of pair of digits, e.g. it would take 128 bits to
+ * accommodate multiplication result in base 2^64 case. These are used
+ * interchangeably. To describe implementation that is. But interface
+ * is designed to isolate this so that low-level primitives implemented
+ * in assembly can be self-contained/self-coherent.
+ */
+#ifndef POLY1305_ASM
+/*
+ * Even though there is __int128 reference implementation targeting
+ * 64-bit platforms provided below, it's not obvious that it's optimal
+ * choice for every one of them. Depending on instruction set overall
+ * amount of instructions can be comparable to one in __int64
+ * implementation. Amount of multiplication instructions would be lower,
+ * but not necessarily overall. And in out-of-order execution context,
+ * it is the latter that can be crucial...
+ *
+ * On related note. Poly1305 author, D. J. Bernstein, discusses and
+ * provides floating-point implementations of the algorithm in question.
+ * It made a lot of sense by the time of introduction, because most
+ * then-modern processors didn't have pipelined integer multiplier.
+ * [Not to mention that some had non-constant timing for integer
+ * multiplications.] Floating-point instructions on the other hand could
+ * be issued every cycle, which allowed to achieve better performance.
+ * Nowadays, with SIMD and/or out-or-order execution, shared or
+ * even emulated FPU, it's more complicated, and floating-point
+ * implementation is not necessarily optimal choice in every situation,
+ * rather contrary...
+ *
+ *                                              <appro@openssl.org>
+ */
+
+typedef unsigned int u32;
+
+/*
+ * poly1305_blocks processes a multiple of POLY1305_BLOCK_SIZE blocks
+ * of |inp| no longer than |len|. Behaviour for |len| not divisible by
+ * block size is unspecified in general case, even though in reference
+ * implementation the trailing chunk is simply ignored. Per algorithm
+ * specification, every input block, complete or last partial, is to be
+ * padded with a bit past most significant byte. The latter kind is then
+ * padded with zeros till block size. This last partial block padding
+ * is caller(*)'s responsibility, and because of this the last partial
+ * block is always processed with separate call with |len| set to
+ * POLY1305_BLOCK_SIZE and |padbit| to 0. In all other cases |padbit|
+ * should be set to 1 to perform implicit padding with 128th bit.
+ * poly1305_blocks does not actually check for this constraint though,
+ * it's caller(*)'s responsibility to comply.
+ *
+ * (*)  In the context "caller" is not application code, but higher
+ *      level Poly1305_* from this very module, so that quirks are
+ *      handled locally.
+ */
+static void
+poly1305_blocks(void *ctx, const unsigned char *inp, size_t len, u32 padbit);
+
+/*
+ * Type-agnostic "rip-off" from constant_time_locl.h
+ */
+# define CONSTANT_TIME_CARRY(a,b) ( \
+         (a ^ ((a ^ b) | ((a - b) ^ b))) >> (sizeof(a) * 8 - 1) \
+         )
+
+# if !defined(PEDANTIC) && \
+     (defined(__SIZEOF_INT128__) && __SIZEOF_INT128__==16) && \
+     (defined(__SIZEOF_LONG__) && __SIZEOF_LONG__==8)
+
+typedef unsigned long u64;
+typedef unsigned __int128 u128;
+
+typedef struct {
+    u64 h[3];
+    u64 r[2];
+} poly1305_internal;
+
+/* pick 32-bit unsigned integer in little endian order */
+static u64 U8TOU64(const unsigned char *p)
+{
+    return (((u64)(p[0] & 0xff)) |
+            ((u64)(p[1] & 0xff) << 8) |
+            ((u64)(p[2] & 0xff) << 16) |
+            ((u64)(p[3] & 0xff) << 24) |
+            ((u64)(p[4] & 0xff) << 32) |
+            ((u64)(p[5] & 0xff) << 40) |
+            ((u64)(p[6] & 0xff) << 48) |
+            ((u64)(p[7] & 0xff) << 56));
+}
+
+/* store a 32-bit unsigned integer in little endian */
+static void U64TO8(unsigned char *p, u64 v)
+{
+    p[0] = (unsigned char)((v) & 0xff);
+    p[1] = (unsigned char)((v >> 8) & 0xff);
+    p[2] = (unsigned char)((v >> 16) & 0xff);
+    p[3] = (unsigned char)((v >> 24) & 0xff);
+    p[4] = (unsigned char)((v >> 32) & 0xff);
+    p[5] = (unsigned char)((v >> 40) & 0xff);
+    p[6] = (unsigned char)((v >> 48) & 0xff);
+    p[7] = (unsigned char)((v >> 56) & 0xff);
+}
+
+static void poly1305_init(void *ctx, const unsigned char key[16])
+{
+    poly1305_internal *st = (poly1305_internal *) ctx;
+
+    /* h = 0 */
+    st->h[0] = 0;
+    st->h[1] = 0;
+    st->h[2] = 0;
+
+    /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
+    st->r[0] = U8TOU64(&key[0]) & 0x0ffffffc0fffffff;
+    st->r[1] = U8TOU64(&key[8]) & 0x0ffffffc0ffffffc;
+}
+
+static void
+poly1305_blocks(void *ctx, const unsigned char *inp, size_t len, u32 padbit)
+{
+    poly1305_internal *st = (poly1305_internal *)ctx;
+    u64 r0, r1;
+    u64 s1;
+    u64 h0, h1, h2, c;
+    u128 d0, d1;
+
+    r0 = st->r[0];
+    r1 = st->r[1];
+
+    s1 = r1 + (r1 >> 2);
+
+    h0 = st->h[0];
+    h1 = st->h[1];
+    h2 = st->h[2];
+
+    while (len >= POLY1305_BLOCK_SIZE) {
+        /* h += m[i] */
+        h0 = (u64)(d0 = (u128)h0 + U8TOU64(inp + 0));
+        h1 = (u64)(d1 = (u128)h1 + (d0 >> 64) + U8TOU64(inp + 8));
+        /*
+         * padbit can be zero only when original len was
+         * POLY1306_BLOCK_SIZE, but we don't check
+         */
+        h2 += (u64)(d1 >> 64) + padbit;
+
+        /* h *= r "%" p, where "%" stands for "partial remainder" */
+        d0 = ((u128)h0 * r0) +
+             ((u128)h1 * s1);
+        d1 = ((u128)h0 * r1) +
+             ((u128)h1 * r0) +
+             (h2 * s1);
+        h2 = (h2 * r0);
+
+        /* last reduction step: */
+        /* a) h2:h0 = h2<<128 + d1<<64 + d0 */
+        h0 = (u64)d0;
+        h1 = (u64)(d1 += d0 >> 64);
+        h2 += (u64)(d1 >> 64);
+        /* b) (h2:h0 += (h2:h0>>130) * 5) %= 2^130 */
+        c = (h2 >> 2) + (h2 & ~3UL);
+        h2 &= 3;
+        h0 += c;
+        h1 += (c = CONSTANT_TIME_CARRY(h0,c));
+        h2 += CONSTANT_TIME_CARRY(h1,c);
+        /*
+         * Occasional overflows to 3rd bit of h2 are taken care of
+         * "naturally". If after this point we end up at the top of
+         * this loop, then the overflow bit will be accounted for
+         * in next iteration. If we end up in poly1305_emit, then
+         * comparison to modulus below will still count as "carry
+         * into 131st bit", so that properly reduced value will be
+         * picked in conditional move.
+         */
+
+        inp += POLY1305_BLOCK_SIZE;
+        len -= POLY1305_BLOCK_SIZE;
+    }
+
+    st->h[0] = h0;
+    st->h[1] = h1;
+    st->h[2] = h2;
+}
+
+static void poly1305_emit(void *ctx, unsigned char mac[16],
+                          const u32 nonce[4])
+{
+    poly1305_internal *st = (poly1305_internal *) ctx;
+    u64 h0, h1, h2;
+    u64 g0, g1, g2;
+    u128 t;
+    u64 mask;
+
+    h0 = st->h[0];
+    h1 = st->h[1];
+    h2 = st->h[2];
+
+    /* compare to modulus by computing h + -p */
+    g0 = (u64)(t = (u128)h0 + 5);
+    g1 = (u64)(t = (u128)h1 + (t >> 64));
+    g2 = h2 + (u64)(t >> 64);
+
+    /* if there was carry into 131st bit, h1:h0 = g1:g0 */
+    mask = 0 - (g2 >> 2);
+    g0 &= mask;
+    g1 &= mask;
+    mask = ~mask;
+    h0 = (h0 & mask) | g0;
+    h1 = (h1 & mask) | g1;
+
+    /* mac = (h + nonce) % (2^128) */
+    h0 = (u64)(t = (u128)h0 + nonce[0] + ((u64)nonce[1]<<32));
+    h1 = (u64)(t = (u128)h1 + nonce[2] + ((u64)nonce[3]<<32) + (t >> 64));
+
+    U64TO8(mac + 0, h0);
+    U64TO8(mac + 8, h1);
+}
+
+# else
+
+#  if defined(_WIN32) && !defined(__MINGW32__)
+typedef unsigned __int64 u64;
+#  elif defined(__arch64__)
+typedef unsigned long u64;
+#  else
+typedef unsigned long long u64;
+#  endif
+
+typedef struct {
+    u32 h[5];
+    u32 r[4];
+} poly1305_internal;
+
+/* store a 32-bit unsigned integer in little endian */
+static void U32TO8(unsigned char *p, unsigned int v)
+{
+    p[0] = (unsigned char)((v) & 0xff);
+    p[1] = (unsigned char)((v >> 8) & 0xff);
+    p[2] = (unsigned char)((v >> 16) & 0xff);
+    p[3] = (unsigned char)((v >> 24) & 0xff);
+}
+
+static void poly1305_init(void *ctx, const unsigned char key[16])
+{
+    poly1305_internal *st = (poly1305_internal *) ctx;
+
+    /* h = 0 */
+    st->h[0] = 0;
+    st->h[1] = 0;
+    st->h[2] = 0;
+    st->h[3] = 0;
+    st->h[4] = 0;
+
+    /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
+    st->r[0] = U8TOU32(&key[0]) & 0x0fffffff;
+    st->r[1] = U8TOU32(&key[4]) & 0x0ffffffc;
+    st->r[2] = U8TOU32(&key[8]) & 0x0ffffffc;
+    st->r[3] = U8TOU32(&key[12]) & 0x0ffffffc;
+}
+
+static void
+poly1305_blocks(void *ctx, const unsigned char *inp, size_t len, u32 padbit)
+{
+    poly1305_internal *st = (poly1305_internal *)ctx;
+    u32 r0, r1, r2, r3;
+    u32 s1, s2, s3;
+    u32 h0, h1, h2, h3, h4, c;
+    u64 d0, d1, d2, d3;
+
+    r0 = st->r[0];
+    r1 = st->r[1];
+    r2 = st->r[2];
+    r3 = st->r[3];
+
+    s1 = r1 + (r1 >> 2);
+    s2 = r2 + (r2 >> 2);
+    s3 = r3 + (r3 >> 2);
+
+    h0 = st->h[0];
+    h1 = st->h[1];
+    h2 = st->h[2];
+    h3 = st->h[3];
+    h4 = st->h[4];
+
+    while (len >= POLY1305_BLOCK_SIZE) {
+        /* h += m[i] */
+        h0 = (u32)(d0 = (u64)h0 + U8TOU32(inp + 0));
+        h1 = (u32)(d1 = (u64)h1 + (d0 >> 32) + U8TOU32(inp + 4));
+        h2 = (u32)(d2 = (u64)h2 + (d1 >> 32) + U8TOU32(inp + 8));
+        h3 = (u32)(d3 = (u64)h3 + (d2 >> 32) + U8TOU32(inp + 12));
+        h4 += (u32)(d3 >> 32) + padbit;
+
+        /* h *= r "%" p, where "%" stands for "partial remainder" */
+        d0 = ((u64)h0 * r0) +
+             ((u64)h1 * s3) +
+             ((u64)h2 * s2) +
+             ((u64)h3 * s1);
+        d1 = ((u64)h0 * r1) +
+             ((u64)h1 * r0) +
+             ((u64)h2 * s3) +
+             ((u64)h3 * s2) +
+             (h4 * s1);
+        d2 = ((u64)h0 * r2) +
+             ((u64)h1 * r1) +
+             ((u64)h2 * r0) +
+             ((u64)h3 * s3) +
+             (h4 * s2);
+        d3 = ((u64)h0 * r3) +
+             ((u64)h1 * r2) +
+             ((u64)h2 * r1) +
+             ((u64)h3 * r0) +
+             (h4 * s3);
+        h4 = (h4 * r0);
+
+        /* last reduction step: */
+        /* a) h4:h0 = h4<<128 + d3<<96 + d2<<64 + d1<<32 + d0 */
+        h0 = (u32)d0;
+        h1 = (u32)(d1 += d0 >> 32);
+        h2 = (u32)(d2 += d1 >> 32);
+        h3 = (u32)(d3 += d2 >> 32);
+        h4 += (u32)(d3 >> 32);
+        /* b) (h4:h0 += (h4:h0>>130) * 5) %= 2^130 */
+        c = (h4 >> 2) + (h4 & ~3U);
+        h4 &= 3;
+        h0 += c;
+        h1 += (c = CONSTANT_TIME_CARRY(h0,c));
+        h2 += (c = CONSTANT_TIME_CARRY(h1,c));
+        h3 += (c = CONSTANT_TIME_CARRY(h2,c));
+        h4 += CONSTANT_TIME_CARRY(h3,c);
+        /*
+         * Occasional overflows to 3rd bit of h4 are taken care of
+         * "naturally". If after this point we end up at the top of
+         * this loop, then the overflow bit will be accounted for
+         * in next iteration. If we end up in poly1305_emit, then
+         * comparison to modulus below will still count as "carry
+         * into 131st bit", so that properly reduced value will be
+         * picked in conditional move.
+         */
+
+        inp += POLY1305_BLOCK_SIZE;
+        len -= POLY1305_BLOCK_SIZE;
+    }
+
+    st->h[0] = h0;
+    st->h[1] = h1;
+    st->h[2] = h2;
+    st->h[3] = h3;
+    st->h[4] = h4;
+}
+
+static void poly1305_emit(void *ctx, unsigned char mac[16],
+                          const u32 nonce[4])
+{
+    poly1305_internal *st = (poly1305_internal *) ctx;
+    u32 h0, h1, h2, h3, h4;
+    u32 g0, g1, g2, g3, g4;
+    u64 t;
+    u32 mask;
+
+    h0 = st->h[0];
+    h1 = st->h[1];
+    h2 = st->h[2];
+    h3 = st->h[3];
+    h4 = st->h[4];
+
+    /* compare to modulus by computing h + -p */
+    g0 = (u32)(t = (u64)h0 + 5);
+    g1 = (u32)(t = (u64)h1 + (t >> 32));
+    g2 = (u32)(t = (u64)h2 + (t >> 32));
+    g3 = (u32)(t = (u64)h3 + (t >> 32));
+    g4 = h4 + (u32)(t >> 32);
+
+    /* if there was carry into 131st bit, h3:h0 = g3:g0 */
+    mask = 0 - (g4 >> 2);
+    g0 &= mask;
+    g1 &= mask;
+    g2 &= mask;
+    g3 &= mask;
+    mask = ~mask;
+    h0 = (h0 & mask) | g0;
+    h1 = (h1 & mask) | g1;
+    h2 = (h2 & mask) | g2;
+    h3 = (h3 & mask) | g3;
+
+    /* mac = (h + nonce) % (2^128) */
+    h0 = (u32)(t = (u64)h0 + nonce[0]);
+    h1 = (u32)(t = (u64)h1 + (t >> 32) + nonce[1]);
+    h2 = (u32)(t = (u64)h2 + (t >> 32) + nonce[2]);
+    h3 = (u32)(t = (u64)h3 + (t >> 32) + nonce[3]);
+
+    U32TO8(mac + 0, h0);
+    U32TO8(mac + 4, h1);
+    U32TO8(mac + 8, h2);
+    U32TO8(mac + 12, h3);
+}
+# endif
+#else
+int poly1305_init(void *ctx, const unsigned char key[16], void *func);
+void poly1305_blocks(void *ctx, const unsigned char *inp, size_t len,
+                     unsigned int padbit);
+void poly1305_emit(void *ctx, unsigned char mac[16],
+                   const unsigned int nonce[4]);
+#endif
+
+void Poly1305_Init(POLY1305 *ctx, const unsigned char key[32])
+{
+    ctx->nonce[0] = U8TOU32(&key[16]);
+    ctx->nonce[1] = U8TOU32(&key[20]);
+    ctx->nonce[2] = U8TOU32(&key[24]);
+    ctx->nonce[3] = U8TOU32(&key[28]);
+
+#ifndef POLY1305_ASM
+    poly1305_init(ctx->opaque, key);
+#else
+    /*
+     * Unlike reference poly1305_init assembly counterpart is expected
+     * to return a value: non-zero if it initializes ctx->func, and zero
+     * otherwise. Latter is to simplify assembly in cases when there no
+     * multiple code paths to switch between.
+     */
+    if (!poly1305_init(ctx->opaque, key, &ctx->func)) {
+        ctx->func.blocks = poly1305_blocks;
+        ctx->func.emit = poly1305_emit;
+    }
+#endif
+
+    ctx->num = 0;
+
+}
+
+#ifdef POLY1305_ASM
+/*
+ * This "eclipses" poly1305_blocks and poly1305_emit, but it's
+ * conscious choice imposed by -Wshadow compiler warnings.
+ */
+# define poly1305_blocks (*poly1305_blocks_p)
+# define poly1305_emit   (*poly1305_emit_p)
+#endif
+
+void Poly1305_Update(POLY1305 *ctx, const unsigned char *inp, size_t len)
+{
+#ifdef POLY1305_ASM
+    /*
+     * As documented, poly1305_blocks is never called with input
+     * longer than single block and padbit argument set to 0. This
+     * property is fluently used in assembly modules to optimize
+     * padbit handling on loop boundary.
+     */
+    poly1305_blocks_f poly1305_blocks_p = ctx->func.blocks;
+#endif
+    size_t rem, num;
+
+    if ((num = ctx->num)) {
+        rem = POLY1305_BLOCK_SIZE - num;
+        if (len >= rem) {
+            memcpy(ctx->data + num, inp, rem);
+            poly1305_blocks(ctx->opaque, ctx->data, POLY1305_BLOCK_SIZE, 1);
+            inp += rem;
+            len -= rem;
+        } else {
+            /* Still not enough data to process a block. */
+            memcpy(ctx->data + num, inp, len);
+            ctx->num = num + len;
+            return;
+        }
+    }
+
+    rem = len % POLY1305_BLOCK_SIZE;
+    len -= rem;
+
+    if (len >= POLY1305_BLOCK_SIZE) {
+        poly1305_blocks(ctx->opaque, inp, len, 1);
+        inp += len;
+    }
+
+    if (rem)
+        memcpy(ctx->data, inp, rem);
+
+    ctx->num = rem;
+}
+
+void Poly1305_Final(POLY1305 *ctx, unsigned char mac[16])
+{
+#ifdef POLY1305_ASM
+    poly1305_blocks_f poly1305_blocks_p = ctx->func.blocks;
+    poly1305_emit_f poly1305_emit_p = ctx->func.emit;
+#endif
+    size_t num;
+
+    if ((num = ctx->num)) {
+        ctx->data[num++] = 1;   /* pad bit */
+        while (num < POLY1305_BLOCK_SIZE)
+            ctx->data[num++] = 0;
+        poly1305_blocks(ctx->opaque, ctx->data, POLY1305_BLOCK_SIZE, 0);
+    }
+
+    poly1305_emit(ctx->opaque, mac, ctx->nonce);
+
+    /* zero out the state */
+    OPENSSL_cleanse(ctx, sizeof(*ctx));
+}
+
+#ifdef SELFTEST
+#include <stdio.h>
+
+struct poly1305_test {
+    const char *inputhex;
+    const char *keyhex;
+    const char *outhex;
+};
+
+static const struct poly1305_test poly1305_tests[] = {
+    /*
+     * RFC7539
+     */
+    {
+     "43727970746f6772617068696320466f72756d2052657365617263682047726f"
+     "7570",
+     "85d6be7857556d337f4452fe42d506a8""0103808afb0db2fd4abff6af4149f51b",
+     "a8061dc1305136c6c22b8baf0c0127a9"
+    },
+    /*
+     * test vectors from "The Poly1305-AES message-authentication code"
+     */
+    {
+     "f3f6",
+     "851fc40c3467ac0be05cc20404f3f700""580b3b0f9447bb1e69d095b5928b6dbc",
+     "f4c633c3044fc145f84f335cb81953de"
+    },
+    {
+     "",
+     "a0f3080000f46400d0c7e9076c834403""dd3fab2251f11ac759f0887129cc2ee7",
+     "dd3fab2251f11ac759f0887129cc2ee7"
+    },
+    {
+     "663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136",
+     "48443d0bb0d21109c89a100b5ce2c208""83149c69b561dd88298a1798b10716ef",
+     "0ee1c16bb73f0f4fd19881753c01cdbe"
+    },
+    {
+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9",
+     "12976a08c4426d0ce8a82407c4f48207""80f8c20aa71202d1e29179cbcb555a57",
+     "5154ad0d2cb26e01274fc51148491f1b"
+    },
+    /*
+     * self-generated vectors exercise "significant" lengths, such that
+     * are handled by different code paths
+     */
+    {
+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af",
+     "12976a08c4426d0ce8a82407c4f48207""80f8c20aa71202d1e29179cbcb555a57",
+     "812059a5da198637cac7c4a631bee466"
+    },
+    {
+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
+     "990c62e48b8018b2c3e4a0fa3134cb67",
+     "12976a08c4426d0ce8a82407c4f48207""80f8c20aa71202d1e29179cbcb555a57",
+     "5b88d7f6228b11e2e28579a5c0c1f761"
+    },
+    {
+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af"
+     "663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136",
+     "12976a08c4426d0ce8a82407c4f48207""80f8c20aa71202d1e29179cbcb555a57",
+     "bbb613b2b6d753ba07395b916aaece15"
+    },
+    {
+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af"
+     "48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef"
+     "663cea190ffb83d89593f3f476b6bc24",
+     "12976a08c4426d0ce8a82407c4f48207""80f8c20aa71202d1e29179cbcb555a57",
+     "c794d7057d1778c4bbee0a39b3d97342"
+    },
+    {
+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af"
+     "48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef"
+     "663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136",
+     "12976a08c4426d0ce8a82407c4f48207""80f8c20aa71202d1e29179cbcb555a57",
+     "ffbcb9b371423152d7fca5ad042fbaa9"
+    },
+    {
+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af"
+     "48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef"
+     "663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136"
+     "812059a5da198637cac7c4a631bee466",
+     "12976a08c4426d0ce8a82407c4f48207""80f8c20aa71202d1e29179cbcb555a57",
+     "069ed6b8ef0f207b3e243bb1019fe632"
+    },
+    {
+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af"
+     "48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef"
+     "663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136"
+     "812059a5da198637cac7c4a631bee4665b88d7f6228b11e2e28579a5c0c1f761",
+     "12976a08c4426d0ce8a82407c4f48207""80f8c20aa71202d1e29179cbcb555a57",
+     "cca339d9a45fa2368c2c68b3a4179133"
+    },
+    {
+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af"
+     "48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef"
+     "663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136"
+     "812059a5da198637cac7c4a631bee4665b88d7f6228b11e2e28579a5c0c1f761"
+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af"
+     "48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef"
+     "663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136",
+     "12976a08c4426d0ce8a82407c4f48207""80f8c20aa71202d1e29179cbcb555a57",
+     "53f6e828a2f0fe0ee815bf0bd5841a34"
+    },
+    {
+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af"
+     "48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef"
+     "663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136"
+     "812059a5da198637cac7c4a631bee4665b88d7f6228b11e2e28579a5c0c1f761"
+     "ab0812724a7f1e342742cbed374d94d136c6b8795d45b3819830f2c04491faf0"
+     "990c62e48b8018b2c3e4a0fa3134cb67fa83e158c994d961c4cb21095c1bf9af"
+     "48443d0bb0d21109c89a100b5ce2c20883149c69b561dd88298a1798b10716ef"
+     "663cea190ffb83d89593f3f476b6bc24d7e679107ea26adb8caf6652d0656136"
+     "812059a5da198637cac7c4a631bee4665b88d7f6228b11e2e28579a5c0c1f761",
+     "12976a08c4426d0ce8a82407c4f48207""80f8c20aa71202d1e29179cbcb555a57",
+     "b846d44e9bbd53cedffbfbb6b7fa4933"
+    },
+    /*
+     * 4th power of the key spills to 131th bit in SIMD key setup
+     */
+    {
+     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+     "ad628107e8351d0f2c231a05dc4a4106""00000000000000000000000000000000",
+     "07145a4c02fe5fa32036de68fabe9066"
+    },
+    {
+    /*
+     * poly1305_ieee754.c failed this in final stage
+     */
+     "842364e156336c0998b933a6237726180d9e3fdcbde4cd5d17080fc3beb49614"
+     "d7122c037463ff104d73f19c12704628d417c4c54a3fe30d3c3d7714382d43b0"
+     "382a50a5dee54be844b076e8df88201a1cd43b90eb21643fa96f39b518aa8340"
+     "c942ff3c31baf7c9bdbf0f31ae3fa096bf8c63030609829fe72e179824890bc8"
+     "e08c315c1cce2a83144dbbff09f74e3efc770b54d0984a8f19b14719e6363564"
+     "1d6b1eedf63efbf080e1783d32445412114c20de0b837a0dfa33d6b82825fff4"
+     "4c9a70ea54ce47f07df698e6b03323b53079364a5fc3e9dd034392bdde86dccd"
+     "da94321c5e44060489336cb65bf3989c36f7282c2f5d2b882c171e74",
+     "95d5c005503e510d8cd0aa072c4a4d06""6eabc52d11653df47fbf63ab198bcc26",
+     "f248312e578d9d58f8b7bb4d19105431"
+    },
+    /*
+     * AVX2 in poly1305-x86.pl failed this with 176+32 split
+     */
+    {
+    "248ac31085b6c2adaaa38259a0d7192c5c35d1bb4ef39ad94c38d1c82479e2dd"
+    "2159a077024b0589bc8a20101b506f0a1ad0bbab76e83a83f1b94be6beae74e8"
+    "74cab692c5963a75436b776121ec9f62399a3e66b2d22707dae81933b6277f3c"
+    "8516bcbe26dbbd86f373103d7cf4cad1888c952118fbfbd0d7b4bedc4ae4936a"
+    "ff91157e7aa47c54442ea78d6ac251d324a0fbe49d89cc3521b66d16e9c66a37"
+    "09894e4eb0a4eedc4ae19468e66b81f2"
+    "71351b1d921ea551047abcc6b87a901fde7db79fa1818c11336dbc07244a40eb",
+    "000102030405060708090a0b0c0d0e0f""00000000000000000000000000000000",
+    "bc939bc5281480fa99c6d68c258ec42f"
+    },
+    /*
+     * test vectors from Google
+     */
+    {
+     "",
+     "c8afaac331ee372cd6082de134943b17""4710130e9f6fea8d72293850a667d86c",
+     "4710130e9f6fea8d72293850a667d86c",
+    },
+    {
+     "48656c6c6f20776f726c6421",
+     "746869732069732033322d6279746520""6b657920666f7220506f6c7931333035",
+     "a6f745008f81c916a20dcc74eef2b2f0"
+    },
+    {
+     "0000000000000000000000000000000000000000000000000000000000000000",
+     "746869732069732033322d6279746520""6b657920666f7220506f6c7931333035",
+     "49ec78090e481ec6c26b33b91ccc0307"
+    },
+    {
+     "89dab80b7717c1db5db437860a3f70218e93e1b8f461fb677f16f35f6f87e2a9"
+     "1c99bc3a47ace47640cc95c345be5ecca5a3523c35cc01893af0b64a62033427"
+     "0372ec12482d1b1e363561698a578b359803495bb4e2ef1930b17a5190b580f1"
+     "41300df30adbeca28f6427a8bc1a999fd51c554a017d095d8c3e3127daf9f595",
+     "2d773be37adb1e4d683bf0075e79c4ee""037918535a7f99ccb7040fb5f5f43aea",
+     "c85d15ed44c378d6b00e23064c7bcd51"
+    },
+    {
+     "000000000000000b1703030200000000"
+     "06db1f1f368d696a810a349c0c714c9a5e7850c2407d721acded95e018d7a852"
+     "66a6e1289cdb4aeb18da5ac8a2b0026d24a59ad485227f3eaedbb2e7e35e1c66"
+     "cd60f9abf716dcc9ac42682dd7dab287a7024c4eefc321cc0574e16793e37cec"
+     "03c5bda42b54c114a80b57af26416c7be742005e20855c73e21dc8e2edc9d435"
+     "cb6f6059280011c270b71570051c1c9b3052126620bc1e2730fa066c7a509d53"
+     "c60e5ae1b40aa6e39e49669228c90eecb4a50db32a50bc49e90b4f4b359a1dfd"
+     "11749cd3867fcf2fb7bb6cd4738f6a4ad6f7ca5058f7618845af9f020f6c3b96"
+     "7b8f4cd4a91e2813b507ae66f2d35c18284f7292186062e10fd5510d18775351"
+     "ef334e7634ab4743f5b68f49adcab384d3fd75f7390f4006ef2a295c8c7a076a"
+     "d54546cd25d2107fbe1436c840924aaebe5b370893cd63d1325b8616fc481088"
+     "6bc152c53221b6df373119393255ee72bcaa880174f1717f9184fa91646f17a2"
+     "4ac55d16bfddca9581a92eda479201f0edbf633600d6066d1ab36d5d2415d713"
+     "51bbcd608a25108d25641992c1f26c531cf9f90203bc4cc19f5927d834b0a471"
+     "16d3884bbb164b8ec883d1ac832e56b3918a98601a08d171881541d594db399c"
+     "6ae6151221745aec814c45b0b05b565436fd6f137aa10a0c0b643761dbd6f9a9"
+     "dcb99b1a6e690854ce0769cde39761d82fcdec15f0d92d7d8e94ade8eb83fbe0",
+     "99e5822dd4173c995e3dae0ddefb9774""3fde3b080134b39f76e9bf8d0e88d546",
+     "2637408fe13086ea73f971e3425e2820"
+    },
+    /*
+     * test vectors from Hanno B旦ck
+     */
+    {
+     "cccccccccccccccccccccccccccccccccccccccccccccccccc80cccccccccccc"
+     "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccecccccc"
+     "ccccccccccccccccccccccccccccccc5cccccccccccccccccccccccccccccccc"
+     "cccccccccce3cccccccccccccccccccccccccccccccccccccccccccccccccccc"
+     "ccccccccaccccccccccccccccccccce6cccccccccc000000afcccccccccccccc"
+     "ccccfffffff50000000000000000000000000000000000000000000000000000"
+     "00ffffffe7000000000000000000000000000000000000000000000000000000"
+     "0000000000000000000000000000000000000000000000000000719205a8521d"
+     "fc",
+     "7f1b0264000000000000000000000000""0000000000000000cccccccccccccccc",
+     "8559b876eceed66eb37798c0457baff9"
+    },
+    {
+     "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0000000000"
+     "00000000800264",
+     "e0001600000000000000000000000000""0000aaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+     "00bd1258978e205444c9aaaa82006fed"
+    },
+    {
+     "02fc",
+     "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c""0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c",
+     "06120c0c0c0c0c0c0c0c0c0c0c0c0c0c"
+    },
+    {
+     "7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b"
+     "7b7b7b7b7b7b7a7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b"
+     "7b7b5c7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b"
+     "7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b6e7b007b7b7b7b7b7b7b7b7b"
+     "7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7a7b7b7b7b7b7b7b7b7b7b7b7b"
+     "7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b5c7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b"
+     "7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b"
+     "7b6e7b001300000000b300000000000000000000000000000000000000000000"
+     "f20000000000000000000000000000000000002000efff000900000000000000"
+     "0000000000100000000009000000640000000000000000000000001300000000"
+     "b300000000000000000000000000000000000000000000f20000000000000000"
+     "000000000000000000002000efff00090000000000000000007a000010000000"
+     "000900000064000000000000000000000000000000000000000000000000fc",
+     "00ff0000000000000000000000000000""00000000001e00000000000000007b7b",
+     "33205bbf9e9f8f7212ab9e2ab9b7e4a5"
+    },
+    {
+     "7777777777777777777777777777777777777777777777777777777777777777"
+     "7777777777777777777777777777777777777777777777777777777777777777"
+     "777777777777777777777777ffffffe9e9acacacacacacacacacacac0000acac"
+     "ec0100acacac2caca2acacacacacacacacacacac64f2",
+     "0000007f0000007f0100002000000000""0000cf77777777777777777777777777",
+     "02ee7c8c546ddeb1a467e4c3981158b9"
+    },
+    /*
+     * test vectors from Andrew Moon
+     */
+    {   /* nacl */
+     "8e993b9f48681273c29650ba32fc76ce48332ea7164d96a4476fb8c531a1186a"
+     "c0dfc17c98dce87b4da7f011ec48c97271d2c20f9b928fe2270d6fb863d51738"
+     "b48eeee314a7cc8ab932164548e526ae90224368517acfeabd6bb3732bc0e9da"
+     "99832b61ca01b6de56244a9e88d5f9b37973f622a43d14a6599b1f654cb45a74"
+     "e355a5",
+     "eea6a7251c1e72916d11c2cb214d3c25""2539121d8e234e652d651fa4c8cff880",
+     "f3ffc7703f9400e52a7dfb4b3d3305d9"
+    },
+    {   /* wrap 2^130-5 */
+     "ffffffffffffffffffffffffffffffff",
+     "02000000000000000000000000000000""00000000000000000000000000000000",
+     "03000000000000000000000000000000"
+    },
+    {   /* wrap 2^128 */
+     "02000000000000000000000000000000",
+     "02000000000000000000000000000000""ffffffffffffffffffffffffffffffff",
+     "03000000000000000000000000000000"
+    },
+    {   /* limb carry */
+     "fffffffffffffffffffffffffffffffff0ffffffffffffffffffffffffffffff"
+     "11000000000000000000000000000000",
+     "01000000000000000000000000000000""00000000000000000000000000000000",
+     "05000000000000000000000000000000"
+    },
+    {   /* 2^130-5 */
+     "fffffffffffffffffffffffffffffffffbfefefefefefefefefefefefefefefe"
+     "01010101010101010101010101010101",
+     "01000000000000000000000000000000""00000000000000000000000000000000",
+     "00000000000000000000000000000000"
+    },
+    {   /* 2^130-6 */
+     "fdffffffffffffffffffffffffffffff",
+     "02000000000000000000000000000000""00000000000000000000000000000000",
+     "faffffffffffffffffffffffffffffff"
+    },
+    {   /* 5*H+L reduction intermediate */
+     "e33594d7505e43b900000000000000003394d7505e4379cd0100000000000000"
+     "0000000000000000000000000000000001000000000000000000000000000000",
+     "01000000000000000400000000000000""00000000000000000000000000000000",
+     "14000000000000005500000000000000"
+    },
+    {   /* 5*H+L reduction final */
+     "e33594d7505e43b900000000000000003394d7505e4379cd0100000000000000"
+     "00000000000000000000000000000000",
+     "01000000000000000400000000000000""00000000000000000000000000000000",
+     "13000000000000000000000000000000"
+    }
+};
+
+static unsigned char hex_digit(char h)
+{
+    int i = OPENSSL_hexchar2int(h);
+
+    if (i < 0)
+        abort();
+    return i;
+}
+
+static void hex_decode(unsigned char *out, const char *hex)
+{
+    size_t j = 0;
+
+    while (*hex != 0) {
+        unsigned char v = hex_digit(*hex++);
+        v <<= 4;
+        v |= hex_digit(*hex++);
+        out[j++] = v;
+    }
+}
+
+static void hexdump(unsigned char *a, size_t len)
+{
+    size_t i;
+
+    for (i = 0; i < len; i++)
+        printf("%02x", a[i]);
+}
+
+int main()
+{
+    static const unsigned num_tests =
+        sizeof(poly1305_tests) / sizeof(struct poly1305_test);
+    unsigned i;
+    unsigned char key[32], out[16], expected[16];
+    POLY1305 poly1305;
+
+    for (i = 0; i < num_tests; i++) {
+        const struct poly1305_test *test = &poly1305_tests[i];
+        unsigned char *in;
+        size_t inlen = strlen(test->inputhex);
+
+        if (strlen(test->keyhex) != sizeof(key) * 2 ||
+            strlen(test->outhex) != sizeof(out) * 2 || (inlen & 1) == 1)
+            return 1;
+
+        inlen /= 2;
+
+        hex_decode(key, test->keyhex);
+        hex_decode(expected, test->outhex);
+
+        in = malloc(inlen);
+
+        hex_decode(in, test->inputhex);
+
+        Poly1305_Init(&poly1305, key);
+        Poly1305_Update(&poly1305, in, inlen);
+        Poly1305_Final(&poly1305, out);
+
+        if (memcmp(out, expected, sizeof(expected)) != 0) {
+            printf("Poly1305 test #%d failed.\n", i);
+            printf("got:      ");
+            hexdump(out, sizeof(out));
+            printf("\nexpected: ");
+            hexdump(expected, sizeof(expected));
+            printf("\n");
+            return 1;
+        }
+
+        if (inlen > 16) {
+            Poly1305_Init(&poly1305, key);
+            Poly1305_Update(&poly1305, in, 1);
+            Poly1305_Update(&poly1305, in+1, inlen-1);
+            Poly1305_Final(&poly1305, out);
+
+            if (memcmp(out, expected, sizeof(expected)) != 0) {
+                printf("Poly1305 test #%d/1+(N-1) failed.\n", i);
+                printf("got:      ");
+                hexdump(out, sizeof(out));
+                printf("\nexpected: ");
+                hexdump(expected, sizeof(expected));
+                printf("\n");
+                return 1;
+            }
+        }
+
+        if (inlen > 32) {
+            size_t half = inlen / 2;
+
+            Poly1305_Init(&poly1305, key);
+            Poly1305_Update(&poly1305, in, half);
+            Poly1305_Update(&poly1305, in+half, inlen-half);
+            Poly1305_Final(&poly1305, out);
+
+            if (memcmp(out, expected, sizeof(expected)) != 0) {
+                printf("Poly1305 test #%d/2 failed.\n", i);
+                printf("got:      ");
+                hexdump(out, sizeof(out));
+                printf("\nexpected: ");
+                hexdump(expected, sizeof(expected));
+                printf("\n");
+                return 1;
+            }
+
+            for (half = 16; half < inlen; half += 16) {
+                Poly1305_Init(&poly1305, key);
+                Poly1305_Update(&poly1305, in, half);
+                Poly1305_Update(&poly1305, in+half, inlen-half);
+                Poly1305_Final(&poly1305, out);
+
+                if (memcmp(out, expected, sizeof(expected)) != 0) {
+                    printf("Poly1305 test #%d/%d+%d failed.\n",
+                                           i, half, inlen-half);
+                    printf("got:      ");
+                    hexdump(out, sizeof(out));
+                    printf("\nexpected: ");
+                    hexdump(expected, sizeof(expected));
+                    printf("\n");
+                    return 1;
+                }
+            }
+        }
+
+        free(in);
+    }
+
+    printf("PASS\n");
+
+# ifdef OPENSSL_CPUID_OBJ
+    {
+        unsigned char buf[8192];
+        unsigned long long stopwatch;
+        unsigned long long OPENSSL_rdtsc();
+
+        memset (buf,0x55,sizeof(buf));
+        memset (key,0xAA,sizeof(key));
+
+        Poly1305_Init(&poly1305, key);
+
+        for (i=0;i<100000;i++)
+            Poly1305_Update(&poly1305,buf,sizeof(buf));
+
+        stopwatch = OPENSSL_rdtsc();
+        for (i=0;i<10000;i++)
+            Poly1305_Update(&poly1305,buf,sizeof(buf));
+        stopwatch = OPENSSL_rdtsc() - stopwatch;
+
+        printf("%g\n",stopwatch/(double)(i*sizeof(buf)));
+
+        stopwatch = OPENSSL_rdtsc();
+        for (i=0;i<10000;i++) {
+            Poly1305_Init(&poly1305, key);
+            Poly1305_Update(&poly1305,buf,16);
+            Poly1305_Final(&poly1305,buf);
+        }
+        stopwatch = OPENSSL_rdtsc() - stopwatch;
+
+        printf("%g\n",stopwatch/(double)(i));
+    }
+# endif
+    return 0;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ppc_arch.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ppc_arch.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ppc_arch.h	(revision 331)
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2014-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
+ */
+
+#ifndef HEADER_PPC_ARCH_H
+# define HEADER_PPC_ARCH_H
+
+extern unsigned int OPENSSL_ppccap_P;
+
+/*
+ * Flags' usage can appear ambiguous, because they are set rather
+ * to reflect OpenSSL performance preferences than actual processor
+ * capabilities.
+ */
+# define PPC_FPU64       (1<<0)
+# define PPC_ALTIVEC     (1<<1)
+# define PPC_CRYPTO207   (1<<2)
+# define PPC_FPU         (1<<3)
+# define PPC_MADD300     (1<<4)
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/md_rand.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/md_rand.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/md_rand.c	(revision 331)
@@ -0,0 +1,666 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <string.h>
+
+#include "e_os.h"
+
+#if !(defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_DSPBIOS))
+# include <sys/time.h>
+#endif
+#if defined(OPENSSL_SYS_VXWORKS)
+# include <time.h>
+#endif
+
+#include <openssl/opensslconf.h>
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+#include <openssl/async.h>
+#include "rand_lcl.h"
+
+#include <openssl/err.h>
+
+#include <internal/thread_once.h>
+
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+#endif
+
+#ifdef BN_DEBUG
+# define PREDICT
+#endif
+
+/* #define PREDICT      1 */
+
+#define STATE_SIZE      1023
+static size_t state_num = 0, state_index = 0;
+static unsigned char state[STATE_SIZE + MD_DIGEST_LENGTH];
+static unsigned char md[MD_DIGEST_LENGTH];
+static long md_count[2] = { 0, 0 };
+
+static double entropy = 0;
+static int initialized = 0;
+
+static CRYPTO_RWLOCK *rand_lock = NULL;
+static CRYPTO_RWLOCK *rand_tmp_lock = NULL;
+static CRYPTO_ONCE rand_lock_init = CRYPTO_ONCE_STATIC_INIT;
+
+/* May be set only when a thread holds rand_lock (to prevent double locking) */
+static unsigned int crypto_lock_rand = 0;
+/* access to locking_threadid is synchronized by rand_tmp_lock */
+/* valid iff crypto_lock_rand is set */
+static CRYPTO_THREAD_ID locking_threadid;
+
+#ifdef PREDICT
+int rand_predictable = 0;
+#endif
+
+static int rand_hw_seed(EVP_MD_CTX *ctx);
+
+static void rand_cleanup(void);
+static int rand_seed(const void *buf, int num);
+static int rand_add(const void *buf, int num, double add_entropy);
+static int rand_bytes(unsigned char *buf, int num, int pseudo);
+static int rand_nopseudo_bytes(unsigned char *buf, int num);
+#if OPENSSL_API_COMPAT < 0x10100000L
+static int rand_pseudo_bytes(unsigned char *buf, int num);
+#endif
+static int rand_status(void);
+
+static RAND_METHOD rand_meth = {
+    rand_seed,
+    rand_nopseudo_bytes,
+    rand_cleanup,
+    rand_add,
+#if OPENSSL_API_COMPAT < 0x10100000L
+    rand_pseudo_bytes,
+#else
+    NULL,
+#endif
+    rand_status
+};
+
+DEFINE_RUN_ONCE_STATIC(do_rand_lock_init)
+{
+    OPENSSL_init_crypto(0, NULL);
+    rand_lock = CRYPTO_THREAD_lock_new();
+    rand_tmp_lock = CRYPTO_THREAD_lock_new();
+    return rand_lock != NULL && rand_tmp_lock != NULL;
+}
+
+RAND_METHOD *RAND_OpenSSL(void)
+{
+    return (&rand_meth);
+}
+
+static void rand_cleanup(void)
+{
+    OPENSSL_cleanse(state, sizeof(state));
+    state_num = 0;
+    state_index = 0;
+    OPENSSL_cleanse(md, MD_DIGEST_LENGTH);
+    md_count[0] = 0;
+    md_count[1] = 0;
+    entropy = 0;
+    initialized = 0;
+    CRYPTO_THREAD_lock_free(rand_lock);
+    CRYPTO_THREAD_lock_free(rand_tmp_lock);
+}
+
+static int rand_add(const void *buf, int num, double add)
+{
+    int i, j, k, st_idx;
+    long md_c[2];
+    unsigned char local_md[MD_DIGEST_LENGTH];
+    EVP_MD_CTX *m;
+    int do_not_lock;
+    int rv = 0;
+
+    if (!num)
+        return 1;
+
+    /*
+     * (Based on the rand(3) manpage)
+     *
+     * The input is chopped up into units of 20 bytes (or less for
+     * the last block).  Each of these blocks is run through the hash
+     * function as follows:  The data passed to the hash function
+     * is the current 'md', the same number of bytes from the 'state'
+     * (the location determined by in incremented looping index) as
+     * the current 'block', the new key data 'block', and 'count'
+     * (which is incremented after each use).
+     * The result of this is kept in 'md' and also xored into the
+     * 'state' at the same locations that were used as input into the
+     * hash function.
+     */
+
+    m = EVP_MD_CTX_new();
+    if (m == NULL)
+        goto err;
+
+    if (!RUN_ONCE(&rand_lock_init, do_rand_lock_init))
+        goto err;
+
+    /* check if we already have the lock */
+    if (crypto_lock_rand) {
+        CRYPTO_THREAD_ID cur = CRYPTO_THREAD_get_current_id();
+        CRYPTO_THREAD_read_lock(rand_tmp_lock);
+        do_not_lock = CRYPTO_THREAD_compare_id(locking_threadid, cur);
+        CRYPTO_THREAD_unlock(rand_tmp_lock);
+    } else
+        do_not_lock = 0;
+
+    if (!do_not_lock)
+        CRYPTO_THREAD_write_lock(rand_lock);
+    st_idx = state_index;
+
+    /*
+     * use our own copies of the counters so that even if a concurrent thread
+     * seeds with exactly the same data and uses the same subarray there's
+     * _some_ difference
+     */
+    md_c[0] = md_count[0];
+    md_c[1] = md_count[1];
+
+    memcpy(local_md, md, sizeof md);
+
+    /* state_index <= state_num <= STATE_SIZE */
+    state_index += num;
+    if (state_index >= STATE_SIZE) {
+        state_index %= STATE_SIZE;
+        state_num = STATE_SIZE;
+    } else if (state_num < STATE_SIZE) {
+        if (state_index > state_num)
+            state_num = state_index;
+    }
+    /* state_index <= state_num <= STATE_SIZE */
+
+    /*
+     * state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE] are what we
+     * will use now, but other threads may use them as well
+     */
+
+    md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0);
+
+    if (!do_not_lock)
+        CRYPTO_THREAD_unlock(rand_lock);
+
+    for (i = 0; i < num; i += MD_DIGEST_LENGTH) {
+        j = (num - i);
+        j = (j > MD_DIGEST_LENGTH) ? MD_DIGEST_LENGTH : j;
+
+        if (!MD_Init(m))
+            goto err;
+        if (!MD_Update(m, local_md, MD_DIGEST_LENGTH))
+            goto err;
+        k = (st_idx + j) - STATE_SIZE;
+        if (k > 0) {
+            if (!MD_Update(m, &(state[st_idx]), j - k))
+                goto err;
+            if (!MD_Update(m, &(state[0]), k))
+                goto err;
+        } else if (!MD_Update(m, &(state[st_idx]), j))
+            goto err;
+
+        /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */
+        if (!MD_Update(m, buf, j))
+            goto err;
+        /*
+         * We know that line may cause programs such as purify and valgrind
+         * to complain about use of uninitialized data.  The problem is not,
+         * it's with the caller.  Removing that line will make sure you get
+         * really bad randomness and thereby other problems such as very
+         * insecure keys.
+         */
+
+        if (!MD_Update(m, (unsigned char *)&(md_c[0]), sizeof(md_c)))
+            goto err;
+        if (!MD_Final(m, local_md))
+            goto err;
+        md_c[1]++;
+
+        buf = (const char *)buf + j;
+
+        for (k = 0; k < j; k++) {
+            /*
+             * Parallel threads may interfere with this, but always each byte
+             * of the new state is the XOR of some previous value of its and
+             * local_md (intermediate values may be lost). Alway using locking
+             * could hurt performance more than necessary given that
+             * conflicts occur only when the total seeding is longer than the
+             * random state.
+             */
+            state[st_idx++] ^= local_md[k];
+            if (st_idx >= STATE_SIZE)
+                st_idx = 0;
+        }
+    }
+
+    if (!do_not_lock)
+        CRYPTO_THREAD_write_lock(rand_lock);
+    /*
+     * Don't just copy back local_md into md -- this could mean that other
+     * thread's seeding remains without effect (except for the incremented
+     * counter).  By XORing it we keep at least as much entropy as fits into
+     * md.
+     */
+    for (k = 0; k < (int)sizeof(md); k++) {
+        md[k] ^= local_md[k];
+    }
+    if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */
+        entropy += add;
+    if (!do_not_lock)
+        CRYPTO_THREAD_unlock(rand_lock);
+
+    rv = 1;
+ err:
+    EVP_MD_CTX_free(m);
+    return rv;
+}
+
+static int rand_seed(const void *buf, int num)
+{
+    return rand_add(buf, num, (double)num);
+}
+
+static int rand_bytes(unsigned char *buf, int num, int pseudo)
+{
+    static volatile int stirred_pool = 0;
+    int i, j, k;
+    size_t num_ceil, st_idx, st_num;
+    int ok;
+    long md_c[2];
+    unsigned char local_md[MD_DIGEST_LENGTH];
+    EVP_MD_CTX *m;
+#ifndef GETPID_IS_MEANINGLESS
+    pid_t curr_pid = getpid();
+#endif
+    time_t curr_time = time(NULL);
+    int do_stir_pool = 0;
+/* time value for various platforms */
+#ifdef OPENSSL_SYS_WIN32
+    FILETIME tv;
+# ifdef _WIN32_WCE
+    SYSTEMTIME t;
+    GetSystemTime(&t);
+    SystemTimeToFileTime(&t, &tv);
+# else
+    GetSystemTimeAsFileTime(&tv);
+# endif
+#elif defined(OPENSSL_SYS_VXWORKS)
+    struct timespec tv;
+    clock_gettime(CLOCK_REALTIME, &ts);
+#elif defined(OPENSSL_SYS_DSPBIOS)
+    unsigned long long tv, OPENSSL_rdtsc();
+    tv = OPENSSL_rdtsc();
+#else
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+#endif
+
+#ifdef PREDICT
+    if (rand_predictable) {
+        static unsigned char val = 0;
+
+        for (i = 0; i < num; i++)
+            buf[i] = val++;
+        return (1);
+    }
+#endif
+
+    if (num <= 0)
+        return 1;
+
+    m = EVP_MD_CTX_new();
+    if (m == NULL)
+        goto err_mem;
+
+    /* round upwards to multiple of MD_DIGEST_LENGTH/2 */
+    num_ceil =
+        (1 + (num - 1) / (MD_DIGEST_LENGTH / 2)) * (MD_DIGEST_LENGTH / 2);
+
+    /*
+     * (Based on the rand(3) manpage:)
+     *
+     * For each group of 10 bytes (or less), we do the following:
+     *
+     * Input into the hash function the local 'md' (which is initialized from
+     * the global 'md' before any bytes are generated), the bytes that are to
+     * be overwritten by the random bytes, and bytes from the 'state'
+     * (incrementing looping index). From this digest output (which is kept
+     * in 'md'), the top (up to) 10 bytes are returned to the caller and the
+     * bottom 10 bytes are xored into the 'state'.
+     *
+     * Finally, after we have finished 'num' random bytes for the
+     * caller, 'count' (which is incremented) and the local and global 'md'
+     * are fed into the hash function and the results are kept in the
+     * global 'md'.
+     */
+
+    if (!RUN_ONCE(&rand_lock_init, do_rand_lock_init))
+        goto err_mem;
+
+    CRYPTO_THREAD_write_lock(rand_lock);
+    /*
+     * We could end up in an async engine while holding this lock so ensure
+     * we don't pause and cause a deadlock
+     */
+    ASYNC_block_pause();
+
+    /* prevent rand_bytes() from trying to obtain the lock again */
+    CRYPTO_THREAD_write_lock(rand_tmp_lock);
+    locking_threadid = CRYPTO_THREAD_get_current_id();
+    CRYPTO_THREAD_unlock(rand_tmp_lock);
+    crypto_lock_rand = 1;
+
+    if (!initialized) {
+        RAND_poll();
+        initialized = 1;
+    }
+
+    if (!stirred_pool)
+        do_stir_pool = 1;
+
+    ok = (entropy >= ENTROPY_NEEDED);
+    if (!ok) {
+        /*
+         * If the PRNG state is not yet unpredictable, then seeing the PRNG
+         * output may help attackers to determine the new state; thus we have
+         * to decrease the entropy estimate. Once we've had enough initial
+         * seeding we don't bother to adjust the entropy count, though,
+         * because we're not ambitious to provide *information-theoretic*
+         * randomness. NOTE: This approach fails if the program forks before
+         * we have enough entropy. Entropy should be collected in a separate
+         * input pool and be transferred to the output pool only when the
+         * entropy limit has been reached.
+         */
+        entropy -= num;
+        if (entropy < 0)
+            entropy = 0;
+    }
+
+    if (do_stir_pool) {
+        /*
+         * In the output function only half of 'md' remains secret, so we
+         * better make sure that the required entropy gets 'evenly
+         * distributed' through 'state', our randomness pool. The input
+         * function (rand_add) chains all of 'md', which makes it more
+         * suitable for this purpose.
+         */
+
+        int n = STATE_SIZE;     /* so that the complete pool gets accessed */
+        while (n > 0) {
+#if MD_DIGEST_LENGTH > 20
+# error "Please adjust DUMMY_SEED."
+#endif
+#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */
+            /*
+             * Note that the seed does not matter, it's just that
+             * rand_add expects to have something to hash.
+             */
+            rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
+            n -= MD_DIGEST_LENGTH;
+        }
+        if (ok)
+            stirred_pool = 1;
+    }
+
+    st_idx = state_index;
+    st_num = state_num;
+    md_c[0] = md_count[0];
+    md_c[1] = md_count[1];
+    memcpy(local_md, md, sizeof md);
+
+    state_index += num_ceil;
+    if (state_index > state_num)
+        state_index %= state_num;
+
+    /*
+     * state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num] are now
+     * ours (but other threads may use them too)
+     */
+
+    md_count[0] += 1;
+
+    /* before unlocking, we must clear 'crypto_lock_rand' */
+    crypto_lock_rand = 0;
+    ASYNC_unblock_pause();
+    CRYPTO_THREAD_unlock(rand_lock);
+
+    while (num > 0) {
+        /* num_ceil -= MD_DIGEST_LENGTH/2 */
+        j = (num >= MD_DIGEST_LENGTH / 2) ? MD_DIGEST_LENGTH / 2 : num;
+        num -= j;
+        if (!MD_Init(m))
+            goto err;
+#ifndef GETPID_IS_MEANINGLESS
+        if (curr_pid) {         /* just in the first iteration to save time */
+            if (!MD_Update(m, (unsigned char *)&curr_pid, sizeof curr_pid))
+                goto err;
+            curr_pid = 0;
+        }
+#endif
+        if (curr_time) {        /* just in the first iteration to save time */
+            if (!MD_Update(m, (unsigned char *)&curr_time, sizeof curr_time))
+                goto err;
+            if (!MD_Update(m, (unsigned char *)&tv, sizeof tv))
+                goto err;
+            curr_time = 0;
+            if (!rand_hw_seed(m))
+                goto err;
+        }
+        if (!MD_Update(m, local_md, MD_DIGEST_LENGTH))
+            goto err;
+        if (!MD_Update(m, (unsigned char *)&(md_c[0]), sizeof(md_c)))
+            goto err;
+
+        k = (st_idx + MD_DIGEST_LENGTH / 2) - st_num;
+        if (k > 0) {
+            if (!MD_Update(m, &(state[st_idx]), MD_DIGEST_LENGTH / 2 - k))
+                goto err;
+            if (!MD_Update(m, &(state[0]), k))
+                goto err;
+        } else if (!MD_Update(m, &(state[st_idx]), MD_DIGEST_LENGTH / 2))
+            goto err;
+        if (!MD_Final(m, local_md))
+            goto err;
+
+        for (i = 0; i < MD_DIGEST_LENGTH / 2; i++) {
+            /* may compete with other threads */
+            state[st_idx++] ^= local_md[i];
+            if (st_idx >= st_num)
+                st_idx = 0;
+            if (i < j)
+                *(buf++) = local_md[i + MD_DIGEST_LENGTH / 2];
+        }
+    }
+
+    if (!MD_Init(m)
+        || !MD_Update(m, (unsigned char *)&(md_c[0]), sizeof(md_c))
+        || !MD_Update(m, local_md, MD_DIGEST_LENGTH))
+        goto err;
+    CRYPTO_THREAD_write_lock(rand_lock);
+    /*
+     * Prevent deadlocks if we end up in an async engine
+     */
+    ASYNC_block_pause();
+    if (!MD_Update(m, md, MD_DIGEST_LENGTH) || !MD_Final(m, md)) {
+        CRYPTO_THREAD_unlock(rand_lock);
+        goto err;
+    }
+    ASYNC_unblock_pause();
+    CRYPTO_THREAD_unlock(rand_lock);
+
+    EVP_MD_CTX_free(m);
+    if (ok)
+        return (1);
+    else if (pseudo)
+        return 0;
+    else {
+        RANDerr(RAND_F_RAND_BYTES, RAND_R_PRNG_NOT_SEEDED);
+        ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
+                           "https://www.openssl.org/docs/faq.html");
+        return (0);
+    }
+ err:
+    RANDerr(RAND_F_RAND_BYTES, ERR_R_EVP_LIB);
+    EVP_MD_CTX_free(m);
+    return 0;
+ err_mem:
+    RANDerr(RAND_F_RAND_BYTES, ERR_R_MALLOC_FAILURE);
+    EVP_MD_CTX_free(m);
+    return 0;
+
+}
+
+static int rand_nopseudo_bytes(unsigned char *buf, int num)
+{
+    return rand_bytes(buf, num, 0);
+}
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+/*
+ * pseudo-random bytes that are guaranteed to be unique but not unpredictable
+ */
+static int rand_pseudo_bytes(unsigned char *buf, int num)
+{
+    return rand_bytes(buf, num, 1);
+}
+#endif
+
+static int rand_status(void)
+{
+    CRYPTO_THREAD_ID cur;
+    int ret;
+    int do_not_lock;
+
+    if (!RUN_ONCE(&rand_lock_init, do_rand_lock_init))
+        return 0;
+
+    cur = CRYPTO_THREAD_get_current_id();
+    /*
+     * check if we already have the lock (could happen if a RAND_poll()
+     * implementation calls RAND_status())
+     */
+    if (crypto_lock_rand) {
+        CRYPTO_THREAD_read_lock(rand_tmp_lock);
+        do_not_lock = CRYPTO_THREAD_compare_id(locking_threadid, cur);
+        CRYPTO_THREAD_unlock(rand_tmp_lock);
+    } else
+        do_not_lock = 0;
+
+    if (!do_not_lock) {
+        CRYPTO_THREAD_write_lock(rand_lock);
+        /*
+         * Prevent deadlocks in case we end up in an async engine
+         */
+        ASYNC_block_pause();
+
+        /*
+         * prevent rand_bytes() from trying to obtain the lock again
+         */
+        CRYPTO_THREAD_write_lock(rand_tmp_lock);
+        locking_threadid = cur;
+        CRYPTO_THREAD_unlock(rand_tmp_lock);
+        crypto_lock_rand = 1;
+    }
+
+    if (!initialized) {
+        RAND_poll();
+        initialized = 1;
+    }
+
+    ret = entropy >= ENTROPY_NEEDED;
+
+    if (!do_not_lock) {
+        /* before unlocking, we must clear 'crypto_lock_rand' */
+        crypto_lock_rand = 0;
+
+        ASYNC_unblock_pause();
+        CRYPTO_THREAD_unlock(rand_lock);
+    }
+
+    return ret;
+}
+
+/*
+ * rand_hw_seed: get seed data from any available hardware RNG. only
+ * currently supports rdrand.
+ */
+
+/* Adapted from eng_rdrand.c */
+
+#if (defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
+     defined(__x86_64) || defined(__x86_64__) || \
+     defined(_M_AMD64) || defined (_M_X64)) && defined(OPENSSL_CPUID_OBJ) \
+     && !defined(OPENSSL_NO_RDRAND)
+
+# define RDRAND_CALLS    4
+
+size_t OPENSSL_ia32_rdrand(void);
+extern unsigned int OPENSSL_ia32cap_P[];
+
+static int rand_hw_seed(EVP_MD_CTX *ctx)
+{
+    int i;
+    if (!(OPENSSL_ia32cap_P[1] & (1 << (62 - 32))))
+        return 1;
+    for (i = 0; i < RDRAND_CALLS; i++) {
+        size_t rnd;
+        rnd = OPENSSL_ia32_rdrand();
+        if (rnd == 0)
+            return 1;
+        if (!MD_Update(ctx, (unsigned char *)&rnd, sizeof(size_t)))
+            return 0;
+    }
+    return 1;
+}
+
+/* XOR an existing buffer with random data */
+
+void rand_hw_xor(unsigned char *buf, size_t num)
+{
+    size_t rnd;
+    if (!(OPENSSL_ia32cap_P[1] & (1 << (62 - 32))))
+        return;
+    while (num >= sizeof(size_t)) {
+        rnd = OPENSSL_ia32_rdrand();
+        if (rnd == 0)
+            return;
+        *((size_t *)buf) ^= rnd;
+        buf += sizeof(size_t);
+        num -= sizeof(size_t);
+    }
+    if (num) {
+        rnd = OPENSSL_ia32_rdrand();
+        if (rnd == 0)
+            return;
+        while (num) {
+            *buf ^= rnd & 0xff;
+            rnd >>= 8;
+            buf++;
+            num--;
+        }
+    }
+}
+
+#else
+
+static int rand_hw_seed(EVP_MD_CTX *ctx)
+{
+    return 1;
+}
+
+void rand_hw_xor(unsigned char *buf, size_t num)
+{
+    return;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_egd.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_egd.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_egd.c	(revision 331)
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2000-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 <openssl/opensslconf.h>
+#ifdef OPENSSL_NO_EGD
+NON_EMPTY_TRANSLATION_UNIT
+#else
+
+# include <openssl/crypto.h>
+# include <openssl/e_os2.h>
+# include <openssl/rand.h>
+
+/*-
+ * Query the EGD <URL: http://www.lothar.com/tech/crypto/>.
+ *
+ * This module supplies three routines:
+ *
+ * RAND_query_egd_bytes(path, buf, bytes)
+ *   will actually query "bytes" bytes of entropy form the egd-socket located
+ *   at path and will write them to buf (if supplied) or will directly feed
+ *   it to RAND_seed() if buf==NULL.
+ *   The number of bytes is not limited by the maximum chunk size of EGD,
+ *   which is 255 bytes. If more than 255 bytes are wanted, several chunks
+ *   of entropy bytes are requested. The connection is left open until the
+ *   query is competed.
+ *   RAND_query_egd_bytes() returns with
+ *     -1  if an error occurred during connection or communication.
+ *     num the number of bytes read from the EGD socket. This number is either
+ *         the number of bytes requested or smaller, if the EGD pool is
+ *         drained and the daemon signals that the pool is empty.
+ *   This routine does not touch any RAND_status(). This is necessary, since
+ *   PRNG functions may call it during initialization.
+ *
+ * RAND_egd_bytes(path, bytes) will query "bytes" bytes and have them
+ *   used to seed the PRNG.
+ *   RAND_egd_bytes() is a wrapper for RAND_query_egd_bytes() with buf=NULL.
+ *   Unlike RAND_query_egd_bytes(), RAND_status() is used to test the
+ *   seed status so that the return value can reflect the seed state:
+ *     -1  if an error occurred during connection or communication _or_
+ *         if the PRNG has still not received the required seeding.
+ *     num the number of bytes read from the EGD socket. This number is either
+ *         the number of bytes requested or smaller, if the EGD pool is
+ *         drained and the daemon signals that the pool is empty.
+ *
+ * RAND_egd(path) will query 255 bytes and use the bytes retrieved to seed
+ *   the PRNG.
+ *   RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255.
+ */
+
+# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_UEFI)
+int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
+{
+    return (-1);
+}
+
+int RAND_egd(const char *path)
+{
+    return (-1);
+}
+
+int RAND_egd_bytes(const char *path, int bytes)
+{
+    return (-1);
+}
+# else
+#  include <openssl/opensslconf.h>
+#  include OPENSSL_UNISTD
+#  include <stddef.h>
+#  include <sys/types.h>
+#  include <sys/socket.h>
+#  ifndef NO_SYS_UN_H
+#   ifdef OPENSSL_SYS_VXWORKS
+#    include <streams/un.h>
+#   else
+#    include <sys/un.h>
+#   endif
+#  else
+struct sockaddr_un {
+    short sun_family;           /* AF_UNIX */
+    char sun_path[108];         /* path name (gag) */
+};
+#  endif                         /* NO_SYS_UN_H */
+#  include <string.h>
+#  include <errno.h>
+
+int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
+{
+    int ret = 0;
+    struct sockaddr_un addr;
+    int len, num, numbytes;
+    int fd = -1;
+    int success;
+    unsigned char egdbuf[2], tempbuf[255], *retrievebuf;
+
+    memset(&addr, 0, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+    if (strlen(path) >= sizeof(addr.sun_path))
+        return (-1);
+    OPENSSL_strlcpy(addr.sun_path, path, sizeof addr.sun_path);
+    len = offsetof(struct sockaddr_un, sun_path) + strlen(path);
+    fd = socket(AF_UNIX, SOCK_STREAM, 0);
+    if (fd == -1)
+        return (-1);
+    success = 0;
+    while (!success) {
+        if (connect(fd, (struct sockaddr *)&addr, len) == 0)
+            success = 1;
+        else {
+            switch (errno) {
+#  ifdef EINTR
+            case EINTR:
+#  endif
+#  ifdef EAGAIN
+            case EAGAIN:
+#  endif
+#  ifdef EINPROGRESS
+            case EINPROGRESS:
+#  endif
+#  ifdef EALREADY
+            case EALREADY:
+#  endif
+                /* No error, try again */
+                break;
+#  ifdef EISCONN
+            case EISCONN:
+                success = 1;
+                break;
+#  endif
+            default:
+                ret = -1;
+                goto err;       /* failure */
+            }
+        }
+    }
+
+    while (bytes > 0) {
+        egdbuf[0] = 1;
+        egdbuf[1] = bytes < 255 ? bytes : 255;
+        numbytes = 0;
+        while (numbytes != 2) {
+            num = write(fd, egdbuf + numbytes, 2 - numbytes);
+            if (num >= 0)
+                numbytes += num;
+            else {
+                switch (errno) {
+#  ifdef EINTR
+                case EINTR:
+#  endif
+#  ifdef EAGAIN
+                case EAGAIN:
+#  endif
+                    /* No error, try again */
+                    break;
+                default:
+                    ret = -1;
+                    goto err;   /* failure */
+                }
+            }
+        }
+        numbytes = 0;
+        while (numbytes != 1) {
+            num = read(fd, egdbuf, 1);
+            if (num == 0)
+                goto err;       /* descriptor closed */
+            else if (num > 0)
+                numbytes += num;
+            else {
+                switch (errno) {
+#  ifdef EINTR
+                case EINTR:
+#  endif
+#  ifdef EAGAIN
+                case EAGAIN:
+#  endif
+                    /* No error, try again */
+                    break;
+                default:
+                    ret = -1;
+                    goto err;   /* failure */
+                }
+            }
+        }
+        if (egdbuf[0] == 0)
+            goto err;
+        if (buf)
+            retrievebuf = buf + ret;
+        else
+            retrievebuf = tempbuf;
+        numbytes = 0;
+        while (numbytes != egdbuf[0]) {
+            num = read(fd, retrievebuf + numbytes, egdbuf[0] - numbytes);
+            if (num == 0)
+                goto err;       /* descriptor closed */
+            else if (num > 0)
+                numbytes += num;
+            else {
+                switch (errno) {
+#  ifdef EINTR
+                case EINTR:
+#  endif
+#  ifdef EAGAIN
+                case EAGAIN:
+#  endif
+                    /* No error, try again */
+                    break;
+                default:
+                    ret = -1;
+                    goto err;   /* failure */
+                }
+            }
+        }
+        ret += egdbuf[0];
+        bytes -= egdbuf[0];
+        if (!buf)
+            RAND_seed(tempbuf, egdbuf[0]);
+    }
+ err:
+    if (fd != -1)
+        close(fd);
+    return (ret);
+}
+
+int RAND_egd_bytes(const char *path, int bytes)
+{
+    int num, ret = -1;
+
+    num = RAND_query_egd_bytes(path, NULL, bytes);
+    if (num < 0)
+        goto err;
+    if (RAND_status() == 1)
+        ret = num;
+ err:
+    return (ret);
+}
+
+int RAND_egd(const char *path)
+{
+    return (RAND_egd_bytes(path, 255));
+}
+
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_err.c	(revision 331)
@@ -0,0 +1,43 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_RAND,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_RAND,0,reason)
+
+static ERR_STRING_DATA RAND_str_functs[] = {
+    {ERR_FUNC(RAND_F_RAND_BYTES), "RAND_bytes"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA RAND_str_reasons[] = {
+    {ERR_REASON(RAND_R_PRNG_NOT_SEEDED), "PRNG not seeded"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_RAND_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(RAND_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, RAND_str_functs);
+        ERR_load_strings(0, RAND_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_lcl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_lcl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_lcl.h	(revision 331)
@@ -0,0 +1,46 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_RAND_LCL_H
+# define HEADER_RAND_LCL_H
+
+# define ENTROPY_NEEDED 32      /* require 256 bits = 32 bytes of randomness */
+
+# if !defined(USE_MD5_RAND) && !defined(USE_SHA1_RAND) && !defined(USE_MDC2_RAND) && !defined(USE_MD2_RAND)
+#  define USE_SHA1_RAND
+# endif
+
+# include <openssl/evp.h>
+# define MD_Update(a,b,c)        EVP_DigestUpdate(a,b,c)
+# define MD_Final(a,b)           EVP_DigestFinal_ex(a,b,NULL)
+# if defined(USE_MD5_RAND)
+#  include <openssl/md5.h>
+#  define MD_DIGEST_LENGTH        MD5_DIGEST_LENGTH
+#  define MD_Init(a)              EVP_DigestInit_ex(a,EVP_md5(), NULL)
+#  define MD(a,b,c)               EVP_Digest(a,b,c,NULL,EVP_md5(), NULL)
+# elif defined(USE_SHA1_RAND)
+#  include <openssl/sha.h>
+#  define MD_DIGEST_LENGTH        SHA_DIGEST_LENGTH
+#  define MD_Init(a)              EVP_DigestInit_ex(a,EVP_sha1(), NULL)
+#  define MD(a,b,c)               EVP_Digest(a,b,c,NULL,EVP_sha1(), NULL)
+# elif defined(USE_MDC2_RAND)
+#  include <openssl/mdc2.h>
+#  define MD_DIGEST_LENGTH        MDC2_DIGEST_LENGTH
+#  define MD_Init(a)              EVP_DigestInit_ex(a,EVP_mdc2(), NULL)
+#  define MD(a,b,c)               EVP_Digest(a,b,c,NULL,EVP_mdc2(), NULL)
+# elif defined(USE_MD2_RAND)
+#  include <openssl/md2.h>
+#  define MD_DIGEST_LENGTH        MD2_DIGEST_LENGTH
+#  define MD_Init(a)              EVP_DigestInit_ex(a,EVP_md2(), NULL)
+#  define MD(a,b,c)               EVP_Digest(a,b,c,NULL,EVP_md2(), NULL)
+# endif
+
+void rand_hw_xor(unsigned char *buf, size_t num);
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_lib.c	(revision 331)
@@ -0,0 +1,126 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <time.h>
+#include "internal/cryptlib.h"
+#include <openssl/opensslconf.h>
+#include "internal/rand.h"
+
+#include <openssl/engine.h>
+
+#ifdef OPENSSL_FIPS
+# include <openssl/fips.h>
+# include <openssl/fips_rand.h>
+#endif
+
+#ifndef OPENSSL_NO_ENGINE
+/* non-NULL if default_RAND_meth is ENGINE-provided */
+static ENGINE *funct_ref = NULL;
+#endif
+static const RAND_METHOD *default_RAND_meth = NULL;
+
+int RAND_set_rand_method(const RAND_METHOD *meth)
+{
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE_finish(funct_ref);
+    funct_ref = NULL;
+#endif
+    default_RAND_meth = meth;
+    return 1;
+}
+
+const RAND_METHOD *RAND_get_rand_method(void)
+{
+    if (!default_RAND_meth) {
+#ifndef OPENSSL_NO_ENGINE
+        ENGINE *e = ENGINE_get_default_RAND();
+        if (e) {
+            default_RAND_meth = ENGINE_get_RAND(e);
+            if (default_RAND_meth == NULL) {
+                ENGINE_finish(e);
+                e = NULL;
+            }
+        }
+        if (e)
+            funct_ref = e;
+        else
+#endif
+            default_RAND_meth = RAND_OpenSSL();
+    }
+    return default_RAND_meth;
+}
+
+#ifndef OPENSSL_NO_ENGINE
+int RAND_set_rand_engine(ENGINE *engine)
+{
+    const RAND_METHOD *tmp_meth = NULL;
+    if (engine) {
+        if (!ENGINE_init(engine))
+            return 0;
+        tmp_meth = ENGINE_get_RAND(engine);
+        if (tmp_meth == NULL) {
+            ENGINE_finish(engine);
+            return 0;
+        }
+    }
+    /* This function releases any prior ENGINE so call it first */
+    RAND_set_rand_method(tmp_meth);
+    funct_ref = engine;
+    return 1;
+}
+#endif
+
+void rand_cleanup_int(void)
+{
+    const RAND_METHOD *meth = RAND_get_rand_method();
+    if (meth && meth->cleanup)
+        meth->cleanup();
+    RAND_set_rand_method(NULL);
+}
+
+void RAND_seed(const void *buf, int num)
+{
+    const RAND_METHOD *meth = RAND_get_rand_method();
+    if (meth && meth->seed)
+        meth->seed(buf, num);
+}
+
+void RAND_add(const void *buf, int num, double entropy)
+{
+    const RAND_METHOD *meth = RAND_get_rand_method();
+    if (meth && meth->add)
+        meth->add(buf, num, entropy);
+}
+
+int RAND_bytes(unsigned char *buf, int num)
+{
+    const RAND_METHOD *meth = RAND_get_rand_method();
+    if (meth && meth->bytes)
+        return meth->bytes(buf, num);
+    return (-1);
+}
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+int RAND_pseudo_bytes(unsigned char *buf, int num)
+{
+    const RAND_METHOD *meth = RAND_get_rand_method();
+    if (meth && meth->pseudorand)
+        return meth->pseudorand(buf, num);
+    return (-1);
+}
+#endif
+
+int RAND_status(void)
+{
+    const RAND_METHOD *meth = RAND_get_rand_method();
+    if (meth && meth->status)
+        return meth->status();
+    return 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_unix.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_unix.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_unix.c	(revision 331)
@@ -0,0 +1,324 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+
+#define USE_SOCKETS
+#include "e_os.h"
+#include "internal/cryptlib.h"
+#include <openssl/rand.h>
+#include "rand_lcl.h"
+
+#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI))
+
+# include <sys/types.h>
+# include <sys/time.h>
+# include <sys/times.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+# include <unistd.h>
+# include <time.h>
+# if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually
+                                 * everywhere */
+#  include <poll.h>
+# endif
+# include <limits.h>
+# ifndef FD_SETSIZE
+#  define FD_SETSIZE (8*sizeof(fd_set))
+# endif
+
+# if defined(OPENSSL_SYS_VOS)
+
+/*
+ * The following algorithm repeatedly samples the real-time clock (RTC) to
+ * generate a sequence of unpredictable data.  The algorithm relies upon the
+ * uneven execution speed of the code (due to factors such as cache misses,
+ * interrupts, bus activity, and scheduling) and upon the rather large
+ * relative difference between the speed of the clock and the rate at which
+ * it can be read.
+ *
+ * If this code is ported to an environment where execution speed is more
+ * constant or where the RTC ticks at a much slower rate, or the clock can be
+ * read with fewer instructions, it is likely that the results would be far
+ * more predictable.
+ *
+ * As a precaution, we generate 4 times the minimum required amount of seed
+ * data.
+ */
+
+int RAND_poll(void)
+{
+    short int code;
+    gid_t curr_gid;
+    pid_t curr_pid;
+    uid_t curr_uid;
+    int i, k;
+    struct timespec ts;
+    unsigned char v;
+
+#  ifdef OPENSSL_SYS_VOS_HPPA
+    long duration;
+    extern void s$sleep(long *_duration, short int *_code);
+#  else
+#   ifdef OPENSSL_SYS_VOS_IA32
+    long long duration;
+    extern void s$sleep2(long long *_duration, short int *_code);
+#   else
+#    error "Unsupported Platform."
+#   endif                       /* OPENSSL_SYS_VOS_IA32 */
+#  endif                        /* OPENSSL_SYS_VOS_HPPA */
+
+    /*
+     * Seed with the gid, pid, and uid, to ensure *some* variation between
+     * different processes.
+     */
+
+    curr_gid = getgid();
+    RAND_add(&curr_gid, sizeof curr_gid, 1);
+    curr_gid = 0;
+
+    curr_pid = getpid();
+    RAND_add(&curr_pid, sizeof curr_pid, 1);
+    curr_pid = 0;
+
+    curr_uid = getuid();
+    RAND_add(&curr_uid, sizeof curr_uid, 1);
+    curr_uid = 0;
+
+    for (i = 0; i < (ENTROPY_NEEDED * 4); i++) {
+        /*
+         * burn some cpu; hope for interrupts, cache collisions, bus
+         * interference, etc.
+         */
+        for (k = 0; k < 99; k++)
+            ts.tv_nsec = random();
+
+#  ifdef OPENSSL_SYS_VOS_HPPA
+        /* sleep for 1/1024 of a second (976 us).  */
+        duration = 1;
+        s$sleep(&duration, &code);
+#  else
+#   ifdef OPENSSL_SYS_VOS_IA32
+        /* sleep for 1/65536 of a second (15 us).  */
+        duration = 1;
+        s$sleep2(&duration, &code);
+#   endif                       /* OPENSSL_SYS_VOS_IA32 */
+#  endif                        /* OPENSSL_SYS_VOS_HPPA */
+
+        /* get wall clock time.  */
+        clock_gettime(CLOCK_REALTIME, &ts);
+
+        /* take 8 bits */
+        v = (unsigned char)(ts.tv_nsec % 256);
+        RAND_add(&v, sizeof v, 1);
+        v = 0;
+    }
+    return 1;
+}
+# elif defined __OpenBSD__
+int RAND_poll(void)
+{
+    u_int32_t rnd = 0, i;
+    unsigned char buf[ENTROPY_NEEDED];
+
+    for (i = 0; i < sizeof(buf); i++) {
+        if (i % 4 == 0)
+            rnd = arc4random();
+        buf[i] = rnd;
+        rnd >>= 8;
+    }
+    RAND_add(buf, sizeof(buf), ENTROPY_NEEDED);
+    OPENSSL_cleanse(buf, sizeof(buf));
+
+    return 1;
+}
+# else                          /* !defined(__OpenBSD__) */
+int RAND_poll(void)
+{
+    unsigned long l;
+    pid_t curr_pid = getpid();
+#  if defined(DEVRANDOM) || (!defined(OPENSS_NO_EGD) && defined(DEVRANDOM_EGD))
+    unsigned char tmpbuf[ENTROPY_NEEDED];
+    int n = 0;
+#  endif
+#  ifdef DEVRANDOM
+    static const char *randomfiles[] = { DEVRANDOM };
+    struct stat randomstats[OSSL_NELEM(randomfiles)];
+    int fd;
+    unsigned int i;
+#  endif
+#  if !defined(OPENSSL_NO_EGD) && defined(DEVRANDOM_EGD)
+    static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
+    const char **egdsocket = NULL;
+#  endif
+
+#  ifdef DEVRANDOM
+    memset(randomstats, 0, sizeof(randomstats));
+    /*
+     * Use a random entropy pool device. Linux, FreeBSD and OpenBSD have
+     * this. Use /dev/urandom if you can as /dev/random may block if it runs
+     * out of random entries.
+     */
+
+    for (i = 0; (i < OSSL_NELEM(randomfiles)) && (n < ENTROPY_NEEDED); i++) {
+        if ((fd = open(randomfiles[i], O_RDONLY
+#   ifdef O_NONBLOCK
+                       | O_NONBLOCK
+#   endif
+#   ifdef O_BINARY
+                       | O_BINARY
+#   endif
+#   ifdef O_NOCTTY              /* If it happens to be a TTY (god forbid), do
+                                 * not make it our controlling tty */
+                       | O_NOCTTY
+#   endif
+             )) >= 0) {
+            int usec = 10 * 1000; /* spend 10ms on each file */
+            int r;
+            unsigned int j;
+            struct stat *st = &randomstats[i];
+
+            /*
+             * Avoid using same input... Used to be O_NOFOLLOW above, but
+             * it's not universally appropriate...
+             */
+            if (fstat(fd, st) != 0) {
+                close(fd);
+                continue;
+            }
+            for (j = 0; j < i; j++) {
+                if (randomstats[j].st_ino == st->st_ino &&
+                    randomstats[j].st_dev == st->st_dev)
+                    break;
+            }
+            if (j < i) {
+                close(fd);
+                continue;
+            }
+
+            do {
+                int try_read = 0;
+
+#   if defined(OPENSSL_SYS_LINUX)
+                /* use poll() */
+                struct pollfd pset;
+
+                pset.fd = fd;
+                pset.events = POLLIN;
+                pset.revents = 0;
+
+                if (poll(&pset, 1, usec / 1000) < 0)
+                    usec = 0;
+                else
+                    try_read = (pset.revents & POLLIN) != 0;
+
+#   else
+                /* use select() */
+                fd_set fset;
+                struct timeval t;
+
+                t.tv_sec = 0;
+                t.tv_usec = usec;
+
+                if (FD_SETSIZE > 0 && (unsigned)fd >= FD_SETSIZE) {
+                    /*
+                     * can't use select, so just try to read once anyway
+                     */
+                    try_read = 1;
+                } else {
+                    FD_ZERO(&fset);
+                    FD_SET(fd, &fset);
+
+                    if (select(fd + 1, &fset, NULL, NULL, &t) >= 0) {
+                        usec = t.tv_usec;
+                        if (FD_ISSET(fd, &fset))
+                            try_read = 1;
+                    } else
+                        usec = 0;
+                }
+#   endif
+
+                if (try_read) {
+                    r = read(fd, (unsigned char *)tmpbuf + n,
+                             ENTROPY_NEEDED - n);
+                    if (r > 0)
+                        n += r;
+                } else
+                    r = -1;
+
+                /*
+                 * Some Unixen will update t in select(), some won't.  For
+                 * those who won't, or if we didn't use select() in the first
+                 * place, give up here, otherwise, we will do this once again
+                 * for the remaining time.
+                 */
+                if (usec == 10 * 1000)
+                    usec = 0;
+            }
+            while ((r > 0 ||
+                    (errno == EINTR || errno == EAGAIN)) && usec != 0
+                   && n < ENTROPY_NEEDED);
+
+            close(fd);
+        }
+    }
+#  endif                        /* defined(DEVRANDOM) */
+
+#  if !defined(OPENSSL_NO_EGD) && defined(DEVRANDOM_EGD)
+    /*
+     * Use an EGD socket to read entropy from an EGD or PRNGD entropy
+     * collecting daemon.
+     */
+
+    for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED;
+         egdsocket++) {
+        int r;
+
+        r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf + n,
+                                 ENTROPY_NEEDED - n);
+        if (r > 0)
+            n += r;
+    }
+#  endif                        /* defined(DEVRANDOM_EGD) */
+
+#  if defined(DEVRANDOM) || (!defined(OPENSSL_NO_EGD) && defined(DEVRANDOM_EGD))
+    if (n > 0) {
+        RAND_add(tmpbuf, sizeof tmpbuf, (double)n);
+        OPENSSL_cleanse(tmpbuf, n);
+    }
+#  endif
+
+    /* put in some default random data, we need more than just this */
+    l = curr_pid;
+    RAND_add(&l, sizeof(l), 0.0);
+    l = getuid();
+    RAND_add(&l, sizeof(l), 0.0);
+
+    l = time(NULL);
+    RAND_add(&l, sizeof(l), 0.0);
+
+#  if defined(DEVRANDOM) || (!defined(OPENSSL_NO_EGD) && defined(DEVRANDOM_EGD))
+    return 1;
+#  else
+    return 0;
+#  endif
+}
+
+# endif                         /* defined(__OpenBSD__) */
+#endif                          /* !(defined(OPENSSL_SYS_WINDOWS) ||
+                                 * defined(OPENSSL_SYS_WIN32) ||
+                                 * defined(OPENSSL_SYS_VMS) ||
+                                 * defined(OPENSSL_SYS_VXWORKS) */
+
+#if defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_UEFI)
+int RAND_poll(void)
+{
+    return 0;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_vms.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_vms.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_vms.c	(revision 331)
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2001-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
+ */
+
+/*
+ * Modified by VMS Software, Inc (2016)
+ *    Eliminate looping through all processes (performance)
+ *    Add additional randomizations using rand() function
+ */
+
+#include <openssl/rand.h>
+#include "rand_lcl.h"
+
+#if defined(OPENSSL_SYS_VMS)
+# include <descrip.h>
+# include <jpidef.h>
+# include <ssdef.h>
+# include <starlet.h>
+# include <efndef>
+# ifdef __DECC
+#  pragma message disable DOLLARID
+# endif
+
+/*
+ * Use 32-bit pointers almost everywhere.  Define the type to which to cast a
+ * pointer passed to an external function.
+ */
+# if __INITIAL_POINTER_SIZE == 64
+#  define PTR_T __void_ptr64
+#  pragma pointer_size save
+#  pragma pointer_size 32
+# else                          /* __INITIAL_POINTER_SIZE == 64 */
+#  define PTR_T void *
+# endif                         /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+static struct items_data_st {
+    short length, code;         /* length is number of bytes */
+} items_data[] = {
+    {4, JPI$_BUFIO},
+    {4, JPI$_CPUTIM},
+    {4, JPI$_DIRIO},
+    {4, JPI$_IMAGECOUNT},
+    {8, JPI$_LAST_LOGIN_I},
+    {8, JPI$_LOGINTIM},
+    {4, JPI$_PAGEFLTS},
+    {4, JPI$_PID},
+    {4, JPI$_PPGCNT},
+    {4, JPI$_WSPEAK},
+    {4, JPI$_FINALEXC},
+    {0, 0}                      /* zero terminated */
+};
+
+int RAND_poll(void)
+{
+
+    /* determine the number of items in the JPI array */
+
+    struct items_data_st item_entry;
+    int item_entry_count = sizeof(items_data)/sizeof(item_entry);
+
+    /* Create the JPI itemlist array to hold item_data content */
+
+    struct {
+        short length, code;
+        int *buffer;
+        int *retlen;
+    } item[item_entry_count], *pitem; /* number of entries in items_data */
+
+    struct items_data_st *pitems_data;
+    int data_buffer[(item_entry_count*2)+4]; /* 8 bytes per entry max */
+    int iosb[2];
+    int sys_time[2];
+    int *ptr;
+    int i, j ;
+    int tmp_length   = 0;
+    int total_length = 0;
+
+    pitems_data = items_data;
+    pitem = item;
+
+
+    /* Setup itemlist for GETJPI */
+    while (pitems_data->length) {
+        pitem->length = pitems_data->length;
+        pitem->code   = pitems_data->code;
+        pitem->buffer = &data_buffer[total_length];
+        pitem->retlen = 0;
+        /* total_length is in longwords */
+        total_length += pitems_data->length/4;
+        pitems_data++;
+        pitem ++;
+    }
+    pitem->length = pitem->code = 0;
+
+    /* Fill data_buffer with various info bits from this process */
+    /* and twist that data to seed the SSL random number init    */
+
+    if (sys$getjpiw(EFN$C_ENF, NULL, NULL, item, &iosb, 0, 0) == SS$_NORMAL) {
+        for (i = 0; i < total_length; i++) {
+            sys$gettim((struct _generic_64 *)&sys_time[0]);
+            srand(sys_time[0] * data_buffer[0] * data_buffer[1] + i);
+
+            if (i == (total_length - 1)) { /* for JPI$_FINALEXC */
+                ptr = &data_buffer[i];
+                for (j = 0; j < 4; j++) {
+                    data_buffer[i + j] = ptr[j];
+                    /* OK to use rand() just to scramble the seed */
+                    data_buffer[i + j] ^= (sys_time[0] ^ rand());
+                    tmp_length++;
+                }
+            } else {
+                /* OK to use rand() just to scramble the seed */
+                data_buffer[i] ^= (sys_time[0] ^ rand());
+            }
+        }
+
+        total_length += (tmp_length - 1);
+
+        /* size of seed is total_length*4 bytes (64bytes) */
+        RAND_add((PTR_T) data_buffer, total_length*4, total_length * 2);
+    } else {
+        return 0;
+    }
+
+    return 1;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_win.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_win.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/rand_win.c	(revision 331)
@@ -0,0 +1,135 @@
+/*
+ * Copyright 1995-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 "internal/cryptlib.h"
+#include <openssl/rand.h>
+#include "rand_lcl.h"
+
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
+# include <windows.h>
+/* On Windows 7 or higher use BCrypt instead of the legacy CryptoAPI */
+# if defined(_MSC_VER) && defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0601
+#  define RAND_WINDOWS_USE_BCRYPT
+# endif
+
+# ifdef RAND_WINDOWS_USE_BCRYPT
+#  include <bcrypt.h>
+#  pragma comment(lib, "bcrypt.lib")
+#  ifndef STATUS_SUCCESS
+#   define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
+#  endif
+# else
+#  include <wincrypt.h>
+/*
+ * Intel hardware RNG CSP -- available from
+ * http://developer.intel.com/design/security/rng/redist_license.htm
+ */
+#  define PROV_INTEL_SEC 22
+#  define INTEL_DEF_PROV L"Intel Hardware Cryptographic Service Provider"
+# endif
+
+static void readtimer(void);
+
+int RAND_poll(void)
+{
+    MEMORYSTATUS mst;
+# ifndef RAND_WINDOWS_USE_BCRYPT
+    HCRYPTPROV hProvider;
+# endif
+    DWORD w;
+    BYTE buf[64];
+
+# ifdef RAND_WINDOWS_USE_BCRYPT
+    if (BCryptGenRandom(NULL, buf, (ULONG)sizeof(buf), BCRYPT_USE_SYSTEM_PREFERRED_RNG) == STATUS_SUCCESS) {
+        RAND_add(buf, sizeof(buf), sizeof(buf));
+    }
+# else
+    /* poll the CryptoAPI PRNG */
+    /* The CryptoAPI returns sizeof(buf) bytes of randomness */
+    if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
+        if (CryptGenRandom(hProvider, (DWORD)sizeof(buf), buf) != 0) {
+            RAND_add(buf, sizeof(buf), sizeof(buf));
+        }
+        CryptReleaseContext(hProvider, 0);
+    }
+
+    /* poll the Pentium PRG with CryptoAPI */
+    if (CryptAcquireContextW(&hProvider, NULL, INTEL_DEF_PROV, PROV_INTEL_SEC, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
+        if (CryptGenRandom(hProvider, (DWORD)sizeof(buf), buf) != 0) {
+            RAND_add(buf, sizeof(buf), sizeof(buf));
+        }
+        CryptReleaseContext(hProvider, 0);
+    }
+# endif
+
+    /* timer data */
+    readtimer();
+
+    /* memory usage statistics */
+    GlobalMemoryStatus(&mst);
+    RAND_add(&mst, sizeof(mst), 1);
+
+    /* process ID */
+    w = GetCurrentProcessId();
+    RAND_add(&w, sizeof(w), 1);
+
+    return (1);
+}
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam)
+{
+    RAND_poll();
+    return RAND_status();
+}
+
+void RAND_screen(void)
+{
+    RAND_poll();
+}
+#endif
+
+/* feed timing information to the PRNG */
+static void readtimer(void)
+{
+    DWORD w;
+    LARGE_INTEGER l;
+    static int have_perfc = 1;
+# if defined(_MSC_VER) && defined(_M_X86)
+    static int have_tsc = 1;
+    DWORD cyclecount;
+
+    if (have_tsc) {
+        __try {
+            __asm {
+            _emit 0x0f _emit 0x31 mov cyclecount, eax}
+            RAND_add(&cyclecount, sizeof(cyclecount), 1);
+        }
+        __except(EXCEPTION_EXECUTE_HANDLER) {
+            have_tsc = 0;
+        }
+    }
+# else
+#  define have_tsc 0
+# endif
+
+    if (have_perfc) {
+        if (QueryPerformanceCounter(&l) == 0)
+            have_perfc = 0;
+        else
+            RAND_add(&l, sizeof(l), 0);
+    }
+
+    if (!have_tsc && !have_perfc) {
+        w = GetTickCount();
+        RAND_add(&w, sizeof(w), 0);
+    }
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/randfile.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/randfile.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/randfile.c	(revision 331)
@@ -0,0 +1,366 @@
+/*
+ * Copyright 1995-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 "internal/cryptlib.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/crypto.h>
+#include <openssl/rand.h>
+#include <openssl/buffer.h>
+
+#ifdef OPENSSL_SYS_VMS
+# include <unixio.h>
+#endif
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifndef OPENSSL_NO_POSIX_IO
+# include <sys/stat.h>
+# include <fcntl.h>
+/*
+ * Following should not be needed, and we could have been stricter
+ * and demand S_IS*. But some systems just don't comply... Formally
+ * below macros are "anatomically incorrect", because normally they
+ * would look like ((m) & MASK == TYPE), but since MASK availability
+ * is as questionable, we settle for this poor-man fallback...
+ */
+# if !defined(S_ISBLK)
+#  if defined(_S_IFBLK)
+#   define S_ISBLK(m) ((m) & _S_IFBLK)
+#  elif defined(S_IFBLK)
+#   define S_ISBLK(m) ((m) & S_IFBLK)
+#  elif defined(_WIN32)
+#   define S_ISBLK(m) 0 /* no concept of block devices on Windows */
+#  endif
+# endif
+# if !defined(S_ISCHR)
+#  if defined(_S_IFCHR)
+#   define S_ISCHR(m) ((m) & _S_IFCHR)
+#  elif defined(S_IFCHR)
+#   define S_ISCHR(m) ((m) & S_IFCHR)
+#  endif
+# endif
+#endif
+
+#ifdef _WIN32
+# define stat    _stat
+# define chmod   _chmod
+# define open    _open
+# define fdopen  _fdopen
+# define fstat   _fstat
+# define fileno  _fileno
+#endif
+
+#undef BUFSIZE
+#define BUFSIZE 1024
+#define RAND_DATA 1024
+
+#ifdef OPENSSL_SYS_VMS
+/*
+ * Misc hacks needed for specific cases.
+ *
+ * __FILE_ptr32 is a type provided by DEC C headers (types.h specifically)
+ * to make sure the FILE* is a 32-bit pointer no matter what.  We know that
+ * stdio function return this type (a study of stdio.h proves it).
+ * Additionally, we create a similar char pointer type for the sake of
+ * vms_setbuf below.
+ */
+# if __INITIAL_POINTER_SIZE == 64
+#  pragma pointer_size save
+#  pragma pointer_size 32
+typedef char *char_ptr32;
+#  pragma pointer_size restore
+/*
+ * On VMS, setbuf() will only take 32-bit pointers, and a compilation
+ * with /POINTER_SIZE=64 will give off a MAYLOSEDATA2 warning here.
+ * Since we know that the FILE* really is a 32-bit pointer expanded to
+ * 64 bits, we also know it's safe to convert it back to a 32-bit pointer.
+ * As for the buffer parameter, we only use NULL here, so that passes as
+ * well...
+ */
+#  define setbuf(fp,buf) (setbuf)((__FILE_ptr32)(fp), (char_ptr32)(buf))
+# endif
+
+/*
+ * This declaration is a nasty hack to get around vms' extension to fopen for
+ * passing in sharing options being disabled by /STANDARD=ANSI89
+ */
+static __FILE_ptr32 (*const vms_fopen)(const char *, const char *, ...) =
+      (__FILE_ptr32 (*)(const char *, const char *, ...))fopen;
+# define VMS_OPEN_ATTRS "shr=get,put,upd,del","ctx=bin,stm","rfm=stm","rat=none","mrs=0"
+
+# define openssl_fopen(fname,mode) vms_fopen((fname), (mode), VMS_OPEN_ATTRS)
+#endif
+
+#define RFILE ".rnd"
+
+/*
+ * Note that these functions are intended for seed files only. Entropy
+ * devices and EGD sockets are handled in rand_unix.c
+ */
+
+int RAND_load_file(const char *file, long bytes)
+{
+    /*-
+     * If bytes >= 0, read up to 'bytes' bytes.
+     * if bytes == -1, read complete file.
+     */
+
+    unsigned char buf[BUFSIZE];
+#ifndef OPENSSL_NO_POSIX_IO
+    struct stat sb;
+#endif
+    int i, ret = 0, n;
+    FILE *in = NULL;
+
+    if (file == NULL)
+        return 0;
+
+    if (bytes == 0)
+        return ret;
+
+    in = openssl_fopen(file, "rb");
+    if (in == NULL)
+        goto err;
+
+#ifndef OPENSSL_NO_POSIX_IO
+    /*
+     * struct stat can have padding and unused fields that may not be
+     * initialized in the call to stat(). We need to clear the entire
+     * structure before calling RAND_add() to avoid complaints from
+     * applications such as Valgrind.
+     */
+    memset(&sb, 0, sizeof(sb));
+    if (fstat(fileno(in), &sb) < 0)
+        goto err;
+    RAND_add(&sb, sizeof(sb), 0.0);
+
+# if defined(S_ISBLK) && defined(S_ISCHR)
+    if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
+        /*
+         * this file is a device. we don't want read an infinite number of
+         * bytes from a random device, nor do we want to use buffered I/O
+         * because we will waste system entropy.
+         */
+        bytes = (bytes == -1) ? 2048 : bytes; /* ok, is 2048 enough? */
+        setbuf(in, NULL); /* don't do buffered reads */
+    }
+# endif
+#endif
+    for (;;) {
+        if (bytes > 0)
+            n = (bytes < BUFSIZE) ? (int)bytes : BUFSIZE;
+        else
+            n = BUFSIZE;
+        i = fread(buf, 1, n, in);
+        if (i <= 0)
+            break;
+
+        RAND_add(buf, i, (double)i);
+        ret += i;
+        if (bytes > 0) {
+            bytes -= n;
+            if (bytes <= 0)
+                break;
+        }
+    }
+    OPENSSL_cleanse(buf, BUFSIZE);
+ err:
+    if (in != NULL)
+        fclose(in);
+    return ret;
+}
+
+int RAND_write_file(const char *file)
+{
+    unsigned char buf[BUFSIZE];
+    int i, ret = 0, rand_err = 0;
+    FILE *out = NULL;
+    int n;
+#ifndef OPENSSL_NO_POSIX_IO
+    struct stat sb;
+
+# if defined(S_ISBLK) && defined(S_ISCHR)
+# ifdef _WIN32
+    /*
+     * Check for |file| being a driver as "ASCII-safe" on Windows,
+     * because driver paths are always ASCII.
+     */
+# endif
+    i = stat(file, &sb);
+    if (i != -1) {
+        if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
+            /*
+             * this file is a device. we don't write back to it. we
+             * "succeed" on the assumption this is some sort of random
+             * device. Otherwise attempting to write to and chmod the device
+             * causes problems.
+             */
+            return 1;
+        }
+    }
+# endif
+#endif
+
+#if defined(O_CREAT) && !defined(OPENSSL_NO_POSIX_IO) && \
+    !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_WINDOWS)
+    {
+# ifndef O_BINARY
+#  define O_BINARY 0
+# endif
+        /*
+         * chmod(..., 0600) is too late to protect the file, permissions
+         * should be restrictive from the start
+         */
+        int fd = open(file, O_WRONLY | O_CREAT | O_BINARY, 0600);
+        if (fd != -1)
+            out = fdopen(fd, "wb");
+    }
+#endif
+
+#ifdef OPENSSL_SYS_VMS
+    /*
+     * VMS NOTE: Prior versions of this routine created a _new_ version of
+     * the rand file for each call into this routine, then deleted all
+     * existing versions named ;-1, and finally renamed the current version
+     * as ';1'. Under concurrent usage, this resulted in an RMS race
+     * condition in rename() which could orphan files (see vms message help
+     * for RMS$_REENT). With the fopen() calls below, openssl/VMS now shares
+     * the top-level version of the rand file. Note that there may still be
+     * conditions where the top-level rand file is locked. If so, this code
+     * will then create a new version of the rand file. Without the delete
+     * and rename code, this can result in ascending file versions that stop
+     * at version 32767, and this routine will then return an error. The
+     * remedy for this is to recode the calling application to avoid
+     * concurrent use of the rand file, or synchronize usage at the
+     * application level. Also consider whether or not you NEED a persistent
+     * rand file in a concurrent use situation.
+     */
+
+    out = openssl_fopen(file, "rb+");
+#endif
+    if (out == NULL)
+        out = openssl_fopen(file, "wb");
+    if (out == NULL)
+        goto err;
+
+#if !defined(NO_CHMOD) && !defined(OPENSSL_NO_POSIX_IO)
+    chmod(file, 0600);
+#endif
+    n = RAND_DATA;
+    for (;;) {
+        i = (n > BUFSIZE) ? BUFSIZE : n;
+        n -= BUFSIZE;
+        if (RAND_bytes(buf, i) <= 0)
+            rand_err = 1;
+        i = fwrite(buf, 1, i, out);
+        if (i <= 0) {
+            ret = 0;
+            break;
+        }
+        ret += i;
+        if (n <= 0)
+            break;
+    }
+
+    fclose(out);
+    OPENSSL_cleanse(buf, BUFSIZE);
+ err:
+    return (rand_err ? -1 : ret);
+}
+
+const char *RAND_file_name(char *buf, size_t size)
+{
+    char *s = NULL;
+    int use_randfile = 1;
+#ifdef __OpenBSD__
+    struct stat sb;
+#endif
+
+#if defined(_WIN32) && defined(CP_UTF8)
+    DWORD len;
+    WCHAR *var, *val;
+
+    if ((var = L"RANDFILE",
+         len = GetEnvironmentVariableW(var, NULL, 0)) == 0
+        && (var = L"HOME", use_randfile = 0,
+            len = GetEnvironmentVariableW(var, NULL, 0)) == 0
+        && (var = L"USERPROFILE",
+            len = GetEnvironmentVariableW(var, NULL, 0)) == 0) {
+        var = L"SYSTEMROOT",
+        len = GetEnvironmentVariableW(var, NULL, 0);
+    }
+
+    if (len != 0) {
+        int sz;
+
+        val = _alloca(len * sizeof(WCHAR));
+
+        if (GetEnvironmentVariableW(var, val, len) < len
+            && (sz = WideCharToMultiByte(CP_UTF8, 0, val, -1, NULL, 0,
+                                         NULL, NULL)) != 0) {
+            s = _alloca(sz);
+            if (WideCharToMultiByte(CP_UTF8, 0, val, -1, s, sz,
+                                    NULL, NULL) == 0)
+                s = NULL;
+        }
+    }
+#else
+    if (OPENSSL_issetugid() != 0) {
+        use_randfile = 0;
+    } else {
+        s = getenv("RANDFILE");
+        if (s == NULL || *s == '\0') {
+            use_randfile = 0;
+            s = getenv("HOME");
+        }
+    }
+#endif
+#ifdef DEFAULT_HOME
+    if (!use_randfile && s == NULL) {
+        s = DEFAULT_HOME;
+    }
+#endif
+    if (s != NULL && *s) {
+        size_t len = strlen(s);
+
+        if (use_randfile && len + 1 < size) {
+            if (OPENSSL_strlcpy(buf, s, size) >= size)
+                return NULL;
+        } else if (len + strlen(RFILE) + 2 < size) {
+            OPENSSL_strlcpy(buf, s, size);
+#ifndef OPENSSL_SYS_VMS
+            OPENSSL_strlcat(buf, "/", size);
+#endif
+            OPENSSL_strlcat(buf, RFILE, size);
+        }
+    } else {
+        buf[0] = '\0';      /* no file name */
+    }
+
+#ifdef __OpenBSD__
+    /*
+     * given that all random loads just fail if the file can't be seen on a
+     * stat, we stat the file we're returning, if it fails, use /dev/arandom
+     * instead. this allows the user to use their own source for good random
+     * data, but defaults to something hopefully decent if that isn't
+     * available.
+     */
+
+    if (!buf[0] || stat(buf, &sb) == -1)
+        if (OPENSSL_strlcpy(buf, "/dev/arandom", size) >= size) {
+            return NULL;
+        }
+#endif
+    return buf[0] ? buf : NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc2/rc2_cbc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc2/rc2_cbc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc2/rc2_cbc.c	(revision 331)
@@ -0,0 +1,179 @@
+/*
+ * Copyright 1995-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 <openssl/rc2.h>
+#include "rc2_locl.h"
+
+void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+                     RC2_KEY *ks, unsigned char *iv, int encrypt)
+{
+    register unsigned long tin0, tin1;
+    register unsigned long tout0, tout1, xor0, xor1;
+    register long l = length;
+    unsigned long tin[2];
+
+    if (encrypt) {
+        c2l(iv, tout0);
+        c2l(iv, tout1);
+        iv -= 8;
+        for (l -= 8; l >= 0; l -= 8) {
+            c2l(in, tin0);
+            c2l(in, tin1);
+            tin0 ^= tout0;
+            tin1 ^= tout1;
+            tin[0] = tin0;
+            tin[1] = tin1;
+            RC2_encrypt(tin, ks);
+            tout0 = tin[0];
+            l2c(tout0, out);
+            tout1 = tin[1];
+            l2c(tout1, out);
+        }
+        if (l != -8) {
+            c2ln(in, tin0, tin1, l + 8);
+            tin0 ^= tout0;
+            tin1 ^= tout1;
+            tin[0] = tin0;
+            tin[1] = tin1;
+            RC2_encrypt(tin, ks);
+            tout0 = tin[0];
+            l2c(tout0, out);
+            tout1 = tin[1];
+            l2c(tout1, out);
+        }
+        l2c(tout0, iv);
+        l2c(tout1, iv);
+    } else {
+        c2l(iv, xor0);
+        c2l(iv, xor1);
+        iv -= 8;
+        for (l -= 8; l >= 0; l -= 8) {
+            c2l(in, tin0);
+            tin[0] = tin0;
+            c2l(in, tin1);
+            tin[1] = tin1;
+            RC2_decrypt(tin, ks);
+            tout0 = tin[0] ^ xor0;
+            tout1 = tin[1] ^ xor1;
+            l2c(tout0, out);
+            l2c(tout1, out);
+            xor0 = tin0;
+            xor1 = tin1;
+        }
+        if (l != -8) {
+            c2l(in, tin0);
+            tin[0] = tin0;
+            c2l(in, tin1);
+            tin[1] = tin1;
+            RC2_decrypt(tin, ks);
+            tout0 = tin[0] ^ xor0;
+            tout1 = tin[1] ^ xor1;
+            l2cn(tout0, tout1, out, l + 8);
+            xor0 = tin0;
+            xor1 = tin1;
+        }
+        l2c(xor0, iv);
+        l2c(xor1, iv);
+    }
+    tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
+    tin[0] = tin[1] = 0;
+}
+
+void RC2_encrypt(unsigned long *d, RC2_KEY *key)
+{
+    int i, n;
+    register RC2_INT *p0, *p1;
+    register RC2_INT x0, x1, x2, x3, t;
+    unsigned long l;
+
+    l = d[0];
+    x0 = (RC2_INT) l & 0xffff;
+    x1 = (RC2_INT) (l >> 16L);
+    l = d[1];
+    x2 = (RC2_INT) l & 0xffff;
+    x3 = (RC2_INT) (l >> 16L);
+
+    n = 3;
+    i = 5;
+
+    p0 = p1 = &(key->data[0]);
+    for (;;) {
+        t = (x0 + (x1 & ~x3) + (x2 & x3) + *(p0++)) & 0xffff;
+        x0 = (t << 1) | (t >> 15);
+        t = (x1 + (x2 & ~x0) + (x3 & x0) + *(p0++)) & 0xffff;
+        x1 = (t << 2) | (t >> 14);
+        t = (x2 + (x3 & ~x1) + (x0 & x1) + *(p0++)) & 0xffff;
+        x2 = (t << 3) | (t >> 13);
+        t = (x3 + (x0 & ~x2) + (x1 & x2) + *(p0++)) & 0xffff;
+        x3 = (t << 5) | (t >> 11);
+
+        if (--i == 0) {
+            if (--n == 0)
+                break;
+            i = (n == 2) ? 6 : 5;
+
+            x0 += p1[x3 & 0x3f];
+            x1 += p1[x0 & 0x3f];
+            x2 += p1[x1 & 0x3f];
+            x3 += p1[x2 & 0x3f];
+        }
+    }
+
+    d[0] =
+        (unsigned long)(x0 & 0xffff) | ((unsigned long)(x1 & 0xffff) << 16L);
+    d[1] =
+        (unsigned long)(x2 & 0xffff) | ((unsigned long)(x3 & 0xffff) << 16L);
+}
+
+void RC2_decrypt(unsigned long *d, RC2_KEY *key)
+{
+    int i, n;
+    register RC2_INT *p0, *p1;
+    register RC2_INT x0, x1, x2, x3, t;
+    unsigned long l;
+
+    l = d[0];
+    x0 = (RC2_INT) l & 0xffff;
+    x1 = (RC2_INT) (l >> 16L);
+    l = d[1];
+    x2 = (RC2_INT) l & 0xffff;
+    x3 = (RC2_INT) (l >> 16L);
+
+    n = 3;
+    i = 5;
+
+    p0 = &(key->data[63]);
+    p1 = &(key->data[0]);
+    for (;;) {
+        t = ((x3 << 11) | (x3 >> 5)) & 0xffff;
+        x3 = (t - (x0 & ~x2) - (x1 & x2) - *(p0--)) & 0xffff;
+        t = ((x2 << 13) | (x2 >> 3)) & 0xffff;
+        x2 = (t - (x3 & ~x1) - (x0 & x1) - *(p0--)) & 0xffff;
+        t = ((x1 << 14) | (x1 >> 2)) & 0xffff;
+        x1 = (t - (x2 & ~x0) - (x3 & x0) - *(p0--)) & 0xffff;
+        t = ((x0 << 15) | (x0 >> 1)) & 0xffff;
+        x0 = (t - (x1 & ~x3) - (x2 & x3) - *(p0--)) & 0xffff;
+
+        if (--i == 0) {
+            if (--n == 0)
+                break;
+            i = (n == 2) ? 6 : 5;
+
+            x3 = (x3 - p1[x2 & 0x3f]) & 0xffff;
+            x2 = (x2 - p1[x1 & 0x3f]) & 0xffff;
+            x1 = (x1 - p1[x0 & 0x3f]) & 0xffff;
+            x0 = (x0 - p1[x3 & 0x3f]) & 0xffff;
+        }
+    }
+
+    d[0] =
+        (unsigned long)(x0 & 0xffff) | ((unsigned long)(x1 & 0xffff) << 16L);
+    d[1] =
+        (unsigned long)(x2 & 0xffff) | ((unsigned long)(x3 & 0xffff) << 16L);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc2/rc2_ecb.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc2/rc2_ecb.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc2/rc2_ecb.c	(revision 331)
@@ -0,0 +1,41 @@
+/*
+ * Copyright 1995-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 <openssl/rc2.h>
+#include "rc2_locl.h"
+#include <openssl/opensslv.h>
+
+/*-
+ * RC2 as implemented frm a posting from
+ * Newsgroups: sci.crypt
+ * Sender: pgut01@cs.auckland.ac.nz (Peter Gutmann)
+ * Subject: Specification for Ron Rivests Cipher No.2
+ * Message-ID: <4fk39f$f70@net.auckland.ac.nz>
+ * Date: 11 Feb 1996 06:45:03 GMT
+ */
+
+void RC2_ecb_encrypt(const unsigned char *in, unsigned char *out, RC2_KEY *ks,
+                     int encrypt)
+{
+    unsigned long l, d[2];
+
+    c2l(in, l);
+    d[0] = l;
+    c2l(in, l);
+    d[1] = l;
+    if (encrypt)
+        RC2_encrypt(d, ks);
+    else
+        RC2_decrypt(d, ks);
+    l = d[0];
+    l2c(l, out);
+    l = d[1];
+    l2c(l, out);
+    l = d[0] = d[1] = 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc2/rc2_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc2/rc2_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc2/rc2_locl.h	(revision 331)
@@ -0,0 +1,106 @@
+/*
+ * Copyright 1995-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
+ */
+
+#undef c2l
+#define c2l(c,l)        (l =((unsigned long)(*((c)++)))    , \
+                         l|=((unsigned long)(*((c)++)))<< 8L, \
+                         l|=((unsigned long)(*((c)++)))<<16L, \
+                         l|=((unsigned long)(*((c)++)))<<24L)
+
+/* NOTE - c is not incremented as per c2l */
+#undef c2ln
+#define c2ln(c,l1,l2,n) { \
+                        c+=n; \
+                        l1=l2=0; \
+                        switch (n) { \
+                        case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
+                        case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
+                        case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
+                        case 5: l2|=((unsigned long)(*(--(c))));     \
+                        case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
+                        case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
+                        case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
+                        case 1: l1|=((unsigned long)(*(--(c))));     \
+                                } \
+                        }
+
+#undef l2c
+#define l2c(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+#undef l2cn
+#define l2cn(l1,l2,c,n) { \
+                        c+=n; \
+                        switch (n) { \
+                        case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
+                        case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
+                        case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
+                        case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
+                        case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
+                        case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
+                        case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
+                        case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
+                                } \
+                        }
+
+/* NOTE - c is not incremented as per n2l */
+#define n2ln(c,l1,l2,n) { \
+                        c+=n; \
+                        l1=l2=0; \
+                        switch (n) { \
+                        case 8: l2 =((unsigned long)(*(--(c))))    ; \
+                        case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
+                        case 6: l2|=((unsigned long)(*(--(c))))<<16; \
+                        case 5: l2|=((unsigned long)(*(--(c))))<<24; \
+                        case 4: l1 =((unsigned long)(*(--(c))))    ; \
+                        case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
+                        case 2: l1|=((unsigned long)(*(--(c))))<<16; \
+                        case 1: l1|=((unsigned long)(*(--(c))))<<24; \
+                                } \
+                        }
+
+/* NOTE - c is not incremented as per l2n */
+#define l2nn(l1,l2,c,n) { \
+                        c+=n; \
+                        switch (n) { \
+                        case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
+                        case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+                        case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+                        case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+                        case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
+                        case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+                        case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+                        case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+                                } \
+                        }
+
+#undef n2l
+#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
+                         l|=((unsigned long)(*((c)++)))<<16L, \
+                         l|=((unsigned long)(*((c)++)))<< 8L, \
+                         l|=((unsigned long)(*((c)++))))
+
+#undef l2n
+#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)     )&0xff))
+
+#define C_RC2(n) \
+        t=(x0+(x1& ~x3)+(x2&x3)+ *(p0++))&0xffff; \
+        x0=(t<<1)|(t>>15); \
+        t=(x1+(x2& ~x0)+(x3&x0)+ *(p0++))&0xffff; \
+        x1=(t<<2)|(t>>14); \
+        t=(x2+(x3& ~x1)+(x0&x1)+ *(p0++))&0xffff; \
+        x2=(t<<3)|(t>>13); \
+        t=(x3+(x0& ~x2)+(x1&x2)+ *(p0++))&0xffff; \
+        x3=(t<<5)|(t>>11);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc2/rc2_skey.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc2/rc2_skey.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc2/rc2_skey.c	(revision 331)
@@ -0,0 +1,98 @@
+/*
+ * Copyright 1995-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 <openssl/rc2.h>
+#include "rc2_locl.h"
+
+static const unsigned char key_table[256] = {
+    0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 0x28, 0xe9, 0xfd, 0x79,
+    0x4a, 0xa0, 0xd8, 0x9d, 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e,
+    0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2, 0x17, 0x9a, 0x59, 0xf5,
+    0x87, 0xb3, 0x4f, 0x13, 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,
+    0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, 0xf0, 0x95, 0x21, 0x22,
+    0x5c, 0x6b, 0x4e, 0x82, 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c,
+    0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc, 0x12, 0x75, 0xca, 0x1f,
+    0x3b, 0xbe, 0xe4, 0xd1, 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,
+    0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, 0x27, 0xf2, 0x1d, 0x9b,
+    0xbc, 0x94, 0x43, 0x03, 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7,
+    0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7, 0x08, 0xe8, 0xea, 0xde,
+    0x80, 0x52, 0xee, 0xf7, 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,
+    0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, 0x4b, 0x9f, 0xd0, 0x5e,
+    0x04, 0x18, 0xa4, 0xec, 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc,
+    0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39, 0x99, 0x7c, 0x3a, 0x85,
+    0x23, 0xb8, 0xb4, 0x7a, 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,
+    0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, 0x05, 0xdf, 0x29, 0x10,
+    0x67, 0x6c, 0xba, 0xc9, 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c,
+    0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9, 0x0d, 0x38, 0x34, 0x1b,
+    0xab, 0x33, 0xff, 0xb0, 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,
+    0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 0x0a, 0xa6, 0x20, 0x68,
+    0xfe, 0x7f, 0xc1, 0xad,
+};
+
+#if defined(_MSC_VER) && defined(_ARM_)
+# pragma optimize("g",off)
+#endif
+
+/*
+ * It has come to my attention that there are 2 versions of the RC2 key
+ * schedule.  One which is normal, and anther which has a hook to use a
+ * reduced key length. BSAFE uses the 'retarded' version.  What I previously
+ * shipped is the same as specifying 1024 for the 'bits' parameter.  Bsafe
+ * uses a version where the bits parameter is the same as len*8
+ */
+void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits)
+{
+    int i, j;
+    unsigned char *k;
+    RC2_INT *ki;
+    unsigned int c, d;
+
+    k = (unsigned char *)&(key->data[0]);
+    *k = 0;                     /* for if there is a zero length key */
+
+    if (len > 128)
+        len = 128;
+    if (bits <= 0)
+        bits = 1024;
+    if (bits > 1024)
+        bits = 1024;
+
+    for (i = 0; i < len; i++)
+        k[i] = data[i];
+
+    /* expand table */
+    d = k[len - 1];
+    j = 0;
+    for (i = len; i < 128; i++, j++) {
+        d = key_table[(k[j] + d) & 0xff];
+        k[i] = d;
+    }
+
+    /* hmm.... key reduction to 'bits' bits */
+
+    j = (bits + 7) >> 3;
+    i = 128 - j;
+    c = (0xff >> (-bits & 0x07));
+
+    d = key_table[k[i] & c];
+    k[i] = d;
+    while (i--) {
+        d = key_table[k[i + j] ^ d];
+        k[i] = d;
+    }
+
+    /* copy from bytes into RC2_INT's */
+    ki = &(key->data[63]);
+    for (i = 127; i >= 0; i -= 2)
+        *(ki--) = ((k[i] << 8) | k[i - 1]) & 0xffff;
+}
+
+#if defined(_MSC_VER)
+# pragma optimize("",on)
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc2/rc2cfb64.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc2/rc2cfb64.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc2/rc2cfb64.c	(revision 331)
@@ -0,0 +1,74 @@
+/*
+ * Copyright 1995-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 <openssl/rc2.h>
+#include "rc2_locl.h"
+
+/*
+ * The input and output encrypted as though 64bit cfb mode is being used.
+ * The extra state information to record how much of the 64bit block we have
+ * used is contained in *num;
+ */
+
+void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                       long length, RC2_KEY *schedule, unsigned char *ivec,
+                       int *num, int encrypt)
+{
+    register unsigned long v0, v1, t;
+    register int n = *num;
+    register long l = length;
+    unsigned long ti[2];
+    unsigned char *iv, c, cc;
+
+    iv = (unsigned char *)ivec;
+    if (encrypt) {
+        while (l--) {
+            if (n == 0) {
+                c2l(iv, v0);
+                ti[0] = v0;
+                c2l(iv, v1);
+                ti[1] = v1;
+                RC2_encrypt((unsigned long *)ti, schedule);
+                iv = (unsigned char *)ivec;
+                t = ti[0];
+                l2c(t, iv);
+                t = ti[1];
+                l2c(t, iv);
+                iv = (unsigned char *)ivec;
+            }
+            c = *(in++) ^ iv[n];
+            *(out++) = c;
+            iv[n] = c;
+            n = (n + 1) & 0x07;
+        }
+    } else {
+        while (l--) {
+            if (n == 0) {
+                c2l(iv, v0);
+                ti[0] = v0;
+                c2l(iv, v1);
+                ti[1] = v1;
+                RC2_encrypt((unsigned long *)ti, schedule);
+                iv = (unsigned char *)ivec;
+                t = ti[0];
+                l2c(t, iv);
+                t = ti[1];
+                l2c(t, iv);
+                iv = (unsigned char *)ivec;
+            }
+            cc = *(in++);
+            c = iv[n];
+            iv[n] = cc;
+            *(out++) = c ^ cc;
+            n = (n + 1) & 0x07;
+        }
+    }
+    v0 = v1 = ti[0] = ti[1] = t = c = cc = 0;
+    *num = n;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc2/rc2ofb64.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc2/rc2ofb64.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc2/rc2ofb64.c	(revision 331)
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1995-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 <openssl/rc2.h>
+#include "rc2_locl.h"
+
+/*
+ * The input and output encrypted as though 64bit ofb mode is being used.
+ * The extra state information to record how much of the 64bit block we have
+ * used is contained in *num;
+ */
+void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+                       long length, RC2_KEY *schedule, unsigned char *ivec,
+                       int *num)
+{
+    register unsigned long v0, v1, t;
+    register int n = *num;
+    register long l = length;
+    unsigned char d[8];
+    register char *dp;
+    unsigned long ti[2];
+    unsigned char *iv;
+    int save = 0;
+
+    iv = (unsigned char *)ivec;
+    c2l(iv, v0);
+    c2l(iv, v1);
+    ti[0] = v0;
+    ti[1] = v1;
+    dp = (char *)d;
+    l2c(v0, dp);
+    l2c(v1, dp);
+    while (l--) {
+        if (n == 0) {
+            RC2_encrypt((unsigned long *)ti, schedule);
+            dp = (char *)d;
+            t = ti[0];
+            l2c(t, dp);
+            t = ti[1];
+            l2c(t, dp);
+            save++;
+        }
+        *(out++) = *(in++) ^ d[n];
+        n = (n + 1) & 0x07;
+    }
+    if (save) {
+        v0 = ti[0];
+        v1 = ti[1];
+        iv = (unsigned char *)ivec;
+        l2c(v0, iv);
+        l2c(v1, iv);
+    }
+    t = v0 = v1 = ti[0] = ti[1] = 0;
+    *num = n;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc4/rc4_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc4/rc4_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc4/rc4_enc.c	(revision 331)
@@ -0,0 +1,86 @@
+/*
+ * Copyright 1995-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 <openssl/rc4.h>
+#include "rc4_locl.h"
+
+/*-
+ * RC4 as implemented from a posting from
+ * Newsgroups: sci.crypt
+ * From: sterndark@netcom.com (David Sterndark)
+ * Subject: RC4 Algorithm revealed.
+ * Message-ID: <sternCvKL4B.Hyy@netcom.com>
+ * Date: Wed, 14 Sep 1994 06:35:31 GMT
+ */
+
+void RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
+         unsigned char *outdata)
+{
+    register RC4_INT *d;
+    register RC4_INT x, y, tx, ty;
+    size_t i;
+
+    x = key->x;
+    y = key->y;
+    d = key->data;
+
+#define LOOP(in,out) \
+                x=((x+1)&0xff); \
+                tx=d[x]; \
+                y=(tx+y)&0xff; \
+                d[x]=ty=d[y]; \
+                d[y]=tx; \
+                (out) = d[(tx+ty)&0xff]^ (in);
+
+    i = len >> 3;
+    if (i) {
+        for (;;) {
+            LOOP(indata[0], outdata[0]);
+            LOOP(indata[1], outdata[1]);
+            LOOP(indata[2], outdata[2]);
+            LOOP(indata[3], outdata[3]);
+            LOOP(indata[4], outdata[4]);
+            LOOP(indata[5], outdata[5]);
+            LOOP(indata[6], outdata[6]);
+            LOOP(indata[7], outdata[7]);
+            indata += 8;
+            outdata += 8;
+            if (--i == 0)
+                break;
+        }
+    }
+    i = len & 0x07;
+    if (i) {
+        for (;;) {
+            LOOP(indata[0], outdata[0]);
+            if (--i == 0)
+                break;
+            LOOP(indata[1], outdata[1]);
+            if (--i == 0)
+                break;
+            LOOP(indata[2], outdata[2]);
+            if (--i == 0)
+                break;
+            LOOP(indata[3], outdata[3]);
+            if (--i == 0)
+                break;
+            LOOP(indata[4], outdata[4]);
+            if (--i == 0)
+                break;
+            LOOP(indata[5], outdata[5]);
+            if (--i == 0)
+                break;
+            LOOP(indata[6], outdata[6]);
+            if (--i == 0)
+                break;
+        }
+    }
+    key->x = x;
+    key->y = y;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc4/rc4_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc4/rc4_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc4/rc4_locl.h	(revision 331)
@@ -0,0 +1,16 @@
+/*
+ * Copyright 1998-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
+ */
+
+#ifndef HEADER_RC4_LOCL_H
+# define HEADER_RC4_LOCL_H
+
+# include <openssl/opensslconf.h>
+# include "internal/cryptlib.h"
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc4/rc4_skey.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc4/rc4_skey.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc4/rc4_skey.c	(revision 331)
@@ -0,0 +1,58 @@
+/*
+ * Copyright 1995-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 <openssl/rc4.h>
+#include "rc4_locl.h"
+#include <openssl/opensslv.h>
+
+const char *RC4_options(void)
+{
+    if (sizeof(RC4_INT) == 1)
+        return ("rc4(char)");
+    else
+        return ("rc4(int)");
+}
+
+/*-
+ * RC4 as implemented from a posting from
+ * Newsgroups: sci.crypt
+ * From: sterndark@netcom.com (David Sterndark)
+ * Subject: RC4 Algorithm revealed.
+ * Message-ID: <sternCvKL4B.Hyy@netcom.com>
+ * Date: Wed, 14 Sep 1994 06:35:31 GMT
+ */
+
+void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
+{
+    register RC4_INT tmp;
+    register int id1, id2;
+    register RC4_INT *d;
+    unsigned int i;
+
+    d = &(key->data[0]);
+    key->x = 0;
+    key->y = 0;
+    id1 = id2 = 0;
+
+#define SK_LOOP(d,n) { \
+                tmp=d[(n)]; \
+                id2 = (data[id1] + tmp + id2) & 0xff; \
+                if (++id1 == len) id1=0; \
+                d[(n)]=d[id2]; \
+                d[id2]=tmp; }
+
+    for (i = 0; i < 256; i++)
+        d[i] = i;
+    for (i = 0; i < 256; i += 4) {
+        SK_LOOP(d, i + 0);
+        SK_LOOP(d, i + 1);
+        SK_LOOP(d, i + 2);
+        SK_LOOP(d, i + 3);
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc5/rc5_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc5/rc5_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rc5/rc5_locl.h	(revision 331)
@@ -0,0 +1,158 @@
+/*
+ * Copyright 1995-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 <stdlib.h>
+
+#undef c2l
+#define c2l(c,l)        (l =((unsigned long)(*((c)++)))    , \
+                         l|=((unsigned long)(*((c)++)))<< 8L, \
+                         l|=((unsigned long)(*((c)++)))<<16L, \
+                         l|=((unsigned long)(*((c)++)))<<24L)
+
+/* NOTE - c is not incremented as per c2l */
+#undef c2ln
+#define c2ln(c,l1,l2,n) { \
+                        c+=n; \
+                        l1=l2=0; \
+                        switch (n) { \
+                        case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
+                        case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
+                        case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
+                        case 5: l2|=((unsigned long)(*(--(c))));     \
+                        case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
+                        case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
+                        case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
+                        case 1: l1|=((unsigned long)(*(--(c))));     \
+                                } \
+                        }
+
+#undef l2c
+#define l2c(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+#undef l2cn
+#define l2cn(l1,l2,c,n) { \
+                        c+=n; \
+                        switch (n) { \
+                        case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
+                        case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
+                        case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
+                        case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \
+                        case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
+                        case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
+                        case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
+                        case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \
+                                } \
+                        }
+
+/* NOTE - c is not incremented as per n2l */
+#define n2ln(c,l1,l2,n) { \
+                        c+=n; \
+                        l1=l2=0; \
+                        switch (n) { \
+                        case 8: l2 =((unsigned long)(*(--(c))))    ; \
+                        case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
+                        case 6: l2|=((unsigned long)(*(--(c))))<<16; \
+                        case 5: l2|=((unsigned long)(*(--(c))))<<24; \
+                        case 4: l1 =((unsigned long)(*(--(c))))    ; \
+                        case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
+                        case 2: l1|=((unsigned long)(*(--(c))))<<16; \
+                        case 1: l1|=((unsigned long)(*(--(c))))<<24; \
+                                } \
+                        }
+
+/* NOTE - c is not incremented as per l2n */
+#define l2nn(l1,l2,c,n) { \
+                        c+=n; \
+                        switch (n) { \
+                        case 8: *(--(c))=(unsigned char)(((l2)    )&0xff); \
+                        case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+                        case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+                        case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+                        case 4: *(--(c))=(unsigned char)(((l1)    )&0xff); \
+                        case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+                        case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+                        case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+                                } \
+                        }
+
+#undef n2l
+#define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24L, \
+                         l|=((unsigned long)(*((c)++)))<<16L, \
+                         l|=((unsigned long)(*((c)++)))<< 8L, \
+                         l|=((unsigned long)(*((c)++))))
+
+#undef l2n
+#define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+                         *((c)++)=(unsigned char)(((l)     )&0xff))
+
+#if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER))
+# define ROTATE_l32(a,n)     _lrotl(a,n)
+# define ROTATE_r32(a,n)     _lrotr(a,n)
+#elif defined(__ICC)
+# define ROTATE_l32(a,n)     _rotl(a,n)
+# define ROTATE_r32(a,n)     _rotr(a,n)
+#elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
+# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
+#  define ROTATE_l32(a,n)       ({ register unsigned int ret;   \
+                                        asm ("roll %%cl,%0"     \
+                                                : "=r"(ret)     \
+                                                : "c"(n),"0"((unsigned int)(a)) \
+                                                : "cc");        \
+                                        ret;                    \
+                                })
+#  define ROTATE_r32(a,n)       ({ register unsigned int ret;   \
+                                        asm ("rorl %%cl,%0"     \
+                                                : "=r"(ret)     \
+                                                : "c"(n),"0"((unsigned int)(a)) \
+                                                : "cc");        \
+                                        ret;                    \
+                                })
+# endif
+#endif
+#ifndef ROTATE_l32
+# define ROTATE_l32(a,n)     (((a)<<(n&0x1f))|(((a)&0xffffffff)>>((32-n)&0x1f)))
+#endif
+#ifndef ROTATE_r32
+# define ROTATE_r32(a,n)     (((a)<<((32-n)&0x1f))|(((a)&0xffffffff)>>(n&0x1f)))
+#endif
+
+#define RC5_32_MASK     0xffffffffL
+
+#define RC5_16_P        0xB7E1
+#define RC5_16_Q        0x9E37
+#define RC5_32_P        0xB7E15163L
+#define RC5_32_Q        0x9E3779B9L
+#define RC5_64_P        0xB7E151628AED2A6BLL
+#define RC5_64_Q        0x9E3779B97F4A7C15LL
+
+#define E_RC5_32(a,b,s,n) \
+        a^=b; \
+        a=ROTATE_l32(a,b); \
+        a+=s[n]; \
+        a&=RC5_32_MASK; \
+        b^=a; \
+        b=ROTATE_l32(b,a); \
+        b+=s[n+1]; \
+        b&=RC5_32_MASK;
+
+#define D_RC5_32(a,b,s,n) \
+        b-=s[n+1]; \
+        b&=RC5_32_MASK; \
+        b=ROTATE_r32(b,a); \
+        b^=a; \
+        a-=s[n]; \
+        a&=RC5_32_MASK; \
+        a=ROTATE_r32(a,b); \
+        a^=b;
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ripemd/rmd_dgst.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ripemd/rmd_dgst.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ripemd/rmd_dgst.c	(revision 331)
@@ -0,0 +1,282 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "rmd_locl.h"
+#include <openssl/opensslv.h>
+
+#ifdef RMD160_ASM
+void ripemd160_block_x86(RIPEMD160_CTX *c, unsigned long *p, size_t num);
+# define ripemd160_block ripemd160_block_x86
+#else
+void ripemd160_block(RIPEMD160_CTX *c, unsigned long *p, size_t num);
+#endif
+
+int RIPEMD160_Init(RIPEMD160_CTX *c)
+{
+    memset(c, 0, sizeof(*c));
+    c->A = RIPEMD160_A;
+    c->B = RIPEMD160_B;
+    c->C = RIPEMD160_C;
+    c->D = RIPEMD160_D;
+    c->E = RIPEMD160_E;
+    return 1;
+}
+
+#ifndef ripemd160_block_data_order
+# ifdef X
+#  undef X
+# endif
+void ripemd160_block_data_order(RIPEMD160_CTX *ctx, const void *p, size_t num)
+{
+    const unsigned char *data = p;
+    register unsigned MD32_REG_T A, B, C, D, E;
+    unsigned MD32_REG_T a, b, c, d, e, l;
+# ifndef MD32_XARRAY
+    /* See comment in crypto/sha/sha_locl.h for details. */
+    unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+        XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15;
+#  define X(i)   XX##i
+# else
+    RIPEMD160_LONG XX[16];
+#  define X(i)   XX[i]
+# endif
+
+    for (; num--;) {
+
+        A = ctx->A;
+        B = ctx->B;
+        C = ctx->C;
+        D = ctx->D;
+        E = ctx->E;
+
+        (void)HOST_c2l(data, l);
+        X(0) = l;
+        (void)HOST_c2l(data, l);
+        X(1) = l;
+        RIP1(A, B, C, D, E, WL00, SL00);
+        (void)HOST_c2l(data, l);
+        X(2) = l;
+        RIP1(E, A, B, C, D, WL01, SL01);
+        (void)HOST_c2l(data, l);
+        X(3) = l;
+        RIP1(D, E, A, B, C, WL02, SL02);
+        (void)HOST_c2l(data, l);
+        X(4) = l;
+        RIP1(C, D, E, A, B, WL03, SL03);
+        (void)HOST_c2l(data, l);
+        X(5) = l;
+        RIP1(B, C, D, E, A, WL04, SL04);
+        (void)HOST_c2l(data, l);
+        X(6) = l;
+        RIP1(A, B, C, D, E, WL05, SL05);
+        (void)HOST_c2l(data, l);
+        X(7) = l;
+        RIP1(E, A, B, C, D, WL06, SL06);
+        (void)HOST_c2l(data, l);
+        X(8) = l;
+        RIP1(D, E, A, B, C, WL07, SL07);
+        (void)HOST_c2l(data, l);
+        X(9) = l;
+        RIP1(C, D, E, A, B, WL08, SL08);
+        (void)HOST_c2l(data, l);
+        X(10) = l;
+        RIP1(B, C, D, E, A, WL09, SL09);
+        (void)HOST_c2l(data, l);
+        X(11) = l;
+        RIP1(A, B, C, D, E, WL10, SL10);
+        (void)HOST_c2l(data, l);
+        X(12) = l;
+        RIP1(E, A, B, C, D, WL11, SL11);
+        (void)HOST_c2l(data, l);
+        X(13) = l;
+        RIP1(D, E, A, B, C, WL12, SL12);
+        (void)HOST_c2l(data, l);
+        X(14) = l;
+        RIP1(C, D, E, A, B, WL13, SL13);
+        (void)HOST_c2l(data, l);
+        X(15) = l;
+        RIP1(B, C, D, E, A, WL14, SL14);
+        RIP1(A, B, C, D, E, WL15, SL15);
+
+        RIP2(E, A, B, C, D, WL16, SL16, KL1);
+        RIP2(D, E, A, B, C, WL17, SL17, KL1);
+        RIP2(C, D, E, A, B, WL18, SL18, KL1);
+        RIP2(B, C, D, E, A, WL19, SL19, KL1);
+        RIP2(A, B, C, D, E, WL20, SL20, KL1);
+        RIP2(E, A, B, C, D, WL21, SL21, KL1);
+        RIP2(D, E, A, B, C, WL22, SL22, KL1);
+        RIP2(C, D, E, A, B, WL23, SL23, KL1);
+        RIP2(B, C, D, E, A, WL24, SL24, KL1);
+        RIP2(A, B, C, D, E, WL25, SL25, KL1);
+        RIP2(E, A, B, C, D, WL26, SL26, KL1);
+        RIP2(D, E, A, B, C, WL27, SL27, KL1);
+        RIP2(C, D, E, A, B, WL28, SL28, KL1);
+        RIP2(B, C, D, E, A, WL29, SL29, KL1);
+        RIP2(A, B, C, D, E, WL30, SL30, KL1);
+        RIP2(E, A, B, C, D, WL31, SL31, KL1);
+
+        RIP3(D, E, A, B, C, WL32, SL32, KL2);
+        RIP3(C, D, E, A, B, WL33, SL33, KL2);
+        RIP3(B, C, D, E, A, WL34, SL34, KL2);
+        RIP3(A, B, C, D, E, WL35, SL35, KL2);
+        RIP3(E, A, B, C, D, WL36, SL36, KL2);
+        RIP3(D, E, A, B, C, WL37, SL37, KL2);
+        RIP3(C, D, E, A, B, WL38, SL38, KL2);
+        RIP3(B, C, D, E, A, WL39, SL39, KL2);
+        RIP3(A, B, C, D, E, WL40, SL40, KL2);
+        RIP3(E, A, B, C, D, WL41, SL41, KL2);
+        RIP3(D, E, A, B, C, WL42, SL42, KL2);
+        RIP3(C, D, E, A, B, WL43, SL43, KL2);
+        RIP3(B, C, D, E, A, WL44, SL44, KL2);
+        RIP3(A, B, C, D, E, WL45, SL45, KL2);
+        RIP3(E, A, B, C, D, WL46, SL46, KL2);
+        RIP3(D, E, A, B, C, WL47, SL47, KL2);
+
+        RIP4(C, D, E, A, B, WL48, SL48, KL3);
+        RIP4(B, C, D, E, A, WL49, SL49, KL3);
+        RIP4(A, B, C, D, E, WL50, SL50, KL3);
+        RIP4(E, A, B, C, D, WL51, SL51, KL3);
+        RIP4(D, E, A, B, C, WL52, SL52, KL3);
+        RIP4(C, D, E, A, B, WL53, SL53, KL3);
+        RIP4(B, C, D, E, A, WL54, SL54, KL3);
+        RIP4(A, B, C, D, E, WL55, SL55, KL3);
+        RIP4(E, A, B, C, D, WL56, SL56, KL3);
+        RIP4(D, E, A, B, C, WL57, SL57, KL3);
+        RIP4(C, D, E, A, B, WL58, SL58, KL3);
+        RIP4(B, C, D, E, A, WL59, SL59, KL3);
+        RIP4(A, B, C, D, E, WL60, SL60, KL3);
+        RIP4(E, A, B, C, D, WL61, SL61, KL3);
+        RIP4(D, E, A, B, C, WL62, SL62, KL3);
+        RIP4(C, D, E, A, B, WL63, SL63, KL3);
+
+        RIP5(B, C, D, E, A, WL64, SL64, KL4);
+        RIP5(A, B, C, D, E, WL65, SL65, KL4);
+        RIP5(E, A, B, C, D, WL66, SL66, KL4);
+        RIP5(D, E, A, B, C, WL67, SL67, KL4);
+        RIP5(C, D, E, A, B, WL68, SL68, KL4);
+        RIP5(B, C, D, E, A, WL69, SL69, KL4);
+        RIP5(A, B, C, D, E, WL70, SL70, KL4);
+        RIP5(E, A, B, C, D, WL71, SL71, KL4);
+        RIP5(D, E, A, B, C, WL72, SL72, KL4);
+        RIP5(C, D, E, A, B, WL73, SL73, KL4);
+        RIP5(B, C, D, E, A, WL74, SL74, KL4);
+        RIP5(A, B, C, D, E, WL75, SL75, KL4);
+        RIP5(E, A, B, C, D, WL76, SL76, KL4);
+        RIP5(D, E, A, B, C, WL77, SL77, KL4);
+        RIP5(C, D, E, A, B, WL78, SL78, KL4);
+        RIP5(B, C, D, E, A, WL79, SL79, KL4);
+
+        a = A;
+        b = B;
+        c = C;
+        d = D;
+        e = E;
+        /* Do other half */
+        A = ctx->A;
+        B = ctx->B;
+        C = ctx->C;
+        D = ctx->D;
+        E = ctx->E;
+
+        RIP5(A, B, C, D, E, WR00, SR00, KR0);
+        RIP5(E, A, B, C, D, WR01, SR01, KR0);
+        RIP5(D, E, A, B, C, WR02, SR02, KR0);
+        RIP5(C, D, E, A, B, WR03, SR03, KR0);
+        RIP5(B, C, D, E, A, WR04, SR04, KR0);
+        RIP5(A, B, C, D, E, WR05, SR05, KR0);
+        RIP5(E, A, B, C, D, WR06, SR06, KR0);
+        RIP5(D, E, A, B, C, WR07, SR07, KR0);
+        RIP5(C, D, E, A, B, WR08, SR08, KR0);
+        RIP5(B, C, D, E, A, WR09, SR09, KR0);
+        RIP5(A, B, C, D, E, WR10, SR10, KR0);
+        RIP5(E, A, B, C, D, WR11, SR11, KR0);
+        RIP5(D, E, A, B, C, WR12, SR12, KR0);
+        RIP5(C, D, E, A, B, WR13, SR13, KR0);
+        RIP5(B, C, D, E, A, WR14, SR14, KR0);
+        RIP5(A, B, C, D, E, WR15, SR15, KR0);
+
+        RIP4(E, A, B, C, D, WR16, SR16, KR1);
+        RIP4(D, E, A, B, C, WR17, SR17, KR1);
+        RIP4(C, D, E, A, B, WR18, SR18, KR1);
+        RIP4(B, C, D, E, A, WR19, SR19, KR1);
+        RIP4(A, B, C, D, E, WR20, SR20, KR1);
+        RIP4(E, A, B, C, D, WR21, SR21, KR1);
+        RIP4(D, E, A, B, C, WR22, SR22, KR1);
+        RIP4(C, D, E, A, B, WR23, SR23, KR1);
+        RIP4(B, C, D, E, A, WR24, SR24, KR1);
+        RIP4(A, B, C, D, E, WR25, SR25, KR1);
+        RIP4(E, A, B, C, D, WR26, SR26, KR1);
+        RIP4(D, E, A, B, C, WR27, SR27, KR1);
+        RIP4(C, D, E, A, B, WR28, SR28, KR1);
+        RIP4(B, C, D, E, A, WR29, SR29, KR1);
+        RIP4(A, B, C, D, E, WR30, SR30, KR1);
+        RIP4(E, A, B, C, D, WR31, SR31, KR1);
+
+        RIP3(D, E, A, B, C, WR32, SR32, KR2);
+        RIP3(C, D, E, A, B, WR33, SR33, KR2);
+        RIP3(B, C, D, E, A, WR34, SR34, KR2);
+        RIP3(A, B, C, D, E, WR35, SR35, KR2);
+        RIP3(E, A, B, C, D, WR36, SR36, KR2);
+        RIP3(D, E, A, B, C, WR37, SR37, KR2);
+        RIP3(C, D, E, A, B, WR38, SR38, KR2);
+        RIP3(B, C, D, E, A, WR39, SR39, KR2);
+        RIP3(A, B, C, D, E, WR40, SR40, KR2);
+        RIP3(E, A, B, C, D, WR41, SR41, KR2);
+        RIP3(D, E, A, B, C, WR42, SR42, KR2);
+        RIP3(C, D, E, A, B, WR43, SR43, KR2);
+        RIP3(B, C, D, E, A, WR44, SR44, KR2);
+        RIP3(A, B, C, D, E, WR45, SR45, KR2);
+        RIP3(E, A, B, C, D, WR46, SR46, KR2);
+        RIP3(D, E, A, B, C, WR47, SR47, KR2);
+
+        RIP2(C, D, E, A, B, WR48, SR48, KR3);
+        RIP2(B, C, D, E, A, WR49, SR49, KR3);
+        RIP2(A, B, C, D, E, WR50, SR50, KR3);
+        RIP2(E, A, B, C, D, WR51, SR51, KR3);
+        RIP2(D, E, A, B, C, WR52, SR52, KR3);
+        RIP2(C, D, E, A, B, WR53, SR53, KR3);
+        RIP2(B, C, D, E, A, WR54, SR54, KR3);
+        RIP2(A, B, C, D, E, WR55, SR55, KR3);
+        RIP2(E, A, B, C, D, WR56, SR56, KR3);
+        RIP2(D, E, A, B, C, WR57, SR57, KR3);
+        RIP2(C, D, E, A, B, WR58, SR58, KR3);
+        RIP2(B, C, D, E, A, WR59, SR59, KR3);
+        RIP2(A, B, C, D, E, WR60, SR60, KR3);
+        RIP2(E, A, B, C, D, WR61, SR61, KR3);
+        RIP2(D, E, A, B, C, WR62, SR62, KR3);
+        RIP2(C, D, E, A, B, WR63, SR63, KR3);
+
+        RIP1(B, C, D, E, A, WR64, SR64);
+        RIP1(A, B, C, D, E, WR65, SR65);
+        RIP1(E, A, B, C, D, WR66, SR66);
+        RIP1(D, E, A, B, C, WR67, SR67);
+        RIP1(C, D, E, A, B, WR68, SR68);
+        RIP1(B, C, D, E, A, WR69, SR69);
+        RIP1(A, B, C, D, E, WR70, SR70);
+        RIP1(E, A, B, C, D, WR71, SR71);
+        RIP1(D, E, A, B, C, WR72, SR72);
+        RIP1(C, D, E, A, B, WR73, SR73);
+        RIP1(B, C, D, E, A, WR74, SR74);
+        RIP1(A, B, C, D, E, WR75, SR75);
+        RIP1(E, A, B, C, D, WR76, SR76);
+        RIP1(D, E, A, B, C, WR77, SR77);
+        RIP1(C, D, E, A, B, WR78, SR78);
+        RIP1(B, C, D, E, A, WR79, SR79);
+
+        D = ctx->B + c + D;
+        ctx->B = ctx->C + d + E;
+        ctx->C = ctx->D + e + A;
+        ctx->D = ctx->E + a + B;
+        ctx->E = ctx->A + b + C;
+        ctx->A = D;
+
+    }
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ripemd/rmd_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ripemd/rmd_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ripemd/rmd_locl.h	(revision 331)
@@ -0,0 +1,88 @@
+/*
+ * Copyright 1995-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 <stdlib.h>
+#include <string.h>
+#include <openssl/opensslconf.h>
+#include <openssl/ripemd.h>
+
+/*
+ * DO EXAMINE COMMENTS IN crypto/md5/md5_locl.h & crypto/md5/md5_dgst.c
+ * FOR EXPLANATIONS ON FOLLOWING "CODE."
+ *                                      <appro@fy.chalmers.se>
+ */
+#ifdef RMD160_ASM
+# if defined(__i386) || defined(__i386__) || defined(_M_IX86)
+#  define ripemd160_block_data_order ripemd160_block_asm_data_order
+# endif
+#endif
+
+void ripemd160_block_data_order(RIPEMD160_CTX *c, const void *p, size_t num);
+
+#define DATA_ORDER_IS_LITTLE_ENDIAN
+
+#define HASH_LONG               RIPEMD160_LONG
+#define HASH_CTX                RIPEMD160_CTX
+#define HASH_CBLOCK             RIPEMD160_CBLOCK
+#define HASH_UPDATE             RIPEMD160_Update
+#define HASH_TRANSFORM          RIPEMD160_Transform
+#define HASH_FINAL              RIPEMD160_Final
+#define HASH_MAKE_STRING(c,s)   do {    \
+        unsigned long ll;               \
+        ll=(c)->A; (void)HOST_l2c(ll,(s));      \
+        ll=(c)->B; (void)HOST_l2c(ll,(s));      \
+        ll=(c)->C; (void)HOST_l2c(ll,(s));      \
+        ll=(c)->D; (void)HOST_l2c(ll,(s));      \
+        ll=(c)->E; (void)HOST_l2c(ll,(s));      \
+        } while (0)
+#define HASH_BLOCK_DATA_ORDER   ripemd160_block_data_order
+
+#include "internal/md32_common.h"
+
+/*
+ * Transformed F2 and F4 are courtesy of Wei Dai <weidai@eskimo.com>
+ */
+#define F1(x,y,z)       ((x) ^ (y) ^ (z))
+#define F2(x,y,z)       ((((y) ^ (z)) & (x)) ^ (z))
+#define F3(x,y,z)       (((~(y)) | (x)) ^ (z))
+#define F4(x,y,z)       ((((x) ^ (y)) & (z)) ^ (y))
+#define F5(x,y,z)       (((~(z)) | (y)) ^ (x))
+
+#define RIPEMD160_A     0x67452301L
+#define RIPEMD160_B     0xEFCDAB89L
+#define RIPEMD160_C     0x98BADCFEL
+#define RIPEMD160_D     0x10325476L
+#define RIPEMD160_E     0xC3D2E1F0L
+
+#include "rmdconst.h"
+
+#define RIP1(a,b,c,d,e,w,s) { \
+        a+=F1(b,c,d)+X(w); \
+        a=ROTATE(a,s)+e; \
+        c=ROTATE(c,10); }
+
+#define RIP2(a,b,c,d,e,w,s,K) { \
+        a+=F2(b,c,d)+X(w)+K; \
+        a=ROTATE(a,s)+e; \
+        c=ROTATE(c,10); }
+
+#define RIP3(a,b,c,d,e,w,s,K) { \
+        a+=F3(b,c,d)+X(w)+K; \
+        a=ROTATE(a,s)+e; \
+        c=ROTATE(c,10); }
+
+#define RIP4(a,b,c,d,e,w,s,K) { \
+        a+=F4(b,c,d)+X(w)+K; \
+        a=ROTATE(a,s)+e; \
+        c=ROTATE(c,10); }
+
+#define RIP5(a,b,c,d,e,w,s,K) { \
+        a+=F5(b,c,d)+X(w)+K; \
+        a=ROTATE(a,s)+e; \
+        c=ROTATE(c,10); }
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ripemd/rmd_one.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ripemd/rmd_one.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ripemd/rmd_one.c	(revision 331)
@@ -0,0 +1,28 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <string.h>
+#include <openssl/ripemd.h>
+#include <openssl/crypto.h>
+
+unsigned char *RIPEMD160(const unsigned char *d, size_t n, unsigned char *md)
+{
+    RIPEMD160_CTX c;
+    static unsigned char m[RIPEMD160_DIGEST_LENGTH];
+
+    if (md == NULL)
+        md = m;
+    if (!RIPEMD160_Init(&c))
+        return NULL;
+    RIPEMD160_Update(&c, d, n);
+    RIPEMD160_Final(md, &c);
+    OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */
+    return (md);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ripemd/rmdconst.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ripemd/rmdconst.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ripemd/rmdconst.h	(revision 331)
@@ -0,0 +1,350 @@
+/*
+ * Copyright 1995-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
+ */
+
+#define KL0 0x00000000L
+#define KL1 0x5A827999L
+#define KL2 0x6ED9EBA1L
+#define KL3 0x8F1BBCDCL
+#define KL4 0xA953FD4EL
+
+#define KR0 0x50A28BE6L
+#define KR1 0x5C4DD124L
+#define KR2 0x6D703EF3L
+#define KR3 0x7A6D76E9L
+#define KR4 0x00000000L
+
+#define WL00  0
+#define SL00 11
+#define WL01  1
+#define SL01 14
+#define WL02  2
+#define SL02 15
+#define WL03  3
+#define SL03 12
+#define WL04  4
+#define SL04  5
+#define WL05  5
+#define SL05  8
+#define WL06  6
+#define SL06  7
+#define WL07  7
+#define SL07  9
+#define WL08  8
+#define SL08 11
+#define WL09  9
+#define SL09 13
+#define WL10 10
+#define SL10 14
+#define WL11 11
+#define SL11 15
+#define WL12 12
+#define SL12  6
+#define WL13 13
+#define SL13  7
+#define WL14 14
+#define SL14  9
+#define WL15 15
+#define SL15  8
+
+#define WL16  7
+#define SL16  7
+#define WL17  4
+#define SL17  6
+#define WL18 13
+#define SL18  8
+#define WL19  1
+#define SL19 13
+#define WL20 10
+#define SL20 11
+#define WL21  6
+#define SL21  9
+#define WL22 15
+#define SL22  7
+#define WL23  3
+#define SL23 15
+#define WL24 12
+#define SL24  7
+#define WL25  0
+#define SL25 12
+#define WL26  9
+#define SL26 15
+#define WL27  5
+#define SL27  9
+#define WL28  2
+#define SL28 11
+#define WL29 14
+#define SL29  7
+#define WL30 11
+#define SL30 13
+#define WL31  8
+#define SL31 12
+
+#define WL32  3
+#define SL32 11
+#define WL33 10
+#define SL33 13
+#define WL34 14
+#define SL34  6
+#define WL35  4
+#define SL35  7
+#define WL36  9
+#define SL36 14
+#define WL37 15
+#define SL37  9
+#define WL38  8
+#define SL38 13
+#define WL39  1
+#define SL39 15
+#define WL40  2
+#define SL40 14
+#define WL41  7
+#define SL41  8
+#define WL42  0
+#define SL42 13
+#define WL43  6
+#define SL43  6
+#define WL44 13
+#define SL44  5
+#define WL45 11
+#define SL45 12
+#define WL46  5
+#define SL46  7
+#define WL47 12
+#define SL47  5
+
+#define WL48  1
+#define SL48 11
+#define WL49  9
+#define SL49 12
+#define WL50 11
+#define SL50 14
+#define WL51 10
+#define SL51 15
+#define WL52  0
+#define SL52 14
+#define WL53  8
+#define SL53 15
+#define WL54 12
+#define SL54  9
+#define WL55  4
+#define SL55  8
+#define WL56 13
+#define SL56  9
+#define WL57  3
+#define SL57 14
+#define WL58  7
+#define SL58  5
+#define WL59 15
+#define SL59  6
+#define WL60 14
+#define SL60  8
+#define WL61  5
+#define SL61  6
+#define WL62  6
+#define SL62  5
+#define WL63  2
+#define SL63 12
+
+#define WL64  4
+#define SL64  9
+#define WL65  0
+#define SL65 15
+#define WL66  5
+#define SL66  5
+#define WL67  9
+#define SL67 11
+#define WL68  7
+#define SL68  6
+#define WL69 12
+#define SL69  8
+#define WL70  2
+#define SL70 13
+#define WL71 10
+#define SL71 12
+#define WL72 14
+#define SL72  5
+#define WL73  1
+#define SL73 12
+#define WL74  3
+#define SL74 13
+#define WL75  8
+#define SL75 14
+#define WL76 11
+#define SL76 11
+#define WL77  6
+#define SL77  8
+#define WL78 15
+#define SL78  5
+#define WL79 13
+#define SL79  6
+
+#define WR00  5
+#define SR00  8
+#define WR01 14
+#define SR01  9
+#define WR02  7
+#define SR02  9
+#define WR03  0
+#define SR03 11
+#define WR04  9
+#define SR04 13
+#define WR05  2
+#define SR05 15
+#define WR06 11
+#define SR06 15
+#define WR07  4
+#define SR07  5
+#define WR08 13
+#define SR08  7
+#define WR09  6
+#define SR09  7
+#define WR10 15
+#define SR10  8
+#define WR11  8
+#define SR11 11
+#define WR12  1
+#define SR12 14
+#define WR13 10
+#define SR13 14
+#define WR14  3
+#define SR14 12
+#define WR15 12
+#define SR15  6
+
+#define WR16  6
+#define SR16  9
+#define WR17 11
+#define SR17 13
+#define WR18  3
+#define SR18 15
+#define WR19  7
+#define SR19  7
+#define WR20  0
+#define SR20 12
+#define WR21 13
+#define SR21  8
+#define WR22  5
+#define SR22  9
+#define WR23 10
+#define SR23 11
+#define WR24 14
+#define SR24  7
+#define WR25 15
+#define SR25  7
+#define WR26  8
+#define SR26 12
+#define WR27 12
+#define SR27  7
+#define WR28  4
+#define SR28  6
+#define WR29  9
+#define SR29 15
+#define WR30  1
+#define SR30 13
+#define WR31  2
+#define SR31 11
+
+#define WR32 15
+#define SR32  9
+#define WR33  5
+#define SR33  7
+#define WR34  1
+#define SR34 15
+#define WR35  3
+#define SR35 11
+#define WR36  7
+#define SR36  8
+#define WR37 14
+#define SR37  6
+#define WR38  6
+#define SR38  6
+#define WR39  9
+#define SR39 14
+#define WR40 11
+#define SR40 12
+#define WR41  8
+#define SR41 13
+#define WR42 12
+#define SR42  5
+#define WR43  2
+#define SR43 14
+#define WR44 10
+#define SR44 13
+#define WR45  0
+#define SR45 13
+#define WR46  4
+#define SR46  7
+#define WR47 13
+#define SR47  5
+
+#define WR48  8
+#define SR48 15
+#define WR49  6
+#define SR49  5
+#define WR50  4
+#define SR50  8
+#define WR51  1
+#define SR51 11
+#define WR52  3
+#define SR52 14
+#define WR53 11
+#define SR53 14
+#define WR54 15
+#define SR54  6
+#define WR55  0
+#define SR55 14
+#define WR56  5
+#define SR56  6
+#define WR57 12
+#define SR57  9
+#define WR58  2
+#define SR58 12
+#define WR59 13
+#define SR59  9
+#define WR60  9
+#define SR60 12
+#define WR61  7
+#define SR61  5
+#define WR62 10
+#define SR62 15
+#define WR63 14
+#define SR63  8
+
+#define WR64 12
+#define SR64  8
+#define WR65 15
+#define SR65  5
+#define WR66 10
+#define SR66 12
+#define WR67  4
+#define SR67  9
+#define WR68  1
+#define SR68 12
+#define WR69  5
+#define SR69  5
+#define WR70  8
+#define SR70 14
+#define WR71  7
+#define SR71  6
+#define WR72  6
+#define SR72  8
+#define WR73  2
+#define SR73 13
+#define WR74 13
+#define SR74  6
+#define WR75 14
+#define SR75  5
+#define WR76  0
+#define SR76 15
+#define WR77  3
+#define SR77 13
+#define WR78  9
+#define SR78 11
+#define WR79 11
+#define SR79 11
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_ameth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_ameth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_ameth.c	(revision 331)
@@ -0,0 +1,866 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/bn.h>
+#include <openssl/cms.h>
+#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
+#include "rsa_locl.h"
+
+#ifndef OPENSSL_NO_CMS
+static int rsa_cms_sign(CMS_SignerInfo *si);
+static int rsa_cms_verify(CMS_SignerInfo *si);
+static int rsa_cms_decrypt(CMS_RecipientInfo *ri);
+static int rsa_cms_encrypt(CMS_RecipientInfo *ri);
+#endif
+
+static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
+{
+    unsigned char *penc = NULL;
+    int penclen;
+    penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc);
+    if (penclen <= 0)
+        return 0;
+    if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA),
+                               V_ASN1_NULL, NULL, penc, penclen))
+        return 1;
+
+    OPENSSL_free(penc);
+    return 0;
+}
+
+static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+{
+    const unsigned char *p;
+    int pklen;
+    RSA *rsa = NULL;
+
+    if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey))
+        return 0;
+    if ((rsa = d2i_RSAPublicKey(NULL, &p, pklen)) == NULL) {
+        RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB);
+        return 0;
+    }
+    EVP_PKEY_assign_RSA(pkey, rsa);
+    return 1;
+}
+
+static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+{
+    if (BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) != 0
+        || BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) != 0)
+        return 0;
+    return 1;
+}
+
+static int old_rsa_priv_decode(EVP_PKEY *pkey,
+                               const unsigned char **pder, int derlen)
+{
+    RSA *rsa;
+
+    if ((rsa = d2i_RSAPrivateKey(NULL, pder, derlen)) == NULL) {
+        RSAerr(RSA_F_OLD_RSA_PRIV_DECODE, ERR_R_RSA_LIB);
+        return 0;
+    }
+    EVP_PKEY_assign_RSA(pkey, rsa);
+    return 1;
+}
+
+static int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
+{
+    return i2d_RSAPrivateKey(pkey->pkey.rsa, pder);
+}
+
+static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
+{
+    unsigned char *rk = NULL;
+    int rklen;
+    rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk);
+
+    if (rklen <= 0) {
+        RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_rsaEncryption), 0,
+                         V_ASN1_NULL, NULL, rk, rklen)) {
+        RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int rsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
+{
+    const unsigned char *p;
+    int pklen;
+    if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8))
+        return 0;
+    return old_rsa_priv_decode(pkey, &p, pklen);
+}
+
+static int int_rsa_size(const EVP_PKEY *pkey)
+{
+    return RSA_size(pkey->pkey.rsa);
+}
+
+static int rsa_bits(const EVP_PKEY *pkey)
+{
+    return BN_num_bits(pkey->pkey.rsa->n);
+}
+
+static int rsa_security_bits(const EVP_PKEY *pkey)
+{
+    return RSA_security_bits(pkey->pkey.rsa);
+}
+
+static void int_rsa_free(EVP_PKEY *pkey)
+{
+    RSA_free(pkey->pkey.rsa);
+}
+
+static int do_rsa_print(BIO *bp, const RSA *x, int off, int priv)
+{
+    char *str;
+    const char *s;
+    int ret = 0, mod_len = 0;
+
+    if (x->n != NULL)
+        mod_len = BN_num_bits(x->n);
+
+    if (!BIO_indent(bp, off, 128))
+        goto err;
+
+    if (priv && x->d) {
+        if (BIO_printf(bp, "Private-Key: (%d bit)\n", mod_len) <= 0)
+            goto err;
+        str = "modulus:";
+        s = "publicExponent:";
+    } else {
+        if (BIO_printf(bp, "Public-Key: (%d bit)\n", mod_len) <= 0)
+            goto err;
+        str = "Modulus:";
+        s = "Exponent:";
+    }
+    if (!ASN1_bn_print(bp, str, x->n, NULL, off))
+        goto err;
+    if (!ASN1_bn_print(bp, s, x->e, NULL, off))
+        goto err;
+    if (priv) {
+        if (!ASN1_bn_print(bp, "privateExponent:", x->d, NULL, off))
+            goto err;
+        if (!ASN1_bn_print(bp, "prime1:", x->p, NULL, off))
+            goto err;
+        if (!ASN1_bn_print(bp, "prime2:", x->q, NULL, off))
+            goto err;
+        if (!ASN1_bn_print(bp, "exponent1:", x->dmp1, NULL, off))
+            goto err;
+        if (!ASN1_bn_print(bp, "exponent2:", x->dmq1, NULL, off))
+            goto err;
+        if (!ASN1_bn_print(bp, "coefficient:", x->iqmp, NULL, off))
+            goto err;
+    }
+    ret = 1;
+ err:
+    return (ret);
+}
+
+static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                         ASN1_PCTX *ctx)
+{
+    return do_rsa_print(bp, pkey->pkey.rsa, indent, 0);
+}
+
+static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
+                          ASN1_PCTX *ctx)
+{
+    return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
+}
+
+/* Given an MGF1 Algorithm ID decode to an Algorithm Identifier */
+static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg)
+{
+    if (alg == NULL)
+        return NULL;
+    if (OBJ_obj2nid(alg->algorithm) != NID_mgf1)
+        return NULL;
+    return ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR),
+                                     alg->parameter);
+}
+
+static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg,
+                                      X509_ALGOR **pmaskHash)
+{
+    RSA_PSS_PARAMS *pss;
+
+    *pmaskHash = NULL;
+
+    pss = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_PSS_PARAMS),
+                                    alg->parameter);
+
+    if (!pss)
+        return NULL;
+
+    *pmaskHash = rsa_mgf1_decode(pss->maskGenAlgorithm);
+
+    return pss;
+}
+
+static int rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss,
+                               X509_ALGOR *maskHash, int indent)
+{
+    int rv = 0;
+    if (!pss) {
+        if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0)
+            return 0;
+        return 1;
+    }
+    if (BIO_puts(bp, "\n") <= 0)
+        goto err;
+    if (!BIO_indent(bp, indent, 128))
+        goto err;
+    if (BIO_puts(bp, "Hash Algorithm: ") <= 0)
+        goto err;
+
+    if (pss->hashAlgorithm) {
+        if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0)
+            goto err;
+    } else if (BIO_puts(bp, "sha1 (default)") <= 0)
+        goto err;
+
+    if (BIO_puts(bp, "\n") <= 0)
+        goto err;
+
+    if (!BIO_indent(bp, indent, 128))
+        goto err;
+
+    if (BIO_puts(bp, "Mask Algorithm: ") <= 0)
+        goto err;
+    if (pss->maskGenAlgorithm) {
+        if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0)
+            goto err;
+        if (BIO_puts(bp, " with ") <= 0)
+            goto err;
+        if (maskHash) {
+            if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0)
+                goto err;
+        } else if (BIO_puts(bp, "INVALID") <= 0)
+            goto err;
+    } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0)
+        goto err;
+    BIO_puts(bp, "\n");
+
+    if (!BIO_indent(bp, indent, 128))
+        goto err;
+    if (BIO_puts(bp, "Salt Length: 0x") <= 0)
+        goto err;
+    if (pss->saltLength) {
+        if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0)
+            goto err;
+    } else if (BIO_puts(bp, "14 (default)") <= 0)
+        goto err;
+    BIO_puts(bp, "\n");
+
+    if (!BIO_indent(bp, indent, 128))
+        goto err;
+    if (BIO_puts(bp, "Trailer Field: 0x") <= 0)
+        goto err;
+    if (pss->trailerField) {
+        if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0)
+            goto err;
+    } else if (BIO_puts(bp, "BC (default)") <= 0)
+        goto err;
+    BIO_puts(bp, "\n");
+
+    rv = 1;
+
+ err:
+    return rv;
+
+}
+
+static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
+                         const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx)
+{
+    if (OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss) {
+        int rv;
+        RSA_PSS_PARAMS *pss;
+        X509_ALGOR *maskHash;
+        pss = rsa_pss_decode(sigalg, &maskHash);
+        rv = rsa_pss_param_print(bp, pss, maskHash, indent);
+        RSA_PSS_PARAMS_free(pss);
+        X509_ALGOR_free(maskHash);
+        if (!rv)
+            return 0;
+    } else if (!sig && BIO_puts(bp, "\n") <= 0)
+        return 0;
+    if (sig)
+        return X509_signature_dump(bp, sig, indent);
+    return 1;
+}
+
+static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+{
+    X509_ALGOR *alg = NULL;
+    switch (op) {
+
+    case ASN1_PKEY_CTRL_PKCS7_SIGN:
+        if (arg1 == 0)
+            PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg);
+        break;
+
+    case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
+        if (arg1 == 0)
+            PKCS7_RECIP_INFO_get0_alg(arg2, &alg);
+        break;
+#ifndef OPENSSL_NO_CMS
+    case ASN1_PKEY_CTRL_CMS_SIGN:
+        if (arg1 == 0)
+            return rsa_cms_sign(arg2);
+        else if (arg1 == 1)
+            return rsa_cms_verify(arg2);
+        break;
+
+    case ASN1_PKEY_CTRL_CMS_ENVELOPE:
+        if (arg1 == 0)
+            return rsa_cms_encrypt(arg2);
+        else if (arg1 == 1)
+            return rsa_cms_decrypt(arg2);
+        break;
+
+    case ASN1_PKEY_CTRL_CMS_RI_TYPE:
+        *(int *)arg2 = CMS_RECIPINFO_TRANS;
+        return 1;
+#endif
+
+    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+        *(int *)arg2 = NID_sha256;
+        return 1;
+
+    default:
+        return -2;
+
+    }
+
+    if (alg)
+        X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
+
+    return 1;
+
+}
+
+/* allocate and set algorithm ID from EVP_MD, default SHA1 */
+static int rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md)
+{
+    if (EVP_MD_type(md) == NID_sha1)
+        return 1;
+    *palg = X509_ALGOR_new();
+    if (*palg == NULL)
+        return 0;
+    X509_ALGOR_set_md(*palg, md);
+    return 1;
+}
+
+/* Allocate and set MGF1 algorithm ID from EVP_MD */
+static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md)
+{
+    X509_ALGOR *algtmp = NULL;
+    ASN1_STRING *stmp = NULL;
+    *palg = NULL;
+    if (EVP_MD_type(mgf1md) == NID_sha1)
+        return 1;
+    /* need to embed algorithm ID inside another */
+    if (!rsa_md_to_algor(&algtmp, mgf1md))
+        goto err;
+    if (!ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp))
+         goto err;
+    *palg = X509_ALGOR_new();
+    if (*palg == NULL)
+        goto err;
+    X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp);
+    stmp = NULL;
+ err:
+    ASN1_STRING_free(stmp);
+    X509_ALGOR_free(algtmp);
+    if (*palg)
+        return 1;
+    return 0;
+}
+
+/* convert algorithm ID to EVP_MD, default SHA1 */
+static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg)
+{
+    const EVP_MD *md;
+    if (!alg)
+        return EVP_sha1();
+    md = EVP_get_digestbyobj(alg->algorithm);
+    if (md == NULL)
+        RSAerr(RSA_F_RSA_ALGOR_TO_MD, RSA_R_UNKNOWN_DIGEST);
+    return md;
+}
+
+/* convert MGF1 algorithm ID to EVP_MD, default SHA1 */
+static const EVP_MD *rsa_mgf1_to_md(X509_ALGOR *alg, X509_ALGOR *maskHash)
+{
+    const EVP_MD *md;
+    if (!alg)
+        return EVP_sha1();
+    /* Check mask and lookup mask hash algorithm */
+    if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) {
+        RSAerr(RSA_F_RSA_MGF1_TO_MD, RSA_R_UNSUPPORTED_MASK_ALGORITHM);
+        return NULL;
+    }
+    if (!maskHash) {
+        RSAerr(RSA_F_RSA_MGF1_TO_MD, RSA_R_UNSUPPORTED_MASK_PARAMETER);
+        return NULL;
+    }
+    md = EVP_get_digestbyobj(maskHash->algorithm);
+    if (md == NULL) {
+        RSAerr(RSA_F_RSA_MGF1_TO_MD, RSA_R_UNKNOWN_MASK_DIGEST);
+        return NULL;
+    }
+    return md;
+}
+
+/*
+ * Convert EVP_PKEY_CTX is PSS mode into corresponding algorithm parameter,
+ * suitable for setting an AlgorithmIdentifier.
+ */
+
+static ASN1_STRING *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx)
+{
+    const EVP_MD *sigmd, *mgf1md;
+    RSA_PSS_PARAMS *pss = NULL;
+    ASN1_STRING *os = NULL;
+    EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx);
+    int saltlen, rv = 0;
+    if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0)
+        goto err;
+    if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0)
+        goto err;
+    if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen))
+        goto err;
+    if (saltlen == -1)
+        saltlen = EVP_MD_size(sigmd);
+    else if (saltlen == -2) {
+        saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
+        if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0)
+            saltlen--;
+    }
+    pss = RSA_PSS_PARAMS_new();
+    if (pss == NULL)
+        goto err;
+    if (saltlen != 20) {
+        pss->saltLength = ASN1_INTEGER_new();
+        if (pss->saltLength == NULL)
+            goto err;
+        if (!ASN1_INTEGER_set(pss->saltLength, saltlen))
+            goto err;
+    }
+    if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd))
+        goto err;
+    if (!rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md))
+        goto err;
+    /* Finally create string with pss parameter encoding. */
+    if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os))
+         goto err;
+    rv = 1;
+ err:
+    RSA_PSS_PARAMS_free(pss);
+    if (rv)
+        return os;
+    ASN1_STRING_free(os);
+    return NULL;
+}
+
+/*
+ * From PSS AlgorithmIdentifier set public key parameters. If pkey isn't NULL
+ * then the EVP_MD_CTX is setup and initialised. If it is NULL parameters are
+ * passed to pkctx instead.
+ */
+
+static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx,
+                          X509_ALGOR *sigalg, EVP_PKEY *pkey)
+{
+    int rv = -1;
+    int saltlen;
+    const EVP_MD *mgf1md = NULL, *md = NULL;
+    RSA_PSS_PARAMS *pss;
+    X509_ALGOR *maskHash;
+    /* Sanity check: make sure it is PSS */
+    if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) {
+        RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_UNSUPPORTED_SIGNATURE_TYPE);
+        return -1;
+    }
+    /* Decode PSS parameters */
+    pss = rsa_pss_decode(sigalg, &maskHash);
+
+    if (pss == NULL) {
+        RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_PSS_PARAMETERS);
+        goto err;
+    }
+    mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash);
+    if (!mgf1md)
+        goto err;
+    md = rsa_algor_to_md(pss->hashAlgorithm);
+    if (!md)
+        goto err;
+
+    if (pss->saltLength) {
+        saltlen = ASN1_INTEGER_get(pss->saltLength);
+
+        /*
+         * Could perform more salt length sanity checks but the main RSA
+         * routines will trap other invalid values anyway.
+         */
+        if (saltlen < 0) {
+            RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_SALT_LENGTH);
+            goto err;
+        }
+    } else
+        saltlen = 20;
+
+    /*
+     * low-level routines support only trailer field 0xbc (value 1) and
+     * PKCS#1 says we should reject any other value anyway.
+     */
+    if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) {
+        RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_TRAILER);
+        goto err;
+    }
+
+    /* We have all parameters now set up context */
+
+    if (pkey) {
+        if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey))
+            goto err;
+    } else {
+        const EVP_MD *checkmd;
+        if (EVP_PKEY_CTX_get_signature_md(pkctx, &checkmd) <= 0)
+            goto err;
+        if (EVP_MD_type(md) != EVP_MD_type(checkmd)) {
+            RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_DIGEST_DOES_NOT_MATCH);
+            goto err;
+        }
+    }
+
+    if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0)
+        goto err;
+
+    if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0)
+        goto err;
+
+    if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
+        goto err;
+    /* Carry on */
+    rv = 1;
+
+ err:
+    RSA_PSS_PARAMS_free(pss);
+    X509_ALGOR_free(maskHash);
+    return rv;
+}
+
+#ifndef OPENSSL_NO_CMS
+static int rsa_cms_verify(CMS_SignerInfo *si)
+{
+    int nid, nid2;
+    X509_ALGOR *alg;
+    EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si);
+    CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg);
+    nid = OBJ_obj2nid(alg->algorithm);
+    if (nid == NID_rsaEncryption)
+        return 1;
+    if (nid == NID_rsassaPss)
+        return rsa_pss_to_ctx(NULL, pkctx, alg, NULL);
+    /* Workaround for some implementation that use a signature OID */
+    if (OBJ_find_sigid_algs(nid, NULL, &nid2)) {
+        if (nid2 == NID_rsaEncryption)
+            return 1;
+    }
+    return 0;
+}
+#endif
+
+/*
+ * Customised RSA item verification routine. This is called when a signature
+ * is encountered requiring special handling. We currently only handle PSS.
+ */
+
+static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+                           X509_ALGOR *sigalg, ASN1_BIT_STRING *sig,
+                           EVP_PKEY *pkey)
+{
+    /* Sanity check: make sure it is PSS */
+    if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) {
+        RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE);
+        return -1;
+    }
+    if (rsa_pss_to_ctx(ctx, NULL, sigalg, pkey) > 0) {
+        /* Carry on */
+        return 2;
+    }
+    return -1;
+}
+
+#ifndef OPENSSL_NO_CMS
+static int rsa_cms_sign(CMS_SignerInfo *si)
+{
+    int pad_mode = RSA_PKCS1_PADDING;
+    X509_ALGOR *alg;
+    EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si);
+    ASN1_STRING *os = NULL;
+    CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg);
+    if (pkctx) {
+        if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
+            return 0;
+    }
+    if (pad_mode == RSA_PKCS1_PADDING) {
+        X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
+        return 1;
+    }
+    /* We don't support it */
+    if (pad_mode != RSA_PKCS1_PSS_PADDING)
+        return 0;
+    os = rsa_ctx_to_pss(pkctx);
+    if (!os)
+        return 0;
+    X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os);
+    return 1;
+}
+#endif
+
+static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
+                         X509_ALGOR *alg1, X509_ALGOR *alg2,
+                         ASN1_BIT_STRING *sig)
+{
+    int pad_mode;
+    EVP_PKEY_CTX *pkctx = EVP_MD_CTX_pkey_ctx(ctx);
+    if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
+        return 0;
+    if (pad_mode == RSA_PKCS1_PADDING)
+        return 2;
+    if (pad_mode == RSA_PKCS1_PSS_PADDING) {
+        ASN1_STRING *os1 = NULL;
+        os1 = rsa_ctx_to_pss(pkctx);
+        if (!os1)
+            return 0;
+        /* Duplicate parameters if we have to */
+        if (alg2) {
+            ASN1_STRING *os2 = ASN1_STRING_dup(os1);
+            if (!os2) {
+                ASN1_STRING_free(os1);
+                return 0;
+            }
+            X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_rsassaPss),
+                            V_ASN1_SEQUENCE, os2);
+        }
+        X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_rsassaPss),
+                        V_ASN1_SEQUENCE, os1);
+        return 3;
+    }
+    return 2;
+}
+
+#ifndef OPENSSL_NO_CMS
+static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg,
+                                        X509_ALGOR **pmaskHash)
+{
+    RSA_OAEP_PARAMS *pss;
+
+    *pmaskHash = NULL;
+
+    pss = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_OAEP_PARAMS),
+                                    alg->parameter);
+
+    if (!pss)
+        return NULL;
+
+    *pmaskHash = rsa_mgf1_decode(pss->maskGenFunc);
+
+    return pss;
+}
+
+static int rsa_cms_decrypt(CMS_RecipientInfo *ri)
+{
+    EVP_PKEY_CTX *pkctx;
+    X509_ALGOR *cmsalg;
+    int nid;
+    int rv = -1;
+    unsigned char *label = NULL;
+    int labellen = 0;
+    const EVP_MD *mgf1md = NULL, *md = NULL;
+    RSA_OAEP_PARAMS *oaep;
+    X509_ALGOR *maskHash;
+    pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+    if (!pkctx)
+        return 0;
+    if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg))
+        return -1;
+    nid = OBJ_obj2nid(cmsalg->algorithm);
+    if (nid == NID_rsaEncryption)
+        return 1;
+    if (nid != NID_rsaesOaep) {
+        RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_ENCRYPTION_TYPE);
+        return -1;
+    }
+    /* Decode OAEP parameters */
+    oaep = rsa_oaep_decode(cmsalg, &maskHash);
+
+    if (oaep == NULL) {
+        RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_OAEP_PARAMETERS);
+        goto err;
+    }
+
+    mgf1md = rsa_mgf1_to_md(oaep->maskGenFunc, maskHash);
+    if (!mgf1md)
+        goto err;
+    md = rsa_algor_to_md(oaep->hashFunc);
+    if (!md)
+        goto err;
+
+    if (oaep->pSourceFunc) {
+        X509_ALGOR *plab = oaep->pSourceFunc;
+        if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) {
+            RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_LABEL_SOURCE);
+            goto err;
+        }
+        if (plab->parameter->type != V_ASN1_OCTET_STRING) {
+            RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_LABEL);
+            goto err;
+        }
+
+        label = plab->parameter->value.octet_string->data;
+        /* Stop label being freed when OAEP parameters are freed */
+        plab->parameter->value.octet_string->data = NULL;
+        labellen = plab->parameter->value.octet_string->length;
+    }
+
+    if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0)
+        goto err;
+    if (EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, md) <= 0)
+        goto err;
+    if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
+        goto err;
+    if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0)
+        goto err;
+    /* Carry on */
+    rv = 1;
+
+ err:
+    RSA_OAEP_PARAMS_free(oaep);
+    X509_ALGOR_free(maskHash);
+    return rv;
+}
+
+static int rsa_cms_encrypt(CMS_RecipientInfo *ri)
+{
+    const EVP_MD *md, *mgf1md;
+    RSA_OAEP_PARAMS *oaep = NULL;
+    ASN1_STRING *os = NULL;
+    X509_ALGOR *alg;
+    EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+    int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen;
+    unsigned char *label;
+    CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg);
+    if (pkctx) {
+        if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
+            return 0;
+    }
+    if (pad_mode == RSA_PKCS1_PADDING) {
+        X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
+        return 1;
+    }
+    /* Not supported */
+    if (pad_mode != RSA_PKCS1_OAEP_PADDING)
+        return 0;
+    if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx, &md) <= 0)
+        goto err;
+    if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0)
+        goto err;
+    labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx, &label);
+    if (labellen < 0)
+        goto err;
+    oaep = RSA_OAEP_PARAMS_new();
+    if (oaep == NULL)
+        goto err;
+    if (!rsa_md_to_algor(&oaep->hashFunc, md))
+        goto err;
+    if (!rsa_md_to_mgf1(&oaep->maskGenFunc, mgf1md))
+        goto err;
+    if (labellen > 0) {
+        ASN1_OCTET_STRING *los;
+        oaep->pSourceFunc = X509_ALGOR_new();
+        if (oaep->pSourceFunc == NULL)
+            goto err;
+        los = ASN1_OCTET_STRING_new();
+        if (los == NULL)
+            goto err;
+        if (!ASN1_OCTET_STRING_set(los, label, labellen)) {
+            ASN1_OCTET_STRING_free(los);
+            goto err;
+        }
+        X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified),
+                        V_ASN1_OCTET_STRING, los);
+    }
+    /* create string with pss parameter encoding. */
+    if (!ASN1_item_pack(oaep, ASN1_ITEM_rptr(RSA_OAEP_PARAMS), &os))
+         goto err;
+    X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os);
+    os = NULL;
+    rv = 1;
+ err:
+    RSA_OAEP_PARAMS_free(oaep);
+    ASN1_STRING_free(os);
+    return rv;
+}
+#endif
+
+const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[2] = {
+    {
+     EVP_PKEY_RSA,
+     EVP_PKEY_RSA,
+     ASN1_PKEY_SIGPARAM_NULL,
+
+     "RSA",
+     "OpenSSL RSA method",
+
+     rsa_pub_decode,
+     rsa_pub_encode,
+     rsa_pub_cmp,
+     rsa_pub_print,
+
+     rsa_priv_decode,
+     rsa_priv_encode,
+     rsa_priv_print,
+
+     int_rsa_size,
+     rsa_bits,
+     rsa_security_bits,
+
+     0, 0, 0, 0, 0, 0,
+
+     rsa_sig_print,
+     int_rsa_free,
+     rsa_pkey_ctrl,
+     old_rsa_priv_decode,
+     old_rsa_priv_encode,
+     rsa_item_verify,
+     rsa_item_sign},
+
+    {
+     EVP_PKEY_RSA2,
+     EVP_PKEY_RSA,
+     ASN1_PKEY_ALIAS}
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_asn1.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_asn1.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_asn1.c	(revision 331)
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2000-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/x509.h>
+#include <openssl/asn1t.h>
+#include "rsa_locl.h"
+
+/* Override the default free and new methods */
+static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                  void *exarg)
+{
+    if (operation == ASN1_OP_NEW_PRE) {
+        *pval = (ASN1_VALUE *)RSA_new();
+        if (*pval != NULL)
+            return 2;
+        return 0;
+    } else if (operation == ASN1_OP_FREE_PRE) {
+        RSA_free((RSA *)*pval);
+        *pval = NULL;
+        return 2;
+    }
+    return 1;
+}
+
+ASN1_SEQUENCE_cb(RSAPrivateKey, rsa_cb) = {
+        ASN1_SIMPLE(RSA, version, LONG),
+        ASN1_SIMPLE(RSA, n, BIGNUM),
+        ASN1_SIMPLE(RSA, e, BIGNUM),
+        ASN1_SIMPLE(RSA, d, CBIGNUM),
+        ASN1_SIMPLE(RSA, p, CBIGNUM),
+        ASN1_SIMPLE(RSA, q, CBIGNUM),
+        ASN1_SIMPLE(RSA, dmp1, CBIGNUM),
+        ASN1_SIMPLE(RSA, dmq1, CBIGNUM),
+        ASN1_SIMPLE(RSA, iqmp, CBIGNUM)
+} ASN1_SEQUENCE_END_cb(RSA, RSAPrivateKey)
+
+
+ASN1_SEQUENCE_cb(RSAPublicKey, rsa_cb) = {
+        ASN1_SIMPLE(RSA, n, BIGNUM),
+        ASN1_SIMPLE(RSA, e, BIGNUM),
+} ASN1_SEQUENCE_END_cb(RSA, RSAPublicKey)
+
+ASN1_SEQUENCE(RSA_PSS_PARAMS) = {
+        ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0),
+        ASN1_EXP_OPT(RSA_PSS_PARAMS, maskGenAlgorithm, X509_ALGOR,1),
+        ASN1_EXP_OPT(RSA_PSS_PARAMS, saltLength, ASN1_INTEGER,2),
+        ASN1_EXP_OPT(RSA_PSS_PARAMS, trailerField, ASN1_INTEGER,3)
+} ASN1_SEQUENCE_END(RSA_PSS_PARAMS)
+
+IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS)
+
+ASN1_SEQUENCE(RSA_OAEP_PARAMS) = {
+        ASN1_EXP_OPT(RSA_OAEP_PARAMS, hashFunc, X509_ALGOR, 0),
+        ASN1_EXP_OPT(RSA_OAEP_PARAMS, maskGenFunc, X509_ALGOR, 1),
+        ASN1_EXP_OPT(RSA_OAEP_PARAMS, pSourceFunc, X509_ALGOR, 2),
+} ASN1_SEQUENCE_END(RSA_OAEP_PARAMS)
+
+IMPLEMENT_ASN1_FUNCTIONS(RSA_OAEP_PARAMS)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPrivateKey, RSAPrivateKey)
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPublicKey, RSAPublicKey)
+
+RSA *RSAPublicKey_dup(RSA *rsa)
+{
+    return ASN1_item_dup(ASN1_ITEM_rptr(RSAPublicKey), rsa);
+}
+
+RSA *RSAPrivateKey_dup(RSA *rsa)
+{
+    return ASN1_item_dup(ASN1_ITEM_rptr(RSAPrivateKey), rsa);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_chk.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_chk.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_chk.c	(revision 331)
@@ -0,0 +1,156 @@
+/*
+ * Copyright 1999-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 <openssl/bn.h>
+#include <openssl/err.h>
+#include "rsa_locl.h"
+
+int RSA_check_key(const RSA *key)
+{
+    return RSA_check_key_ex(key, NULL);
+}
+
+int RSA_check_key_ex(const RSA *key, BN_GENCB *cb)
+{
+    BIGNUM *i, *j, *k, *l, *m;
+    BN_CTX *ctx;
+    int ret = 1;
+
+    if (key->p == NULL || key->q == NULL || key->n == NULL
+            || key->e == NULL || key->d == NULL) {
+        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_VALUE_MISSING);
+        return 0;
+    }
+
+    i = BN_new();
+    j = BN_new();
+    k = BN_new();
+    l = BN_new();
+    m = BN_new();
+    ctx = BN_CTX_new();
+    if (i == NULL || j == NULL || k == NULL || l == NULL
+            || m == NULL || ctx == NULL) {
+        ret = -1;
+        RSAerr(RSA_F_RSA_CHECK_KEY_EX, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (BN_is_one(key->e)) {
+        ret = 0;
+        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_BAD_E_VALUE);
+    }
+    if (!BN_is_odd(key->e)) {
+        ret = 0;
+        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_BAD_E_VALUE);
+    }
+
+    /* p prime? */
+    if (BN_is_prime_ex(key->p, BN_prime_checks, NULL, cb) != 1) {
+        ret = 0;
+        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_P_NOT_PRIME);
+    }
+
+    /* q prime? */
+    if (BN_is_prime_ex(key->q, BN_prime_checks, NULL, cb) != 1) {
+        ret = 0;
+        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_Q_NOT_PRIME);
+    }
+
+    /* n = p*q? */
+    if (!BN_mul(i, key->p, key->q, ctx)) {
+        ret = -1;
+        goto err;
+    }
+    if (BN_cmp(i, key->n) != 0) {
+        ret = 0;
+        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_N_DOES_NOT_EQUAL_P_Q);
+    }
+
+    /* d*e = 1  mod lcm(p-1,q-1)? */
+    if (!BN_sub(i, key->p, BN_value_one())) {
+        ret = -1;
+        goto err;
+    }
+    if (!BN_sub(j, key->q, BN_value_one())) {
+        ret = -1;
+        goto err;
+    }
+
+    /* now compute k = lcm(i,j) */
+    if (!BN_mul(l, i, j, ctx)) {
+        ret = -1;
+        goto err;
+    }
+    if (!BN_gcd(m, i, j, ctx)) {
+        ret = -1;
+        goto err;
+    }
+    if (!BN_div(k, NULL, l, m, ctx)) { /* remainder is 0 */
+        ret = -1;
+        goto err;
+    }
+    if (!BN_mod_mul(i, key->d, key->e, k, ctx)) {
+        ret = -1;
+        goto err;
+    }
+
+    if (!BN_is_one(i)) {
+        ret = 0;
+        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_D_E_NOT_CONGRUENT_TO_1);
+    }
+
+    if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) {
+        /* dmp1 = d mod (p-1)? */
+        if (!BN_sub(i, key->p, BN_value_one())) {
+            ret = -1;
+            goto err;
+        }
+        if (!BN_mod(j, key->d, i, ctx)) {
+            ret = -1;
+            goto err;
+        }
+        if (BN_cmp(j, key->dmp1) != 0) {
+            ret = 0;
+            RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_DMP1_NOT_CONGRUENT_TO_D);
+        }
+
+        /* dmq1 = d mod (q-1)? */
+        if (!BN_sub(i, key->q, BN_value_one())) {
+            ret = -1;
+            goto err;
+        }
+        if (!BN_mod(j, key->d, i, ctx)) {
+            ret = -1;
+            goto err;
+        }
+        if (BN_cmp(j, key->dmq1) != 0) {
+            ret = 0;
+            RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_DMQ1_NOT_CONGRUENT_TO_D);
+        }
+
+        /* iqmp = q^-1 mod p? */
+        if (!BN_mod_inverse(i, key->q, key->p, ctx)) {
+            ret = -1;
+            goto err;
+        }
+        if (BN_cmp(i, key->iqmp) != 0) {
+            ret = 0;
+            RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_IQMP_NOT_INVERSE_OF_Q);
+        }
+    }
+
+ err:
+    BN_free(i);
+    BN_free(j);
+    BN_free(k);
+    BN_free(l);
+    BN_free(m);
+    BN_CTX_free(ctx);
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_crpt.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_crpt.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_crpt.c	(revision 331)
@@ -0,0 +1,178 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/crypto.h>
+#include "internal/cryptlib.h"
+#include <openssl/lhash.h>
+#include "internal/bn_int.h"
+#include <openssl/rand.h>
+#include "rsa_locl.h"
+
+int RSA_bits(const RSA *r)
+{
+    return (BN_num_bits(r->n));
+}
+
+int RSA_size(const RSA *r)
+{
+    return (BN_num_bytes(r->n));
+}
+
+int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
+                       RSA *rsa, int padding)
+{
+    return (rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding));
+}
+
+int RSA_private_encrypt(int flen, const unsigned char *from,
+                        unsigned char *to, RSA *rsa, int padding)
+{
+    return (rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding));
+}
+
+int RSA_private_decrypt(int flen, const unsigned char *from,
+                        unsigned char *to, RSA *rsa, int padding)
+{
+    return (rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding));
+}
+
+int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
+                       RSA *rsa, int padding)
+{
+    return (rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding));
+}
+
+int RSA_flags(const RSA *r)
+{
+    return ((r == NULL) ? 0 : r->meth->flags);
+}
+
+void RSA_blinding_off(RSA *rsa)
+{
+    BN_BLINDING_free(rsa->blinding);
+    rsa->blinding = NULL;
+    rsa->flags &= ~RSA_FLAG_BLINDING;
+    rsa->flags |= RSA_FLAG_NO_BLINDING;
+}
+
+int RSA_blinding_on(RSA *rsa, BN_CTX *ctx)
+{
+    int ret = 0;
+
+    if (rsa->blinding != NULL)
+        RSA_blinding_off(rsa);
+
+    rsa->blinding = RSA_setup_blinding(rsa, ctx);
+    if (rsa->blinding == NULL)
+        goto err;
+
+    rsa->flags |= RSA_FLAG_BLINDING;
+    rsa->flags &= ~RSA_FLAG_NO_BLINDING;
+    ret = 1;
+ err:
+    return (ret);
+}
+
+static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p,
+                                  const BIGNUM *q, BN_CTX *ctx)
+{
+    BIGNUM *ret = NULL, *r0, *r1, *r2;
+
+    if (d == NULL || p == NULL || q == NULL)
+        return NULL;
+
+    BN_CTX_start(ctx);
+    r0 = BN_CTX_get(ctx);
+    r1 = BN_CTX_get(ctx);
+    r2 = BN_CTX_get(ctx);
+    if (r2 == NULL)
+        goto err;
+
+    if (!BN_sub(r1, p, BN_value_one()))
+        goto err;
+    if (!BN_sub(r2, q, BN_value_one()))
+        goto err;
+    if (!BN_mul(r0, r1, r2, ctx))
+        goto err;
+
+    ret = BN_mod_inverse(NULL, d, r0, ctx);
+ err:
+    BN_CTX_end(ctx);
+    return ret;
+}
+
+BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
+{
+    BIGNUM *e;
+    BN_CTX *ctx;
+    BN_BLINDING *ret = NULL;
+
+    if (in_ctx == NULL) {
+        if ((ctx = BN_CTX_new()) == NULL)
+            return 0;
+    } else
+        ctx = in_ctx;
+
+    BN_CTX_start(ctx);
+    e = BN_CTX_get(ctx);
+    if (e == NULL) {
+        RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (rsa->e == NULL) {
+        e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx);
+        if (e == NULL) {
+            RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT);
+            goto err;
+        }
+    } else
+        e = rsa->e;
+
+    if ((RAND_status() == 0) && rsa->d != NULL
+        && bn_get_words(rsa->d) != NULL) {
+        /*
+         * if PRNG is not properly seeded, resort to secret exponent as
+         * unpredictable seed
+         */
+        RAND_add(bn_get_words(rsa->d), bn_get_dmax(rsa->d) * sizeof(BN_ULONG),
+                 0.0);
+    }
+
+    {
+        BIGNUM *n = BN_new();
+
+        if (n == NULL) {
+            RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME);
+
+        ret = BN_BLINDING_create_param(NULL, e, n, ctx, rsa->meth->bn_mod_exp,
+                                       rsa->_method_mod_n);
+        /* We MUST free n before any further use of rsa->n */
+        BN_free(n);
+    }
+    if (ret == NULL) {
+        RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB);
+        goto err;
+    }
+
+    BN_BLINDING_set_current_thread(ret);
+
+ err:
+    BN_CTX_end(ctx);
+    if (ctx != in_ctx)
+        BN_CTX_free(ctx);
+    if (e != rsa->e)
+        BN_free(e);
+
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_depr.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_depr.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_depr.c	(revision 331)
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2002-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
+ */
+
+/*
+ * NB: This file contains deprecated functions (compatibility wrappers to the
+ * "new" versions).
+ */
+
+#include <openssl/opensslconf.h>
+#if OPENSSL_API_COMPAT >= 0x00908000L
+NON_EMPTY_TRANSLATION_UNIT
+
+#else
+
+# include <stdio.h>
+# include <time.h>
+# include "internal/cryptlib.h"
+# include <openssl/bn.h>
+# include <openssl/rsa.h>
+
+RSA *RSA_generate_key(int bits, unsigned long e_value,
+                      void (*callback) (int, int, void *), void *cb_arg)
+{
+    int i;
+    BN_GENCB *cb = BN_GENCB_new();
+    RSA *rsa = RSA_new();
+    BIGNUM *e = BN_new();
+
+    if (cb == NULL || rsa == NULL || e == NULL)
+        goto err;
+
+    /*
+     * The problem is when building with 8, 16, or 32 BN_ULONG, unsigned long
+     * can be larger
+     */
+    for (i = 0; i < (int)sizeof(unsigned long) * 8; i++) {
+        if (e_value & (1UL << i))
+            if (BN_set_bit(e, i) == 0)
+                goto err;
+    }
+
+    BN_GENCB_set_old(cb, callback, cb_arg);
+
+    if (RSA_generate_key_ex(rsa, bits, e, cb)) {
+        BN_free(e);
+        BN_GENCB_free(cb);
+        return rsa;
+    }
+ err:
+    BN_free(e);
+    RSA_free(rsa);
+    BN_GENCB_free(cb);
+    return 0;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_err.c	(revision 331)
@@ -0,0 +1,185 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/rsa.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_RSA,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_RSA,0,reason)
+
+static ERR_STRING_DATA RSA_str_functs[] = {
+    {ERR_FUNC(RSA_F_CHECK_PADDING_MD), "check_padding_md"},
+    {ERR_FUNC(RSA_F_ENCODE_PKCS1), "encode_pkcs1"},
+    {ERR_FUNC(RSA_F_INT_RSA_VERIFY), "int_rsa_verify"},
+    {ERR_FUNC(RSA_F_OLD_RSA_PRIV_DECODE), "old_rsa_priv_decode"},
+    {ERR_FUNC(RSA_F_PKEY_RSA_CTRL), "pkey_rsa_ctrl"},
+    {ERR_FUNC(RSA_F_PKEY_RSA_CTRL_STR), "pkey_rsa_ctrl_str"},
+    {ERR_FUNC(RSA_F_PKEY_RSA_SIGN), "pkey_rsa_sign"},
+    {ERR_FUNC(RSA_F_PKEY_RSA_VERIFY), "pkey_rsa_verify"},
+    {ERR_FUNC(RSA_F_PKEY_RSA_VERIFYRECOVER), "pkey_rsa_verifyrecover"},
+    {ERR_FUNC(RSA_F_RSA_ALGOR_TO_MD), "rsa_algor_to_md"},
+    {ERR_FUNC(RSA_F_RSA_BUILTIN_KEYGEN), "rsa_builtin_keygen"},
+    {ERR_FUNC(RSA_F_RSA_CHECK_KEY), "RSA_check_key"},
+    {ERR_FUNC(RSA_F_RSA_CHECK_KEY_EX), "RSA_check_key_ex"},
+    {ERR_FUNC(RSA_F_RSA_CMS_DECRYPT), "rsa_cms_decrypt"},
+    {ERR_FUNC(RSA_F_RSA_ITEM_VERIFY), "rsa_item_verify"},
+    {ERR_FUNC(RSA_F_RSA_METH_DUP), "RSA_meth_dup"},
+    {ERR_FUNC(RSA_F_RSA_METH_NEW), "RSA_meth_new"},
+    {ERR_FUNC(RSA_F_RSA_METH_SET1_NAME), "RSA_meth_set1_name"},
+    {ERR_FUNC(RSA_F_RSA_MGF1_TO_MD), "rsa_mgf1_to_md"},
+    {ERR_FUNC(RSA_F_RSA_NEW_METHOD), "RSA_new_method"},
+    {ERR_FUNC(RSA_F_RSA_NULL), "RSA_NULL"},
+    {ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_DECRYPT), "RSA_null_private_decrypt"},
+    {ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_ENCRYPT), "RSA_null_private_encrypt"},
+    {ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_DECRYPT), "RSA_null_public_decrypt"},
+    {ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_ENCRYPT), "RSA_null_public_encrypt"},
+    {ERR_FUNC(RSA_F_RSA_OSSL_PRIVATE_DECRYPT), "rsa_ossl_private_decrypt"},
+    {ERR_FUNC(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT), "rsa_ossl_private_encrypt"},
+    {ERR_FUNC(RSA_F_RSA_OSSL_PUBLIC_DECRYPT), "rsa_ossl_public_decrypt"},
+    {ERR_FUNC(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT), "rsa_ossl_public_encrypt"},
+    {ERR_FUNC(RSA_F_RSA_PADDING_ADD_NONE), "RSA_padding_add_none"},
+    {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP),
+     "RSA_padding_add_PKCS1_OAEP"},
+    {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1),
+     "RSA_padding_add_PKCS1_OAEP_mgf1"},
+    {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS), "RSA_padding_add_PKCS1_PSS"},
+    {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1),
+     "RSA_padding_add_PKCS1_PSS_mgf1"},
+    {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1),
+     "RSA_padding_add_PKCS1_type_1"},
+    {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2),
+     "RSA_padding_add_PKCS1_type_2"},
+    {ERR_FUNC(RSA_F_RSA_PADDING_ADD_SSLV23), "RSA_padding_add_SSLv23"},
+    {ERR_FUNC(RSA_F_RSA_PADDING_ADD_X931), "RSA_padding_add_X931"},
+    {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_NONE), "RSA_padding_check_none"},
+    {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP),
+     "RSA_padding_check_PKCS1_OAEP"},
+    {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1),
+     "RSA_padding_check_PKCS1_OAEP_mgf1"},
+    {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1),
+     "RSA_padding_check_PKCS1_type_1"},
+    {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2),
+     "RSA_padding_check_PKCS1_type_2"},
+    {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_SSLV23), "RSA_padding_check_SSLv23"},
+    {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931), "RSA_padding_check_X931"},
+    {ERR_FUNC(RSA_F_RSA_PRINT), "RSA_print"},
+    {ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"},
+    {ERR_FUNC(RSA_F_RSA_PRIV_ENCODE), "rsa_priv_encode"},
+    {ERR_FUNC(RSA_F_RSA_PSS_TO_CTX), "rsa_pss_to_ctx"},
+    {ERR_FUNC(RSA_F_RSA_PUB_DECODE), "rsa_pub_decode"},
+    {ERR_FUNC(RSA_F_RSA_SETUP_BLINDING), "RSA_setup_blinding"},
+    {ERR_FUNC(RSA_F_RSA_SIGN), "RSA_sign"},
+    {ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING),
+     "RSA_sign_ASN1_OCTET_STRING"},
+    {ERR_FUNC(RSA_F_RSA_VERIFY), "RSA_verify"},
+    {ERR_FUNC(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING),
+     "RSA_verify_ASN1_OCTET_STRING"},
+    {ERR_FUNC(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1), "RSA_verify_PKCS1_PSS_mgf1"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA RSA_str_reasons[] = {
+    {ERR_REASON(RSA_R_ALGORITHM_MISMATCH), "algorithm mismatch"},
+    {ERR_REASON(RSA_R_BAD_E_VALUE), "bad e value"},
+    {ERR_REASON(RSA_R_BAD_FIXED_HEADER_DECRYPT), "bad fixed header decrypt"},
+    {ERR_REASON(RSA_R_BAD_PAD_BYTE_COUNT), "bad pad byte count"},
+    {ERR_REASON(RSA_R_BAD_SIGNATURE), "bad signature"},
+    {ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_01), "block type is not 01"},
+    {ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_02), "block type is not 02"},
+    {ERR_REASON(RSA_R_DATA_GREATER_THAN_MOD_LEN),
+     "data greater than mod len"},
+    {ERR_REASON(RSA_R_DATA_TOO_LARGE), "data too large"},
+    {ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),
+     "data too large for key size"},
+    {ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_MODULUS),
+     "data too large for modulus"},
+    {ERR_REASON(RSA_R_DATA_TOO_SMALL), "data too small"},
+    {ERR_REASON(RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE),
+     "data too small for key size"},
+    {ERR_REASON(RSA_R_DIGEST_DOES_NOT_MATCH), "digest does not match"},
+    {ERR_REASON(RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY),
+     "digest too big for rsa key"},
+    {ERR_REASON(RSA_R_DMP1_NOT_CONGRUENT_TO_D), "dmp1 not congruent to d"},
+    {ERR_REASON(RSA_R_DMQ1_NOT_CONGRUENT_TO_D), "dmq1 not congruent to d"},
+    {ERR_REASON(RSA_R_D_E_NOT_CONGRUENT_TO_1), "d e not congruent to 1"},
+    {ERR_REASON(RSA_R_FIRST_OCTET_INVALID), "first octet invalid"},
+    {ERR_REASON(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE),
+     "illegal or unsupported padding mode"},
+    {ERR_REASON(RSA_R_INVALID_DIGEST), "invalid digest"},
+    {ERR_REASON(RSA_R_INVALID_DIGEST_LENGTH), "invalid digest length"},
+    {ERR_REASON(RSA_R_INVALID_HEADER), "invalid header"},
+    {ERR_REASON(RSA_R_INVALID_LABEL), "invalid label"},
+    {ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH), "invalid message length"},
+    {ERR_REASON(RSA_R_INVALID_MGF1_MD), "invalid mgf1 md"},
+    {ERR_REASON(RSA_R_INVALID_OAEP_PARAMETERS), "invalid oaep parameters"},
+    {ERR_REASON(RSA_R_INVALID_PADDING), "invalid padding"},
+    {ERR_REASON(RSA_R_INVALID_PADDING_MODE), "invalid padding mode"},
+    {ERR_REASON(RSA_R_INVALID_PSS_PARAMETERS), "invalid pss parameters"},
+    {ERR_REASON(RSA_R_INVALID_PSS_SALTLEN), "invalid pss saltlen"},
+    {ERR_REASON(RSA_R_INVALID_SALT_LENGTH), "invalid salt length"},
+    {ERR_REASON(RSA_R_INVALID_TRAILER), "invalid trailer"},
+    {ERR_REASON(RSA_R_INVALID_X931_DIGEST), "invalid x931 digest"},
+    {ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q), "iqmp not inverse of q"},
+    {ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL), "key size too small"},
+    {ERR_REASON(RSA_R_LAST_OCTET_INVALID), "last octet invalid"},
+    {ERR_REASON(RSA_R_MODULUS_TOO_LARGE), "modulus too large"},
+    {ERR_REASON(RSA_R_NO_PUBLIC_EXPONENT), "no public exponent"},
+    {ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING),
+     "null before block missing"},
+    {ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q), "n does not equal p q"},
+    {ERR_REASON(RSA_R_OAEP_DECODING_ERROR), "oaep decoding error"},
+    {ERR_REASON(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),
+     "operation not supported for this keytype"},
+    {ERR_REASON(RSA_R_PADDING_CHECK_FAILED), "padding check failed"},
+    {ERR_REASON(RSA_R_PKCS_DECODING_ERROR), "pkcs decoding error"},
+    {ERR_REASON(RSA_R_P_NOT_PRIME), "p not prime"},
+    {ERR_REASON(RSA_R_Q_NOT_PRIME), "q not prime"},
+    {ERR_REASON(RSA_R_RSA_OPERATIONS_NOT_SUPPORTED),
+     "rsa operations not supported"},
+    {ERR_REASON(RSA_R_SLEN_CHECK_FAILED), "salt length check failed"},
+    {ERR_REASON(RSA_R_SLEN_RECOVERY_FAILED), "salt length recovery failed"},
+    {ERR_REASON(RSA_R_SSLV3_ROLLBACK_ATTACK), "sslv3 rollback attack"},
+    {ERR_REASON(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),
+     "the asn1 object identifier is not known for this md"},
+    {ERR_REASON(RSA_R_UNKNOWN_ALGORITHM_TYPE), "unknown algorithm type"},
+    {ERR_REASON(RSA_R_UNKNOWN_DIGEST), "unknown digest"},
+    {ERR_REASON(RSA_R_UNKNOWN_MASK_DIGEST), "unknown mask digest"},
+    {ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE), "unknown padding type"},
+    {ERR_REASON(RSA_R_UNSUPPORTED_ENCRYPTION_TYPE),
+     "unsupported encryption type"},
+    {ERR_REASON(RSA_R_UNSUPPORTED_LABEL_SOURCE), "unsupported label source"},
+    {ERR_REASON(RSA_R_UNSUPPORTED_MASK_ALGORITHM),
+     "unsupported mask algorithm"},
+    {ERR_REASON(RSA_R_UNSUPPORTED_MASK_PARAMETER),
+     "unsupported mask parameter"},
+    {ERR_REASON(RSA_R_UNSUPPORTED_SIGNATURE_TYPE),
+     "unsupported signature type"},
+    {ERR_REASON(RSA_R_VALUE_MISSING), "value missing"},
+    {ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_RSA_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(RSA_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, RSA_str_functs);
+        ERR_load_strings(0, RSA_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_gen.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_gen.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_gen.c	(revision 331)
@@ -0,0 +1,199 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*
+ * NB: these functions have been "upgraded", the deprecated versions (which
+ * are compatibility wrappers using these functions) are in rsa_depr.c. -
+ * Geoff
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include "rsa_locl.h"
+
+static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value,
+                              BN_GENCB *cb);
+
+/*
+ * NB: this wrapper would normally be placed in rsa_lib.c and the static
+ * implementation would probably be in rsa_eay.c. Nonetheless, is kept here
+ * so that we don't introduce a new linker dependency. Eg. any application
+ * that wasn't previously linking object code related to key-generation won't
+ * have to now just because key-generation is part of RSA_METHOD.
+ */
+int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
+{
+    if (rsa->meth->rsa_keygen)
+        return rsa->meth->rsa_keygen(rsa, bits, e_value, cb);
+    return rsa_builtin_keygen(rsa, bits, e_value, cb);
+}
+
+static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value,
+                              BN_GENCB *cb)
+{
+    BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp;
+    int bitsp, bitsq, ok = -1, n = 0;
+    BN_CTX *ctx = NULL;
+
+    ctx = BN_CTX_new();
+    if (ctx == NULL)
+        goto err;
+    BN_CTX_start(ctx);
+    r0 = BN_CTX_get(ctx);
+    r1 = BN_CTX_get(ctx);
+    r2 = BN_CTX_get(ctx);
+    r3 = BN_CTX_get(ctx);
+    if (r3 == NULL)
+        goto err;
+
+    bitsp = (bits + 1) / 2;
+    bitsq = bits - bitsp;
+
+    /* We need the RSA components non-NULL */
+    if (!rsa->n && ((rsa->n = BN_new()) == NULL))
+        goto err;
+    if (!rsa->d && ((rsa->d = BN_secure_new()) == NULL))
+        goto err;
+    if (!rsa->e && ((rsa->e = BN_new()) == NULL))
+        goto err;
+    if (!rsa->p && ((rsa->p = BN_secure_new()) == NULL))
+        goto err;
+    if (!rsa->q && ((rsa->q = BN_secure_new()) == NULL))
+        goto err;
+    if (!rsa->dmp1 && ((rsa->dmp1 = BN_secure_new()) == NULL))
+        goto err;
+    if (!rsa->dmq1 && ((rsa->dmq1 = BN_secure_new()) == NULL))
+        goto err;
+    if (!rsa->iqmp && ((rsa->iqmp = BN_secure_new()) == NULL))
+        goto err;
+
+    if (BN_copy(rsa->e, e_value) == NULL)
+        goto err;
+
+    /* generate p and q */
+    for (;;) {
+        if (!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb))
+            goto err;
+        if (!BN_sub(r2, rsa->p, BN_value_one()))
+            goto err;
+        if (!BN_gcd(r1, r2, rsa->e, ctx))
+            goto err;
+        if (BN_is_one(r1))
+            break;
+        if (!BN_GENCB_call(cb, 2, n++))
+            goto err;
+    }
+    if (!BN_GENCB_call(cb, 3, 0))
+        goto err;
+    for (;;) {
+        /*
+         * When generating ridiculously small keys, we can get stuck
+         * continually regenerating the same prime values. Check for this and
+         * bail if it happens 3 times.
+         */
+        unsigned int degenerate = 0;
+        do {
+            if (!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb))
+                goto err;
+        } while ((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3));
+        if (degenerate == 3) {
+            ok = 0;             /* we set our own err */
+            RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL);
+            goto err;
+        }
+        if (!BN_sub(r2, rsa->q, BN_value_one()))
+            goto err;
+        if (!BN_gcd(r1, r2, rsa->e, ctx))
+            goto err;
+        if (BN_is_one(r1))
+            break;
+        if (!BN_GENCB_call(cb, 2, n++))
+            goto err;
+    }
+    if (!BN_GENCB_call(cb, 3, 1))
+        goto err;
+    if (BN_cmp(rsa->p, rsa->q) < 0) {
+        tmp = rsa->p;
+        rsa->p = rsa->q;
+        rsa->q = tmp;
+    }
+
+    /* calculate n */
+    if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx))
+        goto err;
+
+    /* calculate d */
+    if (!BN_sub(r1, rsa->p, BN_value_one()))
+        goto err;               /* p-1 */
+    if (!BN_sub(r2, rsa->q, BN_value_one()))
+        goto err;               /* q-1 */
+    if (!BN_mul(r0, r1, r2, ctx))
+        goto err;               /* (p-1)(q-1) */
+    {
+        BIGNUM *pr0 = BN_new();
+
+        if (pr0 == NULL)
+            goto err;
+        BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
+        if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx)) {
+            BN_free(pr0);
+            goto err;               /* d */
+        }
+        /* We MUST free pr0 before any further use of r0 */
+        BN_free(pr0);
+    }
+
+    {
+        BIGNUM *d = BN_new();
+
+        if (d == NULL)
+            goto err;
+        BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
+
+        if (   /* calculate d mod (p-1) */
+               !BN_mod(rsa->dmp1, d, r1, ctx)
+               /* calculate d mod (q-1) */
+            || !BN_mod(rsa->dmq1, d, r2, ctx)) {
+            BN_free(d);
+            goto err;
+        }
+        /* We MUST free d before any further use of rsa->d */
+        BN_free(d);
+    }
+
+    {
+        BIGNUM *p = BN_new();
+
+        if (p == NULL)
+            goto err;
+        BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
+
+        /* calculate inverse of q mod p */
+        if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx)) {
+            BN_free(p);
+            goto err;
+        }
+        /* We MUST free p before any further use of rsa->p */
+        BN_free(p);
+    }
+
+    ok = 1;
+ err:
+    if (ok == -1) {
+        RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, ERR_LIB_BN);
+        ok = 0;
+    }
+    if (ctx != NULL)
+        BN_CTX_end(ctx);
+    BN_CTX_free(ctx);
+
+    return ok;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_lib.c	(revision 331)
@@ -0,0 +1,310 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/crypto.h>
+#include "internal/cryptlib.h"
+#include <openssl/lhash.h>
+#include "internal/bn_int.h"
+#include <openssl/engine.h>
+#include "rsa_locl.h"
+
+static const RSA_METHOD *default_RSA_meth = NULL;
+
+RSA *RSA_new(void)
+{
+    RSA *r = RSA_new_method(NULL);
+
+    return r;
+}
+
+void RSA_set_default_method(const RSA_METHOD *meth)
+{
+    default_RSA_meth = meth;
+}
+
+const RSA_METHOD *RSA_get_default_method(void)
+{
+    if (default_RSA_meth == NULL) {
+#ifdef RSA_NULL
+        default_RSA_meth = RSA_null_method();
+#else
+        default_RSA_meth = RSA_PKCS1_OpenSSL();
+#endif
+    }
+
+    return default_RSA_meth;
+}
+
+const RSA_METHOD *RSA_get_method(const RSA *rsa)
+{
+    return rsa->meth;
+}
+
+int RSA_set_method(RSA *rsa, const RSA_METHOD *meth)
+{
+    /*
+     * NB: The caller is specifically setting a method, so it's not up to us
+     * to deal with which ENGINE it comes from.
+     */
+    const RSA_METHOD *mtmp;
+    mtmp = rsa->meth;
+    if (mtmp->finish)
+        mtmp->finish(rsa);
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE_finish(rsa->engine);
+    rsa->engine = NULL;
+#endif
+    rsa->meth = meth;
+    if (meth->init)
+        meth->init(rsa);
+    return 1;
+}
+
+RSA *RSA_new_method(ENGINE *engine)
+{
+    RSA *ret = OPENSSL_zalloc(sizeof(*ret));
+
+    if (ret == NULL) {
+        RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    ret->references = 1;
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ret);
+        return NULL;
+    }
+
+    ret->meth = RSA_get_default_method();
+#ifndef OPENSSL_NO_ENGINE
+    ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW;
+    if (engine) {
+        if (!ENGINE_init(engine)) {
+            RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB);
+            goto err;
+        }
+        ret->engine = engine;
+    } else
+        ret->engine = ENGINE_get_default_RSA();
+    if (ret->engine) {
+        ret->meth = ENGINE_get_RSA(ret->engine);
+        if (ret->meth == NULL) {
+            RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB);
+            goto err;
+        }
+    }
+#endif
+
+    ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW;
+    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) {
+        goto err;
+    }
+
+    if ((ret->meth->init != NULL) && !ret->meth->init(ret)) {
+        RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_INIT_FAIL);
+        goto err;
+    }
+
+    return ret;
+
+err:
+    RSA_free(ret);
+    return NULL;
+}
+
+void RSA_free(RSA *r)
+{
+    int i;
+
+    if (r == NULL)
+        return;
+
+    CRYPTO_atomic_add(&r->references, -1, &i, r->lock);
+    REF_PRINT_COUNT("RSA", r);
+    if (i > 0)
+        return;
+    REF_ASSERT_ISNT(i < 0);
+
+    if (r->meth->finish)
+        r->meth->finish(r);
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE_finish(r->engine);
+#endif
+
+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data);
+
+    CRYPTO_THREAD_lock_free(r->lock);
+
+    BN_clear_free(r->n);
+    BN_clear_free(r->e);
+    BN_clear_free(r->d);
+    BN_clear_free(r->p);
+    BN_clear_free(r->q);
+    BN_clear_free(r->dmp1);
+    BN_clear_free(r->dmq1);
+    BN_clear_free(r->iqmp);
+    BN_BLINDING_free(r->blinding);
+    BN_BLINDING_free(r->mt_blinding);
+    OPENSSL_free(r->bignum_data);
+    OPENSSL_free(r);
+}
+
+int RSA_up_ref(RSA *r)
+{
+    int i;
+
+    if (CRYPTO_atomic_add(&r->references, 1, &i, r->lock) <= 0)
+        return 0;
+
+    REF_PRINT_COUNT("RSA", r);
+    REF_ASSERT_ISNT(i < 2);
+    return ((i > 1) ? 1 : 0);
+}
+
+int RSA_set_ex_data(RSA *r, int idx, void *arg)
+{
+    return (CRYPTO_set_ex_data(&r->ex_data, idx, arg));
+}
+
+void *RSA_get_ex_data(const RSA *r, int idx)
+{
+    return (CRYPTO_get_ex_data(&r->ex_data, idx));
+}
+
+int RSA_security_bits(const RSA *rsa)
+{
+    return BN_security_bits(BN_num_bits(rsa->n), -1);
+}
+
+int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
+{
+    /* If the fields n and e in r are NULL, the corresponding input
+     * parameters MUST be non-NULL for n and e.  d may be
+     * left NULL (in case only the public key is used).
+     */
+    if ((r->n == NULL && n == NULL)
+        || (r->e == NULL && e == NULL))
+        return 0;
+
+    if (n != NULL) {
+        BN_free(r->n);
+        r->n = n;
+    }
+    if (e != NULL) {
+        BN_free(r->e);
+        r->e = e;
+    }
+    if (d != NULL) {
+        BN_free(r->d);
+        r->d = d;
+    }
+
+    return 1;
+}
+
+int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
+{
+    /* If the fields p and q in r are NULL, the corresponding input
+     * parameters MUST be non-NULL.
+     */
+    if ((r->p == NULL && p == NULL)
+        || (r->q == NULL && q == NULL))
+        return 0;
+
+    if (p != NULL) {
+        BN_free(r->p);
+        r->p = p;
+    }
+    if (q != NULL) {
+        BN_free(r->q);
+        r->q = q;
+    }
+
+    return 1;
+}
+
+int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
+{
+    /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input
+     * parameters MUST be non-NULL.
+     */
+    if ((r->dmp1 == NULL && dmp1 == NULL)
+        || (r->dmq1 == NULL && dmq1 == NULL)
+        || (r->iqmp == NULL && iqmp == NULL))
+        return 0;
+
+    if (dmp1 != NULL) {
+        BN_free(r->dmp1);
+        r->dmp1 = dmp1;
+    }
+    if (dmq1 != NULL) {
+        BN_free(r->dmq1);
+        r->dmq1 = dmq1;
+    }
+    if (iqmp != NULL) {
+        BN_free(r->iqmp);
+        r->iqmp = iqmp;
+    }
+
+    return 1;
+}
+
+void RSA_get0_key(const RSA *r,
+                  const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
+{
+    if (n != NULL)
+        *n = r->n;
+    if (e != NULL)
+        *e = r->e;
+    if (d != NULL)
+        *d = r->d;
+}
+
+void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
+{
+    if (p != NULL)
+        *p = r->p;
+    if (q != NULL)
+        *q = r->q;
+}
+
+void RSA_get0_crt_params(const RSA *r,
+                         const BIGNUM **dmp1, const BIGNUM **dmq1,
+                         const BIGNUM **iqmp)
+{
+    if (dmp1 != NULL)
+        *dmp1 = r->dmp1;
+    if (dmq1 != NULL)
+        *dmq1 = r->dmq1;
+    if (iqmp != NULL)
+        *iqmp = r->iqmp;
+}
+
+void RSA_clear_flags(RSA *r, int flags)
+{
+    r->flags &= ~flags;
+}
+
+int RSA_test_flags(const RSA *r, int flags)
+{
+    return r->flags & flags;
+}
+
+void RSA_set_flags(RSA *r, int flags)
+{
+    r->flags |= flags;
+}
+
+ENGINE *RSA_get0_engine(const RSA *r)
+{
+    return r->engine;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_locl.h	(revision 331)
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2006-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 <openssl/rsa.h>
+
+struct rsa_st {
+    /*
+     * The first parameter is used to pickup errors where this is passed
+     * instead of aEVP_PKEY, it is set to 0
+     */
+    int pad;
+    long version;
+    const RSA_METHOD *meth;
+    /* functional reference if 'meth' is ENGINE-provided */
+    ENGINE *engine;
+    BIGNUM *n;
+    BIGNUM *e;
+    BIGNUM *d;
+    BIGNUM *p;
+    BIGNUM *q;
+    BIGNUM *dmp1;
+    BIGNUM *dmq1;
+    BIGNUM *iqmp;
+    /* be careful using this if the RSA structure is shared */
+    CRYPTO_EX_DATA ex_data;
+    int references;
+    int flags;
+    /* Used to cache montgomery values */
+    BN_MONT_CTX *_method_mod_n;
+    BN_MONT_CTX *_method_mod_p;
+    BN_MONT_CTX *_method_mod_q;
+    /*
+     * all BIGNUM values are actually in the following data, if it is not
+     * NULL
+     */
+    char *bignum_data;
+    BN_BLINDING *blinding;
+    BN_BLINDING *mt_blinding;
+    CRYPTO_RWLOCK *lock;
+};
+
+struct rsa_meth_st {
+    char *name;
+    int (*rsa_pub_enc) (int flen, const unsigned char *from,
+                        unsigned char *to, RSA *rsa, int padding);
+    int (*rsa_pub_dec) (int flen, const unsigned char *from,
+                        unsigned char *to, RSA *rsa, int padding);
+    int (*rsa_priv_enc) (int flen, const unsigned char *from,
+                         unsigned char *to, RSA *rsa, int padding);
+    int (*rsa_priv_dec) (int flen, const unsigned char *from,
+                         unsigned char *to, RSA *rsa, int padding);
+    /* Can be null */
+    int (*rsa_mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+    /* Can be null */
+    int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+    /* called at new */
+    int (*init) (RSA *rsa);
+    /* called at free */
+    int (*finish) (RSA *rsa);
+    /* RSA_METHOD_FLAG_* things */
+    int flags;
+    /* may be needed! */
+    char *app_data;
+    /*
+     * New sign and verify functions: some libraries don't allow arbitrary
+     * data to be signed/verified: this allows them to be used. Note: for
+     * this to work the RSA_public_decrypt() and RSA_private_encrypt() should
+     * *NOT* be used RSA_sign(), RSA_verify() should be used instead.
+     */
+    int (*rsa_sign) (int type,
+                     const unsigned char *m, unsigned int m_length,
+                     unsigned char *sigret, unsigned int *siglen,
+                     const RSA *rsa);
+    int (*rsa_verify) (int dtype, const unsigned char *m,
+                       unsigned int m_length, const unsigned char *sigbuf,
+                       unsigned int siglen, const RSA *rsa);
+    /*
+     * If this callback is NULL, the builtin software RSA key-gen will be
+     * used. This is for behavioural compatibility whilst the code gets
+     * rewired, but one day it would be nice to assume there are no such
+     * things as "builtin software" implementations.
+     */
+    int (*rsa_keygen) (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
+};
+
+extern int int_rsa_verify(int dtype, const unsigned char *m,
+                          unsigned int m_len, unsigned char *rm,
+                          size_t *prm_len, const unsigned char *sigbuf,
+                          size_t siglen, RSA *rsa);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_meth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_meth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_meth.c	(revision 331)
@@ -0,0 +1,273 @@
+/*
+ * 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 <string.h>
+#include "rsa_locl.h"
+#include <openssl/err.h>
+
+RSA_METHOD *RSA_meth_new(const char *name, int flags)
+{
+    RSA_METHOD *meth = OPENSSL_zalloc(sizeof(*meth));
+
+    if (meth != NULL) {
+        meth->flags = flags;
+
+        meth->name = OPENSSL_strdup(name);
+        if (meth->name != NULL)
+            return meth;
+
+        OPENSSL_free(meth);
+    }
+
+    RSAerr(RSA_F_RSA_METH_NEW, ERR_R_MALLOC_FAILURE);
+    return NULL;
+}
+
+void RSA_meth_free(RSA_METHOD *meth)
+{
+    if (meth != NULL) {
+        OPENSSL_free(meth->name);
+        OPENSSL_free(meth);
+    }
+}
+
+RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth)
+{
+    RSA_METHOD *ret = OPENSSL_malloc(sizeof(*ret));
+
+    if (ret != NULL) {
+        memcpy(ret, meth, sizeof(*meth));
+
+        ret->name = OPENSSL_strdup(meth->name);
+        if (ret->name != NULL)
+            return ret;
+
+        OPENSSL_free(ret);
+    }
+
+    RSAerr(RSA_F_RSA_METH_DUP, ERR_R_MALLOC_FAILURE);
+    return NULL;
+}
+
+const char *RSA_meth_get0_name(const RSA_METHOD *meth)
+{
+    return meth->name;
+}
+
+int RSA_meth_set1_name(RSA_METHOD *meth, const char *name)
+{
+    char *tmpname = OPENSSL_strdup(name);
+
+    if (tmpname == NULL) {
+        RSAerr(RSA_F_RSA_METH_SET1_NAME, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    OPENSSL_free(meth->name);
+    meth->name = tmpname;
+
+    return 1;
+}
+
+int RSA_meth_get_flags(RSA_METHOD *meth)
+{
+    return meth->flags;
+}
+
+int RSA_meth_set_flags(RSA_METHOD *meth, int flags)
+{
+    meth->flags = flags;
+    return 1;
+}
+
+void *RSA_meth_get0_app_data(const RSA_METHOD *meth)
+{
+    return meth->app_data;
+}
+
+int RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data)
+{
+    meth->app_data = app_data;
+    return 1;
+}
+
+int (*RSA_meth_get_pub_enc(const RSA_METHOD *meth))
+    (int flen, const unsigned char *from,
+     unsigned char *to, RSA *rsa, int padding)
+{
+    return meth->rsa_pub_enc;
+}
+
+int RSA_meth_set_pub_enc(RSA_METHOD *meth,
+                         int (*pub_enc) (int flen, const unsigned char *from,
+                                         unsigned char *to, RSA *rsa,
+                                         int padding))
+{
+    meth->rsa_pub_enc = pub_enc;
+    return 1;
+}
+
+int (*RSA_meth_get_pub_dec(const RSA_METHOD *meth))
+    (int flen, const unsigned char *from,
+     unsigned char *to, RSA *rsa, int padding)
+{
+    return meth->rsa_pub_dec;
+}
+
+int RSA_meth_set_pub_dec(RSA_METHOD *meth,
+                         int (*pub_dec) (int flen, const unsigned char *from,
+                                         unsigned char *to, RSA *rsa,
+                                         int padding))
+{
+    meth->rsa_pub_dec = pub_dec;
+    return 1;
+}
+
+int (*RSA_meth_get_priv_enc(const RSA_METHOD *meth))
+    (int flen, const unsigned char *from,
+     unsigned char *to, RSA *rsa, int padding)
+{
+    return meth->rsa_priv_enc;
+}
+
+int RSA_meth_set_priv_enc(RSA_METHOD *meth,
+                          int (*priv_enc) (int flen, const unsigned char *from,
+                                           unsigned char *to, RSA *rsa,
+                                           int padding))
+{
+    meth->rsa_priv_enc = priv_enc;
+    return 1;
+}
+
+int (*RSA_meth_get_priv_dec(const RSA_METHOD *meth))
+    (int flen, const unsigned char *from,
+     unsigned char *to, RSA *rsa, int padding)
+{
+    return meth->rsa_priv_dec;
+}
+
+int RSA_meth_set_priv_dec(RSA_METHOD *meth,
+                          int (*priv_dec) (int flen, const unsigned char *from,
+                                           unsigned char *to, RSA *rsa,
+                                           int padding))
+{
+    meth->rsa_priv_dec = priv_dec;
+    return 1;
+}
+
+    /* Can be null */
+int (*RSA_meth_get_mod_exp(const RSA_METHOD *meth))
+    (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+{
+    return meth->rsa_mod_exp;
+}
+
+int RSA_meth_set_mod_exp(RSA_METHOD *meth,
+                         int (*mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa,
+                                         BN_CTX *ctx))
+{
+    meth->rsa_mod_exp = mod_exp;
+    return 1;
+}
+
+    /* Can be null */
+int (*RSA_meth_get_bn_mod_exp(const RSA_METHOD *meth))
+    (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+     const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
+{
+    return meth->bn_mod_exp;
+}
+
+int RSA_meth_set_bn_mod_exp(RSA_METHOD *meth,
+                            int (*bn_mod_exp) (BIGNUM *r,
+                                               const BIGNUM *a,
+                                               const BIGNUM *p,
+                                               const BIGNUM *m,
+                                               BN_CTX *ctx,
+                                               BN_MONT_CTX *m_ctx))
+{
+    meth->bn_mod_exp = bn_mod_exp;
+    return 1;
+}
+
+    /* called at new */
+int (*RSA_meth_get_init(const RSA_METHOD *meth)) (RSA *rsa)
+{
+    return meth->init;
+}
+
+int RSA_meth_set_init(RSA_METHOD *meth, int (*init) (RSA *rsa))
+{
+    meth->init = init;
+    return 1;
+}
+
+    /* called at free */
+int (*RSA_meth_get_finish(const RSA_METHOD *meth)) (RSA *rsa)
+{
+    return meth->finish;
+}
+
+int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa))
+{
+    meth->finish = finish;
+    return 1;
+}
+
+int (*RSA_meth_get_sign(const RSA_METHOD *meth))
+    (int type,
+     const unsigned char *m, unsigned int m_length,
+     unsigned char *sigret, unsigned int *siglen,
+     const RSA *rsa)
+{
+    return meth->rsa_sign;
+}
+
+int RSA_meth_set_sign(RSA_METHOD *meth,
+                      int (*sign) (int type, const unsigned char *m,
+                                   unsigned int m_length,
+                                   unsigned char *sigret, unsigned int *siglen,
+                                   const RSA *rsa))
+{
+    meth->rsa_sign = sign;
+    return 1;
+}
+
+int (*RSA_meth_get_verify(const RSA_METHOD *meth))
+    (int dtype, const unsigned char *m,
+     unsigned int m_length, const unsigned char *sigbuf,
+     unsigned int siglen, const RSA *rsa)
+{
+    return meth->rsa_verify;
+}
+
+int RSA_meth_set_verify(RSA_METHOD *meth,
+                        int (*verify) (int dtype, const unsigned char *m,
+                                       unsigned int m_length,
+                                       const unsigned char *sigbuf,
+                                       unsigned int siglen, const RSA *rsa))
+{
+    meth->rsa_verify = verify;
+    return 1;
+}
+
+int (*RSA_meth_get_keygen(const RSA_METHOD *meth))
+    (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb)
+{
+    return meth->rsa_keygen;
+}
+
+int RSA_meth_set_keygen(RSA_METHOD *meth,
+                        int (*keygen) (RSA *rsa, int bits, BIGNUM *e,
+                                       BN_GENCB *cb))
+{
+    meth->rsa_keygen = keygen;
+    return 1;
+}
+
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_none.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_none.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_none.c	(revision 331)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 1995-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 "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+
+int RSA_padding_add_none(unsigned char *to, int tlen,
+                         const unsigned char *from, int flen)
+{
+    if (flen > tlen) {
+        RSAerr(RSA_F_RSA_PADDING_ADD_NONE, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+        return (0);
+    }
+
+    if (flen < tlen) {
+        RSAerr(RSA_F_RSA_PADDING_ADD_NONE, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE);
+        return (0);
+    }
+
+    memcpy(to, from, (unsigned int)flen);
+    return (1);
+}
+
+int RSA_padding_check_none(unsigned char *to, int tlen,
+                           const unsigned char *from, int flen, int num)
+{
+
+    if (flen > tlen) {
+        RSAerr(RSA_F_RSA_PADDING_CHECK_NONE, RSA_R_DATA_TOO_LARGE);
+        return (-1);
+    }
+
+    memset(to, 0, tlen - flen);
+    memcpy(to + tlen - flen, from, flen);
+    return (tlen);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_null.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_null.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_null.c	(revision 331)
@@ -0,0 +1,93 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include "rsa_locl.h"
+
+/*
+ * This is a dummy RSA implementation that just returns errors when called.
+ * It is designed to allow some RSA functions to work while stopping those
+ * covered by the RSA patent. That is RSA, encryption, decryption, signing
+ * and verify is not allowed but RSA key generation, key checking and other
+ * operations (like storing RSA keys) are permitted.
+ */
+
+static int RSA_null_public_encrypt(int flen, const unsigned char *from,
+                                   unsigned char *to, RSA *rsa, int padding);
+static int RSA_null_private_encrypt(int flen, const unsigned char *from,
+                                    unsigned char *to, RSA *rsa, int padding);
+static int RSA_null_public_decrypt(int flen, const unsigned char *from,
+                                   unsigned char *to, RSA *rsa, int padding);
+static int RSA_null_private_decrypt(int flen, const unsigned char *from,
+                                    unsigned char *to, RSA *rsa, int padding);
+static int RSA_null_init(RSA *rsa);
+static int RSA_null_finish(RSA *rsa);
+static RSA_METHOD rsa_null_meth = {
+    "Null RSA",
+    RSA_null_public_encrypt,
+    RSA_null_public_decrypt,
+    RSA_null_private_encrypt,
+    RSA_null_private_decrypt,
+    NULL,
+    NULL,
+    RSA_null_init,
+    RSA_null_finish,
+    0,
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
+
+const RSA_METHOD *RSA_null_method(void)
+{
+    return (&rsa_null_meth);
+}
+
+static int RSA_null_public_encrypt(int flen, const unsigned char *from,
+                                   unsigned char *to, RSA *rsa, int padding)
+{
+    RSAerr(RSA_F_RSA_NULL_PUBLIC_ENCRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+    return -1;
+}
+
+static int RSA_null_private_encrypt(int flen, const unsigned char *from,
+                                    unsigned char *to, RSA *rsa, int padding)
+{
+    RSAerr(RSA_F_RSA_NULL_PRIVATE_ENCRYPT,
+           RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+    return -1;
+}
+
+static int RSA_null_private_decrypt(int flen, const unsigned char *from,
+                                    unsigned char *to, RSA *rsa, int padding)
+{
+    RSAerr(RSA_F_RSA_NULL_PRIVATE_DECRYPT,
+           RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+    return -1;
+}
+
+static int RSA_null_public_decrypt(int flen, const unsigned char *from,
+                                   unsigned char *to, RSA *rsa, int padding)
+{
+    RSAerr(RSA_F_RSA_NULL_PUBLIC_DECRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
+    return -1;
+}
+
+static int RSA_null_init(RSA *rsa)
+{
+    return (1);
+}
+
+static int RSA_null_finish(RSA *rsa)
+{
+    return (1);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_oaep.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_oaep.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_oaep.c	(revision 331)
@@ -0,0 +1,286 @@
+/*
+ * Copyright 1999-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
+ */
+
+/* EME-OAEP as defined in RFC 2437 (PKCS #1 v2.0) */
+
+/*
+ * See Victor Shoup, "OAEP reconsidered," Nov. 2000, <URL:
+ * http://www.shoup.net/papers/oaep.ps.Z> for problems with the security
+ * proof for the original OAEP scheme, which EME-OAEP is based on. A new
+ * proof can be found in E. Fujisaki, T. Okamoto, D. Pointcheval, J. Stern,
+ * "RSA-OEAP is Still Alive!", Dec. 2000, <URL:
+ * http://eprint.iacr.org/2000/061/>. The new proof has stronger requirements
+ * for the underlying permutation: "partial-one-wayness" instead of
+ * one-wayness.  For the RSA function, this is an equivalent notion.
+ */
+
+#include "internal/constant_time_locl.h"
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+#include "rsa_locl.h"
+
+int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
+                               const unsigned char *from, int flen,
+                               const unsigned char *param, int plen)
+{
+    return RSA_padding_add_PKCS1_OAEP_mgf1(to, tlen, from, flen,
+                                           param, plen, NULL, NULL);
+}
+
+int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
+                                    const unsigned char *from, int flen,
+                                    const unsigned char *param, int plen,
+                                    const EVP_MD *md, const EVP_MD *mgf1md)
+{
+    int i, emlen = tlen - 1;
+    unsigned char *db, *seed;
+    unsigned char *dbmask, seedmask[EVP_MAX_MD_SIZE];
+    int mdlen;
+
+    if (md == NULL)
+        md = EVP_sha1();
+    if (mgf1md == NULL)
+        mgf1md = md;
+
+    mdlen = EVP_MD_size(md);
+
+    if (flen > emlen - 2 * mdlen - 1) {
+        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1,
+               RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+        return 0;
+    }
+
+    if (emlen < 2 * mdlen + 1) {
+        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1,
+               RSA_R_KEY_SIZE_TOO_SMALL);
+        return 0;
+    }
+
+    to[0] = 0;
+    seed = to + 1;
+    db = to + mdlen + 1;
+
+    if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL))
+        return 0;
+    memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1);
+    db[emlen - flen - mdlen - 1] = 0x01;
+    memcpy(db + emlen - flen - mdlen, from, (unsigned int)flen);
+    if (RAND_bytes(seed, mdlen) <= 0)
+        return 0;
+#ifdef PKCS_TESTVECT
+    memcpy(seed,
+           "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2\xf0\x6c\xb5\x8f",
+           20);
+#endif
+
+    dbmask = OPENSSL_malloc(emlen - mdlen);
+    if (dbmask == NULL) {
+        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    if (PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md) < 0)
+        goto err;
+    for (i = 0; i < emlen - mdlen; i++)
+        db[i] ^= dbmask[i];
+
+    if (PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md) < 0)
+        goto err;
+    for (i = 0; i < mdlen; i++)
+        seed[i] ^= seedmask[i];
+
+    OPENSSL_free(dbmask);
+    return 1;
+
+ err:
+    OPENSSL_free(dbmask);
+    return 0;
+}
+
+int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
+                                 const unsigned char *from, int flen, int num,
+                                 const unsigned char *param, int plen)
+{
+    return RSA_padding_check_PKCS1_OAEP_mgf1(to, tlen, from, flen, num,
+                                             param, plen, NULL, NULL);
+}
+
+int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
+                                      const unsigned char *from, int flen,
+                                      int num, const unsigned char *param,
+                                      int plen, const EVP_MD *md,
+                                      const EVP_MD *mgf1md)
+{
+    int i, dblen, mlen = -1, one_index = 0, msg_index;
+    unsigned int good, found_one_byte;
+    const unsigned char *maskedseed, *maskeddb;
+    /*
+     * |em| is the encoded message, zero-padded to exactly |num| bytes: em =
+     * Y || maskedSeed || maskedDB
+     */
+    unsigned char *db = NULL, *em = NULL, seed[EVP_MAX_MD_SIZE],
+        phash[EVP_MAX_MD_SIZE];
+    int mdlen;
+
+    if (md == NULL)
+        md = EVP_sha1();
+    if (mgf1md == NULL)
+        mgf1md = md;
+
+    mdlen = EVP_MD_size(md);
+
+    if (tlen <= 0 || flen <= 0)
+        return -1;
+    /*
+     * |num| is the length of the modulus; |flen| is the length of the
+     * encoded message. Therefore, for any |from| that was obtained by
+     * decrypting a ciphertext, we must have |flen| <= |num|. Similarly,
+     * num < 2 * mdlen + 2 must hold for the modulus irrespective of
+     * the ciphertext, see PKCS #1 v2.2, section 7.1.2.
+     * This does not leak any side-channel information.
+     */
+    if (num < flen || num < 2 * mdlen + 2)
+        goto decoding_err;
+
+    dblen = num - mdlen - 1;
+    db = OPENSSL_malloc(dblen);
+    em = OPENSSL_malloc(num);
+    if (db == NULL || em == NULL) {
+        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE);
+        goto cleanup;
+    }
+
+    /*
+     * Always do this zero-padding copy (even when num == flen) to avoid
+     * leaking that information. The copy still leaks some side-channel
+     * information, but it's impossible to have a fixed  memory access
+     * pattern since we can't read out of the bounds of |from|.
+     *
+     * TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL.
+     */
+    memset(em, 0, num);
+    memcpy(em + num - flen, from, flen);
+
+    /*
+     * The first byte must be zero, however we must not leak if this is
+     * true. See James H. Manger, "A Chosen Ciphertext  Attack on RSA
+     * Optimal Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001).
+     */
+    good = constant_time_is_zero(em[0]);
+
+    maskedseed = em + 1;
+    maskeddb = em + 1 + mdlen;
+
+    if (PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md))
+        goto cleanup;
+    for (i = 0; i < mdlen; i++)
+        seed[i] ^= maskedseed[i];
+
+    if (PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md))
+        goto cleanup;
+    for (i = 0; i < dblen; i++)
+        db[i] ^= maskeddb[i];
+
+    if (!EVP_Digest((void *)param, plen, phash, NULL, md, NULL))
+        goto cleanup;
+
+    good &= constant_time_is_zero(CRYPTO_memcmp(db, phash, mdlen));
+
+    found_one_byte = 0;
+    for (i = mdlen; i < dblen; i++) {
+        /*
+         * Padding consists of a number of 0-bytes, followed by a 1.
+         */
+        unsigned int equals1 = constant_time_eq(db[i], 1);
+        unsigned int equals0 = constant_time_is_zero(db[i]);
+        one_index = constant_time_select_int(~found_one_byte & equals1,
+                                             i, one_index);
+        found_one_byte |= equals1;
+        good &= (found_one_byte | equals0);
+    }
+
+    good &= found_one_byte;
+
+    /*
+     * At this point |good| is zero unless the plaintext was valid,
+     * so plaintext-awareness ensures timing side-channels are no longer a
+     * concern.
+     */
+    if (!good)
+        goto decoding_err;
+
+    msg_index = one_index + 1;
+    mlen = dblen - msg_index;
+
+    if (tlen < mlen) {
+        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, RSA_R_DATA_TOO_LARGE);
+        mlen = -1;
+    } else {
+        memcpy(to, db + msg_index, mlen);
+        goto cleanup;
+    }
+
+ decoding_err:
+    /*
+     * To avoid chosen ciphertext attacks, the error message should not
+     * reveal which kind of decoding error happened.
+     */
+    RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1,
+           RSA_R_OAEP_DECODING_ERROR);
+ cleanup:
+    OPENSSL_free(db);
+    OPENSSL_free(em);
+    return mlen;
+}
+
+int PKCS1_MGF1(unsigned char *mask, long len,
+               const unsigned char *seed, long seedlen, const EVP_MD *dgst)
+{
+    long i, outlen = 0;
+    unsigned char cnt[4];
+    EVP_MD_CTX *c = EVP_MD_CTX_new();
+    unsigned char md[EVP_MAX_MD_SIZE];
+    int mdlen;
+    int rv = -1;
+
+    if (c == NULL)
+        goto err;
+    mdlen = EVP_MD_size(dgst);
+    if (mdlen < 0)
+        goto err;
+    for (i = 0; outlen < len; i++) {
+        cnt[0] = (unsigned char)((i >> 24) & 255);
+        cnt[1] = (unsigned char)((i >> 16) & 255);
+        cnt[2] = (unsigned char)((i >> 8)) & 255;
+        cnt[3] = (unsigned char)(i & 255);
+        if (!EVP_DigestInit_ex(c, dgst, NULL)
+            || !EVP_DigestUpdate(c, seed, seedlen)
+            || !EVP_DigestUpdate(c, cnt, 4))
+            goto err;
+        if (outlen + mdlen <= len) {
+            if (!EVP_DigestFinal_ex(c, mask + outlen, NULL))
+                goto err;
+            outlen += mdlen;
+        } else {
+            if (!EVP_DigestFinal_ex(c, md, NULL))
+                goto err;
+            memcpy(mask + outlen, md, len - outlen);
+            outlen = len;
+        }
+    }
+    rv = 0;
+ err:
+    EVP_MD_CTX_free(c);
+    return rv;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_ossl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_ossl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_ossl.c	(revision 331)
@@ -0,0 +1,790 @@
+/*
+ * Copyright 1995-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 "internal/cryptlib.h"
+#include "internal/bn_int.h"
+#include "rsa_locl.h"
+
+#ifndef RSA_NULL
+
+static int rsa_ossl_public_encrypt(int flen, const unsigned char *from,
+                                  unsigned char *to, RSA *rsa, int padding);
+static int rsa_ossl_private_encrypt(int flen, const unsigned char *from,
+                                   unsigned char *to, RSA *rsa, int padding);
+static int rsa_ossl_public_decrypt(int flen, const unsigned char *from,
+                                  unsigned char *to, RSA *rsa, int padding);
+static int rsa_ossl_private_decrypt(int flen, const unsigned char *from,
+                                   unsigned char *to, RSA *rsa, int padding);
+static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa,
+                           BN_CTX *ctx);
+static int rsa_ossl_init(RSA *rsa);
+static int rsa_ossl_finish(RSA *rsa);
+static RSA_METHOD rsa_pkcs1_ossl_meth = {
+    "OpenSSL PKCS#1 RSA (from Eric Young)",
+    rsa_ossl_public_encrypt,
+    rsa_ossl_public_decrypt,     /* signature verification */
+    rsa_ossl_private_encrypt,    /* signing */
+    rsa_ossl_private_decrypt,
+    rsa_ossl_mod_exp,
+    BN_mod_exp_mont,            /* XXX probably we should not use Montgomery
+                                 * if e == 3 */
+    rsa_ossl_init,
+    rsa_ossl_finish,
+    RSA_FLAG_FIPS_METHOD,       /* flags */
+    NULL,
+    0,                          /* rsa_sign */
+    0,                          /* rsa_verify */
+    NULL                        /* rsa_keygen */
+};
+
+const RSA_METHOD *RSA_PKCS1_OpenSSL(void)
+{
+    return &rsa_pkcs1_ossl_meth;
+}
+
+static int rsa_ossl_public_encrypt(int flen, const unsigned char *from,
+                                  unsigned char *to, RSA *rsa, int padding)
+{
+    BIGNUM *f, *ret;
+    int i, j, k, num = 0, r = -1;
+    unsigned char *buf = NULL;
+    BN_CTX *ctx = NULL;
+
+    if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) {
+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE);
+        return -1;
+    }
+
+    if (BN_ucmp(rsa->n, rsa->e) <= 0) {
+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
+        return -1;
+    }
+
+    /* for large moduli, enforce exponent limit */
+    if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) {
+        if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
+            RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
+            return -1;
+        }
+    }
+
+    if ((ctx = BN_CTX_new()) == NULL)
+        goto err;
+    BN_CTX_start(ctx);
+    f = BN_CTX_get(ctx);
+    ret = BN_CTX_get(ctx);
+    num = BN_num_bytes(rsa->n);
+    buf = OPENSSL_malloc(num);
+    if (f == NULL || ret == NULL || buf == NULL) {
+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    switch (padding) {
+    case RSA_PKCS1_PADDING:
+        i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen);
+        break;
+    case RSA_PKCS1_OAEP_PADDING:
+        i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0);
+        break;
+    case RSA_SSLV23_PADDING:
+        i = RSA_padding_add_SSLv23(buf, num, from, flen);
+        break;
+    case RSA_NO_PADDING:
+        i = RSA_padding_add_none(buf, num, from, flen);
+        break;
+    default:
+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
+        goto err;
+    }
+    if (i <= 0)
+        goto err;
+
+    if (BN_bin2bn(buf, num, f) == NULL)
+        goto err;
+
+    if (BN_ucmp(f, rsa->n) >= 0) {
+        /* usually the padding functions would catch this */
+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT,
+               RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+        goto err;
+    }
+
+    if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+        if (!BN_MONT_CTX_set_locked
+            (&rsa->_method_mod_n, rsa->lock, rsa->n, ctx))
+            goto err;
+
+    if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx,
+                               rsa->_method_mod_n))
+        goto err;
+
+    /*
+     * put in leading 0 bytes if the number is less than the length of the
+     * modulus
+     */
+    j = BN_num_bytes(ret);
+    i = BN_bn2bin(ret, &(to[num - j]));
+    for (k = 0; k < (num - i); k++)
+        to[k] = 0;
+
+    r = num;
+ err:
+    if (ctx != NULL)
+        BN_CTX_end(ctx);
+    BN_CTX_free(ctx);
+    OPENSSL_clear_free(buf, num);
+    return (r);
+}
+
+static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
+{
+    BN_BLINDING *ret;
+
+    CRYPTO_THREAD_write_lock(rsa->lock);
+
+    if (rsa->blinding == NULL) {
+        rsa->blinding = RSA_setup_blinding(rsa, ctx);
+    }
+
+    ret = rsa->blinding;
+    if (ret == NULL)
+        goto err;
+
+    if (BN_BLINDING_is_current_thread(ret)) {
+        /* rsa->blinding is ours! */
+
+        *local = 1;
+    } else {
+        /* resort to rsa->mt_blinding instead */
+
+        /*
+         * instructs rsa_blinding_convert(), rsa_blinding_invert() that the
+         * BN_BLINDING is shared, meaning that accesses require locks, and
+         * that the blinding factor must be stored outside the BN_BLINDING
+         */
+        *local = 0;
+
+        if (rsa->mt_blinding == NULL) {
+            rsa->mt_blinding = RSA_setup_blinding(rsa, ctx);
+        }
+        ret = rsa->mt_blinding;
+    }
+
+ err:
+    CRYPTO_THREAD_unlock(rsa->lock);
+    return ret;
+}
+
+static int rsa_blinding_convert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind,
+                                BN_CTX *ctx)
+{
+    if (unblind == NULL)
+        /*
+         * Local blinding: store the unblinding factor in BN_BLINDING.
+         */
+        return BN_BLINDING_convert_ex(f, NULL, b, ctx);
+    else {
+        /*
+         * Shared blinding: store the unblinding factor outside BN_BLINDING.
+         */
+        int ret;
+
+        BN_BLINDING_lock(b);
+        ret = BN_BLINDING_convert_ex(f, unblind, b, ctx);
+        BN_BLINDING_unlock(b);
+
+        return ret;
+    }
+}
+
+static int rsa_blinding_invert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind,
+                               BN_CTX *ctx)
+{
+    /*
+     * For local blinding, unblind is set to NULL, and BN_BLINDING_invert_ex
+     * will use the unblinding factor stored in BN_BLINDING. If BN_BLINDING
+     * is shared between threads, unblind must be non-null:
+     * BN_BLINDING_invert_ex will then use the local unblinding factor, and
+     * will only read the modulus from BN_BLINDING. In both cases it's safe
+     * to access the blinding without a lock.
+     */
+    return BN_BLINDING_invert_ex(f, unblind, b, ctx);
+}
+
+/* signing */
+static int rsa_ossl_private_encrypt(int flen, const unsigned char *from,
+                                   unsigned char *to, RSA *rsa, int padding)
+{
+    BIGNUM *f, *ret, *res;
+    int i, j, k, num = 0, r = -1;
+    unsigned char *buf = NULL;
+    BN_CTX *ctx = NULL;
+    int local_blinding = 0;
+    /*
+     * Used only if the blinding structure is shared. A non-NULL unblind
+     * instructs rsa_blinding_convert() and rsa_blinding_invert() to store
+     * the unblinding factor outside the blinding structure.
+     */
+    BIGNUM *unblind = NULL;
+    BN_BLINDING *blinding = NULL;
+
+    if ((ctx = BN_CTX_new()) == NULL)
+        goto err;
+    BN_CTX_start(ctx);
+    f = BN_CTX_get(ctx);
+    ret = BN_CTX_get(ctx);
+    num = BN_num_bytes(rsa->n);
+    buf = OPENSSL_malloc(num);
+    if (f == NULL || ret == NULL || buf == NULL) {
+        RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    switch (padding) {
+    case RSA_PKCS1_PADDING:
+        i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen);
+        break;
+    case RSA_X931_PADDING:
+        i = RSA_padding_add_X931(buf, num, from, flen);
+        break;
+    case RSA_NO_PADDING:
+        i = RSA_padding_add_none(buf, num, from, flen);
+        break;
+    case RSA_SSLV23_PADDING:
+    default:
+        RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
+        goto err;
+    }
+    if (i <= 0)
+        goto err;
+
+    if (BN_bin2bn(buf, num, f) == NULL)
+        goto err;
+
+    if (BN_ucmp(f, rsa->n) >= 0) {
+        /* usually the padding functions would catch this */
+        RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT,
+               RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+        goto err;
+    }
+
+    if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) {
+        blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
+        if (blinding == NULL) {
+            RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+    }
+
+    if (blinding != NULL) {
+        if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) {
+            RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        if (!rsa_blinding_convert(blinding, f, unblind, ctx))
+            goto err;
+    }
+
+    if ((rsa->flags & RSA_FLAG_EXT_PKEY) ||
+        ((rsa->p != NULL) &&
+         (rsa->q != NULL) &&
+         (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) {
+        if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx))
+            goto err;
+    } else {
+        BIGNUM *d = BN_new();
+        if (d == NULL) {
+            RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
+
+        if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+            if (!BN_MONT_CTX_set_locked
+                (&rsa->_method_mod_n, rsa->lock, rsa->n, ctx)) {
+                BN_free(d);
+                goto err;
+            }
+
+        if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx,
+                                   rsa->_method_mod_n)) {
+            BN_free(d);
+            goto err;
+        }
+        /* We MUST free d before any further use of rsa->d */
+        BN_free(d);
+    }
+
+    if (blinding)
+        if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
+            goto err;
+
+    if (padding == RSA_X931_PADDING) {
+        BN_sub(f, rsa->n, ret);
+        if (BN_cmp(ret, f) > 0)
+            res = f;
+        else
+            res = ret;
+    } else
+        res = ret;
+
+    /*
+     * put in leading 0 bytes if the number is less than the length of the
+     * modulus
+     */
+    j = BN_num_bytes(res);
+    i = BN_bn2bin(res, &(to[num - j]));
+    for (k = 0; k < (num - i); k++)
+        to[k] = 0;
+
+    r = num;
+ err:
+    if (ctx != NULL)
+        BN_CTX_end(ctx);
+    BN_CTX_free(ctx);
+    OPENSSL_clear_free(buf, num);
+    return (r);
+}
+
+static int rsa_ossl_private_decrypt(int flen, const unsigned char *from,
+                                   unsigned char *to, RSA *rsa, int padding)
+{
+    BIGNUM *f, *ret;
+    int j, num = 0, r = -1;
+    unsigned char *p;
+    unsigned char *buf = NULL;
+    BN_CTX *ctx = NULL;
+    int local_blinding = 0;
+    /*
+     * Used only if the blinding structure is shared. A non-NULL unblind
+     * instructs rsa_blinding_convert() and rsa_blinding_invert() to store
+     * the unblinding factor outside the blinding structure.
+     */
+    BIGNUM *unblind = NULL;
+    BN_BLINDING *blinding = NULL;
+
+    if ((ctx = BN_CTX_new()) == NULL)
+        goto err;
+    BN_CTX_start(ctx);
+    f = BN_CTX_get(ctx);
+    ret = BN_CTX_get(ctx);
+    num = BN_num_bytes(rsa->n);
+    buf = OPENSSL_malloc(num);
+    if (f == NULL || ret == NULL || buf == NULL) {
+        RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    /*
+     * This check was for equality but PGP does evil things and chops off the
+     * top '0' bytes
+     */
+    if (flen > num) {
+        RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT,
+               RSA_R_DATA_GREATER_THAN_MOD_LEN);
+        goto err;
+    }
+
+    /* make data into a big number */
+    if (BN_bin2bn(from, (int)flen, f) == NULL)
+        goto err;
+
+    if (BN_ucmp(f, rsa->n) >= 0) {
+        RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT,
+               RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+        goto err;
+    }
+
+    if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) {
+        blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
+        if (blinding == NULL) {
+            RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+    }
+
+    if (blinding != NULL) {
+        if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) {
+            RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        if (!rsa_blinding_convert(blinding, f, unblind, ctx))
+            goto err;
+    }
+
+    /* do the decrypt */
+    if ((rsa->flags & RSA_FLAG_EXT_PKEY) ||
+        ((rsa->p != NULL) &&
+         (rsa->q != NULL) &&
+         (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) {
+        if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx))
+            goto err;
+    } else {
+        BIGNUM *d = BN_new();
+        if (d == NULL) {
+            RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
+
+        if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+            if (!BN_MONT_CTX_set_locked
+                (&rsa->_method_mod_n, rsa->lock, rsa->n, ctx)) {
+                BN_free(d);
+                goto err;
+            }
+        if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx,
+                                   rsa->_method_mod_n)) {
+            BN_free(d);
+            goto err;
+        }
+        /* We MUST free d before any further use of rsa->d */
+        BN_free(d);
+    }
+
+    if (blinding)
+        if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
+            goto err;
+
+    p = buf;
+    j = BN_bn2bin(ret, p);      /* j is only used with no-padding mode */
+
+    switch (padding) {
+    case RSA_PKCS1_PADDING:
+        r = RSA_padding_check_PKCS1_type_2(to, num, buf, j, num);
+        break;
+    case RSA_PKCS1_OAEP_PADDING:
+        r = RSA_padding_check_PKCS1_OAEP(to, num, buf, j, num, NULL, 0);
+        break;
+    case RSA_SSLV23_PADDING:
+        r = RSA_padding_check_SSLv23(to, num, buf, j, num);
+        break;
+    case RSA_NO_PADDING:
+        r = RSA_padding_check_none(to, num, buf, j, num);
+        break;
+    default:
+        RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
+        goto err;
+    }
+    if (r < 0)
+        RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_PADDING_CHECK_FAILED);
+
+ err:
+    if (ctx != NULL)
+        BN_CTX_end(ctx);
+    BN_CTX_free(ctx);
+    OPENSSL_clear_free(buf, num);
+    return (r);
+}
+
+/* signature verification */
+static int rsa_ossl_public_decrypt(int flen, const unsigned char *from,
+                                  unsigned char *to, RSA *rsa, int padding)
+{
+    BIGNUM *f, *ret;
+    int i, num = 0, r = -1;
+    unsigned char *p;
+    unsigned char *buf = NULL;
+    BN_CTX *ctx = NULL;
+
+    if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) {
+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE);
+        return -1;
+    }
+
+    if (BN_ucmp(rsa->n, rsa->e) <= 0) {
+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE);
+        return -1;
+    }
+
+    /* for large moduli, enforce exponent limit */
+    if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) {
+        if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
+            RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE);
+            return -1;
+        }
+    }
+
+    if ((ctx = BN_CTX_new()) == NULL)
+        goto err;
+    BN_CTX_start(ctx);
+    f = BN_CTX_get(ctx);
+    ret = BN_CTX_get(ctx);
+    num = BN_num_bytes(rsa->n);
+    buf = OPENSSL_malloc(num);
+    if (f == NULL || ret == NULL || buf == NULL) {
+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    /*
+     * This check was for equality but PGP does evil things and chops off the
+     * top '0' bytes
+     */
+    if (flen > num) {
+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN);
+        goto err;
+    }
+
+    if (BN_bin2bn(from, flen, f) == NULL)
+        goto err;
+
+    if (BN_ucmp(f, rsa->n) >= 0) {
+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT,
+               RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+        goto err;
+    }
+
+    if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+        if (!BN_MONT_CTX_set_locked
+            (&rsa->_method_mod_n, rsa->lock, rsa->n, ctx))
+            goto err;
+
+    if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx,
+                               rsa->_method_mod_n))
+        goto err;
+
+    if ((padding == RSA_X931_PADDING) && ((bn_get_words(ret)[0] & 0xf) != 12))
+        if (!BN_sub(ret, rsa->n, ret))
+            goto err;
+
+    p = buf;
+    i = BN_bn2bin(ret, p);
+
+    switch (padding) {
+    case RSA_PKCS1_PADDING:
+        r = RSA_padding_check_PKCS1_type_1(to, num, buf, i, num);
+        break;
+    case RSA_X931_PADDING:
+        r = RSA_padding_check_X931(to, num, buf, i, num);
+        break;
+    case RSA_NO_PADDING:
+        r = RSA_padding_check_none(to, num, buf, i, num);
+        break;
+    default:
+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
+        goto err;
+    }
+    if (r < 0)
+        RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_PADDING_CHECK_FAILED);
+
+ err:
+    if (ctx != NULL)
+        BN_CTX_end(ctx);
+    BN_CTX_free(ctx);
+    OPENSSL_clear_free(buf, num);
+    return (r);
+}
+
+static int rsa_ossl_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
+{
+    BIGNUM *r1, *m1, *vrfy;
+    int ret = 0;
+
+    BN_CTX_start(ctx);
+
+    r1 = BN_CTX_get(ctx);
+    m1 = BN_CTX_get(ctx);
+    vrfy = BN_CTX_get(ctx);
+
+    {
+        BIGNUM *p = BN_new(), *q = BN_new();
+
+        /*
+         * Make sure BN_mod_inverse in Montgomery initialization uses the
+         * BN_FLG_CONSTTIME flag
+         */
+        if (p == NULL || q == NULL) {
+            BN_free(p);
+            BN_free(q);
+            goto err;
+        }
+        BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
+        BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME);
+
+        if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) {
+            if (!BN_MONT_CTX_set_locked
+                (&rsa->_method_mod_p, rsa->lock, p, ctx)
+                || !BN_MONT_CTX_set_locked(&rsa->_method_mod_q,
+                                           rsa->lock, q, ctx)) {
+                BN_free(p);
+                BN_free(q);
+                goto err;
+            }
+        }
+        /*
+         * We MUST free p and q before any further use of rsa->p and rsa->q
+         */
+        BN_free(p);
+        BN_free(q);
+    }
+
+    if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+        if (!BN_MONT_CTX_set_locked
+            (&rsa->_method_mod_n, rsa->lock, rsa->n, ctx))
+            goto err;
+
+    /* compute I mod q */
+    {
+        BIGNUM *c = BN_new();
+        if (c == NULL)
+            goto err;
+        BN_with_flags(c, I, BN_FLG_CONSTTIME);
+
+        if (!BN_mod(r1, c, rsa->q, ctx)) {
+            BN_free(c);
+            goto err;
+        }
+
+        {
+            BIGNUM *dmq1 = BN_new();
+            if (dmq1 == NULL) {
+                BN_free(c);
+                goto err;
+            }
+            BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
+
+            /* compute r1^dmq1 mod q */
+            if (!rsa->meth->bn_mod_exp(m1, r1, dmq1, rsa->q, ctx,
+                rsa->_method_mod_q)) {
+                BN_free(c);
+                BN_free(dmq1);
+                goto err;
+            }
+            /* We MUST free dmq1 before any further use of rsa->dmq1 */
+            BN_free(dmq1);
+        }
+
+        /* compute I mod p */
+        if (!BN_mod(r1, c, rsa->p, ctx)) {
+            BN_free(c);
+            goto err;
+        }
+        /* We MUST free c before any further use of I */
+        BN_free(c);
+    }
+
+    {
+        BIGNUM *dmp1 = BN_new();
+        if (dmp1 == NULL)
+            goto err;
+        BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
+
+        /* compute r1^dmp1 mod p */
+        if (!rsa->meth->bn_mod_exp(r0, r1, dmp1, rsa->p, ctx,
+                                   rsa->_method_mod_p)) {
+            BN_free(dmp1);
+            goto err;
+        }
+        /* We MUST free dmp1 before any further use of rsa->dmp1 */
+        BN_free(dmp1);
+    }
+
+    if (!BN_sub(r0, r0, m1))
+        goto err;
+    /*
+     * This will help stop the size of r0 increasing, which does affect the
+     * multiply if it optimised for a power of 2 size
+     */
+    if (BN_is_negative(r0))
+        if (!BN_add(r0, r0, rsa->p))
+            goto err;
+
+    if (!BN_mul(r1, r0, rsa->iqmp, ctx))
+        goto err;
+
+    {
+        BIGNUM *pr1 = BN_new();
+        if (pr1 == NULL)
+            goto err;
+        BN_with_flags(pr1, r1, BN_FLG_CONSTTIME);
+
+        if (!BN_mod(r0, pr1, rsa->p, ctx)) {
+            BN_free(pr1);
+            goto err;
+        }
+        /* We MUST free pr1 before any further use of r1 */
+        BN_free(pr1);
+    }
+
+    /*
+     * If p < q it is occasionally possible for the correction of adding 'p'
+     * if r0 is negative above to leave the result still negative. This can
+     * break the private key operations: the following second correction
+     * should *always* correct this rare occurrence. This will *never* happen
+     * with OpenSSL generated keys because they ensure p > q [steve]
+     */
+    if (BN_is_negative(r0))
+        if (!BN_add(r0, r0, rsa->p))
+            goto err;
+    if (!BN_mul(r1, r0, rsa->q, ctx))
+        goto err;
+    if (!BN_add(r0, r1, m1))
+        goto err;
+
+    if (rsa->e && rsa->n) {
+        if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx,
+                                   rsa->_method_mod_n))
+            goto err;
+        /*
+         * If 'I' was greater than (or equal to) rsa->n, the operation will
+         * be equivalent to using 'I mod n'. However, the result of the
+         * verify will *always* be less than 'n' so we don't check for
+         * absolute equality, just congruency.
+         */
+        if (!BN_sub(vrfy, vrfy, I))
+            goto err;
+        if (!BN_mod(vrfy, vrfy, rsa->n, ctx))
+            goto err;
+        if (BN_is_negative(vrfy))
+            if (!BN_add(vrfy, vrfy, rsa->n))
+                goto err;
+        if (!BN_is_zero(vrfy)) {
+            /*
+             * 'I' and 'vrfy' aren't congruent mod n. Don't leak
+             * miscalculated CRT output, just do a raw (slower) mod_exp and
+             * return that instead.
+             */
+
+            BIGNUM *d = BN_new();
+            if (d == NULL)
+                goto err;
+            BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
+
+            if (!rsa->meth->bn_mod_exp(r0, I, d, rsa->n, ctx,
+                                       rsa->_method_mod_n)) {
+                BN_free(d);
+                goto err;
+            }
+            /* We MUST free d before any further use of rsa->d */
+            BN_free(d);
+        }
+    }
+    ret = 1;
+ err:
+    BN_CTX_end(ctx);
+    return (ret);
+}
+
+static int rsa_ossl_init(RSA *rsa)
+{
+    rsa->flags |= RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE;
+    return (1);
+}
+
+static int rsa_ossl_finish(RSA *rsa)
+{
+    BN_MONT_CTX_free(rsa->_method_mod_n);
+    BN_MONT_CTX_free(rsa->_method_mod_p);
+    BN_MONT_CTX_free(rsa->_method_mod_q);
+    return (1);
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_pk1.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_pk1.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_pk1.c	(revision 331)
@@ -0,0 +1,245 @@
+/*
+ * Copyright 1995-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 "internal/constant_time_locl.h"
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+
+int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen,
+                                 const unsigned char *from, int flen)
+{
+    int j;
+    unsigned char *p;
+
+    if (flen > (tlen - RSA_PKCS1_PADDING_SIZE)) {
+        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1,
+               RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+        return (0);
+    }
+
+    p = (unsigned char *)to;
+
+    *(p++) = 0;
+    *(p++) = 1;                 /* Private Key BT (Block Type) */
+
+    /* pad out with 0xff data */
+    j = tlen - 3 - flen;
+    memset(p, 0xff, j);
+    p += j;
+    *(p++) = '\0';
+    memcpy(p, from, (unsigned int)flen);
+    return (1);
+}
+
+int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen,
+                                   const unsigned char *from, int flen,
+                                   int num)
+{
+    int i, j;
+    const unsigned char *p;
+
+    p = from;
+
+    /*
+     * The format is
+     * 00 || 01 || PS || 00 || D
+     * PS - padding string, at least 8 bytes of FF
+     * D  - data.
+     */
+
+    if (num < 11)
+        return -1;
+
+    /* Accept inputs with and without the leading 0-byte. */
+    if (num == flen) {
+        if ((*p++) != 0x00) {
+            RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,
+                   RSA_R_INVALID_PADDING);
+            return -1;
+        }
+        flen--;
+    }
+
+    if ((num != (flen + 1)) || (*(p++) != 0x01)) {
+        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,
+               RSA_R_BLOCK_TYPE_IS_NOT_01);
+        return (-1);
+    }
+
+    /* scan over padding data */
+    j = flen - 1;               /* one for type. */
+    for (i = 0; i < j; i++) {
+        if (*p != 0xff) {       /* should decrypt to 0xff */
+            if (*p == 0) {
+                p++;
+                break;
+            } else {
+                RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,
+                       RSA_R_BAD_FIXED_HEADER_DECRYPT);
+                return (-1);
+            }
+        }
+        p++;
+    }
+
+    if (i == j) {
+        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,
+               RSA_R_NULL_BEFORE_BLOCK_MISSING);
+        return (-1);
+    }
+
+    if (i < 8) {
+        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,
+               RSA_R_BAD_PAD_BYTE_COUNT);
+        return (-1);
+    }
+    i++;                        /* Skip over the '\0' */
+    j -= i;
+    if (j > tlen) {
+        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, RSA_R_DATA_TOO_LARGE);
+        return (-1);
+    }
+    memcpy(to, p, (unsigned int)j);
+
+    return (j);
+}
+
+int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen,
+                                 const unsigned char *from, int flen)
+{
+    int i, j;
+    unsigned char *p;
+
+    if (flen > (tlen - 11)) {
+        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2,
+               RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+        return (0);
+    }
+
+    p = (unsigned char *)to;
+
+    *(p++) = 0;
+    *(p++) = 2;                 /* Public Key BT (Block Type) */
+
+    /* pad out with non-zero random data */
+    j = tlen - 3 - flen;
+
+    if (RAND_bytes(p, j) <= 0)
+        return (0);
+    for (i = 0; i < j; i++) {
+        if (*p == '\0')
+            do {
+                if (RAND_bytes(p, 1) <= 0)
+                    return (0);
+            } while (*p == '\0');
+        p++;
+    }
+
+    *(p++) = '\0';
+
+    memcpy(p, from, (unsigned int)flen);
+    return (1);
+}
+
+int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
+                                   const unsigned char *from, int flen,
+                                   int num)
+{
+    int i;
+    /* |em| is the encoded message, zero-padded to exactly |num| bytes */
+    unsigned char *em = NULL;
+    unsigned int good, found_zero_byte;
+    int zero_index = 0, msg_index, mlen = -1;
+
+    if (tlen < 0 || flen < 0)
+        return -1;
+
+    /*
+     * PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography Standard",
+     * section 7.2.2.
+     */
+
+    if (flen > num)
+        goto err;
+
+    if (num < 11)
+        goto err;
+
+    em = OPENSSL_zalloc(num);
+    if (em == NULL) {
+        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+    /*
+     * Always do this zero-padding copy (even when num == flen) to avoid
+     * leaking that information. The copy still leaks some side-channel
+     * information, but it's impossible to have a fixed memory access
+     * pattern since we can't read out of the bounds of |from|.
+     *
+     * TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL.
+     */
+    memcpy(em + num - flen, from, flen);
+
+    good = constant_time_is_zero(em[0]);
+    good &= constant_time_eq(em[1], 2);
+
+    found_zero_byte = 0;
+    for (i = 2; i < num; i++) {
+        unsigned int equals0 = constant_time_is_zero(em[i]);
+        zero_index =
+            constant_time_select_int(~found_zero_byte & equals0, i,
+                                     zero_index);
+        found_zero_byte |= equals0;
+    }
+
+    /*
+     * PS must be at least 8 bytes long, and it starts two bytes into |em|.
+     * If we never found a 0-byte, then |zero_index| is 0 and the check
+     * also fails.
+     */
+    good &= constant_time_ge((unsigned int)(zero_index), 2 + 8);
+
+    /*
+     * Skip the zero byte. This is incorrect if we never found a zero-byte
+     * but in this case we also do not copy the message out.
+     */
+    msg_index = zero_index + 1;
+    mlen = num - msg_index;
+
+    /*
+     * For good measure, do this check in constant time as well; it could
+     * leak something if |tlen| was assuming valid padding.
+     */
+    good &= constant_time_ge((unsigned int)(tlen), (unsigned int)(mlen));
+
+    /*
+     * We can't continue in constant-time because we need to copy the result
+     * and we cannot fake its length. This unavoidably leaks timing
+     * information at the API boundary.
+     * TODO(emilia): this could be addressed at the call site,
+     * see BoringSSL commit 0aa0767340baf925bda4804882aab0cb974b2d26.
+     */
+    if (!good) {
+        mlen = -1;
+        goto err;
+    }
+
+    memcpy(to, em + msg_index, mlen);
+
+ err:
+    OPENSSL_free(em);
+    if (mlen == -1)
+        RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,
+               RSA_R_PKCS_DECODING_ERROR);
+    return mlen;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_pmeth.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_pmeth.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_pmeth.c	(revision 331)
@@ -0,0 +1,673 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/rsa.h>
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/x509v3.h>
+#include <openssl/cms.h>
+#include "internal/evp_int.h"
+#include "rsa_locl.h"
+
+/* RSA pkey context structure */
+
+typedef struct {
+    /* Key gen parameters */
+    int nbits;
+    BIGNUM *pub_exp;
+    /* Keygen callback info */
+    int gentmp[2];
+    /* RSA padding mode */
+    int pad_mode;
+    /* message digest */
+    const EVP_MD *md;
+    /* message digest for MGF1 */
+    const EVP_MD *mgf1md;
+    /* PSS salt length */
+    int saltlen;
+    /* Temp buffer */
+    unsigned char *tbuf;
+    /* OAEP label */
+    unsigned char *oaep_label;
+    size_t oaep_labellen;
+} RSA_PKEY_CTX;
+
+static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
+{
+    RSA_PKEY_CTX *rctx;
+    rctx = OPENSSL_zalloc(sizeof(*rctx));
+    if (rctx == NULL)
+        return 0;
+    rctx->nbits = 1024;
+    rctx->pad_mode = RSA_PKCS1_PADDING;
+    rctx->saltlen = -2;
+    ctx->data = rctx;
+    ctx->keygen_info = rctx->gentmp;
+    ctx->keygen_info_count = 2;
+
+    return 1;
+}
+
+static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+{
+    RSA_PKEY_CTX *dctx, *sctx;
+    if (!pkey_rsa_init(dst))
+        return 0;
+    sctx = src->data;
+    dctx = dst->data;
+    dctx->nbits = sctx->nbits;
+    if (sctx->pub_exp) {
+        dctx->pub_exp = BN_dup(sctx->pub_exp);
+        if (!dctx->pub_exp)
+            return 0;
+    }
+    dctx->pad_mode = sctx->pad_mode;
+    dctx->md = sctx->md;
+    dctx->mgf1md = sctx->mgf1md;
+    if (sctx->oaep_label) {
+        OPENSSL_free(dctx->oaep_label);
+        dctx->oaep_label = OPENSSL_memdup(sctx->oaep_label, sctx->oaep_labellen);
+        if (!dctx->oaep_label)
+            return 0;
+        dctx->oaep_labellen = sctx->oaep_labellen;
+    }
+    return 1;
+}
+
+static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk)
+{
+    if (ctx->tbuf)
+        return 1;
+    ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey));
+    if (ctx->tbuf == NULL)
+        return 0;
+    return 1;
+}
+
+static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx)
+{
+    RSA_PKEY_CTX *rctx = ctx->data;
+    if (rctx) {
+        BN_free(rctx->pub_exp);
+        OPENSSL_free(rctx->tbuf);
+        OPENSSL_free(rctx->oaep_label);
+        OPENSSL_free(rctx);
+    }
+}
+
+static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
+                         size_t *siglen, const unsigned char *tbs,
+                         size_t tbslen)
+{
+    int ret;
+    RSA_PKEY_CTX *rctx = ctx->data;
+    RSA *rsa = ctx->pkey->pkey.rsa;
+
+    if (rctx->md) {
+        if (tbslen != (size_t)EVP_MD_size(rctx->md)) {
+            RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_INVALID_DIGEST_LENGTH);
+            return -1;
+        }
+
+        if (EVP_MD_type(rctx->md) == NID_mdc2) {
+            unsigned int sltmp;
+            if (rctx->pad_mode != RSA_PKCS1_PADDING)
+                return -1;
+            ret = RSA_sign_ASN1_OCTET_STRING(0,
+                                             tbs, tbslen, sig, &sltmp, rsa);
+
+            if (ret <= 0)
+                return ret;
+            ret = sltmp;
+        } else if (rctx->pad_mode == RSA_X931_PADDING) {
+            if ((size_t)EVP_PKEY_size(ctx->pkey) < tbslen + 1) {
+                RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_KEY_SIZE_TOO_SMALL);
+                return -1;
+            }
+            if (!setup_tbuf(rctx, ctx)) {
+                RSAerr(RSA_F_PKEY_RSA_SIGN, ERR_R_MALLOC_FAILURE);
+                return -1;
+            }
+            memcpy(rctx->tbuf, tbs, tbslen);
+            rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_type(rctx->md));
+            ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf,
+                                      sig, rsa, RSA_X931_PADDING);
+        } else if (rctx->pad_mode == RSA_PKCS1_PADDING) {
+            unsigned int sltmp;
+            ret = RSA_sign(EVP_MD_type(rctx->md),
+                           tbs, tbslen, sig, &sltmp, rsa);
+            if (ret <= 0)
+                return ret;
+            ret = sltmp;
+        } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) {
+            if (!setup_tbuf(rctx, ctx))
+                return -1;
+            if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa,
+                                                rctx->tbuf, tbs,
+                                                rctx->md, rctx->mgf1md,
+                                                rctx->saltlen))
+                return -1;
+            ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf,
+                                      sig, rsa, RSA_NO_PADDING);
+        } else
+            return -1;
+    } else
+        ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
+                                  rctx->pad_mode);
+    if (ret < 0)
+        return ret;
+    *siglen = ret;
+    return 1;
+}
+
+static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx,
+                                  unsigned char *rout, size_t *routlen,
+                                  const unsigned char *sig, size_t siglen)
+{
+    int ret;
+    RSA_PKEY_CTX *rctx = ctx->data;
+
+    if (rctx->md) {
+        if (rctx->pad_mode == RSA_X931_PADDING) {
+            if (!setup_tbuf(rctx, ctx))
+                return -1;
+            ret = RSA_public_decrypt(siglen, sig,
+                                     rctx->tbuf, ctx->pkey->pkey.rsa,
+                                     RSA_X931_PADDING);
+            if (ret < 1)
+                return 0;
+            ret--;
+            if (rctx->tbuf[ret] != RSA_X931_hash_id(EVP_MD_type(rctx->md))) {
+                RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
+                       RSA_R_ALGORITHM_MISMATCH);
+                return 0;
+            }
+            if (ret != EVP_MD_size(rctx->md)) {
+                RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER,
+                       RSA_R_INVALID_DIGEST_LENGTH);
+                return 0;
+            }
+            if (rout)
+                memcpy(rout, rctx->tbuf, ret);
+        } else if (rctx->pad_mode == RSA_PKCS1_PADDING) {
+            size_t sltmp;
+            ret = int_rsa_verify(EVP_MD_type(rctx->md),
+                                 NULL, 0, rout, &sltmp,
+                                 sig, siglen, ctx->pkey->pkey.rsa);
+            if (ret <= 0)
+                return 0;
+            ret = sltmp;
+        } else
+            return -1;
+    } else
+        ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa,
+                                 rctx->pad_mode);
+    if (ret < 0)
+        return ret;
+    *routlen = ret;
+    return 1;
+}
+
+static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
+                           const unsigned char *sig, size_t siglen,
+                           const unsigned char *tbs, size_t tbslen)
+{
+    RSA_PKEY_CTX *rctx = ctx->data;
+    RSA *rsa = ctx->pkey->pkey.rsa;
+    size_t rslen;
+    if (rctx->md) {
+        if (rctx->pad_mode == RSA_PKCS1_PADDING)
+            return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
+                              sig, siglen, rsa);
+        if (tbslen != (size_t)EVP_MD_size(rctx->md)) {
+            RSAerr(RSA_F_PKEY_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH);
+            return -1;
+        }
+        if (rctx->pad_mode == RSA_X931_PADDING) {
+            if (pkey_rsa_verifyrecover(ctx, NULL, &rslen, sig, siglen) <= 0)
+                return 0;
+        } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) {
+            int ret;
+            if (!setup_tbuf(rctx, ctx))
+                return -1;
+            ret = RSA_public_decrypt(siglen, sig, rctx->tbuf,
+                                     rsa, RSA_NO_PADDING);
+            if (ret <= 0)
+                return 0;
+            ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs,
+                                            rctx->md, rctx->mgf1md,
+                                            rctx->tbuf, rctx->saltlen);
+            if (ret <= 0)
+                return 0;
+            return 1;
+        } else
+            return -1;
+    } else {
+        if (!setup_tbuf(rctx, ctx))
+            return -1;
+        rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf,
+                                   rsa, rctx->pad_mode);
+        if (rslen == 0)
+            return 0;
+    }
+
+    if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen))
+        return 0;
+
+    return 1;
+
+}
+
+static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx,
+                            unsigned char *out, size_t *outlen,
+                            const unsigned char *in, size_t inlen)
+{
+    int ret;
+    RSA_PKEY_CTX *rctx = ctx->data;
+    if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
+        int klen = RSA_size(ctx->pkey->pkey.rsa);
+        if (!setup_tbuf(rctx, ctx))
+            return -1;
+        if (!RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, klen,
+                                             in, inlen,
+                                             rctx->oaep_label,
+                                             rctx->oaep_labellen,
+                                             rctx->md, rctx->mgf1md))
+            return -1;
+        ret = RSA_public_encrypt(klen, rctx->tbuf, out,
+                                 ctx->pkey->pkey.rsa, RSA_NO_PADDING);
+    } else
+        ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa,
+                                 rctx->pad_mode);
+    if (ret < 0)
+        return ret;
+    *outlen = ret;
+    return 1;
+}
+
+static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx,
+                            unsigned char *out, size_t *outlen,
+                            const unsigned char *in, size_t inlen)
+{
+    int ret;
+    RSA_PKEY_CTX *rctx = ctx->data;
+    if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
+        int i;
+        if (!setup_tbuf(rctx, ctx))
+            return -1;
+        ret = RSA_private_decrypt(inlen, in, rctx->tbuf,
+                                  ctx->pkey->pkey.rsa, RSA_NO_PADDING);
+        if (ret <= 0)
+            return ret;
+        for (i = 0; i < ret; i++) {
+            if (rctx->tbuf[i])
+                break;
+        }
+        ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, ret, rctx->tbuf + i,
+                                                ret - i, ret,
+                                                rctx->oaep_label,
+                                                rctx->oaep_labellen,
+                                                rctx->md, rctx->mgf1md);
+    } else
+        ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa,
+                                  rctx->pad_mode);
+    if (ret < 0)
+        return ret;
+    *outlen = ret;
+    return 1;
+}
+
+static int check_padding_md(const EVP_MD *md, int padding)
+{
+    int mdnid;
+    if (!md)
+        return 1;
+
+    mdnid = EVP_MD_type(md);
+
+    if (padding == RSA_NO_PADDING) {
+        RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE);
+        return 0;
+    }
+
+    if (padding == RSA_X931_PADDING) {
+        if (RSA_X931_hash_id(mdnid) == -1) {
+            RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_X931_DIGEST);
+            return 0;
+        }
+    } else {
+        switch(mdnid) {
+        /* List of all supported RSA digests */
+        case NID_sha1:
+        case NID_sha224:
+        case NID_sha256:
+        case NID_sha384:
+        case NID_sha512:
+        case NID_md5:
+        case NID_md5_sha1:
+        case NID_md2:
+        case NID_md4:
+        case NID_mdc2:
+        case NID_ripemd160:
+            return 1;
+
+        default:
+            RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_DIGEST);
+            return 0;
+
+        }
+    }
+
+    return 1;
+}
+
+static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+    RSA_PKEY_CTX *rctx = ctx->data;
+    switch (type) {
+    case EVP_PKEY_CTRL_RSA_PADDING:
+        if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING)) {
+            if (!check_padding_md(rctx->md, p1))
+                return 0;
+            if (p1 == RSA_PKCS1_PSS_PADDING) {
+                if (!(ctx->operation &
+                      (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY)))
+                    goto bad_pad;
+                if (!rctx->md)
+                    rctx->md = EVP_sha1();
+            }
+            if (p1 == RSA_PKCS1_OAEP_PADDING) {
+                if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))
+                    goto bad_pad;
+                if (!rctx->md)
+                    rctx->md = EVP_sha1();
+            }
+            rctx->pad_mode = p1;
+            return 1;
+        }
+ bad_pad:
+        RSAerr(RSA_F_PKEY_RSA_CTRL,
+               RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
+        return -2;
+
+    case EVP_PKEY_CTRL_GET_RSA_PADDING:
+        *(int *)p2 = rctx->pad_mode;
+        return 1;
+
+    case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
+    case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN:
+        if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) {
+            RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN);
+            return -2;
+        }
+        if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN)
+            *(int *)p2 = rctx->saltlen;
+        else {
+            if (p1 < -2)
+                return -2;
+            rctx->saltlen = p1;
+        }
+        return 1;
+
+    case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
+        if (p1 < 512) {
+            RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_KEY_SIZE_TOO_SMALL);
+            return -2;
+        }
+        rctx->nbits = p1;
+        return 1;
+
+    case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
+        if (p2 == NULL || !BN_is_odd((BIGNUM *)p2) || BN_is_one((BIGNUM *)p2)) {
+            RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_BAD_E_VALUE);
+            return -2;
+        }
+        BN_free(rctx->pub_exp);
+        rctx->pub_exp = p2;
+        return 1;
+
+    case EVP_PKEY_CTRL_RSA_OAEP_MD:
+    case EVP_PKEY_CTRL_GET_RSA_OAEP_MD:
+        if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
+            RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE);
+            return -2;
+        }
+        if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD)
+            *(const EVP_MD **)p2 = rctx->md;
+        else
+            rctx->md = p2;
+        return 1;
+
+    case EVP_PKEY_CTRL_MD:
+        if (!check_padding_md(p2, rctx->pad_mode))
+            return 0;
+        rctx->md = p2;
+        return 1;
+
+    case EVP_PKEY_CTRL_GET_MD:
+        *(const EVP_MD **)p2 = rctx->md;
+        return 1;
+
+    case EVP_PKEY_CTRL_RSA_MGF1_MD:
+    case EVP_PKEY_CTRL_GET_RSA_MGF1_MD:
+        if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING
+            && rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
+            RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_MGF1_MD);
+            return -2;
+        }
+        if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) {
+            if (rctx->mgf1md)
+                *(const EVP_MD **)p2 = rctx->mgf1md;
+            else
+                *(const EVP_MD **)p2 = rctx->md;
+        } else
+            rctx->mgf1md = p2;
+        return 1;
+
+    case EVP_PKEY_CTRL_RSA_OAEP_LABEL:
+        if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
+            RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE);
+            return -2;
+        }
+        OPENSSL_free(rctx->oaep_label);
+        if (p2 && p1 > 0) {
+            rctx->oaep_label = p2;
+            rctx->oaep_labellen = p1;
+        } else {
+            rctx->oaep_label = NULL;
+            rctx->oaep_labellen = 0;
+        }
+        return 1;
+
+    case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL:
+        if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
+            RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE);
+            return -2;
+        }
+        *(unsigned char **)p2 = rctx->oaep_label;
+        return rctx->oaep_labellen;
+
+    case EVP_PKEY_CTRL_DIGESTINIT:
+    case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
+    case EVP_PKEY_CTRL_PKCS7_DECRYPT:
+    case EVP_PKEY_CTRL_PKCS7_SIGN:
+        return 1;
+#ifndef OPENSSL_NO_CMS
+    case EVP_PKEY_CTRL_CMS_DECRYPT:
+    case EVP_PKEY_CTRL_CMS_ENCRYPT:
+    case EVP_PKEY_CTRL_CMS_SIGN:
+        return 1;
+#endif
+    case EVP_PKEY_CTRL_PEER_KEY:
+        RSAerr(RSA_F_PKEY_RSA_CTRL,
+               RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+        return -2;
+
+    default:
+        return -2;
+
+    }
+}
+
+static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx,
+                             const char *type, const char *value)
+{
+    if (!value) {
+        RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING);
+        return 0;
+    }
+    if (strcmp(type, "rsa_padding_mode") == 0) {
+        int pm;
+        if (strcmp(value, "pkcs1") == 0)
+            pm = RSA_PKCS1_PADDING;
+        else if (strcmp(value, "sslv23") == 0)
+            pm = RSA_SSLV23_PADDING;
+        else if (strcmp(value, "none") == 0)
+            pm = RSA_NO_PADDING;
+        else if (strcmp(value, "oeap") == 0)
+            pm = RSA_PKCS1_OAEP_PADDING;
+        else if (strcmp(value, "oaep") == 0)
+            pm = RSA_PKCS1_OAEP_PADDING;
+        else if (strcmp(value, "x931") == 0)
+            pm = RSA_X931_PADDING;
+        else if (strcmp(value, "pss") == 0)
+            pm = RSA_PKCS1_PSS_PADDING;
+        else {
+            RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_UNKNOWN_PADDING_TYPE);
+            return -2;
+        }
+        return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
+    }
+
+    if (strcmp(type, "rsa_pss_saltlen") == 0) {
+        int saltlen;
+        saltlen = atoi(value);
+        return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen);
+    }
+
+    if (strcmp(type, "rsa_keygen_bits") == 0) {
+        int nbits;
+        nbits = atoi(value);
+        return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits);
+    }
+
+    if (strcmp(type, "rsa_keygen_pubexp") == 0) {
+        int ret;
+        BIGNUM *pubexp = NULL;
+        if (!BN_asc2bn(&pubexp, value))
+            return 0;
+        ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp);
+        if (ret <= 0)
+            BN_free(pubexp);
+        return ret;
+    }
+
+    if (strcmp(type, "rsa_mgf1_md") == 0) {
+        const EVP_MD *md;
+        if ((md = EVP_get_digestbyname(value)) == NULL) {
+            RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_INVALID_DIGEST);
+            return 0;
+        }
+        return EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md);
+    }
+
+    if (strcmp(type, "rsa_oaep_md") == 0) {
+        const EVP_MD *md;
+        if ((md = EVP_get_digestbyname(value)) == NULL) {
+            RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_INVALID_DIGEST);
+            return 0;
+        }
+        return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md);
+    }
+    if (strcmp(type, "rsa_oaep_label") == 0) {
+        unsigned char *lab;
+        long lablen;
+        int ret;
+        lab = OPENSSL_hexstr2buf(value, &lablen);
+        if (!lab)
+            return 0;
+        ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen);
+        if (ret <= 0)
+            OPENSSL_free(lab);
+        return ret;
+    }
+
+    return -2;
+}
+
+static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+    RSA *rsa = NULL;
+    RSA_PKEY_CTX *rctx = ctx->data;
+    BN_GENCB *pcb;
+    int ret;
+    if (rctx->pub_exp == NULL) {
+        rctx->pub_exp = BN_new();
+        if (rctx->pub_exp == NULL || !BN_set_word(rctx->pub_exp, RSA_F4))
+            return 0;
+    }
+    rsa = RSA_new();
+    if (rsa == NULL)
+        return 0;
+    if (ctx->pkey_gencb) {
+        pcb = BN_GENCB_new();
+        if (pcb == NULL) {
+            RSA_free(rsa);
+            return 0;
+        }
+        evp_pkey_set_cb_translate(pcb, ctx);
+    } else
+        pcb = NULL;
+    ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb);
+    BN_GENCB_free(pcb);
+    if (ret > 0)
+        EVP_PKEY_assign_RSA(pkey, rsa);
+    else
+        RSA_free(rsa);
+    return ret;
+}
+
+const EVP_PKEY_METHOD rsa_pkey_meth = {
+    EVP_PKEY_RSA,
+    EVP_PKEY_FLAG_AUTOARGLEN,
+    pkey_rsa_init,
+    pkey_rsa_copy,
+    pkey_rsa_cleanup,
+
+    0, 0,
+
+    0,
+    pkey_rsa_keygen,
+
+    0,
+    pkey_rsa_sign,
+
+    0,
+    pkey_rsa_verify,
+
+    0,
+    pkey_rsa_verifyrecover,
+
+    0, 0, 0, 0,
+
+    0,
+    pkey_rsa_encrypt,
+
+    0,
+    pkey_rsa_decrypt,
+
+    0, 0,
+
+    pkey_rsa_ctrl,
+    pkey_rsa_ctrl_str
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_prn.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_prn.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_prn.c	(revision 331)
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+
+#ifndef OPENSSL_NO_STDIO
+int RSA_print_fp(FILE *fp, const RSA *x, int off)
+{
+    BIO *b;
+    int ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        RSAerr(RSA_F_RSA_PRINT_FP, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = RSA_print(b, x, off);
+    BIO_free(b);
+    return (ret);
+}
+#endif
+
+int RSA_print(BIO *bp, const RSA *x, int off)
+{
+    EVP_PKEY *pk;
+    int ret;
+    pk = EVP_PKEY_new();
+    if (pk == NULL || !EVP_PKEY_set1_RSA(pk, (RSA *)x))
+        return 0;
+    ret = EVP_PKEY_print_private(bp, pk, off, NULL);
+    EVP_PKEY_free(pk);
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_pss.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_pss.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_pss.c	(revision 331)
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2005-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+#include "rsa_locl.h"
+
+static const unsigned char zeroes[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+#if defined(_MSC_VER) && defined(_ARM_)
+# pragma optimize("g", off)
+#endif
+
+int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
+                         const EVP_MD *Hash, const unsigned char *EM,
+                         int sLen)
+{
+    return RSA_verify_PKCS1_PSS_mgf1(rsa, mHash, Hash, NULL, EM, sLen);
+}
+
+int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
+                              const EVP_MD *Hash, const EVP_MD *mgf1Hash,
+                              const unsigned char *EM, int sLen)
+{
+    int i;
+    int ret = 0;
+    int hLen, maskedDBLen, MSBits, emLen;
+    const unsigned char *H;
+    unsigned char *DB = NULL;
+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+    unsigned char H_[EVP_MAX_MD_SIZE];
+
+
+    if (ctx == NULL)
+        goto err;
+
+    if (mgf1Hash == NULL)
+        mgf1Hash = Hash;
+
+    hLen = EVP_MD_size(Hash);
+    if (hLen < 0)
+        goto err;
+    /*-
+     * Negative sLen has special meanings:
+     *      -1      sLen == hLen
+     *      -2      salt length is autorecovered from signature
+     *      -N      reserved
+     */
+    if (sLen == -1)
+        sLen = hLen;
+    else if (sLen == -2)
+        sLen = -2;
+    else if (sLen < -2) {
+        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
+        goto err;
+    }
+
+    MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
+    emLen = RSA_size(rsa);
+    if (EM[0] & (0xFF << MSBits)) {
+        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_FIRST_OCTET_INVALID);
+        goto err;
+    }
+    if (MSBits == 0) {
+        EM++;
+        emLen--;
+    }
+    if (emLen < (hLen + sLen + 2)) { /* sLen can be small negative */
+        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE);
+        goto err;
+    }
+    if (EM[emLen - 1] != 0xbc) {
+        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_LAST_OCTET_INVALID);
+        goto err;
+    }
+    maskedDBLen = emLen - hLen - 1;
+    H = EM + maskedDBLen;
+    DB = OPENSSL_malloc(maskedDBLen);
+    if (DB == NULL) {
+        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0)
+        goto err;
+    for (i = 0; i < maskedDBLen; i++)
+        DB[i] ^= EM[i];
+    if (MSBits)
+        DB[0] &= 0xFF >> (8 - MSBits);
+    for (i = 0; DB[i] == 0 && i < (maskedDBLen - 1); i++) ;
+    if (DB[i++] != 0x1) {
+        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_RECOVERY_FAILED);
+        goto err;
+    }
+    if (sLen >= 0 && (maskedDBLen - i) != sLen) {
+        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
+        goto err;
+    }
+    if (!EVP_DigestInit_ex(ctx, Hash, NULL)
+        || !EVP_DigestUpdate(ctx, zeroes, sizeof zeroes)
+        || !EVP_DigestUpdate(ctx, mHash, hLen))
+        goto err;
+    if (maskedDBLen - i) {
+        if (!EVP_DigestUpdate(ctx, DB + i, maskedDBLen - i))
+            goto err;
+    }
+    if (!EVP_DigestFinal_ex(ctx, H_, NULL))
+        goto err;
+    if (memcmp(H_, H, hLen)) {
+        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_BAD_SIGNATURE);
+        ret = 0;
+    } else
+        ret = 1;
+
+ err:
+    OPENSSL_free(DB);
+    EVP_MD_CTX_free(ctx);
+
+    return ret;
+
+}
+
+int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
+                              const unsigned char *mHash,
+                              const EVP_MD *Hash, int sLen)
+{
+    return RSA_padding_add_PKCS1_PSS_mgf1(rsa, EM, mHash, Hash, NULL, sLen);
+}
+
+int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
+                                   const unsigned char *mHash,
+                                   const EVP_MD *Hash, const EVP_MD *mgf1Hash,
+                                   int sLen)
+{
+    int i;
+    int ret = 0;
+    int hLen, maskedDBLen, MSBits, emLen;
+    unsigned char *H, *salt = NULL, *p;
+    EVP_MD_CTX *ctx = NULL;
+
+    if (mgf1Hash == NULL)
+        mgf1Hash = Hash;
+
+    hLen = EVP_MD_size(Hash);
+    if (hLen < 0)
+        goto err;
+    /*-
+     * Negative sLen has special meanings:
+     *      -1      sLen == hLen
+     *      -2      salt length is maximized
+     *      -N      reserved
+     */
+    if (sLen == -1)
+        sLen = hLen;
+    else if (sLen == -2)
+        sLen = -2;
+    else if (sLen < -2) {
+        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
+        goto err;
+    }
+
+    MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
+    emLen = RSA_size(rsa);
+    if (MSBits == 0) {
+        *EM++ = 0;
+        emLen--;
+    }
+    if (sLen == -2) {
+        sLen = emLen - hLen - 2;
+    } else if (emLen < (hLen + sLen + 2)) {
+        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
+               RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+        goto err;
+    }
+    if (sLen > 0) {
+        salt = OPENSSL_malloc(sLen);
+        if (salt == NULL) {
+            RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
+                   ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        if (RAND_bytes(salt, sLen) <= 0)
+            goto err;
+    }
+    maskedDBLen = emLen - hLen - 1;
+    H = EM + maskedDBLen;
+    ctx = EVP_MD_CTX_new();
+    if (ctx == NULL)
+        goto err;
+    if (!EVP_DigestInit_ex(ctx, Hash, NULL)
+        || !EVP_DigestUpdate(ctx, zeroes, sizeof zeroes)
+        || !EVP_DigestUpdate(ctx, mHash, hLen))
+        goto err;
+    if (sLen && !EVP_DigestUpdate(ctx, salt, sLen))
+        goto err;
+    if (!EVP_DigestFinal_ex(ctx, H, NULL))
+        goto err;
+
+    /* Generate dbMask in place then perform XOR on it */
+    if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash))
+        goto err;
+
+    p = EM;
+
+    /*
+     * Initial PS XORs with all zeroes which is a NOP so just update pointer.
+     * Note from a test above this value is guaranteed to be non-negative.
+     */
+    p += emLen - sLen - hLen - 2;
+    *p++ ^= 0x1;
+    if (sLen > 0) {
+        for (i = 0; i < sLen; i++)
+            *p++ ^= salt[i];
+    }
+    if (MSBits)
+        EM[0] &= 0xFF >> (8 - MSBits);
+
+    /* H is already in place so just set final 0xbc */
+
+    EM[emLen - 1] = 0xbc;
+
+    ret = 1;
+
+ err:
+    EVP_MD_CTX_free(ctx);
+    OPENSSL_free(salt);
+
+    return ret;
+
+}
+
+#if defined(_MSC_VER)
+# pragma optimize("",on)
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_saos.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_saos.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_saos.c	(revision 331)
@@ -0,0 +1,94 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int RSA_sign_ASN1_OCTET_STRING(int type,
+                               const unsigned char *m, unsigned int m_len,
+                               unsigned char *sigret, unsigned int *siglen,
+                               RSA *rsa)
+{
+    ASN1_OCTET_STRING sig;
+    int i, j, ret = 1;
+    unsigned char *p, *s;
+
+    sig.type = V_ASN1_OCTET_STRING;
+    sig.length = m_len;
+    sig.data = (unsigned char *)m;
+
+    i = i2d_ASN1_OCTET_STRING(&sig, NULL);
+    j = RSA_size(rsa);
+    if (i > (j - RSA_PKCS1_PADDING_SIZE)) {
+        RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING,
+               RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
+        return (0);
+    }
+    s = OPENSSL_malloc((unsigned int)j + 1);
+    if (s == NULL) {
+        RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE);
+        return (0);
+    }
+    p = s;
+    i2d_ASN1_OCTET_STRING(&sig, &p);
+    i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING);
+    if (i <= 0)
+        ret = 0;
+    else
+        *siglen = i;
+
+    OPENSSL_clear_free(s, (unsigned int)j + 1);
+    return (ret);
+}
+
+int RSA_verify_ASN1_OCTET_STRING(int dtype,
+                                 const unsigned char *m,
+                                 unsigned int m_len, unsigned char *sigbuf,
+                                 unsigned int siglen, RSA *rsa)
+{
+    int i, ret = 0;
+    unsigned char *s;
+    const unsigned char *p;
+    ASN1_OCTET_STRING *sig = NULL;
+
+    if (siglen != (unsigned int)RSA_size(rsa)) {
+        RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING,
+               RSA_R_WRONG_SIGNATURE_LENGTH);
+        return (0);
+    }
+
+    s = OPENSSL_malloc((unsigned int)siglen);
+    if (s == NULL) {
+        RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING);
+
+    if (i <= 0)
+        goto err;
+
+    p = s;
+    sig = d2i_ASN1_OCTET_STRING(NULL, &p, (long)i);
+    if (sig == NULL)
+        goto err;
+
+    if (((unsigned int)sig->length != m_len) ||
+        (memcmp(m, sig->data, m_len) != 0)) {
+        RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, RSA_R_BAD_SIGNATURE);
+    } else
+        ret = 1;
+ err:
+    ASN1_OCTET_STRING_free(sig);
+    OPENSSL_clear_free(s, (unsigned int)siglen);
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_sign.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_sign.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_sign.c	(revision 331)
@@ -0,0 +1,248 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+#include "rsa_locl.h"
+
+/* Size of an SSL signature: MD5+SHA1 */
+#define SSL_SIG_LENGTH  36
+
+/*
+ * encode_pkcs1 encodes a DigestInfo prefix of hash |type| and digest |m|, as
+ * described in EMSA-PKCS1-v1_5-ENCODE, RFC 3447 section 9.2 step 2. This
+ * encodes the DigestInfo (T and tLen) but does not add the padding.
+ *
+ * On success, it returns one and sets |*out| to a newly allocated buffer
+ * containing the result and |*out_len| to its length. The caller must free
+ * |*out| with |OPENSSL_free|. Otherwise, it returns zero.
+ */
+static int encode_pkcs1(unsigned char **out, int *out_len, int type,
+                        const unsigned char *m, unsigned int m_len)
+{
+    X509_SIG sig;
+    X509_ALGOR algor;
+    ASN1_TYPE parameter;
+    ASN1_OCTET_STRING digest;
+    uint8_t *der = NULL;
+    int len;
+
+    sig.algor = &algor;
+    sig.algor->algorithm = OBJ_nid2obj(type);
+    if (sig.algor->algorithm == NULL) {
+        RSAerr(RSA_F_ENCODE_PKCS1, RSA_R_UNKNOWN_ALGORITHM_TYPE);
+        return 0;
+    }
+    if (OBJ_length(sig.algor->algorithm) == 0) {
+        RSAerr(RSA_F_ENCODE_PKCS1,
+               RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
+        return 0;
+    }
+    parameter.type = V_ASN1_NULL;
+    parameter.value.ptr = NULL;
+    sig.algor->parameter = &parameter;
+
+    sig.digest = &digest;
+    sig.digest->data = (unsigned char *)m;
+    sig.digest->length = m_len;
+
+    len = i2d_X509_SIG(&sig, &der);
+    if (len < 0)
+        return 0;
+
+    *out = der;
+    *out_len = len;
+    return 1;
+}
+
+int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
+             unsigned char *sigret, unsigned int *siglen, RSA *rsa)
+{
+    int encrypt_len, encoded_len = 0, ret = 0;
+    unsigned char *tmps = NULL;
+    const unsigned char *encoded = NULL;
+
+    if (rsa->meth->rsa_sign) {
+        return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa);
+    }
+
+    /* Compute the encoded digest. */
+    if (type == NID_md5_sha1) {
+        /*
+         * NID_md5_sha1 corresponds to the MD5/SHA1 combination in TLS 1.1 and
+         * earlier. It has no DigestInfo wrapper but otherwise is
+         * RSASSA-PKCS1-v1_5.
+         */
+        if (m_len != SSL_SIG_LENGTH) {
+            RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH);
+            return 0;
+        }
+        encoded_len = SSL_SIG_LENGTH;
+        encoded = m;
+    } else {
+        if (!encode_pkcs1(&tmps, &encoded_len, type, m, m_len))
+            goto err;
+        encoded = tmps;
+    }
+
+    if (encoded_len > RSA_size(rsa) - RSA_PKCS1_PADDING_SIZE) {
+        RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
+        goto err;
+    }
+    encrypt_len = RSA_private_encrypt(encoded_len, encoded, sigret, rsa,
+                                      RSA_PKCS1_PADDING);
+    if (encrypt_len <= 0)
+        goto err;
+
+    *siglen = encrypt_len;
+    ret = 1;
+
+err:
+    OPENSSL_clear_free(tmps, (size_t)encoded_len);
+    return ret;
+}
+
+/*
+ * int_rsa_verify verifies an RSA signature in |sigbuf| using |rsa|. It may be
+ * called in two modes. If |rm| is NULL, it verifies the signature for digest
+ * |m|. Otherwise, it recovers the digest from the signature, writing the digest
+ * to |rm| and the length to |*prm_len|. |type| is the NID of the digest
+ * algorithm to use. It returns one on successful verification and zero
+ * otherwise.
+ */
+int int_rsa_verify(int type, const unsigned char *m, unsigned int m_len,
+                   unsigned char *rm, size_t *prm_len,
+                   const unsigned char *sigbuf, size_t siglen, RSA *rsa)
+{
+    int decrypt_len, ret = 0, encoded_len = 0;
+    unsigned char *decrypt_buf = NULL, *encoded = NULL;
+
+    if (siglen != (size_t)RSA_size(rsa)) {
+        RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH);
+        return 0;
+    }
+
+    /* Recover the encoded digest. */
+    decrypt_buf = OPENSSL_malloc(siglen);
+    if (decrypt_buf == NULL) {
+        RSAerr(RSA_F_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    decrypt_len = RSA_public_decrypt((int)siglen, sigbuf, decrypt_buf, rsa,
+                                     RSA_PKCS1_PADDING);
+    if (decrypt_len <= 0)
+        goto err;
+
+    if (type == NID_md5_sha1) {
+        /*
+         * NID_md5_sha1 corresponds to the MD5/SHA1 combination in TLS 1.1 and
+         * earlier. It has no DigestInfo wrapper but otherwise is
+         * RSASSA-PKCS1-v1_5.
+         */
+        if (decrypt_len != SSL_SIG_LENGTH) {
+            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
+            goto err;
+        }
+
+        if (rm != NULL) {
+            memcpy(rm, decrypt_buf, SSL_SIG_LENGTH);
+            *prm_len = SSL_SIG_LENGTH;
+        } else {
+            if (m_len != SSL_SIG_LENGTH) {
+                RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH);
+                goto err;
+            }
+
+            if (memcmp(decrypt_buf, m, SSL_SIG_LENGTH) != 0) {
+                RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
+                goto err;
+            }
+        }
+    } else if (type == NID_mdc2 && decrypt_len == 2 + 16
+               && decrypt_buf[0] == 0x04 && decrypt_buf[1] == 0x10) {
+        /*
+         * Oddball MDC2 case: signature can be OCTET STRING. check for correct
+         * tag and length octets.
+         */
+        if (rm != NULL) {
+            memcpy(rm, decrypt_buf + 2, 16);
+            *prm_len = 16;
+        } else {
+            if (m_len != 16) {
+                RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH);
+                goto err;
+            }
+
+            if (memcmp(m, decrypt_buf + 2, 16) != 0) {
+                RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
+                goto err;
+            }
+        }
+    } else {
+        /*
+         * If recovering the digest, extract a digest-sized output from the end
+         * of |decrypt_buf| for |encode_pkcs1|, then compare the decryption
+         * output as in a standard verification.
+         */
+        if (rm != NULL) {
+            const EVP_MD *md = EVP_get_digestbynid(type);
+            if (md == NULL) {
+                RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_UNKNOWN_ALGORITHM_TYPE);
+                goto err;
+            }
+
+            m_len = EVP_MD_size(md);
+            if (m_len > (size_t)decrypt_len) {
+                RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH);
+                goto err;
+            }
+            m = decrypt_buf + decrypt_len - m_len;
+        }
+
+        /* Construct the encoded digest and ensure it matches. */
+        if (!encode_pkcs1(&encoded, &encoded_len, type, m, m_len))
+            goto err;
+
+        if (encoded_len != decrypt_len
+            || memcmp(encoded, decrypt_buf, encoded_len) != 0) {
+            RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);
+            goto err;
+        }
+
+        /* Output the recovered digest. */
+        if (rm != NULL) {
+            memcpy(rm, m, m_len);
+            *prm_len = m_len;
+        }
+    }
+
+    ret = 1;
+
+err:
+    OPENSSL_clear_free(encoded, (size_t)encoded_len);
+    OPENSSL_clear_free(decrypt_buf, siglen);
+    return ret;
+}
+
+int RSA_verify(int type, const unsigned char *m, unsigned int m_len,
+               const unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
+{
+
+    if (rsa->meth->rsa_verify) {
+        return rsa->meth->rsa_verify(type, m, m_len, sigbuf, siglen, rsa);
+    }
+
+    return int_rsa_verify(type, m, m_len, NULL, NULL, sigbuf, siglen, rsa);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_ssl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_ssl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_ssl.c	(revision 331)
@@ -0,0 +1,100 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+
+int RSA_padding_add_SSLv23(unsigned char *to, int tlen,
+                           const unsigned char *from, int flen)
+{
+    int i, j;
+    unsigned char *p;
+
+    if (flen > (tlen - 11)) {
+        RSAerr(RSA_F_RSA_PADDING_ADD_SSLV23,
+               RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+        return (0);
+    }
+
+    p = (unsigned char *)to;
+
+    *(p++) = 0;
+    *(p++) = 2;                 /* Public Key BT (Block Type) */
+
+    /* pad out with non-zero random data */
+    j = tlen - 3 - 8 - flen;
+
+    if (RAND_bytes(p, j) <= 0)
+        return (0);
+    for (i = 0; i < j; i++) {
+        if (*p == '\0')
+            do {
+                if (RAND_bytes(p, 1) <= 0)
+                    return (0);
+            } while (*p == '\0');
+        p++;
+    }
+
+    memset(p, 3, 8);
+    p += 8;
+    *(p++) = '\0';
+
+    memcpy(p, from, (unsigned int)flen);
+    return (1);
+}
+
+int RSA_padding_check_SSLv23(unsigned char *to, int tlen,
+                             const unsigned char *from, int flen, int num)
+{
+    int i, j, k;
+    const unsigned char *p;
+
+    p = from;
+    if (flen < 10) {
+        RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_SMALL);
+        return (-1);
+    }
+    if ((num != (flen + 1)) || (*(p++) != 02)) {
+        RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_BLOCK_TYPE_IS_NOT_02);
+        return (-1);
+    }
+
+    /* scan over padding data */
+    j = flen - 1;               /* one for type */
+    for (i = 0; i < j; i++)
+        if (*(p++) == 0)
+            break;
+
+    if ((i == j) || (i < 8)) {
+        RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,
+               RSA_R_NULL_BEFORE_BLOCK_MISSING);
+        return (-1);
+    }
+    for (k = -9; k < -1; k++) {
+        if (p[k] != 0x03)
+            break;
+    }
+    if (k == -1) {
+        RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_SSLV3_ROLLBACK_ATTACK);
+        return (-1);
+    }
+
+    i++;                        /* Skip over the '\0' */
+    j -= i;
+    if (j > tlen) {
+        RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_LARGE);
+        return (-1);
+    }
+    memcpy(to, p, (unsigned int)j);
+
+    return (j);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_x931.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_x931.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_x931.c	(revision 331)
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2005-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/objects.h>
+
+int RSA_padding_add_X931(unsigned char *to, int tlen,
+                         const unsigned char *from, int flen)
+{
+    int j;
+    unsigned char *p;
+
+    /*
+     * Absolute minimum amount of padding is 1 header nibble, 1 padding
+     * nibble and 2 trailer bytes: but 1 hash if is already in 'from'.
+     */
+
+    j = tlen - flen - 2;
+
+    if (j < 0) {
+        RSAerr(RSA_F_RSA_PADDING_ADD_X931, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+        return -1;
+    }
+
+    p = (unsigned char *)to;
+
+    /* If no padding start and end nibbles are in one byte */
+    if (j == 0)
+        *p++ = 0x6A;
+    else {
+        *p++ = 0x6B;
+        if (j > 1) {
+            memset(p, 0xBB, j - 1);
+            p += j - 1;
+        }
+        *p++ = 0xBA;
+    }
+    memcpy(p, from, (unsigned int)flen);
+    p += flen;
+    *p = 0xCC;
+    return (1);
+}
+
+int RSA_padding_check_X931(unsigned char *to, int tlen,
+                           const unsigned char *from, int flen, int num)
+{
+    int i = 0, j;
+    const unsigned char *p;
+
+    p = from;
+    if ((num != flen) || ((*p != 0x6A) && (*p != 0x6B))) {
+        RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_HEADER);
+        return -1;
+    }
+
+    if (*p++ == 0x6B) {
+        j = flen - 3;
+        for (i = 0; i < j; i++) {
+            unsigned char c = *p++;
+            if (c == 0xBA)
+                break;
+            if (c != 0xBB) {
+                RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING);
+                return -1;
+            }
+        }
+
+        j -= i;
+
+        if (i == 0) {
+            RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING);
+            return -1;
+        }
+
+    } else
+        j = flen - 2;
+
+    if (p[j] != 0xCC) {
+        RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_TRAILER);
+        return -1;
+    }
+
+    memcpy(to, p, (unsigned int)j);
+
+    return (j);
+}
+
+/* Translate between X931 hash ids and NIDs */
+
+int RSA_X931_hash_id(int nid)
+{
+    switch (nid) {
+    case NID_sha1:
+        return 0x33;
+
+    case NID_sha256:
+        return 0x34;
+
+    case NID_sha384:
+        return 0x36;
+
+    case NID_sha512:
+        return 0x35;
+
+    }
+    return -1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_x931g.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_x931g.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rsa/rsa_x931g.c	(revision 331)
@@ -0,0 +1,195 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include "rsa_locl.h"
+
+/* X9.31 RSA key derivation and generation */
+
+int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1,
+                       BIGNUM *q2, const BIGNUM *Xp1, const BIGNUM *Xp2,
+                       const BIGNUM *Xp, const BIGNUM *Xq1, const BIGNUM *Xq2,
+                       const BIGNUM *Xq, const BIGNUM *e, BN_GENCB *cb)
+{
+    BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL;
+    BN_CTX *ctx = NULL, *ctx2 = NULL;
+    int ret = 0;
+
+    if (!rsa)
+        goto err;
+
+    ctx = BN_CTX_new();
+    if (ctx == NULL)
+        goto err;
+    BN_CTX_start(ctx);
+
+    r0 = BN_CTX_get(ctx);
+    r1 = BN_CTX_get(ctx);
+    r2 = BN_CTX_get(ctx);
+    r3 = BN_CTX_get(ctx);
+
+    if (r3 == NULL)
+        goto err;
+    if (!rsa->e) {
+        rsa->e = BN_dup(e);
+        if (!rsa->e)
+            goto err;
+    } else
+        e = rsa->e;
+
+    /*
+     * If not all parameters present only calculate what we can. This allows
+     * test programs to output selective parameters.
+     */
+
+    if (Xp && rsa->p == NULL) {
+        rsa->p = BN_new();
+        if (rsa->p == NULL)
+            goto err;
+
+        if (!BN_X931_derive_prime_ex(rsa->p, p1, p2,
+                                     Xp, Xp1, Xp2, e, ctx, cb))
+            goto err;
+    }
+
+    if (Xq && rsa->q == NULL) {
+        rsa->q = BN_new();
+        if (rsa->q == NULL)
+            goto err;
+        if (!BN_X931_derive_prime_ex(rsa->q, q1, q2,
+                                     Xq, Xq1, Xq2, e, ctx, cb))
+            goto err;
+    }
+
+    if (rsa->p == NULL || rsa->q == NULL) {
+        BN_CTX_end(ctx);
+        BN_CTX_free(ctx);
+        return 2;
+    }
+
+    /*
+     * Since both primes are set we can now calculate all remaining
+     * components.
+     */
+
+    /* calculate n */
+    rsa->n = BN_new();
+    if (rsa->n == NULL)
+        goto err;
+    if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx))
+        goto err;
+
+    /* calculate d */
+    if (!BN_sub(r1, rsa->p, BN_value_one()))
+        goto err;               /* p-1 */
+    if (!BN_sub(r2, rsa->q, BN_value_one()))
+        goto err;               /* q-1 */
+    if (!BN_mul(r0, r1, r2, ctx))
+        goto err;               /* (p-1)(q-1) */
+
+    if (!BN_gcd(r3, r1, r2, ctx))
+        goto err;
+
+    if (!BN_div(r0, NULL, r0, r3, ctx))
+        goto err;               /* LCM((p-1)(q-1)) */
+
+    ctx2 = BN_CTX_new();
+    if (ctx2 == NULL)
+        goto err;
+
+    rsa->d = BN_mod_inverse(NULL, rsa->e, r0, ctx2); /* d */
+    if (rsa->d == NULL)
+        goto err;
+
+    /* calculate d mod (p-1) */
+    rsa->dmp1 = BN_new();
+    if (rsa->dmp1 == NULL)
+        goto err;
+    if (!BN_mod(rsa->dmp1, rsa->d, r1, ctx))
+        goto err;
+
+    /* calculate d mod (q-1) */
+    rsa->dmq1 = BN_new();
+    if (rsa->dmq1 == NULL)
+        goto err;
+    if (!BN_mod(rsa->dmq1, rsa->d, r2, ctx))
+        goto err;
+
+    /* calculate inverse of q mod p */
+    rsa->iqmp = BN_mod_inverse(NULL, rsa->q, rsa->p, ctx2);
+
+    ret = 1;
+ err:
+    if (ctx)
+        BN_CTX_end(ctx);
+    BN_CTX_free(ctx);
+    BN_CTX_free(ctx2);
+
+    return ret;
+
+}
+
+int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e,
+                             BN_GENCB *cb)
+{
+    int ok = 0;
+    BIGNUM *Xp = NULL, *Xq = NULL;
+    BN_CTX *ctx = NULL;
+
+    ctx = BN_CTX_new();
+    if (ctx == NULL)
+        goto error;
+
+    BN_CTX_start(ctx);
+    Xp = BN_CTX_get(ctx);
+    Xq = BN_CTX_get(ctx);
+    if (!BN_X931_generate_Xpq(Xp, Xq, bits, ctx))
+        goto error;
+
+    rsa->p = BN_new();
+    rsa->q = BN_new();
+    if (rsa->p == NULL || rsa->q == NULL)
+        goto error;
+
+    /* Generate two primes from Xp, Xq */
+
+    if (!BN_X931_generate_prime_ex(rsa->p, NULL, NULL, NULL, NULL, Xp,
+                                   e, ctx, cb))
+        goto error;
+
+    if (!BN_X931_generate_prime_ex(rsa->q, NULL, NULL, NULL, NULL, Xq,
+                                   e, ctx, cb))
+        goto error;
+
+    /*
+     * Since rsa->p and rsa->q are valid this call will just derive remaining
+     * RSA components.
+     */
+
+    if (!RSA_X931_derive_ex(rsa, NULL, NULL, NULL, NULL,
+                            NULL, NULL, NULL, NULL, NULL, NULL, e, cb))
+        goto error;
+
+    ok = 1;
+
+ error:
+    if (ctx)
+        BN_CTX_end(ctx);
+    BN_CTX_free(ctx);
+
+    if (ok)
+        return 1;
+
+    return 0;
+
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/seed/seed.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/seed/seed.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/seed/seed.c	(revision 331)
@@ -0,0 +1,590 @@
+/*
+ * Copyright 2007-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
+ */
+
+/*
+ * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Neither the name of author nor the names of its contributors may
+ *    be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#ifndef OPENSSL_NO_SEED
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
+# ifdef WIN32
+#  include <memory.h>
+# endif
+
+# include <openssl/seed.h>
+# include "seed_locl.h"
+
+# ifdef SS                      /* can get defined on Solaris by inclusion of
+                                 * <stdlib.h> */
+#  undef SS
+# endif
+
+# if !defined(OPENSSL_SMALL_FOOTPRINT)
+
+#  define G_FUNC(v)       \
+        SS[0][(unsigned char)      (v) & 0xff] ^ \
+        SS[1][(unsigned char) ((v)>>8) & 0xff] ^ \
+        SS[2][(unsigned char)((v)>>16) & 0xff] ^ \
+        SS[3][(unsigned char)((v)>>24) & 0xff]
+
+static const seed_word SS[4][256] = {
+    { 0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0,
+      0x14445054, 0x1d0d111c, 0x2c8ca0ac, 0x25052124,
+      0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c,
+      0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360,
+      0x28082028, 0x04444044, 0x20002020, 0x1d8d919c,
+      0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314,
+      0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378,
+      0x3b8bb3b8, 0x13031310, 0x12c2d2d0, 0x2ecee2ec,
+      0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8,
+      0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074,
+      0x2ccce0ec, 0x15859194, 0x0b0b0308, 0x17475354,
+      0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100,
+      0x24042024, 0x1c0c101c, 0x33437370, 0x18889098,
+      0x10001010, 0x0cccc0cc, 0x32c2f2f0, 0x19c9d1d8,
+      0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380,
+      0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8,
+      0x20406060, 0x10405050, 0x2383a3a0, 0x2bcbe3e8,
+      0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c,
+      0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078,
+      0x2686a2a4, 0x12021210, 0x2f8fa3ac, 0x15c5d1d4,
+      0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140,
+      0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008,
+      0x1f0f131c, 0x19899198, 0x00000000, 0x19091118,
+      0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0,
+      0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324,
+      0x3080b0b0, 0x0b8b8388, 0x0e0e020c, 0x2b8ba3a8,
+      0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c,
+      0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208,
+      0x3f8fb3bc, 0x2fcfe3ec, 0x33c3f3f0, 0x05c5c1c4,
+      0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064,
+      0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218,
+      0x06060204, 0x21012120, 0x2b4b6368, 0x26466264,
+      0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288,
+      0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0,
+      0x3a4a7278, 0x07474344, 0x16869294, 0x25c5e1e4,
+      0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc,
+      0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac,
+      0x36063234, 0x15051114, 0x22022220, 0x38083038,
+      0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c,
+      0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394,
+      0x35053134, 0x0bcbc3c8, 0x0ecec2cc, 0x3c0c303c,
+      0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188,
+      0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8,
+      0x14849094, 0x19495158, 0x02828280, 0x04c4c0c4,
+      0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364,
+      0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8,
+      0x0f0f030c, 0x0e8e828c, 0x02424240, 0x23032320,
+      0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4,
+      0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0,
+      0x2f4f636c, 0x3d0d313c, 0x2d0d212c, 0x00404040,
+      0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0,
+      0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154,
+      0x3b0b3338, 0x1cccd0dc, 0x28486068, 0x3f4f737c,
+      0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254,
+      0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244,
+      0x3585b1b4, 0x2b0b2328, 0x25456164, 0x3acaf2f8,
+      0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c,
+      0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0,
+      0x31013130, 0x2acae2e8, 0x2d4d616c, 0x1f4f535c,
+      0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088,
+      0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4,
+      0x22426260, 0x29092128, 0x07070304, 0x33033330,
+      0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178,
+      0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298
+    },
+    { 0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2,
+      0xcc0fcfc3, 0xdc1eced2, 0xb03383b3, 0xb83888b0,
+      0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3,
+      0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53,
+      0xc003c3c3, 0x60224262, 0x30330333, 0xb43585b1,
+      0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3,
+      0xd013c3d3, 0x90118191, 0x10110111, 0x04060602,
+      0x1c1c0c10, 0xbc3c8cb0, 0x34360632, 0x480b4b43,
+      0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0,
+      0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0,
+      0xc002c2c2, 0x44054541, 0xe021c1e1, 0xd416c6d2,
+      0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890,
+      0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32,
+      0xa42585a1, 0xf839c9f1, 0x0c0d0d01, 0xdc1fcfd3,
+      0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72,
+      0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272,
+      0x40024242, 0xd414c4d0, 0x40014141, 0xc000c0c0,
+      0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83,
+      0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13,
+      0xc80acac2, 0x2c2c0c20, 0xa82a8aa2, 0x34340430,
+      0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1,
+      0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0,
+      0x54174753, 0xac2e8ea2, 0x08080800, 0xc405c5c1,
+      0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1,
+      0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131,
+      0xf435c5f1, 0x880a8a82, 0x682a4a62, 0xb03181b1,
+      0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202,
+      0x20220222, 0x04040400, 0x68284860, 0x70314171,
+      0x04070703, 0xd81bcbd3, 0x9c1d8d91, 0x98198991,
+      0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951,
+      0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0,
+      0x981a8a92, 0xa02383a3, 0xa82b8ba3, 0xd010c0d0,
+      0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12,
+      0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3,
+      0x94168692, 0x783b4b73, 0x5c1c4c50, 0xa02282a2,
+      0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41,
+      0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32,
+      0x0c0c0c00, 0x2c2e0e22, 0xb83a8ab2, 0x6c2e4e62,
+      0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292,
+      0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0,
+      0x14150511, 0xf83bcbf3, 0x70304070, 0x74354571,
+      0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303,
+      0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470,
+      0xd415c5d1, 0xb43484b0, 0xe82acae2, 0x08090901,
+      0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040,
+      0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501,
+      0xf83acaf2, 0x00010101, 0xf030c0f0, 0x282a0a22,
+      0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343,
+      0x84058581, 0x14140410, 0x88098981, 0x981b8b93,
+      0xb03080b0, 0xe425c5e1, 0x48084840, 0x78394971,
+      0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282,
+      0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53,
+      0x74374773, 0x54144450, 0xb03282b2, 0x1c1d0d11,
+      0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642,
+      0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3,
+      0x7c3e4e72, 0xd81acad2, 0xc809c9c1, 0xfc3dcdf1,
+      0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30,
+      0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70,
+      0x0c0e0e02, 0x50104050, 0x38390931, 0x24260622,
+      0x30320232, 0x84048480, 0x68294961, 0x90138393,
+      0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0,
+      0xc80bcbc3, 0x50134353, 0x080a0a02, 0x84078783,
+      0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83,
+      0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3
+    },
+    { 0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3,
+      0x50541444, 0x111c1d0d, 0xa0ac2c8c, 0x21242505,
+      0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e,
+      0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343,
+      0x20282808, 0x40440444, 0x20202000, 0x919c1d8d,
+      0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707,
+      0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b,
+      0xb3b83b8b, 0x13101303, 0xd2d012c2, 0xe2ec2ece,
+      0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888,
+      0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444,
+      0xe0ec2ccc, 0x91941585, 0x03080b0b, 0x53541747,
+      0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101,
+      0x20242404, 0x101c1c0c, 0x73703343, 0x90981888,
+      0x10101000, 0xc0cc0ccc, 0xf2f032c2, 0xd1d819c9,
+      0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383,
+      0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9,
+      0x60602040, 0x50501040, 0xa3a02383, 0xe3e82bcb,
+      0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f,
+      0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848,
+      0xa2a42686, 0x12101202, 0xa3ac2f8f, 0xd1d415c5,
+      0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141,
+      0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808,
+      0x131c1f0f, 0x91981989, 0x00000000, 0x11181909,
+      0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1,
+      0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707,
+      0xb0b03080, 0x83880b8b, 0x020c0e0e, 0xa3a82b8b,
+      0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d,
+      0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a,
+      0xb3bc3f8f, 0xe3ec2fcf, 0xf3f033c3, 0xc1c405c5,
+      0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444,
+      0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a,
+      0x02040606, 0x21202101, 0x63682b4b, 0x62642646,
+      0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a,
+      0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0,
+      0x72783a4a, 0x43440747, 0x92941686, 0xe1e425c5,
+      0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf,
+      0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e,
+      0x32343606, 0x11141505, 0x22202202, 0x30383808,
+      0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c,
+      0x81800181, 0xe1e829c9, 0x80840484, 0x93941787,
+      0x31343505, 0xc3c80bcb, 0xc2cc0ece, 0x303c3c0c,
+      0x71703141, 0x11101101, 0xc3c407c7, 0x81880989,
+      0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8,
+      0x90941484, 0x51581949, 0x82800282, 0xc0c404c4,
+      0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747,
+      0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888,
+      0x030c0f0f, 0x828c0e8e, 0x42400242, 0x23202303,
+      0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484,
+      0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2,
+      0x636c2f4f, 0x313c3d0d, 0x212c2d0d, 0x40400040,
+      0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1,
+      0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545,
+      0x33383b0b, 0xd0dc1ccc, 0x60682848, 0x737c3f4f,
+      0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646,
+      0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646,
+      0xb1b43585, 0x23282b0b, 0x61642545, 0xf2f83aca,
+      0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f,
+      0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282,
+      0x31303101, 0xe2e82aca, 0x616c2d4d, 0x535c1f4f,
+      0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888,
+      0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4,
+      0x62602242, 0x21282909, 0x03040707, 0x33303303,
+      0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949,
+      0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a
+    },
+    { 0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426,
+      0xcfc3cc0f, 0xced2dc1e, 0x83b3b033, 0x88b0b838,
+      0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407,
+      0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b,
+      0xc3c3c003, 0x42626022, 0x03333033, 0x85b1b435,
+      0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427,
+      0xc3d3d013, 0x81919011, 0x01111011, 0x06020406,
+      0x0c101c1c, 0x8cb0bc3c, 0x06323436, 0x4b43480b,
+      0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828,
+      0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434,
+      0xc2c2c002, 0x45414405, 0xc1e1e021, 0xc6d2d416,
+      0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818,
+      0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e,
+      0x85a1a425, 0xc9f1f839, 0x0d010c0d, 0xcfd3dc1f,
+      0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a,
+      0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032,
+      0x42424002, 0xc4d0d414, 0x41414001, 0xc0c0c000,
+      0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b,
+      0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f,
+      0xcac2c80a, 0x0c202c2c, 0x8aa2a82a, 0x04303434,
+      0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829,
+      0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838,
+      0x47535417, 0x8ea2ac2e, 0x08000808, 0xc5c1c405,
+      0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839,
+      0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031,
+      0xc5f1f435, 0x8a82880a, 0x4a62682a, 0x81b1b031,
+      0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002,
+      0x02222022, 0x04000404, 0x48606828, 0x41717031,
+      0x07030407, 0xcbd3d81b, 0x8d919c1d, 0x89919819,
+      0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819,
+      0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c,
+      0x8a92981a, 0x83a3a023, 0x8ba3a82b, 0xc0d0d010,
+      0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a,
+      0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f,
+      0x86929416, 0x4b73783b, 0x4c505c1c, 0x82a2a022,
+      0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d,
+      0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a,
+      0x0c000c0c, 0x0e222c2e, 0x8ab2b83a, 0x4e626c2e,
+      0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012,
+      0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c,
+      0x05111415, 0xcbf3f83b, 0x40707030, 0x45717435,
+      0x4f737c3f, 0x05313435, 0x00101010, 0x03030003,
+      0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434,
+      0xc5d1d415, 0x84b0b434, 0xcae2e82a, 0x09010809,
+      0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000,
+      0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405,
+      0xcaf2f83a, 0x01010001, 0xc0f0f030, 0x0a22282a,
+      0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003,
+      0x85818405, 0x04101414, 0x89818809, 0x8b93981b,
+      0x80b0b030, 0xc5e1e425, 0x48404808, 0x49717839,
+      0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002,
+      0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f,
+      0x47737437, 0x44505414, 0x82b2b032, 0x0d111c1d,
+      0x05212425, 0x4f434c0f, 0x00000000, 0x46424406,
+      0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b,
+      0x4e727c3e, 0xcad2d81a, 0xc9c1c809, 0xcdf1fc3d,
+      0x00303030, 0x85919415, 0x45616425, 0x0c303c3c,
+      0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c,
+      0x0e020c0e, 0x40505010, 0x09313839, 0x06222426,
+      0x02323032, 0x84808404, 0x49616829, 0x83939013,
+      0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424,
+      0xcbc3c80b, 0x43535013, 0x0a02080a, 0x87838407,
+      0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f,
+      0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437
+    }
+};
+
+#else
+
+/* on x86_64 >5x size reduction at 40% performance penalty */
+static const unsigned char SEED_Sbox[2][256] = {
+{
+      0xA9, 0x85, 0xD6, 0xD3, 0x54, 0x1D, 0xAC, 0x25,
+      0x5D, 0x43, 0x18, 0x1E, 0x51, 0xFC, 0xCA, 0x63,
+      0x28, 0x44, 0x20, 0x9D, 0xE0, 0xE2, 0xC8, 0x17,
+      0xA5, 0x8F, 0x03, 0x7B, 0xBB, 0x13, 0xD2, 0xEE,
+      0x70, 0x8C, 0x3F, 0xA8, 0x32, 0xDD, 0xF6, 0x74,
+      0xEC, 0x95, 0x0B, 0x57, 0x5C, 0x5B, 0xBD, 0x01,
+      0x24, 0x1C, 0x73, 0x98, 0x10, 0xCC, 0xF2, 0xD9,
+      0x2C, 0xE7, 0x72, 0x83, 0x9B, 0xD1, 0x86, 0xC9,
+      0x60, 0x50, 0xA3, 0xEB, 0x0D, 0xB6, 0x9E, 0x4F,
+      0xB7, 0x5A, 0xC6, 0x78, 0xA6, 0x12, 0xAF, 0xD5,
+      0x61, 0xC3, 0xB4, 0x41, 0x52, 0x7D, 0x8D, 0x08,
+      0x1F, 0x99, 0x00, 0x19, 0x04, 0x53, 0xF7, 0xE1,
+      0xFD, 0x76, 0x2F, 0x27, 0xB0, 0x8B, 0x0E, 0xAB,
+      0xA2, 0x6E, 0x93, 0x4D, 0x69, 0x7C, 0x09, 0x0A,
+      0xBF, 0xEF, 0xF3, 0xC5, 0x87, 0x14, 0xFE, 0x64,
+      0xDE, 0x2E, 0x4B, 0x1A, 0x06, 0x21, 0x6B, 0x66,
+      0x02, 0xF5, 0x92, 0x8A, 0x0C, 0xB3, 0x7E, 0xD0,
+      0x7A, 0x47, 0x96, 0xE5, 0x26, 0x80, 0xAD, 0xDF,
+      0xA1, 0x30, 0x37, 0xAE, 0x36, 0x15, 0x22, 0x38,
+      0xF4, 0xA7, 0x45, 0x4C, 0x81, 0xE9, 0x84, 0x97,
+      0x35, 0xCB, 0xCE, 0x3C, 0x71, 0x11, 0xC7, 0x89,
+      0x75, 0xFB, 0xDA, 0xF8, 0x94, 0x59, 0x82, 0xC4,
+      0xFF, 0x49, 0x39, 0x67, 0xC0, 0xCF, 0xD7, 0xB8,
+      0x0F, 0x8E, 0x42, 0x23, 0x91, 0x6C, 0xDB, 0xA4,
+      0x34, 0xF1, 0x48, 0xC2, 0x6F, 0x3D, 0x2D, 0x40,
+      0xBE, 0x3E, 0xBC, 0xC1, 0xAA, 0xBA, 0x4E, 0x55,
+      0x3B, 0xDC, 0x68, 0x7F, 0x9C, 0xD8, 0x4A, 0x56,
+      0x77, 0xA0, 0xED, 0x46, 0xB5, 0x2B, 0x65, 0xFA,
+      0xE3, 0xB9, 0xB1, 0x9F, 0x5E, 0xF9, 0xE6, 0xB2,
+      0x31, 0xEA, 0x6D, 0x5F, 0xE4, 0xF0, 0xCD, 0x88,
+      0x16, 0x3A, 0x58, 0xD4, 0x62, 0x29, 0x07, 0x33,
+      0xE8, 0x1B, 0x05, 0x79, 0x90, 0x6A, 0x2A, 0x9A
+    },
+    {
+      0x38, 0xE8, 0x2D, 0xA6, 0xCF, 0xDE, 0xB3, 0xB8,
+      0xAF, 0x60, 0x55, 0xC7, 0x44, 0x6F, 0x6B, 0x5B,
+      0xC3, 0x62, 0x33, 0xB5, 0x29, 0xA0, 0xE2, 0xA7,
+      0xD3, 0x91, 0x11, 0x06, 0x1C, 0xBC, 0x36, 0x4B,
+      0xEF, 0x88, 0x6C, 0xA8, 0x17, 0xC4, 0x16, 0xF4,
+      0xC2, 0x45, 0xE1, 0xD6, 0x3F, 0x3D, 0x8E, 0x98,
+      0x28, 0x4E, 0xF6, 0x3E, 0xA5, 0xF9, 0x0D, 0xDF,
+      0xD8, 0x2B, 0x66, 0x7A, 0x27, 0x2F, 0xF1, 0x72,
+      0x42, 0xD4, 0x41, 0xC0, 0x73, 0x67, 0xAC, 0x8B,
+      0xF7, 0xAD, 0x80, 0x1F, 0xCA, 0x2C, 0xAA, 0x34,
+      0xD2, 0x0B, 0xEE, 0xE9, 0x5D, 0x94, 0x18, 0xF8,
+      0x57, 0xAE, 0x08, 0xC5, 0x13, 0xCD, 0x86, 0xB9,
+      0xFF, 0x7D, 0xC1, 0x31, 0xF5, 0x8A, 0x6A, 0xB1,
+      0xD1, 0x20, 0xD7, 0x02, 0x22, 0x04, 0x68, 0x71,
+      0x07, 0xDB, 0x9D, 0x99, 0x61, 0xBE, 0xE6, 0x59,
+      0xDD, 0x51, 0x90, 0xDC, 0x9A, 0xA3, 0xAB, 0xD0,
+      0x81, 0x0F, 0x47, 0x1A, 0xE3, 0xEC, 0x8D, 0xBF,
+      0x96, 0x7B, 0x5C, 0xA2, 0xA1, 0x63, 0x23, 0x4D,
+      0xC8, 0x9E, 0x9C, 0x3A, 0x0C, 0x2E, 0xBA, 0x6E,
+      0x9F, 0x5A, 0xF2, 0x92, 0xF3, 0x49, 0x78, 0xCC,
+      0x15, 0xFB, 0x70, 0x75, 0x7F, 0x35, 0x10, 0x03,
+      0x64, 0x6D, 0xC6, 0x74, 0xD5, 0xB4, 0xEA, 0x09,
+      0x76, 0x19, 0xFE, 0x40, 0x12, 0xE0, 0xBD, 0x05,
+      0xFA, 0x01, 0xF0, 0x2A, 0x5E, 0xA9, 0x56, 0x43,
+      0x85, 0x14, 0x89, 0x9B, 0xB0, 0xE5, 0x48, 0x79,
+      0x97, 0xFC, 0x1E, 0x82, 0x21, 0x8C, 0x1B, 0x5F,
+      0x77, 0x54, 0xB2, 0x1D, 0x25, 0x4F, 0x00, 0x46,
+      0xED, 0x58, 0x52, 0xEB, 0x7E, 0xDA, 0xC9, 0xFD,
+      0x30, 0x95, 0x65, 0x3C, 0xB6, 0xE4, 0xBB, 0x7C,
+      0x0E, 0x50, 0x39, 0x26, 0x32, 0x84, 0x69, 0x93,
+      0x37, 0xE7, 0x24, 0xA4, 0xCB, 0x53, 0x0A, 0x87,
+      0xD9, 0x4C, 0x83, 0x8F, 0xCE, 0x3B, 0x4A, 0xB7
+    }
+};
+
+static unsigned int G_FUNC(unsigned int v)
+{
+    unsigned int s0, s1, s2, s3, ret;
+
+    s0 = SEED_Sbox[0][(unsigned char)      (v) & 0xff];
+    s1 = SEED_Sbox[1][(unsigned char)((v)>> 8) & 0xff];
+    s2 = SEED_Sbox[0][(unsigned char)((v)>>16) & 0xff];
+    s3 = SEED_Sbox[1][(unsigned char)((v)>>24) & 0xff];
+
+    ret  = ((s0 & 0xFC) ^ (s1 & 0xF3) ^ (s2 & 0xCF) ^ (s3 & 0x3F));
+    ret |= ((s0 & 0xF3) ^ (s1 & 0xCF) ^ (s2 & 0x3F) ^ (s3 & 0xFC)) << 8;
+    ret |= ((s0 & 0xCF) ^ (s1 & 0x3F) ^ (s2 & 0xFC) ^ (s3 & 0xF3)) << 16;
+    ret |= ((s0 & 0x3F) ^ (s1 & 0xFC) ^ (s2 & 0xF3) ^ (s3 & 0xCF)) << 24;
+
+    return ret;
+}
+# endif
+
+/* key schedule constants - golden ratio */
+# define KC0     0x9e3779b9
+# define KC1     0x3c6ef373
+# define KC2     0x78dde6e6
+# define KC3     0xf1bbcdcc
+# define KC4     0xe3779b99
+# define KC5     0xc6ef3733
+# define KC6     0x8dde6e67
+# define KC7     0x1bbcdccf
+# define KC8     0x3779b99e
+# define KC9     0x6ef3733c
+# define KC10    0xdde6e678
+# define KC11    0xbbcdccf1
+# define KC12    0x779b99e3
+# define KC13    0xef3733c6
+# define KC14    0xde6e678d
+# define KC15    0xbcdccf1b
+
+# if defined(OPENSSL_SMALL_FOOTPRINT)
+static const seed_word KC[] = {
+    KC0, KC1, KC2, KC3, KC4, KC5, KC6, KC7,
+    KC8, KC9, KC10, KC11, KC12, KC13, KC14, KC15
+};
+# endif
+
+void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH],
+                  SEED_KEY_SCHEDULE *ks)
+{
+    seed_word x1, x2, x3, x4;
+    seed_word t0, t1;
+
+    char2word(rawkey, x1);
+    char2word(rawkey + 4, x2);
+    char2word(rawkey + 8, x3);
+    char2word(rawkey + 12, x4);
+
+    t0 = (x1 + x3 - KC0) & 0xffffffff;
+    t1 = (x2 - x4 + KC0) & 0xffffffff;
+    KEYUPDATE_TEMP(t0, t1, &ks->data[0]);
+    KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC1);
+    KEYUPDATE_TEMP(t0, t1, &ks->data[2]);
+
+# if !defined(OPENSSL_SMALL_FOOTPRINT)
+    KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC2);
+    KEYUPDATE_TEMP(t0, t1, &ks->data[4]);
+    KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC3);
+    KEYUPDATE_TEMP(t0, t1, &ks->data[6]);
+    KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC4);
+    KEYUPDATE_TEMP(t0, t1, &ks->data[8]);
+    KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC5);
+    KEYUPDATE_TEMP(t0, t1, &ks->data[10]);
+    KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC6);
+    KEYUPDATE_TEMP(t0, t1, &ks->data[12]);
+    KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC7);
+    KEYUPDATE_TEMP(t0, t1, &ks->data[14]);
+    KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC8);
+    KEYUPDATE_TEMP(t0, t1, &ks->data[16]);
+    KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC9);
+    KEYUPDATE_TEMP(t0, t1, &ks->data[18]);
+    KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC10);
+    KEYUPDATE_TEMP(t0, t1, &ks->data[20]);
+    KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC11);
+    KEYUPDATE_TEMP(t0, t1, &ks->data[22]);
+    KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC12);
+    KEYUPDATE_TEMP(t0, t1, &ks->data[24]);
+    KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC13);
+    KEYUPDATE_TEMP(t0, t1, &ks->data[26]);
+    KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC14);
+    KEYUPDATE_TEMP(t0, t1, &ks->data[28]);
+    KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC15);
+    KEYUPDATE_TEMP(t0, t1, &ks->data[30]);
+# else
+    {
+        int i;
+        for (i = 2; i < 16; i += 2) {
+            KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC[i]);
+            KEYUPDATE_TEMP(t0, t1, &ks->data[i * 2]);
+            KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC[i + 1]);
+            KEYUPDATE_TEMP(t0, t1, &ks->data[i * 2 + 2]);
+        }
+    }
+# endif
+}
+
+void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE],
+                  unsigned char d[SEED_BLOCK_SIZE],
+                  const SEED_KEY_SCHEDULE *ks)
+{
+    seed_word x1, x2, x3, x4;
+    seed_word t0, t1;
+
+    char2word(s, x1);
+    char2word(s + 4, x2);
+    char2word(s + 8, x3);
+    char2word(s + 12, x4);
+
+# if !defined(OPENSSL_SMALL_FOOTPRINT)
+    E_SEED(t0, t1, x1, x2, x3, x4, 0);
+    E_SEED(t0, t1, x3, x4, x1, x2, 2);
+    E_SEED(t0, t1, x1, x2, x3, x4, 4);
+    E_SEED(t0, t1, x3, x4, x1, x2, 6);
+    E_SEED(t0, t1, x1, x2, x3, x4, 8);
+    E_SEED(t0, t1, x3, x4, x1, x2, 10);
+    E_SEED(t0, t1, x1, x2, x3, x4, 12);
+    E_SEED(t0, t1, x3, x4, x1, x2, 14);
+    E_SEED(t0, t1, x1, x2, x3, x4, 16);
+    E_SEED(t0, t1, x3, x4, x1, x2, 18);
+    E_SEED(t0, t1, x1, x2, x3, x4, 20);
+    E_SEED(t0, t1, x3, x4, x1, x2, 22);
+    E_SEED(t0, t1, x1, x2, x3, x4, 24);
+    E_SEED(t0, t1, x3, x4, x1, x2, 26);
+    E_SEED(t0, t1, x1, x2, x3, x4, 28);
+    E_SEED(t0, t1, x3, x4, x1, x2, 30);
+# else
+    {
+        int i;
+        for (i = 0; i < 30; i += 4) {
+            E_SEED(t0, t1, x1, x2, x3, x4, i);
+            E_SEED(t0, t1, x3, x4, x1, x2, i + 2);
+        }
+    }
+# endif
+
+    word2char(x3, d);
+    word2char(x4, d + 4);
+    word2char(x1, d + 8);
+    word2char(x2, d + 12);
+}
+
+void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE],
+                  unsigned char d[SEED_BLOCK_SIZE],
+                  const SEED_KEY_SCHEDULE *ks)
+{
+    seed_word x1, x2, x3, x4;
+    seed_word t0, t1;
+
+    char2word(s, x1);
+    char2word(s + 4, x2);
+    char2word(s + 8, x3);
+    char2word(s + 12, x4);
+
+# if !defined(OPENSSL_SMALL_FOOTPRINT)
+    E_SEED(t0, t1, x1, x2, x3, x4, 30);
+    E_SEED(t0, t1, x3, x4, x1, x2, 28);
+    E_SEED(t0, t1, x1, x2, x3, x4, 26);
+    E_SEED(t0, t1, x3, x4, x1, x2, 24);
+    E_SEED(t0, t1, x1, x2, x3, x4, 22);
+    E_SEED(t0, t1, x3, x4, x1, x2, 20);
+    E_SEED(t0, t1, x1, x2, x3, x4, 18);
+    E_SEED(t0, t1, x3, x4, x1, x2, 16);
+    E_SEED(t0, t1, x1, x2, x3, x4, 14);
+    E_SEED(t0, t1, x3, x4, x1, x2, 12);
+    E_SEED(t0, t1, x1, x2, x3, x4, 10);
+    E_SEED(t0, t1, x3, x4, x1, x2, 8);
+    E_SEED(t0, t1, x1, x2, x3, x4, 6);
+    E_SEED(t0, t1, x3, x4, x1, x2, 4);
+    E_SEED(t0, t1, x1, x2, x3, x4, 2);
+    E_SEED(t0, t1, x3, x4, x1, x2, 0);
+# else
+    {
+        int i;
+        for (i = 30; i > 0; i -= 4) {
+            E_SEED(t0, t1, x1, x2, x3, x4, i);
+            E_SEED(t0, t1, x3, x4, x1, x2, i - 2);
+
+        }
+    }
+# endif
+
+    word2char(x3, d);
+    word2char(x4, d + 4);
+    word2char(x1, d + 8);
+    word2char(x2, d + 12);
+}
+
+#endif                          /* OPENSSL_NO_SEED */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/seed/seed_cbc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/seed/seed_cbc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/seed/seed_cbc.c	(revision 331)
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2007-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 <openssl/seed.h>
+#include <openssl/modes.h>
+
+void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                      size_t len, const SEED_KEY_SCHEDULE *ks,
+                      unsigned char ivec[SEED_BLOCK_SIZE], int enc)
+{
+    if (enc)
+        CRYPTO_cbc128_encrypt(in, out, len, ks, ivec,
+                              (block128_f) SEED_encrypt);
+    else
+        CRYPTO_cbc128_decrypt(in, out, len, ks, ivec,
+                              (block128_f) SEED_decrypt);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/seed/seed_cfb.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/seed/seed_cfb.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/seed/seed_cfb.c	(revision 331)
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2007-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 <openssl/seed.h>
+#include <openssl/modes.h>
+
+void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+                         size_t len, const SEED_KEY_SCHEDULE *ks,
+                         unsigned char ivec[SEED_BLOCK_SIZE], int *num,
+                         int enc)
+{
+    CRYPTO_cfb128_encrypt(in, out, len, ks, ivec, num, enc,
+                          (block128_f) SEED_encrypt);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/seed/seed_ecb.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/seed/seed_ecb.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/seed/seed_ecb.c	(revision 331)
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2007-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 <openssl/seed.h>
+
+void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                      const SEED_KEY_SCHEDULE *ks, int enc)
+{
+    if (enc)
+        SEED_encrypt(in, out, ks);
+    else
+        SEED_decrypt(in, out, ks);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/seed/seed_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/seed/seed_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/seed/seed_locl.h	(revision 331)
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2007-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
+ */
+
+/*
+ * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Neither the name of author nor the names of its contributors may
+ *    be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#ifndef HEADER_SEED_LOCL_H
+# define HEADER_SEED_LOCL_H
+
+# include "openssl/e_os2.h"
+# include <openssl/seed.h>
+
+# ifdef SEED_LONG               /* need 32-bit type */
+typedef unsigned long seed_word;
+# else
+typedef unsigned int seed_word;
+# endif
+
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define char2word(c, i)  \
+        (i) = ((((seed_word)(c)[0]) << 24) | (((seed_word)(c)[1]) << 16) | (((seed_word)(c)[2]) << 8) | ((seed_word)(c)[3]))
+
+# define word2char(l, c)  \
+        *((c)+0) = (unsigned char)((l)>>24) & 0xff; \
+        *((c)+1) = (unsigned char)((l)>>16) & 0xff; \
+        *((c)+2) = (unsigned char)((l)>> 8) & 0xff; \
+        *((c)+3) = (unsigned char)((l))     & 0xff
+
+# define KEYSCHEDULE_UPDATE0(T0, T1, X1, X2, X3, X4, KC)  \
+        (T0) = (X3);                                     \
+        (X3) = (((X3)<<8) ^ ((X4)>>24)) & 0xffffffff;    \
+        (X4) = (((X4)<<8) ^ ((T0)>>24)) & 0xffffffff;    \
+        (T0) = ((X1) + (X3) - (KC))     & 0xffffffff;    \
+        (T1) = ((X2) + (KC) - (X4))     & 0xffffffff
+
+# define KEYSCHEDULE_UPDATE1(T0, T1, X1, X2, X3, X4, KC)  \
+        (T0) = (X1);                                     \
+        (X1) = (((X1)>>8) ^ ((X2)<<24)) & 0xffffffff;    \
+        (X2) = (((X2)>>8) ^ ((T0)<<24)) & 0xffffffff;    \
+        (T0) = ((X1) + (X3) - (KC))     & 0xffffffff;     \
+        (T1) = ((X2) + (KC) - (X4))     & 0xffffffff
+
+# define KEYUPDATE_TEMP(T0, T1, K)   \
+        (K)[0] = G_FUNC((T0));      \
+        (K)[1] = G_FUNC((T1))
+
+# define XOR_SEEDBLOCK(DST, SRC)      \
+        ((DST))[0] ^= ((SRC))[0];    \
+        ((DST))[1] ^= ((SRC))[1];    \
+        ((DST))[2] ^= ((SRC))[2];    \
+        ((DST))[3] ^= ((SRC))[3]
+
+# define MOV_SEEDBLOCK(DST, SRC)      \
+        ((DST))[0] = ((SRC))[0];     \
+        ((DST))[1] = ((SRC))[1];     \
+        ((DST))[2] = ((SRC))[2];     \
+        ((DST))[3] = ((SRC))[3]
+
+# define CHAR2WORD(C, I)              \
+        char2word((C),    (I)[0]);    \
+        char2word((C+4),  (I)[1]);    \
+        char2word((C+8),  (I)[2]);    \
+        char2word((C+12), (I)[3])
+
+# define WORD2CHAR(I, C)              \
+        word2char((I)[0], (C));       \
+        word2char((I)[1], (C+4));     \
+        word2char((I)[2], (C+8));     \
+        word2char((I)[3], (C+12))
+
+# define E_SEED(T0, T1, X1, X2, X3, X4, rbase)   \
+        (T0) = (X3) ^ (ks->data)[(rbase)];       \
+        (T1) = (X4) ^ (ks->data)[(rbase)+1];     \
+        (T1) ^= (T0);                            \
+        (T1) = G_FUNC((T1));                     \
+        (T0) = ((T0) + (T1)) & 0xffffffff;       \
+        (T0) = G_FUNC((T0));                     \
+        (T1) = ((T1) + (T0)) & 0xffffffff;       \
+        (T1) = G_FUNC((T1));                     \
+        (T0) = ((T0) + (T1)) & 0xffffffff;       \
+        (X1) ^= (T0);                            \
+        (X2) ^= (T1)
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif                          /* HEADER_SEED_LOCL_H */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/seed/seed_ofb.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/seed/seed_ofb.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/seed/seed_ofb.c	(revision 331)
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2007-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 <openssl/seed.h>
+#include <openssl/modes.h>
+
+void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+                         size_t len, const SEED_KEY_SCHEDULE *ks,
+                         unsigned char ivec[SEED_BLOCK_SIZE], int *num)
+{
+    CRYPTO_ofb128_encrypt(in, out, len, ks, ivec, num,
+                          (block128_f) SEED_encrypt);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/sha/sha1_one.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/sha/sha1_one.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/sha/sha1_one.c	(revision 331)
@@ -0,0 +1,28 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <string.h>
+#include <openssl/crypto.h>
+#include <openssl/sha.h>
+
+unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md)
+{
+    SHA_CTX c;
+    static unsigned char m[SHA_DIGEST_LENGTH];
+
+    if (md == NULL)
+        md = m;
+    if (!SHA1_Init(&c))
+        return NULL;
+    SHA1_Update(&c, d, n);
+    SHA1_Final(md, &c);
+    OPENSSL_cleanse(&c, sizeof(c));
+    return (md);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/sha/sha1dgst.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/sha/sha1dgst.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/sha/sha1dgst.c	(revision 331)
@@ -0,0 +1,17 @@
+/*
+ * Copyright 1995-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 <openssl/crypto.h>
+#include <openssl/opensslconf.h>
+
+# include <openssl/opensslv.h>
+
+/* The implementation is in ../md32_common.h */
+
+# include "sha_locl.h"
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/sha/sha256.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/sha/sha256.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/sha/sha256.c	(revision 331)
@@ -0,0 +1,386 @@
+/*
+ * Copyright 2004-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 <openssl/opensslconf.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/crypto.h>
+#include <openssl/sha.h>
+#include <openssl/opensslv.h>
+
+int SHA224_Init(SHA256_CTX *c)
+{
+    memset(c, 0, sizeof(*c));
+    c->h[0] = 0xc1059ed8UL;
+    c->h[1] = 0x367cd507UL;
+    c->h[2] = 0x3070dd17UL;
+    c->h[3] = 0xf70e5939UL;
+    c->h[4] = 0xffc00b31UL;
+    c->h[5] = 0x68581511UL;
+    c->h[6] = 0x64f98fa7UL;
+    c->h[7] = 0xbefa4fa4UL;
+    c->md_len = SHA224_DIGEST_LENGTH;
+    return 1;
+}
+
+int SHA256_Init(SHA256_CTX *c)
+{
+    memset(c, 0, sizeof(*c));
+    c->h[0] = 0x6a09e667UL;
+    c->h[1] = 0xbb67ae85UL;
+    c->h[2] = 0x3c6ef372UL;
+    c->h[3] = 0xa54ff53aUL;
+    c->h[4] = 0x510e527fUL;
+    c->h[5] = 0x9b05688cUL;
+    c->h[6] = 0x1f83d9abUL;
+    c->h[7] = 0x5be0cd19UL;
+    c->md_len = SHA256_DIGEST_LENGTH;
+    return 1;
+}
+
+unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md)
+{
+    SHA256_CTX c;
+    static unsigned char m[SHA224_DIGEST_LENGTH];
+
+    if (md == NULL)
+        md = m;
+    SHA224_Init(&c);
+    SHA256_Update(&c, d, n);
+    SHA256_Final(md, &c);
+    OPENSSL_cleanse(&c, sizeof(c));
+    return (md);
+}
+
+unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md)
+{
+    SHA256_CTX c;
+    static unsigned char m[SHA256_DIGEST_LENGTH];
+
+    if (md == NULL)
+        md = m;
+    SHA256_Init(&c);
+    SHA256_Update(&c, d, n);
+    SHA256_Final(md, &c);
+    OPENSSL_cleanse(&c, sizeof(c));
+    return (md);
+}
+
+int SHA224_Update(SHA256_CTX *c, const void *data, size_t len)
+{
+    return SHA256_Update(c, data, len);
+}
+
+int SHA224_Final(unsigned char *md, SHA256_CTX *c)
+{
+    return SHA256_Final(md, c);
+}
+
+#define DATA_ORDER_IS_BIG_ENDIAN
+
+#define HASH_LONG               SHA_LONG
+#define HASH_CTX                SHA256_CTX
+#define HASH_CBLOCK             SHA_CBLOCK
+
+/*
+ * Note that FIPS180-2 discusses "Truncation of the Hash Function Output."
+ * default: case below covers for it. It's not clear however if it's
+ * permitted to truncate to amount of bytes not divisible by 4. I bet not,
+ * but if it is, then default: case shall be extended. For reference.
+ * Idea behind separate cases for pre-defined lengths is to let the
+ * compiler decide if it's appropriate to unroll small loops.
+ */
+#define HASH_MAKE_STRING(c,s)   do {    \
+        unsigned long ll;               \
+        unsigned int  nn;               \
+        switch ((c)->md_len)            \
+        {   case SHA224_DIGEST_LENGTH:  \
+                for (nn=0;nn<SHA224_DIGEST_LENGTH/4;nn++)       \
+                {   ll=(c)->h[nn]; (void)HOST_l2c(ll,(s));   }  \
+                break;                  \
+            case SHA256_DIGEST_LENGTH:  \
+                for (nn=0;nn<SHA256_DIGEST_LENGTH/4;nn++)       \
+                {   ll=(c)->h[nn]; (void)HOST_l2c(ll,(s));   }  \
+                break;                  \
+            default:                    \
+                if ((c)->md_len > SHA256_DIGEST_LENGTH) \
+                    return 0;                           \
+                for (nn=0;nn<(c)->md_len/4;nn++)                \
+                {   ll=(c)->h[nn]; (void)HOST_l2c(ll,(s));   }  \
+                break;                  \
+        }                               \
+        } while (0)
+
+#define HASH_UPDATE             SHA256_Update
+#define HASH_TRANSFORM          SHA256_Transform
+#define HASH_FINAL              SHA256_Final
+#define HASH_BLOCK_DATA_ORDER   sha256_block_data_order
+#ifndef SHA256_ASM
+static
+#endif
+void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num);
+
+#include "internal/md32_common.h"
+
+#ifndef SHA256_ASM
+static const SHA_LONG K256[64] = {
+    0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
+    0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
+    0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
+    0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
+    0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+    0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
+    0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
+    0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
+    0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
+    0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+    0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
+    0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
+    0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
+    0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
+    0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+    0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+};
+
+/*
+ * FIPS specification refers to right rotations, while our ROTATE macro
+ * is left one. This is why you might notice that rotation coefficients
+ * differ from those observed in FIPS document by 32-N...
+ */
+# define Sigma0(x)       (ROTATE((x),30) ^ ROTATE((x),19) ^ ROTATE((x),10))
+# define Sigma1(x)       (ROTATE((x),26) ^ ROTATE((x),21) ^ ROTATE((x),7))
+# define sigma0(x)       (ROTATE((x),25) ^ ROTATE((x),14) ^ ((x)>>3))
+# define sigma1(x)       (ROTATE((x),15) ^ ROTATE((x),13) ^ ((x)>>10))
+
+# define Ch(x,y,z)       (((x) & (y)) ^ ((~(x)) & (z)))
+# define Maj(x,y,z)      (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+# ifdef OPENSSL_SMALL_FOOTPRINT
+
+static void sha256_block_data_order(SHA256_CTX *ctx, const void *in,
+                                    size_t num)
+{
+    unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1, T2;
+    SHA_LONG X[16], l;
+    int i;
+    const unsigned char *data = in;
+
+    while (num--) {
+
+        a = ctx->h[0];
+        b = ctx->h[1];
+        c = ctx->h[2];
+        d = ctx->h[3];
+        e = ctx->h[4];
+        f = ctx->h[5];
+        g = ctx->h[6];
+        h = ctx->h[7];
+
+        for (i = 0; i < 16; i++) {
+            (void)HOST_c2l(data, l);
+            T1 = X[i] = l;
+            T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i];
+            T2 = Sigma0(a) + Maj(a, b, c);
+            h = g;
+            g = f;
+            f = e;
+            e = d + T1;
+            d = c;
+            c = b;
+            b = a;
+            a = T1 + T2;
+        }
+
+        for (; i < 64; i++) {
+            s0 = X[(i + 1) & 0x0f];
+            s0 = sigma0(s0);
+            s1 = X[(i + 14) & 0x0f];
+            s1 = sigma1(s1);
+
+            T1 = X[i & 0xf] += s0 + s1 + X[(i + 9) & 0xf];
+            T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i];
+            T2 = Sigma0(a) + Maj(a, b, c);
+            h = g;
+            g = f;
+            f = e;
+            e = d + T1;
+            d = c;
+            c = b;
+            b = a;
+            a = T1 + T2;
+        }
+
+        ctx->h[0] += a;
+        ctx->h[1] += b;
+        ctx->h[2] += c;
+        ctx->h[3] += d;
+        ctx->h[4] += e;
+        ctx->h[5] += f;
+        ctx->h[6] += g;
+        ctx->h[7] += h;
+
+    }
+}
+
+# else
+
+#  define ROUND_00_15(i,a,b,c,d,e,f,g,h)          do {    \
+        T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i];      \
+        h = Sigma0(a) + Maj(a,b,c);                     \
+        d += T1;        h += T1;                } while (0)
+
+#  define ROUND_16_63(i,a,b,c,d,e,f,g,h,X)        do {    \
+        s0 = X[(i+1)&0x0f];     s0 = sigma0(s0);        \
+        s1 = X[(i+14)&0x0f];    s1 = sigma1(s1);        \
+        T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f];    \
+        ROUND_00_15(i,a,b,c,d,e,f,g,h);         } while (0)
+
+static void sha256_block_data_order(SHA256_CTX *ctx, const void *in,
+                                    size_t num)
+{
+    unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1;
+    SHA_LONG X[16];
+    int i;
+    const unsigned char *data = in;
+    const union {
+        long one;
+        char little;
+    } is_endian = {
+        1
+    };
+
+    while (num--) {
+
+        a = ctx->h[0];
+        b = ctx->h[1];
+        c = ctx->h[2];
+        d = ctx->h[3];
+        e = ctx->h[4];
+        f = ctx->h[5];
+        g = ctx->h[6];
+        h = ctx->h[7];
+
+        if (!is_endian.little && sizeof(SHA_LONG) == 4
+            && ((size_t)in % 4) == 0) {
+            const SHA_LONG *W = (const SHA_LONG *)data;
+
+            T1 = X[0] = W[0];
+            ROUND_00_15(0, a, b, c, d, e, f, g, h);
+            T1 = X[1] = W[1];
+            ROUND_00_15(1, h, a, b, c, d, e, f, g);
+            T1 = X[2] = W[2];
+            ROUND_00_15(2, g, h, a, b, c, d, e, f);
+            T1 = X[3] = W[3];
+            ROUND_00_15(3, f, g, h, a, b, c, d, e);
+            T1 = X[4] = W[4];
+            ROUND_00_15(4, e, f, g, h, a, b, c, d);
+            T1 = X[5] = W[5];
+            ROUND_00_15(5, d, e, f, g, h, a, b, c);
+            T1 = X[6] = W[6];
+            ROUND_00_15(6, c, d, e, f, g, h, a, b);
+            T1 = X[7] = W[7];
+            ROUND_00_15(7, b, c, d, e, f, g, h, a);
+            T1 = X[8] = W[8];
+            ROUND_00_15(8, a, b, c, d, e, f, g, h);
+            T1 = X[9] = W[9];
+            ROUND_00_15(9, h, a, b, c, d, e, f, g);
+            T1 = X[10] = W[10];
+            ROUND_00_15(10, g, h, a, b, c, d, e, f);
+            T1 = X[11] = W[11];
+            ROUND_00_15(11, f, g, h, a, b, c, d, e);
+            T1 = X[12] = W[12];
+            ROUND_00_15(12, e, f, g, h, a, b, c, d);
+            T1 = X[13] = W[13];
+            ROUND_00_15(13, d, e, f, g, h, a, b, c);
+            T1 = X[14] = W[14];
+            ROUND_00_15(14, c, d, e, f, g, h, a, b);
+            T1 = X[15] = W[15];
+            ROUND_00_15(15, b, c, d, e, f, g, h, a);
+
+            data += SHA256_CBLOCK;
+        } else {
+            SHA_LONG l;
+
+            (void)HOST_c2l(data, l);
+            T1 = X[0] = l;
+            ROUND_00_15(0, a, b, c, d, e, f, g, h);
+            (void)HOST_c2l(data, l);
+            T1 = X[1] = l;
+            ROUND_00_15(1, h, a, b, c, d, e, f, g);
+            (void)HOST_c2l(data, l);
+            T1 = X[2] = l;
+            ROUND_00_15(2, g, h, a, b, c, d, e, f);
+            (void)HOST_c2l(data, l);
+            T1 = X[3] = l;
+            ROUND_00_15(3, f, g, h, a, b, c, d, e);
+            (void)HOST_c2l(data, l);
+            T1 = X[4] = l;
+            ROUND_00_15(4, e, f, g, h, a, b, c, d);
+            (void)HOST_c2l(data, l);
+            T1 = X[5] = l;
+            ROUND_00_15(5, d, e, f, g, h, a, b, c);
+            (void)HOST_c2l(data, l);
+            T1 = X[6] = l;
+            ROUND_00_15(6, c, d, e, f, g, h, a, b);
+            (void)HOST_c2l(data, l);
+            T1 = X[7] = l;
+            ROUND_00_15(7, b, c, d, e, f, g, h, a);
+            (void)HOST_c2l(data, l);
+            T1 = X[8] = l;
+            ROUND_00_15(8, a, b, c, d, e, f, g, h);
+            (void)HOST_c2l(data, l);
+            T1 = X[9] = l;
+            ROUND_00_15(9, h, a, b, c, d, e, f, g);
+            (void)HOST_c2l(data, l);
+            T1 = X[10] = l;
+            ROUND_00_15(10, g, h, a, b, c, d, e, f);
+            (void)HOST_c2l(data, l);
+            T1 = X[11] = l;
+            ROUND_00_15(11, f, g, h, a, b, c, d, e);
+            (void)HOST_c2l(data, l);
+            T1 = X[12] = l;
+            ROUND_00_15(12, e, f, g, h, a, b, c, d);
+            (void)HOST_c2l(data, l);
+            T1 = X[13] = l;
+            ROUND_00_15(13, d, e, f, g, h, a, b, c);
+            (void)HOST_c2l(data, l);
+            T1 = X[14] = l;
+            ROUND_00_15(14, c, d, e, f, g, h, a, b);
+            (void)HOST_c2l(data, l);
+            T1 = X[15] = l;
+            ROUND_00_15(15, b, c, d, e, f, g, h, a);
+        }
+
+        for (i = 16; i < 64; i += 8) {
+            ROUND_16_63(i + 0, a, b, c, d, e, f, g, h, X);
+            ROUND_16_63(i + 1, h, a, b, c, d, e, f, g, X);
+            ROUND_16_63(i + 2, g, h, a, b, c, d, e, f, X);
+            ROUND_16_63(i + 3, f, g, h, a, b, c, d, e, X);
+            ROUND_16_63(i + 4, e, f, g, h, a, b, c, d, X);
+            ROUND_16_63(i + 5, d, e, f, g, h, a, b, c, X);
+            ROUND_16_63(i + 6, c, d, e, f, g, h, a, b, X);
+            ROUND_16_63(i + 7, b, c, d, e, f, g, h, a, X);
+        }
+
+        ctx->h[0] += a;
+        ctx->h[1] += b;
+        ctx->h[2] += c;
+        ctx->h[3] += d;
+        ctx->h[4] += e;
+        ctx->h[5] += f;
+        ctx->h[6] += g;
+        ctx->h[7] += h;
+
+    }
+}
+
+# endif
+#endif                         /* SHA256_ASM */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/sha/sha512.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/sha/sha512.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/sha/sha512.c	(revision 331)
@@ -0,0 +1,678 @@
+/*
+ * Copyright 2004-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 <openssl/opensslconf.h>
+/*-
+ * IMPLEMENTATION NOTES.
+ *
+ * As you might have noticed 32-bit hash algorithms:
+ *
+ * - permit SHA_LONG to be wider than 32-bit
+ * - optimized versions implement two transform functions: one operating
+ *   on [aligned] data in host byte order and one - on data in input
+ *   stream byte order;
+ * - share common byte-order neutral collector and padding function
+ *   implementations, ../md32_common.h;
+ *
+ * Neither of the above applies to this SHA-512 implementations. Reasons
+ * [in reverse order] are:
+ *
+ * - it's the only 64-bit hash algorithm for the moment of this writing,
+ *   there is no need for common collector/padding implementation [yet];
+ * - by supporting only one transform function [which operates on
+ *   *aligned* data in input stream byte order, big-endian in this case]
+ *   we minimize burden of maintenance in two ways: a) collector/padding
+ *   function is simpler; b) only one transform function to stare at;
+ * - SHA_LONG64 is required to be exactly 64-bit in order to be able to
+ *   apply a number of optimizations to mitigate potential performance
+ *   penalties caused by previous design decision;
+ *
+ * Caveat lector.
+ *
+ * Implementation relies on the fact that "long long" is 64-bit on
+ * both 32- and 64-bit platforms. If some compiler vendor comes up
+ * with 128-bit long long, adjustment to sha.h would be required.
+ * As this implementation relies on 64-bit integer type, it's totally
+ * inappropriate for platforms which don't support it, most notably
+ * 16-bit platforms.
+ *                                      <appro@fy.chalmers.se>
+ */
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/crypto.h>
+#include <openssl/sha.h>
+#include <openssl/opensslv.h>
+
+#include "internal/cryptlib.h"
+
+#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
+    defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || \
+    defined(__s390__) || defined(__s390x__) || \
+    defined(__aarch64__) || \
+    defined(SHA512_ASM)
+# define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
+#endif
+
+int SHA384_Init(SHA512_CTX *c)
+{
+    c->h[0] = U64(0xcbbb9d5dc1059ed8);
+    c->h[1] = U64(0x629a292a367cd507);
+    c->h[2] = U64(0x9159015a3070dd17);
+    c->h[3] = U64(0x152fecd8f70e5939);
+    c->h[4] = U64(0x67332667ffc00b31);
+    c->h[5] = U64(0x8eb44a8768581511);
+    c->h[6] = U64(0xdb0c2e0d64f98fa7);
+    c->h[7] = U64(0x47b5481dbefa4fa4);
+
+    c->Nl = 0;
+    c->Nh = 0;
+    c->num = 0;
+    c->md_len = SHA384_DIGEST_LENGTH;
+    return 1;
+}
+
+int SHA512_Init(SHA512_CTX *c)
+{
+    c->h[0] = U64(0x6a09e667f3bcc908);
+    c->h[1] = U64(0xbb67ae8584caa73b);
+    c->h[2] = U64(0x3c6ef372fe94f82b);
+    c->h[3] = U64(0xa54ff53a5f1d36f1);
+    c->h[4] = U64(0x510e527fade682d1);
+    c->h[5] = U64(0x9b05688c2b3e6c1f);
+    c->h[6] = U64(0x1f83d9abfb41bd6b);
+    c->h[7] = U64(0x5be0cd19137e2179);
+
+    c->Nl = 0;
+    c->Nh = 0;
+    c->num = 0;
+    c->md_len = SHA512_DIGEST_LENGTH;
+    return 1;
+}
+
+#ifndef SHA512_ASM
+static
+#endif
+void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num);
+
+int SHA512_Final(unsigned char *md, SHA512_CTX *c)
+{
+    unsigned char *p = (unsigned char *)c->u.p;
+    size_t n = c->num;
+
+    p[n] = 0x80;                /* There always is a room for one */
+    n++;
+    if (n > (sizeof(c->u) - 16)) {
+        memset(p + n, 0, sizeof(c->u) - n);
+        n = 0;
+        sha512_block_data_order(c, p, 1);
+    }
+
+    memset(p + n, 0, sizeof(c->u) - 16 - n);
+#ifdef  B_ENDIAN
+    c->u.d[SHA_LBLOCK - 2] = c->Nh;
+    c->u.d[SHA_LBLOCK - 1] = c->Nl;
+#else
+    p[sizeof(c->u) - 1] = (unsigned char)(c->Nl);
+    p[sizeof(c->u) - 2] = (unsigned char)(c->Nl >> 8);
+    p[sizeof(c->u) - 3] = (unsigned char)(c->Nl >> 16);
+    p[sizeof(c->u) - 4] = (unsigned char)(c->Nl >> 24);
+    p[sizeof(c->u) - 5] = (unsigned char)(c->Nl >> 32);
+    p[sizeof(c->u) - 6] = (unsigned char)(c->Nl >> 40);
+    p[sizeof(c->u) - 7] = (unsigned char)(c->Nl >> 48);
+    p[sizeof(c->u) - 8] = (unsigned char)(c->Nl >> 56);
+    p[sizeof(c->u) - 9] = (unsigned char)(c->Nh);
+    p[sizeof(c->u) - 10] = (unsigned char)(c->Nh >> 8);
+    p[sizeof(c->u) - 11] = (unsigned char)(c->Nh >> 16);
+    p[sizeof(c->u) - 12] = (unsigned char)(c->Nh >> 24);
+    p[sizeof(c->u) - 13] = (unsigned char)(c->Nh >> 32);
+    p[sizeof(c->u) - 14] = (unsigned char)(c->Nh >> 40);
+    p[sizeof(c->u) - 15] = (unsigned char)(c->Nh >> 48);
+    p[sizeof(c->u) - 16] = (unsigned char)(c->Nh >> 56);
+#endif
+
+    sha512_block_data_order(c, p, 1);
+
+    if (md == 0)
+        return 0;
+
+    switch (c->md_len) {
+        /* Let compiler decide if it's appropriate to unroll... */
+    case SHA384_DIGEST_LENGTH:
+        for (n = 0; n < SHA384_DIGEST_LENGTH / 8; n++) {
+            SHA_LONG64 t = c->h[n];
+
+            *(md++) = (unsigned char)(t >> 56);
+            *(md++) = (unsigned char)(t >> 48);
+            *(md++) = (unsigned char)(t >> 40);
+            *(md++) = (unsigned char)(t >> 32);
+            *(md++) = (unsigned char)(t >> 24);
+            *(md++) = (unsigned char)(t >> 16);
+            *(md++) = (unsigned char)(t >> 8);
+            *(md++) = (unsigned char)(t);
+        }
+        break;
+    case SHA512_DIGEST_LENGTH:
+        for (n = 0; n < SHA512_DIGEST_LENGTH / 8; n++) {
+            SHA_LONG64 t = c->h[n];
+
+            *(md++) = (unsigned char)(t >> 56);
+            *(md++) = (unsigned char)(t >> 48);
+            *(md++) = (unsigned char)(t >> 40);
+            *(md++) = (unsigned char)(t >> 32);
+            *(md++) = (unsigned char)(t >> 24);
+            *(md++) = (unsigned char)(t >> 16);
+            *(md++) = (unsigned char)(t >> 8);
+            *(md++) = (unsigned char)(t);
+        }
+        break;
+        /* ... as well as make sure md_len is not abused. */
+    default:
+        return 0;
+    }
+
+    return 1;
+}
+
+int SHA384_Final(unsigned char *md, SHA512_CTX *c)
+{
+    return SHA512_Final(md, c);
+}
+
+int SHA512_Update(SHA512_CTX *c, const void *_data, size_t len)
+{
+    SHA_LONG64 l;
+    unsigned char *p = c->u.p;
+    const unsigned char *data = (const unsigned char *)_data;
+
+    if (len == 0)
+        return 1;
+
+    l = (c->Nl + (((SHA_LONG64) len) << 3)) & U64(0xffffffffffffffff);
+    if (l < c->Nl)
+        c->Nh++;
+    if (sizeof(len) >= 8)
+        c->Nh += (((SHA_LONG64) len) >> 61);
+    c->Nl = l;
+
+    if (c->num != 0) {
+        size_t n = sizeof(c->u) - c->num;
+
+        if (len < n) {
+            memcpy(p + c->num, data, len), c->num += (unsigned int)len;
+            return 1;
+        } else {
+            memcpy(p + c->num, data, n), c->num = 0;
+            len -= n, data += n;
+            sha512_block_data_order(c, p, 1);
+        }
+    }
+
+    if (len >= sizeof(c->u)) {
+#ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
+        if ((size_t)data % sizeof(c->u.d[0]) != 0)
+            while (len >= sizeof(c->u))
+                memcpy(p, data, sizeof(c->u)),
+                    sha512_block_data_order(c, p, 1),
+                    len -= sizeof(c->u), data += sizeof(c->u);
+        else
+#endif
+            sha512_block_data_order(c, data, len / sizeof(c->u)),
+                data += len, len %= sizeof(c->u), data -= len;
+    }
+
+    if (len != 0)
+        memcpy(p, data, len), c->num = (int)len;
+
+    return 1;
+}
+
+int SHA384_Update(SHA512_CTX *c, const void *data, size_t len)
+{
+    return SHA512_Update(c, data, len);
+}
+
+void SHA512_Transform(SHA512_CTX *c, const unsigned char *data)
+{
+#ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
+    if ((size_t)data % sizeof(c->u.d[0]) != 0)
+        memcpy(c->u.p, data, sizeof(c->u.p)), data = c->u.p;
+#endif
+    sha512_block_data_order(c, data, 1);
+}
+
+unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md)
+{
+    SHA512_CTX c;
+    static unsigned char m[SHA384_DIGEST_LENGTH];
+
+    if (md == NULL)
+        md = m;
+    SHA384_Init(&c);
+    SHA512_Update(&c, d, n);
+    SHA512_Final(md, &c);
+    OPENSSL_cleanse(&c, sizeof(c));
+    return (md);
+}
+
+unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md)
+{
+    SHA512_CTX c;
+    static unsigned char m[SHA512_DIGEST_LENGTH];
+
+    if (md == NULL)
+        md = m;
+    SHA512_Init(&c);
+    SHA512_Update(&c, d, n);
+    SHA512_Final(md, &c);
+    OPENSSL_cleanse(&c, sizeof(c));
+    return (md);
+}
+
+#ifndef SHA512_ASM
+static const SHA_LONG64 K512[80] = {
+    U64(0x428a2f98d728ae22), U64(0x7137449123ef65cd),
+    U64(0xb5c0fbcfec4d3b2f), U64(0xe9b5dba58189dbbc),
+    U64(0x3956c25bf348b538), U64(0x59f111f1b605d019),
+    U64(0x923f82a4af194f9b), U64(0xab1c5ed5da6d8118),
+    U64(0xd807aa98a3030242), U64(0x12835b0145706fbe),
+    U64(0x243185be4ee4b28c), U64(0x550c7dc3d5ffb4e2),
+    U64(0x72be5d74f27b896f), U64(0x80deb1fe3b1696b1),
+    U64(0x9bdc06a725c71235), U64(0xc19bf174cf692694),
+    U64(0xe49b69c19ef14ad2), U64(0xefbe4786384f25e3),
+    U64(0x0fc19dc68b8cd5b5), U64(0x240ca1cc77ac9c65),
+    U64(0x2de92c6f592b0275), U64(0x4a7484aa6ea6e483),
+    U64(0x5cb0a9dcbd41fbd4), U64(0x76f988da831153b5),
+    U64(0x983e5152ee66dfab), U64(0xa831c66d2db43210),
+    U64(0xb00327c898fb213f), U64(0xbf597fc7beef0ee4),
+    U64(0xc6e00bf33da88fc2), U64(0xd5a79147930aa725),
+    U64(0x06ca6351e003826f), U64(0x142929670a0e6e70),
+    U64(0x27b70a8546d22ffc), U64(0x2e1b21385c26c926),
+    U64(0x4d2c6dfc5ac42aed), U64(0x53380d139d95b3df),
+    U64(0x650a73548baf63de), U64(0x766a0abb3c77b2a8),
+    U64(0x81c2c92e47edaee6), U64(0x92722c851482353b),
+    U64(0xa2bfe8a14cf10364), U64(0xa81a664bbc423001),
+    U64(0xc24b8b70d0f89791), U64(0xc76c51a30654be30),
+    U64(0xd192e819d6ef5218), U64(0xd69906245565a910),
+    U64(0xf40e35855771202a), U64(0x106aa07032bbd1b8),
+    U64(0x19a4c116b8d2d0c8), U64(0x1e376c085141ab53),
+    U64(0x2748774cdf8eeb99), U64(0x34b0bcb5e19b48a8),
+    U64(0x391c0cb3c5c95a63), U64(0x4ed8aa4ae3418acb),
+    U64(0x5b9cca4f7763e373), U64(0x682e6ff3d6b2b8a3),
+    U64(0x748f82ee5defb2fc), U64(0x78a5636f43172f60),
+    U64(0x84c87814a1f0ab72), U64(0x8cc702081a6439ec),
+    U64(0x90befffa23631e28), U64(0xa4506cebde82bde9),
+    U64(0xbef9a3f7b2c67915), U64(0xc67178f2e372532b),
+    U64(0xca273eceea26619c), U64(0xd186b8c721c0c207),
+    U64(0xeada7dd6cde0eb1e), U64(0xf57d4f7fee6ed178),
+    U64(0x06f067aa72176fba), U64(0x0a637dc5a2c898a6),
+    U64(0x113f9804bef90dae), U64(0x1b710b35131c471b),
+    U64(0x28db77f523047d84), U64(0x32caab7b40c72493),
+    U64(0x3c9ebe0a15c9bebc), U64(0x431d67c49c100d4c),
+    U64(0x4cc5d4becb3e42b6), U64(0x597f299cfc657e2a),
+    U64(0x5fcb6fab3ad6faec), U64(0x6c44198c4a475817)
+};
+
+# ifndef PEDANTIC
+#  if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+#   if defined(__x86_64) || defined(__x86_64__)
+#    define ROTR(a,n)    ({ SHA_LONG64 ret;              \
+                                asm ("rorq %1,%0"       \
+                                : "=r"(ret)             \
+                                : "J"(n),"0"(a)         \
+                                : "cc"); ret;           })
+#    if !defined(B_ENDIAN)
+#     define PULL64(x) ({ SHA_LONG64 ret=*((const SHA_LONG64 *)(&(x)));  \
+                                asm ("bswapq    %0"             \
+                                : "=r"(ret)                     \
+                                : "0"(ret)); ret;               })
+#    endif
+#   elif (defined(__i386) || defined(__i386__)) && !defined(B_ENDIAN)
+#    if defined(I386_ONLY)
+#     define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\
+                         unsigned int hi=p[0],lo=p[1];          \
+                                asm("xchgb %%ah,%%al;xchgb %%dh,%%dl;"\
+                                    "roll $16,%%eax; roll $16,%%edx; "\
+                                    "xchgb %%ah,%%al;xchgb %%dh,%%dl;" \
+                                : "=a"(lo),"=d"(hi)             \
+                                : "0"(lo),"1"(hi) : "cc");      \
+                                ((SHA_LONG64)hi)<<32|lo;        })
+#    else
+#     define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\
+                         unsigned int hi=p[0],lo=p[1];          \
+                                asm ("bswapl %0; bswapl %1;"    \
+                                : "=r"(lo),"=r"(hi)             \
+                                : "0"(lo),"1"(hi));             \
+                                ((SHA_LONG64)hi)<<32|lo;        })
+#    endif
+#   elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64)
+#    define ROTR(a,n)    ({ SHA_LONG64 ret;              \
+                                asm ("rotrdi %0,%1,%2"  \
+                                : "=r"(ret)             \
+                                : "r"(a),"K"(n)); ret;  })
+#   elif defined(__aarch64__)
+#    define ROTR(a,n)    ({ SHA_LONG64 ret;              \
+                                asm ("ror %0,%1,%2"     \
+                                : "=r"(ret)             \
+                                : "r"(a),"I"(n)); ret;  })
+#    if  defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
+        __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
+#     define PULL64(x)   ({ SHA_LONG64 ret;                      \
+                                asm ("rev       %0,%1"          \
+                                : "=r"(ret)                     \
+                                : "r"(*((const SHA_LONG64 *)(&(x))))); ret;             })
+#    endif
+#   endif
+#  elif defined(_MSC_VER)
+#   if defined(_WIN64)         /* applies to both IA-64 and AMD64 */
+#    pragma intrinsic(_rotr64)
+#    define ROTR(a,n)    _rotr64((a),n)
+#   endif
+#   if defined(_M_IX86) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
+#    if defined(I386_ONLY)
+static SHA_LONG64 __fastcall __pull64be(const void *x)
+{
+    _asm mov edx,[ecx + 0]
+    _asm mov eax,[ecx + 4]
+_asm xchg dh, dl
+        _asm xchg ah, al
+        _asm rol edx, 16 _asm rol eax, 16 _asm xchg dh, dl _asm xchg ah, al}
+#    else
+static SHA_LONG64 __fastcall __pull64be(const void *x)
+{
+    _asm mov edx,[ecx + 0]
+    _asm mov eax,[ecx + 4]
+_asm bswap edx _asm bswap eax}
+#    endif
+#    define PULL64(x) __pull64be(&(x))
+#    if _MSC_VER<=1200
+#     pragma inline_depth(0)
+#    endif
+#   endif
+#  endif
+# endif
+# ifndef PULL64
+#  define B(x,j)    (((SHA_LONG64)(*(((const unsigned char *)(&x))+j)))<<((7-j)*8))
+#  define PULL64(x) (B(x,0)|B(x,1)|B(x,2)|B(x,3)|B(x,4)|B(x,5)|B(x,6)|B(x,7))
+# endif
+# ifndef ROTR
+#  define ROTR(x,s)       (((x)>>s) | (x)<<(64-s))
+# endif
+# define Sigma0(x)       (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
+# define Sigma1(x)       (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
+# define sigma0(x)       (ROTR((x),1)  ^ ROTR((x),8)  ^ ((x)>>7))
+# define sigma1(x)       (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
+# define Ch(x,y,z)       (((x) & (y)) ^ ((~(x)) & (z)))
+# define Maj(x,y,z)      (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+# if defined(__i386) || defined(__i386__) || defined(_M_IX86)
+/*
+ * This code should give better results on 32-bit CPU with less than
+ * ~24 registers, both size and performance wise...
+ */ static void sha512_block_data_order(SHA512_CTX *ctx, const void *in,
+                                        size_t num)
+{
+    const SHA_LONG64 *W = in;
+    SHA_LONG64 A, E, T;
+    SHA_LONG64 X[9 + 80], *F;
+    int i;
+
+    while (num--) {
+
+        F = X + 80;
+        A = ctx->h[0];
+        F[1] = ctx->h[1];
+        F[2] = ctx->h[2];
+        F[3] = ctx->h[3];
+        E = ctx->h[4];
+        F[5] = ctx->h[5];
+        F[6] = ctx->h[6];
+        F[7] = ctx->h[7];
+
+        for (i = 0; i < 16; i++, F--) {
+#  ifdef B_ENDIAN
+            T = W[i];
+#  else
+            T = PULL64(W[i]);
+#  endif
+            F[0] = A;
+            F[4] = E;
+            F[8] = T;
+            T += F[7] + Sigma1(E) + Ch(E, F[5], F[6]) + K512[i];
+            E = F[3] + T;
+            A = T + Sigma0(A) + Maj(A, F[1], F[2]);
+        }
+
+        for (; i < 80; i++, F--) {
+            T = sigma0(F[8 + 16 - 1]);
+            T += sigma1(F[8 + 16 - 14]);
+            T += F[8 + 16] + F[8 + 16 - 9];
+
+            F[0] = A;
+            F[4] = E;
+            F[8] = T;
+            T += F[7] + Sigma1(E) + Ch(E, F[5], F[6]) + K512[i];
+            E = F[3] + T;
+            A = T + Sigma0(A) + Maj(A, F[1], F[2]);
+        }
+
+        ctx->h[0] += A;
+        ctx->h[1] += F[1];
+        ctx->h[2] += F[2];
+        ctx->h[3] += F[3];
+        ctx->h[4] += E;
+        ctx->h[5] += F[5];
+        ctx->h[6] += F[6];
+        ctx->h[7] += F[7];
+
+        W += SHA_LBLOCK;
+    }
+}
+
+# elif defined(OPENSSL_SMALL_FOOTPRINT)
+static void sha512_block_data_order(SHA512_CTX *ctx, const void *in,
+                                    size_t num)
+{
+    const SHA_LONG64 *W = in;
+    SHA_LONG64 a, b, c, d, e, f, g, h, s0, s1, T1, T2;
+    SHA_LONG64 X[16];
+    int i;
+
+    while (num--) {
+
+        a = ctx->h[0];
+        b = ctx->h[1];
+        c = ctx->h[2];
+        d = ctx->h[3];
+        e = ctx->h[4];
+        f = ctx->h[5];
+        g = ctx->h[6];
+        h = ctx->h[7];
+
+        for (i = 0; i < 16; i++) {
+#  ifdef B_ENDIAN
+            T1 = X[i] = W[i];
+#  else
+            T1 = X[i] = PULL64(W[i]);
+#  endif
+            T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i];
+            T2 = Sigma0(a) + Maj(a, b, c);
+            h = g;
+            g = f;
+            f = e;
+            e = d + T1;
+            d = c;
+            c = b;
+            b = a;
+            a = T1 + T2;
+        }
+
+        for (; i < 80; i++) {
+            s0 = X[(i + 1) & 0x0f];
+            s0 = sigma0(s0);
+            s1 = X[(i + 14) & 0x0f];
+            s1 = sigma1(s1);
+
+            T1 = X[i & 0xf] += s0 + s1 + X[(i + 9) & 0xf];
+            T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i];
+            T2 = Sigma0(a) + Maj(a, b, c);
+            h = g;
+            g = f;
+            f = e;
+            e = d + T1;
+            d = c;
+            c = b;
+            b = a;
+            a = T1 + T2;
+        }
+
+        ctx->h[0] += a;
+        ctx->h[1] += b;
+        ctx->h[2] += c;
+        ctx->h[3] += d;
+        ctx->h[4] += e;
+        ctx->h[5] += f;
+        ctx->h[6] += g;
+        ctx->h[7] += h;
+
+        W += SHA_LBLOCK;
+    }
+}
+
+# else
+#  define ROUND_00_15(i,a,b,c,d,e,f,g,h)          do {    \
+        T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i];      \
+        h = Sigma0(a) + Maj(a,b,c);                     \
+        d += T1;        h += T1;                } while (0)
+#  define ROUND_16_80(i,j,a,b,c,d,e,f,g,h,X)      do {    \
+        s0 = X[(j+1)&0x0f];     s0 = sigma0(s0);        \
+        s1 = X[(j+14)&0x0f];    s1 = sigma1(s1);        \
+        T1 = X[(j)&0x0f] += s0 + s1 + X[(j+9)&0x0f];    \
+        ROUND_00_15(i+j,a,b,c,d,e,f,g,h);               } while (0)
+static void sha512_block_data_order(SHA512_CTX *ctx, const void *in,
+                                    size_t num)
+{
+    const SHA_LONG64 *W = in;
+    SHA_LONG64 a, b, c, d, e, f, g, h, s0, s1, T1;
+    SHA_LONG64 X[16];
+    int i;
+
+    while (num--) {
+
+        a = ctx->h[0];
+        b = ctx->h[1];
+        c = ctx->h[2];
+        d = ctx->h[3];
+        e = ctx->h[4];
+        f = ctx->h[5];
+        g = ctx->h[6];
+        h = ctx->h[7];
+
+#  ifdef B_ENDIAN
+        T1 = X[0] = W[0];
+        ROUND_00_15(0, a, b, c, d, e, f, g, h);
+        T1 = X[1] = W[1];
+        ROUND_00_15(1, h, a, b, c, d, e, f, g);
+        T1 = X[2] = W[2];
+        ROUND_00_15(2, g, h, a, b, c, d, e, f);
+        T1 = X[3] = W[3];
+        ROUND_00_15(3, f, g, h, a, b, c, d, e);
+        T1 = X[4] = W[4];
+        ROUND_00_15(4, e, f, g, h, a, b, c, d);
+        T1 = X[5] = W[5];
+        ROUND_00_15(5, d, e, f, g, h, a, b, c);
+        T1 = X[6] = W[6];
+        ROUND_00_15(6, c, d, e, f, g, h, a, b);
+        T1 = X[7] = W[7];
+        ROUND_00_15(7, b, c, d, e, f, g, h, a);
+        T1 = X[8] = W[8];
+        ROUND_00_15(8, a, b, c, d, e, f, g, h);
+        T1 = X[9] = W[9];
+        ROUND_00_15(9, h, a, b, c, d, e, f, g);
+        T1 = X[10] = W[10];
+        ROUND_00_15(10, g, h, a, b, c, d, e, f);
+        T1 = X[11] = W[11];
+        ROUND_00_15(11, f, g, h, a, b, c, d, e);
+        T1 = X[12] = W[12];
+        ROUND_00_15(12, e, f, g, h, a, b, c, d);
+        T1 = X[13] = W[13];
+        ROUND_00_15(13, d, e, f, g, h, a, b, c);
+        T1 = X[14] = W[14];
+        ROUND_00_15(14, c, d, e, f, g, h, a, b);
+        T1 = X[15] = W[15];
+        ROUND_00_15(15, b, c, d, e, f, g, h, a);
+#  else
+        T1 = X[0] = PULL64(W[0]);
+        ROUND_00_15(0, a, b, c, d, e, f, g, h);
+        T1 = X[1] = PULL64(W[1]);
+        ROUND_00_15(1, h, a, b, c, d, e, f, g);
+        T1 = X[2] = PULL64(W[2]);
+        ROUND_00_15(2, g, h, a, b, c, d, e, f);
+        T1 = X[3] = PULL64(W[3]);
+        ROUND_00_15(3, f, g, h, a, b, c, d, e);
+        T1 = X[4] = PULL64(W[4]);
+        ROUND_00_15(4, e, f, g, h, a, b, c, d);
+        T1 = X[5] = PULL64(W[5]);
+        ROUND_00_15(5, d, e, f, g, h, a, b, c);
+        T1 = X[6] = PULL64(W[6]);
+        ROUND_00_15(6, c, d, e, f, g, h, a, b);
+        T1 = X[7] = PULL64(W[7]);
+        ROUND_00_15(7, b, c, d, e, f, g, h, a);
+        T1 = X[8] = PULL64(W[8]);
+        ROUND_00_15(8, a, b, c, d, e, f, g, h);
+        T1 = X[9] = PULL64(W[9]);
+        ROUND_00_15(9, h, a, b, c, d, e, f, g);
+        T1 = X[10] = PULL64(W[10]);
+        ROUND_00_15(10, g, h, a, b, c, d, e, f);
+        T1 = X[11] = PULL64(W[11]);
+        ROUND_00_15(11, f, g, h, a, b, c, d, e);
+        T1 = X[12] = PULL64(W[12]);
+        ROUND_00_15(12, e, f, g, h, a, b, c, d);
+        T1 = X[13] = PULL64(W[13]);
+        ROUND_00_15(13, d, e, f, g, h, a, b, c);
+        T1 = X[14] = PULL64(W[14]);
+        ROUND_00_15(14, c, d, e, f, g, h, a, b);
+        T1 = X[15] = PULL64(W[15]);
+        ROUND_00_15(15, b, c, d, e, f, g, h, a);
+#  endif
+
+        for (i = 16; i < 80; i += 16) {
+            ROUND_16_80(i, 0, a, b, c, d, e, f, g, h, X);
+            ROUND_16_80(i, 1, h, a, b, c, d, e, f, g, X);
+            ROUND_16_80(i, 2, g, h, a, b, c, d, e, f, X);
+            ROUND_16_80(i, 3, f, g, h, a, b, c, d, e, X);
+            ROUND_16_80(i, 4, e, f, g, h, a, b, c, d, X);
+            ROUND_16_80(i, 5, d, e, f, g, h, a, b, c, X);
+            ROUND_16_80(i, 6, c, d, e, f, g, h, a, b, X);
+            ROUND_16_80(i, 7, b, c, d, e, f, g, h, a, X);
+            ROUND_16_80(i, 8, a, b, c, d, e, f, g, h, X);
+            ROUND_16_80(i, 9, h, a, b, c, d, e, f, g, X);
+            ROUND_16_80(i, 10, g, h, a, b, c, d, e, f, X);
+            ROUND_16_80(i, 11, f, g, h, a, b, c, d, e, X);
+            ROUND_16_80(i, 12, e, f, g, h, a, b, c, d, X);
+            ROUND_16_80(i, 13, d, e, f, g, h, a, b, c, X);
+            ROUND_16_80(i, 14, c, d, e, f, g, h, a, b, X);
+            ROUND_16_80(i, 15, b, c, d, e, f, g, h, a, X);
+        }
+
+        ctx->h[0] += a;
+        ctx->h[1] += b;
+        ctx->h[2] += c;
+        ctx->h[3] += d;
+        ctx->h[4] += e;
+        ctx->h[5] += f;
+        ctx->h[6] += g;
+        ctx->h[7] += h;
+
+        W += SHA_LBLOCK;
+    }
+}
+
+# endif
+
+#endif                         /* SHA512_ASM */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/sha/sha_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/sha/sha_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/sha/sha_locl.h	(revision 331)
@@ -0,0 +1,424 @@
+/*
+ * Copyright 1995-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 <stdlib.h>
+#include <string.h>
+
+#include <openssl/opensslconf.h>
+#include <openssl/sha.h>
+
+#define DATA_ORDER_IS_BIG_ENDIAN
+
+#define HASH_LONG               SHA_LONG
+#define HASH_CTX                SHA_CTX
+#define HASH_CBLOCK             SHA_CBLOCK
+#define HASH_MAKE_STRING(c,s)   do {    \
+        unsigned long ll;               \
+        ll=(c)->h0; (void)HOST_l2c(ll,(s));     \
+        ll=(c)->h1; (void)HOST_l2c(ll,(s));     \
+        ll=(c)->h2; (void)HOST_l2c(ll,(s));     \
+        ll=(c)->h3; (void)HOST_l2c(ll,(s));     \
+        ll=(c)->h4; (void)HOST_l2c(ll,(s));     \
+        } while (0)
+
+#define HASH_UPDATE                     SHA1_Update
+#define HASH_TRANSFORM                  SHA1_Transform
+#define HASH_FINAL                      SHA1_Final
+#define HASH_INIT                       SHA1_Init
+#define HASH_BLOCK_DATA_ORDER           sha1_block_data_order
+#define Xupdate(a,ix,ia,ib,ic,id)       ( (a)=(ia^ib^ic^id),    \
+                                          ix=(a)=ROTATE((a),1)  \
+                                        )
+
+#ifndef SHA1_ASM
+static void sha1_block_data_order(SHA_CTX *c, const void *p, size_t num);
+#else
+void sha1_block_data_order(SHA_CTX *c, const void *p, size_t num);
+#endif
+
+#include "internal/md32_common.h"
+
+#define INIT_DATA_h0 0x67452301UL
+#define INIT_DATA_h1 0xefcdab89UL
+#define INIT_DATA_h2 0x98badcfeUL
+#define INIT_DATA_h3 0x10325476UL
+#define INIT_DATA_h4 0xc3d2e1f0UL
+
+int HASH_INIT(SHA_CTX *c)
+{
+    memset(c, 0, sizeof(*c));
+    c->h0 = INIT_DATA_h0;
+    c->h1 = INIT_DATA_h1;
+    c->h2 = INIT_DATA_h2;
+    c->h3 = INIT_DATA_h3;
+    c->h4 = INIT_DATA_h4;
+    return 1;
+}
+
+#define K_00_19 0x5a827999UL
+#define K_20_39 0x6ed9eba1UL
+#define K_40_59 0x8f1bbcdcUL
+#define K_60_79 0xca62c1d6UL
+
+/*
+ * As pointed out by Wei Dai <weidai@eskimo.com>, F() below can be simplified
+ * to the code in F_00_19.  Wei attributes these optimisations to Peter
+ * Gutmann's SHS code, and he attributes it to Rich Schroeppel. #define
+ * F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) I've just become aware of another
+ * tweak to be made, again from Wei Dai, in F_40_59, (x&a)|(y&a) -> (x|y)&a
+ */
+#define F_00_19(b,c,d)  ((((c) ^ (d)) & (b)) ^ (d))
+#define F_20_39(b,c,d)  ((b) ^ (c) ^ (d))
+#define F_40_59(b,c,d)  (((b) & (c)) | (((b)|(c)) & (d)))
+#define F_60_79(b,c,d)  F_20_39(b,c,d)
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+
+# define BODY_00_15(i,a,b,c,d,e,f,xi) \
+        (f)=xi+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
+        (b)=ROTATE((b),30);
+
+# define BODY_16_19(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
+        Xupdate(f,xi,xa,xb,xc,xd); \
+        (f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
+        (b)=ROTATE((b),30);
+
+# define BODY_20_31(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
+        Xupdate(f,xi,xa,xb,xc,xd); \
+        (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
+        (b)=ROTATE((b),30);
+
+# define BODY_32_39(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+        Xupdate(f,xa,xa,xb,xc,xd); \
+        (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
+        (b)=ROTATE((b),30);
+
+# define BODY_40_59(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+        Xupdate(f,xa,xa,xb,xc,xd); \
+        (f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \
+        (b)=ROTATE((b),30);
+
+# define BODY_60_79(i,a,b,c,d,e,f,xa,xb,xc,xd) \
+        Xupdate(f,xa,xa,xb,xc,xd); \
+        (f)=xa+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \
+        (b)=ROTATE((b),30);
+
+# ifdef X
+#  undef X
+# endif
+# ifndef MD32_XARRAY
+  /*
+   * Originally X was an array. As it's automatic it's natural
+   * to expect RISC compiler to accommodate at least part of it in
+   * the register bank, isn't it? Unfortunately not all compilers
+   * "find" this expectation reasonable:-( On order to make such
+   * compilers generate better code I replace X[] with a bunch of
+   * X0, X1, etc. See the function body below...
+   *                                    <appro@fy.chalmers.se>
+   */
+#  define X(i)   XX##i
+# else
+  /*
+   * However! Some compilers (most notably HP C) get overwhelmed by
+   * that many local variables so that we have to have the way to
+   * fall down to the original behavior.
+   */
+#  define X(i)   XX[i]
+# endif
+
+# if !defined(SHA1_ASM)
+static void HASH_BLOCK_DATA_ORDER(SHA_CTX *c, const void *p, size_t num)
+{
+    const unsigned char *data = p;
+    register unsigned MD32_REG_T A, B, C, D, E, T, l;
+#  ifndef MD32_XARRAY
+    unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
+        XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15;
+#  else
+    SHA_LONG XX[16];
+#  endif
+
+    A = c->h0;
+    B = c->h1;
+    C = c->h2;
+    D = c->h3;
+    E = c->h4;
+
+    for (;;) {
+        const union {
+            long one;
+            char little;
+        } is_endian = {
+            1
+        };
+
+        if (!is_endian.little && sizeof(SHA_LONG) == 4
+            && ((size_t)p % 4) == 0) {
+            const SHA_LONG *W = (const SHA_LONG *)data;
+
+            X(0) = W[0];
+            X(1) = W[1];
+            BODY_00_15(0, A, B, C, D, E, T, X(0));
+            X(2) = W[2];
+            BODY_00_15(1, T, A, B, C, D, E, X(1));
+            X(3) = W[3];
+            BODY_00_15(2, E, T, A, B, C, D, X(2));
+            X(4) = W[4];
+            BODY_00_15(3, D, E, T, A, B, C, X(3));
+            X(5) = W[5];
+            BODY_00_15(4, C, D, E, T, A, B, X(4));
+            X(6) = W[6];
+            BODY_00_15(5, B, C, D, E, T, A, X(5));
+            X(7) = W[7];
+            BODY_00_15(6, A, B, C, D, E, T, X(6));
+            X(8) = W[8];
+            BODY_00_15(7, T, A, B, C, D, E, X(7));
+            X(9) = W[9];
+            BODY_00_15(8, E, T, A, B, C, D, X(8));
+            X(10) = W[10];
+            BODY_00_15(9, D, E, T, A, B, C, X(9));
+            X(11) = W[11];
+            BODY_00_15(10, C, D, E, T, A, B, X(10));
+            X(12) = W[12];
+            BODY_00_15(11, B, C, D, E, T, A, X(11));
+            X(13) = W[13];
+            BODY_00_15(12, A, B, C, D, E, T, X(12));
+            X(14) = W[14];
+            BODY_00_15(13, T, A, B, C, D, E, X(13));
+            X(15) = W[15];
+            BODY_00_15(14, E, T, A, B, C, D, X(14));
+            BODY_00_15(15, D, E, T, A, B, C, X(15));
+
+            data += SHA_CBLOCK;
+        } else {
+            (void)HOST_c2l(data, l);
+            X(0) = l;
+            (void)HOST_c2l(data, l);
+            X(1) = l;
+            BODY_00_15(0, A, B, C, D, E, T, X(0));
+            (void)HOST_c2l(data, l);
+            X(2) = l;
+            BODY_00_15(1, T, A, B, C, D, E, X(1));
+            (void)HOST_c2l(data, l);
+            X(3) = l;
+            BODY_00_15(2, E, T, A, B, C, D, X(2));
+            (void)HOST_c2l(data, l);
+            X(4) = l;
+            BODY_00_15(3, D, E, T, A, B, C, X(3));
+            (void)HOST_c2l(data, l);
+            X(5) = l;
+            BODY_00_15(4, C, D, E, T, A, B, X(4));
+            (void)HOST_c2l(data, l);
+            X(6) = l;
+            BODY_00_15(5, B, C, D, E, T, A, X(5));
+            (void)HOST_c2l(data, l);
+            X(7) = l;
+            BODY_00_15(6, A, B, C, D, E, T, X(6));
+            (void)HOST_c2l(data, l);
+            X(8) = l;
+            BODY_00_15(7, T, A, B, C, D, E, X(7));
+            (void)HOST_c2l(data, l);
+            X(9) = l;
+            BODY_00_15(8, E, T, A, B, C, D, X(8));
+            (void)HOST_c2l(data, l);
+            X(10) = l;
+            BODY_00_15(9, D, E, T, A, B, C, X(9));
+            (void)HOST_c2l(data, l);
+            X(11) = l;
+            BODY_00_15(10, C, D, E, T, A, B, X(10));
+            (void)HOST_c2l(data, l);
+            X(12) = l;
+            BODY_00_15(11, B, C, D, E, T, A, X(11));
+            (void)HOST_c2l(data, l);
+            X(13) = l;
+            BODY_00_15(12, A, B, C, D, E, T, X(12));
+            (void)HOST_c2l(data, l);
+            X(14) = l;
+            BODY_00_15(13, T, A, B, C, D, E, X(13));
+            (void)HOST_c2l(data, l);
+            X(15) = l;
+            BODY_00_15(14, E, T, A, B, C, D, X(14));
+            BODY_00_15(15, D, E, T, A, B, C, X(15));
+        }
+
+        BODY_16_19(16, C, D, E, T, A, B, X(0), X(0), X(2), X(8), X(13));
+        BODY_16_19(17, B, C, D, E, T, A, X(1), X(1), X(3), X(9), X(14));
+        BODY_16_19(18, A, B, C, D, E, T, X(2), X(2), X(4), X(10), X(15));
+        BODY_16_19(19, T, A, B, C, D, E, X(3), X(3), X(5), X(11), X(0));
+
+        BODY_20_31(20, E, T, A, B, C, D, X(4), X(4), X(6), X(12), X(1));
+        BODY_20_31(21, D, E, T, A, B, C, X(5), X(5), X(7), X(13), X(2));
+        BODY_20_31(22, C, D, E, T, A, B, X(6), X(6), X(8), X(14), X(3));
+        BODY_20_31(23, B, C, D, E, T, A, X(7), X(7), X(9), X(15), X(4));
+        BODY_20_31(24, A, B, C, D, E, T, X(8), X(8), X(10), X(0), X(5));
+        BODY_20_31(25, T, A, B, C, D, E, X(9), X(9), X(11), X(1), X(6));
+        BODY_20_31(26, E, T, A, B, C, D, X(10), X(10), X(12), X(2), X(7));
+        BODY_20_31(27, D, E, T, A, B, C, X(11), X(11), X(13), X(3), X(8));
+        BODY_20_31(28, C, D, E, T, A, B, X(12), X(12), X(14), X(4), X(9));
+        BODY_20_31(29, B, C, D, E, T, A, X(13), X(13), X(15), X(5), X(10));
+        BODY_20_31(30, A, B, C, D, E, T, X(14), X(14), X(0), X(6), X(11));
+        BODY_20_31(31, T, A, B, C, D, E, X(15), X(15), X(1), X(7), X(12));
+
+        BODY_32_39(32, E, T, A, B, C, D, X(0), X(2), X(8), X(13));
+        BODY_32_39(33, D, E, T, A, B, C, X(1), X(3), X(9), X(14));
+        BODY_32_39(34, C, D, E, T, A, B, X(2), X(4), X(10), X(15));
+        BODY_32_39(35, B, C, D, E, T, A, X(3), X(5), X(11), X(0));
+        BODY_32_39(36, A, B, C, D, E, T, X(4), X(6), X(12), X(1));
+        BODY_32_39(37, T, A, B, C, D, E, X(5), X(7), X(13), X(2));
+        BODY_32_39(38, E, T, A, B, C, D, X(6), X(8), X(14), X(3));
+        BODY_32_39(39, D, E, T, A, B, C, X(7), X(9), X(15), X(4));
+
+        BODY_40_59(40, C, D, E, T, A, B, X(8), X(10), X(0), X(5));
+        BODY_40_59(41, B, C, D, E, T, A, X(9), X(11), X(1), X(6));
+        BODY_40_59(42, A, B, C, D, E, T, X(10), X(12), X(2), X(7));
+        BODY_40_59(43, T, A, B, C, D, E, X(11), X(13), X(3), X(8));
+        BODY_40_59(44, E, T, A, B, C, D, X(12), X(14), X(4), X(9));
+        BODY_40_59(45, D, E, T, A, B, C, X(13), X(15), X(5), X(10));
+        BODY_40_59(46, C, D, E, T, A, B, X(14), X(0), X(6), X(11));
+        BODY_40_59(47, B, C, D, E, T, A, X(15), X(1), X(7), X(12));
+        BODY_40_59(48, A, B, C, D, E, T, X(0), X(2), X(8), X(13));
+        BODY_40_59(49, T, A, B, C, D, E, X(1), X(3), X(9), X(14));
+        BODY_40_59(50, E, T, A, B, C, D, X(2), X(4), X(10), X(15));
+        BODY_40_59(51, D, E, T, A, B, C, X(3), X(5), X(11), X(0));
+        BODY_40_59(52, C, D, E, T, A, B, X(4), X(6), X(12), X(1));
+        BODY_40_59(53, B, C, D, E, T, A, X(5), X(7), X(13), X(2));
+        BODY_40_59(54, A, B, C, D, E, T, X(6), X(8), X(14), X(3));
+        BODY_40_59(55, T, A, B, C, D, E, X(7), X(9), X(15), X(4));
+        BODY_40_59(56, E, T, A, B, C, D, X(8), X(10), X(0), X(5));
+        BODY_40_59(57, D, E, T, A, B, C, X(9), X(11), X(1), X(6));
+        BODY_40_59(58, C, D, E, T, A, B, X(10), X(12), X(2), X(7));
+        BODY_40_59(59, B, C, D, E, T, A, X(11), X(13), X(3), X(8));
+
+        BODY_60_79(60, A, B, C, D, E, T, X(12), X(14), X(4), X(9));
+        BODY_60_79(61, T, A, B, C, D, E, X(13), X(15), X(5), X(10));
+        BODY_60_79(62, E, T, A, B, C, D, X(14), X(0), X(6), X(11));
+        BODY_60_79(63, D, E, T, A, B, C, X(15), X(1), X(7), X(12));
+        BODY_60_79(64, C, D, E, T, A, B, X(0), X(2), X(8), X(13));
+        BODY_60_79(65, B, C, D, E, T, A, X(1), X(3), X(9), X(14));
+        BODY_60_79(66, A, B, C, D, E, T, X(2), X(4), X(10), X(15));
+        BODY_60_79(67, T, A, B, C, D, E, X(3), X(5), X(11), X(0));
+        BODY_60_79(68, E, T, A, B, C, D, X(4), X(6), X(12), X(1));
+        BODY_60_79(69, D, E, T, A, B, C, X(5), X(7), X(13), X(2));
+        BODY_60_79(70, C, D, E, T, A, B, X(6), X(8), X(14), X(3));
+        BODY_60_79(71, B, C, D, E, T, A, X(7), X(9), X(15), X(4));
+        BODY_60_79(72, A, B, C, D, E, T, X(8), X(10), X(0), X(5));
+        BODY_60_79(73, T, A, B, C, D, E, X(9), X(11), X(1), X(6));
+        BODY_60_79(74, E, T, A, B, C, D, X(10), X(12), X(2), X(7));
+        BODY_60_79(75, D, E, T, A, B, C, X(11), X(13), X(3), X(8));
+        BODY_60_79(76, C, D, E, T, A, B, X(12), X(14), X(4), X(9));
+        BODY_60_79(77, B, C, D, E, T, A, X(13), X(15), X(5), X(10));
+        BODY_60_79(78, A, B, C, D, E, T, X(14), X(0), X(6), X(11));
+        BODY_60_79(79, T, A, B, C, D, E, X(15), X(1), X(7), X(12));
+
+        c->h0 = (c->h0 + E) & 0xffffffffL;
+        c->h1 = (c->h1 + T) & 0xffffffffL;
+        c->h2 = (c->h2 + A) & 0xffffffffL;
+        c->h3 = (c->h3 + B) & 0xffffffffL;
+        c->h4 = (c->h4 + C) & 0xffffffffL;
+
+        if (--num == 0)
+            break;
+
+        A = c->h0;
+        B = c->h1;
+        C = c->h2;
+        D = c->h3;
+        E = c->h4;
+
+    }
+}
+# endif
+
+#else                           /* OPENSSL_SMALL_FOOTPRINT */
+
+# define BODY_00_15(xi)           do {   \
+        T=E+K_00_19+F_00_19(B,C,D);     \
+        E=D, D=C, C=ROTATE(B,30), B=A;  \
+        A=ROTATE(A,5)+T+xi;         } while(0)
+
+# define BODY_16_19(xa,xb,xc,xd)  do {   \
+        Xupdate(T,xa,xa,xb,xc,xd);      \
+        T+=E+K_00_19+F_00_19(B,C,D);    \
+        E=D, D=C, C=ROTATE(B,30), B=A;  \
+        A=ROTATE(A,5)+T;            } while(0)
+
+# define BODY_20_39(xa,xb,xc,xd)  do {   \
+        Xupdate(T,xa,xa,xb,xc,xd);      \
+        T+=E+K_20_39+F_20_39(B,C,D);    \
+        E=D, D=C, C=ROTATE(B,30), B=A;  \
+        A=ROTATE(A,5)+T;            } while(0)
+
+# define BODY_40_59(xa,xb,xc,xd)  do {   \
+        Xupdate(T,xa,xa,xb,xc,xd);      \
+        T+=E+K_40_59+F_40_59(B,C,D);    \
+        E=D, D=C, C=ROTATE(B,30), B=A;  \
+        A=ROTATE(A,5)+T;            } while(0)
+
+# define BODY_60_79(xa,xb,xc,xd)  do {   \
+        Xupdate(T,xa,xa,xb,xc,xd);      \
+        T=E+K_60_79+F_60_79(B,C,D);     \
+        E=D, D=C, C=ROTATE(B,30), B=A;  \
+        A=ROTATE(A,5)+T+xa;         } while(0)
+
+# if !defined(SHA1_ASM)
+static void HASH_BLOCK_DATA_ORDER(SHA_CTX *c, const void *p, size_t num)
+{
+    const unsigned char *data = p;
+    register unsigned MD32_REG_T A, B, C, D, E, T, l;
+    int i;
+    SHA_LONG X[16];
+
+    A = c->h0;
+    B = c->h1;
+    C = c->h2;
+    D = c->h3;
+    E = c->h4;
+
+    for (;;) {
+        for (i = 0; i < 16; i++) {
+            (void)HOST_c2l(data, l);
+            X[i] = l;
+            BODY_00_15(X[i]);
+        }
+        for (i = 0; i < 4; i++) {
+            BODY_16_19(X[i], X[i + 2], X[i + 8], X[(i + 13) & 15]);
+        }
+        for (; i < 24; i++) {
+            BODY_20_39(X[i & 15], X[(i + 2) & 15], X[(i + 8) & 15],
+                       X[(i + 13) & 15]);
+        }
+        for (i = 0; i < 20; i++) {
+            BODY_40_59(X[(i + 8) & 15], X[(i + 10) & 15], X[i & 15],
+                       X[(i + 5) & 15]);
+        }
+        for (i = 4; i < 24; i++) {
+            BODY_60_79(X[(i + 8) & 15], X[(i + 10) & 15], X[i & 15],
+                       X[(i + 5) & 15]);
+        }
+
+        c->h0 = (c->h0 + A) & 0xffffffffL;
+        c->h1 = (c->h1 + B) & 0xffffffffL;
+        c->h2 = (c->h2 + C) & 0xffffffffL;
+        c->h3 = (c->h3 + D) & 0xffffffffL;
+        c->h4 = (c->h4 + E) & 0xffffffffL;
+
+        if (--num == 0)
+            break;
+
+        A = c->h0;
+        B = c->h1;
+        C = c->h2;
+        D = c->h3;
+        E = c->h4;
+
+    }
+}
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/sparc_arch.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/sparc_arch.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/sparc_arch.h	(revision 331)
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2012-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
+ */
+
+#ifndef __SPARC_ARCH_H__
+# define __SPARC_ARCH_H__
+
+# define SPARCV9_TICK_PRIVILEGED (1<<0)
+# define SPARCV9_PREFER_FPU      (1<<1)
+# define SPARCV9_VIS1            (1<<2)
+# define SPARCV9_VIS2            (1<<3)/* reserved */
+# define SPARCV9_FMADD           (1<<4)
+# define SPARCV9_BLK             (1<<5)/* VIS1 block copy */
+# define SPARCV9_VIS3            (1<<6)
+# define SPARCV9_RANDOM          (1<<7)
+# define SPARCV9_64BIT_STACK     (1<<8)
+# define SPARCV9_FJAESX          (1<<9)/* Fujitsu SPARC64 X AES */
+# define SPARCV9_FJDESX          (1<<10)/* Fujitsu SPARC64 X DES, reserved */
+# define SPARCV9_FJHPCACE        (1<<11)/* Fujitsu HPC-ACE, reserved */
+# define SPARCV9_IMA             (1<<13)/* reserved */
+# define SPARCV9_VIS4            (1<<14)/* reserved */
+
+/*
+ * OPENSSL_sparcv9cap_P[1] is copy of Compatibility Feature Register,
+ * %asr26, SPARC-T4 and later. There is no SPARCV9_CFR bit in
+ * OPENSSL_sparcv9cap_P[0], as %cfr copy is sufficient...
+ */
+# define CFR_AES         0x00000001/* Supports AES opcodes */
+# define CFR_DES         0x00000002/* Supports DES opcodes */
+# define CFR_KASUMI      0x00000004/* Supports KASUMI opcodes */
+# define CFR_CAMELLIA    0x00000008/* Supports CAMELLIA opcodes */
+# define CFR_MD5         0x00000010/* Supports MD5 opcodes */
+# define CFR_SHA1        0x00000020/* Supports SHA1 opcodes */
+# define CFR_SHA256      0x00000040/* Supports SHA256 opcodes */
+# define CFR_SHA512      0x00000080/* Supports SHA512 opcodes */
+# define CFR_MPMUL       0x00000100/* Supports MPMUL opcodes */
+# define CFR_MONTMUL     0x00000200/* Supports MONTMUL opcodes */
+# define CFR_MONTSQR     0x00000400/* Supports MONTSQR opcodes */
+# define CFR_CRC32C      0x00000800/* Supports CRC32C opcodes */
+# define CFR_XMPMUL      0x00001000/* Supports XMPMUL opcodes */
+# define CFR_XMONTMUL    0x00002000/* Supports XMONTMUL opcodes */
+# define CFR_XMONTSQR    0x00004000/* Supports XMONTSQR opcodes */
+
+# if defined(OPENSSL_PIC) && !defined(__PIC__)
+#  define __PIC__
+# endif
+
+# if defined(__SUNPRO_C) && defined(__sparcv9) && !defined(__arch64__)
+#  define __arch64__
+# endif
+
+# define SPARC_PIC_THUNK(reg)    \
+        .align  32;             \
+.Lpic_thunk:                    \
+        jmp     %o7 + 8;        \
+         add    %o7, reg, reg;
+
+# define SPARC_PIC_THUNK_CALL(reg)                       \
+        sethi   %hi(_GLOBAL_OFFSET_TABLE_-4), reg;      \
+        call    .Lpic_thunk;                            \
+         or     reg, %lo(_GLOBAL_OFFSET_TABLE_+4), reg;
+
+# if 1
+#  define SPARC_SETUP_GOT_REG(reg)       SPARC_PIC_THUNK_CALL(reg)
+# else
+#  define SPARC_SETUP_GOT_REG(reg)       \
+        sethi   %hi(_GLOBAL_OFFSET_TABLE_-4), reg;      \
+        call    .+8;                                    \
+        or      reg,%lo(_GLOBAL_OFFSET_TABLE_+4), reg;  \
+        add     %o7, reg, reg
+# endif
+
+# if defined(__arch64__)
+
+#  define SPARC_LOAD_ADDRESS(SYM, reg)   \
+        setx    SYM, %o7, reg;
+#  define LDPTR          ldx
+#  define SIZE_T_CC      %xcc
+#  define STACK_FRAME    192
+#  define STACK_BIAS     2047
+#  define STACK_7thARG   (STACK_BIAS+176)
+
+# else
+
+#  define SPARC_LOAD_ADDRESS(SYM, reg)   \
+        set     SYM, reg;
+#  define LDPTR          ld
+#  define SIZE_T_CC      %icc
+#  define STACK_FRAME    112
+#  define STACK_BIAS     0
+#  define STACK_7thARG   92
+#  define SPARC_LOAD_ADDRESS_LEAF(SYM,reg,tmp) SPARC_LOAD_ADDRESS(SYM,reg)
+
+# endif
+
+# ifdef __PIC__
+#  undef SPARC_LOAD_ADDRESS
+#  undef SPARC_LOAD_ADDRESS_LEAF
+#  define SPARC_LOAD_ADDRESS(SYM, reg)   \
+        SPARC_SETUP_GOT_REG(reg);       \
+        sethi   %hi(SYM), %o7;          \
+        or      %o7, %lo(SYM), %o7;     \
+        LDPTR   [reg + %o7], reg;
+# endif
+
+# ifndef SPARC_LOAD_ADDRESS_LEAF
+#  define SPARC_LOAD_ADDRESS_LEAF(SYM, reg, tmp) \
+        mov     %o7, tmp;                       \
+        SPARC_LOAD_ADDRESS(SYM, reg)            \
+        mov     tmp, %o7;
+# endif
+
+#endif                          /* __SPARC_ARCH_H__ */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/srp/srp_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/srp/srp_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/srp/srp_lib.c	(revision 331)
@@ -0,0 +1,280 @@
+/*
+ * Copyright 2011-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
+ */
+
+#ifndef OPENSSL_NO_SRP
+# include "internal/cryptlib.h"
+# include <openssl/sha.h>
+# include <openssl/srp.h>
+# include <openssl/evp.h>
+# include "internal/bn_srp.h"
+
+/* calculate = SHA1(PAD(x) || PAD(y)) */
+
+static BIGNUM *srp_Calc_xy(const BIGNUM *x, const BIGNUM *y, const BIGNUM *N)
+{
+    unsigned char digest[SHA_DIGEST_LENGTH];
+    unsigned char *tmp = NULL;
+    int numN = BN_num_bytes(N);
+    BIGNUM *res = NULL;
+    if (x != N && BN_ucmp(x, N) >= 0)
+        return NULL;
+    if (y != N && BN_ucmp(y, N) >= 0)
+        return NULL;
+    if ((tmp = OPENSSL_malloc(numN * 2)) == NULL)
+        goto err;
+    if (BN_bn2binpad(x, tmp, numN) < 0
+        || BN_bn2binpad(y, tmp + numN, numN) < 0
+        || !EVP_Digest(tmp, numN * 2, digest, NULL, EVP_sha1(), NULL))
+        goto err;
+    res = BN_bin2bn(digest, sizeof(digest), NULL);
+ err:
+    OPENSSL_free(tmp);
+    return res;
+}
+
+static BIGNUM *srp_Calc_k(const BIGNUM *N, const BIGNUM *g)
+{
+    /* k = SHA1(N | PAD(g)) -- tls-srp draft 8 */
+    return srp_Calc_xy(N, g, N);
+}
+
+BIGNUM *SRP_Calc_u(const BIGNUM *A, const BIGNUM *B, const BIGNUM *N)
+{
+    /* k = SHA1(PAD(A) || PAD(B) ) -- tls-srp draft 8 */
+    return srp_Calc_xy(A, B, N);
+}
+
+BIGNUM *SRP_Calc_server_key(const BIGNUM *A, const BIGNUM *v, const BIGNUM *u,
+                            const BIGNUM *b, const BIGNUM *N)
+{
+    BIGNUM *tmp = NULL, *S = NULL;
+    BN_CTX *bn_ctx;
+
+    if (u == NULL || A == NULL || v == NULL || b == NULL || N == NULL)
+        return NULL;
+
+    if ((bn_ctx = BN_CTX_new()) == NULL || (tmp = BN_new()) == NULL)
+        goto err;
+
+    /* S = (A*v**u) ** b */
+
+    if (!BN_mod_exp(tmp, v, u, N, bn_ctx))
+        goto err;
+    if (!BN_mod_mul(tmp, A, tmp, N, bn_ctx))
+        goto err;
+
+    S = BN_new();
+    if (S != NULL && !BN_mod_exp(S, tmp, b, N, bn_ctx)) {
+        BN_free(S);
+        S = NULL;
+    }
+ err:
+    BN_CTX_free(bn_ctx);
+    BN_clear_free(tmp);
+    return S;
+}
+
+BIGNUM *SRP_Calc_B(const BIGNUM *b, const BIGNUM *N, const BIGNUM *g,
+                   const BIGNUM *v)
+{
+    BIGNUM *kv = NULL, *gb = NULL;
+    BIGNUM *B = NULL, *k = NULL;
+    BN_CTX *bn_ctx;
+
+    if (b == NULL || N == NULL || g == NULL || v == NULL ||
+        (bn_ctx = BN_CTX_new()) == NULL)
+        return NULL;
+
+    if ((kv = BN_new()) == NULL ||
+        (gb = BN_new()) == NULL || (B = BN_new()) == NULL)
+        goto err;
+
+    /* B = g**b + k*v */
+
+    if (!BN_mod_exp(gb, g, b, N, bn_ctx)
+        || (k = srp_Calc_k(N, g)) == NULL
+        || !BN_mod_mul(kv, v, k, N, bn_ctx)
+        || !BN_mod_add(B, gb, kv, N, bn_ctx)) {
+        BN_free(B);
+        B = NULL;
+    }
+ err:
+    BN_CTX_free(bn_ctx);
+    BN_clear_free(kv);
+    BN_clear_free(gb);
+    BN_free(k);
+    return B;
+}
+
+BIGNUM *SRP_Calc_x(const BIGNUM *s, const char *user, const char *pass)
+{
+    unsigned char dig[SHA_DIGEST_LENGTH];
+    EVP_MD_CTX *ctxt;
+    unsigned char *cs = NULL;
+    BIGNUM *res = NULL;
+
+    if ((s == NULL) || (user == NULL) || (pass == NULL))
+        return NULL;
+
+    ctxt = EVP_MD_CTX_new();
+    if (ctxt == NULL)
+        return NULL;
+    if ((cs = OPENSSL_malloc(BN_num_bytes(s))) == NULL)
+        goto err;
+
+    if (!EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL)
+        || !EVP_DigestUpdate(ctxt, user, strlen(user))
+        || !EVP_DigestUpdate(ctxt, ":", 1)
+        || !EVP_DigestUpdate(ctxt, pass, strlen(pass))
+        || !EVP_DigestFinal_ex(ctxt, dig, NULL)
+        || !EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL))
+        goto err;
+    BN_bn2bin(s, cs);
+    if (!EVP_DigestUpdate(ctxt, cs, BN_num_bytes(s)))
+        goto err;
+
+    if (!EVP_DigestUpdate(ctxt, dig, sizeof(dig))
+        || !EVP_DigestFinal_ex(ctxt, dig, NULL))
+        goto err;
+
+    res = BN_bin2bn(dig, sizeof(dig), NULL);
+
+ err:
+    OPENSSL_free(cs);
+    EVP_MD_CTX_free(ctxt);
+    return res;
+}
+
+BIGNUM *SRP_Calc_A(const BIGNUM *a, const BIGNUM *N, const BIGNUM *g)
+{
+    BN_CTX *bn_ctx;
+    BIGNUM *A = NULL;
+
+    if (a == NULL || N == NULL || g == NULL || (bn_ctx = BN_CTX_new()) == NULL)
+        return NULL;
+
+    if ((A = BN_new()) != NULL && !BN_mod_exp(A, g, a, N, bn_ctx)) {
+        BN_free(A);
+        A = NULL;
+    }
+    BN_CTX_free(bn_ctx);
+    return A;
+}
+
+BIGNUM *SRP_Calc_client_key(const BIGNUM *N, const BIGNUM *B, const BIGNUM *g,
+                            const BIGNUM *x, const BIGNUM *a, const BIGNUM *u)
+{
+    BIGNUM *tmp = NULL, *tmp2 = NULL, *tmp3 = NULL, *k = NULL, *K = NULL;
+    BN_CTX *bn_ctx;
+
+    if (u == NULL || B == NULL || N == NULL || g == NULL || x == NULL
+        || a == NULL || (bn_ctx = BN_CTX_new()) == NULL)
+        return NULL;
+
+    if ((tmp = BN_new()) == NULL ||
+        (tmp2 = BN_new()) == NULL ||
+        (tmp3 = BN_new()) == NULL)
+        goto err;
+
+    if (!BN_mod_exp(tmp, g, x, N, bn_ctx))
+        goto err;
+    if ((k = srp_Calc_k(N, g)) == NULL)
+        goto err;
+    if (!BN_mod_mul(tmp2, tmp, k, N, bn_ctx))
+        goto err;
+    if (!BN_mod_sub(tmp, B, tmp2, N, bn_ctx))
+        goto err;
+    if (!BN_mul(tmp3, u, x, bn_ctx))
+        goto err;
+    if (!BN_add(tmp2, a, tmp3))
+        goto err;
+    K = BN_new();
+    if (K != NULL && !BN_mod_exp(K, tmp, tmp2, N, bn_ctx)) {
+        BN_free(K);
+        K = NULL;
+    }
+
+ err:
+    BN_CTX_free(bn_ctx);
+    BN_clear_free(tmp);
+    BN_clear_free(tmp2);
+    BN_clear_free(tmp3);
+    BN_free(k);
+    return K;
+}
+
+int SRP_Verify_B_mod_N(const BIGNUM *B, const BIGNUM *N)
+{
+    BIGNUM *r;
+    BN_CTX *bn_ctx;
+    int ret = 0;
+
+    if (B == NULL || N == NULL || (bn_ctx = BN_CTX_new()) == NULL)
+        return 0;
+
+    if ((r = BN_new()) == NULL)
+        goto err;
+    /* Checks if B % N == 0 */
+    if (!BN_nnmod(r, B, N, bn_ctx))
+        goto err;
+    ret = !BN_is_zero(r);
+ err:
+    BN_CTX_free(bn_ctx);
+    BN_free(r);
+    return ret;
+}
+
+int SRP_Verify_A_mod_N(const BIGNUM *A, const BIGNUM *N)
+{
+    /* Checks if A % N == 0 */
+    return SRP_Verify_B_mod_N(A, N);
+}
+
+static SRP_gN knowngN[] = {
+    {"8192", &bn_generator_19, &bn_group_8192},
+    {"6144", &bn_generator_5, &bn_group_6144},
+    {"4096", &bn_generator_5, &bn_group_4096},
+    {"3072", &bn_generator_5, &bn_group_3072},
+    {"2048", &bn_generator_2, &bn_group_2048},
+    {"1536", &bn_generator_2, &bn_group_1536},
+    {"1024", &bn_generator_2, &bn_group_1024},
+};
+
+# define KNOWN_GN_NUMBER sizeof(knowngN) / sizeof(SRP_gN)
+
+/*
+ * Check if G and N are known parameters. The values have been generated
+ * from the ietf-tls-srp draft version 8
+ */
+char *SRP_check_known_gN_param(const BIGNUM *g, const BIGNUM *N)
+{
+    size_t i;
+    if ((g == NULL) || (N == NULL))
+        return 0;
+
+    for (i = 0; i < KNOWN_GN_NUMBER; i++) {
+        if (BN_cmp(knowngN[i].g, g) == 0 && BN_cmp(knowngN[i].N, N) == 0)
+            return knowngN[i].id;
+    }
+    return NULL;
+}
+
+SRP_gN *SRP_get_default_gN(const char *id)
+{
+    size_t i;
+
+    if (id == NULL)
+        return knowngN;
+    for (i = 0; i < KNOWN_GN_NUMBER; i++) {
+        if (strcmp(knowngN[i].id, id) == 0)
+            return knowngN + i;
+    }
+    return NULL;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/srp/srp_vfy.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/srp/srp_vfy.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/srp/srp_vfy.c	(revision 331)
@@ -0,0 +1,677 @@
+/*
+ * Copyright 2011-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
+ */
+
+#ifndef OPENSSL_NO_SRP
+# include "internal/cryptlib.h"
+# include <openssl/sha.h>
+# include <openssl/srp.h>
+# include <openssl/evp.h>
+# include <openssl/buffer.h>
+# include <openssl/rand.h>
+# include <openssl/txt_db.h>
+
+# define SRP_RANDOM_SALT_LEN 20
+# define MAX_LEN 2500
+
+static char b64table[] =
+    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
+
+/*
+ * the following two conversion routines have been inspired by code from
+ * Stanford
+ */
+
+/*
+ * Convert a base64 string into raw byte array representation.
+ */
+static int t_fromb64(unsigned char *a, size_t alen, const char *src)
+{
+    char *loc;
+    int i, j;
+    int size;
+
+    while (*src && (*src == ' ' || *src == '\t' || *src == '\n'))
+        ++src;
+    size = strlen(src);
+    if (alen > INT_MAX || size > (int)alen)
+        return -1;
+
+    i = 0;
+    while (i < size) {
+        loc = strchr(b64table, src[i]);
+        if (loc == (char *)0)
+            break;
+        else
+            a[i] = loc - b64table;
+        ++i;
+    }
+    /* if nothing valid to process we have a zero length response */
+    if (i == 0)
+        return 0;
+    size = i;
+    i = size - 1;
+    j = size;
+    while (1) {
+        a[j] = a[i];
+        if (--i < 0)
+            break;
+        a[j] |= (a[i] & 3) << 6;
+        --j;
+        a[j] = (unsigned char)((a[i] & 0x3c) >> 2);
+        if (--i < 0)
+            break;
+        a[j] |= (a[i] & 0xf) << 4;
+        --j;
+        a[j] = (unsigned char)((a[i] & 0x30) >> 4);
+        if (--i < 0)
+            break;
+        a[j] |= (a[i] << 2);
+
+        a[--j] = 0;
+        if (--i < 0)
+            break;
+    }
+    while (a[j] == 0 && j <= size)
+        ++j;
+    i = 0;
+    while (j <= size)
+        a[i++] = a[j++];
+    return i;
+}
+
+/*
+ * Convert a raw byte string into a null-terminated base64 ASCII string.
+ */
+static char *t_tob64(char *dst, const unsigned char *src, int size)
+{
+    int c, pos = size % 3;
+    unsigned char b0 = 0, b1 = 0, b2 = 0, notleading = 0;
+    char *olddst = dst;
+
+    switch (pos) {
+    case 1:
+        b2 = src[0];
+        break;
+    case 2:
+        b1 = src[0];
+        b2 = src[1];
+        break;
+    }
+
+    while (1) {
+        c = (b0 & 0xfc) >> 2;
+        if (notleading || c != 0) {
+            *dst++ = b64table[c];
+            notleading = 1;
+        }
+        c = ((b0 & 3) << 4) | ((b1 & 0xf0) >> 4);
+        if (notleading || c != 0) {
+            *dst++ = b64table[c];
+            notleading = 1;
+        }
+        c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >> 6);
+        if (notleading || c != 0) {
+            *dst++ = b64table[c];
+            notleading = 1;
+        }
+        c = b2 & 0x3f;
+        if (notleading || c != 0) {
+            *dst++ = b64table[c];
+            notleading = 1;
+        }
+        if (pos >= size)
+            break;
+        else {
+            b0 = src[pos++];
+            b1 = src[pos++];
+            b2 = src[pos++];
+        }
+    }
+
+    *dst++ = '\0';
+    return olddst;
+}
+
+void SRP_user_pwd_free(SRP_user_pwd *user_pwd)
+{
+    if (user_pwd == NULL)
+        return;
+    BN_free(user_pwd->s);
+    BN_clear_free(user_pwd->v);
+    OPENSSL_free(user_pwd->id);
+    OPENSSL_free(user_pwd->info);
+    OPENSSL_free(user_pwd);
+}
+
+static SRP_user_pwd *SRP_user_pwd_new(void)
+{
+    SRP_user_pwd *ret = OPENSSL_malloc(sizeof(*ret));
+    if (ret == NULL)
+        return NULL;
+    ret->N = NULL;
+    ret->g = NULL;
+    ret->s = NULL;
+    ret->v = NULL;
+    ret->id = NULL;
+    ret->info = NULL;
+    return ret;
+}
+
+static void SRP_user_pwd_set_gN(SRP_user_pwd *vinfo, const BIGNUM *g,
+                                const BIGNUM *N)
+{
+    vinfo->N = N;
+    vinfo->g = g;
+}
+
+static int SRP_user_pwd_set_ids(SRP_user_pwd *vinfo, const char *id,
+                                const char *info)
+{
+    if (id != NULL && NULL == (vinfo->id = OPENSSL_strdup(id)))
+        return 0;
+    return (info == NULL || NULL != (vinfo->info = OPENSSL_strdup(info)));
+}
+
+static int SRP_user_pwd_set_sv(SRP_user_pwd *vinfo, const char *s,
+                               const char *v)
+{
+    unsigned char tmp[MAX_LEN];
+    int len;
+
+    vinfo->v = NULL;
+    vinfo->s = NULL;
+
+    len = t_fromb64(tmp, sizeof(tmp), v);
+    if (len < 0)
+        return 0;
+    if (NULL == (vinfo->v = BN_bin2bn(tmp, len, NULL)))
+        return 0;
+    len = t_fromb64(tmp, sizeof(tmp), s);
+    if (len < 0)
+        goto err;
+    vinfo->s = BN_bin2bn(tmp, len, NULL);
+    if (vinfo->s == NULL)
+        goto err;
+    return 1;
+ err:
+    BN_free(vinfo->v);
+    vinfo->v = NULL;
+    return 0;
+}
+
+static int SRP_user_pwd_set_sv_BN(SRP_user_pwd *vinfo, BIGNUM *s, BIGNUM *v)
+{
+    vinfo->v = v;
+    vinfo->s = s;
+    return (vinfo->s != NULL && vinfo->v != NULL);
+}
+
+static SRP_user_pwd *srp_user_pwd_dup(SRP_user_pwd *src)
+{
+    SRP_user_pwd *ret;
+
+    if (src == NULL)
+        return NULL;
+    if ((ret = SRP_user_pwd_new()) == NULL)
+        return NULL;
+
+    SRP_user_pwd_set_gN(ret, src->g, src->N);
+    if (!SRP_user_pwd_set_ids(ret, src->id, src->info)
+        || !SRP_user_pwd_set_sv_BN(ret, BN_dup(src->s), BN_dup(src->v))) {
+            SRP_user_pwd_free(ret);
+            return NULL;
+    }
+    return ret;
+}
+
+SRP_VBASE *SRP_VBASE_new(char *seed_key)
+{
+    SRP_VBASE *vb = OPENSSL_malloc(sizeof(*vb));
+
+    if (vb == NULL)
+        return NULL;
+    if ((vb->users_pwd = sk_SRP_user_pwd_new_null()) == NULL
+        || (vb->gN_cache = sk_SRP_gN_cache_new_null()) == NULL) {
+        OPENSSL_free(vb);
+        return NULL;
+    }
+    vb->default_g = NULL;
+    vb->default_N = NULL;
+    vb->seed_key = NULL;
+    if ((seed_key != NULL) && (vb->seed_key = OPENSSL_strdup(seed_key)) == NULL) {
+        sk_SRP_user_pwd_free(vb->users_pwd);
+        sk_SRP_gN_cache_free(vb->gN_cache);
+        OPENSSL_free(vb);
+        return NULL;
+    }
+    return vb;
+}
+
+void SRP_VBASE_free(SRP_VBASE *vb)
+{
+    if (!vb)
+        return;
+    sk_SRP_user_pwd_pop_free(vb->users_pwd, SRP_user_pwd_free);
+    sk_SRP_gN_cache_free(vb->gN_cache);
+    OPENSSL_free(vb->seed_key);
+    OPENSSL_free(vb);
+}
+
+static SRP_gN_cache *SRP_gN_new_init(const char *ch)
+{
+    unsigned char tmp[MAX_LEN];
+    int len;
+    SRP_gN_cache *newgN = OPENSSL_malloc(sizeof(*newgN));
+
+    if (newgN == NULL)
+        return NULL;
+
+    len = t_fromb64(tmp, sizeof(tmp), ch);
+    if (len < 0)
+        goto err;
+
+    if ((newgN->b64_bn = OPENSSL_strdup(ch)) == NULL)
+        goto err;
+
+    if ((newgN->bn = BN_bin2bn(tmp, len, NULL)))
+        return newgN;
+
+    OPENSSL_free(newgN->b64_bn);
+ err:
+    OPENSSL_free(newgN);
+    return NULL;
+}
+
+static void SRP_gN_free(SRP_gN_cache *gN_cache)
+{
+    if (gN_cache == NULL)
+        return;
+    OPENSSL_free(gN_cache->b64_bn);
+    BN_free(gN_cache->bn);
+    OPENSSL_free(gN_cache);
+}
+
+static SRP_gN *SRP_get_gN_by_id(const char *id, STACK_OF(SRP_gN) *gN_tab)
+{
+    int i;
+
+    SRP_gN *gN;
+    if (gN_tab != NULL)
+        for (i = 0; i < sk_SRP_gN_num(gN_tab); i++) {
+            gN = sk_SRP_gN_value(gN_tab, i);
+            if (gN && (id == NULL || strcmp(gN->id, id) == 0))
+                return gN;
+        }
+
+    return SRP_get_default_gN(id);
+}
+
+static BIGNUM *SRP_gN_place_bn(STACK_OF(SRP_gN_cache) *gN_cache, char *ch)
+{
+    int i;
+    if (gN_cache == NULL)
+        return NULL;
+
+    /* search if we have already one... */
+    for (i = 0; i < sk_SRP_gN_cache_num(gN_cache); i++) {
+        SRP_gN_cache *cache = sk_SRP_gN_cache_value(gN_cache, i);
+        if (strcmp(cache->b64_bn, ch) == 0)
+            return cache->bn;
+    }
+    {                           /* it is the first time that we find it */
+        SRP_gN_cache *newgN = SRP_gN_new_init(ch);
+        if (newgN) {
+            if (sk_SRP_gN_cache_insert(gN_cache, newgN, 0) > 0)
+                return newgN->bn;
+            SRP_gN_free(newgN);
+        }
+    }
+    return NULL;
+}
+
+/*
+ * this function parses verifier file. Format is:
+ * string(index):base64(N):base64(g):0
+ * string(username):base64(v):base64(salt):int(index)
+ */
+
+int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file)
+{
+    int error_code;
+    STACK_OF(SRP_gN) *SRP_gN_tab = sk_SRP_gN_new_null();
+    char *last_index = NULL;
+    int i;
+    char **pp;
+
+    SRP_gN *gN = NULL;
+    SRP_user_pwd *user_pwd = NULL;
+
+    TXT_DB *tmpdb = NULL;
+    BIO *in = BIO_new(BIO_s_file());
+
+    error_code = SRP_ERR_OPEN_FILE;
+
+    if (in == NULL || BIO_read_filename(in, verifier_file) <= 0)
+        goto err;
+
+    error_code = SRP_ERR_VBASE_INCOMPLETE_FILE;
+
+    if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL)
+        goto err;
+
+    error_code = SRP_ERR_MEMORY;
+
+    if (vb->seed_key) {
+        last_index = SRP_get_default_gN(NULL)->id;
+    }
+    for (i = 0; i < sk_OPENSSL_PSTRING_num(tmpdb->data); i++) {
+        pp = sk_OPENSSL_PSTRING_value(tmpdb->data, i);
+        if (pp[DB_srptype][0] == DB_SRP_INDEX) {
+            /*
+             * we add this couple in the internal Stack
+             */
+
+            if ((gN = OPENSSL_malloc(sizeof(*gN))) == NULL)
+                goto err;
+
+            if ((gN->id = OPENSSL_strdup(pp[DB_srpid])) == NULL
+                || (gN->N = SRP_gN_place_bn(vb->gN_cache, pp[DB_srpverifier]))
+                        == NULL
+                || (gN->g = SRP_gN_place_bn(vb->gN_cache, pp[DB_srpsalt]))
+                        == NULL
+                || sk_SRP_gN_insert(SRP_gN_tab, gN, 0) == 0)
+                goto err;
+
+            gN = NULL;
+
+            if (vb->seed_key != NULL) {
+                last_index = pp[DB_srpid];
+            }
+        } else if (pp[DB_srptype][0] == DB_SRP_VALID) {
+            /* it is a user .... */
+            const SRP_gN *lgN;
+
+            if ((lgN = SRP_get_gN_by_id(pp[DB_srpgN], SRP_gN_tab)) != NULL) {
+                error_code = SRP_ERR_MEMORY;
+                if ((user_pwd = SRP_user_pwd_new()) == NULL)
+                    goto err;
+
+                SRP_user_pwd_set_gN(user_pwd, lgN->g, lgN->N);
+                if (!SRP_user_pwd_set_ids
+                    (user_pwd, pp[DB_srpid], pp[DB_srpinfo]))
+                    goto err;
+
+                error_code = SRP_ERR_VBASE_BN_LIB;
+                if (!SRP_user_pwd_set_sv
+                    (user_pwd, pp[DB_srpsalt], pp[DB_srpverifier]))
+                    goto err;
+
+                if (sk_SRP_user_pwd_insert(vb->users_pwd, user_pwd, 0) == 0)
+                    goto err;
+                user_pwd = NULL; /* abandon responsibility */
+            }
+        }
+    }
+
+    if (last_index != NULL) {
+        /* this means that we want to simulate a default user */
+
+        if (((gN = SRP_get_gN_by_id(last_index, SRP_gN_tab)) == NULL)) {
+            error_code = SRP_ERR_VBASE_BN_LIB;
+            goto err;
+        }
+        vb->default_g = gN->g;
+        vb->default_N = gN->N;
+        gN = NULL;
+    }
+    error_code = SRP_NO_ERROR;
+
+ err:
+    /*
+     * there may be still some leaks to fix, if this fails, the application
+     * terminates most likely
+     */
+
+    if (gN != NULL) {
+        OPENSSL_free(gN->id);
+        OPENSSL_free(gN);
+    }
+
+    SRP_user_pwd_free(user_pwd);
+
+    TXT_DB_free(tmpdb);
+    BIO_free_all(in);
+
+    sk_SRP_gN_free(SRP_gN_tab);
+
+    return error_code;
+
+}
+
+static SRP_user_pwd *find_user(SRP_VBASE *vb, char *username)
+{
+    int i;
+    SRP_user_pwd *user;
+
+    if (vb == NULL)
+        return NULL;
+
+    for (i = 0; i < sk_SRP_user_pwd_num(vb->users_pwd); i++) {
+        user = sk_SRP_user_pwd_value(vb->users_pwd, i);
+        if (strcmp(user->id, username) == 0)
+            return user;
+    }
+
+    return NULL;
+}
+
+ #if OPENSSL_API_COMPAT < 0x10100000L
+/*
+ * DEPRECATED: use SRP_VBASE_get1_by_user instead.
+ * This method ignores the configured seed and fails for an unknown user.
+ * Ownership of the returned pointer is not released to the caller.
+ * In other words, caller must not free the result.
+ */
+SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username)
+{
+    return find_user(vb, username);
+}
+#endif
+
+/*
+ * Ownership of the returned pointer is released to the caller.
+ * In other words, caller must free the result once done.
+ */
+SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username)
+{
+    SRP_user_pwd *user;
+    unsigned char digv[SHA_DIGEST_LENGTH];
+    unsigned char digs[SHA_DIGEST_LENGTH];
+    EVP_MD_CTX *ctxt = NULL;
+
+    if (vb == NULL)
+        return NULL;
+
+    if ((user = find_user(vb, username)) != NULL)
+        return srp_user_pwd_dup(user);
+
+    if ((vb->seed_key == NULL) ||
+        (vb->default_g == NULL) || (vb->default_N == NULL))
+        return NULL;
+
+/* if the user is unknown we set parameters as well if we have a seed_key */
+
+    if ((user = SRP_user_pwd_new()) == NULL)
+        return NULL;
+
+    SRP_user_pwd_set_gN(user, vb->default_g, vb->default_N);
+
+    if (!SRP_user_pwd_set_ids(user, username, NULL))
+        goto err;
+
+    if (RAND_bytes(digv, SHA_DIGEST_LENGTH) <= 0)
+        goto err;
+    ctxt = EVP_MD_CTX_new();
+    if (ctxt == NULL
+        || !EVP_DigestInit_ex(ctxt, EVP_sha1(), NULL)
+        || !EVP_DigestUpdate(ctxt, vb->seed_key, strlen(vb->seed_key))
+        || !EVP_DigestUpdate(ctxt, username, strlen(username))
+        || !EVP_DigestFinal_ex(ctxt, digs, NULL))
+        goto err;
+    EVP_MD_CTX_free(ctxt);
+    ctxt = NULL;
+    if (SRP_user_pwd_set_sv_BN(user,
+                               BN_bin2bn(digs, SHA_DIGEST_LENGTH, NULL),
+                               BN_bin2bn(digv, SHA_DIGEST_LENGTH, NULL)))
+        return user;
+
+ err:
+    EVP_MD_CTX_free(ctxt);
+    SRP_user_pwd_free(user);
+    return NULL;
+}
+
+/*
+ * create a verifier (*salt,*verifier,g and N are in base64)
+ */
+char *SRP_create_verifier(const char *user, const char *pass, char **salt,
+                          char **verifier, const char *N, const char *g)
+{
+    int len;
+    char *result = NULL, *vf = NULL;
+    const BIGNUM *N_bn = NULL, *g_bn = NULL;
+    BIGNUM *N_bn_alloc = NULL, *g_bn_alloc = NULL, *s = NULL, *v = NULL;
+    unsigned char tmp[MAX_LEN];
+    unsigned char tmp2[MAX_LEN];
+    char *defgNid = NULL;
+    int vfsize = 0;
+
+    if ((user == NULL) ||
+        (pass == NULL) || (salt == NULL) || (verifier == NULL))
+        goto err;
+
+    if (N) {
+        if ((len = t_fromb64(tmp, sizeof(tmp), N)) <= 0)
+            goto err;
+        N_bn_alloc = BN_bin2bn(tmp, len, NULL);
+        N_bn = N_bn_alloc;
+        if ((len = t_fromb64(tmp, sizeof(tmp) ,g)) <= 0)
+            goto err;
+        g_bn_alloc = BN_bin2bn(tmp, len, NULL);
+        g_bn = g_bn_alloc;
+        defgNid = "*";
+    } else {
+        SRP_gN *gN = SRP_get_gN_by_id(g, NULL);
+        if (gN == NULL)
+            goto err;
+        N_bn = gN->N;
+        g_bn = gN->g;
+        defgNid = gN->id;
+    }
+
+    if (*salt == NULL) {
+        if (RAND_bytes(tmp2, SRP_RANDOM_SALT_LEN) <= 0)
+            goto err;
+
+        s = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL);
+    } else {
+        if ((len = t_fromb64(tmp2, sizeof(tmp2), *salt)) <= 0)
+            goto err;
+        s = BN_bin2bn(tmp2, len, NULL);
+    }
+
+    if (!SRP_create_verifier_BN(user, pass, &s, &v, N_bn, g_bn))
+        goto err;
+
+    BN_bn2bin(v, tmp);
+    vfsize = BN_num_bytes(v) * 2;
+    if (((vf = OPENSSL_malloc(vfsize)) == NULL))
+        goto err;
+    t_tob64(vf, tmp, BN_num_bytes(v));
+
+    if (*salt == NULL) {
+        char *tmp_salt;
+
+        if ((tmp_salt = OPENSSL_malloc(SRP_RANDOM_SALT_LEN * 2)) == NULL) {
+            goto err;
+        }
+        t_tob64(tmp_salt, tmp2, SRP_RANDOM_SALT_LEN);
+        *salt = tmp_salt;
+    }
+
+    *verifier = vf;
+    vf = NULL;
+    result = defgNid;
+
+ err:
+    BN_free(N_bn_alloc);
+    BN_free(g_bn_alloc);
+    OPENSSL_clear_free(vf, vfsize);
+    BN_clear_free(s);
+    BN_clear_free(v);
+    return result;
+}
+
+/*
+ * create a verifier (*salt,*verifier,g and N are BIGNUMs). If *salt != NULL
+ * then the provided salt will be used. On successful exit *verifier will point
+ * to a newly allocated BIGNUM containing the verifier and (if a salt was not
+ * provided) *salt will be populated with a newly allocated BIGNUM containing a
+ * random salt.
+ * The caller is responsible for freeing the allocated *salt and *verifier
+ * BIGNUMS.
+ */
+int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt,
+                           BIGNUM **verifier, const BIGNUM *N,
+                           const BIGNUM *g)
+{
+    int result = 0;
+    BIGNUM *x = NULL;
+    BN_CTX *bn_ctx = BN_CTX_new();
+    unsigned char tmp2[MAX_LEN];
+    BIGNUM *salttmp = NULL;
+
+    if ((user == NULL) ||
+        (pass == NULL) ||
+        (salt == NULL) ||
+        (verifier == NULL) || (N == NULL) || (g == NULL) || (bn_ctx == NULL))
+        goto err;
+
+    if (*salt == NULL) {
+        if (RAND_bytes(tmp2, SRP_RANDOM_SALT_LEN) <= 0)
+            goto err;
+
+        salttmp = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL);
+    } else {
+        salttmp = *salt;
+    }
+
+    x = SRP_Calc_x(salttmp, user, pass);
+
+    *verifier = BN_new();
+    if (*verifier == NULL)
+        goto err;
+
+    if (!BN_mod_exp(*verifier, g, x, N, bn_ctx)) {
+        BN_clear_free(*verifier);
+        goto err;
+    }
+
+    result = 1;
+    *salt = salttmp;
+
+ err:
+    if (salt != NULL && *salt != salttmp)
+        BN_clear_free(salttmp);
+    BN_clear_free(x);
+    BN_CTX_free(bn_ctx);
+    return result;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/stack/stack.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/stack/stack.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/stack/stack.c	(revision 331)
@@ -0,0 +1,312 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include "internal/numbers.h"
+#include <openssl/stack.h>
+#include <openssl/objects.h>
+
+struct stack_st {
+    int num;
+    const char **data;
+    int sorted;
+    size_t num_alloc;
+    OPENSSL_sk_compfunc comp;
+};
+
+#undef MIN_NODES
+#define MIN_NODES       4
+
+#include <errno.h>
+
+OPENSSL_sk_compfunc OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, OPENSSL_sk_compfunc c)
+{
+    OPENSSL_sk_compfunc old = sk->comp;
+
+    if (sk->comp != c)
+        sk->sorted = 0;
+    sk->comp = c;
+
+    return old;
+}
+
+OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *sk)
+{
+    OPENSSL_STACK *ret;
+
+    if (sk->num < 0)
+        return NULL;
+
+    if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)
+        return NULL;
+
+    /* direct structure assignment */
+    *ret = *sk;
+
+    if ((ret->data = OPENSSL_malloc(sizeof(*ret->data) * sk->num_alloc)) == NULL)
+        goto err;
+    memcpy(ret->data, sk->data, sizeof(char *) * sk->num);
+    return ret;
+ err:
+    OPENSSL_sk_free(ret);
+    return NULL;
+}
+
+OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk,
+                             OPENSSL_sk_copyfunc copy_func,
+                             OPENSSL_sk_freefunc free_func)
+{
+    OPENSSL_STACK *ret;
+    int i;
+
+    if (sk->num < 0)
+        return NULL;
+
+    if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)
+        return NULL;
+
+    /* direct structure assignment */
+    *ret = *sk;
+
+    ret->num_alloc = sk->num > MIN_NODES ? (size_t)sk->num : MIN_NODES;
+    ret->data = OPENSSL_zalloc(sizeof(*ret->data) * ret->num_alloc);
+    if (ret->data == NULL) {
+        OPENSSL_free(ret);
+        return NULL;
+    }
+
+    for (i = 0; i < ret->num; ++i) {
+        if (sk->data[i] == NULL)
+            continue;
+        if ((ret->data[i] = copy_func(sk->data[i])) == NULL) {
+            while (--i >= 0)
+                if (ret->data[i] != NULL)
+                    free_func((void *)ret->data[i]);
+            OPENSSL_sk_free(ret);
+            return NULL;
+        }
+    }
+    return ret;
+}
+
+OPENSSL_STACK *OPENSSL_sk_new_null(void)
+{
+    return OPENSSL_sk_new((OPENSSL_sk_compfunc)NULL);
+}
+
+OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_compfunc c)
+{
+    OPENSSL_STACK *ret;
+
+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
+        goto err;
+    if ((ret->data = OPENSSL_zalloc(sizeof(*ret->data) * MIN_NODES)) == NULL)
+        goto err;
+    ret->comp = c;
+    ret->num_alloc = MIN_NODES;
+    return (ret);
+
+ err:
+    OPENSSL_free(ret);
+    return (NULL);
+}
+
+int OPENSSL_sk_insert(OPENSSL_STACK *st, const void *data, int loc)
+{
+    if (st == NULL || st->num < 0 || st->num == INT_MAX) {
+        return 0;
+    }
+
+    if (st->num_alloc <= (size_t)(st->num + 1)) {
+        size_t doub_num_alloc = st->num_alloc * 2;
+        const char **tmpdata;
+
+        /* Overflow checks */
+        if (doub_num_alloc < st->num_alloc)
+            return 0;
+
+        /* Avoid overflow due to multiplication by sizeof(char *) */
+        if (doub_num_alloc > SIZE_MAX / sizeof(char *))
+            return 0;
+
+        tmpdata = OPENSSL_realloc((char *)st->data,
+                                  sizeof(char *) * doub_num_alloc);
+        if (tmpdata == NULL)
+            return 0;
+
+        st->data = tmpdata;
+        st->num_alloc = doub_num_alloc;
+    }
+    if ((loc >= st->num) || (loc < 0)) {
+        st->data[st->num] = data;
+    } else {
+        memmove(&st->data[loc + 1], &st->data[loc],
+                sizeof(st->data[0]) * (st->num - loc));
+        st->data[loc] = data;
+    }
+    st->num++;
+    st->sorted = 0;
+    return st->num;
+}
+
+void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *st, const void *p)
+{
+    int i;
+
+    for (i = 0; i < st->num; i++)
+        if (st->data[i] == p)
+            return OPENSSL_sk_delete(st, i);
+    return NULL;
+}
+
+void *OPENSSL_sk_delete(OPENSSL_STACK *st, int loc)
+{
+    const char *ret;
+
+    if (st == NULL || loc < 0 || loc >= st->num)
+        return NULL;
+
+    ret = st->data[loc];
+    if (loc != st->num - 1)
+         memmove(&st->data[loc], &st->data[loc + 1],
+                 sizeof(st->data[0]) * (st->num - loc - 1));
+    st->num--;
+    return (void *)ret;
+}
+
+static int internal_find(OPENSSL_STACK *st, const void *data,
+                         int ret_val_options)
+{
+    const void *r;
+    int i;
+
+    if (st == NULL)
+        return -1;
+
+    if (st->comp == NULL) {
+        for (i = 0; i < st->num; i++)
+            if (st->data[i] == data)
+                return (i);
+        return (-1);
+    }
+    OPENSSL_sk_sort(st);
+    if (data == NULL)
+        return (-1);
+    r = OBJ_bsearch_ex_(&data, st->data, st->num, sizeof(void *), st->comp,
+                        ret_val_options);
+    if (r == NULL)
+        return (-1);
+    return (int)((const char **)r - st->data);
+}
+
+int OPENSSL_sk_find(OPENSSL_STACK *st, const void *data)
+{
+    return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH);
+}
+
+int OPENSSL_sk_find_ex(OPENSSL_STACK *st, const void *data)
+{
+    return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH);
+}
+
+int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data)
+{
+    return (OPENSSL_sk_insert(st, data, st->num));
+}
+
+int OPENSSL_sk_unshift(OPENSSL_STACK *st, const void *data)
+{
+    return (OPENSSL_sk_insert(st, data, 0));
+}
+
+void *OPENSSL_sk_shift(OPENSSL_STACK *st)
+{
+    if (st == NULL)
+        return (NULL);
+    if (st->num <= 0)
+        return (NULL);
+    return (OPENSSL_sk_delete(st, 0));
+}
+
+void *OPENSSL_sk_pop(OPENSSL_STACK *st)
+{
+    if (st == NULL)
+        return (NULL);
+    if (st->num <= 0)
+        return (NULL);
+    return (OPENSSL_sk_delete(st, st->num - 1));
+}
+
+void OPENSSL_sk_zero(OPENSSL_STACK *st)
+{
+    if (st == NULL)
+        return;
+    if (st->num <= 0)
+        return;
+    memset(st->data, 0, sizeof(*st->data) * st->num);
+    st->num = 0;
+}
+
+void OPENSSL_sk_pop_free(OPENSSL_STACK *st, OPENSSL_sk_freefunc func)
+{
+    int i;
+
+    if (st == NULL)
+        return;
+    for (i = 0; i < st->num; i++)
+        if (st->data[i] != NULL)
+            func((char *)st->data[i]);
+    OPENSSL_sk_free(st);
+}
+
+void OPENSSL_sk_free(OPENSSL_STACK *st)
+{
+    if (st == NULL)
+        return;
+    OPENSSL_free(st->data);
+    OPENSSL_free(st);
+}
+
+int OPENSSL_sk_num(const OPENSSL_STACK *st)
+{
+    if (st == NULL)
+        return -1;
+    return st->num;
+}
+
+void *OPENSSL_sk_value(const OPENSSL_STACK *st, int i)
+{
+    if (st == NULL || i < 0 || i >= st->num)
+        return NULL;
+    return (void *)st->data[i];
+}
+
+void *OPENSSL_sk_set(OPENSSL_STACK *st, int i, const void *data)
+{
+    if (st == NULL || i < 0 || i >= st->num)
+        return NULL;
+    st->data[i] = data;
+    return (void *)st->data[i];
+}
+
+void OPENSSL_sk_sort(OPENSSL_STACK *st)
+{
+    if (st && !st->sorted && st->comp != NULL) {
+        qsort(st->data, st->num, sizeof(char *), st->comp);
+        st->sorted = 1;
+    }
+}
+
+int OPENSSL_sk_is_sorted(const OPENSSL_STACK *st)
+{
+    if (st == NULL)
+        return 1;
+    return st->sorted;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/threads_none.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/threads_none.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/threads_none.c	(revision 331)
@@ -0,0 +1,124 @@
+/*
+ * 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 <openssl/crypto.h>
+
+#if !defined(OPENSSL_THREADS) || defined(CRYPTO_TDEBUG)
+
+CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void)
+{
+    CRYPTO_RWLOCK *lock = OPENSSL_zalloc(sizeof(unsigned int));
+    if (lock == NULL)
+        return NULL;
+
+    *(unsigned int *)lock = 1;
+
+    return lock;
+}
+
+int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
+{
+    OPENSSL_assert(*(unsigned int *)lock == 1);
+    return 1;
+}
+
+int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
+{
+    OPENSSL_assert(*(unsigned int *)lock == 1);
+    return 1;
+}
+
+int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock)
+{
+    OPENSSL_assert(*(unsigned int *)lock == 1);
+    return 1;
+}
+
+void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock) {
+    if (lock == NULL)
+        return;
+
+    *(unsigned int *)lock = 0;
+    OPENSSL_free(lock);
+
+    return;
+}
+
+int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
+{
+    if (*once != 0)
+        return 1;
+
+    init();
+    *once = 1;
+
+    return 1;
+}
+
+#define OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX 256
+
+static void *thread_local_storage[OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX];
+
+int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *))
+{
+    static unsigned int thread_local_key = 0;
+
+    if (thread_local_key >= OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX)
+        return 0;
+
+    *key = thread_local_key++;
+
+    thread_local_storage[*key] = NULL;
+
+    return 1;
+}
+
+void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key)
+{
+    if (*key >= OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX)
+        return NULL;
+
+    return thread_local_storage[*key];
+}
+
+int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val)
+{
+    if (*key >= OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX)
+        return 0;
+
+    thread_local_storage[*key] = val;
+
+    return 1;
+}
+
+int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key)
+{
+    *key = OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX + 1;
+    return 1;
+}
+
+CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void)
+{
+    return 0;
+}
+
+int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b)
+{
+    return (a == b);
+}
+
+int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock)
+{
+    *val += amount;
+    *ret  = *val;
+
+    return 1;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/threads_pthread.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/threads_pthread.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/threads_pthread.c	(revision 331)
@@ -0,0 +1,171 @@
+/*
+ * 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 <openssl/crypto.h>
+
+#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && !defined(OPENSSL_SYS_WINDOWS)
+
+# ifdef PTHREAD_RWLOCK_INITIALIZER
+#  define USE_RWLOCK
+# endif
+
+CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void)
+{
+# ifdef USE_RWLOCK
+    CRYPTO_RWLOCK *lock = OPENSSL_zalloc(sizeof(pthread_rwlock_t));
+    if (lock == NULL)
+        return NULL;
+
+    if (pthread_rwlock_init(lock, NULL) != 0) {
+        OPENSSL_free(lock);
+        return NULL;
+    }
+# else
+    pthread_mutexattr_t attr;
+    CRYPTO_RWLOCK *lock = OPENSSL_zalloc(sizeof(pthread_mutex_t));
+    if (lock == NULL)
+        return NULL;
+
+    pthread_mutexattr_init(&attr);
+    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+
+    if (pthread_mutex_init(lock, &attr) != 0) {
+        pthread_mutexattr_destroy(&attr);
+        OPENSSL_free(lock);
+        return NULL;
+    }
+
+    pthread_mutexattr_destroy(&attr);
+# endif
+
+    return lock;
+}
+
+int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
+{
+# ifdef USE_RWLOCK
+    if (pthread_rwlock_rdlock(lock) != 0)
+        return 0;
+# else
+    if (pthread_mutex_lock(lock) != 0)
+        return 0;
+# endif
+
+    return 1;
+}
+
+int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
+{
+# ifdef USE_RWLOCK
+    if (pthread_rwlock_wrlock(lock) != 0)
+        return 0;
+# else
+    if (pthread_mutex_lock(lock) != 0)
+        return 0;
+# endif
+
+    return 1;
+}
+
+int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock)
+{
+# ifdef USE_RWLOCK
+    if (pthread_rwlock_unlock(lock) != 0)
+        return 0;
+# else
+    if (pthread_mutex_unlock(lock) != 0)
+        return 0;
+# endif
+
+    return 1;
+}
+
+void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock)
+{
+    if (lock == NULL)
+        return;
+
+# ifdef USE_RWLOCK
+    pthread_rwlock_destroy(lock);
+# else
+    pthread_mutex_destroy(lock);
+# endif
+    OPENSSL_free(lock);
+
+    return;
+}
+
+int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
+{
+    if (pthread_once(once, init) != 0)
+        return 0;
+
+    return 1;
+}
+
+int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *))
+{
+    if (pthread_key_create(key, cleanup) != 0)
+        return 0;
+
+    return 1;
+}
+
+void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key)
+{
+    return pthread_getspecific(*key);
+}
+
+int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val)
+{
+    if (pthread_setspecific(*key, val) != 0)
+        return 0;
+
+    return 1;
+}
+
+int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key)
+{
+    if (pthread_key_delete(*key) != 0)
+        return 0;
+
+    return 1;
+}
+
+CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void)
+{
+    return pthread_self();
+}
+
+int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b)
+{
+    return pthread_equal(a, b);
+}
+
+int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock)
+{
+# if defined(__GNUC__) && defined(__ATOMIC_ACQ_REL)
+    if (__atomic_is_lock_free(sizeof(*val), val)) {
+        *ret = __atomic_add_fetch(val, amount, __ATOMIC_ACQ_REL);
+        return 1;
+    }
+# endif
+    if (!CRYPTO_THREAD_write_lock(lock))
+        return 0;
+
+    *val += amount;
+    *ret  = *val;
+
+    if (!CRYPTO_THREAD_unlock(lock))
+        return 0;
+
+    return 1;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/threads_win.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/threads_win.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/threads_win.c	(revision 331)
@@ -0,0 +1,136 @@
+/*
+ * 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
+ */
+
+#if defined(_WIN32)
+# include <windows.h>
+#endif
+
+#include <openssl/crypto.h>
+
+#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && defined(OPENSSL_SYS_WINDOWS)
+
+CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void)
+{
+    CRYPTO_RWLOCK *lock = OPENSSL_zalloc(sizeof(CRITICAL_SECTION));
+    if (lock == NULL)
+        return NULL;
+
+    /* 0x400 is the spin count value suggested in the documentation */
+    if (!InitializeCriticalSectionAndSpinCount(lock, 0x400)) {
+        OPENSSL_free(lock);
+        return NULL;
+    }
+
+    return lock;
+}
+
+int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
+{
+    EnterCriticalSection(lock);
+    return 1;
+}
+
+int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
+{
+    EnterCriticalSection(lock);
+    return 1;
+}
+
+int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock)
+{
+    LeaveCriticalSection(lock);
+    return 1;
+}
+
+void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock)
+{
+    if (lock == NULL)
+        return;
+
+    DeleteCriticalSection(lock);
+    OPENSSL_free(lock);
+
+    return;
+}
+
+#  define ONCE_UNINITED     0
+#  define ONCE_ININIT       1
+#  define ONCE_DONE         2
+
+/*
+ * We don't use InitOnceExecuteOnce because that isn't available in WinXP which
+ * we still have to support.
+ */
+int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
+{
+    LONG volatile *lock = (LONG *)once;
+    LONG result;
+
+    if (*lock == ONCE_DONE)
+        return 1;
+
+    do {
+        result = InterlockedCompareExchange(lock, ONCE_ININIT, ONCE_UNINITED);
+        if (result == ONCE_UNINITED) {
+            init();
+            *lock = ONCE_DONE;
+            return 1;
+        }
+    } while (result == ONCE_ININIT);
+
+    return (*lock == ONCE_DONE);
+}
+
+int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *))
+{
+    *key = TlsAlloc();
+    if (*key == TLS_OUT_OF_INDEXES)
+        return 0;
+
+    return 1;
+}
+
+void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key)
+{
+    return TlsGetValue(*key);
+}
+
+int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val)
+{
+    if (TlsSetValue(*key, val) == 0)
+        return 0;
+
+    return 1;
+}
+
+int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key)
+{
+    if (TlsFree(*key) == 0)
+        return 0;
+
+    return 1;
+}
+
+CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void)
+{
+    return GetCurrentThreadId();
+}
+
+int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b)
+{
+    return (a == b);
+}
+
+int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock)
+{
+    *ret = InterlockedExchangeAdd(val, amount) + amount;
+    return 1;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_asn1.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_asn1.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_asn1.c	(revision 331)
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2006-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 <openssl/ts.h>
+#include <openssl/err.h>
+#include <openssl/asn1t.h>
+#include "ts_lcl.h"
+
+ASN1_SEQUENCE(TS_MSG_IMPRINT) = {
+        ASN1_SIMPLE(TS_MSG_IMPRINT, hash_algo, X509_ALGOR),
+        ASN1_SIMPLE(TS_MSG_IMPRINT, hashed_msg, ASN1_OCTET_STRING)
+} static_ASN1_SEQUENCE_END(TS_MSG_IMPRINT)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(TS_MSG_IMPRINT)
+IMPLEMENT_ASN1_DUP_FUNCTION(TS_MSG_IMPRINT)
+TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT **a)
+{
+    return ASN1_d2i_bio_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new,
+                           d2i_TS_MSG_IMPRINT, bp, a);
+}
+
+int i2d_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT *a)
+{
+    return ASN1_i2d_bio_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, bp, a);
+}
+#ifndef OPENSSL_NO_STDIO
+TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a)
+{
+    return ASN1_d2i_fp_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new,
+                          d2i_TS_MSG_IMPRINT, fp, a);
+}
+
+int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a)
+{
+    return ASN1_i2d_fp_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, fp, a);
+}
+#endif
+
+ASN1_SEQUENCE(TS_REQ) = {
+        ASN1_SIMPLE(TS_REQ, version, ASN1_INTEGER),
+        ASN1_SIMPLE(TS_REQ, msg_imprint, TS_MSG_IMPRINT),
+        ASN1_OPT(TS_REQ, policy_id, ASN1_OBJECT),
+        ASN1_OPT(TS_REQ, nonce, ASN1_INTEGER),
+        ASN1_OPT(TS_REQ, cert_req, ASN1_FBOOLEAN),
+        ASN1_IMP_SEQUENCE_OF_OPT(TS_REQ, extensions, X509_EXTENSION, 0)
+} static_ASN1_SEQUENCE_END(TS_REQ)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(TS_REQ)
+IMPLEMENT_ASN1_DUP_FUNCTION(TS_REQ)
+TS_REQ *d2i_TS_REQ_bio(BIO *bp, TS_REQ **a)
+{
+    return ASN1_d2i_bio_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, bp, a);
+}
+
+int i2d_TS_REQ_bio(BIO *bp, TS_REQ *a)
+{
+    return ASN1_i2d_bio_of_const(TS_REQ, i2d_TS_REQ, bp, a);
+}
+#ifndef OPENSSL_NO_STDIO
+TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a)
+{
+    return ASN1_d2i_fp_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, fp, a);
+}
+
+int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a)
+{
+    return ASN1_i2d_fp_of_const(TS_REQ, i2d_TS_REQ, fp, a);
+}
+#endif
+
+ASN1_SEQUENCE(TS_ACCURACY) = {
+        ASN1_OPT(TS_ACCURACY, seconds, ASN1_INTEGER),
+        ASN1_IMP_OPT(TS_ACCURACY, millis, ASN1_INTEGER, 0),
+        ASN1_IMP_OPT(TS_ACCURACY, micros, ASN1_INTEGER, 1)
+} static_ASN1_SEQUENCE_END(TS_ACCURACY)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(TS_ACCURACY)
+IMPLEMENT_ASN1_DUP_FUNCTION(TS_ACCURACY)
+
+ASN1_SEQUENCE(TS_TST_INFO) = {
+        ASN1_SIMPLE(TS_TST_INFO, version, ASN1_INTEGER),
+        ASN1_SIMPLE(TS_TST_INFO, policy_id, ASN1_OBJECT),
+        ASN1_SIMPLE(TS_TST_INFO, msg_imprint, TS_MSG_IMPRINT),
+        ASN1_SIMPLE(TS_TST_INFO, serial, ASN1_INTEGER),
+        ASN1_SIMPLE(TS_TST_INFO, time, ASN1_GENERALIZEDTIME),
+        ASN1_OPT(TS_TST_INFO, accuracy, TS_ACCURACY),
+        ASN1_OPT(TS_TST_INFO, ordering, ASN1_FBOOLEAN),
+        ASN1_OPT(TS_TST_INFO, nonce, ASN1_INTEGER),
+        ASN1_EXP_OPT(TS_TST_INFO, tsa, GENERAL_NAME, 0),
+        ASN1_IMP_SEQUENCE_OF_OPT(TS_TST_INFO, extensions, X509_EXTENSION, 1)
+} static_ASN1_SEQUENCE_END(TS_TST_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(TS_TST_INFO)
+IMPLEMENT_ASN1_DUP_FUNCTION(TS_TST_INFO)
+TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO **a)
+{
+    return ASN1_d2i_bio_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, bp,
+                           a);
+}
+
+int i2d_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO *a)
+{
+    return ASN1_i2d_bio_of_const(TS_TST_INFO, i2d_TS_TST_INFO, bp, a);
+}
+#ifndef OPENSSL_NO_STDIO
+TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a)
+{
+    return ASN1_d2i_fp_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, fp,
+                          a);
+}
+
+int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a)
+{
+    return ASN1_i2d_fp_of_const(TS_TST_INFO, i2d_TS_TST_INFO, fp, a);
+}
+#endif
+
+ASN1_SEQUENCE(TS_STATUS_INFO) = {
+        ASN1_SIMPLE(TS_STATUS_INFO, status, ASN1_INTEGER),
+        ASN1_SEQUENCE_OF_OPT(TS_STATUS_INFO, text, ASN1_UTF8STRING),
+        ASN1_OPT(TS_STATUS_INFO, failure_info, ASN1_BIT_STRING)
+} static_ASN1_SEQUENCE_END(TS_STATUS_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(TS_STATUS_INFO)
+IMPLEMENT_ASN1_DUP_FUNCTION(TS_STATUS_INFO)
+
+static int ts_resp_set_tst_info(TS_RESP *a)
+{
+    long status;
+
+    status = ASN1_INTEGER_get(a->status_info->status);
+
+    if (a->token) {
+        if (status != 0 && status != 1) {
+            TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_PRESENT);
+            return 0;
+        }
+        TS_TST_INFO_free(a->tst_info);
+        a->tst_info = PKCS7_to_TS_TST_INFO(a->token);
+        if (!a->tst_info) {
+            TSerr(TS_F_TS_RESP_SET_TST_INFO,
+                  TS_R_PKCS7_TO_TS_TST_INFO_FAILED);
+            return 0;
+        }
+    } else if (status == 0 || status == 1) {
+        TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_NOT_PRESENT);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int ts_resp_cb(int op, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                      void *exarg)
+{
+    TS_RESP *ts_resp = (TS_RESP *)*pval;
+    if (op == ASN1_OP_NEW_POST) {
+        ts_resp->tst_info = NULL;
+    } else if (op == ASN1_OP_FREE_POST) {
+        TS_TST_INFO_free(ts_resp->tst_info);
+    } else if (op == ASN1_OP_D2I_POST) {
+        if (ts_resp_set_tst_info(ts_resp) == 0)
+            return 0;
+    }
+    return 1;
+}
+
+ASN1_SEQUENCE_cb(TS_RESP, ts_resp_cb) = {
+        ASN1_SIMPLE(TS_RESP, status_info, TS_STATUS_INFO),
+        ASN1_OPT(TS_RESP, token, PKCS7),
+} static_ASN1_SEQUENCE_END_cb(TS_RESP, TS_RESP)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(TS_RESP)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(TS_RESP)
+
+TS_RESP *d2i_TS_RESP_bio(BIO *bp, TS_RESP **a)
+{
+    return ASN1_d2i_bio_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, bp, a);
+}
+
+int i2d_TS_RESP_bio(BIO *bp, TS_RESP *a)
+{
+    return ASN1_i2d_bio_of_const(TS_RESP, i2d_TS_RESP, bp, a);
+}
+#ifndef OPENSSL_NO_STDIO
+TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a)
+{
+    return ASN1_d2i_fp_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, fp, a);
+}
+
+int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a)
+{
+    return ASN1_i2d_fp_of_const(TS_RESP, i2d_TS_RESP, fp, a);
+}
+#endif
+
+ASN1_SEQUENCE(ESS_ISSUER_SERIAL) = {
+        ASN1_SEQUENCE_OF(ESS_ISSUER_SERIAL, issuer, GENERAL_NAME),
+        ASN1_SIMPLE(ESS_ISSUER_SERIAL, serial, ASN1_INTEGER)
+} static_ASN1_SEQUENCE_END(ESS_ISSUER_SERIAL)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(ESS_ISSUER_SERIAL)
+IMPLEMENT_ASN1_DUP_FUNCTION(ESS_ISSUER_SERIAL)
+
+ASN1_SEQUENCE(ESS_CERT_ID) = {
+        ASN1_SIMPLE(ESS_CERT_ID, hash, ASN1_OCTET_STRING),
+        ASN1_OPT(ESS_CERT_ID, issuer_serial, ESS_ISSUER_SERIAL)
+} static_ASN1_SEQUENCE_END(ESS_CERT_ID)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(ESS_CERT_ID)
+IMPLEMENT_ASN1_DUP_FUNCTION(ESS_CERT_ID)
+
+ASN1_SEQUENCE(ESS_SIGNING_CERT) = {
+        ASN1_SEQUENCE_OF(ESS_SIGNING_CERT, cert_ids, ESS_CERT_ID),
+        ASN1_SEQUENCE_OF_OPT(ESS_SIGNING_CERT, policy_info, POLICYINFO)
+} static_ASN1_SEQUENCE_END(ESS_SIGNING_CERT)
+
+IMPLEMENT_ASN1_FUNCTIONS_const(ESS_SIGNING_CERT)
+IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT)
+
+/* Getting encapsulated TS_TST_INFO object from PKCS7. */
+TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token)
+{
+    PKCS7_SIGNED *pkcs7_signed;
+    PKCS7 *enveloped;
+    ASN1_TYPE *tst_info_wrapper;
+    ASN1_OCTET_STRING *tst_info_der;
+    const unsigned char *p;
+
+    if (!PKCS7_type_is_signed(token)) {
+        TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE);
+        return NULL;
+    }
+    if (PKCS7_get_detached(token)) {
+        TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_DETACHED_CONTENT);
+        return NULL;
+    }
+    pkcs7_signed = token->d.sign;
+    enveloped = pkcs7_signed->contents;
+    if (OBJ_obj2nid(enveloped->type) != NID_id_smime_ct_TSTInfo) {
+        TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE);
+        return NULL;
+    }
+    tst_info_wrapper = enveloped->d.other;
+    if (tst_info_wrapper->type != V_ASN1_OCTET_STRING) {
+        TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_TYPE);
+        return NULL;
+    }
+    tst_info_der = tst_info_wrapper->value.octet_string;
+    p = tst_info_der->data;
+    return d2i_TS_TST_INFO(NULL, &p, tst_info_der->length);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_conf.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_conf.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_conf.c	(revision 331)
@@ -0,0 +1,468 @@
+/*
+ * Copyright 2006-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 <string.h>
+
+#include <openssl/crypto.h>
+#include "internal/cryptlib.h"
+#include <openssl/pem.h>
+#include <openssl/engine.h>
+#include <openssl/ts.h>
+
+/* Macro definitions for the configuration file. */
+#define BASE_SECTION                    "tsa"
+#define ENV_DEFAULT_TSA                 "default_tsa"
+#define ENV_SERIAL                      "serial"
+#define ENV_CRYPTO_DEVICE               "crypto_device"
+#define ENV_SIGNER_CERT                 "signer_cert"
+#define ENV_CERTS                       "certs"
+#define ENV_SIGNER_KEY                  "signer_key"
+#define ENV_SIGNER_DIGEST               "signer_digest"
+#define ENV_DEFAULT_POLICY              "default_policy"
+#define ENV_OTHER_POLICIES              "other_policies"
+#define ENV_DIGESTS                     "digests"
+#define ENV_ACCURACY                    "accuracy"
+#define ENV_ORDERING                    "ordering"
+#define ENV_TSA_NAME                    "tsa_name"
+#define ENV_ESS_CERT_ID_CHAIN           "ess_cert_id_chain"
+#define ENV_VALUE_SECS                  "secs"
+#define ENV_VALUE_MILLISECS             "millisecs"
+#define ENV_VALUE_MICROSECS             "microsecs"
+#define ENV_CLOCK_PRECISION_DIGITS      "clock_precision_digits"
+#define ENV_VALUE_YES                   "yes"
+#define ENV_VALUE_NO                    "no"
+
+/* Function definitions for certificate and key loading. */
+
+X509 *TS_CONF_load_cert(const char *file)
+{
+    BIO *cert = NULL;
+    X509 *x = NULL;
+
+    if ((cert = BIO_new_file(file, "r")) == NULL)
+        goto end;
+    x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL);
+ end:
+    if (x == NULL)
+        TSerr(TS_F_TS_CONF_LOAD_CERT, TS_R_CANNOT_LOAD_CERT);
+    BIO_free(cert);
+    return x;
+}
+
+STACK_OF(X509) *TS_CONF_load_certs(const char *file)
+{
+    BIO *certs = NULL;
+    STACK_OF(X509) *othercerts = NULL;
+    STACK_OF(X509_INFO) *allcerts = NULL;
+    int i;
+
+    if ((certs = BIO_new_file(file, "r")) == NULL)
+        goto end;
+    if ((othercerts = sk_X509_new_null()) == NULL)
+        goto end;
+
+    allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL);
+    for (i = 0; i < sk_X509_INFO_num(allcerts); i++) {
+        X509_INFO *xi = sk_X509_INFO_value(allcerts, i);
+        if (xi->x509) {
+            sk_X509_push(othercerts, xi->x509);
+            xi->x509 = NULL;
+        }
+    }
+ end:
+    if (othercerts == NULL)
+        TSerr(TS_F_TS_CONF_LOAD_CERTS, TS_R_CANNOT_LOAD_CERT);
+    sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
+    BIO_free(certs);
+    return othercerts;
+}
+
+EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass)
+{
+    BIO *key = NULL;
+    EVP_PKEY *pkey = NULL;
+
+    if ((key = BIO_new_file(file, "r")) == NULL)
+        goto end;
+    pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, (char *)pass);
+ end:
+    if (pkey == NULL)
+        TSerr(TS_F_TS_CONF_LOAD_KEY, TS_R_CANNOT_LOAD_KEY);
+    BIO_free(key);
+    return pkey;
+}
+
+/* Function definitions for handling configuration options. */
+
+static void ts_CONF_lookup_fail(const char *name, const char *tag)
+{
+    TSerr(TS_F_TS_CONF_LOOKUP_FAIL, TS_R_VAR_LOOKUP_FAILURE);
+    ERR_add_error_data(3, name, "::", tag);
+}
+
+static void ts_CONF_invalid(const char *name, const char *tag)
+{
+    TSerr(TS_F_TS_CONF_INVALID, TS_R_VAR_BAD_VALUE);
+    ERR_add_error_data(3, name, "::", tag);
+}
+
+const char *TS_CONF_get_tsa_section(CONF *conf, const char *section)
+{
+    if (!section) {
+        section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_TSA);
+        if (!section)
+            ts_CONF_lookup_fail(BASE_SECTION, ENV_DEFAULT_TSA);
+    }
+    return section;
+}
+
+int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb,
+                       TS_RESP_CTX *ctx)
+{
+    int ret = 0;
+    char *serial = NCONF_get_string(conf, section, ENV_SERIAL);
+    if (!serial) {
+        ts_CONF_lookup_fail(section, ENV_SERIAL);
+        goto err;
+    }
+    TS_RESP_CTX_set_serial_cb(ctx, cb, serial);
+
+    ret = 1;
+ err:
+    return ret;
+}
+
+#ifndef OPENSSL_NO_ENGINE
+
+int TS_CONF_set_crypto_device(CONF *conf, const char *section,
+                              const char *device)
+{
+    int ret = 0;
+
+    if (device == NULL)
+        device = NCONF_get_string(conf, section, ENV_CRYPTO_DEVICE);
+
+    if (device && !TS_CONF_set_default_engine(device)) {
+        ts_CONF_invalid(section, ENV_CRYPTO_DEVICE);
+        goto err;
+    }
+    ret = 1;
+ err:
+    return ret;
+}
+
+int TS_CONF_set_default_engine(const char *name)
+{
+    ENGINE *e = NULL;
+    int ret = 0;
+
+    if (strcmp(name, "builtin") == 0)
+        return 1;
+
+    if ((e = ENGINE_by_id(name)) == NULL)
+        goto err;
+    if (strcmp(name, "chil") == 0)
+        ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0);
+    if (!ENGINE_set_default(e, ENGINE_METHOD_ALL))
+        goto err;
+    ret = 1;
+
+ err:
+    if (!ret) {
+        TSerr(TS_F_TS_CONF_SET_DEFAULT_ENGINE, TS_R_COULD_NOT_SET_ENGINE);
+        ERR_add_error_data(2, "engine:", name);
+    }
+    ENGINE_free(e);
+    return ret;
+}
+
+#endif
+
+int TS_CONF_set_signer_cert(CONF *conf, const char *section,
+                            const char *cert, TS_RESP_CTX *ctx)
+{
+    int ret = 0;
+    X509 *cert_obj = NULL;
+
+    if (cert == NULL) {
+        cert = NCONF_get_string(conf, section, ENV_SIGNER_CERT);
+        if (cert == NULL) {
+            ts_CONF_lookup_fail(section, ENV_SIGNER_CERT);
+            goto err;
+        }
+    }
+    if ((cert_obj = TS_CONF_load_cert(cert)) == NULL)
+        goto err;
+    if (!TS_RESP_CTX_set_signer_cert(ctx, cert_obj))
+        goto err;
+
+    ret = 1;
+ err:
+    X509_free(cert_obj);
+    return ret;
+}
+
+int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs,
+                      TS_RESP_CTX *ctx)
+{
+    int ret = 0;
+    STACK_OF(X509) *certs_obj = NULL;
+
+    if (certs == NULL) {
+        /* Certificate chain is optional. */
+        if ((certs = NCONF_get_string(conf, section, ENV_CERTS)) == NULL)
+            goto end;
+    }
+    if ((certs_obj = TS_CONF_load_certs(certs)) == NULL)
+        goto err;
+    if (!TS_RESP_CTX_set_certs(ctx, certs_obj))
+        goto err;
+ end:
+    ret = 1;
+ err:
+    sk_X509_pop_free(certs_obj, X509_free);
+    return ret;
+}
+
+int TS_CONF_set_signer_key(CONF *conf, const char *section,
+                           const char *key, const char *pass,
+                           TS_RESP_CTX *ctx)
+{
+    int ret = 0;
+    EVP_PKEY *key_obj = NULL;
+    if (!key)
+        key = NCONF_get_string(conf, section, ENV_SIGNER_KEY);
+    if (!key) {
+        ts_CONF_lookup_fail(section, ENV_SIGNER_KEY);
+        goto err;
+    }
+    if ((key_obj = TS_CONF_load_key(key, pass)) == NULL)
+        goto err;
+    if (!TS_RESP_CTX_set_signer_key(ctx, key_obj))
+        goto err;
+
+    ret = 1;
+ err:
+    EVP_PKEY_free(key_obj);
+    return ret;
+}
+
+int TS_CONF_set_signer_digest(CONF *conf, const char *section,
+                              const char *md, TS_RESP_CTX *ctx)
+{
+    int ret = 0;
+    const EVP_MD *sign_md = NULL;
+    if (md == NULL)
+        md = NCONF_get_string(conf, section, ENV_SIGNER_DIGEST);
+    if (md == NULL) {
+        ts_CONF_lookup_fail(section, ENV_SIGNER_DIGEST);
+        goto err;
+    }
+    sign_md = EVP_get_digestbyname(md);
+    if (sign_md == NULL) {
+        ts_CONF_invalid(section, ENV_SIGNER_DIGEST);
+        goto err;
+    }
+    if (!TS_RESP_CTX_set_signer_digest(ctx, sign_md))
+        goto err;
+
+    ret = 1;
+ err:
+    return ret;
+}
+
+int TS_CONF_set_def_policy(CONF *conf, const char *section,
+                           const char *policy, TS_RESP_CTX *ctx)
+{
+    int ret = 0;
+    ASN1_OBJECT *policy_obj = NULL;
+    if (!policy)
+        policy = NCONF_get_string(conf, section, ENV_DEFAULT_POLICY);
+    if (!policy) {
+        ts_CONF_lookup_fail(section, ENV_DEFAULT_POLICY);
+        goto err;
+    }
+    if ((policy_obj = OBJ_txt2obj(policy, 0)) == NULL) {
+        ts_CONF_invalid(section, ENV_DEFAULT_POLICY);
+        goto err;
+    }
+    if (!TS_RESP_CTX_set_def_policy(ctx, policy_obj))
+        goto err;
+
+    ret = 1;
+ err:
+    ASN1_OBJECT_free(policy_obj);
+    return ret;
+}
+
+int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx)
+{
+    int ret = 0;
+    int i;
+    STACK_OF(CONF_VALUE) *list = NULL;
+    char *policies = NCONF_get_string(conf, section, ENV_OTHER_POLICIES);
+
+    /* If no other policy is specified, that's fine. */
+    if (policies && (list = X509V3_parse_list(policies)) == NULL) {
+        ts_CONF_invalid(section, ENV_OTHER_POLICIES);
+        goto err;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(list); ++i) {
+        CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
+        const char *extval = val->value ? val->value : val->name;
+        ASN1_OBJECT *objtmp;
+
+        if ((objtmp = OBJ_txt2obj(extval, 0)) == NULL) {
+            ts_CONF_invalid(section, ENV_OTHER_POLICIES);
+            goto err;
+        }
+        if (!TS_RESP_CTX_add_policy(ctx, objtmp))
+            goto err;
+        ASN1_OBJECT_free(objtmp);
+    }
+
+    ret = 1;
+ err:
+    sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
+    return ret;
+}
+
+int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx)
+{
+    int ret = 0;
+    int i;
+    STACK_OF(CONF_VALUE) *list = NULL;
+    char *digests = NCONF_get_string(conf, section, ENV_DIGESTS);
+
+    if (digests == NULL) {
+        ts_CONF_lookup_fail(section, ENV_DIGESTS);
+        goto err;
+    }
+    if ((list = X509V3_parse_list(digests)) == NULL) {
+        ts_CONF_invalid(section, ENV_DIGESTS);
+        goto err;
+    }
+    if (sk_CONF_VALUE_num(list) == 0) {
+        ts_CONF_invalid(section, ENV_DIGESTS);
+        goto err;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(list); ++i) {
+        CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
+        const char *extval = val->value ? val->value : val->name;
+        const EVP_MD *md;
+
+        if ((md = EVP_get_digestbyname(extval)) == NULL) {
+            ts_CONF_invalid(section, ENV_DIGESTS);
+            goto err;
+        }
+        if (!TS_RESP_CTX_add_md(ctx, md))
+            goto err;
+    }
+
+    ret = 1;
+ err:
+    sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
+    return ret;
+}
+
+int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx)
+{
+    int ret = 0;
+    int i;
+    int secs = 0, millis = 0, micros = 0;
+    STACK_OF(CONF_VALUE) *list = NULL;
+    char *accuracy = NCONF_get_string(conf, section, ENV_ACCURACY);
+
+    if (accuracy && (list = X509V3_parse_list(accuracy)) == NULL) {
+        ts_CONF_invalid(section, ENV_ACCURACY);
+        goto err;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(list); ++i) {
+        CONF_VALUE *val = sk_CONF_VALUE_value(list, i);
+        if (strcmp(val->name, ENV_VALUE_SECS) == 0) {
+            if (val->value)
+                secs = atoi(val->value);
+        } else if (strcmp(val->name, ENV_VALUE_MILLISECS) == 0) {
+            if (val->value)
+                millis = atoi(val->value);
+        } else if (strcmp(val->name, ENV_VALUE_MICROSECS) == 0) {
+            if (val->value)
+                micros = atoi(val->value);
+        } else {
+            ts_CONF_invalid(section, ENV_ACCURACY);
+            goto err;
+        }
+    }
+    if (!TS_RESP_CTX_set_accuracy(ctx, secs, millis, micros))
+        goto err;
+
+    ret = 1;
+ err:
+    sk_CONF_VALUE_pop_free(list, X509V3_conf_free);
+    return ret;
+}
+
+int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section,
+                                       TS_RESP_CTX *ctx)
+{
+    int ret = 0;
+    long digits = 0;
+
+    /*
+     * If not specified, set the default value to 0, i.e. sec precision
+     */
+    if (!NCONF_get_number_e(conf, section, ENV_CLOCK_PRECISION_DIGITS,
+                            &digits))
+        digits = 0;
+    if (digits < 0 || digits > TS_MAX_CLOCK_PRECISION_DIGITS) {
+        ts_CONF_invalid(section, ENV_CLOCK_PRECISION_DIGITS);
+        goto err;
+    }
+
+    if (!TS_RESP_CTX_set_clock_precision_digits(ctx, digits))
+        goto err;
+
+    return 1;
+ err:
+    return ret;
+}
+
+static int ts_CONF_add_flag(CONF *conf, const char *section,
+                            const char *field, int flag, TS_RESP_CTX *ctx)
+{
+    const char *value = NCONF_get_string(conf, section, field);
+
+    if (value) {
+        if (strcmp(value, ENV_VALUE_YES) == 0)
+            TS_RESP_CTX_add_flags(ctx, flag);
+        else if (strcmp(value, ENV_VALUE_NO) != 0) {
+            ts_CONF_invalid(section, field);
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx)
+{
+    return ts_CONF_add_flag(conf, section, ENV_ORDERING, TS_ORDERING, ctx);
+}
+
+int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx)
+{
+    return ts_CONF_add_flag(conf, section, ENV_TSA_NAME, TS_TSA_NAME, ctx);
+}
+
+int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section,
+                                  TS_RESP_CTX *ctx)
+{
+    return ts_CONF_add_flag(conf, section, ENV_ESS_CERT_ID_CHAIN,
+                            TS_ESS_CERT_ID_CHAIN, ctx);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_err.c	(revision 331)
@@ -0,0 +1,144 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/ts.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_TS,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_TS,0,reason)
+
+static ERR_STRING_DATA TS_str_functs[] = {
+    {ERR_FUNC(TS_F_DEF_SERIAL_CB), "def_serial_cb"},
+    {ERR_FUNC(TS_F_DEF_TIME_CB), "def_time_cb"},
+    {ERR_FUNC(TS_F_ESS_ADD_SIGNING_CERT), "ESS_add_signing_cert"},
+    {ERR_FUNC(TS_F_ESS_CERT_ID_NEW_INIT), "ess_CERT_ID_new_init"},
+    {ERR_FUNC(TS_F_ESS_SIGNING_CERT_NEW_INIT), "ess_SIGNING_CERT_new_init"},
+    {ERR_FUNC(TS_F_INT_TS_RESP_VERIFY_TOKEN), "int_ts_RESP_verify_token"},
+    {ERR_FUNC(TS_F_PKCS7_TO_TS_TST_INFO), "PKCS7_to_TS_TST_INFO"},
+    {ERR_FUNC(TS_F_TS_ACCURACY_SET_MICROS), "TS_ACCURACY_set_micros"},
+    {ERR_FUNC(TS_F_TS_ACCURACY_SET_MILLIS), "TS_ACCURACY_set_millis"},
+    {ERR_FUNC(TS_F_TS_ACCURACY_SET_SECONDS), "TS_ACCURACY_set_seconds"},
+    {ERR_FUNC(TS_F_TS_CHECK_IMPRINTS), "ts_check_imprints"},
+    {ERR_FUNC(TS_F_TS_CHECK_NONCES), "ts_check_nonces"},
+    {ERR_FUNC(TS_F_TS_CHECK_POLICY), "ts_check_policy"},
+    {ERR_FUNC(TS_F_TS_CHECK_SIGNING_CERTS), "ts_check_signing_certs"},
+    {ERR_FUNC(TS_F_TS_CHECK_STATUS_INFO), "ts_check_status_info"},
+    {ERR_FUNC(TS_F_TS_COMPUTE_IMPRINT), "ts_compute_imprint"},
+    {ERR_FUNC(TS_F_TS_CONF_INVALID), "ts_CONF_invalid"},
+    {ERR_FUNC(TS_F_TS_CONF_LOAD_CERT), "TS_CONF_load_cert"},
+    {ERR_FUNC(TS_F_TS_CONF_LOAD_CERTS), "TS_CONF_load_certs"},
+    {ERR_FUNC(TS_F_TS_CONF_LOAD_KEY), "TS_CONF_load_key"},
+    {ERR_FUNC(TS_F_TS_CONF_LOOKUP_FAIL), "ts_CONF_lookup_fail"},
+    {ERR_FUNC(TS_F_TS_CONF_SET_DEFAULT_ENGINE), "TS_CONF_set_default_engine"},
+    {ERR_FUNC(TS_F_TS_GET_STATUS_TEXT), "ts_get_status_text"},
+    {ERR_FUNC(TS_F_TS_MSG_IMPRINT_SET_ALGO), "TS_MSG_IMPRINT_set_algo"},
+    {ERR_FUNC(TS_F_TS_REQ_SET_MSG_IMPRINT), "TS_REQ_set_msg_imprint"},
+    {ERR_FUNC(TS_F_TS_REQ_SET_NONCE), "TS_REQ_set_nonce"},
+    {ERR_FUNC(TS_F_TS_REQ_SET_POLICY_ID), "TS_REQ_set_policy_id"},
+    {ERR_FUNC(TS_F_TS_RESP_CREATE_RESPONSE), "TS_RESP_create_response"},
+    {ERR_FUNC(TS_F_TS_RESP_CREATE_TST_INFO), "ts_RESP_create_tst_info"},
+    {ERR_FUNC(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO),
+     "TS_RESP_CTX_add_failure_info"},
+    {ERR_FUNC(TS_F_TS_RESP_CTX_ADD_MD), "TS_RESP_CTX_add_md"},
+    {ERR_FUNC(TS_F_TS_RESP_CTX_ADD_POLICY), "TS_RESP_CTX_add_policy"},
+    {ERR_FUNC(TS_F_TS_RESP_CTX_NEW), "TS_RESP_CTX_new"},
+    {ERR_FUNC(TS_F_TS_RESP_CTX_SET_ACCURACY), "TS_RESP_CTX_set_accuracy"},
+    {ERR_FUNC(TS_F_TS_RESP_CTX_SET_CERTS), "TS_RESP_CTX_set_certs"},
+    {ERR_FUNC(TS_F_TS_RESP_CTX_SET_DEF_POLICY), "TS_RESP_CTX_set_def_policy"},
+    {ERR_FUNC(TS_F_TS_RESP_CTX_SET_SIGNER_CERT),
+     "TS_RESP_CTX_set_signer_cert"},
+    {ERR_FUNC(TS_F_TS_RESP_CTX_SET_STATUS_INFO),
+     "TS_RESP_CTX_set_status_info"},
+    {ERR_FUNC(TS_F_TS_RESP_GET_POLICY), "ts_RESP_get_policy"},
+    {ERR_FUNC(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION),
+     "TS_RESP_set_genTime_with_precision"},
+    {ERR_FUNC(TS_F_TS_RESP_SET_STATUS_INFO), "TS_RESP_set_status_info"},
+    {ERR_FUNC(TS_F_TS_RESP_SET_TST_INFO), "TS_RESP_set_tst_info"},
+    {ERR_FUNC(TS_F_TS_RESP_SIGN), "ts_RESP_sign"},
+    {ERR_FUNC(TS_F_TS_RESP_VERIFY_SIGNATURE), "TS_RESP_verify_signature"},
+    {ERR_FUNC(TS_F_TS_TST_INFO_SET_ACCURACY), "TS_TST_INFO_set_accuracy"},
+    {ERR_FUNC(TS_F_TS_TST_INFO_SET_MSG_IMPRINT),
+     "TS_TST_INFO_set_msg_imprint"},
+    {ERR_FUNC(TS_F_TS_TST_INFO_SET_NONCE), "TS_TST_INFO_set_nonce"},
+    {ERR_FUNC(TS_F_TS_TST_INFO_SET_POLICY_ID), "TS_TST_INFO_set_policy_id"},
+    {ERR_FUNC(TS_F_TS_TST_INFO_SET_SERIAL), "TS_TST_INFO_set_serial"},
+    {ERR_FUNC(TS_F_TS_TST_INFO_SET_TIME), "TS_TST_INFO_set_time"},
+    {ERR_FUNC(TS_F_TS_TST_INFO_SET_TSA), "TS_TST_INFO_set_tsa"},
+    {ERR_FUNC(TS_F_TS_VERIFY), "TS_VERIFY"},
+    {ERR_FUNC(TS_F_TS_VERIFY_CERT), "ts_verify_cert"},
+    {ERR_FUNC(TS_F_TS_VERIFY_CTX_NEW), "TS_VERIFY_CTX_new"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA TS_str_reasons[] = {
+    {ERR_REASON(TS_R_BAD_PKCS7_TYPE), "bad pkcs7 type"},
+    {ERR_REASON(TS_R_BAD_TYPE), "bad type"},
+    {ERR_REASON(TS_R_CANNOT_LOAD_CERT), "cannot load certificate"},
+    {ERR_REASON(TS_R_CANNOT_LOAD_KEY), "cannot load private key"},
+    {ERR_REASON(TS_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"},
+    {ERR_REASON(TS_R_COULD_NOT_SET_ENGINE), "could not set engine"},
+    {ERR_REASON(TS_R_COULD_NOT_SET_TIME), "could not set time"},
+    {ERR_REASON(TS_R_DETACHED_CONTENT), "detached content"},
+    {ERR_REASON(TS_R_ESS_ADD_SIGNING_CERT_ERROR),
+     "ess add signing cert error"},
+    {ERR_REASON(TS_R_ESS_SIGNING_CERTIFICATE_ERROR),
+     "ess signing certificate error"},
+    {ERR_REASON(TS_R_INVALID_NULL_POINTER), "invalid null pointer"},
+    {ERR_REASON(TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE),
+     "invalid signer certificate purpose"},
+    {ERR_REASON(TS_R_MESSAGE_IMPRINT_MISMATCH), "message imprint mismatch"},
+    {ERR_REASON(TS_R_NONCE_MISMATCH), "nonce mismatch"},
+    {ERR_REASON(TS_R_NONCE_NOT_RETURNED), "nonce not returned"},
+    {ERR_REASON(TS_R_NO_CONTENT), "no content"},
+    {ERR_REASON(TS_R_NO_TIME_STAMP_TOKEN), "no time stamp token"},
+    {ERR_REASON(TS_R_PKCS7_ADD_SIGNATURE_ERROR), "pkcs7 add signature error"},
+    {ERR_REASON(TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR),
+     "pkcs7 add signed attr error"},
+    {ERR_REASON(TS_R_PKCS7_TO_TS_TST_INFO_FAILED),
+     "pkcs7 to ts tst info failed"},
+    {ERR_REASON(TS_R_POLICY_MISMATCH), "policy mismatch"},
+    {ERR_REASON(TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),
+     "private key does not match certificate"},
+    {ERR_REASON(TS_R_RESPONSE_SETUP_ERROR), "response setup error"},
+    {ERR_REASON(TS_R_SIGNATURE_FAILURE), "signature failure"},
+    {ERR_REASON(TS_R_THERE_MUST_BE_ONE_SIGNER), "there must be one signer"},
+    {ERR_REASON(TS_R_TIME_SYSCALL_ERROR), "time syscall error"},
+    {ERR_REASON(TS_R_TOKEN_NOT_PRESENT), "token not present"},
+    {ERR_REASON(TS_R_TOKEN_PRESENT), "token present"},
+    {ERR_REASON(TS_R_TSA_NAME_MISMATCH), "tsa name mismatch"},
+    {ERR_REASON(TS_R_TSA_UNTRUSTED), "tsa untrusted"},
+    {ERR_REASON(TS_R_TST_INFO_SETUP_ERROR), "tst info setup error"},
+    {ERR_REASON(TS_R_TS_DATASIGN), "ts datasign"},
+    {ERR_REASON(TS_R_UNACCEPTABLE_POLICY), "unacceptable policy"},
+    {ERR_REASON(TS_R_UNSUPPORTED_MD_ALGORITHM), "unsupported md algorithm"},
+    {ERR_REASON(TS_R_UNSUPPORTED_VERSION), "unsupported version"},
+    {ERR_REASON(TS_R_VAR_BAD_VALUE), "var bad value"},
+    {ERR_REASON(TS_R_VAR_LOOKUP_FAILURE), "cannot find config variable"},
+    {ERR_REASON(TS_R_WRONG_CONTENT_TYPE), "wrong content type"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_TS_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(TS_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, TS_str_functs);
+        ERR_load_strings(0, TS_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_lcl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_lcl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_lcl.h	(revision 331)
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2015-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
+ */
+
+/*-
+ * MessageImprint ::= SEQUENCE  {
+ *      hashAlgorithm                AlgorithmIdentifier,
+ *      hashedMessage                OCTET STRING  }
+ */
+struct TS_msg_imprint_st {
+    X509_ALGOR *hash_algo;
+    ASN1_OCTET_STRING *hashed_msg;
+};
+
+/*-
+ * TimeStampResp ::= SEQUENCE  {
+ *     status                  PKIStatusInfo,
+ *     timeStampToken          TimeStampToken     OPTIONAL }
+ */
+struct TS_resp_st {
+    TS_STATUS_INFO *status_info;
+    PKCS7 *token;
+    TS_TST_INFO *tst_info;
+};
+
+/*-
+ * TimeStampReq ::= SEQUENCE  {
+ *    version                  INTEGER  { v1(1) },
+ *    messageImprint           MessageImprint,
+ *      --a hash algorithm OID and the hash value of the data to be
+ *      --time-stamped
+ *    reqPolicy                TSAPolicyId                OPTIONAL,
+ *    nonce                    INTEGER                    OPTIONAL,
+ *    certReq                  BOOLEAN                    DEFAULT FALSE,
+ *    extensions               [0] IMPLICIT Extensions    OPTIONAL  }
+ */
+struct TS_req_st {
+    ASN1_INTEGER *version;
+    TS_MSG_IMPRINT *msg_imprint;
+    ASN1_OBJECT *policy_id;
+    ASN1_INTEGER *nonce;
+    ASN1_BOOLEAN cert_req;
+    STACK_OF(X509_EXTENSION) *extensions;
+};
+
+/*-
+ * Accuracy ::= SEQUENCE {
+ *                 seconds        INTEGER           OPTIONAL,
+ *                 millis     [0] INTEGER  (1..999) OPTIONAL,
+ *                 micros     [1] INTEGER  (1..999) OPTIONAL  }
+ */
+struct TS_accuracy_st {
+    ASN1_INTEGER *seconds;
+    ASN1_INTEGER *millis;
+    ASN1_INTEGER *micros;
+};
+
+/*-
+ * TSTInfo ::= SEQUENCE  {
+ *     version                      INTEGER  { v1(1) },
+ *     policy                       TSAPolicyId,
+ *     messageImprint               MessageImprint,
+ *       -- MUST have the same value as the similar field in
+ *       -- TimeStampReq
+ *     serialNumber                 INTEGER,
+ *      -- Time-Stamping users MUST be ready to accommodate integers
+ *      -- up to 160 bits.
+ *     genTime                      GeneralizedTime,
+ *     accuracy                     Accuracy                 OPTIONAL,
+ *     ordering                     BOOLEAN             DEFAULT FALSE,
+ *     nonce                        INTEGER                  OPTIONAL,
+ *       -- MUST be present if the similar field was present
+ *       -- in TimeStampReq.  In that case it MUST have the same value.
+ *     tsa                          [0] GeneralName          OPTIONAL,
+ *     extensions                   [1] IMPLICIT Extensions  OPTIONAL   }
+ */
+struct TS_tst_info_st {
+    ASN1_INTEGER *version;
+    ASN1_OBJECT *policy_id;
+    TS_MSG_IMPRINT *msg_imprint;
+    ASN1_INTEGER *serial;
+    ASN1_GENERALIZEDTIME *time;
+    TS_ACCURACY *accuracy;
+    ASN1_BOOLEAN ordering;
+    ASN1_INTEGER *nonce;
+    GENERAL_NAME *tsa;
+    STACK_OF(X509_EXTENSION) *extensions;
+};
+
+struct TS_status_info_st {
+    ASN1_INTEGER *status;
+    STACK_OF(ASN1_UTF8STRING) *text;
+    ASN1_BIT_STRING *failure_info;
+};
+
+/*-
+ * IssuerSerial ::= SEQUENCE {
+ *         issuer                   GeneralNames,
+ *         serialNumber             CertificateSerialNumber
+ *         }
+ */
+struct ESS_issuer_serial {
+    STACK_OF(GENERAL_NAME) *issuer;
+    ASN1_INTEGER *serial;
+};
+
+/*-
+ * ESSCertID ::=  SEQUENCE {
+ *         certHash                 Hash,
+ *         issuerSerial             IssuerSerial OPTIONAL
+ * }
+ */
+struct ESS_cert_id {
+    ASN1_OCTET_STRING *hash;    /* Always SHA-1 digest. */
+    ESS_ISSUER_SERIAL *issuer_serial;
+};
+
+/*-
+ * SigningCertificate ::=  SEQUENCE {
+ *        certs        SEQUENCE OF ESSCertID,
+ *        policies     SEQUENCE OF PolicyInformation OPTIONAL
+ * }
+ */
+struct ESS_signing_cert {
+    STACK_OF(ESS_CERT_ID) *cert_ids;
+    STACK_OF(POLICYINFO) *policy_info;
+};
+
+
+struct TS_resp_ctx {
+    X509 *signer_cert;
+    EVP_PKEY *signer_key;
+    const EVP_MD *signer_md;
+    STACK_OF(X509) *certs;      /* Certs to include in signed data. */
+    STACK_OF(ASN1_OBJECT) *policies; /* Acceptable policies. */
+    ASN1_OBJECT *default_policy; /* It may appear in policies, too. */
+    STACK_OF(EVP_MD) *mds;      /* Acceptable message digests. */
+    ASN1_INTEGER *seconds;      /* accuracy, 0 means not specified. */
+    ASN1_INTEGER *millis;       /* accuracy, 0 means not specified. */
+    ASN1_INTEGER *micros;       /* accuracy, 0 means not specified. */
+    unsigned clock_precision_digits; /* fraction of seconds in time stamp
+                                      * token. */
+    unsigned flags;             /* Optional info, see values above. */
+    /* Callback functions. */
+    TS_serial_cb serial_cb;
+    void *serial_cb_data;       /* User data for serial_cb. */
+    TS_time_cb time_cb;
+    void *time_cb_data;         /* User data for time_cb. */
+    TS_extension_cb extension_cb;
+    void *extension_cb_data;    /* User data for extension_cb. */
+    /* These members are used only while creating the response. */
+    TS_REQ *request;
+    TS_RESP *response;
+    TS_TST_INFO *tst_info;
+};
+
+struct TS_verify_ctx {
+    /* Set this to the union of TS_VFY_... flags you want to carry out. */
+    unsigned flags;
+    /* Must be set only with TS_VFY_SIGNATURE. certs is optional. */
+    X509_STORE *store;
+    STACK_OF(X509) *certs;
+    /* Must be set only with TS_VFY_POLICY. */
+    ASN1_OBJECT *policy;
+    /*
+     * Must be set only with TS_VFY_IMPRINT. If md_alg is NULL, the
+     * algorithm from the response is used.
+     */
+    X509_ALGOR *md_alg;
+    unsigned char *imprint;
+    unsigned imprint_len;
+    /* Must be set only with TS_VFY_DATA. */
+    BIO *data;
+    /* Must be set only with TS_VFY_TSA_NAME. */
+    ASN1_INTEGER *nonce;
+    /* Must be set only with TS_VFY_TSA_NAME. */
+    GENERAL_NAME *tsa_name;
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_lib.c	(revision 331)
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/bn.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/ts.h>
+#include "ts_lcl.h"
+
+int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num)
+{
+    BIGNUM *num_bn;
+    int result = 0;
+    char *hex;
+
+    num_bn = BN_new();
+    if (num_bn == NULL)
+        return -1;
+    ASN1_INTEGER_to_BN(num, num_bn);
+    if ((hex = BN_bn2hex(num_bn))) {
+        result = BIO_write(bio, "0x", 2) > 0;
+        result = result && BIO_write(bio, hex, strlen(hex)) > 0;
+        OPENSSL_free(hex);
+    }
+    BN_free(num_bn);
+
+    return result;
+}
+
+int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj)
+{
+    char obj_txt[128];
+
+    OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0);
+    BIO_printf(bio, "%s\n", obj_txt);
+
+    return 1;
+}
+
+int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions)
+{
+    int i, critical, n;
+    X509_EXTENSION *ex;
+    ASN1_OBJECT *obj;
+
+    BIO_printf(bio, "Extensions:\n");
+    n = X509v3_get_ext_count(extensions);
+    for (i = 0; i < n; i++) {
+        ex = X509v3_get_ext(extensions, i);
+        obj = X509_EXTENSION_get_object(ex);
+        if (i2a_ASN1_OBJECT(bio, obj) < 0)
+            return 0;
+        critical = X509_EXTENSION_get_critical(ex);
+        BIO_printf(bio, ":%s\n", critical ? " critical" : "");
+        if (!X509V3_EXT_print(bio, ex, 0, 4)) {
+            BIO_printf(bio, "%4s", "");
+            ASN1_STRING_print(bio, X509_EXTENSION_get_data(ex));
+        }
+        BIO_write(bio, "\n", 1);
+    }
+
+    return 1;
+}
+
+int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg)
+{
+    int i = OBJ_obj2nid(alg->algorithm);
+    return BIO_printf(bio, "Hash Algorithm: %s\n",
+                      (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
+}
+
+int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *a)
+{
+    ASN1_OCTET_STRING *msg;
+
+    TS_X509_ALGOR_print_bio(bio, a->hash_algo);
+
+    BIO_printf(bio, "Message data:\n");
+    msg = a->hashed_msg;
+    BIO_dump_indent(bio, (const char *)ASN1_STRING_get0_data(msg),
+                    ASN1_STRING_length(msg), 4);
+
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_req_print.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_req_print.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_req_print.c	(revision 331)
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/bn.h>
+#include <openssl/x509v3.h>
+#include <openssl/ts.h>
+#include "ts_lcl.h"
+
+int TS_REQ_print_bio(BIO *bio, TS_REQ *a)
+{
+    int v;
+    ASN1_OBJECT *policy_id;
+
+    if (a == NULL)
+        return 0;
+
+    v = TS_REQ_get_version(a);
+    BIO_printf(bio, "Version: %d\n", v);
+
+    TS_MSG_IMPRINT_print_bio(bio, a->msg_imprint);
+
+    BIO_printf(bio, "Policy OID: ");
+    policy_id = TS_REQ_get_policy_id(a);
+    if (policy_id == NULL)
+        BIO_printf(bio, "unspecified\n");
+    else
+        TS_OBJ_print_bio(bio, policy_id);
+
+    BIO_printf(bio, "Nonce: ");
+    if (a->nonce == NULL)
+        BIO_printf(bio, "unspecified");
+    else
+        TS_ASN1_INTEGER_print_bio(bio, a->nonce);
+    BIO_write(bio, "\n", 1);
+
+    BIO_printf(bio, "Certificate required: %s\n",
+               a->cert_req ? "yes" : "no");
+
+    TS_ext_print_bio(bio, a->extensions);
+
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_req_utils.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_req_utils.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_req_utils.c	(revision 331)
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/x509v3.h>
+#include <openssl/ts.h>
+#include "ts_lcl.h"
+
+int TS_REQ_set_version(TS_REQ *a, long version)
+{
+    return ASN1_INTEGER_set(a->version, version);
+}
+
+long TS_REQ_get_version(const TS_REQ *a)
+{
+    return ASN1_INTEGER_get(a->version);
+}
+
+int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint)
+{
+    TS_MSG_IMPRINT *new_msg_imprint;
+
+    if (a->msg_imprint == msg_imprint)
+        return 1;
+    new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint);
+    if (new_msg_imprint == NULL) {
+        TSerr(TS_F_TS_REQ_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    TS_MSG_IMPRINT_free(a->msg_imprint);
+    a->msg_imprint = new_msg_imprint;
+    return 1;
+}
+
+TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a)
+{
+    return a->msg_imprint;
+}
+
+int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg)
+{
+    X509_ALGOR *new_alg;
+
+    if (a->hash_algo == alg)
+        return 1;
+    new_alg = X509_ALGOR_dup(alg);
+    if (new_alg == NULL) {
+        TSerr(TS_F_TS_MSG_IMPRINT_SET_ALGO, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    X509_ALGOR_free(a->hash_algo);
+    a->hash_algo = new_alg;
+    return 1;
+}
+
+X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a)
+{
+    return a->hash_algo;
+}
+
+int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len)
+{
+    return ASN1_OCTET_STRING_set(a->hashed_msg, d, len);
+}
+
+ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a)
+{
+    return a->hashed_msg;
+}
+
+int TS_REQ_set_policy_id(TS_REQ *a, const ASN1_OBJECT *policy)
+{
+    ASN1_OBJECT *new_policy;
+
+    if (a->policy_id == policy)
+        return 1;
+    new_policy = OBJ_dup(policy);
+    if (new_policy == NULL) {
+        TSerr(TS_F_TS_REQ_SET_POLICY_ID, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    ASN1_OBJECT_free(a->policy_id);
+    a->policy_id = new_policy;
+    return 1;
+}
+
+ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a)
+{
+    return a->policy_id;
+}
+
+int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce)
+{
+    ASN1_INTEGER *new_nonce;
+
+    if (a->nonce == nonce)
+        return 1;
+    new_nonce = ASN1_INTEGER_dup(nonce);
+    if (new_nonce == NULL) {
+        TSerr(TS_F_TS_REQ_SET_NONCE, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    ASN1_INTEGER_free(a->nonce);
+    a->nonce = new_nonce;
+    return 1;
+}
+
+const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a)
+{
+    return a->nonce;
+}
+
+int TS_REQ_set_cert_req(TS_REQ *a, int cert_req)
+{
+    a->cert_req = cert_req ? 0xFF : 0x00;
+    return 1;
+}
+
+int TS_REQ_get_cert_req(const TS_REQ *a)
+{
+    return a->cert_req ? 1 : 0;
+}
+
+STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a)
+{
+    return a->extensions;
+}
+
+void TS_REQ_ext_free(TS_REQ *a)
+{
+    if (!a)
+        return;
+    sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free);
+    a->extensions = NULL;
+}
+
+int TS_REQ_get_ext_count(TS_REQ *a)
+{
+    return X509v3_get_ext_count(a->extensions);
+}
+
+int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos)
+{
+    return X509v3_get_ext_by_NID(a->extensions, nid, lastpos);
+}
+
+int TS_REQ_get_ext_by_OBJ(TS_REQ *a, const ASN1_OBJECT *obj, int lastpos)
+{
+    return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos);
+}
+
+int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos)
+{
+    return X509v3_get_ext_by_critical(a->extensions, crit, lastpos);
+}
+
+X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc)
+{
+    return X509v3_get_ext(a->extensions, loc);
+}
+
+X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc)
+{
+    return X509v3_delete_ext(a->extensions, loc);
+}
+
+int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc)
+{
+    return X509v3_add_ext(&a->extensions, ex, loc) != NULL;
+}
+
+void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx)
+{
+    return X509V3_get_d2i(a->extensions, nid, crit, idx);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_rsp_print.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_rsp_print.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_rsp_print.c	(revision 331)
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/bn.h>
+#include <openssl/x509v3.h>
+#include <openssl/ts.h>
+#include "ts_lcl.h"
+
+struct status_map_st {
+    int bit;
+    const char *text;
+};
+
+static int ts_status_map_print(BIO *bio, const struct status_map_st *a,
+                               const ASN1_BIT_STRING *v);
+static int ts_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy);
+
+
+int TS_RESP_print_bio(BIO *bio, TS_RESP *a)
+{
+    BIO_printf(bio, "Status info:\n");
+    TS_STATUS_INFO_print_bio(bio, a->status_info);
+
+    BIO_printf(bio, "\nTST info:\n");
+    if (a->tst_info != NULL)
+        TS_TST_INFO_print_bio(bio, a->tst_info);
+    else
+        BIO_printf(bio, "Not included.\n");
+
+    return 1;
+}
+
+int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a)
+{
+    static const char *status_map[] = {
+        "Granted.",
+        "Granted with modifications.",
+        "Rejected.",
+        "Waiting.",
+        "Revocation warning.",
+        "Revoked."
+    };
+    static const struct status_map_st failure_map[] = {
+        {TS_INFO_BAD_ALG,
+         "unrecognized or unsupported algorithm identifier"},
+        {TS_INFO_BAD_REQUEST,
+         "transaction not permitted or supported"},
+        {TS_INFO_BAD_DATA_FORMAT,
+         "the data submitted has the wrong format"},
+        {TS_INFO_TIME_NOT_AVAILABLE,
+         "the TSA's time source is not available"},
+        {TS_INFO_UNACCEPTED_POLICY,
+         "the requested TSA policy is not supported by the TSA"},
+        {TS_INFO_UNACCEPTED_EXTENSION,
+         "the requested extension is not supported by the TSA"},
+        {TS_INFO_ADD_INFO_NOT_AVAILABLE,
+         "the additional information requested could not be understood "
+         "or is not available"},
+        {TS_INFO_SYSTEM_FAILURE,
+         "the request cannot be handled due to system failure"},
+        {-1, NULL}
+    };
+    long status;
+    int i, lines = 0;
+
+    BIO_printf(bio, "Status: ");
+    status = ASN1_INTEGER_get(a->status);
+    if (0 <= status && status < (long)OSSL_NELEM(status_map))
+        BIO_printf(bio, "%s\n", status_map[status]);
+    else
+        BIO_printf(bio, "out of bounds\n");
+
+    BIO_printf(bio, "Status description: ");
+    for (i = 0; i < sk_ASN1_UTF8STRING_num(a->text); ++i) {
+        if (i > 0)
+            BIO_puts(bio, "\t");
+        ASN1_STRING_print_ex(bio, sk_ASN1_UTF8STRING_value(a->text, i), 0);
+        BIO_puts(bio, "\n");
+    }
+    if (i == 0)
+        BIO_printf(bio, "unspecified\n");
+
+    BIO_printf(bio, "Failure info: ");
+    if (a->failure_info != NULL)
+        lines = ts_status_map_print(bio, failure_map, a->failure_info);
+    if (lines == 0)
+        BIO_printf(bio, "unspecified");
+    BIO_printf(bio, "\n");
+
+    return 1;
+}
+
+static int ts_status_map_print(BIO *bio, const struct status_map_st *a,
+                               const ASN1_BIT_STRING *v)
+{
+    int lines = 0;
+
+    for (; a->bit >= 0; ++a) {
+        if (ASN1_BIT_STRING_get_bit(v, a->bit)) {
+            if (++lines > 1)
+                BIO_printf(bio, ", ");
+            BIO_printf(bio, "%s", a->text);
+        }
+    }
+
+    return lines;
+}
+
+int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a)
+{
+    int v;
+
+    if (a == NULL)
+        return 0;
+
+    v = ASN1_INTEGER_get(a->version);
+    BIO_printf(bio, "Version: %d\n", v);
+
+    BIO_printf(bio, "Policy OID: ");
+    TS_OBJ_print_bio(bio, a->policy_id);
+
+    TS_MSG_IMPRINT_print_bio(bio, a->msg_imprint);
+
+    BIO_printf(bio, "Serial number: ");
+    if (a->serial == NULL)
+        BIO_printf(bio, "unspecified");
+    else
+        TS_ASN1_INTEGER_print_bio(bio, a->serial);
+    BIO_write(bio, "\n", 1);
+
+    BIO_printf(bio, "Time stamp: ");
+    ASN1_GENERALIZEDTIME_print(bio, a->time);
+    BIO_write(bio, "\n", 1);
+
+    BIO_printf(bio, "Accuracy: ");
+    if (a->accuracy == NULL)
+        BIO_printf(bio, "unspecified");
+    else
+        ts_ACCURACY_print_bio(bio, a->accuracy);
+    BIO_write(bio, "\n", 1);
+
+    BIO_printf(bio, "Ordering: %s\n", a->ordering ? "yes" : "no");
+
+    BIO_printf(bio, "Nonce: ");
+    if (a->nonce == NULL)
+        BIO_printf(bio, "unspecified");
+    else
+        TS_ASN1_INTEGER_print_bio(bio, a->nonce);
+    BIO_write(bio, "\n", 1);
+
+    BIO_printf(bio, "TSA: ");
+    if (a->tsa == NULL)
+        BIO_printf(bio, "unspecified");
+    else {
+        STACK_OF(CONF_VALUE) *nval;
+        if ((nval = i2v_GENERAL_NAME(NULL, a->tsa, NULL)))
+            X509V3_EXT_val_prn(bio, nval, 0, 0);
+        sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
+    }
+    BIO_write(bio, "\n", 1);
+
+    TS_ext_print_bio(bio, a->extensions);
+
+    return 1;
+}
+
+static int ts_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *a)
+{
+    if (a->seconds != NULL)
+        TS_ASN1_INTEGER_print_bio(bio, a->seconds);
+    else
+        BIO_printf(bio, "unspecified");
+    BIO_printf(bio, " seconds, ");
+    if (a->millis != NULL)
+        TS_ASN1_INTEGER_print_bio(bio, a->millis);
+    else
+        BIO_printf(bio, "unspecified");
+    BIO_printf(bio, " millis, ");
+    if (a->micros != NULL)
+        TS_ASN1_INTEGER_print_bio(bio, a->micros);
+    else
+        BIO_printf(bio, "unspecified");
+    BIO_printf(bio, " micros");
+
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_rsp_sign.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_rsp_sign.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_rsp_sign.c	(revision 331)
@@ -0,0 +1,904 @@
+/*
+ * Copyright 2006-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 "internal/cryptlib.h"
+
+#if defined(OPENSSL_SYS_UNIX)
+# include <sys/time.h>
+#endif
+
+#include <openssl/objects.h>
+#include <openssl/ts.h>
+#include <openssl/pkcs7.h>
+#include "ts_lcl.h"
+
+static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *);
+static int def_time_cb(struct TS_resp_ctx *, void *, long *sec, long *usec);
+static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *);
+
+static void ts_RESP_CTX_init(TS_RESP_CTX *ctx);
+static void ts_RESP_CTX_cleanup(TS_RESP_CTX *ctx);
+static int ts_RESP_check_request(TS_RESP_CTX *ctx);
+static ASN1_OBJECT *ts_RESP_get_policy(TS_RESP_CTX *ctx);
+static TS_TST_INFO *ts_RESP_create_tst_info(TS_RESP_CTX *ctx,
+                                            ASN1_OBJECT *policy);
+static int ts_RESP_process_extensions(TS_RESP_CTX *ctx);
+static int ts_RESP_sign(TS_RESP_CTX *ctx);
+
+static ESS_SIGNING_CERT *ess_SIGNING_CERT_new_init(X509 *signcert,
+                                                   STACK_OF(X509) *certs);
+static ESS_CERT_ID *ess_CERT_ID_new_init(X509 *cert, int issuer_needed);
+static int ts_TST_INFO_content_new(PKCS7 *p7);
+static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc);
+
+static ASN1_GENERALIZEDTIME
+*TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *, long, long,
+                                    unsigned);
+
+/* Default callback for response generation. */
+static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data)
+{
+    ASN1_INTEGER *serial = ASN1_INTEGER_new();
+
+    if (serial == NULL)
+        goto err;
+    if (!ASN1_INTEGER_set(serial, 1))
+        goto err;
+    return serial;
+
+ err:
+    TSerr(TS_F_DEF_SERIAL_CB, ERR_R_MALLOC_FAILURE);
+    TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+                                "Error during serial number generation.");
+    return NULL;
+}
+
+#if defined(OPENSSL_SYS_UNIX)
+
+static int def_time_cb(struct TS_resp_ctx *ctx, void *data,
+                       long *sec, long *usec)
+{
+    struct timeval tv;
+    if (gettimeofday(&tv, NULL) != 0) {
+        TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR);
+        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+                                    "Time is not available.");
+        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
+        return 0;
+    }
+    *sec = tv.tv_sec;
+    *usec = tv.tv_usec;
+
+    return 1;
+}
+
+#else
+
+static int def_time_cb(struct TS_resp_ctx *ctx, void *data,
+                       long *sec, long *usec)
+{
+    time_t t;
+    if (time(&t) == (time_t)-1) {
+        TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR);
+        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+                                    "Time is not available.");
+        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE);
+        return 0;
+    }
+    *sec = (long)t;
+    *usec = 0;
+
+    return 1;
+}
+
+#endif
+
+static int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext,
+                            void *data)
+{
+    TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+                                "Unsupported extension.");
+    TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION);
+    return 0;
+}
+
+/* TS_RESP_CTX management functions. */
+
+TS_RESP_CTX *TS_RESP_CTX_new()
+{
+    TS_RESP_CTX *ctx;
+
+    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
+        TSerr(TS_F_TS_RESP_CTX_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    ctx->signer_md = EVP_sha256();
+
+    ctx->serial_cb = def_serial_cb;
+    ctx->time_cb = def_time_cb;
+    ctx->extension_cb = def_extension_cb;
+
+    return ctx;
+}
+
+void TS_RESP_CTX_free(TS_RESP_CTX *ctx)
+{
+    if (!ctx)
+        return;
+
+    X509_free(ctx->signer_cert);
+    EVP_PKEY_free(ctx->signer_key);
+    sk_X509_pop_free(ctx->certs, X509_free);
+    sk_ASN1_OBJECT_pop_free(ctx->policies, ASN1_OBJECT_free);
+    ASN1_OBJECT_free(ctx->default_policy);
+    sk_EVP_MD_free(ctx->mds);   /* No EVP_MD_free method exists. */
+    ASN1_INTEGER_free(ctx->seconds);
+    ASN1_INTEGER_free(ctx->millis);
+    ASN1_INTEGER_free(ctx->micros);
+    OPENSSL_free(ctx);
+}
+
+int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer)
+{
+    if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1) {
+        TSerr(TS_F_TS_RESP_CTX_SET_SIGNER_CERT,
+              TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE);
+        return 0;
+    }
+    X509_free(ctx->signer_cert);
+    ctx->signer_cert = signer;
+    X509_up_ref(ctx->signer_cert);
+    return 1;
+}
+
+int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key)
+{
+    EVP_PKEY_free(ctx->signer_key);
+    ctx->signer_key = key;
+    EVP_PKEY_up_ref(ctx->signer_key);
+
+    return 1;
+}
+
+int TS_RESP_CTX_set_signer_digest(TS_RESP_CTX *ctx, const EVP_MD *md)
+{
+    ctx->signer_md = md;
+    return 1;
+}
+
+int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *def_policy)
+{
+    ASN1_OBJECT_free(ctx->default_policy);
+    if ((ctx->default_policy = OBJ_dup(def_policy)) == NULL)
+        goto err;
+    return 1;
+ err:
+    TSerr(TS_F_TS_RESP_CTX_SET_DEF_POLICY, ERR_R_MALLOC_FAILURE);
+    return 0;
+}
+
+int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs)
+{
+
+    sk_X509_pop_free(ctx->certs, X509_free);
+    ctx->certs = NULL;
+    if (!certs)
+        return 1;
+    if ((ctx->certs = X509_chain_up_ref(certs)) == NULL) {
+        TSerr(TS_F_TS_RESP_CTX_SET_CERTS, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    return 1;
+}
+
+int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *policy)
+{
+    ASN1_OBJECT *copy = NULL;
+
+    if (ctx->policies == NULL
+        && (ctx->policies = sk_ASN1_OBJECT_new_null()) == NULL)
+        goto err;
+    if ((copy = OBJ_dup(policy)) == NULL)
+        goto err;
+    if (!sk_ASN1_OBJECT_push(ctx->policies, copy))
+        goto err;
+
+    return 1;
+ err:
+    TSerr(TS_F_TS_RESP_CTX_ADD_POLICY, ERR_R_MALLOC_FAILURE);
+    ASN1_OBJECT_free(copy);
+    return 0;
+}
+
+int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md)
+{
+    if (ctx->mds == NULL
+        && (ctx->mds = sk_EVP_MD_new_null()) == NULL)
+        goto err;
+    if (!sk_EVP_MD_push(ctx->mds, md))
+        goto err;
+
+    return 1;
+ err:
+    TSerr(TS_F_TS_RESP_CTX_ADD_MD, ERR_R_MALLOC_FAILURE);
+    return 0;
+}
+
+#define TS_RESP_CTX_accuracy_free(ctx)          \
+        ASN1_INTEGER_free(ctx->seconds);        \
+        ctx->seconds = NULL;                    \
+        ASN1_INTEGER_free(ctx->millis);         \
+        ctx->millis = NULL;                     \
+        ASN1_INTEGER_free(ctx->micros);         \
+        ctx->micros = NULL;
+
+int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx,
+                             int secs, int millis, int micros)
+{
+
+    TS_RESP_CTX_accuracy_free(ctx);
+    if (secs
+        && ((ctx->seconds = ASN1_INTEGER_new()) == NULL
+            || !ASN1_INTEGER_set(ctx->seconds, secs)))
+        goto err;
+    if (millis
+        && ((ctx->millis = ASN1_INTEGER_new()) == NULL
+            || !ASN1_INTEGER_set(ctx->millis, millis)))
+        goto err;
+    if (micros
+        && ((ctx->micros = ASN1_INTEGER_new()) == NULL
+            || !ASN1_INTEGER_set(ctx->micros, micros)))
+        goto err;
+
+    return 1;
+ err:
+    TS_RESP_CTX_accuracy_free(ctx);
+    TSerr(TS_F_TS_RESP_CTX_SET_ACCURACY, ERR_R_MALLOC_FAILURE);
+    return 0;
+}
+
+void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags)
+{
+    ctx->flags |= flags;
+}
+
+void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data)
+{
+    ctx->serial_cb = cb;
+    ctx->serial_cb_data = data;
+}
+
+void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data)
+{
+    ctx->time_cb = cb;
+    ctx->time_cb_data = data;
+}
+
+void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx,
+                                  TS_extension_cb cb, void *data)
+{
+    ctx->extension_cb = cb;
+    ctx->extension_cb_data = data;
+}
+
+int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx,
+                                int status, const char *text)
+{
+    TS_STATUS_INFO *si = NULL;
+    ASN1_UTF8STRING *utf8_text = NULL;
+    int ret = 0;
+
+    if ((si = TS_STATUS_INFO_new()) == NULL)
+        goto err;
+    if (!ASN1_INTEGER_set(si->status, status))
+        goto err;
+    if (text) {
+        if ((utf8_text = ASN1_UTF8STRING_new()) == NULL
+            || !ASN1_STRING_set(utf8_text, text, strlen(text)))
+            goto err;
+        if (si->text == NULL
+            && (si->text = sk_ASN1_UTF8STRING_new_null()) == NULL)
+            goto err;
+        if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text))
+            goto err;
+        utf8_text = NULL;       /* Ownership is lost. */
+    }
+    if (!TS_RESP_set_status_info(ctx->response, si))
+        goto err;
+    ret = 1;
+ err:
+    if (!ret)
+        TSerr(TS_F_TS_RESP_CTX_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE);
+    TS_STATUS_INFO_free(si);
+    ASN1_UTF8STRING_free(utf8_text);
+    return ret;
+}
+
+int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx,
+                                     int status, const char *text)
+{
+    int ret = 1;
+    TS_STATUS_INFO *si = ctx->response->status_info;
+
+    if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED) {
+        ret = TS_RESP_CTX_set_status_info(ctx, status, text);
+    }
+    return ret;
+}
+
+int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure)
+{
+    TS_STATUS_INFO *si = ctx->response->status_info;
+    if (si->failure_info == NULL
+        && (si->failure_info = ASN1_BIT_STRING_new()) == NULL)
+        goto err;
+    if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1))
+        goto err;
+    return 1;
+ err:
+    TSerr(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO, ERR_R_MALLOC_FAILURE);
+    return 0;
+}
+
+TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx)
+{
+    return ctx->request;
+}
+
+TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx)
+{
+    return ctx->tst_info;
+}
+
+int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx,
+                                           unsigned precision)
+{
+    if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
+        return 0;
+    ctx->clock_precision_digits = precision;
+    return 1;
+}
+
+/* Main entry method of the response generation. */
+TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio)
+{
+    ASN1_OBJECT *policy;
+    TS_RESP *response;
+    int result = 0;
+
+    ts_RESP_CTX_init(ctx);
+
+    if ((ctx->response = TS_RESP_new()) == NULL) {
+        TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE);
+        goto end;
+    }
+    if ((ctx->request = d2i_TS_REQ_bio(req_bio, NULL)) == NULL) {
+        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+                                    "Bad request format or system error.");
+        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
+        goto end;
+    }
+    if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL))
+        goto end;
+    if (!ts_RESP_check_request(ctx))
+        goto end;
+    if ((policy = ts_RESP_get_policy(ctx)) == NULL)
+        goto end;
+    if ((ctx->tst_info = ts_RESP_create_tst_info(ctx, policy)) == NULL)
+        goto end;
+    if (!ts_RESP_process_extensions(ctx))
+        goto end;
+    if (!ts_RESP_sign(ctx))
+        goto end;
+    result = 1;
+
+ end:
+    if (!result) {
+        TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR);
+        if (ctx->response != NULL) {
+            if (TS_RESP_CTX_set_status_info_cond(ctx,
+                                                 TS_STATUS_REJECTION,
+                                                 "Error during response "
+                                                 "generation.") == 0) {
+                TS_RESP_free(ctx->response);
+                ctx->response = NULL;
+            }
+        }
+    }
+    response = ctx->response;
+    ctx->response = NULL;       /* Ownership will be returned to caller. */
+    ts_RESP_CTX_cleanup(ctx);
+    return response;
+}
+
+/* Initializes the variable part of the context. */
+static void ts_RESP_CTX_init(TS_RESP_CTX *ctx)
+{
+    ctx->request = NULL;
+    ctx->response = NULL;
+    ctx->tst_info = NULL;
+}
+
+/* Cleans up the variable part of the context. */
+static void ts_RESP_CTX_cleanup(TS_RESP_CTX *ctx)
+{
+    TS_REQ_free(ctx->request);
+    ctx->request = NULL;
+    TS_RESP_free(ctx->response);
+    ctx->response = NULL;
+    TS_TST_INFO_free(ctx->tst_info);
+    ctx->tst_info = NULL;
+}
+
+/* Checks the format and content of the request. */
+static int ts_RESP_check_request(TS_RESP_CTX *ctx)
+{
+    TS_REQ *request = ctx->request;
+    TS_MSG_IMPRINT *msg_imprint;
+    X509_ALGOR *md_alg;
+    int md_alg_id;
+    const ASN1_OCTET_STRING *digest;
+    const EVP_MD *md = NULL;
+    int i;
+
+    if (TS_REQ_get_version(request) != 1) {
+        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+                                    "Bad request version.");
+        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_REQUEST);
+        return 0;
+    }
+
+    msg_imprint = request->msg_imprint;
+    md_alg = msg_imprint->hash_algo;
+    md_alg_id = OBJ_obj2nid(md_alg->algorithm);
+    for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i) {
+        const EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i);
+        if (md_alg_id == EVP_MD_type(current_md))
+            md = current_md;
+    }
+    if (!md) {
+        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+                                    "Message digest algorithm is "
+                                    "not supported.");
+        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
+        return 0;
+    }
+
+    if (md_alg->parameter && ASN1_TYPE_get(md_alg->parameter) != V_ASN1_NULL) {
+        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+                                    "Superfluous message digest "
+                                    "parameter.");
+        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG);
+        return 0;
+    }
+    digest = msg_imprint->hashed_msg;
+    if (digest->length != EVP_MD_size(md)) {
+        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+                                    "Bad message digest.");
+        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT);
+        return 0;
+    }
+
+    return 1;
+}
+
+/* Returns the TSA policy based on the requested and acceptable policies. */
+static ASN1_OBJECT *ts_RESP_get_policy(TS_RESP_CTX *ctx)
+{
+    ASN1_OBJECT *requested = ctx->request->policy_id;
+    ASN1_OBJECT *policy = NULL;
+    int i;
+
+    if (ctx->default_policy == NULL) {
+        TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_INVALID_NULL_POINTER);
+        return NULL;
+    }
+    if (!requested || !OBJ_cmp(requested, ctx->default_policy))
+        policy = ctx->default_policy;
+
+    /* Check if the policy is acceptable. */
+    for (i = 0; !policy && i < sk_ASN1_OBJECT_num(ctx->policies); ++i) {
+        ASN1_OBJECT *current = sk_ASN1_OBJECT_value(ctx->policies, i);
+        if (!OBJ_cmp(requested, current))
+            policy = current;
+    }
+    if (!policy) {
+        TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_UNACCEPTABLE_POLICY);
+        TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+                                    "Requested policy is not " "supported.");
+        TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY);
+    }
+    return policy;
+}
+
+/* Creates the TS_TST_INFO object based on the settings of the context. */
+static TS_TST_INFO *ts_RESP_create_tst_info(TS_RESP_CTX *ctx,
+                                            ASN1_OBJECT *policy)
+{
+    int result = 0;
+    TS_TST_INFO *tst_info = NULL;
+    ASN1_INTEGER *serial = NULL;
+    ASN1_GENERALIZEDTIME *asn1_time = NULL;
+    long sec, usec;
+    TS_ACCURACY *accuracy = NULL;
+    const ASN1_INTEGER *nonce;
+    GENERAL_NAME *tsa_name = NULL;
+
+    if ((tst_info = TS_TST_INFO_new()) == NULL)
+        goto end;
+    if (!TS_TST_INFO_set_version(tst_info, 1))
+        goto end;
+    if (!TS_TST_INFO_set_policy_id(tst_info, policy))
+        goto end;
+    if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint))
+        goto end;
+    if ((serial = ctx->serial_cb(ctx, ctx->serial_cb_data)) == NULL
+        || !TS_TST_INFO_set_serial(tst_info, serial))
+        goto end;
+    if (!ctx->time_cb(ctx, ctx->time_cb_data, &sec, &usec)
+        || (asn1_time =
+            TS_RESP_set_genTime_with_precision(NULL, sec, usec,
+                                        ctx->clock_precision_digits)) == NULL
+        || !TS_TST_INFO_set_time(tst_info, asn1_time))
+        goto end;
+
+    if ((ctx->seconds || ctx->millis || ctx->micros)
+        && (accuracy = TS_ACCURACY_new()) == NULL)
+        goto end;
+    if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds))
+        goto end;
+    if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis))
+        goto end;
+    if (ctx->micros && !TS_ACCURACY_set_micros(accuracy, ctx->micros))
+        goto end;
+    if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy))
+        goto end;
+
+    if ((ctx->flags & TS_ORDERING)
+        && !TS_TST_INFO_set_ordering(tst_info, 1))
+        goto end;
+
+    if ((nonce = ctx->request->nonce) != NULL
+        && !TS_TST_INFO_set_nonce(tst_info, nonce))
+        goto end;
+
+    if (ctx->flags & TS_TSA_NAME) {
+        if ((tsa_name = GENERAL_NAME_new()) == NULL)
+            goto end;
+        tsa_name->type = GEN_DIRNAME;
+        tsa_name->d.dirn =
+            X509_NAME_dup(X509_get_subject_name(ctx->signer_cert));
+        if (!tsa_name->d.dirn)
+            goto end;
+        if (!TS_TST_INFO_set_tsa(tst_info, tsa_name))
+            goto end;
+    }
+
+    result = 1;
+ end:
+    if (!result) {
+        TS_TST_INFO_free(tst_info);
+        tst_info = NULL;
+        TSerr(TS_F_TS_RESP_CREATE_TST_INFO, TS_R_TST_INFO_SETUP_ERROR);
+        TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
+                                         "Error during TSTInfo "
+                                         "generation.");
+    }
+    GENERAL_NAME_free(tsa_name);
+    TS_ACCURACY_free(accuracy);
+    ASN1_GENERALIZEDTIME_free(asn1_time);
+    ASN1_INTEGER_free(serial);
+
+    return tst_info;
+}
+
+/* Processing the extensions of the request. */
+static int ts_RESP_process_extensions(TS_RESP_CTX *ctx)
+{
+    STACK_OF(X509_EXTENSION) *exts = ctx->request->extensions;
+    int i;
+    int ok = 1;
+
+    for (i = 0; ok && i < sk_X509_EXTENSION_num(exts); ++i) {
+        X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
+        /*
+         * The last argument was previously (void *)ctx->extension_cb,
+         * but ISO C doesn't permit converting a function pointer to void *.
+         * For lack of better information, I'm placing a NULL there instead.
+         * The callback can pick its own address out from the ctx anyway...
+         */
+        ok = (*ctx->extension_cb) (ctx, ext, NULL);
+    }
+
+    return ok;
+}
+
+/* Functions for signing the TS_TST_INFO structure of the context. */
+static int ts_RESP_sign(TS_RESP_CTX *ctx)
+{
+    int ret = 0;
+    PKCS7 *p7 = NULL;
+    PKCS7_SIGNER_INFO *si;
+    STACK_OF(X509) *certs;      /* Certificates to include in sc. */
+    ESS_SIGNING_CERT *sc = NULL;
+    ASN1_OBJECT *oid;
+    BIO *p7bio = NULL;
+    int i;
+
+    if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) {
+        TSerr(TS_F_TS_RESP_SIGN, TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+        goto err;
+    }
+
+    if ((p7 = PKCS7_new()) == NULL) {
+        TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if (!PKCS7_set_type(p7, NID_pkcs7_signed))
+        goto err;
+    if (!ASN1_INTEGER_set(p7->d.sign->version, 3))
+        goto err;
+
+    if (ctx->request->cert_req) {
+        PKCS7_add_certificate(p7, ctx->signer_cert);
+        if (ctx->certs) {
+            for (i = 0; i < sk_X509_num(ctx->certs); ++i) {
+                X509 *cert = sk_X509_value(ctx->certs, i);
+                PKCS7_add_certificate(p7, cert);
+            }
+        }
+    }
+
+    if ((si = PKCS7_add_signature(p7, ctx->signer_cert,
+                                  ctx->signer_key, ctx->signer_md)) == NULL) {
+        TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNATURE_ERROR);
+        goto err;
+    }
+
+    oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
+    if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
+                                    V_ASN1_OBJECT, oid)) {
+        TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR);
+        goto err;
+    }
+
+    certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL;
+    if ((sc = ess_SIGNING_CERT_new_init(ctx->signer_cert, certs)) == NULL)
+        goto err;
+    if (!ESS_add_signing_cert(si, sc)) {
+        TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR);
+        goto err;
+    }
+
+    if (!ts_TST_INFO_content_new(p7))
+        goto err;
+    if ((p7bio = PKCS7_dataInit(p7, NULL)) == NULL) {
+        TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info)) {
+        TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
+        goto err;
+    }
+    if (!PKCS7_dataFinal(p7, p7bio)) {
+        TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN);
+        goto err;
+    }
+    TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info);
+    p7 = NULL;                  /* Ownership is lost. */
+    ctx->tst_info = NULL;       /* Ownership is lost. */
+
+    ret = 1;
+ err:
+    if (!ret)
+        TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION,
+                                         "Error during signature "
+                                         "generation.");
+    BIO_free_all(p7bio);
+    ESS_SIGNING_CERT_free(sc);
+    PKCS7_free(p7);
+    return ret;
+}
+
+static ESS_SIGNING_CERT *ess_SIGNING_CERT_new_init(X509 *signcert,
+                                                   STACK_OF(X509) *certs)
+{
+    ESS_CERT_ID *cid;
+    ESS_SIGNING_CERT *sc = NULL;
+    int i;
+
+    if ((sc = ESS_SIGNING_CERT_new()) == NULL)
+        goto err;
+    if (sc->cert_ids == NULL
+        && (sc->cert_ids = sk_ESS_CERT_ID_new_null()) == NULL)
+        goto err;
+
+    if ((cid = ess_CERT_ID_new_init(signcert, 0)) == NULL
+        || !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
+        goto err;
+    for (i = 0; i < sk_X509_num(certs); ++i) {
+        X509 *cert = sk_X509_value(certs, i);
+        if ((cid = ess_CERT_ID_new_init(cert, 1)) == NULL
+            || !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
+            goto err;
+    }
+
+    return sc;
+ err:
+    ESS_SIGNING_CERT_free(sc);
+    TSerr(TS_F_ESS_SIGNING_CERT_NEW_INIT, ERR_R_MALLOC_FAILURE);
+    return NULL;
+}
+
+static ESS_CERT_ID *ess_CERT_ID_new_init(X509 *cert, int issuer_needed)
+{
+    ESS_CERT_ID *cid = NULL;
+    GENERAL_NAME *name = NULL;
+    unsigned char cert_sha1[SHA_DIGEST_LENGTH];
+
+    /* Call for side-effect of computing hash and caching extensions */
+    X509_check_purpose(cert, -1, 0);
+    if ((cid = ESS_CERT_ID_new()) == NULL)
+        goto err;
+    X509_digest(cert, EVP_sha1(), cert_sha1, NULL);
+    if (!ASN1_OCTET_STRING_set(cid->hash, cert_sha1, SHA_DIGEST_LENGTH))
+        goto err;
+
+    /* Setting the issuer/serial if requested. */
+    if (issuer_needed) {
+        if (cid->issuer_serial == NULL
+            && (cid->issuer_serial = ESS_ISSUER_SERIAL_new()) == NULL)
+            goto err;
+        if ((name = GENERAL_NAME_new()) == NULL)
+            goto err;
+        name->type = GEN_DIRNAME;
+        if ((name->d.dirn = X509_NAME_dup(X509_get_issuer_name(cert))) == NULL)
+            goto err;
+        if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name))
+            goto err;
+        name = NULL;            /* Ownership is lost. */
+        ASN1_INTEGER_free(cid->issuer_serial->serial);
+        if (!(cid->issuer_serial->serial =
+              ASN1_INTEGER_dup(X509_get_serialNumber(cert))))
+            goto err;
+    }
+
+    return cid;
+ err:
+    GENERAL_NAME_free(name);
+    ESS_CERT_ID_free(cid);
+    TSerr(TS_F_ESS_CERT_ID_NEW_INIT, ERR_R_MALLOC_FAILURE);
+    return NULL;
+}
+
+static int ts_TST_INFO_content_new(PKCS7 *p7)
+{
+    PKCS7 *ret = NULL;
+    ASN1_OCTET_STRING *octet_string = NULL;
+
+    /* Create new encapsulated NID_id_smime_ct_TSTInfo content. */
+    if ((ret = PKCS7_new()) == NULL)
+        goto err;
+    if ((ret->d.other = ASN1_TYPE_new()) == NULL)
+        goto err;
+    ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo);
+    if ((octet_string = ASN1_OCTET_STRING_new()) == NULL)
+        goto err;
+    ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string);
+    octet_string = NULL;
+
+    /* Add encapsulated content to signed PKCS7 structure. */
+    if (!PKCS7_set_content(p7, ret))
+        goto err;
+
+    return 1;
+ err:
+    ASN1_OCTET_STRING_free(octet_string);
+    PKCS7_free(ret);
+    return 0;
+}
+
+static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc)
+{
+    ASN1_STRING *seq = NULL;
+    unsigned char *p, *pp = NULL;
+    int len;
+
+    len = i2d_ESS_SIGNING_CERT(sc, NULL);
+    if ((pp = OPENSSL_malloc(len)) == NULL) {
+        TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    p = pp;
+    i2d_ESS_SIGNING_CERT(sc, &p);
+    if ((seq = ASN1_STRING_new()) == NULL || !ASN1_STRING_set(seq, pp, len)) {
+        TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    OPENSSL_free(pp);
+    pp = NULL;
+    return PKCS7_add_signed_attribute(si,
+                                      NID_id_smime_aa_signingCertificate,
+                                      V_ASN1_SEQUENCE, seq);
+ err:
+    ASN1_STRING_free(seq);
+    OPENSSL_free(pp);
+
+    return 0;
+}
+
+static ASN1_GENERALIZEDTIME
+*TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time,
+                                    long sec, long usec, unsigned precision)
+{
+    time_t time_sec = (time_t)sec;
+    struct tm *tm = NULL;
+    char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS];
+    char *p = genTime_str;
+    char *p_end = genTime_str + sizeof(genTime_str);
+
+    if (precision > TS_MAX_CLOCK_PRECISION_DIGITS)
+        goto err;
+
+    if ((tm = gmtime(&time_sec)) == NULL)
+        goto err;
+
+    /*
+     * Put "genTime_str" in GeneralizedTime format.  We work around the
+     * restrictions imposed by rfc3280 (i.e. "GeneralizedTime values MUST
+     * NOT include fractional seconds") and OpenSSL related functions to
+     * meet the rfc3161 requirement: "GeneralizedTime syntax can include
+     * fraction-of-second details".
+     */
+    p += BIO_snprintf(p, p_end - p,
+                      "%04d%02d%02d%02d%02d%02d",
+                      tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+                      tm->tm_hour, tm->tm_min, tm->tm_sec);
+    if (precision > 0) {
+        BIO_snprintf(p, 2 + precision, ".%06ld", usec);
+        p += strlen(p);
+
+        /*
+         * To make things a bit harder, X.690 | ISO/IEC 8825-1 provides the
+         * following restrictions for a DER-encoding, which OpenSSL
+         * (specifically ASN1_GENERALIZEDTIME_check() function) doesn't
+         * support: "The encoding MUST terminate with a "Z" (which means
+         * "Zulu" time). The decimal point element, if present, MUST be the
+         * point option ".". The fractional-seconds elements, if present,
+         * MUST omit all trailing 0's; if the elements correspond to 0, they
+         * MUST be wholly omitted, and the decimal point element also MUST be
+         * omitted."
+         */
+        /*
+         * Remove trailing zeros. The dot guarantees the exit condition of
+         * this loop even if all the digits are zero.
+         */
+        while (*--p == '0')
+             continue;
+        if (*p != '.')
+            ++p;
+    }
+    *p++ = 'Z';
+    *p++ = '\0';
+
+    if (asn1_time == NULL
+        && (asn1_time = ASN1_GENERALIZEDTIME_new()) == NULL)
+        goto err;
+    if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str)) {
+        ASN1_GENERALIZEDTIME_free(asn1_time);
+        goto err;
+    }
+    return asn1_time;
+
+ err:
+    TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, TS_R_COULD_NOT_SET_TIME);
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_rsp_utils.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_rsp_utils.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_rsp_utils.c	(revision 331)
@@ -0,0 +1,365 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/ts.h>
+#include <openssl/pkcs7.h>
+#include "ts_lcl.h"
+
+int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *status_info)
+{
+    TS_STATUS_INFO *new_status_info;
+
+    if (a->status_info == status_info)
+        return 1;
+    new_status_info = TS_STATUS_INFO_dup(status_info);
+    if (new_status_info == NULL) {
+        TSerr(TS_F_TS_RESP_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    TS_STATUS_INFO_free(a->status_info);
+    a->status_info = new_status_info;
+
+    return 1;
+}
+
+TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a)
+{
+    return a->status_info;
+}
+
+/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */
+void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info)
+{
+    PKCS7_free(a->token);
+    a->token = p7;
+    TS_TST_INFO_free(a->tst_info);
+    a->tst_info = tst_info;
+}
+
+PKCS7 *TS_RESP_get_token(TS_RESP *a)
+{
+    return a->token;
+}
+
+TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a)
+{
+    return a->tst_info;
+}
+
+int TS_TST_INFO_set_version(TS_TST_INFO *a, long version)
+{
+    return ASN1_INTEGER_set(a->version, version);
+}
+
+long TS_TST_INFO_get_version(const TS_TST_INFO *a)
+{
+    return ASN1_INTEGER_get(a->version);
+}
+
+int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy)
+{
+    ASN1_OBJECT *new_policy;
+
+    if (a->policy_id == policy)
+        return 1;
+    new_policy = OBJ_dup(policy);
+    if (new_policy == NULL) {
+        TSerr(TS_F_TS_TST_INFO_SET_POLICY_ID, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    ASN1_OBJECT_free(a->policy_id);
+    a->policy_id = new_policy;
+    return 1;
+}
+
+ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a)
+{
+    return a->policy_id;
+}
+
+int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint)
+{
+    TS_MSG_IMPRINT *new_msg_imprint;
+
+    if (a->msg_imprint == msg_imprint)
+        return 1;
+    new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint);
+    if (new_msg_imprint == NULL) {
+        TSerr(TS_F_TS_TST_INFO_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    TS_MSG_IMPRINT_free(a->msg_imprint);
+    a->msg_imprint = new_msg_imprint;
+    return 1;
+}
+
+TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a)
+{
+    return a->msg_imprint;
+}
+
+int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial)
+{
+    ASN1_INTEGER *new_serial;
+
+    if (a->serial == serial)
+        return 1;
+    new_serial = ASN1_INTEGER_dup(serial);
+    if (new_serial == NULL) {
+        TSerr(TS_F_TS_TST_INFO_SET_SERIAL, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    ASN1_INTEGER_free(a->serial);
+    a->serial = new_serial;
+    return 1;
+}
+
+const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a)
+{
+    return a->serial;
+}
+
+int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime)
+{
+    ASN1_GENERALIZEDTIME *new_time;
+
+    if (a->time == gtime)
+        return 1;
+    new_time = ASN1_STRING_dup(gtime);
+    if (new_time == NULL) {
+        TSerr(TS_F_TS_TST_INFO_SET_TIME, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    ASN1_GENERALIZEDTIME_free(a->time);
+    a->time = new_time;
+    return 1;
+}
+
+const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a)
+{
+    return a->time;
+}
+
+int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy)
+{
+    TS_ACCURACY *new_accuracy;
+
+    if (a->accuracy == accuracy)
+        return 1;
+    new_accuracy = TS_ACCURACY_dup(accuracy);
+    if (new_accuracy == NULL) {
+        TSerr(TS_F_TS_TST_INFO_SET_ACCURACY, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    TS_ACCURACY_free(a->accuracy);
+    a->accuracy = new_accuracy;
+    return 1;
+}
+
+TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a)
+{
+    return a->accuracy;
+}
+
+int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds)
+{
+    ASN1_INTEGER *new_seconds;
+
+    if (a->seconds == seconds)
+        return 1;
+    new_seconds = ASN1_INTEGER_dup(seconds);
+    if (new_seconds == NULL) {
+        TSerr(TS_F_TS_ACCURACY_SET_SECONDS, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    ASN1_INTEGER_free(a->seconds);
+    a->seconds = new_seconds;
+    return 1;
+}
+
+const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a)
+{
+    return a->seconds;
+}
+
+int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis)
+{
+    ASN1_INTEGER *new_millis = NULL;
+
+    if (a->millis == millis)
+        return 1;
+    if (millis != NULL) {
+        new_millis = ASN1_INTEGER_dup(millis);
+        if (new_millis == NULL) {
+            TSerr(TS_F_TS_ACCURACY_SET_MILLIS, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+    }
+    ASN1_INTEGER_free(a->millis);
+    a->millis = new_millis;
+    return 1;
+}
+
+const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a)
+{
+    return a->millis;
+}
+
+int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros)
+{
+    ASN1_INTEGER *new_micros = NULL;
+
+    if (a->micros == micros)
+        return 1;
+    if (micros != NULL) {
+        new_micros = ASN1_INTEGER_dup(micros);
+        if (new_micros == NULL) {
+            TSerr(TS_F_TS_ACCURACY_SET_MICROS, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+    }
+    ASN1_INTEGER_free(a->micros);
+    a->micros = new_micros;
+    return 1;
+}
+
+const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a)
+{
+    return a->micros;
+}
+
+int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering)
+{
+    a->ordering = ordering ? 0xFF : 0x00;
+    return 1;
+}
+
+int TS_TST_INFO_get_ordering(const TS_TST_INFO *a)
+{
+    return a->ordering ? 1 : 0;
+}
+
+int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce)
+{
+    ASN1_INTEGER *new_nonce;
+
+    if (a->nonce == nonce)
+        return 1;
+    new_nonce = ASN1_INTEGER_dup(nonce);
+    if (new_nonce == NULL) {
+        TSerr(TS_F_TS_TST_INFO_SET_NONCE, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    ASN1_INTEGER_free(a->nonce);
+    a->nonce = new_nonce;
+    return 1;
+}
+
+const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a)
+{
+    return a->nonce;
+}
+
+int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa)
+{
+    GENERAL_NAME *new_tsa;
+
+    if (a->tsa == tsa)
+        return 1;
+    new_tsa = GENERAL_NAME_dup(tsa);
+    if (new_tsa == NULL) {
+        TSerr(TS_F_TS_TST_INFO_SET_TSA, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    GENERAL_NAME_free(a->tsa);
+    a->tsa = new_tsa;
+    return 1;
+}
+
+GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a)
+{
+    return a->tsa;
+}
+
+STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a)
+{
+    return a->extensions;
+}
+
+void TS_TST_INFO_ext_free(TS_TST_INFO *a)
+{
+    if (!a)
+        return;
+    sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free);
+    a->extensions = NULL;
+}
+
+int TS_TST_INFO_get_ext_count(TS_TST_INFO *a)
+{
+    return X509v3_get_ext_count(a->extensions);
+}
+
+int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos)
+{
+    return X509v3_get_ext_by_NID(a->extensions, nid, lastpos);
+}
+
+int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, const ASN1_OBJECT *obj, int lastpos)
+{
+    return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos);
+}
+
+int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos)
+{
+    return X509v3_get_ext_by_critical(a->extensions, crit, lastpos);
+}
+
+X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc)
+{
+    return X509v3_get_ext(a->extensions, loc);
+}
+
+X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc)
+{
+    return X509v3_delete_ext(a->extensions, loc);
+}
+
+int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc)
+{
+    return X509v3_add_ext(&a->extensions, ex, loc) != NULL;
+}
+
+void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx)
+{
+    return X509V3_get_d2i(a->extensions, nid, crit, idx);
+}
+
+int TS_STATUS_INFO_set_status(TS_STATUS_INFO *a, int i)
+{
+    return ASN1_INTEGER_set(a->status, i);
+}
+
+const ASN1_INTEGER *TS_STATUS_INFO_get0_status(const TS_STATUS_INFO *a)
+{
+    return a->status;
+}
+
+const STACK_OF(ASN1_UTF8STRING) *
+TS_STATUS_INFO_get0_text(const TS_STATUS_INFO *a)
+{
+    return a->text;
+}
+
+const ASN1_BIT_STRING *TS_STATUS_INFO_get0_failure_info(const TS_STATUS_INFO *a)
+{
+    return a->failure_info;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_rsp_verify.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_rsp_verify.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_rsp_verify.c	(revision 331)
@@ -0,0 +1,635 @@
+/*
+ * Copyright 2006-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/ts.h>
+#include <openssl/pkcs7.h>
+#include "ts_lcl.h"
+
+static int ts_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
+                          X509 *signer, STACK_OF(X509) **chain);
+static int ts_check_signing_certs(PKCS7_SIGNER_INFO *si,
+                                  STACK_OF(X509) *chain);
+static ESS_SIGNING_CERT *ess_get_signing_cert(PKCS7_SIGNER_INFO *si);
+static int ts_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert);
+static int ts_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509 *cert);
+static int int_ts_RESP_verify_token(TS_VERIFY_CTX *ctx,
+                                    PKCS7 *token, TS_TST_INFO *tst_info);
+static int ts_check_status_info(TS_RESP *response);
+static char *ts_get_status_text(STACK_OF(ASN1_UTF8STRING) *text);
+static int ts_check_policy(const ASN1_OBJECT *req_oid,
+                           const TS_TST_INFO *tst_info);
+static int ts_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
+                              X509_ALGOR **md_alg,
+                              unsigned char **imprint, unsigned *imprint_len);
+static int ts_check_imprints(X509_ALGOR *algor_a,
+                             const unsigned char *imprint_a, unsigned len_a,
+                             TS_TST_INFO *tst_info);
+static int ts_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info);
+static int ts_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer);
+static int ts_find_name(STACK_OF(GENERAL_NAME) *gen_names,
+                        GENERAL_NAME *name);
+
+/*
+ * This must be large enough to hold all values in ts_status_text (with
+ * comma separator) or all text fields in ts_failure_info (also with comma).
+ */
+#define TS_STATUS_BUF_SIZE      256
+
+/*
+ * Local mapping between response codes and descriptions.
+ */
+static const char *ts_status_text[] = {
+    "granted",
+    "grantedWithMods",
+    "rejection",
+    "waiting",
+    "revocationWarning",
+    "revocationNotification"
+};
+
+#define TS_STATUS_TEXT_SIZE     OSSL_NELEM(ts_status_text)
+
+static struct {
+    int code;
+    const char *text;
+} ts_failure_info[] = {
+    {TS_INFO_BAD_ALG, "badAlg"},
+    {TS_INFO_BAD_REQUEST, "badRequest"},
+    {TS_INFO_BAD_DATA_FORMAT, "badDataFormat"},
+    {TS_INFO_TIME_NOT_AVAILABLE, "timeNotAvailable"},
+    {TS_INFO_UNACCEPTED_POLICY, "unacceptedPolicy"},
+    {TS_INFO_UNACCEPTED_EXTENSION, "unacceptedExtension"},
+    {TS_INFO_ADD_INFO_NOT_AVAILABLE, "addInfoNotAvailable"},
+    {TS_INFO_SYSTEM_FAILURE, "systemFailure"}
+};
+
+
+/*-
+ * This function carries out the following tasks:
+ *      - Checks if there is one and only one signer.
+ *      - Search for the signing certificate in 'certs' and in the response.
+ *      - Check the extended key usage and key usage fields of the signer
+ *      certificate (done by the path validation).
+ *      - Build and validate the certificate path.
+ *      - Check if the certificate path meets the requirements of the
+ *      SigningCertificate ESS signed attribute.
+ *      - Verify the signature value.
+ *      - Returns the signer certificate in 'signer', if 'signer' is not NULL.
+ */
+int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
+                             X509_STORE *store, X509 **signer_out)
+{
+    STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL;
+    PKCS7_SIGNER_INFO *si;
+    STACK_OF(X509) *signers = NULL;
+    X509 *signer;
+    STACK_OF(X509) *chain = NULL;
+    char buf[4096];
+    int i, j = 0, ret = 0;
+    BIO *p7bio = NULL;
+
+    /* Some sanity checks first. */
+    if (!token) {
+        TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_INVALID_NULL_POINTER);
+        goto err;
+    }
+    if (!PKCS7_type_is_signed(token)) {
+        TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_WRONG_CONTENT_TYPE);
+        goto err;
+    }
+    sinfos = PKCS7_get_signer_info(token);
+    if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos) != 1) {
+        TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_THERE_MUST_BE_ONE_SIGNER);
+        goto err;
+    }
+    si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0);
+    if (PKCS7_get_detached(token)) {
+        TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_NO_CONTENT);
+        goto err;
+    }
+
+    /*
+     * Get hold of the signer certificate, search only internal certificates
+     * if it was requested.
+     */
+    signers = PKCS7_get0_signers(token, certs, 0);
+    if (!signers || sk_X509_num(signers) != 1)
+        goto err;
+    signer = sk_X509_value(signers, 0);
+
+    if (!ts_verify_cert(store, certs, signer, &chain))
+        goto err;
+    if (!ts_check_signing_certs(si, chain))
+        goto err;
+    p7bio = PKCS7_dataInit(token, NULL);
+
+    /* We now have to 'read' from p7bio to calculate digests etc. */
+    while ((i = BIO_read(p7bio, buf, sizeof(buf))) > 0)
+        continue;
+
+    j = PKCS7_signatureVerify(p7bio, token, si, signer);
+    if (j <= 0) {
+        TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_SIGNATURE_FAILURE);
+        goto err;
+    }
+
+    if (signer_out) {
+        *signer_out = signer;
+        X509_up_ref(signer);
+    }
+    ret = 1;
+
+ err:
+    BIO_free_all(p7bio);
+    sk_X509_pop_free(chain, X509_free);
+    sk_X509_free(signers);
+
+    return ret;
+}
+
+/*
+ * The certificate chain is returned in chain. Caller is responsible for
+ * freeing the vector.
+ */
+static int ts_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted,
+                          X509 *signer, STACK_OF(X509) **chain)
+{
+    X509_STORE_CTX *cert_ctx = NULL;
+    int i;
+    int ret = 0;
+
+    *chain = NULL;
+    cert_ctx = X509_STORE_CTX_new();
+    if (cert_ctx == NULL) {
+        TSerr(TS_F_TS_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if (!X509_STORE_CTX_init(cert_ctx, store, signer, untrusted))
+        goto end;
+    X509_STORE_CTX_set_purpose(cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN);
+    i = X509_verify_cert(cert_ctx);
+    if (i <= 0) {
+        int j = X509_STORE_CTX_get_error(cert_ctx);
+        TSerr(TS_F_TS_VERIFY_CERT, TS_R_CERTIFICATE_VERIFY_ERROR);
+        ERR_add_error_data(2, "Verify error:",
+                           X509_verify_cert_error_string(j));
+        goto err;
+    }
+    *chain = X509_STORE_CTX_get1_chain(cert_ctx);
+    ret = 1;
+    goto end;
+
+err:
+    ret = 0;
+
+end:
+    X509_STORE_CTX_free(cert_ctx);
+    return ret;
+}
+
+static int ts_check_signing_certs(PKCS7_SIGNER_INFO *si,
+                                  STACK_OF(X509) *chain)
+{
+    ESS_SIGNING_CERT *ss = ess_get_signing_cert(si);
+    STACK_OF(ESS_CERT_ID) *cert_ids = NULL;
+    X509 *cert;
+    int i = 0;
+    int ret = 0;
+
+    if (!ss)
+        goto err;
+    cert_ids = ss->cert_ids;
+    cert = sk_X509_value(chain, 0);
+    if (ts_find_cert(cert_ids, cert) != 0)
+        goto err;
+
+    /*
+     * Check the other certificates of the chain if there are more than one
+     * certificate ids in cert_ids.
+     */
+    if (sk_ESS_CERT_ID_num(cert_ids) > 1) {
+        for (i = 1; i < sk_X509_num(chain); ++i) {
+            cert = sk_X509_value(chain, i);
+            if (ts_find_cert(cert_ids, cert) < 0)
+                goto err;
+        }
+    }
+    ret = 1;
+ err:
+    if (!ret)
+        TSerr(TS_F_TS_CHECK_SIGNING_CERTS,
+              TS_R_ESS_SIGNING_CERTIFICATE_ERROR);
+    ESS_SIGNING_CERT_free(ss);
+    return ret;
+}
+
+static ESS_SIGNING_CERT *ess_get_signing_cert(PKCS7_SIGNER_INFO *si)
+{
+    ASN1_TYPE *attr;
+    const unsigned char *p;
+    attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificate);
+    if (!attr)
+        return NULL;
+    p = attr->value.sequence->data;
+    return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length);
+}
+
+/* Returns < 0 if certificate is not found, certificate index otherwise. */
+static int ts_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert)
+{
+    int i;
+    unsigned char cert_sha1[SHA_DIGEST_LENGTH];
+
+    if (!cert_ids || !cert)
+        return -1;
+
+    X509_digest(cert, EVP_sha1(), cert_sha1, NULL);
+
+    /* Recompute SHA1 hash of certificate if necessary (side effect). */
+    X509_check_purpose(cert, -1, 0);
+
+    /* Look for cert in the cert_ids vector. */
+    for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) {
+        ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i);
+
+        if (cid->hash->length == SHA_DIGEST_LENGTH
+            && memcmp(cid->hash->data, cert_sha1, SHA_DIGEST_LENGTH) == 0) {
+            ESS_ISSUER_SERIAL *is = cid->issuer_serial;
+            if (!is || !ts_issuer_serial_cmp(is, cert))
+                return i;
+        }
+    }
+
+    return -1;
+}
+
+static int ts_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509 *cert)
+{
+    GENERAL_NAME *issuer;
+
+    if (!is || !cert || sk_GENERAL_NAME_num(is->issuer) != 1)
+        return -1;
+
+    issuer = sk_GENERAL_NAME_value(is->issuer, 0);
+    if (issuer->type != GEN_DIRNAME
+        || X509_NAME_cmp(issuer->d.dirn, X509_get_issuer_name(cert)))
+        return -1;
+
+    if (ASN1_INTEGER_cmp(is->serial, X509_get_serialNumber(cert)))
+        return -1;
+
+    return 0;
+}
+
+/*-
+ * Verifies whether 'response' contains a valid response with regards
+ * to the settings of the context:
+ *      - Gives an error message if the TS_TST_INFO is not present.
+ *      - Calls _TS_RESP_verify_token to verify the token content.
+ */
+int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response)
+{
+    PKCS7 *token = response->token;
+    TS_TST_INFO *tst_info = response->tst_info;
+    int ret = 0;
+
+    if (!ts_check_status_info(response))
+        goto err;
+    if (!int_ts_RESP_verify_token(ctx, token, tst_info))
+        goto err;
+    ret = 1;
+
+ err:
+    return ret;
+}
+
+/*
+ * Tries to extract a TS_TST_INFO structure from the PKCS7 token and
+ * calls the internal int_TS_RESP_verify_token function for verifying it.
+ */
+int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token)
+{
+    TS_TST_INFO *tst_info = PKCS7_to_TS_TST_INFO(token);
+    int ret = 0;
+    if (tst_info) {
+        ret = int_ts_RESP_verify_token(ctx, token, tst_info);
+        TS_TST_INFO_free(tst_info);
+    }
+    return ret;
+}
+
+/*-
+ * Verifies whether the 'token' contains a valid time stamp token
+ * with regards to the settings of the context. Only those checks are
+ * carried out that are specified in the context:
+ *      - Verifies the signature of the TS_TST_INFO.
+ *      - Checks the version number of the response.
+ *      - Check if the requested and returned policies math.
+ *      - Check if the message imprints are the same.
+ *      - Check if the nonces are the same.
+ *      - Check if the TSA name matches the signer.
+ *      - Check if the TSA name is the expected TSA.
+ */
+static int int_ts_RESP_verify_token(TS_VERIFY_CTX *ctx,
+                                    PKCS7 *token, TS_TST_INFO *tst_info)
+{
+    X509 *signer = NULL;
+    GENERAL_NAME *tsa_name = tst_info->tsa;
+    X509_ALGOR *md_alg = NULL;
+    unsigned char *imprint = NULL;
+    unsigned imprint_len = 0;
+    int ret = 0;
+    int flags = ctx->flags;
+
+    /* Some options require us to also check the signature */
+    if (((flags & TS_VFY_SIGNER) && tsa_name != NULL)
+            || (flags & TS_VFY_TSA_NAME)) {
+        flags |= TS_VFY_SIGNATURE;
+    }
+
+    if ((flags & TS_VFY_SIGNATURE)
+        && !TS_RESP_verify_signature(token, ctx->certs, ctx->store, &signer))
+        goto err;
+    if ((flags & TS_VFY_VERSION)
+        && TS_TST_INFO_get_version(tst_info) != 1) {
+        TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_UNSUPPORTED_VERSION);
+        goto err;
+    }
+    if ((flags & TS_VFY_POLICY)
+        && !ts_check_policy(ctx->policy, tst_info))
+        goto err;
+    if ((flags & TS_VFY_IMPRINT)
+        && !ts_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len,
+                              tst_info))
+        goto err;
+    if ((flags & TS_VFY_DATA)
+        && (!ts_compute_imprint(ctx->data, tst_info,
+                                &md_alg, &imprint, &imprint_len)
+            || !ts_check_imprints(md_alg, imprint, imprint_len, tst_info)))
+        goto err;
+    if ((flags & TS_VFY_NONCE)
+        && !ts_check_nonces(ctx->nonce, tst_info))
+        goto err;
+    if ((flags & TS_VFY_SIGNER)
+        && tsa_name && !ts_check_signer_name(tsa_name, signer)) {
+        TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_NAME_MISMATCH);
+        goto err;
+    }
+    if ((flags & TS_VFY_TSA_NAME)
+        && !ts_check_signer_name(ctx->tsa_name, signer)) {
+        TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_UNTRUSTED);
+        goto err;
+    }
+    ret = 1;
+
+ err:
+    X509_free(signer);
+    X509_ALGOR_free(md_alg);
+    OPENSSL_free(imprint);
+    return ret;
+}
+
+static int ts_check_status_info(TS_RESP *response)
+{
+    TS_STATUS_INFO *info = response->status_info;
+    long status = ASN1_INTEGER_get(info->status);
+    const char *status_text = NULL;
+    char *embedded_status_text = NULL;
+    char failure_text[TS_STATUS_BUF_SIZE] = "";
+
+    if (status == 0 || status == 1)
+        return 1;
+
+    /* There was an error, get the description in status_text. */
+    if (0 <= status && status < (long) OSSL_NELEM(ts_status_text))
+        status_text = ts_status_text[status];
+    else
+        status_text = "unknown code";
+
+    if (sk_ASN1_UTF8STRING_num(info->text) > 0
+        && (embedded_status_text = ts_get_status_text(info->text)) == NULL)
+        return 0;
+
+    /* Fill in failure_text with the failure information. */
+    if (info->failure_info) {
+        int i;
+        int first = 1;
+        for (i = 0; i < (int)OSSL_NELEM(ts_failure_info); ++i) {
+            if (ASN1_BIT_STRING_get_bit(info->failure_info,
+                                        ts_failure_info[i].code)) {
+                if (!first)
+                    strcat(failure_text, ",");
+                else
+                    first = 0;
+                strcat(failure_text, ts_failure_info[i].text);
+            }
+        }
+    }
+    if (failure_text[0] == '\0')
+        strcpy(failure_text, "unspecified");
+
+    TSerr(TS_F_TS_CHECK_STATUS_INFO, TS_R_NO_TIME_STAMP_TOKEN);
+    ERR_add_error_data(6,
+                       "status code: ", status_text,
+                       ", status text: ", embedded_status_text ?
+                       embedded_status_text : "unspecified",
+                       ", failure codes: ", failure_text);
+    OPENSSL_free(embedded_status_text);
+
+    return 0;
+}
+
+static char *ts_get_status_text(STACK_OF(ASN1_UTF8STRING) *text)
+{
+    int i;
+    int length = 0;
+    char *result = NULL;
+    char *p;
+
+    for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) {
+        ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i);
+        if (ASN1_STRING_length(current) > TS_MAX_STATUS_LENGTH - length - 1)
+            return NULL;
+        length += ASN1_STRING_length(current);
+        length += 1;            /* separator character */
+    }
+    if ((result = OPENSSL_malloc(length)) == NULL) {
+        TSerr(TS_F_TS_GET_STATUS_TEXT, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    for (i = 0, p = result; i < sk_ASN1_UTF8STRING_num(text); ++i) {
+        ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i);
+        length = ASN1_STRING_length(current);
+        if (i > 0)
+            *p++ = '/';
+        strncpy(p, (const char *)ASN1_STRING_get0_data(current), length);
+        p += length;
+    }
+    *p = '\0';
+
+    return result;
+}
+
+static int ts_check_policy(const ASN1_OBJECT *req_oid, 
+                           const TS_TST_INFO *tst_info)
+{
+    const ASN1_OBJECT *resp_oid = tst_info->policy_id;
+
+    if (OBJ_cmp(req_oid, resp_oid) != 0) {
+        TSerr(TS_F_TS_CHECK_POLICY, TS_R_POLICY_MISMATCH);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int ts_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
+                              X509_ALGOR **md_alg,
+                              unsigned char **imprint, unsigned *imprint_len)
+{
+    TS_MSG_IMPRINT *msg_imprint = tst_info->msg_imprint;
+    X509_ALGOR *md_alg_resp = msg_imprint->hash_algo;
+    const EVP_MD *md;
+    EVP_MD_CTX *md_ctx = NULL;
+    unsigned char buffer[4096];
+    int length;
+
+    *md_alg = NULL;
+    *imprint = NULL;
+
+    if ((*md_alg = X509_ALGOR_dup(md_alg_resp)) == NULL)
+        goto err;
+    if ((md = EVP_get_digestbyobj((*md_alg)->algorithm)) == NULL) {
+        TSerr(TS_F_TS_COMPUTE_IMPRINT, TS_R_UNSUPPORTED_MD_ALGORITHM);
+        goto err;
+    }
+    length = EVP_MD_size(md);
+    if (length < 0)
+        goto err;
+    *imprint_len = length;
+    if ((*imprint = OPENSSL_malloc(*imprint_len)) == NULL) {
+        TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    md_ctx = EVP_MD_CTX_new();
+    if (md_ctx == NULL) {
+        TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if (!EVP_DigestInit(md_ctx, md))
+        goto err;
+    while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0) {
+        if (!EVP_DigestUpdate(md_ctx, buffer, length))
+            goto err;
+    }
+    if (!EVP_DigestFinal(md_ctx, *imprint, NULL))
+        goto err;
+    EVP_MD_CTX_free(md_ctx);
+
+    return 1;
+ err:
+    EVP_MD_CTX_free(md_ctx);
+    X509_ALGOR_free(*md_alg);
+    OPENSSL_free(*imprint);
+    *imprint_len = 0;
+    *imprint = 0;
+    return 0;
+}
+
+static int ts_check_imprints(X509_ALGOR *algor_a,
+                             const unsigned char *imprint_a, unsigned len_a,
+                             TS_TST_INFO *tst_info)
+{
+    TS_MSG_IMPRINT *b = tst_info->msg_imprint;
+    X509_ALGOR *algor_b = b->hash_algo;
+    int ret = 0;
+
+    if (algor_a) {
+        if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm))
+            goto err;
+
+        /* The parameter must be NULL in both. */
+        if ((algor_a->parameter
+             && ASN1_TYPE_get(algor_a->parameter) != V_ASN1_NULL)
+            || (algor_b->parameter
+                && ASN1_TYPE_get(algor_b->parameter) != V_ASN1_NULL))
+            goto err;
+    }
+
+    ret = len_a == (unsigned)ASN1_STRING_length(b->hashed_msg) &&
+        memcmp(imprint_a, ASN1_STRING_get0_data(b->hashed_msg), len_a) == 0;
+ err:
+    if (!ret)
+        TSerr(TS_F_TS_CHECK_IMPRINTS, TS_R_MESSAGE_IMPRINT_MISMATCH);
+    return ret;
+}
+
+static int ts_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info)
+{
+    const ASN1_INTEGER *b = tst_info->nonce;
+
+    if (!b) {
+        TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_NOT_RETURNED);
+        return 0;
+    }
+
+    /* No error if a nonce is returned without being requested. */
+    if (ASN1_INTEGER_cmp(a, b) != 0) {
+        TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_MISMATCH);
+        return 0;
+    }
+
+    return 1;
+}
+
+/*
+ * Check if the specified TSA name matches either the subject or one of the
+ * subject alternative names of the TSA certificate.
+ */
+static int ts_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer)
+{
+    STACK_OF(GENERAL_NAME) *gen_names = NULL;
+    int idx = -1;
+    int found = 0;
+
+    if (tsa_name->type == GEN_DIRNAME
+        && X509_name_cmp(tsa_name->d.dirn, X509_get_subject_name(signer)) == 0)
+        return 1;
+    gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, NULL, &idx);
+    while (gen_names != NULL) {
+        found = ts_find_name(gen_names, tsa_name) >= 0;
+        if (found)
+            break;
+        /*
+         * Get the next subject alternative name, although there should be no
+         * more than one.
+         */
+        GENERAL_NAMES_free(gen_names);
+        gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, NULL, &idx);
+    }
+    GENERAL_NAMES_free(gen_names);
+
+    return found;
+}
+
+/* Returns 1 if name is in gen_names, 0 otherwise. */
+static int ts_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name)
+{
+    int i, found;
+    for (i = 0, found = 0; !found && i < sk_GENERAL_NAME_num(gen_names); ++i) {
+        GENERAL_NAME *current = sk_GENERAL_NAME_value(gen_names, i);
+        found = GENERAL_NAME_cmp(current, name) == 0;
+    }
+    return found ? i - 1 : -1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_verify_ctx.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_verify_ctx.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ts/ts_verify_ctx.c	(revision 331)
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2006-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 "internal/cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/ts.h>
+#include "ts_lcl.h"
+
+TS_VERIFY_CTX *TS_VERIFY_CTX_new(void)
+{
+    TS_VERIFY_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+    if (ctx == NULL)
+        TSerr(TS_F_TS_VERIFY_CTX_NEW, ERR_R_MALLOC_FAILURE);
+    return ctx;
+}
+
+void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx)
+{
+    OPENSSL_assert(ctx != NULL);
+    memset(ctx, 0, sizeof(*ctx));
+}
+
+void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx)
+{
+    if (!ctx)
+        return;
+
+    TS_VERIFY_CTX_cleanup(ctx);
+    OPENSSL_free(ctx);
+}
+
+int TS_VERIFY_CTX_add_flags(TS_VERIFY_CTX *ctx, int f)
+{
+    ctx->flags |= f;
+    return ctx->flags;
+}
+
+int TS_VERIFY_CTX_set_flags(TS_VERIFY_CTX *ctx, int f)
+{
+    ctx->flags = f;
+    return ctx->flags;
+}
+
+BIO *TS_VERIFY_CTX_set_data(TS_VERIFY_CTX *ctx, BIO *b)
+{
+    ctx->data = b;
+    return ctx->data;
+}
+
+X509_STORE *TS_VERIFY_CTX_set_store(TS_VERIFY_CTX *ctx, X509_STORE *s)
+{
+    ctx->store = s;
+    return ctx->store;
+}
+
+STACK_OF(X509) *TS_VERIFY_CTS_set_certs(TS_VERIFY_CTX *ctx,
+                                        STACK_OF(X509) *certs)
+{
+    ctx->certs = certs;
+    return ctx->certs;
+}
+
+unsigned char *TS_VERIFY_CTX_set_imprint(TS_VERIFY_CTX *ctx,
+                                         unsigned char *hexstr, long len)
+{
+    ctx->imprint = hexstr;
+    ctx->imprint_len = len;
+    return ctx->imprint;
+}
+
+void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx)
+{
+    if (!ctx)
+        return;
+
+    X509_STORE_free(ctx->store);
+    sk_X509_pop_free(ctx->certs, X509_free);
+
+    ASN1_OBJECT_free(ctx->policy);
+
+    X509_ALGOR_free(ctx->md_alg);
+    OPENSSL_free(ctx->imprint);
+
+    BIO_free_all(ctx->data);
+
+    ASN1_INTEGER_free(ctx->nonce);
+
+    GENERAL_NAME_free(ctx->tsa_name);
+
+    TS_VERIFY_CTX_init(ctx);
+}
+
+TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx)
+{
+    TS_VERIFY_CTX *ret = ctx;
+    ASN1_OBJECT *policy;
+    TS_MSG_IMPRINT *imprint;
+    X509_ALGOR *md_alg;
+    ASN1_OCTET_STRING *msg;
+    const ASN1_INTEGER *nonce;
+
+    OPENSSL_assert(req != NULL);
+    if (ret)
+        TS_VERIFY_CTX_cleanup(ret);
+    else if ((ret = TS_VERIFY_CTX_new()) == NULL)
+        return NULL;
+
+    ret->flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE);
+
+    if ((policy = req->policy_id) != NULL) {
+        if ((ret->policy = OBJ_dup(policy)) == NULL)
+            goto err;
+    } else
+        ret->flags &= ~TS_VFY_POLICY;
+
+    imprint = req->msg_imprint;
+    md_alg = imprint->hash_algo;
+    if ((ret->md_alg = X509_ALGOR_dup(md_alg)) == NULL)
+        goto err;
+    msg = imprint->hashed_msg;
+    ret->imprint_len = ASN1_STRING_length(msg);
+    if ((ret->imprint = OPENSSL_malloc(ret->imprint_len)) == NULL)
+        goto err;
+    memcpy(ret->imprint, ASN1_STRING_get0_data(msg), ret->imprint_len);
+
+    if ((nonce = req->nonce) != NULL) {
+        if ((ret->nonce = ASN1_INTEGER_dup(nonce)) == NULL)
+            goto err;
+    } else
+        ret->flags &= ~TS_VFY_NONCE;
+
+    return ret;
+ err:
+    if (ctx)
+        TS_VERIFY_CTX_cleanup(ctx);
+    else
+        TS_VERIFY_CTX_free(ret);
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/txt_db/txt_db.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/txt_db/txt_db.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/txt_db/txt_db.c	(revision 331)
@@ -0,0 +1,301 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/txt_db.h>
+
+#undef BUFSIZE
+#define BUFSIZE 512
+
+TXT_DB *TXT_DB_read(BIO *in, int num)
+{
+    TXT_DB *ret = NULL;
+    int esc = 0;
+    long ln = 0;
+    int i, add, n;
+    int size = BUFSIZE;
+    int offset = 0;
+    char *p, *f;
+    OPENSSL_STRING *pp;
+    BUF_MEM *buf = NULL;
+
+    if ((buf = BUF_MEM_new()) == NULL)
+        goto err;
+    if (!BUF_MEM_grow(buf, size))
+        goto err;
+
+    if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)
+        goto err;
+    ret->num_fields = num;
+    ret->index = NULL;
+    ret->qual = NULL;
+    if ((ret->data = sk_OPENSSL_PSTRING_new_null()) == NULL)
+        goto err;
+    if ((ret->index = OPENSSL_malloc(sizeof(*ret->index) * num)) == NULL)
+        goto err;
+    if ((ret->qual = OPENSSL_malloc(sizeof(*(ret->qual)) * num)) == NULL)
+        goto err;
+    for (i = 0; i < num; i++) {
+        ret->index[i] = NULL;
+        ret->qual[i] = NULL;
+    }
+
+    add = (num + 1) * sizeof(char *);
+    buf->data[size - 1] = '\0';
+    offset = 0;
+    for (;;) {
+        if (offset != 0) {
+            size += BUFSIZE;
+            if (!BUF_MEM_grow_clean(buf, size))
+                goto err;
+        }
+        buf->data[offset] = '\0';
+        BIO_gets(in, &(buf->data[offset]), size - offset);
+        ln++;
+        if (buf->data[offset] == '\0')
+            break;
+        if ((offset == 0) && (buf->data[0] == '#'))
+            continue;
+        i = strlen(&(buf->data[offset]));
+        offset += i;
+        if (buf->data[offset - 1] != '\n')
+            continue;
+        else {
+            buf->data[offset - 1] = '\0'; /* blat the '\n' */
+            if ((p = OPENSSL_malloc(add + offset)) == NULL)
+                goto err;
+            offset = 0;
+        }
+        pp = (char **)p;
+        p += add;
+        n = 0;
+        pp[n++] = p;
+        i = 0;
+        f = buf->data;
+
+        esc = 0;
+        for (;;) {
+            if (*f == '\0')
+                break;
+            if (*f == '\t') {
+                if (esc)
+                    p--;
+                else {
+                    *(p++) = '\0';
+                    f++;
+                    if (n >= num)
+                        break;
+                    pp[n++] = p;
+                    continue;
+                }
+            }
+            esc = (*f == '\\');
+            *(p++) = *(f++);
+        }
+        *(p++) = '\0';
+        if ((n != num) || (*f != '\0')) {
+            ret->error = DB_ERROR_WRONG_NUM_FIELDS;
+            goto err;
+        }
+        pp[n] = p;
+        if (!sk_OPENSSL_PSTRING_push(ret->data, pp))
+            goto err;
+    }
+    BUF_MEM_free(buf);
+    return ret;
+ err:
+    BUF_MEM_free(buf);
+    if (ret != NULL) {
+        sk_OPENSSL_PSTRING_free(ret->data);
+        OPENSSL_free(ret->index);
+        OPENSSL_free(ret->qual);
+        OPENSSL_free(ret);
+    }
+    return (NULL);
+}
+
+OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx,
+                                    OPENSSL_STRING *value)
+{
+    OPENSSL_STRING *ret;
+    LHASH_OF(OPENSSL_STRING) *lh;
+
+    if (idx >= db->num_fields) {
+        db->error = DB_ERROR_INDEX_OUT_OF_RANGE;
+        return (NULL);
+    }
+    lh = db->index[idx];
+    if (lh == NULL) {
+        db->error = DB_ERROR_NO_INDEX;
+        return (NULL);
+    }
+    ret = lh_OPENSSL_STRING_retrieve(lh, value);
+    db->error = DB_ERROR_OK;
+    return (ret);
+}
+
+int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *),
+                        OPENSSL_LH_HASHFUNC hash, OPENSSL_LH_COMPFUNC cmp)
+{
+    LHASH_OF(OPENSSL_STRING) *idx;
+    OPENSSL_STRING *r;
+    int i, n;
+
+    if (field >= db->num_fields) {
+        db->error = DB_ERROR_INDEX_OUT_OF_RANGE;
+        return (0);
+    }
+    /* FIXME: we lose type checking at this point */
+    if ((idx = (LHASH_OF(OPENSSL_STRING) *)OPENSSL_LH_new(hash, cmp)) == NULL) {
+        db->error = DB_ERROR_MALLOC;
+        return (0);
+    }
+    n = sk_OPENSSL_PSTRING_num(db->data);
+    for (i = 0; i < n; i++) {
+        r = sk_OPENSSL_PSTRING_value(db->data, i);
+        if ((qual != NULL) && (qual(r) == 0))
+            continue;
+        if ((r = lh_OPENSSL_STRING_insert(idx, r)) != NULL) {
+            db->error = DB_ERROR_INDEX_CLASH;
+            db->arg1 = sk_OPENSSL_PSTRING_find(db->data, r);
+            db->arg2 = i;
+            lh_OPENSSL_STRING_free(idx);
+            return (0);
+        }
+    }
+    lh_OPENSSL_STRING_free(db->index[field]);
+    db->index[field] = idx;
+    db->qual[field] = qual;
+    return (1);
+}
+
+long TXT_DB_write(BIO *out, TXT_DB *db)
+{
+    long i, j, n, nn, l, tot = 0;
+    char *p, **pp, *f;
+    BUF_MEM *buf = NULL;
+    long ret = -1;
+
+    if ((buf = BUF_MEM_new()) == NULL)
+        goto err;
+    n = sk_OPENSSL_PSTRING_num(db->data);
+    nn = db->num_fields;
+    for (i = 0; i < n; i++) {
+        pp = sk_OPENSSL_PSTRING_value(db->data, i);
+
+        l = 0;
+        for (j = 0; j < nn; j++) {
+            if (pp[j] != NULL)
+                l += strlen(pp[j]);
+        }
+        if (!BUF_MEM_grow_clean(buf, (int)(l * 2 + nn)))
+            goto err;
+
+        p = buf->data;
+        for (j = 0; j < nn; j++) {
+            f = pp[j];
+            if (f != NULL)
+                for (;;) {
+                    if (*f == '\0')
+                        break;
+                    if (*f == '\t')
+                        *(p++) = '\\';
+                    *(p++) = *(f++);
+                }
+            *(p++) = '\t';
+        }
+        p[-1] = '\n';
+        j = p - buf->data;
+        if (BIO_write(out, buf->data, (int)j) != j)
+            goto err;
+        tot += j;
+    }
+    ret = tot;
+ err:
+    BUF_MEM_free(buf);
+    return (ret);
+}
+
+int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *row)
+{
+    int i;
+    OPENSSL_STRING *r;
+
+    for (i = 0; i < db->num_fields; i++) {
+        if (db->index[i] != NULL) {
+            if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0))
+                continue;
+            r = lh_OPENSSL_STRING_retrieve(db->index[i], row);
+            if (r != NULL) {
+                db->error = DB_ERROR_INDEX_CLASH;
+                db->arg1 = i;
+                db->arg_row = r;
+                goto err;
+            }
+        }
+    }
+    /* We have passed the index checks, now just append and insert */
+    if (!sk_OPENSSL_PSTRING_push(db->data, row)) {
+        db->error = DB_ERROR_MALLOC;
+        goto err;
+    }
+
+    for (i = 0; i < db->num_fields; i++) {
+        if (db->index[i] != NULL) {
+            if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0))
+                continue;
+            (void)lh_OPENSSL_STRING_insert(db->index[i], row);
+        }
+    }
+    return (1);
+ err:
+    return (0);
+}
+
+void TXT_DB_free(TXT_DB *db)
+{
+    int i, n;
+    char **p, *max;
+
+    if (db == NULL)
+        return;
+
+    if (db->index != NULL) {
+        for (i = db->num_fields - 1; i >= 0; i--)
+            lh_OPENSSL_STRING_free(db->index[i]);
+        OPENSSL_free(db->index);
+    }
+    OPENSSL_free(db->qual);
+    if (db->data != NULL) {
+        for (i = sk_OPENSSL_PSTRING_num(db->data) - 1; i >= 0; i--) {
+            /*
+             * check if any 'fields' have been allocated from outside of the
+             * initial block
+             */
+            p = sk_OPENSSL_PSTRING_value(db->data, i);
+            max = p[db->num_fields]; /* last address */
+            if (max == NULL) {  /* new row */
+                for (n = 0; n < db->num_fields; n++)
+                    OPENSSL_free(p[n]);
+            } else {
+                for (n = 0; n < db->num_fields; n++) {
+                    if (((p[n] < (char *)p) || (p[n] > max)))
+                        OPENSSL_free(p[n]);
+                }
+            }
+            OPENSSL_free(sk_OPENSSL_PSTRING_value(db->data, i));
+        }
+        sk_OPENSSL_PSTRING_free(db->data);
+    }
+    OPENSSL_free(db);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ui/ui_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ui/ui_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/ui/ui_locl.h	(revision 331)
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2001-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
+ */
+
+#ifndef HEADER_UI_LOCL_H
+# define HEADER_UI_LOCL_H
+
+# include <openssl/ui.h>
+# include <openssl/crypto.h>
+
+# ifdef _
+#  undef _
+# endif
+
+struct ui_method_st {
+    char *name;
+    /*
+     * All the functions return 1 or non-NULL for success and 0 or NULL for
+     * failure
+     */
+    /*
+     * Open whatever channel for this, be it the console, an X window or
+     * whatever. This function should use the ex_data structure to save
+     * intermediate data.
+     */
+    int (*ui_open_session) (UI *ui);
+    int (*ui_write_string) (UI *ui, UI_STRING *uis);
+    /*
+     * Flush the output.  If a GUI dialog box is used, this function can be
+     * used to actually display it.
+     */
+    int (*ui_flush) (UI *ui);
+    int (*ui_read_string) (UI *ui, UI_STRING *uis);
+    int (*ui_close_session) (UI *ui);
+    /*
+     * Construct a prompt in a user-defined manner.  object_desc is a textual
+     * short description of the object, for example "pass phrase", and
+     * object_name is the name of the object (might be a card name or a file
+     * name. The returned string shall always be allocated on the heap with
+     * OPENSSL_malloc(), and need to be free'd with OPENSSL_free().
+     */
+    char *(*ui_construct_prompt) (UI *ui, const char *object_desc,
+                                  const char *object_name);
+};
+
+struct ui_string_st {
+    enum UI_string_types type;  /* Input */
+    const char *out_string;     /* Input */
+    int input_flags;            /* Flags from the user */
+    /*
+     * The following parameters are completely irrelevant for UIT_INFO, and
+     * can therefore be set to 0 or NULL
+     */
+    char *result_buf;           /* Input and Output: If not NULL,
+                                 * user-defined with size in result_maxsize.
+                                 * Otherwise, it may be allocated by the UI
+                                 * routine, meaning result_minsize is going
+                                 * to be overwritten. */
+    union {
+        struct {
+            int result_minsize; /* Input: minimum required size of the
+                                 * result. */
+            int result_maxsize; /* Input: maximum permitted size of the
+                                 * result */
+            const char *test_buf; /* Input: test string to verify against */
+        } string_data;
+        struct {
+            const char *action_desc; /* Input */
+            const char *ok_chars; /* Input */
+            const char *cancel_chars; /* Input */
+        } boolean_data;
+    } _;
+
+# define OUT_STRING_FREEABLE 0x01
+    int flags;                  /* flags for internal use */
+};
+
+struct ui_st {
+    const UI_METHOD *meth;
+    STACK_OF(UI_STRING) *strings; /* We might want to prompt for more than
+                                   * one thing at a time, and with different
+                                   * echoing status.  */
+    void *user_data;
+    CRYPTO_EX_DATA ex_data;
+# define UI_FLAG_REDOABLE        0x0001
+# define UI_FLAG_PRINT_ERRORS    0x0100
+    int flags;
+
+    CRYPTO_RWLOCK *lock;
+};
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/uid.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/uid.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/uid.c	(revision 331)
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2001-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 <openssl/crypto.h>
+#include <openssl/opensslconf.h>
+
+#if defined(__OpenBSD__) || (defined(__FreeBSD__) && __FreeBSD__ > 2)
+
+# include OPENSSL_UNISTD
+
+int OPENSSL_issetugid(void)
+{
+    return issetugid();
+}
+
+#elif defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS)
+
+int OPENSSL_issetugid(void)
+{
+    return 0;
+}
+
+#else
+
+# include OPENSSL_UNISTD
+# include <sys/types.h>
+
+int OPENSSL_issetugid(void)
+{
+    if (getuid() != geteuid())
+        return 1;
+    if (getgid() != getegid())
+        return 1;
+    return 0;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/vms_rms.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/vms_rms.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/vms_rms.h	(revision 331)
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2011-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
+ */
+
+#ifdef NAML$C_MAXRSS
+
+# define CC_RMS_NAMX cc$rms_naml
+# define FAB_NAMX fab$l_naml
+# define FAB_OR_NAML( fab, naml) naml
+# define FAB_OR_NAML_DNA naml$l_long_defname
+# define FAB_OR_NAML_DNS naml$l_long_defname_size
+# define FAB_OR_NAML_FNA naml$l_long_filename
+# define FAB_OR_NAML_FNS naml$l_long_filename_size
+# define NAMX_ESA naml$l_long_expand
+# define NAMX_ESL naml$l_long_expand_size
+# define NAMX_ESS naml$l_long_expand_alloc
+# define NAMX_NOP naml$b_nop
+# define SET_NAMX_NO_SHORT_UPCASE( nam) nam.naml$v_no_short_upcase = 1
+
+# if __INITIAL_POINTER_SIZE == 64
+#  define NAMX_DNA_FNA_SET(fab) fab.fab$l_dna = (__char_ptr32) -1; \
+   fab.fab$l_fna = (__char_ptr32) -1;
+# else                          /* __INITIAL_POINTER_SIZE == 64 */
+#  define NAMX_DNA_FNA_SET(fab) fab.fab$l_dna = (char *) -1; \
+   fab.fab$l_fna = (char *) -1;
+# endif                         /* __INITIAL_POINTER_SIZE == 64 [else] */
+
+# define NAMX_MAXRSS NAML$C_MAXRSS
+# define NAMX_STRUCT NAML
+
+#else                           /* def NAML$C_MAXRSS */
+
+# define CC_RMS_NAMX cc$rms_nam
+# define FAB_NAMX fab$l_nam
+# define FAB_OR_NAML( fab, naml) fab
+# define FAB_OR_NAML_DNA fab$l_dna
+# define FAB_OR_NAML_DNS fab$b_dns
+# define FAB_OR_NAML_FNA fab$l_fna
+# define FAB_OR_NAML_FNS fab$b_fns
+# define NAMX_ESA nam$l_esa
+# define NAMX_ESL nam$b_esl
+# define NAMX_ESS nam$b_ess
+# define NAMX_NOP nam$b_nop
+# define NAMX_DNA_FNA_SET(fab)
+# define NAMX_MAXRSS NAM$C_MAXRSS
+# define NAMX_STRUCT NAM
+# ifdef NAM$M_NO_SHORT_UPCASE
+#  define SET_NAMX_NO_SHORT_UPCASE( nam) naml.naml$v_no_short_upcase = 1
+# else                          /* def NAM$M_NO_SHORT_UPCASE */
+#  define SET_NAMX_NO_SHORT_UPCASE( nam)
+# endif                         /* def NAM$M_NO_SHORT_UPCASE [else] */
+
+#endif                          /* def NAML$C_MAXRSS [else] */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/whrlpool/wp_block.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/whrlpool/wp_block.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/whrlpool/wp_block.c	(revision 331)
@@ -0,0 +1,792 @@
+/*
+ * Copyright 2005-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
+ */
+
+/**
+ * The Whirlpool hashing function.
+ *
+ * <P>
+ * <b>References</b>
+ *
+ * <P>
+ * The Whirlpool algorithm was developed by
+ * <a href="mailto:pbarreto@scopus.com.br">Paulo S. L. M. Barreto</a> and
+ * <a href="mailto:vincent.rijmen@cryptomathic.com">Vincent Rijmen</a>.
+ *
+ * See
+ *      P.S.L.M. Barreto, V. Rijmen,
+ *      ``The Whirlpool hashing function,''
+ *      NESSIE submission, 2000 (tweaked version, 2001),
+ *      <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip>
+ *
+ * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and
+ * Vincent Rijmen. Lookup "reference implementations" on
+ * <http://planeta.terra.com.br/informatica/paulobarreto/>
+ *
+ * =============================================================================
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "wp_locl.h"
+#include <string.h>
+
+typedef unsigned char u8;
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32)
+typedef unsigned __int64 u64;
+#elif defined(__arch64__)
+typedef unsigned long u64;
+#else
+typedef unsigned long long u64;
+#endif
+
+#define ROUNDS  10
+
+#define STRICT_ALIGNMENT
+#if !defined(PEDANTIC) && (defined(__i386) || defined(__i386__) || \
+                           defined(__x86_64) || defined(__x86_64__) || \
+                           defined(_M_IX86) || defined(_M_AMD64) || \
+                           defined(_M_X64))
+/*
+ * Well, formally there're couple of other architectures, which permit
+ * unaligned loads, specifically those not crossing cache lines, IA-64 and
+ * PowerPC...
+ */
+# undef STRICT_ALIGNMENT
+#endif
+
+#undef SMALL_REGISTER_BANK
+#if defined(__i386) || defined(__i386__) || defined(_M_IX86)
+# define SMALL_REGISTER_BANK
+# if defined(WHIRLPOOL_ASM)
+#  ifndef OPENSSL_SMALL_FOOTPRINT
+/*
+ * it appears that for elder non-MMX
+ * CPUs this is actually faster!
+ */
+#   define OPENSSL_SMALL_FOOTPRINT
+#  endif
+#  define GO_FOR_MMX(ctx,inp,num)     do {                    \
+        extern unsigned long OPENSSL_ia32cap_P[];               \
+        void whirlpool_block_mmx(void *,const void *,size_t);   \
+        if (!(OPENSSL_ia32cap_P[0] & (1<<23)))  break;          \
+        whirlpool_block_mmx(ctx->H.c,inp,num);  return;         \
+                                        } while (0)
+# endif
+#endif
+
+#undef ROTATE
+#ifndef PEDANTIC
+# if defined(_MSC_VER)
+#  if defined(_WIN64)            /* applies to both IA-64 and AMD64 */
+#   pragma intrinsic(_rotl64)
+#   define ROTATE(a,n) _rotl64((a),n)
+#  endif
+# elif defined(__GNUC__) && __GNUC__>=2
+#  if defined(__x86_64) || defined(__x86_64__)
+#   if defined(L_ENDIAN)
+#    define ROTATE(a,n)       ({ u64 ret; asm ("rolq %1,%0"   \
+                                   : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; })
+#   elif defined(B_ENDIAN)
+       /*
+        * Most will argue that x86_64 is always little-endian. Well, yes, but
+        * then we have stratus.com who has modified gcc to "emulate"
+        * big-endian on x86. Is there evidence that they [or somebody else]
+        * won't do same for x86_64? Naturally no. And this line is waiting
+        * ready for that brave soul:-)
+        */
+#    define ROTATE(a,n)       ({ u64 ret; asm ("rorq %1,%0"   \
+                                   : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; })
+#   endif
+#  elif defined(__ia64) || defined(__ia64__)
+#   if defined(L_ENDIAN)
+#    define ROTATE(a,n)       ({ u64 ret; asm ("shrp %0=%1,%1,%2"     \
+                                   : "=r"(ret) : "r"(a),"M"(64-(n))); ret; })
+#   elif defined(B_ENDIAN)
+#    define ROTATE(a,n)       ({ u64 ret; asm ("shrp %0=%1,%1,%2"     \
+                                   : "=r"(ret) : "r"(a),"M"(n)); ret; })
+#   endif
+#  endif
+# endif
+#endif
+
+#if defined(OPENSSL_SMALL_FOOTPRINT)
+# if !defined(ROTATE)
+#  if defined(L_ENDIAN)         /* little-endians have to rotate left */
+#   define ROTATE(i,n)       ((i)<<(n) ^ (i)>>(64-n))
+#  elif defined(B_ENDIAN)       /* big-endians have to rotate right */
+#   define ROTATE(i,n)       ((i)>>(n) ^ (i)<<(64-n))
+#  endif
+# endif
+# if defined(ROTATE) && !defined(STRICT_ALIGNMENT)
+#  define STRICT_ALIGNMENT      /* ensure smallest table size */
+# endif
+#endif
+
+/*
+ * Table size depends on STRICT_ALIGNMENT and whether or not endian-
+ * specific ROTATE macro is defined. If STRICT_ALIGNMENT is not
+ * defined, which is normally the case on x86[_64] CPUs, the table is
+ * 4KB large unconditionally. Otherwise if ROTATE is defined, the
+ * table is 2KB large, and otherwise - 16KB. 2KB table requires a
+ * whole bunch of additional rotations, but I'm willing to "trade,"
+ * because 16KB table certainly trashes L1 cache. I wish all CPUs
+ * could handle unaligned load as 4KB table doesn't trash the cache,
+ * nor does it require additional rotations.
+ */
+/*
+ * Note that every Cn macro expands as two loads: one byte load and
+ * one quadword load. One can argue that that many single-byte loads
+ * is too excessive, as one could load a quadword and "milk" it for
+ * eight 8-bit values instead. Well, yes, but in order to do so *and*
+ * avoid excessive loads you have to accommodate a handful of 64-bit
+ * values in the register bank and issue a bunch of shifts and mask.
+ * It's a tradeoff: loads vs. shift and mask in big register bank[!].
+ * On most CPUs eight single-byte loads are faster and I let other
+ * ones to depend on smart compiler to fold byte loads if beneficial.
+ * Hand-coded assembler would be another alternative:-)
+ */
+#ifdef STRICT_ALIGNMENT
+# if defined(ROTATE)
+#  define N   1
+#  define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7
+#  define C0(K,i)     (Cx.q[K.c[(i)*8+0]])
+#  define C1(K,i)     ROTATE(Cx.q[K.c[(i)*8+1]],8)
+#  define C2(K,i)     ROTATE(Cx.q[K.c[(i)*8+2]],16)
+#  define C3(K,i)     ROTATE(Cx.q[K.c[(i)*8+3]],24)
+#  define C4(K,i)     ROTATE(Cx.q[K.c[(i)*8+4]],32)
+#  define C5(K,i)     ROTATE(Cx.q[K.c[(i)*8+5]],40)
+#  define C6(K,i)     ROTATE(Cx.q[K.c[(i)*8+6]],48)
+#  define C7(K,i)     ROTATE(Cx.q[K.c[(i)*8+7]],56)
+# else
+#  define N   8
+#  define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7, \
+                                        c7,c0,c1,c2,c3,c4,c5,c6, \
+                                        c6,c7,c0,c1,c2,c3,c4,c5, \
+                                        c5,c6,c7,c0,c1,c2,c3,c4, \
+                                        c4,c5,c6,c7,c0,c1,c2,c3, \
+                                        c3,c4,c5,c6,c7,c0,c1,c2, \
+                                        c2,c3,c4,c5,c6,c7,c0,c1, \
+                                        c1,c2,c3,c4,c5,c6,c7,c0
+#  define C0(K,i)     (Cx.q[0+8*K.c[(i)*8+0]])
+#  define C1(K,i)     (Cx.q[1+8*K.c[(i)*8+1]])
+#  define C2(K,i)     (Cx.q[2+8*K.c[(i)*8+2]])
+#  define C3(K,i)     (Cx.q[3+8*K.c[(i)*8+3]])
+#  define C4(K,i)     (Cx.q[4+8*K.c[(i)*8+4]])
+#  define C5(K,i)     (Cx.q[5+8*K.c[(i)*8+5]])
+#  define C6(K,i)     (Cx.q[6+8*K.c[(i)*8+6]])
+#  define C7(K,i)     (Cx.q[7+8*K.c[(i)*8+7]])
+# endif
+#else
+# define N     2
+# define LL(c0,c1,c2,c3,c4,c5,c6,c7)   c0,c1,c2,c3,c4,c5,c6,c7, \
+                                        c0,c1,c2,c3,c4,c5,c6,c7
+# define C0(K,i)       (((u64*)(Cx.c+0))[2*K.c[(i)*8+0]])
+# define C1(K,i)       (((u64*)(Cx.c+7))[2*K.c[(i)*8+1]])
+# define C2(K,i)       (((u64*)(Cx.c+6))[2*K.c[(i)*8+2]])
+# define C3(K,i)       (((u64*)(Cx.c+5))[2*K.c[(i)*8+3]])
+# define C4(K,i)       (((u64*)(Cx.c+4))[2*K.c[(i)*8+4]])
+# define C5(K,i)       (((u64*)(Cx.c+3))[2*K.c[(i)*8+5]])
+# define C6(K,i)       (((u64*)(Cx.c+2))[2*K.c[(i)*8+6]])
+# define C7(K,i)       (((u64*)(Cx.c+1))[2*K.c[(i)*8+7]])
+#endif
+
+static const
+    union {
+    u8 c[(256 * N + ROUNDS) * sizeof(u64)];
+    u64 q[(256 * N + ROUNDS)];
+} Cx = {
+        {
+            /* Note endian-neutral representation:-) */
+            LL(0x18, 0x18, 0x60, 0x18, 0xc0, 0x78, 0x30, 0xd8),
+            LL(0x23, 0x23, 0x8c, 0x23, 0x05, 0xaf, 0x46, 0x26),
+            LL(0xc6, 0xc6, 0x3f, 0xc6, 0x7e, 0xf9, 0x91, 0xb8),
+            LL(0xe8, 0xe8, 0x87, 0xe8, 0x13, 0x6f, 0xcd, 0xfb),
+            LL(0x87, 0x87, 0x26, 0x87, 0x4c, 0xa1, 0x13, 0xcb),
+            LL(0xb8, 0xb8, 0xda, 0xb8, 0xa9, 0x62, 0x6d, 0x11),
+            LL(0x01, 0x01, 0x04, 0x01, 0x08, 0x05, 0x02, 0x09),
+            LL(0x4f, 0x4f, 0x21, 0x4f, 0x42, 0x6e, 0x9e, 0x0d),
+            LL(0x36, 0x36, 0xd8, 0x36, 0xad, 0xee, 0x6c, 0x9b),
+            LL(0xa6, 0xa6, 0xa2, 0xa6, 0x59, 0x04, 0x51, 0xff),
+            LL(0xd2, 0xd2, 0x6f, 0xd2, 0xde, 0xbd, 0xb9, 0x0c),
+            LL(0xf5, 0xf5, 0xf3, 0xf5, 0xfb, 0x06, 0xf7, 0x0e),
+            LL(0x79, 0x79, 0xf9, 0x79, 0xef, 0x80, 0xf2, 0x96),
+            LL(0x6f, 0x6f, 0xa1, 0x6f, 0x5f, 0xce, 0xde, 0x30),
+            LL(0x91, 0x91, 0x7e, 0x91, 0xfc, 0xef, 0x3f, 0x6d),
+            LL(0x52, 0x52, 0x55, 0x52, 0xaa, 0x07, 0xa4, 0xf8),
+            LL(0x60, 0x60, 0x9d, 0x60, 0x27, 0xfd, 0xc0, 0x47),
+            LL(0xbc, 0xbc, 0xca, 0xbc, 0x89, 0x76, 0x65, 0x35),
+            LL(0x9b, 0x9b, 0x56, 0x9b, 0xac, 0xcd, 0x2b, 0x37),
+            LL(0x8e, 0x8e, 0x02, 0x8e, 0x04, 0x8c, 0x01, 0x8a),
+            LL(0xa3, 0xa3, 0xb6, 0xa3, 0x71, 0x15, 0x5b, 0xd2),
+            LL(0x0c, 0x0c, 0x30, 0x0c, 0x60, 0x3c, 0x18, 0x6c),
+            LL(0x7b, 0x7b, 0xf1, 0x7b, 0xff, 0x8a, 0xf6, 0x84),
+            LL(0x35, 0x35, 0xd4, 0x35, 0xb5, 0xe1, 0x6a, 0x80),
+            LL(0x1d, 0x1d, 0x74, 0x1d, 0xe8, 0x69, 0x3a, 0xf5),
+            LL(0xe0, 0xe0, 0xa7, 0xe0, 0x53, 0x47, 0xdd, 0xb3),
+            LL(0xd7, 0xd7, 0x7b, 0xd7, 0xf6, 0xac, 0xb3, 0x21),
+            LL(0xc2, 0xc2, 0x2f, 0xc2, 0x5e, 0xed, 0x99, 0x9c),
+            LL(0x2e, 0x2e, 0xb8, 0x2e, 0x6d, 0x96, 0x5c, 0x43),
+            LL(0x4b, 0x4b, 0x31, 0x4b, 0x62, 0x7a, 0x96, 0x29),
+            LL(0xfe, 0xfe, 0xdf, 0xfe, 0xa3, 0x21, 0xe1, 0x5d),
+            LL(0x57, 0x57, 0x41, 0x57, 0x82, 0x16, 0xae, 0xd5),
+            LL(0x15, 0x15, 0x54, 0x15, 0xa8, 0x41, 0x2a, 0xbd),
+            LL(0x77, 0x77, 0xc1, 0x77, 0x9f, 0xb6, 0xee, 0xe8),
+            LL(0x37, 0x37, 0xdc, 0x37, 0xa5, 0xeb, 0x6e, 0x92),
+            LL(0xe5, 0xe5, 0xb3, 0xe5, 0x7b, 0x56, 0xd7, 0x9e),
+            LL(0x9f, 0x9f, 0x46, 0x9f, 0x8c, 0xd9, 0x23, 0x13),
+            LL(0xf0, 0xf0, 0xe7, 0xf0, 0xd3, 0x17, 0xfd, 0x23),
+            LL(0x4a, 0x4a, 0x35, 0x4a, 0x6a, 0x7f, 0x94, 0x20),
+            LL(0xda, 0xda, 0x4f, 0xda, 0x9e, 0x95, 0xa9, 0x44),
+            LL(0x58, 0x58, 0x7d, 0x58, 0xfa, 0x25, 0xb0, 0xa2),
+            LL(0xc9, 0xc9, 0x03, 0xc9, 0x06, 0xca, 0x8f, 0xcf),
+            LL(0x29, 0x29, 0xa4, 0x29, 0x55, 0x8d, 0x52, 0x7c),
+            LL(0x0a, 0x0a, 0x28, 0x0a, 0x50, 0x22, 0x14, 0x5a),
+            LL(0xb1, 0xb1, 0xfe, 0xb1, 0xe1, 0x4f, 0x7f, 0x50),
+            LL(0xa0, 0xa0, 0xba, 0xa0, 0x69, 0x1a, 0x5d, 0xc9),
+            LL(0x6b, 0x6b, 0xb1, 0x6b, 0x7f, 0xda, 0xd6, 0x14),
+            LL(0x85, 0x85, 0x2e, 0x85, 0x5c, 0xab, 0x17, 0xd9),
+            LL(0xbd, 0xbd, 0xce, 0xbd, 0x81, 0x73, 0x67, 0x3c),
+            LL(0x5d, 0x5d, 0x69, 0x5d, 0xd2, 0x34, 0xba, 0x8f),
+            LL(0x10, 0x10, 0x40, 0x10, 0x80, 0x50, 0x20, 0x90),
+            LL(0xf4, 0xf4, 0xf7, 0xf4, 0xf3, 0x03, 0xf5, 0x07),
+            LL(0xcb, 0xcb, 0x0b, 0xcb, 0x16, 0xc0, 0x8b, 0xdd),
+            LL(0x3e, 0x3e, 0xf8, 0x3e, 0xed, 0xc6, 0x7c, 0xd3),
+            LL(0x05, 0x05, 0x14, 0x05, 0x28, 0x11, 0x0a, 0x2d),
+            LL(0x67, 0x67, 0x81, 0x67, 0x1f, 0xe6, 0xce, 0x78),
+            LL(0xe4, 0xe4, 0xb7, 0xe4, 0x73, 0x53, 0xd5, 0x97),
+            LL(0x27, 0x27, 0x9c, 0x27, 0x25, 0xbb, 0x4e, 0x02),
+            LL(0x41, 0x41, 0x19, 0x41, 0x32, 0x58, 0x82, 0x73),
+            LL(0x8b, 0x8b, 0x16, 0x8b, 0x2c, 0x9d, 0x0b, 0xa7),
+            LL(0xa7, 0xa7, 0xa6, 0xa7, 0x51, 0x01, 0x53, 0xf6),
+            LL(0x7d, 0x7d, 0xe9, 0x7d, 0xcf, 0x94, 0xfa, 0xb2),
+            LL(0x95, 0x95, 0x6e, 0x95, 0xdc, 0xfb, 0x37, 0x49),
+            LL(0xd8, 0xd8, 0x47, 0xd8, 0x8e, 0x9f, 0xad, 0x56),
+            LL(0xfb, 0xfb, 0xcb, 0xfb, 0x8b, 0x30, 0xeb, 0x70),
+            LL(0xee, 0xee, 0x9f, 0xee, 0x23, 0x71, 0xc1, 0xcd),
+            LL(0x7c, 0x7c, 0xed, 0x7c, 0xc7, 0x91, 0xf8, 0xbb),
+            LL(0x66, 0x66, 0x85, 0x66, 0x17, 0xe3, 0xcc, 0x71),
+            LL(0xdd, 0xdd, 0x53, 0xdd, 0xa6, 0x8e, 0xa7, 0x7b),
+            LL(0x17, 0x17, 0x5c, 0x17, 0xb8, 0x4b, 0x2e, 0xaf),
+            LL(0x47, 0x47, 0x01, 0x47, 0x02, 0x46, 0x8e, 0x45),
+            LL(0x9e, 0x9e, 0x42, 0x9e, 0x84, 0xdc, 0x21, 0x1a),
+            LL(0xca, 0xca, 0x0f, 0xca, 0x1e, 0xc5, 0x89, 0xd4),
+            LL(0x2d, 0x2d, 0xb4, 0x2d, 0x75, 0x99, 0x5a, 0x58),
+            LL(0xbf, 0xbf, 0xc6, 0xbf, 0x91, 0x79, 0x63, 0x2e),
+            LL(0x07, 0x07, 0x1c, 0x07, 0x38, 0x1b, 0x0e, 0x3f),
+            LL(0xad, 0xad, 0x8e, 0xad, 0x01, 0x23, 0x47, 0xac),
+            LL(0x5a, 0x5a, 0x75, 0x5a, 0xea, 0x2f, 0xb4, 0xb0),
+            LL(0x83, 0x83, 0x36, 0x83, 0x6c, 0xb5, 0x1b, 0xef),
+            LL(0x33, 0x33, 0xcc, 0x33, 0x85, 0xff, 0x66, 0xb6),
+            LL(0x63, 0x63, 0x91, 0x63, 0x3f, 0xf2, 0xc6, 0x5c),
+            LL(0x02, 0x02, 0x08, 0x02, 0x10, 0x0a, 0x04, 0x12),
+            LL(0xaa, 0xaa, 0x92, 0xaa, 0x39, 0x38, 0x49, 0x93),
+            LL(0x71, 0x71, 0xd9, 0x71, 0xaf, 0xa8, 0xe2, 0xde),
+            LL(0xc8, 0xc8, 0x07, 0xc8, 0x0e, 0xcf, 0x8d, 0xc6),
+            LL(0x19, 0x19, 0x64, 0x19, 0xc8, 0x7d, 0x32, 0xd1),
+            LL(0x49, 0x49, 0x39, 0x49, 0x72, 0x70, 0x92, 0x3b),
+            LL(0xd9, 0xd9, 0x43, 0xd9, 0x86, 0x9a, 0xaf, 0x5f),
+            LL(0xf2, 0xf2, 0xef, 0xf2, 0xc3, 0x1d, 0xf9, 0x31),
+            LL(0xe3, 0xe3, 0xab, 0xe3, 0x4b, 0x48, 0xdb, 0xa8),
+            LL(0x5b, 0x5b, 0x71, 0x5b, 0xe2, 0x2a, 0xb6, 0xb9),
+            LL(0x88, 0x88, 0x1a, 0x88, 0x34, 0x92, 0x0d, 0xbc),
+            LL(0x9a, 0x9a, 0x52, 0x9a, 0xa4, 0xc8, 0x29, 0x3e),
+            LL(0x26, 0x26, 0x98, 0x26, 0x2d, 0xbe, 0x4c, 0x0b),
+            LL(0x32, 0x32, 0xc8, 0x32, 0x8d, 0xfa, 0x64, 0xbf),
+            LL(0xb0, 0xb0, 0xfa, 0xb0, 0xe9, 0x4a, 0x7d, 0x59),
+            LL(0xe9, 0xe9, 0x83, 0xe9, 0x1b, 0x6a, 0xcf, 0xf2),
+            LL(0x0f, 0x0f, 0x3c, 0x0f, 0x78, 0x33, 0x1e, 0x77),
+            LL(0xd5, 0xd5, 0x73, 0xd5, 0xe6, 0xa6, 0xb7, 0x33),
+            LL(0x80, 0x80, 0x3a, 0x80, 0x74, 0xba, 0x1d, 0xf4),
+            LL(0xbe, 0xbe, 0xc2, 0xbe, 0x99, 0x7c, 0x61, 0x27),
+            LL(0xcd, 0xcd, 0x13, 0xcd, 0x26, 0xde, 0x87, 0xeb),
+            LL(0x34, 0x34, 0xd0, 0x34, 0xbd, 0xe4, 0x68, 0x89),
+            LL(0x48, 0x48, 0x3d, 0x48, 0x7a, 0x75, 0x90, 0x32),
+            LL(0xff, 0xff, 0xdb, 0xff, 0xab, 0x24, 0xe3, 0x54),
+            LL(0x7a, 0x7a, 0xf5, 0x7a, 0xf7, 0x8f, 0xf4, 0x8d),
+            LL(0x90, 0x90, 0x7a, 0x90, 0xf4, 0xea, 0x3d, 0x64),
+            LL(0x5f, 0x5f, 0x61, 0x5f, 0xc2, 0x3e, 0xbe, 0x9d),
+            LL(0x20, 0x20, 0x80, 0x20, 0x1d, 0xa0, 0x40, 0x3d),
+            LL(0x68, 0x68, 0xbd, 0x68, 0x67, 0xd5, 0xd0, 0x0f),
+            LL(0x1a, 0x1a, 0x68, 0x1a, 0xd0, 0x72, 0x34, 0xca),
+            LL(0xae, 0xae, 0x82, 0xae, 0x19, 0x2c, 0x41, 0xb7),
+            LL(0xb4, 0xb4, 0xea, 0xb4, 0xc9, 0x5e, 0x75, 0x7d),
+            LL(0x54, 0x54, 0x4d, 0x54, 0x9a, 0x19, 0xa8, 0xce),
+            LL(0x93, 0x93, 0x76, 0x93, 0xec, 0xe5, 0x3b, 0x7f),
+            LL(0x22, 0x22, 0x88, 0x22, 0x0d, 0xaa, 0x44, 0x2f),
+            LL(0x64, 0x64, 0x8d, 0x64, 0x07, 0xe9, 0xc8, 0x63),
+            LL(0xf1, 0xf1, 0xe3, 0xf1, 0xdb, 0x12, 0xff, 0x2a),
+            LL(0x73, 0x73, 0xd1, 0x73, 0xbf, 0xa2, 0xe6, 0xcc),
+            LL(0x12, 0x12, 0x48, 0x12, 0x90, 0x5a, 0x24, 0x82),
+            LL(0x40, 0x40, 0x1d, 0x40, 0x3a, 0x5d, 0x80, 0x7a),
+            LL(0x08, 0x08, 0x20, 0x08, 0x40, 0x28, 0x10, 0x48),
+            LL(0xc3, 0xc3, 0x2b, 0xc3, 0x56, 0xe8, 0x9b, 0x95),
+            LL(0xec, 0xec, 0x97, 0xec, 0x33, 0x7b, 0xc5, 0xdf),
+            LL(0xdb, 0xdb, 0x4b, 0xdb, 0x96, 0x90, 0xab, 0x4d),
+            LL(0xa1, 0xa1, 0xbe, 0xa1, 0x61, 0x1f, 0x5f, 0xc0),
+            LL(0x8d, 0x8d, 0x0e, 0x8d, 0x1c, 0x83, 0x07, 0x91),
+            LL(0x3d, 0x3d, 0xf4, 0x3d, 0xf5, 0xc9, 0x7a, 0xc8),
+            LL(0x97, 0x97, 0x66, 0x97, 0xcc, 0xf1, 0x33, 0x5b),
+            LL(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
+            LL(0xcf, 0xcf, 0x1b, 0xcf, 0x36, 0xd4, 0x83, 0xf9),
+            LL(0x2b, 0x2b, 0xac, 0x2b, 0x45, 0x87, 0x56, 0x6e),
+            LL(0x76, 0x76, 0xc5, 0x76, 0x97, 0xb3, 0xec, 0xe1),
+            LL(0x82, 0x82, 0x32, 0x82, 0x64, 0xb0, 0x19, 0xe6),
+            LL(0xd6, 0xd6, 0x7f, 0xd6, 0xfe, 0xa9, 0xb1, 0x28),
+            LL(0x1b, 0x1b, 0x6c, 0x1b, 0xd8, 0x77, 0x36, 0xc3),
+            LL(0xb5, 0xb5, 0xee, 0xb5, 0xc1, 0x5b, 0x77, 0x74),
+            LL(0xaf, 0xaf, 0x86, 0xaf, 0x11, 0x29, 0x43, 0xbe),
+            LL(0x6a, 0x6a, 0xb5, 0x6a, 0x77, 0xdf, 0xd4, 0x1d),
+            LL(0x50, 0x50, 0x5d, 0x50, 0xba, 0x0d, 0xa0, 0xea),
+            LL(0x45, 0x45, 0x09, 0x45, 0x12, 0x4c, 0x8a, 0x57),
+            LL(0xf3, 0xf3, 0xeb, 0xf3, 0xcb, 0x18, 0xfb, 0x38),
+            LL(0x30, 0x30, 0xc0, 0x30, 0x9d, 0xf0, 0x60, 0xad),
+            LL(0xef, 0xef, 0x9b, 0xef, 0x2b, 0x74, 0xc3, 0xc4),
+            LL(0x3f, 0x3f, 0xfc, 0x3f, 0xe5, 0xc3, 0x7e, 0xda),
+            LL(0x55, 0x55, 0x49, 0x55, 0x92, 0x1c, 0xaa, 0xc7),
+            LL(0xa2, 0xa2, 0xb2, 0xa2, 0x79, 0x10, 0x59, 0xdb),
+            LL(0xea, 0xea, 0x8f, 0xea, 0x03, 0x65, 0xc9, 0xe9),
+            LL(0x65, 0x65, 0x89, 0x65, 0x0f, 0xec, 0xca, 0x6a),
+            LL(0xba, 0xba, 0xd2, 0xba, 0xb9, 0x68, 0x69, 0x03),
+            LL(0x2f, 0x2f, 0xbc, 0x2f, 0x65, 0x93, 0x5e, 0x4a),
+            LL(0xc0, 0xc0, 0x27, 0xc0, 0x4e, 0xe7, 0x9d, 0x8e),
+            LL(0xde, 0xde, 0x5f, 0xde, 0xbe, 0x81, 0xa1, 0x60),
+            LL(0x1c, 0x1c, 0x70, 0x1c, 0xe0, 0x6c, 0x38, 0xfc),
+            LL(0xfd, 0xfd, 0xd3, 0xfd, 0xbb, 0x2e, 0xe7, 0x46),
+            LL(0x4d, 0x4d, 0x29, 0x4d, 0x52, 0x64, 0x9a, 0x1f),
+            LL(0x92, 0x92, 0x72, 0x92, 0xe4, 0xe0, 0x39, 0x76),
+            LL(0x75, 0x75, 0xc9, 0x75, 0x8f, 0xbc, 0xea, 0xfa),
+            LL(0x06, 0x06, 0x18, 0x06, 0x30, 0x1e, 0x0c, 0x36),
+            LL(0x8a, 0x8a, 0x12, 0x8a, 0x24, 0x98, 0x09, 0xae),
+            LL(0xb2, 0xb2, 0xf2, 0xb2, 0xf9, 0x40, 0x79, 0x4b),
+            LL(0xe6, 0xe6, 0xbf, 0xe6, 0x63, 0x59, 0xd1, 0x85),
+            LL(0x0e, 0x0e, 0x38, 0x0e, 0x70, 0x36, 0x1c, 0x7e),
+            LL(0x1f, 0x1f, 0x7c, 0x1f, 0xf8, 0x63, 0x3e, 0xe7),
+            LL(0x62, 0x62, 0x95, 0x62, 0x37, 0xf7, 0xc4, 0x55),
+            LL(0xd4, 0xd4, 0x77, 0xd4, 0xee, 0xa3, 0xb5, 0x3a),
+            LL(0xa8, 0xa8, 0x9a, 0xa8, 0x29, 0x32, 0x4d, 0x81),
+            LL(0x96, 0x96, 0x62, 0x96, 0xc4, 0xf4, 0x31, 0x52),
+            LL(0xf9, 0xf9, 0xc3, 0xf9, 0x9b, 0x3a, 0xef, 0x62),
+            LL(0xc5, 0xc5, 0x33, 0xc5, 0x66, 0xf6, 0x97, 0xa3),
+            LL(0x25, 0x25, 0x94, 0x25, 0x35, 0xb1, 0x4a, 0x10),
+            LL(0x59, 0x59, 0x79, 0x59, 0xf2, 0x20, 0xb2, 0xab),
+            LL(0x84, 0x84, 0x2a, 0x84, 0x54, 0xae, 0x15, 0xd0),
+            LL(0x72, 0x72, 0xd5, 0x72, 0xb7, 0xa7, 0xe4, 0xc5),
+            LL(0x39, 0x39, 0xe4, 0x39, 0xd5, 0xdd, 0x72, 0xec),
+            LL(0x4c, 0x4c, 0x2d, 0x4c, 0x5a, 0x61, 0x98, 0x16),
+            LL(0x5e, 0x5e, 0x65, 0x5e, 0xca, 0x3b, 0xbc, 0x94),
+            LL(0x78, 0x78, 0xfd, 0x78, 0xe7, 0x85, 0xf0, 0x9f),
+            LL(0x38, 0x38, 0xe0, 0x38, 0xdd, 0xd8, 0x70, 0xe5),
+            LL(0x8c, 0x8c, 0x0a, 0x8c, 0x14, 0x86, 0x05, 0x98),
+            LL(0xd1, 0xd1, 0x63, 0xd1, 0xc6, 0xb2, 0xbf, 0x17),
+            LL(0xa5, 0xa5, 0xae, 0xa5, 0x41, 0x0b, 0x57, 0xe4),
+            LL(0xe2, 0xe2, 0xaf, 0xe2, 0x43, 0x4d, 0xd9, 0xa1),
+            LL(0x61, 0x61, 0x99, 0x61, 0x2f, 0xf8, 0xc2, 0x4e),
+            LL(0xb3, 0xb3, 0xf6, 0xb3, 0xf1, 0x45, 0x7b, 0x42),
+            LL(0x21, 0x21, 0x84, 0x21, 0x15, 0xa5, 0x42, 0x34),
+            LL(0x9c, 0x9c, 0x4a, 0x9c, 0x94, 0xd6, 0x25, 0x08),
+            LL(0x1e, 0x1e, 0x78, 0x1e, 0xf0, 0x66, 0x3c, 0xee),
+            LL(0x43, 0x43, 0x11, 0x43, 0x22, 0x52, 0x86, 0x61),
+            LL(0xc7, 0xc7, 0x3b, 0xc7, 0x76, 0xfc, 0x93, 0xb1),
+            LL(0xfc, 0xfc, 0xd7, 0xfc, 0xb3, 0x2b, 0xe5, 0x4f),
+            LL(0x04, 0x04, 0x10, 0x04, 0x20, 0x14, 0x08, 0x24),
+            LL(0x51, 0x51, 0x59, 0x51, 0xb2, 0x08, 0xa2, 0xe3),
+            LL(0x99, 0x99, 0x5e, 0x99, 0xbc, 0xc7, 0x2f, 0x25),
+            LL(0x6d, 0x6d, 0xa9, 0x6d, 0x4f, 0xc4, 0xda, 0x22),
+            LL(0x0d, 0x0d, 0x34, 0x0d, 0x68, 0x39, 0x1a, 0x65),
+            LL(0xfa, 0xfa, 0xcf, 0xfa, 0x83, 0x35, 0xe9, 0x79),
+            LL(0xdf, 0xdf, 0x5b, 0xdf, 0xb6, 0x84, 0xa3, 0x69),
+            LL(0x7e, 0x7e, 0xe5, 0x7e, 0xd7, 0x9b, 0xfc, 0xa9),
+            LL(0x24, 0x24, 0x90, 0x24, 0x3d, 0xb4, 0x48, 0x19),
+            LL(0x3b, 0x3b, 0xec, 0x3b, 0xc5, 0xd7, 0x76, 0xfe),
+            LL(0xab, 0xab, 0x96, 0xab, 0x31, 0x3d, 0x4b, 0x9a),
+            LL(0xce, 0xce, 0x1f, 0xce, 0x3e, 0xd1, 0x81, 0xf0),
+            LL(0x11, 0x11, 0x44, 0x11, 0x88, 0x55, 0x22, 0x99),
+            LL(0x8f, 0x8f, 0x06, 0x8f, 0x0c, 0x89, 0x03, 0x83),
+            LL(0x4e, 0x4e, 0x25, 0x4e, 0x4a, 0x6b, 0x9c, 0x04),
+            LL(0xb7, 0xb7, 0xe6, 0xb7, 0xd1, 0x51, 0x73, 0x66),
+            LL(0xeb, 0xeb, 0x8b, 0xeb, 0x0b, 0x60, 0xcb, 0xe0),
+            LL(0x3c, 0x3c, 0xf0, 0x3c, 0xfd, 0xcc, 0x78, 0xc1),
+            LL(0x81, 0x81, 0x3e, 0x81, 0x7c, 0xbf, 0x1f, 0xfd),
+            LL(0x94, 0x94, 0x6a, 0x94, 0xd4, 0xfe, 0x35, 0x40),
+            LL(0xf7, 0xf7, 0xfb, 0xf7, 0xeb, 0x0c, 0xf3, 0x1c),
+            LL(0xb9, 0xb9, 0xde, 0xb9, 0xa1, 0x67, 0x6f, 0x18),
+            LL(0x13, 0x13, 0x4c, 0x13, 0x98, 0x5f, 0x26, 0x8b),
+            LL(0x2c, 0x2c, 0xb0, 0x2c, 0x7d, 0x9c, 0x58, 0x51),
+            LL(0xd3, 0xd3, 0x6b, 0xd3, 0xd6, 0xb8, 0xbb, 0x05),
+            LL(0xe7, 0xe7, 0xbb, 0xe7, 0x6b, 0x5c, 0xd3, 0x8c),
+            LL(0x6e, 0x6e, 0xa5, 0x6e, 0x57, 0xcb, 0xdc, 0x39),
+            LL(0xc4, 0xc4, 0x37, 0xc4, 0x6e, 0xf3, 0x95, 0xaa),
+            LL(0x03, 0x03, 0x0c, 0x03, 0x18, 0x0f, 0x06, 0x1b),
+            LL(0x56, 0x56, 0x45, 0x56, 0x8a, 0x13, 0xac, 0xdc),
+            LL(0x44, 0x44, 0x0d, 0x44, 0x1a, 0x49, 0x88, 0x5e),
+            LL(0x7f, 0x7f, 0xe1, 0x7f, 0xdf, 0x9e, 0xfe, 0xa0),
+            LL(0xa9, 0xa9, 0x9e, 0xa9, 0x21, 0x37, 0x4f, 0x88),
+            LL(0x2a, 0x2a, 0xa8, 0x2a, 0x4d, 0x82, 0x54, 0x67),
+            LL(0xbb, 0xbb, 0xd6, 0xbb, 0xb1, 0x6d, 0x6b, 0x0a),
+            LL(0xc1, 0xc1, 0x23, 0xc1, 0x46, 0xe2, 0x9f, 0x87),
+            LL(0x53, 0x53, 0x51, 0x53, 0xa2, 0x02, 0xa6, 0xf1),
+            LL(0xdc, 0xdc, 0x57, 0xdc, 0xae, 0x8b, 0xa5, 0x72),
+            LL(0x0b, 0x0b, 0x2c, 0x0b, 0x58, 0x27, 0x16, 0x53),
+            LL(0x9d, 0x9d, 0x4e, 0x9d, 0x9c, 0xd3, 0x27, 0x01),
+            LL(0x6c, 0x6c, 0xad, 0x6c, 0x47, 0xc1, 0xd8, 0x2b),
+            LL(0x31, 0x31, 0xc4, 0x31, 0x95, 0xf5, 0x62, 0xa4),
+            LL(0x74, 0x74, 0xcd, 0x74, 0x87, 0xb9, 0xe8, 0xf3),
+            LL(0xf6, 0xf6, 0xff, 0xf6, 0xe3, 0x09, 0xf1, 0x15),
+            LL(0x46, 0x46, 0x05, 0x46, 0x0a, 0x43, 0x8c, 0x4c),
+            LL(0xac, 0xac, 0x8a, 0xac, 0x09, 0x26, 0x45, 0xa5),
+            LL(0x89, 0x89, 0x1e, 0x89, 0x3c, 0x97, 0x0f, 0xb5),
+            LL(0x14, 0x14, 0x50, 0x14, 0xa0, 0x44, 0x28, 0xb4),
+            LL(0xe1, 0xe1, 0xa3, 0xe1, 0x5b, 0x42, 0xdf, 0xba),
+            LL(0x16, 0x16, 0x58, 0x16, 0xb0, 0x4e, 0x2c, 0xa6),
+            LL(0x3a, 0x3a, 0xe8, 0x3a, 0xcd, 0xd2, 0x74, 0xf7),
+            LL(0x69, 0x69, 0xb9, 0x69, 0x6f, 0xd0, 0xd2, 0x06),
+            LL(0x09, 0x09, 0x24, 0x09, 0x48, 0x2d, 0x12, 0x41),
+            LL(0x70, 0x70, 0xdd, 0x70, 0xa7, 0xad, 0xe0, 0xd7),
+            LL(0xb6, 0xb6, 0xe2, 0xb6, 0xd9, 0x54, 0x71, 0x6f),
+            LL(0xd0, 0xd0, 0x67, 0xd0, 0xce, 0xb7, 0xbd, 0x1e),
+            LL(0xed, 0xed, 0x93, 0xed, 0x3b, 0x7e, 0xc7, 0xd6),
+            LL(0xcc, 0xcc, 0x17, 0xcc, 0x2e, 0xdb, 0x85, 0xe2),
+            LL(0x42, 0x42, 0x15, 0x42, 0x2a, 0x57, 0x84, 0x68),
+            LL(0x98, 0x98, 0x5a, 0x98, 0xb4, 0xc2, 0x2d, 0x2c),
+            LL(0xa4, 0xa4, 0xaa, 0xa4, 0x49, 0x0e, 0x55, 0xed),
+            LL(0x28, 0x28, 0xa0, 0x28, 0x5d, 0x88, 0x50, 0x75),
+            LL(0x5c, 0x5c, 0x6d, 0x5c, 0xda, 0x31, 0xb8, 0x86),
+            LL(0xf8, 0xf8, 0xc7, 0xf8, 0x93, 0x3f, 0xed, 0x6b),
+            LL(0x86, 0x86, 0x22, 0x86, 0x44, 0xa4, 0x11, 0xc2),
+#define RC      (&(Cx.q[256*N]))
+            0x18, 0x23, 0xc6, 0xe8, 0x87, 0xb8, 0x01, 0x4f,
+            /* rc[ROUNDS] */
+            0x36, 0xa6, 0xd2, 0xf5, 0x79, 0x6f, 0x91, 0x52, 0x60, 0xbc, 0x9b,
+            0x8e, 0xa3, 0x0c, 0x7b, 0x35, 0x1d, 0xe0, 0xd7, 0xc2, 0x2e, 0x4b,
+            0xfe, 0x57, 0x15, 0x77, 0x37, 0xe5, 0x9f, 0xf0, 0x4a, 0xda, 0x58,
+            0xc9, 0x29, 0x0a, 0xb1, 0xa0, 0x6b, 0x85, 0xbd, 0x5d, 0x10, 0xf4,
+            0xcb, 0x3e, 0x05, 0x67, 0xe4, 0x27, 0x41, 0x8b, 0xa7, 0x7d, 0x95,
+            0xd8, 0xfb, 0xee, 0x7c, 0x66, 0xdd, 0x17, 0x47, 0x9e, 0xca, 0x2d,
+            0xbf, 0x07, 0xad, 0x5a, 0x83, 0x33
+        }
+    };
+
+void whirlpool_block(WHIRLPOOL_CTX *ctx, const void *inp, size_t n)
+{
+    int r;
+    const u8 *p = inp;
+    union {
+        u64 q[8];
+        u8 c[64];
+    } S, K, *H = (void *)ctx->H.q;
+
+#ifdef GO_FOR_MMX
+    GO_FOR_MMX(ctx, inp, n);
+#endif
+    do {
+#ifdef OPENSSL_SMALL_FOOTPRINT
+        u64 L[8];
+        int i;
+
+        for (i = 0; i < 64; i++)
+            S.c[i] = (K.c[i] = H->c[i]) ^ p[i];
+        for (r = 0; r < ROUNDS; r++) {
+            for (i = 0; i < 8; i++) {
+                L[i] = i ? 0 : RC[r];
+                L[i] ^= C0(K, i) ^ C1(K, (i - 1) & 7) ^
+                    C2(K, (i - 2) & 7) ^ C3(K, (i - 3) & 7) ^
+                    C4(K, (i - 4) & 7) ^ C5(K, (i - 5) & 7) ^
+                    C6(K, (i - 6) & 7) ^ C7(K, (i - 7) & 7);
+            }
+            memcpy(K.q, L, 64);
+            for (i = 0; i < 8; i++) {
+                L[i] ^= C0(S, i) ^ C1(S, (i - 1) & 7) ^
+                    C2(S, (i - 2) & 7) ^ C3(S, (i - 3) & 7) ^
+                    C4(S, (i - 4) & 7) ^ C5(S, (i - 5) & 7) ^
+                    C6(S, (i - 6) & 7) ^ C7(S, (i - 7) & 7);
+            }
+            memcpy(S.q, L, 64);
+        }
+        for (i = 0; i < 64; i++)
+            H->c[i] ^= S.c[i] ^ p[i];
+#else
+        u64 L0, L1, L2, L3, L4, L5, L6, L7;
+
+# ifdef STRICT_ALIGNMENT
+        if ((size_t)p & 7) {
+            memcpy(S.c, p, 64);
+            S.q[0] ^= (K.q[0] = H->q[0]);
+            S.q[1] ^= (K.q[1] = H->q[1]);
+            S.q[2] ^= (K.q[2] = H->q[2]);
+            S.q[3] ^= (K.q[3] = H->q[3]);
+            S.q[4] ^= (K.q[4] = H->q[4]);
+            S.q[5] ^= (K.q[5] = H->q[5]);
+            S.q[6] ^= (K.q[6] = H->q[6]);
+            S.q[7] ^= (K.q[7] = H->q[7]);
+        } else
+# endif
+        {
+            const u64 *pa = (const u64 *)p;
+            S.q[0] = (K.q[0] = H->q[0]) ^ pa[0];
+            S.q[1] = (K.q[1] = H->q[1]) ^ pa[1];
+            S.q[2] = (K.q[2] = H->q[2]) ^ pa[2];
+            S.q[3] = (K.q[3] = H->q[3]) ^ pa[3];
+            S.q[4] = (K.q[4] = H->q[4]) ^ pa[4];
+            S.q[5] = (K.q[5] = H->q[5]) ^ pa[5];
+            S.q[6] = (K.q[6] = H->q[6]) ^ pa[6];
+            S.q[7] = (K.q[7] = H->q[7]) ^ pa[7];
+        }
+
+        for (r = 0; r < ROUNDS; r++) {
+# ifdef SMALL_REGISTER_BANK
+            L0 = C0(K, 0) ^ C1(K, 7) ^ C2(K, 6) ^ C3(K, 5) ^
+                C4(K, 4) ^ C5(K, 3) ^ C6(K, 2) ^ C7(K, 1) ^ RC[r];
+            L1 = C0(K, 1) ^ C1(K, 0) ^ C2(K, 7) ^ C3(K, 6) ^
+                C4(K, 5) ^ C5(K, 4) ^ C6(K, 3) ^ C7(K, 2);
+            L2 = C0(K, 2) ^ C1(K, 1) ^ C2(K, 0) ^ C3(K, 7) ^
+                C4(K, 6) ^ C5(K, 5) ^ C6(K, 4) ^ C7(K, 3);
+            L3 = C0(K, 3) ^ C1(K, 2) ^ C2(K, 1) ^ C3(K, 0) ^
+                C4(K, 7) ^ C5(K, 6) ^ C6(K, 5) ^ C7(K, 4);
+            L4 = C0(K, 4) ^ C1(K, 3) ^ C2(K, 2) ^ C3(K, 1) ^
+                C4(K, 0) ^ C5(K, 7) ^ C6(K, 6) ^ C7(K, 5);
+            L5 = C0(K, 5) ^ C1(K, 4) ^ C2(K, 3) ^ C3(K, 2) ^
+                C4(K, 1) ^ C5(K, 0) ^ C6(K, 7) ^ C7(K, 6);
+            L6 = C0(K, 6) ^ C1(K, 5) ^ C2(K, 4) ^ C3(K, 3) ^
+                C4(K, 2) ^ C5(K, 1) ^ C6(K, 0) ^ C7(K, 7);
+            L7 = C0(K, 7) ^ C1(K, 6) ^ C2(K, 5) ^ C3(K, 4) ^
+                C4(K, 3) ^ C5(K, 2) ^ C6(K, 1) ^ C7(K, 0);
+
+            K.q[0] = L0;
+            K.q[1] = L1;
+            K.q[2] = L2;
+            K.q[3] = L3;
+            K.q[4] = L4;
+            K.q[5] = L5;
+            K.q[6] = L6;
+            K.q[7] = L7;
+
+            L0 ^= C0(S, 0) ^ C1(S, 7) ^ C2(S, 6) ^ C3(S, 5) ^
+                C4(S, 4) ^ C5(S, 3) ^ C6(S, 2) ^ C7(S, 1);
+            L1 ^= C0(S, 1) ^ C1(S, 0) ^ C2(S, 7) ^ C3(S, 6) ^
+                C4(S, 5) ^ C5(S, 4) ^ C6(S, 3) ^ C7(S, 2);
+            L2 ^= C0(S, 2) ^ C1(S, 1) ^ C2(S, 0) ^ C3(S, 7) ^
+                C4(S, 6) ^ C5(S, 5) ^ C6(S, 4) ^ C7(S, 3);
+            L3 ^= C0(S, 3) ^ C1(S, 2) ^ C2(S, 1) ^ C3(S, 0) ^
+                C4(S, 7) ^ C5(S, 6) ^ C6(S, 5) ^ C7(S, 4);
+            L4 ^= C0(S, 4) ^ C1(S, 3) ^ C2(S, 2) ^ C3(S, 1) ^
+                C4(S, 0) ^ C5(S, 7) ^ C6(S, 6) ^ C7(S, 5);
+            L5 ^= C0(S, 5) ^ C1(S, 4) ^ C2(S, 3) ^ C3(S, 2) ^
+                C4(S, 1) ^ C5(S, 0) ^ C6(S, 7) ^ C7(S, 6);
+            L6 ^= C0(S, 6) ^ C1(S, 5) ^ C2(S, 4) ^ C3(S, 3) ^
+                C4(S, 2) ^ C5(S, 1) ^ C6(S, 0) ^ C7(S, 7);
+            L7 ^= C0(S, 7) ^ C1(S, 6) ^ C2(S, 5) ^ C3(S, 4) ^
+                C4(S, 3) ^ C5(S, 2) ^ C6(S, 1) ^ C7(S, 0);
+
+            S.q[0] = L0;
+            S.q[1] = L1;
+            S.q[2] = L2;
+            S.q[3] = L3;
+            S.q[4] = L4;
+            S.q[5] = L5;
+            S.q[6] = L6;
+            S.q[7] = L7;
+# else
+            L0 = C0(K, 0);
+            L1 = C1(K, 0);
+            L2 = C2(K, 0);
+            L3 = C3(K, 0);
+            L4 = C4(K, 0);
+            L5 = C5(K, 0);
+            L6 = C6(K, 0);
+            L7 = C7(K, 0);
+            L0 ^= RC[r];
+
+            L1 ^= C0(K, 1);
+            L2 ^= C1(K, 1);
+            L3 ^= C2(K, 1);
+            L4 ^= C3(K, 1);
+            L5 ^= C4(K, 1);
+            L6 ^= C5(K, 1);
+            L7 ^= C6(K, 1);
+            L0 ^= C7(K, 1);
+
+            L2 ^= C0(K, 2);
+            L3 ^= C1(K, 2);
+            L4 ^= C2(K, 2);
+            L5 ^= C3(K, 2);
+            L6 ^= C4(K, 2);
+            L7 ^= C5(K, 2);
+            L0 ^= C6(K, 2);
+            L1 ^= C7(K, 2);
+
+            L3 ^= C0(K, 3);
+            L4 ^= C1(K, 3);
+            L5 ^= C2(K, 3);
+            L6 ^= C3(K, 3);
+            L7 ^= C4(K, 3);
+            L0 ^= C5(K, 3);
+            L1 ^= C6(K, 3);
+            L2 ^= C7(K, 3);
+
+            L4 ^= C0(K, 4);
+            L5 ^= C1(K, 4);
+            L6 ^= C2(K, 4);
+            L7 ^= C3(K, 4);
+            L0 ^= C4(K, 4);
+            L1 ^= C5(K, 4);
+            L2 ^= C6(K, 4);
+            L3 ^= C7(K, 4);
+
+            L5 ^= C0(K, 5);
+            L6 ^= C1(K, 5);
+            L7 ^= C2(K, 5);
+            L0 ^= C3(K, 5);
+            L1 ^= C4(K, 5);
+            L2 ^= C5(K, 5);
+            L3 ^= C6(K, 5);
+            L4 ^= C7(K, 5);
+
+            L6 ^= C0(K, 6);
+            L7 ^= C1(K, 6);
+            L0 ^= C2(K, 6);
+            L1 ^= C3(K, 6);
+            L2 ^= C4(K, 6);
+            L3 ^= C5(K, 6);
+            L4 ^= C6(K, 6);
+            L5 ^= C7(K, 6);
+
+            L7 ^= C0(K, 7);
+            L0 ^= C1(K, 7);
+            L1 ^= C2(K, 7);
+            L2 ^= C3(K, 7);
+            L3 ^= C4(K, 7);
+            L4 ^= C5(K, 7);
+            L5 ^= C6(K, 7);
+            L6 ^= C7(K, 7);
+
+            K.q[0] = L0;
+            K.q[1] = L1;
+            K.q[2] = L2;
+            K.q[3] = L3;
+            K.q[4] = L4;
+            K.q[5] = L5;
+            K.q[6] = L6;
+            K.q[7] = L7;
+
+            L0 ^= C0(S, 0);
+            L1 ^= C1(S, 0);
+            L2 ^= C2(S, 0);
+            L3 ^= C3(S, 0);
+            L4 ^= C4(S, 0);
+            L5 ^= C5(S, 0);
+            L6 ^= C6(S, 0);
+            L7 ^= C7(S, 0);
+
+            L1 ^= C0(S, 1);
+            L2 ^= C1(S, 1);
+            L3 ^= C2(S, 1);
+            L4 ^= C3(S, 1);
+            L5 ^= C4(S, 1);
+            L6 ^= C5(S, 1);
+            L7 ^= C6(S, 1);
+            L0 ^= C7(S, 1);
+
+            L2 ^= C0(S, 2);
+            L3 ^= C1(S, 2);
+            L4 ^= C2(S, 2);
+            L5 ^= C3(S, 2);
+            L6 ^= C4(S, 2);
+            L7 ^= C5(S, 2);
+            L0 ^= C6(S, 2);
+            L1 ^= C7(S, 2);
+
+            L3 ^= C0(S, 3);
+            L4 ^= C1(S, 3);
+            L5 ^= C2(S, 3);
+            L6 ^= C3(S, 3);
+            L7 ^= C4(S, 3);
+            L0 ^= C5(S, 3);
+            L1 ^= C6(S, 3);
+            L2 ^= C7(S, 3);
+
+            L4 ^= C0(S, 4);
+            L5 ^= C1(S, 4);
+            L6 ^= C2(S, 4);
+            L7 ^= C3(S, 4);
+            L0 ^= C4(S, 4);
+            L1 ^= C5(S, 4);
+            L2 ^= C6(S, 4);
+            L3 ^= C7(S, 4);
+
+            L5 ^= C0(S, 5);
+            L6 ^= C1(S, 5);
+            L7 ^= C2(S, 5);
+            L0 ^= C3(S, 5);
+            L1 ^= C4(S, 5);
+            L2 ^= C5(S, 5);
+            L3 ^= C6(S, 5);
+            L4 ^= C7(S, 5);
+
+            L6 ^= C0(S, 6);
+            L7 ^= C1(S, 6);
+            L0 ^= C2(S, 6);
+            L1 ^= C3(S, 6);
+            L2 ^= C4(S, 6);
+            L3 ^= C5(S, 6);
+            L4 ^= C6(S, 6);
+            L5 ^= C7(S, 6);
+
+            L7 ^= C0(S, 7);
+            L0 ^= C1(S, 7);
+            L1 ^= C2(S, 7);
+            L2 ^= C3(S, 7);
+            L3 ^= C4(S, 7);
+            L4 ^= C5(S, 7);
+            L5 ^= C6(S, 7);
+            L6 ^= C7(S, 7);
+
+            S.q[0] = L0;
+            S.q[1] = L1;
+            S.q[2] = L2;
+            S.q[3] = L3;
+            S.q[4] = L4;
+            S.q[5] = L5;
+            S.q[6] = L6;
+            S.q[7] = L7;
+# endif
+        }
+
+# ifdef STRICT_ALIGNMENT
+        if ((size_t)p & 7) {
+            int i;
+            for (i = 0; i < 64; i++)
+                H->c[i] ^= S.c[i] ^ p[i];
+        } else
+# endif
+        {
+            const u64 *pa = (const u64 *)p;
+            H->q[0] ^= S.q[0] ^ pa[0];
+            H->q[1] ^= S.q[1] ^ pa[1];
+            H->q[2] ^= S.q[2] ^ pa[2];
+            H->q[3] ^= S.q[3] ^ pa[3];
+            H->q[4] ^= S.q[4] ^ pa[4];
+            H->q[5] ^= S.q[5] ^ pa[5];
+            H->q[6] ^= S.q[6] ^ pa[6];
+            H->q[7] ^= S.q[7] ^ pa[7];
+        }
+#endif
+        p += 64;
+    } while (--n);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/whrlpool/wp_dgst.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/whrlpool/wp_dgst.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/whrlpool/wp_dgst.c	(revision 331)
@@ -0,0 +1,266 @@
+/*
+ * Copyright 2005-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
+ */
+
+/**
+ * The Whirlpool hashing function.
+ *
+ * <P>
+ * <b>References</b>
+ *
+ * <P>
+ * The Whirlpool algorithm was developed by
+ * <a href="mailto:pbarreto@scopus.com.br">Paulo S. L. M. Barreto</a> and
+ * <a href="mailto:vincent.rijmen@cryptomathic.com">Vincent Rijmen</a>.
+ *
+ * See
+ *      P.S.L.M. Barreto, V. Rijmen,
+ *      ``The Whirlpool hashing function,''
+ *      NESSIE submission, 2000 (tweaked version, 2001),
+ *      <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip>
+ *
+ * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and
+ * Vincent Rijmen. Lookup "reference implementations" on
+ * <http://planeta.terra.com.br/informatica/paulobarreto/>
+ *
+ * =============================================================================
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * OpenSSL-specific implementation notes.
+ *
+ * WHIRLPOOL_Update as well as one-stroke WHIRLPOOL both expect
+ * number of *bytes* as input length argument. Bit-oriented routine
+ * as specified by authors is called WHIRLPOOL_BitUpdate[!] and
+ * does not have one-stroke counterpart.
+ *
+ * WHIRLPOOL_BitUpdate implements byte-oriented loop, essentially
+ * to serve WHIRLPOOL_Update. This is done for performance.
+ *
+ * Unlike authors' reference implementation, block processing
+ * routine whirlpool_block is designed to operate on multi-block
+ * input. This is done for performance.
+ */
+
+#include <openssl/crypto.h>
+#include "wp_locl.h"
+#include <string.h>
+
+int WHIRLPOOL_Init(WHIRLPOOL_CTX *c)
+{
+    memset(c, 0, sizeof(*c));
+    return (1);
+}
+
+int WHIRLPOOL_Update(WHIRLPOOL_CTX *c, const void *_inp, size_t bytes)
+{
+    /*
+     * Well, largest suitable chunk size actually is
+     * (1<<(sizeof(size_t)*8-3))-64, but below number is large enough for not
+     * to care about excessive calls to WHIRLPOOL_BitUpdate...
+     */
+    size_t chunk = ((size_t)1) << (sizeof(size_t) * 8 - 4);
+    const unsigned char *inp = _inp;
+
+    while (bytes >= chunk) {
+        WHIRLPOOL_BitUpdate(c, inp, chunk * 8);
+        bytes -= chunk;
+        inp += chunk;
+    }
+    if (bytes)
+        WHIRLPOOL_BitUpdate(c, inp, bytes * 8);
+
+    return (1);
+}
+
+void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *_inp, size_t bits)
+{
+    size_t n;
+    unsigned int bitoff = c->bitoff,
+        bitrem = bitoff % 8, inpgap = (8 - (unsigned int)bits % 8) & 7;
+    const unsigned char *inp = _inp;
+
+    /*
+     * This 256-bit increment procedure relies on the size_t being natural
+     * size of CPU register, so that we don't have to mask the value in order
+     * to detect overflows.
+     */
+    c->bitlen[0] += bits;
+    if (c->bitlen[0] < bits) {  /* overflow */
+        n = 1;
+        do {
+            c->bitlen[n]++;
+        } while (c->bitlen[n] == 0
+                 && ++n < (WHIRLPOOL_COUNTER / sizeof(size_t)));
+    }
+#ifndef OPENSSL_SMALL_FOOTPRINT
+ reconsider:
+    if (inpgap == 0 && bitrem == 0) { /* byte-oriented loop */
+        while (bits) {
+            if (bitoff == 0 && (n = bits / WHIRLPOOL_BBLOCK)) {
+                whirlpool_block(c, inp, n);
+                inp += n * WHIRLPOOL_BBLOCK / 8;
+                bits %= WHIRLPOOL_BBLOCK;
+            } else {
+                unsigned int byteoff = bitoff / 8;
+
+                bitrem = WHIRLPOOL_BBLOCK - bitoff; /* re-use bitrem */
+                if (bits >= bitrem) {
+                    bits -= bitrem;
+                    bitrem /= 8;
+                    memcpy(c->data + byteoff, inp, bitrem);
+                    inp += bitrem;
+                    whirlpool_block(c, c->data, 1);
+                    bitoff = 0;
+                } else {
+                    memcpy(c->data + byteoff, inp, bits / 8);
+                    bitoff += (unsigned int)bits;
+                    bits = 0;
+                }
+                c->bitoff = bitoff;
+            }
+        }
+    } else                      /* bit-oriented loop */
+#endif
+    {
+        /*-
+                   inp
+                   |
+                   +-------+-------+-------
+                      |||||||||||||||||||||
+                   +-------+-------+-------
+        +-------+-------+-------+-------+-------
+        ||||||||||||||                          c->data
+        +-------+-------+-------+-------+-------
+                |
+                c->bitoff/8
+        */
+        while (bits) {
+            unsigned int byteoff = bitoff / 8;
+            unsigned char b;
+
+#ifndef OPENSSL_SMALL_FOOTPRINT
+            if (bitrem == inpgap) {
+                c->data[byteoff++] |= inp[0] & (0xff >> inpgap);
+                inpgap = 8 - inpgap;
+                bitoff += inpgap;
+                bitrem = 0;     /* bitoff%8 */
+                bits -= inpgap;
+                inpgap = 0;     /* bits%8 */
+                inp++;
+                if (bitoff == WHIRLPOOL_BBLOCK) {
+                    whirlpool_block(c, c->data, 1);
+                    bitoff = 0;
+                }
+                c->bitoff = bitoff;
+                goto reconsider;
+            } else
+#endif
+            if (bits >= 8) {
+                b = ((inp[0] << inpgap) | (inp[1] >> (8 - inpgap)));
+                b &= 0xff;
+                if (bitrem)
+                    c->data[byteoff++] |= b >> bitrem;
+                else
+                    c->data[byteoff++] = b;
+                bitoff += 8;
+                bits -= 8;
+                inp++;
+                if (bitoff >= WHIRLPOOL_BBLOCK) {
+                    whirlpool_block(c, c->data, 1);
+                    byteoff = 0;
+                    bitoff %= WHIRLPOOL_BBLOCK;
+                }
+                if (bitrem)
+                    c->data[byteoff] = b << (8 - bitrem);
+            } else {            /* remaining less than 8 bits */
+
+                b = (inp[0] << inpgap) & 0xff;
+                if (bitrem)
+                    c->data[byteoff++] |= b >> bitrem;
+                else
+                    c->data[byteoff++] = b;
+                bitoff += (unsigned int)bits;
+                if (bitoff == WHIRLPOOL_BBLOCK) {
+                    whirlpool_block(c, c->data, 1);
+                    byteoff = 0;
+                    bitoff %= WHIRLPOOL_BBLOCK;
+                }
+                if (bitrem)
+                    c->data[byteoff] = b << (8 - bitrem);
+                bits = 0;
+            }
+            c->bitoff = bitoff;
+        }
+    }
+}
+
+int WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c)
+{
+    unsigned int bitoff = c->bitoff, byteoff = bitoff / 8;
+    size_t i, j, v;
+    unsigned char *p;
+
+    bitoff %= 8;
+    if (bitoff)
+        c->data[byteoff] |= 0x80 >> bitoff;
+    else
+        c->data[byteoff] = 0x80;
+    byteoff++;
+
+    /* pad with zeros */
+    if (byteoff > (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER)) {
+        if (byteoff < WHIRLPOOL_BBLOCK / 8)
+            memset(&c->data[byteoff], 0, WHIRLPOOL_BBLOCK / 8 - byteoff);
+        whirlpool_block(c, c->data, 1);
+        byteoff = 0;
+    }
+    if (byteoff < (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER))
+        memset(&c->data[byteoff], 0,
+               (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER) - byteoff);
+    /* smash 256-bit c->bitlen in big-endian order */
+    p = &c->data[WHIRLPOOL_BBLOCK / 8 - 1]; /* last byte in c->data */
+    for (i = 0; i < WHIRLPOOL_COUNTER / sizeof(size_t); i++)
+        for (v = c->bitlen[i], j = 0; j < sizeof(size_t); j++, v >>= 8)
+            *p-- = (unsigned char)(v & 0xff);
+
+    whirlpool_block(c, c->data, 1);
+
+    if (md) {
+        memcpy(md, c->H.c, WHIRLPOOL_DIGEST_LENGTH);
+        OPENSSL_cleanse(c, sizeof(*c));
+        return (1);
+    }
+    return (0);
+}
+
+unsigned char *WHIRLPOOL(const void *inp, size_t bytes, unsigned char *md)
+{
+    WHIRLPOOL_CTX ctx;
+    static unsigned char m[WHIRLPOOL_DIGEST_LENGTH];
+
+    if (md == NULL)
+        md = m;
+    WHIRLPOOL_Init(&ctx);
+    WHIRLPOOL_Update(&ctx, inp, bytes);
+    WHIRLPOOL_Final(md, &ctx);
+    return (md);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/whrlpool/wp_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/whrlpool/wp_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/whrlpool/wp_locl.h	(revision 331)
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2005-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 <openssl/whrlpool.h>
+
+void whirlpool_block(WHIRLPOOL_CTX *, const void *, size_t);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/by_dir.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/by_dir.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/by_dir.c	(revision 331)
@@ -0,0 +1,388 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include "internal/cryptlib.h"
+
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifndef OPENSSL_NO_POSIX_IO
+# include <sys/stat.h>
+#endif
+
+
+#include <openssl/lhash.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+#include "x509_lcl.h"
+
+struct lookup_dir_hashes_st {
+    unsigned long hash;
+    int suffix;
+};
+
+struct lookup_dir_entry_st {
+    char *dir;
+    int dir_type;
+    STACK_OF(BY_DIR_HASH) *hashes;
+};
+
+typedef struct lookup_dir_st {
+    BUF_MEM *buffer;
+    STACK_OF(BY_DIR_ENTRY) *dirs;
+    CRYPTO_RWLOCK *lock;
+} BY_DIR;
+
+static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
+                    char **ret);
+static int new_dir(X509_LOOKUP *lu);
+static void free_dir(X509_LOOKUP *lu);
+static int add_cert_dir(BY_DIR *ctx, const char *dir, int type);
+static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type,
+                               X509_NAME *name, X509_OBJECT *ret);
+static X509_LOOKUP_METHOD x509_dir_lookup = {
+    "Load certs from files in a directory",
+    new_dir,                    /* new */
+    free_dir,                   /* free */
+    NULL,                       /* init */
+    NULL,                       /* shutdown */
+    dir_ctrl,                   /* ctrl */
+    get_cert_by_subject,        /* get_by_subject */
+    NULL,                       /* get_by_issuer_serial */
+    NULL,                       /* get_by_fingerprint */
+    NULL,                       /* get_by_alias */
+};
+
+X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void)
+{
+    return (&x509_dir_lookup);
+}
+
+static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
+                    char **retp)
+{
+    int ret = 0;
+    BY_DIR *ld;
+    char *dir = NULL;
+
+    ld = (BY_DIR *)ctx->method_data;
+
+    switch (cmd) {
+    case X509_L_ADD_DIR:
+        if (argl == X509_FILETYPE_DEFAULT) {
+            dir = (char *)getenv(X509_get_default_cert_dir_env());
+            if (dir)
+                ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM);
+            else
+                ret = add_cert_dir(ld, X509_get_default_cert_dir(),
+                                   X509_FILETYPE_PEM);
+            if (!ret) {
+                X509err(X509_F_DIR_CTRL, X509_R_LOADING_CERT_DIR);
+            }
+        } else
+            ret = add_cert_dir(ld, argp, (int)argl);
+        break;
+    }
+    return (ret);
+}
+
+static int new_dir(X509_LOOKUP *lu)
+{
+    BY_DIR *a;
+
+    if ((a = OPENSSL_malloc(sizeof(*a))) == NULL)
+        return 0;
+    if ((a->buffer = BUF_MEM_new()) == NULL) {
+        OPENSSL_free(a);
+        return 0;
+    }
+    a->dirs = NULL;
+    a->lock = CRYPTO_THREAD_lock_new();
+    if (a->lock == NULL) {
+        BUF_MEM_free(a->buffer);
+        OPENSSL_free(a);
+        return 0;
+    }
+    lu->method_data = (char *)a;
+    return 1;
+}
+
+static void by_dir_hash_free(BY_DIR_HASH *hash)
+{
+    OPENSSL_free(hash);
+}
+
+static int by_dir_hash_cmp(const BY_DIR_HASH *const *a,
+                           const BY_DIR_HASH *const *b)
+{
+    if ((*a)->hash > (*b)->hash)
+        return 1;
+    if ((*a)->hash < (*b)->hash)
+        return -1;
+    return 0;
+}
+
+static void by_dir_entry_free(BY_DIR_ENTRY *ent)
+{
+    OPENSSL_free(ent->dir);
+    sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free);
+    OPENSSL_free(ent);
+}
+
+static void free_dir(X509_LOOKUP *lu)
+{
+    BY_DIR *a;
+
+    a = (BY_DIR *)lu->method_data;
+    sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free);
+    BUF_MEM_free(a->buffer);
+    CRYPTO_THREAD_lock_free(a->lock);
+    OPENSSL_free(a);
+}
+
+static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
+{
+    const char *s, *p;
+
+    if (dir == NULL || !*dir) {
+        X509err(X509_F_ADD_CERT_DIR, X509_R_INVALID_DIRECTORY);
+        return 0;
+    }
+
+    s = dir;
+    p = s;
+    do {
+        if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0')) {
+            BY_DIR_ENTRY *ent;
+            int j;
+            size_t len;
+            const char *ss = s;
+            s = p + 1;
+            len = p - ss;
+            if (len == 0)
+                continue;
+            for (j = 0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++) {
+                ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j);
+                if (strlen(ent->dir) == len &&
+                    strncmp(ent->dir, ss, len) == 0)
+                    break;
+            }
+            if (j < sk_BY_DIR_ENTRY_num(ctx->dirs))
+                continue;
+            if (ctx->dirs == NULL) {
+                ctx->dirs = sk_BY_DIR_ENTRY_new_null();
+                if (!ctx->dirs) {
+                    X509err(X509_F_ADD_CERT_DIR, ERR_R_MALLOC_FAILURE);
+                    return 0;
+                }
+            }
+            ent = OPENSSL_malloc(sizeof(*ent));
+            if (ent == NULL)
+                return 0;
+            ent->dir_type = type;
+            ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp);
+            ent->dir = OPENSSL_strndup(ss, len);
+            if (ent->dir == NULL || ent->hashes == NULL) {
+                by_dir_entry_free(ent);
+                return 0;
+            }
+            if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) {
+                by_dir_entry_free(ent);
+                return 0;
+            }
+        }
+    } while (*p++ != '\0');
+    return 1;
+}
+
+static int get_cert_by_subject(X509_LOOKUP *xl, X509_LOOKUP_TYPE type,
+                               X509_NAME *name, X509_OBJECT *ret)
+{
+    BY_DIR *ctx;
+    union {
+        X509 st_x509;
+        X509_CRL crl;
+    } data;
+    int ok = 0;
+    int i, j, k;
+    unsigned long h;
+    BUF_MEM *b = NULL;
+    X509_OBJECT stmp, *tmp;
+    const char *postfix = "";
+
+    if (name == NULL)
+        return (0);
+
+    stmp.type = type;
+    if (type == X509_LU_X509) {
+        data.st_x509.cert_info.subject = name;
+        stmp.data.x509 = &data.st_x509;
+        postfix = "";
+    } else if (type == X509_LU_CRL) {
+        data.crl.crl.issuer = name;
+        stmp.data.crl = &data.crl;
+        postfix = "r";
+    } else {
+        X509err(X509_F_GET_CERT_BY_SUBJECT, X509_R_WRONG_LOOKUP_TYPE);
+        goto finish;
+    }
+
+    if ((b = BUF_MEM_new()) == NULL) {
+        X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_BUF_LIB);
+        goto finish;
+    }
+
+    ctx = (BY_DIR *)xl->method_data;
+
+    h = X509_NAME_hash(name);
+    for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) {
+        BY_DIR_ENTRY *ent;
+        int idx;
+        BY_DIR_HASH htmp, *hent;
+        ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i);
+        j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1;
+        if (!BUF_MEM_grow(b, j)) {
+            X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE);
+            goto finish;
+        }
+        if (type == X509_LU_CRL && ent->hashes) {
+            htmp.hash = h;
+            CRYPTO_THREAD_read_lock(ctx->lock);
+            idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
+            if (idx >= 0) {
+                hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
+                k = hent->suffix;
+            } else {
+                hent = NULL;
+                k = 0;
+            }
+            CRYPTO_THREAD_unlock(ctx->lock);
+        } else {
+            k = 0;
+            hent = NULL;
+        }
+        for (;;) {
+            char c = '/';
+#ifdef OPENSSL_SYS_VMS
+            c = ent->dir[strlen(ent->dir) - 1];
+            if (c != ':' && c != '>' && c != ']') {
+                /*
+                 * If no separator is present, we assume the directory
+                 * specifier is a logical name, and add a colon.  We really
+                 * should use better VMS routines for merging things like
+                 * this, but this will do for now... -- Richard Levitte
+                 */
+                c = ':';
+            } else {
+                c = '\0';
+            }
+#endif
+            if (c == '\0') {
+                /*
+                 * This is special.  When c == '\0', no directory separator
+                 * should be added.
+                 */
+                BIO_snprintf(b->data, b->max,
+                             "%s%08lx.%s%d", ent->dir, h, postfix, k);
+            } else {
+                BIO_snprintf(b->data, b->max,
+                             "%s%c%08lx.%s%d", ent->dir, c, h, postfix, k);
+            }
+#ifndef OPENSSL_NO_POSIX_IO
+# ifdef _WIN32
+#  define stat _stat
+# endif
+            {
+                struct stat st;
+                if (stat(b->data, &st) < 0)
+                    break;
+            }
+#endif
+            /* found one. */
+            if (type == X509_LU_X509) {
+                if ((X509_load_cert_file(xl, b->data, ent->dir_type)) == 0)
+                    break;
+            } else if (type == X509_LU_CRL) {
+                if ((X509_load_crl_file(xl, b->data, ent->dir_type)) == 0)
+                    break;
+            }
+            /* else case will caught higher up */
+            k++;
+        }
+
+        /*
+         * we have added it to the cache so now pull it out again
+         */
+        CRYPTO_THREAD_write_lock(ctx->lock);
+        j = sk_X509_OBJECT_find(xl->store_ctx->objs, &stmp);
+        if (j != -1)
+            tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j);
+        else
+            tmp = NULL;
+        CRYPTO_THREAD_unlock(ctx->lock);
+
+        /* If a CRL, update the last file suffix added for this */
+
+        if (type == X509_LU_CRL) {
+            CRYPTO_THREAD_write_lock(ctx->lock);
+            /*
+             * Look for entry again in case another thread added an entry
+             * first.
+             */
+            if (!hent) {
+                htmp.hash = h;
+                idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
+                if (idx >= 0)
+                    hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
+            }
+            if (!hent) {
+                hent = OPENSSL_malloc(sizeof(*hent));
+                if (hent == NULL) {
+                    CRYPTO_THREAD_unlock(ctx->lock);
+                    X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE);
+                    ok = 0;
+                    goto finish;
+                }
+                hent->hash = h;
+                hent->suffix = k;
+                if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) {
+                    CRYPTO_THREAD_unlock(ctx->lock);
+                    OPENSSL_free(hent);
+                    ok = 0;
+                    goto finish;
+                }
+            } else if (hent->suffix < k) {
+                hent->suffix = k;
+            }
+
+            CRYPTO_THREAD_unlock(ctx->lock);
+
+        }
+
+        if (tmp != NULL) {
+            ok = 1;
+            ret->type = tmp->type;
+            memcpy(&ret->data, &tmp->data, sizeof(ret->data));
+            /*
+             * If we were going to up the reference count, we would need to
+             * do it on a perl 'type' basis
+             */
+        /*- CRYPTO_add(&tmp->data.x509->references,1,
+                    CRYPTO_LOCK_X509);*/
+            goto finish;
+        }
+    }
+ finish:
+    BUF_MEM_free(b);
+    return (ok);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/by_file.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/by_file.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/by_file.c	(revision 331)
@@ -0,0 +1,221 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include "internal/cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/buffer.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include "x509_lcl.h"
+
+static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
+                        long argl, char **ret);
+static X509_LOOKUP_METHOD x509_file_lookup = {
+    "Load file into cache",
+    NULL,                       /* new */
+    NULL,                       /* free */
+    NULL,                       /* init */
+    NULL,                       /* shutdown */
+    by_file_ctrl,               /* ctrl */
+    NULL,                       /* get_by_subject */
+    NULL,                       /* get_by_issuer_serial */
+    NULL,                       /* get_by_fingerprint */
+    NULL,                       /* get_by_alias */
+};
+
+X509_LOOKUP_METHOD *X509_LOOKUP_file(void)
+{
+    return (&x509_file_lookup);
+}
+
+static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp,
+                        long argl, char **ret)
+{
+    int ok = 0;
+    char *file;
+
+    switch (cmd) {
+    case X509_L_FILE_LOAD:
+        if (argl == X509_FILETYPE_DEFAULT) {
+            file = (char *)getenv(X509_get_default_cert_file_env());
+            if (file)
+                ok = (X509_load_cert_crl_file(ctx, file,
+                                              X509_FILETYPE_PEM) != 0);
+
+            else
+                ok = (X509_load_cert_crl_file
+                      (ctx, X509_get_default_cert_file(),
+                       X509_FILETYPE_PEM) != 0);
+
+            if (!ok) {
+                X509err(X509_F_BY_FILE_CTRL, X509_R_LOADING_DEFAULTS);
+            }
+        } else {
+            if (argl == X509_FILETYPE_PEM)
+                ok = (X509_load_cert_crl_file(ctx, argp,
+                                              X509_FILETYPE_PEM) != 0);
+            else
+                ok = (X509_load_cert_file(ctx, argp, (int)argl) != 0);
+        }
+        break;
+    }
+    return (ok);
+}
+
+int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
+{
+    int ret = 0;
+    BIO *in = NULL;
+    int i, count = 0;
+    X509 *x = NULL;
+
+    if (file == NULL)
+        return (1);
+    in = BIO_new(BIO_s_file());
+
+    if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
+        X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_SYS_LIB);
+        goto err;
+    }
+
+    if (type == X509_FILETYPE_PEM) {
+        for (;;) {
+            x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
+            if (x == NULL) {
+                if ((ERR_GET_REASON(ERR_peek_last_error()) ==
+                     PEM_R_NO_START_LINE) && (count > 0)) {
+                    ERR_clear_error();
+                    break;
+                } else {
+                    X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_PEM_LIB);
+                    goto err;
+                }
+            }
+            i = X509_STORE_add_cert(ctx->store_ctx, x);
+            if (!i)
+                goto err;
+            count++;
+            X509_free(x);
+            x = NULL;
+        }
+        ret = count;
+    } else if (type == X509_FILETYPE_ASN1) {
+        x = d2i_X509_bio(in, NULL);
+        if (x == NULL) {
+            X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_ASN1_LIB);
+            goto err;
+        }
+        i = X509_STORE_add_cert(ctx->store_ctx, x);
+        if (!i)
+            goto err;
+        ret = i;
+    } else {
+        X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_BAD_X509_FILETYPE);
+        goto err;
+    }
+ err:
+    X509_free(x);
+    BIO_free(in);
+    return (ret);
+}
+
+int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
+{
+    int ret = 0;
+    BIO *in = NULL;
+    int i, count = 0;
+    X509_CRL *x = NULL;
+
+    if (file == NULL)
+        return (1);
+    in = BIO_new(BIO_s_file());
+
+    if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
+        X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_SYS_LIB);
+        goto err;
+    }
+
+    if (type == X509_FILETYPE_PEM) {
+        for (;;) {
+            x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
+            if (x == NULL) {
+                if ((ERR_GET_REASON(ERR_peek_last_error()) ==
+                     PEM_R_NO_START_LINE) && (count > 0)) {
+                    ERR_clear_error();
+                    break;
+                } else {
+                    X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_PEM_LIB);
+                    goto err;
+                }
+            }
+            i = X509_STORE_add_crl(ctx->store_ctx, x);
+            if (!i)
+                goto err;
+            count++;
+            X509_CRL_free(x);
+            x = NULL;
+        }
+        ret = count;
+    } else if (type == X509_FILETYPE_ASN1) {
+        x = d2i_X509_CRL_bio(in, NULL);
+        if (x == NULL) {
+            X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_ASN1_LIB);
+            goto err;
+        }
+        i = X509_STORE_add_crl(ctx->store_ctx, x);
+        if (!i)
+            goto err;
+        ret = i;
+    } else {
+        X509err(X509_F_X509_LOAD_CRL_FILE, X509_R_BAD_X509_FILETYPE);
+        goto err;
+    }
+ err:
+    X509_CRL_free(x);
+    BIO_free(in);
+    return (ret);
+}
+
+int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
+{
+    STACK_OF(X509_INFO) *inf;
+    X509_INFO *itmp;
+    BIO *in;
+    int i, count = 0;
+    if (type != X509_FILETYPE_PEM)
+        return X509_load_cert_file(ctx, file, type);
+    in = BIO_new_file(file, "r");
+    if (!in) {
+        X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_SYS_LIB);
+        return 0;
+    }
+    inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
+    BIO_free(in);
+    if (!inf) {
+        X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_PEM_LIB);
+        return 0;
+    }
+    for (i = 0; i < sk_X509_INFO_num(inf); i++) {
+        itmp = sk_X509_INFO_value(inf, i);
+        if (itmp->x509) {
+            X509_STORE_add_cert(ctx->store_ctx, itmp->x509);
+            count++;
+        }
+        if (itmp->crl) {
+            X509_STORE_add_crl(ctx->store_ctx, itmp->crl);
+            count++;
+        }
+    }
+    sk_X509_INFO_pop_free(inf, X509_INFO_free);
+    return count;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/t_crl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/t_crl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/t_crl.c	(revision 331)
@@ -0,0 +1,89 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/bn.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#ifndef OPENSSL_NO_STDIO
+int X509_CRL_print_fp(FILE *fp, X509_CRL *x)
+{
+    BIO *b;
+    int ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        X509err(X509_F_X509_CRL_PRINT_FP, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = X509_CRL_print(b, x);
+    BIO_free(b);
+    return (ret);
+}
+#endif
+
+int X509_CRL_print(BIO *out, X509_CRL *x)
+{
+    STACK_OF(X509_REVOKED) *rev;
+    X509_REVOKED *r;
+    const X509_ALGOR *sig_alg;
+    const ASN1_BIT_STRING *sig;
+    long l;
+    int i;
+    char *p;
+
+    BIO_printf(out, "Certificate Revocation List (CRL):\n");
+    l = X509_CRL_get_version(x);
+    if (l >= 0 && l <= 1)
+        BIO_printf(out, "%8sVersion %ld (0x%lx)\n", "", l + 1, (unsigned long)l);
+    else
+        BIO_printf(out, "%8sVersion unknown (%ld)\n", "", l);
+    X509_CRL_get0_signature(x, &sig, &sig_alg);
+    X509_signature_print(out, sig_alg, NULL);
+    p = X509_NAME_oneline(X509_CRL_get_issuer(x), NULL, 0);
+    BIO_printf(out, "%8sIssuer: %s\n", "", p);
+    OPENSSL_free(p);
+    BIO_printf(out, "%8sLast Update: ", "");
+    ASN1_TIME_print(out, X509_CRL_get0_lastUpdate(x));
+    BIO_printf(out, "\n%8sNext Update: ", "");
+    if (X509_CRL_get0_nextUpdate(x))
+        ASN1_TIME_print(out, X509_CRL_get0_nextUpdate(x));
+    else
+        BIO_printf(out, "NONE");
+    BIO_printf(out, "\n");
+
+    X509V3_extensions_print(out, "CRL extensions",
+                            X509_CRL_get0_extensions(x), 0, 8);
+
+    rev = X509_CRL_get_REVOKED(x);
+
+    if (sk_X509_REVOKED_num(rev) > 0)
+        BIO_printf(out, "Revoked Certificates:\n");
+    else
+        BIO_printf(out, "No Revoked Certificates.\n");
+
+    for (i = 0; i < sk_X509_REVOKED_num(rev); i++) {
+        r = sk_X509_REVOKED_value(rev, i);
+        BIO_printf(out, "    Serial Number: ");
+        i2a_ASN1_INTEGER(out, X509_REVOKED_get0_serialNumber(r));
+        BIO_printf(out, "\n        Revocation Date: ");
+        ASN1_TIME_print(out, X509_REVOKED_get0_revocationDate(r));
+        BIO_printf(out, "\n");
+        X509V3_extensions_print(out, "CRL entry extensions",
+                                X509_REVOKED_get0_extensions(r), 0, 8);
+    }
+    X509_signature_print(out, sig_alg, sig);
+
+    return 1;
+
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/t_req.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/t_req.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/t_req.c	(revision 331)
@@ -0,0 +1,198 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/bn.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+
+#ifndef OPENSSL_NO_STDIO
+int X509_REQ_print_fp(FILE *fp, X509_REQ *x)
+{
+    BIO *b;
+    int ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        X509err(X509_F_X509_REQ_PRINT_FP, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = X509_REQ_print(b, x);
+    BIO_free(b);
+    return (ret);
+}
+#endif
+
+int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,
+                      unsigned long cflag)
+{
+    long l;
+    int i;
+    EVP_PKEY *pkey;
+    STACK_OF(X509_EXTENSION) *exts;
+    char mlch = ' ';
+    int nmindent = 0;
+
+    if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
+        mlch = '\n';
+        nmindent = 12;
+    }
+
+    if (nmflags == X509_FLAG_COMPAT)
+        nmindent = 16;
+
+    if (!(cflag & X509_FLAG_NO_HEADER)) {
+        if (BIO_write(bp, "Certificate Request:\n", 21) <= 0)
+            goto err;
+        if (BIO_write(bp, "    Data:\n", 10) <= 0)
+            goto err;
+    }
+    if (!(cflag & X509_FLAG_NO_VERSION)) {
+        l = X509_REQ_get_version(x);
+        if (l >= 0 && l <= 2) {
+            if (BIO_printf(bp, "%8sVersion: %ld (0x%lx)\n", "", l + 1, (unsigned long)l) <= 0)
+                goto err;
+        } else {
+            if (BIO_printf(bp, "%8sVersion: Unknown (%ld)\n", "", l) <= 0)
+                goto err;
+        }
+    }
+    if (!(cflag & X509_FLAG_NO_SUBJECT)) {
+        if (BIO_printf(bp, "        Subject:%c", mlch) <= 0)
+            goto err;
+        if (X509_NAME_print_ex(bp, X509_REQ_get_subject_name(x),
+            nmindent, nmflags) < 0)
+            goto err;
+        if (BIO_write(bp, "\n", 1) <= 0)
+            goto err;
+    }
+    if (!(cflag & X509_FLAG_NO_PUBKEY)) {
+        X509_PUBKEY *xpkey;
+        ASN1_OBJECT *koid;
+        if (BIO_write(bp, "        Subject Public Key Info:\n", 33) <= 0)
+            goto err;
+        if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
+            goto err;
+        xpkey = X509_REQ_get_X509_PUBKEY(x);
+        X509_PUBKEY_get0_param(&koid, NULL, NULL, NULL, xpkey);
+        if (i2a_ASN1_OBJECT(bp, koid) <= 0)
+            goto err;
+        if (BIO_puts(bp, "\n") <= 0)
+            goto err;
+
+        pkey = X509_REQ_get0_pubkey(x);
+        if (pkey == NULL) {
+            BIO_printf(bp, "%12sUnable to load Public Key\n", "");
+            ERR_print_errors(bp);
+        } else {
+            EVP_PKEY_print_public(bp, pkey, 16, NULL);
+        }
+    }
+
+    if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) {
+        /* may not be */
+        if (BIO_printf(bp, "%8sAttributes:\n", "") <= 0)
+            goto err;
+
+        if (X509_REQ_get_attr_count(x) == 0) {
+            if (BIO_printf(bp, "%12sa0:00\n", "") <= 0)
+                goto err;
+        } else {
+            for (i = 0; i < X509_REQ_get_attr_count(x); i++) {
+                ASN1_TYPE *at;
+                X509_ATTRIBUTE *a;
+                ASN1_BIT_STRING *bs = NULL;
+                ASN1_OBJECT *aobj;
+                int j, type = 0, count = 1, ii = 0;
+
+                a = X509_REQ_get_attr(x, i);
+                aobj = X509_ATTRIBUTE_get0_object(a);
+                if (X509_REQ_extension_nid(OBJ_obj2nid(aobj)))
+                    continue;
+                if (BIO_printf(bp, "%12s", "") <= 0)
+                    goto err;
+                if ((j = i2a_ASN1_OBJECT(bp, aobj)) > 0) {
+                    ii = 0;
+                    count = X509_ATTRIBUTE_count(a);
+ get_next:
+                    at = X509_ATTRIBUTE_get0_type(a, ii);
+                    type = at->type;
+                    bs = at->value.asn1_string;
+                }
+                for (j = 25 - j; j > 0; j--)
+                    if (BIO_write(bp, " ", 1) != 1)
+                        goto err;
+                if (BIO_puts(bp, ":") <= 0)
+                    goto err;
+                if ((type == V_ASN1_PRINTABLESTRING) ||
+                    (type == V_ASN1_T61STRING) ||
+                    (type == V_ASN1_UTF8STRING) ||
+                    (type == V_ASN1_IA5STRING)) {
+                    if (BIO_write(bp, (char *)bs->data, bs->length)
+                        != bs->length)
+                        goto err;
+                    BIO_puts(bp, "\n");
+                } else {
+                    BIO_puts(bp, "unable to print attribute\n");
+                }
+                if (++ii < count)
+                    goto get_next;
+            }
+        }
+    }
+    if (!(cflag & X509_FLAG_NO_EXTENSIONS)) {
+        exts = X509_REQ_get_extensions(x);
+        if (exts) {
+            BIO_printf(bp, "%8sRequested Extensions:\n", "");
+            for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
+                ASN1_OBJECT *obj;
+                X509_EXTENSION *ex;
+                int critical;
+                ex = sk_X509_EXTENSION_value(exts, i);
+                if (BIO_printf(bp, "%12s", "") <= 0)
+                    goto err;
+                obj = X509_EXTENSION_get_object(ex);
+                i2a_ASN1_OBJECT(bp, obj);
+                critical = X509_EXTENSION_get_critical(ex);
+                if (BIO_printf(bp, ": %s\n", critical ? "critical" : "") <= 0)
+                    goto err;
+                if (!X509V3_EXT_print(bp, ex, cflag, 16)) {
+                    BIO_printf(bp, "%16s", "");
+                    ASN1_STRING_print(bp, X509_EXTENSION_get_data(ex));
+                }
+                if (BIO_write(bp, "\n", 1) <= 0)
+                    goto err;
+            }
+            sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+        }
+    }
+
+    if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
+        const X509_ALGOR *sig_alg;
+        const ASN1_BIT_STRING *sig;
+        X509_REQ_get0_signature(x, &sig, &sig_alg);
+        if (!X509_signature_print(bp, sig_alg, sig))
+            goto err;
+    }
+
+    return (1);
+ err:
+    X509err(X509_F_X509_REQ_PRINT_EX, ERR_R_BUF_LIB);
+    return (0);
+}
+
+int X509_REQ_print(BIO *bp, X509_REQ *x)
+{
+    return X509_REQ_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/t_x509.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/t_x509.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/t_x509.c	(revision 331)
@@ -0,0 +1,376 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/bn.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include "internal/asn1_int.h"
+
+#ifndef OPENSSL_NO_STDIO
+int X509_print_fp(FILE *fp, X509 *x)
+{
+    return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+}
+
+int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag,
+                     unsigned long cflag)
+{
+    BIO *b;
+    int ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        X509err(X509_F_X509_PRINT_EX_FP, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = X509_print_ex(b, x, nmflag, cflag);
+    BIO_free(b);
+    return (ret);
+}
+#endif
+
+int X509_print(BIO *bp, X509 *x)
+{
+    return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+}
+
+int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
+                  unsigned long cflag)
+{
+    long l;
+    int ret = 0, i;
+    char *m = NULL, mlch = ' ';
+    int nmindent = 0;
+    ASN1_INTEGER *bs;
+    EVP_PKEY *pkey = NULL;
+    const char *neg;
+
+    if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
+        mlch = '\n';
+        nmindent = 12;
+    }
+
+    if (nmflags == X509_FLAG_COMPAT)
+        nmindent = 16;
+
+    if (!(cflag & X509_FLAG_NO_HEADER)) {
+        if (BIO_write(bp, "Certificate:\n", 13) <= 0)
+            goto err;
+        if (BIO_write(bp, "    Data:\n", 10) <= 0)
+            goto err;
+    }
+    if (!(cflag & X509_FLAG_NO_VERSION)) {
+        l = X509_get_version(x);
+        if (l >= 0 && l <= 2) {
+            if (BIO_printf(bp, "%8sVersion: %ld (0x%lx)\n", "", l + 1, (unsigned long)l) <= 0)
+                goto err;
+        } else {
+            if (BIO_printf(bp, "%8sVersion: Unknown (%ld)\n", "", l) <= 0)
+                goto err;
+        }
+    }
+    if (!(cflag & X509_FLAG_NO_SERIAL)) {
+
+        if (BIO_write(bp, "        Serial Number:", 22) <= 0)
+            goto err;
+
+        bs = X509_get_serialNumber(x);
+        if (bs->length <= (int)sizeof(long)) {
+                ERR_set_mark();
+                l = ASN1_INTEGER_get(bs);
+                ERR_pop_to_mark();
+        } else {
+            l = -1;
+        }
+        if (l != -1) {
+            unsigned long ul;
+            if (bs->type == V_ASN1_NEG_INTEGER) {
+                ul = 0 - (unsigned long)l;
+                neg = "-";
+            } else {
+                ul = l;
+                neg = "";
+            }
+            if (BIO_printf(bp, " %s%lu (%s0x%lx)\n", neg, ul, neg, ul) <= 0)
+                goto err;
+        } else {
+            neg = (bs->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : "";
+            if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0)
+                goto err;
+
+            for (i = 0; i < bs->length; i++) {
+                if (BIO_printf(bp, "%02x%c", bs->data[i],
+                               ((i + 1 == bs->length) ? '\n' : ':')) <= 0)
+                    goto err;
+            }
+        }
+
+    }
+
+    if (!(cflag & X509_FLAG_NO_SIGNAME)) {
+        const X509_ALGOR *tsig_alg = X509_get0_tbs_sigalg(x);
+        if (X509_signature_print(bp, tsig_alg, NULL) <= 0)
+            goto err;
+    }
+
+    if (!(cflag & X509_FLAG_NO_ISSUER)) {
+        if (BIO_printf(bp, "        Issuer:%c", mlch) <= 0)
+            goto err;
+        if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags)
+            < 0)
+            goto err;
+        if (BIO_write(bp, "\n", 1) <= 0)
+            goto err;
+    }
+    if (!(cflag & X509_FLAG_NO_VALIDITY)) {
+        if (BIO_write(bp, "        Validity\n", 17) <= 0)
+            goto err;
+        if (BIO_write(bp, "            Not Before: ", 24) <= 0)
+            goto err;
+        if (!ASN1_TIME_print(bp, X509_get0_notBefore(x)))
+            goto err;
+        if (BIO_write(bp, "\n            Not After : ", 25) <= 0)
+            goto err;
+        if (!ASN1_TIME_print(bp, X509_get0_notAfter(x)))
+            goto err;
+        if (BIO_write(bp, "\n", 1) <= 0)
+            goto err;
+    }
+    if (!(cflag & X509_FLAG_NO_SUBJECT)) {
+        if (BIO_printf(bp, "        Subject:%c", mlch) <= 0)
+            goto err;
+        if (X509_NAME_print_ex
+            (bp, X509_get_subject_name(x), nmindent, nmflags) < 0)
+            goto err;
+        if (BIO_write(bp, "\n", 1) <= 0)
+            goto err;
+    }
+    if (!(cflag & X509_FLAG_NO_PUBKEY)) {
+        X509_PUBKEY *xpkey = X509_get_X509_PUBKEY(x);
+        ASN1_OBJECT *xpoid;
+        X509_PUBKEY_get0_param(&xpoid, NULL, NULL, NULL, xpkey);
+        if (BIO_write(bp, "        Subject Public Key Info:\n", 33) <= 0)
+            goto err;
+        if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
+            goto err;
+        if (i2a_ASN1_OBJECT(bp, xpoid) <= 0)
+            goto err;
+        if (BIO_puts(bp, "\n") <= 0)
+            goto err;
+
+        pkey = X509_get0_pubkey(x);
+        if (pkey == NULL) {
+            BIO_printf(bp, "%12sUnable to load Public Key\n", "");
+            ERR_print_errors(bp);
+        } else {
+            EVP_PKEY_print_public(bp, pkey, 16, NULL);
+        }
+    }
+
+    if (!(cflag & X509_FLAG_NO_IDS)) {
+        const ASN1_BIT_STRING *iuid, *suid;
+        X509_get0_uids(x, &iuid, &suid);
+        if (iuid != NULL) {
+            if (BIO_printf(bp, "%8sIssuer Unique ID: ", "") <= 0)
+                goto err;
+            if (!X509_signature_dump(bp, iuid, 12))
+                goto err;
+        }
+        if (suid != NULL) {
+            if (BIO_printf(bp, "%8sSubject Unique ID: ", "") <= 0)
+                goto err;
+            if (!X509_signature_dump(bp, suid, 12))
+                goto err;
+        }
+    }
+
+    if (!(cflag & X509_FLAG_NO_EXTENSIONS))
+        X509V3_extensions_print(bp, "X509v3 extensions",
+                                X509_get0_extensions(x), cflag, 8);
+
+    if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
+        const X509_ALGOR *sig_alg;
+        const ASN1_BIT_STRING *sig;
+        X509_get0_signature(&sig, &sig_alg, x);
+        if (X509_signature_print(bp, sig_alg, sig) <= 0)
+            goto err;
+    }
+    if (!(cflag & X509_FLAG_NO_AUX)) {
+        if (!X509_aux_print(bp, x, 0))
+            goto err;
+    }
+    ret = 1;
+ err:
+    OPENSSL_free(m);
+    return (ret);
+}
+
+int X509_ocspid_print(BIO *bp, X509 *x)
+{
+    unsigned char *der = NULL;
+    unsigned char *dertmp;
+    int derlen;
+    int i;
+    unsigned char SHA1md[SHA_DIGEST_LENGTH];
+    ASN1_BIT_STRING *keybstr;
+    X509_NAME *subj;
+
+    /*
+     * display the hash of the subject as it would appear in OCSP requests
+     */
+    if (BIO_printf(bp, "        Subject OCSP hash: ") <= 0)
+        goto err;
+    subj = X509_get_subject_name(x);
+    derlen = i2d_X509_NAME(subj, NULL);
+    if ((der = dertmp = OPENSSL_malloc(derlen)) == NULL)
+        goto err;
+    i2d_X509_NAME(subj, &dertmp);
+
+    if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
+        goto err;
+    for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
+        if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
+            goto err;
+    }
+    OPENSSL_free(der);
+    der = NULL;
+
+    /*
+     * display the hash of the public key as it would appear in OCSP requests
+     */
+    if (BIO_printf(bp, "\n        Public key OCSP hash: ") <= 0)
+        goto err;
+
+    keybstr = X509_get0_pubkey_bitstr(x);
+
+    if (keybstr == NULL)
+        goto err;
+
+    if (!EVP_Digest(ASN1_STRING_get0_data(keybstr),
+                    ASN1_STRING_length(keybstr), SHA1md, NULL, EVP_sha1(),
+                    NULL))
+        goto err;
+    for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
+        if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
+            goto err;
+    }
+    BIO_printf(bp, "\n");
+
+    return (1);
+ err:
+    OPENSSL_free(der);
+    return (0);
+}
+
+int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent)
+{
+    const unsigned char *s;
+    int i, n;
+
+    n = sig->length;
+    s = sig->data;
+    for (i = 0; i < n; i++) {
+        if ((i % 18) == 0) {
+            if (BIO_write(bp, "\n", 1) <= 0)
+                return 0;
+            if (BIO_indent(bp, indent, indent) <= 0)
+                return 0;
+        }
+        if (BIO_printf(bp, "%02x%s", s[i], ((i + 1) == n) ? "" : ":") <= 0)
+            return 0;
+    }
+    if (BIO_write(bp, "\n", 1) != 1)
+        return 0;
+
+    return 1;
+}
+
+int X509_signature_print(BIO *bp, const X509_ALGOR *sigalg,
+                         const ASN1_STRING *sig)
+{
+    int sig_nid;
+    if (BIO_puts(bp, "    Signature Algorithm: ") <= 0)
+        return 0;
+    if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0)
+        return 0;
+
+    sig_nid = OBJ_obj2nid(sigalg->algorithm);
+    if (sig_nid != NID_undef) {
+        int pkey_nid, dig_nid;
+        const EVP_PKEY_ASN1_METHOD *ameth;
+        if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid)) {
+            ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
+            if (ameth && ameth->sig_print)
+                return ameth->sig_print(bp, sigalg, sig, 9, 0);
+        }
+    }
+    if (sig)
+        return X509_signature_dump(bp, sig, 9);
+    else if (BIO_puts(bp, "\n") <= 0)
+        return 0;
+    return 1;
+}
+
+int X509_aux_print(BIO *out, X509 *x, int indent)
+{
+    char oidstr[80], first;
+    STACK_OF(ASN1_OBJECT) *trust, *reject;
+    const unsigned char *alias, *keyid;
+    int keyidlen;
+    int i;
+    if (X509_trusted(x) == 0)
+        return 1;
+    trust = X509_get0_trust_objects(x);
+    reject = X509_get0_reject_objects(x);
+    if (trust) {
+        first = 1;
+        BIO_printf(out, "%*sTrusted Uses:\n%*s", indent, "", indent + 2, "");
+        for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) {
+            if (!first)
+                BIO_puts(out, ", ");
+            else
+                first = 0;
+            OBJ_obj2txt(oidstr, sizeof oidstr,
+                        sk_ASN1_OBJECT_value(trust, i), 0);
+            BIO_puts(out, oidstr);
+        }
+        BIO_puts(out, "\n");
+    } else
+        BIO_printf(out, "%*sNo Trusted Uses.\n", indent, "");
+    if (reject) {
+        first = 1;
+        BIO_printf(out, "%*sRejected Uses:\n%*s", indent, "", indent + 2, "");
+        for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) {
+            if (!first)
+                BIO_puts(out, ", ");
+            else
+                first = 0;
+            OBJ_obj2txt(oidstr, sizeof oidstr,
+                        sk_ASN1_OBJECT_value(reject, i), 0);
+            BIO_puts(out, oidstr);
+        }
+        BIO_puts(out, "\n");
+    } else
+        BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
+    alias = X509_alias_get0(x, NULL);
+    if (alias)
+        BIO_printf(out, "%*sAlias: %s\n", indent, "", alias);
+    keyid = X509_keyid_get0(x, &keyidlen);
+    if (keyid) {
+        BIO_printf(out, "%*sKey Id: ", indent, "");
+        for (i = 0; i < keyidlen; i++)
+            BIO_printf(out, "%s%02X", i ? ":" : "", keyid[i]);
+        BIO_write(out, "\n", 1);
+    }
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_att.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_att.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_att.c	(revision 331)
@@ -0,0 +1,329 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/stack.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include "x509_lcl.h"
+
+int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x)
+{
+    return sk_X509_ATTRIBUTE_num(x);
+}
+
+int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
+                           int lastpos)
+{
+    const ASN1_OBJECT *obj = OBJ_nid2obj(nid);
+
+    if (obj == NULL)
+        return (-2);
+    return (X509at_get_attr_by_OBJ(x, obj, lastpos));
+}
+
+int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk,
+                           const ASN1_OBJECT *obj, int lastpos)
+{
+    int n;
+    X509_ATTRIBUTE *ex;
+
+    if (sk == NULL)
+        return (-1);
+    lastpos++;
+    if (lastpos < 0)
+        lastpos = 0;
+    n = sk_X509_ATTRIBUTE_num(sk);
+    for (; lastpos < n; lastpos++) {
+        ex = sk_X509_ATTRIBUTE_value(sk, lastpos);
+        if (OBJ_cmp(ex->object, obj) == 0)
+            return (lastpos);
+    }
+    return (-1);
+}
+
+X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc)
+{
+    if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0)
+        return NULL;
+    else
+        return sk_X509_ATTRIBUTE_value(x, loc);
+}
+
+X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc)
+{
+    X509_ATTRIBUTE *ret;
+
+    if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0)
+        return (NULL);
+    ret = sk_X509_ATTRIBUTE_delete(x, loc);
+    return (ret);
+}
+
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
+                                           X509_ATTRIBUTE *attr)
+{
+    X509_ATTRIBUTE *new_attr = NULL;
+    STACK_OF(X509_ATTRIBUTE) *sk = NULL;
+
+    if (x == NULL) {
+        X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_PASSED_NULL_PARAMETER);
+        goto err2;
+    }
+
+    if (*x == NULL) {
+        if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL)
+            goto err;
+    } else
+        sk = *x;
+
+    if ((new_attr = X509_ATTRIBUTE_dup(attr)) == NULL)
+        goto err2;
+    if (!sk_X509_ATTRIBUTE_push(sk, new_attr))
+        goto err;
+    if (*x == NULL)
+        *x = sk;
+    return (sk);
+ err:
+    X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_MALLOC_FAILURE);
+ err2:
+    X509_ATTRIBUTE_free(new_attr);
+    sk_X509_ATTRIBUTE_free(sk);
+    return (NULL);
+}
+
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE)
+                                                  **x, const ASN1_OBJECT *obj,
+                                                  int type,
+                                                  const unsigned char *bytes,
+                                                  int len)
+{
+    X509_ATTRIBUTE *attr;
+    STACK_OF(X509_ATTRIBUTE) *ret;
+    attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len);
+    if (!attr)
+        return 0;
+    ret = X509at_add1_attr(x, attr);
+    X509_ATTRIBUTE_free(attr);
+    return ret;
+}
+
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE)
+                                                  **x, int nid, int type,
+                                                  const unsigned char *bytes,
+                                                  int len)
+{
+    X509_ATTRIBUTE *attr;
+    STACK_OF(X509_ATTRIBUTE) *ret;
+    attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len);
+    if (!attr)
+        return 0;
+    ret = X509at_add1_attr(x, attr);
+    X509_ATTRIBUTE_free(attr);
+    return ret;
+}
+
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE)
+                                                  **x, const char *attrname,
+                                                  int type,
+                                                  const unsigned char *bytes,
+                                                  int len)
+{
+    X509_ATTRIBUTE *attr;
+    STACK_OF(X509_ATTRIBUTE) *ret;
+    attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len);
+    if (!attr)
+        return 0;
+    ret = X509at_add1_attr(x, attr);
+    X509_ATTRIBUTE_free(attr);
+    return ret;
+}
+
+void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x,
+                              const ASN1_OBJECT *obj, int lastpos, int type)
+{
+    int i;
+    X509_ATTRIBUTE *at;
+    i = X509at_get_attr_by_OBJ(x, obj, lastpos);
+    if (i == -1)
+        return NULL;
+    if ((lastpos <= -2) && (X509at_get_attr_by_OBJ(x, obj, i) != -1))
+        return NULL;
+    at = X509at_get_attr(x, i);
+    if (lastpos <= -3 && (X509_ATTRIBUTE_count(at) != 1))
+        return NULL;
+    return X509_ATTRIBUTE_get0_data(at, 0, type, NULL);
+}
+
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
+                                             int atrtype, const void *data,
+                                             int len)
+{
+    ASN1_OBJECT *obj;
+    X509_ATTRIBUTE *ret;
+
+    obj = OBJ_nid2obj(nid);
+    if (obj == NULL) {
+        X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_NID, X509_R_UNKNOWN_NID);
+        return (NULL);
+    }
+    ret = X509_ATTRIBUTE_create_by_OBJ(attr, obj, atrtype, data, len);
+    if (ret == NULL)
+        ASN1_OBJECT_free(obj);
+    return (ret);
+}
+
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
+                                             const ASN1_OBJECT *obj,
+                                             int atrtype, const void *data,
+                                             int len)
+{
+    X509_ATTRIBUTE *ret;
+
+    if ((attr == NULL) || (*attr == NULL)) {
+        if ((ret = X509_ATTRIBUTE_new()) == NULL) {
+            X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ,
+                    ERR_R_MALLOC_FAILURE);
+            return (NULL);
+        }
+    } else
+        ret = *attr;
+
+    if (!X509_ATTRIBUTE_set1_object(ret, obj))
+        goto err;
+    if (!X509_ATTRIBUTE_set1_data(ret, atrtype, data, len))
+        goto err;
+
+    if ((attr != NULL) && (*attr == NULL))
+        *attr = ret;
+    return (ret);
+ err:
+    if ((attr == NULL) || (ret != *attr))
+        X509_ATTRIBUTE_free(ret);
+    return (NULL);
+}
+
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
+                                             const char *atrname, int type,
+                                             const unsigned char *bytes,
+                                             int len)
+{
+    ASN1_OBJECT *obj;
+    X509_ATTRIBUTE *nattr;
+
+    obj = OBJ_txt2obj(atrname, 0);
+    if (obj == NULL) {
+        X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT,
+                X509_R_INVALID_FIELD_NAME);
+        ERR_add_error_data(2, "name=", atrname);
+        return (NULL);
+    }
+    nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len);
+    ASN1_OBJECT_free(obj);
+    return nattr;
+}
+
+int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj)
+{
+    if ((attr == NULL) || (obj == NULL))
+        return (0);
+    ASN1_OBJECT_free(attr->object);
+    attr->object = OBJ_dup(obj);
+    return attr->object != NULL;
+}
+
+int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
+                             const void *data, int len)
+{
+    ASN1_TYPE *ttmp = NULL;
+    ASN1_STRING *stmp = NULL;
+    int atype = 0;
+    if (!attr)
+        return 0;
+    if (attrtype & MBSTRING_FLAG) {
+        stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype,
+                                      OBJ_obj2nid(attr->object));
+        if (!stmp) {
+            X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_ASN1_LIB);
+            return 0;
+        }
+        atype = stmp->type;
+    } else if (len != -1) {
+        if ((stmp = ASN1_STRING_type_new(attrtype)) == NULL)
+            goto err;
+        if (!ASN1_STRING_set(stmp, data, len))
+            goto err;
+        atype = attrtype;
+    }
+    /*
+     * This is a bit naughty because the attribute should really have at
+     * least one value but some types use and zero length SET and require
+     * this.
+     */
+    if (attrtype == 0) {
+        ASN1_STRING_free(stmp);
+        return 1;
+    }
+    if ((ttmp = ASN1_TYPE_new()) == NULL)
+        goto err;
+    if ((len == -1) && !(attrtype & MBSTRING_FLAG)) {
+        if (!ASN1_TYPE_set1(ttmp, attrtype, data))
+            goto err;
+    } else {
+        ASN1_TYPE_set(ttmp, atype, stmp);
+        stmp = NULL;
+    }
+    if (!sk_ASN1_TYPE_push(attr->set, ttmp))
+        goto err;
+    return 1;
+ err:
+    X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_MALLOC_FAILURE);
+    ASN1_TYPE_free(ttmp);
+    ASN1_STRING_free(stmp);
+    return 0;
+}
+
+int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr)
+{
+    if (attr == NULL)
+        return 0;
+    return sk_ASN1_TYPE_num(attr->set);
+}
+
+ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr)
+{
+    if (attr == NULL)
+        return (NULL);
+    return (attr->object);
+}
+
+void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
+                               int atrtype, void *data)
+{
+    ASN1_TYPE *ttmp;
+    ttmp = X509_ATTRIBUTE_get0_type(attr, idx);
+    if (!ttmp)
+        return NULL;
+    if (atrtype != ASN1_TYPE_get(ttmp)) {
+        X509err(X509_F_X509_ATTRIBUTE_GET0_DATA, X509_R_WRONG_TYPE);
+        return NULL;
+    }
+    return ttmp->value.ptr;
+}
+
+ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx)
+{
+    if (attr == NULL)
+        return NULL;
+    return sk_ASN1_TYPE_value(attr->set, idx);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_cmp.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_cmp.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_cmp.c	(revision 331)
@@ -0,0 +1,459 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <ctype.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include "internal/x509_int.h"
+
+int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b)
+{
+    int i;
+    const X509_CINF *ai, *bi;
+
+    ai = &a->cert_info;
+    bi = &b->cert_info;
+    i = ASN1_INTEGER_cmp(&ai->serialNumber, &bi->serialNumber);
+    if (i)
+        return (i);
+    return (X509_NAME_cmp(ai->issuer, bi->issuer));
+}
+
+#ifndef OPENSSL_NO_MD5
+unsigned long X509_issuer_and_serial_hash(X509 *a)
+{
+    unsigned long ret = 0;
+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+    unsigned char md[16];
+    char *f;
+
+    if (ctx == NULL)
+        goto err;
+    f = X509_NAME_oneline(a->cert_info.issuer, NULL, 0);
+    if (!EVP_DigestInit_ex(ctx, EVP_md5(), NULL))
+        goto err;
+    if (!EVP_DigestUpdate(ctx, (unsigned char *)f, strlen(f)))
+        goto err;
+    OPENSSL_free(f);
+    if (!EVP_DigestUpdate
+        (ctx, (unsigned char *)a->cert_info.serialNumber.data,
+         (unsigned long)a->cert_info.serialNumber.length))
+        goto err;
+    if (!EVP_DigestFinal_ex(ctx, &(md[0]), NULL))
+        goto err;
+    ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
+           ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
+        ) & 0xffffffffL;
+ err:
+    EVP_MD_CTX_free(ctx);
+    return (ret);
+}
+#endif
+
+int X509_issuer_name_cmp(const X509 *a, const X509 *b)
+{
+    return (X509_NAME_cmp(a->cert_info.issuer, b->cert_info.issuer));
+}
+
+int X509_subject_name_cmp(const X509 *a, const X509 *b)
+{
+    return (X509_NAME_cmp(a->cert_info.subject, b->cert_info.subject));
+}
+
+int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b)
+{
+    return (X509_NAME_cmp(a->crl.issuer, b->crl.issuer));
+}
+
+int X509_CRL_match(const X509_CRL *a, const X509_CRL *b)
+{
+    return memcmp(a->sha1_hash, b->sha1_hash, 20);
+}
+
+X509_NAME *X509_get_issuer_name(const X509 *a)
+{
+    return (a->cert_info.issuer);
+}
+
+unsigned long X509_issuer_name_hash(X509 *x)
+{
+    return (X509_NAME_hash(x->cert_info.issuer));
+}
+
+#ifndef OPENSSL_NO_MD5
+unsigned long X509_issuer_name_hash_old(X509 *x)
+{
+    return (X509_NAME_hash_old(x->cert_info.issuer));
+}
+#endif
+
+X509_NAME *X509_get_subject_name(const X509 *a)
+{
+    return (a->cert_info.subject);
+}
+
+ASN1_INTEGER *X509_get_serialNumber(X509 *a)
+{
+    return &a->cert_info.serialNumber;
+}
+
+const ASN1_INTEGER *X509_get0_serialNumber(const X509 *a)
+{
+    return &a->cert_info.serialNumber;
+}
+
+unsigned long X509_subject_name_hash(X509 *x)
+{
+    return (X509_NAME_hash(x->cert_info.subject));
+}
+
+#ifndef OPENSSL_NO_MD5
+unsigned long X509_subject_name_hash_old(X509 *x)
+{
+    return (X509_NAME_hash_old(x->cert_info.subject));
+}
+#endif
+
+/*
+ * Compare two certificates: they must be identical for this to work. NB:
+ * Although "cmp" operations are generally prototyped to take "const"
+ * arguments (eg. for use in STACKs), the way X509 handling is - these
+ * operations may involve ensuring the hashes are up-to-date and ensuring
+ * certain cert information is cached. So this is the point where the
+ * "depth-first" constification tree has to halt with an evil cast.
+ */
+int X509_cmp(const X509 *a, const X509 *b)
+{
+    int rv;
+    /* ensure hash is valid */
+    X509_check_purpose((X509 *)a, -1, 0);
+    X509_check_purpose((X509 *)b, -1, 0);
+
+    rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH);
+    if (rv)
+        return rv;
+    /* Check for match against stored encoding too */
+    if (!a->cert_info.enc.modified && !b->cert_info.enc.modified) {
+        if (a->cert_info.enc.len < b->cert_info.enc.len)
+            return -1;
+        if (a->cert_info.enc.len > b->cert_info.enc.len)
+            return 1;
+        return memcmp(a->cert_info.enc.enc, b->cert_info.enc.enc,
+                      a->cert_info.enc.len);
+    }
+    return rv;
+}
+
+int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
+{
+    int ret;
+
+    /* Ensure canonical encoding is present and up to date */
+
+    if (!a->canon_enc || a->modified) {
+        ret = i2d_X509_NAME((X509_NAME *)a, NULL);
+        if (ret < 0)
+            return -2;
+    }
+
+    if (!b->canon_enc || b->modified) {
+        ret = i2d_X509_NAME((X509_NAME *)b, NULL);
+        if (ret < 0)
+            return -2;
+    }
+
+    ret = a->canon_enclen - b->canon_enclen;
+
+    if (ret)
+        return ret;
+
+    return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen);
+
+}
+
+unsigned long X509_NAME_hash(X509_NAME *x)
+{
+    unsigned long ret = 0;
+    unsigned char md[SHA_DIGEST_LENGTH];
+
+    /* Make sure X509_NAME structure contains valid cached encoding */
+    i2d_X509_NAME(x, NULL);
+    if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(),
+                    NULL))
+        return 0;
+
+    ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
+           ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
+        ) & 0xffffffffL;
+    return (ret);
+}
+
+#ifndef OPENSSL_NO_MD5
+/*
+ * I now DER encode the name and hash it.  Since I cache the DER encoding,
+ * this is reasonably efficient.
+ */
+
+unsigned long X509_NAME_hash_old(X509_NAME *x)
+{
+    EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
+    unsigned long ret = 0;
+    unsigned char md[16];
+
+    if (md_ctx == NULL)
+        return ret;
+
+    /* Make sure X509_NAME structure contains valid cached encoding */
+    i2d_X509_NAME(x, NULL);
+    EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+    if (EVP_DigestInit_ex(md_ctx, EVP_md5(), NULL)
+        && EVP_DigestUpdate(md_ctx, x->bytes->data, x->bytes->length)
+        && EVP_DigestFinal_ex(md_ctx, md, NULL))
+        ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
+               ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
+            ) & 0xffffffffL;
+    EVP_MD_CTX_free(md_ctx);
+
+    return (ret);
+}
+#endif
+
+/* Search a stack of X509 for a match */
+X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
+                                     ASN1_INTEGER *serial)
+{
+    int i;
+    X509 x, *x509 = NULL;
+
+    if (!sk)
+        return NULL;
+
+    x.cert_info.serialNumber = *serial;
+    x.cert_info.issuer = name;
+
+    for (i = 0; i < sk_X509_num(sk); i++) {
+        x509 = sk_X509_value(sk, i);
+        if (X509_issuer_and_serial_cmp(x509, &x) == 0)
+            return (x509);
+    }
+    return (NULL);
+}
+
+X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name)
+{
+    X509 *x509;
+    int i;
+
+    for (i = 0; i < sk_X509_num(sk); i++) {
+        x509 = sk_X509_value(sk, i);
+        if (X509_NAME_cmp(X509_get_subject_name(x509), name) == 0)
+            return (x509);
+    }
+    return (NULL);
+}
+
+EVP_PKEY *X509_get0_pubkey(const X509 *x)
+{
+    if (x == NULL)
+        return NULL;
+    return X509_PUBKEY_get0(x->cert_info.key);
+}
+
+EVP_PKEY *X509_get_pubkey(X509 *x)
+{
+    if (x == NULL)
+        return NULL;
+    return X509_PUBKEY_get(x->cert_info.key);
+}
+
+int X509_check_private_key(const X509 *x, const EVP_PKEY *k)
+{
+    const EVP_PKEY *xk;
+    int ret;
+
+    xk = X509_get0_pubkey(x);
+
+    if (xk)
+        ret = EVP_PKEY_cmp(xk, k);
+    else
+        ret = -2;
+
+    switch (ret) {
+    case 1:
+        break;
+    case 0:
+        X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_VALUES_MISMATCH);
+        break;
+    case -1:
+        X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_TYPE_MISMATCH);
+        break;
+    case -2:
+        X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_UNKNOWN_KEY_TYPE);
+    }
+    if (ret > 0)
+        return 1;
+    return 0;
+}
+
+/*
+ * Check a suite B algorithm is permitted: pass in a public key and the NID
+ * of its signature (or 0 if no signature). The pflags is a pointer to a
+ * flags field which must contain the suite B verification flags.
+ */
+
+#ifndef OPENSSL_NO_EC
+
+static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags)
+{
+    const EC_GROUP *grp = NULL;
+    int curve_nid;
+    if (pkey && EVP_PKEY_id(pkey) == EVP_PKEY_EC)
+        grp = EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey));
+    if (!grp)
+        return X509_V_ERR_SUITE_B_INVALID_ALGORITHM;
+    curve_nid = EC_GROUP_get_curve_name(grp);
+    /* Check curve is consistent with LOS */
+    if (curve_nid == NID_secp384r1) { /* P-384 */
+        /*
+         * Check signature algorithm is consistent with curve.
+         */
+        if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA384)
+            return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
+        if (!(*pflags & X509_V_FLAG_SUITEB_192_LOS))
+            return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
+        /* If we encounter P-384 we cannot use P-256 later */
+        *pflags &= ~X509_V_FLAG_SUITEB_128_LOS_ONLY;
+    } else if (curve_nid == NID_X9_62_prime256v1) { /* P-256 */
+        if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA256)
+            return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM;
+        if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY))
+            return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED;
+    } else
+        return X509_V_ERR_SUITE_B_INVALID_CURVE;
+
+    return X509_V_OK;
+}
+
+int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
+                            unsigned long flags)
+{
+    int rv, i, sign_nid;
+    EVP_PKEY *pk;
+    unsigned long tflags = flags;
+
+    if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
+        return X509_V_OK;
+
+    /* If no EE certificate passed in must be first in chain */
+    if (x == NULL) {
+        x = sk_X509_value(chain, 0);
+        i = 1;
+    } else
+        i = 0;
+
+    pk = X509_get0_pubkey(x);
+
+    /*
+     * With DANE-EE(3) success, or DANE-EE(3)/PKIX-EE(1) failure we don't build
+     * a chain all, just report trust success or failure, but must also report
+     * Suite-B errors if applicable.  This is indicated via a NULL chain
+     * pointer.  All we need to do is check the leaf key algorithm.
+     */
+    if (chain == NULL)
+        return check_suite_b(pk, -1, &tflags);
+
+    if (X509_get_version(x) != 2) {
+        rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
+        /* Correct error depth */
+        i = 0;
+        goto end;
+    }
+
+    /* Check EE key only */
+    rv = check_suite_b(pk, -1, &tflags);
+    if (rv != X509_V_OK) {
+        /* Correct error depth */
+        i = 0;
+        goto end;
+    }
+    for (; i < sk_X509_num(chain); i++) {
+        sign_nid = X509_get_signature_nid(x);
+        x = sk_X509_value(chain, i);
+        if (X509_get_version(x) != 2) {
+            rv = X509_V_ERR_SUITE_B_INVALID_VERSION;
+            goto end;
+        }
+        pk = X509_get0_pubkey(x);
+        rv = check_suite_b(pk, sign_nid, &tflags);
+        if (rv != X509_V_OK)
+            goto end;
+    }
+
+    /* Final check: root CA signature */
+    rv = check_suite_b(pk, X509_get_signature_nid(x), &tflags);
+ end:
+    if (rv != X509_V_OK) {
+        /* Invalid signature or LOS errors are for previous cert */
+        if ((rv == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM
+             || rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED) && i)
+            i--;
+        /*
+         * If we have LOS error and flags changed then we are signing P-384
+         * with P-256. Use more meaningful error.
+         */
+        if (rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED && flags != tflags)
+            rv = X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256;
+        if (perror_depth)
+            *perror_depth = i;
+    }
+    return rv;
+}
+
+int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags)
+{
+    int sign_nid;
+    if (!(flags & X509_V_FLAG_SUITEB_128_LOS))
+        return X509_V_OK;
+    sign_nid = OBJ_obj2nid(crl->crl.sig_alg.algorithm);
+    return check_suite_b(pk, sign_nid, &flags);
+}
+
+#else
+int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain,
+                            unsigned long flags)
+{
+    return 0;
+}
+
+int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags)
+{
+    return 0;
+}
+
+#endif
+/*
+ * Not strictly speaking an "up_ref" as a STACK doesn't have a reference
+ * count but it has the same effect by duping the STACK and upping the ref of
+ * each X509 structure.
+ */
+STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain)
+{
+    STACK_OF(X509) *ret;
+    int i;
+    ret = sk_X509_dup(chain);
+    for (i = 0; i < sk_X509_num(ret); i++) {
+        X509 *x = sk_X509_value(ret, i);
+        X509_up_ref(x);
+    }
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_d2.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_d2.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_d2.c	(revision 331)
@@ -0,0 +1,57 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+
+int X509_STORE_set_default_paths(X509_STORE *ctx)
+{
+    X509_LOOKUP *lookup;
+
+    lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file());
+    if (lookup == NULL)
+        return (0);
+    X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
+
+    lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir());
+    if (lookup == NULL)
+        return (0);
+    X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
+
+    /* clear any errors */
+    ERR_clear_error();
+
+    return (1);
+}
+
+int X509_STORE_load_locations(X509_STORE *ctx, const char *file,
+                              const char *path)
+{
+    X509_LOOKUP *lookup;
+
+    if (file != NULL) {
+        lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file());
+        if (lookup == NULL)
+            return (0);
+        if (X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) != 1)
+            return (0);
+    }
+    if (path != NULL) {
+        lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir());
+        if (lookup == NULL)
+            return (0);
+        if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1)
+            return (0);
+    }
+    if ((path == NULL) && (file == NULL))
+        return (0);
+    return (1);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_def.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_def.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_def.c	(revision 331)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/crypto.h>
+#include <openssl/x509.h>
+
+const char *X509_get_default_private_dir(void)
+{
+    return (X509_PRIVATE_DIR);
+}
+
+const char *X509_get_default_cert_area(void)
+{
+    return (X509_CERT_AREA);
+}
+
+const char *X509_get_default_cert_dir(void)
+{
+    return (X509_CERT_DIR);
+}
+
+const char *X509_get_default_cert_file(void)
+{
+    return (X509_CERT_FILE);
+}
+
+const char *X509_get_default_cert_dir_env(void)
+{
+    return (X509_CERT_DIR_EVP);
+}
+
+const char *X509_get_default_cert_file_env(void)
+{
+    return (X509_CERT_FILE_EVP);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_err.c	(revision 331)
@@ -0,0 +1,142 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/x509.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509,0,reason)
+
+static ERR_STRING_DATA X509_str_functs[] = {
+    {ERR_FUNC(X509_F_ADD_CERT_DIR), "add_cert_dir"},
+    {ERR_FUNC(X509_F_BUILD_CHAIN), "build_chain"},
+    {ERR_FUNC(X509_F_BY_FILE_CTRL), "by_file_ctrl"},
+    {ERR_FUNC(X509_F_CHECK_NAME_CONSTRAINTS), "check_name_constraints"},
+    {ERR_FUNC(X509_F_CHECK_POLICY), "check_policy"},
+    {ERR_FUNC(X509_F_DANE_I2D), "dane_i2d"},
+    {ERR_FUNC(X509_F_DIR_CTRL), "dir_ctrl"},
+    {ERR_FUNC(X509_F_GET_CERT_BY_SUBJECT), "get_cert_by_subject"},
+    {ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_DECODE), "NETSCAPE_SPKI_b64_decode"},
+    {ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_ENCODE), "NETSCAPE_SPKI_b64_encode"},
+    {ERR_FUNC(X509_F_X509AT_ADD1_ATTR), "X509at_add1_attr"},
+    {ERR_FUNC(X509_F_X509V3_ADD_EXT), "X509v3_add_ext"},
+    {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_NID),
+     "X509_ATTRIBUTE_create_by_NID"},
+    {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ),
+     "X509_ATTRIBUTE_create_by_OBJ"},
+    {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT),
+     "X509_ATTRIBUTE_create_by_txt"},
+    {ERR_FUNC(X509_F_X509_ATTRIBUTE_GET0_DATA), "X509_ATTRIBUTE_get0_data"},
+    {ERR_FUNC(X509_F_X509_ATTRIBUTE_SET1_DATA), "X509_ATTRIBUTE_set1_data"},
+    {ERR_FUNC(X509_F_X509_CHECK_PRIVATE_KEY), "X509_check_private_key"},
+    {ERR_FUNC(X509_F_X509_CRL_DIFF), "X509_CRL_diff"},
+    {ERR_FUNC(X509_F_X509_CRL_PRINT_FP), "X509_CRL_print_fp"},
+    {ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_NID),
+     "X509_EXTENSION_create_by_NID"},
+    {ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_OBJ),
+     "X509_EXTENSION_create_by_OBJ"},
+    {ERR_FUNC(X509_F_X509_GET_PUBKEY_PARAMETERS),
+     "X509_get_pubkey_parameters"},
+    {ERR_FUNC(X509_F_X509_LOAD_CERT_CRL_FILE), "X509_load_cert_crl_file"},
+    {ERR_FUNC(X509_F_X509_LOAD_CERT_FILE), "X509_load_cert_file"},
+    {ERR_FUNC(X509_F_X509_LOAD_CRL_FILE), "X509_load_crl_file"},
+    {ERR_FUNC(X509_F_X509_NAME_ADD_ENTRY), "X509_NAME_add_entry"},
+    {ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_NID),
+     "X509_NAME_ENTRY_create_by_NID"},
+    {ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT),
+     "X509_NAME_ENTRY_create_by_txt"},
+    {ERR_FUNC(X509_F_X509_NAME_ENTRY_SET_OBJECT),
+     "X509_NAME_ENTRY_set_object"},
+    {ERR_FUNC(X509_F_X509_NAME_ONELINE), "X509_NAME_oneline"},
+    {ERR_FUNC(X509_F_X509_NAME_PRINT), "X509_NAME_print"},
+    {ERR_FUNC(X509_F_X509_OBJECT_NEW), "X509_OBJECT_new"},
+    {ERR_FUNC(X509_F_X509_PRINT_EX_FP), "X509_print_ex_fp"},
+    {ERR_FUNC(X509_F_X509_PUBKEY_DECODE), "x509_pubkey_decode"},
+    {ERR_FUNC(X509_F_X509_PUBKEY_GET0), "X509_PUBKEY_get0"},
+    {ERR_FUNC(X509_F_X509_PUBKEY_SET), "X509_PUBKEY_set"},
+    {ERR_FUNC(X509_F_X509_REQ_CHECK_PRIVATE_KEY),
+     "X509_REQ_check_private_key"},
+    {ERR_FUNC(X509_F_X509_REQ_PRINT_EX), "X509_REQ_print_ex"},
+    {ERR_FUNC(X509_F_X509_REQ_PRINT_FP), "X509_REQ_print_fp"},
+    {ERR_FUNC(X509_F_X509_REQ_TO_X509), "X509_REQ_to_X509"},
+    {ERR_FUNC(X509_F_X509_STORE_ADD_CERT), "X509_STORE_add_cert"},
+    {ERR_FUNC(X509_F_X509_STORE_ADD_CRL), "X509_STORE_add_crl"},
+    {ERR_FUNC(X509_F_X509_STORE_CTX_GET1_ISSUER),
+     "X509_STORE_CTX_get1_issuer"},
+    {ERR_FUNC(X509_F_X509_STORE_CTX_INIT), "X509_STORE_CTX_init"},
+    {ERR_FUNC(X509_F_X509_STORE_CTX_NEW), "X509_STORE_CTX_new"},
+    {ERR_FUNC(X509_F_X509_STORE_CTX_PURPOSE_INHERIT),
+     "X509_STORE_CTX_purpose_inherit"},
+    {ERR_FUNC(X509_F_X509_TO_X509_REQ), "X509_to_X509_REQ"},
+    {ERR_FUNC(X509_F_X509_TRUST_ADD), "X509_TRUST_add"},
+    {ERR_FUNC(X509_F_X509_TRUST_SET), "X509_TRUST_set"},
+    {ERR_FUNC(X509_F_X509_VERIFY_CERT), "X509_verify_cert"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA X509_str_reasons[] = {
+    {ERR_REASON(X509_R_AKID_MISMATCH), "akid mismatch"},
+    {ERR_REASON(X509_R_BAD_SELECTOR), "bad selector"},
+    {ERR_REASON(X509_R_BAD_X509_FILETYPE), "bad x509 filetype"},
+    {ERR_REASON(X509_R_BASE64_DECODE_ERROR), "base64 decode error"},
+    {ERR_REASON(X509_R_CANT_CHECK_DH_KEY), "cant check dh key"},
+    {ERR_REASON(X509_R_CERT_ALREADY_IN_HASH_TABLE),
+     "cert already in hash table"},
+    {ERR_REASON(X509_R_CRL_ALREADY_DELTA), "crl already delta"},
+    {ERR_REASON(X509_R_CRL_VERIFY_FAILURE), "crl verify failure"},
+    {ERR_REASON(X509_R_IDP_MISMATCH), "idp mismatch"},
+    {ERR_REASON(X509_R_INVALID_DIRECTORY), "invalid directory"},
+    {ERR_REASON(X509_R_INVALID_FIELD_NAME), "invalid field name"},
+    {ERR_REASON(X509_R_INVALID_TRUST), "invalid trust"},
+    {ERR_REASON(X509_R_ISSUER_MISMATCH), "issuer mismatch"},
+    {ERR_REASON(X509_R_KEY_TYPE_MISMATCH), "key type mismatch"},
+    {ERR_REASON(X509_R_KEY_VALUES_MISMATCH), "key values mismatch"},
+    {ERR_REASON(X509_R_LOADING_CERT_DIR), "loading cert dir"},
+    {ERR_REASON(X509_R_LOADING_DEFAULTS), "loading defaults"},
+    {ERR_REASON(X509_R_METHOD_NOT_SUPPORTED), "method not supported"},
+    {ERR_REASON(X509_R_NAME_TOO_LONG), "name too long"},
+    {ERR_REASON(X509_R_NEWER_CRL_NOT_NEWER), "newer crl not newer"},
+    {ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY),
+     "no cert set for us to verify"},
+    {ERR_REASON(X509_R_NO_CRL_NUMBER), "no crl number"},
+    {ERR_REASON(X509_R_PUBLIC_KEY_DECODE_ERROR), "public key decode error"},
+    {ERR_REASON(X509_R_PUBLIC_KEY_ENCODE_ERROR), "public key encode error"},
+    {ERR_REASON(X509_R_SHOULD_RETRY), "should retry"},
+    {ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN),
+     "unable to find parameters in chain"},
+    {ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY),
+     "unable to get certs public key"},
+    {ERR_REASON(X509_R_UNKNOWN_KEY_TYPE), "unknown key type"},
+    {ERR_REASON(X509_R_UNKNOWN_NID), "unknown nid"},
+    {ERR_REASON(X509_R_UNKNOWN_PURPOSE_ID), "unknown purpose id"},
+    {ERR_REASON(X509_R_UNKNOWN_TRUST_ID), "unknown trust id"},
+    {ERR_REASON(X509_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"},
+    {ERR_REASON(X509_R_WRONG_LOOKUP_TYPE), "wrong lookup type"},
+    {ERR_REASON(X509_R_WRONG_TYPE), "wrong type"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_X509_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(X509_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, X509_str_functs);
+        ERR_load_strings(0, X509_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_ext.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_ext.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_ext.c	(revision 331)
@@ -0,0 +1,160 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/stack.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+#include <openssl/x509v3.h>
+
+int X509_CRL_get_ext_count(const X509_CRL *x)
+{
+    return (X509v3_get_ext_count(x->crl.extensions));
+}
+
+int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos)
+{
+    return (X509v3_get_ext_by_NID(x->crl.extensions, nid, lastpos));
+}
+
+int X509_CRL_get_ext_by_OBJ(const X509_CRL *x, const ASN1_OBJECT *obj,
+                            int lastpos)
+{
+    return (X509v3_get_ext_by_OBJ(x->crl.extensions, obj, lastpos));
+}
+
+int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, int lastpos)
+{
+    return (X509v3_get_ext_by_critical(x->crl.extensions, crit, lastpos));
+}
+
+X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc)
+{
+    return (X509v3_get_ext(x->crl.extensions, loc));
+}
+
+X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc)
+{
+    return (X509v3_delete_ext(x->crl.extensions, loc));
+}
+
+void *X509_CRL_get_ext_d2i(const X509_CRL *x, int nid, int *crit, int *idx)
+{
+    return X509V3_get_d2i(x->crl.extensions, nid, crit, idx);
+}
+
+int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
+                          unsigned long flags)
+{
+    return X509V3_add1_i2d(&x->crl.extensions, nid, value, crit, flags);
+}
+
+int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc)
+{
+    return (X509v3_add_ext(&(x->crl.extensions), ex, loc) != NULL);
+}
+
+int X509_get_ext_count(const X509 *x)
+{
+    return (X509v3_get_ext_count(x->cert_info.extensions));
+}
+
+int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos)
+{
+    return (X509v3_get_ext_by_NID(x->cert_info.extensions, nid, lastpos));
+}
+
+int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, int lastpos)
+{
+    return (X509v3_get_ext_by_OBJ(x->cert_info.extensions, obj, lastpos));
+}
+
+int X509_get_ext_by_critical(const X509 *x, int crit, int lastpos)
+{
+    return (X509v3_get_ext_by_critical
+            (x->cert_info.extensions, crit, lastpos));
+}
+
+X509_EXTENSION *X509_get_ext(const X509 *x, int loc)
+{
+    return (X509v3_get_ext(x->cert_info.extensions, loc));
+}
+
+X509_EXTENSION *X509_delete_ext(X509 *x, int loc)
+{
+    return (X509v3_delete_ext(x->cert_info.extensions, loc));
+}
+
+int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc)
+{
+    return (X509v3_add_ext(&(x->cert_info.extensions), ex, loc) != NULL);
+}
+
+void *X509_get_ext_d2i(const X509 *x, int nid, int *crit, int *idx)
+{
+    return X509V3_get_d2i(x->cert_info.extensions, nid, crit, idx);
+}
+
+int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
+                      unsigned long flags)
+{
+    return X509V3_add1_i2d(&x->cert_info.extensions, nid, value, crit,
+                           flags);
+}
+
+int X509_REVOKED_get_ext_count(const X509_REVOKED *x)
+{
+    return (X509v3_get_ext_count(x->extensions));
+}
+
+int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, int lastpos)
+{
+    return (X509v3_get_ext_by_NID(x->extensions, nid, lastpos));
+}
+
+int X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, const ASN1_OBJECT *obj,
+                                int lastpos)
+{
+    return (X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos));
+}
+
+int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, int crit, int lastpos)
+{
+    return (X509v3_get_ext_by_critical(x->extensions, crit, lastpos));
+}
+
+X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, int loc)
+{
+    return (X509v3_get_ext(x->extensions, loc));
+}
+
+X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc)
+{
+    return (X509v3_delete_ext(x->extensions, loc));
+}
+
+int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc)
+{
+    return (X509v3_add_ext(&(x->extensions), ex, loc) != NULL);
+}
+
+void *X509_REVOKED_get_ext_d2i(const X509_REVOKED *x, int nid, int *crit, int *idx)
+{
+    return X509V3_get_d2i(x->extensions, nid, crit, idx);
+}
+
+int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
+                              unsigned long flags)
+{
+    return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_lcl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_lcl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_lcl.h	(revision 331)
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2014-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
+ */
+
+/*
+ * This structure holds all parameters associated with a verify operation by
+ * including an X509_VERIFY_PARAM structure in related structures the
+ * parameters used can be customized
+ */
+
+struct X509_VERIFY_PARAM_st {
+    char *name;
+    time_t check_time;          /* Time to use */
+    uint32_t inh_flags;         /* Inheritance flags */
+    unsigned long flags;        /* Various verify flags */
+    int purpose;                /* purpose to check untrusted certificates */
+    int trust;                  /* trust setting to check */
+    int depth;                  /* Verify depth */
+    int auth_level;             /* Security level for chain verification */
+    STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */
+    /* Peer identity details */
+    STACK_OF(OPENSSL_STRING) *hosts; /* Set of acceptable names */
+    unsigned int hostflags;     /* Flags to control matching features */
+    char *peername;             /* Matching hostname in peer certificate */
+    char *email;                /* If not NULL email address to match */
+    size_t emaillen;
+    unsigned char *ip;          /* If not NULL IP address to match */
+    size_t iplen;               /* Length of IP address */
+};
+
+/* No error callback if depth < 0 */
+int x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth);
+
+/* a sequence of these are used */
+struct x509_attributes_st {
+    ASN1_OBJECT *object;
+    STACK_OF(ASN1_TYPE) *set;
+};
+
+struct X509_extension_st {
+    ASN1_OBJECT *object;
+    ASN1_BOOLEAN critical;
+    ASN1_OCTET_STRING value;
+};
+
+/*
+ * Method to handle CRL access. In general a CRL could be very large (several
+ * Mb) and can consume large amounts of resources if stored in memory by
+ * multiple processes. This method allows general CRL operations to be
+ * redirected to more efficient callbacks: for example a CRL entry database.
+ */
+
+#define X509_CRL_METHOD_DYNAMIC         1
+
+struct x509_crl_method_st {
+    int flags;
+    int (*crl_init) (X509_CRL *crl);
+    int (*crl_free) (X509_CRL *crl);
+    int (*crl_lookup) (X509_CRL *crl, X509_REVOKED **ret,
+                       ASN1_INTEGER *ser, X509_NAME *issuer);
+    int (*crl_verify) (X509_CRL *crl, EVP_PKEY *pk);
+};
+
+struct x509_lookup_method_st {
+    const char *name;
+    int (*new_item) (X509_LOOKUP *ctx);
+    void (*free) (X509_LOOKUP *ctx);
+    int (*init) (X509_LOOKUP *ctx);
+    int (*shutdown) (X509_LOOKUP *ctx);
+    int (*ctrl) (X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
+                 char **ret);
+    int (*get_by_subject) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+                           X509_NAME *name, X509_OBJECT *ret);
+    int (*get_by_issuer_serial) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+                                 X509_NAME *name, ASN1_INTEGER *serial,
+                                 X509_OBJECT *ret);
+    int (*get_by_fingerprint) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+                               const unsigned char *bytes, int len,
+                               X509_OBJECT *ret);
+    int (*get_by_alias) (X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+                         const char *str, int len, X509_OBJECT *ret);
+};
+
+/* This is the functions plus an instance of the local variables. */
+struct x509_lookup_st {
+    int init;                   /* have we been started */
+    int skip;                   /* don't use us. */
+    X509_LOOKUP_METHOD *method; /* the functions */
+    char *method_data;          /* method data */
+    X509_STORE *store_ctx;      /* who owns us */
+};
+
+/*
+ * This is used to hold everything.  It is used for all certificate
+ * validation.  Once we have a certificate chain, the 'verify' function is
+ * then called to actually check the cert chain.
+ */
+struct x509_store_st {
+    /* The following is a cache of trusted certs */
+    int cache;                  /* if true, stash any hits */
+    STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */
+    /* These are external lookup methods */
+    STACK_OF(X509_LOOKUP) *get_cert_methods;
+    X509_VERIFY_PARAM *param;
+    /* Callbacks for various operations */
+    /* called to verify a certificate */
+    int (*verify) (X509_STORE_CTX *ctx);
+    /* error callback */
+    int (*verify_cb) (int ok, X509_STORE_CTX *ctx);
+    /* get issuers cert from ctx */
+    int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
+    /* check issued */
+    int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
+    /* Check revocation status of chain */
+    int (*check_revocation) (X509_STORE_CTX *ctx);
+    /* retrieve CRL */
+    int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x);
+    /* Check CRL validity */
+    int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl);
+    /* Check certificate against CRL */
+    int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x);
+    /* Check policy status of the chain */
+    int (*check_policy) (X509_STORE_CTX *ctx);
+    STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm);
+    STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm);
+    int (*cleanup) (X509_STORE_CTX *ctx);
+    CRYPTO_EX_DATA ex_data;
+    int references;
+    CRYPTO_RWLOCK *lock;
+};
+
+typedef struct lookup_dir_hashes_st BY_DIR_HASH;
+typedef struct lookup_dir_entry_st BY_DIR_ENTRY;
+DEFINE_STACK_OF(BY_DIR_HASH)
+DEFINE_STACK_OF(BY_DIR_ENTRY)
+typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
+DEFINE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_lu.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_lu.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_lu.c	(revision 331)
@@ -0,0 +1,861 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+#include <openssl/x509v3.h>
+#include "x509_lcl.h"
+
+X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
+{
+    X509_LOOKUP *ret;
+
+    ret = OPENSSL_zalloc(sizeof(*ret));
+    if (ret == NULL)
+        return NULL;
+
+    ret->method = method;
+    if ((method->new_item != NULL) && !method->new_item(ret)) {
+        OPENSSL_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+void X509_LOOKUP_free(X509_LOOKUP *ctx)
+{
+    if (ctx == NULL)
+        return;
+    if ((ctx->method != NULL) && (ctx->method->free != NULL))
+        (*ctx->method->free) (ctx);
+    OPENSSL_free(ctx);
+}
+
+int X509_STORE_lock(X509_STORE *s)
+{
+    return CRYPTO_THREAD_write_lock(s->lock);
+}
+
+int X509_STORE_unlock(X509_STORE *s)
+{
+    return CRYPTO_THREAD_unlock(s->lock);
+}
+
+int X509_LOOKUP_init(X509_LOOKUP *ctx)
+{
+    if (ctx->method == NULL)
+        return 0;
+    if (ctx->method->init != NULL)
+        return ctx->method->init(ctx);
+    else
+        return 1;
+}
+
+int X509_LOOKUP_shutdown(X509_LOOKUP *ctx)
+{
+    if (ctx->method == NULL)
+        return 0;
+    if (ctx->method->shutdown != NULL)
+        return ctx->method->shutdown(ctx);
+    else
+        return 1;
+}
+
+int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
+                     char **ret)
+{
+    if (ctx->method == NULL)
+        return -1;
+    if (ctx->method->ctrl != NULL)
+        return ctx->method->ctrl(ctx, cmd, argc, argl, ret);
+    else
+        return 1;
+}
+
+int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+                           X509_NAME *name, X509_OBJECT *ret)
+{
+    if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL))
+        return 0;
+    if (ctx->skip)
+        return 0;
+    return ctx->method->get_by_subject(ctx, type, name, ret);
+}
+
+int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+                                 X509_NAME *name, ASN1_INTEGER *serial,
+                                 X509_OBJECT *ret)
+{
+    if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL))
+        return 0;
+    return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret);
+}
+
+int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+                               const unsigned char *bytes, int len,
+                               X509_OBJECT *ret)
+{
+    if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL))
+        return 0;
+    return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret);
+}
+
+int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+                         const char *str, int len, X509_OBJECT *ret)
+{
+    if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL))
+        return 0;
+    return ctx->method->get_by_alias(ctx, type, str, len, ret);
+}
+
+static int x509_object_cmp(const X509_OBJECT *const *a,
+                           const X509_OBJECT *const *b)
+{
+    int ret;
+
+    ret = ((*a)->type - (*b)->type);
+    if (ret)
+        return ret;
+    switch ((*a)->type) {
+    case X509_LU_X509:
+        ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509);
+        break;
+    case X509_LU_CRL:
+        ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl);
+        break;
+    default:
+        /* abort(); */
+        return 0;
+    }
+    return ret;
+}
+
+X509_STORE *X509_STORE_new(void)
+{
+    X509_STORE *ret;
+
+    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL)
+        return NULL;
+    if ((ret->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL)
+        goto err;
+    ret->cache = 1;
+    if ((ret->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL)
+        goto err;
+
+    if ((ret->param = X509_VERIFY_PARAM_new()) == NULL)
+        goto err;
+
+    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data))
+        goto err;
+
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL)
+        goto err;
+
+    ret->references = 1;
+    return ret;
+
+err:
+    X509_VERIFY_PARAM_free(ret->param);
+    sk_X509_OBJECT_free(ret->objs);
+    sk_X509_LOOKUP_free(ret->get_cert_methods);
+    OPENSSL_free(ret);
+    return NULL;
+}
+
+static void cleanup(X509_OBJECT *a)
+{
+    if (!a)
+        return;
+    if (a->type == X509_LU_X509) {
+        X509_free(a->data.x509);
+    } else if (a->type == X509_LU_CRL) {
+        X509_CRL_free(a->data.crl);
+    } else {
+        /* abort(); */
+    }
+
+    OPENSSL_free(a);
+}
+
+void X509_STORE_free(X509_STORE *vfy)
+{
+    int i;
+    STACK_OF(X509_LOOKUP) *sk;
+    X509_LOOKUP *lu;
+
+    if (vfy == NULL)
+        return;
+
+    CRYPTO_atomic_add(&vfy->references, -1, &i, vfy->lock);
+    REF_PRINT_COUNT("X509_STORE", vfy);
+    if (i > 0)
+        return;
+    REF_ASSERT_ISNT(i < 0);
+
+    sk = vfy->get_cert_methods;
+    for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
+        lu = sk_X509_LOOKUP_value(sk, i);
+        X509_LOOKUP_shutdown(lu);
+        X509_LOOKUP_free(lu);
+    }
+    sk_X509_LOOKUP_free(sk);
+    sk_X509_OBJECT_pop_free(vfy->objs, cleanup);
+
+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data);
+    X509_VERIFY_PARAM_free(vfy->param);
+    CRYPTO_THREAD_lock_free(vfy->lock);
+    OPENSSL_free(vfy);
+}
+
+int X509_STORE_up_ref(X509_STORE *vfy)
+{
+    int i;
+
+    if (CRYPTO_atomic_add(&vfy->references, 1, &i, vfy->lock) <= 0)
+        return 0;
+
+    REF_PRINT_COUNT("X509_STORE", a);
+    REF_ASSERT_ISNT(i < 2);
+    return ((i > 1) ? 1 : 0);
+}
+
+X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m)
+{
+    int i;
+    STACK_OF(X509_LOOKUP) *sk;
+    X509_LOOKUP *lu;
+
+    sk = v->get_cert_methods;
+    for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) {
+        lu = sk_X509_LOOKUP_value(sk, i);
+        if (m == lu->method) {
+            return lu;
+        }
+    }
+    /* a new one */
+    lu = X509_LOOKUP_new(m);
+    if (lu == NULL)
+        return NULL;
+    else {
+        lu->store_ctx = v;
+        if (sk_X509_LOOKUP_push(v->get_cert_methods, lu))
+            return lu;
+        else {
+            X509_LOOKUP_free(lu);
+            return NULL;
+        }
+    }
+}
+
+X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs,
+                                               X509_LOOKUP_TYPE type,
+                                               X509_NAME *name)
+{
+    X509_OBJECT *ret = X509_OBJECT_new();
+
+    if (ret == NULL)
+        return NULL;
+    if (!X509_STORE_CTX_get_by_subject(vs, type, name, ret)) {
+        X509_OBJECT_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type,
+                                  X509_NAME *name, X509_OBJECT *ret)
+{
+    X509_STORE *ctx = vs->ctx;
+    X509_LOOKUP *lu;
+    X509_OBJECT stmp, *tmp;
+    int i, j;
+
+    CRYPTO_THREAD_write_lock(ctx->lock);
+    tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name);
+    CRYPTO_THREAD_unlock(ctx->lock);
+
+    if (tmp == NULL || type == X509_LU_CRL) {
+        for (i = 0; i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) {
+            lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i);
+            j = X509_LOOKUP_by_subject(lu, type, name, &stmp);
+            if (j) {
+                tmp = &stmp;
+                break;
+            }
+        }
+        if (tmp == NULL)
+            return 0;
+    }
+
+    ret->type = tmp->type;
+    ret->data.ptr = tmp->data.ptr;
+
+    X509_OBJECT_up_ref_count(ret);
+
+    return 1;
+}
+
+int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
+{
+    X509_OBJECT *obj;
+    int ret = 1, added = 1;
+
+    if (x == NULL)
+        return 0;
+    obj = X509_OBJECT_new();
+    if (obj == NULL)
+        return 0;
+    obj->type = X509_LU_X509;
+    obj->data.x509 = x;
+    X509_OBJECT_up_ref_count(obj);
+
+    CRYPTO_THREAD_write_lock(ctx->lock);
+
+    if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
+        X509err(X509_F_X509_STORE_ADD_CERT,
+                X509_R_CERT_ALREADY_IN_HASH_TABLE);
+        ret = 0;
+    } else {
+        added = sk_X509_OBJECT_push(ctx->objs, obj);
+        ret = added != 0;
+    }
+
+    CRYPTO_THREAD_unlock(ctx->lock);
+
+    if (!ret)                   /* obj not pushed */
+        X509_OBJECT_free(obj);
+    if (!added)                 /* on push failure */
+        X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE);
+
+    return ret;
+}
+
+int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
+{
+    X509_OBJECT *obj;
+    int ret = 1, added = 1;
+
+    if (x == NULL)
+        return 0;
+    obj = X509_OBJECT_new();
+    if (obj == NULL)
+        return 0;
+    obj->type = X509_LU_CRL;
+    obj->data.crl = x;
+    X509_OBJECT_up_ref_count(obj);
+
+    CRYPTO_THREAD_write_lock(ctx->lock);
+
+    if (X509_OBJECT_retrieve_match(ctx->objs, obj)) {
+        X509err(X509_F_X509_STORE_ADD_CRL, X509_R_CERT_ALREADY_IN_HASH_TABLE);
+        ret = 0;
+    } else {
+        added = sk_X509_OBJECT_push(ctx->objs, obj);
+        ret = added != 0;
+    }
+
+    CRYPTO_THREAD_unlock(ctx->lock);
+
+    if (!ret)                   /* obj not pushed */
+        X509_OBJECT_free(obj);
+    if (!added)                 /* on push failure */
+        X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE);
+
+    return ret;
+}
+
+int X509_OBJECT_up_ref_count(X509_OBJECT *a)
+{
+    switch (a->type) {
+    default:
+        break;
+    case X509_LU_X509:
+        return X509_up_ref(a->data.x509);
+    case X509_LU_CRL:
+        return X509_CRL_up_ref(a->data.crl);
+    }
+    return 1;
+}
+
+X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a)
+{
+    if (a == NULL || a->type != X509_LU_X509)
+        return NULL;
+    return a->data.x509;
+}
+
+X509_CRL *X509_OBJECT_get0_X509_CRL(X509_OBJECT *a)
+{
+    if (a == NULL || a->type != X509_LU_CRL)
+        return NULL;
+    return a->data.crl;
+}
+
+X509_LOOKUP_TYPE X509_OBJECT_get_type(const X509_OBJECT *a)
+{
+    return a->type;
+}
+
+X509_OBJECT *X509_OBJECT_new()
+{
+    X509_OBJECT *ret = OPENSSL_zalloc(sizeof(*ret));
+
+    if (ret == NULL) {
+        X509err(X509_F_X509_OBJECT_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    ret->type = X509_LU_NONE;
+    return ret;
+}
+
+
+void X509_OBJECT_free(X509_OBJECT *a)
+{
+    if (a == NULL)
+        return;
+    switch (a->type) {
+    default:
+        break;
+    case X509_LU_X509:
+        X509_free(a->data.x509);
+        break;
+    case X509_LU_CRL:
+        X509_CRL_free(a->data.crl);
+        break;
+    }
+    OPENSSL_free(a);
+}
+
+static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
+                               X509_NAME *name, int *pnmatch)
+{
+    X509_OBJECT stmp;
+    X509 x509_s;
+    X509_CRL crl_s;
+    int idx;
+
+    stmp.type = type;
+    switch (type) {
+    case X509_LU_X509:
+        stmp.data.x509 = &x509_s;
+        x509_s.cert_info.subject = name;
+        break;
+    case X509_LU_CRL:
+        stmp.data.crl = &crl_s;
+        crl_s.crl.issuer = name;
+        break;
+    default:
+        /* abort(); */
+        return -1;
+    }
+
+    idx = sk_X509_OBJECT_find(h, &stmp);
+    if (idx >= 0 && pnmatch) {
+        int tidx;
+        const X509_OBJECT *tobj, *pstmp;
+        *pnmatch = 1;
+        pstmp = &stmp;
+        for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) {
+            tobj = sk_X509_OBJECT_value(h, tidx);
+            if (x509_object_cmp(&tobj, &pstmp))
+                break;
+            (*pnmatch)++;
+        }
+    }
+    return idx;
+}
+
+int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
+                               X509_NAME *name)
+{
+    return x509_object_idx_cnt(h, type, name, NULL);
+}
+
+X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
+                                             X509_LOOKUP_TYPE type,
+                                             X509_NAME *name)
+{
+    int idx;
+    idx = X509_OBJECT_idx_by_subject(h, type, name);
+    if (idx == -1)
+        return NULL;
+    return sk_X509_OBJECT_value(h, idx);
+}
+
+STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *v)
+{
+    return v->objs;
+}
+
+STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm)
+{
+    int i, idx, cnt;
+    STACK_OF(X509) *sk = NULL;
+    X509 *x;
+    X509_OBJECT *obj;
+
+    CRYPTO_THREAD_write_lock(ctx->ctx->lock);
+    idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
+    if (idx < 0) {
+        /*
+         * Nothing found in cache: do lookup to possibly add new objects to
+         * cache
+         */
+        X509_OBJECT *xobj = X509_OBJECT_new();
+
+        CRYPTO_THREAD_unlock(ctx->ctx->lock);
+        if (xobj == NULL)
+            return NULL;
+        if (!X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, nm, xobj)) {
+            X509_OBJECT_free(xobj);
+            return NULL;
+        }
+        X509_OBJECT_free(xobj);
+        CRYPTO_THREAD_write_lock(ctx->ctx->lock);
+        idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt);
+        if (idx < 0) {
+            CRYPTO_THREAD_unlock(ctx->ctx->lock);
+            return NULL;
+        }
+    }
+
+    sk = sk_X509_new_null();
+    for (i = 0; i < cnt; i++, idx++) {
+        obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
+        x = obj->data.x509;
+        X509_up_ref(x);
+        if (!sk_X509_push(sk, x)) {
+            CRYPTO_THREAD_unlock(ctx->ctx->lock);
+            X509_free(x);
+            sk_X509_pop_free(sk, X509_free);
+            return NULL;
+        }
+    }
+    CRYPTO_THREAD_unlock(ctx->ctx->lock);
+    return sk;
+}
+
+STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
+{
+    int i, idx, cnt;
+    STACK_OF(X509_CRL) *sk = sk_X509_CRL_new_null();
+    X509_CRL *x;
+    X509_OBJECT *obj, *xobj = X509_OBJECT_new();
+
+    /* Always do lookup to possibly add new CRLs to cache */
+    if (sk == NULL || xobj == NULL ||
+            !X509_STORE_CTX_get_by_subject(ctx, X509_LU_CRL, nm, xobj)) {
+        X509_OBJECT_free(xobj);
+        sk_X509_CRL_free(sk);
+        return NULL;
+    }
+    X509_OBJECT_free(xobj);
+    CRYPTO_THREAD_write_lock(ctx->ctx->lock);
+    idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt);
+    if (idx < 0) {
+        CRYPTO_THREAD_unlock(ctx->ctx->lock);
+        sk_X509_CRL_free(sk);
+        return NULL;
+    }
+
+    for (i = 0; i < cnt; i++, idx++) {
+        obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
+        x = obj->data.crl;
+        X509_CRL_up_ref(x);
+        if (!sk_X509_CRL_push(sk, x)) {
+            CRYPTO_THREAD_unlock(ctx->ctx->lock);
+            X509_CRL_free(x);
+            sk_X509_CRL_pop_free(sk, X509_CRL_free);
+            return NULL;
+        }
+    }
+    CRYPTO_THREAD_unlock(ctx->ctx->lock);
+    return sk;
+}
+
+X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
+                                        X509_OBJECT *x)
+{
+    int idx, i;
+    X509_OBJECT *obj;
+    idx = sk_X509_OBJECT_find(h, x);
+    if (idx == -1)
+        return NULL;
+    if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL))
+        return sk_X509_OBJECT_value(h, idx);
+    for (i = idx; i < sk_X509_OBJECT_num(h); i++) {
+        obj = sk_X509_OBJECT_value(h, i);
+        if (x509_object_cmp
+            ((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x))
+            return NULL;
+        if (x->type == X509_LU_X509) {
+            if (!X509_cmp(obj->data.x509, x->data.x509))
+                return obj;
+        } else if (x->type == X509_LU_CRL) {
+            if (!X509_CRL_match(obj->data.crl, x->data.crl))
+                return obj;
+        } else
+            return obj;
+    }
+    return NULL;
+}
+
+/*-
+ * Try to get issuer certificate from store. Due to limitations
+ * of the API this can only retrieve a single certificate matching
+ * a given subject name. However it will fill the cache with all
+ * matching certificates, so we can examine the cache for all
+ * matches.
+ *
+ * Return values are:
+ *  1 lookup successful.
+ *  0 certificate not found.
+ * -1 some other error.
+ */
+int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
+{
+    X509_NAME *xn;
+    X509_OBJECT *obj = X509_OBJECT_new(), *pobj = NULL;
+    int i, ok, idx, ret;
+
+    if (obj == NULL)
+        return -1;
+    *issuer = NULL;
+    xn = X509_get_issuer_name(x);
+    ok = X509_STORE_CTX_get_by_subject(ctx, X509_LU_X509, xn, obj);
+    if (ok != 1) {
+        X509_OBJECT_free(obj);
+        return 0;
+    }
+    /* If certificate matches all OK */
+    if (ctx->check_issued(ctx, x, obj->data.x509)) {
+        if (x509_check_cert_time(ctx, obj->data.x509, -1)) {
+            *issuer = obj->data.x509;
+            X509_up_ref(*issuer);
+            X509_OBJECT_free(obj);
+            return 1;
+        }
+    }
+    X509_OBJECT_free(obj);
+
+    /* Else find index of first cert accepted by 'check_issued' */
+    ret = 0;
+    CRYPTO_THREAD_write_lock(ctx->ctx->lock);
+    idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
+    if (idx != -1) {            /* should be true as we've had at least one
+                                 * match */
+        /* Look through all matching certs for suitable issuer */
+        for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) {
+            pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i);
+            /* See if we've run past the matches */
+            if (pobj->type != X509_LU_X509)
+                break;
+            if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509)))
+                break;
+            if (ctx->check_issued(ctx, x, pobj->data.x509)) {
+                *issuer = pobj->data.x509;
+                ret = 1;
+                /*
+                 * If times check, exit with match,
+                 * otherwise keep looking. Leave last
+                 * match in issuer so we return nearest
+                 * match if no certificate time is OK.
+                 */
+
+                if (x509_check_cert_time(ctx, *issuer, -1))
+                    break;
+            }
+        }
+    }
+    CRYPTO_THREAD_unlock(ctx->ctx->lock);
+    if (*issuer)
+        X509_up_ref(*issuer);
+    return ret;
+}
+
+int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags)
+{
+    return X509_VERIFY_PARAM_set_flags(ctx->param, flags);
+}
+
+int X509_STORE_set_depth(X509_STORE *ctx, int depth)
+{
+    X509_VERIFY_PARAM_set_depth(ctx->param, depth);
+    return 1;
+}
+
+int X509_STORE_set_purpose(X509_STORE *ctx, int purpose)
+{
+    return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
+}
+
+int X509_STORE_set_trust(X509_STORE *ctx, int trust)
+{
+    return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
+}
+
+int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param)
+{
+    return X509_VERIFY_PARAM_set1(ctx->param, param);
+}
+
+X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx)
+{
+    return ctx->param;
+}
+
+void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify)
+{
+    ctx->verify = verify;
+}
+
+X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx)
+{
+    return ctx->verify;
+}
+
+void X509_STORE_set_verify_cb(X509_STORE *ctx,
+                              X509_STORE_CTX_verify_cb verify_cb)
+{
+    ctx->verify_cb = verify_cb;
+}
+
+X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(X509_STORE *ctx)
+{
+    return ctx->verify_cb;
+}
+
+void X509_STORE_set_get_issuer(X509_STORE *ctx,
+                               X509_STORE_CTX_get_issuer_fn get_issuer)
+{
+    ctx->get_issuer = get_issuer;
+}
+
+X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(X509_STORE *ctx)
+{
+    return ctx->get_issuer;
+}
+
+void X509_STORE_set_check_issued(X509_STORE *ctx,
+                                 X509_STORE_CTX_check_issued_fn check_issued)
+{
+    ctx->check_issued = check_issued;
+}
+
+X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(X509_STORE *ctx)
+{
+    return ctx->check_issued;
+}
+
+void X509_STORE_set_check_revocation(X509_STORE *ctx,
+                                     X509_STORE_CTX_check_revocation_fn check_revocation)
+{
+    ctx->check_revocation = check_revocation;
+}
+
+X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation(X509_STORE *ctx)
+{
+    return ctx->check_revocation;
+}
+
+void X509_STORE_set_get_crl(X509_STORE *ctx,
+                            X509_STORE_CTX_get_crl_fn get_crl)
+{
+    ctx->get_crl = get_crl;
+}
+
+X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(X509_STORE *ctx)
+{
+    return ctx->get_crl;
+}
+
+void X509_STORE_set_check_crl(X509_STORE *ctx,
+                              X509_STORE_CTX_check_crl_fn check_crl)
+{
+    ctx->check_crl = check_crl;
+}
+
+X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(X509_STORE *ctx)
+{
+    return ctx->check_crl;
+}
+
+void X509_STORE_set_cert_crl(X509_STORE *ctx,
+                             X509_STORE_CTX_cert_crl_fn cert_crl)
+{
+    ctx->cert_crl = cert_crl;
+}
+
+X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(X509_STORE *ctx)
+{
+    return ctx->cert_crl;
+}
+
+void X509_STORE_set_check_policy(X509_STORE *ctx,
+                                 X509_STORE_CTX_check_policy_fn check_policy)
+{
+    ctx->check_policy = check_policy;
+}
+
+X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(X509_STORE *ctx)
+{
+    return ctx->check_policy;
+}
+
+void X509_STORE_set_lookup_certs(X509_STORE *ctx,
+                                 X509_STORE_CTX_lookup_certs_fn lookup_certs)
+{
+    ctx->lookup_certs = lookup_certs;
+}
+
+X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(X509_STORE *ctx)
+{
+    return ctx->lookup_certs;
+}
+
+void X509_STORE_set_lookup_crls(X509_STORE *ctx,
+                                X509_STORE_CTX_lookup_crls_fn lookup_crls)
+{
+    ctx->lookup_crls = lookup_crls;
+}
+
+X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(X509_STORE *ctx)
+{
+    return ctx->lookup_crls;
+}
+
+void X509_STORE_set_cleanup(X509_STORE *ctx,
+                            X509_STORE_CTX_cleanup_fn ctx_cleanup)
+{
+    ctx->cleanup = ctx_cleanup;
+}
+
+X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(X509_STORE *ctx)
+{
+    return ctx->cleanup;
+}
+
+int X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data)
+{
+    return CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
+}
+
+void *X509_STORE_get_ex_data(X509_STORE *ctx, int idx)
+{
+    return CRYPTO_get_ex_data(&ctx->ex_data, idx);
+}
+
+X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx)
+{
+    return ctx->ctx;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_obj.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_obj.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_obj.c	(revision 331)
@@ -0,0 +1,182 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/buffer.h>
+#include "internal/x509_int.h"
+
+/*
+ * Limit to ensure we don't overflow: much greater than
+ * anything encountered in practice.
+ */
+
+#define NAME_ONELINE_MAX    (1024 * 1024)
+
+char *X509_NAME_oneline(const X509_NAME *a, char *buf, int len)
+{
+    const X509_NAME_ENTRY *ne;
+    int i;
+    int n, lold, l, l1, l2, num, j, type;
+    const char *s;
+    char *p;
+    unsigned char *q;
+    BUF_MEM *b = NULL;
+    static const char hex[17] = "0123456789ABCDEF";
+    int gs_doit[4];
+    char tmp_buf[80];
+#ifdef CHARSET_EBCDIC
+    unsigned char ebcdic_buf[1024];
+#endif
+
+    if (buf == NULL) {
+        if ((b = BUF_MEM_new()) == NULL)
+            goto err;
+        if (!BUF_MEM_grow(b, 200))
+            goto err;
+        b->data[0] = '\0';
+        len = 200;
+    } else if (len == 0) {
+        return NULL;
+    }
+    if (a == NULL) {
+        if (b) {
+            buf = b->data;
+            OPENSSL_free(b);
+        }
+        strncpy(buf, "NO X509_NAME", len);
+        buf[len - 1] = '\0';
+        return buf;
+    }
+
+    len--;                      /* space for '\0' */
+    l = 0;
+    for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
+        ne = sk_X509_NAME_ENTRY_value(a->entries, i);
+        n = OBJ_obj2nid(ne->object);
+        if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
+            i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object);
+            s = tmp_buf;
+        }
+        l1 = strlen(s);
+
+        type = ne->value->type;
+        num = ne->value->length;
+        if (num > NAME_ONELINE_MAX) {
+            X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG);
+            goto end;
+        }
+        q = ne->value->data;
+#ifdef CHARSET_EBCDIC
+        if (type == V_ASN1_GENERALSTRING ||
+            type == V_ASN1_VISIBLESTRING ||
+            type == V_ASN1_PRINTABLESTRING ||
+            type == V_ASN1_TELETEXSTRING ||
+            type == V_ASN1_IA5STRING) {
+            if (num > (int)sizeof(ebcdic_buf))
+                num = sizeof(ebcdic_buf);
+            ascii2ebcdic(ebcdic_buf, q, num);
+            q = ebcdic_buf;
+        }
+#endif
+
+        if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) {
+            gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0;
+            for (j = 0; j < num; j++)
+                if (q[j] != 0)
+                    gs_doit[j & 3] = 1;
+
+            if (gs_doit[0] | gs_doit[1] | gs_doit[2])
+                gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1;
+            else {
+                gs_doit[0] = gs_doit[1] = gs_doit[2] = 0;
+                gs_doit[3] = 1;
+            }
+        } else
+            gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1;
+
+        for (l2 = j = 0; j < num; j++) {
+            if (!gs_doit[j & 3])
+                continue;
+            l2++;
+#ifndef CHARSET_EBCDIC
+            if ((q[j] < ' ') || (q[j] > '~'))
+                l2 += 3;
+#else
+            if ((os_toascii[q[j]] < os_toascii[' ']) ||
+                (os_toascii[q[j]] > os_toascii['~']))
+                l2 += 3;
+#endif
+        }
+
+        lold = l;
+        l += 1 + l1 + 1 + l2;
+        if (l > NAME_ONELINE_MAX) {
+            X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG);
+            goto end;
+        }
+        if (b != NULL) {
+            if (!BUF_MEM_grow(b, l + 1))
+                goto err;
+            p = &(b->data[lold]);
+        } else if (l > len) {
+            break;
+        } else
+            p = &(buf[lold]);
+        *(p++) = '/';
+        memcpy(p, s, (unsigned int)l1);
+        p += l1;
+        *(p++) = '=';
+
+#ifndef CHARSET_EBCDIC          /* q was assigned above already. */
+        q = ne->value->data;
+#endif
+
+        for (j = 0; j < num; j++) {
+            if (!gs_doit[j & 3])
+                continue;
+#ifndef CHARSET_EBCDIC
+            n = q[j];
+            if ((n < ' ') || (n > '~')) {
+                *(p++) = '\\';
+                *(p++) = 'x';
+                *(p++) = hex[(n >> 4) & 0x0f];
+                *(p++) = hex[n & 0x0f];
+            } else
+                *(p++) = n;
+#else
+            n = os_toascii[q[j]];
+            if ((n < os_toascii[' ']) || (n > os_toascii['~'])) {
+                *(p++) = '\\';
+                *(p++) = 'x';
+                *(p++) = hex[(n >> 4) & 0x0f];
+                *(p++) = hex[n & 0x0f];
+            } else
+                *(p++) = q[j];
+#endif
+        }
+        *p = '\0';
+    }
+    if (b != NULL) {
+        p = b->data;
+        OPENSSL_free(b);
+    } else
+        p = buf;
+    if (i == 0)
+        *p = '\0';
+    return (p);
+ err:
+    X509err(X509_F_X509_NAME_ONELINE, ERR_R_MALLOC_FAILURE);
+ end:
+    BUF_MEM_free(b);
+    return (NULL);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_r2x.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_r2x.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_r2x.c	(revision 331)
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+
+X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
+{
+    X509 *ret = NULL;
+    X509_CINF *xi = NULL;
+    X509_NAME *xn;
+    EVP_PKEY *pubkey = NULL;
+
+    if ((ret = X509_new()) == NULL) {
+        X509err(X509_F_X509_REQ_TO_X509, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    /* duplicate the request */
+    xi = &ret->cert_info;
+
+    if (sk_X509_ATTRIBUTE_num(r->req_info.attributes) != 0) {
+        if ((xi->version = ASN1_INTEGER_new()) == NULL)
+            goto err;
+        if (!ASN1_INTEGER_set(xi->version, 2))
+            goto err;
+/*-     xi->extensions=ri->attributes; <- bad, should not ever be done
+        ri->attributes=NULL; */
+    }
+
+    xn = X509_REQ_get_subject_name(r);
+    if (X509_set_subject_name(ret, xn) == 0)
+        goto err;
+    if (X509_set_issuer_name(ret, xn) == 0)
+        goto err;
+
+    if (X509_gmtime_adj(xi->validity.notBefore, 0) == NULL)
+        goto err;
+    if (X509_gmtime_adj(xi->validity.notAfter, (long)60 * 60 * 24 * days) ==
+        NULL)
+        goto err;
+
+    pubkey = X509_REQ_get0_pubkey(r);
+    if (pubkey == NULL || !X509_set_pubkey(ret, pubkey))
+        goto err;
+
+    if (!X509_sign(ret, pkey, EVP_md5()))
+        goto err;
+    return ret;
+
+ err:
+    X509_free(ret);
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_req.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_req.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_req.c	(revision 331)
@@ -0,0 +1,298 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+#include <openssl/objects.h>
+#include <openssl/buffer.h>
+#include <openssl/pem.h>
+
+X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
+{
+    X509_REQ *ret;
+    X509_REQ_INFO *ri;
+    int i;
+    EVP_PKEY *pktmp;
+
+    ret = X509_REQ_new();
+    if (ret == NULL) {
+        X509err(X509_F_X509_TO_X509_REQ, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    ri = &ret->req_info;
+
+    ri->version->length = 1;
+    ri->version->data = OPENSSL_malloc(1);
+    if (ri->version->data == NULL)
+        goto err;
+    ri->version->data[0] = 0;   /* version == 0 */
+
+    if (!X509_REQ_set_subject_name(ret, X509_get_subject_name(x)))
+        goto err;
+
+    pktmp = X509_get0_pubkey(x);
+    if (pktmp == NULL)
+        goto err;
+    i = X509_REQ_set_pubkey(ret, pktmp);
+    if (!i)
+        goto err;
+
+    if (pkey != NULL) {
+        if (!X509_REQ_sign(ret, pkey, md))
+            goto err;
+    }
+    return (ret);
+ err:
+    X509_REQ_free(ret);
+    return (NULL);
+}
+
+EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req)
+{
+    if (req == NULL)
+        return (NULL);
+    return (X509_PUBKEY_get(req->req_info.pubkey));
+}
+
+EVP_PKEY *X509_REQ_get0_pubkey(X509_REQ *req)
+{
+    if (req == NULL)
+        return NULL;
+    return (X509_PUBKEY_get0(req->req_info.pubkey));
+}
+
+X509_PUBKEY *X509_REQ_get_X509_PUBKEY(X509_REQ *req)
+{
+    return req->req_info.pubkey;
+}
+
+int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
+{
+    EVP_PKEY *xk = NULL;
+    int ok = 0;
+
+    xk = X509_REQ_get_pubkey(x);
+    switch (EVP_PKEY_cmp(xk, k)) {
+    case 1:
+        ok = 1;
+        break;
+    case 0:
+        X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,
+                X509_R_KEY_VALUES_MISMATCH);
+        break;
+    case -1:
+        X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_KEY_TYPE_MISMATCH);
+        break;
+    case -2:
+#ifndef OPENSSL_NO_EC
+        if (EVP_PKEY_id(k) == EVP_PKEY_EC) {
+            X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, ERR_R_EC_LIB);
+            break;
+        }
+#endif
+#ifndef OPENSSL_NO_DH
+        if (EVP_PKEY_id(k) == EVP_PKEY_DH) {
+            /* No idea */
+            X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,
+                    X509_R_CANT_CHECK_DH_KEY);
+            break;
+        }
+#endif
+        X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_UNKNOWN_KEY_TYPE);
+    }
+
+    EVP_PKEY_free(xk);
+    return (ok);
+}
+
+/*
+ * It seems several organisations had the same idea of including a list of
+ * extensions in a certificate request. There are at least two OIDs that are
+ * used and there may be more: so the list is configurable.
+ */
+
+static int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef };
+
+static int *ext_nids = ext_nid_list;
+
+int X509_REQ_extension_nid(int req_nid)
+{
+    int i, nid;
+    for (i = 0;; i++) {
+        nid = ext_nids[i];
+        if (nid == NID_undef)
+            return 0;
+        else if (req_nid == nid)
+            return 1;
+    }
+}
+
+int *X509_REQ_get_extension_nids(void)
+{
+    return ext_nids;
+}
+
+void X509_REQ_set_extension_nids(int *nids)
+{
+    ext_nids = nids;
+}
+
+STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req)
+{
+    X509_ATTRIBUTE *attr;
+    ASN1_TYPE *ext = NULL;
+    int idx, *pnid;
+    const unsigned char *p;
+
+    if ((req == NULL) || !ext_nids)
+        return (NULL);
+    for (pnid = ext_nids; *pnid != NID_undef; pnid++) {
+        idx = X509_REQ_get_attr_by_NID(req, *pnid, -1);
+        if (idx == -1)
+            continue;
+        attr = X509_REQ_get_attr(req, idx);
+        ext = X509_ATTRIBUTE_get0_type(attr, 0);
+        break;
+    }
+    if (!ext || (ext->type != V_ASN1_SEQUENCE))
+        return NULL;
+    p = ext->value.sequence->data;
+    return (STACK_OF(X509_EXTENSION) *)
+        ASN1_item_d2i(NULL, &p, ext->value.sequence->length,
+                      ASN1_ITEM_rptr(X509_EXTENSIONS));
+}
+
+/*
+ * Add a STACK_OF extensions to a certificate request: allow alternative OIDs
+ * in case we want to create a non standard one.
+ */
+
+int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
+                                int nid)
+{
+    int extlen;
+    int rv = 0;
+    unsigned char *ext = NULL;
+    /* Generate encoding of extensions */
+    extlen = ASN1_item_i2d((ASN1_VALUE *)exts, &ext,
+                           ASN1_ITEM_rptr(X509_EXTENSIONS));
+    if (extlen <= 0)
+        return 0;
+    rv = X509_REQ_add1_attr_by_NID(req, nid, V_ASN1_SEQUENCE, ext, extlen);
+    OPENSSL_free(ext);
+    return rv;
+}
+
+/* This is the normal usage: use the "official" OID */
+int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts)
+{
+    return X509_REQ_add_extensions_nid(req, exts, NID_ext_req);
+}
+
+/* Request attribute functions */
+
+int X509_REQ_get_attr_count(const X509_REQ *req)
+{
+    return X509at_get_attr_count(req->req_info.attributes);
+}
+
+int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos)
+{
+    return X509at_get_attr_by_NID(req->req_info.attributes, nid, lastpos);
+}
+
+int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj,
+                             int lastpos)
+{
+    return X509at_get_attr_by_OBJ(req->req_info.attributes, obj, lastpos);
+}
+
+X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc)
+{
+    return X509at_get_attr(req->req_info.attributes, loc);
+}
+
+X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc)
+{
+    return X509at_delete_attr(req->req_info.attributes, loc);
+}
+
+int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr)
+{
+    if (X509at_add1_attr(&req->req_info.attributes, attr))
+        return 1;
+    return 0;
+}
+
+int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
+                              const ASN1_OBJECT *obj, int type,
+                              const unsigned char *bytes, int len)
+{
+    if (X509at_add1_attr_by_OBJ(&req->req_info.attributes, obj,
+                                type, bytes, len))
+        return 1;
+    return 0;
+}
+
+int X509_REQ_add1_attr_by_NID(X509_REQ *req,
+                              int nid, int type,
+                              const unsigned char *bytes, int len)
+{
+    if (X509at_add1_attr_by_NID(&req->req_info.attributes, nid,
+                                type, bytes, len))
+        return 1;
+    return 0;
+}
+
+int X509_REQ_add1_attr_by_txt(X509_REQ *req,
+                              const char *attrname, int type,
+                              const unsigned char *bytes, int len)
+{
+    if (X509at_add1_attr_by_txt(&req->req_info.attributes, attrname,
+                                type, bytes, len))
+        return 1;
+    return 0;
+}
+
+long X509_REQ_get_version(const X509_REQ *req)
+{
+    return ASN1_INTEGER_get(req->req_info.version);
+}
+
+X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req)
+{
+    return req->req_info.subject;
+}
+
+void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig,
+                             const X509_ALGOR **palg)
+{
+    if (psig != NULL)
+        *psig = req->signature;
+    if (palg != NULL)
+        *palg = &req->sig_alg;
+}
+
+int X509_REQ_get_signature_nid(const X509_REQ *req)
+{
+    return OBJ_obj2nid(req->sig_alg.algorithm);
+}
+
+int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp)
+{
+    req->req_info.enc.modified = 1;
+    return i2d_X509_REQ_INFO(&req->req_info, pp);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_set.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_set.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_set.c	(revision 331)
@@ -0,0 +1,159 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+
+int X509_set_version(X509 *x, long version)
+{
+    if (x == NULL)
+        return (0);
+    if (version == 0) {
+        ASN1_INTEGER_free(x->cert_info.version);
+        x->cert_info.version = NULL;
+        return (1);
+    }
+    if (x->cert_info.version == NULL) {
+        if ((x->cert_info.version = ASN1_INTEGER_new()) == NULL)
+            return (0);
+    }
+    return (ASN1_INTEGER_set(x->cert_info.version, version));
+}
+
+int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial)
+{
+    ASN1_INTEGER *in;
+
+    if (x == NULL)
+        return 0;
+    in = &x->cert_info.serialNumber;
+    if (in != serial)
+        return ASN1_STRING_copy(in, serial);
+    return 1;
+}
+
+int X509_set_issuer_name(X509 *x, X509_NAME *name)
+{
+    if (x == NULL)
+        return (0);
+    return (X509_NAME_set(&x->cert_info.issuer, name));
+}
+
+int X509_set_subject_name(X509 *x, X509_NAME *name)
+{
+    if (x == NULL)
+        return (0);
+    return (X509_NAME_set(&x->cert_info.subject, name));
+}
+
+int x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm)
+{
+    ASN1_TIME *in;
+    in = *ptm;
+    if (in != tm) {
+        in = ASN1_STRING_dup(tm);
+        if (in != NULL) {
+            ASN1_TIME_free(*ptm);
+            *ptm = in;
+        }
+    }
+    return (in != NULL);
+}
+
+int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm)
+{
+    if (x == NULL)
+        return 0;
+    return x509_set1_time(&x->cert_info.validity.notBefore, tm);
+}
+
+int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm)
+{
+    if (x == NULL)
+        return 0;
+    return x509_set1_time(&x->cert_info.validity.notAfter, tm);
+}
+
+int X509_set_pubkey(X509 *x, EVP_PKEY *pkey)
+{
+    if (x == NULL)
+        return (0);
+    return (X509_PUBKEY_set(&(x->cert_info.key), pkey));
+}
+
+int X509_up_ref(X509 *x)
+{
+    int i;
+
+    if (CRYPTO_atomic_add(&x->references, 1, &i, x->lock) <= 0)
+        return 0;
+
+    REF_PRINT_COUNT("X509", x);
+    REF_ASSERT_ISNT(i < 2);
+    return ((i > 1) ? 1 : 0);
+}
+
+long X509_get_version(const X509 *x)
+{
+    return ASN1_INTEGER_get(x->cert_info.version);
+}
+
+const ASN1_TIME *X509_get0_notBefore(const X509 *x)
+{
+    return x->cert_info.validity.notBefore;
+}
+
+const ASN1_TIME *X509_get0_notAfter(const X509 *x)
+{
+    return x->cert_info.validity.notAfter;
+}
+
+ASN1_TIME *X509_getm_notBefore(const X509 *x)
+{
+    return x->cert_info.validity.notBefore;
+}
+
+ASN1_TIME *X509_getm_notAfter(const X509 *x)
+{
+    return x->cert_info.validity.notAfter;
+}
+
+int X509_get_signature_type(const X509 *x)
+{
+    return EVP_PKEY_type(OBJ_obj2nid(x->sig_alg.algorithm));
+}
+
+X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x)
+{
+    return x->cert_info.key;
+}
+
+const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x)
+{
+    return x->cert_info.extensions;
+}
+
+void X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **piuid,
+                    const ASN1_BIT_STRING **psuid)
+{
+    if (piuid != NULL)
+        *piuid = x->cert_info.issuerUID;
+    if (psuid != NULL)
+        *psuid = x->cert_info.subjectUID;
+}
+
+const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x)
+{
+    return &x->cert_info.signature;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_trs.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_trs.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_trs.c	(revision 331)
@@ -0,0 +1,298 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509v3.h>
+#include "internal/x509_int.h"
+
+static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b);
+static void trtable_free(X509_TRUST *p);
+
+static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags);
+static int trust_1oid(X509_TRUST *trust, X509 *x, int flags);
+static int trust_compat(X509_TRUST *trust, X509 *x, int flags);
+
+static int obj_trust(int id, X509 *x, int flags);
+static int (*default_trust) (int id, X509 *x, int flags) = obj_trust;
+
+/*
+ * WARNING: the following table should be kept in order of trust and without
+ * any gaps so we can just subtract the minimum trust value to get an index
+ * into the table
+ */
+
+static X509_TRUST trstandard[] = {
+    {X509_TRUST_COMPAT, 0, trust_compat, "compatible", 0, NULL},
+    {X509_TRUST_SSL_CLIENT, 0, trust_1oidany, "SSL Client", NID_client_auth,
+     NULL},
+    {X509_TRUST_SSL_SERVER, 0, trust_1oidany, "SSL Server", NID_server_auth,
+     NULL},
+    {X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect,
+     NULL},
+    {X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, "Object Signer", NID_code_sign,
+     NULL},
+    {X509_TRUST_OCSP_SIGN, 0, trust_1oid, "OCSP responder", NID_OCSP_sign,
+     NULL},
+    {X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP,
+     NULL},
+    {X509_TRUST_TSA, 0, trust_1oidany, "TSA server", NID_time_stamp, NULL}
+};
+
+#define X509_TRUST_COUNT        OSSL_NELEM(trstandard)
+
+static STACK_OF(X509_TRUST) *trtable = NULL;
+
+static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b)
+{
+    return (*a)->trust - (*b)->trust;
+}
+
+int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *,
+                                                                int) {
+    int (*oldtrust) (int, X509 *, int);
+    oldtrust = default_trust;
+    default_trust = trust;
+    return oldtrust;
+}
+
+int X509_check_trust(X509 *x, int id, int flags)
+{
+    X509_TRUST *pt;
+    int idx;
+
+    /* We get this as a default value */
+    if (id == X509_TRUST_DEFAULT)
+        return obj_trust(NID_anyExtendedKeyUsage, x,
+                         flags | X509_TRUST_DO_SS_COMPAT);
+    idx = X509_TRUST_get_by_id(id);
+    if (idx == -1)
+        return default_trust(id, x, flags);
+    pt = X509_TRUST_get0(idx);
+    return pt->check_trust(pt, x, flags);
+}
+
+int X509_TRUST_get_count(void)
+{
+    if (!trtable)
+        return X509_TRUST_COUNT;
+    return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT;
+}
+
+X509_TRUST *X509_TRUST_get0(int idx)
+{
+    if (idx < 0)
+        return NULL;
+    if (idx < (int)X509_TRUST_COUNT)
+        return trstandard + idx;
+    return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT);
+}
+
+int X509_TRUST_get_by_id(int id)
+{
+    X509_TRUST tmp;
+    int idx;
+    if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX))
+        return id - X509_TRUST_MIN;
+    tmp.trust = id;
+    if (!trtable)
+        return -1;
+    idx = sk_X509_TRUST_find(trtable, &tmp);
+    if (idx == -1)
+        return -1;
+    return idx + X509_TRUST_COUNT;
+}
+
+int X509_TRUST_set(int *t, int trust)
+{
+    if (X509_TRUST_get_by_id(trust) == -1) {
+        X509err(X509_F_X509_TRUST_SET, X509_R_INVALID_TRUST);
+        return 0;
+    }
+    *t = trust;
+    return 1;
+}
+
+int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int),
+                   const char *name, int arg1, void *arg2)
+{
+    int idx;
+    X509_TRUST *trtmp;
+    /*
+     * This is set according to what we change: application can't set it
+     */
+    flags &= ~X509_TRUST_DYNAMIC;
+    /* This will always be set for application modified trust entries */
+    flags |= X509_TRUST_DYNAMIC_NAME;
+    /* Get existing entry if any */
+    idx = X509_TRUST_get_by_id(id);
+    /* Need a new entry */
+    if (idx == -1) {
+        if ((trtmp = OPENSSL_malloc(sizeof(*trtmp))) == NULL) {
+            X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        trtmp->flags = X509_TRUST_DYNAMIC;
+    } else
+        trtmp = X509_TRUST_get0(idx);
+
+    /* OPENSSL_free existing name if dynamic */
+    if (trtmp->flags & X509_TRUST_DYNAMIC_NAME)
+        OPENSSL_free(trtmp->name);
+    /* dup supplied name */
+    if ((trtmp->name = OPENSSL_strdup(name)) == NULL) {
+        X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    /* Keep the dynamic flag of existing entry */
+    trtmp->flags &= X509_TRUST_DYNAMIC;
+    /* Set all other flags */
+    trtmp->flags |= flags;
+
+    trtmp->trust = id;
+    trtmp->check_trust = ck;
+    trtmp->arg1 = arg1;
+    trtmp->arg2 = arg2;
+
+    /* If its a new entry manage the dynamic table */
+    if (idx == -1) {
+        if (trtable == NULL
+            && (trtable = sk_X509_TRUST_new(tr_cmp)) == NULL) {
+            X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
+            goto err;;
+        }
+        if (!sk_X509_TRUST_push(trtable, trtmp)) {
+            X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    }
+    return 1;
+ err:
+    if (idx == -1) {
+        OPENSSL_free(trtmp->name);
+        OPENSSL_free(trtmp);
+    }
+    return 0;
+}
+
+static void trtable_free(X509_TRUST *p)
+{
+    if (!p)
+        return;
+    if (p->flags & X509_TRUST_DYNAMIC) {
+        if (p->flags & X509_TRUST_DYNAMIC_NAME)
+            OPENSSL_free(p->name);
+        OPENSSL_free(p);
+    }
+}
+
+void X509_TRUST_cleanup(void)
+{
+    sk_X509_TRUST_pop_free(trtable, trtable_free);
+    trtable = NULL;
+}
+
+int X509_TRUST_get_flags(const X509_TRUST *xp)
+{
+    return xp->flags;
+}
+
+char *X509_TRUST_get0_name(const X509_TRUST *xp)
+{
+    return xp->name;
+}
+
+int X509_TRUST_get_trust(const X509_TRUST *xp)
+{
+    return xp->trust;
+}
+
+static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags)
+{
+    /*
+     * Declare the chain verified if the desired trust OID is not rejected in
+     * any auxiliary trust info for this certificate, and the OID is either
+     * expressly trusted, or else either "anyEKU" is trusted, or the
+     * certificate is self-signed.
+     */
+    flags |= X509_TRUST_DO_SS_COMPAT | X509_TRUST_OK_ANY_EKU;
+    return obj_trust(trust->arg1, x, flags);
+}
+
+static int trust_1oid(X509_TRUST *trust, X509 *x, int flags)
+{
+    /*
+     * Declare the chain verified only if the desired trust OID is not
+     * rejected and is expressly trusted.  Neither "anyEKU" nor "compat"
+     * trust in self-signed certificates apply.
+     */
+    flags &= ~(X509_TRUST_DO_SS_COMPAT | X509_TRUST_OK_ANY_EKU);
+    return obj_trust(trust->arg1, x, flags);
+}
+
+static int trust_compat(X509_TRUST *trust, X509 *x, int flags)
+{
+    /* Call for side-effect of computing hash and caching extensions */
+    X509_check_purpose(x, -1, 0);
+    if ((flags & X509_TRUST_NO_SS_COMPAT) == 0 && x->ex_flags & EXFLAG_SS)
+        return X509_TRUST_TRUSTED;
+    else
+        return X509_TRUST_UNTRUSTED;
+}
+
+static int obj_trust(int id, X509 *x, int flags)
+{
+    X509_CERT_AUX *ax = x->aux;
+    int i;
+
+    if (ax && ax->reject) {
+        for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) {
+            ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(ax->reject, i);
+            int nid = OBJ_obj2nid(obj);
+
+            if (nid == id || (nid == NID_anyExtendedKeyUsage &&
+                (flags & X509_TRUST_OK_ANY_EKU)))
+                return X509_TRUST_REJECTED;
+        }
+    }
+
+    if (ax && ax->trust) {
+        for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) {
+            ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(ax->trust, i);
+            int nid = OBJ_obj2nid(obj);
+
+            if (nid == id || (nid == NID_anyExtendedKeyUsage &&
+                (flags & X509_TRUST_OK_ANY_EKU)))
+                return X509_TRUST_TRUSTED;
+        }
+        /*
+         * Reject when explicit trust EKU are set and none match.
+         *
+         * Returning untrusted is enough for for full chains that end in
+         * self-signed roots, because when explicit trust is specified it
+         * suppresses the default blanket trust of self-signed objects.
+         *
+         * But for partial chains, this is not enough, because absent a similar
+         * trust-self-signed policy, non matching EKUs are indistinguishable
+         * from lack of EKU constraints.
+         *
+         * Therefore, failure to match any trusted purpose must trigger an
+         * explicit reject.
+         */
+        return X509_TRUST_REJECTED;
+    }
+
+    if ((flags & X509_TRUST_DO_SS_COMPAT) == 0)
+        return X509_TRUST_UNTRUSTED;
+
+    /*
+     * Not rejected, and there is no list of accepted uses, try compat.
+     */
+    return trust_compat(NULL, x, flags);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_txt.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_txt.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_txt.c	(revision 331)
@@ -0,0 +1,177 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include "internal/cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+#include <openssl/objects.h>
+
+const char *X509_verify_cert_error_string(long n)
+{
+    switch ((int)n) {
+    case X509_V_OK:
+        return ("ok");
+    case X509_V_ERR_UNSPECIFIED:
+        return ("unspecified certificate verification error");
+    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+        return ("unable to get issuer certificate");
+    case X509_V_ERR_UNABLE_TO_GET_CRL:
+        return ("unable to get certificate CRL");
+    case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
+        return ("unable to decrypt certificate's signature");
+    case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
+        return ("unable to decrypt CRL's signature");
+    case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
+        return ("unable to decode issuer public key");
+    case X509_V_ERR_CERT_SIGNATURE_FAILURE:
+        return ("certificate signature failure");
+    case X509_V_ERR_CRL_SIGNATURE_FAILURE:
+        return ("CRL signature failure");
+    case X509_V_ERR_CERT_NOT_YET_VALID:
+        return ("certificate is not yet valid");
+    case X509_V_ERR_CERT_HAS_EXPIRED:
+        return ("certificate has expired");
+    case X509_V_ERR_CRL_NOT_YET_VALID:
+        return ("CRL is not yet valid");
+    case X509_V_ERR_CRL_HAS_EXPIRED:
+        return ("CRL has expired");
+    case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+        return ("format error in certificate's notBefore field");
+    case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+        return ("format error in certificate's notAfter field");
+    case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
+        return ("format error in CRL's lastUpdate field");
+    case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
+        return ("format error in CRL's nextUpdate field");
+    case X509_V_ERR_OUT_OF_MEM:
+        return ("out of memory");
+    case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+        return ("self signed certificate");
+    case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
+        return ("self signed certificate in certificate chain");
+    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
+        return ("unable to get local issuer certificate");
+    case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
+        return ("unable to verify the first certificate");
+    case X509_V_ERR_CERT_CHAIN_TOO_LONG:
+        return ("certificate chain too long");
+    case X509_V_ERR_CERT_REVOKED:
+        return ("certificate revoked");
+    case X509_V_ERR_INVALID_CA:
+        return ("invalid CA certificate");
+    case X509_V_ERR_PATH_LENGTH_EXCEEDED:
+        return ("path length constraint exceeded");
+    case X509_V_ERR_INVALID_PURPOSE:
+        return ("unsupported certificate purpose");
+    case X509_V_ERR_CERT_UNTRUSTED:
+        return ("certificate not trusted");
+    case X509_V_ERR_CERT_REJECTED:
+        return ("certificate rejected");
+    case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
+        return ("subject issuer mismatch");
+    case X509_V_ERR_AKID_SKID_MISMATCH:
+        return ("authority and subject key identifier mismatch");
+    case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
+        return ("authority and issuer serial number mismatch");
+    case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
+        return ("key usage does not include certificate signing");
+    case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
+        return ("unable to get CRL issuer certificate");
+    case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
+        return ("unhandled critical extension");
+    case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN:
+        return ("key usage does not include CRL signing");
+    case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
+        return ("unhandled critical CRL extension");
+    case X509_V_ERR_INVALID_NON_CA:
+        return ("invalid non-CA certificate (has CA markings)");
+    case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED:
+        return ("proxy path length constraint exceeded");
+    case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
+        return ("key usage does not include digital signature");
+    case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED:
+        return
+            ("proxy certificates not allowed, please set the appropriate flag");
+    case X509_V_ERR_INVALID_EXTENSION:
+        return ("invalid or inconsistent certificate extension");
+    case X509_V_ERR_INVALID_POLICY_EXTENSION:
+        return ("invalid or inconsistent certificate policy extension");
+    case X509_V_ERR_NO_EXPLICIT_POLICY:
+        return ("no explicit policy");
+    case X509_V_ERR_DIFFERENT_CRL_SCOPE:
+        return ("Different CRL scope");
+    case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE:
+        return ("Unsupported extension feature");
+    case X509_V_ERR_UNNESTED_RESOURCE:
+        return ("RFC 3779 resource not subset of parent's resources");
+    case X509_V_ERR_PERMITTED_VIOLATION:
+        return ("permitted subtree violation");
+    case X509_V_ERR_EXCLUDED_VIOLATION:
+        return ("excluded subtree violation");
+    case X509_V_ERR_SUBTREE_MINMAX:
+        return ("name constraints minimum and maximum not supported");
+    case X509_V_ERR_APPLICATION_VERIFICATION:
+        return ("application verification failure");
+    case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:
+        return ("unsupported name constraint type");
+    case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX:
+        return ("unsupported or invalid name constraint syntax");
+    case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX:
+        return ("unsupported or invalid name syntax");
+    case X509_V_ERR_CRL_PATH_VALIDATION_ERROR:
+        return ("CRL path validation error");
+    case X509_V_ERR_PATH_LOOP:
+        return ("Path Loop");
+    case X509_V_ERR_SUITE_B_INVALID_VERSION:
+        return ("Suite B: certificate version invalid");
+    case X509_V_ERR_SUITE_B_INVALID_ALGORITHM:
+        return ("Suite B: invalid public key algorithm");
+    case X509_V_ERR_SUITE_B_INVALID_CURVE:
+        return ("Suite B: invalid ECC curve");
+    case X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM:
+        return ("Suite B: invalid signature algorithm");
+    case X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED:
+        return ("Suite B: curve not allowed for this LOS");
+    case X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256:
+        return ("Suite B: cannot sign P-384 with P-256");
+    case X509_V_ERR_HOSTNAME_MISMATCH:
+        return ("Hostname mismatch");
+    case X509_V_ERR_EMAIL_MISMATCH:
+        return ("Email address mismatch");
+    case X509_V_ERR_IP_ADDRESS_MISMATCH:
+        return ("IP address mismatch");
+    case X509_V_ERR_DANE_NO_MATCH:
+        return ("No matching DANE TLSA records");
+    case X509_V_ERR_EE_KEY_TOO_SMALL:
+        return ("EE certificate key too weak");
+    case X509_V_ERR_CA_KEY_TOO_SMALL:
+        return ("CA certificate key too weak");
+    case X509_V_ERR_CA_MD_TOO_WEAK:
+        return ("CA signature digest algorithm too weak");
+    case X509_V_ERR_INVALID_CALL:
+        return ("Invalid certificate verification context");
+    case X509_V_ERR_STORE_LOOKUP:
+        return ("Issuer certificate lookup error");
+    case X509_V_ERR_NO_VALID_SCTS:
+        return ("Certificate Transparency required, but no valid SCTs found");
+    case X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION:
+        return ("proxy subject name violation");
+
+    default:
+        /* Printing an error number into a static buffer is not thread-safe */
+        return ("unknown certificate verification error");
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_v3.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_v3.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_v3.c	(revision 331)
@@ -0,0 +1,234 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/stack.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include "x509_lcl.h"
+
+int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x)
+{
+    if (x == NULL)
+        return (0);
+    return (sk_X509_EXTENSION_num(x));
+}
+
+int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid,
+                          int lastpos)
+{
+    ASN1_OBJECT *obj;
+
+    obj = OBJ_nid2obj(nid);
+    if (obj == NULL)
+        return (-2);
+    return (X509v3_get_ext_by_OBJ(x, obj, lastpos));
+}
+
+int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk,
+                          const ASN1_OBJECT *obj, int lastpos)
+{
+    int n;
+    X509_EXTENSION *ex;
+
+    if (sk == NULL)
+        return (-1);
+    lastpos++;
+    if (lastpos < 0)
+        lastpos = 0;
+    n = sk_X509_EXTENSION_num(sk);
+    for (; lastpos < n; lastpos++) {
+        ex = sk_X509_EXTENSION_value(sk, lastpos);
+        if (OBJ_cmp(ex->object, obj) == 0)
+            return (lastpos);
+    }
+    return (-1);
+}
+
+int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit,
+                               int lastpos)
+{
+    int n;
+    X509_EXTENSION *ex;
+
+    if (sk == NULL)
+        return (-1);
+    lastpos++;
+    if (lastpos < 0)
+        lastpos = 0;
+    n = sk_X509_EXTENSION_num(sk);
+    for (; lastpos < n; lastpos++) {
+        ex = sk_X509_EXTENSION_value(sk, lastpos);
+        if (((ex->critical > 0) && crit) || ((ex->critical <= 0) && !crit))
+            return (lastpos);
+    }
+    return (-1);
+}
+
+X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc)
+{
+    if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0)
+        return NULL;
+    else
+        return sk_X509_EXTENSION_value(x, loc);
+}
+
+X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc)
+{
+    X509_EXTENSION *ret;
+
+    if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0)
+        return (NULL);
+    ret = sk_X509_EXTENSION_delete(x, loc);
+    return (ret);
+}
+
+STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
+                                         X509_EXTENSION *ex, int loc)
+{
+    X509_EXTENSION *new_ex = NULL;
+    int n;
+    STACK_OF(X509_EXTENSION) *sk = NULL;
+
+    if (x == NULL) {
+        X509err(X509_F_X509V3_ADD_EXT, ERR_R_PASSED_NULL_PARAMETER);
+        goto err2;
+    }
+
+    if (*x == NULL) {
+        if ((sk = sk_X509_EXTENSION_new_null()) == NULL)
+            goto err;
+    } else
+        sk = *x;
+
+    n = sk_X509_EXTENSION_num(sk);
+    if (loc > n)
+        loc = n;
+    else if (loc < 0)
+        loc = n;
+
+    if ((new_ex = X509_EXTENSION_dup(ex)) == NULL)
+        goto err2;
+    if (!sk_X509_EXTENSION_insert(sk, new_ex, loc))
+        goto err;
+    if (*x == NULL)
+        *x = sk;
+    return (sk);
+ err:
+    X509err(X509_F_X509V3_ADD_EXT, ERR_R_MALLOC_FAILURE);
+ err2:
+    X509_EXTENSION_free(new_ex);
+    sk_X509_EXTENSION_free(sk);
+    return (NULL);
+}
+
+X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid,
+                                             int crit,
+                                             ASN1_OCTET_STRING *data)
+{
+    ASN1_OBJECT *obj;
+    X509_EXTENSION *ret;
+
+    obj = OBJ_nid2obj(nid);
+    if (obj == NULL) {
+        X509err(X509_F_X509_EXTENSION_CREATE_BY_NID, X509_R_UNKNOWN_NID);
+        return (NULL);
+    }
+    ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data);
+    if (ret == NULL)
+        ASN1_OBJECT_free(obj);
+    return (ret);
+}
+
+X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
+                                             const ASN1_OBJECT *obj, int crit,
+                                             ASN1_OCTET_STRING *data)
+{
+    X509_EXTENSION *ret;
+
+    if ((ex == NULL) || (*ex == NULL)) {
+        if ((ret = X509_EXTENSION_new()) == NULL) {
+            X509err(X509_F_X509_EXTENSION_CREATE_BY_OBJ,
+                    ERR_R_MALLOC_FAILURE);
+            return (NULL);
+        }
+    } else
+        ret = *ex;
+
+    if (!X509_EXTENSION_set_object(ret, obj))
+        goto err;
+    if (!X509_EXTENSION_set_critical(ret, crit))
+        goto err;
+    if (!X509_EXTENSION_set_data(ret, data))
+        goto err;
+
+    if ((ex != NULL) && (*ex == NULL))
+        *ex = ret;
+    return (ret);
+ err:
+    if ((ex == NULL) || (ret != *ex))
+        X509_EXTENSION_free(ret);
+    return (NULL);
+}
+
+int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj)
+{
+    if ((ex == NULL) || (obj == NULL))
+        return (0);
+    ASN1_OBJECT_free(ex->object);
+    ex->object = OBJ_dup(obj);
+    return ex->object != NULL;
+}
+
+int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit)
+{
+    if (ex == NULL)
+        return (0);
+    ex->critical = (crit) ? 0xFF : -1;
+    return (1);
+}
+
+int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data)
+{
+    int i;
+
+    if (ex == NULL)
+        return (0);
+    i = ASN1_OCTET_STRING_set(&ex->value, data->data, data->length);
+    if (!i)
+        return (0);
+    return (1);
+}
+
+ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex)
+{
+    if (ex == NULL)
+        return (NULL);
+    return (ex->object);
+}
+
+ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ex)
+{
+    if (ex == NULL)
+        return (NULL);
+    return &ex->value;
+}
+
+int X509_EXTENSION_get_critical(const X509_EXTENSION *ex)
+{
+    if (ex == NULL)
+        return (0);
+    if (ex->critical > 0)
+        return 1;
+    return 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_vfy.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_vfy.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_vfy.c	(revision 331)
@@ -0,0 +1,3275 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <time.h>
+#include <errno.h>
+#include <limits.h>
+
+#include "internal/cryptlib.h"
+#include <openssl/crypto.h>
+#include <openssl/lhash.h>
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/objects.h>
+#include <internal/dane.h>
+#include <internal/x509_int.h>
+#include "x509_lcl.h"
+
+/* CRL score values */
+
+/* No unhandled critical extensions */
+
+#define CRL_SCORE_NOCRITICAL    0x100
+
+/* certificate is within CRL scope */
+
+#define CRL_SCORE_SCOPE         0x080
+
+/* CRL times valid */
+
+#define CRL_SCORE_TIME          0x040
+
+/* Issuer name matches certificate */
+
+#define CRL_SCORE_ISSUER_NAME   0x020
+
+/* If this score or above CRL is probably valid */
+
+#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE)
+
+/* CRL issuer is certificate issuer */
+
+#define CRL_SCORE_ISSUER_CERT   0x018
+
+/* CRL issuer is on certificate path */
+
+#define CRL_SCORE_SAME_PATH     0x008
+
+/* CRL issuer matches CRL AKID */
+
+#define CRL_SCORE_AKID          0x004
+
+/* Have a delta CRL with valid times */
+
+#define CRL_SCORE_TIME_DELTA    0x002
+
+static int build_chain(X509_STORE_CTX *ctx);
+static int verify_chain(X509_STORE_CTX *ctx);
+static int dane_verify(X509_STORE_CTX *ctx);
+static int null_callback(int ok, X509_STORE_CTX *e);
+static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
+static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x);
+static int check_chain_extensions(X509_STORE_CTX *ctx);
+static int check_name_constraints(X509_STORE_CTX *ctx);
+static int check_id(X509_STORE_CTX *ctx);
+static int check_trust(X509_STORE_CTX *ctx, int num_untrusted);
+static int check_revocation(X509_STORE_CTX *ctx);
+static int check_cert(X509_STORE_CTX *ctx);
+static int check_policy(X509_STORE_CTX *ctx);
+static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
+static int check_dane_issuer(X509_STORE_CTX *ctx, int depth);
+static int check_key_level(X509_STORE_CTX *ctx, X509 *cert);
+static int check_sig_level(X509_STORE_CTX *ctx, X509 *cert);
+
+static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
+                         unsigned int *preasons, X509_CRL *crl, X509 *x);
+static int get_crl_delta(X509_STORE_CTX *ctx,
+                         X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x);
+static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl,
+                         int *pcrl_score, X509_CRL *base,
+                         STACK_OF(X509_CRL) *crls);
+static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer,
+                           int *pcrl_score);
+static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
+                           unsigned int *preasons);
+static int check_crl_path(X509_STORE_CTX *ctx, X509 *x);
+static int check_crl_chain(X509_STORE_CTX *ctx,
+                           STACK_OF(X509) *cert_path,
+                           STACK_OF(X509) *crl_path);
+
+static int internal_verify(X509_STORE_CTX *ctx);
+
+static int null_callback(int ok, X509_STORE_CTX *e)
+{
+    return ok;
+}
+
+/* Return 1 is a certificate is self signed */
+static int cert_self_signed(X509 *x)
+{
+    /*
+     * FIXME: x509v3_cache_extensions() needs to detect more failures and not
+     * set EXFLAG_SET when that happens.  Especially, if the failures are
+     * parse errors, rather than memory pressure!
+     */
+    X509_check_purpose(x, -1, 0);
+    if (x->ex_flags & EXFLAG_SS)
+        return 1;
+    else
+        return 0;
+}
+
+/* Given a certificate try and find an exact match in the store */
+
+static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
+{
+    STACK_OF(X509) *certs;
+    X509 *xtmp = NULL;
+    int i;
+    /* Lookup all certs with matching subject name */
+    certs = ctx->lookup_certs(ctx, X509_get_subject_name(x));
+    if (certs == NULL)
+        return NULL;
+    /* Look for exact match */
+    for (i = 0; i < sk_X509_num(certs); i++) {
+        xtmp = sk_X509_value(certs, i);
+        if (!X509_cmp(xtmp, x))
+            break;
+    }
+    if (i < sk_X509_num(certs))
+        X509_up_ref(xtmp);
+    else
+        xtmp = NULL;
+    sk_X509_pop_free(certs, X509_free);
+    return xtmp;
+}
+
+/*-
+ * Inform the verify callback of an error.
+ * If B<x> is not NULL it is the error cert, otherwise use the chain cert at
+ * B<depth>.
+ * If B<err> is not X509_V_OK, that's the error value, otherwise leave
+ * unchanged (presumably set by the caller).
+ *
+ * Returns 0 to abort verification with an error, non-zero to continue.
+ */
+static int verify_cb_cert(X509_STORE_CTX *ctx, X509 *x, int depth, int err)
+{
+    ctx->error_depth = depth;
+    ctx->current_cert = (x != NULL) ? x : sk_X509_value(ctx->chain, depth);
+    if (err != X509_V_OK)
+        ctx->error = err;
+    return ctx->verify_cb(0, ctx);
+}
+
+/*-
+ * Inform the verify callback of an error, CRL-specific variant.  Here, the
+ * error depth and certificate are already set, we just specify the error
+ * number.
+ *
+ * Returns 0 to abort verification with an error, non-zero to continue.
+ */
+static int verify_cb_crl(X509_STORE_CTX *ctx, int err)
+{
+    ctx->error = err;
+    return ctx->verify_cb(0, ctx);
+}
+
+static int check_auth_level(X509_STORE_CTX *ctx)
+{
+    int i;
+    int num = sk_X509_num(ctx->chain);
+
+    if (ctx->param->auth_level <= 0)
+        return 1;
+
+    for (i = 0; i < num; ++i) {
+        X509 *cert = sk_X509_value(ctx->chain, i);
+
+        /*
+         * We've already checked the security of the leaf key, so here we only
+         * check the security of issuer keys.
+         */
+        if (i > 0 && !check_key_level(ctx, cert) &&
+            verify_cb_cert(ctx, cert, i, X509_V_ERR_CA_KEY_TOO_SMALL) == 0)
+            return 0;
+        /*
+         * We also check the signature algorithm security of all certificates
+         * except those of the trust anchor at index num-1.
+         */
+        if (i < num - 1 && !check_sig_level(ctx, cert) &&
+            verify_cb_cert(ctx, cert, i, X509_V_ERR_CA_MD_TOO_WEAK) == 0)
+            return 0;
+    }
+    return 1;
+}
+
+static int verify_chain(X509_STORE_CTX *ctx)
+{
+    int err;
+    int ok;
+
+    /*
+     * Before either returning with an error, or continuing with CRL checks,
+     * instantiate chain public key parameters.
+     */
+    if ((ok = build_chain(ctx)) == 0 ||
+        (ok = check_chain_extensions(ctx)) == 0 ||
+        (ok = check_auth_level(ctx)) == 0 ||
+        (ok = check_name_constraints(ctx)) == 0 ||
+        (ok = check_id(ctx)) == 0 || 1)
+        X509_get_pubkey_parameters(NULL, ctx->chain);
+    if (ok == 0 || (ok = ctx->check_revocation(ctx)) == 0)
+        return ok;
+
+    err = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain,
+                                  ctx->param->flags);
+    if (err != X509_V_OK) {
+        if ((ok = verify_cb_cert(ctx, NULL, ctx->error_depth, err)) == 0)
+            return ok;
+    }
+
+    /* Verify chain signatures and expiration times */
+    ok = (ctx->verify != NULL) ? ctx->verify(ctx) : internal_verify(ctx);
+    if (!ok)
+        return ok;
+
+#ifndef OPENSSL_NO_RFC3779
+    /* RFC 3779 path validation, now that CRL check has been done */
+    if ((ok = X509v3_asid_validate_path(ctx)) == 0)
+        return ok;
+    if ((ok = X509v3_addr_validate_path(ctx)) == 0)
+        return ok;
+#endif
+
+    /* If we get this far evaluate policies */
+    if (ctx->param->flags & X509_V_FLAG_POLICY_CHECK)
+        ok = ctx->check_policy(ctx);
+    return ok;
+}
+
+int X509_verify_cert(X509_STORE_CTX *ctx)
+{
+    SSL_DANE *dane = ctx->dane;
+    int ret;
+
+    if (ctx->cert == NULL) {
+        X509err(X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
+        ctx->error = X509_V_ERR_INVALID_CALL;
+        return -1;
+    }
+
+    if (ctx->chain != NULL) {
+        /*
+         * This X509_STORE_CTX has already been used to verify a cert. We
+         * cannot do another one.
+         */
+        X509err(X509_F_X509_VERIFY_CERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        ctx->error = X509_V_ERR_INVALID_CALL;
+        return -1;
+    }
+
+    /*
+     * first we make sure the chain we are going to build is present and that
+     * the first entry is in place
+     */
+    if (((ctx->chain = sk_X509_new_null()) == NULL) ||
+        (!sk_X509_push(ctx->chain, ctx->cert))) {
+        X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
+        ctx->error = X509_V_ERR_OUT_OF_MEM;
+        return -1;
+    }
+    X509_up_ref(ctx->cert);
+    ctx->num_untrusted = 1;
+
+    /* If the peer's public key is too weak, we can stop early. */
+    if (!check_key_level(ctx, ctx->cert) &&
+        !verify_cb_cert(ctx, ctx->cert, 0, X509_V_ERR_EE_KEY_TOO_SMALL))
+        return 0;
+
+    if (DANETLS_ENABLED(dane))
+        ret = dane_verify(ctx);
+    else
+        ret = verify_chain(ctx);
+
+    /*
+     * Safety-net.  If we are returning an error, we must also set ctx->error,
+     * so that the chain is not considered verified should the error be ignored
+     * (e.g. TLS with SSL_VERIFY_NONE).
+     */
+    if (ret <= 0 && ctx->error == X509_V_OK)
+        ctx->error = X509_V_ERR_UNSPECIFIED;
+    return ret;
+}
+
+/*
+ * Given a STACK_OF(X509) find the issuer of cert (if any)
+ */
+static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x)
+{
+    int i;
+    X509 *issuer, *rv = NULL;
+
+    for (i = 0; i < sk_X509_num(sk); i++) {
+        issuer = sk_X509_value(sk, i);
+        if (ctx->check_issued(ctx, x, issuer)) {
+            rv = issuer;
+            if (x509_check_cert_time(ctx, rv, -1))
+                break;
+        }
+    }
+    return rv;
+}
+
+/* Given a possible certificate and issuer check them */
+
+static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer)
+{
+    int ret;
+    if (x == issuer)
+        return cert_self_signed(x);
+    ret = X509_check_issued(issuer, x);
+    if (ret == X509_V_OK) {
+        int i;
+        X509 *ch;
+        /* Special case: single self signed certificate */
+        if (cert_self_signed(x) && sk_X509_num(ctx->chain) == 1)
+            return 1;
+        for (i = 0; i < sk_X509_num(ctx->chain); i++) {
+            ch = sk_X509_value(ctx->chain, i);
+            if (ch == issuer || !X509_cmp(ch, issuer)) {
+                ret = X509_V_ERR_PATH_LOOP;
+                break;
+            }
+        }
+    }
+
+    return (ret == X509_V_OK);
+}
+
+/* Alternative lookup method: look from a STACK stored in other_ctx */
+
+static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
+{
+    *issuer = find_issuer(ctx, ctx->other_ctx, x);
+    if (*issuer) {
+        X509_up_ref(*issuer);
+        return 1;
+    } else
+        return 0;
+}
+
+static STACK_OF(X509) *lookup_certs_sk(X509_STORE_CTX *ctx, X509_NAME *nm)
+{
+    STACK_OF(X509) *sk = NULL;
+    X509 *x;
+    int i;
+    for (i = 0; i < sk_X509_num(ctx->other_ctx); i++) {
+        x = sk_X509_value(ctx->other_ctx, i);
+        if (X509_NAME_cmp(nm, X509_get_subject_name(x)) == 0) {
+            if (sk == NULL)
+                sk = sk_X509_new_null();
+            if (sk == NULL || sk_X509_push(sk, x) == 0) {
+                sk_X509_pop_free(sk, X509_free);
+                return NULL;
+            }
+            X509_up_ref(x);
+        }
+    }
+    return sk;
+}
+
+/*
+ * Check EE or CA certificate purpose.  For trusted certificates explicit local
+ * auxiliary trust can be used to override EKU-restrictions.
+ */
+static int check_purpose(X509_STORE_CTX *ctx, X509 *x, int purpose, int depth,
+                         int must_be_ca)
+{
+    int tr_ok = X509_TRUST_UNTRUSTED;
+
+    /*
+     * For trusted certificates we want to see whether any auxiliary trust
+     * settings trump the purpose constraints.
+     *
+     * This is complicated by the fact that the trust ordinals in
+     * ctx->param->trust are entirely independent of the purpose ordinals in
+     * ctx->param->purpose!
+     *
+     * What connects them is their mutual initialization via calls from
+     * X509_STORE_CTX_set_default() into X509_VERIFY_PARAM_lookup() which sets
+     * related values of both param->trust and param->purpose.  It is however
+     * typically possible to infer associated trust values from a purpose value
+     * via the X509_PURPOSE API.
+     *
+     * Therefore, we can only check for trust overrides when the purpose we're
+     * checking is the same as ctx->param->purpose and ctx->param->trust is
+     * also set.
+     */
+    if (depth >= ctx->num_untrusted && purpose == ctx->param->purpose)
+        tr_ok = X509_check_trust(x, ctx->param->trust, X509_TRUST_NO_SS_COMPAT);
+
+    switch (tr_ok) {
+    case X509_TRUST_TRUSTED:
+        return 1;
+    case X509_TRUST_REJECTED:
+        break;
+    default:
+        switch (X509_check_purpose(x, purpose, must_be_ca > 0)) {
+        case 1:
+            return 1;
+        case 0:
+            break;
+        default:
+            if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) == 0)
+                return 1;
+        }
+        break;
+    }
+
+    return verify_cb_cert(ctx, x, depth, X509_V_ERR_INVALID_PURPOSE);
+}
+
+/*
+ * Check a certificate chains extensions for consistency with the supplied
+ * purpose
+ */
+
+static int check_chain_extensions(X509_STORE_CTX *ctx)
+{
+    int i, must_be_ca, plen = 0;
+    X509 *x;
+    int proxy_path_length = 0;
+    int purpose;
+    int allow_proxy_certs;
+    int num = sk_X509_num(ctx->chain);
+
+    /*-
+     *  must_be_ca can have 1 of 3 values:
+     * -1: we accept both CA and non-CA certificates, to allow direct
+     *     use of self-signed certificates (which are marked as CA).
+     * 0:  we only accept non-CA certificates.  This is currently not
+     *     used, but the possibility is present for future extensions.
+     * 1:  we only accept CA certificates.  This is currently used for
+     *     all certificates in the chain except the leaf certificate.
+     */
+    must_be_ca = -1;
+
+    /* CRL path validation */
+    if (ctx->parent) {
+        allow_proxy_certs = 0;
+        purpose = X509_PURPOSE_CRL_SIGN;
+    } else {
+        allow_proxy_certs =
+            ! !(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
+        purpose = ctx->param->purpose;
+    }
+
+    for (i = 0; i < num; i++) {
+        int ret;
+        x = sk_X509_value(ctx->chain, i);
+        if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
+            && (x->ex_flags & EXFLAG_CRITICAL)) {
+            if (!verify_cb_cert(ctx, x, i,
+                                X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION))
+                return 0;
+        }
+        if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) {
+            if (!verify_cb_cert(ctx, x, i,
+                                X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED))
+                return 0;
+        }
+        ret = X509_check_ca(x);
+        switch (must_be_ca) {
+        case -1:
+            if ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
+                && (ret != 1) && (ret != 0)) {
+                ret = 0;
+                ctx->error = X509_V_ERR_INVALID_CA;
+            } else
+                ret = 1;
+            break;
+        case 0:
+            if (ret != 0) {
+                ret = 0;
+                ctx->error = X509_V_ERR_INVALID_NON_CA;
+            } else
+                ret = 1;
+            break;
+        default:
+            /* X509_V_FLAG_X509_STRICT is implicit for intermediate CAs */
+            if ((ret == 0)
+                || ((i + 1 < num || ctx->param->flags & X509_V_FLAG_X509_STRICT)
+                    && (ret != 1))) {
+                ret = 0;
+                ctx->error = X509_V_ERR_INVALID_CA;
+            } else
+                ret = 1;
+            break;
+        }
+        if (ret == 0 && !verify_cb_cert(ctx, x, i, X509_V_OK))
+            return 0;
+        /* check_purpose() makes the callback as needed */
+        if (purpose > 0 && !check_purpose(ctx, x, purpose, i, must_be_ca))
+            return 0;
+        /* Check pathlen if not self issued */
+        if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
+            && (x->ex_pathlen != -1)
+            && (plen > (x->ex_pathlen + proxy_path_length + 1))) {
+            if (!verify_cb_cert(ctx, x, i, X509_V_ERR_PATH_LENGTH_EXCEEDED))
+                return 0;
+        }
+        /* Increment path length if not self issued */
+        if (!(x->ex_flags & EXFLAG_SI))
+            plen++;
+        /*
+         * If this certificate is a proxy certificate, the next certificate
+         * must be another proxy certificate or a EE certificate.  If not,
+         * the next certificate must be a CA certificate.
+         */
+        if (x->ex_flags & EXFLAG_PROXY) {
+            /*
+             * RFC3820, 4.1.3 (b)(1) stipulates that if pCPathLengthConstraint
+             * is less than max_path_length, the former should be copied to
+             * the latter, and 4.1.4 (a) stipulates that max_path_length
+             * should be verified to be larger than zero and decrement it.
+             *
+             * Because we're checking the certs in the reverse order, we start
+             * with verifying that proxy_path_length isn't larger than pcPLC,
+             * and copy the latter to the former if it is, and finally,
+             * increment proxy_path_length.
+             */
+            if (x->ex_pcpathlen != -1) {
+                if (proxy_path_length > x->ex_pcpathlen) {
+                    if (!verify_cb_cert(ctx, x, i,
+                                        X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED))
+                        return 0;
+                }
+                proxy_path_length = x->ex_pcpathlen;
+            }
+            proxy_path_length++;
+            must_be_ca = 0;
+        } else
+            must_be_ca = 1;
+    }
+    return 1;
+}
+
+static int check_name_constraints(X509_STORE_CTX *ctx)
+{
+    int i;
+
+    /* Check name constraints for all certificates */
+    for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--) {
+        X509 *x = sk_X509_value(ctx->chain, i);
+        int j;
+
+        /* Ignore self issued certs unless last in chain */
+        if (i && (x->ex_flags & EXFLAG_SI))
+            continue;
+
+        /*
+         * Proxy certificates policy has an extra constraint, where the
+         * certificate subject MUST be the issuer with a single CN entry
+         * added.
+         * (RFC 3820: 3.4, 4.1.3 (a)(4))
+         */
+        if (x->ex_flags & EXFLAG_PROXY) {
+            X509_NAME *tmpsubject = X509_get_subject_name(x);
+            X509_NAME *tmpissuer = X509_get_issuer_name(x);
+            X509_NAME_ENTRY *tmpentry = NULL;
+            int last_object_nid = 0;
+            int err = X509_V_OK;
+            int last_object_loc = X509_NAME_entry_count(tmpsubject) - 1;
+
+            /* Check that there are at least two RDNs */
+            if (last_object_loc < 1) {
+                err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION;
+                goto proxy_name_done;
+            }
+
+            /*
+             * Check that there is exactly one more RDN in subject as
+             * there is in issuer.
+             */
+            if (X509_NAME_entry_count(tmpsubject)
+                != X509_NAME_entry_count(tmpissuer) + 1) {
+                err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION;
+                goto proxy_name_done;
+            }
+
+            /*
+             * Check that the last subject component isn't part of a
+             * multivalued RDN
+             */
+            if (X509_NAME_ENTRY_set(X509_NAME_get_entry(tmpsubject,
+                                                        last_object_loc))
+                == X509_NAME_ENTRY_set(X509_NAME_get_entry(tmpsubject,
+                                                           last_object_loc - 1))) {
+                err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION;
+                goto proxy_name_done;
+            }
+
+            /*
+             * Check that the last subject RDN is a commonName, and that
+             * all the previous RDNs match the issuer exactly
+             */
+            tmpsubject = X509_NAME_dup(tmpsubject);
+            if (tmpsubject == NULL) {
+                X509err(X509_F_CHECK_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
+                ctx->error = X509_V_ERR_OUT_OF_MEM;
+                return 0;
+            }
+
+            tmpentry =
+                X509_NAME_delete_entry(tmpsubject, last_object_loc);
+            last_object_nid =
+                OBJ_obj2nid(X509_NAME_ENTRY_get_object(tmpentry));
+
+            if (last_object_nid != NID_commonName
+                || X509_NAME_cmp(tmpsubject, tmpissuer) != 0) {
+                err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION;
+            }
+
+            X509_NAME_ENTRY_free(tmpentry);
+            X509_NAME_free(tmpsubject);
+
+         proxy_name_done:
+            if (err != X509_V_OK
+                && !verify_cb_cert(ctx, x, i, err))
+                return 0;
+        }
+
+        /*
+         * Check against constraints for all certificates higher in chain
+         * including trust anchor. Trust anchor not strictly speaking needed
+         * but if it includes constraints it is to be assumed it expects them
+         * to be obeyed.
+         */
+        for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) {
+            NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
+
+            if (nc) {
+                int rv = NAME_CONSTRAINTS_check(x, nc);
+
+                /* If EE certificate check commonName too */
+                if (rv == X509_V_OK && i == 0)
+                    rv = NAME_CONSTRAINTS_check_CN(x, nc);
+
+                switch (rv) {
+                case X509_V_OK:
+                    break;
+                case X509_V_ERR_OUT_OF_MEM:
+                    return 0;
+                default:
+                    if (!verify_cb_cert(ctx, x, i, rv))
+                        return 0;
+                    break;
+                }
+            }
+        }
+    }
+    return 1;
+}
+
+static int check_id_error(X509_STORE_CTX *ctx, int errcode)
+{
+    return verify_cb_cert(ctx, ctx->cert, 0, errcode);
+}
+
+static int check_hosts(X509 *x, X509_VERIFY_PARAM *vpm)
+{
+    int i;
+    int n = sk_OPENSSL_STRING_num(vpm->hosts);
+    char *name;
+
+    if (vpm->peername != NULL) {
+        OPENSSL_free(vpm->peername);
+        vpm->peername = NULL;
+    }
+    for (i = 0; i < n; ++i) {
+        name = sk_OPENSSL_STRING_value(vpm->hosts, i);
+        if (X509_check_host(x, name, 0, vpm->hostflags, &vpm->peername) > 0)
+            return 1;
+    }
+    return n == 0;
+}
+
+static int check_id(X509_STORE_CTX *ctx)
+{
+    X509_VERIFY_PARAM *vpm = ctx->param;
+    X509 *x = ctx->cert;
+    if (vpm->hosts && check_hosts(x, vpm) <= 0) {
+        if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH))
+            return 0;
+    }
+    if (vpm->email && X509_check_email(x, vpm->email, vpm->emaillen, 0) <= 0) {
+        if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH))
+            return 0;
+    }
+    if (vpm->ip && X509_check_ip(x, vpm->ip, vpm->iplen, 0) <= 0) {
+        if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH))
+            return 0;
+    }
+    return 1;
+}
+
+static int check_trust(X509_STORE_CTX *ctx, int num_untrusted)
+{
+    int i;
+    X509 *x = NULL;
+    X509 *mx;
+    SSL_DANE *dane = ctx->dane;
+    int num = sk_X509_num(ctx->chain);
+    int trust;
+
+    /*
+     * Check for a DANE issuer at depth 1 or greater, if it is a DANE-TA(2)
+     * match, we're done, otherwise we'll merely record the match depth.
+     */
+    if (DANETLS_HAS_TA(dane) && num_untrusted > 0 && num_untrusted < num) {
+        switch (trust = check_dane_issuer(ctx, num_untrusted)) {
+        case X509_TRUST_TRUSTED:
+        case X509_TRUST_REJECTED:
+            return trust;
+        }
+    }
+
+    /*
+     * Check trusted certificates in chain at depth num_untrusted and up.
+     * Note, that depths 0..num_untrusted-1 may also contain trusted
+     * certificates, but the caller is expected to have already checked those,
+     * and wants to incrementally check just any added since.
+     */
+    for (i = num_untrusted; i < num; i++) {
+        x = sk_X509_value(ctx->chain, i);
+        trust = X509_check_trust(x, ctx->param->trust, 0);
+        /* If explicitly trusted return trusted */
+        if (trust == X509_TRUST_TRUSTED)
+            goto trusted;
+        if (trust == X509_TRUST_REJECTED)
+            goto rejected;
+    }
+
+    /*
+     * If we are looking at a trusted certificate, and accept partial chains,
+     * the chain is PKIX trusted.
+     */
+    if (num_untrusted < num) {
+        if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN)
+            goto trusted;
+        return X509_TRUST_UNTRUSTED;
+    }
+
+    if (num_untrusted == num && ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
+        /*
+         * Last-resort call with no new trusted certificates, check the leaf
+         * for a direct trust store match.
+         */
+        i = 0;
+        x = sk_X509_value(ctx->chain, i);
+        mx = lookup_cert_match(ctx, x);
+        if (!mx)
+            return X509_TRUST_UNTRUSTED;
+
+        /*
+         * Check explicit auxiliary trust/reject settings.  If none are set,
+         * we'll accept X509_TRUST_UNTRUSTED when not self-signed.
+         */
+        trust = X509_check_trust(mx, ctx->param->trust, 0);
+        if (trust == X509_TRUST_REJECTED) {
+            X509_free(mx);
+            goto rejected;
+        }
+
+        /* Replace leaf with trusted match */
+        (void) sk_X509_set(ctx->chain, 0, mx);
+        X509_free(x);
+        ctx->num_untrusted = 0;
+        goto trusted;
+    }
+
+    /*
+     * If no trusted certs in chain at all return untrusted and allow
+     * standard (no issuer cert) etc errors to be indicated.
+     */
+    return X509_TRUST_UNTRUSTED;
+
+ rejected:
+    if (!verify_cb_cert(ctx, x, i, X509_V_ERR_CERT_REJECTED))
+        return X509_TRUST_REJECTED;
+    return X509_TRUST_UNTRUSTED;
+
+ trusted:
+    if (!DANETLS_ENABLED(dane))
+        return X509_TRUST_TRUSTED;
+    if (dane->pdpth < 0)
+        dane->pdpth = num_untrusted;
+    /* With DANE, PKIX alone is not trusted until we have both */
+    if (dane->mdpth >= 0)
+        return X509_TRUST_TRUSTED;
+    return X509_TRUST_UNTRUSTED;
+}
+
+static int check_revocation(X509_STORE_CTX *ctx)
+{
+    int i = 0, last = 0, ok = 0;
+    if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
+        return 1;
+    if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
+        last = sk_X509_num(ctx->chain) - 1;
+    else {
+        /* If checking CRL paths this isn't the EE certificate */
+        if (ctx->parent)
+            return 1;
+        last = 0;
+    }
+    for (i = 0; i <= last; i++) {
+        ctx->error_depth = i;
+        ok = check_cert(ctx);
+        if (!ok)
+            return ok;
+    }
+    return 1;
+}
+
+static int check_cert(X509_STORE_CTX *ctx)
+{
+    X509_CRL *crl = NULL, *dcrl = NULL;
+    int ok = 0;
+    int cnum = ctx->error_depth;
+    X509 *x = sk_X509_value(ctx->chain, cnum);
+
+    ctx->current_cert = x;
+    ctx->current_issuer = NULL;
+    ctx->current_crl_score = 0;
+    ctx->current_reasons = 0;
+
+    if (x->ex_flags & EXFLAG_PROXY)
+        return 1;
+
+    while (ctx->current_reasons != CRLDP_ALL_REASONS) {
+        unsigned int last_reasons = ctx->current_reasons;
+
+        /* Try to retrieve relevant CRL */
+        if (ctx->get_crl)
+            ok = ctx->get_crl(ctx, &crl, x);
+        else
+            ok = get_crl_delta(ctx, &crl, &dcrl, x);
+        /*
+         * If error looking up CRL, nothing we can do except notify callback
+         */
+        if (!ok) {
+            ok = verify_cb_crl(ctx, X509_V_ERR_UNABLE_TO_GET_CRL);
+            goto done;
+        }
+        ctx->current_crl = crl;
+        ok = ctx->check_crl(ctx, crl);
+        if (!ok)
+            goto done;
+
+        if (dcrl) {
+            ok = ctx->check_crl(ctx, dcrl);
+            if (!ok)
+                goto done;
+            ok = ctx->cert_crl(ctx, dcrl, x);
+            if (!ok)
+                goto done;
+        } else
+            ok = 1;
+
+        /* Don't look in full CRL if delta reason is removefromCRL */
+        if (ok != 2) {
+            ok = ctx->cert_crl(ctx, crl, x);
+            if (!ok)
+                goto done;
+        }
+
+        X509_CRL_free(crl);
+        X509_CRL_free(dcrl);
+        crl = NULL;
+        dcrl = NULL;
+        /*
+         * If reasons not updated we won't get anywhere by another iteration,
+         * so exit loop.
+         */
+        if (last_reasons == ctx->current_reasons) {
+            ok = verify_cb_crl(ctx, X509_V_ERR_UNABLE_TO_GET_CRL);
+            goto done;
+        }
+    }
+ done:
+    X509_CRL_free(crl);
+    X509_CRL_free(dcrl);
+
+    ctx->current_crl = NULL;
+    return ok;
+}
+
+/* Check CRL times against values in X509_STORE_CTX */
+
+static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
+{
+    time_t *ptime;
+    int i;
+
+    if (notify)
+        ctx->current_crl = crl;
+    if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
+        ptime = &ctx->param->check_time;
+    else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME)
+        return 1;
+    else
+        ptime = NULL;
+
+    i = X509_cmp_time(X509_CRL_get0_lastUpdate(crl), ptime);
+    if (i == 0) {
+        if (!notify)
+            return 0;
+        if (!verify_cb_crl(ctx, X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD))
+            return 0;
+    }
+
+    if (i > 0) {
+        if (!notify)
+            return 0;
+        if (!verify_cb_crl(ctx, X509_V_ERR_CRL_NOT_YET_VALID))
+            return 0;
+    }
+
+    if (X509_CRL_get0_nextUpdate(crl)) {
+        i = X509_cmp_time(X509_CRL_get0_nextUpdate(crl), ptime);
+
+        if (i == 0) {
+            if (!notify)
+                return 0;
+            if (!verify_cb_crl(ctx, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD))
+                return 0;
+        }
+        /* Ignore expiry of base CRL is delta is valid */
+        if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) {
+            if (!notify)
+                return 0;
+            if (!verify_cb_crl(ctx, X509_V_ERR_CRL_HAS_EXPIRED))
+                return 0;
+        }
+    }
+
+    if (notify)
+        ctx->current_crl = NULL;
+
+    return 1;
+}
+
+static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
+                      X509 **pissuer, int *pscore, unsigned int *preasons,
+                      STACK_OF(X509_CRL) *crls)
+{
+    int i, crl_score, best_score = *pscore;
+    unsigned int reasons, best_reasons = 0;
+    X509 *x = ctx->current_cert;
+    X509_CRL *crl, *best_crl = NULL;
+    X509 *crl_issuer = NULL, *best_crl_issuer = NULL;
+
+    for (i = 0; i < sk_X509_CRL_num(crls); i++) {
+        crl = sk_X509_CRL_value(crls, i);
+        reasons = *preasons;
+        crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
+        if (crl_score < best_score || crl_score == 0)
+            continue;
+        /* If current CRL is equivalent use it if it is newer */
+        if (crl_score == best_score && best_crl != NULL) {
+            int day, sec;
+            if (ASN1_TIME_diff(&day, &sec, X509_CRL_get0_lastUpdate(best_crl),
+                               X509_CRL_get0_lastUpdate(crl)) == 0)
+                continue;
+            /*
+             * ASN1_TIME_diff never returns inconsistent signs for |day|
+             * and |sec|.
+             */
+            if (day <= 0 && sec <= 0)
+                continue;
+        }
+        best_crl = crl;
+        best_crl_issuer = crl_issuer;
+        best_score = crl_score;
+        best_reasons = reasons;
+    }
+
+    if (best_crl) {
+        X509_CRL_free(*pcrl);
+        *pcrl = best_crl;
+        *pissuer = best_crl_issuer;
+        *pscore = best_score;
+        *preasons = best_reasons;
+        X509_CRL_up_ref(best_crl);
+        X509_CRL_free(*pdcrl);
+        *pdcrl = NULL;
+        get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
+    }
+
+    if (best_score >= CRL_SCORE_VALID)
+        return 1;
+
+    return 0;
+}
+
+/*
+ * Compare two CRL extensions for delta checking purposes. They should be
+ * both present or both absent. If both present all fields must be identical.
+ */
+
+static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
+{
+    ASN1_OCTET_STRING *exta, *extb;
+    int i;
+    i = X509_CRL_get_ext_by_NID(a, nid, -1);
+    if (i >= 0) {
+        /* Can't have multiple occurrences */
+        if (X509_CRL_get_ext_by_NID(a, nid, i) != -1)
+            return 0;
+        exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i));
+    } else
+        exta = NULL;
+
+    i = X509_CRL_get_ext_by_NID(b, nid, -1);
+
+    if (i >= 0) {
+
+        if (X509_CRL_get_ext_by_NID(b, nid, i) != -1)
+            return 0;
+        extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i));
+    } else
+        extb = NULL;
+
+    if (!exta && !extb)
+        return 1;
+
+    if (!exta || !extb)
+        return 0;
+
+    if (ASN1_OCTET_STRING_cmp(exta, extb))
+        return 0;
+
+    return 1;
+}
+
+/* See if a base and delta are compatible */
+
+static int check_delta_base(X509_CRL *delta, X509_CRL *base)
+{
+    /* Delta CRL must be a delta */
+    if (!delta->base_crl_number)
+        return 0;
+    /* Base must have a CRL number */
+    if (!base->crl_number)
+        return 0;
+    /* Issuer names must match */
+    if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(delta)))
+        return 0;
+    /* AKID and IDP must match */
+    if (!crl_extension_match(delta, base, NID_authority_key_identifier))
+        return 0;
+    if (!crl_extension_match(delta, base, NID_issuing_distribution_point))
+        return 0;
+    /* Delta CRL base number must not exceed Full CRL number. */
+    if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
+        return 0;
+    /* Delta CRL number must exceed full CRL number */
+    if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0)
+        return 1;
+    return 0;
+}
+
+/*
+ * For a given base CRL find a delta... maybe extend to delta scoring or
+ * retrieve a chain of deltas...
+ */
+
+static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore,
+                         X509_CRL *base, STACK_OF(X509_CRL) *crls)
+{
+    X509_CRL *delta;
+    int i;
+    if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS))
+        return;
+    if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST))
+        return;
+    for (i = 0; i < sk_X509_CRL_num(crls); i++) {
+        delta = sk_X509_CRL_value(crls, i);
+        if (check_delta_base(delta, base)) {
+            if (check_crl_time(ctx, delta, 0))
+                *pscore |= CRL_SCORE_TIME_DELTA;
+            X509_CRL_up_ref(delta);
+            *dcrl = delta;
+            return;
+        }
+    }
+    *dcrl = NULL;
+}
+
+/*
+ * For a given CRL return how suitable it is for the supplied certificate
+ * 'x'. The return value is a mask of several criteria. If the issuer is not
+ * the certificate issuer this is returned in *pissuer. The reasons mask is
+ * also used to determine if the CRL is suitable: if no new reasons the CRL
+ * is rejected, otherwise reasons is updated.
+ */
+
+static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
+                         unsigned int *preasons, X509_CRL *crl, X509 *x)
+{
+
+    int crl_score = 0;
+    unsigned int tmp_reasons = *preasons, crl_reasons;
+
+    /* First see if we can reject CRL straight away */
+
+    /* Invalid IDP cannot be processed */
+    if (crl->idp_flags & IDP_INVALID)
+        return 0;
+    /* Reason codes or indirect CRLs need extended CRL support */
+    if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) {
+        if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS))
+            return 0;
+    } else if (crl->idp_flags & IDP_REASONS) {
+        /* If no new reasons reject */
+        if (!(crl->idp_reasons & ~tmp_reasons))
+            return 0;
+    }
+    /* Don't process deltas at this stage */
+    else if (crl->base_crl_number)
+        return 0;
+    /* If issuer name doesn't match certificate need indirect CRL */
+    if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) {
+        if (!(crl->idp_flags & IDP_INDIRECT))
+            return 0;
+    } else
+        crl_score |= CRL_SCORE_ISSUER_NAME;
+
+    if (!(crl->flags & EXFLAG_CRITICAL))
+        crl_score |= CRL_SCORE_NOCRITICAL;
+
+    /* Check expiry */
+    if (check_crl_time(ctx, crl, 0))
+        crl_score |= CRL_SCORE_TIME;
+
+    /* Check authority key ID and locate certificate issuer */
+    crl_akid_check(ctx, crl, pissuer, &crl_score);
+
+    /* If we can't locate certificate issuer at this point forget it */
+
+    if (!(crl_score & CRL_SCORE_AKID))
+        return 0;
+
+    /* Check cert for matching CRL distribution points */
+
+    if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) {
+        /* If no new reasons reject */
+        if (!(crl_reasons & ~tmp_reasons))
+            return 0;
+        tmp_reasons |= crl_reasons;
+        crl_score |= CRL_SCORE_SCOPE;
+    }
+
+    *preasons = tmp_reasons;
+
+    return crl_score;
+
+}
+
+static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
+                           X509 **pissuer, int *pcrl_score)
+{
+    X509 *crl_issuer = NULL;
+    X509_NAME *cnm = X509_CRL_get_issuer(crl);
+    int cidx = ctx->error_depth;
+    int i;
+
+    if (cidx != sk_X509_num(ctx->chain) - 1)
+        cidx++;
+
+    crl_issuer = sk_X509_value(ctx->chain, cidx);
+
+    if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
+        if (*pcrl_score & CRL_SCORE_ISSUER_NAME) {
+            *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_ISSUER_CERT;
+            *pissuer = crl_issuer;
+            return;
+        }
+    }
+
+    for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++) {
+        crl_issuer = sk_X509_value(ctx->chain, cidx);
+        if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
+            continue;
+        if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
+            *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_SAME_PATH;
+            *pissuer = crl_issuer;
+            return;
+        }
+    }
+
+    /* Anything else needs extended CRL support */
+
+    if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
+        return;
+
+    /*
+     * Otherwise the CRL issuer is not on the path. Look for it in the set of
+     * untrusted certificates.
+     */
+    for (i = 0; i < sk_X509_num(ctx->untrusted); i++) {
+        crl_issuer = sk_X509_value(ctx->untrusted, i);
+        if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
+            continue;
+        if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
+            *pissuer = crl_issuer;
+            *pcrl_score |= CRL_SCORE_AKID;
+            return;
+        }
+    }
+}
+
+/*
+ * Check the path of a CRL issuer certificate. This creates a new
+ * X509_STORE_CTX and populates it with most of the parameters from the
+ * parent. This could be optimised somewhat since a lot of path checking will
+ * be duplicated by the parent, but this will rarely be used in practice.
+ */
+
+static int check_crl_path(X509_STORE_CTX *ctx, X509 *x)
+{
+    X509_STORE_CTX crl_ctx;
+    int ret;
+
+    /* Don't allow recursive CRL path validation */
+    if (ctx->parent)
+        return 0;
+    if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted))
+        return -1;
+
+    crl_ctx.crls = ctx->crls;
+    /* Copy verify params across */
+    X509_STORE_CTX_set0_param(&crl_ctx, ctx->param);
+
+    crl_ctx.parent = ctx;
+    crl_ctx.verify_cb = ctx->verify_cb;
+
+    /* Verify CRL issuer */
+    ret = X509_verify_cert(&crl_ctx);
+    if (ret <= 0)
+        goto err;
+
+    /* Check chain is acceptable */
+    ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
+ err:
+    X509_STORE_CTX_cleanup(&crl_ctx);
+    return ret;
+}
+
+/*
+ * RFC3280 says nothing about the relationship between CRL path and
+ * certificate path, which could lead to situations where a certificate could
+ * be revoked or validated by a CA not authorised to do so. RFC5280 is more
+ * strict and states that the two paths must end in the same trust anchor,
+ * though some discussions remain... until this is resolved we use the
+ * RFC5280 version
+ */
+
+static int check_crl_chain(X509_STORE_CTX *ctx,
+                           STACK_OF(X509) *cert_path,
+                           STACK_OF(X509) *crl_path)
+{
+    X509 *cert_ta, *crl_ta;
+    cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1);
+    crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1);
+    if (!X509_cmp(cert_ta, crl_ta))
+        return 1;
+    return 0;
+}
+
+/*-
+ * Check for match between two dist point names: three separate cases.
+ * 1. Both are relative names and compare X509_NAME types.
+ * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES.
+ * 3. Both are full names and compare two GENERAL_NAMES.
+ * 4. One is NULL: automatic match.
+ */
+
+static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b)
+{
+    X509_NAME *nm = NULL;
+    GENERAL_NAMES *gens = NULL;
+    GENERAL_NAME *gena, *genb;
+    int i, j;
+    if (!a || !b)
+        return 1;
+    if (a->type == 1) {
+        if (!a->dpname)
+            return 0;
+        /* Case 1: two X509_NAME */
+        if (b->type == 1) {
+            if (!b->dpname)
+                return 0;
+            if (!X509_NAME_cmp(a->dpname, b->dpname))
+                return 1;
+            else
+                return 0;
+        }
+        /* Case 2: set name and GENERAL_NAMES appropriately */
+        nm = a->dpname;
+        gens = b->name.fullname;
+    } else if (b->type == 1) {
+        if (!b->dpname)
+            return 0;
+        /* Case 2: set name and GENERAL_NAMES appropriately */
+        gens = a->name.fullname;
+        nm = b->dpname;
+    }
+
+    /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */
+    if (nm) {
+        for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+            gena = sk_GENERAL_NAME_value(gens, i);
+            if (gena->type != GEN_DIRNAME)
+                continue;
+            if (!X509_NAME_cmp(nm, gena->d.directoryName))
+                return 1;
+        }
+        return 0;
+    }
+
+    /* Else case 3: two GENERAL_NAMES */
+
+    for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) {
+        gena = sk_GENERAL_NAME_value(a->name.fullname, i);
+        for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) {
+            genb = sk_GENERAL_NAME_value(b->name.fullname, j);
+            if (!GENERAL_NAME_cmp(gena, genb))
+                return 1;
+        }
+    }
+
+    return 0;
+
+}
+
+static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score)
+{
+    int i;
+    X509_NAME *nm = X509_CRL_get_issuer(crl);
+    /* If no CRLissuer return is successful iff don't need a match */
+    if (!dp->CRLissuer)
+        return ! !(crl_score & CRL_SCORE_ISSUER_NAME);
+    for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
+        GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
+        if (gen->type != GEN_DIRNAME)
+            continue;
+        if (!X509_NAME_cmp(gen->d.directoryName, nm))
+            return 1;
+    }
+    return 0;
+}
+
+/* Check CRLDP and IDP */
+
+static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
+                           unsigned int *preasons)
+{
+    int i;
+    if (crl->idp_flags & IDP_ONLYATTR)
+        return 0;
+    if (x->ex_flags & EXFLAG_CA) {
+        if (crl->idp_flags & IDP_ONLYUSER)
+            return 0;
+    } else {
+        if (crl->idp_flags & IDP_ONLYCA)
+            return 0;
+    }
+    *preasons = crl->idp_reasons;
+    for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) {
+        DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
+        if (crldp_check_crlissuer(dp, crl, crl_score)) {
+            if (!crl->idp || idp_check_dp(dp->distpoint, crl->idp->distpoint)) {
+                *preasons &= dp->dp_reasons;
+                return 1;
+            }
+        }
+    }
+    if ((!crl->idp || !crl->idp->distpoint)
+        && (crl_score & CRL_SCORE_ISSUER_NAME))
+        return 1;
+    return 0;
+}
+
+/*
+ * Retrieve CRL corresponding to current certificate. If deltas enabled try
+ * to find a delta CRL too
+ */
+
+static int get_crl_delta(X509_STORE_CTX *ctx,
+                         X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x)
+{
+    int ok;
+    X509 *issuer = NULL;
+    int crl_score = 0;
+    unsigned int reasons;
+    X509_CRL *crl = NULL, *dcrl = NULL;
+    STACK_OF(X509_CRL) *skcrl;
+    X509_NAME *nm = X509_get_issuer_name(x);
+
+    reasons = ctx->current_reasons;
+    ok = get_crl_sk(ctx, &crl, &dcrl,
+                    &issuer, &crl_score, &reasons, ctx->crls);
+    if (ok)
+        goto done;
+
+    /* Lookup CRLs from store */
+
+    skcrl = ctx->lookup_crls(ctx, nm);
+
+    /* If no CRLs found and a near match from get_crl_sk use that */
+    if (!skcrl && crl)
+        goto done;
+
+    get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl);
+
+    sk_X509_CRL_pop_free(skcrl, X509_CRL_free);
+
+ done:
+    /* If we got any kind of CRL use it and return success */
+    if (crl) {
+        ctx->current_issuer = issuer;
+        ctx->current_crl_score = crl_score;
+        ctx->current_reasons = reasons;
+        *pcrl = crl;
+        *pdcrl = dcrl;
+        return 1;
+    }
+    return 0;
+}
+
+/* Check CRL validity */
+static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
+{
+    X509 *issuer = NULL;
+    EVP_PKEY *ikey = NULL;
+    int cnum = ctx->error_depth;
+    int chnum = sk_X509_num(ctx->chain) - 1;
+
+    /* if we have an alternative CRL issuer cert use that */
+    if (ctx->current_issuer)
+        issuer = ctx->current_issuer;
+    /*
+     * Else find CRL issuer: if not last certificate then issuer is next
+     * certificate in chain.
+     */
+    else if (cnum < chnum)
+        issuer = sk_X509_value(ctx->chain, cnum + 1);
+    else {
+        issuer = sk_X509_value(ctx->chain, chnum);
+        /* If not self signed, can't check signature */
+        if (!ctx->check_issued(ctx, issuer, issuer) &&
+            !verify_cb_crl(ctx, X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER))
+            return 0;
+    }
+
+    if (issuer == NULL)
+        return 1;
+
+    /*
+     * Skip most tests for deltas because they have already been done
+     */
+    if (!crl->base_crl_number) {
+        /* Check for cRLSign bit if keyUsage present */
+        if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
+            !(issuer->ex_kusage & KU_CRL_SIGN) &&
+            !verify_cb_crl(ctx, X509_V_ERR_KEYUSAGE_NO_CRL_SIGN))
+            return 0;
+
+        if (!(ctx->current_crl_score & CRL_SCORE_SCOPE) &&
+            !verify_cb_crl(ctx, X509_V_ERR_DIFFERENT_CRL_SCOPE))
+            return 0;
+
+        if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH) &&
+            check_crl_path(ctx, ctx->current_issuer) <= 0 &&
+            !verify_cb_crl(ctx, X509_V_ERR_CRL_PATH_VALIDATION_ERROR))
+            return 0;
+
+        if ((crl->idp_flags & IDP_INVALID) &&
+            !verify_cb_crl(ctx, X509_V_ERR_INVALID_EXTENSION))
+            return 0;
+    }
+
+    if (!(ctx->current_crl_score & CRL_SCORE_TIME) &&
+        !check_crl_time(ctx, crl, 1))
+        return 0;
+
+    /* Attempt to get issuer certificate public key */
+    ikey = X509_get0_pubkey(issuer);
+
+    if (!ikey &&
+        !verify_cb_crl(ctx, X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY))
+        return 0;
+
+    if (ikey) {
+        int rv = X509_CRL_check_suiteb(crl, ikey, ctx->param->flags);
+
+        if (rv != X509_V_OK && !verify_cb_crl(ctx, rv))
+            return 0;
+        /* Verify CRL signature */
+        if (X509_CRL_verify(crl, ikey) <= 0 &&
+            !verify_cb_crl(ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE))
+            return 0;
+    }
+    return 1;
+}
+
+/* Check certificate against CRL */
+static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
+{
+    X509_REVOKED *rev;
+
+    /*
+     * The rules changed for this... previously if a CRL contained unhandled
+     * critical extensions it could still be used to indicate a certificate
+     * was revoked. This has since been changed since critical extensions can
+     * change the meaning of CRL entries.
+     */
+    if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
+        && (crl->flags & EXFLAG_CRITICAL) &&
+        !verify_cb_crl(ctx, X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION))
+        return 0;
+    /*
+     * Look for serial number of certificate in CRL.  If found, make sure
+     * reason is not removeFromCRL.
+     */
+    if (X509_CRL_get0_by_cert(crl, &rev, x)) {
+        if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
+            return 2;
+        if (!verify_cb_crl(ctx, X509_V_ERR_CERT_REVOKED))
+            return 0;
+    }
+
+    return 1;
+}
+
+static int check_policy(X509_STORE_CTX *ctx)
+{
+    int ret;
+
+    if (ctx->parent)
+        return 1;
+    /*
+     * With DANE, the trust anchor might be a bare public key, not a
+     * certificate!  In that case our chain does not have the trust anchor
+     * certificate as a top-most element.  This comports well with RFC5280
+     * chain verification, since there too, the trust anchor is not part of the
+     * chain to be verified.  In particular, X509_policy_check() does not look
+     * at the TA cert, but assumes that it is present as the top-most chain
+     * element.  We therefore temporarily push a NULL cert onto the chain if it
+     * was verified via a bare public key, and pop it off right after the
+     * X509_policy_check() call.
+     */
+    if (ctx->bare_ta_signed && !sk_X509_push(ctx->chain, NULL)) {
+        X509err(X509_F_CHECK_POLICY, ERR_R_MALLOC_FAILURE);
+        ctx->error = X509_V_ERR_OUT_OF_MEM;
+        return 0;
+    }
+    ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
+                            ctx->param->policies, ctx->param->flags);
+    if (ctx->bare_ta_signed)
+        sk_X509_pop(ctx->chain);
+
+    if (ret == X509_PCY_TREE_INTERNAL) {
+        X509err(X509_F_CHECK_POLICY, ERR_R_MALLOC_FAILURE);
+        ctx->error = X509_V_ERR_OUT_OF_MEM;
+        return 0;
+    }
+    /* Invalid or inconsistent extensions */
+    if (ret == X509_PCY_TREE_INVALID) {
+        int i;
+
+        /* Locate certificates with bad extensions and notify callback. */
+        for (i = 1; i < sk_X509_num(ctx->chain); i++) {
+            X509 *x = sk_X509_value(ctx->chain, i);
+
+            if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
+                continue;
+            if (!verify_cb_cert(ctx, x, i,
+                                X509_V_ERR_INVALID_POLICY_EXTENSION))
+                return 0;
+        }
+        return 1;
+    }
+    if (ret == X509_PCY_TREE_FAILURE) {
+        ctx->current_cert = NULL;
+        ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
+        return ctx->verify_cb(0, ctx);
+    }
+    if (ret != X509_PCY_TREE_VALID) {
+        X509err(X509_F_CHECK_POLICY, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) {
+        ctx->current_cert = NULL;
+        /*
+         * Verification errors need to be "sticky", a callback may have allowed
+         * an SSL handshake to continue despite an error, and we must then
+         * remain in an error state.  Therefore, we MUST NOT clear earlier
+         * verification errors by setting the error to X509_V_OK.
+         */
+        if (!ctx->verify_cb(2, ctx))
+            return 0;
+    }
+
+    return 1;
+}
+
+/*-
+ * Check certificate validity times.
+ * If depth >= 0, invoke verification callbacks on error, otherwise just return
+ * the validation status.
+ *
+ * Return 1 on success, 0 otherwise.
+ */
+int x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth)
+{
+    time_t *ptime;
+    int i;
+
+    if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
+        ptime = &ctx->param->check_time;
+    else if (ctx->param->flags & X509_V_FLAG_NO_CHECK_TIME)
+        return 1;
+    else
+        ptime = NULL;
+
+    i = X509_cmp_time(X509_get0_notBefore(x), ptime);
+    if (i >= 0 && depth < 0)
+        return 0;
+    if (i == 0 && !verify_cb_cert(ctx, x, depth,
+                                  X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD))
+        return 0;
+    if (i > 0 && !verify_cb_cert(ctx, x, depth, X509_V_ERR_CERT_NOT_YET_VALID))
+        return 0;
+
+    i = X509_cmp_time(X509_get0_notAfter(x), ptime);
+    if (i <= 0 && depth < 0)
+        return 0;
+    if (i == 0 && !verify_cb_cert(ctx, x, depth,
+                                  X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD))
+        return 0;
+    if (i < 0 && !verify_cb_cert(ctx, x, depth, X509_V_ERR_CERT_HAS_EXPIRED))
+        return 0;
+    return 1;
+}
+
+static int internal_verify(X509_STORE_CTX *ctx)
+{
+    int n = sk_X509_num(ctx->chain) - 1;
+    X509 *xi = sk_X509_value(ctx->chain, n);
+    X509 *xs;
+
+    /*
+     * With DANE-verified bare public key TA signatures, it remains only to
+     * check the timestamps of the top certificate.  We report the issuer as
+     * NULL, since all we have is a bare key.
+     */
+    if (ctx->bare_ta_signed) {
+        xs = xi;
+        xi = NULL;
+        goto check_cert;
+    }
+
+    if (ctx->check_issued(ctx, xi, xi))
+        xs = xi;
+    else {
+        if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
+            xs = xi;
+            goto check_cert;
+        }
+        if (n <= 0)
+            return verify_cb_cert(ctx, xi, 0,
+                                  X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE);
+        n--;
+        ctx->error_depth = n;
+        xs = sk_X509_value(ctx->chain, n);
+    }
+
+    /*
+     * Do not clear ctx->error=0, it must be "sticky", only the user's callback
+     * is allowed to reset errors (at its own peril).
+     */
+    while (n >= 0) {
+        EVP_PKEY *pkey;
+
+        /*
+         * Skip signature check for self signed certificates unless explicitly
+         * asked for.  It doesn't add any security and just wastes time.  If
+         * the issuer's public key is unusable, report the issuer certificate
+         * and its depth (rather than the depth of the subject).
+         */
+        if (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)) {
+            if ((pkey = X509_get0_pubkey(xi)) == NULL) {
+                if (!verify_cb_cert(ctx, xi, xi != xs ? n+1 : n,
+                        X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY))
+                    return 0;
+            } else if (X509_verify(xs, pkey) <= 0) {
+                if (!verify_cb_cert(ctx, xs, n,
+                                    X509_V_ERR_CERT_SIGNATURE_FAILURE))
+                    return 0;
+            }
+        }
+
+ check_cert:
+        /* Calls verify callback as needed */
+        if (!x509_check_cert_time(ctx, xs, n))
+            return 0;
+
+        /*
+         * Signal success at this depth.  However, the previous error (if any)
+         * is retained.
+         */
+        ctx->current_issuer = xi;
+        ctx->current_cert = xs;
+        ctx->error_depth = n;
+        if (!ctx->verify_cb(1, ctx))
+            return 0;
+
+        if (--n >= 0) {
+            xi = xs;
+            xs = sk_X509_value(ctx->chain, n);
+        }
+    }
+    return 1;
+}
+
+int X509_cmp_current_time(const ASN1_TIME *ctm)
+{
+    return X509_cmp_time(ctm, NULL);
+}
+
+int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
+{
+    char *str;
+    ASN1_TIME atm;
+    long offset;
+    char buff1[24], buff2[24], *p;
+    int i, j, remaining;
+
+    p = buff1;
+    remaining = ctm->length;
+    str = (char *)ctm->data;
+    /*
+     * Note that the following (historical) code allows much more slack in the
+     * time format than RFC5280. In RFC5280, the representation is fixed:
+     * UTCTime: YYMMDDHHMMSSZ
+     * GeneralizedTime: YYYYMMDDHHMMSSZ
+     */
+    if (ctm->type == V_ASN1_UTCTIME) {
+        /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
+        int min_length = sizeof("YYMMDDHHMMZ") - 1;
+        int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
+        if (remaining < min_length || remaining > max_length)
+            return 0;
+        memcpy(p, str, 10);
+        p += 10;
+        str += 10;
+        remaining -= 10;
+    } else {
+        /* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */
+        int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
+        int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
+        if (remaining < min_length || remaining > max_length)
+            return 0;
+        memcpy(p, str, 12);
+        p += 12;
+        str += 12;
+        remaining -= 12;
+    }
+
+    if ((*str == 'Z') || (*str == '-') || (*str == '+')) {
+        *(p++) = '0';
+        *(p++) = '0';
+    } else {
+        /* SS (seconds) */
+        if (remaining < 2)
+            return 0;
+        *(p++) = *(str++);
+        *(p++) = *(str++);
+        remaining -= 2;
+        /*
+         * Skip any (up to three) fractional seconds...
+         * TODO(emilia): in RFC5280, fractional seconds are forbidden.
+         * Can we just kill them altogether?
+         */
+        if (remaining && *str == '.') {
+            str++;
+            remaining--;
+            for (i = 0; i < 3 && remaining; i++, str++, remaining--) {
+                if (*str < '0' || *str > '9')
+                    break;
+            }
+        }
+
+    }
+    *(p++) = 'Z';
+    *(p++) = '\0';
+
+    /* We now need either a terminating 'Z' or an offset. */
+    if (!remaining)
+        return 0;
+    if (*str == 'Z') {
+        if (remaining != 1)
+            return 0;
+        offset = 0;
+    } else {
+        /* (+-)HHMM */
+        if ((*str != '+') && (*str != '-'))
+            return 0;
+        /* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */
+        if (remaining != 5)
+            return 0;
+        if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
+            str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
+            return 0;
+        offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60;
+        offset += (str[3] - '0') * 10 + (str[4] - '0');
+        if (*str == '-')
+            offset = -offset;
+    }
+    atm.type = ctm->type;
+    atm.flags = 0;
+    atm.length = sizeof(buff2);
+    atm.data = (unsigned char *)buff2;
+
+    if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL)
+        return 0;
+
+    if (ctm->type == V_ASN1_UTCTIME) {
+        i = (buff1[0] - '0') * 10 + (buff1[1] - '0');
+        if (i < 50)
+            i += 100;           /* cf. RFC 2459 */
+        j = (buff2[0] - '0') * 10 + (buff2[1] - '0');
+        if (j < 50)
+            j += 100;
+
+        if (i < j)
+            return -1;
+        if (i > j)
+            return 1;
+    }
+    i = strcmp(buff1, buff2);
+    if (i == 0)                 /* wait a second then return younger :-) */
+        return -1;
+    else
+        return i;
+}
+
+ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj)
+{
+    return X509_time_adj(s, adj, NULL);
+}
+
+ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm)
+{
+    return X509_time_adj_ex(s, 0, offset_sec, in_tm);
+}
+
+ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
+                            int offset_day, long offset_sec, time_t *in_tm)
+{
+    time_t t;
+
+    if (in_tm)
+        t = *in_tm;
+    else
+        time(&t);
+
+    if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING)) {
+        if (s->type == V_ASN1_UTCTIME)
+            return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
+        if (s->type == V_ASN1_GENERALIZEDTIME)
+            return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
+    }
+    return ASN1_TIME_adj(s, t, offset_day, offset_sec);
+}
+
+int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain)
+{
+    EVP_PKEY *ktmp = NULL, *ktmp2;
+    int i, j;
+
+    if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey))
+        return 1;
+
+    for (i = 0; i < sk_X509_num(chain); i++) {
+        ktmp = X509_get0_pubkey(sk_X509_value(chain, i));
+        if (ktmp == NULL) {
+            X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,
+                    X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY);
+            return 0;
+        }
+        if (!EVP_PKEY_missing_parameters(ktmp))
+            break;
+    }
+    if (ktmp == NULL) {
+        X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,
+                X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN);
+        return 0;
+    }
+
+    /* first, populate the other certs */
+    for (j = i - 1; j >= 0; j--) {
+        ktmp2 = X509_get0_pubkey(sk_X509_value(chain, j));
+        EVP_PKEY_copy_parameters(ktmp2, ktmp);
+    }
+
+    if (pkey != NULL)
+        EVP_PKEY_copy_parameters(pkey, ktmp);
+    return 1;
+}
+
+/* Make a delta CRL as the diff between two full CRLs */
+
+X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
+                        EVP_PKEY *skey, const EVP_MD *md, unsigned int flags)
+{
+    X509_CRL *crl = NULL;
+    int i;
+    STACK_OF(X509_REVOKED) *revs = NULL;
+    /* CRLs can't be delta already */
+    if (base->base_crl_number || newer->base_crl_number) {
+        X509err(X509_F_X509_CRL_DIFF, X509_R_CRL_ALREADY_DELTA);
+        return NULL;
+    }
+    /* Base and new CRL must have a CRL number */
+    if (!base->crl_number || !newer->crl_number) {
+        X509err(X509_F_X509_CRL_DIFF, X509_R_NO_CRL_NUMBER);
+        return NULL;
+    }
+    /* Issuer names must match */
+    if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(newer))) {
+        X509err(X509_F_X509_CRL_DIFF, X509_R_ISSUER_MISMATCH);
+        return NULL;
+    }
+    /* AKID and IDP must match */
+    if (!crl_extension_match(base, newer, NID_authority_key_identifier)) {
+        X509err(X509_F_X509_CRL_DIFF, X509_R_AKID_MISMATCH);
+        return NULL;
+    }
+    if (!crl_extension_match(base, newer, NID_issuing_distribution_point)) {
+        X509err(X509_F_X509_CRL_DIFF, X509_R_IDP_MISMATCH);
+        return NULL;
+    }
+    /* Newer CRL number must exceed full CRL number */
+    if (ASN1_INTEGER_cmp(newer->crl_number, base->crl_number) <= 0) {
+        X509err(X509_F_X509_CRL_DIFF, X509_R_NEWER_CRL_NOT_NEWER);
+        return NULL;
+    }
+    /* CRLs must verify */
+    if (skey && (X509_CRL_verify(base, skey) <= 0 ||
+                 X509_CRL_verify(newer, skey) <= 0)) {
+        X509err(X509_F_X509_CRL_DIFF, X509_R_CRL_VERIFY_FAILURE);
+        return NULL;
+    }
+    /* Create new CRL */
+    crl = X509_CRL_new();
+    if (crl == NULL || !X509_CRL_set_version(crl, 1))
+        goto memerr;
+    /* Set issuer name */
+    if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer)))
+        goto memerr;
+
+    if (!X509_CRL_set1_lastUpdate(crl, X509_CRL_get0_lastUpdate(newer)))
+        goto memerr;
+    if (!X509_CRL_set1_nextUpdate(crl, X509_CRL_get0_nextUpdate(newer)))
+        goto memerr;
+
+    /* Set base CRL number: must be critical */
+
+    if (!X509_CRL_add1_ext_i2d(crl, NID_delta_crl, base->crl_number, 1, 0))
+        goto memerr;
+
+    /*
+     * Copy extensions across from newest CRL to delta: this will set CRL
+     * number to correct value too.
+     */
+
+    for (i = 0; i < X509_CRL_get_ext_count(newer); i++) {
+        X509_EXTENSION *ext;
+        ext = X509_CRL_get_ext(newer, i);
+        if (!X509_CRL_add_ext(crl, ext, -1))
+            goto memerr;
+    }
+
+    /* Go through revoked entries, copying as needed */
+
+    revs = X509_CRL_get_REVOKED(newer);
+
+    for (i = 0; i < sk_X509_REVOKED_num(revs); i++) {
+        X509_REVOKED *rvn, *rvtmp;
+        rvn = sk_X509_REVOKED_value(revs, i);
+        /*
+         * Add only if not also in base. TODO: need something cleverer here
+         * for some more complex CRLs covering multiple CAs.
+         */
+        if (!X509_CRL_get0_by_serial(base, &rvtmp, &rvn->serialNumber)) {
+            rvtmp = X509_REVOKED_dup(rvn);
+            if (!rvtmp)
+                goto memerr;
+            if (!X509_CRL_add0_revoked(crl, rvtmp)) {
+                X509_REVOKED_free(rvtmp);
+                goto memerr;
+            }
+        }
+    }
+    /* TODO: optionally prune deleted entries */
+
+    if (skey && md && !X509_CRL_sign(crl, skey, md))
+        goto memerr;
+
+    return crl;
+
+ memerr:
+    X509err(X509_F_X509_CRL_DIFF, ERR_R_MALLOC_FAILURE);
+    X509_CRL_free(crl);
+    return NULL;
+}
+
+int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data)
+{
+    return CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
+}
+
+void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
+{
+    return CRYPTO_get_ex_data(&ctx->ex_data, idx);
+}
+
+int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx)
+{
+    return ctx->error;
+}
+
+void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err)
+{
+    ctx->error = err;
+}
+
+int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx)
+{
+    return ctx->error_depth;
+}
+
+void X509_STORE_CTX_set_error_depth(X509_STORE_CTX *ctx, int depth)
+{
+    ctx->error_depth = depth;
+}
+
+X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
+{
+    return ctx->current_cert;
+}
+
+void X509_STORE_CTX_set_current_cert(X509_STORE_CTX *ctx, X509 *x)
+{
+    ctx->current_cert = x;
+}
+
+STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx)
+{
+    return ctx->chain;
+}
+
+STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
+{
+    if (!ctx->chain)
+        return NULL;
+    return X509_chain_up_ref(ctx->chain);
+}
+
+X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx)
+{
+    return ctx->current_issuer;
+}
+
+X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx)
+{
+    return ctx->current_crl;
+}
+
+X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx)
+{
+    return ctx->parent;
+}
+
+void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x)
+{
+    ctx->cert = x;
+}
+
+void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk)
+{
+    ctx->crls = sk;
+}
+
+int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
+{
+    /*
+     * XXX: Why isn't this function always used to set the associated trust?
+     * Should there even be a VPM->trust field at all?  Or should the trust
+     * always be inferred from the purpose by X509_STORE_CTX_init().
+     */
+    return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
+}
+
+int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
+{
+    /*
+     * XXX: See above, this function would only be needed when the default
+     * trust for the purpose needs an override in a corner case.
+     */
+    return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
+}
+
+/*
+ * This function is used to set the X509_STORE_CTX purpose and trust values.
+ * This is intended to be used when another structure has its own trust and
+ * purpose values which (if set) will be inherited by the ctx. If they aren't
+ * set then we will usually have a default purpose in mind which should then
+ * be used to set the trust value. An example of this is SSL use: an SSL
+ * structure will have its own purpose and trust settings which the
+ * application can set: if they aren't set then we use the default of SSL
+ * client/server.
+ */
+
+int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
+                                   int purpose, int trust)
+{
+    int idx;
+    /* If purpose not set use default */
+    if (!purpose)
+        purpose = def_purpose;
+    /* If we have a purpose then check it is valid */
+    if (purpose) {
+        X509_PURPOSE *ptmp;
+        idx = X509_PURPOSE_get_by_id(purpose);
+        if (idx == -1) {
+            X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
+                    X509_R_UNKNOWN_PURPOSE_ID);
+            return 0;
+        }
+        ptmp = X509_PURPOSE_get0(idx);
+        if (ptmp->trust == X509_TRUST_DEFAULT) {
+            idx = X509_PURPOSE_get_by_id(def_purpose);
+            /*
+             * XXX: In the two callers above def_purpose is always 0, which is
+             * not a known value, so idx will always be -1.  How is the
+             * X509_TRUST_DEFAULT case actually supposed to be handled?
+             */
+            if (idx == -1) {
+                X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
+                        X509_R_UNKNOWN_PURPOSE_ID);
+                return 0;
+            }
+            ptmp = X509_PURPOSE_get0(idx);
+        }
+        /* If trust not set then get from purpose default */
+        if (!trust)
+            trust = ptmp->trust;
+    }
+    if (trust) {
+        idx = X509_TRUST_get_by_id(trust);
+        if (idx == -1) {
+            X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
+                    X509_R_UNKNOWN_TRUST_ID);
+            return 0;
+        }
+    }
+
+    if (purpose && !ctx->param->purpose)
+        ctx->param->purpose = purpose;
+    if (trust && !ctx->param->trust)
+        ctx->param->trust = trust;
+    return 1;
+}
+
+X509_STORE_CTX *X509_STORE_CTX_new(void)
+{
+    X509_STORE_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+    if (ctx == NULL) {
+        X509err(X509_F_X509_STORE_CTX_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    return ctx;
+}
+
+void X509_STORE_CTX_free(X509_STORE_CTX *ctx)
+{
+    if (ctx == NULL)
+        return;
+
+    X509_STORE_CTX_cleanup(ctx);
+    OPENSSL_free(ctx);
+}
+
+int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
+                        STACK_OF(X509) *chain)
+{
+    int ret = 1;
+
+    ctx->ctx = store;
+    ctx->cert = x509;
+    ctx->untrusted = chain;
+    ctx->crls = NULL;
+    ctx->num_untrusted = 0;
+    ctx->other_ctx = NULL;
+    ctx->valid = 0;
+    ctx->chain = NULL;
+    ctx->error = 0;
+    ctx->explicit_policy = 0;
+    ctx->error_depth = 0;
+    ctx->current_cert = NULL;
+    ctx->current_issuer = NULL;
+    ctx->current_crl = NULL;
+    ctx->current_crl_score = 0;
+    ctx->current_reasons = 0;
+    ctx->tree = NULL;
+    ctx->parent = NULL;
+    ctx->dane = NULL;
+    ctx->bare_ta_signed = 0;
+    /* Zero ex_data to make sure we're cleanup-safe */
+    memset(&ctx->ex_data, 0, sizeof(ctx->ex_data));
+
+    /* store->cleanup is always 0 in OpenSSL, if set must be idempotent */
+    if (store)
+        ctx->cleanup = store->cleanup;
+    else
+        ctx->cleanup = 0;
+
+    if (store && store->check_issued)
+        ctx->check_issued = store->check_issued;
+    else
+        ctx->check_issued = check_issued;
+
+    if (store && store->get_issuer)
+        ctx->get_issuer = store->get_issuer;
+    else
+        ctx->get_issuer = X509_STORE_CTX_get1_issuer;
+
+    if (store && store->verify_cb)
+        ctx->verify_cb = store->verify_cb;
+    else
+        ctx->verify_cb = null_callback;
+
+    if (store && store->verify)
+        ctx->verify = store->verify;
+    else
+        ctx->verify = internal_verify;
+
+    if (store && store->check_revocation)
+        ctx->check_revocation = store->check_revocation;
+    else
+        ctx->check_revocation = check_revocation;
+
+    if (store && store->get_crl)
+        ctx->get_crl = store->get_crl;
+    else
+        ctx->get_crl = NULL;
+
+    if (store && store->check_crl)
+        ctx->check_crl = store->check_crl;
+    else
+        ctx->check_crl = check_crl;
+
+    if (store && store->cert_crl)
+        ctx->cert_crl = store->cert_crl;
+    else
+        ctx->cert_crl = cert_crl;
+
+    if (store && store->check_policy)
+        ctx->check_policy = store->check_policy;
+    else
+        ctx->check_policy = check_policy;
+
+    if (store && store->lookup_certs)
+        ctx->lookup_certs = store->lookup_certs;
+    else
+        ctx->lookup_certs = X509_STORE_CTX_get1_certs;
+
+    if (store && store->lookup_crls)
+        ctx->lookup_crls = store->lookup_crls;
+    else
+        ctx->lookup_crls = X509_STORE_CTX_get1_crls;
+
+    ctx->param = X509_VERIFY_PARAM_new();
+    if (ctx->param == NULL) {
+        X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    /*
+     * Inherit callbacks and flags from X509_STORE if not set use defaults.
+     */
+    if (store)
+        ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
+    else
+        ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT | X509_VP_FLAG_ONCE;
+
+    if (ret)
+        ret = X509_VERIFY_PARAM_inherit(ctx->param,
+                                        X509_VERIFY_PARAM_lookup("default"));
+
+    if (ret == 0) {
+        X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    /*
+     * XXX: For now, continue to inherit trust from VPM, but infer from the
+     * purpose if this still yields the default value.
+     */
+    if (ctx->param->trust == X509_TRUST_DEFAULT) {
+        int idx = X509_PURPOSE_get_by_id(ctx->param->purpose);
+        X509_PURPOSE *xp = X509_PURPOSE_get0(idx);
+
+        if (xp != NULL)
+            ctx->param->trust = X509_PURPOSE_get_trust(xp);
+    }
+
+    if (CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx,
+                           &ctx->ex_data))
+        return 1;
+    X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
+
+ err:
+    /*
+     * On error clean up allocated storage, if the store context was not
+     * allocated with X509_STORE_CTX_new() this is our last chance to do so.
+     */
+    X509_STORE_CTX_cleanup(ctx);
+    return 0;
+}
+
+/*
+ * Set alternative lookup method: just a STACK of trusted certificates. This
+ * avoids X509_STORE nastiness where it isn't needed.
+ */
+void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
+{
+    ctx->other_ctx = sk;
+    ctx->get_issuer = get_issuer_sk;
+    ctx->lookup_certs = lookup_certs_sk;
+}
+
+void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
+{
+    /*
+     * We need to be idempotent because, unfortunately, free() also calls
+     * cleanup(), so the natural call sequence new(), init(), cleanup(), free()
+     * calls cleanup() for the same object twice!  Thus we must zero the
+     * pointers below after they're freed!
+     */
+    /* Seems to always be 0 in OpenSSL, do this at most once. */
+    if (ctx->cleanup != NULL) {
+        ctx->cleanup(ctx);
+        ctx->cleanup = NULL;
+    }
+    if (ctx->param != NULL) {
+        if (ctx->parent == NULL)
+            X509_VERIFY_PARAM_free(ctx->param);
+        ctx->param = NULL;
+    }
+    X509_policy_tree_free(ctx->tree);
+    ctx->tree = NULL;
+    sk_X509_pop_free(ctx->chain, X509_free);
+    ctx->chain = NULL;
+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data));
+    memset(&ctx->ex_data, 0, sizeof(ctx->ex_data));
+}
+
+void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth)
+{
+    X509_VERIFY_PARAM_set_depth(ctx->param, depth);
+}
+
+void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags)
+{
+    X509_VERIFY_PARAM_set_flags(ctx->param, flags);
+}
+
+void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
+                             time_t t)
+{
+    X509_VERIFY_PARAM_set_time(ctx->param, t);
+}
+
+X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx)
+{
+    return ctx->cert;
+}
+
+STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx)
+{
+    return ctx->untrusted;
+}
+
+void X509_STORE_CTX_set0_untrusted(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
+{
+    ctx->untrusted = sk;
+}
+
+void X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
+{
+    sk_X509_pop_free(ctx->chain, X509_free);
+    ctx->chain = sk;
+}
+
+void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
+                                  X509_STORE_CTX_verify_cb verify_cb)
+{
+    ctx->verify_cb = verify_cb;
+}
+
+X509_STORE_CTX_verify_cb X509_STORE_CTX_get_verify_cb(X509_STORE_CTX *ctx)
+{
+    return ctx->verify_cb;
+}
+
+void X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx,
+                               X509_STORE_CTX_verify_fn verify)
+{
+    ctx->verify = verify;
+}
+
+X509_STORE_CTX_verify_fn X509_STORE_CTX_get_verify(X509_STORE_CTX *ctx)
+{
+    return ctx->verify;
+}
+
+X509_STORE_CTX_get_issuer_fn X509_STORE_CTX_get_get_issuer(X509_STORE_CTX *ctx)
+{
+    return ctx->get_issuer;
+}
+
+X509_STORE_CTX_check_issued_fn X509_STORE_CTX_get_check_issued(X509_STORE_CTX *ctx)
+{
+    return ctx->check_issued;
+}
+
+X509_STORE_CTX_check_revocation_fn X509_STORE_CTX_get_check_revocation(X509_STORE_CTX *ctx)
+{
+    return ctx->check_revocation;
+}
+
+X509_STORE_CTX_get_crl_fn X509_STORE_CTX_get_get_crl(X509_STORE_CTX *ctx)
+{
+    return ctx->get_crl;
+}
+
+X509_STORE_CTX_check_crl_fn X509_STORE_CTX_get_check_crl(X509_STORE_CTX *ctx)
+{
+    return ctx->check_crl;
+}
+
+X509_STORE_CTX_cert_crl_fn X509_STORE_CTX_get_cert_crl(X509_STORE_CTX *ctx)
+{
+    return ctx->cert_crl;
+}
+
+X509_STORE_CTX_check_policy_fn X509_STORE_CTX_get_check_policy(X509_STORE_CTX *ctx)
+{
+    return ctx->check_policy;
+}
+
+X509_STORE_CTX_lookup_certs_fn X509_STORE_CTX_get_lookup_certs(X509_STORE_CTX *ctx)
+{
+    return ctx->lookup_certs;
+}
+
+X509_STORE_CTX_lookup_crls_fn X509_STORE_CTX_get_lookup_crls(X509_STORE_CTX *ctx)
+{
+    return ctx->lookup_crls;
+}
+
+X509_STORE_CTX_cleanup_fn X509_STORE_CTX_get_cleanup(X509_STORE_CTX *ctx)
+{
+    return ctx->cleanup;
+}
+
+X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx)
+{
+    return ctx->tree;
+}
+
+int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx)
+{
+    return ctx->explicit_policy;
+}
+
+int X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx)
+{
+    return ctx->num_untrusted;
+}
+
+int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name)
+{
+    const X509_VERIFY_PARAM *param;
+    param = X509_VERIFY_PARAM_lookup(name);
+    if (!param)
+        return 0;
+    return X509_VERIFY_PARAM_inherit(ctx->param, param);
+}
+
+X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx)
+{
+    return ctx->param;
+}
+
+void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param)
+{
+    X509_VERIFY_PARAM_free(ctx->param);
+    ctx->param = param;
+}
+
+void X509_STORE_CTX_set0_dane(X509_STORE_CTX *ctx, SSL_DANE *dane)
+{
+    ctx->dane = dane;
+}
+
+static unsigned char *dane_i2d(
+    X509 *cert,
+    uint8_t selector,
+    unsigned int *i2dlen)
+{
+    unsigned char *buf = NULL;
+    int len;
+
+    /*
+     * Extract ASN.1 DER form of certificate or public key.
+     */
+    switch (selector) {
+    case DANETLS_SELECTOR_CERT:
+        len = i2d_X509(cert, &buf);
+        break;
+    case DANETLS_SELECTOR_SPKI:
+        len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &buf);
+        break;
+    default:
+        X509err(X509_F_DANE_I2D, X509_R_BAD_SELECTOR);
+        return NULL;
+    }
+
+    if (len < 0 || buf == NULL) {
+        X509err(X509_F_DANE_I2D, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    *i2dlen = (unsigned int)len;
+    return buf;
+}
+
+#define DANETLS_NONE 256        /* impossible uint8_t */
+
+static int dane_match(X509_STORE_CTX *ctx, X509 *cert, int depth)
+{
+    SSL_DANE *dane = ctx->dane;
+    unsigned usage = DANETLS_NONE;
+    unsigned selector = DANETLS_NONE;
+    unsigned ordinal = DANETLS_NONE;
+    unsigned mtype = DANETLS_NONE;
+    unsigned char *i2dbuf = NULL;
+    unsigned int i2dlen = 0;
+    unsigned char mdbuf[EVP_MAX_MD_SIZE];
+    unsigned char *cmpbuf = NULL;
+    unsigned int cmplen = 0;
+    int i;
+    int recnum;
+    int matched = 0;
+    danetls_record *t = NULL;
+    uint32_t mask;
+
+    mask = (depth == 0) ? DANETLS_EE_MASK : DANETLS_TA_MASK;
+
+    /*
+     * The trust store is not applicable with DANE-TA(2)
+     */
+    if (depth >= ctx->num_untrusted)
+        mask &= DANETLS_PKIX_MASK;
+
+    /*
+     * If we've previously matched a PKIX-?? record, no need to test any
+     * further PKIX-?? records, it remains to just build the PKIX chain.
+     * Had the match been a DANE-?? record, we'd be done already.
+     */
+    if (dane->mdpth >= 0)
+        mask &= ~DANETLS_PKIX_MASK;
+
+    /*-
+     * https://tools.ietf.org/html/rfc7671#section-5.1
+     * https://tools.ietf.org/html/rfc7671#section-5.2
+     * https://tools.ietf.org/html/rfc7671#section-5.3
+     * https://tools.ietf.org/html/rfc7671#section-5.4
+     *
+     * We handle DANE-EE(3) records first as they require no chain building
+     * and no expiration or hostname checks.  We also process digests with
+     * higher ordinals first and ignore lower priorities except Full(0) which
+     * is always processed (last).  If none match, we then process PKIX-EE(1).
+     *
+     * NOTE: This relies on DANE usages sorting before the corresponding PKIX
+     * usages in SSL_dane_tlsa_add(), and also on descending sorting of digest
+     * priorities.  See twin comment in ssl/ssl_lib.c.
+     *
+     * We expect that most TLSA RRsets will have just a single usage, so we
+     * don't go out of our way to cache multiple selector-specific i2d buffers
+     * across usages, but if the selector happens to remain the same as switch
+     * usages, that's OK.  Thus, a set of "3 1 1", "3 0 1", "1 1 1", "1 0 1",
+     * records would result in us generating each of the certificate and public
+     * key DER forms twice, but more typically we'd just see multiple "3 1 1"
+     * or multiple "3 0 1" records.
+     *
+     * As soon as we find a match at any given depth, we stop, because either
+     * we've matched a DANE-?? record and the peer is authenticated, or, after
+     * exhausting all DANE-?? records, we've matched a PKIX-?? record, which is
+     * sufficient for DANE, and what remains to do is ordinary PKIX validation.
+     */
+    recnum = (dane->umask & mask) ? sk_danetls_record_num(dane->trecs) : 0;
+    for (i = 0; matched == 0 && i < recnum; ++i) {
+        t = sk_danetls_record_value(dane->trecs, i);
+        if ((DANETLS_USAGE_BIT(t->usage) & mask) == 0)
+            continue;
+        if (t->usage != usage) {
+            usage = t->usage;
+
+            /* Reset digest agility for each usage/selector pair */
+            mtype = DANETLS_NONE;
+            ordinal = dane->dctx->mdord[t->mtype];
+        }
+        if (t->selector != selector) {
+            selector = t->selector;
+
+            /* Update per-selector state */
+            OPENSSL_free(i2dbuf);
+            i2dbuf = dane_i2d(cert, selector, &i2dlen);
+            if (i2dbuf == NULL)
+                return -1;
+
+            /* Reset digest agility for each usage/selector pair */
+            mtype = DANETLS_NONE;
+            ordinal = dane->dctx->mdord[t->mtype];
+        } else if (t->mtype != DANETLS_MATCHING_FULL) {
+            /*-
+             * Digest agility:
+             *
+             *     <https://tools.ietf.org/html/rfc7671#section-9>
+             *
+             * For a fixed selector, after processing all records with the
+             * highest mtype ordinal, ignore all mtypes with lower ordinals
+             * other than "Full".
+             */
+            if (dane->dctx->mdord[t->mtype] < ordinal)
+                continue;
+        }
+
+        /*
+         * Each time we hit a (new selector or) mtype, re-compute the relevant
+         * digest, more complex caching is not worth the code space.
+         */
+        if (t->mtype != mtype) {
+            const EVP_MD *md = dane->dctx->mdevp[mtype = t->mtype];
+            cmpbuf = i2dbuf;
+            cmplen = i2dlen;
+
+            if (md != NULL) {
+                cmpbuf = mdbuf;
+                if (!EVP_Digest(i2dbuf, i2dlen, cmpbuf, &cmplen, md, 0)) {
+                    matched = -1;
+                    break;
+                }
+            }
+        }
+
+        /*
+         * Squirrel away the certificate and depth if we have a match.  Any
+         * DANE match is dispositive, but with PKIX we still need to build a
+         * full chain.
+         */
+        if (cmplen == t->dlen &&
+            memcmp(cmpbuf, t->data, cmplen) == 0) {
+            if (DANETLS_USAGE_BIT(usage) & DANETLS_DANE_MASK)
+                matched = 1;
+            if (matched || dane->mdpth < 0) {
+                dane->mdpth = depth;
+                dane->mtlsa = t;
+                OPENSSL_free(dane->mcert);
+                dane->mcert = cert;
+                X509_up_ref(cert);
+            }
+            break;
+        }
+    }
+
+    /* Clear the one-element DER cache */
+    OPENSSL_free(i2dbuf);
+    return matched;
+}
+
+static int check_dane_issuer(X509_STORE_CTX *ctx, int depth)
+{
+    SSL_DANE *dane = ctx->dane;
+    int matched = 0;
+    X509 *cert;
+
+    if (!DANETLS_HAS_TA(dane) || depth == 0)
+        return  X509_TRUST_UNTRUSTED;
+
+    /*
+     * Record any DANE trust-anchor matches, for the first depth to test, if
+     * there's one at that depth. (This'll be false for length 1 chains looking
+     * for an exact match for the leaf certificate).
+     */
+    cert = sk_X509_value(ctx->chain, depth);
+    if (cert != NULL && (matched = dane_match(ctx, cert, depth)) < 0)
+        return  X509_TRUST_REJECTED;
+    if (matched > 0) {
+        ctx->num_untrusted = depth - 1;
+        return  X509_TRUST_TRUSTED;
+    }
+
+    return  X509_TRUST_UNTRUSTED;
+}
+
+static int check_dane_pkeys(X509_STORE_CTX *ctx)
+{
+    SSL_DANE *dane = ctx->dane;
+    danetls_record *t;
+    int num = ctx->num_untrusted;
+    X509 *cert = sk_X509_value(ctx->chain, num - 1);
+    int recnum = sk_danetls_record_num(dane->trecs);
+    int i;
+
+    for (i = 0; i < recnum; ++i) {
+        t = sk_danetls_record_value(dane->trecs, i);
+        if (t->usage != DANETLS_USAGE_DANE_TA ||
+            t->selector != DANETLS_SELECTOR_SPKI ||
+            t->mtype != DANETLS_MATCHING_FULL ||
+            X509_verify(cert, t->spki) <= 0)
+            continue;
+
+        /* Clear any PKIX-?? matches that failed to extend to a full chain */
+        X509_free(dane->mcert);
+        dane->mcert = NULL;
+
+        /* Record match via a bare TA public key */
+        ctx->bare_ta_signed = 1;
+        dane->mdpth = num - 1;
+        dane->mtlsa = t;
+
+        /* Prune any excess chain certificates */
+        num = sk_X509_num(ctx->chain);
+        for (; num > ctx->num_untrusted; --num)
+            X509_free(sk_X509_pop(ctx->chain));
+
+        return X509_TRUST_TRUSTED;
+    }
+
+    return X509_TRUST_UNTRUSTED;
+}
+
+static void dane_reset(SSL_DANE *dane)
+{
+    /*
+     * Reset state to verify another chain, or clear after failure.
+     */
+    X509_free(dane->mcert);
+    dane->mcert = NULL;
+    dane->mtlsa = NULL;
+    dane->mdpth = -1;
+    dane->pdpth = -1;
+}
+
+static int check_leaf_suiteb(X509_STORE_CTX *ctx, X509 *cert)
+{
+    int err = X509_chain_check_suiteb(NULL, cert, NULL, ctx->param->flags);
+
+    if (err == X509_V_OK)
+        return 1;
+    return verify_cb_cert(ctx, cert, 0, err);
+}
+
+static int dane_verify(X509_STORE_CTX *ctx)
+{
+    X509 *cert = ctx->cert;
+    SSL_DANE *dane = ctx->dane;
+    int matched;
+    int done;
+
+    dane_reset(dane);
+
+    /*-
+     * When testing the leaf certificate, if we match a DANE-EE(3) record,
+     * dane_match() returns 1 and we're done.  If however we match a PKIX-EE(1)
+     * record, the match depth and matching TLSA record are recorded, but the
+     * return value is 0, because we still need to find a PKIX trust-anchor.
+     * Therefore, when DANE authentication is enabled (required), we're done
+     * if:
+     *   + matched < 0, internal error.
+     *   + matched == 1, we matched a DANE-EE(3) record
+     *   + matched == 0, mdepth < 0 (no PKIX-EE match) and there are no
+     *     DANE-TA(2) or PKIX-TA(0) to test.
+     */
+    matched = dane_match(ctx, ctx->cert, 0);
+    done = matched != 0 || (!DANETLS_HAS_TA(dane) && dane->mdpth < 0);
+
+    if (done)
+        X509_get_pubkey_parameters(NULL, ctx->chain);
+
+    if (matched > 0) {
+        /* Callback invoked as needed */
+        if (!check_leaf_suiteb(ctx, cert))
+            return 0;
+        /* Callback invoked as needed */
+        if ((dane->flags & DANE_FLAG_NO_DANE_EE_NAMECHECKS) == 0 &&
+            !check_id(ctx))
+            return 0;
+        /* Bypass internal_verify(), issue depth 0 success callback */
+        ctx->error_depth = 0;
+        ctx->current_cert = cert;
+        return ctx->verify_cb(1, ctx);
+    }
+
+    if (matched < 0) {
+        ctx->error_depth = 0;
+        ctx->current_cert = cert;
+        ctx->error = X509_V_ERR_OUT_OF_MEM;
+        return -1;
+    }
+
+    if (done) {
+        /* Fail early, TA-based success is not possible */
+        if (!check_leaf_suiteb(ctx, cert))
+            return 0;
+        return verify_cb_cert(ctx, cert, 0, X509_V_ERR_DANE_NO_MATCH);
+    }
+
+    /*
+     * Chain verification for usages 0/1/2.  TLSA record matching of depth > 0
+     * certificates happens in-line with building the rest of the chain.
+     */
+    return verify_chain(ctx);
+}
+
+/* Get issuer, without duplicate suppression */
+static int get_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *cert)
+{
+    STACK_OF(X509) *saved_chain = ctx->chain;
+    int ok;
+
+    ctx->chain = NULL;
+    ok = ctx->get_issuer(issuer, ctx, cert);
+    ctx->chain = saved_chain;
+
+    return ok;
+}
+
+static int build_chain(X509_STORE_CTX *ctx)
+{
+    SSL_DANE *dane = ctx->dane;
+    int num = sk_X509_num(ctx->chain);
+    X509 *cert = sk_X509_value(ctx->chain, num - 1);
+    int ss = cert_self_signed(cert);
+    STACK_OF(X509) *sktmp = NULL;
+    unsigned int search;
+    int may_trusted = 0;
+    int may_alternate = 0;
+    int trust = X509_TRUST_UNTRUSTED;
+    int alt_untrusted = 0;
+    int depth;
+    int ok = 0;
+    int i;
+
+    /* Our chain starts with a single untrusted element. */
+    OPENSSL_assert(num == 1 && ctx->num_untrusted == num);
+
+#define S_DOUNTRUSTED      (1 << 0)     /* Search untrusted chain */
+#define S_DOTRUSTED        (1 << 1)     /* Search trusted store */
+#define S_DOALTERNATE      (1 << 2)     /* Retry with pruned alternate chain */
+    /*
+     * Set up search policy, untrusted if possible, trusted-first if enabled.
+     * If we're doing DANE and not doing PKIX-TA/PKIX-EE, we never look in the
+     * trust_store, otherwise we might look there first.  If not trusted-first,
+     * and alternate chains are not disabled, try building an alternate chain
+     * if no luck with untrusted first.
+     */
+    search = (ctx->untrusted != NULL) ? S_DOUNTRUSTED : 0;
+    if (DANETLS_HAS_PKIX(dane) || !DANETLS_HAS_DANE(dane)) {
+        if (search == 0 || ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
+            search |= S_DOTRUSTED;
+        else if (!(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS))
+            may_alternate = 1;
+        may_trusted = 1;
+    }
+
+    /*
+     * Shallow-copy the stack of untrusted certificates (with TLS, this is
+     * typically the content of the peer's certificate message) so can make
+     * multiple passes over it, while free to remove elements as we go.
+     */
+    if (ctx->untrusted && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) {
+        X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE);
+        ctx->error = X509_V_ERR_OUT_OF_MEM;
+        return 0;
+    }
+
+    /*
+     * If we got any "DANE-TA(2) Cert(0) Full(0)" trust-anchors from DNS, add
+     * them to our working copy of the untrusted certificate stack.  Since the
+     * caller of X509_STORE_CTX_init() may have provided only a leaf cert with
+     * no corresponding stack of untrusted certificates, we may need to create
+     * an empty stack first.  [ At present only the ssl library provides DANE
+     * support, and ssl_verify_cert_chain() always provides a non-null stack
+     * containing at least the leaf certificate, but we must be prepared for
+     * this to change. ]
+     */
+    if (DANETLS_ENABLED(dane) && dane->certs != NULL) {
+        if (sktmp == NULL && (sktmp = sk_X509_new_null()) == NULL) {
+            X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE);
+            ctx->error = X509_V_ERR_OUT_OF_MEM;
+            return 0;
+        }
+        for (i = 0; i < sk_X509_num(dane->certs); ++i) {
+            if (!sk_X509_push(sktmp, sk_X509_value(dane->certs, i))) {
+                sk_X509_free(sktmp);
+                X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE);
+                ctx->error = X509_V_ERR_OUT_OF_MEM;
+                return 0;
+            }
+        }
+    }
+
+    /*
+     * Still absurdly large, but arithmetically safe, a lower hard upper bound
+     * might be reasonable.
+     */
+    if (ctx->param->depth > INT_MAX/2)
+        ctx->param->depth = INT_MAX/2;
+
+    /*
+     * Try to Extend the chain until we reach an ultimately trusted issuer.
+     * Build chains up to one longer the limit, later fail if we hit the limit,
+     * with an X509_V_ERR_CERT_CHAIN_TOO_LONG error code.
+     */
+    depth = ctx->param->depth + 1;
+
+    while (search != 0) {
+        X509 *x;
+        X509 *xtmp = NULL;
+
+        /*
+         * Look in the trust store if enabled for first lookup, or we've run
+         * out of untrusted issuers and search here is not disabled.  When we
+         * reach the depth limit, we stop extending the chain, if by that point
+         * we've not found a trust-anchor, any trusted chain would be too long.
+         *
+         * The error reported to the application verify callback is at the
+         * maximal valid depth with the current certificate equal to the last
+         * not ultimately-trusted issuer.  For example, with verify_depth = 0,
+         * the callback will report errors at depth=1 when the immediate issuer
+         * of the leaf certificate is not a trust anchor.  No attempt will be
+         * made to locate an issuer for that certificate, since such a chain
+         * would be a-priori too long.
+         */
+        if ((search & S_DOTRUSTED) != 0) {
+            i = num = sk_X509_num(ctx->chain);
+            if ((search & S_DOALTERNATE) != 0) {
+                /*
+                 * As high up the chain as we can, look for an alternative
+                 * trusted issuer of an untrusted certificate that currently
+                 * has an untrusted issuer.  We use the alt_untrusted variable
+                 * to track how far up the chain we find the first match.  It
+                 * is only if and when we find a match, that we prune the chain
+                 * and reset ctx->num_untrusted to the reduced count of
+                 * untrusted certificates.  While we're searching for such a
+                 * match (which may never be found), it is neither safe nor
+                 * wise to preemptively modify either the chain or
+                 * ctx->num_untrusted.
+                 *
+                 * Note, like ctx->num_untrusted, alt_untrusted is a count of
+                 * untrusted certificates, not a "depth".
+                 */
+                i = alt_untrusted;
+            }
+            x = sk_X509_value(ctx->chain, i-1);
+
+            ok = (depth < num) ? 0 : get_issuer(&xtmp, ctx, x);
+
+            if (ok < 0) {
+                trust = X509_TRUST_REJECTED;
+                ctx->error = X509_V_ERR_STORE_LOOKUP;
+                search = 0;
+                continue;
+            }
+
+            if (ok > 0) {
+                /*
+                 * Alternative trusted issuer for a mid-chain untrusted cert?
+                 * Pop the untrusted cert's successors and retry.  We might now
+                 * be able to complete a valid chain via the trust store.  Note
+                 * that despite the current trust-store match we might still
+                 * fail complete the chain to a suitable trust-anchor, in which
+                 * case we may prune some more untrusted certificates and try
+                 * again.  Thus the S_DOALTERNATE bit may yet be turned on
+                 * again with an even shorter untrusted chain!
+                 *
+                 * If in the process we threw away our matching PKIX-TA trust
+                 * anchor, reset DANE trust.  We might find a suitable trusted
+                 * certificate among the ones from the trust store.
+                 */
+                if ((search & S_DOALTERNATE) != 0) {
+                    OPENSSL_assert(num > i && i > 0 && ss == 0);
+                    search &= ~S_DOALTERNATE;
+                    for (; num > i; --num)
+                        X509_free(sk_X509_pop(ctx->chain));
+                    ctx->num_untrusted = num;
+
+                    if (DANETLS_ENABLED(dane) &&
+                        dane->mdpth >= ctx->num_untrusted) {
+                        dane->mdpth = -1;
+                        X509_free(dane->mcert);
+                        dane->mcert = NULL;
+                    }
+                    if (DANETLS_ENABLED(dane) &&
+                        dane->pdpth >= ctx->num_untrusted)
+                        dane->pdpth = -1;
+                }
+
+                /*
+                 * Self-signed untrusted certificates get replaced by their
+                 * trusted matching issuer.  Otherwise, grow the chain.
+                 */
+                if (ss == 0) {
+                    if (!sk_X509_push(ctx->chain, x = xtmp)) {
+                        X509_free(xtmp);
+                        X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE);
+                        trust = X509_TRUST_REJECTED;
+                        ctx->error = X509_V_ERR_OUT_OF_MEM;
+                        search = 0;
+                        continue;
+                    }
+                    ss = cert_self_signed(x);
+                } else if (num == ctx->num_untrusted) {
+                    /*
+                     * We have a self-signed certificate that has the same
+                     * subject name (and perhaps keyid and/or serial number) as
+                     * a trust-anchor.  We must have an exact match to avoid
+                     * possible impersonation via key substitution etc.
+                     */
+                    if (X509_cmp(x, xtmp) != 0) {
+                        /* Self-signed untrusted mimic. */
+                        X509_free(xtmp);
+                        ok = 0;
+                    } else {
+                        X509_free(x);
+                        ctx->num_untrusted = --num;
+                        (void) sk_X509_set(ctx->chain, num, x = xtmp);
+                    }
+                }
+
+                /*
+                 * We've added a new trusted certificate to the chain, recheck
+                 * trust.  If not done, and not self-signed look deeper.
+                 * Whether or not we're doing "trusted first", we no longer
+                 * look for untrusted certificates from the peer's chain.
+                 *
+                 * At this point ctx->num_trusted and num must reflect the
+                 * correct number of untrusted certificates, since the DANE
+                 * logic in check_trust() depends on distinguishing CAs from
+                 * "the wire" from CAs from the trust store.  In particular, the
+                 * certificate at depth "num" should be the new trusted
+                 * certificate with ctx->num_untrusted <= num.
+                 */
+                if (ok) {
+                    OPENSSL_assert(ctx->num_untrusted <= num);
+                    search &= ~S_DOUNTRUSTED;
+                    switch (trust = check_trust(ctx, num)) {
+                    case X509_TRUST_TRUSTED:
+                    case X509_TRUST_REJECTED:
+                        search = 0;
+                        continue;
+                    }
+                    if (ss == 0)
+                        continue;
+                }
+            }
+
+            /*
+             * No dispositive decision, and either self-signed or no match, if
+             * we were doing untrusted-first, and alt-chains are not disabled,
+             * do that, by repeatedly losing one untrusted element at a time,
+             * and trying to extend the shorted chain.
+             */
+            if ((search & S_DOUNTRUSTED) == 0) {
+                /* Continue search for a trusted issuer of a shorter chain? */
+                if ((search & S_DOALTERNATE) != 0 && --alt_untrusted > 0)
+                    continue;
+                /* Still no luck and no fallbacks left? */
+                if (!may_alternate || (search & S_DOALTERNATE) != 0 ||
+                    ctx->num_untrusted < 2)
+                    break;
+                /* Search for a trusted issuer of a shorter chain */
+                search |= S_DOALTERNATE;
+                alt_untrusted = ctx->num_untrusted - 1;
+                ss = 0;
+            }
+        }
+
+        /*
+         * Extend chain with peer-provided certificates
+         */
+        if ((search & S_DOUNTRUSTED) != 0) {
+            num = sk_X509_num(ctx->chain);
+            OPENSSL_assert(num == ctx->num_untrusted);
+            x = sk_X509_value(ctx->chain, num-1);
+
+            /*
+             * Once we run out of untrusted issuers, we stop looking for more
+             * and start looking only in the trust store if enabled.
+             */
+            xtmp = (ss || depth < num) ? NULL : find_issuer(ctx, sktmp, x);
+            if (xtmp == NULL) {
+                search &= ~S_DOUNTRUSTED;
+                if (may_trusted)
+                    search |= S_DOTRUSTED;
+                continue;
+            }
+
+            /* Drop this issuer from future consideration */
+            (void) sk_X509_delete_ptr(sktmp, xtmp);
+
+            if (!sk_X509_push(ctx->chain, xtmp)) {
+                X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE);
+                trust = X509_TRUST_REJECTED;
+                ctx->error = X509_V_ERR_OUT_OF_MEM;
+                search = 0;
+                continue;
+            }
+
+            X509_up_ref(x = xtmp);
+            ++ctx->num_untrusted;
+            ss = cert_self_signed(xtmp);
+
+            /*
+             * Check for DANE-TA trust of the topmost untrusted certificate.
+             */
+            switch (trust = check_dane_issuer(ctx, ctx->num_untrusted - 1)) {
+            case X509_TRUST_TRUSTED:
+            case X509_TRUST_REJECTED:
+                search = 0;
+                continue;
+            }
+        }
+    }
+    sk_X509_free(sktmp);
+
+    /*
+     * Last chance to make a trusted chain, either bare DANE-TA public-key
+     * signers, or else direct leaf PKIX trust.
+     */
+    num = sk_X509_num(ctx->chain);
+    if (num <= depth) {
+        if (trust == X509_TRUST_UNTRUSTED && DANETLS_HAS_DANE_TA(dane))
+            trust = check_dane_pkeys(ctx);
+        if (trust == X509_TRUST_UNTRUSTED && num == ctx->num_untrusted)
+            trust = check_trust(ctx, num);
+    }
+
+    switch (trust) {
+    case X509_TRUST_TRUSTED:
+        return 1;
+    case X509_TRUST_REJECTED:
+        /* Callback already issued */
+        return 0;
+    case X509_TRUST_UNTRUSTED:
+    default:
+        num = sk_X509_num(ctx->chain);
+        if (num > depth)
+            return verify_cb_cert(ctx, NULL, num-1,
+                                  X509_V_ERR_CERT_CHAIN_TOO_LONG);
+        if (DANETLS_ENABLED(dane) &&
+            (!DANETLS_HAS_PKIX(dane) || dane->pdpth >= 0))
+            return verify_cb_cert(ctx, NULL, num-1, X509_V_ERR_DANE_NO_MATCH);
+        if (ss && sk_X509_num(ctx->chain) == 1)
+            return verify_cb_cert(ctx, NULL, num-1,
+                                  X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT);
+        if (ss)
+            return verify_cb_cert(ctx, NULL, num-1,
+                                  X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN);
+        if (ctx->num_untrusted < num)
+            return verify_cb_cert(ctx, NULL, num-1,
+                                  X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT);
+        return verify_cb_cert(ctx, NULL, num-1,
+                              X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY);
+    }
+}
+
+static const int minbits_table[] = { 80, 112, 128, 192, 256 };
+static const int NUM_AUTH_LEVELS = OSSL_NELEM(minbits_table);
+
+/*
+ * Check whether the public key of ``cert`` meets the security level of
+ * ``ctx``.
+ *
+ * Returns 1 on success, 0 otherwise.
+ */
+static int check_key_level(X509_STORE_CTX *ctx, X509 *cert)
+{
+    EVP_PKEY *pkey = X509_get0_pubkey(cert);
+    int level = ctx->param->auth_level;
+
+    /* Unsupported or malformed keys are not secure */
+    if (pkey == NULL)
+        return 0;
+
+    if (level <= 0)
+        return 1;
+    if (level > NUM_AUTH_LEVELS)
+        level = NUM_AUTH_LEVELS;
+
+    return EVP_PKEY_security_bits(pkey) >= minbits_table[level - 1];
+}
+
+/*
+ * Check whether the signature digest algorithm of ``cert`` meets the security
+ * level of ``ctx``.  Should not be checked for trust anchors (whether
+ * self-signed or otherwise).
+ *
+ * Returns 1 on success, 0 otherwise.
+ */
+static int check_sig_level(X509_STORE_CTX *ctx, X509 *cert)
+{
+    int nid = X509_get_signature_nid(cert);
+    int mdnid = NID_undef;
+    int secbits = -1;
+    int level = ctx->param->auth_level;
+
+    if (level <= 0)
+        return 1;
+    if (level > NUM_AUTH_LEVELS)
+        level = NUM_AUTH_LEVELS;
+
+    /* Lookup signature algorithm digest */
+    if (nid && OBJ_find_sigid_algs(nid, &mdnid, NULL)) {
+        const EVP_MD *md;
+
+        /* Assume 4 bits of collision resistance for each hash octet */
+        if (mdnid != NID_undef && (md = EVP_get_digestbynid(mdnid)) != NULL)
+            secbits = EVP_MD_size(md) * 4;
+    }
+
+    return secbits >= minbits_table[level - 1];
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_vpm.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_vpm.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509_vpm.c	(revision 331)
@@ -0,0 +1,617 @@
+/*
+ * Copyright 2004-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 <stdio.h>
+
+#include "internal/cryptlib.h"
+#include <openssl/crypto.h>
+#include <openssl/lhash.h>
+#include <openssl/buffer.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include "internal/x509_int.h"
+
+#include "x509_lcl.h"
+
+/* X509_VERIFY_PARAM functions */
+
+#define SET_HOST 0
+#define ADD_HOST 1
+
+static char *str_copy(const char *s)
+{
+    return OPENSSL_strdup(s);
+}
+
+static void str_free(char *s)
+{
+    OPENSSL_free(s);
+}
+
+static int int_x509_param_set_hosts(X509_VERIFY_PARAM *vpm, int mode,
+                                    const char *name, size_t namelen)
+{
+    char *copy;
+
+    /*
+     * Refuse names with embedded NUL bytes, except perhaps as final byte.
+     * XXX: Do we need to push an error onto the error stack?
+     */
+    if (namelen == 0 || name == NULL)
+        namelen = name ? strlen(name) : 0;
+    else if (name && memchr(name, '\0', namelen > 1 ? namelen - 1 : namelen))
+        return 0;
+    if (namelen > 0 && name[namelen - 1] == '\0')
+        --namelen;
+
+    if (mode == SET_HOST) {
+        sk_OPENSSL_STRING_pop_free(vpm->hosts, str_free);
+        vpm->hosts = NULL;
+    }
+    if (name == NULL || namelen == 0)
+        return 1;
+
+    copy = OPENSSL_strndup(name, namelen);
+    if (copy == NULL)
+        return 0;
+
+    if (vpm->hosts == NULL &&
+        (vpm->hosts = sk_OPENSSL_STRING_new_null()) == NULL) {
+        OPENSSL_free(copy);
+        return 0;
+    }
+
+    if (!sk_OPENSSL_STRING_push(vpm->hosts, copy)) {
+        OPENSSL_free(copy);
+        if (sk_OPENSSL_STRING_num(vpm->hosts) == 0) {
+            sk_OPENSSL_STRING_free(vpm->hosts);
+            vpm->hosts = NULL;
+        }
+        return 0;
+    }
+
+    return 1;
+}
+
+static void x509_verify_param_zero(X509_VERIFY_PARAM *param)
+{
+    if (!param)
+        return;
+    param->name = NULL;
+    param->purpose = 0;
+    param->trust = X509_TRUST_DEFAULT;
+    /*
+     * param->inh_flags = X509_VP_FLAG_DEFAULT;
+     */
+    param->inh_flags = 0;
+    param->flags = 0;
+    param->depth = -1;
+    param->auth_level = -1; /* -1 means unset, 0 is explicit */
+    sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
+    param->policies = NULL;
+    sk_OPENSSL_STRING_pop_free(param->hosts, str_free);
+    param->hosts = NULL;
+    OPENSSL_free(param->peername);
+    param->peername = NULL;
+    OPENSSL_free(param->email);
+    param->email = NULL;
+    param->emaillen = 0;
+    OPENSSL_free(param->ip);
+    param->ip = NULL;
+    param->iplen = 0;
+}
+
+X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void)
+{
+    X509_VERIFY_PARAM *param;
+
+    param = OPENSSL_zalloc(sizeof(*param));
+    if (param == NULL)
+        return NULL;
+    x509_verify_param_zero(param);
+    return param;
+}
+
+void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param)
+{
+    if (!param)
+        return;
+    x509_verify_param_zero(param);
+    OPENSSL_free(param);
+}
+
+/*-
+ * This function determines how parameters are "inherited" from one structure
+ * to another. There are several different ways this can happen.
+ *
+ * 1. If a child structure needs to have its values initialized from a parent
+ *    they are simply copied across. For example SSL_CTX copied to SSL.
+ * 2. If the structure should take on values only if they are currently unset.
+ *    For example the values in an SSL structure will take appropriate value
+ *    for SSL servers or clients but only if the application has not set new
+ *    ones.
+ *
+ * The "inh_flags" field determines how this function behaves.
+ *
+ * Normally any values which are set in the default are not copied from the
+ * destination and verify flags are ORed together.
+ *
+ * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied
+ * to the destination. Effectively the values in "to" become default values
+ * which will be used only if nothing new is set in "from".
+ *
+ * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether
+ * they are set or not. Flags is still Ored though.
+ *
+ * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead
+ * of ORed.
+ *
+ * If X509_VP_FLAG_LOCKED is set then no values are copied.
+ *
+ * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed
+ * after the next call.
+ */
+
+/* Macro to test if a field should be copied from src to dest */
+
+#define test_x509_verify_param_copy(field, def) \
+        (to_overwrite || \
+                ((src->field != def) && (to_default || (dest->field == def))))
+
+/* Macro to test and copy a field if necessary */
+
+#define x509_verify_param_copy(field, def) \
+        if (test_x509_verify_param_copy(field, def)) \
+                dest->field = src->field
+
+int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
+                              const X509_VERIFY_PARAM *src)
+{
+    unsigned long inh_flags;
+    int to_default, to_overwrite;
+    if (!src)
+        return 1;
+    inh_flags = dest->inh_flags | src->inh_flags;
+
+    if (inh_flags & X509_VP_FLAG_ONCE)
+        dest->inh_flags = 0;
+
+    if (inh_flags & X509_VP_FLAG_LOCKED)
+        return 1;
+
+    if (inh_flags & X509_VP_FLAG_DEFAULT)
+        to_default = 1;
+    else
+        to_default = 0;
+
+    if (inh_flags & X509_VP_FLAG_OVERWRITE)
+        to_overwrite = 1;
+    else
+        to_overwrite = 0;
+
+    x509_verify_param_copy(purpose, 0);
+    x509_verify_param_copy(trust, X509_TRUST_DEFAULT);
+    x509_verify_param_copy(depth, -1);
+    x509_verify_param_copy(auth_level, -1);
+
+    /* If overwrite or check time not set, copy across */
+
+    if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) {
+        dest->check_time = src->check_time;
+        dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME;
+        /* Don't need to copy flag: that is done below */
+    }
+
+    if (inh_flags & X509_VP_FLAG_RESET_FLAGS)
+        dest->flags = 0;
+
+    dest->flags |= src->flags;
+
+    if (test_x509_verify_param_copy(policies, NULL)) {
+        if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies))
+            return 0;
+    }
+
+    /* Copy the host flags if and only if we're copying the host list */
+    if (test_x509_verify_param_copy(hosts, NULL)) {
+        sk_OPENSSL_STRING_pop_free(dest->hosts, str_free);
+        dest->hosts = NULL;
+        if (src->hosts) {
+            dest->hosts =
+                sk_OPENSSL_STRING_deep_copy(src->hosts, str_copy, str_free);
+            if (dest->hosts == NULL)
+                return 0;
+            dest->hostflags = src->hostflags;
+        }
+    }
+
+    if (test_x509_verify_param_copy(email, NULL)) {
+        if (!X509_VERIFY_PARAM_set1_email(dest, src->email, src->emaillen))
+            return 0;
+    }
+
+    if (test_x509_verify_param_copy(ip, NULL)) {
+        if (!X509_VERIFY_PARAM_set1_ip(dest, src->ip, src->iplen))
+            return 0;
+    }
+
+    return 1;
+}
+
+int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
+                           const X509_VERIFY_PARAM *from)
+{
+    unsigned long save_flags = to->inh_flags;
+    int ret;
+    to->inh_flags |= X509_VP_FLAG_DEFAULT;
+    ret = X509_VERIFY_PARAM_inherit(to, from);
+    to->inh_flags = save_flags;
+    return ret;
+}
+
+static int int_x509_param_set1(char **pdest, size_t *pdestlen,
+                               const char *src, size_t srclen)
+{
+    void *tmp;
+    if (src) {
+        if (srclen == 0)
+            srclen = strlen(src);
+
+        tmp = OPENSSL_memdup(src, srclen);
+        if (tmp == NULL)
+            return 0;
+    } else {
+        tmp = NULL;
+        srclen = 0;
+    }
+    OPENSSL_free(*pdest);
+    *pdest = tmp;
+    if (pdestlen != NULL)
+        *pdestlen = srclen;
+    return 1;
+}
+
+int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name)
+{
+    OPENSSL_free(param->name);
+    param->name = OPENSSL_strdup(name);
+    if (param->name)
+        return 1;
+    return 0;
+}
+
+int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags)
+{
+    param->flags |= flags;
+    if (flags & X509_V_FLAG_POLICY_MASK)
+        param->flags |= X509_V_FLAG_POLICY_CHECK;
+    return 1;
+}
+
+int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
+                                  unsigned long flags)
+{
+    param->flags &= ~flags;
+    return 1;
+}
+
+unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param)
+{
+    return param->flags;
+}
+
+uint32_t X509_VERIFY_PARAM_get_inh_flags(const X509_VERIFY_PARAM *param)
+{
+    return param->inh_flags;
+}
+
+int X509_VERIFY_PARAM_set_inh_flags(X509_VERIFY_PARAM *param, uint32_t flags)
+{
+    param->inh_flags = flags;
+    return 1;
+}
+
+int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose)
+{
+    return X509_PURPOSE_set(&param->purpose, purpose);
+}
+
+int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust)
+{
+    return X509_TRUST_set(&param->trust, trust);
+}
+
+void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth)
+{
+    param->depth = depth;
+}
+
+void X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level)
+{
+    param->auth_level = auth_level;
+}
+
+time_t X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param)
+{
+    return param->check_time;
+}
+
+void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t)
+{
+    param->check_time = t;
+    param->flags |= X509_V_FLAG_USE_CHECK_TIME;
+}
+
+int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
+                                  ASN1_OBJECT *policy)
+{
+    if (!param->policies) {
+        param->policies = sk_ASN1_OBJECT_new_null();
+        if (!param->policies)
+            return 0;
+    }
+    if (!sk_ASN1_OBJECT_push(param->policies, policy))
+        return 0;
+    return 1;
+}
+
+int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
+                                    STACK_OF(ASN1_OBJECT) *policies)
+{
+    int i;
+    ASN1_OBJECT *oid, *doid;
+
+    if (!param)
+        return 0;
+    sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
+
+    if (!policies) {
+        param->policies = NULL;
+        return 1;
+    }
+
+    param->policies = sk_ASN1_OBJECT_new_null();
+    if (!param->policies)
+        return 0;
+
+    for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) {
+        oid = sk_ASN1_OBJECT_value(policies, i);
+        doid = OBJ_dup(oid);
+        if (!doid)
+            return 0;
+        if (!sk_ASN1_OBJECT_push(param->policies, doid)) {
+            ASN1_OBJECT_free(doid);
+            return 0;
+        }
+    }
+    param->flags |= X509_V_FLAG_POLICY_CHECK;
+    return 1;
+}
+
+int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
+                                const char *name, size_t namelen)
+{
+    return int_x509_param_set_hosts(param, SET_HOST, name, namelen);
+}
+
+int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
+                                const char *name, size_t namelen)
+{
+    return int_x509_param_set_hosts(param, ADD_HOST, name, namelen);
+}
+
+void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
+                                     unsigned int flags)
+{
+    param->hostflags = flags;
+}
+
+char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param)
+{
+    return param->peername;
+}
+
+/*
+ * Move peername from one param structure to another, freeing any name present
+ * at the target.  If the source is a NULL parameter structure, free and zero
+ * the target peername.
+ */
+void X509_VERIFY_PARAM_move_peername(X509_VERIFY_PARAM *to,
+                                     X509_VERIFY_PARAM *from)
+{
+    char *peername = (from != NULL) ? from->peername : NULL;
+
+    if (to->peername != peername) {
+        OPENSSL_free(to->peername);
+        to->peername = peername;
+    }
+    if (from)
+        from->peername = NULL;
+}
+
+int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
+                                 const char *email, size_t emaillen)
+{
+    return int_x509_param_set1(&param->email, &param->emaillen,
+                               email, emaillen);
+}
+
+int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
+                              const unsigned char *ip, size_t iplen)
+{
+    if (iplen != 0 && iplen != 4 && iplen != 16)
+        return 0;
+    return int_x509_param_set1((char **)&param->ip, &param->iplen,
+                               (char *)ip, iplen);
+}
+
+int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc)
+{
+    unsigned char ipout[16];
+    size_t iplen;
+
+    iplen = (size_t)a2i_ipadd(ipout, ipasc);
+    if (iplen == 0)
+        return 0;
+    return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen);
+}
+
+int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
+{
+    return param->depth;
+}
+
+int X509_VERIFY_PARAM_get_auth_level(const X509_VERIFY_PARAM *param)
+{
+    return param->auth_level;
+}
+
+const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param)
+{
+    return param->name;
+}
+
+#define vpm_empty_id NULL, 0U, NULL, NULL, 0, NULL, 0
+
+/*
+ * Default verify parameters: these are used for various applications and can
+ * be overridden by the user specified table. NB: the 'name' field *must* be
+ * in alphabetical order because it will be searched using OBJ_search.
+ */
+
+static const X509_VERIFY_PARAM default_table[] = {
+    {
+     "default",                 /* X509 default parameters */
+     0,                         /* Check time */
+     0,                         /* internal flags */
+     X509_V_FLAG_TRUSTED_FIRST, /* flags */
+     0,                         /* purpose */
+     0,                         /* trust */
+     100,                       /* depth */
+     -1,                        /* auth_level */
+     NULL,                      /* policies */
+     vpm_empty_id},
+    {
+     "pkcs7",                   /* S/MIME sign parameters */
+     0,                         /* Check time */
+     0,                         /* internal flags */
+     0,                         /* flags */
+     X509_PURPOSE_SMIME_SIGN,   /* purpose */
+     X509_TRUST_EMAIL,          /* trust */
+     -1,                        /* depth */
+     -1,                        /* auth_level */
+     NULL,                      /* policies */
+     vpm_empty_id},
+    {
+     "smime_sign",              /* S/MIME sign parameters */
+     0,                         /* Check time */
+     0,                         /* internal flags */
+     0,                         /* flags */
+     X509_PURPOSE_SMIME_SIGN,   /* purpose */
+     X509_TRUST_EMAIL,          /* trust */
+     -1,                        /* depth */
+     -1,                        /* auth_level */
+     NULL,                      /* policies */
+     vpm_empty_id},
+    {
+     "ssl_client",              /* SSL/TLS client parameters */
+     0,                         /* Check time */
+     0,                         /* internal flags */
+     0,                         /* flags */
+     X509_PURPOSE_SSL_CLIENT,   /* purpose */
+     X509_TRUST_SSL_CLIENT,     /* trust */
+     -1,                        /* depth */
+     -1,                        /* auth_level */
+     NULL,                      /* policies */
+     vpm_empty_id},
+    {
+     "ssl_server",              /* SSL/TLS server parameters */
+     0,                         /* Check time */
+     0,                         /* internal flags */
+     0,                         /* flags */
+     X509_PURPOSE_SSL_SERVER,   /* purpose */
+     X509_TRUST_SSL_SERVER,     /* trust */
+     -1,                        /* depth */
+     -1,                        /* auth_level */
+     NULL,                      /* policies */
+     vpm_empty_id}
+};
+
+static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL;
+
+static int table_cmp(const X509_VERIFY_PARAM *a, const X509_VERIFY_PARAM *b)
+{
+    return strcmp(a->name, b->name);
+}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table);
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table);
+
+static int param_cmp(const X509_VERIFY_PARAM *const *a,
+                     const X509_VERIFY_PARAM *const *b)
+{
+    return strcmp((*a)->name, (*b)->name);
+}
+
+int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param)
+{
+    int idx;
+    X509_VERIFY_PARAM *ptmp;
+    if (param_table == NULL) {
+        param_table = sk_X509_VERIFY_PARAM_new(param_cmp);
+        if (param_table == NULL)
+            return 0;
+    } else {
+        idx = sk_X509_VERIFY_PARAM_find(param_table, param);
+        if (idx != -1) {
+            ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx);
+            X509_VERIFY_PARAM_free(ptmp);
+            (void)sk_X509_VERIFY_PARAM_delete(param_table, idx);
+        }
+    }
+    if (!sk_X509_VERIFY_PARAM_push(param_table, param))
+        return 0;
+    return 1;
+}
+
+int X509_VERIFY_PARAM_get_count(void)
+{
+    int num = OSSL_NELEM(default_table);
+    if (param_table)
+        num += sk_X509_VERIFY_PARAM_num(param_table);
+    return num;
+}
+
+const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id)
+{
+    int num = OSSL_NELEM(default_table);
+    if (id < num)
+        return default_table + id;
+    return sk_X509_VERIFY_PARAM_value(param_table, id - num);
+}
+
+const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name)
+{
+    int idx;
+    X509_VERIFY_PARAM pm;
+
+    pm.name = (char *)name;
+    if (param_table) {
+        idx = sk_X509_VERIFY_PARAM_find(param_table, &pm);
+        if (idx != -1)
+            return sk_X509_VERIFY_PARAM_value(param_table, idx);
+    }
+    return OBJ_bsearch_table(&pm, default_table, OSSL_NELEM(default_table));
+}
+
+void X509_VERIFY_PARAM_table_cleanup(void)
+{
+    sk_X509_VERIFY_PARAM_pop_free(param_table, X509_VERIFY_PARAM_free);
+    param_table = NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509cset.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509cset.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509cset.c	(revision 331)
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2001-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+
+int X509_CRL_set_version(X509_CRL *x, long version)
+{
+    if (x == NULL)
+        return (0);
+    if (x->crl.version == NULL) {
+        if ((x->crl.version = ASN1_INTEGER_new()) == NULL)
+            return (0);
+    }
+    return (ASN1_INTEGER_set(x->crl.version, version));
+}
+
+int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name)
+{
+    if (x == NULL)
+        return (0);
+    return (X509_NAME_set(&x->crl.issuer, name));
+}
+
+int X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm)
+{
+    if (x == NULL)
+        return 0;
+    return x509_set1_time(&x->crl.lastUpdate, tm);
+}
+
+int X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm)
+{
+    if (x == NULL)
+        return 0;
+    return x509_set1_time(&x->crl.nextUpdate, tm);
+}
+
+int X509_CRL_sort(X509_CRL *c)
+{
+    int i;
+    X509_REVOKED *r;
+    /*
+     * sort the data so it will be written in serial number order
+     */
+    sk_X509_REVOKED_sort(c->crl.revoked);
+    for (i = 0; i < sk_X509_REVOKED_num(c->crl.revoked); i++) {
+        r = sk_X509_REVOKED_value(c->crl.revoked, i);
+        r->sequence = i;
+    }
+    c->crl.enc.modified = 1;
+    return 1;
+}
+
+int X509_CRL_up_ref(X509_CRL *crl)
+{
+    int i;
+
+    if (CRYPTO_atomic_add(&crl->references, 1, &i, crl->lock) <= 0)
+        return 0;
+
+    REF_PRINT_COUNT("X509_CRL", crl);
+    REF_ASSERT_ISNT(i < 2);
+    return ((i > 1) ? 1 : 0);
+}
+
+long X509_CRL_get_version(const X509_CRL *crl)
+{
+    return ASN1_INTEGER_get(crl->crl.version);
+}
+
+const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl)
+{
+    return crl->crl.lastUpdate;
+}
+
+const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl)
+{
+    return crl->crl.nextUpdate;
+}
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl)
+{
+    return crl->crl.lastUpdate;
+}
+
+ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl)
+{
+    return crl->crl.nextUpdate;
+}
+#endif
+
+X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl)
+{
+    return crl->crl.issuer;
+}
+
+const STACK_OF(X509_EXTENSION) *X509_CRL_get0_extensions(const X509_CRL *crl)
+{
+    return crl->crl.extensions;
+}
+
+STACK_OF(X509_REVOKED) *X509_CRL_get_REVOKED(X509_CRL *crl)
+{
+    return crl->crl.revoked;
+}
+
+void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig,
+                             const X509_ALGOR **palg)
+{
+    if (psig != NULL)
+        *psig = &crl->signature;
+    if (palg != NULL)
+        *palg = &crl->sig_alg;
+}
+
+int X509_CRL_get_signature_nid(const X509_CRL *crl)
+{
+    return OBJ_obj2nid(crl->sig_alg.algorithm);
+}
+
+const ASN1_TIME *X509_REVOKED_get0_revocationDate(const X509_REVOKED *x)
+{
+    return x->revocationDate;
+}
+
+int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm)
+{
+    ASN1_TIME *in;
+
+    if (x == NULL)
+        return (0);
+    in = x->revocationDate;
+    if (in != tm) {
+        in = ASN1_STRING_dup(tm);
+        if (in != NULL) {
+            ASN1_TIME_free(x->revocationDate);
+            x->revocationDate = in;
+        }
+    }
+    return (in != NULL);
+}
+
+const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *x)
+{
+    return &x->serialNumber;
+}
+
+int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial)
+{
+    ASN1_INTEGER *in;
+
+    if (x == NULL)
+        return (0);
+    in = &x->serialNumber;
+    if (in != serial)
+        return ASN1_STRING_copy(in, serial);
+    return 1;
+}
+
+const STACK_OF(X509_EXTENSION) *X509_REVOKED_get0_extensions(const X509_REVOKED *r)
+{
+    return r->extensions;
+}
+
+int i2d_re_X509_CRL_tbs(X509_CRL *crl, unsigned char **pp)
+{
+    crl->crl.enc.modified = 1;
+    return i2d_X509_CRL_INFO(&crl->crl, pp);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509name.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509name.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509name.c	(revision 331)
@@ -0,0 +1,358 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/stack.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+
+int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len)
+{
+    ASN1_OBJECT *obj;
+
+    obj = OBJ_nid2obj(nid);
+    if (obj == NULL)
+        return (-1);
+    return (X509_NAME_get_text_by_OBJ(name, obj, buf, len));
+}
+
+int X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, char *buf,
+                              int len)
+{
+    int i;
+    const ASN1_STRING *data;
+
+    i = X509_NAME_get_index_by_OBJ(name, obj, -1);
+    if (i < 0)
+        return (-1);
+    data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i));
+    i = (data->length > (len - 1)) ? (len - 1) : data->length;
+    if (buf == NULL)
+        return (data->length);
+    memcpy(buf, data->data, i);
+    buf[i] = '\0';
+    return (i);
+}
+
+int X509_NAME_entry_count(const X509_NAME *name)
+{
+    if (name == NULL)
+        return (0);
+    return (sk_X509_NAME_ENTRY_num(name->entries));
+}
+
+int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos)
+{
+    ASN1_OBJECT *obj;
+
+    obj = OBJ_nid2obj(nid);
+    if (obj == NULL)
+        return (-2);
+    return (X509_NAME_get_index_by_OBJ(name, obj, lastpos));
+}
+
+/* NOTE: you should be passing -1, not 0 as lastpos */
+int X509_NAME_get_index_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int lastpos)
+{
+    int n;
+    X509_NAME_ENTRY *ne;
+    STACK_OF(X509_NAME_ENTRY) *sk;
+
+    if (name == NULL)
+        return (-1);
+    if (lastpos < 0)
+        lastpos = -1;
+    sk = name->entries;
+    n = sk_X509_NAME_ENTRY_num(sk);
+    for (lastpos++; lastpos < n; lastpos++) {
+        ne = sk_X509_NAME_ENTRY_value(sk, lastpos);
+        if (OBJ_cmp(ne->object, obj) == 0)
+            return (lastpos);
+    }
+    return (-1);
+}
+
+X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc)
+{
+    if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc
+        || loc < 0)
+        return (NULL);
+    else
+        return (sk_X509_NAME_ENTRY_value(name->entries, loc));
+}
+
+X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc)
+{
+    X509_NAME_ENTRY *ret;
+    int i, n, set_prev, set_next;
+    STACK_OF(X509_NAME_ENTRY) *sk;
+
+    if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc
+        || loc < 0)
+        return (NULL);
+    sk = name->entries;
+    ret = sk_X509_NAME_ENTRY_delete(sk, loc);
+    n = sk_X509_NAME_ENTRY_num(sk);
+    name->modified = 1;
+    if (loc == n)
+        return (ret);
+
+    /* else we need to fixup the set field */
+    if (loc != 0)
+        set_prev = (sk_X509_NAME_ENTRY_value(sk, loc - 1))->set;
+    else
+        set_prev = ret->set - 1;
+    set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set;
+
+    /*-
+     * set_prev is the previous set
+     * set is the current set
+     * set_next is the following
+     * prev  1 1    1 1     1 1     1 1
+     * set   1      1       2       2
+     * next  1 1    2 2     2 2     3 2
+     * so basically only if prev and next differ by 2, then
+     * re-number down by 1
+     */
+    if (set_prev + 1 < set_next)
+        for (i = loc; i < n; i++)
+            sk_X509_NAME_ENTRY_value(sk, i)->set--;
+    return (ret);
+}
+
+int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int type,
+                               const unsigned char *bytes, int len, int loc,
+                               int set)
+{
+    X509_NAME_ENTRY *ne;
+    int ret;
+    ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len);
+    if (!ne)
+        return 0;
+    ret = X509_NAME_add_entry(name, ne, loc, set);
+    X509_NAME_ENTRY_free(ne);
+    return ret;
+}
+
+int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
+                               const unsigned char *bytes, int len, int loc,
+                               int set)
+{
+    X509_NAME_ENTRY *ne;
+    int ret;
+    ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len);
+    if (!ne)
+        return 0;
+    ret = X509_NAME_add_entry(name, ne, loc, set);
+    X509_NAME_ENTRY_free(ne);
+    return ret;
+}
+
+int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
+                               const unsigned char *bytes, int len, int loc,
+                               int set)
+{
+    X509_NAME_ENTRY *ne;
+    int ret;
+    ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len);
+    if (!ne)
+        return 0;
+    ret = X509_NAME_add_entry(name, ne, loc, set);
+    X509_NAME_ENTRY_free(ne);
+    return ret;
+}
+
+/*
+ * if set is -1, append to previous set, 0 'a new one', and 1, prepend to the
+ * guy we are about to stomp on.
+ */
+int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne, int loc,
+                        int set)
+{
+    X509_NAME_ENTRY *new_name = NULL;
+    int n, i, inc;
+    STACK_OF(X509_NAME_ENTRY) *sk;
+
+    if (name == NULL)
+        return (0);
+    sk = name->entries;
+    n = sk_X509_NAME_ENTRY_num(sk);
+    if (loc > n)
+        loc = n;
+    else if (loc < 0)
+        loc = n;
+
+    name->modified = 1;
+
+    if (set == -1) {
+        if (loc == 0) {
+            set = 0;
+            inc = 1;
+        } else {
+            set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set;
+            inc = 0;
+        }
+    } else {                    /* if (set >= 0) */
+
+        if (loc >= n) {
+            if (loc != 0)
+                set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1;
+            else
+                set = 0;
+        } else
+            set = sk_X509_NAME_ENTRY_value(sk, loc)->set;
+        inc = (set == 0) ? 1 : 0;
+    }
+
+    /*
+     * X509_NAME_ENTRY_dup is ASN1 generated code, that can't be easily
+     * const'ified; harmless cast as dup() don't modify its input.
+     */
+    if ((new_name = X509_NAME_ENTRY_dup((X509_NAME_ENTRY *)ne)) == NULL)
+        goto err;
+    new_name->set = set;
+    if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) {
+        X509err(X509_F_X509_NAME_ADD_ENTRY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if (inc) {
+        n = sk_X509_NAME_ENTRY_num(sk);
+        for (i = loc + 1; i < n; i++)
+            sk_X509_NAME_ENTRY_value(sk, i - 1)->set += 1;
+    }
+    return (1);
+ err:
+    X509_NAME_ENTRY_free(new_name);
+    return (0);
+}
+
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
+                                               const char *field, int type,
+                                               const unsigned char *bytes,
+                                               int len)
+{
+    ASN1_OBJECT *obj;
+    X509_NAME_ENTRY *nentry;
+
+    obj = OBJ_txt2obj(field, 0);
+    if (obj == NULL) {
+        X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT,
+                X509_R_INVALID_FIELD_NAME);
+        ERR_add_error_data(2, "name=", field);
+        return (NULL);
+    }
+    nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
+    ASN1_OBJECT_free(obj);
+    return nentry;
+}
+
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
+                                               int type,
+                                               const unsigned char *bytes,
+                                               int len)
+{
+    ASN1_OBJECT *obj;
+    X509_NAME_ENTRY *nentry;
+
+    obj = OBJ_nid2obj(nid);
+    if (obj == NULL) {
+        X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_NID, X509_R_UNKNOWN_NID);
+        return (NULL);
+    }
+    nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len);
+    ASN1_OBJECT_free(obj);
+    return nentry;
+}
+
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
+                                               const ASN1_OBJECT *obj, int type,
+                                               const unsigned char *bytes,
+                                               int len)
+{
+    X509_NAME_ENTRY *ret;
+
+    if ((ne == NULL) || (*ne == NULL)) {
+        if ((ret = X509_NAME_ENTRY_new()) == NULL)
+            return (NULL);
+    } else
+        ret = *ne;
+
+    if (!X509_NAME_ENTRY_set_object(ret, obj))
+        goto err;
+    if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len))
+        goto err;
+
+    if ((ne != NULL) && (*ne == NULL))
+        *ne = ret;
+    return (ret);
+ err:
+    if ((ne == NULL) || (ret != *ne))
+        X509_NAME_ENTRY_free(ret);
+    return (NULL);
+}
+
+int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj)
+{
+    if ((ne == NULL) || (obj == NULL)) {
+        X509err(X509_F_X509_NAME_ENTRY_SET_OBJECT,
+                ERR_R_PASSED_NULL_PARAMETER);
+        return (0);
+    }
+    ASN1_OBJECT_free(ne->object);
+    ne->object = OBJ_dup(obj);
+    return ((ne->object == NULL) ? 0 : 1);
+}
+
+int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
+                             const unsigned char *bytes, int len)
+{
+    int i;
+
+    if ((ne == NULL) || ((bytes == NULL) && (len != 0)))
+        return (0);
+    if ((type > 0) && (type & MBSTRING_FLAG))
+        return ASN1_STRING_set_by_NID(&ne->value, bytes,
+                                      len, type,
+                                      OBJ_obj2nid(ne->object)) ? 1 : 0;
+    if (len < 0)
+        len = strlen((const char *)bytes);
+    i = ASN1_STRING_set(ne->value, bytes, len);
+    if (!i)
+        return (0);
+    if (type != V_ASN1_UNDEF) {
+        if (type == V_ASN1_APP_CHOOSE)
+            ne->value->type = ASN1_PRINTABLE_type(bytes, len);
+        else
+            ne->value->type = type;
+    }
+    return (1);
+}
+
+ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne)
+{
+    if (ne == NULL)
+        return (NULL);
+    return (ne->object);
+}
+
+ASN1_STRING *X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne)
+{
+    if (ne == NULL)
+        return (NULL);
+    return (ne->value);
+}
+
+int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne)
+{
+    return ne->set;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509rset.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509rset.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509rset.c	(revision 331)
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+
+int X509_REQ_set_version(X509_REQ *x, long version)
+{
+    if (x == NULL)
+        return (0);
+    x->req_info.enc.modified = 1;
+    return (ASN1_INTEGER_set(x->req_info.version, version));
+}
+
+int X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name)
+{
+    if (x == NULL)
+        return (0);
+    x->req_info.enc.modified = 1;
+    return (X509_NAME_set(&x->req_info.subject, name));
+}
+
+int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey)
+{
+    if (x == NULL)
+        return (0);
+    x->req_info.enc.modified = 1;
+    return (X509_PUBKEY_set(&x->req_info.pubkey, pkey));
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509spki.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509spki.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509spki.c	(revision 331)
@@ -0,0 +1,75 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509.h>
+
+int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey)
+{
+    if ((x == NULL) || (x->spkac == NULL))
+        return (0);
+    return (X509_PUBKEY_set(&(x->spkac->pubkey), pkey));
+}
+
+EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x)
+{
+    if ((x == NULL) || (x->spkac == NULL))
+        return (NULL);
+    return (X509_PUBKEY_get(x->spkac->pubkey));
+}
+
+/* Load a Netscape SPKI from a base64 encoded string */
+
+NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len)
+{
+    unsigned char *spki_der;
+    const unsigned char *p;
+    int spki_len;
+    NETSCAPE_SPKI *spki;
+    if (len <= 0)
+        len = strlen(str);
+    if ((spki_der = OPENSSL_malloc(len + 1)) == NULL) {
+        X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    spki_len = EVP_DecodeBlock(spki_der, (const unsigned char *)str, len);
+    if (spki_len < 0) {
+        X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, X509_R_BASE64_DECODE_ERROR);
+        OPENSSL_free(spki_der);
+        return NULL;
+    }
+    p = spki_der;
+    spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len);
+    OPENSSL_free(spki_der);
+    return spki;
+}
+
+/* Generate a base64 encoded string from an SPKI */
+
+char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki)
+{
+    unsigned char *der_spki, *p;
+    char *b64_str;
+    int der_len;
+    der_len = i2d_NETSCAPE_SPKI(spki, NULL);
+    der_spki = OPENSSL_malloc(der_len);
+    b64_str = OPENSSL_malloc(der_len * 2);
+    if (der_spki == NULL || b64_str == NULL) {
+        X509err(X509_F_NETSCAPE_SPKI_B64_ENCODE, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(der_spki);
+        OPENSSL_free(b64_str);
+        return NULL;
+    }
+    p = der_spki;
+    i2d_NETSCAPE_SPKI(spki, &p);
+    EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len);
+    OPENSSL_free(der_spki);
+    return b64_str;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509type.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509type.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x509type.c	(revision 331)
@@ -0,0 +1,77 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+
+int X509_certificate_type(const X509 *x, const EVP_PKEY *pkey)
+{
+    const EVP_PKEY *pk;
+    int ret = 0, i;
+
+    if (x == NULL)
+        return (0);
+
+    if (pkey == NULL)
+        pk = X509_get0_pubkey(x);
+    else
+        pk = pkey;
+
+    if (pk == NULL)
+        return (0);
+
+    switch (EVP_PKEY_id(pk)) {
+    case EVP_PKEY_RSA:
+        ret = EVP_PK_RSA | EVP_PKT_SIGN;
+/*              if (!sign only extension) */
+        ret |= EVP_PKT_ENC;
+        break;
+    case EVP_PKEY_DSA:
+        ret = EVP_PK_DSA | EVP_PKT_SIGN;
+        break;
+    case EVP_PKEY_EC:
+        ret = EVP_PK_EC | EVP_PKT_SIGN | EVP_PKT_EXCH;
+        break;
+    case EVP_PKEY_DH:
+        ret = EVP_PK_DH | EVP_PKT_EXCH;
+        break;
+    case NID_id_GostR3410_2001:
+    case NID_id_GostR3410_2012_256:
+    case NID_id_GostR3410_2012_512:
+        ret = EVP_PKT_EXCH | EVP_PKT_SIGN;
+        break;
+    default:
+        break;
+    }
+
+    i = X509_get_signature_nid(x);
+    if (i && OBJ_find_sigid_algs(i, NULL, &i)) {
+
+        switch (i) {
+        case NID_rsaEncryption:
+        case NID_rsa:
+            ret |= EVP_PKS_RSA;
+            break;
+        case NID_dsa:
+        case NID_dsa_2:
+            ret |= EVP_PKS_DSA;
+            break;
+        case NID_X9_62_id_ecPublicKey:
+            ret |= EVP_PKS_EC;
+            break;
+        default:
+            break;
+        }
+    }
+
+    return (ret);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_all.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_all.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_all.c	(revision 331)
@@ -0,0 +1,526 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/stack.h>
+#include "internal/cryptlib.h"
+#include <openssl/buffer.h>
+#include <openssl/asn1.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+#include <openssl/ocsp.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/x509v3.h>
+
+int X509_verify(X509 *a, EVP_PKEY *r)
+{
+    if (X509_ALGOR_cmp(&a->sig_alg, &a->cert_info.signature))
+        return 0;
+    return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), &a->sig_alg,
+                             &a->signature, &a->cert_info, r));
+}
+
+int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r)
+{
+    return (ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO),
+                             &a->sig_alg, a->signature, &a->req_info, r));
+}
+
+int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r)
+{
+    return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC),
+                             &a->sig_algor, a->signature, a->spkac, r));
+}
+
+int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
+{
+    x->cert_info.enc.modified = 1;
+    return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), &x->cert_info.signature,
+                           &x->sig_alg, &x->signature, &x->cert_info, pkey,
+                           md));
+}
+
+int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx)
+{
+    x->cert_info.enc.modified = 1;
+    return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF),
+                              &x->cert_info.signature,
+                              &x->sig_alg, &x->signature, &x->cert_info, ctx);
+}
+
+#ifndef OPENSSL_NO_OCSP
+int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert)
+{
+    return OCSP_REQ_CTX_nbio_d2i(rctx,
+                                 (ASN1_VALUE **)pcert, ASN1_ITEM_rptr(X509));
+}
+#endif
+
+int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md)
+{
+    return (ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), &x->sig_alg, NULL,
+                           x->signature, &x->req_info, pkey, md));
+}
+
+int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx)
+{
+    return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO),
+                              &x->sig_alg, NULL, x->signature, &x->req_info,
+                              ctx);
+}
+
+int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md)
+{
+    x->crl.enc.modified = 1;
+    return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), &x->crl.sig_alg,
+                           &x->sig_alg, &x->signature, &x->crl, pkey, md));
+}
+
+int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx)
+{
+    x->crl.enc.modified = 1;
+    return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO),
+                              &x->crl.sig_alg, &x->sig_alg, &x->signature,
+                              &x->crl, ctx);
+}
+
+#ifndef OPENSSL_NO_OCSP
+int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl)
+{
+    return OCSP_REQ_CTX_nbio_d2i(rctx,
+                                 (ASN1_VALUE **)pcrl,
+                                 ASN1_ITEM_rptr(X509_CRL));
+}
+#endif
+
+int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md)
+{
+    return (ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), &x->sig_algor, NULL,
+                           x->signature, x->spkac, pkey, md));
+}
+
+#ifndef OPENSSL_NO_STDIO
+X509 *d2i_X509_fp(FILE *fp, X509 **x509)
+{
+    return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509);
+}
+
+int i2d_X509_fp(FILE *fp, X509 *x509)
+{
+    return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509), fp, x509);
+}
+#endif
+
+X509 *d2i_X509_bio(BIO *bp, X509 **x509)
+{
+    return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509), bp, x509);
+}
+
+int i2d_X509_bio(BIO *bp, X509 *x509)
+{
+    return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509);
+}
+
+#ifndef OPENSSL_NO_STDIO
+X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl)
+{
+    return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
+}
+
+int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl)
+{
+    return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
+}
+#endif
+
+X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl)
+{
+    return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
+}
+
+int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl)
+{
+    return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
+}
+
+#ifndef OPENSSL_NO_STDIO
+PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7)
+{
+    return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7);
+}
+
+int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7)
+{
+    return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS7), fp, p7);
+}
+#endif
+
+PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7)
+{
+    return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bp, p7);
+}
+
+int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7)
+{
+    return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS7), bp, p7);
+}
+
+#ifndef OPENSSL_NO_STDIO
+X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req)
+{
+    return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
+}
+
+int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req)
+{
+    return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
+}
+#endif
+
+X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req)
+{
+    return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
+}
+
+int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req)
+{
+    return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
+}
+
+#ifndef OPENSSL_NO_RSA
+
+# ifndef OPENSSL_NO_STDIO
+RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa)
+{
+    return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa);
+}
+
+int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa)
+{
+    return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa);
+}
+
+RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa)
+{
+    return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa);
+}
+
+RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa)
+{
+    return ASN1_d2i_fp((void *(*)(void))
+                       RSA_new, (D2I_OF(void)) d2i_RSA_PUBKEY, fp,
+                       (void **)rsa);
+}
+
+int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa)
+{
+    return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa);
+}
+
+int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa)
+{
+    return ASN1_i2d_fp((I2D_OF(void))i2d_RSA_PUBKEY, fp, rsa);
+}
+# endif
+
+RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa)
+{
+    return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
+}
+
+int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa)
+{
+    return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
+}
+
+RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa)
+{
+    return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);
+}
+
+RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa)
+{
+    return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSA_PUBKEY, bp, rsa);
+}
+
+int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa)
+{
+    return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);
+}
+
+int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa)
+{
+    return ASN1_i2d_bio_of(RSA, i2d_RSA_PUBKEY, bp, rsa);
+}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+# ifndef OPENSSL_NO_STDIO
+DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa)
+{
+    return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSAPrivateKey, fp, dsa);
+}
+
+int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa)
+{
+    return ASN1_i2d_fp_of_const(DSA, i2d_DSAPrivateKey, fp, dsa);
+}
+
+DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa)
+{
+    return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSA_PUBKEY, fp, dsa);
+}
+
+int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa)
+{
+    return ASN1_i2d_fp_of(DSA, i2d_DSA_PUBKEY, fp, dsa);
+}
+# endif
+
+DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa)
+{
+    return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSAPrivateKey, bp, dsa);
+}
+
+int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa)
+{
+    return ASN1_i2d_bio_of_const(DSA, i2d_DSAPrivateKey, bp, dsa);
+}
+
+DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa)
+{
+    return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSA_PUBKEY, bp, dsa);
+}
+
+int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa)
+{
+    return ASN1_i2d_bio_of(DSA, i2d_DSA_PUBKEY, bp, dsa);
+}
+
+#endif
+
+#ifndef OPENSSL_NO_EC
+# ifndef OPENSSL_NO_STDIO
+EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey)
+{
+    return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, fp, eckey);
+}
+
+int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey)
+{
+    return ASN1_i2d_fp_of(EC_KEY, i2d_EC_PUBKEY, fp, eckey);
+}
+
+EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey)
+{
+    return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, fp, eckey);
+}
+
+int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey)
+{
+    return ASN1_i2d_fp_of(EC_KEY, i2d_ECPrivateKey, fp, eckey);
+}
+# endif
+EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey)
+{
+    return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, bp, eckey);
+}
+
+int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *ecdsa)
+{
+    return ASN1_i2d_bio_of(EC_KEY, i2d_EC_PUBKEY, bp, ecdsa);
+}
+
+EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey)
+{
+    return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, bp, eckey);
+}
+
+int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey)
+{
+    return ASN1_i2d_bio_of(EC_KEY, i2d_ECPrivateKey, bp, eckey);
+}
+#endif
+
+int X509_pubkey_digest(const X509 *data, const EVP_MD *type,
+                       unsigned char *md, unsigned int *len)
+{
+    ASN1_BIT_STRING *key;
+    key = X509_get0_pubkey_bitstr(data);
+    if (!key)
+        return 0;
+    return EVP_Digest(key->data, key->length, md, len, type, NULL);
+}
+
+int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
+                unsigned int *len)
+{
+    if (type == EVP_sha1() && (data->ex_flags & EXFLAG_SET) != 0) {
+        /* Asking for SHA1 and we already computed it. */
+        if (len != NULL)
+            *len = sizeof(data->sha1_hash);
+        memcpy(md, data->sha1_hash, sizeof(data->sha1_hash));
+        return 1;
+    }
+    return (ASN1_item_digest
+            (ASN1_ITEM_rptr(X509), type, (char *)data, md, len));
+}
+
+int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type,
+                    unsigned char *md, unsigned int *len)
+{
+    if (type == EVP_sha1() && (data->flags & EXFLAG_SET) != 0) {
+        /* Asking for SHA1; always computed in CRL d2i. */
+        if (len != NULL)
+            *len = sizeof(data->sha1_hash);
+        memcpy(md, data->sha1_hash, sizeof(data->sha1_hash));
+        return 1;
+    }
+    return (ASN1_item_digest
+            (ASN1_ITEM_rptr(X509_CRL), type, (char *)data, md, len));
+}
+
+int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type,
+                    unsigned char *md, unsigned int *len)
+{
+    return (ASN1_item_digest
+            (ASN1_ITEM_rptr(X509_REQ), type, (char *)data, md, len));
+}
+
+int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type,
+                     unsigned char *md, unsigned int *len)
+{
+    return (ASN1_item_digest
+            (ASN1_ITEM_rptr(X509_NAME), type, (char *)data, md, len));
+}
+
+int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,
+                                   const EVP_MD *type, unsigned char *md,
+                                   unsigned int *len)
+{
+    return (ASN1_item_digest(ASN1_ITEM_rptr(PKCS7_ISSUER_AND_SERIAL), type,
+                             (char *)data, md, len));
+}
+
+#ifndef OPENSSL_NO_STDIO
+X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8)
+{
+    return ASN1_d2i_fp_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, fp, p8);
+}
+
+int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8)
+{
+    return ASN1_i2d_fp_of(X509_SIG, i2d_X509_SIG, fp, p8);
+}
+#endif
+
+X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8)
+{
+    return ASN1_d2i_bio_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, bp, p8);
+}
+
+int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8)
+{
+    return ASN1_i2d_bio_of(X509_SIG, i2d_X509_SIG, bp, p8);
+}
+
+#ifndef OPENSSL_NO_STDIO
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
+                                                PKCS8_PRIV_KEY_INFO **p8inf)
+{
+    return ASN1_d2i_fp_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new,
+                          d2i_PKCS8_PRIV_KEY_INFO, fp, p8inf);
+}
+
+int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf)
+{
+    return ASN1_i2d_fp_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, fp,
+                          p8inf);
+}
+
+int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key)
+{
+    PKCS8_PRIV_KEY_INFO *p8inf;
+    int ret;
+    p8inf = EVP_PKEY2PKCS8(key);
+    if (!p8inf)
+        return 0;
+    ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf);
+    PKCS8_PRIV_KEY_INFO_free(p8inf);
+    return ret;
+}
+
+int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey)
+{
+    return ASN1_i2d_fp_of(EVP_PKEY, i2d_PrivateKey, fp, pkey);
+}
+
+EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a)
+{
+    return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, fp, a);
+}
+
+int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey)
+{
+    return ASN1_i2d_fp_of(EVP_PKEY, i2d_PUBKEY, fp, pkey);
+}
+
+EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a)
+{
+    return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, fp, a);
+}
+
+#endif
+
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
+                                                 PKCS8_PRIV_KEY_INFO **p8inf)
+{
+    return ASN1_d2i_bio_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new,
+                           d2i_PKCS8_PRIV_KEY_INFO, bp, p8inf);
+}
+
+int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf)
+{
+    return ASN1_i2d_bio_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, bp,
+                           p8inf);
+}
+
+int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key)
+{
+    PKCS8_PRIV_KEY_INFO *p8inf;
+    int ret;
+    p8inf = EVP_PKEY2PKCS8(key);
+    if (!p8inf)
+        return 0;
+    ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
+    PKCS8_PRIV_KEY_INFO_free(p8inf);
+    return ret;
+}
+
+int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey)
+{
+    return ASN1_i2d_bio_of(EVP_PKEY, i2d_PrivateKey, bp, pkey);
+}
+
+EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a)
+{
+    return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, bp, a);
+}
+
+int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey)
+{
+    return ASN1_i2d_bio_of(EVP_PKEY, i2d_PUBKEY, bp, pkey);
+}
+
+EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a)
+{
+    return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, bp, a);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_attrib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_attrib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_attrib.c	(revision 331)
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "x509_lcl.h"
+
+/*-
+ * X509_ATTRIBUTE: this has the following form:
+ *
+ * typedef struct x509_attributes_st
+ *      {
+ *      ASN1_OBJECT *object;
+ *      STACK_OF(ASN1_TYPE) *set;
+ *      } X509_ATTRIBUTE;
+ *
+ */
+
+ASN1_SEQUENCE(X509_ATTRIBUTE) = {
+        ASN1_SIMPLE(X509_ATTRIBUTE, object, ASN1_OBJECT),
+        ASN1_SET_OF(X509_ATTRIBUTE, set, ASN1_ANY)
+} ASN1_SEQUENCE_END(X509_ATTRIBUTE)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_ATTRIBUTE)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_ATTRIBUTE)
+
+X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value)
+{
+    X509_ATTRIBUTE *ret = NULL;
+    ASN1_TYPE *val = NULL;
+
+    if ((ret = X509_ATTRIBUTE_new()) == NULL)
+        return (NULL);
+    ret->object = OBJ_nid2obj(nid);
+    if ((val = ASN1_TYPE_new()) == NULL)
+        goto err;
+    if (!sk_ASN1_TYPE_push(ret->set, val))
+        goto err;
+
+    ASN1_TYPE_set(val, atrtype, value);
+    return (ret);
+ err:
+    X509_ATTRIBUTE_free(ret);
+    ASN1_TYPE_free(val);
+    return (NULL);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_crl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_crl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_crl.c	(revision 331)
@@ -0,0 +1,459 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+#include <openssl/x509v3.h>
+#include "x509_lcl.h"
+
+static int X509_REVOKED_cmp(const X509_REVOKED *const *a,
+                            const X509_REVOKED *const *b);
+static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
+
+ASN1_SEQUENCE(X509_REVOKED) = {
+        ASN1_EMBED(X509_REVOKED,serialNumber, ASN1_INTEGER),
+        ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME),
+        ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION)
+} ASN1_SEQUENCE_END(X509_REVOKED)
+
+static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r);
+static int def_crl_lookup(X509_CRL *crl,
+                          X509_REVOKED **ret, ASN1_INTEGER *serial,
+                          X509_NAME *issuer);
+
+static X509_CRL_METHOD int_crl_meth = {
+    0,
+    0, 0,
+    def_crl_lookup,
+    def_crl_verify
+};
+
+static const X509_CRL_METHOD *default_crl_method = &int_crl_meth;
+
+/*
+ * The X509_CRL_INFO structure needs a bit of customisation. Since we cache
+ * the original encoding the signature won't be affected by reordering of the
+ * revoked field.
+ */
+static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                      void *exarg)
+{
+    X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
+
+    if (!a || !a->revoked)
+        return 1;
+    switch (operation) {
+        /*
+         * Just set cmp function here. We don't sort because that would
+         * affect the output of X509_CRL_print().
+         */
+    case ASN1_OP_D2I_POST:
+        (void)sk_X509_REVOKED_set_cmp_func(a->revoked, X509_REVOKED_cmp);
+        break;
+    }
+    return 1;
+}
+
+
+ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = {
+        ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER),
+        ASN1_EMBED(X509_CRL_INFO, sig_alg, X509_ALGOR),
+        ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME),
+        ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME),
+        ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME),
+        ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED),
+        ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0)
+} ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO)
+
+/*
+ * Set CRL entry issuer according to CRL certificate issuer extension. Check
+ * for unhandled critical CRL entry extensions.
+ */
+
+static int crl_set_issuers(X509_CRL *crl)
+{
+
+    int i, j;
+    GENERAL_NAMES *gens, *gtmp;
+    STACK_OF(X509_REVOKED) *revoked;
+
+    revoked = X509_CRL_get_REVOKED(crl);
+
+    gens = NULL;
+    for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) {
+        X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
+        STACK_OF(X509_EXTENSION) *exts;
+        ASN1_ENUMERATED *reason;
+        X509_EXTENSION *ext;
+        gtmp = X509_REVOKED_get_ext_d2i(rev,
+                                        NID_certificate_issuer, &j, NULL);
+        if (!gtmp && (j != -1)) {
+            crl->flags |= EXFLAG_INVALID;
+            return 1;
+        }
+
+        if (gtmp) {
+            gens = gtmp;
+            if (!crl->issuers) {
+                crl->issuers = sk_GENERAL_NAMES_new_null();
+                if (!crl->issuers)
+                    return 0;
+            }
+            if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
+                return 0;
+        }
+        rev->issuer = gens;
+
+        reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, &j, NULL);
+        if (!reason && (j != -1)) {
+            crl->flags |= EXFLAG_INVALID;
+            return 1;
+        }
+
+        if (reason) {
+            rev->reason = ASN1_ENUMERATED_get(reason);
+            ASN1_ENUMERATED_free(reason);
+        } else
+            rev->reason = CRL_REASON_NONE;
+
+        /* Check for critical CRL entry extensions */
+
+        exts = rev->extensions;
+
+        for (j = 0; j < sk_X509_EXTENSION_num(exts); j++) {
+            ext = sk_X509_EXTENSION_value(exts, j);
+            if (X509_EXTENSION_get_critical(ext)) {
+                if (OBJ_obj2nid(X509_EXTENSION_get_object(ext)) == NID_certificate_issuer)
+                    continue;
+                crl->flags |= EXFLAG_CRITICAL;
+                break;
+            }
+        }
+
+    }
+
+    return 1;
+
+}
+
+/*
+ * The X509_CRL structure needs a bit of customisation. Cache some extensions
+ * and hash of the whole CRL.
+ */
+static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                  void *exarg)
+{
+    X509_CRL *crl = (X509_CRL *)*pval;
+    STACK_OF(X509_EXTENSION) *exts;
+    X509_EXTENSION *ext;
+    int idx;
+
+    switch (operation) {
+    case ASN1_OP_NEW_POST:
+        crl->idp = NULL;
+        crl->akid = NULL;
+        crl->flags = 0;
+        crl->idp_flags = 0;
+        crl->idp_reasons = CRLDP_ALL_REASONS;
+        crl->meth = default_crl_method;
+        crl->meth_data = NULL;
+        crl->issuers = NULL;
+        crl->crl_number = NULL;
+        crl->base_crl_number = NULL;
+        break;
+
+    case ASN1_OP_D2I_POST:
+        X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
+        crl->idp = X509_CRL_get_ext_d2i(crl,
+                                        NID_issuing_distribution_point, NULL,
+                                        NULL);
+        if (crl->idp)
+            setup_idp(crl, crl->idp);
+
+        crl->akid = X509_CRL_get_ext_d2i(crl,
+                                         NID_authority_key_identifier, NULL,
+                                         NULL);
+
+        crl->crl_number = X509_CRL_get_ext_d2i(crl,
+                                               NID_crl_number, NULL, NULL);
+
+        crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
+                                                    NID_delta_crl, NULL,
+                                                    NULL);
+        /* Delta CRLs must have CRL number */
+        if (crl->base_crl_number && !crl->crl_number)
+            crl->flags |= EXFLAG_INVALID;
+
+        /*
+         * See if we have any unhandled critical CRL extensions and indicate
+         * this in a flag. We only currently handle IDP so anything else
+         * critical sets the flag. This code accesses the X509_CRL structure
+         * directly: applications shouldn't do this.
+         */
+
+        exts = crl->crl.extensions;
+
+        for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) {
+            int nid;
+            ext = sk_X509_EXTENSION_value(exts, idx);
+            nid = OBJ_obj2nid(X509_EXTENSION_get_object(ext));
+            if (nid == NID_freshest_crl)
+                crl->flags |= EXFLAG_FRESHEST;
+            if (X509_EXTENSION_get_critical(ext)) {
+                /* We handle IDP and deltas */
+                if ((nid == NID_issuing_distribution_point)
+                    || (nid == NID_authority_key_identifier)
+                    || (nid == NID_delta_crl))
+                    continue;
+                crl->flags |= EXFLAG_CRITICAL;
+                break;
+            }
+        }
+
+        if (!crl_set_issuers(crl))
+            return 0;
+
+        if (crl->meth->crl_init) {
+            if (crl->meth->crl_init(crl) == 0)
+                return 0;
+        }
+
+        crl->flags |= EXFLAG_SET;
+        break;
+
+    case ASN1_OP_FREE_POST:
+        if (crl->meth->crl_free) {
+            if (!crl->meth->crl_free(crl))
+                return 0;
+        }
+        AUTHORITY_KEYID_free(crl->akid);
+        ISSUING_DIST_POINT_free(crl->idp);
+        ASN1_INTEGER_free(crl->crl_number);
+        ASN1_INTEGER_free(crl->base_crl_number);
+        sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
+        break;
+    }
+    return 1;
+}
+
+/* Convert IDP into a more convenient form */
+
+static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
+{
+    int idp_only = 0;
+    /* Set various flags according to IDP */
+    crl->idp_flags |= IDP_PRESENT;
+    if (idp->onlyuser > 0) {
+        idp_only++;
+        crl->idp_flags |= IDP_ONLYUSER;
+    }
+    if (idp->onlyCA > 0) {
+        idp_only++;
+        crl->idp_flags |= IDP_ONLYCA;
+    }
+    if (idp->onlyattr > 0) {
+        idp_only++;
+        crl->idp_flags |= IDP_ONLYATTR;
+    }
+
+    if (idp_only > 1)
+        crl->idp_flags |= IDP_INVALID;
+
+    if (idp->indirectCRL > 0)
+        crl->idp_flags |= IDP_INDIRECT;
+
+    if (idp->onlysomereasons) {
+        crl->idp_flags |= IDP_REASONS;
+        if (idp->onlysomereasons->length > 0)
+            crl->idp_reasons = idp->onlysomereasons->data[0];
+        if (idp->onlysomereasons->length > 1)
+            crl->idp_reasons |= (idp->onlysomereasons->data[1] << 8);
+        crl->idp_reasons &= CRLDP_ALL_REASONS;
+    }
+
+    DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
+}
+
+ASN1_SEQUENCE_ref(X509_CRL, crl_cb) = {
+        ASN1_EMBED(X509_CRL, crl, X509_CRL_INFO),
+        ASN1_EMBED(X509_CRL, sig_alg, X509_ALGOR),
+        ASN1_EMBED(X509_CRL, signature, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_REVOKED)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_CRL)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL)
+
+static int X509_REVOKED_cmp(const X509_REVOKED *const *a,
+                            const X509_REVOKED *const *b)
+{
+    return (ASN1_STRING_cmp((ASN1_STRING *)&(*a)->serialNumber,
+                            (ASN1_STRING *)&(*b)->serialNumber));
+}
+
+int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)
+{
+    X509_CRL_INFO *inf;
+    inf = &crl->crl;
+    if (inf->revoked == NULL)
+        inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp);
+    if (inf->revoked == NULL || !sk_X509_REVOKED_push(inf->revoked, rev)) {
+        ASN1err(ASN1_F_X509_CRL_ADD0_REVOKED, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    inf->enc.modified = 1;
+    return 1;
+}
+
+int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r)
+{
+    if (crl->meth->crl_verify)
+        return crl->meth->crl_verify(crl, r);
+    return 0;
+}
+
+int X509_CRL_get0_by_serial(X509_CRL *crl,
+                            X509_REVOKED **ret, ASN1_INTEGER *serial)
+{
+    if (crl->meth->crl_lookup)
+        return crl->meth->crl_lookup(crl, ret, serial, NULL);
+    return 0;
+}
+
+int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x)
+{
+    if (crl->meth->crl_lookup)
+        return crl->meth->crl_lookup(crl, ret,
+                                     X509_get_serialNumber(x),
+                                     X509_get_issuer_name(x));
+    return 0;
+}
+
+static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r)
+{
+    return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
+                             &crl->sig_alg, &crl->signature, &crl->crl, r));
+}
+
+static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm,
+                                    X509_REVOKED *rev)
+{
+    int i;
+
+    if (!rev->issuer) {
+        if (!nm)
+            return 1;
+        if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
+            return 1;
+        return 0;
+    }
+
+    if (!nm)
+        nm = X509_CRL_get_issuer(crl);
+
+    for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) {
+        GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
+        if (gen->type != GEN_DIRNAME)
+            continue;
+        if (!X509_NAME_cmp(nm, gen->d.directoryName))
+            return 1;
+    }
+    return 0;
+
+}
+
+static int def_crl_lookup(X509_CRL *crl,
+                          X509_REVOKED **ret, ASN1_INTEGER *serial,
+                          X509_NAME *issuer)
+{
+    X509_REVOKED rtmp, *rev;
+    int idx;
+    rtmp.serialNumber = *serial;
+    /*
+     * Sort revoked into serial number order if not already sorted. Do this
+     * under a lock to avoid race condition.
+     */
+    if (!sk_X509_REVOKED_is_sorted(crl->crl.revoked)) {
+        CRYPTO_THREAD_write_lock(crl->lock);
+        sk_X509_REVOKED_sort(crl->crl.revoked);
+        CRYPTO_THREAD_unlock(crl->lock);
+    }
+    idx = sk_X509_REVOKED_find(crl->crl.revoked, &rtmp);
+    if (idx < 0)
+        return 0;
+    /* Need to look for matching name */
+    for (; idx < sk_X509_REVOKED_num(crl->crl.revoked); idx++) {
+        rev = sk_X509_REVOKED_value(crl->crl.revoked, idx);
+        if (ASN1_INTEGER_cmp(&rev->serialNumber, serial))
+            return 0;
+        if (crl_revoked_issuer_match(crl, issuer, rev)) {
+            if (ret)
+                *ret = rev;
+            if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
+                return 2;
+            return 1;
+        }
+    }
+    return 0;
+}
+
+void X509_CRL_set_default_method(const X509_CRL_METHOD *meth)
+{
+    if (meth == NULL)
+        default_crl_method = &int_crl_meth;
+    else
+        default_crl_method = meth;
+}
+
+X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl),
+                                     int (*crl_free) (X509_CRL *crl),
+                                     int (*crl_lookup) (X509_CRL *crl,
+                                                        X509_REVOKED **ret,
+                                                        ASN1_INTEGER *ser,
+                                                        X509_NAME *issuer),
+                                     int (*crl_verify) (X509_CRL *crl,
+                                                        EVP_PKEY *pk))
+{
+    X509_CRL_METHOD *m;
+    m = OPENSSL_malloc(sizeof(*m));
+    if (m == NULL)
+        return NULL;
+    m->crl_init = crl_init;
+    m->crl_free = crl_free;
+    m->crl_lookup = crl_lookup;
+    m->crl_verify = crl_verify;
+    m->flags = X509_CRL_METHOD_DYNAMIC;
+    return m;
+}
+
+void X509_CRL_METHOD_free(X509_CRL_METHOD *m)
+{
+    if (m == NULL || !(m->flags & X509_CRL_METHOD_DYNAMIC))
+        return;
+    OPENSSL_free(m);
+}
+
+void X509_CRL_set_meth_data(X509_CRL *crl, void *dat)
+{
+    crl->meth_data = dat;
+}
+
+void *X509_CRL_get_meth_data(X509_CRL *crl)
+{
+    return crl->meth_data;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_exten.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_exten.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_exten.c	(revision 331)
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-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 <stddef.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include "x509_lcl.h"
+
+ASN1_SEQUENCE(X509_EXTENSION) = {
+        ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT),
+        ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN),
+        ASN1_EMBED(X509_EXTENSION, value, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(X509_EXTENSION)
+
+ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION)
+ASN1_ITEM_TEMPLATE_END(X509_EXTENSIONS)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_EXTENSION)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_EXTENSION)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_name.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_name.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_name.c	(revision 331)
@@ -0,0 +1,557 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <ctype.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+#include "internal/asn1_int.h"
+#include "x509_lcl.h"
+
+/*
+ * Maximum length of X509_NAME: much larger than anything we should
+ * ever see in practice.
+ */
+
+#define X509_NAME_MAX (1024 * 1024)
+
+static int x509_name_ex_d2i(ASN1_VALUE **val,
+                            const unsigned char **in, long len,
+                            const ASN1_ITEM *it,
+                            int tag, int aclass, char opt, ASN1_TLC *ctx);
+
+static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
+                            const ASN1_ITEM *it, int tag, int aclass);
+static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
+static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
+
+static int x509_name_encode(X509_NAME *a);
+static int x509_name_canon(X509_NAME *a);
+static int asn1_string_canon(ASN1_STRING *out, const ASN1_STRING *in);
+static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname,
+                          unsigned char **in);
+
+static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
+                              int indent,
+                              const char *fname, const ASN1_PCTX *pctx);
+
+ASN1_SEQUENCE(X509_NAME_ENTRY) = {
+        ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
+        ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
+} ASN1_SEQUENCE_END(X509_NAME_ENTRY)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY)
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)
+
+/*
+ * For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so
+ * declare two template wrappers for this
+ */
+
+ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
+static_ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)
+
+ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
+static_ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
+
+/*
+ * Normally that's where it would end: we'd have two nested STACK structures
+ * representing the ASN1. Unfortunately X509_NAME uses a completely different
+ * form and caches encodings so we have to process the internal form and
+ * convert to the external form.
+ */
+
+static const ASN1_EXTERN_FUNCS x509_name_ff = {
+    NULL,
+    x509_name_ex_new,
+    x509_name_ex_free,
+    0,                          /* Default clear behaviour is OK */
+    x509_name_ex_d2i,
+    x509_name_ex_i2d,
+    x509_name_ex_print
+};
+
+IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_NAME)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME)
+
+static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
+{
+    X509_NAME *ret = OPENSSL_zalloc(sizeof(*ret));
+
+    if (ret == NULL)
+        goto memerr;
+    if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL)
+        goto memerr;
+    if ((ret->bytes = BUF_MEM_new()) == NULL)
+        goto memerr;
+    ret->modified = 1;
+    *val = (ASN1_VALUE *)ret;
+    return 1;
+
+ memerr:
+    ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE);
+    if (ret) {
+        sk_X509_NAME_ENTRY_free(ret->entries);
+        OPENSSL_free(ret);
+    }
+    return 0;
+}
+
+static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
+{
+    X509_NAME *a;
+
+    if (!pval || !*pval)
+        return;
+    a = (X509_NAME *)*pval;
+
+    BUF_MEM_free(a->bytes);
+    sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free);
+    OPENSSL_free(a->canon_enc);
+    OPENSSL_free(a);
+    *pval = NULL;
+}
+
+static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
+{
+    sk_X509_NAME_ENTRY_free(ne);
+}
+
+static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
+{
+    sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
+}
+
+static int x509_name_ex_d2i(ASN1_VALUE **val,
+                            const unsigned char **in, long len,
+                            const ASN1_ITEM *it, int tag, int aclass,
+                            char opt, ASN1_TLC *ctx)
+{
+    const unsigned char *p = *in, *q;
+    union {
+        STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
+        ASN1_VALUE *a;
+    } intname = {
+        NULL
+    };
+    union {
+        X509_NAME *x;
+        ASN1_VALUE *a;
+    } nm = {
+        NULL
+    };
+    int i, j, ret;
+    STACK_OF(X509_NAME_ENTRY) *entries;
+    X509_NAME_ENTRY *entry;
+    if (len > X509_NAME_MAX)
+        len = X509_NAME_MAX;
+    q = p;
+
+    /* Get internal representation of Name */
+    ret = ASN1_item_ex_d2i(&intname.a,
+                           &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
+                           tag, aclass, opt, ctx);
+
+    if (ret <= 0)
+        return ret;
+
+    if (*val)
+        x509_name_ex_free(val, NULL);
+    if (!x509_name_ex_new(&nm.a, NULL))
+        goto err;
+    /* We've decoded it: now cache encoding */
+    if (!BUF_MEM_grow(nm.x->bytes, p - q))
+        goto err;
+    memcpy(nm.x->bytes->data, q, p - q);
+
+    /* Convert internal representation to X509_NAME structure */
+    for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
+        entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
+        for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
+            entry = sk_X509_NAME_ENTRY_value(entries, j);
+            entry->set = i;
+            if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
+                goto err;
+            sk_X509_NAME_ENTRY_set(entries, j, NULL);
+        }
+    }
+    ret = x509_name_canon(nm.x);
+    if (!ret)
+        goto err;
+    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+                                         local_sk_X509_NAME_ENTRY_free);
+    nm.x->modified = 0;
+    *val = nm.a;
+    *in = p;
+    return ret;
+
+ err:
+    if (nm.x != NULL)
+        X509_NAME_free(nm.x);
+    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+                                         local_sk_X509_NAME_ENTRY_pop_free);
+    ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
+    return 0;
+}
+
+static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
+                            const ASN1_ITEM *it, int tag, int aclass)
+{
+    int ret;
+    X509_NAME *a = (X509_NAME *)*val;
+    if (a->modified) {
+        ret = x509_name_encode(a);
+        if (ret < 0)
+            return ret;
+        ret = x509_name_canon(a);
+        if (ret < 0)
+            return ret;
+    }
+    ret = a->bytes->length;
+    if (out != NULL) {
+        memcpy(*out, a->bytes->data, ret);
+        *out += ret;
+    }
+    return ret;
+}
+
+static int x509_name_encode(X509_NAME *a)
+{
+    union {
+        STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
+        ASN1_VALUE *a;
+    } intname = {
+        NULL
+    };
+    int len;
+    unsigned char *p;
+    STACK_OF(X509_NAME_ENTRY) *entries = NULL;
+    X509_NAME_ENTRY *entry;
+    int i, set = -1;
+    intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
+    if (!intname.s)
+        goto memerr;
+    for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
+        entry = sk_X509_NAME_ENTRY_value(a->entries, i);
+        if (entry->set != set) {
+            entries = sk_X509_NAME_ENTRY_new_null();
+            if (!entries)
+                goto memerr;
+            if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries)) {
+                sk_X509_NAME_ENTRY_free(entries);
+                goto memerr;
+            }
+            set = entry->set;
+        }
+        if (!sk_X509_NAME_ENTRY_push(entries, entry))
+            goto memerr;
+    }
+    len = ASN1_item_ex_i2d(&intname.a, NULL,
+                           ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
+    if (!BUF_MEM_grow(a->bytes, len))
+        goto memerr;
+    p = (unsigned char *)a->bytes->data;
+    ASN1_item_ex_i2d(&intname.a,
+                     &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
+    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+                                         local_sk_X509_NAME_ENTRY_free);
+    a->modified = 0;
+    return len;
+ memerr:
+    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+                                         local_sk_X509_NAME_ENTRY_free);
+    ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE);
+    return -1;
+}
+
+static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
+                              int indent,
+                              const char *fname, const ASN1_PCTX *pctx)
+{
+    if (X509_NAME_print_ex(out, (const X509_NAME *)*pval,
+                           indent, pctx->nm_flags) <= 0)
+        return 0;
+    return 2;
+}
+
+/*
+ * This function generates the canonical encoding of the Name structure. In
+ * it all strings are converted to UTF8, leading, trailing and multiple
+ * spaces collapsed, converted to lower case and the leading SEQUENCE header
+ * removed. In future we could also normalize the UTF8 too. By doing this
+ * comparison of Name structures can be rapidly performed by just using
+ * memcmp() of the canonical encoding. By omitting the leading SEQUENCE name
+ * constraints of type dirName can also be checked with a simple memcmp().
+ */
+
+static int x509_name_canon(X509_NAME *a)
+{
+    unsigned char *p;
+    STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
+    STACK_OF(X509_NAME_ENTRY) *entries = NULL;
+    X509_NAME_ENTRY *entry, *tmpentry = NULL;
+    int i, set = -1, ret = 0, len;
+
+    OPENSSL_free(a->canon_enc);
+    a->canon_enc = NULL;
+    /* Special case: empty X509_NAME => null encoding */
+    if (sk_X509_NAME_ENTRY_num(a->entries) == 0) {
+        a->canon_enclen = 0;
+        return 1;
+    }
+    intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
+    if (!intname)
+        goto err;
+    for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
+        entry = sk_X509_NAME_ENTRY_value(a->entries, i);
+        if (entry->set != set) {
+            entries = sk_X509_NAME_ENTRY_new_null();
+            if (!entries)
+                goto err;
+            if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) {
+                sk_X509_NAME_ENTRY_free(entries);
+                goto err;
+            }
+            set = entry->set;
+        }
+        tmpentry = X509_NAME_ENTRY_new();
+        if (tmpentry == NULL)
+            goto err;
+        tmpentry->object = OBJ_dup(entry->object);
+        if (tmpentry->object == NULL)
+            goto err;
+        if (!asn1_string_canon(tmpentry->value, entry->value))
+            goto err;
+        if (!sk_X509_NAME_ENTRY_push(entries, tmpentry))
+            goto err;
+        tmpentry = NULL;
+    }
+
+    /* Finally generate encoding */
+
+    len = i2d_name_canon(intname, NULL);
+    if (len < 0)
+        goto err;
+    a->canon_enclen = len;
+
+    p = OPENSSL_malloc(a->canon_enclen);
+
+    if (p == NULL)
+        goto err;
+
+    a->canon_enc = p;
+
+    i2d_name_canon(intname, &p);
+
+    ret = 1;
+
+ err:
+
+    X509_NAME_ENTRY_free(tmpentry);
+    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
+                                         local_sk_X509_NAME_ENTRY_pop_free);
+    return ret;
+}
+
+/* Bitmap of all the types of string that will be canonicalized. */
+
+#define ASN1_MASK_CANON \
+        (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
+        | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
+        | B_ASN1_VISIBLESTRING)
+
+static int asn1_string_canon(ASN1_STRING *out, const ASN1_STRING *in)
+{
+    unsigned char *to, *from;
+    int len, i;
+
+    /* If type not in bitmask just copy string across */
+    if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) {
+        if (!ASN1_STRING_copy(out, in))
+            return 0;
+        return 1;
+    }
+
+    out->type = V_ASN1_UTF8STRING;
+    out->length = ASN1_STRING_to_UTF8(&out->data, in);
+    if (out->length == -1)
+        return 0;
+
+    to = out->data;
+    from = to;
+
+    len = out->length;
+
+    /*
+     * Convert string in place to canonical form. Ultimately we may need to
+     * handle a wider range of characters but for now ignore anything with
+     * MSB set and rely on the isspace() and tolower() functions.
+     */
+
+    /* Ignore leading spaces */
+    while ((len > 0) && !(*from & 0x80) && isspace(*from)) {
+        from++;
+        len--;
+    }
+
+    to = from + len;
+
+    /* Ignore trailing spaces */
+    while ((len > 0) && !(to[-1] & 0x80) && isspace(to[-1])) {
+        to--;
+        len--;
+    }
+
+    to = out->data;
+
+    i = 0;
+    while (i < len) {
+        /* If MSB set just copy across */
+        if (*from & 0x80) {
+            *to++ = *from++;
+            i++;
+        }
+        /* Collapse multiple spaces */
+        else if (isspace(*from)) {
+            /* Copy one space across */
+            *to++ = ' ';
+            /*
+             * Ignore subsequent spaces. Note: don't need to check len here
+             * because we know the last character is a non-space so we can't
+             * overflow.
+             */
+            do {
+                from++;
+                i++;
+            }
+            while (!(*from & 0x80) && isspace(*from));
+        } else {
+            *to++ = tolower(*from);
+            from++;
+            i++;
+        }
+    }
+
+    out->length = to - out->data;
+
+    return 1;
+
+}
+
+static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname,
+                          unsigned char **in)
+{
+    int i, len, ltmp;
+    ASN1_VALUE *v;
+    STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
+
+    len = 0;
+    for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) {
+        v = sk_ASN1_VALUE_value(intname, i);
+        ltmp = ASN1_item_ex_i2d(&v, in,
+                                ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
+        if (ltmp < 0)
+            return ltmp;
+        len += ltmp;
+    }
+    return len;
+}
+
+int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
+{
+    X509_NAME *in;
+
+    if (!xn || !name)
+        return (0);
+
+    if (*xn != name) {
+        in = X509_NAME_dup(name);
+        if (in != NULL) {
+            X509_NAME_free(*xn);
+            *xn = in;
+        }
+    }
+    return (*xn != NULL);
+}
+
+int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase)
+{
+    char *s, *c, *b;
+    int l, i;
+
+    l = 80 - 2 - obase;
+
+    b = X509_NAME_oneline(name, NULL, 0);
+    if (!b)
+        return 0;
+    if (!*b) {
+        OPENSSL_free(b);
+        return 1;
+    }
+    s = b + 1;                  /* skip the first slash */
+
+    c = s;
+    for (;;) {
+#ifndef CHARSET_EBCDIC
+        if (((*s == '/') &&
+             ((s[1] >= 'A') && (s[1] <= 'Z') && ((s[2] == '=') ||
+                                                 ((s[2] >= 'A')
+                                                  && (s[2] <= 'Z')
+                                                  && (s[3] == '='))
+              ))) || (*s == '\0'))
+#else
+        if (((*s == '/') &&
+             (isupper(s[1]) && ((s[2] == '=') ||
+                                (isupper(s[2]) && (s[3] == '='))
+              ))) || (*s == '\0'))
+#endif
+        {
+            i = s - c;
+            if (BIO_write(bp, c, i) != i)
+                goto err;
+            c = s + 1;          /* skip following slash */
+            if (*s != '\0') {
+                if (BIO_write(bp, ", ", 2) != 2)
+                    goto err;
+            }
+            l--;
+        }
+        if (*s == '\0')
+            break;
+        s++;
+        l--;
+    }
+
+    OPENSSL_free(b);
+    return 1;
+ err:
+    X509err(X509_F_X509_NAME_PRINT, ERR_R_BUF_LIB);
+    OPENSSL_free(b);
+    return 0;
+}
+
+int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder,
+                       size_t *pderlen)
+{
+    /* Make sure encoding is valid */
+    if (i2d_X509_NAME(nm, NULL) <= 0)
+        return 0;
+    if (pder != NULL)
+        *pder = (unsigned char *)nm->bytes->data;
+    if (pderlen != NULL)
+        *pderlen = nm->bytes->length;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_pubkey.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_pubkey.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_pubkey.c	(revision 331)
@@ -0,0 +1,374 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "internal/asn1_int.h"
+#include "internal/evp_int.h"
+#include "internal/x509_int.h"
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+
+struct X509_pubkey_st {
+    X509_ALGOR *algor;
+    ASN1_BIT_STRING *public_key;
+    EVP_PKEY *pkey;
+};
+
+static int x509_pubkey_decode(EVP_PKEY **pk, X509_PUBKEY *key);
+
+/* Minor tweak to operation: free up EVP_PKEY */
+static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                     void *exarg)
+{
+    if (operation == ASN1_OP_FREE_POST) {
+        X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
+        EVP_PKEY_free(pubkey->pkey);
+    } else if (operation == ASN1_OP_D2I_POST) {
+        /* Attempt to decode public key and cache in pubkey structure. */
+        X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
+        EVP_PKEY_free(pubkey->pkey);
+        /*
+         * Opportunistically decode the key but remove any non fatal errors
+         * from the queue. Subsequent explicit attempts to decode/use the key
+         * will return an appropriate error.
+         */
+        ERR_set_mark();
+        if (x509_pubkey_decode(&pubkey->pkey, pubkey) == -1)
+            return 0;
+        ERR_pop_to_mark();
+    }
+    return 1;
+}
+
+ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
+        ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
+        ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
+
+int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
+{
+    X509_PUBKEY *pk = NULL;
+
+    if (x == NULL)
+        return (0);
+
+    if ((pk = X509_PUBKEY_new()) == NULL)
+        goto error;
+
+    if (pkey->ameth) {
+        if (pkey->ameth->pub_encode) {
+            if (!pkey->ameth->pub_encode(pk, pkey)) {
+                X509err(X509_F_X509_PUBKEY_SET,
+                        X509_R_PUBLIC_KEY_ENCODE_ERROR);
+                goto error;
+            }
+        } else {
+            X509err(X509_F_X509_PUBKEY_SET, X509_R_METHOD_NOT_SUPPORTED);
+            goto error;
+        }
+    } else {
+        X509err(X509_F_X509_PUBKEY_SET, X509_R_UNSUPPORTED_ALGORITHM);
+        goto error;
+    }
+
+    X509_PUBKEY_free(*x);
+    *x = pk;
+    pk->pkey = pkey;
+    EVP_PKEY_up_ref(pkey);
+    return 1;
+
+ error:
+    X509_PUBKEY_free(pk);
+    return 0;
+}
+
+/*
+ * Attempt to decode a public key.
+ * Returns 1 on success, 0 for a decode failure and -1 for a fatal
+ * error e.g. malloc failure.
+ */
+
+
+static int x509_pubkey_decode(EVP_PKEY **ppkey, X509_PUBKEY *key)
+    {
+    EVP_PKEY *pkey = EVP_PKEY_new();
+
+    if (pkey == NULL) {
+        X509err(X509_F_X509_PUBKEY_DECODE, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+
+    if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(key->algor->algorithm))) {
+        X509err(X509_F_X509_PUBKEY_DECODE, X509_R_UNSUPPORTED_ALGORITHM);
+        goto error;
+    }
+
+    if (pkey->ameth->pub_decode) {
+        /*
+         * Treat any failure of pub_decode as a decode error. In
+         * future we could have different return codes for decode
+         * errors and fatal errors such as malloc failure.
+         */
+        if (!pkey->ameth->pub_decode(pkey, key)) {
+            X509err(X509_F_X509_PUBKEY_DECODE, X509_R_PUBLIC_KEY_DECODE_ERROR);
+            goto error;
+        }
+    } else {
+        X509err(X509_F_X509_PUBKEY_DECODE, X509_R_METHOD_NOT_SUPPORTED);
+        goto error;
+    }
+
+    *ppkey = pkey;
+    return 1;
+
+ error:
+    EVP_PKEY_free(pkey);
+    return 0;
+}
+
+EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key)
+{
+    EVP_PKEY *ret = NULL;
+
+    if (key == NULL || key->public_key == NULL)
+        return NULL;
+
+    if (key->pkey != NULL)
+        return key->pkey;
+
+    /*
+     * When the key ASN.1 is initially parsed an attempt is made to
+     * decode the public key and cache the EVP_PKEY structure. If this
+     * operation fails the cached value will be NULL. Parsing continues
+     * to allow parsing of unknown key types or unsupported forms.
+     * We repeat the decode operation so the appropriate errors are left
+     * in the queue.
+     */
+    x509_pubkey_decode(&ret, key);
+    /* If decode doesn't fail something bad happened */
+    if (ret != NULL) {
+        X509err(X509_F_X509_PUBKEY_GET0, ERR_R_INTERNAL_ERROR);
+        EVP_PKEY_free(ret);
+    }
+
+    return NULL;
+}
+
+EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
+{
+    EVP_PKEY *ret = X509_PUBKEY_get0(key);
+    if (ret != NULL)
+        EVP_PKEY_up_ref(ret);
+    return ret;
+}
+
+/*
+ * Now two pseudo ASN1 routines that take an EVP_PKEY structure and encode or
+ * decode as X509_PUBKEY
+ */
+
+EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length)
+{
+    X509_PUBKEY *xpk;
+    EVP_PKEY *pktmp;
+    const unsigned char *q;
+    q = *pp;
+    xpk = d2i_X509_PUBKEY(NULL, &q, length);
+    if (!xpk)
+        return NULL;
+    pktmp = X509_PUBKEY_get(xpk);
+    X509_PUBKEY_free(xpk);
+    if (!pktmp)
+        return NULL;
+    *pp = q;
+    if (a) {
+        EVP_PKEY_free(*a);
+        *a = pktmp;
+    }
+    return pktmp;
+}
+
+int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
+{
+    X509_PUBKEY *xpk = NULL;
+    int ret;
+    if (!a)
+        return 0;
+    if (!X509_PUBKEY_set(&xpk, a))
+        return 0;
+    ret = i2d_X509_PUBKEY(xpk, pp);
+    X509_PUBKEY_free(xpk);
+    return ret;
+}
+
+/*
+ * The following are equivalents but which return RSA and DSA keys
+ */
+#ifndef OPENSSL_NO_RSA
+RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length)
+{
+    EVP_PKEY *pkey;
+    RSA *key;
+    const unsigned char *q;
+    q = *pp;
+    pkey = d2i_PUBKEY(NULL, &q, length);
+    if (!pkey)
+        return NULL;
+    key = EVP_PKEY_get1_RSA(pkey);
+    EVP_PKEY_free(pkey);
+    if (!key)
+        return NULL;
+    *pp = q;
+    if (a) {
+        RSA_free(*a);
+        *a = key;
+    }
+    return key;
+}
+
+int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
+{
+    EVP_PKEY *pktmp;
+    int ret;
+    if (!a)
+        return 0;
+    pktmp = EVP_PKEY_new();
+    if (pktmp == NULL) {
+        ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    EVP_PKEY_set1_RSA(pktmp, a);
+    ret = i2d_PUBKEY(pktmp, pp);
+    EVP_PKEY_free(pktmp);
+    return ret;
+}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length)
+{
+    EVP_PKEY *pkey;
+    DSA *key;
+    const unsigned char *q;
+    q = *pp;
+    pkey = d2i_PUBKEY(NULL, &q, length);
+    if (!pkey)
+        return NULL;
+    key = EVP_PKEY_get1_DSA(pkey);
+    EVP_PKEY_free(pkey);
+    if (!key)
+        return NULL;
+    *pp = q;
+    if (a) {
+        DSA_free(*a);
+        *a = key;
+    }
+    return key;
+}
+
+int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
+{
+    EVP_PKEY *pktmp;
+    int ret;
+    if (!a)
+        return 0;
+    pktmp = EVP_PKEY_new();
+    if (pktmp == NULL) {
+        ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    EVP_PKEY_set1_DSA(pktmp, a);
+    ret = i2d_PUBKEY(pktmp, pp);
+    EVP_PKEY_free(pktmp);
+    return ret;
+}
+#endif
+
+#ifndef OPENSSL_NO_EC
+EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
+{
+    EVP_PKEY *pkey;
+    EC_KEY *key;
+    const unsigned char *q;
+    q = *pp;
+    pkey = d2i_PUBKEY(NULL, &q, length);
+    if (!pkey)
+        return (NULL);
+    key = EVP_PKEY_get1_EC_KEY(pkey);
+    EVP_PKEY_free(pkey);
+    if (!key)
+        return (NULL);
+    *pp = q;
+    if (a) {
+        EC_KEY_free(*a);
+        *a = key;
+    }
+    return (key);
+}
+
+int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
+{
+    EVP_PKEY *pktmp;
+    int ret;
+    if (!a)
+        return (0);
+    if ((pktmp = EVP_PKEY_new()) == NULL) {
+        ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
+        return (0);
+    }
+    EVP_PKEY_set1_EC_KEY(pktmp, a);
+    ret = i2d_PUBKEY(pktmp, pp);
+    EVP_PKEY_free(pktmp);
+    return (ret);
+}
+#endif
+
+int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
+                           int ptype, void *pval,
+                           unsigned char *penc, int penclen)
+{
+    if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
+        return 0;
+    if (penc) {
+        OPENSSL_free(pub->public_key->data);
+        pub->public_key->data = penc;
+        pub->public_key->length = penclen;
+        /* Set number of unused bits to zero */
+        pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+        pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+    }
+    return 1;
+}
+
+int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
+                           const unsigned char **pk, int *ppklen,
+                           X509_ALGOR **pa, X509_PUBKEY *pub)
+{
+    if (ppkalg)
+        *ppkalg = pub->algor->algorithm;
+    if (pk) {
+        *pk = pub->public_key->data;
+        *ppklen = pub->public_key->length;
+    }
+    if (pa)
+        *pa = pub->algor;
+    return 1;
+}
+
+ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x)
+{
+    if (x == NULL)
+        return NULL;
+    return x->cert_info.key->public_key;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_req.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_req.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_req.c	(revision 331)
@@ -0,0 +1,68 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+
+/*-
+ * X509_REQ_INFO is handled in an unusual way to get round
+ * invalid encodings. Some broken certificate requests don't
+ * encode the attributes field if it is empty. This is in
+ * violation of PKCS#10 but we need to tolerate it. We do
+ * this by making the attributes field OPTIONAL then using
+ * the callback to initialise it to an empty STACK.
+ *
+ * This means that the field will be correctly encoded unless
+ * we NULL out the field.
+ *
+ * As a result we no longer need the req_kludge field because
+ * the information is now contained in the attributes field:
+ * 1. If it is NULL then it's the invalid omission.
+ * 2. If it is empty it is the correct encoding.
+ * 3. If it is not empty then some attributes are present.
+ *
+ */
+
+static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                   void *exarg)
+{
+    X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval;
+
+    if (operation == ASN1_OP_NEW_POST) {
+        rinf->attributes = sk_X509_ATTRIBUTE_new_null();
+        if (!rinf->attributes)
+            return 0;
+    }
+    return 1;
+}
+
+ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = {
+        ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER),
+        ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME),
+        ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY),
+        /* This isn't really OPTIONAL but it gets round invalid
+         * encodings
+         */
+        ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0)
+} ASN1_SEQUENCE_END_enc(X509_REQ_INFO, X509_REQ_INFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO)
+
+ASN1_SEQUENCE_ref(X509_REQ, 0) = {
+        ASN1_EMBED(X509_REQ, req_info, X509_REQ_INFO),
+        ASN1_EMBED(X509_REQ, sig_alg, X509_ALGOR),
+        ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_ref(X509_REQ, X509_REQ)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_REQ)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_x509.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_x509.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_x509.c	(revision 331)
@@ -0,0 +1,224 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include "internal/x509_int.h"
+
+ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = {
+        ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0),
+        ASN1_EMBED(X509_CINF, serialNumber, ASN1_INTEGER),
+        ASN1_EMBED(X509_CINF, signature, X509_ALGOR),
+        ASN1_SIMPLE(X509_CINF, issuer, X509_NAME),
+        ASN1_EMBED(X509_CINF, validity, X509_VAL),
+        ASN1_SIMPLE(X509_CINF, subject, X509_NAME),
+        ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY),
+        ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1),
+        ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2),
+        ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3)
+} ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_CINF)
+/* X509 top level structure needs a bit of customisation */
+
+extern void policy_cache_free(X509_POLICY_CACHE *cache);
+
+static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                   void *exarg)
+{
+    X509 *ret = (X509 *)*pval;
+
+    switch (operation) {
+
+    case ASN1_OP_NEW_POST:
+        ret->ex_flags = 0;
+        ret->ex_pathlen = -1;
+        ret->ex_pcpathlen = -1;
+        ret->skid = NULL;
+        ret->akid = NULL;
+#ifndef OPENSSL_NO_RFC3779
+        ret->rfc3779_addr = NULL;
+        ret->rfc3779_asid = NULL;
+#endif
+        ret->aux = NULL;
+        ret->crldp = NULL;
+        if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data))
+            return 0;
+        break;
+
+    case ASN1_OP_FREE_POST:
+        CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
+        X509_CERT_AUX_free(ret->aux);
+        ASN1_OCTET_STRING_free(ret->skid);
+        AUTHORITY_KEYID_free(ret->akid);
+        CRL_DIST_POINTS_free(ret->crldp);
+        policy_cache_free(ret->policy_cache);
+        GENERAL_NAMES_free(ret->altname);
+        NAME_CONSTRAINTS_free(ret->nc);
+#ifndef OPENSSL_NO_RFC3779
+        sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free);
+        ASIdentifiers_free(ret->rfc3779_asid);
+#endif
+        break;
+
+    }
+
+    return 1;
+
+}
+
+ASN1_SEQUENCE_ref(X509, x509_cb) = {
+        ASN1_EMBED(X509, cert_info, X509_CINF),
+        ASN1_EMBED(X509, sig_alg, X509_ALGOR),
+        ASN1_EMBED(X509, signature, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END_ref(X509, X509)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509)
+
+IMPLEMENT_ASN1_DUP_FUNCTION(X509)
+
+int X509_set_ex_data(X509 *r, int idx, void *arg)
+{
+    return (CRYPTO_set_ex_data(&r->ex_data, idx, arg));
+}
+
+void *X509_get_ex_data(X509 *r, int idx)
+{
+    return (CRYPTO_get_ex_data(&r->ex_data, idx));
+}
+
+/*
+ * X509_AUX ASN1 routines. X509_AUX is the name given to a certificate with
+ * extra info tagged on the end. Since these functions set how a certificate
+ * is trusted they should only be used when the certificate comes from a
+ * reliable source such as local storage.
+ */
+
+X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
+{
+    const unsigned char *q;
+    X509 *ret;
+    int freeret = 0;
+
+    /* Save start position */
+    q = *pp;
+
+    if (a == NULL || *a == NULL)
+        freeret = 1;
+    ret = d2i_X509(a, &q, length);
+    /* If certificate unreadable then forget it */
+    if (ret == NULL)
+        return NULL;
+    /* update length */
+    length -= q - *pp;
+    if (length > 0 && !d2i_X509_CERT_AUX(&ret->aux, &q, length))
+        goto err;
+    *pp = q;
+    return ret;
+ err:
+    if (freeret) {
+        X509_free(ret);
+        if (a)
+            *a = NULL;
+    }
+    return NULL;
+}
+
+/*
+ * Serialize trusted certificate to *pp or just return the required buffer
+ * length if pp == NULL.  We ultimately want to avoid modifying *pp in the
+ * error path, but that depends on similar hygiene in lower-level functions.
+ * Here we avoid compounding the problem.
+ */
+static int i2d_x509_aux_internal(X509 *a, unsigned char **pp)
+{
+    int length, tmplen;
+    unsigned char *start = pp != NULL ? *pp : NULL;
+
+    OPENSSL_assert(pp == NULL || *pp != NULL);
+
+    /*
+     * This might perturb *pp on error, but fixing that belongs in i2d_X509()
+     * not here.  It should be that if a == NULL length is zero, but we check
+     * both just in case.
+     */
+    length = i2d_X509(a, pp);
+    if (length <= 0 || a == NULL)
+        return length;
+
+    tmplen = i2d_X509_CERT_AUX(a->aux, pp);
+    if (tmplen < 0) {
+        if (start != NULL)
+            *pp = start;
+        return tmplen;
+    }
+    length += tmplen;
+
+    return length;
+}
+
+/*
+ * Serialize trusted certificate to *pp, or just return the required buffer
+ * length if pp == NULL.
+ *
+ * When pp is not NULL, but *pp == NULL, we allocate the buffer, but since
+ * we're writing two ASN.1 objects back to back, we can't have i2d_X509() do
+ * the allocation, nor can we allow i2d_X509_CERT_AUX() to increment the
+ * allocated buffer.
+ */
+int i2d_X509_AUX(X509 *a, unsigned char **pp)
+{
+    int length;
+    unsigned char *tmp;
+
+    /* Buffer provided by caller */
+    if (pp == NULL || *pp != NULL)
+        return i2d_x509_aux_internal(a, pp);
+
+    /* Obtain the combined length */
+    if ((length = i2d_x509_aux_internal(a, NULL)) <= 0)
+        return length;
+
+    /* Allocate requisite combined storage */
+    *pp = tmp = OPENSSL_malloc(length);
+    if (tmp == NULL)
+        return -1; /* Push error onto error stack? */
+
+    /* Encode, but keep *pp at the originally malloced pointer */
+    length = i2d_x509_aux_internal(a, &tmp);
+    if (length <= 0) {
+        OPENSSL_free(*pp);
+        *pp = NULL;
+    }
+    return length;
+}
+
+int i2d_re_X509_tbs(X509 *x, unsigned char **pp)
+{
+    x->cert_info.enc.modified = 1;
+    return i2d_X509_CINF(&x->cert_info, pp);
+}
+
+void X509_get0_signature(const ASN1_BIT_STRING **psig,
+                         const X509_ALGOR **palg, const X509 *x)
+{
+    if (psig)
+        *psig = &x->signature;
+    if (palg)
+        *palg = &x->sig_alg;
+}
+
+int X509_get_signature_nid(const X509 *x)
+{
+    return OBJ_obj2nid(x->sig_alg.algorithm);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_x509a.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_x509a.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509/x_x509a.c	(revision 331)
@@ -0,0 +1,169 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+
+/*
+ * X509_CERT_AUX routines. These are used to encode additional user
+ * modifiable data about a certificate. This data is appended to the X509
+ * encoding when the *_X509_AUX routines are used. This means that the
+ * "traditional" X509 routines will simply ignore the extra data.
+ */
+
+static X509_CERT_AUX *aux_get(X509 *x);
+
+ASN1_SEQUENCE(X509_CERT_AUX) = {
+        ASN1_SEQUENCE_OF_OPT(X509_CERT_AUX, trust, ASN1_OBJECT),
+        ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, reject, ASN1_OBJECT, 0),
+        ASN1_OPT(X509_CERT_AUX, alias, ASN1_UTF8STRING),
+        ASN1_OPT(X509_CERT_AUX, keyid, ASN1_OCTET_STRING),
+        ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, other, X509_ALGOR, 1)
+} ASN1_SEQUENCE_END(X509_CERT_AUX)
+
+IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_AUX)
+
+int X509_trusted(const X509 *x)
+{
+    return x->aux ? 1 : 0;
+}
+
+static X509_CERT_AUX *aux_get(X509 *x)
+{
+    if (x == NULL)
+        return NULL;
+    if (x->aux == NULL && (x->aux = X509_CERT_AUX_new()) == NULL)
+        return NULL;
+    return x->aux;
+}
+
+int X509_alias_set1(X509 *x, const unsigned char *name, int len)
+{
+    X509_CERT_AUX *aux;
+    if (!name) {
+        if (!x || !x->aux || !x->aux->alias)
+            return 1;
+        ASN1_UTF8STRING_free(x->aux->alias);
+        x->aux->alias = NULL;
+        return 1;
+    }
+    if ((aux = aux_get(x)) == NULL)
+        return 0;
+    if (aux->alias == NULL && (aux->alias = ASN1_UTF8STRING_new()) == NULL)
+        return 0;
+    return ASN1_STRING_set(aux->alias, name, len);
+}
+
+int X509_keyid_set1(X509 *x, const unsigned char *id, int len)
+{
+    X509_CERT_AUX *aux;
+    if (!id) {
+        if (!x || !x->aux || !x->aux->keyid)
+            return 1;
+        ASN1_OCTET_STRING_free(x->aux->keyid);
+        x->aux->keyid = NULL;
+        return 1;
+    }
+    if ((aux = aux_get(x)) == NULL)
+        return 0;
+    if (aux->keyid == NULL
+        && (aux->keyid = ASN1_OCTET_STRING_new()) == NULL)
+        return 0;
+    return ASN1_STRING_set(aux->keyid, id, len);
+}
+
+unsigned char *X509_alias_get0(X509 *x, int *len)
+{
+    if (!x->aux || !x->aux->alias)
+        return NULL;
+    if (len)
+        *len = x->aux->alias->length;
+    return x->aux->alias->data;
+}
+
+unsigned char *X509_keyid_get0(X509 *x, int *len)
+{
+    if (!x->aux || !x->aux->keyid)
+        return NULL;
+    if (len)
+        *len = x->aux->keyid->length;
+    return x->aux->keyid->data;
+}
+
+int X509_add1_trust_object(X509 *x, const ASN1_OBJECT *obj)
+{
+    X509_CERT_AUX *aux;
+    ASN1_OBJECT *objtmp = NULL;
+    if (obj) {
+        objtmp = OBJ_dup(obj);
+        if (!objtmp)
+            return 0;
+    }
+    if ((aux = aux_get(x)) == NULL)
+        goto err;
+    if (aux->trust == NULL
+        && (aux->trust = sk_ASN1_OBJECT_new_null()) == NULL)
+        goto err;
+    if (!objtmp || sk_ASN1_OBJECT_push(aux->trust, objtmp))
+        return 1;
+ err:
+    ASN1_OBJECT_free(objtmp);
+    return 0;
+}
+
+int X509_add1_reject_object(X509 *x, const ASN1_OBJECT *obj)
+{
+    X509_CERT_AUX *aux;
+    ASN1_OBJECT *objtmp;
+    if ((objtmp = OBJ_dup(obj)) == NULL)
+        return 0;
+    if ((aux = aux_get(x)) == NULL)
+        goto err;
+    if (aux->reject == NULL
+        && (aux->reject = sk_ASN1_OBJECT_new_null()) == NULL)
+        goto err;
+    return sk_ASN1_OBJECT_push(aux->reject, objtmp);
+ err:
+    ASN1_OBJECT_free(objtmp);
+    return 0;
+}
+
+void X509_trust_clear(X509 *x)
+{
+    if (x->aux) {
+        sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free);
+        x->aux->trust = NULL;
+    }
+}
+
+void X509_reject_clear(X509 *x)
+{
+    if (x->aux) {
+        sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free);
+        x->aux->reject = NULL;
+    }
+}
+
+STACK_OF(ASN1_OBJECT) *X509_get0_trust_objects(X509 *x)
+{
+    if (x->aux != NULL)
+        return x->aux->trust;
+    return NULL;
+}
+
+STACK_OF(ASN1_OBJECT) *X509_get0_reject_objects(X509 *x)
+{
+    if (x->aux != NULL)
+        return x->aux->reject;
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/ext_dat.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/ext_dat.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/ext_dat.h	(revision 331)
@@ -0,0 +1,24 @@
+/*
+ * Copyright 1999-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
+ */
+
+int name_cmp(const char *name, const char *cmp);
+
+extern const X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku;
+extern const X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo;
+extern const X509V3_EXT_METHOD v3_ns_ia5_list[8], v3_alt[3], v3_skey_id, v3_akey_id;
+extern const X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate;
+extern const X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl;
+extern const X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff;
+extern const X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc;
+extern const X509V3_EXT_METHOD v3_crl_hold, v3_pci;
+extern const X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints;
+extern const X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp;
+extern const X509V3_EXT_METHOD v3_addr, v3_asid;
+extern const X509V3_EXT_METHOD v3_ct_scts[3];
+extern const X509V3_EXT_METHOD v3_tls_feature;
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_cache.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_cache.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_cache.c	(revision 331)
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2004-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 "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include "internal/x509_int.h"
+
+#include "pcy_int.h"
+
+static int policy_data_cmp(const X509_POLICY_DATA *const *a,
+                           const X509_POLICY_DATA *const *b);
+static int policy_cache_set_int(long *out, ASN1_INTEGER *value);
+
+/*
+ * Set cache entry according to CertificatePolicies extension. Note: this
+ * destroys the passed CERTIFICATEPOLICIES structure.
+ */
+
+static int policy_cache_create(X509 *x,
+                               CERTIFICATEPOLICIES *policies, int crit)
+{
+    int i;
+    int ret = 0;
+    X509_POLICY_CACHE *cache = x->policy_cache;
+    X509_POLICY_DATA *data = NULL;
+    POLICYINFO *policy;
+    if (sk_POLICYINFO_num(policies) == 0)
+        goto bad_policy;
+    cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp);
+    if (cache->data == NULL)
+        goto bad_policy;
+    for (i = 0; i < sk_POLICYINFO_num(policies); i++) {
+        policy = sk_POLICYINFO_value(policies, i);
+        data = policy_data_new(policy, NULL, crit);
+        if (data == NULL)
+            goto bad_policy;
+        /*
+         * Duplicate policy OIDs are illegal: reject if matches found.
+         */
+        if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
+            if (cache->anyPolicy) {
+                ret = -1;
+                goto bad_policy;
+            }
+            cache->anyPolicy = data;
+        } else if (sk_X509_POLICY_DATA_find(cache->data, data) != -1) {
+            ret = -1;
+            goto bad_policy;
+        } else if (!sk_X509_POLICY_DATA_push(cache->data, data))
+            goto bad_policy;
+        data = NULL;
+    }
+    ret = 1;
+ bad_policy:
+    if (ret == -1)
+        x->ex_flags |= EXFLAG_INVALID_POLICY;
+    policy_data_free(data);
+    sk_POLICYINFO_pop_free(policies, POLICYINFO_free);
+    if (ret <= 0) {
+        sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
+        cache->data = NULL;
+    }
+    return ret;
+}
+
+static int policy_cache_new(X509 *x)
+{
+    X509_POLICY_CACHE *cache;
+    ASN1_INTEGER *ext_any = NULL;
+    POLICY_CONSTRAINTS *ext_pcons = NULL;
+    CERTIFICATEPOLICIES *ext_cpols = NULL;
+    POLICY_MAPPINGS *ext_pmaps = NULL;
+    int i;
+
+    if (x->policy_cache != NULL)
+        return 1;
+    cache = OPENSSL_malloc(sizeof(*cache));
+    if (cache == NULL)
+        return 0;
+    cache->anyPolicy = NULL;
+    cache->data = NULL;
+    cache->any_skip = -1;
+    cache->explicit_skip = -1;
+    cache->map_skip = -1;
+
+    x->policy_cache = cache;
+
+    /*
+     * Handle requireExplicitPolicy *first*. Need to process this even if we
+     * don't have any policies.
+     */
+    ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL);
+
+    if (!ext_pcons) {
+        if (i != -1)
+            goto bad_cache;
+    } else {
+        if (!ext_pcons->requireExplicitPolicy
+            && !ext_pcons->inhibitPolicyMapping)
+            goto bad_cache;
+        if (!policy_cache_set_int(&cache->explicit_skip,
+                                  ext_pcons->requireExplicitPolicy))
+            goto bad_cache;
+        if (!policy_cache_set_int(&cache->map_skip,
+                                  ext_pcons->inhibitPolicyMapping))
+            goto bad_cache;
+    }
+
+    /* Process CertificatePolicies */
+
+    ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL);
+    /*
+     * If no CertificatePolicies extension or problem decoding then there is
+     * no point continuing because the valid policies will be NULL.
+     */
+    if (!ext_cpols) {
+        /* If not absent some problem with extension */
+        if (i != -1)
+            goto bad_cache;
+        return 1;
+    }
+
+    i = policy_cache_create(x, ext_cpols, i);
+
+    /* NB: ext_cpols freed by policy_cache_set_policies */
+
+    if (i <= 0)
+        return i;
+
+    ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL);
+
+    if (!ext_pmaps) {
+        /* If not absent some problem with extension */
+        if (i != -1)
+            goto bad_cache;
+    } else {
+        i = policy_cache_set_mapping(x, ext_pmaps);
+        if (i <= 0)
+            goto bad_cache;
+    }
+
+    ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL);
+
+    if (!ext_any) {
+        if (i != -1)
+            goto bad_cache;
+    } else if (!policy_cache_set_int(&cache->any_skip, ext_any))
+        goto bad_cache;
+    goto just_cleanup;
+
+ bad_cache:
+    x->ex_flags |= EXFLAG_INVALID_POLICY;
+
+ just_cleanup:
+    POLICY_CONSTRAINTS_free(ext_pcons);
+    ASN1_INTEGER_free(ext_any);
+    return 1;
+
+}
+
+void policy_cache_free(X509_POLICY_CACHE *cache)
+{
+    if (!cache)
+        return;
+    policy_data_free(cache->anyPolicy);
+    sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free);
+    OPENSSL_free(cache);
+}
+
+const X509_POLICY_CACHE *policy_cache_set(X509 *x)
+{
+
+    if (x->policy_cache == NULL) {
+        CRYPTO_THREAD_write_lock(x->lock);
+        policy_cache_new(x);
+        CRYPTO_THREAD_unlock(x->lock);
+    }
+
+    return x->policy_cache;
+
+}
+
+X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
+                                         const ASN1_OBJECT *id)
+{
+    int idx;
+    X509_POLICY_DATA tmp;
+    tmp.valid_policy = (ASN1_OBJECT *)id;
+    idx = sk_X509_POLICY_DATA_find(cache->data, &tmp);
+    if (idx == -1)
+        return NULL;
+    return sk_X509_POLICY_DATA_value(cache->data, idx);
+}
+
+static int policy_data_cmp(const X509_POLICY_DATA *const *a,
+                           const X509_POLICY_DATA *const *b)
+{
+    return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy);
+}
+
+static int policy_cache_set_int(long *out, ASN1_INTEGER *value)
+{
+    if (value == NULL)
+        return 1;
+    if (value->type == V_ASN1_NEG_INTEGER)
+        return 0;
+    *out = ASN1_INTEGER_get(value);
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_data.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_data.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_data.c	(revision 331)
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2004-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 "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#include "pcy_int.h"
+
+/* Policy Node routines */
+
+void policy_data_free(X509_POLICY_DATA *data)
+{
+    if (!data)
+        return;
+    ASN1_OBJECT_free(data->valid_policy);
+    /* Don't free qualifiers if shared */
+    if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS))
+        sk_POLICYQUALINFO_pop_free(data->qualifier_set, POLICYQUALINFO_free);
+    sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free);
+    OPENSSL_free(data);
+}
+
+/*
+ * Create a data based on an existing policy. If 'id' is NULL use the OID in
+ * the policy, otherwise use 'id'. This behaviour covers the two types of
+ * data in RFC3280: data with from a CertificatePolicies extension and
+ * additional data with just the qualifiers of anyPolicy and ID from another
+ * source.
+ */
+
+X509_POLICY_DATA *policy_data_new(POLICYINFO *policy,
+                                  const ASN1_OBJECT *cid, int crit)
+{
+    X509_POLICY_DATA *ret;
+    ASN1_OBJECT *id;
+    if (!policy && !cid)
+        return NULL;
+    if (cid) {
+        id = OBJ_dup(cid);
+        if (!id)
+            return NULL;
+    } else
+        id = NULL;
+    ret = OPENSSL_zalloc(sizeof(*ret));
+    if (ret == NULL)
+        return NULL;
+    ret->expected_policy_set = sk_ASN1_OBJECT_new_null();
+    if (ret->expected_policy_set == NULL) {
+        OPENSSL_free(ret);
+        ASN1_OBJECT_free(id);
+        return NULL;
+    }
+
+    if (crit)
+        ret->flags = POLICY_DATA_FLAG_CRITICAL;
+
+    if (id)
+        ret->valid_policy = id;
+    else {
+        ret->valid_policy = policy->policyid;
+        policy->policyid = NULL;
+    }
+
+    if (policy) {
+        ret->qualifier_set = policy->qualifiers;
+        policy->qualifiers = NULL;
+    }
+
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_int.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_int.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_int.h	(revision 331)
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2004-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
+ */
+
+typedef struct X509_POLICY_DATA_st X509_POLICY_DATA;
+
+DEFINE_STACK_OF(X509_POLICY_DATA)
+
+/* Internal structures */
+
+/*
+ * This structure and the field names correspond to the Policy 'node' of
+ * RFC3280. NB this structure contains no pointers to parent or child data:
+ * X509_POLICY_NODE contains that. This means that the main policy data can
+ * be kept static and cached with the certificate.
+ */
+
+struct X509_POLICY_DATA_st {
+    unsigned int flags;
+    /* Policy OID and qualifiers for this data */
+    ASN1_OBJECT *valid_policy;
+    STACK_OF(POLICYQUALINFO) *qualifier_set;
+    STACK_OF(ASN1_OBJECT) *expected_policy_set;
+};
+
+/* X509_POLICY_DATA flags values */
+
+/*
+ * This flag indicates the structure has been mapped using a policy mapping
+ * extension. If policy mapping is not active its references get deleted.
+ */
+
+#define POLICY_DATA_FLAG_MAPPED                 0x1
+
+/*
+ * This flag indicates the data doesn't correspond to a policy in Certificate
+ * Policies: it has been mapped to any policy.
+ */
+
+#define POLICY_DATA_FLAG_MAPPED_ANY             0x2
+
+/* AND with flags to see if any mapping has occurred */
+
+#define POLICY_DATA_FLAG_MAP_MASK               0x3
+
+/* qualifiers are shared and shouldn't be freed */
+
+#define POLICY_DATA_FLAG_SHARED_QUALIFIERS      0x4
+
+/* Parent node is an extra node and should be freed */
+
+#define POLICY_DATA_FLAG_EXTRA_NODE             0x8
+
+/* Corresponding CertificatePolicies is critical */
+
+#define POLICY_DATA_FLAG_CRITICAL               0x10
+
+/* This structure is cached with a certificate */
+
+struct X509_POLICY_CACHE_st {
+    /* anyPolicy data or NULL if no anyPolicy */
+    X509_POLICY_DATA *anyPolicy;
+    /* other policy data */
+    STACK_OF(X509_POLICY_DATA) *data;
+    /* If InhibitAnyPolicy present this is its value or -1 if absent. */
+    long any_skip;
+    /*
+     * If policyConstraints and requireExplicitPolicy present this is its
+     * value or -1 if absent.
+     */
+    long explicit_skip;
+    /*
+     * If policyConstraints and policyMapping present this is its value or -1
+     * if absent.
+     */
+    long map_skip;
+};
+
+/*
+ * #define POLICY_CACHE_FLAG_CRITICAL POLICY_DATA_FLAG_CRITICAL
+ */
+
+/* This structure represents the relationship between nodes */
+
+struct X509_POLICY_NODE_st {
+    /* node data this refers to */
+    const X509_POLICY_DATA *data;
+    /* Parent node */
+    X509_POLICY_NODE *parent;
+    /* Number of child nodes */
+    int nchild;
+};
+
+struct X509_POLICY_LEVEL_st {
+    /* Cert for this level */
+    X509 *cert;
+    /* nodes at this level */
+    STACK_OF(X509_POLICY_NODE) *nodes;
+    /* anyPolicy node */
+    X509_POLICY_NODE *anyPolicy;
+    /* Extra data */
+    /*
+     * STACK_OF(X509_POLICY_DATA) *extra_data;
+     */
+    unsigned int flags;
+};
+
+struct X509_POLICY_TREE_st {
+    /* This is the tree 'level' data */
+    X509_POLICY_LEVEL *levels;
+    int nlevel;
+    /*
+     * Extra policy data when additional nodes (not from the certificate) are
+     * required.
+     */
+    STACK_OF(X509_POLICY_DATA) *extra_data;
+    /* This is the authority constrained policy set */
+    STACK_OF(X509_POLICY_NODE) *auth_policies;
+    STACK_OF(X509_POLICY_NODE) *user_policies;
+    unsigned int flags;
+};
+
+/* Set if anyPolicy present in user policies */
+#define POLICY_FLAG_ANY_POLICY          0x2
+
+/* Useful macros */
+
+#define node_data_critical(data) (data->flags & POLICY_DATA_FLAG_CRITICAL)
+#define node_critical(node) node_data_critical(node->data)
+
+/* Internal functions */
+
+X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id,
+                                  int crit);
+void policy_data_free(X509_POLICY_DATA *data);
+
+X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache,
+                                         const ASN1_OBJECT *id);
+int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps);
+
+STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void);
+
+void policy_cache_init(void);
+
+void policy_cache_free(X509_POLICY_CACHE *cache);
+
+X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
+                                  const X509_POLICY_NODE *parent,
+                                  const ASN1_OBJECT *id);
+
+X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk,
+                               const ASN1_OBJECT *id);
+
+X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
+                                 X509_POLICY_DATA *data,
+                                 X509_POLICY_NODE *parent,
+                                 X509_POLICY_TREE *tree);
+void policy_node_free(X509_POLICY_NODE *node);
+int policy_node_match(const X509_POLICY_LEVEL *lvl,
+                      const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
+
+const X509_POLICY_CACHE *policy_cache_set(X509 *x);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_lib.c	(revision 331)
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2004-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 "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#include "pcy_int.h"
+
+/* accessor functions */
+
+/* X509_POLICY_TREE stuff */
+
+int X509_policy_tree_level_count(const X509_POLICY_TREE *tree)
+{
+    if (!tree)
+        return 0;
+    return tree->nlevel;
+}
+
+X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree,
+                                               int i)
+{
+    if (!tree || (i < 0) || (i >= tree->nlevel))
+        return NULL;
+    return tree->levels + i;
+}
+
+STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const
+                                                           X509_POLICY_TREE
+                                                           *tree)
+{
+    if (!tree)
+        return NULL;
+    return tree->auth_policies;
+}
+
+STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const
+                                                                X509_POLICY_TREE
+                                                                *tree)
+{
+    if (!tree)
+        return NULL;
+    if (tree->flags & POLICY_FLAG_ANY_POLICY)
+        return tree->auth_policies;
+    else
+        return tree->user_policies;
+}
+
+/* X509_POLICY_LEVEL stuff */
+
+int X509_policy_level_node_count(X509_POLICY_LEVEL *level)
+{
+    int n;
+    if (!level)
+        return 0;
+    if (level->anyPolicy)
+        n = 1;
+    else
+        n = 0;
+    if (level->nodes)
+        n += sk_X509_POLICY_NODE_num(level->nodes);
+    return n;
+}
+
+X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i)
+{
+    if (!level)
+        return NULL;
+    if (level->anyPolicy) {
+        if (i == 0)
+            return level->anyPolicy;
+        i--;
+    }
+    return sk_X509_POLICY_NODE_value(level->nodes, i);
+}
+
+/* X509_POLICY_NODE stuff */
+
+const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node)
+{
+    if (!node)
+        return NULL;
+    return node->data->valid_policy;
+}
+
+STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const
+                                                           X509_POLICY_NODE
+                                                           *node)
+{
+    if (!node)
+        return NULL;
+    return node->data->qualifier_set;
+}
+
+const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE
+                                                     *node)
+{
+    if (!node)
+        return NULL;
+    return node->parent;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_map.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_map.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_map.c	(revision 331)
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2004-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 "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include "internal/x509_int.h"
+
+#include "pcy_int.h"
+
+/*
+ * Set policy mapping entries in cache. Note: this modifies the passed
+ * POLICY_MAPPINGS structure
+ */
+
+int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps)
+{
+    POLICY_MAPPING *map;
+    X509_POLICY_DATA *data;
+    X509_POLICY_CACHE *cache = x->policy_cache;
+    int i;
+    int ret = 0;
+    if (sk_POLICY_MAPPING_num(maps) == 0) {
+        ret = -1;
+        goto bad_mapping;
+    }
+    for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) {
+        map = sk_POLICY_MAPPING_value(maps, i);
+        /* Reject if map to or from anyPolicy */
+        if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy)
+            || (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy)) {
+            ret = -1;
+            goto bad_mapping;
+        }
+
+        /* Attempt to find matching policy data */
+        data = policy_cache_find_data(cache, map->issuerDomainPolicy);
+        /* If we don't have anyPolicy can't map */
+        if (data == NULL && !cache->anyPolicy)
+            continue;
+
+        /* Create a NODE from anyPolicy */
+        if (data == NULL) {
+            data = policy_data_new(NULL, map->issuerDomainPolicy,
+                                   cache->anyPolicy->flags
+                                   & POLICY_DATA_FLAG_CRITICAL);
+            if (data == NULL)
+                goto bad_mapping;
+            data->qualifier_set = cache->anyPolicy->qualifier_set;
+            /*
+             * map->issuerDomainPolicy = NULL;
+             */
+            data->flags |= POLICY_DATA_FLAG_MAPPED_ANY;
+            data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
+            if (!sk_X509_POLICY_DATA_push(cache->data, data)) {
+                policy_data_free(data);
+                goto bad_mapping;
+            }
+        } else
+            data->flags |= POLICY_DATA_FLAG_MAPPED;
+        if (!sk_ASN1_OBJECT_push(data->expected_policy_set,
+                                 map->subjectDomainPolicy))
+            goto bad_mapping;
+        map->subjectDomainPolicy = NULL;
+
+    }
+
+    ret = 1;
+ bad_mapping:
+    if (ret == -1)
+        x->ex_flags |= EXFLAG_INVALID_POLICY;
+    sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free);
+    return ret;
+
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_node.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_node.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_node.c	(revision 331)
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2004-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 <openssl/asn1.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#include "pcy_int.h"
+
+static int node_cmp(const X509_POLICY_NODE *const *a,
+                    const X509_POLICY_NODE *const *b)
+{
+    return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy);
+}
+
+STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void)
+{
+    return sk_X509_POLICY_NODE_new(node_cmp);
+}
+
+X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes,
+                               const ASN1_OBJECT *id)
+{
+    X509_POLICY_DATA n;
+    X509_POLICY_NODE l;
+    int idx;
+
+    n.valid_policy = (ASN1_OBJECT *)id;
+    l.data = &n;
+
+    idx = sk_X509_POLICY_NODE_find(nodes, &l);
+    if (idx == -1)
+        return NULL;
+
+    return sk_X509_POLICY_NODE_value(nodes, idx);
+
+}
+
+X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
+                                  const X509_POLICY_NODE *parent,
+                                  const ASN1_OBJECT *id)
+{
+    X509_POLICY_NODE *node;
+    int i;
+    for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) {
+        node = sk_X509_POLICY_NODE_value(level->nodes, i);
+        if (node->parent == parent) {
+            if (!OBJ_cmp(node->data->valid_policy, id))
+                return node;
+        }
+    }
+    return NULL;
+}
+
+X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
+                                 X509_POLICY_DATA *data,
+                                 X509_POLICY_NODE *parent,
+                                 X509_POLICY_TREE *tree)
+{
+    X509_POLICY_NODE *node;
+
+    node = OPENSSL_zalloc(sizeof(*node));
+    if (node == NULL)
+        return NULL;
+    node->data = data;
+    node->parent = parent;
+    if (level) {
+        if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
+            if (level->anyPolicy)
+                goto node_error;
+            level->anyPolicy = node;
+        } else {
+
+            if (level->nodes == NULL)
+                level->nodes = policy_node_cmp_new();
+            if (level->nodes == NULL)
+                goto node_error;
+            if (!sk_X509_POLICY_NODE_push(level->nodes, node))
+                goto node_error;
+        }
+    }
+
+    if (tree) {
+        if (tree->extra_data == NULL)
+            tree->extra_data = sk_X509_POLICY_DATA_new_null();
+        if (tree->extra_data == NULL)
+            goto node_error;
+        if (!sk_X509_POLICY_DATA_push(tree->extra_data, data))
+            goto node_error;
+    }
+
+    if (parent)
+        parent->nchild++;
+
+    return node;
+
+ node_error:
+    policy_node_free(node);
+    return NULL;
+}
+
+void policy_node_free(X509_POLICY_NODE *node)
+{
+    OPENSSL_free(node);
+}
+
+/*
+ * See if a policy node matches a policy OID. If mapping enabled look through
+ * expected policy set otherwise just valid policy.
+ */
+
+int policy_node_match(const X509_POLICY_LEVEL *lvl,
+                      const X509_POLICY_NODE *node, const ASN1_OBJECT *oid)
+{
+    int i;
+    ASN1_OBJECT *policy_oid;
+    const X509_POLICY_DATA *x = node->data;
+
+    if ((lvl->flags & X509_V_FLAG_INHIBIT_MAP)
+        || !(x->flags & POLICY_DATA_FLAG_MAP_MASK)) {
+        if (!OBJ_cmp(x->valid_policy, oid))
+            return 1;
+        return 0;
+    }
+
+    for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++) {
+        policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i);
+        if (!OBJ_cmp(policy_oid, oid))
+            return 1;
+    }
+    return 0;
+
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_tree.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_tree.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/pcy_tree.c	(revision 331)
@@ -0,0 +1,696 @@
+/*
+ * Copyright 2004-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 "internal/cryptlib.h"
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+#include "pcy_int.h"
+
+/*
+ * Enable this to print out the complete policy tree at various point during
+ * evaluation.
+ */
+
+/*
+ * #define OPENSSL_POLICY_DEBUG
+ */
+
+#ifdef OPENSSL_POLICY_DEBUG
+
+static void expected_print(BIO *err, X509_POLICY_LEVEL *lev,
+                           X509_POLICY_NODE *node, int indent)
+{
+    if ((lev->flags & X509_V_FLAG_INHIBIT_MAP)
+        || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK))
+        BIO_puts(err, "  Not Mapped\n");
+    else {
+        int i;
+        STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set;
+        ASN1_OBJECT *oid;
+        BIO_puts(err, "  Expected: ");
+        for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) {
+            oid = sk_ASN1_OBJECT_value(pset, i);
+            if (i)
+                BIO_puts(err, ", ");
+            i2a_ASN1_OBJECT(err, oid);
+        }
+        BIO_puts(err, "\n");
+    }
+}
+
+static void tree_print(char *str, X509_POLICY_TREE *tree,
+                       X509_POLICY_LEVEL *curr)
+{
+    BIO *err = BIO_new_fp(stderr, BIO_NOCLOSE);
+    X509_POLICY_LEVEL *plev;
+
+    if (err == NULL)
+        return;
+    if (!curr)
+        curr = tree->levels + tree->nlevel;
+    else
+        curr++;
+
+    BIO_printf(err, "Level print after %s\n", str);
+    BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels);
+    for (plev = tree->levels; plev != curr; plev++) {
+        int i;
+
+        BIO_printf(err, "Level %ld, flags = %x\n",
+                   (long)(plev - tree->levels), plev->flags);
+        for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) {
+            X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(plev->nodes, i);
+
+            X509_POLICY_NODE_print(err, node, 2);
+            expected_print(err, plev, node, 2);
+            BIO_printf(err, "  Flags: %x\n", node->data->flags);
+        }
+        if (plev->anyPolicy)
+            X509_POLICY_NODE_print(err, plev->anyPolicy, 2);
+    }
+    BIO_free(err);
+}
+#endif
+
+/*-
+ * Return value: <= 0 on error, or positive bit mask:
+ *
+ * X509_PCY_TREE_VALID: valid tree
+ * X509_PCY_TREE_EMPTY: empty tree (including bare TA case)
+ * X509_PCY_TREE_EXPLICIT: explicit policy required
+ */
+static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
+                     unsigned int flags)
+{
+    X509_POLICY_TREE *tree;
+    X509_POLICY_LEVEL *level;
+    const X509_POLICY_CACHE *cache;
+    X509_POLICY_DATA *data = NULL;
+    int ret = X509_PCY_TREE_VALID;
+    int n = sk_X509_num(certs) - 1; /* RFC5280 paths omit the TA */
+    int explicit_policy = (flags & X509_V_FLAG_EXPLICIT_POLICY) ? 0 : n+1;
+    int any_skip = (flags & X509_V_FLAG_INHIBIT_ANY) ? 0 : n+1;
+    int map_skip = (flags & X509_V_FLAG_INHIBIT_MAP) ? 0 : n+1;
+    int i;
+
+    *ptree = NULL;
+
+    /* Can't do anything with just a trust anchor */
+    if (n == 0)
+        return X509_PCY_TREE_EMPTY;
+
+    /*
+     * First setup the policy cache in all n non-TA certificates, this will be
+     * used in X509_verify_cert() which will invoke the verify callback for all
+     * certificates with invalid policy extensions.
+     */
+    for (i = n - 1; i >= 0; i--) {
+        X509 *x = sk_X509_value(certs, i);
+
+        /* Call for side-effect of computing hash and caching extensions */
+        X509_check_purpose(x, -1, 0);
+
+        /* If cache is NULL, likely ENOMEM: return immediately */
+        if (policy_cache_set(x) == NULL)
+            return X509_PCY_TREE_INTERNAL;
+    }
+
+    /*
+     * At this point check for invalid policies and required explicit policy.
+     * Note that the explicit_policy counter is a count-down to zero, with the
+     * requirement kicking in if and once it does that.  The counter is
+     * decremented for every non-self-issued certificate in the path, but may
+     * be further reduced by policy constraints in a non-leaf certificate.
+     *
+     * The ultimate policy set is the intersection of all the policies along
+     * the path, if we hit a certificate with an empty policy set, and explicit
+     * policy is required we're done.
+     */
+    for (i = n - 1;
+         i >= 0 && (explicit_policy > 0 || (ret & X509_PCY_TREE_EMPTY) == 0);
+         i--) {
+        X509 *x = sk_X509_value(certs, i);
+        uint32_t ex_flags = X509_get_extension_flags(x);
+
+        /* All the policies are already cached, we can return early */
+        if (ex_flags & EXFLAG_INVALID_POLICY)
+            return X509_PCY_TREE_INVALID;
+
+        /* Access the cache which we now know exists */
+        cache = policy_cache_set(x);
+
+        if ((ret & X509_PCY_TREE_VALID) && cache->data == NULL)
+            ret = X509_PCY_TREE_EMPTY;
+        if (explicit_policy > 0) {
+            if (!(ex_flags & EXFLAG_SI))
+                explicit_policy--;
+            if ((cache->explicit_skip >= 0)
+                && (cache->explicit_skip < explicit_policy))
+                explicit_policy = cache->explicit_skip;
+        }
+    }
+
+    if (explicit_policy == 0)
+        ret |= X509_PCY_TREE_EXPLICIT;
+    if ((ret & X509_PCY_TREE_VALID) == 0)
+        return ret;
+
+    /* If we get this far initialize the tree */
+    if ((tree = OPENSSL_zalloc(sizeof(*tree))) == NULL)
+        return X509_PCY_TREE_INTERNAL;
+
+    /*
+     * http://tools.ietf.org/html/rfc5280#section-6.1.2, figure 3.
+     *
+     * The top level is implicitly for the trust anchor with valid expected
+     * policies of anyPolicy.  (RFC 5280 has the TA at depth 0 and the leaf at
+     * depth n, we have the leaf at depth 0 and the TA at depth n).
+     */
+    if ((tree->levels = OPENSSL_zalloc(sizeof(*tree->levels)*(n+1))) == NULL) {
+        OPENSSL_free(tree);
+        return X509_PCY_TREE_INTERNAL;
+    }
+    tree->nlevel = n+1;
+    level = tree->levels;
+    if ((data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0)) == NULL)
+        goto bad_tree;
+    if (level_add_node(level, data, NULL, tree) == NULL) {
+        policy_data_free(data);
+        goto bad_tree;
+    }
+
+    /*
+     * In this pass initialize all the tree levels and whether anyPolicy and
+     * policy mapping are inhibited at each level.
+     */
+    for (i = n - 1; i >= 0; i--) {
+        X509 *x = sk_X509_value(certs, i);
+        uint32_t ex_flags = X509_get_extension_flags(x);
+
+        /* Access the cache which we now know exists */
+        cache = policy_cache_set(x);
+
+        X509_up_ref(x);
+        (++level)->cert = x;
+
+        if (!cache->anyPolicy)
+            level->flags |= X509_V_FLAG_INHIBIT_ANY;
+
+        /* Determine inhibit any and inhibit map flags */
+        if (any_skip == 0) {
+            /*
+             * Any matching allowed only if certificate is self issued and not
+             * the last in the chain.
+             */
+            if (!(ex_flags & EXFLAG_SI) || (i == 0))
+                level->flags |= X509_V_FLAG_INHIBIT_ANY;
+        } else {
+            if (!(ex_flags & EXFLAG_SI))
+                any_skip--;
+            if ((cache->any_skip >= 0) && (cache->any_skip < any_skip))
+                any_skip = cache->any_skip;
+        }
+
+        if (map_skip == 0)
+            level->flags |= X509_V_FLAG_INHIBIT_MAP;
+        else {
+            if (!(ex_flags & EXFLAG_SI))
+                map_skip--;
+            if ((cache->map_skip >= 0) && (cache->map_skip < map_skip))
+                map_skip = cache->map_skip;
+        }
+    }
+
+    *ptree = tree;
+    return ret;
+
+ bad_tree:
+    X509_policy_tree_free(tree);
+    return X509_PCY_TREE_INTERNAL;
+}
+
+/*
+ * Return value: 1 on success, 0 otherwise
+ */
+static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
+                                    X509_POLICY_DATA *data)
+{
+    X509_POLICY_LEVEL *last = curr - 1;
+    int i, matched = 0;
+
+    /* Iterate through all in nodes linking matches */
+    for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
+        X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(last->nodes, i);
+
+        if (policy_node_match(last, node, data->valid_policy)) {
+            if (level_add_node(curr, data, node, NULL) == NULL)
+                return 0;
+            matched = 1;
+        }
+    }
+    if (!matched && last->anyPolicy) {
+        if (level_add_node(curr, data, last->anyPolicy, NULL) == NULL)
+            return 0;
+    }
+    return 1;
+}
+
+/*
+ * This corresponds to RFC3280 6.1.3(d)(1): link any data from
+ * CertificatePolicies onto matching parent or anyPolicy if no match.
+ *
+ * Return value: 1 on success, 0 otherwise.
+ */
+static int tree_link_nodes(X509_POLICY_LEVEL *curr,
+                           const X509_POLICY_CACHE *cache)
+{
+    int i;
+
+    for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) {
+        X509_POLICY_DATA *data = sk_X509_POLICY_DATA_value(cache->data, i);
+
+        /* Look for matching nodes in previous level */
+        if (!tree_link_matching_nodes(curr, data))
+            return 0;
+    }
+    return 1;
+}
+
+/*
+ * This corresponds to RFC3280 6.1.3(d)(2): Create new data for any unmatched
+ * policies in the parent and link to anyPolicy.
+ *
+ * Return value: 1 on success, 0 otherwise.
+ */
+static int tree_add_unmatched(X509_POLICY_LEVEL *curr,
+                              const X509_POLICY_CACHE *cache,
+                              const ASN1_OBJECT *id,
+                              X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
+{
+    X509_POLICY_DATA *data;
+
+    if (id == NULL)
+        id = node->data->valid_policy;
+    /*
+     * Create a new node with qualifiers from anyPolicy and id from unmatched
+     * node.
+     */
+    if ((data = policy_data_new(NULL, id, node_critical(node))) == NULL)
+        return 0;
+
+    /* Curr may not have anyPolicy */
+    data->qualifier_set = cache->anyPolicy->qualifier_set;
+    data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
+    if (level_add_node(curr, data, node, tree) == NULL) {
+        policy_data_free(data);
+        return 0;
+    }
+    return 1;
+}
+
+/*
+ * Return value: 1 on success, 0 otherwise.
+ */
+static int tree_link_unmatched(X509_POLICY_LEVEL *curr,
+                               const X509_POLICY_CACHE *cache,
+                               X509_POLICY_NODE *node, X509_POLICY_TREE *tree)
+{
+    const X509_POLICY_LEVEL *last = curr - 1;
+    int i;
+
+    if ((last->flags & X509_V_FLAG_INHIBIT_MAP)
+        || !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) {
+        /* If no policy mapping: matched if one child present */
+        if (node->nchild)
+            return 1;
+        if (!tree_add_unmatched(curr, cache, NULL, node, tree))
+            return 0;
+        /* Add it */
+    } else {
+        /* If mapping: matched if one child per expected policy set */
+        STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set;
+        if (node->nchild == sk_ASN1_OBJECT_num(expset))
+            return 1;
+        /* Locate unmatched nodes */
+        for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) {
+            ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i);
+            if (level_find_node(curr, node, oid))
+                continue;
+            if (!tree_add_unmatched(curr, cache, oid, node, tree))
+                return 0;
+        }
+
+    }
+    return 1;
+}
+
+/*
+ * Return value: 1 on success, 0 otherwise
+ */
+static int tree_link_any(X509_POLICY_LEVEL *curr,
+                         const X509_POLICY_CACHE *cache,
+                         X509_POLICY_TREE *tree)
+{
+    int i;
+    X509_POLICY_NODE *node;
+    X509_POLICY_LEVEL *last = curr - 1;
+
+    for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) {
+        node = sk_X509_POLICY_NODE_value(last->nodes, i);
+
+        if (!tree_link_unmatched(curr, cache, node, tree))
+            return 0;
+    }
+    /* Finally add link to anyPolicy */
+    if (last->anyPolicy &&
+        level_add_node(curr, cache->anyPolicy, last->anyPolicy, NULL) == NULL)
+        return 0;
+    return 1;
+}
+
+/*-
+ * Prune the tree: delete any child mapped child data on the current level then
+ * proceed up the tree deleting any data with no children. If we ever have no
+ * data on a level we can halt because the tree will be empty.
+ *
+ * Return value: <= 0 error, otherwise one of:
+ *
+ * X509_PCY_TREE_VALID: valid tree
+ * X509_PCY_TREE_EMPTY: empty tree
+ */
+static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr)
+{
+    STACK_OF(X509_POLICY_NODE) *nodes;
+    X509_POLICY_NODE *node;
+    int i;
+    nodes = curr->nodes;
+    if (curr->flags & X509_V_FLAG_INHIBIT_MAP) {
+        for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
+            node = sk_X509_POLICY_NODE_value(nodes, i);
+            /* Delete any mapped data: see RFC3280 XXXX */
+            if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) {
+                node->parent->nchild--;
+                OPENSSL_free(node);
+                (void)sk_X509_POLICY_NODE_delete(nodes, i);
+            }
+        }
+    }
+
+    for (;;) {
+        --curr;
+        nodes = curr->nodes;
+        for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) {
+            node = sk_X509_POLICY_NODE_value(nodes, i);
+            if (node->nchild == 0) {
+                node->parent->nchild--;
+                OPENSSL_free(node);
+                (void)sk_X509_POLICY_NODE_delete(nodes, i);
+            }
+        }
+        if (curr->anyPolicy && !curr->anyPolicy->nchild) {
+            if (curr->anyPolicy->parent)
+                curr->anyPolicy->parent->nchild--;
+            OPENSSL_free(curr->anyPolicy);
+            curr->anyPolicy = NULL;
+        }
+        if (curr == tree->levels) {
+            /* If we zapped anyPolicy at top then tree is empty */
+            if (!curr->anyPolicy)
+                return X509_PCY_TREE_EMPTY;
+            break;
+        }
+    }
+    return X509_PCY_TREE_VALID;
+}
+
+/*
+ * Return value: 1 on success, 0 otherwise.
+ */
+static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes,
+                              X509_POLICY_NODE *pcy)
+{
+    if (*pnodes == NULL &&
+        (*pnodes = policy_node_cmp_new()) == NULL)
+        return 0;
+    if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1)
+        return 1;
+    return sk_X509_POLICY_NODE_push(*pnodes, pcy) != 0;
+}
+
+#define TREE_CALC_FAILURE 0
+#define TREE_CALC_OK_NOFREE 1
+#define TREE_CALC_OK_DOFREE 2
+
+/*-
+ * Calculate the authority set based on policy tree. The 'pnodes' parameter is
+ * used as a store for the set of policy nodes used to calculate the user set.
+ * If the authority set is not anyPolicy then pnodes will just point to the
+ * authority set. If however the authority set is anyPolicy then the set of
+ * valid policies (other than anyPolicy) is store in pnodes.
+ *
+ * Return value:
+ *  TREE_CALC_FAILURE on failure,
+ *  TREE_CALC_OK_NOFREE on success and pnodes need not be freed,
+ *  TREE_CALC_OK_DOFREE on success and pnodes needs to be freed
+ */
+static int tree_calculate_authority_set(X509_POLICY_TREE *tree,
+                                        STACK_OF(X509_POLICY_NODE) **pnodes)
+{
+    X509_POLICY_LEVEL *curr;
+    X509_POLICY_NODE *node, *anyptr;
+    STACK_OF(X509_POLICY_NODE) **addnodes;
+    int i, j;
+    curr = tree->levels + tree->nlevel - 1;
+
+    /* If last level contains anyPolicy set is anyPolicy */
+    if (curr->anyPolicy) {
+        if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy))
+            return TREE_CALC_FAILURE;
+        addnodes = pnodes;
+    } else
+        /* Add policies to authority set */
+        addnodes = &tree->auth_policies;
+
+    curr = tree->levels;
+    for (i = 1; i < tree->nlevel; i++) {
+        /*
+         * If no anyPolicy node on this this level it can't appear on lower
+         * levels so end search.
+         */
+        if ((anyptr = curr->anyPolicy) == NULL)
+            break;
+        curr++;
+        for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) {
+            node = sk_X509_POLICY_NODE_value(curr->nodes, j);
+            if ((node->parent == anyptr)
+                && !tree_add_auth_node(addnodes, node)) {
+                if (addnodes == pnodes) {
+                    sk_X509_POLICY_NODE_free(*pnodes);
+                    *pnodes = NULL;
+                }
+                return TREE_CALC_FAILURE;
+            }
+        }
+    }
+    if (addnodes == pnodes)
+        return TREE_CALC_OK_DOFREE;
+
+    *pnodes = tree->auth_policies;
+    return TREE_CALC_OK_NOFREE;
+}
+
+/*
+ * Return value: 1 on success, 0 otherwise.
+ */
+static int tree_calculate_user_set(X509_POLICY_TREE *tree,
+                                   STACK_OF(ASN1_OBJECT) *policy_oids,
+                                   STACK_OF(X509_POLICY_NODE) *auth_nodes)
+{
+    int i;
+    X509_POLICY_NODE *node;
+    ASN1_OBJECT *oid;
+    X509_POLICY_NODE *anyPolicy;
+    X509_POLICY_DATA *extra;
+
+    /*
+     * Check if anyPolicy present in authority constrained policy set: this
+     * will happen if it is a leaf node.
+     */
+    if (sk_ASN1_OBJECT_num(policy_oids) <= 0)
+        return 1;
+
+    anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy;
+
+    for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
+        oid = sk_ASN1_OBJECT_value(policy_oids, i);
+        if (OBJ_obj2nid(oid) == NID_any_policy) {
+            tree->flags |= POLICY_FLAG_ANY_POLICY;
+            return 1;
+        }
+    }
+
+    for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) {
+        oid = sk_ASN1_OBJECT_value(policy_oids, i);
+        node = tree_find_sk(auth_nodes, oid);
+        if (!node) {
+            if (!anyPolicy)
+                continue;
+            /*
+             * Create a new node with policy ID from user set and qualifiers
+             * from anyPolicy.
+             */
+            extra = policy_data_new(NULL, oid, node_critical(anyPolicy));
+            if (extra == NULL)
+                return 0;
+            extra->qualifier_set = anyPolicy->data->qualifier_set;
+            extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
+                | POLICY_DATA_FLAG_EXTRA_NODE;
+            node = level_add_node(NULL, extra, anyPolicy->parent, tree);
+        }
+        if (!tree->user_policies) {
+            tree->user_policies = sk_X509_POLICY_NODE_new_null();
+            if (!tree->user_policies)
+                return 1;
+        }
+        if (!sk_X509_POLICY_NODE_push(tree->user_policies, node))
+            return 0;
+    }
+    return 1;
+}
+
+/*-
+ * Return value: <= 0 error, otherwise one of:
+ *  X509_PCY_TREE_VALID: valid tree
+ *  X509_PCY_TREE_EMPTY: empty tree
+ * (see tree_prune()).
+ */
+static int tree_evaluate(X509_POLICY_TREE *tree)
+{
+    int ret, i;
+    X509_POLICY_LEVEL *curr = tree->levels + 1;
+    const X509_POLICY_CACHE *cache;
+
+    for (i = 1; i < tree->nlevel; i++, curr++) {
+        cache = policy_cache_set(curr->cert);
+        if (!tree_link_nodes(curr, cache))
+            return X509_PCY_TREE_INTERNAL;
+
+        if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
+            && !tree_link_any(curr, cache, tree))
+            return X509_PCY_TREE_INTERNAL;
+#ifdef OPENSSL_POLICY_DEBUG
+        tree_print("before tree_prune()", tree, curr);
+#endif
+        ret = tree_prune(tree, curr);
+        if (ret != X509_PCY_TREE_VALID)
+            return ret;
+    }
+    return X509_PCY_TREE_VALID;
+}
+
+static void exnode_free(X509_POLICY_NODE *node)
+{
+    if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE))
+        OPENSSL_free(node);
+}
+
+void X509_policy_tree_free(X509_POLICY_TREE *tree)
+{
+    X509_POLICY_LEVEL *curr;
+    int i;
+
+    if (!tree)
+        return;
+
+    sk_X509_POLICY_NODE_free(tree->auth_policies);
+    sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free);
+
+    for (i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) {
+        X509_free(curr->cert);
+        sk_X509_POLICY_NODE_pop_free(curr->nodes, policy_node_free);
+        policy_node_free(curr->anyPolicy);
+    }
+
+    sk_X509_POLICY_DATA_pop_free(tree->extra_data, policy_data_free);
+    OPENSSL_free(tree->levels);
+    OPENSSL_free(tree);
+
+}
+
+/*-
+ * Application policy checking function.
+ * Return codes:
+ *  X509_PCY_TREE_FAILURE:  Failure to satisfy explicit policy
+ *  X509_PCY_TREE_INVALID:  Inconsistent or invalid extensions
+ *  X509_PCY_TREE_INTERNAL: Internal error, most likely malloc
+ *  X509_PCY_TREE_VALID:    Success (null tree if empty or bare TA)
+ */
+int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
+                      STACK_OF(X509) *certs,
+                      STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags)
+{
+    int init_ret;
+    int ret;
+    X509_POLICY_TREE *tree = NULL;
+    STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL;
+
+    *ptree = NULL;
+    *pexplicit_policy = 0;
+    init_ret = tree_init(&tree, certs, flags);
+
+    if (init_ret <= 0)
+        return init_ret;
+
+    if ((init_ret & X509_PCY_TREE_EXPLICIT) == 0) {
+        if (init_ret & X509_PCY_TREE_EMPTY) {
+            X509_policy_tree_free(tree);
+            return X509_PCY_TREE_VALID;
+        }
+    } else {
+        *pexplicit_policy = 1;
+        /* Tree empty and requireExplicit True: Error */
+        if (init_ret & X509_PCY_TREE_EMPTY)
+            return X509_PCY_TREE_FAILURE;
+    }
+
+    ret = tree_evaluate(tree);
+#ifdef OPENSSL_POLICY_DEBUG
+    tree_print("tree_evaluate()", tree, NULL);
+#endif
+    if (ret <= 0)
+        goto error;
+
+    if (ret == X509_PCY_TREE_EMPTY) {
+        X509_policy_tree_free(tree);
+        if (init_ret & X509_PCY_TREE_EXPLICIT)
+            return X509_PCY_TREE_FAILURE;
+        return X509_PCY_TREE_VALID;
+    }
+
+    /* Tree is not empty: continue */
+    if ((ret = tree_calculate_authority_set(tree, &auth_nodes)) == 0 ||
+        !tree_calculate_user_set(tree, policy_oids, auth_nodes))
+        goto error;
+    if (ret == TREE_CALC_OK_DOFREE)
+        sk_X509_POLICY_NODE_free(auth_nodes);
+
+    *ptree = tree;
+
+    if (init_ret & X509_PCY_TREE_EXPLICIT) {
+        nodes = X509_policy_tree_get0_user_policies(tree);
+        if (sk_X509_POLICY_NODE_num(nodes) <= 0)
+            return X509_PCY_TREE_FAILURE;
+    }
+    return X509_PCY_TREE_VALID;
+
+ error:
+    X509_policy_tree_free(tree);
+    return X509_PCY_TREE_INTERNAL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_addr.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_addr.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_addr.c	(revision 331)
@@ -0,0 +1,1305 @@
+/*
+ * Copyright 2006-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
+ */
+
+/*
+ * Implementation of RFC 3779 section 2.2.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/buffer.h>
+#include <openssl/x509v3.h>
+#include "internal/x509_int.h"
+#include "ext_dat.h"
+
+#ifndef OPENSSL_NO_RFC3779
+
+/*
+ * OpenSSL ASN.1 template translation of RFC 3779 2.2.3.
+ */
+
+ASN1_SEQUENCE(IPAddressRange) = {
+  ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING),
+  ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END(IPAddressRange)
+
+ASN1_CHOICE(IPAddressOrRange) = {
+  ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING),
+  ASN1_SIMPLE(IPAddressOrRange, u.addressRange,  IPAddressRange)
+} ASN1_CHOICE_END(IPAddressOrRange)
+
+ASN1_CHOICE(IPAddressChoice) = {
+  ASN1_SIMPLE(IPAddressChoice,      u.inherit,           ASN1_NULL),
+  ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange)
+} ASN1_CHOICE_END(IPAddressChoice)
+
+ASN1_SEQUENCE(IPAddressFamily) = {
+  ASN1_SIMPLE(IPAddressFamily, addressFamily,   ASN1_OCTET_STRING),
+  ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice)
+} ASN1_SEQUENCE_END(IPAddressFamily)
+
+ASN1_ITEM_TEMPLATE(IPAddrBlocks) =
+  ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0,
+                        IPAddrBlocks, IPAddressFamily)
+static_ASN1_ITEM_TEMPLATE_END(IPAddrBlocks)
+
+IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange)
+IMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange)
+IMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice)
+IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily)
+
+/*
+ * How much buffer space do we need for a raw address?
+ */
+#define ADDR_RAW_BUF_LEN        16
+
+/*
+ * What's the address length associated with this AFI?
+ */
+static int length_from_afi(const unsigned afi)
+{
+    switch (afi) {
+    case IANA_AFI_IPV4:
+        return 4;
+    case IANA_AFI_IPV6:
+        return 16;
+    default:
+        return 0;
+    }
+}
+
+/*
+ * Extract the AFI from an IPAddressFamily.
+ */
+unsigned int X509v3_addr_get_afi(const IPAddressFamily *f)
+{
+    return ((f != NULL &&
+             f->addressFamily != NULL && f->addressFamily->data != NULL)
+            ? ((f->addressFamily->data[0] << 8) | (f->addressFamily->data[1]))
+            : 0);
+}
+
+/*
+ * Expand the bitstring form of an address into a raw byte array.
+ * At the moment this is coded for simplicity, not speed.
+ */
+static int addr_expand(unsigned char *addr,
+                       const ASN1_BIT_STRING *bs,
+                       const int length, const unsigned char fill)
+{
+    if (bs->length < 0 || bs->length > length)
+        return 0;
+    if (bs->length > 0) {
+        memcpy(addr, bs->data, bs->length);
+        if ((bs->flags & 7) != 0) {
+            unsigned char mask = 0xFF >> (8 - (bs->flags & 7));
+            if (fill == 0)
+                addr[bs->length - 1] &= ~mask;
+            else
+                addr[bs->length - 1] |= mask;
+        }
+    }
+    memset(addr + bs->length, fill, length - bs->length);
+    return 1;
+}
+
+/*
+ * Extract the prefix length from a bitstring.
+ */
+#define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7)))
+
+/*
+ * i2r handler for one address bitstring.
+ */
+static int i2r_address(BIO *out,
+                       const unsigned afi,
+                       const unsigned char fill, const ASN1_BIT_STRING *bs)
+{
+    unsigned char addr[ADDR_RAW_BUF_LEN];
+    int i, n;
+
+    if (bs->length < 0)
+        return 0;
+    switch (afi) {
+    case IANA_AFI_IPV4:
+        if (!addr_expand(addr, bs, 4, fill))
+            return 0;
+        BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
+        break;
+    case IANA_AFI_IPV6:
+        if (!addr_expand(addr, bs, 16, fill))
+            return 0;
+        for (n = 16; n > 1 && addr[n - 1] == 0x00 && addr[n - 2] == 0x00;
+             n -= 2) ;
+        for (i = 0; i < n; i += 2)
+            BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i + 1],
+                       (i < 14 ? ":" : ""));
+        if (i < 16)
+            BIO_puts(out, ":");
+        if (i == 0)
+            BIO_puts(out, ":");
+        break;
+    default:
+        for (i = 0; i < bs->length; i++)
+            BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]);
+        BIO_printf(out, "[%d]", (int)(bs->flags & 7));
+        break;
+    }
+    return 1;
+}
+
+/*
+ * i2r handler for a sequence of addresses and ranges.
+ */
+static int i2r_IPAddressOrRanges(BIO *out,
+                                 const int indent,
+                                 const IPAddressOrRanges *aors,
+                                 const unsigned afi)
+{
+    int i;
+    for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) {
+        const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i);
+        BIO_printf(out, "%*s", indent, "");
+        switch (aor->type) {
+        case IPAddressOrRange_addressPrefix:
+            if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix))
+                return 0;
+            BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix));
+            continue;
+        case IPAddressOrRange_addressRange:
+            if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min))
+                return 0;
+            BIO_puts(out, "-");
+            if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max))
+                return 0;
+            BIO_puts(out, "\n");
+            continue;
+        }
+    }
+    return 1;
+}
+
+/*
+ * i2r handler for an IPAddrBlocks extension.
+ */
+static int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method,
+                            void *ext, BIO *out, int indent)
+{
+    const IPAddrBlocks *addr = ext;
+    int i;
+    for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+        IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
+        const unsigned int afi = X509v3_addr_get_afi(f);
+        switch (afi) {
+        case IANA_AFI_IPV4:
+            BIO_printf(out, "%*sIPv4", indent, "");
+            break;
+        case IANA_AFI_IPV6:
+            BIO_printf(out, "%*sIPv6", indent, "");
+            break;
+        default:
+            BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi);
+            break;
+        }
+        if (f->addressFamily->length > 2) {
+            switch (f->addressFamily->data[2]) {
+            case 1:
+                BIO_puts(out, " (Unicast)");
+                break;
+            case 2:
+                BIO_puts(out, " (Multicast)");
+                break;
+            case 3:
+                BIO_puts(out, " (Unicast/Multicast)");
+                break;
+            case 4:
+                BIO_puts(out, " (MPLS)");
+                break;
+            case 64:
+                BIO_puts(out, " (Tunnel)");
+                break;
+            case 65:
+                BIO_puts(out, " (VPLS)");
+                break;
+            case 66:
+                BIO_puts(out, " (BGP MDT)");
+                break;
+            case 128:
+                BIO_puts(out, " (MPLS-labeled VPN)");
+                break;
+            default:
+                BIO_printf(out, " (Unknown SAFI %u)",
+                           (unsigned)f->addressFamily->data[2]);
+                break;
+            }
+        }
+        switch (f->ipAddressChoice->type) {
+        case IPAddressChoice_inherit:
+            BIO_puts(out, ": inherit\n");
+            break;
+        case IPAddressChoice_addressesOrRanges:
+            BIO_puts(out, ":\n");
+            if (!i2r_IPAddressOrRanges(out,
+                                       indent + 2,
+                                       f->ipAddressChoice->
+                                       u.addressesOrRanges, afi))
+                return 0;
+            break;
+        }
+    }
+    return 1;
+}
+
+/*
+ * Sort comparison function for a sequence of IPAddressOrRange
+ * elements.
+ *
+ * There's no sane answer we can give if addr_expand() fails, and an
+ * assertion failure on externally supplied data is seriously uncool,
+ * so we just arbitrarily declare that if given invalid inputs this
+ * function returns -1.  If this messes up your preferred sort order
+ * for garbage input, tough noogies.
+ */
+static int IPAddressOrRange_cmp(const IPAddressOrRange *a,
+                                const IPAddressOrRange *b, const int length)
+{
+    unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN];
+    int prefixlen_a = 0, prefixlen_b = 0;
+    int r;
+
+    switch (a->type) {
+    case IPAddressOrRange_addressPrefix:
+        if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00))
+            return -1;
+        prefixlen_a = addr_prefixlen(a->u.addressPrefix);
+        break;
+    case IPAddressOrRange_addressRange:
+        if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00))
+            return -1;
+        prefixlen_a = length * 8;
+        break;
+    }
+
+    switch (b->type) {
+    case IPAddressOrRange_addressPrefix:
+        if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00))
+            return -1;
+        prefixlen_b = addr_prefixlen(b->u.addressPrefix);
+        break;
+    case IPAddressOrRange_addressRange:
+        if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00))
+            return -1;
+        prefixlen_b = length * 8;
+        break;
+    }
+
+    if ((r = memcmp(addr_a, addr_b, length)) != 0)
+        return r;
+    else
+        return prefixlen_a - prefixlen_b;
+}
+
+/*
+ * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort()
+ * comparison routines are only allowed two arguments.
+ */
+static int v4IPAddressOrRange_cmp(const IPAddressOrRange *const *a,
+                                  const IPAddressOrRange *const *b)
+{
+    return IPAddressOrRange_cmp(*a, *b, 4);
+}
+
+/*
+ * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort()
+ * comparison routines are only allowed two arguments.
+ */
+static int v6IPAddressOrRange_cmp(const IPAddressOrRange *const *a,
+                                  const IPAddressOrRange *const *b)
+{
+    return IPAddressOrRange_cmp(*a, *b, 16);
+}
+
+/*
+ * Calculate whether a range collapses to a prefix.
+ * See last paragraph of RFC 3779 2.2.3.7.
+ */
+static int range_should_be_prefix(const unsigned char *min,
+                                  const unsigned char *max, const int length)
+{
+    unsigned char mask;
+    int i, j;
+
+    OPENSSL_assert(memcmp(min, max, length) <= 0);
+    for (i = 0; i < length && min[i] == max[i]; i++) ;
+    for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--) ;
+    if (i < j)
+        return -1;
+    if (i > j)
+        return i * 8;
+    mask = min[i] ^ max[i];
+    switch (mask) {
+    case 0x01:
+        j = 7;
+        break;
+    case 0x03:
+        j = 6;
+        break;
+    case 0x07:
+        j = 5;
+        break;
+    case 0x0F:
+        j = 4;
+        break;
+    case 0x1F:
+        j = 3;
+        break;
+    case 0x3F:
+        j = 2;
+        break;
+    case 0x7F:
+        j = 1;
+        break;
+    default:
+        return -1;
+    }
+    if ((min[i] & mask) != 0 || (max[i] & mask) != mask)
+        return -1;
+    else
+        return i * 8 + j;
+}
+
+/*
+ * Construct a prefix.
+ */
+static int make_addressPrefix(IPAddressOrRange **result,
+                              unsigned char *addr, const int prefixlen)
+{
+    int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8;
+    IPAddressOrRange *aor = IPAddressOrRange_new();
+
+    if (aor == NULL)
+        return 0;
+    aor->type = IPAddressOrRange_addressPrefix;
+    if (aor->u.addressPrefix == NULL &&
+        (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL)
+        goto err;
+    if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen))
+        goto err;
+    aor->u.addressPrefix->flags &= ~7;
+    aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+    if (bitlen > 0) {
+        aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen);
+        aor->u.addressPrefix->flags |= 8 - bitlen;
+    }
+
+    *result = aor;
+    return 1;
+
+ err:
+    IPAddressOrRange_free(aor);
+    return 0;
+}
+
+/*
+ * Construct a range.  If it can be expressed as a prefix,
+ * return a prefix instead.  Doing this here simplifies
+ * the rest of the code considerably.
+ */
+static int make_addressRange(IPAddressOrRange **result,
+                             unsigned char *min,
+                             unsigned char *max, const int length)
+{
+    IPAddressOrRange *aor;
+    int i, prefixlen;
+
+    if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0)
+        return make_addressPrefix(result, min, prefixlen);
+
+    if ((aor = IPAddressOrRange_new()) == NULL)
+        return 0;
+    aor->type = IPAddressOrRange_addressRange;
+    OPENSSL_assert(aor->u.addressRange == NULL);
+    if ((aor->u.addressRange = IPAddressRange_new()) == NULL)
+        goto err;
+    if (aor->u.addressRange->min == NULL &&
+        (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL)
+        goto err;
+    if (aor->u.addressRange->max == NULL &&
+        (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL)
+        goto err;
+
+    for (i = length; i > 0 && min[i - 1] == 0x00; --i) ;
+    if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i))
+        goto err;
+    aor->u.addressRange->min->flags &= ~7;
+    aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+    if (i > 0) {
+        unsigned char b = min[i - 1];
+        int j = 1;
+        while ((b & (0xFFU >> j)) != 0)
+            ++j;
+        aor->u.addressRange->min->flags |= 8 - j;
+    }
+
+    for (i = length; i > 0 && max[i - 1] == 0xFF; --i) ;
+    if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i))
+        goto err;
+    aor->u.addressRange->max->flags &= ~7;
+    aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+    if (i > 0) {
+        unsigned char b = max[i - 1];
+        int j = 1;
+        while ((b & (0xFFU >> j)) != (0xFFU >> j))
+            ++j;
+        aor->u.addressRange->max->flags |= 8 - j;
+    }
+
+    *result = aor;
+    return 1;
+
+ err:
+    IPAddressOrRange_free(aor);
+    return 0;
+}
+
+/*
+ * Construct a new address family or find an existing one.
+ */
+static IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr,
+                                             const unsigned afi,
+                                             const unsigned *safi)
+{
+    IPAddressFamily *f;
+    unsigned char key[3];
+    int keylen;
+    int i;
+
+    key[0] = (afi >> 8) & 0xFF;
+    key[1] = afi & 0xFF;
+    if (safi != NULL) {
+        key[2] = *safi & 0xFF;
+        keylen = 3;
+    } else {
+        keylen = 2;
+    }
+
+    for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+        f = sk_IPAddressFamily_value(addr, i);
+        OPENSSL_assert(f->addressFamily->data != NULL);
+        if (f->addressFamily->length == keylen &&
+            !memcmp(f->addressFamily->data, key, keylen))
+            return f;
+    }
+
+    if ((f = IPAddressFamily_new()) == NULL)
+        goto err;
+    if (f->ipAddressChoice == NULL &&
+        (f->ipAddressChoice = IPAddressChoice_new()) == NULL)
+        goto err;
+    if (f->addressFamily == NULL &&
+        (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL)
+        goto err;
+    if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen))
+        goto err;
+    if (!sk_IPAddressFamily_push(addr, f))
+        goto err;
+
+    return f;
+
+ err:
+    IPAddressFamily_free(f);
+    return NULL;
+}
+
+/*
+ * Add an inheritance element.
+ */
+int X509v3_addr_add_inherit(IPAddrBlocks *addr,
+                            const unsigned afi, const unsigned *safi)
+{
+    IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
+    if (f == NULL ||
+        f->ipAddressChoice == NULL ||
+        (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
+         f->ipAddressChoice->u.addressesOrRanges != NULL))
+        return 0;
+    if (f->ipAddressChoice->type == IPAddressChoice_inherit &&
+        f->ipAddressChoice->u.inherit != NULL)
+        return 1;
+    if (f->ipAddressChoice->u.inherit == NULL &&
+        (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL)
+        return 0;
+    f->ipAddressChoice->type = IPAddressChoice_inherit;
+    return 1;
+}
+
+/*
+ * Construct an IPAddressOrRange sequence, or return an existing one.
+ */
+static IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr,
+                                               const unsigned afi,
+                                               const unsigned *safi)
+{
+    IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi);
+    IPAddressOrRanges *aors = NULL;
+
+    if (f == NULL ||
+        f->ipAddressChoice == NULL ||
+        (f->ipAddressChoice->type == IPAddressChoice_inherit &&
+         f->ipAddressChoice->u.inherit != NULL))
+        return NULL;
+    if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges)
+        aors = f->ipAddressChoice->u.addressesOrRanges;
+    if (aors != NULL)
+        return aors;
+    if ((aors = sk_IPAddressOrRange_new_null()) == NULL)
+        return NULL;
+    switch (afi) {
+    case IANA_AFI_IPV4:
+        (void)sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp);
+        break;
+    case IANA_AFI_IPV6:
+        (void)sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp);
+        break;
+    }
+    f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges;
+    f->ipAddressChoice->u.addressesOrRanges = aors;
+    return aors;
+}
+
+/*
+ * Add a prefix.
+ */
+int X509v3_addr_add_prefix(IPAddrBlocks *addr,
+                           const unsigned afi,
+                           const unsigned *safi,
+                           unsigned char *a, const int prefixlen)
+{
+    IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
+    IPAddressOrRange *aor;
+    if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen))
+        return 0;
+    if (sk_IPAddressOrRange_push(aors, aor))
+        return 1;
+    IPAddressOrRange_free(aor);
+    return 0;
+}
+
+/*
+ * Add a range.
+ */
+int X509v3_addr_add_range(IPAddrBlocks *addr,
+                          const unsigned afi,
+                          const unsigned *safi,
+                          unsigned char *min, unsigned char *max)
+{
+    IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
+    IPAddressOrRange *aor;
+    int length = length_from_afi(afi);
+    if (aors == NULL)
+        return 0;
+    if (!make_addressRange(&aor, min, max, length))
+        return 0;
+    if (sk_IPAddressOrRange_push(aors, aor))
+        return 1;
+    IPAddressOrRange_free(aor);
+    return 0;
+}
+
+/*
+ * Extract min and max values from an IPAddressOrRange.
+ */
+static int extract_min_max(IPAddressOrRange *aor,
+                           unsigned char *min, unsigned char *max, int length)
+{
+    if (aor == NULL || min == NULL || max == NULL)
+        return 0;
+    switch (aor->type) {
+    case IPAddressOrRange_addressPrefix:
+        return (addr_expand(min, aor->u.addressPrefix, length, 0x00) &&
+                addr_expand(max, aor->u.addressPrefix, length, 0xFF));
+    case IPAddressOrRange_addressRange:
+        return (addr_expand(min, aor->u.addressRange->min, length, 0x00) &&
+                addr_expand(max, aor->u.addressRange->max, length, 0xFF));
+    }
+    return 0;
+}
+
+/*
+ * Public wrapper for extract_min_max().
+ */
+int X509v3_addr_get_range(IPAddressOrRange *aor,
+                          const unsigned afi,
+                          unsigned char *min,
+                          unsigned char *max, const int length)
+{
+    int afi_length = length_from_afi(afi);
+    if (aor == NULL || min == NULL || max == NULL ||
+        afi_length == 0 || length < afi_length ||
+        (aor->type != IPAddressOrRange_addressPrefix &&
+         aor->type != IPAddressOrRange_addressRange) ||
+        !extract_min_max(aor, min, max, afi_length))
+        return 0;
+
+    return afi_length;
+}
+
+/*
+ * Sort comparison function for a sequence of IPAddressFamily.
+ *
+ * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about
+ * the ordering: I can read it as meaning that IPv6 without a SAFI
+ * comes before IPv4 with a SAFI, which seems pretty weird.  The
+ * examples in appendix B suggest that the author intended the
+ * null-SAFI rule to apply only within a single AFI, which is what I
+ * would have expected and is what the following code implements.
+ */
+static int IPAddressFamily_cmp(const IPAddressFamily *const *a_,
+                               const IPAddressFamily *const *b_)
+{
+    const ASN1_OCTET_STRING *a = (*a_)->addressFamily;
+    const ASN1_OCTET_STRING *b = (*b_)->addressFamily;
+    int len = ((a->length <= b->length) ? a->length : b->length);
+    int cmp = memcmp(a->data, b->data, len);
+    return cmp ? cmp : a->length - b->length;
+}
+
+/*
+ * Check whether an IPAddrBLocks is in canonical form.
+ */
+int X509v3_addr_is_canonical(IPAddrBlocks *addr)
+{
+    unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
+    unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
+    IPAddressOrRanges *aors;
+    int i, j, k;
+
+    /*
+     * Empty extension is canonical.
+     */
+    if (addr == NULL)
+        return 1;
+
+    /*
+     * Check whether the top-level list is in order.
+     */
+    for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) {
+        const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i);
+        const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1);
+        if (IPAddressFamily_cmp(&a, &b) >= 0)
+            return 0;
+    }
+
+    /*
+     * Top level's ok, now check each address family.
+     */
+    for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+        IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
+        int length = length_from_afi(X509v3_addr_get_afi(f));
+
+        /*
+         * Inheritance is canonical.  Anything other than inheritance or
+         * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something.
+         */
+        if (f == NULL || f->ipAddressChoice == NULL)
+            return 0;
+        switch (f->ipAddressChoice->type) {
+        case IPAddressChoice_inherit:
+            continue;
+        case IPAddressChoice_addressesOrRanges:
+            break;
+        default:
+            return 0;
+        }
+
+        /*
+         * It's an IPAddressOrRanges sequence, check it.
+         */
+        aors = f->ipAddressChoice->u.addressesOrRanges;
+        if (sk_IPAddressOrRange_num(aors) == 0)
+            return 0;
+        for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) {
+            IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
+            IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1);
+
+            if (!extract_min_max(a, a_min, a_max, length) ||
+                !extract_min_max(b, b_min, b_max, length))
+                return 0;
+
+            /*
+             * Punt misordered list, overlapping start, or inverted range.
+             */
+            if (memcmp(a_min, b_min, length) >= 0 ||
+                memcmp(a_min, a_max, length) > 0 ||
+                memcmp(b_min, b_max, length) > 0)
+                return 0;
+
+            /*
+             * Punt if adjacent or overlapping.  Check for adjacency by
+             * subtracting one from b_min first.
+             */
+            for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--) ;
+            if (memcmp(a_max, b_min, length) >= 0)
+                return 0;
+
+            /*
+             * Check for range that should be expressed as a prefix.
+             */
+            if (a->type == IPAddressOrRange_addressRange &&
+                range_should_be_prefix(a_min, a_max, length) >= 0)
+                return 0;
+        }
+
+        /*
+         * Check range to see if it's inverted or should be a
+         * prefix.
+         */
+        j = sk_IPAddressOrRange_num(aors) - 1;
+        {
+            IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
+            if (a != NULL && a->type == IPAddressOrRange_addressRange) {
+                if (!extract_min_max(a, a_min, a_max, length))
+                    return 0;
+                if (memcmp(a_min, a_max, length) > 0 ||
+                    range_should_be_prefix(a_min, a_max, length) >= 0)
+                    return 0;
+            }
+        }
+    }
+
+    /*
+     * If we made it through all that, we're happy.
+     */
+    return 1;
+}
+
+/*
+ * Whack an IPAddressOrRanges into canonical form.
+ */
+static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors,
+                                      const unsigned afi)
+{
+    int i, j, length = length_from_afi(afi);
+
+    /*
+     * Sort the IPAddressOrRanges sequence.
+     */
+    sk_IPAddressOrRange_sort(aors);
+
+    /*
+     * Clean up representation issues, punt on duplicates or overlaps.
+     */
+    for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) {
+        IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i);
+        IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1);
+        unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
+        unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN];
+
+        if (!extract_min_max(a, a_min, a_max, length) ||
+            !extract_min_max(b, b_min, b_max, length))
+            return 0;
+
+        /*
+         * Punt inverted ranges.
+         */
+        if (memcmp(a_min, a_max, length) > 0 ||
+            memcmp(b_min, b_max, length) > 0)
+            return 0;
+
+        /*
+         * Punt overlaps.
+         */
+        if (memcmp(a_max, b_min, length) >= 0)
+            return 0;
+
+        /*
+         * Merge if a and b are adjacent.  We check for
+         * adjacency by subtracting one from b_min first.
+         */
+        for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--) ;
+        if (memcmp(a_max, b_min, length) == 0) {
+            IPAddressOrRange *merged;
+            if (!make_addressRange(&merged, a_min, b_max, length))
+                return 0;
+            (void)sk_IPAddressOrRange_set(aors, i, merged);
+            (void)sk_IPAddressOrRange_delete(aors, i + 1);
+            IPAddressOrRange_free(a);
+            IPAddressOrRange_free(b);
+            --i;
+            continue;
+        }
+    }
+
+    /*
+     * Check for inverted final range.
+     */
+    j = sk_IPAddressOrRange_num(aors) - 1;
+    {
+        IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
+        if (a != NULL && a->type == IPAddressOrRange_addressRange) {
+            unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
+            if (!extract_min_max(a, a_min, a_max, length))
+                return 0;
+            if (memcmp(a_min, a_max, length) > 0)
+                return 0;
+        }
+    }
+
+    return 1;
+}
+
+/*
+ * Whack an IPAddrBlocks extension into canonical form.
+ */
+int X509v3_addr_canonize(IPAddrBlocks *addr)
+{
+    int i;
+    for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+        IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
+        if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges &&
+            !IPAddressOrRanges_canonize(f->ipAddressChoice->
+                                        u.addressesOrRanges,
+                                        X509v3_addr_get_afi(f)))
+            return 0;
+    }
+    (void)sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp);
+    sk_IPAddressFamily_sort(addr);
+    OPENSSL_assert(X509v3_addr_is_canonical(addr));
+    return 1;
+}
+
+/*
+ * v2i handler for the IPAddrBlocks extension.
+ */
+static void *v2i_IPAddrBlocks(const struct v3_ext_method *method,
+                              struct v3_ext_ctx *ctx,
+                              STACK_OF(CONF_VALUE) *values)
+{
+    static const char v4addr_chars[] = "0123456789.";
+    static const char v6addr_chars[] = "0123456789.:abcdefABCDEF";
+    IPAddrBlocks *addr = NULL;
+    char *s = NULL, *t;
+    int i;
+
+    if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) {
+        X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+        CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
+        unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN];
+        unsigned afi, *safi = NULL, safi_;
+        const char *addr_chars = NULL;
+        int prefixlen, i1, i2, delim, length;
+
+        if (!name_cmp(val->name, "IPv4")) {
+            afi = IANA_AFI_IPV4;
+        } else if (!name_cmp(val->name, "IPv6")) {
+            afi = IANA_AFI_IPV6;
+        } else if (!name_cmp(val->name, "IPv4-SAFI")) {
+            afi = IANA_AFI_IPV4;
+            safi = &safi_;
+        } else if (!name_cmp(val->name, "IPv6-SAFI")) {
+            afi = IANA_AFI_IPV6;
+            safi = &safi_;
+        } else {
+            X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
+                      X509V3_R_EXTENSION_NAME_ERROR);
+            X509V3_conf_err(val);
+            goto err;
+        }
+
+        switch (afi) {
+        case IANA_AFI_IPV4:
+            addr_chars = v4addr_chars;
+            break;
+        case IANA_AFI_IPV6:
+            addr_chars = v6addr_chars;
+            break;
+        }
+
+        length = length_from_afi(afi);
+
+        /*
+         * Handle SAFI, if any, and OPENSSL_strdup() so we can null-terminate
+         * the other input values.
+         */
+        if (safi != NULL) {
+            *safi = strtoul(val->value, &t, 0);
+            t += strspn(t, " \t");
+            if (*safi > 0xFF || *t++ != ':') {
+                X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI);
+                X509V3_conf_err(val);
+                goto err;
+            }
+            t += strspn(t, " \t");
+            s = OPENSSL_strdup(t);
+        } else {
+            s = OPENSSL_strdup(val->value);
+        }
+        if (s == NULL) {
+            X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+
+        /*
+         * Check for inheritance.  Not worth additional complexity to
+         * optimize this (seldom-used) case.
+         */
+        if (strcmp(s, "inherit") == 0) {
+            if (!X509v3_addr_add_inherit(addr, afi, safi)) {
+                X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
+                          X509V3_R_INVALID_INHERITANCE);
+                X509V3_conf_err(val);
+                goto err;
+            }
+            OPENSSL_free(s);
+            s = NULL;
+            continue;
+        }
+
+        i1 = strspn(s, addr_chars);
+        i2 = i1 + strspn(s + i1, " \t");
+        delim = s[i2++];
+        s[i1] = '\0';
+
+        if (a2i_ipadd(min, s) != length) {
+            X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS);
+            X509V3_conf_err(val);
+            goto err;
+        }
+
+        switch (delim) {
+        case '/':
+            prefixlen = (int)strtoul(s + i2, &t, 10);
+            if (t == s + i2 || *t != '\0') {
+                X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
+                          X509V3_R_EXTENSION_VALUE_ERROR);
+                X509V3_conf_err(val);
+                goto err;
+            }
+            if (!X509v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) {
+                X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            break;
+        case '-':
+            i1 = i2 + strspn(s + i2, " \t");
+            i2 = i1 + strspn(s + i1, addr_chars);
+            if (i1 == i2 || s[i2] != '\0') {
+                X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
+                          X509V3_R_EXTENSION_VALUE_ERROR);
+                X509V3_conf_err(val);
+                goto err;
+            }
+            if (a2i_ipadd(max, s + i1) != length) {
+                X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
+                          X509V3_R_INVALID_IPADDRESS);
+                X509V3_conf_err(val);
+                goto err;
+            }
+            if (memcmp(min, max, length_from_afi(afi)) > 0) {
+                X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
+                          X509V3_R_EXTENSION_VALUE_ERROR);
+                X509V3_conf_err(val);
+                goto err;
+            }
+            if (!X509v3_addr_add_range(addr, afi, safi, min, max)) {
+                X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            break;
+        case '\0':
+            if (!X509v3_addr_add_prefix(addr, afi, safi, min, length * 8)) {
+                X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            break;
+        default:
+            X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
+                      X509V3_R_EXTENSION_VALUE_ERROR);
+            X509V3_conf_err(val);
+            goto err;
+        }
+
+        OPENSSL_free(s);
+        s = NULL;
+    }
+
+    /*
+     * Canonize the result, then we're done.
+     */
+    if (!X509v3_addr_canonize(addr))
+        goto err;
+    return addr;
+
+ err:
+    OPENSSL_free(s);
+    sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free);
+    return NULL;
+}
+
+/*
+ * OpenSSL dispatch
+ */
+const X509V3_EXT_METHOD v3_addr = {
+    NID_sbgp_ipAddrBlock,       /* nid */
+    0,                          /* flags */
+    ASN1_ITEM_ref(IPAddrBlocks), /* template */
+    0, 0, 0, 0,                 /* old functions, ignored */
+    0,                          /* i2s */
+    0,                          /* s2i */
+    0,                          /* i2v */
+    v2i_IPAddrBlocks,           /* v2i */
+    i2r_IPAddrBlocks,           /* i2r */
+    0,                          /* r2i */
+    NULL                        /* extension-specific data */
+};
+
+/*
+ * Figure out whether extension sues inheritance.
+ */
+int X509v3_addr_inherits(IPAddrBlocks *addr)
+{
+    int i;
+    if (addr == NULL)
+        return 0;
+    for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
+        IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
+        if (f->ipAddressChoice->type == IPAddressChoice_inherit)
+            return 1;
+    }
+    return 0;
+}
+
+/*
+ * Figure out whether parent contains child.
+ */
+static int addr_contains(IPAddressOrRanges *parent,
+                         IPAddressOrRanges *child, int length)
+{
+    unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN];
+    unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN];
+    int p, c;
+
+    if (child == NULL || parent == child)
+        return 1;
+    if (parent == NULL)
+        return 0;
+
+    p = 0;
+    for (c = 0; c < sk_IPAddressOrRange_num(child); c++) {
+        if (!extract_min_max(sk_IPAddressOrRange_value(child, c),
+                             c_min, c_max, length))
+            return -1;
+        for (;; p++) {
+            if (p >= sk_IPAddressOrRange_num(parent))
+                return 0;
+            if (!extract_min_max(sk_IPAddressOrRange_value(parent, p),
+                                 p_min, p_max, length))
+                return 0;
+            if (memcmp(p_max, c_max, length) < 0)
+                continue;
+            if (memcmp(p_min, c_min, length) > 0)
+                return 0;
+            break;
+        }
+    }
+
+    return 1;
+}
+
+/*
+ * Test whether a is a subset of b.
+ */
+int X509v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b)
+{
+    int i;
+    if (a == NULL || a == b)
+        return 1;
+    if (b == NULL || X509v3_addr_inherits(a) || X509v3_addr_inherits(b))
+        return 0;
+    (void)sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp);
+    for (i = 0; i < sk_IPAddressFamily_num(a); i++) {
+        IPAddressFamily *fa = sk_IPAddressFamily_value(a, i);
+        int j = sk_IPAddressFamily_find(b, fa);
+        IPAddressFamily *fb;
+        fb = sk_IPAddressFamily_value(b, j);
+        if (fb == NULL)
+            return 0;
+        if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges,
+                           fa->ipAddressChoice->u.addressesOrRanges,
+                           length_from_afi(X509v3_addr_get_afi(fb))))
+            return 0;
+    }
+    return 1;
+}
+
+/*
+ * Validation error handling via callback.
+ */
+#define validation_err(_err_)           \
+  do {                                  \
+    if (ctx != NULL) {                  \
+      ctx->error = _err_;               \
+      ctx->error_depth = i;             \
+      ctx->current_cert = x;            \
+      ret = ctx->verify_cb(0, ctx);     \
+    } else {                            \
+      ret = 0;                          \
+    }                                   \
+    if (!ret)                           \
+      goto done;                        \
+  } while (0)
+
+/*
+ * Core code for RFC 3779 2.3 path validation.
+ *
+ * Returns 1 for success, 0 on error.
+ *
+ * When returning 0, ctx->error MUST be set to an appropriate value other than
+ * X509_V_OK.
+ */
+static int addr_validate_path_internal(X509_STORE_CTX *ctx,
+                                       STACK_OF(X509) *chain,
+                                       IPAddrBlocks *ext)
+{
+    IPAddrBlocks *child = NULL;
+    int i, j, ret = 1;
+    X509 *x;
+
+    OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0);
+    OPENSSL_assert(ctx != NULL || ext != NULL);
+    OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL);
+
+    /*
+     * Figure out where to start.  If we don't have an extension to
+     * check, we're done.  Otherwise, check canonical form and
+     * set up for walking up the chain.
+     */
+    if (ext != NULL) {
+        i = -1;
+        x = NULL;
+    } else {
+        i = 0;
+        x = sk_X509_value(chain, i);
+        OPENSSL_assert(x != NULL);
+        if ((ext = x->rfc3779_addr) == NULL)
+            goto done;
+    }
+    if (!X509v3_addr_is_canonical(ext))
+        validation_err(X509_V_ERR_INVALID_EXTENSION);
+    (void)sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp);
+    if ((child = sk_IPAddressFamily_dup(ext)) == NULL) {
+        X509V3err(X509V3_F_ADDR_VALIDATE_PATH_INTERNAL,
+                  ERR_R_MALLOC_FAILURE);
+        ctx->error = X509_V_ERR_OUT_OF_MEM;
+        ret = 0;
+        goto done;
+    }
+
+    /*
+     * Now walk up the chain.  No cert may list resources that its
+     * parent doesn't list.
+     */
+    for (i++; i < sk_X509_num(chain); i++) {
+        x = sk_X509_value(chain, i);
+        OPENSSL_assert(x != NULL);
+        if (!X509v3_addr_is_canonical(x->rfc3779_addr))
+            validation_err(X509_V_ERR_INVALID_EXTENSION);
+        if (x->rfc3779_addr == NULL) {
+            for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
+                IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
+                if (fc->ipAddressChoice->type != IPAddressChoice_inherit) {
+                    validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+                    break;
+                }
+            }
+            continue;
+        }
+        (void)sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr,
+                                              IPAddressFamily_cmp);
+        for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
+            IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
+            int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc);
+            IPAddressFamily *fp =
+                sk_IPAddressFamily_value(x->rfc3779_addr, k);
+            if (fp == NULL) {
+                if (fc->ipAddressChoice->type ==
+                    IPAddressChoice_addressesOrRanges) {
+                    validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+                    break;
+                }
+                continue;
+            }
+            if (fp->ipAddressChoice->type ==
+                IPAddressChoice_addressesOrRanges) {
+                if (fc->ipAddressChoice->type == IPAddressChoice_inherit
+                    || addr_contains(fp->ipAddressChoice->u.addressesOrRanges,
+                                     fc->ipAddressChoice->u.addressesOrRanges,
+                                     length_from_afi(X509v3_addr_get_afi(fc))))
+                    sk_IPAddressFamily_set(child, j, fp);
+                else
+                    validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+            }
+        }
+    }
+
+    /*
+     * Trust anchor can't inherit.
+     */
+    OPENSSL_assert(x != NULL);
+    if (x->rfc3779_addr != NULL) {
+        for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) {
+            IPAddressFamily *fp =
+                sk_IPAddressFamily_value(x->rfc3779_addr, j);
+            if (fp->ipAddressChoice->type == IPAddressChoice_inherit
+                && sk_IPAddressFamily_find(child, fp) >= 0)
+                validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+        }
+    }
+
+ done:
+    sk_IPAddressFamily_free(child);
+    return ret;
+}
+
+#undef validation_err
+
+/*
+ * RFC 3779 2.3 path validation -- called from X509_verify_cert().
+ */
+int X509v3_addr_validate_path(X509_STORE_CTX *ctx)
+{
+    return addr_validate_path_internal(ctx, ctx->chain, NULL);
+}
+
+/*
+ * RFC 3779 2.3 path validation of an extension.
+ * Test whether chain covers extension.
+ */
+int X509v3_addr_validate_resource_set(STACK_OF(X509) *chain,
+                                  IPAddrBlocks *ext, int allow_inheritance)
+{
+    if (ext == NULL)
+        return 1;
+    if (chain == NULL || sk_X509_num(chain) == 0)
+        return 0;
+    if (!allow_inheritance && X509v3_addr_inherits(ext))
+        return 0;
+    return addr_validate_path_internal(NULL, chain, ext);
+}
+
+#endif                          /* OPENSSL_NO_RFC3779 */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_akey.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_akey.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_akey.c	(revision 331)
@@ -0,0 +1,160 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+#include "ext_dat.h"
+
+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
+                                                 AUTHORITY_KEYID *akeyid,
+                                                 STACK_OF(CONF_VALUE)
+                                                 *extlist);
+static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
+                                            X509V3_CTX *ctx,
+                                            STACK_OF(CONF_VALUE) *values);
+
+const X509V3_EXT_METHOD v3_akey_id = {
+    NID_authority_key_identifier,
+    X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID),
+    0, 0, 0, 0,
+    0, 0,
+    (X509V3_EXT_I2V) i2v_AUTHORITY_KEYID,
+    (X509V3_EXT_V2I)v2i_AUTHORITY_KEYID,
+    0, 0,
+    NULL
+};
+
+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
+                                                 AUTHORITY_KEYID *akeyid,
+                                                 STACK_OF(CONF_VALUE)
+                                                 *extlist)
+{
+    char *tmp;
+    if (akeyid->keyid) {
+        tmp = OPENSSL_buf2hexstr(akeyid->keyid->data, akeyid->keyid->length);
+        X509V3_add_value("keyid", tmp, &extlist);
+        OPENSSL_free(tmp);
+    }
+    if (akeyid->issuer)
+        extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist);
+    if (akeyid->serial) {
+        tmp = OPENSSL_buf2hexstr(akeyid->serial->data, akeyid->serial->length);
+        X509V3_add_value("serial", tmp, &extlist);
+        OPENSSL_free(tmp);
+    }
+    return extlist;
+}
+
+/*-
+ * Currently two options:
+ * keyid: use the issuers subject keyid, the value 'always' means its is
+ * an error if the issuer certificate doesn't have a key id.
+ * issuer: use the issuers cert issuer and serial number. The default is
+ * to only use this if keyid is not present. With the option 'always'
+ * this is always included.
+ */
+
+static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
+                                            X509V3_CTX *ctx,
+                                            STACK_OF(CONF_VALUE) *values)
+{
+    char keyid = 0, issuer = 0;
+    int i;
+    CONF_VALUE *cnf;
+    ASN1_OCTET_STRING *ikeyid = NULL;
+    X509_NAME *isname = NULL;
+    GENERAL_NAMES *gens = NULL;
+    GENERAL_NAME *gen = NULL;
+    ASN1_INTEGER *serial = NULL;
+    X509_EXTENSION *ext;
+    X509 *cert;
+    AUTHORITY_KEYID *akeyid;
+
+    for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+        cnf = sk_CONF_VALUE_value(values, i);
+        if (strcmp(cnf->name, "keyid") == 0) {
+            keyid = 1;
+            if (cnf->value && strcmp(cnf->value, "always") == 0)
+                keyid = 2;
+        } else if (strcmp(cnf->name, "issuer") == 0) {
+            issuer = 1;
+            if (cnf->value && strcmp(cnf->value, "always") == 0)
+                issuer = 2;
+        } else {
+            X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, X509V3_R_UNKNOWN_OPTION);
+            ERR_add_error_data(2, "name=", cnf->name);
+            return NULL;
+        }
+    }
+
+    if (!ctx || !ctx->issuer_cert) {
+        if (ctx && (ctx->flags == CTX_TEST))
+            return AUTHORITY_KEYID_new();
+        X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,
+                  X509V3_R_NO_ISSUER_CERTIFICATE);
+        return NULL;
+    }
+
+    cert = ctx->issuer_cert;
+
+    if (keyid) {
+        i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1);
+        if ((i >= 0) && (ext = X509_get_ext(cert, i)))
+            ikeyid = X509V3_EXT_d2i(ext);
+        if (keyid == 2 && !ikeyid) {
+            X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,
+                      X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
+            return NULL;
+        }
+    }
+
+    if ((issuer && !ikeyid) || (issuer == 2)) {
+        isname = X509_NAME_dup(X509_get_issuer_name(cert));
+        serial = ASN1_INTEGER_dup(X509_get_serialNumber(cert));
+        if (!isname || !serial) {
+            X509V3err(X509V3_F_V2I_AUTHORITY_KEYID,
+                      X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS);
+            goto err;
+        }
+    }
+
+    if ((akeyid = AUTHORITY_KEYID_new()) == NULL)
+        goto err;
+
+    if (isname) {
+        if ((gens = sk_GENERAL_NAME_new_null()) == NULL
+            || (gen = GENERAL_NAME_new()) == NULL
+            || !sk_GENERAL_NAME_push(gens, gen)) {
+            X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        gen->type = GEN_DIRNAME;
+        gen->d.dirn = isname;
+    }
+
+    akeyid->issuer = gens;
+    gen = NULL;
+    gens = NULL;
+    akeyid->serial = serial;
+    akeyid->keyid = ikeyid;
+
+    return akeyid;
+
+ err:
+    sk_GENERAL_NAME_free(gens);
+    GENERAL_NAME_free(gen);
+    X509_NAME_free(isname);
+    ASN1_INTEGER_free(serial);
+    ASN1_OCTET_STRING_free(ikeyid);
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_akeya.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_akeya.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_akeya.c	(revision 331)
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2001-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+ASN1_SEQUENCE(AUTHORITY_KEYID) = {
+        ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0),
+        ASN1_IMP_SEQUENCE_OF_OPT(AUTHORITY_KEYID, issuer, GENERAL_NAME, 1),
+        ASN1_IMP_OPT(AUTHORITY_KEYID, serial, ASN1_INTEGER, 2)
+} ASN1_SEQUENCE_END(AUTHORITY_KEYID)
+
+IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_KEYID)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_alt.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_alt.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_alt.c	(revision 331)
@@ -0,0 +1,566 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+#include "ext_dat.h"
+
+static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
+                                      X509V3_CTX *ctx,
+                                      STACK_OF(CONF_VALUE) *nval);
+static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
+                                     X509V3_CTX *ctx,
+                                     STACK_OF(CONF_VALUE) *nval);
+static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p);
+static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens);
+static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx);
+static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx);
+
+const X509V3_EXT_METHOD v3_alt[3] = {
+    {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
+     0, 0, 0, 0,
+     0, 0,
+     (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
+     (X509V3_EXT_V2I)v2i_subject_alt,
+     NULL, NULL, NULL},
+
+    {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES),
+     0, 0, 0, 0,
+     0, 0,
+     (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
+     (X509V3_EXT_V2I)v2i_issuer_alt,
+     NULL, NULL, NULL},
+
+    {NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES),
+     0, 0, 0, 0,
+     0, 0,
+     (X509V3_EXT_I2V) i2v_GENERAL_NAMES,
+     NULL, NULL, NULL, NULL},
+};
+
+STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
+                                        GENERAL_NAMES *gens,
+                                        STACK_OF(CONF_VALUE) *ret)
+{
+    int i;
+    GENERAL_NAME *gen;
+    for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+        gen = sk_GENERAL_NAME_value(gens, i);
+        ret = i2v_GENERAL_NAME(method, gen, ret);
+    }
+    if (!ret)
+        return sk_CONF_VALUE_new_null();
+    return ret;
+}
+
+STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
+                                       GENERAL_NAME *gen,
+                                       STACK_OF(CONF_VALUE) *ret)
+{
+    unsigned char *p;
+    char oline[256], htmp[5];
+    int i;
+    switch (gen->type) {
+    case GEN_OTHERNAME:
+        X509V3_add_value("othername", "<unsupported>", &ret);
+        break;
+
+    case GEN_X400:
+        X509V3_add_value("X400Name", "<unsupported>", &ret);
+        break;
+
+    case GEN_EDIPARTY:
+        X509V3_add_value("EdiPartyName", "<unsupported>", &ret);
+        break;
+
+    case GEN_EMAIL:
+        X509V3_add_value_uchar("email", gen->d.ia5->data, &ret);
+        break;
+
+    case GEN_DNS:
+        X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret);
+        break;
+
+    case GEN_URI:
+        X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret);
+        break;
+
+    case GEN_DIRNAME:
+        X509_NAME_oneline(gen->d.dirn, oline, 256);
+        X509V3_add_value("DirName", oline, &ret);
+        break;
+
+    case GEN_IPADD:
+        p = gen->d.ip->data;
+        if (gen->d.ip->length == 4)
+            BIO_snprintf(oline, sizeof oline,
+                         "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+        else if (gen->d.ip->length == 16) {
+            oline[0] = 0;
+            for (i = 0; i < 8; i++) {
+                BIO_snprintf(htmp, sizeof htmp, "%X", p[0] << 8 | p[1]);
+                p += 2;
+                strcat(oline, htmp);
+                if (i != 7)
+                    strcat(oline, ":");
+            }
+        } else {
+            X509V3_add_value("IP Address", "<invalid>", &ret);
+            break;
+        }
+        X509V3_add_value("IP Address", oline, &ret);
+        break;
+
+    case GEN_RID:
+        i2t_ASN1_OBJECT(oline, 256, gen->d.rid);
+        X509V3_add_value("Registered ID", oline, &ret);
+        break;
+    }
+    return ret;
+}
+
+int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen)
+{
+    unsigned char *p;
+    int i;
+    switch (gen->type) {
+    case GEN_OTHERNAME:
+        BIO_printf(out, "othername:<unsupported>");
+        break;
+
+    case GEN_X400:
+        BIO_printf(out, "X400Name:<unsupported>");
+        break;
+
+    case GEN_EDIPARTY:
+        /* Maybe fix this: it is supported now */
+        BIO_printf(out, "EdiPartyName:<unsupported>");
+        break;
+
+    case GEN_EMAIL:
+        BIO_printf(out, "email:%s", gen->d.ia5->data);
+        break;
+
+    case GEN_DNS:
+        BIO_printf(out, "DNS:%s", gen->d.ia5->data);
+        break;
+
+    case GEN_URI:
+        BIO_printf(out, "URI:%s", gen->d.ia5->data);
+        break;
+
+    case GEN_DIRNAME:
+        BIO_printf(out, "DirName:");
+        X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE);
+        break;
+
+    case GEN_IPADD:
+        p = gen->d.ip->data;
+        if (gen->d.ip->length == 4)
+            BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+        else if (gen->d.ip->length == 16) {
+            BIO_printf(out, "IP Address");
+            for (i = 0; i < 8; i++) {
+                BIO_printf(out, ":%X", p[0] << 8 | p[1]);
+                p += 2;
+            }
+            BIO_puts(out, "\n");
+        } else {
+            BIO_printf(out, "IP Address:<invalid>");
+            break;
+        }
+        break;
+
+    case GEN_RID:
+        BIO_printf(out, "Registered ID:");
+        i2a_ASN1_OBJECT(out, gen->d.rid);
+        break;
+    }
+    return 1;
+}
+
+static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
+                                     X509V3_CTX *ctx,
+                                     STACK_OF(CONF_VALUE) *nval)
+{
+    GENERAL_NAMES *gens = NULL;
+    CONF_VALUE *cnf;
+    int i;
+
+    if ((gens = sk_GENERAL_NAME_new_null()) == NULL) {
+        X509V3err(X509V3_F_V2I_ISSUER_ALT, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        cnf = sk_CONF_VALUE_value(nval, i);
+        if (!name_cmp(cnf->name, "issuer")
+            && cnf->value && strcmp(cnf->value, "copy") == 0) {
+            if (!copy_issuer(ctx, gens))
+                goto err;
+        } else {
+            GENERAL_NAME *gen;
+            if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL)
+                goto err;
+            sk_GENERAL_NAME_push(gens, gen);
+        }
+    }
+    return gens;
+ err:
+    sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+    return NULL;
+}
+
+/* Append subject altname of issuer to issuer alt name of subject */
+
+static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
+{
+    GENERAL_NAMES *ialt;
+    GENERAL_NAME *gen;
+    X509_EXTENSION *ext;
+    int i;
+
+    if (ctx && (ctx->flags == CTX_TEST))
+        return 1;
+    if (!ctx || !ctx->issuer_cert) {
+        X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_NO_ISSUER_DETAILS);
+        goto err;
+    }
+    i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
+    if (i < 0)
+        return 1;
+    if ((ext = X509_get_ext(ctx->issuer_cert, i)) == NULL
+        || (ialt = X509V3_EXT_d2i(ext)) == NULL) {
+        X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_ISSUER_DECODE_ERROR);
+        goto err;
+    }
+
+    for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) {
+        gen = sk_GENERAL_NAME_value(ialt, i);
+        if (!sk_GENERAL_NAME_push(gens, gen)) {
+            X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    }
+    sk_GENERAL_NAME_free(ialt);
+
+    return 1;
+
+ err:
+    return 0;
+
+}
+
+static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
+                                      X509V3_CTX *ctx,
+                                      STACK_OF(CONF_VALUE) *nval)
+{
+    GENERAL_NAMES *gens = NULL;
+    CONF_VALUE *cnf;
+    int i;
+
+    if ((gens = sk_GENERAL_NAME_new_null()) == NULL) {
+        X509V3err(X509V3_F_V2I_SUBJECT_ALT, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        cnf = sk_CONF_VALUE_value(nval, i);
+        if (!name_cmp(cnf->name, "email")
+            && cnf->value && strcmp(cnf->value, "copy") == 0) {
+            if (!copy_email(ctx, gens, 0))
+                goto err;
+        } else if (!name_cmp(cnf->name, "email")
+                   && cnf->value && strcmp(cnf->value, "move") == 0) {
+            if (!copy_email(ctx, gens, 1))
+                goto err;
+        } else {
+            GENERAL_NAME *gen;
+            if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL)
+                goto err;
+            sk_GENERAL_NAME_push(gens, gen);
+        }
+    }
+    return gens;
+ err:
+    sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+    return NULL;
+}
+
+/*
+ * Copy any email addresses in a certificate or request to GENERAL_NAMES
+ */
+
+static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
+{
+    X509_NAME *nm;
+    ASN1_IA5STRING *email = NULL;
+    X509_NAME_ENTRY *ne;
+    GENERAL_NAME *gen = NULL;
+    int i;
+    if (ctx != NULL && ctx->flags == CTX_TEST)
+        return 1;
+    if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
+        X509V3err(X509V3_F_COPY_EMAIL, X509V3_R_NO_SUBJECT_DETAILS);
+        goto err;
+    }
+    /* Find the subject name */
+    if (ctx->subject_cert)
+        nm = X509_get_subject_name(ctx->subject_cert);
+    else
+        nm = X509_REQ_get_subject_name(ctx->subject_req);
+
+    /* Now add any email address(es) to STACK */
+    i = -1;
+    while ((i = X509_NAME_get_index_by_NID(nm,
+                                           NID_pkcs9_emailAddress, i)) >= 0) {
+        ne = X509_NAME_get_entry(nm, i);
+        email = ASN1_STRING_dup(X509_NAME_ENTRY_get_data(ne));
+        if (move_p) {
+            X509_NAME_delete_entry(nm, i);
+            X509_NAME_ENTRY_free(ne);
+            i--;
+        }
+        if (email == NULL || (gen = GENERAL_NAME_new()) == NULL) {
+            X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        gen->d.ia5 = email;
+        email = NULL;
+        gen->type = GEN_EMAIL;
+        if (!sk_GENERAL_NAME_push(gens, gen)) {
+            X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        gen = NULL;
+    }
+
+    return 1;
+
+ err:
+    GENERAL_NAME_free(gen);
+    ASN1_IA5STRING_free(email);
+    return 0;
+
+}
+
+GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
+                                 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+{
+    GENERAL_NAME *gen;
+    GENERAL_NAMES *gens = NULL;
+    CONF_VALUE *cnf;
+    int i;
+
+    if ((gens = sk_GENERAL_NAME_new_null()) == NULL) {
+        X509V3err(X509V3_F_V2I_GENERAL_NAMES, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        cnf = sk_CONF_VALUE_value(nval, i);
+        if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL)
+            goto err;
+        sk_GENERAL_NAME_push(gens, gen);
+    }
+    return gens;
+ err:
+    sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+    return NULL;
+}
+
+GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method,
+                               X509V3_CTX *ctx, CONF_VALUE *cnf)
+{
+    return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0);
+}
+
+GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
+                               const X509V3_EXT_METHOD *method,
+                               X509V3_CTX *ctx, int gen_type, const char *value,
+                               int is_nc)
+{
+    char is_string = 0;
+    GENERAL_NAME *gen = NULL;
+
+    if (!value) {
+        X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_MISSING_VALUE);
+        return NULL;
+    }
+
+    if (out)
+        gen = out;
+    else {
+        gen = GENERAL_NAME_new();
+        if (gen == NULL) {
+            X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE);
+            return NULL;
+        }
+    }
+
+    switch (gen_type) {
+    case GEN_URI:
+    case GEN_EMAIL:
+    case GEN_DNS:
+        is_string = 1;
+        break;
+
+    case GEN_RID:
+        {
+            ASN1_OBJECT *obj;
+            if ((obj = OBJ_txt2obj(value, 0)) == NULL) {
+                X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_OBJECT);
+                ERR_add_error_data(2, "value=", value);
+                goto err;
+            }
+            gen->d.rid = obj;
+        }
+        break;
+
+    case GEN_IPADD:
+        if (is_nc)
+            gen->d.ip = a2i_IPADDRESS_NC(value);
+        else
+            gen->d.ip = a2i_IPADDRESS(value);
+        if (gen->d.ip == NULL) {
+            X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_IP_ADDRESS);
+            ERR_add_error_data(2, "value=", value);
+            goto err;
+        }
+        break;
+
+    case GEN_DIRNAME:
+        if (!do_dirname(gen, value, ctx)) {
+            X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_DIRNAME_ERROR);
+            goto err;
+        }
+        break;
+
+    case GEN_OTHERNAME:
+        if (!do_othername(gen, value, ctx)) {
+            X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_OTHERNAME_ERROR);
+            goto err;
+        }
+        break;
+    default:
+        X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_UNSUPPORTED_TYPE);
+        goto err;
+    }
+
+    if (is_string) {
+        if ((gen->d.ia5 = ASN1_IA5STRING_new()) == NULL ||
+            !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value,
+                             strlen(value))) {
+            X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    }
+
+    gen->type = gen_type;
+
+    return gen;
+
+ err:
+    if (!out)
+        GENERAL_NAME_free(gen);
+    return NULL;
+}
+
+GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
+                                  const X509V3_EXT_METHOD *method,
+                                  X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc)
+{
+    int type;
+
+    char *name, *value;
+
+    name = cnf->name;
+    value = cnf->value;
+
+    if (!value) {
+        X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_MISSING_VALUE);
+        return NULL;
+    }
+
+    if (!name_cmp(name, "email"))
+        type = GEN_EMAIL;
+    else if (!name_cmp(name, "URI"))
+        type = GEN_URI;
+    else if (!name_cmp(name, "DNS"))
+        type = GEN_DNS;
+    else if (!name_cmp(name, "RID"))
+        type = GEN_RID;
+    else if (!name_cmp(name, "IP"))
+        type = GEN_IPADD;
+    else if (!name_cmp(name, "dirName"))
+        type = GEN_DIRNAME;
+    else if (!name_cmp(name, "otherName"))
+        type = GEN_OTHERNAME;
+    else {
+        X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_UNSUPPORTED_OPTION);
+        ERR_add_error_data(2, "name=", name);
+        return NULL;
+    }
+
+    return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc);
+
+}
+
+static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx)
+{
+    char *objtmp = NULL, *p;
+    int objlen;
+
+    if ((p = strchr(value, ';')) == NULL)
+        return 0;
+    if ((gen->d.otherName = OTHERNAME_new()) == NULL)
+        return 0;
+    /*
+     * Free this up because we will overwrite it. no need to free type_id
+     * because it is static
+     */
+    ASN1_TYPE_free(gen->d.otherName->value);
+    if ((gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)) == NULL)
+        return 0;
+    objlen = p - value;
+    objtmp = OPENSSL_strndup(value, objlen);
+    if (objtmp == NULL)
+        return 0;
+    gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
+    OPENSSL_free(objtmp);
+    if (!gen->d.otherName->type_id)
+        return 0;
+    return 1;
+}
+
+static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx)
+{
+    int ret = 0;
+    STACK_OF(CONF_VALUE) *sk = NULL;
+    X509_NAME *nm;
+
+    if ((nm = X509_NAME_new()) == NULL)
+        goto err;
+    sk = X509V3_get_section(ctx, value);
+    if (!sk) {
+        X509V3err(X509V3_F_DO_DIRNAME, X509V3_R_SECTION_NOT_FOUND);
+        ERR_add_error_data(2, "section=", value);
+        goto err;
+    }
+    /* FIXME: should allow other character types... */
+    ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC);
+    if (!ret)
+        goto err;
+    gen->d.dirn = nm;
+
+err:
+    if (ret == 0)
+        X509_NAME_free(nm);
+    X509V3_section_free(ctx, sk);
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_asid.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_asid.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_asid.c	(revision 331)
@@ -0,0 +1,852 @@
+/*
+ * Copyright 2006-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
+ */
+
+/*
+ * Implementation of RFC 3779 section 3.2.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+#include <openssl/bn.h>
+#include "ext_dat.h"
+
+#ifndef OPENSSL_NO_RFC3779
+
+/*
+ * OpenSSL ASN.1 template translation of RFC 3779 3.2.3.
+ */
+
+ASN1_SEQUENCE(ASRange) = {
+  ASN1_SIMPLE(ASRange, min, ASN1_INTEGER),
+  ASN1_SIMPLE(ASRange, max, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(ASRange)
+
+ASN1_CHOICE(ASIdOrRange) = {
+  ASN1_SIMPLE(ASIdOrRange, u.id,    ASN1_INTEGER),
+  ASN1_SIMPLE(ASIdOrRange, u.range, ASRange)
+} ASN1_CHOICE_END(ASIdOrRange)
+
+ASN1_CHOICE(ASIdentifierChoice) = {
+  ASN1_SIMPLE(ASIdentifierChoice,      u.inherit,       ASN1_NULL),
+  ASN1_SEQUENCE_OF(ASIdentifierChoice, u.asIdsOrRanges, ASIdOrRange)
+} ASN1_CHOICE_END(ASIdentifierChoice)
+
+ASN1_SEQUENCE(ASIdentifiers) = {
+  ASN1_EXP_OPT(ASIdentifiers, asnum, ASIdentifierChoice, 0),
+  ASN1_EXP_OPT(ASIdentifiers, rdi,   ASIdentifierChoice, 1)
+} ASN1_SEQUENCE_END(ASIdentifiers)
+
+IMPLEMENT_ASN1_FUNCTIONS(ASRange)
+IMPLEMENT_ASN1_FUNCTIONS(ASIdOrRange)
+IMPLEMENT_ASN1_FUNCTIONS(ASIdentifierChoice)
+IMPLEMENT_ASN1_FUNCTIONS(ASIdentifiers)
+
+/*
+ * i2r method for an ASIdentifierChoice.
+ */
+static int i2r_ASIdentifierChoice(BIO *out,
+                                  ASIdentifierChoice *choice,
+                                  int indent, const char *msg)
+{
+    int i;
+    char *s;
+    if (choice == NULL)
+        return 1;
+    BIO_printf(out, "%*s%s:\n", indent, "", msg);
+    switch (choice->type) {
+    case ASIdentifierChoice_inherit:
+        BIO_printf(out, "%*sinherit\n", indent + 2, "");
+        break;
+    case ASIdentifierChoice_asIdsOrRanges:
+        for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges); i++) {
+            ASIdOrRange *aor =
+                sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+            switch (aor->type) {
+            case ASIdOrRange_id:
+                if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) == NULL)
+                    return 0;
+                BIO_printf(out, "%*s%s\n", indent + 2, "", s);
+                OPENSSL_free(s);
+                break;
+            case ASIdOrRange_range:
+                if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->min)) == NULL)
+                    return 0;
+                BIO_printf(out, "%*s%s-", indent + 2, "", s);
+                OPENSSL_free(s);
+                if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->max)) == NULL)
+                    return 0;
+                BIO_printf(out, "%s\n", s);
+                OPENSSL_free(s);
+                break;
+            default:
+                return 0;
+            }
+        }
+        break;
+    default:
+        return 0;
+    }
+    return 1;
+}
+
+/*
+ * i2r method for an ASIdentifier extension.
+ */
+static int i2r_ASIdentifiers(const X509V3_EXT_METHOD *method,
+                             void *ext, BIO *out, int indent)
+{
+    ASIdentifiers *asid = ext;
+    return (i2r_ASIdentifierChoice(out, asid->asnum, indent,
+                                   "Autonomous System Numbers") &&
+            i2r_ASIdentifierChoice(out, asid->rdi, indent,
+                                   "Routing Domain Identifiers"));
+}
+
+/*
+ * Sort comparison function for a sequence of ASIdOrRange elements.
+ */
+static int ASIdOrRange_cmp(const ASIdOrRange *const *a_,
+                           const ASIdOrRange *const *b_)
+{
+    const ASIdOrRange *a = *a_, *b = *b_;
+
+    OPENSSL_assert((a->type == ASIdOrRange_id && a->u.id != NULL) ||
+                   (a->type == ASIdOrRange_range && a->u.range != NULL &&
+                    a->u.range->min != NULL && a->u.range->max != NULL));
+
+    OPENSSL_assert((b->type == ASIdOrRange_id && b->u.id != NULL) ||
+                   (b->type == ASIdOrRange_range && b->u.range != NULL &&
+                    b->u.range->min != NULL && b->u.range->max != NULL));
+
+    if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id)
+        return ASN1_INTEGER_cmp(a->u.id, b->u.id);
+
+    if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) {
+        int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min);
+        return r != 0 ? r : ASN1_INTEGER_cmp(a->u.range->max,
+                                             b->u.range->max);
+    }
+
+    if (a->type == ASIdOrRange_id)
+        return ASN1_INTEGER_cmp(a->u.id, b->u.range->min);
+    else
+        return ASN1_INTEGER_cmp(a->u.range->min, b->u.id);
+}
+
+/*
+ * Add an inherit element.
+ */
+int X509v3_asid_add_inherit(ASIdentifiers *asid, int which)
+{
+    ASIdentifierChoice **choice;
+    if (asid == NULL)
+        return 0;
+    switch (which) {
+    case V3_ASID_ASNUM:
+        choice = &asid->asnum;
+        break;
+    case V3_ASID_RDI:
+        choice = &asid->rdi;
+        break;
+    default:
+        return 0;
+    }
+    if (*choice == NULL) {
+        if ((*choice = ASIdentifierChoice_new()) == NULL)
+            return 0;
+        OPENSSL_assert((*choice)->u.inherit == NULL);
+        if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL)
+            return 0;
+        (*choice)->type = ASIdentifierChoice_inherit;
+    }
+    return (*choice)->type == ASIdentifierChoice_inherit;
+}
+
+/*
+ * Add an ID or range to an ASIdentifierChoice.
+ */
+int X509v3_asid_add_id_or_range(ASIdentifiers *asid,
+                                int which, ASN1_INTEGER *min, ASN1_INTEGER *max)
+{
+    ASIdentifierChoice **choice;
+    ASIdOrRange *aor;
+    if (asid == NULL)
+        return 0;
+    switch (which) {
+    case V3_ASID_ASNUM:
+        choice = &asid->asnum;
+        break;
+    case V3_ASID_RDI:
+        choice = &asid->rdi;
+        break;
+    default:
+        return 0;
+    }
+    if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit)
+        return 0;
+    if (*choice == NULL) {
+        if ((*choice = ASIdentifierChoice_new()) == NULL)
+            return 0;
+        OPENSSL_assert((*choice)->u.asIdsOrRanges == NULL);
+        (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp);
+        if ((*choice)->u.asIdsOrRanges == NULL)
+            return 0;
+        (*choice)->type = ASIdentifierChoice_asIdsOrRanges;
+    }
+    if ((aor = ASIdOrRange_new()) == NULL)
+        return 0;
+    if (max == NULL) {
+        aor->type = ASIdOrRange_id;
+        aor->u.id = min;
+    } else {
+        aor->type = ASIdOrRange_range;
+        if ((aor->u.range = ASRange_new()) == NULL)
+            goto err;
+        ASN1_INTEGER_free(aor->u.range->min);
+        aor->u.range->min = min;
+        ASN1_INTEGER_free(aor->u.range->max);
+        aor->u.range->max = max;
+    }
+    if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor)))
+        goto err;
+    return 1;
+
+ err:
+    ASIdOrRange_free(aor);
+    return 0;
+}
+
+/*
+ * Extract min and max values from an ASIdOrRange.
+ */
+static void extract_min_max(ASIdOrRange *aor,
+                            ASN1_INTEGER **min, ASN1_INTEGER **max)
+{
+    OPENSSL_assert(aor != NULL && min != NULL && max != NULL);
+    switch (aor->type) {
+    case ASIdOrRange_id:
+        *min = aor->u.id;
+        *max = aor->u.id;
+        return;
+    case ASIdOrRange_range:
+        *min = aor->u.range->min;
+        *max = aor->u.range->max;
+        return;
+    }
+}
+
+/*
+ * Check whether an ASIdentifierChoice is in canonical form.
+ */
+static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice)
+{
+    ASN1_INTEGER *a_max_plus_one = NULL;
+    BIGNUM *bn = NULL;
+    int i, ret = 0;
+
+    /*
+     * Empty element or inheritance is canonical.
+     */
+    if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
+        return 1;
+
+    /*
+     * If not a list, or if empty list, it's broken.
+     */
+    if (choice->type != ASIdentifierChoice_asIdsOrRanges ||
+        sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0)
+        return 0;
+
+    /*
+     * It's a list, check it.
+     */
+    for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
+        ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+        ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1);
+        ASN1_INTEGER *a_min = NULL, *a_max = NULL, *b_min = NULL, *b_max =
+            NULL;
+
+        extract_min_max(a, &a_min, &a_max);
+        extract_min_max(b, &b_min, &b_max);
+
+        /*
+         * Punt misordered list, overlapping start, or inverted range.
+         */
+        if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 ||
+            ASN1_INTEGER_cmp(a_min, a_max) > 0 ||
+            ASN1_INTEGER_cmp(b_min, b_max) > 0)
+            goto done;
+
+        /*
+         * Calculate a_max + 1 to check for adjacency.
+         */
+        if ((bn == NULL && (bn = BN_new()) == NULL) ||
+            ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
+            !BN_add_word(bn, 1) ||
+            (a_max_plus_one =
+             BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) {
+            X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL,
+                      ERR_R_MALLOC_FAILURE);
+            goto done;
+        }
+
+        /*
+         * Punt if adjacent or overlapping.
+         */
+        if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0)
+            goto done;
+    }
+
+    /*
+     * Check for inverted range.
+     */
+    i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1;
+    {
+        ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+        ASN1_INTEGER *a_min, *a_max;
+        if (a != NULL && a->type == ASIdOrRange_range) {
+            extract_min_max(a, &a_min, &a_max);
+            if (ASN1_INTEGER_cmp(a_min, a_max) > 0)
+                goto done;
+        }
+    }
+
+    ret = 1;
+
+ done:
+    ASN1_INTEGER_free(a_max_plus_one);
+    BN_free(bn);
+    return ret;
+}
+
+/*
+ * Check whether an ASIdentifier extension is in canonical form.
+ */
+int X509v3_asid_is_canonical(ASIdentifiers *asid)
+{
+    return (asid == NULL ||
+            (ASIdentifierChoice_is_canonical(asid->asnum) &&
+             ASIdentifierChoice_is_canonical(asid->rdi)));
+}
+
+/*
+ * Whack an ASIdentifierChoice into canonical form.
+ */
+static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice)
+{
+    ASN1_INTEGER *a_max_plus_one = NULL;
+    BIGNUM *bn = NULL;
+    int i, ret = 0;
+
+    /*
+     * Nothing to do for empty element or inheritance.
+     */
+    if (choice == NULL || choice->type == ASIdentifierChoice_inherit)
+        return 1;
+
+    /*
+     * If not a list, or if empty list, it's broken.
+     */
+    if (choice->type != ASIdentifierChoice_asIdsOrRanges ||
+        sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) {
+        X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
+                  X509V3_R_EXTENSION_VALUE_ERROR);
+        return 0;
+    }
+
+    /*
+     * We have a non-empty list.  Sort it.
+     */
+    sk_ASIdOrRange_sort(choice->u.asIdsOrRanges);
+
+    /*
+     * Now check for errors and suboptimal encoding, rejecting the
+     * former and fixing the latter.
+     */
+    for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) {
+        ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+        ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1);
+        ASN1_INTEGER *a_min = NULL, *a_max = NULL, *b_min = NULL, *b_max =
+            NULL;
+
+        extract_min_max(a, &a_min, &a_max);
+        extract_min_max(b, &b_min, &b_max);
+
+        /*
+         * Make sure we're properly sorted (paranoia).
+         */
+        OPENSSL_assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0);
+
+        /*
+         * Punt inverted ranges.
+         */
+        if (ASN1_INTEGER_cmp(a_min, a_max) > 0 ||
+            ASN1_INTEGER_cmp(b_min, b_max) > 0)
+            goto done;
+
+        /*
+         * Check for overlaps.
+         */
+        if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) {
+            X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
+                      X509V3_R_EXTENSION_VALUE_ERROR);
+            goto done;
+        }
+
+        /*
+         * Calculate a_max + 1 to check for adjacency.
+         */
+        if ((bn == NULL && (bn = BN_new()) == NULL) ||
+            ASN1_INTEGER_to_BN(a_max, bn) == NULL ||
+            !BN_add_word(bn, 1) ||
+            (a_max_plus_one =
+             BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) {
+            X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
+                      ERR_R_MALLOC_FAILURE);
+            goto done;
+        }
+
+        /*
+         * If a and b are adjacent, merge them.
+         */
+        if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) {
+            ASRange *r;
+            switch (a->type) {
+            case ASIdOrRange_id:
+                if ((r = OPENSSL_malloc(sizeof(*r))) == NULL) {
+                    X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE,
+                              ERR_R_MALLOC_FAILURE);
+                    goto done;
+                }
+                r->min = a_min;
+                r->max = b_max;
+                a->type = ASIdOrRange_range;
+                a->u.range = r;
+                break;
+            case ASIdOrRange_range:
+                ASN1_INTEGER_free(a->u.range->max);
+                a->u.range->max = b_max;
+                break;
+            }
+            switch (b->type) {
+            case ASIdOrRange_id:
+                b->u.id = NULL;
+                break;
+            case ASIdOrRange_range:
+                b->u.range->max = NULL;
+                break;
+            }
+            ASIdOrRange_free(b);
+            (void)sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1);
+            i--;
+            continue;
+        }
+    }
+
+    /*
+     * Check for final inverted range.
+     */
+    i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1;
+    {
+        ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i);
+        ASN1_INTEGER *a_min, *a_max;
+        if (a != NULL && a->type == ASIdOrRange_range) {
+            extract_min_max(a, &a_min, &a_max);
+            if (ASN1_INTEGER_cmp(a_min, a_max) > 0)
+                goto done;
+        }
+    }
+
+    OPENSSL_assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */
+
+    ret = 1;
+
+ done:
+    ASN1_INTEGER_free(a_max_plus_one);
+    BN_free(bn);
+    return ret;
+}
+
+/*
+ * Whack an ASIdentifier extension into canonical form.
+ */
+int X509v3_asid_canonize(ASIdentifiers *asid)
+{
+    return (asid == NULL ||
+            (ASIdentifierChoice_canonize(asid->asnum) &&
+             ASIdentifierChoice_canonize(asid->rdi)));
+}
+
+/*
+ * v2i method for an ASIdentifier extension.
+ */
+static void *v2i_ASIdentifiers(const struct v3_ext_method *method,
+                               struct v3_ext_ctx *ctx,
+                               STACK_OF(CONF_VALUE) *values)
+{
+    ASN1_INTEGER *min = NULL, *max = NULL;
+    ASIdentifiers *asid = NULL;
+    int i;
+
+    if ((asid = ASIdentifiers_new()) == NULL) {
+        X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+        CONF_VALUE *val = sk_CONF_VALUE_value(values, i);
+        int i1 = 0, i2 = 0, i3 = 0, is_range = 0, which = 0;
+
+        /*
+         * Figure out whether this is an AS or an RDI.
+         */
+        if (!name_cmp(val->name, "AS")) {
+            which = V3_ASID_ASNUM;
+        } else if (!name_cmp(val->name, "RDI")) {
+            which = V3_ASID_RDI;
+        } else {
+            X509V3err(X509V3_F_V2I_ASIDENTIFIERS,
+                      X509V3_R_EXTENSION_NAME_ERROR);
+            X509V3_conf_err(val);
+            goto err;
+        }
+
+        /*
+         * Handle inheritance.
+         */
+        if (strcmp(val->value, "inherit") == 0) {
+            if (X509v3_asid_add_inherit(asid, which))
+                continue;
+            X509V3err(X509V3_F_V2I_ASIDENTIFIERS,
+                      X509V3_R_INVALID_INHERITANCE);
+            X509V3_conf_err(val);
+            goto err;
+        }
+
+        /*
+         * Number, range, or mistake, pick it apart and figure out which.
+         */
+        i1 = strspn(val->value, "0123456789");
+        if (val->value[i1] == '\0') {
+            is_range = 0;
+        } else {
+            is_range = 1;
+            i2 = i1 + strspn(val->value + i1, " \t");
+            if (val->value[i2] != '-') {
+                X509V3err(X509V3_F_V2I_ASIDENTIFIERS,
+                          X509V3_R_INVALID_ASNUMBER);
+                X509V3_conf_err(val);
+                goto err;
+            }
+            i2++;
+            i2 = i2 + strspn(val->value + i2, " \t");
+            i3 = i2 + strspn(val->value + i2, "0123456789");
+            if (val->value[i3] != '\0') {
+                X509V3err(X509V3_F_V2I_ASIDENTIFIERS,
+                          X509V3_R_INVALID_ASRANGE);
+                X509V3_conf_err(val);
+                goto err;
+            }
+        }
+
+        /*
+         * Syntax is ok, read and add it.
+         */
+        if (!is_range) {
+            if (!X509V3_get_value_int(val, &min)) {
+                X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+        } else {
+            char *s = OPENSSL_strdup(val->value);
+            if (s == NULL) {
+                X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            s[i1] = '\0';
+            min = s2i_ASN1_INTEGER(NULL, s);
+            max = s2i_ASN1_INTEGER(NULL, s + i2);
+            OPENSSL_free(s);
+            if (min == NULL || max == NULL) {
+                X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            if (ASN1_INTEGER_cmp(min, max) > 0) {
+                X509V3err(X509V3_F_V2I_ASIDENTIFIERS,
+                          X509V3_R_EXTENSION_VALUE_ERROR);
+                goto err;
+            }
+        }
+        if (!X509v3_asid_add_id_or_range(asid, which, min, max)) {
+            X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        min = max = NULL;
+    }
+
+    /*
+     * Canonize the result, then we're done.
+     */
+    if (!X509v3_asid_canonize(asid))
+        goto err;
+    return asid;
+
+ err:
+    ASIdentifiers_free(asid);
+    ASN1_INTEGER_free(min);
+    ASN1_INTEGER_free(max);
+    return NULL;
+}
+
+/*
+ * OpenSSL dispatch.
+ */
+const X509V3_EXT_METHOD v3_asid = {
+    NID_sbgp_autonomousSysNum,  /* nid */
+    0,                          /* flags */
+    ASN1_ITEM_ref(ASIdentifiers), /* template */
+    0, 0, 0, 0,                 /* old functions, ignored */
+    0,                          /* i2s */
+    0,                          /* s2i */
+    0,                          /* i2v */
+    v2i_ASIdentifiers,          /* v2i */
+    i2r_ASIdentifiers,          /* i2r */
+    0,                          /* r2i */
+    NULL                        /* extension-specific data */
+};
+
+/*
+ * Figure out whether extension uses inheritance.
+ */
+int X509v3_asid_inherits(ASIdentifiers *asid)
+{
+    return (asid != NULL &&
+            ((asid->asnum != NULL &&
+              asid->asnum->type == ASIdentifierChoice_inherit) ||
+             (asid->rdi != NULL &&
+              asid->rdi->type == ASIdentifierChoice_inherit)));
+}
+
+/*
+ * Figure out whether parent contains child.
+ */
+static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child)
+{
+    ASN1_INTEGER *p_min = NULL, *p_max = NULL, *c_min = NULL, *c_max = NULL;
+    int p, c;
+
+    if (child == NULL || parent == child)
+        return 1;
+    if (parent == NULL)
+        return 0;
+
+    p = 0;
+    for (c = 0; c < sk_ASIdOrRange_num(child); c++) {
+        extract_min_max(sk_ASIdOrRange_value(child, c), &c_min, &c_max);
+        for (;; p++) {
+            if (p >= sk_ASIdOrRange_num(parent))
+                return 0;
+            extract_min_max(sk_ASIdOrRange_value(parent, p), &p_min, &p_max);
+            if (ASN1_INTEGER_cmp(p_max, c_max) < 0)
+                continue;
+            if (ASN1_INTEGER_cmp(p_min, c_min) > 0)
+                return 0;
+            break;
+        }
+    }
+
+    return 1;
+}
+
+/*
+ * Test whether a is a subset of b.
+ */
+int X509v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b)
+{
+    return (a == NULL ||
+            a == b ||
+            (b != NULL &&
+             !X509v3_asid_inherits(a) &&
+             !X509v3_asid_inherits(b) &&
+             asid_contains(b->asnum->u.asIdsOrRanges,
+                           a->asnum->u.asIdsOrRanges) &&
+             asid_contains(b->rdi->u.asIdsOrRanges,
+                           a->rdi->u.asIdsOrRanges)));
+}
+
+/*
+ * Validation error handling via callback.
+ */
+#define validation_err(_err_)           \
+  do {                                  \
+    if (ctx != NULL) {                  \
+      ctx->error = _err_;               \
+      ctx->error_depth = i;             \
+      ctx->current_cert = x;            \
+      ret = ctx->verify_cb(0, ctx);     \
+    } else {                            \
+      ret = 0;                          \
+    }                                   \
+    if (!ret)                           \
+      goto done;                        \
+  } while (0)
+
+/*
+ * Core code for RFC 3779 3.3 path validation.
+ */
+static int asid_validate_path_internal(X509_STORE_CTX *ctx,
+                                       STACK_OF(X509) *chain,
+                                       ASIdentifiers *ext)
+{
+    ASIdOrRanges *child_as = NULL, *child_rdi = NULL;
+    int i, ret = 1, inherit_as = 0, inherit_rdi = 0;
+    X509 *x;
+
+    OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0);
+    OPENSSL_assert(ctx != NULL || ext != NULL);
+    OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL);
+
+    /*
+     * Figure out where to start.  If we don't have an extension to
+     * check, we're done.  Otherwise, check canonical form and
+     * set up for walking up the chain.
+     */
+    if (ext != NULL) {
+        i = -1;
+        x = NULL;
+    } else {
+        i = 0;
+        x = sk_X509_value(chain, i);
+        OPENSSL_assert(x != NULL);
+        if ((ext = x->rfc3779_asid) == NULL)
+            goto done;
+    }
+    if (!X509v3_asid_is_canonical(ext))
+        validation_err(X509_V_ERR_INVALID_EXTENSION);
+    if (ext->asnum != NULL) {
+        switch (ext->asnum->type) {
+        case ASIdentifierChoice_inherit:
+            inherit_as = 1;
+            break;
+        case ASIdentifierChoice_asIdsOrRanges:
+            child_as = ext->asnum->u.asIdsOrRanges;
+            break;
+        }
+    }
+    if (ext->rdi != NULL) {
+        switch (ext->rdi->type) {
+        case ASIdentifierChoice_inherit:
+            inherit_rdi = 1;
+            break;
+        case ASIdentifierChoice_asIdsOrRanges:
+            child_rdi = ext->rdi->u.asIdsOrRanges;
+            break;
+        }
+    }
+
+    /*
+     * Now walk up the chain.  Extensions must be in canonical form, no
+     * cert may list resources that its parent doesn't list.
+     */
+    for (i++; i < sk_X509_num(chain); i++) {
+        x = sk_X509_value(chain, i);
+        OPENSSL_assert(x != NULL);
+        if (x->rfc3779_asid == NULL) {
+            if (child_as != NULL || child_rdi != NULL)
+                validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+            continue;
+        }
+        if (!X509v3_asid_is_canonical(x->rfc3779_asid))
+            validation_err(X509_V_ERR_INVALID_EXTENSION);
+        if (x->rfc3779_asid->asnum == NULL && child_as != NULL) {
+            validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+            child_as = NULL;
+            inherit_as = 0;
+        }
+        if (x->rfc3779_asid->asnum != NULL &&
+            x->rfc3779_asid->asnum->type ==
+            ASIdentifierChoice_asIdsOrRanges) {
+            if (inherit_as
+                || asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges,
+                                 child_as)) {
+                child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges;
+                inherit_as = 0;
+            } else {
+                validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+            }
+        }
+        if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) {
+            validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+            child_rdi = NULL;
+            inherit_rdi = 0;
+        }
+        if (x->rfc3779_asid->rdi != NULL &&
+            x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) {
+            if (inherit_rdi ||
+                asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges,
+                              child_rdi)) {
+                child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges;
+                inherit_rdi = 0;
+            } else {
+                validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+            }
+        }
+    }
+
+    /*
+     * Trust anchor can't inherit.
+     */
+    OPENSSL_assert(x != NULL);
+    if (x->rfc3779_asid != NULL) {
+        if (x->rfc3779_asid->asnum != NULL &&
+            x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit)
+            validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+        if (x->rfc3779_asid->rdi != NULL &&
+            x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit)
+            validation_err(X509_V_ERR_UNNESTED_RESOURCE);
+    }
+
+ done:
+    return ret;
+}
+
+#undef validation_err
+
+/*
+ * RFC 3779 3.3 path validation -- called from X509_verify_cert().
+ */
+int X509v3_asid_validate_path(X509_STORE_CTX *ctx)
+{
+    return asid_validate_path_internal(ctx, ctx->chain, NULL);
+}
+
+/*
+ * RFC 3779 3.3 path validation of an extension.
+ * Test whether chain covers extension.
+ */
+int X509v3_asid_validate_resource_set(STACK_OF(X509) *chain,
+                                      ASIdentifiers *ext, int allow_inheritance)
+{
+    if (ext == NULL)
+        return 1;
+    if (chain == NULL || sk_X509_num(chain) == 0)
+        return 0;
+    if (!allow_inheritance && X509v3_asid_inherits(ext))
+        return 0;
+    return asid_validate_path_internal(NULL, chain, ext);
+}
+
+#endif                          /* OPENSSL_NO_RFC3779 */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_bcons.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_bcons.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_bcons.c	(revision 331)
@@ -0,0 +1,84 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+#include "ext_dat.h"
+
+static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
+                                                   BASIC_CONSTRAINTS *bcons,
+                                                   STACK_OF(CONF_VALUE)
+                                                   *extlist);
+static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
+                                                X509V3_CTX *ctx,
+                                                STACK_OF(CONF_VALUE) *values);
+
+const X509V3_EXT_METHOD v3_bcons = {
+    NID_basic_constraints, 0,
+    ASN1_ITEM_ref(BASIC_CONSTRAINTS),
+    0, 0, 0, 0,
+    0, 0,
+    (X509V3_EXT_I2V) i2v_BASIC_CONSTRAINTS,
+    (X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS,
+    NULL, NULL,
+    NULL
+};
+
+ASN1_SEQUENCE(BASIC_CONSTRAINTS) = {
+        ASN1_OPT(BASIC_CONSTRAINTS, ca, ASN1_FBOOLEAN),
+        ASN1_OPT(BASIC_CONSTRAINTS, pathlen, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(BASIC_CONSTRAINTS)
+
+IMPLEMENT_ASN1_FUNCTIONS(BASIC_CONSTRAINTS)
+
+static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
+                                                   BASIC_CONSTRAINTS *bcons,
+                                                   STACK_OF(CONF_VALUE)
+                                                   *extlist)
+{
+    X509V3_add_value_bool("CA", bcons->ca, &extlist);
+    X509V3_add_value_int("pathlen", bcons->pathlen, &extlist);
+    return extlist;
+}
+
+static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
+                                                X509V3_CTX *ctx,
+                                                STACK_OF(CONF_VALUE) *values)
+{
+    BASIC_CONSTRAINTS *bcons = NULL;
+    CONF_VALUE *val;
+    int i;
+
+    if ((bcons = BASIC_CONSTRAINTS_new()) == NULL) {
+        X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+        val = sk_CONF_VALUE_value(values, i);
+        if (strcmp(val->name, "CA") == 0) {
+            if (!X509V3_get_value_bool(val, &bcons->ca))
+                goto err;
+        } else if (strcmp(val->name, "pathlen") == 0) {
+            if (!X509V3_get_value_int(val, &bcons->pathlen))
+                goto err;
+        } else {
+            X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, X509V3_R_INVALID_NAME);
+            X509V3_conf_err(val);
+            goto err;
+        }
+    }
+    return bcons;
+ err:
+    BASIC_CONSTRAINTS_free(bcons);
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_bitst.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_bitst.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_bitst.c	(revision 331)
@@ -0,0 +1,93 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+#include "ext_dat.h"
+
+static BIT_STRING_BITNAME ns_cert_type_table[] = {
+    {0, "SSL Client", "client"},
+    {1, "SSL Server", "server"},
+    {2, "S/MIME", "email"},
+    {3, "Object Signing", "objsign"},
+    {4, "Unused", "reserved"},
+    {5, "SSL CA", "sslCA"},
+    {6, "S/MIME CA", "emailCA"},
+    {7, "Object Signing CA", "objCA"},
+    {-1, NULL, NULL}
+};
+
+static BIT_STRING_BITNAME key_usage_type_table[] = {
+    {0, "Digital Signature", "digitalSignature"},
+    {1, "Non Repudiation", "nonRepudiation"},
+    {2, "Key Encipherment", "keyEncipherment"},
+    {3, "Data Encipherment", "dataEncipherment"},
+    {4, "Key Agreement", "keyAgreement"},
+    {5, "Certificate Sign", "keyCertSign"},
+    {6, "CRL Sign", "cRLSign"},
+    {7, "Encipher Only", "encipherOnly"},
+    {8, "Decipher Only", "decipherOnly"},
+    {-1, NULL, NULL}
+};
+
+const X509V3_EXT_METHOD v3_nscert =
+EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table);
+const X509V3_EXT_METHOD v3_key_usage =
+EXT_BITSTRING(NID_key_usage, key_usage_type_table);
+
+STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+                                          ASN1_BIT_STRING *bits,
+                                          STACK_OF(CONF_VALUE) *ret)
+{
+    BIT_STRING_BITNAME *bnam;
+    for (bnam = method->usr_data; bnam->lname; bnam++) {
+        if (ASN1_BIT_STRING_get_bit(bits, bnam->bitnum))
+            X509V3_add_value(bnam->lname, NULL, &ret);
+    }
+    return ret;
+}
+
+ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+                                     X509V3_CTX *ctx,
+                                     STACK_OF(CONF_VALUE) *nval)
+{
+    CONF_VALUE *val;
+    ASN1_BIT_STRING *bs;
+    int i;
+    BIT_STRING_BITNAME *bnam;
+    if ((bs = ASN1_BIT_STRING_new()) == NULL) {
+        X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        val = sk_CONF_VALUE_value(nval, i);
+        for (bnam = method->usr_data; bnam->lname; bnam++) {
+            if (strcmp(bnam->sname, val->name) == 0
+                || strcmp(bnam->lname, val->name) == 0) {
+                if (!ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1)) {
+                    X509V3err(X509V3_F_V2I_ASN1_BIT_STRING,
+                              ERR_R_MALLOC_FAILURE);
+                    ASN1_BIT_STRING_free(bs);
+                    return NULL;
+                }
+                break;
+            }
+        }
+        if (!bnam->lname) {
+            X509V3err(X509V3_F_V2I_ASN1_BIT_STRING,
+                      X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT);
+            X509V3_conf_err(val);
+            ASN1_BIT_STRING_free(bs);
+            return NULL;
+        }
+    }
+    return bs;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_conf.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_conf.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_conf.c	(revision 331)
@@ -0,0 +1,507 @@
+/*
+ * Copyright 1999-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
+ */
+
+/* extension creation utilities */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509.h>
+#include "internal/x509_int.h"
+#include <openssl/x509v3.h>
+
+static int v3_check_critical(const char **value);
+static int v3_check_generic(const char **value);
+static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
+                                    int crit, const char *value);
+static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value,
+                                            int crit, int type,
+                                            X509V3_CTX *ctx);
+static char *conf_lhash_get_string(void *db, const char *section, const char *value);
+static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, const char *section);
+static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method,
+                                  int ext_nid, int crit, void *ext_struc);
+static unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx,
+                                   long *ext_len);
+/* CONF *conf:  Config file    */
+/* char *name:  Name    */
+/* char *value:  Value    */
+X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name,
+                                 const char *value)
+{
+    int crit;
+    int ext_type;
+    X509_EXTENSION *ret;
+    crit = v3_check_critical(&value);
+    if ((ext_type = v3_check_generic(&value)))
+        return v3_generic_extension(name, value, crit, ext_type, ctx);
+    ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
+    if (!ret) {
+        X509V3err(X509V3_F_X509V3_EXT_NCONF, X509V3_R_ERROR_IN_EXTENSION);
+        ERR_add_error_data(4, "name=", name, ", value=", value);
+    }
+    return ret;
+}
+
+/* CONF *conf:  Config file    */
+/* char *value:  Value    */
+X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
+                                     const char *value)
+{
+    int crit;
+    int ext_type;
+    crit = v3_check_critical(&value);
+    if ((ext_type = v3_check_generic(&value)))
+        return v3_generic_extension(OBJ_nid2sn(ext_nid),
+                                    value, crit, ext_type, ctx);
+    return do_ext_nconf(conf, ctx, ext_nid, crit, value);
+}
+
+/* CONF *conf:  Config file    */
+/* char *value:  Value    */
+static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
+                                    int crit, const char *value)
+{
+    const X509V3_EXT_METHOD *method;
+    X509_EXTENSION *ext;
+    STACK_OF(CONF_VALUE) *nval;
+    void *ext_struc;
+
+    if (ext_nid == NID_undef) {
+        X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_UNKNOWN_EXTENSION_NAME);
+        return NULL;
+    }
+    if ((method = X509V3_EXT_get_nid(ext_nid)) == NULL) {
+        X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_UNKNOWN_EXTENSION);
+        return NULL;
+    }
+    /* Now get internal extension representation based on type */
+    if (method->v2i) {
+        if (*value == '@')
+            nval = NCONF_get_section(conf, value + 1);
+        else
+            nval = X509V3_parse_list(value);
+        if (nval == NULL || sk_CONF_VALUE_num(nval) <= 0) {
+            X509V3err(X509V3_F_DO_EXT_NCONF,
+                      X509V3_R_INVALID_EXTENSION_STRING);
+            ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=",
+                               value);
+            if (*value != '@')
+                sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
+            return NULL;
+        }
+        ext_struc = method->v2i(method, ctx, nval);
+        if (*value != '@')
+            sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
+        if (!ext_struc)
+            return NULL;
+    } else if (method->s2i) {
+        if ((ext_struc = method->s2i(method, ctx, value)) == NULL)
+            return NULL;
+    } else if (method->r2i) {
+        if (!ctx->db || !ctx->db_meth) {
+            X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_NO_CONFIG_DATABASE);
+            return NULL;
+        }
+        if ((ext_struc = method->r2i(method, ctx, value)) == NULL)
+            return NULL;
+    } else {
+        X509V3err(X509V3_F_DO_EXT_NCONF,
+                  X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
+        ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
+        return NULL;
+    }
+
+    ext = do_ext_i2d(method, ext_nid, crit, ext_struc);
+    if (method->it)
+        ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it));
+    else
+        method->ext_free(ext_struc);
+    return ext;
+
+}
+
+static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method,
+                                  int ext_nid, int crit, void *ext_struc)
+{
+    unsigned char *ext_der = NULL;
+    int ext_len;
+    ASN1_OCTET_STRING *ext_oct = NULL;
+    X509_EXTENSION *ext;
+    /* Convert internal representation to DER */
+    if (method->it) {
+        ext_der = NULL;
+        ext_len =
+            ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it));
+        if (ext_len < 0)
+            goto merr;
+    } else {
+        unsigned char *p;
+
+        ext_len = method->i2d(ext_struc, NULL);
+        if ((ext_der = OPENSSL_malloc(ext_len)) == NULL)
+            goto merr;
+        p = ext_der;
+        method->i2d(ext_struc, &p);
+    }
+    if ((ext_oct = ASN1_OCTET_STRING_new()) == NULL)
+        goto merr;
+    ext_oct->data = ext_der;
+    ext_der = NULL;
+    ext_oct->length = ext_len;
+
+    ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
+    if (!ext)
+        goto merr;
+    ASN1_OCTET_STRING_free(ext_oct);
+
+    return ext;
+
+ merr:
+    X509V3err(X509V3_F_DO_EXT_I2D, ERR_R_MALLOC_FAILURE);
+    OPENSSL_free(ext_der);
+    ASN1_OCTET_STRING_free(ext_oct);
+    return NULL;
+
+}
+
+/* Given an internal structure, nid and critical flag create an extension */
+
+X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc)
+{
+    const X509V3_EXT_METHOD *method;
+
+    if ((method = X509V3_EXT_get_nid(ext_nid)) == NULL) {
+        X509V3err(X509V3_F_X509V3_EXT_I2D, X509V3_R_UNKNOWN_EXTENSION);
+        return NULL;
+    }
+    return do_ext_i2d(method, ext_nid, crit, ext_struc);
+}
+
+/* Check the extension string for critical flag */
+static int v3_check_critical(const char **value)
+{
+    const char *p = *value;
+    if ((strlen(p) < 9) || strncmp(p, "critical,", 9))
+        return 0;
+    p += 9;
+    while (isspace((unsigned char)*p))
+        p++;
+    *value = p;
+    return 1;
+}
+
+/* Check extension string for generic extension and return the type */
+static int v3_check_generic(const char **value)
+{
+    int gen_type = 0;
+    const char *p = *value;
+    if ((strlen(p) >= 4) && strncmp(p, "DER:", 4) == 0) {
+        p += 4;
+        gen_type = 1;
+    } else if ((strlen(p) >= 5) && strncmp(p, "ASN1:", 5) == 0) {
+        p += 5;
+        gen_type = 2;
+    } else
+        return 0;
+
+    while (isspace((unsigned char)*p))
+        p++;
+    *value = p;
+    return gen_type;
+}
+
+/* Create a generic extension: for now just handle DER type */
+static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value,
+                                            int crit, int gen_type,
+                                            X509V3_CTX *ctx)
+{
+    unsigned char *ext_der = NULL;
+    long ext_len = 0;
+    ASN1_OBJECT *obj = NULL;
+    ASN1_OCTET_STRING *oct = NULL;
+    X509_EXTENSION *extension = NULL;
+
+    if ((obj = OBJ_txt2obj(ext, 0)) == NULL) {
+        X509V3err(X509V3_F_V3_GENERIC_EXTENSION,
+                  X509V3_R_EXTENSION_NAME_ERROR);
+        ERR_add_error_data(2, "name=", ext);
+        goto err;
+    }
+
+    if (gen_type == 1)
+        ext_der = OPENSSL_hexstr2buf(value, &ext_len);
+    else if (gen_type == 2)
+        ext_der = generic_asn1(value, ctx, &ext_len);
+
+    if (ext_der == NULL) {
+        X509V3err(X509V3_F_V3_GENERIC_EXTENSION,
+                  X509V3_R_EXTENSION_VALUE_ERROR);
+        ERR_add_error_data(2, "value=", value);
+        goto err;
+    }
+
+    if ((oct = ASN1_OCTET_STRING_new()) == NULL) {
+        X509V3err(X509V3_F_V3_GENERIC_EXTENSION, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    oct->data = ext_der;
+    oct->length = ext_len;
+    ext_der = NULL;
+
+    extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);
+
+ err:
+    ASN1_OBJECT_free(obj);
+    ASN1_OCTET_STRING_free(oct);
+    OPENSSL_free(ext_der);
+    return extension;
+
+}
+
+static unsigned char *generic_asn1(const char *value, X509V3_CTX *ctx,
+                                   long *ext_len)
+{
+    ASN1_TYPE *typ;
+    unsigned char *ext_der = NULL;
+    typ = ASN1_generate_v3(value, ctx);
+    if (typ == NULL)
+        return NULL;
+    *ext_len = i2d_ASN1_TYPE(typ, &ext_der);
+    ASN1_TYPE_free(typ);
+    return ext_der;
+}
+
+static void delete_ext(STACK_OF(X509_EXTENSION) *sk, X509_EXTENSION *dext)
+{
+    int idx;
+    ASN1_OBJECT *obj;
+    obj = X509_EXTENSION_get_object(dext);
+    while ((idx = X509v3_get_ext_by_OBJ(sk, obj, -1)) >= 0) {
+        X509_EXTENSION *tmpext = X509v3_get_ext(sk, idx);
+        X509v3_delete_ext(sk, idx);
+        X509_EXTENSION_free(tmpext);
+    }
+}
+
+/*
+ * This is the main function: add a bunch of extensions based on a config
+ * file section to an extension STACK.
+ */
+
+int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section,
+                            STACK_OF(X509_EXTENSION) **sk)
+{
+    X509_EXTENSION *ext;
+    STACK_OF(CONF_VALUE) *nval;
+    CONF_VALUE *val;
+    int i;
+
+    if ((nval = NCONF_get_section(conf, section)) == NULL)
+        return 0;
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        val = sk_CONF_VALUE_value(nval, i);
+        if ((ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value)) == NULL)
+            return 0;
+        if (ctx->flags == X509V3_CTX_REPLACE)
+            delete_ext(*sk, ext);
+        if (sk)
+            X509v3_add_ext(sk, ext, -1);
+        X509_EXTENSION_free(ext);
+    }
+    return 1;
+}
+
+/*
+ * Convenience functions to add extensions to a certificate, CRL and request
+ */
+
+int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section,
+                         X509 *cert)
+{
+    STACK_OF(X509_EXTENSION) **sk = NULL;
+    if (cert)
+        sk = &cert->cert_info.extensions;
+    return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
+}
+
+/* Same as above but for a CRL */
+
+int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section,
+                             X509_CRL *crl)
+{
+    STACK_OF(X509_EXTENSION) **sk = NULL;
+    if (crl)
+        sk = &crl->crl.extensions;
+    return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
+}
+
+/* Add extensions to certificate request */
+
+int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section,
+                             X509_REQ *req)
+{
+    STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL;
+    int i;
+    if (req)
+        sk = &extlist;
+    i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
+    if (!i || !sk)
+        return i;
+    i = X509_REQ_add_extensions(req, extlist);
+    sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
+    return i;
+}
+
+/* Config database functions */
+
+char *X509V3_get_string(X509V3_CTX *ctx, const char *name, const char *section)
+{
+    if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string) {
+        X509V3err(X509V3_F_X509V3_GET_STRING, X509V3_R_OPERATION_NOT_DEFINED);
+        return NULL;
+    }
+    if (ctx->db_meth->get_string)
+        return ctx->db_meth->get_string(ctx->db, name, section);
+    return NULL;
+}
+
+STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, const char *section)
+{
+    if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section) {
+        X509V3err(X509V3_F_X509V3_GET_SECTION,
+                  X509V3_R_OPERATION_NOT_DEFINED);
+        return NULL;
+    }
+    if (ctx->db_meth->get_section)
+        return ctx->db_meth->get_section(ctx->db, section);
+    return NULL;
+}
+
+void X509V3_string_free(X509V3_CTX *ctx, char *str)
+{
+    if (!str)
+        return;
+    if (ctx->db_meth->free_string)
+        ctx->db_meth->free_string(ctx->db, str);
+}
+
+void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section)
+{
+    if (!section)
+        return;
+    if (ctx->db_meth->free_section)
+        ctx->db_meth->free_section(ctx->db, section);
+}
+
+static char *nconf_get_string(void *db, const char *section, const char *value)
+{
+    return NCONF_get_string(db, section, value);
+}
+
+static STACK_OF(CONF_VALUE) *nconf_get_section(void *db, const char *section)
+{
+    return NCONF_get_section(db, section);
+}
+
+static X509V3_CONF_METHOD nconf_method = {
+    nconf_get_string,
+    nconf_get_section,
+    NULL,
+    NULL
+};
+
+void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf)
+{
+    ctx->db_meth = &nconf_method;
+    ctx->db = conf;
+}
+
+void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req,
+                    X509_CRL *crl, int flags)
+{
+    ctx->issuer_cert = issuer;
+    ctx->subject_cert = subj;
+    ctx->crl = crl;
+    ctx->subject_req = req;
+    ctx->flags = flags;
+}
+
+/* Old conf compatibility functions */
+
+X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+                                const char *name, const char *value)
+{
+    CONF ctmp;
+    CONF_set_nconf(&ctmp, conf);
+    return X509V3_EXT_nconf(&ctmp, ctx, name, value);
+}
+
+/* LHASH *conf:  Config file    */
+/* char *value:  Value    */
+X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf,
+                                    X509V3_CTX *ctx, int ext_nid, const char *value)
+{
+    CONF ctmp;
+    CONF_set_nconf(&ctmp, conf);
+    return X509V3_EXT_nconf_nid(&ctmp, ctx, ext_nid, value);
+}
+
+static char *conf_lhash_get_string(void *db, const char *section, const char *value)
+{
+    return CONF_get_string(db, section, value);
+}
+
+static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, const char *section)
+{
+    return CONF_get_section(db, section);
+}
+
+static X509V3_CONF_METHOD conf_lhash_method = {
+    conf_lhash_get_string,
+    conf_lhash_get_section,
+    NULL,
+    NULL
+};
+
+void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash)
+{
+    ctx->db_meth = &conf_lhash_method;
+    ctx->db = lhash;
+}
+
+int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+                        const char *section, X509 *cert)
+{
+    CONF ctmp;
+    CONF_set_nconf(&ctmp, conf);
+    return X509V3_EXT_add_nconf(&ctmp, ctx, section, cert);
+}
+
+/* Same as above but for a CRL */
+
+int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+                            const char *section, X509_CRL *crl)
+{
+    CONF ctmp;
+    CONF_set_nconf(&ctmp, conf);
+    return X509V3_EXT_CRL_add_nconf(&ctmp, ctx, section, crl);
+}
+
+/* Add extensions to certificate request */
+
+int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+                            const char *section, X509_REQ *req)
+{
+    CONF ctmp;
+    CONF_set_nconf(&ctmp, conf);
+    return X509V3_EXT_REQ_add_nconf(&ctmp, ctx, section, req);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_cpols.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_cpols.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_cpols.c	(revision 331)
@@ -0,0 +1,441 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+#include "pcy_int.h"
+#include "ext_dat.h"
+
+/* Certificate policies extension support: this one is a bit complex... */
+
+static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol,
+                       BIO *out, int indent);
+static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
+                                         X509V3_CTX *ctx, const char *value);
+static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals,
+                             int indent);
+static void print_notice(BIO *out, USERNOTICE *notice, int indent);
+static POLICYINFO *policy_section(X509V3_CTX *ctx,
+                                  STACK_OF(CONF_VALUE) *polstrs, int ia5org);
+static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
+                                      STACK_OF(CONF_VALUE) *unot, int ia5org);
+static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos);
+
+const X509V3_EXT_METHOD v3_cpols = {
+    NID_certificate_policies, 0, ASN1_ITEM_ref(CERTIFICATEPOLICIES),
+    0, 0, 0, 0,
+    0, 0,
+    0, 0,
+    (X509V3_EXT_I2R)i2r_certpol,
+    (X509V3_EXT_R2I)r2i_certpol,
+    NULL
+};
+
+ASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CERTIFICATEPOLICIES, POLICYINFO)
+ASN1_ITEM_TEMPLATE_END(CERTIFICATEPOLICIES)
+
+IMPLEMENT_ASN1_FUNCTIONS(CERTIFICATEPOLICIES)
+
+ASN1_SEQUENCE(POLICYINFO) = {
+        ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT),
+        ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO)
+} ASN1_SEQUENCE_END(POLICYINFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(POLICYINFO)
+
+ASN1_ADB_TEMPLATE(policydefault) = ASN1_SIMPLE(POLICYQUALINFO, d.other, ASN1_ANY);
+
+ASN1_ADB(POLICYQUALINFO) = {
+        ADB_ENTRY(NID_id_qt_cps, ASN1_SIMPLE(POLICYQUALINFO, d.cpsuri, ASN1_IA5STRING)),
+        ADB_ENTRY(NID_id_qt_unotice, ASN1_SIMPLE(POLICYQUALINFO, d.usernotice, USERNOTICE))
+} ASN1_ADB_END(POLICYQUALINFO, 0, pqualid, 0, &policydefault_tt, NULL);
+
+ASN1_SEQUENCE(POLICYQUALINFO) = {
+        ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT),
+        ASN1_ADB_OBJECT(POLICYQUALINFO)
+} ASN1_SEQUENCE_END(POLICYQUALINFO)
+
+IMPLEMENT_ASN1_FUNCTIONS(POLICYQUALINFO)
+
+ASN1_SEQUENCE(USERNOTICE) = {
+        ASN1_OPT(USERNOTICE, noticeref, NOTICEREF),
+        ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT)
+} ASN1_SEQUENCE_END(USERNOTICE)
+
+IMPLEMENT_ASN1_FUNCTIONS(USERNOTICE)
+
+ASN1_SEQUENCE(NOTICEREF) = {
+        ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT),
+        ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(NOTICEREF)
+
+IMPLEMENT_ASN1_FUNCTIONS(NOTICEREF)
+
+static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
+                                         X509V3_CTX *ctx, const char *value)
+{
+    STACK_OF(POLICYINFO) *pols = NULL;
+    char *pstr;
+    POLICYINFO *pol;
+    ASN1_OBJECT *pobj;
+    STACK_OF(CONF_VALUE) *vals;
+    CONF_VALUE *cnf;
+    int i, ia5org;
+    pols = sk_POLICYINFO_new_null();
+    if (pols == NULL) {
+        X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    vals = X509V3_parse_list(value);
+    if (vals == NULL) {
+        X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_X509V3_LIB);
+        goto err;
+    }
+    ia5org = 0;
+    for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
+        cnf = sk_CONF_VALUE_value(vals, i);
+        if (cnf->value || !cnf->name) {
+            X509V3err(X509V3_F_R2I_CERTPOL,
+                      X509V3_R_INVALID_POLICY_IDENTIFIER);
+            X509V3_conf_err(cnf);
+            goto err;
+        }
+        pstr = cnf->name;
+        if (strcmp(pstr, "ia5org") == 0) {
+            ia5org = 1;
+            continue;
+        } else if (*pstr == '@') {
+            STACK_OF(CONF_VALUE) *polsect;
+            polsect = X509V3_get_section(ctx, pstr + 1);
+            if (!polsect) {
+                X509V3err(X509V3_F_R2I_CERTPOL, X509V3_R_INVALID_SECTION);
+
+                X509V3_conf_err(cnf);
+                goto err;
+            }
+            pol = policy_section(ctx, polsect, ia5org);
+            X509V3_section_free(ctx, polsect);
+            if (pol == NULL)
+                goto err;
+        } else {
+            if ((pobj = OBJ_txt2obj(cnf->name, 0)) == NULL) {
+                X509V3err(X509V3_F_R2I_CERTPOL,
+                          X509V3_R_INVALID_OBJECT_IDENTIFIER);
+                X509V3_conf_err(cnf);
+                goto err;
+            }
+            pol = POLICYINFO_new();
+            if (pol == NULL) {
+                X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
+                ASN1_OBJECT_free(pobj);
+                goto err;
+            }
+            pol->policyid = pobj;
+        }
+        if (!sk_POLICYINFO_push(pols, pol)) {
+            POLICYINFO_free(pol);
+            X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    }
+    sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
+    return pols;
+ err:
+    sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
+    sk_POLICYINFO_pop_free(pols, POLICYINFO_free);
+    return NULL;
+}
+
+static POLICYINFO *policy_section(X509V3_CTX *ctx,
+                                  STACK_OF(CONF_VALUE) *polstrs, int ia5org)
+{
+    int i;
+    CONF_VALUE *cnf;
+    POLICYINFO *pol;
+    POLICYQUALINFO *qual;
+
+    if ((pol = POLICYINFO_new()) == NULL)
+        goto merr;
+    for (i = 0; i < sk_CONF_VALUE_num(polstrs); i++) {
+        cnf = sk_CONF_VALUE_value(polstrs, i);
+        if (strcmp(cnf->name, "policyIdentifier") == 0) {
+            ASN1_OBJECT *pobj;
+            if ((pobj = OBJ_txt2obj(cnf->value, 0)) == NULL) {
+                X509V3err(X509V3_F_POLICY_SECTION,
+                          X509V3_R_INVALID_OBJECT_IDENTIFIER);
+                X509V3_conf_err(cnf);
+                goto err;
+            }
+            pol->policyid = pobj;
+
+        } else if (!name_cmp(cnf->name, "CPS")) {
+            if (pol->qualifiers == NULL)
+                pol->qualifiers = sk_POLICYQUALINFO_new_null();
+            if ((qual = POLICYQUALINFO_new()) == NULL)
+                goto merr;
+            if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
+                goto merr;
+            if ((qual->pqualid = OBJ_nid2obj(NID_id_qt_cps)) == NULL) {
+                X509V3err(X509V3_F_POLICY_SECTION, ERR_R_INTERNAL_ERROR);
+                goto err;
+            }
+            if ((qual->d.cpsuri = ASN1_IA5STRING_new()) == NULL)
+                goto merr;
+            if (!ASN1_STRING_set(qual->d.cpsuri, cnf->value,
+                                 strlen(cnf->value)))
+                goto merr;
+        } else if (!name_cmp(cnf->name, "userNotice")) {
+            STACK_OF(CONF_VALUE) *unot;
+            if (*cnf->value != '@') {
+                X509V3err(X509V3_F_POLICY_SECTION,
+                          X509V3_R_EXPECTED_A_SECTION_NAME);
+                X509V3_conf_err(cnf);
+                goto err;
+            }
+            unot = X509V3_get_section(ctx, cnf->value + 1);
+            if (!unot) {
+                X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_INVALID_SECTION);
+
+                X509V3_conf_err(cnf);
+                goto err;
+            }
+            qual = notice_section(ctx, unot, ia5org);
+            X509V3_section_free(ctx, unot);
+            if (!qual)
+                goto err;
+            if (!pol->qualifiers)
+                pol->qualifiers = sk_POLICYQUALINFO_new_null();
+            if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
+                goto merr;
+        } else {
+            X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_INVALID_OPTION);
+
+            X509V3_conf_err(cnf);
+            goto err;
+        }
+    }
+    if (!pol->policyid) {
+        X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_NO_POLICY_IDENTIFIER);
+        goto err;
+    }
+
+    return pol;
+
+ merr:
+    X509V3err(X509V3_F_POLICY_SECTION, ERR_R_MALLOC_FAILURE);
+
+ err:
+    POLICYINFO_free(pol);
+    return NULL;
+
+}
+
+static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
+                                      STACK_OF(CONF_VALUE) *unot, int ia5org)
+{
+    int i, ret;
+    CONF_VALUE *cnf;
+    USERNOTICE *not;
+    POLICYQUALINFO *qual;
+
+    if ((qual = POLICYQUALINFO_new()) == NULL)
+        goto merr;
+    if ((qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice)) == NULL) {
+        X509V3err(X509V3_F_NOTICE_SECTION, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+    if ((not = USERNOTICE_new()) == NULL)
+        goto merr;
+    qual->d.usernotice = not;
+    for (i = 0; i < sk_CONF_VALUE_num(unot); i++) {
+        cnf = sk_CONF_VALUE_value(unot, i);
+        if (strcmp(cnf->name, "explicitText") == 0) {
+            if ((not->exptext = ASN1_VISIBLESTRING_new()) == NULL)
+                goto merr;
+            if (!ASN1_STRING_set(not->exptext, cnf->value,
+                                 strlen(cnf->value)))
+                goto merr;
+        } else if (strcmp(cnf->name, "organization") == 0) {
+            NOTICEREF *nref;
+            if (!not->noticeref) {
+                if ((nref = NOTICEREF_new()) == NULL)
+                    goto merr;
+                not->noticeref = nref;
+            } else
+                nref = not->noticeref;
+            if (ia5org)
+                nref->organization->type = V_ASN1_IA5STRING;
+            else
+                nref->organization->type = V_ASN1_VISIBLESTRING;
+            if (!ASN1_STRING_set(nref->organization, cnf->value,
+                                 strlen(cnf->value)))
+                goto merr;
+        } else if (strcmp(cnf->name, "noticeNumbers") == 0) {
+            NOTICEREF *nref;
+            STACK_OF(CONF_VALUE) *nos;
+            if (!not->noticeref) {
+                if ((nref = NOTICEREF_new()) == NULL)
+                    goto merr;
+                not->noticeref = nref;
+            } else
+                nref = not->noticeref;
+            nos = X509V3_parse_list(cnf->value);
+            if (!nos || !sk_CONF_VALUE_num(nos)) {
+                X509V3err(X509V3_F_NOTICE_SECTION, X509V3_R_INVALID_NUMBERS);
+                X509V3_conf_err(cnf);
+                sk_CONF_VALUE_pop_free(nos, X509V3_conf_free);
+                goto err;
+            }
+            ret = nref_nos(nref->noticenos, nos);
+            sk_CONF_VALUE_pop_free(nos, X509V3_conf_free);
+            if (!ret)
+                goto err;
+        } else {
+            X509V3err(X509V3_F_NOTICE_SECTION, X509V3_R_INVALID_OPTION);
+            X509V3_conf_err(cnf);
+            goto err;
+        }
+    }
+
+    if (not->noticeref &&
+        (!not->noticeref->noticenos || !not->noticeref->organization)) {
+        X509V3err(X509V3_F_NOTICE_SECTION,
+                  X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
+        goto err;
+    }
+
+    return qual;
+
+ merr:
+    X509V3err(X509V3_F_NOTICE_SECTION, ERR_R_MALLOC_FAILURE);
+
+ err:
+    POLICYQUALINFO_free(qual);
+    return NULL;
+}
+
+static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos)
+{
+    CONF_VALUE *cnf;
+    ASN1_INTEGER *aint;
+
+    int i;
+
+    for (i = 0; i < sk_CONF_VALUE_num(nos); i++) {
+        cnf = sk_CONF_VALUE_value(nos, i);
+        if ((aint = s2i_ASN1_INTEGER(NULL, cnf->name)) == NULL) {
+            X509V3err(X509V3_F_NREF_NOS, X509V3_R_INVALID_NUMBER);
+            goto err;
+        }
+        if (!sk_ASN1_INTEGER_push(nnums, aint))
+            goto merr;
+    }
+    return 1;
+
+ merr:
+    ASN1_INTEGER_free(aint);
+    X509V3err(X509V3_F_NREF_NOS, ERR_R_MALLOC_FAILURE);
+
+ err:
+    return 0;
+}
+
+static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol,
+                       BIO *out, int indent)
+{
+    int i;
+    POLICYINFO *pinfo;
+    /* First print out the policy OIDs */
+    for (i = 0; i < sk_POLICYINFO_num(pol); i++) {
+        pinfo = sk_POLICYINFO_value(pol, i);
+        BIO_printf(out, "%*sPolicy: ", indent, "");
+        i2a_ASN1_OBJECT(out, pinfo->policyid);
+        BIO_puts(out, "\n");
+        if (pinfo->qualifiers)
+            print_qualifiers(out, pinfo->qualifiers, indent + 2);
+    }
+    return 1;
+}
+
+static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals,
+                             int indent)
+{
+    POLICYQUALINFO *qualinfo;
+    int i;
+    for (i = 0; i < sk_POLICYQUALINFO_num(quals); i++) {
+        qualinfo = sk_POLICYQUALINFO_value(quals, i);
+        switch (OBJ_obj2nid(qualinfo->pqualid)) {
+        case NID_id_qt_cps:
+            BIO_printf(out, "%*sCPS: %s\n", indent, "",
+                       qualinfo->d.cpsuri->data);
+            break;
+
+        case NID_id_qt_unotice:
+            BIO_printf(out, "%*sUser Notice:\n", indent, "");
+            print_notice(out, qualinfo->d.usernotice, indent + 2);
+            break;
+
+        default:
+            BIO_printf(out, "%*sUnknown Qualifier: ", indent + 2, "");
+
+            i2a_ASN1_OBJECT(out, qualinfo->pqualid);
+            BIO_puts(out, "\n");
+            break;
+        }
+    }
+}
+
+static void print_notice(BIO *out, USERNOTICE *notice, int indent)
+{
+    int i;
+    if (notice->noticeref) {
+        NOTICEREF *ref;
+        ref = notice->noticeref;
+        BIO_printf(out, "%*sOrganization: %s\n", indent, "",
+                   ref->organization->data);
+        BIO_printf(out, "%*sNumber%s: ", indent, "",
+                   sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : "");
+        for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) {
+            ASN1_INTEGER *num;
+            char *tmp;
+            num = sk_ASN1_INTEGER_value(ref->noticenos, i);
+            if (i)
+                BIO_puts(out, ", ");
+            tmp = i2s_ASN1_INTEGER(NULL, num);
+            BIO_puts(out, tmp);
+            OPENSSL_free(tmp);
+        }
+        BIO_puts(out, "\n");
+    }
+    if (notice->exptext)
+        BIO_printf(out, "%*sExplicit Text: %s\n", indent, "",
+                   notice->exptext->data);
+}
+
+void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent)
+{
+    const X509_POLICY_DATA *dat = node->data;
+
+    BIO_printf(out, "%*sPolicy: ", indent, "");
+
+    i2a_ASN1_OBJECT(out, dat->valid_policy);
+    BIO_puts(out, "\n");
+    BIO_printf(out, "%*s%s\n", indent + 2, "",
+               node_data_critical(dat) ? "Critical" : "Non Critical");
+    if (dat->qualifier_set)
+        print_qualifiers(out, dat->qualifier_set, indent + 2);
+    else
+        BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, "");
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_crld.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_crld.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_crld.c	(revision 331)
@@ -0,0 +1,509 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+#include "internal/x509_int.h"
+#include "ext_dat.h"
+
+static void *v2i_crld(const X509V3_EXT_METHOD *method,
+                      X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
+                     int indent);
+
+const X509V3_EXT_METHOD v3_crld = {
+    NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
+    0, 0, 0, 0,
+    0, 0,
+    0,
+    v2i_crld,
+    i2r_crldp, 0,
+    NULL
+};
+
+const X509V3_EXT_METHOD v3_freshest_crl = {
+    NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS),
+    0, 0, 0, 0,
+    0, 0,
+    0,
+    v2i_crld,
+    i2r_crldp, 0,
+    NULL
+};
+
+static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx,
+                                                    char *sect)
+{
+    STACK_OF(CONF_VALUE) *gnsect;
+    STACK_OF(GENERAL_NAME) *gens;
+    if (*sect == '@')
+        gnsect = X509V3_get_section(ctx, sect + 1);
+    else
+        gnsect = X509V3_parse_list(sect);
+    if (!gnsect) {
+        X509V3err(X509V3_F_GNAMES_FROM_SECTNAME, X509V3_R_SECTION_NOT_FOUND);
+        return NULL;
+    }
+    gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect);
+    if (*sect == '@')
+        X509V3_section_free(ctx, gnsect);
+    else
+        sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free);
+    return gens;
+}
+
+static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
+                               CONF_VALUE *cnf)
+{
+    STACK_OF(GENERAL_NAME) *fnm = NULL;
+    STACK_OF(X509_NAME_ENTRY) *rnm = NULL;
+
+    if (strncmp(cnf->name, "fullname", 9) == 0) {
+        fnm = gnames_from_sectname(ctx, cnf->value);
+        if (!fnm)
+            goto err;
+    } else if (strcmp(cnf->name, "relativename") == 0) {
+        int ret;
+        STACK_OF(CONF_VALUE) *dnsect;
+        X509_NAME *nm;
+        nm = X509_NAME_new();
+        if (nm == NULL)
+            return -1;
+        dnsect = X509V3_get_section(ctx, cnf->value);
+        if (!dnsect) {
+            X509V3err(X509V3_F_SET_DIST_POINT_NAME,
+                      X509V3_R_SECTION_NOT_FOUND);
+            return -1;
+        }
+        ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC);
+        X509V3_section_free(ctx, dnsect);
+        rnm = nm->entries;
+        nm->entries = NULL;
+        X509_NAME_free(nm);
+        if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0)
+            goto err;
+        /*
+         * Since its a name fragment can't have more than one RDNSequence
+         */
+        if (sk_X509_NAME_ENTRY_value(rnm,
+                                     sk_X509_NAME_ENTRY_num(rnm) - 1)->set) {
+            X509V3err(X509V3_F_SET_DIST_POINT_NAME,
+                      X509V3_R_INVALID_MULTIPLE_RDNS);
+            goto err;
+        }
+    } else
+        return 0;
+
+    if (*pdp) {
+        X509V3err(X509V3_F_SET_DIST_POINT_NAME,
+                  X509V3_R_DISTPOINT_ALREADY_SET);
+        goto err;
+    }
+
+    *pdp = DIST_POINT_NAME_new();
+    if (*pdp == NULL)
+        goto err;
+    if (fnm) {
+        (*pdp)->type = 0;
+        (*pdp)->name.fullname = fnm;
+    } else {
+        (*pdp)->type = 1;
+        (*pdp)->name.relativename = rnm;
+    }
+
+    return 1;
+
+ err:
+    sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free);
+    sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free);
+    return -1;
+}
+
+static const BIT_STRING_BITNAME reason_flags[] = {
+    {0, "Unused", "unused"},
+    {1, "Key Compromise", "keyCompromise"},
+    {2, "CA Compromise", "CACompromise"},
+    {3, "Affiliation Changed", "affiliationChanged"},
+    {4, "Superseded", "superseded"},
+    {5, "Cessation Of Operation", "cessationOfOperation"},
+    {6, "Certificate Hold", "certificateHold"},
+    {7, "Privilege Withdrawn", "privilegeWithdrawn"},
+    {8, "AA Compromise", "AACompromise"},
+    {-1, NULL, NULL}
+};
+
+static int set_reasons(ASN1_BIT_STRING **preas, char *value)
+{
+    STACK_OF(CONF_VALUE) *rsk = NULL;
+    const BIT_STRING_BITNAME *pbn;
+    const char *bnam;
+    int i, ret = 0;
+    rsk = X509V3_parse_list(value);
+    if (rsk == NULL)
+        return 0;
+    if (*preas != NULL)
+        goto err;
+    for (i = 0; i < sk_CONF_VALUE_num(rsk); i++) {
+        bnam = sk_CONF_VALUE_value(rsk, i)->name;
+        if (*preas == NULL) {
+            *preas = ASN1_BIT_STRING_new();
+            if (*preas == NULL)
+                goto err;
+        }
+        for (pbn = reason_flags; pbn->lname; pbn++) {
+            if (strcmp(pbn->sname, bnam) == 0) {
+                if (!ASN1_BIT_STRING_set_bit(*preas, pbn->bitnum, 1))
+                    goto err;
+                break;
+            }
+        }
+        if (!pbn->lname)
+            goto err;
+    }
+    ret = 1;
+
+ err:
+    sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free);
+    return ret;
+}
+
+static int print_reasons(BIO *out, const char *rname,
+                         ASN1_BIT_STRING *rflags, int indent)
+{
+    int first = 1;
+    const BIT_STRING_BITNAME *pbn;
+    BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, "");
+    for (pbn = reason_flags; pbn->lname; pbn++) {
+        if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) {
+            if (first)
+                first = 0;
+            else
+                BIO_puts(out, ", ");
+            BIO_puts(out, pbn->lname);
+        }
+    }
+    if (first)
+        BIO_puts(out, "<EMPTY>\n");
+    else
+        BIO_puts(out, "\n");
+    return 1;
+}
+
+static DIST_POINT *crldp_from_section(X509V3_CTX *ctx,
+                                      STACK_OF(CONF_VALUE) *nval)
+{
+    int i;
+    CONF_VALUE *cnf;
+    DIST_POINT *point = NULL;
+    point = DIST_POINT_new();
+    if (point == NULL)
+        goto err;
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        int ret;
+        cnf = sk_CONF_VALUE_value(nval, i);
+        ret = set_dist_point_name(&point->distpoint, ctx, cnf);
+        if (ret > 0)
+            continue;
+        if (ret < 0)
+            goto err;
+        if (strcmp(cnf->name, "reasons") == 0) {
+            if (!set_reasons(&point->reasons, cnf->value))
+                goto err;
+        } else if (strcmp(cnf->name, "CRLissuer") == 0) {
+            point->CRLissuer = gnames_from_sectname(ctx, cnf->value);
+            if (!point->CRLissuer)
+                goto err;
+        }
+    }
+
+    return point;
+
+ err:
+    DIST_POINT_free(point);
+    return NULL;
+}
+
+static void *v2i_crld(const X509V3_EXT_METHOD *method,
+                      X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+{
+    STACK_OF(DIST_POINT) *crld = NULL;
+    GENERAL_NAMES *gens = NULL;
+    GENERAL_NAME *gen = NULL;
+    CONF_VALUE *cnf;
+    int i;
+
+    if ((crld = sk_DIST_POINT_new_null()) == NULL)
+        goto merr;
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        DIST_POINT *point;
+        cnf = sk_CONF_VALUE_value(nval, i);
+        if (!cnf->value) {
+            STACK_OF(CONF_VALUE) *dpsect;
+            dpsect = X509V3_get_section(ctx, cnf->name);
+            if (!dpsect)
+                goto err;
+            point = crldp_from_section(ctx, dpsect);
+            X509V3_section_free(ctx, dpsect);
+            if (!point)
+                goto err;
+            if (!sk_DIST_POINT_push(crld, point)) {
+                DIST_POINT_free(point);
+                goto merr;
+            }
+        } else {
+            if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL)
+                goto err;
+            if ((gens = GENERAL_NAMES_new()) == NULL)
+                goto merr;
+            if (!sk_GENERAL_NAME_push(gens, gen))
+                goto merr;
+            gen = NULL;
+            if ((point = DIST_POINT_new()) == NULL)
+                goto merr;
+            if (!sk_DIST_POINT_push(crld, point)) {
+                DIST_POINT_free(point);
+                goto merr;
+            }
+            if ((point->distpoint = DIST_POINT_NAME_new()) == NULL)
+                goto merr;
+            point->distpoint->name.fullname = gens;
+            point->distpoint->type = 0;
+            gens = NULL;
+        }
+    }
+    return crld;
+
+ merr:
+    X509V3err(X509V3_F_V2I_CRLD, ERR_R_MALLOC_FAILURE);
+ err:
+    GENERAL_NAME_free(gen);
+    GENERAL_NAMES_free(gens);
+    sk_DIST_POINT_pop_free(crld, DIST_POINT_free);
+    return NULL;
+}
+
+static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                  void *exarg)
+{
+    DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval;
+
+    switch (operation) {
+    case ASN1_OP_NEW_POST:
+        dpn->dpname = NULL;
+        break;
+
+    case ASN1_OP_FREE_POST:
+        X509_NAME_free(dpn->dpname);
+        break;
+    }
+    return 1;
+}
+
+
+ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = {
+        ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0),
+        ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1)
+} ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type)
+
+
+IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME)
+
+ASN1_SEQUENCE(DIST_POINT) = {
+        ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0),
+        ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1),
+        ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2)
+} ASN1_SEQUENCE_END(DIST_POINT)
+
+IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT)
+
+ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT)
+ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS)
+
+IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS)
+
+ASN1_SEQUENCE(ISSUING_DIST_POINT) = {
+        ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0),
+        ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1),
+        ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2),
+        ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3),
+        ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4),
+        ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5)
+} ASN1_SEQUENCE_END(ISSUING_DIST_POINT)
+
+IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
+
+static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
+                   int indent);
+static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+                     STACK_OF(CONF_VALUE) *nval);
+
+const X509V3_EXT_METHOD v3_idp = {
+    NID_issuing_distribution_point, X509V3_EXT_MULTILINE,
+    ASN1_ITEM_ref(ISSUING_DIST_POINT),
+    0, 0, 0, 0,
+    0, 0,
+    0,
+    v2i_idp,
+    i2r_idp, 0,
+    NULL
+};
+
+static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+                     STACK_OF(CONF_VALUE) *nval)
+{
+    ISSUING_DIST_POINT *idp = NULL;
+    CONF_VALUE *cnf;
+    char *name, *val;
+    int i, ret;
+    idp = ISSUING_DIST_POINT_new();
+    if (idp == NULL)
+        goto merr;
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        cnf = sk_CONF_VALUE_value(nval, i);
+        name = cnf->name;
+        val = cnf->value;
+        ret = set_dist_point_name(&idp->distpoint, ctx, cnf);
+        if (ret > 0)
+            continue;
+        if (ret < 0)
+            goto err;
+        if (strcmp(name, "onlyuser") == 0) {
+            if (!X509V3_get_value_bool(cnf, &idp->onlyuser))
+                goto err;
+        } else if (strcmp(name, "onlyCA") == 0) {
+            if (!X509V3_get_value_bool(cnf, &idp->onlyCA))
+                goto err;
+        } else if (strcmp(name, "onlyAA") == 0) {
+            if (!X509V3_get_value_bool(cnf, &idp->onlyattr))
+                goto err;
+        } else if (strcmp(name, "indirectCRL") == 0) {
+            if (!X509V3_get_value_bool(cnf, &idp->indirectCRL))
+                goto err;
+        } else if (strcmp(name, "onlysomereasons") == 0) {
+            if (!set_reasons(&idp->onlysomereasons, val))
+                goto err;
+        } else {
+            X509V3err(X509V3_F_V2I_IDP, X509V3_R_INVALID_NAME);
+            X509V3_conf_err(cnf);
+            goto err;
+        }
+    }
+    return idp;
+
+ merr:
+    X509V3err(X509V3_F_V2I_IDP, ERR_R_MALLOC_FAILURE);
+ err:
+    ISSUING_DIST_POINT_free(idp);
+    return NULL;
+}
+
+static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent)
+{
+    int i;
+    for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+        BIO_printf(out, "%*s", indent + 2, "");
+        GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i));
+        BIO_puts(out, "\n");
+    }
+    return 1;
+}
+
+static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent)
+{
+    if (dpn->type == 0) {
+        BIO_printf(out, "%*sFull Name:\n", indent, "");
+        print_gens(out, dpn->name.fullname, indent);
+    } else {
+        X509_NAME ntmp;
+        ntmp.entries = dpn->name.relativename;
+        BIO_printf(out, "%*sRelative Name:\n%*s", indent, "", indent + 2, "");
+        X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE);
+        BIO_puts(out, "\n");
+    }
+    return 1;
+}
+
+static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out,
+                   int indent)
+{
+    ISSUING_DIST_POINT *idp = pidp;
+    if (idp->distpoint)
+        print_distpoint(out, idp->distpoint, indent);
+    if (idp->onlyuser > 0)
+        BIO_printf(out, "%*sOnly User Certificates\n", indent, "");
+    if (idp->onlyCA > 0)
+        BIO_printf(out, "%*sOnly CA Certificates\n", indent, "");
+    if (idp->indirectCRL > 0)
+        BIO_printf(out, "%*sIndirect CRL\n", indent, "");
+    if (idp->onlysomereasons)
+        print_reasons(out, "Only Some Reasons", idp->onlysomereasons, indent);
+    if (idp->onlyattr > 0)
+        BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, "");
+    if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0)
+        && (idp->indirectCRL <= 0) && !idp->onlysomereasons
+        && (idp->onlyattr <= 0))
+        BIO_printf(out, "%*s<EMPTY>\n", indent, "");
+
+    return 1;
+}
+
+static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out,
+                     int indent)
+{
+    STACK_OF(DIST_POINT) *crld = pcrldp;
+    DIST_POINT *point;
+    int i;
+    for (i = 0; i < sk_DIST_POINT_num(crld); i++) {
+        BIO_puts(out, "\n");
+        point = sk_DIST_POINT_value(crld, i);
+        if (point->distpoint)
+            print_distpoint(out, point->distpoint, indent);
+        if (point->reasons)
+            print_reasons(out, "Reasons", point->reasons, indent);
+        if (point->CRLissuer) {
+            BIO_printf(out, "%*sCRL Issuer:\n", indent, "");
+            print_gens(out, point->CRLissuer, indent);
+        }
+    }
+    return 1;
+}
+
+int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname)
+{
+    int i;
+    STACK_OF(X509_NAME_ENTRY) *frag;
+    X509_NAME_ENTRY *ne;
+    if (!dpn || (dpn->type != 1))
+        return 1;
+    frag = dpn->name.relativename;
+    dpn->dpname = X509_NAME_dup(iname);
+    if (!dpn->dpname)
+        return 0;
+    for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) {
+        ne = sk_X509_NAME_ENTRY_value(frag, i);
+        if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) {
+            X509_NAME_free(dpn->dpname);
+            dpn->dpname = NULL;
+            return 0;
+        }
+    }
+    /* generate cached encoding of name */
+    if (i2d_X509_NAME(dpn->dpname, NULL) < 0) {
+        X509_NAME_free(dpn->dpname);
+        dpn->dpname = NULL;
+        return 0;
+    }
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_enum.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_enum.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_enum.c	(revision 331)
@@ -0,0 +1,53 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509v3.h>
+#include "ext_dat.h"
+
+static ENUMERATED_NAMES crl_reasons[] = {
+    {CRL_REASON_UNSPECIFIED, "Unspecified", "unspecified"},
+    {CRL_REASON_KEY_COMPROMISE, "Key Compromise", "keyCompromise"},
+    {CRL_REASON_CA_COMPROMISE, "CA Compromise", "CACompromise"},
+    {CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed",
+     "affiliationChanged"},
+    {CRL_REASON_SUPERSEDED, "Superseded", "superseded"},
+    {CRL_REASON_CESSATION_OF_OPERATION,
+     "Cessation Of Operation", "cessationOfOperation"},
+    {CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold"},
+    {CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL"},
+    {CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn",
+     "privilegeWithdrawn"},
+    {CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise"},
+    {-1, NULL, NULL}
+};
+
+const X509V3_EXT_METHOD v3_crl_reason = {
+    NID_crl_reason, 0, ASN1_ITEM_ref(ASN1_ENUMERATED),
+    0, 0, 0, 0,
+    (X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE,
+    0,
+    0, 0, 0, 0,
+    crl_reasons
+};
+
+char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method, 
+                                const ASN1_ENUMERATED *e)
+{
+    ENUMERATED_NAMES *enam;
+    long strval;
+
+    strval = ASN1_ENUMERATED_get(e);
+    for (enam = method->usr_data; enam->lname; enam++) {
+        if (strval == enam->bitnum)
+            return OPENSSL_strdup(enam->lname);
+    }
+    return i2s_ASN1_ENUMERATED(method, e);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_extku.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_extku.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_extku.c	(revision 331)
@@ -0,0 +1,100 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+#include "ext_dat.h"
+
+static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
+                                    X509V3_CTX *ctx,
+                                    STACK_OF(CONF_VALUE) *nval);
+static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD
+                                                    *method, void *eku, STACK_OF(CONF_VALUE)
+                                                    *extlist);
+
+const X509V3_EXT_METHOD v3_ext_ku = {
+    NID_ext_key_usage, 0,
+    ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
+    0, 0, 0, 0,
+    0, 0,
+    i2v_EXTENDED_KEY_USAGE,
+    v2i_EXTENDED_KEY_USAGE,
+    0, 0,
+    NULL
+};
+
+/* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */
+const X509V3_EXT_METHOD v3_ocsp_accresp = {
+    NID_id_pkix_OCSP_acceptableResponses, 0,
+    ASN1_ITEM_ref(EXTENDED_KEY_USAGE),
+    0, 0, 0, 0,
+    0, 0,
+    i2v_EXTENDED_KEY_USAGE,
+    v2i_EXTENDED_KEY_USAGE,
+    0, 0,
+    NULL
+};
+
+ASN1_ITEM_TEMPLATE(EXTENDED_KEY_USAGE) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, EXTENDED_KEY_USAGE, ASN1_OBJECT)
+ASN1_ITEM_TEMPLATE_END(EXTENDED_KEY_USAGE)
+
+IMPLEMENT_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE)
+
+static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD
+                                                    *method, void *a, STACK_OF(CONF_VALUE)
+                                                    *ext_list)
+{
+    EXTENDED_KEY_USAGE *eku = a;
+    int i;
+    ASN1_OBJECT *obj;
+    char obj_tmp[80];
+    for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
+        obj = sk_ASN1_OBJECT_value(eku, i);
+        i2t_ASN1_OBJECT(obj_tmp, 80, obj);
+        X509V3_add_value(NULL, obj_tmp, &ext_list);
+    }
+    return ext_list;
+}
+
+static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
+                                    X509V3_CTX *ctx,
+                                    STACK_OF(CONF_VALUE) *nval)
+{
+    EXTENDED_KEY_USAGE *extku;
+    char *extval;
+    ASN1_OBJECT *objtmp;
+    CONF_VALUE *val;
+    int i;
+
+    if ((extku = sk_ASN1_OBJECT_new_null()) == NULL) {
+        X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        val = sk_CONF_VALUE_value(nval, i);
+        if (val->value)
+            extval = val->value;
+        else
+            extval = val->name;
+        if ((objtmp = OBJ_txt2obj(extval, 0)) == NULL) {
+            sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free);
+            X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE,
+                      X509V3_R_INVALID_OBJECT_IDENTIFIER);
+            X509V3_conf_err(val);
+            return NULL;
+        }
+        sk_ASN1_OBJECT_push(extku, objtmp);
+    }
+    return extku;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_genn.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_genn.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_genn.c	(revision 331)
@@ -0,0 +1,200 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+ASN1_SEQUENCE(OTHERNAME) = {
+        ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT),
+        /* Maybe have a true ANY DEFINED BY later */
+        ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0)
+} ASN1_SEQUENCE_END(OTHERNAME)
+
+IMPLEMENT_ASN1_FUNCTIONS(OTHERNAME)
+
+ASN1_SEQUENCE(EDIPARTYNAME) = {
+        ASN1_IMP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0),
+        ASN1_IMP_OPT(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1)
+} ASN1_SEQUENCE_END(EDIPARTYNAME)
+
+IMPLEMENT_ASN1_FUNCTIONS(EDIPARTYNAME)
+
+ASN1_CHOICE(GENERAL_NAME) = {
+        ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME),
+        ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL),
+        ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS),
+        /* Don't decode this */
+        ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400),
+        /* X509_NAME is a CHOICE type so use EXPLICIT */
+        ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME),
+        ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY),
+        ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, GEN_URI),
+        ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD),
+        ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID)
+} ASN1_CHOICE_END(GENERAL_NAME)
+
+IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAME)
+
+ASN1_ITEM_TEMPLATE(GENERAL_NAMES) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, GENERAL_NAME)
+ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES)
+
+IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES)
+
+GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a)
+{
+    return (GENERAL_NAME *)ASN1_dup((i2d_of_void *)i2d_GENERAL_NAME,
+                                    (d2i_of_void *)d2i_GENERAL_NAME,
+                                    (char *)a);
+}
+
+/* Returns 0 if they are equal, != 0 otherwise. */
+int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
+{
+    int result = -1;
+
+    if (!a || !b || a->type != b->type)
+        return -1;
+    switch (a->type) {
+    case GEN_X400:
+    case GEN_EDIPARTY:
+        result = ASN1_TYPE_cmp(a->d.other, b->d.other);
+        break;
+
+    case GEN_OTHERNAME:
+        result = OTHERNAME_cmp(a->d.otherName, b->d.otherName);
+        break;
+
+    case GEN_EMAIL:
+    case GEN_DNS:
+    case GEN_URI:
+        result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
+        break;
+
+    case GEN_DIRNAME:
+        result = X509_NAME_cmp(a->d.dirn, b->d.dirn);
+        break;
+
+    case GEN_IPADD:
+        result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
+        break;
+
+    case GEN_RID:
+        result = OBJ_cmp(a->d.rid, b->d.rid);
+        break;
+    }
+    return result;
+}
+
+/* Returns 0 if they are equal, != 0 otherwise. */
+int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b)
+{
+    int result = -1;
+
+    if (!a || !b)
+        return -1;
+    /* Check their type first. */
+    if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0)
+        return result;
+    /* Check the value. */
+    result = ASN1_TYPE_cmp(a->value, b->value);
+    return result;
+}
+
+void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value)
+{
+    switch (type) {
+    case GEN_X400:
+    case GEN_EDIPARTY:
+        a->d.other = value;
+        break;
+
+    case GEN_OTHERNAME:
+        a->d.otherName = value;
+        break;
+
+    case GEN_EMAIL:
+    case GEN_DNS:
+    case GEN_URI:
+        a->d.ia5 = value;
+        break;
+
+    case GEN_DIRNAME:
+        a->d.dirn = value;
+        break;
+
+    case GEN_IPADD:
+        a->d.ip = value;
+        break;
+
+    case GEN_RID:
+        a->d.rid = value;
+        break;
+    }
+    a->type = type;
+}
+
+void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype)
+{
+    if (ptype)
+        *ptype = a->type;
+    switch (a->type) {
+    case GEN_X400:
+    case GEN_EDIPARTY:
+        return a->d.other;
+
+    case GEN_OTHERNAME:
+        return a->d.otherName;
+
+    case GEN_EMAIL:
+    case GEN_DNS:
+    case GEN_URI:
+        return a->d.ia5;
+
+    case GEN_DIRNAME:
+        return a->d.dirn;
+
+    case GEN_IPADD:
+        return a->d.ip;
+
+    case GEN_RID:
+        return a->d.rid;
+
+    default:
+        return NULL;
+    }
+}
+
+int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
+                                ASN1_OBJECT *oid, ASN1_TYPE *value)
+{
+    OTHERNAME *oth;
+    oth = OTHERNAME_new();
+    if (oth == NULL)
+        return 0;
+    oth->type_id = oid;
+    oth->value = value;
+    GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth);
+    return 1;
+}
+
+int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen,
+                                ASN1_OBJECT **poid, ASN1_TYPE **pvalue)
+{
+    if (gen->type != GEN_OTHERNAME)
+        return 0;
+    if (poid)
+        *poid = gen->d.otherName->type_id;
+    if (pvalue)
+        *pvalue = gen->d.otherName->value;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_ia5.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_ia5.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_ia5.c	(revision 331)
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+#include "ext_dat.h"
+
+const X509V3_EXT_METHOD v3_ns_ia5_list[8] = {
+    EXT_IA5STRING(NID_netscape_base_url),
+    EXT_IA5STRING(NID_netscape_revocation_url),
+    EXT_IA5STRING(NID_netscape_ca_revocation_url),
+    EXT_IA5STRING(NID_netscape_renewal_url),
+    EXT_IA5STRING(NID_netscape_ca_policy_url),
+    EXT_IA5STRING(NID_netscape_ssl_server_name),
+    EXT_IA5STRING(NID_netscape_comment),
+    EXT_END
+};
+
+char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5)
+{
+    char *tmp;
+
+    if (!ia5 || !ia5->length)
+        return NULL;
+    if ((tmp = OPENSSL_malloc(ia5->length + 1)) == NULL) {
+        X509V3err(X509V3_F_I2S_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    memcpy(tmp, ia5->data, ia5->length);
+    tmp[ia5->length] = 0;
+    return tmp;
+}
+
+ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
+                                   X509V3_CTX *ctx, const char *str)
+{
+    ASN1_IA5STRING *ia5;
+    if (!str) {
+        X509V3err(X509V3_F_S2I_ASN1_IA5STRING,
+                  X509V3_R_INVALID_NULL_ARGUMENT);
+        return NULL;
+    }
+    if ((ia5 = ASN1_IA5STRING_new()) == NULL)
+        goto err;
+    if (!ASN1_STRING_set((ASN1_STRING *)ia5, str, strlen(str))) {
+        ASN1_IA5STRING_free(ia5);
+        return NULL;
+    }
+#ifdef CHARSET_EBCDIC
+    ebcdic2ascii(ia5->data, ia5->data, ia5->length);
+#endif                          /* CHARSET_EBCDIC */
+    return ia5;
+ err:
+    X509V3err(X509V3_F_S2I_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE);
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_info.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_info.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_info.c	(revision 331)
@@ -0,0 +1,157 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+#include "ext_dat.h"
+
+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
+                                                       *method, AUTHORITY_INFO_ACCESS
+                                                       *ainfo, STACK_OF(CONF_VALUE)
+                                                       *ret);
+static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
+                                                        *method,
+                                                        X509V3_CTX *ctx,
+                                                        STACK_OF(CONF_VALUE)
+                                                        *nval);
+
+const X509V3_EXT_METHOD v3_info = { NID_info_access, X509V3_EXT_MULTILINE,
+    ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
+    0, 0, 0, 0,
+    0, 0,
+    (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS,
+    (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
+    0, 0,
+    NULL
+};
+
+const X509V3_EXT_METHOD v3_sinfo = { NID_sinfo_access, X509V3_EXT_MULTILINE,
+    ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
+    0, 0, 0, 0,
+    0, 0,
+    (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS,
+    (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
+    0, 0,
+    NULL
+};
+
+ASN1_SEQUENCE(ACCESS_DESCRIPTION) = {
+        ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT),
+        ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME)
+} ASN1_SEQUENCE_END(ACCESS_DESCRIPTION)
+
+IMPLEMENT_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
+
+ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION)
+ASN1_ITEM_TEMPLATE_END(AUTHORITY_INFO_ACCESS)
+
+IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
+
+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
+                                                       *method, AUTHORITY_INFO_ACCESS
+                                                       *ainfo, STACK_OF(CONF_VALUE)
+                                                       *ret)
+{
+    ACCESS_DESCRIPTION *desc;
+    int i, nlen;
+    char objtmp[80], *ntmp;
+    CONF_VALUE *vtmp;
+    for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) {
+        desc = sk_ACCESS_DESCRIPTION_value(ainfo, i);
+        ret = i2v_GENERAL_NAME(method, desc->location, ret);
+        if (!ret)
+            break;
+        vtmp = sk_CONF_VALUE_value(ret, i);
+        i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method);
+        nlen = strlen(objtmp) + strlen(vtmp->name) + 5;
+        ntmp = OPENSSL_malloc(nlen);
+        if (ntmp == NULL) {
+            X509V3err(X509V3_F_I2V_AUTHORITY_INFO_ACCESS,
+                      ERR_R_MALLOC_FAILURE);
+            return NULL;
+        }
+        OPENSSL_strlcpy(ntmp, objtmp, nlen);
+        OPENSSL_strlcat(ntmp, " - ", nlen);
+        OPENSSL_strlcat(ntmp, vtmp->name, nlen);
+        OPENSSL_free(vtmp->name);
+        vtmp->name = ntmp;
+
+    }
+    if (!ret)
+        return sk_CONF_VALUE_new_null();
+    return ret;
+}
+
+static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
+                                                        *method,
+                                                        X509V3_CTX *ctx,
+                                                        STACK_OF(CONF_VALUE)
+                                                        *nval)
+{
+    AUTHORITY_INFO_ACCESS *ainfo = NULL;
+    CONF_VALUE *cnf, ctmp;
+    ACCESS_DESCRIPTION *acc;
+    int i, objlen;
+    char *objtmp, *ptmp;
+
+    if ((ainfo = sk_ACCESS_DESCRIPTION_new_null()) == NULL) {
+        X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        cnf = sk_CONF_VALUE_value(nval, i);
+        if ((acc = ACCESS_DESCRIPTION_new()) == NULL
+            || !sk_ACCESS_DESCRIPTION_push(ainfo, acc)) {
+            X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,
+                      ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        ptmp = strchr(cnf->name, ';');
+        if (!ptmp) {
+            X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,
+                      X509V3_R_INVALID_SYNTAX);
+            goto err;
+        }
+        objlen = ptmp - cnf->name;
+        ctmp.name = ptmp + 1;
+        ctmp.value = cnf->value;
+        if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0))
+            goto err;
+        if ((objtmp = OPENSSL_strndup(cnf->name, objlen)) == NULL) {
+            X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,
+                      ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        acc->method = OBJ_txt2obj(objtmp, 0);
+        if (!acc->method) {
+            X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS,
+                      X509V3_R_BAD_OBJECT);
+            ERR_add_error_data(2, "value=", objtmp);
+            OPENSSL_free(objtmp);
+            goto err;
+        }
+        OPENSSL_free(objtmp);
+
+    }
+    return ainfo;
+ err:
+    sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free);
+    return NULL;
+}
+
+int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION *a)
+{
+    i2a_ASN1_OBJECT(bp, a->method);
+    return 2;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_int.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_int.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_int.c	(revision 331)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509v3.h>
+#include "ext_dat.h"
+
+const X509V3_EXT_METHOD v3_crl_num = {
+    NID_crl_number, 0, ASN1_ITEM_ref(ASN1_INTEGER),
+    0, 0, 0, 0,
+    (X509V3_EXT_I2S)i2s_ASN1_INTEGER,
+    0,
+    0, 0, 0, 0, NULL
+};
+
+const X509V3_EXT_METHOD v3_delta_crl = {
+    NID_delta_crl, 0, ASN1_ITEM_ref(ASN1_INTEGER),
+    0, 0, 0, 0,
+    (X509V3_EXT_I2S)i2s_ASN1_INTEGER,
+    0,
+    0, 0, 0, 0, NULL
+};
+
+static void *s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx,
+                          const char *value)
+{
+    return s2i_ASN1_INTEGER(meth, value);
+}
+
+const X509V3_EXT_METHOD v3_inhibit_anyp = {
+    NID_inhibit_any_policy, 0, ASN1_ITEM_ref(ASN1_INTEGER),
+    0, 0, 0, 0,
+    (X509V3_EXT_I2S)i2s_ASN1_INTEGER,
+    (X509V3_EXT_S2I)s2i_asn1_int,
+    0, 0, 0, 0, NULL
+};
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_lib.c	(revision 331)
@@ -0,0 +1,360 @@
+/*
+ * Copyright 1999-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
+ */
+
+/* X509 v3 extension utilities */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+#include "ext_dat.h"
+
+static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL;
+
+static int ext_cmp(const X509V3_EXT_METHOD *const *a,
+                   const X509V3_EXT_METHOD *const *b);
+static void ext_list_free(X509V3_EXT_METHOD *ext);
+
+int X509V3_EXT_add(X509V3_EXT_METHOD *ext)
+{
+    if (ext_list == NULL
+        && (ext_list = sk_X509V3_EXT_METHOD_new(ext_cmp)) == NULL) {
+        X509V3err(X509V3_F_X509V3_EXT_ADD, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) {
+        X509V3err(X509V3_F_X509V3_EXT_ADD, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    return 1;
+}
+
+static int ext_cmp(const X509V3_EXT_METHOD *const *a,
+                   const X509V3_EXT_METHOD *const *b)
+{
+    return ((*a)->ext_nid - (*b)->ext_nid);
+}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *,
+                           const X509V3_EXT_METHOD *, ext);
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *,
+                             const X509V3_EXT_METHOD *, ext);
+
+/*
+ * This table will be searched using OBJ_bsearch so it *must* kept in order
+ * of the ext_nid values.
+ */
+
+static const X509V3_EXT_METHOD *standard_exts[] = {
+    &v3_nscert,
+    &v3_ns_ia5_list[0],
+    &v3_ns_ia5_list[1],
+    &v3_ns_ia5_list[2],
+    &v3_ns_ia5_list[3],
+    &v3_ns_ia5_list[4],
+    &v3_ns_ia5_list[5],
+    &v3_ns_ia5_list[6],
+    &v3_skey_id,
+    &v3_key_usage,
+    &v3_pkey_usage_period,
+    &v3_alt[0],
+    &v3_alt[1],
+    &v3_bcons,
+    &v3_crl_num,
+    &v3_cpols,
+    &v3_akey_id,
+    &v3_crld,
+    &v3_ext_ku,
+    &v3_delta_crl,
+    &v3_crl_reason,
+#ifndef OPENSSL_NO_OCSP
+    &v3_crl_invdate,
+#endif
+    &v3_sxnet,
+    &v3_info,
+#ifndef OPENSSL_NO_RFC3779
+    &v3_addr,
+    &v3_asid,
+#endif
+#ifndef OPENSSL_NO_OCSP
+    &v3_ocsp_nonce,
+    &v3_ocsp_crlid,
+    &v3_ocsp_accresp,
+    &v3_ocsp_nocheck,
+    &v3_ocsp_acutoff,
+    &v3_ocsp_serviceloc,
+#endif
+    &v3_sinfo,
+    &v3_policy_constraints,
+#ifndef OPENSSL_NO_OCSP
+    &v3_crl_hold,
+#endif
+    &v3_pci,
+    &v3_name_constraints,
+    &v3_policy_mappings,
+    &v3_inhibit_anyp,
+    &v3_idp,
+    &v3_alt[2],
+    &v3_freshest_crl,
+#ifndef OPENSSL_NO_CT
+    &v3_ct_scts[0],
+    &v3_ct_scts[1],
+    &v3_ct_scts[2],
+#endif
+    &v3_tls_feature,
+};
+
+/* Number of standard extensions */
+
+#define STANDARD_EXTENSION_COUNT OSSL_NELEM(standard_exts)
+
+const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid)
+{
+    X509V3_EXT_METHOD tmp;
+    const X509V3_EXT_METHOD *t = &tmp, *const *ret;
+    int idx;
+    if (nid < 0)
+        return NULL;
+    tmp.ext_nid = nid;
+    ret = OBJ_bsearch_ext(&t, standard_exts, STANDARD_EXTENSION_COUNT);
+    if (ret)
+        return *ret;
+    if (!ext_list)
+        return NULL;
+    idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp);
+    if (idx == -1)
+        return NULL;
+    return sk_X509V3_EXT_METHOD_value(ext_list, idx);
+}
+
+const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext)
+{
+    int nid;
+    if ((nid = OBJ_obj2nid(X509_EXTENSION_get_object(ext))) == NID_undef)
+        return NULL;
+    return X509V3_EXT_get_nid(nid);
+}
+
+int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist)
+{
+    for (; extlist->ext_nid != -1; extlist++)
+        if (!X509V3_EXT_add(extlist))
+            return 0;
+    return 1;
+}
+
+int X509V3_EXT_add_alias(int nid_to, int nid_from)
+{
+    const X509V3_EXT_METHOD *ext;
+    X509V3_EXT_METHOD *tmpext;
+
+    if ((ext = X509V3_EXT_get_nid(nid_from)) == NULL) {
+        X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS, X509V3_R_EXTENSION_NOT_FOUND);
+        return 0;
+    }
+    if ((tmpext = OPENSSL_malloc(sizeof(*tmpext))) == NULL) {
+        X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    *tmpext = *ext;
+    tmpext->ext_nid = nid_to;
+    tmpext->ext_flags |= X509V3_EXT_DYNAMIC;
+    return X509V3_EXT_add(tmpext);
+}
+
+void X509V3_EXT_cleanup(void)
+{
+    sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free);
+    ext_list = NULL;
+}
+
+static void ext_list_free(X509V3_EXT_METHOD *ext)
+{
+    if (ext->ext_flags & X509V3_EXT_DYNAMIC)
+        OPENSSL_free(ext);
+}
+
+/*
+ * Legacy function: we don't need to add standard extensions any more because
+ * they are now kept in ext_dat.h.
+ */
+
+int X509V3_add_standard_extensions(void)
+{
+    return 1;
+}
+
+/* Return an extension internal structure */
+
+void *X509V3_EXT_d2i(X509_EXTENSION *ext)
+{
+    const X509V3_EXT_METHOD *method;
+    const unsigned char *p;
+    ASN1_STRING *extvalue;
+    int extlen;
+
+    if ((method = X509V3_EXT_get(ext)) == NULL)
+        return NULL;
+    extvalue = X509_EXTENSION_get_data(ext);
+    p = ASN1_STRING_get0_data(extvalue);
+    extlen = ASN1_STRING_length(extvalue);
+    if (method->it)
+        return ASN1_item_d2i(NULL, &p, extlen, ASN1_ITEM_ptr(method->it));
+    return method->d2i(NULL, &p, extlen);
+}
+
+/*-
+ * Get critical flag and decoded version of extension from a NID.
+ * The "idx" variable returns the last found extension and can
+ * be used to retrieve multiple extensions of the same NID.
+ * However multiple extensions with the same NID is usually
+ * due to a badly encoded certificate so if idx is NULL we
+ * choke if multiple extensions exist.
+ * The "crit" variable is set to the critical value.
+ * The return value is the decoded extension or NULL on
+ * error. The actual error can have several different causes,
+ * the value of *crit reflects the cause:
+ * >= 0, extension found but not decoded (reflects critical value).
+ * -1 extension not found.
+ * -2 extension occurs more than once.
+ */
+
+void *X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *x, int nid, int *crit,
+                     int *idx)
+{
+    int lastpos, i;
+    X509_EXTENSION *ex, *found_ex = NULL;
+    if (!x) {
+        if (idx)
+            *idx = -1;
+        if (crit)
+            *crit = -1;
+        return NULL;
+    }
+    if (idx)
+        lastpos = *idx + 1;
+    else
+        lastpos = 0;
+    if (lastpos < 0)
+        lastpos = 0;
+    for (i = lastpos; i < sk_X509_EXTENSION_num(x); i++) {
+        ex = sk_X509_EXTENSION_value(x, i);
+        if (OBJ_obj2nid(X509_EXTENSION_get_object(ex)) == nid) {
+            if (idx) {
+                *idx = i;
+                found_ex = ex;
+                break;
+            } else if (found_ex) {
+                /* Found more than one */
+                if (crit)
+                    *crit = -2;
+                return NULL;
+            }
+            found_ex = ex;
+        }
+    }
+    if (found_ex) {
+        /* Found it */
+        if (crit)
+            *crit = X509_EXTENSION_get_critical(found_ex);
+        return X509V3_EXT_d2i(found_ex);
+    }
+
+    /* Extension not found */
+    if (idx)
+        *idx = -1;
+    if (crit)
+        *crit = -1;
+    return NULL;
+}
+
+/*
+ * This function is a general extension append, replace and delete utility.
+ * The precise operation is governed by the 'flags' value. The 'crit' and
+ * 'value' arguments (if relevant) are the extensions internal structure.
+ */
+
+int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value,
+                    int crit, unsigned long flags)
+{
+    int extidx = -1;
+    int errcode;
+    X509_EXTENSION *ext, *extmp;
+    unsigned long ext_op = flags & X509V3_ADD_OP_MASK;
+
+    /*
+     * If appending we don't care if it exists, otherwise look for existing
+     * extension.
+     */
+    if (ext_op != X509V3_ADD_APPEND)
+        extidx = X509v3_get_ext_by_NID(*x, nid, -1);
+
+    /* See if extension exists */
+    if (extidx >= 0) {
+        /* If keep existing, nothing to do */
+        if (ext_op == X509V3_ADD_KEEP_EXISTING)
+            return 1;
+        /* If default then its an error */
+        if (ext_op == X509V3_ADD_DEFAULT) {
+            errcode = X509V3_R_EXTENSION_EXISTS;
+            goto err;
+        }
+        /* If delete, just delete it */
+        if (ext_op == X509V3_ADD_DELETE) {
+            if (!sk_X509_EXTENSION_delete(*x, extidx))
+                return -1;
+            return 1;
+        }
+    } else {
+        /*
+         * If replace existing or delete, error since extension must exist
+         */
+        if ((ext_op == X509V3_ADD_REPLACE_EXISTING) ||
+            (ext_op == X509V3_ADD_DELETE)) {
+            errcode = X509V3_R_EXTENSION_NOT_FOUND;
+            goto err;
+        }
+    }
+
+    /*
+     * If we get this far then we have to create an extension: could have
+     * some flags for alternative encoding schemes...
+     */
+
+    ext = X509V3_EXT_i2d(nid, crit, value);
+
+    if (!ext) {
+        X509V3err(X509V3_F_X509V3_ADD1_I2D,
+                  X509V3_R_ERROR_CREATING_EXTENSION);
+        return 0;
+    }
+
+    /* If extension exists replace it.. */
+    if (extidx >= 0) {
+        extmp = sk_X509_EXTENSION_value(*x, extidx);
+        X509_EXTENSION_free(extmp);
+        if (!sk_X509_EXTENSION_set(*x, extidx, ext))
+            return -1;
+        return 1;
+    }
+
+    if (*x == NULL
+        && (*x = sk_X509_EXTENSION_new_null()) == NULL)
+        return -1;
+    if (!sk_X509_EXTENSION_push(*x, ext))
+        return -1;
+
+    return 1;
+
+ err:
+    if (!(flags & X509V3_ADD_SILENT))
+        X509V3err(X509V3_F_X509V3_ADD1_I2D, errcode);
+    return 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_ncons.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_ncons.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_ncons.c	(revision 331)
@@ -0,0 +1,513 @@
+/*
+ * Copyright 2003-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include "internal/asn1_int.h"
+#include <openssl/asn1t.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+#include "internal/x509_int.h"
+#include "ext_dat.h"
+
+static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
+                                  X509V3_CTX *ctx,
+                                  STACK_OF(CONF_VALUE) *nval);
+static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
+                                BIO *bp, int ind);
+static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
+                                   STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp,
+                                   int ind, const char *name);
+static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip);
+
+static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc);
+static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen);
+static int nc_dn(X509_NAME *sub, X509_NAME *nm);
+static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns);
+static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml);
+static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base);
+static int nc_ip(ASN1_OCTET_STRING *ip, ASN1_OCTET_STRING *base);
+
+const X509V3_EXT_METHOD v3_name_constraints = {
+    NID_name_constraints, 0,
+    ASN1_ITEM_ref(NAME_CONSTRAINTS),
+    0, 0, 0, 0,
+    0, 0,
+    0, v2i_NAME_CONSTRAINTS,
+    i2r_NAME_CONSTRAINTS, 0,
+    NULL
+};
+
+ASN1_SEQUENCE(GENERAL_SUBTREE) = {
+        ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME),
+        ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0),
+        ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1)
+} ASN1_SEQUENCE_END(GENERAL_SUBTREE)
+
+ASN1_SEQUENCE(NAME_CONSTRAINTS) = {
+        ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees,
+                                                        GENERAL_SUBTREE, 0),
+        ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees,
+                                                        GENERAL_SUBTREE, 1),
+} ASN1_SEQUENCE_END(NAME_CONSTRAINTS)
+
+
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
+
+static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
+                                  X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+{
+    int i;
+    CONF_VALUE tval, *val;
+    STACK_OF(GENERAL_SUBTREE) **ptree = NULL;
+    NAME_CONSTRAINTS *ncons = NULL;
+    GENERAL_SUBTREE *sub = NULL;
+
+    ncons = NAME_CONSTRAINTS_new();
+    if (ncons == NULL)
+        goto memerr;
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        val = sk_CONF_VALUE_value(nval, i);
+        if (strncmp(val->name, "permitted", 9) == 0 && val->name[9]) {
+            ptree = &ncons->permittedSubtrees;
+            tval.name = val->name + 10;
+        } else if (strncmp(val->name, "excluded", 8) == 0 && val->name[8]) {
+            ptree = &ncons->excludedSubtrees;
+            tval.name = val->name + 9;
+        } else {
+            X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, X509V3_R_INVALID_SYNTAX);
+            goto err;
+        }
+        tval.value = val->value;
+        sub = GENERAL_SUBTREE_new();
+        if (sub == NULL)
+            goto memerr;
+        if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1))
+            goto err;
+        if (*ptree == NULL)
+            *ptree = sk_GENERAL_SUBTREE_new_null();
+        if (*ptree == NULL || !sk_GENERAL_SUBTREE_push(*ptree, sub))
+            goto memerr;
+        sub = NULL;
+    }
+
+    return ncons;
+
+ memerr:
+    X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
+ err:
+    NAME_CONSTRAINTS_free(ncons);
+    GENERAL_SUBTREE_free(sub);
+
+    return NULL;
+}
+
+static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a,
+                                BIO *bp, int ind)
+{
+    NAME_CONSTRAINTS *ncons = a;
+    do_i2r_name_constraints(method, ncons->permittedSubtrees,
+                            bp, ind, "Permitted");
+    do_i2r_name_constraints(method, ncons->excludedSubtrees,
+                            bp, ind, "Excluded");
+    return 1;
+}
+
+static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method,
+                                   STACK_OF(GENERAL_SUBTREE) *trees,
+                                   BIO *bp, int ind, const char *name)
+{
+    GENERAL_SUBTREE *tree;
+    int i;
+    if (sk_GENERAL_SUBTREE_num(trees) > 0)
+        BIO_printf(bp, "%*s%s:\n", ind, "", name);
+    for (i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) {
+        tree = sk_GENERAL_SUBTREE_value(trees, i);
+        BIO_printf(bp, "%*s", ind + 2, "");
+        if (tree->base->type == GEN_IPADD)
+            print_nc_ipadd(bp, tree->base->d.ip);
+        else
+            GENERAL_NAME_print(bp, tree->base);
+        BIO_puts(bp, "\n");
+    }
+    return 1;
+}
+
+static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip)
+{
+    int i, len;
+    unsigned char *p;
+    p = ip->data;
+    len = ip->length;
+    BIO_puts(bp, "IP:");
+    if (len == 8) {
+        BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d",
+                   p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+    } else if (len == 32) {
+        for (i = 0; i < 16; i++) {
+            BIO_printf(bp, "%X", p[0] << 8 | p[1]);
+            p += 2;
+            if (i == 7)
+                BIO_puts(bp, "/");
+            else if (i != 15)
+                BIO_puts(bp, ":");
+        }
+    } else
+        BIO_printf(bp, "IP Address:<invalid>");
+    return 1;
+}
+
+/*-
+ * Check a certificate conforms to a specified set of constraints.
+ * Return values:
+ *  X509_V_OK: All constraints obeyed.
+ *  X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation.
+ *  X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation.
+ *  X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type.
+ *  X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:  Unsupported constraint type.
+ *  X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax.
+ *  X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name
+ */
+
+int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc)
+{
+    int r, i;
+    X509_NAME *nm;
+
+    nm = X509_get_subject_name(x);
+
+    if (X509_NAME_entry_count(nm) > 0) {
+        GENERAL_NAME gntmp;
+        gntmp.type = GEN_DIRNAME;
+        gntmp.d.directoryName = nm;
+
+        r = nc_match(&gntmp, nc);
+
+        if (r != X509_V_OK)
+            return r;
+
+        gntmp.type = GEN_EMAIL;
+
+        /* Process any email address attributes in subject name */
+
+        for (i = -1;;) {
+            const X509_NAME_ENTRY *ne;
+
+            i = X509_NAME_get_index_by_NID(nm, NID_pkcs9_emailAddress, i);
+            if (i == -1)
+                break;
+            ne = X509_NAME_get_entry(nm, i);
+            gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne);
+            if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING)
+                return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+
+            r = nc_match(&gntmp, nc);
+
+            if (r != X509_V_OK)
+                return r;
+        }
+
+    }
+
+    for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++) {
+        GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i);
+        r = nc_match(gen, nc);
+        if (r != X509_V_OK)
+            return r;
+    }
+
+    return X509_V_OK;
+
+}
+
+int NAME_CONSTRAINTS_check_CN(X509 *x, NAME_CONSTRAINTS *nc)
+{
+    int r, i;
+    X509_NAME *nm;
+
+    ASN1_STRING stmp;
+    GENERAL_NAME gntmp;
+    stmp.flags = 0;
+    stmp.type = V_ASN1_IA5STRING;
+    gntmp.type = GEN_DNS;
+    gntmp.d.dNSName = &stmp;
+
+    nm = X509_get_subject_name(x);
+
+    /* Process any commonName attributes in subject name */
+
+    for (i = -1;;) {
+        X509_NAME_ENTRY *ne;
+        ASN1_STRING *hn;
+        i = X509_NAME_get_index_by_NID(nm, NID_commonName, i);
+        if (i == -1)
+            break;
+        ne = X509_NAME_get_entry(nm, i);
+        hn = X509_NAME_ENTRY_get_data(ne);
+        /* Only process attributes that look like host names */
+        if (asn1_valid_host(hn)) {
+            unsigned char *h;
+            int hlen = ASN1_STRING_to_UTF8(&h, hn);
+            if (hlen <= 0)
+                return X509_V_ERR_OUT_OF_MEM;
+
+            stmp.length = hlen;
+            stmp.data = h;
+
+            r = nc_match(&gntmp, nc);
+
+            OPENSSL_free(h);
+
+            if (r != X509_V_OK)
+                    return r;
+        }
+    }
+    return X509_V_OK;
+}
+
+static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc)
+{
+    GENERAL_SUBTREE *sub;
+    int i, r, match = 0;
+
+    /*
+     * Permitted subtrees: if any subtrees exist of matching the type at
+     * least one subtree must match.
+     */
+
+    for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) {
+        sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i);
+        if (gen->type != sub->base->type)
+            continue;
+        if (sub->minimum || sub->maximum)
+            return X509_V_ERR_SUBTREE_MINMAX;
+        /* If we already have a match don't bother trying any more */
+        if (match == 2)
+            continue;
+        if (match == 0)
+            match = 1;
+        r = nc_match_single(gen, sub->base);
+        if (r == X509_V_OK)
+            match = 2;
+        else if (r != X509_V_ERR_PERMITTED_VIOLATION)
+            return r;
+    }
+
+    if (match == 1)
+        return X509_V_ERR_PERMITTED_VIOLATION;
+
+    /* Excluded subtrees: must not match any of these */
+
+    for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) {
+        sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i);
+        if (gen->type != sub->base->type)
+            continue;
+        if (sub->minimum || sub->maximum)
+            return X509_V_ERR_SUBTREE_MINMAX;
+
+        r = nc_match_single(gen, sub->base);
+        if (r == X509_V_OK)
+            return X509_V_ERR_EXCLUDED_VIOLATION;
+        else if (r != X509_V_ERR_PERMITTED_VIOLATION)
+            return r;
+
+    }
+
+    return X509_V_OK;
+
+}
+
+static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base)
+{
+    switch (base->type) {
+    case GEN_DIRNAME:
+        return nc_dn(gen->d.directoryName, base->d.directoryName);
+
+    case GEN_DNS:
+        return nc_dns(gen->d.dNSName, base->d.dNSName);
+
+    case GEN_EMAIL:
+        return nc_email(gen->d.rfc822Name, base->d.rfc822Name);
+
+    case GEN_URI:
+        return nc_uri(gen->d.uniformResourceIdentifier,
+                      base->d.uniformResourceIdentifier);
+
+    case GEN_IPADD:
+        return nc_ip(gen->d.iPAddress, base->d.iPAddress);
+
+    default:
+        return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE;
+    }
+
+}
+
+/*
+ * directoryName name constraint matching. The canonical encoding of
+ * X509_NAME makes this comparison easy. It is matched if the subtree is a
+ * subset of the name.
+ */
+
+static int nc_dn(X509_NAME *nm, X509_NAME *base)
+{
+    /* Ensure canonical encodings are up to date.  */
+    if (nm->modified && i2d_X509_NAME(nm, NULL) < 0)
+        return X509_V_ERR_OUT_OF_MEM;
+    if (base->modified && i2d_X509_NAME(base, NULL) < 0)
+        return X509_V_ERR_OUT_OF_MEM;
+    if (base->canon_enclen > nm->canon_enclen)
+        return X509_V_ERR_PERMITTED_VIOLATION;
+    if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen))
+        return X509_V_ERR_PERMITTED_VIOLATION;
+    return X509_V_OK;
+}
+
+static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base)
+{
+    char *baseptr = (char *)base->data;
+    char *dnsptr = (char *)dns->data;
+    /* Empty matches everything */
+    if (!*baseptr)
+        return X509_V_OK;
+    /*
+     * Otherwise can add zero or more components on the left so compare RHS
+     * and if dns is longer and expect '.' as preceding character.
+     */
+    if (dns->length > base->length) {
+        dnsptr += dns->length - base->length;
+        if (*baseptr != '.' && dnsptr[-1] != '.')
+            return X509_V_ERR_PERMITTED_VIOLATION;
+    }
+
+    if (strcasecmp(baseptr, dnsptr))
+        return X509_V_ERR_PERMITTED_VIOLATION;
+
+    return X509_V_OK;
+
+}
+
+static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base)
+{
+    const char *baseptr = (char *)base->data;
+    const char *emlptr = (char *)eml->data;
+
+    const char *baseat = strchr(baseptr, '@');
+    const char *emlat = strchr(emlptr, '@');
+    if (!emlat)
+        return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+    /* Special case: initial '.' is RHS match */
+    if (!baseat && (*baseptr == '.')) {
+        if (eml->length > base->length) {
+            emlptr += eml->length - base->length;
+            if (strcasecmp(baseptr, emlptr) == 0)
+                return X509_V_OK;
+        }
+        return X509_V_ERR_PERMITTED_VIOLATION;
+    }
+
+    /* If we have anything before '@' match local part */
+
+    if (baseat) {
+        if (baseat != baseptr) {
+            if ((baseat - baseptr) != (emlat - emlptr))
+                return X509_V_ERR_PERMITTED_VIOLATION;
+            /* Case sensitive match of local part */
+            if (strncmp(baseptr, emlptr, emlat - emlptr))
+                return X509_V_ERR_PERMITTED_VIOLATION;
+        }
+        /* Position base after '@' */
+        baseptr = baseat + 1;
+    }
+    emlptr = emlat + 1;
+    /* Just have hostname left to match: case insensitive */
+    if (strcasecmp(baseptr, emlptr))
+        return X509_V_ERR_PERMITTED_VIOLATION;
+
+    return X509_V_OK;
+
+}
+
+static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base)
+{
+    const char *baseptr = (char *)base->data;
+    const char *hostptr = (char *)uri->data;
+    const char *p = strchr(hostptr, ':');
+    int hostlen;
+    /* Check for foo:// and skip past it */
+    if (!p || (p[1] != '/') || (p[2] != '/'))
+        return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+    hostptr = p + 3;
+
+    /* Determine length of hostname part of URI */
+
+    /* Look for a port indicator as end of hostname first */
+
+    p = strchr(hostptr, ':');
+    /* Otherwise look for trailing slash */
+    if (!p)
+        p = strchr(hostptr, '/');
+
+    if (!p)
+        hostlen = strlen(hostptr);
+    else
+        hostlen = p - hostptr;
+
+    if (hostlen == 0)
+        return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+
+    /* Special case: initial '.' is RHS match */
+    if (*baseptr == '.') {
+        if (hostlen > base->length) {
+            p = hostptr + hostlen - base->length;
+            if (strncasecmp(p, baseptr, base->length) == 0)
+                return X509_V_OK;
+        }
+        return X509_V_ERR_PERMITTED_VIOLATION;
+    }
+
+    if ((base->length != (int)hostlen)
+        || strncasecmp(hostptr, baseptr, hostlen))
+        return X509_V_ERR_PERMITTED_VIOLATION;
+
+    return X509_V_OK;
+
+}
+
+static int nc_ip(ASN1_OCTET_STRING *ip, ASN1_OCTET_STRING *base)
+{
+    int hostlen, baselen, i;
+    unsigned char *hostptr, *baseptr, *maskptr;
+    hostptr = ip->data;
+    hostlen = ip->length;
+    baseptr = base->data;
+    baselen = base->length;
+
+    /* Invalid if not IPv4 or IPv6 */
+    if (!((hostlen == 4) || (hostlen == 16)))
+        return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+    if (!((baselen == 8) || (baselen == 32)))
+        return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
+
+    /* Do not match IPv4 with IPv6 */
+    if (hostlen * 2 != baselen)
+        return X509_V_ERR_PERMITTED_VIOLATION;
+
+    maskptr = base->data + hostlen;
+
+    /* Considering possible not aligned base ipAddress */
+    /* Not checking for wrong mask definition: i.e.: 255.0.255.0 */
+    for (i = 0; i < hostlen; i++)
+        if ((hostptr[i] & maskptr[i]) != (baseptr[i] & maskptr[i]))
+            return X509_V_ERR_PERMITTED_VIOLATION;
+
+    return X509_V_OK;
+
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_pci.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_pci.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_pci.c	(revision 331)
@@ -0,0 +1,321 @@
+/*
+ * Copyright 2004-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
+ */
+
+/* Copyright (c) 2004 Kungliga Tekniska H旦gskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+#include "ext_dat.h"
+
+static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext,
+                   BIO *out, int indent);
+static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
+                                          X509V3_CTX *ctx, char *str);
+
+const X509V3_EXT_METHOD v3_pci =
+    { NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION),
+    0, 0, 0, 0,
+    0, 0,
+    NULL, NULL,
+    (X509V3_EXT_I2R)i2r_pci,
+    (X509V3_EXT_R2I)r2i_pci,
+    NULL,
+};
+
+static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci,
+                   BIO *out, int indent)
+{
+    BIO_printf(out, "%*sPath Length Constraint: ", indent, "");
+    if (pci->pcPathLengthConstraint)
+        i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint);
+    else
+        BIO_printf(out, "infinite");
+    BIO_puts(out, "\n");
+    BIO_printf(out, "%*sPolicy Language: ", indent, "");
+    i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage);
+    BIO_puts(out, "\n");
+    if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data)
+        BIO_printf(out, "%*sPolicy Text: %s\n", indent, "",
+                   pci->proxyPolicy->policy->data);
+    return 1;
+}
+
+static int process_pci_value(CONF_VALUE *val,
+                             ASN1_OBJECT **language, ASN1_INTEGER **pathlen,
+                             ASN1_OCTET_STRING **policy)
+{
+    int free_policy = 0;
+
+    if (strcmp(val->name, "language") == 0) {
+        if (*language) {
+            X509V3err(X509V3_F_PROCESS_PCI_VALUE,
+                      X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED);
+            X509V3_conf_err(val);
+            return 0;
+        }
+        if ((*language = OBJ_txt2obj(val->value, 0)) == NULL) {
+            X509V3err(X509V3_F_PROCESS_PCI_VALUE,
+                      X509V3_R_INVALID_OBJECT_IDENTIFIER);
+            X509V3_conf_err(val);
+            return 0;
+        }
+    } else if (strcmp(val->name, "pathlen") == 0) {
+        if (*pathlen) {
+            X509V3err(X509V3_F_PROCESS_PCI_VALUE,
+                      X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED);
+            X509V3_conf_err(val);
+            return 0;
+        }
+        if (!X509V3_get_value_int(val, pathlen)) {
+            X509V3err(X509V3_F_PROCESS_PCI_VALUE,
+                      X509V3_R_POLICY_PATH_LENGTH);
+            X509V3_conf_err(val);
+            return 0;
+        }
+    } else if (strcmp(val->name, "policy") == 0) {
+        unsigned char *tmp_data = NULL;
+        long val_len;
+        if (!*policy) {
+            *policy = ASN1_OCTET_STRING_new();
+            if (*policy == NULL) {
+                X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE);
+                X509V3_conf_err(val);
+                return 0;
+            }
+            free_policy = 1;
+        }
+        if (strncmp(val->value, "hex:", 4) == 0) {
+            unsigned char *tmp_data2 =
+                OPENSSL_hexstr2buf(val->value + 4, &val_len);
+
+            if (!tmp_data2) {
+                X509V3_conf_err(val);
+                goto err;
+            }
+
+            tmp_data = OPENSSL_realloc((*policy)->data,
+                                       (*policy)->length + val_len + 1);
+            if (tmp_data) {
+                (*policy)->data = tmp_data;
+                memcpy(&(*policy)->data[(*policy)->length],
+                       tmp_data2, val_len);
+                (*policy)->length += val_len;
+                (*policy)->data[(*policy)->length] = '\0';
+            } else {
+                OPENSSL_free(tmp_data2);
+                /*
+                 * realloc failure implies the original data space is b0rked
+                 * too!
+                 */
+                OPENSSL_free((*policy)->data);
+                (*policy)->data = NULL;
+                (*policy)->length = 0;
+                X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE);
+                X509V3_conf_err(val);
+                goto err;
+            }
+            OPENSSL_free(tmp_data2);
+        } else if (strncmp(val->value, "file:", 5) == 0) {
+            unsigned char buf[2048];
+            int n;
+            BIO *b = BIO_new_file(val->value + 5, "r");
+            if (!b) {
+                X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_BIO_LIB);
+                X509V3_conf_err(val);
+                goto err;
+            }
+            while ((n = BIO_read(b, buf, sizeof(buf))) > 0
+                   || (n == 0 && BIO_should_retry(b))) {
+                if (!n)
+                    continue;
+
+                tmp_data = OPENSSL_realloc((*policy)->data,
+                                           (*policy)->length + n + 1);
+
+                if (!tmp_data) {
+                    OPENSSL_free((*policy)->data);
+                    (*policy)->data = NULL;
+                    (*policy)->length = 0;
+                    X509V3err(X509V3_F_PROCESS_PCI_VALUE,
+                              ERR_R_MALLOC_FAILURE);
+                    X509V3_conf_err(val);
+                    BIO_free_all(b);
+                    goto err;
+                }
+
+                (*policy)->data = tmp_data;
+                memcpy(&(*policy)->data[(*policy)->length], buf, n);
+                (*policy)->length += n;
+                (*policy)->data[(*policy)->length] = '\0';
+            }
+            BIO_free_all(b);
+
+            if (n < 0) {
+                X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_BIO_LIB);
+                X509V3_conf_err(val);
+                goto err;
+            }
+        } else if (strncmp(val->value, "text:", 5) == 0) {
+            val_len = strlen(val->value + 5);
+            tmp_data = OPENSSL_realloc((*policy)->data,
+                                       (*policy)->length + val_len + 1);
+            if (tmp_data) {
+                (*policy)->data = tmp_data;
+                memcpy(&(*policy)->data[(*policy)->length],
+                       val->value + 5, val_len);
+                (*policy)->length += val_len;
+                (*policy)->data[(*policy)->length] = '\0';
+            } else {
+                /*
+                 * realloc failure implies the original data space is b0rked
+                 * too!
+                 */
+                OPENSSL_free((*policy)->data);
+                (*policy)->data = NULL;
+                (*policy)->length = 0;
+                X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE);
+                X509V3_conf_err(val);
+                goto err;
+            }
+        } else {
+            X509V3err(X509V3_F_PROCESS_PCI_VALUE,
+                      X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
+            X509V3_conf_err(val);
+            goto err;
+        }
+        if (!tmp_data) {
+            X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE);
+            X509V3_conf_err(val);
+            goto err;
+        }
+    }
+    return 1;
+ err:
+    if (free_policy) {
+        ASN1_OCTET_STRING_free(*policy);
+        *policy = NULL;
+    }
+    return 0;
+}
+
+static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
+                                          X509V3_CTX *ctx, char *value)
+{
+    PROXY_CERT_INFO_EXTENSION *pci = NULL;
+    STACK_OF(CONF_VALUE) *vals;
+    ASN1_OBJECT *language = NULL;
+    ASN1_INTEGER *pathlen = NULL;
+    ASN1_OCTET_STRING *policy = NULL;
+    int i, j;
+
+    vals = X509V3_parse_list(value);
+    for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
+        CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i);
+        if (!cnf->name || (*cnf->name != '@' && !cnf->value)) {
+            X509V3err(X509V3_F_R2I_PCI,
+                      X509V3_R_INVALID_PROXY_POLICY_SETTING);
+            X509V3_conf_err(cnf);
+            goto err;
+        }
+        if (*cnf->name == '@') {
+            STACK_OF(CONF_VALUE) *sect;
+            int success_p = 1;
+
+            sect = X509V3_get_section(ctx, cnf->name + 1);
+            if (!sect) {
+                X509V3err(X509V3_F_R2I_PCI, X509V3_R_INVALID_SECTION);
+                X509V3_conf_err(cnf);
+                goto err;
+            }
+            for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++) {
+                success_p =
+                    process_pci_value(sk_CONF_VALUE_value(sect, j),
+                                      &language, &pathlen, &policy);
+            }
+            X509V3_section_free(ctx, sect);
+            if (!success_p)
+                goto err;
+        } else {
+            if (!process_pci_value(cnf, &language, &pathlen, &policy)) {
+                X509V3_conf_err(cnf);
+                goto err;
+            }
+        }
+    }
+
+    /* Language is mandatory */
+    if (!language) {
+        X509V3err(X509V3_F_R2I_PCI,
+                  X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED);
+        goto err;
+    }
+    i = OBJ_obj2nid(language);
+    if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy) {
+        X509V3err(X509V3_F_R2I_PCI,
+                  X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
+        goto err;
+    }
+
+    pci = PROXY_CERT_INFO_EXTENSION_new();
+    if (pci == NULL) {
+        X509V3err(X509V3_F_R2I_PCI, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    pci->proxyPolicy->policyLanguage = language;
+    language = NULL;
+    pci->proxyPolicy->policy = policy;
+    policy = NULL;
+    pci->pcPathLengthConstraint = pathlen;
+    pathlen = NULL;
+    goto end;
+ err:
+    ASN1_OBJECT_free(language);
+    ASN1_INTEGER_free(pathlen);
+    pathlen = NULL;
+    ASN1_OCTET_STRING_free(policy);
+    policy = NULL;
+    PROXY_CERT_INFO_EXTENSION_free(pci);
+    pci = NULL;
+ end:
+    sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
+    return pci;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_pcia.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_pcia.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_pcia.c	(revision 331)
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2004-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
+ */
+
+/* Copyright (c) 2004 Kungliga Tekniska H旦gskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+
+ASN1_SEQUENCE(PROXY_POLICY) =
+        {
+        ASN1_SIMPLE(PROXY_POLICY,policyLanguage,ASN1_OBJECT),
+        ASN1_OPT(PROXY_POLICY,policy,ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(PROXY_POLICY)
+
+IMPLEMENT_ASN1_FUNCTIONS(PROXY_POLICY)
+
+ASN1_SEQUENCE(PROXY_CERT_INFO_EXTENSION) =
+        {
+        ASN1_OPT(PROXY_CERT_INFO_EXTENSION,pcPathLengthConstraint,ASN1_INTEGER),
+        ASN1_SIMPLE(PROXY_CERT_INFO_EXTENSION,proxyPolicy,PROXY_POLICY)
+} ASN1_SEQUENCE_END(PROXY_CERT_INFO_EXTENSION)
+
+IMPLEMENT_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_pcons.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_pcons.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_pcons.c	(revision 331)
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2003-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+#include "ext_dat.h"
+
+static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD
+                                                    *method, void *bcons, STACK_OF(CONF_VALUE)
+                                                    *extlist);
+static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
+                                    X509V3_CTX *ctx,
+                                    STACK_OF(CONF_VALUE) *values);
+
+const X509V3_EXT_METHOD v3_policy_constraints = {
+    NID_policy_constraints, 0,
+    ASN1_ITEM_ref(POLICY_CONSTRAINTS),
+    0, 0, 0, 0,
+    0, 0,
+    i2v_POLICY_CONSTRAINTS,
+    v2i_POLICY_CONSTRAINTS,
+    NULL, NULL,
+    NULL
+};
+
+ASN1_SEQUENCE(POLICY_CONSTRAINTS) = {
+        ASN1_IMP_OPT(POLICY_CONSTRAINTS, requireExplicitPolicy, ASN1_INTEGER,0),
+        ASN1_IMP_OPT(POLICY_CONSTRAINTS, inhibitPolicyMapping, ASN1_INTEGER,1)
+} ASN1_SEQUENCE_END(POLICY_CONSTRAINTS)
+
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
+
+static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD
+                                                    *method, void *a, STACK_OF(CONF_VALUE)
+                                                    *extlist)
+{
+    POLICY_CONSTRAINTS *pcons = a;
+    X509V3_add_value_int("Require Explicit Policy",
+                         pcons->requireExplicitPolicy, &extlist);
+    X509V3_add_value_int("Inhibit Policy Mapping",
+                         pcons->inhibitPolicyMapping, &extlist);
+    return extlist;
+}
+
+static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
+                                    X509V3_CTX *ctx,
+                                    STACK_OF(CONF_VALUE) *values)
+{
+    POLICY_CONSTRAINTS *pcons = NULL;
+    CONF_VALUE *val;
+    int i;
+
+    if ((pcons = POLICY_CONSTRAINTS_new()) == NULL) {
+        X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(values); i++) {
+        val = sk_CONF_VALUE_value(values, i);
+        if (strcmp(val->name, "requireExplicitPolicy") == 0) {
+            if (!X509V3_get_value_int(val, &pcons->requireExplicitPolicy))
+                goto err;
+        } else if (strcmp(val->name, "inhibitPolicyMapping") == 0) {
+            if (!X509V3_get_value_int(val, &pcons->inhibitPolicyMapping))
+                goto err;
+        } else {
+            X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, X509V3_R_INVALID_NAME);
+            X509V3_conf_err(val);
+            goto err;
+        }
+    }
+    if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) {
+        X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS,
+                  X509V3_R_ILLEGAL_EMPTY_EXTENSION);
+        goto err;
+    }
+
+    return pcons;
+ err:
+    POLICY_CONSTRAINTS_free(pcons);
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_pku.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_pku.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_pku.c	(revision 331)
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+#include "ext_dat.h"
+
+static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method,
+                                 PKEY_USAGE_PERIOD *usage, BIO *out,
+                                 int indent);
+/*
+ * static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method,
+ * X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values);
+ */
+const X509V3_EXT_METHOD v3_pkey_usage_period = {
+    NID_private_key_usage_period, 0, ASN1_ITEM_ref(PKEY_USAGE_PERIOD),
+    0, 0, 0, 0,
+    0, 0, 0, 0,
+    (X509V3_EXT_I2R)i2r_PKEY_USAGE_PERIOD, NULL,
+    NULL
+};
+
+ASN1_SEQUENCE(PKEY_USAGE_PERIOD) = {
+        ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notBefore, ASN1_GENERALIZEDTIME, 0),
+        ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notAfter, ASN1_GENERALIZEDTIME, 1)
+} ASN1_SEQUENCE_END(PKEY_USAGE_PERIOD)
+
+IMPLEMENT_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD)
+
+static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method,
+                                 PKEY_USAGE_PERIOD *usage, BIO *out,
+                                 int indent)
+{
+    BIO_printf(out, "%*s", indent, "");
+    if (usage->notBefore) {
+        BIO_write(out, "Not Before: ", 12);
+        ASN1_GENERALIZEDTIME_print(out, usage->notBefore);
+        if (usage->notAfter)
+            BIO_write(out, ", ", 2);
+    }
+    if (usage->notAfter) {
+        BIO_write(out, "Not After: ", 11);
+        ASN1_GENERALIZEDTIME_print(out, usage->notAfter);
+    }
+    return 1;
+}
+
+/*-
+static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(method, ctx, values)
+X509V3_EXT_METHOD *method;
+X509V3_CTX *ctx;
+STACK_OF(CONF_VALUE) *values;
+{
+return NULL;
+}
+*/
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_pmaps.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_pmaps.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_pmaps.c	(revision 331)
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2003-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+#include "ext_dat.h"
+
+static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
+                                 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD
+                                                 *method, void *pmps, STACK_OF(CONF_VALUE)
+                                                 *extlist);
+
+const X509V3_EXT_METHOD v3_policy_mappings = {
+    NID_policy_mappings, 0,
+    ASN1_ITEM_ref(POLICY_MAPPINGS),
+    0, 0, 0, 0,
+    0, 0,
+    i2v_POLICY_MAPPINGS,
+    v2i_POLICY_MAPPINGS,
+    0, 0,
+    NULL
+};
+
+ASN1_SEQUENCE(POLICY_MAPPING) = {
+        ASN1_SIMPLE(POLICY_MAPPING, issuerDomainPolicy, ASN1_OBJECT),
+        ASN1_SIMPLE(POLICY_MAPPING, subjectDomainPolicy, ASN1_OBJECT)
+} ASN1_SEQUENCE_END(POLICY_MAPPING)
+
+ASN1_ITEM_TEMPLATE(POLICY_MAPPINGS) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, POLICY_MAPPINGS,
+                                                                POLICY_MAPPING)
+ASN1_ITEM_TEMPLATE_END(POLICY_MAPPINGS)
+
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING)
+
+static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD
+                                                 *method, void *a, STACK_OF(CONF_VALUE)
+                                                 *ext_list)
+{
+    POLICY_MAPPINGS *pmaps = a;
+    POLICY_MAPPING *pmap;
+    int i;
+    char obj_tmp1[80];
+    char obj_tmp2[80];
+    for (i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) {
+        pmap = sk_POLICY_MAPPING_value(pmaps, i);
+        i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy);
+        i2t_ASN1_OBJECT(obj_tmp2, 80, pmap->subjectDomainPolicy);
+        X509V3_add_value(obj_tmp1, obj_tmp2, &ext_list);
+    }
+    return ext_list;
+}
+
+static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
+                                 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+{
+    POLICY_MAPPINGS *pmaps = NULL;
+    POLICY_MAPPING *pmap = NULL;
+    ASN1_OBJECT *obj1 = NULL, *obj2 = NULL;
+    CONF_VALUE *val;
+    int i;
+
+    if ((pmaps = sk_POLICY_MAPPING_new_null()) == NULL) {
+        X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        val = sk_CONF_VALUE_value(nval, i);
+        if (!val->value || !val->name) {
+            X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,
+                      X509V3_R_INVALID_OBJECT_IDENTIFIER);
+            X509V3_conf_err(val);
+            goto err;
+        }
+        obj1 = OBJ_txt2obj(val->name, 0);
+        obj2 = OBJ_txt2obj(val->value, 0);
+        if (!obj1 || !obj2) {
+            X509V3err(X509V3_F_V2I_POLICY_MAPPINGS,
+                      X509V3_R_INVALID_OBJECT_IDENTIFIER);
+            X509V3_conf_err(val);
+            goto err;
+        }
+        pmap = POLICY_MAPPING_new();
+        if (pmap == NULL) {
+            X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        pmap->issuerDomainPolicy = obj1;
+        pmap->subjectDomainPolicy = obj2;
+        obj1 = obj2 = NULL;
+        sk_POLICY_MAPPING_push(pmaps, pmap);
+    }
+    return pmaps;
+ err:
+    ASN1_OBJECT_free(obj1);
+    ASN1_OBJECT_free(obj2);
+    sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_prn.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_prn.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_prn.c	(revision 331)
@@ -0,0 +1,210 @@
+/*
+ * Copyright 1999-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
+ */
+
+/* X509 v3 extension utilities */
+
+#include <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+/* Extension printing routines */
+
+static int unknown_ext_print(BIO *out, const unsigned char *ext, int extlen,
+                             unsigned long flag, int indent, int supported);
+
+/* Print out a name+value stack */
+
+void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
+                        int ml)
+{
+    int i;
+    CONF_VALUE *nval;
+    if (!val)
+        return;
+    if (!ml || !sk_CONF_VALUE_num(val)) {
+        BIO_printf(out, "%*s", indent, "");
+        if (!sk_CONF_VALUE_num(val))
+            BIO_puts(out, "<EMPTY>\n");
+    }
+    for (i = 0; i < sk_CONF_VALUE_num(val); i++) {
+        if (ml)
+            BIO_printf(out, "%*s", indent, "");
+        else if (i > 0)
+            BIO_printf(out, ", ");
+        nval = sk_CONF_VALUE_value(val, i);
+        if (!nval->name)
+            BIO_puts(out, nval->value);
+        else if (!nval->value)
+            BIO_puts(out, nval->name);
+#ifndef CHARSET_EBCDIC
+        else
+            BIO_printf(out, "%s:%s", nval->name, nval->value);
+#else
+        else {
+            int len;
+            char *tmp;
+            len = strlen(nval->value) + 1;
+            tmp = OPENSSL_malloc(len);
+            if (tmp != NULL) {
+                ascii2ebcdic(tmp, nval->value, len);
+                BIO_printf(out, "%s:%s", nval->name, tmp);
+                OPENSSL_free(tmp);
+            }
+        }
+#endif
+        if (ml)
+            BIO_puts(out, "\n");
+    }
+}
+
+/* Main routine: print out a general extension */
+
+int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag,
+                     int indent)
+{
+    void *ext_str = NULL;
+    char *value = NULL;
+    ASN1_OCTET_STRING *extoct;
+    const unsigned char *p;
+    int extlen;
+    const X509V3_EXT_METHOD *method;
+    STACK_OF(CONF_VALUE) *nval = NULL;
+    int ok = 1;
+
+    extoct = X509_EXTENSION_get_data(ext);
+    p = ASN1_STRING_get0_data(extoct);
+    extlen = ASN1_STRING_length(extoct);
+
+    if ((method = X509V3_EXT_get(ext)) == NULL)
+        return unknown_ext_print(out, p, extlen, flag, indent, 0);
+    if (method->it)
+        ext_str = ASN1_item_d2i(NULL, &p, extlen, ASN1_ITEM_ptr(method->it));
+    else
+        ext_str = method->d2i(NULL, &p, extlen);
+
+    if (!ext_str)
+        return unknown_ext_print(out, p, extlen, flag, indent, 1);
+
+    if (method->i2s) {
+        if ((value = method->i2s(method, ext_str)) == NULL) {
+            ok = 0;
+            goto err;
+        }
+#ifndef CHARSET_EBCDIC
+        BIO_printf(out, "%*s%s", indent, "", value);
+#else
+        {
+            int len;
+            char *tmp;
+            len = strlen(value) + 1;
+            tmp = OPENSSL_malloc(len);
+            if (tmp != NULL) {
+                ascii2ebcdic(tmp, value, len);
+                BIO_printf(out, "%*s%s", indent, "", tmp);
+                OPENSSL_free(tmp);
+            }
+        }
+#endif
+    } else if (method->i2v) {
+        if ((nval = method->i2v(method, ext_str, NULL)) == NULL) {
+            ok = 0;
+            goto err;
+        }
+        X509V3_EXT_val_prn(out, nval, indent,
+                           method->ext_flags & X509V3_EXT_MULTILINE);
+    } else if (method->i2r) {
+        if (!method->i2r(method, ext_str, out, indent))
+            ok = 0;
+    } else
+        ok = 0;
+
+ err:
+    sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
+    OPENSSL_free(value);
+    if (method->it)
+        ASN1_item_free(ext_str, ASN1_ITEM_ptr(method->it));
+    else
+        method->ext_free(ext_str);
+    return ok;
+}
+
+int X509V3_extensions_print(BIO *bp, const char *title,
+                            const STACK_OF(X509_EXTENSION) *exts,
+                            unsigned long flag, int indent)
+{
+    int i, j;
+
+    if (sk_X509_EXTENSION_num(exts) <= 0)
+        return 1;
+
+    if (title) {
+        BIO_printf(bp, "%*s%s:\n", indent, "", title);
+        indent += 4;
+    }
+
+    for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
+        ASN1_OBJECT *obj;
+        X509_EXTENSION *ex;
+        ex = sk_X509_EXTENSION_value(exts, i);
+        if (indent && BIO_printf(bp, "%*s", indent, "") <= 0)
+            return 0;
+        obj = X509_EXTENSION_get_object(ex);
+        i2a_ASN1_OBJECT(bp, obj);
+        j = X509_EXTENSION_get_critical(ex);
+        if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0)
+            return 0;
+        if (!X509V3_EXT_print(bp, ex, flag, indent + 4)) {
+            BIO_printf(bp, "%*s", indent + 4, "");
+            ASN1_STRING_print(bp, X509_EXTENSION_get_data(ex));
+        }
+        if (BIO_write(bp, "\n", 1) <= 0)
+            return 0;
+    }
+    return 1;
+}
+
+static int unknown_ext_print(BIO *out, const unsigned char *ext, int extlen,
+                             unsigned long flag, int indent, int supported)
+{
+    switch (flag & X509V3_EXT_UNKNOWN_MASK) {
+
+    case X509V3_EXT_DEFAULT:
+        return 0;
+
+    case X509V3_EXT_ERROR_UNKNOWN:
+        if (supported)
+            BIO_printf(out, "%*s<Parse Error>", indent, "");
+        else
+            BIO_printf(out, "%*s<Not Supported>", indent, "");
+        return 1;
+
+    case X509V3_EXT_PARSE_UNKNOWN:
+        return ASN1_parse_dump(out, ext, extlen, indent, -1);
+    case X509V3_EXT_DUMP_UNKNOWN:
+        return BIO_dump_indent(out, (const char *)ext, extlen, indent);
+
+    default:
+        return 1;
+    }
+}
+
+#ifndef OPENSSL_NO_STDIO
+int X509V3_EXT_print_fp(FILE *fp, X509_EXTENSION *ext, int flag, int indent)
+{
+    BIO *bio_tmp;
+    int ret;
+
+    if ((bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL)
+        return 0;
+    ret = X509V3_EXT_print(bio_tmp, ext, flag, indent);
+    BIO_free(bio_tmp);
+    return ret;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_purp.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_purp.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_purp.c	(revision 331)
@@ -0,0 +1,865 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include "internal/numbers.h"
+#include <openssl/x509v3.h>
+#include <openssl/x509_vfy.h>
+#include "internal/x509_int.h"
+
+static void x509v3_cache_extensions(X509 *x);
+
+static int check_ssl_ca(const X509 *x);
+static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x,
+                                    int ca);
+static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x,
+                                    int ca);
+static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x,
+                                       int ca);
+static int purpose_smime(const X509 *x, int ca);
+static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x,
+                                    int ca);
+static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x,
+                                       int ca);
+static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x,
+                                  int ca);
+static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
+                                        int ca);
+static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca);
+static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca);
+
+static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b);
+static void xptable_free(X509_PURPOSE *p);
+
+static X509_PURPOSE xstandard[] = {
+    {X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0,
+     check_purpose_ssl_client, "SSL client", "sslclient", NULL},
+    {X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0,
+     check_purpose_ssl_server, "SSL server", "sslserver", NULL},
+    {X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0,
+     check_purpose_ns_ssl_server, "Netscape SSL server", "nssslserver", NULL},
+    {X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign,
+     "S/MIME signing", "smimesign", NULL},
+    {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0,
+     check_purpose_smime_encrypt, "S/MIME encryption", "smimeencrypt", NULL},
+    {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign,
+     "CRL signing", "crlsign", NULL},
+    {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, "Any Purpose", "any",
+     NULL},
+    {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper,
+     "OCSP helper", "ocsphelper", NULL},
+    {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0,
+     check_purpose_timestamp_sign, "Time Stamp signing", "timestampsign",
+     NULL},
+};
+
+#define X509_PURPOSE_COUNT OSSL_NELEM(xstandard)
+
+static STACK_OF(X509_PURPOSE) *xptable = NULL;
+
+static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b)
+{
+    return (*a)->purpose - (*b)->purpose;
+}
+
+/*
+ * As much as I'd like to make X509_check_purpose use a "const" X509* I
+ * really can't because it does recalculate hashes and do other non-const
+ * things.
+ */
+int X509_check_purpose(X509 *x, int id, int ca)
+{
+    int idx;
+    const X509_PURPOSE *pt;
+    if (!(x->ex_flags & EXFLAG_SET)) {
+        CRYPTO_THREAD_write_lock(x->lock);
+        x509v3_cache_extensions(x);
+        CRYPTO_THREAD_unlock(x->lock);
+    }
+    /* Return if side-effect only call */
+    if (id == -1)
+        return 1;
+    idx = X509_PURPOSE_get_by_id(id);
+    if (idx == -1)
+        return -1;
+    pt = X509_PURPOSE_get0(idx);
+    return pt->check_purpose(pt, x, ca);
+}
+
+int X509_PURPOSE_set(int *p, int purpose)
+{
+    if (X509_PURPOSE_get_by_id(purpose) == -1) {
+        X509V3err(X509V3_F_X509_PURPOSE_SET, X509V3_R_INVALID_PURPOSE);
+        return 0;
+    }
+    *p = purpose;
+    return 1;
+}
+
+int X509_PURPOSE_get_count(void)
+{
+    if (!xptable)
+        return X509_PURPOSE_COUNT;
+    return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT;
+}
+
+X509_PURPOSE *X509_PURPOSE_get0(int idx)
+{
+    if (idx < 0)
+        return NULL;
+    if (idx < (int)X509_PURPOSE_COUNT)
+        return xstandard + idx;
+    return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT);
+}
+
+int X509_PURPOSE_get_by_sname(const char *sname)
+{
+    int i;
+    X509_PURPOSE *xptmp;
+    for (i = 0; i < X509_PURPOSE_get_count(); i++) {
+        xptmp = X509_PURPOSE_get0(i);
+        if (strcmp(xptmp->sname, sname) == 0)
+            return i;
+    }
+    return -1;
+}
+
+int X509_PURPOSE_get_by_id(int purpose)
+{
+    X509_PURPOSE tmp;
+    int idx;
+    if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX))
+        return purpose - X509_PURPOSE_MIN;
+    tmp.purpose = purpose;
+    if (!xptable)
+        return -1;
+    idx = sk_X509_PURPOSE_find(xptable, &tmp);
+    if (idx == -1)
+        return -1;
+    return idx + X509_PURPOSE_COUNT;
+}
+
+int X509_PURPOSE_add(int id, int trust, int flags,
+                     int (*ck) (const X509_PURPOSE *, const X509 *, int),
+                     const char *name, const char *sname, void *arg)
+{
+    int idx;
+    X509_PURPOSE *ptmp;
+    /*
+     * This is set according to what we change: application can't set it
+     */
+    flags &= ~X509_PURPOSE_DYNAMIC;
+    /* This will always be set for application modified trust entries */
+    flags |= X509_PURPOSE_DYNAMIC_NAME;
+    /* Get existing entry if any */
+    idx = X509_PURPOSE_get_by_id(id);
+    /* Need a new entry */
+    if (idx == -1) {
+        if ((ptmp = OPENSSL_malloc(sizeof(*ptmp))) == NULL) {
+            X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        ptmp->flags = X509_PURPOSE_DYNAMIC;
+    } else
+        ptmp = X509_PURPOSE_get0(idx);
+
+    /* OPENSSL_free existing name if dynamic */
+    if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) {
+        OPENSSL_free(ptmp->name);
+        OPENSSL_free(ptmp->sname);
+    }
+    /* dup supplied name */
+    ptmp->name = OPENSSL_strdup(name);
+    ptmp->sname = OPENSSL_strdup(sname);
+    if (!ptmp->name || !ptmp->sname) {
+        X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    /* Keep the dynamic flag of existing entry */
+    ptmp->flags &= X509_PURPOSE_DYNAMIC;
+    /* Set all other flags */
+    ptmp->flags |= flags;
+
+    ptmp->purpose = id;
+    ptmp->trust = trust;
+    ptmp->check_purpose = ck;
+    ptmp->usr_data = arg;
+
+    /* If its a new entry manage the dynamic table */
+    if (idx == -1) {
+        if (xptable == NULL
+            && (xptable = sk_X509_PURPOSE_new(xp_cmp)) == NULL) {
+            X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        if (!sk_X509_PURPOSE_push(xptable, ptmp)) {
+            X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    }
+    return 1;
+ err:
+    if (idx == -1) {
+        OPENSSL_free(ptmp->name);
+        OPENSSL_free(ptmp->sname);
+        OPENSSL_free(ptmp);
+    }
+    return 0;
+}
+
+static void xptable_free(X509_PURPOSE *p)
+{
+    if (!p)
+        return;
+    if (p->flags & X509_PURPOSE_DYNAMIC) {
+        if (p->flags & X509_PURPOSE_DYNAMIC_NAME) {
+            OPENSSL_free(p->name);
+            OPENSSL_free(p->sname);
+        }
+        OPENSSL_free(p);
+    }
+}
+
+void X509_PURPOSE_cleanup(void)
+{
+    sk_X509_PURPOSE_pop_free(xptable, xptable_free);
+    xptable = NULL;
+}
+
+int X509_PURPOSE_get_id(const X509_PURPOSE *xp)
+{
+    return xp->purpose;
+}
+
+char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp)
+{
+    return xp->name;
+}
+
+char *X509_PURPOSE_get0_sname(const X509_PURPOSE *xp)
+{
+    return xp->sname;
+}
+
+int X509_PURPOSE_get_trust(const X509_PURPOSE *xp)
+{
+    return xp->trust;
+}
+
+static int nid_cmp(const int *a, const int *b)
+{
+    return *a - *b;
+}
+
+DECLARE_OBJ_BSEARCH_CMP_FN(int, int, nid);
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(int, int, nid);
+
+int X509_supported_extension(X509_EXTENSION *ex)
+{
+    /*
+     * This table is a list of the NIDs of supported extensions: that is
+     * those which are used by the verify process. If an extension is
+     * critical and doesn't appear in this list then the verify process will
+     * normally reject the certificate. The list must be kept in numerical
+     * order because it will be searched using bsearch.
+     */
+
+    static const int supported_nids[] = {
+        NID_netscape_cert_type, /* 71 */
+        NID_key_usage,          /* 83 */
+        NID_subject_alt_name,   /* 85 */
+        NID_basic_constraints,  /* 87 */
+        NID_certificate_policies, /* 89 */
+        NID_ext_key_usage,      /* 126 */
+#ifndef OPENSSL_NO_RFC3779
+        NID_sbgp_ipAddrBlock,   /* 290 */
+        NID_sbgp_autonomousSysNum, /* 291 */
+#endif
+        NID_policy_constraints, /* 401 */
+        NID_proxyCertInfo,      /* 663 */
+        NID_name_constraints,   /* 666 */
+        NID_policy_mappings,    /* 747 */
+        NID_inhibit_any_policy  /* 748 */
+    };
+
+    int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex));
+
+    if (ex_nid == NID_undef)
+        return 0;
+
+    if (OBJ_bsearch_nid(&ex_nid, supported_nids, OSSL_NELEM(supported_nids)))
+        return 1;
+    return 0;
+}
+
+static void setup_dp(X509 *x, DIST_POINT *dp)
+{
+    X509_NAME *iname = NULL;
+    int i;
+    if (dp->reasons) {
+        if (dp->reasons->length > 0)
+            dp->dp_reasons = dp->reasons->data[0];
+        if (dp->reasons->length > 1)
+            dp->dp_reasons |= (dp->reasons->data[1] << 8);
+        dp->dp_reasons &= CRLDP_ALL_REASONS;
+    } else
+        dp->dp_reasons = CRLDP_ALL_REASONS;
+    if (!dp->distpoint || (dp->distpoint->type != 1))
+        return;
+    for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
+        GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
+        if (gen->type == GEN_DIRNAME) {
+            iname = gen->d.directoryName;
+            break;
+        }
+    }
+    if (!iname)
+        iname = X509_get_issuer_name(x);
+
+    DIST_POINT_set_dpname(dp->distpoint, iname);
+
+}
+
+static void setup_crldp(X509 *x)
+{
+    int i;
+    x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
+    for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++)
+        setup_dp(x, sk_DIST_POINT_value(x->crldp, i));
+}
+
+#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
+#define ku_reject(x, usage) \
+        (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
+#define xku_reject(x, usage) \
+        (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
+#define ns_reject(x, usage) \
+        (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
+
+static void x509v3_cache_extensions(X509 *x)
+{
+    BASIC_CONSTRAINTS *bs;
+    PROXY_CERT_INFO_EXTENSION *pci;
+    ASN1_BIT_STRING *usage;
+    ASN1_BIT_STRING *ns;
+    EXTENDED_KEY_USAGE *extusage;
+    X509_EXTENSION *ex;
+
+    int i;
+    if (x->ex_flags & EXFLAG_SET)
+        return;
+    X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
+    /* V1 should mean no extensions ... */
+    if (!X509_get_version(x))
+        x->ex_flags |= EXFLAG_V1;
+    /* Handle basic constraints */
+    if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) {
+        if (bs->ca)
+            x->ex_flags |= EXFLAG_CA;
+        if (bs->pathlen) {
+            if ((bs->pathlen->type == V_ASN1_NEG_INTEGER)
+                || !bs->ca) {
+                x->ex_flags |= EXFLAG_INVALID;
+                x->ex_pathlen = 0;
+            } else
+                x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
+        } else
+            x->ex_pathlen = -1;
+        BASIC_CONSTRAINTS_free(bs);
+        x->ex_flags |= EXFLAG_BCONS;
+    }
+    /* Handle proxy certificates */
+    if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
+        if (x->ex_flags & EXFLAG_CA
+            || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0
+            || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) {
+            x->ex_flags |= EXFLAG_INVALID;
+        }
+        if (pci->pcPathLengthConstraint) {
+            x->ex_pcpathlen = ASN1_INTEGER_get(pci->pcPathLengthConstraint);
+        } else
+            x->ex_pcpathlen = -1;
+        PROXY_CERT_INFO_EXTENSION_free(pci);
+        x->ex_flags |= EXFLAG_PROXY;
+    }
+    /* Handle key usage */
+    if ((usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {
+        if (usage->length > 0) {
+            x->ex_kusage = usage->data[0];
+            if (usage->length > 1)
+                x->ex_kusage |= usage->data[1] << 8;
+        } else
+            x->ex_kusage = 0;
+        x->ex_flags |= EXFLAG_KUSAGE;
+        ASN1_BIT_STRING_free(usage);
+    }
+    x->ex_xkusage = 0;
+    if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) {
+        x->ex_flags |= EXFLAG_XKUSAGE;
+        for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
+            switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) {
+            case NID_server_auth:
+                x->ex_xkusage |= XKU_SSL_SERVER;
+                break;
+
+            case NID_client_auth:
+                x->ex_xkusage |= XKU_SSL_CLIENT;
+                break;
+
+            case NID_email_protect:
+                x->ex_xkusage |= XKU_SMIME;
+                break;
+
+            case NID_code_sign:
+                x->ex_xkusage |= XKU_CODE_SIGN;
+                break;
+
+            case NID_ms_sgc:
+            case NID_ns_sgc:
+                x->ex_xkusage |= XKU_SGC;
+                break;
+
+            case NID_OCSP_sign:
+                x->ex_xkusage |= XKU_OCSP_SIGN;
+                break;
+
+            case NID_time_stamp:
+                x->ex_xkusage |= XKU_TIMESTAMP;
+                break;
+
+            case NID_dvcs:
+                x->ex_xkusage |= XKU_DVCS;
+                break;
+
+            case NID_anyExtendedKeyUsage:
+                x->ex_xkusage |= XKU_ANYEKU;
+                break;
+            }
+        }
+        sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
+    }
+
+    if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) {
+        if (ns->length > 0)
+            x->ex_nscert = ns->data[0];
+        else
+            x->ex_nscert = 0;
+        x->ex_flags |= EXFLAG_NSCERT;
+        ASN1_BIT_STRING_free(ns);
+    }
+    x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
+    x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
+    /* Does subject name match issuer ? */
+    if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) {
+        x->ex_flags |= EXFLAG_SI;
+        /* If SKID matches AKID also indicate self signed */
+        if (X509_check_akid(x, x->akid) == X509_V_OK &&
+            !ku_reject(x, KU_KEY_CERT_SIGN))
+            x->ex_flags |= EXFLAG_SS;
+    }
+    x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
+    x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL);
+    if (!x->nc && (i != -1))
+        x->ex_flags |= EXFLAG_INVALID;
+    setup_crldp(x);
+
+#ifndef OPENSSL_NO_RFC3779
+    x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL);
+    x->rfc3779_asid = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum,
+                                       NULL, NULL);
+#endif
+    for (i = 0; i < X509_get_ext_count(x); i++) {
+        ex = X509_get_ext(x, i);
+        if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
+            == NID_freshest_crl)
+            x->ex_flags |= EXFLAG_FRESHEST;
+        if (!X509_EXTENSION_get_critical(ex))
+            continue;
+        if (!X509_supported_extension(ex)) {
+            x->ex_flags |= EXFLAG_CRITICAL;
+            break;
+        }
+    }
+    x->ex_flags |= EXFLAG_SET;
+}
+
+/*-
+ * CA checks common to all purposes
+ * return codes:
+ * 0 not a CA
+ * 1 is a CA
+ * 2 basicConstraints absent so "maybe" a CA
+ * 3 basicConstraints absent but self signed V1.
+ * 4 basicConstraints absent but keyUsage present and keyCertSign asserted.
+ */
+
+static int check_ca(const X509 *x)
+{
+    /* keyUsage if present should allow cert signing */
+    if (ku_reject(x, KU_KEY_CERT_SIGN))
+        return 0;
+    if (x->ex_flags & EXFLAG_BCONS) {
+        if (x->ex_flags & EXFLAG_CA)
+            return 1;
+        /* If basicConstraints says not a CA then say so */
+        else
+            return 0;
+    } else {
+        /* we support V1 roots for...  uh, I don't really know why. */
+        if ((x->ex_flags & V1_ROOT) == V1_ROOT)
+            return 3;
+        /*
+         * If key usage present it must have certSign so tolerate it
+         */
+        else if (x->ex_flags & EXFLAG_KUSAGE)
+            return 4;
+        /* Older certificates could have Netscape-specific CA types */
+        else if (x->ex_flags & EXFLAG_NSCERT && x->ex_nscert & NS_ANY_CA)
+            return 5;
+        /* can this still be regarded a CA certificate?  I doubt it */
+        return 0;
+    }
+}
+
+void X509_set_proxy_flag(X509 *x)
+{
+    x->ex_flags |= EXFLAG_PROXY;
+}
+
+void X509_set_proxy_pathlen(X509 *x, long l)
+{
+    x->ex_pcpathlen = l;
+}
+
+int X509_check_ca(X509 *x)
+{
+    if (!(x->ex_flags & EXFLAG_SET)) {
+        CRYPTO_THREAD_write_lock(x->lock);
+        x509v3_cache_extensions(x);
+        CRYPTO_THREAD_unlock(x->lock);
+    }
+
+    return check_ca(x);
+}
+
+/* Check SSL CA: common checks for SSL client and server */
+static int check_ssl_ca(const X509 *x)
+{
+    int ca_ret;
+    ca_ret = check_ca(x);
+    if (!ca_ret)
+        return 0;
+    /* check nsCertType if present */
+    if (ca_ret != 5 || x->ex_nscert & NS_SSL_CA)
+        return ca_ret;
+    else
+        return 0;
+}
+
+static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x,
+                                    int ca)
+{
+    if (xku_reject(x, XKU_SSL_CLIENT))
+        return 0;
+    if (ca)
+        return check_ssl_ca(x);
+    /* We need to do digital signatures or key agreement */
+    if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT))
+        return 0;
+    /* nsCertType if present should allow SSL client use */
+    if (ns_reject(x, NS_SSL_CLIENT))
+        return 0;
+    return 1;
+}
+
+/*
+ * Key usage needed for TLS/SSL server: digital signature, encipherment or
+ * key agreement. The ssl code can check this more thoroughly for individual
+ * key types.
+ */
+#define KU_TLS \
+        KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT|KU_KEY_AGREEMENT
+
+static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x,
+                                    int ca)
+{
+    if (xku_reject(x, XKU_SSL_SERVER | XKU_SGC))
+        return 0;
+    if (ca)
+        return check_ssl_ca(x);
+
+    if (ns_reject(x, NS_SSL_SERVER))
+        return 0;
+    if (ku_reject(x, KU_TLS))
+        return 0;
+
+    return 1;
+
+}
+
+static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x,
+                                       int ca)
+{
+    int ret;
+    ret = check_purpose_ssl_server(xp, x, ca);
+    if (!ret || ca)
+        return ret;
+    /* We need to encipher or Netscape complains */
+    if (ku_reject(x, KU_KEY_ENCIPHERMENT))
+        return 0;
+    return ret;
+}
+
+/* common S/MIME checks */
+static int purpose_smime(const X509 *x, int ca)
+{
+    if (xku_reject(x, XKU_SMIME))
+        return 0;
+    if (ca) {
+        int ca_ret;
+        ca_ret = check_ca(x);
+        if (!ca_ret)
+            return 0;
+        /* check nsCertType if present */
+        if (ca_ret != 5 || x->ex_nscert & NS_SMIME_CA)
+            return ca_ret;
+        else
+            return 0;
+    }
+    if (x->ex_flags & EXFLAG_NSCERT) {
+        if (x->ex_nscert & NS_SMIME)
+            return 1;
+        /* Workaround for some buggy certificates */
+        if (x->ex_nscert & NS_SSL_CLIENT)
+            return 2;
+        return 0;
+    }
+    return 1;
+}
+
+static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x,
+                                    int ca)
+{
+    int ret;
+    ret = purpose_smime(x, ca);
+    if (!ret || ca)
+        return ret;
+    if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION))
+        return 0;
+    return ret;
+}
+
+static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x,
+                                       int ca)
+{
+    int ret;
+    ret = purpose_smime(x, ca);
+    if (!ret || ca)
+        return ret;
+    if (ku_reject(x, KU_KEY_ENCIPHERMENT))
+        return 0;
+    return ret;
+}
+
+static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x,
+                                  int ca)
+{
+    if (ca) {
+        int ca_ret;
+        if ((ca_ret = check_ca(x)) != 2)
+            return ca_ret;
+        else
+            return 0;
+    }
+    if (ku_reject(x, KU_CRL_SIGN))
+        return 0;
+    return 1;
+}
+
+/*
+ * OCSP helper: this is *not* a full OCSP check. It just checks that each CA
+ * is valid. Additional checks must be made on the chain.
+ */
+
+static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca)
+{
+    /*
+     * Must be a valid CA.  Should we really support the "I don't know" value
+     * (2)?
+     */
+    if (ca)
+        return check_ca(x);
+    /* leaf certificate is checked in OCSP_verify() */
+    return 1;
+}
+
+static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
+                                        int ca)
+{
+    int i_ext;
+
+    /* If ca is true we must return if this is a valid CA certificate. */
+    if (ca)
+        return check_ca(x);
+
+    /*
+     * Check the optional key usage field:
+     * if Key Usage is present, it must be one of digitalSignature
+     * and/or nonRepudiation (other values are not consistent and shall
+     * be rejected).
+     */
+    if ((x->ex_flags & EXFLAG_KUSAGE)
+        && ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) ||
+            !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE))))
+        return 0;
+
+    /* Only time stamp key usage is permitted and it's required. */
+    if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP)
+        return 0;
+
+    /* Extended Key Usage MUST be critical */
+    i_ext = X509_get_ext_by_NID(x, NID_ext_key_usage, -1);
+    if (i_ext >= 0) {
+        X509_EXTENSION *ext = X509_get_ext((X509 *)x, i_ext);
+        if (!X509_EXTENSION_get_critical(ext))
+            return 0;
+    }
+
+    return 1;
+}
+
+static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca)
+{
+    return 1;
+}
+
+/*-
+ * Various checks to see if one certificate issued the second.
+ * This can be used to prune a set of possible issuer certificates
+ * which have been looked up using some simple method such as by
+ * subject name.
+ * These are:
+ * 1. Check issuer_name(subject) == subject_name(issuer)
+ * 2. If akid(subject) exists check it matches issuer
+ * 3. If key_usage(issuer) exists check it supports certificate signing
+ * returns 0 for OK, positive for reason for mismatch, reasons match
+ * codes for X509_verify_cert()
+ */
+
+int X509_check_issued(X509 *issuer, X509 *subject)
+{
+    if (X509_NAME_cmp(X509_get_subject_name(issuer),
+                      X509_get_issuer_name(subject)))
+        return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
+    x509v3_cache_extensions(issuer);
+    x509v3_cache_extensions(subject);
+
+    if (subject->akid) {
+        int ret = X509_check_akid(issuer, subject->akid);
+        if (ret != X509_V_OK)
+            return ret;
+    }
+
+    if (subject->ex_flags & EXFLAG_PROXY) {
+        if (ku_reject(issuer, KU_DIGITAL_SIGNATURE))
+            return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE;
+    } else if (ku_reject(issuer, KU_KEY_CERT_SIGN))
+        return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
+    return X509_V_OK;
+}
+
+int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid)
+{
+
+    if (!akid)
+        return X509_V_OK;
+
+    /* Check key ids (if present) */
+    if (akid->keyid && issuer->skid &&
+        ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid))
+        return X509_V_ERR_AKID_SKID_MISMATCH;
+    /* Check serial number */
+    if (akid->serial &&
+        ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial))
+        return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
+    /* Check issuer name */
+    if (akid->issuer) {
+        /*
+         * Ugh, for some peculiar reason AKID includes SEQUENCE OF
+         * GeneralName. So look for a DirName. There may be more than one but
+         * we only take any notice of the first.
+         */
+        GENERAL_NAMES *gens;
+        GENERAL_NAME *gen;
+        X509_NAME *nm = NULL;
+        int i;
+        gens = akid->issuer;
+        for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+            gen = sk_GENERAL_NAME_value(gens, i);
+            if (gen->type == GEN_DIRNAME) {
+                nm = gen->d.dirn;
+                break;
+            }
+        }
+        if (nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)))
+            return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
+    }
+    return X509_V_OK;
+}
+
+uint32_t X509_get_extension_flags(X509 *x)
+{
+    /* Call for side-effect of computing hash and caching extensions */
+    X509_check_purpose(x, -1, -1);
+    return x->ex_flags;
+}
+
+uint32_t X509_get_key_usage(X509 *x)
+{
+    /* Call for side-effect of computing hash and caching extensions */
+    X509_check_purpose(x, -1, -1);
+    if (x->ex_flags & EXFLAG_KUSAGE)
+        return x->ex_kusage;
+    return UINT32_MAX;
+}
+
+uint32_t X509_get_extended_key_usage(X509 *x)
+{
+    /* Call for side-effect of computing hash and caching extensions */
+    X509_check_purpose(x, -1, -1);
+    if (x->ex_flags & EXFLAG_XKUSAGE)
+        return x->ex_xkusage;
+    return UINT32_MAX;
+}
+
+const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x)
+{
+    /* Call for side-effect of computing hash and caching extensions */
+    X509_check_purpose(x, -1, -1);
+    return x->skid;
+}
+
+long X509_get_pathlen(X509 *x)
+{
+    /* Called for side effect of caching extensions */
+    if (X509_check_purpose(x, -1, -1) != 1
+            || (x->ex_flags & EXFLAG_BCONS) == 0)
+        return -1;
+    return x->ex_pathlen;
+}
+
+long X509_get_proxy_pathlen(X509 *x)
+{
+    /* Called for side effect of caching extensions */
+    if (X509_check_purpose(x, -1, -1) != 1
+            || (x->ex_flags & EXFLAG_PROXY) == 0)
+        return -1;
+    return x->ex_pcpathlen;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_skey.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_skey.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_skey.c	(revision 331)
@@ -0,0 +1,106 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/x509v3.h>
+#include "internal/x509_int.h"
+#include "ext_dat.h"
+
+static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
+                                      X509V3_CTX *ctx, char *str);
+const X509V3_EXT_METHOD v3_skey_id = {
+    NID_subject_key_identifier, 0, ASN1_ITEM_ref(ASN1_OCTET_STRING),
+    0, 0, 0, 0,
+    (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING,
+    (X509V3_EXT_S2I)s2i_skey_id,
+    0, 0, 0, 0,
+    NULL
+};
+
+char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, 
+                            const ASN1_OCTET_STRING *oct)
+{
+    return OPENSSL_buf2hexstr(oct->data, oct->length);
+}
+
+ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
+                                         X509V3_CTX *ctx, const char *str)
+{
+    ASN1_OCTET_STRING *oct;
+    long length;
+
+    if ((oct = ASN1_OCTET_STRING_new()) == NULL) {
+        X509V3err(X509V3_F_S2I_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    if ((oct->data = OPENSSL_hexstr2buf(str, &length)) == NULL) {
+        ASN1_OCTET_STRING_free(oct);
+        return NULL;
+    }
+
+    oct->length = length;
+
+    return oct;
+
+}
+
+static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
+                                      X509V3_CTX *ctx, char *str)
+{
+    ASN1_OCTET_STRING *oct;
+    X509_PUBKEY *pubkey;
+    const unsigned char *pk;
+    int pklen;
+    unsigned char pkey_dig[EVP_MAX_MD_SIZE];
+    unsigned int diglen;
+
+    if (strcmp(str, "hash"))
+        return s2i_ASN1_OCTET_STRING(method, ctx, str);
+
+    if ((oct = ASN1_OCTET_STRING_new()) == NULL) {
+        X509V3err(X509V3_F_S2I_SKEY_ID, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    if (ctx && (ctx->flags == CTX_TEST))
+        return oct;
+
+    if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) {
+        X509V3err(X509V3_F_S2I_SKEY_ID, X509V3_R_NO_PUBLIC_KEY);
+        goto err;
+    }
+
+    if (ctx->subject_req)
+        pubkey = ctx->subject_req->req_info.pubkey;
+    else
+        pubkey = ctx->subject_cert->cert_info.key;
+
+    if (pubkey == NULL) {
+        X509V3err(X509V3_F_S2I_SKEY_ID, X509V3_R_NO_PUBLIC_KEY);
+        goto err;
+    }
+
+    X509_PUBKEY_get0_param(NULL, &pk, &pklen, NULL, pubkey);
+
+    if (!EVP_Digest(pk, pklen, pkey_dig, &diglen, EVP_sha1(), NULL))
+        goto err;
+
+    if (!ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) {
+        X509V3err(X509V3_F_S2I_SKEY_ID, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    return oct;
+
+ err:
+    ASN1_OCTET_STRING_free(oct);
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_sxnet.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_sxnet.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_sxnet.c	(revision 331)
@@ -0,0 +1,226 @@
+/*
+ * Copyright 1999-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+#include "ext_dat.h"
+
+/* Support for Thawte strong extranet extension */
+
+#define SXNET_TEST
+
+static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out,
+                     int indent);
+#ifdef SXNET_TEST
+static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+                        STACK_OF(CONF_VALUE) *nval);
+#endif
+const X509V3_EXT_METHOD v3_sxnet = {
+    NID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET),
+    0, 0, 0, 0,
+    0, 0,
+    0,
+#ifdef SXNET_TEST
+    (X509V3_EXT_V2I)sxnet_v2i,
+#else
+    0,
+#endif
+    (X509V3_EXT_I2R)sxnet_i2r,
+    0,
+    NULL
+};
+
+ASN1_SEQUENCE(SXNETID) = {
+        ASN1_SIMPLE(SXNETID, zone, ASN1_INTEGER),
+        ASN1_SIMPLE(SXNETID, user, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(SXNETID)
+
+IMPLEMENT_ASN1_FUNCTIONS(SXNETID)
+
+ASN1_SEQUENCE(SXNET) = {
+        ASN1_SIMPLE(SXNET, version, ASN1_INTEGER),
+        ASN1_SEQUENCE_OF(SXNET, ids, SXNETID)
+} ASN1_SEQUENCE_END(SXNET)
+
+IMPLEMENT_ASN1_FUNCTIONS(SXNET)
+
+static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out,
+                     int indent)
+{
+    long v;
+    char *tmp;
+    SXNETID *id;
+    int i;
+    v = ASN1_INTEGER_get(sx->version);
+    BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", v + 1, v);
+    for (i = 0; i < sk_SXNETID_num(sx->ids); i++) {
+        id = sk_SXNETID_value(sx->ids, i);
+        tmp = i2s_ASN1_INTEGER(NULL, id->zone);
+        BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp);
+        OPENSSL_free(tmp);
+        ASN1_STRING_print(out, id->user);
+    }
+    return 1;
+}
+
+#ifdef SXNET_TEST
+
+/*
+ * NBB: this is used for testing only. It should *not* be used for anything
+ * else because it will just take static IDs from the configuration file and
+ * they should really be separate values for each user.
+ */
+
+static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+                        STACK_OF(CONF_VALUE) *nval)
+{
+    CONF_VALUE *cnf;
+    SXNET *sx = NULL;
+    int i;
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        cnf = sk_CONF_VALUE_value(nval, i);
+        if (!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1))
+            return NULL;
+    }
+    return sx;
+}
+
+#endif
+
+/* Strong Extranet utility functions */
+
+/* Add an id given the zone as an ASCII number */
+
+int SXNET_add_id_asc(SXNET **psx, const char *zone, const char *user, int userlen)
+{
+    ASN1_INTEGER *izone;
+
+    if ((izone = s2i_ASN1_INTEGER(NULL, zone)) == NULL) {
+        X509V3err(X509V3_F_SXNET_ADD_ID_ASC, X509V3_R_ERROR_CONVERTING_ZONE);
+        return 0;
+    }
+    return SXNET_add_id_INTEGER(psx, izone, user, userlen);
+}
+
+/* Add an id given the zone as an unsigned long */
+
+int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, const char *user,
+                       int userlen)
+{
+    ASN1_INTEGER *izone;
+
+    if ((izone = ASN1_INTEGER_new()) == NULL
+        || !ASN1_INTEGER_set(izone, lzone)) {
+        X509V3err(X509V3_F_SXNET_ADD_ID_ULONG, ERR_R_MALLOC_FAILURE);
+        ASN1_INTEGER_free(izone);
+        return 0;
+    }
+    return SXNET_add_id_INTEGER(psx, izone, user, userlen);
+
+}
+
+/*
+ * Add an id given the zone as an ASN1_INTEGER. Note this version uses the
+ * passed integer and doesn't make a copy so don't free it up afterwards.
+ */
+
+int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, const char *user,
+                         int userlen)
+{
+    SXNET *sx = NULL;
+    SXNETID *id = NULL;
+    if (!psx || !zone || !user) {
+        X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER,
+                  X509V3_R_INVALID_NULL_ARGUMENT);
+        return 0;
+    }
+    if (userlen == -1)
+        userlen = strlen(user);
+    if (userlen > 64) {
+        X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, X509V3_R_USER_TOO_LONG);
+        return 0;
+    }
+    if (*psx == NULL) {
+        if ((sx = SXNET_new()) == NULL)
+            goto err;
+        if (!ASN1_INTEGER_set(sx->version, 0))
+            goto err;
+        *psx = sx;
+    } else
+        sx = *psx;
+    if (SXNET_get_id_INTEGER(sx, zone)) {
+        X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, X509V3_R_DUPLICATE_ZONE_ID);
+        return 0;
+    }
+
+    if ((id = SXNETID_new()) == NULL)
+        goto err;
+    if (userlen == -1)
+        userlen = strlen(user);
+
+    if (!ASN1_OCTET_STRING_set(id->user, (const unsigned char *)user, userlen))
+        goto err;
+    if (!sk_SXNETID_push(sx->ids, id))
+        goto err;
+    id->zone = zone;
+    return 1;
+
+ err:
+    X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, ERR_R_MALLOC_FAILURE);
+    SXNETID_free(id);
+    SXNET_free(sx);
+    *psx = NULL;
+    return 0;
+}
+
+ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, const char *zone)
+{
+    ASN1_INTEGER *izone;
+    ASN1_OCTET_STRING *oct;
+
+    if ((izone = s2i_ASN1_INTEGER(NULL, zone)) == NULL) {
+        X509V3err(X509V3_F_SXNET_GET_ID_ASC, X509V3_R_ERROR_CONVERTING_ZONE);
+        return NULL;
+    }
+    oct = SXNET_get_id_INTEGER(sx, izone);
+    ASN1_INTEGER_free(izone);
+    return oct;
+}
+
+ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone)
+{
+    ASN1_INTEGER *izone;
+    ASN1_OCTET_STRING *oct;
+
+    if ((izone = ASN1_INTEGER_new()) == NULL
+        || !ASN1_INTEGER_set(izone, lzone)) {
+        X509V3err(X509V3_F_SXNET_GET_ID_ULONG, ERR_R_MALLOC_FAILURE);
+        ASN1_INTEGER_free(izone);
+        return NULL;
+    }
+    oct = SXNET_get_id_INTEGER(sx, izone);
+    ASN1_INTEGER_free(izone);
+    return oct;
+}
+
+ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone)
+{
+    SXNETID *id;
+    int i;
+    for (i = 0; i < sk_SXNETID_num(sx->ids); i++) {
+        id = sk_SXNETID_value(sx->ids, i);
+        if (!ASN1_INTEGER_cmp(id->zone, zone))
+            return id->user;
+    }
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_tlsf.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_tlsf.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_tlsf.c	(revision 331)
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2015-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 <stdio.h>
+#include "internal/cryptlib.h"
+#include "internal/o_str.h"
+#include <openssl/asn1t.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+#include "ext_dat.h"
+
+static STACK_OF(CONF_VALUE) *i2v_TLS_FEATURE(const X509V3_EXT_METHOD *method,
+                                             TLS_FEATURE *tls_feature,
+                                             STACK_OF(CONF_VALUE) *ext_list);
+static TLS_FEATURE *v2i_TLS_FEATURE(const X509V3_EXT_METHOD *method,
+                                    X509V3_CTX *ctx,
+                                    STACK_OF(CONF_VALUE) *nval);
+
+ASN1_ITEM_TEMPLATE(TLS_FEATURE) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, TLS_FEATURE, ASN1_INTEGER)
+static_ASN1_ITEM_TEMPLATE_END(TLS_FEATURE)
+
+IMPLEMENT_ASN1_ALLOC_FUNCTIONS(TLS_FEATURE)
+
+const X509V3_EXT_METHOD v3_tls_feature = {
+    NID_tlsfeature, 0,
+    ASN1_ITEM_ref(TLS_FEATURE),
+    0, 0, 0, 0,
+    0, 0,
+    (X509V3_EXT_I2V)i2v_TLS_FEATURE,
+    (X509V3_EXT_V2I)v2i_TLS_FEATURE,
+    0, 0,
+    NULL
+};
+
+
+typedef struct {
+    long num;
+    const char *name;
+} TLS_FEATURE_NAME;
+
+static TLS_FEATURE_NAME tls_feature_tbl[] = {
+    { 5, "status_request" },
+    { 17, "status_request_v2" }
+};
+
+/*
+ * i2v_TLS_FEATURE converts the TLS_FEATURE structure tls_feature into the
+ * STACK_OF(CONF_VALUE) structure ext_list. STACK_OF(CONF_VALUE) is the format
+ * used by the CONF library to represent a multi-valued extension.  ext_list is
+ * returned.
+ */
+static STACK_OF(CONF_VALUE) *i2v_TLS_FEATURE(const X509V3_EXT_METHOD *method,
+                                             TLS_FEATURE *tls_feature,
+                                             STACK_OF(CONF_VALUE) *ext_list)
+{
+    int i;
+    size_t j;
+    ASN1_INTEGER *ai;
+    long tlsextid;
+    for (i = 0; i < sk_ASN1_INTEGER_num(tls_feature); i++) {
+        ai = sk_ASN1_INTEGER_value(tls_feature, i);
+        tlsextid = ASN1_INTEGER_get(ai);
+        for (j = 0; j < OSSL_NELEM(tls_feature_tbl); j++)
+            if (tlsextid == tls_feature_tbl[j].num)
+                break;
+        if (j < OSSL_NELEM(tls_feature_tbl))
+            X509V3_add_value(NULL, tls_feature_tbl[j].name, &ext_list);
+        else
+            X509V3_add_value_int(NULL, ai, &ext_list);
+    }
+    return ext_list;
+}
+
+/*
+ * v2i_TLS_FEATURE converts the multi-valued extension nval into a TLS_FEATURE
+ * structure, which is returned if the conversion is successful.  In case of
+ * error, NULL is returned.
+ */
+static TLS_FEATURE *v2i_TLS_FEATURE(const X509V3_EXT_METHOD *method,
+                                    X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval)
+{
+    TLS_FEATURE *tlsf;
+    char *extval, *endptr;
+    ASN1_INTEGER *ai;
+    CONF_VALUE *val;
+    int i;
+    size_t j;
+    long tlsextid;
+
+    if ((tlsf = sk_ASN1_INTEGER_new_null()) == NULL) {
+        X509V3err(X509V3_F_V2I_TLS_FEATURE, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
+        val = sk_CONF_VALUE_value(nval, i);
+        if (val->value)
+            extval = val->value;
+        else
+            extval = val->name;
+
+        for (j = 0; j < OSSL_NELEM(tls_feature_tbl); j++)
+            if (strcasecmp(extval, tls_feature_tbl[j].name) == 0)
+                break;
+        if (j < OSSL_NELEM(tls_feature_tbl))
+            tlsextid = tls_feature_tbl[j].num;
+        else {
+            tlsextid = strtol(extval, &endptr, 10);
+            if (((*endptr) != '\0') || (extval == endptr) || (tlsextid < 0) ||
+                (tlsextid > 65535)) {
+                X509V3err(X509V3_F_V2I_TLS_FEATURE, X509V3_R_INVALID_SYNTAX);
+                X509V3_conf_err(val);
+                goto err;
+            }
+        }
+
+        ai = ASN1_INTEGER_new();
+        if (ai == NULL) {
+            X509V3err(X509V3_F_V2I_TLS_FEATURE, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        ASN1_INTEGER_set(ai, tlsextid);
+        sk_ASN1_INTEGER_push(tlsf, ai);
+    }
+    return tlsf;
+
+ err:
+    sk_ASN1_INTEGER_pop_free(tlsf, ASN1_INTEGER_free);
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_utl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_utl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3_utl.c	(revision 331)
@@ -0,0 +1,1195 @@
+/*
+ * Copyright 1999-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
+ */
+
+/* X509 v3 extension utilities */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "internal/cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+#include "internal/x509_int.h"
+#include <openssl/bn.h>
+#include "ext_dat.h"
+
+static char *strip_spaces(char *name);
+static int sk_strcmp(const char *const *a, const char *const *b);
+static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name,
+                                           GENERAL_NAMES *gens);
+static void str_free(OPENSSL_STRING str);
+static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, const ASN1_IA5STRING *email);
+
+static int ipv4_from_asc(unsigned char *v4, const char *in);
+static int ipv6_from_asc(unsigned char *v6, const char *in);
+static int ipv6_cb(const char *elem, int len, void *usr);
+static int ipv6_hex(unsigned char *out, const char *in, int inlen);
+
+/* Add a CONF_VALUE name value pair to stack */
+
+int X509V3_add_value(const char *name, const char *value,
+                     STACK_OF(CONF_VALUE) **extlist)
+{
+    CONF_VALUE *vtmp = NULL;
+    char *tname = NULL, *tvalue = NULL;
+
+    if (name && (tname = OPENSSL_strdup(name)) == NULL)
+        goto err;
+    if (value && (tvalue = OPENSSL_strdup(value)) == NULL)
+        goto err;
+    if ((vtmp = OPENSSL_malloc(sizeof(*vtmp))) == NULL)
+        goto err;
+    if (*extlist == NULL && (*extlist = sk_CONF_VALUE_new_null()) == NULL)
+        goto err;
+    vtmp->section = NULL;
+    vtmp->name = tname;
+    vtmp->value = tvalue;
+    if (!sk_CONF_VALUE_push(*extlist, vtmp))
+        goto err;
+    return 1;
+ err:
+    X509V3err(X509V3_F_X509V3_ADD_VALUE, ERR_R_MALLOC_FAILURE);
+    OPENSSL_free(vtmp);
+    OPENSSL_free(tname);
+    OPENSSL_free(tvalue);
+    return 0;
+}
+
+int X509V3_add_value_uchar(const char *name, const unsigned char *value,
+                           STACK_OF(CONF_VALUE) **extlist)
+{
+    return X509V3_add_value(name, (const char *)value, extlist);
+}
+
+/* Free function for STACK_OF(CONF_VALUE) */
+
+void X509V3_conf_free(CONF_VALUE *conf)
+{
+    if (!conf)
+        return;
+    OPENSSL_free(conf->name);
+    OPENSSL_free(conf->value);
+    OPENSSL_free(conf->section);
+    OPENSSL_free(conf);
+}
+
+int X509V3_add_value_bool(const char *name, int asn1_bool,
+                          STACK_OF(CONF_VALUE) **extlist)
+{
+    if (asn1_bool)
+        return X509V3_add_value(name, "TRUE", extlist);
+    return X509V3_add_value(name, "FALSE", extlist);
+}
+
+int X509V3_add_value_bool_nf(const char *name, int asn1_bool,
+                             STACK_OF(CONF_VALUE) **extlist)
+{
+    if (asn1_bool)
+        return X509V3_add_value(name, "TRUE", extlist);
+    return 1;
+}
+
+char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, const ASN1_ENUMERATED *a)
+{
+    BIGNUM *bntmp = NULL;
+    char *strtmp = NULL;
+
+    if (!a)
+        return NULL;
+    if ((bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) == NULL
+        || (strtmp = BN_bn2dec(bntmp)) == NULL)
+        X509V3err(X509V3_F_I2S_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
+    BN_free(bntmp);
+    return strtmp;
+}
+
+char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, const ASN1_INTEGER *a)
+{
+    BIGNUM *bntmp = NULL;
+    char *strtmp = NULL;
+
+    if (!a)
+        return NULL;
+    if ((bntmp = ASN1_INTEGER_to_BN(a, NULL)) == NULL
+        || (strtmp = BN_bn2dec(bntmp)) == NULL)
+        X509V3err(X509V3_F_I2S_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
+    BN_free(bntmp);
+    return strtmp;
+}
+
+ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, const char *value)
+{
+    BIGNUM *bn = NULL;
+    ASN1_INTEGER *aint;
+    int isneg, ishex;
+    int ret;
+    if (value == NULL) {
+        X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_INVALID_NULL_VALUE);
+        return NULL;
+    }
+    bn = BN_new();
+    if (bn == NULL) {
+        X509V3err(X509V3_F_S2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    if (value[0] == '-') {
+        value++;
+        isneg = 1;
+    } else
+        isneg = 0;
+
+    if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) {
+        value += 2;
+        ishex = 1;
+    } else
+        ishex = 0;
+
+    if (ishex)
+        ret = BN_hex2bn(&bn, value);
+    else
+        ret = BN_dec2bn(&bn, value);
+
+    if (!ret || value[ret]) {
+        BN_free(bn);
+        X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_BN_DEC2BN_ERROR);
+        return NULL;
+    }
+
+    if (isneg && BN_is_zero(bn))
+        isneg = 0;
+
+    aint = BN_to_ASN1_INTEGER(bn, NULL);
+    BN_free(bn);
+    if (!aint) {
+        X509V3err(X509V3_F_S2I_ASN1_INTEGER,
+                  X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
+        return NULL;
+    }
+    if (isneg)
+        aint->type |= V_ASN1_NEG;
+    return aint;
+}
+
+int X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint,
+                         STACK_OF(CONF_VALUE) **extlist)
+{
+    char *strtmp;
+    int ret;
+
+    if (!aint)
+        return 1;
+    if ((strtmp = i2s_ASN1_INTEGER(NULL, aint)) == NULL)
+        return 0;
+    ret = X509V3_add_value(name, strtmp, extlist);
+    OPENSSL_free(strtmp);
+    return ret;
+}
+
+int X509V3_get_value_bool(const CONF_VALUE *value, int *asn1_bool)
+{
+    const char *btmp;
+
+    if ((btmp = value->value) == NULL)
+        goto err;
+    if (strcmp(btmp, "TRUE") == 0
+        || strcmp(btmp, "true") == 0
+        || strcmp(btmp, "Y") == 0
+        || strcmp(btmp, "y") == 0
+        || strcmp(btmp, "YES") == 0
+        || strcmp(btmp, "yes") == 0) {
+        *asn1_bool = 0xff;
+        return 1;
+    }
+    if (strcmp(btmp, "FALSE") == 0
+        || strcmp(btmp, "false") == 0
+        || strcmp(btmp, "N") == 0
+        || strcmp(btmp, "n") == 0
+        || strcmp(btmp, "NO") == 0
+        || strcmp(btmp, "no") == 0) {
+        *asn1_bool = 0;
+        return 1;
+    }
+ err:
+    X509V3err(X509V3_F_X509V3_GET_VALUE_BOOL,
+              X509V3_R_INVALID_BOOLEAN_STRING);
+    X509V3_conf_err(value);
+    return 0;
+}
+
+int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint)
+{
+    ASN1_INTEGER *itmp;
+
+    if ((itmp = s2i_ASN1_INTEGER(NULL, value->value)) == NULL) {
+        X509V3_conf_err(value);
+        return 0;
+    }
+    *aint = itmp;
+    return 1;
+}
+
+#define HDR_NAME        1
+#define HDR_VALUE       2
+
+/*
+ * #define DEBUG
+ */
+
+STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
+{
+    char *p, *q, c;
+    char *ntmp, *vtmp;
+    STACK_OF(CONF_VALUE) *values = NULL;
+    char *linebuf;
+    int state;
+    /* We are going to modify the line so copy it first */
+    linebuf = OPENSSL_strdup(line);
+    if (linebuf == NULL) {
+        X509V3err(X509V3_F_X509V3_PARSE_LIST, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    state = HDR_NAME;
+    ntmp = NULL;
+    /* Go through all characters */
+    for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n');
+         p++) {
+
+        switch (state) {
+        case HDR_NAME:
+            if (c == ':') {
+                state = HDR_VALUE;
+                *p = 0;
+                ntmp = strip_spaces(q);
+                if (!ntmp) {
+                    X509V3err(X509V3_F_X509V3_PARSE_LIST,
+                              X509V3_R_INVALID_NULL_NAME);
+                    goto err;
+                }
+                q = p + 1;
+            } else if (c == ',') {
+                *p = 0;
+                ntmp = strip_spaces(q);
+                q = p + 1;
+                if (!ntmp) {
+                    X509V3err(X509V3_F_X509V3_PARSE_LIST,
+                              X509V3_R_INVALID_NULL_NAME);
+                    goto err;
+                }
+                X509V3_add_value(ntmp, NULL, &values);
+            }
+            break;
+
+        case HDR_VALUE:
+            if (c == ',') {
+                state = HDR_NAME;
+                *p = 0;
+                vtmp = strip_spaces(q);
+                if (!vtmp) {
+                    X509V3err(X509V3_F_X509V3_PARSE_LIST,
+                              X509V3_R_INVALID_NULL_VALUE);
+                    goto err;
+                }
+                X509V3_add_value(ntmp, vtmp, &values);
+                ntmp = NULL;
+                q = p + 1;
+            }
+
+        }
+    }
+
+    if (state == HDR_VALUE) {
+        vtmp = strip_spaces(q);
+        if (!vtmp) {
+            X509V3err(X509V3_F_X509V3_PARSE_LIST,
+                      X509V3_R_INVALID_NULL_VALUE);
+            goto err;
+        }
+        X509V3_add_value(ntmp, vtmp, &values);
+    } else {
+        ntmp = strip_spaces(q);
+        if (!ntmp) {
+            X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME);
+            goto err;
+        }
+        X509V3_add_value(ntmp, NULL, &values);
+    }
+    OPENSSL_free(linebuf);
+    return values;
+
+ err:
+    OPENSSL_free(linebuf);
+    sk_CONF_VALUE_pop_free(values, X509V3_conf_free);
+    return NULL;
+
+}
+
+/* Delete leading and trailing spaces from a string */
+static char *strip_spaces(char *name)
+{
+    char *p, *q;
+    /* Skip over leading spaces */
+    p = name;
+    while (*p && isspace((unsigned char)*p))
+        p++;
+    if (!*p)
+        return NULL;
+    q = p + strlen(p) - 1;
+    while ((q != p) && isspace((unsigned char)*q))
+        q--;
+    if (p != q)
+        q[1] = 0;
+    if (!*p)
+        return NULL;
+    return p;
+}
+
+
+/*
+ * V2I name comparison function: returns zero if 'name' matches cmp or cmp.*
+ */
+
+int name_cmp(const char *name, const char *cmp)
+{
+    int len, ret;
+    char c;
+    len = strlen(cmp);
+    if ((ret = strncmp(name, cmp, len)))
+        return ret;
+    c = name[len];
+    if (!c || (c == '.'))
+        return 0;
+    return 1;
+}
+
+static int sk_strcmp(const char *const *a, const char *const *b)
+{
+    return strcmp(*a, *b);
+}
+
+STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x)
+{
+    GENERAL_NAMES *gens;
+    STACK_OF(OPENSSL_STRING) *ret;
+
+    gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
+    ret = get_email(X509_get_subject_name(x), gens);
+    sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+    return ret;
+}
+
+STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x)
+{
+    AUTHORITY_INFO_ACCESS *info;
+    STACK_OF(OPENSSL_STRING) *ret = NULL;
+    int i;
+
+    info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL);
+    if (!info)
+        return NULL;
+    for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) {
+        ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
+        if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) {
+            if (ad->location->type == GEN_URI) {
+                if (!append_ia5
+                    (&ret, ad->location->d.uniformResourceIdentifier))
+                    break;
+            }
+        }
+    }
+    AUTHORITY_INFO_ACCESS_free(info);
+    return ret;
+}
+
+STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x)
+{
+    GENERAL_NAMES *gens;
+    STACK_OF(X509_EXTENSION) *exts;
+    STACK_OF(OPENSSL_STRING) *ret;
+
+    exts = X509_REQ_get_extensions(x);
+    gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL);
+    ret = get_email(X509_REQ_get_subject_name(x), gens);
+    sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+    sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+    return ret;
+}
+
+static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name,
+                                           GENERAL_NAMES *gens)
+{
+    STACK_OF(OPENSSL_STRING) *ret = NULL;
+    X509_NAME_ENTRY *ne;
+    ASN1_IA5STRING *email;
+    GENERAL_NAME *gen;
+    int i;
+    /* Now add any email address(es) to STACK */
+    i = -1;
+    /* First supplied X509_NAME */
+    while ((i = X509_NAME_get_index_by_NID(name,
+                                           NID_pkcs9_emailAddress, i)) >= 0) {
+        ne = X509_NAME_get_entry(name, i);
+        email = X509_NAME_ENTRY_get_data(ne);
+        if (!append_ia5(&ret, email))
+            return NULL;
+    }
+    for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+        gen = sk_GENERAL_NAME_value(gens, i);
+        if (gen->type != GEN_EMAIL)
+            continue;
+        if (!append_ia5(&ret, gen->d.ia5))
+            return NULL;
+    }
+    return ret;
+}
+
+static void str_free(OPENSSL_STRING str)
+{
+    OPENSSL_free(str);
+}
+
+static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, const ASN1_IA5STRING *email)
+{
+    char *emtmp;
+    /* First some sanity checks */
+    if (email->type != V_ASN1_IA5STRING)
+        return 1;
+    if (!email->data || !email->length)
+        return 1;
+    if (*sk == NULL)
+        *sk = sk_OPENSSL_STRING_new(sk_strcmp);
+    if (*sk == NULL)
+        return 0;
+    /* Don't add duplicates */
+    if (sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1)
+        return 1;
+    emtmp = OPENSSL_strdup((char *)email->data);
+    if (emtmp == NULL || !sk_OPENSSL_STRING_push(*sk, emtmp)) {
+        OPENSSL_free(emtmp);    /* free on push failure */
+        X509_email_free(*sk);
+        *sk = NULL;
+        return 0;
+    }
+    return 1;
+}
+
+void X509_email_free(STACK_OF(OPENSSL_STRING) *sk)
+{
+    sk_OPENSSL_STRING_pop_free(sk, str_free);
+}
+
+typedef int (*equal_fn) (const unsigned char *pattern, size_t pattern_len,
+                         const unsigned char *subject, size_t subject_len,
+                         unsigned int flags);
+
+/* Skip pattern prefix to match "wildcard" subject */
+static void skip_prefix(const unsigned char **p, size_t *plen,
+                        size_t subject_len,
+                        unsigned int flags)
+{
+    const unsigned char *pattern = *p;
+    size_t pattern_len = *plen;
+
+    /*
+     * If subject starts with a leading '.' followed by more octets, and
+     * pattern is longer, compare just an equal-length suffix with the
+     * full subject (starting at the '.'), provided the prefix contains
+     * no NULs.
+     */
+    if ((flags & _X509_CHECK_FLAG_DOT_SUBDOMAINS) == 0)
+        return;
+
+    while (pattern_len > subject_len && *pattern) {
+        if ((flags & X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) &&
+            *pattern == '.')
+            break;
+        ++pattern;
+        --pattern_len;
+    }
+
+    /* Skip if entire prefix acceptable */
+    if (pattern_len == subject_len) {
+        *p = pattern;
+        *plen = pattern_len;
+    }
+}
+
+/* Compare while ASCII ignoring case. */
+static int equal_nocase(const unsigned char *pattern, size_t pattern_len,
+                        const unsigned char *subject, size_t subject_len,
+                        unsigned int flags)
+{
+    skip_prefix(&pattern, &pattern_len, subject_len, flags);
+    if (pattern_len != subject_len)
+        return 0;
+    while (pattern_len) {
+        unsigned char l = *pattern;
+        unsigned char r = *subject;
+        /* The pattern must not contain NUL characters. */
+        if (l == 0)
+            return 0;
+        if (l != r) {
+            if ('A' <= l && l <= 'Z')
+                l = (l - 'A') + 'a';
+            if ('A' <= r && r <= 'Z')
+                r = (r - 'A') + 'a';
+            if (l != r)
+                return 0;
+        }
+        ++pattern;
+        ++subject;
+        --pattern_len;
+    }
+    return 1;
+}
+
+/* Compare using memcmp. */
+static int equal_case(const unsigned char *pattern, size_t pattern_len,
+                      const unsigned char *subject, size_t subject_len,
+                      unsigned int flags)
+{
+    skip_prefix(&pattern, &pattern_len, subject_len, flags);
+    if (pattern_len != subject_len)
+        return 0;
+    return !memcmp(pattern, subject, pattern_len);
+}
+
+/*
+ * RFC 5280, section 7.5, requires that only the domain is compared in a
+ * case-insensitive manner.
+ */
+static int equal_email(const unsigned char *a, size_t a_len,
+                       const unsigned char *b, size_t b_len,
+                       unsigned int unused_flags)
+{
+    size_t i = a_len;
+    if (a_len != b_len)
+        return 0;
+    /*
+     * We search backwards for the '@' character, so that we do not have to
+     * deal with quoted local-parts.  The domain part is compared in a
+     * case-insensitive manner.
+     */
+    while (i > 0) {
+        --i;
+        if (a[i] == '@' || b[i] == '@') {
+            if (!equal_nocase(a + i, a_len - i, b + i, a_len - i, 0))
+                return 0;
+            break;
+        }
+    }
+    if (i == 0)
+        i = a_len;
+    return equal_case(a, i, b, i, 0);
+}
+
+/*
+ * Compare the prefix and suffix with the subject, and check that the
+ * characters in-between are valid.
+ */
+static int wildcard_match(const unsigned char *prefix, size_t prefix_len,
+                          const unsigned char *suffix, size_t suffix_len,
+                          const unsigned char *subject, size_t subject_len,
+                          unsigned int flags)
+{
+    const unsigned char *wildcard_start;
+    const unsigned char *wildcard_end;
+    const unsigned char *p;
+    int allow_multi = 0;
+    int allow_idna = 0;
+
+    if (subject_len < prefix_len + suffix_len)
+        return 0;
+    if (!equal_nocase(prefix, prefix_len, subject, prefix_len, flags))
+        return 0;
+    wildcard_start = subject + prefix_len;
+    wildcard_end = subject + (subject_len - suffix_len);
+    if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len, flags))
+        return 0;
+    /*
+     * If the wildcard makes up the entire first label, it must match at
+     * least one character.
+     */
+    if (prefix_len == 0 && *suffix == '.') {
+        if (wildcard_start == wildcard_end)
+            return 0;
+        allow_idna = 1;
+        if (flags & X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS)
+            allow_multi = 1;
+    }
+    /* IDNA labels cannot match partial wildcards */
+    if (!allow_idna &&
+        subject_len >= 4 && strncasecmp((char *)subject, "xn--", 4) == 0)
+        return 0;
+    /* The wildcard may match a literal '*' */
+    if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*')
+        return 1;
+    /*
+     * Check that the part matched by the wildcard contains only
+     * permitted characters and only matches a single label unless
+     * allow_multi is set.
+     */
+    for (p = wildcard_start; p != wildcard_end; ++p)
+        if (!(('0' <= *p && *p <= '9') ||
+              ('A' <= *p && *p <= 'Z') ||
+              ('a' <= *p && *p <= 'z') ||
+              *p == '-' || (allow_multi && *p == '.')))
+            return 0;
+    return 1;
+}
+
+#define LABEL_START     (1 << 0)
+#define LABEL_END       (1 << 1)
+#define LABEL_HYPHEN    (1 << 2)
+#define LABEL_IDNA      (1 << 3)
+
+static const unsigned char *valid_star(const unsigned char *p, size_t len,
+                                       unsigned int flags)
+{
+    const unsigned char *star = 0;
+    size_t i;
+    int state = LABEL_START;
+    int dots = 0;
+    for (i = 0; i < len; ++i) {
+        /*
+         * Locate first and only legal wildcard, either at the start
+         * or end of a non-IDNA first and not final label.
+         */
+        if (p[i] == '*') {
+            int atstart = (state & LABEL_START);
+            int atend = (i == len - 1 || p[i + 1] == '.');
+            /*-
+             * At most one wildcard per pattern.
+             * No wildcards in IDNA labels.
+             * No wildcards after the first label.
+             */
+            if (star != NULL || (state & LABEL_IDNA) != 0 || dots)
+                return NULL;
+            /* Only full-label '*.example.com' wildcards? */
+            if ((flags & X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS)
+                && (!atstart || !atend))
+                return NULL;
+            /* No 'foo*bar' wildcards */
+            if (!atstart && !atend)
+                return NULL;
+            star = &p[i];
+            state &= ~LABEL_START;
+        } else if (('a' <= p[i] && p[i] <= 'z')
+                   || ('A' <= p[i] && p[i] <= 'Z')
+                   || ('0' <= p[i] && p[i] <= '9')) {
+            if ((state & LABEL_START) != 0
+                && len - i >= 4 && strncasecmp((char *)&p[i], "xn--", 4) == 0)
+                state |= LABEL_IDNA;
+            state &= ~(LABEL_HYPHEN | LABEL_START);
+        } else if (p[i] == '.') {
+            if ((state & (LABEL_HYPHEN | LABEL_START)) != 0)
+                return NULL;
+            state = LABEL_START;
+            ++dots;
+        } else if (p[i] == '-') {
+            /* no domain/subdomain starts with '-' */
+            if ((state & LABEL_START) != 0)
+                return NULL;
+            state |= LABEL_HYPHEN;
+        } else
+            return NULL;
+    }
+
+    /*
+     * The final label must not end in a hyphen or ".", and
+     * there must be at least two dots after the star.
+     */
+    if ((state & (LABEL_START | LABEL_HYPHEN)) != 0 || dots < 2)
+        return NULL;
+    return star;
+}
+
+/* Compare using wildcards. */
+static int equal_wildcard(const unsigned char *pattern, size_t pattern_len,
+                          const unsigned char *subject, size_t subject_len,
+                          unsigned int flags)
+{
+    const unsigned char *star = NULL;
+
+    /*
+     * Subject names starting with '.' can only match a wildcard pattern
+     * via a subject sub-domain pattern suffix match.
+     */
+    if (!(subject_len > 1 && subject[0] == '.'))
+        star = valid_star(pattern, pattern_len, flags);
+    if (star == NULL)
+        return equal_nocase(pattern, pattern_len,
+                            subject, subject_len, flags);
+    return wildcard_match(pattern, star - pattern,
+                          star + 1, (pattern + pattern_len) - star - 1,
+                          subject, subject_len, flags);
+}
+
+/*
+ * Compare an ASN1_STRING to a supplied string. If they match return 1. If
+ * cmp_type > 0 only compare if string matches the type, otherwise convert it
+ * to UTF8.
+ */
+
+static int do_check_string(const ASN1_STRING *a, int cmp_type, equal_fn equal,
+                           unsigned int flags, const char *b, size_t blen,
+                           char **peername)
+{
+    int rv = 0;
+
+    if (!a->data || !a->length)
+        return 0;
+    if (cmp_type > 0) {
+        if (cmp_type != a->type)
+            return 0;
+        if (cmp_type == V_ASN1_IA5STRING)
+            rv = equal(a->data, a->length, (unsigned char *)b, blen, flags);
+        else if (a->length == (int)blen && !memcmp(a->data, b, blen))
+            rv = 1;
+        if (rv > 0 && peername)
+            *peername = OPENSSL_strndup((char *)a->data, a->length);
+    } else {
+        int astrlen;
+        unsigned char *astr;
+        astrlen = ASN1_STRING_to_UTF8(&astr, a);
+        if (astrlen < 0) {
+            /*
+             * -1 could be an internal malloc failure or a decoding error from
+             * malformed input; we can't distinguish.
+             */
+            return -1;
+        }
+        rv = equal(astr, astrlen, (unsigned char *)b, blen, flags);
+        if (rv > 0 && peername)
+            *peername = OPENSSL_strndup((char *)astr, astrlen);
+        OPENSSL_free(astr);
+    }
+    return rv;
+}
+
+static int do_x509_check(X509 *x, const char *chk, size_t chklen,
+                         unsigned int flags, int check_type, char **peername)
+{
+    GENERAL_NAMES *gens = NULL;
+    X509_NAME *name = NULL;
+    int i;
+    int cnid = NID_undef;
+    int alt_type;
+    int san_present = 0;
+    int rv = 0;
+    equal_fn equal;
+
+    /* See below, this flag is internal-only */
+    flags &= ~_X509_CHECK_FLAG_DOT_SUBDOMAINS;
+    if (check_type == GEN_EMAIL) {
+        cnid = NID_pkcs9_emailAddress;
+        alt_type = V_ASN1_IA5STRING;
+        equal = equal_email;
+    } else if (check_type == GEN_DNS) {
+        cnid = NID_commonName;
+        /* Implicit client-side DNS sub-domain pattern */
+        if (chklen > 1 && chk[0] == '.')
+            flags |= _X509_CHECK_FLAG_DOT_SUBDOMAINS;
+        alt_type = V_ASN1_IA5STRING;
+        if (flags & X509_CHECK_FLAG_NO_WILDCARDS)
+            equal = equal_nocase;
+        else
+            equal = equal_wildcard;
+    } else {
+        alt_type = V_ASN1_OCTET_STRING;
+        equal = equal_case;
+    }
+
+    if (chklen == 0)
+        chklen = strlen(chk);
+
+    gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
+    if (gens) {
+        for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+            GENERAL_NAME *gen;
+            ASN1_STRING *cstr;
+            gen = sk_GENERAL_NAME_value(gens, i);
+            if (gen->type != check_type)
+                continue;
+            san_present = 1;
+            if (check_type == GEN_EMAIL)
+                cstr = gen->d.rfc822Name;
+            else if (check_type == GEN_DNS)
+                cstr = gen->d.dNSName;
+            else
+                cstr = gen->d.iPAddress;
+            /* Positive on success, negative on error! */
+            if ((rv = do_check_string(cstr, alt_type, equal, flags,
+                                      chk, chklen, peername)) != 0)
+                break;
+        }
+        GENERAL_NAMES_free(gens);
+        if (rv != 0)
+            return rv;
+        if (san_present && !(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT))
+            return 0;
+    }
+
+    /* We're done if CN-ID is not pertinent */
+    if (cnid == NID_undef || (flags & X509_CHECK_FLAG_NEVER_CHECK_SUBJECT))
+        return 0;
+
+    i = -1;
+    name = X509_get_subject_name(x);
+    while ((i = X509_NAME_get_index_by_NID(name, cnid, i)) >= 0) {
+        const X509_NAME_ENTRY *ne = X509_NAME_get_entry(name, i);
+        const ASN1_STRING *str = X509_NAME_ENTRY_get_data(ne);
+
+        /* Positive on success, negative on error! */
+        if ((rv = do_check_string(str, -1, equal, flags,
+                                  chk, chklen, peername)) != 0)
+            return rv;
+    }
+    return 0;
+}
+
+int X509_check_host(X509 *x, const char *chk, size_t chklen,
+                    unsigned int flags, char **peername)
+{
+    if (chk == NULL)
+        return -2;
+    /*
+     * Embedded NULs are disallowed, except as the last character of a
+     * string of length 2 or more (tolerate caller including terminating
+     * NUL in string length).
+     */
+    if (chklen == 0)
+        chklen = strlen(chk);
+    else if (memchr(chk, '\0', chklen > 1 ? chklen - 1 : chklen))
+        return -2;
+    if (chklen > 1 && chk[chklen - 1] == '\0')
+        --chklen;
+    return do_x509_check(x, chk, chklen, flags, GEN_DNS, peername);
+}
+
+int X509_check_email(X509 *x, const char *chk, size_t chklen,
+                     unsigned int flags)
+{
+    if (chk == NULL)
+        return -2;
+    /*
+     * Embedded NULs are disallowed, except as the last character of a
+     * string of length 2 or more (tolerate caller including terminating
+     * NUL in string length).
+     */
+    if (chklen == 0)
+        chklen = strlen((char *)chk);
+    else if (memchr(chk, '\0', chklen > 1 ? chklen - 1 : chklen))
+        return -2;
+    if (chklen > 1 && chk[chklen - 1] == '\0')
+        --chklen;
+    return do_x509_check(x, chk, chklen, flags, GEN_EMAIL, NULL);
+}
+
+int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen,
+                  unsigned int flags)
+{
+    if (chk == NULL)
+        return -2;
+    return do_x509_check(x, (char *)chk, chklen, flags, GEN_IPADD, NULL);
+}
+
+int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags)
+{
+    unsigned char ipout[16];
+    size_t iplen;
+
+    if (ipasc == NULL)
+        return -2;
+    iplen = (size_t)a2i_ipadd(ipout, ipasc);
+    if (iplen == 0)
+        return -2;
+    return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL);
+}
+
+/*
+ * Convert IP addresses both IPv4 and IPv6 into an OCTET STRING compatible
+ * with RFC3280.
+ */
+
+ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc)
+{
+    unsigned char ipout[16];
+    ASN1_OCTET_STRING *ret;
+    int iplen;
+
+    /* If string contains a ':' assume IPv6 */
+
+    iplen = a2i_ipadd(ipout, ipasc);
+
+    if (!iplen)
+        return NULL;
+
+    ret = ASN1_OCTET_STRING_new();
+    if (ret == NULL)
+        return NULL;
+    if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) {
+        ASN1_OCTET_STRING_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc)
+{
+    ASN1_OCTET_STRING *ret = NULL;
+    unsigned char ipout[32];
+    char *iptmp = NULL, *p;
+    int iplen1, iplen2;
+    p = strchr(ipasc, '/');
+    if (!p)
+        return NULL;
+    iptmp = OPENSSL_strdup(ipasc);
+    if (!iptmp)
+        return NULL;
+    p = iptmp + (p - ipasc);
+    *p++ = 0;
+
+    iplen1 = a2i_ipadd(ipout, iptmp);
+
+    if (!iplen1)
+        goto err;
+
+    iplen2 = a2i_ipadd(ipout + iplen1, p);
+
+    OPENSSL_free(iptmp);
+    iptmp = NULL;
+
+    if (!iplen2 || (iplen1 != iplen2))
+        goto err;
+
+    ret = ASN1_OCTET_STRING_new();
+    if (ret == NULL)
+        goto err;
+    if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2))
+        goto err;
+
+    return ret;
+
+ err:
+    OPENSSL_free(iptmp);
+    ASN1_OCTET_STRING_free(ret);
+    return NULL;
+}
+
+int a2i_ipadd(unsigned char *ipout, const char *ipasc)
+{
+    /* If string contains a ':' assume IPv6 */
+
+    if (strchr(ipasc, ':')) {
+        if (!ipv6_from_asc(ipout, ipasc))
+            return 0;
+        return 16;
+    } else {
+        if (!ipv4_from_asc(ipout, ipasc))
+            return 0;
+        return 4;
+    }
+}
+
+static int ipv4_from_asc(unsigned char *v4, const char *in)
+{
+    int a0, a1, a2, a3;
+    if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4)
+        return 0;
+    if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255)
+        || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255))
+        return 0;
+    v4[0] = a0;
+    v4[1] = a1;
+    v4[2] = a2;
+    v4[3] = a3;
+    return 1;
+}
+
+typedef struct {
+    /* Temporary store for IPV6 output */
+    unsigned char tmp[16];
+    /* Total number of bytes in tmp */
+    int total;
+    /* The position of a zero (corresponding to '::') */
+    int zero_pos;
+    /* Number of zeroes */
+    int zero_cnt;
+} IPV6_STAT;
+
+static int ipv6_from_asc(unsigned char *v6, const char *in)
+{
+    IPV6_STAT v6stat;
+    v6stat.total = 0;
+    v6stat.zero_pos = -1;
+    v6stat.zero_cnt = 0;
+    /*
+     * Treat the IPv6 representation as a list of values separated by ':'.
+     * The presence of a '::' will parse as one, two or three zero length
+     * elements.
+     */
+    if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat))
+        return 0;
+
+    /* Now for some sanity checks */
+
+    if (v6stat.zero_pos == -1) {
+        /* If no '::' must have exactly 16 bytes */
+        if (v6stat.total != 16)
+            return 0;
+    } else {
+        /* If '::' must have less than 16 bytes */
+        if (v6stat.total == 16)
+            return 0;
+        /* More than three zeroes is an error */
+        if (v6stat.zero_cnt > 3)
+            return 0;
+        /* Can only have three zeroes if nothing else present */
+        else if (v6stat.zero_cnt == 3) {
+            if (v6stat.total > 0)
+                return 0;
+        }
+        /* Can only have two zeroes if at start or end */
+        else if (v6stat.zero_cnt == 2) {
+            if ((v6stat.zero_pos != 0)
+                && (v6stat.zero_pos != v6stat.total))
+                return 0;
+        } else
+            /* Can only have one zero if *not* start or end */
+        {
+            if ((v6stat.zero_pos == 0)
+                || (v6stat.zero_pos == v6stat.total))
+                return 0;
+        }
+    }
+
+    /* Format result */
+
+    if (v6stat.zero_pos >= 0) {
+        /* Copy initial part */
+        memcpy(v6, v6stat.tmp, v6stat.zero_pos);
+        /* Zero middle */
+        memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total);
+        /* Copy final part */
+        if (v6stat.total != v6stat.zero_pos)
+            memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total,
+                   v6stat.tmp + v6stat.zero_pos,
+                   v6stat.total - v6stat.zero_pos);
+    } else
+        memcpy(v6, v6stat.tmp, 16);
+
+    return 1;
+}
+
+static int ipv6_cb(const char *elem, int len, void *usr)
+{
+    IPV6_STAT *s = usr;
+    /* Error if 16 bytes written */
+    if (s->total == 16)
+        return 0;
+    if (len == 0) {
+        /* Zero length element, corresponds to '::' */
+        if (s->zero_pos == -1)
+            s->zero_pos = s->total;
+        /* If we've already got a :: its an error */
+        else if (s->zero_pos != s->total)
+            return 0;
+        s->zero_cnt++;
+    } else {
+        /* If more than 4 characters could be final a.b.c.d form */
+        if (len > 4) {
+            /* Need at least 4 bytes left */
+            if (s->total > 12)
+                return 0;
+            /* Must be end of string */
+            if (elem[len])
+                return 0;
+            if (!ipv4_from_asc(s->tmp + s->total, elem))
+                return 0;
+            s->total += 4;
+        } else {
+            if (!ipv6_hex(s->tmp + s->total, elem, len))
+                return 0;
+            s->total += 2;
+        }
+    }
+    return 1;
+}
+
+/*
+ * Convert a string of up to 4 hex digits into the corresponding IPv6 form.
+ */
+
+static int ipv6_hex(unsigned char *out, const char *in, int inlen)
+{
+    unsigned char c;
+    unsigned int num = 0;
+    int x;
+
+    if (inlen > 4)
+        return 0;
+    while (inlen--) {
+        c = *in++;
+        num <<= 4;
+        x = OPENSSL_hexchar2int(c);
+        if (x < 0)
+            return 0;
+        num |= (char)x;
+    }
+    out[0] = num >> 8;
+    out[1] = num & 0xff;
+    return 1;
+}
+
+int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk,
+                             unsigned long chtype)
+{
+    CONF_VALUE *v;
+    int i, mval, spec_char, plus_char;
+    char *p, *type;
+    if (!nm)
+        return 0;
+
+    for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
+        v = sk_CONF_VALUE_value(dn_sk, i);
+        type = v->name;
+        /*
+         * Skip past any leading X. X: X, etc to allow for multiple instances
+         */
+        for (p = type; *p; p++) {
+#ifndef CHARSET_EBCDIC
+            spec_char = ((*p == ':') || (*p == ',') || (*p == '.'));
+#else
+            spec_char = ((*p == os_toascii[':']) || (*p == os_toascii[','])
+                    || (*p == os_toascii['.']));
+#endif
+            if (spec_char) {
+                p++;
+                if (*p)
+                    type = p;
+                break;
+            }
+        }
+#ifndef CHARSET_EBCDIC
+        plus_char = (*type == '+');
+#else
+        plus_char = (*type == os_toascii['+']);
+#endif
+        if (plus_char) {
+            mval = -1;
+            type++;
+        } else
+            mval = 0;
+        if (!X509_NAME_add_entry_by_txt(nm, type, chtype,
+                                        (unsigned char *)v->value, -1, -1,
+                                        mval))
+            return 0;
+
+    }
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/crypto/x509v3/v3err.c	(revision 331)
@@ -0,0 +1,187 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509V3,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509V3,0,reason)
+
+static ERR_STRING_DATA X509V3_str_functs[] = {
+    {ERR_FUNC(X509V3_F_A2I_GENERAL_NAME), "a2i_GENERAL_NAME"},
+    {ERR_FUNC(X509V3_F_ADDR_VALIDATE_PATH_INTERNAL),
+     "addr_validate_path_internal"},
+    {ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE),
+     "ASIdentifierChoice_canonize"},
+    {ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL),
+     "ASIdentifierChoice_is_canonical"},
+    {ERR_FUNC(X509V3_F_COPY_EMAIL), "copy_email"},
+    {ERR_FUNC(X509V3_F_COPY_ISSUER), "copy_issuer"},
+    {ERR_FUNC(X509V3_F_DO_DIRNAME), "do_dirname"},
+    {ERR_FUNC(X509V3_F_DO_EXT_I2D), "do_ext_i2d"},
+    {ERR_FUNC(X509V3_F_DO_EXT_NCONF), "do_ext_nconf"},
+    {ERR_FUNC(X509V3_F_GNAMES_FROM_SECTNAME), "gnames_from_sectname"},
+    {ERR_FUNC(X509V3_F_I2S_ASN1_ENUMERATED), "i2s_ASN1_ENUMERATED"},
+    {ERR_FUNC(X509V3_F_I2S_ASN1_IA5STRING), "i2s_ASN1_IA5STRING"},
+    {ERR_FUNC(X509V3_F_I2S_ASN1_INTEGER), "i2s_ASN1_INTEGER"},
+    {ERR_FUNC(X509V3_F_I2V_AUTHORITY_INFO_ACCESS),
+     "i2v_AUTHORITY_INFO_ACCESS"},
+    {ERR_FUNC(X509V3_F_NOTICE_SECTION), "notice_section"},
+    {ERR_FUNC(X509V3_F_NREF_NOS), "nref_nos"},
+    {ERR_FUNC(X509V3_F_POLICY_SECTION), "policy_section"},
+    {ERR_FUNC(X509V3_F_PROCESS_PCI_VALUE), "process_pci_value"},
+    {ERR_FUNC(X509V3_F_R2I_CERTPOL), "r2i_certpol"},
+    {ERR_FUNC(X509V3_F_R2I_PCI), "r2i_pci"},
+    {ERR_FUNC(X509V3_F_S2I_ASN1_IA5STRING), "s2i_ASN1_IA5STRING"},
+    {ERR_FUNC(X509V3_F_S2I_ASN1_INTEGER), "s2i_ASN1_INTEGER"},
+    {ERR_FUNC(X509V3_F_S2I_ASN1_OCTET_STRING), "s2i_ASN1_OCTET_STRING"},
+    {ERR_FUNC(X509V3_F_S2I_SKEY_ID), "s2i_skey_id"},
+    {ERR_FUNC(X509V3_F_SET_DIST_POINT_NAME), "set_dist_point_name"},
+    {ERR_FUNC(X509V3_F_SXNET_ADD_ID_ASC), "SXNET_add_id_asc"},
+    {ERR_FUNC(X509V3_F_SXNET_ADD_ID_INTEGER), "SXNET_add_id_INTEGER"},
+    {ERR_FUNC(X509V3_F_SXNET_ADD_ID_ULONG), "SXNET_add_id_ulong"},
+    {ERR_FUNC(X509V3_F_SXNET_GET_ID_ASC), "SXNET_get_id_asc"},
+    {ERR_FUNC(X509V3_F_SXNET_GET_ID_ULONG), "SXNET_get_id_ulong"},
+    {ERR_FUNC(X509V3_F_V2I_ASIDENTIFIERS), "v2i_ASIdentifiers"},
+    {ERR_FUNC(X509V3_F_V2I_ASN1_BIT_STRING), "v2i_ASN1_BIT_STRING"},
+    {ERR_FUNC(X509V3_F_V2I_AUTHORITY_INFO_ACCESS),
+     "v2i_AUTHORITY_INFO_ACCESS"},
+    {ERR_FUNC(X509V3_F_V2I_AUTHORITY_KEYID), "v2i_AUTHORITY_KEYID"},
+    {ERR_FUNC(X509V3_F_V2I_BASIC_CONSTRAINTS), "v2i_BASIC_CONSTRAINTS"},
+    {ERR_FUNC(X509V3_F_V2I_CRLD), "v2i_crld"},
+    {ERR_FUNC(X509V3_F_V2I_EXTENDED_KEY_USAGE), "v2i_EXTENDED_KEY_USAGE"},
+    {ERR_FUNC(X509V3_F_V2I_GENERAL_NAMES), "v2i_GENERAL_NAMES"},
+    {ERR_FUNC(X509V3_F_V2I_GENERAL_NAME_EX), "v2i_GENERAL_NAME_ex"},
+    {ERR_FUNC(X509V3_F_V2I_IDP), "v2i_idp"},
+    {ERR_FUNC(X509V3_F_V2I_IPADDRBLOCKS), "v2i_IPAddrBlocks"},
+    {ERR_FUNC(X509V3_F_V2I_ISSUER_ALT), "v2i_issuer_alt"},
+    {ERR_FUNC(X509V3_F_V2I_NAME_CONSTRAINTS), "v2i_NAME_CONSTRAINTS"},
+    {ERR_FUNC(X509V3_F_V2I_POLICY_CONSTRAINTS), "v2i_POLICY_CONSTRAINTS"},
+    {ERR_FUNC(X509V3_F_V2I_POLICY_MAPPINGS), "v2i_POLICY_MAPPINGS"},
+    {ERR_FUNC(X509V3_F_V2I_SUBJECT_ALT), "v2i_subject_alt"},
+    {ERR_FUNC(X509V3_F_V2I_TLS_FEATURE), "v2i_TLS_FEATURE"},
+    {ERR_FUNC(X509V3_F_V3_GENERIC_EXTENSION), "v3_generic_extension"},
+    {ERR_FUNC(X509V3_F_X509V3_ADD1_I2D), "X509V3_add1_i2d"},
+    {ERR_FUNC(X509V3_F_X509V3_ADD_VALUE), "X509V3_add_value"},
+    {ERR_FUNC(X509V3_F_X509V3_EXT_ADD), "X509V3_EXT_add"},
+    {ERR_FUNC(X509V3_F_X509V3_EXT_ADD_ALIAS), "X509V3_EXT_add_alias"},
+    {ERR_FUNC(X509V3_F_X509V3_EXT_I2D), "X509V3_EXT_i2d"},
+    {ERR_FUNC(X509V3_F_X509V3_EXT_NCONF), "X509V3_EXT_nconf"},
+    {ERR_FUNC(X509V3_F_X509V3_GET_SECTION), "X509V3_get_section"},
+    {ERR_FUNC(X509V3_F_X509V3_GET_STRING), "X509V3_get_string"},
+    {ERR_FUNC(X509V3_F_X509V3_GET_VALUE_BOOL), "X509V3_get_value_bool"},
+    {ERR_FUNC(X509V3_F_X509V3_PARSE_LIST), "X509V3_parse_list"},
+    {ERR_FUNC(X509V3_F_X509_PURPOSE_ADD), "X509_PURPOSE_add"},
+    {ERR_FUNC(X509V3_F_X509_PURPOSE_SET), "X509_PURPOSE_set"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA X509V3_str_reasons[] = {
+    {ERR_REASON(X509V3_R_BAD_IP_ADDRESS), "bad ip address"},
+    {ERR_REASON(X509V3_R_BAD_OBJECT), "bad object"},
+    {ERR_REASON(X509V3_R_BN_DEC2BN_ERROR), "bn dec2bn error"},
+    {ERR_REASON(X509V3_R_BN_TO_ASN1_INTEGER_ERROR),
+     "bn to asn1 integer error"},
+    {ERR_REASON(X509V3_R_DIRNAME_ERROR), "dirname error"},
+    {ERR_REASON(X509V3_R_DISTPOINT_ALREADY_SET), "distpoint already set"},
+    {ERR_REASON(X509V3_R_DUPLICATE_ZONE_ID), "duplicate zone id"},
+    {ERR_REASON(X509V3_R_ERROR_CONVERTING_ZONE), "error converting zone"},
+    {ERR_REASON(X509V3_R_ERROR_CREATING_EXTENSION),
+     "error creating extension"},
+    {ERR_REASON(X509V3_R_ERROR_IN_EXTENSION), "error in extension"},
+    {ERR_REASON(X509V3_R_EXPECTED_A_SECTION_NAME), "expected a section name"},
+    {ERR_REASON(X509V3_R_EXTENSION_EXISTS), "extension exists"},
+    {ERR_REASON(X509V3_R_EXTENSION_NAME_ERROR), "extension name error"},
+    {ERR_REASON(X509V3_R_EXTENSION_NOT_FOUND), "extension not found"},
+    {ERR_REASON(X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED),
+     "extension setting not supported"},
+    {ERR_REASON(X509V3_R_EXTENSION_VALUE_ERROR), "extension value error"},
+    {ERR_REASON(X509V3_R_ILLEGAL_EMPTY_EXTENSION), "illegal empty extension"},
+    {ERR_REASON(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG),
+     "incorrect policy syntax tag"},
+    {ERR_REASON(X509V3_R_INVALID_ASNUMBER), "invalid asnumber"},
+    {ERR_REASON(X509V3_R_INVALID_ASRANGE), "invalid asrange"},
+    {ERR_REASON(X509V3_R_INVALID_BOOLEAN_STRING), "invalid boolean string"},
+    {ERR_REASON(X509V3_R_INVALID_EXTENSION_STRING),
+     "invalid extension string"},
+    {ERR_REASON(X509V3_R_INVALID_INHERITANCE), "invalid inheritance"},
+    {ERR_REASON(X509V3_R_INVALID_IPADDRESS), "invalid ipaddress"},
+    {ERR_REASON(X509V3_R_INVALID_MULTIPLE_RDNS), "invalid multiple rdns"},
+    {ERR_REASON(X509V3_R_INVALID_NAME), "invalid name"},
+    {ERR_REASON(X509V3_R_INVALID_NULL_ARGUMENT), "invalid null argument"},
+    {ERR_REASON(X509V3_R_INVALID_NULL_NAME), "invalid null name"},
+    {ERR_REASON(X509V3_R_INVALID_NULL_VALUE), "invalid null value"},
+    {ERR_REASON(X509V3_R_INVALID_NUMBER), "invalid number"},
+    {ERR_REASON(X509V3_R_INVALID_NUMBERS), "invalid numbers"},
+    {ERR_REASON(X509V3_R_INVALID_OBJECT_IDENTIFIER),
+     "invalid object identifier"},
+    {ERR_REASON(X509V3_R_INVALID_OPTION), "invalid option"},
+    {ERR_REASON(X509V3_R_INVALID_POLICY_IDENTIFIER),
+     "invalid policy identifier"},
+    {ERR_REASON(X509V3_R_INVALID_PROXY_POLICY_SETTING),
+     "invalid proxy policy setting"},
+    {ERR_REASON(X509V3_R_INVALID_PURPOSE), "invalid purpose"},
+    {ERR_REASON(X509V3_R_INVALID_SAFI), "invalid safi"},
+    {ERR_REASON(X509V3_R_INVALID_SECTION), "invalid section"},
+    {ERR_REASON(X509V3_R_INVALID_SYNTAX), "invalid syntax"},
+    {ERR_REASON(X509V3_R_ISSUER_DECODE_ERROR), "issuer decode error"},
+    {ERR_REASON(X509V3_R_MISSING_VALUE), "missing value"},
+    {ERR_REASON(X509V3_R_NEED_ORGANIZATION_AND_NUMBERS),
+     "need organization and numbers"},
+    {ERR_REASON(X509V3_R_NO_CONFIG_DATABASE), "no config database"},
+    {ERR_REASON(X509V3_R_NO_ISSUER_CERTIFICATE), "no issuer certificate"},
+    {ERR_REASON(X509V3_R_NO_ISSUER_DETAILS), "no issuer details"},
+    {ERR_REASON(X509V3_R_NO_POLICY_IDENTIFIER), "no policy identifier"},
+    {ERR_REASON(X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED),
+     "no proxy cert policy language defined"},
+    {ERR_REASON(X509V3_R_NO_PUBLIC_KEY), "no public key"},
+    {ERR_REASON(X509V3_R_NO_SUBJECT_DETAILS), "no subject details"},
+    {ERR_REASON(X509V3_R_OPERATION_NOT_DEFINED), "operation not defined"},
+    {ERR_REASON(X509V3_R_OTHERNAME_ERROR), "othername error"},
+    {ERR_REASON(X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED),
+     "policy language already defined"},
+    {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH), "policy path length"},
+    {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED),
+     "policy path length already defined"},
+    {ERR_REASON(X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY),
+     "policy when proxy language requires no policy"},
+    {ERR_REASON(X509V3_R_SECTION_NOT_FOUND), "section not found"},
+    {ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS),
+     "unable to get issuer details"},
+    {ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_KEYID),
+     "unable to get issuer keyid"},
+    {ERR_REASON(X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT),
+     "unknown bit string argument"},
+    {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION), "unknown extension"},
+    {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION_NAME), "unknown extension name"},
+    {ERR_REASON(X509V3_R_UNKNOWN_OPTION), "unknown option"},
+    {ERR_REASON(X509V3_R_UNSUPPORTED_OPTION), "unsupported option"},
+    {ERR_REASON(X509V3_R_UNSUPPORTED_TYPE), "unsupported type"},
+    {ERR_REASON(X509V3_R_USER_TOO_LONG), "user too long"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_X509V3_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(X509V3_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, X509V3_str_functs);
+        ERR_load_strings(0, X509V3_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/e_os.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/e_os.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/e_os.h	(revision 331)
@@ -0,0 +1,520 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_E_OS_H
+# define HEADER_E_OS_H
+
+# include <openssl/opensslconf.h>
+
+# include <openssl/e_os2.h>
+/*
+ * <openssl/e_os2.h> contains what we can justify to make visible to the
+ * outside; this file e_os.h is not part of the exported interface.
+ */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Used to checking reference counts, most while doing perl5 stuff :-) */
+# if defined(OPENSSL_NO_STDIO)
+#  if defined(REF_PRINT)
+#   error "REF_PRINT requires stdio"
+#  endif
+# endif
+
+# if !defined(NDEBUG) && !defined(OPENSSL_NO_STDIO)
+#  define REF_ASSERT_ISNT(test) \
+    (void)((test) ? (OPENSSL_die("refcount error", __FILE__, __LINE__), 1) : 0)
+# else
+#  define REF_ASSERT_ISNT(i)
+# endif
+# ifdef REF_PRINT
+#  define REF_PRINT_COUNT(a, b) \
+        fprintf(stderr, "%p:%4d:%s\n", b, b->references, a)
+# else
+#  define REF_PRINT_COUNT(a, b)
+# endif
+
+# define osslargused(x)      (void)x
+# define OPENSSL_CONF        "openssl.cnf"
+
+# ifndef DEVRANDOM
+/*
+ * set this to a comma-separated list of 'random' device files to try out. My
+ * default, we will try to read at least one of these files
+ */
+#  define DEVRANDOM "/dev/urandom","/dev/random","/dev/srandom"
+# endif
+# if !defined(OPENSSL_NO_EGD) && !defined(DEVRANDOM_EGD)
+/*
+ * set this to a comma-separated list of 'egd' sockets to try out. These
+ * sockets will be tried in the order listed in case accessing the device
+ * files listed in DEVRANDOM did not return enough entropy.
+ */
+#  define DEVRANDOM_EGD "/var/run/egd-pool","/dev/egd-pool","/etc/egd-pool","/etc/entropy"
+# endif
+
+# if defined(OPENSSL_SYS_VXWORKS)
+#  define NO_SYS_PARAM_H
+#  define NO_CHMOD
+#  define NO_SYSLOG
+# endif
+
+/********************************************************************
+ The Microsoft section
+ ********************************************************************/
+# if defined(OPENSSL_SYS_WIN32) && !defined(WIN32)
+#  define WIN32
+# endif
+# if defined(OPENSSL_SYS_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+# endif
+# if defined(OPENSSL_SYS_MSDOS) && !defined(MSDOS)
+#  define MSDOS
+# endif
+
+# if (defined(MSDOS) || defined(OPENSSL_SYS_UEFI)) && !defined(GETPID_IS_MEANINGLESS)
+#  define GETPID_IS_MEANINGLESS
+# endif
+
+# ifdef WIN32
+#  define NO_SYS_UN_H
+#  define get_last_sys_error()    GetLastError()
+#  define clear_sys_error()       SetLastError(0)
+#  if !defined(WINNT)
+#   define WIN_CONSOLE_BUG
+#  endif
+# else
+#  define get_last_sys_error()    errno
+#  define clear_sys_error()       errno=0
+# endif
+
+# if defined(WINDOWS)
+#  define get_last_socket_error() WSAGetLastError()
+#  define clear_socket_error()    WSASetLastError(0)
+#  define readsocket(s,b,n)       recv((s),(b),(n),0)
+#  define writesocket(s,b,n)      send((s),(b),(n),0)
+# elif defined(__DJGPP__)
+#  define WATT32
+#  define WATT32_NO_OLDIES
+#  define get_last_socket_error() errno
+#  define clear_socket_error()    errno=0
+#  define closesocket(s)          close_s(s)
+#  define readsocket(s,b,n)       read_s(s,b,n)
+#  define writesocket(s,b,n)      send(s,b,n,0)
+# elif defined(OPENSSL_SYS_VMS)
+#  define get_last_socket_error() errno
+#  define clear_socket_error()    errno=0
+#  define ioctlsocket(a,b,c)      ioctl(a,b,c)
+#  define closesocket(s)          close(s)
+#  define readsocket(s,b,n)       recv((s),(b),(n),0)
+#  define writesocket(s,b,n)      send((s),(b),(n),0)
+# elif defined(OPENSSL_SYS_VXWORKS)
+#  define get_last_socket_error() errno
+#  define clear_socket_error()    errno=0
+#  define ioctlsocket(a,b,c)          ioctl((a),(b),(int)(c))
+#  define closesocket(s)              close(s)
+#  define readsocket(s,b,n)           read((s),(b),(n))
+#  define writesocket(s,b,n)          write((s),(char *)(b),(n))
+# else
+#  define get_last_socket_error() errno
+#  define clear_socket_error()    errno=0
+#  define ioctlsocket(a,b,c)      ioctl(a,b,c)
+#  define closesocket(s)          close(s)
+#  define readsocket(s,b,n)       read((s),(b),(n))
+#  define writesocket(s,b,n)      write((s),(b),(n))
+# endif
+
+# if (defined(WINDOWS) || defined(MSDOS))
+
+#  ifdef __DJGPP__
+#   include <unistd.h>
+#   include <sys/stat.h>
+#   include <sys/socket.h>
+#   include <sys/un.h>
+#   include <tcp.h>
+#   include <netdb.h>
+#   define _setmode setmode
+#   define _O_TEXT O_TEXT
+#   define _O_BINARY O_BINARY
+#   define HAS_LFN_SUPPORT(name)  (pathconf((name), _PC_NAME_MAX) > 12)
+#   undef DEVRANDOM_EGD  /*  Neither MS-DOS nor FreeDOS provide 'egd' sockets.  */
+#   undef DEVRANDOM
+#   define DEVRANDOM "/dev/urandom\x24"
+#  endif                        /* __DJGPP__ */
+
+#  ifndef S_IFDIR
+#   define S_IFDIR     _S_IFDIR
+#  endif
+
+#  ifndef S_IFMT
+#   define S_IFMT      _S_IFMT
+#  endif
+
+#  if !defined(WINNT) && !defined(__DJGPP__)
+#   define NO_SYSLOG
+#  endif
+#  define NO_DIRENT
+
+#  ifdef WINDOWS
+#   if !defined(_WIN32_WCE) && !defined(_WIN32_WINNT)
+       /*
+        * Defining _WIN32_WINNT here in e_os.h implies certain "discipline."
+        * Most notably we ought to check for availability of each specific
+        * routine that was introduced after denoted _WIN32_WINNT with
+        * GetProcAddress(). Normally newer functions are masked with higher
+        * _WIN32_WINNT in SDK headers. So that if you wish to use them in
+        * some module, you'd need to override _WIN32_WINNT definition in
+        * the target module in order to "reach for" prototypes, but replace
+        * calls to new functions with indirect calls. Alternatively it
+        * might be possible to achieve the goal by /DELAYLOAD-ing .DLLs
+        * and check for current OS version instead.
+        */
+#    define _WIN32_WINNT 0x0501
+#   endif
+#   if defined(_WIN32_WINNT) || defined(_WIN32_WCE)
+       /*
+        * Just like defining _WIN32_WINNT including winsock2.h implies
+        * certain "discipline" for maintaining [broad] binary compatibility.
+        * As long as structures are invariant among Winsock versions,
+        * it's sufficient to check for specific Winsock2 API availability
+        * at run-time [DSO_global_lookup is recommended]...
+        */
+#    include <winsock2.h>
+#    include <ws2tcpip.h>
+       /* yes, they have to be #included prior to <windows.h> */
+#   endif
+#   include <windows.h>
+#   include <stdio.h>
+#   include <stddef.h>
+#   include <errno.h>
+#   if defined(_WIN32_WCE) && !defined(EACCES)
+#    define EACCES   13
+#   endif
+#   include <string.h>
+#   ifdef _WIN64
+#    define strlen(s) _strlen31(s)
+/* cut strings to 2GB */
+static __inline unsigned int _strlen31(const char *str)
+{
+    unsigned int len = 0;
+    while (*str && len < 0x80000000U)
+        str++, len++;
+    return len & 0x7FFFFFFF;
+}
+#   endif
+#   include <malloc.h>
+#   if defined(_MSC_VER) && _MSC_VER<=1200 && defined(_MT) && defined(isspace)
+       /* compensate for bug in VC6 ctype.h */
+#    undef isspace
+#    undef isdigit
+#    undef isalnum
+#    undef isupper
+#    undef isxdigit
+#   endif
+#   if defined(_MSC_VER) && !defined(_WIN32_WCE) && !defined(_DLL) && defined(stdin)
+#    if _MSC_VER>=1300 && _MSC_VER<1600
+#     undef stdin
+#     undef stdout
+#     undef stderr
+FILE *__iob_func();
+#     define stdin  (&__iob_func()[0])
+#     define stdout (&__iob_func()[1])
+#     define stderr (&__iob_func()[2])
+#    elif _MSC_VER<1300 && defined(I_CAN_LIVE_WITH_LNK4049)
+#     undef stdin
+#     undef stdout
+#     undef stderr
+         /*
+          * pre-1300 has __p__iob(), but it's available only in msvcrt.lib,
+          * or in other words with /MD. Declaring implicit import, i.e. with
+          * _imp_ prefix, works correctly with all compiler options, but
+          * without /MD results in LINK warning LNK4049: 'locally defined
+          * symbol "__iob" imported'.
+          */
+extern FILE *_imp___iob;
+#     define stdin  (&_imp___iob[0])
+#     define stdout (&_imp___iob[1])
+#     define stderr (&_imp___iob[2])
+#    endif
+#   endif
+#  endif
+#  include <io.h>
+#  include <fcntl.h>
+
+#  ifdef OPENSSL_SYS_WINCE
+#   define OPENSSL_NO_POSIX_IO
+#  endif
+
+#  define EXIT(n) exit(n)
+#  define LIST_SEPARATOR_CHAR ';'
+#  ifndef X_OK
+#   define X_OK        0
+#  endif
+#  ifndef W_OK
+#   define W_OK        2
+#  endif
+#  ifndef R_OK
+#   define R_OK        4
+#  endif
+#  ifdef OPENSSL_SYS_WINCE
+#   define DEFAULT_HOME  ""
+#  else
+#   define DEFAULT_HOME  "C:"
+#  endif
+
+/* Avoid Visual Studio 13 GetVersion deprecated problems */
+#  if defined(_MSC_VER) && _MSC_VER>=1800
+#   define check_winnt() (1)
+#   define check_win_minplat(x) (1)
+#  else
+#   define check_winnt() (GetVersion() < 0x80000000)
+#   define check_win_minplat(x) (LOBYTE(LOWORD(GetVersion())) >= (x))
+#  endif
+
+# else                          /* The non-microsoft world */
+
+#  ifdef OPENSSL_SYS_VMS
+#   define VMS 1
+  /*
+   * some programs don't include stdlib, so exit() and others give implicit
+   * function warnings
+   */
+#   include <stdlib.h>
+#   if defined(__DECC)
+#    include <unistd.h>
+#   else
+#    include <unixlib.h>
+#   endif
+#   define LIST_SEPARATOR_CHAR ','
+  /* We don't have any well-defined random devices on VMS, yet... */
+#   undef DEVRANDOM
+  /*-
+     We need to do this since VMS has the following coding on status codes:
+
+     Bits 0-2: status type: 0 = warning, 1 = success, 2 = error, 3 = info ...
+               The important thing to know is that odd numbers are considered
+               good, while even ones are considered errors.
+     Bits 3-15: actual status number
+     Bits 16-27: facility number.  0 is considered "unknown"
+     Bits 28-31: control bits.  If bit 28 is set, the shell won't try to
+                 output the message (which, for random codes, just looks ugly)
+
+     So, what we do here is to change 0 to 1 to get the default success status,
+     and everything else is shifted up to fit into the status number field, and
+     the status is tagged as an error, which is what is wanted here.
+
+     Finally, we add the VMS C facility code 0x35a000, because there are some
+     programs, such as Perl, that will reinterpret the code back to something
+     POSIXly.  'man perlvms' explains it further.
+
+     NOTE: the perlvms manual wants to turn all codes 2 to 255 into success
+     codes (status type = 1).  I couldn't disagree more.  Fortunately, the
+     status type doesn't seem to bother Perl.
+     -- Richard Levitte
+  */
+#   define EXIT(n)  exit((n) ? (((n) << 3) | 2 | 0x10000000 | 0x35a000) : 1)
+
+#   define NO_SYS_PARAM_H
+#   define NO_SYS_UN_H
+
+#   define DEFAULT_HOME "SYS$LOGIN:"
+
+#  else
+     /* !defined VMS */
+#   ifdef OPENSSL_UNISTD
+#    include OPENSSL_UNISTD
+#   else
+#    include <unistd.h>
+#   endif
+#   ifndef NO_SYS_TYPES_H
+#    include <sys/types.h>
+#   endif
+#   ifdef OPENSSL_SYS_WIN32_CYGWIN
+#    include <io.h>
+#    include <fcntl.h>
+#   endif
+
+#   define LIST_SEPARATOR_CHAR ':'
+#   define EXIT(n)             exit(n)
+#  endif
+
+# endif
+
+/*************/
+
+# ifdef USE_SOCKETS
+#  ifdef OPENSSL_NO_SOCK
+#  elif defined(WINDOWS) || defined(MSDOS)
+      /* windows world */
+#   if !defined(__DJGPP__)
+#    if defined(_WIN32_WCE) && _WIN32_WCE<410
+#     define getservbyname _masked_declaration_getservbyname
+#    endif
+#    if !defined(IPPROTO_IP)
+         /* winsock[2].h was included already? */
+#     include <winsock.h>
+#    endif
+#    ifdef getservbyname
+#     undef getservbyname
+         /* this is used to be wcecompat/include/winsock_extras.h */
+struct servent *PASCAL getservbyname(const char *, const char *);
+#    endif
+
+#    ifdef _WIN64
+/*
+ * Even though sizeof(SOCKET) is 8, it's safe to cast it to int, because
+ * the value constitutes an index in per-process table of limited size
+ * and not a real pointer. And we also depend on fact that all processors
+ * Windows run on happen to be two's-complement, which allows to
+ * interchange INVALID_SOCKET and -1.
+ */
+#     define socket(d,t,p)   ((int)socket(d,t,p))
+#     define accept(s,f,l)   ((int)accept(s,f,l))
+#    endif
+#   else
+#   endif
+
+#  else
+
+#   ifndef NO_SYS_PARAM_H
+#    include <sys/param.h>
+#   endif
+#   ifdef OPENSSL_SYS_VXWORKS
+#    include <time.h>
+#   endif
+
+#   include <netdb.h>
+#   if defined(OPENSSL_SYS_VMS_NODECC)
+#    include <socket.h>
+#    include <in.h>
+#    include <inet.h>
+#   else
+#    include <sys/socket.h>
+#    ifndef NO_SYS_UN_H
+#     ifdef OPENSSL_SYS_VXWORKS
+#      include <streams/un.h>
+#     else
+#      include <sys/un.h>
+#     endif
+#     ifndef UNIX_PATH_MAX
+#      define UNIX_PATH_MAX sizeof(((struct sockaddr_un *)NULL)->sun_path)
+#     endif
+#    endif
+#    ifdef FILIO_H
+#     include <sys/filio.h> /* FIONBIO in some SVR4, e.g. unixware, solaris */
+#    endif
+#    include <netinet/in.h>
+#    include <arpa/inet.h>
+#    include <netinet/tcp.h>
+#   endif
+
+#   ifdef OPENSSL_SYS_AIX
+#    include <sys/select.h>
+#   endif
+
+#   ifdef __QNX__
+#    include <sys/select.h>
+#   endif
+
+#   ifndef VMS
+#    include <sys/ioctl.h>
+#   else
+        /* ioctl is only in VMS > 7.0 and when socketshr is not used */
+#    if !defined(TCPIP_TYPE_SOCKETSHR) && defined(__VMS_VER) && (__VMS_VER > 70000000)
+#     include <sys/ioctl.h>
+#    endif
+#   endif
+
+#   ifdef VMS
+#    include <unixio.h>
+#    if defined(TCPIP_TYPE_SOCKETSHR)
+#     include <socketshr.h>
+#    endif
+#   endif
+
+#   ifndef INVALID_SOCKET
+#    define INVALID_SOCKET      (-1)
+#   endif                       /* INVALID_SOCKET */
+#  endif
+
+/*
+ * Some IPv6 implementations are broken, disable them in known bad versions.
+ */
+#  if !defined(OPENSSL_USE_IPV6)
+#   if defined(AF_INET6) && !defined(NETWARE_CLIB)
+#    define OPENSSL_USE_IPV6 1
+#   else
+#    define OPENSSL_USE_IPV6 0
+#   endif
+#  endif
+
+# endif
+
+# ifndef OPENSSL_EXIT
+#  if defined(MONOLITH) && !defined(OPENSSL_C)
+#   define OPENSSL_EXIT(n) return(n)
+#  else
+#   define OPENSSL_EXIT(n) do { EXIT(n); return(n); } while(0)
+#  endif
+# endif
+
+/***********************************************/
+
+# if defined(OPENSSL_SYS_WINDOWS)
+#  define strcasecmp _stricmp
+#  define strncasecmp _strnicmp
+#  if (_MSC_VER >= 1310)
+#   define open _open
+#   define fdopen _fdopen
+#   define close _close
+#   ifndef strdup
+#    define strdup _strdup
+#   endif
+#   define unlink _unlink
+#  endif
+# else
+#  include <strings.h>
+# endif
+
+/* vxworks */
+# if defined(OPENSSL_SYS_VXWORKS)
+#  include <ioLib.h>
+#  include <tickLib.h>
+#  include <sysLib.h>
+
+#  define TTY_STRUCT int
+
+#  define sleep(a) taskDelay((a) * sysClkRateGet())
+
+#  include <vxWorks.h>
+#  include <sockLib.h>
+#  include <taskLib.h>
+
+#  define getpid taskIdSelf
+
+/*
+ * NOTE: these are implemented by helpers in database app! if the database is
+ * not linked, we need to implement them elswhere
+ */
+struct hostent *gethostbyname(const char *name);
+struct hostent *gethostbyaddr(const char *addr, int length, int type);
+struct servent *getservbyname(const char *name, const char *proto);
+
+# endif
+/* end vxworks */
+
+#define OSSL_NELEM(x)    (sizeof(x)/sizeof(x[0]))
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/engines/afalg/e_afalg.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/engines/afalg/e_afalg.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/engines/afalg/e_afalg.h	(revision 331)
@@ -0,0 +1,75 @@
+/*
+ * 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
+ */
+
+#ifndef HEADER_AFALG_H
+# define HEADER_AFALG_H
+
+# ifdef ALG_DEBUG
+#  define ALG_DGB(x, ...) fprintf(stderr, "ALG_DBG: " x, __VA_ARGS__)
+#  define ALG_INFO(x, ...) fprintf(stderr, "ALG_INFO: " x, __VA_ARGS__)
+#  define ALG_WARN(x, ...) fprintf(stderr, "ALG_WARN: " x, __VA_ARGS__)
+# else
+#  define ALG_DGB(x, ...)
+#  define ALG_INFO(x, ...)
+#  define ALG_WARN(x, ...)
+# endif
+
+# define ALG_ERR(x, ...) fprintf(stderr, "ALG_ERR: " x, __VA_ARGS__)
+# define ALG_PERR(x, ...) \
+                do { \
+                    fprintf(stderr, "ALG_PERR: " x, __VA_ARGS__); \
+                    perror(NULL); \
+                } while(0)
+# define ALG_PWARN(x, ...) \
+                do { \
+                    fprintf(stderr, "ALG_PERR: " x, __VA_ARGS__); \
+                    perror(NULL); \
+                } while(0)
+
+# ifndef AES_BLOCK_SIZE
+#  define AES_BLOCK_SIZE   16
+# endif
+# define AES_KEY_SIZE_128 16
+# define AES_IV_LEN       16
+
+# define MAX_INFLIGHTS 1
+
+typedef enum {
+    MODE_UNINIT = 0,
+    MODE_SYNC,
+    MODE_ASYNC
+} op_mode;
+
+struct afalg_aio_st {
+    int efd;
+    op_mode mode;
+    aio_context_t aio_ctx;
+    struct io_event events[MAX_INFLIGHTS];
+    struct iocb cbt[MAX_INFLIGHTS];
+};
+typedef struct afalg_aio_st afalg_aio;
+
+/*
+ * MAGIC Number to identify correct initialisation
+ * of afalg_ctx.
+ */
+# define MAGIC_INIT_NUM 0x1890671
+
+struct afalg_ctx_st {
+    int init_done;
+    int sfd;
+    int bfd;
+# ifdef ALG_ZERO_COPY
+    int zc_pipe[2];
+# endif
+    afalg_aio aio;
+};
+
+typedef struct afalg_ctx_st afalg_ctx;
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/engines/afalg/e_afalg_err.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/engines/afalg/e_afalg_err.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/engines/afalg/e_afalg_err.h	(revision 331)
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*
+ * NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#ifndef HEADER_AFALG_ERR_H
+# define HEADER_AFALG_ERR_H
+
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+/* BEGIN ERROR CODES */
+void ERR_load_AFALG_strings(void);
+void ERR_unload_AFALG_strings(void);
+void ERR_AFALG_error(int function, int reason, char *file, int line);
+# define AFALGerr(f,r) ERR_AFALG_error((f),(r),__FILE__,__LINE__)
+
+/* Error codes for the AFALG functions. */
+
+/* Function codes. */
+# define AFALG_F_AFALG_CHK_PLATFORM                       100
+# define AFALG_F_AFALG_CREATE_BIND_SK                     106
+# define AFALG_F_AFALG_CREATE_BIND_SOCKET                 105
+# define AFALG_F_AFALG_CREATE_SK                          108
+# define AFALG_F_AFALG_INIT_AIO                           101
+# define AFALG_F_AFALG_SETUP_ASYNC_EVENT_NOTIFICATION     107
+# define AFALG_F_AFALG_SET_KEY                            109
+# define AFALG_F_AFALG_SOCKET                             102
+# define AFALG_F_AFALG_START_CIPHER_SK                    103
+# define AFALG_F_BIND_AFALG                               104
+
+/* Reason codes. */
+# define AFALG_R_EVENTFD_FAILED                           108
+# define AFALG_R_FAILED_TO_GET_PLATFORM_INFO              111
+# define AFALG_R_INIT_FAILED                              100
+# define AFALG_R_IO_SETUP_FAILED                          105
+# define AFALG_R_KERNEL_DOES_NOT_SUPPORT_AFALG            101
+# define AFALG_R_KERNEL_DOES_NOT_SUPPORT_ASYNC_AFALG      107
+# define AFALG_R_MEM_ALLOC_FAILED                         102
+# define AFALG_R_SOCKET_ACCEPT_FAILED                     110
+# define AFALG_R_SOCKET_BIND_FAILED                       103
+# define AFALG_R_SOCKET_CREATE_FAILED                     109
+# define AFALG_R_SOCKET_OPERATION_FAILED                  104
+# define AFALG_R_SOCKET_SET_KEY_FAILED                    106
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/engines/e_capi.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/engines/e_capi.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/engines/e_capi.c	(revision 331)
@@ -0,0 +1,1916 @@
+/*
+ * Copyright 2008-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
+ */
+
+#ifdef _WIN32
+# ifndef _WIN32_WINNT
+#  define _WIN32_WINNT 0x0400
+# endif
+# include <windows.h>
+# include <wincrypt.h>
+
+# include <stdio.h>
+# include <string.h>
+# include <stdlib.h>
+# include <malloc.h>
+# ifndef alloca
+#  define alloca _alloca
+# endif
+
+# include <openssl/crypto.h>
+
+# ifndef OPENSSL_NO_CAPIENG
+
+#  include <openssl/buffer.h>
+#  include <openssl/bn.h>
+#  include <openssl/rsa.h>
+#  include <openssl/dsa.h>
+
+/*
+ * This module uses several "new" interfaces, among which is
+ * CertGetCertificateContextProperty. CERT_KEY_PROV_INFO_PROP_ID is
+ * one of possible values you can pass to function in question. By
+ * checking if it's defined we can see if wincrypt.h and accompanying
+ * crypt32.lib are in shape. The native MingW32 headers up to and
+ * including __W32API_VERSION 3.14 lack of struct DSSPUBKEY and the
+ * defines CERT_STORE_PROV_SYSTEM_A and CERT_STORE_READONLY_FLAG,
+ * so we check for these too and avoid compiling.
+ * Yes, it's rather "weak" test and if compilation fails,
+ * then re-configure with -DOPENSSL_NO_CAPIENG.
+ */
+#  if defined(CERT_KEY_PROV_INFO_PROP_ID) && \
+    defined(CERT_STORE_PROV_SYSTEM_A) && \
+    defined(CERT_STORE_READONLY_FLAG)
+#   define __COMPILE_CAPIENG
+#  endif                        /* CERT_KEY_PROV_INFO_PROP_ID */
+# endif                         /* OPENSSL_NO_CAPIENG */
+#endif                          /* _WIN32 */
+
+#ifdef __COMPILE_CAPIENG
+
+# undef X509_EXTENSIONS
+
+/* Definitions which may be missing from earlier version of headers */
+# ifndef CERT_STORE_OPEN_EXISTING_FLAG
+#  define CERT_STORE_OPEN_EXISTING_FLAG                   0x00004000
+# endif
+
+# ifndef CERT_STORE_CREATE_NEW_FLAG
+#  define CERT_STORE_CREATE_NEW_FLAG                      0x00002000
+# endif
+
+# ifndef CERT_SYSTEM_STORE_CURRENT_USER
+#  define CERT_SYSTEM_STORE_CURRENT_USER                  0x00010000
+# endif
+
+# ifndef ALG_SID_SHA_256
+#  define ALG_SID_SHA_256                 12
+# endif
+# ifndef ALG_SID_SHA_384
+#  define ALG_SID_SHA_384                 13
+# endif
+# ifndef ALG_SID_SHA_512
+#  define ALG_SID_SHA_512                 14
+# endif
+
+# ifndef CALG_SHA_256
+#  define CALG_SHA_256            (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_256)
+# endif
+# ifndef CALG_SHA_384
+#  define CALG_SHA_384            (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_384)
+# endif
+# ifndef CALG_SHA_512
+#  define CALG_SHA_512            (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_512)
+# endif
+
+# ifndef PROV_RSA_AES
+#  define PROV_RSA_AES 24
+# endif
+
+# include <openssl/engine.h>
+# include <openssl/pem.h>
+# include <openssl/x509v3.h>
+
+# include "e_capi_err.h"
+# include "e_capi_err.c"
+
+static const char *engine_capi_id = "capi";
+static const char *engine_capi_name = "CryptoAPI ENGINE";
+
+typedef struct CAPI_CTX_st CAPI_CTX;
+typedef struct CAPI_KEY_st CAPI_KEY;
+
+static void capi_addlasterror(void);
+static void capi_adderror(DWORD err);
+
+static void CAPI_trace(CAPI_CTX * ctx, char *format, ...);
+
+static int capi_list_providers(CAPI_CTX * ctx, BIO *out);
+static int capi_list_containers(CAPI_CTX * ctx, BIO *out);
+int capi_list_certs(CAPI_CTX * ctx, BIO *out, char *storename);
+void capi_free_key(CAPI_KEY * key);
+
+static PCCERT_CONTEXT capi_find_cert(CAPI_CTX * ctx, const char *id,
+                                     HCERTSTORE hstore);
+
+CAPI_KEY *capi_find_key(CAPI_CTX * ctx, const char *id);
+
+static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id,
+                                   UI_METHOD *ui_method, void *callback_data);
+static int capi_rsa_sign(int dtype, const unsigned char *m,
+                         unsigned int m_len, unsigned char *sigret,
+                         unsigned int *siglen, const RSA *rsa);
+static int capi_rsa_priv_enc(int flen, const unsigned char *from,
+                             unsigned char *to, RSA *rsa, int padding);
+static int capi_rsa_priv_dec(int flen, const unsigned char *from,
+                             unsigned char *to, RSA *rsa, int padding);
+static int capi_rsa_free(RSA *rsa);
+
+# ifndef OPENSSL_NO_DSA
+static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen,
+                                 DSA *dsa);
+static int capi_dsa_free(DSA *dsa);
+# endif
+
+static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
+                                     STACK_OF(X509_NAME) *ca_dn, X509 **pcert,
+                                     EVP_PKEY **pkey, STACK_OF(X509) **pother,
+                                     UI_METHOD *ui_method,
+                                     void *callback_data);
+
+static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
+# ifdef OPENSSL_CAPIENG_DIALOG
+static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
+# endif
+
+void engine_load_capi_int(void);
+
+typedef PCCERT_CONTEXT(WINAPI *CERTDLG) (HCERTSTORE, HWND, LPCWSTR,
+                                         LPCWSTR, DWORD, DWORD, void *);
+typedef HWND(WINAPI *GETCONSWIN) (void);
+
+/*
+ * This structure contains CAPI ENGINE specific data: it contains various
+ * global options and affects how other functions behave.
+ */
+
+# define CAPI_DBG_TRACE  2
+# define CAPI_DBG_ERROR  1
+
+struct CAPI_CTX_st {
+    int debug_level;
+    char *debug_file;
+    /* Parameters to use for container lookup */
+    DWORD keytype;
+    LPSTR cspname;
+    DWORD csptype;
+    /* Certificate store name to use */
+    LPSTR storename;
+    LPSTR ssl_client_store;
+    /* System store flags */
+    DWORD store_flags;
+/* Lookup string meanings in load_private_key */
+/* Substring of subject: uses "storename" */
+# define CAPI_LU_SUBSTR          1
+/* Friendly name: uses storename */
+# define CAPI_LU_FNAME           2
+/* Container name: uses cspname, keytype */
+# define CAPI_LU_CONTNAME        3
+    int lookup_method;
+/* Info to dump with dumpcerts option */
+/* Issuer and serial name strings */
+# define CAPI_DMP_SUMMARY        0x1
+/* Friendly name */
+# define CAPI_DMP_FNAME          0x2
+/* Full X509_print dump */
+# define CAPI_DMP_FULL           0x4
+/* Dump PEM format certificate */
+# define CAPI_DMP_PEM            0x8
+/* Dump pseudo key (if possible) */
+# define CAPI_DMP_PSKEY          0x10
+/* Dump key info (if possible) */
+# define CAPI_DMP_PKEYINFO       0x20
+    DWORD dump_flags;
+    int (*client_cert_select) (ENGINE *e, SSL *ssl, STACK_OF(X509) *certs);
+    CERTDLG certselectdlg;
+    GETCONSWIN getconswindow;
+};
+
+static CAPI_CTX *capi_ctx_new(void);
+static void capi_ctx_free(CAPI_CTX * ctx);
+static int capi_ctx_set_provname(CAPI_CTX * ctx, LPSTR pname, DWORD type,
+                                 int check);
+static int capi_ctx_set_provname_idx(CAPI_CTX * ctx, int idx);
+
+# define CAPI_CMD_LIST_CERTS             ENGINE_CMD_BASE
+# define CAPI_CMD_LOOKUP_CERT            (ENGINE_CMD_BASE + 1)
+# define CAPI_CMD_DEBUG_LEVEL            (ENGINE_CMD_BASE + 2)
+# define CAPI_CMD_DEBUG_FILE             (ENGINE_CMD_BASE + 3)
+# define CAPI_CMD_KEYTYPE                (ENGINE_CMD_BASE + 4)
+# define CAPI_CMD_LIST_CSPS              (ENGINE_CMD_BASE + 5)
+# define CAPI_CMD_SET_CSP_IDX            (ENGINE_CMD_BASE + 6)
+# define CAPI_CMD_SET_CSP_NAME           (ENGINE_CMD_BASE + 7)
+# define CAPI_CMD_SET_CSP_TYPE           (ENGINE_CMD_BASE + 8)
+# define CAPI_CMD_LIST_CONTAINERS        (ENGINE_CMD_BASE + 9)
+# define CAPI_CMD_LIST_OPTIONS           (ENGINE_CMD_BASE + 10)
+# define CAPI_CMD_LOOKUP_METHOD          (ENGINE_CMD_BASE + 11)
+# define CAPI_CMD_STORE_NAME             (ENGINE_CMD_BASE + 12)
+# define CAPI_CMD_STORE_FLAGS            (ENGINE_CMD_BASE + 13)
+
+static const ENGINE_CMD_DEFN capi_cmd_defns[] = {
+    {CAPI_CMD_LIST_CERTS,
+     "list_certs",
+     "List all certificates in store",
+     ENGINE_CMD_FLAG_NO_INPUT},
+    {CAPI_CMD_LOOKUP_CERT,
+     "lookup_cert",
+     "Lookup and output certificates",
+     ENGINE_CMD_FLAG_STRING},
+    {CAPI_CMD_DEBUG_LEVEL,
+     "debug_level",
+     "debug level (1=errors, 2=trace)",
+     ENGINE_CMD_FLAG_NUMERIC},
+    {CAPI_CMD_DEBUG_FILE,
+     "debug_file",
+     "debugging filename)",
+     ENGINE_CMD_FLAG_STRING},
+    {CAPI_CMD_KEYTYPE,
+     "key_type",
+     "Key type: 1=AT_KEYEXCHANGE (default), 2=AT_SIGNATURE",
+     ENGINE_CMD_FLAG_NUMERIC},
+    {CAPI_CMD_LIST_CSPS,
+     "list_csps",
+     "List all CSPs",
+     ENGINE_CMD_FLAG_NO_INPUT},
+    {CAPI_CMD_SET_CSP_IDX,
+     "csp_idx",
+     "Set CSP by index",
+     ENGINE_CMD_FLAG_NUMERIC},
+    {CAPI_CMD_SET_CSP_NAME,
+     "csp_name",
+     "Set CSP name, (default CSP used if not specified)",
+     ENGINE_CMD_FLAG_STRING},
+    {CAPI_CMD_SET_CSP_TYPE,
+     "csp_type",
+     "Set CSP type, (default RSA_PROV_FULL)",
+     ENGINE_CMD_FLAG_NUMERIC},
+    {CAPI_CMD_LIST_CONTAINERS,
+     "list_containers",
+     "list container names",
+     ENGINE_CMD_FLAG_NO_INPUT},
+    {CAPI_CMD_LIST_OPTIONS,
+     "list_options",
+     "Set list options (1=summary,2=friendly name, 4=full printout, 8=PEM output, 16=XXX, "
+     "32=private key info)",
+     ENGINE_CMD_FLAG_NUMERIC},
+    {CAPI_CMD_LOOKUP_METHOD,
+     "lookup_method",
+     "Set key lookup method (1=substring, 2=friendlyname, 3=container name)",
+     ENGINE_CMD_FLAG_NUMERIC},
+    {CAPI_CMD_STORE_NAME,
+     "store_name",
+     "certificate store name, default \"MY\"",
+     ENGINE_CMD_FLAG_STRING},
+    {CAPI_CMD_STORE_FLAGS,
+     "store_flags",
+     "Certificate store flags: 1 = system store",
+     ENGINE_CMD_FLAG_NUMERIC},
+
+    {0, NULL, NULL, 0}
+};
+
+static int capi_idx = -1;
+static int rsa_capi_idx = -1;
+static int dsa_capi_idx = -1;
+static int cert_capi_idx = -1;
+
+static int capi_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void))
+{
+    int ret = 1;
+    CAPI_CTX *ctx;
+    BIO *out;
+    LPSTR tmpstr;
+    if (capi_idx == -1) {
+        CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_ENGINE_NOT_INITIALIZED);
+        return 0;
+    }
+    ctx = ENGINE_get_ex_data(e, capi_idx);
+    out = BIO_new_fp(stdout, BIO_NOCLOSE);
+    if (out == NULL) {
+        CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_FILE_OPEN_ERROR);
+        return 0;
+    }
+    switch (cmd) {
+    case CAPI_CMD_LIST_CSPS:
+        ret = capi_list_providers(ctx, out);
+        break;
+
+    case CAPI_CMD_LIST_CERTS:
+        ret = capi_list_certs(ctx, out, NULL);
+        break;
+
+    case CAPI_CMD_LOOKUP_CERT:
+        ret = capi_list_certs(ctx, out, p);
+        break;
+
+    case CAPI_CMD_LIST_CONTAINERS:
+        ret = capi_list_containers(ctx, out);
+        break;
+
+    case CAPI_CMD_STORE_NAME:
+        tmpstr = OPENSSL_strdup(p);
+        if (tmpstr != NULL) {
+            OPENSSL_free(ctx->storename);
+            ctx->storename = tmpstr;
+            CAPI_trace(ctx, "Setting store name to %s\n", p);
+        } else {
+            CAPIerr(CAPI_F_CAPI_CTRL, ERR_R_MALLOC_FAILURE);
+            ret = 0;
+        }
+        break;
+
+    case CAPI_CMD_STORE_FLAGS:
+        if (i & 1) {
+            ctx->store_flags |= CERT_SYSTEM_STORE_LOCAL_MACHINE;
+            ctx->store_flags &= ~CERT_SYSTEM_STORE_CURRENT_USER;
+        } else {
+            ctx->store_flags |= CERT_SYSTEM_STORE_CURRENT_USER;
+            ctx->store_flags &= ~CERT_SYSTEM_STORE_LOCAL_MACHINE;
+        }
+        CAPI_trace(ctx, "Setting flags to %d\n", i);
+        break;
+
+    case CAPI_CMD_DEBUG_LEVEL:
+        ctx->debug_level = (int)i;
+        CAPI_trace(ctx, "Setting debug level to %d\n", ctx->debug_level);
+        break;
+
+    case CAPI_CMD_DEBUG_FILE:
+        tmpstr = OPENSSL_strdup(p);
+        if (tmpstr != NULL) {
+            ctx->debug_file = tmpstr;
+            CAPI_trace(ctx, "Setting debug file to %s\n", ctx->debug_file);
+        } else {
+            CAPIerr(CAPI_F_CAPI_CTRL, ERR_R_MALLOC_FAILURE);
+            ret = 0;
+        }
+        break;
+
+    case CAPI_CMD_KEYTYPE:
+        ctx->keytype = i;
+        CAPI_trace(ctx, "Setting key type to %d\n", ctx->keytype);
+        break;
+
+    case CAPI_CMD_SET_CSP_IDX:
+        ret = capi_ctx_set_provname_idx(ctx, i);
+        break;
+
+    case CAPI_CMD_LIST_OPTIONS:
+        ctx->dump_flags = i;
+        break;
+
+    case CAPI_CMD_LOOKUP_METHOD:
+        if (i < 1 || i > 3) {
+            CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_INVALID_LOOKUP_METHOD);
+            BIO_free(out);
+            return 0;
+        }
+        ctx->lookup_method = i;
+        break;
+
+    case CAPI_CMD_SET_CSP_NAME:
+        ret = capi_ctx_set_provname(ctx, p, ctx->csptype, 1);
+        break;
+
+    case CAPI_CMD_SET_CSP_TYPE:
+        ctx->csptype = i;
+        break;
+
+    default:
+        CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_UNKNOWN_COMMAND);
+        ret = 0;
+    }
+
+    BIO_free(out);
+    return ret;
+
+}
+
+static RSA_METHOD *capi_rsa_method = NULL;
+# ifndef OPENSSL_NO_DSA
+static DSA_METHOD *capi_dsa_method = NULL;
+# endif
+
+static int use_aes_csp = 0;
+
+static int capi_init(ENGINE *e)
+{
+    CAPI_CTX *ctx;
+    const RSA_METHOD *ossl_rsa_meth;
+# ifndef OPENSSL_NO_DSA
+    const DSA_METHOD *ossl_dsa_meth;
+# endif
+    HCRYPTPROV hprov;
+
+    if (capi_idx < 0) {
+        capi_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 0);
+        if (capi_idx < 0)
+            goto memerr;
+
+        cert_capi_idx = X509_get_ex_new_index(0, NULL, NULL, NULL, 0);
+
+        /* Setup RSA_METHOD */
+        rsa_capi_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
+        ossl_rsa_meth = RSA_PKCS1_OpenSSL();
+        if (   !RSA_meth_set_pub_enc(capi_rsa_method,
+                                     RSA_meth_get_pub_enc(ossl_rsa_meth))
+            || !RSA_meth_set_pub_dec(capi_rsa_method,
+                                     RSA_meth_get_pub_dec(ossl_rsa_meth))
+            || !RSA_meth_set_priv_enc(capi_rsa_method, capi_rsa_priv_enc)
+            || !RSA_meth_set_priv_dec(capi_rsa_method, capi_rsa_priv_dec)
+            || !RSA_meth_set_mod_exp(capi_rsa_method,
+                                     RSA_meth_get_mod_exp(ossl_rsa_meth))
+            || !RSA_meth_set_bn_mod_exp(capi_rsa_method,
+                                        RSA_meth_get_bn_mod_exp(ossl_rsa_meth))
+            || !RSA_meth_set_finish(capi_rsa_method, capi_rsa_free)
+            || !RSA_meth_set_sign(capi_rsa_method, capi_rsa_sign)) {
+            goto memerr;
+        }
+
+# ifndef OPENSSL_NO_DSA
+        /* Setup DSA Method */
+        dsa_capi_idx = DSA_get_ex_new_index(0, NULL, NULL, NULL, 0);
+        ossl_dsa_meth = DSA_OpenSSL();
+        if (   !DSA_meth_set_sign(capi_dsa_method, capi_dsa_do_sign)
+            || !DSA_meth_set_verify(capi_dsa_method,
+                                    DSA_meth_get_verify(ossl_dsa_meth))
+            || !DSA_meth_set_finish(capi_dsa_method, capi_dsa_free)
+            || !DSA_meth_set_mod_exp(capi_dsa_method,
+                                     DSA_meth_get_mod_exp(ossl_dsa_meth))
+            || !DSA_meth_set_bn_mod_exp(capi_dsa_method,
+                                    DSA_meth_get_bn_mod_exp(ossl_dsa_meth))) {
+            goto memerr;
+        }
+# endif
+    }
+
+    ctx = capi_ctx_new();
+    if (ctx == NULL)
+        goto memerr;
+
+    ENGINE_set_ex_data(e, capi_idx, ctx);
+
+# ifdef OPENSSL_CAPIENG_DIALOG
+    {
+        HMODULE cryptui = LoadLibrary(TEXT("CRYPTUI.DLL"));
+        HMODULE kernel = GetModuleHandle(TEXT("KERNEL32.DLL"));
+        if (cryptui)
+            ctx->certselectdlg =
+                (CERTDLG) GetProcAddress(cryptui,
+                                         "CryptUIDlgSelectCertificateFromStore");
+        if (kernel)
+            ctx->getconswindow =
+                (GETCONSWIN) GetProcAddress(kernel, "GetConsoleWindow");
+        if (cryptui && !OPENSSL_isservice())
+            ctx->client_cert_select = cert_select_dialog;
+    }
+# endif
+
+    /* See if we support AES CSP */
+
+    if (CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_AES,
+                            CRYPT_VERIFYCONTEXT)) {
+        use_aes_csp = 1;
+        CryptReleaseContext(hprov, 0);
+    }
+
+    return 1;
+
+ memerr:
+    CAPIerr(CAPI_F_CAPI_INIT, ERR_R_MALLOC_FAILURE);
+    return 0;
+
+    return 1;
+}
+
+static int capi_destroy(ENGINE *e)
+{
+    RSA_meth_free(capi_rsa_method);
+    capi_rsa_method = NULL;
+# ifndef OPENSSL_NO_DSA
+    DSA_meth_free(capi_dsa_method);
+    capi_dsa_method = NULL;
+# endif
+    ERR_unload_CAPI_strings();
+    return 1;
+}
+
+static int capi_finish(ENGINE *e)
+{
+    CAPI_CTX *ctx;
+    ctx = ENGINE_get_ex_data(e, capi_idx);
+    capi_ctx_free(ctx);
+    ENGINE_set_ex_data(e, capi_idx, NULL);
+    return 1;
+}
+
+/*
+ * CryptoAPI key application data. This contains a handle to the private key
+ * container (for sign operations) and a handle to the key (for decrypt
+ * operations).
+ */
+
+struct CAPI_KEY_st {
+    /* Associated certificate context (if any) */
+    PCCERT_CONTEXT pcert;
+    HCRYPTPROV hprov;
+    HCRYPTKEY key;
+    DWORD keyspec;
+};
+
+static int bind_capi(ENGINE *e)
+{
+    capi_rsa_method = RSA_meth_new("CryptoAPI RSA method", 0);
+    if (capi_rsa_method == NULL)
+        return 0;
+# ifndef OPENSSL_NO_DSA
+    capi_dsa_method = DSA_meth_new("CryptoAPI DSA method", 0);
+    if (capi_dsa_method == NULL)
+        goto memerr;
+# endif
+    if (!ENGINE_set_id(e, engine_capi_id)
+        || !ENGINE_set_name(e, engine_capi_name)
+        || !ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL)
+        || !ENGINE_set_init_function(e, capi_init)
+        || !ENGINE_set_finish_function(e, capi_finish)
+        || !ENGINE_set_destroy_function(e, capi_destroy)
+        || !ENGINE_set_RSA(e, capi_rsa_method)
+# ifndef OPENSSL_NO_DSA
+        || !ENGINE_set_DSA(e, capi_dsa_method)
+# endif
+        || !ENGINE_set_load_privkey_function(e, capi_load_privkey)
+        || !ENGINE_set_load_ssl_client_cert_function(e,
+                                                     capi_load_ssl_client_cert)
+        || !ENGINE_set_cmd_defns(e, capi_cmd_defns)
+        || !ENGINE_set_ctrl_function(e, capi_ctrl))
+        goto memerr;
+    ERR_load_CAPI_strings();
+
+    return 1;
+ memerr:
+    RSA_meth_free(capi_rsa_method);
+    capi_rsa_method = NULL;
+# ifndef OPENSSL_NO_DSA
+    DSA_meth_free(capi_dsa_method);
+    capi_dsa_method = NULL;
+# endif
+    return 0;
+}
+
+# ifndef OPENSSL_NO_DYNAMIC_ENGINE
+static int bind_helper(ENGINE *e, const char *id)
+{
+    if (id && (strcmp(id, engine_capi_id) != 0))
+        return 0;
+    if (!bind_capi(e))
+        return 0;
+    return 1;
+}
+
+IMPLEMENT_DYNAMIC_CHECK_FN()
+    IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
+# else
+static ENGINE *engine_capi(void)
+{
+    ENGINE *ret = ENGINE_new();
+    if (ret == NULL)
+        return NULL;
+    if (!bind_capi(ret)) {
+        ENGINE_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+void engine_load_capi_int(void)
+{
+    /* Copied from eng_[openssl|dyn].c */
+    ENGINE *toadd = engine_capi();
+    if (!toadd)
+        return;
+    ENGINE_add(toadd);
+    ENGINE_free(toadd);
+    ERR_clear_error();
+}
+# endif
+
+static int lend_tobn(BIGNUM *bn, unsigned char *bin, int binlen)
+{
+    int i;
+    /*
+     * Reverse buffer in place: since this is a keyblob structure that will
+     * be freed up after conversion anyway it doesn't matter if we change
+     * it.
+     */
+    for (i = 0; i < binlen / 2; i++) {
+        unsigned char c;
+        c = bin[i];
+        bin[i] = bin[binlen - i - 1];
+        bin[binlen - i - 1] = c;
+    }
+
+    if (!BN_bin2bn(bin, binlen, bn))
+        return 0;
+    return 1;
+}
+
+/* Given a CAPI_KEY get an EVP_PKEY structure */
+
+static EVP_PKEY *capi_get_pkey(ENGINE *eng, CAPI_KEY * key)
+{
+    unsigned char *pubkey = NULL;
+    DWORD len;
+    BLOBHEADER *bh;
+    RSA *rkey = NULL;
+    DSA *dkey = NULL;
+    EVP_PKEY *ret = NULL;
+    if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, NULL, &len)) {
+        CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR);
+        capi_addlasterror();
+        return NULL;
+    }
+
+    pubkey = OPENSSL_malloc(len);
+
+    if (pubkey == NULL)
+        goto memerr;
+
+    if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, pubkey, &len)) {
+        CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_ERROR);
+        capi_addlasterror();
+        goto err;
+    }
+
+    bh = (BLOBHEADER *) pubkey;
+    if (bh->bType != PUBLICKEYBLOB) {
+        CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_PUBLIC_KEY_BLOB);
+        goto err;
+    }
+    if (bh->aiKeyAlg == CALG_RSA_SIGN || bh->aiKeyAlg == CALG_RSA_KEYX) {
+        RSAPUBKEY *rp;
+        DWORD rsa_modlen;
+        BIGNUM *e = NULL, *n = NULL;
+        unsigned char *rsa_modulus;
+        rp = (RSAPUBKEY *) (bh + 1);
+        if (rp->magic != 0x31415352) {
+            char magstr[10];
+            BIO_snprintf(magstr, 10, "%lx", rp->magic);
+            CAPIerr(CAPI_F_CAPI_GET_PKEY,
+                    CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER);
+            ERR_add_error_data(2, "magic=0x", magstr);
+            goto err;
+        }
+        rsa_modulus = (unsigned char *)(rp + 1);
+        rkey = RSA_new_method(eng);
+        if (!rkey)
+            goto memerr;
+
+        e = BN_new();
+        n = BN_new();
+
+        if (e == NULL || n == NULL) {
+            BN_free(e);
+            BN_free(n);
+            goto memerr;
+        }
+
+        RSA_set0_key(rkey, n, e, NULL);
+
+        if (!BN_set_word(e, rp->pubexp))
+            goto memerr;
+
+        rsa_modlen = rp->bitlen / 8;
+        if (!lend_tobn(n, rsa_modulus, rsa_modlen))
+            goto memerr;
+
+        RSA_set_ex_data(rkey, rsa_capi_idx, key);
+
+        if ((ret = EVP_PKEY_new()) == NULL)
+            goto memerr;
+
+        EVP_PKEY_assign_RSA(ret, rkey);
+        rkey = NULL;
+
+# ifndef OPENSSL_NO_DSA
+    } else if (bh->aiKeyAlg == CALG_DSS_SIGN) {
+        DSSPUBKEY *dp;
+        DWORD dsa_plen;
+        unsigned char *btmp;
+        BIGNUM *p, *q, *g, *pub_key;
+        dp = (DSSPUBKEY *) (bh + 1);
+        if (dp->magic != 0x31535344) {
+            char magstr[10];
+            BIO_snprintf(magstr, 10, "%lx", dp->magic);
+            CAPIerr(CAPI_F_CAPI_GET_PKEY,
+                    CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER);
+            ERR_add_error_data(2, "magic=0x", magstr);
+            goto err;
+        }
+        dsa_plen = dp->bitlen / 8;
+        btmp = (unsigned char *)(dp + 1);
+        dkey = DSA_new_method(eng);
+        if (!dkey)
+            goto memerr;
+        p = BN_new();
+        q = BN_new();
+        g = BN_new();
+        pub_key = BN_new();
+        if (p == NULL || q == NULL || g == NULL || pub_key == NULL) {
+            BN_free(p);
+            BN_free(q);
+            BN_free(g);
+            BN_free(pub_key);
+            goto memerr;
+        }
+        DSA_set0_pqg(dkey, p, q, g);
+        DSA_set0_key(dkey, pub_key, NULL);
+        if (!lend_tobn(p, btmp, dsa_plen))
+            goto memerr;
+        btmp += dsa_plen;
+        if (!lend_tobn(q, btmp, 20))
+            goto memerr;
+        btmp += 20;
+        if (!lend_tobn(g, btmp, dsa_plen))
+            goto memerr;
+        btmp += dsa_plen;
+        if (!lend_tobn(pub_key, btmp, dsa_plen))
+            goto memerr;
+        btmp += dsa_plen;
+
+        DSA_set_ex_data(dkey, dsa_capi_idx, key);
+
+        if ((ret = EVP_PKEY_new()) == NULL)
+            goto memerr;
+
+        EVP_PKEY_assign_DSA(ret, dkey);
+        dkey = NULL;
+# endif
+    } else {
+        char algstr[10];
+        BIO_snprintf(algstr, 10, "%ux", bh->aiKeyAlg);
+        CAPIerr(CAPI_F_CAPI_GET_PKEY,
+                CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM);
+        ERR_add_error_data(2, "aiKeyAlg=0x", algstr);
+        goto err;
+    }
+
+ err:
+    OPENSSL_free(pubkey);
+    if (!ret) {
+        RSA_free(rkey);
+# ifndef OPENSSL_NO_DSA
+        DSA_free(dkey);
+# endif
+    }
+
+    return ret;
+
+ memerr:
+    CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_MALLOC_FAILURE);
+    goto err;
+
+}
+
+static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id,
+                                   UI_METHOD *ui_method, void *callback_data)
+{
+    CAPI_CTX *ctx;
+    CAPI_KEY *key;
+    EVP_PKEY *ret;
+    ctx = ENGINE_get_ex_data(eng, capi_idx);
+
+    if (!ctx) {
+        CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_CANT_FIND_CAPI_CONTEXT);
+        return NULL;
+    }
+
+    key = capi_find_key(ctx, key_id);
+
+    if (!key)
+        return NULL;
+
+    ret = capi_get_pkey(eng, key);
+
+    if (!ret)
+        capi_free_key(key);
+    return ret;
+
+}
+
+/* CryptoAPI RSA operations */
+
+int capi_rsa_priv_enc(int flen, const unsigned char *from,
+                      unsigned char *to, RSA *rsa, int padding)
+{
+    CAPIerr(CAPI_F_CAPI_RSA_PRIV_ENC, CAPI_R_FUNCTION_NOT_SUPPORTED);
+    return -1;
+}
+
+int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len,
+                  unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
+{
+    ALG_ID alg;
+    HCRYPTHASH hash;
+    DWORD slen;
+    unsigned int i;
+    int ret = -1;
+    CAPI_KEY *capi_key;
+    CAPI_CTX *ctx;
+
+    ctx = ENGINE_get_ex_data(RSA_get0_engine(rsa), capi_idx);
+
+    CAPI_trace(ctx, "Called CAPI_rsa_sign()\n");
+
+    capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
+    if (!capi_key) {
+        CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_GET_KEY);
+        return -1;
+    }
+/* Convert the signature type to a CryptoAPI algorithm ID */
+    switch (dtype) {
+    case NID_sha256:
+        alg = CALG_SHA_256;
+        break;
+
+    case NID_sha384:
+        alg = CALG_SHA_384;
+        break;
+
+    case NID_sha512:
+        alg = CALG_SHA_512;
+        break;
+
+    case NID_sha1:
+        alg = CALG_SHA1;
+        break;
+
+    case NID_md5:
+        alg = CALG_MD5;
+        break;
+
+    case NID_md5_sha1:
+        alg = CALG_SSL3_SHAMD5;
+        break;
+    default:
+        {
+            char algstr[10];
+            BIO_snprintf(algstr, 10, "%x", dtype);
+            CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_UNSUPPORTED_ALGORITHM_NID);
+            ERR_add_error_data(2, "NID=0x", algstr);
+            return -1;
+        }
+    }
+
+/* Create the hash object */
+    if (!CryptCreateHash(capi_key->hprov, alg, 0, 0, &hash)) {
+        CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT);
+        capi_addlasterror();
+        return -1;
+    }
+/* Set the hash value to the value passed */
+
+    if (!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)m, 0)) {
+        CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_SET_HASH_VALUE);
+        capi_addlasterror();
+        goto err;
+    }
+
+/* Finally sign it */
+    slen = RSA_size(rsa);
+    if (!CryptSignHash(hash, capi_key->keyspec, NULL, 0, sigret, &slen)) {
+        CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_ERROR_SIGNING_HASH);
+        capi_addlasterror();
+        goto err;
+    } else {
+        ret = 1;
+        /* Inplace byte reversal of signature */
+        for (i = 0; i < slen / 2; i++) {
+            unsigned char c;
+            c = sigret[i];
+            sigret[i] = sigret[slen - i - 1];
+            sigret[slen - i - 1] = c;
+        }
+        *siglen = slen;
+    }
+
+    /* Now cleanup */
+
+ err:
+    CryptDestroyHash(hash);
+
+    return ret;
+}
+
+int capi_rsa_priv_dec(int flen, const unsigned char *from,
+                      unsigned char *to, RSA *rsa, int padding)
+{
+    int i;
+    unsigned char *tmpbuf;
+    CAPI_KEY *capi_key;
+    CAPI_CTX *ctx;
+    DWORD dlen;
+
+    if (flen <= 0)
+        return flen;
+
+    ctx = ENGINE_get_ex_data(RSA_get0_engine(rsa), capi_idx);
+
+    CAPI_trace(ctx, "Called capi_rsa_priv_dec()\n");
+
+    capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
+    if (!capi_key) {
+        CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_CANT_GET_KEY);
+        return -1;
+    }
+
+    if (padding != RSA_PKCS1_PADDING) {
+        char errstr[10];
+        BIO_snprintf(errstr, 10, "%d", padding);
+        CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_UNSUPPORTED_PADDING);
+        ERR_add_error_data(2, "padding=", errstr);
+        return -1;
+    }
+
+    /* Create temp reverse order version of input */
+    if ((tmpbuf = OPENSSL_malloc(flen)) == NULL) {
+        CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+    for (i = 0; i < flen; i++)
+        tmpbuf[flen - i - 1] = from[i];
+
+    /* Finally decrypt it */
+    dlen = flen;
+    if (!CryptDecrypt(capi_key->key, 0, TRUE, 0, tmpbuf, &dlen)) {
+        CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_DECRYPT_ERROR);
+        capi_addlasterror();
+        OPENSSL_free(tmpbuf);
+        return -1;
+    } else
+        memcpy(to, tmpbuf, (flen = (int)dlen));
+
+    OPENSSL_free(tmpbuf);
+
+    return flen;
+}
+
+static int capi_rsa_free(RSA *rsa)
+{
+    CAPI_KEY *capi_key;
+    capi_key = RSA_get_ex_data(rsa, rsa_capi_idx);
+    capi_free_key(capi_key);
+    RSA_set_ex_data(rsa, rsa_capi_idx, 0);
+    return 1;
+}
+
+# ifndef OPENSSL_NO_DSA
+/* CryptoAPI DSA operations */
+
+static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen,
+                                 DSA *dsa)
+{
+    HCRYPTHASH hash;
+    DWORD slen;
+    DSA_SIG *ret = NULL;
+    CAPI_KEY *capi_key;
+    CAPI_CTX *ctx;
+    unsigned char csigbuf[40];
+
+    ctx = ENGINE_get_ex_data(DSA_get0_engine(dsa), capi_idx);
+
+    CAPI_trace(ctx, "Called CAPI_dsa_do_sign()\n");
+
+    capi_key = DSA_get_ex_data(dsa, dsa_capi_idx);
+
+    if (!capi_key) {
+        CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_GET_KEY);
+        return NULL;
+    }
+
+    if (dlen != 20) {
+        CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_INVALID_DIGEST_LENGTH);
+        return NULL;
+    }
+
+    /* Create the hash object */
+    if (!CryptCreateHash(capi_key->hprov, CALG_SHA1, 0, 0, &hash)) {
+        CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT);
+        capi_addlasterror();
+        return NULL;
+    }
+
+    /* Set the hash value to the value passed */
+    if (!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)digest, 0)) {
+        CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_SET_HASH_VALUE);
+        capi_addlasterror();
+        goto err;
+    }
+
+    /* Finally sign it */
+    slen = sizeof(csigbuf);
+    if (!CryptSignHash(hash, capi_key->keyspec, NULL, 0, csigbuf, &slen)) {
+        CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_ERROR_SIGNING_HASH);
+        capi_addlasterror();
+        goto err;
+    } else {
+        BIGNUM *r = BN_new(), *s = BN_new();
+
+        if (r == NULL || s == NULL
+            || !lend_tobn(r, csigbuf, 20)
+            || !lend_tobn(s, csigbuf + 20, 20)
+            || (ret = DSA_SIG_new()) == NULL) {
+            BN_free(r); /* BN_free checks for BIGNUM * being NULL */
+            BN_free(s);
+            goto err;
+        }
+        DSA_SIG_set0(ret, r, s);
+    }
+
+    /* Now cleanup */
+
+ err:
+    OPENSSL_cleanse(csigbuf, 40);
+    CryptDestroyHash(hash);
+    return ret;
+}
+
+static int capi_dsa_free(DSA *dsa)
+{
+    CAPI_KEY *capi_key;
+    capi_key = DSA_get_ex_data(dsa, dsa_capi_idx);
+    capi_free_key(capi_key);
+    DSA_set_ex_data(dsa, dsa_capi_idx, 0);
+    return 1;
+}
+# endif
+
+static void capi_vtrace(CAPI_CTX * ctx, int level, char *format,
+                        va_list argptr)
+{
+    BIO *out;
+
+    if (!ctx || (ctx->debug_level < level) || (!ctx->debug_file))
+        return;
+    out = BIO_new_file(ctx->debug_file, "a+");
+    if (out == NULL) {
+        CAPIerr(CAPI_F_CAPI_VTRACE, CAPI_R_FILE_OPEN_ERROR);
+        return;
+    }
+    BIO_vprintf(out, format, argptr);
+    BIO_free(out);
+}
+
+static void CAPI_trace(CAPI_CTX * ctx, char *format, ...)
+{
+    va_list args;
+    va_start(args, format);
+    capi_vtrace(ctx, CAPI_DBG_TRACE, format, args);
+    va_end(args);
+}
+
+static void capi_addlasterror(void)
+{
+    capi_adderror(GetLastError());
+}
+
+static void capi_adderror(DWORD err)
+{
+    char errstr[10];
+    BIO_snprintf(errstr, 10, "%lX", err);
+    ERR_add_error_data(2, "Error code= 0x", errstr);
+}
+
+static char *wide_to_asc(LPCWSTR wstr)
+{
+    char *str;
+    int len_0, sz;
+
+    if (!wstr)
+        return NULL;
+    len_0 = (int)wcslen(wstr) + 1; /* WideCharToMultiByte expects int */
+    sz = WideCharToMultiByte(CP_ACP, 0, wstr, len_0, NULL, 0, NULL, NULL);
+    if (!sz) {
+        CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR);
+        return NULL;
+    }
+    str = OPENSSL_malloc(sz);
+    if (str == NULL) {
+        CAPIerr(CAPI_F_WIDE_TO_ASC, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    if (!WideCharToMultiByte(CP_ACP, 0, wstr, len_0, str, sz, NULL, NULL)) {
+        OPENSSL_free(str);
+        CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR);
+        return NULL;
+    }
+    return str;
+}
+
+static int capi_get_provname(CAPI_CTX * ctx, LPSTR * pname, DWORD * ptype,
+                             DWORD idx)
+{
+    DWORD len, err;
+    LPTSTR name;
+    CAPI_trace(ctx, "capi_get_provname, index=%d\n", idx);
+    if (!CryptEnumProviders(idx, NULL, 0, ptype, NULL, &len)) {
+        err = GetLastError();
+        if (err == ERROR_NO_MORE_ITEMS)
+            return 2;
+        CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR);
+        capi_adderror(err);
+        return 0;
+    }
+    name = OPENSSL_malloc(len);
+    if (name == NULL) {
+        CAPIerr(CAPI_F_CAPI_GET_PROVNAME, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    if (!CryptEnumProviders(idx, NULL, 0, ptype, name, &len)) {
+        err = GetLastError();
+        OPENSSL_free(name);
+        if (err == ERROR_NO_MORE_ITEMS)
+            return 2;
+        CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR);
+        capi_adderror(err);
+        return 0;
+    }
+    if (sizeof(TCHAR) != sizeof(char)) {
+        *pname = wide_to_asc((WCHAR *)name);
+        OPENSSL_free(name);
+        if (*pname == NULL)
+            return 0;
+    } else
+        *pname = (char *)name;
+    CAPI_trace(ctx, "capi_get_provname, returned name=%s, type=%d\n", *pname,
+               *ptype);
+
+    return 1;
+}
+
+static int capi_list_providers(CAPI_CTX * ctx, BIO *out)
+{
+    DWORD idx, ptype;
+    int ret;
+    LPSTR provname = NULL;
+    CAPI_trace(ctx, "capi_list_providers\n");
+    BIO_printf(out, "Available CSPs:\n");
+    for (idx = 0;; idx++) {
+        ret = capi_get_provname(ctx, &provname, &ptype, idx);
+        if (ret == 2)
+            break;
+        if (ret == 0)
+            break;
+        BIO_printf(out, "%lu. %s, type %lu\n", idx, provname, ptype);
+        OPENSSL_free(provname);
+    }
+    return 1;
+}
+
+static int capi_list_containers(CAPI_CTX * ctx, BIO *out)
+{
+    int ret = 1;
+    HCRYPTPROV hprov;
+    DWORD err, idx, flags, buflen = 0, clen;
+    LPSTR cname;
+    LPTSTR cspname = NULL;
+
+    CAPI_trace(ctx, "Listing containers CSP=%s, type = %d\n", ctx->cspname,
+               ctx->csptype);
+    if (ctx->cspname && sizeof(TCHAR) != sizeof(char)) {
+        if ((clen =
+             MultiByteToWideChar(CP_ACP, 0, ctx->cspname, -1, NULL, 0))) {
+            cspname = alloca(clen * sizeof(WCHAR));
+            MultiByteToWideChar(CP_ACP, 0, ctx->cspname, -1, (WCHAR *)cspname,
+                                clen);
+        }
+        if (!cspname) {
+            CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, ERR_R_MALLOC_FAILURE);
+            capi_addlasterror();
+            return 0;
+        }
+    } else
+        cspname = (TCHAR *)ctx->cspname;
+    if (!CryptAcquireContext
+        (&hprov, NULL, cspname, ctx->csptype, CRYPT_VERIFYCONTEXT)) {
+        CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS,
+                CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
+        capi_addlasterror();
+        return 0;
+    }
+    if (!CryptGetProvParam
+        (hprov, PP_ENUMCONTAINERS, NULL, &buflen, CRYPT_FIRST)) {
+        CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR);
+        capi_addlasterror();
+        CryptReleaseContext(hprov, 0);
+        return 0;
+    }
+    CAPI_trace(ctx, "Got max container len %d\n", buflen);
+    if (buflen == 0)
+        buflen = 1024;
+    cname = OPENSSL_malloc(buflen);
+    if (cname == NULL) {
+        CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    for (idx = 0;; idx++) {
+        clen = buflen;
+        cname[0] = 0;
+
+        if (idx == 0)
+            flags = CRYPT_FIRST;
+        else
+            flags = 0;
+        if (!CryptGetProvParam
+            (hprov, PP_ENUMCONTAINERS, (BYTE *) cname, &clen, flags)) {
+            err = GetLastError();
+            if (err == ERROR_NO_MORE_ITEMS)
+                goto done;
+            CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR);
+            capi_adderror(err);
+            goto err;
+        }
+        CAPI_trace(ctx, "Container name %s, len=%d, index=%d, flags=%d\n",
+                   cname, clen, idx, flags);
+        if (!cname[0] && (clen == buflen)) {
+            CAPI_trace(ctx, "Enumerate bug: using workaround\n");
+            goto done;
+        }
+        BIO_printf(out, "%lu. %s\n", idx, cname);
+    }
+ err:
+
+    ret = 0;
+
+ done:
+    OPENSSL_free(cname);
+    CryptReleaseContext(hprov, 0);
+
+    return ret;
+}
+
+static CRYPT_KEY_PROV_INFO *capi_get_prov_info(CAPI_CTX * ctx, PCCERT_CONTEXT cert)
+{
+    DWORD len;
+    CRYPT_KEY_PROV_INFO *pinfo;
+
+    if (!CertGetCertificateContextProperty
+        (cert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &len))
+        return NULL;
+    pinfo = OPENSSL_malloc(len);
+    if (pinfo == NULL) {
+        CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    if (!CertGetCertificateContextProperty
+        (cert, CERT_KEY_PROV_INFO_PROP_ID, pinfo, &len)) {
+        CAPIerr(CAPI_F_CAPI_GET_PROV_INFO,
+                CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO);
+        capi_addlasterror();
+        OPENSSL_free(pinfo);
+        return NULL;
+    }
+    return pinfo;
+}
+
+static void capi_dump_prov_info(CAPI_CTX * ctx, BIO *out,
+                                CRYPT_KEY_PROV_INFO * pinfo)
+{
+    char *provname = NULL, *contname = NULL;
+    if (!pinfo) {
+        BIO_printf(out, "  No Private Key\n");
+        return;
+    }
+    provname = wide_to_asc(pinfo->pwszProvName);
+    contname = wide_to_asc(pinfo->pwszContainerName);
+    if (!provname || !contname)
+        goto err;
+
+    BIO_printf(out, "  Private Key Info:\n");
+    BIO_printf(out, "    Provider Name:  %s, Provider Type %lu\n", provname,
+               pinfo->dwProvType);
+    BIO_printf(out, "    Container Name: %s, Key Type %lu\n", contname,
+               pinfo->dwKeySpec);
+ err:
+    OPENSSL_free(provname);
+    OPENSSL_free(contname);
+}
+
+static char *capi_cert_get_fname(CAPI_CTX * ctx, PCCERT_CONTEXT cert)
+{
+    LPWSTR wfname;
+    DWORD dlen;
+
+    CAPI_trace(ctx, "capi_cert_get_fname\n");
+    if (!CertGetCertificateContextProperty
+        (cert, CERT_FRIENDLY_NAME_PROP_ID, NULL, &dlen))
+        return NULL;
+    wfname = OPENSSL_malloc(dlen);
+    if (wfname == NULL)
+        return NULL;
+    if (CertGetCertificateContextProperty
+        (cert, CERT_FRIENDLY_NAME_PROP_ID, wfname, &dlen)) {
+        char *fname = wide_to_asc(wfname);
+        OPENSSL_free(wfname);
+        return fname;
+    }
+    CAPIerr(CAPI_F_CAPI_CERT_GET_FNAME, CAPI_R_ERROR_GETTING_FRIENDLY_NAME);
+    capi_addlasterror();
+
+    OPENSSL_free(wfname);
+    return NULL;
+}
+
+static void capi_dump_cert(CAPI_CTX * ctx, BIO *out, PCCERT_CONTEXT cert)
+{
+    X509 *x;
+    const unsigned char *p;
+    unsigned long flags = ctx->dump_flags;
+    if (flags & CAPI_DMP_FNAME) {
+        char *fname;
+        fname = capi_cert_get_fname(ctx, cert);
+        if (fname) {
+            BIO_printf(out, "  Friendly Name \"%s\"\n", fname);
+            OPENSSL_free(fname);
+        } else
+            BIO_printf(out, "  <No Friendly Name>\n");
+    }
+
+    p = cert->pbCertEncoded;
+    x = d2i_X509(NULL, &p, cert->cbCertEncoded);
+    if (!x)
+        BIO_printf(out, "  <Can't parse certificate>\n");
+    if (flags & CAPI_DMP_SUMMARY) {
+        BIO_printf(out, "  Subject: ");
+        X509_NAME_print_ex(out, X509_get_subject_name(x), 0, XN_FLAG_ONELINE);
+        BIO_printf(out, "\n  Issuer: ");
+        X509_NAME_print_ex(out, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE);
+        BIO_printf(out, "\n");
+    }
+    if (flags & CAPI_DMP_FULL)
+        X509_print_ex(out, x, XN_FLAG_ONELINE, 0);
+
+    if (flags & CAPI_DMP_PKEYINFO) {
+        CRYPT_KEY_PROV_INFO *pinfo;
+        pinfo = capi_get_prov_info(ctx, cert);
+        capi_dump_prov_info(ctx, out, pinfo);
+        OPENSSL_free(pinfo);
+    }
+
+    if (flags & CAPI_DMP_PEM)
+        PEM_write_bio_X509(out, x);
+    X509_free(x);
+}
+
+static HCERTSTORE capi_open_store(CAPI_CTX * ctx, char *storename)
+{
+    HCERTSTORE hstore;
+
+    if (!storename)
+        storename = ctx->storename;
+    if (!storename)
+        storename = "MY";
+    CAPI_trace(ctx, "Opening certificate store %s\n", storename);
+
+    hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0,
+                           ctx->store_flags, storename);
+    if (!hstore) {
+        CAPIerr(CAPI_F_CAPI_OPEN_STORE, CAPI_R_ERROR_OPENING_STORE);
+        capi_addlasterror();
+    }
+    return hstore;
+}
+
+int capi_list_certs(CAPI_CTX * ctx, BIO *out, char *id)
+{
+    char *storename;
+    int idx;
+    int ret = 1;
+    HCERTSTORE hstore;
+    PCCERT_CONTEXT cert = NULL;
+
+    storename = ctx->storename;
+    if (!storename)
+        storename = "MY";
+    CAPI_trace(ctx, "Listing certs for store %s\n", storename);
+
+    hstore = capi_open_store(ctx, storename);
+    if (!hstore)
+        return 0;
+    if (id) {
+        cert = capi_find_cert(ctx, id, hstore);
+        if (!cert) {
+            ret = 0;
+            goto err;
+        }
+        capi_dump_cert(ctx, out, cert);
+        CertFreeCertificateContext(cert);
+    } else {
+        for (idx = 0;; idx++) {
+            cert = CertEnumCertificatesInStore(hstore, cert);
+            if (!cert)
+                break;
+            BIO_printf(out, "Certificate %d\n", idx);
+            capi_dump_cert(ctx, out, cert);
+        }
+    }
+ err:
+    CertCloseStore(hstore, 0);
+    return ret;
+}
+
+static PCCERT_CONTEXT capi_find_cert(CAPI_CTX * ctx, const char *id,
+                                     HCERTSTORE hstore)
+{
+    PCCERT_CONTEXT cert = NULL;
+    char *fname = NULL;
+    int match;
+    switch (ctx->lookup_method) {
+    case CAPI_LU_SUBSTR:
+        return CertFindCertificateInStore(hstore,
+                                          X509_ASN_ENCODING, 0,
+                                          CERT_FIND_SUBJECT_STR_A, id, NULL);
+    case CAPI_LU_FNAME:
+        for (;;) {
+            cert = CertEnumCertificatesInStore(hstore, cert);
+            if (!cert)
+                return NULL;
+            fname = capi_cert_get_fname(ctx, cert);
+            if (fname) {
+                if (strcmp(fname, id))
+                    match = 0;
+                else
+                    match = 1;
+                OPENSSL_free(fname);
+                if (match)
+                    return cert;
+            }
+        }
+    default:
+        return NULL;
+    }
+}
+
+static CAPI_KEY *capi_get_key(CAPI_CTX * ctx, const TCHAR *contname,
+                              TCHAR *provname, DWORD ptype, DWORD keyspec)
+{
+    DWORD dwFlags = 0;
+    CAPI_KEY *key = OPENSSL_malloc(sizeof(*key));
+
+    if (key == NULL)
+        return NULL;
+    /* If PROV_RSA_AES supported use it instead */
+    if (ptype == PROV_RSA_FULL && use_aes_csp) {
+        provname = NULL;
+        ptype = PROV_RSA_AES;
+        CAPI_trace(ctx, "capi_get_key, contname=%s, RSA_AES_CSP\n", contname);
+    } else if (sizeof(TCHAR) == sizeof(char)) {
+        CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n",
+                   contname, provname, ptype);
+    } else if (ctx && ctx->debug_level >= CAPI_DBG_TRACE && ctx->debug_file) {
+        /* above 'if' is optimization to minimize malloc-ations */
+        char *_contname = wide_to_asc((WCHAR *)contname);
+        char *_provname = wide_to_asc((WCHAR *)provname);
+
+        CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n",
+                   _contname, _provname, ptype);
+        OPENSSL_free(_provname);
+        OPENSSL_free(_contname);
+    }
+    if (ctx->store_flags & CERT_SYSTEM_STORE_LOCAL_MACHINE)
+        dwFlags = CRYPT_MACHINE_KEYSET;
+    if (!CryptAcquireContext(&key->hprov, contname, provname, ptype, dwFlags)) {
+        CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
+        capi_addlasterror();
+        goto err;
+    }
+    if (!CryptGetUserKey(key->hprov, keyspec, &key->key)) {
+        CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_GETUSERKEY_ERROR);
+        capi_addlasterror();
+        CryptReleaseContext(key->hprov, 0);
+        goto err;
+    }
+    key->keyspec = keyspec;
+    key->pcert = NULL;
+    return key;
+
+ err:
+    OPENSSL_free(key);
+    return NULL;
+}
+
+static CAPI_KEY *capi_get_cert_key(CAPI_CTX * ctx, PCCERT_CONTEXT cert)
+{
+    CAPI_KEY *key = NULL;
+    CRYPT_KEY_PROV_INFO *pinfo = NULL;
+    char *provname = NULL, *contname = NULL;
+    pinfo = capi_get_prov_info(ctx, cert);
+    if (!pinfo)
+        goto err;
+    if (sizeof(TCHAR) != sizeof(char))
+        key = capi_get_key(ctx, (TCHAR *)pinfo->pwszContainerName,
+                           (TCHAR *)pinfo->pwszProvName,
+                           pinfo->dwProvType, pinfo->dwKeySpec);
+    else {
+        provname = wide_to_asc(pinfo->pwszProvName);
+        contname = wide_to_asc(pinfo->pwszContainerName);
+        if (!provname || !contname)
+            goto err;
+        key = capi_get_key(ctx, (TCHAR *)contname, (TCHAR *)provname,
+                           pinfo->dwProvType, pinfo->dwKeySpec);
+    }
+
+ err:
+    OPENSSL_free(pinfo);
+    OPENSSL_free(provname);
+    OPENSSL_free(contname);
+    return key;
+}
+
+CAPI_KEY *capi_find_key(CAPI_CTX * ctx, const char *id)
+{
+    PCCERT_CONTEXT cert;
+    HCERTSTORE hstore;
+    CAPI_KEY *key = NULL;
+    switch (ctx->lookup_method) {
+    case CAPI_LU_SUBSTR:
+    case CAPI_LU_FNAME:
+        hstore = capi_open_store(ctx, NULL);
+        if (!hstore)
+            return NULL;
+        cert = capi_find_cert(ctx, id, hstore);
+        if (cert) {
+            key = capi_get_cert_key(ctx, cert);
+            CertFreeCertificateContext(cert);
+        }
+        CertCloseStore(hstore, 0);
+        break;
+
+    case CAPI_LU_CONTNAME:
+        if (sizeof(TCHAR) != sizeof(char)) {
+            WCHAR *contname, *provname;
+            DWORD len;
+
+            if ((len = MultiByteToWideChar(CP_ACP, 0, id, -1, NULL, 0)) &&
+                (contname = alloca(len * sizeof(WCHAR)),
+                 MultiByteToWideChar(CP_ACP, 0, id, -1, contname, len)) &&
+                (len =
+                 MultiByteToWideChar(CP_ACP, 0, ctx->cspname, -1, NULL, 0))
+                && (provname =
+                    alloca(len * sizeof(WCHAR)), MultiByteToWideChar(CP_ACP,
+                                                                     0,
+                                                                     ctx->cspname,
+                                                                     -1,
+                                                                     provname,
+                                                                     len)))
+                key =
+                    capi_get_key(ctx, (TCHAR *)contname, (TCHAR *)provname,
+                                 ctx->csptype, ctx->keytype);
+        } else
+            key = capi_get_key(ctx, (TCHAR *)id,
+                               (TCHAR *)ctx->cspname,
+                               ctx->csptype, ctx->keytype);
+        break;
+    }
+
+    return key;
+}
+
+void capi_free_key(CAPI_KEY * key)
+{
+    if (!key)
+        return;
+    CryptDestroyKey(key->key);
+    CryptReleaseContext(key->hprov, 0);
+    if (key->pcert)
+        CertFreeCertificateContext(key->pcert);
+    OPENSSL_free(key);
+}
+
+/* Initialize a CAPI_CTX structure */
+
+static CAPI_CTX *capi_ctx_new(void)
+{
+    CAPI_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+    if (ctx == NULL) {
+        CAPIerr(CAPI_F_CAPI_CTX_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    ctx->csptype = PROV_RSA_FULL;
+    ctx->dump_flags = CAPI_DMP_SUMMARY | CAPI_DMP_FNAME;
+    ctx->keytype = AT_KEYEXCHANGE;
+    ctx->store_flags = CERT_STORE_OPEN_EXISTING_FLAG |
+        CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_CURRENT_USER;
+    ctx->lookup_method = CAPI_LU_SUBSTR;
+    ctx->client_cert_select = cert_select_simple;
+    return ctx;
+}
+
+static void capi_ctx_free(CAPI_CTX * ctx)
+{
+    CAPI_trace(ctx, "Calling capi_ctx_free with %lx\n", ctx);
+    if (!ctx)
+        return;
+    OPENSSL_free(ctx->cspname);
+    OPENSSL_free(ctx->debug_file);
+    OPENSSL_free(ctx->storename);
+    OPENSSL_free(ctx->ssl_client_store);
+    OPENSSL_free(ctx);
+}
+
+static int capi_ctx_set_provname(CAPI_CTX * ctx, LPSTR pname, DWORD type,
+                                 int check)
+{
+    LPSTR tmpcspname;
+
+    CAPI_trace(ctx, "capi_ctx_set_provname, name=%s, type=%d\n", pname, type);
+    if (check) {
+        HCRYPTPROV hprov;
+        LPTSTR name = NULL;
+
+        if (sizeof(TCHAR) != sizeof(char)) {
+            DWORD len;
+            if ((len = MultiByteToWideChar(CP_ACP, 0, pname, -1, NULL, 0))) {
+                name = alloca(len * sizeof(WCHAR));
+                MultiByteToWideChar(CP_ACP, 0, pname, -1, (WCHAR *)name, len);
+            }
+        } else
+            name = (TCHAR *)pname;
+
+        if (!name || !CryptAcquireContext(&hprov, NULL, name, type,
+                                          CRYPT_VERIFYCONTEXT)) {
+            CAPIerr(CAPI_F_CAPI_CTX_SET_PROVNAME,
+                    CAPI_R_CRYPTACQUIRECONTEXT_ERROR);
+            capi_addlasterror();
+            return 0;
+        }
+        CryptReleaseContext(hprov, 0);
+    }
+    tmpcspname = OPENSSL_strdup(pname);
+    if (tmpcspname == NULL) {
+        CAPIerr(CAPI_F_CAPI_CTX_SET_PROVNAME, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    OPENSSL_free(ctx->cspname);
+    ctx->cspname = tmpcspname;
+    ctx->csptype = type;
+    return 1;
+}
+
+static int capi_ctx_set_provname_idx(CAPI_CTX * ctx, int idx)
+{
+    LPSTR pname;
+    DWORD type;
+    int res;
+    if (capi_get_provname(ctx, &pname, &type, idx) != 1)
+        return 0;
+    res = capi_ctx_set_provname(ctx, pname, type, 0);
+    OPENSSL_free(pname);
+    return res;
+}
+
+static int cert_issuer_match(STACK_OF(X509_NAME) *ca_dn, X509 *x)
+{
+    int i;
+    X509_NAME *nm;
+    /* Special case: empty list: match anything */
+    if (sk_X509_NAME_num(ca_dn) <= 0)
+        return 1;
+    for (i = 0; i < sk_X509_NAME_num(ca_dn); i++) {
+        nm = sk_X509_NAME_value(ca_dn, i);
+        if (!X509_NAME_cmp(nm, X509_get_issuer_name(x)))
+            return 1;
+    }
+    return 0;
+}
+
+static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl,
+                                     STACK_OF(X509_NAME) *ca_dn, X509 **pcert,
+                                     EVP_PKEY **pkey, STACK_OF(X509) **pother,
+                                     UI_METHOD *ui_method,
+                                     void *callback_data)
+{
+    STACK_OF(X509) *certs = NULL;
+    X509 *x;
+    char *storename;
+    const unsigned char *p;
+    int i, client_cert_idx;
+    HCERTSTORE hstore;
+    PCCERT_CONTEXT cert = NULL, excert = NULL;
+    CAPI_CTX *ctx;
+    CAPI_KEY *key;
+    ctx = ENGINE_get_ex_data(e, capi_idx);
+
+    *pcert = NULL;
+    *pkey = NULL;
+
+    storename = ctx->ssl_client_store;
+    if (!storename)
+        storename = "MY";
+
+    hstore = capi_open_store(ctx, storename);
+    if (!hstore)
+        return 0;
+    /* Enumerate all certificates collect any matches */
+    for (i = 0;; i++) {
+        cert = CertEnumCertificatesInStore(hstore, cert);
+        if (!cert)
+            break;
+        p = cert->pbCertEncoded;
+        x = d2i_X509(NULL, &p, cert->cbCertEncoded);
+        if (!x) {
+            CAPI_trace(ctx, "Can't Parse Certificate %d\n", i);
+            continue;
+        }
+        if (cert_issuer_match(ca_dn, x)
+            && X509_check_purpose(x, X509_PURPOSE_SSL_CLIENT, 0)) {
+            key = capi_get_cert_key(ctx, cert);
+            if (!key) {
+                X509_free(x);
+                continue;
+            }
+            /*
+             * Match found: attach extra data to it so we can retrieve the
+             * key later.
+             */
+            excert = CertDuplicateCertificateContext(cert);
+            key->pcert = excert;
+            X509_set_ex_data(x, cert_capi_idx, key);
+
+            if (!certs)
+                certs = sk_X509_new_null();
+
+            sk_X509_push(certs, x);
+        } else
+            X509_free(x);
+
+    }
+
+    if (cert)
+        CertFreeCertificateContext(cert);
+    if (hstore)
+        CertCloseStore(hstore, 0);
+
+    if (!certs)
+        return 0;
+
+    /* Select the appropriate certificate */
+
+    client_cert_idx = ctx->client_cert_select(e, ssl, certs);
+
+    /* Set the selected certificate and free the rest */
+
+    for (i = 0; i < sk_X509_num(certs); i++) {
+        x = sk_X509_value(certs, i);
+        if (i == client_cert_idx)
+            *pcert = x;
+        else {
+            key = X509_get_ex_data(x, cert_capi_idx);
+            capi_free_key(key);
+            X509_free(x);
+        }
+    }
+
+    sk_X509_free(certs);
+
+    if (!*pcert)
+        return 0;
+
+    /* Setup key for selected certificate */
+
+    key = X509_get_ex_data(*pcert, cert_capi_idx);
+    *pkey = capi_get_pkey(e, key);
+    X509_set_ex_data(*pcert, cert_capi_idx, NULL);
+
+    return 1;
+
+}
+
+/* Simple client cert selection function: always select first */
+
+static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
+{
+    return 0;
+}
+
+# ifdef OPENSSL_CAPIENG_DIALOG
+
+/*
+ * More complex cert selection function, using standard function
+ * CryptUIDlgSelectCertificateFromStore() to produce a dialog box.
+ */
+
+/*
+ * Definitions which are in cryptuiapi.h but this is not present in older
+ * versions of headers.
+ */
+
+#  ifndef CRYPTUI_SELECT_LOCATION_COLUMN
+#   define CRYPTUI_SELECT_LOCATION_COLUMN                   0x000000010
+#   define CRYPTUI_SELECT_INTENDEDUSE_COLUMN                0x000000004
+#  endif
+
+#  define dlg_title L"OpenSSL Application SSL Client Certificate Selection"
+#  define dlg_prompt L"Select a certificate to use for authentication"
+#  define dlg_columns      CRYPTUI_SELECT_LOCATION_COLUMN \
+                        |CRYPTUI_SELECT_INTENDEDUSE_COLUMN
+
+static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs)
+{
+    X509 *x;
+    HCERTSTORE dstore;
+    PCCERT_CONTEXT cert;
+    CAPI_CTX *ctx;
+    CAPI_KEY *key;
+    HWND hwnd;
+    int i, idx = -1;
+    if (sk_X509_num(certs) == 1)
+        return 0;
+    ctx = ENGINE_get_ex_data(e, capi_idx);
+    /* Create an in memory store of certificates */
+    dstore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
+                           CERT_STORE_CREATE_NEW_FLAG, NULL);
+    if (!dstore) {
+        CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_CREATING_STORE);
+        capi_addlasterror();
+        goto err;
+    }
+    /* Add all certificates to store */
+    for (i = 0; i < sk_X509_num(certs); i++) {
+        x = sk_X509_value(certs, i);
+        key = X509_get_ex_data(x, cert_capi_idx);
+
+        if (!CertAddCertificateContextToStore(dstore, key->pcert,
+                                              CERT_STORE_ADD_NEW, NULL)) {
+            CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_ADDING_CERT);
+            capi_addlasterror();
+            goto err;
+        }
+
+    }
+    hwnd = GetForegroundWindow();
+    if (!hwnd)
+        hwnd = GetActiveWindow();
+    if (!hwnd && ctx->getconswindow)
+        hwnd = ctx->getconswindow();
+    /* Call dialog to select one */
+    cert = ctx->certselectdlg(dstore, hwnd, dlg_title, dlg_prompt,
+                              dlg_columns, 0, NULL);
+
+    /* Find matching cert from list */
+    if (cert) {
+        for (i = 0; i < sk_X509_num(certs); i++) {
+            x = sk_X509_value(certs, i);
+            key = X509_get_ex_data(x, cert_capi_idx);
+            if (CertCompareCertificate
+                (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, cert->pCertInfo,
+                 key->pcert->pCertInfo)) {
+                idx = i;
+                break;
+            }
+        }
+    }
+
+ err:
+    if (dstore)
+        CertCloseStore(dstore, 0);
+    return idx;
+
+}
+# endif
+
+#else                           /* !__COMPILE_CAPIENG */
+# include <openssl/engine.h>
+# ifndef OPENSSL_NO_DYNAMIC_ENGINE
+OPENSSL_EXPORT
+    int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns);
+OPENSSL_EXPORT
+    int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns)
+{
+    return 0;
+}
+
+IMPLEMENT_DYNAMIC_CHECK_FN()
+# else
+void engine_load_capi_int(void);
+void engine_load_capi_int(void)
+{
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/engines/e_capi_err.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/engines/e_capi_err.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/engines/e_capi_err.h	(revision 331)
@@ -0,0 +1,88 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*
+ * NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#ifndef HEADER_CAPI_ERR_H
+# define HEADER_CAPI_ERR_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+static void ERR_load_CAPI_strings(void);
+static void ERR_unload_CAPI_strings(void);
+static void ERR_CAPI_error(int function, int reason, char *file, int line);
+# define CAPIerr(f,r) ERR_CAPI_error((f),(r),OPENSSL_FILE,OPENSSL_LINE)
+
+/* Error codes for the CAPI functions. */
+
+/* Function codes. */
+# define CAPI_F_CAPI_CERT_GET_FNAME                       99
+# define CAPI_F_CAPI_CTRL                                 100
+# define CAPI_F_CAPI_CTX_NEW                              101
+# define CAPI_F_CAPI_CTX_SET_PROVNAME                     102
+# define CAPI_F_CAPI_DSA_DO_SIGN                          114
+# define CAPI_F_CAPI_GET_KEY                              103
+# define CAPI_F_CAPI_GET_PKEY                             115
+# define CAPI_F_CAPI_GET_PROVNAME                         104
+# define CAPI_F_CAPI_GET_PROV_INFO                        105
+# define CAPI_F_CAPI_INIT                                 106
+# define CAPI_F_CAPI_LIST_CONTAINERS                      107
+# define CAPI_F_CAPI_LOAD_PRIVKEY                         108
+# define CAPI_F_CAPI_OPEN_STORE                           109
+# define CAPI_F_CAPI_RSA_PRIV_DEC                         110
+# define CAPI_F_CAPI_RSA_PRIV_ENC                         111
+# define CAPI_F_CAPI_RSA_SIGN                             112
+# define CAPI_F_CAPI_VTRACE                               118
+# define CAPI_F_CERT_SELECT_DIALOG                        117
+# define CAPI_F_CLIENT_CERT_SELECT                        116
+# define CAPI_F_WIDE_TO_ASC                               113
+
+/* Reason codes. */
+# define CAPI_R_CANT_CREATE_HASH_OBJECT                   99
+# define CAPI_R_CANT_FIND_CAPI_CONTEXT                    100
+# define CAPI_R_CANT_GET_KEY                              101
+# define CAPI_R_CANT_SET_HASH_VALUE                       102
+# define CAPI_R_CRYPTACQUIRECONTEXT_ERROR                 103
+# define CAPI_R_CRYPTENUMPROVIDERS_ERROR                  104
+# define CAPI_R_DECRYPT_ERROR                             105
+# define CAPI_R_ENGINE_NOT_INITIALIZED                    106
+# define CAPI_R_ENUMCONTAINERS_ERROR                      107
+# define CAPI_R_ERROR_ADDING_CERT                         125
+# define CAPI_R_ERROR_CREATING_STORE                      126
+# define CAPI_R_ERROR_GETTING_FRIENDLY_NAME               108
+# define CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO           109
+# define CAPI_R_ERROR_OPENING_STORE                       110
+# define CAPI_R_ERROR_SIGNING_HASH                        111
+# define CAPI_R_FILE_OPEN_ERROR                           128
+# define CAPI_R_FUNCTION_NOT_SUPPORTED                    112
+# define CAPI_R_GETUSERKEY_ERROR                          113
+# define CAPI_R_INVALID_DIGEST_LENGTH                     124
+# define CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER  122
+# define CAPI_R_INVALID_LOOKUP_METHOD                     114
+# define CAPI_R_INVALID_PUBLIC_KEY_BLOB                   115
+# define CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER  123
+# define CAPI_R_PUBKEY_EXPORT_ERROR                       116
+# define CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR                117
+# define CAPI_R_UNKNOWN_COMMAND                           118
+# define CAPI_R_UNSUPPORTED_ALGORITHM_NID                 119
+# define CAPI_R_UNSUPPORTED_PADDING                       120
+# define CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM          121
+# define CAPI_R_WIN32_ERROR                               127
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/engines/e_chil_err.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/engines/e_chil_err.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/engines/e_chil_err.h	(revision 331)
@@ -0,0 +1,64 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*
+ * NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#ifndef HEADER_HWCRHK_ERR_H
+# define HEADER_HWCRHK_ERR_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+static void ERR_load_HWCRHK_strings(void);
+static void ERR_unload_HWCRHK_strings(void);
+static void ERR_HWCRHK_error(int function, int reason, char *file, int line);
+# define HWCRHKerr(f,r) ERR_HWCRHK_error((f),(r),OPENSSL_FILE,OPENSSL_LINE)
+
+/* Error codes for the HWCRHK functions. */
+
+/* Function codes. */
+# define HWCRHK_F_HWCRHK_CTRL                             100
+# define HWCRHK_F_HWCRHK_FINISH                           101
+# define HWCRHK_F_HWCRHK_GET_PASS                         102
+# define HWCRHK_F_HWCRHK_INIT                             103
+# define HWCRHK_F_HWCRHK_INSERT_CARD                      104
+# define HWCRHK_F_HWCRHK_LOAD_PRIVKEY                     105
+# define HWCRHK_F_HWCRHK_LOAD_PUBKEY                      106
+# define HWCRHK_F_HWCRHK_MOD_EXP                          107
+# define HWCRHK_F_HWCRHK_RAND_BYTES                       108
+# define HWCRHK_F_HWCRHK_RSA_MOD_EXP                      109
+# define HWCRHK_F_BIND_HELPER                             110
+# define HWCRHK_F_HWCRHK_MUTEX_INIT                       111
+
+/* Reason codes. */
+# define HWCRHK_R_ALREADY_LOADED                          100
+# define HWCRHK_R_BIO_WAS_FREED                           101
+# define HWCRHK_R_CHIL_ERROR                              102
+# define HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED            103
+# define HWCRHK_R_DSO_FAILURE                             104
+# define HWCRHK_R_MISSING_KEY_COMPONENTS                  105
+# define HWCRHK_R_NOT_INITIALISED                         106
+# define HWCRHK_R_NOT_LOADED                              107
+# define HWCRHK_R_NO_CALLBACK                             108
+# define HWCRHK_R_NO_KEY                                  109
+# define HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED         110
+# define HWCRHK_R_REQUEST_FAILED                          111
+# define HWCRHK_R_REQUEST_FALLBACK                        112
+# define HWCRHK_R_UNIT_FAILURE                            113
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/engines/e_dasync_err.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/engines/e_dasync_err.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/engines/e_dasync_err.h	(revision 331)
@@ -0,0 +1,52 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*
+ * NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#ifndef HEADER_DASYNC_ERR_H
+# define HEADER_DASYNC_ERR_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+static void ERR_load_DASYNC_strings(void);
+static void ERR_unload_DASYNC_strings(void);
+static void ERR_DASYNC_error(int function, int reason, char *file, int line);
+# define DASYNCerr(f,r) ERR_DASYNC_error((f),(r),OPENSSL_FILE,OPENSSL_LINE)
+
+/* Error codes for the DASYNC functions. */
+
+/* Function codes. */
+# define DASYNC_F_BIND_DASYNC                             107
+# define DASYNC_F_CIPHER_AES_128_CBC_CODE                 100
+# define DASYNC_F_DASYNC_AES128_CBC_HMAC_SHA1_INIT_KEY    109
+# define DASYNC_F_DASYNC_AES128_INIT_KEY                  108
+# define DASYNC_F_DASYNC_BN_MOD_EXP                       101
+# define DASYNC_F_DASYNC_CIPHER_INIT_KEY_HELPER           110
+# define DASYNC_F_DASYNC_MOD_EXP                          102
+# define DASYNC_F_DASYNC_PRIVATE_DECRYPT                  103
+# define DASYNC_F_DASYNC_PRIVATE_ENCRYPT                  104
+# define DASYNC_F_DASYNC_PUBLIC_DECRYPT                   105
+# define DASYNC_F_DASYNC_PUBLIC_ENCRYPT                   106
+
+/* Reason codes. */
+# define DASYNC_R_INIT_FAILED                             102
+# define DASYNC_R_LENGTH_NOT_BLOCK_ALIGNED                100
+# define DASYNC_R_UNKNOWN_FAULT                           101
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/engines/e_ossltest_err.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/engines/e_ossltest_err.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/engines/e_ossltest_err.h	(revision 331)
@@ -0,0 +1,41 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*
+ * NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#ifndef HEADER_OSSLTEST_ERR_H
+# define HEADER_OSSLTEST_ERR_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* BEGIN ERROR CODES */
+static void ERR_load_OSSLTEST_strings(void);
+static void ERR_unload_OSSLTEST_strings(void);
+static void ERR_OSSLTEST_error(int function, int reason, char *file, int line);
+# define OSSLTESTerr(f,r) ERR_OSSLTEST_error((f),(r),OPENSSL_FILE,OPENSSL_LINE)
+
+/* Error codes for the OSSLTEST functions. */
+
+/* Function codes. */
+# define OSSLTEST_F_BIND_OSSLTEST                         100
+# define OSSLTEST_F_OSSLTEST_AES128_INIT_KEY              101
+
+/* Reason codes. */
+# define OSSLTEST_R_INIT_FAILED                           100
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/engines/e_padlock.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/engines/e_padlock.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/engines/e_padlock.c	(revision 331)
@@ -0,0 +1,747 @@
+/*
+ * Copyright 2004-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 <stdio.h>
+#include <string.h>
+
+#include <openssl/opensslconf.h>
+#include <openssl/crypto.h>
+#include <openssl/engine.h>
+#include <openssl/evp.h>
+#include <openssl/aes.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <openssl/modes.h>
+
+#ifndef OPENSSL_NO_HW
+# ifndef OPENSSL_NO_HW_PADLOCK
+
+/* Attempt to have a single source for both 0.9.7 and 0.9.8 :-) */
+#  if (OPENSSL_VERSION_NUMBER >= 0x00908000L)
+#   ifndef OPENSSL_NO_DYNAMIC_ENGINE
+#    define DYNAMIC_ENGINE
+#   endif
+#  elif (OPENSSL_VERSION_NUMBER >= 0x00907000L)
+#   ifdef ENGINE_DYNAMIC_SUPPORT
+#    define DYNAMIC_ENGINE
+#   endif
+#  else
+#   error "Only OpenSSL >= 0.9.7 is supported"
+#  endif
+
+/*
+ * VIA PadLock AES is available *ONLY* on some x86 CPUs. Not only that it
+ * doesn't exist elsewhere, but it even can't be compiled on other platforms!
+ */
+
+#  undef COMPILE_HW_PADLOCK
+#  if !defined(I386_ONLY) && defined(PADLOCK_ASM)
+#   define COMPILE_HW_PADLOCK
+#   ifdef OPENSSL_NO_DYNAMIC_ENGINE
+static ENGINE *ENGINE_padlock(void);
+#   endif
+#  endif
+
+#  ifdef OPENSSL_NO_DYNAMIC_ENGINE
+void engine_load_padlock_int(void);
+void engine_load_padlock_int(void)
+{
+/* On non-x86 CPUs it just returns. */
+#   ifdef COMPILE_HW_PADLOCK
+    ENGINE *toadd = ENGINE_padlock();
+    if (!toadd)
+        return;
+    ENGINE_add(toadd);
+    ENGINE_free(toadd);
+    ERR_clear_error();
+#   endif
+}
+
+#  endif
+
+#  ifdef COMPILE_HW_PADLOCK
+
+/* Function for ENGINE detection and control */
+static int padlock_available(void);
+static int padlock_init(ENGINE *e);
+
+/* RNG Stuff */
+static RAND_METHOD padlock_rand;
+
+/* Cipher Stuff */
+static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
+                           const int **nids, int nid);
+
+/* Engine names */
+static const char *padlock_id = "padlock";
+static char padlock_name[100];
+
+/* Available features */
+static int padlock_use_ace = 0; /* Advanced Cryptography Engine */
+static int padlock_use_rng = 0; /* Random Number Generator */
+
+/* ===== Engine "management" functions ===== */
+
+/* Prepare the ENGINE structure for registration */
+static int padlock_bind_helper(ENGINE *e)
+{
+    /* Check available features */
+    padlock_available();
+
+    /*
+     * RNG is currently disabled for reasons discussed in commentary just
+     * before padlock_rand_bytes function.
+     */
+    padlock_use_rng = 0;
+
+    /* Generate a nice engine name with available features */
+    BIO_snprintf(padlock_name, sizeof(padlock_name),
+                 "VIA PadLock (%s, %s)",
+                 padlock_use_rng ? "RNG" : "no-RNG",
+                 padlock_use_ace ? "ACE" : "no-ACE");
+
+    /* Register everything or return with an error */
+    if (!ENGINE_set_id(e, padlock_id) ||
+        !ENGINE_set_name(e, padlock_name) ||
+        !ENGINE_set_init_function(e, padlock_init) ||
+        (padlock_use_ace && !ENGINE_set_ciphers(e, padlock_ciphers)) ||
+        (padlock_use_rng && !ENGINE_set_RAND(e, &padlock_rand))) {
+        return 0;
+    }
+
+    /* Everything looks good */
+    return 1;
+}
+
+#   ifdef OPENSSL_NO_DYNAMIC_ENGINE
+/* Constructor */
+static ENGINE *ENGINE_padlock(void)
+{
+    ENGINE *eng = ENGINE_new();
+
+    if (eng == NULL) {
+        return NULL;
+    }
+
+    if (!padlock_bind_helper(eng)) {
+        ENGINE_free(eng);
+        return NULL;
+    }
+
+    return eng;
+}
+#   endif
+
+/* Check availability of the engine */
+static int padlock_init(ENGINE *e)
+{
+    return (padlock_use_rng || padlock_use_ace);
+}
+
+/*
+ * This stuff is needed if this ENGINE is being compiled into a
+ * self-contained shared-library.
+ */
+#   ifdef DYNAMIC_ENGINE
+static int padlock_bind_fn(ENGINE *e, const char *id)
+{
+    if (id && (strcmp(id, padlock_id) != 0)) {
+        return 0;
+    }
+
+    if (!padlock_bind_helper(e)) {
+        return 0;
+    }
+
+    return 1;
+}
+
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(padlock_bind_fn)
+#   endif                       /* DYNAMIC_ENGINE */
+/* ===== Here comes the "real" engine ===== */
+
+/* Some AES-related constants */
+#   define AES_BLOCK_SIZE          16
+#   define AES_KEY_SIZE_128        16
+#   define AES_KEY_SIZE_192        24
+#   define AES_KEY_SIZE_256        32
+    /*
+     * Here we store the status information relevant to the current context.
+     */
+    /*
+     * BIG FAT WARNING: Inline assembler in PADLOCK_XCRYPT_ASM() depends on
+     * the order of items in this structure.  Don't blindly modify, reorder,
+     * etc!
+     */
+struct padlock_cipher_data {
+    unsigned char iv[AES_BLOCK_SIZE]; /* Initialization vector */
+    union {
+        unsigned int pad[4];
+        struct {
+            int rounds:4;
+            int dgst:1;         /* n/a in C3 */
+            int align:1;        /* n/a in C3 */
+            int ciphr:1;        /* n/a in C3 */
+            unsigned int keygen:1;
+            int interm:1;
+            unsigned int encdec:1;
+            int ksize:2;
+        } b;
+    } cword;                    /* Control word */
+    AES_KEY ks;                 /* Encryption key */
+};
+
+/* Interface to assembler module */
+unsigned int padlock_capability();
+void padlock_key_bswap(AES_KEY *key);
+void padlock_verify_context(struct padlock_cipher_data *ctx);
+void padlock_reload_key();
+void padlock_aes_block(void *out, const void *inp,
+                       struct padlock_cipher_data *ctx);
+int padlock_ecb_encrypt(void *out, const void *inp,
+                        struct padlock_cipher_data *ctx, size_t len);
+int padlock_cbc_encrypt(void *out, const void *inp,
+                        struct padlock_cipher_data *ctx, size_t len);
+int padlock_cfb_encrypt(void *out, const void *inp,
+                        struct padlock_cipher_data *ctx, size_t len);
+int padlock_ofb_encrypt(void *out, const void *inp,
+                        struct padlock_cipher_data *ctx, size_t len);
+int padlock_ctr32_encrypt(void *out, const void *inp,
+                          struct padlock_cipher_data *ctx, size_t len);
+int padlock_xstore(void *out, int edx);
+void padlock_sha1_oneshot(void *ctx, const void *inp, size_t len);
+void padlock_sha1(void *ctx, const void *inp, size_t len);
+void padlock_sha256_oneshot(void *ctx, const void *inp, size_t len);
+void padlock_sha256(void *ctx, const void *inp, size_t len);
+
+/*
+ * Load supported features of the CPU to see if the PadLock is available.
+ */
+static int padlock_available(void)
+{
+    unsigned int edx = padlock_capability();
+
+    /* Fill up some flags */
+    padlock_use_ace = ((edx & (0x3 << 6)) == (0x3 << 6));
+    padlock_use_rng = ((edx & (0x3 << 2)) == (0x3 << 2));
+
+    return padlock_use_ace + padlock_use_rng;
+}
+
+/* ===== AES encryption/decryption ===== */
+
+#   if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb)
+#    define NID_aes_128_cfb NID_aes_128_cfb128
+#   endif
+
+#   if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb)
+#    define NID_aes_128_ofb NID_aes_128_ofb128
+#   endif
+
+#   if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb)
+#    define NID_aes_192_cfb NID_aes_192_cfb128
+#   endif
+
+#   if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb)
+#    define NID_aes_192_ofb NID_aes_192_ofb128
+#   endif
+
+#   if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb)
+#    define NID_aes_256_cfb NID_aes_256_cfb128
+#   endif
+
+#   if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb)
+#    define NID_aes_256_ofb NID_aes_256_ofb128
+#   endif
+
+/* List of supported ciphers. */
+static const int padlock_cipher_nids[] = {
+    NID_aes_128_ecb,
+    NID_aes_128_cbc,
+    NID_aes_128_cfb,
+    NID_aes_128_ofb,
+    NID_aes_128_ctr,
+
+    NID_aes_192_ecb,
+    NID_aes_192_cbc,
+    NID_aes_192_cfb,
+    NID_aes_192_ofb,
+    NID_aes_192_ctr,
+
+    NID_aes_256_ecb,
+    NID_aes_256_cbc,
+    NID_aes_256_cfb,
+    NID_aes_256_ofb,
+    NID_aes_256_ctr
+};
+
+static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids) /
+                                      sizeof(padlock_cipher_nids[0]));
+
+/* Function prototypes ... */
+static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                                const unsigned char *iv, int enc);
+
+#   define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) +         \
+        ( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F )      )
+#   define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\
+        NEAREST_ALIGNED(EVP_CIPHER_CTX_get_cipher_data(ctx)))
+
+static int
+padlock_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
+                   const unsigned char *in_arg, size_t nbytes)
+{
+    return padlock_ecb_encrypt(out_arg, in_arg,
+                               ALIGNED_CIPHER_DATA(ctx), nbytes);
+}
+
+static int
+padlock_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
+                   const unsigned char *in_arg, size_t nbytes)
+{
+    struct padlock_cipher_data *cdata = ALIGNED_CIPHER_DATA(ctx);
+    int ret;
+
+    memcpy(cdata->iv, EVP_CIPHER_CTX_iv(ctx), AES_BLOCK_SIZE);
+    if ((ret = padlock_cbc_encrypt(out_arg, in_arg, cdata, nbytes)))
+        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), cdata->iv, AES_BLOCK_SIZE);
+    return ret;
+}
+
+static int
+padlock_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
+                   const unsigned char *in_arg, size_t nbytes)
+{
+    struct padlock_cipher_data *cdata = ALIGNED_CIPHER_DATA(ctx);
+    size_t chunk;
+
+    if ((chunk = EVP_CIPHER_CTX_num(ctx))) {   /* borrow chunk variable */
+        unsigned char *ivp = EVP_CIPHER_CTX_iv_noconst(ctx);
+
+        if (chunk >= AES_BLOCK_SIZE)
+            return 0;           /* bogus value */
+
+        if (EVP_CIPHER_CTX_encrypting(ctx))
+            while (chunk < AES_BLOCK_SIZE && nbytes != 0) {
+                ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk];
+                chunk++, nbytes--;
+        } else
+            while (chunk < AES_BLOCK_SIZE && nbytes != 0) {
+                unsigned char c = *(in_arg++);
+                *(out_arg++) = c ^ ivp[chunk];
+                ivp[chunk++] = c, nbytes--;
+            }
+
+        EVP_CIPHER_CTX_set_num(ctx, chunk % AES_BLOCK_SIZE);
+    }
+
+    if (nbytes == 0)
+        return 1;
+
+    memcpy(cdata->iv, EVP_CIPHER_CTX_iv(ctx), AES_BLOCK_SIZE);
+
+    if ((chunk = nbytes & ~(AES_BLOCK_SIZE - 1))) {
+        if (!padlock_cfb_encrypt(out_arg, in_arg, cdata, chunk))
+            return 0;
+        nbytes -= chunk;
+    }
+
+    if (nbytes) {
+        unsigned char *ivp = cdata->iv;
+
+        out_arg += chunk;
+        in_arg += chunk;
+        EVP_CIPHER_CTX_set_num(ctx, nbytes);
+        if (cdata->cword.b.encdec) {
+            cdata->cword.b.encdec = 0;
+            padlock_reload_key();
+            padlock_aes_block(ivp, ivp, cdata);
+            cdata->cword.b.encdec = 1;
+            padlock_reload_key();
+            while (nbytes) {
+                unsigned char c = *(in_arg++);
+                *(out_arg++) = c ^ *ivp;
+                *(ivp++) = c, nbytes--;
+            }
+        } else {
+            padlock_reload_key();
+            padlock_aes_block(ivp, ivp, cdata);
+            padlock_reload_key();
+            while (nbytes) {
+                *ivp = *(out_arg++) = *(in_arg++) ^ *ivp;
+                ivp++, nbytes--;
+            }
+        }
+    }
+
+    memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), cdata->iv, AES_BLOCK_SIZE);
+
+    return 1;
+}
+
+static int
+padlock_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
+                   const unsigned char *in_arg, size_t nbytes)
+{
+    struct padlock_cipher_data *cdata = ALIGNED_CIPHER_DATA(ctx);
+    size_t chunk;
+
+    /*
+     * ctx->num is maintained in byte-oriented modes, such as CFB and OFB...
+     */
+    if ((chunk = EVP_CIPHER_CTX_num(ctx))) {   /* borrow chunk variable */
+        unsigned char *ivp = EVP_CIPHER_CTX_iv_noconst(ctx);
+
+        if (chunk >= AES_BLOCK_SIZE)
+            return 0;           /* bogus value */
+
+        while (chunk < AES_BLOCK_SIZE && nbytes != 0) {
+            *(out_arg++) = *(in_arg++) ^ ivp[chunk];
+            chunk++, nbytes--;
+        }
+
+        EVP_CIPHER_CTX_set_num(ctx, chunk % AES_BLOCK_SIZE);
+    }
+
+    if (nbytes == 0)
+        return 1;
+
+    memcpy(cdata->iv, EVP_CIPHER_CTX_iv(ctx), AES_BLOCK_SIZE);
+
+    if ((chunk = nbytes & ~(AES_BLOCK_SIZE - 1))) {
+        if (!padlock_ofb_encrypt(out_arg, in_arg, cdata, chunk))
+            return 0;
+        nbytes -= chunk;
+    }
+
+    if (nbytes) {
+        unsigned char *ivp = cdata->iv;
+
+        out_arg += chunk;
+        in_arg += chunk;
+        EVP_CIPHER_CTX_set_num(ctx, nbytes);
+        padlock_reload_key();   /* empirically found */
+        padlock_aes_block(ivp, ivp, cdata);
+        padlock_reload_key();   /* empirically found */
+        while (nbytes) {
+            *(out_arg++) = *(in_arg++) ^ *ivp;
+            ivp++, nbytes--;
+        }
+    }
+
+    memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), cdata->iv, AES_BLOCK_SIZE);
+
+    return 1;
+}
+
+static void padlock_ctr32_encrypt_glue(const unsigned char *in,
+                                       unsigned char *out, size_t blocks,
+                                       struct padlock_cipher_data *ctx,
+                                       const unsigned char *ivec)
+{
+    memcpy(ctx->iv, ivec, AES_BLOCK_SIZE);
+    padlock_ctr32_encrypt(out, in, ctx, AES_BLOCK_SIZE * blocks);
+}
+
+static int
+padlock_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg,
+                   const unsigned char *in_arg, size_t nbytes)
+{
+    struct padlock_cipher_data *cdata = ALIGNED_CIPHER_DATA(ctx);
+    unsigned int num = EVP_CIPHER_CTX_num(ctx);
+
+    CRYPTO_ctr128_encrypt_ctr32(in_arg, out_arg, nbytes,
+                                cdata, EVP_CIPHER_CTX_iv_noconst(ctx),
+                                EVP_CIPHER_CTX_buf_noconst(ctx), &num,
+                                (ctr128_f) padlock_ctr32_encrypt_glue);
+
+    EVP_CIPHER_CTX_set_num(ctx, (size_t)num);
+    return 1;
+}
+
+#   define EVP_CIPHER_block_size_ECB       AES_BLOCK_SIZE
+#   define EVP_CIPHER_block_size_CBC       AES_BLOCK_SIZE
+#   define EVP_CIPHER_block_size_OFB       1
+#   define EVP_CIPHER_block_size_CFB       1
+#   define EVP_CIPHER_block_size_CTR       1
+
+/*
+ * Declaring so many ciphers by hand would be a pain. Instead introduce a bit
+ * of preprocessor magic :-)
+ */
+#   define DECLARE_AES_EVP(ksize,lmode,umode)      \
+static EVP_CIPHER *_hidden_aes_##ksize##_##lmode = NULL; \
+static const EVP_CIPHER *padlock_aes_##ksize##_##lmode(void) \
+{                                                                       \
+    if (_hidden_aes_##ksize##_##lmode == NULL                           \
+        && ((_hidden_aes_##ksize##_##lmode =                            \
+             EVP_CIPHER_meth_new(NID_aes_##ksize##_##lmode,             \
+                                 EVP_CIPHER_block_size_##umode,         \
+                                 AES_KEY_SIZE_##ksize)) == NULL         \
+            || !EVP_CIPHER_meth_set_iv_length(_hidden_aes_##ksize##_##lmode, \
+                                              AES_BLOCK_SIZE)           \
+            || !EVP_CIPHER_meth_set_flags(_hidden_aes_##ksize##_##lmode, \
+                                          0 | EVP_CIPH_##umode##_MODE)  \
+            || !EVP_CIPHER_meth_set_init(_hidden_aes_##ksize##_##lmode, \
+                                         padlock_aes_init_key)          \
+            || !EVP_CIPHER_meth_set_do_cipher(_hidden_aes_##ksize##_##lmode, \
+                                              padlock_##lmode##_cipher) \
+            || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_aes_##ksize##_##lmode, \
+                                                  sizeof(struct padlock_cipher_data) + 16) \
+            || !EVP_CIPHER_meth_set_set_asn1_params(_hidden_aes_##ksize##_##lmode, \
+                                                    EVP_CIPHER_set_asn1_iv) \
+            || !EVP_CIPHER_meth_set_get_asn1_params(_hidden_aes_##ksize##_##lmode, \
+                                                    EVP_CIPHER_get_asn1_iv))) { \
+        EVP_CIPHER_meth_free(_hidden_aes_##ksize##_##lmode);            \
+        _hidden_aes_##ksize##_##lmode = NULL;                           \
+    }                                                                   \
+    return _hidden_aes_##ksize##_##lmode;                               \
+}
+
+DECLARE_AES_EVP(128, ecb, ECB)
+DECLARE_AES_EVP(128, cbc, CBC)
+DECLARE_AES_EVP(128, cfb, CFB)
+DECLARE_AES_EVP(128, ofb, OFB)
+DECLARE_AES_EVP(128, ctr, CTR)
+
+DECLARE_AES_EVP(192, ecb, ECB)
+DECLARE_AES_EVP(192, cbc, CBC)
+DECLARE_AES_EVP(192, cfb, CFB)
+DECLARE_AES_EVP(192, ofb, OFB)
+DECLARE_AES_EVP(192, ctr, CTR)
+
+DECLARE_AES_EVP(256, ecb, ECB)
+DECLARE_AES_EVP(256, cbc, CBC)
+DECLARE_AES_EVP(256, cfb, CFB)
+DECLARE_AES_EVP(256, ofb, OFB)
+DECLARE_AES_EVP(256, ctr, CTR)
+
+static int
+padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids,
+                int nid)
+{
+    /* No specific cipher => return a list of supported nids ... */
+    if (!cipher) {
+        *nids = padlock_cipher_nids;
+        return padlock_cipher_nids_num;
+    }
+
+    /* ... or the requested "cipher" otherwise */
+    switch (nid) {
+    case NID_aes_128_ecb:
+        *cipher = padlock_aes_128_ecb();
+        break;
+    case NID_aes_128_cbc:
+        *cipher = padlock_aes_128_cbc();
+        break;
+    case NID_aes_128_cfb:
+        *cipher = padlock_aes_128_cfb();
+        break;
+    case NID_aes_128_ofb:
+        *cipher = padlock_aes_128_ofb();
+        break;
+    case NID_aes_128_ctr:
+        *cipher = padlock_aes_128_ctr();
+        break;
+
+    case NID_aes_192_ecb:
+        *cipher = padlock_aes_192_ecb();
+        break;
+    case NID_aes_192_cbc:
+        *cipher = padlock_aes_192_cbc();
+        break;
+    case NID_aes_192_cfb:
+        *cipher = padlock_aes_192_cfb();
+        break;
+    case NID_aes_192_ofb:
+        *cipher = padlock_aes_192_ofb();
+        break;
+    case NID_aes_192_ctr:
+        *cipher = padlock_aes_192_ctr();
+        break;
+
+    case NID_aes_256_ecb:
+        *cipher = padlock_aes_256_ecb();
+        break;
+    case NID_aes_256_cbc:
+        *cipher = padlock_aes_256_cbc();
+        break;
+    case NID_aes_256_cfb:
+        *cipher = padlock_aes_256_cfb();
+        break;
+    case NID_aes_256_ofb:
+        *cipher = padlock_aes_256_ofb();
+        break;
+    case NID_aes_256_ctr:
+        *cipher = padlock_aes_256_ctr();
+        break;
+
+    default:
+        /* Sorry, we don't support this NID */
+        *cipher = NULL;
+        return 0;
+    }
+
+    return 1;
+}
+
+/* Prepare the encryption key for PadLock usage */
+static int
+padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                     const unsigned char *iv, int enc)
+{
+    struct padlock_cipher_data *cdata;
+    int key_len = EVP_CIPHER_CTX_key_length(ctx) * 8;
+    unsigned long mode = EVP_CIPHER_CTX_mode(ctx);
+
+    if (key == NULL)
+        return 0;               /* ERROR */
+
+    cdata = ALIGNED_CIPHER_DATA(ctx);
+    memset(cdata, 0, sizeof(*cdata));
+
+    /* Prepare Control word. */
+    if (mode == EVP_CIPH_OFB_MODE || mode == EVP_CIPH_CTR_MODE)
+        cdata->cword.b.encdec = 0;
+    else
+        cdata->cword.b.encdec = (EVP_CIPHER_CTX_encrypting(ctx) == 0);
+    cdata->cword.b.rounds = 10 + (key_len - 128) / 32;
+    cdata->cword.b.ksize = (key_len - 128) / 64;
+
+    switch (key_len) {
+    case 128:
+        /*
+         * PadLock can generate an extended key for AES128 in hardware
+         */
+        memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128);
+        cdata->cword.b.keygen = 0;
+        break;
+
+    case 192:
+    case 256:
+        /*
+         * Generate an extended AES key in software. Needed for AES192/AES256
+         */
+        /*
+         * Well, the above applies to Stepping 8 CPUs and is listed as
+         * hardware errata. They most likely will fix it at some point and
+         * then a check for stepping would be due here.
+         */
+        if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE)
+            && !enc)
+            AES_set_decrypt_key(key, key_len, &cdata->ks);
+        else
+            AES_set_encrypt_key(key, key_len, &cdata->ks);
+#   ifndef AES_ASM
+        /*
+         * OpenSSL C functions use byte-swapped extended key.
+         */
+        padlock_key_bswap(&cdata->ks);
+#   endif
+        cdata->cword.b.keygen = 1;
+        break;
+
+    default:
+        /* ERROR */
+        return 0;
+    }
+
+    /*
+     * This is done to cover for cases when user reuses the
+     * context for new key. The catch is that if we don't do
+     * this, padlock_eas_cipher might proceed with old key...
+     */
+    padlock_reload_key();
+
+    return 1;
+}
+
+/* ===== Random Number Generator ===== */
+/*
+ * This code is not engaged. The reason is that it does not comply
+ * with recommendations for VIA RNG usage for secure applications
+ * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it
+ * provide meaningful error control...
+ */
+/*
+ * Wrapper that provides an interface between the API and the raw PadLock
+ * RNG
+ */
+static int padlock_rand_bytes(unsigned char *output, int count)
+{
+    unsigned int eax, buf;
+
+    while (count >= 8) {
+        eax = padlock_xstore(output, 0);
+        if (!(eax & (1 << 6)))
+            return 0;           /* RNG disabled */
+        /* this ---vv--- covers DC bias, Raw Bits and String Filter */
+        if (eax & (0x1F << 10))
+            return 0;
+        if ((eax & 0x1F) == 0)
+            continue;           /* no data, retry... */
+        if ((eax & 0x1F) != 8)
+            return 0;           /* fatal failure...  */
+        output += 8;
+        count -= 8;
+    }
+    while (count > 0) {
+        eax = padlock_xstore(&buf, 3);
+        if (!(eax & (1 << 6)))
+            return 0;           /* RNG disabled */
+        /* this ---vv--- covers DC bias, Raw Bits and String Filter */
+        if (eax & (0x1F << 10))
+            return 0;
+        if ((eax & 0x1F) == 0)
+            continue;           /* no data, retry... */
+        if ((eax & 0x1F) != 1)
+            return 0;           /* fatal failure...  */
+        *output++ = (unsigned char)buf;
+        count--;
+    }
+    OPENSSL_cleanse(&buf, sizeof(buf));
+
+    return 1;
+}
+
+/* Dummy but necessary function */
+static int padlock_rand_status(void)
+{
+    return 1;
+}
+
+/* Prepare structure for registration */
+static RAND_METHOD padlock_rand = {
+    NULL,                       /* seed */
+    padlock_rand_bytes,         /* bytes */
+    NULL,                       /* cleanup */
+    NULL,                       /* add */
+    padlock_rand_bytes,         /* pseudorand */
+    padlock_rand_status,        /* rand status */
+};
+
+#  endif                        /* COMPILE_HW_PADLOCK */
+# endif                         /* !OPENSSL_NO_HW_PADLOCK */
+#endif                          /* !OPENSSL_NO_HW */
+
+#if defined(OPENSSL_NO_HW) || defined(OPENSSL_NO_HW_PADLOCK) \
+        || !defined(COMPILE_HW_PADLOCK)
+# ifndef OPENSSL_NO_DYNAMIC_ENGINE
+OPENSSL_EXPORT
+    int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns);
+OPENSSL_EXPORT
+    int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns)
+{
+    return 0;
+}
+
+IMPLEMENT_DYNAMIC_CHECK_FN()
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/engines/vendor_defns/hwcryptohook.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/engines/vendor_defns/hwcryptohook.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/engines/vendor_defns/hwcryptohook.h	(revision 331)
@@ -0,0 +1,509 @@
+/*
+ * Copyright 2002-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
+ */
+
+/*-
+ * ModExp / RSA (with/without KM) plugin API
+ *
+ * The application will load a dynamic library which
+ * exports entrypoint(s) defined in this file.
+ *
+ * This set of entrypoints provides only a multithreaded,
+ * synchronous-within-each-thread, facility.
+ *
+ *
+ * This file is Copyright 1998-2000 nCipher Corporation Limited.
+ *
+ * Redistribution and use in source and binary forms, with opr without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the copyright notice,
+ *    this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions, and the following
+ *    disclaimer, in the documentation and/or other materials provided
+ *    with the distribution
+ *
+ * IN NO EVENT SHALL NCIPHER CORPORATION LIMITED (`NCIPHER') AND/OR
+ * ANY OTHER AUTHORS OR DISTRIBUTORS OF THIS FILE BE LIABLE for any
+ * damages arising directly or indirectly from this file, its use or
+ * this licence.  Without prejudice to the generality of the
+ * foregoing: all liability shall be excluded for direct, indirect,
+ * special, incidental, consequential or other damages or any loss of
+ * profits, business, revenue goodwill or anticipated savings;
+ * liability shall be excluded even if nCipher or anyone else has been
+ * advised of the possibility of damage.  In any event, if the
+ * exclusion of liability is not effective, the liability of nCipher
+ * or any author or distributor shall be limited to the lesser of the
+ * price paid and 1,000 pounds sterling. This licence only fails to
+ * exclude or limit liability for death or personal injury arising out
+ * of negligence, and only to the extent that such an exclusion or
+ * limitation is not effective.
+ *
+ * NCIPHER AND THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ALL
+ * AND ANY WARRANTIES (WHETHER EXPRESS OR IMPLIED), including, but not
+ * limited to, any implied warranties of merchantability, fitness for
+ * a particular purpose, satisfactory quality, and/or non-infringement
+ * of any third party rights.
+ *
+ * US Government use: This software and documentation is Commercial
+ * Computer Software and Computer Software Documentation, as defined in
+ * sub-paragraphs (a)(1) and (a)(5) of DFAR 252.227-7014, "Rights in
+ * Noncommercial Computer Software and Noncommercial Computer Software
+ * Documentation."  Use, duplication or disclosure by the Government is
+ * subject to the terms and conditions specified here.
+ *
+ * By using or distributing this file you will be accepting these
+ * terms and conditions, including the limitation of liability and
+ * lack of warranty.  If you do not wish to accept these terms and
+ * conditions, DO NOT USE THE FILE.
+ *
+ *
+ * The actual dynamically loadable plugin, and the library files for
+ * static linking, which are also provided in some distributions, are
+ * not covered by the licence described above.  You should have
+ * received a separate licence with terms and conditions for these
+ * library files; if you received the library files without a licence,
+ * please contact nCipher.
+ *
+ */
+
+#ifndef HWCRYPTOHOOK_H
+# define HWCRYPTOHOOK_H
+
+# include <sys/types.h>
+# include <stdio.h>
+
+# ifndef HWCRYPTOHOOK_DECLARE_APPTYPES
+#  define HWCRYPTOHOOK_DECLARE_APPTYPES 1
+# endif
+
+# define HWCRYPTOHOOK_ERROR_FAILED   -1
+# define HWCRYPTOHOOK_ERROR_FALLBACK -2
+# define HWCRYPTOHOOK_ERROR_MPISIZE  -3
+
+# if HWCRYPTOHOOK_DECLARE_APPTYPES
+
+/*-
+ * These structs are defined by the application and opaque to the
+ * crypto plugin.  The application may define these as it sees fit.
+ * Default declarations are provided here, but the application may
+ *  #define HWCRYPTOHOOK_DECLARE_APPTYPES 0
+ * to prevent these declarations, and instead provide its own
+ * declarations of these types.  (Pointers to them must still be
+ * ordinary pointers to structs or unions, or the resulting combined
+ * program will have a type inconsistency.)
+ */
+typedef struct HWCryptoHook_MutexValue HWCryptoHook_Mutex;
+typedef struct HWCryptoHook_CondVarValue HWCryptoHook_CondVar;
+typedef struct HWCryptoHook_PassphraseContextValue
+ HWCryptoHook_PassphraseContext;
+typedef struct HWCryptoHook_CallerContextValue HWCryptoHook_CallerContext;
+
+# endif                         /* HWCRYPTOHOOK_DECLARE_APPTYPES */
+
+/*-
+ * These next two structs are opaque to the application.  The crypto
+ * plugin will return pointers to them; the caller simply manipulates
+ * the pointers.
+ */
+typedef struct HWCryptoHook_Context *HWCryptoHook_ContextHandle;
+typedef struct HWCryptoHook_RSAKey *HWCryptoHook_RSAKeyHandle;
+
+typedef struct {
+    char *buf;
+    size_t size;
+} HWCryptoHook_ErrMsgBuf;
+/*-
+ * Used for error reporting.  When a HWCryptoHook function fails it
+ * will return a sentinel value (0 for pointer-valued functions, or a
+ * negative number, usually HWCRYPTOHOOK_ERROR_FAILED, for
+ * integer-valued ones).  It will, if an ErrMsgBuf is passed, also put
+ * an error message there.
+ *
+ * size is the size of the buffer, and will not be modified.  If you
+ * pass 0 for size you must pass 0 for buf, and nothing will be
+ * recorded (just as if you passed 0 for the struct pointer).
+ * Messages written to the buffer will always be null-terminated, even
+ * when truncated to fit within size bytes.
+ *
+ * The contents of the buffer are not defined if there is no error.
+ */
+
+typedef struct HWCryptoHook_MPIStruct {
+    unsigned char *buf;
+    size_t size;
+} HWCryptoHook_MPI;
+/*-
+ * When one of these is returned, a pointer is passed to the function.
+ * At call, size is the space available.  Afterwards it is updated to
+ * be set to the actual length (which may be more than the space available,
+ * if there was not enough room and the result was truncated).
+ * buf (the pointer) is not updated.
+ *
+ * size is in bytes and may be zero at call or return, but must be a
+ * multiple of the limb size.  Zero limbs at the MS end are not
+ * permitted.
+ */
+
+# define HWCryptoHook_InitFlags_FallbackModExp    0x0002UL
+# define HWCryptoHook_InitFlags_FallbackRSAImmed  0x0004UL
+/*-
+ * Enable requesting fallback to software in case of problems with the
+ * hardware support.  This indicates to the crypto provider that the
+ * application is prepared to fall back to software operation if the
+ * ModExp* or RSAImmed* functions return HWCRYPTOHOOK_ERROR_FALLBACK.
+ * Without this flag those calls will never return
+ * HWCRYPTOHOOK_ERROR_FALLBACK.  The flag will also cause the crypto
+ * provider to avoid repeatedly attempting to contact dead hardware
+ * within a short interval, if appropriate.
+ */
+
+# define HWCryptoHook_InitFlags_SimpleForkCheck   0x0010UL
+/*-
+ * Without _SimpleForkCheck the library is allowed to assume that the
+ * application will not fork and call the library in the child(ren).
+ *
+ * When it is specified, this is allowed.  However, after a fork
+ * neither parent nor child may unload any loaded keys or call
+ * _Finish.  Instead, they should call exit (or die with a signal)
+ * without calling _Finish.  After all the children have died the
+ * parent may unload keys or call _Finish.
+ *
+ * This flag only has any effect on UN*X platforms.
+ */
+
+typedef struct {
+    unsigned long flags;
+    void *logstream;            /* usually a FILE*.  See below. */
+    size_t limbsize;            /* bignum format - size of radix type, must
+                                 * be power of 2 */
+    int mslimbfirst;            /* 0 or 1 */
+    int msbytefirst;            /* 0 or 1; -1 = native */
+    /*-
+    * All the callback functions should return 0 on success, or a
+    * nonzero integer (whose value will be visible in the error message
+    * put in the buffer passed to the call).
+    *
+    * If a callback is not available pass a null function pointer.
+    *
+    * The callbacks may not call down again into the crypto plugin.
+    */
+    /*-
+    * For thread-safety.  Set everything to 0 if you promise only to be
+    * singlethreaded.  maxsimultaneous is the number of calls to
+    * ModExp[Crt]/RSAImmed{Priv,Pub}/RSA.  If you don't know what to
+    * put there then say 0 and the hook library will use a default.
+    *
+    * maxmutexes is a small limit on the number of simultaneous mutexes
+    * which will be requested by the library.  If there is no small
+    * limit, set it to 0.  If the crypto plugin cannot create the
+    * advertised number of mutexes the calls to its functions may fail.
+    * If a low number of mutexes is advertised the plugin will try to
+    * do the best it can.  Making larger numbers of mutexes available
+    * may improve performance and parallelism by reducing contention
+    * over critical sections.  Unavailability of any mutexes, implying
+    * single-threaded operation, should be indicated by the setting
+    * mutex_init et al to 0.
+    */
+    int maxmutexes;
+    int maxsimultaneous;
+    size_t mutexsize;
+    int (*mutex_init) (HWCryptoHook_Mutex *,
+                       HWCryptoHook_CallerContext * cactx);
+    int (*mutex_acquire) (HWCryptoHook_Mutex *);
+    void (*mutex_release) (HWCryptoHook_Mutex *);
+    void (*mutex_destroy) (HWCryptoHook_Mutex *);
+    /*-
+    * For greater efficiency, can use condition vars internally for
+    * synchronisation.  In this case maxsimultaneous is ignored, but
+    * the other mutex stuff must be available.  In singlethreaded
+    * programs, set everything to 0.
+    */
+    size_t condvarsize;
+    int (*condvar_init) (HWCryptoHook_CondVar *,
+                         HWCryptoHook_CallerContext * cactx);
+    int (*condvar_wait) (HWCryptoHook_CondVar *, HWCryptoHook_Mutex *);
+    void (*condvar_signal) (HWCryptoHook_CondVar *);
+    void (*condvar_broadcast) (HWCryptoHook_CondVar *);
+    void (*condvar_destroy) (HWCryptoHook_CondVar *);
+    /*-
+    * The semantics of acquiring and releasing mutexes and broadcasting
+    * and waiting on condition variables are expected to be those from
+    * POSIX threads (pthreads).  The mutexes may be (in pthread-speak)
+    * fast mutexes, recursive mutexes, or nonrecursive ones.
+    *
+    * The _release/_signal/_broadcast and _destroy functions must
+    * always succeed when given a valid argument; if they are given an
+    * invalid argument then the program (crypto plugin + application)
+    * has an internal error, and they should abort the program.
+    */
+    int (*getpassphrase) (const char *prompt_info,
+                          int *len_io, char *buf,
+                          HWCryptoHook_PassphraseContext * ppctx,
+                          HWCryptoHook_CallerContext * cactx);
+    /*-
+    * Passphrases and the prompt_info, if they contain high-bit-set
+    * characters, are UTF-8.  The prompt_info may be a null pointer if
+    * no prompt information is available (it should not be an empty
+    * string).  It will not contain text like `enter passphrase';
+    * instead it might say something like `Operator Card for John
+    * Smith' or `SmartCard in nFast Module #1, Slot #1'.
+    *
+    * buf points to a buffer in which to return the passphrase; on
+    * entry *len_io is the length of the buffer.  It should be updated
+    * by the callback.  The returned passphrase should not be
+    * null-terminated by the callback.
+    */
+    int (*getphystoken) (const char *prompt_info,
+                         const char *wrong_info,
+                         HWCryptoHook_PassphraseContext * ppctx,
+                         HWCryptoHook_CallerContext * cactx);
+    /*-
+    * Requests that the human user physically insert a different
+    * smartcard, DataKey, etc.  The plugin should check whether the
+    * currently inserted token(s) are appropriate, and if they are it
+    * should not make this call.
+    *
+    * prompt_info is as before.  wrong_info is a description of the
+    * currently inserted token(s) so that the user is told what
+    * something is.  wrong_info, like prompt_info, may be null, but
+    * should not be an empty string.  Its contents should be
+    * syntactically similar to that of prompt_info.
+    */
+    /*-
+    * Note that a single LoadKey operation might cause several calls to
+    * getpassphrase and/or requestphystoken.  If requestphystoken is
+    * not provided (ie, a null pointer is passed) then the plugin may
+    * not support loading keys for which authorisation by several cards
+    * is required.  If getpassphrase is not provided then cards with
+    * passphrases may not be supported.
+    *
+    * getpassphrase and getphystoken do not need to check that the
+    * passphrase has been entered correctly or the correct token
+    * inserted; the crypto plugin will do that.  If this is not the
+    * case then the crypto plugin is responsible for calling these
+    * routines again as appropriate until the correct token(s) and
+    * passphrase(s) are supplied as required, or until any retry limits
+    * implemented by the crypto plugin are reached.
+    *
+    * In either case, the application must allow the user to say `no'
+    * or `cancel' to indicate that they do not know the passphrase or
+    * have the appropriate token; this should cause the callback to
+    * return nonzero indicating error.
+    */
+    void (*logmessage) (void *logstream, const char *message);
+    /*-
+    * A log message will be generated at least every time something goes
+    * wrong and an ErrMsgBuf is filled in (or would be if one was
+    * provided).  Other diagnostic information may be written there too,
+    * including more detailed reasons for errors which are reported in an
+    * ErrMsgBuf.
+    *
+    * When a log message is generated, this callback is called.  It
+    * should write a message to the relevant logging arrangements.
+    *
+    * The message string passed will be null-terminated and may be of arbitrary
+    * length.  It will not be prefixed by the time and date, nor by the
+    * name of the library that is generating it - if this is required,
+    * the logmessage callback must do it.  The message will not have a
+    * trailing newline (though it may contain internal newlines).
+    *
+    * If a null pointer is passed for logmessage a default function is
+    * used.  The default function treats logstream as a FILE* which has
+    * been converted to a void*.  If logstream is 0 it does nothing.
+    * Otherwise it prepends the date and time and library name and
+    * writes the message to logstream.  Each line will be prefixed by a
+    * descriptive string containing the date, time and identity of the
+    * crypto plugin.  Errors on the logstream are not reported
+    * anywhere, and the default function doesn't flush the stream, so
+    * the application must set the buffering how it wants it.
+    *
+    * The crypto plugin may also provide a facility to have copies of
+    * log messages sent elsewhere, and or for adjusting the verbosity
+    * of the log messages; any such facilities will be configured by
+    * external means.
+    */
+} HWCryptoHook_InitInfo;
+
+typedef
+HWCryptoHook_ContextHandle HWCryptoHook_Init_t(const HWCryptoHook_InitInfo *
+                                               initinfo, size_t initinfosize,
+                                               const HWCryptoHook_ErrMsgBuf *
+                                               errors,
+                                               HWCryptoHook_CallerContext *
+                                               cactx);
+extern HWCryptoHook_Init_t HWCryptoHook_Init;
+
+/*-
+ * Caller should set initinfosize to the size of the HWCryptoHook struct,
+ * so it can be extended later.
+ *
+ * On success, a message for display or logging by the server,
+ * including the name and version number of the plugin, will be filled
+ * in into *errors; on failure *errors is used for error handling, as
+ * usual.
+ */
+
+/*-
+ * All these functions return 0 on success, HWCRYPTOHOOK_ERROR_FAILED
+ * on most failures.  HWCRYPTOHOOK_ERROR_MPISIZE means at least one of
+ * the output MPI buffer(s) was too small; the sizes of all have been
+ * set to the desired size (and for those where the buffer was large
+ * enough, the value may have been copied in), and no error message
+ * has been recorded.
+ *
+ * You may pass 0 for the errors struct.  In any case, unless you set
+ * _NoStderr at init time then messages may be reported to stderr.
+ */
+
+/*-
+ * The RSAImmed* functions (and key managed RSA) only work with
+ * modules which have an RSA patent licence - currently that means KM
+ * units; the ModExp* ones work with all modules, so you need a patent
+ * licence in the software in the US.  They are otherwise identical.
+ */
+
+typedef
+void HWCryptoHook_Finish_t(HWCryptoHook_ContextHandle hwctx);
+extern HWCryptoHook_Finish_t HWCryptoHook_Finish;
+/* You must not have any calls going or keys loaded when you call this. */
+
+typedef
+int HWCryptoHook_RandomBytes_t(HWCryptoHook_ContextHandle hwctx,
+                               unsigned char *buf, size_t len,
+                               const HWCryptoHook_ErrMsgBuf * errors);
+extern HWCryptoHook_RandomBytes_t HWCryptoHook_RandomBytes;
+
+typedef
+int HWCryptoHook_ModExp_t(HWCryptoHook_ContextHandle hwctx,
+                          HWCryptoHook_MPI a,
+                          HWCryptoHook_MPI p,
+                          HWCryptoHook_MPI n,
+                          HWCryptoHook_MPI * r,
+                          const HWCryptoHook_ErrMsgBuf * errors);
+extern HWCryptoHook_ModExp_t HWCryptoHook_ModExp;
+
+typedef
+int HWCryptoHook_RSAImmedPub_t(HWCryptoHook_ContextHandle hwctx,
+                               HWCryptoHook_MPI m,
+                               HWCryptoHook_MPI e,
+                               HWCryptoHook_MPI n,
+                               HWCryptoHook_MPI * r,
+                               const HWCryptoHook_ErrMsgBuf * errors);
+extern HWCryptoHook_RSAImmedPub_t HWCryptoHook_RSAImmedPub;
+
+typedef
+int HWCryptoHook_ModExpCRT_t(HWCryptoHook_ContextHandle hwctx,
+                             HWCryptoHook_MPI a,
+                             HWCryptoHook_MPI p,
+                             HWCryptoHook_MPI q,
+                             HWCryptoHook_MPI dmp1,
+                             HWCryptoHook_MPI dmq1,
+                             HWCryptoHook_MPI iqmp,
+                             HWCryptoHook_MPI * r,
+                             const HWCryptoHook_ErrMsgBuf * errors);
+extern HWCryptoHook_ModExpCRT_t HWCryptoHook_ModExpCRT;
+
+typedef
+int HWCryptoHook_RSAImmedPriv_t(HWCryptoHook_ContextHandle hwctx,
+                                HWCryptoHook_MPI m,
+                                HWCryptoHook_MPI p,
+                                HWCryptoHook_MPI q,
+                                HWCryptoHook_MPI dmp1,
+                                HWCryptoHook_MPI dmq1,
+                                HWCryptoHook_MPI iqmp,
+                                HWCryptoHook_MPI * r,
+                                const HWCryptoHook_ErrMsgBuf * errors);
+extern HWCryptoHook_RSAImmedPriv_t HWCryptoHook_RSAImmedPriv;
+
+/*-
+ * The RSAImmed* and ModExp* functions may return E_FAILED or
+ * E_FALLBACK for failure.
+ *
+ * E_FAILED means the failure is permanent and definite and there
+ *    should be no attempt to fall back to software.  (Eg, for some
+ *    applications, which support only the acceleration-only
+ *    functions, the `key material' may actually be an encoded key
+ *    identifier, and doing the operation in software would give wrong
+ *    answers.)
+ *
+ * E_FALLBACK means that doing the computation in software would seem
+ *    reasonable.  If an application pays attention to this and is
+ *    able to fall back, it should also set the Fallback init flags.
+ */
+
+typedef
+int HWCryptoHook_RSALoadKey_t(HWCryptoHook_ContextHandle hwctx,
+                              const char *key_ident,
+                              HWCryptoHook_RSAKeyHandle * keyhandle_r,
+                              const HWCryptoHook_ErrMsgBuf * errors,
+                              HWCryptoHook_PassphraseContext * ppctx);
+extern HWCryptoHook_RSALoadKey_t HWCryptoHook_RSALoadKey;
+/*-
+ * The key_ident is a null-terminated string configured by the
+ * user via the application's usual configuration mechanisms.
+ * It is provided to the user by the crypto provider's key management
+ * system.  The user must be able to enter at least any string of between
+ * 1 and 1023 characters inclusive, consisting of printable 7-bit
+ * ASCII characters.  The provider should avoid using
+ * any characters except alphanumerics and the punctuation
+ * characters  _ - + . / @ ~  (the user is expected to be able
+ * to enter these without quoting).  The string may be case-sensitive.
+ * The application may allow the user to enter other NULL-terminated strings,
+ * and the provider must cope (returning an error if the string is not
+ * valid).
+ *
+ * If the key does not exist, no error is recorded and 0 is returned;
+ * keyhandle_r will be set to 0 instead of to a key handle.
+ */
+
+typedef
+int HWCryptoHook_RSAGetPublicKey_t(HWCryptoHook_RSAKeyHandle k,
+                                   HWCryptoHook_MPI * n,
+                                   HWCryptoHook_MPI * e,
+                                   const HWCryptoHook_ErrMsgBuf * errors);
+extern HWCryptoHook_RSAGetPublicKey_t HWCryptoHook_RSAGetPublicKey;
+/*-
+ * The crypto plugin will not store certificates.
+ *
+ * Although this function for acquiring the public key value is
+ * provided, it is not the purpose of this API to deal fully with the
+ * handling of the public key.
+ *
+ * It is expected that the crypto supplier's key generation program
+ * will provide general facilities for producing X.509
+ * self-certificates and certificate requests in PEM format.  These
+ * will be given to the user so that they can configure them in the
+ * application, send them to CAs, or whatever.
+ *
+ * In case this kind of certificate handling is not appropriate, the
+ * crypto supplier's key generation program should be able to be
+ * configured not to generate such a self-certificate or certificate
+ * request.  Then the application will need to do all of this, and
+ * will need to store and handle the public key and certificates
+ * itself.
+ */
+
+typedef
+int HWCryptoHook_RSAUnloadKey_t(HWCryptoHook_RSAKeyHandle k,
+                                const HWCryptoHook_ErrMsgBuf * errors);
+extern HWCryptoHook_RSAUnloadKey_t HWCryptoHook_RSAUnloadKey;
+/* Might fail due to locking problems, or other serious internal problems. */
+
+typedef
+int HWCryptoHook_RSA_t(HWCryptoHook_MPI m,
+                       HWCryptoHook_RSAKeyHandle k,
+                       HWCryptoHook_MPI * r,
+                       const HWCryptoHook_ErrMsgBuf * errors);
+extern HWCryptoHook_RSA_t HWCryptoHook_RSA;
+/* RSA private key operation (sign or decrypt) - raw, unpadded. */
+
+#endif                          /* HWCRYPTOHOOK_H */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/bio.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/bio.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/bio.h	(revision 331)
@@ -0,0 +1,26 @@
+/*
+ * 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 <openssl/bio.h>
+
+struct bio_method_st {
+    int type;
+    const char *name;
+    int (*bwrite) (BIO *, const char *, int);
+    int (*bread) (BIO *, char *, int);
+    int (*bputs) (BIO *, const char *);
+    int (*bgets) (BIO *, char *, int);
+    long (*ctrl) (BIO *, int, long, void *);
+    int (*create) (BIO *);
+    int (*destroy) (BIO *);
+    long (*callback_ctrl) (BIO *, int, bio_info_cb *);
+};
+
+void bio_free_ex_data(BIO *bio);
+void bio_cleanup(void);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/comp.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/comp.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/comp.h	(revision 331)
@@ -0,0 +1,12 @@
+/*
+ * 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 <openssl/comp.h>
+
+void comp_zlib_cleanup_int(void);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/conf.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/conf.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/conf.h	(revision 331)
@@ -0,0 +1,32 @@
+/*
+ * 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
+ */
+
+#ifndef HEADER_INTERNAL_CONF_H
+# define HEADER_INTERNAL_CONF_H
+
+#include <openssl/conf.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct ossl_init_settings_st {
+    char *appname;
+};
+
+void openssl_config_int(const char *appname);
+void openssl_no_config_int(void);
+void conf_modules_free_int(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/constant_time_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/constant_time_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/constant_time_locl.h	(revision 331)
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2014-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
+ */
+
+#ifndef HEADER_CONSTANT_TIME_LOCL_H
+# define HEADER_CONSTANT_TIME_LOCL_H
+
+# include <openssl/e_os2.h>              /* For 'ossl_inline' */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-
+ * The boolean methods return a bitmask of all ones (0xff...f) for true
+ * and 0 for false. This is useful for choosing a value based on the result
+ * of a conditional in constant time. For example,
+ *
+ * if (a < b) {
+ *   c = a;
+ * } else {
+ *   c = b;
+ * }
+ *
+ * can be written as
+ *
+ * unsigned int lt = constant_time_lt(a, b);
+ * c = constant_time_select(lt, a, b);
+ */
+
+/*
+ * Returns the given value with the MSB copied to all the other
+ * bits. Uses the fact that arithmetic shift shifts-in the sign bit.
+ * However, this is not ensured by the C standard so you may need to
+ * replace this with something else on odd CPUs.
+ */
+static ossl_inline unsigned int constant_time_msb(unsigned int a);
+
+/*
+ * Returns 0xff..f if a < b and 0 otherwise.
+ */
+static ossl_inline unsigned int constant_time_lt(unsigned int a,
+                                                 unsigned int b);
+/* Convenience method for getting an 8-bit mask. */
+static ossl_inline unsigned char constant_time_lt_8(unsigned int a,
+                                                    unsigned int b);
+
+/*
+ * Returns 0xff..f if a >= b and 0 otherwise.
+ */
+static ossl_inline unsigned int constant_time_ge(unsigned int a,
+                                                 unsigned int b);
+/* Convenience method for getting an 8-bit mask. */
+static ossl_inline unsigned char constant_time_ge_8(unsigned int a,
+                                                    unsigned int b);
+
+/*
+ * Returns 0xff..f if a == 0 and 0 otherwise.
+ */
+static ossl_inline unsigned int constant_time_is_zero(unsigned int a);
+/* Convenience method for getting an 8-bit mask. */
+static ossl_inline unsigned char constant_time_is_zero_8(unsigned int a);
+
+/*
+ * Returns 0xff..f if a == b and 0 otherwise.
+ */
+static ossl_inline unsigned int constant_time_eq(unsigned int a,
+                                                 unsigned int b);
+/* Convenience method for getting an 8-bit mask. */
+static ossl_inline unsigned char constant_time_eq_8(unsigned int a,
+                                                    unsigned int b);
+/* Signed integers. */
+static ossl_inline unsigned int constant_time_eq_int(int a, int b);
+/* Convenience method for getting an 8-bit mask. */
+static ossl_inline unsigned char constant_time_eq_int_8(int a, int b);
+
+/*-
+ * Returns (mask & a) | (~mask & b).
+ *
+ * When |mask| is all 1s or all 0s (as returned by the methods above),
+ * the select methods return either |a| (if |mask| is nonzero) or |b|
+ * (if |mask| is zero).
+ */
+static ossl_inline unsigned int constant_time_select(unsigned int mask,
+                                                     unsigned int a,
+                                                     unsigned int b);
+/* Convenience method for unsigned chars. */
+static ossl_inline unsigned char constant_time_select_8(unsigned char mask,
+                                                        unsigned char a,
+                                                        unsigned char b);
+/* Convenience method for signed integers. */
+static ossl_inline int constant_time_select_int(unsigned int mask, int a,
+                                                int b);
+
+static ossl_inline unsigned int constant_time_msb(unsigned int a)
+{
+    return 0 - (a >> (sizeof(a) * 8 - 1));
+}
+
+static ossl_inline unsigned int constant_time_lt(unsigned int a,
+                                                 unsigned int b)
+{
+    return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b)));
+}
+
+static ossl_inline unsigned char constant_time_lt_8(unsigned int a,
+                                                    unsigned int b)
+{
+    return (unsigned char)(constant_time_lt(a, b));
+}
+
+static ossl_inline unsigned int constant_time_ge(unsigned int a,
+                                                 unsigned int b)
+{
+    return ~constant_time_lt(a, b);
+}
+
+static ossl_inline unsigned char constant_time_ge_8(unsigned int a,
+                                                    unsigned int b)
+{
+    return (unsigned char)(constant_time_ge(a, b));
+}
+
+static ossl_inline unsigned int constant_time_is_zero(unsigned int a)
+{
+    return constant_time_msb(~a & (a - 1));
+}
+
+static ossl_inline unsigned char constant_time_is_zero_8(unsigned int a)
+{
+    return (unsigned char)(constant_time_is_zero(a));
+}
+
+static ossl_inline unsigned int constant_time_eq(unsigned int a,
+                                                 unsigned int b)
+{
+    return constant_time_is_zero(a ^ b);
+}
+
+static ossl_inline unsigned char constant_time_eq_8(unsigned int a,
+                                                    unsigned int b)
+{
+    return (unsigned char)(constant_time_eq(a, b));
+}
+
+static ossl_inline unsigned int constant_time_eq_int(int a, int b)
+{
+    return constant_time_eq((unsigned)(a), (unsigned)(b));
+}
+
+static ossl_inline unsigned char constant_time_eq_int_8(int a, int b)
+{
+    return constant_time_eq_8((unsigned)(a), (unsigned)(b));
+}
+
+static ossl_inline unsigned int constant_time_select(unsigned int mask,
+                                                     unsigned int a,
+                                                     unsigned int b)
+{
+    return (mask & a) | (~mask & b);
+}
+
+static ossl_inline unsigned char constant_time_select_8(unsigned char mask,
+                                                        unsigned char a,
+                                                        unsigned char b)
+{
+    return (unsigned char)(constant_time_select(mask, a, b));
+}
+
+static ossl_inline int constant_time_select_int(unsigned int mask, int a,
+                                                int b)
+{
+    return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b)));
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif                          /* HEADER_CONSTANT_TIME_LOCL_H */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/dane.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/dane.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/dane.h	(revision 331)
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2015-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
+ */
+
+#ifndef HEADER_INTERNAL_DANE_H
+#define HEADER_INTERNAL_DANE_H
+
+#include <openssl/safestack.h>
+
+/*-
+ * Certificate usages:
+ * https://tools.ietf.org/html/rfc6698#section-2.1.1
+ */
+#define DANETLS_USAGE_PKIX_TA   0
+#define DANETLS_USAGE_PKIX_EE   1
+#define DANETLS_USAGE_DANE_TA   2
+#define DANETLS_USAGE_DANE_EE   3
+#define DANETLS_USAGE_LAST      DANETLS_USAGE_DANE_EE
+
+/*-
+ * Selectors:
+ * https://tools.ietf.org/html/rfc6698#section-2.1.2
+ */
+#define DANETLS_SELECTOR_CERT   0
+#define DANETLS_SELECTOR_SPKI   1
+#define DANETLS_SELECTOR_LAST   DANETLS_SELECTOR_SPKI
+
+/*-
+ * Matching types:
+ * https://tools.ietf.org/html/rfc6698#section-2.1.3
+ */
+#define DANETLS_MATCHING_FULL   0
+#define DANETLS_MATCHING_2256   1
+#define DANETLS_MATCHING_2512   2
+#define DANETLS_MATCHING_LAST   DANETLS_MATCHING_2512
+
+typedef struct danetls_record_st {
+    uint8_t usage;
+    uint8_t selector;
+    uint8_t mtype;
+    unsigned char *data;
+    size_t dlen;
+    EVP_PKEY *spki;
+} danetls_record;
+
+DEFINE_STACK_OF(danetls_record)
+
+/*
+ * Shared DANE context
+ */
+struct dane_ctx_st {
+    const EVP_MD  **mdevp;      /* mtype -> digest */
+    uint8_t        *mdord;      /* mtype -> preference */
+    uint8_t         mdmax;      /* highest supported mtype */
+    unsigned long   flags;      /* feature bitmask */
+};
+
+/*
+ * Per connection DANE state
+ */
+struct ssl_dane_st {
+    struct dane_ctx_st *dctx;
+    STACK_OF(danetls_record) *trecs;
+    STACK_OF(X509) *certs;      /* DANE-TA(2) Cert(0) Full(0) certs */
+    danetls_record *mtlsa;      /* Matching TLSA record */
+    X509           *mcert;      /* DANE matched cert */
+    uint32_t        umask;      /* Usages present */
+    int             mdpth;      /* Depth of matched cert */
+    int             pdpth;      /* Depth of PKIX trust */
+    unsigned long   flags;      /* feature bitmask */
+};
+
+#define DANETLS_ENABLED(dane)  \
+    ((dane) != NULL && sk_danetls_record_num((dane)->trecs) > 0)
+
+#define DANETLS_USAGE_BIT(u)   (((uint32_t)1) << u)
+
+#define DANETLS_PKIX_TA_MASK (DANETLS_USAGE_BIT(DANETLS_USAGE_PKIX_TA))
+#define DANETLS_PKIX_EE_MASK (DANETLS_USAGE_BIT(DANETLS_USAGE_PKIX_EE))
+#define DANETLS_DANE_TA_MASK (DANETLS_USAGE_BIT(DANETLS_USAGE_DANE_TA))
+#define DANETLS_DANE_EE_MASK (DANETLS_USAGE_BIT(DANETLS_USAGE_DANE_EE))
+
+#define DANETLS_PKIX_MASK (DANETLS_PKIX_TA_MASK | DANETLS_PKIX_EE_MASK)
+#define DANETLS_DANE_MASK (DANETLS_DANE_TA_MASK | DANETLS_DANE_EE_MASK)
+#define DANETLS_TA_MASK (DANETLS_PKIX_TA_MASK | DANETLS_DANE_TA_MASK)
+#define DANETLS_EE_MASK (DANETLS_PKIX_EE_MASK | DANETLS_DANE_EE_MASK)
+
+#define DANETLS_HAS_PKIX(dane) ((dane) && ((dane)->umask & DANETLS_PKIX_MASK))
+#define DANETLS_HAS_DANE(dane) ((dane) && ((dane)->umask & DANETLS_DANE_MASK))
+#define DANETLS_HAS_TA(dane)   ((dane) && ((dane)->umask & DANETLS_TA_MASK))
+#define DANETLS_HAS_EE(dane)   ((dane) && ((dane)->umask & DANETLS_EE_MASK))
+
+#define DANETLS_HAS_PKIX_TA(dane) ((dane)&&((dane)->umask & DANETLS_PKIX_TA_MASK))
+#define DANETLS_HAS_PKIX_EE(dane) ((dane)&&((dane)->umask & DANETLS_PKIX_EE_MASK))
+#define DANETLS_HAS_DANE_TA(dane) ((dane)&&((dane)->umask & DANETLS_DANE_TA_MASK))
+#define DANETLS_HAS_DANE_EE(dane) ((dane)&&((dane)->umask & DANETLS_DANE_EE_MASK))
+
+#endif /* HEADER_INTERNAL_DANE_H */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/dso.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/dso.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/dso.h	(revision 331)
@@ -0,0 +1,239 @@
+/*
+ * Copyright 2000-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
+ */
+
+#ifndef HEADER_DSO_H
+# define HEADER_DSO_H
+
+# include <openssl/crypto.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* These values are used as commands to DSO_ctrl() */
+# define DSO_CTRL_GET_FLAGS      1
+# define DSO_CTRL_SET_FLAGS      2
+# define DSO_CTRL_OR_FLAGS       3
+
+/*
+ * By default, DSO_load() will translate the provided filename into a form
+ * typical for the platform using the dso_name_converter function of the
+ * method. Eg. win32 will transform "blah" into "blah.dll", and dlfcn will
+ * transform it into "libblah.so". This callback could even utilise the
+ * DSO_METHOD's converter too if it only wants to override behaviour for
+ * one or two possible DSO methods. However, the following flag can be
+ * set in a DSO to prevent *any* native name-translation at all - eg. if
+ * the caller has prompted the user for a path to a driver library so the
+ * filename should be interpreted as-is.
+ */
+# define DSO_FLAG_NO_NAME_TRANSLATION            0x01
+/*
+ * An extra flag to give if only the extension should be added as
+ * translation.  This is obviously only of importance on Unix and other
+ * operating systems where the translation also may prefix the name with
+ * something, like 'lib', and ignored everywhere else. This flag is also
+ * ignored if DSO_FLAG_NO_NAME_TRANSLATION is used at the same time.
+ */
+# define DSO_FLAG_NAME_TRANSLATION_EXT_ONLY      0x02
+
+/*
+ * Don't unload the DSO when we call DSO_free()
+ */
+# define DSO_FLAG_NO_UNLOAD_ON_FREE              0x04
+/*
+ * The following flag controls the translation of symbol names to upper case.
+ * This is currently only being implemented for OpenVMS.
+ */
+# define DSO_FLAG_UPCASE_SYMBOL                  0x10
+
+/*
+ * This flag loads the library with public symbols. Meaning: The exported
+ * symbols of this library are public to all libraries loaded after this
+ * library. At the moment only implemented in unix.
+ */
+# define DSO_FLAG_GLOBAL_SYMBOLS                 0x20
+
+typedef void (*DSO_FUNC_TYPE) (void);
+
+typedef struct dso_st DSO;
+typedef struct dso_meth_st DSO_METHOD;
+
+/*
+ * The function prototype used for method functions (or caller-provided
+ * callbacks) that transform filenames. They are passed a DSO structure
+ * pointer (or NULL if they are to be used independently of a DSO object) and
+ * a filename to transform. They should either return NULL (if there is an
+ * error condition) or a newly allocated string containing the transformed
+ * form that the caller will need to free with OPENSSL_free() when done.
+ */
+typedef char *(*DSO_NAME_CONVERTER_FUNC)(DSO *, const char *);
+/*
+ * The function prototype used for method functions (or caller-provided
+ * callbacks) that merge two file specifications. They are passed a DSO
+ * structure pointer (or NULL if they are to be used independently of a DSO
+ * object) and two file specifications to merge. They should either return
+ * NULL (if there is an error condition) or a newly allocated string
+ * containing the result of merging that the caller will need to free with
+ * OPENSSL_free() when done. Here, merging means that bits and pieces are
+ * taken from each of the file specifications and added together in whatever
+ * fashion that is sensible for the DSO method in question.  The only rule
+ * that really applies is that if the two specification contain pieces of the
+ * same type, the copy from the first string takes priority.  One could see
+ * it as the first specification is the one given by the user and the second
+ * being a bunch of defaults to add on if they're missing in the first.
+ */
+typedef char *(*DSO_MERGER_FUNC)(DSO *, const char *, const char *);
+
+DSO *DSO_new(void);
+int DSO_free(DSO *dso);
+int DSO_flags(DSO *dso);
+int DSO_up_ref(DSO *dso);
+long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg);
+
+/*
+ * These functions can be used to get/set the platform-independent filename
+ * used for a DSO. NB: set will fail if the DSO is already loaded.
+ */
+const char *DSO_get_filename(DSO *dso);
+int DSO_set_filename(DSO *dso, const char *filename);
+/*
+ * This function will invoke the DSO's name_converter callback to translate a
+ * filename, or if the callback isn't set it will instead use the DSO_METHOD's
+ * converter. If "filename" is NULL, the "filename" in the DSO itself will be
+ * used. If the DSO_FLAG_NO_NAME_TRANSLATION flag is set, then the filename is
+ * simply duplicated. NB: This function is usually called from within a
+ * DSO_METHOD during the processing of a DSO_load() call, and is exposed so
+ * that caller-created DSO_METHODs can do the same thing. A non-NULL return
+ * value will need to be OPENSSL_free()'d.
+ */
+char *DSO_convert_filename(DSO *dso, const char *filename);
+/*
+ * This function will invoke the DSO's merger callback to merge two file
+ * specifications, or if the callback isn't set it will instead use the
+ * DSO_METHOD's merger.  A non-NULL return value will need to be
+ * OPENSSL_free()'d.
+ */
+char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2);
+
+/*
+ * The all-singing all-dancing load function, you normally pass NULL for the
+ * first and third parameters. Use DSO_up_ref and DSO_free for subsequent
+ * reference count handling. Any flags passed in will be set in the
+ * constructed DSO after its init() function but before the load operation.
+ * If 'dso' is non-NULL, 'flags' is ignored.
+ */
+DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags);
+
+/* This function binds to a function inside a shared library. */
+DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname);
+
+/*
+ * This method is the default, but will beg, borrow, or steal whatever method
+ * should be the default on any particular platform (including
+ * DSO_METH_null() if necessary).
+ */
+DSO_METHOD *DSO_METHOD_openssl(void);
+
+/*
+ * This function writes null-terminated pathname of DSO module containing
+ * 'addr' into 'sz' large caller-provided 'path' and returns the number of
+ * characters [including trailing zero] written to it. If 'sz' is 0 or
+ * negative, 'path' is ignored and required amount of charachers [including
+ * trailing zero] to accommodate pathname is returned. If 'addr' is NULL, then
+ * pathname of cryptolib itself is returned. Negative or zero return value
+ * denotes error.
+ */
+int DSO_pathbyaddr(void *addr, char *path, int sz);
+
+/*
+ * Like DSO_pathbyaddr() but instead returns a handle to the DSO for the symbol
+ * or NULL on error.
+ */
+DSO *DSO_dsobyaddr(void *addr, int flags);
+
+/*
+ * This function should be used with caution! It looks up symbols in *all*
+ * loaded modules and if module gets unloaded by somebody else attempt to
+ * dereference the pointer is doomed to have fatal consequences. Primary
+ * usage for this function is to probe *core* system functionality, e.g.
+ * check if getnameinfo(3) is available at run-time without bothering about
+ * OS-specific details such as libc.so.versioning or where does it actually
+ * reside: in libc itself or libsocket.
+ */
+void *DSO_global_lookup(const char *name);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_DSO_strings(void);
+
+/* Error codes for the DSO functions. */
+
+/* Function codes. */
+# define DSO_F_DLFCN_BIND_FUNC                            100
+# define DSO_F_DLFCN_LOAD                                 102
+# define DSO_F_DLFCN_MERGER                               130
+# define DSO_F_DLFCN_NAME_CONVERTER                       123
+# define DSO_F_DLFCN_UNLOAD                               103
+# define DSO_F_DL_BIND_FUNC                               104
+# define DSO_F_DL_LOAD                                    106
+# define DSO_F_DL_MERGER                                  131
+# define DSO_F_DL_NAME_CONVERTER                          124
+# define DSO_F_DL_UNLOAD                                  107
+# define DSO_F_DSO_BIND_FUNC                              108
+# define DSO_F_DSO_CONVERT_FILENAME                       126
+# define DSO_F_DSO_CTRL                                   110
+# define DSO_F_DSO_FREE                                   111
+# define DSO_F_DSO_GET_FILENAME                           127
+# define DSO_F_DSO_GLOBAL_LOOKUP                          139
+# define DSO_F_DSO_LOAD                                   112
+# define DSO_F_DSO_MERGE                                  132
+# define DSO_F_DSO_NEW_METHOD                             113
+# define DSO_F_DSO_PATHBYADDR                             105
+# define DSO_F_DSO_SET_FILENAME                           129
+# define DSO_F_DSO_UP_REF                                 114
+# define DSO_F_VMS_BIND_SYM                               115
+# define DSO_F_VMS_LOAD                                   116
+# define DSO_F_VMS_MERGER                                 133
+# define DSO_F_VMS_UNLOAD                                 117
+# define DSO_F_WIN32_BIND_FUNC                            101
+# define DSO_F_WIN32_GLOBALLOOKUP                         142
+# define DSO_F_WIN32_JOINER                               135
+# define DSO_F_WIN32_LOAD                                 120
+# define DSO_F_WIN32_MERGER                               134
+# define DSO_F_WIN32_NAME_CONVERTER                       125
+# define DSO_F_WIN32_PATHBYADDR                           109
+# define DSO_F_WIN32_SPLITTER                             136
+# define DSO_F_WIN32_UNLOAD                               121
+
+/* Reason codes. */
+# define DSO_R_CTRL_FAILED                                100
+# define DSO_R_DSO_ALREADY_LOADED                         110
+# define DSO_R_EMPTY_FILE_STRUCTURE                       113
+# define DSO_R_FAILURE                                    114
+# define DSO_R_FILENAME_TOO_BIG                           101
+# define DSO_R_FINISH_FAILED                              102
+# define DSO_R_INCORRECT_FILE_SYNTAX                      115
+# define DSO_R_LOAD_FAILED                                103
+# define DSO_R_NAME_TRANSLATION_FAILED                    109
+# define DSO_R_NO_FILENAME                                111
+# define DSO_R_NULL_HANDLE                                104
+# define DSO_R_SET_FILENAME_FAILED                        112
+# define DSO_R_STACK_ERROR                                105
+# define DSO_R_SYM_FAILURE                                106
+# define DSO_R_UNLOAD_FAILED                              107
+# define DSO_R_UNSUPPORTED                                108
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/err.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/err.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/err.h	(revision 331)
@@ -0,0 +1,15 @@
+/*
+ * 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
+ */
+
+#ifndef INTERNAL_ERR_H
+# define INTERNAL_ERR_H
+
+void err_free_strings_int(void);
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/numbers.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/numbers.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/numbers.h	(revision 331)
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2015-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
+ */
+
+#ifndef HEADER_NUMBERS_H
+# define HEADER_NUMBERS_H
+
+# include <limits.h>
+
+# if (-1 & 3) == 0x03		/* Two's complement */
+
+#  define __MAXUINT__(T) ((T) -1)
+#  define __MAXINT__(T) ((T) ((((T) 1) << ((sizeof(T) * CHAR_BIT) - 1)) ^ __MAXUINT__(T)))
+#  define __MININT__(T) (-__MAXINT__(T) - 1)
+
+# elif (-1 & 3) == 0x02		/* One's complement */
+
+#  define __MAXUINT__(T) (((T) -1) + 1)
+#  define __MAXINT__(T) ((T) ((((T) 1) << ((sizeof(T) * CHAR_BIT) - 1)) ^ __MAXUINT__(T)))
+#  define __MININT__(T) (-__MAXINT__(T))
+
+# elif (-1 & 3) == 0x01		/* Sign/magnitude */
+
+#  define __MAXINT__(T) ((T) (((((T) 1) << ((sizeof(T) * CHAR_BIT) - 2)) - 1) | (((T) 1) << ((sizeof(T) * CHAR_BIT) - 2))))
+#  define __MAXUINT__(T) ((T) (__MAXINT__(T) | (((T) 1) << ((sizeof(T) * CHAR_BIT) - 1))))
+#  define __MININT__(T) (-__MAXINT__(T))
+
+# else
+
+#  error "do not know the integer encoding on this architecture"
+
+# endif
+
+# ifndef INT8_MAX
+#  define INT8_MIN __MININT__(int8_t)
+#  define INT8_MAX __MAXINT__(int8_t)
+#  define UINT8_MAX __MAXUINT__(uint8_t)
+# endif
+
+# ifndef INT16_MAX
+#  define INT16_MIN __MININT__(int16_t)
+#  define INT16_MAX __MAXINT__(int16_t)
+#  define UINT16_MAX __MAXUINT__(uint16_t)
+# endif
+
+# ifndef INT32_MAX
+#  define INT32_MIN __MININT__(int32_t)
+#  define INT32_MAX __MAXINT__(int32_t)
+#  define UINT32_MAX __MAXUINT__(uint32_t)
+# endif
+
+# ifndef INT64_MAX
+#  define INT64_MIN __MININT__(int64_t)
+#  define INT64_MAX __MAXINT__(int64_t)
+#  define UINT64_MAX __MAXUINT__(uint64_t)
+# endif
+
+# ifndef SIZE_MAX
+#  define SIZE_MAX __MAXUINT__(size_t)
+# endif
+
+#endif
+
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/o_dir.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/o_dir.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/o_dir.h	(revision 331)
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2004-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
+ */
+
+/*
+ * Copied from Richard Levitte's (richard@levitte.org) LP library.  All
+ * symbol names have been changed, with permission from the author.
+ */
+
+/* $LP: LPlib/source/LPdir.h,v 1.1 2004/06/14 08:56:04 _cvs_levitte Exp $ */
+/*
+ * Copyright (c) 2004, Richard Levitte <richard@levitte.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef O_DIR_H
+# define O_DIR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct OPENSSL_dir_context_st OPENSSL_DIR_CTX;
+
+  /*
+   * returns NULL on error or end-of-directory. If it is end-of-directory,
+   * errno will be zero
+   */
+const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx, const char *directory);
+  /* returns 1 on success, 0 on error */
+int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif                          /* LPDIR_H */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/o_str.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/o_str.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/o_str.h	(revision 331)
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2003-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
+ */
+
+#ifndef HEADER_O_STR_H
+# define HEADER_O_STR_H
+
+# include <stddef.h>            /* to get size_t */
+
+int OPENSSL_memcmp(const void *p1, const void *p2, size_t n);
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/thread_once.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/thread_once.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/internal/thread_once.h	(revision 331)
@@ -0,0 +1,45 @@
+/*
+ * Copyright 1995-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 <openssl/crypto.h>
+
+#define DEFINE_RUN_ONCE(init)                   \
+    static int init(void);                     \
+    int init##_ossl_ret_ = 0;                   \
+    void init##_ossl_(void)                     \
+    {                                           \
+        init##_ossl_ret_ = init();              \
+    }                                           \
+    static int init(void)
+#define DECLARE_RUN_ONCE(init)                  \
+    extern int init##_ossl_ret_;                \
+    void init##_ossl_(void);
+
+#define DEFINE_RUN_ONCE_STATIC(init)            \
+    static int init(void);                     \
+    static int init##_ossl_ret_ = 0;            \
+    static void init##_ossl_(void)              \
+    {                                           \
+        init##_ossl_ret_ = init();              \
+    }                                           \
+    static int init(void)
+
+/*
+ * RUN_ONCE - use CRYPTO_THREAD_run_once, and check if the init succeeded
+ * @once: pointer to static object of type CRYPTO_ONCE
+ * @init: function name that was previously given to DEFINE_RUN_ONCE,
+ *        DEFINE_RUN_ONCE_STATIC or DECLARE_RUN_ONCE.  This function
+ *        must return 1 for success or 0 for failure.
+ *
+ * The return value is 1 on success (*) or 0 in case of error.
+ *
+ * (*) by convention, since the init function must return 1 on success.
+ */
+#define RUN_ONCE(once, init)                                            \
+    (CRYPTO_THREAD_run_once(once, init##_ossl_) ? init##_ossl_ret_ : 0)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/__DECC_INCLUDE_EPILOGUE.H
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/__DECC_INCLUDE_EPILOGUE.H	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/__DECC_INCLUDE_EPILOGUE.H	(revision 331)
@@ -0,0 +1,16 @@
+/*
+ * 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
+ */
+
+/*
+ * This file is only used by HP C on VMS, and is included automatically
+ * after each header file from this directory
+ */
+
+/* restore state.  Must correspond to the save in __decc_include_prologue.h */
+#pragma names restore
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/__DECC_INCLUDE_PROLOGUE.H
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/__DECC_INCLUDE_PROLOGUE.H	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/__DECC_INCLUDE_PROLOGUE.H	(revision 331)
@@ -0,0 +1,20 @@
+/*
+ * 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
+ */
+
+/*
+ * This file is only used by HP C on VMS, and is included automatically
+ * after each header file from this directory
+ */
+
+/* save state */
+#pragma names save
+/* have the compiler shorten symbols larger than 31 chars to 23 chars
+ * followed by a 8 hex char CRC
+ */
+#pragma names as_is,shortened
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/aes.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/aes.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/aes.h	(revision 331)
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2002-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
+ */
+
+#ifndef HEADER_AES_H
+# define HEADER_AES_H
+
+# include <openssl/opensslconf.h>
+
+# include <stddef.h>
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+# define AES_ENCRYPT     1
+# define AES_DECRYPT     0
+
+/*
+ * Because array size can't be a const in C, the following two are macros.
+ * Both sizes are in bytes.
+ */
+# define AES_MAXNR 14
+# define AES_BLOCK_SIZE 16
+
+/* This should be a hidden type, but EVP requires that the size be known */
+struct aes_key_st {
+# ifdef AES_LONG
+    unsigned long rd_key[4 * (AES_MAXNR + 1)];
+# else
+    unsigned int rd_key[4 * (AES_MAXNR + 1)];
+# endif
+    int rounds;
+};
+typedef struct aes_key_st AES_KEY;
+
+const char *AES_options(void);
+
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+                        AES_KEY *key);
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+                        AES_KEY *key);
+
+void AES_encrypt(const unsigned char *in, unsigned char *out,
+                 const AES_KEY *key);
+void AES_decrypt(const unsigned char *in, unsigned char *out,
+                 const AES_KEY *key);
+
+void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                     const AES_KEY *key, const int enc);
+void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                     size_t length, const AES_KEY *key,
+                     unsigned char *ivec, const int enc);
+void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+                        size_t length, const AES_KEY *key,
+                        unsigned char *ivec, int *num, const int enc);
+void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
+                      size_t length, const AES_KEY *key,
+                      unsigned char *ivec, int *num, const int enc);
+void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
+                      size_t length, const AES_KEY *key,
+                      unsigned char *ivec, int *num, const int enc);
+void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+                        size_t length, const AES_KEY *key,
+                        unsigned char *ivec, int *num);
+/* NB: the IV is _two_ blocks long */
+void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
+                     size_t length, const AES_KEY *key,
+                     unsigned char *ivec, const int enc);
+/* NB: the IV is _four_ blocks long */
+void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
+                        size_t length, const AES_KEY *key,
+                        const AES_KEY *key2, const unsigned char *ivec,
+                        const int enc);
+
+int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
+                 unsigned char *out,
+                 const unsigned char *in, unsigned int inlen);
+int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
+                   unsigned char *out,
+                   const unsigned char *in, unsigned int inlen);
+
+
+# ifdef  __cplusplus
+}
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/asn1.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/asn1.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/asn1.h	(revision 331)
@@ -0,0 +1,1096 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_ASN1_H
+# define HEADER_ASN1_H
+
+# include <time.h>
+# include <openssl/e_os2.h>
+# include <openssl/opensslconf.h>
+# include <openssl/bio.h>
+# include <openssl/stack.h>
+# include <openssl/safestack.h>
+
+# include <openssl/symhacks.h>
+
+# include <openssl/ossl_typ.h>
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  include <openssl/bn.h>
+# endif
+
+# ifdef OPENSSL_BUILD_SHLIBCRYPTO
+#  undef OPENSSL_EXTERN
+#  define OPENSSL_EXTERN OPENSSL_EXPORT
+# endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define V_ASN1_UNIVERSAL                0x00
+# define V_ASN1_APPLICATION              0x40
+# define V_ASN1_CONTEXT_SPECIFIC         0x80
+# define V_ASN1_PRIVATE                  0xc0
+
+# define V_ASN1_CONSTRUCTED              0x20
+# define V_ASN1_PRIMITIVE_TAG            0x1f
+# define V_ASN1_PRIMATIVE_TAG            0x1f
+
+# define V_ASN1_APP_CHOOSE               -2/* let the recipient choose */
+# define V_ASN1_OTHER                    -3/* used in ASN1_TYPE */
+# define V_ASN1_ANY                      -4/* used in ASN1 template code */
+
+# define V_ASN1_UNDEF                    -1
+/* ASN.1 tag values */
+# define V_ASN1_EOC                      0
+# define V_ASN1_BOOLEAN                  1 /**/
+# define V_ASN1_INTEGER                  2
+# define V_ASN1_BIT_STRING               3
+# define V_ASN1_OCTET_STRING             4
+# define V_ASN1_NULL                     5
+# define V_ASN1_OBJECT                   6
+# define V_ASN1_OBJECT_DESCRIPTOR        7
+# define V_ASN1_EXTERNAL                 8
+# define V_ASN1_REAL                     9
+# define V_ASN1_ENUMERATED               10
+# define V_ASN1_UTF8STRING               12
+# define V_ASN1_SEQUENCE                 16
+# define V_ASN1_SET                      17
+# define V_ASN1_NUMERICSTRING            18 /**/
+# define V_ASN1_PRINTABLESTRING          19
+# define V_ASN1_T61STRING                20
+# define V_ASN1_TELETEXSTRING            20/* alias */
+# define V_ASN1_VIDEOTEXSTRING           21 /**/
+# define V_ASN1_IA5STRING                22
+# define V_ASN1_UTCTIME                  23
+# define V_ASN1_GENERALIZEDTIME          24 /**/
+# define V_ASN1_GRAPHICSTRING            25 /**/
+# define V_ASN1_ISO64STRING              26 /**/
+# define V_ASN1_VISIBLESTRING            26/* alias */
+# define V_ASN1_GENERALSTRING            27 /**/
+# define V_ASN1_UNIVERSALSTRING          28 /**/
+# define V_ASN1_BMPSTRING                30
+
+/*
+ * NB the constants below are used internally by ASN1_INTEGER
+ * and ASN1_ENUMERATED to indicate the sign. They are *not* on
+ * the wire tag values.
+ */
+
+# define V_ASN1_NEG                      0x100
+# define V_ASN1_NEG_INTEGER              (2 | V_ASN1_NEG)
+# define V_ASN1_NEG_ENUMERATED           (10 | V_ASN1_NEG)
+
+/* For use with d2i_ASN1_type_bytes() */
+# define B_ASN1_NUMERICSTRING    0x0001
+# define B_ASN1_PRINTABLESTRING  0x0002
+# define B_ASN1_T61STRING        0x0004
+# define B_ASN1_TELETEXSTRING    0x0004
+# define B_ASN1_VIDEOTEXSTRING   0x0008
+# define B_ASN1_IA5STRING        0x0010
+# define B_ASN1_GRAPHICSTRING    0x0020
+# define B_ASN1_ISO64STRING      0x0040
+# define B_ASN1_VISIBLESTRING    0x0040
+# define B_ASN1_GENERALSTRING    0x0080
+# define B_ASN1_UNIVERSALSTRING  0x0100
+# define B_ASN1_OCTET_STRING     0x0200
+# define B_ASN1_BIT_STRING       0x0400
+# define B_ASN1_BMPSTRING        0x0800
+# define B_ASN1_UNKNOWN          0x1000
+# define B_ASN1_UTF8STRING       0x2000
+# define B_ASN1_UTCTIME          0x4000
+# define B_ASN1_GENERALIZEDTIME  0x8000
+# define B_ASN1_SEQUENCE         0x10000
+/* For use with ASN1_mbstring_copy() */
+# define MBSTRING_FLAG           0x1000
+# define MBSTRING_UTF8           (MBSTRING_FLAG)
+# define MBSTRING_ASC            (MBSTRING_FLAG|1)
+# define MBSTRING_BMP            (MBSTRING_FLAG|2)
+# define MBSTRING_UNIV           (MBSTRING_FLAG|4)
+# define SMIME_OLDMIME           0x400
+# define SMIME_CRLFEOL           0x800
+# define SMIME_STREAM            0x1000
+    struct X509_algor_st;
+DEFINE_STACK_OF(X509_ALGOR)
+
+# define ASN1_STRING_FLAG_BITS_LEFT 0x08/* Set if 0x07 has bits left value */
+/*
+ * This indicates that the ASN1_STRING is not a real value but just a place
+ * holder for the location where indefinite length constructed data should be
+ * inserted in the memory buffer
+ */
+# define ASN1_STRING_FLAG_NDEF 0x010
+
+/*
+ * This flag is used by the CMS code to indicate that a string is not
+ * complete and is a place holder for content when it had all been accessed.
+ * The flag will be reset when content has been written to it.
+ */
+
+# define ASN1_STRING_FLAG_CONT 0x020
+/*
+ * This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING
+ * type.
+ */
+# define ASN1_STRING_FLAG_MSTRING 0x040
+/* String is embedded and only content should be freed */
+# define ASN1_STRING_FLAG_EMBED 0x080
+/* This is the base type that holds just about everything :-) */
+struct asn1_string_st {
+    int length;
+    int type;
+    unsigned char *data;
+    /*
+     * The value of the following field depends on the type being held.  It
+     * is mostly being used for BIT_STRING so if the input data has a
+     * non-zero 'unused bits' value, it will be handled correctly
+     */
+    long flags;
+};
+
+/*
+ * ASN1_ENCODING structure: this is used to save the received encoding of an
+ * ASN1 type. This is useful to get round problems with invalid encodings
+ * which can break signatures.
+ */
+
+typedef struct ASN1_ENCODING_st {
+    unsigned char *enc;         /* DER encoding */
+    long len;                   /* Length of encoding */
+    int modified;               /* set to 1 if 'enc' is invalid */
+} ASN1_ENCODING;
+
+/* Used with ASN1 LONG type: if a long is set to this it is omitted */
+# define ASN1_LONG_UNDEF 0x7fffffffL
+
+# define STABLE_FLAGS_MALLOC     0x01
+/*
+ * A zero passed to ASN1_STRING_TABLE_new_add for the flags is interpreted
+ * as "don't change" and STABLE_FLAGS_MALLOC is always set. By setting
+ * STABLE_FLAGS_MALLOC only we can clear the existing value. Use the alias
+ * STABLE_FLAGS_CLEAR to reflect this.
+ */
+# define STABLE_FLAGS_CLEAR      STABLE_FLAGS_MALLOC
+# define STABLE_NO_MASK          0x02
+# define DIRSTRING_TYPE  \
+ (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING)
+# define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING)
+
+typedef struct asn1_string_table_st {
+    int nid;
+    long minsize;
+    long maxsize;
+    unsigned long mask;
+    unsigned long flags;
+} ASN1_STRING_TABLE;
+
+DEFINE_STACK_OF(ASN1_STRING_TABLE)
+
+/* size limits: this stuff is taken straight from RFC2459 */
+
+# define ub_name                         32768
+# define ub_common_name                  64
+# define ub_locality_name                128
+# define ub_state_name                   128
+# define ub_organization_name            64
+# define ub_organization_unit_name       64
+# define ub_title                        64
+# define ub_email_address                128
+
+/*
+ * Declarations for template structures: for full definitions see asn1t.h
+ */
+typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE;
+typedef struct ASN1_TLC_st ASN1_TLC;
+/* This is just an opaque pointer */
+typedef struct ASN1_VALUE_st ASN1_VALUE;
+
+/* Declare ASN1 functions: the implement macro in in asn1t.h */
+
+# define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type)
+
+# define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \
+        DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type)
+
+# define DECLARE_ASN1_FUNCTIONS_name(type, name) \
+        DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+        DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name)
+
+# define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \
+        DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+        DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name)
+
+# define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \
+        type *d2i_##name(type **a, const unsigned char **in, long len); \
+        int i2d_##name(type *a, unsigned char **out); \
+        DECLARE_ASN1_ITEM(itname)
+
+# define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \
+        type *d2i_##name(type **a, const unsigned char **in, long len); \
+        int i2d_##name(const type *a, unsigned char **out); \
+        DECLARE_ASN1_ITEM(name)
+
+# define DECLARE_ASN1_NDEF_FUNCTION(name) \
+        int i2d_##name##_NDEF(name *a, unsigned char **out);
+
+# define DECLARE_ASN1_FUNCTIONS_const(name) \
+        DECLARE_ASN1_ALLOC_FUNCTIONS(name) \
+        DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name)
+
+# define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+        type *name##_new(void); \
+        void name##_free(type *a);
+
+# define DECLARE_ASN1_PRINT_FUNCTION(stname) \
+        DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname)
+
+# define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \
+        int fname##_print_ctx(BIO *out, stname *x, int indent, \
+                                         const ASN1_PCTX *pctx);
+
+# define D2I_OF(type) type *(*)(type **,const unsigned char **,long)
+# define I2D_OF(type) int (*)(type *,unsigned char **)
+# define I2D_OF_const(type) int (*)(const type *,unsigned char **)
+
+# define CHECKED_D2I_OF(type, d2i) \
+    ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0)))
+# define CHECKED_I2D_OF(type, i2d) \
+    ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0)))
+# define CHECKED_NEW_OF(type, xnew) \
+    ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0)))
+# define CHECKED_PTR_OF(type, p) \
+    ((void*) (1 ? p : (type*)0))
+# define CHECKED_PPTR_OF(type, p) \
+    ((void**) (1 ? p : (type**)0))
+
+# define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long)
+# define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **)
+# define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type)
+
+TYPEDEF_D2I2D_OF(void);
+
+/*-
+ * The following macros and typedefs allow an ASN1_ITEM
+ * to be embedded in a structure and referenced. Since
+ * the ASN1_ITEM pointers need to be globally accessible
+ * (possibly from shared libraries) they may exist in
+ * different forms. On platforms that support it the
+ * ASN1_ITEM structure itself will be globally exported.
+ * Other platforms will export a function that returns
+ * an ASN1_ITEM pointer.
+ *
+ * To handle both cases transparently the macros below
+ * should be used instead of hard coding an ASN1_ITEM
+ * pointer in a structure.
+ *
+ * The structure will look like this:
+ *
+ * typedef struct SOMETHING_st {
+ *      ...
+ *      ASN1_ITEM_EXP *iptr;
+ *      ...
+ * } SOMETHING;
+ *
+ * It would be initialised as e.g.:
+ *
+ * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...};
+ *
+ * and the actual pointer extracted with:
+ *
+ * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr);
+ *
+ * Finally an ASN1_ITEM pointer can be extracted from an
+ * appropriate reference with: ASN1_ITEM_rptr(X509). This
+ * would be used when a function takes an ASN1_ITEM * argument.
+ *
+ */
+
+# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+/* ASN1_ITEM pointer exported type */
+typedef const ASN1_ITEM ASN1_ITEM_EXP;
+
+/* Macro to obtain ASN1_ITEM pointer from exported type */
+#  define ASN1_ITEM_ptr(iptr) (iptr)
+
+/* Macro to include ASN1_ITEM pointer from base type */
+#  define ASN1_ITEM_ref(iptr) (&(iptr##_it))
+
+#  define ASN1_ITEM_rptr(ref) (&(ref##_it))
+
+#  define DECLARE_ASN1_ITEM(name) \
+        OPENSSL_EXTERN const ASN1_ITEM name##_it;
+
+# else
+
+/*
+ * Platforms that can't easily handle shared global variables are declared as
+ * functions returning ASN1_ITEM pointers.
+ */
+
+/* ASN1_ITEM pointer exported type */
+typedef const ASN1_ITEM *ASN1_ITEM_EXP (void);
+
+/* Macro to obtain ASN1_ITEM pointer from exported type */
+#  define ASN1_ITEM_ptr(iptr) (iptr())
+
+/* Macro to include ASN1_ITEM pointer from base type */
+#  define ASN1_ITEM_ref(iptr) (iptr##_it)
+
+#  define ASN1_ITEM_rptr(ref) (ref##_it())
+
+#  define DECLARE_ASN1_ITEM(name) \
+        const ASN1_ITEM * name##_it(void);
+
+# endif
+
+/* Parameters used by ASN1_STRING_print_ex() */
+
+/*
+ * These determine which characters to escape: RFC2253 special characters,
+ * control characters and MSB set characters
+ */
+
+# define ASN1_STRFLGS_ESC_2253           1
+# define ASN1_STRFLGS_ESC_CTRL           2
+# define ASN1_STRFLGS_ESC_MSB            4
+
+/*
+ * This flag determines how we do escaping: normally RC2253 backslash only,
+ * set this to use backslash and quote.
+ */
+
+# define ASN1_STRFLGS_ESC_QUOTE          8
+
+/* These three flags are internal use only. */
+
+/* Character is a valid PrintableString character */
+# define CHARTYPE_PRINTABLESTRING        0x10
+/* Character needs escaping if it is the first character */
+# define CHARTYPE_FIRST_ESC_2253         0x20
+/* Character needs escaping if it is the last character */
+# define CHARTYPE_LAST_ESC_2253          0x40
+
+/*
+ * NB the internal flags are safely reused below by flags handled at the top
+ * level.
+ */
+
+/*
+ * If this is set we convert all character strings to UTF8 first
+ */
+
+# define ASN1_STRFLGS_UTF8_CONVERT       0x10
+
+/*
+ * If this is set we don't attempt to interpret content: just assume all
+ * strings are 1 byte per character. This will produce some pretty odd
+ * looking output!
+ */
+
+# define ASN1_STRFLGS_IGNORE_TYPE        0x20
+
+/* If this is set we include the string type in the output */
+# define ASN1_STRFLGS_SHOW_TYPE          0x40
+
+/*
+ * This determines which strings to display and which to 'dump' (hex dump of
+ * content octets or DER encoding). We can only dump non character strings or
+ * everything. If we don't dump 'unknown' they are interpreted as character
+ * strings with 1 octet per character and are subject to the usual escaping
+ * options.
+ */
+
+# define ASN1_STRFLGS_DUMP_ALL           0x80
+# define ASN1_STRFLGS_DUMP_UNKNOWN       0x100
+
+/*
+ * These determine what 'dumping' does, we can dump the content octets or the
+ * DER encoding: both use the RFC2253 #XXXXX notation.
+ */
+
+# define ASN1_STRFLGS_DUMP_DER           0x200
+
+/*
+ * This flag specifies that RC2254 escaping shall be performed.
+ */
+#define ASN1_STRFLGS_ESC_2254           0x400
+
+/*
+ * All the string flags consistent with RFC2253, escaping control characters
+ * isn't essential in RFC2253 but it is advisable anyway.
+ */
+
+# define ASN1_STRFLGS_RFC2253    (ASN1_STRFLGS_ESC_2253 | \
+                                ASN1_STRFLGS_ESC_CTRL | \
+                                ASN1_STRFLGS_ESC_MSB | \
+                                ASN1_STRFLGS_UTF8_CONVERT | \
+                                ASN1_STRFLGS_DUMP_UNKNOWN | \
+                                ASN1_STRFLGS_DUMP_DER)
+
+DEFINE_STACK_OF(ASN1_INTEGER)
+
+DEFINE_STACK_OF(ASN1_GENERALSTRING)
+
+DEFINE_STACK_OF(ASN1_UTF8STRING)
+
+typedef struct asn1_type_st {
+    int type;
+    union {
+        char *ptr;
+        ASN1_BOOLEAN boolean;
+        ASN1_STRING *asn1_string;
+        ASN1_OBJECT *object;
+        ASN1_INTEGER *integer;
+        ASN1_ENUMERATED *enumerated;
+        ASN1_BIT_STRING *bit_string;
+        ASN1_OCTET_STRING *octet_string;
+        ASN1_PRINTABLESTRING *printablestring;
+        ASN1_T61STRING *t61string;
+        ASN1_IA5STRING *ia5string;
+        ASN1_GENERALSTRING *generalstring;
+        ASN1_BMPSTRING *bmpstring;
+        ASN1_UNIVERSALSTRING *universalstring;
+        ASN1_UTCTIME *utctime;
+        ASN1_GENERALIZEDTIME *generalizedtime;
+        ASN1_VISIBLESTRING *visiblestring;
+        ASN1_UTF8STRING *utf8string;
+        /*
+         * set and sequence are left complete and still contain the set or
+         * sequence bytes
+         */
+        ASN1_STRING *set;
+        ASN1_STRING *sequence;
+        ASN1_VALUE *asn1_value;
+    } value;
+} ASN1_TYPE;
+
+DEFINE_STACK_OF(ASN1_TYPE)
+
+typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY;
+
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY)
+
+/* This is used to contain a list of bit names */
+typedef struct BIT_STRING_BITNAME_st {
+    int bitnum;
+    const char *lname;
+    const char *sname;
+} BIT_STRING_BITNAME;
+
+# define B_ASN1_TIME \
+                        B_ASN1_UTCTIME | \
+                        B_ASN1_GENERALIZEDTIME
+
+# define B_ASN1_PRINTABLE \
+                        B_ASN1_NUMERICSTRING| \
+                        B_ASN1_PRINTABLESTRING| \
+                        B_ASN1_T61STRING| \
+                        B_ASN1_IA5STRING| \
+                        B_ASN1_BIT_STRING| \
+                        B_ASN1_UNIVERSALSTRING|\
+                        B_ASN1_BMPSTRING|\
+                        B_ASN1_UTF8STRING|\
+                        B_ASN1_SEQUENCE|\
+                        B_ASN1_UNKNOWN
+
+# define B_ASN1_DIRECTORYSTRING \
+                        B_ASN1_PRINTABLESTRING| \
+                        B_ASN1_TELETEXSTRING|\
+                        B_ASN1_BMPSTRING|\
+                        B_ASN1_UNIVERSALSTRING|\
+                        B_ASN1_UTF8STRING
+
+# define B_ASN1_DISPLAYTEXT \
+                        B_ASN1_IA5STRING| \
+                        B_ASN1_VISIBLESTRING| \
+                        B_ASN1_BMPSTRING|\
+                        B_ASN1_UTF8STRING
+
+DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
+
+int ASN1_TYPE_get(const ASN1_TYPE *a);
+void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
+int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value);
+int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b);
+
+ASN1_TYPE *ASN1_TYPE_pack_sequence(const ASN1_ITEM *it, void *s, ASN1_TYPE **t);
+void *ASN1_TYPE_unpack_sequence(const ASN1_ITEM *it, const ASN1_TYPE *t);
+
+ASN1_OBJECT *ASN1_OBJECT_new(void);
+void ASN1_OBJECT_free(ASN1_OBJECT *a);
+int i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp);
+ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
+                             long length);
+
+DECLARE_ASN1_ITEM(ASN1_OBJECT)
+
+DEFINE_STACK_OF(ASN1_OBJECT)
+
+ASN1_STRING *ASN1_STRING_new(void);
+void ASN1_STRING_free(ASN1_STRING *a);
+void ASN1_STRING_clear_free(ASN1_STRING *a);
+int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str);
+ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *a);
+ASN1_STRING *ASN1_STRING_type_new(int type);
+int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b);
+  /*
+   * Since this is used to store all sorts of things, via macros, for now,
+   * make its data void *
+   */
+int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
+void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len);
+int ASN1_STRING_length(const ASN1_STRING *x);
+void ASN1_STRING_length_set(ASN1_STRING *x, int n);
+int ASN1_STRING_type(const ASN1_STRING *x);
+DEPRECATEDIN_1_1_0(unsigned char *ASN1_STRING_data(ASN1_STRING *x))
+const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING)
+int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length);
+int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value);
+int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n);
+int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a,
+                          const unsigned char *flags, int flags_len);
+
+int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
+                               BIT_STRING_BITNAME *tbl, int indent);
+int ASN1_BIT_STRING_num_asc(const char *name, BIT_STRING_BITNAME *tbl);
+int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, const char *name, int value,
+                            BIT_STRING_BITNAME *tbl);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER)
+ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
+                                long length);
+ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x);
+int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED)
+
+int ASN1_UTCTIME_check(const ASN1_UTCTIME *a);
+ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t);
+ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
+                               int offset_day, long offset_sec);
+int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str);
+int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t);
+
+int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *a);
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
+                                               time_t t);
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
+                                               time_t t, int offset_day,
+                                               long offset_sec);
+int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str);
+int ASN1_TIME_diff(int *pday, int *psec,
+                   const ASN1_TIME *from, const ASN1_TIME *to);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
+ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a);
+int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a,
+                          const ASN1_OCTET_STRING *b);
+int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data,
+                          int len);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_NULL)
+DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING)
+
+int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
+int UTF8_putc(unsigned char *str, int len, unsigned long value);
+
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE)
+
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT)
+DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME)
+DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
+DECLARE_ASN1_FUNCTIONS(ASN1_TIME)
+
+DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF)
+
+ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t);
+ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
+                         int offset_day, long offset_sec);
+int ASN1_TIME_check(const ASN1_TIME *t);
+ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME
+                                                   **out);
+int ASN1_TIME_set_string(ASN1_TIME *s, const char *str);
+
+int i2a_ASN1_INTEGER(BIO *bp, const ASN1_INTEGER *a);
+int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size);
+int i2a_ASN1_ENUMERATED(BIO *bp, const ASN1_ENUMERATED *a);
+int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size);
+int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a);
+int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size);
+int i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *a, int type);
+int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a);
+
+int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num);
+ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
+                                const char *sn, const char *ln);
+
+int ASN1_INTEGER_get_int64(int64_t *pr, const ASN1_INTEGER *a);
+int ASN1_INTEGER_set_int64(ASN1_INTEGER *a, int64_t r);
+int ASN1_INTEGER_get_uint64(uint64_t *pr, const ASN1_INTEGER *a);
+int ASN1_INTEGER_set_uint64(ASN1_INTEGER *a, uint64_t r);
+
+int ASN1_INTEGER_set(ASN1_INTEGER *a, long v);
+long ASN1_INTEGER_get(const ASN1_INTEGER *a);
+ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai);
+BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn);
+
+int ASN1_ENUMERATED_get_int64(int64_t *pr, const ASN1_ENUMERATED *a);
+int ASN1_ENUMERATED_set_int64(ASN1_ENUMERATED *a, int64_t r);
+
+
+int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v);
+long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a);
+ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai);
+BIGNUM *ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn);
+
+/* General */
+/* given a string, return the correct type, max is the maximum length */
+int ASN1_PRINTABLE_type(const unsigned char *s, int max);
+
+unsigned long ASN1_tag2bit(int tag);
+
+/* SPECIALS */
+int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
+                    int *pclass, long omax);
+int ASN1_check_infinite_end(unsigned char **p, long len);
+int ASN1_const_check_infinite_end(const unsigned char **p, long len);
+void ASN1_put_object(unsigned char **pp, int constructed, int length,
+                     int tag, int xclass);
+int ASN1_put_eoc(unsigned char **pp);
+int ASN1_object_size(int constructed, int length, int tag);
+
+/* Used to implement other functions */
+void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x);
+
+# define ASN1_dup_of(type,i2d,d2i,x) \
+    ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \
+                     CHECKED_D2I_OF(type, d2i), \
+                     CHECKED_PTR_OF(type, x)))
+
+# define ASN1_dup_of_const(type,i2d,d2i,x) \
+    ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \
+                     CHECKED_D2I_OF(type, d2i), \
+                     CHECKED_PTR_OF(const type, x)))
+
+void *ASN1_item_dup(const ASN1_ITEM *it, void *x);
+
+/* ASN1 alloc/free macros for when a type is only used internally */
+
+# define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type))
+# define M_ASN1_free_of(x, type) \
+                ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type))
+
+# ifndef OPENSSL_NO_STDIO
+void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x);
+
+#  define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \
+    ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \
+                        CHECKED_D2I_OF(type, d2i), \
+                        in, \
+                        CHECKED_PPTR_OF(type, x)))
+
+void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x);
+int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x);
+
+#  define ASN1_i2d_fp_of(type,i2d,out,x) \
+    (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \
+                 out, \
+                 CHECKED_PTR_OF(type, x)))
+
+#  define ASN1_i2d_fp_of_const(type,i2d,out,x) \
+    (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \
+                 out, \
+                 CHECKED_PTR_OF(const type, x)))
+
+int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x);
+int ASN1_STRING_print_ex_fp(FILE *fp, const ASN1_STRING *str, unsigned long flags);
+# endif
+
+int ASN1_STRING_to_UTF8(unsigned char **out, const ASN1_STRING *in);
+
+void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x);
+
+#  define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \
+    ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \
+                          CHECKED_D2I_OF(type, d2i), \
+                          in, \
+                          CHECKED_PPTR_OF(type, x)))
+
+void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x);
+int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x);
+
+#  define ASN1_i2d_bio_of(type,i2d,out,x) \
+    (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \
+                  out, \
+                  CHECKED_PTR_OF(type, x)))
+
+#  define ASN1_i2d_bio_of_const(type,i2d,out,x) \
+    (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \
+                  out, \
+                  CHECKED_PTR_OF(const type, x)))
+
+int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x);
+int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a);
+int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a);
+int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a);
+int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v);
+int ASN1_STRING_print_ex(BIO *out, const ASN1_STRING *str, unsigned long flags);
+int ASN1_buf_print(BIO *bp, const unsigned char *buf, size_t buflen, int off);
+int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
+                  unsigned char *buf, int off);
+int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent);
+int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent,
+                    int dump);
+const char *ASN1_tag2str(int tag);
+
+/* Used to load and write Netscape format cert */
+
+int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s);
+
+int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len);
+int ASN1_TYPE_get_octetstring(const ASN1_TYPE *a, unsigned char *data, int max_len);
+int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num,
+                                  unsigned char *data, int len);
+int ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *a, long *num,
+                                  unsigned char *data, int max_len);
+
+void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it);
+
+ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it,
+                            ASN1_OCTET_STRING **oct);
+
+void ASN1_STRING_set_default_mask(unsigned long mask);
+int ASN1_STRING_set_default_mask_asc(const char *p);
+unsigned long ASN1_STRING_get_default_mask(void);
+int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
+                       int inform, unsigned long mask);
+int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
+                        int inform, unsigned long mask,
+                        long minsize, long maxsize);
+
+ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out,
+                                    const unsigned char *in, int inlen,
+                                    int inform, int nid);
+ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid);
+int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long);
+void ASN1_STRING_TABLE_cleanup(void);
+
+/* ASN1 template functions */
+
+/* Old API compatible functions */
+ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it);
+void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it);
+ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in,
+                          long len, const ASN1_ITEM *it);
+int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
+int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out,
+                       const ASN1_ITEM *it);
+
+void ASN1_add_oid_module(void);
+void ASN1_add_stable_module(void);
+
+ASN1_TYPE *ASN1_generate_nconf(const char *str, CONF *nconf);
+ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf);
+int ASN1_str2mask(const char *str, unsigned long *pmask);
+
+/* ASN1 Print flags */
+
+/* Indicate missing OPTIONAL fields */
+# define ASN1_PCTX_FLAGS_SHOW_ABSENT             0x001
+/* Mark start and end of SEQUENCE */
+# define ASN1_PCTX_FLAGS_SHOW_SEQUENCE           0x002
+/* Mark start and end of SEQUENCE/SET OF */
+# define ASN1_PCTX_FLAGS_SHOW_SSOF               0x004
+/* Show the ASN1 type of primitives */
+# define ASN1_PCTX_FLAGS_SHOW_TYPE               0x008
+/* Don't show ASN1 type of ANY */
+# define ASN1_PCTX_FLAGS_NO_ANY_TYPE             0x010
+/* Don't show ASN1 type of MSTRINGs */
+# define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE         0x020
+/* Don't show field names in SEQUENCE */
+# define ASN1_PCTX_FLAGS_NO_FIELD_NAME           0x040
+/* Show structure names of each SEQUENCE field */
+# define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME  0x080
+/* Don't show structure name even at top level */
+# define ASN1_PCTX_FLAGS_NO_STRUCT_NAME          0x100
+
+int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
+                    const ASN1_ITEM *it, const ASN1_PCTX *pctx);
+ASN1_PCTX *ASN1_PCTX_new(void);
+void ASN1_PCTX_free(ASN1_PCTX *p);
+unsigned long ASN1_PCTX_get_flags(const ASN1_PCTX *p);
+void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_nm_flags(const ASN1_PCTX *p);
+void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_cert_flags(const ASN1_PCTX *p);
+void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_oid_flags(const ASN1_PCTX *p);
+void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags);
+unsigned long ASN1_PCTX_get_str_flags(const ASN1_PCTX *p);
+void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags);
+
+ASN1_SCTX *ASN1_SCTX_new(int (*scan_cb) (ASN1_SCTX *ctx));
+void ASN1_SCTX_free(ASN1_SCTX *p);
+const ASN1_ITEM *ASN1_SCTX_get_item(ASN1_SCTX *p);
+const ASN1_TEMPLATE *ASN1_SCTX_get_template(ASN1_SCTX *p);
+unsigned long ASN1_SCTX_get_flags(ASN1_SCTX *p);
+void ASN1_SCTX_set_app_data(ASN1_SCTX *p, void *data);
+void *ASN1_SCTX_get_app_data(ASN1_SCTX *p);
+
+const BIO_METHOD *BIO_f_asn1(void);
+
+BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it);
+
+int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+                        const ASN1_ITEM *it);
+int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
+                              const char *hdr, const ASN1_ITEM *it);
+int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
+                     int ctype_nid, int econt_nid,
+                     STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it);
+ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it);
+int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
+int SMIME_text(BIO *in, BIO *out);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_ASN1_strings(void);
+
+/* Error codes for the ASN1 functions. */
+
+/* Function codes. */
+# define ASN1_F_A2D_ASN1_OBJECT                           100
+# define ASN1_F_A2I_ASN1_INTEGER                          102
+# define ASN1_F_A2I_ASN1_STRING                           103
+# define ASN1_F_APPEND_EXP                                176
+# define ASN1_F_ASN1_BIT_STRING_SET_BIT                   183
+# define ASN1_F_ASN1_CB                                   177
+# define ASN1_F_ASN1_CHECK_TLEN                           104
+# define ASN1_F_ASN1_COLLECT                              106
+# define ASN1_F_ASN1_D2I_EX_PRIMITIVE                     108
+# define ASN1_F_ASN1_D2I_FP                               109
+# define ASN1_F_ASN1_D2I_READ_BIO                         107
+# define ASN1_F_ASN1_DIGEST                               184
+# define ASN1_F_ASN1_DO_ADB                               110
+# define ASN1_F_ASN1_DO_LOCK                              233
+# define ASN1_F_ASN1_DUP                                  111
+# define ASN1_F_ASN1_EX_C2I                               204
+# define ASN1_F_ASN1_FIND_END                             190
+# define ASN1_F_ASN1_GENERALIZEDTIME_ADJ                  216
+# define ASN1_F_ASN1_GENERATE_V3                          178
+# define ASN1_F_ASN1_GET_INT64                            224
+# define ASN1_F_ASN1_GET_OBJECT                           114
+# define ASN1_F_ASN1_GET_UINT64                           225
+# define ASN1_F_ASN1_I2D_BIO                              116
+# define ASN1_F_ASN1_I2D_FP                               117
+# define ASN1_F_ASN1_ITEM_D2I_FP                          206
+# define ASN1_F_ASN1_ITEM_DUP                             191
+# define ASN1_F_ASN1_ITEM_EMBED_D2I                       120
+# define ASN1_F_ASN1_ITEM_EMBED_NEW                       121
+# define ASN1_F_ASN1_ITEM_I2D_BIO                         192
+# define ASN1_F_ASN1_ITEM_I2D_FP                          193
+# define ASN1_F_ASN1_ITEM_PACK                            198
+# define ASN1_F_ASN1_ITEM_SIGN                            195
+# define ASN1_F_ASN1_ITEM_SIGN_CTX                        220
+# define ASN1_F_ASN1_ITEM_UNPACK                          199
+# define ASN1_F_ASN1_ITEM_VERIFY                          197
+# define ASN1_F_ASN1_MBSTRING_NCOPY                       122
+# define ASN1_F_ASN1_OBJECT_NEW                           123
+# define ASN1_F_ASN1_OUTPUT_DATA                          214
+# define ASN1_F_ASN1_PCTX_NEW                             205
+# define ASN1_F_ASN1_SCTX_NEW                             221
+# define ASN1_F_ASN1_SIGN                                 128
+# define ASN1_F_ASN1_STR2TYPE                             179
+# define ASN1_F_ASN1_STRING_GET_INT64                     227
+# define ASN1_F_ASN1_STRING_GET_UINT64                    230
+# define ASN1_F_ASN1_STRING_SET                           186
+# define ASN1_F_ASN1_STRING_TABLE_ADD                     129
+# define ASN1_F_ASN1_STRING_TO_BN                         228
+# define ASN1_F_ASN1_STRING_TYPE_NEW                      130
+# define ASN1_F_ASN1_TEMPLATE_EX_D2I                      132
+# define ASN1_F_ASN1_TEMPLATE_NEW                         133
+# define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I                   131
+# define ASN1_F_ASN1_TIME_ADJ                             217
+# define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING             134
+# define ASN1_F_ASN1_TYPE_GET_OCTETSTRING                 135
+# define ASN1_F_ASN1_UTCTIME_ADJ                          218
+# define ASN1_F_ASN1_VERIFY                               137
+# define ASN1_F_B64_READ_ASN1                             209
+# define ASN1_F_B64_WRITE_ASN1                            210
+# define ASN1_F_BIO_NEW_NDEF                              208
+# define ASN1_F_BITSTR_CB                                 180
+# define ASN1_F_BN_TO_ASN1_STRING                         229
+# define ASN1_F_C2I_ASN1_BIT_STRING                       189
+# define ASN1_F_C2I_ASN1_INTEGER                          194
+# define ASN1_F_C2I_ASN1_OBJECT                           196
+# define ASN1_F_C2I_IBUF                                  226
+# define ASN1_F_COLLECT_DATA                              140
+# define ASN1_F_D2I_ASN1_OBJECT                           147
+# define ASN1_F_D2I_ASN1_UINTEGER                         150
+# define ASN1_F_D2I_AUTOPRIVATEKEY                        207
+# define ASN1_F_D2I_PRIVATEKEY                            154
+# define ASN1_F_D2I_PUBLICKEY                             155
+# define ASN1_F_DO_TCREATE                                222
+# define ASN1_F_I2D_ASN1_BIO_STREAM                       211
+# define ASN1_F_I2D_DSA_PUBKEY                            161
+# define ASN1_F_I2D_EC_PUBKEY                             181
+# define ASN1_F_I2D_PRIVATEKEY                            163
+# define ASN1_F_I2D_PUBLICKEY                             164
+# define ASN1_F_I2D_RSA_PUBKEY                            165
+# define ASN1_F_LONG_C2I                                  166
+# define ASN1_F_OID_MODULE_INIT                           174
+# define ASN1_F_PARSE_TAGGING                             182
+# define ASN1_F_PKCS5_PBE2_SET_IV                         167
+# define ASN1_F_PKCS5_PBE2_SET_SCRYPT                     231
+# define ASN1_F_PKCS5_PBE_SET                             202
+# define ASN1_F_PKCS5_PBE_SET0_ALGOR                      215
+# define ASN1_F_PKCS5_PBKDF2_SET                          219
+# define ASN1_F_PKCS5_SCRYPT_SET                          232
+# define ASN1_F_SMIME_READ_ASN1                           212
+# define ASN1_F_SMIME_TEXT                                213
+# define ASN1_F_STBL_MODULE_INIT                          223
+# define ASN1_F_X509_CRL_ADD0_REVOKED                     169
+# define ASN1_F_X509_INFO_NEW                             170
+# define ASN1_F_X509_NAME_ENCODE                          203
+# define ASN1_F_X509_NAME_EX_D2I                          158
+# define ASN1_F_X509_NAME_EX_NEW                          171
+# define ASN1_F_X509_PKEY_NEW                             173
+
+/* Reason codes. */
+# define ASN1_R_ADDING_OBJECT                             171
+# define ASN1_R_ASN1_PARSE_ERROR                          203
+# define ASN1_R_ASN1_SIG_PARSE_ERROR                      204
+# define ASN1_R_AUX_ERROR                                 100
+# define ASN1_R_BAD_OBJECT_HEADER                         102
+# define ASN1_R_BMPSTRING_IS_WRONG_LENGTH                 214
+# define ASN1_R_BN_LIB                                    105
+# define ASN1_R_BOOLEAN_IS_WRONG_LENGTH                   106
+# define ASN1_R_BUFFER_TOO_SMALL                          107
+# define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER           108
+# define ASN1_R_CONTEXT_NOT_INITIALISED                   217
+# define ASN1_R_DATA_IS_WRONG                             109
+# define ASN1_R_DECODE_ERROR                              110
+# define ASN1_R_DEPTH_EXCEEDED                            174
+# define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED         198
+# define ASN1_R_ENCODE_ERROR                              112
+# define ASN1_R_ERROR_GETTING_TIME                        173
+# define ASN1_R_ERROR_LOADING_SECTION                     172
+# define ASN1_R_ERROR_SETTING_CIPHER_PARAMS               114
+# define ASN1_R_EXPECTING_AN_INTEGER                      115
+# define ASN1_R_EXPECTING_AN_OBJECT                       116
+# define ASN1_R_EXPLICIT_LENGTH_MISMATCH                  119
+# define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED              120
+# define ASN1_R_FIELD_MISSING                             121
+# define ASN1_R_FIRST_NUM_TOO_LARGE                       122
+# define ASN1_R_HEADER_TOO_LONG                           123
+# define ASN1_R_ILLEGAL_BITSTRING_FORMAT                  175
+# define ASN1_R_ILLEGAL_BOOLEAN                           176
+# define ASN1_R_ILLEGAL_CHARACTERS                        124
+# define ASN1_R_ILLEGAL_FORMAT                            177
+# define ASN1_R_ILLEGAL_HEX                               178
+# define ASN1_R_ILLEGAL_IMPLICIT_TAG                      179
+# define ASN1_R_ILLEGAL_INTEGER                           180
+# define ASN1_R_ILLEGAL_NEGATIVE_VALUE                    226
+# define ASN1_R_ILLEGAL_NESTED_TAGGING                    181
+# define ASN1_R_ILLEGAL_NULL                              125
+# define ASN1_R_ILLEGAL_NULL_VALUE                        182
+# define ASN1_R_ILLEGAL_OBJECT                            183
+# define ASN1_R_ILLEGAL_OPTIONAL_ANY                      126
+# define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE          170
+# define ASN1_R_ILLEGAL_PADDING                           221
+# define ASN1_R_ILLEGAL_TAGGED_ANY                        127
+# define ASN1_R_ILLEGAL_TIME_VALUE                        184
+# define ASN1_R_ILLEGAL_ZERO_CONTENT                      222
+# define ASN1_R_INTEGER_NOT_ASCII_FORMAT                  185
+# define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG                128
+# define ASN1_R_INVALID_BIT_STRING_BITS_LEFT              220
+# define ASN1_R_INVALID_BMPSTRING_LENGTH                  129
+# define ASN1_R_INVALID_DIGIT                             130
+# define ASN1_R_INVALID_MIME_TYPE                         205
+# define ASN1_R_INVALID_MODIFIER                          186
+# define ASN1_R_INVALID_NUMBER                            187
+# define ASN1_R_INVALID_OBJECT_ENCODING                   216
+# define ASN1_R_INVALID_SCRYPT_PARAMETERS                 227
+# define ASN1_R_INVALID_SEPARATOR                         131
+# define ASN1_R_INVALID_STRING_TABLE_VALUE                218
+# define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH            133
+# define ASN1_R_INVALID_UTF8STRING                        134
+# define ASN1_R_INVALID_VALUE                             219
+# define ASN1_R_LIST_ERROR                                188
+# define ASN1_R_MIME_NO_CONTENT_TYPE                      206
+# define ASN1_R_MIME_PARSE_ERROR                          207
+# define ASN1_R_MIME_SIG_PARSE_ERROR                      208
+# define ASN1_R_MISSING_EOC                               137
+# define ASN1_R_MISSING_SECOND_NUMBER                     138
+# define ASN1_R_MISSING_VALUE                             189
+# define ASN1_R_MSTRING_NOT_UNIVERSAL                     139
+# define ASN1_R_MSTRING_WRONG_TAG                         140
+# define ASN1_R_NESTED_ASN1_STRING                        197
+# define ASN1_R_NON_HEX_CHARACTERS                        141
+# define ASN1_R_NOT_ASCII_FORMAT                          190
+# define ASN1_R_NOT_ENOUGH_DATA                           142
+# define ASN1_R_NO_CONTENT_TYPE                           209
+# define ASN1_R_NO_MATCHING_CHOICE_TYPE                   143
+# define ASN1_R_NO_MULTIPART_BODY_FAILURE                 210
+# define ASN1_R_NO_MULTIPART_BOUNDARY                     211
+# define ASN1_R_NO_SIG_CONTENT_TYPE                       212
+# define ASN1_R_NULL_IS_WRONG_LENGTH                      144
+# define ASN1_R_OBJECT_NOT_ASCII_FORMAT                   191
+# define ASN1_R_ODD_NUMBER_OF_CHARS                       145
+# define ASN1_R_SECOND_NUMBER_TOO_LARGE                   147
+# define ASN1_R_SEQUENCE_LENGTH_MISMATCH                  148
+# define ASN1_R_SEQUENCE_NOT_CONSTRUCTED                  149
+# define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG              192
+# define ASN1_R_SHORT_LINE                                150
+# define ASN1_R_SIG_INVALID_MIME_TYPE                     213
+# define ASN1_R_STREAMING_NOT_SUPPORTED                   202
+# define ASN1_R_STRING_TOO_LONG                           151
+# define ASN1_R_STRING_TOO_SHORT                          152
+# define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154
+# define ASN1_R_TIME_NOT_ASCII_FORMAT                     193
+# define ASN1_R_TOO_LARGE                                 223
+# define ASN1_R_TOO_LONG                                  155
+# define ASN1_R_TOO_SMALL                                 224
+# define ASN1_R_TYPE_NOT_CONSTRUCTED                      156
+# define ASN1_R_TYPE_NOT_PRIMITIVE                        195
+# define ASN1_R_UNEXPECTED_EOC                            159
+# define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH           215
+# define ASN1_R_UNKNOWN_FORMAT                            160
+# define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM          161
+# define ASN1_R_UNKNOWN_OBJECT_TYPE                       162
+# define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE                   163
+# define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM               199
+# define ASN1_R_UNKNOWN_TAG                               194
+# define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE           164
+# define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE               167
+# define ASN1_R_UNSUPPORTED_TYPE                          196
+# define ASN1_R_WRONG_INTEGER_TYPE                        225
+# define ASN1_R_WRONG_PUBLIC_KEY_TYPE                     200
+# define ASN1_R_WRONG_TAG                                 168
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/asn1_mac.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/asn1_mac.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/asn1_mac.h	(revision 331)
@@ -0,0 +1,10 @@
+/*
+ * Copyright 2015-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
+ */
+
+#error "This file is obsolete; please update your software."
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/asn1t.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/asn1t.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/asn1t.h	(revision 331)
@@ -0,0 +1,924 @@
+/*
+ * Copyright 2000-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
+ */
+
+#ifndef HEADER_ASN1T_H
+# define HEADER_ASN1T_H
+
+# include <stddef.h>
+# include <openssl/e_os2.h>
+# include <openssl/asn1.h>
+
+# ifdef OPENSSL_BUILD_SHLIBCRYPTO
+#  undef OPENSSL_EXTERN
+#  define OPENSSL_EXTERN OPENSSL_EXPORT
+# endif
+
+/* ASN1 template defines, structures and functions */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
+#  define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr))
+
+/* Macros for start and end of ASN1_ITEM definition */
+
+#  define ASN1_ITEM_start(itname) \
+        OPENSSL_GLOBAL const ASN1_ITEM itname##_it = {
+
+#  define static_ASN1_ITEM_start(itname) \
+        static const ASN1_ITEM itname##_it = {
+
+#  define ASN1_ITEM_end(itname)                 \
+                };
+
+# else
+
+/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
+#  define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr()))
+
+/* Macros for start and end of ASN1_ITEM definition */
+
+#  define ASN1_ITEM_start(itname) \
+        const ASN1_ITEM * itname##_it(void) \
+        { \
+                static const ASN1_ITEM local_it = {
+
+#  define static_ASN1_ITEM_start(itname) \
+        static ASN1_ITEM_start(itname)
+
+#  define ASN1_ITEM_end(itname) \
+                }; \
+        return &local_it; \
+        }
+
+# endif
+
+/* Macros to aid ASN1 template writing */
+
+# define ASN1_ITEM_TEMPLATE(tname) \
+        static const ASN1_TEMPLATE tname##_item_tt
+
+# define ASN1_ITEM_TEMPLATE_END(tname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_PRIMITIVE,\
+                -1,\
+                &tname##_item_tt,\
+                0,\
+                NULL,\
+                0,\
+                #tname \
+        ASN1_ITEM_end(tname)
+# define static_ASN1_ITEM_TEMPLATE_END(tname) \
+        ;\
+        static_ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_PRIMITIVE,\
+                -1,\
+                &tname##_item_tt,\
+                0,\
+                NULL,\
+                0,\
+                #tname \
+        ASN1_ITEM_end(tname)
+
+/* This is a ASN1 type which just embeds a template */
+
+/*-
+ * This pair helps declare a SEQUENCE. We can do:
+ *
+ *      ASN1_SEQUENCE(stname) = {
+ *              ... SEQUENCE components ...
+ *      } ASN1_SEQUENCE_END(stname)
+ *
+ *      This will produce an ASN1_ITEM called stname_it
+ *      for a structure called stname.
+ *
+ *      If you want the same structure but a different
+ *      name then use:
+ *
+ *      ASN1_SEQUENCE(itname) = {
+ *              ... SEQUENCE components ...
+ *      } ASN1_SEQUENCE_END_name(stname, itname)
+ *
+ *      This will create an item called itname_it using
+ *      a structure called stname.
+ */
+
+# define ASN1_SEQUENCE(tname) \
+        static const ASN1_TEMPLATE tname##_seq_tt[]
+
+# define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname)
+
+# define static_ASN1_SEQUENCE_END(stname) static_ASN1_SEQUENCE_END_name(stname, stname)
+
+# define ASN1_SEQUENCE_END_name(stname, tname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_SEQUENCE,\
+                V_ASN1_SEQUENCE,\
+                tname##_seq_tt,\
+                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+                NULL,\
+                sizeof(stname),\
+                #stname \
+        ASN1_ITEM_end(tname)
+
+# define static_ASN1_SEQUENCE_END_name(stname, tname) \
+        ;\
+        static_ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_SEQUENCE,\
+                V_ASN1_SEQUENCE,\
+                tname##_seq_tt,\
+                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+                NULL,\
+                sizeof(stname),\
+                #stname \
+        ASN1_ITEM_end(tname)
+
+# define ASN1_NDEF_SEQUENCE(tname) \
+        ASN1_SEQUENCE(tname)
+
+# define ASN1_NDEF_SEQUENCE_cb(tname, cb) \
+        ASN1_SEQUENCE_cb(tname, cb)
+
+# define ASN1_SEQUENCE_cb(tname, cb) \
+        static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
+        ASN1_SEQUENCE(tname)
+
+# define ASN1_BROKEN_SEQUENCE(tname) \
+        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \
+        ASN1_SEQUENCE(tname)
+
+# define ASN1_SEQUENCE_ref(tname, cb) \
+        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), offsetof(tname, lock), cb, 0}; \
+        ASN1_SEQUENCE(tname)
+
+# define ASN1_SEQUENCE_enc(tname, enc, cb) \
+        static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \
+        ASN1_SEQUENCE(tname)
+
+# define ASN1_NDEF_SEQUENCE_END(tname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_NDEF_SEQUENCE,\
+                V_ASN1_SEQUENCE,\
+                tname##_seq_tt,\
+                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+                NULL,\
+                sizeof(tname),\
+                #tname \
+        ASN1_ITEM_end(tname)
+# define static_ASN1_NDEF_SEQUENCE_END(tname) \
+        ;\
+        static_ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_NDEF_SEQUENCE,\
+                V_ASN1_SEQUENCE,\
+                tname##_seq_tt,\
+                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+                NULL,\
+                sizeof(tname),\
+                #tname \
+        ASN1_ITEM_end(tname)
+
+# define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname)
+# define static_ASN1_BROKEN_SEQUENCE_END(stname) \
+        static_ASN1_SEQUENCE_END_ref(stname, stname)
+
+# define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
+
+# define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
+# define static_ASN1_SEQUENCE_END_cb(stname, tname) static_ASN1_SEQUENCE_END_ref(stname, tname)
+
+# define ASN1_SEQUENCE_END_ref(stname, tname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_SEQUENCE,\
+                V_ASN1_SEQUENCE,\
+                tname##_seq_tt,\
+                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+                &tname##_aux,\
+                sizeof(stname),\
+                #stname \
+        ASN1_ITEM_end(tname)
+# define static_ASN1_SEQUENCE_END_ref(stname, tname) \
+        ;\
+        static_ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_SEQUENCE,\
+                V_ASN1_SEQUENCE,\
+                tname##_seq_tt,\
+                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+                &tname##_aux,\
+                sizeof(stname),\
+                #stname \
+        ASN1_ITEM_end(tname)
+
+# define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_NDEF_SEQUENCE,\
+                V_ASN1_SEQUENCE,\
+                tname##_seq_tt,\
+                sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+                &tname##_aux,\
+                sizeof(stname),\
+                #stname \
+        ASN1_ITEM_end(tname)
+
+/*-
+ * This pair helps declare a CHOICE type. We can do:
+ *
+ *      ASN1_CHOICE(chname) = {
+ *              ... CHOICE options ...
+ *      ASN1_CHOICE_END(chname)
+ *
+ *      This will produce an ASN1_ITEM called chname_it
+ *      for a structure called chname. The structure
+ *      definition must look like this:
+ *      typedef struct {
+ *              int type;
+ *              union {
+ *                      ASN1_SOMETHING *opt1;
+ *                      ASN1_SOMEOTHER *opt2;
+ *              } value;
+ *      } chname;
+ *
+ *      the name of the selector must be 'type'.
+ *      to use an alternative selector name use the
+ *      ASN1_CHOICE_END_selector() version.
+ */
+
+# define ASN1_CHOICE(tname) \
+        static const ASN1_TEMPLATE tname##_ch_tt[]
+
+# define ASN1_CHOICE_cb(tname, cb) \
+        static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
+        ASN1_CHOICE(tname)
+
+# define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname)
+
+# define static_ASN1_CHOICE_END(stname) static_ASN1_CHOICE_END_name(stname, stname)
+
+# define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type)
+
+# define static_ASN1_CHOICE_END_name(stname, tname) static_ASN1_CHOICE_END_selector(stname, tname, type)
+
+# define ASN1_CHOICE_END_selector(stname, tname, selname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_CHOICE,\
+                offsetof(stname,selname) ,\
+                tname##_ch_tt,\
+                sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
+                NULL,\
+                sizeof(stname),\
+                #stname \
+        ASN1_ITEM_end(tname)
+
+# define static_ASN1_CHOICE_END_selector(stname, tname, selname) \
+        ;\
+        static_ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_CHOICE,\
+                offsetof(stname,selname) ,\
+                tname##_ch_tt,\
+                sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
+                NULL,\
+                sizeof(stname),\
+                #stname \
+        ASN1_ITEM_end(tname)
+
+# define ASN1_CHOICE_END_cb(stname, tname, selname) \
+        ;\
+        ASN1_ITEM_start(tname) \
+                ASN1_ITYPE_CHOICE,\
+                offsetof(stname,selname) ,\
+                tname##_ch_tt,\
+                sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
+                &tname##_aux,\
+                sizeof(stname),\
+                #stname \
+        ASN1_ITEM_end(tname)
+
+/* This helps with the template wrapper form of ASN1_ITEM */
+
+# define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \
+        (flags), (tag), 0,\
+        #name, ASN1_ITEM_ref(type) }
+
+/* These help with SEQUENCE or CHOICE components */
+
+/* used to declare other types */
+
+# define ASN1_EX_TYPE(flags, tag, stname, field, type) { \
+        (flags), (tag), offsetof(stname, field),\
+        #field, ASN1_ITEM_ref(type) }
+
+/* implicit and explicit helper macros */
+
+# define ASN1_IMP_EX(stname, field, type, tag, ex) \
+                ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type)
+
+# define ASN1_EXP_EX(stname, field, type, tag, ex) \
+                ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type)
+
+/* Any defined by macros: the field used is in the table itself */
+
+# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+#  define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
+#  define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
+# else
+#  define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb }
+#  define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb }
+# endif
+/* Plain simple type */
+# define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type)
+/* Embedded simple type */
+# define ASN1_EMBED(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_EMBED,0, stname, field, type)
+
+/* OPTIONAL simple type */
+# define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* IMPLICIT tagged simple type */
+# define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0)
+
+/* IMPLICIT tagged OPTIONAL simple type */
+# define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
+
+/* Same as above but EXPLICIT */
+
+# define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0)
+# define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
+
+/* SEQUENCE OF type */
+# define ASN1_SEQUENCE_OF(stname, field, type) \
+                ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type)
+
+/* OPTIONAL SEQUENCE OF */
+# define ASN1_SEQUENCE_OF_OPT(stname, field, type) \
+                ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* Same as above but for SET OF */
+
+# define ASN1_SET_OF(stname, field, type) \
+                ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type)
+
+# define ASN1_SET_OF_OPT(stname, field, type) \
+                ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */
+
+# define ASN1_IMP_SET_OF(stname, field, type, tag) \
+                        ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
+
+# define ASN1_EXP_SET_OF(stname, field, type, tag) \
+                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
+
+# define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \
+                        ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
+
+# define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \
+                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
+
+# define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \
+                        ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
+
+# define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \
+                        ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
+
+# define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \
+                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
+
+# define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \
+                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
+
+/* EXPLICIT using indefinite length constructed form */
+# define ASN1_NDEF_EXP(stname, field, type, tag) \
+                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF)
+
+/* EXPLICIT OPTIONAL using indefinite length constructed form */
+# define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \
+                        ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF)
+
+/* Macros for the ASN1_ADB structure */
+
+# define ASN1_ADB(name) \
+        static const ASN1_ADB_TABLE name##_adbtbl[]
+
+# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+#  define ASN1_ADB_END(name, flags, field, adb_cb, def, none) \
+        ;\
+        static const ASN1_ADB name##_adb = {\
+                flags,\
+                offsetof(name, field),\
+                adb_cb,\
+                name##_adbtbl,\
+                sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
+                def,\
+                none\
+        }
+
+# else
+
+#  define ASN1_ADB_END(name, flags, field, adb_cb, def, none) \
+        ;\
+        static const ASN1_ITEM *name##_adb(void) \
+        { \
+        static const ASN1_ADB internal_adb = \
+                {\
+                flags,\
+                offsetof(name, field),\
+                adb_cb,\
+                name##_adbtbl,\
+                sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
+                def,\
+                none\
+                }; \
+                return (const ASN1_ITEM *) &internal_adb; \
+        } \
+        void dummy_function(void)
+
+# endif
+
+# define ADB_ENTRY(val, template) {val, template}
+
+# define ASN1_ADB_TEMPLATE(name) \
+        static const ASN1_TEMPLATE name##_tt
+
+/*
+ * This is the ASN1 template structure that defines a wrapper round the
+ * actual type. It determines the actual position of the field in the value
+ * structure, various flags such as OPTIONAL and the field name.
+ */
+
+struct ASN1_TEMPLATE_st {
+    unsigned long flags;        /* Various flags */
+    long tag;                   /* tag, not used if no tagging */
+    unsigned long offset;       /* Offset of this field in structure */
+    const char *field_name;     /* Field name */
+    ASN1_ITEM_EXP *item;        /* Relevant ASN1_ITEM or ASN1_ADB */
+};
+
+/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */
+
+# define ASN1_TEMPLATE_item(t) (t->item_ptr)
+# define ASN1_TEMPLATE_adb(t) (t->item_ptr)
+
+typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE;
+typedef struct ASN1_ADB_st ASN1_ADB;
+
+struct ASN1_ADB_st {
+    unsigned long flags;        /* Various flags */
+    unsigned long offset;       /* Offset of selector field */
+    int (*adb_cb)(long *psel);  /* Application callback */
+    const ASN1_ADB_TABLE *tbl;  /* Table of possible types */
+    long tblcount;              /* Number of entries in tbl */
+    const ASN1_TEMPLATE *default_tt; /* Type to use if no match */
+    const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */
+};
+
+struct ASN1_ADB_TABLE_st {
+    long value;                 /* NID for an object or value for an int */
+    const ASN1_TEMPLATE tt;     /* item for this value */
+};
+
+/* template flags */
+
+/* Field is optional */
+# define ASN1_TFLG_OPTIONAL      (0x1)
+
+/* Field is a SET OF */
+# define ASN1_TFLG_SET_OF        (0x1 << 1)
+
+/* Field is a SEQUENCE OF */
+# define ASN1_TFLG_SEQUENCE_OF   (0x2 << 1)
+
+/*
+ * Special case: this refers to a SET OF that will be sorted into DER order
+ * when encoded *and* the corresponding STACK will be modified to match the
+ * new order.
+ */
+# define ASN1_TFLG_SET_ORDER     (0x3 << 1)
+
+/* Mask for SET OF or SEQUENCE OF */
+# define ASN1_TFLG_SK_MASK       (0x3 << 1)
+
+/*
+ * These flags mean the tag should be taken from the tag field. If EXPLICIT
+ * then the underlying type is used for the inner tag.
+ */
+
+/* IMPLICIT tagging */
+# define ASN1_TFLG_IMPTAG        (0x1 << 3)
+
+/* EXPLICIT tagging, inner tag from underlying type */
+# define ASN1_TFLG_EXPTAG        (0x2 << 3)
+
+# define ASN1_TFLG_TAG_MASK      (0x3 << 3)
+
+/* context specific IMPLICIT */
+# define ASN1_TFLG_IMPLICIT      ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT
+
+/* context specific EXPLICIT */
+# define ASN1_TFLG_EXPLICIT      ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT
+
+/*
+ * If tagging is in force these determine the type of tag to use. Otherwise
+ * the tag is determined by the underlying type. These values reflect the
+ * actual octet format.
+ */
+
+/* Universal tag */
+# define ASN1_TFLG_UNIVERSAL     (0x0<<6)
+/* Application tag */
+# define ASN1_TFLG_APPLICATION   (0x1<<6)
+/* Context specific tag */
+# define ASN1_TFLG_CONTEXT       (0x2<<6)
+/* Private tag */
+# define ASN1_TFLG_PRIVATE       (0x3<<6)
+
+# define ASN1_TFLG_TAG_CLASS     (0x3<<6)
+
+/*
+ * These are for ANY DEFINED BY type. In this case the 'item' field points to
+ * an ASN1_ADB structure which contains a table of values to decode the
+ * relevant type
+ */
+
+# define ASN1_TFLG_ADB_MASK      (0x3<<8)
+
+# define ASN1_TFLG_ADB_OID       (0x1<<8)
+
+# define ASN1_TFLG_ADB_INT       (0x1<<9)
+
+/*
+ * This flag when present in a SEQUENCE OF, SET OF or EXPLICIT causes
+ * indefinite length constructed encoding to be used if required.
+ */
+
+# define ASN1_TFLG_NDEF          (0x1<<11)
+
+/* Field is embedded and not a pointer */
+# define ASN1_TFLG_EMBED         (0x1 << 12)
+
+/* This is the actual ASN1 item itself */
+
+struct ASN1_ITEM_st {
+    char itype;                 /* The item type, primitive, SEQUENCE, CHOICE
+                                 * or extern */
+    long utype;                 /* underlying type */
+    const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains
+                                     * the contents */
+    long tcount;                /* Number of templates if SEQUENCE or CHOICE */
+    const void *funcs;          /* functions that handle this type */
+    long size;                  /* Structure size (usually) */
+    const char *sname;          /* Structure name */
+};
+
+/*-
+ * These are values for the itype field and
+ * determine how the type is interpreted.
+ *
+ * For PRIMITIVE types the underlying type
+ * determines the behaviour if items is NULL.
+ *
+ * Otherwise templates must contain a single
+ * template and the type is treated in the
+ * same way as the type specified in the template.
+ *
+ * For SEQUENCE types the templates field points
+ * to the members, the size field is the
+ * structure size.
+ *
+ * For CHOICE types the templates field points
+ * to each possible member (typically a union)
+ * and the 'size' field is the offset of the
+ * selector.
+ *
+ * The 'funcs' field is used for application
+ * specific functions.
+ *
+ * The EXTERN type uses a new style d2i/i2d.
+ * The new style should be used where possible
+ * because it avoids things like the d2i IMPLICIT
+ * hack.
+ *
+ * MSTRING is a multiple string type, it is used
+ * for a CHOICE of character strings where the
+ * actual strings all occupy an ASN1_STRING
+ * structure. In this case the 'utype' field
+ * has a special meaning, it is used as a mask
+ * of acceptable types using the B_ASN1 constants.
+ *
+ * NDEF_SEQUENCE is the same as SEQUENCE except
+ * that it will use indefinite length constructed
+ * encoding if requested.
+ *
+ */
+
+# define ASN1_ITYPE_PRIMITIVE            0x0
+
+# define ASN1_ITYPE_SEQUENCE             0x1
+
+# define ASN1_ITYPE_CHOICE               0x2
+
+# define ASN1_ITYPE_EXTERN               0x4
+
+# define ASN1_ITYPE_MSTRING              0x5
+
+# define ASN1_ITYPE_NDEF_SEQUENCE        0x6
+
+/*
+ * Cache for ASN1 tag and length, so we don't keep re-reading it for things
+ * like CHOICE
+ */
+
+struct ASN1_TLC_st {
+    char valid;                 /* Values below are valid */
+    int ret;                    /* return value */
+    long plen;                  /* length */
+    int ptag;                   /* class value */
+    int pclass;                 /* class value */
+    int hdrlen;                 /* header length */
+};
+
+/* Typedefs for ASN1 function pointers */
+typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
+                        const ASN1_ITEM *it, int tag, int aclass, char opt,
+                        ASN1_TLC *ctx);
+
+typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+                        const ASN1_ITEM *it, int tag, int aclass);
+typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
+typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval,
+                               int indent, const char *fname,
+                               const ASN1_PCTX *pctx);
+
+typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont,
+                               int *putype, const ASN1_ITEM *it);
+typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont,
+                               int len, int utype, char *free_cont,
+                               const ASN1_ITEM *it);
+typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval,
+                                 const ASN1_ITEM *it, int indent,
+                                 const ASN1_PCTX *pctx);
+
+typedef struct ASN1_EXTERN_FUNCS_st {
+    void *app_data;
+    ASN1_ex_new_func *asn1_ex_new;
+    ASN1_ex_free_func *asn1_ex_free;
+    ASN1_ex_free_func *asn1_ex_clear;
+    ASN1_ex_d2i *asn1_ex_d2i;
+    ASN1_ex_i2d *asn1_ex_i2d;
+    ASN1_ex_print_func *asn1_ex_print;
+} ASN1_EXTERN_FUNCS;
+
+typedef struct ASN1_PRIMITIVE_FUNCS_st {
+    void *app_data;
+    unsigned long flags;
+    ASN1_ex_new_func *prim_new;
+    ASN1_ex_free_func *prim_free;
+    ASN1_ex_free_func *prim_clear;
+    ASN1_primitive_c2i *prim_c2i;
+    ASN1_primitive_i2c *prim_i2c;
+    ASN1_primitive_print *prim_print;
+} ASN1_PRIMITIVE_FUNCS;
+
+/*
+ * This is the ASN1_AUX structure: it handles various miscellaneous
+ * requirements. For example the use of reference counts and an informational
+ * callback. The "informational callback" is called at various points during
+ * the ASN1 encoding and decoding. It can be used to provide minor
+ * customisation of the structures used. This is most useful where the
+ * supplied routines *almost* do the right thing but need some extra help at
+ * a few points. If the callback returns zero then it is assumed a fatal
+ * error has occurred and the main operation should be abandoned. If major
+ * changes in the default behaviour are required then an external type is
+ * more appropriate.
+ */
+
+typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it,
+                        void *exarg);
+
+typedef struct ASN1_AUX_st {
+    void *app_data;
+    int flags;
+    int ref_offset;             /* Offset of reference value */
+    int ref_lock;               /* Lock type to use */
+    ASN1_aux_cb *asn1_cb;
+    int enc_offset;             /* Offset of ASN1_ENCODING structure */
+} ASN1_AUX;
+
+/* For print related callbacks exarg points to this structure */
+typedef struct ASN1_PRINT_ARG_st {
+    BIO *out;
+    int indent;
+    const ASN1_PCTX *pctx;
+} ASN1_PRINT_ARG;
+
+/* For streaming related callbacks exarg points to this structure */
+typedef struct ASN1_STREAM_ARG_st {
+    /* BIO to stream through */
+    BIO *out;
+    /* BIO with filters appended */
+    BIO *ndef_bio;
+    /* Streaming I/O boundary */
+    unsigned char **boundary;
+} ASN1_STREAM_ARG;
+
+/* Flags in ASN1_AUX */
+
+/* Use a reference count */
+# define ASN1_AFLG_REFCOUNT      1
+/* Save the encoding of structure (useful for signatures) */
+# define ASN1_AFLG_ENCODING      2
+/* The Sequence length is invalid */
+# define ASN1_AFLG_BROKEN        4
+
+/* operation values for asn1_cb */
+
+# define ASN1_OP_NEW_PRE         0
+# define ASN1_OP_NEW_POST        1
+# define ASN1_OP_FREE_PRE        2
+# define ASN1_OP_FREE_POST       3
+# define ASN1_OP_D2I_PRE         4
+# define ASN1_OP_D2I_POST        5
+# define ASN1_OP_I2D_PRE         6
+# define ASN1_OP_I2D_POST        7
+# define ASN1_OP_PRINT_PRE       8
+# define ASN1_OP_PRINT_POST      9
+# define ASN1_OP_STREAM_PRE      10
+# define ASN1_OP_STREAM_POST     11
+# define ASN1_OP_DETACHED_PRE    12
+# define ASN1_OP_DETACHED_POST   13
+
+/* Macro to implement a primitive type */
+# define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0)
+# define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \
+                                ASN1_ITEM_start(itname) \
+                                        ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \
+                                ASN1_ITEM_end(itname)
+
+/* Macro to implement a multi string type */
+# define IMPLEMENT_ASN1_MSTRING(itname, mask) \
+                                ASN1_ITEM_start(itname) \
+                                        ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \
+                                ASN1_ITEM_end(itname)
+
+# define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \
+        ASN1_ITEM_start(sname) \
+                ASN1_ITYPE_EXTERN, \
+                tag, \
+                NULL, \
+                0, \
+                &fptrs, \
+                0, \
+                #sname \
+        ASN1_ITEM_end(sname)
+
+/* Macro to implement standard functions in terms of ASN1_ITEM structures */
+
+# define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname)
+
+# define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname)
+
+# define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \
+                        IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname)
+
+# define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \
+                IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname)
+
+# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \
+                IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname)
+
+# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \
+        pre stname *fname##_new(void) \
+        { \
+                return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
+        } \
+        pre void fname##_free(stname *a) \
+        { \
+                ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
+        }
+
+# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \
+        stname *fname##_new(void) \
+        { \
+                return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
+        } \
+        void fname##_free(stname *a) \
+        { \
+                ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
+        }
+
+# define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \
+        IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
+        IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
+
+# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
+        stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
+        { \
+                return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
+        } \
+        int i2d_##fname(stname *a, unsigned char **out) \
+        { \
+                return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
+        }
+
+# define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \
+        int i2d_##stname##_NDEF(stname *a, unsigned char **out) \
+        { \
+                return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\
+        }
+
+# define IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(stname) \
+        static stname *d2i_##stname(stname **a, \
+                                   const unsigned char **in, long len) \
+        { \
+                return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, \
+                                               ASN1_ITEM_rptr(stname)); \
+        } \
+        static int i2d_##stname(stname *a, unsigned char **out) \
+        { \
+                return ASN1_item_i2d((ASN1_VALUE *)a, out, \
+                                     ASN1_ITEM_rptr(stname)); \
+        }
+
+/*
+ * This includes evil casts to remove const: they will go away when full ASN1
+ * constification is done.
+ */
+# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
+        stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
+        { \
+                return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
+        } \
+        int i2d_##fname(const stname *a, unsigned char **out) \
+        { \
+                return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
+        }
+
+# define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \
+        stname * stname##_dup(stname *x) \
+        { \
+        return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \
+        }
+
+# define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \
+        IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname)
+
+# define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \
+        int fname##_print_ctx(BIO *out, stname *x, int indent, \
+                                                const ASN1_PCTX *pctx) \
+        { \
+                return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \
+                        ASN1_ITEM_rptr(itname), pctx); \
+        }
+
+# define IMPLEMENT_ASN1_FUNCTIONS_const(name) \
+                IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name)
+
+# define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \
+        IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
+        IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
+
+/* external definitions for primitive types */
+
+DECLARE_ASN1_ITEM(ASN1_BOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_TBOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_FBOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_SEQUENCE)
+DECLARE_ASN1_ITEM(CBIGNUM)
+DECLARE_ASN1_ITEM(BIGNUM)
+DECLARE_ASN1_ITEM(LONG)
+DECLARE_ASN1_ITEM(ZLONG)
+
+DEFINE_STACK_OF(ASN1_VALUE)
+
+/* Functions used internally by the ASN1 code */
+
+int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
+                     const ASN1_ITEM *it, int tag, int aclass, char opt,
+                     ASN1_TLC *ctx);
+
+int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
+                     const ASN1_ITEM *it, int tag, int aclass);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/async.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/async.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/async.h	(revision 331)
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2015-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 <stdlib.h>
+
+#ifndef HEADER_ASYNC_H
+# define HEADER_ASYNC_H
+
+#if defined(_WIN32)
+# if defined(BASETYPES) || defined(_WINDEF_H)
+/* application has to include <windows.h> to use this */
+#define OSSL_ASYNC_FD       HANDLE
+#define OSSL_BAD_ASYNC_FD   INVALID_HANDLE_VALUE
+# endif
+#else
+#define OSSL_ASYNC_FD       int
+#define OSSL_BAD_ASYNC_FD   -1
+#endif
+
+
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+typedef struct async_job_st ASYNC_JOB;
+typedef struct async_wait_ctx_st ASYNC_WAIT_CTX;
+
+#define ASYNC_ERR      0
+#define ASYNC_NO_JOBS  1
+#define ASYNC_PAUSE    2
+#define ASYNC_FINISH   3
+
+int ASYNC_init_thread(size_t max_size, size_t init_size);
+void ASYNC_cleanup_thread(void);
+
+#ifdef OSSL_ASYNC_FD
+ASYNC_WAIT_CTX *ASYNC_WAIT_CTX_new(void);
+void ASYNC_WAIT_CTX_free(ASYNC_WAIT_CTX *ctx);
+int ASYNC_WAIT_CTX_set_wait_fd(ASYNC_WAIT_CTX *ctx, const void *key,
+                               OSSL_ASYNC_FD fd,
+                               void *custom_data,
+                               void (*cleanup)(ASYNC_WAIT_CTX *, const void *,
+                                               OSSL_ASYNC_FD, void *));
+int ASYNC_WAIT_CTX_get_fd(ASYNC_WAIT_CTX *ctx, const void *key,
+                        OSSL_ASYNC_FD *fd, void **custom_data);
+int ASYNC_WAIT_CTX_get_all_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *fd,
+                               size_t *numfds);
+int ASYNC_WAIT_CTX_get_changed_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *addfd,
+                                   size_t *numaddfds, OSSL_ASYNC_FD *delfd,
+                                   size_t *numdelfds);
+int ASYNC_WAIT_CTX_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key);
+#endif
+
+int ASYNC_is_capable(void);
+
+int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *ctx, int *ret,
+                    int (*func)(void *), void *args, size_t size);
+int ASYNC_pause_job(void);
+
+ASYNC_JOB *ASYNC_get_current_job(void);
+ASYNC_WAIT_CTX *ASYNC_get_wait_ctx(ASYNC_JOB *job);
+void ASYNC_block_pause(void);
+void ASYNC_unblock_pause(void);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_ASYNC_strings(void);
+
+/* Error codes for the ASYNC functions. */
+
+/* Function codes. */
+# define ASYNC_F_ASYNC_CTX_NEW                            100
+# define ASYNC_F_ASYNC_INIT_THREAD                        101
+# define ASYNC_F_ASYNC_JOB_NEW                            102
+# define ASYNC_F_ASYNC_PAUSE_JOB                          103
+# define ASYNC_F_ASYNC_START_FUNC                         104
+# define ASYNC_F_ASYNC_START_JOB                          105
+
+/* Reason codes. */
+# define ASYNC_R_FAILED_TO_SET_POOL                       101
+# define ASYNC_R_FAILED_TO_SWAP_CONTEXT                   102
+# define ASYNC_R_INIT_FAILED                              105
+# define ASYNC_R_INVALID_POOL_SIZE                        103
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/bio.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/bio.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/bio.h	(revision 331)
@@ -0,0 +1,854 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_BIO_H
+# define HEADER_BIO_H
+
+# include <openssl/e_os2.h>
+
+# ifndef OPENSSL_NO_STDIO
+#  include <stdio.h>
+# endif
+# include <stdarg.h>
+
+# include <openssl/crypto.h>
+
+# ifndef OPENSSL_NO_SCTP
+#  ifndef OPENSSL_SYS_VMS
+#   include <stdint.h>
+#  else
+#   include <inttypes.h>
+#  endif
+# endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* There are the classes of BIOs */
+# define BIO_TYPE_DESCRIPTOR     0x0100 /* socket, fd, connect or accept */
+# define BIO_TYPE_FILTER         0x0200
+# define BIO_TYPE_SOURCE_SINK    0x0400
+
+/* These are the 'types' of BIOs */
+# define BIO_TYPE_NONE             0
+# define BIO_TYPE_MEM            ( 1|BIO_TYPE_SOURCE_SINK)
+# define BIO_TYPE_FILE           ( 2|BIO_TYPE_SOURCE_SINK)
+
+# define BIO_TYPE_FD             ( 4|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)
+# define BIO_TYPE_SOCKET         ( 5|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)
+# define BIO_TYPE_NULL           ( 6|BIO_TYPE_SOURCE_SINK)
+# define BIO_TYPE_SSL            ( 7|BIO_TYPE_FILTER)
+# define BIO_TYPE_MD             ( 8|BIO_TYPE_FILTER)
+# define BIO_TYPE_BUFFER         ( 9|BIO_TYPE_FILTER)
+# define BIO_TYPE_CIPHER         (10|BIO_TYPE_FILTER)
+# define BIO_TYPE_BASE64         (11|BIO_TYPE_FILTER)
+# define BIO_TYPE_CONNECT        (12|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)
+# define BIO_TYPE_ACCEPT         (13|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)
+
+# define BIO_TYPE_NBIO_TEST      (16|BIO_TYPE_FILTER)/* server proxy BIO */
+# define BIO_TYPE_NULL_FILTER    (17|BIO_TYPE_FILTER)
+# define BIO_TYPE_BIO            (19|BIO_TYPE_SOURCE_SINK)/* half a BIO pair */
+# define BIO_TYPE_LINEBUFFER     (20|BIO_TYPE_FILTER)
+# define BIO_TYPE_DGRAM          (21|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)
+# define BIO_TYPE_ASN1           (22|BIO_TYPE_FILTER)
+# define BIO_TYPE_COMP           (23|BIO_TYPE_FILTER)
+# ifndef OPENSSL_NO_SCTP
+#  define BIO_TYPE_DGRAM_SCTP    (24|BIO_TYPE_SOURCE_SINK|BIO_TYPE_DESCRIPTOR)
+# endif
+
+#define BIO_TYPE_START           128
+
+/*
+ * BIO_FILENAME_READ|BIO_CLOSE to open or close on free.
+ * BIO_set_fp(in,stdin,BIO_NOCLOSE);
+ */
+# define BIO_NOCLOSE             0x00
+# define BIO_CLOSE               0x01
+
+/*
+ * These are used in the following macros and are passed to BIO_ctrl()
+ */
+# define BIO_CTRL_RESET          1/* opt - rewind/zero etc */
+# define BIO_CTRL_EOF            2/* opt - are we at the eof */
+# define BIO_CTRL_INFO           3/* opt - extra tit-bits */
+# define BIO_CTRL_SET            4/* man - set the 'IO' type */
+# define BIO_CTRL_GET            5/* man - get the 'IO' type */
+# define BIO_CTRL_PUSH           6/* opt - internal, used to signify change */
+# define BIO_CTRL_POP            7/* opt - internal, used to signify change */
+# define BIO_CTRL_GET_CLOSE      8/* man - set the 'close' on free */
+# define BIO_CTRL_SET_CLOSE      9/* man - set the 'close' on free */
+# define BIO_CTRL_PENDING        10/* opt - is their more data buffered */
+# define BIO_CTRL_FLUSH          11/* opt - 'flush' buffered output */
+# define BIO_CTRL_DUP            12/* man - extra stuff for 'duped' BIO */
+# define BIO_CTRL_WPENDING       13/* opt - number of bytes still to write */
+# define BIO_CTRL_SET_CALLBACK   14/* opt - set callback function */
+# define BIO_CTRL_GET_CALLBACK   15/* opt - set callback function */
+
+# define BIO_CTRL_SET_FILENAME   30/* BIO_s_file special */
+
+/* dgram BIO stuff */
+# define BIO_CTRL_DGRAM_CONNECT       31/* BIO dgram special */
+# define BIO_CTRL_DGRAM_SET_CONNECTED 32/* allow for an externally connected
+                                         * socket to be passed in */
+# define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33/* setsockopt, essentially */
+# define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34/* getsockopt, essentially */
+# define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35/* setsockopt, essentially */
+# define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36/* getsockopt, essentially */
+
+# define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37/* flag whether the last */
+# define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38/* I/O operation tiemd out */
+
+/* #ifdef IP_MTU_DISCOVER */
+# define BIO_CTRL_DGRAM_MTU_DISCOVER       39/* set DF bit on egress packets */
+/* #endif */
+
+# define BIO_CTRL_DGRAM_QUERY_MTU          40/* as kernel for current MTU */
+# define BIO_CTRL_DGRAM_GET_FALLBACK_MTU   47
+# define BIO_CTRL_DGRAM_GET_MTU            41/* get cached value for MTU */
+# define BIO_CTRL_DGRAM_SET_MTU            42/* set cached value for MTU.
+                                              * want to use this if asking
+                                              * the kernel fails */
+
+# define BIO_CTRL_DGRAM_MTU_EXCEEDED       43/* check whether the MTU was
+                                              * exceed in the previous write
+                                              * operation */
+
+# define BIO_CTRL_DGRAM_GET_PEER           46
+# define BIO_CTRL_DGRAM_SET_PEER           44/* Destination for the data */
+
+# define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT   45/* Next DTLS handshake timeout
+                                              * to adjust socket timeouts */
+# define BIO_CTRL_DGRAM_SET_DONT_FRAG      48
+
+# define BIO_CTRL_DGRAM_GET_MTU_OVERHEAD   49
+
+# define BIO_CTRL_DGRAM_SET_PEEK_MODE      50
+
+# ifndef OPENSSL_NO_SCTP
+/* SCTP stuff */
+#  define BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE    50
+#  define BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY                51
+#  define BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY               52
+#  define BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD               53
+#  define BIO_CTRL_DGRAM_SCTP_GET_SNDINFO         60
+#  define BIO_CTRL_DGRAM_SCTP_SET_SNDINFO         61
+#  define BIO_CTRL_DGRAM_SCTP_GET_RCVINFO         62
+#  define BIO_CTRL_DGRAM_SCTP_SET_RCVINFO         63
+#  define BIO_CTRL_DGRAM_SCTP_GET_PRINFO                  64
+#  define BIO_CTRL_DGRAM_SCTP_SET_PRINFO                  65
+#  define BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN               70
+# endif
+
+/* modifiers */
+# define BIO_FP_READ             0x02
+# define BIO_FP_WRITE            0x04
+# define BIO_FP_APPEND           0x08
+# define BIO_FP_TEXT             0x10
+
+# define BIO_FLAGS_READ          0x01
+# define BIO_FLAGS_WRITE         0x02
+# define BIO_FLAGS_IO_SPECIAL    0x04
+# define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL)
+# define BIO_FLAGS_SHOULD_RETRY  0x08
+# ifndef BIO_FLAGS_UPLINK
+/*
+ * "UPLINK" flag denotes file descriptors provided by application. It
+ * defaults to 0, as most platforms don't require UPLINK interface.
+ */
+#  define BIO_FLAGS_UPLINK        0
+# endif
+
+# define BIO_FLAGS_BASE64_NO_NL  0x100
+
+/*
+ * This is used with memory BIOs:
+ * BIO_FLAGS_MEM_RDONLY means we shouldn't free up or change the data in any way;
+ * BIO_FLAGS_NONCLEAR_RST means we should't clear data on reset.
+ */
+# define BIO_FLAGS_MEM_RDONLY    0x200
+# define BIO_FLAGS_NONCLEAR_RST  0x400
+
+typedef union bio_addr_st BIO_ADDR;
+typedef struct bio_addrinfo_st BIO_ADDRINFO;
+
+int BIO_get_new_index(void);
+void BIO_set_flags(BIO *b, int flags);
+int BIO_test_flags(const BIO *b, int flags);
+void BIO_clear_flags(BIO *b, int flags);
+
+# define BIO_get_flags(b) BIO_test_flags(b, ~(0x0))
+# define BIO_set_retry_special(b) \
+                BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY))
+# define BIO_set_retry_read(b) \
+                BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY))
+# define BIO_set_retry_write(b) \
+                BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY))
+
+/* These are normally used internally in BIOs */
+# define BIO_clear_retry_flags(b) \
+                BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+# define BIO_get_retry_flags(b) \
+                BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+
+/* These should be used by the application to tell why we should retry */
+# define BIO_should_read(a)              BIO_test_flags(a, BIO_FLAGS_READ)
+# define BIO_should_write(a)             BIO_test_flags(a, BIO_FLAGS_WRITE)
+# define BIO_should_io_special(a)        BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL)
+# define BIO_retry_type(a)               BIO_test_flags(a, BIO_FLAGS_RWS)
+# define BIO_should_retry(a)             BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY)
+
+/*
+ * The next three are used in conjunction with the BIO_should_io_special()
+ * condition.  After this returns true, BIO *BIO_get_retry_BIO(BIO *bio, int
+ * *reason); will walk the BIO stack and return the 'reason' for the special
+ * and the offending BIO. Given a BIO, BIO_get_retry_reason(bio) will return
+ * the code.
+ */
+/*
+ * Returned from the SSL bio when the certificate retrieval code had an error
+ */
+# define BIO_RR_SSL_X509_LOOKUP          0x01
+/* Returned from the connect BIO when a connect would have blocked */
+# define BIO_RR_CONNECT                  0x02
+/* Returned from the accept BIO when an accept would have blocked */
+# define BIO_RR_ACCEPT                   0x03
+
+/* These are passed by the BIO callback */
+# define BIO_CB_FREE     0x01
+# define BIO_CB_READ     0x02
+# define BIO_CB_WRITE    0x03
+# define BIO_CB_PUTS     0x04
+# define BIO_CB_GETS     0x05
+# define BIO_CB_CTRL     0x06
+
+/*
+ * The callback is called before and after the underling operation, The
+ * BIO_CB_RETURN flag indicates if it is after the call
+ */
+# define BIO_CB_RETURN   0x80
+# define BIO_CB_return(a) ((a)|BIO_CB_RETURN)
+# define BIO_cb_pre(a)   (!((a)&BIO_CB_RETURN))
+# define BIO_cb_post(a)  ((a)&BIO_CB_RETURN)
+
+typedef long (*BIO_callback_fn)(BIO *b, int oper, const char *argp, int argi,
+                                long argl, long ret);
+BIO_callback_fn BIO_get_callback(const BIO *b);
+void BIO_set_callback(BIO *b, BIO_callback_fn callback);
+char *BIO_get_callback_arg(const BIO *b);
+void BIO_set_callback_arg(BIO *b, char *arg);
+
+typedef struct bio_method_st BIO_METHOD;
+
+const char *BIO_method_name(const BIO *b);
+int BIO_method_type(const BIO *b);
+
+typedef void bio_info_cb(BIO *, int, const char *, int, long, long);
+
+DEFINE_STACK_OF(BIO)
+
+/* Prefix and suffix callback in ASN1 BIO */
+typedef int asn1_ps_func (BIO *b, unsigned char **pbuf, int *plen,
+                          void *parg);
+
+# ifndef OPENSSL_NO_SCTP
+/* SCTP parameter structs */
+struct bio_dgram_sctp_sndinfo {
+    uint16_t snd_sid;
+    uint16_t snd_flags;
+    uint32_t snd_ppid;
+    uint32_t snd_context;
+};
+
+struct bio_dgram_sctp_rcvinfo {
+    uint16_t rcv_sid;
+    uint16_t rcv_ssn;
+    uint16_t rcv_flags;
+    uint32_t rcv_ppid;
+    uint32_t rcv_tsn;
+    uint32_t rcv_cumtsn;
+    uint32_t rcv_context;
+};
+
+struct bio_dgram_sctp_prinfo {
+    uint16_t pr_policy;
+    uint32_t pr_value;
+};
+# endif
+
+/*
+ * #define BIO_CONN_get_param_hostname BIO_ctrl
+ */
+
+# define BIO_C_SET_CONNECT                       100
+# define BIO_C_DO_STATE_MACHINE                  101
+# define BIO_C_SET_NBIO                          102
+/* # define BIO_C_SET_PROXY_PARAM                   103 */
+# define BIO_C_SET_FD                            104
+# define BIO_C_GET_FD                            105
+# define BIO_C_SET_FILE_PTR                      106
+# define BIO_C_GET_FILE_PTR                      107
+# define BIO_C_SET_FILENAME                      108
+# define BIO_C_SET_SSL                           109
+# define BIO_C_GET_SSL                           110
+# define BIO_C_SET_MD                            111
+# define BIO_C_GET_MD                            112
+# define BIO_C_GET_CIPHER_STATUS                 113
+# define BIO_C_SET_BUF_MEM                       114
+# define BIO_C_GET_BUF_MEM_PTR                   115
+# define BIO_C_GET_BUFF_NUM_LINES                116
+# define BIO_C_SET_BUFF_SIZE                     117
+# define BIO_C_SET_ACCEPT                        118
+# define BIO_C_SSL_MODE                          119
+# define BIO_C_GET_MD_CTX                        120
+/* # define BIO_C_GET_PROXY_PARAM                   121 */
+# define BIO_C_SET_BUFF_READ_DATA                122/* data to read first */
+# define BIO_C_GET_CONNECT                       123
+# define BIO_C_GET_ACCEPT                        124
+# define BIO_C_SET_SSL_RENEGOTIATE_BYTES         125
+# define BIO_C_GET_SSL_NUM_RENEGOTIATES          126
+# define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT       127
+# define BIO_C_FILE_SEEK                         128
+# define BIO_C_GET_CIPHER_CTX                    129
+# define BIO_C_SET_BUF_MEM_EOF_RETURN            130/* return end of input
+                                                     * value */
+# define BIO_C_SET_BIND_MODE                     131
+# define BIO_C_GET_BIND_MODE                     132
+# define BIO_C_FILE_TELL                         133
+# define BIO_C_GET_SOCKS                         134
+# define BIO_C_SET_SOCKS                         135
+
+# define BIO_C_SET_WRITE_BUF_SIZE                136/* for BIO_s_bio */
+# define BIO_C_GET_WRITE_BUF_SIZE                137
+# define BIO_C_MAKE_BIO_PAIR                     138
+# define BIO_C_DESTROY_BIO_PAIR                  139
+# define BIO_C_GET_WRITE_GUARANTEE               140
+# define BIO_C_GET_READ_REQUEST                  141
+# define BIO_C_SHUTDOWN_WR                       142
+# define BIO_C_NREAD0                            143
+# define BIO_C_NREAD                             144
+# define BIO_C_NWRITE0                           145
+# define BIO_C_NWRITE                            146
+# define BIO_C_RESET_READ_REQUEST                147
+# define BIO_C_SET_MD_CTX                        148
+
+# define BIO_C_SET_PREFIX                        149
+# define BIO_C_GET_PREFIX                        150
+# define BIO_C_SET_SUFFIX                        151
+# define BIO_C_GET_SUFFIX                        152
+
+# define BIO_C_SET_EX_ARG                        153
+# define BIO_C_GET_EX_ARG                        154
+
+# define BIO_C_SET_CONNECT_MODE                  155
+
+# define BIO_set_app_data(s,arg)         BIO_set_ex_data(s,0,arg)
+# define BIO_get_app_data(s)             BIO_get_ex_data(s,0)
+
+# define BIO_set_nbio(b,n)             BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL)
+
+# ifndef OPENSSL_NO_SOCK
+/* IP families we support, for BIO_s_connect() and BIO_s_accept() */
+/* Note: the underlying operating system may not support some of them */
+#  define BIO_FAMILY_IPV4                         4
+#  define BIO_FAMILY_IPV6                         6
+#  define BIO_FAMILY_IPANY                        256
+
+/* BIO_s_connect() */
+#  define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name)
+#  define BIO_set_conn_port(b,port)     BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port)
+#  define BIO_set_conn_address(b,addr)  BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)addr)
+#  define BIO_set_conn_ip_family(b,f)   BIO_int_ctrl(b,BIO_C_SET_CONNECT,3,f)
+#  define BIO_get_conn_hostname(b)      ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0))
+#  define BIO_get_conn_port(b)          ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1))
+#  define BIO_get_conn_address(b)       ((const BIO_ADDR *)BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2))
+#  define BIO_get_conn_ip_family(b)     BIO_ctrl(b,BIO_C_GET_CONNECT,3,NULL)
+#  define BIO_set_conn_mode(b,n)        BIO_ctrl(b,BIO_C_SET_CONNECT_MODE,(n),NULL)
+
+/* BIO_s_accept() */
+#  define BIO_set_accept_name(b,name)   BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name)
+#  define BIO_set_accept_port(b,port)   BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(char *)port)
+#  define BIO_get_accept_name(b)        ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0))
+#  define BIO_get_accept_port(b)        ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,1))
+#  define BIO_get_peer_name(b)          ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,2))
+#  define BIO_get_peer_port(b)          ((const char *)BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,3))
+/* #define BIO_set_nbio(b,n)    BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */
+#  define BIO_set_nbio_accept(b,n)      BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(n)?(void *)"a":NULL)
+#  define BIO_set_accept_bios(b,bio)    BIO_ctrl(b,BIO_C_SET_ACCEPT,3,(char *)bio)
+#  define BIO_set_accept_ip_family(b,f) BIO_int_ctrl(b,BIO_C_SET_ACCEPT,4,f)
+#  define BIO_get_accept_ip_family(b)   BIO_ctrl(b,BIO_C_GET_ACCEPT,4,NULL)
+
+/* Aliases kept for backward compatibility */
+#  define BIO_BIND_NORMAL                 0
+#  define BIO_BIND_REUSEADDR              BIO_SOCK_REUSEADDR
+#  define BIO_BIND_REUSEADDR_IF_UNUSED    BIO_SOCK_REUSEADDR
+#  define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL)
+#  define BIO_get_bind_mode(b)    BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL)
+
+/* BIO_s_accept() and BIO_s_connect() */
+#  define BIO_do_connect(b)       BIO_do_handshake(b)
+#  define BIO_do_accept(b)        BIO_do_handshake(b)
+# endif /* OPENSSL_NO_SOCK */
+
+# define BIO_do_handshake(b)     BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL)
+
+/* BIO_s_datagram(), BIO_s_fd(), BIO_s_socket(), BIO_s_accept() and BIO_s_connect() */
+# define BIO_set_fd(b,fd,c)      BIO_int_ctrl(b,BIO_C_SET_FD,c,fd)
+# define BIO_get_fd(b,c)         BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c)
+
+/* BIO_s_file() */
+# define BIO_set_fp(b,fp,c)      BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp)
+# define BIO_get_fp(b,fpp)       BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)fpp)
+
+/* BIO_s_fd() and BIO_s_file() */
+# define BIO_seek(b,ofs) (int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL)
+# define BIO_tell(b)     (int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL)
+
+/*
+ * name is cast to lose const, but might be better to route through a
+ * function so we can do it safely
+ */
+# ifdef CONST_STRICT
+/*
+ * If you are wondering why this isn't defined, its because CONST_STRICT is
+ * purely a compile-time kludge to allow const to be checked.
+ */
+int BIO_read_filename(BIO *b, const char *name);
+# else
+#  define BIO_read_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \
+                BIO_CLOSE|BIO_FP_READ,(char *)name)
+# endif
+# define BIO_write_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \
+                BIO_CLOSE|BIO_FP_WRITE,name)
+# define BIO_append_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \
+                BIO_CLOSE|BIO_FP_APPEND,name)
+# define BIO_rw_filename(b,name) (int)BIO_ctrl(b,BIO_C_SET_FILENAME, \
+                BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name)
+
+/*
+ * WARNING WARNING, this ups the reference count on the read bio of the SSL
+ * structure.  This is because the ssl read BIO is now pointed to by the
+ * next_bio field in the bio.  So when you free the BIO, make sure you are
+ * doing a BIO_free_all() to catch the underlying BIO.
+ */
+# define BIO_set_ssl(b,ssl,c)    BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl)
+# define BIO_get_ssl(b,sslp)     BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp)
+# define BIO_set_ssl_mode(b,client)      BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL)
+# define BIO_set_ssl_renegotiate_bytes(b,num) \
+        BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL)
+# define BIO_get_num_renegotiates(b) \
+        BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL)
+# define BIO_set_ssl_renegotiate_timeout(b,seconds) \
+        BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL)
+
+/* defined in evp.h */
+/* #define BIO_set_md(b,md)     BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */
+
+# define BIO_get_mem_data(b,pp)  BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp)
+# define BIO_set_mem_buf(b,bm,c) BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)bm)
+# define BIO_get_mem_ptr(b,pp)   BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0,(char *)pp)
+# define BIO_set_mem_eof_return(b,v) \
+                                BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL)
+
+/* For the BIO_f_buffer() type */
+# define BIO_get_buffer_num_lines(b)     BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL)
+# define BIO_set_buffer_size(b,size)     BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL)
+# define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0)
+# define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1)
+# define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf)
+
+/* Don't use the next one unless you know what you are doing :-) */
+# define BIO_dup_state(b,ret)    BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret))
+
+# define BIO_reset(b)            (int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL)
+# define BIO_eof(b)              (int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL)
+# define BIO_set_close(b,c)      (int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL)
+# define BIO_get_close(b)        (int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL)
+# define BIO_pending(b)          (int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL)
+# define BIO_wpending(b)         (int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL)
+/* ...pending macros have inappropriate return type */
+size_t BIO_ctrl_pending(BIO *b);
+size_t BIO_ctrl_wpending(BIO *b);
+# define BIO_flush(b)            (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL)
+# define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \
+                                                   cbp)
+# define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb)
+
+/* For the BIO_f_buffer() type */
+# define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL)
+
+/* For BIO_s_bio() */
+# define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL)
+# define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL)
+# define BIO_make_bio_pair(b1,b2)   (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2)
+# define BIO_destroy_bio_pair(b)    (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL)
+# define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL)
+/* macros with inappropriate type -- but ...pending macros use int too: */
+# define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL)
+# define BIO_get_read_request(b)    (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL)
+size_t BIO_ctrl_get_write_guarantee(BIO *b);
+size_t BIO_ctrl_get_read_request(BIO *b);
+int BIO_ctrl_reset_read_request(BIO *b);
+
+/* ctrl macros for dgram */
+# define BIO_ctrl_dgram_connect(b,peer)  \
+                     (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)peer)
+# define BIO_ctrl_set_connected(b,peer) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, 0, (char *)peer)
+# define BIO_dgram_recv_timedout(b) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL)
+# define BIO_dgram_send_timedout(b) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL)
+# define BIO_dgram_get_peer(b,peer) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer)
+# define BIO_dgram_set_peer(b,peer) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer)
+# define BIO_dgram_get_mtu_overhead(b) \
+         (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL)
+
+#define BIO_get_ex_new_index(l, p, newf, dupf, freef) \
+    CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, l, p, newf, dupf, freef)
+int BIO_set_ex_data(BIO *bio, int idx, void *data);
+void *BIO_get_ex_data(BIO *bio, int idx);
+uint64_t BIO_number_read(BIO *bio);
+uint64_t BIO_number_written(BIO *bio);
+
+/* For BIO_f_asn1() */
+int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
+                        asn1_ps_func *prefix_free);
+int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
+                        asn1_ps_func **pprefix_free);
+int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
+                        asn1_ps_func *suffix_free);
+int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
+                        asn1_ps_func **psuffix_free);
+
+const BIO_METHOD *BIO_s_file(void);
+BIO *BIO_new_file(const char *filename, const char *mode);
+# ifndef OPENSSL_NO_STDIO
+BIO *BIO_new_fp(FILE *stream, int close_flag);
+# endif
+BIO *BIO_new(const BIO_METHOD *type);
+int BIO_free(BIO *a);
+void BIO_set_data(BIO *a, void *ptr);
+void *BIO_get_data(BIO *a);
+void BIO_set_init(BIO *a, int init);
+int BIO_get_init(BIO *a);
+void BIO_set_shutdown(BIO *a, int shut);
+int BIO_get_shutdown(BIO *a);
+void BIO_vfree(BIO *a);
+int BIO_up_ref(BIO *a);
+int BIO_read(BIO *b, void *data, int len);
+int BIO_gets(BIO *bp, char *buf, int size);
+int BIO_write(BIO *b, const void *data, int len);
+int BIO_puts(BIO *bp, const char *buf);
+int BIO_indent(BIO *b, int indent, int max);
+long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg);
+long BIO_callback_ctrl(BIO *b, int cmd,
+                       void (*fp) (BIO *, int, const char *, int, long, long));
+void *BIO_ptr_ctrl(BIO *bp, int cmd, long larg);
+long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg);
+BIO *BIO_push(BIO *b, BIO *append);
+BIO *BIO_pop(BIO *b);
+void BIO_free_all(BIO *a);
+BIO *BIO_find_type(BIO *b, int bio_type);
+BIO *BIO_next(BIO *b);
+void BIO_set_next(BIO *b, BIO *next);
+BIO *BIO_get_retry_BIO(BIO *bio, int *reason);
+int BIO_get_retry_reason(BIO *bio);
+void BIO_set_retry_reason(BIO *bio, int reason);
+BIO *BIO_dup_chain(BIO *in);
+
+int BIO_nread0(BIO *bio, char **buf);
+int BIO_nread(BIO *bio, char **buf, int num);
+int BIO_nwrite0(BIO *bio, char **buf);
+int BIO_nwrite(BIO *bio, char **buf, int num);
+
+long BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi,
+                        long argl, long ret);
+
+const BIO_METHOD *BIO_s_mem(void);
+const BIO_METHOD *BIO_s_secmem(void);
+BIO *BIO_new_mem_buf(const void *buf, int len);
+# ifndef OPENSSL_NO_SOCK
+const BIO_METHOD *BIO_s_socket(void);
+const BIO_METHOD *BIO_s_connect(void);
+const BIO_METHOD *BIO_s_accept(void);
+# endif
+const BIO_METHOD *BIO_s_fd(void);
+const BIO_METHOD *BIO_s_log(void);
+const BIO_METHOD *BIO_s_bio(void);
+const BIO_METHOD *BIO_s_null(void);
+const BIO_METHOD *BIO_f_null(void);
+const BIO_METHOD *BIO_f_buffer(void);
+const BIO_METHOD *BIO_f_linebuffer(void);
+const BIO_METHOD *BIO_f_nbio_test(void);
+# ifndef OPENSSL_NO_DGRAM
+const BIO_METHOD *BIO_s_datagram(void);
+int BIO_dgram_non_fatal_error(int error);
+BIO *BIO_new_dgram(int fd, int close_flag);
+#  ifndef OPENSSL_NO_SCTP
+const BIO_METHOD *BIO_s_datagram_sctp(void);
+BIO *BIO_new_dgram_sctp(int fd, int close_flag);
+int BIO_dgram_is_sctp(BIO *bio);
+int BIO_dgram_sctp_notification_cb(BIO *b,
+                                   void (*handle_notifications) (BIO *bio,
+                                                                 void *context,
+                                                                 void *buf),
+                                   void *context);
+int BIO_dgram_sctp_wait_for_dry(BIO *b);
+int BIO_dgram_sctp_msg_waiting(BIO *b);
+#  endif
+# endif
+
+# ifndef OPENSSL_NO_SOCK
+int BIO_sock_should_retry(int i);
+int BIO_sock_non_fatal_error(int error);
+# endif
+
+int BIO_fd_should_retry(int i);
+int BIO_fd_non_fatal_error(int error);
+int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u),
+                void *u, const char *s, int len);
+int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u),
+                       void *u, const char *s, int len, int indent);
+int BIO_dump(BIO *b, const char *bytes, int len);
+int BIO_dump_indent(BIO *b, const char *bytes, int len, int indent);
+# ifndef OPENSSL_NO_STDIO
+int BIO_dump_fp(FILE *fp, const char *s, int len);
+int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent);
+# endif
+int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data,
+                   int datalen);
+
+# ifndef OPENSSL_NO_SOCK
+BIO_ADDR *BIO_ADDR_new(void);
+int BIO_ADDR_rawmake(BIO_ADDR *ap, int family,
+                     const void *where, size_t wherelen, unsigned short port);
+void BIO_ADDR_free(BIO_ADDR *);
+void BIO_ADDR_clear(BIO_ADDR *ap);
+int BIO_ADDR_family(const BIO_ADDR *ap);
+int BIO_ADDR_rawaddress(const BIO_ADDR *ap, void *p, size_t *l);
+unsigned short BIO_ADDR_rawport(const BIO_ADDR *ap);
+char *BIO_ADDR_hostname_string(const BIO_ADDR *ap, int numeric);
+char *BIO_ADDR_service_string(const BIO_ADDR *ap, int numeric);
+char *BIO_ADDR_path_string(const BIO_ADDR *ap);
+
+const BIO_ADDRINFO *BIO_ADDRINFO_next(const BIO_ADDRINFO *bai);
+int BIO_ADDRINFO_family(const BIO_ADDRINFO *bai);
+int BIO_ADDRINFO_socktype(const BIO_ADDRINFO *bai);
+int BIO_ADDRINFO_protocol(const BIO_ADDRINFO *bai);
+const BIO_ADDR *BIO_ADDRINFO_address(const BIO_ADDRINFO *bai);
+void BIO_ADDRINFO_free(BIO_ADDRINFO *bai);
+
+enum BIO_hostserv_priorities {
+    BIO_PARSE_PRIO_HOST, BIO_PARSE_PRIO_SERV
+};
+int BIO_parse_hostserv(const char *hostserv, char **host, char **service,
+                       enum BIO_hostserv_priorities hostserv_prio);
+enum BIO_lookup_type {
+    BIO_LOOKUP_CLIENT, BIO_LOOKUP_SERVER
+};
+int BIO_lookup(const char *host, const char *service,
+               enum BIO_lookup_type lookup_type,
+               int family, int socktype, BIO_ADDRINFO **res);
+int BIO_sock_error(int sock);
+int BIO_socket_ioctl(int fd, long type, void *arg);
+int BIO_socket_nbio(int fd, int mode);
+int BIO_sock_init(void);
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  define BIO_sock_cleanup() while(0) continue
+# endif
+int BIO_set_tcp_ndelay(int sock, int turn_on);
+
+DEPRECATEDIN_1_1_0(struct hostent *BIO_gethostbyname(const char *name))
+DEPRECATEDIN_1_1_0(int BIO_get_port(const char *str, unsigned short *port_ptr))
+DEPRECATEDIN_1_1_0(int BIO_get_host_ip(const char *str, unsigned char *ip))
+DEPRECATEDIN_1_1_0(int BIO_get_accept_socket(char *host_port, int mode))
+DEPRECATEDIN_1_1_0(int BIO_accept(int sock, char **ip_port))
+
+union BIO_sock_info_u {
+    BIO_ADDR *addr;
+};
+enum BIO_sock_info_type {
+    BIO_SOCK_INFO_ADDRESS
+};
+int BIO_sock_info(int sock,
+                  enum BIO_sock_info_type type, union BIO_sock_info_u *info);
+
+#  define BIO_SOCK_REUSEADDR    0x01
+#  define BIO_SOCK_V6_ONLY      0x02
+#  define BIO_SOCK_KEEPALIVE    0x04
+#  define BIO_SOCK_NONBLOCK     0x08
+#  define BIO_SOCK_NODELAY      0x10
+
+int BIO_socket(int domain, int socktype, int protocol, int options);
+int BIO_connect(int sock, const BIO_ADDR *addr, int options);
+int BIO_listen(int sock, const BIO_ADDR *addr, int options);
+int BIO_accept_ex(int accept_sock, BIO_ADDR *addr, int options);
+int BIO_closesocket(int sock);
+
+BIO *BIO_new_socket(int sock, int close_flag);
+BIO *BIO_new_connect(const char *host_port);
+BIO *BIO_new_accept(const char *host_port);
+# endif /* OPENSSL_NO_SOCK*/
+
+BIO *BIO_new_fd(int fd, int close_flag);
+
+int BIO_new_bio_pair(BIO **bio1, size_t writebuf1,
+                     BIO **bio2, size_t writebuf2);
+/*
+ * If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints.
+ * Otherwise returns 0 and sets *bio1 and *bio2 to NULL. Size 0 uses default
+ * value.
+ */
+
+void BIO_copy_next_retry(BIO *b);
+
+/*
+ * long BIO_ghbn_ctrl(int cmd,int iarg,char *parg);
+ */
+
+# ifdef __GNUC__
+#  define __bio_h__attr__ __attribute__
+# else
+#  define __bio_h__attr__(x)
+# endif
+int BIO_printf(BIO *bio, const char *format, ...)
+__bio_h__attr__((__format__(__printf__, 2, 3)));
+int BIO_vprintf(BIO *bio, const char *format, va_list args)
+__bio_h__attr__((__format__(__printf__, 2, 0)));
+int BIO_snprintf(char *buf, size_t n, const char *format, ...)
+__bio_h__attr__((__format__(__printf__, 3, 4)));
+int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
+__bio_h__attr__((__format__(__printf__, 3, 0)));
+# undef __bio_h__attr__
+
+
+BIO_METHOD *BIO_meth_new(int type, const char *name);
+void BIO_meth_free(BIO_METHOD *biom);
+int (*BIO_meth_get_write(BIO_METHOD *biom)) (BIO *, const char *, int);
+int BIO_meth_set_write(BIO_METHOD *biom,
+                       int (*write) (BIO *, const char *, int));
+int (*BIO_meth_get_read(BIO_METHOD *biom)) (BIO *, char *, int);
+int BIO_meth_set_read(BIO_METHOD *biom,
+                      int (*read) (BIO *, char *, int));
+int (*BIO_meth_get_puts(BIO_METHOD *biom)) (BIO *, const char *);
+int BIO_meth_set_puts(BIO_METHOD *biom,
+                      int (*puts) (BIO *, const char *));
+int (*BIO_meth_get_gets(BIO_METHOD *biom)) (BIO *, char *, int);
+int BIO_meth_set_gets(BIO_METHOD *biom,
+                      int (*gets) (BIO *, char *, int));
+long (*BIO_meth_get_ctrl(BIO_METHOD *biom)) (BIO *, int, long, void *);
+int BIO_meth_set_ctrl(BIO_METHOD *biom,
+                      long (*ctrl) (BIO *, int, long, void *));
+int (*BIO_meth_get_create(BIO_METHOD *bion)) (BIO *);
+int BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *));
+int (*BIO_meth_get_destroy(BIO_METHOD *biom)) (BIO *);
+int BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *));
+long (*BIO_meth_get_callback_ctrl(BIO_METHOD *biom))
+                                 (BIO *, int, bio_info_cb *);
+int BIO_meth_set_callback_ctrl(BIO_METHOD *biom,
+                               long (*callback_ctrl) (BIO *, int,
+                                                      bio_info_cb *));
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_BIO_strings(void);
+
+/* Error codes for the BIO functions. */
+
+/* Function codes. */
+# define BIO_F_ACPT_STATE                                 100
+# define BIO_F_ADDR_STRINGS                               134
+# define BIO_F_BIO_ACCEPT                                 101
+# define BIO_F_BIO_ACCEPT_EX                              137
+# define BIO_F_BIO_ADDR_NEW                               144
+# define BIO_F_BIO_CALLBACK_CTRL                          131
+# define BIO_F_BIO_CONNECT                                138
+# define BIO_F_BIO_CTRL                                   103
+# define BIO_F_BIO_GETS                                   104
+# define BIO_F_BIO_GET_HOST_IP                            106
+# define BIO_F_BIO_GET_NEW_INDEX                          102
+# define BIO_F_BIO_GET_PORT                               107
+# define BIO_F_BIO_LISTEN                                 139
+# define BIO_F_BIO_LOOKUP                                 135
+# define BIO_F_BIO_MAKE_PAIR                              121
+# define BIO_F_BIO_NEW                                    108
+# define BIO_F_BIO_NEW_FILE                               109
+# define BIO_F_BIO_NEW_MEM_BUF                            126
+# define BIO_F_BIO_NREAD                                  123
+# define BIO_F_BIO_NREAD0                                 124
+# define BIO_F_BIO_NWRITE                                 125
+# define BIO_F_BIO_NWRITE0                                122
+# define BIO_F_BIO_PARSE_HOSTSERV                         136
+# define BIO_F_BIO_PUTS                                   110
+# define BIO_F_BIO_READ                                   111
+# define BIO_F_BIO_SOCKET                                 140
+# define BIO_F_BIO_SOCKET_NBIO                            142
+# define BIO_F_BIO_SOCK_INFO                              141
+# define BIO_F_BIO_SOCK_INIT                              112
+# define BIO_F_BIO_WRITE                                  113
+# define BIO_F_BUFFER_CTRL                                114
+# define BIO_F_CONN_CTRL                                  127
+# define BIO_F_CONN_STATE                                 115
+# define BIO_F_DGRAM_SCTP_READ                            132
+# define BIO_F_DGRAM_SCTP_WRITE                           133
+# define BIO_F_FILE_CTRL                                  116
+# define BIO_F_FILE_READ                                  130
+# define BIO_F_LINEBUFFER_CTRL                            129
+# define BIO_F_MEM_WRITE                                  117
+# define BIO_F_SSL_NEW                                    118
+
+/* Reason codes. */
+# define BIO_R_ACCEPT_ERROR                               100
+# define BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET               141
+# define BIO_R_AMBIGUOUS_HOST_OR_SERVICE                  129
+# define BIO_R_BAD_FOPEN_MODE                             101
+# define BIO_R_BROKEN_PIPE                                124
+# define BIO_R_CONNECT_ERROR                              103
+# define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET          107
+# define BIO_R_GETSOCKNAME_ERROR                          132
+# define BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS              133
+# define BIO_R_GETTING_SOCKTYPE                           134
+# define BIO_R_INVALID_ARGUMENT                           125
+# define BIO_R_INVALID_SOCKET                             135
+# define BIO_R_IN_USE                                     123
+# define BIO_R_LISTEN_V6_ONLY                             136
+# define BIO_R_LOOKUP_RETURNED_NOTHING                    142
+# define BIO_R_MALFORMED_HOST_OR_SERVICE                  130
+# define BIO_R_NBIO_CONNECT_ERROR                         110
+# define BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED        143
+# define BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED           144
+# define BIO_R_NO_PORT_DEFINED                            113
+# define BIO_R_NO_SUCH_FILE                               128
+# define BIO_R_NULL_PARAMETER                             115
+# define BIO_R_UNABLE_TO_BIND_SOCKET                      117
+# define BIO_R_UNABLE_TO_CREATE_SOCKET                    118
+# define BIO_R_UNABLE_TO_KEEPALIVE                        137
+# define BIO_R_UNABLE_TO_LISTEN_SOCKET                    119
+# define BIO_R_UNABLE_TO_NODELAY                          138
+# define BIO_R_UNABLE_TO_REUSEADDR                        139
+# define BIO_R_UNAVAILABLE_IP_FAMILY                      145
+# define BIO_R_UNINITIALIZED                              120
+# define BIO_R_UNKNOWN_INFO_TYPE                          140
+# define BIO_R_UNSUPPORTED_IP_FAMILY                      146
+# define BIO_R_UNSUPPORTED_METHOD                         121
+# define BIO_R_UNSUPPORTED_PROTOCOL_FAMILY                131
+# define BIO_R_WRITE_TO_READ_ONLY_BIO                     126
+# define BIO_R_WSASTARTUP                                 122
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/blowfish.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/blowfish.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/blowfish.h	(revision 331)
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_BLOWFISH_H
+# define HEADER_BLOWFISH_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_BF
+# include <openssl/e_os2.h>
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+# define BF_ENCRYPT      1
+# define BF_DECRYPT      0
+
+/*-
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! BF_LONG has to be at least 32 bits wide.                     !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+# define BF_LONG unsigned int
+
+# define BF_ROUNDS       16
+# define BF_BLOCK        8
+
+typedef struct bf_key_st {
+    BF_LONG P[BF_ROUNDS + 2];
+    BF_LONG S[4 * 256];
+} BF_KEY;
+
+void BF_set_key(BF_KEY *key, int len, const unsigned char *data);
+
+void BF_encrypt(BF_LONG *data, const BF_KEY *key);
+void BF_decrypt(BF_LONG *data, const BF_KEY *key);
+
+void BF_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                    const BF_KEY *key, int enc);
+void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+                    const BF_KEY *schedule, unsigned char *ivec, int enc);
+void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                      long length, const BF_KEY *schedule,
+                      unsigned char *ivec, int *num, int enc);
+void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+                      long length, const BF_KEY *schedule,
+                      unsigned char *ivec, int *num);
+const char *BF_options(void);
+
+# ifdef  __cplusplus
+}
+# endif
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/bn.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/bn.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/bn.h	(revision 331)
@@ -0,0 +1,575 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the Eric Young open source
+ * license provided above.
+ *
+ * The binary polynomial arithmetic software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#ifndef HEADER_BN_H
+# define HEADER_BN_H
+
+# include <openssl/e_os2.h>
+# ifndef OPENSSL_NO_STDIO
+#  include <stdio.h>
+# endif
+# include <openssl/opensslconf.h>
+# include <openssl/ossl_typ.h>
+# include <openssl/crypto.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+ * 64-bit processor with LP64 ABI
+ */
+# ifdef SIXTY_FOUR_BIT_LONG
+#  define BN_ULONG        unsigned long
+#  define BN_BYTES        8
+# endif
+
+/*
+ * 64-bit processor other than LP64 ABI
+ */
+# ifdef SIXTY_FOUR_BIT
+#  define BN_ULONG        unsigned long long
+#  define BN_BYTES        8
+# endif
+
+# ifdef THIRTY_TWO_BIT
+#  define BN_ULONG        unsigned int
+#  define BN_BYTES        4
+# endif
+
+# define BN_BITS2       (BN_BYTES * 8)
+# define BN_BITS        (BN_BITS2 * 2)
+# define BN_TBIT        ((BN_ULONG)1 << (BN_BITS2 - 1))
+
+# define BN_FLG_MALLOCED         0x01
+# define BN_FLG_STATIC_DATA      0x02
+
+/*
+ * avoid leaking exponent information through timing,
+ * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime,
+ * BN_div() will call BN_div_no_branch,
+ * BN_mod_inverse() will call BN_mod_inverse_no_branch.
+ */
+# define BN_FLG_CONSTTIME        0x04
+# define BN_FLG_SECURE           0x08
+
+# if OPENSSL_API_COMPAT < 0x00908000L
+/* deprecated name for the flag */
+#  define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME
+#  define BN_FLG_FREE            0x8000 /* used for debugging */
+# endif
+
+void BN_set_flags(BIGNUM *b, int n);
+int BN_get_flags(const BIGNUM *b, int n);
+
+/* Values for |top| in BN_rand() */
+#define BN_RAND_TOP_ANY    -1
+#define BN_RAND_TOP_ONE     0
+#define BN_RAND_TOP_TWO     1
+
+/* Values for |bottom| in BN_rand() */
+#define BN_RAND_BOTTOM_ANY  0
+#define BN_RAND_BOTTOM_ODD  1
+
+/*
+ * get a clone of a BIGNUM with changed flags, for *temporary* use only (the
+ * two BIGNUMs cannot be used in parallel!). Also only for *read only* use. The
+ * value |dest| should be a newly allocated BIGNUM obtained via BN_new() that
+ * has not been otherwise initialised or used.
+ */
+void BN_with_flags(BIGNUM *dest, const BIGNUM *b, int flags);
+
+/* Wrapper function to make using BN_GENCB easier */
+int BN_GENCB_call(BN_GENCB *cb, int a, int b);
+
+BN_GENCB *BN_GENCB_new(void);
+void BN_GENCB_free(BN_GENCB *cb);
+
+/* Populate a BN_GENCB structure with an "old"-style callback */
+void BN_GENCB_set_old(BN_GENCB *gencb, void (*callback) (int, int, void *),
+                      void *cb_arg);
+
+/* Populate a BN_GENCB structure with a "new"-style callback */
+void BN_GENCB_set(BN_GENCB *gencb, int (*callback) (int, int, BN_GENCB *),
+                  void *cb_arg);
+
+void *BN_GENCB_get_arg(BN_GENCB *cb);
+
+# define BN_prime_checks 0      /* default: select number of iterations based
+                                 * on the size of the number */
+
+/*
+ * number of Miller-Rabin iterations for an error rate of less than 2^-80 for
+ * random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook of
+ * Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996];
+ * original paper: Damgaard, Landrock, Pomerance: Average case error
+ * estimates for the strong probable prime test. -- Math. Comp. 61 (1993)
+ * 177-194)
+ */
+# define BN_prime_checks_for_size(b) ((b) >= 1300 ?  2 : \
+                                (b) >=  850 ?  3 : \
+                                (b) >=  650 ?  4 : \
+                                (b) >=  550 ?  5 : \
+                                (b) >=  450 ?  6 : \
+                                (b) >=  400 ?  7 : \
+                                (b) >=  350 ?  8 : \
+                                (b) >=  300 ?  9 : \
+                                (b) >=  250 ? 12 : \
+                                (b) >=  200 ? 15 : \
+                                (b) >=  150 ? 18 : \
+                                /* b >= 100 */ 27)
+
+# define BN_num_bytes(a) ((BN_num_bits(a)+7)/8)
+
+int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w);
+int BN_is_zero(const BIGNUM *a);
+int BN_is_one(const BIGNUM *a);
+int BN_is_word(const BIGNUM *a, const BN_ULONG w);
+int BN_is_odd(const BIGNUM *a);
+
+# define BN_one(a)       (BN_set_word((a),1))
+
+void BN_zero_ex(BIGNUM *a);
+
+# if OPENSSL_API_COMPAT >= 0x00908000L
+#  define BN_zero(a)      BN_zero_ex(a)
+# else
+#  define BN_zero(a)      (BN_set_word((a),0))
+# endif
+
+const BIGNUM *BN_value_one(void);
+char *BN_options(void);
+BN_CTX *BN_CTX_new(void);
+BN_CTX *BN_CTX_secure_new(void);
+void BN_CTX_free(BN_CTX *c);
+void BN_CTX_start(BN_CTX *ctx);
+BIGNUM *BN_CTX_get(BN_CTX *ctx);
+void BN_CTX_end(BN_CTX *ctx);
+int BN_rand(BIGNUM *rnd, int bits, int top, int bottom);
+int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom);
+int BN_rand_range(BIGNUM *rnd, const BIGNUM *range);
+int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range);
+int BN_num_bits(const BIGNUM *a);
+int BN_num_bits_word(BN_ULONG l);
+int BN_security_bits(int L, int N);
+BIGNUM *BN_new(void);
+BIGNUM *BN_secure_new(void);
+void BN_clear_free(BIGNUM *a);
+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
+void BN_swap(BIGNUM *a, BIGNUM *b);
+BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
+int BN_bn2bin(const BIGNUM *a, unsigned char *to);
+int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen);
+BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret);
+int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen);
+BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret);
+int BN_bn2mpi(const BIGNUM *a, unsigned char *to);
+int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx);
+/** BN_set_negative sets sign of a BIGNUM
+ * \param  b  pointer to the BIGNUM object
+ * \param  n  0 if the BIGNUM b should be positive and a value != 0 otherwise
+ */
+void BN_set_negative(BIGNUM *b, int n);
+/** BN_is_negative returns 1 if the BIGNUM is negative
+ * \param  a  pointer to the BIGNUM object
+ * \return 1 if a < 0 and 0 otherwise
+ */
+int BN_is_negative(const BIGNUM *b);
+
+int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+           BN_CTX *ctx);
+# define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx))
+int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
+int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+               BN_CTX *ctx);
+int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                     const BIGNUM *m);
+int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+               BN_CTX *ctx);
+int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                     const BIGNUM *m);
+int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,
+               BN_CTX *ctx);
+int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m);
+int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m,
+                  BN_CTX *ctx);
+int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m);
+
+BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
+int BN_mul_word(BIGNUM *a, BN_ULONG w);
+int BN_add_word(BIGNUM *a, BN_ULONG w);
+int BN_sub_word(BIGNUM *a, BN_ULONG w);
+int BN_set_word(BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_get_word(const BIGNUM *a);
+
+int BN_cmp(const BIGNUM *a, const BIGNUM *b);
+void BN_free(BIGNUM *a);
+int BN_is_bit_set(const BIGNUM *a, int n);
+int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
+int BN_lshift1(BIGNUM *r, const BIGNUM *a);
+int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+
+int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+               const BIGNUM *m, BN_CTX *ctx);
+int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                    const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+                              const BIGNUM *m, BN_CTX *ctx,
+                              BN_MONT_CTX *in_mont);
+int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
+                         const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1,
+                     const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m,
+                     BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                      const BIGNUM *m, BN_CTX *ctx);
+
+int BN_mask_bits(BIGNUM *a, int n);
+# ifndef OPENSSL_NO_STDIO
+int BN_print_fp(FILE *fp, const BIGNUM *a);
+# endif
+int BN_print(BIO *bio, const BIGNUM *a);
+int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx);
+int BN_rshift(BIGNUM *r, const BIGNUM *a, int n);
+int BN_rshift1(BIGNUM *r, const BIGNUM *a);
+void BN_clear(BIGNUM *a);
+BIGNUM *BN_dup(const BIGNUM *a);
+int BN_ucmp(const BIGNUM *a, const BIGNUM *b);
+int BN_set_bit(BIGNUM *a, int n);
+int BN_clear_bit(BIGNUM *a, int n);
+char *BN_bn2hex(const BIGNUM *a);
+char *BN_bn2dec(const BIGNUM *a);
+int BN_hex2bn(BIGNUM **a, const char *str);
+int BN_dec2bn(BIGNUM **a, const char *str);
+int BN_asc2bn(BIGNUM **a, const char *str);
+int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); /* returns
+                                                                  * -2 for
+                                                                  * error */
+BIGNUM *BN_mod_inverse(BIGNUM *ret,
+                       const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);
+BIGNUM *BN_mod_sqrt(BIGNUM *ret,
+                    const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);
+
+void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords);
+
+/* Deprecated versions */
+DEPRECATEDIN_0_9_8(BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe,
+                                             const BIGNUM *add,
+                                             const BIGNUM *rem,
+                                             void (*callback) (int, int,
+                                                               void *),
+                                             void *cb_arg))
+DEPRECATEDIN_0_9_8(int
+                   BN_is_prime(const BIGNUM *p, int nchecks,
+                               void (*callback) (int, int, void *),
+                               BN_CTX *ctx, void *cb_arg))
+DEPRECATEDIN_0_9_8(int
+                   BN_is_prime_fasttest(const BIGNUM *p, int nchecks,
+                                        void (*callback) (int, int, void *),
+                                        BN_CTX *ctx, void *cb_arg,
+                                        int do_trial_division))
+
+/* Newer versions */
+int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add,
+                         const BIGNUM *rem, BN_GENCB *cb);
+int BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, BN_GENCB *cb);
+int BN_is_prime_fasttest_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx,
+                            int do_trial_division, BN_GENCB *cb);
+
+int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx);
+
+int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+                            const BIGNUM *Xp, const BIGNUM *Xp1,
+                            const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx,
+                            BN_GENCB *cb);
+int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, BIGNUM *Xp1,
+                              BIGNUM *Xp2, const BIGNUM *Xp, const BIGNUM *e,
+                              BN_CTX *ctx, BN_GENCB *cb);
+
+BN_MONT_CTX *BN_MONT_CTX_new(void);
+int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                          BN_MONT_CTX *mont, BN_CTX *ctx);
+int BN_to_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
+                     BN_CTX *ctx);
+int BN_from_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
+                       BN_CTX *ctx);
+void BN_MONT_CTX_free(BN_MONT_CTX *mont);
+int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx);
+BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from);
+BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_RWLOCK *lock,
+                                    const BIGNUM *mod, BN_CTX *ctx);
+
+/* BN_BLINDING flags */
+# define BN_BLINDING_NO_UPDATE   0x00000001
+# define BN_BLINDING_NO_RECREATE 0x00000002
+
+BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod);
+void BN_BLINDING_free(BN_BLINDING *b);
+int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx);
+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *);
+int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,
+                          BN_CTX *);
+
+int BN_BLINDING_is_current_thread(BN_BLINDING *b);
+void BN_BLINDING_set_current_thread(BN_BLINDING *b);
+int BN_BLINDING_lock(BN_BLINDING *b);
+int BN_BLINDING_unlock(BN_BLINDING *b);
+
+unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
+void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
+BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
+                                      const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
+                                      int (*bn_mod_exp) (BIGNUM *r,
+                                                         const BIGNUM *a,
+                                                         const BIGNUM *p,
+                                                         const BIGNUM *m,
+                                                         BN_CTX *ctx,
+                                                         BN_MONT_CTX *m_ctx),
+                                      BN_MONT_CTX *m_ctx);
+
+DEPRECATEDIN_0_9_8(void BN_set_params(int mul, int high, int low, int mont))
+DEPRECATEDIN_0_9_8(int BN_get_params(int which)) /* 0, mul, 1 high, 2 low, 3
+                                                  * mont */
+
+BN_RECP_CTX *BN_RECP_CTX_new(void);
+void BN_RECP_CTX_free(BN_RECP_CTX *recp);
+int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *rdiv, BN_CTX *ctx);
+int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
+                          BN_RECP_CTX *recp, BN_CTX *ctx);
+int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                    const BIGNUM *m, BN_CTX *ctx);
+int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
+                BN_RECP_CTX *recp, BN_CTX *ctx);
+
+# ifndef OPENSSL_NO_EC2M
+
+/*
+ * Functions for arithmetic over binary polynomials represented by BIGNUMs.
+ * The BIGNUM::neg property of BIGNUMs representing binary polynomials is
+ * ignored. Note that input arguments are not const so that their bit arrays
+ * can be expanded to the appropriate size if needed.
+ */
+
+/*
+ * r = a + b
+ */
+int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+#  define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b)
+/*
+ * r=a mod p
+ */
+int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p);
+/* r = (a * b) mod p */
+int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                    const BIGNUM *p, BN_CTX *ctx);
+/* r = (a * a) mod p */
+int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+/* r = (1 / b) mod p */
+int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx);
+/* r = (a / b) mod p */
+int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                    const BIGNUM *p, BN_CTX *ctx);
+/* r = (a ^ b) mod p */
+int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                    const BIGNUM *p, BN_CTX *ctx);
+/* r = sqrt(a) mod p */
+int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                     BN_CTX *ctx);
+/* r^2 + r = a mod p */
+int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+                           BN_CTX *ctx);
+#  define BN_GF2m_cmp(a, b) BN_ucmp((a), (b))
+/*-
+ * Some functions allow for representation of the irreducible polynomials
+ * as an unsigned int[], say p.  The irreducible f(t) is then of the form:
+ *     t^p[0] + t^p[1] + ... + t^p[k]
+ * where m = p[0] > p[1] > ... > p[k] = 0.
+ */
+/* r = a mod p */
+int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]);
+/* r = (a * b) mod p */
+int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                        const int p[], BN_CTX *ctx);
+/* r = (a * a) mod p */
+int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[],
+                        BN_CTX *ctx);
+/* r = (1 / b) mod p */
+int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[],
+                        BN_CTX *ctx);
+/* r = (a / b) mod p */
+int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                        const int p[], BN_CTX *ctx);
+/* r = (a ^ b) mod p */
+int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+                        const int p[], BN_CTX *ctx);
+/* r = sqrt(a) mod p */
+int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a,
+                         const int p[], BN_CTX *ctx);
+/* r^2 + r = a mod p */
+int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a,
+                               const int p[], BN_CTX *ctx);
+int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max);
+int BN_GF2m_arr2poly(const int p[], BIGNUM *a);
+
+# endif
+
+/*
+ * faster mod functions for the 'NIST primes' 0 <= a < p^2
+ */
+int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+
+const BIGNUM *BN_get0_nist_prime_192(void);
+const BIGNUM *BN_get0_nist_prime_224(void);
+const BIGNUM *BN_get0_nist_prime_256(void);
+const BIGNUM *BN_get0_nist_prime_384(void);
+const BIGNUM *BN_get0_nist_prime_521(void);
+
+int (*BN_nist_mod_func(const BIGNUM *p)) (BIGNUM *r, const BIGNUM *a,
+                                          const BIGNUM *field, BN_CTX *ctx);
+
+int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range,
+                          const BIGNUM *priv, const unsigned char *message,
+                          size_t message_len, BN_CTX *ctx);
+
+/* Primes from RFC 2409 */
+BIGNUM *BN_get_rfc2409_prime_768(BIGNUM *bn);
+BIGNUM *BN_get_rfc2409_prime_1024(BIGNUM *bn);
+
+/* Primes from RFC 3526 */
+BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *bn);
+BIGNUM *BN_get_rfc3526_prime_2048(BIGNUM *bn);
+BIGNUM *BN_get_rfc3526_prime_3072(BIGNUM *bn);
+BIGNUM *BN_get_rfc3526_prime_4096(BIGNUM *bn);
+BIGNUM *BN_get_rfc3526_prime_6144(BIGNUM *bn);
+BIGNUM *BN_get_rfc3526_prime_8192(BIGNUM *bn);
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  define get_rfc2409_prime_768 BN_get_rfc2409_prime_768
+#  define get_rfc2409_prime_1024 BN_get_rfc2409_prime_1024
+#  define get_rfc3526_prime_1536 BN_get_rfc3526_prime_1536
+#  define get_rfc3526_prime_2048 BN_get_rfc3526_prime_2048
+#  define get_rfc3526_prime_3072 BN_get_rfc3526_prime_3072
+#  define get_rfc3526_prime_4096 BN_get_rfc3526_prime_4096
+#  define get_rfc3526_prime_6144 BN_get_rfc3526_prime_6144
+#  define get_rfc3526_prime_8192 BN_get_rfc3526_prime_8192
+# endif
+
+int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_BN_strings(void);
+
+/* Error codes for the BN functions. */
+
+/* Function codes. */
+# define BN_F_BNRAND                                      127
+# define BN_F_BN_BLINDING_CONVERT_EX                      100
+# define BN_F_BN_BLINDING_CREATE_PARAM                    128
+# define BN_F_BN_BLINDING_INVERT_EX                       101
+# define BN_F_BN_BLINDING_NEW                             102
+# define BN_F_BN_BLINDING_UPDATE                          103
+# define BN_F_BN_BN2DEC                                   104
+# define BN_F_BN_BN2HEX                                   105
+# define BN_F_BN_COMPUTE_WNAF                             142
+# define BN_F_BN_CTX_GET                                  116
+# define BN_F_BN_CTX_NEW                                  106
+# define BN_F_BN_CTX_START                                129
+# define BN_F_BN_DIV                                      107
+# define BN_F_BN_DIV_RECP                                 130
+# define BN_F_BN_EXP                                      123
+# define BN_F_BN_EXPAND_INTERNAL                          120
+# define BN_F_BN_GENCB_NEW                                143
+# define BN_F_BN_GENERATE_DSA_NONCE                       140
+# define BN_F_BN_GENERATE_PRIME_EX                        141
+# define BN_F_BN_GF2M_MOD                                 131
+# define BN_F_BN_GF2M_MOD_EXP                             132
+# define BN_F_BN_GF2M_MOD_MUL                             133
+# define BN_F_BN_GF2M_MOD_SOLVE_QUAD                      134
+# define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR                  135
+# define BN_F_BN_GF2M_MOD_SQR                             136
+# define BN_F_BN_GF2M_MOD_SQRT                            137
+# define BN_F_BN_LSHIFT                                   145
+# define BN_F_BN_MOD_EXP2_MONT                            118
+# define BN_F_BN_MOD_EXP_MONT                             109
+# define BN_F_BN_MOD_EXP_MONT_CONSTTIME                   124
+# define BN_F_BN_MOD_EXP_MONT_WORD                        117
+# define BN_F_BN_MOD_EXP_RECP                             125
+# define BN_F_BN_MOD_EXP_SIMPLE                           126
+# define BN_F_BN_MOD_INVERSE                              110
+# define BN_F_BN_MOD_INVERSE_NO_BRANCH                    139
+# define BN_F_BN_MOD_LSHIFT_QUICK                         119
+# define BN_F_BN_MOD_SQRT                                 121
+# define BN_F_BN_MPI2BN                                   112
+# define BN_F_BN_NEW                                      113
+# define BN_F_BN_RAND                                     114
+# define BN_F_BN_RAND_RANGE                               122
+# define BN_F_BN_RSHIFT                                   146
+# define BN_F_BN_SET_WORDS                                144
+# define BN_F_BN_USUB                                     115
+
+/* Reason codes. */
+# define BN_R_ARG2_LT_ARG3                                100
+# define BN_R_BAD_RECIPROCAL                              101
+# define BN_R_BIGNUM_TOO_LONG                             114
+# define BN_R_BITS_TOO_SMALL                              118
+# define BN_R_CALLED_WITH_EVEN_MODULUS                    102
+# define BN_R_DIV_BY_ZERO                                 103
+# define BN_R_ENCODING_ERROR                              104
+# define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA                105
+# define BN_R_INPUT_NOT_REDUCED                           110
+# define BN_R_INVALID_LENGTH                              106
+# define BN_R_INVALID_RANGE                               115
+# define BN_R_INVALID_SHIFT                               119
+# define BN_R_NOT_A_SQUARE                                111
+# define BN_R_NOT_INITIALIZED                             107
+# define BN_R_NO_INVERSE                                  108
+# define BN_R_NO_SOLUTION                                 116
+# define BN_R_PRIVATE_KEY_TOO_LARGE                       117
+# define BN_R_P_IS_NOT_PRIME                              112
+# define BN_R_TOO_MANY_ITERATIONS                         113
+# define BN_R_TOO_MANY_TEMPORARY_VARIABLES                109
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/buffer.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/buffer.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/buffer.h	(revision 331)
@@ -0,0 +1,76 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_BUFFER_H
+# define HEADER_BUFFER_H
+
+# include <openssl/ossl_typ.h>
+# ifndef HEADER_CRYPTO_H
+#  include <openssl/crypto.h>
+# endif
+
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# include <stddef.h>
+
+# if !defined(NO_SYS_TYPES_H)
+#  include <sys/types.h>
+# endif
+
+/*
+ * These names are outdated as of OpenSSL 1.1; a future release
+ * will move them to be deprecated.
+ */
+# define BUF_strdup(s) OPENSSL_strdup(s)
+# define BUF_strndup(s, size) OPENSSL_strndup(s, size)
+# define BUF_memdup(data, size) OPENSSL_memdup(data, size)
+# define BUF_strlcpy(dst, src, size)  OPENSSL_strlcpy(dst, src, size)
+# define BUF_strlcat(dst, src, size) OPENSSL_strlcat(dst, src, size)
+# define BUF_strnlen(str, maxlen) OPENSSL_strnlen(str, maxlen)
+
+struct buf_mem_st {
+    size_t length;              /* current number of bytes */
+    char *data;
+    size_t max;                 /* size of buffer */
+    unsigned long flags;
+};
+
+# define BUF_MEM_FLAG_SECURE  0x01
+
+BUF_MEM *BUF_MEM_new(void);
+BUF_MEM *BUF_MEM_new_ex(unsigned long flags);
+void BUF_MEM_free(BUF_MEM *a);
+size_t BUF_MEM_grow(BUF_MEM *str, size_t len);
+size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len);
+void BUF_reverse(unsigned char *out, const unsigned char *in, size_t siz);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_BUF_strings(void);
+
+/* Error codes for the BUF functions. */
+
+/* Function codes. */
+# define BUF_F_BUF_MEM_GROW                               100
+# define BUF_F_BUF_MEM_GROW_CLEAN                         105
+# define BUF_F_BUF_MEM_NEW                                101
+
+/* Reason codes. */
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/camellia.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/camellia.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/camellia.h	(revision 331)
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2006-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
+ */
+
+#ifndef HEADER_CAMELLIA_H
+# define HEADER_CAMELLIA_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_CAMELLIA
+# include <stddef.h>
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define CAMELLIA_ENCRYPT        1
+# define CAMELLIA_DECRYPT        0
+
+/*
+ * Because array size can't be a const in C, the following two are macros.
+ * Both sizes are in bytes.
+ */
+
+/* This should be a hidden type, but EVP requires that the size be known */
+
+# define CAMELLIA_BLOCK_SIZE 16
+# define CAMELLIA_TABLE_BYTE_LEN 272
+# define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
+
+typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match
+                                                               * with WORD */
+
+struct camellia_key_st {
+    union {
+        double d;               /* ensures 64-bit align */
+        KEY_TABLE_TYPE rd_key;
+    } u;
+    int grand_rounds;
+};
+typedef struct camellia_key_st CAMELLIA_KEY;
+
+int Camellia_set_key(const unsigned char *userKey, const int bits,
+                     CAMELLIA_KEY *key);
+
+void Camellia_encrypt(const unsigned char *in, unsigned char *out,
+                      const CAMELLIA_KEY *key);
+void Camellia_decrypt(const unsigned char *in, unsigned char *out,
+                      const CAMELLIA_KEY *key);
+
+void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                          const CAMELLIA_KEY *key, const int enc);
+void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                          size_t length, const CAMELLIA_KEY *key,
+                          unsigned char *ivec, const int enc);
+void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t length, const CAMELLIA_KEY *key,
+                             unsigned char *ivec, int *num, const int enc);
+void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t length, const CAMELLIA_KEY *key,
+                           unsigned char *ivec, int *num, const int enc);
+void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t length, const CAMELLIA_KEY *key,
+                           unsigned char *ivec, int *num, const int enc);
+void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t length, const CAMELLIA_KEY *key,
+                             unsigned char *ivec, int *num);
+void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t length, const CAMELLIA_KEY *key,
+                             unsigned char ivec[CAMELLIA_BLOCK_SIZE],
+                             unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE],
+                             unsigned int *num);
+
+# ifdef  __cplusplus
+}
+# endif
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/cast.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/cast.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/cast.h	(revision 331)
@@ -0,0 +1,53 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_CAST_H
+# define HEADER_CAST_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_CAST
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+# define CAST_ENCRYPT    1
+# define CAST_DECRYPT    0
+
+# define CAST_LONG unsigned int
+
+# define CAST_BLOCK      8
+# define CAST_KEY_LENGTH 16
+
+typedef struct cast_key_st {
+    CAST_LONG data[32];
+    int short_key;              /* Use reduced rounds for short key */
+} CAST_KEY;
+
+void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data);
+void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                      const CAST_KEY *key, int enc);
+void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key);
+void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key);
+void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                      long length, const CAST_KEY *ks, unsigned char *iv,
+                      int enc);
+void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                        long length, const CAST_KEY *schedule,
+                        unsigned char *ivec, int *num, int enc);
+void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+                        long length, const CAST_KEY *schedule,
+                        unsigned char *ivec, int *num);
+
+# ifdef  __cplusplus
+}
+# endif
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/cmac.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/cmac.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/cmac.h	(revision 331)
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2010-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
+ */
+
+#ifndef HEADER_CMAC_H
+# define HEADER_CMAC_H
+
+# ifndef OPENSSL_NO_CMAC
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# include <openssl/evp.h>
+
+/* Opaque */
+typedef struct CMAC_CTX_st CMAC_CTX;
+
+CMAC_CTX *CMAC_CTX_new(void);
+void CMAC_CTX_cleanup(CMAC_CTX *ctx);
+void CMAC_CTX_free(CMAC_CTX *ctx);
+EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx);
+int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in);
+
+int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen,
+              const EVP_CIPHER *cipher, ENGINE *impl);
+int CMAC_Update(CMAC_CTX *ctx, const void *data, size_t dlen);
+int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen);
+int CMAC_resume(CMAC_CTX *ctx);
+
+#ifdef  __cplusplus
+}
+#endif
+
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/cms.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/cms.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/cms.h	(revision 331)
@@ -0,0 +1,512 @@
+/*
+ * Copyright 2008-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
+ */
+
+#ifndef HEADER_CMS_H
+# define HEADER_CMS_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_CMS
+# include <openssl/x509.h>
+# include <openssl/x509v3.h>
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+typedef struct CMS_ContentInfo_st CMS_ContentInfo;
+typedef struct CMS_SignerInfo_st CMS_SignerInfo;
+typedef struct CMS_CertificateChoices CMS_CertificateChoices;
+typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice;
+typedef struct CMS_RecipientInfo_st CMS_RecipientInfo;
+typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest;
+typedef struct CMS_Receipt_st CMS_Receipt;
+typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey;
+typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute;
+
+DEFINE_STACK_OF(CMS_SignerInfo)
+DEFINE_STACK_OF(CMS_RecipientEncryptedKey)
+DEFINE_STACK_OF(CMS_RecipientInfo)
+DEFINE_STACK_OF(CMS_RevocationInfoChoice)
+DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
+DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest)
+DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
+
+# define CMS_SIGNERINFO_ISSUER_SERIAL    0
+# define CMS_SIGNERINFO_KEYIDENTIFIER    1
+
+# define CMS_RECIPINFO_NONE              -1
+# define CMS_RECIPINFO_TRANS             0
+# define CMS_RECIPINFO_AGREE             1
+# define CMS_RECIPINFO_KEK               2
+# define CMS_RECIPINFO_PASS              3
+# define CMS_RECIPINFO_OTHER             4
+
+/* S/MIME related flags */
+
+# define CMS_TEXT                        0x1
+# define CMS_NOCERTS                     0x2
+# define CMS_NO_CONTENT_VERIFY           0x4
+# define CMS_NO_ATTR_VERIFY              0x8
+# define CMS_NOSIGS                      \
+                        (CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY)
+# define CMS_NOINTERN                    0x10
+# define CMS_NO_SIGNER_CERT_VERIFY       0x20
+# define CMS_NOVERIFY                    0x20
+# define CMS_DETACHED                    0x40
+# define CMS_BINARY                      0x80
+# define CMS_NOATTR                      0x100
+# define CMS_NOSMIMECAP                  0x200
+# define CMS_NOOLDMIMETYPE               0x400
+# define CMS_CRLFEOL                     0x800
+# define CMS_STREAM                      0x1000
+# define CMS_NOCRL                       0x2000
+# define CMS_PARTIAL                     0x4000
+# define CMS_REUSE_DIGEST                0x8000
+# define CMS_USE_KEYID                   0x10000
+# define CMS_DEBUG_DECRYPT               0x20000
+# define CMS_KEY_PARAM                   0x40000
+# define CMS_ASCIICRLF                   0x80000
+
+const ASN1_OBJECT *CMS_get0_type(const CMS_ContentInfo *cms);
+
+BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont);
+int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio);
+
+ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms);
+int CMS_is_detached(CMS_ContentInfo *cms);
+int CMS_set_detached(CMS_ContentInfo *cms, int detached);
+
+# ifdef HEADER_PEM_H
+DECLARE_PEM_rw_const(CMS, CMS_ContentInfo)
+# endif
+int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms);
+CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms);
+int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms);
+
+BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms);
+int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags);
+int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in,
+                             int flags);
+CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont);
+int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags);
+
+int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont,
+              unsigned int flags);
+
+CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey,
+                          STACK_OF(X509) *certs, BIO *data,
+                          unsigned int flags);
+
+CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
+                                  X509 *signcert, EVP_PKEY *pkey,
+                                  STACK_OF(X509) *certs, unsigned int flags);
+
+int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags);
+CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags);
+
+int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+                      unsigned int flags);
+CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
+                                   unsigned int flags);
+
+int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
+                              const unsigned char *key, size_t keylen,
+                              BIO *dcont, BIO *out, unsigned int flags);
+
+CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
+                                           const unsigned char *key,
+                                           size_t keylen, unsigned int flags);
+
+int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
+                               const unsigned char *key, size_t keylen);
+
+int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
+               X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags);
+
+int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
+                       STACK_OF(X509) *certs,
+                       X509_STORE *store, unsigned int flags);
+
+STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);
+
+CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
+                             const EVP_CIPHER *cipher, unsigned int flags);
+
+int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert,
+                BIO *dcont, BIO *out, unsigned int flags);
+
+int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert);
+int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
+                         unsigned char *key, size_t keylen,
+                         const unsigned char *id, size_t idlen);
+int CMS_decrypt_set1_password(CMS_ContentInfo *cms,
+                              unsigned char *pass, ossl_ssize_t passlen);
+
+STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
+int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
+EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri);
+CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher);
+CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
+                                           X509 *recip, unsigned int flags);
+int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey);
+int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert);
+int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
+                                     EVP_PKEY **pk, X509 **recip,
+                                     X509_ALGOR **palg);
+int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
+                                          ASN1_OCTET_STRING **keyid,
+                                          X509_NAME **issuer,
+                                          ASN1_INTEGER **sno);
+
+CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
+                                          unsigned char *key, size_t keylen,
+                                          unsigned char *id, size_t idlen,
+                                          ASN1_GENERALIZEDTIME *date,
+                                          ASN1_OBJECT *otherTypeId,
+                                          ASN1_TYPE *otherType);
+
+int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
+                                    X509_ALGOR **palg,
+                                    ASN1_OCTET_STRING **pid,
+                                    ASN1_GENERALIZEDTIME **pdate,
+                                    ASN1_OBJECT **potherid,
+                                    ASN1_TYPE **pothertype);
+
+int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
+                               unsigned char *key, size_t keylen);
+
+int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,
+                                   const unsigned char *id, size_t idlen);
+
+int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri,
+                                    unsigned char *pass,
+                                    ossl_ssize_t passlen);
+
+CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
+                                               int iter, int wrap_nid,
+                                               int pbe_nid,
+                                               unsigned char *pass,
+                                               ossl_ssize_t passlen,
+                                               const EVP_CIPHER *kekciph);
+
+int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
+int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
+
+int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+                   unsigned int flags);
+CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags);
+
+int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid);
+const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms);
+
+CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms);
+int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert);
+int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert);
+STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms);
+
+CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms);
+int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl);
+int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl);
+STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms);
+
+int CMS_SignedData_init(CMS_ContentInfo *cms);
+CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
+                                X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
+                                unsigned int flags);
+EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si);
+EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si);
+STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms);
+
+void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer);
+int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
+                                  ASN1_OCTET_STRING **keyid,
+                                  X509_NAME **issuer, ASN1_INTEGER **sno);
+int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert);
+int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
+                           unsigned int flags);
+void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk,
+                              X509 **signer, X509_ALGOR **pdig,
+                              X509_ALGOR **psig);
+ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si);
+int CMS_SignerInfo_sign(CMS_SignerInfo *si);
+int CMS_SignerInfo_verify(CMS_SignerInfo *si);
+int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain);
+
+int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs);
+int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
+                            int algnid, int keysize);
+int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap);
+
+int CMS_signed_get_attr_count(const CMS_SignerInfo *si);
+int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
+                               int lastpos);
+int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, const ASN1_OBJECT *obj,
+                               int lastpos);
+X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc);
+X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc);
+int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
+int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
+                                const ASN1_OBJECT *obj, int type,
+                                const void *bytes, int len);
+int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
+                                int nid, int type,
+                                const void *bytes, int len);
+int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
+                                const char *attrname, int type,
+                                const void *bytes, int len);
+void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, const ASN1_OBJECT *oid,
+                                  int lastpos, int type);
+
+int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si);
+int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
+                                 int lastpos);
+int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si,
+                                 const ASN1_OBJECT *obj, int lastpos);
+X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc);
+X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc);
+int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
+int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
+                                  const ASN1_OBJECT *obj, int type,
+                                  const void *bytes, int len);
+int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
+                                  int nid, int type,
+                                  const void *bytes, int len);
+int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
+                                  const char *attrname, int type,
+                                  const void *bytes, int len);
+void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
+                                    int lastpos, int type);
+
+# ifdef HEADER_X509V3_H
+
+int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr);
+CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
+                                               int allorfirst,
+                                               STACK_OF(GENERAL_NAMES)
+                                               *receiptList, STACK_OF(GENERAL_NAMES)
+                                               *receiptsTo);
+int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr);
+void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
+                                    ASN1_STRING **pcid,
+                                    int *pallorfirst,
+                                    STACK_OF(GENERAL_NAMES) **plist,
+                                    STACK_OF(GENERAL_NAMES) **prto);
+# endif
+int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri,
+                                    X509_ALGOR **palg,
+                                    ASN1_OCTET_STRING **pukm);
+STACK_OF(CMS_RecipientEncryptedKey)
+*CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri);
+
+int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri,
+                                        X509_ALGOR **pubalg,
+                                        ASN1_BIT_STRING **pubkey,
+                                        ASN1_OCTET_STRING **keyid,
+                                        X509_NAME **issuer,
+                                        ASN1_INTEGER **sno);
+
+int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert);
+
+int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek,
+                                      ASN1_OCTET_STRING **keyid,
+                                      ASN1_GENERALIZEDTIME **tm,
+                                      CMS_OtherKeyAttribute **other,
+                                      X509_NAME **issuer, ASN1_INTEGER **sno);
+int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek,
+                                       X509 *cert);
+int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk);
+EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri);
+int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms,
+                                   CMS_RecipientInfo *ri,
+                                   CMS_RecipientEncryptedKey *rek);
+
+int CMS_SharedInfo_encode(unsigned char **pder, X509_ALGOR *kekalg,
+                          ASN1_OCTET_STRING *ukm, int keylen);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_CMS_strings(void);
+
+/* Error codes for the CMS functions. */
+
+/* Function codes. */
+# define CMS_F_CHECK_CONTENT                              99
+# define CMS_F_CMS_ADD0_CERT                              164
+# define CMS_F_CMS_ADD0_RECIPIENT_KEY                     100
+# define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD                165
+# define CMS_F_CMS_ADD1_RECEIPTREQUEST                    158
+# define CMS_F_CMS_ADD1_RECIPIENT_CERT                    101
+# define CMS_F_CMS_ADD1_SIGNER                            102
+# define CMS_F_CMS_ADD1_SIGNINGTIME                       103
+# define CMS_F_CMS_COMPRESS                               104
+# define CMS_F_CMS_COMPRESSEDDATA_CREATE                  105
+# define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO                106
+# define CMS_F_CMS_COPY_CONTENT                           107
+# define CMS_F_CMS_COPY_MESSAGEDIGEST                     108
+# define CMS_F_CMS_DATA                                   109
+# define CMS_F_CMS_DATAFINAL                              110
+# define CMS_F_CMS_DATAINIT                               111
+# define CMS_F_CMS_DECRYPT                                112
+# define CMS_F_CMS_DECRYPT_SET1_KEY                       113
+# define CMS_F_CMS_DECRYPT_SET1_PASSWORD                  166
+# define CMS_F_CMS_DECRYPT_SET1_PKEY                      114
+# define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX               115
+# define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO               116
+# define CMS_F_CMS_DIGESTEDDATA_DO_FINAL                  117
+# define CMS_F_CMS_DIGEST_VERIFY                          118
+# define CMS_F_CMS_ENCODE_RECEIPT                         161
+# define CMS_F_CMS_ENCRYPT                                119
+# define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO              120
+# define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT                  121
+# define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT                  122
+# define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY                 123
+# define CMS_F_CMS_ENVELOPEDDATA_CREATE                   124
+# define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO                 125
+# define CMS_F_CMS_ENVELOPED_DATA_INIT                    126
+# define CMS_F_CMS_ENV_ASN1_CTRL                          171
+# define CMS_F_CMS_FINAL                                  127
+# define CMS_F_CMS_GET0_CERTIFICATE_CHOICES               128
+# define CMS_F_CMS_GET0_CONTENT                           129
+# define CMS_F_CMS_GET0_ECONTENT_TYPE                     130
+# define CMS_F_CMS_GET0_ENVELOPED                         131
+# define CMS_F_CMS_GET0_REVOCATION_CHOICES                132
+# define CMS_F_CMS_GET0_SIGNED                            133
+# define CMS_F_CMS_MSGSIGDIGEST_ADD1                      162
+# define CMS_F_CMS_RECEIPTREQUEST_CREATE0                 159
+# define CMS_F_CMS_RECEIPT_VERIFY                         160
+# define CMS_F_CMS_RECIPIENTINFO_DECRYPT                  134
+# define CMS_F_CMS_RECIPIENTINFO_ENCRYPT                  169
+# define CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT             178
+# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG            175
+# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID        173
+# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS           172
+# define CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP         174
+# define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT            135
+# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT            136
+# define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID            137
+# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP             138
+# define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP            139
+# define CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT             140
+# define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT             141
+# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS           142
+# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID      143
+# define CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT               167
+# define CMS_F_CMS_RECIPIENTINFO_SET0_KEY                 144
+# define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD            168
+# define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY                145
+# define CMS_F_CMS_SD_ASN1_CTRL                           170
+# define CMS_F_CMS_SET1_IAS                               176
+# define CMS_F_CMS_SET1_KEYID                             177
+# define CMS_F_CMS_SET1_SIGNERIDENTIFIER                  146
+# define CMS_F_CMS_SET_DETACHED                           147
+# define CMS_F_CMS_SIGN                                   148
+# define CMS_F_CMS_SIGNED_DATA_INIT                       149
+# define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN                150
+# define CMS_F_CMS_SIGNERINFO_SIGN                        151
+# define CMS_F_CMS_SIGNERINFO_VERIFY                      152
+# define CMS_F_CMS_SIGNERINFO_VERIFY_CERT                 153
+# define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT              154
+# define CMS_F_CMS_SIGN_RECEIPT                           163
+# define CMS_F_CMS_STREAM                                 155
+# define CMS_F_CMS_UNCOMPRESS                             156
+# define CMS_F_CMS_VERIFY                                 157
+
+/* Reason codes. */
+# define CMS_R_ADD_SIGNER_ERROR                           99
+# define CMS_R_CERTIFICATE_ALREADY_PRESENT                175
+# define CMS_R_CERTIFICATE_HAS_NO_KEYID                   160
+# define CMS_R_CERTIFICATE_VERIFY_ERROR                   100
+# define CMS_R_CIPHER_INITIALISATION_ERROR                101
+# define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR      102
+# define CMS_R_CMS_DATAFINAL_ERROR                        103
+# define CMS_R_CMS_LIB                                    104
+# define CMS_R_CONTENTIDENTIFIER_MISMATCH                 170
+# define CMS_R_CONTENT_NOT_FOUND                          105
+# define CMS_R_CONTENT_TYPE_MISMATCH                      171
+# define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA           106
+# define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA            107
+# define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA               108
+# define CMS_R_CONTENT_VERIFY_ERROR                       109
+# define CMS_R_CTRL_ERROR                                 110
+# define CMS_R_CTRL_FAILURE                               111
+# define CMS_R_DECRYPT_ERROR                              112
+# define CMS_R_ERROR_GETTING_PUBLIC_KEY                   113
+# define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE      114
+# define CMS_R_ERROR_SETTING_KEY                          115
+# define CMS_R_ERROR_SETTING_RECIPIENTINFO                116
+# define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH               117
+# define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER           176
+# define CMS_R_INVALID_KEY_LENGTH                         118
+# define CMS_R_MD_BIO_INIT_ERROR                          119
+# define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH       120
+# define CMS_R_MESSAGEDIGEST_WRONG_LENGTH                 121
+# define CMS_R_MSGSIGDIGEST_ERROR                         172
+# define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE          162
+# define CMS_R_MSGSIGDIGEST_WRONG_LENGTH                  163
+# define CMS_R_NEED_ONE_SIGNER                            164
+# define CMS_R_NOT_A_SIGNED_RECEIPT                       165
+# define CMS_R_NOT_ENCRYPTED_DATA                         122
+# define CMS_R_NOT_KEK                                    123
+# define CMS_R_NOT_KEY_AGREEMENT                          181
+# define CMS_R_NOT_KEY_TRANSPORT                          124
+# define CMS_R_NOT_PWRI                                   177
+# define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE            125
+# define CMS_R_NO_CIPHER                                  126
+# define CMS_R_NO_CONTENT                                 127
+# define CMS_R_NO_CONTENT_TYPE                            173
+# define CMS_R_NO_DEFAULT_DIGEST                          128
+# define CMS_R_NO_DIGEST_SET                              129
+# define CMS_R_NO_KEY                                     130
+# define CMS_R_NO_KEY_OR_CERT                             174
+# define CMS_R_NO_MATCHING_DIGEST                         131
+# define CMS_R_NO_MATCHING_RECIPIENT                      132
+# define CMS_R_NO_MATCHING_SIGNATURE                      166
+# define CMS_R_NO_MSGSIGDIGEST                            167
+# define CMS_R_NO_PASSWORD                                178
+# define CMS_R_NO_PRIVATE_KEY                             133
+# define CMS_R_NO_PUBLIC_KEY                              134
+# define CMS_R_NO_RECEIPT_REQUEST                         168
+# define CMS_R_NO_SIGNERS                                 135
+# define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE     136
+# define CMS_R_RECEIPT_DECODE_ERROR                       169
+# define CMS_R_RECIPIENT_ERROR                            137
+# define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND               138
+# define CMS_R_SIGNFINAL_ERROR                            139
+# define CMS_R_SMIME_TEXT_ERROR                           140
+# define CMS_R_STORE_INIT_ERROR                           141
+# define CMS_R_TYPE_NOT_COMPRESSED_DATA                   142
+# define CMS_R_TYPE_NOT_DATA                              143
+# define CMS_R_TYPE_NOT_DIGESTED_DATA                     144
+# define CMS_R_TYPE_NOT_ENCRYPTED_DATA                    145
+# define CMS_R_TYPE_NOT_ENVELOPED_DATA                    146
+# define CMS_R_UNABLE_TO_FINALIZE_CONTEXT                 147
+# define CMS_R_UNKNOWN_CIPHER                             148
+# define CMS_R_UNKNOWN_DIGEST_ALGORIHM                    149
+# define CMS_R_UNKNOWN_ID                                 150
+# define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM          151
+# define CMS_R_UNSUPPORTED_CONTENT_TYPE                   152
+# define CMS_R_UNSUPPORTED_KEK_ALGORITHM                  153
+# define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM       179
+# define CMS_R_UNSUPPORTED_RECIPIENT_TYPE                 154
+# define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE              155
+# define CMS_R_UNSUPPORTED_TYPE                           156
+# define CMS_R_UNWRAP_ERROR                               157
+# define CMS_R_UNWRAP_FAILURE                             180
+# define CMS_R_VERIFICATION_FAILURE                       158
+# define CMS_R_WRAP_ERROR                                 159
+
+#  ifdef  __cplusplus
+}
+#  endif
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/comp.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/comp.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/comp.h	(revision 331)
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2015-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
+ */
+
+#ifndef HEADER_COMP_H
+# define HEADER_COMP_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_COMP
+# include <openssl/crypto.h>
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+
+
+COMP_CTX *COMP_CTX_new(COMP_METHOD *meth);
+const COMP_METHOD *COMP_CTX_get_method(const COMP_CTX *ctx);
+int COMP_CTX_get_type(const COMP_CTX* comp);
+int COMP_get_type(const COMP_METHOD *meth);
+const char *COMP_get_name(const COMP_METHOD *meth);
+void COMP_CTX_free(COMP_CTX *ctx);
+
+int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen,
+                        unsigned char *in, int ilen);
+int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen,
+                      unsigned char *in, int ilen);
+
+COMP_METHOD *COMP_zlib(void);
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+#define COMP_zlib_cleanup() while(0) continue
+#endif
+
+# ifdef HEADER_BIO_H
+#  ifdef ZLIB
+const BIO_METHOD *BIO_f_zlib(void);
+#  endif
+# endif
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_COMP_strings(void);
+
+/* Error codes for the COMP functions. */
+
+/* Function codes. */
+# define COMP_F_BIO_ZLIB_FLUSH                            99
+# define COMP_F_BIO_ZLIB_NEW                              100
+# define COMP_F_BIO_ZLIB_READ                             101
+# define COMP_F_BIO_ZLIB_WRITE                            102
+
+/* Reason codes. */
+# define COMP_R_ZLIB_DEFLATE_ERROR                        99
+# define COMP_R_ZLIB_INFLATE_ERROR                        100
+# define COMP_R_ZLIB_NOT_SUPPORTED                        101
+
+#  ifdef  __cplusplus
+}
+#  endif
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/conf.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/conf.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/conf.h	(revision 331)
@@ -0,0 +1,216 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef  HEADER_CONF_H
+# define HEADER_CONF_H
+
+# include <openssl/bio.h>
+# include <openssl/lhash.h>
+# include <openssl/stack.h>
+# include <openssl/safestack.h>
+# include <openssl/e_os2.h>
+
+# include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+    char *section;
+    char *name;
+    char *value;
+} CONF_VALUE;
+
+DEFINE_STACK_OF(CONF_VALUE)
+DEFINE_LHASH_OF(CONF_VALUE);
+
+struct conf_st;
+struct conf_method_st;
+typedef struct conf_method_st CONF_METHOD;
+
+struct conf_method_st {
+    const char *name;
+    CONF *(*create) (CONF_METHOD *meth);
+    int (*init) (CONF *conf);
+    int (*destroy) (CONF *conf);
+    int (*destroy_data) (CONF *conf);
+    int (*load_bio) (CONF *conf, BIO *bp, long *eline);
+    int (*dump) (const CONF *conf, BIO *bp);
+    int (*is_number) (const CONF *conf, char c);
+    int (*to_int) (const CONF *conf, char c);
+    int (*load) (CONF *conf, const char *name, long *eline);
+};
+
+/* Module definitions */
+
+typedef struct conf_imodule_st CONF_IMODULE;
+typedef struct conf_module_st CONF_MODULE;
+
+DEFINE_STACK_OF(CONF_MODULE)
+DEFINE_STACK_OF(CONF_IMODULE)
+
+/* DSO module function typedefs */
+typedef int conf_init_func (CONF_IMODULE *md, const CONF *cnf);
+typedef void conf_finish_func (CONF_IMODULE *md);
+
+# define CONF_MFLAGS_IGNORE_ERRORS       0x1
+# define CONF_MFLAGS_IGNORE_RETURN_CODES 0x2
+# define CONF_MFLAGS_SILENT              0x4
+# define CONF_MFLAGS_NO_DSO              0x8
+# define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10
+# define CONF_MFLAGS_DEFAULT_SECTION     0x20
+
+int CONF_set_default_method(CONF_METHOD *meth);
+void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash);
+LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file,
+                                long *eline);
+# ifndef OPENSSL_NO_STDIO
+LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp,
+                                   long *eline);
+# endif
+LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,
+                                    long *eline);
+STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf,
+                                       const char *section);
+char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group,
+                      const char *name);
+long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group,
+                     const char *name);
+void CONF_free(LHASH_OF(CONF_VALUE) *conf);
+#ifndef OPENSSL_NO_STDIO
+int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out);
+#endif
+int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out);
+
+DEPRECATEDIN_1_1_0(void OPENSSL_config(const char *config_name))
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+# define OPENSSL_no_config() \
+    OPENSSL_init_crypto(OPENSSL_INIT_NO_LOAD_CONFIG, NULL)
+#endif
+
+/*
+ * New conf code.  The semantics are different from the functions above. If
+ * that wasn't the case, the above functions would have been replaced
+ */
+
+struct conf_st {
+    CONF_METHOD *meth;
+    void *meth_data;
+    LHASH_OF(CONF_VALUE) *data;
+};
+
+CONF *NCONF_new(CONF_METHOD *meth);
+CONF_METHOD *NCONF_default(void);
+CONF_METHOD *NCONF_WIN32(void);
+void NCONF_free(CONF *conf);
+void NCONF_free_data(CONF *conf);
+
+int NCONF_load(CONF *conf, const char *file, long *eline);
+# ifndef OPENSSL_NO_STDIO
+int NCONF_load_fp(CONF *conf, FILE *fp, long *eline);
+# endif
+int NCONF_load_bio(CONF *conf, BIO *bp, long *eline);
+STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf,
+                                        const char *section);
+char *NCONF_get_string(const CONF *conf, const char *group, const char *name);
+int NCONF_get_number_e(const CONF *conf, const char *group, const char *name,
+                       long *result);
+#ifndef OPENSSL_NO_STDIO
+int NCONF_dump_fp(const CONF *conf, FILE *out);
+#endif
+int NCONF_dump_bio(const CONF *conf, BIO *out);
+
+#define NCONF_get_number(c,g,n,r) NCONF_get_number_e(c,g,n,r)
+
+/* Module functions */
+
+int CONF_modules_load(const CONF *cnf, const char *appname,
+                      unsigned long flags);
+int CONF_modules_load_file(const char *filename, const char *appname,
+                           unsigned long flags);
+void CONF_modules_unload(int all);
+void CONF_modules_finish(void);
+#if OPENSSL_API_COMPAT < 0x10100000L
+# define CONF_modules_free() while(0) continue
+#endif
+int CONF_module_add(const char *name, conf_init_func *ifunc,
+                    conf_finish_func *ffunc);
+
+const char *CONF_imodule_get_name(const CONF_IMODULE *md);
+const char *CONF_imodule_get_value(const CONF_IMODULE *md);
+void *CONF_imodule_get_usr_data(const CONF_IMODULE *md);
+void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data);
+CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md);
+unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md);
+void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags);
+void *CONF_module_get_usr_data(CONF_MODULE *pmod);
+void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data);
+
+char *CONF_get1_default_config_file(void);
+
+int CONF_parse_list(const char *list, int sep, int nospc,
+                    int (*list_cb) (const char *elem, int len, void *usr),
+                    void *arg);
+
+void OPENSSL_load_builtin_modules(void);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_CONF_strings(void);
+
+/* Error codes for the CONF functions. */
+
+/* Function codes. */
+# define CONF_F_CONF_DUMP_FP                              104
+# define CONF_F_CONF_LOAD                                 100
+# define CONF_F_CONF_LOAD_FP                              103
+# define CONF_F_CONF_PARSE_LIST                           119
+# define CONF_F_DEF_LOAD                                  120
+# define CONF_F_DEF_LOAD_BIO                              121
+# define CONF_F_MODULE_INIT                               115
+# define CONF_F_MODULE_LOAD_DSO                           117
+# define CONF_F_MODULE_RUN                                118
+# define CONF_F_NCONF_DUMP_BIO                            105
+# define CONF_F_NCONF_DUMP_FP                             106
+# define CONF_F_NCONF_GET_NUMBER_E                        112
+# define CONF_F_NCONF_GET_SECTION                         108
+# define CONF_F_NCONF_GET_STRING                          109
+# define CONF_F_NCONF_LOAD                                113
+# define CONF_F_NCONF_LOAD_BIO                            110
+# define CONF_F_NCONF_LOAD_FP                             114
+# define CONF_F_NCONF_NEW                                 111
+# define CONF_F_STR_COPY                                  101
+
+/* Reason codes. */
+# define CONF_R_ERROR_LOADING_DSO                         110
+# define CONF_R_LIST_CANNOT_BE_NULL                       115
+# define CONF_R_MISSING_CLOSE_SQUARE_BRACKET              100
+# define CONF_R_MISSING_EQUAL_SIGN                        101
+# define CONF_R_MISSING_INIT_FUNCTION                     112
+# define CONF_R_MODULE_INITIALIZATION_ERROR               109
+# define CONF_R_NO_CLOSE_BRACE                            102
+# define CONF_R_NO_CONF                                   105
+# define CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE           106
+# define CONF_R_NO_SECTION                                107
+# define CONF_R_NO_SUCH_FILE                              114
+# define CONF_R_NO_VALUE                                  108
+# define CONF_R_UNABLE_TO_CREATE_NEW_SECTION              103
+# define CONF_R_UNKNOWN_MODULE_NAME                       113
+# define CONF_R_VARIABLE_HAS_NO_VALUE                     104
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/conf_api.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/conf_api.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/conf_api.h	(revision 331)
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef  HEADER_CONF_API_H
+# define HEADER_CONF_API_H
+
+# include <openssl/lhash.h>
+# include <openssl/conf.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Up until OpenSSL 0.9.5a, this was new_section */
+CONF_VALUE *_CONF_new_section(CONF *conf, const char *section);
+/* Up until OpenSSL 0.9.5a, this was get_section */
+CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section);
+/* Up until OpenSSL 0.9.5a, this was CONF_get_section */
+STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf,
+                                               const char *section);
+
+int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value);
+char *_CONF_get_string(const CONF *conf, const char *section,
+                       const char *name);
+long _CONF_get_number(const CONF *conf, const char *section,
+                      const char *name);
+
+int _CONF_new_data(CONF *conf);
+void _CONF_free_data(CONF *conf);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/crypto.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/crypto.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/crypto.h	(revision 331)
@@ -0,0 +1,463 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_CRYPTO_H
+# define HEADER_CRYPTO_H
+
+# include <stdlib.h>
+# include <time.h>
+
+# include <openssl/e_os2.h>
+
+# ifndef OPENSSL_NO_STDIO
+#  include <stdio.h>
+# endif
+
+# include <openssl/stack.h>
+# include <openssl/safestack.h>
+# include <openssl/opensslv.h>
+# include <openssl/ossl_typ.h>
+# include <openssl/opensslconf.h>
+
+# ifdef CHARSET_EBCDIC
+#  include <openssl/ebcdic.h>
+# endif
+
+/*
+ * Resolve problems on some operating systems with symbol names that clash
+ * one way or another
+ */
+# include <openssl/symhacks.h>
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  include <openssl/opensslv.h>
+# endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  define SSLeay                  OpenSSL_version_num
+#  define SSLeay_version          OpenSSL_version
+#  define SSLEAY_VERSION_NUMBER   OPENSSL_VERSION_NUMBER
+#  define SSLEAY_VERSION          OPENSSL_VERSION
+#  define SSLEAY_CFLAGS           OPENSSL_CFLAGS
+#  define SSLEAY_BUILT_ON         OPENSSL_BUILT_ON
+#  define SSLEAY_PLATFORM         OPENSSL_PLATFORM
+#  define SSLEAY_DIR              OPENSSL_DIR
+
+/*
+ * Old type for allocating dynamic locks. No longer used. Use the new thread
+ * API instead.
+ */
+typedef struct {
+    int dummy;
+} CRYPTO_dynlock;
+
+# endif /* OPENSSL_API_COMPAT */
+
+typedef void CRYPTO_RWLOCK;
+
+CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void);
+int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock);
+int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock);
+int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock);
+void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock);
+
+int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock);
+
+/*
+ * The following can be used to detect memory leaks in the library. If
+ * used, it turns on malloc checking
+ */
+# define CRYPTO_MEM_CHECK_OFF     0x0   /* Control only */
+# define CRYPTO_MEM_CHECK_ON      0x1   /* Control and mode bit */
+# define CRYPTO_MEM_CHECK_ENABLE  0x2   /* Control and mode bit */
+# define CRYPTO_MEM_CHECK_DISABLE 0x3   /* Control only */
+
+struct crypto_ex_data_st {
+    STACK_OF(void) *sk;
+};
+DEFINE_STACK_OF(void)
+
+/*
+ * Per class, we have a STACK of function pointers.
+ */
+# define CRYPTO_EX_INDEX_SSL              0
+# define CRYPTO_EX_INDEX_SSL_CTX          1
+# define CRYPTO_EX_INDEX_SSL_SESSION      2
+# define CRYPTO_EX_INDEX_X509             3
+# define CRYPTO_EX_INDEX_X509_STORE       4
+# define CRYPTO_EX_INDEX_X509_STORE_CTX   5
+# define CRYPTO_EX_INDEX_DH               6
+# define CRYPTO_EX_INDEX_DSA              7
+# define CRYPTO_EX_INDEX_EC_KEY           8
+# define CRYPTO_EX_INDEX_RSA              9
+# define CRYPTO_EX_INDEX_ENGINE          10
+# define CRYPTO_EX_INDEX_UI              11
+# define CRYPTO_EX_INDEX_BIO             12
+# define CRYPTO_EX_INDEX_APP             13
+# define CRYPTO_EX_INDEX__COUNT          14
+
+/*
+ * This is the default callbacks, but we can have others as well: this is
+ * needed in Win32 where the application malloc and the library malloc may
+ * not be the same.
+ */
+#define OPENSSL_malloc_init() \
+    CRYPTO_set_mem_functions(CRYPTO_malloc, CRYPTO_realloc, CRYPTO_free)
+
+int CRYPTO_mem_ctrl(int mode);
+
+# define OPENSSL_malloc(num) \
+        CRYPTO_malloc(num, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_zalloc(num) \
+        CRYPTO_zalloc(num, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_realloc(addr, num) \
+        CRYPTO_realloc(addr, num, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_clear_realloc(addr, old_num, num) \
+        CRYPTO_clear_realloc(addr, old_num, num, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_clear_free(addr, num) \
+        CRYPTO_clear_free(addr, num, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_free(addr) \
+        CRYPTO_free(addr, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_memdup(str, s) \
+        CRYPTO_memdup((str), s, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_strdup(str) \
+        CRYPTO_strdup(str, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_strndup(str, n) \
+        CRYPTO_strndup(str, n, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_secure_malloc(num) \
+        CRYPTO_secure_malloc(num, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_secure_zalloc(num) \
+        CRYPTO_secure_zalloc(num, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_secure_free(addr) \
+        CRYPTO_secure_free(addr, OPENSSL_FILE, OPENSSL_LINE)
+# define OPENSSL_secure_actual_size(ptr) \
+        CRYPTO_secure_actual_size(ptr)
+
+size_t OPENSSL_strlcpy(char *dst, const char *src, size_t siz);
+size_t OPENSSL_strlcat(char *dst, const char *src, size_t siz);
+size_t OPENSSL_strnlen(const char *str, size_t maxlen);
+char *OPENSSL_buf2hexstr(const unsigned char *buffer, long len);
+unsigned char *OPENSSL_hexstr2buf(const char *str, long *len);
+int OPENSSL_hexchar2int(unsigned char c);
+
+# define OPENSSL_MALLOC_MAX_NELEMS(type)  (((1U<<(sizeof(int)*8-1))-1)/sizeof(type))
+
+unsigned long OpenSSL_version_num(void);
+const char *OpenSSL_version(int type);
+# define OPENSSL_VERSION          0
+# define OPENSSL_CFLAGS           1
+# define OPENSSL_BUILT_ON         2
+# define OPENSSL_PLATFORM         3
+# define OPENSSL_DIR              4
+# define OPENSSL_ENGINES_DIR      5
+
+int OPENSSL_issetugid(void);
+
+typedef void CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+                           int idx, long argl, void *argp);
+typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+                             int idx, long argl, void *argp);
+typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
+                           void *srcp, int idx, long argl, void *argp);
+__owur int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
+                            CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+                            CRYPTO_EX_free *free_func);
+/* No longer use an index. */
+int CRYPTO_free_ex_index(int class_index, int idx);
+
+/*
+ * Initialise/duplicate/free CRYPTO_EX_DATA variables corresponding to a
+ * given class (invokes whatever per-class callbacks are applicable)
+ */
+int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
+int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
+                       const CRYPTO_EX_DATA *from);
+
+void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
+
+/*
+ * Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular
+ * index (relative to the class type involved)
+ */
+int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val);
+void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx);
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+/*
+ * This function cleans up all "ex_data" state. It mustn't be called under
+ * potential race-conditions.
+ */
+# define CRYPTO_cleanup_all_ex_data() while(0) continue
+
+/*
+ * The old locking functions have been removed completely without compatibility
+ * macros. This is because the old functions either could not properly report
+ * errors, or the returned error values were not clearly documented.
+ * Replacing the locking functions with with no-ops would cause race condition
+ * issues in the affected applications. It is far better for them to fail at
+ * compile time.
+ * On the other hand, the locking callbacks are no longer used.  Consequently,
+ * the callback management functions can be safely replaced with no-op macros.
+ */
+#  define CRYPTO_num_locks()            (1)
+#  define CRYPTO_set_locking_callback(func)
+#  define CRYPTO_get_locking_callback()         (NULL)
+#  define CRYPTO_set_add_lock_callback(func)
+#  define CRYPTO_get_add_lock_callback()        (NULL)
+
+/*
+ * These defines where used in combination with the old locking callbacks,
+ * they are not called anymore, but old code that's not called might still
+ * use them.
+ */
+#  define CRYPTO_LOCK             1
+#  define CRYPTO_UNLOCK           2
+#  define CRYPTO_READ             4
+#  define CRYPTO_WRITE            8
+
+/* This structure is no longer used */
+typedef struct crypto_threadid_st {
+    int dummy;
+} CRYPTO_THREADID;
+/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */
+#  define CRYPTO_THREADID_set_numeric(id, val)
+#  define CRYPTO_THREADID_set_pointer(id, ptr)
+#  define CRYPTO_THREADID_set_callback(threadid_func)   (0)
+#  define CRYPTO_THREADID_get_callback()                (NULL)
+#  define CRYPTO_THREADID_current(id)
+#  define CRYPTO_THREADID_cmp(a, b)                     (-1)
+#  define CRYPTO_THREADID_cpy(dest, src)
+#  define CRYPTO_THREADID_hash(id)                      (0UL)
+
+#  if OPENSSL_API_COMPAT < 0x10000000L
+#   define CRYPTO_set_id_callback(func)
+#   define CRYPTO_get_id_callback()                     (NULL)
+#   define CRYPTO_thread_id()                           (0UL)
+#  endif /* OPENSSL_API_COMPAT < 0x10000000L */
+
+#  define CRYPTO_set_dynlock_create_callback(dyn_create_function)
+#  define CRYPTO_set_dynlock_lock_callback(dyn_lock_function)
+#  define CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function)
+#  define CRYPTO_get_dynlock_create_callback()          (NULL)
+#  define CRYPTO_get_dynlock_lock_callback()            (NULL)
+#  define CRYPTO_get_dynlock_destroy_callback()         (NULL)
+# endif /* OPENSSL_API_COMPAT < 0x10100000L */
+
+int CRYPTO_set_mem_functions(
+        void *(*m) (size_t, const char *, int),
+        void *(*r) (void *, size_t, const char *, int),
+        void (*f) (void *, const char *, int));
+int CRYPTO_set_mem_debug(int flag);
+void CRYPTO_get_mem_functions(
+        void *(**m) (size_t, const char *, int),
+        void *(**r) (void *, size_t, const char *, int),
+        void (**f) (void *, const char *, int));
+
+void *CRYPTO_malloc(size_t num, const char *file, int line);
+void *CRYPTO_zalloc(size_t num, const char *file, int line);
+void *CRYPTO_memdup(const void *str, size_t siz, const char *file, int line);
+char *CRYPTO_strdup(const char *str, const char *file, int line);
+char *CRYPTO_strndup(const char *str, size_t s, const char *file, int line);
+void CRYPTO_free(void *ptr, const char *file, int line);
+void CRYPTO_clear_free(void *ptr, size_t num, const char *file, int line);
+void *CRYPTO_realloc(void *addr, size_t num, const char *file, int line);
+void *CRYPTO_clear_realloc(void *addr, size_t old_num, size_t num,
+                           const char *file, int line);
+
+int CRYPTO_secure_malloc_init(size_t sz, int minsize);
+int CRYPTO_secure_malloc_done(void);
+void *CRYPTO_secure_malloc(size_t num, const char *file, int line);
+void *CRYPTO_secure_zalloc(size_t num, const char *file, int line);
+void CRYPTO_secure_free(void *ptr, const char *file, int line);
+int CRYPTO_secure_allocated(const void *ptr);
+int CRYPTO_secure_malloc_initialized(void);
+size_t CRYPTO_secure_actual_size(void *ptr);
+size_t CRYPTO_secure_used(void);
+
+void OPENSSL_cleanse(void *ptr, size_t len);
+
+# ifndef OPENSSL_NO_CRYPTO_MDEBUG
+#  define OPENSSL_mem_debug_push(info) \
+        CRYPTO_mem_debug_push(info, OPENSSL_FILE, OPENSSL_LINE)
+#  define OPENSSL_mem_debug_pop() \
+        CRYPTO_mem_debug_pop()
+int CRYPTO_mem_debug_push(const char *info, const char *file, int line);
+int CRYPTO_mem_debug_pop(void);
+
+/*-
+ * Debugging functions (enabled by CRYPTO_set_mem_debug(1))
+ * The flag argument has the following significance:
+ *   0:   called before the actual memory allocation has taken place
+ *   1:   called after the actual memory allocation has taken place
+ */
+void CRYPTO_mem_debug_malloc(void *addr, size_t num, int flag,
+        const char *file, int line);
+void CRYPTO_mem_debug_realloc(void *addr1, void *addr2, size_t num, int flag,
+        const char *file, int line);
+void CRYPTO_mem_debug_free(void *addr, int flag,
+        const char *file, int line);
+
+#  ifndef OPENSSL_NO_STDIO
+int CRYPTO_mem_leaks_fp(FILE *);
+#  endif
+int CRYPTO_mem_leaks(BIO *bio);
+# endif
+
+/* die if we have to */
+ossl_noreturn void OPENSSL_die(const char *assertion, const char *file, int line);
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  define OpenSSLDie(f,l,a) OPENSSL_die((a),(f),(l))
+# endif
+# define OPENSSL_assert(e) \
+    (void)((e) ? 0 : (OPENSSL_die("assertion failed: " #e, OPENSSL_FILE, OPENSSL_LINE), 1))
+
+int OPENSSL_isservice(void);
+
+int FIPS_mode(void);
+int FIPS_mode_set(int r);
+
+void OPENSSL_init(void);
+
+struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result);
+int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec);
+int OPENSSL_gmtime_diff(int *pday, int *psec,
+                        const struct tm *from, const struct tm *to);
+
+/*
+ * CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal.
+ * It takes an amount of time dependent on |len|, but independent of the
+ * contents of |a| and |b|. Unlike memcmp, it cannot be used to put elements
+ * into a defined order as the return value when a != b is undefined, other
+ * than to be non-zero.
+ */
+int CRYPTO_memcmp(const volatile void * volatile in_a,
+                  const volatile void * volatile in_b,
+                  size_t len);
+
+/* Standard initialisation options */
+# define OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS 0x00000001L
+# define OPENSSL_INIT_LOAD_CRYPTO_STRINGS    0x00000002L
+# define OPENSSL_INIT_ADD_ALL_CIPHERS        0x00000004L
+# define OPENSSL_INIT_ADD_ALL_DIGESTS        0x00000008L
+# define OPENSSL_INIT_NO_ADD_ALL_CIPHERS     0x00000010L
+# define OPENSSL_INIT_NO_ADD_ALL_DIGESTS     0x00000020L
+# define OPENSSL_INIT_LOAD_CONFIG            0x00000040L
+# define OPENSSL_INIT_NO_LOAD_CONFIG         0x00000080L
+# define OPENSSL_INIT_ASYNC                  0x00000100L
+# define OPENSSL_INIT_ENGINE_RDRAND          0x00000200L
+# define OPENSSL_INIT_ENGINE_DYNAMIC         0x00000400L
+# define OPENSSL_INIT_ENGINE_OPENSSL         0x00000800L
+# define OPENSSL_INIT_ENGINE_CRYPTODEV       0x00001000L
+# define OPENSSL_INIT_ENGINE_CAPI            0x00002000L
+# define OPENSSL_INIT_ENGINE_PADLOCK         0x00004000L
+# define OPENSSL_INIT_ENGINE_AFALG           0x00008000L
+/* OPENSSL_INIT flag 0x00010000 reserved for internal use */
+/* OPENSSL_INIT flag range 0xfff00000 reserved for OPENSSL_init_ssl() */
+/* Max OPENSSL_INIT flag value is 0x80000000 */
+
+/* openssl and dasync not counted as builtin */
+# define OPENSSL_INIT_ENGINE_ALL_BUILTIN \
+    (OPENSSL_INIT_ENGINE_RDRAND | OPENSSL_INIT_ENGINE_DYNAMIC \
+    | OPENSSL_INIT_ENGINE_CRYPTODEV | OPENSSL_INIT_ENGINE_CAPI | \
+    OPENSSL_INIT_ENGINE_PADLOCK)
+
+
+/* Library initialisation functions */
+void OPENSSL_cleanup(void);
+int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
+int OPENSSL_atexit(void (*handler)(void));
+void OPENSSL_thread_stop(void);
+
+/* Low-level control of initialization */
+OPENSSL_INIT_SETTINGS *OPENSSL_INIT_new(void);
+# ifndef OPENSSL_NO_STDIO
+int OPENSSL_INIT_set_config_appname(OPENSSL_INIT_SETTINGS *settings,
+                                    const char *config_file);
+# endif
+void OPENSSL_INIT_free(OPENSSL_INIT_SETTINGS *settings);
+
+# if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG)
+#  if defined(_WIN32)
+#   if defined(BASETYPES) || defined(_WINDEF_H)
+/* application has to include <windows.h> in order to use this */
+typedef DWORD CRYPTO_THREAD_LOCAL;
+typedef DWORD CRYPTO_THREAD_ID;
+
+typedef LONG CRYPTO_ONCE;
+#    define CRYPTO_ONCE_STATIC_INIT 0
+#   endif
+#  else
+#   include <pthread.h>
+typedef pthread_once_t CRYPTO_ONCE;
+typedef pthread_key_t CRYPTO_THREAD_LOCAL;
+typedef pthread_t CRYPTO_THREAD_ID;
+
+#   define CRYPTO_ONCE_STATIC_INIT PTHREAD_ONCE_INIT
+#  endif
+# endif
+
+# if !defined(CRYPTO_ONCE_STATIC_INIT)
+typedef unsigned int CRYPTO_ONCE;
+typedef unsigned int CRYPTO_THREAD_LOCAL;
+typedef unsigned int CRYPTO_THREAD_ID;
+#  define CRYPTO_ONCE_STATIC_INIT 0
+# endif
+
+int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void));
+
+int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *));
+void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key);
+int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val);
+int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key);
+
+CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void);
+int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_CRYPTO_strings(void);
+
+/* Error codes for the CRYPTO functions. */
+
+/* Function codes. */
+# define CRYPTO_F_CRYPTO_DUP_EX_DATA                      110
+# define CRYPTO_F_CRYPTO_FREE_EX_DATA                     111
+# define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX                 100
+# define CRYPTO_F_CRYPTO_MEMDUP                           115
+# define CRYPTO_F_CRYPTO_NEW_EX_DATA                      112
+# define CRYPTO_F_CRYPTO_SET_EX_DATA                      102
+# define CRYPTO_F_FIPS_MODE_SET                           109
+# define CRYPTO_F_GET_AND_LOCK                            113
+# define CRYPTO_F_OPENSSL_BUF2HEXSTR                      117
+# define CRYPTO_F_OPENSSL_HEXSTR2BUF                      118
+# define CRYPTO_F_OPENSSL_INIT_CRYPTO                     116
+
+/* Reason codes. */
+# define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED                 101
+# define CRYPTO_R_ILLEGAL_HEX_DIGIT                       102
+# define CRYPTO_R_ODD_NUMBER_OF_DIGITS                    103
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ct.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ct.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ct.h	(revision 331)
@@ -0,0 +1,533 @@
+/*
+ * 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
+ */
+
+#ifndef HEADER_CT_H
+# define HEADER_CT_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_CT
+# include <openssl/ossl_typ.h>
+# include <openssl/safestack.h>
+# include <openssl/x509.h>
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+
+/* Minimum RSA key size, from RFC6962 */
+# define SCT_MIN_RSA_BITS 2048
+
+/* All hashes are SHA256 in v1 of Certificate Transparency */
+# define CT_V1_HASHLEN SHA256_DIGEST_LENGTH
+
+typedef enum {
+    CT_LOG_ENTRY_TYPE_NOT_SET = -1,
+    CT_LOG_ENTRY_TYPE_X509 = 0,
+    CT_LOG_ENTRY_TYPE_PRECERT = 1
+} ct_log_entry_type_t;
+
+typedef enum {
+    SCT_VERSION_NOT_SET = -1,
+    SCT_VERSION_V1 = 0
+} sct_version_t;
+
+typedef enum {
+    SCT_SOURCE_UNKNOWN,
+    SCT_SOURCE_TLS_EXTENSION,
+    SCT_SOURCE_X509V3_EXTENSION,
+    SCT_SOURCE_OCSP_STAPLED_RESPONSE
+} sct_source_t;
+
+typedef enum {
+    SCT_VALIDATION_STATUS_NOT_SET,
+    SCT_VALIDATION_STATUS_UNKNOWN_LOG,
+    SCT_VALIDATION_STATUS_VALID,
+    SCT_VALIDATION_STATUS_INVALID,
+    SCT_VALIDATION_STATUS_UNVERIFIED,
+    SCT_VALIDATION_STATUS_UNKNOWN_VERSION
+} sct_validation_status_t;
+
+DEFINE_STACK_OF(SCT)
+DEFINE_STACK_OF(CTLOG)
+
+/******************************************
+ * CT policy evaluation context functions *
+ ******************************************/
+
+/*
+ * Creates a new, empty policy evaluation context.
+ * The caller is responsible for calling CT_POLICY_EVAL_CTX_free when finished
+ * with the CT_POLICY_EVAL_CTX.
+ */
+CT_POLICY_EVAL_CTX *CT_POLICY_EVAL_CTX_new(void);
+
+/* Deletes a policy evaluation context and anything it owns. */
+void CT_POLICY_EVAL_CTX_free(CT_POLICY_EVAL_CTX *ctx);
+
+/* Gets the peer certificate that the SCTs are for */
+X509* CT_POLICY_EVAL_CTX_get0_cert(const CT_POLICY_EVAL_CTX *ctx);
+
+/*
+ * Sets the certificate associated with the received SCTs.
+ * Increments the reference count of cert.
+ * Returns 1 on success, 0 otherwise.
+ */
+int CT_POLICY_EVAL_CTX_set1_cert(CT_POLICY_EVAL_CTX *ctx, X509 *cert);
+
+/* Gets the issuer of the aforementioned certificate */
+X509* CT_POLICY_EVAL_CTX_get0_issuer(const CT_POLICY_EVAL_CTX *ctx);
+
+/*
+ * Sets the issuer of the certificate associated with the received SCTs.
+ * Increments the reference count of issuer.
+ * Returns 1 on success, 0 otherwise.
+ */
+int CT_POLICY_EVAL_CTX_set1_issuer(CT_POLICY_EVAL_CTX *ctx, X509 *issuer);
+
+/* Gets the CT logs that are trusted sources of SCTs */
+const CTLOG_STORE *CT_POLICY_EVAL_CTX_get0_log_store(const CT_POLICY_EVAL_CTX *ctx);
+
+/* Sets the log store that is in use. It must outlive the CT_POLICY_EVAL_CTX. */
+void CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(CT_POLICY_EVAL_CTX *ctx,
+                                               CTLOG_STORE *log_store);
+
+/*
+ * Gets the time, in milliseconds since the Unix epoch, that will be used as the
+ * current time when checking whether an SCT was issued in the future.
+ * Such SCTs will fail validation, as required by RFC6962.
+ */
+uint64_t CT_POLICY_EVAL_CTX_get_time(const CT_POLICY_EVAL_CTX *ctx);
+
+/*
+ * Sets the time to evaluate SCTs against, in milliseconds since the Unix epoch.
+ * If an SCT's timestamp is after this time, it will be interpreted as having
+ * been issued in the future. RFC6962 states that "TLS clients MUST reject SCTs
+ * whose timestamp is in the future", so an SCT will not validate in this case.
+ */
+void CT_POLICY_EVAL_CTX_set_time(CT_POLICY_EVAL_CTX *ctx, uint64_t time_in_ms);
+
+/*****************
+ * SCT functions *
+ *****************/
+
+/*
+ * Creates a new, blank SCT.
+ * The caller is responsible for calling SCT_free when finished with the SCT.
+ */
+SCT *SCT_new(void);
+
+/*
+ * Creates a new SCT from some base64-encoded strings.
+ * The caller is responsible for calling SCT_free when finished with the SCT.
+ */
+SCT *SCT_new_from_base64(unsigned char version,
+                         const char *logid_base64,
+                         ct_log_entry_type_t entry_type,
+                         uint64_t timestamp,
+                         const char *extensions_base64,
+                         const char *signature_base64);
+
+/*
+ * Frees the SCT and the underlying data structures.
+ */
+void SCT_free(SCT *sct);
+
+/*
+ * Free a stack of SCTs, and the underlying SCTs themselves.
+ * Intended to be compatible with X509V3_EXT_FREE.
+ */
+void SCT_LIST_free(STACK_OF(SCT) *a);
+
+/*
+ * Returns the version of the SCT.
+ */
+sct_version_t SCT_get_version(const SCT *sct);
+
+/*
+ * Set the version of an SCT.
+ * Returns 1 on success, 0 if the version is unrecognized.
+ */
+__owur int SCT_set_version(SCT *sct, sct_version_t version);
+
+/*
+ * Returns the log entry type of the SCT.
+ */
+ct_log_entry_type_t SCT_get_log_entry_type(const SCT *sct);
+
+/*
+ * Set the log entry type of an SCT.
+ * Returns 1 on success, 0 otherwise.
+ */
+__owur int SCT_set_log_entry_type(SCT *sct, ct_log_entry_type_t entry_type);
+
+/*
+ * Gets the ID of the log that an SCT came from.
+ * Ownership of the log ID remains with the SCT.
+ * Returns the length of the log ID.
+ */
+size_t SCT_get0_log_id(const SCT *sct, unsigned char **log_id);
+
+/*
+ * Set the log ID of an SCT to point directly to the *log_id specified.
+ * The SCT takes ownership of the specified pointer.
+ * Returns 1 on success, 0 otherwise.
+ */
+__owur int SCT_set0_log_id(SCT *sct, unsigned char *log_id, size_t log_id_len);
+
+/*
+ * Set the log ID of an SCT.
+ * This makes a copy of the log_id.
+ * Returns 1 on success, 0 otherwise.
+ */
+__owur int SCT_set1_log_id(SCT *sct, const unsigned char *log_id,
+                           size_t log_id_len);
+
+/*
+ * Returns the timestamp for the SCT (epoch time in milliseconds).
+ */
+uint64_t SCT_get_timestamp(const SCT *sct);
+
+/*
+ * Set the timestamp of an SCT (epoch time in milliseconds).
+ */
+void SCT_set_timestamp(SCT *sct, uint64_t timestamp);
+
+/*
+ * Return the NID for the signature used by the SCT.
+ * For CT v1, this will be either NID_sha256WithRSAEncryption or
+ * NID_ecdsa_with_SHA256 (or NID_undef if incorrect/unset).
+ */
+int SCT_get_signature_nid(const SCT *sct);
+
+/*
+ * Set the signature type of an SCT
+ * For CT v1, this should be either NID_sha256WithRSAEncryption or
+ * NID_ecdsa_with_SHA256.
+ * Returns 1 on success, 0 otherwise.
+ */
+__owur int SCT_set_signature_nid(SCT *sct, int nid);
+
+/*
+ * Set *ext to point to the extension data for the SCT. ext must not be NULL.
+ * The SCT retains ownership of this pointer.
+ * Returns length of the data pointed to.
+ */
+size_t SCT_get0_extensions(const SCT *sct, unsigned char **ext);
+
+/*
+ * Set the extensions of an SCT to point directly to the *ext specified.
+ * The SCT takes ownership of the specified pointer.
+ */
+void SCT_set0_extensions(SCT *sct, unsigned char *ext, size_t ext_len);
+
+/*
+ * Set the extensions of an SCT.
+ * This takes a copy of the ext.
+ * Returns 1 on success, 0 otherwise.
+ */
+__owur int SCT_set1_extensions(SCT *sct, const unsigned char *ext,
+                               size_t ext_len);
+
+/*
+ * Set *sig to point to the signature for the SCT. sig must not be NULL.
+ * The SCT retains ownership of this pointer.
+ * Returns length of the data pointed to.
+ */
+size_t SCT_get0_signature(const SCT *sct, unsigned char **sig);
+
+/*
+ * Set the signature of an SCT to point directly to the *sig specified.
+ * The SCT takes ownership of the specified pointer.
+ */
+void SCT_set0_signature(SCT *sct, unsigned char *sig, size_t sig_len);
+
+/*
+ * Set the signature of an SCT to be a copy of the *sig specified.
+ * Returns 1 on success, 0 otherwise.
+ */
+__owur int SCT_set1_signature(SCT *sct, const unsigned char *sig,
+                              size_t sig_len);
+
+/*
+ * The origin of this SCT, e.g. TLS extension, OCSP response, etc.
+ */
+sct_source_t SCT_get_source(const SCT *sct);
+
+/*
+ * Set the origin of this SCT, e.g. TLS extension, OCSP response, etc.
+ * Returns 1 on success, 0 otherwise.
+ */
+__owur int SCT_set_source(SCT *sct, sct_source_t source);
+
+/*
+ * Returns a text string describing the validation status of |sct|.
+ */
+const char *SCT_validation_status_string(const SCT *sct);
+
+/*
+ * Pretty-prints an |sct| to |out|.
+ * It will be indented by the number of spaces specified by |indent|.
+ * If |logs| is not NULL, it will be used to lookup the CT log that the SCT came
+ * from, so that the log name can be printed.
+ */
+void SCT_print(const SCT *sct, BIO *out, int indent, const CTLOG_STORE *logs);
+
+/*
+ * Pretty-prints an |sct_list| to |out|.
+ * It will be indented by the number of spaces specified by |indent|.
+ * SCTs will be delimited by |separator|.
+ * If |logs| is not NULL, it will be used to lookup the CT log that each SCT
+ * came from, so that the log names can be printed.
+ */
+void SCT_LIST_print(const STACK_OF(SCT) *sct_list, BIO *out, int indent,
+                    const char *separator, const CTLOG_STORE *logs);
+
+/*
+ * Gets the last result of validating this SCT.
+ * If it has not been validated yet, returns SCT_VALIDATION_STATUS_NOT_SET.
+ */
+sct_validation_status_t SCT_get_validation_status(const SCT *sct);
+
+/*
+ * Validates the given SCT with the provided context.
+ * Sets the "validation_status" field of the SCT.
+ * Returns 1 if the SCT is valid and the signature verifies.
+ * Returns 0 if the SCT is invalid or could not be verified.
+ * Returns -1 if an error occurs.
+ */
+__owur int SCT_validate(SCT *sct, const CT_POLICY_EVAL_CTX *ctx);
+
+/*
+ * Validates the given list of SCTs with the provided context.
+ * Sets the "validation_status" field of each SCT.
+ * Returns 1 if there are no invalid SCTs and all signatures verify.
+ * Returns 0 if at least one SCT is invalid or could not be verified.
+ * Returns a negative integer if an error occurs.
+ */
+__owur int SCT_LIST_validate(const STACK_OF(SCT) *scts,
+                             CT_POLICY_EVAL_CTX *ctx);
+
+
+/*********************************
+ * SCT parsing and serialisation *
+ *********************************/
+
+/*
+ * Serialize (to TLS format) a stack of SCTs and return the length.
+ * "a" must not be NULL.
+ * If "pp" is NULL, just return the length of what would have been serialized.
+ * If "pp" is not NULL and "*pp" is null, function will allocate a new pointer
+ * for data that caller is responsible for freeing (only if function returns
+ * successfully).
+ * If "pp" is NULL and "*pp" is not NULL, caller is responsible for ensuring
+ * that "*pp" is large enough to accept all of the serialized data.
+ * Returns < 0 on error, >= 0 indicating bytes written (or would have been)
+ * on success.
+ */
+__owur int i2o_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp);
+
+/*
+ * Convert TLS format SCT list to a stack of SCTs.
+ * If "a" or "*a" is NULL, a new stack will be created that the caller is
+ * responsible for freeing (by calling SCT_LIST_free).
+ * "**pp" and "*pp" must not be NULL.
+ * Upon success, "*pp" will point to after the last bytes read, and a stack
+ * will be returned.
+ * Upon failure, a NULL pointer will be returned, and the position of "*pp" is
+ * not defined.
+ */
+STACK_OF(SCT) *o2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp,
+                            size_t len);
+
+/*
+ * Serialize (to DER format) a stack of SCTs and return the length.
+ * "a" must not be NULL.
+ * If "pp" is NULL, just returns the length of what would have been serialized.
+ * If "pp" is not NULL and "*pp" is null, function will allocate a new pointer
+ * for data that caller is responsible for freeing (only if function returns
+ * successfully).
+ * If "pp" is NULL and "*pp" is not NULL, caller is responsible for ensuring
+ * that "*pp" is large enough to accept all of the serialized data.
+ * Returns < 0 on error, >= 0 indicating bytes written (or would have been)
+ * on success.
+ */
+__owur int i2d_SCT_LIST(const STACK_OF(SCT) *a, unsigned char **pp);
+
+/*
+ * Parses an SCT list in DER format and returns it.
+ * If "a" or "*a" is NULL, a new stack will be created that the caller is
+ * responsible for freeing (by calling SCT_LIST_free).
+ * "**pp" and "*pp" must not be NULL.
+ * Upon success, "*pp" will point to after the last bytes read, and a stack
+ * will be returned.
+ * Upon failure, a NULL pointer will be returned, and the position of "*pp" is
+ * not defined.
+ */
+STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp,
+                            long len);
+
+/*
+ * Serialize (to TLS format) an |sct| and write it to |out|.
+ * If |out| is null, no SCT will be output but the length will still be returned.
+ * If |out| points to a null pointer, a string will be allocated to hold the
+ * TLS-format SCT. It is the responsibility of the caller to free it.
+ * If |out| points to an allocated string, the TLS-format SCT will be written
+ * to it.
+ * The length of the SCT in TLS format will be returned.
+ */
+__owur int i2o_SCT(const SCT *sct, unsigned char **out);
+
+/*
+ * Parses an SCT in TLS format and returns it.
+ * If |psct| is not null, it will end up pointing to the parsed SCT. If it
+ * already points to a non-null pointer, the pointer will be free'd.
+ * |in| should be a pointer to a string containing the TLS-format SCT.
+ * |in| will be advanced to the end of the SCT if parsing succeeds.
+ * |len| should be the length of the SCT in |in|.
+ * Returns NULL if an error occurs.
+ * If the SCT is an unsupported version, only the SCT's 'sct' and 'sct_len'
+ * fields will be populated (with |in| and |len| respectively).
+ */
+SCT *o2i_SCT(SCT **psct, const unsigned char **in, size_t len);
+
+/********************
+ * CT log functions *
+ ********************/
+
+/*
+ * Creates a new CT log instance with the given |public_key| and |name|.
+ * Takes ownership of |public_key| but copies |name|.
+ * Returns NULL if malloc fails or if |public_key| cannot be converted to DER.
+ * Should be deleted by the caller using CTLOG_free when no longer needed.
+ */
+CTLOG *CTLOG_new(EVP_PKEY *public_key, const char *name);
+
+/*
+ * Creates a new CTLOG instance with the base64-encoded SubjectPublicKeyInfo DER
+ * in |pkey_base64|. The |name| is a string to help users identify this log.
+ * Returns 1 on success, 0 on failure.
+ * Should be deleted by the caller using CTLOG_free when no longer needed.
+ */
+int CTLOG_new_from_base64(CTLOG ** ct_log,
+                          const char *pkey_base64, const char *name);
+
+/*
+ * Deletes a CT log instance and its fields.
+ */
+void CTLOG_free(CTLOG *log);
+
+/* Gets the name of the CT log */
+const char *CTLOG_get0_name(const CTLOG *log);
+/* Gets the ID of the CT log */
+void CTLOG_get0_log_id(const CTLOG *log, const uint8_t **log_id,
+                       size_t *log_id_len);
+/* Gets the public key of the CT log */
+EVP_PKEY *CTLOG_get0_public_key(const CTLOG *log);
+
+/**************************
+ * CT log store functions *
+ **************************/
+
+/*
+ * Creates a new CT log store.
+ * Should be deleted by the caller using CTLOG_STORE_free when no longer needed.
+ */
+CTLOG_STORE *CTLOG_STORE_new(void);
+
+/*
+ * Deletes a CT log store and all of the CT log instances held within.
+ */
+void CTLOG_STORE_free(CTLOG_STORE *store);
+
+/*
+ * Finds a CT log in the store based on its log ID.
+ * Returns the CT log, or NULL if no match is found.
+ */
+const CTLOG *CTLOG_STORE_get0_log_by_id(const CTLOG_STORE *store,
+                                        const uint8_t *log_id,
+                                        size_t log_id_len);
+
+/*
+ * Loads a CT log list into a |store| from a |file|.
+ * Returns 1 if loading is successful, or 0 otherwise.
+ */
+__owur int CTLOG_STORE_load_file(CTLOG_STORE *store, const char *file);
+
+/*
+ * Loads the default CT log list into a |store|.
+ * See internal/cryptlib.h for the environment variable and file path that are
+ * consulted to find the default file.
+ * Returns 1 if loading is successful, or 0 otherwise.
+ */
+__owur int CTLOG_STORE_load_default_file(CTLOG_STORE *store);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_CT_strings(void);
+
+/* Error codes for the CT functions. */
+
+/* Function codes. */
+# define CT_F_CTLOG_NEW                                   117
+# define CT_F_CTLOG_NEW_FROM_BASE64                       118
+# define CT_F_CTLOG_NEW_FROM_CONF                         119
+# define CT_F_CTLOG_STORE_LOAD_CTX_NEW                    122
+# define CT_F_CTLOG_STORE_LOAD_FILE                       123
+# define CT_F_CTLOG_STORE_LOAD_LOG                        130
+# define CT_F_CTLOG_STORE_NEW                             131
+# define CT_F_CT_BASE64_DECODE                            124
+# define CT_F_CT_POLICY_EVAL_CTX_NEW                      133
+# define CT_F_CT_V1_LOG_ID_FROM_PKEY                      125
+# define CT_F_I2O_SCT                                     107
+# define CT_F_I2O_SCT_LIST                                108
+# define CT_F_I2O_SCT_SIGNATURE                           109
+# define CT_F_O2I_SCT                                     110
+# define CT_F_O2I_SCT_LIST                                111
+# define CT_F_O2I_SCT_SIGNATURE                           112
+# define CT_F_SCT_CTX_NEW                                 126
+# define CT_F_SCT_CTX_VERIFY                              128
+# define CT_F_SCT_NEW                                     100
+# define CT_F_SCT_NEW_FROM_BASE64                         127
+# define CT_F_SCT_SET0_LOG_ID                             101
+# define CT_F_SCT_SET1_EXTENSIONS                         114
+# define CT_F_SCT_SET1_LOG_ID                             115
+# define CT_F_SCT_SET1_SIGNATURE                          116
+# define CT_F_SCT_SET_LOG_ENTRY_TYPE                      102
+# define CT_F_SCT_SET_SIGNATURE_NID                       103
+# define CT_F_SCT_SET_VERSION                             104
+
+/* Reason codes. */
+# define CT_R_BASE64_DECODE_ERROR                         108
+# define CT_R_INVALID_LOG_ID_LENGTH                       100
+# define CT_R_LOG_CONF_INVALID                            109
+# define CT_R_LOG_CONF_INVALID_KEY                        110
+# define CT_R_LOG_CONF_MISSING_DESCRIPTION                111
+# define CT_R_LOG_CONF_MISSING_KEY                        112
+# define CT_R_LOG_KEY_INVALID                             113
+# define CT_R_SCT_FUTURE_TIMESTAMP                        116
+# define CT_R_SCT_INVALID                                 104
+# define CT_R_SCT_INVALID_SIGNATURE                       107
+# define CT_R_SCT_LIST_INVALID                            105
+# define CT_R_SCT_LOG_ID_MISMATCH                         114
+# define CT_R_SCT_NOT_SET                                 106
+# define CT_R_SCT_UNSUPPORTED_VERSION                     115
+# define CT_R_UNRECOGNIZED_SIGNATURE_NID                  101
+# define CT_R_UNSUPPORTED_ENTRY_TYPE                      102
+# define CT_R_UNSUPPORTED_VERSION                         103
+
+#  ifdef  __cplusplus
+}
+#  endif
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/des.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/des.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/des.h	(revision 331)
@@ -0,0 +1,174 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_DES_H
+# define HEADER_DES_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_DES
+# ifdef  __cplusplus
+extern "C" {
+# endif
+# include <openssl/e_os2.h>
+
+typedef unsigned int DES_LONG;
+
+# ifdef OPENSSL_BUILD_SHLIBCRYPTO
+#  undef OPENSSL_EXTERN
+#  define OPENSSL_EXTERN OPENSSL_EXPORT
+# endif
+
+typedef unsigned char DES_cblock[8];
+typedef /* const */ unsigned char const_DES_cblock[8];
+/*
+ * With "const", gcc 2.8.1 on Solaris thinks that DES_cblock * and
+ * const_DES_cblock * are incompatible pointer types.
+ */
+
+typedef struct DES_ks {
+    union {
+        DES_cblock cblock;
+        /*
+         * make sure things are correct size on machines with 8 byte longs
+         */
+        DES_LONG deslong[2];
+    } ks[16];
+} DES_key_schedule;
+
+# define DES_KEY_SZ      (sizeof(DES_cblock))
+# define DES_SCHEDULE_SZ (sizeof(DES_key_schedule))
+
+# define DES_ENCRYPT     1
+# define DES_DECRYPT     0
+
+# define DES_CBC_MODE    0
+# define DES_PCBC_MODE   1
+
+# define DES_ecb2_encrypt(i,o,k1,k2,e) \
+        DES_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
+
+# define DES_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
+        DES_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
+
+# define DES_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
+        DES_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
+
+# define DES_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
+        DES_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
+
+OPENSSL_DECLARE_GLOBAL(int, DES_check_key); /* defaults to false */
+# define DES_check_key OPENSSL_GLOBAL_REF(DES_check_key)
+
+const char *DES_options(void);
+void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
+                      DES_key_schedule *ks1, DES_key_schedule *ks2,
+                      DES_key_schedule *ks3, int enc);
+DES_LONG DES_cbc_cksum(const unsigned char *input, DES_cblock *output,
+                       long length, DES_key_schedule *schedule,
+                       const_DES_cblock *ivec);
+/* DES_cbc_encrypt does not update the IV!  Use DES_ncbc_encrypt instead. */
+void DES_cbc_encrypt(const unsigned char *input, unsigned char *output,
+                     long length, DES_key_schedule *schedule,
+                     DES_cblock *ivec, int enc);
+void DES_ncbc_encrypt(const unsigned char *input, unsigned char *output,
+                      long length, DES_key_schedule *schedule,
+                      DES_cblock *ivec, int enc);
+void DES_xcbc_encrypt(const unsigned char *input, unsigned char *output,
+                      long length, DES_key_schedule *schedule,
+                      DES_cblock *ivec, const_DES_cblock *inw,
+                      const_DES_cblock *outw, int enc);
+void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
+                     long length, DES_key_schedule *schedule,
+                     DES_cblock *ivec, int enc);
+void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output,
+                     DES_key_schedule *ks, int enc);
+
+/*
+ * This is the DES encryption function that gets called by just about every
+ * other DES routine in the library.  You should not use this function except
+ * to implement 'modes' of DES.  I say this because the functions that call
+ * this routine do the conversion from 'char *' to long, and this needs to be
+ * done to make sure 'non-aligned' memory access do not occur.  The
+ * characters are loaded 'little endian'. Data is a pointer to 2 unsigned
+ * long's and ks is the DES_key_schedule to use.  enc, is non zero specifies
+ * encryption, zero if decryption.
+ */
+void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc);
+
+/*
+ * This functions is the same as DES_encrypt1() except that the DES initial
+ * permutation (IP) and final permutation (FP) have been left out.  As for
+ * DES_encrypt1(), you should not use this function. It is used by the
+ * routines in the library that implement triple DES. IP() DES_encrypt2()
+ * DES_encrypt2() DES_encrypt2() FP() is the same as DES_encrypt1()
+ * DES_encrypt1() DES_encrypt1() except faster :-).
+ */
+void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc);
+
+void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
+                  DES_key_schedule *ks2, DES_key_schedule *ks3);
+void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
+                  DES_key_schedule *ks2, DES_key_schedule *ks3);
+void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output,
+                          long length,
+                          DES_key_schedule *ks1, DES_key_schedule *ks2,
+                          DES_key_schedule *ks3, DES_cblock *ivec, int enc);
+void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                            long length, DES_key_schedule *ks1,
+                            DES_key_schedule *ks2, DES_key_schedule *ks3,
+                            DES_cblock *ivec, int *num, int enc);
+void DES_ede3_cfb_encrypt(const unsigned char *in, unsigned char *out,
+                          int numbits, long length, DES_key_schedule *ks1,
+                          DES_key_schedule *ks2, DES_key_schedule *ks3,
+                          DES_cblock *ivec, int enc);
+void DES_ede3_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+                            long length, DES_key_schedule *ks1,
+                            DES_key_schedule *ks2, DES_key_schedule *ks3,
+                            DES_cblock *ivec, int *num);
+char *DES_fcrypt(const char *buf, const char *salt, char *ret);
+char *DES_crypt(const char *buf, const char *salt);
+void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits,
+                     long length, DES_key_schedule *schedule,
+                     DES_cblock *ivec);
+void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output,
+                      long length, DES_key_schedule *schedule,
+                      DES_cblock *ivec, int enc);
+DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[],
+                        long length, int out_count, DES_cblock *seed);
+int DES_random_key(DES_cblock *ret);
+void DES_set_odd_parity(DES_cblock *key);
+int DES_check_key_parity(const_DES_cblock *key);
+int DES_is_weak_key(const_DES_cblock *key);
+/*
+ * DES_set_key (= set_key = DES_key_sched = key_sched) calls
+ * DES_set_key_checked if global variable DES_check_key is set,
+ * DES_set_key_unchecked otherwise.
+ */
+int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule);
+int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule);
+int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule);
+void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule);
+void DES_string_to_key(const char *str, DES_cblock *key);
+void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2);
+void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                       long length, DES_key_schedule *schedule,
+                       DES_cblock *ivec, int *num, int enc);
+void DES_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+                       long length, DES_key_schedule *schedule,
+                       DES_cblock *ivec, int *num);
+
+# define DES_fixup_key_parity DES_set_odd_parity
+
+# ifdef  __cplusplus
+}
+# endif
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/dh.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/dh.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/dh.h	(revision 331)
@@ -0,0 +1,344 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_DH_H
+# define HEADER_DH_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_DH
+# include <openssl/e_os2.h>
+# include <openssl/bio.h>
+# include <openssl/asn1.h>
+# include <openssl/ossl_typ.h>
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  include <openssl/bn.h>
+# endif
+
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+# ifndef OPENSSL_DH_MAX_MODULUS_BITS
+#  define OPENSSL_DH_MAX_MODULUS_BITS    10000
+# endif
+
+# define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024
+
+# define DH_FLAG_CACHE_MONT_P     0x01
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+/*
+ * Does nothing. Previously this switched off constant time behaviour.
+ */
+#  define DH_FLAG_NO_EXP_CONSTTIME 0x00
+# endif
+
+/*
+ * If this flag is set the DH method is FIPS compliant and can be used in
+ * FIPS mode. This is set in the validated module method. If an application
+ * sets this flag in its own methods it is its responsibility to ensure the
+ * result is compliant.
+ */
+
+# define DH_FLAG_FIPS_METHOD                     0x0400
+
+/*
+ * If this flag is set the operations normally disabled in FIPS mode are
+ * permitted it is then the applications responsibility to ensure that the
+ * usage is compliant.
+ */
+
+# define DH_FLAG_NON_FIPS_ALLOW                  0x0400
+
+/* Already defined in ossl_typ.h */
+/* typedef struct dh_st DH; */
+/* typedef struct dh_method DH_METHOD; */
+
+DECLARE_ASN1_ITEM(DHparams)
+
+# define DH_GENERATOR_2          2
+/* #define DH_GENERATOR_3       3 */
+# define DH_GENERATOR_5          5
+
+/* DH_check error codes */
+# define DH_CHECK_P_NOT_PRIME            0x01
+# define DH_CHECK_P_NOT_SAFE_PRIME       0x02
+# define DH_UNABLE_TO_CHECK_GENERATOR    0x04
+# define DH_NOT_SUITABLE_GENERATOR       0x08
+# define DH_CHECK_Q_NOT_PRIME            0x10
+# define DH_CHECK_INVALID_Q_VALUE        0x20
+# define DH_CHECK_INVALID_J_VALUE        0x40
+
+/* DH_check_pub_key error codes */
+# define DH_CHECK_PUBKEY_TOO_SMALL       0x01
+# define DH_CHECK_PUBKEY_TOO_LARGE       0x02
+# define DH_CHECK_PUBKEY_INVALID         0x04
+
+/*
+ * primes p where (p-1)/2 is prime too are called "safe"; we define this for
+ * backward compatibility:
+ */
+# define DH_CHECK_P_NOT_STRONG_PRIME     DH_CHECK_P_NOT_SAFE_PRIME
+
+# define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \
+                (char *(*)())d2i_DHparams,(fp),(unsigned char **)(x))
+# define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \
+                (unsigned char *)(x))
+# define d2i_DHparams_bio(bp,x) ASN1_d2i_bio_of(DH,DH_new,d2i_DHparams,bp,x)
+# define i2d_DHparams_bio(bp,x) ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x)
+
+DH *DHparams_dup(DH *);
+
+const DH_METHOD *DH_OpenSSL(void);
+
+void DH_set_default_method(const DH_METHOD *meth);
+const DH_METHOD *DH_get_default_method(void);
+int DH_set_method(DH *dh, const DH_METHOD *meth);
+DH *DH_new_method(ENGINE *engine);
+
+DH *DH_new(void);
+void DH_free(DH *dh);
+int DH_up_ref(DH *dh);
+int DH_bits(const DH *dh);
+int DH_size(const DH *dh);
+int DH_security_bits(const DH *dh);
+#define DH_get_ex_new_index(l, p, newf, dupf, freef) \
+    CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DH, l, p, newf, dupf, freef)
+int DH_set_ex_data(DH *d, int idx, void *arg);
+void *DH_get_ex_data(DH *d, int idx);
+
+/* Deprecated version */
+DEPRECATEDIN_0_9_8(DH *DH_generate_parameters(int prime_len, int generator,
+                                              void (*callback) (int, int,
+                                                                void *),
+                                              void *cb_arg))
+
+/* New version */
+int DH_generate_parameters_ex(DH *dh, int prime_len, int generator,
+                              BN_GENCB *cb);
+
+int DH_check_params(const DH *dh, int *ret);
+int DH_check(const DH *dh, int *codes);
+int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *codes);
+int DH_generate_key(DH *dh);
+int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
+int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh);
+DH *d2i_DHparams(DH **a, const unsigned char **pp, long length);
+int i2d_DHparams(const DH *a, unsigned char **pp);
+DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length);
+int i2d_DHxparams(const DH *a, unsigned char **pp);
+# ifndef OPENSSL_NO_STDIO
+int DHparams_print_fp(FILE *fp, const DH *x);
+# endif
+int DHparams_print(BIO *bp, const DH *x);
+
+/* RFC 5114 parameters */
+DH *DH_get_1024_160(void);
+DH *DH_get_2048_224(void);
+DH *DH_get_2048_256(void);
+
+# ifndef OPENSSL_NO_CMS
+/* RFC2631 KDF */
+int DH_KDF_X9_42(unsigned char *out, size_t outlen,
+                 const unsigned char *Z, size_t Zlen,
+                 ASN1_OBJECT *key_oid,
+                 const unsigned char *ukm, size_t ukmlen, const EVP_MD *md);
+# endif
+
+void DH_get0_pqg(const DH *dh,
+                 const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
+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_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key);
+void DH_clear_flags(DH *dh, int flags);
+int DH_test_flags(const DH *dh, int flags);
+void DH_set_flags(DH *dh, int flags);
+ENGINE *DH_get0_engine(DH *d);
+long DH_get_length(const DH *dh);
+int DH_set_length(DH *dh, long length);
+
+DH_METHOD *DH_meth_new(const char *name, int flags);
+void DH_meth_free(DH_METHOD *dhm);
+DH_METHOD *DH_meth_dup(const DH_METHOD *dhm);
+const char *DH_meth_get0_name(const DH_METHOD *dhm);
+int DH_meth_set1_name(DH_METHOD *dhm, const char *name);
+int DH_meth_get_flags(DH_METHOD *dhm);
+int DH_meth_set_flags(DH_METHOD *dhm, int flags);
+void *DH_meth_get0_app_data(const DH_METHOD *dhm);
+int DH_meth_set0_app_data(DH_METHOD *dhm, void *app_data);
+int (*DH_meth_get_generate_key(const DH_METHOD *dhm)) (DH *);
+int DH_meth_set_generate_key(DH_METHOD *dhm, int (*generate_key) (DH *));
+int (*DH_meth_get_compute_key(const DH_METHOD *dhm))
+        (unsigned char *key, const BIGNUM *pub_key, DH *dh);
+int DH_meth_set_compute_key(DH_METHOD *dhm,
+        int (*compute_key) (unsigned char *key, const BIGNUM *pub_key, DH *dh));
+int (*DH_meth_get_bn_mod_exp(const DH_METHOD *dhm))
+    (const DH *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *,
+     BN_CTX *, BN_MONT_CTX *);
+int DH_meth_set_bn_mod_exp(DH_METHOD *dhm,
+    int (*bn_mod_exp) (const DH *, BIGNUM *, const BIGNUM *, const BIGNUM *,
+                       const BIGNUM *, BN_CTX *, BN_MONT_CTX *));
+int (*DH_meth_get_init(const DH_METHOD *dhm))(DH *);
+int DH_meth_set_init(DH_METHOD *dhm, int (*init)(DH *));
+int (*DH_meth_get_finish(const DH_METHOD *dhm)) (DH *);
+int DH_meth_set_finish(DH_METHOD *dhm, int (*finish) (DH *));
+int (*DH_meth_get_generate_params(const DH_METHOD *dhm))
+        (DH *, int, int, BN_GENCB *);
+int DH_meth_set_generate_params(DH_METHOD *dhm,
+        int (*generate_params) (DH *, int, int, BN_GENCB *));
+
+
+# define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL)
+
+# define EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, len, NULL)
+
+# define EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, typ, NULL)
+
+# define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL)
+
+# define EVP_PKEY_CTX_set_dh_rfc5114(ctx, gen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_RFC5114, gen, NULL)
+
+# define EVP_PKEY_CTX_set_dhx_rfc5114(ctx, gen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_RFC5114, gen, NULL)
+
+# define EVP_PKEY_CTX_set_dh_kdf_type(ctx, kdf) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_TYPE, kdf, NULL)
+
+# define EVP_PKEY_CTX_get_dh_kdf_type(ctx) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_TYPE, -2, NULL)
+
+# define EVP_PKEY_CTX_set0_dh_kdf_oid(ctx, oid) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_OID, 0, (void *)oid)
+
+# define EVP_PKEY_CTX_get0_dh_kdf_oid(ctx, poid) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_GET_DH_KDF_OID, 0, (void *)poid)
+
+# define EVP_PKEY_CTX_set_dh_kdf_md(ctx, md) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_MD, 0, (void *)md)
+
+# define EVP_PKEY_CTX_get_dh_kdf_md(ctx, pmd) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_GET_DH_KDF_MD, 0, (void *)pmd)
+
+# define EVP_PKEY_CTX_set_dh_kdf_outlen(ctx, len) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_OUTLEN, len, NULL)
+
+# define EVP_PKEY_CTX_get_dh_kdf_outlen(ctx, plen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                        EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN, 0, (void *)plen)
+
+# define EVP_PKEY_CTX_set0_dh_kdf_ukm(ctx, p, plen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_UKM, plen, (void *)p)
+
+# define EVP_PKEY_CTX_get0_dh_kdf_ukm(ctx, p) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_GET_DH_KDF_UKM, 0, (void *)p)
+
+# define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN     (EVP_PKEY_ALG_CTRL + 1)
+# define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR     (EVP_PKEY_ALG_CTRL + 2)
+# define EVP_PKEY_CTRL_DH_RFC5114                (EVP_PKEY_ALG_CTRL + 3)
+# define EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN  (EVP_PKEY_ALG_CTRL + 4)
+# define EVP_PKEY_CTRL_DH_PARAMGEN_TYPE          (EVP_PKEY_ALG_CTRL + 5)
+# define EVP_PKEY_CTRL_DH_KDF_TYPE               (EVP_PKEY_ALG_CTRL + 6)
+# define EVP_PKEY_CTRL_DH_KDF_MD                 (EVP_PKEY_ALG_CTRL + 7)
+# define EVP_PKEY_CTRL_GET_DH_KDF_MD             (EVP_PKEY_ALG_CTRL + 8)
+# define EVP_PKEY_CTRL_DH_KDF_OUTLEN             (EVP_PKEY_ALG_CTRL + 9)
+# define EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN         (EVP_PKEY_ALG_CTRL + 10)
+# define EVP_PKEY_CTRL_DH_KDF_UKM                (EVP_PKEY_ALG_CTRL + 11)
+# define EVP_PKEY_CTRL_GET_DH_KDF_UKM            (EVP_PKEY_ALG_CTRL + 12)
+# define EVP_PKEY_CTRL_DH_KDF_OID                (EVP_PKEY_ALG_CTRL + 13)
+# define EVP_PKEY_CTRL_GET_DH_KDF_OID            (EVP_PKEY_ALG_CTRL + 14)
+
+/* KDF types */
+# define EVP_PKEY_DH_KDF_NONE                            1
+# ifndef OPENSSL_NO_CMS
+# define EVP_PKEY_DH_KDF_X9_42                           2
+# endif
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_DH_strings(void);
+
+/* Error codes for the DH functions. */
+
+/* Function codes. */
+# define DH_F_COMPUTE_KEY                                 102
+# define DH_F_DHPARAMS_PRINT_FP                           101
+# define DH_F_DH_BUILTIN_GENPARAMS                        106
+# define DH_F_DH_CMS_DECRYPT                              114
+# define DH_F_DH_CMS_SET_PEERKEY                          115
+# define DH_F_DH_CMS_SET_SHARED_INFO                      116
+# define DH_F_DH_METH_DUP                                 117
+# define DH_F_DH_METH_NEW                                 118
+# define DH_F_DH_METH_SET1_NAME                           119
+# define DH_F_DH_NEW_METHOD                               105
+# define DH_F_DH_PARAM_DECODE                             107
+# define DH_F_DH_PRIV_DECODE                              110
+# define DH_F_DH_PRIV_ENCODE                              111
+# define DH_F_DH_PUB_DECODE                               108
+# define DH_F_DH_PUB_ENCODE                               109
+# define DH_F_DO_DH_PRINT                                 100
+# define DH_F_GENERATE_KEY                                103
+# define DH_F_PKEY_DH_DERIVE                              112
+# define DH_F_PKEY_DH_KEYGEN                              113
+
+/* Reason codes. */
+# define DH_R_BAD_GENERATOR                               101
+# define DH_R_BN_DECODE_ERROR                             109
+# define DH_R_BN_ERROR                                    106
+# define DH_R_DECODE_ERROR                                104
+# define DH_R_INVALID_PUBKEY                              102
+# define DH_R_KDF_PARAMETER_ERROR                         112
+# define DH_R_KEYS_NOT_SET                                108
+# define DH_R_MODULUS_TOO_LARGE                           103
+# define DH_R_NO_PARAMETERS_SET                           107
+# define DH_R_NO_PRIVATE_VALUE                            100
+# define DH_R_PARAMETER_ENCODING_ERROR                    105
+# define DH_R_PEER_KEY_ERROR                              111
+# define DH_R_SHARED_INFO_ERROR                           113
+
+#  ifdef  __cplusplus
+}
+#  endif
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/dsa.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/dsa.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/dsa.h	(revision 331)
@@ -0,0 +1,283 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*
+ * The DSS routines are based on patches supplied by
+ * Steven Schoch <schoch@sheba.arc.nasa.gov>.
+ */
+
+#ifndef HEADER_DSA_H
+# define HEADER_DSA_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_DSA
+# ifdef  __cplusplus
+extern "C" {
+# endif
+# include <openssl/e_os2.h>
+# include <openssl/bio.h>
+# include <openssl/crypto.h>
+# include <openssl/ossl_typ.h>
+# include <openssl/opensslconf.h>
+# include <openssl/bn.h>
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  include <openssl/dh.h>
+# endif
+
+# ifndef OPENSSL_DSA_MAX_MODULUS_BITS
+#  define OPENSSL_DSA_MAX_MODULUS_BITS   10000
+# endif
+
+# define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024
+
+# define DSA_FLAG_CACHE_MONT_P   0x01
+# if OPENSSL_API_COMPAT < 0x10100000L
+/*
+ * Does nothing. Previously this switched off constant time behaviour.
+ */
+#  define DSA_FLAG_NO_EXP_CONSTTIME       0x00
+# endif
+
+/*
+ * If this flag is set the DSA method is FIPS compliant and can be used in
+ * FIPS mode. This is set in the validated module method. If an application
+ * sets this flag in its own methods it is its responsibility to ensure the
+ * result is compliant.
+ */
+
+# define DSA_FLAG_FIPS_METHOD                    0x0400
+
+/*
+ * If this flag is set the operations normally disabled in FIPS mode are
+ * permitted it is then the applications responsibility to ensure that the
+ * usage is compliant.
+ */
+
+# define DSA_FLAG_NON_FIPS_ALLOW                 0x0400
+# define DSA_FLAG_FIPS_CHECKED                   0x0800
+
+/* Already defined in ossl_typ.h */
+/* typedef struct dsa_st DSA; */
+/* typedef struct dsa_method DSA_METHOD; */
+
+typedef struct DSA_SIG_st DSA_SIG;
+
+# define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \
+                (char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x))
+# define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \
+                (unsigned char *)(x))
+# define d2i_DSAparams_bio(bp,x) ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAparams,bp,x)
+# define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x)
+
+DSA *DSAparams_dup(DSA *x);
+DSA_SIG *DSA_SIG_new(void);
+void DSA_SIG_free(DSA_SIG *a);
+int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp);
+DSA_SIG *d2i_DSA_SIG(DSA_SIG **v, const unsigned char **pp, long length);
+void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);
+int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s);
+
+DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
+int DSA_do_verify(const unsigned char *dgst, int dgst_len,
+                  DSA_SIG *sig, DSA *dsa);
+
+const DSA_METHOD *DSA_OpenSSL(void);
+
+void DSA_set_default_method(const DSA_METHOD *);
+const DSA_METHOD *DSA_get_default_method(void);
+int DSA_set_method(DSA *dsa, const DSA_METHOD *);
+const DSA_METHOD *DSA_get_method(DSA *d);
+
+DSA *DSA_new(void);
+DSA *DSA_new_method(ENGINE *engine);
+void DSA_free(DSA *r);
+/* "up" the DSA object's reference count */
+int DSA_up_ref(DSA *r);
+int DSA_size(const DSA *);
+int DSA_bits(const DSA *d);
+int DSA_security_bits(const DSA *d);
+        /* next 4 return -1 on error */
+int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
+int DSA_sign(int type, const unsigned char *dgst, int dlen,
+             unsigned char *sig, unsigned int *siglen, DSA *dsa);
+int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
+               const unsigned char *sigbuf, int siglen, DSA *dsa);
+#define DSA_get_ex_new_index(l, p, newf, dupf, freef) \
+    CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DSA, l, p, newf, dupf, freef)
+int DSA_set_ex_data(DSA *d, int idx, void *arg);
+void *DSA_get_ex_data(DSA *d, int idx);
+
+DSA *d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length);
+DSA *d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length);
+DSA *d2i_DSAparams(DSA **a, const unsigned char **pp, long length);
+
+/* Deprecated version */
+DEPRECATEDIN_0_9_8(DSA *DSA_generate_parameters(int bits,
+                                                unsigned char *seed,
+                                                int seed_len,
+                                                int *counter_ret,
+                                                unsigned long *h_ret, void
+                                                 (*callback) (int, int,
+                                                              void *),
+                                                void *cb_arg))
+
+/* New version */
+int DSA_generate_parameters_ex(DSA *dsa, int bits,
+                               const unsigned char *seed, int seed_len,
+                               int *counter_ret, unsigned long *h_ret,
+                               BN_GENCB *cb);
+
+int DSA_generate_key(DSA *a);
+int i2d_DSAPublicKey(const DSA *a, unsigned char **pp);
+int i2d_DSAPrivateKey(const DSA *a, unsigned char **pp);
+int i2d_DSAparams(const DSA *a, unsigned char **pp);
+
+int DSAparams_print(BIO *bp, const DSA *x);
+int DSA_print(BIO *bp, const DSA *x, int off);
+# ifndef OPENSSL_NO_STDIO
+int DSAparams_print_fp(FILE *fp, const DSA *x);
+int DSA_print_fp(FILE *bp, const DSA *x, int off);
+# endif
+
+# define DSS_prime_checks 50
+/*
+ * Primality test according to FIPS PUB 186[-1], Appendix 2.1: 50 rounds of
+ * Rabin-Miller
+ */
+# define DSA_is_prime(n, callback, cb_arg) \
+        BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg)
+
+# ifndef OPENSSL_NO_DH
+/*
+ * Convert DSA structure (key or just parameters) into DH structure (be
+ * careful to avoid small subgroup attacks when using this!)
+ */
+DH *DSA_dup_DH(const DSA *r);
+# endif
+
+# define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \
+                                EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL)
+
+# define EVP_PKEY_CTRL_DSA_PARAMGEN_BITS         (EVP_PKEY_ALG_CTRL + 1)
+# define EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS       (EVP_PKEY_ALG_CTRL + 2)
+# define EVP_PKEY_CTRL_DSA_PARAMGEN_MD           (EVP_PKEY_ALG_CTRL + 3)
+
+void DSA_get0_pqg(const DSA *d,
+                  const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
+int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g);
+void DSA_get0_key(const DSA *d,
+                  const BIGNUM **pub_key, const BIGNUM **priv_key);
+int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key);
+void DSA_clear_flags(DSA *d, int flags);
+int DSA_test_flags(const DSA *d, int flags);
+void DSA_set_flags(DSA *d, int flags);
+ENGINE *DSA_get0_engine(DSA *d);
+
+DSA_METHOD *DSA_meth_new(const char *name, int flags);
+void DSA_meth_free(DSA_METHOD *dsam);
+DSA_METHOD *DSA_meth_dup(const DSA_METHOD *dsam);
+const char *DSA_meth_get0_name(const DSA_METHOD *dsam);
+int DSA_meth_set1_name(DSA_METHOD *dsam, const char *name);
+int DSA_meth_get_flags(DSA_METHOD *dsam);
+int DSA_meth_set_flags(DSA_METHOD *dsam, int flags);
+void *DSA_meth_get0_app_data(const DSA_METHOD *dsam);
+int DSA_meth_set0_app_data(DSA_METHOD *dsam, void *app_data);
+DSA_SIG *(*DSA_meth_get_sign(const DSA_METHOD *dsam))
+        (const unsigned char *, int, DSA *);
+int DSA_meth_set_sign(DSA_METHOD *dsam,
+                       DSA_SIG *(*sign) (const unsigned char *, int, DSA *));
+int (*DSA_meth_get_sign_setup(const DSA_METHOD *dsam))
+        (DSA *, BN_CTX *, BIGNUM **, BIGNUM **);
+int DSA_meth_set_sign_setup(DSA_METHOD *dsam,
+        int (*sign_setup) (DSA *, BN_CTX *, BIGNUM **, BIGNUM **));
+int (*DSA_meth_get_verify(const DSA_METHOD *dsam))
+        (const unsigned char *, int , DSA_SIG *, DSA *);
+int DSA_meth_set_verify(DSA_METHOD *dsam,
+    int (*verify) (const unsigned char *, int, DSA_SIG *, DSA *));
+int (*DSA_meth_get_mod_exp(const DSA_METHOD *dsam))
+        (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *,
+         const BIGNUM *, const BIGNUM *, BN_CTX *, BN_MONT_CTX *);
+int DSA_meth_set_mod_exp(DSA_METHOD *dsam,
+    int (*mod_exp) (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *,
+                    const BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *,
+                    BN_MONT_CTX *));
+int (*DSA_meth_get_bn_mod_exp(const DSA_METHOD *dsam))
+    (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *, const BIGNUM *,
+     BN_CTX *, BN_MONT_CTX *);
+int DSA_meth_set_bn_mod_exp(DSA_METHOD *dsam,
+    int (*bn_mod_exp) (DSA *, BIGNUM *, const BIGNUM *, const BIGNUM *,
+                       const BIGNUM *, BN_CTX *, BN_MONT_CTX *));
+int (*DSA_meth_get_init(const DSA_METHOD *dsam))(DSA *);
+int DSA_meth_set_init(DSA_METHOD *dsam, int (*init)(DSA *));
+int (*DSA_meth_get_finish(const DSA_METHOD *dsam)) (DSA *);
+int DSA_meth_set_finish(DSA_METHOD *dsam, int (*finish) (DSA *));
+int (*DSA_meth_get_paramgen(const DSA_METHOD *dsam))
+        (DSA *, int, const unsigned char *, int, int *, unsigned long *,
+         BN_GENCB *);
+int DSA_meth_set_paramgen(DSA_METHOD *dsam,
+        int (*paramgen) (DSA *, int, const unsigned char *, int, int *,
+                         unsigned long *, BN_GENCB *));
+int (*DSA_meth_get_keygen(const DSA_METHOD *dsam)) (DSA *);
+int DSA_meth_set_keygen(DSA_METHOD *dsam, int (*keygen) (DSA *));
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_DSA_strings(void);
+
+/* Error codes for the DSA functions. */
+
+/* Function codes. */
+# define DSA_F_DSAPARAMS_PRINT                            100
+# define DSA_F_DSAPARAMS_PRINT_FP                         101
+# define DSA_F_DSA_BUILTIN_PARAMGEN                       125
+# define DSA_F_DSA_BUILTIN_PARAMGEN2                      126
+# define DSA_F_DSA_DO_SIGN                                112
+# define DSA_F_DSA_DO_VERIFY                              113
+# define DSA_F_DSA_METH_DUP                               127
+# define DSA_F_DSA_METH_NEW                               128
+# define DSA_F_DSA_METH_SET1_NAME                         129
+# define DSA_F_DSA_NEW_METHOD                             103
+# define DSA_F_DSA_PARAM_DECODE                           119
+# define DSA_F_DSA_PRINT_FP                               105
+# define DSA_F_DSA_PRIV_DECODE                            115
+# define DSA_F_DSA_PRIV_ENCODE                            116
+# define DSA_F_DSA_PUB_DECODE                             117
+# define DSA_F_DSA_PUB_ENCODE                             118
+# define DSA_F_DSA_SIGN                                   106
+# define DSA_F_DSA_SIGN_SETUP                             107
+# define DSA_F_DSA_SIG_NEW                                102
+# define DSA_F_OLD_DSA_PRIV_DECODE                        122
+# define DSA_F_PKEY_DSA_CTRL                              120
+# define DSA_F_PKEY_DSA_KEYGEN                            121
+
+/* Reason codes. */
+# define DSA_R_BAD_Q_VALUE                                102
+# define DSA_R_BN_DECODE_ERROR                            108
+# define DSA_R_BN_ERROR                                   109
+# define DSA_R_DECODE_ERROR                               104
+# define DSA_R_INVALID_DIGEST_TYPE                        106
+# define DSA_R_INVALID_PARAMETERS                         112
+# define DSA_R_MISSING_PARAMETERS                         101
+# define DSA_R_MODULUS_TOO_LARGE                          103
+# define DSA_R_NO_PARAMETERS_SET                          107
+# define DSA_R_PARAMETER_ENCODING_ERROR                   105
+# define DSA_R_Q_NOT_PRIME                                113
+# define DSA_R_SEED_LEN_SMALL                             110
+
+#  ifdef  __cplusplus
+}
+#  endif
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/dtls1.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/dtls1.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/dtls1.h	(revision 331)
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2005-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
+ */
+
+#ifndef HEADER_DTLS1_H
+# define HEADER_DTLS1_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define DTLS1_VERSION                   0xFEFF
+# define DTLS1_2_VERSION                 0xFEFD
+# define DTLS_MIN_VERSION                DTLS1_VERSION
+# define DTLS_MAX_VERSION                DTLS1_2_VERSION
+# define DTLS1_VERSION_MAJOR             0xFE
+
+# define DTLS1_BAD_VER                   0x0100
+
+/* Special value for method supporting multiple versions */
+# define DTLS_ANY_VERSION                0x1FFFF
+
+/* lengths of messages */
+# define DTLS1_COOKIE_LENGTH                     256
+
+# define DTLS1_RT_HEADER_LENGTH                  13
+
+# define DTLS1_HM_HEADER_LENGTH                  12
+
+# define DTLS1_HM_BAD_FRAGMENT                   -2
+# define DTLS1_HM_FRAGMENT_RETRY                 -3
+
+# define DTLS1_CCS_HEADER_LENGTH                  1
+
+# ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+#  define DTLS1_AL_HEADER_LENGTH                   7
+# else
+#  define DTLS1_AL_HEADER_LENGTH                   2
+# endif
+
+
+/* Timeout multipliers (timeout slice is defined in apps/timeouts.h */
+# define DTLS1_TMO_READ_COUNT                      2
+# define DTLS1_TMO_WRITE_COUNT                     2
+
+# define DTLS1_TMO_ALERT_COUNT                     12
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/e_os2.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/e_os2.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/e_os2.h	(revision 331)
@@ -0,0 +1,311 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_E_OS2_H
+# define HEADER_E_OS2_H
+
+# include <openssl/opensslconf.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************
+ * Detect operating systems.  This probably needs completing.
+ * The result is that at least one OPENSSL_SYS_os macro should be defined.
+ * However, if none is defined, Unix is assumed.
+ **/
+
+# define OPENSSL_SYS_UNIX
+
+/* --------------------- Microsoft operating systems ---------------------- */
+
+/*
+ * Note that MSDOS actually denotes 32-bit environments running on top of
+ * MS-DOS, such as DJGPP one.
+ */
+# if defined(OPENSSL_SYS_MSDOS)
+#  undef OPENSSL_SYS_UNIX
+# endif
+
+/*
+ * For 32 bit environment, there seems to be the CygWin environment and then
+ * all the others that try to do the same thing Microsoft does...
+ */
+/*
+ * UEFI lives here because it might be built with a Microsoft toolchain and
+ * we need to avoid the false positive match on Windows.
+ */
+# if defined(OPENSSL_SYS_UEFI)
+#  undef OPENSSL_SYS_UNIX
+# elif defined(OPENSSL_SYS_UWIN)
+#  undef OPENSSL_SYS_UNIX
+#  define OPENSSL_SYS_WIN32_UWIN
+# else
+#  if defined(__CYGWIN__) || defined(OPENSSL_SYS_CYGWIN)
+#   undef OPENSSL_SYS_UNIX
+#   define OPENSSL_SYS_WIN32_CYGWIN
+#  else
+#   if defined(_WIN32) || defined(OPENSSL_SYS_WIN32)
+#    undef OPENSSL_SYS_UNIX
+#    if !defined(OPENSSL_SYS_WIN32)
+#     define OPENSSL_SYS_WIN32
+#    endif
+#   endif
+#   if defined(_WIN64) || defined(OPENSSL_SYS_WIN64)
+#    undef OPENSSL_SYS_UNIX
+#    if !defined(OPENSSL_SYS_WIN64)
+#     define OPENSSL_SYS_WIN64
+#    endif
+#   endif
+#   if defined(OPENSSL_SYS_WINNT)
+#    undef OPENSSL_SYS_UNIX
+#   endif
+#   if defined(OPENSSL_SYS_WINCE)
+#    undef OPENSSL_SYS_UNIX
+#   endif
+#  endif
+# endif
+
+/* Anything that tries to look like Microsoft is "Windows" */
+# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN64) || defined(OPENSSL_SYS_WINNT) || defined(OPENSSL_SYS_WINCE)
+#  undef OPENSSL_SYS_UNIX
+#  define OPENSSL_SYS_WINDOWS
+#  ifndef OPENSSL_SYS_MSDOS
+#   define OPENSSL_SYS_MSDOS
+#  endif
+# endif
+
+/*
+ * DLL settings.  This part is a bit tough, because it's up to the
+ * application implementor how he or she will link the application, so it
+ * requires some macro to be used.
+ */
+# ifdef OPENSSL_SYS_WINDOWS
+#  ifndef OPENSSL_OPT_WINDLL
+#   if defined(_WINDLL)         /* This is used when building OpenSSL to
+                                 * indicate that DLL linkage should be used */
+#    define OPENSSL_OPT_WINDLL
+#   endif
+#  endif
+# endif
+
+/* ------------------------------- OpenVMS -------------------------------- */
+# if defined(__VMS) || defined(VMS) || defined(OPENSSL_SYS_VMS)
+#  if !defined(OPENSSL_SYS_VMS)
+#   undef OPENSSL_SYS_UNIX
+#  endif
+#  define OPENSSL_SYS_VMS
+#  if defined(__DECC)
+#   define OPENSSL_SYS_VMS_DECC
+#  elif defined(__DECCXX)
+#   define OPENSSL_SYS_VMS_DECC
+#   define OPENSSL_SYS_VMS_DECCXX
+#  else
+#   define OPENSSL_SYS_VMS_NODECC
+#  endif
+# endif
+
+/* -------------------------------- Unix ---------------------------------- */
+# ifdef OPENSSL_SYS_UNIX
+#  if defined(linux) || defined(__linux__) && !defined(OPENSSL_SYS_LINUX)
+#   define OPENSSL_SYS_LINUX
+#  endif
+#  if defined(_AIX) && !defined(OPENSSL_SYS_AIX)
+#   define OPENSSL_SYS_AIX
+#  endif
+# endif
+
+/* -------------------------------- VOS ----------------------------------- */
+# if defined(__VOS__) && !defined(OPENSSL_SYS_VOS)
+#  define OPENSSL_SYS_VOS
+#  ifdef __HPPA__
+#   define OPENSSL_SYS_VOS_HPPA
+#  endif
+#  ifdef __IA32__
+#   define OPENSSL_SYS_VOS_IA32
+#  endif
+# endif
+
+/**
+ * That's it for OS-specific stuff
+ *****************************************************************************/
+
+/* Specials for I/O an exit */
+# ifdef OPENSSL_SYS_MSDOS
+#  define OPENSSL_UNISTD_IO <io.h>
+#  define OPENSSL_DECLARE_EXIT extern void exit(int);
+# else
+#  define OPENSSL_UNISTD_IO OPENSSL_UNISTD
+#  define OPENSSL_DECLARE_EXIT  /* declared in unistd.h */
+# endif
+
+/*-
+ * Definitions of OPENSSL_GLOBAL and OPENSSL_EXTERN, to define and declare
+ * certain global symbols that, with some compilers under VMS, have to be
+ * defined and declared explicitly with globaldef and globalref.
+ * Definitions of OPENSSL_EXPORT and OPENSSL_IMPORT, to define and declare
+ * DLL exports and imports for compilers under Win32.  These are a little
+ * more complicated to use.  Basically, for any library that exports some
+ * global variables, the following code must be present in the header file
+ * that declares them, before OPENSSL_EXTERN is used:
+ *
+ * #ifdef SOME_BUILD_FLAG_MACRO
+ * # undef OPENSSL_EXTERN
+ * # define OPENSSL_EXTERN OPENSSL_EXPORT
+ * #endif
+ *
+ * The default is to have OPENSSL_EXPORT, OPENSSL_EXTERN and OPENSSL_GLOBAL
+ * have some generally sensible values.
+ */
+
+# if defined(OPENSSL_SYS_VMS_NODECC)
+#  define OPENSSL_EXPORT globalref
+#  define OPENSSL_EXTERN globalref
+#  define OPENSSL_GLOBAL globaldef
+# elif defined(OPENSSL_SYS_WINDOWS) && defined(OPENSSL_OPT_WINDLL)
+#  define OPENSSL_EXPORT extern __declspec(dllexport)
+#  define OPENSSL_EXTERN extern __declspec(dllimport)
+#  define OPENSSL_GLOBAL
+# else
+#  define OPENSSL_EXPORT extern
+#  define OPENSSL_EXTERN extern
+#  define OPENSSL_GLOBAL
+# endif
+
+/*-
+ * Macros to allow global variables to be reached through function calls when
+ * required (if a shared library version requires it, for example.
+ * The way it's done allows definitions like this:
+ *
+ *      // in foobar.c
+ *      OPENSSL_IMPLEMENT_GLOBAL(int,foobar,0)
+ *      // in foobar.h
+ *      OPENSSL_DECLARE_GLOBAL(int,foobar);
+ *      #define foobar OPENSSL_GLOBAL_REF(foobar)
+ */
+# ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION
+#  define OPENSSL_IMPLEMENT_GLOBAL(type,name,value)                      \
+        type *_shadow_##name(void)                                      \
+        { static type _hide_##name=value; return &_hide_##name; }
+#  define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void)
+#  define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name()))
+# else
+#  define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) OPENSSL_GLOBAL type _shadow_##name=value;
+#  define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name
+#  define OPENSSL_GLOBAL_REF(name) _shadow_##name
+# endif
+
+# ifdef _WIN32
+#  ifdef _WIN64
+#   define ossl_ssize_t __int64
+#   define OSSL_SSIZE_MAX _I64_MAX
+#  else
+#   define ossl_ssize_t int
+#   define OSSL_SSIZE_MAX INT_MAX
+#  endif
+# endif
+
+# if defined(OPENSSL_SYS_UEFI) && !defined(ssize_t)
+#  define ossl_ssize_t int
+#  define OSSL_SSIZE_MAX INT_MAX
+# endif
+
+# ifndef ossl_ssize_t
+#  define ossl_ssize_t ssize_t
+#  if defined(SSIZE_MAX)
+#   define OSSL_SSIZE_MAX SSIZE_MAX
+#  elif defined(_POSIX_SSIZE_MAX)
+#   define OSSL_SSIZE_MAX _POSIX_SSIZE_MAX
+#  endif
+# endif
+
+# ifdef DEBUG_UNUSED
+#  define __owur __attribute__((__warn_unused_result__))
+# else
+#  define __owur
+# endif
+
+/* Standard integer types */
+# if defined(OPENSSL_SYS_UEFI)
+typedef INT8 int8_t;
+typedef UINT8 uint8_t;
+typedef INT16 int16_t;
+typedef UINT16 uint16_t;
+typedef INT32 int32_t;
+typedef UINT32 uint32_t;
+typedef INT64 int64_t;
+typedef UINT64 uint64_t;
+#  define PRIu64 "%Lu"
+# elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
+     defined(__osf__) || defined(__sgi) || defined(__hpux) || \
+     defined(OPENSSL_SYS_VMS) || defined (__OpenBSD__)
+#  include <inttypes.h>
+# elif defined(_MSC_VER) && _MSC_VER<=1500
+/*
+ * minimally required typdefs for systems not supporting inttypes.h or
+ * stdint.h: currently just older VC++
+ */
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef int int32_t;
+typedef unsigned int uint32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+# else
+#  include <stdint.h>
+# endif
+
+/*
+ * We need a format operator for some client tools for uint64_t.  If inttypes.h
+ * isn't available or did not define it, just go with hard-coded.
+ */
+# ifndef PRIu64
+#  ifdef SIXTY_FOUR_BIT_LONG
+#   define PRIu64 "lu"
+#  else
+#   define PRIu64 "llu"
+#  endif
+# endif
+
+/* ossl_inline: portable inline definition usable in public headers */
+# if !defined(inline) && !defined(__cplusplus)
+#  if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L
+   /* just use inline */
+#   define ossl_inline inline
+#  elif defined(__GNUC__) && __GNUC__>=2
+#   define ossl_inline __inline__
+#  elif defined(_MSC_VER)
+  /*
+   * Visual Studio: inline is available in C++ only, however
+   * __inline is available for C, see
+   * http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx
+   */
+#   define ossl_inline __inline
+#  else
+#   define ossl_inline
+#  endif
+# else
+#  define ossl_inline inline
+# endif
+
+# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
+#  define ossl_noreturn _Noreturn
+# elif defined(__GNUC__) && __GNUC__ >= 2
+#  define ossl_noreturn __attribute__((noreturn))
+# else
+#  define ossl_noreturn
+# endif
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ebcdic.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ebcdic.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ebcdic.h	(revision 331)
@@ -0,0 +1,33 @@
+/*
+ * Copyright 1999-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
+ */
+
+#ifndef HEADER_EBCDIC_H
+# define HEADER_EBCDIC_H
+
+# include <stdlib.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Avoid name clashes with other applications */
+# define os_toascii   _openssl_os_toascii
+# define os_toebcdic  _openssl_os_toebcdic
+# define ebcdic2ascii _openssl_ebcdic2ascii
+# define ascii2ebcdic _openssl_ascii2ebcdic
+
+extern const unsigned char os_toascii[256];
+extern const unsigned char os_toebcdic[256];
+void *ebcdic2ascii(void *dest, const void *srce, size_t count);
+void *ascii2ebcdic(void *dest, const void *srce, size_t count);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ec.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ec.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ec.h	(revision 331)
@@ -0,0 +1,1581 @@
+/*
+ * Copyright 2002-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#ifndef HEADER_EC_H
+# define HEADER_EC_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_EC
+# include <openssl/asn1.h>
+# include <openssl/symhacks.h>
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  include <openssl/bn.h>
+# endif
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+# ifndef OPENSSL_ECC_MAX_FIELD_BITS
+#  define OPENSSL_ECC_MAX_FIELD_BITS 661
+# endif
+
+/** Enum for the point conversion form as defined in X9.62 (ECDSA)
+ *  for the encoding of a elliptic curve point (x,y) */
+typedef enum {
+        /** the point is encoded as z||x, where the octet z specifies
+         *  which solution of the quadratic equation y is  */
+    POINT_CONVERSION_COMPRESSED = 2,
+        /** the point is encoded as z||x||y, where z is the octet 0x04  */
+    POINT_CONVERSION_UNCOMPRESSED = 4,
+        /** the point is encoded as z||x||y, where the octet z specifies
+         *  which solution of the quadratic equation y is  */
+    POINT_CONVERSION_HYBRID = 6
+} point_conversion_form_t;
+
+typedef struct ec_method_st EC_METHOD;
+typedef struct ec_group_st EC_GROUP;
+typedef struct ec_point_st EC_POINT;
+typedef struct ecpk_parameters_st ECPKPARAMETERS;
+typedef struct ec_parameters_st ECPARAMETERS;
+
+/********************************************************************/
+/*               EC_METHODs for curves over GF(p)                   */
+/********************************************************************/
+
+/** Returns the basic GFp ec methods which provides the basis for the
+ *  optimized methods.
+ *  \return  EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_simple_method(void);
+
+/** Returns GFp methods using montgomery multiplication.
+ *  \return  EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_mont_method(void);
+
+/** Returns GFp methods using optimized methods for NIST recommended curves
+ *  \return  EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_nist_method(void);
+
+# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+/** Returns 64-bit optimized methods for nistp224
+ *  \return  EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_nistp224_method(void);
+
+/** Returns 64-bit optimized methods for nistp256
+ *  \return  EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_nistp256_method(void);
+
+/** Returns 64-bit optimized methods for nistp521
+ *  \return  EC_METHOD object
+ */
+const EC_METHOD *EC_GFp_nistp521_method(void);
+# endif
+
+# ifndef OPENSSL_NO_EC2M
+/********************************************************************/
+/*           EC_METHOD for curves over GF(2^m)                      */
+/********************************************************************/
+
+/** Returns the basic GF2m ec method
+ *  \return  EC_METHOD object
+ */
+const EC_METHOD *EC_GF2m_simple_method(void);
+
+# endif
+
+/********************************************************************/
+/*                   EC_GROUP functions                             */
+/********************************************************************/
+
+/** Creates a new EC_GROUP object
+ *  \param   meth  EC_METHOD to use
+ *  \return  newly created EC_GROUP object or NULL in case of an error.
+ */
+EC_GROUP *EC_GROUP_new(const EC_METHOD *meth);
+
+/** Frees a EC_GROUP object
+ *  \param  group  EC_GROUP object to be freed.
+ */
+void EC_GROUP_free(EC_GROUP *group);
+
+/** Clears and frees a EC_GROUP object
+ *  \param  group  EC_GROUP object to be cleared and freed.
+ */
+void EC_GROUP_clear_free(EC_GROUP *group);
+
+/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD.
+ *  \param  dst  destination EC_GROUP object
+ *  \param  src  source EC_GROUP object
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src);
+
+/** Creates a new EC_GROUP object and copies the copies the content
+ *  form src to the newly created EC_KEY object
+ *  \param  src  source EC_GROUP object
+ *  \return newly created EC_GROUP object or NULL in case of an error.
+ */
+EC_GROUP *EC_GROUP_dup(const EC_GROUP *src);
+
+/** Returns the EC_METHOD of the EC_GROUP object.
+ *  \param  group  EC_GROUP object
+ *  \return EC_METHOD used in this EC_GROUP object.
+ */
+const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group);
+
+/** Returns the field type of the EC_METHOD.
+ *  \param  meth  EC_METHOD object
+ *  \return NID of the underlying field type OID.
+ */
+int EC_METHOD_get_field_type(const EC_METHOD *meth);
+
+/** Sets the generator and it's order/cofactor of a EC_GROUP object.
+ *  \param  group      EC_GROUP object
+ *  \param  generator  EC_POINT object with the generator.
+ *  \param  order      the order of the group generated by the generator.
+ *  \param  cofactor   the index of the sub-group generated by the generator
+ *                     in the group of all points on the elliptic curve.
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator,
+                           const BIGNUM *order, const BIGNUM *cofactor);
+
+/** Returns the generator of a EC_GROUP object.
+ *  \param  group  EC_GROUP object
+ *  \return the currently used generator (possibly NULL).
+ */
+const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group);
+
+/** Returns the montgomery data for order(Generator)
+ *  \param  group  EC_GROUP object
+ *  \return the currently used montgomery data (possibly NULL).
+*/
+BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group);
+
+/** Gets the order of a EC_GROUP
+ *  \param  group  EC_GROUP object
+ *  \param  order  BIGNUM to which the order is copied
+ *  \param  ctx    unused
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx);
+
+/** Gets the order of an EC_GROUP
+ *  \param  group  EC_GROUP object
+ *  \return the group order
+ */
+const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group);
+
+/** Gets the number of bits of the order of an EC_GROUP
+ *  \param  group  EC_GROUP object
+ *  \return number of bits of group order.
+ */
+int EC_GROUP_order_bits(const EC_GROUP *group);
+
+/** Gets the cofactor of a EC_GROUP
+ *  \param  group     EC_GROUP object
+ *  \param  cofactor  BIGNUM to which the cofactor is copied
+ *  \param  ctx       unused
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
+                          BN_CTX *ctx);
+
+/** Gets the cofactor of an EC_GROUP
+ *  \param  group  EC_GROUP object
+ *  \return the group cofactor
+ */
+const BIGNUM *EC_GROUP_get0_cofactor(const EC_GROUP *group);
+
+/** Sets the name of a EC_GROUP object
+ *  \param  group  EC_GROUP object
+ *  \param  nid    NID of the curve name OID
+ */
+void EC_GROUP_set_curve_name(EC_GROUP *group, int nid);
+
+/** Returns the curve name of a EC_GROUP object
+ *  \param  group  EC_GROUP object
+ *  \return NID of the curve name OID or 0 if not set.
+ */
+int EC_GROUP_get_curve_name(const EC_GROUP *group);
+
+void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
+int EC_GROUP_get_asn1_flag(const EC_GROUP *group);
+
+void EC_GROUP_set_point_conversion_form(EC_GROUP *group,
+                                        point_conversion_form_t form);
+point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);
+
+unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x);
+size_t EC_GROUP_get_seed_len(const EC_GROUP *);
+size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);
+
+/** Sets the parameter of a ec over GFp defined by y^2 = x^3 + a*x + b
+ *  \param  group  EC_GROUP object
+ *  \param  p      BIGNUM with the prime number
+ *  \param  a      BIGNUM with parameter a of the equation
+ *  \param  b      BIGNUM with parameter b of the equation
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
+                           const BIGNUM *b, BN_CTX *ctx);
+
+/** Gets the parameter of the ec over GFp defined by y^2 = x^3 + a*x + b
+ *  \param  group  EC_GROUP object
+ *  \param  p      BIGNUM for the prime number
+ *  \param  a      BIGNUM for parameter a of the equation
+ *  \param  b      BIGNUM for parameter b of the equation
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
+                           BIGNUM *b, BN_CTX *ctx);
+
+# ifndef OPENSSL_NO_EC2M
+/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
+ *  \param  group  EC_GROUP object
+ *  \param  p      BIGNUM with the polynomial defining the underlying field
+ *  \param  a      BIGNUM with parameter a of the equation
+ *  \param  b      BIGNUM with parameter b of the equation
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
+                            const BIGNUM *b, BN_CTX *ctx);
+
+/** Gets the parameter of the ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b
+ *  \param  group  EC_GROUP object
+ *  \param  p      BIGNUM for the polynomial defining the underlying field
+ *  \param  a      BIGNUM for parameter a of the equation
+ *  \param  b      BIGNUM for parameter b of the equation
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
+                            BIGNUM *b, BN_CTX *ctx);
+# endif
+/** Returns the number of bits needed to represent a field element
+ *  \param  group  EC_GROUP object
+ *  \return number of bits needed to represent a field element
+ */
+int EC_GROUP_get_degree(const EC_GROUP *group);
+
+/** Checks whether the parameter in the EC_GROUP define a valid ec group
+ *  \param  group  EC_GROUP object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 if group is a valid ec group and 0 otherwise
+ */
+int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);
+
+/** Checks whether the discriminant of the elliptic curve is zero or not
+ *  \param  group  EC_GROUP object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 if the discriminant is not zero and 0 otherwise
+ */
+int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx);
+
+/** Compares two EC_GROUP objects
+ *  \param  a    first EC_GROUP object
+ *  \param  b    second EC_GROUP object
+ *  \param  ctx  BN_CTX object (optional)
+ *  \return 0 if the groups are equal, 1 if not, or -1 on error
+ */
+int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx);
+
+/*
+ * EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*() after
+ * choosing an appropriate EC_METHOD
+ */
+
+/** Creates a new EC_GROUP object with the specified parameters defined
+ *  over GFp (defined by the equation y^2 = x^3 + a*x + b)
+ *  \param  p    BIGNUM with the prime number
+ *  \param  a    BIGNUM with the parameter a of the equation
+ *  \param  b    BIGNUM with the parameter b of the equation
+ *  \param  ctx  BN_CTX object (optional)
+ *  \return newly created EC_GROUP object with the specified parameters
+ */
+EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
+                                 const BIGNUM *b, BN_CTX *ctx);
+# ifndef OPENSSL_NO_EC2M
+/** Creates a new EC_GROUP object with the specified parameters defined
+ *  over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b)
+ *  \param  p    BIGNUM with the polynomial defining the underlying field
+ *  \param  a    BIGNUM with the parameter a of the equation
+ *  \param  b    BIGNUM with the parameter b of the equation
+ *  \param  ctx  BN_CTX object (optional)
+ *  \return newly created EC_GROUP object with the specified parameters
+ */
+EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a,
+                                  const BIGNUM *b, BN_CTX *ctx);
+# endif
+
+/** Creates a EC_GROUP object with a curve specified by a NID
+ *  \param  nid  NID of the OID of the curve name
+ *  \return newly created EC_GROUP object with specified curve or NULL
+ *          if an error occurred
+ */
+EC_GROUP *EC_GROUP_new_by_curve_name(int nid);
+
+/** Creates a new EC_GROUP object from an ECPARAMETERS object
+ *  \param  params  pointer to the ECPARAMETERS object
+ *  \return newly created EC_GROUP object with specified curve or NULL
+ *          if an error occurred
+ */
+EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params);
+
+/** Creates an ECPARAMETERS object for the the given EC_GROUP object.
+ *  \param  group   pointer to the EC_GROUP object
+ *  \param  params  pointer to an existing ECPARAMETERS object or NULL
+ *  \return pointer to the new ECPARAMETERS object or NULL
+ *          if an error occurred.
+ */
+ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group,
+                                        ECPARAMETERS *params);
+
+/** Creates a new EC_GROUP object from an ECPKPARAMETERS object
+ *  \param  params  pointer to an existing ECPKPARAMETERS object, or NULL
+ *  \return newly created EC_GROUP object with specified curve, or NULL
+ *          if an error occurred
+ */
+EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params);
+
+/** Creates an ECPKPARAMETERS object for the the given EC_GROUP object.
+ *  \param  group   pointer to the EC_GROUP object
+ *  \param  params  pointer to an existing ECPKPARAMETERS object or NULL
+ *  \return pointer to the new ECPKPARAMETERS object or NULL
+ *          if an error occurred.
+ */
+ECPKPARAMETERS *EC_GROUP_get_ecpkparameters(const EC_GROUP *group,
+                                            ECPKPARAMETERS *params);
+
+/********************************************************************/
+/*               handling of internal curves                        */
+/********************************************************************/
+
+typedef struct {
+    int nid;
+    const char *comment;
+} EC_builtin_curve;
+
+/*
+ * EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number of all
+ * available curves or zero if a error occurred. In case r is not zero,
+ * nitems EC_builtin_curve structures are filled with the data of the first
+ * nitems internal groups
+ */
+size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems);
+
+const char *EC_curve_nid2nist(int nid);
+int EC_curve_nist2nid(const char *name);
+
+/********************************************************************/
+/*                    EC_POINT functions                            */
+/********************************************************************/
+
+/** Creates a new EC_POINT object for the specified EC_GROUP
+ *  \param  group  EC_GROUP the underlying EC_GROUP object
+ *  \return newly created EC_POINT object or NULL if an error occurred
+ */
+EC_POINT *EC_POINT_new(const EC_GROUP *group);
+
+/** Frees a EC_POINT object
+ *  \param  point  EC_POINT object to be freed
+ */
+void EC_POINT_free(EC_POINT *point);
+
+/** Clears and frees a EC_POINT object
+ *  \param  point  EC_POINT object to be cleared and freed
+ */
+void EC_POINT_clear_free(EC_POINT *point);
+
+/** Copies EC_POINT object
+ *  \param  dst  destination EC_POINT object
+ *  \param  src  source EC_POINT object
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src);
+
+/** Creates a new EC_POINT object and copies the content of the supplied
+ *  EC_POINT
+ *  \param  src    source EC_POINT object
+ *  \param  group  underlying the EC_GROUP object
+ *  \return newly created EC_POINT object or NULL if an error occurred
+ */
+EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group);
+
+/** Returns the EC_METHOD used in EC_POINT object
+ *  \param  point  EC_POINT object
+ *  \return the EC_METHOD used
+ */
+const EC_METHOD *EC_POINT_method_of(const EC_POINT *point);
+
+/** Sets a point to infinity (neutral element)
+ *  \param  group  underlying EC_GROUP object
+ *  \param  point  EC_POINT to set to infinity
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point);
+
+/** Sets the jacobian projective coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with the x-coordinate
+ *  \param  y      BIGNUM with the y-coordinate
+ *  \param  z      BIGNUM with the z-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
+                                             EC_POINT *p, const BIGNUM *x,
+                                             const BIGNUM *y, const BIGNUM *z,
+                                             BN_CTX *ctx);
+
+/** Gets the jacobian projective coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM for the x-coordinate
+ *  \param  y      BIGNUM for the y-coordinate
+ *  \param  z      BIGNUM for the z-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
+                                             const EC_POINT *p, BIGNUM *x,
+                                             BIGNUM *y, BIGNUM *z,
+                                             BN_CTX *ctx);
+
+/** Sets the affine coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with the x-coordinate
+ *  \param  y      BIGNUM with the y-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p,
+                                        const BIGNUM *x, const BIGNUM *y,
+                                        BN_CTX *ctx);
+
+/** Gets the affine coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM for the x-coordinate
+ *  \param  y      BIGNUM for the y-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
+                                        const EC_POINT *p, BIGNUM *x,
+                                        BIGNUM *y, BN_CTX *ctx);
+
+/** Sets the x9.62 compressed coordinates of a EC_POINT over GFp
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with x-coordinate
+ *  \param  y_bit  integer with the y-Bit (either 0 or 1)
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
+                                            EC_POINT *p, const BIGNUM *x,
+                                            int y_bit, BN_CTX *ctx);
+# ifndef OPENSSL_NO_EC2M
+/** Sets the affine coordinates of a EC_POINT over GF2m
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with the x-coordinate
+ *  \param  y      BIGNUM with the y-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p,
+                                         const BIGNUM *x, const BIGNUM *y,
+                                         BN_CTX *ctx);
+
+/** Gets the affine coordinates of a EC_POINT over GF2m
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM for the x-coordinate
+ *  \param  y      BIGNUM for the y-coordinate
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group,
+                                         const EC_POINT *p, BIGNUM *x,
+                                         BIGNUM *y, BN_CTX *ctx);
+
+/** Sets the x9.62 compressed coordinates of a EC_POINT over GF2m
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  x      BIGNUM with x-coordinate
+ *  \param  y_bit  integer with the y-Bit (either 0 or 1)
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group,
+                                             EC_POINT *p, const BIGNUM *x,
+                                             int y_bit, BN_CTX *ctx);
+# endif
+/** Encodes a EC_POINT object to a octet string
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  form   point conversion form
+ *  \param  buf    memory buffer for the result. If NULL the function returns
+ *                 required buffer size.
+ *  \param  len    length of the memory buffer
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return the length of the encoded octet string or 0 if an error occurred
+ */
+size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p,
+                          point_conversion_form_t form,
+                          unsigned char *buf, size_t len, BN_CTX *ctx);
+
+/** Decodes a EC_POINT from a octet string
+ *  \param  group  underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \param  buf    memory buffer with the encoded ec point
+ *  \param  len    length of the encoded ec point
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p,
+                       const unsigned char *buf, size_t len, BN_CTX *ctx);
+
+/** Encodes an EC_POINT object to an allocated octet string
+ *  \param  group  underlying EC_GROUP object
+ *  \param  point  EC_POINT object
+ *  \param  form   point conversion form
+ *  \param  pbuf   returns pointer to allocated buffer
+ *  \param  len    length of the memory buffer
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return the length of the encoded octet string or 0 if an error occurred
+ */
+
+size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point,
+                          point_conversion_form_t form,
+                          unsigned char **pbuf, BN_CTX *ctx);
+
+/* other interfaces to point2oct/oct2point: */
+BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
+                          point_conversion_form_t form, BIGNUM *, BN_CTX *);
+EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *,
+                            EC_POINT *, BN_CTX *);
+char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *,
+                         point_conversion_form_t form, BN_CTX *);
+EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *,
+                             EC_POINT *, BN_CTX *);
+
+/********************************************************************/
+/*         functions for doing EC_POINT arithmetic                  */
+/********************************************************************/
+
+/** Computes the sum of two EC_POINT
+ *  \param  group  underlying EC_GROUP object
+ *  \param  r      EC_POINT object for the result (r = a + b)
+ *  \param  a      EC_POINT object with the first summand
+ *  \param  b      EC_POINT object with the second summand
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+                 const EC_POINT *b, BN_CTX *ctx);
+
+/** Computes the double of a EC_POINT
+ *  \param  group  underlying EC_GROUP object
+ *  \param  r      EC_POINT object for the result (r = 2 * a)
+ *  \param  a      EC_POINT object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
+                 BN_CTX *ctx);
+
+/** Computes the inverse of a EC_POINT
+ *  \param  group  underlying EC_GROUP object
+ *  \param  a      EC_POINT object to be inverted (it's used for the result as well)
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx);
+
+/** Checks whether the point is the neutral element of the group
+ *  \param  group  the underlying EC_GROUP object
+ *  \param  p      EC_POINT object
+ *  \return 1 if the point is the neutral element and 0 otherwise
+ */
+int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p);
+
+/** Checks whether the point is on the curve
+ *  \param  group  underlying EC_GROUP object
+ *  \param  point  EC_POINT object to check
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 if the point is on the curve, 0 if not, or -1 on error
+ */
+int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
+                         BN_CTX *ctx);
+
+/** Compares two EC_POINTs
+ *  \param  group  underlying EC_GROUP object
+ *  \param  a      first EC_POINT object
+ *  \param  b      second EC_POINT object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 if the points are not equal, 0 if they are, or -1 on error
+ */
+int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
+                 BN_CTX *ctx);
+
+int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx);
+int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
+                          EC_POINT *points[], BN_CTX *ctx);
+
+/** Computes r = generator * n + sum_{i=0}^{num-1} p[i] * m[i]
+ *  \param  group  underlying EC_GROUP object
+ *  \param  r      EC_POINT object for the result
+ *  \param  n      BIGNUM with the multiplier for the group generator (optional)
+ *  \param  num    number further summands
+ *  \param  p      array of size num of EC_POINT objects
+ *  \param  m      array of size num of BIGNUM objects
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n,
+                  size_t num, const EC_POINT *p[], const BIGNUM *m[],
+                  BN_CTX *ctx);
+
+/** Computes r = generator * n + q * m
+ *  \param  group  underlying EC_GROUP object
+ *  \param  r      EC_POINT object for the result
+ *  \param  n      BIGNUM with the multiplier for the group generator (optional)
+ *  \param  q      EC_POINT object with the first factor of the second summand
+ *  \param  m      BIGNUM with the second factor of the second summand
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n,
+                 const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx);
+
+/** Stores multiples of generator for faster point multiplication
+ *  \param  group  EC_GROUP object
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+
+/** Reports whether a precomputation has been done
+ *  \param  group  EC_GROUP object
+ *  \return 1 if a pre-computation has been done and 0 otherwise
+ */
+int EC_GROUP_have_precompute_mult(const EC_GROUP *group);
+
+/********************************************************************/
+/*                       ASN1 stuff                                 */
+/********************************************************************/
+
+DECLARE_ASN1_ITEM(ECPKPARAMETERS)
+DECLARE_ASN1_ALLOC_FUNCTIONS(ECPKPARAMETERS)
+DECLARE_ASN1_ITEM(ECPARAMETERS)
+DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS)
+
+/*
+ * EC_GROUP_get_basis_type() returns the NID of the basis type used to
+ * represent the field elements
+ */
+int EC_GROUP_get_basis_type(const EC_GROUP *);
+# ifndef OPENSSL_NO_EC2M
+int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k);
+int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1,
+                                   unsigned int *k2, unsigned int *k3);
+# endif
+
+# define OPENSSL_EC_EXPLICIT_CURVE  0x000
+# define OPENSSL_EC_NAMED_CURVE     0x001
+
+EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len);
+int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out);
+
+# define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x)
+# define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x)
+# define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \
+                (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x))
+# define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \
+                (unsigned char *)(x))
+
+int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off);
+# ifndef OPENSSL_NO_STDIO
+int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
+# endif
+
+/********************************************************************/
+/*                      EC_KEY functions                            */
+/********************************************************************/
+
+/* some values for the encoding_flag */
+# define EC_PKEY_NO_PARAMETERS   0x001
+# define EC_PKEY_NO_PUBKEY       0x002
+
+/* some values for the flags field */
+# define EC_FLAG_NON_FIPS_ALLOW  0x1
+# define EC_FLAG_FIPS_CHECKED    0x2
+# define EC_FLAG_COFACTOR_ECDH   0x1000
+
+/** Creates a new EC_KEY object.
+ *  \return EC_KEY object or NULL if an error occurred.
+ */
+EC_KEY *EC_KEY_new(void);
+
+int EC_KEY_get_flags(const EC_KEY *key);
+
+void EC_KEY_set_flags(EC_KEY *key, int flags);
+
+void EC_KEY_clear_flags(EC_KEY *key, int flags);
+
+/** Creates a new EC_KEY object using a named curve as underlying
+ *  EC_GROUP object.
+ *  \param  nid  NID of the named curve.
+ *  \return EC_KEY object or NULL if an error occurred.
+ */
+EC_KEY *EC_KEY_new_by_curve_name(int nid);
+
+/** Frees a EC_KEY object.
+ *  \param  key  EC_KEY object to be freed.
+ */
+void EC_KEY_free(EC_KEY *key);
+
+/** Copies a EC_KEY object.
+ *  \param  dst  destination EC_KEY object
+ *  \param  src  src EC_KEY object
+ *  \return dst or NULL if an error occurred.
+ */
+EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src);
+
+/** Creates a new EC_KEY object and copies the content from src to it.
+ *  \param  src  the source EC_KEY object
+ *  \return newly created EC_KEY object or NULL if an error occurred.
+ */
+EC_KEY *EC_KEY_dup(const EC_KEY *src);
+
+/** Increases the internal reference count of a EC_KEY object.
+ *  \param  key  EC_KEY object
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_up_ref(EC_KEY *key);
+
+/** Returns the EC_GROUP object of a EC_KEY object
+ *  \param  key  EC_KEY object
+ *  \return the EC_GROUP object (possibly NULL).
+ */
+const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key);
+
+/** Sets the EC_GROUP of a EC_KEY object.
+ *  \param  key    EC_KEY object
+ *  \param  group  EC_GROUP to use in the EC_KEY object (note: the EC_KEY
+ *                 object will use an own copy of the EC_GROUP).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group);
+
+/** Returns the private key of a EC_KEY object.
+ *  \param  key  EC_KEY object
+ *  \return a BIGNUM with the private key (possibly NULL).
+ */
+const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key);
+
+/** Sets the private key of a EC_KEY object.
+ *  \param  key  EC_KEY object
+ *  \param  prv  BIGNUM with the private key (note: the EC_KEY object
+ *               will use an own copy of the BIGNUM).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv);
+
+/** Returns the public key of a EC_KEY object.
+ *  \param  key  the EC_KEY object
+ *  \return a EC_POINT object with the public key (possibly NULL)
+ */
+const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);
+
+/** Sets the public key of a EC_KEY object.
+ *  \param  key  EC_KEY object
+ *  \param  pub  EC_POINT object with the public key (note: the EC_KEY object
+ *               will use an own copy of the EC_POINT object).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
+
+unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
+void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags);
+point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key);
+void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform);
+
+#define EC_KEY_get_ex_new_index(l, p, newf, dupf, freef) \
+    CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_EC_KEY, l, p, newf, dupf, freef)
+int EC_KEY_set_ex_data(EC_KEY *key, int idx, void *arg);
+void *EC_KEY_get_ex_data(const EC_KEY *key, int idx);
+
+/* wrapper functions for the underlying EC_GROUP object */
+void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag);
+
+/** Creates a table of pre-computed multiples of the generator to
+ *  accelerate further EC_KEY operations.
+ *  \param  key  EC_KEY object
+ *  \param  ctx  BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx);
+
+/** Creates a new ec private (and optional a new public) key.
+ *  \param  key  EC_KEY object
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int EC_KEY_generate_key(EC_KEY *key);
+
+/** Verifies that a private and/or public key is valid.
+ *  \param  key  the EC_KEY object
+ *  \return 1 on success and 0 otherwise.
+ */
+int EC_KEY_check_key(const EC_KEY *key);
+
+/** Indicates if an EC_KEY can be used for signing.
+ *  \param  key  the EC_KEY object
+ *  \return 1 if can can sign and 0 otherwise.
+ */
+int EC_KEY_can_sign(const EC_KEY *eckey);
+
+/** Sets a public key from affine coordinates performing
+ *  necessary NIST PKV tests.
+ *  \param  key  the EC_KEY object
+ *  \param  x    public key x coordinate
+ *  \param  y    public key y coordinate
+ *  \return 1 on success and 0 otherwise.
+ */
+int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
+                                             BIGNUM *y);
+
+/** Encodes an EC_KEY public key to an allocated octet string
+ *  \param  key    key to encode
+ *  \param  form   point conversion form
+ *  \param  pbuf   returns pointer to allocated buffer
+ *  \param  len    length of the memory buffer
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return the length of the encoded octet string or 0 if an error occurred
+ */
+
+size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form,
+                      unsigned char **pbuf, BN_CTX *ctx);
+
+/** Decodes a EC_KEY public key from a octet string
+ *  \param  key    key to decode
+ *  \param  buf    memory buffer with the encoded ec point
+ *  \param  len    length of the encoded ec point
+ *  \param  ctx    BN_CTX object (optional)
+ *  \return 1 on success and 0 if an error occurred
+ */
+
+int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len,
+                   BN_CTX *ctx);
+
+/** Decodes an EC_KEY private key from an octet string
+ *  \param  key    key to decode
+ *  \param  buf    memory buffer with the encoded private key
+ *  \param  len    length of the encoded key
+ *  \return 1 on success and 0 if an error occurred
+ */
+
+int EC_KEY_oct2priv(EC_KEY *key, const unsigned char *buf, size_t len);
+
+/** Encodes a EC_KEY private key to an octet string
+ *  \param  key    key to encode
+ *  \param  buf    memory buffer for the result. If NULL the function returns
+ *                 required buffer size.
+ *  \param  len    length of the memory buffer
+ *  \return the length of the encoded octet string or 0 if an error occurred
+ */
+
+size_t EC_KEY_priv2oct(const EC_KEY *key, unsigned char *buf, size_t len);
+
+/** Encodes an EC_KEY private key to an allocated octet string
+ *  \param  key    key to encode
+ *  \param  pbuf   returns pointer to allocated buffer
+ *  \return the length of the encoded octet string or 0 if an error occurred
+ */
+
+size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf);
+
+/********************************************************************/
+/*        de- and encoding functions for SEC1 ECPrivateKey          */
+/********************************************************************/
+
+/** Decodes a private key from a memory buffer.
+ *  \param  key  a pointer to a EC_KEY object which should be used (or NULL)
+ *  \param  in   pointer to memory with the DER encoded private key
+ *  \param  len  length of the DER encoded private key
+ *  \return the decoded private key or NULL if an error occurred.
+ */
+EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len);
+
+/** Encodes a private key object and stores the result in a buffer.
+ *  \param  key  the EC_KEY object to encode
+ *  \param  out  the buffer for the result (if NULL the function returns number
+ *               of bytes needed).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out);
+
+/********************************************************************/
+/*        de- and encoding functions for EC parameters              */
+/********************************************************************/
+
+/** Decodes ec parameter from a memory buffer.
+ *  \param  key  a pointer to a EC_KEY object which should be used (or NULL)
+ *  \param  in   pointer to memory with the DER encoded ec parameters
+ *  \param  len  length of the DER encoded ec parameters
+ *  \return a EC_KEY object with the decoded parameters or NULL if an error
+ *          occurred.
+ */
+EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len);
+
+/** Encodes ec parameter and stores the result in a buffer.
+ *  \param  key  the EC_KEY object with ec parameters to encode
+ *  \param  out  the buffer for the result (if NULL the function returns number
+ *               of bytes needed).
+ *  \return 1 on success and 0 if an error occurred.
+ */
+int i2d_ECParameters(EC_KEY *key, unsigned char **out);
+
+/********************************************************************/
+/*         de- and encoding functions for EC public key             */
+/*         (octet string, not DER -- hence 'o2i' and 'i2o')         */
+/********************************************************************/
+
+/** Decodes a ec public key from a octet string.
+ *  \param  key  a pointer to a EC_KEY object which should be used
+ *  \param  in   memory buffer with the encoded public key
+ *  \param  len  length of the encoded public key
+ *  \return EC_KEY object with decoded public key or NULL if an error
+ *          occurred.
+ */
+EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len);
+
+/** Encodes a ec public key in an octet string.
+ *  \param  key  the EC_KEY object with the public key
+ *  \param  out  the buffer for the result (if NULL the function returns number
+ *               of bytes needed).
+ *  \return 1 on success and 0 if an error occurred
+ */
+int i2o_ECPublicKey(const EC_KEY *key, unsigned char **out);
+
+/** Prints out the ec parameters on human readable form.
+ *  \param  bp   BIO object to which the information is printed
+ *  \param  key  EC_KEY object
+ *  \return 1 on success and 0 if an error occurred
+ */
+int ECParameters_print(BIO *bp, const EC_KEY *key);
+
+/** Prints out the contents of a EC_KEY object
+ *  \param  bp   BIO object to which the information is printed
+ *  \param  key  EC_KEY object
+ *  \param  off  line offset
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_KEY_print(BIO *bp, const EC_KEY *key, int off);
+
+# ifndef OPENSSL_NO_STDIO
+/** Prints out the ec parameters on human readable form.
+ *  \param  fp   file descriptor to which the information is printed
+ *  \param  key  EC_KEY object
+ *  \return 1 on success and 0 if an error occurred
+ */
+int ECParameters_print_fp(FILE *fp, const EC_KEY *key);
+
+/** Prints out the contents of a EC_KEY object
+ *  \param  fp   file descriptor to which the information is printed
+ *  \param  key  EC_KEY object
+ *  \param  off  line offset
+ *  \return 1 on success and 0 if an error occurred
+ */
+int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off);
+
+# endif
+
+const EC_KEY_METHOD *EC_KEY_OpenSSL(void);
+const EC_KEY_METHOD *EC_KEY_get_default_method(void);
+void EC_KEY_set_default_method(const EC_KEY_METHOD *meth);
+const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *key);
+int EC_KEY_set_method(EC_KEY *key, const EC_KEY_METHOD *meth);
+EC_KEY *EC_KEY_new_method(ENGINE *engine);
+
+int ECDH_KDF_X9_62(unsigned char *out, size_t outlen,
+                   const unsigned char *Z, size_t Zlen,
+                   const unsigned char *sinfo, size_t sinfolen,
+                   const EVP_MD *md);
+
+int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
+                     const EC_KEY *ecdh,
+                     void *(*KDF) (const void *in, size_t inlen,
+                                   void *out, size_t *outlen));
+
+typedef struct ECDSA_SIG_st ECDSA_SIG;
+
+/** Allocates and initialize a ECDSA_SIG structure
+ *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
+ */
+ECDSA_SIG *ECDSA_SIG_new(void);
+
+/** frees a ECDSA_SIG structure
+ *  \param  sig  pointer to the ECDSA_SIG structure
+ */
+void ECDSA_SIG_free(ECDSA_SIG *sig);
+
+/** DER encode content of ECDSA_SIG object (note: this function modifies *pp
+ *  (*pp += length of the DER encoded signature)).
+ *  \param  sig  pointer to the ECDSA_SIG object
+ *  \param  pp   pointer to a unsigned char pointer for the output or NULL
+ *  \return the length of the DER encoded ECDSA_SIG object or 0
+ */
+int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);
+
+/** Decodes a DER encoded ECDSA signature (note: this function changes *pp
+ *  (*pp += len)).
+ *  \param  sig  pointer to ECDSA_SIG pointer (may be NULL)
+ *  \param  pp   memory buffer with the DER encoded signature
+ *  \param  len  length of the buffer
+ *  \return pointer to the decoded ECDSA_SIG structure (or NULL)
+ */
+ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len);
+
+/** Accessor for r and s fields of ECDSA_SIG
+ *  \param  sig  pointer to ECDSA_SIG pointer
+ *  \param  pr   pointer to BIGNUM pointer for r (may be NULL)
+ *  \param  ps   pointer to BIGNUM pointer for s (may be NULL)
+ */
+void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps);
+
+/** Setter for r and s fields of ECDSA_SIG
+ *  \param  sig  pointer to ECDSA_SIG pointer
+ *  \param  r    pointer to BIGNUM for r (may be NULL)
+ *  \param  s    pointer to BIGNUM for s (may be NULL)
+ */
+int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s);
+
+/** Computes the ECDSA signature of the given hash value using
+ *  the supplied private key and returns the created signature.
+ *  \param  dgst      pointer to the hash value
+ *  \param  dgst_len  length of the hash value
+ *  \param  eckey     EC_KEY object containing a private EC key
+ *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
+ */
+ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dgst_len,
+                         EC_KEY *eckey);
+
+/** Computes ECDSA signature of a given hash value using the supplied
+ *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ *  \param  dgst     pointer to the hash value to sign
+ *  \param  dgstlen  length of the hash value
+ *  \param  kinv     BIGNUM with a pre-computed inverse k (optional)
+ *  \param  rp       BIGNUM with a pre-computed rp value (optional),
+ *                   see ECDSA_sign_setup
+ *  \param  eckey    EC_KEY object containing a private EC key
+ *  \return pointer to a ECDSA_SIG structure or NULL if an error occurred
+ */
+ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen,
+                            const BIGNUM *kinv, const BIGNUM *rp,
+                            EC_KEY *eckey);
+
+/** Verifies that the supplied signature is a valid ECDSA
+ *  signature of the supplied hash value using the supplied public key.
+ *  \param  dgst      pointer to the hash value
+ *  \param  dgst_len  length of the hash value
+ *  \param  sig       ECDSA_SIG structure
+ *  \param  eckey     EC_KEY object containing a public EC key
+ *  \return 1 if the signature is valid, 0 if the signature is invalid
+ *          and -1 on error
+ */
+int ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
+                    const ECDSA_SIG *sig, EC_KEY *eckey);
+
+/** Precompute parts of the signing operation
+ *  \param  eckey  EC_KEY object containing a private EC key
+ *  \param  ctx    BN_CTX object (optional)
+ *  \param  kinv   BIGNUM pointer for the inverse of k
+ *  \param  rp     BIGNUM pointer for x coordinate of k * generator
+ *  \return 1 on success and 0 otherwise
+ */
+int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, BIGNUM **rp);
+
+/** Computes ECDSA signature of a given hash value using the supplied
+ *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ *  \param  type     this parameter is ignored
+ *  \param  dgst     pointer to the hash value to sign
+ *  \param  dgstlen  length of the hash value
+ *  \param  sig      memory for the DER encoded created signature
+ *  \param  siglen   pointer to the length of the returned signature
+ *  \param  eckey    EC_KEY object containing a private EC key
+ *  \return 1 on success and 0 otherwise
+ */
+int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen,
+               unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);
+
+/** Computes ECDSA signature of a given hash value using the supplied
+ *  private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ *  \param  type     this parameter is ignored
+ *  \param  dgst     pointer to the hash value to sign
+ *  \param  dgstlen  length of the hash value
+ *  \param  sig      buffer to hold the DER encoded signature
+ *  \param  siglen   pointer to the length of the returned signature
+ *  \param  kinv     BIGNUM with a pre-computed inverse k (optional)
+ *  \param  rp       BIGNUM with a pre-computed rp value (optional),
+ *                   see ECDSA_sign_setup
+ *  \param  eckey    EC_KEY object containing a private EC key
+ *  \return 1 on success and 0 otherwise
+ */
+int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen,
+                  unsigned char *sig, unsigned int *siglen,
+                  const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey);
+
+/** Verifies that the given signature is valid ECDSA signature
+ *  of the supplied hash value using the specified public key.
+ *  \param  type     this parameter is ignored
+ *  \param  dgst     pointer to the hash value
+ *  \param  dgstlen  length of the hash value
+ *  \param  sig      pointer to the DER encoded signature
+ *  \param  siglen   length of the DER encoded signature
+ *  \param  eckey    EC_KEY object containing a public EC key
+ *  \return 1 if the signature is valid, 0 if the signature is invalid
+ *          and -1 on error
+ */
+int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen,
+                 const unsigned char *sig, int siglen, EC_KEY *eckey);
+
+/** Returns the maximum length of the DER encoded signature
+ *  \param  eckey  EC_KEY object
+ *  \return numbers of bytes required for the DER encoded signature
+ */
+int ECDSA_size(const EC_KEY *eckey);
+
+/********************************************************************/
+/*  EC_KEY_METHOD constructors, destructors, writers and accessors  */
+/********************************************************************/
+
+EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *meth);
+void EC_KEY_METHOD_free(EC_KEY_METHOD *meth);
+void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth,
+                            int (*init)(EC_KEY *key),
+                            void (*finish)(EC_KEY *key),
+                            int (*copy)(EC_KEY *dest, const EC_KEY *src),
+                            int (*set_group)(EC_KEY *key, const EC_GROUP *grp),
+                            int (*set_private)(EC_KEY *key,
+                                               const BIGNUM *priv_key),
+                            int (*set_public)(EC_KEY *key,
+                                              const EC_POINT *pub_key));
+
+void EC_KEY_METHOD_set_keygen(EC_KEY_METHOD *meth,
+                              int (*keygen)(EC_KEY *key));
+
+void EC_KEY_METHOD_set_compute_key(EC_KEY_METHOD *meth,
+                                   int (*ckey)(unsigned char **psec,
+                                               size_t *pseclen,
+                                               const EC_POINT *pub_key,
+                                               const EC_KEY *ecdh));
+
+void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth,
+                            int (*sign)(int type, const unsigned char *dgst,
+                                        int dlen, unsigned char *sig,
+                                        unsigned int *siglen,
+                                        const BIGNUM *kinv, const BIGNUM *r,
+                                        EC_KEY *eckey),
+                            int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
+                                              BIGNUM **kinvp, BIGNUM **rp),
+                            ECDSA_SIG *(*sign_sig)(const unsigned char *dgst,
+                                                   int dgst_len,
+                                                   const BIGNUM *in_kinv,
+                                                   const BIGNUM *in_r,
+                                                   EC_KEY *eckey));
+
+void EC_KEY_METHOD_set_verify(EC_KEY_METHOD *meth,
+                              int (*verify)(int type, const unsigned
+                                            char *dgst, int dgst_len,
+                                            const unsigned char *sigbuf,
+                                            int sig_len, EC_KEY *eckey),
+                              int (*verify_sig)(const unsigned char *dgst,
+                                                int dgst_len,
+                                                const ECDSA_SIG *sig,
+                                                EC_KEY *eckey));
+
+void EC_KEY_METHOD_get_init(EC_KEY_METHOD *meth,
+                            int (**pinit)(EC_KEY *key),
+                            void (**pfinish)(EC_KEY *key),
+                            int (**pcopy)(EC_KEY *dest, const EC_KEY *src),
+                            int (**pset_group)(EC_KEY *key,
+                                               const EC_GROUP *grp),
+                            int (**pset_private)(EC_KEY *key,
+                                                 const BIGNUM *priv_key),
+                            int (**pset_public)(EC_KEY *key,
+                                                const EC_POINT *pub_key));
+
+void EC_KEY_METHOD_get_keygen(EC_KEY_METHOD *meth,
+                              int (**pkeygen)(EC_KEY *key));
+
+void EC_KEY_METHOD_get_compute_key(EC_KEY_METHOD *meth,
+                                   int (**pck)(unsigned char **psec,
+                                               size_t *pseclen,
+                                               const EC_POINT *pub_key,
+                                               const EC_KEY *ecdh));
+
+void EC_KEY_METHOD_get_sign(EC_KEY_METHOD *meth,
+                            int (**psign)(int type, const unsigned char *dgst,
+                                          int dlen, unsigned char *sig,
+                                          unsigned int *siglen,
+                                          const BIGNUM *kinv, const BIGNUM *r,
+                                          EC_KEY *eckey),
+                            int (**psign_setup)(EC_KEY *eckey, BN_CTX *ctx_in,
+                                                BIGNUM **kinvp, BIGNUM **rp),
+                            ECDSA_SIG *(**psign_sig)(const unsigned char *dgst,
+                                                     int dgst_len,
+                                                     const BIGNUM *in_kinv,
+                                                     const BIGNUM *in_r,
+                                                     EC_KEY *eckey));
+
+void EC_KEY_METHOD_get_verify(EC_KEY_METHOD *meth,
+                              int (**pverify)(int type, const unsigned
+                                              char *dgst, int dgst_len,
+                                              const unsigned char *sigbuf,
+                                              int sig_len, EC_KEY *eckey),
+                              int (**pverify_sig)(const unsigned char *dgst,
+                                                  int dgst_len,
+                                                  const ECDSA_SIG *sig,
+                                                  EC_KEY *eckey));
+
+# define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x)
+
+# ifndef __cplusplus
+#  if defined(__SUNPRO_C)
+#   if __SUNPRO_C >= 0x520
+#    pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
+#   endif
+#  endif
+# endif
+
+# define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \
+                                EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL)
+
+# define EVP_PKEY_CTX_set_ec_param_enc(ctx, flag) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \
+                                EVP_PKEY_CTRL_EC_PARAM_ENC, flag, NULL)
+
+# define EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, flag) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_EC_ECDH_COFACTOR, flag, NULL)
+
+# define EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_EC_ECDH_COFACTOR, -2, NULL)
+
+# define EVP_PKEY_CTX_set_ecdh_kdf_type(ctx, kdf) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_EC_KDF_TYPE, kdf, NULL)
+
+# define EVP_PKEY_CTX_get_ecdh_kdf_type(ctx) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_EC_KDF_TYPE, -2, NULL)
+
+# define EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_EC_KDF_MD, 0, (void *)md)
+
+# define EVP_PKEY_CTX_get_ecdh_kdf_md(ctx, pmd) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_GET_EC_KDF_MD, 0, (void *)pmd)
+
+# define EVP_PKEY_CTX_set_ecdh_kdf_outlen(ctx, len) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_EC_KDF_OUTLEN, len, NULL)
+
+# define EVP_PKEY_CTX_get_ecdh_kdf_outlen(ctx, plen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_DERIVE, \
+                        EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN, 0, (void *)plen)
+
+# define EVP_PKEY_CTX_set0_ecdh_kdf_ukm(ctx, p, plen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_EC_KDF_UKM, plen, (void *)p)
+
+# define EVP_PKEY_CTX_get0_ecdh_kdf_ukm(ctx, p) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0, (void *)p)
+
+# define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID             (EVP_PKEY_ALG_CTRL + 1)
+# define EVP_PKEY_CTRL_EC_PARAM_ENC                      (EVP_PKEY_ALG_CTRL + 2)
+# define EVP_PKEY_CTRL_EC_ECDH_COFACTOR                  (EVP_PKEY_ALG_CTRL + 3)
+# define EVP_PKEY_CTRL_EC_KDF_TYPE                       (EVP_PKEY_ALG_CTRL + 4)
+# define EVP_PKEY_CTRL_EC_KDF_MD                         (EVP_PKEY_ALG_CTRL + 5)
+# define EVP_PKEY_CTRL_GET_EC_KDF_MD                     (EVP_PKEY_ALG_CTRL + 6)
+# define EVP_PKEY_CTRL_EC_KDF_OUTLEN                     (EVP_PKEY_ALG_CTRL + 7)
+# define EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN                 (EVP_PKEY_ALG_CTRL + 8)
+# define EVP_PKEY_CTRL_EC_KDF_UKM                        (EVP_PKEY_ALG_CTRL + 9)
+# define EVP_PKEY_CTRL_GET_EC_KDF_UKM                    (EVP_PKEY_ALG_CTRL + 10)
+/* KDF types */
+# define EVP_PKEY_ECDH_KDF_NONE                          1
+# define EVP_PKEY_ECDH_KDF_X9_62                         2
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_EC_strings(void);
+
+/* Error codes for the EC functions. */
+
+/* Function codes. */
+# define EC_F_BN_TO_FELEM                                 224
+# define EC_F_D2I_ECPARAMETERS                            144
+# define EC_F_D2I_ECPKPARAMETERS                          145
+# define EC_F_D2I_ECPRIVATEKEY                            146
+# define EC_F_DO_EC_KEY_PRINT                             221
+# define EC_F_ECDH_CMS_DECRYPT                            238
+# define EC_F_ECDH_CMS_SET_SHARED_INFO                    239
+# define EC_F_ECDH_COMPUTE_KEY                            246
+# define EC_F_ECDH_SIMPLE_COMPUTE_KEY                     257
+# define EC_F_ECDSA_DO_SIGN_EX                            251
+# define EC_F_ECDSA_DO_VERIFY                             252
+# define EC_F_ECDSA_SIGN_EX                               254
+# define EC_F_ECDSA_SIGN_SETUP                            248
+# define EC_F_ECDSA_SIG_NEW                               265
+# define EC_F_ECDSA_VERIFY                                253
+# define EC_F_ECKEY_PARAM2TYPE                            223
+# define EC_F_ECKEY_PARAM_DECODE                          212
+# define EC_F_ECKEY_PRIV_DECODE                           213
+# define EC_F_ECKEY_PRIV_ENCODE                           214
+# define EC_F_ECKEY_PUB_DECODE                            215
+# define EC_F_ECKEY_PUB_ENCODE                            216
+# define EC_F_ECKEY_TYPE2PARAM                            220
+# define EC_F_ECPARAMETERS_PRINT                          147
+# define EC_F_ECPARAMETERS_PRINT_FP                       148
+# define EC_F_ECPKPARAMETERS_PRINT                        149
+# define EC_F_ECPKPARAMETERS_PRINT_FP                     150
+# define EC_F_ECP_NISTZ256_GET_AFFINE                     240
+# define EC_F_ECP_NISTZ256_MULT_PRECOMPUTE                243
+# define EC_F_ECP_NISTZ256_POINTS_MUL                     241
+# define EC_F_ECP_NISTZ256_PRE_COMP_NEW                   244
+# define EC_F_ECP_NISTZ256_WINDOWED_MUL                   242
+# define EC_F_ECX_KEY_OP                                  266
+# define EC_F_ECX_PRIV_ENCODE                             267
+# define EC_F_ECX_PUB_ENCODE                              268
+# define EC_F_EC_ASN1_GROUP2CURVE                         153
+# define EC_F_EC_ASN1_GROUP2FIELDID                       154
+# define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY           208
+# define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT     159
+# define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE              195
+# define EC_F_EC_GF2M_SIMPLE_OCT2POINT                    160
+# define EC_F_EC_GF2M_SIMPLE_POINT2OCT                    161
+# define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162
+# define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163
+# define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES   164
+# define EC_F_EC_GFP_MONT_FIELD_DECODE                    133
+# define EC_F_EC_GFP_MONT_FIELD_ENCODE                    134
+# define EC_F_EC_GFP_MONT_FIELD_MUL                       131
+# define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE                209
+# define EC_F_EC_GFP_MONT_FIELD_SQR                       132
+# define EC_F_EC_GFP_MONT_GROUP_SET_CURVE                 189
+# define EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE             225
+# define EC_F_EC_GFP_NISTP224_POINTS_MUL                  228
+# define EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES 226
+# define EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE             230
+# define EC_F_EC_GFP_NISTP256_POINTS_MUL                  231
+# define EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES 232
+# define EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE             233
+# define EC_F_EC_GFP_NISTP521_POINTS_MUL                  234
+# define EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES 235
+# define EC_F_EC_GFP_NIST_FIELD_MUL                       200
+# define EC_F_EC_GFP_NIST_FIELD_SQR                       201
+# define EC_F_EC_GFP_NIST_GROUP_SET_CURVE                 202
+# define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT      165
+# define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE               166
+# define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE                   102
+# define EC_F_EC_GFP_SIMPLE_OCT2POINT                     103
+# define EC_F_EC_GFP_SIMPLE_POINT2OCT                     104
+# define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE            137
+# define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES  167
+# define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES  168
+# define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES    169
+# define EC_F_EC_GROUP_CHECK                              170
+# define EC_F_EC_GROUP_CHECK_DISCRIMINANT                 171
+# define EC_F_EC_GROUP_COPY                               106
+# define EC_F_EC_GROUP_GET_CURVE_GF2M                     172
+# define EC_F_EC_GROUP_GET_CURVE_GFP                      130
+# define EC_F_EC_GROUP_GET_DEGREE                         173
+# define EC_F_EC_GROUP_GET_ECPARAMETERS                   261
+# define EC_F_EC_GROUP_GET_ECPKPARAMETERS                 262
+# define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS              193
+# define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS                194
+# define EC_F_EC_GROUP_NEW                                108
+# define EC_F_EC_GROUP_NEW_BY_CURVE_NAME                  174
+# define EC_F_EC_GROUP_NEW_FROM_DATA                      175
+# define EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS              263
+# define EC_F_EC_GROUP_NEW_FROM_ECPKPARAMETERS            264
+# define EC_F_EC_GROUP_SET_CURVE_GF2M                     176
+# define EC_F_EC_GROUP_SET_CURVE_GFP                      109
+# define EC_F_EC_GROUP_SET_GENERATOR                      111
+# define EC_F_EC_KEY_CHECK_KEY                            177
+# define EC_F_EC_KEY_COPY                                 178
+# define EC_F_EC_KEY_GENERATE_KEY                         179
+# define EC_F_EC_KEY_NEW                                  182
+# define EC_F_EC_KEY_NEW_METHOD                           245
+# define EC_F_EC_KEY_OCT2PRIV                             255
+# define EC_F_EC_KEY_PRINT                                180
+# define EC_F_EC_KEY_PRINT_FP                             181
+# define EC_F_EC_KEY_PRIV2OCT                             256
+# define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES    229
+# define EC_F_EC_KEY_SIMPLE_CHECK_KEY                     258
+# define EC_F_EC_KEY_SIMPLE_OCT2PRIV                      259
+# define EC_F_EC_KEY_SIMPLE_PRIV2OCT                      260
+# define EC_F_EC_POINTS_MAKE_AFFINE                       136
+# define EC_F_EC_POINT_ADD                                112
+# define EC_F_EC_POINT_CMP                                113
+# define EC_F_EC_POINT_COPY                               114
+# define EC_F_EC_POINT_DBL                                115
+# define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M        183
+# define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP         116
+# define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP    117
+# define EC_F_EC_POINT_INVERT                             210
+# define EC_F_EC_POINT_IS_AT_INFINITY                     118
+# define EC_F_EC_POINT_IS_ON_CURVE                        119
+# define EC_F_EC_POINT_MAKE_AFFINE                        120
+# define EC_F_EC_POINT_NEW                                121
+# define EC_F_EC_POINT_OCT2POINT                          122
+# define EC_F_EC_POINT_POINT2OCT                          123
+# define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M        185
+# define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP         124
+# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M    186
+# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP     125
+# define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP    126
+# define EC_F_EC_POINT_SET_TO_INFINITY                    127
+# define EC_F_EC_PRE_COMP_NEW                             196
+# define EC_F_EC_WNAF_MUL                                 187
+# define EC_F_EC_WNAF_PRECOMPUTE_MULT                     188
+# define EC_F_I2D_ECPARAMETERS                            190
+# define EC_F_I2D_ECPKPARAMETERS                          191
+# define EC_F_I2D_ECPRIVATEKEY                            192
+# define EC_F_I2O_ECPUBLICKEY                             151
+# define EC_F_NISTP224_PRE_COMP_NEW                       227
+# define EC_F_NISTP256_PRE_COMP_NEW                       236
+# define EC_F_NISTP521_PRE_COMP_NEW                       237
+# define EC_F_O2I_ECPUBLICKEY                             152
+# define EC_F_OLD_EC_PRIV_DECODE                          222
+# define EC_F_OSSL_ECDH_COMPUTE_KEY                       247
+# define EC_F_OSSL_ECDSA_SIGN_SIG                         249
+# define EC_F_OSSL_ECDSA_VERIFY_SIG                       250
+# define EC_F_PKEY_ECX_DERIVE                             269
+# define EC_F_PKEY_EC_CTRL                                197
+# define EC_F_PKEY_EC_CTRL_STR                            198
+# define EC_F_PKEY_EC_DERIVE                              217
+# define EC_F_PKEY_EC_KEYGEN                              199
+# define EC_F_PKEY_EC_PARAMGEN                            219
+# define EC_F_PKEY_EC_SIGN                                218
+
+/* Reason codes. */
+# define EC_R_ASN1_ERROR                                  115
+# define EC_R_BAD_SIGNATURE                               156
+# define EC_R_BIGNUM_OUT_OF_RANGE                         144
+# define EC_R_BUFFER_TOO_SMALL                            100
+# define EC_R_COORDINATES_OUT_OF_RANGE                    146
+# define EC_R_CURVE_DOES_NOT_SUPPORT_ECDH                 160
+# define EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING              159
+# define EC_R_D2I_ECPKPARAMETERS_FAILURE                  117
+# define EC_R_DECODE_ERROR                                142
+# define EC_R_DISCRIMINANT_IS_ZERO                        118
+# define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE                119
+# define EC_R_FIELD_TOO_LARGE                             143
+# define EC_R_GF2M_NOT_SUPPORTED                          147
+# define EC_R_GROUP2PKPARAMETERS_FAILURE                  120
+# define EC_R_I2D_ECPKPARAMETERS_FAILURE                  121
+# define EC_R_INCOMPATIBLE_OBJECTS                        101
+# define EC_R_INVALID_ARGUMENT                            112
+# define EC_R_INVALID_COMPRESSED_POINT                    110
+# define EC_R_INVALID_COMPRESSION_BIT                     109
+# define EC_R_INVALID_CURVE                               141
+# define EC_R_INVALID_DIGEST                              151
+# define EC_R_INVALID_DIGEST_TYPE                         138
+# define EC_R_INVALID_ENCODING                            102
+# define EC_R_INVALID_FIELD                               103
+# define EC_R_INVALID_FORM                                104
+# define EC_R_INVALID_GROUP_ORDER                         122
+# define EC_R_INVALID_KEY                                 116
+# define EC_R_INVALID_OUTPUT_LENGTH                       161
+# define EC_R_INVALID_PEER_KEY                            133
+# define EC_R_INVALID_PENTANOMIAL_BASIS                   132
+# define EC_R_INVALID_PRIVATE_KEY                         123
+# define EC_R_INVALID_TRINOMIAL_BASIS                     137
+# define EC_R_KDF_PARAMETER_ERROR                         148
+# define EC_R_KEYS_NOT_SET                                140
+# define EC_R_MISSING_PARAMETERS                          124
+# define EC_R_MISSING_PRIVATE_KEY                         125
+# define EC_R_NEED_NEW_SETUP_VALUES                       157
+# define EC_R_NOT_A_NIST_PRIME                            135
+# define EC_R_NOT_IMPLEMENTED                             126
+# define EC_R_NOT_INITIALIZED                             111
+# define EC_R_NO_PARAMETERS_SET                           139
+# define EC_R_NO_PRIVATE_VALUE                            154
+# define EC_R_OPERATION_NOT_SUPPORTED                     152
+# define EC_R_PASSED_NULL_PARAMETER                       134
+# define EC_R_PEER_KEY_ERROR                              149
+# define EC_R_PKPARAMETERS2GROUP_FAILURE                  127
+# define EC_R_POINT_ARITHMETIC_FAILURE                    155
+# define EC_R_POINT_AT_INFINITY                           106
+# define EC_R_POINT_IS_NOT_ON_CURVE                       107
+# define EC_R_RANDOM_NUMBER_GENERATION_FAILED             158
+# define EC_R_SHARED_INFO_ERROR                           150
+# define EC_R_SLOT_FULL                                   108
+# define EC_R_UNDEFINED_GENERATOR                         113
+# define EC_R_UNDEFINED_ORDER                             128
+# define EC_R_UNKNOWN_GROUP                               129
+# define EC_R_UNKNOWN_ORDER                               114
+# define EC_R_UNSUPPORTED_FIELD                           131
+# define EC_R_WRONG_CURVE_PARAMETERS                      145
+# define EC_R_WRONG_ORDER                                 130
+
+#  ifdef  __cplusplus
+}
+#  endif
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ecdh.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ecdh.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ecdh.h	(revision 331)
@@ -0,0 +1,10 @@
+/*
+ * Copyright 2002-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 <openssl/ec.h>
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ecdsa.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ecdsa.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ecdsa.h	(revision 331)
@@ -0,0 +1,10 @@
+/*
+ * Copyright 2002-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 <openssl/ec.h>
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/engine.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/engine.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/engine.h	(revision 331)
@@ -0,0 +1,840 @@
+/*
+ * Copyright 2000-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_ENGINE_H
+# define HEADER_ENGINE_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_ENGINE
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  include <openssl/bn.h>
+#  include <openssl/rsa.h>
+#  include <openssl/dsa.h>
+#  include <openssl/dh.h>
+#  include <openssl/ec.h>
+#  include <openssl/rand.h>
+#  include <openssl/ui.h>
+#  include <openssl/err.h>
+# endif
+# include <openssl/ossl_typ.h>
+# include <openssl/symhacks.h>
+# include <openssl/x509.h>
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+/*
+ * These flags are used to control combinations of algorithm (methods) by
+ * bitwise "OR"ing.
+ */
+# define ENGINE_METHOD_RSA               (unsigned int)0x0001
+# define ENGINE_METHOD_DSA               (unsigned int)0x0002
+# define ENGINE_METHOD_DH                (unsigned int)0x0004
+# define ENGINE_METHOD_RAND              (unsigned int)0x0008
+# define ENGINE_METHOD_CIPHERS           (unsigned int)0x0040
+# define ENGINE_METHOD_DIGESTS           (unsigned int)0x0080
+# define ENGINE_METHOD_PKEY_METHS        (unsigned int)0x0200
+# define ENGINE_METHOD_PKEY_ASN1_METHS   (unsigned int)0x0400
+# define ENGINE_METHOD_EC                (unsigned int)0x0800
+/* Obvious all-or-nothing cases. */
+# define ENGINE_METHOD_ALL               (unsigned int)0xFFFF
+# define ENGINE_METHOD_NONE              (unsigned int)0x0000
+
+/*
+ * This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used
+ * internally to control registration of ENGINE implementations, and can be
+ * set by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to
+ * initialise registered ENGINEs if they are not already initialised.
+ */
+# define ENGINE_TABLE_FLAG_NOINIT        (unsigned int)0x0001
+
+/* ENGINE flags that can be set by ENGINE_set_flags(). */
+/* Not used */
+/* #define ENGINE_FLAGS_MALLOCED        0x0001 */
+
+/*
+ * This flag is for ENGINEs that wish to handle the various 'CMD'-related
+ * control commands on their own. Without this flag, ENGINE_ctrl() handles
+ * these control commands on behalf of the ENGINE using their "cmd_defns"
+ * data.
+ */
+# define ENGINE_FLAGS_MANUAL_CMD_CTRL    (int)0x0002
+
+/*
+ * This flag is for ENGINEs who return new duplicate structures when found
+ * via "ENGINE_by_id()". When an ENGINE must store state (eg. if
+ * ENGINE_ctrl() commands are called in sequence as part of some stateful
+ * process like key-generation setup and execution), it can set this flag -
+ * then each attempt to obtain the ENGINE will result in it being copied into
+ * a new structure. Normally, ENGINEs don't declare this flag so
+ * ENGINE_by_id() just increments the existing ENGINE's structural reference
+ * count.
+ */
+# define ENGINE_FLAGS_BY_ID_COPY         (int)0x0004
+
+/*
+ * This flag if for an ENGINE that does not want its methods registered as
+ * part of ENGINE_register_all_complete() for example if the methods are not
+ * usable as default methods.
+ */
+
+# define ENGINE_FLAGS_NO_REGISTER_ALL    (int)0x0008
+
+/*
+ * ENGINEs can support their own command types, and these flags are used in
+ * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input
+ * each command expects. Currently only numeric and string input is
+ * supported. If a control command supports none of the _NUMERIC, _STRING, or
+ * _NO_INPUT options, then it is regarded as an "internal" control command -
+ * and not for use in config setting situations. As such, they're not
+ * available to the ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl()
+ * access. Changes to this list of 'command types' should be reflected
+ * carefully in ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string().
+ */
+
+/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */
+# define ENGINE_CMD_FLAG_NUMERIC         (unsigned int)0x0001
+/*
+ * accepts string input (cast from 'void*' to 'const char *', 4th parameter
+ * to ENGINE_ctrl)
+ */
+# define ENGINE_CMD_FLAG_STRING          (unsigned int)0x0002
+/*
+ * Indicates that the control command takes *no* input. Ie. the control
+ * command is unparameterised.
+ */
+# define ENGINE_CMD_FLAG_NO_INPUT        (unsigned int)0x0004
+/*
+ * Indicates that the control command is internal. This control command won't
+ * be shown in any output, and is only usable through the ENGINE_ctrl_cmd()
+ * function.
+ */
+# define ENGINE_CMD_FLAG_INTERNAL        (unsigned int)0x0008
+
+/*
+ * NB: These 3 control commands are deprecated and should not be used.
+ * ENGINEs relying on these commands should compile conditional support for
+ * compatibility (eg. if these symbols are defined) but should also migrate
+ * the same functionality to their own ENGINE-specific control functions that
+ * can be "discovered" by calling applications. The fact these control
+ * commands wouldn't be "executable" (ie. usable by text-based config)
+ * doesn't change the fact that application code can find and use them
+ * without requiring per-ENGINE hacking.
+ */
+
+/*
+ * These flags are used to tell the ctrl function what should be done. All
+ * command numbers are shared between all engines, even if some don't make
+ * sense to some engines.  In such a case, they do nothing but return the
+ * error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED.
+ */
+# define ENGINE_CTRL_SET_LOGSTREAM               1
+# define ENGINE_CTRL_SET_PASSWORD_CALLBACK       2
+# define ENGINE_CTRL_HUP                         3/* Close and reinitialise
+                                                   * any handles/connections
+                                                   * etc. */
+# define ENGINE_CTRL_SET_USER_INTERFACE          4/* Alternative to callback */
+# define ENGINE_CTRL_SET_CALLBACK_DATA           5/* User-specific data, used
+                                                   * when calling the password
+                                                   * callback and the user
+                                                   * interface */
+# define ENGINE_CTRL_LOAD_CONFIGURATION          6/* Load a configuration,
+                                                   * given a string that
+                                                   * represents a file name
+                                                   * or so */
+# define ENGINE_CTRL_LOAD_SECTION                7/* Load data from a given
+                                                   * section in the already
+                                                   * loaded configuration */
+
+/*
+ * These control commands allow an application to deal with an arbitrary
+ * engine in a dynamic way. Warn: Negative return values indicate errors FOR
+ * THESE COMMANDS because zero is used to indicate 'end-of-list'. Other
+ * commands, including ENGINE-specific command types, return zero for an
+ * error. An ENGINE can choose to implement these ctrl functions, and can
+ * internally manage things however it chooses - it does so by setting the
+ * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise
+ * the ENGINE_ctrl() code handles this on the ENGINE's behalf using the
+ * cmd_defns data (set using ENGINE_set_cmd_defns()). This means an ENGINE's
+ * ctrl() handler need only implement its own commands - the above "meta"
+ * commands will be taken care of.
+ */
+
+/*
+ * Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not",
+ * then all the remaining control commands will return failure, so it is
+ * worth checking this first if the caller is trying to "discover" the
+ * engine's capabilities and doesn't want errors generated unnecessarily.
+ */
+# define ENGINE_CTRL_HAS_CTRL_FUNCTION           10
+/*
+ * Returns a positive command number for the first command supported by the
+ * engine. Returns zero if no ctrl commands are supported.
+ */
+# define ENGINE_CTRL_GET_FIRST_CMD_TYPE          11
+/*
+ * The 'long' argument specifies a command implemented by the engine, and the
+ * return value is the next command supported, or zero if there are no more.
+ */
+# define ENGINE_CTRL_GET_NEXT_CMD_TYPE           12
+/*
+ * The 'void*' argument is a command name (cast from 'const char *'), and the
+ * return value is the command that corresponds to it.
+ */
+# define ENGINE_CTRL_GET_CMD_FROM_NAME           13
+/*
+ * The next two allow a command to be converted into its corresponding string
+ * form. In each case, the 'long' argument supplies the command. In the
+ * NAME_LEN case, the return value is the length of the command name (not
+ * counting a trailing EOL). In the NAME case, the 'void*' argument must be a
+ * string buffer large enough, and it will be populated with the name of the
+ * command (WITH a trailing EOL).
+ */
+# define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD       14
+# define ENGINE_CTRL_GET_NAME_FROM_CMD           15
+/* The next two are similar but give a "short description" of a command. */
+# define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD       16
+# define ENGINE_CTRL_GET_DESC_FROM_CMD           17
+/*
+ * With this command, the return value is the OR'd combination of
+ * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given
+ * engine-specific ctrl command expects.
+ */
+# define ENGINE_CTRL_GET_CMD_FLAGS               18
+
+/*
+ * ENGINE implementations should start the numbering of their own control
+ * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc).
+ */
+# define ENGINE_CMD_BASE                         200
+
+/*
+ * NB: These 2 nCipher "chil" control commands are deprecated, and their
+ * functionality is now available through ENGINE-specific control commands
+ * (exposed through the above-mentioned 'CMD'-handling). Code using these 2
+ * commands should be migrated to the more general command handling before
+ * these are removed.
+ */
+
+/* Flags specific to the nCipher "chil" engine */
+# define ENGINE_CTRL_CHIL_SET_FORKCHECK          100
+        /*
+         * Depending on the value of the (long)i argument, this sets or
+         * unsets the SimpleForkCheck flag in the CHIL API to enable or
+         * disable checking and workarounds for applications that fork().
+         */
+# define ENGINE_CTRL_CHIL_NO_LOCKING             101
+        /*
+         * This prevents the initialisation function from providing mutex
+         * callbacks to the nCipher library.
+         */
+
+/*
+ * If an ENGINE supports its own specific control commands and wishes the
+ * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on
+ * its behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN
+ * entries to ENGINE_set_cmd_defns(). It should also implement a ctrl()
+ * handler that supports the stated commands (ie. the "cmd_num" entries as
+ * described by the array). NB: The array must be ordered in increasing order
+ * of cmd_num. "null-terminated" means that the last ENGINE_CMD_DEFN element
+ * has cmd_num set to zero and/or cmd_name set to NULL.
+ */
+typedef struct ENGINE_CMD_DEFN_st {
+    unsigned int cmd_num;       /* The command number */
+    const char *cmd_name;       /* The command name itself */
+    const char *cmd_desc;       /* A short description of the command */
+    unsigned int cmd_flags;     /* The input the command expects */
+} ENGINE_CMD_DEFN;
+
+/* Generic function pointer */
+typedef int (*ENGINE_GEN_FUNC_PTR) (void);
+/* Generic function pointer taking no arguments */
+typedef int (*ENGINE_GEN_INT_FUNC_PTR) (ENGINE *);
+/* Specific control function pointer */
+typedef int (*ENGINE_CTRL_FUNC_PTR) (ENGINE *, int, long, void *,
+                                     void (*f) (void));
+/* Generic load_key function pointer */
+typedef EVP_PKEY *(*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
+                                         UI_METHOD *ui_method,
+                                         void *callback_data);
+typedef int (*ENGINE_SSL_CLIENT_CERT_PTR) (ENGINE *, SSL *ssl,
+                                           STACK_OF(X509_NAME) *ca_dn,
+                                           X509 **pcert, EVP_PKEY **pkey,
+                                           STACK_OF(X509) **pother,
+                                           UI_METHOD *ui_method,
+                                           void *callback_data);
+/*-
+ * These callback types are for an ENGINE's handler for cipher and digest logic.
+ * These handlers have these prototypes;
+ *   int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
+ *   int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid);
+ * Looking at how to implement these handlers in the case of cipher support, if
+ * the framework wants the EVP_CIPHER for 'nid', it will call;
+ *   foo(e, &p_evp_cipher, NULL, nid);    (return zero for failure)
+ * If the framework wants a list of supported 'nid's, it will call;
+ *   foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error)
+ */
+/*
+ * Returns to a pointer to the array of supported cipher 'nid's. If the
+ * second parameter is non-NULL it is set to the size of the returned array.
+ */
+typedef int (*ENGINE_CIPHERS_PTR) (ENGINE *, const EVP_CIPHER **,
+                                   const int **, int);
+typedef int (*ENGINE_DIGESTS_PTR) (ENGINE *, const EVP_MD **, const int **,
+                                   int);
+typedef int (*ENGINE_PKEY_METHS_PTR) (ENGINE *, EVP_PKEY_METHOD **,
+                                      const int **, int);
+typedef int (*ENGINE_PKEY_ASN1_METHS_PTR) (ENGINE *, EVP_PKEY_ASN1_METHOD **,
+                                           const int **, int);
+/*
+ * STRUCTURE functions ... all of these functions deal with pointers to
+ * ENGINE structures where the pointers have a "structural reference". This
+ * means that their reference is to allowed access to the structure but it
+ * does not imply that the structure is functional. To simply increment or
+ * decrement the structural reference count, use ENGINE_by_id and
+ * ENGINE_free. NB: This is not required when iterating using ENGINE_get_next
+ * as it will automatically decrement the structural reference count of the
+ * "current" ENGINE and increment the structural reference count of the
+ * ENGINE it returns (unless it is NULL).
+ */
+
+/* Get the first/last "ENGINE" type available. */
+ENGINE *ENGINE_get_first(void);
+ENGINE *ENGINE_get_last(void);
+/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
+ENGINE *ENGINE_get_next(ENGINE *e);
+ENGINE *ENGINE_get_prev(ENGINE *e);
+/* Add another "ENGINE" type into the array. */
+int ENGINE_add(ENGINE *e);
+/* Remove an existing "ENGINE" type from the array. */
+int ENGINE_remove(ENGINE *e);
+/* Retrieve an engine from the list by its unique "id" value. */
+ENGINE *ENGINE_by_id(const char *id);
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+# define ENGINE_load_openssl() \
+    OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_OPENSSL, NULL)
+# define ENGINE_load_dynamic() \
+    OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_DYNAMIC, NULL)
+# ifndef OPENSSL_NO_STATIC_ENGINE
+#  define ENGINE_load_padlock() \
+    OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_PADLOCK, NULL)
+#  define ENGINE_load_capi() \
+    OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_CAPI, NULL)
+#  define ENGINE_load_afalg() \
+    OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_AFALG, NULL)
+# endif
+# define ENGINE_load_cryptodev() \
+    OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_CRYPTODEV, NULL)
+# define ENGINE_load_rdrand() \
+    OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_RDRAND, NULL)
+#endif
+void ENGINE_load_builtin_engines(void);
+
+/*
+ * Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
+ * "registry" handling.
+ */
+unsigned int ENGINE_get_table_flags(void);
+void ENGINE_set_table_flags(unsigned int flags);
+
+/*- Manage registration of ENGINEs per "table". For each type, there are 3
+ * functions;
+ *   ENGINE_register_***(e) - registers the implementation from 'e' (if it has one)
+ *   ENGINE_unregister_***(e) - unregister the implementation from 'e'
+ *   ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list
+ * Cleanup is automatically registered from each table when required.
+ */
+
+int ENGINE_register_RSA(ENGINE *e);
+void ENGINE_unregister_RSA(ENGINE *e);
+void ENGINE_register_all_RSA(void);
+
+int ENGINE_register_DSA(ENGINE *e);
+void ENGINE_unregister_DSA(ENGINE *e);
+void ENGINE_register_all_DSA(void);
+
+int ENGINE_register_EC(ENGINE *e);
+void ENGINE_unregister_EC(ENGINE *e);
+void ENGINE_register_all_EC(void);
+
+int ENGINE_register_DH(ENGINE *e);
+void ENGINE_unregister_DH(ENGINE *e);
+void ENGINE_register_all_DH(void);
+
+int ENGINE_register_RAND(ENGINE *e);
+void ENGINE_unregister_RAND(ENGINE *e);
+void ENGINE_register_all_RAND(void);
+
+int ENGINE_register_ciphers(ENGINE *e);
+void ENGINE_unregister_ciphers(ENGINE *e);
+void ENGINE_register_all_ciphers(void);
+
+int ENGINE_register_digests(ENGINE *e);
+void ENGINE_unregister_digests(ENGINE *e);
+void ENGINE_register_all_digests(void);
+
+int ENGINE_register_pkey_meths(ENGINE *e);
+void ENGINE_unregister_pkey_meths(ENGINE *e);
+void ENGINE_register_all_pkey_meths(void);
+
+int ENGINE_register_pkey_asn1_meths(ENGINE *e);
+void ENGINE_unregister_pkey_asn1_meths(ENGINE *e);
+void ENGINE_register_all_pkey_asn1_meths(void);
+
+/*
+ * These functions register all support from the above categories. Note, use
+ * of these functions can result in static linkage of code your application
+ * may not need. If you only need a subset of functionality, consider using
+ * more selective initialisation.
+ */
+int ENGINE_register_complete(ENGINE *e);
+int ENGINE_register_all_complete(void);
+
+/*
+ * Send parametrised control commands to the engine. The possibilities to
+ * send down an integer, a pointer to data or a function pointer are
+ * provided. Any of the parameters may or may not be NULL, depending on the
+ * command number. In actuality, this function only requires a structural
+ * (rather than functional) reference to an engine, but many control commands
+ * may require the engine be functional. The caller should be aware of trying
+ * commands that require an operational ENGINE, and only use functional
+ * references in such situations.
+ */
+int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void));
+
+/*
+ * This function tests if an ENGINE-specific command is usable as a
+ * "setting". Eg. in an application's config file that gets processed through
+ * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to
+ * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl().
+ */
+int ENGINE_cmd_is_executable(ENGINE *e, int cmd);
+
+/*
+ * This function works like ENGINE_ctrl() with the exception of taking a
+ * command name instead of a command number, and can handle optional
+ * commands. See the comment on ENGINE_ctrl_cmd_string() for an explanation
+ * on how to use the cmd_name and cmd_optional.
+ */
+int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
+                    long i, void *p, void (*f) (void), int cmd_optional);
+
+/*
+ * This function passes a command-name and argument to an ENGINE. The
+ * cmd_name is converted to a command number and the control command is
+ * called using 'arg' as an argument (unless the ENGINE doesn't support such
+ * a command, in which case no control command is called). The command is
+ * checked for input flags, and if necessary the argument will be converted
+ * to a numeric value. If cmd_optional is non-zero, then if the ENGINE
+ * doesn't support the given cmd_name the return value will be success
+ * anyway. This function is intended for applications to use so that users
+ * (or config files) can supply engine-specific config data to the ENGINE at
+ * run-time to control behaviour of specific engines. As such, it shouldn't
+ * be used for calling ENGINE_ctrl() functions that return data, deal with
+ * binary data, or that are otherwise supposed to be used directly through
+ * ENGINE_ctrl() in application code. Any "return" data from an ENGINE_ctrl()
+ * operation in this function will be lost - the return value is interpreted
+ * as failure if the return value is zero, success otherwise, and this
+ * function returns a boolean value as a result. In other words, vendors of
+ * 'ENGINE'-enabled devices should write ENGINE implementations with
+ * parameterisations that work in this scheme, so that compliant ENGINE-based
+ * applications can work consistently with the same configuration for the
+ * same ENGINE-enabled devices, across applications.
+ */
+int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
+                           int cmd_optional);
+
+/*
+ * These functions are useful for manufacturing new ENGINE structures. They
+ * don't address reference counting at all - one uses them to populate an
+ * ENGINE structure with personalised implementations of things prior to
+ * using it directly or adding it to the builtin ENGINE list in OpenSSL.
+ * These are also here so that the ENGINE structure doesn't have to be
+ * exposed and break binary compatibility!
+ */
+ENGINE *ENGINE_new(void);
+int ENGINE_free(ENGINE *e);
+int ENGINE_up_ref(ENGINE *e);
+int ENGINE_set_id(ENGINE *e, const char *id);
+int ENGINE_set_name(ENGINE *e, const char *name);
+int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);
+int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
+int ENGINE_set_EC(ENGINE *e, const EC_KEY_METHOD *ecdsa_meth);
+int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);
+int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);
+int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f);
+int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);
+int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);
+int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);
+int ENGINE_set_load_privkey_function(ENGINE *e,
+                                     ENGINE_LOAD_KEY_PTR loadpriv_f);
+int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
+int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
+                                             ENGINE_SSL_CLIENT_CERT_PTR
+                                             loadssl_f);
+int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
+int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
+int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f);
+int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f);
+int ENGINE_set_flags(ENGINE *e, int flags);
+int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
+/* These functions allow control over any per-structure ENGINE data. */
+#define ENGINE_get_ex_new_index(l, p, newf, dupf, freef) \
+    CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ENGINE, l, p, newf, dupf, freef)
+int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg);
+void *ENGINE_get_ex_data(const ENGINE *e, int idx);
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+/*
+ * This function previously cleaned up anything that needs it. Auto-deinit will
+ * now take care of it so it is no longer required to call this function.
+ */
+# define ENGINE_cleanup() while(0) continue
+#endif
+
+/*
+ * These return values from within the ENGINE structure. These can be useful
+ * with functional references as well as structural references - it depends
+ * which you obtained. Using the result for functional purposes if you only
+ * obtained a structural reference may be problematic!
+ */
+const char *ENGINE_get_id(const ENGINE *e);
+const char *ENGINE_get_name(const ENGINE *e);
+const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e);
+const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e);
+const EC_KEY_METHOD *ENGINE_get_EC(const ENGINE *e);
+const DH_METHOD *ENGINE_get_DH(const ENGINE *e);
+const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e);
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e);
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e);
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e);
+ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
+ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
+ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
+ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE
+                                                               *e);
+ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
+ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
+ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e);
+ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e);
+const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
+const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
+const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid);
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid);
+const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
+                                                          const char *str,
+                                                          int len);
+const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
+                                                      const char *str,
+                                                      int len);
+const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
+int ENGINE_get_flags(const ENGINE *e);
+
+/*
+ * FUNCTIONAL functions. These functions deal with ENGINE structures that
+ * have (or will) be initialised for use. Broadly speaking, the structural
+ * functions are useful for iterating the list of available engine types,
+ * creating new engine types, and other "list" operations. These functions
+ * actually deal with ENGINEs that are to be used. As such these functions
+ * can fail (if applicable) when particular engines are unavailable - eg. if
+ * a hardware accelerator is not attached or not functioning correctly. Each
+ * ENGINE has 2 reference counts; structural and functional. Every time a
+ * functional reference is obtained or released, a corresponding structural
+ * reference is automatically obtained or released too.
+ */
+
+/*
+ * Initialise a engine type for use (or up its reference count if it's
+ * already in use). This will fail if the engine is not currently operational
+ * and cannot initialise.
+ */
+int ENGINE_init(ENGINE *e);
+/*
+ * Free a functional reference to a engine type. This does not require a
+ * corresponding call to ENGINE_free as it also releases a structural
+ * reference.
+ */
+int ENGINE_finish(ENGINE *e);
+
+/*
+ * The following functions handle keys that are stored in some secondary
+ * location, handled by the engine.  The storage may be on a card or
+ * whatever.
+ */
+EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
+                                  UI_METHOD *ui_method, void *callback_data);
+EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
+                                 UI_METHOD *ui_method, void *callback_data);
+int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
+                                STACK_OF(X509_NAME) *ca_dn, X509 **pcert,
+                                EVP_PKEY **ppkey, STACK_OF(X509) **pother,
+                                UI_METHOD *ui_method, void *callback_data);
+
+/*
+ * This returns a pointer for the current ENGINE structure that is (by
+ * default) performing any RSA operations. The value returned is an
+ * incremented reference, so it should be free'd (ENGINE_finish) before it is
+ * discarded.
+ */
+ENGINE *ENGINE_get_default_RSA(void);
+/* Same for the other "methods" */
+ENGINE *ENGINE_get_default_DSA(void);
+ENGINE *ENGINE_get_default_EC(void);
+ENGINE *ENGINE_get_default_DH(void);
+ENGINE *ENGINE_get_default_RAND(void);
+/*
+ * These functions can be used to get a functional reference to perform
+ * ciphering or digesting corresponding to "nid".
+ */
+ENGINE *ENGINE_get_cipher_engine(int nid);
+ENGINE *ENGINE_get_digest_engine(int nid);
+ENGINE *ENGINE_get_pkey_meth_engine(int nid);
+ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid);
+
+/*
+ * This sets a new default ENGINE structure for performing RSA operations. If
+ * the result is non-zero (success) then the ENGINE structure will have had
+ * its reference count up'd so the caller should still free their own
+ * reference 'e'.
+ */
+int ENGINE_set_default_RSA(ENGINE *e);
+int ENGINE_set_default_string(ENGINE *e, const char *def_list);
+/* Same for the other "methods" */
+int ENGINE_set_default_DSA(ENGINE *e);
+int ENGINE_set_default_EC(ENGINE *e);
+int ENGINE_set_default_DH(ENGINE *e);
+int ENGINE_set_default_RAND(ENGINE *e);
+int ENGINE_set_default_ciphers(ENGINE *e);
+int ENGINE_set_default_digests(ENGINE *e);
+int ENGINE_set_default_pkey_meths(ENGINE *e);
+int ENGINE_set_default_pkey_asn1_meths(ENGINE *e);
+
+/*
+ * The combination "set" - the flags are bitwise "OR"d from the
+ * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
+ * function, this function can result in unnecessary static linkage. If your
+ * application requires only specific functionality, consider using more
+ * selective functions.
+ */
+int ENGINE_set_default(ENGINE *e, unsigned int flags);
+
+void ENGINE_add_conf_module(void);
+
+/* Deprecated functions ... */
+/* int ENGINE_clear_defaults(void); */
+
+/**************************/
+/* DYNAMIC ENGINE SUPPORT */
+/**************************/
+
+/* Binary/behaviour compatibility levels */
+# define OSSL_DYNAMIC_VERSION            (unsigned long)0x00030000
+/*
+ * Binary versions older than this are too old for us (whether we're a loader
+ * or a loadee)
+ */
+# define OSSL_DYNAMIC_OLDEST             (unsigned long)0x00030000
+
+/*
+ * When compiling an ENGINE entirely as an external shared library, loadable
+ * by the "dynamic" ENGINE, these types are needed. The 'dynamic_fns'
+ * structure type provides the calling application's (or library's) error
+ * functionality and memory management function pointers to the loaded
+ * library. These should be used/set in the loaded library code so that the
+ * loading application's 'state' will be used/changed in all operations. The
+ * 'static_state' pointer allows the loaded library to know if it shares the
+ * same static data as the calling application (or library), and thus whether
+ * these callbacks need to be set or not.
+ */
+typedef void *(*dyn_MEM_malloc_fn) (size_t, const char *, int);
+typedef void *(*dyn_MEM_realloc_fn) (void *, size_t, const char *, int);
+typedef void (*dyn_MEM_free_fn) (void *, const char *, int);
+typedef struct st_dynamic_MEM_fns {
+    dyn_MEM_malloc_fn malloc_fn;
+    dyn_MEM_realloc_fn realloc_fn;
+    dyn_MEM_free_fn free_fn;
+} dynamic_MEM_fns;
+/*
+ * FIXME: Perhaps the memory and locking code (crypto.h) should declare and
+ * use these types so we (and any other dependent code) can simplify a bit??
+ */
+/* The top-level structure */
+typedef struct st_dynamic_fns {
+    void *static_state;
+    dynamic_MEM_fns mem_fns;
+} dynamic_fns;
+
+/*
+ * The version checking function should be of this prototype. NB: The
+ * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading
+ * code. If this function returns zero, it indicates a (potential) version
+ * incompatibility and the loaded library doesn't believe it can proceed.
+ * Otherwise, the returned value is the (latest) version supported by the
+ * loading library. The loader may still decide that the loaded code's
+ * version is unsatisfactory and could veto the load. The function is
+ * expected to be implemented with the symbol name "v_check", and a default
+ * implementation can be fully instantiated with
+ * IMPLEMENT_DYNAMIC_CHECK_FN().
+ */
+typedef unsigned long (*dynamic_v_check_fn) (unsigned long ossl_version);
+# define IMPLEMENT_DYNAMIC_CHECK_FN() \
+        OPENSSL_EXPORT unsigned long v_check(unsigned long v); \
+        OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \
+                if (v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \
+                return 0; }
+
+/*
+ * This function is passed the ENGINE structure to initialise with its own
+ * function and command settings. It should not adjust the structural or
+ * functional reference counts. If this function returns zero, (a) the load
+ * will be aborted, (b) the previous ENGINE state will be memcpy'd back onto
+ * the structure, and (c) the shared library will be unloaded. So
+ * implementations should do their own internal cleanup in failure
+ * circumstances otherwise they could leak. The 'id' parameter, if non-NULL,
+ * represents the ENGINE id that the loader is looking for. If this is NULL,
+ * the shared library can choose to return failure or to initialise a
+ * 'default' ENGINE. If non-NULL, the shared library must initialise only an
+ * ENGINE matching the passed 'id'. The function is expected to be
+ * implemented with the symbol name "bind_engine". A standard implementation
+ * can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where the parameter
+ * 'fn' is a callback function that populates the ENGINE structure and
+ * returns an int value (zero for failure). 'fn' should have prototype;
+ * [static] int fn(ENGINE *e, const char *id);
+ */
+typedef int (*dynamic_bind_engine) (ENGINE *e, const char *id,
+                                    const dynamic_fns *fns);
+# define IMPLEMENT_DYNAMIC_BIND_FN(fn) \
+        OPENSSL_EXPORT \
+        int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); \
+        OPENSSL_EXPORT \
+        int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \
+            if (ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \
+            CRYPTO_set_mem_functions(fns->mem_fns.malloc_fn, \
+                                     fns->mem_fns.realloc_fn, \
+                                     fns->mem_fns.free_fn); \
+        skip_cbs: \
+            if (!fn(e, id)) return 0; \
+            return 1; }
+
+/*
+ * If the loading application (or library) and the loaded ENGINE library
+ * share the same static data (eg. they're both dynamically linked to the
+ * same libcrypto.so) we need a way to avoid trying to set system callbacks -
+ * this would fail, and for the same reason that it's unnecessary to try. If
+ * the loaded ENGINE has (or gets from through the loader) its own copy of
+ * the libcrypto static data, we will need to set the callbacks. The easiest
+ * way to detect this is to have a function that returns a pointer to some
+ * static data and let the loading application and loaded ENGINE compare
+ * their respective values.
+ */
+void *ENGINE_get_static_state(void);
+
+# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
+DEPRECATEDIN_1_1_0(void ENGINE_setup_bsd_cryptodev(void))
+# endif
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_ENGINE_strings(void);
+
+/* Error codes for the ENGINE functions. */
+
+/* Function codes. */
+# define ENGINE_F_DYNAMIC_CTRL                            180
+# define ENGINE_F_DYNAMIC_GET_DATA_CTX                    181
+# define ENGINE_F_DYNAMIC_LOAD                            182
+# define ENGINE_F_DYNAMIC_SET_DATA_CTX                    183
+# define ENGINE_F_ENGINE_ADD                              105
+# define ENGINE_F_ENGINE_BY_ID                            106
+# define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE                170
+# define ENGINE_F_ENGINE_CTRL                             142
+# define ENGINE_F_ENGINE_CTRL_CMD                         178
+# define ENGINE_F_ENGINE_CTRL_CMD_STRING                  171
+# define ENGINE_F_ENGINE_FINISH                           107
+# define ENGINE_F_ENGINE_GET_CIPHER                       185
+# define ENGINE_F_ENGINE_GET_DIGEST                       186
+# define ENGINE_F_ENGINE_GET_FIRST                        195
+# define ENGINE_F_ENGINE_GET_LAST                         196
+# define ENGINE_F_ENGINE_GET_NEXT                         115
+# define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH               193
+# define ENGINE_F_ENGINE_GET_PKEY_METH                    192
+# define ENGINE_F_ENGINE_GET_PREV                         116
+# define ENGINE_F_ENGINE_INIT                             119
+# define ENGINE_F_ENGINE_LIST_ADD                         120
+# define ENGINE_F_ENGINE_LIST_REMOVE                      121
+# define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY                 150
+# define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY                  151
+# define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT             194
+# define ENGINE_F_ENGINE_NEW                              122
+# define ENGINE_F_ENGINE_PKEY_ASN1_FIND_STR               197
+# define ENGINE_F_ENGINE_REMOVE                           123
+# define ENGINE_F_ENGINE_SET_DEFAULT_STRING               189
+# define ENGINE_F_ENGINE_SET_ID                           129
+# define ENGINE_F_ENGINE_SET_NAME                         130
+# define ENGINE_F_ENGINE_TABLE_REGISTER                   184
+# define ENGINE_F_ENGINE_UNLOCKED_FINISH                  191
+# define ENGINE_F_ENGINE_UP_REF                           190
+# define ENGINE_F_INT_CTRL_HELPER                         172
+# define ENGINE_F_INT_ENGINE_CONFIGURE                    188
+# define ENGINE_F_INT_ENGINE_MODULE_INIT                  187
+
+/* Reason codes. */
+# define ENGINE_R_ALREADY_LOADED                          100
+# define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER                133
+# define ENGINE_R_CMD_NOT_EXECUTABLE                      134
+# define ENGINE_R_COMMAND_TAKES_INPUT                     135
+# define ENGINE_R_COMMAND_TAKES_NO_INPUT                  136
+# define ENGINE_R_CONFLICTING_ENGINE_ID                   103
+# define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED            119
+# define ENGINE_R_DSO_FAILURE                             104
+# define ENGINE_R_DSO_NOT_FOUND                           132
+# define ENGINE_R_ENGINES_SECTION_ERROR                   148
+# define ENGINE_R_ENGINE_CONFIGURATION_ERROR              102
+# define ENGINE_R_ENGINE_IS_NOT_IN_LIST                   105
+# define ENGINE_R_ENGINE_SECTION_ERROR                    149
+# define ENGINE_R_FAILED_LOADING_PRIVATE_KEY              128
+# define ENGINE_R_FAILED_LOADING_PUBLIC_KEY               129
+# define ENGINE_R_FINISH_FAILED                           106
+# define ENGINE_R_ID_OR_NAME_MISSING                      108
+# define ENGINE_R_INIT_FAILED                             109
+# define ENGINE_R_INTERNAL_LIST_ERROR                     110
+# define ENGINE_R_INVALID_ARGUMENT                        143
+# define ENGINE_R_INVALID_CMD_NAME                        137
+# define ENGINE_R_INVALID_CMD_NUMBER                      138
+# define ENGINE_R_INVALID_INIT_VALUE                      151
+# define ENGINE_R_INVALID_STRING                          150
+# define ENGINE_R_NOT_INITIALISED                         117
+# define ENGINE_R_NOT_LOADED                              112
+# define ENGINE_R_NO_CONTROL_FUNCTION                     120
+# define ENGINE_R_NO_INDEX                                144
+# define ENGINE_R_NO_LOAD_FUNCTION                        125
+# define ENGINE_R_NO_REFERENCE                            130
+# define ENGINE_R_NO_SUCH_ENGINE                          116
+# define ENGINE_R_UNIMPLEMENTED_CIPHER                    146
+# define ENGINE_R_UNIMPLEMENTED_DIGEST                    147
+# define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD         101
+# define ENGINE_R_VERSION_INCOMPATIBILITY                 145
+
+#  ifdef  __cplusplus
+}
+#  endif
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/err.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/err.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/err.h	(revision 331)
@@ -0,0 +1,259 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_ERR_H
+# define HEADER_ERR_H
+
+# include <openssl/e_os2.h>
+
+# ifndef OPENSSL_NO_STDIO
+#  include <stdio.h>
+#  include <stdlib.h>
+# endif
+
+# include <openssl/ossl_typ.h>
+# include <openssl/bio.h>
+# include <openssl/lhash.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# ifndef OPENSSL_NO_ERR
+#  define ERR_PUT_error(a,b,c,d,e)        ERR_put_error(a,b,c,d,e)
+# else
+#  define ERR_PUT_error(a,b,c,d,e)        ERR_put_error(a,b,c,NULL,0)
+# endif
+
+# include <errno.h>
+
+# define ERR_TXT_MALLOCED        0x01
+# define ERR_TXT_STRING          0x02
+
+# define ERR_FLAG_MARK           0x01
+
+# define ERR_NUM_ERRORS  16
+typedef struct err_state_st {
+    int err_flags[ERR_NUM_ERRORS];
+    unsigned long err_buffer[ERR_NUM_ERRORS];
+    char *err_data[ERR_NUM_ERRORS];
+    int err_data_flags[ERR_NUM_ERRORS];
+    const char *err_file[ERR_NUM_ERRORS];
+    int err_line[ERR_NUM_ERRORS];
+    int top, bottom;
+} ERR_STATE;
+
+/* library */
+# define ERR_LIB_NONE            1
+# define ERR_LIB_SYS             2
+# define ERR_LIB_BN              3
+# define ERR_LIB_RSA             4
+# define ERR_LIB_DH              5
+# define ERR_LIB_EVP             6
+# define ERR_LIB_BUF             7
+# define ERR_LIB_OBJ             8
+# define ERR_LIB_PEM             9
+# define ERR_LIB_DSA             10
+# define ERR_LIB_X509            11
+/* #define ERR_LIB_METH         12 */
+# define ERR_LIB_ASN1            13
+# define ERR_LIB_CONF            14
+# define ERR_LIB_CRYPTO          15
+# define ERR_LIB_EC              16
+# define ERR_LIB_SSL             20
+/* #define ERR_LIB_SSL23        21 */
+/* #define ERR_LIB_SSL2         22 */
+/* #define ERR_LIB_SSL3         23 */
+/* #define ERR_LIB_RSAREF       30 */
+/* #define ERR_LIB_PROXY        31 */
+# define ERR_LIB_BIO             32
+# define ERR_LIB_PKCS7           33
+# define ERR_LIB_X509V3          34
+# define ERR_LIB_PKCS12          35
+# define ERR_LIB_RAND            36
+# define ERR_LIB_DSO             37
+# define ERR_LIB_ENGINE          38
+# define ERR_LIB_OCSP            39
+# define ERR_LIB_UI              40
+# define ERR_LIB_COMP            41
+# define ERR_LIB_ECDSA           42
+# define ERR_LIB_ECDH            43
+# define ERR_LIB_STORE           44
+# define ERR_LIB_FIPS            45
+# define ERR_LIB_CMS             46
+# define ERR_LIB_TS              47
+# define ERR_LIB_HMAC            48
+/* # define ERR_LIB_JPAKE       49 */
+# define ERR_LIB_CT              50
+# define ERR_LIB_ASYNC           51
+# define ERR_LIB_KDF             52
+
+# define ERR_LIB_USER            128
+
+# define SYSerr(f,r)  ERR_PUT_error(ERR_LIB_SYS,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define BNerr(f,r)   ERR_PUT_error(ERR_LIB_BN,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define RSAerr(f,r)  ERR_PUT_error(ERR_LIB_RSA,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define DHerr(f,r)   ERR_PUT_error(ERR_LIB_DH,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define EVPerr(f,r)  ERR_PUT_error(ERR_LIB_EVP,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define BUFerr(f,r)  ERR_PUT_error(ERR_LIB_BUF,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define OBJerr(f,r)  ERR_PUT_error(ERR_LIB_OBJ,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define PEMerr(f,r)  ERR_PUT_error(ERR_LIB_PEM,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define DSAerr(f,r)  ERR_PUT_error(ERR_LIB_DSA,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define ECerr(f,r)   ERR_PUT_error(ERR_LIB_EC,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define SSLerr(f,r)  ERR_PUT_error(ERR_LIB_SSL,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define BIOerr(f,r)  ERR_PUT_error(ERR_LIB_BIO,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define ECDSAerr(f,r)  ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define ECDHerr(f,r)  ERR_PUT_error(ERR_LIB_ECDH,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define CTerr(f,r) ERR_PUT_error(ERR_LIB_CT,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define ASYNCerr(f,r) ERR_PUT_error(ERR_LIB_ASYNC,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+# define KDFerr(f,r) ERR_PUT_error(ERR_LIB_KDF,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
+
+# define ERR_PACK(l,f,r) ( \
+        (((unsigned int)(l) & 0x0FF) << 24L) | \
+        (((unsigned int)(f) & 0xFFF) << 12L) | \
+        (((unsigned int)(r) & 0xFFF)       ) )
+# define ERR_GET_LIB(l)          (int)(((l) >> 24L) & 0x0FFL)
+# define ERR_GET_FUNC(l)         (int)(((l) >> 12L) & 0xFFFL)
+# define ERR_GET_REASON(l)       (int)( (l)         & 0xFFFL)
+# define ERR_FATAL_ERROR(l)      (int)( (l)         & ERR_R_FATAL)
+
+/* OS functions */
+# define SYS_F_FOPEN             1
+# define SYS_F_CONNECT           2
+# define SYS_F_GETSERVBYNAME     3
+# define SYS_F_SOCKET            4
+# define SYS_F_IOCTLSOCKET       5
+# define SYS_F_BIND              6
+# define SYS_F_LISTEN            7
+# define SYS_F_ACCEPT            8
+# define SYS_F_WSASTARTUP        9/* Winsock stuff */
+# define SYS_F_OPENDIR           10
+# define SYS_F_FREAD             11
+# define SYS_F_GETADDRINFO       12
+# define SYS_F_GETNAMEINFO       13
+# define SYS_F_SETSOCKOPT        14
+# define SYS_F_GETSOCKOPT        15
+# define SYS_F_GETSOCKNAME       16
+# define SYS_F_GETHOSTBYNAME     17
+
+/* reasons */
+# define ERR_R_SYS_LIB   ERR_LIB_SYS/* 2 */
+# define ERR_R_BN_LIB    ERR_LIB_BN/* 3 */
+# define ERR_R_RSA_LIB   ERR_LIB_RSA/* 4 */
+# define ERR_R_DH_LIB    ERR_LIB_DH/* 5 */
+# define ERR_R_EVP_LIB   ERR_LIB_EVP/* 6 */
+# define ERR_R_BUF_LIB   ERR_LIB_BUF/* 7 */
+# define ERR_R_OBJ_LIB   ERR_LIB_OBJ/* 8 */
+# define ERR_R_PEM_LIB   ERR_LIB_PEM/* 9 */
+# define ERR_R_DSA_LIB   ERR_LIB_DSA/* 10 */
+# define ERR_R_X509_LIB  ERR_LIB_X509/* 11 */
+# define ERR_R_ASN1_LIB  ERR_LIB_ASN1/* 13 */
+# define ERR_R_EC_LIB    ERR_LIB_EC/* 16 */
+# define ERR_R_BIO_LIB   ERR_LIB_BIO/* 32 */
+# define ERR_R_PKCS7_LIB ERR_LIB_PKCS7/* 33 */
+# define ERR_R_X509V3_LIB ERR_LIB_X509V3/* 34 */
+# define ERR_R_ENGINE_LIB ERR_LIB_ENGINE/* 38 */
+# define ERR_R_ECDSA_LIB ERR_LIB_ECDSA/* 42 */
+
+# define ERR_R_NESTED_ASN1_ERROR                 58
+# define ERR_R_MISSING_ASN1_EOS                  63
+
+/* fatal error */
+# define ERR_R_FATAL                             64
+# define ERR_R_MALLOC_FAILURE                    (1|ERR_R_FATAL)
+# define ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED       (2|ERR_R_FATAL)
+# define ERR_R_PASSED_NULL_PARAMETER             (3|ERR_R_FATAL)
+# define ERR_R_INTERNAL_ERROR                    (4|ERR_R_FATAL)
+# define ERR_R_DISABLED                          (5|ERR_R_FATAL)
+# define ERR_R_INIT_FAIL                         (6|ERR_R_FATAL)
+# define ERR_R_PASSED_INVALID_ARGUMENT           (7)
+
+/*
+ * 99 is the maximum possible ERR_R_... code, higher values are reserved for
+ * the individual libraries
+ */
+
+typedef struct ERR_string_data_st {
+    unsigned long error;
+    const char *string;
+} ERR_STRING_DATA;
+
+DEFINE_LHASH_OF(ERR_STRING_DATA);
+
+void ERR_put_error(int lib, int func, int reason, const char *file, int line);
+void ERR_set_error_data(char *data, int flags);
+
+unsigned long ERR_get_error(void);
+unsigned long ERR_get_error_line(const char **file, int *line);
+unsigned long ERR_get_error_line_data(const char **file, int *line,
+                                      const char **data, int *flags);
+unsigned long ERR_peek_error(void);
+unsigned long ERR_peek_error_line(const char **file, int *line);
+unsigned long ERR_peek_error_line_data(const char **file, int *line,
+                                       const char **data, int *flags);
+unsigned long ERR_peek_last_error(void);
+unsigned long ERR_peek_last_error_line(const char **file, int *line);
+unsigned long ERR_peek_last_error_line_data(const char **file, int *line,
+                                            const char **data, int *flags);
+void ERR_clear_error(void);
+char *ERR_error_string(unsigned long e, char *buf);
+void ERR_error_string_n(unsigned long e, char *buf, size_t len);
+const char *ERR_lib_error_string(unsigned long e);
+const char *ERR_func_error_string(unsigned long e);
+const char *ERR_reason_error_string(unsigned long e);
+void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u),
+                         void *u);
+# ifndef OPENSSL_NO_STDIO
+void ERR_print_errors_fp(FILE *fp);
+# endif
+void ERR_print_errors(BIO *bp);
+void ERR_add_error_data(int num, ...);
+void ERR_add_error_vdata(int num, va_list args);
+int ERR_load_strings(int lib, ERR_STRING_DATA str[]);
+int ERR_unload_strings(int lib, ERR_STRING_DATA str[]);
+int ERR_load_ERR_strings(void);
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+# define ERR_load_crypto_strings() \
+    OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL)
+# define ERR_free_strings() while(0) continue
+#endif
+
+DEPRECATEDIN_1_1_0(void ERR_remove_thread_state(void *))
+DEPRECATEDIN_1_0_0(void ERR_remove_state(unsigned long pid))
+ERR_STATE *ERR_get_state(void);
+
+int ERR_get_next_error_library(void);
+
+int ERR_set_mark(void);
+int ERR_pop_to_mark(void);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/evp.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/evp.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/evp.h	(revision 331)
@@ -0,0 +1,1590 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_ENVELOPE_H
+# define HEADER_ENVELOPE_H
+
+# include <openssl/opensslconf.h>
+# include <openssl/ossl_typ.h>
+# include <openssl/symhacks.h>
+# include <openssl/bio.h>
+
+# define EVP_MAX_MD_SIZE                 64/* longest known is SHA512 */
+# define EVP_MAX_KEY_LENGTH              64
+# define EVP_MAX_IV_LENGTH               16
+# define EVP_MAX_BLOCK_LENGTH            32
+
+# define PKCS5_SALT_LEN                  8
+/* Default PKCS#5 iteration count */
+# define PKCS5_DEFAULT_ITER              2048
+
+# include <openssl/objects.h>
+
+# define EVP_PK_RSA      0x0001
+# define EVP_PK_DSA      0x0002
+# define EVP_PK_DH       0x0004
+# define EVP_PK_EC       0x0008
+# define EVP_PKT_SIGN    0x0010
+# define EVP_PKT_ENC     0x0020
+# define EVP_PKT_EXCH    0x0040
+# define EVP_PKS_RSA     0x0100
+# define EVP_PKS_DSA     0x0200
+# define EVP_PKS_EC      0x0400
+
+# define EVP_PKEY_NONE   NID_undef
+# define EVP_PKEY_RSA    NID_rsaEncryption
+# define EVP_PKEY_RSA2   NID_rsa
+# define EVP_PKEY_DSA    NID_dsa
+# define EVP_PKEY_DSA1   NID_dsa_2
+# define EVP_PKEY_DSA2   NID_dsaWithSHA
+# define EVP_PKEY_DSA3   NID_dsaWithSHA1
+# define EVP_PKEY_DSA4   NID_dsaWithSHA1_2
+# define EVP_PKEY_DH     NID_dhKeyAgreement
+# define EVP_PKEY_DHX    NID_dhpublicnumber
+# define EVP_PKEY_EC     NID_X9_62_id_ecPublicKey
+# define EVP_PKEY_HMAC   NID_hmac
+# define EVP_PKEY_CMAC   NID_cmac
+# define EVP_PKEY_TLS1_PRF NID_tls1_prf
+# define EVP_PKEY_HKDF   NID_hkdf
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define EVP_PKEY_MO_SIGN        0x0001
+# define EVP_PKEY_MO_VERIFY      0x0002
+# define EVP_PKEY_MO_ENCRYPT     0x0004
+# define EVP_PKEY_MO_DECRYPT     0x0008
+
+# ifndef EVP_MD
+EVP_MD *EVP_MD_meth_new(int md_type, int pkey_type);
+EVP_MD *EVP_MD_meth_dup(const EVP_MD *md);
+void EVP_MD_meth_free(EVP_MD *md);
+
+int EVP_MD_meth_set_input_blocksize(EVP_MD *md, int blocksize);
+int EVP_MD_meth_set_result_size(EVP_MD *md, int resultsize);
+int EVP_MD_meth_set_app_datasize(EVP_MD *md, int datasize);
+int EVP_MD_meth_set_flags(EVP_MD *md, unsigned long flags);
+int EVP_MD_meth_set_init(EVP_MD *md, int (*init)(EVP_MD_CTX *ctx));
+int EVP_MD_meth_set_update(EVP_MD *md, int (*update)(EVP_MD_CTX *ctx,
+                                                     const void *data,
+                                                     size_t count));
+int EVP_MD_meth_set_final(EVP_MD *md, int (*final)(EVP_MD_CTX *ctx,
+                                                   unsigned char *md));
+int EVP_MD_meth_set_copy(EVP_MD *md, int (*copy)(EVP_MD_CTX *to,
+                                                 const EVP_MD_CTX *from));
+int EVP_MD_meth_set_cleanup(EVP_MD *md, int (*cleanup)(EVP_MD_CTX *ctx));
+int EVP_MD_meth_set_ctrl(EVP_MD *md, int (*ctrl)(EVP_MD_CTX *ctx, int cmd,
+                                                 int p1, void *p2));
+
+int EVP_MD_meth_get_input_blocksize(const EVP_MD *md);
+int EVP_MD_meth_get_result_size(const EVP_MD *md);
+int EVP_MD_meth_get_app_datasize(const EVP_MD *md);
+unsigned long EVP_MD_meth_get_flags(const EVP_MD *md);
+int (*EVP_MD_meth_get_init(const EVP_MD *md))(EVP_MD_CTX *ctx);
+int (*EVP_MD_meth_get_update(const EVP_MD *md))(EVP_MD_CTX *ctx,
+                                                const void *data,
+                                                size_t count);
+int (*EVP_MD_meth_get_final(const EVP_MD *md))(EVP_MD_CTX *ctx,
+                                               unsigned char *md);
+int (*EVP_MD_meth_get_copy(const EVP_MD *md))(EVP_MD_CTX *to,
+                                              const EVP_MD_CTX *from);
+int (*EVP_MD_meth_get_cleanup(const EVP_MD *md))(EVP_MD_CTX *ctx);
+int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd,
+                                              int p1, void *p2);
+
+/* digest can only handle a single block */
+#  define EVP_MD_FLAG_ONESHOT     0x0001
+
+/* DigestAlgorithmIdentifier flags... */
+
+#  define EVP_MD_FLAG_DIGALGID_MASK               0x0018
+
+/* NULL or absent parameter accepted. Use NULL */
+
+#  define EVP_MD_FLAG_DIGALGID_NULL               0x0000
+
+/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */
+
+#  define EVP_MD_FLAG_DIGALGID_ABSENT             0x0008
+
+/* Custom handling via ctrl */
+
+#  define EVP_MD_FLAG_DIGALGID_CUSTOM             0x0018
+
+/* Note if suitable for use in FIPS mode */
+#  define EVP_MD_FLAG_FIPS        0x0400
+
+/* Digest ctrls */
+
+#  define EVP_MD_CTRL_DIGALGID                    0x1
+#  define EVP_MD_CTRL_MICALG                      0x2
+
+/* Minimum Algorithm specific ctrl value */
+
+#  define EVP_MD_CTRL_ALG_CTRL                    0x1000
+
+# endif                         /* !EVP_MD */
+
+/* values for EVP_MD_CTX flags */
+
+# define EVP_MD_CTX_FLAG_ONESHOT         0x0001/* digest update will be
+                                                * called once only */
+# define EVP_MD_CTX_FLAG_CLEANED         0x0002/* context has already been
+                                                * cleaned */
+# define EVP_MD_CTX_FLAG_REUSE           0x0004/* Don't free up ctx->md_data
+                                                * in EVP_MD_CTX_reset */
+/*
+ * FIPS and pad options are ignored in 1.0.0, definitions are here so we
+ * don't accidentally reuse the values for other purposes.
+ */
+
+# define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW  0x0008/* Allow use of non FIPS
+                                                * digest in FIPS mode */
+
+/*
+ * The following PAD options are also currently ignored in 1.0.0, digest
+ * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*()
+ * instead.
+ */
+# define EVP_MD_CTX_FLAG_PAD_MASK        0xF0/* RSA mode to use */
+# define EVP_MD_CTX_FLAG_PAD_PKCS1       0x00/* PKCS#1 v1.5 mode */
+# define EVP_MD_CTX_FLAG_PAD_X931        0x10/* X9.31 mode */
+# define EVP_MD_CTX_FLAG_PAD_PSS         0x20/* PSS mode */
+
+# define EVP_MD_CTX_FLAG_NO_INIT         0x0100/* Don't initialize md_data */
+/*
+ * Some functions such as EVP_DigestSign only finalise copies of internal
+ * contexts so additional data can be included after the finalisation call.
+ * This is inefficient if this functionality is not required: it is disabled
+ * if the following flag is set.
+ */
+# define EVP_MD_CTX_FLAG_FINALISE        0x0200
+
+EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len);
+EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher);
+void EVP_CIPHER_meth_free(EVP_CIPHER *cipher);
+
+int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len);
+int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags);
+int EVP_CIPHER_meth_set_impl_ctx_size(EVP_CIPHER *cipher, int ctx_size);
+int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher,
+                             int (*init) (EVP_CIPHER_CTX *ctx,
+                                          const unsigned char *key,
+                                          const unsigned char *iv,
+                                          int enc));
+int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher,
+                                  int (*do_cipher) (EVP_CIPHER_CTX *ctx,
+                                                    unsigned char *out,
+                                                    const unsigned char *in,
+                                                    size_t inl));
+int EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher,
+                                int (*cleanup) (EVP_CIPHER_CTX *));
+int EVP_CIPHER_meth_set_set_asn1_params(EVP_CIPHER *cipher,
+                                        int (*set_asn1_parameters) (EVP_CIPHER_CTX *,
+                                                                    ASN1_TYPE *));
+int EVP_CIPHER_meth_set_get_asn1_params(EVP_CIPHER *cipher,
+                                        int (*get_asn1_parameters) (EVP_CIPHER_CTX *,
+                                                                    ASN1_TYPE *));
+int EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher,
+                             int (*ctrl) (EVP_CIPHER_CTX *, int type,
+                                          int arg, void *ptr));
+
+int (*EVP_CIPHER_meth_get_init(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx,
+                                                          const unsigned char *key,
+                                                          const unsigned char *iv,
+                                                          int enc);
+int (*EVP_CIPHER_meth_get_do_cipher(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx,
+                                                               unsigned char *out,
+                                                               const unsigned char *in,
+                                                               size_t inl);
+int (*EVP_CIPHER_meth_get_cleanup(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *);
+int (*EVP_CIPHER_meth_get_set_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
+                                                                     ASN1_TYPE *);
+int (*EVP_CIPHER_meth_get_get_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
+                                                               ASN1_TYPE *);
+int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
+                                                          int type, int arg,
+                                                          void *ptr);
+
+/* Values for cipher flags */
+
+/* Modes for ciphers */
+
+# define         EVP_CIPH_STREAM_CIPHER          0x0
+# define         EVP_CIPH_ECB_MODE               0x1
+# define         EVP_CIPH_CBC_MODE               0x2
+# define         EVP_CIPH_CFB_MODE               0x3
+# define         EVP_CIPH_OFB_MODE               0x4
+# define         EVP_CIPH_CTR_MODE               0x5
+# define         EVP_CIPH_GCM_MODE               0x6
+# define         EVP_CIPH_CCM_MODE               0x7
+# define         EVP_CIPH_XTS_MODE               0x10001
+# define         EVP_CIPH_WRAP_MODE              0x10002
+# define         EVP_CIPH_OCB_MODE               0x10003
+# define         EVP_CIPH_MODE                   0xF0007
+/* Set if variable length cipher */
+# define         EVP_CIPH_VARIABLE_LENGTH        0x8
+/* Set if the iv handling should be done by the cipher itself */
+# define         EVP_CIPH_CUSTOM_IV              0x10
+/* Set if the cipher's init() function should be called if key is NULL */
+# define         EVP_CIPH_ALWAYS_CALL_INIT       0x20
+/* Call ctrl() to init cipher parameters */
+# define         EVP_CIPH_CTRL_INIT              0x40
+/* Don't use standard key length function */
+# define         EVP_CIPH_CUSTOM_KEY_LENGTH      0x80
+/* Don't use standard block padding */
+# define         EVP_CIPH_NO_PADDING             0x100
+/* cipher handles random key generation */
+# define         EVP_CIPH_RAND_KEY               0x200
+/* cipher has its own additional copying logic */
+# define         EVP_CIPH_CUSTOM_COPY            0x400
+/* Allow use default ASN1 get/set iv */
+# define         EVP_CIPH_FLAG_DEFAULT_ASN1      0x1000
+/* Buffer length in bits not bytes: CFB1 mode only */
+# define         EVP_CIPH_FLAG_LENGTH_BITS       0x2000
+/* Note if suitable for use in FIPS mode */
+# define         EVP_CIPH_FLAG_FIPS              0x4000
+/* Allow non FIPS cipher in FIPS mode */
+# define         EVP_CIPH_FLAG_NON_FIPS_ALLOW    0x8000
+/*
+ * Cipher handles any and all padding logic as well as finalisation.
+ */
+# define         EVP_CIPH_FLAG_CUSTOM_CIPHER     0x100000
+# define         EVP_CIPH_FLAG_AEAD_CIPHER       0x200000
+# define         EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0x400000
+/* Cipher can handle pipeline operations */
+# define         EVP_CIPH_FLAG_PIPELINE          0X800000
+
+/*
+ * Cipher context flag to indicate we can handle wrap mode: if allowed in
+ * older applications it could overflow buffers.
+ */
+
+# define         EVP_CIPHER_CTX_FLAG_WRAP_ALLOW  0x1
+
+/* ctrl() values */
+
+# define         EVP_CTRL_INIT                   0x0
+# define         EVP_CTRL_SET_KEY_LENGTH         0x1
+# define         EVP_CTRL_GET_RC2_KEY_BITS       0x2
+# define         EVP_CTRL_SET_RC2_KEY_BITS       0x3
+# define         EVP_CTRL_GET_RC5_ROUNDS         0x4
+# define         EVP_CTRL_SET_RC5_ROUNDS         0x5
+# define         EVP_CTRL_RAND_KEY               0x6
+# define         EVP_CTRL_PBE_PRF_NID            0x7
+# define         EVP_CTRL_COPY                   0x8
+# define         EVP_CTRL_AEAD_SET_IVLEN         0x9
+# define         EVP_CTRL_AEAD_GET_TAG           0x10
+# define         EVP_CTRL_AEAD_SET_TAG           0x11
+# define         EVP_CTRL_AEAD_SET_IV_FIXED      0x12
+# define         EVP_CTRL_GCM_SET_IVLEN          EVP_CTRL_AEAD_SET_IVLEN
+# define         EVP_CTRL_GCM_GET_TAG            EVP_CTRL_AEAD_GET_TAG
+# define         EVP_CTRL_GCM_SET_TAG            EVP_CTRL_AEAD_SET_TAG
+# define         EVP_CTRL_GCM_SET_IV_FIXED       EVP_CTRL_AEAD_SET_IV_FIXED
+# define         EVP_CTRL_GCM_IV_GEN             0x13
+# define         EVP_CTRL_CCM_SET_IVLEN          EVP_CTRL_AEAD_SET_IVLEN
+# define         EVP_CTRL_CCM_GET_TAG            EVP_CTRL_AEAD_GET_TAG
+# define         EVP_CTRL_CCM_SET_TAG            EVP_CTRL_AEAD_SET_TAG
+# define         EVP_CTRL_CCM_SET_IV_FIXED       EVP_CTRL_AEAD_SET_IV_FIXED
+# define         EVP_CTRL_CCM_SET_L              0x14
+# define         EVP_CTRL_CCM_SET_MSGLEN         0x15
+/*
+ * AEAD cipher deduces payload length and returns number of bytes required to
+ * store MAC and eventual padding. Subsequent call to EVP_Cipher even
+ * appends/verifies MAC.
+ */
+# define         EVP_CTRL_AEAD_TLS1_AAD          0x16
+/* Used by composite AEAD ciphers, no-op in GCM, CCM... */
+# define         EVP_CTRL_AEAD_SET_MAC_KEY       0x17
+/* Set the GCM invocation field, decrypt only */
+# define         EVP_CTRL_GCM_SET_IV_INV         0x18
+
+# define         EVP_CTRL_TLS1_1_MULTIBLOCK_AAD  0x19
+# define         EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT      0x1a
+# define         EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT      0x1b
+# define         EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE  0x1c
+
+# define         EVP_CTRL_SSL3_MASTER_SECRET             0x1d
+
+/* EVP_CTRL_SET_SBOX takes the char * specifying S-boxes */
+# define         EVP_CTRL_SET_SBOX                       0x1e
+/*
+ * EVP_CTRL_SBOX_USED takes a 'size_t' and 'char *', pointing at a
+ * pre-allocated buffer with specified size
+ */
+# define         EVP_CTRL_SBOX_USED                      0x1f
+/* EVP_CTRL_KEY_MESH takes 'size_t' number of bytes to mesh the key after,
+ * 0 switches meshing off
+ */
+# define         EVP_CTRL_KEY_MESH                       0x20
+/* EVP_CTRL_BLOCK_PADDING_MODE takes the padding mode */
+# define         EVP_CTRL_BLOCK_PADDING_MODE             0x21
+
+/* Set the output buffers to use for a pipelined operation */
+# define         EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS       0x22
+/* Set the input buffers to use for a pipelined operation */
+# define         EVP_CTRL_SET_PIPELINE_INPUT_BUFS        0x23
+/* Set the input buffer lengths to use for a pipelined operation */
+# define         EVP_CTRL_SET_PIPELINE_INPUT_LENS        0x24
+
+/* Padding modes */
+#define EVP_PADDING_PKCS7       1
+#define EVP_PADDING_ISO7816_4   2
+#define EVP_PADDING_ANSI923     3
+#define EVP_PADDING_ISO10126    4
+#define EVP_PADDING_ZERO        5
+
+/* RFC 5246 defines additional data to be 13 bytes in length */
+# define         EVP_AEAD_TLS1_AAD_LEN           13
+
+typedef struct {
+    unsigned char *out;
+    const unsigned char *inp;
+    size_t len;
+    unsigned int interleave;
+} EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM;
+
+/* GCM TLS constants */
+/* Length of fixed part of IV derived from PRF */
+# define EVP_GCM_TLS_FIXED_IV_LEN                        4
+/* Length of explicit part of IV part of TLS records */
+# define EVP_GCM_TLS_EXPLICIT_IV_LEN                     8
+/* Length of tag for TLS */
+# define EVP_GCM_TLS_TAG_LEN                             16
+
+/* CCM TLS constants */
+/* Length of fixed part of IV derived from PRF */
+# define EVP_CCM_TLS_FIXED_IV_LEN                        4
+/* Length of explicit part of IV part of TLS records */
+# define EVP_CCM_TLS_EXPLICIT_IV_LEN                     8
+
+typedef struct evp_cipher_info_st {
+    const EVP_CIPHER *cipher;
+    unsigned char iv[EVP_MAX_IV_LENGTH];
+} EVP_CIPHER_INFO;
+
+
+/* Password based encryption function */
+typedef int (EVP_PBE_KEYGEN) (EVP_CIPHER_CTX *ctx, const char *pass,
+                              int passlen, ASN1_TYPE *param,
+                              const EVP_CIPHER *cipher, const EVP_MD *md,
+                              int en_de);
+
+# ifndef OPENSSL_NO_RSA
+#  define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
+                                        (char *)(rsa))
+# endif
+
+# ifndef OPENSSL_NO_DSA
+#  define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\
+                                        (char *)(dsa))
+# endif
+
+# ifndef OPENSSL_NO_DH
+#  define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\
+                                        (char *)(dh))
+# endif
+
+# ifndef OPENSSL_NO_EC
+#  define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\
+                                        (char *)(eckey))
+# endif
+
+/* Add some extra combinations */
+# define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a))
+# define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a))
+# define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a))
+# define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a))
+
+int EVP_MD_type(const EVP_MD *md);
+# define EVP_MD_nid(e)                   EVP_MD_type(e)
+# define EVP_MD_name(e)                  OBJ_nid2sn(EVP_MD_nid(e))
+int EVP_MD_pkey_type(const EVP_MD *md);
+int EVP_MD_size(const EVP_MD *md);
+int EVP_MD_block_size(const EVP_MD *md);
+unsigned long EVP_MD_flags(const EVP_MD *md);
+
+const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx);
+int (*EVP_MD_CTX_update_fn(EVP_MD_CTX *ctx))(EVP_MD_CTX *ctx,
+                                             const void *data, size_t count);
+void EVP_MD_CTX_set_update_fn(EVP_MD_CTX *ctx,
+                              int (*update) (EVP_MD_CTX *ctx,
+                                             const void *data, size_t count));
+# define EVP_MD_CTX_size(e)              EVP_MD_size(EVP_MD_CTX_md(e))
+# define EVP_MD_CTX_block_size(e)        EVP_MD_block_size(EVP_MD_CTX_md(e))
+# define EVP_MD_CTX_type(e)              EVP_MD_type(EVP_MD_CTX_md(e))
+EVP_PKEY_CTX *EVP_MD_CTX_pkey_ctx(const EVP_MD_CTX *ctx);
+void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx);
+
+int EVP_CIPHER_nid(const EVP_CIPHER *cipher);
+# define EVP_CIPHER_name(e)              OBJ_nid2sn(EVP_CIPHER_nid(e))
+int EVP_CIPHER_block_size(const EVP_CIPHER *cipher);
+int EVP_CIPHER_impl_ctx_size(const EVP_CIPHER *cipher);
+int EVP_CIPHER_key_length(const EVP_CIPHER *cipher);
+int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher);
+unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher);
+# define EVP_CIPHER_mode(e)              (EVP_CIPHER_flags(e) & EVP_CIPH_MODE)
+
+const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_encrypting(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx);
+const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx);
+const unsigned char *EVP_CIPHER_CTX_original_iv(const EVP_CIPHER_CTX *ctx);
+unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx);
+unsigned char *EVP_CIPHER_CTX_buf_noconst(EVP_CIPHER_CTX *ctx);
+int EVP_CIPHER_CTX_num(const EVP_CIPHER_CTX *ctx);
+void EVP_CIPHER_CTX_set_num(EVP_CIPHER_CTX *ctx, int num);
+int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in);
+void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx);
+void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data);
+void *EVP_CIPHER_CTX_get_cipher_data(const EVP_CIPHER_CTX *ctx);
+void *EVP_CIPHER_CTX_set_cipher_data(EVP_CIPHER_CTX *ctx, void *cipher_data);
+# define EVP_CIPHER_CTX_type(c)         EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c))
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  define EVP_CIPHER_CTX_flags(c)       EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(c))
+# endif
+# define EVP_CIPHER_CTX_mode(c)         EVP_CIPHER_mode(EVP_CIPHER_CTX_cipher(c))
+
+# define EVP_ENCODE_LENGTH(l)    (((l+2)/3*4)+(l/48+1)*2+80)
+# define EVP_DECODE_LENGTH(l)    ((l+3)/4*3+80)
+
+# define EVP_SignInit_ex(a,b,c)          EVP_DigestInit_ex(a,b,c)
+# define EVP_SignInit(a,b)               EVP_DigestInit(a,b)
+# define EVP_SignUpdate(a,b,c)           EVP_DigestUpdate(a,b,c)
+# define EVP_VerifyInit_ex(a,b,c)        EVP_DigestInit_ex(a,b,c)
+# define EVP_VerifyInit(a,b)             EVP_DigestInit(a,b)
+# define EVP_VerifyUpdate(a,b,c)         EVP_DigestUpdate(a,b,c)
+# define EVP_OpenUpdate(a,b,c,d,e)       EVP_DecryptUpdate(a,b,c,d,e)
+# define EVP_SealUpdate(a,b,c,d,e)       EVP_EncryptUpdate(a,b,c,d,e)
+# define EVP_DigestSignUpdate(a,b,c)     EVP_DigestUpdate(a,b,c)
+# define EVP_DigestVerifyUpdate(a,b,c)   EVP_DigestUpdate(a,b,c)
+
+# ifdef CONST_STRICT
+void BIO_set_md(BIO *, const EVP_MD *md);
+# else
+#  define BIO_set_md(b,md)               BIO_ctrl(b,BIO_C_SET_MD,0,(char *)md)
+# endif
+# define BIO_get_md(b,mdp)               BIO_ctrl(b,BIO_C_GET_MD,0,(char *)mdp)
+# define BIO_get_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_GET_MD_CTX,0,(char *)mdcp)
+# define BIO_set_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_SET_MD_CTX,0,(char *)mdcp)
+# define BIO_get_cipher_status(b)        BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL)
+# define BIO_get_cipher_ctx(b,c_pp)      BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(char *)c_pp)
+
+/*__owur*/ int EVP_Cipher(EVP_CIPHER_CTX *c,
+                          unsigned char *out,
+                          const unsigned char *in, unsigned int inl);
+
+# define EVP_add_cipher_alias(n,alias) \
+        OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n))
+# define EVP_add_digest_alias(n,alias) \
+        OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n))
+# define EVP_delete_cipher_alias(alias) \
+        OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS);
+# define EVP_delete_digest_alias(alias) \
+        OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS);
+
+int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2);
+EVP_MD_CTX *EVP_MD_CTX_new(void);
+int EVP_MD_CTX_reset(EVP_MD_CTX *ctx);
+void EVP_MD_CTX_free(EVP_MD_CTX *ctx);
+# define EVP_MD_CTX_create()     EVP_MD_CTX_new()
+# define EVP_MD_CTX_init(ctx)    EVP_MD_CTX_reset((ctx))
+# define EVP_MD_CTX_destroy(ctx) EVP_MD_CTX_free((ctx))
+__owur int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in);
+void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags);
+void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags);
+int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags);
+__owur int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type,
+                                 ENGINE *impl);
+__owur int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d,
+                                size_t cnt);
+__owur int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md,
+                                  unsigned int *s);
+__owur int EVP_Digest(const void *data, size_t count,
+                          unsigned char *md, unsigned int *size,
+                          const EVP_MD *type, ENGINE *impl);
+
+__owur int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in);
+__owur int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
+__owur int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md,
+                           unsigned int *s);
+
+#ifndef OPENSSL_NO_UI
+int EVP_read_pw_string(char *buf, int length, const char *prompt, int verify);
+int EVP_read_pw_string_min(char *buf, int minlen, int maxlen,
+                           const char *prompt, int verify);
+void EVP_set_pw_prompt(const char *prompt);
+char *EVP_get_pw_prompt(void);
+#endif
+
+__owur int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
+                          const unsigned char *salt,
+                          const unsigned char *data, int datal, int count,
+                          unsigned char *key, unsigned char *iv);
+
+void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags);
+void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags);
+int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags);
+
+__owur int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+                           const unsigned char *key, const unsigned char *iv);
+/*__owur*/ int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,
+                                  const EVP_CIPHER *cipher, ENGINE *impl,
+                                  const unsigned char *key,
+                                  const unsigned char *iv);
+/*__owur*/ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                                 int *outl, const unsigned char *in, int inl);
+/*__owur*/ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                                   int *outl);
+/*__owur*/ int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                                int *outl);
+
+__owur int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+                           const unsigned char *key, const unsigned char *iv);
+/*__owur*/ int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx,
+                                  const EVP_CIPHER *cipher, ENGINE *impl,
+                                  const unsigned char *key,
+                                  const unsigned char *iv);
+/*__owur*/ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                                 int *outl, const unsigned char *in, int inl);
+__owur int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm,
+                            int *outl);
+/*__owur*/ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm,
+                                   int *outl);
+
+__owur int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
+                          const unsigned char *key, const unsigned char *iv,
+                          int enc);
+/*__owur*/ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx,
+                                 const EVP_CIPHER *cipher, ENGINE *impl,
+                                 const unsigned char *key,
+                                 const unsigned char *iv, int enc);
+__owur int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                            int *outl, const unsigned char *in, int inl);
+__owur int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm,
+                           int *outl);
+__owur int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm,
+                              int *outl);
+
+__owur int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s,
+                         EVP_PKEY *pkey);
+
+__owur int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
+                           unsigned int siglen, EVP_PKEY *pkey);
+
+/*__owur*/ int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+                                  const EVP_MD *type, ENGINE *e,
+                                  EVP_PKEY *pkey);
+__owur int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
+                               size_t *siglen);
+
+__owur int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+                                const EVP_MD *type, ENGINE *e,
+                                EVP_PKEY *pkey);
+__owur int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
+                                 size_t siglen);
+
+# ifndef OPENSSL_NO_RSA
+__owur int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+                        const unsigned char *ek, int ekl,
+                        const unsigned char *iv, EVP_PKEY *priv);
+__owur int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+
+__owur int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+                        unsigned char **ek, int *ekl, unsigned char *iv,
+                        EVP_PKEY **pubk, int npubk);
+__owur int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+# endif
+
+EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void);
+void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx);
+int EVP_ENCODE_CTX_copy(EVP_ENCODE_CTX *dctx, EVP_ENCODE_CTX *sctx);
+int EVP_ENCODE_CTX_num(EVP_ENCODE_CTX *ctx);
+void EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
+int EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
+                     const unsigned char *in, int inl);
+void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl);
+int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n);
+
+void EVP_DecodeInit(EVP_ENCODE_CTX *ctx);
+int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
+                     const unsigned char *in, int inl);
+int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned
+                    char *out, int *outl);
+int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n);
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  define EVP_CIPHER_CTX_init(c)      EVP_CIPHER_CTX_reset(c)
+#  define EVP_CIPHER_CTX_cleanup(c)   EVP_CIPHER_CTX_reset(c)
+# endif
+EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void);
+int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c);
+void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *c);
+int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen);
+int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad);
+int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
+int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key);
+
+const BIO_METHOD *BIO_f_md(void);
+const BIO_METHOD *BIO_f_base64(void);
+const BIO_METHOD *BIO_f_cipher(void);
+const BIO_METHOD *BIO_f_reliable(void);
+__owur int BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k,
+                          const unsigned char *i, int enc);
+
+const EVP_MD *EVP_md_null(void);
+# ifndef OPENSSL_NO_MD2
+const EVP_MD *EVP_md2(void);
+# endif
+# ifndef OPENSSL_NO_MD4
+const EVP_MD *EVP_md4(void);
+# endif
+# ifndef OPENSSL_NO_MD5
+const EVP_MD *EVP_md5(void);
+const EVP_MD *EVP_md5_sha1(void);
+# endif
+# ifndef OPENSSL_NO_BLAKE2
+const EVP_MD *EVP_blake2b512(void);
+const EVP_MD *EVP_blake2s256(void);
+# endif
+const EVP_MD *EVP_sha1(void);
+const EVP_MD *EVP_sha224(void);
+const EVP_MD *EVP_sha256(void);
+const EVP_MD *EVP_sha384(void);
+const EVP_MD *EVP_sha512(void);
+# ifndef OPENSSL_NO_MDC2
+const EVP_MD *EVP_mdc2(void);
+# endif
+# ifndef OPENSSL_NO_RMD160
+const EVP_MD *EVP_ripemd160(void);
+# endif
+# ifndef OPENSSL_NO_WHIRLPOOL
+const EVP_MD *EVP_whirlpool(void);
+# endif
+const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */
+# ifndef OPENSSL_NO_DES
+const EVP_CIPHER *EVP_des_ecb(void);
+const EVP_CIPHER *EVP_des_ede(void);
+const EVP_CIPHER *EVP_des_ede3(void);
+const EVP_CIPHER *EVP_des_ede_ecb(void);
+const EVP_CIPHER *EVP_des_ede3_ecb(void);
+const EVP_CIPHER *EVP_des_cfb64(void);
+#  define EVP_des_cfb EVP_des_cfb64
+const EVP_CIPHER *EVP_des_cfb1(void);
+const EVP_CIPHER *EVP_des_cfb8(void);
+const EVP_CIPHER *EVP_des_ede_cfb64(void);
+#  define EVP_des_ede_cfb EVP_des_ede_cfb64
+const EVP_CIPHER *EVP_des_ede3_cfb64(void);
+#  define EVP_des_ede3_cfb EVP_des_ede3_cfb64
+const EVP_CIPHER *EVP_des_ede3_cfb1(void);
+const EVP_CIPHER *EVP_des_ede3_cfb8(void);
+const EVP_CIPHER *EVP_des_ofb(void);
+const EVP_CIPHER *EVP_des_ede_ofb(void);
+const EVP_CIPHER *EVP_des_ede3_ofb(void);
+const EVP_CIPHER *EVP_des_cbc(void);
+const EVP_CIPHER *EVP_des_ede_cbc(void);
+const EVP_CIPHER *EVP_des_ede3_cbc(void);
+const EVP_CIPHER *EVP_desx_cbc(void);
+const EVP_CIPHER *EVP_des_ede3_wrap(void);
+/*
+ * This should now be supported through the dev_crypto ENGINE. But also, why
+ * are rc4 and md5 declarations made here inside a "NO_DES" precompiler
+ * branch?
+ */
+# endif
+# ifndef OPENSSL_NO_RC4
+const EVP_CIPHER *EVP_rc4(void);
+const EVP_CIPHER *EVP_rc4_40(void);
+#  ifndef OPENSSL_NO_MD5
+const EVP_CIPHER *EVP_rc4_hmac_md5(void);
+#  endif
+# endif
+# ifndef OPENSSL_NO_IDEA
+const EVP_CIPHER *EVP_idea_ecb(void);
+const EVP_CIPHER *EVP_idea_cfb64(void);
+#  define EVP_idea_cfb EVP_idea_cfb64
+const EVP_CIPHER *EVP_idea_ofb(void);
+const EVP_CIPHER *EVP_idea_cbc(void);
+# endif
+# ifndef OPENSSL_NO_RC2
+const EVP_CIPHER *EVP_rc2_ecb(void);
+const EVP_CIPHER *EVP_rc2_cbc(void);
+const EVP_CIPHER *EVP_rc2_40_cbc(void);
+const EVP_CIPHER *EVP_rc2_64_cbc(void);
+const EVP_CIPHER *EVP_rc2_cfb64(void);
+#  define EVP_rc2_cfb EVP_rc2_cfb64
+const EVP_CIPHER *EVP_rc2_ofb(void);
+# endif
+# ifndef OPENSSL_NO_BF
+const EVP_CIPHER *EVP_bf_ecb(void);
+const EVP_CIPHER *EVP_bf_cbc(void);
+const EVP_CIPHER *EVP_bf_cfb64(void);
+#  define EVP_bf_cfb EVP_bf_cfb64
+const EVP_CIPHER *EVP_bf_ofb(void);
+# endif
+# ifndef OPENSSL_NO_CAST
+const EVP_CIPHER *EVP_cast5_ecb(void);
+const EVP_CIPHER *EVP_cast5_cbc(void);
+const EVP_CIPHER *EVP_cast5_cfb64(void);
+#  define EVP_cast5_cfb EVP_cast5_cfb64
+const EVP_CIPHER *EVP_cast5_ofb(void);
+# endif
+# ifndef OPENSSL_NO_RC5
+const EVP_CIPHER *EVP_rc5_32_12_16_cbc(void);
+const EVP_CIPHER *EVP_rc5_32_12_16_ecb(void);
+const EVP_CIPHER *EVP_rc5_32_12_16_cfb64(void);
+#  define EVP_rc5_32_12_16_cfb EVP_rc5_32_12_16_cfb64
+const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void);
+# endif
+const EVP_CIPHER *EVP_aes_128_ecb(void);
+const EVP_CIPHER *EVP_aes_128_cbc(void);
+const EVP_CIPHER *EVP_aes_128_cfb1(void);
+const EVP_CIPHER *EVP_aes_128_cfb8(void);
+const EVP_CIPHER *EVP_aes_128_cfb128(void);
+# define EVP_aes_128_cfb EVP_aes_128_cfb128
+const EVP_CIPHER *EVP_aes_128_ofb(void);
+const EVP_CIPHER *EVP_aes_128_ctr(void);
+const EVP_CIPHER *EVP_aes_128_ccm(void);
+const EVP_CIPHER *EVP_aes_128_gcm(void);
+const EVP_CIPHER *EVP_aes_128_xts(void);
+const EVP_CIPHER *EVP_aes_128_wrap(void);
+const EVP_CIPHER *EVP_aes_128_wrap_pad(void);
+# ifndef OPENSSL_NO_OCB
+const EVP_CIPHER *EVP_aes_128_ocb(void);
+# endif
+const EVP_CIPHER *EVP_aes_192_ecb(void);
+const EVP_CIPHER *EVP_aes_192_cbc(void);
+const EVP_CIPHER *EVP_aes_192_cfb1(void);
+const EVP_CIPHER *EVP_aes_192_cfb8(void);
+const EVP_CIPHER *EVP_aes_192_cfb128(void);
+# define EVP_aes_192_cfb EVP_aes_192_cfb128
+const EVP_CIPHER *EVP_aes_192_ofb(void);
+const EVP_CIPHER *EVP_aes_192_ctr(void);
+const EVP_CIPHER *EVP_aes_192_ccm(void);
+const EVP_CIPHER *EVP_aes_192_gcm(void);
+const EVP_CIPHER *EVP_aes_192_wrap(void);
+const EVP_CIPHER *EVP_aes_192_wrap_pad(void);
+# ifndef OPENSSL_NO_OCB
+const EVP_CIPHER *EVP_aes_192_ocb(void);
+# endif
+const EVP_CIPHER *EVP_aes_256_ecb(void);
+const EVP_CIPHER *EVP_aes_256_cbc(void);
+const EVP_CIPHER *EVP_aes_256_cfb1(void);
+const EVP_CIPHER *EVP_aes_256_cfb8(void);
+const EVP_CIPHER *EVP_aes_256_cfb128(void);
+# define EVP_aes_256_cfb EVP_aes_256_cfb128
+const EVP_CIPHER *EVP_aes_256_ofb(void);
+const EVP_CIPHER *EVP_aes_256_ctr(void);
+const EVP_CIPHER *EVP_aes_256_ccm(void);
+const EVP_CIPHER *EVP_aes_256_gcm(void);
+const EVP_CIPHER *EVP_aes_256_xts(void);
+const EVP_CIPHER *EVP_aes_256_wrap(void);
+const EVP_CIPHER *EVP_aes_256_wrap_pad(void);
+# ifndef OPENSSL_NO_OCB
+const EVP_CIPHER *EVP_aes_256_ocb(void);
+# endif
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void);
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void);
+const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void);
+const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void);
+# ifndef OPENSSL_NO_CAMELLIA
+const EVP_CIPHER *EVP_camellia_128_ecb(void);
+const EVP_CIPHER *EVP_camellia_128_cbc(void);
+const EVP_CIPHER *EVP_camellia_128_cfb1(void);
+const EVP_CIPHER *EVP_camellia_128_cfb8(void);
+const EVP_CIPHER *EVP_camellia_128_cfb128(void);
+#  define EVP_camellia_128_cfb EVP_camellia_128_cfb128
+const EVP_CIPHER *EVP_camellia_128_ofb(void);
+const EVP_CIPHER *EVP_camellia_128_ctr(void);
+const EVP_CIPHER *EVP_camellia_192_ecb(void);
+const EVP_CIPHER *EVP_camellia_192_cbc(void);
+const EVP_CIPHER *EVP_camellia_192_cfb1(void);
+const EVP_CIPHER *EVP_camellia_192_cfb8(void);
+const EVP_CIPHER *EVP_camellia_192_cfb128(void);
+#  define EVP_camellia_192_cfb EVP_camellia_192_cfb128
+const EVP_CIPHER *EVP_camellia_192_ofb(void);
+const EVP_CIPHER *EVP_camellia_192_ctr(void);
+const EVP_CIPHER *EVP_camellia_256_ecb(void);
+const EVP_CIPHER *EVP_camellia_256_cbc(void);
+const EVP_CIPHER *EVP_camellia_256_cfb1(void);
+const EVP_CIPHER *EVP_camellia_256_cfb8(void);
+const EVP_CIPHER *EVP_camellia_256_cfb128(void);
+#  define EVP_camellia_256_cfb EVP_camellia_256_cfb128
+const EVP_CIPHER *EVP_camellia_256_ofb(void);
+const EVP_CIPHER *EVP_camellia_256_ctr(void);
+# endif
+# ifndef OPENSSL_NO_CHACHA
+const EVP_CIPHER *EVP_chacha20(void);
+#  ifndef OPENSSL_NO_POLY1305
+const EVP_CIPHER *EVP_chacha20_poly1305(void);
+#  endif
+# endif
+
+# ifndef OPENSSL_NO_SEED
+const EVP_CIPHER *EVP_seed_ecb(void);
+const EVP_CIPHER *EVP_seed_cbc(void);
+const EVP_CIPHER *EVP_seed_cfb128(void);
+#  define EVP_seed_cfb EVP_seed_cfb128
+const EVP_CIPHER *EVP_seed_ofb(void);
+# endif
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  define OPENSSL_add_all_algorithms_conf() \
+    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
+                        | OPENSSL_INIT_ADD_ALL_DIGESTS \
+                        | OPENSSL_INIT_LOAD_CONFIG, NULL)
+#  define OPENSSL_add_all_algorithms_noconf() \
+    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
+                        | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL)
+
+#  ifdef OPENSSL_LOAD_CONF
+#   define OpenSSL_add_all_algorithms() \
+    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
+                        | OPENSSL_INIT_ADD_ALL_DIGESTS \
+                        | OPENSSL_INIT_LOAD_CONFIG, NULL)
+#  else
+#   define OpenSSL_add_all_algorithms() \
+    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
+                        | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL)
+#  endif
+
+#  define OpenSSL_add_all_ciphers() \
+    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL)
+#  define OpenSSL_add_all_digests() \
+    OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL)
+
+#  define EVP_cleanup() while(0) continue
+# endif
+
+int EVP_add_cipher(const EVP_CIPHER *cipher);
+int EVP_add_digest(const EVP_MD *digest);
+
+const EVP_CIPHER *EVP_get_cipherbyname(const char *name);
+const EVP_MD *EVP_get_digestbyname(const char *name);
+
+void EVP_CIPHER_do_all(void (*fn) (const EVP_CIPHER *ciph,
+                                   const char *from, const char *to, void *x),
+                       void *arg);
+void EVP_CIPHER_do_all_sorted(void (*fn)
+                               (const EVP_CIPHER *ciph, const char *from,
+                                const char *to, void *x), void *arg);
+
+void EVP_MD_do_all(void (*fn) (const EVP_MD *ciph,
+                               const char *from, const char *to, void *x),
+                   void *arg);
+void EVP_MD_do_all_sorted(void (*fn)
+                           (const EVP_MD *ciph, const char *from,
+                            const char *to, void *x), void *arg);
+
+int EVP_PKEY_decrypt_old(unsigned char *dec_key,
+                         const unsigned char *enc_key, int enc_key_len,
+                         EVP_PKEY *private_key);
+int EVP_PKEY_encrypt_old(unsigned char *enc_key,
+                         const unsigned char *key, int key_len,
+                         EVP_PKEY *pub_key);
+int EVP_PKEY_type(int type);
+int EVP_PKEY_id(const EVP_PKEY *pkey);
+int EVP_PKEY_base_id(const EVP_PKEY *pkey);
+int EVP_PKEY_bits(const EVP_PKEY *pkey);
+int EVP_PKEY_security_bits(const EVP_PKEY *pkey);
+int EVP_PKEY_size(EVP_PKEY *pkey);
+int EVP_PKEY_set_type(EVP_PKEY *pkey, int type);
+int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len);
+int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key);
+void *EVP_PKEY_get0(const EVP_PKEY *pkey);
+const unsigned char *EVP_PKEY_get0_hmac(const EVP_PKEY *pkey, size_t *len);
+
+# ifndef OPENSSL_NO_RSA
+struct rsa_st;
+int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key);
+struct rsa_st *EVP_PKEY_get0_RSA(EVP_PKEY *pkey);
+struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey);
+# endif
+# ifndef OPENSSL_NO_DSA
+struct dsa_st;
+int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, struct dsa_st *key);
+struct dsa_st *EVP_PKEY_get0_DSA(EVP_PKEY *pkey);
+struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey);
+# endif
+# ifndef OPENSSL_NO_DH
+struct dh_st;
+int EVP_PKEY_set1_DH(EVP_PKEY *pkey, struct dh_st *key);
+struct dh_st *EVP_PKEY_get0_DH(EVP_PKEY *pkey);
+struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey);
+# endif
+# ifndef OPENSSL_NO_EC
+struct ec_key_st;
+int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key);
+struct ec_key_st *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey);
+struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);
+# endif
+
+EVP_PKEY *EVP_PKEY_new(void);
+int EVP_PKEY_up_ref(EVP_PKEY *pkey);
+void EVP_PKEY_free(EVP_PKEY *pkey);
+
+EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp,
+                        long length);
+int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp);
+
+EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
+                         long length);
+EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
+                             long length);
+int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp);
+
+int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from);
+int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey);
+int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode);
+int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b);
+
+int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
+
+int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
+                          int indent, ASN1_PCTX *pctx);
+int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
+                           int indent, ASN1_PCTX *pctx);
+int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
+                          int indent, ASN1_PCTX *pctx);
+
+int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);
+
+int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey,
+                                   const unsigned char *pt, size_t ptlen);
+size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt);
+
+int EVP_CIPHER_type(const EVP_CIPHER *ctx);
+
+/* calls methods */
+int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+
+/* These are used by EVP_CIPHER methods */
+int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+
+/* PKCS5 password based encryption */
+int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+                       ASN1_TYPE *param, const EVP_CIPHER *cipher,
+                       const EVP_MD *md, int en_de);
+int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
+                           const unsigned char *salt, int saltlen, int iter,
+                           int keylen, unsigned char *out);
+int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
+                      const unsigned char *salt, int saltlen, int iter,
+                      const EVP_MD *digest, int keylen, unsigned char *out);
+int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+                          ASN1_TYPE *param, const EVP_CIPHER *cipher,
+                          const EVP_MD *md, int en_de);
+
+#ifndef OPENSSL_NO_SCRYPT
+int EVP_PBE_scrypt(const char *pass, size_t passlen,
+                   const unsigned char *salt, size_t saltlen,
+                   uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem,
+                   unsigned char *key, size_t keylen);
+
+int PKCS5_v2_scrypt_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
+                             int passlen, ASN1_TYPE *param,
+                             const EVP_CIPHER *c, const EVP_MD *md, int en_de);
+#endif
+
+void PKCS5_PBE_add(void);
+
+int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
+                       ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de);
+
+/* PBE type */
+
+/* Can appear as the outermost AlgorithmIdentifier */
+# define EVP_PBE_TYPE_OUTER      0x0
+/* Is an PRF type OID */
+# define EVP_PBE_TYPE_PRF        0x1
+/* Is a PKCS#5 v2.0 KDF */
+# define EVP_PBE_TYPE_KDF        0x2
+
+int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid,
+                         int md_nid, EVP_PBE_KEYGEN *keygen);
+int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
+                    EVP_PBE_KEYGEN *keygen);
+int EVP_PBE_find(int type, int pbe_nid, int *pcnid, int *pmnid,
+                 EVP_PBE_KEYGEN **pkeygen);
+void EVP_PBE_cleanup(void);
+int EVP_PBE_get(int *ptype, int *ppbe_nid, size_t num);
+
+# define ASN1_PKEY_ALIAS         0x1
+# define ASN1_PKEY_DYNAMIC       0x2
+# define ASN1_PKEY_SIGPARAM_NULL 0x4
+
+# define ASN1_PKEY_CTRL_PKCS7_SIGN       0x1
+# define ASN1_PKEY_CTRL_PKCS7_ENCRYPT    0x2
+# define ASN1_PKEY_CTRL_DEFAULT_MD_NID   0x3
+# define ASN1_PKEY_CTRL_CMS_SIGN         0x5
+# define ASN1_PKEY_CTRL_CMS_ENVELOPE     0x7
+# define ASN1_PKEY_CTRL_CMS_RI_TYPE      0x8
+
+# define ASN1_PKEY_CTRL_SET1_TLS_ENCPT   0x9
+# define ASN1_PKEY_CTRL_GET1_TLS_ENCPT   0xa
+
+int EVP_PKEY_asn1_get_count(void);
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx);
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type);
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
+                                                   const char *str, int len);
+int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth);
+int EVP_PKEY_asn1_add_alias(int to, int from);
+int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id,
+                            int *ppkey_flags, const char **pinfo,
+                            const char **ppem_str,
+                            const EVP_PKEY_ASN1_METHOD *ameth);
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(const EVP_PKEY *pkey);
+EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags,
+                                        const char *pem_str,
+                                        const char *info);
+void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
+                        const EVP_PKEY_ASN1_METHOD *src);
+void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth);
+void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
+                              int (*pub_decode) (EVP_PKEY *pk,
+                                                 X509_PUBKEY *pub),
+                              int (*pub_encode) (X509_PUBKEY *pub,
+                                                 const EVP_PKEY *pk),
+                              int (*pub_cmp) (const EVP_PKEY *a,
+                                              const EVP_PKEY *b),
+                              int (*pub_print) (BIO *out,
+                                                const EVP_PKEY *pkey,
+                                                int indent, ASN1_PCTX *pctx),
+                              int (*pkey_size) (const EVP_PKEY *pk),
+                              int (*pkey_bits) (const EVP_PKEY *pk));
+void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
+                               int (*priv_decode) (EVP_PKEY *pk,
+                                                   const PKCS8_PRIV_KEY_INFO
+                                                   *p8inf),
+                               int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8,
+                                                   const EVP_PKEY *pk),
+                               int (*priv_print) (BIO *out,
+                                                  const EVP_PKEY *pkey,
+                                                  int indent,
+                                                  ASN1_PCTX *pctx));
+void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
+                             int (*param_decode) (EVP_PKEY *pkey,
+                                                  const unsigned char **pder,
+                                                  int derlen),
+                             int (*param_encode) (const EVP_PKEY *pkey,
+                                                  unsigned char **pder),
+                             int (*param_missing) (const EVP_PKEY *pk),
+                             int (*param_copy) (EVP_PKEY *to,
+                                                const EVP_PKEY *from),
+                             int (*param_cmp) (const EVP_PKEY *a,
+                                               const EVP_PKEY *b),
+                             int (*param_print) (BIO *out,
+                                                 const EVP_PKEY *pkey,
+                                                 int indent,
+                                                 ASN1_PCTX *pctx));
+
+void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
+                            void (*pkey_free) (EVP_PKEY *pkey));
+void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
+                            int (*pkey_ctrl) (EVP_PKEY *pkey, int op,
+                                              long arg1, void *arg2));
+void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth,
+                            int (*item_verify) (EVP_MD_CTX *ctx,
+                                                const ASN1_ITEM *it,
+                                                void *asn,
+                                                X509_ALGOR *a,
+                                                ASN1_BIT_STRING *sig,
+                                                EVP_PKEY *pkey),
+                            int (*item_sign) (EVP_MD_CTX *ctx,
+                                              const ASN1_ITEM *it,
+                                              void *asn,
+                                              X509_ALGOR *alg1,
+                                              X509_ALGOR *alg2,
+                                              ASN1_BIT_STRING *sig));
+
+void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth,
+                                     int (*pkey_security_bits) (const EVP_PKEY
+                                                                *pk));
+
+# define EVP_PKEY_OP_UNDEFINED           0
+# define EVP_PKEY_OP_PARAMGEN            (1<<1)
+# define EVP_PKEY_OP_KEYGEN              (1<<2)
+# define EVP_PKEY_OP_SIGN                (1<<3)
+# define EVP_PKEY_OP_VERIFY              (1<<4)
+# define EVP_PKEY_OP_VERIFYRECOVER       (1<<5)
+# define EVP_PKEY_OP_SIGNCTX             (1<<6)
+# define EVP_PKEY_OP_VERIFYCTX           (1<<7)
+# define EVP_PKEY_OP_ENCRYPT             (1<<8)
+# define EVP_PKEY_OP_DECRYPT             (1<<9)
+# define EVP_PKEY_OP_DERIVE              (1<<10)
+
+# define EVP_PKEY_OP_TYPE_SIG    \
+        (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \
+                | EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX)
+
+# define EVP_PKEY_OP_TYPE_CRYPT \
+        (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT)
+
+# define EVP_PKEY_OP_TYPE_NOGEN \
+        (EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_DERIVE)
+
+# define EVP_PKEY_OP_TYPE_GEN \
+                (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN)
+
+# define  EVP_PKEY_CTX_set_signature_md(ctx, md) \
+                EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,  \
+                                        EVP_PKEY_CTRL_MD, 0, (void *)md)
+
+# define  EVP_PKEY_CTX_get_signature_md(ctx, pmd)        \
+                EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG,  \
+                                        EVP_PKEY_CTRL_GET_MD, 0, (void *)pmd)
+
+# define  EVP_PKEY_CTX_set_mac_key(ctx, key, len)        \
+                EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_KEYGEN,  \
+                                  EVP_PKEY_CTRL_SET_MAC_KEY, len, (void *)key)
+
+# define EVP_PKEY_CTRL_MD                1
+# define EVP_PKEY_CTRL_PEER_KEY          2
+
+# define EVP_PKEY_CTRL_PKCS7_ENCRYPT     3
+# define EVP_PKEY_CTRL_PKCS7_DECRYPT     4
+
+# define EVP_PKEY_CTRL_PKCS7_SIGN        5
+
+# define EVP_PKEY_CTRL_SET_MAC_KEY       6
+
+# define EVP_PKEY_CTRL_DIGESTINIT        7
+
+/* Used by GOST key encryption in TLS */
+# define EVP_PKEY_CTRL_SET_IV            8
+
+# define EVP_PKEY_CTRL_CMS_ENCRYPT       9
+# define EVP_PKEY_CTRL_CMS_DECRYPT       10
+# define EVP_PKEY_CTRL_CMS_SIGN          11
+
+# define EVP_PKEY_CTRL_CIPHER            12
+
+# define EVP_PKEY_CTRL_GET_MD            13
+
+# define EVP_PKEY_ALG_CTRL               0x1000
+
+# define EVP_PKEY_FLAG_AUTOARGLEN        2
+/*
+ * Method handles all operations: don't assume any digest related defaults.
+ */
+# define EVP_PKEY_FLAG_SIGCTX_CUSTOM     4
+
+const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type);
+EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags);
+void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags,
+                             const EVP_PKEY_METHOD *meth);
+void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src);
+void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth);
+int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth);
+
+EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
+EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
+EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx);
+void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
+                      int cmd, int p1, void *p2);
+int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
+                          const char *value);
+
+int EVP_PKEY_CTX_str2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *str);
+int EVP_PKEY_CTX_hex2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *hex);
+
+int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx);
+void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen);
+
+EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
+                               const unsigned char *key, int keylen);
+
+void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data);
+void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx);
+EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx);
+
+EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx);
+
+void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data);
+void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
+                  unsigned char *sig, size_t *siglen,
+                  const unsigned char *tbs, size_t tbslen);
+int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_verify(EVP_PKEY_CTX *ctx,
+                    const unsigned char *sig, size_t siglen,
+                    const unsigned char *tbs, size_t tbslen);
+int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
+                            unsigned char *rout, size_t *routlen,
+                            const unsigned char *sig, size_t siglen);
+int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
+                     unsigned char *out, size_t *outlen,
+                     const unsigned char *in, size_t inlen);
+int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
+                     unsigned char *out, size_t *outlen,
+                     const unsigned char *in, size_t inlen);
+
+int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer);
+int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
+
+typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
+int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
+
+void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb);
+EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx);
+
+int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx);
+
+void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
+                            int (*init) (EVP_PKEY_CTX *ctx));
+
+void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
+                            int (*copy) (EVP_PKEY_CTX *dst,
+                                         EVP_PKEY_CTX *src));
+
+void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
+                               void (*cleanup) (EVP_PKEY_CTX *ctx));
+
+void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
+                                int (*paramgen_init) (EVP_PKEY_CTX *ctx),
+                                int (*paramgen) (EVP_PKEY_CTX *ctx,
+                                                 EVP_PKEY *pkey));
+
+void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
+                              int (*keygen_init) (EVP_PKEY_CTX *ctx),
+                              int (*keygen) (EVP_PKEY_CTX *ctx,
+                                             EVP_PKEY *pkey));
+
+void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
+                            int (*sign_init) (EVP_PKEY_CTX *ctx),
+                            int (*sign) (EVP_PKEY_CTX *ctx,
+                                         unsigned char *sig, size_t *siglen,
+                                         const unsigned char *tbs,
+                                         size_t tbslen));
+
+void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
+                              int (*verify_init) (EVP_PKEY_CTX *ctx),
+                              int (*verify) (EVP_PKEY_CTX *ctx,
+                                             const unsigned char *sig,
+                                             size_t siglen,
+                                             const unsigned char *tbs,
+                                             size_t tbslen));
+
+void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
+                                      int (*verify_recover_init) (EVP_PKEY_CTX
+                                                                  *ctx),
+                                      int (*verify_recover) (EVP_PKEY_CTX
+                                                             *ctx,
+                                                             unsigned char
+                                                             *sig,
+                                                             size_t *siglen,
+                                                             const unsigned
+                                                             char *tbs,
+                                                             size_t tbslen));
+
+void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
+                               int (*signctx_init) (EVP_PKEY_CTX *ctx,
+                                                    EVP_MD_CTX *mctx),
+                               int (*signctx) (EVP_PKEY_CTX *ctx,
+                                               unsigned char *sig,
+                                               size_t *siglen,
+                                               EVP_MD_CTX *mctx));
+
+void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
+                                 int (*verifyctx_init) (EVP_PKEY_CTX *ctx,
+                                                        EVP_MD_CTX *mctx),
+                                 int (*verifyctx) (EVP_PKEY_CTX *ctx,
+                                                   const unsigned char *sig,
+                                                   int siglen,
+                                                   EVP_MD_CTX *mctx));
+
+void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
+                               int (*encrypt_init) (EVP_PKEY_CTX *ctx),
+                               int (*encryptfn) (EVP_PKEY_CTX *ctx,
+                                                 unsigned char *out,
+                                                 size_t *outlen,
+                                                 const unsigned char *in,
+                                                 size_t inlen));
+
+void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
+                               int (*decrypt_init) (EVP_PKEY_CTX *ctx),
+                               int (*decrypt) (EVP_PKEY_CTX *ctx,
+                                               unsigned char *out,
+                                               size_t *outlen,
+                                               const unsigned char *in,
+                                               size_t inlen));
+
+void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
+                              int (*derive_init) (EVP_PKEY_CTX *ctx),
+                              int (*derive) (EVP_PKEY_CTX *ctx,
+                                             unsigned char *key,
+                                             size_t *keylen));
+
+void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
+                            int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1,
+                                         void *p2),
+                            int (*ctrl_str) (EVP_PKEY_CTX *ctx,
+                                             const char *type,
+                                             const char *value));
+
+void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth,
+                            int (**pinit) (EVP_PKEY_CTX *ctx));
+
+void EVP_PKEY_meth_get_copy(EVP_PKEY_METHOD *pmeth,
+                            int (**pcopy) (EVP_PKEY_CTX *dst,
+                                           EVP_PKEY_CTX *src));
+
+void EVP_PKEY_meth_get_cleanup(EVP_PKEY_METHOD *pmeth,
+                               void (**pcleanup) (EVP_PKEY_CTX *ctx));
+
+void EVP_PKEY_meth_get_paramgen(EVP_PKEY_METHOD *pmeth,
+                                int (**pparamgen_init) (EVP_PKEY_CTX *ctx),
+                                int (**pparamgen) (EVP_PKEY_CTX *ctx,
+                                                   EVP_PKEY *pkey));
+
+void EVP_PKEY_meth_get_keygen(EVP_PKEY_METHOD *pmeth,
+                              int (**pkeygen_init) (EVP_PKEY_CTX *ctx),
+                              int (**pkeygen) (EVP_PKEY_CTX *ctx,
+                                               EVP_PKEY *pkey));
+
+void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth,
+                            int (**psign_init) (EVP_PKEY_CTX *ctx),
+                            int (**psign) (EVP_PKEY_CTX *ctx,
+                                           unsigned char *sig, size_t *siglen,
+                                           const unsigned char *tbs,
+                                           size_t tbslen));
+
+void EVP_PKEY_meth_get_verify(EVP_PKEY_METHOD *pmeth,
+                              int (**pverify_init) (EVP_PKEY_CTX *ctx),
+                              int (**pverify) (EVP_PKEY_CTX *ctx,
+                                               const unsigned char *sig,
+                                               size_t siglen,
+                                               const unsigned char *tbs,
+                                               size_t tbslen));
+
+void EVP_PKEY_meth_get_verify_recover(EVP_PKEY_METHOD *pmeth,
+                                      int (**pverify_recover_init) (EVP_PKEY_CTX
+                                                                    *ctx),
+                                      int (**pverify_recover) (EVP_PKEY_CTX
+                                                               *ctx,
+                                                               unsigned char
+                                                               *sig,
+                                                               size_t *siglen,
+                                                               const unsigned
+                                                               char *tbs,
+                                                               size_t tbslen));
+
+void EVP_PKEY_meth_get_signctx(EVP_PKEY_METHOD *pmeth,
+                               int (**psignctx_init) (EVP_PKEY_CTX *ctx,
+                                                      EVP_MD_CTX *mctx),
+                               int (**psignctx) (EVP_PKEY_CTX *ctx,
+                                                 unsigned char *sig,
+                                                 size_t *siglen,
+                                                 EVP_MD_CTX *mctx));
+
+void EVP_PKEY_meth_get_verifyctx(EVP_PKEY_METHOD *pmeth,
+                                 int (**pverifyctx_init) (EVP_PKEY_CTX *ctx,
+                                                          EVP_MD_CTX *mctx),
+                                 int (**pverifyctx) (EVP_PKEY_CTX *ctx,
+                                                     const unsigned char *sig,
+                                                     int siglen,
+                                                     EVP_MD_CTX *mctx));
+
+void EVP_PKEY_meth_get_encrypt(EVP_PKEY_METHOD *pmeth,
+                               int (**pencrypt_init) (EVP_PKEY_CTX *ctx),
+                               int (**pencryptfn) (EVP_PKEY_CTX *ctx,
+                                                   unsigned char *out,
+                                                   size_t *outlen,
+                                                   const unsigned char *in,
+                                                   size_t inlen));
+
+void EVP_PKEY_meth_get_decrypt(EVP_PKEY_METHOD *pmeth,
+                               int (**pdecrypt_init) (EVP_PKEY_CTX *ctx),
+                               int (**pdecrypt) (EVP_PKEY_CTX *ctx,
+                                                 unsigned char *out,
+                                                 size_t *outlen,
+                                                 const unsigned char *in,
+                                                 size_t inlen));
+
+void EVP_PKEY_meth_get_derive(EVP_PKEY_METHOD *pmeth,
+                              int (**pderive_init) (EVP_PKEY_CTX *ctx),
+                              int (**pderive) (EVP_PKEY_CTX *ctx,
+                                               unsigned char *key,
+                                               size_t *keylen));
+
+void EVP_PKEY_meth_get_ctrl(EVP_PKEY_METHOD *pmeth,
+                            int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1,
+                                           void *p2),
+                            int (**pctrl_str) (EVP_PKEY_CTX *ctx,
+                                               const char *type,
+                                               const char *value));
+
+void EVP_add_alg_module(void);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_EVP_strings(void);
+
+/* Error codes for the EVP functions. */
+
+/* Function codes. */
+# define EVP_F_AESNI_INIT_KEY                             165
+# define EVP_F_AES_INIT_KEY                               133
+# define EVP_F_AES_OCB_CIPHER                             169
+# define EVP_F_AES_T4_INIT_KEY                            178
+# define EVP_F_AES_WRAP_CIPHER                            170
+# define EVP_F_ALG_MODULE_INIT                            177
+# define EVP_F_CAMELLIA_INIT_KEY                          159
+# define EVP_F_CHACHA20_POLY1305_CTRL                     182
+# define EVP_F_CMLL_T4_INIT_KEY                           179
+# define EVP_F_DES_EDE3_WRAP_CIPHER                       171
+# define EVP_F_DO_SIGVER_INIT                             161
+# define EVP_F_EVP_CIPHERINIT_EX                          123
+# define EVP_F_EVP_CIPHER_CTX_COPY                        163
+# define EVP_F_EVP_CIPHER_CTX_CTRL                        124
+# define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH              122
+# define EVP_F_EVP_DECRYPTFINAL_EX                        101
+# define EVP_F_EVP_DECRYPTUPDATE                          166
+# define EVP_F_EVP_DIGESTINIT_EX                          128
+# define EVP_F_EVP_ENCRYPTFINAL_EX                        127
+# define EVP_F_EVP_ENCRYPTUPDATE                          167
+# define EVP_F_EVP_MD_CTX_COPY_EX                         110
+# define EVP_F_EVP_MD_SIZE                                162
+# define EVP_F_EVP_OPENINIT                               102
+# define EVP_F_EVP_PBE_ALG_ADD                            115
+# define EVP_F_EVP_PBE_ALG_ADD_TYPE                       160
+# define EVP_F_EVP_PBE_CIPHERINIT                         116
+# define EVP_F_EVP_PBE_SCRYPT                             181
+# define EVP_F_EVP_PKCS82PKEY                             111
+# define EVP_F_EVP_PKEY2PKCS8                             113
+# define EVP_F_EVP_PKEY_COPY_PARAMETERS                   103
+# define EVP_F_EVP_PKEY_CTX_CTRL                          137
+# define EVP_F_EVP_PKEY_CTX_CTRL_STR                      150
+# define EVP_F_EVP_PKEY_CTX_DUP                           156
+# define EVP_F_EVP_PKEY_DECRYPT                           104
+# define EVP_F_EVP_PKEY_DECRYPT_INIT                      138
+# define EVP_F_EVP_PKEY_DECRYPT_OLD                       151
+# define EVP_F_EVP_PKEY_DERIVE                            153
+# define EVP_F_EVP_PKEY_DERIVE_INIT                       154
+# define EVP_F_EVP_PKEY_DERIVE_SET_PEER                   155
+# define EVP_F_EVP_PKEY_ENCRYPT                           105
+# define EVP_F_EVP_PKEY_ENCRYPT_INIT                      139
+# define EVP_F_EVP_PKEY_ENCRYPT_OLD                       152
+# define EVP_F_EVP_PKEY_GET0_DH                           119
+# define EVP_F_EVP_PKEY_GET0_DSA                          120
+# define EVP_F_EVP_PKEY_GET0_EC_KEY                       131
+# define EVP_F_EVP_PKEY_GET0_HMAC                         183
+# define EVP_F_EVP_PKEY_GET0_RSA                          121
+# define EVP_F_EVP_PKEY_KEYGEN                            146
+# define EVP_F_EVP_PKEY_KEYGEN_INIT                       147
+# define EVP_F_EVP_PKEY_NEW                               106
+# define EVP_F_EVP_PKEY_PARAMGEN                          148
+# define EVP_F_EVP_PKEY_PARAMGEN_INIT                     149
+# define EVP_F_EVP_PKEY_SIGN                              140
+# define EVP_F_EVP_PKEY_SIGN_INIT                         141
+# define EVP_F_EVP_PKEY_VERIFY                            142
+# define EVP_F_EVP_PKEY_VERIFY_INIT                       143
+# define EVP_F_EVP_PKEY_VERIFY_RECOVER                    144
+# define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT               145
+# define EVP_F_EVP_SIGNFINAL                              107
+# define EVP_F_EVP_VERIFYFINAL                            108
+# define EVP_F_INT_CTX_NEW                                157
+# define EVP_F_PKCS5_PBE_KEYIVGEN                         117
+# define EVP_F_PKCS5_V2_PBE_KEYIVGEN                      118
+# define EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN                   164
+# define EVP_F_PKCS5_V2_SCRYPT_KEYIVGEN                   180
+# define EVP_F_PKEY_SET_TYPE                              158
+# define EVP_F_RC2_MAGIC_TO_METH                          109
+# define EVP_F_RC5_CTRL                                   125
+
+/* Reason codes. */
+# define EVP_R_AES_KEY_SETUP_FAILED                       143
+# define EVP_R_BAD_DECRYPT                                100
+# define EVP_R_BUFFER_TOO_SMALL                           155
+# define EVP_R_CAMELLIA_KEY_SETUP_FAILED                  157
+# define EVP_R_CIPHER_PARAMETER_ERROR                     122
+# define EVP_R_COMMAND_NOT_SUPPORTED                      147
+# define EVP_R_COPY_ERROR                                 173
+# define EVP_R_CTRL_NOT_IMPLEMENTED                       132
+# define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED             133
+# define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH          138
+# define EVP_R_DECODE_ERROR                               114
+# define EVP_R_DIFFERENT_KEY_TYPES                        101
+# define EVP_R_DIFFERENT_PARAMETERS                       153
+# define EVP_R_ERROR_LOADING_SECTION                      165
+# define EVP_R_ERROR_SETTING_FIPS_MODE                    166
+# define EVP_R_EXPECTING_AN_HMAC_KEY                      174
+# define EVP_R_EXPECTING_AN_RSA_KEY                       127
+# define EVP_R_EXPECTING_A_DH_KEY                         128
+# define EVP_R_EXPECTING_A_DSA_KEY                        129
+# define EVP_R_EXPECTING_A_EC_KEY                         142
+# define EVP_R_FIPS_MODE_NOT_SUPPORTED                    167
+# define EVP_R_ILLEGAL_SCRYPT_PARAMETERS                  171
+# define EVP_R_INITIALIZATION_ERROR                       134
+# define EVP_R_INPUT_NOT_INITIALIZED                      111
+# define EVP_R_INVALID_DIGEST                             152
+# define EVP_R_INVALID_FIPS_MODE                          168
+# define EVP_R_INVALID_KEY                                163
+# define EVP_R_INVALID_KEY_LENGTH                         130
+# define EVP_R_INVALID_OPERATION                          148
+# define EVP_R_KEYGEN_FAILURE                             120
+# define EVP_R_MEMORY_LIMIT_EXCEEDED                      172
+# define EVP_R_MESSAGE_DIGEST_IS_NULL                     159
+# define EVP_R_METHOD_NOT_SUPPORTED                       144
+# define EVP_R_MISSING_PARAMETERS                         103
+# define EVP_R_NO_CIPHER_SET                              131
+# define EVP_R_NO_DEFAULT_DIGEST                          158
+# define EVP_R_NO_DIGEST_SET                              139
+# define EVP_R_NO_KEY_SET                                 154
+# define EVP_R_NO_OPERATION_SET                           149
+# define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE   150
+# define EVP_R_OPERATON_NOT_INITIALIZED                   151
+# define EVP_R_PARTIALLY_OVERLAPPING                      162
+# define EVP_R_PRIVATE_KEY_DECODE_ERROR                   145
+# define EVP_R_PRIVATE_KEY_ENCODE_ERROR                   146
+# define EVP_R_PUBLIC_KEY_NOT_RSA                         106
+# define EVP_R_UNKNOWN_CIPHER                             160
+# define EVP_R_UNKNOWN_DIGEST                             161
+# define EVP_R_UNKNOWN_OPTION                             169
+# define EVP_R_UNKNOWN_PBE_ALGORITHM                      121
+# define EVP_R_UNSUPPORTED_ALGORITHM                      156
+# define EVP_R_UNSUPPORTED_CIPHER                         107
+# define EVP_R_UNSUPPORTED_KEYLENGTH                      123
+# define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION        124
+# define EVP_R_UNSUPPORTED_KEY_SIZE                       108
+# define EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS               135
+# define EVP_R_UNSUPPORTED_PRF                            125
+# define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM          118
+# define EVP_R_UNSUPPORTED_SALT_TYPE                      126
+# define EVP_R_WRAP_MODE_NOT_ALLOWED                      170
+# define EVP_R_WRONG_FINAL_BLOCK_LENGTH                   109
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/hmac.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/hmac.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/hmac.h	(revision 331)
@@ -0,0 +1,49 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_HMAC_H
+# define HEADER_HMAC_H
+
+# include <openssl/opensslconf.h>
+
+# include <openssl/evp.h>
+
+# define HMAC_MAX_MD_CBLOCK      128/* largest known is SHA512 */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+size_t HMAC_size(const HMAC_CTX *e);
+HMAC_CTX *HMAC_CTX_new(void);
+int HMAC_CTX_reset(HMAC_CTX *ctx);
+void HMAC_CTX_free(HMAC_CTX *ctx);
+
+DEPRECATEDIN_1_1_0(__owur int HMAC_Init(HMAC_CTX *ctx, const void *key, int len,
+                     const EVP_MD *md))
+
+/*__owur*/ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
+                            const EVP_MD *md, ENGINE *impl);
+/*__owur*/ int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data,
+                           size_t len);
+/*__owur*/ int HMAC_Final(HMAC_CTX *ctx, unsigned char *md,
+                          unsigned int *len);
+unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
+                    const unsigned char *d, size_t n, unsigned char *md,
+                    unsigned int *md_len);
+__owur int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx);
+
+void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags);
+const EVP_MD *HMAC_CTX_get_md(const HMAC_CTX *ctx);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/idea.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/idea.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/idea.h	(revision 331)
@@ -0,0 +1,64 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_IDEA_H
+# define HEADER_IDEA_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_IDEA
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+typedef unsigned int IDEA_INT;
+
+# define IDEA_ENCRYPT    1
+# define IDEA_DECRYPT    0
+
+# define IDEA_BLOCK      8
+# define IDEA_KEY_LENGTH 16
+
+typedef struct idea_key_st {
+    IDEA_INT data[9][6];
+} IDEA_KEY_SCHEDULE;
+
+const char *IDEA_options(void);
+void IDEA_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                      IDEA_KEY_SCHEDULE *ks);
+void IDEA_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks);
+void IDEA_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk);
+void IDEA_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                      long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,
+                      int enc);
+void IDEA_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                        long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,
+                        int *num, int enc);
+void IDEA_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+                        long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,
+                        int *num);
+void IDEA_encrypt(unsigned long *in, IDEA_KEY_SCHEDULE *ks);
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  define idea_options          IDEA_options
+#  define idea_ecb_encrypt      IDEA_ecb_encrypt
+#  define idea_set_encrypt_key  IDEA_set_encrypt_key
+#  define idea_set_decrypt_key  IDEA_set_decrypt_key
+#  define idea_cbc_encrypt      IDEA_cbc_encrypt
+#  define idea_cfb64_encrypt    IDEA_cfb64_encrypt
+#  define idea_ofb64_encrypt    IDEA_ofb64_encrypt
+#  define idea_encrypt          IDEA_encrypt
+# endif
+
+# ifdef  __cplusplus
+}
+# endif
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/kdf.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/kdf.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/kdf.h	(revision 331)
@@ -0,0 +1,75 @@
+/*
+ * 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
+ */
+
+#ifndef HEADER_KDF_H
+# define HEADER_KDF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# define EVP_PKEY_CTRL_TLS_MD       (EVP_PKEY_ALG_CTRL)
+# define EVP_PKEY_CTRL_TLS_SECRET   (EVP_PKEY_ALG_CTRL + 1)
+# define EVP_PKEY_CTRL_TLS_SEED     (EVP_PKEY_ALG_CTRL + 2)
+# define EVP_PKEY_CTRL_HKDF_MD      (EVP_PKEY_ALG_CTRL + 3)
+# define EVP_PKEY_CTRL_HKDF_SALT    (EVP_PKEY_ALG_CTRL + 4)
+# define EVP_PKEY_CTRL_HKDF_KEY     (EVP_PKEY_ALG_CTRL + 5)
+# define EVP_PKEY_CTRL_HKDF_INFO    (EVP_PKEY_ALG_CTRL + 6)
+
+# define EVP_PKEY_CTX_set_tls1_prf_md(pctx, md) \
+            EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \
+                              EVP_PKEY_CTRL_TLS_MD, 0, (void *)md)
+
+# define EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, sec, seclen) \
+            EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \
+                              EVP_PKEY_CTRL_TLS_SECRET, seclen, (void *)sec)
+
+# define EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed, seedlen) \
+            EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \
+                              EVP_PKEY_CTRL_TLS_SEED, seedlen, (void *)seed)
+
+# define EVP_PKEY_CTX_set_hkdf_md(pctx, md) \
+            EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \
+                              EVP_PKEY_CTRL_HKDF_MD, 0, (void *)md)
+
+# define EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, saltlen) \
+            EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \
+                              EVP_PKEY_CTRL_HKDF_SALT, saltlen, (void *)salt)
+
+# define EVP_PKEY_CTX_set1_hkdf_key(pctx, key, keylen) \
+            EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \
+                              EVP_PKEY_CTRL_HKDF_KEY, keylen, (void *)key)
+
+# define EVP_PKEY_CTX_add1_hkdf_info(pctx, info, infolen) \
+            EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DERIVE, \
+                              EVP_PKEY_CTRL_HKDF_INFO, infolen, (void *)info)
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_KDF_strings(void);
+
+/* Error codes for the KDF functions. */
+
+/* Function codes. */
+# define KDF_F_PKEY_TLS1_PRF_CTRL_STR                     100
+# define KDF_F_PKEY_TLS1_PRF_DERIVE                       101
+
+/* Reason codes. */
+# define KDF_R_INVALID_DIGEST                             100
+# define KDF_R_MISSING_PARAMETER                          101
+# define KDF_R_VALUE_MISSING                              102
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/lhash.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/lhash.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/lhash.h	(revision 331)
@@ -0,0 +1,204 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*
+ * Header for dynamic hash table routines Author - Eric Young
+ */
+
+#ifndef HEADER_LHASH_H
+# define HEADER_LHASH_H
+
+# include <openssl/e_os2.h>
+# include <openssl/bio.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct lhash_node_st OPENSSL_LH_NODE;
+typedef int (*OPENSSL_LH_COMPFUNC) (const void *, const void *);
+typedef unsigned long (*OPENSSL_LH_HASHFUNC) (const void *);
+typedef void (*OPENSSL_LH_DOALL_FUNC) (void *);
+typedef void (*OPENSSL_LH_DOALL_FUNCARG) (void *, void *);
+typedef struct lhash_st OPENSSL_LHASH;
+
+/*
+ * Macros for declaring and implementing type-safe wrappers for LHASH
+ * callbacks. This way, callbacks can be provided to LHASH structures without
+ * function pointer casting and the macro-defined callbacks provide
+ * per-variable casting before deferring to the underlying type-specific
+ * callbacks. NB: It is possible to place a "static" in front of both the
+ * DECLARE and IMPLEMENT macros if the functions are strictly internal.
+ */
+
+/* First: "hash" functions */
+# define DECLARE_LHASH_HASH_FN(name, o_type) \
+        unsigned long name##_LHASH_HASH(const void *);
+# define IMPLEMENT_LHASH_HASH_FN(name, o_type) \
+        unsigned long name##_LHASH_HASH(const void *arg) { \
+                const o_type *a = arg; \
+                return name##_hash(a); }
+# define LHASH_HASH_FN(name) name##_LHASH_HASH
+
+/* Second: "compare" functions */
+# define DECLARE_LHASH_COMP_FN(name, o_type) \
+        int name##_LHASH_COMP(const void *, const void *);
+# define IMPLEMENT_LHASH_COMP_FN(name, o_type) \
+        int name##_LHASH_COMP(const void *arg1, const void *arg2) { \
+                const o_type *a = arg1;             \
+                const o_type *b = arg2; \
+                return name##_cmp(a,b); }
+# define LHASH_COMP_FN(name) name##_LHASH_COMP
+
+/* Fourth: "doall_arg" functions */
+# define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
+        void name##_LHASH_DOALL_ARG(void *, void *);
+# define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
+        void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \
+                o_type *a = arg1; \
+                a_type *b = arg2; \
+                name##_doall_arg(a, b); }
+# define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG
+
+
+# define LH_LOAD_MULT    256
+
+int OPENSSL_LH_error(OPENSSL_LHASH *lh);
+OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c);
+void OPENSSL_LH_free(OPENSSL_LHASH *lh);
+void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data);
+void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data);
+void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data);
+void OPENSSL_LH_doall(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNC func);
+void OPENSSL_LH_doall_arg(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNCARG func, void *arg);
+unsigned long OPENSSL_LH_strhash(const char *c);
+unsigned long OPENSSL_LH_num_items(const OPENSSL_LHASH *lh);
+unsigned long OPENSSL_LH_get_down_load(const OPENSSL_LHASH *lh);
+void OPENSSL_LH_set_down_load(OPENSSL_LHASH *lh, unsigned long down_load);
+
+# ifndef OPENSSL_NO_STDIO
+void OPENSSL_LH_stats(const OPENSSL_LHASH *lh, FILE *fp);
+void OPENSSL_LH_node_stats(const OPENSSL_LHASH *lh, FILE *fp);
+void OPENSSL_LH_node_usage_stats(const OPENSSL_LHASH *lh, FILE *fp);
+# endif
+void OPENSSL_LH_stats_bio(const OPENSSL_LHASH *lh, BIO *out);
+void OPENSSL_LH_node_stats_bio(const OPENSSL_LHASH *lh, BIO *out);
+void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH *lh, BIO *out);
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  define _LHASH OPENSSL_LHASH
+#  define LHASH_NODE OPENSSL_LH_NODE
+#  define lh_error OPENSSL_LH_error
+#  define lh_new OPENSSL_lh_new
+#  define lh_free OPENSSL_LH_free
+#  define lh_insert OPENSSL_LH_insert
+#  define lh_delete OPENSSL_LH_delete
+#  define lh_retrieve OPENSSL_LH_retrieve
+#  define lh_doall OPENSSL_LH_doall
+#  define lh_doall_arg OPENSSL_LH_doall_arg
+#  define lh_strhash OPENSSL_LH_strhash
+#  define lh_num_items OPENSSL_LH_num_items
+#  ifndef OPENSSL_NO_STDIO
+#   define lh_stats OPENSSL_LH_stats
+#   define lh_node_stats OPENSSL_LH_node_stats
+#   define lh_node_usage_stats OPENSSL_LH_node_usage_stats
+#  endif
+#  define lh_stats_bio OPENSSL_LH_stats_bio
+#  define lh_node_stats_bio OPENSSL_LH_node_stats_bio
+#  define lh_node_usage_stats_bio OPENSSL_LH_node_usage_stats_bio
+# endif
+
+/* Type checking... */
+
+# define LHASH_OF(type) struct lhash_st_##type
+
+# define DEFINE_LHASH_OF(type) \
+    LHASH_OF(type) { union lh_##type##_dummy { void* d1; unsigned long d2; int d3; } dummy; }; \
+    static ossl_inline LHASH_OF(type) * \
+        lh_##type##_new(unsigned long (*hfn)(const type *), \
+                        int (*cfn)(const type *, const type *)) \
+    { \
+        return (LHASH_OF(type) *) \
+            OPENSSL_LH_new((OPENSSL_LH_HASHFUNC)hfn, (OPENSSL_LH_COMPFUNC)cfn); \
+    } \
+    static ossl_inline void lh_##type##_free(LHASH_OF(type) *lh) \
+    { \
+        OPENSSL_LH_free((OPENSSL_LHASH *)lh); \
+    } \
+    static ossl_inline type *lh_##type##_insert(LHASH_OF(type) *lh, type *d) \
+    { \
+        return (type *)OPENSSL_LH_insert((OPENSSL_LHASH *)lh, d); \
+    } \
+    static ossl_inline type *lh_##type##_delete(LHASH_OF(type) *lh, const type *d) \
+    { \
+        return (type *)OPENSSL_LH_delete((OPENSSL_LHASH *)lh, d); \
+    } \
+    static ossl_inline type *lh_##type##_retrieve(LHASH_OF(type) *lh, const type *d) \
+    { \
+        return (type *)OPENSSL_LH_retrieve((OPENSSL_LHASH *)lh, d); \
+    } \
+    static ossl_inline int lh_##type##_error(LHASH_OF(type) *lh) \
+    { \
+        return OPENSSL_LH_error((OPENSSL_LHASH *)lh); \
+    } \
+    static ossl_inline unsigned long lh_##type##_num_items(LHASH_OF(type) *lh) \
+    { \
+        return OPENSSL_LH_num_items((OPENSSL_LHASH *)lh); \
+    } \
+    static ossl_inline void lh_##type##_node_stats_bio(const LHASH_OF(type) *lh, BIO *out) \
+    { \
+        OPENSSL_LH_node_stats_bio((const OPENSSL_LHASH *)lh, out); \
+    } \
+    static ossl_inline void lh_##type##_node_usage_stats_bio(const LHASH_OF(type) *lh, BIO *out) \
+    { \
+        OPENSSL_LH_node_usage_stats_bio((const OPENSSL_LHASH *)lh, out); \
+    } \
+    static ossl_inline void lh_##type##_stats_bio(const LHASH_OF(type) *lh, BIO *out) \
+    { \
+        OPENSSL_LH_stats_bio((const OPENSSL_LHASH *)lh, out); \
+    } \
+    static ossl_inline unsigned long lh_##type##_get_down_load(LHASH_OF(type) *lh) \
+    { \
+        return OPENSSL_LH_get_down_load((OPENSSL_LHASH *)lh); \
+    } \
+    static ossl_inline void lh_##type##_set_down_load(LHASH_OF(type) *lh, unsigned long dl) \
+    { \
+        OPENSSL_LH_set_down_load((OPENSSL_LHASH *)lh, dl); \
+    } \
+    static ossl_inline void lh_##type##_doall(LHASH_OF(type) *lh, \
+                                         void (*doall)(type *)) \
+    { \
+        OPENSSL_LH_doall((OPENSSL_LHASH *)lh, (OPENSSL_LH_DOALL_FUNC)doall); \
+    } \
+    LHASH_OF(type)
+
+#define IMPLEMENT_LHASH_DOALL_ARG_CONST(type, argtype) \
+    int_implement_lhash_doall(type, argtype, const type)
+
+#define IMPLEMENT_LHASH_DOALL_ARG(type, argtype) \
+    int_implement_lhash_doall(type, argtype, type)
+
+#define int_implement_lhash_doall(type, argtype, cbargtype) \
+    static ossl_inline void \
+        lh_##type##_doall_##argtype(LHASH_OF(type) *lh, \
+                                   void (*fn)(cbargtype *, argtype *), \
+                                   argtype *arg) \
+    { \
+        OPENSSL_LH_doall_arg((OPENSSL_LHASH *)lh, (OPENSSL_LH_DOALL_FUNCARG)fn, (void *)arg); \
+    } \
+    LHASH_OF(type)
+
+DEFINE_LHASH_OF(OPENSSL_STRING);
+DEFINE_LHASH_OF(OPENSSL_CSTRING);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/md2.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/md2.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/md2.h	(revision 331)
@@ -0,0 +1,44 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_MD2_H
+# define HEADER_MD2_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_MD2
+# include <stddef.h>
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+typedef unsigned char MD2_INT;
+
+# define MD2_DIGEST_LENGTH       16
+# define MD2_BLOCK               16
+
+typedef struct MD2state_st {
+    unsigned int num;
+    unsigned char data[MD2_BLOCK];
+    MD2_INT cksm[MD2_BLOCK];
+    MD2_INT state[MD2_BLOCK];
+} MD2_CTX;
+
+const char *MD2_options(void);
+int MD2_Init(MD2_CTX *c);
+int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len);
+int MD2_Final(unsigned char *md, MD2_CTX *c);
+unsigned char *MD2(const unsigned char *d, size_t n, unsigned char *md);
+
+# ifdef  __cplusplus
+}
+# endif
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/md4.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/md4.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/md4.h	(revision 331)
@@ -0,0 +1,51 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_MD4_H
+# define HEADER_MD4_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_MD4
+# include <openssl/e_os2.h>
+# include <stddef.h>
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+/*-
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! MD4_LONG has to be at least 32 bits wide.                     !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+# define MD4_LONG unsigned int
+
+# define MD4_CBLOCK      64
+# define MD4_LBLOCK      (MD4_CBLOCK/4)
+# define MD4_DIGEST_LENGTH 16
+
+typedef struct MD4state_st {
+    MD4_LONG A, B, C, D;
+    MD4_LONG Nl, Nh;
+    MD4_LONG data[MD4_LBLOCK];
+    unsigned int num;
+} MD4_CTX;
+
+int MD4_Init(MD4_CTX *c);
+int MD4_Update(MD4_CTX *c, const void *data, size_t len);
+int MD4_Final(unsigned char *md, MD4_CTX *c);
+unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md);
+void MD4_Transform(MD4_CTX *c, const unsigned char *b);
+
+# ifdef  __cplusplus
+}
+# endif
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/md5.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/md5.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/md5.h	(revision 331)
@@ -0,0 +1,50 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_MD5_H
+# define HEADER_MD5_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_MD5
+# include <openssl/e_os2.h>
+# include <stddef.h>
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! MD5_LONG has to be at least 32 bits wide.                     !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+# define MD5_LONG unsigned int
+
+# define MD5_CBLOCK      64
+# define MD5_LBLOCK      (MD5_CBLOCK/4)
+# define MD5_DIGEST_LENGTH 16
+
+typedef struct MD5state_st {
+    MD5_LONG A, B, C, D;
+    MD5_LONG Nl, Nh;
+    MD5_LONG data[MD5_LBLOCK];
+    unsigned int num;
+} MD5_CTX;
+
+int MD5_Init(MD5_CTX *c);
+int MD5_Update(MD5_CTX *c, const void *data, size_t len);
+int MD5_Final(unsigned char *md, MD5_CTX *c);
+unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
+void MD5_Transform(MD5_CTX *c, const unsigned char *b);
+# ifdef  __cplusplus
+}
+# endif
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/mdc2.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/mdc2.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/mdc2.h	(revision 331)
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_MDC2_H
+# define HEADER_MDC2_H
+
+# include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_NO_MDC2
+# include <stdlib.h>
+# include <openssl/des.h>
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+# define MDC2_BLOCK              8
+# define MDC2_DIGEST_LENGTH      16
+
+typedef struct mdc2_ctx_st {
+    unsigned int num;
+    unsigned char data[MDC2_BLOCK];
+    DES_cblock h, hh;
+    int pad_type;               /* either 1 or 2, default 1 */
+} MDC2_CTX;
+
+int MDC2_Init(MDC2_CTX *c);
+int MDC2_Update(MDC2_CTX *c, const unsigned char *data, size_t len);
+int MDC2_Final(unsigned char *md, MDC2_CTX *c);
+unsigned char *MDC2(const unsigned char *d, size_t n, unsigned char *md);
+
+# ifdef  __cplusplus
+}
+# endif
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/modes.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/modes.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/modes.h	(revision 331)
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2008-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 <stddef.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+typedef void (*block128_f) (const unsigned char in[16],
+                            unsigned char out[16], const void *key);
+
+typedef void (*cbc128_f) (const unsigned char *in, unsigned char *out,
+                          size_t len, const void *key,
+                          unsigned char ivec[16], int enc);
+
+typedef void (*ctr128_f) (const unsigned char *in, unsigned char *out,
+                          size_t blocks, const void *key,
+                          const unsigned char ivec[16]);
+
+typedef void (*ccm128_f) (const unsigned char *in, unsigned char *out,
+                          size_t blocks, const void *key,
+                          const unsigned char ivec[16],
+                          unsigned char cmac[16]);
+
+void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const void *key,
+                           unsigned char ivec[16], block128_f block);
+void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const void *key,
+                           unsigned char ivec[16], block128_f block);
+
+void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const void *key,
+                           unsigned char ivec[16],
+                           unsigned char ecount_buf[16], unsigned int *num,
+                           block128_f block);
+
+void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out,
+                                 size_t len, const void *key,
+                                 unsigned char ivec[16],
+                                 unsigned char ecount_buf[16],
+                                 unsigned int *num, ctr128_f ctr);
+
+void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const void *key,
+                           unsigned char ivec[16], int *num,
+                           block128_f block);
+
+void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+                           size_t len, const void *key,
+                           unsigned char ivec[16], int *num,
+                           int enc, block128_f block);
+void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t length, const void *key,
+                             unsigned char ivec[16], int *num,
+                             int enc, block128_f block);
+void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t bits, const void *key,
+                             unsigned char ivec[16], int *num,
+                             int enc, block128_f block);
+
+size_t CRYPTO_cts128_encrypt_block(const unsigned char *in,
+                                   unsigned char *out, size_t len,
+                                   const void *key, unsigned char ivec[16],
+                                   block128_f block);
+size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
+                             size_t len, const void *key,
+                             unsigned char ivec[16], cbc128_f cbc);
+size_t CRYPTO_cts128_decrypt_block(const unsigned char *in,
+                                   unsigned char *out, size_t len,
+                                   const void *key, unsigned char ivec[16],
+                                   block128_f block);
+size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
+                             size_t len, const void *key,
+                             unsigned char ivec[16], cbc128_f cbc);
+
+size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in,
+                                       unsigned char *out, size_t len,
+                                       const void *key,
+                                       unsigned char ivec[16],
+                                       block128_f block);
+size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out,
+                                 size_t len, const void *key,
+                                 unsigned char ivec[16], cbc128_f cbc);
+size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in,
+                                       unsigned char *out, size_t len,
+                                       const void *key,
+                                       unsigned char ivec[16],
+                                       block128_f block);
+size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out,
+                                 size_t len, const void *key,
+                                 unsigned char ivec[16], cbc128_f cbc);
+
+typedef struct gcm128_context GCM128_CONTEXT;
+
+GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block);
+void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block);
+void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv,
+                         size_t len);
+int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad,
+                      size_t len);
+int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
+                          const unsigned char *in, unsigned char *out,
+                          size_t len);
+int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
+                          const unsigned char *in, unsigned char *out,
+                          size_t len);
+int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
+                                const unsigned char *in, unsigned char *out,
+                                size_t len, ctr128_f stream);
+int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
+                                const unsigned char *in, unsigned char *out,
+                                size_t len, ctr128_f stream);
+int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag,
+                         size_t len);
+void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len);
+void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx);
+
+typedef struct ccm128_context CCM128_CONTEXT;
+
+void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx,
+                        unsigned int M, unsigned int L, void *key,
+                        block128_f block);
+int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, const unsigned char *nonce,
+                        size_t nlen, size_t mlen);
+void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, const unsigned char *aad,
+                       size_t alen);
+int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, const unsigned char *inp,
+                          unsigned char *out, size_t len);
+int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, const unsigned char *inp,
+                          unsigned char *out, size_t len);
+int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp,
+                                unsigned char *out, size_t len,
+                                ccm128_f stream);
+int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp,
+                                unsigned char *out, size_t len,
+                                ccm128_f stream);
+size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len);
+
+typedef struct xts128_context XTS128_CONTEXT;
+
+int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
+                          const unsigned char iv[16],
+                          const unsigned char *inp, unsigned char *out,
+                          size_t len, int enc);
+
+size_t CRYPTO_128_wrap(void *key, const unsigned char *iv,
+                       unsigned char *out,
+                       const unsigned char *in, size_t inlen,
+                       block128_f block);
+
+size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv,
+                         unsigned char *out,
+                         const unsigned char *in, size_t inlen,
+                         block128_f block);
+size_t CRYPTO_128_wrap_pad(void *key, const unsigned char *icv,
+                           unsigned char *out, const unsigned char *in,
+                           size_t inlen, block128_f block);
+size_t CRYPTO_128_unwrap_pad(void *key, const unsigned char *icv,
+                             unsigned char *out, const unsigned char *in,
+                             size_t inlen, block128_f block);
+
+#ifndef OPENSSL_NO_OCB
+typedef struct ocb128_context OCB128_CONTEXT;
+
+typedef void (*ocb128_f) (const unsigned char *in, unsigned char *out,
+                          size_t blocks, const void *key,
+                          size_t start_block_num,
+                          unsigned char offset_i[16],
+                          const unsigned char L_[][16],
+                          unsigned char checksum[16]);
+
+OCB128_CONTEXT *CRYPTO_ocb128_new(void *keyenc, void *keydec,
+                                  block128_f encrypt, block128_f decrypt,
+                                  ocb128_f stream);
+int CRYPTO_ocb128_init(OCB128_CONTEXT *ctx, void *keyenc, void *keydec,
+                       block128_f encrypt, block128_f decrypt,
+                       ocb128_f stream);
+int CRYPTO_ocb128_copy_ctx(OCB128_CONTEXT *dest, OCB128_CONTEXT *src,
+                           void *keyenc, void *keydec);
+int CRYPTO_ocb128_setiv(OCB128_CONTEXT *ctx, const unsigned char *iv,
+                        size_t len, size_t taglen);
+int CRYPTO_ocb128_aad(OCB128_CONTEXT *ctx, const unsigned char *aad,
+                      size_t len);
+int CRYPTO_ocb128_encrypt(OCB128_CONTEXT *ctx, const unsigned char *in,
+                          unsigned char *out, size_t len);
+int CRYPTO_ocb128_decrypt(OCB128_CONTEXT *ctx, const unsigned char *in,
+                          unsigned char *out, size_t len);
+int CRYPTO_ocb128_finish(OCB128_CONTEXT *ctx, const unsigned char *tag,
+                         size_t len);
+int CRYPTO_ocb128_tag(OCB128_CONTEXT *ctx, unsigned char *tag, size_t len);
+void CRYPTO_ocb128_cleanup(OCB128_CONTEXT *ctx);
+#endif                          /* OPENSSL_NO_OCB */
+
+#ifdef  __cplusplus
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/obj_mac.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/obj_mac.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/obj_mac.h	(revision 331)
@@ -0,0 +1,4577 @@
+/*
+ * WARNING: do not edit!
+ * Generated by crypto/objects/objects.pl
+ *
+ * Copyright 2000-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
+ */
+
+#define SN_undef                        "UNDEF"
+#define LN_undef                        "undefined"
+#define NID_undef                       0
+#define OBJ_undef                       0L
+
+#define SN_itu_t                "ITU-T"
+#define LN_itu_t                "itu-t"
+#define NID_itu_t               645
+#define OBJ_itu_t               0L
+
+#define NID_ccitt               404
+#define OBJ_ccitt               OBJ_itu_t
+
+#define SN_iso          "ISO"
+#define LN_iso          "iso"
+#define NID_iso         181
+#define OBJ_iso         1L
+
+#define SN_joint_iso_itu_t              "JOINT-ISO-ITU-T"
+#define LN_joint_iso_itu_t              "joint-iso-itu-t"
+#define NID_joint_iso_itu_t             646
+#define OBJ_joint_iso_itu_t             2L
+
+#define NID_joint_iso_ccitt             393
+#define OBJ_joint_iso_ccitt             OBJ_joint_iso_itu_t
+
+#define SN_member_body          "member-body"
+#define LN_member_body          "ISO Member Body"
+#define NID_member_body         182
+#define OBJ_member_body         OBJ_iso,2L
+
+#define SN_identified_organization              "identified-organization"
+#define NID_identified_organization             676
+#define OBJ_identified_organization             OBJ_iso,3L
+
+#define SN_hmac_md5             "HMAC-MD5"
+#define LN_hmac_md5             "hmac-md5"
+#define NID_hmac_md5            780
+#define OBJ_hmac_md5            OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L
+
+#define SN_hmac_sha1            "HMAC-SHA1"
+#define LN_hmac_sha1            "hmac-sha1"
+#define NID_hmac_sha1           781
+#define OBJ_hmac_sha1           OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L
+
+#define SN_certicom_arc         "certicom-arc"
+#define NID_certicom_arc                677
+#define OBJ_certicom_arc                OBJ_identified_organization,132L
+
+#define SN_international_organizations          "international-organizations"
+#define LN_international_organizations          "International Organizations"
+#define NID_international_organizations         647
+#define OBJ_international_organizations         OBJ_joint_iso_itu_t,23L
+
+#define SN_wap          "wap"
+#define NID_wap         678
+#define OBJ_wap         OBJ_international_organizations,43L
+
+#define SN_wap_wsg              "wap-wsg"
+#define NID_wap_wsg             679
+#define OBJ_wap_wsg             OBJ_wap,1L
+
+#define SN_selected_attribute_types             "selected-attribute-types"
+#define LN_selected_attribute_types             "Selected Attribute Types"
+#define NID_selected_attribute_types            394
+#define OBJ_selected_attribute_types            OBJ_joint_iso_itu_t,5L,1L,5L
+
+#define SN_clearance            "clearance"
+#define NID_clearance           395
+#define OBJ_clearance           OBJ_selected_attribute_types,55L
+
+#define SN_ISO_US               "ISO-US"
+#define LN_ISO_US               "ISO US Member Body"
+#define NID_ISO_US              183
+#define OBJ_ISO_US              OBJ_member_body,840L
+
+#define SN_X9_57                "X9-57"
+#define LN_X9_57                "X9.57"
+#define NID_X9_57               184
+#define OBJ_X9_57               OBJ_ISO_US,10040L
+
+#define SN_X9cm         "X9cm"
+#define LN_X9cm         "X9.57 CM ?"
+#define NID_X9cm                185
+#define OBJ_X9cm                OBJ_X9_57,4L
+
+#define SN_dsa          "DSA"
+#define LN_dsa          "dsaEncryption"
+#define NID_dsa         116
+#define OBJ_dsa         OBJ_X9cm,1L
+
+#define SN_dsaWithSHA1          "DSA-SHA1"
+#define LN_dsaWithSHA1          "dsaWithSHA1"
+#define NID_dsaWithSHA1         113
+#define OBJ_dsaWithSHA1         OBJ_X9cm,3L
+
+#define SN_ansi_X9_62           "ansi-X9-62"
+#define LN_ansi_X9_62           "ANSI X9.62"
+#define NID_ansi_X9_62          405
+#define OBJ_ansi_X9_62          OBJ_ISO_US,10045L
+
+#define OBJ_X9_62_id_fieldType          OBJ_ansi_X9_62,1L
+
+#define SN_X9_62_prime_field            "prime-field"
+#define NID_X9_62_prime_field           406
+#define OBJ_X9_62_prime_field           OBJ_X9_62_id_fieldType,1L
+
+#define SN_X9_62_characteristic_two_field               "characteristic-two-field"
+#define NID_X9_62_characteristic_two_field              407
+#define OBJ_X9_62_characteristic_two_field              OBJ_X9_62_id_fieldType,2L
+
+#define SN_X9_62_id_characteristic_two_basis            "id-characteristic-two-basis"
+#define NID_X9_62_id_characteristic_two_basis           680
+#define OBJ_X9_62_id_characteristic_two_basis           OBJ_X9_62_characteristic_two_field,3L
+
+#define SN_X9_62_onBasis                "onBasis"
+#define NID_X9_62_onBasis               681
+#define OBJ_X9_62_onBasis               OBJ_X9_62_id_characteristic_two_basis,1L
+
+#define SN_X9_62_tpBasis                "tpBasis"
+#define NID_X9_62_tpBasis               682
+#define OBJ_X9_62_tpBasis               OBJ_X9_62_id_characteristic_two_basis,2L
+
+#define SN_X9_62_ppBasis                "ppBasis"
+#define NID_X9_62_ppBasis               683
+#define OBJ_X9_62_ppBasis               OBJ_X9_62_id_characteristic_two_basis,3L
+
+#define OBJ_X9_62_id_publicKeyType              OBJ_ansi_X9_62,2L
+
+#define SN_X9_62_id_ecPublicKey         "id-ecPublicKey"
+#define NID_X9_62_id_ecPublicKey                408
+#define OBJ_X9_62_id_ecPublicKey                OBJ_X9_62_id_publicKeyType,1L
+
+#define OBJ_X9_62_ellipticCurve         OBJ_ansi_X9_62,3L
+
+#define OBJ_X9_62_c_TwoCurve            OBJ_X9_62_ellipticCurve,0L
+
+#define SN_X9_62_c2pnb163v1             "c2pnb163v1"
+#define NID_X9_62_c2pnb163v1            684
+#define OBJ_X9_62_c2pnb163v1            OBJ_X9_62_c_TwoCurve,1L
+
+#define SN_X9_62_c2pnb163v2             "c2pnb163v2"
+#define NID_X9_62_c2pnb163v2            685
+#define OBJ_X9_62_c2pnb163v2            OBJ_X9_62_c_TwoCurve,2L
+
+#define SN_X9_62_c2pnb163v3             "c2pnb163v3"
+#define NID_X9_62_c2pnb163v3            686
+#define OBJ_X9_62_c2pnb163v3            OBJ_X9_62_c_TwoCurve,3L
+
+#define SN_X9_62_c2pnb176v1             "c2pnb176v1"
+#define NID_X9_62_c2pnb176v1            687
+#define OBJ_X9_62_c2pnb176v1            OBJ_X9_62_c_TwoCurve,4L
+
+#define SN_X9_62_c2tnb191v1             "c2tnb191v1"
+#define NID_X9_62_c2tnb191v1            688
+#define OBJ_X9_62_c2tnb191v1            OBJ_X9_62_c_TwoCurve,5L
+
+#define SN_X9_62_c2tnb191v2             "c2tnb191v2"
+#define NID_X9_62_c2tnb191v2            689
+#define OBJ_X9_62_c2tnb191v2            OBJ_X9_62_c_TwoCurve,6L
+
+#define SN_X9_62_c2tnb191v3             "c2tnb191v3"
+#define NID_X9_62_c2tnb191v3            690
+#define OBJ_X9_62_c2tnb191v3            OBJ_X9_62_c_TwoCurve,7L
+
+#define SN_X9_62_c2onb191v4             "c2onb191v4"
+#define NID_X9_62_c2onb191v4            691
+#define OBJ_X9_62_c2onb191v4            OBJ_X9_62_c_TwoCurve,8L
+
+#define SN_X9_62_c2onb191v5             "c2onb191v5"
+#define NID_X9_62_c2onb191v5            692
+#define OBJ_X9_62_c2onb191v5            OBJ_X9_62_c_TwoCurve,9L
+
+#define SN_X9_62_c2pnb208w1             "c2pnb208w1"
+#define NID_X9_62_c2pnb208w1            693
+#define OBJ_X9_62_c2pnb208w1            OBJ_X9_62_c_TwoCurve,10L
+
+#define SN_X9_62_c2tnb239v1             "c2tnb239v1"
+#define NID_X9_62_c2tnb239v1            694
+#define OBJ_X9_62_c2tnb239v1            OBJ_X9_62_c_TwoCurve,11L
+
+#define SN_X9_62_c2tnb239v2             "c2tnb239v2"
+#define NID_X9_62_c2tnb239v2            695
+#define OBJ_X9_62_c2tnb239v2            OBJ_X9_62_c_TwoCurve,12L
+
+#define SN_X9_62_c2tnb239v3             "c2tnb239v3"
+#define NID_X9_62_c2tnb239v3            696
+#define OBJ_X9_62_c2tnb239v3            OBJ_X9_62_c_TwoCurve,13L
+
+#define SN_X9_62_c2onb239v4             "c2onb239v4"
+#define NID_X9_62_c2onb239v4            697
+#define OBJ_X9_62_c2onb239v4            OBJ_X9_62_c_TwoCurve,14L
+
+#define SN_X9_62_c2onb239v5             "c2onb239v5"
+#define NID_X9_62_c2onb239v5            698
+#define OBJ_X9_62_c2onb239v5            OBJ_X9_62_c_TwoCurve,15L
+
+#define SN_X9_62_c2pnb272w1             "c2pnb272w1"
+#define NID_X9_62_c2pnb272w1            699
+#define OBJ_X9_62_c2pnb272w1            OBJ_X9_62_c_TwoCurve,16L
+
+#define SN_X9_62_c2pnb304w1             "c2pnb304w1"
+#define NID_X9_62_c2pnb304w1            700
+#define OBJ_X9_62_c2pnb304w1            OBJ_X9_62_c_TwoCurve,17L
+
+#define SN_X9_62_c2tnb359v1             "c2tnb359v1"
+#define NID_X9_62_c2tnb359v1            701
+#define OBJ_X9_62_c2tnb359v1            OBJ_X9_62_c_TwoCurve,18L
+
+#define SN_X9_62_c2pnb368w1             "c2pnb368w1"
+#define NID_X9_62_c2pnb368w1            702
+#define OBJ_X9_62_c2pnb368w1            OBJ_X9_62_c_TwoCurve,19L
+
+#define SN_X9_62_c2tnb431r1             "c2tnb431r1"
+#define NID_X9_62_c2tnb431r1            703
+#define OBJ_X9_62_c2tnb431r1            OBJ_X9_62_c_TwoCurve,20L
+
+#define OBJ_X9_62_primeCurve            OBJ_X9_62_ellipticCurve,1L
+
+#define SN_X9_62_prime192v1             "prime192v1"
+#define NID_X9_62_prime192v1            409
+#define OBJ_X9_62_prime192v1            OBJ_X9_62_primeCurve,1L
+
+#define SN_X9_62_prime192v2             "prime192v2"
+#define NID_X9_62_prime192v2            410
+#define OBJ_X9_62_prime192v2            OBJ_X9_62_primeCurve,2L
+
+#define SN_X9_62_prime192v3             "prime192v3"
+#define NID_X9_62_prime192v3            411
+#define OBJ_X9_62_prime192v3            OBJ_X9_62_primeCurve,3L
+
+#define SN_X9_62_prime239v1             "prime239v1"
+#define NID_X9_62_prime239v1            412
+#define OBJ_X9_62_prime239v1            OBJ_X9_62_primeCurve,4L
+
+#define SN_X9_62_prime239v2             "prime239v2"
+#define NID_X9_62_prime239v2            413
+#define OBJ_X9_62_prime239v2            OBJ_X9_62_primeCurve,5L
+
+#define SN_X9_62_prime239v3             "prime239v3"
+#define NID_X9_62_prime239v3            414
+#define OBJ_X9_62_prime239v3            OBJ_X9_62_primeCurve,6L
+
+#define SN_X9_62_prime256v1             "prime256v1"
+#define NID_X9_62_prime256v1            415
+#define OBJ_X9_62_prime256v1            OBJ_X9_62_primeCurve,7L
+
+#define OBJ_X9_62_id_ecSigType          OBJ_ansi_X9_62,4L
+
+#define SN_ecdsa_with_SHA1              "ecdsa-with-SHA1"
+#define NID_ecdsa_with_SHA1             416
+#define OBJ_ecdsa_with_SHA1             OBJ_X9_62_id_ecSigType,1L
+
+#define SN_ecdsa_with_Recommended               "ecdsa-with-Recommended"
+#define NID_ecdsa_with_Recommended              791
+#define OBJ_ecdsa_with_Recommended              OBJ_X9_62_id_ecSigType,2L
+
+#define SN_ecdsa_with_Specified         "ecdsa-with-Specified"
+#define NID_ecdsa_with_Specified                792
+#define OBJ_ecdsa_with_Specified                OBJ_X9_62_id_ecSigType,3L
+
+#define SN_ecdsa_with_SHA224            "ecdsa-with-SHA224"
+#define NID_ecdsa_with_SHA224           793
+#define OBJ_ecdsa_with_SHA224           OBJ_ecdsa_with_Specified,1L
+
+#define SN_ecdsa_with_SHA256            "ecdsa-with-SHA256"
+#define NID_ecdsa_with_SHA256           794
+#define OBJ_ecdsa_with_SHA256           OBJ_ecdsa_with_Specified,2L
+
+#define SN_ecdsa_with_SHA384            "ecdsa-with-SHA384"
+#define NID_ecdsa_with_SHA384           795
+#define OBJ_ecdsa_with_SHA384           OBJ_ecdsa_with_Specified,3L
+
+#define SN_ecdsa_with_SHA512            "ecdsa-with-SHA512"
+#define NID_ecdsa_with_SHA512           796
+#define OBJ_ecdsa_with_SHA512           OBJ_ecdsa_with_Specified,4L
+
+#define OBJ_secg_ellipticCurve          OBJ_certicom_arc,0L
+
+#define SN_secp112r1            "secp112r1"
+#define NID_secp112r1           704
+#define OBJ_secp112r1           OBJ_secg_ellipticCurve,6L
+
+#define SN_secp112r2            "secp112r2"
+#define NID_secp112r2           705
+#define OBJ_secp112r2           OBJ_secg_ellipticCurve,7L
+
+#define SN_secp128r1            "secp128r1"
+#define NID_secp128r1           706
+#define OBJ_secp128r1           OBJ_secg_ellipticCurve,28L
+
+#define SN_secp128r2            "secp128r2"
+#define NID_secp128r2           707
+#define OBJ_secp128r2           OBJ_secg_ellipticCurve,29L
+
+#define SN_secp160k1            "secp160k1"
+#define NID_secp160k1           708
+#define OBJ_secp160k1           OBJ_secg_ellipticCurve,9L
+
+#define SN_secp160r1            "secp160r1"
+#define NID_secp160r1           709
+#define OBJ_secp160r1           OBJ_secg_ellipticCurve,8L
+
+#define SN_secp160r2            "secp160r2"
+#define NID_secp160r2           710
+#define OBJ_secp160r2           OBJ_secg_ellipticCurve,30L
+
+#define SN_secp192k1            "secp192k1"
+#define NID_secp192k1           711
+#define OBJ_secp192k1           OBJ_secg_ellipticCurve,31L
+
+#define SN_secp224k1            "secp224k1"
+#define NID_secp224k1           712
+#define OBJ_secp224k1           OBJ_secg_ellipticCurve,32L
+
+#define SN_secp224r1            "secp224r1"
+#define NID_secp224r1           713
+#define OBJ_secp224r1           OBJ_secg_ellipticCurve,33L
+
+#define SN_secp256k1            "secp256k1"
+#define NID_secp256k1           714
+#define OBJ_secp256k1           OBJ_secg_ellipticCurve,10L
+
+#define SN_secp384r1            "secp384r1"
+#define NID_secp384r1           715
+#define OBJ_secp384r1           OBJ_secg_ellipticCurve,34L
+
+#define SN_secp521r1            "secp521r1"
+#define NID_secp521r1           716
+#define OBJ_secp521r1           OBJ_secg_ellipticCurve,35L
+
+#define SN_sect113r1            "sect113r1"
+#define NID_sect113r1           717
+#define OBJ_sect113r1           OBJ_secg_ellipticCurve,4L
+
+#define SN_sect113r2            "sect113r2"
+#define NID_sect113r2           718
+#define OBJ_sect113r2           OBJ_secg_ellipticCurve,5L
+
+#define SN_sect131r1            "sect131r1"
+#define NID_sect131r1           719
+#define OBJ_sect131r1           OBJ_secg_ellipticCurve,22L
+
+#define SN_sect131r2            "sect131r2"
+#define NID_sect131r2           720
+#define OBJ_sect131r2           OBJ_secg_ellipticCurve,23L
+
+#define SN_sect163k1            "sect163k1"
+#define NID_sect163k1           721
+#define OBJ_sect163k1           OBJ_secg_ellipticCurve,1L
+
+#define SN_sect163r1            "sect163r1"
+#define NID_sect163r1           722
+#define OBJ_sect163r1           OBJ_secg_ellipticCurve,2L
+
+#define SN_sect163r2            "sect163r2"
+#define NID_sect163r2           723
+#define OBJ_sect163r2           OBJ_secg_ellipticCurve,15L
+
+#define SN_sect193r1            "sect193r1"
+#define NID_sect193r1           724
+#define OBJ_sect193r1           OBJ_secg_ellipticCurve,24L
+
+#define SN_sect193r2            "sect193r2"
+#define NID_sect193r2           725
+#define OBJ_sect193r2           OBJ_secg_ellipticCurve,25L
+
+#define SN_sect233k1            "sect233k1"
+#define NID_sect233k1           726
+#define OBJ_sect233k1           OBJ_secg_ellipticCurve,26L
+
+#define SN_sect233r1            "sect233r1"
+#define NID_sect233r1           727
+#define OBJ_sect233r1           OBJ_secg_ellipticCurve,27L
+
+#define SN_sect239k1            "sect239k1"
+#define NID_sect239k1           728
+#define OBJ_sect239k1           OBJ_secg_ellipticCurve,3L
+
+#define SN_sect283k1            "sect283k1"
+#define NID_sect283k1           729
+#define OBJ_sect283k1           OBJ_secg_ellipticCurve,16L
+
+#define SN_sect283r1            "sect283r1"
+#define NID_sect283r1           730
+#define OBJ_sect283r1           OBJ_secg_ellipticCurve,17L
+
+#define SN_sect409k1            "sect409k1"
+#define NID_sect409k1           731
+#define OBJ_sect409k1           OBJ_secg_ellipticCurve,36L
+
+#define SN_sect409r1            "sect409r1"
+#define NID_sect409r1           732
+#define OBJ_sect409r1           OBJ_secg_ellipticCurve,37L
+
+#define SN_sect571k1            "sect571k1"
+#define NID_sect571k1           733
+#define OBJ_sect571k1           OBJ_secg_ellipticCurve,38L
+
+#define SN_sect571r1            "sect571r1"
+#define NID_sect571r1           734
+#define OBJ_sect571r1           OBJ_secg_ellipticCurve,39L
+
+#define OBJ_wap_wsg_idm_ecid            OBJ_wap_wsg,4L
+
+#define SN_wap_wsg_idm_ecid_wtls1               "wap-wsg-idm-ecid-wtls1"
+#define NID_wap_wsg_idm_ecid_wtls1              735
+#define OBJ_wap_wsg_idm_ecid_wtls1              OBJ_wap_wsg_idm_ecid,1L
+
+#define SN_wap_wsg_idm_ecid_wtls3               "wap-wsg-idm-ecid-wtls3"
+#define NID_wap_wsg_idm_ecid_wtls3              736
+#define OBJ_wap_wsg_idm_ecid_wtls3              OBJ_wap_wsg_idm_ecid,3L
+
+#define SN_wap_wsg_idm_ecid_wtls4               "wap-wsg-idm-ecid-wtls4"
+#define NID_wap_wsg_idm_ecid_wtls4              737
+#define OBJ_wap_wsg_idm_ecid_wtls4              OBJ_wap_wsg_idm_ecid,4L
+
+#define SN_wap_wsg_idm_ecid_wtls5               "wap-wsg-idm-ecid-wtls5"
+#define NID_wap_wsg_idm_ecid_wtls5              738
+#define OBJ_wap_wsg_idm_ecid_wtls5              OBJ_wap_wsg_idm_ecid,5L
+
+#define SN_wap_wsg_idm_ecid_wtls6               "wap-wsg-idm-ecid-wtls6"
+#define NID_wap_wsg_idm_ecid_wtls6              739
+#define OBJ_wap_wsg_idm_ecid_wtls6              OBJ_wap_wsg_idm_ecid,6L
+
+#define SN_wap_wsg_idm_ecid_wtls7               "wap-wsg-idm-ecid-wtls7"
+#define NID_wap_wsg_idm_ecid_wtls7              740
+#define OBJ_wap_wsg_idm_ecid_wtls7              OBJ_wap_wsg_idm_ecid,7L
+
+#define SN_wap_wsg_idm_ecid_wtls8               "wap-wsg-idm-ecid-wtls8"
+#define NID_wap_wsg_idm_ecid_wtls8              741
+#define OBJ_wap_wsg_idm_ecid_wtls8              OBJ_wap_wsg_idm_ecid,8L
+
+#define SN_wap_wsg_idm_ecid_wtls9               "wap-wsg-idm-ecid-wtls9"
+#define NID_wap_wsg_idm_ecid_wtls9              742
+#define OBJ_wap_wsg_idm_ecid_wtls9              OBJ_wap_wsg_idm_ecid,9L
+
+#define SN_wap_wsg_idm_ecid_wtls10              "wap-wsg-idm-ecid-wtls10"
+#define NID_wap_wsg_idm_ecid_wtls10             743
+#define OBJ_wap_wsg_idm_ecid_wtls10             OBJ_wap_wsg_idm_ecid,10L
+
+#define SN_wap_wsg_idm_ecid_wtls11              "wap-wsg-idm-ecid-wtls11"
+#define NID_wap_wsg_idm_ecid_wtls11             744
+#define OBJ_wap_wsg_idm_ecid_wtls11             OBJ_wap_wsg_idm_ecid,11L
+
+#define SN_wap_wsg_idm_ecid_wtls12              "wap-wsg-idm-ecid-wtls12"
+#define NID_wap_wsg_idm_ecid_wtls12             745
+#define OBJ_wap_wsg_idm_ecid_wtls12             OBJ_wap_wsg_idm_ecid,12L
+
+#define SN_cast5_cbc            "CAST5-CBC"
+#define LN_cast5_cbc            "cast5-cbc"
+#define NID_cast5_cbc           108
+#define OBJ_cast5_cbc           OBJ_ISO_US,113533L,7L,66L,10L
+
+#define SN_cast5_ecb            "CAST5-ECB"
+#define LN_cast5_ecb            "cast5-ecb"
+#define NID_cast5_ecb           109
+
+#define SN_cast5_cfb64          "CAST5-CFB"
+#define LN_cast5_cfb64          "cast5-cfb"
+#define NID_cast5_cfb64         110
+
+#define SN_cast5_ofb64          "CAST5-OFB"
+#define LN_cast5_ofb64          "cast5-ofb"
+#define NID_cast5_ofb64         111
+
+#define LN_pbeWithMD5AndCast5_CBC               "pbeWithMD5AndCast5CBC"
+#define NID_pbeWithMD5AndCast5_CBC              112
+#define OBJ_pbeWithMD5AndCast5_CBC              OBJ_ISO_US,113533L,7L,66L,12L
+
+#define SN_id_PasswordBasedMAC          "id-PasswordBasedMAC"
+#define LN_id_PasswordBasedMAC          "password based MAC"
+#define NID_id_PasswordBasedMAC         782
+#define OBJ_id_PasswordBasedMAC         OBJ_ISO_US,113533L,7L,66L,13L
+
+#define SN_id_DHBasedMac                "id-DHBasedMac"
+#define LN_id_DHBasedMac                "Diffie-Hellman based MAC"
+#define NID_id_DHBasedMac               783
+#define OBJ_id_DHBasedMac               OBJ_ISO_US,113533L,7L,66L,30L
+
+#define SN_rsadsi               "rsadsi"
+#define LN_rsadsi               "RSA Data Security, Inc."
+#define NID_rsadsi              1
+#define OBJ_rsadsi              OBJ_ISO_US,113549L
+
+#define SN_pkcs         "pkcs"
+#define LN_pkcs         "RSA Data Security, Inc. PKCS"
+#define NID_pkcs                2
+#define OBJ_pkcs                OBJ_rsadsi,1L
+
+#define SN_pkcs1                "pkcs1"
+#define NID_pkcs1               186
+#define OBJ_pkcs1               OBJ_pkcs,1L
+
+#define LN_rsaEncryption                "rsaEncryption"
+#define NID_rsaEncryption               6
+#define OBJ_rsaEncryption               OBJ_pkcs1,1L
+
+#define SN_md2WithRSAEncryption         "RSA-MD2"
+#define LN_md2WithRSAEncryption         "md2WithRSAEncryption"
+#define NID_md2WithRSAEncryption                7
+#define OBJ_md2WithRSAEncryption                OBJ_pkcs1,2L
+
+#define SN_md4WithRSAEncryption         "RSA-MD4"
+#define LN_md4WithRSAEncryption         "md4WithRSAEncryption"
+#define NID_md4WithRSAEncryption                396
+#define OBJ_md4WithRSAEncryption                OBJ_pkcs1,3L
+
+#define SN_md5WithRSAEncryption         "RSA-MD5"
+#define LN_md5WithRSAEncryption         "md5WithRSAEncryption"
+#define NID_md5WithRSAEncryption                8
+#define OBJ_md5WithRSAEncryption                OBJ_pkcs1,4L
+
+#define SN_sha1WithRSAEncryption                "RSA-SHA1"
+#define LN_sha1WithRSAEncryption                "sha1WithRSAEncryption"
+#define NID_sha1WithRSAEncryption               65
+#define OBJ_sha1WithRSAEncryption               OBJ_pkcs1,5L
+
+#define SN_rsaesOaep            "RSAES-OAEP"
+#define LN_rsaesOaep            "rsaesOaep"
+#define NID_rsaesOaep           919
+#define OBJ_rsaesOaep           OBJ_pkcs1,7L
+
+#define SN_mgf1         "MGF1"
+#define LN_mgf1         "mgf1"
+#define NID_mgf1                911
+#define OBJ_mgf1                OBJ_pkcs1,8L
+
+#define SN_pSpecified           "PSPECIFIED"
+#define LN_pSpecified           "pSpecified"
+#define NID_pSpecified          935
+#define OBJ_pSpecified          OBJ_pkcs1,9L
+
+#define SN_rsassaPss            "RSASSA-PSS"
+#define LN_rsassaPss            "rsassaPss"
+#define NID_rsassaPss           912
+#define OBJ_rsassaPss           OBJ_pkcs1,10L
+
+#define SN_sha256WithRSAEncryption              "RSA-SHA256"
+#define LN_sha256WithRSAEncryption              "sha256WithRSAEncryption"
+#define NID_sha256WithRSAEncryption             668
+#define OBJ_sha256WithRSAEncryption             OBJ_pkcs1,11L
+
+#define SN_sha384WithRSAEncryption              "RSA-SHA384"
+#define LN_sha384WithRSAEncryption              "sha384WithRSAEncryption"
+#define NID_sha384WithRSAEncryption             669
+#define OBJ_sha384WithRSAEncryption             OBJ_pkcs1,12L
+
+#define SN_sha512WithRSAEncryption              "RSA-SHA512"
+#define LN_sha512WithRSAEncryption              "sha512WithRSAEncryption"
+#define NID_sha512WithRSAEncryption             670
+#define OBJ_sha512WithRSAEncryption             OBJ_pkcs1,13L
+
+#define SN_sha224WithRSAEncryption              "RSA-SHA224"
+#define LN_sha224WithRSAEncryption              "sha224WithRSAEncryption"
+#define NID_sha224WithRSAEncryption             671
+#define OBJ_sha224WithRSAEncryption             OBJ_pkcs1,14L
+
+#define SN_pkcs3                "pkcs3"
+#define NID_pkcs3               27
+#define OBJ_pkcs3               OBJ_pkcs,3L
+
+#define LN_dhKeyAgreement               "dhKeyAgreement"
+#define NID_dhKeyAgreement              28
+#define OBJ_dhKeyAgreement              OBJ_pkcs3,1L
+
+#define SN_pkcs5                "pkcs5"
+#define NID_pkcs5               187
+#define OBJ_pkcs5               OBJ_pkcs,5L
+
+#define SN_pbeWithMD2AndDES_CBC         "PBE-MD2-DES"
+#define LN_pbeWithMD2AndDES_CBC         "pbeWithMD2AndDES-CBC"
+#define NID_pbeWithMD2AndDES_CBC                9
+#define OBJ_pbeWithMD2AndDES_CBC                OBJ_pkcs5,1L
+
+#define SN_pbeWithMD5AndDES_CBC         "PBE-MD5-DES"
+#define LN_pbeWithMD5AndDES_CBC         "pbeWithMD5AndDES-CBC"
+#define NID_pbeWithMD5AndDES_CBC                10
+#define OBJ_pbeWithMD5AndDES_CBC                OBJ_pkcs5,3L
+
+#define SN_pbeWithMD2AndRC2_CBC         "PBE-MD2-RC2-64"
+#define LN_pbeWithMD2AndRC2_CBC         "pbeWithMD2AndRC2-CBC"
+#define NID_pbeWithMD2AndRC2_CBC                168
+#define OBJ_pbeWithMD2AndRC2_CBC                OBJ_pkcs5,4L
+
+#define SN_pbeWithMD5AndRC2_CBC         "PBE-MD5-RC2-64"
+#define LN_pbeWithMD5AndRC2_CBC         "pbeWithMD5AndRC2-CBC"
+#define NID_pbeWithMD5AndRC2_CBC                169
+#define OBJ_pbeWithMD5AndRC2_CBC                OBJ_pkcs5,6L
+
+#define SN_pbeWithSHA1AndDES_CBC                "PBE-SHA1-DES"
+#define LN_pbeWithSHA1AndDES_CBC                "pbeWithSHA1AndDES-CBC"
+#define NID_pbeWithSHA1AndDES_CBC               170
+#define OBJ_pbeWithSHA1AndDES_CBC               OBJ_pkcs5,10L
+
+#define SN_pbeWithSHA1AndRC2_CBC                "PBE-SHA1-RC2-64"
+#define LN_pbeWithSHA1AndRC2_CBC                "pbeWithSHA1AndRC2-CBC"
+#define NID_pbeWithSHA1AndRC2_CBC               68
+#define OBJ_pbeWithSHA1AndRC2_CBC               OBJ_pkcs5,11L
+
+#define LN_id_pbkdf2            "PBKDF2"
+#define NID_id_pbkdf2           69
+#define OBJ_id_pbkdf2           OBJ_pkcs5,12L
+
+#define LN_pbes2                "PBES2"
+#define NID_pbes2               161
+#define OBJ_pbes2               OBJ_pkcs5,13L
+
+#define LN_pbmac1               "PBMAC1"
+#define NID_pbmac1              162
+#define OBJ_pbmac1              OBJ_pkcs5,14L
+
+#define SN_pkcs7                "pkcs7"
+#define NID_pkcs7               20
+#define OBJ_pkcs7               OBJ_pkcs,7L
+
+#define LN_pkcs7_data           "pkcs7-data"
+#define NID_pkcs7_data          21
+#define OBJ_pkcs7_data          OBJ_pkcs7,1L
+
+#define LN_pkcs7_signed         "pkcs7-signedData"
+#define NID_pkcs7_signed                22
+#define OBJ_pkcs7_signed                OBJ_pkcs7,2L
+
+#define LN_pkcs7_enveloped              "pkcs7-envelopedData"
+#define NID_pkcs7_enveloped             23
+#define OBJ_pkcs7_enveloped             OBJ_pkcs7,3L
+
+#define LN_pkcs7_signedAndEnveloped             "pkcs7-signedAndEnvelopedData"
+#define NID_pkcs7_signedAndEnveloped            24
+#define OBJ_pkcs7_signedAndEnveloped            OBJ_pkcs7,4L
+
+#define LN_pkcs7_digest         "pkcs7-digestData"
+#define NID_pkcs7_digest                25
+#define OBJ_pkcs7_digest                OBJ_pkcs7,5L
+
+#define LN_pkcs7_encrypted              "pkcs7-encryptedData"
+#define NID_pkcs7_encrypted             26
+#define OBJ_pkcs7_encrypted             OBJ_pkcs7,6L
+
+#define SN_pkcs9                "pkcs9"
+#define NID_pkcs9               47
+#define OBJ_pkcs9               OBJ_pkcs,9L
+
+#define LN_pkcs9_emailAddress           "emailAddress"
+#define NID_pkcs9_emailAddress          48
+#define OBJ_pkcs9_emailAddress          OBJ_pkcs9,1L
+
+#define LN_pkcs9_unstructuredName               "unstructuredName"
+#define NID_pkcs9_unstructuredName              49
+#define OBJ_pkcs9_unstructuredName              OBJ_pkcs9,2L
+
+#define LN_pkcs9_contentType            "contentType"
+#define NID_pkcs9_contentType           50
+#define OBJ_pkcs9_contentType           OBJ_pkcs9,3L
+
+#define LN_pkcs9_messageDigest          "messageDigest"
+#define NID_pkcs9_messageDigest         51
+#define OBJ_pkcs9_messageDigest         OBJ_pkcs9,4L
+
+#define LN_pkcs9_signingTime            "signingTime"
+#define NID_pkcs9_signingTime           52
+#define OBJ_pkcs9_signingTime           OBJ_pkcs9,5L
+
+#define LN_pkcs9_countersignature               "countersignature"
+#define NID_pkcs9_countersignature              53
+#define OBJ_pkcs9_countersignature              OBJ_pkcs9,6L
+
+#define LN_pkcs9_challengePassword              "challengePassword"
+#define NID_pkcs9_challengePassword             54
+#define OBJ_pkcs9_challengePassword             OBJ_pkcs9,7L
+
+#define LN_pkcs9_unstructuredAddress            "unstructuredAddress"
+#define NID_pkcs9_unstructuredAddress           55
+#define OBJ_pkcs9_unstructuredAddress           OBJ_pkcs9,8L
+
+#define LN_pkcs9_extCertAttributes              "extendedCertificateAttributes"
+#define NID_pkcs9_extCertAttributes             56
+#define OBJ_pkcs9_extCertAttributes             OBJ_pkcs9,9L
+
+#define SN_ext_req              "extReq"
+#define LN_ext_req              "Extension Request"
+#define NID_ext_req             172
+#define OBJ_ext_req             OBJ_pkcs9,14L
+
+#define SN_SMIMECapabilities            "SMIME-CAPS"
+#define LN_SMIMECapabilities            "S/MIME Capabilities"
+#define NID_SMIMECapabilities           167
+#define OBJ_SMIMECapabilities           OBJ_pkcs9,15L
+
+#define SN_SMIME                "SMIME"
+#define LN_SMIME                "S/MIME"
+#define NID_SMIME               188
+#define OBJ_SMIME               OBJ_pkcs9,16L
+
+#define SN_id_smime_mod         "id-smime-mod"
+#define NID_id_smime_mod                189
+#define OBJ_id_smime_mod                OBJ_SMIME,0L
+
+#define SN_id_smime_ct          "id-smime-ct"
+#define NID_id_smime_ct         190
+#define OBJ_id_smime_ct         OBJ_SMIME,1L
+
+#define SN_id_smime_aa          "id-smime-aa"
+#define NID_id_smime_aa         191
+#define OBJ_id_smime_aa         OBJ_SMIME,2L
+
+#define SN_id_smime_alg         "id-smime-alg"
+#define NID_id_smime_alg                192
+#define OBJ_id_smime_alg                OBJ_SMIME,3L
+
+#define SN_id_smime_cd          "id-smime-cd"
+#define NID_id_smime_cd         193
+#define OBJ_id_smime_cd         OBJ_SMIME,4L
+
+#define SN_id_smime_spq         "id-smime-spq"
+#define NID_id_smime_spq                194
+#define OBJ_id_smime_spq                OBJ_SMIME,5L
+
+#define SN_id_smime_cti         "id-smime-cti"
+#define NID_id_smime_cti                195
+#define OBJ_id_smime_cti                OBJ_SMIME,6L
+
+#define SN_id_smime_mod_cms             "id-smime-mod-cms"
+#define NID_id_smime_mod_cms            196
+#define OBJ_id_smime_mod_cms            OBJ_id_smime_mod,1L
+
+#define SN_id_smime_mod_ess             "id-smime-mod-ess"
+#define NID_id_smime_mod_ess            197
+#define OBJ_id_smime_mod_ess            OBJ_id_smime_mod,2L
+
+#define SN_id_smime_mod_oid             "id-smime-mod-oid"
+#define NID_id_smime_mod_oid            198
+#define OBJ_id_smime_mod_oid            OBJ_id_smime_mod,3L
+
+#define SN_id_smime_mod_msg_v3          "id-smime-mod-msg-v3"
+#define NID_id_smime_mod_msg_v3         199
+#define OBJ_id_smime_mod_msg_v3         OBJ_id_smime_mod,4L
+
+#define SN_id_smime_mod_ets_eSignature_88               "id-smime-mod-ets-eSignature-88"
+#define NID_id_smime_mod_ets_eSignature_88              200
+#define OBJ_id_smime_mod_ets_eSignature_88              OBJ_id_smime_mod,5L
+
+#define SN_id_smime_mod_ets_eSignature_97               "id-smime-mod-ets-eSignature-97"
+#define NID_id_smime_mod_ets_eSignature_97              201
+#define OBJ_id_smime_mod_ets_eSignature_97              OBJ_id_smime_mod,6L
+
+#define SN_id_smime_mod_ets_eSigPolicy_88               "id-smime-mod-ets-eSigPolicy-88"
+#define NID_id_smime_mod_ets_eSigPolicy_88              202
+#define OBJ_id_smime_mod_ets_eSigPolicy_88              OBJ_id_smime_mod,7L
+
+#define SN_id_smime_mod_ets_eSigPolicy_97               "id-smime-mod-ets-eSigPolicy-97"
+#define NID_id_smime_mod_ets_eSigPolicy_97              203
+#define OBJ_id_smime_mod_ets_eSigPolicy_97              OBJ_id_smime_mod,8L
+
+#define SN_id_smime_ct_receipt          "id-smime-ct-receipt"
+#define NID_id_smime_ct_receipt         204
+#define OBJ_id_smime_ct_receipt         OBJ_id_smime_ct,1L
+
+#define SN_id_smime_ct_authData         "id-smime-ct-authData"
+#define NID_id_smime_ct_authData                205
+#define OBJ_id_smime_ct_authData                OBJ_id_smime_ct,2L
+
+#define SN_id_smime_ct_publishCert              "id-smime-ct-publishCert"
+#define NID_id_smime_ct_publishCert             206
+#define OBJ_id_smime_ct_publishCert             OBJ_id_smime_ct,3L
+
+#define SN_id_smime_ct_TSTInfo          "id-smime-ct-TSTInfo"
+#define NID_id_smime_ct_TSTInfo         207
+#define OBJ_id_smime_ct_TSTInfo         OBJ_id_smime_ct,4L
+
+#define SN_id_smime_ct_TDTInfo          "id-smime-ct-TDTInfo"
+#define NID_id_smime_ct_TDTInfo         208
+#define OBJ_id_smime_ct_TDTInfo         OBJ_id_smime_ct,5L
+
+#define SN_id_smime_ct_contentInfo              "id-smime-ct-contentInfo"
+#define NID_id_smime_ct_contentInfo             209
+#define OBJ_id_smime_ct_contentInfo             OBJ_id_smime_ct,6L
+
+#define SN_id_smime_ct_DVCSRequestData          "id-smime-ct-DVCSRequestData"
+#define NID_id_smime_ct_DVCSRequestData         210
+#define OBJ_id_smime_ct_DVCSRequestData         OBJ_id_smime_ct,7L
+
+#define SN_id_smime_ct_DVCSResponseData         "id-smime-ct-DVCSResponseData"
+#define NID_id_smime_ct_DVCSResponseData                211
+#define OBJ_id_smime_ct_DVCSResponseData                OBJ_id_smime_ct,8L
+
+#define SN_id_smime_ct_compressedData           "id-smime-ct-compressedData"
+#define NID_id_smime_ct_compressedData          786
+#define OBJ_id_smime_ct_compressedData          OBJ_id_smime_ct,9L
+
+#define SN_id_smime_ct_contentCollection                "id-smime-ct-contentCollection"
+#define NID_id_smime_ct_contentCollection               1058
+#define OBJ_id_smime_ct_contentCollection               OBJ_id_smime_ct,19L
+
+#define SN_id_smime_ct_authEnvelopedData                "id-smime-ct-authEnvelopedData"
+#define NID_id_smime_ct_authEnvelopedData               1059
+#define OBJ_id_smime_ct_authEnvelopedData               OBJ_id_smime_ct,23L
+
+#define SN_id_ct_asciiTextWithCRLF              "id-ct-asciiTextWithCRLF"
+#define NID_id_ct_asciiTextWithCRLF             787
+#define OBJ_id_ct_asciiTextWithCRLF             OBJ_id_smime_ct,27L
+
+#define SN_id_ct_xml            "id-ct-xml"
+#define NID_id_ct_xml           1060
+#define OBJ_id_ct_xml           OBJ_id_smime_ct,28L
+
+#define SN_id_smime_aa_receiptRequest           "id-smime-aa-receiptRequest"
+#define NID_id_smime_aa_receiptRequest          212
+#define OBJ_id_smime_aa_receiptRequest          OBJ_id_smime_aa,1L
+
+#define SN_id_smime_aa_securityLabel            "id-smime-aa-securityLabel"
+#define NID_id_smime_aa_securityLabel           213
+#define OBJ_id_smime_aa_securityLabel           OBJ_id_smime_aa,2L
+
+#define SN_id_smime_aa_mlExpandHistory          "id-smime-aa-mlExpandHistory"
+#define NID_id_smime_aa_mlExpandHistory         214
+#define OBJ_id_smime_aa_mlExpandHistory         OBJ_id_smime_aa,3L
+
+#define SN_id_smime_aa_contentHint              "id-smime-aa-contentHint"
+#define NID_id_smime_aa_contentHint             215
+#define OBJ_id_smime_aa_contentHint             OBJ_id_smime_aa,4L
+
+#define SN_id_smime_aa_msgSigDigest             "id-smime-aa-msgSigDigest"
+#define NID_id_smime_aa_msgSigDigest            216
+#define OBJ_id_smime_aa_msgSigDigest            OBJ_id_smime_aa,5L
+
+#define SN_id_smime_aa_encapContentType         "id-smime-aa-encapContentType"
+#define NID_id_smime_aa_encapContentType                217
+#define OBJ_id_smime_aa_encapContentType                OBJ_id_smime_aa,6L
+
+#define SN_id_smime_aa_contentIdentifier                "id-smime-aa-contentIdentifier"
+#define NID_id_smime_aa_contentIdentifier               218
+#define OBJ_id_smime_aa_contentIdentifier               OBJ_id_smime_aa,7L
+
+#define SN_id_smime_aa_macValue         "id-smime-aa-macValue"
+#define NID_id_smime_aa_macValue                219
+#define OBJ_id_smime_aa_macValue                OBJ_id_smime_aa,8L
+
+#define SN_id_smime_aa_equivalentLabels         "id-smime-aa-equivalentLabels"
+#define NID_id_smime_aa_equivalentLabels                220
+#define OBJ_id_smime_aa_equivalentLabels                OBJ_id_smime_aa,9L
+
+#define SN_id_smime_aa_contentReference         "id-smime-aa-contentReference"
+#define NID_id_smime_aa_contentReference                221
+#define OBJ_id_smime_aa_contentReference                OBJ_id_smime_aa,10L
+
+#define SN_id_smime_aa_encrypKeyPref            "id-smime-aa-encrypKeyPref"
+#define NID_id_smime_aa_encrypKeyPref           222
+#define OBJ_id_smime_aa_encrypKeyPref           OBJ_id_smime_aa,11L
+
+#define SN_id_smime_aa_signingCertificate               "id-smime-aa-signingCertificate"
+#define NID_id_smime_aa_signingCertificate              223
+#define OBJ_id_smime_aa_signingCertificate              OBJ_id_smime_aa,12L
+
+#define SN_id_smime_aa_smimeEncryptCerts                "id-smime-aa-smimeEncryptCerts"
+#define NID_id_smime_aa_smimeEncryptCerts               224
+#define OBJ_id_smime_aa_smimeEncryptCerts               OBJ_id_smime_aa,13L
+
+#define SN_id_smime_aa_timeStampToken           "id-smime-aa-timeStampToken"
+#define NID_id_smime_aa_timeStampToken          225
+#define OBJ_id_smime_aa_timeStampToken          OBJ_id_smime_aa,14L
+
+#define SN_id_smime_aa_ets_sigPolicyId          "id-smime-aa-ets-sigPolicyId"
+#define NID_id_smime_aa_ets_sigPolicyId         226
+#define OBJ_id_smime_aa_ets_sigPolicyId         OBJ_id_smime_aa,15L
+
+#define SN_id_smime_aa_ets_commitmentType               "id-smime-aa-ets-commitmentType"
+#define NID_id_smime_aa_ets_commitmentType              227
+#define OBJ_id_smime_aa_ets_commitmentType              OBJ_id_smime_aa,16L
+
+#define SN_id_smime_aa_ets_signerLocation               "id-smime-aa-ets-signerLocation"
+#define NID_id_smime_aa_ets_signerLocation              228
+#define OBJ_id_smime_aa_ets_signerLocation              OBJ_id_smime_aa,17L
+
+#define SN_id_smime_aa_ets_signerAttr           "id-smime-aa-ets-signerAttr"
+#define NID_id_smime_aa_ets_signerAttr          229
+#define OBJ_id_smime_aa_ets_signerAttr          OBJ_id_smime_aa,18L
+
+#define SN_id_smime_aa_ets_otherSigCert         "id-smime-aa-ets-otherSigCert"
+#define NID_id_smime_aa_ets_otherSigCert                230
+#define OBJ_id_smime_aa_ets_otherSigCert                OBJ_id_smime_aa,19L
+
+#define SN_id_smime_aa_ets_contentTimestamp             "id-smime-aa-ets-contentTimestamp"
+#define NID_id_smime_aa_ets_contentTimestamp            231
+#define OBJ_id_smime_aa_ets_contentTimestamp            OBJ_id_smime_aa,20L
+
+#define SN_id_smime_aa_ets_CertificateRefs              "id-smime-aa-ets-CertificateRefs"
+#define NID_id_smime_aa_ets_CertificateRefs             232
+#define OBJ_id_smime_aa_ets_CertificateRefs             OBJ_id_smime_aa,21L
+
+#define SN_id_smime_aa_ets_RevocationRefs               "id-smime-aa-ets-RevocationRefs"
+#define NID_id_smime_aa_ets_RevocationRefs              233
+#define OBJ_id_smime_aa_ets_RevocationRefs              OBJ_id_smime_aa,22L
+
+#define SN_id_smime_aa_ets_certValues           "id-smime-aa-ets-certValues"
+#define NID_id_smime_aa_ets_certValues          234
+#define OBJ_id_smime_aa_ets_certValues          OBJ_id_smime_aa,23L
+
+#define SN_id_smime_aa_ets_revocationValues             "id-smime-aa-ets-revocationValues"
+#define NID_id_smime_aa_ets_revocationValues            235
+#define OBJ_id_smime_aa_ets_revocationValues            OBJ_id_smime_aa,24L
+
+#define SN_id_smime_aa_ets_escTimeStamp         "id-smime-aa-ets-escTimeStamp"
+#define NID_id_smime_aa_ets_escTimeStamp                236
+#define OBJ_id_smime_aa_ets_escTimeStamp                OBJ_id_smime_aa,25L
+
+#define SN_id_smime_aa_ets_certCRLTimestamp             "id-smime-aa-ets-certCRLTimestamp"
+#define NID_id_smime_aa_ets_certCRLTimestamp            237
+#define OBJ_id_smime_aa_ets_certCRLTimestamp            OBJ_id_smime_aa,26L
+
+#define SN_id_smime_aa_ets_archiveTimeStamp             "id-smime-aa-ets-archiveTimeStamp"
+#define NID_id_smime_aa_ets_archiveTimeStamp            238
+#define OBJ_id_smime_aa_ets_archiveTimeStamp            OBJ_id_smime_aa,27L
+
+#define SN_id_smime_aa_signatureType            "id-smime-aa-signatureType"
+#define NID_id_smime_aa_signatureType           239
+#define OBJ_id_smime_aa_signatureType           OBJ_id_smime_aa,28L
+
+#define SN_id_smime_aa_dvcs_dvc         "id-smime-aa-dvcs-dvc"
+#define NID_id_smime_aa_dvcs_dvc                240
+#define OBJ_id_smime_aa_dvcs_dvc                OBJ_id_smime_aa,29L
+
+#define SN_id_smime_alg_ESDHwith3DES            "id-smime-alg-ESDHwith3DES"
+#define NID_id_smime_alg_ESDHwith3DES           241
+#define OBJ_id_smime_alg_ESDHwith3DES           OBJ_id_smime_alg,1L
+
+#define SN_id_smime_alg_ESDHwithRC2             "id-smime-alg-ESDHwithRC2"
+#define NID_id_smime_alg_ESDHwithRC2            242
+#define OBJ_id_smime_alg_ESDHwithRC2            OBJ_id_smime_alg,2L
+
+#define SN_id_smime_alg_3DESwrap                "id-smime-alg-3DESwrap"
+#define NID_id_smime_alg_3DESwrap               243
+#define OBJ_id_smime_alg_3DESwrap               OBJ_id_smime_alg,3L
+
+#define SN_id_smime_alg_RC2wrap         "id-smime-alg-RC2wrap"
+#define NID_id_smime_alg_RC2wrap                244
+#define OBJ_id_smime_alg_RC2wrap                OBJ_id_smime_alg,4L
+
+#define SN_id_smime_alg_ESDH            "id-smime-alg-ESDH"
+#define NID_id_smime_alg_ESDH           245
+#define OBJ_id_smime_alg_ESDH           OBJ_id_smime_alg,5L
+
+#define SN_id_smime_alg_CMS3DESwrap             "id-smime-alg-CMS3DESwrap"
+#define NID_id_smime_alg_CMS3DESwrap            246
+#define OBJ_id_smime_alg_CMS3DESwrap            OBJ_id_smime_alg,6L
+
+#define SN_id_smime_alg_CMSRC2wrap              "id-smime-alg-CMSRC2wrap"
+#define NID_id_smime_alg_CMSRC2wrap             247
+#define OBJ_id_smime_alg_CMSRC2wrap             OBJ_id_smime_alg,7L
+
+#define SN_id_alg_PWRI_KEK              "id-alg-PWRI-KEK"
+#define NID_id_alg_PWRI_KEK             893
+#define OBJ_id_alg_PWRI_KEK             OBJ_id_smime_alg,9L
+
+#define SN_id_smime_cd_ldap             "id-smime-cd-ldap"
+#define NID_id_smime_cd_ldap            248
+#define OBJ_id_smime_cd_ldap            OBJ_id_smime_cd,1L
+
+#define SN_id_smime_spq_ets_sqt_uri             "id-smime-spq-ets-sqt-uri"
+#define NID_id_smime_spq_ets_sqt_uri            249
+#define OBJ_id_smime_spq_ets_sqt_uri            OBJ_id_smime_spq,1L
+
+#define SN_id_smime_spq_ets_sqt_unotice         "id-smime-spq-ets-sqt-unotice"
+#define NID_id_smime_spq_ets_sqt_unotice                250
+#define OBJ_id_smime_spq_ets_sqt_unotice                OBJ_id_smime_spq,2L
+
+#define SN_id_smime_cti_ets_proofOfOrigin               "id-smime-cti-ets-proofOfOrigin"
+#define NID_id_smime_cti_ets_proofOfOrigin              251
+#define OBJ_id_smime_cti_ets_proofOfOrigin              OBJ_id_smime_cti,1L
+
+#define SN_id_smime_cti_ets_proofOfReceipt              "id-smime-cti-ets-proofOfReceipt"
+#define NID_id_smime_cti_ets_proofOfReceipt             252
+#define OBJ_id_smime_cti_ets_proofOfReceipt             OBJ_id_smime_cti,2L
+
+#define SN_id_smime_cti_ets_proofOfDelivery             "id-smime-cti-ets-proofOfDelivery"
+#define NID_id_smime_cti_ets_proofOfDelivery            253
+#define OBJ_id_smime_cti_ets_proofOfDelivery            OBJ_id_smime_cti,3L
+
+#define SN_id_smime_cti_ets_proofOfSender               "id-smime-cti-ets-proofOfSender"
+#define NID_id_smime_cti_ets_proofOfSender              254
+#define OBJ_id_smime_cti_ets_proofOfSender              OBJ_id_smime_cti,4L
+
+#define SN_id_smime_cti_ets_proofOfApproval             "id-smime-cti-ets-proofOfApproval"
+#define NID_id_smime_cti_ets_proofOfApproval            255
+#define OBJ_id_smime_cti_ets_proofOfApproval            OBJ_id_smime_cti,5L
+
+#define SN_id_smime_cti_ets_proofOfCreation             "id-smime-cti-ets-proofOfCreation"
+#define NID_id_smime_cti_ets_proofOfCreation            256
+#define OBJ_id_smime_cti_ets_proofOfCreation            OBJ_id_smime_cti,6L
+
+#define LN_friendlyName         "friendlyName"
+#define NID_friendlyName                156
+#define OBJ_friendlyName                OBJ_pkcs9,20L
+
+#define LN_localKeyID           "localKeyID"
+#define NID_localKeyID          157
+#define OBJ_localKeyID          OBJ_pkcs9,21L
+
+#define SN_ms_csp_name          "CSPName"
+#define LN_ms_csp_name          "Microsoft CSP Name"
+#define NID_ms_csp_name         417
+#define OBJ_ms_csp_name         1L,3L,6L,1L,4L,1L,311L,17L,1L
+
+#define SN_LocalKeySet          "LocalKeySet"
+#define LN_LocalKeySet          "Microsoft Local Key set"
+#define NID_LocalKeySet         856
+#define OBJ_LocalKeySet         1L,3L,6L,1L,4L,1L,311L,17L,2L
+
+#define OBJ_certTypes           OBJ_pkcs9,22L
+
+#define LN_x509Certificate              "x509Certificate"
+#define NID_x509Certificate             158
+#define OBJ_x509Certificate             OBJ_certTypes,1L
+
+#define LN_sdsiCertificate              "sdsiCertificate"
+#define NID_sdsiCertificate             159
+#define OBJ_sdsiCertificate             OBJ_certTypes,2L
+
+#define OBJ_crlTypes            OBJ_pkcs9,23L
+
+#define LN_x509Crl              "x509Crl"
+#define NID_x509Crl             160
+#define OBJ_x509Crl             OBJ_crlTypes,1L
+
+#define OBJ_pkcs12              OBJ_pkcs,12L
+
+#define OBJ_pkcs12_pbeids               OBJ_pkcs12,1L
+
+#define SN_pbe_WithSHA1And128BitRC4             "PBE-SHA1-RC4-128"
+#define LN_pbe_WithSHA1And128BitRC4             "pbeWithSHA1And128BitRC4"
+#define NID_pbe_WithSHA1And128BitRC4            144
+#define OBJ_pbe_WithSHA1And128BitRC4            OBJ_pkcs12_pbeids,1L
+
+#define SN_pbe_WithSHA1And40BitRC4              "PBE-SHA1-RC4-40"
+#define LN_pbe_WithSHA1And40BitRC4              "pbeWithSHA1And40BitRC4"
+#define NID_pbe_WithSHA1And40BitRC4             145
+#define OBJ_pbe_WithSHA1And40BitRC4             OBJ_pkcs12_pbeids,2L
+
+#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC           "PBE-SHA1-3DES"
+#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC           "pbeWithSHA1And3-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC          146
+#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC          OBJ_pkcs12_pbeids,3L
+
+#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC           "PBE-SHA1-2DES"
+#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC           "pbeWithSHA1And2-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC          147
+#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC          OBJ_pkcs12_pbeids,4L
+
+#define SN_pbe_WithSHA1And128BitRC2_CBC         "PBE-SHA1-RC2-128"
+#define LN_pbe_WithSHA1And128BitRC2_CBC         "pbeWithSHA1And128BitRC2-CBC"
+#define NID_pbe_WithSHA1And128BitRC2_CBC                148
+#define OBJ_pbe_WithSHA1And128BitRC2_CBC                OBJ_pkcs12_pbeids,5L
+
+#define SN_pbe_WithSHA1And40BitRC2_CBC          "PBE-SHA1-RC2-40"
+#define LN_pbe_WithSHA1And40BitRC2_CBC          "pbeWithSHA1And40BitRC2-CBC"
+#define NID_pbe_WithSHA1And40BitRC2_CBC         149
+#define OBJ_pbe_WithSHA1And40BitRC2_CBC         OBJ_pkcs12_pbeids,6L
+
+#define OBJ_pkcs12_Version1             OBJ_pkcs12,10L
+
+#define OBJ_pkcs12_BagIds               OBJ_pkcs12_Version1,1L
+
+#define LN_keyBag               "keyBag"
+#define NID_keyBag              150
+#define OBJ_keyBag              OBJ_pkcs12_BagIds,1L
+
+#define LN_pkcs8ShroudedKeyBag          "pkcs8ShroudedKeyBag"
+#define NID_pkcs8ShroudedKeyBag         151
+#define OBJ_pkcs8ShroudedKeyBag         OBJ_pkcs12_BagIds,2L
+
+#define LN_certBag              "certBag"
+#define NID_certBag             152
+#define OBJ_certBag             OBJ_pkcs12_BagIds,3L
+
+#define LN_crlBag               "crlBag"
+#define NID_crlBag              153
+#define OBJ_crlBag              OBJ_pkcs12_BagIds,4L
+
+#define LN_secretBag            "secretBag"
+#define NID_secretBag           154
+#define OBJ_secretBag           OBJ_pkcs12_BagIds,5L
+
+#define LN_safeContentsBag              "safeContentsBag"
+#define NID_safeContentsBag             155
+#define OBJ_safeContentsBag             OBJ_pkcs12_BagIds,6L
+
+#define SN_md2          "MD2"
+#define LN_md2          "md2"
+#define NID_md2         3
+#define OBJ_md2         OBJ_rsadsi,2L,2L
+
+#define SN_md4          "MD4"
+#define LN_md4          "md4"
+#define NID_md4         257
+#define OBJ_md4         OBJ_rsadsi,2L,4L
+
+#define SN_md5          "MD5"
+#define LN_md5          "md5"
+#define NID_md5         4
+#define OBJ_md5         OBJ_rsadsi,2L,5L
+
+#define SN_md5_sha1             "MD5-SHA1"
+#define LN_md5_sha1             "md5-sha1"
+#define NID_md5_sha1            114
+
+#define LN_hmacWithMD5          "hmacWithMD5"
+#define NID_hmacWithMD5         797
+#define OBJ_hmacWithMD5         OBJ_rsadsi,2L,6L
+
+#define LN_hmacWithSHA1         "hmacWithSHA1"
+#define NID_hmacWithSHA1                163
+#define OBJ_hmacWithSHA1                OBJ_rsadsi,2L,7L
+
+#define LN_hmacWithSHA224               "hmacWithSHA224"
+#define NID_hmacWithSHA224              798
+#define OBJ_hmacWithSHA224              OBJ_rsadsi,2L,8L
+
+#define LN_hmacWithSHA256               "hmacWithSHA256"
+#define NID_hmacWithSHA256              799
+#define OBJ_hmacWithSHA256              OBJ_rsadsi,2L,9L
+
+#define LN_hmacWithSHA384               "hmacWithSHA384"
+#define NID_hmacWithSHA384              800
+#define OBJ_hmacWithSHA384              OBJ_rsadsi,2L,10L
+
+#define LN_hmacWithSHA512               "hmacWithSHA512"
+#define NID_hmacWithSHA512              801
+#define OBJ_hmacWithSHA512              OBJ_rsadsi,2L,11L
+
+#define SN_rc2_cbc              "RC2-CBC"
+#define LN_rc2_cbc              "rc2-cbc"
+#define NID_rc2_cbc             37
+#define OBJ_rc2_cbc             OBJ_rsadsi,3L,2L
+
+#define SN_rc2_ecb              "RC2-ECB"
+#define LN_rc2_ecb              "rc2-ecb"
+#define NID_rc2_ecb             38
+
+#define SN_rc2_cfb64            "RC2-CFB"
+#define LN_rc2_cfb64            "rc2-cfb"
+#define NID_rc2_cfb64           39
+
+#define SN_rc2_ofb64            "RC2-OFB"
+#define LN_rc2_ofb64            "rc2-ofb"
+#define NID_rc2_ofb64           40
+
+#define SN_rc2_40_cbc           "RC2-40-CBC"
+#define LN_rc2_40_cbc           "rc2-40-cbc"
+#define NID_rc2_40_cbc          98
+
+#define SN_rc2_64_cbc           "RC2-64-CBC"
+#define LN_rc2_64_cbc           "rc2-64-cbc"
+#define NID_rc2_64_cbc          166
+
+#define SN_rc4          "RC4"
+#define LN_rc4          "rc4"
+#define NID_rc4         5
+#define OBJ_rc4         OBJ_rsadsi,3L,4L
+
+#define SN_rc4_40               "RC4-40"
+#define LN_rc4_40               "rc4-40"
+#define NID_rc4_40              97
+
+#define SN_des_ede3_cbc         "DES-EDE3-CBC"
+#define LN_des_ede3_cbc         "des-ede3-cbc"
+#define NID_des_ede3_cbc                44
+#define OBJ_des_ede3_cbc                OBJ_rsadsi,3L,7L
+
+#define SN_rc5_cbc              "RC5-CBC"
+#define LN_rc5_cbc              "rc5-cbc"
+#define NID_rc5_cbc             120
+#define OBJ_rc5_cbc             OBJ_rsadsi,3L,8L
+
+#define SN_rc5_ecb              "RC5-ECB"
+#define LN_rc5_ecb              "rc5-ecb"
+#define NID_rc5_ecb             121
+
+#define SN_rc5_cfb64            "RC5-CFB"
+#define LN_rc5_cfb64            "rc5-cfb"
+#define NID_rc5_cfb64           122
+
+#define SN_rc5_ofb64            "RC5-OFB"
+#define LN_rc5_ofb64            "rc5-ofb"
+#define NID_rc5_ofb64           123
+
+#define SN_ms_ext_req           "msExtReq"
+#define LN_ms_ext_req           "Microsoft Extension Request"
+#define NID_ms_ext_req          171
+#define OBJ_ms_ext_req          1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
+
+#define SN_ms_code_ind          "msCodeInd"
+#define LN_ms_code_ind          "Microsoft Individual Code Signing"
+#define NID_ms_code_ind         134
+#define OBJ_ms_code_ind         1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
+
+#define SN_ms_code_com          "msCodeCom"
+#define LN_ms_code_com          "Microsoft Commercial Code Signing"
+#define NID_ms_code_com         135
+#define OBJ_ms_code_com         1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
+
+#define SN_ms_ctl_sign          "msCTLSign"
+#define LN_ms_ctl_sign          "Microsoft Trust List Signing"
+#define NID_ms_ctl_sign         136
+#define OBJ_ms_ctl_sign         1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
+
+#define SN_ms_sgc               "msSGC"
+#define LN_ms_sgc               "Microsoft Server Gated Crypto"
+#define NID_ms_sgc              137
+#define OBJ_ms_sgc              1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
+
+#define SN_ms_efs               "msEFS"
+#define LN_ms_efs               "Microsoft Encrypted File System"
+#define NID_ms_efs              138
+#define OBJ_ms_efs              1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
+
+#define SN_ms_smartcard_login           "msSmartcardLogin"
+#define LN_ms_smartcard_login           "Microsoft Smartcardlogin"
+#define NID_ms_smartcard_login          648
+#define OBJ_ms_smartcard_login          1L,3L,6L,1L,4L,1L,311L,20L,2L,2L
+
+#define SN_ms_upn               "msUPN"
+#define LN_ms_upn               "Microsoft Universal Principal Name"
+#define NID_ms_upn              649
+#define OBJ_ms_upn              1L,3L,6L,1L,4L,1L,311L,20L,2L,3L
+
+#define SN_idea_cbc             "IDEA-CBC"
+#define LN_idea_cbc             "idea-cbc"
+#define NID_idea_cbc            34
+#define OBJ_idea_cbc            1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
+
+#define SN_idea_ecb             "IDEA-ECB"
+#define LN_idea_ecb             "idea-ecb"
+#define NID_idea_ecb            36
+
+#define SN_idea_cfb64           "IDEA-CFB"
+#define LN_idea_cfb64           "idea-cfb"
+#define NID_idea_cfb64          35
+
+#define SN_idea_ofb64           "IDEA-OFB"
+#define LN_idea_ofb64           "idea-ofb"
+#define NID_idea_ofb64          46
+
+#define SN_bf_cbc               "BF-CBC"
+#define LN_bf_cbc               "bf-cbc"
+#define NID_bf_cbc              91
+#define OBJ_bf_cbc              1L,3L,6L,1L,4L,1L,3029L,1L,2L
+
+#define SN_bf_ecb               "BF-ECB"
+#define LN_bf_ecb               "bf-ecb"
+#define NID_bf_ecb              92
+
+#define SN_bf_cfb64             "BF-CFB"
+#define LN_bf_cfb64             "bf-cfb"
+#define NID_bf_cfb64            93
+
+#define SN_bf_ofb64             "BF-OFB"
+#define LN_bf_ofb64             "bf-ofb"
+#define NID_bf_ofb64            94
+
+#define SN_id_pkix              "PKIX"
+#define NID_id_pkix             127
+#define OBJ_id_pkix             1L,3L,6L,1L,5L,5L,7L
+
+#define SN_id_pkix_mod          "id-pkix-mod"
+#define NID_id_pkix_mod         258
+#define OBJ_id_pkix_mod         OBJ_id_pkix,0L
+
+#define SN_id_pe                "id-pe"
+#define NID_id_pe               175
+#define OBJ_id_pe               OBJ_id_pkix,1L
+
+#define SN_id_qt                "id-qt"
+#define NID_id_qt               259
+#define OBJ_id_qt               OBJ_id_pkix,2L
+
+#define SN_id_kp                "id-kp"
+#define NID_id_kp               128
+#define OBJ_id_kp               OBJ_id_pkix,3L
+
+#define SN_id_it                "id-it"
+#define NID_id_it               260
+#define OBJ_id_it               OBJ_id_pkix,4L
+
+#define SN_id_pkip              "id-pkip"
+#define NID_id_pkip             261
+#define OBJ_id_pkip             OBJ_id_pkix,5L
+
+#define SN_id_alg               "id-alg"
+#define NID_id_alg              262
+#define OBJ_id_alg              OBJ_id_pkix,6L
+
+#define SN_id_cmc               "id-cmc"
+#define NID_id_cmc              263
+#define OBJ_id_cmc              OBJ_id_pkix,7L
+
+#define SN_id_on                "id-on"
+#define NID_id_on               264
+#define OBJ_id_on               OBJ_id_pkix,8L
+
+#define SN_id_pda               "id-pda"
+#define NID_id_pda              265
+#define OBJ_id_pda              OBJ_id_pkix,9L
+
+#define SN_id_aca               "id-aca"
+#define NID_id_aca              266
+#define OBJ_id_aca              OBJ_id_pkix,10L
+
+#define SN_id_qcs               "id-qcs"
+#define NID_id_qcs              267
+#define OBJ_id_qcs              OBJ_id_pkix,11L
+
+#define SN_id_cct               "id-cct"
+#define NID_id_cct              268
+#define OBJ_id_cct              OBJ_id_pkix,12L
+
+#define SN_id_ppl               "id-ppl"
+#define NID_id_ppl              662
+#define OBJ_id_ppl              OBJ_id_pkix,21L
+
+#define SN_id_ad                "id-ad"
+#define NID_id_ad               176
+#define OBJ_id_ad               OBJ_id_pkix,48L
+
+#define SN_id_pkix1_explicit_88         "id-pkix1-explicit-88"
+#define NID_id_pkix1_explicit_88                269
+#define OBJ_id_pkix1_explicit_88                OBJ_id_pkix_mod,1L
+
+#define SN_id_pkix1_implicit_88         "id-pkix1-implicit-88"
+#define NID_id_pkix1_implicit_88                270
+#define OBJ_id_pkix1_implicit_88                OBJ_id_pkix_mod,2L
+
+#define SN_id_pkix1_explicit_93         "id-pkix1-explicit-93"
+#define NID_id_pkix1_explicit_93                271
+#define OBJ_id_pkix1_explicit_93                OBJ_id_pkix_mod,3L
+
+#define SN_id_pkix1_implicit_93         "id-pkix1-implicit-93"
+#define NID_id_pkix1_implicit_93                272
+#define OBJ_id_pkix1_implicit_93                OBJ_id_pkix_mod,4L
+
+#define SN_id_mod_crmf          "id-mod-crmf"
+#define NID_id_mod_crmf         273
+#define OBJ_id_mod_crmf         OBJ_id_pkix_mod,5L
+
+#define SN_id_mod_cmc           "id-mod-cmc"
+#define NID_id_mod_cmc          274
+#define OBJ_id_mod_cmc          OBJ_id_pkix_mod,6L
+
+#define SN_id_mod_kea_profile_88                "id-mod-kea-profile-88"
+#define NID_id_mod_kea_profile_88               275
+#define OBJ_id_mod_kea_profile_88               OBJ_id_pkix_mod,7L
+
+#define SN_id_mod_kea_profile_93                "id-mod-kea-profile-93"
+#define NID_id_mod_kea_profile_93               276
+#define OBJ_id_mod_kea_profile_93               OBJ_id_pkix_mod,8L
+
+#define SN_id_mod_cmp           "id-mod-cmp"
+#define NID_id_mod_cmp          277
+#define OBJ_id_mod_cmp          OBJ_id_pkix_mod,9L
+
+#define SN_id_mod_qualified_cert_88             "id-mod-qualified-cert-88"
+#define NID_id_mod_qualified_cert_88            278
+#define OBJ_id_mod_qualified_cert_88            OBJ_id_pkix_mod,10L
+
+#define SN_id_mod_qualified_cert_93             "id-mod-qualified-cert-93"
+#define NID_id_mod_qualified_cert_93            279
+#define OBJ_id_mod_qualified_cert_93            OBJ_id_pkix_mod,11L
+
+#define SN_id_mod_attribute_cert                "id-mod-attribute-cert"
+#define NID_id_mod_attribute_cert               280
+#define OBJ_id_mod_attribute_cert               OBJ_id_pkix_mod,12L
+
+#define SN_id_mod_timestamp_protocol            "id-mod-timestamp-protocol"
+#define NID_id_mod_timestamp_protocol           281
+#define OBJ_id_mod_timestamp_protocol           OBJ_id_pkix_mod,13L
+
+#define SN_id_mod_ocsp          "id-mod-ocsp"
+#define NID_id_mod_ocsp         282
+#define OBJ_id_mod_ocsp         OBJ_id_pkix_mod,14L
+
+#define SN_id_mod_dvcs          "id-mod-dvcs"
+#define NID_id_mod_dvcs         283
+#define OBJ_id_mod_dvcs         OBJ_id_pkix_mod,15L
+
+#define SN_id_mod_cmp2000               "id-mod-cmp2000"
+#define NID_id_mod_cmp2000              284
+#define OBJ_id_mod_cmp2000              OBJ_id_pkix_mod,16L
+
+#define SN_info_access          "authorityInfoAccess"
+#define LN_info_access          "Authority Information Access"
+#define NID_info_access         177
+#define OBJ_info_access         OBJ_id_pe,1L
+
+#define SN_biometricInfo                "biometricInfo"
+#define LN_biometricInfo                "Biometric Info"
+#define NID_biometricInfo               285
+#define OBJ_biometricInfo               OBJ_id_pe,2L
+
+#define SN_qcStatements         "qcStatements"
+#define NID_qcStatements                286
+#define OBJ_qcStatements                OBJ_id_pe,3L
+
+#define SN_ac_auditEntity               "ac-auditEntity"
+#define NID_ac_auditEntity              287
+#define OBJ_ac_auditEntity              OBJ_id_pe,4L
+
+#define SN_ac_targeting         "ac-targeting"
+#define NID_ac_targeting                288
+#define OBJ_ac_targeting                OBJ_id_pe,5L
+
+#define SN_aaControls           "aaControls"
+#define NID_aaControls          289
+#define OBJ_aaControls          OBJ_id_pe,6L
+
+#define SN_sbgp_ipAddrBlock             "sbgp-ipAddrBlock"
+#define NID_sbgp_ipAddrBlock            290
+#define OBJ_sbgp_ipAddrBlock            OBJ_id_pe,7L
+
+#define SN_sbgp_autonomousSysNum                "sbgp-autonomousSysNum"
+#define NID_sbgp_autonomousSysNum               291
+#define OBJ_sbgp_autonomousSysNum               OBJ_id_pe,8L
+
+#define SN_sbgp_routerIdentifier                "sbgp-routerIdentifier"
+#define NID_sbgp_routerIdentifier               292
+#define OBJ_sbgp_routerIdentifier               OBJ_id_pe,9L
+
+#define SN_ac_proxying          "ac-proxying"
+#define NID_ac_proxying         397
+#define OBJ_ac_proxying         OBJ_id_pe,10L
+
+#define SN_sinfo_access         "subjectInfoAccess"
+#define LN_sinfo_access         "Subject Information Access"
+#define NID_sinfo_access                398
+#define OBJ_sinfo_access                OBJ_id_pe,11L
+
+#define SN_proxyCertInfo                "proxyCertInfo"
+#define LN_proxyCertInfo                "Proxy Certificate Information"
+#define NID_proxyCertInfo               663
+#define OBJ_proxyCertInfo               OBJ_id_pe,14L
+
+#define SN_tlsfeature           "tlsfeature"
+#define LN_tlsfeature           "TLS Feature"
+#define NID_tlsfeature          1020
+#define OBJ_tlsfeature          OBJ_id_pe,24L
+
+#define SN_id_qt_cps            "id-qt-cps"
+#define LN_id_qt_cps            "Policy Qualifier CPS"
+#define NID_id_qt_cps           164
+#define OBJ_id_qt_cps           OBJ_id_qt,1L
+
+#define SN_id_qt_unotice                "id-qt-unotice"
+#define LN_id_qt_unotice                "Policy Qualifier User Notice"
+#define NID_id_qt_unotice               165
+#define OBJ_id_qt_unotice               OBJ_id_qt,2L
+
+#define SN_textNotice           "textNotice"
+#define NID_textNotice          293
+#define OBJ_textNotice          OBJ_id_qt,3L
+
+#define SN_server_auth          "serverAuth"
+#define LN_server_auth          "TLS Web Server Authentication"
+#define NID_server_auth         129
+#define OBJ_server_auth         OBJ_id_kp,1L
+
+#define SN_client_auth          "clientAuth"
+#define LN_client_auth          "TLS Web Client Authentication"
+#define NID_client_auth         130
+#define OBJ_client_auth         OBJ_id_kp,2L
+
+#define SN_code_sign            "codeSigning"
+#define LN_code_sign            "Code Signing"
+#define NID_code_sign           131
+#define OBJ_code_sign           OBJ_id_kp,3L
+
+#define SN_email_protect                "emailProtection"
+#define LN_email_protect                "E-mail Protection"
+#define NID_email_protect               132
+#define OBJ_email_protect               OBJ_id_kp,4L
+
+#define SN_ipsecEndSystem               "ipsecEndSystem"
+#define LN_ipsecEndSystem               "IPSec End System"
+#define NID_ipsecEndSystem              294
+#define OBJ_ipsecEndSystem              OBJ_id_kp,5L
+
+#define SN_ipsecTunnel          "ipsecTunnel"
+#define LN_ipsecTunnel          "IPSec Tunnel"
+#define NID_ipsecTunnel         295
+#define OBJ_ipsecTunnel         OBJ_id_kp,6L
+
+#define SN_ipsecUser            "ipsecUser"
+#define LN_ipsecUser            "IPSec User"
+#define NID_ipsecUser           296
+#define OBJ_ipsecUser           OBJ_id_kp,7L
+
+#define SN_time_stamp           "timeStamping"
+#define LN_time_stamp           "Time Stamping"
+#define NID_time_stamp          133
+#define OBJ_time_stamp          OBJ_id_kp,8L
+
+#define SN_OCSP_sign            "OCSPSigning"
+#define LN_OCSP_sign            "OCSP Signing"
+#define NID_OCSP_sign           180
+#define OBJ_OCSP_sign           OBJ_id_kp,9L
+
+#define SN_dvcs         "DVCS"
+#define LN_dvcs         "dvcs"
+#define NID_dvcs                297
+#define OBJ_dvcs                OBJ_id_kp,10L
+
+#define SN_ipsec_IKE            "ipsecIKE"
+#define LN_ipsec_IKE            "ipsec Internet Key Exchange"
+#define NID_ipsec_IKE           1022
+#define OBJ_ipsec_IKE           OBJ_id_kp,17L
+
+#define SN_capwapAC             "capwapAC"
+#define LN_capwapAC             "Ctrl/provision WAP Access"
+#define NID_capwapAC            1023
+#define OBJ_capwapAC            OBJ_id_kp,18L
+
+#define SN_capwapWTP            "capwapWTP"
+#define LN_capwapWTP            "Ctrl/Provision WAP Termination"
+#define NID_capwapWTP           1024
+#define OBJ_capwapWTP           OBJ_id_kp,19L
+
+#define SN_sshClient            "secureShellClient"
+#define LN_sshClient            "SSH Client"
+#define NID_sshClient           1025
+#define OBJ_sshClient           OBJ_id_kp,21L
+
+#define SN_sshServer            "secureShellServer"
+#define LN_sshServer            "SSH Server"
+#define NID_sshServer           1026
+#define OBJ_sshServer           OBJ_id_kp,22L
+
+#define SN_sendRouter           "sendRouter"
+#define LN_sendRouter           "Send Router"
+#define NID_sendRouter          1027
+#define OBJ_sendRouter          OBJ_id_kp,23L
+
+#define SN_sendProxiedRouter            "sendProxiedRouter"
+#define LN_sendProxiedRouter            "Send Proxied Router"
+#define NID_sendProxiedRouter           1028
+#define OBJ_sendProxiedRouter           OBJ_id_kp,24L
+
+#define SN_sendOwner            "sendOwner"
+#define LN_sendOwner            "Send Owner"
+#define NID_sendOwner           1029
+#define OBJ_sendOwner           OBJ_id_kp,25L
+
+#define SN_sendProxiedOwner             "sendProxiedOwner"
+#define LN_sendProxiedOwner             "Send Proxied Owner"
+#define NID_sendProxiedOwner            1030
+#define OBJ_sendProxiedOwner            OBJ_id_kp,26L
+
+#define SN_id_it_caProtEncCert          "id-it-caProtEncCert"
+#define NID_id_it_caProtEncCert         298
+#define OBJ_id_it_caProtEncCert         OBJ_id_it,1L
+
+#define SN_id_it_signKeyPairTypes               "id-it-signKeyPairTypes"
+#define NID_id_it_signKeyPairTypes              299
+#define OBJ_id_it_signKeyPairTypes              OBJ_id_it,2L
+
+#define SN_id_it_encKeyPairTypes                "id-it-encKeyPairTypes"
+#define NID_id_it_encKeyPairTypes               300
+#define OBJ_id_it_encKeyPairTypes               OBJ_id_it,3L
+
+#define SN_id_it_preferredSymmAlg               "id-it-preferredSymmAlg"
+#define NID_id_it_preferredSymmAlg              301
+#define OBJ_id_it_preferredSymmAlg              OBJ_id_it,4L
+
+#define SN_id_it_caKeyUpdateInfo                "id-it-caKeyUpdateInfo"
+#define NID_id_it_caKeyUpdateInfo               302
+#define OBJ_id_it_caKeyUpdateInfo               OBJ_id_it,5L
+
+#define SN_id_it_currentCRL             "id-it-currentCRL"
+#define NID_id_it_currentCRL            303
+#define OBJ_id_it_currentCRL            OBJ_id_it,6L
+
+#define SN_id_it_unsupportedOIDs                "id-it-unsupportedOIDs"
+#define NID_id_it_unsupportedOIDs               304
+#define OBJ_id_it_unsupportedOIDs               OBJ_id_it,7L
+
+#define SN_id_it_subscriptionRequest            "id-it-subscriptionRequest"
+#define NID_id_it_subscriptionRequest           305
+#define OBJ_id_it_subscriptionRequest           OBJ_id_it,8L
+
+#define SN_id_it_subscriptionResponse           "id-it-subscriptionResponse"
+#define NID_id_it_subscriptionResponse          306
+#define OBJ_id_it_subscriptionResponse          OBJ_id_it,9L
+
+#define SN_id_it_keyPairParamReq                "id-it-keyPairParamReq"
+#define NID_id_it_keyPairParamReq               307
+#define OBJ_id_it_keyPairParamReq               OBJ_id_it,10L
+
+#define SN_id_it_keyPairParamRep                "id-it-keyPairParamRep"
+#define NID_id_it_keyPairParamRep               308
+#define OBJ_id_it_keyPairParamRep               OBJ_id_it,11L
+
+#define SN_id_it_revPassphrase          "id-it-revPassphrase"
+#define NID_id_it_revPassphrase         309
+#define OBJ_id_it_revPassphrase         OBJ_id_it,12L
+
+#define SN_id_it_implicitConfirm                "id-it-implicitConfirm"
+#define NID_id_it_implicitConfirm               310
+#define OBJ_id_it_implicitConfirm               OBJ_id_it,13L
+
+#define SN_id_it_confirmWaitTime                "id-it-confirmWaitTime"
+#define NID_id_it_confirmWaitTime               311
+#define OBJ_id_it_confirmWaitTime               OBJ_id_it,14L
+
+#define SN_id_it_origPKIMessage         "id-it-origPKIMessage"
+#define NID_id_it_origPKIMessage                312
+#define OBJ_id_it_origPKIMessage                OBJ_id_it,15L
+
+#define SN_id_it_suppLangTags           "id-it-suppLangTags"
+#define NID_id_it_suppLangTags          784
+#define OBJ_id_it_suppLangTags          OBJ_id_it,16L
+
+#define SN_id_regCtrl           "id-regCtrl"
+#define NID_id_regCtrl          313
+#define OBJ_id_regCtrl          OBJ_id_pkip,1L
+
+#define SN_id_regInfo           "id-regInfo"
+#define NID_id_regInfo          314
+#define OBJ_id_regInfo          OBJ_id_pkip,2L
+
+#define SN_id_regCtrl_regToken          "id-regCtrl-regToken"
+#define NID_id_regCtrl_regToken         315
+#define OBJ_id_regCtrl_regToken         OBJ_id_regCtrl,1L
+
+#define SN_id_regCtrl_authenticator             "id-regCtrl-authenticator"
+#define NID_id_regCtrl_authenticator            316
+#define OBJ_id_regCtrl_authenticator            OBJ_id_regCtrl,2L
+
+#define SN_id_regCtrl_pkiPublicationInfo                "id-regCtrl-pkiPublicationInfo"
+#define NID_id_regCtrl_pkiPublicationInfo               317
+#define OBJ_id_regCtrl_pkiPublicationInfo               OBJ_id_regCtrl,3L
+
+#define SN_id_regCtrl_pkiArchiveOptions         "id-regCtrl-pkiArchiveOptions"
+#define NID_id_regCtrl_pkiArchiveOptions                318
+#define OBJ_id_regCtrl_pkiArchiveOptions                OBJ_id_regCtrl,4L
+
+#define SN_id_regCtrl_oldCertID         "id-regCtrl-oldCertID"
+#define NID_id_regCtrl_oldCertID                319
+#define OBJ_id_regCtrl_oldCertID                OBJ_id_regCtrl,5L
+
+#define SN_id_regCtrl_protocolEncrKey           "id-regCtrl-protocolEncrKey"
+#define NID_id_regCtrl_protocolEncrKey          320
+#define OBJ_id_regCtrl_protocolEncrKey          OBJ_id_regCtrl,6L
+
+#define SN_id_regInfo_utf8Pairs         "id-regInfo-utf8Pairs"
+#define NID_id_regInfo_utf8Pairs                321
+#define OBJ_id_regInfo_utf8Pairs                OBJ_id_regInfo,1L
+
+#define SN_id_regInfo_certReq           "id-regInfo-certReq"
+#define NID_id_regInfo_certReq          322
+#define OBJ_id_regInfo_certReq          OBJ_id_regInfo,2L
+
+#define SN_id_alg_des40         "id-alg-des40"
+#define NID_id_alg_des40                323
+#define OBJ_id_alg_des40                OBJ_id_alg,1L
+
+#define SN_id_alg_noSignature           "id-alg-noSignature"
+#define NID_id_alg_noSignature          324
+#define OBJ_id_alg_noSignature          OBJ_id_alg,2L
+
+#define SN_id_alg_dh_sig_hmac_sha1              "id-alg-dh-sig-hmac-sha1"
+#define NID_id_alg_dh_sig_hmac_sha1             325
+#define OBJ_id_alg_dh_sig_hmac_sha1             OBJ_id_alg,3L
+
+#define SN_id_alg_dh_pop                "id-alg-dh-pop"
+#define NID_id_alg_dh_pop               326
+#define OBJ_id_alg_dh_pop               OBJ_id_alg,4L
+
+#define SN_id_cmc_statusInfo            "id-cmc-statusInfo"
+#define NID_id_cmc_statusInfo           327
+#define OBJ_id_cmc_statusInfo           OBJ_id_cmc,1L
+
+#define SN_id_cmc_identification                "id-cmc-identification"
+#define NID_id_cmc_identification               328
+#define OBJ_id_cmc_identification               OBJ_id_cmc,2L
+
+#define SN_id_cmc_identityProof         "id-cmc-identityProof"
+#define NID_id_cmc_identityProof                329
+#define OBJ_id_cmc_identityProof                OBJ_id_cmc,3L
+
+#define SN_id_cmc_dataReturn            "id-cmc-dataReturn"
+#define NID_id_cmc_dataReturn           330
+#define OBJ_id_cmc_dataReturn           OBJ_id_cmc,4L
+
+#define SN_id_cmc_transactionId         "id-cmc-transactionId"
+#define NID_id_cmc_transactionId                331
+#define OBJ_id_cmc_transactionId                OBJ_id_cmc,5L
+
+#define SN_id_cmc_senderNonce           "id-cmc-senderNonce"
+#define NID_id_cmc_senderNonce          332
+#define OBJ_id_cmc_senderNonce          OBJ_id_cmc,6L
+
+#define SN_id_cmc_recipientNonce                "id-cmc-recipientNonce"
+#define NID_id_cmc_recipientNonce               333
+#define OBJ_id_cmc_recipientNonce               OBJ_id_cmc,7L
+
+#define SN_id_cmc_addExtensions         "id-cmc-addExtensions"
+#define NID_id_cmc_addExtensions                334
+#define OBJ_id_cmc_addExtensions                OBJ_id_cmc,8L
+
+#define SN_id_cmc_encryptedPOP          "id-cmc-encryptedPOP"
+#define NID_id_cmc_encryptedPOP         335
+#define OBJ_id_cmc_encryptedPOP         OBJ_id_cmc,9L
+
+#define SN_id_cmc_decryptedPOP          "id-cmc-decryptedPOP"
+#define NID_id_cmc_decryptedPOP         336
+#define OBJ_id_cmc_decryptedPOP         OBJ_id_cmc,10L
+
+#define SN_id_cmc_lraPOPWitness         "id-cmc-lraPOPWitness"
+#define NID_id_cmc_lraPOPWitness                337
+#define OBJ_id_cmc_lraPOPWitness                OBJ_id_cmc,11L
+
+#define SN_id_cmc_getCert               "id-cmc-getCert"
+#define NID_id_cmc_getCert              338
+#define OBJ_id_cmc_getCert              OBJ_id_cmc,15L
+
+#define SN_id_cmc_getCRL                "id-cmc-getCRL"
+#define NID_id_cmc_getCRL               339
+#define OBJ_id_cmc_getCRL               OBJ_id_cmc,16L
+
+#define SN_id_cmc_revokeRequest         "id-cmc-revokeRequest"
+#define NID_id_cmc_revokeRequest                340
+#define OBJ_id_cmc_revokeRequest                OBJ_id_cmc,17L
+
+#define SN_id_cmc_regInfo               "id-cmc-regInfo"
+#define NID_id_cmc_regInfo              341
+#define OBJ_id_cmc_regInfo              OBJ_id_cmc,18L
+
+#define SN_id_cmc_responseInfo          "id-cmc-responseInfo"
+#define NID_id_cmc_responseInfo         342
+#define OBJ_id_cmc_responseInfo         OBJ_id_cmc,19L
+
+#define SN_id_cmc_queryPending          "id-cmc-queryPending"
+#define NID_id_cmc_queryPending         343
+#define OBJ_id_cmc_queryPending         OBJ_id_cmc,21L
+
+#define SN_id_cmc_popLinkRandom         "id-cmc-popLinkRandom"
+#define NID_id_cmc_popLinkRandom                344
+#define OBJ_id_cmc_popLinkRandom                OBJ_id_cmc,22L
+
+#define SN_id_cmc_popLinkWitness                "id-cmc-popLinkWitness"
+#define NID_id_cmc_popLinkWitness               345
+#define OBJ_id_cmc_popLinkWitness               OBJ_id_cmc,23L
+
+#define SN_id_cmc_confirmCertAcceptance         "id-cmc-confirmCertAcceptance"
+#define NID_id_cmc_confirmCertAcceptance                346
+#define OBJ_id_cmc_confirmCertAcceptance                OBJ_id_cmc,24L
+
+#define SN_id_on_personalData           "id-on-personalData"
+#define NID_id_on_personalData          347
+#define OBJ_id_on_personalData          OBJ_id_on,1L
+
+#define SN_id_on_permanentIdentifier            "id-on-permanentIdentifier"
+#define LN_id_on_permanentIdentifier            "Permanent Identifier"
+#define NID_id_on_permanentIdentifier           858
+#define OBJ_id_on_permanentIdentifier           OBJ_id_on,3L
+
+#define SN_id_pda_dateOfBirth           "id-pda-dateOfBirth"
+#define NID_id_pda_dateOfBirth          348
+#define OBJ_id_pda_dateOfBirth          OBJ_id_pda,1L
+
+#define SN_id_pda_placeOfBirth          "id-pda-placeOfBirth"
+#define NID_id_pda_placeOfBirth         349
+#define OBJ_id_pda_placeOfBirth         OBJ_id_pda,2L
+
+#define SN_id_pda_gender                "id-pda-gender"
+#define NID_id_pda_gender               351
+#define OBJ_id_pda_gender               OBJ_id_pda,3L
+
+#define SN_id_pda_countryOfCitizenship          "id-pda-countryOfCitizenship"
+#define NID_id_pda_countryOfCitizenship         352
+#define OBJ_id_pda_countryOfCitizenship         OBJ_id_pda,4L
+
+#define SN_id_pda_countryOfResidence            "id-pda-countryOfResidence"
+#define NID_id_pda_countryOfResidence           353
+#define OBJ_id_pda_countryOfResidence           OBJ_id_pda,5L
+
+#define SN_id_aca_authenticationInfo            "id-aca-authenticationInfo"
+#define NID_id_aca_authenticationInfo           354
+#define OBJ_id_aca_authenticationInfo           OBJ_id_aca,1L
+
+#define SN_id_aca_accessIdentity                "id-aca-accessIdentity"
+#define NID_id_aca_accessIdentity               355
+#define OBJ_id_aca_accessIdentity               OBJ_id_aca,2L
+
+#define SN_id_aca_chargingIdentity              "id-aca-chargingIdentity"
+#define NID_id_aca_chargingIdentity             356
+#define OBJ_id_aca_chargingIdentity             OBJ_id_aca,3L
+
+#define SN_id_aca_group         "id-aca-group"
+#define NID_id_aca_group                357
+#define OBJ_id_aca_group                OBJ_id_aca,4L
+
+#define SN_id_aca_role          "id-aca-role"
+#define NID_id_aca_role         358
+#define OBJ_id_aca_role         OBJ_id_aca,5L
+
+#define SN_id_aca_encAttrs              "id-aca-encAttrs"
+#define NID_id_aca_encAttrs             399
+#define OBJ_id_aca_encAttrs             OBJ_id_aca,6L
+
+#define SN_id_qcs_pkixQCSyntax_v1               "id-qcs-pkixQCSyntax-v1"
+#define NID_id_qcs_pkixQCSyntax_v1              359
+#define OBJ_id_qcs_pkixQCSyntax_v1              OBJ_id_qcs,1L
+
+#define SN_id_cct_crs           "id-cct-crs"
+#define NID_id_cct_crs          360
+#define OBJ_id_cct_crs          OBJ_id_cct,1L
+
+#define SN_id_cct_PKIData               "id-cct-PKIData"
+#define NID_id_cct_PKIData              361
+#define OBJ_id_cct_PKIData              OBJ_id_cct,2L
+
+#define SN_id_cct_PKIResponse           "id-cct-PKIResponse"
+#define NID_id_cct_PKIResponse          362
+#define OBJ_id_cct_PKIResponse          OBJ_id_cct,3L
+
+#define SN_id_ppl_anyLanguage           "id-ppl-anyLanguage"
+#define LN_id_ppl_anyLanguage           "Any language"
+#define NID_id_ppl_anyLanguage          664
+#define OBJ_id_ppl_anyLanguage          OBJ_id_ppl,0L
+
+#define SN_id_ppl_inheritAll            "id-ppl-inheritAll"
+#define LN_id_ppl_inheritAll            "Inherit all"
+#define NID_id_ppl_inheritAll           665
+#define OBJ_id_ppl_inheritAll           OBJ_id_ppl,1L
+
+#define SN_Independent          "id-ppl-independent"
+#define LN_Independent          "Independent"
+#define NID_Independent         667
+#define OBJ_Independent         OBJ_id_ppl,2L
+
+#define SN_ad_OCSP              "OCSP"
+#define LN_ad_OCSP              "OCSP"
+#define NID_ad_OCSP             178
+#define OBJ_ad_OCSP             OBJ_id_ad,1L
+
+#define SN_ad_ca_issuers                "caIssuers"
+#define LN_ad_ca_issuers                "CA Issuers"
+#define NID_ad_ca_issuers               179
+#define OBJ_ad_ca_issuers               OBJ_id_ad,2L
+
+#define SN_ad_timeStamping              "ad_timestamping"
+#define LN_ad_timeStamping              "AD Time Stamping"
+#define NID_ad_timeStamping             363
+#define OBJ_ad_timeStamping             OBJ_id_ad,3L
+
+#define SN_ad_dvcs              "AD_DVCS"
+#define LN_ad_dvcs              "ad dvcs"
+#define NID_ad_dvcs             364
+#define OBJ_ad_dvcs             OBJ_id_ad,4L
+
+#define SN_caRepository         "caRepository"
+#define LN_caRepository         "CA Repository"
+#define NID_caRepository                785
+#define OBJ_caRepository                OBJ_id_ad,5L
+
+#define OBJ_id_pkix_OCSP                OBJ_ad_OCSP
+
+#define SN_id_pkix_OCSP_basic           "basicOCSPResponse"
+#define LN_id_pkix_OCSP_basic           "Basic OCSP Response"
+#define NID_id_pkix_OCSP_basic          365
+#define OBJ_id_pkix_OCSP_basic          OBJ_id_pkix_OCSP,1L
+
+#define SN_id_pkix_OCSP_Nonce           "Nonce"
+#define LN_id_pkix_OCSP_Nonce           "OCSP Nonce"
+#define NID_id_pkix_OCSP_Nonce          366
+#define OBJ_id_pkix_OCSP_Nonce          OBJ_id_pkix_OCSP,2L
+
+#define SN_id_pkix_OCSP_CrlID           "CrlID"
+#define LN_id_pkix_OCSP_CrlID           "OCSP CRL ID"
+#define NID_id_pkix_OCSP_CrlID          367
+#define OBJ_id_pkix_OCSP_CrlID          OBJ_id_pkix_OCSP,3L
+
+#define SN_id_pkix_OCSP_acceptableResponses             "acceptableResponses"
+#define LN_id_pkix_OCSP_acceptableResponses             "Acceptable OCSP Responses"
+#define NID_id_pkix_OCSP_acceptableResponses            368
+#define OBJ_id_pkix_OCSP_acceptableResponses            OBJ_id_pkix_OCSP,4L
+
+#define SN_id_pkix_OCSP_noCheck         "noCheck"
+#define LN_id_pkix_OCSP_noCheck         "OCSP No Check"
+#define NID_id_pkix_OCSP_noCheck                369
+#define OBJ_id_pkix_OCSP_noCheck                OBJ_id_pkix_OCSP,5L
+
+#define SN_id_pkix_OCSP_archiveCutoff           "archiveCutoff"
+#define LN_id_pkix_OCSP_archiveCutoff           "OCSP Archive Cutoff"
+#define NID_id_pkix_OCSP_archiveCutoff          370
+#define OBJ_id_pkix_OCSP_archiveCutoff          OBJ_id_pkix_OCSP,6L
+
+#define SN_id_pkix_OCSP_serviceLocator          "serviceLocator"
+#define LN_id_pkix_OCSP_serviceLocator          "OCSP Service Locator"
+#define NID_id_pkix_OCSP_serviceLocator         371
+#define OBJ_id_pkix_OCSP_serviceLocator         OBJ_id_pkix_OCSP,7L
+
+#define SN_id_pkix_OCSP_extendedStatus          "extendedStatus"
+#define LN_id_pkix_OCSP_extendedStatus          "Extended OCSP Status"
+#define NID_id_pkix_OCSP_extendedStatus         372
+#define OBJ_id_pkix_OCSP_extendedStatus         OBJ_id_pkix_OCSP,8L
+
+#define SN_id_pkix_OCSP_valid           "valid"
+#define NID_id_pkix_OCSP_valid          373
+#define OBJ_id_pkix_OCSP_valid          OBJ_id_pkix_OCSP,9L
+
+#define SN_id_pkix_OCSP_path            "path"
+#define NID_id_pkix_OCSP_path           374
+#define OBJ_id_pkix_OCSP_path           OBJ_id_pkix_OCSP,10L
+
+#define SN_id_pkix_OCSP_trustRoot               "trustRoot"
+#define LN_id_pkix_OCSP_trustRoot               "Trust Root"
+#define NID_id_pkix_OCSP_trustRoot              375
+#define OBJ_id_pkix_OCSP_trustRoot              OBJ_id_pkix_OCSP,11L
+
+#define SN_algorithm            "algorithm"
+#define LN_algorithm            "algorithm"
+#define NID_algorithm           376
+#define OBJ_algorithm           1L,3L,14L,3L,2L
+
+#define SN_md5WithRSA           "RSA-NP-MD5"
+#define LN_md5WithRSA           "md5WithRSA"
+#define NID_md5WithRSA          104
+#define OBJ_md5WithRSA          OBJ_algorithm,3L
+
+#define SN_des_ecb              "DES-ECB"
+#define LN_des_ecb              "des-ecb"
+#define NID_des_ecb             29
+#define OBJ_des_ecb             OBJ_algorithm,6L
+
+#define SN_des_cbc              "DES-CBC"
+#define LN_des_cbc              "des-cbc"
+#define NID_des_cbc             31
+#define OBJ_des_cbc             OBJ_algorithm,7L
+
+#define SN_des_ofb64            "DES-OFB"
+#define LN_des_ofb64            "des-ofb"
+#define NID_des_ofb64           45
+#define OBJ_des_ofb64           OBJ_algorithm,8L
+
+#define SN_des_cfb64            "DES-CFB"
+#define LN_des_cfb64            "des-cfb"
+#define NID_des_cfb64           30
+#define OBJ_des_cfb64           OBJ_algorithm,9L
+
+#define SN_rsaSignature         "rsaSignature"
+#define NID_rsaSignature                377
+#define OBJ_rsaSignature                OBJ_algorithm,11L
+
+#define SN_dsa_2                "DSA-old"
+#define LN_dsa_2                "dsaEncryption-old"
+#define NID_dsa_2               67
+#define OBJ_dsa_2               OBJ_algorithm,12L
+
+#define SN_dsaWithSHA           "DSA-SHA"
+#define LN_dsaWithSHA           "dsaWithSHA"
+#define NID_dsaWithSHA          66
+#define OBJ_dsaWithSHA          OBJ_algorithm,13L
+
+#define SN_shaWithRSAEncryption         "RSA-SHA"
+#define LN_shaWithRSAEncryption         "shaWithRSAEncryption"
+#define NID_shaWithRSAEncryption                42
+#define OBJ_shaWithRSAEncryption                OBJ_algorithm,15L
+
+#define SN_des_ede_ecb          "DES-EDE"
+#define LN_des_ede_ecb          "des-ede"
+#define NID_des_ede_ecb         32
+#define OBJ_des_ede_ecb         OBJ_algorithm,17L
+
+#define SN_des_ede3_ecb         "DES-EDE3"
+#define LN_des_ede3_ecb         "des-ede3"
+#define NID_des_ede3_ecb                33
+
+#define SN_des_ede_cbc          "DES-EDE-CBC"
+#define LN_des_ede_cbc          "des-ede-cbc"
+#define NID_des_ede_cbc         43
+
+#define SN_des_ede_cfb64                "DES-EDE-CFB"
+#define LN_des_ede_cfb64                "des-ede-cfb"
+#define NID_des_ede_cfb64               60
+
+#define SN_des_ede3_cfb64               "DES-EDE3-CFB"
+#define LN_des_ede3_cfb64               "des-ede3-cfb"
+#define NID_des_ede3_cfb64              61
+
+#define SN_des_ede_ofb64                "DES-EDE-OFB"
+#define LN_des_ede_ofb64                "des-ede-ofb"
+#define NID_des_ede_ofb64               62
+
+#define SN_des_ede3_ofb64               "DES-EDE3-OFB"
+#define LN_des_ede3_ofb64               "des-ede3-ofb"
+#define NID_des_ede3_ofb64              63
+
+#define SN_desx_cbc             "DESX-CBC"
+#define LN_desx_cbc             "desx-cbc"
+#define NID_desx_cbc            80
+
+#define SN_sha          "SHA"
+#define LN_sha          "sha"
+#define NID_sha         41
+#define OBJ_sha         OBJ_algorithm,18L
+
+#define SN_sha1         "SHA1"
+#define LN_sha1         "sha1"
+#define NID_sha1                64
+#define OBJ_sha1                OBJ_algorithm,26L
+
+#define SN_dsaWithSHA1_2                "DSA-SHA1-old"
+#define LN_dsaWithSHA1_2                "dsaWithSHA1-old"
+#define NID_dsaWithSHA1_2               70
+#define OBJ_dsaWithSHA1_2               OBJ_algorithm,27L
+
+#define SN_sha1WithRSA          "RSA-SHA1-2"
+#define LN_sha1WithRSA          "sha1WithRSA"
+#define NID_sha1WithRSA         115
+#define OBJ_sha1WithRSA         OBJ_algorithm,29L
+
+#define SN_ripemd160            "RIPEMD160"
+#define LN_ripemd160            "ripemd160"
+#define NID_ripemd160           117
+#define OBJ_ripemd160           1L,3L,36L,3L,2L,1L
+
+#define SN_ripemd160WithRSA             "RSA-RIPEMD160"
+#define LN_ripemd160WithRSA             "ripemd160WithRSA"
+#define NID_ripemd160WithRSA            119
+#define OBJ_ripemd160WithRSA            1L,3L,36L,3L,3L,1L,2L
+
+#define SN_blake2b512           "BLAKE2b512"
+#define LN_blake2b512           "blake2b512"
+#define NID_blake2b512          1056
+#define OBJ_blake2b512          1L,3L,6L,1L,4L,1L,1722L,12L,2L,1L,16L
+
+#define SN_blake2s256           "BLAKE2s256"
+#define LN_blake2s256           "blake2s256"
+#define NID_blake2s256          1057
+#define OBJ_blake2s256          1L,3L,6L,1L,4L,1L,1722L,12L,2L,2L,8L
+
+#define SN_sxnet                "SXNetID"
+#define LN_sxnet                "Strong Extranet ID"
+#define NID_sxnet               143
+#define OBJ_sxnet               1L,3L,101L,1L,4L,1L
+
+#define SN_X500         "X500"
+#define LN_X500         "directory services (X.500)"
+#define NID_X500                11
+#define OBJ_X500                2L,5L
+
+#define SN_X509         "X509"
+#define NID_X509                12
+#define OBJ_X509                OBJ_X500,4L
+
+#define SN_commonName           "CN"
+#define LN_commonName           "commonName"
+#define NID_commonName          13
+#define OBJ_commonName          OBJ_X509,3L
+
+#define SN_surname              "SN"
+#define LN_surname              "surname"
+#define NID_surname             100
+#define OBJ_surname             OBJ_X509,4L
+
+#define LN_serialNumber         "serialNumber"
+#define NID_serialNumber                105
+#define OBJ_serialNumber                OBJ_X509,5L
+
+#define SN_countryName          "C"
+#define LN_countryName          "countryName"
+#define NID_countryName         14
+#define OBJ_countryName         OBJ_X509,6L
+
+#define SN_localityName         "L"
+#define LN_localityName         "localityName"
+#define NID_localityName                15
+#define OBJ_localityName                OBJ_X509,7L
+
+#define SN_stateOrProvinceName          "ST"
+#define LN_stateOrProvinceName          "stateOrProvinceName"
+#define NID_stateOrProvinceName         16
+#define OBJ_stateOrProvinceName         OBJ_X509,8L
+
+#define SN_streetAddress                "street"
+#define LN_streetAddress                "streetAddress"
+#define NID_streetAddress               660
+#define OBJ_streetAddress               OBJ_X509,9L
+
+#define SN_organizationName             "O"
+#define LN_organizationName             "organizationName"
+#define NID_organizationName            17
+#define OBJ_organizationName            OBJ_X509,10L
+
+#define SN_organizationalUnitName               "OU"
+#define LN_organizationalUnitName               "organizationalUnitName"
+#define NID_organizationalUnitName              18
+#define OBJ_organizationalUnitName              OBJ_X509,11L
+
+#define SN_title                "title"
+#define LN_title                "title"
+#define NID_title               106
+#define OBJ_title               OBJ_X509,12L
+
+#define LN_description          "description"
+#define NID_description         107
+#define OBJ_description         OBJ_X509,13L
+
+#define LN_searchGuide          "searchGuide"
+#define NID_searchGuide         859
+#define OBJ_searchGuide         OBJ_X509,14L
+
+#define LN_businessCategory             "businessCategory"
+#define NID_businessCategory            860
+#define OBJ_businessCategory            OBJ_X509,15L
+
+#define LN_postalAddress                "postalAddress"
+#define NID_postalAddress               861
+#define OBJ_postalAddress               OBJ_X509,16L
+
+#define LN_postalCode           "postalCode"
+#define NID_postalCode          661
+#define OBJ_postalCode          OBJ_X509,17L
+
+#define LN_postOfficeBox                "postOfficeBox"
+#define NID_postOfficeBox               862
+#define OBJ_postOfficeBox               OBJ_X509,18L
+
+#define LN_physicalDeliveryOfficeName           "physicalDeliveryOfficeName"
+#define NID_physicalDeliveryOfficeName          863
+#define OBJ_physicalDeliveryOfficeName          OBJ_X509,19L
+
+#define LN_telephoneNumber              "telephoneNumber"
+#define NID_telephoneNumber             864
+#define OBJ_telephoneNumber             OBJ_X509,20L
+
+#define LN_telexNumber          "telexNumber"
+#define NID_telexNumber         865
+#define OBJ_telexNumber         OBJ_X509,21L
+
+#define LN_teletexTerminalIdentifier            "teletexTerminalIdentifier"
+#define NID_teletexTerminalIdentifier           866
+#define OBJ_teletexTerminalIdentifier           OBJ_X509,22L
+
+#define LN_facsimileTelephoneNumber             "facsimileTelephoneNumber"
+#define NID_facsimileTelephoneNumber            867
+#define OBJ_facsimileTelephoneNumber            OBJ_X509,23L
+
+#define LN_x121Address          "x121Address"
+#define NID_x121Address         868
+#define OBJ_x121Address         OBJ_X509,24L
+
+#define LN_internationaliSDNNumber              "internationaliSDNNumber"
+#define NID_internationaliSDNNumber             869
+#define OBJ_internationaliSDNNumber             OBJ_X509,25L
+
+#define LN_registeredAddress            "registeredAddress"
+#define NID_registeredAddress           870
+#define OBJ_registeredAddress           OBJ_X509,26L
+
+#define LN_destinationIndicator         "destinationIndicator"
+#define NID_destinationIndicator                871
+#define OBJ_destinationIndicator                OBJ_X509,27L
+
+#define LN_preferredDeliveryMethod              "preferredDeliveryMethod"
+#define NID_preferredDeliveryMethod             872
+#define OBJ_preferredDeliveryMethod             OBJ_X509,28L
+
+#define LN_presentationAddress          "presentationAddress"
+#define NID_presentationAddress         873
+#define OBJ_presentationAddress         OBJ_X509,29L
+
+#define LN_supportedApplicationContext          "supportedApplicationContext"
+#define NID_supportedApplicationContext         874
+#define OBJ_supportedApplicationContext         OBJ_X509,30L
+
+#define SN_member               "member"
+#define NID_member              875
+#define OBJ_member              OBJ_X509,31L
+
+#define SN_owner                "owner"
+#define NID_owner               876
+#define OBJ_owner               OBJ_X509,32L
+
+#define LN_roleOccupant         "roleOccupant"
+#define NID_roleOccupant                877
+#define OBJ_roleOccupant                OBJ_X509,33L
+
+#define SN_seeAlso              "seeAlso"
+#define NID_seeAlso             878
+#define OBJ_seeAlso             OBJ_X509,34L
+
+#define LN_userPassword         "userPassword"
+#define NID_userPassword                879
+#define OBJ_userPassword                OBJ_X509,35L
+
+#define LN_userCertificate              "userCertificate"
+#define NID_userCertificate             880
+#define OBJ_userCertificate             OBJ_X509,36L
+
+#define LN_cACertificate                "cACertificate"
+#define NID_cACertificate               881
+#define OBJ_cACertificate               OBJ_X509,37L
+
+#define LN_authorityRevocationList              "authorityRevocationList"
+#define NID_authorityRevocationList             882
+#define OBJ_authorityRevocationList             OBJ_X509,38L
+
+#define LN_certificateRevocationList            "certificateRevocationList"
+#define NID_certificateRevocationList           883
+#define OBJ_certificateRevocationList           OBJ_X509,39L
+
+#define LN_crossCertificatePair         "crossCertificatePair"
+#define NID_crossCertificatePair                884
+#define OBJ_crossCertificatePair                OBJ_X509,40L
+
+#define SN_name         "name"
+#define LN_name         "name"
+#define NID_name                173
+#define OBJ_name                OBJ_X509,41L
+
+#define SN_givenName            "GN"
+#define LN_givenName            "givenName"
+#define NID_givenName           99
+#define OBJ_givenName           OBJ_X509,42L
+
+#define SN_initials             "initials"
+#define LN_initials             "initials"
+#define NID_initials            101
+#define OBJ_initials            OBJ_X509,43L
+
+#define LN_generationQualifier          "generationQualifier"
+#define NID_generationQualifier         509
+#define OBJ_generationQualifier         OBJ_X509,44L
+
+#define LN_x500UniqueIdentifier         "x500UniqueIdentifier"
+#define NID_x500UniqueIdentifier                503
+#define OBJ_x500UniqueIdentifier                OBJ_X509,45L
+
+#define SN_dnQualifier          "dnQualifier"
+#define LN_dnQualifier          "dnQualifier"
+#define NID_dnQualifier         174
+#define OBJ_dnQualifier         OBJ_X509,46L
+
+#define LN_enhancedSearchGuide          "enhancedSearchGuide"
+#define NID_enhancedSearchGuide         885
+#define OBJ_enhancedSearchGuide         OBJ_X509,47L
+
+#define LN_protocolInformation          "protocolInformation"
+#define NID_protocolInformation         886
+#define OBJ_protocolInformation         OBJ_X509,48L
+
+#define LN_distinguishedName            "distinguishedName"
+#define NID_distinguishedName           887
+#define OBJ_distinguishedName           OBJ_X509,49L
+
+#define LN_uniqueMember         "uniqueMember"
+#define NID_uniqueMember                888
+#define OBJ_uniqueMember                OBJ_X509,50L
+
+#define LN_houseIdentifier              "houseIdentifier"
+#define NID_houseIdentifier             889
+#define OBJ_houseIdentifier             OBJ_X509,51L
+
+#define LN_supportedAlgorithms          "supportedAlgorithms"
+#define NID_supportedAlgorithms         890
+#define OBJ_supportedAlgorithms         OBJ_X509,52L
+
+#define LN_deltaRevocationList          "deltaRevocationList"
+#define NID_deltaRevocationList         891
+#define OBJ_deltaRevocationList         OBJ_X509,53L
+
+#define SN_dmdName              "dmdName"
+#define NID_dmdName             892
+#define OBJ_dmdName             OBJ_X509,54L
+
+#define LN_pseudonym            "pseudonym"
+#define NID_pseudonym           510
+#define OBJ_pseudonym           OBJ_X509,65L
+
+#define SN_role         "role"
+#define LN_role         "role"
+#define NID_role                400
+#define OBJ_role                OBJ_X509,72L
+
+#define SN_X500algorithms               "X500algorithms"
+#define LN_X500algorithms               "directory services - algorithms"
+#define NID_X500algorithms              378
+#define OBJ_X500algorithms              OBJ_X500,8L
+
+#define SN_rsa          "RSA"
+#define LN_rsa          "rsa"
+#define NID_rsa         19
+#define OBJ_rsa         OBJ_X500algorithms,1L,1L
+
+#define SN_mdc2WithRSA          "RSA-MDC2"
+#define LN_mdc2WithRSA          "mdc2WithRSA"
+#define NID_mdc2WithRSA         96
+#define OBJ_mdc2WithRSA         OBJ_X500algorithms,3L,100L
+
+#define SN_mdc2         "MDC2"
+#define LN_mdc2         "mdc2"
+#define NID_mdc2                95
+#define OBJ_mdc2                OBJ_X500algorithms,3L,101L
+
+#define SN_id_ce                "id-ce"
+#define NID_id_ce               81
+#define OBJ_id_ce               OBJ_X500,29L
+
+#define SN_subject_directory_attributes         "subjectDirectoryAttributes"
+#define LN_subject_directory_attributes         "X509v3 Subject Directory Attributes"
+#define NID_subject_directory_attributes                769
+#define OBJ_subject_directory_attributes                OBJ_id_ce,9L
+
+#define SN_subject_key_identifier               "subjectKeyIdentifier"
+#define LN_subject_key_identifier               "X509v3 Subject Key Identifier"
+#define NID_subject_key_identifier              82
+#define OBJ_subject_key_identifier              OBJ_id_ce,14L
+
+#define SN_key_usage            "keyUsage"
+#define LN_key_usage            "X509v3 Key Usage"
+#define NID_key_usage           83
+#define OBJ_key_usage           OBJ_id_ce,15L
+
+#define SN_private_key_usage_period             "privateKeyUsagePeriod"
+#define LN_private_key_usage_period             "X509v3 Private Key Usage Period"
+#define NID_private_key_usage_period            84
+#define OBJ_private_key_usage_period            OBJ_id_ce,16L
+
+#define SN_subject_alt_name             "subjectAltName"
+#define LN_subject_alt_name             "X509v3 Subject Alternative Name"
+#define NID_subject_alt_name            85
+#define OBJ_subject_alt_name            OBJ_id_ce,17L
+
+#define SN_issuer_alt_name              "issuerAltName"
+#define LN_issuer_alt_name              "X509v3 Issuer Alternative Name"
+#define NID_issuer_alt_name             86
+#define OBJ_issuer_alt_name             OBJ_id_ce,18L
+
+#define SN_basic_constraints            "basicConstraints"
+#define LN_basic_constraints            "X509v3 Basic Constraints"
+#define NID_basic_constraints           87
+#define OBJ_basic_constraints           OBJ_id_ce,19L
+
+#define SN_crl_number           "crlNumber"
+#define LN_crl_number           "X509v3 CRL Number"
+#define NID_crl_number          88
+#define OBJ_crl_number          OBJ_id_ce,20L
+
+#define SN_crl_reason           "CRLReason"
+#define LN_crl_reason           "X509v3 CRL Reason Code"
+#define NID_crl_reason          141
+#define OBJ_crl_reason          OBJ_id_ce,21L
+
+#define SN_invalidity_date              "invalidityDate"
+#define LN_invalidity_date              "Invalidity Date"
+#define NID_invalidity_date             142
+#define OBJ_invalidity_date             OBJ_id_ce,24L
+
+#define SN_delta_crl            "deltaCRL"
+#define LN_delta_crl            "X509v3 Delta CRL Indicator"
+#define NID_delta_crl           140
+#define OBJ_delta_crl           OBJ_id_ce,27L
+
+#define SN_issuing_distribution_point           "issuingDistributionPoint"
+#define LN_issuing_distribution_point           "X509v3 Issuing Distribution Point"
+#define NID_issuing_distribution_point          770
+#define OBJ_issuing_distribution_point          OBJ_id_ce,28L
+
+#define SN_certificate_issuer           "certificateIssuer"
+#define LN_certificate_issuer           "X509v3 Certificate Issuer"
+#define NID_certificate_issuer          771
+#define OBJ_certificate_issuer          OBJ_id_ce,29L
+
+#define SN_name_constraints             "nameConstraints"
+#define LN_name_constraints             "X509v3 Name Constraints"
+#define NID_name_constraints            666
+#define OBJ_name_constraints            OBJ_id_ce,30L
+
+#define SN_crl_distribution_points              "crlDistributionPoints"
+#define LN_crl_distribution_points              "X509v3 CRL Distribution Points"
+#define NID_crl_distribution_points             103
+#define OBJ_crl_distribution_points             OBJ_id_ce,31L
+
+#define SN_certificate_policies         "certificatePolicies"
+#define LN_certificate_policies         "X509v3 Certificate Policies"
+#define NID_certificate_policies                89
+#define OBJ_certificate_policies                OBJ_id_ce,32L
+
+#define SN_any_policy           "anyPolicy"
+#define LN_any_policy           "X509v3 Any Policy"
+#define NID_any_policy          746
+#define OBJ_any_policy          OBJ_certificate_policies,0L
+
+#define SN_policy_mappings              "policyMappings"
+#define LN_policy_mappings              "X509v3 Policy Mappings"
+#define NID_policy_mappings             747
+#define OBJ_policy_mappings             OBJ_id_ce,33L
+
+#define SN_authority_key_identifier             "authorityKeyIdentifier"
+#define LN_authority_key_identifier             "X509v3 Authority Key Identifier"
+#define NID_authority_key_identifier            90
+#define OBJ_authority_key_identifier            OBJ_id_ce,35L
+
+#define SN_policy_constraints           "policyConstraints"
+#define LN_policy_constraints           "X509v3 Policy Constraints"
+#define NID_policy_constraints          401
+#define OBJ_policy_constraints          OBJ_id_ce,36L
+
+#define SN_ext_key_usage                "extendedKeyUsage"
+#define LN_ext_key_usage                "X509v3 Extended Key Usage"
+#define NID_ext_key_usage               126
+#define OBJ_ext_key_usage               OBJ_id_ce,37L
+
+#define SN_freshest_crl         "freshestCRL"
+#define LN_freshest_crl         "X509v3 Freshest CRL"
+#define NID_freshest_crl                857
+#define OBJ_freshest_crl                OBJ_id_ce,46L
+
+#define SN_inhibit_any_policy           "inhibitAnyPolicy"
+#define LN_inhibit_any_policy           "X509v3 Inhibit Any Policy"
+#define NID_inhibit_any_policy          748
+#define OBJ_inhibit_any_policy          OBJ_id_ce,54L
+
+#define SN_target_information           "targetInformation"
+#define LN_target_information           "X509v3 AC Targeting"
+#define NID_target_information          402
+#define OBJ_target_information          OBJ_id_ce,55L
+
+#define SN_no_rev_avail         "noRevAvail"
+#define LN_no_rev_avail         "X509v3 No Revocation Available"
+#define NID_no_rev_avail                403
+#define OBJ_no_rev_avail                OBJ_id_ce,56L
+
+#define SN_anyExtendedKeyUsage          "anyExtendedKeyUsage"
+#define LN_anyExtendedKeyUsage          "Any Extended Key Usage"
+#define NID_anyExtendedKeyUsage         910
+#define OBJ_anyExtendedKeyUsage         OBJ_ext_key_usage,0L
+
+#define SN_netscape             "Netscape"
+#define LN_netscape             "Netscape Communications Corp."
+#define NID_netscape            57
+#define OBJ_netscape            2L,16L,840L,1L,113730L
+
+#define SN_netscape_cert_extension              "nsCertExt"
+#define LN_netscape_cert_extension              "Netscape Certificate Extension"
+#define NID_netscape_cert_extension             58
+#define OBJ_netscape_cert_extension             OBJ_netscape,1L
+
+#define SN_netscape_data_type           "nsDataType"
+#define LN_netscape_data_type           "Netscape Data Type"
+#define NID_netscape_data_type          59
+#define OBJ_netscape_data_type          OBJ_netscape,2L
+
+#define SN_netscape_cert_type           "nsCertType"
+#define LN_netscape_cert_type           "Netscape Cert Type"
+#define NID_netscape_cert_type          71
+#define OBJ_netscape_cert_type          OBJ_netscape_cert_extension,1L
+
+#define SN_netscape_base_url            "nsBaseUrl"
+#define LN_netscape_base_url            "Netscape Base Url"
+#define NID_netscape_base_url           72
+#define OBJ_netscape_base_url           OBJ_netscape_cert_extension,2L
+
+#define SN_netscape_revocation_url              "nsRevocationUrl"
+#define LN_netscape_revocation_url              "Netscape Revocation Url"
+#define NID_netscape_revocation_url             73
+#define OBJ_netscape_revocation_url             OBJ_netscape_cert_extension,3L
+
+#define SN_netscape_ca_revocation_url           "nsCaRevocationUrl"
+#define LN_netscape_ca_revocation_url           "Netscape CA Revocation Url"
+#define NID_netscape_ca_revocation_url          74
+#define OBJ_netscape_ca_revocation_url          OBJ_netscape_cert_extension,4L
+
+#define SN_netscape_renewal_url         "nsRenewalUrl"
+#define LN_netscape_renewal_url         "Netscape Renewal Url"
+#define NID_netscape_renewal_url                75
+#define OBJ_netscape_renewal_url                OBJ_netscape_cert_extension,7L
+
+#define SN_netscape_ca_policy_url               "nsCaPolicyUrl"
+#define LN_netscape_ca_policy_url               "Netscape CA Policy Url"
+#define NID_netscape_ca_policy_url              76
+#define OBJ_netscape_ca_policy_url              OBJ_netscape_cert_extension,8L
+
+#define SN_netscape_ssl_server_name             "nsSslServerName"
+#define LN_netscape_ssl_server_name             "Netscape SSL Server Name"
+#define NID_netscape_ssl_server_name            77
+#define OBJ_netscape_ssl_server_name            OBJ_netscape_cert_extension,12L
+
+#define SN_netscape_comment             "nsComment"
+#define LN_netscape_comment             "Netscape Comment"
+#define NID_netscape_comment            78
+#define OBJ_netscape_comment            OBJ_netscape_cert_extension,13L
+
+#define SN_netscape_cert_sequence               "nsCertSequence"
+#define LN_netscape_cert_sequence               "Netscape Certificate Sequence"
+#define NID_netscape_cert_sequence              79
+#define OBJ_netscape_cert_sequence              OBJ_netscape_data_type,5L
+
+#define SN_ns_sgc               "nsSGC"
+#define LN_ns_sgc               "Netscape Server Gated Crypto"
+#define NID_ns_sgc              139
+#define OBJ_ns_sgc              OBJ_netscape,4L,1L
+
+#define SN_org          "ORG"
+#define LN_org          "org"
+#define NID_org         379
+#define OBJ_org         OBJ_iso,3L
+
+#define SN_dod          "DOD"
+#define LN_dod          "dod"
+#define NID_dod         380
+#define OBJ_dod         OBJ_org,6L
+
+#define SN_iana         "IANA"
+#define LN_iana         "iana"
+#define NID_iana                381
+#define OBJ_iana                OBJ_dod,1L
+
+#define OBJ_internet            OBJ_iana
+
+#define SN_Directory            "directory"
+#define LN_Directory            "Directory"
+#define NID_Directory           382
+#define OBJ_Directory           OBJ_internet,1L
+
+#define SN_Management           "mgmt"
+#define LN_Management           "Management"
+#define NID_Management          383
+#define OBJ_Management          OBJ_internet,2L
+
+#define SN_Experimental         "experimental"
+#define LN_Experimental         "Experimental"
+#define NID_Experimental                384
+#define OBJ_Experimental                OBJ_internet,3L
+
+#define SN_Private              "private"
+#define LN_Private              "Private"
+#define NID_Private             385
+#define OBJ_Private             OBJ_internet,4L
+
+#define SN_Security             "security"
+#define LN_Security             "Security"
+#define NID_Security            386
+#define OBJ_Security            OBJ_internet,5L
+
+#define SN_SNMPv2               "snmpv2"
+#define LN_SNMPv2               "SNMPv2"
+#define NID_SNMPv2              387
+#define OBJ_SNMPv2              OBJ_internet,6L
+
+#define LN_Mail         "Mail"
+#define NID_Mail                388
+#define OBJ_Mail                OBJ_internet,7L
+
+#define SN_Enterprises          "enterprises"
+#define LN_Enterprises          "Enterprises"
+#define NID_Enterprises         389
+#define OBJ_Enterprises         OBJ_Private,1L
+
+#define SN_dcObject             "dcobject"
+#define LN_dcObject             "dcObject"
+#define NID_dcObject            390
+#define OBJ_dcObject            OBJ_Enterprises,1466L,344L
+
+#define SN_mime_mhs             "mime-mhs"
+#define LN_mime_mhs             "MIME MHS"
+#define NID_mime_mhs            504
+#define OBJ_mime_mhs            OBJ_Mail,1L
+
+#define SN_mime_mhs_headings            "mime-mhs-headings"
+#define LN_mime_mhs_headings            "mime-mhs-headings"
+#define NID_mime_mhs_headings           505
+#define OBJ_mime_mhs_headings           OBJ_mime_mhs,1L
+
+#define SN_mime_mhs_bodies              "mime-mhs-bodies"
+#define LN_mime_mhs_bodies              "mime-mhs-bodies"
+#define NID_mime_mhs_bodies             506
+#define OBJ_mime_mhs_bodies             OBJ_mime_mhs,2L
+
+#define SN_id_hex_partial_message               "id-hex-partial-message"
+#define LN_id_hex_partial_message               "id-hex-partial-message"
+#define NID_id_hex_partial_message              507
+#define OBJ_id_hex_partial_message              OBJ_mime_mhs_headings,1L
+
+#define SN_id_hex_multipart_message             "id-hex-multipart-message"
+#define LN_id_hex_multipart_message             "id-hex-multipart-message"
+#define NID_id_hex_multipart_message            508
+#define OBJ_id_hex_multipart_message            OBJ_mime_mhs_headings,2L
+
+#define SN_zlib_compression             "ZLIB"
+#define LN_zlib_compression             "zlib compression"
+#define NID_zlib_compression            125
+#define OBJ_zlib_compression            OBJ_id_smime_alg,8L
+
+#define OBJ_csor                2L,16L,840L,1L,101L,3L
+
+#define OBJ_nistAlgorithms              OBJ_csor,4L
+
+#define OBJ_aes         OBJ_nistAlgorithms,1L
+
+#define SN_aes_128_ecb          "AES-128-ECB"
+#define LN_aes_128_ecb          "aes-128-ecb"
+#define NID_aes_128_ecb         418
+#define OBJ_aes_128_ecb         OBJ_aes,1L
+
+#define SN_aes_128_cbc          "AES-128-CBC"
+#define LN_aes_128_cbc          "aes-128-cbc"
+#define NID_aes_128_cbc         419
+#define OBJ_aes_128_cbc         OBJ_aes,2L
+
+#define SN_aes_128_ofb128               "AES-128-OFB"
+#define LN_aes_128_ofb128               "aes-128-ofb"
+#define NID_aes_128_ofb128              420
+#define OBJ_aes_128_ofb128              OBJ_aes,3L
+
+#define SN_aes_128_cfb128               "AES-128-CFB"
+#define LN_aes_128_cfb128               "aes-128-cfb"
+#define NID_aes_128_cfb128              421
+#define OBJ_aes_128_cfb128              OBJ_aes,4L
+
+#define SN_id_aes128_wrap               "id-aes128-wrap"
+#define NID_id_aes128_wrap              788
+#define OBJ_id_aes128_wrap              OBJ_aes,5L
+
+#define SN_aes_128_gcm          "id-aes128-GCM"
+#define LN_aes_128_gcm          "aes-128-gcm"
+#define NID_aes_128_gcm         895
+#define OBJ_aes_128_gcm         OBJ_aes,6L
+
+#define SN_aes_128_ccm          "id-aes128-CCM"
+#define LN_aes_128_ccm          "aes-128-ccm"
+#define NID_aes_128_ccm         896
+#define OBJ_aes_128_ccm         OBJ_aes,7L
+
+#define SN_id_aes128_wrap_pad           "id-aes128-wrap-pad"
+#define NID_id_aes128_wrap_pad          897
+#define OBJ_id_aes128_wrap_pad          OBJ_aes,8L
+
+#define SN_aes_192_ecb          "AES-192-ECB"
+#define LN_aes_192_ecb          "aes-192-ecb"
+#define NID_aes_192_ecb         422
+#define OBJ_aes_192_ecb         OBJ_aes,21L
+
+#define SN_aes_192_cbc          "AES-192-CBC"
+#define LN_aes_192_cbc          "aes-192-cbc"
+#define NID_aes_192_cbc         423
+#define OBJ_aes_192_cbc         OBJ_aes,22L
+
+#define SN_aes_192_ofb128               "AES-192-OFB"
+#define LN_aes_192_ofb128               "aes-192-ofb"
+#define NID_aes_192_ofb128              424
+#define OBJ_aes_192_ofb128              OBJ_aes,23L
+
+#define SN_aes_192_cfb128               "AES-192-CFB"
+#define LN_aes_192_cfb128               "aes-192-cfb"
+#define NID_aes_192_cfb128              425
+#define OBJ_aes_192_cfb128              OBJ_aes,24L
+
+#define SN_id_aes192_wrap               "id-aes192-wrap"
+#define NID_id_aes192_wrap              789
+#define OBJ_id_aes192_wrap              OBJ_aes,25L
+
+#define SN_aes_192_gcm          "id-aes192-GCM"
+#define LN_aes_192_gcm          "aes-192-gcm"
+#define NID_aes_192_gcm         898
+#define OBJ_aes_192_gcm         OBJ_aes,26L
+
+#define SN_aes_192_ccm          "id-aes192-CCM"
+#define LN_aes_192_ccm          "aes-192-ccm"
+#define NID_aes_192_ccm         899
+#define OBJ_aes_192_ccm         OBJ_aes,27L
+
+#define SN_id_aes192_wrap_pad           "id-aes192-wrap-pad"
+#define NID_id_aes192_wrap_pad          900
+#define OBJ_id_aes192_wrap_pad          OBJ_aes,28L
+
+#define SN_aes_256_ecb          "AES-256-ECB"
+#define LN_aes_256_ecb          "aes-256-ecb"
+#define NID_aes_256_ecb         426
+#define OBJ_aes_256_ecb         OBJ_aes,41L
+
+#define SN_aes_256_cbc          "AES-256-CBC"
+#define LN_aes_256_cbc          "aes-256-cbc"
+#define NID_aes_256_cbc         427
+#define OBJ_aes_256_cbc         OBJ_aes,42L
+
+#define SN_aes_256_ofb128               "AES-256-OFB"
+#define LN_aes_256_ofb128               "aes-256-ofb"
+#define NID_aes_256_ofb128              428
+#define OBJ_aes_256_ofb128              OBJ_aes,43L
+
+#define SN_aes_256_cfb128               "AES-256-CFB"
+#define LN_aes_256_cfb128               "aes-256-cfb"
+#define NID_aes_256_cfb128              429
+#define OBJ_aes_256_cfb128              OBJ_aes,44L
+
+#define SN_id_aes256_wrap               "id-aes256-wrap"
+#define NID_id_aes256_wrap              790
+#define OBJ_id_aes256_wrap              OBJ_aes,45L
+
+#define SN_aes_256_gcm          "id-aes256-GCM"
+#define LN_aes_256_gcm          "aes-256-gcm"
+#define NID_aes_256_gcm         901
+#define OBJ_aes_256_gcm         OBJ_aes,46L
+
+#define SN_aes_256_ccm          "id-aes256-CCM"
+#define LN_aes_256_ccm          "aes-256-ccm"
+#define NID_aes_256_ccm         902
+#define OBJ_aes_256_ccm         OBJ_aes,47L
+
+#define SN_id_aes256_wrap_pad           "id-aes256-wrap-pad"
+#define NID_id_aes256_wrap_pad          903
+#define OBJ_id_aes256_wrap_pad          OBJ_aes,48L
+
+#define SN_aes_128_cfb1         "AES-128-CFB1"
+#define LN_aes_128_cfb1         "aes-128-cfb1"
+#define NID_aes_128_cfb1                650
+
+#define SN_aes_192_cfb1         "AES-192-CFB1"
+#define LN_aes_192_cfb1         "aes-192-cfb1"
+#define NID_aes_192_cfb1                651
+
+#define SN_aes_256_cfb1         "AES-256-CFB1"
+#define LN_aes_256_cfb1         "aes-256-cfb1"
+#define NID_aes_256_cfb1                652
+
+#define SN_aes_128_cfb8         "AES-128-CFB8"
+#define LN_aes_128_cfb8         "aes-128-cfb8"
+#define NID_aes_128_cfb8                653
+
+#define SN_aes_192_cfb8         "AES-192-CFB8"
+#define LN_aes_192_cfb8         "aes-192-cfb8"
+#define NID_aes_192_cfb8                654
+
+#define SN_aes_256_cfb8         "AES-256-CFB8"
+#define LN_aes_256_cfb8         "aes-256-cfb8"
+#define NID_aes_256_cfb8                655
+
+#define SN_aes_128_ctr          "AES-128-CTR"
+#define LN_aes_128_ctr          "aes-128-ctr"
+#define NID_aes_128_ctr         904
+
+#define SN_aes_192_ctr          "AES-192-CTR"
+#define LN_aes_192_ctr          "aes-192-ctr"
+#define NID_aes_192_ctr         905
+
+#define SN_aes_256_ctr          "AES-256-CTR"
+#define LN_aes_256_ctr          "aes-256-ctr"
+#define NID_aes_256_ctr         906
+
+#define SN_aes_128_ocb          "AES-128-OCB"
+#define LN_aes_128_ocb          "aes-128-ocb"
+#define NID_aes_128_ocb         958
+
+#define SN_aes_192_ocb          "AES-192-OCB"
+#define LN_aes_192_ocb          "aes-192-ocb"
+#define NID_aes_192_ocb         959
+
+#define SN_aes_256_ocb          "AES-256-OCB"
+#define LN_aes_256_ocb          "aes-256-ocb"
+#define NID_aes_256_ocb         960
+
+#define SN_aes_128_xts          "AES-128-XTS"
+#define LN_aes_128_xts          "aes-128-xts"
+#define NID_aes_128_xts         913
+
+#define SN_aes_256_xts          "AES-256-XTS"
+#define LN_aes_256_xts          "aes-256-xts"
+#define NID_aes_256_xts         914
+
+#define SN_des_cfb1             "DES-CFB1"
+#define LN_des_cfb1             "des-cfb1"
+#define NID_des_cfb1            656
+
+#define SN_des_cfb8             "DES-CFB8"
+#define LN_des_cfb8             "des-cfb8"
+#define NID_des_cfb8            657
+
+#define SN_des_ede3_cfb1                "DES-EDE3-CFB1"
+#define LN_des_ede3_cfb1                "des-ede3-cfb1"
+#define NID_des_ede3_cfb1               658
+
+#define SN_des_ede3_cfb8                "DES-EDE3-CFB8"
+#define LN_des_ede3_cfb8                "des-ede3-cfb8"
+#define NID_des_ede3_cfb8               659
+
+#define OBJ_nist_hashalgs               OBJ_nistAlgorithms,2L
+
+#define SN_sha256               "SHA256"
+#define LN_sha256               "sha256"
+#define NID_sha256              672
+#define OBJ_sha256              OBJ_nist_hashalgs,1L
+
+#define SN_sha384               "SHA384"
+#define LN_sha384               "sha384"
+#define NID_sha384              673
+#define OBJ_sha384              OBJ_nist_hashalgs,2L
+
+#define SN_sha512               "SHA512"
+#define LN_sha512               "sha512"
+#define NID_sha512              674
+#define OBJ_sha512              OBJ_nist_hashalgs,3L
+
+#define SN_sha224               "SHA224"
+#define LN_sha224               "sha224"
+#define NID_sha224              675
+#define OBJ_sha224              OBJ_nist_hashalgs,4L
+
+#define OBJ_dsa_with_sha2               OBJ_nistAlgorithms,3L
+
+#define SN_dsa_with_SHA224              "dsa_with_SHA224"
+#define NID_dsa_with_SHA224             802
+#define OBJ_dsa_with_SHA224             OBJ_dsa_with_sha2,1L
+
+#define SN_dsa_with_SHA256              "dsa_with_SHA256"
+#define NID_dsa_with_SHA256             803
+#define OBJ_dsa_with_SHA256             OBJ_dsa_with_sha2,2L
+
+#define SN_hold_instruction_code                "holdInstructionCode"
+#define LN_hold_instruction_code                "Hold Instruction Code"
+#define NID_hold_instruction_code               430
+#define OBJ_hold_instruction_code               OBJ_id_ce,23L
+
+#define OBJ_holdInstruction             OBJ_X9_57,2L
+
+#define SN_hold_instruction_none                "holdInstructionNone"
+#define LN_hold_instruction_none                "Hold Instruction None"
+#define NID_hold_instruction_none               431
+#define OBJ_hold_instruction_none               OBJ_holdInstruction,1L
+
+#define SN_hold_instruction_call_issuer         "holdInstructionCallIssuer"
+#define LN_hold_instruction_call_issuer         "Hold Instruction Call Issuer"
+#define NID_hold_instruction_call_issuer                432
+#define OBJ_hold_instruction_call_issuer                OBJ_holdInstruction,2L
+
+#define SN_hold_instruction_reject              "holdInstructionReject"
+#define LN_hold_instruction_reject              "Hold Instruction Reject"
+#define NID_hold_instruction_reject             433
+#define OBJ_hold_instruction_reject             OBJ_holdInstruction,3L
+
+#define SN_data         "data"
+#define NID_data                434
+#define OBJ_data                OBJ_itu_t,9L
+
+#define SN_pss          "pss"
+#define NID_pss         435
+#define OBJ_pss         OBJ_data,2342L
+
+#define SN_ucl          "ucl"
+#define NID_ucl         436
+#define OBJ_ucl         OBJ_pss,19200300L
+
+#define SN_pilot                "pilot"
+#define NID_pilot               437
+#define OBJ_pilot               OBJ_ucl,100L
+
+#define LN_pilotAttributeType           "pilotAttributeType"
+#define NID_pilotAttributeType          438
+#define OBJ_pilotAttributeType          OBJ_pilot,1L
+
+#define LN_pilotAttributeSyntax         "pilotAttributeSyntax"
+#define NID_pilotAttributeSyntax                439
+#define OBJ_pilotAttributeSyntax                OBJ_pilot,3L
+
+#define LN_pilotObjectClass             "pilotObjectClass"
+#define NID_pilotObjectClass            440
+#define OBJ_pilotObjectClass            OBJ_pilot,4L
+
+#define LN_pilotGroups          "pilotGroups"
+#define NID_pilotGroups         441
+#define OBJ_pilotGroups         OBJ_pilot,10L
+
+#define LN_iA5StringSyntax              "iA5StringSyntax"
+#define NID_iA5StringSyntax             442
+#define OBJ_iA5StringSyntax             OBJ_pilotAttributeSyntax,4L
+
+#define LN_caseIgnoreIA5StringSyntax            "caseIgnoreIA5StringSyntax"
+#define NID_caseIgnoreIA5StringSyntax           443
+#define OBJ_caseIgnoreIA5StringSyntax           OBJ_pilotAttributeSyntax,5L
+
+#define LN_pilotObject          "pilotObject"
+#define NID_pilotObject         444
+#define OBJ_pilotObject         OBJ_pilotObjectClass,3L
+
+#define LN_pilotPerson          "pilotPerson"
+#define NID_pilotPerson         445
+#define OBJ_pilotPerson         OBJ_pilotObjectClass,4L
+
+#define SN_account              "account"
+#define NID_account             446
+#define OBJ_account             OBJ_pilotObjectClass,5L
+
+#define SN_document             "document"
+#define NID_document            447
+#define OBJ_document            OBJ_pilotObjectClass,6L
+
+#define SN_room         "room"
+#define NID_room                448
+#define OBJ_room                OBJ_pilotObjectClass,7L
+
+#define LN_documentSeries               "documentSeries"
+#define NID_documentSeries              449
+#define OBJ_documentSeries              OBJ_pilotObjectClass,9L
+
+#define SN_Domain               "domain"
+#define LN_Domain               "Domain"
+#define NID_Domain              392
+#define OBJ_Domain              OBJ_pilotObjectClass,13L
+
+#define LN_rFC822localPart              "rFC822localPart"
+#define NID_rFC822localPart             450
+#define OBJ_rFC822localPart             OBJ_pilotObjectClass,14L
+
+#define LN_dNSDomain            "dNSDomain"
+#define NID_dNSDomain           451
+#define OBJ_dNSDomain           OBJ_pilotObjectClass,15L
+
+#define LN_domainRelatedObject          "domainRelatedObject"
+#define NID_domainRelatedObject         452
+#define OBJ_domainRelatedObject         OBJ_pilotObjectClass,17L
+
+#define LN_friendlyCountry              "friendlyCountry"
+#define NID_friendlyCountry             453
+#define OBJ_friendlyCountry             OBJ_pilotObjectClass,18L
+
+#define LN_simpleSecurityObject         "simpleSecurityObject"
+#define NID_simpleSecurityObject                454
+#define OBJ_simpleSecurityObject                OBJ_pilotObjectClass,19L
+
+#define LN_pilotOrganization            "pilotOrganization"
+#define NID_pilotOrganization           455
+#define OBJ_pilotOrganization           OBJ_pilotObjectClass,20L
+
+#define LN_pilotDSA             "pilotDSA"
+#define NID_pilotDSA            456
+#define OBJ_pilotDSA            OBJ_pilotObjectClass,21L
+
+#define LN_qualityLabelledData          "qualityLabelledData"
+#define NID_qualityLabelledData         457
+#define OBJ_qualityLabelledData         OBJ_pilotObjectClass,22L
+
+#define SN_userId               "UID"
+#define LN_userId               "userId"
+#define NID_userId              458
+#define OBJ_userId              OBJ_pilotAttributeType,1L
+
+#define LN_textEncodedORAddress         "textEncodedORAddress"
+#define NID_textEncodedORAddress                459
+#define OBJ_textEncodedORAddress                OBJ_pilotAttributeType,2L
+
+#define SN_rfc822Mailbox                "mail"
+#define LN_rfc822Mailbox                "rfc822Mailbox"
+#define NID_rfc822Mailbox               460
+#define OBJ_rfc822Mailbox               OBJ_pilotAttributeType,3L
+
+#define SN_info         "info"
+#define NID_info                461
+#define OBJ_info                OBJ_pilotAttributeType,4L
+
+#define LN_favouriteDrink               "favouriteDrink"
+#define NID_favouriteDrink              462
+#define OBJ_favouriteDrink              OBJ_pilotAttributeType,5L
+
+#define LN_roomNumber           "roomNumber"
+#define NID_roomNumber          463
+#define OBJ_roomNumber          OBJ_pilotAttributeType,6L
+
+#define SN_photo                "photo"
+#define NID_photo               464
+#define OBJ_photo               OBJ_pilotAttributeType,7L
+
+#define LN_userClass            "userClass"
+#define NID_userClass           465
+#define OBJ_userClass           OBJ_pilotAttributeType,8L
+
+#define SN_host         "host"
+#define NID_host                466
+#define OBJ_host                OBJ_pilotAttributeType,9L
+
+#define SN_manager              "manager"
+#define NID_manager             467
+#define OBJ_manager             OBJ_pilotAttributeType,10L
+
+#define LN_documentIdentifier           "documentIdentifier"
+#define NID_documentIdentifier          468
+#define OBJ_documentIdentifier          OBJ_pilotAttributeType,11L
+
+#define LN_documentTitle                "documentTitle"
+#define NID_documentTitle               469
+#define OBJ_documentTitle               OBJ_pilotAttributeType,12L
+
+#define LN_documentVersion              "documentVersion"
+#define NID_documentVersion             470
+#define OBJ_documentVersion             OBJ_pilotAttributeType,13L
+
+#define LN_documentAuthor               "documentAuthor"
+#define NID_documentAuthor              471
+#define OBJ_documentAuthor              OBJ_pilotAttributeType,14L
+
+#define LN_documentLocation             "documentLocation"
+#define NID_documentLocation            472
+#define OBJ_documentLocation            OBJ_pilotAttributeType,15L
+
+#define LN_homeTelephoneNumber          "homeTelephoneNumber"
+#define NID_homeTelephoneNumber         473
+#define OBJ_homeTelephoneNumber         OBJ_pilotAttributeType,20L
+
+#define SN_secretary            "secretary"
+#define NID_secretary           474
+#define OBJ_secretary           OBJ_pilotAttributeType,21L
+
+#define LN_otherMailbox         "otherMailbox"
+#define NID_otherMailbox                475
+#define OBJ_otherMailbox                OBJ_pilotAttributeType,22L
+
+#define LN_lastModifiedTime             "lastModifiedTime"
+#define NID_lastModifiedTime            476
+#define OBJ_lastModifiedTime            OBJ_pilotAttributeType,23L
+
+#define LN_lastModifiedBy               "lastModifiedBy"
+#define NID_lastModifiedBy              477
+#define OBJ_lastModifiedBy              OBJ_pilotAttributeType,24L
+
+#define SN_domainComponent              "DC"
+#define LN_domainComponent              "domainComponent"
+#define NID_domainComponent             391
+#define OBJ_domainComponent             OBJ_pilotAttributeType,25L
+
+#define LN_aRecord              "aRecord"
+#define NID_aRecord             478
+#define OBJ_aRecord             OBJ_pilotAttributeType,26L
+
+#define LN_pilotAttributeType27         "pilotAttributeType27"
+#define NID_pilotAttributeType27                479
+#define OBJ_pilotAttributeType27                OBJ_pilotAttributeType,27L
+
+#define LN_mXRecord             "mXRecord"
+#define NID_mXRecord            480
+#define OBJ_mXRecord            OBJ_pilotAttributeType,28L
+
+#define LN_nSRecord             "nSRecord"
+#define NID_nSRecord            481
+#define OBJ_nSRecord            OBJ_pilotAttributeType,29L
+
+#define LN_sOARecord            "sOARecord"
+#define NID_sOARecord           482
+#define OBJ_sOARecord           OBJ_pilotAttributeType,30L
+
+#define LN_cNAMERecord          "cNAMERecord"
+#define NID_cNAMERecord         483
+#define OBJ_cNAMERecord         OBJ_pilotAttributeType,31L
+
+#define LN_associatedDomain             "associatedDomain"
+#define NID_associatedDomain            484
+#define OBJ_associatedDomain            OBJ_pilotAttributeType,37L
+
+#define LN_associatedName               "associatedName"
+#define NID_associatedName              485
+#define OBJ_associatedName              OBJ_pilotAttributeType,38L
+
+#define LN_homePostalAddress            "homePostalAddress"
+#define NID_homePostalAddress           486
+#define OBJ_homePostalAddress           OBJ_pilotAttributeType,39L
+
+#define LN_personalTitle                "personalTitle"
+#define NID_personalTitle               487
+#define OBJ_personalTitle               OBJ_pilotAttributeType,40L
+
+#define LN_mobileTelephoneNumber                "mobileTelephoneNumber"
+#define NID_mobileTelephoneNumber               488
+#define OBJ_mobileTelephoneNumber               OBJ_pilotAttributeType,41L
+
+#define LN_pagerTelephoneNumber         "pagerTelephoneNumber"
+#define NID_pagerTelephoneNumber                489
+#define OBJ_pagerTelephoneNumber                OBJ_pilotAttributeType,42L
+
+#define LN_friendlyCountryName          "friendlyCountryName"
+#define NID_friendlyCountryName         490
+#define OBJ_friendlyCountryName         OBJ_pilotAttributeType,43L
+
+#define SN_uniqueIdentifier             "uid"
+#define LN_uniqueIdentifier             "uniqueIdentifier"
+#define NID_uniqueIdentifier            102
+#define OBJ_uniqueIdentifier            OBJ_pilotAttributeType,44L
+
+#define LN_organizationalStatus         "organizationalStatus"
+#define NID_organizationalStatus                491
+#define OBJ_organizationalStatus                OBJ_pilotAttributeType,45L
+
+#define LN_janetMailbox         "janetMailbox"
+#define NID_janetMailbox                492
+#define OBJ_janetMailbox                OBJ_pilotAttributeType,46L
+
+#define LN_mailPreferenceOption         "mailPreferenceOption"
+#define NID_mailPreferenceOption                493
+#define OBJ_mailPreferenceOption                OBJ_pilotAttributeType,47L
+
+#define LN_buildingName         "buildingName"
+#define NID_buildingName                494
+#define OBJ_buildingName                OBJ_pilotAttributeType,48L
+
+#define LN_dSAQuality           "dSAQuality"
+#define NID_dSAQuality          495
+#define OBJ_dSAQuality          OBJ_pilotAttributeType,49L
+
+#define LN_singleLevelQuality           "singleLevelQuality"
+#define NID_singleLevelQuality          496
+#define OBJ_singleLevelQuality          OBJ_pilotAttributeType,50L
+
+#define LN_subtreeMinimumQuality                "subtreeMinimumQuality"
+#define NID_subtreeMinimumQuality               497
+#define OBJ_subtreeMinimumQuality               OBJ_pilotAttributeType,51L
+
+#define LN_subtreeMaximumQuality                "subtreeMaximumQuality"
+#define NID_subtreeMaximumQuality               498
+#define OBJ_subtreeMaximumQuality               OBJ_pilotAttributeType,52L
+
+#define LN_personalSignature            "personalSignature"
+#define NID_personalSignature           499
+#define OBJ_personalSignature           OBJ_pilotAttributeType,53L
+
+#define LN_dITRedirect          "dITRedirect"
+#define NID_dITRedirect         500
+#define OBJ_dITRedirect         OBJ_pilotAttributeType,54L
+
+#define SN_audio                "audio"
+#define NID_audio               501
+#define OBJ_audio               OBJ_pilotAttributeType,55L
+
+#define LN_documentPublisher            "documentPublisher"
+#define NID_documentPublisher           502
+#define OBJ_documentPublisher           OBJ_pilotAttributeType,56L
+
+#define SN_id_set               "id-set"
+#define LN_id_set               "Secure Electronic Transactions"
+#define NID_id_set              512
+#define OBJ_id_set              OBJ_international_organizations,42L
+
+#define SN_set_ctype            "set-ctype"
+#define LN_set_ctype            "content types"
+#define NID_set_ctype           513
+#define OBJ_set_ctype           OBJ_id_set,0L
+
+#define SN_set_msgExt           "set-msgExt"
+#define LN_set_msgExt           "message extensions"
+#define NID_set_msgExt          514
+#define OBJ_set_msgExt          OBJ_id_set,1L
+
+#define SN_set_attr             "set-attr"
+#define NID_set_attr            515
+#define OBJ_set_attr            OBJ_id_set,3L
+
+#define SN_set_policy           "set-policy"
+#define NID_set_policy          516
+#define OBJ_set_policy          OBJ_id_set,5L
+
+#define SN_set_certExt          "set-certExt"
+#define LN_set_certExt          "certificate extensions"
+#define NID_set_certExt         517
+#define OBJ_set_certExt         OBJ_id_set,7L
+
+#define SN_set_brand            "set-brand"
+#define NID_set_brand           518
+#define OBJ_set_brand           OBJ_id_set,8L
+
+#define SN_setct_PANData                "setct-PANData"
+#define NID_setct_PANData               519
+#define OBJ_setct_PANData               OBJ_set_ctype,0L
+
+#define SN_setct_PANToken               "setct-PANToken"
+#define NID_setct_PANToken              520
+#define OBJ_setct_PANToken              OBJ_set_ctype,1L
+
+#define SN_setct_PANOnly                "setct-PANOnly"
+#define NID_setct_PANOnly               521
+#define OBJ_setct_PANOnly               OBJ_set_ctype,2L
+
+#define SN_setct_OIData         "setct-OIData"
+#define NID_setct_OIData                522
+#define OBJ_setct_OIData                OBJ_set_ctype,3L
+
+#define SN_setct_PI             "setct-PI"
+#define NID_setct_PI            523
+#define OBJ_setct_PI            OBJ_set_ctype,4L
+
+#define SN_setct_PIData         "setct-PIData"
+#define NID_setct_PIData                524
+#define OBJ_setct_PIData                OBJ_set_ctype,5L
+
+#define SN_setct_PIDataUnsigned         "setct-PIDataUnsigned"
+#define NID_setct_PIDataUnsigned                525
+#define OBJ_setct_PIDataUnsigned                OBJ_set_ctype,6L
+
+#define SN_setct_HODInput               "setct-HODInput"
+#define NID_setct_HODInput              526
+#define OBJ_setct_HODInput              OBJ_set_ctype,7L
+
+#define SN_setct_AuthResBaggage         "setct-AuthResBaggage"
+#define NID_setct_AuthResBaggage                527
+#define OBJ_setct_AuthResBaggage                OBJ_set_ctype,8L
+
+#define SN_setct_AuthRevReqBaggage              "setct-AuthRevReqBaggage"
+#define NID_setct_AuthRevReqBaggage             528
+#define OBJ_setct_AuthRevReqBaggage             OBJ_set_ctype,9L
+
+#define SN_setct_AuthRevResBaggage              "setct-AuthRevResBaggage"
+#define NID_setct_AuthRevResBaggage             529
+#define OBJ_setct_AuthRevResBaggage             OBJ_set_ctype,10L
+
+#define SN_setct_CapTokenSeq            "setct-CapTokenSeq"
+#define NID_setct_CapTokenSeq           530
+#define OBJ_setct_CapTokenSeq           OBJ_set_ctype,11L
+
+#define SN_setct_PInitResData           "setct-PInitResData"
+#define NID_setct_PInitResData          531
+#define OBJ_setct_PInitResData          OBJ_set_ctype,12L
+
+#define SN_setct_PI_TBS         "setct-PI-TBS"
+#define NID_setct_PI_TBS                532
+#define OBJ_setct_PI_TBS                OBJ_set_ctype,13L
+
+#define SN_setct_PResData               "setct-PResData"
+#define NID_setct_PResData              533
+#define OBJ_setct_PResData              OBJ_set_ctype,14L
+
+#define SN_setct_AuthReqTBS             "setct-AuthReqTBS"
+#define NID_setct_AuthReqTBS            534
+#define OBJ_setct_AuthReqTBS            OBJ_set_ctype,16L
+
+#define SN_setct_AuthResTBS             "setct-AuthResTBS"
+#define NID_setct_AuthResTBS            535
+#define OBJ_setct_AuthResTBS            OBJ_set_ctype,17L
+
+#define SN_setct_AuthResTBSX            "setct-AuthResTBSX"
+#define NID_setct_AuthResTBSX           536
+#define OBJ_setct_AuthResTBSX           OBJ_set_ctype,18L
+
+#define SN_setct_AuthTokenTBS           "setct-AuthTokenTBS"
+#define NID_setct_AuthTokenTBS          537
+#define OBJ_setct_AuthTokenTBS          OBJ_set_ctype,19L
+
+#define SN_setct_CapTokenData           "setct-CapTokenData"
+#define NID_setct_CapTokenData          538
+#define OBJ_setct_CapTokenData          OBJ_set_ctype,20L
+
+#define SN_setct_CapTokenTBS            "setct-CapTokenTBS"
+#define NID_setct_CapTokenTBS           539
+#define OBJ_setct_CapTokenTBS           OBJ_set_ctype,21L
+
+#define SN_setct_AcqCardCodeMsg         "setct-AcqCardCodeMsg"
+#define NID_setct_AcqCardCodeMsg                540
+#define OBJ_setct_AcqCardCodeMsg                OBJ_set_ctype,22L
+
+#define SN_setct_AuthRevReqTBS          "setct-AuthRevReqTBS"
+#define NID_setct_AuthRevReqTBS         541
+#define OBJ_setct_AuthRevReqTBS         OBJ_set_ctype,23L
+
+#define SN_setct_AuthRevResData         "setct-AuthRevResData"
+#define NID_setct_AuthRevResData                542
+#define OBJ_setct_AuthRevResData                OBJ_set_ctype,24L
+
+#define SN_setct_AuthRevResTBS          "setct-AuthRevResTBS"
+#define NID_setct_AuthRevResTBS         543
+#define OBJ_setct_AuthRevResTBS         OBJ_set_ctype,25L
+
+#define SN_setct_CapReqTBS              "setct-CapReqTBS"
+#define NID_setct_CapReqTBS             544
+#define OBJ_setct_CapReqTBS             OBJ_set_ctype,26L
+
+#define SN_setct_CapReqTBSX             "setct-CapReqTBSX"
+#define NID_setct_CapReqTBSX            545
+#define OBJ_setct_CapReqTBSX            OBJ_set_ctype,27L
+
+#define SN_setct_CapResData             "setct-CapResData"
+#define NID_setct_CapResData            546
+#define OBJ_setct_CapResData            OBJ_set_ctype,28L
+
+#define SN_setct_CapRevReqTBS           "setct-CapRevReqTBS"
+#define NID_setct_CapRevReqTBS          547
+#define OBJ_setct_CapRevReqTBS          OBJ_set_ctype,29L
+
+#define SN_setct_CapRevReqTBSX          "setct-CapRevReqTBSX"
+#define NID_setct_CapRevReqTBSX         548
+#define OBJ_setct_CapRevReqTBSX         OBJ_set_ctype,30L
+
+#define SN_setct_CapRevResData          "setct-CapRevResData"
+#define NID_setct_CapRevResData         549
+#define OBJ_setct_CapRevResData         OBJ_set_ctype,31L
+
+#define SN_setct_CredReqTBS             "setct-CredReqTBS"
+#define NID_setct_CredReqTBS            550
+#define OBJ_setct_CredReqTBS            OBJ_set_ctype,32L
+
+#define SN_setct_CredReqTBSX            "setct-CredReqTBSX"
+#define NID_setct_CredReqTBSX           551
+#define OBJ_setct_CredReqTBSX           OBJ_set_ctype,33L
+
+#define SN_setct_CredResData            "setct-CredResData"
+#define NID_setct_CredResData           552
+#define OBJ_setct_CredResData           OBJ_set_ctype,34L
+
+#define SN_setct_CredRevReqTBS          "setct-CredRevReqTBS"
+#define NID_setct_CredRevReqTBS         553
+#define OBJ_setct_CredRevReqTBS         OBJ_set_ctype,35L
+
+#define SN_setct_CredRevReqTBSX         "setct-CredRevReqTBSX"
+#define NID_setct_CredRevReqTBSX                554
+#define OBJ_setct_CredRevReqTBSX                OBJ_set_ctype,36L
+
+#define SN_setct_CredRevResData         "setct-CredRevResData"
+#define NID_setct_CredRevResData                555
+#define OBJ_setct_CredRevResData                OBJ_set_ctype,37L
+
+#define SN_setct_PCertReqData           "setct-PCertReqData"
+#define NID_setct_PCertReqData          556
+#define OBJ_setct_PCertReqData          OBJ_set_ctype,38L
+
+#define SN_setct_PCertResTBS            "setct-PCertResTBS"
+#define NID_setct_PCertResTBS           557
+#define OBJ_setct_PCertResTBS           OBJ_set_ctype,39L
+
+#define SN_setct_BatchAdminReqData              "setct-BatchAdminReqData"
+#define NID_setct_BatchAdminReqData             558
+#define OBJ_setct_BatchAdminReqData             OBJ_set_ctype,40L
+
+#define SN_setct_BatchAdminResData              "setct-BatchAdminResData"
+#define NID_setct_BatchAdminResData             559
+#define OBJ_setct_BatchAdminResData             OBJ_set_ctype,41L
+
+#define SN_setct_CardCInitResTBS                "setct-CardCInitResTBS"
+#define NID_setct_CardCInitResTBS               560
+#define OBJ_setct_CardCInitResTBS               OBJ_set_ctype,42L
+
+#define SN_setct_MeAqCInitResTBS                "setct-MeAqCInitResTBS"
+#define NID_setct_MeAqCInitResTBS               561
+#define OBJ_setct_MeAqCInitResTBS               OBJ_set_ctype,43L
+
+#define SN_setct_RegFormResTBS          "setct-RegFormResTBS"
+#define NID_setct_RegFormResTBS         562
+#define OBJ_setct_RegFormResTBS         OBJ_set_ctype,44L
+
+#define SN_setct_CertReqData            "setct-CertReqData"
+#define NID_setct_CertReqData           563
+#define OBJ_setct_CertReqData           OBJ_set_ctype,45L
+
+#define SN_setct_CertReqTBS             "setct-CertReqTBS"
+#define NID_setct_CertReqTBS            564
+#define OBJ_setct_CertReqTBS            OBJ_set_ctype,46L
+
+#define SN_setct_CertResData            "setct-CertResData"
+#define NID_setct_CertResData           565
+#define OBJ_setct_CertResData           OBJ_set_ctype,47L
+
+#define SN_setct_CertInqReqTBS          "setct-CertInqReqTBS"
+#define NID_setct_CertInqReqTBS         566
+#define OBJ_setct_CertInqReqTBS         OBJ_set_ctype,48L
+
+#define SN_setct_ErrorTBS               "setct-ErrorTBS"
+#define NID_setct_ErrorTBS              567
+#define OBJ_setct_ErrorTBS              OBJ_set_ctype,49L
+
+#define SN_setct_PIDualSignedTBE                "setct-PIDualSignedTBE"
+#define NID_setct_PIDualSignedTBE               568
+#define OBJ_setct_PIDualSignedTBE               OBJ_set_ctype,50L
+
+#define SN_setct_PIUnsignedTBE          "setct-PIUnsignedTBE"
+#define NID_setct_PIUnsignedTBE         569
+#define OBJ_setct_PIUnsignedTBE         OBJ_set_ctype,51L
+
+#define SN_setct_AuthReqTBE             "setct-AuthReqTBE"
+#define NID_setct_AuthReqTBE            570
+#define OBJ_setct_AuthReqTBE            OBJ_set_ctype,52L
+
+#define SN_setct_AuthResTBE             "setct-AuthResTBE"
+#define NID_setct_AuthResTBE            571
+#define OBJ_setct_AuthResTBE            OBJ_set_ctype,53L
+
+#define SN_setct_AuthResTBEX            "setct-AuthResTBEX"
+#define NID_setct_AuthResTBEX           572
+#define OBJ_setct_AuthResTBEX           OBJ_set_ctype,54L
+
+#define SN_setct_AuthTokenTBE           "setct-AuthTokenTBE"
+#define NID_setct_AuthTokenTBE          573
+#define OBJ_setct_AuthTokenTBE          OBJ_set_ctype,55L
+
+#define SN_setct_CapTokenTBE            "setct-CapTokenTBE"
+#define NID_setct_CapTokenTBE           574
+#define OBJ_setct_CapTokenTBE           OBJ_set_ctype,56L
+
+#define SN_setct_CapTokenTBEX           "setct-CapTokenTBEX"
+#define NID_setct_CapTokenTBEX          575
+#define OBJ_setct_CapTokenTBEX          OBJ_set_ctype,57L
+
+#define SN_setct_AcqCardCodeMsgTBE              "setct-AcqCardCodeMsgTBE"
+#define NID_setct_AcqCardCodeMsgTBE             576
+#define OBJ_setct_AcqCardCodeMsgTBE             OBJ_set_ctype,58L
+
+#define SN_setct_AuthRevReqTBE          "setct-AuthRevReqTBE"
+#define NID_setct_AuthRevReqTBE         577
+#define OBJ_setct_AuthRevReqTBE         OBJ_set_ctype,59L
+
+#define SN_setct_AuthRevResTBE          "setct-AuthRevResTBE"
+#define NID_setct_AuthRevResTBE         578
+#define OBJ_setct_AuthRevResTBE         OBJ_set_ctype,60L
+
+#define SN_setct_AuthRevResTBEB         "setct-AuthRevResTBEB"
+#define NID_setct_AuthRevResTBEB                579
+#define OBJ_setct_AuthRevResTBEB                OBJ_set_ctype,61L
+
+#define SN_setct_CapReqTBE              "setct-CapReqTBE"
+#define NID_setct_CapReqTBE             580
+#define OBJ_setct_CapReqTBE             OBJ_set_ctype,62L
+
+#define SN_setct_CapReqTBEX             "setct-CapReqTBEX"
+#define NID_setct_CapReqTBEX            581
+#define OBJ_setct_CapReqTBEX            OBJ_set_ctype,63L
+
+#define SN_setct_CapResTBE              "setct-CapResTBE"
+#define NID_setct_CapResTBE             582
+#define OBJ_setct_CapResTBE             OBJ_set_ctype,64L
+
+#define SN_setct_CapRevReqTBE           "setct-CapRevReqTBE"
+#define NID_setct_CapRevReqTBE          583
+#define OBJ_setct_CapRevReqTBE          OBJ_set_ctype,65L
+
+#define SN_setct_CapRevReqTBEX          "setct-CapRevReqTBEX"
+#define NID_setct_CapRevReqTBEX         584
+#define OBJ_setct_CapRevReqTBEX         OBJ_set_ctype,66L
+
+#define SN_setct_CapRevResTBE           "setct-CapRevResTBE"
+#define NID_setct_CapRevResTBE          585
+#define OBJ_setct_CapRevResTBE          OBJ_set_ctype,67L
+
+#define SN_setct_CredReqTBE             "setct-CredReqTBE"
+#define NID_setct_CredReqTBE            586
+#define OBJ_setct_CredReqTBE            OBJ_set_ctype,68L
+
+#define SN_setct_CredReqTBEX            "setct-CredReqTBEX"
+#define NID_setct_CredReqTBEX           587
+#define OBJ_setct_CredReqTBEX           OBJ_set_ctype,69L
+
+#define SN_setct_CredResTBE             "setct-CredResTBE"
+#define NID_setct_CredResTBE            588
+#define OBJ_setct_CredResTBE            OBJ_set_ctype,70L
+
+#define SN_setct_CredRevReqTBE          "setct-CredRevReqTBE"
+#define NID_setct_CredRevReqTBE         589
+#define OBJ_setct_CredRevReqTBE         OBJ_set_ctype,71L
+
+#define SN_setct_CredRevReqTBEX         "setct-CredRevReqTBEX"
+#define NID_setct_CredRevReqTBEX                590
+#define OBJ_setct_CredRevReqTBEX                OBJ_set_ctype,72L
+
+#define SN_setct_CredRevResTBE          "setct-CredRevResTBE"
+#define NID_setct_CredRevResTBE         591
+#define OBJ_setct_CredRevResTBE         OBJ_set_ctype,73L
+
+#define SN_setct_BatchAdminReqTBE               "setct-BatchAdminReqTBE"
+#define NID_setct_BatchAdminReqTBE              592
+#define OBJ_setct_BatchAdminReqTBE              OBJ_set_ctype,74L
+
+#define SN_setct_BatchAdminResTBE               "setct-BatchAdminResTBE"
+#define NID_setct_BatchAdminResTBE              593
+#define OBJ_setct_BatchAdminResTBE              OBJ_set_ctype,75L
+
+#define SN_setct_RegFormReqTBE          "setct-RegFormReqTBE"
+#define NID_setct_RegFormReqTBE         594
+#define OBJ_setct_RegFormReqTBE         OBJ_set_ctype,76L
+
+#define SN_setct_CertReqTBE             "setct-CertReqTBE"
+#define NID_setct_CertReqTBE            595
+#define OBJ_setct_CertReqTBE            OBJ_set_ctype,77L
+
+#define SN_setct_CertReqTBEX            "setct-CertReqTBEX"
+#define NID_setct_CertReqTBEX           596
+#define OBJ_setct_CertReqTBEX           OBJ_set_ctype,78L
+
+#define SN_setct_CertResTBE             "setct-CertResTBE"
+#define NID_setct_CertResTBE            597
+#define OBJ_setct_CertResTBE            OBJ_set_ctype,79L
+
+#define SN_setct_CRLNotificationTBS             "setct-CRLNotificationTBS"
+#define NID_setct_CRLNotificationTBS            598
+#define OBJ_setct_CRLNotificationTBS            OBJ_set_ctype,80L
+
+#define SN_setct_CRLNotificationResTBS          "setct-CRLNotificationResTBS"
+#define NID_setct_CRLNotificationResTBS         599
+#define OBJ_setct_CRLNotificationResTBS         OBJ_set_ctype,81L
+
+#define SN_setct_BCIDistributionTBS             "setct-BCIDistributionTBS"
+#define NID_setct_BCIDistributionTBS            600
+#define OBJ_setct_BCIDistributionTBS            OBJ_set_ctype,82L
+
+#define SN_setext_genCrypt              "setext-genCrypt"
+#define LN_setext_genCrypt              "generic cryptogram"
+#define NID_setext_genCrypt             601
+#define OBJ_setext_genCrypt             OBJ_set_msgExt,1L
+
+#define SN_setext_miAuth                "setext-miAuth"
+#define LN_setext_miAuth                "merchant initiated auth"
+#define NID_setext_miAuth               602
+#define OBJ_setext_miAuth               OBJ_set_msgExt,3L
+
+#define SN_setext_pinSecure             "setext-pinSecure"
+#define NID_setext_pinSecure            603
+#define OBJ_setext_pinSecure            OBJ_set_msgExt,4L
+
+#define SN_setext_pinAny                "setext-pinAny"
+#define NID_setext_pinAny               604
+#define OBJ_setext_pinAny               OBJ_set_msgExt,5L
+
+#define SN_setext_track2                "setext-track2"
+#define NID_setext_track2               605
+#define OBJ_setext_track2               OBJ_set_msgExt,7L
+
+#define SN_setext_cv            "setext-cv"
+#define LN_setext_cv            "additional verification"
+#define NID_setext_cv           606
+#define OBJ_setext_cv           OBJ_set_msgExt,8L
+
+#define SN_set_policy_root              "set-policy-root"
+#define NID_set_policy_root             607
+#define OBJ_set_policy_root             OBJ_set_policy,0L
+
+#define SN_setCext_hashedRoot           "setCext-hashedRoot"
+#define NID_setCext_hashedRoot          608
+#define OBJ_setCext_hashedRoot          OBJ_set_certExt,0L
+
+#define SN_setCext_certType             "setCext-certType"
+#define NID_setCext_certType            609
+#define OBJ_setCext_certType            OBJ_set_certExt,1L
+
+#define SN_setCext_merchData            "setCext-merchData"
+#define NID_setCext_merchData           610
+#define OBJ_setCext_merchData           OBJ_set_certExt,2L
+
+#define SN_setCext_cCertRequired                "setCext-cCertRequired"
+#define NID_setCext_cCertRequired               611
+#define OBJ_setCext_cCertRequired               OBJ_set_certExt,3L
+
+#define SN_setCext_tunneling            "setCext-tunneling"
+#define NID_setCext_tunneling           612
+#define OBJ_setCext_tunneling           OBJ_set_certExt,4L
+
+#define SN_setCext_setExt               "setCext-setExt"
+#define NID_setCext_setExt              613
+#define OBJ_setCext_setExt              OBJ_set_certExt,5L
+
+#define SN_setCext_setQualf             "setCext-setQualf"
+#define NID_setCext_setQualf            614
+#define OBJ_setCext_setQualf            OBJ_set_certExt,6L
+
+#define SN_setCext_PGWYcapabilities             "setCext-PGWYcapabilities"
+#define NID_setCext_PGWYcapabilities            615
+#define OBJ_setCext_PGWYcapabilities            OBJ_set_certExt,7L
+
+#define SN_setCext_TokenIdentifier              "setCext-TokenIdentifier"
+#define NID_setCext_TokenIdentifier             616
+#define OBJ_setCext_TokenIdentifier             OBJ_set_certExt,8L
+
+#define SN_setCext_Track2Data           "setCext-Track2Data"
+#define NID_setCext_Track2Data          617
+#define OBJ_setCext_Track2Data          OBJ_set_certExt,9L
+
+#define SN_setCext_TokenType            "setCext-TokenType"
+#define NID_setCext_TokenType           618
+#define OBJ_setCext_TokenType           OBJ_set_certExt,10L
+
+#define SN_setCext_IssuerCapabilities           "setCext-IssuerCapabilities"
+#define NID_setCext_IssuerCapabilities          619
+#define OBJ_setCext_IssuerCapabilities          OBJ_set_certExt,11L
+
+#define SN_setAttr_Cert         "setAttr-Cert"
+#define NID_setAttr_Cert                620
+#define OBJ_setAttr_Cert                OBJ_set_attr,0L
+
+#define SN_setAttr_PGWYcap              "setAttr-PGWYcap"
+#define LN_setAttr_PGWYcap              "payment gateway capabilities"
+#define NID_setAttr_PGWYcap             621
+#define OBJ_setAttr_PGWYcap             OBJ_set_attr,1L
+
+#define SN_setAttr_TokenType            "setAttr-TokenType"
+#define NID_setAttr_TokenType           622
+#define OBJ_setAttr_TokenType           OBJ_set_attr,2L
+
+#define SN_setAttr_IssCap               "setAttr-IssCap"
+#define LN_setAttr_IssCap               "issuer capabilities"
+#define NID_setAttr_IssCap              623
+#define OBJ_setAttr_IssCap              OBJ_set_attr,3L
+
+#define SN_set_rootKeyThumb             "set-rootKeyThumb"
+#define NID_set_rootKeyThumb            624
+#define OBJ_set_rootKeyThumb            OBJ_setAttr_Cert,0L
+
+#define SN_set_addPolicy                "set-addPolicy"
+#define NID_set_addPolicy               625
+#define OBJ_set_addPolicy               OBJ_setAttr_Cert,1L
+
+#define SN_setAttr_Token_EMV            "setAttr-Token-EMV"
+#define NID_setAttr_Token_EMV           626
+#define OBJ_setAttr_Token_EMV           OBJ_setAttr_TokenType,1L
+
+#define SN_setAttr_Token_B0Prime                "setAttr-Token-B0Prime"
+#define NID_setAttr_Token_B0Prime               627
+#define OBJ_setAttr_Token_B0Prime               OBJ_setAttr_TokenType,2L
+
+#define SN_setAttr_IssCap_CVM           "setAttr-IssCap-CVM"
+#define NID_setAttr_IssCap_CVM          628
+#define OBJ_setAttr_IssCap_CVM          OBJ_setAttr_IssCap,3L
+
+#define SN_setAttr_IssCap_T2            "setAttr-IssCap-T2"
+#define NID_setAttr_IssCap_T2           629
+#define OBJ_setAttr_IssCap_T2           OBJ_setAttr_IssCap,4L
+
+#define SN_setAttr_IssCap_Sig           "setAttr-IssCap-Sig"
+#define NID_setAttr_IssCap_Sig          630
+#define OBJ_setAttr_IssCap_Sig          OBJ_setAttr_IssCap,5L
+
+#define SN_setAttr_GenCryptgrm          "setAttr-GenCryptgrm"
+#define LN_setAttr_GenCryptgrm          "generate cryptogram"
+#define NID_setAttr_GenCryptgrm         631
+#define OBJ_setAttr_GenCryptgrm         OBJ_setAttr_IssCap_CVM,1L
+
+#define SN_setAttr_T2Enc                "setAttr-T2Enc"
+#define LN_setAttr_T2Enc                "encrypted track 2"
+#define NID_setAttr_T2Enc               632
+#define OBJ_setAttr_T2Enc               OBJ_setAttr_IssCap_T2,1L
+
+#define SN_setAttr_T2cleartxt           "setAttr-T2cleartxt"
+#define LN_setAttr_T2cleartxt           "cleartext track 2"
+#define NID_setAttr_T2cleartxt          633
+#define OBJ_setAttr_T2cleartxt          OBJ_setAttr_IssCap_T2,2L
+
+#define SN_setAttr_TokICCsig            "setAttr-TokICCsig"
+#define LN_setAttr_TokICCsig            "ICC or token signature"
+#define NID_setAttr_TokICCsig           634
+#define OBJ_setAttr_TokICCsig           OBJ_setAttr_IssCap_Sig,1L
+
+#define SN_setAttr_SecDevSig            "setAttr-SecDevSig"
+#define LN_setAttr_SecDevSig            "secure device signature"
+#define NID_setAttr_SecDevSig           635
+#define OBJ_setAttr_SecDevSig           OBJ_setAttr_IssCap_Sig,2L
+
+#define SN_set_brand_IATA_ATA           "set-brand-IATA-ATA"
+#define NID_set_brand_IATA_ATA          636
+#define OBJ_set_brand_IATA_ATA          OBJ_set_brand,1L
+
+#define SN_set_brand_Diners             "set-brand-Diners"
+#define NID_set_brand_Diners            637
+#define OBJ_set_brand_Diners            OBJ_set_brand,30L
+
+#define SN_set_brand_AmericanExpress            "set-brand-AmericanExpress"
+#define NID_set_brand_AmericanExpress           638
+#define OBJ_set_brand_AmericanExpress           OBJ_set_brand,34L
+
+#define SN_set_brand_JCB                "set-brand-JCB"
+#define NID_set_brand_JCB               639
+#define OBJ_set_brand_JCB               OBJ_set_brand,35L
+
+#define SN_set_brand_Visa               "set-brand-Visa"
+#define NID_set_brand_Visa              640
+#define OBJ_set_brand_Visa              OBJ_set_brand,4L
+
+#define SN_set_brand_MasterCard         "set-brand-MasterCard"
+#define NID_set_brand_MasterCard                641
+#define OBJ_set_brand_MasterCard                OBJ_set_brand,5L
+
+#define SN_set_brand_Novus              "set-brand-Novus"
+#define NID_set_brand_Novus             642
+#define OBJ_set_brand_Novus             OBJ_set_brand,6011L
+
+#define SN_des_cdmf             "DES-CDMF"
+#define LN_des_cdmf             "des-cdmf"
+#define NID_des_cdmf            643
+#define OBJ_des_cdmf            OBJ_rsadsi,3L,10L
+
+#define SN_rsaOAEPEncryptionSET         "rsaOAEPEncryptionSET"
+#define NID_rsaOAEPEncryptionSET                644
+#define OBJ_rsaOAEPEncryptionSET                OBJ_rsadsi,1L,1L,6L
+
+#define SN_ipsec3               "Oakley-EC2N-3"
+#define LN_ipsec3               "ipsec3"
+#define NID_ipsec3              749
+
+#define SN_ipsec4               "Oakley-EC2N-4"
+#define LN_ipsec4               "ipsec4"
+#define NID_ipsec4              750
+
+#define SN_whirlpool            "whirlpool"
+#define NID_whirlpool           804
+#define OBJ_whirlpool           OBJ_iso,0L,10118L,3L,0L,55L
+
+#define SN_cryptopro            "cryptopro"
+#define NID_cryptopro           805
+#define OBJ_cryptopro           OBJ_member_body,643L,2L,2L
+
+#define SN_cryptocom            "cryptocom"
+#define NID_cryptocom           806
+#define OBJ_cryptocom           OBJ_member_body,643L,2L,9L
+
+#define SN_id_tc26              "id-tc26"
+#define NID_id_tc26             974
+#define OBJ_id_tc26             OBJ_member_body,643L,7L,1L
+
+#define SN_id_GostR3411_94_with_GostR3410_2001          "id-GostR3411-94-with-GostR3410-2001"
+#define LN_id_GostR3411_94_with_GostR3410_2001          "GOST R 34.11-94 with GOST R 34.10-2001"
+#define NID_id_GostR3411_94_with_GostR3410_2001         807
+#define OBJ_id_GostR3411_94_with_GostR3410_2001         OBJ_cryptopro,3L
+
+#define SN_id_GostR3411_94_with_GostR3410_94            "id-GostR3411-94-with-GostR3410-94"
+#define LN_id_GostR3411_94_with_GostR3410_94            "GOST R 34.11-94 with GOST R 34.10-94"
+#define NID_id_GostR3411_94_with_GostR3410_94           808
+#define OBJ_id_GostR3411_94_with_GostR3410_94           OBJ_cryptopro,4L
+
+#define SN_id_GostR3411_94              "md_gost94"
+#define LN_id_GostR3411_94              "GOST R 34.11-94"
+#define NID_id_GostR3411_94             809
+#define OBJ_id_GostR3411_94             OBJ_cryptopro,9L
+
+#define SN_id_HMACGostR3411_94          "id-HMACGostR3411-94"
+#define LN_id_HMACGostR3411_94          "HMAC GOST 34.11-94"
+#define NID_id_HMACGostR3411_94         810
+#define OBJ_id_HMACGostR3411_94         OBJ_cryptopro,10L
+
+#define SN_id_GostR3410_2001            "gost2001"
+#define LN_id_GostR3410_2001            "GOST R 34.10-2001"
+#define NID_id_GostR3410_2001           811
+#define OBJ_id_GostR3410_2001           OBJ_cryptopro,19L
+
+#define SN_id_GostR3410_94              "gost94"
+#define LN_id_GostR3410_94              "GOST R 34.10-94"
+#define NID_id_GostR3410_94             812
+#define OBJ_id_GostR3410_94             OBJ_cryptopro,20L
+
+#define SN_id_Gost28147_89              "gost89"
+#define LN_id_Gost28147_89              "GOST 28147-89"
+#define NID_id_Gost28147_89             813
+#define OBJ_id_Gost28147_89             OBJ_cryptopro,21L
+
+#define SN_gost89_cnt           "gost89-cnt"
+#define NID_gost89_cnt          814
+
+#define SN_gost89_cnt_12                "gost89-cnt-12"
+#define NID_gost89_cnt_12               975
+
+#define SN_gost89_cbc           "gost89-cbc"
+#define NID_gost89_cbc          1009
+
+#define SN_gost89_ecb           "gost89-ecb"
+#define NID_gost89_ecb          1010
+
+#define SN_gost89_ctr           "gost89-ctr"
+#define NID_gost89_ctr          1011
+
+#define SN_id_Gost28147_89_MAC          "gost-mac"
+#define LN_id_Gost28147_89_MAC          "GOST 28147-89 MAC"
+#define NID_id_Gost28147_89_MAC         815
+#define OBJ_id_Gost28147_89_MAC         OBJ_cryptopro,22L
+
+#define SN_gost_mac_12          "gost-mac-12"
+#define NID_gost_mac_12         976
+
+#define SN_id_GostR3411_94_prf          "prf-gostr3411-94"
+#define LN_id_GostR3411_94_prf          "GOST R 34.11-94 PRF"
+#define NID_id_GostR3411_94_prf         816
+#define OBJ_id_GostR3411_94_prf         OBJ_cryptopro,23L
+
+#define SN_id_GostR3410_2001DH          "id-GostR3410-2001DH"
+#define LN_id_GostR3410_2001DH          "GOST R 34.10-2001 DH"
+#define NID_id_GostR3410_2001DH         817
+#define OBJ_id_GostR3410_2001DH         OBJ_cryptopro,98L
+
+#define SN_id_GostR3410_94DH            "id-GostR3410-94DH"
+#define LN_id_GostR3410_94DH            "GOST R 34.10-94 DH"
+#define NID_id_GostR3410_94DH           818
+#define OBJ_id_GostR3410_94DH           OBJ_cryptopro,99L
+
+#define SN_id_Gost28147_89_CryptoPro_KeyMeshing         "id-Gost28147-89-CryptoPro-KeyMeshing"
+#define NID_id_Gost28147_89_CryptoPro_KeyMeshing                819
+#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing                OBJ_cryptopro,14L,1L
+
+#define SN_id_Gost28147_89_None_KeyMeshing              "id-Gost28147-89-None-KeyMeshing"
+#define NID_id_Gost28147_89_None_KeyMeshing             820
+#define OBJ_id_Gost28147_89_None_KeyMeshing             OBJ_cryptopro,14L,0L
+
+#define SN_id_GostR3411_94_TestParamSet         "id-GostR3411-94-TestParamSet"
+#define NID_id_GostR3411_94_TestParamSet                821
+#define OBJ_id_GostR3411_94_TestParamSet                OBJ_cryptopro,30L,0L
+
+#define SN_id_GostR3411_94_CryptoProParamSet            "id-GostR3411-94-CryptoProParamSet"
+#define NID_id_GostR3411_94_CryptoProParamSet           822
+#define OBJ_id_GostR3411_94_CryptoProParamSet           OBJ_cryptopro,30L,1L
+
+#define SN_id_Gost28147_89_TestParamSet         "id-Gost28147-89-TestParamSet"
+#define NID_id_Gost28147_89_TestParamSet                823
+#define OBJ_id_Gost28147_89_TestParamSet                OBJ_cryptopro,31L,0L
+
+#define SN_id_Gost28147_89_CryptoPro_A_ParamSet         "id-Gost28147-89-CryptoPro-A-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_A_ParamSet                824
+#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet                OBJ_cryptopro,31L,1L
+
+#define SN_id_Gost28147_89_CryptoPro_B_ParamSet         "id-Gost28147-89-CryptoPro-B-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_B_ParamSet                825
+#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet                OBJ_cryptopro,31L,2L
+
+#define SN_id_Gost28147_89_CryptoPro_C_ParamSet         "id-Gost28147-89-CryptoPro-C-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_C_ParamSet                826
+#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet                OBJ_cryptopro,31L,3L
+
+#define SN_id_Gost28147_89_CryptoPro_D_ParamSet         "id-Gost28147-89-CryptoPro-D-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_D_ParamSet                827
+#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet                OBJ_cryptopro,31L,4L
+
+#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet         "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet                828
+#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet                OBJ_cryptopro,31L,5L
+
+#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet         "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet                829
+#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet                OBJ_cryptopro,31L,6L
+
+#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet             "id-Gost28147-89-CryptoPro-RIC-1-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet            830
+#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet            OBJ_cryptopro,31L,7L
+
+#define SN_id_GostR3410_94_TestParamSet         "id-GostR3410-94-TestParamSet"
+#define NID_id_GostR3410_94_TestParamSet                831
+#define OBJ_id_GostR3410_94_TestParamSet                OBJ_cryptopro,32L,0L
+
+#define SN_id_GostR3410_94_CryptoPro_A_ParamSet         "id-GostR3410-94-CryptoPro-A-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_A_ParamSet                832
+#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet                OBJ_cryptopro,32L,2L
+
+#define SN_id_GostR3410_94_CryptoPro_B_ParamSet         "id-GostR3410-94-CryptoPro-B-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_B_ParamSet                833
+#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet                OBJ_cryptopro,32L,3L
+
+#define SN_id_GostR3410_94_CryptoPro_C_ParamSet         "id-GostR3410-94-CryptoPro-C-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_C_ParamSet                834
+#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet                OBJ_cryptopro,32L,4L
+
+#define SN_id_GostR3410_94_CryptoPro_D_ParamSet         "id-GostR3410-94-CryptoPro-D-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_D_ParamSet                835
+#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet                OBJ_cryptopro,32L,5L
+
+#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet              "id-GostR3410-94-CryptoPro-XchA-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet             836
+#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet             OBJ_cryptopro,33L,1L
+
+#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet              "id-GostR3410-94-CryptoPro-XchB-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet             837
+#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet             OBJ_cryptopro,33L,2L
+
+#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet              "id-GostR3410-94-CryptoPro-XchC-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet             838
+#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet             OBJ_cryptopro,33L,3L
+
+#define SN_id_GostR3410_2001_TestParamSet               "id-GostR3410-2001-TestParamSet"
+#define NID_id_GostR3410_2001_TestParamSet              839
+#define OBJ_id_GostR3410_2001_TestParamSet              OBJ_cryptopro,35L,0L
+
+#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet               "id-GostR3410-2001-CryptoPro-A-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet              840
+#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet              OBJ_cryptopro,35L,1L
+
+#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet               "id-GostR3410-2001-CryptoPro-B-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet              841
+#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet              OBJ_cryptopro,35L,2L
+
+#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet               "id-GostR3410-2001-CryptoPro-C-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet              842
+#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet              OBJ_cryptopro,35L,3L
+
+#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet            "id-GostR3410-2001-CryptoPro-XchA-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet           843
+#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet           OBJ_cryptopro,36L,0L
+
+#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet            "id-GostR3410-2001-CryptoPro-XchB-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet           844
+#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet           OBJ_cryptopro,36L,1L
+
+#define SN_id_GostR3410_94_a            "id-GostR3410-94-a"
+#define NID_id_GostR3410_94_a           845
+#define OBJ_id_GostR3410_94_a           OBJ_id_GostR3410_94,1L
+
+#define SN_id_GostR3410_94_aBis         "id-GostR3410-94-aBis"
+#define NID_id_GostR3410_94_aBis                846
+#define OBJ_id_GostR3410_94_aBis                OBJ_id_GostR3410_94,2L
+
+#define SN_id_GostR3410_94_b            "id-GostR3410-94-b"
+#define NID_id_GostR3410_94_b           847
+#define OBJ_id_GostR3410_94_b           OBJ_id_GostR3410_94,3L
+
+#define SN_id_GostR3410_94_bBis         "id-GostR3410-94-bBis"
+#define NID_id_GostR3410_94_bBis                848
+#define OBJ_id_GostR3410_94_bBis                OBJ_id_GostR3410_94,4L
+
+#define SN_id_Gost28147_89_cc           "id-Gost28147-89-cc"
+#define LN_id_Gost28147_89_cc           "GOST 28147-89 Cryptocom ParamSet"
+#define NID_id_Gost28147_89_cc          849
+#define OBJ_id_Gost28147_89_cc          OBJ_cryptocom,1L,6L,1L
+
+#define SN_id_GostR3410_94_cc           "gost94cc"
+#define LN_id_GostR3410_94_cc           "GOST 34.10-94 Cryptocom"
+#define NID_id_GostR3410_94_cc          850
+#define OBJ_id_GostR3410_94_cc          OBJ_cryptocom,1L,5L,3L
+
+#define SN_id_GostR3410_2001_cc         "gost2001cc"
+#define LN_id_GostR3410_2001_cc         "GOST 34.10-2001 Cryptocom"
+#define NID_id_GostR3410_2001_cc                851
+#define OBJ_id_GostR3410_2001_cc                OBJ_cryptocom,1L,5L,4L
+
+#define SN_id_GostR3411_94_with_GostR3410_94_cc         "id-GostR3411-94-with-GostR3410-94-cc"
+#define LN_id_GostR3411_94_with_GostR3410_94_cc         "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom"
+#define NID_id_GostR3411_94_with_GostR3410_94_cc                852
+#define OBJ_id_GostR3411_94_with_GostR3410_94_cc                OBJ_cryptocom,1L,3L,3L
+
+#define SN_id_GostR3411_94_with_GostR3410_2001_cc               "id-GostR3411-94-with-GostR3410-2001-cc"
+#define LN_id_GostR3411_94_with_GostR3410_2001_cc               "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom"
+#define NID_id_GostR3411_94_with_GostR3410_2001_cc              853
+#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc              OBJ_cryptocom,1L,3L,4L
+
+#define SN_id_GostR3410_2001_ParamSet_cc                "id-GostR3410-2001-ParamSet-cc"
+#define LN_id_GostR3410_2001_ParamSet_cc                "GOST R 3410-2001 Parameter Set Cryptocom"
+#define NID_id_GostR3410_2001_ParamSet_cc               854
+#define OBJ_id_GostR3410_2001_ParamSet_cc               OBJ_cryptocom,1L,8L,1L
+
+#define SN_id_tc26_algorithms           "id-tc26-algorithms"
+#define NID_id_tc26_algorithms          977
+#define OBJ_id_tc26_algorithms          OBJ_id_tc26,1L
+
+#define SN_id_tc26_sign         "id-tc26-sign"
+#define NID_id_tc26_sign                978
+#define OBJ_id_tc26_sign                OBJ_id_tc26_algorithms,1L
+
+#define SN_id_GostR3410_2012_256                "gost2012_256"
+#define LN_id_GostR3410_2012_256                "GOST R 34.10-2012 with 256 bit modulus"
+#define NID_id_GostR3410_2012_256               979
+#define OBJ_id_GostR3410_2012_256               OBJ_id_tc26_sign,1L
+
+#define SN_id_GostR3410_2012_512                "gost2012_512"
+#define LN_id_GostR3410_2012_512                "GOST R 34.10-2012 with 512 bit modulus"
+#define NID_id_GostR3410_2012_512               980
+#define OBJ_id_GostR3410_2012_512               OBJ_id_tc26_sign,2L
+
+#define SN_id_tc26_digest               "id-tc26-digest"
+#define NID_id_tc26_digest              981
+#define OBJ_id_tc26_digest              OBJ_id_tc26_algorithms,2L
+
+#define SN_id_GostR3411_2012_256                "md_gost12_256"
+#define LN_id_GostR3411_2012_256                "GOST R 34.11-2012 with 256 bit hash"
+#define NID_id_GostR3411_2012_256               982
+#define OBJ_id_GostR3411_2012_256               OBJ_id_tc26_digest,2L
+
+#define SN_id_GostR3411_2012_512                "md_gost12_512"
+#define LN_id_GostR3411_2012_512                "GOST R 34.11-2012 with 512 bit hash"
+#define NID_id_GostR3411_2012_512               983
+#define OBJ_id_GostR3411_2012_512               OBJ_id_tc26_digest,3L
+
+#define SN_id_tc26_signwithdigest               "id-tc26-signwithdigest"
+#define NID_id_tc26_signwithdigest              984
+#define OBJ_id_tc26_signwithdigest              OBJ_id_tc26_algorithms,3L
+
+#define SN_id_tc26_signwithdigest_gost3410_2012_256             "id-tc26-signwithdigest-gost3410-2012-256"
+#define LN_id_tc26_signwithdigest_gost3410_2012_256             "GOST R 34.10-2012 with GOST R 34.11-2012 (256 bit)"
+#define NID_id_tc26_signwithdigest_gost3410_2012_256            985
+#define OBJ_id_tc26_signwithdigest_gost3410_2012_256            OBJ_id_tc26_signwithdigest,2L
+
+#define SN_id_tc26_signwithdigest_gost3410_2012_512             "id-tc26-signwithdigest-gost3410-2012-512"
+#define LN_id_tc26_signwithdigest_gost3410_2012_512             "GOST R 34.10-2012 with GOST R 34.11-2012 (512 bit)"
+#define NID_id_tc26_signwithdigest_gost3410_2012_512            986
+#define OBJ_id_tc26_signwithdigest_gost3410_2012_512            OBJ_id_tc26_signwithdigest,3L
+
+#define SN_id_tc26_mac          "id-tc26-mac"
+#define NID_id_tc26_mac         987
+#define OBJ_id_tc26_mac         OBJ_id_tc26_algorithms,4L
+
+#define SN_id_tc26_hmac_gost_3411_2012_256              "id-tc26-hmac-gost-3411-2012-256"
+#define LN_id_tc26_hmac_gost_3411_2012_256              "HMAC GOST 34.11-2012 256 bit"
+#define NID_id_tc26_hmac_gost_3411_2012_256             988
+#define OBJ_id_tc26_hmac_gost_3411_2012_256             OBJ_id_tc26_mac,1L
+
+#define SN_id_tc26_hmac_gost_3411_2012_512              "id-tc26-hmac-gost-3411-2012-512"
+#define LN_id_tc26_hmac_gost_3411_2012_512              "HMAC GOST 34.11-2012 512 bit"
+#define NID_id_tc26_hmac_gost_3411_2012_512             989
+#define OBJ_id_tc26_hmac_gost_3411_2012_512             OBJ_id_tc26_mac,2L
+
+#define SN_id_tc26_cipher               "id-tc26-cipher"
+#define NID_id_tc26_cipher              990
+#define OBJ_id_tc26_cipher              OBJ_id_tc26_algorithms,5L
+
+#define SN_id_tc26_agreement            "id-tc26-agreement"
+#define NID_id_tc26_agreement           991
+#define OBJ_id_tc26_agreement           OBJ_id_tc26_algorithms,6L
+
+#define SN_id_tc26_agreement_gost_3410_2012_256         "id-tc26-agreement-gost-3410-2012-256"
+#define NID_id_tc26_agreement_gost_3410_2012_256                992
+#define OBJ_id_tc26_agreement_gost_3410_2012_256                OBJ_id_tc26_agreement,1L
+
+#define SN_id_tc26_agreement_gost_3410_2012_512         "id-tc26-agreement-gost-3410-2012-512"
+#define NID_id_tc26_agreement_gost_3410_2012_512                993
+#define OBJ_id_tc26_agreement_gost_3410_2012_512                OBJ_id_tc26_agreement,2L
+
+#define SN_id_tc26_constants            "id-tc26-constants"
+#define NID_id_tc26_constants           994
+#define OBJ_id_tc26_constants           OBJ_id_tc26,2L
+
+#define SN_id_tc26_sign_constants               "id-tc26-sign-constants"
+#define NID_id_tc26_sign_constants              995
+#define OBJ_id_tc26_sign_constants              OBJ_id_tc26_constants,1L
+
+#define SN_id_tc26_gost_3410_2012_512_constants         "id-tc26-gost-3410-2012-512-constants"
+#define NID_id_tc26_gost_3410_2012_512_constants                996
+#define OBJ_id_tc26_gost_3410_2012_512_constants                OBJ_id_tc26_sign_constants,2L
+
+#define SN_id_tc26_gost_3410_2012_512_paramSetTest              "id-tc26-gost-3410-2012-512-paramSetTest"
+#define LN_id_tc26_gost_3410_2012_512_paramSetTest              "GOST R 34.10-2012 (512 bit) testing parameter set"
+#define NID_id_tc26_gost_3410_2012_512_paramSetTest             997
+#define OBJ_id_tc26_gost_3410_2012_512_paramSetTest             OBJ_id_tc26_gost_3410_2012_512_constants,0L
+
+#define SN_id_tc26_gost_3410_2012_512_paramSetA         "id-tc26-gost-3410-2012-512-paramSetA"
+#define LN_id_tc26_gost_3410_2012_512_paramSetA         "GOST R 34.10-2012 (512 bit) ParamSet A"
+#define NID_id_tc26_gost_3410_2012_512_paramSetA                998
+#define OBJ_id_tc26_gost_3410_2012_512_paramSetA                OBJ_id_tc26_gost_3410_2012_512_constants,1L
+
+#define SN_id_tc26_gost_3410_2012_512_paramSetB         "id-tc26-gost-3410-2012-512-paramSetB"
+#define LN_id_tc26_gost_3410_2012_512_paramSetB         "GOST R 34.10-2012 (512 bit) ParamSet B"
+#define NID_id_tc26_gost_3410_2012_512_paramSetB                999
+#define OBJ_id_tc26_gost_3410_2012_512_paramSetB                OBJ_id_tc26_gost_3410_2012_512_constants,2L
+
+#define SN_id_tc26_digest_constants             "id-tc26-digest-constants"
+#define NID_id_tc26_digest_constants            1000
+#define OBJ_id_tc26_digest_constants            OBJ_id_tc26_constants,2L
+
+#define SN_id_tc26_cipher_constants             "id-tc26-cipher-constants"
+#define NID_id_tc26_cipher_constants            1001
+#define OBJ_id_tc26_cipher_constants            OBJ_id_tc26_constants,5L
+
+#define SN_id_tc26_gost_28147_constants         "id-tc26-gost-28147-constants"
+#define NID_id_tc26_gost_28147_constants                1002
+#define OBJ_id_tc26_gost_28147_constants                OBJ_id_tc26_cipher_constants,1L
+
+#define SN_id_tc26_gost_28147_param_Z           "id-tc26-gost-28147-param-Z"
+#define LN_id_tc26_gost_28147_param_Z           "GOST 28147-89 TC26 parameter set"
+#define NID_id_tc26_gost_28147_param_Z          1003
+#define OBJ_id_tc26_gost_28147_param_Z          OBJ_id_tc26_gost_28147_constants,1L
+
+#define SN_INN          "INN"
+#define LN_INN          "INN"
+#define NID_INN         1004
+#define OBJ_INN         OBJ_member_body,643L,3L,131L,1L,1L
+
+#define SN_OGRN         "OGRN"
+#define LN_OGRN         "OGRN"
+#define NID_OGRN                1005
+#define OBJ_OGRN                OBJ_member_body,643L,100L,1L
+
+#define SN_SNILS                "SNILS"
+#define LN_SNILS                "SNILS"
+#define NID_SNILS               1006
+#define OBJ_SNILS               OBJ_member_body,643L,100L,3L
+
+#define SN_subjectSignTool              "subjectSignTool"
+#define LN_subjectSignTool              "Signing Tool of Subject"
+#define NID_subjectSignTool             1007
+#define OBJ_subjectSignTool             OBJ_member_body,643L,100L,111L
+
+#define SN_issuerSignTool               "issuerSignTool"
+#define LN_issuerSignTool               "Signing Tool of Issuer"
+#define NID_issuerSignTool              1008
+#define OBJ_issuerSignTool              OBJ_member_body,643L,100L,112L
+
+#define SN_grasshopper_ecb              "grasshopper-ecb"
+#define NID_grasshopper_ecb             1012
+
+#define SN_grasshopper_ctr              "grasshopper-ctr"
+#define NID_grasshopper_ctr             1013
+
+#define SN_grasshopper_ofb              "grasshopper-ofb"
+#define NID_grasshopper_ofb             1014
+
+#define SN_grasshopper_cbc              "grasshopper-cbc"
+#define NID_grasshopper_cbc             1015
+
+#define SN_grasshopper_cfb              "grasshopper-cfb"
+#define NID_grasshopper_cfb             1016
+
+#define SN_grasshopper_mac              "grasshopper-mac"
+#define NID_grasshopper_mac             1017
+
+#define SN_camellia_128_cbc             "CAMELLIA-128-CBC"
+#define LN_camellia_128_cbc             "camellia-128-cbc"
+#define NID_camellia_128_cbc            751
+#define OBJ_camellia_128_cbc            1L,2L,392L,200011L,61L,1L,1L,1L,2L
+
+#define SN_camellia_192_cbc             "CAMELLIA-192-CBC"
+#define LN_camellia_192_cbc             "camellia-192-cbc"
+#define NID_camellia_192_cbc            752
+#define OBJ_camellia_192_cbc            1L,2L,392L,200011L,61L,1L,1L,1L,3L
+
+#define SN_camellia_256_cbc             "CAMELLIA-256-CBC"
+#define LN_camellia_256_cbc             "camellia-256-cbc"
+#define NID_camellia_256_cbc            753
+#define OBJ_camellia_256_cbc            1L,2L,392L,200011L,61L,1L,1L,1L,4L
+
+#define SN_id_camellia128_wrap          "id-camellia128-wrap"
+#define NID_id_camellia128_wrap         907
+#define OBJ_id_camellia128_wrap         1L,2L,392L,200011L,61L,1L,1L,3L,2L
+
+#define SN_id_camellia192_wrap          "id-camellia192-wrap"
+#define NID_id_camellia192_wrap         908
+#define OBJ_id_camellia192_wrap         1L,2L,392L,200011L,61L,1L,1L,3L,3L
+
+#define SN_id_camellia256_wrap          "id-camellia256-wrap"
+#define NID_id_camellia256_wrap         909
+#define OBJ_id_camellia256_wrap         1L,2L,392L,200011L,61L,1L,1L,3L,4L
+
+#define OBJ_ntt_ds              0L,3L,4401L,5L
+
+#define OBJ_camellia            OBJ_ntt_ds,3L,1L,9L
+
+#define SN_camellia_128_ecb             "CAMELLIA-128-ECB"
+#define LN_camellia_128_ecb             "camellia-128-ecb"
+#define NID_camellia_128_ecb            754
+#define OBJ_camellia_128_ecb            OBJ_camellia,1L
+
+#define SN_camellia_128_ofb128          "CAMELLIA-128-OFB"
+#define LN_camellia_128_ofb128          "camellia-128-ofb"
+#define NID_camellia_128_ofb128         766
+#define OBJ_camellia_128_ofb128         OBJ_camellia,3L
+
+#define SN_camellia_128_cfb128          "CAMELLIA-128-CFB"
+#define LN_camellia_128_cfb128          "camellia-128-cfb"
+#define NID_camellia_128_cfb128         757
+#define OBJ_camellia_128_cfb128         OBJ_camellia,4L
+
+#define SN_camellia_128_gcm             "CAMELLIA-128-GCM"
+#define LN_camellia_128_gcm             "camellia-128-gcm"
+#define NID_camellia_128_gcm            961
+#define OBJ_camellia_128_gcm            OBJ_camellia,6L
+
+#define SN_camellia_128_ccm             "CAMELLIA-128-CCM"
+#define LN_camellia_128_ccm             "camellia-128-ccm"
+#define NID_camellia_128_ccm            962
+#define OBJ_camellia_128_ccm            OBJ_camellia,7L
+
+#define SN_camellia_128_ctr             "CAMELLIA-128-CTR"
+#define LN_camellia_128_ctr             "camellia-128-ctr"
+#define NID_camellia_128_ctr            963
+#define OBJ_camellia_128_ctr            OBJ_camellia,9L
+
+#define SN_camellia_128_cmac            "CAMELLIA-128-CMAC"
+#define LN_camellia_128_cmac            "camellia-128-cmac"
+#define NID_camellia_128_cmac           964
+#define OBJ_camellia_128_cmac           OBJ_camellia,10L
+
+#define SN_camellia_192_ecb             "CAMELLIA-192-ECB"
+#define LN_camellia_192_ecb             "camellia-192-ecb"
+#define NID_camellia_192_ecb            755
+#define OBJ_camellia_192_ecb            OBJ_camellia,21L
+
+#define SN_camellia_192_ofb128          "CAMELLIA-192-OFB"
+#define LN_camellia_192_ofb128          "camellia-192-ofb"
+#define NID_camellia_192_ofb128         767
+#define OBJ_camellia_192_ofb128         OBJ_camellia,23L
+
+#define SN_camellia_192_cfb128          "CAMELLIA-192-CFB"
+#define LN_camellia_192_cfb128          "camellia-192-cfb"
+#define NID_camellia_192_cfb128         758
+#define OBJ_camellia_192_cfb128         OBJ_camellia,24L
+
+#define SN_camellia_192_gcm             "CAMELLIA-192-GCM"
+#define LN_camellia_192_gcm             "camellia-192-gcm"
+#define NID_camellia_192_gcm            965
+#define OBJ_camellia_192_gcm            OBJ_camellia,26L
+
+#define SN_camellia_192_ccm             "CAMELLIA-192-CCM"
+#define LN_camellia_192_ccm             "camellia-192-ccm"
+#define NID_camellia_192_ccm            966
+#define OBJ_camellia_192_ccm            OBJ_camellia,27L
+
+#define SN_camellia_192_ctr             "CAMELLIA-192-CTR"
+#define LN_camellia_192_ctr             "camellia-192-ctr"
+#define NID_camellia_192_ctr            967
+#define OBJ_camellia_192_ctr            OBJ_camellia,29L
+
+#define SN_camellia_192_cmac            "CAMELLIA-192-CMAC"
+#define LN_camellia_192_cmac            "camellia-192-cmac"
+#define NID_camellia_192_cmac           968
+#define OBJ_camellia_192_cmac           OBJ_camellia,30L
+
+#define SN_camellia_256_ecb             "CAMELLIA-256-ECB"
+#define LN_camellia_256_ecb             "camellia-256-ecb"
+#define NID_camellia_256_ecb            756
+#define OBJ_camellia_256_ecb            OBJ_camellia,41L
+
+#define SN_camellia_256_ofb128          "CAMELLIA-256-OFB"
+#define LN_camellia_256_ofb128          "camellia-256-ofb"
+#define NID_camellia_256_ofb128         768
+#define OBJ_camellia_256_ofb128         OBJ_camellia,43L
+
+#define SN_camellia_256_cfb128          "CAMELLIA-256-CFB"
+#define LN_camellia_256_cfb128          "camellia-256-cfb"
+#define NID_camellia_256_cfb128         759
+#define OBJ_camellia_256_cfb128         OBJ_camellia,44L
+
+#define SN_camellia_256_gcm             "CAMELLIA-256-GCM"
+#define LN_camellia_256_gcm             "camellia-256-gcm"
+#define NID_camellia_256_gcm            969
+#define OBJ_camellia_256_gcm            OBJ_camellia,46L
+
+#define SN_camellia_256_ccm             "CAMELLIA-256-CCM"
+#define LN_camellia_256_ccm             "camellia-256-ccm"
+#define NID_camellia_256_ccm            970
+#define OBJ_camellia_256_ccm            OBJ_camellia,47L
+
+#define SN_camellia_256_ctr             "CAMELLIA-256-CTR"
+#define LN_camellia_256_ctr             "camellia-256-ctr"
+#define NID_camellia_256_ctr            971
+#define OBJ_camellia_256_ctr            OBJ_camellia,49L
+
+#define SN_camellia_256_cmac            "CAMELLIA-256-CMAC"
+#define LN_camellia_256_cmac            "camellia-256-cmac"
+#define NID_camellia_256_cmac           972
+#define OBJ_camellia_256_cmac           OBJ_camellia,50L
+
+#define SN_camellia_128_cfb1            "CAMELLIA-128-CFB1"
+#define LN_camellia_128_cfb1            "camellia-128-cfb1"
+#define NID_camellia_128_cfb1           760
+
+#define SN_camellia_192_cfb1            "CAMELLIA-192-CFB1"
+#define LN_camellia_192_cfb1            "camellia-192-cfb1"
+#define NID_camellia_192_cfb1           761
+
+#define SN_camellia_256_cfb1            "CAMELLIA-256-CFB1"
+#define LN_camellia_256_cfb1            "camellia-256-cfb1"
+#define NID_camellia_256_cfb1           762
+
+#define SN_camellia_128_cfb8            "CAMELLIA-128-CFB8"
+#define LN_camellia_128_cfb8            "camellia-128-cfb8"
+#define NID_camellia_128_cfb8           763
+
+#define SN_camellia_192_cfb8            "CAMELLIA-192-CFB8"
+#define LN_camellia_192_cfb8            "camellia-192-cfb8"
+#define NID_camellia_192_cfb8           764
+
+#define SN_camellia_256_cfb8            "CAMELLIA-256-CFB8"
+#define LN_camellia_256_cfb8            "camellia-256-cfb8"
+#define NID_camellia_256_cfb8           765
+
+#define SN_kisa         "KISA"
+#define LN_kisa         "kisa"
+#define NID_kisa                773
+#define OBJ_kisa                OBJ_member_body,410L,200004L
+
+#define SN_seed_ecb             "SEED-ECB"
+#define LN_seed_ecb             "seed-ecb"
+#define NID_seed_ecb            776
+#define OBJ_seed_ecb            OBJ_kisa,1L,3L
+
+#define SN_seed_cbc             "SEED-CBC"
+#define LN_seed_cbc             "seed-cbc"
+#define NID_seed_cbc            777
+#define OBJ_seed_cbc            OBJ_kisa,1L,4L
+
+#define SN_seed_cfb128          "SEED-CFB"
+#define LN_seed_cfb128          "seed-cfb"
+#define NID_seed_cfb128         779
+#define OBJ_seed_cfb128         OBJ_kisa,1L,5L
+
+#define SN_seed_ofb128          "SEED-OFB"
+#define LN_seed_ofb128          "seed-ofb"
+#define NID_seed_ofb128         778
+#define OBJ_seed_ofb128         OBJ_kisa,1L,6L
+
+#define SN_hmac         "HMAC"
+#define LN_hmac         "hmac"
+#define NID_hmac                855
+
+#define SN_cmac         "CMAC"
+#define LN_cmac         "cmac"
+#define NID_cmac                894
+
+#define SN_rc4_hmac_md5         "RC4-HMAC-MD5"
+#define LN_rc4_hmac_md5         "rc4-hmac-md5"
+#define NID_rc4_hmac_md5                915
+
+#define SN_aes_128_cbc_hmac_sha1                "AES-128-CBC-HMAC-SHA1"
+#define LN_aes_128_cbc_hmac_sha1                "aes-128-cbc-hmac-sha1"
+#define NID_aes_128_cbc_hmac_sha1               916
+
+#define SN_aes_192_cbc_hmac_sha1                "AES-192-CBC-HMAC-SHA1"
+#define LN_aes_192_cbc_hmac_sha1                "aes-192-cbc-hmac-sha1"
+#define NID_aes_192_cbc_hmac_sha1               917
+
+#define SN_aes_256_cbc_hmac_sha1                "AES-256-CBC-HMAC-SHA1"
+#define LN_aes_256_cbc_hmac_sha1                "aes-256-cbc-hmac-sha1"
+#define NID_aes_256_cbc_hmac_sha1               918
+
+#define SN_aes_128_cbc_hmac_sha256              "AES-128-CBC-HMAC-SHA256"
+#define LN_aes_128_cbc_hmac_sha256              "aes-128-cbc-hmac-sha256"
+#define NID_aes_128_cbc_hmac_sha256             948
+
+#define SN_aes_192_cbc_hmac_sha256              "AES-192-CBC-HMAC-SHA256"
+#define LN_aes_192_cbc_hmac_sha256              "aes-192-cbc-hmac-sha256"
+#define NID_aes_192_cbc_hmac_sha256             949
+
+#define SN_aes_256_cbc_hmac_sha256              "AES-256-CBC-HMAC-SHA256"
+#define LN_aes_256_cbc_hmac_sha256              "aes-256-cbc-hmac-sha256"
+#define NID_aes_256_cbc_hmac_sha256             950
+
+#define SN_chacha20_poly1305            "ChaCha20-Poly1305"
+#define LN_chacha20_poly1305            "chacha20-poly1305"
+#define NID_chacha20_poly1305           1018
+
+#define SN_chacha20             "ChaCha20"
+#define LN_chacha20             "chacha20"
+#define NID_chacha20            1019
+
+#define SN_dhpublicnumber               "dhpublicnumber"
+#define LN_dhpublicnumber               "X9.42 DH"
+#define NID_dhpublicnumber              920
+#define OBJ_dhpublicnumber              OBJ_ISO_US,10046L,2L,1L
+
+#define SN_brainpoolP160r1              "brainpoolP160r1"
+#define NID_brainpoolP160r1             921
+#define OBJ_brainpoolP160r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,1L
+
+#define SN_brainpoolP160t1              "brainpoolP160t1"
+#define NID_brainpoolP160t1             922
+#define OBJ_brainpoolP160t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,2L
+
+#define SN_brainpoolP192r1              "brainpoolP192r1"
+#define NID_brainpoolP192r1             923
+#define OBJ_brainpoolP192r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,3L
+
+#define SN_brainpoolP192t1              "brainpoolP192t1"
+#define NID_brainpoolP192t1             924
+#define OBJ_brainpoolP192t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,4L
+
+#define SN_brainpoolP224r1              "brainpoolP224r1"
+#define NID_brainpoolP224r1             925
+#define OBJ_brainpoolP224r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,5L
+
+#define SN_brainpoolP224t1              "brainpoolP224t1"
+#define NID_brainpoolP224t1             926
+#define OBJ_brainpoolP224t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,6L
+
+#define SN_brainpoolP256r1              "brainpoolP256r1"
+#define NID_brainpoolP256r1             927
+#define OBJ_brainpoolP256r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,7L
+
+#define SN_brainpoolP256t1              "brainpoolP256t1"
+#define NID_brainpoolP256t1             928
+#define OBJ_brainpoolP256t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,8L
+
+#define SN_brainpoolP320r1              "brainpoolP320r1"
+#define NID_brainpoolP320r1             929
+#define OBJ_brainpoolP320r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,9L
+
+#define SN_brainpoolP320t1              "brainpoolP320t1"
+#define NID_brainpoolP320t1             930
+#define OBJ_brainpoolP320t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,10L
+
+#define SN_brainpoolP384r1              "brainpoolP384r1"
+#define NID_brainpoolP384r1             931
+#define OBJ_brainpoolP384r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,11L
+
+#define SN_brainpoolP384t1              "brainpoolP384t1"
+#define NID_brainpoolP384t1             932
+#define OBJ_brainpoolP384t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,12L
+
+#define SN_brainpoolP512r1              "brainpoolP512r1"
+#define NID_brainpoolP512r1             933
+#define OBJ_brainpoolP512r1             1L,3L,36L,3L,3L,2L,8L,1L,1L,13L
+
+#define SN_brainpoolP512t1              "brainpoolP512t1"
+#define NID_brainpoolP512t1             934
+#define OBJ_brainpoolP512t1             1L,3L,36L,3L,3L,2L,8L,1L,1L,14L
+
+#define OBJ_x9_63_scheme                1L,3L,133L,16L,840L,63L,0L
+
+#define OBJ_secg_scheme         OBJ_certicom_arc,1L
+
+#define SN_dhSinglePass_stdDH_sha1kdf_scheme            "dhSinglePass-stdDH-sha1kdf-scheme"
+#define NID_dhSinglePass_stdDH_sha1kdf_scheme           936
+#define OBJ_dhSinglePass_stdDH_sha1kdf_scheme           OBJ_x9_63_scheme,2L
+
+#define SN_dhSinglePass_stdDH_sha224kdf_scheme          "dhSinglePass-stdDH-sha224kdf-scheme"
+#define NID_dhSinglePass_stdDH_sha224kdf_scheme         937
+#define OBJ_dhSinglePass_stdDH_sha224kdf_scheme         OBJ_secg_scheme,11L,0L
+
+#define SN_dhSinglePass_stdDH_sha256kdf_scheme          "dhSinglePass-stdDH-sha256kdf-scheme"
+#define NID_dhSinglePass_stdDH_sha256kdf_scheme         938
+#define OBJ_dhSinglePass_stdDH_sha256kdf_scheme         OBJ_secg_scheme,11L,1L
+
+#define SN_dhSinglePass_stdDH_sha384kdf_scheme          "dhSinglePass-stdDH-sha384kdf-scheme"
+#define NID_dhSinglePass_stdDH_sha384kdf_scheme         939
+#define OBJ_dhSinglePass_stdDH_sha384kdf_scheme         OBJ_secg_scheme,11L,2L
+
+#define SN_dhSinglePass_stdDH_sha512kdf_scheme          "dhSinglePass-stdDH-sha512kdf-scheme"
+#define NID_dhSinglePass_stdDH_sha512kdf_scheme         940
+#define OBJ_dhSinglePass_stdDH_sha512kdf_scheme         OBJ_secg_scheme,11L,3L
+
+#define SN_dhSinglePass_cofactorDH_sha1kdf_scheme               "dhSinglePass-cofactorDH-sha1kdf-scheme"
+#define NID_dhSinglePass_cofactorDH_sha1kdf_scheme              941
+#define OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme              OBJ_x9_63_scheme,3L
+
+#define SN_dhSinglePass_cofactorDH_sha224kdf_scheme             "dhSinglePass-cofactorDH-sha224kdf-scheme"
+#define NID_dhSinglePass_cofactorDH_sha224kdf_scheme            942
+#define OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme            OBJ_secg_scheme,14L,0L
+
+#define SN_dhSinglePass_cofactorDH_sha256kdf_scheme             "dhSinglePass-cofactorDH-sha256kdf-scheme"
+#define NID_dhSinglePass_cofactorDH_sha256kdf_scheme            943
+#define OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme            OBJ_secg_scheme,14L,1L
+
+#define SN_dhSinglePass_cofactorDH_sha384kdf_scheme             "dhSinglePass-cofactorDH-sha384kdf-scheme"
+#define NID_dhSinglePass_cofactorDH_sha384kdf_scheme            944
+#define OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme            OBJ_secg_scheme,14L,2L
+
+#define SN_dhSinglePass_cofactorDH_sha512kdf_scheme             "dhSinglePass-cofactorDH-sha512kdf-scheme"
+#define NID_dhSinglePass_cofactorDH_sha512kdf_scheme            945
+#define OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme            OBJ_secg_scheme,14L,3L
+
+#define SN_dh_std_kdf           "dh-std-kdf"
+#define NID_dh_std_kdf          946
+
+#define SN_dh_cofactor_kdf              "dh-cofactor-kdf"
+#define NID_dh_cofactor_kdf             947
+
+#define SN_ct_precert_scts              "ct_precert_scts"
+#define LN_ct_precert_scts              "CT Precertificate SCTs"
+#define NID_ct_precert_scts             951
+#define OBJ_ct_precert_scts             1L,3L,6L,1L,4L,1L,11129L,2L,4L,2L
+
+#define SN_ct_precert_poison            "ct_precert_poison"
+#define LN_ct_precert_poison            "CT Precertificate Poison"
+#define NID_ct_precert_poison           952
+#define OBJ_ct_precert_poison           1L,3L,6L,1L,4L,1L,11129L,2L,4L,3L
+
+#define SN_ct_precert_signer            "ct_precert_signer"
+#define LN_ct_precert_signer            "CT Precertificate Signer"
+#define NID_ct_precert_signer           953
+#define OBJ_ct_precert_signer           1L,3L,6L,1L,4L,1L,11129L,2L,4L,4L
+
+#define SN_ct_cert_scts         "ct_cert_scts"
+#define LN_ct_cert_scts         "CT Certificate SCTs"
+#define NID_ct_cert_scts                954
+#define OBJ_ct_cert_scts                1L,3L,6L,1L,4L,1L,11129L,2L,4L,5L
+
+#define SN_jurisdictionLocalityName             "jurisdictionL"
+#define LN_jurisdictionLocalityName             "jurisdictionLocalityName"
+#define NID_jurisdictionLocalityName            955
+#define OBJ_jurisdictionLocalityName            1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,1L
+
+#define SN_jurisdictionStateOrProvinceName              "jurisdictionST"
+#define LN_jurisdictionStateOrProvinceName              "jurisdictionStateOrProvinceName"
+#define NID_jurisdictionStateOrProvinceName             956
+#define OBJ_jurisdictionStateOrProvinceName             1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,2L
+
+#define SN_jurisdictionCountryName              "jurisdictionC"
+#define LN_jurisdictionCountryName              "jurisdictionCountryName"
+#define NID_jurisdictionCountryName             957
+#define OBJ_jurisdictionCountryName             1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,3L
+
+#define SN_id_scrypt            "id-scrypt"
+#define NID_id_scrypt           973
+#define OBJ_id_scrypt           1L,3L,6L,1L,4L,1L,11591L,4L,11L
+
+#define SN_tls1_prf             "TLS1-PRF"
+#define LN_tls1_prf             "tls1-prf"
+#define NID_tls1_prf            1021
+
+#define SN_hkdf         "HKDF"
+#define LN_hkdf         "hkdf"
+#define NID_hkdf                1036
+
+#define SN_id_pkinit            "id-pkinit"
+#define NID_id_pkinit           1031
+#define OBJ_id_pkinit           1L,3L,6L,1L,5L,2L,3L
+
+#define SN_pkInitClientAuth             "pkInitClientAuth"
+#define LN_pkInitClientAuth             "PKINIT Client Auth"
+#define NID_pkInitClientAuth            1032
+#define OBJ_pkInitClientAuth            OBJ_id_pkinit,4L
+
+#define SN_pkInitKDC            "pkInitKDC"
+#define LN_pkInitKDC            "Signing KDC Response"
+#define NID_pkInitKDC           1033
+#define OBJ_pkInitKDC           OBJ_id_pkinit,5L
+
+#define SN_X25519               "X25519"
+#define NID_X25519              1034
+#define OBJ_X25519              1L,3L,101L,110L
+
+#define SN_X448         "X448"
+#define NID_X448                1035
+#define OBJ_X448                1L,3L,101L,111L
+
+#define SN_kx_rsa               "KxRSA"
+#define LN_kx_rsa               "kx-rsa"
+#define NID_kx_rsa              1037
+
+#define SN_kx_ecdhe             "KxECDHE"
+#define LN_kx_ecdhe             "kx-ecdhe"
+#define NID_kx_ecdhe            1038
+
+#define SN_kx_dhe               "KxDHE"
+#define LN_kx_dhe               "kx-dhe"
+#define NID_kx_dhe              1039
+
+#define SN_kx_ecdhe_psk         "KxECDHE-PSK"
+#define LN_kx_ecdhe_psk         "kx-ecdhe-psk"
+#define NID_kx_ecdhe_psk                1040
+
+#define SN_kx_dhe_psk           "KxDHE-PSK"
+#define LN_kx_dhe_psk           "kx-dhe-psk"
+#define NID_kx_dhe_psk          1041
+
+#define SN_kx_rsa_psk           "KxRSA_PSK"
+#define LN_kx_rsa_psk           "kx-rsa-psk"
+#define NID_kx_rsa_psk          1042
+
+#define SN_kx_psk               "KxPSK"
+#define LN_kx_psk               "kx-psk"
+#define NID_kx_psk              1043
+
+#define SN_kx_srp               "KxSRP"
+#define LN_kx_srp               "kx-srp"
+#define NID_kx_srp              1044
+
+#define SN_kx_gost              "KxGOST"
+#define LN_kx_gost              "kx-gost"
+#define NID_kx_gost             1045
+
+#define SN_auth_rsa             "AuthRSA"
+#define LN_auth_rsa             "auth-rsa"
+#define NID_auth_rsa            1046
+
+#define SN_auth_ecdsa           "AuthECDSA"
+#define LN_auth_ecdsa           "auth-ecdsa"
+#define NID_auth_ecdsa          1047
+
+#define SN_auth_psk             "AuthPSK"
+#define LN_auth_psk             "auth-psk"
+#define NID_auth_psk            1048
+
+#define SN_auth_dss             "AuthDSS"
+#define LN_auth_dss             "auth-dss"
+#define NID_auth_dss            1049
+
+#define SN_auth_gost01          "AuthGOST01"
+#define LN_auth_gost01          "auth-gost01"
+#define NID_auth_gost01         1050
+
+#define SN_auth_gost12          "AuthGOST12"
+#define LN_auth_gost12          "auth-gost12"
+#define NID_auth_gost12         1051
+
+#define SN_auth_srp             "AuthSRP"
+#define LN_auth_srp             "auth-srp"
+#define NID_auth_srp            1052
+
+#define SN_auth_null            "AuthNULL"
+#define LN_auth_null            "auth-null"
+#define NID_auth_null           1053
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/objects.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/objects.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/objects.h	(revision 331)
@@ -0,0 +1,1097 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_OBJECTS_H
+# define HEADER_OBJECTS_H
+
+# define USE_OBJ_MAC
+
+# ifdef USE_OBJ_MAC
+#  include <openssl/obj_mac.h>
+# else
+#  define SN_undef                        "UNDEF"
+#  define LN_undef                        "undefined"
+#  define NID_undef                       0
+#  define OBJ_undef                       0L
+
+#  define SN_Algorithm                    "Algorithm"
+#  define LN_algorithm                    "algorithm"
+#  define NID_algorithm                   38
+#  define OBJ_algorithm                   1L,3L,14L,3L,2L
+
+#  define LN_rsadsi                       "rsadsi"
+#  define NID_rsadsi                      1
+#  define OBJ_rsadsi                      1L,2L,840L,113549L
+
+#  define LN_pkcs                         "pkcs"
+#  define NID_pkcs                        2
+#  define OBJ_pkcs                        OBJ_rsadsi,1L
+
+#  define SN_md2                          "MD2"
+#  define LN_md2                          "md2"
+#  define NID_md2                         3
+#  define OBJ_md2                         OBJ_rsadsi,2L,2L
+
+#  define SN_md5                          "MD5"
+#  define LN_md5                          "md5"
+#  define NID_md5                         4
+#  define OBJ_md5                         OBJ_rsadsi,2L,5L
+
+#  define SN_rc4                          "RC4"
+#  define LN_rc4                          "rc4"
+#  define NID_rc4                         5
+#  define OBJ_rc4                         OBJ_rsadsi,3L,4L
+
+#  define LN_rsaEncryption                "rsaEncryption"
+#  define NID_rsaEncryption               6
+#  define OBJ_rsaEncryption               OBJ_pkcs,1L,1L
+
+#  define SN_md2WithRSAEncryption         "RSA-MD2"
+#  define LN_md2WithRSAEncryption         "md2WithRSAEncryption"
+#  define NID_md2WithRSAEncryption        7
+#  define OBJ_md2WithRSAEncryption        OBJ_pkcs,1L,2L
+
+#  define SN_md5WithRSAEncryption         "RSA-MD5"
+#  define LN_md5WithRSAEncryption         "md5WithRSAEncryption"
+#  define NID_md5WithRSAEncryption        8
+#  define OBJ_md5WithRSAEncryption        OBJ_pkcs,1L,4L
+
+#  define SN_pbeWithMD2AndDES_CBC         "PBE-MD2-DES"
+#  define LN_pbeWithMD2AndDES_CBC         "pbeWithMD2AndDES-CBC"
+#  define NID_pbeWithMD2AndDES_CBC        9
+#  define OBJ_pbeWithMD2AndDES_CBC        OBJ_pkcs,5L,1L
+
+#  define SN_pbeWithMD5AndDES_CBC         "PBE-MD5-DES"
+#  define LN_pbeWithMD5AndDES_CBC         "pbeWithMD5AndDES-CBC"
+#  define NID_pbeWithMD5AndDES_CBC        10
+#  define OBJ_pbeWithMD5AndDES_CBC        OBJ_pkcs,5L,3L
+
+#  define LN_X500                         "X500"
+#  define NID_X500                        11
+#  define OBJ_X500                        2L,5L
+
+#  define LN_X509                         "X509"
+#  define NID_X509                        12
+#  define OBJ_X509                        OBJ_X500,4L
+
+#  define SN_commonName                   "CN"
+#  define LN_commonName                   "commonName"
+#  define NID_commonName                  13
+#  define OBJ_commonName                  OBJ_X509,3L
+
+#  define SN_countryName                  "C"
+#  define LN_countryName                  "countryName"
+#  define NID_countryName                 14
+#  define OBJ_countryName                 OBJ_X509,6L
+
+#  define SN_localityName                 "L"
+#  define LN_localityName                 "localityName"
+#  define NID_localityName                15
+#  define OBJ_localityName                OBJ_X509,7L
+
+/* Postal Address? PA */
+
+/* should be "ST" (rfc1327) but MS uses 'S' */
+#  define SN_stateOrProvinceName          "ST"
+#  define LN_stateOrProvinceName          "stateOrProvinceName"
+#  define NID_stateOrProvinceName         16
+#  define OBJ_stateOrProvinceName         OBJ_X509,8L
+
+#  define SN_organizationName             "O"
+#  define LN_organizationName             "organizationName"
+#  define NID_organizationName            17
+#  define OBJ_organizationName            OBJ_X509,10L
+
+#  define SN_organizationalUnitName       "OU"
+#  define LN_organizationalUnitName       "organizationalUnitName"
+#  define NID_organizationalUnitName      18
+#  define OBJ_organizationalUnitName      OBJ_X509,11L
+
+#  define SN_rsa                          "RSA"
+#  define LN_rsa                          "rsa"
+#  define NID_rsa                         19
+#  define OBJ_rsa                         OBJ_X500,8L,1L,1L
+
+#  define LN_pkcs7                        "pkcs7"
+#  define NID_pkcs7                       20
+#  define OBJ_pkcs7                       OBJ_pkcs,7L
+
+#  define LN_pkcs7_data                   "pkcs7-data"
+#  define NID_pkcs7_data                  21
+#  define OBJ_pkcs7_data                  OBJ_pkcs7,1L
+
+#  define LN_pkcs7_signed                 "pkcs7-signedData"
+#  define NID_pkcs7_signed                22
+#  define OBJ_pkcs7_signed                OBJ_pkcs7,2L
+
+#  define LN_pkcs7_enveloped              "pkcs7-envelopedData"
+#  define NID_pkcs7_enveloped             23
+#  define OBJ_pkcs7_enveloped             OBJ_pkcs7,3L
+
+#  define LN_pkcs7_signedAndEnveloped     "pkcs7-signedAndEnvelopedData"
+#  define NID_pkcs7_signedAndEnveloped    24
+#  define OBJ_pkcs7_signedAndEnveloped    OBJ_pkcs7,4L
+
+#  define LN_pkcs7_digest                 "pkcs7-digestData"
+#  define NID_pkcs7_digest                25
+#  define OBJ_pkcs7_digest                OBJ_pkcs7,5L
+
+#  define LN_pkcs7_encrypted              "pkcs7-encryptedData"
+#  define NID_pkcs7_encrypted             26
+#  define OBJ_pkcs7_encrypted             OBJ_pkcs7,6L
+
+#  define LN_pkcs3                        "pkcs3"
+#  define NID_pkcs3                       27
+#  define OBJ_pkcs3                       OBJ_pkcs,3L
+
+#  define LN_dhKeyAgreement               "dhKeyAgreement"
+#  define NID_dhKeyAgreement              28
+#  define OBJ_dhKeyAgreement              OBJ_pkcs3,1L
+
+#  define SN_des_ecb                      "DES-ECB"
+#  define LN_des_ecb                      "des-ecb"
+#  define NID_des_ecb                     29
+#  define OBJ_des_ecb                     OBJ_algorithm,6L
+
+#  define SN_des_cfb64                    "DES-CFB"
+#  define LN_des_cfb64                    "des-cfb"
+#  define NID_des_cfb64                   30
+/* IV + num */
+#  define OBJ_des_cfb64                   OBJ_algorithm,9L
+
+#  define SN_des_cbc                      "DES-CBC"
+#  define LN_des_cbc                      "des-cbc"
+#  define NID_des_cbc                     31
+/* IV */
+#  define OBJ_des_cbc                     OBJ_algorithm,7L
+
+#  define SN_des_ede                      "DES-EDE"
+#  define LN_des_ede                      "des-ede"
+#  define NID_des_ede                     32
+/* ?? */
+#  define OBJ_des_ede                     OBJ_algorithm,17L
+
+#  define SN_des_ede3                     "DES-EDE3"
+#  define LN_des_ede3                     "des-ede3"
+#  define NID_des_ede3                    33
+
+#  define SN_idea_cbc                     "IDEA-CBC"
+#  define LN_idea_cbc                     "idea-cbc"
+#  define NID_idea_cbc                    34
+#  define OBJ_idea_cbc                    1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
+
+#  define SN_idea_cfb64                   "IDEA-CFB"
+#  define LN_idea_cfb64                   "idea-cfb"
+#  define NID_idea_cfb64                  35
+
+#  define SN_idea_ecb                     "IDEA-ECB"
+#  define LN_idea_ecb                     "idea-ecb"
+#  define NID_idea_ecb                    36
+
+#  define SN_rc2_cbc                      "RC2-CBC"
+#  define LN_rc2_cbc                      "rc2-cbc"
+#  define NID_rc2_cbc                     37
+#  define OBJ_rc2_cbc                     OBJ_rsadsi,3L,2L
+
+#  define SN_rc2_ecb                      "RC2-ECB"
+#  define LN_rc2_ecb                      "rc2-ecb"
+#  define NID_rc2_ecb                     38
+
+#  define SN_rc2_cfb64                    "RC2-CFB"
+#  define LN_rc2_cfb64                    "rc2-cfb"
+#  define NID_rc2_cfb64                   39
+
+#  define SN_rc2_ofb64                    "RC2-OFB"
+#  define LN_rc2_ofb64                    "rc2-ofb"
+#  define NID_rc2_ofb64                   40
+
+#  define SN_sha                          "SHA"
+#  define LN_sha                          "sha"
+#  define NID_sha                         41
+#  define OBJ_sha                         OBJ_algorithm,18L
+
+#  define SN_shaWithRSAEncryption         "RSA-SHA"
+#  define LN_shaWithRSAEncryption         "shaWithRSAEncryption"
+#  define NID_shaWithRSAEncryption        42
+#  define OBJ_shaWithRSAEncryption        OBJ_algorithm,15L
+
+#  define SN_des_ede_cbc                  "DES-EDE-CBC"
+#  define LN_des_ede_cbc                  "des-ede-cbc"
+#  define NID_des_ede_cbc                 43
+
+#  define SN_des_ede3_cbc                 "DES-EDE3-CBC"
+#  define LN_des_ede3_cbc                 "des-ede3-cbc"
+#  define NID_des_ede3_cbc                44
+#  define OBJ_des_ede3_cbc                OBJ_rsadsi,3L,7L
+
+#  define SN_des_ofb64                    "DES-OFB"
+#  define LN_des_ofb64                    "des-ofb"
+#  define NID_des_ofb64                   45
+#  define OBJ_des_ofb64                   OBJ_algorithm,8L
+
+#  define SN_idea_ofb64                   "IDEA-OFB"
+#  define LN_idea_ofb64                   "idea-ofb"
+#  define NID_idea_ofb64                  46
+
+#  define LN_pkcs9                        "pkcs9"
+#  define NID_pkcs9                       47
+#  define OBJ_pkcs9                       OBJ_pkcs,9L
+
+#  define SN_pkcs9_emailAddress           "Email"
+#  define LN_pkcs9_emailAddress           "emailAddress"
+#  define NID_pkcs9_emailAddress          48
+#  define OBJ_pkcs9_emailAddress          OBJ_pkcs9,1L
+
+#  define LN_pkcs9_unstructuredName       "unstructuredName"
+#  define NID_pkcs9_unstructuredName      49
+#  define OBJ_pkcs9_unstructuredName      OBJ_pkcs9,2L
+
+#  define LN_pkcs9_contentType            "contentType"
+#  define NID_pkcs9_contentType           50
+#  define OBJ_pkcs9_contentType           OBJ_pkcs9,3L
+
+#  define LN_pkcs9_messageDigest          "messageDigest"
+#  define NID_pkcs9_messageDigest         51
+#  define OBJ_pkcs9_messageDigest         OBJ_pkcs9,4L
+
+#  define LN_pkcs9_signingTime            "signingTime"
+#  define NID_pkcs9_signingTime           52
+#  define OBJ_pkcs9_signingTime           OBJ_pkcs9,5L
+
+#  define LN_pkcs9_countersignature       "countersignature"
+#  define NID_pkcs9_countersignature      53
+#  define OBJ_pkcs9_countersignature      OBJ_pkcs9,6L
+
+#  define LN_pkcs9_challengePassword      "challengePassword"
+#  define NID_pkcs9_challengePassword     54
+#  define OBJ_pkcs9_challengePassword     OBJ_pkcs9,7L
+
+#  define LN_pkcs9_unstructuredAddress    "unstructuredAddress"
+#  define NID_pkcs9_unstructuredAddress   55
+#  define OBJ_pkcs9_unstructuredAddress   OBJ_pkcs9,8L
+
+#  define LN_pkcs9_extCertAttributes      "extendedCertificateAttributes"
+#  define NID_pkcs9_extCertAttributes     56
+#  define OBJ_pkcs9_extCertAttributes     OBJ_pkcs9,9L
+
+#  define SN_netscape                     "Netscape"
+#  define LN_netscape                     "Netscape Communications Corp."
+#  define NID_netscape                    57
+#  define OBJ_netscape                    2L,16L,840L,1L,113730L
+
+#  define SN_netscape_cert_extension      "nsCertExt"
+#  define LN_netscape_cert_extension      "Netscape Certificate Extension"
+#  define NID_netscape_cert_extension     58
+#  define OBJ_netscape_cert_extension     OBJ_netscape,1L
+
+#  define SN_netscape_data_type           "nsDataType"
+#  define LN_netscape_data_type           "Netscape Data Type"
+#  define NID_netscape_data_type          59
+#  define OBJ_netscape_data_type          OBJ_netscape,2L
+
+#  define SN_des_ede_cfb64                "DES-EDE-CFB"
+#  define LN_des_ede_cfb64                "des-ede-cfb"
+#  define NID_des_ede_cfb64               60
+
+#  define SN_des_ede3_cfb64               "DES-EDE3-CFB"
+#  define LN_des_ede3_cfb64               "des-ede3-cfb"
+#  define NID_des_ede3_cfb64              61
+
+#  define SN_des_ede_ofb64                "DES-EDE-OFB"
+#  define LN_des_ede_ofb64                "des-ede-ofb"
+#  define NID_des_ede_ofb64               62
+
+#  define SN_des_ede3_ofb64               "DES-EDE3-OFB"
+#  define LN_des_ede3_ofb64               "des-ede3-ofb"
+#  define NID_des_ede3_ofb64              63
+
+/* I'm not sure about the object ID */
+#  define SN_sha1                         "SHA1"
+#  define LN_sha1                         "sha1"
+#  define NID_sha1                        64
+#  define OBJ_sha1                        OBJ_algorithm,26L
+/* 28 Jun 1996 - eay */
+/* #define OBJ_sha1                     1L,3L,14L,2L,26L,05L <- wrong */
+
+#  define SN_sha1WithRSAEncryption        "RSA-SHA1"
+#  define LN_sha1WithRSAEncryption        "sha1WithRSAEncryption"
+#  define NID_sha1WithRSAEncryption       65
+#  define OBJ_sha1WithRSAEncryption       OBJ_pkcs,1L,5L
+
+#  define SN_dsaWithSHA                   "DSA-SHA"
+#  define LN_dsaWithSHA                   "dsaWithSHA"
+#  define NID_dsaWithSHA                  66
+#  define OBJ_dsaWithSHA                  OBJ_algorithm,13L
+
+#  define SN_dsa_2                        "DSA-old"
+#  define LN_dsa_2                        "dsaEncryption-old"
+#  define NID_dsa_2                       67
+#  define OBJ_dsa_2                       OBJ_algorithm,12L
+
+/* proposed by microsoft to RSA */
+#  define SN_pbeWithSHA1AndRC2_CBC        "PBE-SHA1-RC2-64"
+#  define LN_pbeWithSHA1AndRC2_CBC        "pbeWithSHA1AndRC2-CBC"
+#  define NID_pbeWithSHA1AndRC2_CBC       68
+#  define OBJ_pbeWithSHA1AndRC2_CBC       OBJ_pkcs,5L,11L
+
+/*
+ * proposed by microsoft to RSA as pbeWithSHA1AndRC4: it is now defined
+ * explicitly in PKCS#5 v2.0 as id-PBKDF2 which is something completely
+ * different.
+ */
+#  define LN_id_pbkdf2                    "PBKDF2"
+#  define NID_id_pbkdf2                   69
+#  define OBJ_id_pbkdf2                   OBJ_pkcs,5L,12L
+
+#  define SN_dsaWithSHA1_2                "DSA-SHA1-old"
+#  define LN_dsaWithSHA1_2                "dsaWithSHA1-old"
+#  define NID_dsaWithSHA1_2               70
+/* Got this one from 'sdn706r20.pdf' which is actually an NSA document :-) */
+#  define OBJ_dsaWithSHA1_2               OBJ_algorithm,27L
+
+#  define SN_netscape_cert_type           "nsCertType"
+#  define LN_netscape_cert_type           "Netscape Cert Type"
+#  define NID_netscape_cert_type          71
+#  define OBJ_netscape_cert_type          OBJ_netscape_cert_extension,1L
+
+#  define SN_netscape_base_url            "nsBaseUrl"
+#  define LN_netscape_base_url            "Netscape Base Url"
+#  define NID_netscape_base_url           72
+#  define OBJ_netscape_base_url           OBJ_netscape_cert_extension,2L
+
+#  define SN_netscape_revocation_url      "nsRevocationUrl"
+#  define LN_netscape_revocation_url      "Netscape Revocation Url"
+#  define NID_netscape_revocation_url     73
+#  define OBJ_netscape_revocation_url     OBJ_netscape_cert_extension,3L
+
+#  define SN_netscape_ca_revocation_url   "nsCaRevocationUrl"
+#  define LN_netscape_ca_revocation_url   "Netscape CA Revocation Url"
+#  define NID_netscape_ca_revocation_url  74
+#  define OBJ_netscape_ca_revocation_url  OBJ_netscape_cert_extension,4L
+
+#  define SN_netscape_renewal_url         "nsRenewalUrl"
+#  define LN_netscape_renewal_url         "Netscape Renewal Url"
+#  define NID_netscape_renewal_url        75
+#  define OBJ_netscape_renewal_url        OBJ_netscape_cert_extension,7L
+
+#  define SN_netscape_ca_policy_url       "nsCaPolicyUrl"
+#  define LN_netscape_ca_policy_url       "Netscape CA Policy Url"
+#  define NID_netscape_ca_policy_url      76
+#  define OBJ_netscape_ca_policy_url      OBJ_netscape_cert_extension,8L
+
+#  define SN_netscape_ssl_server_name     "nsSslServerName"
+#  define LN_netscape_ssl_server_name     "Netscape SSL Server Name"
+#  define NID_netscape_ssl_server_name    77
+#  define OBJ_netscape_ssl_server_name    OBJ_netscape_cert_extension,12L
+
+#  define SN_netscape_comment             "nsComment"
+#  define LN_netscape_comment             "Netscape Comment"
+#  define NID_netscape_comment            78
+#  define OBJ_netscape_comment            OBJ_netscape_cert_extension,13L
+
+#  define SN_netscape_cert_sequence       "nsCertSequence"
+#  define LN_netscape_cert_sequence       "Netscape Certificate Sequence"
+#  define NID_netscape_cert_sequence      79
+#  define OBJ_netscape_cert_sequence      OBJ_netscape_data_type,5L
+
+#  define SN_desx_cbc                     "DESX-CBC"
+#  define LN_desx_cbc                     "desx-cbc"
+#  define NID_desx_cbc                    80
+
+#  define SN_id_ce                        "id-ce"
+#  define NID_id_ce                       81
+#  define OBJ_id_ce                       2L,5L,29L
+
+#  define SN_subject_key_identifier       "subjectKeyIdentifier"
+#  define LN_subject_key_identifier       "X509v3 Subject Key Identifier"
+#  define NID_subject_key_identifier      82
+#  define OBJ_subject_key_identifier      OBJ_id_ce,14L
+
+#  define SN_key_usage                    "keyUsage"
+#  define LN_key_usage                    "X509v3 Key Usage"
+#  define NID_key_usage                   83
+#  define OBJ_key_usage                   OBJ_id_ce,15L
+
+#  define SN_private_key_usage_period     "privateKeyUsagePeriod"
+#  define LN_private_key_usage_period     "X509v3 Private Key Usage Period"
+#  define NID_private_key_usage_period    84
+#  define OBJ_private_key_usage_period    OBJ_id_ce,16L
+
+#  define SN_subject_alt_name             "subjectAltName"
+#  define LN_subject_alt_name             "X509v3 Subject Alternative Name"
+#  define NID_subject_alt_name            85
+#  define OBJ_subject_alt_name            OBJ_id_ce,17L
+
+#  define SN_issuer_alt_name              "issuerAltName"
+#  define LN_issuer_alt_name              "X509v3 Issuer Alternative Name"
+#  define NID_issuer_alt_name             86
+#  define OBJ_issuer_alt_name             OBJ_id_ce,18L
+
+#  define SN_basic_constraints            "basicConstraints"
+#  define LN_basic_constraints            "X509v3 Basic Constraints"
+#  define NID_basic_constraints           87
+#  define OBJ_basic_constraints           OBJ_id_ce,19L
+
+#  define SN_crl_number                   "crlNumber"
+#  define LN_crl_number                   "X509v3 CRL Number"
+#  define NID_crl_number                  88
+#  define OBJ_crl_number                  OBJ_id_ce,20L
+
+#  define SN_certificate_policies         "certificatePolicies"
+#  define LN_certificate_policies         "X509v3 Certificate Policies"
+#  define NID_certificate_policies        89
+#  define OBJ_certificate_policies        OBJ_id_ce,32L
+
+#  define SN_authority_key_identifier     "authorityKeyIdentifier"
+#  define LN_authority_key_identifier     "X509v3 Authority Key Identifier"
+#  define NID_authority_key_identifier    90
+#  define OBJ_authority_key_identifier    OBJ_id_ce,35L
+
+#  define SN_bf_cbc                       "BF-CBC"
+#  define LN_bf_cbc                       "bf-cbc"
+#  define NID_bf_cbc                      91
+#  define OBJ_bf_cbc                      1L,3L,6L,1L,4L,1L,3029L,1L,2L
+
+#  define SN_bf_ecb                       "BF-ECB"
+#  define LN_bf_ecb                       "bf-ecb"
+#  define NID_bf_ecb                      92
+
+#  define SN_bf_cfb64                     "BF-CFB"
+#  define LN_bf_cfb64                     "bf-cfb"
+#  define NID_bf_cfb64                    93
+
+#  define SN_bf_ofb64                     "BF-OFB"
+#  define LN_bf_ofb64                     "bf-ofb"
+#  define NID_bf_ofb64                    94
+
+#  define SN_mdc2                         "MDC2"
+#  define LN_mdc2                         "mdc2"
+#  define NID_mdc2                        95
+#  define OBJ_mdc2                        2L,5L,8L,3L,101L
+/* An alternative?                      1L,3L,14L,3L,2L,19L */
+
+#  define SN_mdc2WithRSA                  "RSA-MDC2"
+#  define LN_mdc2WithRSA                  "mdc2withRSA"
+#  define NID_mdc2WithRSA                 96
+#  define OBJ_mdc2WithRSA                 2L,5L,8L,3L,100L
+
+#  define SN_rc4_40                       "RC4-40"
+#  define LN_rc4_40                       "rc4-40"
+#  define NID_rc4_40                      97
+
+#  define SN_rc2_40_cbc                   "RC2-40-CBC"
+#  define LN_rc2_40_cbc                   "rc2-40-cbc"
+#  define NID_rc2_40_cbc                  98
+
+#  define SN_givenName                    "G"
+#  define LN_givenName                    "givenName"
+#  define NID_givenName                   99
+#  define OBJ_givenName                   OBJ_X509,42L
+
+#  define SN_surname                      "S"
+#  define LN_surname                      "surname"
+#  define NID_surname                     100
+#  define OBJ_surname                     OBJ_X509,4L
+
+#  define SN_initials                     "I"
+#  define LN_initials                     "initials"
+#  define NID_initials                    101
+#  define OBJ_initials                    OBJ_X509,43L
+
+#  define SN_uniqueIdentifier             "UID"
+#  define LN_uniqueIdentifier             "uniqueIdentifier"
+#  define NID_uniqueIdentifier            102
+#  define OBJ_uniqueIdentifier            OBJ_X509,45L
+
+#  define SN_crl_distribution_points      "crlDistributionPoints"
+#  define LN_crl_distribution_points      "X509v3 CRL Distribution Points"
+#  define NID_crl_distribution_points     103
+#  define OBJ_crl_distribution_points     OBJ_id_ce,31L
+
+#  define SN_md5WithRSA                   "RSA-NP-MD5"
+#  define LN_md5WithRSA                   "md5WithRSA"
+#  define NID_md5WithRSA                  104
+#  define OBJ_md5WithRSA                  OBJ_algorithm,3L
+
+#  define SN_serialNumber                 "SN"
+#  define LN_serialNumber                 "serialNumber"
+#  define NID_serialNumber                105
+#  define OBJ_serialNumber                OBJ_X509,5L
+
+#  define SN_title                        "T"
+#  define LN_title                        "title"
+#  define NID_title                       106
+#  define OBJ_title                       OBJ_X509,12L
+
+#  define SN_description                  "D"
+#  define LN_description                  "description"
+#  define NID_description                 107
+#  define OBJ_description                 OBJ_X509,13L
+
+/* CAST5 is CAST-128, I'm just sticking with the documentation */
+#  define SN_cast5_cbc                    "CAST5-CBC"
+#  define LN_cast5_cbc                    "cast5-cbc"
+#  define NID_cast5_cbc                   108
+#  define OBJ_cast5_cbc                   1L,2L,840L,113533L,7L,66L,10L
+
+#  define SN_cast5_ecb                    "CAST5-ECB"
+#  define LN_cast5_ecb                    "cast5-ecb"
+#  define NID_cast5_ecb                   109
+
+#  define SN_cast5_cfb64                  "CAST5-CFB"
+#  define LN_cast5_cfb64                  "cast5-cfb"
+#  define NID_cast5_cfb64                 110
+
+#  define SN_cast5_ofb64                  "CAST5-OFB"
+#  define LN_cast5_ofb64                  "cast5-ofb"
+#  define NID_cast5_ofb64                 111
+
+#  define LN_pbeWithMD5AndCast5_CBC       "pbeWithMD5AndCast5CBC"
+#  define NID_pbeWithMD5AndCast5_CBC      112
+#  define OBJ_pbeWithMD5AndCast5_CBC      1L,2L,840L,113533L,7L,66L,12L
+
+/*-
+ * This is one sun will soon be using :-(
+ * id-dsa-with-sha1 ID  ::= {
+ *   iso(1) member-body(2) us(840) x9-57 (10040) x9cm(4) 3 }
+ */
+#  define SN_dsaWithSHA1                  "DSA-SHA1"
+#  define LN_dsaWithSHA1                  "dsaWithSHA1"
+#  define NID_dsaWithSHA1                 113
+#  define OBJ_dsaWithSHA1                 1L,2L,840L,10040L,4L,3L
+
+#  define NID_md5_sha1                    114
+#  define SN_md5_sha1                     "MD5-SHA1"
+#  define LN_md5_sha1                     "md5-sha1"
+
+#  define SN_sha1WithRSA                  "RSA-SHA1-2"
+#  define LN_sha1WithRSA                  "sha1WithRSA"
+#  define NID_sha1WithRSA                 115
+#  define OBJ_sha1WithRSA                 OBJ_algorithm,29L
+
+#  define SN_dsa                          "DSA"
+#  define LN_dsa                          "dsaEncryption"
+#  define NID_dsa                         116
+#  define OBJ_dsa                         1L,2L,840L,10040L,4L,1L
+
+#  define SN_ripemd160                    "RIPEMD160"
+#  define LN_ripemd160                    "ripemd160"
+#  define NID_ripemd160                   117
+#  define OBJ_ripemd160                   1L,3L,36L,3L,2L,1L
+
+/*
+ * The name should actually be rsaSignatureWithripemd160, but I'm going to
+ * continue using the convention I'm using with the other ciphers
+ */
+#  define SN_ripemd160WithRSA             "RSA-RIPEMD160"
+#  define LN_ripemd160WithRSA             "ripemd160WithRSA"
+#  define NID_ripemd160WithRSA            119
+#  define OBJ_ripemd160WithRSA            1L,3L,36L,3L,3L,1L,2L
+
+/*-
+ * Taken from rfc2040
+ *  RC5_CBC_Parameters ::= SEQUENCE {
+ *      version           INTEGER (v1_0(16)),
+ *      rounds            INTEGER (8..127),
+ *      blockSizeInBits   INTEGER (64, 128),
+ *      iv                OCTET STRING OPTIONAL
+ *      }
+ */
+#  define SN_rc5_cbc                      "RC5-CBC"
+#  define LN_rc5_cbc                      "rc5-cbc"
+#  define NID_rc5_cbc                     120
+#  define OBJ_rc5_cbc                     OBJ_rsadsi,3L,8L
+
+#  define SN_rc5_ecb                      "RC5-ECB"
+#  define LN_rc5_ecb                      "rc5-ecb"
+#  define NID_rc5_ecb                     121
+
+#  define SN_rc5_cfb64                    "RC5-CFB"
+#  define LN_rc5_cfb64                    "rc5-cfb"
+#  define NID_rc5_cfb64                   122
+
+#  define SN_rc5_ofb64                    "RC5-OFB"
+#  define LN_rc5_ofb64                    "rc5-ofb"
+#  define NID_rc5_ofb64                   123
+
+#  define SN_rle_compression              "RLE"
+#  define LN_rle_compression              "run length compression"
+#  define NID_rle_compression             124
+#  define OBJ_rle_compression             1L,1L,1L,1L,666L,1L
+
+#  define SN_zlib_compression             "ZLIB"
+#  define LN_zlib_compression             "zlib compression"
+#  define NID_zlib_compression            125
+#  define OBJ_zlib_compression            1L,1L,1L,1L,666L,2L
+
+#  define SN_ext_key_usage                "extendedKeyUsage"
+#  define LN_ext_key_usage                "X509v3 Extended Key Usage"
+#  define NID_ext_key_usage               126
+#  define OBJ_ext_key_usage               OBJ_id_ce,37
+
+#  define SN_id_pkix                      "PKIX"
+#  define NID_id_pkix                     127
+#  define OBJ_id_pkix                     1L,3L,6L,1L,5L,5L,7L
+
+#  define SN_id_kp                        "id-kp"
+#  define NID_id_kp                       128
+#  define OBJ_id_kp                       OBJ_id_pkix,3L
+
+/* PKIX extended key usage OIDs */
+
+#  define SN_server_auth                  "serverAuth"
+#  define LN_server_auth                  "TLS Web Server Authentication"
+#  define NID_server_auth                 129
+#  define OBJ_server_auth                 OBJ_id_kp,1L
+
+#  define SN_client_auth                  "clientAuth"
+#  define LN_client_auth                  "TLS Web Client Authentication"
+#  define NID_client_auth                 130
+#  define OBJ_client_auth                 OBJ_id_kp,2L
+
+#  define SN_code_sign                    "codeSigning"
+#  define LN_code_sign                    "Code Signing"
+#  define NID_code_sign                   131
+#  define OBJ_code_sign                   OBJ_id_kp,3L
+
+#  define SN_email_protect                "emailProtection"
+#  define LN_email_protect                "E-mail Protection"
+#  define NID_email_protect               132
+#  define OBJ_email_protect               OBJ_id_kp,4L
+
+#  define SN_time_stamp                   "timeStamping"
+#  define LN_time_stamp                   "Time Stamping"
+#  define NID_time_stamp                  133
+#  define OBJ_time_stamp                  OBJ_id_kp,8L
+
+/* Additional extended key usage OIDs: Microsoft */
+
+#  define SN_ms_code_ind                  "msCodeInd"
+#  define LN_ms_code_ind                  "Microsoft Individual Code Signing"
+#  define NID_ms_code_ind                 134
+#  define OBJ_ms_code_ind                 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
+
+#  define SN_ms_code_com                  "msCodeCom"
+#  define LN_ms_code_com                  "Microsoft Commercial Code Signing"
+#  define NID_ms_code_com                 135
+#  define OBJ_ms_code_com                 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
+
+#  define SN_ms_ctl_sign                  "msCTLSign"
+#  define LN_ms_ctl_sign                  "Microsoft Trust List Signing"
+#  define NID_ms_ctl_sign                 136
+#  define OBJ_ms_ctl_sign                 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
+
+#  define SN_ms_sgc                       "msSGC"
+#  define LN_ms_sgc                       "Microsoft Server Gated Crypto"
+#  define NID_ms_sgc                      137
+#  define OBJ_ms_sgc                      1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
+
+#  define SN_ms_efs                       "msEFS"
+#  define LN_ms_efs                       "Microsoft Encrypted File System"
+#  define NID_ms_efs                      138
+#  define OBJ_ms_efs                      1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
+
+/* Additional usage: Netscape */
+
+#  define SN_ns_sgc                       "nsSGC"
+#  define LN_ns_sgc                       "Netscape Server Gated Crypto"
+#  define NID_ns_sgc                      139
+#  define OBJ_ns_sgc                      OBJ_netscape,4L,1L
+
+#  define SN_delta_crl                    "deltaCRL"
+#  define LN_delta_crl                    "X509v3 Delta CRL Indicator"
+#  define NID_delta_crl                   140
+#  define OBJ_delta_crl                   OBJ_id_ce,27L
+
+#  define SN_crl_reason                   "CRLReason"
+#  define LN_crl_reason                   "CRL Reason Code"
+#  define NID_crl_reason                  141
+#  define OBJ_crl_reason                  OBJ_id_ce,21L
+
+#  define SN_invalidity_date              "invalidityDate"
+#  define LN_invalidity_date              "Invalidity Date"
+#  define NID_invalidity_date             142
+#  define OBJ_invalidity_date             OBJ_id_ce,24L
+
+#  define SN_sxnet                        "SXNetID"
+#  define LN_sxnet                        "Strong Extranet ID"
+#  define NID_sxnet                       143
+#  define OBJ_sxnet                       1L,3L,101L,1L,4L,1L
+
+/* PKCS12 and related OBJECT IDENTIFIERS */
+
+#  define OBJ_pkcs12                      OBJ_pkcs,12L
+#  define OBJ_pkcs12_pbeids               OBJ_pkcs12, 1
+
+#  define SN_pbe_WithSHA1And128BitRC4     "PBE-SHA1-RC4-128"
+#  define LN_pbe_WithSHA1And128BitRC4     "pbeWithSHA1And128BitRC4"
+#  define NID_pbe_WithSHA1And128BitRC4    144
+#  define OBJ_pbe_WithSHA1And128BitRC4    OBJ_pkcs12_pbeids, 1L
+
+#  define SN_pbe_WithSHA1And40BitRC4      "PBE-SHA1-RC4-40"
+#  define LN_pbe_WithSHA1And40BitRC4      "pbeWithSHA1And40BitRC4"
+#  define NID_pbe_WithSHA1And40BitRC4     145
+#  define OBJ_pbe_WithSHA1And40BitRC4     OBJ_pkcs12_pbeids, 2L
+
+#  define SN_pbe_WithSHA1And3_Key_TripleDES_CBC   "PBE-SHA1-3DES"
+#  define LN_pbe_WithSHA1And3_Key_TripleDES_CBC   "pbeWithSHA1And3-KeyTripleDES-CBC"
+#  define NID_pbe_WithSHA1And3_Key_TripleDES_CBC  146
+#  define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC  OBJ_pkcs12_pbeids, 3L
+
+#  define SN_pbe_WithSHA1And2_Key_TripleDES_CBC   "PBE-SHA1-2DES"
+#  define LN_pbe_WithSHA1And2_Key_TripleDES_CBC   "pbeWithSHA1And2-KeyTripleDES-CBC"
+#  define NID_pbe_WithSHA1And2_Key_TripleDES_CBC  147
+#  define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC  OBJ_pkcs12_pbeids, 4L
+
+#  define SN_pbe_WithSHA1And128BitRC2_CBC         "PBE-SHA1-RC2-128"
+#  define LN_pbe_WithSHA1And128BitRC2_CBC         "pbeWithSHA1And128BitRC2-CBC"
+#  define NID_pbe_WithSHA1And128BitRC2_CBC        148
+#  define OBJ_pbe_WithSHA1And128BitRC2_CBC        OBJ_pkcs12_pbeids, 5L
+
+#  define SN_pbe_WithSHA1And40BitRC2_CBC  "PBE-SHA1-RC2-40"
+#  define LN_pbe_WithSHA1And40BitRC2_CBC  "pbeWithSHA1And40BitRC2-CBC"
+#  define NID_pbe_WithSHA1And40BitRC2_CBC 149
+#  define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids, 6L
+
+#  define OBJ_pkcs12_Version1     OBJ_pkcs12, 10L
+
+#  define OBJ_pkcs12_BagIds       OBJ_pkcs12_Version1, 1L
+
+#  define LN_keyBag               "keyBag"
+#  define NID_keyBag              150
+#  define OBJ_keyBag              OBJ_pkcs12_BagIds, 1L
+
+#  define LN_pkcs8ShroudedKeyBag  "pkcs8ShroudedKeyBag"
+#  define NID_pkcs8ShroudedKeyBag 151
+#  define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds, 2L
+
+#  define LN_certBag              "certBag"
+#  define NID_certBag             152
+#  define OBJ_certBag             OBJ_pkcs12_BagIds, 3L
+
+#  define LN_crlBag               "crlBag"
+#  define NID_crlBag              153
+#  define OBJ_crlBag              OBJ_pkcs12_BagIds, 4L
+
+#  define LN_secretBag            "secretBag"
+#  define NID_secretBag           154
+#  define OBJ_secretBag           OBJ_pkcs12_BagIds, 5L
+
+#  define LN_safeContentsBag      "safeContentsBag"
+#  define NID_safeContentsBag     155
+#  define OBJ_safeContentsBag     OBJ_pkcs12_BagIds, 6L
+
+#  define LN_friendlyName         "friendlyName"
+#  define NID_friendlyName        156
+#  define OBJ_friendlyName        OBJ_pkcs9, 20L
+
+#  define LN_localKeyID           "localKeyID"
+#  define NID_localKeyID          157
+#  define OBJ_localKeyID          OBJ_pkcs9, 21L
+
+#  define OBJ_certTypes           OBJ_pkcs9, 22L
+
+#  define LN_x509Certificate      "x509Certificate"
+#  define NID_x509Certificate     158
+#  define OBJ_x509Certificate     OBJ_certTypes, 1L
+
+#  define LN_sdsiCertificate      "sdsiCertificate"
+#  define NID_sdsiCertificate     159
+#  define OBJ_sdsiCertificate     OBJ_certTypes, 2L
+
+#  define OBJ_crlTypes            OBJ_pkcs9, 23L
+
+#  define LN_x509Crl              "x509Crl"
+#  define NID_x509Crl             160
+#  define OBJ_x509Crl             OBJ_crlTypes, 1L
+
+/* PKCS#5 v2 OIDs */
+
+#  define LN_pbes2                "PBES2"
+#  define NID_pbes2               161
+#  define OBJ_pbes2               OBJ_pkcs,5L,13L
+
+#  define LN_pbmac1               "PBMAC1"
+#  define NID_pbmac1              162
+#  define OBJ_pbmac1              OBJ_pkcs,5L,14L
+
+#  define LN_hmacWithSHA1         "hmacWithSHA1"
+#  define NID_hmacWithSHA1        163
+#  define OBJ_hmacWithSHA1        OBJ_rsadsi,2L,7L
+
+/* Policy Qualifier Ids */
+
+#  define LN_id_qt_cps            "Policy Qualifier CPS"
+#  define SN_id_qt_cps            "id-qt-cps"
+#  define NID_id_qt_cps           164
+#  define OBJ_id_qt_cps           OBJ_id_pkix,2L,1L
+
+#  define LN_id_qt_unotice        "Policy Qualifier User Notice"
+#  define SN_id_qt_unotice        "id-qt-unotice"
+#  define NID_id_qt_unotice       165
+#  define OBJ_id_qt_unotice       OBJ_id_pkix,2L,2L
+
+#  define SN_rc2_64_cbc                   "RC2-64-CBC"
+#  define LN_rc2_64_cbc                   "rc2-64-cbc"
+#  define NID_rc2_64_cbc                  166
+
+#  define SN_SMIMECapabilities            "SMIME-CAPS"
+#  define LN_SMIMECapabilities            "S/MIME Capabilities"
+#  define NID_SMIMECapabilities           167
+#  define OBJ_SMIMECapabilities           OBJ_pkcs9,15L
+
+#  define SN_pbeWithMD2AndRC2_CBC         "PBE-MD2-RC2-64"
+#  define LN_pbeWithMD2AndRC2_CBC         "pbeWithMD2AndRC2-CBC"
+#  define NID_pbeWithMD2AndRC2_CBC        168
+#  define OBJ_pbeWithMD2AndRC2_CBC        OBJ_pkcs,5L,4L
+
+#  define SN_pbeWithMD5AndRC2_CBC         "PBE-MD5-RC2-64"
+#  define LN_pbeWithMD5AndRC2_CBC         "pbeWithMD5AndRC2-CBC"
+#  define NID_pbeWithMD5AndRC2_CBC        169
+#  define OBJ_pbeWithMD5AndRC2_CBC        OBJ_pkcs,5L,6L
+
+#  define SN_pbeWithSHA1AndDES_CBC        "PBE-SHA1-DES"
+#  define LN_pbeWithSHA1AndDES_CBC        "pbeWithSHA1AndDES-CBC"
+#  define NID_pbeWithSHA1AndDES_CBC       170
+#  define OBJ_pbeWithSHA1AndDES_CBC       OBJ_pkcs,5L,10L
+
+/* Extension request OIDs */
+
+#  define LN_ms_ext_req                   "Microsoft Extension Request"
+#  define SN_ms_ext_req                   "msExtReq"
+#  define NID_ms_ext_req                  171
+#  define OBJ_ms_ext_req                  1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
+
+#  define LN_ext_req                      "Extension Request"
+#  define SN_ext_req                      "extReq"
+#  define NID_ext_req                     172
+#  define OBJ_ext_req                     OBJ_pkcs9,14L
+
+#  define SN_name                         "name"
+#  define LN_name                         "name"
+#  define NID_name                        173
+#  define OBJ_name                        OBJ_X509,41L
+
+#  define SN_dnQualifier                  "dnQualifier"
+#  define LN_dnQualifier                  "dnQualifier"
+#  define NID_dnQualifier                 174
+#  define OBJ_dnQualifier                 OBJ_X509,46L
+
+#  define SN_id_pe                        "id-pe"
+#  define NID_id_pe                       175
+#  define OBJ_id_pe                       OBJ_id_pkix,1L
+
+#  define SN_id_ad                        "id-ad"
+#  define NID_id_ad                       176
+#  define OBJ_id_ad                       OBJ_id_pkix,48L
+
+#  define SN_info_access                  "authorityInfoAccess"
+#  define LN_info_access                  "Authority Information Access"
+#  define NID_info_access                 177
+#  define OBJ_info_access                 OBJ_id_pe,1L
+
+#  define SN_ad_OCSP                      "OCSP"
+#  define LN_ad_OCSP                      "OCSP"
+#  define NID_ad_OCSP                     178
+#  define OBJ_ad_OCSP                     OBJ_id_ad,1L
+
+#  define SN_ad_ca_issuers                "caIssuers"
+#  define LN_ad_ca_issuers                "CA Issuers"
+#  define NID_ad_ca_issuers               179
+#  define OBJ_ad_ca_issuers               OBJ_id_ad,2L
+
+#  define SN_OCSP_sign                    "OCSPSigning"
+#  define LN_OCSP_sign                    "OCSP Signing"
+#  define NID_OCSP_sign                   180
+#  define OBJ_OCSP_sign                   OBJ_id_kp,9L
+# endif                         /* USE_OBJ_MAC */
+
+# include <openssl/bio.h>
+# include <openssl/asn1.h>
+
+# define OBJ_NAME_TYPE_UNDEF             0x00
+# define OBJ_NAME_TYPE_MD_METH           0x01
+# define OBJ_NAME_TYPE_CIPHER_METH       0x02
+# define OBJ_NAME_TYPE_PKEY_METH         0x03
+# define OBJ_NAME_TYPE_COMP_METH         0x04
+# define OBJ_NAME_TYPE_NUM               0x05
+
+# define OBJ_NAME_ALIAS                  0x8000
+
+# define OBJ_BSEARCH_VALUE_ON_NOMATCH            0x01
+# define OBJ_BSEARCH_FIRST_VALUE_ON_MATCH        0x02
+
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct obj_name_st {
+    int type;
+    int alias;
+    const char *name;
+    const char *data;
+} OBJ_NAME;
+
+# define         OBJ_create_and_add_object(a,b,c) OBJ_create(a,b,c)
+
+int OBJ_NAME_init(void);
+int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *),
+                       int (*cmp_func) (const char *, const char *),
+                       void (*free_func) (const char *, int, const char *));
+const char *OBJ_NAME_get(const char *name, int type);
+int OBJ_NAME_add(const char *name, int type, const char *data);
+int OBJ_NAME_remove(const char *name, int type);
+void OBJ_NAME_cleanup(int type); /* -1 for everything */
+void OBJ_NAME_do_all(int type, void (*fn) (const OBJ_NAME *, void *arg),
+                     void *arg);
+void OBJ_NAME_do_all_sorted(int type,
+                            void (*fn) (const OBJ_NAME *, void *arg),
+                            void *arg);
+
+ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o);
+ASN1_OBJECT *OBJ_nid2obj(int n);
+const char *OBJ_nid2ln(int n);
+const char *OBJ_nid2sn(int n);
+int OBJ_obj2nid(const ASN1_OBJECT *o);
+ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name);
+int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name);
+int OBJ_txt2nid(const char *s);
+int OBJ_ln2nid(const char *s);
+int OBJ_sn2nid(const char *s);
+int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b);
+const void *OBJ_bsearch_(const void *key, const void *base, int num, int size,
+                         int (*cmp) (const void *, const void *));
+const void *OBJ_bsearch_ex_(const void *key, const void *base, int num,
+                            int size,
+                            int (*cmp) (const void *, const void *),
+                            int flags);
+
+# define _DECLARE_OBJ_BSEARCH_CMP_FN(scope, type1, type2, nm)    \
+  static int nm##_cmp_BSEARCH_CMP_FN(const void *, const void *); \
+  static int nm##_cmp(type1 const *, type2 const *); \
+  scope type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num)
+
+# define DECLARE_OBJ_BSEARCH_CMP_FN(type1, type2, cmp)   \
+  _DECLARE_OBJ_BSEARCH_CMP_FN(static, type1, type2, cmp)
+# define DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm)     \
+  type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num)
+
+/*-
+ * Unsolved problem: if a type is actually a pointer type, like
+ * nid_triple is, then its impossible to get a const where you need
+ * it. Consider:
+ *
+ * typedef int nid_triple[3];
+ * const void *a_;
+ * const nid_triple const *a = a_;
+ *
+ * The assignement discards a const because what you really want is:
+ *
+ * const int const * const *a = a_;
+ *
+ * But if you do that, you lose the fact that a is an array of 3 ints,
+ * which breaks comparison functions.
+ *
+ * Thus we end up having to cast, sadly, or unpack the
+ * declarations. Or, as I finally did in this case, delcare nid_triple
+ * to be a struct, which it should have been in the first place.
+ *
+ * Ben, August 2008.
+ *
+ * Also, strictly speaking not all types need be const, but handling
+ * the non-constness means a lot of complication, and in practice
+ * comparison routines do always not touch their arguments.
+ */
+
+# define IMPLEMENT_OBJ_BSEARCH_CMP_FN(type1, type2, nm)  \
+  static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)    \
+      { \
+      type1 const *a = a_; \
+      type2 const *b = b_; \
+      return nm##_cmp(a,b); \
+      } \
+  static type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \
+      { \
+      return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \
+                                        nm##_cmp_BSEARCH_CMP_FN); \
+      } \
+      extern void dummy_prototype(void)
+
+# define IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm)   \
+  static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)    \
+      { \
+      type1 const *a = a_; \
+      type2 const *b = b_; \
+      return nm##_cmp(a,b); \
+      } \
+  type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \
+      { \
+      return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \
+                                        nm##_cmp_BSEARCH_CMP_FN); \
+      } \
+      extern void dummy_prototype(void)
+
+# define OBJ_bsearch(type1,key,type2,base,num,cmp)                              \
+  ((type2 *)OBJ_bsearch_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \
+                         num,sizeof(type2),                             \
+                         ((void)CHECKED_PTR_OF(type1,cmp##_type_1),     \
+                          (void)CHECKED_PTR_OF(type2,cmp##_type_2),     \
+                          cmp##_BSEARCH_CMP_FN)))
+
+# define OBJ_bsearch_ex(type1,key,type2,base,num,cmp,flags)                      \
+  ((type2 *)OBJ_bsearch_ex_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \
+                         num,sizeof(type2),                             \
+                         ((void)CHECKED_PTR_OF(type1,cmp##_type_1),     \
+                          (void)type_2=CHECKED_PTR_OF(type2,cmp##_type_2), \
+                          cmp##_BSEARCH_CMP_FN)),flags)
+
+int OBJ_new_nid(int num);
+int OBJ_add_object(const ASN1_OBJECT *obj);
+int OBJ_create(const char *oid, const char *sn, const char *ln);
+#if OPENSSL_API_COMPAT < 0x10100000L
+# define OBJ_cleanup() while(0) continue
+#endif
+int OBJ_create_objects(BIO *in);
+
+size_t OBJ_length(const ASN1_OBJECT *obj);
+const unsigned char *OBJ_get0_data(const ASN1_OBJECT *obj);
+
+int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid);
+int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid);
+int OBJ_add_sigid(int signid, int dig_id, int pkey_id);
+void OBJ_sigid_free(void);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_OBJ_strings(void);
+
+/* Error codes for the OBJ functions. */
+
+/* Function codes. */
+# define OBJ_F_OBJ_ADD_OBJECT                             105
+# define OBJ_F_OBJ_CREATE                                 100
+# define OBJ_F_OBJ_DUP                                    101
+# define OBJ_F_OBJ_NAME_NEW_INDEX                         106
+# define OBJ_F_OBJ_NID2LN                                 102
+# define OBJ_F_OBJ_NID2OBJ                                103
+# define OBJ_F_OBJ_NID2SN                                 104
+
+/* Reason codes. */
+# define OBJ_R_OID_EXISTS                                 102
+# define OBJ_R_UNKNOWN_NID                                101
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ocsp.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ocsp.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ocsp.h	(revision 331)
@@ -0,0 +1,412 @@
+/*
+ * Copyright 2000-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
+ */
+
+#ifndef HEADER_OCSP_H
+# define HEADER_OCSP_H
+
+#include <openssl/opensslconf.h>
+
+/*
+ * These definitions are outside the OPENSSL_NO_OCSP guard because although for
+ * historical reasons they have OCSP_* names, they can actually be used
+ * independently of OCSP. E.g. see RFC5280
+ */
+/*-
+ *   CRLReason ::= ENUMERATED {
+ *        unspecified             (0),
+ *        keyCompromise           (1),
+ *        cACompromise            (2),
+ *        affiliationChanged      (3),
+ *        superseded              (4),
+ *        cessationOfOperation    (5),
+ *        certificateHold         (6),
+ *        removeFromCRL           (8) }
+ */
+#  define OCSP_REVOKED_STATUS_NOSTATUS               -1
+#  define OCSP_REVOKED_STATUS_UNSPECIFIED             0
+#  define OCSP_REVOKED_STATUS_KEYCOMPROMISE           1
+#  define OCSP_REVOKED_STATUS_CACOMPROMISE            2
+#  define OCSP_REVOKED_STATUS_AFFILIATIONCHANGED      3
+#  define OCSP_REVOKED_STATUS_SUPERSEDED              4
+#  define OCSP_REVOKED_STATUS_CESSATIONOFOPERATION    5
+#  define OCSP_REVOKED_STATUS_CERTIFICATEHOLD         6
+#  define OCSP_REVOKED_STATUS_REMOVEFROMCRL           8
+
+
+# ifndef OPENSSL_NO_OCSP
+
+#  include <openssl/ossl_typ.h>
+#  include <openssl/x509.h>
+#  include <openssl/x509v3.h>
+#  include <openssl/safestack.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Various flags and values */
+
+#  define OCSP_DEFAULT_NONCE_LENGTH       16
+
+#  define OCSP_NOCERTS                    0x1
+#  define OCSP_NOINTERN                   0x2
+#  define OCSP_NOSIGS                     0x4
+#  define OCSP_NOCHAIN                    0x8
+#  define OCSP_NOVERIFY                   0x10
+#  define OCSP_NOEXPLICIT                 0x20
+#  define OCSP_NOCASIGN                   0x40
+#  define OCSP_NODELEGATED                0x80
+#  define OCSP_NOCHECKS                   0x100
+#  define OCSP_TRUSTOTHER                 0x200
+#  define OCSP_RESPID_KEY                 0x400
+#  define OCSP_NOTIME                     0x800
+
+typedef struct ocsp_cert_id_st OCSP_CERTID;
+
+DEFINE_STACK_OF(OCSP_CERTID)
+
+typedef struct ocsp_one_request_st OCSP_ONEREQ;
+
+DEFINE_STACK_OF(OCSP_ONEREQ)
+
+typedef struct ocsp_req_info_st OCSP_REQINFO;
+typedef struct ocsp_signature_st OCSP_SIGNATURE;
+typedef struct ocsp_request_st OCSP_REQUEST;
+
+#  define OCSP_RESPONSE_STATUS_SUCCESSFUL           0
+#  define OCSP_RESPONSE_STATUS_MALFORMEDREQUEST     1
+#  define OCSP_RESPONSE_STATUS_INTERNALERROR        2
+#  define OCSP_RESPONSE_STATUS_TRYLATER             3
+#  define OCSP_RESPONSE_STATUS_SIGREQUIRED          5
+#  define OCSP_RESPONSE_STATUS_UNAUTHORIZED         6
+
+typedef struct ocsp_resp_bytes_st OCSP_RESPBYTES;
+
+#  define V_OCSP_RESPID_NAME 0
+#  define V_OCSP_RESPID_KEY  1
+
+DEFINE_STACK_OF(OCSP_RESPID)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPID)
+
+typedef struct ocsp_revoked_info_st OCSP_REVOKEDINFO;
+
+#  define V_OCSP_CERTSTATUS_GOOD    0
+#  define V_OCSP_CERTSTATUS_REVOKED 1
+#  define V_OCSP_CERTSTATUS_UNKNOWN 2
+
+typedef struct ocsp_cert_status_st OCSP_CERTSTATUS;
+typedef struct ocsp_single_response_st OCSP_SINGLERESP;
+
+DEFINE_STACK_OF(OCSP_SINGLERESP)
+
+typedef struct ocsp_response_data_st OCSP_RESPDATA;
+
+typedef struct ocsp_basic_response_st OCSP_BASICRESP;
+
+typedef struct ocsp_crl_id_st OCSP_CRLID;
+typedef struct ocsp_service_locator_st OCSP_SERVICELOC;
+
+#  define PEM_STRING_OCSP_REQUEST "OCSP REQUEST"
+#  define PEM_STRING_OCSP_RESPONSE "OCSP RESPONSE"
+
+#  define d2i_OCSP_REQUEST_bio(bp,p) ASN1_d2i_bio_of(OCSP_REQUEST,OCSP_REQUEST_new,d2i_OCSP_REQUEST,bp,p)
+
+#  define d2i_OCSP_RESPONSE_bio(bp,p) ASN1_d2i_bio_of(OCSP_RESPONSE,OCSP_RESPONSE_new,d2i_OCSP_RESPONSE,bp,p)
+
+#  define PEM_read_bio_OCSP_REQUEST(bp,x,cb) (OCSP_REQUEST *)PEM_ASN1_read_bio( \
+     (char *(*)())d2i_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,bp,(char **)x,cb,NULL)
+
+#   define PEM_read_bio_OCSP_RESPONSE(bp,x,cb)(OCSP_RESPONSE *)PEM_ASN1_read_bio(\
+     (char *(*)())d2i_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,bp,(char **)x,cb,NULL)
+
+#  define PEM_write_bio_OCSP_REQUEST(bp,o) \
+    PEM_ASN1_write_bio((int (*)())i2d_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,\
+                        bp,(char *)o, NULL,NULL,0,NULL,NULL)
+
+#  define PEM_write_bio_OCSP_RESPONSE(bp,o) \
+    PEM_ASN1_write_bio((int (*)())i2d_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,\
+                        bp,(char *)o, NULL,NULL,0,NULL,NULL)
+
+#  define i2d_OCSP_RESPONSE_bio(bp,o) ASN1_i2d_bio_of(OCSP_RESPONSE,i2d_OCSP_RESPONSE,bp,o)
+
+#  define i2d_OCSP_REQUEST_bio(bp,o) ASN1_i2d_bio_of(OCSP_REQUEST,i2d_OCSP_REQUEST,bp,o)
+
+#  define OCSP_REQUEST_sign(o,pkey,md) \
+        ASN1_item_sign(ASN1_ITEM_rptr(OCSP_REQINFO),\
+                &o->optionalSignature->signatureAlgorithm,NULL,\
+                o->optionalSignature->signature,&o->tbsRequest,pkey,md)
+
+#  define OCSP_BASICRESP_sign(o,pkey,md,d) \
+        ASN1_item_sign(ASN1_ITEM_rptr(OCSP_RESPDATA),&o->signatureAlgorithm,NULL,\
+                o->signature,&o->tbsResponseData,pkey,md)
+
+#  define OCSP_REQUEST_verify(a,r) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_REQINFO),\
+        &a->optionalSignature->signatureAlgorithm,\
+        a->optionalSignature->signature,&a->tbsRequest,r)
+
+#  define OCSP_BASICRESP_verify(a,r,d) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_RESPDATA),\
+        &a->signatureAlgorithm,a->signature,&a->tbsResponseData,r)
+
+#  define ASN1_BIT_STRING_digest(data,type,md,len) \
+        ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len)
+
+#  define OCSP_CERTSTATUS_dup(cs)\
+                (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\
+                (char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs))
+
+OCSP_CERTID *OCSP_CERTID_dup(OCSP_CERTID *id);
+
+OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req);
+OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req,
+                               int maxline);
+int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx);
+int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx);
+OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *io, int maxline);
+void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx);
+void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len);
+int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it,
+                     ASN1_VALUE *val);
+int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx, ASN1_VALUE **pval,
+                          const ASN1_ITEM *it);
+BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx);
+int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it,
+                     ASN1_VALUE *val);
+int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, const char *op, const char *path);
+int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req);
+int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx,
+                             const char *name, const char *value);
+
+OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, const X509 *subject,
+                             const X509 *issuer);
+
+OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst,
+                              const X509_NAME *issuerName,
+                              const ASN1_BIT_STRING *issuerKey,
+                              const ASN1_INTEGER *serialNumber);
+
+OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid);
+
+int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len);
+int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len);
+int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs);
+int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req);
+
+int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm);
+int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert);
+
+int OCSP_request_sign(OCSP_REQUEST *req,
+                      X509 *signer,
+                      EVP_PKEY *key,
+                      const EVP_MD *dgst,
+                      STACK_OF(X509) *certs, unsigned long flags);
+
+int OCSP_response_status(OCSP_RESPONSE *resp);
+OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp);
+
+const ASN1_OCTET_STRING *OCSP_resp_get0_signature(const OCSP_BASICRESP *bs);
+
+int OCSP_resp_count(OCSP_BASICRESP *bs);
+OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx);
+const ASN1_GENERALIZEDTIME *OCSP_resp_get0_produced_at(const OCSP_BASICRESP* bs);
+const STACK_OF(X509) *OCSP_resp_get0_certs(const OCSP_BASICRESP *bs);
+int OCSP_resp_get0_id(const OCSP_BASICRESP *bs,
+                      const ASN1_OCTET_STRING **pid,
+                      const X509_NAME **pname);
+
+int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last);
+int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason,
+                            ASN1_GENERALIZEDTIME **revtime,
+                            ASN1_GENERALIZEDTIME **thisupd,
+                            ASN1_GENERALIZEDTIME **nextupd);
+int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status,
+                          int *reason,
+                          ASN1_GENERALIZEDTIME **revtime,
+                          ASN1_GENERALIZEDTIME **thisupd,
+                          ASN1_GENERALIZEDTIME **nextupd);
+int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd,
+                        ASN1_GENERALIZEDTIME *nextupd, long sec, long maxsec);
+
+int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs,
+                        X509_STORE *store, unsigned long flags);
+
+int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath,
+                   int *pssl);
+
+int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b);
+int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b);
+
+int OCSP_request_onereq_count(OCSP_REQUEST *req);
+OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i);
+OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one);
+int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd,
+                      ASN1_OCTET_STRING **pikeyHash,
+                      ASN1_INTEGER **pserial, OCSP_CERTID *cid);
+int OCSP_request_is_signed(OCSP_REQUEST *req);
+OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs);
+OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp,
+                                        OCSP_CERTID *cid,
+                                        int status, int reason,
+                                        ASN1_TIME *revtime,
+                                        ASN1_TIME *thisupd,
+                                        ASN1_TIME *nextupd);
+int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert);
+int OCSP_basic_sign(OCSP_BASICRESP *brsp,
+                    X509 *signer, EVP_PKEY *key, const EVP_MD *dgst,
+                    STACK_OF(X509) *certs, unsigned long flags);
+int OCSP_RESPID_set_by_name(OCSP_RESPID *respid, X509 *cert);
+int OCSP_RESPID_set_by_key(OCSP_RESPID *respid, X509 *cert);
+int OCSP_RESPID_match(OCSP_RESPID *respid, X509 *cert);
+
+X509_EXTENSION *OCSP_crlID_new(const char *url, long *n, char *tim);
+
+X509_EXTENSION *OCSP_accept_responses_new(char **oids);
+
+X509_EXTENSION *OCSP_archive_cutoff_new(char *tim);
+
+X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, const char **urls);
+
+int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x);
+int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos);
+int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, const ASN1_OBJECT *obj,
+                                int lastpos);
+int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos);
+X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc);
+X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc);
+void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit,
+                                int *idx);
+int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit,
+                              unsigned long flags);
+int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc);
+
+int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x);
+int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos);
+int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, const ASN1_OBJECT *obj, int lastpos);
+int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos);
+X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc);
+X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc);
+void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx);
+int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit,
+                             unsigned long flags);
+int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc);
+
+int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x);
+int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos);
+int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, const ASN1_OBJECT *obj,
+                                  int lastpos);
+int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit,
+                                       int lastpos);
+X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc);
+X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc);
+void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit,
+                                  int *idx);
+int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value,
+                                int crit, unsigned long flags);
+int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc);
+
+int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x);
+int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos);
+int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, const ASN1_OBJECT *obj,
+                                   int lastpos);
+int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit,
+                                        int lastpos);
+X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc);
+X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc);
+void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit,
+                                   int *idx);
+int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value,
+                                 int crit, unsigned long flags);
+int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc);
+const OCSP_CERTID *OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *x);
+
+DECLARE_ASN1_FUNCTIONS(OCSP_SINGLERESP)
+DECLARE_ASN1_FUNCTIONS(OCSP_CERTSTATUS)
+DECLARE_ASN1_FUNCTIONS(OCSP_REVOKEDINFO)
+DECLARE_ASN1_FUNCTIONS(OCSP_BASICRESP)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPDATA)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPID)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPONSE)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPBYTES)
+DECLARE_ASN1_FUNCTIONS(OCSP_ONEREQ)
+DECLARE_ASN1_FUNCTIONS(OCSP_CERTID)
+DECLARE_ASN1_FUNCTIONS(OCSP_REQUEST)
+DECLARE_ASN1_FUNCTIONS(OCSP_SIGNATURE)
+DECLARE_ASN1_FUNCTIONS(OCSP_REQINFO)
+DECLARE_ASN1_FUNCTIONS(OCSP_CRLID)
+DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC)
+
+const char *OCSP_response_status_str(long s);
+const char *OCSP_cert_status_str(long s);
+const char *OCSP_crl_reason_str(long s);
+
+int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *a, unsigned long flags);
+int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags);
+
+int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
+                      X509_STORE *st, unsigned long flags);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_OCSP_strings(void);
+
+/* Error codes for the OCSP functions. */
+
+/* Function codes. */
+# define OCSP_F_D2I_OCSP_NONCE                            102
+# define OCSP_F_OCSP_BASIC_ADD1_STATUS                    103
+# define OCSP_F_OCSP_BASIC_SIGN                           104
+# define OCSP_F_OCSP_BASIC_VERIFY                         105
+# define OCSP_F_OCSP_CERT_ID_NEW                          101
+# define OCSP_F_OCSP_CHECK_DELEGATED                      106
+# define OCSP_F_OCSP_CHECK_IDS                            107
+# define OCSP_F_OCSP_CHECK_ISSUER                         108
+# define OCSP_F_OCSP_CHECK_VALIDITY                       115
+# define OCSP_F_OCSP_MATCH_ISSUERID                       109
+# define OCSP_F_OCSP_PARSE_URL                            114
+# define OCSP_F_OCSP_REQUEST_SIGN                         110
+# define OCSP_F_OCSP_REQUEST_VERIFY                       116
+# define OCSP_F_OCSP_RESPONSE_GET1_BASIC                  111
+# define OCSP_F_PARSE_HTTP_LINE1                          118
+
+/* Reason codes. */
+# define OCSP_R_CERTIFICATE_VERIFY_ERROR                  101
+# define OCSP_R_DIGEST_ERR                                102
+# define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD                 122
+# define OCSP_R_ERROR_IN_THISUPDATE_FIELD                 123
+# define OCSP_R_ERROR_PARSING_URL                         121
+# define OCSP_R_MISSING_OCSPSIGNING_USAGE                 103
+# define OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE              124
+# define OCSP_R_NOT_BASIC_RESPONSE                        104
+# define OCSP_R_NO_CERTIFICATES_IN_CHAIN                  105
+# define OCSP_R_NO_RESPONSE_DATA                          108
+# define OCSP_R_NO_REVOKED_TIME                           109
+# define OCSP_R_NO_SIGNER_KEY                             130
+# define OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE    110
+# define OCSP_R_REQUEST_NOT_SIGNED                        128
+# define OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA      111
+# define OCSP_R_ROOT_CA_NOT_TRUSTED                       112
+# define OCSP_R_SERVER_RESPONSE_ERROR                     114
+# define OCSP_R_SERVER_RESPONSE_PARSE_ERROR               115
+# define OCSP_R_SIGNATURE_FAILURE                         117
+# define OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND              118
+# define OCSP_R_STATUS_EXPIRED                            125
+# define OCSP_R_STATUS_NOT_YET_VALID                      126
+# define OCSP_R_STATUS_TOO_OLD                            127
+# define OCSP_R_UNKNOWN_MESSAGE_DIGEST                    119
+# define OCSP_R_UNKNOWN_NID                               120
+# define OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE            129
+
+#  ifdef  __cplusplus
+}
+#  endif
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/opensslconf.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/opensslconf.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/opensslconf.h	(revision 331)
@@ -0,0 +1,169 @@
+/*
+ * WARNING: do not edit!
+ * Generated by Makefile from include/openssl/opensslconf.h.in
+ *
+ * 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
+ */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_ALGORITHM_DEFINES
+# error OPENSSL_ALGORITHM_DEFINES no longer supported
+#endif
+
+/*
+ * OpenSSL was configured with the following options:
+ */
+
+#ifndef OPENSSL_NO_MD2
+# define OPENSSL_NO_MD2
+#endif
+#ifndef OPENSSL_NO_RC5
+# define OPENSSL_NO_RC5
+#endif
+#ifndef OPENSSL_NO_UI
+# define OPENSSL_NO_UI
+#endif
+#ifndef OPENSSL_NO_ASAN
+# define OPENSSL_NO_ASAN
+#endif
+#ifndef OPENSSL_NO_ASM
+# define OPENSSL_NO_ASM
+#endif
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG
+# define OPENSSL_NO_CRYPTO_MDEBUG
+#endif
+#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
+# define OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
+#endif
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+# define OPENSSL_NO_EC_NISTP_64_GCC_128
+#endif
+#ifndef OPENSSL_NO_EGD
+# define OPENSSL_NO_EGD
+#endif
+#ifndef OPENSSL_NO_FUZZ_AFL
+# define OPENSSL_NO_FUZZ_AFL
+#endif
+#ifndef OPENSSL_NO_FUZZ_LIBFUZZER
+# define OPENSSL_NO_FUZZ_LIBFUZZER
+#endif
+#ifndef OPENSSL_NO_HEARTBEATS
+# define OPENSSL_NO_HEARTBEATS
+#endif
+#ifndef OPENSSL_NO_MSAN
+# define OPENSSL_NO_MSAN
+#endif
+#ifndef OPENSSL_NO_SCTP
+# define OPENSSL_NO_SCTP
+#endif
+#ifndef OPENSSL_NO_SSL_TRACE
+# define OPENSSL_NO_SSL_TRACE
+#endif
+#ifndef OPENSSL_NO_SSL3
+# define OPENSSL_NO_SSL3
+#endif
+#ifndef OPENSSL_NO_SSL3_METHOD
+# define OPENSSL_NO_SSL3_METHOD
+#endif
+#ifndef OPENSSL_NO_UBSAN
+# define OPENSSL_NO_UBSAN
+#endif
+#ifndef OPENSSL_NO_UNIT_TEST
+# define OPENSSL_NO_UNIT_TEST
+#endif
+#ifndef OPENSSL_NO_AFALGENG
+# define OPENSSL_NO_AFALGENG
+#endif
+
+
+/*
+ * Sometimes OPENSSSL_NO_xxx ends up with an empty file and some compilers
+ * don't like that.  This will hopefully silence them.
+ */
+#define NON_EMPTY_TRANSLATION_UNIT static void *dummy = &dummy;
+
+/*
+ * Applications should use -DOPENSSL_API_COMPAT=<version> to suppress the
+ * declarations of functions deprecated in or before <version>. Otherwise, they
+ * still won't see them if the library has been built to disable deprecated
+ * functions.
+ */
+#if defined(OPENSSL_NO_DEPRECATED)
+# define DECLARE_DEPRECATED(f)
+#elif __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 0)
+# define DECLARE_DEPRECATED(f)    f __attribute__ ((deprecated));
+#else
+# define DECLARE_DEPRECATED(f)   f;
+#endif
+
+#ifndef OPENSSL_FILE
+# ifdef OPENSSL_NO_FILENAMES
+#  define OPENSSL_FILE ""
+#  define OPENSSL_LINE 0
+# else
+#  define OPENSSL_FILE __FILE__
+#  define OPENSSL_LINE __LINE__
+# endif
+#endif
+
+#ifndef OPENSSL_MIN_API
+# define OPENSSL_MIN_API 0
+#endif
+
+#if !defined(OPENSSL_API_COMPAT) || OPENSSL_API_COMPAT < OPENSSL_MIN_API
+# undef OPENSSL_API_COMPAT
+# define OPENSSL_API_COMPAT OPENSSL_MIN_API
+#endif
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+# define DEPRECATEDIN_1_1_0(f)   DECLARE_DEPRECATED(f)
+#else
+# define DEPRECATEDIN_1_1_0(f)
+#endif
+
+#if OPENSSL_API_COMPAT < 0x10000000L
+# define DEPRECATEDIN_1_0_0(f)   DECLARE_DEPRECATED(f)
+#else
+# define DEPRECATEDIN_1_0_0(f)
+#endif
+
+#if OPENSSL_API_COMPAT < 0x00908000L
+# define DEPRECATEDIN_0_9_8(f)   DECLARE_DEPRECATED(f)
+#else
+# define DEPRECATEDIN_0_9_8(f)
+#endif
+
+
+
+/* Generate 80386 code? */
+#undef I386_ONLY
+
+#undef OPENSSL_UNISTD
+#define OPENSSL_UNISTD <unistd.h>
+
+#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+/*
+ * The following are cipher-specific, but are part of the public API.
+ */
+#if !defined(OPENSSL_SYS_UEFI)
+# define BN_LLONG
+/* Only one for the following should be defined */
+# undef SIXTY_FOUR_BIT_LONG
+# undef SIXTY_FOUR_BIT
+# define THIRTY_TWO_BIT
+#endif
+
+#define RC4_INT unsigned char
+
+#ifdef  __cplusplus
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/opensslv.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/opensslv.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/opensslv.h	(revision 331)
@@ -0,0 +1,105 @@
+/*
+ * Copyright 1999-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
+ */
+
+#ifndef HEADER_OPENSSLV_H
+# define HEADER_OPENSSLV_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*-
+ * Numeric release version identifier:
+ * MNNFFPPS: major minor fix patch status
+ * The status nibble has one of the values 0 for development, 1 to e for betas
+ * 1 to 14, and f for release.  The patch level is exactly that.
+ * For example:
+ * 0.9.3-dev      0x00903000
+ * 0.9.3-beta1    0x00903001
+ * 0.9.3-beta2-dev 0x00903002
+ * 0.9.3-beta2    0x00903002 (same as ...beta2-dev)
+ * 0.9.3          0x0090300f
+ * 0.9.3a         0x0090301f
+ * 0.9.4          0x0090400f
+ * 1.2.3z         0x102031af
+ *
+ * For continuity reasons (because 0.9.5 is already out, and is coded
+ * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level
+ * part is slightly different, by setting the highest bit.  This means
+ * that 0.9.5a looks like this: 0x0090581f.  At 0.9.6, we can start
+ * with 0x0090600S...
+ *
+ * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.)
+ * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
+ *  major minor fix final patch/beta)
+ */
+# define OPENSSL_VERSION_NUMBER  0x1010005fL
+# ifdef OPENSSL_FIPS
+#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.1.0e-fips  16 Feb 2017"
+# else
+#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.1.0e  16 Feb 2017"
+# endif
+
+/*-
+ * The macros below are to be used for shared library (.so, .dll, ...)
+ * versioning.  That kind of versioning works a bit differently between
+ * operating systems.  The most usual scheme is to set a major and a minor
+ * number, and have the runtime loader check that the major number is equal
+ * to what it was at application link time, while the minor number has to
+ * be greater or equal to what it was at application link time.  With this
+ * scheme, the version number is usually part of the file name, like this:
+ *
+ *      libcrypto.so.0.9
+ *
+ * Some unixen also make a softlink with the major version number only:
+ *
+ *      libcrypto.so.0
+ *
+ * On Tru64 and IRIX 6.x it works a little bit differently.  There, the
+ * shared library version is stored in the file, and is actually a series
+ * of versions, separated by colons.  The rightmost version present in the
+ * library when linking an application is stored in the application to be
+ * matched at run time.  When the application is run, a check is done to
+ * see if the library version stored in the application matches any of the
+ * versions in the version string of the library itself.
+ * This version string can be constructed in any way, depending on what
+ * kind of matching is desired.  However, to implement the same scheme as
+ * the one used in the other unixen, all compatible versions, from lowest
+ * to highest, should be part of the string.  Consecutive builds would
+ * give the following versions strings:
+ *
+ *      3.0
+ *      3.0:3.1
+ *      3.0:3.1:3.2
+ *      4.0
+ *      4.0:4.1
+ *
+ * Notice how version 4 is completely incompatible with version, and
+ * therefore give the breach you can see.
+ *
+ * There may be other schemes as well that I haven't yet discovered.
+ *
+ * So, here's the way it works here: first of all, the library version
+ * number doesn't need at all to match the overall OpenSSL version.
+ * However, it's nice and more understandable if it actually does.
+ * The current library version is stored in the macro SHLIB_VERSION_NUMBER,
+ * which is just a piece of text in the format "M.m.e" (Major, minor, edit).
+ * For the sake of Tru64, IRIX, and any other OS that behaves in similar ways,
+ * we need to keep a history of version numbers, which is done in the
+ * macro SHLIB_VERSION_HISTORY.  The numbers are separated by colons and
+ * should only keep the versions that are binary compatible with the current.
+ */
+# define SHLIB_VERSION_HISTORY ""
+# define SHLIB_VERSION_NUMBER "1.1"
+
+
+#ifdef  __cplusplus
+}
+#endif
+#endif                          /* HEADER_OPENSSLV_H */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ossl_typ.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ossl_typ.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ossl_typ.h	(revision 331)
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2001-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
+ */
+
+#ifndef HEADER_OPENSSL_TYPES_H
+# define HEADER_OPENSSL_TYPES_H
+
+#include <limits.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# include <openssl/e_os2.h>
+
+# ifdef NO_ASN1_TYPEDEFS
+#  define ASN1_INTEGER            ASN1_STRING
+#  define ASN1_ENUMERATED         ASN1_STRING
+#  define ASN1_BIT_STRING         ASN1_STRING
+#  define ASN1_OCTET_STRING       ASN1_STRING
+#  define ASN1_PRINTABLESTRING    ASN1_STRING
+#  define ASN1_T61STRING          ASN1_STRING
+#  define ASN1_IA5STRING          ASN1_STRING
+#  define ASN1_UTCTIME            ASN1_STRING
+#  define ASN1_GENERALIZEDTIME    ASN1_STRING
+#  define ASN1_TIME               ASN1_STRING
+#  define ASN1_GENERALSTRING      ASN1_STRING
+#  define ASN1_UNIVERSALSTRING    ASN1_STRING
+#  define ASN1_BMPSTRING          ASN1_STRING
+#  define ASN1_VISIBLESTRING      ASN1_STRING
+#  define ASN1_UTF8STRING         ASN1_STRING
+#  define ASN1_BOOLEAN            int
+#  define ASN1_NULL               int
+# else
+typedef struct asn1_string_st ASN1_INTEGER;
+typedef struct asn1_string_st ASN1_ENUMERATED;
+typedef struct asn1_string_st ASN1_BIT_STRING;
+typedef struct asn1_string_st ASN1_OCTET_STRING;
+typedef struct asn1_string_st ASN1_PRINTABLESTRING;
+typedef struct asn1_string_st ASN1_T61STRING;
+typedef struct asn1_string_st ASN1_IA5STRING;
+typedef struct asn1_string_st ASN1_GENERALSTRING;
+typedef struct asn1_string_st ASN1_UNIVERSALSTRING;
+typedef struct asn1_string_st ASN1_BMPSTRING;
+typedef struct asn1_string_st ASN1_UTCTIME;
+typedef struct asn1_string_st ASN1_TIME;
+typedef struct asn1_string_st ASN1_GENERALIZEDTIME;
+typedef struct asn1_string_st ASN1_VISIBLESTRING;
+typedef struct asn1_string_st ASN1_UTF8STRING;
+typedef struct asn1_string_st ASN1_STRING;
+typedef int ASN1_BOOLEAN;
+typedef int ASN1_NULL;
+# endif
+
+typedef struct asn1_object_st ASN1_OBJECT;
+
+typedef struct ASN1_ITEM_st ASN1_ITEM;
+typedef struct asn1_pctx_st ASN1_PCTX;
+typedef struct asn1_sctx_st ASN1_SCTX;
+
+# ifdef _WIN32
+#  undef X509_NAME
+#  undef X509_EXTENSIONS
+#  undef PKCS7_ISSUER_AND_SERIAL
+#  undef PKCS7_SIGNER_INFO
+#  undef OCSP_REQUEST
+#  undef OCSP_RESPONSE
+# endif
+
+# ifdef BIGNUM
+#  undef BIGNUM
+# endif
+struct dane_st;
+typedef struct bio_st BIO;
+typedef struct bignum_st BIGNUM;
+typedef struct bignum_ctx BN_CTX;
+typedef struct bn_blinding_st BN_BLINDING;
+typedef struct bn_mont_ctx_st BN_MONT_CTX;
+typedef struct bn_recp_ctx_st BN_RECP_CTX;
+typedef struct bn_gencb_st BN_GENCB;
+
+typedef struct buf_mem_st BUF_MEM;
+
+typedef struct evp_cipher_st EVP_CIPHER;
+typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
+typedef struct evp_md_st EVP_MD;
+typedef struct evp_md_ctx_st EVP_MD_CTX;
+typedef struct evp_pkey_st EVP_PKEY;
+
+typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD;
+
+typedef struct evp_pkey_method_st EVP_PKEY_METHOD;
+typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
+
+typedef struct evp_Encode_Ctx_st EVP_ENCODE_CTX;
+
+typedef struct hmac_ctx_st HMAC_CTX;
+
+typedef struct dh_st DH;
+typedef struct dh_method DH_METHOD;
+
+typedef struct dsa_st DSA;
+typedef struct dsa_method DSA_METHOD;
+
+typedef struct rsa_st RSA;
+typedef struct rsa_meth_st RSA_METHOD;
+
+typedef struct ec_key_st EC_KEY;
+typedef struct ec_key_method_st EC_KEY_METHOD;
+
+typedef struct rand_meth_st RAND_METHOD;
+
+typedef struct ssl_dane_st SSL_DANE;
+typedef struct x509_st X509;
+typedef struct X509_algor_st X509_ALGOR;
+typedef struct X509_crl_st X509_CRL;
+typedef struct x509_crl_method_st X509_CRL_METHOD;
+typedef struct x509_revoked_st X509_REVOKED;
+typedef struct X509_name_st X509_NAME;
+typedef struct X509_pubkey_st X509_PUBKEY;
+typedef struct x509_store_st X509_STORE;
+typedef struct x509_store_ctx_st X509_STORE_CTX;
+
+typedef struct x509_object_st X509_OBJECT;
+typedef struct x509_lookup_st X509_LOOKUP;
+typedef struct x509_lookup_method_st X509_LOOKUP_METHOD;
+typedef struct X509_VERIFY_PARAM_st X509_VERIFY_PARAM;
+
+typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO;
+
+typedef struct v3_ext_ctx X509V3_CTX;
+typedef struct conf_st CONF;
+typedef struct ossl_init_settings_st OPENSSL_INIT_SETTINGS;
+
+typedef struct ui_st UI;
+typedef struct ui_method_st UI_METHOD;
+
+typedef struct engine_st ENGINE;
+typedef struct ssl_st SSL;
+typedef struct ssl_ctx_st SSL_CTX;
+
+typedef struct comp_ctx_st COMP_CTX;
+typedef struct comp_method_st COMP_METHOD;
+
+typedef struct X509_POLICY_NODE_st X509_POLICY_NODE;
+typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL;
+typedef struct X509_POLICY_TREE_st X509_POLICY_TREE;
+typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE;
+
+typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID;
+typedef struct DIST_POINT_st DIST_POINT;
+typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT;
+typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS;
+
+typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
+
+typedef struct ocsp_req_ctx_st OCSP_REQ_CTX;
+typedef struct ocsp_response_st OCSP_RESPONSE;
+typedef struct ocsp_responder_id_st OCSP_RESPID;
+
+typedef struct sct_st SCT;
+typedef struct sct_ctx_st SCT_CTX;
+typedef struct ctlog_st CTLOG;
+typedef struct ctlog_store_st CTLOG_STORE;
+typedef struct ct_policy_eval_ctx_st CT_POLICY_EVAL_CTX;
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && \
+    defined(INTMAX_MAX) && defined(UINTMAX_MAX)
+typedef intmax_t ossl_intmax_t;
+typedef uintmax_t ossl_uintmax_t;
+#else
+/*
+ * Not long long, because the C-library can only be expected to provide
+ * strtoll(), strtoull() at the same time as intmax_t and strtoimax(),
+ * strtoumax().  Since we use these for parsing arguments, we need the
+ * conversion functions, not just the sizes.
+ */
+typedef long ossl_intmax_t;
+typedef unsigned long ossl_uintmax_t;
+#endif
+
+#ifdef  __cplusplus
+}
+#endif
+#endif                          /* def HEADER_OPENSSL_TYPES_H */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/pem.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/pem.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/pem.h	(revision 331)
@@ -0,0 +1,501 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_PEM_H
+# define HEADER_PEM_H
+
+# include <openssl/e_os2.h>
+# include <openssl/bio.h>
+# include <openssl/stack.h>
+# include <openssl/evp.h>
+# include <openssl/x509.h>
+# include <openssl/pem2.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define PEM_BUFSIZE             1024
+
+# define PEM_STRING_X509_OLD     "X509 CERTIFICATE"
+# define PEM_STRING_X509         "CERTIFICATE"
+# define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE"
+# define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST"
+# define PEM_STRING_X509_REQ     "CERTIFICATE REQUEST"
+# define PEM_STRING_X509_CRL     "X509 CRL"
+# define PEM_STRING_EVP_PKEY     "ANY PRIVATE KEY"
+# define PEM_STRING_PUBLIC       "PUBLIC KEY"
+# define PEM_STRING_RSA          "RSA PRIVATE KEY"
+# define PEM_STRING_RSA_PUBLIC   "RSA PUBLIC KEY"
+# define PEM_STRING_DSA          "DSA PRIVATE KEY"
+# define PEM_STRING_DSA_PUBLIC   "DSA PUBLIC KEY"
+# define PEM_STRING_PKCS7        "PKCS7"
+# define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA"
+# define PEM_STRING_PKCS8        "ENCRYPTED PRIVATE KEY"
+# define PEM_STRING_PKCS8INF     "PRIVATE KEY"
+# define PEM_STRING_DHPARAMS     "DH PARAMETERS"
+# define PEM_STRING_DHXPARAMS    "X9.42 DH PARAMETERS"
+# define PEM_STRING_SSL_SESSION  "SSL SESSION PARAMETERS"
+# define PEM_STRING_DSAPARAMS    "DSA PARAMETERS"
+# define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
+# define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
+# define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY"
+# define PEM_STRING_PARAMETERS   "PARAMETERS"
+# define PEM_STRING_CMS          "CMS"
+
+# define PEM_TYPE_ENCRYPTED      10
+# define PEM_TYPE_MIC_ONLY       20
+# define PEM_TYPE_MIC_CLEAR      30
+# define PEM_TYPE_CLEAR          40
+
+typedef struct pem_recip_st {
+    char *name;
+    X509_NAME *dn;
+    int cipher;
+    int key_enc;
+    /*      char iv[8]; unused and wrong size */
+} PEM_USER;
+
+typedef struct pem_ctx_st {
+    int type;                   /* what type of object */
+    struct {
+        int version;
+        int mode;
+    } proc_type;
+
+    char *domain;
+
+    struct {
+        int cipher;
+        /*-
+        unused, and wrong size
+        unsigned char iv[8]; */
+    } DEK_info;
+
+    PEM_USER *originator;
+
+    int num_recipient;
+    PEM_USER **recipient;
+
+/*-
+    XXX(ben): don#t think this is used!
+        STACK *x509_chain;      / * certificate chain */
+    EVP_MD *md;                 /* signature type */
+
+    int md_enc;                 /* is the md encrypted or not? */
+    int md_len;                 /* length of md_data */
+    char *md_data;              /* message digest, could be pkey encrypted */
+
+    EVP_CIPHER *dec;            /* date encryption cipher */
+    int key_len;                /* key length */
+    unsigned char *key;         /* key */
+  /*-
+    unused, and wrong size
+    unsigned char iv[8]; */
+
+    int data_enc;               /* is the data encrypted */
+    int data_len;
+    unsigned char *data;
+} PEM_CTX;
+
+/*
+ * These macros make the PEM_read/PEM_write functions easier to maintain and
+ * write. Now they are all implemented with either: IMPLEMENT_PEM_rw(...) or
+ * IMPLEMENT_PEM_rw_cb(...)
+ */
+
+# ifdef OPENSSL_NO_STDIO
+
+#  define IMPLEMENT_PEM_read_fp(name, type, str, asn1) /**/
+#  define IMPLEMENT_PEM_write_fp(name, type, str, asn1) /**/
+#  define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) /**/
+#  define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) /**/
+#  define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) /**/
+# else
+
+#  define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \
+type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\
+{ \
+return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \
+}
+
+#  define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \
+int PEM_write_##name(FILE *fp, type *x) \
+{ \
+return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \
+}
+
+#  define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \
+int PEM_write_##name(FILE *fp, const type *x) \
+{ \
+return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \
+}
+
+#  define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \
+int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
+             unsigned char *kstr, int klen, pem_password_cb *cb, \
+                  void *u) \
+        { \
+        return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \
+        }
+
+#  define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \
+int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
+             unsigned char *kstr, int klen, pem_password_cb *cb, \
+                  void *u) \
+        { \
+        return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \
+        }
+
+# endif
+
+# define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
+type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\
+{ \
+return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \
+}
+
+# define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
+int PEM_write_bio_##name(BIO *bp, type *x) \
+{ \
+return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \
+}
+
+# define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
+int PEM_write_bio_##name(BIO *bp, const type *x) \
+{ \
+return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \
+}
+
+# define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
+int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
+             unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
+        { \
+        return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \
+        }
+
+# define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
+int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
+             unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
+        { \
+        return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \
+        }
+
+# define IMPLEMENT_PEM_write(name, type, str, asn1) \
+        IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
+        IMPLEMENT_PEM_write_fp(name, type, str, asn1)
+
+# define IMPLEMENT_PEM_write_const(name, type, str, asn1) \
+        IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
+        IMPLEMENT_PEM_write_fp_const(name, type, str, asn1)
+
+# define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \
+        IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
+        IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1)
+
+# define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \
+        IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
+        IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1)
+
+# define IMPLEMENT_PEM_read(name, type, str, asn1) \
+        IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
+        IMPLEMENT_PEM_read_fp(name, type, str, asn1)
+
+# define IMPLEMENT_PEM_rw(name, type, str, asn1) \
+        IMPLEMENT_PEM_read(name, type, str, asn1) \
+        IMPLEMENT_PEM_write(name, type, str, asn1)
+
+# define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \
+        IMPLEMENT_PEM_read(name, type, str, asn1) \
+        IMPLEMENT_PEM_write_const(name, type, str, asn1)
+
+# define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \
+        IMPLEMENT_PEM_read(name, type, str, asn1) \
+        IMPLEMENT_PEM_write_cb(name, type, str, asn1)
+
+/* These are the same except they are for the declarations */
+
+# if defined(OPENSSL_NO_STDIO)
+
+#  define DECLARE_PEM_read_fp(name, type) /**/
+#  define DECLARE_PEM_write_fp(name, type) /**/
+#  define DECLARE_PEM_write_fp_const(name, type) /**/
+#  define DECLARE_PEM_write_cb_fp(name, type) /**/
+# else
+
+#  define DECLARE_PEM_read_fp(name, type) \
+        type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u);
+
+#  define DECLARE_PEM_write_fp(name, type) \
+        int PEM_write_##name(FILE *fp, type *x);
+
+#  define DECLARE_PEM_write_fp_const(name, type) \
+        int PEM_write_##name(FILE *fp, const type *x);
+
+#  define DECLARE_PEM_write_cb_fp(name, type) \
+        int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
+             unsigned char *kstr, int klen, pem_password_cb *cb, void *u);
+
+# endif
+
+#  define DECLARE_PEM_read_bio(name, type) \
+        type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u);
+
+#  define DECLARE_PEM_write_bio(name, type) \
+        int PEM_write_bio_##name(BIO *bp, type *x);
+
+#  define DECLARE_PEM_write_bio_const(name, type) \
+        int PEM_write_bio_##name(BIO *bp, const type *x);
+
+#  define DECLARE_PEM_write_cb_bio(name, type) \
+        int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
+             unsigned char *kstr, int klen, pem_password_cb *cb, void *u);
+
+# define DECLARE_PEM_write(name, type) \
+        DECLARE_PEM_write_bio(name, type) \
+        DECLARE_PEM_write_fp(name, type)
+# define DECLARE_PEM_write_const(name, type) \
+        DECLARE_PEM_write_bio_const(name, type) \
+        DECLARE_PEM_write_fp_const(name, type)
+# define DECLARE_PEM_write_cb(name, type) \
+        DECLARE_PEM_write_cb_bio(name, type) \
+        DECLARE_PEM_write_cb_fp(name, type)
+# define DECLARE_PEM_read(name, type) \
+        DECLARE_PEM_read_bio(name, type) \
+        DECLARE_PEM_read_fp(name, type)
+# define DECLARE_PEM_rw(name, type) \
+        DECLARE_PEM_read(name, type) \
+        DECLARE_PEM_write(name, type)
+# define DECLARE_PEM_rw_const(name, type) \
+        DECLARE_PEM_read(name, type) \
+        DECLARE_PEM_write_const(name, type)
+# define DECLARE_PEM_rw_cb(name, type) \
+        DECLARE_PEM_read(name, type) \
+        DECLARE_PEM_write_cb(name, type)
+typedef int pem_password_cb (char *buf, int size, int rwflag, void *userdata);
+
+int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher);
+int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *len,
+                  pem_password_cb *callback, void *u);
+
+int PEM_read_bio(BIO *bp, char **name, char **header,
+                 unsigned char **data, long *len);
+int PEM_write_bio(BIO *bp, const char *name, const char *hdr,
+                  const unsigned char *data, long len);
+int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm,
+                       const char *name, BIO *bp, pem_password_cb *cb,
+                       void *u);
+void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x,
+                        pem_password_cb *cb, void *u);
+int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x,
+                       const EVP_CIPHER *enc, unsigned char *kstr, int klen,
+                       pem_password_cb *cb, void *u);
+
+STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk,
+                                            pem_password_cb *cb, void *u);
+int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
+                            unsigned char *kstr, int klen,
+                            pem_password_cb *cd, void *u);
+
+#ifndef OPENSSL_NO_STDIO
+int PEM_read(FILE *fp, char **name, char **header,
+             unsigned char **data, long *len);
+int PEM_write(FILE *fp, const char *name, const char *hdr,
+              const unsigned char *data, long len);
+void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
+                    pem_password_cb *cb, void *u);
+int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
+                   void *x, const EVP_CIPHER *enc, unsigned char *kstr,
+                   int klen, pem_password_cb *callback, void *u);
+STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
+                                        pem_password_cb *cb, void *u);
+#endif
+
+int PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type);
+int PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *d, unsigned int cnt);
+int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
+                  unsigned int *siglen, EVP_PKEY *pkey);
+
+int PEM_def_callback(char *buf, int num, int w, void *key);
+void PEM_proc_type(char *buf, int type);
+void PEM_dek_info(char *buf, const char *type, int len, char *str);
+
+# include <openssl/symhacks.h>
+
+DECLARE_PEM_rw(X509, X509)
+DECLARE_PEM_rw(X509_AUX, X509)
+DECLARE_PEM_rw(X509_REQ, X509_REQ)
+DECLARE_PEM_write(X509_REQ_NEW, X509_REQ)
+DECLARE_PEM_rw(X509_CRL, X509_CRL)
+DECLARE_PEM_rw(PKCS7, PKCS7)
+DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE)
+DECLARE_PEM_rw(PKCS8, X509_SIG)
+DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
+# ifndef OPENSSL_NO_RSA
+DECLARE_PEM_rw_cb(RSAPrivateKey, RSA)
+DECLARE_PEM_rw_const(RSAPublicKey, RSA)
+DECLARE_PEM_rw(RSA_PUBKEY, RSA)
+# endif
+# ifndef OPENSSL_NO_DSA
+DECLARE_PEM_rw_cb(DSAPrivateKey, DSA)
+DECLARE_PEM_rw(DSA_PUBKEY, DSA)
+DECLARE_PEM_rw_const(DSAparams, DSA)
+# endif
+# ifndef OPENSSL_NO_EC
+DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP)
+DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY)
+DECLARE_PEM_rw(EC_PUBKEY, EC_KEY)
+# endif
+# ifndef OPENSSL_NO_DH
+DECLARE_PEM_rw_const(DHparams, DH)
+DECLARE_PEM_write_const(DHxparams, DH)
+# endif
+DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY)
+DECLARE_PEM_rw(PUBKEY, EVP_PKEY)
+
+int PEM_write_bio_PrivateKey_traditional(BIO *bp, EVP_PKEY *x,
+                                         const EVP_CIPHER *enc,
+                                         unsigned char *kstr, int klen,
+                                         pem_password_cb *cb, void *u);
+
+int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
+                                      char *kstr, int klen,
+                                      pem_password_cb *cb, void *u);
+int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *,
+                                  char *, int, pem_password_cb *, void *);
+int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+                            char *kstr, int klen,
+                            pem_password_cb *cb, void *u);
+int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
+                                char *kstr, int klen,
+                                pem_password_cb *cb, void *u);
+EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
+                                  void *u);
+
+# ifndef OPENSSL_NO_STDIO
+int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+                           char *kstr, int klen,
+                           pem_password_cb *cb, void *u);
+int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
+                               char *kstr, int klen,
+                               pem_password_cb *cb, void *u);
+int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
+                                  char *kstr, int klen,
+                                  pem_password_cb *cb, void *u);
+
+EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb,
+                                 void *u);
+
+int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+                              char *kstr, int klen, pem_password_cb *cd,
+                              void *u);
+# endif
+EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x);
+int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x);
+
+# ifndef OPENSSL_NO_DSA
+EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length);
+EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length);
+EVP_PKEY *b2i_PrivateKey_bio(BIO *in);
+EVP_PKEY *b2i_PublicKey_bio(BIO *in);
+int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk);
+int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk);
+#  ifndef OPENSSL_NO_RC4
+EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u);
+int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
+                pem_password_cb *cb, void *u);
+#  endif
+# endif
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_PEM_strings(void);
+
+/* Error codes for the PEM functions. */
+
+/* Function codes. */
+# define PEM_F_B2I_DSS                                    127
+# define PEM_F_B2I_PVK_BIO                                128
+# define PEM_F_B2I_RSA                                    129
+# define PEM_F_CHECK_BITLEN_DSA                           130
+# define PEM_F_CHECK_BITLEN_RSA                           131
+# define PEM_F_D2I_PKCS8PRIVATEKEY_BIO                    120
+# define PEM_F_D2I_PKCS8PRIVATEKEY_FP                     121
+# define PEM_F_DO_B2I                                     132
+# define PEM_F_DO_B2I_BIO                                 133
+# define PEM_F_DO_BLOB_HEADER                             134
+# define PEM_F_DO_PK8PKEY                                 126
+# define PEM_F_DO_PK8PKEY_FP                              125
+# define PEM_F_DO_PVK_BODY                                135
+# define PEM_F_DO_PVK_HEADER                              136
+# define PEM_F_I2B_PVK                                    137
+# define PEM_F_I2B_PVK_BIO                                138
+# define PEM_F_LOAD_IV                                    101
+# define PEM_F_PEM_ASN1_READ                              102
+# define PEM_F_PEM_ASN1_READ_BIO                          103
+# define PEM_F_PEM_ASN1_WRITE                             104
+# define PEM_F_PEM_ASN1_WRITE_BIO                         105
+# define PEM_F_PEM_DEF_CALLBACK                           100
+# define PEM_F_PEM_DO_HEADER                              106
+# define PEM_F_PEM_GET_EVP_CIPHER_INFO                    107
+# define PEM_F_PEM_READ                                   108
+# define PEM_F_PEM_READ_BIO                               109
+# define PEM_F_PEM_READ_BIO_DHPARAMS                      141
+# define PEM_F_PEM_READ_BIO_PARAMETERS                    140
+# define PEM_F_PEM_READ_BIO_PRIVATEKEY                    123
+# define PEM_F_PEM_READ_DHPARAMS                          142
+# define PEM_F_PEM_READ_PRIVATEKEY                        124
+# define PEM_F_PEM_SIGNFINAL                              112
+# define PEM_F_PEM_WRITE                                  113
+# define PEM_F_PEM_WRITE_BIO                              114
+# define PEM_F_PEM_WRITE_PRIVATEKEY                       139
+# define PEM_F_PEM_X509_INFO_READ                         115
+# define PEM_F_PEM_X509_INFO_READ_BIO                     116
+# define PEM_F_PEM_X509_INFO_WRITE_BIO                    117
+
+/* Reason codes. */
+# define PEM_R_BAD_BASE64_DECODE                          100
+# define PEM_R_BAD_DECRYPT                                101
+# define PEM_R_BAD_END_LINE                               102
+# define PEM_R_BAD_IV_CHARS                               103
+# define PEM_R_BAD_MAGIC_NUMBER                           116
+# define PEM_R_BAD_PASSWORD_READ                          104
+# define PEM_R_BAD_VERSION_NUMBER                         117
+# define PEM_R_BIO_WRITE_FAILURE                          118
+# define PEM_R_CIPHER_IS_NULL                             127
+# define PEM_R_ERROR_CONVERTING_PRIVATE_KEY               115
+# define PEM_R_EXPECTING_PRIVATE_KEY_BLOB                 119
+# define PEM_R_EXPECTING_PUBLIC_KEY_BLOB                  120
+# define PEM_R_HEADER_TOO_LONG                            128
+# define PEM_R_INCONSISTENT_HEADER                        121
+# define PEM_R_KEYBLOB_HEADER_PARSE_ERROR                 122
+# define PEM_R_KEYBLOB_TOO_SHORT                          123
+# define PEM_R_MISSING_DEK_IV                             129
+# define PEM_R_NOT_DEK_INFO                               105
+# define PEM_R_NOT_ENCRYPTED                              106
+# define PEM_R_NOT_PROC_TYPE                              107
+# define PEM_R_NO_START_LINE                              108
+# define PEM_R_PROBLEMS_GETTING_PASSWORD                  109
+# define PEM_R_PVK_DATA_TOO_SHORT                         124
+# define PEM_R_PVK_TOO_SHORT                              125
+# define PEM_R_READ_KEY                                   111
+# define PEM_R_SHORT_HEADER                               112
+# define PEM_R_UNEXPECTED_DEK_IV                          130
+# define PEM_R_UNSUPPORTED_CIPHER                         113
+# define PEM_R_UNSUPPORTED_ENCRYPTION                     114
+# define PEM_R_UNSUPPORTED_KEY_COMPONENTS                 126
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/pem2.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/pem2.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/pem2.h	(revision 331)
@@ -0,0 +1,20 @@
+/*
+ * Copyright 1999-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
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef HEADER_PEM_H
+int ERR_load_PEM_strings(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/pkcs12.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/pkcs12.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/pkcs12.h	(revision 331)
@@ -0,0 +1,282 @@
+/*
+ * Copyright 1999-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
+ */
+
+#ifndef HEADER_PKCS12_H
+# define HEADER_PKCS12_H
+
+# include <openssl/bio.h>
+# include <openssl/x509.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# define PKCS12_KEY_ID   1
+# define PKCS12_IV_ID    2
+# define PKCS12_MAC_ID   3
+
+/* Default iteration count */
+# ifndef PKCS12_DEFAULT_ITER
+#  define PKCS12_DEFAULT_ITER     PKCS5_DEFAULT_ITER
+# endif
+
+# define PKCS12_MAC_KEY_LENGTH 20
+
+# define PKCS12_SALT_LEN 8
+
+/* It's not clear if these are actually needed... */
+# define PKCS12_key_gen PKCS12_key_gen_utf8
+# define PKCS12_add_friendlyname PKCS12_add_friendlyname_utf8
+
+/* MS key usage constants */
+
+# define KEY_EX  0x10
+# define KEY_SIG 0x80
+
+typedef struct PKCS12_MAC_DATA_st PKCS12_MAC_DATA;
+
+typedef struct PKCS12_st PKCS12;
+
+typedef struct PKCS12_SAFEBAG_st PKCS12_SAFEBAG;
+
+DEFINE_STACK_OF(PKCS12_SAFEBAG)
+
+typedef struct pkcs12_bag_st PKCS12_BAGS;
+
+# define PKCS12_ERROR    0
+# define PKCS12_OK       1
+
+/* Compatibility macros */
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+
+# define M_PKCS12_bag_type PKCS12_bag_type
+# define M_PKCS12_cert_bag_type PKCS12_cert_bag_type
+# define M_PKCS12_crl_bag_type PKCS12_cert_bag_type
+
+# define PKCS12_certbag2x509 PKCS12_SAFEBAG_get1_cert
+# define PKCS12_certbag2scrl PKCS12_SAFEBAG_get1_crl
+# define PKCS12_bag_type PKCS12_SAFEBAG_get_nid
+# define PKCS12_cert_bag_type PKCS12_SAFEBAG_get_bag_nid
+# define PKCS12_x5092certbag PKCS12_SAFEBAG_create_cert
+# define PKCS12_x509crl2certbag PKCS12_SAFEBAG_create_crl
+# define PKCS12_MAKE_KEYBAG PKCS12_SAFEBAG_create0_p8inf
+# define PKCS12_MAKE_SHKEYBAG PKCS12_SAFEBAG_create_pkcs8_encrypt
+
+#endif
+
+DEPRECATEDIN_1_1_0(ASN1_TYPE *PKCS12_get_attr(const PKCS12_SAFEBAG *bag, int attr_nid))
+
+ASN1_TYPE *PKCS8_get_attr(PKCS8_PRIV_KEY_INFO *p8, int attr_nid);
+int PKCS12_mac_present(const PKCS12 *p12);
+void PKCS12_get0_mac(const ASN1_OCTET_STRING **pmac,
+                     const X509_ALGOR **pmacalg,
+                     const ASN1_OCTET_STRING **psalt,
+                     const ASN1_INTEGER **piter,
+                     const PKCS12 *p12);
+
+const ASN1_TYPE *PKCS12_SAFEBAG_get0_attr(const PKCS12_SAFEBAG *bag,
+                                          int attr_nid);
+const ASN1_OBJECT *PKCS12_SAFEBAG_get0_type(const PKCS12_SAFEBAG *bag);
+int PKCS12_SAFEBAG_get_nid(const PKCS12_SAFEBAG *bag);
+int PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag);
+
+X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag);
+X509_CRL *PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag);
+const STACK_OF(PKCS12_SAFEBAG) *
+PKCS12_SAFEBAG_get0_safes(const PKCS12_SAFEBAG *bag);
+const PKCS8_PRIV_KEY_INFO *PKCS12_SAFEBAG_get0_p8inf(const PKCS12_SAFEBAG *bag);
+const X509_SIG *PKCS12_SAFEBAG_get0_pkcs8(const PKCS12_SAFEBAG *bag);
+
+PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_cert(X509 *x509);
+PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_crl(X509_CRL *crl);
+PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8);
+PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8);
+PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid,
+                                                    const char *pass,
+                                                    int passlen,
+                                                    unsigned char *salt,
+                                                    int saltlen, int iter,
+                                                    PKCS8_PRIV_KEY_INFO *p8inf);
+
+PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it,
+                                         int nid1, int nid2);
+PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(const X509_SIG *p8, const char *pass,
+                                   int passlen);
+PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(const PKCS12_SAFEBAG *bag,
+                                         const char *pass, int passlen);
+X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
+                        const char *pass, int passlen, unsigned char *salt,
+                        int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8);
+X509_SIG *PKCS8_set0_pbe(const char *pass, int passlen,
+                        PKCS8_PRIV_KEY_INFO *p8inf, X509_ALGOR *pbe);
+PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk);
+STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7);
+PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
+                             unsigned char *salt, int saltlen, int iter,
+                             STACK_OF(PKCS12_SAFEBAG) *bags);
+STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass,
+                                                  int passlen);
+
+int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes);
+STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12);
+
+int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name,
+                          int namelen);
+int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name,
+                                int namelen);
+int PKCS12_add_friendlyname_utf8(PKCS12_SAFEBAG *bag, const char *name,
+                                 int namelen);
+int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name,
+                           int namelen);
+int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag,
+                                const unsigned char *name, int namelen);
+int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage);
+ASN1_TYPE *PKCS12_get_attr_gen(const STACK_OF(X509_ATTRIBUTE) *attrs,
+                               int attr_nid);
+char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag);
+const STACK_OF(X509_ATTRIBUTE) *
+PKCS12_SAFEBAG_get0_attrs(const PKCS12_SAFEBAG *bag);
+unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor,
+                                const char *pass, int passlen,
+                                const unsigned char *in, int inlen,
+                                unsigned char **data, int *datalen,
+                                int en_de);
+void *PKCS12_item_decrypt_d2i(const X509_ALGOR *algor, const ASN1_ITEM *it,
+                              const char *pass, int passlen,
+                              const ASN1_OCTET_STRING *oct, int zbuf);
+ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor,
+                                           const ASN1_ITEM *it,
+                                           const char *pass, int passlen,
+                                           void *obj, int zbuf);
+PKCS12 *PKCS12_init(int mode);
+int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
+                       int saltlen, int id, int iter, int n,
+                       unsigned char *out, const EVP_MD *md_type);
+int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
+                       int saltlen, int id, int iter, int n,
+                       unsigned char *out, const EVP_MD *md_type);
+int PKCS12_key_gen_utf8(const char *pass, int passlen, unsigned char *salt,
+                        int saltlen, int id, int iter, int n,
+                        unsigned char *out, const EVP_MD *md_type);
+int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+                        ASN1_TYPE *param, const EVP_CIPHER *cipher,
+                        const EVP_MD *md_type, int en_de);
+int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
+                   unsigned char *mac, unsigned int *maclen);
+int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen);
+int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
+                   unsigned char *salt, int saltlen, int iter,
+                   const EVP_MD *md_type);
+int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt,
+                     int saltlen, const EVP_MD *md_type);
+unsigned char *OPENSSL_asc2uni(const char *asc, int asclen,
+                               unsigned char **uni, int *unilen);
+char *OPENSSL_uni2asc(const unsigned char *uni, int unilen);
+unsigned char *OPENSSL_utf82uni(const char *asc, int asclen,
+                                unsigned char **uni, int *unilen);
+char *OPENSSL_uni2utf8(const unsigned char *uni, int unilen);
+
+DECLARE_ASN1_FUNCTIONS(PKCS12)
+DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA)
+DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG)
+DECLARE_ASN1_FUNCTIONS(PKCS12_BAGS)
+
+DECLARE_ASN1_ITEM(PKCS12_SAFEBAGS)
+DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES)
+
+void PKCS12_PBE_add(void);
+int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
+                 STACK_OF(X509) **ca);
+PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey,
+                      X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert,
+                      int iter, int mac_iter, int keytype);
+
+PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert);
+PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags,
+                               EVP_PKEY *key, int key_usage, int iter,
+                               int key_nid, const char *pass);
+int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
+                    int safe_nid, int iter, const char *pass);
+PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid);
+
+int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12);
+# ifndef OPENSSL_NO_STDIO
+int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12);
+# endif
+PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12);
+# ifndef OPENSSL_NO_STDIO
+PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12);
+# endif
+int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_PKCS12_strings(void);
+
+/* Error codes for the PKCS12 functions. */
+
+/* Function codes. */
+# define PKCS12_F_PKCS12_CREATE                           105
+# define PKCS12_F_PKCS12_GEN_MAC                          107
+# define PKCS12_F_PKCS12_INIT                             109
+# define PKCS12_F_PKCS12_ITEM_DECRYPT_D2I                 106
+# define PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT                 108
+# define PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG                117
+# define PKCS12_F_PKCS12_KEY_GEN_ASC                      110
+# define PKCS12_F_PKCS12_KEY_GEN_UNI                      111
+# define PKCS12_F_PKCS12_KEY_GEN_UTF8                     116
+# define PKCS12_F_PKCS12_NEWPASS                          128
+# define PKCS12_F_PKCS12_PACK_P7DATA                      114
+# define PKCS12_F_PKCS12_PACK_P7ENCDATA                   115
+# define PKCS12_F_PKCS12_PARSE                            118
+# define PKCS12_F_PKCS12_PBE_CRYPT                        119
+# define PKCS12_F_PKCS12_PBE_KEYIVGEN                     120
+# define PKCS12_F_PKCS12_SAFEBAG_CREATE0_P8INF            112
+# define PKCS12_F_PKCS12_SAFEBAG_CREATE0_PKCS8            113
+# define PKCS12_F_PKCS12_SAFEBAG_CREATE_PKCS8_ENCRYPT     133
+# define PKCS12_F_PKCS12_SETUP_MAC                        122
+# define PKCS12_F_PKCS12_SET_MAC                          123
+# define PKCS12_F_PKCS12_UNPACK_AUTHSAFES                 130
+# define PKCS12_F_PKCS12_UNPACK_P7DATA                    131
+# define PKCS12_F_PKCS12_VERIFY_MAC                       126
+# define PKCS12_F_PKCS8_ENCRYPT                           125
+# define PKCS12_F_PKCS8_SET0_PBE                          132
+
+/* Reason codes. */
+# define PKCS12_R_CANT_PACK_STRUCTURE                     100
+# define PKCS12_R_CONTENT_TYPE_NOT_DATA                   121
+# define PKCS12_R_DECODE_ERROR                            101
+# define PKCS12_R_ENCODE_ERROR                            102
+# define PKCS12_R_ENCRYPT_ERROR                           103
+# define PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE       120
+# define PKCS12_R_INVALID_NULL_ARGUMENT                   104
+# define PKCS12_R_INVALID_NULL_PKCS12_POINTER             105
+# define PKCS12_R_IV_GEN_ERROR                            106
+# define PKCS12_R_KEY_GEN_ERROR                           107
+# define PKCS12_R_MAC_ABSENT                              108
+# define PKCS12_R_MAC_GENERATION_ERROR                    109
+# define PKCS12_R_MAC_SETUP_ERROR                         110
+# define PKCS12_R_MAC_STRING_SET_ERROR                    111
+# define PKCS12_R_MAC_VERIFY_FAILURE                      113
+# define PKCS12_R_PARSE_ERROR                             114
+# define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR           115
+# define PKCS12_R_PKCS12_CIPHERFINAL_ERROR                116
+# define PKCS12_R_PKCS12_PBE_CRYPT_ERROR                  117
+# define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM                118
+# define PKCS12_R_UNSUPPORTED_PKCS12_MODE                 119
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/pkcs7.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/pkcs7.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/pkcs7.h	(revision 331)
@@ -0,0 +1,404 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_PKCS7_H
+# define HEADER_PKCS7_H
+
+# include <openssl/asn1.h>
+# include <openssl/bio.h>
+# include <openssl/e_os2.h>
+
+# include <openssl/symhacks.h>
+# include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*-
+Encryption_ID           DES-CBC
+Digest_ID               MD5
+Digest_Encryption_ID    rsaEncryption
+Key_Encryption_ID       rsaEncryption
+*/
+
+typedef struct pkcs7_issuer_and_serial_st {
+    X509_NAME *issuer;
+    ASN1_INTEGER *serial;
+} PKCS7_ISSUER_AND_SERIAL;
+
+typedef struct pkcs7_signer_info_st {
+    ASN1_INTEGER *version;      /* version 1 */
+    PKCS7_ISSUER_AND_SERIAL *issuer_and_serial;
+    X509_ALGOR *digest_alg;
+    STACK_OF(X509_ATTRIBUTE) *auth_attr; /* [ 0 ] */
+    X509_ALGOR *digest_enc_alg;
+    ASN1_OCTET_STRING *enc_digest;
+    STACK_OF(X509_ATTRIBUTE) *unauth_attr; /* [ 1 ] */
+    /* The private key to sign with */
+    EVP_PKEY *pkey;
+} PKCS7_SIGNER_INFO;
+
+DEFINE_STACK_OF(PKCS7_SIGNER_INFO)
+
+typedef struct pkcs7_recip_info_st {
+    ASN1_INTEGER *version;      /* version 0 */
+    PKCS7_ISSUER_AND_SERIAL *issuer_and_serial;
+    X509_ALGOR *key_enc_algor;
+    ASN1_OCTET_STRING *enc_key;
+    X509 *cert;                 /* get the pub-key from this */
+} PKCS7_RECIP_INFO;
+
+DEFINE_STACK_OF(PKCS7_RECIP_INFO)
+
+typedef struct pkcs7_signed_st {
+    ASN1_INTEGER *version;      /* version 1 */
+    STACK_OF(X509_ALGOR) *md_algs; /* md used */
+    STACK_OF(X509) *cert;       /* [ 0 ] */
+    STACK_OF(X509_CRL) *crl;    /* [ 1 ] */
+    STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
+    struct pkcs7_st *contents;
+} PKCS7_SIGNED;
+/*
+ * The above structure is very very similar to PKCS7_SIGN_ENVELOPE. How about
+ * merging the two
+ */
+
+typedef struct pkcs7_enc_content_st {
+    ASN1_OBJECT *content_type;
+    X509_ALGOR *algorithm;
+    ASN1_OCTET_STRING *enc_data; /* [ 0 ] */
+    const EVP_CIPHER *cipher;
+} PKCS7_ENC_CONTENT;
+
+typedef struct pkcs7_enveloped_st {
+    ASN1_INTEGER *version;      /* version 0 */
+    STACK_OF(PKCS7_RECIP_INFO) *recipientinfo;
+    PKCS7_ENC_CONTENT *enc_data;
+} PKCS7_ENVELOPE;
+
+typedef struct pkcs7_signedandenveloped_st {
+    ASN1_INTEGER *version;      /* version 1 */
+    STACK_OF(X509_ALGOR) *md_algs; /* md used */
+    STACK_OF(X509) *cert;       /* [ 0 ] */
+    STACK_OF(X509_CRL) *crl;    /* [ 1 ] */
+    STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
+    PKCS7_ENC_CONTENT *enc_data;
+    STACK_OF(PKCS7_RECIP_INFO) *recipientinfo;
+} PKCS7_SIGN_ENVELOPE;
+
+typedef struct pkcs7_digest_st {
+    ASN1_INTEGER *version;      /* version 0 */
+    X509_ALGOR *md;             /* md used */
+    struct pkcs7_st *contents;
+    ASN1_OCTET_STRING *digest;
+} PKCS7_DIGEST;
+
+typedef struct pkcs7_encrypted_st {
+    ASN1_INTEGER *version;      /* version 0 */
+    PKCS7_ENC_CONTENT *enc_data;
+} PKCS7_ENCRYPT;
+
+typedef struct pkcs7_st {
+    /*
+     * The following is non NULL if it contains ASN1 encoding of this
+     * structure
+     */
+    unsigned char *asn1;
+    long length;
+# define PKCS7_S_HEADER  0
+# define PKCS7_S_BODY    1
+# define PKCS7_S_TAIL    2
+    int state;                  /* used during processing */
+    int detached;
+    ASN1_OBJECT *type;
+    /* content as defined by the type */
+    /*
+     * all encryption/message digests are applied to the 'contents', leaving
+     * out the 'type' field.
+     */
+    union {
+        char *ptr;
+        /* NID_pkcs7_data */
+        ASN1_OCTET_STRING *data;
+        /* NID_pkcs7_signed */
+        PKCS7_SIGNED *sign;
+        /* NID_pkcs7_enveloped */
+        PKCS7_ENVELOPE *enveloped;
+        /* NID_pkcs7_signedAndEnveloped */
+        PKCS7_SIGN_ENVELOPE *signed_and_enveloped;
+        /* NID_pkcs7_digest */
+        PKCS7_DIGEST *digest;
+        /* NID_pkcs7_encrypted */
+        PKCS7_ENCRYPT *encrypted;
+        /* Anything else */
+        ASN1_TYPE *other;
+    } d;
+} PKCS7;
+
+DEFINE_STACK_OF(PKCS7)
+
+# define PKCS7_OP_SET_DETACHED_SIGNATURE 1
+# define PKCS7_OP_GET_DETACHED_SIGNATURE 2
+
+# define PKCS7_get_signed_attributes(si) ((si)->auth_attr)
+# define PKCS7_get_attributes(si)        ((si)->unauth_attr)
+
+# define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed)
+# define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
+# define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped)
+# define PKCS7_type_is_signedAndEnveloped(a) \
+                (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped)
+# define PKCS7_type_is_data(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
+# define PKCS7_type_is_digest(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
+
+# define PKCS7_set_detached(p,v) \
+                PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL)
+# define PKCS7_get_detached(p) \
+                PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL)
+
+# define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7))
+
+/* S/MIME related flags */
+
+# define PKCS7_TEXT              0x1
+# define PKCS7_NOCERTS           0x2
+# define PKCS7_NOSIGS            0x4
+# define PKCS7_NOCHAIN           0x8
+# define PKCS7_NOINTERN          0x10
+# define PKCS7_NOVERIFY          0x20
+# define PKCS7_DETACHED          0x40
+# define PKCS7_BINARY            0x80
+# define PKCS7_NOATTR            0x100
+# define PKCS7_NOSMIMECAP        0x200
+# define PKCS7_NOOLDMIMETYPE     0x400
+# define PKCS7_CRLFEOL           0x800
+# define PKCS7_STREAM            0x1000
+# define PKCS7_NOCRL             0x2000
+# define PKCS7_PARTIAL           0x4000
+# define PKCS7_REUSE_DIGEST      0x8000
+# define PKCS7_NO_DUAL_CONTENT   0x10000
+
+/* Flags: for compatibility with older code */
+
+# define SMIME_TEXT      PKCS7_TEXT
+# define SMIME_NOCERTS   PKCS7_NOCERTS
+# define SMIME_NOSIGS    PKCS7_NOSIGS
+# define SMIME_NOCHAIN   PKCS7_NOCHAIN
+# define SMIME_NOINTERN  PKCS7_NOINTERN
+# define SMIME_NOVERIFY  PKCS7_NOVERIFY
+# define SMIME_DETACHED  PKCS7_DETACHED
+# define SMIME_BINARY    PKCS7_BINARY
+# define SMIME_NOATTR    PKCS7_NOATTR
+
+/* CRLF ASCII canonicalisation */
+# define SMIME_ASCIICRLF         0x80000
+
+DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
+
+int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,
+                                   const EVP_MD *type, unsigned char *md,
+                                   unsigned int *len);
+# ifndef OPENSSL_NO_STDIO
+PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7);
+int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7);
+# endif
+PKCS7 *PKCS7_dup(PKCS7 *p7);
+PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7);
+int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7);
+int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
+int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
+
+DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO)
+DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
+DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNED)
+DECLARE_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT)
+DECLARE_ASN1_FUNCTIONS(PKCS7_ENVELOPE)
+DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE)
+DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST)
+DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT)
+DECLARE_ASN1_FUNCTIONS(PKCS7)
+
+DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN)
+DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY)
+
+DECLARE_ASN1_NDEF_FUNCTION(PKCS7)
+DECLARE_ASN1_PRINT_FUNCTION(PKCS7)
+
+long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg);
+
+int PKCS7_set_type(PKCS7 *p7, int type);
+int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other);
+int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data);
+int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
+                          const EVP_MD *dgst);
+int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si);
+int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i);
+int PKCS7_add_certificate(PKCS7 *p7, X509 *x509);
+int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509);
+int PKCS7_content_new(PKCS7 *p7, int nid);
+int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx,
+                     BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si);
+int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
+                          X509 *x509);
+
+BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio);
+int PKCS7_dataFinal(PKCS7 *p7, BIO *bio);
+BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert);
+
+PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509,
+                                       EVP_PKEY *pkey, const EVP_MD *dgst);
+X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
+int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md);
+STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7);
+
+PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509);
+void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
+                                 X509_ALGOR **pdig, X509_ALGOR **psig);
+void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc);
+int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri);
+int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509);
+int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher);
+int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7);
+
+PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx);
+ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk);
+int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int type,
+                               void *data);
+int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
+                        void *value);
+ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid);
+ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid);
+int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
+                                STACK_OF(X509_ATTRIBUTE) *sk);
+int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,
+                         STACK_OF(X509_ATTRIBUTE) *sk);
+
+PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
+                  BIO *data, int flags);
+
+PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7,
+                                         X509 *signcert, EVP_PKEY *pkey,
+                                         const EVP_MD *md, int flags);
+
+int PKCS7_final(PKCS7 *p7, BIO *data, int flags);
+int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
+                 BIO *indata, BIO *out, int flags);
+STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs,
+                                   int flags);
+PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
+                     int flags);
+int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data,
+                  int flags);
+
+int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si,
+                              STACK_OF(X509_ALGOR) *cap);
+STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si);
+int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg);
+
+int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid);
+int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t);
+int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
+                             const unsigned char *md, int mdlen);
+
+int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags);
+PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont);
+
+BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_PKCS7_strings(void);
+
+/* Error codes for the PKCS7 functions. */
+
+/* Function codes. */
+# define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB                   136
+# define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME           135
+# define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP                118
+# define PKCS7_F_PKCS7_ADD_CERTIFICATE                    100
+# define PKCS7_F_PKCS7_ADD_CRL                            101
+# define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO                 102
+# define PKCS7_F_PKCS7_ADD_SIGNATURE                      131
+# define PKCS7_F_PKCS7_ADD_SIGNER                         103
+# define PKCS7_F_PKCS7_BIO_ADD_DIGEST                     125
+# define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST               138
+# define PKCS7_F_PKCS7_CTRL                               104
+# define PKCS7_F_PKCS7_DATADECODE                         112
+# define PKCS7_F_PKCS7_DATAFINAL                          128
+# define PKCS7_F_PKCS7_DATAINIT                           105
+# define PKCS7_F_PKCS7_DATAVERIFY                         107
+# define PKCS7_F_PKCS7_DECRYPT                            114
+# define PKCS7_F_PKCS7_DECRYPT_RINFO                      133
+# define PKCS7_F_PKCS7_ENCODE_RINFO                       132
+# define PKCS7_F_PKCS7_ENCRYPT                            115
+# define PKCS7_F_PKCS7_FINAL                              134
+# define PKCS7_F_PKCS7_FIND_DIGEST                        127
+# define PKCS7_F_PKCS7_GET0_SIGNERS                       124
+# define PKCS7_F_PKCS7_RECIP_INFO_SET                     130
+# define PKCS7_F_PKCS7_SET_CIPHER                         108
+# define PKCS7_F_PKCS7_SET_CONTENT                        109
+# define PKCS7_F_PKCS7_SET_DIGEST                         126
+# define PKCS7_F_PKCS7_SET_TYPE                           110
+# define PKCS7_F_PKCS7_SIGN                               116
+# define PKCS7_F_PKCS7_SIGNATUREVERIFY                    113
+# define PKCS7_F_PKCS7_SIGNER_INFO_SET                    129
+# define PKCS7_F_PKCS7_SIGNER_INFO_SIGN                   139
+# define PKCS7_F_PKCS7_SIGN_ADD_SIGNER                    137
+# define PKCS7_F_PKCS7_SIMPLE_SMIMECAP                    119
+# define PKCS7_F_PKCS7_VERIFY                             117
+
+/* Reason codes. */
+# define PKCS7_R_CERTIFICATE_VERIFY_ERROR                 117
+# define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER          144
+# define PKCS7_R_CIPHER_NOT_INITIALIZED                   116
+# define PKCS7_R_CONTENT_AND_DATA_PRESENT                 118
+# define PKCS7_R_CTRL_ERROR                               152
+# define PKCS7_R_DECRYPT_ERROR                            119
+# define PKCS7_R_DIGEST_FAILURE                           101
+# define PKCS7_R_ENCRYPTION_CTRL_FAILURE                  149
+# define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150
+# define PKCS7_R_ERROR_ADDING_RECIPIENT                   120
+# define PKCS7_R_ERROR_SETTING_CIPHER                     121
+# define PKCS7_R_INVALID_NULL_POINTER                     143
+# define PKCS7_R_INVALID_SIGNED_DATA_TYPE                 155
+# define PKCS7_R_NO_CONTENT                               122
+# define PKCS7_R_NO_DEFAULT_DIGEST                        151
+# define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND            154
+# define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE         115
+# define PKCS7_R_NO_SIGNATURES_ON_DATA                    123
+# define PKCS7_R_NO_SIGNERS                               142
+# define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE     104
+# define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR                124
+# define PKCS7_R_PKCS7_ADD_SIGNER_ERROR                   153
+# define PKCS7_R_PKCS7_DATASIGN                           145
+# define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE   127
+# define PKCS7_R_SIGNATURE_FAILURE                        105
+# define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND             128
+# define PKCS7_R_SIGNING_CTRL_FAILURE                     147
+# define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE  148
+# define PKCS7_R_SMIME_TEXT_ERROR                         129
+# define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE               106
+# define PKCS7_R_UNABLE_TO_FIND_MEM_BIO                   107
+# define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST            108
+# define PKCS7_R_UNKNOWN_DIGEST_TYPE                      109
+# define PKCS7_R_UNKNOWN_OPERATION                        110
+# define PKCS7_R_UNSUPPORTED_CIPHER_TYPE                  111
+# define PKCS7_R_UNSUPPORTED_CONTENT_TYPE                 112
+# define PKCS7_R_WRONG_CONTENT_TYPE                       113
+# define PKCS7_R_WRONG_PKCS7_TYPE                         114
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/rand.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/rand.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/rand.h	(revision 331)
@@ -0,0 +1,89 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_RAND_H
+# define HEADER_RAND_H
+
+# include <stdlib.h>
+# include <openssl/ossl_typ.h>
+# include <openssl/e_os2.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Already defined in ossl_typ.h */
+/* typedef struct rand_meth_st RAND_METHOD; */
+
+struct rand_meth_st {
+    int (*seed) (const void *buf, int num);
+    int (*bytes) (unsigned char *buf, int num);
+    void (*cleanup) (void);
+    int (*add) (const void *buf, int num, double entropy);
+    int (*pseudorand) (unsigned char *buf, int num);
+    int (*status) (void);
+};
+
+# ifdef BN_DEBUG
+extern int rand_predictable;
+# endif
+
+int RAND_set_rand_method(const RAND_METHOD *meth);
+const RAND_METHOD *RAND_get_rand_method(void);
+# ifndef OPENSSL_NO_ENGINE
+int RAND_set_rand_engine(ENGINE *engine);
+# endif
+RAND_METHOD *RAND_OpenSSL(void);
+#if OPENSSL_API_COMPAT < 0x10100000L
+# define RAND_cleanup() while(0) continue
+#endif
+int RAND_bytes(unsigned char *buf, int num);
+DEPRECATEDIN_1_1_0(int RAND_pseudo_bytes(unsigned char *buf, int num))
+void RAND_seed(const void *buf, int num);
+#if defined(__ANDROID__) && defined(__NDK_FPABI__)
+__NDK_FPABI__	/* __attribute__((pcs("aapcs"))) on ARM */
+#endif
+void RAND_add(const void *buf, int num, double entropy);
+int RAND_load_file(const char *file, long max_bytes);
+int RAND_write_file(const char *file);
+const char *RAND_file_name(char *file, size_t num);
+int RAND_status(void);
+# ifndef OPENSSL_NO_EGD
+int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes);
+int RAND_egd(const char *path);
+int RAND_egd_bytes(const char *path, int bytes);
+# endif
+int RAND_poll(void);
+
+#if defined(_WIN32) && (defined(BASETYPES) || defined(_WINDEF_H))
+/* application has to include <windows.h> in order to use these */
+DEPRECATEDIN_1_1_0(void RAND_screen(void))
+DEPRECATEDIN_1_1_0(int RAND_event(UINT, WPARAM, LPARAM))
+#endif
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_RAND_strings(void);
+
+/* Error codes for the RAND functions. */
+
+/* Function codes. */
+# define RAND_F_RAND_BYTES                                100
+
+/* Reason codes. */
+# define RAND_R_PRNG_NOT_SEEDED                           100
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/rc2.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/rc2.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/rc2.h	(revision 331)
@@ -0,0 +1,51 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_RC2_H
+# define HEADER_RC2_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_RC2
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+typedef unsigned int RC2_INT;
+
+# define RC2_ENCRYPT     1
+# define RC2_DECRYPT     0
+
+# define RC2_BLOCK       8
+# define RC2_KEY_LENGTH  16
+
+typedef struct rc2_key_st {
+    RC2_INT data[64];
+} RC2_KEY;
+
+void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits);
+void RC2_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                     RC2_KEY *key, int enc);
+void RC2_encrypt(unsigned long *data, RC2_KEY *key);
+void RC2_decrypt(unsigned long *data, RC2_KEY *key);
+void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+                     RC2_KEY *ks, unsigned char *iv, int enc);
+void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                       long length, RC2_KEY *schedule, unsigned char *ivec,
+                       int *num, int enc);
+void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+                       long length, RC2_KEY *schedule, unsigned char *ivec,
+                       int *num);
+
+# ifdef  __cplusplus
+}
+# endif
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/rc4.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/rc4.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/rc4.h	(revision 331)
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_RC4_H
+# define HEADER_RC4_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_RC4
+# include <stddef.h>
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct rc4_key_st {
+    RC4_INT x, y;
+    RC4_INT data[256];
+} RC4_KEY;
+
+const char *RC4_options(void);
+void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
+void RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
+         unsigned char *outdata);
+
+# ifdef  __cplusplus
+}
+# endif
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/rc5.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/rc5.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/rc5.h	(revision 331)
@@ -0,0 +1,63 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_RC5_H
+# define HEADER_RC5_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_RC5
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+# define RC5_ENCRYPT     1
+# define RC5_DECRYPT     0
+
+# define RC5_32_INT unsigned int
+
+# define RC5_32_BLOCK            8
+# define RC5_32_KEY_LENGTH       16/* This is a default, max is 255 */
+
+/*
+ * This are the only values supported.  Tweak the code if you want more The
+ * most supported modes will be RC5-32/12/16 RC5-32/16/8
+ */
+# define RC5_8_ROUNDS    8
+# define RC5_12_ROUNDS   12
+# define RC5_16_ROUNDS   16
+
+typedef struct rc5_key_st {
+    /* Number of rounds */
+    int rounds;
+    RC5_32_INT data[2 * (RC5_16_ROUNDS + 1)];
+} RC5_32_KEY;
+
+void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data,
+                    int rounds);
+void RC5_32_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                        RC5_32_KEY *key, int enc);
+void RC5_32_encrypt(unsigned long *data, RC5_32_KEY *key);
+void RC5_32_decrypt(unsigned long *data, RC5_32_KEY *key);
+void RC5_32_cbc_encrypt(const unsigned char *in, unsigned char *out,
+                        long length, RC5_32_KEY *ks, unsigned char *iv,
+                        int enc);
+void RC5_32_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+                          long length, RC5_32_KEY *schedule,
+                          unsigned char *ivec, int *num, int enc);
+void RC5_32_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+                          long length, RC5_32_KEY *schedule,
+                          unsigned char *ivec, int *num);
+
+# ifdef  __cplusplus
+}
+# endif
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ripemd.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ripemd.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ripemd.h	(revision 331)
@@ -0,0 +1,47 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_RIPEMD_H
+# define HEADER_RIPEMD_H
+
+# include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_NO_RMD160
+# include <openssl/e_os2.h>
+# include <stddef.h>
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+# define RIPEMD160_LONG unsigned int
+
+# define RIPEMD160_CBLOCK        64
+# define RIPEMD160_LBLOCK        (RIPEMD160_CBLOCK/4)
+# define RIPEMD160_DIGEST_LENGTH 20
+
+typedef struct RIPEMD160state_st {
+    RIPEMD160_LONG A, B, C, D, E;
+    RIPEMD160_LONG Nl, Nh;
+    RIPEMD160_LONG data[RIPEMD160_LBLOCK];
+    unsigned int num;
+} RIPEMD160_CTX;
+
+int RIPEMD160_Init(RIPEMD160_CTX *c);
+int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len);
+int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c);
+unsigned char *RIPEMD160(const unsigned char *d, size_t n, unsigned char *md);
+void RIPEMD160_Transform(RIPEMD160_CTX *c, const unsigned char *b);
+
+# ifdef  __cplusplus
+}
+# endif
+# endif
+
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/rsa.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/rsa.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/rsa.h	(revision 331)
@@ -0,0 +1,590 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_RSA_H
+# define HEADER_RSA_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_RSA
+# include <openssl/asn1.h>
+# include <openssl/bio.h>
+# include <openssl/crypto.h>
+# include <openssl/ossl_typ.h>
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  include <openssl/bn.h>
+# endif
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+/* The types RSA and RSA_METHOD are defined in ossl_typ.h */
+
+# ifndef OPENSSL_RSA_MAX_MODULUS_BITS
+#  define OPENSSL_RSA_MAX_MODULUS_BITS   16384
+# endif
+
+# define OPENSSL_RSA_FIPS_MIN_MODULUS_BITS 1024
+
+# ifndef OPENSSL_RSA_SMALL_MODULUS_BITS
+#  define OPENSSL_RSA_SMALL_MODULUS_BITS 3072
+# endif
+# ifndef OPENSSL_RSA_MAX_PUBEXP_BITS
+
+/* exponent limit enforced for "large" modulus only */
+#  define OPENSSL_RSA_MAX_PUBEXP_BITS    64
+# endif
+
+# define RSA_3   0x3L
+# define RSA_F4  0x10001L
+
+# define RSA_METHOD_FLAG_NO_CHECK        0x0001/* don't check pub/private
+                                                * match */
+
+# define RSA_FLAG_CACHE_PUBLIC           0x0002
+# define RSA_FLAG_CACHE_PRIVATE          0x0004
+# define RSA_FLAG_BLINDING               0x0008
+# define RSA_FLAG_THREAD_SAFE            0x0010
+/*
+ * This flag means the private key operations will be handled by rsa_mod_exp
+ * and that they do not depend on the private key components being present:
+ * for example a key stored in external hardware. Without this flag
+ * bn_mod_exp gets called when private key components are absent.
+ */
+# define RSA_FLAG_EXT_PKEY               0x0020
+
+/*
+ * new with 0.9.6j and 0.9.7b; the built-in
+ * RSA implementation now uses blinding by
+ * default (ignoring RSA_FLAG_BLINDING),
+ * but other engines might not need it
+ */
+# define RSA_FLAG_NO_BLINDING            0x0080
+# if OPENSSL_API_COMPAT < 0x10100000L
+/*
+ * Does nothing. Previously this switched off constant time behaviour.
+ */
+#  define RSA_FLAG_NO_CONSTTIME           0x0000
+# endif
+# if OPENSSL_API_COMPAT < 0x00908000L
+/* deprecated name for the flag*/
+/*
+ * new with 0.9.7h; the built-in RSA
+ * implementation now uses constant time
+ * modular exponentiation for secret exponents
+ * by default. This flag causes the
+ * faster variable sliding window method to
+ * be used for all exponents.
+ */
+#  define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME
+# endif
+
+# define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, \
+                                pad, NULL)
+
+# define EVP_PKEY_CTX_get_rsa_padding(ctx, ppad) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, \
+                                EVP_PKEY_CTRL_GET_RSA_PADDING, 0, ppad)
+
+# define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
+                                (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \
+                                EVP_PKEY_CTRL_RSA_PSS_SALTLEN, \
+                                len, NULL)
+
+# define EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, plen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
+                                (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \
+                                EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, \
+                                0, plen)
+
+# define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
+                                EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL)
+
+# define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \
+                                EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp)
+
+# define  EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md)  \
+                EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
+                        EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \
+                                EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)md)
+
+# define  EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md)  \
+                EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,  \
+                                EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)md)
+
+# define  EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, pmd) \
+                EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \
+                        EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \
+                                EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)pmd)
+
+# define  EVP_PKEY_CTX_get_rsa_oaep_md(ctx, pmd) \
+                EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,  \
+                                EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void *)pmd)
+
+# define  EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, l, llen) \
+                EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,  \
+                                EVP_PKEY_CTRL_RSA_OAEP_LABEL, llen, (void *)l)
+
+# define  EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, l)       \
+                EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,  \
+                                EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, (void *)l)
+
+# define EVP_PKEY_CTRL_RSA_PADDING       (EVP_PKEY_ALG_CTRL + 1)
+# define EVP_PKEY_CTRL_RSA_PSS_SALTLEN   (EVP_PKEY_ALG_CTRL + 2)
+
+# define EVP_PKEY_CTRL_RSA_KEYGEN_BITS   (EVP_PKEY_ALG_CTRL + 3)
+# define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 4)
+# define EVP_PKEY_CTRL_RSA_MGF1_MD       (EVP_PKEY_ALG_CTRL + 5)
+
+# define EVP_PKEY_CTRL_GET_RSA_PADDING           (EVP_PKEY_ALG_CTRL + 6)
+# define EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN       (EVP_PKEY_ALG_CTRL + 7)
+# define EVP_PKEY_CTRL_GET_RSA_MGF1_MD           (EVP_PKEY_ALG_CTRL + 8)
+
+# define EVP_PKEY_CTRL_RSA_OAEP_MD       (EVP_PKEY_ALG_CTRL + 9)
+# define EVP_PKEY_CTRL_RSA_OAEP_LABEL    (EVP_PKEY_ALG_CTRL + 10)
+
+# define EVP_PKEY_CTRL_GET_RSA_OAEP_MD   (EVP_PKEY_ALG_CTRL + 11)
+# define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12)
+
+# define RSA_PKCS1_PADDING       1
+# define RSA_SSLV23_PADDING      2
+# define RSA_NO_PADDING          3
+# define RSA_PKCS1_OAEP_PADDING  4
+# define RSA_X931_PADDING        5
+/* EVP_PKEY_ only */
+# define RSA_PKCS1_PSS_PADDING   6
+
+# define RSA_PKCS1_PADDING_SIZE  11
+
+# define RSA_set_app_data(s,arg)         RSA_set_ex_data(s,0,arg)
+# define RSA_get_app_data(s)             RSA_get_ex_data(s,0)
+
+RSA *RSA_new(void);
+RSA *RSA_new_method(ENGINE *engine);
+int RSA_bits(const RSA *rsa);
+int RSA_size(const RSA *rsa);
+int RSA_security_bits(const RSA *rsa);
+
+int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d);
+int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q);
+int RSA_set0_crt_params(RSA *r,BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp);
+void RSA_get0_key(const RSA *r,
+                  const BIGNUM **n, const BIGNUM **e, const BIGNUM **d);
+void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q);
+void RSA_get0_crt_params(const RSA *r,
+                         const BIGNUM **dmp1, const BIGNUM **dmq1,
+                         const BIGNUM **iqmp);
+void RSA_clear_flags(RSA *r, int flags);
+int RSA_test_flags(const RSA *r, int flags);
+void RSA_set_flags(RSA *r, int flags);
+ENGINE *RSA_get0_engine(const RSA *r);
+
+/* Deprecated version */
+DEPRECATEDIN_0_9_8(RSA *RSA_generate_key(int bits, unsigned long e, void
+                                         (*callback) (int, int, void *),
+                                         void *cb_arg))
+
+/* New version */
+int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
+
+int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1,
+                       BIGNUM *q2, const BIGNUM *Xp1, const BIGNUM *Xp2,
+                       const BIGNUM *Xp, const BIGNUM *Xq1, const BIGNUM *Xq2,
+                       const BIGNUM *Xq, const BIGNUM *e, BN_GENCB *cb);
+int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e,
+                             BN_GENCB *cb);
+
+int RSA_check_key(const RSA *);
+int RSA_check_key_ex(const RSA *, BN_GENCB *cb);
+        /* next 4 return -1 on error */
+int RSA_public_encrypt(int flen, const unsigned char *from,
+                       unsigned char *to, RSA *rsa, int padding);
+int RSA_private_encrypt(int flen, const unsigned char *from,
+                        unsigned char *to, RSA *rsa, int padding);
+int RSA_public_decrypt(int flen, const unsigned char *from,
+                       unsigned char *to, RSA *rsa, int padding);
+int RSA_private_decrypt(int flen, const unsigned char *from,
+                        unsigned char *to, RSA *rsa, int padding);
+void RSA_free(RSA *r);
+/* "up" the RSA object's reference count */
+int RSA_up_ref(RSA *r);
+
+int RSA_flags(const RSA *r);
+
+void RSA_set_default_method(const RSA_METHOD *meth);
+const RSA_METHOD *RSA_get_default_method(void);
+const RSA_METHOD *RSA_get_method(const RSA *rsa);
+int RSA_set_method(RSA *rsa, const RSA_METHOD *meth);
+
+/* these are the actual RSA functions */
+const RSA_METHOD *RSA_PKCS1_OpenSSL(void);
+
+const RSA_METHOD *RSA_null_method(void);
+
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPublicKey)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPrivateKey)
+
+typedef struct rsa_pss_params_st {
+    X509_ALGOR *hashAlgorithm;
+    X509_ALGOR *maskGenAlgorithm;
+    ASN1_INTEGER *saltLength;
+    ASN1_INTEGER *trailerField;
+} RSA_PSS_PARAMS;
+
+DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS)
+
+typedef struct rsa_oaep_params_st {
+    X509_ALGOR *hashFunc;
+    X509_ALGOR *maskGenFunc;
+    X509_ALGOR *pSourceFunc;
+} RSA_OAEP_PARAMS;
+
+DECLARE_ASN1_FUNCTIONS(RSA_OAEP_PARAMS)
+
+# ifndef OPENSSL_NO_STDIO
+int RSA_print_fp(FILE *fp, const RSA *r, int offset);
+# endif
+
+int RSA_print(BIO *bp, const RSA *r, int offset);
+
+/*
+ * The following 2 functions sign and verify a X509_SIG ASN1 object inside
+ * PKCS#1 padded RSA encryption
+ */
+int RSA_sign(int type, const unsigned char *m, unsigned int m_length,
+             unsigned char *sigret, unsigned int *siglen, RSA *rsa);
+int RSA_verify(int type, const unsigned char *m, unsigned int m_length,
+               const unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
+
+/*
+ * The following 2 function sign and verify a ASN1_OCTET_STRING object inside
+ * PKCS#1 padded RSA encryption
+ */
+int RSA_sign_ASN1_OCTET_STRING(int type,
+                               const unsigned char *m, unsigned int m_length,
+                               unsigned char *sigret, unsigned int *siglen,
+                               RSA *rsa);
+int RSA_verify_ASN1_OCTET_STRING(int type, const unsigned char *m,
+                                 unsigned int m_length, unsigned char *sigbuf,
+                                 unsigned int siglen, RSA *rsa);
+
+int RSA_blinding_on(RSA *rsa, BN_CTX *ctx);
+void RSA_blinding_off(RSA *rsa);
+BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx);
+
+int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen,
+                                 const unsigned char *f, int fl);
+int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen,
+                                   const unsigned char *f, int fl,
+                                   int rsa_len);
+int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen,
+                                 const unsigned char *f, int fl);
+int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
+                                   const unsigned char *f, int fl,
+                                   int rsa_len);
+int PKCS1_MGF1(unsigned char *mask, long len, const unsigned char *seed,
+               long seedlen, const EVP_MD *dgst);
+int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
+                               const unsigned char *f, int fl,
+                               const unsigned char *p, int pl);
+int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
+                                 const unsigned char *f, int fl, int rsa_len,
+                                 const unsigned char *p, int pl);
+int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
+                                    const unsigned char *from, int flen,
+                                    const unsigned char *param, int plen,
+                                    const EVP_MD *md, const EVP_MD *mgf1md);
+int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
+                                      const unsigned char *from, int flen,
+                                      int num, const unsigned char *param,
+                                      int plen, const EVP_MD *md,
+                                      const EVP_MD *mgf1md);
+int RSA_padding_add_SSLv23(unsigned char *to, int tlen,
+                           const unsigned char *f, int fl);
+int RSA_padding_check_SSLv23(unsigned char *to, int tlen,
+                             const unsigned char *f, int fl, int rsa_len);
+int RSA_padding_add_none(unsigned char *to, int tlen, const unsigned char *f,
+                         int fl);
+int RSA_padding_check_none(unsigned char *to, int tlen,
+                           const unsigned char *f, int fl, int rsa_len);
+int RSA_padding_add_X931(unsigned char *to, int tlen, const unsigned char *f,
+                         int fl);
+int RSA_padding_check_X931(unsigned char *to, int tlen,
+                           const unsigned char *f, int fl, int rsa_len);
+int RSA_X931_hash_id(int nid);
+
+int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
+                         const EVP_MD *Hash, const unsigned char *EM,
+                         int sLen);
+int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
+                              const unsigned char *mHash, const EVP_MD *Hash,
+                              int sLen);
+
+int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
+                              const EVP_MD *Hash, const EVP_MD *mgf1Hash,
+                              const unsigned char *EM, int sLen);
+
+int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
+                                   const unsigned char *mHash,
+                                   const EVP_MD *Hash, const EVP_MD *mgf1Hash,
+                                   int sLen);
+
+#define RSA_get_ex_new_index(l, p, newf, dupf, freef) \
+    CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, l, p, newf, dupf, freef)
+int RSA_set_ex_data(RSA *r, int idx, void *arg);
+void *RSA_get_ex_data(const RSA *r, int idx);
+
+RSA *RSAPublicKey_dup(RSA *rsa);
+RSA *RSAPrivateKey_dup(RSA *rsa);
+
+/*
+ * If this flag is set the RSA method is FIPS compliant and can be used in
+ * FIPS mode. This is set in the validated module method. If an application
+ * sets this flag in its own methods it is its responsibility to ensure the
+ * result is compliant.
+ */
+
+# define RSA_FLAG_FIPS_METHOD                    0x0400
+
+/*
+ * If this flag is set the operations normally disabled in FIPS mode are
+ * permitted it is then the applications responsibility to ensure that the
+ * usage is compliant.
+ */
+
+# define RSA_FLAG_NON_FIPS_ALLOW                 0x0400
+/*
+ * Application has decided PRNG is good enough to generate a key: don't
+ * check.
+ */
+# define RSA_FLAG_CHECKED                        0x0800
+
+RSA_METHOD *RSA_meth_new(const char *name, int flags);
+void RSA_meth_free(RSA_METHOD *meth);
+RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth);
+const char *RSA_meth_get0_name(const RSA_METHOD *meth);
+int RSA_meth_set1_name(RSA_METHOD *meth, const char *name);
+int RSA_meth_get_flags(RSA_METHOD *meth);
+int RSA_meth_set_flags(RSA_METHOD *meth, int flags);
+void *RSA_meth_get0_app_data(const RSA_METHOD *meth);
+int RSA_meth_set0_app_data(RSA_METHOD *meth, void *app_data);
+int (*RSA_meth_get_pub_enc(const RSA_METHOD *meth))
+    (int flen, const unsigned char *from,
+     unsigned char *to, RSA *rsa, int padding);
+int RSA_meth_set_pub_enc(RSA_METHOD *rsa,
+                         int (*pub_enc) (int flen, const unsigned char *from,
+                                         unsigned char *to, RSA *rsa,
+                                         int padding));
+int (*RSA_meth_get_pub_dec(const RSA_METHOD *meth))
+    (int flen, const unsigned char *from,
+     unsigned char *to, RSA *rsa, int padding);
+int RSA_meth_set_pub_dec(RSA_METHOD *rsa,
+                         int (*pub_dec) (int flen, const unsigned char *from,
+                                         unsigned char *to, RSA *rsa,
+                                         int padding));
+int (*RSA_meth_get_priv_enc(const RSA_METHOD *meth))
+    (int flen, const unsigned char *from,
+     unsigned char *to, RSA *rsa, int padding);
+int RSA_meth_set_priv_enc(RSA_METHOD *rsa,
+                          int (*priv_enc) (int flen, const unsigned char *from,
+                                           unsigned char *to, RSA *rsa,
+                                           int padding));
+int (*RSA_meth_get_priv_dec(const RSA_METHOD *meth))
+    (int flen, const unsigned char *from,
+     unsigned char *to, RSA *rsa, int padding);
+int RSA_meth_set_priv_dec(RSA_METHOD *rsa,
+                          int (*priv_dec) (int flen, const unsigned char *from,
+                                           unsigned char *to, RSA *rsa,
+                                           int padding));
+int (*RSA_meth_get_mod_exp(const RSA_METHOD *meth))
+    (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);
+int RSA_meth_set_mod_exp(RSA_METHOD *rsa,
+                         int (*mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa,
+                                         BN_CTX *ctx));
+int (*RSA_meth_get_bn_mod_exp(const RSA_METHOD *meth))
+    (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+     const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int RSA_meth_set_bn_mod_exp(RSA_METHOD *rsa,
+                            int (*bn_mod_exp) (BIGNUM *r,
+                                               const BIGNUM *a,
+                                               const BIGNUM *p,
+                                               const BIGNUM *m,
+                                               BN_CTX *ctx,
+                                               BN_MONT_CTX *m_ctx));
+int (*RSA_meth_get_init(const RSA_METHOD *meth)) (RSA *rsa);
+int RSA_meth_set_init(RSA_METHOD *rsa, int (*init) (RSA *rsa));
+int (*RSA_meth_get_finish(const RSA_METHOD *meth)) (RSA *rsa);
+int RSA_meth_set_finish(RSA_METHOD *rsa, int (*finish) (RSA *rsa));
+int (*RSA_meth_get_sign(const RSA_METHOD *meth))
+    (int type,
+     const unsigned char *m, unsigned int m_length,
+     unsigned char *sigret, unsigned int *siglen,
+     const RSA *rsa);
+int RSA_meth_set_sign(RSA_METHOD *rsa,
+                      int (*sign) (int type, const unsigned char *m,
+                                   unsigned int m_length,
+                                   unsigned char *sigret, unsigned int *siglen,
+                                   const RSA *rsa));
+int (*RSA_meth_get_verify(const RSA_METHOD *meth))
+    (int dtype, const unsigned char *m,
+     unsigned int m_length, const unsigned char *sigbuf,
+     unsigned int siglen, const RSA *rsa);
+int RSA_meth_set_verify(RSA_METHOD *rsa,
+                        int (*verify) (int dtype, const unsigned char *m,
+                                       unsigned int m_length,
+                                       const unsigned char *sigbuf,
+                                       unsigned int siglen, const RSA *rsa));
+int (*RSA_meth_get_keygen(const RSA_METHOD *meth))
+    (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
+int RSA_meth_set_keygen(RSA_METHOD *rsa,
+                        int (*keygen) (RSA *rsa, int bits, BIGNUM *e,
+                                       BN_GENCB *cb));
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_RSA_strings(void);
+
+/* Error codes for the RSA functions. */
+
+/* Function codes. */
+# define RSA_F_CHECK_PADDING_MD                           140
+# define RSA_F_ENCODE_PKCS1                               146
+# define RSA_F_INT_RSA_VERIFY                             145
+# define RSA_F_OLD_RSA_PRIV_DECODE                        147
+# define RSA_F_PKEY_RSA_CTRL                              143
+# define RSA_F_PKEY_RSA_CTRL_STR                          144
+# define RSA_F_PKEY_RSA_SIGN                              142
+# define RSA_F_PKEY_RSA_VERIFY                            149
+# define RSA_F_PKEY_RSA_VERIFYRECOVER                     141
+# define RSA_F_RSA_ALGOR_TO_MD                            156
+# define RSA_F_RSA_BUILTIN_KEYGEN                         129
+# define RSA_F_RSA_CHECK_KEY                              123
+# define RSA_F_RSA_CHECK_KEY_EX                           160
+# define RSA_F_RSA_CMS_DECRYPT                            159
+# define RSA_F_RSA_ITEM_VERIFY                            148
+# define RSA_F_RSA_METH_DUP                               161
+# define RSA_F_RSA_METH_NEW                               162
+# define RSA_F_RSA_METH_SET1_NAME                         163
+# define RSA_F_RSA_MGF1_TO_MD                             157
+# define RSA_F_RSA_NEW_METHOD                             106
+# define RSA_F_RSA_NULL                                   124
+# define RSA_F_RSA_NULL_PRIVATE_DECRYPT                   132
+# define RSA_F_RSA_NULL_PRIVATE_ENCRYPT                   133
+# define RSA_F_RSA_NULL_PUBLIC_DECRYPT                    134
+# define RSA_F_RSA_NULL_PUBLIC_ENCRYPT                    135
+# define RSA_F_RSA_OSSL_PRIVATE_DECRYPT                   101
+# define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT                   102
+# define RSA_F_RSA_OSSL_PUBLIC_DECRYPT                    103
+# define RSA_F_RSA_OSSL_PUBLIC_ENCRYPT                    104
+# define RSA_F_RSA_PADDING_ADD_NONE                       107
+# define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP                 121
+# define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1            154
+# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS                  125
+# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1             152
+# define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1               108
+# define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2               109
+# define RSA_F_RSA_PADDING_ADD_SSLV23                     110
+# define RSA_F_RSA_PADDING_ADD_X931                       127
+# define RSA_F_RSA_PADDING_CHECK_NONE                     111
+# define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP               122
+# define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1          153
+# define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1             112
+# define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2             113
+# define RSA_F_RSA_PADDING_CHECK_SSLV23                   114
+# define RSA_F_RSA_PADDING_CHECK_X931                     128
+# define RSA_F_RSA_PRINT                                  115
+# define RSA_F_RSA_PRINT_FP                               116
+# define RSA_F_RSA_PRIV_ENCODE                            138
+# define RSA_F_RSA_PSS_TO_CTX                             155
+# define RSA_F_RSA_PUB_DECODE                             139
+# define RSA_F_RSA_SETUP_BLINDING                         136
+# define RSA_F_RSA_SIGN                                   117
+# define RSA_F_RSA_SIGN_ASN1_OCTET_STRING                 118
+# define RSA_F_RSA_VERIFY                                 119
+# define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING               120
+# define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1                  126
+
+/* Reason codes. */
+# define RSA_R_ALGORITHM_MISMATCH                         100
+# define RSA_R_BAD_E_VALUE                                101
+# define RSA_R_BAD_FIXED_HEADER_DECRYPT                   102
+# define RSA_R_BAD_PAD_BYTE_COUNT                         103
+# define RSA_R_BAD_SIGNATURE                              104
+# define RSA_R_BLOCK_TYPE_IS_NOT_01                       106
+# define RSA_R_BLOCK_TYPE_IS_NOT_02                       107
+# define RSA_R_DATA_GREATER_THAN_MOD_LEN                  108
+# define RSA_R_DATA_TOO_LARGE                             109
+# define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE                110
+# define RSA_R_DATA_TOO_LARGE_FOR_MODULUS                 132
+# define RSA_R_DATA_TOO_SMALL                             111
+# define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE                122
+# define RSA_R_DIGEST_DOES_NOT_MATCH                      158
+# define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY                 112
+# define RSA_R_DMP1_NOT_CONGRUENT_TO_D                    124
+# define RSA_R_DMQ1_NOT_CONGRUENT_TO_D                    125
+# define RSA_R_D_E_NOT_CONGRUENT_TO_1                     123
+# define RSA_R_FIRST_OCTET_INVALID                        133
+# define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE        144
+# define RSA_R_INVALID_DIGEST                             157
+# define RSA_R_INVALID_DIGEST_LENGTH                      143
+# define RSA_R_INVALID_HEADER                             137
+# define RSA_R_INVALID_LABEL                              160
+# define RSA_R_INVALID_MESSAGE_LENGTH                     131
+# define RSA_R_INVALID_MGF1_MD                            156
+# define RSA_R_INVALID_OAEP_PARAMETERS                    161
+# define RSA_R_INVALID_PADDING                            138
+# define RSA_R_INVALID_PADDING_MODE                       141
+# define RSA_R_INVALID_PSS_PARAMETERS                     149
+# define RSA_R_INVALID_PSS_SALTLEN                        146
+# define RSA_R_INVALID_SALT_LENGTH                        150
+# define RSA_R_INVALID_TRAILER                            139
+# define RSA_R_INVALID_X931_DIGEST                        142
+# define RSA_R_IQMP_NOT_INVERSE_OF_Q                      126
+# define RSA_R_KEY_SIZE_TOO_SMALL                         120
+# define RSA_R_LAST_OCTET_INVALID                         134
+# define RSA_R_MODULUS_TOO_LARGE                          105
+# define RSA_R_NO_PUBLIC_EXPONENT                         140
+# define RSA_R_NULL_BEFORE_BLOCK_MISSING                  113
+# define RSA_R_N_DOES_NOT_EQUAL_P_Q                       127
+# define RSA_R_OAEP_DECODING_ERROR                        121
+# define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE   148
+# define RSA_R_PADDING_CHECK_FAILED                       114
+# define RSA_R_PKCS_DECODING_ERROR                        159
+# define RSA_R_P_NOT_PRIME                                128
+# define RSA_R_Q_NOT_PRIME                                129
+# define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED               130
+# define RSA_R_SLEN_CHECK_FAILED                          136
+# define RSA_R_SLEN_RECOVERY_FAILED                       135
+# define RSA_R_SSLV3_ROLLBACK_ATTACK                      115
+# define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116
+# define RSA_R_UNKNOWN_ALGORITHM_TYPE                     117
+# define RSA_R_UNKNOWN_DIGEST                             166
+# define RSA_R_UNKNOWN_MASK_DIGEST                        151
+# define RSA_R_UNKNOWN_PADDING_TYPE                       118
+# define RSA_R_UNSUPPORTED_ENCRYPTION_TYPE                162
+# define RSA_R_UNSUPPORTED_LABEL_SOURCE                   163
+# define RSA_R_UNSUPPORTED_MASK_ALGORITHM                 153
+# define RSA_R_UNSUPPORTED_MASK_PARAMETER                 154
+# define RSA_R_UNSUPPORTED_SIGNATURE_TYPE                 155
+# define RSA_R_VALUE_MISSING                              147
+# define RSA_R_WRONG_SIGNATURE_LENGTH                     119
+
+#  ifdef  __cplusplus
+}
+#  endif
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/safestack.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/safestack.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/safestack.h	(revision 331)
@@ -0,0 +1,164 @@
+/*
+ * Copyright 1999-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
+ */
+
+#ifndef HEADER_SAFESTACK_H
+# define HEADER_SAFESTACK_H
+
+# include <openssl/stack.h>
+# include <openssl/e_os2.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# define STACK_OF(type) struct stack_st_##type
+
+# define SKM_DEFINE_STACK_OF(t1, t2, t3) \
+    STACK_OF(t1); \
+    typedef int (*sk_##t1##_compfunc)(const t3 * const *a, const t3 *const *b); \
+    typedef void (*sk_##t1##_freefunc)(t3 *a); \
+    typedef t3 * (*sk_##t1##_copyfunc)(const t3 *a); \
+    static ossl_inline int sk_##t1##_num(const STACK_OF(t1) *sk) \
+    { \
+        return OPENSSL_sk_num((const OPENSSL_STACK *)sk); \
+    } \
+    static ossl_inline t2 *sk_##t1##_value(const STACK_OF(t1) *sk, int idx) \
+    { \
+        return (t2 *)OPENSSL_sk_value((const OPENSSL_STACK *)sk, idx); \
+    } \
+    static ossl_inline STACK_OF(t1) *sk_##t1##_new(sk_##t1##_compfunc compare) \
+    { \
+        return (STACK_OF(t1) *)OPENSSL_sk_new((OPENSSL_sk_compfunc)compare); \
+    } \
+    static ossl_inline STACK_OF(t1) *sk_##t1##_new_null(void) \
+    { \
+        return (STACK_OF(t1) *)OPENSSL_sk_new_null(); \
+    } \
+    static ossl_inline void sk_##t1##_free(STACK_OF(t1) *sk) \
+    { \
+        OPENSSL_sk_free((OPENSSL_STACK *)sk); \
+    } \
+    static ossl_inline void sk_##t1##_zero(STACK_OF(t1) *sk) \
+    { \
+        OPENSSL_sk_zero((OPENSSL_STACK *)sk); \
+    } \
+    static ossl_inline t2 *sk_##t1##_delete(STACK_OF(t1) *sk, int i) \
+    { \
+        return (t2 *)OPENSSL_sk_delete((OPENSSL_STACK *)sk, i); \
+    } \
+    static ossl_inline t2 *sk_##t1##_delete_ptr(STACK_OF(t1) *sk, t2 *ptr) \
+    { \
+        return (t2 *)OPENSSL_sk_delete_ptr((OPENSSL_STACK *)sk, \
+                                           (const void *)ptr); \
+    } \
+    static ossl_inline int sk_##t1##_push(STACK_OF(t1) *sk, t2 *ptr) \
+    { \
+        return OPENSSL_sk_push((OPENSSL_STACK *)sk, (const void *)ptr); \
+    } \
+    static ossl_inline int sk_##t1##_unshift(STACK_OF(t1) *sk, t2 *ptr) \
+    { \
+        return OPENSSL_sk_unshift((OPENSSL_STACK *)sk, (const void *)ptr); \
+    } \
+    static ossl_inline t2 *sk_##t1##_pop(STACK_OF(t1) *sk) \
+    { \
+        return (t2 *)OPENSSL_sk_pop((OPENSSL_STACK *)sk); \
+    } \
+    static ossl_inline t2 *sk_##t1##_shift(STACK_OF(t1) *sk) \
+    { \
+        return (t2 *)OPENSSL_sk_shift((OPENSSL_STACK *)sk); \
+    } \
+    static ossl_inline void sk_##t1##_pop_free(STACK_OF(t1) *sk, sk_##t1##_freefunc freefunc) \
+    { \
+        OPENSSL_sk_pop_free((OPENSSL_STACK *)sk, (OPENSSL_sk_freefunc)freefunc); \
+    } \
+    static ossl_inline int sk_##t1##_insert(STACK_OF(t1) *sk, t2 *ptr, int idx) \
+    { \
+        return OPENSSL_sk_insert((OPENSSL_STACK *)sk, (const void *)ptr, idx); \
+    } \
+    static ossl_inline t2 *sk_##t1##_set(STACK_OF(t1) *sk, int idx, t2 *ptr) \
+    { \
+        return (t2 *)OPENSSL_sk_set((OPENSSL_STACK *)sk, idx, (const void *)ptr); \
+    } \
+    static ossl_inline int sk_##t1##_find(STACK_OF(t1) *sk, t2 *ptr) \
+    { \
+        return OPENSSL_sk_find((OPENSSL_STACK *)sk, (const void *)ptr); \
+    } \
+    static ossl_inline int sk_##t1##_find_ex(STACK_OF(t1) *sk, t2 *ptr) \
+    { \
+        return OPENSSL_sk_find_ex((OPENSSL_STACK *)sk, (const void *)ptr); \
+    } \
+    static ossl_inline void sk_##t1##_sort(STACK_OF(t1) *sk) \
+    { \
+        OPENSSL_sk_sort((OPENSSL_STACK *)sk); \
+    } \
+    static ossl_inline int sk_##t1##_is_sorted(const STACK_OF(t1) *sk) \
+    { \
+        return OPENSSL_sk_is_sorted((const OPENSSL_STACK *)sk); \
+    } \
+    static ossl_inline STACK_OF(t1) * sk_##t1##_dup(const STACK_OF(t1) *sk) \
+    { \
+        return (STACK_OF(t1) *)OPENSSL_sk_dup((const OPENSSL_STACK *)sk); \
+    } \
+    static ossl_inline STACK_OF(t1) *sk_##t1##_deep_copy(const STACK_OF(t1) *sk, \
+                                                    sk_##t1##_copyfunc copyfunc, \
+                                                    sk_##t1##_freefunc freefunc) \
+    { \
+        return (STACK_OF(t1) *)OPENSSL_sk_deep_copy((const OPENSSL_STACK *)sk, \
+                                            (OPENSSL_sk_copyfunc)copyfunc, \
+                                            (OPENSSL_sk_freefunc)freefunc); \
+    } \
+    static ossl_inline sk_##t1##_compfunc sk_##t1##_set_cmp_func(STACK_OF(t1) *sk, sk_##t1##_compfunc compare) \
+    { \
+        return (sk_##t1##_compfunc)OPENSSL_sk_set_cmp_func((OPENSSL_STACK *)sk, (OPENSSL_sk_compfunc)compare); \
+    }
+
+# define DEFINE_SPECIAL_STACK_OF(t1, t2) SKM_DEFINE_STACK_OF(t1, t2, t2)
+# define DEFINE_STACK_OF(t) SKM_DEFINE_STACK_OF(t, t, t)
+# define DEFINE_SPECIAL_STACK_OF_CONST(t1, t2) \
+            SKM_DEFINE_STACK_OF(t1, const t2, t2)
+# define DEFINE_STACK_OF_CONST(t) SKM_DEFINE_STACK_OF(t, const t, t)
+
+/*-
+ * Strings are special: normally an lhash entry will point to a single
+ * (somewhat) mutable object. In the case of strings:
+ *
+ * a) Instead of a single char, there is an array of chars, NUL-terminated.
+ * b) The string may have be immutable.
+ *
+ * So, they need their own declarations. Especially important for
+ * type-checking tools, such as Deputy.
+ *
+ * In practice, however, it appears to be hard to have a const
+ * string. For now, I'm settling for dealing with the fact it is a
+ * string at all.
+ */
+typedef char *OPENSSL_STRING;
+typedef const char *OPENSSL_CSTRING;
+
+/*-
+ * Confusingly, LHASH_OF(STRING) deals with char ** throughout, but
+ * STACK_OF(STRING) is really more like STACK_OF(char), only, as mentioned
+ * above, instead of a single char each entry is a NUL-terminated array of
+ * chars. So, we have to implement STRING specially for STACK_OF. This is
+ * dealt with in the autogenerated macros below.
+ */
+DEFINE_SPECIAL_STACK_OF(OPENSSL_STRING, char)
+DEFINE_SPECIAL_STACK_OF_CONST(OPENSSL_CSTRING, char)
+
+/*
+ * Similarly, we sometimes use a block of characters, NOT nul-terminated.
+ * These should also be distinguished from "normal" stacks.
+ */
+typedef void *OPENSSL_BLOCK;
+DEFINE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void)
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/seed.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/seed.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/seed.h	(revision 331)
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2007-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
+ */
+
+/*
+ * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Neither the name of author nor the names of its contributors may
+ *    be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef HEADER_SEED_H
+# define HEADER_SEED_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_SEED
+# include <openssl/e_os2.h>
+# include <openssl/crypto.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* look whether we need 'long' to get 32 bits */
+# ifdef AES_LONG
+#  ifndef SEED_LONG
+#   define SEED_LONG 1
+#  endif
+# endif
+
+# if !defined(NO_SYS_TYPES_H)
+#  include <sys/types.h>
+# endif
+
+# define SEED_BLOCK_SIZE 16
+# define SEED_KEY_LENGTH 16
+
+typedef struct seed_key_st {
+# ifdef SEED_LONG
+    unsigned long data[32];
+# else
+    unsigned int data[32];
+# endif
+} SEED_KEY_SCHEDULE;
+
+void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH],
+                  SEED_KEY_SCHEDULE *ks);
+
+void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE],
+                  unsigned char d[SEED_BLOCK_SIZE],
+                  const SEED_KEY_SCHEDULE *ks);
+void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE],
+                  unsigned char d[SEED_BLOCK_SIZE],
+                  const SEED_KEY_SCHEDULE *ks);
+
+void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out,
+                      const SEED_KEY_SCHEDULE *ks, int enc);
+void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len,
+                      const SEED_KEY_SCHEDULE *ks,
+                      unsigned char ivec[SEED_BLOCK_SIZE], int enc);
+void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+                         size_t len, const SEED_KEY_SCHEDULE *ks,
+                         unsigned char ivec[SEED_BLOCK_SIZE], int *num,
+                         int enc);
+void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+                         size_t len, const SEED_KEY_SCHEDULE *ks,
+                         unsigned char ivec[SEED_BLOCK_SIZE], int *num);
+
+# ifdef  __cplusplus
+}
+# endif
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/sha.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/sha.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/sha.h	(revision 331)
@@ -0,0 +1,119 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_SHA_H
+# define HEADER_SHA_H
+
+# include <openssl/e_os2.h>
+# include <stddef.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*-
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! SHA_LONG has to be at least 32 bits wide.                    !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+# define SHA_LONG unsigned int
+
+# define SHA_LBLOCK      16
+# define SHA_CBLOCK      (SHA_LBLOCK*4)/* SHA treats input data as a
+                                        * contiguous array of 32 bit wide
+                                        * big-endian values. */
+# define SHA_LAST_BLOCK  (SHA_CBLOCK-8)
+# define SHA_DIGEST_LENGTH 20
+
+typedef struct SHAstate_st {
+    SHA_LONG h0, h1, h2, h3, h4;
+    SHA_LONG Nl, Nh;
+    SHA_LONG data[SHA_LBLOCK];
+    unsigned int num;
+} SHA_CTX;
+
+int SHA1_Init(SHA_CTX *c);
+int SHA1_Update(SHA_CTX *c, const void *data, size_t len);
+int SHA1_Final(unsigned char *md, SHA_CTX *c);
+unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md);
+void SHA1_Transform(SHA_CTX *c, const unsigned char *data);
+
+# define SHA256_CBLOCK   (SHA_LBLOCK*4)/* SHA-256 treats input data as a
+                                        * contiguous array of 32 bit wide
+                                        * big-endian values. */
+
+typedef struct SHA256state_st {
+    SHA_LONG h[8];
+    SHA_LONG Nl, Nh;
+    SHA_LONG data[SHA_LBLOCK];
+    unsigned int num, md_len;
+} SHA256_CTX;
+
+int SHA224_Init(SHA256_CTX *c);
+int SHA224_Update(SHA256_CTX *c, const void *data, size_t len);
+int SHA224_Final(unsigned char *md, SHA256_CTX *c);
+unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md);
+int SHA256_Init(SHA256_CTX *c);
+int SHA256_Update(SHA256_CTX *c, const void *data, size_t len);
+int SHA256_Final(unsigned char *md, SHA256_CTX *c);
+unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md);
+void SHA256_Transform(SHA256_CTX *c, const unsigned char *data);
+
+# define SHA224_DIGEST_LENGTH    28
+# define SHA256_DIGEST_LENGTH    32
+# define SHA384_DIGEST_LENGTH    48
+# define SHA512_DIGEST_LENGTH    64
+
+/*
+ * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64
+ * being exactly 64-bit wide. See Implementation Notes in sha512.c
+ * for further details.
+ */
+/*
+ * SHA-512 treats input data as a
+ * contiguous array of 64 bit
+ * wide big-endian values.
+ */
+# define SHA512_CBLOCK   (SHA_LBLOCK*8)
+# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
+#  define SHA_LONG64 unsigned __int64
+#  define U64(C)     C##UI64
+# elif defined(__arch64__)
+#  define SHA_LONG64 unsigned long
+#  define U64(C)     C##UL
+# else
+#  define SHA_LONG64 unsigned long long
+#  define U64(C)     C##ULL
+# endif
+
+typedef struct SHA512state_st {
+    SHA_LONG64 h[8];
+    SHA_LONG64 Nl, Nh;
+    union {
+        SHA_LONG64 d[SHA_LBLOCK];
+        unsigned char p[SHA512_CBLOCK];
+    } u;
+    unsigned int num, md_len;
+} SHA512_CTX;
+
+int SHA384_Init(SHA512_CTX *c);
+int SHA384_Update(SHA512_CTX *c, const void *data, size_t len);
+int SHA384_Final(unsigned char *md, SHA512_CTX *c);
+unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md);
+int SHA512_Init(SHA512_CTX *c);
+int SHA512_Update(SHA512_CTX *c, const void *data, size_t len);
+int SHA512_Final(unsigned char *md, SHA512_CTX *c);
+unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md);
+void SHA512_Transform(SHA512_CTX *c, const unsigned char *data);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/srp.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/srp.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/srp.h	(revision 331)
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2011-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
+ */
+
+#ifndef HEADER_SRP_H
+# define HEADER_SRP_H
+
+#include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_NO_SRP
+# include <stdio.h>
+# include <string.h>
+# include <openssl/safestack.h>
+# include <openssl/bn.h>
+# include <openssl/crypto.h>
+
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+typedef struct SRP_gN_cache_st {
+    char *b64_bn;
+    BIGNUM *bn;
+} SRP_gN_cache;
+
+
+DEFINE_STACK_OF(SRP_gN_cache)
+
+typedef struct SRP_user_pwd_st {
+    /* Owned by us. */
+    char *id;
+    BIGNUM *s;
+    BIGNUM *v;
+    /* Not owned by us. */
+    const BIGNUM *g;
+    const BIGNUM *N;
+    /* Owned by us. */
+    char *info;
+} SRP_user_pwd;
+
+void SRP_user_pwd_free(SRP_user_pwd *user_pwd);
+
+DEFINE_STACK_OF(SRP_user_pwd)
+
+typedef struct SRP_VBASE_st {
+    STACK_OF(SRP_user_pwd) *users_pwd;
+    STACK_OF(SRP_gN_cache) *gN_cache;
+/* to simulate a user */
+    char *seed_key;
+    const BIGNUM *default_g;
+    const BIGNUM *default_N;
+} SRP_VBASE;
+
+/*
+ * Internal structure storing N and g pair
+ */
+typedef struct SRP_gN_st {
+    char *id;
+    const BIGNUM *g;
+    const BIGNUM *N;
+} SRP_gN;
+
+DEFINE_STACK_OF(SRP_gN)
+
+SRP_VBASE *SRP_VBASE_new(char *seed_key);
+void SRP_VBASE_free(SRP_VBASE *vb);
+int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file);
+
+/* This method ignores the configured seed and fails for an unknown user. */
+DEPRECATEDIN_1_1_0(SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username))
+/* NOTE: unlike in SRP_VBASE_get_by_user, caller owns the returned pointer.*/
+SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username);
+
+char *SRP_create_verifier(const char *user, const char *pass, char **salt,
+                          char **verifier, const char *N, const char *g);
+int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt,
+                           BIGNUM **verifier, const BIGNUM *N,
+                           const BIGNUM *g);
+
+# define SRP_NO_ERROR 0
+# define SRP_ERR_VBASE_INCOMPLETE_FILE 1
+# define SRP_ERR_VBASE_BN_LIB 2
+# define SRP_ERR_OPEN_FILE 3
+# define SRP_ERR_MEMORY 4
+
+# define DB_srptype      0
+# define DB_srpverifier  1
+# define DB_srpsalt      2
+# define DB_srpid        3
+# define DB_srpgN        4
+# define DB_srpinfo      5
+# undef  DB_NUMBER
+# define DB_NUMBER       6
+
+# define DB_SRP_INDEX    'I'
+# define DB_SRP_VALID    'V'
+# define DB_SRP_REVOKED  'R'
+# define DB_SRP_MODIF    'v'
+
+/* see srp.c */
+char *SRP_check_known_gN_param(const BIGNUM *g, const BIGNUM *N);
+SRP_gN *SRP_get_default_gN(const char *id);
+
+/* server side .... */
+BIGNUM *SRP_Calc_server_key(const BIGNUM *A, const BIGNUM *v, const BIGNUM *u,
+                            const BIGNUM *b, const BIGNUM *N);
+BIGNUM *SRP_Calc_B(const BIGNUM *b, const BIGNUM *N, const BIGNUM *g,
+                   const BIGNUM *v);
+int SRP_Verify_A_mod_N(const BIGNUM *A, const BIGNUM *N);
+BIGNUM *SRP_Calc_u(const BIGNUM *A, const BIGNUM *B, const BIGNUM *N);
+
+/* client side .... */
+BIGNUM *SRP_Calc_x(const BIGNUM *s, const char *user, const char *pass);
+BIGNUM *SRP_Calc_A(const BIGNUM *a, const BIGNUM *N, const BIGNUM *g);
+BIGNUM *SRP_Calc_client_key(const BIGNUM *N, const BIGNUM *B, const BIGNUM *g,
+                            const BIGNUM *x, const BIGNUM *a, const BIGNUM *u);
+int SRP_Verify_B_mod_N(const BIGNUM *B, const BIGNUM *N);
+
+# define SRP_MINIMAL_N 1024
+
+# ifdef  __cplusplus
+}
+# endif
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/srtp.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/srtp.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/srtp.h	(revision 331)
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2011-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
+ */
+
+/*
+ * DTLS code by Eric Rescorla <ekr@rtfm.com>
+ *
+ * Copyright (C) 2006, Network Resonance, Inc. Copyright (C) 2011, RTFM, Inc.
+ */
+
+#ifndef HEADER_D1_SRTP_H
+# define HEADER_D1_SRTP_H
+
+# include <openssl/ssl.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define SRTP_AES128_CM_SHA1_80 0x0001
+# define SRTP_AES128_CM_SHA1_32 0x0002
+# define SRTP_AES128_F8_SHA1_80 0x0003
+# define SRTP_AES128_F8_SHA1_32 0x0004
+# define SRTP_NULL_SHA1_80      0x0005
+# define SRTP_NULL_SHA1_32      0x0006
+
+/* AEAD SRTP protection profiles from RFC 7714 */
+# define SRTP_AEAD_AES_128_GCM  0x0007
+# define SRTP_AEAD_AES_256_GCM  0x0008
+
+# ifndef OPENSSL_NO_SRTP
+
+__owur int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles);
+__owur int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles);
+
+__owur STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl);
+__owur SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s);
+
+# endif
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ssl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ssl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ssl.h	(revision 331)
@@ -0,0 +1,2531 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#ifndef HEADER_SSL_H
+# define HEADER_SSL_H
+
+# include <openssl/e_os2.h>
+# include <openssl/opensslconf.h>
+# include <openssl/comp.h>
+# include <openssl/bio.h>
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  include <openssl/x509.h>
+#  include <openssl/crypto.h>
+#  include <openssl/lhash.h>
+#  include <openssl/buffer.h>
+# endif
+# include <openssl/pem.h>
+# include <openssl/hmac.h>
+# include <openssl/async.h>
+
+# include <openssl/safestack.h>
+# include <openssl/symhacks.h>
+# include <openssl/ct.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* OpenSSL version number for ASN.1 encoding of the session information */
+/*-
+ * Version 0 - initial version
+ * Version 1 - added the optional peer certificate
+ */
+# define SSL_SESSION_ASN1_VERSION 0x0001
+
+# define SSL_MAX_SSL_SESSION_ID_LENGTH           32
+# define SSL_MAX_SID_CTX_LENGTH                  32
+
+# define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES     (512/8)
+# define SSL_MAX_KEY_ARG_LENGTH                  8
+# define SSL_MAX_MASTER_KEY_LENGTH               48
+
+/* The maximum number of encrypt/decrypt pipelines we can support */
+# define SSL_MAX_PIPELINES  32
+
+/* text strings for the ciphers */
+
+/* These are used to specify which ciphers to use and not to use */
+
+# define SSL_TXT_LOW             "LOW"
+# define SSL_TXT_MEDIUM          "MEDIUM"
+# define SSL_TXT_HIGH            "HIGH"
+# define SSL_TXT_FIPS            "FIPS"
+
+# define SSL_TXT_aNULL           "aNULL"
+# define SSL_TXT_eNULL           "eNULL"
+# define SSL_TXT_NULL            "NULL"
+
+# define SSL_TXT_kRSA            "kRSA"
+# define SSL_TXT_kDHr            "kDHr"
+# define SSL_TXT_kDHd            "kDHd"
+# define SSL_TXT_kDH             "kDH"
+# define SSL_TXT_kEDH            "kEDH"/* alias for kDHE */
+# define SSL_TXT_kDHE            "kDHE"
+# define SSL_TXT_kECDHr          "kECDHr"
+# define SSL_TXT_kECDHe          "kECDHe"
+# define SSL_TXT_kECDH           "kECDH"
+# define SSL_TXT_kEECDH          "kEECDH"/* alias for kECDHE */
+# define SSL_TXT_kECDHE          "kECDHE"
+# define SSL_TXT_kPSK            "kPSK"
+# define SSL_TXT_kRSAPSK         "kRSAPSK"
+# define SSL_TXT_kECDHEPSK       "kECDHEPSK"
+# define SSL_TXT_kDHEPSK         "kDHEPSK"
+# define SSL_TXT_kGOST           "kGOST"
+# define SSL_TXT_kSRP            "kSRP"
+
+# define SSL_TXT_aRSA            "aRSA"
+# define SSL_TXT_aDSS            "aDSS"
+# define SSL_TXT_aDH             "aDH"
+# define SSL_TXT_aECDH           "aECDH"
+# define SSL_TXT_aECDSA          "aECDSA"
+# define SSL_TXT_aPSK            "aPSK"
+# define SSL_TXT_aGOST94         "aGOST94"
+# define SSL_TXT_aGOST01         "aGOST01"
+# define SSL_TXT_aGOST12         "aGOST12"
+# define SSL_TXT_aGOST           "aGOST"
+# define SSL_TXT_aSRP            "aSRP"
+
+# define SSL_TXT_DSS             "DSS"
+# define SSL_TXT_DH              "DH"
+# define SSL_TXT_DHE             "DHE"/* same as "kDHE:-ADH" */
+# define SSL_TXT_EDH             "EDH"/* alias for DHE */
+# define SSL_TXT_ADH             "ADH"
+# define SSL_TXT_RSA             "RSA"
+# define SSL_TXT_ECDH            "ECDH"
+# define SSL_TXT_EECDH           "EECDH"/* alias for ECDHE" */
+# define SSL_TXT_ECDHE           "ECDHE"/* same as "kECDHE:-AECDH" */
+# define SSL_TXT_AECDH           "AECDH"
+# define SSL_TXT_ECDSA           "ECDSA"
+# define SSL_TXT_PSK             "PSK"
+# define SSL_TXT_SRP             "SRP"
+
+# define SSL_TXT_DES             "DES"
+# define SSL_TXT_3DES            "3DES"
+# define SSL_TXT_RC4             "RC4"
+# define SSL_TXT_RC2             "RC2"
+# define SSL_TXT_IDEA            "IDEA"
+# define SSL_TXT_SEED            "SEED"
+# define SSL_TXT_AES128          "AES128"
+# define SSL_TXT_AES256          "AES256"
+# define SSL_TXT_AES             "AES"
+# define SSL_TXT_AES_GCM         "AESGCM"
+# define SSL_TXT_AES_CCM         "AESCCM"
+# define SSL_TXT_AES_CCM_8       "AESCCM8"
+# define SSL_TXT_CAMELLIA128     "CAMELLIA128"
+# define SSL_TXT_CAMELLIA256     "CAMELLIA256"
+# define SSL_TXT_CAMELLIA        "CAMELLIA"
+# define SSL_TXT_CHACHA20        "CHACHA20"
+# define SSL_TXT_GOST            "GOST89"
+
+# define SSL_TXT_MD5             "MD5"
+# define SSL_TXT_SHA1            "SHA1"
+# define SSL_TXT_SHA             "SHA"/* same as "SHA1" */
+# define SSL_TXT_GOST94          "GOST94"
+# define SSL_TXT_GOST89MAC       "GOST89MAC"
+# define SSL_TXT_GOST12          "GOST12"
+# define SSL_TXT_GOST89MAC12     "GOST89MAC12"
+# define SSL_TXT_SHA256          "SHA256"
+# define SSL_TXT_SHA384          "SHA384"
+
+# define SSL_TXT_SSLV3           "SSLv3"
+# define SSL_TXT_TLSV1           "TLSv1"
+# define SSL_TXT_TLSV1_1         "TLSv1.1"
+# define SSL_TXT_TLSV1_2         "TLSv1.2"
+
+# define SSL_TXT_ALL             "ALL"
+
+/*-
+ * COMPLEMENTOF* definitions. These identifiers are used to (de-select)
+ * ciphers normally not being used.
+ * Example: "RC4" will activate all ciphers using RC4 including ciphers
+ * without authentication, which would normally disabled by DEFAULT (due
+ * the "!ADH" being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT"
+ * will make sure that it is also disabled in the specific selection.
+ * COMPLEMENTOF* identifiers are portable between version, as adjustments
+ * to the default cipher setup will also be included here.
+ *
+ * COMPLEMENTOFDEFAULT does not experience the same special treatment that
+ * DEFAULT gets, as only selection is being done and no sorting as needed
+ * for DEFAULT.
+ */
+# define SSL_TXT_CMPALL          "COMPLEMENTOFALL"
+# define SSL_TXT_CMPDEF          "COMPLEMENTOFDEFAULT"
+
+/*
+ * The following cipher list is used by default. It also is substituted when
+ * an application-defined cipher list string starts with 'DEFAULT'.
+ */
+# define SSL_DEFAULT_CIPHER_LIST "ALL:!COMPLEMENTOFDEFAULT:!eNULL"
+/*
+ * As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always
+ * starts with a reasonable order, and all we have to do for DEFAULT is
+ * throwing out anonymous and unencrypted ciphersuites! (The latter are not
+ * actually enabled by ALL, but "ALL:RSA" would enable some of them.)
+ */
+
+/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */
+# define SSL_SENT_SHUTDOWN       1
+# define SSL_RECEIVED_SHUTDOWN   2
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define SSL_FILETYPE_ASN1       X509_FILETYPE_ASN1
+# define SSL_FILETYPE_PEM        X509_FILETYPE_PEM
+
+/*
+ * This is needed to stop compilers complaining about the 'struct ssl_st *'
+ * function parameters used to prototype callbacks in SSL_CTX.
+ */
+typedef struct ssl_st *ssl_crock_st;
+typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT;
+typedef struct ssl_method_st SSL_METHOD;
+typedef struct ssl_cipher_st SSL_CIPHER;
+typedef struct ssl_session_st SSL_SESSION;
+typedef struct tls_sigalgs_st TLS_SIGALGS;
+typedef struct ssl_conf_ctx_st SSL_CONF_CTX;
+typedef struct ssl_comp_st SSL_COMP;
+
+STACK_OF(SSL_CIPHER);
+STACK_OF(SSL_COMP);
+
+/* SRTP protection profiles for use with the use_srtp extension (RFC 5764)*/
+typedef struct srtp_protection_profile_st {
+    const char *name;
+    unsigned long id;
+} SRTP_PROTECTION_PROFILE;
+
+DEFINE_STACK_OF(SRTP_PROTECTION_PROFILE)
+
+typedef int (*tls_session_ticket_ext_cb_fn) (SSL *s,
+                                             const unsigned char *data,
+                                             int len, void *arg);
+typedef int (*tls_session_secret_cb_fn) (SSL *s, void *secret,
+                                         int *secret_len,
+                                         STACK_OF(SSL_CIPHER) *peer_ciphers,
+                                         const SSL_CIPHER **cipher, void *arg);
+
+/* Typedefs for handling custom extensions */
+
+typedef int (*custom_ext_add_cb) (SSL *s, unsigned int ext_type,
+                                  const unsigned char **out,
+                                  size_t *outlen, int *al, void *add_arg);
+
+typedef void (*custom_ext_free_cb) (SSL *s, unsigned int ext_type,
+                                    const unsigned char *out, void *add_arg);
+
+typedef int (*custom_ext_parse_cb) (SSL *s, unsigned int ext_type,
+                                    const unsigned char *in,
+                                    size_t inlen, int *al, void *parse_arg);
+
+/* Typedef for verification callback */
+typedef int (*SSL_verify_cb)(int preverify_ok, X509_STORE_CTX *x509_ctx);
+
+/* Allow initial connection to servers that don't support RI */
+# define SSL_OP_LEGACY_SERVER_CONNECT                    0x00000004U
+/* Removed from OpenSSL 0.9.8q and 1.0.0c */
+/* Dead forever, see CVE-2010-4180. */
+# define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG         0x0U
+# define SSL_OP_TLSEXT_PADDING                           0x00000010U
+# define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER               0x0U
+# define SSL_OP_SAFARI_ECDHE_ECDSA_BUG                   0x00000040U
+/* Ancient SSLeay version, retained for compatibility */
+# define SSL_OP_SSLEAY_080_CLIENT_DH_BUG                 0x0
+# define SSL_OP_TLS_D5_BUG                               0x0U
+/* Removed from OpenSSL 1.1.0 */
+# define SSL_OP_TLS_BLOCK_PADDING_BUG                    0x0U
+
+/* Hasn't done anything since OpenSSL 0.9.7h, retained for compatibility */
+# define SSL_OP_MSIE_SSLV2_RSA_PADDING                   0x0
+/* Refers to ancient SSLREF and SSLv2, retained for compatibility */
+# define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG              0x0
+/* Related to removed SSLv2 */
+# define SSL_OP_MICROSOFT_SESS_ID_BUG                    0x0
+# define SSL_OP_NETSCAPE_CHALLENGE_BUG                   0x0
+
+/*
+ * Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added in
+ * OpenSSL 0.9.6d.  Usually (depending on the application protocol) the
+ * workaround is not needed.  Unfortunately some broken SSL/TLS
+ * implementations cannot handle it at all, which is why we include it in
+ * SSL_OP_ALL.
+ */
+/* added in 0.9.6e */
+# define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS              0x00000800U
+
+/*
+ * SSL_OP_ALL: various bug workarounds that should be rather harmless.  This
+ * used to be 0x000FFFFFL before 0.9.7.
+ */
+# define SSL_OP_ALL                                      0x80000BFFU
+
+/* DTLS options */
+# define SSL_OP_NO_QUERY_MTU                 0x00001000U
+/* Turn on Cookie Exchange (on relevant for servers) */
+# define SSL_OP_COOKIE_EXCHANGE              0x00002000U
+/* Don't use RFC4507 ticket extension */
+# define SSL_OP_NO_TICKET                    0x00004000U
+# ifndef OPENSSL_NO_DTLS1_METHOD
+/* Use Cisco's "speshul" version of DTLS_BAD_VER
+ * (only with deprecated DTLSv1_client_method())  */
+#  define SSL_OP_CISCO_ANYCONNECT             0x00008000U
+# endif
+
+/* As server, disallow session resumption on renegotiation */
+# define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION   0x00010000U
+/* Don't use compression even if supported */
+# define SSL_OP_NO_COMPRESSION                           0x00020000U
+/* Permit unsafe legacy renegotiation */
+# define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION        0x00040000U
+/* Does nothing: retained for compatibility */
+# define SSL_OP_SINGLE_ECDH_USE                          0x0
+/* Does nothing: retained for compatibility */
+# define SSL_OP_SINGLE_DH_USE                            0x0
+/* Does nothing: retained for compatibility */
+# define SSL_OP_EPHEMERAL_RSA                            0x0
+/*
+ * Set on servers to choose the cipher according to the server's preferences
+ */
+# define SSL_OP_CIPHER_SERVER_PREFERENCE                 0x00400000U
+/*
+ * If set, a server will allow a client to issue a SSLv3.0 version number as
+ * latest version supported in the premaster secret, even when TLSv1.0
+ * (version 3.1) was announced in the client hello. Normally this is
+ * forbidden to prevent version rollback attacks.
+ */
+# define SSL_OP_TLS_ROLLBACK_BUG                         0x00800000U
+
+# define SSL_OP_NO_SSLv2                                 0x00000000U
+# define SSL_OP_NO_SSLv3                                 0x02000000U
+# define SSL_OP_NO_TLSv1                                 0x04000000U
+# define SSL_OP_NO_TLSv1_2                               0x08000000U
+# define SSL_OP_NO_TLSv1_1                               0x10000000U
+
+# define SSL_OP_NO_DTLSv1                                0x04000000U
+# define SSL_OP_NO_DTLSv1_2                              0x08000000U
+
+# define SSL_OP_NO_SSL_MASK (SSL_OP_NO_SSLv3|\
+        SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2)
+# define SSL_OP_NO_DTLS_MASK (SSL_OP_NO_DTLSv1|SSL_OP_NO_DTLSv1_2)
+
+
+/* Removed from previous versions */
+# define SSL_OP_PKCS1_CHECK_1                            0x0
+# define SSL_OP_PKCS1_CHECK_2                            0x0
+# define SSL_OP_NETSCAPE_CA_DN_BUG                       0x0
+# define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG          0x0U
+/*
+ * Make server add server-hello extension from early version of cryptopro
+ * draft, when GOST ciphersuite is negotiated. Required for interoperability
+ * with CryptoPro CSP 3.x
+ */
+# define SSL_OP_CRYPTOPRO_TLSEXT_BUG                     0x80000000U
+
+/*
+ * Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success
+ * when just a single record has been written):
+ */
+# define SSL_MODE_ENABLE_PARTIAL_WRITE       0x00000001U
+/*
+ * Make it possible to retry SSL_write() with changed buffer location (buffer
+ * contents must stay the same!); this is not the default to avoid the
+ * misconception that non-blocking SSL_write() behaves like non-blocking
+ * write():
+ */
+# define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002U
+/*
+ * Never bother the application with retries if the transport is blocking:
+ */
+# define SSL_MODE_AUTO_RETRY 0x00000004U
+/* Don't attempt to automatically build certificate chain */
+# define SSL_MODE_NO_AUTO_CHAIN 0x00000008U
+/*
+ * Save RAM by releasing read and write buffers when they're empty. (SSL3 and
+ * TLS only.) "Released" buffers are put onto a free-list in the context or
+ * just freed (depending on the context's setting for freelist_max_len).
+ */
+# define SSL_MODE_RELEASE_BUFFERS 0x00000010U
+/*
+ * Send the current time in the Random fields of the ClientHello and
+ * ServerHello records for compatibility with hypothetical implementations
+ * that require it.
+ */
+# define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020U
+# define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040U
+/*
+ * Send TLS_FALLBACK_SCSV in the ClientHello. To be set only by applications
+ * that reconnect with a downgraded protocol version; see
+ * draft-ietf-tls-downgrade-scsv-00 for details. DO NOT ENABLE THIS if your
+ * application attempts a normal handshake. Only use this in explicit
+ * fallback retries, following the guidance in
+ * draft-ietf-tls-downgrade-scsv-00.
+ */
+# define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080U
+/*
+ * Support Asynchronous operation
+ */
+# define SSL_MODE_ASYNC 0x00000100U
+
+/* Cert related flags */
+/*
+ * Many implementations ignore some aspects of the TLS standards such as
+ * enforcing certificate chain algorithms. When this is set we enforce them.
+ */
+# define SSL_CERT_FLAG_TLS_STRICT                0x00000001U
+
+/* Suite B modes, takes same values as certificate verify flags */
+# define SSL_CERT_FLAG_SUITEB_128_LOS_ONLY       0x10000
+/* Suite B 192 bit only mode */
+# define SSL_CERT_FLAG_SUITEB_192_LOS            0x20000
+/* Suite B 128 bit mode allowing 192 bit algorithms */
+# define SSL_CERT_FLAG_SUITEB_128_LOS            0x30000
+
+/* Perform all sorts of protocol violations for testing purposes */
+# define SSL_CERT_FLAG_BROKEN_PROTOCOL           0x10000000
+
+/* Flags for building certificate chains */
+/* Treat any existing certificates as untrusted CAs */
+# define SSL_BUILD_CHAIN_FLAG_UNTRUSTED          0x1
+/* Don't include root CA in chain */
+# define SSL_BUILD_CHAIN_FLAG_NO_ROOT            0x2
+/* Just check certificates already there */
+# define SSL_BUILD_CHAIN_FLAG_CHECK              0x4
+/* Ignore verification errors */
+# define SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR       0x8
+/* Clear verification errors from queue */
+# define SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR        0x10
+
+/* Flags returned by SSL_check_chain */
+/* Certificate can be used with this session */
+# define CERT_PKEY_VALID         0x1
+/* Certificate can also be used for signing */
+# define CERT_PKEY_SIGN          0x2
+/* EE certificate signing algorithm OK */
+# define CERT_PKEY_EE_SIGNATURE  0x10
+/* CA signature algorithms OK */
+# define CERT_PKEY_CA_SIGNATURE  0x20
+/* EE certificate parameters OK */
+# define CERT_PKEY_EE_PARAM      0x40
+/* CA certificate parameters OK */
+# define CERT_PKEY_CA_PARAM      0x80
+/* Signing explicitly allowed as opposed to SHA1 fallback */
+# define CERT_PKEY_EXPLICIT_SIGN 0x100
+/* Client CA issuer names match (always set for server cert) */
+# define CERT_PKEY_ISSUER_NAME   0x200
+/* Cert type matches client types (always set for server cert) */
+# define CERT_PKEY_CERT_TYPE     0x400
+/* Cert chain suitable to Suite B */
+# define CERT_PKEY_SUITEB        0x800
+
+# define SSL_CONF_FLAG_CMDLINE           0x1
+# define SSL_CONF_FLAG_FILE              0x2
+# define SSL_CONF_FLAG_CLIENT            0x4
+# define SSL_CONF_FLAG_SERVER            0x8
+# define SSL_CONF_FLAG_SHOW_ERRORS       0x10
+# define SSL_CONF_FLAG_CERTIFICATE       0x20
+# define SSL_CONF_FLAG_REQUIRE_PRIVATE   0x40
+/* Configuration value types */
+# define SSL_CONF_TYPE_UNKNOWN           0x0
+# define SSL_CONF_TYPE_STRING            0x1
+# define SSL_CONF_TYPE_FILE              0x2
+# define SSL_CONF_TYPE_DIR               0x3
+# define SSL_CONF_TYPE_NONE              0x4
+
+/*
+ * Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, they
+ * cannot be used to clear bits.
+ */
+
+unsigned long SSL_CTX_get_options(const SSL_CTX *ctx);
+unsigned long SSL_get_options(const SSL* s);
+unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op);
+unsigned long SSL_clear_options(SSL *s, unsigned long op);
+unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op);
+unsigned long SSL_set_options(SSL *s, unsigned long op);
+
+# define SSL_CTX_set_mode(ctx,op) \
+        SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
+# define SSL_CTX_clear_mode(ctx,op) \
+        SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_MODE,(op),NULL)
+# define SSL_CTX_get_mode(ctx) \
+        SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL)
+# define SSL_clear_mode(ssl,op) \
+        SSL_ctrl((ssl),SSL_CTRL_CLEAR_MODE,(op),NULL)
+# define SSL_set_mode(ssl,op) \
+        SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL)
+# define SSL_get_mode(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL)
+# define SSL_set_mtu(ssl, mtu) \
+        SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL)
+# define DTLS_set_link_mtu(ssl, mtu) \
+        SSL_ctrl((ssl),DTLS_CTRL_SET_LINK_MTU,(mtu),NULL)
+# define DTLS_get_link_min_mtu(ssl) \
+        SSL_ctrl((ssl),DTLS_CTRL_GET_LINK_MIN_MTU,0,NULL)
+
+# define SSL_get_secure_renegotiation_support(ssl) \
+        SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL)
+
+# ifndef OPENSSL_NO_HEARTBEATS
+#  define SSL_heartbeat(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_DTLS_EXT_SEND_HEARTBEAT,0,NULL)
+# endif
+
+# define SSL_CTX_set_cert_flags(ctx,op) \
+        SSL_CTX_ctrl((ctx),SSL_CTRL_CERT_FLAGS,(op),NULL)
+# define SSL_set_cert_flags(s,op) \
+        SSL_ctrl((s),SSL_CTRL_CERT_FLAGS,(op),NULL)
+# define SSL_CTX_clear_cert_flags(ctx,op) \
+        SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL)
+# define SSL_clear_cert_flags(s,op) \
+        SSL_ctrl((s),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL)
+
+void SSL_CTX_set_msg_callback(SSL_CTX *ctx,
+                              void (*cb) (int write_p, int version,
+                                          int content_type, const void *buf,
+                                          size_t len, SSL *ssl, void *arg));
+void SSL_set_msg_callback(SSL *ssl,
+                          void (*cb) (int write_p, int version,
+                                      int content_type, const void *buf,
+                                      size_t len, SSL *ssl, void *arg));
+# define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
+# define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
+
+# define SSL_get_extms_support(s) \
+        SSL_ctrl((s),SSL_CTRL_GET_EXTMS_SUPPORT,0,NULL)
+
+# ifndef OPENSSL_NO_SRP
+
+/* see tls_srp.c */
+__owur int SSL_SRP_CTX_init(SSL *s);
+__owur int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx);
+int SSL_SRP_CTX_free(SSL *ctx);
+int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx);
+__owur int SSL_srp_server_param_with_username(SSL *s, int *ad);
+__owur int SRP_Calc_A_param(SSL *s);
+
+# endif
+
+/* 100k max cert list */
+# define SSL_MAX_CERT_LIST_DEFAULT 1024*100
+
+# define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT      (1024*20)
+
+/*
+ * This callback type is used inside SSL_CTX, SSL, and in the functions that
+ * set them. It is used to override the generation of SSL/TLS session IDs in
+ * a server. Return value should be zero on an error, non-zero to proceed.
+ * Also, callbacks should themselves check if the id they generate is unique
+ * otherwise the SSL handshake will fail with an error - callbacks can do
+ * this using the 'ssl' value they're passed by;
+ * SSL_has_matching_session_id(ssl, id, *id_len) The length value passed in
+ * is set at the maximum size the session ID can be. In SSLv3/TLSv1 it is 32
+ * bytes. The callback can alter this length to be less if desired. It is
+ * also an error for the callback to set the size to zero.
+ */
+typedef int (*GEN_SESSION_CB) (const SSL *ssl, unsigned char *id,
+                               unsigned int *id_len);
+
+# define SSL_SESS_CACHE_OFF                      0x0000
+# define SSL_SESS_CACHE_CLIENT                   0x0001
+# define SSL_SESS_CACHE_SERVER                   0x0002
+# define SSL_SESS_CACHE_BOTH     (SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER)
+# define SSL_SESS_CACHE_NO_AUTO_CLEAR            0x0080
+/* enough comments already ... see SSL_CTX_set_session_cache_mode(3) */
+# define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP       0x0100
+# define SSL_SESS_CACHE_NO_INTERNAL_STORE        0x0200
+# define SSL_SESS_CACHE_NO_INTERNAL \
+        (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE)
+
+LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx);
+# define SSL_CTX_sess_number(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL)
+# define SSL_CTX_sess_connect(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT,0,NULL)
+# define SSL_CTX_sess_connect_good(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_GOOD,0,NULL)
+# define SSL_CTX_sess_connect_renegotiate(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_RENEGOTIATE,0,NULL)
+# define SSL_CTX_sess_accept(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT,0,NULL)
+# define SSL_CTX_sess_accept_renegotiate(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_RENEGOTIATE,0,NULL)
+# define SSL_CTX_sess_accept_good(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_GOOD,0,NULL)
+# define SSL_CTX_sess_hits(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_HIT,0,NULL)
+# define SSL_CTX_sess_cb_hits(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CB_HIT,0,NULL)
+# define SSL_CTX_sess_misses(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_MISSES,0,NULL)
+# define SSL_CTX_sess_timeouts(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL)
+# define SSL_CTX_sess_cache_full(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL)
+
+void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
+                             int (*new_session_cb) (struct ssl_st *ssl,
+                                                    SSL_SESSION *sess));
+int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (struct ssl_st *ssl,
+                                              SSL_SESSION *sess);
+void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,
+                                void (*remove_session_cb) (struct ssl_ctx_st
+                                                           *ctx,
+                                                           SSL_SESSION
+                                                           *sess));
+void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (struct ssl_ctx_st *ctx,
+                                                  SSL_SESSION *sess);
+void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
+                             SSL_SESSION *(*get_session_cb) (struct ssl_st
+                                                             *ssl,
+                                                             const unsigned char
+                                                             *data, int len,
+                                                             int *copy));
+SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (struct ssl_st *ssl,
+                                                       const unsigned char *data,
+                                                       int len, int *copy);
+void SSL_CTX_set_info_callback(SSL_CTX *ctx,
+                               void (*cb) (const SSL *ssl, int type,
+                                           int val));
+void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type,
+                                                 int val);
+void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx,
+                                int (*client_cert_cb) (SSL *ssl, X509 **x509,
+                                                       EVP_PKEY **pkey));
+int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509,
+                                                 EVP_PKEY **pkey);
+# ifndef OPENSSL_NO_ENGINE
+__owur int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e);
+# endif
+void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx,
+                                    int (*app_gen_cookie_cb) (SSL *ssl,
+                                                              unsigned char
+                                                              *cookie,
+                                                              unsigned int
+                                                              *cookie_len));
+void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx,
+                                  int (*app_verify_cookie_cb) (SSL *ssl,
+                                                               const unsigned char
+                                                               *cookie,
+                                                               unsigned int
+                                                               cookie_len));
+# ifndef OPENSSL_NO_NEXTPROTONEG
+void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s,
+                                           int (*cb) (SSL *ssl,
+                                                      const unsigned char
+                                                      **out,
+                                                      unsigned int *outlen,
+                                                      void *arg), void *arg);
+void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s,
+                                      int (*cb) (SSL *ssl,
+                                                 unsigned char **out,
+                                                 unsigned char *outlen,
+                                                 const unsigned char *in,
+                                                 unsigned int inlen,
+                                                 void *arg), void *arg);
+void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data,
+                                    unsigned *len);
+# endif
+
+__owur int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
+                          const unsigned char *in, unsigned int inlen,
+                          const unsigned char *client,
+                          unsigned int client_len);
+
+# define OPENSSL_NPN_UNSUPPORTED 0
+# define OPENSSL_NPN_NEGOTIATED  1
+# define OPENSSL_NPN_NO_OVERLAP  2
+
+__owur int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos,
+                                   unsigned int protos_len);
+__owur int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos,
+                               unsigned int protos_len);
+void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx,
+                                int (*cb) (SSL *ssl,
+                                           const unsigned char **out,
+                                           unsigned char *outlen,
+                                           const unsigned char *in,
+                                           unsigned int inlen,
+                                           void *arg), void *arg);
+void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
+                            unsigned int *len);
+
+# ifndef OPENSSL_NO_PSK
+/*
+ * the maximum length of the buffer given to callbacks containing the
+ * resulting identity/psk
+ */
+#  define PSK_MAX_IDENTITY_LEN 128
+#  define PSK_MAX_PSK_LEN 256
+void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx,
+                                     unsigned int (*psk_client_callback) (SSL
+                                                                          *ssl,
+                                                                          const
+                                                                          char
+                                                                          *hint,
+                                                                          char
+                                                                          *identity,
+                                                                          unsigned
+                                                                          int
+                                                                          max_identity_len,
+                                                                          unsigned
+                                                                          char
+                                                                          *psk,
+                                                                          unsigned
+                                                                          int
+                                                                          max_psk_len));
+void SSL_set_psk_client_callback(SSL *ssl,
+                                 unsigned int (*psk_client_callback) (SSL
+                                                                      *ssl,
+                                                                      const
+                                                                      char
+                                                                      *hint,
+                                                                      char
+                                                                      *identity,
+                                                                      unsigned
+                                                                      int
+                                                                      max_identity_len,
+                                                                      unsigned
+                                                                      char
+                                                                      *psk,
+                                                                      unsigned
+                                                                      int
+                                                                      max_psk_len));
+void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx,
+                                     unsigned int (*psk_server_callback) (SSL
+                                                                          *ssl,
+                                                                          const
+                                                                          char
+                                                                          *identity,
+                                                                          unsigned
+                                                                          char
+                                                                          *psk,
+                                                                          unsigned
+                                                                          int
+                                                                          max_psk_len));
+void SSL_set_psk_server_callback(SSL *ssl,
+                                 unsigned int (*psk_server_callback) (SSL
+                                                                      *ssl,
+                                                                      const
+                                                                      char
+                                                                      *identity,
+                                                                      unsigned
+                                                                      char
+                                                                      *psk,
+                                                                      unsigned
+                                                                      int
+                                                                      max_psk_len));
+__owur int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint);
+__owur int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint);
+const char *SSL_get_psk_identity_hint(const SSL *s);
+const char *SSL_get_psk_identity(const SSL *s);
+# endif
+
+/* Register callbacks to handle custom TLS Extensions for client or server. */
+
+__owur int SSL_CTX_has_client_custom_ext(const SSL_CTX *ctx,
+                                         unsigned int ext_type);
+
+__owur int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, unsigned int ext_type,
+                                  custom_ext_add_cb add_cb,
+                                  custom_ext_free_cb free_cb,
+                                  void *add_arg,
+                                  custom_ext_parse_cb parse_cb,
+                                  void *parse_arg);
+
+__owur int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, unsigned int ext_type,
+                                  custom_ext_add_cb add_cb,
+                                  custom_ext_free_cb free_cb,
+                                  void *add_arg,
+                                  custom_ext_parse_cb parse_cb,
+                                  void *parse_arg);
+
+__owur int SSL_extension_supported(unsigned int ext_type);
+
+# define SSL_NOTHING            1
+# define SSL_WRITING            2
+# define SSL_READING            3
+# define SSL_X509_LOOKUP        4
+# define SSL_ASYNC_PAUSED       5
+# define SSL_ASYNC_NO_JOBS      6
+
+/* These will only be used when doing non-blocking IO */
+# define SSL_want_nothing(s)     (SSL_want(s) == SSL_NOTHING)
+# define SSL_want_read(s)        (SSL_want(s) == SSL_READING)
+# define SSL_want_write(s)       (SSL_want(s) == SSL_WRITING)
+# define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP)
+# define SSL_want_async(s)       (SSL_want(s) == SSL_ASYNC_PAUSED)
+# define SSL_want_async_job(s)   (SSL_want(s) == SSL_ASYNC_NO_JOBS)
+
+# define SSL_MAC_FLAG_READ_MAC_STREAM 1
+# define SSL_MAC_FLAG_WRITE_MAC_STREAM 2
+
+#ifdef __cplusplus
+}
+#endif
+
+# include <openssl/ssl2.h>
+# include <openssl/ssl3.h>
+# include <openssl/tls1.h>      /* This is mostly sslv3 with a few tweaks */
+# include <openssl/dtls1.h>     /* Datagram TLS */
+# include <openssl/srtp.h>      /* Support for the use_srtp extension */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+ * These need to be after the above set of includes due to a compiler bug
+ * in VisualStudio 2015
+ */
+DEFINE_STACK_OF_CONST(SSL_CIPHER)
+DEFINE_STACK_OF(SSL_COMP)
+
+/* compatibility */
+# define SSL_set_app_data(s,arg)         (SSL_set_ex_data(s,0,(char *)arg))
+# define SSL_get_app_data(s)             (SSL_get_ex_data(s,0))
+# define SSL_SESSION_set_app_data(s,a)   (SSL_SESSION_set_ex_data(s,0,(char *)a))
+# define SSL_SESSION_get_app_data(s)     (SSL_SESSION_get_ex_data(s,0))
+# define SSL_CTX_get_app_data(ctx)       (SSL_CTX_get_ex_data(ctx,0))
+# define SSL_CTX_set_app_data(ctx,arg)   (SSL_CTX_set_ex_data(ctx,0,(char *)arg))
+DEPRECATEDIN_1_1_0(void SSL_set_debug(SSL *s, int debug))
+
+
+/*
+ * The valid handshake states (one for each type message sent and one for each
+ * type of message received). There are also two "special" states:
+ * TLS = TLS or DTLS state
+ * DTLS = DTLS specific state
+ * CR/SR = Client Read/Server Read
+ * CW/SW = Client Write/Server Write
+ *
+ * The "special" states are:
+ * TLS_ST_BEFORE = No handshake has been initiated yet
+ * TLS_ST_OK = A handshake has been successfully completed
+ */
+typedef enum {
+    TLS_ST_BEFORE,
+    TLS_ST_OK,
+    DTLS_ST_CR_HELLO_VERIFY_REQUEST,
+    TLS_ST_CR_SRVR_HELLO,
+    TLS_ST_CR_CERT,
+    TLS_ST_CR_CERT_STATUS,
+    TLS_ST_CR_KEY_EXCH,
+    TLS_ST_CR_CERT_REQ,
+    TLS_ST_CR_SRVR_DONE,
+    TLS_ST_CR_SESSION_TICKET,
+    TLS_ST_CR_CHANGE,
+    TLS_ST_CR_FINISHED,
+    TLS_ST_CW_CLNT_HELLO,
+    TLS_ST_CW_CERT,
+    TLS_ST_CW_KEY_EXCH,
+    TLS_ST_CW_CERT_VRFY,
+    TLS_ST_CW_CHANGE,
+    TLS_ST_CW_NEXT_PROTO,
+    TLS_ST_CW_FINISHED,
+    TLS_ST_SW_HELLO_REQ,
+    TLS_ST_SR_CLNT_HELLO,
+    DTLS_ST_SW_HELLO_VERIFY_REQUEST,
+    TLS_ST_SW_SRVR_HELLO,
+    TLS_ST_SW_CERT,
+    TLS_ST_SW_KEY_EXCH,
+    TLS_ST_SW_CERT_REQ,
+    TLS_ST_SW_SRVR_DONE,
+    TLS_ST_SR_CERT,
+    TLS_ST_SR_KEY_EXCH,
+    TLS_ST_SR_CERT_VRFY,
+    TLS_ST_SR_NEXT_PROTO,
+    TLS_ST_SR_CHANGE,
+    TLS_ST_SR_FINISHED,
+    TLS_ST_SW_SESSION_TICKET,
+    TLS_ST_SW_CERT_STATUS,
+    TLS_ST_SW_CHANGE,
+    TLS_ST_SW_FINISHED
+} OSSL_HANDSHAKE_STATE;
+
+/*
+ * Most of the following state values are no longer used and are defined to be
+ * the closest equivalent value in the current state machine code. Not all
+ * defines have an equivalent and are set to a dummy value (-1). SSL_ST_CONNECT
+ * and SSL_ST_ACCEPT are still in use in the definition of SSL_CB_ACCEPT_LOOP,
+ * SSL_CB_ACCEPT_EXIT, SSL_CB_CONNECT_LOOP and SSL_CB_CONNECT_EXIT.
+ */
+
+# define SSL_ST_CONNECT                  0x1000
+# define SSL_ST_ACCEPT                   0x2000
+
+# define SSL_ST_MASK                     0x0FFF
+
+# define SSL_CB_LOOP                     0x01
+# define SSL_CB_EXIT                     0x02
+# define SSL_CB_READ                     0x04
+# define SSL_CB_WRITE                    0x08
+# define SSL_CB_ALERT                    0x4000/* used in callback */
+# define SSL_CB_READ_ALERT               (SSL_CB_ALERT|SSL_CB_READ)
+# define SSL_CB_WRITE_ALERT              (SSL_CB_ALERT|SSL_CB_WRITE)
+# define SSL_CB_ACCEPT_LOOP              (SSL_ST_ACCEPT|SSL_CB_LOOP)
+# define SSL_CB_ACCEPT_EXIT              (SSL_ST_ACCEPT|SSL_CB_EXIT)
+# define SSL_CB_CONNECT_LOOP             (SSL_ST_CONNECT|SSL_CB_LOOP)
+# define SSL_CB_CONNECT_EXIT             (SSL_ST_CONNECT|SSL_CB_EXIT)
+# define SSL_CB_HANDSHAKE_START          0x10
+# define SSL_CB_HANDSHAKE_DONE           0x20
+
+/* Is the SSL_connection established? */
+# define SSL_in_connect_init(a)          (SSL_in_init(a) && !SSL_is_server(a))
+# define SSL_in_accept_init(a)           (SSL_in_init(a) && SSL_is_server(a))
+int SSL_in_init(SSL *s);
+int SSL_in_before(SSL *s);
+int SSL_is_init_finished(SSL *s);
+
+/*
+ * The following 3 states are kept in ssl->rlayer.rstate when reads fail, you
+ * should not need these
+ */
+# define SSL_ST_READ_HEADER                      0xF0
+# define SSL_ST_READ_BODY                        0xF1
+# define SSL_ST_READ_DONE                        0xF2
+
+/*-
+ * Obtain latest Finished message
+ *   -- that we sent (SSL_get_finished)
+ *   -- that we expected from peer (SSL_get_peer_finished).
+ * Returns length (0 == no Finished so far), copies up to 'count' bytes.
+ */
+size_t SSL_get_finished(const SSL *s, void *buf, size_t count);
+size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
+
+/*
+ * use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 2 options are
+ * 'ored' with SSL_VERIFY_PEER if they are desired
+ */
+# define SSL_VERIFY_NONE                 0x00
+# define SSL_VERIFY_PEER                 0x01
+# define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02
+# define SSL_VERIFY_CLIENT_ONCE          0x04
+
+# define OpenSSL_add_ssl_algorithms()    SSL_library_init()
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  define SSLeay_add_ssl_algorithms()    SSL_library_init()
+# endif
+
+/* More backward compatibility */
+# define SSL_get_cipher(s) \
+                SSL_CIPHER_get_name(SSL_get_current_cipher(s))
+# define SSL_get_cipher_bits(s,np) \
+                SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np)
+# define SSL_get_cipher_version(s) \
+                SSL_CIPHER_get_version(SSL_get_current_cipher(s))
+# define SSL_get_cipher_name(s) \
+                SSL_CIPHER_get_name(SSL_get_current_cipher(s))
+# define SSL_get_time(a)         SSL_SESSION_get_time(a)
+# define SSL_set_time(a,b)       SSL_SESSION_set_time((a),(b))
+# define SSL_get_timeout(a)      SSL_SESSION_get_timeout(a)
+# define SSL_set_timeout(a,b)    SSL_SESSION_set_timeout((a),(b))
+
+# define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id)
+# define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id)
+
+DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
+# define SSL_AD_REASON_OFFSET            1000/* offset to get SSL_R_... value
+                                              * from SSL_AD_... */
+/* These alert types are for SSLv3 and TLSv1 */
+# define SSL_AD_CLOSE_NOTIFY             SSL3_AD_CLOSE_NOTIFY
+/* fatal */
+# define SSL_AD_UNEXPECTED_MESSAGE       SSL3_AD_UNEXPECTED_MESSAGE
+/* fatal */
+# define SSL_AD_BAD_RECORD_MAC           SSL3_AD_BAD_RECORD_MAC
+# define SSL_AD_DECRYPTION_FAILED        TLS1_AD_DECRYPTION_FAILED
+# define SSL_AD_RECORD_OVERFLOW          TLS1_AD_RECORD_OVERFLOW
+/* fatal */
+# define SSL_AD_DECOMPRESSION_FAILURE    SSL3_AD_DECOMPRESSION_FAILURE
+/* fatal */
+# define SSL_AD_HANDSHAKE_FAILURE        SSL3_AD_HANDSHAKE_FAILURE
+/* Not for TLS */
+# define SSL_AD_NO_CERTIFICATE           SSL3_AD_NO_CERTIFICATE
+# define SSL_AD_BAD_CERTIFICATE          SSL3_AD_BAD_CERTIFICATE
+# define SSL_AD_UNSUPPORTED_CERTIFICATE  SSL3_AD_UNSUPPORTED_CERTIFICATE
+# define SSL_AD_CERTIFICATE_REVOKED      SSL3_AD_CERTIFICATE_REVOKED
+# define SSL_AD_CERTIFICATE_EXPIRED      SSL3_AD_CERTIFICATE_EXPIRED
+# define SSL_AD_CERTIFICATE_UNKNOWN      SSL3_AD_CERTIFICATE_UNKNOWN
+/* fatal */
+# define SSL_AD_ILLEGAL_PARAMETER        SSL3_AD_ILLEGAL_PARAMETER
+/* fatal */
+# define SSL_AD_UNKNOWN_CA               TLS1_AD_UNKNOWN_CA
+/* fatal */
+# define SSL_AD_ACCESS_DENIED            TLS1_AD_ACCESS_DENIED
+/* fatal */
+# define SSL_AD_DECODE_ERROR             TLS1_AD_DECODE_ERROR
+# define SSL_AD_DECRYPT_ERROR            TLS1_AD_DECRYPT_ERROR
+/* fatal */
+# define SSL_AD_EXPORT_RESTRICTION       TLS1_AD_EXPORT_RESTRICTION
+/* fatal */
+# define SSL_AD_PROTOCOL_VERSION         TLS1_AD_PROTOCOL_VERSION
+/* fatal */
+# define SSL_AD_INSUFFICIENT_SECURITY    TLS1_AD_INSUFFICIENT_SECURITY
+/* fatal */
+# define SSL_AD_INTERNAL_ERROR           TLS1_AD_INTERNAL_ERROR
+# define SSL_AD_USER_CANCELLED           TLS1_AD_USER_CANCELLED
+# define SSL_AD_NO_RENEGOTIATION         TLS1_AD_NO_RENEGOTIATION
+# define SSL_AD_UNSUPPORTED_EXTENSION    TLS1_AD_UNSUPPORTED_EXTENSION
+# define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE
+# define SSL_AD_UNRECOGNIZED_NAME        TLS1_AD_UNRECOGNIZED_NAME
+# define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
+# define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
+/* fatal */
+# define SSL_AD_UNKNOWN_PSK_IDENTITY     TLS1_AD_UNKNOWN_PSK_IDENTITY
+/* fatal */
+# define SSL_AD_INAPPROPRIATE_FALLBACK   TLS1_AD_INAPPROPRIATE_FALLBACK
+# define SSL_AD_NO_APPLICATION_PROTOCOL  TLS1_AD_NO_APPLICATION_PROTOCOL
+# define SSL_ERROR_NONE                  0
+# define SSL_ERROR_SSL                   1
+# define SSL_ERROR_WANT_READ             2
+# define SSL_ERROR_WANT_WRITE            3
+# define SSL_ERROR_WANT_X509_LOOKUP      4
+# define SSL_ERROR_SYSCALL               5/* look at error stack/return
+                                           * value/errno */
+# define SSL_ERROR_ZERO_RETURN           6
+# define SSL_ERROR_WANT_CONNECT          7
+# define SSL_ERROR_WANT_ACCEPT           8
+# define SSL_ERROR_WANT_ASYNC            9
+# define SSL_ERROR_WANT_ASYNC_JOB       10
+# define SSL_CTRL_SET_TMP_DH                     3
+# define SSL_CTRL_SET_TMP_ECDH                   4
+# define SSL_CTRL_SET_TMP_DH_CB                  6
+# define SSL_CTRL_GET_CLIENT_CERT_REQUEST        9
+# define SSL_CTRL_GET_NUM_RENEGOTIATIONS         10
+# define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS       11
+# define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS       12
+# define SSL_CTRL_GET_FLAGS                      13
+# define SSL_CTRL_EXTRA_CHAIN_CERT               14
+# define SSL_CTRL_SET_MSG_CALLBACK               15
+# define SSL_CTRL_SET_MSG_CALLBACK_ARG           16
+/* only applies to datagram connections */
+# define SSL_CTRL_SET_MTU                17
+/* Stats */
+# define SSL_CTRL_SESS_NUMBER                    20
+# define SSL_CTRL_SESS_CONNECT                   21
+# define SSL_CTRL_SESS_CONNECT_GOOD              22
+# define SSL_CTRL_SESS_CONNECT_RENEGOTIATE       23
+# define SSL_CTRL_SESS_ACCEPT                    24
+# define SSL_CTRL_SESS_ACCEPT_GOOD               25
+# define SSL_CTRL_SESS_ACCEPT_RENEGOTIATE        26
+# define SSL_CTRL_SESS_HIT                       27
+# define SSL_CTRL_SESS_CB_HIT                    28
+# define SSL_CTRL_SESS_MISSES                    29
+# define SSL_CTRL_SESS_TIMEOUTS                  30
+# define SSL_CTRL_SESS_CACHE_FULL                31
+# define SSL_CTRL_MODE                           33
+# define SSL_CTRL_GET_READ_AHEAD                 40
+# define SSL_CTRL_SET_READ_AHEAD                 41
+# define SSL_CTRL_SET_SESS_CACHE_SIZE            42
+# define SSL_CTRL_GET_SESS_CACHE_SIZE            43
+# define SSL_CTRL_SET_SESS_CACHE_MODE            44
+# define SSL_CTRL_GET_SESS_CACHE_MODE            45
+# define SSL_CTRL_GET_MAX_CERT_LIST              50
+# define SSL_CTRL_SET_MAX_CERT_LIST              51
+# define SSL_CTRL_SET_MAX_SEND_FRAGMENT          52
+/* see tls1.h for macros based on these */
+# define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB       53
+# define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG      54
+# define SSL_CTRL_SET_TLSEXT_HOSTNAME            55
+# define SSL_CTRL_SET_TLSEXT_DEBUG_CB            56
+# define SSL_CTRL_SET_TLSEXT_DEBUG_ARG           57
+# define SSL_CTRL_GET_TLSEXT_TICKET_KEYS         58
+# define SSL_CTRL_SET_TLSEXT_TICKET_KEYS         59
+/*# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT    60 */
+/*# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB 61 */
+/*# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG 62 */
+# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB       63
+# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG   64
+# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE     65
+# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS     66
+# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS     67
+# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS      68
+# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS      69
+# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP        70
+# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP        71
+# define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB       72
+# define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB    75
+# define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB                76
+# define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB             77
+# define SSL_CTRL_SET_SRP_ARG            78
+# define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME               79
+# define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH               80
+# define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD               81
+# ifndef OPENSSL_NO_HEARTBEATS
+#  define SSL_CTRL_DTLS_EXT_SEND_HEARTBEAT               85
+#  define SSL_CTRL_GET_DTLS_EXT_HEARTBEAT_PENDING        86
+#  define SSL_CTRL_SET_DTLS_EXT_HEARTBEAT_NO_REQUESTS    87
+# endif
+# define DTLS_CTRL_GET_TIMEOUT           73
+# define DTLS_CTRL_HANDLE_TIMEOUT        74
+# define SSL_CTRL_GET_RI_SUPPORT                 76
+# define SSL_CTRL_CLEAR_MODE                     78
+# define SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB      79
+# define SSL_CTRL_GET_EXTRA_CHAIN_CERTS          82
+# define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS        83
+# define SSL_CTRL_CHAIN                          88
+# define SSL_CTRL_CHAIN_CERT                     89
+# define SSL_CTRL_GET_CURVES                     90
+# define SSL_CTRL_SET_CURVES                     91
+# define SSL_CTRL_SET_CURVES_LIST                92
+# define SSL_CTRL_GET_SHARED_CURVE               93
+# define SSL_CTRL_SET_SIGALGS                    97
+# define SSL_CTRL_SET_SIGALGS_LIST               98
+# define SSL_CTRL_CERT_FLAGS                     99
+# define SSL_CTRL_CLEAR_CERT_FLAGS               100
+# define SSL_CTRL_SET_CLIENT_SIGALGS             101
+# define SSL_CTRL_SET_CLIENT_SIGALGS_LIST        102
+# define SSL_CTRL_GET_CLIENT_CERT_TYPES          103
+# define SSL_CTRL_SET_CLIENT_CERT_TYPES          104
+# define SSL_CTRL_BUILD_CERT_CHAIN               105
+# define SSL_CTRL_SET_VERIFY_CERT_STORE          106
+# define SSL_CTRL_SET_CHAIN_CERT_STORE           107
+# define SSL_CTRL_GET_PEER_SIGNATURE_NID         108
+# define SSL_CTRL_GET_SERVER_TMP_KEY             109
+# define SSL_CTRL_GET_RAW_CIPHERLIST             110
+# define SSL_CTRL_GET_EC_POINT_FORMATS           111
+# define SSL_CTRL_GET_CHAIN_CERTS                115
+# define SSL_CTRL_SELECT_CURRENT_CERT            116
+# define SSL_CTRL_SET_CURRENT_CERT               117
+# define SSL_CTRL_SET_DH_AUTO                    118
+# define DTLS_CTRL_SET_LINK_MTU                  120
+# define DTLS_CTRL_GET_LINK_MIN_MTU              121
+# define SSL_CTRL_GET_EXTMS_SUPPORT              122
+# define SSL_CTRL_SET_MIN_PROTO_VERSION          123
+# define SSL_CTRL_SET_MAX_PROTO_VERSION          124
+# define SSL_CTRL_SET_SPLIT_SEND_FRAGMENT        125
+# define SSL_CTRL_SET_MAX_PIPELINES              126
+# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE     127
+# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB       128
+# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG   129
+# define SSL_CERT_SET_FIRST                      1
+# define SSL_CERT_SET_NEXT                       2
+# define SSL_CERT_SET_SERVER                     3
+# define DTLSv1_get_timeout(ssl, arg) \
+        SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
+# define DTLSv1_handle_timeout(ssl) \
+        SSL_ctrl(ssl,DTLS_CTRL_HANDLE_TIMEOUT,0, NULL)
+# define SSL_num_renegotiations(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL)
+# define SSL_clear_num_renegotiations(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL)
+# define SSL_total_renegotiations(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL)
+# define SSL_CTX_set_tmp_dh(ctx,dh) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
+# define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
+# define SSL_CTX_set_dh_auto(ctx, onoff) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_DH_AUTO,onoff,NULL)
+# define SSL_set_dh_auto(s, onoff) \
+        SSL_ctrl(s,SSL_CTRL_SET_DH_AUTO,onoff,NULL)
+# define SSL_set_tmp_dh(ssl,dh) \
+        SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
+# define SSL_set_tmp_ecdh(ssl,ecdh) \
+        SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
+# define SSL_CTX_add_extra_chain_cert(ctx,x509) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509)
+# define SSL_CTX_get_extra_chain_certs(ctx,px509) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,0,px509)
+# define SSL_CTX_get_extra_chain_certs_only(ctx,px509) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,1,px509)
+# define SSL_CTX_clear_extra_chain_certs(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS,0,NULL)
+# define SSL_CTX_set0_chain(ctx,sk) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)sk)
+# define SSL_CTX_set1_chain(ctx,sk) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,1,(char *)sk)
+# define SSL_CTX_add0_chain_cert(ctx,x509) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509)
+# define SSL_CTX_add1_chain_cert(ctx,x509) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)x509)
+# define SSL_CTX_get0_chain_certs(ctx,px509) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_CHAIN_CERTS,0,px509)
+# define SSL_CTX_clear_chain_certs(ctx) \
+        SSL_CTX_set0_chain(ctx,NULL)
+# define SSL_CTX_build_cert_chain(ctx, flags) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL)
+# define SSL_CTX_select_current_cert(ctx,x509) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)x509)
+# define SSL_CTX_set_current_cert(ctx, op) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURRENT_CERT, op, NULL)
+# define SSL_CTX_set0_verify_cert_store(ctx,st) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)st)
+# define SSL_CTX_set1_verify_cert_store(ctx,st) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)st)
+# define SSL_CTX_set0_chain_cert_store(ctx,st) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)st)
+# define SSL_CTX_set1_chain_cert_store(ctx,st) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)st)
+# define SSL_set0_chain(ctx,sk) \
+        SSL_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)sk)
+# define SSL_set1_chain(ctx,sk) \
+        SSL_ctrl(ctx,SSL_CTRL_CHAIN,1,(char *)sk)
+# define SSL_add0_chain_cert(ctx,x509) \
+        SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509)
+# define SSL_add1_chain_cert(ctx,x509) \
+        SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)x509)
+# define SSL_get0_chain_certs(ctx,px509) \
+        SSL_ctrl(ctx,SSL_CTRL_GET_CHAIN_CERTS,0,px509)
+# define SSL_clear_chain_certs(ctx) \
+        SSL_set0_chain(ctx,NULL)
+# define SSL_build_cert_chain(s, flags) \
+        SSL_ctrl(s,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL)
+# define SSL_select_current_cert(ctx,x509) \
+        SSL_ctrl(ctx,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)x509)
+# define SSL_set_current_cert(ctx,op) \
+        SSL_ctrl(ctx,SSL_CTRL_SET_CURRENT_CERT, op, NULL)
+# define SSL_set0_verify_cert_store(s,st) \
+        SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)st)
+# define SSL_set1_verify_cert_store(s,st) \
+        SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)st)
+# define SSL_set0_chain_cert_store(s,st) \
+        SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)st)
+# define SSL_set1_chain_cert_store(s,st) \
+        SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)st)
+# define SSL_get1_curves(ctx, s) \
+        SSL_ctrl(ctx,SSL_CTRL_GET_CURVES,0,(char *)s)
+# define SSL_CTX_set1_curves(ctx, clist, clistlen) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURVES,clistlen,(char *)clist)
+# define SSL_CTX_set1_curves_list(ctx, s) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURVES_LIST,0,(char *)s)
+# define SSL_set1_curves(ctx, clist, clistlen) \
+        SSL_ctrl(ctx,SSL_CTRL_SET_CURVES,clistlen,(char *)clist)
+# define SSL_set1_curves_list(ctx, s) \
+        SSL_ctrl(ctx,SSL_CTRL_SET_CURVES_LIST,0,(char *)s)
+# define SSL_get_shared_curve(s, n) \
+        SSL_ctrl(s,SSL_CTRL_GET_SHARED_CURVE,n,NULL)
+# define SSL_CTX_set1_sigalgs(ctx, slist, slistlen) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS,slistlen,(int *)slist)
+# define SSL_CTX_set1_sigalgs_list(ctx, s) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)s)
+# define SSL_set1_sigalgs(ctx, slist, slistlen) \
+        SSL_ctrl(ctx,SSL_CTRL_SET_SIGALGS,slistlen,(int *)slist)
+# define SSL_set1_sigalgs_list(ctx, s) \
+        SSL_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)s)
+# define SSL_CTX_set1_client_sigalgs(ctx, slist, slistlen) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,slistlen,(int *)slist)
+# define SSL_CTX_set1_client_sigalgs_list(ctx, s) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)s)
+# define SSL_set1_client_sigalgs(ctx, slist, slistlen) \
+        SSL_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,clistlen,(int *)slist)
+# define SSL_set1_client_sigalgs_list(ctx, s) \
+        SSL_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)s)
+# define SSL_get0_certificate_types(s, clist) \
+        SSL_ctrl(s, SSL_CTRL_GET_CLIENT_CERT_TYPES, 0, (char *)clist)
+# define SSL_CTX_set1_client_certificate_types(ctx, clist, clistlen) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen,(char *)clist)
+# define SSL_set1_client_certificate_types(s, clist, clistlen) \
+        SSL_ctrl(s,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen,(char *)clist)
+# define SSL_get_peer_signature_nid(s, pn) \
+        SSL_ctrl(s,SSL_CTRL_GET_PEER_SIGNATURE_NID,0,pn)
+# define SSL_get_server_tmp_key(s, pk) \
+        SSL_ctrl(s,SSL_CTRL_GET_SERVER_TMP_KEY,0,pk)
+# define SSL_get0_raw_cipherlist(s, plst) \
+        SSL_ctrl(s,SSL_CTRL_GET_RAW_CIPHERLIST,0,plst)
+# define SSL_get0_ec_point_formats(s, plst) \
+        SSL_ctrl(s,SSL_CTRL_GET_EC_POINT_FORMATS,0,plst)
+#define SSL_CTX_set_min_proto_version(ctx, version) \
+        SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL)
+#define SSL_CTX_set_max_proto_version(ctx, version) \
+        SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL)
+#define SSL_set_min_proto_version(s, version) \
+        SSL_ctrl(s, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL)
+#define SSL_set_max_proto_version(s, version) \
+        SSL_ctrl(s, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL)
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+/* Provide some compatibility macros for removed functionality. */
+# define SSL_CTX_need_tmp_RSA(ctx)                0
+# define SSL_CTX_set_tmp_rsa(ctx,rsa)             1
+# define SSL_need_tmp_RSA(ssl)                    0
+# define SSL_set_tmp_rsa(ssl,rsa)                 1
+# define SSL_CTX_set_ecdh_auto(dummy, onoff)      ((onoff) != 0)
+# define SSL_set_ecdh_auto(dummy, onoff)          ((onoff) != 0)
+/*
+ * We "pretend" to call the callback to avoid warnings about unused static
+ * functions.
+ */
+# define SSL_CTX_set_tmp_rsa_callback(ctx, cb)    while(0) (cb)(NULL, 0, 0)
+# define SSL_set_tmp_rsa_callback(ssl, cb)        while(0) (cb)(NULL, 0, 0)
+#endif
+
+__owur const BIO_METHOD *BIO_f_ssl(void);
+__owur BIO *BIO_new_ssl(SSL_CTX *ctx, int client);
+__owur BIO *BIO_new_ssl_connect(SSL_CTX *ctx);
+__owur BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx);
+__owur int BIO_ssl_copy_session_id(BIO *to, BIO *from);
+void BIO_ssl_shutdown(BIO *ssl_bio);
+
+__owur int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str);
+__owur SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth);
+int SSL_CTX_up_ref(SSL_CTX *ctx);
+void SSL_CTX_free(SSL_CTX *);
+__owur long SSL_CTX_set_timeout(SSL_CTX *ctx, long t);
+__owur long SSL_CTX_get_timeout(const SSL_CTX *ctx);
+__owur X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *);
+void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *);
+__owur int SSL_want(const SSL *s);
+__owur int SSL_clear(SSL *s);
+
+void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm);
+
+__owur const SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
+__owur int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits);
+__owur const char *SSL_CIPHER_get_version(const SSL_CIPHER *c);
+__owur const char *SSL_CIPHER_get_name(const SSL_CIPHER *c);
+__owur uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *c);
+__owur int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *c);
+__owur int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *c);
+__owur int SSL_CIPHER_is_aead(const SSL_CIPHER *c);
+
+__owur int SSL_get_fd(const SSL *s);
+__owur int SSL_get_rfd(const SSL *s);
+__owur int SSL_get_wfd(const SSL *s);
+__owur const char *SSL_get_cipher_list(const SSL *s, int n);
+__owur char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len);
+__owur int SSL_get_read_ahead(const SSL *s);
+__owur int SSL_pending(const SSL *s);
+__owur int SSL_has_pending(const SSL *s);
+# ifndef OPENSSL_NO_SOCK
+__owur int SSL_set_fd(SSL *s, int fd);
+__owur int SSL_set_rfd(SSL *s, int fd);
+__owur int SSL_set_wfd(SSL *s, int fd);
+# endif
+void SSL_set0_rbio(SSL *s, BIO *rbio);
+void SSL_set0_wbio(SSL *s, BIO *wbio);
+void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio);
+__owur BIO *SSL_get_rbio(const SSL *s);
+__owur BIO *SSL_get_wbio(const SSL *s);
+__owur int SSL_set_cipher_list(SSL *s, const char *str);
+void SSL_set_read_ahead(SSL *s, int yes);
+__owur int SSL_get_verify_mode(const SSL *s);
+__owur int SSL_get_verify_depth(const SSL *s);
+__owur SSL_verify_cb SSL_get_verify_callback(const SSL *s);
+void SSL_set_verify(SSL *s, int mode, SSL_verify_cb callback);
+void SSL_set_verify_depth(SSL *s, int depth);
+void SSL_set_cert_cb(SSL *s, int (*cb) (SSL *ssl, void *arg), void *arg);
+# ifndef OPENSSL_NO_RSA
+__owur int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
+__owur int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len);
+# endif
+__owur int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
+__owur int SSL_use_PrivateKey_ASN1(int pk, SSL *ssl, const unsigned char *d,
+                            long len);
+__owur int SSL_use_certificate(SSL *ssl, X509 *x);
+__owur int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
+
+/* Set serverinfo data for the current active cert. */
+__owur int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
+                           size_t serverinfo_length);
+__owur int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file);
+
+#ifndef OPENSSL_NO_RSA
+__owur int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
+#endif
+
+__owur int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type);
+__owur int SSL_use_certificate_file(SSL *ssl, const char *file, int type);
+
+#ifndef OPENSSL_NO_RSA
+__owur int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type);
+#endif
+__owur int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
+__owur int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
+/* PEM type */
+__owur int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file);
+__owur int SSL_use_certificate_chain_file(SSL *ssl, const char *file);
+__owur STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file);
+__owur int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
+                                        const char *file);
+int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
+                                       const char *dir);
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+# define SSL_load_error_strings() \
+    OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS \
+                     | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL)
+#endif
+
+__owur const char *SSL_state_string(const SSL *s);
+__owur const char *SSL_rstate_string(const SSL *s);
+__owur const char *SSL_state_string_long(const SSL *s);
+__owur const char *SSL_rstate_string_long(const SSL *s);
+__owur long SSL_SESSION_get_time(const SSL_SESSION *s);
+__owur long SSL_SESSION_set_time(SSL_SESSION *s, long t);
+__owur long SSL_SESSION_get_timeout(const SSL_SESSION *s);
+__owur long SSL_SESSION_set_timeout(SSL_SESSION *s, long t);
+__owur int SSL_SESSION_get_protocol_version(const SSL_SESSION *s);
+__owur const char *SSL_SESSION_get0_hostname(const SSL_SESSION *s);
+__owur const SSL_CIPHER *SSL_SESSION_get0_cipher(const SSL_SESSION *s);
+__owur int SSL_SESSION_has_ticket(const SSL_SESSION *s);
+__owur unsigned long SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *s);
+void SSL_SESSION_get0_ticket(const SSL_SESSION *s, const unsigned char **tick,
+                            size_t *len);
+__owur int SSL_copy_session_id(SSL *to, const SSL *from);
+__owur X509 *SSL_SESSION_get0_peer(SSL_SESSION *s);
+__owur int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx,
+                                unsigned int sid_ctx_len);
+__owur int SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid,
+                               unsigned int sid_len);
+
+__owur SSL_SESSION *SSL_SESSION_new(void);
+const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s,
+                                        unsigned int *len);
+const unsigned char *SSL_SESSION_get0_id_context(const SSL_SESSION *s,
+                                                unsigned int *len);
+__owur unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s);
+# ifndef OPENSSL_NO_STDIO
+int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *ses);
+# endif
+int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses);
+int SSL_SESSION_print_keylog(BIO *bp, const SSL_SESSION *x);
+int SSL_SESSION_up_ref(SSL_SESSION *ses);
+void SSL_SESSION_free(SSL_SESSION *ses);
+__owur int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp);
+__owur int SSL_set_session(SSL *to, SSL_SESSION *session);
+__owur int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
+int SSL_CTX_remove_session(SSL_CTX *, SSL_SESSION *c);
+__owur int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB);
+__owur int SSL_set_generate_session_id(SSL *, GEN_SESSION_CB);
+__owur int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
+                                unsigned int id_len);
+SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
+                             long length);
+
+# ifdef HEADER_X509_H
+__owur X509 *SSL_get_peer_certificate(const SSL *s);
+# endif
+
+__owur STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s);
+
+__owur int SSL_CTX_get_verify_mode(const SSL_CTX *ctx);
+__owur int SSL_CTX_get_verify_depth(const SSL_CTX *ctx);
+__owur SSL_verify_cb SSL_CTX_get_verify_callback(const SSL_CTX *ctx);
+void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, SSL_verify_cb callback);
+void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth);
+void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,
+                                      int (*cb) (X509_STORE_CTX *, void *),
+                                      void *arg);
+void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb) (SSL *ssl, void *arg),
+                         void *arg);
+# ifndef OPENSSL_NO_RSA
+__owur int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
+__owur int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d,
+                                   long len);
+# endif
+__owur int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
+__owur int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx,
+                                const unsigned char *d, long len);
+__owur int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);
+__owur int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len,
+                                 const unsigned char *d);
+
+void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb);
+void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u);
+pem_password_cb *SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx);
+void *SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx);
+void SSL_set_default_passwd_cb(SSL *s, pem_password_cb *cb);
+void SSL_set_default_passwd_cb_userdata(SSL *s, void *u);
+pem_password_cb *SSL_get_default_passwd_cb(SSL *s);
+void *SSL_get_default_passwd_cb_userdata(SSL *s);
+
+__owur int SSL_CTX_check_private_key(const SSL_CTX *ctx);
+__owur int SSL_check_private_key(const SSL *ctx);
+
+__owur int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx,
+                                   unsigned int sid_ctx_len);
+
+SSL *SSL_new(SSL_CTX *ctx);
+int SSL_up_ref(SSL *s);
+int SSL_is_dtls(const SSL *s);
+__owur int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx,
+                               unsigned int sid_ctx_len);
+
+__owur int SSL_CTX_set_purpose(SSL_CTX *s, int purpose);
+__owur int SSL_set_purpose(SSL *s, int purpose);
+__owur int SSL_CTX_set_trust(SSL_CTX *s, int trust);
+__owur int SSL_set_trust(SSL *s, int trust);
+
+__owur int SSL_set1_host(SSL *s, const char *hostname);
+__owur int SSL_add1_host(SSL *s, const char *hostname);
+__owur const char *SSL_get0_peername(SSL *s);
+void SSL_set_hostflags(SSL *s, unsigned int flags);
+
+__owur int SSL_CTX_dane_enable(SSL_CTX *ctx);
+__owur int SSL_CTX_dane_mtype_set(SSL_CTX *ctx, const EVP_MD *md,
+                                  uint8_t mtype, uint8_t ord);
+__owur int SSL_dane_enable(SSL *s, const char *basedomain);
+__owur int SSL_dane_tlsa_add(SSL *s, uint8_t usage, uint8_t selector,
+                             uint8_t mtype, unsigned char *data, size_t dlen);
+__owur int SSL_get0_dane_authority(SSL *s, X509 **mcert, EVP_PKEY **mspki);
+__owur int SSL_get0_dane_tlsa(SSL *s, uint8_t *usage, uint8_t *selector,
+                              uint8_t *mtype, unsigned const char **data,
+                              size_t *dlen);
+/*
+ * Bridge opacity barrier between libcrypt and libssl, also needed to support
+ * offline testing in test/danetest.c
+ */
+SSL_DANE *SSL_get0_dane(SSL *ssl);
+/*
+ * DANE flags
+ */
+unsigned long SSL_CTX_dane_set_flags(SSL_CTX *ctx, unsigned long flags);
+unsigned long SSL_CTX_dane_clear_flags(SSL_CTX *ctx, unsigned long flags);
+unsigned long SSL_dane_set_flags(SSL *ssl, unsigned long flags);
+unsigned long SSL_dane_clear_flags(SSL *ssl, unsigned long flags);
+
+__owur int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm);
+__owur int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm);
+
+__owur X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx);
+__owur X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl);
+
+# ifndef OPENSSL_NO_SRP
+int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name);
+int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password);
+int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength);
+int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx,
+                                        char *(*cb) (SSL *, void *));
+int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx,
+                                          int (*cb) (SSL *, void *));
+int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx,
+                                      int (*cb) (SSL *, int *, void *));
+int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg);
+
+int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g,
+                             BIGNUM *sa, BIGNUM *v, char *info);
+int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass,
+                                const char *grp);
+
+__owur BIGNUM *SSL_get_srp_g(SSL *s);
+__owur BIGNUM *SSL_get_srp_N(SSL *s);
+
+__owur char *SSL_get_srp_username(SSL *s);
+__owur char *SSL_get_srp_userinfo(SSL *s);
+# endif
+
+void SSL_certs_clear(SSL *s);
+void SSL_free(SSL *ssl);
+# ifdef OSSL_ASYNC_FD
+/*
+ * Windows application developer has to include windows.h to use these.
+ */
+__owur int SSL_waiting_for_async(SSL *s);
+__owur int SSL_get_all_async_fds(SSL *s, OSSL_ASYNC_FD *fds, size_t *numfds);
+__owur int SSL_get_changed_async_fds(SSL *s, OSSL_ASYNC_FD *addfd,
+                                     size_t *numaddfds, OSSL_ASYNC_FD *delfd,
+                                     size_t *numdelfds);
+# endif
+__owur int SSL_accept(SSL *ssl);
+__owur int SSL_connect(SSL *ssl);
+__owur int SSL_read(SSL *ssl, void *buf, int num);
+__owur int SSL_peek(SSL *ssl, void *buf, int num);
+__owur int SSL_write(SSL *ssl, const void *buf, int num);
+long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg);
+long SSL_callback_ctrl(SSL *, int, void (*)(void));
+long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg);
+long SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void));
+
+__owur int SSL_get_error(const SSL *s, int ret_code);
+__owur const char *SSL_get_version(const SSL *s);
+
+/* This sets the 'default' SSL version that SSL_new() will create */
+__owur int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth);
+
+# ifndef OPENSSL_NO_SSL3_METHOD
+DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *SSLv3_method(void)) /* SSLv3 */
+DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *SSLv3_server_method(void)) /* SSLv3 */
+DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *SSLv3_client_method(void)) /* SSLv3 */
+# endif
+
+#define SSLv23_method           TLS_method
+#define SSLv23_server_method    TLS_server_method
+#define SSLv23_client_method    TLS_client_method
+
+/* Negotiate highest available SSL/TLS version */
+__owur const SSL_METHOD *TLS_method(void);
+__owur const SSL_METHOD *TLS_server_method(void);
+__owur const SSL_METHOD *TLS_client_method(void);
+
+# ifndef OPENSSL_NO_TLS1_METHOD
+DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_method(void)) /* TLSv1.0 */
+DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_server_method(void)) /* TLSv1.0 */
+DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_client_method(void)) /* TLSv1.0 */
+# endif
+
+# ifndef OPENSSL_NO_TLS1_1_METHOD
+DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_1_method(void)) /* TLSv1.1 */
+DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_1_server_method(void)) /* TLSv1.1 */
+DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_1_client_method(void)) /* TLSv1.1 */
+# endif
+
+# ifndef OPENSSL_NO_TLS1_2_METHOD
+DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_method(void)) /* TLSv1.2 */
+DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_server_method(void)) /* TLSv1.2 */
+DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *TLSv1_2_client_method(void)) /* TLSv1.2 */
+# endif
+
+# ifndef OPENSSL_NO_DTLS1_METHOD
+DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_method(void)) /* DTLSv1.0 */
+DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_server_method(void)) /* DTLSv1.0 */
+DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_client_method(void)) /* DTLSv1.0 */
+# endif
+
+# ifndef OPENSSL_NO_DTLS1_2_METHOD
+DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_2_method(void)) /* DTLSv1.2 */
+DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_2_server_method(void)) /* DTLSv1.2 */
+DEPRECATEDIN_1_1_0(__owur const SSL_METHOD *DTLSv1_2_client_method(void)) /* DTLSv1.2 */
+#endif
+
+__owur const SSL_METHOD *DTLS_method(void); /* DTLS 1.0 and 1.2 */
+__owur const SSL_METHOD *DTLS_server_method(void); /* DTLS 1.0 and 1.2 */
+__owur const SSL_METHOD *DTLS_client_method(void); /* DTLS 1.0 and 1.2 */
+
+__owur STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
+__owur STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx);
+__owur STACK_OF(SSL_CIPHER) *SSL_get_client_ciphers(const SSL *s);
+__owur STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s);
+
+__owur int SSL_do_handshake(SSL *s);
+int SSL_renegotiate(SSL *s);
+__owur int SSL_renegotiate_abbreviated(SSL *s);
+__owur int SSL_renegotiate_pending(SSL *s);
+int SSL_shutdown(SSL *s);
+
+__owur const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx);
+__owur const SSL_METHOD *SSL_get_ssl_method(SSL *s);
+__owur int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method);
+__owur const char *SSL_alert_type_string_long(int value);
+__owur const char *SSL_alert_type_string(int value);
+__owur const char *SSL_alert_desc_string_long(int value);
+__owur const char *SSL_alert_desc_string(int value);
+
+void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list);
+void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list);
+__owur STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s);
+__owur STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s);
+__owur int SSL_add_client_CA(SSL *ssl, X509 *x);
+__owur int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x);
+
+void SSL_set_connect_state(SSL *s);
+void SSL_set_accept_state(SSL *s);
+
+__owur long SSL_get_default_timeout(const SSL *s);
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+# define SSL_library_init() OPENSSL_init_ssl(0, NULL)
+#endif
+
+__owur char *SSL_CIPHER_description(const SSL_CIPHER *, char *buf, int size);
+__owur STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk);
+
+__owur SSL *SSL_dup(SSL *ssl);
+
+__owur X509 *SSL_get_certificate(const SSL *ssl);
+/*
+ * EVP_PKEY
+ */ struct evp_pkey_st *SSL_get_privatekey(const SSL *ssl);
+
+__owur X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx);
+__owur EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx);
+
+void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode);
+__owur int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx);
+void SSL_set_quiet_shutdown(SSL *ssl, int mode);
+__owur int SSL_get_quiet_shutdown(const SSL *ssl);
+void SSL_set_shutdown(SSL *ssl, int mode);
+__owur int SSL_get_shutdown(const SSL *ssl);
+__owur int SSL_version(const SSL *ssl);
+__owur int SSL_client_version(const SSL *s);
+__owur int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
+__owur int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx);
+__owur int SSL_CTX_set_default_verify_file(SSL_CTX *ctx);
+__owur int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
+                                  const char *CApath);
+# define SSL_get0_session SSL_get_session/* just peek at pointer */
+__owur SSL_SESSION *SSL_get_session(const SSL *ssl);
+__owur SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */
+__owur SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
+SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx);
+void SSL_set_info_callback(SSL *ssl,
+                           void (*cb) (const SSL *ssl, int type, int val));
+void (*SSL_get_info_callback(const SSL *ssl)) (const SSL *ssl, int type,
+                                               int val);
+__owur OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl);
+
+void SSL_set_verify_result(SSL *ssl, long v);
+__owur long SSL_get_verify_result(const SSL *ssl);
+__owur STACK_OF(X509) *SSL_get0_verified_chain(const SSL *s);
+
+__owur size_t SSL_get_client_random(const SSL *ssl, unsigned char *out,
+                                    size_t outlen);
+__owur size_t SSL_get_server_random(const SSL *ssl, unsigned char *out,
+                                    size_t outlen);
+__owur size_t SSL_SESSION_get_master_key(const SSL_SESSION *ssl,
+                                         unsigned char *out, size_t outlen);
+
+#define SSL_get_ex_new_index(l, p, newf, dupf, freef) \
+    CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, l, p, newf, dupf, freef)
+__owur int SSL_set_ex_data(SSL *ssl, int idx, void *data);
+void *SSL_get_ex_data(const SSL *ssl, int idx);
+#define SSL_SESSION_get_ex_new_index(l, p, newf, dupf, freef) \
+    CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, l, p, newf, dupf, freef)
+__owur int SSL_SESSION_set_ex_data(SSL_SESSION *ss, int idx, void *data);
+void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss, int idx);
+#define SSL_CTX_get_ex_new_index(l, p, newf, dupf, freef) \
+    CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, l, p, newf, dupf, freef)
+__owur int SSL_CTX_set_ex_data(SSL_CTX *ssl, int idx, void *data);
+void *SSL_CTX_get_ex_data(const SSL_CTX *ssl, int idx);
+
+__owur int SSL_get_ex_data_X509_STORE_CTX_idx(void);
+
+# define SSL_CTX_sess_set_cache_size(ctx,t) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL)
+# define SSL_CTX_sess_get_cache_size(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_SIZE,0,NULL)
+# define SSL_CTX_set_session_cache_mode(ctx,m) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL)
+# define SSL_CTX_get_session_cache_mode(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL)
+
+# define SSL_CTX_get_default_read_ahead(ctx) SSL_CTX_get_read_ahead(ctx)
+# define SSL_CTX_set_default_read_ahead(ctx,m) SSL_CTX_set_read_ahead(ctx,m)
+# define SSL_CTX_get_read_ahead(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL)
+# define SSL_CTX_set_read_ahead(ctx,m) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL)
+# define SSL_CTX_get_max_cert_list(ctx) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL)
+# define SSL_CTX_set_max_cert_list(ctx,m) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL)
+# define SSL_get_max_cert_list(ssl) \
+        SSL_ctrl(ssl,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL)
+# define SSL_set_max_cert_list(ssl,m) \
+        SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL)
+
+# define SSL_CTX_set_max_send_fragment(ctx,m) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL)
+# define SSL_set_max_send_fragment(ssl,m) \
+        SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL)
+# define SSL_CTX_set_split_send_fragment(ctx,m) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SPLIT_SEND_FRAGMENT,m,NULL)
+# define SSL_set_split_send_fragment(ssl,m) \
+        SSL_ctrl(ssl,SSL_CTRL_SET_SPLIT_SEND_FRAGMENT,m,NULL)
+# define SSL_CTX_set_max_pipelines(ctx,m) \
+        SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_PIPELINES,m,NULL)
+# define SSL_set_max_pipelines(ssl,m) \
+        SSL_ctrl(ssl,SSL_CTRL_SET_MAX_PIPELINES,m,NULL)
+
+void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len);
+void SSL_set_default_read_buffer_len(SSL *s, size_t len);
+
+# ifndef OPENSSL_NO_DH
+/* NB: the |keylength| is only applicable when is_export is true */
+void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
+                                 DH *(*dh) (SSL *ssl, int is_export,
+                                            int keylength));
+void SSL_set_tmp_dh_callback(SSL *ssl,
+                             DH *(*dh) (SSL *ssl, int is_export,
+                                        int keylength));
+# endif
+
+__owur const COMP_METHOD *SSL_get_current_compression(SSL *s);
+__owur const COMP_METHOD *SSL_get_current_expansion(SSL *s);
+__owur const char *SSL_COMP_get_name(const COMP_METHOD *comp);
+__owur const char *SSL_COMP_get0_name(const SSL_COMP *comp);
+__owur int SSL_COMP_get_id(const SSL_COMP *comp);
+STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void);
+__owur STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP)
+                                                      *meths);
+#if OPENSSL_API_COMPAT < 0x10100000L
+# define SSL_COMP_free_compression_methods() while(0) continue
+#endif
+__owur int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm);
+
+const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr);
+int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *c);
+int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *c);
+
+/* TLS extensions functions */
+__owur int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len);
+
+__owur int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
+                                  void *arg);
+
+/* Pre-shared secret session resumption functions */
+__owur int SSL_set_session_secret_cb(SSL *s,
+                              tls_session_secret_cb_fn tls_session_secret_cb,
+                              void *arg);
+
+void SSL_CTX_set_not_resumable_session_callback(SSL_CTX *ctx,
+                                                int (*cb) (SSL *ssl,
+                                                           int
+                                                           is_forward_secure));
+
+void SSL_set_not_resumable_session_callback(SSL *ssl,
+                                            int (*cb) (SSL *ssl,
+                                                       int
+                                                       is_forward_secure));
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  define SSL_cache_hit(s) SSL_session_reused(s)
+# endif
+
+__owur int SSL_session_reused(SSL *s);
+__owur int SSL_is_server(SSL *s);
+
+__owur __owur SSL_CONF_CTX *SSL_CONF_CTX_new(void);
+int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx);
+void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx);
+unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags);
+__owur unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags);
+__owur int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre);
+
+void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl);
+void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx);
+
+__owur int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value);
+__owur int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv);
+__owur int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd);
+
+void SSL_add_ssl_module(void);
+int SSL_config(SSL *s, const char *name);
+int SSL_CTX_config(SSL_CTX *ctx, const char *name);
+
+# ifndef OPENSSL_NO_SSL_TRACE
+void SSL_trace(int write_p, int version, int content_type,
+               const void *buf, size_t len, SSL *ssl, void *arg);
+__owur const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c);
+# endif
+
+# ifndef OPENSSL_NO_SOCK
+int DTLSv1_listen(SSL *s, BIO_ADDR *client);
+# endif
+
+# ifndef OPENSSL_NO_CT
+
+/*
+ * A callback for verifying that the received SCTs are sufficient.
+ * Expected to return 1 if they are sufficient, otherwise 0.
+ * May return a negative integer if an error occurs.
+ * A connection should be aborted if the SCTs are deemed insufficient.
+ */
+typedef int(*ssl_ct_validation_cb)(const CT_POLICY_EVAL_CTX *ctx,
+                                   const STACK_OF(SCT) *scts, void *arg);
+
+/*
+ * Sets a |callback| that is invoked upon receipt of ServerHelloDone to validate
+ * the received SCTs.
+ * If the callback returns a non-positive result, the connection is terminated.
+ * Call this function before beginning a handshake.
+ * If a NULL |callback| is provided, SCT validation is disabled.
+ * |arg| is arbitrary userdata that will be passed to the callback whenever it
+ * is invoked. Ownership of |arg| remains with the caller.
+ *
+ * NOTE: A side-effect of setting a CT callback is that an OCSP stapled response
+ *       will be requested.
+ */
+int SSL_set_ct_validation_callback(SSL *s, ssl_ct_validation_cb callback,
+                                   void *arg);
+int SSL_CTX_set_ct_validation_callback(SSL_CTX *ctx,
+                                       ssl_ct_validation_cb callback,
+                                       void *arg);
+#define SSL_disable_ct(s) \
+        ((void) SSL_set_validation_callback((s), NULL, NULL))
+#define SSL_CTX_disable_ct(ctx) \
+        ((void) SSL_CTX_set_validation_callback((ctx), NULL, NULL))
+
+/*
+ * The validation type enumerates the available behaviours of the built-in SSL
+ * CT validation callback selected via SSL_enable_ct() and SSL_CTX_enable_ct().
+ * The underlying callback is a static function in libssl.
+ */
+enum {
+    SSL_CT_VALIDATION_PERMISSIVE = 0,
+    SSL_CT_VALIDATION_STRICT
+};
+
+/*
+ * Enable CT by setting up a callback that implements one of the built-in
+ * validation variants.  The SSL_CT_VALIDATION_PERMISSIVE variant always
+ * continues the handshake, the application can make appropriate decisions at
+ * handshake completion.  The SSL_CT_VALIDATION_STRICT variant requires at
+ * least one valid SCT, or else handshake termination will be requested.  The
+ * handshake may continue anyway if SSL_VERIFY_NONE is in effect.
+ */
+int SSL_enable_ct(SSL *s, int validation_mode);
+int SSL_CTX_enable_ct(SSL_CTX *ctx, int validation_mode);
+
+/*
+ * Report whether a non-NULL callback is enabled.
+ */
+int SSL_ct_is_enabled(const SSL *s);
+int SSL_CTX_ct_is_enabled(const SSL_CTX *ctx);
+
+/* Gets the SCTs received from a connection */
+const STACK_OF(SCT) *SSL_get0_peer_scts(SSL *s);
+
+/*
+ * Loads the CT log list from the default location.
+ * If a CTLOG_STORE has previously been set using SSL_CTX_set_ctlog_store,
+ * the log information loaded from this file will be appended to the
+ * CTLOG_STORE.
+ * Returns 1 on success, 0 otherwise.
+ */
+int SSL_CTX_set_default_ctlog_list_file(SSL_CTX *ctx);
+
+/*
+ * Loads the CT log list from the specified file path.
+ * If a CTLOG_STORE has previously been set using SSL_CTX_set_ctlog_store,
+ * the log information loaded from this file will be appended to the
+ * CTLOG_STORE.
+ * Returns 1 on success, 0 otherwise.
+ */
+int SSL_CTX_set_ctlog_list_file(SSL_CTX *ctx, const char *path);
+
+/*
+ * Sets the CT log list used by all SSL connections created from this SSL_CTX.
+ * Ownership of the CTLOG_STORE is transferred to the SSL_CTX.
+ */
+void SSL_CTX_set0_ctlog_store(SSL_CTX *ctx, CTLOG_STORE *logs);
+
+/*
+ * Gets the CT log list used by all SSL connections created from this SSL_CTX.
+ * This will be NULL unless one of the following functions has been called:
+ * - SSL_CTX_set_default_ctlog_list_file
+ * - SSL_CTX_set_ctlog_list_file
+ * - SSL_CTX_set_ctlog_store
+ */
+const CTLOG_STORE *SSL_CTX_get0_ctlog_store(const SSL_CTX *ctx);
+
+# endif /* OPENSSL_NO_CT */
+
+/* What the "other" parameter contains in security callback */
+/* Mask for type */
+# define SSL_SECOP_OTHER_TYPE    0xffff0000
+# define SSL_SECOP_OTHER_NONE    0
+# define SSL_SECOP_OTHER_CIPHER  (1 << 16)
+# define SSL_SECOP_OTHER_CURVE   (2 << 16)
+# define SSL_SECOP_OTHER_DH      (3 << 16)
+# define SSL_SECOP_OTHER_PKEY    (4 << 16)
+# define SSL_SECOP_OTHER_SIGALG  (5 << 16)
+# define SSL_SECOP_OTHER_CERT    (6 << 16)
+
+/* Indicated operation refers to peer key or certificate */
+# define SSL_SECOP_PEER          0x1000
+
+/* Values for "op" parameter in security callback */
+
+/* Called to filter ciphers */
+/* Ciphers client supports */
+# define SSL_SECOP_CIPHER_SUPPORTED      (1 | SSL_SECOP_OTHER_CIPHER)
+/* Cipher shared by client/server */
+# define SSL_SECOP_CIPHER_SHARED         (2 | SSL_SECOP_OTHER_CIPHER)
+/* Sanity check of cipher server selects */
+# define SSL_SECOP_CIPHER_CHECK          (3 | SSL_SECOP_OTHER_CIPHER)
+/* Curves supported by client */
+# define SSL_SECOP_CURVE_SUPPORTED       (4 | SSL_SECOP_OTHER_CURVE)
+/* Curves shared by client/server */
+# define SSL_SECOP_CURVE_SHARED          (5 | SSL_SECOP_OTHER_CURVE)
+/* Sanity check of curve server selects */
+# define SSL_SECOP_CURVE_CHECK           (6 | SSL_SECOP_OTHER_CURVE)
+/* Temporary DH key */
+# define SSL_SECOP_TMP_DH                (7 | SSL_SECOP_OTHER_PKEY)
+/* SSL/TLS version */
+# define SSL_SECOP_VERSION               (9 | SSL_SECOP_OTHER_NONE)
+/* Session tickets */
+# define SSL_SECOP_TICKET                (10 | SSL_SECOP_OTHER_NONE)
+/* Supported signature algorithms sent to peer */
+# define SSL_SECOP_SIGALG_SUPPORTED      (11 | SSL_SECOP_OTHER_SIGALG)
+/* Shared signature algorithm */
+# define SSL_SECOP_SIGALG_SHARED         (12 | SSL_SECOP_OTHER_SIGALG)
+/* Sanity check signature algorithm allowed */
+# define SSL_SECOP_SIGALG_CHECK          (13 | SSL_SECOP_OTHER_SIGALG)
+/* Used to get mask of supported public key signature algorithms */
+# define SSL_SECOP_SIGALG_MASK           (14 | SSL_SECOP_OTHER_SIGALG)
+/* Use to see if compression is allowed */
+# define SSL_SECOP_COMPRESSION           (15 | SSL_SECOP_OTHER_NONE)
+/* EE key in certificate */
+# define SSL_SECOP_EE_KEY                (16 | SSL_SECOP_OTHER_CERT)
+/* CA key in certificate */
+# define SSL_SECOP_CA_KEY                (17 | SSL_SECOP_OTHER_CERT)
+/* CA digest algorithm in certificate */
+# define SSL_SECOP_CA_MD                 (18 | SSL_SECOP_OTHER_CERT)
+/* Peer EE key in certificate */
+# define SSL_SECOP_PEER_EE_KEY           (SSL_SECOP_EE_KEY | SSL_SECOP_PEER)
+/* Peer CA key in certificate */
+# define SSL_SECOP_PEER_CA_KEY           (SSL_SECOP_CA_KEY | SSL_SECOP_PEER)
+/* Peer CA digest algorithm in certificate */
+# define SSL_SECOP_PEER_CA_MD            (SSL_SECOP_CA_MD | SSL_SECOP_PEER)
+
+void SSL_set_security_level(SSL *s, int level);
+__owur int SSL_get_security_level(const SSL *s);
+void SSL_set_security_callback(SSL *s,
+                               int (*cb) (const SSL *s, const SSL_CTX *ctx, int op,
+                                          int bits, int nid, void *other,
+                                          void *ex));
+int (*SSL_get_security_callback(const SSL *s)) (const SSL *s, const SSL_CTX *ctx, int op,
+                                                int bits, int nid,
+                                                void *other, void *ex);
+void SSL_set0_security_ex_data(SSL *s, void *ex);
+__owur void *SSL_get0_security_ex_data(const SSL *s);
+
+void SSL_CTX_set_security_level(SSL_CTX *ctx, int level);
+__owur int SSL_CTX_get_security_level(const SSL_CTX *ctx);
+void SSL_CTX_set_security_callback(SSL_CTX *ctx,
+                                   int (*cb) (const SSL *s, const SSL_CTX *ctx, int op,
+                                              int bits, int nid, void *other,
+                                              void *ex));
+int (*SSL_CTX_get_security_callback(const SSL_CTX *ctx)) (const SSL *s,
+                                                          const SSL_CTX *ctx,
+                                                          int op, int bits,
+                                                          int nid,
+                                                          void *other,
+                                                          void *ex);
+void SSL_CTX_set0_security_ex_data(SSL_CTX *ctx, void *ex);
+__owur void *SSL_CTX_get0_security_ex_data(const SSL_CTX *ctx);
+
+/* OPENSSL_INIT flag 0x010000 reserved for internal use */
+#define OPENSSL_INIT_NO_LOAD_SSL_STRINGS    0x00100000L
+#define OPENSSL_INIT_LOAD_SSL_STRINGS       0x00200000L
+
+#define OPENSSL_INIT_SSL_DEFAULT \
+        (OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_LOAD_CRYPTO_STRINGS)
+
+int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings);
+
+# ifndef OPENSSL_NO_UNIT_TEST
+__owur const struct openssl_ssl_test_functions *SSL_test_functions(void);
+# endif
+
+extern const char SSL_version_str[];
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_SSL_strings(void);
+
+/* Error codes for the SSL functions. */
+
+/* Function codes. */
+# define SSL_F_CHECK_SUITEB_CIPHER_LIST                   331
+# define SSL_F_CT_MOVE_SCTS                               345
+# define SSL_F_CT_STRICT                                  349
+# define SSL_F_D2I_SSL_SESSION                            103
+# define SSL_F_DANE_CTX_ENABLE                            347
+# define SSL_F_DANE_MTYPE_SET                             393
+# define SSL_F_DANE_TLSA_ADD                              394
+# define SSL_F_DO_DTLS1_WRITE                             245
+# define SSL_F_DO_SSL3_WRITE                              104
+# define SSL_F_DTLS1_BUFFER_RECORD                        247
+# define SSL_F_DTLS1_CHECK_TIMEOUT_NUM                    318
+# define SSL_F_DTLS1_HEARTBEAT                            305
+# define SSL_F_DTLS1_PREPROCESS_FRAGMENT                  288
+# define SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS             424
+# define SSL_F_DTLS1_PROCESS_RECORD                       257
+# define SSL_F_DTLS1_READ_BYTES                           258
+# define SSL_F_DTLS1_READ_FAILED                          339
+# define SSL_F_DTLS1_RETRANSMIT_MESSAGE                   390
+# define SSL_F_DTLS1_WRITE_APP_DATA_BYTES                 268
+# define SSL_F_DTLSV1_LISTEN                              350
+# define SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC          371
+# define SSL_F_DTLS_CONSTRUCT_HELLO_VERIFY_REQUEST        385
+# define SSL_F_DTLS_GET_REASSEMBLED_MESSAGE               370
+# define SSL_F_DTLS_PROCESS_HELLO_VERIFY                  386
+# define SSL_F_OPENSSL_INIT_SSL                           342
+# define SSL_F_OSSL_STATEM_CLIENT_READ_TRANSITION         417
+# define SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION         418
+# define SSL_F_READ_STATE_MACHINE                         352
+# define SSL_F_SSL3_CHANGE_CIPHER_STATE                   129
+# define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM              130
+# define SSL_F_SSL3_CTRL                                  213
+# define SSL_F_SSL3_CTX_CTRL                              133
+# define SSL_F_SSL3_DIGEST_CACHED_RECORDS                 293
+# define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC                 292
+# define SSL_F_SSL3_FINAL_FINISH_MAC                      285
+# define SSL_F_SSL3_GENERATE_KEY_BLOCK                    238
+# define SSL_F_SSL3_GENERATE_MASTER_SECRET                388
+# define SSL_F_SSL3_GET_RECORD                            143
+# define SSL_F_SSL3_INIT_FINISHED_MAC                     397
+# define SSL_F_SSL3_OUTPUT_CERT_CHAIN                     147
+# define SSL_F_SSL3_READ_BYTES                            148
+# define SSL_F_SSL3_READ_N                                149
+# define SSL_F_SSL3_SETUP_KEY_BLOCK                       157
+# define SSL_F_SSL3_SETUP_READ_BUFFER                     156
+# define SSL_F_SSL3_SETUP_WRITE_BUFFER                    291
+# define SSL_F_SSL3_WRITE_BYTES                           158
+# define SSL_F_SSL3_WRITE_PENDING                         159
+# define SSL_F_SSL_ADD_CERT_CHAIN                         316
+# define SSL_F_SSL_ADD_CERT_TO_BUF                        319
+# define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT        298
+# define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT                 277
+# define SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT           307
+# define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK         215
+# define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK        216
+# define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT        299
+# define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT                 278
+# define SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT           308
+# define SSL_F_SSL_BAD_METHOD                             160
+# define SSL_F_SSL_BUILD_CERT_CHAIN                       332
+# define SSL_F_SSL_BYTES_TO_CIPHER_LIST                   161
+# define SSL_F_SSL_CERT_ADD0_CHAIN_CERT                   346
+# define SSL_F_SSL_CERT_DUP                               221
+# define SSL_F_SSL_CERT_NEW                               162
+# define SSL_F_SSL_CERT_SET0_CHAIN                        340
+# define SSL_F_SSL_CHECK_PRIVATE_KEY                      163
+# define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT               280
+# define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG            279
+# define SSL_F_SSL_CIPHER_PROCESS_RULESTR                 230
+# define SSL_F_SSL_CIPHER_STRENGTH_SORT                   231
+# define SSL_F_SSL_CLEAR                                  164
+# define SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD            165
+# define SSL_F_SSL_CONF_CMD                               334
+# define SSL_F_SSL_CREATE_CIPHER_LIST                     166
+# define SSL_F_SSL_CTRL                                   232
+# define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY                  168
+# define SSL_F_SSL_CTX_ENABLE_CT                          398
+# define SSL_F_SSL_CTX_MAKE_PROFILES                      309
+# define SSL_F_SSL_CTX_NEW                                169
+# define SSL_F_SSL_CTX_SET_ALPN_PROTOS                    343
+# define SSL_F_SSL_CTX_SET_CIPHER_LIST                    269
+# define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE             290
+# define SSL_F_SSL_CTX_SET_CT_VALIDATION_CALLBACK         396
+# define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT             219
+# define SSL_F_SSL_CTX_SET_SSL_VERSION                    170
+# define SSL_F_SSL_CTX_USE_CERTIFICATE                    171
+# define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1               172
+# define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE               173
+# define SSL_F_SSL_CTX_USE_PRIVATEKEY                     174
+# define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1                175
+# define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE                176
+# define SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT              272
+# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY                  177
+# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1             178
+# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE             179
+# define SSL_F_SSL_CTX_USE_SERVERINFO                     336
+# define SSL_F_SSL_CTX_USE_SERVERINFO_FILE                337
+# define SSL_F_SSL_DANE_DUP                               403
+# define SSL_F_SSL_DANE_ENABLE                            395
+# define SSL_F_SSL_DO_CONFIG                              391
+# define SSL_F_SSL_DO_HANDSHAKE                           180
+# define SSL_F_SSL_DUP_CA_LIST                            408
+# define SSL_F_SSL_ENABLE_CT                              402
+# define SSL_F_SSL_GET_NEW_SESSION                        181
+# define SSL_F_SSL_GET_PREV_SESSION                       217
+# define SSL_F_SSL_GET_SERVER_CERT_INDEX                  322
+# define SSL_F_SSL_GET_SIGN_PKEY                          183
+# define SSL_F_SSL_INIT_WBIO_BUFFER                       184
+# define SSL_F_SSL_LOAD_CLIENT_CA_FILE                    185
+# define SSL_F_SSL_MODULE_INIT                            392
+# define SSL_F_SSL_NEW                                    186
+# define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT      300
+# define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT               302
+# define SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT         310
+# define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT      301
+# define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT               303
+# define SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT         311
+# define SSL_F_SSL_PEEK                                   270
+# define SSL_F_SSL_READ                                   223
+# define SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT                320
+# define SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT                321
+# define SSL_F_SSL_SESSION_DUP                            348
+# define SSL_F_SSL_SESSION_NEW                            189
+# define SSL_F_SSL_SESSION_PRINT_FP                       190
+# define SSL_F_SSL_SESSION_SET1_ID                        423
+# define SSL_F_SSL_SESSION_SET1_ID_CONTEXT                312
+# define SSL_F_SSL_SET_ALPN_PROTOS                        344
+# define SSL_F_SSL_SET_CERT                               191
+# define SSL_F_SSL_SET_CIPHER_LIST                        271
+# define SSL_F_SSL_SET_CT_VALIDATION_CALLBACK             399
+# define SSL_F_SSL_SET_FD                                 192
+# define SSL_F_SSL_SET_PKEY                               193
+# define SSL_F_SSL_SET_RFD                                194
+# define SSL_F_SSL_SET_SESSION                            195
+# define SSL_F_SSL_SET_SESSION_ID_CONTEXT                 218
+# define SSL_F_SSL_SET_SESSION_TICKET_EXT                 294
+# define SSL_F_SSL_SET_WFD                                196
+# define SSL_F_SSL_SHUTDOWN                               224
+# define SSL_F_SSL_SRP_CTX_INIT                           313
+# define SSL_F_SSL_START_ASYNC_JOB                        389
+# define SSL_F_SSL_UNDEFINED_FUNCTION                     197
+# define SSL_F_SSL_UNDEFINED_VOID_FUNCTION                244
+# define SSL_F_SSL_USE_CERTIFICATE                        198
+# define SSL_F_SSL_USE_CERTIFICATE_ASN1                   199
+# define SSL_F_SSL_USE_CERTIFICATE_FILE                   200
+# define SSL_F_SSL_USE_PRIVATEKEY                         201
+# define SSL_F_SSL_USE_PRIVATEKEY_ASN1                    202
+# define SSL_F_SSL_USE_PRIVATEKEY_FILE                    203
+# define SSL_F_SSL_USE_PSK_IDENTITY_HINT                  273
+# define SSL_F_SSL_USE_RSAPRIVATEKEY                      204
+# define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1                 205
+# define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE                 206
+# define SSL_F_SSL_VALIDATE_CT                            400
+# define SSL_F_SSL_VERIFY_CERT_CHAIN                      207
+# define SSL_F_SSL_WRITE                                  208
+# define SSL_F_STATE_MACHINE                              353
+# define SSL_F_TLS12_CHECK_PEER_SIGALG                    333
+# define SSL_F_TLS1_CHANGE_CIPHER_STATE                   209
+# define SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS            341
+# define SSL_F_TLS1_ENC                                   401
+# define SSL_F_TLS1_EXPORT_KEYING_MATERIAL                314
+# define SSL_F_TLS1_GET_CURVELIST                         338
+# define SSL_F_TLS1_PRF                                   284
+# define SSL_F_TLS1_SETUP_KEY_BLOCK                       211
+# define SSL_F_TLS1_SET_SERVER_SIGALGS                    335
+# define SSL_F_TLS_CLIENT_KEY_EXCHANGE_POST_WORK          354
+# define SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST          372
+# define SSL_F_TLS_CONSTRUCT_CKE_DHE                      404
+# define SSL_F_TLS_CONSTRUCT_CKE_ECDHE                    405
+# define SSL_F_TLS_CONSTRUCT_CKE_GOST                     406
+# define SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE             407
+# define SSL_F_TLS_CONSTRUCT_CKE_RSA                      409
+# define SSL_F_TLS_CONSTRUCT_CKE_SRP                      410
+# define SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE           355
+# define SSL_F_TLS_CONSTRUCT_CLIENT_HELLO                 356
+# define SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE          357
+# define SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY                358
+# define SSL_F_TLS_CONSTRUCT_FINISHED                     359
+# define SSL_F_TLS_CONSTRUCT_HELLO_REQUEST                373
+# define SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET           428
+# define SSL_F_TLS_CONSTRUCT_SERVER_CERTIFICATE           374
+# define SSL_F_TLS_CONSTRUCT_SERVER_DONE                  375
+# define SSL_F_TLS_CONSTRUCT_SERVER_HELLO                 376
+# define SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE          377
+# define SSL_F_TLS_GET_MESSAGE_BODY                       351
+# define SSL_F_TLS_GET_MESSAGE_HEADER                     387
+# define SSL_F_TLS_POST_PROCESS_CLIENT_HELLO              378
+# define SSL_F_TLS_POST_PROCESS_CLIENT_KEY_EXCHANGE       384
+# define SSL_F_TLS_PREPARE_CLIENT_CERTIFICATE             360
+# define SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST            361
+# define SSL_F_TLS_PROCESS_CERT_STATUS                    362
+# define SSL_F_TLS_PROCESS_CERT_VERIFY                    379
+# define SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC             363
+# define SSL_F_TLS_PROCESS_CKE_DHE                        411
+# define SSL_F_TLS_PROCESS_CKE_ECDHE                      412
+# define SSL_F_TLS_PROCESS_CKE_GOST                       413
+# define SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE               414
+# define SSL_F_TLS_PROCESS_CKE_RSA                        415
+# define SSL_F_TLS_PROCESS_CKE_SRP                        416
+# define SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE             380
+# define SSL_F_TLS_PROCESS_CLIENT_HELLO                   381
+# define SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE            382
+# define SSL_F_TLS_PROCESS_FINISHED                       364
+# define SSL_F_TLS_PROCESS_KEY_EXCHANGE                   365
+# define SSL_F_TLS_PROCESS_NEW_SESSION_TICKET             366
+# define SSL_F_TLS_PROCESS_NEXT_PROTO                     383
+# define SSL_F_TLS_PROCESS_SERVER_CERTIFICATE             367
+# define SSL_F_TLS_PROCESS_SERVER_DONE                    368
+# define SSL_F_TLS_PROCESS_SERVER_HELLO                   369
+# define SSL_F_TLS_PROCESS_SKE_DHE                        419
+# define SSL_F_TLS_PROCESS_SKE_ECDHE                      420
+# define SSL_F_TLS_PROCESS_SKE_PSK_PREAMBLE               421
+# define SSL_F_TLS_PROCESS_SKE_SRP                        422
+# define SSL_F_USE_CERTIFICATE_CHAIN_FILE                 220
+
+/* Reason codes. */
+# define SSL_R_APP_DATA_IN_HANDSHAKE                      100
+# define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272
+# define SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE       143
+# define SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE     158
+# define SSL_R_BAD_CHANGE_CIPHER_SPEC                     103
+# define SSL_R_BAD_DATA                                   390
+# define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK              106
+# define SSL_R_BAD_DECOMPRESSION                          107
+# define SSL_R_BAD_DH_VALUE                               102
+# define SSL_R_BAD_DIGEST_LENGTH                          111
+# define SSL_R_BAD_ECC_CERT                               304
+# define SSL_R_BAD_ECPOINT                                306
+# define SSL_R_BAD_HANDSHAKE_LENGTH                       332
+# define SSL_R_BAD_HELLO_REQUEST                          105
+# define SSL_R_BAD_LENGTH                                 271
+# define SSL_R_BAD_PACKET_LENGTH                          115
+# define SSL_R_BAD_PROTOCOL_VERSION_NUMBER                116
+# define SSL_R_BAD_RSA_ENCRYPT                            119
+# define SSL_R_BAD_SIGNATURE                              123
+# define SSL_R_BAD_SRP_A_LENGTH                           347
+# define SSL_R_BAD_SRP_PARAMETERS                         371
+# define SSL_R_BAD_SRTP_MKI_VALUE                         352
+# define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST           353
+# define SSL_R_BAD_SSL_FILETYPE                           124
+# define SSL_R_BAD_VALUE                                  384
+# define SSL_R_BAD_WRITE_RETRY                            127
+# define SSL_R_BIO_NOT_SET                                128
+# define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG                  129
+# define SSL_R_BN_LIB                                     130
+# define SSL_R_CA_DN_LENGTH_MISMATCH                      131
+# define SSL_R_CA_KEY_TOO_SMALL                           397
+# define SSL_R_CA_MD_TOO_WEAK                             398
+# define SSL_R_CCS_RECEIVED_EARLY                         133
+# define SSL_R_CERTIFICATE_VERIFY_FAILED                  134
+# define SSL_R_CERT_CB_ERROR                              377
+# define SSL_R_CERT_LENGTH_MISMATCH                       135
+# define SSL_R_CIPHER_CODE_WRONG_LENGTH                   137
+# define SSL_R_CIPHER_OR_HASH_UNAVAILABLE                 138
+# define SSL_R_CLIENTHELLO_TLSEXT                         226
+# define SSL_R_COMPRESSED_LENGTH_TOO_LONG                 140
+# define SSL_R_COMPRESSION_DISABLED                       343
+# define SSL_R_COMPRESSION_FAILURE                        141
+# define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE    307
+# define SSL_R_COMPRESSION_LIBRARY_ERROR                  142
+# define SSL_R_CONNECTION_TYPE_NOT_SET                    144
+# define SSL_R_CONTEXT_NOT_DANE_ENABLED                   167
+# define SSL_R_COOKIE_GEN_CALLBACK_FAILURE                400
+# define SSL_R_COOKIE_MISMATCH                            308
+# define SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED       206
+# define SSL_R_DANE_ALREADY_ENABLED                       172
+# define SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL            173
+# define SSL_R_DANE_NOT_ENABLED                           175
+# define SSL_R_DANE_TLSA_BAD_CERTIFICATE                  180
+# define SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE            184
+# define SSL_R_DANE_TLSA_BAD_DATA_LENGTH                  189
+# define SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH                192
+# define SSL_R_DANE_TLSA_BAD_MATCHING_TYPE                200
+# define SSL_R_DANE_TLSA_BAD_PUBLIC_KEY                   201
+# define SSL_R_DANE_TLSA_BAD_SELECTOR                     202
+# define SSL_R_DANE_TLSA_NULL_DATA                        203
+# define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED              145
+# define SSL_R_DATA_LENGTH_TOO_LONG                       146
+# define SSL_R_DECRYPTION_FAILED                          147
+# define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC        281
+# define SSL_R_DH_KEY_TOO_SMALL                           394
+# define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG            148
+# define SSL_R_DIGEST_CHECK_FAILED                        149
+# define SSL_R_DTLS_MESSAGE_TOO_BIG                       334
+# define SSL_R_DUPLICATE_COMPRESSION_ID                   309
+# define SSL_R_ECC_CERT_NOT_FOR_SIGNING                   318
+# define SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE              374
+# define SSL_R_EE_KEY_TOO_SMALL                           399
+# define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST         354
+# define SSL_R_ENCRYPTED_LENGTH_TOO_LONG                  150
+# define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST              151
+# define SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN             204
+# define SSL_R_EXCESSIVE_MESSAGE_SIZE                     152
+# define SSL_R_EXTRA_DATA_IN_MESSAGE                      153
+# define SSL_R_FAILED_TO_INIT_ASYNC                       405
+# define SSL_R_FRAGMENTED_CLIENT_HELLO                    401
+# define SSL_R_GOT_A_FIN_BEFORE_A_CCS                     154
+# define SSL_R_HTTPS_PROXY_REQUEST                        155
+# define SSL_R_HTTP_REQUEST                               156
+# define SSL_R_ILLEGAL_SUITEB_DIGEST                      380
+# define SSL_R_INAPPROPRIATE_FALLBACK                     373
+# define SSL_R_INCONSISTENT_COMPRESSION                   340
+# define SSL_R_INCONSISTENT_EXTMS                         104
+# define SSL_R_INVALID_COMMAND                            280
+# define SSL_R_INVALID_COMPRESSION_ALGORITHM              341
+# define SSL_R_INVALID_CONFIGURATION_NAME                 113
+# define SSL_R_INVALID_CT_VALIDATION_TYPE                 212
+# define SSL_R_INVALID_NULL_CMD_NAME                      385
+# define SSL_R_INVALID_SEQUENCE_NUMBER                    402
+# define SSL_R_INVALID_SERVERINFO_DATA                    388
+# define SSL_R_INVALID_SRP_USERNAME                       357
+# define SSL_R_INVALID_STATUS_RESPONSE                    328
+# define SSL_R_INVALID_TICKET_KEYS_LENGTH                 325
+# define SSL_R_LENGTH_MISMATCH                            159
+# define SSL_R_LENGTH_TOO_LONG                            404
+# define SSL_R_LENGTH_TOO_SHORT                           160
+# define SSL_R_LIBRARY_BUG                                274
+# define SSL_R_LIBRARY_HAS_NO_CIPHERS                     161
+# define SSL_R_MISSING_DSA_SIGNING_CERT                   165
+# define SSL_R_MISSING_ECDSA_SIGNING_CERT                 381
+# define SSL_R_MISSING_RSA_CERTIFICATE                    168
+# define SSL_R_MISSING_RSA_ENCRYPTING_CERT                169
+# define SSL_R_MISSING_RSA_SIGNING_CERT                   170
+# define SSL_R_MISSING_SRP_PARAM                          358
+# define SSL_R_MISSING_TMP_DH_KEY                         171
+# define SSL_R_MISSING_TMP_ECDH_KEY                       311
+# define SSL_R_NO_CERTIFICATES_RETURNED                   176
+# define SSL_R_NO_CERTIFICATE_ASSIGNED                    177
+# define SSL_R_NO_CERTIFICATE_SET                         179
+# define SSL_R_NO_CIPHERS_AVAILABLE                       181
+# define SSL_R_NO_CIPHERS_SPECIFIED                       183
+# define SSL_R_NO_CIPHER_MATCH                            185
+# define SSL_R_NO_CLIENT_CERT_METHOD                      331
+# define SSL_R_NO_COMPRESSION_SPECIFIED                   187
+# define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER           330
+# define SSL_R_NO_METHOD_SPECIFIED                        188
+# define SSL_R_NO_PEM_EXTENSIONS                          389
+# define SSL_R_NO_PRIVATE_KEY_ASSIGNED                    190
+# define SSL_R_NO_PROTOCOLS_AVAILABLE                     191
+# define SSL_R_NO_RENEGOTIATION                           339
+# define SSL_R_NO_REQUIRED_DIGEST                         324
+# define SSL_R_NO_SHARED_CIPHER                           193
+# define SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS             376
+# define SSL_R_NO_SRTP_PROFILES                           359
+# define SSL_R_NO_VALID_SCTS                              216
+# define SSL_R_NO_VERIFY_COOKIE_CALLBACK                  403
+# define SSL_R_NULL_SSL_CTX                               195
+# define SSL_R_NULL_SSL_METHOD_PASSED                     196
+# define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED            197
+# define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344
+# define SSL_R_PACKET_LENGTH_TOO_LONG                     198
+# define SSL_R_PARSE_TLSEXT                               227
+# define SSL_R_PATH_TOO_LONG                              270
+# define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE          199
+# define SSL_R_PEM_NAME_BAD_PREFIX                        391
+# define SSL_R_PEM_NAME_TOO_SHORT                         392
+# define SSL_R_PIPELINE_FAILURE                           406
+# define SSL_R_PROTOCOL_IS_SHUTDOWN                       207
+# define SSL_R_PSK_IDENTITY_NOT_FOUND                     223
+# define SSL_R_PSK_NO_CLIENT_CB                           224
+# define SSL_R_PSK_NO_SERVER_CB                           225
+# define SSL_R_READ_BIO_NOT_SET                           211
+# define SSL_R_READ_TIMEOUT_EXPIRED                       312
+# define SSL_R_RECORD_LENGTH_MISMATCH                     213
+# define SSL_R_RECORD_TOO_SMALL                           298
+# define SSL_R_RENEGOTIATE_EXT_TOO_LONG                   335
+# define SSL_R_RENEGOTIATION_ENCODING_ERR                 336
+# define SSL_R_RENEGOTIATION_MISMATCH                     337
+# define SSL_R_REQUIRED_CIPHER_MISSING                    215
+# define SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING     342
+# define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING           345
+# define SSL_R_SCT_VERIFICATION_FAILED                    208
+# define SSL_R_SERVERHELLO_TLSEXT                         275
+# define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED           277
+# define SSL_R_SHUTDOWN_WHILE_IN_INIT                     407
+# define SSL_R_SIGNATURE_ALGORITHMS_ERROR                 360
+# define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE      220
+# define SSL_R_SRP_A_CALC                                 361
+# define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES           362
+# define SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG      363
+# define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE            364
+# define SSL_R_SSL3_EXT_INVALID_SERVERNAME                319
+# define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE           320
+# define SSL_R_SSL3_SESSION_ID_TOO_LONG                   300
+# define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE                1042
+# define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC                 1020
+# define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED            1045
+# define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED            1044
+# define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN            1046
+# define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE          1030
+# define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE              1040
+# define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER              1047
+# define SSL_R_SSLV3_ALERT_NO_CERTIFICATE                 1041
+# define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE             1010
+# define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE        1043
+# define SSL_R_SSL_COMMAND_SECTION_EMPTY                  117
+# define SSL_R_SSL_COMMAND_SECTION_NOT_FOUND              125
+# define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION         228
+# define SSL_R_SSL_HANDSHAKE_FAILURE                      229
+# define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS                 230
+# define SSL_R_SSL_NEGATIVE_LENGTH                        372
+# define SSL_R_SSL_SECTION_EMPTY                          126
+# define SSL_R_SSL_SECTION_NOT_FOUND                      136
+# define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED             301
+# define SSL_R_SSL_SESSION_ID_CONFLICT                    302
+# define SSL_R_SSL_SESSION_ID_TOO_LONG                    408
+# define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG            273
+# define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH              303
+# define SSL_R_SSL_SESSION_VERSION_MISMATCH               210
+# define SSL_R_TLSV1_ALERT_ACCESS_DENIED                  1049
+# define SSL_R_TLSV1_ALERT_DECODE_ERROR                   1050
+# define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED              1021
+# define SSL_R_TLSV1_ALERT_DECRYPT_ERROR                  1051
+# define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION             1060
+# define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK         1086
+# define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY          1071
+# define SSL_R_TLSV1_ALERT_INTERNAL_ERROR                 1080
+# define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION               1100
+# define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION               1070
+# define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW                1022
+# define SSL_R_TLSV1_ALERT_UNKNOWN_CA                     1048
+# define SSL_R_TLSV1_ALERT_USER_CANCELLED                 1090
+# define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE           1114
+# define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE      1113
+# define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE             1111
+# define SSL_R_TLSV1_UNRECOGNIZED_NAME                    1112
+# define SSL_R_TLSV1_UNSUPPORTED_EXTENSION                1110
+# define SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT           365
+# define SSL_R_TLS_HEARTBEAT_PENDING                      366
+# define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL                 367
+# define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST             157
+# define SSL_R_TOO_MANY_WARN_ALERTS                       409
+# define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS             314
+# define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS       239
+# define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES           242
+# define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES          243
+# define SSL_R_UNEXPECTED_MESSAGE                         244
+# define SSL_R_UNEXPECTED_RECORD                          245
+# define SSL_R_UNINITIALIZED                              276
+# define SSL_R_UNKNOWN_ALERT_TYPE                         246
+# define SSL_R_UNKNOWN_CERTIFICATE_TYPE                   247
+# define SSL_R_UNKNOWN_CIPHER_RETURNED                    248
+# define SSL_R_UNKNOWN_CIPHER_TYPE                        249
+# define SSL_R_UNKNOWN_CMD_NAME                           386
+# define SSL_R_UNKNOWN_COMMAND                            139
+# define SSL_R_UNKNOWN_DIGEST                             368
+# define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE                  250
+# define SSL_R_UNKNOWN_PKEY_TYPE                          251
+# define SSL_R_UNKNOWN_PROTOCOL                           252
+# define SSL_R_UNKNOWN_SSL_VERSION                        254
+# define SSL_R_UNKNOWN_STATE                              255
+# define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED       338
+# define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM          257
+# define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE                 315
+# define SSL_R_UNSUPPORTED_PROTOCOL                       258
+# define SSL_R_UNSUPPORTED_SSL_VERSION                    259
+# define SSL_R_UNSUPPORTED_STATUS_TYPE                    329
+# define SSL_R_USE_SRTP_NOT_NEGOTIATED                    369
+# define SSL_R_VERSION_TOO_HIGH                           166
+# define SSL_R_VERSION_TOO_LOW                            396
+# define SSL_R_WRONG_CERTIFICATE_TYPE                     383
+# define SSL_R_WRONG_CIPHER_RETURNED                      261
+# define SSL_R_WRONG_CURVE                                378
+# define SSL_R_WRONG_SIGNATURE_LENGTH                     264
+# define SSL_R_WRONG_SIGNATURE_SIZE                       265
+# define SSL_R_WRONG_SIGNATURE_TYPE                       370
+# define SSL_R_WRONG_SSL_VERSION                          266
+# define SSL_R_WRONG_VERSION_NUMBER                       267
+# define SSL_R_X509_LIB                                   268
+# define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS           269
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ssl2.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ssl2.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ssl2.h	(revision 331)
@@ -0,0 +1,24 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_SSL2_H
+# define HEADER_SSL2_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define SSL2_VERSION            0x0002
+
+# define SSL2_MT_CLIENT_HELLO            1
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ssl3.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ssl3.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ssl3.h	(revision 331)
@@ -0,0 +1,310 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_SSL3_H
+# define HEADER_SSL3_H
+
+# include <openssl/comp.h>
+# include <openssl/buffer.h>
+# include <openssl/evp.h>
+# include <openssl/ssl.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Signalling cipher suite value from RFC 5746
+ * (TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
+ */
+# define SSL3_CK_SCSV                            0x030000FF
+
+/*
+ * Signalling cipher suite value from draft-ietf-tls-downgrade-scsv-00
+ * (TLS_FALLBACK_SCSV)
+ */
+# define SSL3_CK_FALLBACK_SCSV                   0x03005600
+
+# define SSL3_CK_RSA_NULL_MD5                    0x03000001
+# define SSL3_CK_RSA_NULL_SHA                    0x03000002
+# define SSL3_CK_RSA_RC4_40_MD5                  0x03000003
+# define SSL3_CK_RSA_RC4_128_MD5                 0x03000004
+# define SSL3_CK_RSA_RC4_128_SHA                 0x03000005
+# define SSL3_CK_RSA_RC2_40_MD5                  0x03000006
+# define SSL3_CK_RSA_IDEA_128_SHA                0x03000007
+# define SSL3_CK_RSA_DES_40_CBC_SHA              0x03000008
+# define SSL3_CK_RSA_DES_64_CBC_SHA              0x03000009
+# define SSL3_CK_RSA_DES_192_CBC3_SHA            0x0300000A
+
+# define SSL3_CK_DH_DSS_DES_40_CBC_SHA           0x0300000B
+# define SSL3_CK_DH_DSS_DES_64_CBC_SHA           0x0300000C
+# define SSL3_CK_DH_DSS_DES_192_CBC3_SHA         0x0300000D
+# define SSL3_CK_DH_RSA_DES_40_CBC_SHA           0x0300000E
+# define SSL3_CK_DH_RSA_DES_64_CBC_SHA           0x0300000F
+# define SSL3_CK_DH_RSA_DES_192_CBC3_SHA         0x03000010
+
+# define SSL3_CK_DHE_DSS_DES_40_CBC_SHA          0x03000011
+# define SSL3_CK_EDH_DSS_DES_40_CBC_SHA          SSL3_CK_DHE_DSS_DES_40_CBC_SHA
+# define SSL3_CK_DHE_DSS_DES_64_CBC_SHA          0x03000012
+# define SSL3_CK_EDH_DSS_DES_64_CBC_SHA          SSL3_CK_DHE_DSS_DES_64_CBC_SHA
+# define SSL3_CK_DHE_DSS_DES_192_CBC3_SHA        0x03000013
+# define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA        SSL3_CK_DHE_DSS_DES_192_CBC3_SHA
+# define SSL3_CK_DHE_RSA_DES_40_CBC_SHA          0x03000014
+# define SSL3_CK_EDH_RSA_DES_40_CBC_SHA          SSL3_CK_DHE_RSA_DES_40_CBC_SHA
+# define SSL3_CK_DHE_RSA_DES_64_CBC_SHA          0x03000015
+# define SSL3_CK_EDH_RSA_DES_64_CBC_SHA          SSL3_CK_DHE_RSA_DES_64_CBC_SHA
+# define SSL3_CK_DHE_RSA_DES_192_CBC3_SHA        0x03000016
+# define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA        SSL3_CK_DHE_RSA_DES_192_CBC3_SHA
+
+# define SSL3_CK_ADH_RC4_40_MD5                  0x03000017
+# define SSL3_CK_ADH_RC4_128_MD5                 0x03000018
+# define SSL3_CK_ADH_DES_40_CBC_SHA              0x03000019
+# define SSL3_CK_ADH_DES_64_CBC_SHA              0x0300001A
+# define SSL3_CK_ADH_DES_192_CBC_SHA             0x0300001B
+
+# define SSL3_TXT_RSA_NULL_MD5                   "NULL-MD5"
+# define SSL3_TXT_RSA_NULL_SHA                   "NULL-SHA"
+# define SSL3_TXT_RSA_RC4_40_MD5                 "EXP-RC4-MD5"
+# define SSL3_TXT_RSA_RC4_128_MD5                "RC4-MD5"
+# define SSL3_TXT_RSA_RC4_128_SHA                "RC4-SHA"
+# define SSL3_TXT_RSA_RC2_40_MD5                 "EXP-RC2-CBC-MD5"
+# define SSL3_TXT_RSA_IDEA_128_SHA               "IDEA-CBC-SHA"
+# define SSL3_TXT_RSA_DES_40_CBC_SHA             "EXP-DES-CBC-SHA"
+# define SSL3_TXT_RSA_DES_64_CBC_SHA             "DES-CBC-SHA"
+# define SSL3_TXT_RSA_DES_192_CBC3_SHA           "DES-CBC3-SHA"
+
+# define SSL3_TXT_DH_DSS_DES_40_CBC_SHA          "EXP-DH-DSS-DES-CBC-SHA"
+# define SSL3_TXT_DH_DSS_DES_64_CBC_SHA          "DH-DSS-DES-CBC-SHA"
+# define SSL3_TXT_DH_DSS_DES_192_CBC3_SHA        "DH-DSS-DES-CBC3-SHA"
+# define SSL3_TXT_DH_RSA_DES_40_CBC_SHA          "EXP-DH-RSA-DES-CBC-SHA"
+# define SSL3_TXT_DH_RSA_DES_64_CBC_SHA          "DH-RSA-DES-CBC-SHA"
+# define SSL3_TXT_DH_RSA_DES_192_CBC3_SHA        "DH-RSA-DES-CBC3-SHA"
+
+# define SSL3_TXT_DHE_DSS_DES_40_CBC_SHA         "EXP-DHE-DSS-DES-CBC-SHA"
+# define SSL3_TXT_DHE_DSS_DES_64_CBC_SHA         "DHE-DSS-DES-CBC-SHA"
+# define SSL3_TXT_DHE_DSS_DES_192_CBC3_SHA       "DHE-DSS-DES-CBC3-SHA"
+# define SSL3_TXT_DHE_RSA_DES_40_CBC_SHA         "EXP-DHE-RSA-DES-CBC-SHA"
+# define SSL3_TXT_DHE_RSA_DES_64_CBC_SHA         "DHE-RSA-DES-CBC-SHA"
+# define SSL3_TXT_DHE_RSA_DES_192_CBC3_SHA       "DHE-RSA-DES-CBC3-SHA"
+
+/*
+ * This next block of six "EDH" labels is for backward compatibility with
+ * older versions of OpenSSL.  New code should use the six "DHE" labels above
+ * instead:
+ */
+# define SSL3_TXT_EDH_DSS_DES_40_CBC_SHA         "EXP-EDH-DSS-DES-CBC-SHA"
+# define SSL3_TXT_EDH_DSS_DES_64_CBC_SHA         "EDH-DSS-DES-CBC-SHA"
+# define SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA       "EDH-DSS-DES-CBC3-SHA"
+# define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA         "EXP-EDH-RSA-DES-CBC-SHA"
+# define SSL3_TXT_EDH_RSA_DES_64_CBC_SHA         "EDH-RSA-DES-CBC-SHA"
+# define SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA       "EDH-RSA-DES-CBC3-SHA"
+
+# define SSL3_TXT_ADH_RC4_40_MD5                 "EXP-ADH-RC4-MD5"
+# define SSL3_TXT_ADH_RC4_128_MD5                "ADH-RC4-MD5"
+# define SSL3_TXT_ADH_DES_40_CBC_SHA             "EXP-ADH-DES-CBC-SHA"
+# define SSL3_TXT_ADH_DES_64_CBC_SHA             "ADH-DES-CBC-SHA"
+# define SSL3_TXT_ADH_DES_192_CBC_SHA            "ADH-DES-CBC3-SHA"
+
+# define SSL3_SSL_SESSION_ID_LENGTH              32
+# define SSL3_MAX_SSL_SESSION_ID_LENGTH          32
+
+# define SSL3_MASTER_SECRET_SIZE                 48
+# define SSL3_RANDOM_SIZE                        32
+# define SSL3_SESSION_ID_SIZE                    32
+# define SSL3_RT_HEADER_LENGTH                   5
+
+# define SSL3_HM_HEADER_LENGTH                  4
+
+# ifndef SSL3_ALIGN_PAYLOAD
+ /*
+  * Some will argue that this increases memory footprint, but it's not
+  * actually true. Point is that malloc has to return at least 64-bit aligned
+  * pointers, meaning that allocating 5 bytes wastes 3 bytes in either case.
+  * Suggested pre-gaping simply moves these wasted bytes from the end of
+  * allocated region to its front, but makes data payload aligned, which
+  * improves performance:-)
+  */
+#  define SSL3_ALIGN_PAYLOAD                     8
+# else
+#  if (SSL3_ALIGN_PAYLOAD&(SSL3_ALIGN_PAYLOAD-1))!=0
+#   error "insane SSL3_ALIGN_PAYLOAD"
+#   undef SSL3_ALIGN_PAYLOAD
+#  endif
+# endif
+
+/*
+ * This is the maximum MAC (digest) size used by the SSL library. Currently
+ * maximum of 20 is used by SHA1, but we reserve for future extension for
+ * 512-bit hashes.
+ */
+
+# define SSL3_RT_MAX_MD_SIZE                     64
+
+/*
+ * Maximum block size used in all ciphersuites. Currently 16 for AES.
+ */
+
+# define SSL_RT_MAX_CIPHER_BLOCK_SIZE            16
+
+# define SSL3_RT_MAX_EXTRA                       (16384)
+
+/* Maximum plaintext length: defined by SSL/TLS standards */
+# define SSL3_RT_MAX_PLAIN_LENGTH                16384
+/* Maximum compression overhead: defined by SSL/TLS standards */
+# define SSL3_RT_MAX_COMPRESSED_OVERHEAD         1024
+
+/*
+ * The standards give a maximum encryption overhead of 1024 bytes. In
+ * practice the value is lower than this. The overhead is the maximum number
+ * of padding bytes (256) plus the mac size.
+ */
+# define SSL3_RT_MAX_ENCRYPTED_OVERHEAD  (256 + SSL3_RT_MAX_MD_SIZE)
+
+/*
+ * OpenSSL currently only uses a padding length of at most one block so the
+ * send overhead is smaller.
+ */
+
+# define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \
+                        (SSL_RT_MAX_CIPHER_BLOCK_SIZE + SSL3_RT_MAX_MD_SIZE)
+
+/* If compression isn't used don't include the compression overhead */
+
+# ifdef OPENSSL_NO_COMP
+#  define SSL3_RT_MAX_COMPRESSED_LENGTH           SSL3_RT_MAX_PLAIN_LENGTH
+# else
+#  define SSL3_RT_MAX_COMPRESSED_LENGTH   \
+                (SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD)
+# endif
+# define SSL3_RT_MAX_ENCRYPTED_LENGTH    \
+                (SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH)
+# define SSL3_RT_MAX_PACKET_SIZE         \
+                (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
+
+# define SSL3_MD_CLIENT_FINISHED_CONST   "\x43\x4C\x4E\x54"
+# define SSL3_MD_SERVER_FINISHED_CONST   "\x53\x52\x56\x52"
+
+# define SSL3_VERSION                    0x0300
+# define SSL3_VERSION_MAJOR              0x03
+# define SSL3_VERSION_MINOR              0x00
+
+# define SSL3_RT_CHANGE_CIPHER_SPEC      20
+# define SSL3_RT_ALERT                   21
+# define SSL3_RT_HANDSHAKE               22
+# define SSL3_RT_APPLICATION_DATA        23
+# define DTLS1_RT_HEARTBEAT              24
+
+/* Pseudo content types to indicate additional parameters */
+# define TLS1_RT_CRYPTO                  0x1000
+# define TLS1_RT_CRYPTO_PREMASTER        (TLS1_RT_CRYPTO | 0x1)
+# define TLS1_RT_CRYPTO_CLIENT_RANDOM    (TLS1_RT_CRYPTO | 0x2)
+# define TLS1_RT_CRYPTO_SERVER_RANDOM    (TLS1_RT_CRYPTO | 0x3)
+# define TLS1_RT_CRYPTO_MASTER           (TLS1_RT_CRYPTO | 0x4)
+
+# define TLS1_RT_CRYPTO_READ             0x0000
+# define TLS1_RT_CRYPTO_WRITE            0x0100
+# define TLS1_RT_CRYPTO_MAC              (TLS1_RT_CRYPTO | 0x5)
+# define TLS1_RT_CRYPTO_KEY              (TLS1_RT_CRYPTO | 0x6)
+# define TLS1_RT_CRYPTO_IV               (TLS1_RT_CRYPTO | 0x7)
+# define TLS1_RT_CRYPTO_FIXED_IV         (TLS1_RT_CRYPTO | 0x8)
+
+/* Pseudo content type for SSL/TLS header info */
+# define SSL3_RT_HEADER                  0x100
+
+# define SSL3_AL_WARNING                 1
+# define SSL3_AL_FATAL                   2
+
+# define SSL3_AD_CLOSE_NOTIFY             0
+# define SSL3_AD_UNEXPECTED_MESSAGE      10/* fatal */
+# define SSL3_AD_BAD_RECORD_MAC          20/* fatal */
+# define SSL3_AD_DECOMPRESSION_FAILURE   30/* fatal */
+# define SSL3_AD_HANDSHAKE_FAILURE       40/* fatal */
+# define SSL3_AD_NO_CERTIFICATE          41
+# define SSL3_AD_BAD_CERTIFICATE         42
+# define SSL3_AD_UNSUPPORTED_CERTIFICATE 43
+# define SSL3_AD_CERTIFICATE_REVOKED     44
+# define SSL3_AD_CERTIFICATE_EXPIRED     45
+# define SSL3_AD_CERTIFICATE_UNKNOWN     46
+# define SSL3_AD_ILLEGAL_PARAMETER       47/* fatal */
+
+# define TLS1_HB_REQUEST         1
+# define TLS1_HB_RESPONSE        2
+
+
+# define SSL3_CT_RSA_SIGN                        1
+# define SSL3_CT_DSS_SIGN                        2
+# define SSL3_CT_RSA_FIXED_DH                    3
+# define SSL3_CT_DSS_FIXED_DH                    4
+# define SSL3_CT_RSA_EPHEMERAL_DH                5
+# define SSL3_CT_DSS_EPHEMERAL_DH                6
+# define SSL3_CT_FORTEZZA_DMS                    20
+/*
+ * SSL3_CT_NUMBER is used to size arrays and it must be large enough to
+ * contain all of the cert types defined either for SSLv3 and TLSv1.
+ */
+# define SSL3_CT_NUMBER                  9
+
+# define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS       0x0001
+
+/* Removed from OpenSSL 1.1.0 */
+# define TLS1_FLAGS_TLS_PADDING_BUG              0x0
+
+# define TLS1_FLAGS_SKIP_CERT_VERIFY             0x0010
+
+/* Set if we encrypt then mac instead of usual mac then encrypt */
+# define TLS1_FLAGS_ENCRYPT_THEN_MAC_READ        0x0100
+# define TLS1_FLAGS_ENCRYPT_THEN_MAC             TLS1_FLAGS_ENCRYPT_THEN_MAC_READ
+
+/* Set if extended master secret extension received from peer */
+# define TLS1_FLAGS_RECEIVED_EXTMS               0x0200
+
+# define TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE       0x0400
+
+# define SSL3_MT_HELLO_REQUEST                   0
+# define SSL3_MT_CLIENT_HELLO                    1
+# define SSL3_MT_SERVER_HELLO                    2
+# define SSL3_MT_NEWSESSION_TICKET               4
+# define SSL3_MT_CERTIFICATE                     11
+# define SSL3_MT_SERVER_KEY_EXCHANGE             12
+# define SSL3_MT_CERTIFICATE_REQUEST             13
+# define SSL3_MT_SERVER_DONE                     14
+# define SSL3_MT_CERTIFICATE_VERIFY              15
+# define SSL3_MT_CLIENT_KEY_EXCHANGE             16
+# define SSL3_MT_FINISHED                        20
+# define SSL3_MT_CERTIFICATE_STATUS              22
+# ifndef OPENSSL_NO_NEXTPROTONEG
+#  define SSL3_MT_NEXT_PROTO                      67
+# endif
+# define DTLS1_MT_HELLO_VERIFY_REQUEST    3
+
+/* Dummy message type for handling CCS like a normal handshake message */
+# define SSL3_MT_CHANGE_CIPHER_SPEC              0x0101
+
+# define SSL3_MT_CCS                             1
+
+/* These are used when changing over to a new cipher */
+# define SSL3_CC_READ            0x01
+# define SSL3_CC_WRITE           0x02
+# define SSL3_CC_CLIENT          0x10
+# define SSL3_CC_SERVER          0x20
+# define SSL3_CHANGE_CIPHER_CLIENT_WRITE (SSL3_CC_CLIENT|SSL3_CC_WRITE)
+# define SSL3_CHANGE_CIPHER_SERVER_READ  (SSL3_CC_SERVER|SSL3_CC_READ)
+# define SSL3_CHANGE_CIPHER_CLIENT_READ  (SSL3_CC_CLIENT|SSL3_CC_READ)
+# define SSL3_CHANGE_CIPHER_SERVER_WRITE (SSL3_CC_SERVER|SSL3_CC_WRITE)
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/stack.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/stack.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/stack.h	(revision 331)
@@ -0,0 +1,78 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_STACK_H
+# define HEADER_STACK_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct stack_st OPENSSL_STACK; /* Use STACK_OF(...) instead */
+
+typedef int (*OPENSSL_sk_compfunc)(const void *, const void *);
+typedef void (*OPENSSL_sk_freefunc)(void *);
+typedef void *(*OPENSSL_sk_copyfunc)(const void *);
+
+int OPENSSL_sk_num(const OPENSSL_STACK *);
+void *OPENSSL_sk_value(const OPENSSL_STACK *, int);
+
+void *OPENSSL_sk_set(OPENSSL_STACK *st, int i, const void *data);
+
+OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_compfunc cmp);
+OPENSSL_STACK *OPENSSL_sk_new_null(void);
+void OPENSSL_sk_free(OPENSSL_STACK *);
+void OPENSSL_sk_pop_free(OPENSSL_STACK *st, void (*func) (void *));
+OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *, OPENSSL_sk_copyfunc c, OPENSSL_sk_freefunc f);
+int OPENSSL_sk_insert(OPENSSL_STACK *sk, const void *data, int where);
+void *OPENSSL_sk_delete(OPENSSL_STACK *st, int loc);
+void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *st, const void *p);
+int OPENSSL_sk_find(OPENSSL_STACK *st, const void *data);
+int OPENSSL_sk_find_ex(OPENSSL_STACK *st, const void *data);
+int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data);
+int OPENSSL_sk_unshift(OPENSSL_STACK *st, const void *data);
+void *OPENSSL_sk_shift(OPENSSL_STACK *st);
+void *OPENSSL_sk_pop(OPENSSL_STACK *st);
+void OPENSSL_sk_zero(OPENSSL_STACK *st);
+OPENSSL_sk_compfunc OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, OPENSSL_sk_compfunc cmp);
+OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *st);
+void OPENSSL_sk_sort(OPENSSL_STACK *st);
+int OPENSSL_sk_is_sorted(const OPENSSL_STACK *st);
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  define _STACK OPENSSL_STACK
+#  define sk_num OPENSSL_sk_num
+#  define sk_value OPENSSL_sk_value
+#  define sk_set OPENSSL_sk_set
+#  define sk_new OPENSSL_sk_new
+#  define sk_new_null OPENSSL_sk_new_null
+#  define sk_free OPENSSL_sk_free
+#  define sk_pop_free OPENSSL_sk_pop_free
+#  define sk_deep_copy OPENSSL_sk_deep_copy
+#  define sk_insert OPENSSL_sk_insert
+#  define sk_delete OPENSSL_sk_delete
+#  define sk_delete_ptr OPENSSL_sk_delete_ptr
+#  define sk_find OPENSSL_sk_find
+#  define sk_find_ex OPENSSL_sk_find_ex
+#  define sk_push OPENSSL_sk_push
+#  define sk_unshift OPENSSL_sk_unshift
+#  define sk_shift OPENSSL_sk_shift
+#  define sk_pop OPENSSL_sk_pop
+#  define sk_zero OPENSSL_sk_zero
+#  define sk_set_cmp_func OPENSSL_sk_set_cmp_func
+#  define sk_dup OPENSSL_sk_dup
+#  define sk_sort OPENSSL_sk_sort
+#  define sk_is_sorted OPENSSL_sk_is_sorted
+# endif
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/symhacks.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/symhacks.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/symhacks.h	(revision 331)
@@ -0,0 +1,52 @@
+/*
+ * Copyright 1999-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
+ */
+
+#ifndef HEADER_SYMHACKS_H
+# define HEADER_SYMHACKS_H
+
+# include <openssl/e_os2.h>
+
+/* Case insensitive linking causes problems.... */
+# if defined(OPENSSL_SYS_VMS)
+#  undef ERR_load_CRYPTO_strings
+#  define ERR_load_CRYPTO_strings                 ERR_load_CRYPTOlib_strings
+#  undef OCSP_crlID_new
+#  define OCSP_crlID_new                          OCSP_crlID2_new
+
+#  undef d2i_ECPARAMETERS
+#  define d2i_ECPARAMETERS                        d2i_UC_ECPARAMETERS
+#  undef i2d_ECPARAMETERS
+#  define i2d_ECPARAMETERS                        i2d_UC_ECPARAMETERS
+#  undef d2i_ECPKPARAMETERS
+#  define d2i_ECPKPARAMETERS                      d2i_UC_ECPKPARAMETERS
+#  undef i2d_ECPKPARAMETERS
+#  define i2d_ECPKPARAMETERS                      i2d_UC_ECPKPARAMETERS
+
+/*
+ * These functions do not seem to exist! However, I'm paranoid... Original
+ * command in x509v3.h: These functions are being redefined in another
+ * directory, and clash when the linker is case-insensitive, so let's hide
+ * them a little, by giving them an extra 'o' at the beginning of the name...
+ */
+#  undef X509v3_cleanup_extensions
+#  define X509v3_cleanup_extensions               oX509v3_cleanup_extensions
+#  undef X509v3_add_extension
+#  define X509v3_add_extension                    oX509v3_add_extension
+#  undef X509v3_add_netscape_extensions
+#  define X509v3_add_netscape_extensions          oX509v3_add_netscape_extensions
+#  undef X509v3_add_standard_extensions
+#  define X509v3_add_standard_extensions          oX509v3_add_standard_extensions
+
+/* This one clashes with CMS_data_create */
+#  undef cms_Data_create
+#  define cms_Data_create                         priv_cms_Data_create
+
+# endif
+
+#endif                          /* ! defined HEADER_VMS_IDHACKS_H */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/tls1.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/tls1.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/tls1.h	(revision 331)
@@ -0,0 +1,972 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * ECC cipher suite support in OpenSSL originally written by
+ * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#ifndef HEADER_TLS1_H
+# define HEADER_TLS1_H
+
+# include <openssl/buffer.h>
+# include <openssl/x509.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Default security level if not overridden at config time */
+# ifndef OPENSSL_TLS_SECURITY_LEVEL
+#  define OPENSSL_TLS_SECURITY_LEVEL 1
+# endif
+
+# define TLS1_VERSION                    0x0301
+# define TLS1_1_VERSION                  0x0302
+# define TLS1_2_VERSION                  0x0303
+# define TLS_MAX_VERSION                 TLS1_2_VERSION
+
+/* Special value for method supporting multiple versions */
+# define TLS_ANY_VERSION                 0x10000
+
+# define TLS1_VERSION_MAJOR              0x03
+# define TLS1_VERSION_MINOR              0x01
+
+# define TLS1_1_VERSION_MAJOR            0x03
+# define TLS1_1_VERSION_MINOR            0x02
+
+# define TLS1_2_VERSION_MAJOR            0x03
+# define TLS1_2_VERSION_MINOR            0x03
+
+# define TLS1_get_version(s) \
+                ((SSL_version(s) >> 8) == TLS1_VERSION_MAJOR ? SSL_version(s) : 0)
+
+# define TLS1_get_client_version(s) \
+                ((SSL_client_version(s) >> 8) == TLS1_VERSION_MAJOR ? SSL_client_version(s) : 0)
+
+# define TLS1_AD_DECRYPTION_FAILED       21
+# define TLS1_AD_RECORD_OVERFLOW         22
+# define TLS1_AD_UNKNOWN_CA              48/* fatal */
+# define TLS1_AD_ACCESS_DENIED           49/* fatal */
+# define TLS1_AD_DECODE_ERROR            50/* fatal */
+# define TLS1_AD_DECRYPT_ERROR           51
+# define TLS1_AD_EXPORT_RESTRICTION      60/* fatal */
+# define TLS1_AD_PROTOCOL_VERSION        70/* fatal */
+# define TLS1_AD_INSUFFICIENT_SECURITY   71/* fatal */
+# define TLS1_AD_INTERNAL_ERROR          80/* fatal */
+# define TLS1_AD_INAPPROPRIATE_FALLBACK  86/* fatal */
+# define TLS1_AD_USER_CANCELLED          90
+# define TLS1_AD_NO_RENEGOTIATION        100
+/* codes 110-114 are from RFC3546 */
+# define TLS1_AD_UNSUPPORTED_EXTENSION   110
+# define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111
+# define TLS1_AD_UNRECOGNIZED_NAME       112
+# define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113
+# define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114
+# define TLS1_AD_UNKNOWN_PSK_IDENTITY    115/* fatal */
+# define TLS1_AD_NO_APPLICATION_PROTOCOL 120 /* fatal */
+
+/* ExtensionType values from RFC3546 / RFC4366 / RFC6066 */
+# define TLSEXT_TYPE_server_name                 0
+# define TLSEXT_TYPE_max_fragment_length         1
+# define TLSEXT_TYPE_client_certificate_url      2
+# define TLSEXT_TYPE_trusted_ca_keys             3
+# define TLSEXT_TYPE_truncated_hmac              4
+# define TLSEXT_TYPE_status_request              5
+/* ExtensionType values from RFC4681 */
+# define TLSEXT_TYPE_user_mapping                6
+/* ExtensionType values from RFC5878 */
+# define TLSEXT_TYPE_client_authz                7
+# define TLSEXT_TYPE_server_authz                8
+/* ExtensionType values from RFC6091 */
+# define TLSEXT_TYPE_cert_type           9
+
+/* ExtensionType values from RFC4492 */
+# define TLSEXT_TYPE_elliptic_curves             10
+# define TLSEXT_TYPE_ec_point_formats            11
+
+/* ExtensionType value from RFC5054 */
+# define TLSEXT_TYPE_srp                         12
+
+/* ExtensionType values from RFC5246 */
+# define TLSEXT_TYPE_signature_algorithms        13
+
+/* ExtensionType value from RFC5764 */
+# define TLSEXT_TYPE_use_srtp    14
+
+/* ExtensionType value from RFC5620 */
+# define TLSEXT_TYPE_heartbeat   15
+
+/* ExtensionType value from RFC7301 */
+# define TLSEXT_TYPE_application_layer_protocol_negotiation 16
+
+/*
+ * Extension type for Certificate Transparency
+ * https://tools.ietf.org/html/rfc6962#section-3.3.1
+ */
+# define TLSEXT_TYPE_signed_certificate_timestamp    18
+
+/*
+ * ExtensionType value for TLS padding extension.
+ * http://tools.ietf.org/html/draft-agl-tls-padding
+ */
+# define TLSEXT_TYPE_padding     21
+
+/* ExtensionType value from RFC7366 */
+# define TLSEXT_TYPE_encrypt_then_mac    22
+
+/* ExtensionType value from RFC7627 */
+# define TLSEXT_TYPE_extended_master_secret      23
+
+/* ExtensionType value from RFC4507 */
+# define TLSEXT_TYPE_session_ticket              35
+
+/* Temporary extension type */
+# define TLSEXT_TYPE_renegotiate                 0xff01
+
+# ifndef OPENSSL_NO_NEXTPROTONEG
+/* This is not an IANA defined extension number */
+#  define TLSEXT_TYPE_next_proto_neg              13172
+# endif
+
+/* NameType value from RFC3546 */
+# define TLSEXT_NAMETYPE_host_name 0
+/* status request value from RFC3546 */
+# define TLSEXT_STATUSTYPE_ocsp 1
+
+/* ECPointFormat values from RFC4492 */
+# define TLSEXT_ECPOINTFORMAT_first                      0
+# define TLSEXT_ECPOINTFORMAT_uncompressed               0
+# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime  1
+# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2  2
+# define TLSEXT_ECPOINTFORMAT_last                       2
+
+/* Signature and hash algorithms from RFC5246 */
+# define TLSEXT_signature_anonymous                      0
+# define TLSEXT_signature_rsa                            1
+# define TLSEXT_signature_dsa                            2
+# define TLSEXT_signature_ecdsa                          3
+# define TLSEXT_signature_gostr34102001                  237
+# define TLSEXT_signature_gostr34102012_256              238
+# define TLSEXT_signature_gostr34102012_512              239
+
+/* Total number of different signature algorithms */
+# define TLSEXT_signature_num                            7
+
+# define TLSEXT_hash_none                                0
+# define TLSEXT_hash_md5                                 1
+# define TLSEXT_hash_sha1                                2
+# define TLSEXT_hash_sha224                              3
+# define TLSEXT_hash_sha256                              4
+# define TLSEXT_hash_sha384                              5
+# define TLSEXT_hash_sha512                              6
+# define TLSEXT_hash_gostr3411                           237
+# define TLSEXT_hash_gostr34112012_256                   238
+# define TLSEXT_hash_gostr34112012_512                   239
+
+/* Total number of different digest algorithms */
+
+# define TLSEXT_hash_num                                 10
+
+/* Flag set for unrecognised algorithms */
+# define TLSEXT_nid_unknown                              0x1000000
+
+/* ECC curves */
+
+# define TLSEXT_curve_P_256                              23
+# define TLSEXT_curve_P_384                              24
+
+# define TLSEXT_MAXLEN_host_name 255
+
+__owur const char *SSL_get_servername(const SSL *s, const int type);
+__owur int SSL_get_servername_type(const SSL *s);
+/*
+ * SSL_export_keying_material exports a value derived from the master secret,
+ * as specified in RFC 5705. It writes |olen| bytes to |out| given a label and
+ * optional context. (Since a zero length context is allowed, the |use_context|
+ * flag controls whether a context is included.) It returns 1 on success and
+ * zero otherwise.
+ */
+__owur int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
+                               const char *label, size_t llen,
+                               const unsigned char *p, size_t plen,
+                               int use_context);
+
+int SSL_get_sigalgs(SSL *s, int idx,
+                    int *psign, int *phash, int *psignandhash,
+                    unsigned char *rsig, unsigned char *rhash);
+
+int SSL_get_shared_sigalgs(SSL *s, int idx,
+                           int *psign, int *phash, int *psignandhash,
+                           unsigned char *rsig, unsigned char *rhash);
+
+__owur int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain);
+
+# define SSL_set_tlsext_host_name(s,name) \
+SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name)
+
+# define SSL_set_tlsext_debug_callback(ssl, cb) \
+SSL_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_CB,(void (*)(void))cb)
+
+# define SSL_set_tlsext_debug_arg(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_ARG,0, (void *)arg)
+
+# define SSL_get_tlsext_status_type(ssl) \
+SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE,0, NULL)
+
+# define SSL_set_tlsext_status_type(ssl, type) \
+SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,type, NULL)
+
+# define SSL_get_tlsext_status_exts(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg)
+
+# define SSL_set_tlsext_status_exts(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg)
+
+# define SSL_get_tlsext_status_ids(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg)
+
+# define SSL_set_tlsext_status_ids(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg)
+
+# define SSL_get_tlsext_status_ocsp_resp(ssl, arg) \
+SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP,0, (void *)arg)
+
+# define SSL_set_tlsext_status_ocsp_resp(ssl, arg, arglen) \
+SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,arglen, (void *)arg)
+
+# define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \
+SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,(void (*)(void))cb)
+
+# define SSL_TLSEXT_ERR_OK 0
+# define SSL_TLSEXT_ERR_ALERT_WARNING 1
+# define SSL_TLSEXT_ERR_ALERT_FATAL 2
+# define SSL_TLSEXT_ERR_NOACK 3
+
+# define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \
+SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0, (void *)arg)
+
+# define SSL_CTX_get_tlsext_ticket_keys(ctx, keys, keylen) \
+        SSL_CTX_ctrl((ctx),SSL_CTRL_GET_TLSEXT_TICKET_KEYS,(keylen),(keys))
+# define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \
+        SSL_CTX_ctrl((ctx),SSL_CTRL_SET_TLSEXT_TICKET_KEYS,(keylen),(keys))
+
+# define SSL_CTX_get_tlsext_status_cb(ssl, cb) \
+SSL_CTX_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB,0, (void (**)(void))cb)
+# define SSL_CTX_set_tlsext_status_cb(ssl, cb) \
+SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,(void (*)(void))cb)
+
+# define SSL_CTX_get_tlsext_status_arg(ssl, arg) \
+SSL_CTX_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG,0, (void *)arg
+# define SSL_CTX_set_tlsext_status_arg(ssl, arg) \
+SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0, (void *)arg)
+
+#define SSL_CTX_set_tlsext_status_type(ssl, type) \
+        SSL_CTX_ctrl(ssl, SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE, type, NULL)
+
+#define SSL_CTX_get_tlsext_status_type(ssl) \
+        SSL_CTX_ctrl(ssl, SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE, 0, NULL)
+
+# define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \
+SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb)
+
+# ifndef OPENSSL_NO_HEARTBEATS
+#  define SSL_DTLSEXT_HB_ENABLED                   0x01
+#  define SSL_DTLSEXT_HB_DONT_SEND_REQUESTS        0x02
+#  define SSL_DTLSEXT_HB_DONT_RECV_REQUESTS        0x04
+#  define SSL_get_dtlsext_heartbeat_pending(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_GET_DTLS_EXT_HEARTBEAT_PENDING,0,NULL)
+#  define SSL_set_dtlsext_heartbeat_no_requests(ssl, arg) \
+        SSL_ctrl((ssl),SSL_CTRL_SET_DTLS_EXT_HEARTBEAT_NO_REQUESTS,arg,NULL)
+
+#  if OPENSSL_API_COMPAT < 0x10100000L
+#   define SSL_CTRL_TLS_EXT_SEND_HEARTBEAT \
+        SSL_CTRL_DTLS_EXT_SEND_HEARTBEAT
+#   define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING \
+        SSL_CTRL_GET_DTLS_EXT_HEARTBEAT_PENDING
+#   define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS \
+        SSL_CTRL_SET_DTLS_EXT_HEARTBEAT_NO_REQUESTS
+#   define SSL_TLSEXT_HB_ENABLED \
+        SSL_DTLSEXT_HB_ENABLED
+#   define SSL_TLSEXT_HB_DONT_SEND_REQUESTS \
+        SSL_DTLSEXT_HB_DONT_SEND_REQUESTS
+#   define SSL_TLSEXT_HB_DONT_RECV_REQUESTS \
+        SSL_DTLSEXT_HB_DONT_RECV_REQUESTS
+#   define SSL_get_tlsext_heartbeat_pending(ssl) \
+        SSL_get_dtlsext_heartbeat_pending(ssl)
+#   define SSL_set_tlsext_heartbeat_no_requests(ssl, arg) \
+        SSL_set_dtlsext_heartbeat_no_requests(ssl, arg)
+#  endif
+# endif
+
+/* PSK ciphersuites from 4279 */
+# define TLS1_CK_PSK_WITH_RC4_128_SHA                    0x0300008A
+# define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA               0x0300008B
+# define TLS1_CK_PSK_WITH_AES_128_CBC_SHA                0x0300008C
+# define TLS1_CK_PSK_WITH_AES_256_CBC_SHA                0x0300008D
+
+# define TLS1_CK_DHE_PSK_WITH_RC4_128_SHA                0x0300008E
+# define TLS1_CK_DHE_PSK_WITH_3DES_EDE_CBC_SHA           0x0300008F
+# define TLS1_CK_DHE_PSK_WITH_AES_128_CBC_SHA            0x03000090
+# define TLS1_CK_DHE_PSK_WITH_AES_256_CBC_SHA            0x03000091
+
+# define TLS1_CK_RSA_PSK_WITH_RC4_128_SHA                0x03000092
+# define TLS1_CK_RSA_PSK_WITH_3DES_EDE_CBC_SHA           0x03000093
+# define TLS1_CK_RSA_PSK_WITH_AES_128_CBC_SHA            0x03000094
+# define TLS1_CK_RSA_PSK_WITH_AES_256_CBC_SHA            0x03000095
+
+/* PSK ciphersuites from 5487 */
+# define TLS1_CK_PSK_WITH_AES_128_GCM_SHA256             0x030000A8
+# define TLS1_CK_PSK_WITH_AES_256_GCM_SHA384             0x030000A9
+# define TLS1_CK_DHE_PSK_WITH_AES_128_GCM_SHA256         0x030000AA
+# define TLS1_CK_DHE_PSK_WITH_AES_256_GCM_SHA384         0x030000AB
+# define TLS1_CK_RSA_PSK_WITH_AES_128_GCM_SHA256         0x030000AC
+# define TLS1_CK_RSA_PSK_WITH_AES_256_GCM_SHA384         0x030000AD
+
+# define TLS1_CK_PSK_WITH_AES_128_CBC_SHA256             0x030000AE
+# define TLS1_CK_PSK_WITH_AES_256_CBC_SHA384             0x030000AF
+# define TLS1_CK_PSK_WITH_NULL_SHA256                    0x030000B0
+# define TLS1_CK_PSK_WITH_NULL_SHA384                    0x030000B1
+
+# define TLS1_CK_DHE_PSK_WITH_AES_128_CBC_SHA256         0x030000B2
+# define TLS1_CK_DHE_PSK_WITH_AES_256_CBC_SHA384         0x030000B3
+# define TLS1_CK_DHE_PSK_WITH_NULL_SHA256                0x030000B4
+# define TLS1_CK_DHE_PSK_WITH_NULL_SHA384                0x030000B5
+
+# define TLS1_CK_RSA_PSK_WITH_AES_128_CBC_SHA256         0x030000B6
+# define TLS1_CK_RSA_PSK_WITH_AES_256_CBC_SHA384         0x030000B7
+# define TLS1_CK_RSA_PSK_WITH_NULL_SHA256                0x030000B8
+# define TLS1_CK_RSA_PSK_WITH_NULL_SHA384                0x030000B9
+
+/* NULL PSK ciphersuites from RFC4785 */
+# define TLS1_CK_PSK_WITH_NULL_SHA                       0x0300002C
+# define TLS1_CK_DHE_PSK_WITH_NULL_SHA                   0x0300002D
+# define TLS1_CK_RSA_PSK_WITH_NULL_SHA                   0x0300002E
+
+/* AES ciphersuites from RFC3268 */
+# define TLS1_CK_RSA_WITH_AES_128_SHA                    0x0300002F
+# define TLS1_CK_DH_DSS_WITH_AES_128_SHA                 0x03000030
+# define TLS1_CK_DH_RSA_WITH_AES_128_SHA                 0x03000031
+# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA                0x03000032
+# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA                0x03000033
+# define TLS1_CK_ADH_WITH_AES_128_SHA                    0x03000034
+
+# define TLS1_CK_RSA_WITH_AES_256_SHA                    0x03000035
+# define TLS1_CK_DH_DSS_WITH_AES_256_SHA                 0x03000036
+# define TLS1_CK_DH_RSA_WITH_AES_256_SHA                 0x03000037
+# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA                0x03000038
+# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA                0x03000039
+# define TLS1_CK_ADH_WITH_AES_256_SHA                    0x0300003A
+
+/* TLS v1.2 ciphersuites */
+# define TLS1_CK_RSA_WITH_NULL_SHA256                    0x0300003B
+# define TLS1_CK_RSA_WITH_AES_128_SHA256                 0x0300003C
+# define TLS1_CK_RSA_WITH_AES_256_SHA256                 0x0300003D
+# define TLS1_CK_DH_DSS_WITH_AES_128_SHA256              0x0300003E
+# define TLS1_CK_DH_RSA_WITH_AES_128_SHA256              0x0300003F
+# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA256             0x03000040
+
+/* Camellia ciphersuites from RFC4132 */
+# define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA           0x03000041
+# define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA        0x03000042
+# define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA        0x03000043
+# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA       0x03000044
+# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA       0x03000045
+# define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA           0x03000046
+
+/* TLS v1.2 ciphersuites */
+# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA256             0x03000067
+# define TLS1_CK_DH_DSS_WITH_AES_256_SHA256              0x03000068
+# define TLS1_CK_DH_RSA_WITH_AES_256_SHA256              0x03000069
+# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA256             0x0300006A
+# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA256             0x0300006B
+# define TLS1_CK_ADH_WITH_AES_128_SHA256                 0x0300006C
+# define TLS1_CK_ADH_WITH_AES_256_SHA256                 0x0300006D
+
+/* Camellia ciphersuites from RFC4132 */
+# define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA           0x03000084
+# define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA        0x03000085
+# define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA        0x03000086
+# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA       0x03000087
+# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA       0x03000088
+# define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA           0x03000089
+
+/* SEED ciphersuites from RFC4162 */
+# define TLS1_CK_RSA_WITH_SEED_SHA                       0x03000096
+# define TLS1_CK_DH_DSS_WITH_SEED_SHA                    0x03000097
+# define TLS1_CK_DH_RSA_WITH_SEED_SHA                    0x03000098
+# define TLS1_CK_DHE_DSS_WITH_SEED_SHA                   0x03000099
+# define TLS1_CK_DHE_RSA_WITH_SEED_SHA                   0x0300009A
+# define TLS1_CK_ADH_WITH_SEED_SHA                       0x0300009B
+
+/* TLS v1.2 GCM ciphersuites from RFC5288 */
+# define TLS1_CK_RSA_WITH_AES_128_GCM_SHA256             0x0300009C
+# define TLS1_CK_RSA_WITH_AES_256_GCM_SHA384             0x0300009D
+# define TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256         0x0300009E
+# define TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384         0x0300009F
+# define TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256          0x030000A0
+# define TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384          0x030000A1
+# define TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256         0x030000A2
+# define TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384         0x030000A3
+# define TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256          0x030000A4
+# define TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384          0x030000A5
+# define TLS1_CK_ADH_WITH_AES_128_GCM_SHA256             0x030000A6
+# define TLS1_CK_ADH_WITH_AES_256_GCM_SHA384             0x030000A7
+
+/* CCM ciphersuites from RFC6655 */
+# define TLS1_CK_RSA_WITH_AES_128_CCM                    0x0300C09C
+# define TLS1_CK_RSA_WITH_AES_256_CCM                    0x0300C09D
+# define TLS1_CK_DHE_RSA_WITH_AES_128_CCM                0x0300C09E
+# define TLS1_CK_DHE_RSA_WITH_AES_256_CCM                0x0300C09F
+# define TLS1_CK_RSA_WITH_AES_128_CCM_8                  0x0300C0A0
+# define TLS1_CK_RSA_WITH_AES_256_CCM_8                  0x0300C0A1
+# define TLS1_CK_DHE_RSA_WITH_AES_128_CCM_8              0x0300C0A2
+# define TLS1_CK_DHE_RSA_WITH_AES_256_CCM_8              0x0300C0A3
+# define TLS1_CK_PSK_WITH_AES_128_CCM                    0x0300C0A4
+# define TLS1_CK_PSK_WITH_AES_256_CCM                    0x0300C0A5
+# define TLS1_CK_DHE_PSK_WITH_AES_128_CCM                0x0300C0A6
+# define TLS1_CK_DHE_PSK_WITH_AES_256_CCM                0x0300C0A7
+# define TLS1_CK_PSK_WITH_AES_128_CCM_8                  0x0300C0A8
+# define TLS1_CK_PSK_WITH_AES_256_CCM_8                  0x0300C0A9
+# define TLS1_CK_DHE_PSK_WITH_AES_128_CCM_8              0x0300C0AA
+# define TLS1_CK_DHE_PSK_WITH_AES_256_CCM_8              0x0300C0AB
+
+/* CCM ciphersuites from RFC7251 */
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CCM            0x0300C0AC
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CCM            0x0300C0AD
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CCM_8          0x0300C0AE
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CCM_8          0x0300C0AF
+
+/* TLS 1.2 Camellia SHA-256 ciphersuites from RFC5932 */
+# define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA256                0x030000BA
+# define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256             0x030000BB
+# define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256             0x030000BC
+# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256            0x030000BD
+# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256            0x030000BE
+# define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA256                0x030000BF
+
+# define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA256                0x030000C0
+# define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256             0x030000C1
+# define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256             0x030000C2
+# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256            0x030000C3
+# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256            0x030000C4
+# define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA256                0x030000C5
+
+/* ECC ciphersuites from RFC4492 */
+# define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA                0x0300C001
+# define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA             0x0300C002
+# define TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA        0x0300C003
+# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA         0x0300C004
+# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA         0x0300C005
+
+# define TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA               0x0300C006
+# define TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA            0x0300C007
+# define TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA       0x0300C008
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA        0x0300C009
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA        0x0300C00A
+
+# define TLS1_CK_ECDH_RSA_WITH_NULL_SHA                  0x0300C00B
+# define TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA               0x0300C00C
+# define TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA          0x0300C00D
+# define TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA           0x0300C00E
+# define TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA           0x0300C00F
+
+# define TLS1_CK_ECDHE_RSA_WITH_NULL_SHA                 0x0300C010
+# define TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA              0x0300C011
+# define TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA         0x0300C012
+# define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA          0x0300C013
+# define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA          0x0300C014
+
+# define TLS1_CK_ECDH_anon_WITH_NULL_SHA                 0x0300C015
+# define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA              0x0300C016
+# define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA         0x0300C017
+# define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA          0x0300C018
+# define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA          0x0300C019
+
+/* SRP ciphersuites from RFC 5054 */
+# define TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA           0x0300C01A
+# define TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA       0x0300C01B
+# define TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA       0x0300C01C
+# define TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA            0x0300C01D
+# define TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA        0x0300C01E
+# define TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA        0x0300C01F
+# define TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA            0x0300C020
+# define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA        0x0300C021
+# define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA        0x0300C022
+
+/* ECDH HMAC based ciphersuites from RFC5289 */
+
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256         0x0300C023
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384         0x0300C024
+# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256          0x0300C025
+# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384          0x0300C026
+# define TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256           0x0300C027
+# define TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384           0x0300C028
+# define TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256            0x0300C029
+# define TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384            0x0300C02A
+
+/* ECDH GCM based ciphersuites from RFC5289 */
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256     0x0300C02B
+# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384     0x0300C02C
+# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256      0x0300C02D
+# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384      0x0300C02E
+# define TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256       0x0300C02F
+# define TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384       0x0300C030
+# define TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256        0x0300C031
+# define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384        0x0300C032
+
+/* ECDHE PSK ciphersuites from RFC5489 */
+# define TLS1_CK_ECDHE_PSK_WITH_RC4_128_SHA              0x0300C033
+# define TLS1_CK_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA         0x0300C034
+# define TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA          0x0300C035
+# define TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA          0x0300C036
+
+# define TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA256       0x0300C037
+# define TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA384       0x0300C038
+
+/* NULL PSK ciphersuites from RFC4785 */
+
+# define TLS1_CK_ECDHE_PSK_WITH_NULL_SHA                 0x0300C039
+# define TLS1_CK_ECDHE_PSK_WITH_NULL_SHA256              0x0300C03A
+# define TLS1_CK_ECDHE_PSK_WITH_NULL_SHA384              0x0300C03B
+
+/* Camellia-CBC ciphersuites from RFC6367 */
+# define TLS1_CK_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 0x0300C072
+# define TLS1_CK_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 0x0300C073
+# define TLS1_CK_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256  0x0300C074
+# define TLS1_CK_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384  0x0300C075
+# define TLS1_CK_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256   0x0300C076
+# define TLS1_CK_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384   0x0300C077
+# define TLS1_CK_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256    0x0300C078
+# define TLS1_CK_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384    0x0300C079
+
+# define TLS1_CK_PSK_WITH_CAMELLIA_128_CBC_SHA256         0x0300C094
+# define TLS1_CK_PSK_WITH_CAMELLIA_256_CBC_SHA384         0x0300C095
+# define TLS1_CK_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256     0x0300C096
+# define TLS1_CK_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384     0x0300C097
+# define TLS1_CK_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256     0x0300C098
+# define TLS1_CK_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384     0x0300C099
+# define TLS1_CK_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256   0x0300C09A
+# define TLS1_CK_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384   0x0300C09B
+
+/* draft-ietf-tls-chacha20-poly1305-03 */
+# define TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305         0x0300CCA8
+# define TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305       0x0300CCA9
+# define TLS1_CK_DHE_RSA_WITH_CHACHA20_POLY1305           0x0300CCAA
+# define TLS1_CK_PSK_WITH_CHACHA20_POLY1305               0x0300CCAB
+# define TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305         0x0300CCAC
+# define TLS1_CK_DHE_PSK_WITH_CHACHA20_POLY1305           0x0300CCAD
+# define TLS1_CK_RSA_PSK_WITH_CHACHA20_POLY1305           0x0300CCAE
+
+/*
+ * XXX Backward compatibility alert: Older versions of OpenSSL gave some DHE
+ * ciphers names with "EDH" instead of "DHE".  Going forward, we should be
+ * using DHE everywhere, though we may indefinitely maintain aliases for
+ * users or configurations that used "EDH"
+ */
+# define TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA               "DHE-DSS-RC4-SHA"
+
+# define TLS1_TXT_PSK_WITH_NULL_SHA                      "PSK-NULL-SHA"
+# define TLS1_TXT_DHE_PSK_WITH_NULL_SHA                  "DHE-PSK-NULL-SHA"
+# define TLS1_TXT_RSA_PSK_WITH_NULL_SHA                  "RSA-PSK-NULL-SHA"
+
+/* AES ciphersuites from RFC3268 */
+# define TLS1_TXT_RSA_WITH_AES_128_SHA                   "AES128-SHA"
+# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA                "DH-DSS-AES128-SHA"
+# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA                "DH-RSA-AES128-SHA"
+# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA               "DHE-DSS-AES128-SHA"
+# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA               "DHE-RSA-AES128-SHA"
+# define TLS1_TXT_ADH_WITH_AES_128_SHA                   "ADH-AES128-SHA"
+
+# define TLS1_TXT_RSA_WITH_AES_256_SHA                   "AES256-SHA"
+# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA                "DH-DSS-AES256-SHA"
+# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA                "DH-RSA-AES256-SHA"
+# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA               "DHE-DSS-AES256-SHA"
+# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA               "DHE-RSA-AES256-SHA"
+# define TLS1_TXT_ADH_WITH_AES_256_SHA                   "ADH-AES256-SHA"
+
+/* ECC ciphersuites from RFC4492 */
+# define TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA               "ECDH-ECDSA-NULL-SHA"
+# define TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA            "ECDH-ECDSA-RC4-SHA"
+# define TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA       "ECDH-ECDSA-DES-CBC3-SHA"
+# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA        "ECDH-ECDSA-AES128-SHA"
+# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA        "ECDH-ECDSA-AES256-SHA"
+
+# define TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA              "ECDHE-ECDSA-NULL-SHA"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA           "ECDHE-ECDSA-RC4-SHA"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA      "ECDHE-ECDSA-DES-CBC3-SHA"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA       "ECDHE-ECDSA-AES128-SHA"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA       "ECDHE-ECDSA-AES256-SHA"
+
+# define TLS1_TXT_ECDH_RSA_WITH_NULL_SHA                 "ECDH-RSA-NULL-SHA"
+# define TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA              "ECDH-RSA-RC4-SHA"
+# define TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA         "ECDH-RSA-DES-CBC3-SHA"
+# define TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA          "ECDH-RSA-AES128-SHA"
+# define TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA          "ECDH-RSA-AES256-SHA"
+
+# define TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA                "ECDHE-RSA-NULL-SHA"
+# define TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA             "ECDHE-RSA-RC4-SHA"
+# define TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA        "ECDHE-RSA-DES-CBC3-SHA"
+# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA         "ECDHE-RSA-AES128-SHA"
+# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA         "ECDHE-RSA-AES256-SHA"
+
+# define TLS1_TXT_ECDH_anon_WITH_NULL_SHA                "AECDH-NULL-SHA"
+# define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA             "AECDH-RC4-SHA"
+# define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA        "AECDH-DES-CBC3-SHA"
+# define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA         "AECDH-AES128-SHA"
+# define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA         "AECDH-AES256-SHA"
+
+/* PSK ciphersuites from RFC 4279 */
+# define TLS1_TXT_PSK_WITH_RC4_128_SHA                   "PSK-RC4-SHA"
+# define TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA              "PSK-3DES-EDE-CBC-SHA"
+# define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA               "PSK-AES128-CBC-SHA"
+# define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA               "PSK-AES256-CBC-SHA"
+
+# define TLS1_TXT_DHE_PSK_WITH_RC4_128_SHA               "DHE-PSK-RC4-SHA"
+# define TLS1_TXT_DHE_PSK_WITH_3DES_EDE_CBC_SHA          "DHE-PSK-3DES-EDE-CBC-SHA"
+# define TLS1_TXT_DHE_PSK_WITH_AES_128_CBC_SHA           "DHE-PSK-AES128-CBC-SHA"
+# define TLS1_TXT_DHE_PSK_WITH_AES_256_CBC_SHA           "DHE-PSK-AES256-CBC-SHA"
+# define TLS1_TXT_RSA_PSK_WITH_RC4_128_SHA               "RSA-PSK-RC4-SHA"
+# define TLS1_TXT_RSA_PSK_WITH_3DES_EDE_CBC_SHA          "RSA-PSK-3DES-EDE-CBC-SHA"
+# define TLS1_TXT_RSA_PSK_WITH_AES_128_CBC_SHA           "RSA-PSK-AES128-CBC-SHA"
+# define TLS1_TXT_RSA_PSK_WITH_AES_256_CBC_SHA           "RSA-PSK-AES256-CBC-SHA"
+
+/* PSK ciphersuites from RFC 5487 */
+# define TLS1_TXT_PSK_WITH_AES_128_GCM_SHA256            "PSK-AES128-GCM-SHA256"
+# define TLS1_TXT_PSK_WITH_AES_256_GCM_SHA384            "PSK-AES256-GCM-SHA384"
+# define TLS1_TXT_DHE_PSK_WITH_AES_128_GCM_SHA256        "DHE-PSK-AES128-GCM-SHA256"
+# define TLS1_TXT_DHE_PSK_WITH_AES_256_GCM_SHA384        "DHE-PSK-AES256-GCM-SHA384"
+# define TLS1_TXT_RSA_PSK_WITH_AES_128_GCM_SHA256        "RSA-PSK-AES128-GCM-SHA256"
+# define TLS1_TXT_RSA_PSK_WITH_AES_256_GCM_SHA384        "RSA-PSK-AES256-GCM-SHA384"
+
+# define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA256            "PSK-AES128-CBC-SHA256"
+# define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA384            "PSK-AES256-CBC-SHA384"
+# define TLS1_TXT_PSK_WITH_NULL_SHA256                   "PSK-NULL-SHA256"
+# define TLS1_TXT_PSK_WITH_NULL_SHA384                   "PSK-NULL-SHA384"
+
+# define TLS1_TXT_DHE_PSK_WITH_AES_128_CBC_SHA256        "DHE-PSK-AES128-CBC-SHA256"
+# define TLS1_TXT_DHE_PSK_WITH_AES_256_CBC_SHA384        "DHE-PSK-AES256-CBC-SHA384"
+# define TLS1_TXT_DHE_PSK_WITH_NULL_SHA256               "DHE-PSK-NULL-SHA256"
+# define TLS1_TXT_DHE_PSK_WITH_NULL_SHA384               "DHE-PSK-NULL-SHA384"
+
+# define TLS1_TXT_RSA_PSK_WITH_AES_128_CBC_SHA256        "RSA-PSK-AES128-CBC-SHA256"
+# define TLS1_TXT_RSA_PSK_WITH_AES_256_CBC_SHA384        "RSA-PSK-AES256-CBC-SHA384"
+# define TLS1_TXT_RSA_PSK_WITH_NULL_SHA256               "RSA-PSK-NULL-SHA256"
+# define TLS1_TXT_RSA_PSK_WITH_NULL_SHA384               "RSA-PSK-NULL-SHA384"
+
+/* SRP ciphersuite from RFC 5054 */
+# define TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA          "SRP-3DES-EDE-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA      "SRP-RSA-3DES-EDE-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA      "SRP-DSS-3DES-EDE-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA           "SRP-AES-128-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA       "SRP-RSA-AES-128-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA       "SRP-DSS-AES-128-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA           "SRP-AES-256-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA       "SRP-RSA-AES-256-CBC-SHA"
+# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA       "SRP-DSS-AES-256-CBC-SHA"
+
+/* Camellia ciphersuites from RFC4132 */
+# define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA          "CAMELLIA128-SHA"
+# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA       "DH-DSS-CAMELLIA128-SHA"
+# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA       "DH-RSA-CAMELLIA128-SHA"
+# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA      "DHE-DSS-CAMELLIA128-SHA"
+# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA      "DHE-RSA-CAMELLIA128-SHA"
+# define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA          "ADH-CAMELLIA128-SHA"
+
+# define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA          "CAMELLIA256-SHA"
+# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA       "DH-DSS-CAMELLIA256-SHA"
+# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA       "DH-RSA-CAMELLIA256-SHA"
+# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA      "DHE-DSS-CAMELLIA256-SHA"
+# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA      "DHE-RSA-CAMELLIA256-SHA"
+# define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA          "ADH-CAMELLIA256-SHA"
+
+/* TLS 1.2 Camellia SHA-256 ciphersuites from RFC5932 */
+# define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA256               "CAMELLIA128-SHA256"
+# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256            "DH-DSS-CAMELLIA128-SHA256"
+# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256            "DH-RSA-CAMELLIA128-SHA256"
+# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256           "DHE-DSS-CAMELLIA128-SHA256"
+# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256           "DHE-RSA-CAMELLIA128-SHA256"
+# define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA256               "ADH-CAMELLIA128-SHA256"
+
+# define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA256               "CAMELLIA256-SHA256"
+# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256            "DH-DSS-CAMELLIA256-SHA256"
+# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256            "DH-RSA-CAMELLIA256-SHA256"
+# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256           "DHE-DSS-CAMELLIA256-SHA256"
+# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256           "DHE-RSA-CAMELLIA256-SHA256"
+# define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA256               "ADH-CAMELLIA256-SHA256"
+
+# define TLS1_TXT_PSK_WITH_CAMELLIA_128_CBC_SHA256               "PSK-CAMELLIA128-SHA256"
+# define TLS1_TXT_PSK_WITH_CAMELLIA_256_CBC_SHA384               "PSK-CAMELLIA256-SHA384"
+# define TLS1_TXT_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256           "DHE-PSK-CAMELLIA128-SHA256"
+# define TLS1_TXT_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384           "DHE-PSK-CAMELLIA256-SHA384"
+# define TLS1_TXT_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256           "RSA-PSK-CAMELLIA128-SHA256"
+# define TLS1_TXT_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384           "RSA-PSK-CAMELLIA256-SHA384"
+# define TLS1_TXT_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256         "ECDHE-PSK-CAMELLIA128-SHA256"
+# define TLS1_TXT_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384         "ECDHE-PSK-CAMELLIA256-SHA384"
+
+/* SEED ciphersuites from RFC4162 */
+# define TLS1_TXT_RSA_WITH_SEED_SHA                      "SEED-SHA"
+# define TLS1_TXT_DH_DSS_WITH_SEED_SHA                   "DH-DSS-SEED-SHA"
+# define TLS1_TXT_DH_RSA_WITH_SEED_SHA                   "DH-RSA-SEED-SHA"
+# define TLS1_TXT_DHE_DSS_WITH_SEED_SHA                  "DHE-DSS-SEED-SHA"
+# define TLS1_TXT_DHE_RSA_WITH_SEED_SHA                  "DHE-RSA-SEED-SHA"
+# define TLS1_TXT_ADH_WITH_SEED_SHA                      "ADH-SEED-SHA"
+
+/* TLS v1.2 ciphersuites */
+# define TLS1_TXT_RSA_WITH_NULL_SHA256                   "NULL-SHA256"
+# define TLS1_TXT_RSA_WITH_AES_128_SHA256                "AES128-SHA256"
+# define TLS1_TXT_RSA_WITH_AES_256_SHA256                "AES256-SHA256"
+# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA256             "DH-DSS-AES128-SHA256"
+# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA256             "DH-RSA-AES128-SHA256"
+# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256            "DHE-DSS-AES128-SHA256"
+# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256            "DHE-RSA-AES128-SHA256"
+# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA256             "DH-DSS-AES256-SHA256"
+# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA256             "DH-RSA-AES256-SHA256"
+# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256            "DHE-DSS-AES256-SHA256"
+# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256            "DHE-RSA-AES256-SHA256"
+# define TLS1_TXT_ADH_WITH_AES_128_SHA256                "ADH-AES128-SHA256"
+# define TLS1_TXT_ADH_WITH_AES_256_SHA256                "ADH-AES256-SHA256"
+
+/* TLS v1.2 GCM ciphersuites from RFC5288 */
+# define TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256            "AES128-GCM-SHA256"
+# define TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384            "AES256-GCM-SHA384"
+# define TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256        "DHE-RSA-AES128-GCM-SHA256"
+# define TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384        "DHE-RSA-AES256-GCM-SHA384"
+# define TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256         "DH-RSA-AES128-GCM-SHA256"
+# define TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384         "DH-RSA-AES256-GCM-SHA384"
+# define TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256        "DHE-DSS-AES128-GCM-SHA256"
+# define TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384        "DHE-DSS-AES256-GCM-SHA384"
+# define TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256         "DH-DSS-AES128-GCM-SHA256"
+# define TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384         "DH-DSS-AES256-GCM-SHA384"
+# define TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256            "ADH-AES128-GCM-SHA256"
+# define TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384            "ADH-AES256-GCM-SHA384"
+
+/* CCM ciphersuites from RFC6655 */
+
+# define TLS1_TXT_RSA_WITH_AES_128_CCM                   "AES128-CCM"
+# define TLS1_TXT_RSA_WITH_AES_256_CCM                   "AES256-CCM"
+# define TLS1_TXT_DHE_RSA_WITH_AES_128_CCM               "DHE-RSA-AES128-CCM"
+# define TLS1_TXT_DHE_RSA_WITH_AES_256_CCM               "DHE-RSA-AES256-CCM"
+
+# define TLS1_TXT_RSA_WITH_AES_128_CCM_8                 "AES128-CCM8"
+# define TLS1_TXT_RSA_WITH_AES_256_CCM_8                 "AES256-CCM8"
+# define TLS1_TXT_DHE_RSA_WITH_AES_128_CCM_8             "DHE-RSA-AES128-CCM8"
+# define TLS1_TXT_DHE_RSA_WITH_AES_256_CCM_8             "DHE-RSA-AES256-CCM8"
+
+# define TLS1_TXT_PSK_WITH_AES_128_CCM                   "PSK-AES128-CCM"
+# define TLS1_TXT_PSK_WITH_AES_256_CCM                   "PSK-AES256-CCM"
+# define TLS1_TXT_DHE_PSK_WITH_AES_128_CCM               "DHE-PSK-AES128-CCM"
+# define TLS1_TXT_DHE_PSK_WITH_AES_256_CCM               "DHE-PSK-AES256-CCM"
+
+# define TLS1_TXT_PSK_WITH_AES_128_CCM_8                 "PSK-AES128-CCM8"
+# define TLS1_TXT_PSK_WITH_AES_256_CCM_8                 "PSK-AES256-CCM8"
+# define TLS1_TXT_DHE_PSK_WITH_AES_128_CCM_8             "DHE-PSK-AES128-CCM8"
+# define TLS1_TXT_DHE_PSK_WITH_AES_256_CCM_8             "DHE-PSK-AES256-CCM8"
+
+/* CCM ciphersuites from RFC7251 */
+
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CCM       "ECDHE-ECDSA-AES128-CCM"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CCM       "ECDHE-ECDSA-AES256-CCM"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CCM_8     "ECDHE-ECDSA-AES128-CCM8"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CCM_8     "ECDHE-ECDSA-AES256-CCM8"
+
+/* ECDH HMAC based ciphersuites from RFC5289 */
+
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256    "ECDHE-ECDSA-AES128-SHA256"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384    "ECDHE-ECDSA-AES256-SHA384"
+# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256     "ECDH-ECDSA-AES128-SHA256"
+# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384     "ECDH-ECDSA-AES256-SHA384"
+# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256      "ECDHE-RSA-AES128-SHA256"
+# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384      "ECDHE-RSA-AES256-SHA384"
+# define TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256       "ECDH-RSA-AES128-SHA256"
+# define TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384       "ECDH-RSA-AES256-SHA384"
+
+/* ECDH GCM based ciphersuites from RFC5289 */
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256    "ECDHE-ECDSA-AES128-GCM-SHA256"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384    "ECDHE-ECDSA-AES256-GCM-SHA384"
+# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256     "ECDH-ECDSA-AES128-GCM-SHA256"
+# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384     "ECDH-ECDSA-AES256-GCM-SHA384"
+# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256      "ECDHE-RSA-AES128-GCM-SHA256"
+# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384      "ECDHE-RSA-AES256-GCM-SHA384"
+# define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256       "ECDH-RSA-AES128-GCM-SHA256"
+# define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384       "ECDH-RSA-AES256-GCM-SHA384"
+
+/* TLS v1.2 PSK GCM ciphersuites from RFC5487 */
+# define TLS1_TXT_PSK_WITH_AES_128_GCM_SHA256            "PSK-AES128-GCM-SHA256"
+# define TLS1_TXT_PSK_WITH_AES_256_GCM_SHA384            "PSK-AES256-GCM-SHA384"
+
+/* ECDHE PSK ciphersuites from RFC 5489 */
+# define TLS1_TXT_ECDHE_PSK_WITH_RC4_128_SHA               "ECDHE-PSK-RC4-SHA"
+# define TLS1_TXT_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA          "ECDHE-PSK-3DES-EDE-CBC-SHA"
+# define TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA           "ECDHE-PSK-AES128-CBC-SHA"
+# define TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA           "ECDHE-PSK-AES256-CBC-SHA"
+
+# define TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA256        "ECDHE-PSK-AES128-CBC-SHA256"
+# define TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA384        "ECDHE-PSK-AES256-CBC-SHA384"
+
+# define TLS1_TXT_ECDHE_PSK_WITH_NULL_SHA                  "ECDHE-PSK-NULL-SHA"
+# define TLS1_TXT_ECDHE_PSK_WITH_NULL_SHA256               "ECDHE-PSK-NULL-SHA256"
+# define TLS1_TXT_ECDHE_PSK_WITH_NULL_SHA384               "ECDHE-PSK-NULL-SHA384"
+
+/* Camellia-CBC ciphersuites from RFC6367 */
+# define TLS1_TXT_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 "ECDHE-ECDSA-CAMELLIA128-SHA256"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 "ECDHE-ECDSA-CAMELLIA256-SHA384"
+# define TLS1_TXT_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256  "ECDH-ECDSA-CAMELLIA128-SHA256"
+# define TLS1_TXT_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384  "ECDH-ECDSA-CAMELLIA256-SHA384"
+# define TLS1_TXT_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256   "ECDHE-RSA-CAMELLIA128-SHA256"
+# define TLS1_TXT_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384   "ECDHE-RSA-CAMELLIA256-SHA384"
+# define TLS1_TXT_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256    "ECDH-RSA-CAMELLIA128-SHA256"
+# define TLS1_TXT_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384    "ECDH-RSA-CAMELLIA256-SHA384"
+
+/* draft-ietf-tls-chacha20-poly1305-03 */
+# define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305         "ECDHE-RSA-CHACHA20-POLY1305"
+# define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305       "ECDHE-ECDSA-CHACHA20-POLY1305"
+# define TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305           "DHE-RSA-CHACHA20-POLY1305"
+# define TLS1_TXT_PSK_WITH_CHACHA20_POLY1305               "PSK-CHACHA20-POLY1305"
+# define TLS1_TXT_ECDHE_PSK_WITH_CHACHA20_POLY1305         "ECDHE-PSK-CHACHA20-POLY1305"
+# define TLS1_TXT_DHE_PSK_WITH_CHACHA20_POLY1305           "DHE-PSK-CHACHA20-POLY1305"
+# define TLS1_TXT_RSA_PSK_WITH_CHACHA20_POLY1305           "RSA-PSK-CHACHA20-POLY1305"
+
+# define TLS_CT_RSA_SIGN                 1
+# define TLS_CT_DSS_SIGN                 2
+# define TLS_CT_RSA_FIXED_DH             3
+# define TLS_CT_DSS_FIXED_DH             4
+# define TLS_CT_ECDSA_SIGN               64
+# define TLS_CT_RSA_FIXED_ECDH           65
+# define TLS_CT_ECDSA_FIXED_ECDH         66
+# define TLS_CT_GOST01_SIGN              22
+# define TLS_CT_GOST12_SIGN              238
+# define TLS_CT_GOST12_512_SIGN          239
+
+/*
+ * when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see
+ * comment there)
+ */
+# define TLS_CT_NUMBER                   9
+
+# define TLS1_FINISH_MAC_LENGTH          12
+
+# define TLS_MD_MAX_CONST_SIZE                   22
+# define TLS_MD_CLIENT_FINISH_CONST              "client finished"
+# define TLS_MD_CLIENT_FINISH_CONST_SIZE         15
+# define TLS_MD_SERVER_FINISH_CONST              "server finished"
+# define TLS_MD_SERVER_FINISH_CONST_SIZE         15
+# define TLS_MD_KEY_EXPANSION_CONST              "key expansion"
+# define TLS_MD_KEY_EXPANSION_CONST_SIZE         13
+# define TLS_MD_CLIENT_WRITE_KEY_CONST           "client write key"
+# define TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE      16
+# define TLS_MD_SERVER_WRITE_KEY_CONST           "server write key"
+# define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE      16
+# define TLS_MD_IV_BLOCK_CONST                   "IV block"
+# define TLS_MD_IV_BLOCK_CONST_SIZE              8
+# define TLS_MD_MASTER_SECRET_CONST              "master secret"
+# define TLS_MD_MASTER_SECRET_CONST_SIZE         13
+# define TLS_MD_EXTENDED_MASTER_SECRET_CONST     "extended master secret"
+# define TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE        22
+
+# ifdef CHARSET_EBCDIC
+#  undef TLS_MD_CLIENT_FINISH_CONST
+/*
+ * client finished
+ */
+#  define TLS_MD_CLIENT_FINISH_CONST    "\x63\x6c\x69\x65\x6e\x74\x20\x66\x69\x6e\x69\x73\x68\x65\x64"
+
+#  undef TLS_MD_SERVER_FINISH_CONST
+/*
+ * server finished
+ */
+#  define TLS_MD_SERVER_FINISH_CONST    "\x73\x65\x72\x76\x65\x72\x20\x66\x69\x6e\x69\x73\x68\x65\x64"
+
+#  undef TLS_MD_SERVER_WRITE_KEY_CONST
+/*
+ * server write key
+ */
+#  define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"
+
+#  undef TLS_MD_KEY_EXPANSION_CONST
+/*
+ * key expansion
+ */
+#  define TLS_MD_KEY_EXPANSION_CONST    "\x6b\x65\x79\x20\x65\x78\x70\x61\x6e\x73\x69\x6f\x6e"
+
+#  undef TLS_MD_CLIENT_WRITE_KEY_CONST
+/*
+ * client write key
+ */
+#  define TLS_MD_CLIENT_WRITE_KEY_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"
+
+#  undef TLS_MD_SERVER_WRITE_KEY_CONST
+/*
+ * server write key
+ */
+#  define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"
+
+#  undef TLS_MD_IV_BLOCK_CONST
+/*
+ * IV block
+ */
+#  define TLS_MD_IV_BLOCK_CONST         "\x49\x56\x20\x62\x6c\x6f\x63\x6b"
+
+#  undef TLS_MD_MASTER_SECRET_CONST
+/*
+ * master secret
+ */
+#  define TLS_MD_MASTER_SECRET_CONST    "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74"
+#  undef TLS_MD_EXTENDED_MASTER_SECRET_CONST
+/*
+ * extended master secret
+ */
+#  define TLS_MD_EXTENDED_MASTER_SECRET_CONST    "\x65\x78\x74\x65\x63\x64\x65\x64\x20\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74"
+# endif
+
+/* TLS Session Ticket extension struct */
+struct tls_session_ticket_ext_st {
+    unsigned short length;
+    void *data;
+};
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ts.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ts.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ts.h	(revision 331)
@@ -0,0 +1,643 @@
+/*
+ * Copyright 2006-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
+ */
+
+#ifndef HEADER_TS_H
+# define HEADER_TS_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_TS
+# include <openssl/symhacks.h>
+# include <openssl/buffer.h>
+# include <openssl/evp.h>
+# include <openssl/bio.h>
+# include <openssl/stack.h>
+# include <openssl/asn1.h>
+# include <openssl/safestack.h>
+# include <openssl/rsa.h>
+# include <openssl/dsa.h>
+# include <openssl/dh.h>
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+# include <openssl/x509.h>
+# include <openssl/x509v3.h>
+
+typedef struct TS_msg_imprint_st TS_MSG_IMPRINT;
+typedef struct TS_req_st TS_REQ;
+typedef struct TS_accuracy_st TS_ACCURACY;
+typedef struct TS_tst_info_st TS_TST_INFO;
+
+/* Possible values for status. */
+# define TS_STATUS_GRANTED                       0
+# define TS_STATUS_GRANTED_WITH_MODS             1
+# define TS_STATUS_REJECTION                     2
+# define TS_STATUS_WAITING                       3
+# define TS_STATUS_REVOCATION_WARNING            4
+# define TS_STATUS_REVOCATION_NOTIFICATION       5
+
+/* Possible values for failure_info. */
+# define TS_INFO_BAD_ALG                 0
+# define TS_INFO_BAD_REQUEST             2
+# define TS_INFO_BAD_DATA_FORMAT         5
+# define TS_INFO_TIME_NOT_AVAILABLE      14
+# define TS_INFO_UNACCEPTED_POLICY       15
+# define TS_INFO_UNACCEPTED_EXTENSION    16
+# define TS_INFO_ADD_INFO_NOT_AVAILABLE  17
+# define TS_INFO_SYSTEM_FAILURE          25
+
+
+typedef struct TS_status_info_st TS_STATUS_INFO;
+typedef struct ESS_issuer_serial ESS_ISSUER_SERIAL;
+typedef struct ESS_cert_id ESS_CERT_ID;
+typedef struct ESS_signing_cert ESS_SIGNING_CERT;
+
+DEFINE_STACK_OF(ESS_CERT_ID)
+
+typedef struct TS_resp_st TS_RESP;
+
+TS_REQ *TS_REQ_new(void);
+void TS_REQ_free(TS_REQ *a);
+int i2d_TS_REQ(const TS_REQ *a, unsigned char **pp);
+TS_REQ *d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length);
+
+TS_REQ *TS_REQ_dup(TS_REQ *a);
+
+#ifndef OPENSSL_NO_STDIO
+TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a);
+int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a);
+#endif
+TS_REQ *d2i_TS_REQ_bio(BIO *fp, TS_REQ **a);
+int i2d_TS_REQ_bio(BIO *fp, TS_REQ *a);
+
+TS_MSG_IMPRINT *TS_MSG_IMPRINT_new(void);
+void TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a);
+int i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp);
+TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a,
+                                   const unsigned char **pp, long length);
+
+TS_MSG_IMPRINT *TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a);
+
+#ifndef OPENSSL_NO_STDIO
+TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a);
+int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a);
+#endif
+TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bio, TS_MSG_IMPRINT **a);
+int i2d_TS_MSG_IMPRINT_bio(BIO *bio, TS_MSG_IMPRINT *a);
+
+TS_RESP *TS_RESP_new(void);
+void TS_RESP_free(TS_RESP *a);
+int i2d_TS_RESP(const TS_RESP *a, unsigned char **pp);
+TS_RESP *d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length);
+TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token);
+TS_RESP *TS_RESP_dup(TS_RESP *a);
+
+#ifndef OPENSSL_NO_STDIO
+TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a);
+int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a);
+#endif
+TS_RESP *d2i_TS_RESP_bio(BIO *bio, TS_RESP **a);
+int i2d_TS_RESP_bio(BIO *bio, TS_RESP *a);
+
+TS_STATUS_INFO *TS_STATUS_INFO_new(void);
+void TS_STATUS_INFO_free(TS_STATUS_INFO *a);
+int i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp);
+TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a,
+                                   const unsigned char **pp, long length);
+TS_STATUS_INFO *TS_STATUS_INFO_dup(TS_STATUS_INFO *a);
+
+TS_TST_INFO *TS_TST_INFO_new(void);
+void TS_TST_INFO_free(TS_TST_INFO *a);
+int i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp);
+TS_TST_INFO *d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp,
+                             long length);
+TS_TST_INFO *TS_TST_INFO_dup(TS_TST_INFO *a);
+
+#ifndef OPENSSL_NO_STDIO
+TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a);
+int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a);
+#endif
+TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bio, TS_TST_INFO **a);
+int i2d_TS_TST_INFO_bio(BIO *bio, TS_TST_INFO *a);
+
+TS_ACCURACY *TS_ACCURACY_new(void);
+void TS_ACCURACY_free(TS_ACCURACY *a);
+int i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp);
+TS_ACCURACY *d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp,
+                             long length);
+TS_ACCURACY *TS_ACCURACY_dup(TS_ACCURACY *a);
+
+ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void);
+void ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a);
+int i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a, unsigned char **pp);
+ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a,
+                                         const unsigned char **pp,
+                                         long length);
+ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a);
+
+ESS_CERT_ID *ESS_CERT_ID_new(void);
+void ESS_CERT_ID_free(ESS_CERT_ID *a);
+int i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp);
+ESS_CERT_ID *d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp,
+                             long length);
+ESS_CERT_ID *ESS_CERT_ID_dup(ESS_CERT_ID *a);
+
+ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void);
+void ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a);
+int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, unsigned char **pp);
+ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a,
+                                       const unsigned char **pp, long length);
+ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a);
+
+int TS_REQ_set_version(TS_REQ *a, long version);
+long TS_REQ_get_version(const TS_REQ *a);
+
+int TS_STATUS_INFO_set_status(TS_STATUS_INFO *a, int i);
+const ASN1_INTEGER *TS_STATUS_INFO_get0_status(const TS_STATUS_INFO *a);
+
+const STACK_OF(ASN1_UTF8STRING) *
+TS_STATUS_INFO_get0_text(const TS_STATUS_INFO *a);
+
+const ASN1_BIT_STRING *
+TS_STATUS_INFO_get0_failure_info(const TS_STATUS_INFO *a);
+
+int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint);
+TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a);
+
+int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg);
+X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a);
+
+int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len);
+ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a);
+
+int TS_REQ_set_policy_id(TS_REQ *a, const ASN1_OBJECT *policy);
+ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a);
+
+int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce);
+const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a);
+
+int TS_REQ_set_cert_req(TS_REQ *a, int cert_req);
+int TS_REQ_get_cert_req(const TS_REQ *a);
+
+STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a);
+void TS_REQ_ext_free(TS_REQ *a);
+int TS_REQ_get_ext_count(TS_REQ *a);
+int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos);
+int TS_REQ_get_ext_by_OBJ(TS_REQ *a, const ASN1_OBJECT *obj, int lastpos);
+int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos);
+X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc);
+X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc);
+int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc);
+void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx);
+
+/* Function declarations for TS_REQ defined in ts/ts_req_print.c */
+
+int TS_REQ_print_bio(BIO *bio, TS_REQ *a);
+
+/* Function declarations for TS_RESP defined in ts/ts_resp_utils.c */
+
+int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *info);
+TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a);
+
+/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */
+void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info);
+PKCS7 *TS_RESP_get_token(TS_RESP *a);
+TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a);
+
+int TS_TST_INFO_set_version(TS_TST_INFO *a, long version);
+long TS_TST_INFO_get_version(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy_id);
+ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a);
+
+int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint);
+TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a);
+
+int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial);
+const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime);
+const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy);
+TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a);
+
+int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds);
+const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a);
+
+int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis);
+const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a);
+
+int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros);
+const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a);
+
+int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering);
+int TS_TST_INFO_get_ordering(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce);
+const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a);
+
+int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa);
+GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a);
+
+STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a);
+void TS_TST_INFO_ext_free(TS_TST_INFO *a);
+int TS_TST_INFO_get_ext_count(TS_TST_INFO *a);
+int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos);
+int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, const ASN1_OBJECT *obj,
+                               int lastpos);
+int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos);
+X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc);
+X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc);
+int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc);
+void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx);
+
+/*
+ * Declarations related to response generation, defined in ts/ts_resp_sign.c.
+ */
+
+/* Optional flags for response generation. */
+
+/* Don't include the TSA name in response. */
+# define TS_TSA_NAME             0x01
+
+/* Set ordering to true in response. */
+# define TS_ORDERING             0x02
+
+/*
+ * Include the signer certificate and the other specified certificates in
+ * the ESS signing certificate attribute beside the PKCS7 signed data.
+ * Only the signer certificates is included by default.
+ */
+# define TS_ESS_CERT_ID_CHAIN    0x04
+
+/* Forward declaration. */
+struct TS_resp_ctx;
+
+/* This must return a unique number less than 160 bits long. */
+typedef ASN1_INTEGER *(*TS_serial_cb) (struct TS_resp_ctx *, void *);
+
+/*
+ * This must return the seconds and microseconds since Jan 1, 1970 in the sec
+ * and usec variables allocated by the caller. Return non-zero for success
+ * and zero for failure.
+ */
+typedef int (*TS_time_cb) (struct TS_resp_ctx *, void *, long *sec,
+                           long *usec);
+
+/*
+ * This must process the given extension. It can modify the TS_TST_INFO
+ * object of the context. Return values: !0 (processed), 0 (error, it must
+ * set the status info/failure info of the response).
+ */
+typedef int (*TS_extension_cb) (struct TS_resp_ctx *, X509_EXTENSION *,
+                                void *);
+
+typedef struct TS_resp_ctx TS_RESP_CTX;
+
+DEFINE_STACK_OF_CONST(EVP_MD)
+
+/* Creates a response context that can be used for generating responses. */
+TS_RESP_CTX *TS_RESP_CTX_new(void);
+void TS_RESP_CTX_free(TS_RESP_CTX *ctx);
+
+/* This parameter must be set. */
+int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer);
+
+/* This parameter must be set. */
+int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key);
+
+int TS_RESP_CTX_set_signer_digest(TS_RESP_CTX *ctx,
+                                  const EVP_MD *signer_digest);
+
+/* This parameter must be set. */
+int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *def_policy);
+
+/* No additional certs are included in the response by default. */
+int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs);
+
+/*
+ * Adds a new acceptable policy, only the default policy is accepted by
+ * default.
+ */
+int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, const ASN1_OBJECT *policy);
+
+/*
+ * Adds a new acceptable message digest. Note that no message digests are
+ * accepted by default. The md argument is shared with the caller.
+ */
+int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md);
+
+/* Accuracy is not included by default. */
+int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx,
+                             int secs, int millis, int micros);
+
+/*
+ * Clock precision digits, i.e. the number of decimal digits: '0' means sec,
+ * '3' msec, '6' usec, and so on. Default is 0.
+ */
+int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx,
+                                           unsigned clock_precision_digits);
+/* At most we accept usec precision. */
+# define TS_MAX_CLOCK_PRECISION_DIGITS   6
+
+/* Maximum status message length */
+# define TS_MAX_STATUS_LENGTH   (1024 * 1024)
+
+/* No flags are set by default. */
+void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags);
+
+/* Default callback always returns a constant. */
+void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data);
+
+/* Default callback uses the gettimeofday() and gmtime() system calls. */
+void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data);
+
+/*
+ * Default callback rejects all extensions. The extension callback is called
+ * when the TS_TST_INFO object is already set up and not signed yet.
+ */
+/* FIXME: extension handling is not tested yet. */
+void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx,
+                                  TS_extension_cb cb, void *data);
+
+/* The following methods can be used in the callbacks. */
+int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx,
+                                int status, const char *text);
+
+/* Sets the status info only if it is still TS_STATUS_GRANTED. */
+int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx,
+                                     int status, const char *text);
+
+int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure);
+
+/* The get methods below can be used in the extension callback. */
+TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx);
+
+TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx);
+
+/*
+ * Creates the signed TS_TST_INFO and puts it in TS_RESP.
+ * In case of errors it sets the status info properly.
+ * Returns NULL only in case of memory allocation/fatal error.
+ */
+TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio);
+
+/*
+ * Declarations related to response verification,
+ * they are defined in ts/ts_resp_verify.c.
+ */
+
+int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
+                             X509_STORE *store, X509 **signer_out);
+
+/* Context structure for the generic verify method. */
+
+/* Verify the signer's certificate and the signature of the response. */
+# define TS_VFY_SIGNATURE        (1u << 0)
+/* Verify the version number of the response. */
+# define TS_VFY_VERSION          (1u << 1)
+/* Verify if the policy supplied by the user matches the policy of the TSA. */
+# define TS_VFY_POLICY           (1u << 2)
+/*
+ * Verify the message imprint provided by the user. This flag should not be
+ * specified with TS_VFY_DATA.
+ */
+# define TS_VFY_IMPRINT          (1u << 3)
+/*
+ * Verify the message imprint computed by the verify method from the user
+ * provided data and the MD algorithm of the response. This flag should not
+ * be specified with TS_VFY_IMPRINT.
+ */
+# define TS_VFY_DATA             (1u << 4)
+/* Verify the nonce value. */
+# define TS_VFY_NONCE            (1u << 5)
+/* Verify if the TSA name field matches the signer certificate. */
+# define TS_VFY_SIGNER           (1u << 6)
+/* Verify if the TSA name field equals to the user provided name. */
+# define TS_VFY_TSA_NAME         (1u << 7)
+
+/* You can use the following convenience constants. */
+# define TS_VFY_ALL_IMPRINT      (TS_VFY_SIGNATURE       \
+                                 | TS_VFY_VERSION       \
+                                 | TS_VFY_POLICY        \
+                                 | TS_VFY_IMPRINT       \
+                                 | TS_VFY_NONCE         \
+                                 | TS_VFY_SIGNER        \
+                                 | TS_VFY_TSA_NAME)
+# define TS_VFY_ALL_DATA         (TS_VFY_SIGNATURE       \
+                                 | TS_VFY_VERSION       \
+                                 | TS_VFY_POLICY        \
+                                 | TS_VFY_DATA          \
+                                 | TS_VFY_NONCE         \
+                                 | TS_VFY_SIGNER        \
+                                 | TS_VFY_TSA_NAME)
+
+typedef struct TS_verify_ctx TS_VERIFY_CTX;
+
+int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response);
+int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token);
+
+/*
+ * Declarations related to response verification context,
+ */
+TS_VERIFY_CTX *TS_VERIFY_CTX_new(void);
+void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx);
+void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx);
+void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx);
+int TS_VERIFY_CTX_set_flags(TS_VERIFY_CTX *ctx, int f);
+int TS_VERIFY_CTX_add_flags(TS_VERIFY_CTX *ctx, int f);
+BIO *TS_VERIFY_CTX_set_data(TS_VERIFY_CTX *ctx, BIO *b);
+unsigned char *TS_VERIFY_CTX_set_imprint(TS_VERIFY_CTX *ctx,
+                                         unsigned char *hexstr, long len);
+X509_STORE *TS_VERIFY_CTX_set_store(TS_VERIFY_CTX *ctx, X509_STORE *s);
+STACK_OF(X509) *TS_VERIFY_CTS_set_certs(TS_VERIFY_CTX *ctx, STACK_OF(X509) *certs);
+
+/*-
+ * If ctx is NULL, it allocates and returns a new object, otherwise
+ * it returns ctx. It initialises all the members as follows:
+ * flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE)
+ * certs = NULL
+ * store = NULL
+ * policy = policy from the request or NULL if absent (in this case
+ *      TS_VFY_POLICY is cleared from flags as well)
+ * md_alg = MD algorithm from request
+ * imprint, imprint_len = imprint from request
+ * data = NULL
+ * nonce, nonce_len = nonce from the request or NULL if absent (in this case
+ *      TS_VFY_NONCE is cleared from flags as well)
+ * tsa_name = NULL
+ * Important: after calling this method TS_VFY_SIGNATURE should be added!
+ */
+TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx);
+
+/* Function declarations for TS_RESP defined in ts/ts_resp_print.c */
+
+int TS_RESP_print_bio(BIO *bio, TS_RESP *a);
+int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a);
+int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a);
+
+/* Common utility functions defined in ts/ts_lib.c */
+
+int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num);
+int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj);
+int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions);
+int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg);
+int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg);
+
+/*
+ * Function declarations for handling configuration options, defined in
+ * ts/ts_conf.c
+ */
+
+X509 *TS_CONF_load_cert(const char *file);
+STACK_OF(X509) *TS_CONF_load_certs(const char *file);
+EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass);
+const char *TS_CONF_get_tsa_section(CONF *conf, const char *section);
+int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb,
+                       TS_RESP_CTX *ctx);
+#ifndef OPENSSL_NO_ENGINE
+int TS_CONF_set_crypto_device(CONF *conf, const char *section,
+                              const char *device);
+int TS_CONF_set_default_engine(const char *name);
+#endif
+int TS_CONF_set_signer_cert(CONF *conf, const char *section,
+                            const char *cert, TS_RESP_CTX *ctx);
+int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs,
+                      TS_RESP_CTX *ctx);
+int TS_CONF_set_signer_key(CONF *conf, const char *section,
+                           const char *key, const char *pass,
+                           TS_RESP_CTX *ctx);
+int TS_CONF_set_signer_digest(CONF *conf, const char *section,
+                               const char *md, TS_RESP_CTX *ctx);
+int TS_CONF_set_def_policy(CONF *conf, const char *section,
+                           const char *policy, TS_RESP_CTX *ctx);
+int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section,
+                                       TS_RESP_CTX *ctx);
+int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx);
+int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section,
+                                  TS_RESP_CTX *ctx);
+
+/* -------------------------------------------------- */
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_TS_strings(void);
+
+/* Error codes for the TS functions. */
+
+/* Function codes. */
+# define TS_F_DEF_SERIAL_CB                               110
+# define TS_F_DEF_TIME_CB                                 111
+# define TS_F_ESS_ADD_SIGNING_CERT                        112
+# define TS_F_ESS_CERT_ID_NEW_INIT                        113
+# define TS_F_ESS_SIGNING_CERT_NEW_INIT                   114
+# define TS_F_INT_TS_RESP_VERIFY_TOKEN                    149
+# define TS_F_PKCS7_TO_TS_TST_INFO                        148
+# define TS_F_TS_ACCURACY_SET_MICROS                      115
+# define TS_F_TS_ACCURACY_SET_MILLIS                      116
+# define TS_F_TS_ACCURACY_SET_SECONDS                     117
+# define TS_F_TS_CHECK_IMPRINTS                           100
+# define TS_F_TS_CHECK_NONCES                             101
+# define TS_F_TS_CHECK_POLICY                             102
+# define TS_F_TS_CHECK_SIGNING_CERTS                      103
+# define TS_F_TS_CHECK_STATUS_INFO                        104
+# define TS_F_TS_COMPUTE_IMPRINT                          145
+# define TS_F_TS_CONF_INVALID                             151
+# define TS_F_TS_CONF_LOAD_CERT                           153
+# define TS_F_TS_CONF_LOAD_CERTS                          154
+# define TS_F_TS_CONF_LOAD_KEY                            155
+# define TS_F_TS_CONF_LOOKUP_FAIL                         152
+# define TS_F_TS_CONF_SET_DEFAULT_ENGINE                  146
+# define TS_F_TS_GET_STATUS_TEXT                          105
+# define TS_F_TS_MSG_IMPRINT_SET_ALGO                     118
+# define TS_F_TS_REQ_SET_MSG_IMPRINT                      119
+# define TS_F_TS_REQ_SET_NONCE                            120
+# define TS_F_TS_REQ_SET_POLICY_ID                        121
+# define TS_F_TS_RESP_CREATE_RESPONSE                     122
+# define TS_F_TS_RESP_CREATE_TST_INFO                     123
+# define TS_F_TS_RESP_CTX_ADD_FAILURE_INFO                124
+# define TS_F_TS_RESP_CTX_ADD_MD                          125
+# define TS_F_TS_RESP_CTX_ADD_POLICY                      126
+# define TS_F_TS_RESP_CTX_NEW                             127
+# define TS_F_TS_RESP_CTX_SET_ACCURACY                    128
+# define TS_F_TS_RESP_CTX_SET_CERTS                       129
+# define TS_F_TS_RESP_CTX_SET_DEF_POLICY                  130
+# define TS_F_TS_RESP_CTX_SET_SIGNER_CERT                 131
+# define TS_F_TS_RESP_CTX_SET_STATUS_INFO                 132
+# define TS_F_TS_RESP_GET_POLICY                          133
+# define TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION          134
+# define TS_F_TS_RESP_SET_STATUS_INFO                     135
+# define TS_F_TS_RESP_SET_TST_INFO                        150
+# define TS_F_TS_RESP_SIGN                                136
+# define TS_F_TS_RESP_VERIFY_SIGNATURE                    106
+# define TS_F_TS_TST_INFO_SET_ACCURACY                    137
+# define TS_F_TS_TST_INFO_SET_MSG_IMPRINT                 138
+# define TS_F_TS_TST_INFO_SET_NONCE                       139
+# define TS_F_TS_TST_INFO_SET_POLICY_ID                   140
+# define TS_F_TS_TST_INFO_SET_SERIAL                      141
+# define TS_F_TS_TST_INFO_SET_TIME                        142
+# define TS_F_TS_TST_INFO_SET_TSA                         143
+# define TS_F_TS_VERIFY                                   108
+# define TS_F_TS_VERIFY_CERT                              109
+# define TS_F_TS_VERIFY_CTX_NEW                           144
+
+/* Reason codes. */
+# define TS_R_BAD_PKCS7_TYPE                              132
+# define TS_R_BAD_TYPE                                    133
+# define TS_R_CANNOT_LOAD_CERT                            137
+# define TS_R_CANNOT_LOAD_KEY                             138
+# define TS_R_CERTIFICATE_VERIFY_ERROR                    100
+# define TS_R_COULD_NOT_SET_ENGINE                        127
+# define TS_R_COULD_NOT_SET_TIME                          115
+# define TS_R_DETACHED_CONTENT                            134
+# define TS_R_ESS_ADD_SIGNING_CERT_ERROR                  116
+# define TS_R_ESS_SIGNING_CERTIFICATE_ERROR               101
+# define TS_R_INVALID_NULL_POINTER                        102
+# define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE          117
+# define TS_R_MESSAGE_IMPRINT_MISMATCH                    103
+# define TS_R_NONCE_MISMATCH                              104
+# define TS_R_NONCE_NOT_RETURNED                          105
+# define TS_R_NO_CONTENT                                  106
+# define TS_R_NO_TIME_STAMP_TOKEN                         107
+# define TS_R_PKCS7_ADD_SIGNATURE_ERROR                   118
+# define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR                 119
+# define TS_R_PKCS7_TO_TS_TST_INFO_FAILED                 129
+# define TS_R_POLICY_MISMATCH                             108
+# define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE      120
+# define TS_R_RESPONSE_SETUP_ERROR                        121
+# define TS_R_SIGNATURE_FAILURE                           109
+# define TS_R_THERE_MUST_BE_ONE_SIGNER                    110
+# define TS_R_TIME_SYSCALL_ERROR                          122
+# define TS_R_TOKEN_NOT_PRESENT                           130
+# define TS_R_TOKEN_PRESENT                               131
+# define TS_R_TSA_NAME_MISMATCH                           111
+# define TS_R_TSA_UNTRUSTED                               112
+# define TS_R_TST_INFO_SETUP_ERROR                        123
+# define TS_R_TS_DATASIGN                                 124
+# define TS_R_UNACCEPTABLE_POLICY                         125
+# define TS_R_UNSUPPORTED_MD_ALGORITHM                    126
+# define TS_R_UNSUPPORTED_VERSION                         113
+# define TS_R_VAR_BAD_VALUE                               135
+# define TS_R_VAR_LOOKUP_FAILURE                          136
+# define TS_R_WRONG_CONTENT_TYPE                          114
+
+#  ifdef  __cplusplus
+}
+#  endif
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/txt_db.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/txt_db.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/txt_db.h	(revision 331)
@@ -0,0 +1,57 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_TXT_DB_H
+# define HEADER_TXT_DB_H
+
+# include <openssl/opensslconf.h>
+# include <openssl/bio.h>
+# include <openssl/stack.h>
+# include <openssl/lhash.h>
+
+# define DB_ERROR_OK                     0
+# define DB_ERROR_MALLOC                 1
+# define DB_ERROR_INDEX_CLASH            2
+# define DB_ERROR_INDEX_OUT_OF_RANGE     3
+# define DB_ERROR_NO_INDEX               4
+# define DB_ERROR_INSERT_INDEX_CLASH     5
+# define DB_ERROR_WRONG_NUM_FIELDS       6
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef OPENSSL_STRING *OPENSSL_PSTRING;
+DEFINE_SPECIAL_STACK_OF(OPENSSL_PSTRING, OPENSSL_STRING)
+
+typedef struct txt_db_st {
+    int num_fields;
+    STACK_OF(OPENSSL_PSTRING) *data;
+    LHASH_OF(OPENSSL_STRING) **index;
+    int (**qual) (OPENSSL_STRING *);
+    long error;
+    long arg1;
+    long arg2;
+    OPENSSL_STRING *arg_row;
+} TXT_DB;
+
+TXT_DB *TXT_DB_read(BIO *in, int num);
+long TXT_DB_write(BIO *out, TXT_DB *db);
+int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *),
+                        OPENSSL_LH_HASHFUNC hash, OPENSSL_LH_COMPFUNC cmp);
+void TXT_DB_free(TXT_DB *db);
+OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx,
+                                    OPENSSL_STRING *value);
+int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *value);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ui.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ui.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/ui.h	(revision 331)
@@ -0,0 +1,378 @@
+/*
+ * Copyright 2001-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
+ */
+
+#ifndef HEADER_UI_H
+# define HEADER_UI_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_UI
+
+#  if OPENSSL_API_COMPAT < 0x10100000L
+#   include <openssl/crypto.h>
+#  endif
+#  include <openssl/safestack.h>
+#  include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+ * All the following functions return -1 or NULL on error and in some cases
+ * (UI_process()) -2 if interrupted or in some other way cancelled. When
+ * everything is fine, they return 0, a positive value or a non-NULL pointer,
+ * all depending on their purpose.
+ */
+
+/* Creators and destructor.   */
+UI *UI_new(void);
+UI *UI_new_method(const UI_METHOD *method);
+void UI_free(UI *ui);
+
+/*-
+   The following functions are used to add strings to be printed and prompt
+   strings to prompt for data.  The names are UI_{add,dup}_<function>_string
+   and UI_{add,dup}_input_boolean.
+
+   UI_{add,dup}_<function>_string have the following meanings:
+        add     add a text or prompt string.  The pointers given to these
+                functions are used verbatim, no copying is done.
+        dup     make a copy of the text or prompt string, then add the copy
+                to the collection of strings in the user interface.
+        <function>
+                The function is a name for the functionality that the given
+                string shall be used for.  It can be one of:
+                        input   use the string as data prompt.
+                        verify  use the string as verification prompt.  This
+                                is used to verify a previous input.
+                        info    use the string for informational output.
+                        error   use the string for error output.
+   Honestly, there's currently no difference between info and error for the
+   moment.
+
+   UI_{add,dup}_input_boolean have the same semantics for "add" and "dup",
+   and are typically used when one wants to prompt for a yes/no response.
+
+   All of the functions in this group take a UI and a prompt string.
+   The string input and verify addition functions also take a flag argument,
+   a buffer for the result to end up with, a minimum input size and a maximum
+   input size (the result buffer MUST be large enough to be able to contain
+   the maximum number of characters).  Additionally, the verify addition
+   functions takes another buffer to compare the result against.
+   The boolean input functions take an action description string (which should
+   be safe to ignore if the expected user action is obvious, for example with
+   a dialog box with an OK button and a Cancel button), a string of acceptable
+   characters to mean OK and to mean Cancel.  The two last strings are checked
+   to make sure they don't have common characters.  Additionally, the same
+   flag argument as for the string input is taken, as well as a result buffer.
+   The result buffer is required to be at least one byte long.  Depending on
+   the answer, the first character from the OK or the Cancel character strings
+   will be stored in the first byte of the result buffer.  No NUL will be
+   added, so the result is *not* a string.
+
+   On success, the all return an index of the added information.  That index
+   is useful when retrieving results with UI_get0_result(). */
+int UI_add_input_string(UI *ui, const char *prompt, int flags,
+                        char *result_buf, int minsize, int maxsize);
+int UI_dup_input_string(UI *ui, const char *prompt, int flags,
+                        char *result_buf, int minsize, int maxsize);
+int UI_add_verify_string(UI *ui, const char *prompt, int flags,
+                         char *result_buf, int minsize, int maxsize,
+                         const char *test_buf);
+int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
+                         char *result_buf, int minsize, int maxsize,
+                         const char *test_buf);
+int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
+                         const char *ok_chars, const char *cancel_chars,
+                         int flags, char *result_buf);
+int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
+                         const char *ok_chars, const char *cancel_chars,
+                         int flags, char *result_buf);
+int UI_add_info_string(UI *ui, const char *text);
+int UI_dup_info_string(UI *ui, const char *text);
+int UI_add_error_string(UI *ui, const char *text);
+int UI_dup_error_string(UI *ui, const char *text);
+
+/* These are the possible flags.  They can be or'ed together. */
+/* Use to have echoing of input */
+# define UI_INPUT_FLAG_ECHO              0x01
+/*
+ * Use a default password.  Where that password is found is completely up to
+ * the application, it might for example be in the user data set with
+ * UI_add_user_data().  It is not recommended to have more than one input in
+ * each UI being marked with this flag, or the application might get
+ * confused.
+ */
+#  define UI_INPUT_FLAG_DEFAULT_PWD       0x02
+
+/*-
+ * The user of these routines may want to define flags of their own.  The core
+ * UI won't look at those, but will pass them on to the method routines.  They
+ * must use higher bits so they don't get confused with the UI bits above.
+ * UI_INPUT_FLAG_USER_BASE tells which is the lowest bit to use.  A good
+ * example of use is this:
+ *
+ *    #define MY_UI_FLAG1       (0x01 << UI_INPUT_FLAG_USER_BASE)
+ *
+*/
+#  define UI_INPUT_FLAG_USER_BASE 16
+
+/*-
+ * The following function helps construct a prompt.  object_desc is a
+ * textual short description of the object, for example "pass phrase",
+ * and object_name is the name of the object (might be a card name or
+ * a file name.
+ * The returned string shall always be allocated on the heap with
+ * OPENSSL_malloc(), and need to be free'd with OPENSSL_free().
+ *
+ * If the ui_method doesn't contain a pointer to a user-defined prompt
+ * constructor, a default string is built, looking like this:
+ *
+ *       "Enter {object_desc} for {object_name}:"
+ *
+ * So, if object_desc has the value "pass phrase" and object_name has
+ * the value "foo.key", the resulting string is:
+ *
+ *       "Enter pass phrase for foo.key:"
+*/
+char *UI_construct_prompt(UI *ui_method,
+                          const char *object_desc, const char *object_name);
+
+/*
+ * The following function is used to store a pointer to user-specific data.
+ * Any previous such pointer will be returned and replaced.
+ *
+ * For callback purposes, this function makes a lot more sense than using
+ * ex_data, since the latter requires that different parts of OpenSSL or
+ * applications share the same ex_data index.
+ *
+ * Note that the UI_OpenSSL() method completely ignores the user data. Other
+ * methods may not, however.
+ */
+void *UI_add_user_data(UI *ui, void *user_data);
+/* We need a user data retrieving function as well.  */
+void *UI_get0_user_data(UI *ui);
+
+/* Return the result associated with a prompt given with the index i. */
+const char *UI_get0_result(UI *ui, int i);
+
+/* When all strings have been added, process the whole thing. */
+int UI_process(UI *ui);
+
+/*
+ * Give a user interface parametrised control commands.  This can be used to
+ * send down an integer, a data pointer or a function pointer, as well as be
+ * used to get information from a UI.
+ */
+int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void));
+
+/* The commands */
+/*
+ * Use UI_CONTROL_PRINT_ERRORS with the value 1 to have UI_process print the
+ * OpenSSL error stack before printing any info or added error messages and
+ * before any prompting.
+ */
+#  define UI_CTRL_PRINT_ERRORS            1
+/*
+ * Check if a UI_process() is possible to do again with the same instance of
+ * a user interface.  This makes UI_ctrl() return 1 if it is redoable, and 0
+ * if not.
+ */
+# define UI_CTRL_IS_REDOABLE             2
+
+/* Some methods may use extra data */
+# define UI_set_app_data(s,arg)         UI_set_ex_data(s,0,arg)
+# define UI_get_app_data(s)             UI_get_ex_data(s,0)
+
+#define UI_get_ex_new_index(l, p, newf, dupf, freef) \
+    CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI, l, p, newf, dupf, freef)
+int UI_set_ex_data(UI *r, int idx, void *arg);
+void *UI_get_ex_data(UI *r, int idx);
+
+/* Use specific methods instead of the built-in one */
+void UI_set_default_method(const UI_METHOD *meth);
+const UI_METHOD *UI_get_default_method(void);
+const UI_METHOD *UI_get_method(UI *ui);
+const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth);
+
+/* The method with all the built-in thingies */
+UI_METHOD *UI_OpenSSL(void);
+
+/* ---------- For method writers ---------- */
+/*-
+   A method contains a number of functions that implement the low level
+   of the User Interface.  The functions are:
+
+        an opener       This function starts a session, maybe by opening
+                        a channel to a tty, or by opening a window.
+        a writer        This function is called to write a given string,
+                        maybe to the tty, maybe as a field label in a
+                        window.
+        a flusher       This function is called to flush everything that
+                        has been output so far.  It can be used to actually
+                        display a dialog box after it has been built.
+        a reader        This function is called to read a given prompt,
+                        maybe from the tty, maybe from a field in a
+                        window.  Note that it's called with all string
+                        structures, not only the prompt ones, so it must
+                        check such things itself.
+        a closer        This function closes the session, maybe by closing
+                        the channel to the tty, or closing the window.
+
+   All these functions are expected to return:
+
+        0       on error.
+        1       on success.
+        -1      on out-of-band events, for example if some prompting has
+                been canceled (by pressing Ctrl-C, for example).  This is
+                only checked when returned by the flusher or the reader.
+
+   The way this is used, the opener is first called, then the writer for all
+   strings, then the flusher, then the reader for all strings and finally the
+   closer.  Note that if you want to prompt from a terminal or other command
+   line interface, the best is to have the reader also write the prompts
+   instead of having the writer do it.  If you want to prompt from a dialog
+   box, the writer can be used to build up the contents of the box, and the
+   flusher to actually display the box and run the event loop until all data
+   has been given, after which the reader only grabs the given data and puts
+   them back into the UI strings.
+
+   All method functions take a UI as argument.  Additionally, the writer and
+   the reader take a UI_STRING.
+*/
+
+/*
+ * The UI_STRING type is the data structure that contains all the needed info
+ * about a string or a prompt, including test data for a verification prompt.
+ */
+typedef struct ui_string_st UI_STRING;
+DEFINE_STACK_OF(UI_STRING)
+
+/*
+ * The different types of strings that are currently supported. This is only
+ * needed by method authors.
+ */
+enum UI_string_types {
+    UIT_NONE = 0,
+    UIT_PROMPT,                 /* Prompt for a string */
+    UIT_VERIFY,                 /* Prompt for a string and verify */
+    UIT_BOOLEAN,                /* Prompt for a yes/no response */
+    UIT_INFO,                   /* Send info to the user */
+    UIT_ERROR                   /* Send an error message to the user */
+};
+
+/* Create and manipulate methods */
+UI_METHOD *UI_create_method(const char *name);
+void UI_destroy_method(UI_METHOD *ui_method);
+int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui));
+int UI_method_set_writer(UI_METHOD *method,
+                         int (*writer) (UI *ui, UI_STRING *uis));
+int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui));
+int UI_method_set_reader(UI_METHOD *method,
+                         int (*reader) (UI *ui, UI_STRING *uis));
+int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui));
+int UI_method_set_prompt_constructor(UI_METHOD *method,
+                                     char *(*prompt_constructor) (UI *ui,
+                                                                  const char
+                                                                  *object_desc,
+                                                                  const char
+                                                                  *object_name));
+int (*UI_method_get_opener(UI_METHOD *method)) (UI *);
+int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *);
+int (*UI_method_get_flusher(UI_METHOD *method)) (UI *);
+int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *);
+int (*UI_method_get_closer(UI_METHOD *method)) (UI *);
+char *(*UI_method_get_prompt_constructor(UI_METHOD *method)) (UI *,
+                                                              const char *,
+                                                              const char *);
+
+/*
+ * The following functions are helpers for method writers to access relevant
+ * data from a UI_STRING.
+ */
+
+/* Return type of the UI_STRING */
+enum UI_string_types UI_get_string_type(UI_STRING *uis);
+/* Return input flags of the UI_STRING */
+int UI_get_input_flags(UI_STRING *uis);
+/* Return the actual string to output (the prompt, info or error) */
+const char *UI_get0_output_string(UI_STRING *uis);
+/*
+ * Return the optional action string to output (the boolean prompt
+ * instruction)
+ */
+const char *UI_get0_action_string(UI_STRING *uis);
+/* Return the result of a prompt */
+const char *UI_get0_result_string(UI_STRING *uis);
+/*
+ * Return the string to test the result against.  Only useful with verifies.
+ */
+const char *UI_get0_test_string(UI_STRING *uis);
+/* Return the required minimum size of the result */
+int UI_get_result_minsize(UI_STRING *uis);
+/* Return the required maximum size of the result */
+int UI_get_result_maxsize(UI_STRING *uis);
+/* Set the result of a UI_STRING. */
+int UI_set_result(UI *ui, UI_STRING *uis, const char *result);
+
+/* A couple of popular utility functions */
+int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt,
+                           int verify);
+int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt,
+                    int verify);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_UI_strings(void);
+
+/* Error codes for the UI functions. */
+
+/* Function codes. */
+# define UI_F_CLOSE_CONSOLE                               115
+# define UI_F_ECHO_CONSOLE                                116
+# define UI_F_GENERAL_ALLOCATE_BOOLEAN                    108
+# define UI_F_GENERAL_ALLOCATE_PROMPT                     109
+# define UI_F_NOECHO_CONSOLE                              117
+# define UI_F_OPEN_CONSOLE                                114
+# define UI_F_UI_CREATE_METHOD                            112
+# define UI_F_UI_CTRL                                     111
+# define UI_F_UI_DUP_ERROR_STRING                         101
+# define UI_F_UI_DUP_INFO_STRING                          102
+# define UI_F_UI_DUP_INPUT_BOOLEAN                        110
+# define UI_F_UI_DUP_INPUT_STRING                         103
+# define UI_F_UI_DUP_VERIFY_STRING                        106
+# define UI_F_UI_GET0_RESULT                              107
+# define UI_F_UI_NEW_METHOD                               104
+# define UI_F_UI_PROCESS                                  113
+# define UI_F_UI_SET_RESULT                               105
+
+/* Reason codes. */
+# define UI_R_COMMON_OK_AND_CANCEL_CHARACTERS             104
+# define UI_R_INDEX_TOO_LARGE                             102
+# define UI_R_INDEX_TOO_SMALL                             103
+# define UI_R_NO_RESULT_BUFFER                            105
+# define UI_R_PROCESSING_ERROR                            107
+# define UI_R_RESULT_TOO_LARGE                            100
+# define UI_R_RESULT_TOO_SMALL                            101
+# define UI_R_SYSASSIGN_ERROR                             109
+# define UI_R_SYSDASSGN_ERROR                             110
+# define UI_R_SYSQIOW_ERROR                               111
+# define UI_R_UNKNOWN_CONTROL_COMMAND                     106
+# define UI_R_UNKNOWN_TTYGET_ERRNO_VALUE                  108
+
+#  ifdef  __cplusplus
+}
+#  endif
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/whrlpool.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/whrlpool.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/whrlpool.h	(revision 331)
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2005-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
+ */
+
+#ifndef HEADER_WHRLPOOL_H
+# define HEADER_WHRLPOOL_H
+
+#include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_WHIRLPOOL
+# include <openssl/e_os2.h>
+# include <stddef.h>
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+# define WHIRLPOOL_DIGEST_LENGTH (512/8)
+# define WHIRLPOOL_BBLOCK        512
+# define WHIRLPOOL_COUNTER       (256/8)
+
+typedef struct {
+    union {
+        unsigned char c[WHIRLPOOL_DIGEST_LENGTH];
+        /* double q is here to ensure 64-bit alignment */
+        double q[WHIRLPOOL_DIGEST_LENGTH / sizeof(double)];
+    } H;
+    unsigned char data[WHIRLPOOL_BBLOCK / 8];
+    unsigned int bitoff;
+    size_t bitlen[WHIRLPOOL_COUNTER / sizeof(size_t)];
+} WHIRLPOOL_CTX;
+
+int WHIRLPOOL_Init(WHIRLPOOL_CTX *c);
+int WHIRLPOOL_Update(WHIRLPOOL_CTX *c, const void *inp, size_t bytes);
+void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *inp, size_t bits);
+int WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c);
+unsigned char *WHIRLPOOL(const void *inp, size_t bytes, unsigned char *md);
+
+# ifdef __cplusplus
+}
+# endif
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/x509.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/x509.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/x509.h	(revision 331)
@@ -0,0 +1,1123 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_X509_H
+# define HEADER_X509_H
+
+# include <openssl/e_os2.h>
+# include <openssl/ossl_typ.h>
+# include <openssl/symhacks.h>
+# include <openssl/buffer.h>
+# include <openssl/evp.h>
+# include <openssl/bio.h>
+# include <openssl/stack.h>
+# include <openssl/asn1.h>
+# include <openssl/safestack.h>
+# include <openssl/ec.h>
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  include <openssl/rsa.h>
+#  include <openssl/dsa.h>
+#  include <openssl/dh.h>
+# endif
+
+# include <openssl/sha.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define X509_FILETYPE_PEM       1
+# define X509_FILETYPE_ASN1      2
+# define X509_FILETYPE_DEFAULT   3
+
+# define X509v3_KU_DIGITAL_SIGNATURE     0x0080
+# define X509v3_KU_NON_REPUDIATION       0x0040
+# define X509v3_KU_KEY_ENCIPHERMENT      0x0020
+# define X509v3_KU_DATA_ENCIPHERMENT     0x0010
+# define X509v3_KU_KEY_AGREEMENT         0x0008
+# define X509v3_KU_KEY_CERT_SIGN         0x0004
+# define X509v3_KU_CRL_SIGN              0x0002
+# define X509v3_KU_ENCIPHER_ONLY         0x0001
+# define X509v3_KU_DECIPHER_ONLY         0x8000
+# define X509v3_KU_UNDEF                 0xffff
+
+struct X509_algor_st {
+    ASN1_OBJECT *algorithm;
+    ASN1_TYPE *parameter;
+} /* X509_ALGOR */ ;
+
+typedef STACK_OF(X509_ALGOR) X509_ALGORS;
+
+typedef struct X509_val_st {
+    ASN1_TIME *notBefore;
+    ASN1_TIME *notAfter;
+} X509_VAL;
+
+typedef struct X509_sig_st X509_SIG;
+
+typedef struct X509_name_entry_st X509_NAME_ENTRY;
+
+DEFINE_STACK_OF(X509_NAME_ENTRY)
+
+DEFINE_STACK_OF(X509_NAME)
+
+# define X509_EX_V_NETSCAPE_HACK         0x8000
+# define X509_EX_V_INIT                  0x0001
+typedef struct X509_extension_st X509_EXTENSION;
+
+typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS;
+
+DEFINE_STACK_OF(X509_EXTENSION)
+
+typedef struct x509_attributes_st X509_ATTRIBUTE;
+
+DEFINE_STACK_OF(X509_ATTRIBUTE)
+
+typedef struct X509_req_info_st X509_REQ_INFO;
+
+typedef struct X509_req_st X509_REQ;
+
+typedef struct x509_cert_aux_st X509_CERT_AUX;
+
+typedef struct x509_cinf_st X509_CINF;
+
+DEFINE_STACK_OF(X509)
+
+/* This is used for a table of trust checking functions */
+
+typedef struct x509_trust_st {
+    int trust;
+    int flags;
+    int (*check_trust) (struct x509_trust_st *, X509 *, int);
+    char *name;
+    int arg1;
+    void *arg2;
+} X509_TRUST;
+
+DEFINE_STACK_OF(X509_TRUST)
+
+/* standard trust ids */
+
+# define X509_TRUST_DEFAULT      0 /* Only valid in purpose settings */
+
+# define X509_TRUST_COMPAT       1
+# define X509_TRUST_SSL_CLIENT   2
+# define X509_TRUST_SSL_SERVER   3
+# define X509_TRUST_EMAIL        4
+# define X509_TRUST_OBJECT_SIGN  5
+# define X509_TRUST_OCSP_SIGN    6
+# define X509_TRUST_OCSP_REQUEST 7
+# define X509_TRUST_TSA          8
+
+/* Keep these up to date! */
+# define X509_TRUST_MIN          1
+# define X509_TRUST_MAX          8
+
+/* trust_flags values */
+# define X509_TRUST_DYNAMIC      (1U << 0)
+# define X509_TRUST_DYNAMIC_NAME (1U << 1)
+/* No compat trust if self-signed, preempts "DO_SS" */
+# define X509_TRUST_NO_SS_COMPAT (1U << 2)
+/* Compat trust if no explicit accepted trust EKUs */
+# define X509_TRUST_DO_SS_COMPAT (1U << 3)
+/* Accept "anyEKU" as a wildcard trust OID */
+# define X509_TRUST_OK_ANY_EKU   (1U << 4)
+
+/* check_trust return codes */
+
+# define X509_TRUST_TRUSTED      1
+# define X509_TRUST_REJECTED     2
+# define X509_TRUST_UNTRUSTED    3
+
+/* Flags for X509_print_ex() */
+
+# define X509_FLAG_COMPAT                0
+# define X509_FLAG_NO_HEADER             1L
+# define X509_FLAG_NO_VERSION            (1L << 1)
+# define X509_FLAG_NO_SERIAL             (1L << 2)
+# define X509_FLAG_NO_SIGNAME            (1L << 3)
+# define X509_FLAG_NO_ISSUER             (1L << 4)
+# define X509_FLAG_NO_VALIDITY           (1L << 5)
+# define X509_FLAG_NO_SUBJECT            (1L << 6)
+# define X509_FLAG_NO_PUBKEY             (1L << 7)
+# define X509_FLAG_NO_EXTENSIONS         (1L << 8)
+# define X509_FLAG_NO_SIGDUMP            (1L << 9)
+# define X509_FLAG_NO_AUX                (1L << 10)
+# define X509_FLAG_NO_ATTRIBUTES         (1L << 11)
+# define X509_FLAG_NO_IDS                (1L << 12)
+
+/* Flags specific to X509_NAME_print_ex() */
+
+/* The field separator information */
+
+# define XN_FLAG_SEP_MASK        (0xf << 16)
+
+# define XN_FLAG_COMPAT          0/* Traditional; use old X509_NAME_print */
+# define XN_FLAG_SEP_COMMA_PLUS  (1 << 16)/* RFC2253 ,+ */
+# define XN_FLAG_SEP_CPLUS_SPC   (2 << 16)/* ,+ spaced: more readable */
+# define XN_FLAG_SEP_SPLUS_SPC   (3 << 16)/* ;+ spaced */
+# define XN_FLAG_SEP_MULTILINE   (4 << 16)/* One line per field */
+
+# define XN_FLAG_DN_REV          (1 << 20)/* Reverse DN order */
+
+/* How the field name is shown */
+
+# define XN_FLAG_FN_MASK         (0x3 << 21)
+
+# define XN_FLAG_FN_SN           0/* Object short name */
+# define XN_FLAG_FN_LN           (1 << 21)/* Object long name */
+# define XN_FLAG_FN_OID          (2 << 21)/* Always use OIDs */
+# define XN_FLAG_FN_NONE         (3 << 21)/* No field names */
+
+# define XN_FLAG_SPC_EQ          (1 << 23)/* Put spaces round '=' */
+
+/*
+ * This determines if we dump fields we don't recognise: RFC2253 requires
+ * this.
+ */
+
+# define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24)
+
+# define XN_FLAG_FN_ALIGN        (1 << 25)/* Align field names to 20
+                                           * characters */
+
+/* Complete set of RFC2253 flags */
+
+# define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \
+                        XN_FLAG_SEP_COMMA_PLUS | \
+                        XN_FLAG_DN_REV | \
+                        XN_FLAG_FN_SN | \
+                        XN_FLAG_DUMP_UNKNOWN_FIELDS)
+
+/* readable oneline form */
+
+# define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \
+                        ASN1_STRFLGS_ESC_QUOTE | \
+                        XN_FLAG_SEP_CPLUS_SPC | \
+                        XN_FLAG_SPC_EQ | \
+                        XN_FLAG_FN_SN)
+
+/* readable multiline form */
+
+# define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \
+                        ASN1_STRFLGS_ESC_MSB | \
+                        XN_FLAG_SEP_MULTILINE | \
+                        XN_FLAG_SPC_EQ | \
+                        XN_FLAG_FN_LN | \
+                        XN_FLAG_FN_ALIGN)
+
+DEFINE_STACK_OF(X509_REVOKED)
+
+typedef struct X509_crl_info_st X509_CRL_INFO;
+
+DEFINE_STACK_OF(X509_CRL)
+
+typedef struct private_key_st {
+    int version;
+    /* The PKCS#8 data types */
+    X509_ALGOR *enc_algor;
+    ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */
+    /* When decrypted, the following will not be NULL */
+    EVP_PKEY *dec_pkey;
+    /* used to encrypt and decrypt */
+    int key_length;
+    char *key_data;
+    int key_free;               /* true if we should auto free key_data */
+    /* expanded version of 'enc_algor' */
+    EVP_CIPHER_INFO cipher;
+} X509_PKEY;
+
+typedef struct X509_info_st {
+    X509 *x509;
+    X509_CRL *crl;
+    X509_PKEY *x_pkey;
+    EVP_CIPHER_INFO enc_cipher;
+    int enc_len;
+    char *enc_data;
+} X509_INFO;
+
+DEFINE_STACK_OF(X509_INFO)
+
+/*
+ * The next 2 structures and their 8 routines were sent to me by Pat Richard
+ * <patr@x509.com> and are used to manipulate Netscapes spki structures -
+ * useful if you are writing a CA web page
+ */
+typedef struct Netscape_spkac_st {
+    X509_PUBKEY *pubkey;
+    ASN1_IA5STRING *challenge;  /* challenge sent in atlas >= PR2 */
+} NETSCAPE_SPKAC;
+
+typedef struct Netscape_spki_st {
+    NETSCAPE_SPKAC *spkac;      /* signed public key and challenge */
+    X509_ALGOR sig_algor;
+    ASN1_BIT_STRING *signature;
+} NETSCAPE_SPKI;
+
+/* Netscape certificate sequence structure */
+typedef struct Netscape_certificate_sequence {
+    ASN1_OBJECT *type;
+    STACK_OF(X509) *certs;
+} NETSCAPE_CERT_SEQUENCE;
+
+/*- Unused (and iv length is wrong)
+typedef struct CBCParameter_st
+        {
+        unsigned char iv[8];
+        } CBC_PARAM;
+*/
+
+/* Password based encryption structure */
+
+typedef struct PBEPARAM_st {
+    ASN1_OCTET_STRING *salt;
+    ASN1_INTEGER *iter;
+} PBEPARAM;
+
+/* Password based encryption V2 structures */
+
+typedef struct PBE2PARAM_st {
+    X509_ALGOR *keyfunc;
+    X509_ALGOR *encryption;
+} PBE2PARAM;
+
+typedef struct PBKDF2PARAM_st {
+/* Usually OCTET STRING but could be anything */
+    ASN1_TYPE *salt;
+    ASN1_INTEGER *iter;
+    ASN1_INTEGER *keylength;
+    X509_ALGOR *prf;
+} PBKDF2PARAM;
+
+#ifdef  __cplusplus
+}
+#endif
+
+# include <openssl/x509_vfy.h>
+# include <openssl/pkcs7.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+# define X509_EXT_PACK_UNKNOWN   1
+# define X509_EXT_PACK_STRING    2
+
+# define         X509_extract_key(x)     X509_get_pubkey(x)/*****/
+# define         X509_REQ_extract_key(a) X509_REQ_get_pubkey(a)
+# define         X509_name_cmp(a,b)      X509_NAME_cmp((a),(b))
+
+void X509_CRL_set_default_method(const X509_CRL_METHOD *meth);
+X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl),
+                                     int (*crl_free) (X509_CRL *crl),
+                                     int (*crl_lookup) (X509_CRL *crl,
+                                                        X509_REVOKED **ret,
+                                                        ASN1_INTEGER *ser,
+                                                        X509_NAME *issuer),
+                                     int (*crl_verify) (X509_CRL *crl,
+                                                        EVP_PKEY *pk));
+void X509_CRL_METHOD_free(X509_CRL_METHOD *m);
+
+void X509_CRL_set_meth_data(X509_CRL *crl, void *dat);
+void *X509_CRL_get_meth_data(X509_CRL *crl);
+
+const char *X509_verify_cert_error_string(long n);
+
+int X509_verify(X509 *a, EVP_PKEY *r);
+
+int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r);
+int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r);
+int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r);
+
+NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len);
+char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x);
+EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x);
+int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
+
+int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);
+
+int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent);
+int X509_signature_print(BIO *bp, const X509_ALGOR *alg,
+                         const ASN1_STRING *sig);
+
+int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx);
+# ifndef OPENSSL_NO_OCSP
+int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert);
+# endif
+int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx);
+int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx);
+# ifndef OPENSSL_NO_OCSP
+int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl);
+# endif
+int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);
+
+int X509_pubkey_digest(const X509 *data, const EVP_MD *type,
+                       unsigned char *md, unsigned int *len);
+int X509_digest(const X509 *data, const EVP_MD *type,
+                unsigned char *md, unsigned int *len);
+int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type,
+                    unsigned char *md, unsigned int *len);
+int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type,
+                    unsigned char *md, unsigned int *len);
+int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type,
+                     unsigned char *md, unsigned int *len);
+
+# ifndef OPENSSL_NO_STDIO
+X509 *d2i_X509_fp(FILE *fp, X509 **x509);
+int i2d_X509_fp(FILE *fp, X509 *x509);
+X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl);
+int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl);
+X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req);
+int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req);
+#  ifndef OPENSSL_NO_RSA
+RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa);
+int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa);
+RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa);
+int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa);
+RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa);
+int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa);
+#  endif
+#  ifndef OPENSSL_NO_DSA
+DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa);
+int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa);
+DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa);
+int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa);
+#  endif
+#  ifndef OPENSSL_NO_EC
+EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey);
+int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey);
+EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey);
+int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey);
+#  endif
+X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8);
+int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8);
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
+                                                PKCS8_PRIV_KEY_INFO **p8inf);
+int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf);
+int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key);
+int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
+int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
+# endif
+
+X509 *d2i_X509_bio(BIO *bp, X509 **x509);
+int i2d_X509_bio(BIO *bp, X509 *x509);
+X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl);
+int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl);
+X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req);
+int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req);
+#  ifndef OPENSSL_NO_RSA
+RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa);
+int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa);
+RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa);
+int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa);
+RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa);
+int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa);
+#  endif
+#  ifndef OPENSSL_NO_DSA
+DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa);
+int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa);
+DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa);
+int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa);
+#  endif
+#  ifndef OPENSSL_NO_EC
+EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey);
+int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey);
+EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey);
+int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey);
+#  endif
+X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8);
+int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8);
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
+                                                 PKCS8_PRIV_KEY_INFO **p8inf);
+int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf);
+int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key);
+int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
+int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);
+
+X509 *X509_dup(X509 *x509);
+X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa);
+X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex);
+X509_CRL *X509_CRL_dup(X509_CRL *crl);
+X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *rev);
+X509_REQ *X509_REQ_dup(X509_REQ *req);
+X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
+int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype,
+                    void *pval);
+void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype,
+                     const void **ppval, const X509_ALGOR *algor);
+void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md);
+int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b);
+
+X509_NAME *X509_NAME_dup(X509_NAME *xn);
+X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
+
+int X509_cmp_time(const ASN1_TIME *s, time_t *t);
+int X509_cmp_current_time(const ASN1_TIME *s);
+ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *t);
+ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
+                            int offset_day, long offset_sec, time_t *t);
+ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj);
+
+const char *X509_get_default_cert_area(void);
+const char *X509_get_default_cert_dir(void);
+const char *X509_get_default_cert_file(void);
+const char *X509_get_default_cert_dir_env(void);
+const char *X509_get_default_cert_file_env(void);
+const char *X509_get_default_private_dir(void);
+
+X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
+X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey);
+
+DECLARE_ASN1_FUNCTIONS(X509_ALGOR)
+DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS)
+DECLARE_ASN1_FUNCTIONS(X509_VAL)
+
+DECLARE_ASN1_FUNCTIONS(X509_PUBKEY)
+
+int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey);
+EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key);
+EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key);
+int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain);
+long X509_get_pathlen(X509 *x);
+int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp);
+EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length);
+# ifndef OPENSSL_NO_RSA
+int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp);
+RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length);
+# endif
+# ifndef OPENSSL_NO_DSA
+int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp);
+DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length);
+# endif
+# ifndef OPENSSL_NO_EC
+int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp);
+EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length);
+# endif
+
+DECLARE_ASN1_FUNCTIONS(X509_SIG)
+void X509_SIG_get0(const X509_SIG *sig, const X509_ALGOR **palg,
+                   const ASN1_OCTET_STRING **pdigest);
+void X509_SIG_getm(X509_SIG *sig, X509_ALGOR **palg,
+                   ASN1_OCTET_STRING **pdigest);
+
+DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO)
+DECLARE_ASN1_FUNCTIONS(X509_REQ)
+
+DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE)
+X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value);
+
+DECLARE_ASN1_FUNCTIONS(X509_EXTENSION)
+DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS)
+
+DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY)
+
+DECLARE_ASN1_FUNCTIONS(X509_NAME)
+
+int X509_NAME_set(X509_NAME **xn, X509_NAME *name);
+
+DECLARE_ASN1_FUNCTIONS(X509_CINF)
+
+DECLARE_ASN1_FUNCTIONS(X509)
+DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX)
+
+#define X509_get_ex_new_index(l, p, newf, dupf, freef) \
+    CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509, l, p, newf, dupf, freef)
+int X509_set_ex_data(X509 *r, int idx, void *arg);
+void *X509_get_ex_data(X509 *r, int idx);
+int i2d_X509_AUX(X509 *a, unsigned char **pp);
+X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length);
+
+int i2d_re_X509_tbs(X509 *x, unsigned char **pp);
+
+void X509_get0_signature(const ASN1_BIT_STRING **psig,
+                         const X509_ALGOR **palg, const X509 *x);
+int X509_get_signature_nid(const X509 *x);
+
+int X509_trusted(const X509 *x);
+int X509_alias_set1(X509 *x, const unsigned char *name, int len);
+int X509_keyid_set1(X509 *x, const unsigned char *id, int len);
+unsigned char *X509_alias_get0(X509 *x, int *len);
+unsigned char *X509_keyid_get0(X509 *x, int *len);
+int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *,
+                                                                int);
+int X509_TRUST_set(int *t, int trust);
+int X509_add1_trust_object(X509 *x, const ASN1_OBJECT *obj);
+int X509_add1_reject_object(X509 *x, const ASN1_OBJECT *obj);
+void X509_trust_clear(X509 *x);
+void X509_reject_clear(X509 *x);
+
+STACK_OF(ASN1_OBJECT) *X509_get0_trust_objects(X509 *x);
+STACK_OF(ASN1_OBJECT) *X509_get0_reject_objects(X509 *x);
+
+DECLARE_ASN1_FUNCTIONS(X509_REVOKED)
+DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO)
+DECLARE_ASN1_FUNCTIONS(X509_CRL)
+
+int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
+int X509_CRL_get0_by_serial(X509_CRL *crl,
+                            X509_REVOKED **ret, ASN1_INTEGER *serial);
+int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x);
+
+X509_PKEY *X509_PKEY_new(void);
+void X509_PKEY_free(X509_PKEY *a);
+
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI)
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)
+
+X509_INFO *X509_INFO_new(void);
+void X509_INFO_free(X509_INFO *a);
+char *X509_NAME_oneline(const X509_NAME *a, char *buf, int size);
+
+int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1,
+                ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey);
+
+int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
+                unsigned char *md, unsigned int *len);
+
+int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1,
+              X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
+              char *data, EVP_PKEY *pkey, const EVP_MD *type);
+
+int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *data,
+                     unsigned char *md, unsigned int *len);
+
+int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1,
+                     ASN1_BIT_STRING *signature, void *data, EVP_PKEY *pkey);
+
+int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
+                   X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *data,
+                   EVP_PKEY *pkey, const EVP_MD *type);
+int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
+                       X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
+                       void *asn, EVP_MD_CTX *ctx);
+
+long X509_get_version(const X509 *x);
+int X509_set_version(X509 *x, long version);
+int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial);
+ASN1_INTEGER *X509_get_serialNumber(X509 *x);
+const ASN1_INTEGER *X509_get0_serialNumber(const X509 *x);
+int X509_set_issuer_name(X509 *x, X509_NAME *name);
+X509_NAME *X509_get_issuer_name(const X509 *a);
+int X509_set_subject_name(X509 *x, X509_NAME *name);
+X509_NAME *X509_get_subject_name(const X509 *a);
+const ASN1_TIME * X509_get0_notBefore(const X509 *x);
+ASN1_TIME *X509_getm_notBefore(const X509 *x);
+int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm);
+const ASN1_TIME *X509_get0_notAfter(const X509 *x);
+ASN1_TIME *X509_getm_notAfter(const X509 *x);
+int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm);
+int X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
+int X509_up_ref(X509 *x);
+int X509_get_signature_type(const X509 *x);
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  define X509_get_notBefore X509_getm_notBefore
+#  define X509_get_notAfter X509_getm_notAfter
+#  define X509_set_notBefore X509_set1_notBefore
+#  define X509_set_notAfter X509_set1_notAfter
+#endif
+
+
+/*
+ * This one is only used so that a binary form can output, as in
+ * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf)
+ */
+X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x);
+const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x);
+void X509_get0_uids(const X509 *x, const ASN1_BIT_STRING **piuid,
+                    const ASN1_BIT_STRING **psuid);
+const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x);
+
+EVP_PKEY *X509_get0_pubkey(const X509 *x);
+EVP_PKEY *X509_get_pubkey(X509 *x);
+ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x);
+int X509_certificate_type(const X509 *x, const EVP_PKEY *pubkey);
+
+long X509_REQ_get_version(const X509_REQ *req);
+int X509_REQ_set_version(X509_REQ *x, long version);
+X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req);
+int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name);
+void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig,
+                             const X509_ALGOR **palg);
+int X509_REQ_get_signature_nid(const X509_REQ *req);
+int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp);
+int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
+EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req);
+EVP_PKEY *X509_REQ_get0_pubkey(X509_REQ *req);
+X509_PUBKEY *X509_REQ_get_X509_PUBKEY(X509_REQ *req);
+int X509_REQ_extension_nid(int nid);
+int *X509_REQ_get_extension_nids(void);
+void X509_REQ_set_extension_nids(int *nids);
+STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req);
+int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
+                                int nid);
+int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts);
+int X509_REQ_get_attr_count(const X509_REQ *req);
+int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos);
+int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, const ASN1_OBJECT *obj,
+                             int lastpos);
+X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc);
+X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc);
+int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr);
+int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
+                              const ASN1_OBJECT *obj, int type,
+                              const unsigned char *bytes, int len);
+int X509_REQ_add1_attr_by_NID(X509_REQ *req,
+                              int nid, int type,
+                              const unsigned char *bytes, int len);
+int X509_REQ_add1_attr_by_txt(X509_REQ *req,
+                              const char *attrname, int type,
+                              const unsigned char *bytes, int len);
+
+int X509_CRL_set_version(X509_CRL *x, long version);
+int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
+int X509_CRL_set1_lastUpdate(X509_CRL *x, const ASN1_TIME *tm);
+int X509_CRL_set1_nextUpdate(X509_CRL *x, const ASN1_TIME *tm);
+int X509_CRL_sort(X509_CRL *crl);
+int X509_CRL_up_ref(X509_CRL *crl);
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  define X509_CRL_set_lastUpdate X509_CRL_set1_lastUpdate
+#  define X509_CRL_set_nextUpdate X509_CRL_set1_nextUpdate
+#endif
+
+long X509_CRL_get_version(const X509_CRL *crl);
+const ASN1_TIME *X509_CRL_get0_lastUpdate(const X509_CRL *crl);
+const ASN1_TIME *X509_CRL_get0_nextUpdate(const X509_CRL *crl);
+DEPRECATEDIN_1_1_0(ASN1_TIME *X509_CRL_get_lastUpdate(X509_CRL *crl))
+DEPRECATEDIN_1_1_0(ASN1_TIME *X509_CRL_get_nextUpdate(X509_CRL *crl))
+X509_NAME *X509_CRL_get_issuer(const X509_CRL *crl);
+const STACK_OF(X509_EXTENSION) *X509_CRL_get0_extensions(const X509_CRL *crl);
+STACK_OF(X509_REVOKED) *X509_CRL_get_REVOKED(X509_CRL *crl);
+void X509_CRL_get0_signature(const X509_CRL *crl, const ASN1_BIT_STRING **psig,
+                             const X509_ALGOR **palg);
+int X509_CRL_get_signature_nid(const X509_CRL *crl);
+int i2d_re_X509_CRL_tbs(X509_CRL *req, unsigned char **pp);
+
+const ASN1_INTEGER *X509_REVOKED_get0_serialNumber(const X509_REVOKED *x);
+int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
+const ASN1_TIME *X509_REVOKED_get0_revocationDate(const X509_REVOKED *x);
+int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm);
+const STACK_OF(X509_EXTENSION) *
+X509_REVOKED_get0_extensions(const X509_REVOKED *r);
+
+X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
+                        EVP_PKEY *skey, const EVP_MD *md, unsigned int flags);
+
+int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey);
+
+int X509_check_private_key(const X509 *x509, const EVP_PKEY *pkey);
+int X509_chain_check_suiteb(int *perror_depth,
+                            X509 *x, STACK_OF(X509) *chain,
+                            unsigned long flags);
+int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags);
+STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain);
+
+int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b);
+unsigned long X509_issuer_and_serial_hash(X509 *a);
+
+int X509_issuer_name_cmp(const X509 *a, const X509 *b);
+unsigned long X509_issuer_name_hash(X509 *a);
+
+int X509_subject_name_cmp(const X509 *a, const X509 *b);
+unsigned long X509_subject_name_hash(X509 *x);
+
+# ifndef OPENSSL_NO_MD5
+unsigned long X509_issuer_name_hash_old(X509 *a);
+unsigned long X509_subject_name_hash_old(X509 *x);
+# endif
+
+int X509_cmp(const X509 *a, const X509 *b);
+int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
+unsigned long X509_NAME_hash(X509_NAME *x);
+unsigned long X509_NAME_hash_old(X509_NAME *x);
+
+int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
+int X509_CRL_match(const X509_CRL *a, const X509_CRL *b);
+int X509_aux_print(BIO *out, X509 *x, int indent);
+# ifndef OPENSSL_NO_STDIO
+int X509_print_ex_fp(FILE *bp, X509 *x, unsigned long nmflag,
+                     unsigned long cflag);
+int X509_print_fp(FILE *bp, X509 *x);
+int X509_CRL_print_fp(FILE *bp, X509_CRL *x);
+int X509_REQ_print_fp(FILE *bp, X509_REQ *req);
+int X509_NAME_print_ex_fp(FILE *fp, const X509_NAME *nm, int indent,
+                          unsigned long flags);
+# endif
+
+int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase);
+int X509_NAME_print_ex(BIO *out, const X509_NAME *nm, int indent,
+                       unsigned long flags);
+int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflag,
+                  unsigned long cflag);
+int X509_print(BIO *bp, X509 *x);
+int X509_ocspid_print(BIO *bp, X509 *x);
+int X509_CRL_print(BIO *bp, X509_CRL *x);
+int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag,
+                      unsigned long cflag);
+int X509_REQ_print(BIO *bp, X509_REQ *req);
+
+int X509_NAME_entry_count(const X509_NAME *name);
+int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len);
+int X509_NAME_get_text_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj,
+                              char *buf, int len);
+
+/*
+ * NOTE: you should be passing -1, not 0 as lastpos. The functions that use
+ * lastpos, search after that position on.
+ */
+int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos);
+int X509_NAME_get_index_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj,
+                               int lastpos);
+X509_NAME_ENTRY *X509_NAME_get_entry(const X509_NAME *name, int loc);
+X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
+int X509_NAME_add_entry(X509_NAME *name, const X509_NAME_ENTRY *ne,
+                        int loc, int set);
+int X509_NAME_add_entry_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, int type,
+                               const unsigned char *bytes, int len, int loc,
+                               int set);
+int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
+                               const unsigned char *bytes, int len, int loc,
+                               int set);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
+                                               const char *field, int type,
+                                               const unsigned char *bytes,
+                                               int len);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
+                                               int type, 
+                                               const unsigned char *bytes,
+                                               int len);
+int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
+                               const unsigned char *bytes, int len, int loc,
+                               int set);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
+                                               const ASN1_OBJECT *obj, int type,
+                                               const unsigned char *bytes,
+                                               int len);
+int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj);
+int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
+                             const unsigned char *bytes, int len);
+ASN1_OBJECT *X509_NAME_ENTRY_get_object(const X509_NAME_ENTRY *ne);
+ASN1_STRING * X509_NAME_ENTRY_get_data(const X509_NAME_ENTRY *ne);
+int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne);
+
+int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder,
+                       size_t *pderlen);
+
+int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x);
+int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x,
+                          int nid, int lastpos);
+int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x,
+                          const ASN1_OBJECT *obj, int lastpos);
+int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x,
+                               int crit, int lastpos);
+X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc);
+X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc);
+STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
+                                         X509_EXTENSION *ex, int loc);
+
+int X509_get_ext_count(const X509 *x);
+int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos);
+int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, int lastpos);
+int X509_get_ext_by_critical(const X509 *x, int crit, int lastpos);
+X509_EXTENSION *X509_get_ext(const X509 *x, int loc);
+X509_EXTENSION *X509_delete_ext(X509 *x, int loc);
+int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
+void *X509_get_ext_d2i(const X509 *x, int nid, int *crit, int *idx);
+int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
+                      unsigned long flags);
+
+int X509_CRL_get_ext_count(const X509_CRL *x);
+int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos);
+int X509_CRL_get_ext_by_OBJ(const X509_CRL *x, const ASN1_OBJECT *obj,
+                            int lastpos);
+int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, int lastpos);
+X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc);
+X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc);
+int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc);
+void *X509_CRL_get_ext_d2i(const X509_CRL *x, int nid, int *crit, int *idx);
+int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
+                          unsigned long flags);
+
+int X509_REVOKED_get_ext_count(const X509_REVOKED *x);
+int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, int lastpos);
+int X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, const ASN1_OBJECT *obj,
+                                int lastpos);
+int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, int crit,
+                                     int lastpos);
+X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, int loc);
+X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc);
+int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc);
+void *X509_REVOKED_get_ext_d2i(const X509_REVOKED *x, int nid, int *crit,
+                               int *idx);
+int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
+                              unsigned long flags);
+
+X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
+                                             int nid, int crit,
+                                             ASN1_OCTET_STRING *data);
+X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
+                                             const ASN1_OBJECT *obj, int crit,
+                                             ASN1_OCTET_STRING *data);
+int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj);
+int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit);
+int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data);
+ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex);
+ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne);
+int X509_EXTENSION_get_critical(const X509_EXTENSION *ex);
+
+int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x);
+int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
+                           int lastpos);
+int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk,
+                           const ASN1_OBJECT *obj, int lastpos);
+X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc);
+X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
+                                           X509_ATTRIBUTE *attr);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE)
+                                                  **x, const ASN1_OBJECT *obj,
+                                                  int type,
+                                                  const unsigned char *bytes,
+                                                  int len);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE)
+                                                  **x, int nid, int type,
+                                                  const unsigned char *bytes,
+                                                  int len);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE)
+                                                  **x, const char *attrname,
+                                                  int type,
+                                                  const unsigned char *bytes,
+                                                  int len);
+void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x,
+                              const ASN1_OBJECT *obj, int lastpos, int type);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
+                                             int atrtype, const void *data,
+                                             int len);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
+                                             const ASN1_OBJECT *obj,
+                                             int atrtype, const void *data,
+                                             int len);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
+                                             const char *atrname, int type,
+                                             const unsigned char *bytes,
+                                             int len);
+int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj);
+int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
+                             const void *data, int len);
+void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype,
+                               void *data);
+int X509_ATTRIBUTE_count(const X509_ATTRIBUTE *attr);
+ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr);
+ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx);
+
+int EVP_PKEY_get_attr_count(const EVP_PKEY *key);
+int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos);
+int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, const ASN1_OBJECT *obj,
+                             int lastpos);
+X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc);
+X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc);
+int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr);
+int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
+                              const ASN1_OBJECT *obj, int type,
+                              const unsigned char *bytes, int len);
+int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
+                              int nid, int type,
+                              const unsigned char *bytes, int len);
+int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
+                              const char *attrname, int type,
+                              const unsigned char *bytes, int len);
+
+int X509_verify_cert(X509_STORE_CTX *ctx);
+
+/* lookup a cert from a X509 STACK */
+X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
+                                     ASN1_INTEGER *serial);
+X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name);
+
+DECLARE_ASN1_FUNCTIONS(PBEPARAM)
+DECLARE_ASN1_FUNCTIONS(PBE2PARAM)
+DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM)
+
+int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
+                         const unsigned char *salt, int saltlen);
+
+X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
+                          const unsigned char *salt, int saltlen);
+X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
+                           unsigned char *salt, int saltlen);
+X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
+                              unsigned char *salt, int saltlen,
+                              unsigned char *aiv, int prf_nid);
+
+#ifndef OPENSSL_NO_SCRYPT
+X509_ALGOR *PKCS5_pbe2_set_scrypt(const EVP_CIPHER *cipher,
+                                  const unsigned char *salt, int saltlen,
+                                  unsigned char *aiv, uint64_t N, uint64_t r,
+                                  uint64_t p);
+#endif
+
+X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
+                             int prf_nid, int keylen);
+
+/* PKCS#8 utilities */
+
+DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
+
+EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8);
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey);
+
+int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
+                    int version, int ptype, void *pval,
+                    unsigned char *penc, int penclen);
+int PKCS8_pkey_get0(const ASN1_OBJECT **ppkalg,
+                    const unsigned char **pk, int *ppklen,
+                    const X509_ALGOR **pa, const PKCS8_PRIV_KEY_INFO *p8);
+
+const STACK_OF(X509_ATTRIBUTE) *
+PKCS8_pkey_get0_attrs(const PKCS8_PRIV_KEY_INFO *p8);
+int PKCS8_pkey_add1_attr_by_NID(PKCS8_PRIV_KEY_INFO *p8, int nid, int type,
+                                const unsigned char *bytes, int len);
+
+int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
+                           int ptype, void *pval,
+                           unsigned char *penc, int penclen);
+int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
+                           const unsigned char **pk, int *ppklen,
+                           X509_ALGOR **pa, X509_PUBKEY *pub);
+
+int X509_check_trust(X509 *x, int id, int flags);
+int X509_TRUST_get_count(void);
+X509_TRUST *X509_TRUST_get0(int idx);
+int X509_TRUST_get_by_id(int id);
+int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int),
+                   const char *name, int arg1, void *arg2);
+void X509_TRUST_cleanup(void);
+int X509_TRUST_get_flags(const X509_TRUST *xp);
+char *X509_TRUST_get0_name(const X509_TRUST *xp);
+int X509_TRUST_get_trust(const X509_TRUST *xp);
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_X509_strings(void);
+
+/* Error codes for the X509 functions. */
+
+/* Function codes. */
+# define X509_F_ADD_CERT_DIR                              100
+# define X509_F_BUILD_CHAIN                               106
+# define X509_F_BY_FILE_CTRL                              101
+# define X509_F_CHECK_NAME_CONSTRAINTS                    149
+# define X509_F_CHECK_POLICY                              145
+# define X509_F_DANE_I2D                                  107
+# define X509_F_DIR_CTRL                                  102
+# define X509_F_GET_CERT_BY_SUBJECT                       103
+# define X509_F_NETSCAPE_SPKI_B64_DECODE                  129
+# define X509_F_NETSCAPE_SPKI_B64_ENCODE                  130
+# define X509_F_X509AT_ADD1_ATTR                          135
+# define X509_F_X509V3_ADD_EXT                            104
+# define X509_F_X509_ATTRIBUTE_CREATE_BY_NID              136
+# define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ              137
+# define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT              140
+# define X509_F_X509_ATTRIBUTE_GET0_DATA                  139
+# define X509_F_X509_ATTRIBUTE_SET1_DATA                  138
+# define X509_F_X509_CHECK_PRIVATE_KEY                    128
+# define X509_F_X509_CRL_DIFF                             105
+# define X509_F_X509_CRL_PRINT_FP                         147
+# define X509_F_X509_EXTENSION_CREATE_BY_NID              108
+# define X509_F_X509_EXTENSION_CREATE_BY_OBJ              109
+# define X509_F_X509_GET_PUBKEY_PARAMETERS                110
+# define X509_F_X509_LOAD_CERT_CRL_FILE                   132
+# define X509_F_X509_LOAD_CERT_FILE                       111
+# define X509_F_X509_LOAD_CRL_FILE                        112
+# define X509_F_X509_NAME_ADD_ENTRY                       113
+# define X509_F_X509_NAME_ENTRY_CREATE_BY_NID             114
+# define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT             131
+# define X509_F_X509_NAME_ENTRY_SET_OBJECT                115
+# define X509_F_X509_NAME_ONELINE                         116
+# define X509_F_X509_NAME_PRINT                           117
+# define X509_F_X509_OBJECT_NEW                           150
+# define X509_F_X509_PRINT_EX_FP                          118
+# define X509_F_X509_PUBKEY_DECODE                        148
+# define X509_F_X509_PUBKEY_GET0                          119
+# define X509_F_X509_PUBKEY_SET                           120
+# define X509_F_X509_REQ_CHECK_PRIVATE_KEY                144
+# define X509_F_X509_REQ_PRINT_EX                         121
+# define X509_F_X509_REQ_PRINT_FP                         122
+# define X509_F_X509_REQ_TO_X509                          123
+# define X509_F_X509_STORE_ADD_CERT                       124
+# define X509_F_X509_STORE_ADD_CRL                        125
+# define X509_F_X509_STORE_CTX_GET1_ISSUER                146
+# define X509_F_X509_STORE_CTX_INIT                       143
+# define X509_F_X509_STORE_CTX_NEW                        142
+# define X509_F_X509_STORE_CTX_PURPOSE_INHERIT            134
+# define X509_F_X509_TO_X509_REQ                          126
+# define X509_F_X509_TRUST_ADD                            133
+# define X509_F_X509_TRUST_SET                            141
+# define X509_F_X509_VERIFY_CERT                          127
+
+/* Reason codes. */
+# define X509_R_AKID_MISMATCH                             110
+# define X509_R_BAD_SELECTOR                              133
+# define X509_R_BAD_X509_FILETYPE                         100
+# define X509_R_BASE64_DECODE_ERROR                       118
+# define X509_R_CANT_CHECK_DH_KEY                         114
+# define X509_R_CERT_ALREADY_IN_HASH_TABLE                101
+# define X509_R_CRL_ALREADY_DELTA                         127
+# define X509_R_CRL_VERIFY_FAILURE                        131
+# define X509_R_IDP_MISMATCH                              128
+# define X509_R_INVALID_DIRECTORY                         113
+# define X509_R_INVALID_FIELD_NAME                        119
+# define X509_R_INVALID_TRUST                             123
+# define X509_R_ISSUER_MISMATCH                           129
+# define X509_R_KEY_TYPE_MISMATCH                         115
+# define X509_R_KEY_VALUES_MISMATCH                       116
+# define X509_R_LOADING_CERT_DIR                          103
+# define X509_R_LOADING_DEFAULTS                          104
+# define X509_R_METHOD_NOT_SUPPORTED                      124
+# define X509_R_NAME_TOO_LONG                             134
+# define X509_R_NEWER_CRL_NOT_NEWER                       132
+# define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY              105
+# define X509_R_NO_CRL_NUMBER                             130
+# define X509_R_PUBLIC_KEY_DECODE_ERROR                   125
+# define X509_R_PUBLIC_KEY_ENCODE_ERROR                   126
+# define X509_R_SHOULD_RETRY                              106
+# define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN        107
+# define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY            108
+# define X509_R_UNKNOWN_KEY_TYPE                          117
+# define X509_R_UNKNOWN_NID                               109
+# define X509_R_UNKNOWN_PURPOSE_ID                        121
+# define X509_R_UNKNOWN_TRUST_ID                          120
+# define X509_R_UNSUPPORTED_ALGORITHM                     111
+# define X509_R_WRONG_LOOKUP_TYPE                         112
+# define X509_R_WRONG_TYPE                                122
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/x509_vfy.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/x509_vfy.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/x509_vfy.h	(revision 331)
@@ -0,0 +1,545 @@
+/*
+ * Copyright 1995-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
+ */
+
+#ifndef HEADER_X509_VFY_H
+# define HEADER_X509_VFY_H
+
+/*
+ * Protect against recursion, x509.h and x509_vfy.h each include the other.
+ */
+# ifndef HEADER_X509_H
+#  include <openssl/x509.h>
+# endif
+
+# include <openssl/opensslconf.h>
+# include <openssl/lhash.h>
+# include <openssl/bio.h>
+# include <openssl/crypto.h>
+# include <openssl/symhacks.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*-
+SSL_CTX -> X509_STORE
+                -> X509_LOOKUP
+                        ->X509_LOOKUP_METHOD
+                -> X509_LOOKUP
+                        ->X509_LOOKUP_METHOD
+
+SSL     -> X509_STORE_CTX
+                ->X509_STORE
+
+The X509_STORE holds the tables etc for verification stuff.
+A X509_STORE_CTX is used while validating a single certificate.
+The X509_STORE has X509_LOOKUPs for looking up certs.
+The X509_STORE then calls a function to actually verify the
+certificate chain.
+*/
+
+typedef enum {
+    X509_LU_NONE = 0,
+    X509_LU_X509, X509_LU_CRL
+} X509_LOOKUP_TYPE;
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+#define X509_LU_RETRY   -1
+#define X509_LU_FAIL    0
+#endif
+
+DEFINE_STACK_OF(X509_LOOKUP)
+DEFINE_STACK_OF(X509_OBJECT)
+DEFINE_STACK_OF(X509_VERIFY_PARAM)
+
+int X509_STORE_set_depth(X509_STORE *store, int depth);
+
+typedef int (*X509_STORE_CTX_verify_cb)(int, X509_STORE_CTX *);
+typedef int (*X509_STORE_CTX_verify_fn)(X509_STORE_CTX *);
+typedef int (*X509_STORE_CTX_get_issuer_fn)(X509 **issuer,
+                                            X509_STORE_CTX *ctx, X509 *x);
+typedef int (*X509_STORE_CTX_check_issued_fn)(X509_STORE_CTX *ctx,
+                                              X509 *x, X509 *issuer);
+typedef int (*X509_STORE_CTX_check_revocation_fn)(X509_STORE_CTX *ctx);
+typedef int (*X509_STORE_CTX_get_crl_fn)(X509_STORE_CTX *ctx,
+                                         X509_CRL **crl, X509 *x);
+typedef int (*X509_STORE_CTX_check_crl_fn)(X509_STORE_CTX *ctx, X509_CRL *crl);
+typedef int (*X509_STORE_CTX_cert_crl_fn)(X509_STORE_CTX *ctx,
+                                          X509_CRL *crl, X509 *x);
+typedef int (*X509_STORE_CTX_check_policy_fn)(X509_STORE_CTX *ctx);
+typedef STACK_OF(X509) *(*X509_STORE_CTX_lookup_certs_fn)(X509_STORE_CTX *ctx,
+                                                          X509_NAME *nm);
+typedef STACK_OF(X509_CRL) *(*X509_STORE_CTX_lookup_crls_fn)(X509_STORE_CTX *ctx,
+                                                             X509_NAME *nm);
+typedef int (*X509_STORE_CTX_cleanup_fn)(X509_STORE_CTX *ctx);
+
+
+void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
+
+# define X509_STORE_CTX_set_app_data(ctx,data) \
+        X509_STORE_CTX_set_ex_data(ctx,0,data)
+# define X509_STORE_CTX_get_app_data(ctx) \
+        X509_STORE_CTX_get_ex_data(ctx,0)
+
+# define X509_L_FILE_LOAD        1
+# define X509_L_ADD_DIR          2
+
+# define X509_LOOKUP_load_file(x,name,type) \
+                X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL)
+
+# define X509_LOOKUP_add_dir(x,name,type) \
+                X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL)
+
+# define         X509_V_OK                                       0
+# define         X509_V_ERR_UNSPECIFIED                          1
+# define         X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT            2
+# define         X509_V_ERR_UNABLE_TO_GET_CRL                    3
+# define         X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE     4
+# define         X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE      5
+# define         X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY   6
+# define         X509_V_ERR_CERT_SIGNATURE_FAILURE               7
+# define         X509_V_ERR_CRL_SIGNATURE_FAILURE                8
+# define         X509_V_ERR_CERT_NOT_YET_VALID                   9
+# define         X509_V_ERR_CERT_HAS_EXPIRED                     10
+# define         X509_V_ERR_CRL_NOT_YET_VALID                    11
+# define         X509_V_ERR_CRL_HAS_EXPIRED                      12
+# define         X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD       13
+# define         X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD        14
+# define         X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD       15
+# define         X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD       16
+# define         X509_V_ERR_OUT_OF_MEM                           17
+# define         X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT          18
+# define         X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN            19
+# define         X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY    20
+# define         X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE      21
+# define         X509_V_ERR_CERT_CHAIN_TOO_LONG                  22
+# define         X509_V_ERR_CERT_REVOKED                         23
+# define         X509_V_ERR_INVALID_CA                           24
+# define         X509_V_ERR_PATH_LENGTH_EXCEEDED                 25
+# define         X509_V_ERR_INVALID_PURPOSE                      26
+# define         X509_V_ERR_CERT_UNTRUSTED                       27
+# define         X509_V_ERR_CERT_REJECTED                        28
+/* These are 'informational' when looking for issuer cert */
+# define         X509_V_ERR_SUBJECT_ISSUER_MISMATCH              29
+# define         X509_V_ERR_AKID_SKID_MISMATCH                   30
+# define         X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH          31
+# define         X509_V_ERR_KEYUSAGE_NO_CERTSIGN                 32
+# define         X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER             33
+# define         X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION         34
+# define         X509_V_ERR_KEYUSAGE_NO_CRL_SIGN                 35
+# define         X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION     36
+# define         X509_V_ERR_INVALID_NON_CA                       37
+# define         X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED           38
+# define         X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE        39
+# define         X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED       40
+# define         X509_V_ERR_INVALID_EXTENSION                    41
+# define         X509_V_ERR_INVALID_POLICY_EXTENSION             42
+# define         X509_V_ERR_NO_EXPLICIT_POLICY                   43
+# define         X509_V_ERR_DIFFERENT_CRL_SCOPE                  44
+# define         X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE        45
+# define         X509_V_ERR_UNNESTED_RESOURCE                    46
+# define         X509_V_ERR_PERMITTED_VIOLATION                  47
+# define         X509_V_ERR_EXCLUDED_VIOLATION                   48
+# define         X509_V_ERR_SUBTREE_MINMAX                       49
+/* The application is not happy */
+# define         X509_V_ERR_APPLICATION_VERIFICATION             50
+# define         X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE          51
+# define         X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX        52
+# define         X509_V_ERR_UNSUPPORTED_NAME_SYNTAX              53
+# define         X509_V_ERR_CRL_PATH_VALIDATION_ERROR            54
+/* Another issuer check debug option */
+# define         X509_V_ERR_PATH_LOOP                            55
+/* Suite B mode algorithm violation */
+# define         X509_V_ERR_SUITE_B_INVALID_VERSION              56
+# define         X509_V_ERR_SUITE_B_INVALID_ALGORITHM            57
+# define         X509_V_ERR_SUITE_B_INVALID_CURVE                58
+# define         X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM  59
+# define         X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED              60
+# define         X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61
+/* Host, email and IP check errors */
+# define         X509_V_ERR_HOSTNAME_MISMATCH                    62
+# define         X509_V_ERR_EMAIL_MISMATCH                       63
+# define         X509_V_ERR_IP_ADDRESS_MISMATCH                  64
+/* DANE TLSA errors */
+# define         X509_V_ERR_DANE_NO_MATCH                        65
+/* security level errors */
+# define         X509_V_ERR_EE_KEY_TOO_SMALL                     66
+# define         X509_V_ERR_CA_KEY_TOO_SMALL                     67
+# define         X509_V_ERR_CA_MD_TOO_WEAK                       68
+/* Caller error */
+# define         X509_V_ERR_INVALID_CALL                         69
+/* Issuer lookup error */
+# define         X509_V_ERR_STORE_LOOKUP                         70
+/* Certificate transparency */
+# define         X509_V_ERR_NO_VALID_SCTS                        71
+
+# define         X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION         72
+
+/* Certificate verify flags */
+
+# if OPENSSL_API_COMPAT < 0x10100000L
+#  define X509_V_FLAG_CB_ISSUER_CHECK             0x0   /* Deprecated */
+# endif
+/* Use check time instead of current time */
+# define X509_V_FLAG_USE_CHECK_TIME              0x2
+/* Lookup CRLs */
+# define X509_V_FLAG_CRL_CHECK                   0x4
+/* Lookup CRLs for whole chain */
+# define X509_V_FLAG_CRL_CHECK_ALL               0x8
+/* Ignore unhandled critical extensions */
+# define X509_V_FLAG_IGNORE_CRITICAL             0x10
+/* Disable workarounds for broken certificates */
+# define X509_V_FLAG_X509_STRICT                 0x20
+/* Enable proxy certificate validation */
+# define X509_V_FLAG_ALLOW_PROXY_CERTS           0x40
+/* Enable policy checking */
+# define X509_V_FLAG_POLICY_CHECK                0x80
+/* Policy variable require-explicit-policy */
+# define X509_V_FLAG_EXPLICIT_POLICY             0x100
+/* Policy variable inhibit-any-policy */
+# define X509_V_FLAG_INHIBIT_ANY                 0x200
+/* Policy variable inhibit-policy-mapping */
+# define X509_V_FLAG_INHIBIT_MAP                 0x400
+/* Notify callback that policy is OK */
+# define X509_V_FLAG_NOTIFY_POLICY               0x800
+/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */
+# define X509_V_FLAG_EXTENDED_CRL_SUPPORT        0x1000
+/* Delta CRL support */
+# define X509_V_FLAG_USE_DELTAS                  0x2000
+/* Check self-signed CA signature */
+# define X509_V_FLAG_CHECK_SS_SIGNATURE          0x4000
+/* Use trusted store first */
+# define X509_V_FLAG_TRUSTED_FIRST               0x8000
+/* Suite B 128 bit only mode: not normally used */
+# define X509_V_FLAG_SUITEB_128_LOS_ONLY         0x10000
+/* Suite B 192 bit only mode */
+# define X509_V_FLAG_SUITEB_192_LOS              0x20000
+/* Suite B 128 bit mode allowing 192 bit algorithms */
+# define X509_V_FLAG_SUITEB_128_LOS              0x30000
+/* Allow partial chains if at least one certificate is in trusted store */
+# define X509_V_FLAG_PARTIAL_CHAIN               0x80000
+/*
+ * If the initial chain is not trusted, do not attempt to build an alternative
+ * chain. Alternate chain checking was introduced in 1.1.0. Setting this flag
+ * will force the behaviour to match that of previous versions.
+ */
+# define X509_V_FLAG_NO_ALT_CHAINS               0x100000
+/* Do not check certificate/CRL validity against current time */
+# define X509_V_FLAG_NO_CHECK_TIME               0x200000
+
+# define X509_VP_FLAG_DEFAULT                    0x1
+# define X509_VP_FLAG_OVERWRITE                  0x2
+# define X509_VP_FLAG_RESET_FLAGS                0x4
+# define X509_VP_FLAG_LOCKED                     0x8
+# define X509_VP_FLAG_ONCE                       0x10
+
+/* Internal use: mask of policy related options */
+# define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \
+                                | X509_V_FLAG_EXPLICIT_POLICY \
+                                | X509_V_FLAG_INHIBIT_ANY \
+                                | X509_V_FLAG_INHIBIT_MAP)
+
+int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, X509_LOOKUP_TYPE type,
+                               X509_NAME *name);
+X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
+                                             X509_LOOKUP_TYPE type,
+                                             X509_NAME *name);
+X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
+                                        X509_OBJECT *x);
+int X509_OBJECT_up_ref_count(X509_OBJECT *a);
+X509_OBJECT *X509_OBJECT_new(void);
+void X509_OBJECT_free(X509_OBJECT *a);
+X509_LOOKUP_TYPE X509_OBJECT_get_type(const X509_OBJECT *a);
+X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a);
+X509_CRL *X509_OBJECT_get0_X509_CRL(X509_OBJECT *a);
+X509_STORE *X509_STORE_new(void);
+void X509_STORE_free(X509_STORE *v);
+int X509_STORE_lock(X509_STORE *ctx);
+int X509_STORE_unlock(X509_STORE *ctx);
+int X509_STORE_up_ref(X509_STORE *v);
+STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *v);
+
+STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *st, X509_NAME *nm);
+STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *st, X509_NAME *nm);
+int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags);
+int X509_STORE_set_purpose(X509_STORE *ctx, int purpose);
+int X509_STORE_set_trust(X509_STORE *ctx, int trust);
+int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm);
+X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx);
+int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags);
+
+void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify);
+#define X509_STORE_set_verify_func(ctx, func) \
+            X509_STORE_set_verify((ctx),(func))
+void X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx,
+                               X509_STORE_CTX_verify_fn verify);
+X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx);
+void X509_STORE_set_verify_cb(X509_STORE *ctx,
+                              X509_STORE_CTX_verify_cb verify_cb);
+# define X509_STORE_set_verify_cb_func(ctx,func) \
+            X509_STORE_set_verify_cb((ctx),(func))
+X509_STORE_CTX_verify_cb X509_STORE_get_verify_cb(X509_STORE *ctx);
+void X509_STORE_set_get_issuer(X509_STORE *ctx,
+                               X509_STORE_CTX_get_issuer_fn get_issuer);
+X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(X509_STORE *ctx);
+void X509_STORE_set_check_issued(X509_STORE *ctx,
+                                 X509_STORE_CTX_check_issued_fn check_issued);
+X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(X509_STORE *ctx);
+void X509_STORE_set_check_revocation(X509_STORE *ctx,
+                                     X509_STORE_CTX_check_revocation_fn check_revocation);
+X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation(X509_STORE *ctx);
+void X509_STORE_set_get_crl(X509_STORE *ctx,
+                            X509_STORE_CTX_get_crl_fn get_crl);
+X509_STORE_CTX_get_crl_fn X509_STORE_get_get_crl(X509_STORE *ctx);
+void X509_STORE_set_check_crl(X509_STORE *ctx,
+                              X509_STORE_CTX_check_crl_fn check_crl);
+X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(X509_STORE *ctx);
+void X509_STORE_set_cert_crl(X509_STORE *ctx,
+                             X509_STORE_CTX_cert_crl_fn cert_crl);
+X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(X509_STORE *ctx);
+void X509_STORE_set_check_policy(X509_STORE *ctx,
+                                 X509_STORE_CTX_check_policy_fn check_policy);
+X509_STORE_CTX_check_policy_fn X509_STORE_get_check_policy(X509_STORE *ctx);
+void X509_STORE_set_lookup_certs(X509_STORE *ctx,
+                                 X509_STORE_CTX_lookup_certs_fn lookup_certs);
+X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(X509_STORE *ctx);
+void X509_STORE_set_lookup_crls(X509_STORE *ctx,
+                                X509_STORE_CTX_lookup_crls_fn lookup_crls);
+#define X509_STORE_set_lookup_crls_cb(ctx, func) \
+    X509_STORE_set_lookup_crls((ctx), (func))
+X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(X509_STORE *ctx);
+void X509_STORE_set_cleanup(X509_STORE *ctx,
+                            X509_STORE_CTX_cleanup_fn cleanup);
+X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(X509_STORE *ctx);
+
+#define X509_STORE_get_ex_new_index(l, p, newf, dupf, freef) \
+    CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE, l, p, newf, dupf, freef)
+int X509_STORE_set_ex_data(X509_STORE *ctx, int idx, void *data);
+void *X509_STORE_get_ex_data(X509_STORE *ctx, int idx);
+
+X509_STORE_CTX *X509_STORE_CTX_new(void);
+
+int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
+
+void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
+int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
+                        X509 *x509, STACK_OF(X509) *chain);
+void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
+void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);
+
+X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx);
+X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx);
+STACK_OF(X509)* X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx);
+void X509_STORE_CTX_set0_untrusted(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
+void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
+                                  X509_STORE_CTX_verify_cb verify);
+X509_STORE_CTX_verify_cb X509_STORE_CTX_get_verify_cb(X509_STORE_CTX *ctx);
+X509_STORE_CTX_verify_fn X509_STORE_CTX_get_verify(X509_STORE_CTX *ctx);
+X509_STORE_CTX_get_issuer_fn X509_STORE_CTX_get_get_issuer(X509_STORE_CTX *ctx);
+X509_STORE_CTX_check_issued_fn X509_STORE_CTX_get_check_issued(X509_STORE_CTX *ctx);
+X509_STORE_CTX_check_revocation_fn X509_STORE_CTX_get_check_revocation(X509_STORE_CTX *ctx);
+X509_STORE_CTX_get_crl_fn X509_STORE_CTX_get_get_crl(X509_STORE_CTX *ctx);
+X509_STORE_CTX_check_crl_fn X509_STORE_CTX_get_check_crl(X509_STORE_CTX *ctx);
+X509_STORE_CTX_cert_crl_fn X509_STORE_CTX_get_cert_crl(X509_STORE_CTX *ctx);
+X509_STORE_CTX_check_policy_fn X509_STORE_CTX_get_check_policy(X509_STORE_CTX *ctx);
+X509_STORE_CTX_lookup_certs_fn X509_STORE_CTX_get_lookup_certs(X509_STORE_CTX *ctx);
+X509_STORE_CTX_lookup_crls_fn X509_STORE_CTX_get_lookup_crls(X509_STORE_CTX *ctx);
+X509_STORE_CTX_cleanup_fn X509_STORE_CTX_get_cleanup(X509_STORE_CTX *ctx);
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+# define X509_STORE_CTX_get_chain X509_STORE_CTX_get0_chain
+# define X509_STORE_CTX_set_chain X509_STORE_CTX_set0_untrusted
+# define X509_STORE_CTX_trusted_stack X509_STORE_CTX_set0_trusted_stack
+# define X509_STORE_get_by_subject X509_STORE_CTX_get_by_subject
+# define X509_STORE_get1_cert X509_STORE_CTX_get1_certs
+# define X509_STORE_get1_crl X509_STORE_CTX_get1_crls
+#endif
+
+X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m);
+X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void);
+X509_LOOKUP_METHOD *X509_LOOKUP_file(void);
+
+int X509_STORE_add_cert(X509_STORE *ctx, X509 *x);
+int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x);
+
+int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, X509_LOOKUP_TYPE type,
+                                  X509_NAME *name, X509_OBJECT *ret);
+X509_OBJECT *X509_STORE_CTX_get_obj_by_subject(X509_STORE_CTX *vs,
+                                               X509_LOOKUP_TYPE type,
+                                               X509_NAME *name);
+
+int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
+                     long argl, char **ret);
+
+int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type);
+int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type);
+int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type);
+
+X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method);
+void X509_LOOKUP_free(X509_LOOKUP *ctx);
+int X509_LOOKUP_init(X509_LOOKUP *ctx);
+int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+                           X509_NAME *name, X509_OBJECT *ret);
+int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+                                 X509_NAME *name, ASN1_INTEGER *serial,
+                                 X509_OBJECT *ret);
+int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+                               const unsigned char *bytes, int len,
+                               X509_OBJECT *ret);
+int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, X509_LOOKUP_TYPE type,
+                         const char *str, int len, X509_OBJECT *ret);
+int X509_LOOKUP_shutdown(X509_LOOKUP *ctx);
+
+int X509_STORE_load_locations(X509_STORE *ctx,
+                              const char *file, const char *dir);
+int X509_STORE_set_default_paths(X509_STORE *ctx);
+
+#define X509_STORE_CTX_get_ex_new_index(l, p, newf, dupf, freef) \
+    CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, l, p, newf, dupf, freef)
+int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data);
+void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx);
+int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
+void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int s);
+int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
+void X509_STORE_CTX_set_error_depth(X509_STORE_CTX *ctx, int depth);
+X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
+void X509_STORE_CTX_set_current_cert(X509_STORE_CTX *ctx, X509 *x);
+X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx);
+X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx);
+X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx);
+STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx);
+STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
+void X509_STORE_CTX_set_cert(X509_STORE_CTX *c, X509 *x);
+void X509_STORE_CTX_set0_verified_chain(X509_STORE_CTX *c, STACK_OF(X509) *sk);
+void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, STACK_OF(X509_CRL) *sk);
+int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
+int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust);
+int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
+                                   int purpose, int trust);
+void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags);
+void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
+                             time_t t);
+
+X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx);
+int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx);
+int X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx);
+
+X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx);
+void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param);
+int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name);
+
+/*
+ * Bridge opacity barrier between libcrypt and libssl, also needed to support
+ * offline testing in test/danetest.c
+ */
+void X509_STORE_CTX_set0_dane(X509_STORE_CTX *ctx, SSL_DANE *dane);
+#define DANE_FLAG_NO_DANE_EE_NAMECHECKS (1L << 0)
+
+/* X509_VERIFY_PARAM functions */
+
+X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void);
+void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param);
+int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to,
+                              const X509_VERIFY_PARAM *from);
+int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
+                           const X509_VERIFY_PARAM *from);
+int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name);
+int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param,
+                                unsigned long flags);
+int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
+                                  unsigned long flags);
+unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param);
+int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose);
+int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust);
+void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth);
+void X509_VERIFY_PARAM_set_auth_level(X509_VERIFY_PARAM *param, int auth_level);
+time_t X509_VERIFY_PARAM_get_time(const X509_VERIFY_PARAM *param);
+void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t);
+int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
+                                  ASN1_OBJECT *policy);
+int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
+                                    STACK_OF(ASN1_OBJECT) *policies);
+
+int X509_VERIFY_PARAM_set_inh_flags(X509_VERIFY_PARAM *param,
+                                    uint32_t flags);
+uint32_t X509_VERIFY_PARAM_get_inh_flags(const X509_VERIFY_PARAM *param);
+
+int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
+                                const char *name, size_t namelen);
+int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
+                                const char *name, size_t namelen);
+void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
+                                     unsigned int flags);
+char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *);
+void X509_VERIFY_PARAM_move_peername(X509_VERIFY_PARAM *, X509_VERIFY_PARAM *);
+int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
+                                 const char *email, size_t emaillen);
+int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
+                              const unsigned char *ip, size_t iplen);
+int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param,
+                                  const char *ipasc);
+
+int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param);
+int X509_VERIFY_PARAM_get_auth_level(const X509_VERIFY_PARAM *param);
+const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param);
+
+int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param);
+int X509_VERIFY_PARAM_get_count(void);
+const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id);
+const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name);
+void X509_VERIFY_PARAM_table_cleanup(void);
+
+/* Non positive return values are errors */
+#define X509_PCY_TREE_FAILURE  -2 /* Failure to satisfy explicit policy */
+#define X509_PCY_TREE_INVALID  -1 /* Inconsistent or invalid extensions */
+#define X509_PCY_TREE_INTERNAL  0 /* Internal error, most likely malloc */
+
+/*
+ * Positive return values form a bit mask, all but the first are internal to
+ * the library and don't appear in results from X509_policy_check().
+ */
+#define X509_PCY_TREE_VALID     1 /* The policy tree is valid */
+#define X509_PCY_TREE_EMPTY     2 /* The policy tree is empty */
+#define X509_PCY_TREE_EXPLICIT  4 /* Explicit policy required */
+
+int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
+                      STACK_OF(X509) *certs,
+                      STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags);
+
+void X509_policy_tree_free(X509_POLICY_TREE *tree);
+
+int X509_policy_tree_level_count(const X509_POLICY_TREE *tree);
+X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree,
+                                               int i);
+
+STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const
+                                                           X509_POLICY_TREE
+                                                           *tree);
+
+STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const
+                                                                X509_POLICY_TREE
+                                                                *tree);
+
+int X509_policy_level_node_count(X509_POLICY_LEVEL *level);
+
+X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level,
+                                              int i);
+
+const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node);
+
+STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const
+                                                           X509_POLICY_NODE
+                                                           *node);
+const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE
+                                                     *node);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/x509v3.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/x509v3.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/include/openssl/x509v3.h	(revision 331)
@@ -0,0 +1,1006 @@
+/*
+ * Copyright 1999-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
+ */
+
+#ifndef HEADER_X509V3_H
+# define HEADER_X509V3_H
+
+# include <openssl/bio.h>
+# include <openssl/x509.h>
+# include <openssl/conf.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Forward reference */
+struct v3_ext_method;
+struct v3_ext_ctx;
+
+/* Useful typedefs */
+
+typedef void *(*X509V3_EXT_NEW)(void);
+typedef void (*X509V3_EXT_FREE) (void *);
+typedef void *(*X509V3_EXT_D2I)(void *, const unsigned char **, long);
+typedef int (*X509V3_EXT_I2D) (void *, unsigned char **);
+typedef STACK_OF(CONF_VALUE) *
+    (*X509V3_EXT_I2V) (const struct v3_ext_method *method, void *ext,
+                       STACK_OF(CONF_VALUE) *extlist);
+typedef void *(*X509V3_EXT_V2I)(const struct v3_ext_method *method,
+                                struct v3_ext_ctx *ctx,
+                                STACK_OF(CONF_VALUE) *values);
+typedef char *(*X509V3_EXT_I2S)(const struct v3_ext_method *method,
+                                void *ext);
+typedef void *(*X509V3_EXT_S2I)(const struct v3_ext_method *method,
+                                struct v3_ext_ctx *ctx, const char *str);
+typedef int (*X509V3_EXT_I2R) (const struct v3_ext_method *method, void *ext,
+                               BIO *out, int indent);
+typedef void *(*X509V3_EXT_R2I)(const struct v3_ext_method *method,
+                                struct v3_ext_ctx *ctx, const char *str);
+
+/* V3 extension structure */
+
+struct v3_ext_method {
+    int ext_nid;
+    int ext_flags;
+/* If this is set the following four fields are ignored */
+    ASN1_ITEM_EXP *it;
+/* Old style ASN1 calls */
+    X509V3_EXT_NEW ext_new;
+    X509V3_EXT_FREE ext_free;
+    X509V3_EXT_D2I d2i;
+    X509V3_EXT_I2D i2d;
+/* The following pair is used for string extensions */
+    X509V3_EXT_I2S i2s;
+    X509V3_EXT_S2I s2i;
+/* The following pair is used for multi-valued extensions */
+    X509V3_EXT_I2V i2v;
+    X509V3_EXT_V2I v2i;
+/* The following are used for raw extensions */
+    X509V3_EXT_I2R i2r;
+    X509V3_EXT_R2I r2i;
+    void *usr_data;             /* Any extension specific data */
+};
+
+typedef struct X509V3_CONF_METHOD_st {
+    char *(*get_string) (void *db, const char *section, const char *value);
+    STACK_OF(CONF_VALUE) *(*get_section) (void *db, const char *section);
+    void (*free_string) (void *db, char *string);
+    void (*free_section) (void *db, STACK_OF(CONF_VALUE) *section);
+} X509V3_CONF_METHOD;
+
+/* Context specific info */
+struct v3_ext_ctx {
+# define CTX_TEST 0x1
+# define X509V3_CTX_REPLACE 0x2
+    int flags;
+    X509 *issuer_cert;
+    X509 *subject_cert;
+    X509_REQ *subject_req;
+    X509_CRL *crl;
+    X509V3_CONF_METHOD *db_meth;
+    void *db;
+/* Maybe more here */
+};
+
+typedef struct v3_ext_method X509V3_EXT_METHOD;
+
+DEFINE_STACK_OF(X509V3_EXT_METHOD)
+
+/* ext_flags values */
+# define X509V3_EXT_DYNAMIC      0x1
+# define X509V3_EXT_CTX_DEP      0x2
+# define X509V3_EXT_MULTILINE    0x4
+
+typedef BIT_STRING_BITNAME ENUMERATED_NAMES;
+
+typedef struct BASIC_CONSTRAINTS_st {
+    int ca;
+    ASN1_INTEGER *pathlen;
+} BASIC_CONSTRAINTS;
+
+typedef struct PKEY_USAGE_PERIOD_st {
+    ASN1_GENERALIZEDTIME *notBefore;
+    ASN1_GENERALIZEDTIME *notAfter;
+} PKEY_USAGE_PERIOD;
+
+typedef struct otherName_st {
+    ASN1_OBJECT *type_id;
+    ASN1_TYPE *value;
+} OTHERNAME;
+
+typedef struct EDIPartyName_st {
+    ASN1_STRING *nameAssigner;
+    ASN1_STRING *partyName;
+} EDIPARTYNAME;
+
+typedef struct GENERAL_NAME_st {
+# define GEN_OTHERNAME   0
+# define GEN_EMAIL       1
+# define GEN_DNS         2
+# define GEN_X400        3
+# define GEN_DIRNAME     4
+# define GEN_EDIPARTY    5
+# define GEN_URI         6
+# define GEN_IPADD       7
+# define GEN_RID         8
+    int type;
+    union {
+        char *ptr;
+        OTHERNAME *otherName;   /* otherName */
+        ASN1_IA5STRING *rfc822Name;
+        ASN1_IA5STRING *dNSName;
+        ASN1_TYPE *x400Address;
+        X509_NAME *directoryName;
+        EDIPARTYNAME *ediPartyName;
+        ASN1_IA5STRING *uniformResourceIdentifier;
+        ASN1_OCTET_STRING *iPAddress;
+        ASN1_OBJECT *registeredID;
+        /* Old names */
+        ASN1_OCTET_STRING *ip;  /* iPAddress */
+        X509_NAME *dirn;        /* dirn */
+        ASN1_IA5STRING *ia5;    /* rfc822Name, dNSName,
+                                 * uniformResourceIdentifier */
+        ASN1_OBJECT *rid;       /* registeredID */
+        ASN1_TYPE *other;       /* x400Address */
+    } d;
+} GENERAL_NAME;
+
+typedef struct ACCESS_DESCRIPTION_st {
+    ASN1_OBJECT *method;
+    GENERAL_NAME *location;
+} ACCESS_DESCRIPTION;
+
+typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
+
+typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE;
+
+typedef STACK_OF(ASN1_INTEGER) TLS_FEATURE;
+
+DEFINE_STACK_OF(GENERAL_NAME)
+typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES;
+DEFINE_STACK_OF(GENERAL_NAMES)
+
+DEFINE_STACK_OF(ACCESS_DESCRIPTION)
+
+typedef struct DIST_POINT_NAME_st {
+    int type;
+    union {
+        GENERAL_NAMES *fullname;
+        STACK_OF(X509_NAME_ENTRY) *relativename;
+    } name;
+/* If relativename then this contains the full distribution point name */
+    X509_NAME *dpname;
+} DIST_POINT_NAME;
+/* All existing reasons */
+# define CRLDP_ALL_REASONS       0x807f
+
+# define CRL_REASON_NONE                         -1
+# define CRL_REASON_UNSPECIFIED                  0
+# define CRL_REASON_KEY_COMPROMISE               1
+# define CRL_REASON_CA_COMPROMISE                2
+# define CRL_REASON_AFFILIATION_CHANGED          3
+# define CRL_REASON_SUPERSEDED                   4
+# define CRL_REASON_CESSATION_OF_OPERATION       5
+# define CRL_REASON_CERTIFICATE_HOLD             6
+# define CRL_REASON_REMOVE_FROM_CRL              8
+# define CRL_REASON_PRIVILEGE_WITHDRAWN          9
+# define CRL_REASON_AA_COMPROMISE                10
+
+struct DIST_POINT_st {
+    DIST_POINT_NAME *distpoint;
+    ASN1_BIT_STRING *reasons;
+    GENERAL_NAMES *CRLissuer;
+    int dp_reasons;
+};
+
+typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS;
+
+DEFINE_STACK_OF(DIST_POINT)
+
+struct AUTHORITY_KEYID_st {
+    ASN1_OCTET_STRING *keyid;
+    GENERAL_NAMES *issuer;
+    ASN1_INTEGER *serial;
+};
+
+/* Strong extranet structures */
+
+typedef struct SXNET_ID_st {
+    ASN1_INTEGER *zone;
+    ASN1_OCTET_STRING *user;
+} SXNETID;
+
+DEFINE_STACK_OF(SXNETID)
+
+typedef struct SXNET_st {
+    ASN1_INTEGER *version;
+    STACK_OF(SXNETID) *ids;
+} SXNET;
+
+typedef struct NOTICEREF_st {
+    ASN1_STRING *organization;
+    STACK_OF(ASN1_INTEGER) *noticenos;
+} NOTICEREF;
+
+typedef struct USERNOTICE_st {
+    NOTICEREF *noticeref;
+    ASN1_STRING *exptext;
+} USERNOTICE;
+
+typedef struct POLICYQUALINFO_st {
+    ASN1_OBJECT *pqualid;
+    union {
+        ASN1_IA5STRING *cpsuri;
+        USERNOTICE *usernotice;
+        ASN1_TYPE *other;
+    } d;
+} POLICYQUALINFO;
+
+DEFINE_STACK_OF(POLICYQUALINFO)
+
+typedef struct POLICYINFO_st {
+    ASN1_OBJECT *policyid;
+    STACK_OF(POLICYQUALINFO) *qualifiers;
+} POLICYINFO;
+
+typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES;
+
+DEFINE_STACK_OF(POLICYINFO)
+
+typedef struct POLICY_MAPPING_st {
+    ASN1_OBJECT *issuerDomainPolicy;
+    ASN1_OBJECT *subjectDomainPolicy;
+} POLICY_MAPPING;
+
+DEFINE_STACK_OF(POLICY_MAPPING)
+
+typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS;
+
+typedef struct GENERAL_SUBTREE_st {
+    GENERAL_NAME *base;
+    ASN1_INTEGER *minimum;
+    ASN1_INTEGER *maximum;
+} GENERAL_SUBTREE;
+
+DEFINE_STACK_OF(GENERAL_SUBTREE)
+
+struct NAME_CONSTRAINTS_st {
+    STACK_OF(GENERAL_SUBTREE) *permittedSubtrees;
+    STACK_OF(GENERAL_SUBTREE) *excludedSubtrees;
+};
+
+typedef struct POLICY_CONSTRAINTS_st {
+    ASN1_INTEGER *requireExplicitPolicy;
+    ASN1_INTEGER *inhibitPolicyMapping;
+} POLICY_CONSTRAINTS;
+
+/* Proxy certificate structures, see RFC 3820 */
+typedef struct PROXY_POLICY_st {
+    ASN1_OBJECT *policyLanguage;
+    ASN1_OCTET_STRING *policy;
+} PROXY_POLICY;
+
+typedef struct PROXY_CERT_INFO_EXTENSION_st {
+    ASN1_INTEGER *pcPathLengthConstraint;
+    PROXY_POLICY *proxyPolicy;
+} PROXY_CERT_INFO_EXTENSION;
+
+DECLARE_ASN1_FUNCTIONS(PROXY_POLICY)
+DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION)
+
+struct ISSUING_DIST_POINT_st {
+    DIST_POINT_NAME *distpoint;
+    int onlyuser;
+    int onlyCA;
+    ASN1_BIT_STRING *onlysomereasons;
+    int indirectCRL;
+    int onlyattr;
+};
+
+/* Values in idp_flags field */
+/* IDP present */
+# define IDP_PRESENT     0x1
+/* IDP values inconsistent */
+# define IDP_INVALID     0x2
+/* onlyuser true */
+# define IDP_ONLYUSER    0x4
+/* onlyCA true */
+# define IDP_ONLYCA      0x8
+/* onlyattr true */
+# define IDP_ONLYATTR    0x10
+/* indirectCRL true */
+# define IDP_INDIRECT    0x20
+/* onlysomereasons present */
+# define IDP_REASONS     0x40
+
+# define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \
+",name:", val->name, ",value:", val->value);
+
+# define X509V3_set_ctx_test(ctx) \
+                        X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST)
+# define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL;
+
+# define EXT_BITSTRING(nid, table) { nid, 0, ASN1_ITEM_ref(ASN1_BIT_STRING), \
+                        0,0,0,0, \
+                        0,0, \
+                        (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \
+                        (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, \
+                        NULL, NULL, \
+                        table}
+
+# define EXT_IA5STRING(nid) { nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), \
+                        0,0,0,0, \
+                        (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, \
+                        (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, \
+                        0,0,0,0, \
+                        NULL}
+
+# define EXT_END { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+
+/* X509_PURPOSE stuff */
+
+# define EXFLAG_BCONS            0x1
+# define EXFLAG_KUSAGE           0x2
+# define EXFLAG_XKUSAGE          0x4
+# define EXFLAG_NSCERT           0x8
+
+# define EXFLAG_CA               0x10
+/* Really self issued not necessarily self signed */
+# define EXFLAG_SI               0x20
+# define EXFLAG_V1               0x40
+# define EXFLAG_INVALID          0x80
+/* EXFLAG_SET is set to indicate that some values have been precomputed */
+# define EXFLAG_SET              0x100
+# define EXFLAG_CRITICAL         0x200
+# define EXFLAG_PROXY            0x400
+
+# define EXFLAG_INVALID_POLICY   0x800
+# define EXFLAG_FRESHEST         0x1000
+/* Self signed */
+# define EXFLAG_SS               0x2000
+
+# define KU_DIGITAL_SIGNATURE    0x0080
+# define KU_NON_REPUDIATION      0x0040
+# define KU_KEY_ENCIPHERMENT     0x0020
+# define KU_DATA_ENCIPHERMENT    0x0010
+# define KU_KEY_AGREEMENT        0x0008
+# define KU_KEY_CERT_SIGN        0x0004
+# define KU_CRL_SIGN             0x0002
+# define KU_ENCIPHER_ONLY        0x0001
+# define KU_DECIPHER_ONLY        0x8000
+
+# define NS_SSL_CLIENT           0x80
+# define NS_SSL_SERVER           0x40
+# define NS_SMIME                0x20
+# define NS_OBJSIGN              0x10
+# define NS_SSL_CA               0x04
+# define NS_SMIME_CA             0x02
+# define NS_OBJSIGN_CA           0x01
+# define NS_ANY_CA               (NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA)
+
+# define XKU_SSL_SERVER          0x1
+# define XKU_SSL_CLIENT          0x2
+# define XKU_SMIME               0x4
+# define XKU_CODE_SIGN           0x8
+# define XKU_SGC                 0x10
+# define XKU_OCSP_SIGN           0x20
+# define XKU_TIMESTAMP           0x40
+# define XKU_DVCS                0x80
+# define XKU_ANYEKU              0x100
+
+# define X509_PURPOSE_DYNAMIC    0x1
+# define X509_PURPOSE_DYNAMIC_NAME       0x2
+
+typedef struct x509_purpose_st {
+    int purpose;
+    int trust;                  /* Default trust ID */
+    int flags;
+    int (*check_purpose) (const struct x509_purpose_st *, const X509 *, int);
+    char *name;
+    char *sname;
+    void *usr_data;
+} X509_PURPOSE;
+
+# define X509_PURPOSE_SSL_CLIENT         1
+# define X509_PURPOSE_SSL_SERVER         2
+# define X509_PURPOSE_NS_SSL_SERVER      3
+# define X509_PURPOSE_SMIME_SIGN         4
+# define X509_PURPOSE_SMIME_ENCRYPT      5
+# define X509_PURPOSE_CRL_SIGN           6
+# define X509_PURPOSE_ANY                7
+# define X509_PURPOSE_OCSP_HELPER        8
+# define X509_PURPOSE_TIMESTAMP_SIGN     9
+
+# define X509_PURPOSE_MIN                1
+# define X509_PURPOSE_MAX                9
+
+/* Flags for X509V3_EXT_print() */
+
+# define X509V3_EXT_UNKNOWN_MASK         (0xfL << 16)
+/* Return error for unknown extensions */
+# define X509V3_EXT_DEFAULT              0
+/* Print error for unknown extensions */
+# define X509V3_EXT_ERROR_UNKNOWN        (1L << 16)
+/* ASN1 parse unknown extensions */
+# define X509V3_EXT_PARSE_UNKNOWN        (2L << 16)
+/* BIO_dump unknown extensions */
+# define X509V3_EXT_DUMP_UNKNOWN         (3L << 16)
+
+/* Flags for X509V3_add1_i2d */
+
+# define X509V3_ADD_OP_MASK              0xfL
+# define X509V3_ADD_DEFAULT              0L
+# define X509V3_ADD_APPEND               1L
+# define X509V3_ADD_REPLACE              2L
+# define X509V3_ADD_REPLACE_EXISTING     3L
+# define X509V3_ADD_KEEP_EXISTING        4L
+# define X509V3_ADD_DELETE               5L
+# define X509V3_ADD_SILENT               0x10
+
+DEFINE_STACK_OF(X509_PURPOSE)
+
+DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS)
+
+DECLARE_ASN1_FUNCTIONS(SXNET)
+DECLARE_ASN1_FUNCTIONS(SXNETID)
+
+int SXNET_add_id_asc(SXNET **psx, const char *zone, const char *user, int userlen);
+int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, const char *user,
+                       int userlen);
+int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *izone, const char *user,
+                         int userlen);
+
+ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, const char *zone);
+ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone);
+ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone);
+
+DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID)
+
+DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD)
+
+DECLARE_ASN1_FUNCTIONS(GENERAL_NAME)
+GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a);
+int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b);
+
+ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+                                     X509V3_CTX *ctx,
+                                     STACK_OF(CONF_VALUE) *nval);
+STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+                                          ASN1_BIT_STRING *bits,
+                                          STACK_OF(CONF_VALUE) *extlist);
+char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5);
+ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
+                                   X509V3_CTX *ctx, const char *str);
+
+STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
+                                       GENERAL_NAME *gen,
+                                       STACK_OF(CONF_VALUE) *ret);
+int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen);
+
+DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES)
+
+STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
+                                        GENERAL_NAMES *gen,
+                                        STACK_OF(CONF_VALUE) *extlist);
+GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
+                                 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+
+DECLARE_ASN1_FUNCTIONS(OTHERNAME)
+DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME)
+int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b);
+void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value);
+void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype);
+int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
+                                ASN1_OBJECT *oid, ASN1_TYPE *value);
+int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen,
+                                ASN1_OBJECT **poid, ASN1_TYPE **pvalue);
+
+char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
+                            const ASN1_OCTET_STRING *ia5);
+ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
+                                         X509V3_CTX *ctx, const char *str);
+
+DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE)
+int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION *a);
+
+DECLARE_ASN1_ALLOC_FUNCTIONS(TLS_FEATURE)
+
+DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES)
+DECLARE_ASN1_FUNCTIONS(POLICYINFO)
+DECLARE_ASN1_FUNCTIONS(POLICYQUALINFO)
+DECLARE_ASN1_FUNCTIONS(USERNOTICE)
+DECLARE_ASN1_FUNCTIONS(NOTICEREF)
+
+DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS)
+DECLARE_ASN1_FUNCTIONS(DIST_POINT)
+DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME)
+DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT)
+
+int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname);
+
+int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc);
+int NAME_CONSTRAINTS_check_CN(X509 *x, NAME_CONSTRAINTS *nc);
+
+DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
+DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
+
+DECLARE_ASN1_ITEM(POLICY_MAPPING)
+DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING)
+DECLARE_ASN1_ITEM(POLICY_MAPPINGS)
+
+DECLARE_ASN1_ITEM(GENERAL_SUBTREE)
+DECLARE_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
+
+DECLARE_ASN1_ITEM(NAME_CONSTRAINTS)
+DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
+
+DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
+DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS)
+
+GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
+                               const X509V3_EXT_METHOD *method,
+                               X509V3_CTX *ctx, int gen_type,
+                               const char *value, int is_nc);
+
+# ifdef HEADER_CONF_H
+GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method,
+                               X509V3_CTX *ctx, CONF_VALUE *cnf);
+GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
+                                  const X509V3_EXT_METHOD *method,
+                                  X509V3_CTX *ctx, CONF_VALUE *cnf,
+                                  int is_nc);
+void X509V3_conf_free(CONF_VALUE *val);
+
+X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
+                                     const char *value);
+X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name,
+                                 const char *value);
+int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section,
+                            STACK_OF(X509_EXTENSION) **sk);
+int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section,
+                         X509 *cert);
+int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section,
+                             X509_REQ *req);
+int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, const char *section,
+                             X509_CRL *crl);
+
+X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf,
+                                    X509V3_CTX *ctx, int ext_nid,
+                                    const char *value);
+X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+                                const char *name, const char *value);
+int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+                        const char *section, X509 *cert);
+int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+                            const char *section, X509_REQ *req);
+int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx,
+                            const char *section, X509_CRL *crl);
+
+int X509V3_add_value_bool_nf(const char *name, int asn1_bool,
+                             STACK_OF(CONF_VALUE) **extlist);
+int X509V3_get_value_bool(const CONF_VALUE *value, int *asn1_bool);
+int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint);
+void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf);
+void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash);
+# endif
+
+char *X509V3_get_string(X509V3_CTX *ctx, const char *name, const char *section);
+STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, const char *section);
+void X509V3_string_free(X509V3_CTX *ctx, char *str);
+void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section);
+void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject,
+                    X509_REQ *req, X509_CRL *crl, int flags);
+
+int X509V3_add_value(const char *name, const char *value,
+                     STACK_OF(CONF_VALUE) **extlist);
+int X509V3_add_value_uchar(const char *name, const unsigned char *value,
+                           STACK_OF(CONF_VALUE) **extlist);
+int X509V3_add_value_bool(const char *name, int asn1_bool,
+                          STACK_OF(CONF_VALUE) **extlist);
+int X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint,
+                         STACK_OF(CONF_VALUE) **extlist);
+char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, const ASN1_INTEGER *aint);
+ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, const char *value);
+char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, const ASN1_ENUMERATED *aint);
+char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth,
+                                const ASN1_ENUMERATED *aint);
+int X509V3_EXT_add(X509V3_EXT_METHOD *ext);
+int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist);
+int X509V3_EXT_add_alias(int nid_to, int nid_from);
+void X509V3_EXT_cleanup(void);
+
+const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext);
+const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid);
+int X509V3_add_standard_extensions(void);
+STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line);
+void *X509V3_EXT_d2i(X509_EXTENSION *ext);
+void *X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *x, int nid, int *crit,
+                     int *idx);
+
+X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);
+int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value,
+                    int crit, unsigned long flags);
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+/* The new declarations are in crypto.h, but the old ones were here. */
+# define hex_to_string OPENSSL_buf2hexstr
+# define string_to_hex OPENSSL_hexstr2buf
+#endif
+
+void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
+                        int ml);
+int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag,
+                     int indent);
+#ifndef OPENSSL_NO_STDIO
+int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent);
+#endif
+int X509V3_extensions_print(BIO *out, const char *title,
+                            const STACK_OF(X509_EXTENSION) *exts,
+                            unsigned long flag, int indent);
+
+int X509_check_ca(X509 *x);
+int X509_check_purpose(X509 *x, int id, int ca);
+int X509_supported_extension(X509_EXTENSION *ex);
+int X509_PURPOSE_set(int *p, int purpose);
+int X509_check_issued(X509 *issuer, X509 *subject);
+int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid);
+void X509_set_proxy_flag(X509 *x);
+void X509_set_proxy_pathlen(X509 *x, long l);
+long X509_get_proxy_pathlen(X509 *x);
+
+uint32_t X509_get_extension_flags(X509 *x);
+uint32_t X509_get_key_usage(X509 *x);
+uint32_t X509_get_extended_key_usage(X509 *x);
+const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x);
+
+int X509_PURPOSE_get_count(void);
+X509_PURPOSE *X509_PURPOSE_get0(int idx);
+int X509_PURPOSE_get_by_sname(const char *sname);
+int X509_PURPOSE_get_by_id(int id);
+int X509_PURPOSE_add(int id, int trust, int flags,
+                     int (*ck) (const X509_PURPOSE *, const X509 *, int),
+                     const char *name, const char *sname, void *arg);
+char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp);
+char *X509_PURPOSE_get0_sname(const X509_PURPOSE *xp);
+int X509_PURPOSE_get_trust(const X509_PURPOSE *xp);
+void X509_PURPOSE_cleanup(void);
+int X509_PURPOSE_get_id(const X509_PURPOSE *);
+
+STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x);
+STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x);
+void X509_email_free(STACK_OF(OPENSSL_STRING) *sk);
+STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x);
+/* Flags for X509_check_* functions */
+
+/*
+ * Always check subject name for host match even if subject alt names present
+ */
+# define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT    0x1
+/* Disable wildcard matching for dnsName fields and common name. */
+# define X509_CHECK_FLAG_NO_WILDCARDS    0x2
+/* Wildcards must not match a partial label. */
+# define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0x4
+/* Allow (non-partial) wildcards to match multiple labels. */
+# define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0x8
+/* Constraint verifier subdomain patterns to match a single labels. */
+# define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0x10
+/* Never check the subject CN */
+# define X509_CHECK_FLAG_NEVER_CHECK_SUBJECT    0x20
+/*
+ * Match reference identifiers starting with "." to any sub-domain.
+ * This is a non-public flag, turned on implicitly when the subject
+ * reference identity is a DNS name.
+ */
+# define _X509_CHECK_FLAG_DOT_SUBDOMAINS 0x8000
+
+int X509_check_host(X509 *x, const char *chk, size_t chklen,
+                    unsigned int flags, char **peername);
+int X509_check_email(X509 *x, const char *chk, size_t chklen,
+                     unsigned int flags);
+int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen,
+                  unsigned int flags);
+int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags);
+
+ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc);
+ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc);
+int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk,
+                             unsigned long chtype);
+
+void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent);
+DEFINE_STACK_OF(X509_POLICY_NODE)
+
+#ifndef OPENSSL_NO_RFC3779
+typedef struct ASRange_st {
+    ASN1_INTEGER *min, *max;
+} ASRange;
+
+# define ASIdOrRange_id          0
+# define ASIdOrRange_range       1
+
+typedef struct ASIdOrRange_st {
+    int type;
+    union {
+        ASN1_INTEGER *id;
+        ASRange *range;
+    } u;
+} ASIdOrRange;
+
+typedef STACK_OF(ASIdOrRange) ASIdOrRanges;
+DEFINE_STACK_OF(ASIdOrRange)
+
+# define ASIdentifierChoice_inherit              0
+# define ASIdentifierChoice_asIdsOrRanges        1
+
+typedef struct ASIdentifierChoice_st {
+    int type;
+    union {
+        ASN1_NULL *inherit;
+        ASIdOrRanges *asIdsOrRanges;
+    } u;
+} ASIdentifierChoice;
+
+typedef struct ASIdentifiers_st {
+    ASIdentifierChoice *asnum, *rdi;
+} ASIdentifiers;
+
+DECLARE_ASN1_FUNCTIONS(ASRange)
+DECLARE_ASN1_FUNCTIONS(ASIdOrRange)
+DECLARE_ASN1_FUNCTIONS(ASIdentifierChoice)
+DECLARE_ASN1_FUNCTIONS(ASIdentifiers)
+
+typedef struct IPAddressRange_st {
+    ASN1_BIT_STRING *min, *max;
+} IPAddressRange;
+
+# define IPAddressOrRange_addressPrefix  0
+# define IPAddressOrRange_addressRange   1
+
+typedef struct IPAddressOrRange_st {
+    int type;
+    union {
+        ASN1_BIT_STRING *addressPrefix;
+        IPAddressRange *addressRange;
+    } u;
+} IPAddressOrRange;
+
+typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges;
+DEFINE_STACK_OF(IPAddressOrRange)
+
+# define IPAddressChoice_inherit                 0
+# define IPAddressChoice_addressesOrRanges       1
+
+typedef struct IPAddressChoice_st {
+    int type;
+    union {
+        ASN1_NULL *inherit;
+        IPAddressOrRanges *addressesOrRanges;
+    } u;
+} IPAddressChoice;
+
+typedef struct IPAddressFamily_st {
+    ASN1_OCTET_STRING *addressFamily;
+    IPAddressChoice *ipAddressChoice;
+} IPAddressFamily;
+
+typedef STACK_OF(IPAddressFamily) IPAddrBlocks;
+DEFINE_STACK_OF(IPAddressFamily)
+
+DECLARE_ASN1_FUNCTIONS(IPAddressRange)
+DECLARE_ASN1_FUNCTIONS(IPAddressOrRange)
+DECLARE_ASN1_FUNCTIONS(IPAddressChoice)
+DECLARE_ASN1_FUNCTIONS(IPAddressFamily)
+
+/*
+ * API tag for elements of the ASIdentifer SEQUENCE.
+ */
+# define V3_ASID_ASNUM   0
+# define V3_ASID_RDI     1
+
+/*
+ * AFI values, assigned by IANA.  It'd be nice to make the AFI
+ * handling code totally generic, but there are too many little things
+ * that would need to be defined for other address families for it to
+ * be worth the trouble.
+ */
+# define IANA_AFI_IPV4   1
+# define IANA_AFI_IPV6   2
+
+/*
+ * Utilities to construct and extract values from RFC3779 extensions,
+ * since some of the encodings (particularly for IP address prefixes
+ * and ranges) are a bit tedious to work with directly.
+ */
+int X509v3_asid_add_inherit(ASIdentifiers *asid, int which);
+int X509v3_asid_add_id_or_range(ASIdentifiers *asid, int which,
+                                ASN1_INTEGER *min, ASN1_INTEGER *max);
+int X509v3_addr_add_inherit(IPAddrBlocks *addr,
+                            const unsigned afi, const unsigned *safi);
+int X509v3_addr_add_prefix(IPAddrBlocks *addr,
+                           const unsigned afi, const unsigned *safi,
+                           unsigned char *a, const int prefixlen);
+int X509v3_addr_add_range(IPAddrBlocks *addr,
+                          const unsigned afi, const unsigned *safi,
+                          unsigned char *min, unsigned char *max);
+unsigned X509v3_addr_get_afi(const IPAddressFamily *f);
+int X509v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi,
+                          unsigned char *min, unsigned char *max,
+                          const int length);
+
+/*
+ * Canonical forms.
+ */
+int X509v3_asid_is_canonical(ASIdentifiers *asid);
+int X509v3_addr_is_canonical(IPAddrBlocks *addr);
+int X509v3_asid_canonize(ASIdentifiers *asid);
+int X509v3_addr_canonize(IPAddrBlocks *addr);
+
+/*
+ * Tests for inheritance and containment.
+ */
+int X509v3_asid_inherits(ASIdentifiers *asid);
+int X509v3_addr_inherits(IPAddrBlocks *addr);
+int X509v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b);
+int X509v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b);
+
+/*
+ * Check whether RFC 3779 extensions nest properly in chains.
+ */
+int X509v3_asid_validate_path(X509_STORE_CTX *);
+int X509v3_addr_validate_path(X509_STORE_CTX *);
+int X509v3_asid_validate_resource_set(STACK_OF(X509) *chain,
+                                      ASIdentifiers *ext,
+                                      int allow_inheritance);
+int X509v3_addr_validate_resource_set(STACK_OF(X509) *chain,
+                                      IPAddrBlocks *ext, int allow_inheritance);
+
+#endif                         /* OPENSSL_NO_RFC3779 */
+
+/* BEGIN ERROR CODES */
+/*
+ * The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+int ERR_load_X509V3_strings(void);
+
+/* Error codes for the X509V3 functions. */
+
+/* Function codes. */
+# define X509V3_F_A2I_GENERAL_NAME                        164
+# define X509V3_F_ADDR_VALIDATE_PATH_INTERNAL             166
+# define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE             161
+# define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL         162
+# define X509V3_F_COPY_EMAIL                              122
+# define X509V3_F_COPY_ISSUER                             123
+# define X509V3_F_DO_DIRNAME                              144
+# define X509V3_F_DO_EXT_I2D                              135
+# define X509V3_F_DO_EXT_NCONF                            151
+# define X509V3_F_GNAMES_FROM_SECTNAME                    156
+# define X509V3_F_I2S_ASN1_ENUMERATED                     121
+# define X509V3_F_I2S_ASN1_IA5STRING                      149
+# define X509V3_F_I2S_ASN1_INTEGER                        120
+# define X509V3_F_I2V_AUTHORITY_INFO_ACCESS               138
+# define X509V3_F_NOTICE_SECTION                          132
+# define X509V3_F_NREF_NOS                                133
+# define X509V3_F_POLICY_SECTION                          131
+# define X509V3_F_PROCESS_PCI_VALUE                       150
+# define X509V3_F_R2I_CERTPOL                             130
+# define X509V3_F_R2I_PCI                                 155
+# define X509V3_F_S2I_ASN1_IA5STRING                      100
+# define X509V3_F_S2I_ASN1_INTEGER                        108
+# define X509V3_F_S2I_ASN1_OCTET_STRING                   112
+# define X509V3_F_S2I_SKEY_ID                             115
+# define X509V3_F_SET_DIST_POINT_NAME                     158
+# define X509V3_F_SXNET_ADD_ID_ASC                        125
+# define X509V3_F_SXNET_ADD_ID_INTEGER                    126
+# define X509V3_F_SXNET_ADD_ID_ULONG                      127
+# define X509V3_F_SXNET_GET_ID_ASC                        128
+# define X509V3_F_SXNET_GET_ID_ULONG                      129
+# define X509V3_F_V2I_ASIDENTIFIERS                       163
+# define X509V3_F_V2I_ASN1_BIT_STRING                     101
+# define X509V3_F_V2I_AUTHORITY_INFO_ACCESS               139
+# define X509V3_F_V2I_AUTHORITY_KEYID                     119
+# define X509V3_F_V2I_BASIC_CONSTRAINTS                   102
+# define X509V3_F_V2I_CRLD                                134
+# define X509V3_F_V2I_EXTENDED_KEY_USAGE                  103
+# define X509V3_F_V2I_GENERAL_NAMES                       118
+# define X509V3_F_V2I_GENERAL_NAME_EX                     117
+# define X509V3_F_V2I_IDP                                 157
+# define X509V3_F_V2I_IPADDRBLOCKS                        159
+# define X509V3_F_V2I_ISSUER_ALT                          153
+# define X509V3_F_V2I_NAME_CONSTRAINTS                    147
+# define X509V3_F_V2I_POLICY_CONSTRAINTS                  146
+# define X509V3_F_V2I_POLICY_MAPPINGS                     145
+# define X509V3_F_V2I_SUBJECT_ALT                         154
+# define X509V3_F_V2I_TLS_FEATURE                         165
+# define X509V3_F_V3_GENERIC_EXTENSION                    116
+# define X509V3_F_X509V3_ADD1_I2D                         140
+# define X509V3_F_X509V3_ADD_VALUE                        105
+# define X509V3_F_X509V3_EXT_ADD                          104
+# define X509V3_F_X509V3_EXT_ADD_ALIAS                    106
+# define X509V3_F_X509V3_EXT_I2D                          136
+# define X509V3_F_X509V3_EXT_NCONF                        152
+# define X509V3_F_X509V3_GET_SECTION                      142
+# define X509V3_F_X509V3_GET_STRING                       143
+# define X509V3_F_X509V3_GET_VALUE_BOOL                   110
+# define X509V3_F_X509V3_PARSE_LIST                       109
+# define X509V3_F_X509_PURPOSE_ADD                        137
+# define X509V3_F_X509_PURPOSE_SET                        141
+
+/* Reason codes. */
+# define X509V3_R_BAD_IP_ADDRESS                          118
+# define X509V3_R_BAD_OBJECT                              119
+# define X509V3_R_BN_DEC2BN_ERROR                         100
+# define X509V3_R_BN_TO_ASN1_INTEGER_ERROR                101
+# define X509V3_R_DIRNAME_ERROR                           149
+# define X509V3_R_DISTPOINT_ALREADY_SET                   160
+# define X509V3_R_DUPLICATE_ZONE_ID                       133
+# define X509V3_R_ERROR_CONVERTING_ZONE                   131
+# define X509V3_R_ERROR_CREATING_EXTENSION                144
+# define X509V3_R_ERROR_IN_EXTENSION                      128
+# define X509V3_R_EXPECTED_A_SECTION_NAME                 137
+# define X509V3_R_EXTENSION_EXISTS                        145
+# define X509V3_R_EXTENSION_NAME_ERROR                    115
+# define X509V3_R_EXTENSION_NOT_FOUND                     102
+# define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED         103
+# define X509V3_R_EXTENSION_VALUE_ERROR                   116
+# define X509V3_R_ILLEGAL_EMPTY_EXTENSION                 151
+# define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG             152
+# define X509V3_R_INVALID_ASNUMBER                        162
+# define X509V3_R_INVALID_ASRANGE                         163
+# define X509V3_R_INVALID_BOOLEAN_STRING                  104
+# define X509V3_R_INVALID_EXTENSION_STRING                105
+# define X509V3_R_INVALID_INHERITANCE                     165
+# define X509V3_R_INVALID_IPADDRESS                       166
+# define X509V3_R_INVALID_MULTIPLE_RDNS                   161
+# define X509V3_R_INVALID_NAME                            106
+# define X509V3_R_INVALID_NULL_ARGUMENT                   107
+# define X509V3_R_INVALID_NULL_NAME                       108
+# define X509V3_R_INVALID_NULL_VALUE                      109
+# define X509V3_R_INVALID_NUMBER                          140
+# define X509V3_R_INVALID_NUMBERS                         141
+# define X509V3_R_INVALID_OBJECT_IDENTIFIER               110
+# define X509V3_R_INVALID_OPTION                          138
+# define X509V3_R_INVALID_POLICY_IDENTIFIER               134
+# define X509V3_R_INVALID_PROXY_POLICY_SETTING            153
+# define X509V3_R_INVALID_PURPOSE                         146
+# define X509V3_R_INVALID_SAFI                            164
+# define X509V3_R_INVALID_SECTION                         135
+# define X509V3_R_INVALID_SYNTAX                          143
+# define X509V3_R_ISSUER_DECODE_ERROR                     126
+# define X509V3_R_MISSING_VALUE                           124
+# define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS           142
+# define X509V3_R_NO_CONFIG_DATABASE                      136
+# define X509V3_R_NO_ISSUER_CERTIFICATE                   121
+# define X509V3_R_NO_ISSUER_DETAILS                       127
+# define X509V3_R_NO_POLICY_IDENTIFIER                    139
+# define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED   154
+# define X509V3_R_NO_PUBLIC_KEY                           114
+# define X509V3_R_NO_SUBJECT_DETAILS                      125
+# define X509V3_R_OPERATION_NOT_DEFINED                   148
+# define X509V3_R_OTHERNAME_ERROR                         147
+# define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED         155
+# define X509V3_R_POLICY_PATH_LENGTH                      156
+# define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED      157
+# define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159
+# define X509V3_R_SECTION_NOT_FOUND                       150
+# define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS            122
+# define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID              123
+# define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT             111
+# define X509V3_R_UNKNOWN_EXTENSION                       129
+# define X509V3_R_UNKNOWN_EXTENSION_NAME                  130
+# define X509V3_R_UNKNOWN_OPTION                          120
+# define X509V3_R_UNSUPPORTED_OPTION                      117
+# define X509V3_R_UNSUPPORTED_TYPE                        167
+# define X509V3_R_USER_TOO_LONG                           132
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/bio_ssl.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/bio_ssl.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/bio_ssl.c	(revision 331)
@@ -0,0 +1,528 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <openssl/crypto.h>
+#include "internal/bio.h"
+#include <openssl/err.h>
+#include "ssl_locl.h"
+
+static int ssl_write(BIO *h, const char *buf, int num);
+static int ssl_read(BIO *h, char *buf, int size);
+static int ssl_puts(BIO *h, const char *str);
+static long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int ssl_new(BIO *h);
+static int ssl_free(BIO *data);
+static long ssl_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+typedef struct bio_ssl_st {
+    SSL *ssl;                   /* The ssl handle :-) */
+    /* re-negotiate every time the total number of bytes is this size */
+    int num_renegotiates;
+    unsigned long renegotiate_count;
+    unsigned long byte_count;
+    unsigned long renegotiate_timeout;
+    unsigned long last_time;
+} BIO_SSL;
+
+static const BIO_METHOD methods_sslp = {
+    BIO_TYPE_SSL, "ssl",
+    ssl_write,
+    ssl_read,
+    ssl_puts,
+    NULL,                       /* ssl_gets, */
+    ssl_ctrl,
+    ssl_new,
+    ssl_free,
+    ssl_callback_ctrl,
+};
+
+const BIO_METHOD *BIO_f_ssl(void)
+{
+    return (&methods_sslp);
+}
+
+static int ssl_new(BIO *bi)
+{
+    BIO_SSL *bs = OPENSSL_zalloc(sizeof(*bs));
+
+    if (bs == NULL) {
+        BIOerr(BIO_F_SSL_NEW, ERR_R_MALLOC_FAILURE);
+        return (0);
+    }
+    BIO_set_init(bi, 0);
+    BIO_set_data(bi, bs);
+    /* Clear all flags */
+    BIO_clear_flags(bi, ~0);
+
+    return 1;
+}
+
+static int ssl_free(BIO *a)
+{
+    BIO_SSL *bs;
+
+    if (a == NULL)
+        return (0);
+    bs = BIO_get_data(a);
+    if (bs->ssl != NULL)
+        SSL_shutdown(bs->ssl);
+    if (BIO_get_shutdown(a)) {
+        if (BIO_get_init(a))
+            SSL_free(bs->ssl);
+        /* Clear all flags */
+        BIO_clear_flags(a, ~0);
+        BIO_set_init(a, 0);
+    }
+    OPENSSL_free(bs);
+    return 1;
+}
+
+static int ssl_read(BIO *b, char *out, int outl)
+{
+    int ret = 1;
+    BIO_SSL *sb;
+    SSL *ssl;
+    int retry_reason = 0;
+    int r = 0;
+
+    if (out == NULL)
+        return (0);
+    sb = BIO_get_data(b);
+    ssl = sb->ssl;
+
+    BIO_clear_retry_flags(b);
+
+    ret = SSL_read(ssl, out, outl);
+
+    switch (SSL_get_error(ssl, ret)) {
+    case SSL_ERROR_NONE:
+        if (ret <= 0)
+            break;
+        if (sb->renegotiate_count > 0) {
+            sb->byte_count += ret;
+            if (sb->byte_count > sb->renegotiate_count) {
+                sb->byte_count = 0;
+                sb->num_renegotiates++;
+                SSL_renegotiate(ssl);
+                r = 1;
+            }
+        }
+        if ((sb->renegotiate_timeout > 0) && (!r)) {
+            unsigned long tm;
+
+            tm = (unsigned long)time(NULL);
+            if (tm > sb->last_time + sb->renegotiate_timeout) {
+                sb->last_time = tm;
+                sb->num_renegotiates++;
+                SSL_renegotiate(ssl);
+            }
+        }
+
+        break;
+    case SSL_ERROR_WANT_READ:
+        BIO_set_retry_read(b);
+        break;
+    case SSL_ERROR_WANT_WRITE:
+        BIO_set_retry_write(b);
+        break;
+    case SSL_ERROR_WANT_X509_LOOKUP:
+        BIO_set_retry_special(b);
+        retry_reason = BIO_RR_SSL_X509_LOOKUP;
+        break;
+    case SSL_ERROR_WANT_ACCEPT:
+        BIO_set_retry_special(b);
+        retry_reason = BIO_RR_ACCEPT;
+        break;
+    case SSL_ERROR_WANT_CONNECT:
+        BIO_set_retry_special(b);
+        retry_reason = BIO_RR_CONNECT;
+        break;
+    case SSL_ERROR_SYSCALL:
+    case SSL_ERROR_SSL:
+    case SSL_ERROR_ZERO_RETURN:
+    default:
+        break;
+    }
+
+    BIO_set_retry_reason(b, retry_reason);
+    return (ret);
+}
+
+static int ssl_write(BIO *b, const char *out, int outl)
+{
+    int ret, r = 0;
+    int retry_reason = 0;
+    SSL *ssl;
+    BIO_SSL *bs;
+
+    if (out == NULL)
+        return (0);
+    bs = BIO_get_data(b);
+    ssl = bs->ssl;
+
+    BIO_clear_retry_flags(b);
+
+    /*
+     * ret=SSL_do_handshake(ssl); if (ret > 0)
+     */
+    ret = SSL_write(ssl, out, outl);
+
+    switch (SSL_get_error(ssl, ret)) {
+    case SSL_ERROR_NONE:
+        if (ret <= 0)
+            break;
+        if (bs->renegotiate_count > 0) {
+            bs->byte_count += ret;
+            if (bs->byte_count > bs->renegotiate_count) {
+                bs->byte_count = 0;
+                bs->num_renegotiates++;
+                SSL_renegotiate(ssl);
+                r = 1;
+            }
+        }
+        if ((bs->renegotiate_timeout > 0) && (!r)) {
+            unsigned long tm;
+
+            tm = (unsigned long)time(NULL);
+            if (tm > bs->last_time + bs->renegotiate_timeout) {
+                bs->last_time = tm;
+                bs->num_renegotiates++;
+                SSL_renegotiate(ssl);
+            }
+        }
+        break;
+    case SSL_ERROR_WANT_WRITE:
+        BIO_set_retry_write(b);
+        break;
+    case SSL_ERROR_WANT_READ:
+        BIO_set_retry_read(b);
+        break;
+    case SSL_ERROR_WANT_X509_LOOKUP:
+        BIO_set_retry_special(b);
+        retry_reason = BIO_RR_SSL_X509_LOOKUP;
+        break;
+    case SSL_ERROR_WANT_CONNECT:
+        BIO_set_retry_special(b);
+        retry_reason = BIO_RR_CONNECT;
+    case SSL_ERROR_SYSCALL:
+    case SSL_ERROR_SSL:
+    default:
+        break;
+    }
+
+    BIO_set_retry_reason(b, retry_reason);
+    return ret;
+}
+
+static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    SSL **sslp, *ssl;
+    BIO_SSL *bs, *dbs;
+    BIO *dbio, *bio;
+    long ret = 1;
+    BIO *next;
+
+    bs = BIO_get_data(b);
+    next = BIO_next(b);
+    ssl = bs->ssl;
+    if ((ssl == NULL) && (cmd != BIO_C_SET_SSL))
+        return (0);
+    switch (cmd) {
+    case BIO_CTRL_RESET:
+        SSL_shutdown(ssl);
+
+        if (ssl->handshake_func == ssl->method->ssl_connect)
+            SSL_set_connect_state(ssl);
+        else if (ssl->handshake_func == ssl->method->ssl_accept)
+            SSL_set_accept_state(ssl);
+
+        if (!SSL_clear(ssl)) {
+            ret = 0;
+            break;
+        }
+
+        if (next != NULL)
+            ret = BIO_ctrl(next, cmd, num, ptr);
+        else if (ssl->rbio != NULL)
+            ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);
+        else
+            ret = 1;
+        break;
+    case BIO_CTRL_INFO:
+        ret = 0;
+        break;
+    case BIO_C_SSL_MODE:
+        if (num)                /* client mode */
+            SSL_set_connect_state(ssl);
+        else
+            SSL_set_accept_state(ssl);
+        break;
+    case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT:
+        ret = bs->renegotiate_timeout;
+        if (num < 60)
+            num = 5;
+        bs->renegotiate_timeout = (unsigned long)num;
+        bs->last_time = (unsigned long)time(NULL);
+        break;
+    case BIO_C_SET_SSL_RENEGOTIATE_BYTES:
+        ret = bs->renegotiate_count;
+        if ((long)num >= 512)
+            bs->renegotiate_count = (unsigned long)num;
+        break;
+    case BIO_C_GET_SSL_NUM_RENEGOTIATES:
+        ret = bs->num_renegotiates;
+        break;
+    case BIO_C_SET_SSL:
+        if (ssl != NULL) {
+            ssl_free(b);
+            if (!ssl_new(b))
+                return 0;
+        }
+        BIO_set_shutdown(b, num);
+        ssl = (SSL *)ptr;
+        bs->ssl = ssl;
+        bio = SSL_get_rbio(ssl);
+        if (bio != NULL) {
+            if (next != NULL)
+                BIO_push(bio, next);
+            BIO_set_next(b, bio);
+            BIO_up_ref(bio);
+        }
+        BIO_set_init(b, 1);
+        break;
+    case BIO_C_GET_SSL:
+        if (ptr != NULL) {
+            sslp = (SSL **)ptr;
+            *sslp = ssl;
+        } else
+            ret = 0;
+        break;
+    case BIO_CTRL_GET_CLOSE:
+        ret = BIO_get_shutdown(b);
+        break;
+    case BIO_CTRL_SET_CLOSE:
+        BIO_set_shutdown(b, (int)num);
+        break;
+    case BIO_CTRL_WPENDING:
+        ret = BIO_ctrl(ssl->wbio, cmd, num, ptr);
+        break;
+    case BIO_CTRL_PENDING:
+        ret = SSL_pending(ssl);
+        if (ret == 0)
+            ret = BIO_pending(ssl->rbio);
+        break;
+    case BIO_CTRL_FLUSH:
+        BIO_clear_retry_flags(b);
+        ret = BIO_ctrl(ssl->wbio, cmd, num, ptr);
+        BIO_copy_next_retry(b);
+        break;
+    case BIO_CTRL_PUSH:
+        if ((next != NULL) && (next != ssl->rbio)) {
+            /*
+             * We are going to pass ownership of next to the SSL object...but
+             * we don't own a reference to pass yet - so up ref
+             */
+            BIO_up_ref(next);
+            SSL_set_bio(ssl, next, next);
+        }
+        break;
+    case BIO_CTRL_POP:
+        /* Only detach if we are the BIO explicitly being popped */
+        if (b == ptr) {
+            /* This will clear the reference we obtained during push */
+            SSL_set_bio(ssl, NULL, NULL);
+        }
+        break;
+    case BIO_C_DO_STATE_MACHINE:
+        BIO_clear_retry_flags(b);
+
+        BIO_set_retry_reason(b, 0);
+        ret = (int)SSL_do_handshake(ssl);
+
+        switch (SSL_get_error(ssl, (int)ret)) {
+        case SSL_ERROR_WANT_READ:
+            BIO_set_flags(b, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY);
+            break;
+        case SSL_ERROR_WANT_WRITE:
+            BIO_set_flags(b, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY);
+            break;
+        case SSL_ERROR_WANT_CONNECT:
+            BIO_set_flags(b, BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY);
+            BIO_set_retry_reason(b, BIO_get_retry_reason(next));
+            break;
+        case SSL_ERROR_WANT_X509_LOOKUP:
+            BIO_set_retry_special(b);
+            BIO_set_retry_reason(b, BIO_RR_SSL_X509_LOOKUP);
+            break;
+        default:
+            break;
+        }
+        break;
+    case BIO_CTRL_DUP:
+        dbio = (BIO *)ptr;
+        dbs = BIO_get_data(dbio);
+        SSL_free(dbs->ssl);
+        dbs->ssl = SSL_dup(ssl);
+        dbs->num_renegotiates = bs->num_renegotiates;
+        dbs->renegotiate_count = bs->renegotiate_count;
+        dbs->byte_count = bs->byte_count;
+        dbs->renegotiate_timeout = bs->renegotiate_timeout;
+        dbs->last_time = bs->last_time;
+        ret = (dbs->ssl != NULL);
+        break;
+    case BIO_C_GET_FD:
+        ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);
+        break;
+    case BIO_CTRL_SET_CALLBACK:
+        {
+#if 0                           /* FIXME: Should this be used? -- Richard
+                                 * Levitte */
+            SSLerr(SSL_F_SSL_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+            ret = -1;
+#else
+            ret = 0;
+#endif
+        }
+        break;
+    case BIO_CTRL_GET_CALLBACK:
+        {
+            void (**fptr) (const SSL *xssl, int type, int val);
+
+            fptr = (void (**)(const SSL *xssl, int type, int val))ptr;
+            *fptr = SSL_get_info_callback(ssl);
+        }
+        break;
+    default:
+        ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);
+        break;
+    }
+    return (ret);
+}
+
+static long ssl_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+    SSL *ssl;
+    BIO_SSL *bs;
+    long ret = 1;
+
+    bs = BIO_get_data(b);
+    ssl = bs->ssl;
+    switch (cmd) {
+    case BIO_CTRL_SET_CALLBACK:
+        {
+            /*
+             * FIXME: setting this via a completely different prototype seems
+             * like a crap idea
+             */
+            SSL_set_info_callback(ssl, (void (*)(const SSL *, int, int))fp);
+        }
+        break;
+    default:
+        ret = BIO_callback_ctrl(ssl->rbio, cmd, fp);
+        break;
+    }
+    return (ret);
+}
+
+static int ssl_puts(BIO *bp, const char *str)
+{
+    int n, ret;
+
+    n = strlen(str);
+    ret = BIO_write(bp, str, n);
+    return (ret);
+}
+
+BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx)
+{
+#ifndef OPENSSL_NO_SOCK
+    BIO *ret = NULL, *buf = NULL, *ssl = NULL;
+
+    if ((buf = BIO_new(BIO_f_buffer())) == NULL)
+        return (NULL);
+    if ((ssl = BIO_new_ssl_connect(ctx)) == NULL)
+        goto err;
+    if ((ret = BIO_push(buf, ssl)) == NULL)
+        goto err;
+    return (ret);
+ err:
+    BIO_free(buf);
+    BIO_free(ssl);
+#endif
+    return (NULL);
+}
+
+BIO *BIO_new_ssl_connect(SSL_CTX *ctx)
+{
+#ifndef OPENSSL_NO_SOCK
+    BIO *ret = NULL, *con = NULL, *ssl = NULL;
+
+    if ((con = BIO_new(BIO_s_connect())) == NULL)
+        return (NULL);
+    if ((ssl = BIO_new_ssl(ctx, 1)) == NULL)
+        goto err;
+    if ((ret = BIO_push(ssl, con)) == NULL)
+        goto err;
+    return (ret);
+ err:
+    BIO_free(con);
+#endif
+    return (NULL);
+}
+
+BIO *BIO_new_ssl(SSL_CTX *ctx, int client)
+{
+    BIO *ret;
+    SSL *ssl;
+
+    if ((ret = BIO_new(BIO_f_ssl())) == NULL)
+        return (NULL);
+    if ((ssl = SSL_new(ctx)) == NULL) {
+        BIO_free(ret);
+        return (NULL);
+    }
+    if (client)
+        SSL_set_connect_state(ssl);
+    else
+        SSL_set_accept_state(ssl);
+
+    BIO_set_ssl(ret, ssl, BIO_CLOSE);
+    return (ret);
+}
+
+int BIO_ssl_copy_session_id(BIO *t, BIO *f)
+{
+    BIO_SSL *tdata, *fdata;
+    t = BIO_find_type(t, BIO_TYPE_SSL);
+    f = BIO_find_type(f, BIO_TYPE_SSL);
+    if ((t == NULL) || (f == NULL))
+        return 0;
+    tdata = BIO_get_data(t);
+    fdata = BIO_get_data(f);
+    if ((tdata->ssl == NULL) || (fdata->ssl == NULL))
+        return (0);
+    if (!SSL_copy_session_id(tdata->ssl, (fdata->ssl)))
+        return 0;
+    return (1);
+}
+
+void BIO_ssl_shutdown(BIO *b)
+{
+    SSL *s;
+
+    b = BIO_find_type(b, BIO_TYPE_SSL);
+    if (b == NULL)
+        return;
+
+    s = BIO_get_data(b);
+    SSL_shutdown(s);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/d1_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/d1_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/d1_lib.c	(revision 331)
@@ -0,0 +1,1087 @@
+/*
+ * Copyright 2005-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 <stdio.h>
+#define USE_SOCKETS
+#include <openssl/objects.h>
+#include <openssl/rand.h>
+#include "ssl_locl.h"
+
+#if defined(OPENSSL_SYS_VMS)
+# include <sys/timeb.h>
+#elif defined(OPENSSL_SYS_VXWORKS)
+# include <sys/times.h>
+#elif !defined(OPENSSL_SYS_WIN32)
+# include <sys/time.h>
+#endif
+
+static void get_current_time(struct timeval *t);
+static int dtls1_set_handshake_header(SSL *s, int type, unsigned long len);
+static int dtls1_handshake_write(SSL *s);
+static unsigned int dtls1_link_min_mtu(void);
+
+/* XDTLS:  figure out the right values */
+static const unsigned int g_probable_mtu[] = { 1500, 512, 256 };
+
+const SSL3_ENC_METHOD DTLSv1_enc_data = {
+    tls1_enc,
+    tls1_mac,
+    tls1_setup_key_block,
+    tls1_generate_master_secret,
+    tls1_change_cipher_state,
+    tls1_final_finish_mac,
+    TLS1_FINISH_MAC_LENGTH,
+    TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
+    TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
+    tls1_alert_code,
+    tls1_export_keying_material,
+    SSL_ENC_FLAG_DTLS | SSL_ENC_FLAG_EXPLICIT_IV,
+    DTLS1_HM_HEADER_LENGTH,
+    dtls1_set_handshake_header,
+    dtls1_handshake_write
+};
+
+const SSL3_ENC_METHOD DTLSv1_2_enc_data = {
+    tls1_enc,
+    tls1_mac,
+    tls1_setup_key_block,
+    tls1_generate_master_secret,
+    tls1_change_cipher_state,
+    tls1_final_finish_mac,
+    TLS1_FINISH_MAC_LENGTH,
+    TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
+    TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
+    tls1_alert_code,
+    tls1_export_keying_material,
+    SSL_ENC_FLAG_DTLS | SSL_ENC_FLAG_EXPLICIT_IV | SSL_ENC_FLAG_SIGALGS
+        | SSL_ENC_FLAG_SHA256_PRF | SSL_ENC_FLAG_TLS1_2_CIPHERS,
+    DTLS1_HM_HEADER_LENGTH,
+    dtls1_set_handshake_header,
+    dtls1_handshake_write
+};
+
+long dtls1_default_timeout(void)
+{
+    /*
+     * 2 hours, the 24 hours mentioned in the DTLSv1 spec is way too long for
+     * http, the cache would over fill
+     */
+    return (60 * 60 * 2);
+}
+
+int dtls1_new(SSL *s)
+{
+    DTLS1_STATE *d1;
+
+    if (!DTLS_RECORD_LAYER_new(&s->rlayer)) {
+        return 0;
+    }
+
+    if (!ssl3_new(s))
+        return (0);
+    if ((d1 = OPENSSL_zalloc(sizeof(*d1))) == NULL) {
+        ssl3_free(s);
+        return (0);
+    }
+
+    d1->buffered_messages = pqueue_new();
+    d1->sent_messages = pqueue_new();
+
+    if (s->server) {
+        d1->cookie_len = sizeof(s->d1->cookie);
+    }
+
+    d1->link_mtu = 0;
+    d1->mtu = 0;
+
+    if (d1->buffered_messages == NULL || d1->sent_messages == NULL) {
+        pqueue_free(d1->buffered_messages);
+        pqueue_free(d1->sent_messages);
+        OPENSSL_free(d1);
+        ssl3_free(s);
+        return (0);
+    }
+
+    s->d1 = d1;
+    s->method->ssl_clear(s);
+    return (1);
+}
+
+static void dtls1_clear_queues(SSL *s)
+{
+    dtls1_clear_received_buffer(s);
+    dtls1_clear_sent_buffer(s);
+}
+
+void dtls1_clear_received_buffer(SSL *s)
+{
+    pitem *item = NULL;
+    hm_fragment *frag = NULL;
+
+    while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) {
+        frag = (hm_fragment *)item->data;
+        dtls1_hm_fragment_free(frag);
+        pitem_free(item);
+    }
+}
+
+void dtls1_clear_sent_buffer(SSL *s)
+{
+    pitem *item = NULL;
+    hm_fragment *frag = NULL;
+
+    while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) {
+        frag = (hm_fragment *)item->data;
+        dtls1_hm_fragment_free(frag);
+        pitem_free(item);
+    }
+}
+
+
+void dtls1_free(SSL *s)
+{
+    DTLS_RECORD_LAYER_free(&s->rlayer);
+
+    ssl3_free(s);
+
+    dtls1_clear_queues(s);
+
+    pqueue_free(s->d1->buffered_messages);
+    pqueue_free(s->d1->sent_messages);
+
+    OPENSSL_free(s->d1);
+    s->d1 = NULL;
+}
+
+void dtls1_clear(SSL *s)
+{
+    pqueue *buffered_messages;
+    pqueue *sent_messages;
+    unsigned int mtu;
+    unsigned int link_mtu;
+
+    DTLS_RECORD_LAYER_clear(&s->rlayer);
+
+    if (s->d1) {
+        buffered_messages = s->d1->buffered_messages;
+        sent_messages = s->d1->sent_messages;
+        mtu = s->d1->mtu;
+        link_mtu = s->d1->link_mtu;
+
+        dtls1_clear_queues(s);
+
+        memset(s->d1, 0, sizeof(*s->d1));
+
+        if (s->server) {
+            s->d1->cookie_len = sizeof(s->d1->cookie);
+        }
+
+        if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) {
+            s->d1->mtu = mtu;
+            s->d1->link_mtu = link_mtu;
+        }
+
+        s->d1->buffered_messages = buffered_messages;
+        s->d1->sent_messages = sent_messages;
+    }
+
+    ssl3_clear(s);
+
+    if (s->method->version == DTLS_ANY_VERSION)
+        s->version = DTLS_MAX_VERSION;
+#ifndef OPENSSL_NO_DTLS1_METHOD
+    else if (s->options & SSL_OP_CISCO_ANYCONNECT)
+        s->client_version = s->version = DTLS1_BAD_VER;
+#endif
+    else
+        s->version = s->method->version;
+}
+
+long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
+{
+    int ret = 0;
+
+    switch (cmd) {
+    case DTLS_CTRL_GET_TIMEOUT:
+        if (dtls1_get_timeout(s, (struct timeval *)parg) != NULL) {
+            ret = 1;
+        }
+        break;
+    case DTLS_CTRL_HANDLE_TIMEOUT:
+        ret = dtls1_handle_timeout(s);
+        break;
+    case DTLS_CTRL_SET_LINK_MTU:
+        if (larg < (long)dtls1_link_min_mtu())
+            return 0;
+        s->d1->link_mtu = larg;
+        return 1;
+    case DTLS_CTRL_GET_LINK_MIN_MTU:
+        return (long)dtls1_link_min_mtu();
+    case SSL_CTRL_SET_MTU:
+        /*
+         *  We may not have a BIO set yet so can't call dtls1_min_mtu()
+         *  We'll have to make do with dtls1_link_min_mtu() and max overhead
+         */
+        if (larg < (long)dtls1_link_min_mtu() - DTLS1_MAX_MTU_OVERHEAD)
+            return 0;
+        s->d1->mtu = larg;
+        return larg;
+    default:
+        ret = ssl3_ctrl(s, cmd, larg, parg);
+        break;
+    }
+    return (ret);
+}
+
+void dtls1_start_timer(SSL *s)
+{
+#ifndef OPENSSL_NO_SCTP
+    /* Disable timer for SCTP */
+    if (BIO_dgram_is_sctp(SSL_get_wbio(s))) {
+        memset(&s->d1->next_timeout, 0, sizeof(s->d1->next_timeout));
+        return;
+    }
+#endif
+
+    /* If timer is not set, initialize duration with 1 second */
+    if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) {
+        s->d1->timeout_duration = 1;
+    }
+
+    /* Set timeout to current time */
+    get_current_time(&(s->d1->next_timeout));
+
+    /* Add duration to current time */
+    s->d1->next_timeout.tv_sec += s->d1->timeout_duration;
+    BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
+             &(s->d1->next_timeout));
+}
+
+struct timeval *dtls1_get_timeout(SSL *s, struct timeval *timeleft)
+{
+    struct timeval timenow;
+
+    /* If no timeout is set, just return NULL */
+    if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) {
+        return NULL;
+    }
+
+    /* Get current time */
+    get_current_time(&timenow);
+
+    /* If timer already expired, set remaining time to 0 */
+    if (s->d1->next_timeout.tv_sec < timenow.tv_sec ||
+        (s->d1->next_timeout.tv_sec == timenow.tv_sec &&
+         s->d1->next_timeout.tv_usec <= timenow.tv_usec)) {
+        memset(timeleft, 0, sizeof(*timeleft));
+        return timeleft;
+    }
+
+    /* Calculate time left until timer expires */
+    memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval));
+    timeleft->tv_sec -= timenow.tv_sec;
+    timeleft->tv_usec -= timenow.tv_usec;
+    if (timeleft->tv_usec < 0) {
+        timeleft->tv_sec--;
+        timeleft->tv_usec += 1000000;
+    }
+
+    /*
+     * If remaining time is less than 15 ms, set it to 0 to prevent issues
+     * because of small divergences with socket timeouts.
+     */
+    if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) {
+        memset(timeleft, 0, sizeof(*timeleft));
+    }
+
+    return timeleft;
+}
+
+int dtls1_is_timer_expired(SSL *s)
+{
+    struct timeval timeleft;
+
+    /* Get time left until timeout, return false if no timer running */
+    if (dtls1_get_timeout(s, &timeleft) == NULL) {
+        return 0;
+    }
+
+    /* Return false if timer is not expired yet */
+    if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) {
+        return 0;
+    }
+
+    /* Timer expired, so return true */
+    return 1;
+}
+
+void dtls1_double_timeout(SSL *s)
+{
+    s->d1->timeout_duration *= 2;
+    if (s->d1->timeout_duration > 60)
+        s->d1->timeout_duration = 60;
+    dtls1_start_timer(s);
+}
+
+void dtls1_stop_timer(SSL *s)
+{
+    /* Reset everything */
+    memset(&s->d1->timeout, 0, sizeof(s->d1->timeout));
+    memset(&s->d1->next_timeout, 0, sizeof(s->d1->next_timeout));
+    s->d1->timeout_duration = 1;
+    BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
+             &(s->d1->next_timeout));
+    /* Clear retransmission buffer */
+    dtls1_clear_sent_buffer(s);
+}
+
+int dtls1_check_timeout_num(SSL *s)
+{
+    unsigned int mtu;
+
+    s->d1->timeout.num_alerts++;
+
+    /* Reduce MTU after 2 unsuccessful retransmissions */
+    if (s->d1->timeout.num_alerts > 2
+        && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) {
+        mtu =
+            BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
+        if (mtu < s->d1->mtu)
+            s->d1->mtu = mtu;
+    }
+
+    if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) {
+        /* fail the connection, enough alerts have been sent */
+        SSLerr(SSL_F_DTLS1_CHECK_TIMEOUT_NUM, SSL_R_READ_TIMEOUT_EXPIRED);
+        return -1;
+    }
+
+    return 0;
+}
+
+int dtls1_handle_timeout(SSL *s)
+{
+    /* if no timer is expired, don't do anything */
+    if (!dtls1_is_timer_expired(s)) {
+        return 0;
+    }
+
+    dtls1_double_timeout(s);
+
+    if (dtls1_check_timeout_num(s) < 0)
+        return -1;
+
+    s->d1->timeout.read_timeouts++;
+    if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) {
+        s->d1->timeout.read_timeouts = 1;
+    }
+#ifndef OPENSSL_NO_HEARTBEATS
+    if (s->tlsext_hb_pending) {
+        s->tlsext_hb_pending = 0;
+        return dtls1_heartbeat(s);
+    }
+#endif
+
+    dtls1_start_timer(s);
+    return dtls1_retransmit_buffered_messages(s);
+}
+
+static void get_current_time(struct timeval *t)
+{
+#if defined(_WIN32)
+    SYSTEMTIME st;
+    union {
+        unsigned __int64 ul;
+        FILETIME ft;
+    } now;
+
+    GetSystemTime(&st);
+    SystemTimeToFileTime(&st, &now.ft);
+    /* re-bias to 1/1/1970 */
+# ifdef  __MINGW32__
+    now.ul -= 116444736000000000ULL;
+# else
+    /* *INDENT-OFF* */
+    now.ul -= 116444736000000000UI64;
+    /* *INDENT-ON* */
+# endif
+    t->tv_sec = (long)(now.ul / 10000000);
+    t->tv_usec = ((int)(now.ul % 10000000)) / 10;
+#elif defined(OPENSSL_SYS_VMS)
+    struct timeb tb;
+    ftime(&tb);
+    t->tv_sec = (long)tb.time;
+    t->tv_usec = (long)tb.millitm * 1000;
+#else
+    gettimeofday(t, NULL);
+#endif
+}
+
+#define LISTEN_SUCCESS              2
+#define LISTEN_SEND_VERIFY_REQUEST  1
+
+#ifndef OPENSSL_NO_SOCK
+int DTLSv1_listen(SSL *s, BIO_ADDR *client)
+{
+    int next, n, ret = 0, clearpkt = 0;
+    unsigned char cookie[DTLS1_COOKIE_LENGTH];
+    unsigned char seq[SEQ_NUM_SIZE];
+    const unsigned char *data;
+    unsigned char *p, *buf;
+    unsigned long reclen, fragoff, fraglen, msglen;
+    unsigned int rectype, versmajor, msgseq, msgtype, clientvers, cookielen;
+    BIO *rbio, *wbio;
+    BUF_MEM *bufm;
+    BIO_ADDR *tmpclient = NULL;
+    PACKET pkt, msgpkt, msgpayload, session, cookiepkt;
+
+    if (s->handshake_func == NULL) {
+        /* Not properly initialized yet */
+        SSL_set_accept_state(s);
+    }
+
+    /* Ensure there is no state left over from a previous invocation */
+    if (!SSL_clear(s))
+        return -1;
+
+    ERR_clear_error();
+
+    rbio = SSL_get_rbio(s);
+    wbio = SSL_get_wbio(s);
+
+    if (!rbio || !wbio) {
+        SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_BIO_NOT_SET);
+        return -1;
+    }
+
+    /*
+     * We only peek at incoming ClientHello's until we're sure we are going to
+     * to respond with a HelloVerifyRequest. If its a ClientHello with a valid
+     * cookie then we leave it in the BIO for accept to handle.
+     */
+    BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 1, NULL);
+
+    /*
+     * Note: This check deliberately excludes DTLS1_BAD_VER because that version
+     * requires the MAC to be calculated *including* the first ClientHello
+     * (without the cookie). Since DTLSv1_listen is stateless that cannot be
+     * supported. DTLS1_BAD_VER must use cookies in a stateful manner (e.g. via
+     * SSL_accept)
+     */
+    if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00)) {
+        SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_UNSUPPORTED_SSL_VERSION);
+        return -1;
+    }
+
+    if (s->init_buf == NULL) {
+        if ((bufm = BUF_MEM_new()) == NULL) {
+            SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_MALLOC_FAILURE);
+            return -1;
+        }
+
+        if (!BUF_MEM_grow(bufm, SSL3_RT_MAX_PLAIN_LENGTH)) {
+            BUF_MEM_free(bufm);
+            SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_MALLOC_FAILURE);
+            return -1;
+        }
+        s->init_buf = bufm;
+    }
+    buf = (unsigned char *)s->init_buf->data;
+
+    do {
+        /* Get a packet */
+
+        clear_sys_error();
+        /*
+         * Technically a ClientHello could be SSL3_RT_MAX_PLAIN_LENGTH
+         * + DTLS1_RT_HEADER_LENGTH bytes long. Normally init_buf does not store
+         * the record header as well, but we do here. We've set up init_buf to
+         * be the standard size for simplicity. In practice we shouldn't ever
+         * receive a ClientHello as long as this. If we do it will get dropped
+         * in the record length check below.
+         */
+        n = BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH);
+
+        if (n <= 0) {
+            if (BIO_should_retry(rbio)) {
+                /* Non-blocking IO */
+                goto end;
+            }
+            return -1;
+        }
+
+        /* If we hit any problems we need to clear this packet from the BIO */
+        clearpkt = 1;
+
+        if (!PACKET_buf_init(&pkt, buf, n)) {
+            SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_INTERNAL_ERROR);
+            return -1;
+        }
+
+        /*
+         * Parse the received record. If there are any problems with it we just
+         * dump it - with no alert. RFC6347 says this "Unlike TLS, DTLS is
+         * resilient in the face of invalid records (e.g., invalid formatting,
+         * length, MAC, etc.).  In general, invalid records SHOULD be silently
+         * discarded, thus preserving the association; however, an error MAY be
+         * logged for diagnostic purposes."
+         */
+
+        /* this packet contained a partial record, dump it */
+        if (n < DTLS1_RT_HEADER_LENGTH) {
+            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_RECORD_TOO_SMALL);
+            goto end;
+        }
+
+        if (s->msg_callback)
+            s->msg_callback(0, 0, SSL3_RT_HEADER, buf,
+                            DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg);
+
+        /* Get the record header */
+        if (!PACKET_get_1(&pkt, &rectype)
+            || !PACKET_get_1(&pkt, &versmajor)) {
+            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH);
+            goto end;
+        }
+
+        if (rectype != SSL3_RT_HANDSHAKE) {
+            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_UNEXPECTED_MESSAGE);
+            goto end;
+        }
+
+        /*
+         * Check record version number. We only check that the major version is
+         * the same.
+         */
+        if (versmajor != DTLS1_VERSION_MAJOR) {
+            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_BAD_PROTOCOL_VERSION_NUMBER);
+            goto end;
+        }
+
+        if (!PACKET_forward(&pkt, 1)
+            /* Save the sequence number: 64 bits, with top 2 bytes = epoch */
+            || !PACKET_copy_bytes(&pkt, seq, SEQ_NUM_SIZE)
+            || !PACKET_get_length_prefixed_2(&pkt, &msgpkt)) {
+            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH);
+            goto end;
+        }
+        /*
+         * We allow data remaining at the end of the packet because there could
+         * be a second record (but we ignore it)
+         */
+
+        /* This is an initial ClientHello so the epoch has to be 0 */
+        if (seq[0] != 0 || seq[1] != 0) {
+            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_UNEXPECTED_MESSAGE);
+            goto end;
+        }
+
+        /* Get a pointer to the raw message for the later callback */
+        data = PACKET_data(&msgpkt);
+
+        /* Finished processing the record header, now process the message */
+        if (!PACKET_get_1(&msgpkt, &msgtype)
+            || !PACKET_get_net_3(&msgpkt, &msglen)
+            || !PACKET_get_net_2(&msgpkt, &msgseq)
+            || !PACKET_get_net_3(&msgpkt, &fragoff)
+            || !PACKET_get_net_3(&msgpkt, &fraglen)
+            || !PACKET_get_sub_packet(&msgpkt, &msgpayload, fraglen)
+            || PACKET_remaining(&msgpkt) != 0) {
+            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH);
+            goto end;
+        }
+
+        if (msgtype != SSL3_MT_CLIENT_HELLO) {
+            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_UNEXPECTED_MESSAGE);
+            goto end;
+        }
+
+        /* Message sequence number can only be 0 or 1 */
+        if (msgseq > 2) {
+            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_INVALID_SEQUENCE_NUMBER);
+            goto end;
+        }
+
+        /*
+         * We don't support fragment reassembly for ClientHellos whilst
+         * listening because that would require server side state (which is
+         * against the whole point of the ClientHello/HelloVerifyRequest
+         * mechanism). Instead we only look at the first ClientHello fragment
+         * and require that the cookie must be contained within it.
+         */
+        if (fragoff != 0 || fraglen > msglen) {
+            /* Non initial ClientHello fragment (or bad fragment) */
+            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_FRAGMENTED_CLIENT_HELLO);
+            goto end;
+        }
+
+        if (s->msg_callback)
+            s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, data,
+                            fraglen + DTLS1_HM_HEADER_LENGTH, s,
+                            s->msg_callback_arg);
+
+        if (!PACKET_get_net_2(&msgpayload, &clientvers)) {
+            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH);
+            goto end;
+        }
+
+        /*
+         * Verify client version is supported
+         */
+        if (DTLS_VERSION_LT(clientvers, (unsigned int)s->method->version) &&
+            s->method->version != DTLS_ANY_VERSION) {
+            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_WRONG_VERSION_NUMBER);
+            goto end;
+        }
+
+        if (!PACKET_forward(&msgpayload, SSL3_RANDOM_SIZE)
+            || !PACKET_get_length_prefixed_1(&msgpayload, &session)
+            || !PACKET_get_length_prefixed_1(&msgpayload, &cookiepkt)) {
+            /*
+             * Could be malformed or the cookie does not fit within the initial
+             * ClientHello fragment. Either way we can't handle it.
+             */
+            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH);
+            goto end;
+        }
+
+        /*
+         * Check if we have a cookie or not. If not we need to send a
+         * HelloVerifyRequest.
+         */
+        if (PACKET_remaining(&cookiepkt) == 0) {
+            next = LISTEN_SEND_VERIFY_REQUEST;
+        } else {
+            /*
+             * We have a cookie, so lets check it.
+             */
+            if (s->ctx->app_verify_cookie_cb == NULL) {
+                SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_NO_VERIFY_COOKIE_CALLBACK);
+                /* This is fatal */
+                return -1;
+            }
+            if (s->ctx->app_verify_cookie_cb(s, PACKET_data(&cookiepkt),
+                                             PACKET_remaining(&cookiepkt)) ==
+                0) {
+                /*
+                 * We treat invalid cookies in the same was as no cookie as
+                 * per RFC6347
+                 */
+                next = LISTEN_SEND_VERIFY_REQUEST;
+            } else {
+                /* Cookie verification succeeded */
+                next = LISTEN_SUCCESS;
+            }
+        }
+
+        if (next == LISTEN_SEND_VERIFY_REQUEST) {
+            /*
+             * There was no cookie in the ClientHello so we need to send a
+             * HelloVerifyRequest. If this fails we do not worry about trying
+             * to resend, we just drop it.
+             */
+
+            /*
+             * Dump the read packet, we don't need it any more. Ignore return
+             * value
+             */
+            BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 0, NULL);
+            BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH);
+            BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 1, NULL);
+
+            /* Generate the cookie */
+            if (s->ctx->app_gen_cookie_cb == NULL ||
+                s->ctx->app_gen_cookie_cb(s, cookie, &cookielen) == 0 ||
+                cookielen > 255) {
+                SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_COOKIE_GEN_CALLBACK_FAILURE);
+                /* This is fatal */
+                return -1;
+            }
+
+            p = &buf[DTLS1_RT_HEADER_LENGTH];
+            msglen = dtls_raw_hello_verify_request(p + DTLS1_HM_HEADER_LENGTH,
+                                                   cookie, cookielen);
+
+            *p++ = DTLS1_MT_HELLO_VERIFY_REQUEST;
+
+            /* Message length */
+            l2n3(msglen, p);
+
+            /* Message sequence number is always 0 for a HelloVerifyRequest */
+            s2n(0, p);
+
+            /*
+             * We never fragment a HelloVerifyRequest, so fragment offset is 0
+             * and fragment length is message length
+             */
+            l2n3(0, p);
+            l2n3(msglen, p);
+
+            /* Set reclen equal to length of whole handshake message */
+            reclen = msglen + DTLS1_HM_HEADER_LENGTH;
+
+            /* Add the record header */
+            p = buf;
+
+            *(p++) = SSL3_RT_HANDSHAKE;
+            /*
+             * Special case: for hello verify request, client version 1.0 and we
+             * haven't decided which version to use yet send back using version
+             * 1.0 header: otherwise some clients will ignore it.
+             */
+            if (s->method->version == DTLS_ANY_VERSION) {
+                *(p++) = DTLS1_VERSION >> 8;
+                *(p++) = DTLS1_VERSION & 0xff;
+            } else {
+                *(p++) = s->version >> 8;
+                *(p++) = s->version & 0xff;
+            }
+
+            /*
+             * Record sequence number is always the same as in the received
+             * ClientHello
+             */
+            memcpy(p, seq, SEQ_NUM_SIZE);
+            p += SEQ_NUM_SIZE;
+
+            /* Length */
+            s2n(reclen, p);
+
+            /*
+             * Set reclen equal to length of whole record including record
+             * header
+             */
+            reclen += DTLS1_RT_HEADER_LENGTH;
+
+            if (s->msg_callback)
+                s->msg_callback(1, 0, SSL3_RT_HEADER, buf,
+                                DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg);
+
+            if ((tmpclient = BIO_ADDR_new()) == NULL) {
+                SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_MALLOC_FAILURE);
+                goto end;
+            }
+
+            /*
+             * This is unnecessary if rbio and wbio are one and the same - but
+             * maybe they're not. We ignore errors here - some BIOs do not
+             * support this.
+             */
+            if (BIO_dgram_get_peer(rbio, tmpclient) > 0) {
+                (void)BIO_dgram_set_peer(wbio, tmpclient);
+            }
+            BIO_ADDR_free(tmpclient);
+            tmpclient = NULL;
+
+            if (BIO_write(wbio, buf, reclen) < (int)reclen) {
+                if (BIO_should_retry(wbio)) {
+                    /*
+                     * Non-blocking IO...but we're stateless, so we're just
+                     * going to drop this packet.
+                     */
+                    goto end;
+                }
+                return -1;
+            }
+
+            if (BIO_flush(wbio) <= 0) {
+                if (BIO_should_retry(wbio)) {
+                    /*
+                     * Non-blocking IO...but we're stateless, so we're just
+                     * going to drop this packet.
+                     */
+                    goto end;
+                }
+                return -1;
+            }
+        }
+    } while (next != LISTEN_SUCCESS);
+
+    /*
+     * Set expected sequence numbers to continue the handshake.
+     */
+    s->d1->handshake_read_seq = 1;
+    s->d1->handshake_write_seq = 1;
+    s->d1->next_handshake_write_seq = 1;
+    DTLS_RECORD_LAYER_set_write_sequence(&s->rlayer, seq);
+
+    /*
+     * We are doing cookie exchange, so make sure we set that option in the
+     * SSL object
+     */
+    SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE);
+
+    /*
+     * Tell the state machine that we've done the initial hello verify
+     * exchange
+     */
+    ossl_statem_set_hello_verify_done(s);
+
+    /*
+     * Some BIOs may not support this. If we fail we clear the client address
+     */
+    if (BIO_dgram_get_peer(rbio, client) <= 0)
+        BIO_ADDR_clear(client);
+
+    ret = 1;
+    clearpkt = 0;
+ end:
+    BIO_ADDR_free(tmpclient);
+    BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 0, NULL);
+    if (clearpkt) {
+        /* Dump this packet. Ignore return value */
+        BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH);
+    }
+    return ret;
+}
+#endif
+
+static int dtls1_set_handshake_header(SSL *s, int htype, unsigned long len)
+{
+    dtls1_set_message_header(s, htype, len, 0, len);
+    s->init_num = (int)len + DTLS1_HM_HEADER_LENGTH;
+    s->init_off = 0;
+    /* Buffer the message to handle re-xmits */
+
+    if (!dtls1_buffer_message(s, 0))
+        return 0;
+
+    return 1;
+}
+
+static int dtls1_handshake_write(SSL *s)
+{
+    return dtls1_do_write(s, SSL3_RT_HANDSHAKE);
+}
+
+#ifndef OPENSSL_NO_HEARTBEATS
+
+# define HEARTBEAT_SIZE(payload, padding) ( \
+    1 /* heartbeat type */ + \
+    2 /* heartbeat length */ + \
+    (payload) + (padding))
+
+# define HEARTBEAT_SIZE_STD(payload) HEARTBEAT_SIZE(payload, 16)
+
+int dtls1_process_heartbeat(SSL *s, unsigned char *p, unsigned int length)
+{
+    unsigned char *pl;
+    unsigned short hbtype;
+    unsigned int payload;
+    unsigned int padding = 16;  /* Use minimum padding */
+
+    if (s->msg_callback)
+        s->msg_callback(0, s->version, DTLS1_RT_HEARTBEAT,
+                        p, length, s, s->msg_callback_arg);
+
+    /* Read type and payload length */
+    if (HEARTBEAT_SIZE_STD(0) > length)
+        return 0;               /* silently discard */
+    if (length > SSL3_RT_MAX_PLAIN_LENGTH)
+        return 0;               /* silently discard per RFC 6520 sec. 4 */
+
+    hbtype = *p++;
+    n2s(p, payload);
+    if (HEARTBEAT_SIZE_STD(payload) > length)
+        return 0;               /* silently discard per RFC 6520 sec. 4 */
+    pl = p;
+
+    if (hbtype == TLS1_HB_REQUEST) {
+        unsigned char *buffer, *bp;
+        unsigned int write_length = HEARTBEAT_SIZE(payload, padding);
+        int r;
+
+        if (write_length > SSL3_RT_MAX_PLAIN_LENGTH)
+            return 0;
+
+        /* Allocate memory for the response. */
+        buffer = OPENSSL_malloc(write_length);
+        if (buffer == NULL)
+            return -1;
+        bp = buffer;
+
+        /* Enter response type, length and copy payload */
+        *bp++ = TLS1_HB_RESPONSE;
+        s2n(payload, bp);
+        memcpy(bp, pl, payload);
+        bp += payload;
+        /* Random padding */
+        if (RAND_bytes(bp, padding) <= 0) {
+            OPENSSL_free(buffer);
+            return -1;
+        }
+
+        r = dtls1_write_bytes(s, DTLS1_RT_HEARTBEAT, buffer, write_length);
+
+        if (r >= 0 && s->msg_callback)
+            s->msg_callback(1, s->version, DTLS1_RT_HEARTBEAT,
+                            buffer, write_length, s, s->msg_callback_arg);
+
+        OPENSSL_free(buffer);
+
+        if (r < 0)
+            return r;
+    } else if (hbtype == TLS1_HB_RESPONSE) {
+        unsigned int seq;
+
+        /*
+         * We only send sequence numbers (2 bytes unsigned int), and 16
+         * random bytes, so we just try to read the sequence number
+         */
+        n2s(pl, seq);
+
+        if (payload == 18 && seq == s->tlsext_hb_seq) {
+            dtls1_stop_timer(s);
+            s->tlsext_hb_seq++;
+            s->tlsext_hb_pending = 0;
+        }
+    }
+
+    return 0;
+}
+
+int dtls1_heartbeat(SSL *s)
+{
+    unsigned char *buf, *p;
+    int ret = -1;
+    unsigned int payload = 18;  /* Sequence number + random bytes */
+    unsigned int padding = 16;  /* Use minimum padding */
+    unsigned int size;
+
+    /* Only send if peer supports and accepts HB requests... */
+    if (!(s->tlsext_heartbeat & SSL_DTLSEXT_HB_ENABLED) ||
+        s->tlsext_heartbeat & SSL_DTLSEXT_HB_DONT_SEND_REQUESTS) {
+        SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT);
+        return -1;
+    }
+
+    /* ...and there is none in flight yet... */
+    if (s->tlsext_hb_pending) {
+        SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PENDING);
+        return -1;
+    }
+
+    /* ...and no handshake in progress. */
+    if (SSL_in_init(s) || ossl_statem_get_in_handshake(s)) {
+        SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE);
+        return -1;
+    }
+
+    /*-
+     * Create HeartBeat message, we just use a sequence number
+     * as payload to distinguish different messages and add
+     * some random stuff.
+     */
+    size = HEARTBEAT_SIZE(payload, padding);
+    buf = OPENSSL_malloc(size);
+    if (buf == NULL) {
+        SSLerr(SSL_F_DTLS1_HEARTBEAT, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+    p = buf;
+    /* Message Type */
+    *p++ = TLS1_HB_REQUEST;
+    /* Payload length (18 bytes here) */
+    s2n(payload, p);
+    /* Sequence number */
+    s2n(s->tlsext_hb_seq, p);
+    /* 16 random bytes */
+    if (RAND_bytes(p, 16) <= 0) {
+        SSLerr(SSL_F_DTLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+    p += 16;
+    /* Random padding */
+    if (RAND_bytes(p, padding) <= 0) {
+        SSLerr(SSL_F_DTLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
+    ret = dtls1_write_bytes(s, DTLS1_RT_HEARTBEAT, buf, size);
+    if (ret >= 0) {
+        if (s->msg_callback)
+            s->msg_callback(1, s->version, DTLS1_RT_HEARTBEAT,
+                            buf, size, s, s->msg_callback_arg);
+
+        dtls1_start_timer(s);
+        s->tlsext_hb_pending = 1;
+    }
+
+ err:
+    OPENSSL_free(buf);
+
+    return ret;
+}
+#endif
+
+int dtls1_shutdown(SSL *s)
+{
+    int ret;
+#ifndef OPENSSL_NO_SCTP
+    BIO *wbio;
+
+    wbio = SSL_get_wbio(s);
+    if (wbio != NULL && BIO_dgram_is_sctp(wbio) &&
+        !(s->shutdown & SSL_SENT_SHUTDOWN)) {
+        ret = BIO_dgram_sctp_wait_for_dry(wbio);
+        if (ret < 0)
+            return -1;
+
+        if (ret == 0)
+            BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 1,
+                     NULL);
+    }
+#endif
+    ret = ssl3_shutdown(s);
+#ifndef OPENSSL_NO_SCTP
+    BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 0, NULL);
+#endif
+    return ret;
+}
+
+int dtls1_query_mtu(SSL *s)
+{
+    if (s->d1->link_mtu) {
+        s->d1->mtu =
+            s->d1->link_mtu - BIO_dgram_get_mtu_overhead(SSL_get_wbio(s));
+        s->d1->link_mtu = 0;
+    }
+
+    /* AHA!  Figure out the MTU, and stick to the right size */
+    if (s->d1->mtu < dtls1_min_mtu(s)) {
+        if (!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) {
+            s->d1->mtu =
+                BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
+
+            /*
+             * I've seen the kernel return bogus numbers when it doesn't know
+             * (initial write), so just make sure we have a reasonable number
+             */
+            if (s->d1->mtu < dtls1_min_mtu(s)) {
+                /* Set to min mtu */
+                s->d1->mtu = dtls1_min_mtu(s);
+                BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU,
+                         s->d1->mtu, NULL);
+            }
+        } else
+            return 0;
+    }
+    return 1;
+}
+
+static unsigned int dtls1_link_min_mtu(void)
+{
+    return (g_probable_mtu[(sizeof(g_probable_mtu) /
+                            sizeof(g_probable_mtu[0])) - 1]);
+}
+
+unsigned int dtls1_min_mtu(SSL *s)
+{
+    return dtls1_link_min_mtu() - BIO_dgram_get_mtu_overhead(SSL_get_wbio(s));
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/d1_msg.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/d1_msg.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/d1_msg.c	(revision 331)
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2005-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
+ */
+
+#define USE_SOCKETS
+#include "ssl_locl.h"
+
+int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len)
+{
+    int i;
+
+#ifndef OPENSSL_NO_SCTP
+    /*
+     * Check if we have to continue an interrupted handshake for reading
+     * belated app data with SCTP.
+     */
+    if ((SSL_in_init(s) && !ossl_statem_get_in_handshake(s)) ||
+        (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
+         ossl_statem_in_sctp_read_sock(s)))
+#else
+    if (SSL_in_init(s) && !ossl_statem_get_in_handshake(s))
+#endif
+    {
+        i = s->handshake_func(s);
+        if (i < 0)
+            return (i);
+        if (i == 0) {
+            SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES,
+                   SSL_R_SSL_HANDSHAKE_FAILURE);
+            return -1;
+        }
+    }
+
+    if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
+        SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES, SSL_R_DTLS_MESSAGE_TOO_BIG);
+        return -1;
+    }
+
+    i = dtls1_write_bytes(s, type, buf_, len);
+    return i;
+}
+
+int dtls1_dispatch_alert(SSL *s)
+{
+    int i, j;
+    void (*cb) (const SSL *ssl, int type, int val) = NULL;
+    unsigned char buf[DTLS1_AL_HEADER_LENGTH];
+    unsigned char *ptr = &buf[0];
+
+    s->s3->alert_dispatch = 0;
+
+    memset(buf, 0, sizeof(buf));
+    *ptr++ = s->s3->send_alert[0];
+    *ptr++ = s->s3->send_alert[1];
+
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+    if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) {
+        s2n(s->d1->handshake_read_seq, ptr);
+        l2n3(s->d1->r_msg_hdr.frag_off, ptr);
+    }
+#endif
+
+    i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0);
+    if (i <= 0) {
+        s->s3->alert_dispatch = 1;
+        /* fprintf( stderr, "not done with alert\n" ); */
+    } else {
+        if (s->s3->send_alert[0] == SSL3_AL_FATAL
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+            || s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+#endif
+            )
+            (void)BIO_flush(s->wbio);
+
+        if (s->msg_callback)
+            s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert,
+                            2, s, s->msg_callback_arg);
+
+        if (s->info_callback != NULL)
+            cb = s->info_callback;
+        else if (s->ctx->info_callback != NULL)
+            cb = s->ctx->info_callback;
+
+        if (cb != NULL) {
+            j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1];
+            cb(s, SSL_CB_WRITE_ALERT, j);
+        }
+    }
+    return (i);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/d1_srtp.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/d1_srtp.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/d1_srtp.c	(revision 331)
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2011-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
+ */
+
+/*
+ * DTLS code by Eric Rescorla <ekr@rtfm.com>
+ *
+ * Copyright (C) 2006, Network Resonance, Inc. Copyright (C) 2011, RTFM, Inc.
+ */
+
+#include <stdio.h>
+#include <openssl/objects.h>
+#include "ssl_locl.h"
+
+#ifndef OPENSSL_NO_SRTP
+
+static SRTP_PROTECTION_PROFILE srtp_known_profiles[] = {
+    {
+     "SRTP_AES128_CM_SHA1_80",
+     SRTP_AES128_CM_SHA1_80,
+     },
+    {
+     "SRTP_AES128_CM_SHA1_32",
+     SRTP_AES128_CM_SHA1_32,
+     },
+    {
+     "SRTP_AEAD_AES_128_GCM",
+     SRTP_AEAD_AES_128_GCM,
+     },
+    {
+     "SRTP_AEAD_AES_256_GCM",
+     SRTP_AEAD_AES_256_GCM,
+     },
+    {0}
+};
+
+static int find_profile_by_name(char *profile_name,
+                                SRTP_PROTECTION_PROFILE **pptr, unsigned len)
+{
+    SRTP_PROTECTION_PROFILE *p;
+
+    p = srtp_known_profiles;
+    while (p->name) {
+        if ((len == strlen(p->name))
+            && strncmp(p->name, profile_name, len) == 0) {
+            *pptr = p;
+            return 0;
+        }
+
+        p++;
+    }
+
+    return 1;
+}
+
+static int ssl_ctx_make_profiles(const char *profiles_string,
+                                 STACK_OF(SRTP_PROTECTION_PROFILE) **out)
+{
+    STACK_OF(SRTP_PROTECTION_PROFILE) *profiles;
+
+    char *col;
+    char *ptr = (char *)profiles_string;
+    SRTP_PROTECTION_PROFILE *p;
+
+    if ((profiles = sk_SRTP_PROTECTION_PROFILE_new_null()) == NULL) {
+        SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,
+               SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
+        return 1;
+    }
+
+    do {
+        col = strchr(ptr, ':');
+
+        if (!find_profile_by_name(ptr, &p, col ? col - ptr : (int)strlen(ptr))) {
+            if (sk_SRTP_PROTECTION_PROFILE_find(profiles, p) >= 0) {
+                SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,
+                       SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+                goto err;
+            }
+
+            if (!sk_SRTP_PROTECTION_PROFILE_push(profiles, p)) {
+                SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,
+                       SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
+                goto err;
+            }
+        } else {
+            SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,
+                   SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
+            goto err;
+        }
+
+        if (col)
+            ptr = col + 1;
+    } while (col);
+
+    sk_SRTP_PROTECTION_PROFILE_free(*out);
+
+    *out = profiles;
+
+    return 0;
+ err:
+    sk_SRTP_PROTECTION_PROFILE_free(profiles);
+    return 1;
+}
+
+int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles)
+{
+    return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles);
+}
+
+int SSL_set_tlsext_use_srtp(SSL *s, const char *profiles)
+{
+    return ssl_ctx_make_profiles(profiles, &s->srtp_profiles);
+}
+
+STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *s)
+{
+    if (s != NULL) {
+        if (s->srtp_profiles != NULL) {
+            return s->srtp_profiles;
+        } else if ((s->ctx != NULL) && (s->ctx->srtp_profiles != NULL)) {
+            return s->ctx->srtp_profiles;
+        }
+    }
+
+    return NULL;
+}
+
+SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s)
+{
+    return s->srtp_profile;
+}
+
+/*
+ * Note: this function returns 0 length if there are no profiles specified
+ */
+int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len,
+                                     int maxlen)
+{
+    int ct = 0;
+    int i;
+    STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = 0;
+    SRTP_PROTECTION_PROFILE *prof;
+
+    clnt = SSL_get_srtp_profiles(s);
+    ct = sk_SRTP_PROTECTION_PROFILE_num(clnt); /* -1 if clnt == 0 */
+
+    if (p) {
+        if (ct == 0) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT,
+                   SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST);
+            return 1;
+        }
+
+        if ((2 + ct * 2 + 1) > maxlen) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT,
+                   SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
+            return 1;
+        }
+
+        /* Add the length */
+        s2n(ct * 2, p);
+        for (i = 0; i < ct; i++) {
+            prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
+            s2n(prof->id, p);
+        }
+
+        /* Add an empty use_mki value */
+        *p++ = 0;
+    }
+
+    *len = 2 + ct * 2 + 1;
+
+    return 0;
+}
+
+int ssl_parse_clienthello_use_srtp_ext(SSL *s, PACKET *pkt, int *al)
+{
+    SRTP_PROTECTION_PROFILE *sprof;
+    STACK_OF(SRTP_PROTECTION_PROFILE) *srvr;
+    unsigned int ct, mki_len, id;
+    int i, srtp_pref;
+    PACKET subpkt;
+
+    /* Pull off the length of the cipher suite list  and check it is even */
+    if (!PACKET_get_net_2(pkt, &ct)
+        || (ct & 1) != 0 || !PACKET_get_sub_packet(pkt, &subpkt, ct)) {
+        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,
+               SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+        *al = SSL_AD_DECODE_ERROR;
+        return 1;
+    }
+
+    srvr = SSL_get_srtp_profiles(s);
+    s->srtp_profile = NULL;
+    /* Search all profiles for a match initially */
+    srtp_pref = sk_SRTP_PROTECTION_PROFILE_num(srvr);
+
+    while (PACKET_remaining(&subpkt)) {
+        if (!PACKET_get_net_2(&subpkt, &id)) {
+            SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,
+                   SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+            *al = SSL_AD_DECODE_ERROR;
+            return 1;
+        }
+
+        /*
+         * Only look for match in profiles of higher preference than
+         * current match.
+         * If no profiles have been have been configured then this
+         * does nothing.
+         */
+        for (i = 0; i < srtp_pref; i++) {
+            sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i);
+            if (sprof->id == id) {
+                s->srtp_profile = sprof;
+                srtp_pref = i;
+                break;
+            }
+        }
+    }
+
+    /*
+     * Now extract the MKI value as a sanity check, but discard it for now
+     */
+    if (!PACKET_get_1(pkt, &mki_len)) {
+        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,
+               SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+        *al = SSL_AD_DECODE_ERROR;
+        return 1;
+    }
+
+    if (!PACKET_forward(pkt, mki_len)
+        || PACKET_remaining(pkt)) {
+        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,
+               SSL_R_BAD_SRTP_MKI_VALUE);
+        *al = SSL_AD_DECODE_ERROR;
+        return 1;
+    }
+
+    return 0;
+}
+
+int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len,
+                                     int maxlen)
+{
+    if (p) {
+        if (maxlen < 5) {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT,
+                   SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
+            return 1;
+        }
+
+        if (s->srtp_profile == 0) {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT,
+                   SSL_R_USE_SRTP_NOT_NEGOTIATED);
+            return 1;
+        }
+        s2n(2, p);
+        s2n(s->srtp_profile->id, p);
+        *p++ = 0;
+    }
+    *len = 5;
+
+    return 0;
+}
+
+int ssl_parse_serverhello_use_srtp_ext(SSL *s, PACKET *pkt, int *al)
+{
+    unsigned int id, ct, mki;
+    int i;
+
+    STACK_OF(SRTP_PROTECTION_PROFILE) *clnt;
+    SRTP_PROTECTION_PROFILE *prof;
+
+    if (!PACKET_get_net_2(pkt, &ct)
+        || ct != 2 || !PACKET_get_net_2(pkt, &id)
+        || !PACKET_get_1(pkt, &mki)
+        || PACKET_remaining(pkt) != 0) {
+        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
+               SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+        *al = SSL_AD_DECODE_ERROR;
+        return 1;
+    }
+
+    if (mki != 0) {
+        /* Must be no MKI, since we never offer one */
+        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
+               SSL_R_BAD_SRTP_MKI_VALUE);
+        *al = SSL_AD_ILLEGAL_PARAMETER;
+        return 1;
+    }
+
+    clnt = SSL_get_srtp_profiles(s);
+
+    /* Throw an error if the server gave us an unsolicited extension */
+    if (clnt == NULL) {
+        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
+               SSL_R_NO_SRTP_PROFILES);
+        *al = SSL_AD_DECODE_ERROR;
+        return 1;
+    }
+
+    /*
+     * Check to see if the server gave us something we support (and
+     * presumably offered)
+     */
+    for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(clnt); i++) {
+        prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
+
+        if (prof->id == id) {
+            s->srtp_profile = prof;
+            *al = 0;
+            return 0;
+        }
+    }
+
+    SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
+           SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+    *al = SSL_AD_DECODE_ERROR;
+    return 1;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/methods.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/methods.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/methods.c	(revision 331)
@@ -0,0 +1,266 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/objects.h>
+#include "ssl_locl.h"
+
+/*-
+ * TLS/SSLv3 methods
+ */
+
+IMPLEMENT_tls_meth_func(TLS_ANY_VERSION, 0, 0,
+                        TLS_method,
+                        ossl_statem_accept,
+                        ossl_statem_connect, TLSv1_2_enc_data)
+#ifndef OPENSSL_NO_TLS1_2_METHOD
+IMPLEMENT_tls_meth_func(TLS1_2_VERSION, 0, SSL_OP_NO_TLSv1_2,
+                        tlsv1_2_method,
+                        ossl_statem_accept,
+                        ossl_statem_connect, TLSv1_2_enc_data)
+#endif
+#ifndef OPENSSL_NO_TLS1_1_METHOD
+IMPLEMENT_tls_meth_func(TLS1_1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_TLSv1_1,
+                        tlsv1_1_method,
+                        ossl_statem_accept,
+                        ossl_statem_connect, TLSv1_1_enc_data)
+#endif
+#ifndef OPENSSL_NO_TLS1_METHOD
+IMPLEMENT_tls_meth_func(TLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_TLSv1,
+                        tlsv1_method,
+                        ossl_statem_accept, ossl_statem_connect, TLSv1_enc_data)
+#endif
+#ifndef OPENSSL_NO_SSL3_METHOD
+IMPLEMENT_ssl3_meth_func(sslv3_method, ossl_statem_accept, ossl_statem_connect)
+#endif
+/*-
+ * TLS/SSLv3 server methods
+ */
+IMPLEMENT_tls_meth_func(TLS_ANY_VERSION, 0, 0,
+                        TLS_server_method,
+                        ossl_statem_accept,
+                        ssl_undefined_function, TLSv1_2_enc_data)
+#ifndef OPENSSL_NO_TLS1_2_METHOD
+IMPLEMENT_tls_meth_func(TLS1_2_VERSION, 0, SSL_OP_NO_TLSv1_2,
+                        tlsv1_2_server_method,
+                        ossl_statem_accept,
+                        ssl_undefined_function, TLSv1_2_enc_data)
+#endif
+#ifndef OPENSSL_NO_TLS1_1_METHOD
+IMPLEMENT_tls_meth_func(TLS1_1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_TLSv1_1,
+                        tlsv1_1_server_method,
+                        ossl_statem_accept,
+                        ssl_undefined_function, TLSv1_1_enc_data)
+#endif
+#ifndef OPENSSL_NO_TLS1_METHOD
+IMPLEMENT_tls_meth_func(TLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_TLSv1,
+                        tlsv1_server_method,
+                        ossl_statem_accept,
+                        ssl_undefined_function, TLSv1_enc_data)
+#endif
+#ifndef OPENSSL_NO_SSL3_METHOD
+IMPLEMENT_ssl3_meth_func(sslv3_server_method,
+                         ossl_statem_accept, ssl_undefined_function)
+#endif
+/*-
+ * TLS/SSLv3 client methods
+ */
+IMPLEMENT_tls_meth_func(TLS_ANY_VERSION, 0, 0,
+                        TLS_client_method,
+                        ssl_undefined_function,
+                        ossl_statem_connect, TLSv1_2_enc_data)
+#ifndef OPENSSL_NO_TLS1_2_METHOD
+IMPLEMENT_tls_meth_func(TLS1_2_VERSION, 0, SSL_OP_NO_TLSv1_2,
+                        tlsv1_2_client_method,
+                        ssl_undefined_function,
+                        ossl_statem_connect, TLSv1_2_enc_data)
+#endif
+#ifndef OPENSSL_NO_TLS1_1_METHOD
+IMPLEMENT_tls_meth_func(TLS1_1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_TLSv1_1,
+                        tlsv1_1_client_method,
+                        ssl_undefined_function,
+                        ossl_statem_connect, TLSv1_1_enc_data)
+#endif
+#ifndef OPENSSL_NO_TLS1_METHOD
+IMPLEMENT_tls_meth_func(TLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_TLSv1,
+                        tlsv1_client_method,
+                        ssl_undefined_function,
+                        ossl_statem_connect, TLSv1_enc_data)
+#endif
+#ifndef OPENSSL_NO_SSL3_METHOD
+IMPLEMENT_ssl3_meth_func(sslv3_client_method,
+                         ssl_undefined_function, ossl_statem_connect)
+#endif
+/*-
+ * DTLS methods
+ */
+#ifndef OPENSSL_NO_DTLS1_METHOD
+IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_DTLSv1,
+                          dtlsv1_method,
+                          ossl_statem_accept,
+                          ossl_statem_connect, DTLSv1_enc_data)
+#endif
+#ifndef OPENSSL_NO_DTLS1_2_METHOD
+IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2,
+                          dtlsv1_2_method,
+                          ossl_statem_accept,
+                          ossl_statem_connect, DTLSv1_2_enc_data)
+#endif
+IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0,
+                          DTLS_method,
+                          ossl_statem_accept,
+                          ossl_statem_connect, DTLSv1_2_enc_data)
+
+/*-
+ * DTLS server methods
+ */
+#ifndef OPENSSL_NO_DTLS1_METHOD
+IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_DTLSv1,
+                          dtlsv1_server_method,
+                          ossl_statem_accept,
+                          ssl_undefined_function, DTLSv1_enc_data)
+#endif
+#ifndef OPENSSL_NO_DTLS1_2_METHOD
+IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2,
+                          dtlsv1_2_server_method,
+                          ossl_statem_accept,
+                          ssl_undefined_function, DTLSv1_2_enc_data)
+#endif
+IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0,
+                          DTLS_server_method,
+                          ossl_statem_accept,
+                          ssl_undefined_function, DTLSv1_2_enc_data)
+
+/*-
+ * DTLS client methods
+ */
+#ifndef OPENSSL_NO_DTLS1_METHOD
+IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_DTLSv1,
+                          dtlsv1_client_method,
+                          ssl_undefined_function,
+                          ossl_statem_connect, DTLSv1_enc_data)
+IMPLEMENT_dtls1_meth_func(DTLS1_BAD_VER, SSL_METHOD_NO_SUITEB, SSL_OP_NO_DTLSv1,
+                          dtls_bad_ver_client_method,
+                          ssl_undefined_function,
+                          ossl_statem_connect, DTLSv1_enc_data)
+#endif
+#ifndef OPENSSL_NO_DTLS1_2_METHOD
+IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2,
+                          dtlsv1_2_client_method,
+                          ssl_undefined_function,
+                          ossl_statem_connect, DTLSv1_2_enc_data)
+#endif
+IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0,
+                          DTLS_client_method,
+                          ssl_undefined_function,
+                          ossl_statem_connect, DTLSv1_2_enc_data)
+#if OPENSSL_API_COMPAT < 0x10100000L
+# ifndef OPENSSL_NO_TLS1_2_METHOD
+const SSL_METHOD *TLSv1_2_method(void)
+{
+    return tlsv1_2_method();
+}
+
+const SSL_METHOD *TLSv1_2_server_method(void)
+{
+    return tlsv1_2_server_method();
+}
+
+const SSL_METHOD *TLSv1_2_client_method(void)
+{
+    return tlsv1_2_client_method();
+}
+# endif
+
+# ifndef OPENSSL_NO_TLS1_1_METHOD
+const SSL_METHOD *TLSv1_1_method(void)
+{
+    return tlsv1_1_method();
+}
+
+const SSL_METHOD *TLSv1_1_server_method(void)
+{
+    return tlsv1_1_server_method();
+}
+
+const SSL_METHOD *TLSv1_1_client_method(void)
+{
+    return tlsv1_1_client_method();
+}
+# endif
+
+# ifndef OPENSSL_NO_TLS1_METHOD
+const SSL_METHOD *TLSv1_method(void)
+{
+    return tlsv1_method();
+}
+
+const SSL_METHOD *TLSv1_server_method(void)
+{
+    return tlsv1_server_method();
+}
+
+const SSL_METHOD *TLSv1_client_method(void)
+{
+    return tlsv1_client_method();
+}
+# endif
+
+# ifndef OPENSSL_NO_SSL3_METHOD
+const SSL_METHOD *SSLv3_method(void)
+{
+    return sslv3_method();
+}
+
+const SSL_METHOD *SSLv3_server_method(void)
+{
+    return sslv3_server_method();
+}
+
+const SSL_METHOD *SSLv3_client_method(void)
+{
+    return sslv3_client_method();
+}
+# endif
+
+# ifndef OPENSSL_NO_DTLS1_2_METHOD
+const SSL_METHOD *DTLSv1_2_method(void)
+{
+    return dtlsv1_2_method();
+}
+
+const SSL_METHOD *DTLSv1_2_server_method(void)
+{
+    return dtlsv1_2_server_method();
+}
+
+const SSL_METHOD *DTLSv1_2_client_method(void)
+{
+    return dtlsv1_2_client_method();
+}
+# endif
+
+# ifndef OPENSSL_NO_DTLS1_METHOD
+const SSL_METHOD *DTLSv1_method(void)
+{
+    return dtlsv1_method();
+}
+
+const SSL_METHOD *DTLSv1_server_method(void)
+{
+    return dtlsv1_server_method();
+}
+
+const SSL_METHOD *DTLSv1_client_method(void)
+{
+    return dtlsv1_client_method();
+}
+# endif
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/packet_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/packet_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/packet_locl.h	(revision 331)
@@ -0,0 +1,555 @@
+/*
+ * Copyright 2015-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
+ */
+
+#ifndef HEADER_PACKET_LOCL_H
+# define HEADER_PACKET_LOCL_H
+
+# include <string.h>
+# include <openssl/bn.h>
+# include <openssl/buffer.h>
+# include <openssl/crypto.h>
+# include <openssl/e_os2.h>
+
+# include "internal/numbers.h"
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+typedef struct {
+    /* Pointer to where we are currently reading from */
+    const unsigned char *curr;
+    /* Number of bytes remaining */
+    size_t remaining;
+} PACKET;
+
+/* Internal unchecked shorthand; don't use outside this file. */
+static ossl_inline void packet_forward(PACKET *pkt, size_t len)
+{
+    pkt->curr += len;
+    pkt->remaining -= len;
+}
+
+/*
+ * Returns the number of bytes remaining to be read in the PACKET
+ */
+static ossl_inline size_t PACKET_remaining(const PACKET *pkt)
+{
+    return pkt->remaining;
+}
+
+/*
+ * Returns a pointer to the first byte after the packet data.
+ * Useful for integrating with non-PACKET parsing code.
+ * Specifically, we use PACKET_end() to verify that a d2i_... call
+ * has consumed the entire packet contents.
+ */
+static ossl_inline const unsigned char *PACKET_end(const PACKET *pkt)
+{
+    return pkt->curr + pkt->remaining;
+}
+
+/*
+ * Returns a pointer to the PACKET's current position.
+ * For use in non-PACKETized APIs.
+ */
+static ossl_inline const unsigned char *PACKET_data(const PACKET *pkt)
+{
+    return pkt->curr;
+}
+
+/*
+ * Initialise a PACKET with |len| bytes held in |buf|. This does not make a
+ * copy of the data so |buf| must be present for the whole time that the PACKET
+ * is being used.
+ */
+__owur static ossl_inline int PACKET_buf_init(PACKET *pkt,
+                                              const unsigned char *buf,
+                                              size_t len)
+{
+    /* Sanity check for negative values. */
+    if (len > (size_t)(SIZE_MAX / 2))
+        return 0;
+
+    pkt->curr = buf;
+    pkt->remaining = len;
+    return 1;
+}
+
+/* Initialize a PACKET to hold zero bytes. */
+static ossl_inline void PACKET_null_init(PACKET *pkt)
+{
+    pkt->curr = NULL;
+    pkt->remaining = 0;
+}
+
+/*
+ * Returns 1 if the packet has length |num| and its contents equal the |num|
+ * bytes read from |ptr|. Returns 0 otherwise (lengths or contents not equal).
+ * If lengths are equal, performs the comparison in constant time.
+ */
+__owur static ossl_inline int PACKET_equal(const PACKET *pkt, const void *ptr,
+                                           size_t num)
+{
+    if (PACKET_remaining(pkt) != num)
+        return 0;
+    return CRYPTO_memcmp(pkt->curr, ptr, num) == 0;
+}
+
+/*
+ * Peek ahead and initialize |subpkt| with the next |len| bytes read from |pkt|.
+ * Data is not copied: the |subpkt| packet will share its underlying buffer with
+ * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
+ */
+__owur static ossl_inline int PACKET_peek_sub_packet(const PACKET *pkt,
+                                                     PACKET *subpkt, size_t len)
+{
+    if (PACKET_remaining(pkt) < len)
+        return 0;
+
+    return PACKET_buf_init(subpkt, pkt->curr, len);
+}
+
+/*
+ * Initialize |subpkt| with the next |len| bytes read from |pkt|. Data is not
+ * copied: the |subpkt| packet will share its underlying buffer with the
+ * original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
+ */
+__owur static ossl_inline int PACKET_get_sub_packet(PACKET *pkt,
+                                                    PACKET *subpkt, size_t len)
+{
+    if (!PACKET_peek_sub_packet(pkt, subpkt, len))
+        return 0;
+
+    packet_forward(pkt, len);
+
+    return 1;
+}
+
+/*
+ * Peek ahead at 2 bytes in network order from |pkt| and store the value in
+ * |*data|
+ */
+__owur static ossl_inline int PACKET_peek_net_2(const PACKET *pkt,
+                                                unsigned int *data)
+{
+    if (PACKET_remaining(pkt) < 2)
+        return 0;
+
+    *data = ((unsigned int)(*pkt->curr)) << 8;
+    *data |= *(pkt->curr + 1);
+
+    return 1;
+}
+
+/* Equivalent of n2s */
+/* Get 2 bytes in network order from |pkt| and store the value in |*data| */
+__owur static ossl_inline int PACKET_get_net_2(PACKET *pkt, unsigned int *data)
+{
+    if (!PACKET_peek_net_2(pkt, data))
+        return 0;
+
+    packet_forward(pkt, 2);
+
+    return 1;
+}
+
+/*
+ * Peek ahead at 3 bytes in network order from |pkt| and store the value in
+ * |*data|
+ */
+__owur static ossl_inline int PACKET_peek_net_3(const PACKET *pkt,
+                                                unsigned long *data)
+{
+    if (PACKET_remaining(pkt) < 3)
+        return 0;
+
+    *data = ((unsigned long)(*pkt->curr)) << 16;
+    *data |= ((unsigned long)(*(pkt->curr + 1))) << 8;
+    *data |= *(pkt->curr + 2);
+
+    return 1;
+}
+
+/* Equivalent of n2l3 */
+/* Get 3 bytes in network order from |pkt| and store the value in |*data| */
+__owur static ossl_inline int PACKET_get_net_3(PACKET *pkt, unsigned long *data)
+{
+    if (!PACKET_peek_net_3(pkt, data))
+        return 0;
+
+    packet_forward(pkt, 3);
+
+    return 1;
+}
+
+/*
+ * Peek ahead at 4 bytes in network order from |pkt| and store the value in
+ * |*data|
+ */
+__owur static ossl_inline int PACKET_peek_net_4(const PACKET *pkt,
+                                                unsigned long *data)
+{
+    if (PACKET_remaining(pkt) < 4)
+        return 0;
+
+    *data = ((unsigned long)(*pkt->curr)) << 24;
+    *data |= ((unsigned long)(*(pkt->curr + 1))) << 16;
+    *data |= ((unsigned long)(*(pkt->curr + 2))) << 8;
+    *data |= *(pkt->curr + 3);
+
+    return 1;
+}
+
+/* Equivalent of n2l */
+/* Get 4 bytes in network order from |pkt| and store the value in |*data| */
+__owur static ossl_inline int PACKET_get_net_4(PACKET *pkt, unsigned long *data)
+{
+    if (!PACKET_peek_net_4(pkt, data))
+        return 0;
+
+    packet_forward(pkt, 4);
+
+    return 1;
+}
+
+/* Peek ahead at 1 byte from |pkt| and store the value in |*data| */
+__owur static ossl_inline int PACKET_peek_1(const PACKET *pkt,
+                                            unsigned int *data)
+{
+    if (!PACKET_remaining(pkt))
+        return 0;
+
+    *data = *pkt->curr;
+
+    return 1;
+}
+
+/* Get 1 byte from |pkt| and store the value in |*data| */
+__owur static ossl_inline int PACKET_get_1(PACKET *pkt, unsigned int *data)
+{
+    if (!PACKET_peek_1(pkt, data))
+        return 0;
+
+    packet_forward(pkt, 1);
+
+    return 1;
+}
+
+/*
+ * Peek ahead at 4 bytes in reverse network order from |pkt| and store the value
+ * in |*data|
+ */
+__owur static ossl_inline int PACKET_peek_4(const PACKET *pkt,
+                                            unsigned long *data)
+{
+    if (PACKET_remaining(pkt) < 4)
+        return 0;
+
+    *data = *pkt->curr;
+    *data |= ((unsigned long)(*(pkt->curr + 1))) << 8;
+    *data |= ((unsigned long)(*(pkt->curr + 2))) << 16;
+    *data |= ((unsigned long)(*(pkt->curr + 3))) << 24;
+
+    return 1;
+}
+
+/* Equivalent of c2l */
+/*
+ * Get 4 bytes in reverse network order from |pkt| and store the value in
+ * |*data|
+ */
+__owur static ossl_inline int PACKET_get_4(PACKET *pkt, unsigned long *data)
+{
+    if (!PACKET_peek_4(pkt, data))
+        return 0;
+
+    packet_forward(pkt, 4);
+
+    return 1;
+}
+
+/*
+ * Peek ahead at |len| bytes from the |pkt| and store a pointer to them in
+ * |*data|. This just points at the underlying buffer that |pkt| is using. The
+ * caller should not free this data directly (it will be freed when the
+ * underlying buffer gets freed
+ */
+__owur static ossl_inline int PACKET_peek_bytes(const PACKET *pkt,
+                                                const unsigned char **data,
+                                                size_t len)
+{
+    if (PACKET_remaining(pkt) < len)
+        return 0;
+
+    *data = pkt->curr;
+
+    return 1;
+}
+
+/*
+ * Read |len| bytes from the |pkt| and store a pointer to them in |*data|. This
+ * just points at the underlying buffer that |pkt| is using. The caller should
+ * not free this data directly (it will be freed when the underlying buffer gets
+ * freed
+ */
+__owur static ossl_inline int PACKET_get_bytes(PACKET *pkt,
+                                               const unsigned char **data,
+                                               size_t len)
+{
+    if (!PACKET_peek_bytes(pkt, data, len))
+        return 0;
+
+    packet_forward(pkt, len);
+
+    return 1;
+}
+
+/* Peek ahead at |len| bytes from |pkt| and copy them to |data| */
+__owur static ossl_inline int PACKET_peek_copy_bytes(const PACKET *pkt,
+                                                     unsigned char *data,
+                                                     size_t len)
+{
+    if (PACKET_remaining(pkt) < len)
+        return 0;
+
+    memcpy(data, pkt->curr, len);
+
+    return 1;
+}
+
+/*
+ * Read |len| bytes from |pkt| and copy them to |data|.
+ * The caller is responsible for ensuring that |data| can hold |len| bytes.
+ */
+__owur static ossl_inline int PACKET_copy_bytes(PACKET *pkt,
+                                                unsigned char *data, size_t len)
+{
+    if (!PACKET_peek_copy_bytes(pkt, data, len))
+        return 0;
+
+    packet_forward(pkt, len);
+
+    return 1;
+}
+
+/*
+ * Copy packet data to |dest|, and set |len| to the number of copied bytes.
+ * If the packet has more than |dest_len| bytes, nothing is copied.
+ * Returns 1 if the packet data fits in |dest_len| bytes, 0 otherwise.
+ * Does not forward PACKET position (because it is typically the last thing
+ * done with a given PACKET).
+ */
+__owur static ossl_inline int PACKET_copy_all(const PACKET *pkt,
+                                              unsigned char *dest,
+                                              size_t dest_len, size_t *len)
+{
+    if (PACKET_remaining(pkt) > dest_len) {
+        *len = 0;
+        return 0;
+    }
+    *len = pkt->remaining;
+    memcpy(dest, pkt->curr, pkt->remaining);
+    return 1;
+}
+
+/*
+ * Copy |pkt| bytes to a newly allocated buffer and store a pointer to the
+ * result in |*data|, and the length in |len|.
+ * If |*data| is not NULL, the old data is OPENSSL_free'd.
+ * If the packet is empty, or malloc fails, |*data| will be set to NULL.
+ * Returns 1 if the malloc succeeds and 0 otherwise.
+ * Does not forward PACKET position (because it is typically the last thing
+ * done with a given PACKET).
+ */
+__owur static ossl_inline int PACKET_memdup(const PACKET *pkt,
+                                            unsigned char **data, size_t *len)
+{
+    size_t length;
+
+    OPENSSL_free(*data);
+    *data = NULL;
+    *len = 0;
+
+    length = PACKET_remaining(pkt);
+
+    if (length == 0)
+        return 1;
+
+    *data = OPENSSL_memdup(pkt->curr, length);
+    if (*data == NULL)
+        return 0;
+
+    *len = length;
+    return 1;
+}
+
+/*
+ * Read a C string from |pkt| and copy to a newly allocated, NUL-terminated
+ * buffer. Store a pointer to the result in |*data|.
+ * If |*data| is not NULL, the old data is OPENSSL_free'd.
+ * If the data in |pkt| does not contain a NUL-byte, the entire data is
+ * copied and NUL-terminated.
+ * Returns 1 if the malloc succeeds and 0 otherwise.
+ * Does not forward PACKET position (because it is typically the last thing done
+ * with a given PACKET).
+ */
+__owur static ossl_inline int PACKET_strndup(const PACKET *pkt, char **data)
+{
+    OPENSSL_free(*data);
+
+    /* This will succeed on an empty packet, unless pkt->curr == NULL. */
+    *data = OPENSSL_strndup((const char *)pkt->curr, PACKET_remaining(pkt));
+    return (*data != NULL);
+}
+
+/* Returns 1 if |pkt| contains at least one 0-byte, 0 otherwise. */
+static ossl_inline int PACKET_contains_zero_byte(const PACKET *pkt)
+{
+    return memchr(pkt->curr, 0, pkt->remaining) != NULL;
+}
+
+/* Move the current reading position forward |len| bytes */
+__owur static ossl_inline int PACKET_forward(PACKET *pkt, size_t len)
+{
+    if (PACKET_remaining(pkt) < len)
+        return 0;
+
+    packet_forward(pkt, len);
+
+    return 1;
+}
+
+/*
+ * Reads a variable-length vector prefixed with a one-byte length, and stores
+ * the contents in |subpkt|. |pkt| can equal |subpkt|.
+ * Data is not copied: the |subpkt| packet will share its underlying buffer with
+ * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
+ * Upon failure, the original |pkt| and |subpkt| are not modified.
+ */
+__owur static ossl_inline int PACKET_get_length_prefixed_1(PACKET *pkt,
+                                                           PACKET *subpkt)
+{
+    unsigned int length;
+    const unsigned char *data;
+    PACKET tmp = *pkt;
+    if (!PACKET_get_1(&tmp, &length) ||
+        !PACKET_get_bytes(&tmp, &data, (size_t)length)) {
+        return 0;
+    }
+
+    *pkt = tmp;
+    subpkt->curr = data;
+    subpkt->remaining = length;
+
+    return 1;
+}
+
+/*
+ * Like PACKET_get_length_prefixed_1, but additionally, fails when there are
+ * leftover bytes in |pkt|.
+ */
+__owur static ossl_inline int PACKET_as_length_prefixed_1(PACKET *pkt,
+                                                          PACKET *subpkt)
+{
+    unsigned int length;
+    const unsigned char *data;
+    PACKET tmp = *pkt;
+    if (!PACKET_get_1(&tmp, &length) ||
+        !PACKET_get_bytes(&tmp, &data, (size_t)length) ||
+        PACKET_remaining(&tmp) != 0) {
+        return 0;
+    }
+
+    *pkt = tmp;
+    subpkt->curr = data;
+    subpkt->remaining = length;
+
+    return 1;
+}
+
+/*
+ * Reads a variable-length vector prefixed with a two-byte length, and stores
+ * the contents in |subpkt|. |pkt| can equal |subpkt|.
+ * Data is not copied: the |subpkt| packet will share its underlying buffer with
+ * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
+ * Upon failure, the original |pkt| and |subpkt| are not modified.
+ */
+__owur static ossl_inline int PACKET_get_length_prefixed_2(PACKET *pkt,
+                                                           PACKET *subpkt)
+{
+    unsigned int length;
+    const unsigned char *data;
+    PACKET tmp = *pkt;
+
+    if (!PACKET_get_net_2(&tmp, &length) ||
+        !PACKET_get_bytes(&tmp, &data, (size_t)length)) {
+        return 0;
+    }
+
+    *pkt = tmp;
+    subpkt->curr = data;
+    subpkt->remaining = length;
+
+    return 1;
+}
+
+/*
+ * Like PACKET_get_length_prefixed_2, but additionally, fails when there are
+ * leftover bytes in |pkt|.
+ */
+__owur static ossl_inline int PACKET_as_length_prefixed_2(PACKET *pkt,
+                                                          PACKET *subpkt)
+{
+    unsigned int length;
+    const unsigned char *data;
+    PACKET tmp = *pkt;
+
+    if (!PACKET_get_net_2(&tmp, &length) ||
+        !PACKET_get_bytes(&tmp, &data, (size_t)length) ||
+        PACKET_remaining(&tmp) != 0) {
+        return 0;
+    }
+
+    *pkt = tmp;
+    subpkt->curr = data;
+    subpkt->remaining = length;
+
+    return 1;
+}
+
+/*
+ * Reads a variable-length vector prefixed with a three-byte length, and stores
+ * the contents in |subpkt|. |pkt| can equal |subpkt|.
+ * Data is not copied: the |subpkt| packet will share its underlying buffer with
+ * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
+ * Upon failure, the original |pkt| and |subpkt| are not modified.
+ */
+__owur static ossl_inline int PACKET_get_length_prefixed_3(PACKET *pkt,
+                                                           PACKET *subpkt)
+{
+    unsigned long length;
+    const unsigned char *data;
+    PACKET tmp = *pkt;
+    if (!PACKET_get_net_3(&tmp, &length) ||
+        !PACKET_get_bytes(&tmp, &data, (size_t)length)) {
+        return 0;
+    }
+
+    *pkt = tmp;
+    subpkt->curr = data;
+    subpkt->remaining = length;
+
+    return 1;
+}
+# ifdef __cplusplus
+}
+# endif
+
+#endif                          /* HEADER_PACKET_LOCL_H */
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/pqueue.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/pqueue.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/pqueue.c	(revision 331)
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2005-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 "ssl_locl.h"
+#include <openssl/bn.h>
+
+struct pqueue_st {
+    pitem *items;
+    int count;
+};
+
+pitem *pitem_new(unsigned char *prio64be, void *data)
+{
+    pitem *item = OPENSSL_malloc(sizeof(*item));
+    if (item == NULL)
+        return NULL;
+
+    memcpy(item->priority, prio64be, sizeof(item->priority));
+
+    item->data = data;
+    item->next = NULL;
+
+    return item;
+}
+
+void pitem_free(pitem *item)
+{
+    OPENSSL_free(item);
+}
+
+pqueue *pqueue_new()
+{
+    pqueue *pq = OPENSSL_zalloc(sizeof(*pq));
+
+    return pq;
+}
+
+void pqueue_free(pqueue *pq)
+{
+    OPENSSL_free(pq);
+}
+
+pitem *pqueue_insert(pqueue *pq, pitem *item)
+{
+    pitem *curr, *next;
+
+    if (pq->items == NULL) {
+        pq->items = item;
+        return item;
+    }
+
+    for (curr = NULL, next = pq->items;
+         next != NULL; curr = next, next = next->next) {
+        /*
+         * we can compare 64-bit value in big-endian encoding with memcmp:-)
+         */
+        int cmp = memcmp(next->priority, item->priority, 8);
+        if (cmp > 0) {          /* next > item */
+            item->next = next;
+
+            if (curr == NULL)
+                pq->items = item;
+            else
+                curr->next = item;
+
+            return item;
+        }
+
+        else if (cmp == 0)      /* duplicates not allowed */
+            return NULL;
+    }
+
+    item->next = NULL;
+    curr->next = item;
+
+    return item;
+}
+
+pitem *pqueue_peek(pqueue *pq)
+{
+    return pq->items;
+}
+
+pitem *pqueue_pop(pqueue *pq)
+{
+    pitem *item = pq->items;
+
+    if (pq->items != NULL)
+        pq->items = pq->items->next;
+
+    return item;
+}
+
+pitem *pqueue_find(pqueue *pq, unsigned char *prio64be)
+{
+    pitem *next;
+    pitem *found = NULL;
+
+    if (pq->items == NULL)
+        return NULL;
+
+    for (next = pq->items; next->next != NULL; next = next->next) {
+        if (memcmp(next->priority, prio64be, 8) == 0) {
+            found = next;
+            break;
+        }
+    }
+
+    /* check the one last node */
+    if (memcmp(next->priority, prio64be, 8) == 0)
+        found = next;
+
+    if (!found)
+        return NULL;
+
+    return found;
+}
+
+pitem *pqueue_iterator(pqueue *pq)
+{
+    return pqueue_peek(pq);
+}
+
+pitem *pqueue_next(pitem **item)
+{
+    pitem *ret;
+
+    if (item == NULL || *item == NULL)
+        return NULL;
+
+    /* *item != NULL */
+    ret = *item;
+    *item = (*item)->next;
+
+    return ret;
+}
+
+int pqueue_size(pqueue *pq)
+{
+    pitem *item = pq->items;
+    int count = 0;
+
+    while (item != NULL) {
+        count++;
+        item = item->next;
+    }
+    return count;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/dtls1_bitmap.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/dtls1_bitmap.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/dtls1_bitmap.c	(revision 331)
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2005-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 "../ssl_locl.h"
+#include "record_locl.h"
+
+/* mod 128 saturating subtract of two 64-bit values in big-endian order */
+static int satsub64be(const unsigned char *v1, const unsigned char *v2)
+{
+    int64_t ret;
+    uint64_t l1, l2;
+
+    n2l8(v1, l1);
+    n2l8(v2, l2);
+
+    ret = l1 - l2;
+
+    /* We do not permit wrap-around */
+    if (l1 > l2 && ret < 0)
+        return 128;
+    else if (l2 > l1 && ret > 0)
+        return -128;
+
+    if (ret > 128)
+        return 128;
+    else if (ret < -128)
+        return -128;
+    else
+        return (int)ret;
+}
+
+int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap)
+{
+    int cmp;
+    unsigned int shift;
+    const unsigned char *seq = s->rlayer.read_sequence;
+
+    cmp = satsub64be(seq, bitmap->max_seq_num);
+    if (cmp > 0) {
+        SSL3_RECORD_set_seq_num(RECORD_LAYER_get_rrec(&s->rlayer), seq);
+        return 1;               /* this record in new */
+    }
+    shift = -cmp;
+    if (shift >= sizeof(bitmap->map) * 8)
+        return 0;               /* stale, outside the window */
+    else if (bitmap->map & (1UL << shift))
+        return 0;               /* record previously received */
+
+    SSL3_RECORD_set_seq_num(RECORD_LAYER_get_rrec(&s->rlayer), seq);
+    return 1;
+}
+
+void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap)
+{
+    int cmp;
+    unsigned int shift;
+    const unsigned char *seq = RECORD_LAYER_get_read_sequence(&s->rlayer);
+
+    cmp = satsub64be(seq, bitmap->max_seq_num);
+    if (cmp > 0) {
+        shift = cmp;
+        if (shift < sizeof(bitmap->map) * 8)
+            bitmap->map <<= shift, bitmap->map |= 1UL;
+        else
+            bitmap->map = 1UL;
+        memcpy(bitmap->max_seq_num, seq, SEQ_NUM_SIZE);
+    } else {
+        shift = -cmp;
+        if (shift < sizeof(bitmap->map) * 8)
+            bitmap->map |= 1UL << shift;
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/rec_layer_d1.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/rec_layer_d1.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/rec_layer_d1.c	(revision 331)
@@ -0,0 +1,1224 @@
+/*
+ * Copyright 2005-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 <stdio.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "../ssl_locl.h"
+#include <openssl/evp.h>
+#include <openssl/buffer.h>
+#include "record_locl.h"
+
+int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl)
+{
+    DTLS_RECORD_LAYER *d;
+
+    if ((d = OPENSSL_malloc(sizeof(*d))) == NULL)
+        return (0);
+
+    rl->d = d;
+
+    d->unprocessed_rcds.q = pqueue_new();
+    d->processed_rcds.q = pqueue_new();
+    d->buffered_app_data.q = pqueue_new();
+
+    if (d->unprocessed_rcds.q == NULL || d->processed_rcds.q == NULL
+        || d->buffered_app_data.q == NULL) {
+        pqueue_free(d->unprocessed_rcds.q);
+        pqueue_free(d->processed_rcds.q);
+        pqueue_free(d->buffered_app_data.q);
+        OPENSSL_free(d);
+        rl->d = NULL;
+        return (0);
+    }
+
+    return 1;
+}
+
+void DTLS_RECORD_LAYER_free(RECORD_LAYER *rl)
+{
+    DTLS_RECORD_LAYER_clear(rl);
+    pqueue_free(rl->d->unprocessed_rcds.q);
+    pqueue_free(rl->d->processed_rcds.q);
+    pqueue_free(rl->d->buffered_app_data.q);
+    OPENSSL_free(rl->d);
+    rl->d = NULL;
+}
+
+void DTLS_RECORD_LAYER_clear(RECORD_LAYER *rl)
+{
+    DTLS_RECORD_LAYER *d;
+    pitem *item = NULL;
+    DTLS1_RECORD_DATA *rdata;
+    pqueue *unprocessed_rcds;
+    pqueue *processed_rcds;
+    pqueue *buffered_app_data;
+
+    d = rl->d;
+
+    while ((item = pqueue_pop(d->unprocessed_rcds.q)) != NULL) {
+        rdata = (DTLS1_RECORD_DATA *)item->data;
+        OPENSSL_free(rdata->rbuf.buf);
+        OPENSSL_free(item->data);
+        pitem_free(item);
+    }
+
+    while ((item = pqueue_pop(d->processed_rcds.q)) != NULL) {
+        rdata = (DTLS1_RECORD_DATA *)item->data;
+        OPENSSL_free(rdata->rbuf.buf);
+        OPENSSL_free(item->data);
+        pitem_free(item);
+    }
+
+    while ((item = pqueue_pop(d->buffered_app_data.q)) != NULL) {
+        rdata = (DTLS1_RECORD_DATA *)item->data;
+        OPENSSL_free(rdata->rbuf.buf);
+        OPENSSL_free(item->data);
+        pitem_free(item);
+    }
+
+    unprocessed_rcds = d->unprocessed_rcds.q;
+    processed_rcds = d->processed_rcds.q;
+    buffered_app_data = d->buffered_app_data.q;
+    memset(d, 0, sizeof(*d));
+    d->unprocessed_rcds.q = unprocessed_rcds;
+    d->processed_rcds.q = processed_rcds;
+    d->buffered_app_data.q = buffered_app_data;
+}
+
+void DTLS_RECORD_LAYER_set_saved_w_epoch(RECORD_LAYER *rl, unsigned short e)
+{
+    if (e == rl->d->w_epoch - 1) {
+        memcpy(rl->d->curr_write_sequence,
+               rl->write_sequence, sizeof(rl->write_sequence));
+        memcpy(rl->write_sequence,
+               rl->d->last_write_sequence, sizeof(rl->write_sequence));
+    } else if (e == rl->d->w_epoch + 1) {
+        memcpy(rl->d->last_write_sequence,
+               rl->write_sequence, sizeof(unsigned char[8]));
+        memcpy(rl->write_sequence,
+               rl->d->curr_write_sequence, sizeof(rl->write_sequence));
+    }
+    rl->d->w_epoch = e;
+}
+
+void DTLS_RECORD_LAYER_resync_write(RECORD_LAYER *rl)
+{
+    memcpy(rl->write_sequence, rl->read_sequence, sizeof(rl->write_sequence));
+}
+
+void DTLS_RECORD_LAYER_set_write_sequence(RECORD_LAYER *rl, unsigned char *seq)
+{
+    memcpy(rl->write_sequence, seq, SEQ_NUM_SIZE);
+}
+
+static int have_handshake_fragment(SSL *s, int type, unsigned char *buf,
+                                   int len);
+
+/* copy buffered record into SSL structure */
+static int dtls1_copy_record(SSL *s, pitem *item)
+{
+    DTLS1_RECORD_DATA *rdata;
+
+    rdata = (DTLS1_RECORD_DATA *)item->data;
+
+    SSL3_BUFFER_release(&s->rlayer.rbuf);
+
+    s->rlayer.packet = rdata->packet;
+    s->rlayer.packet_length = rdata->packet_length;
+    memcpy(&s->rlayer.rbuf, &(rdata->rbuf), sizeof(SSL3_BUFFER));
+    memcpy(&s->rlayer.rrec, &(rdata->rrec), sizeof(SSL3_RECORD));
+
+    /* Set proper sequence number for mac calculation */
+    memcpy(&(s->rlayer.read_sequence[2]), &(rdata->packet[5]), 6);
+
+    return (1);
+}
+
+int dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
+{
+    DTLS1_RECORD_DATA *rdata;
+    pitem *item;
+
+    /* Limit the size of the queue to prevent DOS attacks */
+    if (pqueue_size(queue->q) >= 100)
+        return 0;
+
+    rdata = OPENSSL_malloc(sizeof(*rdata));
+    item = pitem_new(priority, rdata);
+    if (rdata == NULL || item == NULL) {
+        OPENSSL_free(rdata);
+        pitem_free(item);
+        SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
+        return -1;
+    }
+
+    rdata->packet = s->rlayer.packet;
+    rdata->packet_length = s->rlayer.packet_length;
+    memcpy(&(rdata->rbuf), &s->rlayer.rbuf, sizeof(SSL3_BUFFER));
+    memcpy(&(rdata->rrec), &s->rlayer.rrec, sizeof(SSL3_RECORD));
+
+    item->data = rdata;
+
+#ifndef OPENSSL_NO_SCTP
+    /* Store bio_dgram_sctp_rcvinfo struct */
+    if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
+        (SSL_get_state(s) == TLS_ST_SR_FINISHED
+         || SSL_get_state(s) == TLS_ST_CR_FINISHED)) {
+        BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_GET_RCVINFO,
+                 sizeof(rdata->recordinfo), &rdata->recordinfo);
+    }
+#endif
+
+    s->rlayer.packet = NULL;
+    s->rlayer.packet_length = 0;
+    memset(&s->rlayer.rbuf, 0, sizeof(s->rlayer.rbuf));
+    memset(&s->rlayer.rrec, 0, sizeof(s->rlayer.rrec));
+
+    if (!ssl3_setup_buffers(s)) {
+        SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
+        OPENSSL_free(rdata->rbuf.buf);
+        OPENSSL_free(rdata);
+        pitem_free(item);
+        return (-1);
+    }
+
+    /* insert should not fail, since duplicates are dropped */
+    if (pqueue_insert(queue->q, item) == NULL) {
+        SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
+        OPENSSL_free(rdata->rbuf.buf);
+        OPENSSL_free(rdata);
+        pitem_free(item);
+        return (-1);
+    }
+
+    return (1);
+}
+
+int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue)
+{
+    pitem *item;
+
+    item = pqueue_pop(queue->q);
+    if (item) {
+        dtls1_copy_record(s, item);
+
+        OPENSSL_free(item->data);
+        pitem_free(item);
+
+        return (1);
+    }
+
+    return (0);
+}
+
+/*
+ * retrieve a buffered record that belongs to the new epoch, i.e., not
+ * processed yet
+ */
+#define dtls1_get_unprocessed_record(s) \
+                   dtls1_retrieve_buffered_record((s), \
+                   &((s)->rlayer.d->unprocessed_rcds))
+
+int dtls1_process_buffered_records(SSL *s)
+{
+    pitem *item;
+    SSL3_BUFFER *rb;
+    SSL3_RECORD *rr;
+    DTLS1_BITMAP *bitmap;
+    unsigned int is_next_epoch;
+    int replayok = 1;
+
+    item = pqueue_peek(s->rlayer.d->unprocessed_rcds.q);
+    if (item) {
+        /* Check if epoch is current. */
+        if (s->rlayer.d->unprocessed_rcds.epoch != s->rlayer.d->r_epoch)
+            return 1;         /* Nothing to do. */
+
+        rr = RECORD_LAYER_get_rrec(&s->rlayer);
+
+        rb = RECORD_LAYER_get_rbuf(&s->rlayer);
+
+        if (SSL3_BUFFER_get_left(rb) > 0) {
+            /*
+             * We've still got data from the current packet to read. There could
+             * be a record from the new epoch in it - so don't overwrite it
+             * with the unprocessed records yet (we'll do it when we've
+             * finished reading the current packet).
+             */
+            return 1;
+        }
+
+        /* Process all the records. */
+        while (pqueue_peek(s->rlayer.d->unprocessed_rcds.q)) {
+            dtls1_get_unprocessed_record(s);
+            bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
+            if (bitmap == NULL) {
+                /*
+                 * Should not happen. This will only ever be NULL when the
+                 * current record is from a different epoch. But that cannot
+                 * be the case because we already checked the epoch above
+                 */
+                 SSLerr(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS,
+                        ERR_R_INTERNAL_ERROR);
+                 return 0;
+            }
+#ifndef OPENSSL_NO_SCTP
+            /* Only do replay check if no SCTP bio */
+            if (!BIO_dgram_is_sctp(SSL_get_rbio(s)))
+#endif
+            {
+                /*
+                 * Check whether this is a repeat, or aged record. We did this
+                 * check once already when we first received the record - but
+                 * we might have updated the window since then due to
+                 * records we subsequently processed.
+                 */
+                replayok = dtls1_record_replay_check(s, bitmap);
+            }
+
+            if (!replayok || !dtls1_process_record(s, bitmap)) {
+                /* dump this record */
+                rr->length = 0;
+                RECORD_LAYER_reset_packet_length(&s->rlayer);
+                continue;
+            }
+
+            if (dtls1_buffer_record(s, &(s->rlayer.d->processed_rcds),
+                    SSL3_RECORD_get_seq_num(s->rlayer.rrec)) < 0)
+                return 0;
+        }
+    }
+
+    /*
+     * sync epoch numbers once all the unprocessed records have been
+     * processed
+     */
+    s->rlayer.d->processed_rcds.epoch = s->rlayer.d->r_epoch;
+    s->rlayer.d->unprocessed_rcds.epoch = s->rlayer.d->r_epoch + 1;
+
+    return 1;
+}
+
+/*-
+ * Return up to 'len' payload bytes received in 'type' records.
+ * 'type' is one of the following:
+ *
+ *   -  SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
+ *   -  SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
+ *   -  0 (during a shutdown, no data has to be returned)
+ *
+ * If we don't have stored data to work from, read a SSL/TLS record first
+ * (possibly multiple records if we still don't have anything to return).
+ *
+ * This function must handle any surprises the peer may have for us, such as
+ * Alert records (e.g. close_notify) or renegotiation requests. ChangeCipherSpec
+ * messages are treated as if they were handshake messages *if* the |recd_type|
+ * argument is non NULL.
+ * Also if record payloads contain fragments too small to process, we store
+ * them until there is enough for the respective protocol (the record protocol
+ * may use arbitrary fragmentation and even interleaving):
+ *     Change cipher spec protocol
+ *             just 1 byte needed, no need for keeping anything stored
+ *     Alert protocol
+ *             2 bytes needed (AlertLevel, AlertDescription)
+ *     Handshake protocol
+ *             4 bytes needed (HandshakeType, uint24 length) -- we just have
+ *             to detect unexpected Client Hello and Hello Request messages
+ *             here, anything else is handled by higher layers
+ *     Application data protocol
+ *             none of our business
+ */
+int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
+                     int len, int peek)
+{
+    int al, i, j, ret;
+    unsigned int n;
+    SSL3_RECORD *rr;
+    void (*cb) (const SSL *ssl, int type2, int val) = NULL;
+
+    if (!SSL3_BUFFER_is_initialised(&s->rlayer.rbuf)) {
+        /* Not initialized yet */
+        if (!ssl3_setup_buffers(s))
+            return (-1);
+    }
+
+    if ((type && (type != SSL3_RT_APPLICATION_DATA) &&
+         (type != SSL3_RT_HANDSHAKE)) ||
+        (peek && (type != SSL3_RT_APPLICATION_DATA))) {
+        SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
+        return -1;
+    }
+
+    /*
+     * check whether there's a handshake message (client hello?) waiting
+     */
+    if ((ret = have_handshake_fragment(s, type, buf, len))) {
+        *recvd_type = SSL3_RT_HANDSHAKE;
+        return ret;
+    }
+
+    /*
+     * Now s->rlayer.d->handshake_fragment_len == 0 if
+     * type == SSL3_RT_HANDSHAKE.
+     */
+
+#ifndef OPENSSL_NO_SCTP
+    /*
+     * Continue handshake if it had to be interrupted to read app data with
+     * SCTP.
+     */
+    if ((!ossl_statem_get_in_handshake(s) && SSL_in_init(s)) ||
+        (BIO_dgram_is_sctp(SSL_get_rbio(s))
+         && ossl_statem_in_sctp_read_sock(s)
+         && s->s3->in_read_app_data != 2))
+#else
+    if (!ossl_statem_get_in_handshake(s) && SSL_in_init(s))
+#endif
+    {
+        /* type == SSL3_RT_APPLICATION_DATA */
+        i = s->handshake_func(s);
+        if (i < 0)
+            return (i);
+        if (i == 0) {
+            SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE);
+            return (-1);
+        }
+    }
+
+ start:
+    s->rwstate = SSL_NOTHING;
+
+    /*-
+     * s->s3->rrec.type         - is the type of record
+     * s->s3->rrec.data,    - data
+     * s->s3->rrec.off,     - offset into 'data' for next read
+     * s->s3->rrec.length,  - number of bytes.
+     */
+    rr = s->rlayer.rrec;
+
+    /*
+     * We are not handshaking and have no data yet, so process data buffered
+     * during the last handshake in advance, if any.
+     */
+    if (SSL_is_init_finished(s) && SSL3_RECORD_get_length(rr) == 0) {
+        pitem *item;
+        item = pqueue_pop(s->rlayer.d->buffered_app_data.q);
+        if (item) {
+#ifndef OPENSSL_NO_SCTP
+            /* Restore bio_dgram_sctp_rcvinfo struct */
+            if (BIO_dgram_is_sctp(SSL_get_rbio(s))) {
+                DTLS1_RECORD_DATA *rdata = (DTLS1_RECORD_DATA *)item->data;
+                BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_SET_RCVINFO,
+                         sizeof(rdata->recordinfo), &rdata->recordinfo);
+            }
+#endif
+
+            dtls1_copy_record(s, item);
+
+            OPENSSL_free(item->data);
+            pitem_free(item);
+        }
+    }
+
+    /* Check for timeout */
+    if (dtls1_handle_timeout(s) > 0)
+        goto start;
+
+    /* get new packet if necessary */
+    if ((SSL3_RECORD_get_length(rr) == 0)
+        || (s->rlayer.rstate == SSL_ST_READ_BODY)) {
+        ret = dtls1_get_record(s);
+        if (ret <= 0) {
+            ret = dtls1_read_failed(s, ret);
+            /* anything other than a timeout is an error */
+            if (ret <= 0)
+                return (ret);
+            else
+                goto start;
+        }
+    }
+
+    /*
+     * Reset the count of consecutive warning alerts if we've got a non-empty
+     * record that isn't an alert.
+     */
+    if (SSL3_RECORD_get_type(rr) != SSL3_RT_ALERT
+            && SSL3_RECORD_get_length(rr) != 0)
+        s->rlayer.alert_count = 0;
+
+    /* we now have a packet which can be read and processed */
+
+    if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
+                                   * reset by ssl3_get_finished */
+        && (SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE)) {
+        /*
+         * We now have application data between CCS and Finished. Most likely
+         * the packets were reordered on their way, so buffer the application
+         * data for later processing rather than dropping the connection.
+         */
+        if (dtls1_buffer_record(s, &(s->rlayer.d->buffered_app_data),
+                                SSL3_RECORD_get_seq_num(rr)) < 0) {
+            SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
+            return -1;
+        }
+        SSL3_RECORD_set_length(rr, 0);
+        goto start;
+    }
+
+    /*
+     * If the other end has shut down, throw anything we read away (even in
+     * 'peek' mode)
+     */
+    if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
+        SSL3_RECORD_set_length(rr, 0);
+        s->rwstate = SSL_NOTHING;
+        return (0);
+    }
+
+    if (type == SSL3_RECORD_get_type(rr)
+        || (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC
+            && type == SSL3_RT_HANDSHAKE && recvd_type != NULL)) {
+        /*
+         * SSL3_RT_APPLICATION_DATA or
+         * SSL3_RT_HANDSHAKE or
+         * SSL3_RT_CHANGE_CIPHER_SPEC
+         */
+        /*
+         * make sure that we are not getting application data when we are
+         * doing a handshake for the first time
+         */
+        if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&
+            (s->enc_read_ctx == NULL)) {
+            al = SSL_AD_UNEXPECTED_MESSAGE;
+            SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_APP_DATA_IN_HANDSHAKE);
+            goto f_err;
+        }
+
+        if (recvd_type != NULL)
+            *recvd_type = SSL3_RECORD_get_type(rr);
+
+        if (len <= 0)
+            return (len);
+
+        if ((unsigned int)len > SSL3_RECORD_get_length(rr))
+            n = SSL3_RECORD_get_length(rr);
+        else
+            n = (unsigned int)len;
+
+        memcpy(buf, &(SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)]), n);
+        if (!peek) {
+            SSL3_RECORD_sub_length(rr, n);
+            SSL3_RECORD_add_off(rr, n);
+            if (SSL3_RECORD_get_length(rr) == 0) {
+                s->rlayer.rstate = SSL_ST_READ_HEADER;
+                SSL3_RECORD_set_off(rr, 0);
+            }
+        }
+#ifndef OPENSSL_NO_SCTP
+        /*
+         * We were about to renegotiate but had to read belated application
+         * data first, so retry.
+         */
+        if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
+            SSL3_RECORD_get_type(rr) == SSL3_RT_APPLICATION_DATA &&
+            ossl_statem_in_sctp_read_sock(s)) {
+            s->rwstate = SSL_READING;
+            BIO_clear_retry_flags(SSL_get_rbio(s));
+            BIO_set_retry_read(SSL_get_rbio(s));
+        }
+
+        /*
+         * We might had to delay a close_notify alert because of reordered
+         * app data. If there was an alert and there is no message to read
+         * anymore, finally set shutdown.
+         */
+        if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
+            s->d1->shutdown_received
+            && !BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) {
+            s->shutdown |= SSL_RECEIVED_SHUTDOWN;
+            return (0);
+        }
+#endif
+        return (n);
+    }
+
+    /*
+     * If we get here, then type != rr->type; if we have a handshake message,
+     * then it was unexpected (Hello Request or Client Hello).
+     */
+
+    /*
+     * In case of record types for which we have 'fragment' storage, fill
+     * that so that we can process the data at a fixed place.
+     */
+    {
+        unsigned int k, dest_maxlen = 0;
+        unsigned char *dest = NULL;
+        unsigned int *dest_len = NULL;
+
+        if (SSL3_RECORD_get_type(rr) == SSL3_RT_HANDSHAKE) {
+            dest_maxlen = sizeof s->rlayer.d->handshake_fragment;
+            dest = s->rlayer.d->handshake_fragment;
+            dest_len = &s->rlayer.d->handshake_fragment_len;
+        } else if (SSL3_RECORD_get_type(rr) == SSL3_RT_ALERT) {
+            dest_maxlen = sizeof(s->rlayer.d->alert_fragment);
+            dest = s->rlayer.d->alert_fragment;
+            dest_len = &s->rlayer.d->alert_fragment_len;
+        }
+#ifndef OPENSSL_NO_HEARTBEATS
+        else if (SSL3_RECORD_get_type(rr) == DTLS1_RT_HEARTBEAT) {
+            /* We allow a 0 return */
+            if (dtls1_process_heartbeat(s, SSL3_RECORD_get_data(rr),
+                                        SSL3_RECORD_get_length(rr)) < 0) {
+                return -1;
+            }
+            /* Exit and notify application to read again */
+            SSL3_RECORD_set_length(rr, 0);
+            s->rwstate = SSL_READING;
+            BIO_clear_retry_flags(SSL_get_rbio(s));
+            BIO_set_retry_read(SSL_get_rbio(s));
+            return (-1);
+        }
+#endif
+        /* else it's a CCS message, or application data or wrong */
+        else if (SSL3_RECORD_get_type(rr) != SSL3_RT_CHANGE_CIPHER_SPEC) {
+            /*
+             * Application data while renegotiating is allowed. Try again
+             * reading.
+             */
+            if (SSL3_RECORD_get_type(rr) == SSL3_RT_APPLICATION_DATA) {
+                BIO *bio;
+                s->s3->in_read_app_data = 2;
+                bio = SSL_get_rbio(s);
+                s->rwstate = SSL_READING;
+                BIO_clear_retry_flags(bio);
+                BIO_set_retry_read(bio);
+                return (-1);
+            }
+
+            /* Not certain if this is the right error handling */
+            al = SSL_AD_UNEXPECTED_MESSAGE;
+            SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD);
+            goto f_err;
+        }
+
+        if (dest_maxlen > 0) {
+            /*
+             * XDTLS: In a pathological case, the Client Hello may be
+             * fragmented--don't always expect dest_maxlen bytes
+             */
+            if (SSL3_RECORD_get_length(rr) < dest_maxlen) {
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+                /*
+                 * for normal alerts rr->length is 2, while
+                 * dest_maxlen is 7 if we were to handle this
+                 * non-existing alert...
+                 */
+                FIX ME;
+#endif
+                s->rlayer.rstate = SSL_ST_READ_HEADER;
+                SSL3_RECORD_set_length(rr, 0);
+                goto start;
+            }
+
+            /* now move 'n' bytes: */
+            for (k = 0; k < dest_maxlen; k++) {
+                dest[k] = SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)];
+                SSL3_RECORD_add_off(rr, 1);
+                SSL3_RECORD_add_length(rr, -1);
+            }
+            *dest_len = dest_maxlen;
+        }
+    }
+
+    /*-
+     * s->rlayer.d->handshake_fragment_len == 12  iff  rr->type == SSL3_RT_HANDSHAKE;
+     * s->rlayer.d->alert_fragment_len == 7      iff  rr->type == SSL3_RT_ALERT.
+     * (Possibly rr is 'empty' now, i.e. rr->length may be 0.)
+     */
+
+    /* If we are a client, check for an incoming 'Hello Request': */
+    if ((!s->server) &&
+        (s->rlayer.d->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) &&
+        (s->rlayer.d->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&
+        (s->session != NULL) && (s->session->cipher != NULL)) {
+        s->rlayer.d->handshake_fragment_len = 0;
+
+        if ((s->rlayer.d->handshake_fragment[1] != 0) ||
+            (s->rlayer.d->handshake_fragment[2] != 0) ||
+            (s->rlayer.d->handshake_fragment[3] != 0)) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_HELLO_REQUEST);
+            goto f_err;
+        }
+
+        /*
+         * no need to check sequence number on HELLO REQUEST messages
+         */
+
+        if (s->msg_callback)
+            s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
+                            s->rlayer.d->handshake_fragment, 4, s,
+                            s->msg_callback_arg);
+
+        if (SSL_is_init_finished(s) &&
+            !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
+            !s->s3->renegotiate) {
+            s->d1->handshake_read_seq++;
+            s->new_session = 1;
+            ssl3_renegotiate(s);
+            if (ssl3_renegotiate_check(s)) {
+                i = s->handshake_func(s);
+                if (i < 0)
+                    return (i);
+                if (i == 0) {
+                    SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE);
+                    return (-1);
+                }
+
+                if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
+                    if (SSL3_BUFFER_get_left(&s->rlayer.rbuf) == 0) {
+                        /* no read-ahead left? */
+                        BIO *bio;
+                        /*
+                         * In the case where we try to read application data,
+                         * but we trigger an SSL handshake, we return -1 with
+                         * the retry option set.  Otherwise renegotiation may
+                         * cause nasty problems in the blocking world
+                         */
+                        s->rwstate = SSL_READING;
+                        bio = SSL_get_rbio(s);
+                        BIO_clear_retry_flags(bio);
+                        BIO_set_retry_read(bio);
+                        return (-1);
+                    }
+                }
+            }
+        }
+        /*
+         * we either finished a handshake or ignored the request, now try
+         * again to obtain the (application) data we were asked for
+         */
+        goto start;
+    }
+
+    if (s->rlayer.d->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH) {
+        int alert_level = s->rlayer.d->alert_fragment[0];
+        int alert_descr = s->rlayer.d->alert_fragment[1];
+
+        s->rlayer.d->alert_fragment_len = 0;
+
+        if (s->msg_callback)
+            s->msg_callback(0, s->version, SSL3_RT_ALERT,
+                            s->rlayer.d->alert_fragment, 2, s,
+                            s->msg_callback_arg);
+
+        if (s->info_callback != NULL)
+            cb = s->info_callback;
+        else if (s->ctx->info_callback != NULL)
+            cb = s->ctx->info_callback;
+
+        if (cb != NULL) {
+            j = (alert_level << 8) | alert_descr;
+            cb(s, SSL_CB_READ_ALERT, j);
+        }
+
+        if (alert_level == SSL3_AL_WARNING) {
+            s->s3->warn_alert = alert_descr;
+
+            s->rlayer.alert_count++;
+            if (s->rlayer.alert_count == MAX_WARN_ALERT_COUNT) {
+                al = SSL_AD_UNEXPECTED_MESSAGE;
+                SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS);
+                goto f_err;
+            }
+
+            if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
+#ifndef OPENSSL_NO_SCTP
+                /*
+                 * With SCTP and streams the socket may deliver app data
+                 * after a close_notify alert. We have to check this first so
+                 * that nothing gets discarded.
+                 */
+                if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
+                    BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) {
+                    s->d1->shutdown_received = 1;
+                    s->rwstate = SSL_READING;
+                    BIO_clear_retry_flags(SSL_get_rbio(s));
+                    BIO_set_retry_read(SSL_get_rbio(s));
+                    return -1;
+                }
+#endif
+                s->shutdown |= SSL_RECEIVED_SHUTDOWN;
+                return (0);
+            }
+#if 0
+            /* XXX: this is a possible improvement in the future */
+            /* now check if it's a missing record */
+            if (alert_descr == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) {
+                unsigned short seq;
+                unsigned int frag_off;
+                unsigned char *p = &(s->rlayer.d->alert_fragment[2]);
+
+                n2s(p, seq);
+                n2l3(p, frag_off);
+
+                dtls1_retransmit_message(s,
+                                         dtls1_get_queue_priority
+                                         (frag->msg_header.seq, 0), frag_off,
+                                         &found);
+                if (!found && SSL_in_init(s)) {
+                    /*
+                     * fprintf( stderr,"in init = %d\n", SSL_in_init(s));
+                     */
+                    /*
+                     * requested a message not yet sent, send an alert
+                     * ourselves
+                     */
+                    ssl3_send_alert(s, SSL3_AL_WARNING,
+                                    DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
+                }
+            }
+#endif
+        } else if (alert_level == SSL3_AL_FATAL) {
+            char tmp[16];
+
+            s->rwstate = SSL_NOTHING;
+            s->s3->fatal_alert = alert_descr;
+            SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr);
+            BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr);
+            ERR_add_error_data(2, "SSL alert number ", tmp);
+            s->shutdown |= SSL_RECEIVED_SHUTDOWN;
+            SSL_CTX_remove_session(s->session_ctx, s->session);
+            return (0);
+        } else {
+            al = SSL_AD_ILLEGAL_PARAMETER;
+            SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNKNOWN_ALERT_TYPE);
+            goto f_err;
+        }
+
+        goto start;
+    }
+
+    if (s->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a
+                                            * shutdown */
+        s->rwstate = SSL_NOTHING;
+        SSL3_RECORD_set_length(rr, 0);
+        return (0);
+    }
+
+    if (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC) {
+        /*
+         * We can't process a CCS now, because previous handshake messages
+         * are still missing, so just drop it.
+         */
+        SSL3_RECORD_set_length(rr, 0);
+        goto start;
+    }
+
+    /*
+     * Unexpected handshake message (Client Hello, or protocol violation)
+     */
+    if ((s->rlayer.d->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) &&
+        !ossl_statem_get_in_handshake(s)) {
+        struct hm_header_st msg_hdr;
+
+        /* this may just be a stale retransmit */
+        dtls1_get_message_header(rr->data, &msg_hdr);
+        if (SSL3_RECORD_get_epoch(rr) != s->rlayer.d->r_epoch) {
+            SSL3_RECORD_set_length(rr, 0);
+            goto start;
+        }
+
+        /*
+         * If we are server, we may have a repeated FINISHED of the client
+         * here, then retransmit our CCS and FINISHED.
+         */
+        if (msg_hdr.type == SSL3_MT_FINISHED) {
+            if (dtls1_check_timeout_num(s) < 0)
+                return -1;
+
+            dtls1_retransmit_buffered_messages(s);
+            SSL3_RECORD_set_length(rr, 0);
+            goto start;
+        }
+
+        if (SSL_is_init_finished(s) &&
+            !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) {
+            ossl_statem_set_in_init(s, 1);
+            s->renegotiate = 1;
+            s->new_session = 1;
+        }
+        i = s->handshake_func(s);
+        if (i < 0)
+            return (i);
+        if (i == 0) {
+            SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE);
+            return (-1);
+        }
+
+        if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
+            if (SSL3_BUFFER_get_left(&s->rlayer.rbuf) == 0) {
+                /* no read-ahead left? */
+                BIO *bio;
+                /*
+                 * In the case where we try to read application data, but we
+                 * trigger an SSL handshake, we return -1 with the retry
+                 * option set.  Otherwise renegotiation may cause nasty
+                 * problems in the blocking world
+                 */
+                s->rwstate = SSL_READING;
+                bio = SSL_get_rbio(s);
+                BIO_clear_retry_flags(bio);
+                BIO_set_retry_read(bio);
+                return (-1);
+            }
+        }
+        goto start;
+    }
+
+    switch (SSL3_RECORD_get_type(rr)) {
+    default:
+        /* TLS just ignores unknown message types */
+        if (s->version == TLS1_VERSION) {
+            SSL3_RECORD_set_length(rr, 0);
+            goto start;
+        }
+        al = SSL_AD_UNEXPECTED_MESSAGE;
+        SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD);
+        goto f_err;
+    case SSL3_RT_CHANGE_CIPHER_SPEC:
+    case SSL3_RT_ALERT:
+    case SSL3_RT_HANDSHAKE:
+        /*
+         * we already handled all of these, with the possible exception of
+         * SSL3_RT_HANDSHAKE when ossl_statem_get_in_handshake(s) is true, but
+         * that should not happen when type != rr->type
+         */
+        al = SSL_AD_UNEXPECTED_MESSAGE;
+        SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
+        goto f_err;
+    case SSL3_RT_APPLICATION_DATA:
+        /*
+         * At this point, we were expecting handshake data, but have
+         * application data.  If the library was running inside ssl3_read()
+         * (i.e. in_read_app_data is set) and it makes sense to read
+         * application data at this point (session renegotiation not yet
+         * started), we will indulge it.
+         */
+        if (s->s3->in_read_app_data &&
+            (s->s3->total_renegotiations != 0) &&
+            ossl_statem_app_data_allowed(s)) {
+            s->s3->in_read_app_data = 2;
+            return (-1);
+        } else {
+            al = SSL_AD_UNEXPECTED_MESSAGE;
+            SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD);
+            goto f_err;
+        }
+    }
+    /* not reached */
+
+ f_err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    return (-1);
+}
+
+        /*
+         * this only happens when a client hello is received and a handshake
+         * is started.
+         */
+static int have_handshake_fragment(SSL *s, int type, unsigned char *buf,
+                                   int len)
+{
+
+    if ((type == SSL3_RT_HANDSHAKE)
+        && (s->rlayer.d->handshake_fragment_len > 0))
+        /* (partially) satisfy request from storage */
+    {
+        unsigned char *src = s->rlayer.d->handshake_fragment;
+        unsigned char *dst = buf;
+        unsigned int k, n;
+
+        /* peek == 0 */
+        n = 0;
+        while ((len > 0) && (s->rlayer.d->handshake_fragment_len > 0)) {
+            *dst++ = *src++;
+            len--;
+            s->rlayer.d->handshake_fragment_len--;
+            n++;
+        }
+        /* move any remaining fragment bytes: */
+        for (k = 0; k < s->rlayer.d->handshake_fragment_len; k++)
+            s->rlayer.d->handshake_fragment[k] = *src++;
+        return n;
+    }
+
+    return 0;
+}
+
+/*
+ * Call this to write data in records of type 'type' It will return <= 0 if
+ * not all data has been sent or non-blocking IO.
+ */
+int dtls1_write_bytes(SSL *s, int type, const void *buf, int len)
+{
+    int i;
+
+    OPENSSL_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH);
+    s->rwstate = SSL_NOTHING;
+    i = do_dtls1_write(s, type, buf, len, 0);
+    return i;
+}
+
+int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
+                   unsigned int len, int create_empty_fragment)
+{
+    unsigned char *p, *pseq;
+    int i, mac_size, clear = 0;
+    int prefix_len = 0;
+    int eivlen;
+    SSL3_RECORD wr;
+    SSL3_BUFFER *wb;
+    SSL_SESSION *sess;
+
+    wb = &s->rlayer.wbuf[0];
+
+    /*
+     * first check if there is a SSL3_BUFFER still being written out.  This
+     * will happen with non blocking IO
+     */
+    if (SSL3_BUFFER_get_left(wb) != 0) {
+        OPENSSL_assert(0);      /* XDTLS: want to see if we ever get here */
+        return (ssl3_write_pending(s, type, buf, len));
+    }
+
+    /* If we have an alert to send, lets send it */
+    if (s->s3->alert_dispatch) {
+        i = s->method->ssl_dispatch_alert(s);
+        if (i <= 0)
+            return (i);
+        /* if it went, fall through and send more stuff */
+    }
+
+    if (len == 0 && !create_empty_fragment)
+        return 0;
+
+    sess = s->session;
+
+    if ((sess == NULL) ||
+        (s->enc_write_ctx == NULL) || (EVP_MD_CTX_md(s->write_hash) == NULL))
+        clear = 1;
+
+    if (clear)
+        mac_size = 0;
+    else {
+        mac_size = EVP_MD_CTX_size(s->write_hash);
+        if (mac_size < 0)
+            goto err;
+    }
+
+    p = SSL3_BUFFER_get_buf(wb) + prefix_len;
+
+    /* write the header */
+
+    *(p++) = type & 0xff;
+    SSL3_RECORD_set_type(&wr, type);
+    /*
+     * Special case: for hello verify request, client version 1.0 and we
+     * haven't decided which version to use yet send back using version 1.0
+     * header: otherwise some clients will ignore it.
+     */
+    if (s->method->version == DTLS_ANY_VERSION &&
+        s->max_proto_version != DTLS1_BAD_VER) {
+        *(p++) = DTLS1_VERSION >> 8;
+        *(p++) = DTLS1_VERSION & 0xff;
+    } else {
+        *(p++) = s->version >> 8;
+        *(p++) = s->version & 0xff;
+    }
+
+    /* field where we are to write out packet epoch, seq num and len */
+    pseq = p;
+    p += 10;
+
+    /* Explicit IV length, block ciphers appropriate version flag */
+    if (s->enc_write_ctx) {
+        int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx);
+        if (mode == EVP_CIPH_CBC_MODE) {
+            eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx);
+            if (eivlen <= 1)
+                eivlen = 0;
+        }
+        /* Need explicit part of IV for GCM mode */
+        else if (mode == EVP_CIPH_GCM_MODE)
+            eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
+        else if (mode == EVP_CIPH_CCM_MODE)
+            eivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
+        else
+            eivlen = 0;
+    } else
+        eivlen = 0;
+
+    /* lets setup the record stuff. */
+    SSL3_RECORD_set_data(&wr, p + eivlen); /* make room for IV in case of CBC */
+    SSL3_RECORD_set_length(&wr, (int)len);
+    SSL3_RECORD_set_input(&wr, (unsigned char *)buf);
+
+    /*
+     * we now 'read' from wr.input, wr.length bytes into wr.data
+     */
+
+    /* first we compress */
+    if (s->compress != NULL) {
+        if (!ssl3_do_compress(s, &wr)) {
+            SSLerr(SSL_F_DO_DTLS1_WRITE, SSL_R_COMPRESSION_FAILURE);
+            goto err;
+        }
+    } else {
+        memcpy(SSL3_RECORD_get_data(&wr), SSL3_RECORD_get_input(&wr),
+               SSL3_RECORD_get_length(&wr));
+        SSL3_RECORD_reset_input(&wr);
+    }
+
+    /*
+     * we should still have the output to wr.data and the input from
+     * wr.input.  Length should be wr.length. wr.data still points in the
+     * wb->buf
+     */
+
+    if (mac_size != 0) {
+        if (s->method->ssl3_enc->mac(s, &wr,
+                                     &(p[SSL3_RECORD_get_length(&wr) + eivlen]),
+                                     1) < 0)
+            goto err;
+        SSL3_RECORD_add_length(&wr, mac_size);
+    }
+
+    /* this is true regardless of mac size */
+    SSL3_RECORD_set_data(&wr, p);
+    SSL3_RECORD_reset_input(&wr);
+
+    if (eivlen)
+        SSL3_RECORD_add_length(&wr, eivlen);
+
+    if (s->method->ssl3_enc->enc(s, &wr, 1, 1) < 1)
+        goto err;
+
+    /* record length after mac and block padding */
+    /*
+     * if (type == SSL3_RT_APPLICATION_DATA || (type == SSL3_RT_ALERT && !
+     * SSL_in_init(s)))
+     */
+
+    /* there's only one epoch between handshake and app data */
+
+    s2n(s->rlayer.d->w_epoch, pseq);
+
+    /* XDTLS: ?? */
+    /*
+     * else s2n(s->d1->handshake_epoch, pseq);
+     */
+
+    memcpy(pseq, &(s->rlayer.write_sequence[2]), 6);
+    pseq += 6;
+    s2n(SSL3_RECORD_get_length(&wr), pseq);
+
+    if (s->msg_callback)
+        s->msg_callback(1, 0, SSL3_RT_HEADER, pseq - DTLS1_RT_HEADER_LENGTH,
+                        DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg);
+
+    /*
+     * we should now have wr.data pointing to the encrypted data, which is
+     * wr->length long
+     */
+    SSL3_RECORD_set_type(&wr, type); /* not needed but helps for debugging */
+    SSL3_RECORD_add_length(&wr, DTLS1_RT_HEADER_LENGTH);
+
+    ssl3_record_sequence_update(&(s->rlayer.write_sequence[0]));
+
+    if (create_empty_fragment) {
+        /*
+         * we are in a recursive call; just return the length, don't write
+         * out anything here
+         */
+        return wr.length;
+    }
+
+    /* now let's set up wb */
+    SSL3_BUFFER_set_left(wb, prefix_len + SSL3_RECORD_get_length(&wr));
+    SSL3_BUFFER_set_offset(wb, 0);
+
+    /*
+     * memorize arguments so that ssl3_write_pending can detect bad write
+     * retries later
+     */
+    s->rlayer.wpend_tot = len;
+    s->rlayer.wpend_buf = buf;
+    s->rlayer.wpend_type = type;
+    s->rlayer.wpend_ret = len;
+
+    /* we now just need to write the buffer */
+    return ssl3_write_pending(s, type, buf, len);
+ err:
+    return -1;
+}
+
+DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr,
+                               unsigned int *is_next_epoch)
+{
+
+    *is_next_epoch = 0;
+
+    /* In current epoch, accept HM, CCS, DATA, & ALERT */
+    if (rr->epoch == s->rlayer.d->r_epoch)
+        return &s->rlayer.d->bitmap;
+
+    /*
+     * Only HM and ALERT messages can be from the next epoch and only if we
+     * have already processed all of the unprocessed records from the last
+     * epoch
+     */
+    else if (rr->epoch == (unsigned long)(s->rlayer.d->r_epoch + 1) &&
+             s->rlayer.d->unprocessed_rcds.epoch != s->rlayer.d->r_epoch &&
+             (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) {
+        *is_next_epoch = 1;
+        return &s->rlayer.d->next_bitmap;
+    }
+
+    return NULL;
+}
+
+void dtls1_reset_seq_numbers(SSL *s, int rw)
+{
+    unsigned char *seq;
+    unsigned int seq_bytes = sizeof(s->rlayer.read_sequence);
+
+    if (rw & SSL3_CC_READ) {
+        seq = s->rlayer.read_sequence;
+        s->rlayer.d->r_epoch++;
+        memcpy(&s->rlayer.d->bitmap, &s->rlayer.d->next_bitmap,
+               sizeof(s->rlayer.d->bitmap));
+        memset(&s->rlayer.d->next_bitmap, 0, sizeof(s->rlayer.d->next_bitmap));
+
+        /*
+         * We must not use any buffered messages received from the previous
+         * epoch
+         */
+        dtls1_clear_received_buffer(s);
+    } else {
+        seq = s->rlayer.write_sequence;
+        memcpy(s->rlayer.d->last_write_sequence, seq,
+               sizeof(s->rlayer.write_sequence));
+        s->rlayer.d->w_epoch++;
+    }
+
+    memset(seq, 0, seq_bytes);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/rec_layer_s3.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/rec_layer_s3.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/rec_layer_s3.c	(revision 331)
@@ -0,0 +1,1527 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <limits.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "../ssl_locl.h"
+#include <openssl/evp.h>
+#include <openssl/buffer.h>
+#include <openssl/rand.h>
+#include "record_locl.h"
+
+#if     defined(OPENSSL_SMALL_FOOTPRINT) || \
+        !(      defined(AES_ASM) &&     ( \
+                defined(__x86_64)       || defined(__x86_64__)  || \
+                defined(_M_AMD64)       || defined(_M_X64)      ) \
+        )
+# undef EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
+# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0
+#endif
+
+void RECORD_LAYER_init(RECORD_LAYER *rl, SSL *s)
+{
+    rl->s = s;
+    RECORD_LAYER_set_first_record(&s->rlayer);
+    SSL3_RECORD_clear(rl->rrec, SSL_MAX_PIPELINES);
+}
+
+void RECORD_LAYER_clear(RECORD_LAYER *rl)
+{
+    rl->rstate = SSL_ST_READ_HEADER;
+
+    /*
+     * Do I need to clear read_ahead? As far as I can tell read_ahead did not
+     * previously get reset by SSL_clear...so I'll keep it that way..but is
+     * that right?
+     */
+
+    rl->packet = NULL;
+    rl->packet_length = 0;
+    rl->wnum = 0;
+    memset(rl->alert_fragment, 0, sizeof(rl->alert_fragment));
+    rl->alert_fragment_len = 0;
+    memset(rl->handshake_fragment, 0, sizeof(rl->handshake_fragment));
+    rl->handshake_fragment_len = 0;
+    rl->wpend_tot = 0;
+    rl->wpend_type = 0;
+    rl->wpend_ret = 0;
+    rl->wpend_buf = NULL;
+
+    SSL3_BUFFER_clear(&rl->rbuf);
+    ssl3_release_write_buffer(rl->s);
+    rl->numrpipes = 0;
+    SSL3_RECORD_clear(rl->rrec, SSL_MAX_PIPELINES);
+
+    RECORD_LAYER_reset_read_sequence(rl);
+    RECORD_LAYER_reset_write_sequence(rl);
+
+    if (rl->d)
+        DTLS_RECORD_LAYER_clear(rl);
+}
+
+void RECORD_LAYER_release(RECORD_LAYER *rl)
+{
+    if (SSL3_BUFFER_is_initialised(&rl->rbuf))
+        ssl3_release_read_buffer(rl->s);
+    if (rl->numwpipes > 0)
+        ssl3_release_write_buffer(rl->s);
+    SSL3_RECORD_release(rl->rrec, SSL_MAX_PIPELINES);
+}
+
+int RECORD_LAYER_read_pending(const RECORD_LAYER *rl)
+{
+    return SSL3_BUFFER_get_left(&rl->rbuf) != 0;
+}
+
+int RECORD_LAYER_write_pending(const RECORD_LAYER *rl)
+{
+    return (rl->numwpipes > 0)
+        && SSL3_BUFFER_get_left(&rl->wbuf[rl->numwpipes - 1]) != 0;
+}
+
+int RECORD_LAYER_set_data(RECORD_LAYER *rl, const unsigned char *buf, int len)
+{
+    rl->packet_length = len;
+    if (len != 0) {
+        rl->rstate = SSL_ST_READ_HEADER;
+        if (!SSL3_BUFFER_is_initialised(&rl->rbuf))
+            if (!ssl3_setup_read_buffer(rl->s))
+                return 0;
+    }
+
+    rl->packet = SSL3_BUFFER_get_buf(&rl->rbuf);
+    SSL3_BUFFER_set_data(&rl->rbuf, buf, len);
+
+    return 1;
+}
+
+void RECORD_LAYER_reset_read_sequence(RECORD_LAYER *rl)
+{
+    memset(rl->read_sequence, 0, sizeof(rl->read_sequence));
+}
+
+void RECORD_LAYER_reset_write_sequence(RECORD_LAYER *rl)
+{
+    memset(rl->write_sequence, 0, sizeof(rl->write_sequence));
+}
+
+int ssl3_pending(const SSL *s)
+{
+    unsigned int i;
+    int num = 0;
+
+    if (s->rlayer.rstate == SSL_ST_READ_BODY)
+        return 0;
+
+    for (i = 0; i < RECORD_LAYER_get_numrpipes(&s->rlayer); i++) {
+        if (SSL3_RECORD_get_type(&s->rlayer.rrec[i])
+            != SSL3_RT_APPLICATION_DATA)
+            return 0;
+        num += SSL3_RECORD_get_length(&s->rlayer.rrec[i]);
+    }
+
+    return num;
+}
+
+void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len)
+{
+    ctx->default_read_buf_len = len;
+}
+
+void SSL_set_default_read_buffer_len(SSL *s, size_t len)
+{
+    SSL3_BUFFER_set_default_len(RECORD_LAYER_get_rbuf(&s->rlayer), len);
+}
+
+const char *SSL_rstate_string_long(const SSL *s)
+{
+    switch (s->rlayer.rstate) {
+    case SSL_ST_READ_HEADER:
+        return "read header";
+    case SSL_ST_READ_BODY:
+        return "read body";
+    case SSL_ST_READ_DONE:
+        return "read done";
+    default:
+        return "unknown";
+    }
+}
+
+const char *SSL_rstate_string(const SSL *s)
+{
+    switch (s->rlayer.rstate) {
+    case SSL_ST_READ_HEADER:
+        return "RH";
+    case SSL_ST_READ_BODY:
+        return "RB";
+    case SSL_ST_READ_DONE:
+        return "RD";
+    default:
+        return "unknown";
+    }
+}
+
+/*
+ * Return values are as per SSL_read()
+ */
+int ssl3_read_n(SSL *s, int n, int max, int extend, int clearold)
+{
+    /*
+     * If extend == 0, obtain new n-byte packet; if extend == 1, increase
+     * packet by another n bytes. The packet will be in the sub-array of
+     * s->s3->rbuf.buf specified by s->packet and s->packet_length. (If
+     * s->rlayer.read_ahead is set, 'max' bytes may be stored in rbuf [plus
+     * s->packet_length bytes if extend == 1].)
+     * if clearold == 1, move the packet to the start of the buffer; if
+     * clearold == 0 then leave any old packets where they were
+     */
+    int i, len, left;
+    size_t align = 0;
+    unsigned char *pkt;
+    SSL3_BUFFER *rb;
+
+    if (n <= 0)
+        return n;
+
+    rb = &s->rlayer.rbuf;
+    if (rb->buf == NULL)
+        if (!ssl3_setup_read_buffer(s))
+            return -1;
+
+    left = rb->left;
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+    align = (size_t)rb->buf + SSL3_RT_HEADER_LENGTH;
+    align = SSL3_ALIGN_PAYLOAD - 1 - ((align - 1) % SSL3_ALIGN_PAYLOAD);
+#endif
+
+    if (!extend) {
+        /* start with empty packet ... */
+        if (left == 0)
+            rb->offset = align;
+        else if (align != 0 && left >= SSL3_RT_HEADER_LENGTH) {
+            /*
+             * check if next packet length is large enough to justify payload
+             * alignment...
+             */
+            pkt = rb->buf + rb->offset;
+            if (pkt[0] == SSL3_RT_APPLICATION_DATA
+                && (pkt[3] << 8 | pkt[4]) >= 128) {
+                /*
+                 * Note that even if packet is corrupted and its length field
+                 * is insane, we can only be led to wrong decision about
+                 * whether memmove will occur or not. Header values has no
+                 * effect on memmove arguments and therefore no buffer
+                 * overrun can be triggered.
+                 */
+                memmove(rb->buf + align, pkt, left);
+                rb->offset = align;
+            }
+        }
+        s->rlayer.packet = rb->buf + rb->offset;
+        s->rlayer.packet_length = 0;
+        /* ... now we can act as if 'extend' was set */
+    }
+
+    len = s->rlayer.packet_length;
+    pkt = rb->buf + align;
+    /*
+     * Move any available bytes to front of buffer: 'len' bytes already
+     * pointed to by 'packet', 'left' extra ones at the end
+     */
+    if (s->rlayer.packet != pkt && clearold == 1) {
+        memmove(pkt, s->rlayer.packet, len + left);
+        s->rlayer.packet = pkt;
+        rb->offset = len + align;
+    }
+
+    /*
+     * For DTLS/UDP reads should not span multiple packets because the read
+     * operation returns the whole packet at once (as long as it fits into
+     * the buffer).
+     */
+    if (SSL_IS_DTLS(s)) {
+        if (left == 0 && extend)
+            return 0;
+        if (left > 0 && n > left)
+            n = left;
+    }
+
+    /* if there is enough in the buffer from a previous read, take some */
+    if (left >= n) {
+        s->rlayer.packet_length += n;
+        rb->left = left - n;
+        rb->offset += n;
+        return (n);
+    }
+
+    /* else we need to read more data */
+
+    if (n > (int)(rb->len - rb->offset)) { /* does not happen */
+        SSLerr(SSL_F_SSL3_READ_N, ERR_R_INTERNAL_ERROR);
+        return -1;
+    }
+
+    /* We always act like read_ahead is set for DTLS */
+    if (!s->rlayer.read_ahead && !SSL_IS_DTLS(s))
+        /* ignore max parameter */
+        max = n;
+    else {
+        if (max < n)
+            max = n;
+        if (max > (int)(rb->len - rb->offset))
+            max = rb->len - rb->offset;
+    }
+
+    while (left < n) {
+        /*
+         * Now we have len+left bytes at the front of s->s3->rbuf.buf and
+         * need to read in more until we have len+n (up to len+max if
+         * possible)
+         */
+
+        clear_sys_error();
+        if (s->rbio != NULL) {
+            s->rwstate = SSL_READING;
+            i = BIO_read(s->rbio, pkt + len + left, max - left);
+        } else {
+            SSLerr(SSL_F_SSL3_READ_N, SSL_R_READ_BIO_NOT_SET);
+            i = -1;
+        }
+
+        if (i <= 0) {
+            rb->left = left;
+            if (s->mode & SSL_MODE_RELEASE_BUFFERS && !SSL_IS_DTLS(s))
+                if (len + left == 0)
+                    ssl3_release_read_buffer(s);
+            return i;
+        }
+        left += i;
+        /*
+         * reads should *never* span multiple packets for DTLS because the
+         * underlying transport protocol is message oriented as opposed to
+         * byte oriented as in the TLS case.
+         */
+        if (SSL_IS_DTLS(s)) {
+            if (n > left)
+                n = left;       /* makes the while condition false */
+        }
+    }
+
+    /* done reading, now the book-keeping */
+    rb->offset += n;
+    rb->left = left - n;
+    s->rlayer.packet_length += n;
+    s->rwstate = SSL_NOTHING;
+    return (n);
+}
+
+/*
+ * Call this to write data in records of type 'type' It will return <= 0 if
+ * not all data has been sent or non-blocking IO.
+ */
+int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
+{
+    const unsigned char *buf = buf_;
+    int tot;
+    unsigned int n, split_send_fragment, maxpipes;
+#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
+    unsigned int max_send_fragment, nw;
+    unsigned int u_len = (unsigned int)len;
+#endif
+    SSL3_BUFFER *wb = &s->rlayer.wbuf[0];
+    int i;
+
+    if (len < 0) {
+        SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_SSL_NEGATIVE_LENGTH);
+        return -1;
+    }
+
+    s->rwstate = SSL_NOTHING;
+    tot = s->rlayer.wnum;
+    /*
+     * ensure that if we end up with a smaller value of data to write out
+     * than the the original len from a write which didn't complete for
+     * non-blocking I/O and also somehow ended up avoiding the check for
+     * this in ssl3_write_pending/SSL_R_BAD_WRITE_RETRY as it must never be
+     * possible to end up with (len-tot) as a large number that will then
+     * promptly send beyond the end of the users buffer ... so we trap and
+     * report the error in a way the user will notice
+     */
+    if ((unsigned int)len < s->rlayer.wnum) {
+        SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_BAD_LENGTH);
+        return -1;
+    }
+
+    s->rlayer.wnum = 0;
+
+    if (SSL_in_init(s) && !ossl_statem_get_in_handshake(s)) {
+        i = s->handshake_func(s);
+        if (i < 0)
+            return (i);
+        if (i == 0) {
+            SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE);
+            return -1;
+        }
+    }
+
+    /*
+     * first check if there is a SSL3_BUFFER still being written out.  This
+     * will happen with non blocking IO
+     */
+    if (wb->left != 0) {
+        i = ssl3_write_pending(s, type, &buf[tot], s->rlayer.wpend_tot);
+        if (i <= 0) {
+            /* XXX should we ssl3_release_write_buffer if i<0? */
+            s->rlayer.wnum = tot;
+            return i;
+        }
+        tot += i;               /* this might be last fragment */
+    }
+#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
+    /*
+     * Depending on platform multi-block can deliver several *times*
+     * better performance. Downside is that it has to allocate
+     * jumbo buffer to accommodate up to 8 records, but the
+     * compromise is considered worthy.
+     */
+    if (type == SSL3_RT_APPLICATION_DATA &&
+        u_len >= 4 * (max_send_fragment = s->max_send_fragment) &&
+        s->compress == NULL && s->msg_callback == NULL &&
+        !SSL_WRITE_ETM(s) && SSL_USE_EXPLICIT_IV(s) &&
+        EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_write_ctx)) &
+        EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) {
+        unsigned char aad[13];
+        EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
+        int packlen;
+
+        /* minimize address aliasing conflicts */
+        if ((max_send_fragment & 0xfff) == 0)
+            max_send_fragment -= 512;
+
+        if (tot == 0 || wb->buf == NULL) { /* allocate jumbo buffer */
+            ssl3_release_write_buffer(s);
+
+            packlen = EVP_CIPHER_CTX_ctrl(s->enc_write_ctx,
+                                          EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE,
+                                          max_send_fragment, NULL);
+
+            if (u_len >= 8 * max_send_fragment)
+                packlen *= 8;
+            else
+                packlen *= 4;
+
+            if (!ssl3_setup_write_buffer(s, 1, packlen)) {
+                SSLerr(SSL_F_SSL3_WRITE_BYTES, ERR_R_MALLOC_FAILURE);
+                return -1;
+            }
+        } else if (tot == len) { /* done? */
+            /* free jumbo buffer */
+            ssl3_release_write_buffer(s);
+            return tot;
+        }
+
+        n = (len - tot);
+        for (;;) {
+            if (n < 4 * max_send_fragment) {
+                /* free jumbo buffer */
+                ssl3_release_write_buffer(s);
+                break;
+            }
+
+            if (s->s3->alert_dispatch) {
+                i = s->method->ssl_dispatch_alert(s);
+                if (i <= 0) {
+                    s->rlayer.wnum = tot;
+                    return i;
+                }
+            }
+
+            if (n >= 8 * max_send_fragment)
+                nw = max_send_fragment * (mb_param.interleave = 8);
+            else
+                nw = max_send_fragment * (mb_param.interleave = 4);
+
+            memcpy(aad, s->rlayer.write_sequence, 8);
+            aad[8] = type;
+            aad[9] = (unsigned char)(s->version >> 8);
+            aad[10] = (unsigned char)(s->version);
+            aad[11] = 0;
+            aad[12] = 0;
+            mb_param.out = NULL;
+            mb_param.inp = aad;
+            mb_param.len = nw;
+
+            packlen = EVP_CIPHER_CTX_ctrl(s->enc_write_ctx,
+                                          EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
+                                          sizeof(mb_param), &mb_param);
+
+            if (packlen <= 0 || packlen > (int)wb->len) { /* never happens */
+                /* free jumbo buffer */
+                ssl3_release_write_buffer(s);
+                break;
+            }
+
+            mb_param.out = wb->buf;
+            mb_param.inp = &buf[tot];
+            mb_param.len = nw;
+
+            if (EVP_CIPHER_CTX_ctrl(s->enc_write_ctx,
+                                    EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
+                                    sizeof(mb_param), &mb_param) <= 0)
+                return -1;
+
+            s->rlayer.write_sequence[7] += mb_param.interleave;
+            if (s->rlayer.write_sequence[7] < mb_param.interleave) {
+                int j = 6;
+                while (j >= 0 && (++s->rlayer.write_sequence[j--]) == 0) ;
+            }
+
+            wb->offset = 0;
+            wb->left = packlen;
+
+            s->rlayer.wpend_tot = nw;
+            s->rlayer.wpend_buf = &buf[tot];
+            s->rlayer.wpend_type = type;
+            s->rlayer.wpend_ret = nw;
+
+            i = ssl3_write_pending(s, type, &buf[tot], nw);
+            if (i <= 0) {
+                if (i < 0 && (!s->wbio || !BIO_should_retry(s->wbio))) {
+                    /* free jumbo buffer */
+                    ssl3_release_write_buffer(s);
+                }
+                s->rlayer.wnum = tot;
+                return i;
+            }
+            if (i == (int)n) {
+                /* free jumbo buffer */
+                ssl3_release_write_buffer(s);
+                return tot + i;
+            }
+            n -= i;
+            tot += i;
+        }
+    } else
+#endif
+    if (tot == len) {           /* done? */
+        if (s->mode & SSL_MODE_RELEASE_BUFFERS && !SSL_IS_DTLS(s))
+            ssl3_release_write_buffer(s);
+
+        return tot;
+    }
+
+    n = (len - tot);
+
+    split_send_fragment = s->split_send_fragment;
+    /*
+     * If max_pipelines is 0 then this means "undefined" and we default to
+     * 1 pipeline. Similarly if the cipher does not support pipelined
+     * processing then we also only use 1 pipeline, or if we're not using
+     * explicit IVs
+     */
+    maxpipes = s->max_pipelines;
+    if (maxpipes > SSL_MAX_PIPELINES) {
+        /*
+         * We should have prevented this when we set max_pipelines so we
+         * shouldn't get here
+         */
+        SSLerr(SSL_F_SSL3_WRITE_BYTES, ERR_R_INTERNAL_ERROR);
+        return -1;
+    }
+    if (maxpipes == 0
+        || s->enc_write_ctx == NULL
+        || !(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_write_ctx))
+             & EVP_CIPH_FLAG_PIPELINE)
+        || !SSL_USE_EXPLICIT_IV(s))
+        maxpipes = 1;
+    if (s->max_send_fragment == 0 || split_send_fragment > s->max_send_fragment
+        || split_send_fragment == 0) {
+        /*
+         * We should have prevented this when we set the split and max send
+         * fragments so we shouldn't get here
+         */
+        SSLerr(SSL_F_SSL3_WRITE_BYTES, ERR_R_INTERNAL_ERROR);
+        return -1;
+    }
+
+    for (;;) {
+        unsigned int pipelens[SSL_MAX_PIPELINES], tmppipelen, remain;
+        unsigned int numpipes, j;
+
+        if (n == 0)
+            numpipes = 1;
+        else
+            numpipes = ((n - 1) / split_send_fragment) + 1;
+        if (numpipes > maxpipes)
+            numpipes = maxpipes;
+
+        if (n / numpipes >= s->max_send_fragment) {
+            /*
+             * We have enough data to completely fill all available
+             * pipelines
+             */
+            for (j = 0; j < numpipes; j++) {
+                pipelens[j] = s->max_send_fragment;
+            }
+        } else {
+            /* We can partially fill all available pipelines */
+            tmppipelen = n / numpipes;
+            remain = n % numpipes;
+            for (j = 0; j < numpipes; j++) {
+                pipelens[j] = tmppipelen;
+                if (j < remain)
+                    pipelens[j]++;
+            }
+        }
+
+        i = do_ssl3_write(s, type, &(buf[tot]), pipelens, numpipes, 0);
+        if (i <= 0) {
+            /* XXX should we ssl3_release_write_buffer if i<0? */
+            s->rlayer.wnum = tot;
+            return i;
+        }
+
+        if ((i == (int)n) ||
+            (type == SSL3_RT_APPLICATION_DATA &&
+             (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) {
+            /*
+             * next chunk of data should get another prepended empty fragment
+             * in ciphersuites with known-IV weakness:
+             */
+            s->s3->empty_fragment_done = 0;
+
+            if ((i == (int)n) && s->mode & SSL_MODE_RELEASE_BUFFERS &&
+                !SSL_IS_DTLS(s))
+                ssl3_release_write_buffer(s);
+
+            return tot + i;
+        }
+
+        n -= i;
+        tot += i;
+    }
+}
+
+int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+                  unsigned int *pipelens, unsigned int numpipes,
+                  int create_empty_fragment)
+{
+    unsigned char *outbuf[SSL_MAX_PIPELINES], *plen[SSL_MAX_PIPELINES];
+    SSL3_RECORD wr[SSL_MAX_PIPELINES];
+    int i, mac_size, clear = 0;
+    int prefix_len = 0;
+    int eivlen;
+    size_t align = 0;
+    SSL3_BUFFER *wb;
+    SSL_SESSION *sess;
+    unsigned int totlen = 0;
+    unsigned int j;
+
+    for (j = 0; j < numpipes; j++)
+        totlen += pipelens[j];
+    /*
+     * first check if there is a SSL3_BUFFER still being written out.  This
+     * will happen with non blocking IO
+     */
+    if (RECORD_LAYER_write_pending(&s->rlayer))
+        return (ssl3_write_pending(s, type, buf, totlen));
+
+    /* If we have an alert to send, lets send it */
+    if (s->s3->alert_dispatch) {
+        i = s->method->ssl_dispatch_alert(s);
+        if (i <= 0)
+            return (i);
+        /* if it went, fall through and send more stuff */
+    }
+
+    if (s->rlayer.numwpipes < numpipes)
+        if (!ssl3_setup_write_buffer(s, numpipes, 0))
+            return -1;
+
+    if (totlen == 0 && !create_empty_fragment)
+        return 0;
+
+    sess = s->session;
+
+    if ((sess == NULL) ||
+        (s->enc_write_ctx == NULL) || (EVP_MD_CTX_md(s->write_hash) == NULL)) {
+        clear = s->enc_write_ctx ? 0 : 1; /* must be AEAD cipher */
+        mac_size = 0;
+    } else {
+        mac_size = EVP_MD_CTX_size(s->write_hash);
+        if (mac_size < 0)
+            goto err;
+    }
+
+    /*
+     * 'create_empty_fragment' is true only when this function calls itself
+     */
+    if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done) {
+        /*
+         * countermeasure against known-IV weakness in CBC ciphersuites (see
+         * http://www.openssl.org/~bodo/tls-cbc.txt)
+         */
+
+        if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA) {
+            /*
+             * recursive function call with 'create_empty_fragment' set; this
+             * prepares and buffers the data for an empty fragment (these
+             * 'prefix_len' bytes are sent out later together with the actual
+             * payload)
+             */
+            unsigned int tmppipelen = 0;
+
+            prefix_len = do_ssl3_write(s, type, buf, &tmppipelen, 1, 1);
+            if (prefix_len <= 0)
+                goto err;
+
+            if (prefix_len >
+                (SSL3_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD)) {
+                /* insufficient space */
+                SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
+                goto err;
+            }
+        }
+
+        s->s3->empty_fragment_done = 1;
+    }
+
+    if (create_empty_fragment) {
+        wb = &s->rlayer.wbuf[0];
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+        /*
+         * extra fragment would be couple of cipher blocks, which would be
+         * multiple of SSL3_ALIGN_PAYLOAD, so if we want to align the real
+         * payload, then we can just pretend we simply have two headers.
+         */
+        align = (size_t)SSL3_BUFFER_get_buf(wb) + 2 * SSL3_RT_HEADER_LENGTH;
+        align = SSL3_ALIGN_PAYLOAD - 1 - ((align - 1) % SSL3_ALIGN_PAYLOAD);
+#endif
+        outbuf[0] = SSL3_BUFFER_get_buf(wb) + align;
+        SSL3_BUFFER_set_offset(wb, align);
+    } else if (prefix_len) {
+        wb = &s->rlayer.wbuf[0];
+        outbuf[0] = SSL3_BUFFER_get_buf(wb) + SSL3_BUFFER_get_offset(wb)
+            + prefix_len;
+    } else {
+        for (j = 0; j < numpipes; j++) {
+            wb = &s->rlayer.wbuf[j];
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+            align = (size_t)SSL3_BUFFER_get_buf(wb) + SSL3_RT_HEADER_LENGTH;
+            align = SSL3_ALIGN_PAYLOAD - 1 - ((align - 1) % SSL3_ALIGN_PAYLOAD);
+#endif
+            outbuf[j] = SSL3_BUFFER_get_buf(wb) + align;
+            SSL3_BUFFER_set_offset(wb, align);
+        }
+    }
+
+    /* Explicit IV length, block ciphers appropriate version flag */
+    if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s)) {
+        int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx);
+        if (mode == EVP_CIPH_CBC_MODE) {
+            eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx);
+            if (eivlen <= 1)
+                eivlen = 0;
+        }
+        /* Need explicit part of IV for GCM mode */
+        else if (mode == EVP_CIPH_GCM_MODE)
+            eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
+        else if (mode == EVP_CIPH_CCM_MODE)
+            eivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
+        else
+            eivlen = 0;
+    } else
+        eivlen = 0;
+
+    totlen = 0;
+    /* Clear our SSL3_RECORD structures */
+    memset(wr, 0, sizeof wr);
+    for (j = 0; j < numpipes; j++) {
+        /* write the header */
+        *(outbuf[j]++) = type & 0xff;
+        SSL3_RECORD_set_type(&wr[j], type);
+
+        *(outbuf[j]++) = (s->version >> 8);
+        /*
+         * Some servers hang if initial client hello is larger than 256 bytes
+         * and record version number > TLS 1.0
+         */
+        if (SSL_get_state(s) == TLS_ST_CW_CLNT_HELLO
+            && !s->renegotiate && TLS1_get_version(s) > TLS1_VERSION)
+            *(outbuf[j]++) = 0x1;
+        else
+            *(outbuf[j]++) = s->version & 0xff;
+
+        /* field where we are to write out packet length */
+        plen[j] = outbuf[j];
+        outbuf[j] += 2;
+
+        /* lets setup the record stuff. */
+        SSL3_RECORD_set_data(&wr[j], outbuf[j] + eivlen);
+        SSL3_RECORD_set_length(&wr[j], (int)pipelens[j]);
+        SSL3_RECORD_set_input(&wr[j], (unsigned char *)&buf[totlen]);
+        totlen += pipelens[j];
+
+        /*
+         * we now 'read' from wr->input, wr->length bytes into wr->data
+         */
+
+        /* first we compress */
+        if (s->compress != NULL) {
+            if (!ssl3_do_compress(s, &wr[j])) {
+                SSLerr(SSL_F_DO_SSL3_WRITE, SSL_R_COMPRESSION_FAILURE);
+                goto err;
+            }
+        } else {
+            memcpy(wr[j].data, wr[j].input, wr[j].length);
+            SSL3_RECORD_reset_input(&wr[j]);
+        }
+
+        /*
+         * we should still have the output to wr->data and the input from
+         * wr->input.  Length should be wr->length. wr->data still points in the
+         * wb->buf
+         */
+
+        if (!SSL_WRITE_ETM(s) && mac_size != 0) {
+            if (s->method->ssl3_enc->mac(s, &wr[j],
+                                         &(outbuf[j][wr[j].length + eivlen]),
+                                         1) < 0)
+                goto err;
+            SSL3_RECORD_add_length(&wr[j], mac_size);
+        }
+
+        SSL3_RECORD_set_data(&wr[j], outbuf[j]);
+        SSL3_RECORD_reset_input(&wr[j]);
+
+        if (eivlen) {
+            /*
+             * if (RAND_pseudo_bytes(p, eivlen) <= 0) goto err;
+             */
+            SSL3_RECORD_add_length(&wr[j], eivlen);
+        }
+    }
+
+    if (s->method->ssl3_enc->enc(s, wr, numpipes, 1) < 1)
+        goto err;
+
+    for (j = 0; j < numpipes; j++) {
+        if (SSL_WRITE_ETM(s) && mac_size != 0) {
+            if (s->method->ssl3_enc->mac(s, &wr[j],
+                                         outbuf[j] + wr[j].length, 1) < 0)
+                goto err;
+            SSL3_RECORD_add_length(&wr[j], mac_size);
+        }
+
+        /* record length after mac and block padding */
+        s2n(SSL3_RECORD_get_length(&wr[j]), plen[j]);
+
+        if (s->msg_callback)
+            s->msg_callback(1, 0, SSL3_RT_HEADER, plen[j] - 5, 5, s,
+                            s->msg_callback_arg);
+
+        /*
+         * we should now have wr->data pointing to the encrypted data, which is
+         * wr->length long
+         */
+        SSL3_RECORD_set_type(&wr[j], type); /* not needed but helps for
+                                             * debugging */
+        SSL3_RECORD_add_length(&wr[j], SSL3_RT_HEADER_LENGTH);
+
+        if (create_empty_fragment) {
+            /*
+             * we are in a recursive call; just return the length, don't write
+             * out anything here
+             */
+            if (j > 0) {
+                /* We should never be pipelining an empty fragment!! */
+                SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
+                goto err;
+            }
+            return SSL3_RECORD_get_length(wr);
+        }
+
+        /* now let's set up wb */
+        SSL3_BUFFER_set_left(&s->rlayer.wbuf[j],
+                             prefix_len + SSL3_RECORD_get_length(&wr[j]));
+    }
+
+    /*
+     * memorize arguments so that ssl3_write_pending can detect bad write
+     * retries later
+     */
+    s->rlayer.wpend_tot = totlen;
+    s->rlayer.wpend_buf = buf;
+    s->rlayer.wpend_type = type;
+    s->rlayer.wpend_ret = totlen;
+
+    /* we now just need to write the buffer */
+    return ssl3_write_pending(s, type, buf, totlen);
+ err:
+    return -1;
+}
+
+/* if s->s3->wbuf.left != 0, we need to call this
+ *
+ * Return values are as per SSL_write()
+ */
+int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
+                       unsigned int len)
+{
+    int i;
+    SSL3_BUFFER *wb = s->rlayer.wbuf;
+    unsigned int currbuf = 0;
+
+/* XXXX */
+    if ((s->rlayer.wpend_tot > (int)len)
+        || ((s->rlayer.wpend_buf != buf) &&
+            !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER))
+        || (s->rlayer.wpend_type != type)) {
+        SSLerr(SSL_F_SSL3_WRITE_PENDING, SSL_R_BAD_WRITE_RETRY);
+        return (-1);
+    }
+
+    for (;;) {
+        /* Loop until we find a buffer we haven't written out yet */
+        if (SSL3_BUFFER_get_left(&wb[currbuf]) == 0
+            && currbuf < s->rlayer.numwpipes - 1) {
+            currbuf++;
+            continue;
+        }
+        clear_sys_error();
+        if (s->wbio != NULL) {
+            s->rwstate = SSL_WRITING;
+            i = BIO_write(s->wbio, (char *)
+                          &(SSL3_BUFFER_get_buf(&wb[currbuf])
+                            [SSL3_BUFFER_get_offset(&wb[currbuf])]),
+                          (unsigned int)SSL3_BUFFER_get_left(&wb[currbuf]));
+        } else {
+            SSLerr(SSL_F_SSL3_WRITE_PENDING, SSL_R_BIO_NOT_SET);
+            i = -1;
+        }
+        if (i == SSL3_BUFFER_get_left(&wb[currbuf])) {
+            SSL3_BUFFER_set_left(&wb[currbuf], 0);
+            SSL3_BUFFER_add_offset(&wb[currbuf], i);
+            if (currbuf + 1 < s->rlayer.numwpipes)
+                continue;
+            s->rwstate = SSL_NOTHING;
+            return (s->rlayer.wpend_ret);
+        } else if (i <= 0) {
+            if (SSL_IS_DTLS(s)) {
+                /*
+                 * For DTLS, just drop it. That's kind of the whole point in
+                 * using a datagram service
+                 */
+                SSL3_BUFFER_set_left(&wb[currbuf], 0);
+            }
+            return i;
+        }
+        SSL3_BUFFER_add_offset(&wb[currbuf], i);
+        SSL3_BUFFER_add_left(&wb[currbuf], -i);
+    }
+}
+
+/*-
+ * Return up to 'len' payload bytes received in 'type' records.
+ * 'type' is one of the following:
+ *
+ *   -  SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
+ *   -  SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
+ *   -  0 (during a shutdown, no data has to be returned)
+ *
+ * If we don't have stored data to work from, read a SSL/TLS record first
+ * (possibly multiple records if we still don't have anything to return).
+ *
+ * This function must handle any surprises the peer may have for us, such as
+ * Alert records (e.g. close_notify) or renegotiation requests. ChangeCipherSpec
+ * messages are treated as if they were handshake messages *if* the |recd_type|
+ * argument is non NULL.
+ * Also if record payloads contain fragments too small to process, we store
+ * them until there is enough for the respective protocol (the record protocol
+ * may use arbitrary fragmentation and even interleaving):
+ *     Change cipher spec protocol
+ *             just 1 byte needed, no need for keeping anything stored
+ *     Alert protocol
+ *             2 bytes needed (AlertLevel, AlertDescription)
+ *     Handshake protocol
+ *             4 bytes needed (HandshakeType, uint24 length) -- we just have
+ *             to detect unexpected Client Hello and Hello Request messages
+ *             here, anything else is handled by higher layers
+ *     Application data protocol
+ *             none of our business
+ */
+int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
+                    int len, int peek)
+{
+    int al, i, j, ret;
+    unsigned int n, curr_rec, num_recs, read_bytes;
+    SSL3_RECORD *rr;
+    SSL3_BUFFER *rbuf;
+    void (*cb) (const SSL *ssl, int type2, int val) = NULL;
+
+    rbuf = &s->rlayer.rbuf;
+
+    if (!SSL3_BUFFER_is_initialised(rbuf)) {
+        /* Not initialized yet */
+        if (!ssl3_setup_read_buffer(s))
+            return (-1);
+    }
+
+    if ((type && (type != SSL3_RT_APPLICATION_DATA)
+         && (type != SSL3_RT_HANDSHAKE)) || (peek
+                                             && (type !=
+                                                 SSL3_RT_APPLICATION_DATA))) {
+        SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR);
+        return -1;
+    }
+
+    if ((type == SSL3_RT_HANDSHAKE) && (s->rlayer.handshake_fragment_len > 0))
+        /* (partially) satisfy request from storage */
+    {
+        unsigned char *src = s->rlayer.handshake_fragment;
+        unsigned char *dst = buf;
+        unsigned int k;
+
+        /* peek == 0 */
+        n = 0;
+        while ((len > 0) && (s->rlayer.handshake_fragment_len > 0)) {
+            *dst++ = *src++;
+            len--;
+            s->rlayer.handshake_fragment_len--;
+            n++;
+        }
+        /* move any remaining fragment bytes: */
+        for (k = 0; k < s->rlayer.handshake_fragment_len; k++)
+            s->rlayer.handshake_fragment[k] = *src++;
+
+        if (recvd_type != NULL)
+            *recvd_type = SSL3_RT_HANDSHAKE;
+
+        return n;
+    }
+
+    /*
+     * Now s->rlayer.handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE.
+     */
+
+    if (!ossl_statem_get_in_handshake(s) && SSL_in_init(s)) {
+        /* type == SSL3_RT_APPLICATION_DATA */
+        i = s->handshake_func(s);
+        if (i < 0)
+            return (i);
+        if (i == 0) {
+            SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE);
+            return (-1);
+        }
+    }
+ start:
+    s->rwstate = SSL_NOTHING;
+
+    /*-
+     * For each record 'i' up to |num_recs]
+     * rr[i].type     - is the type of record
+     * rr[i].data,    - data
+     * rr[i].off,     - offset into 'data' for next read
+     * rr[i].length,  - number of bytes.
+     */
+    rr = s->rlayer.rrec;
+    num_recs = RECORD_LAYER_get_numrpipes(&s->rlayer);
+
+    do {
+        /* get new records if necessary */
+        if (num_recs == 0) {
+            ret = ssl3_get_record(s);
+            if (ret <= 0)
+                return (ret);
+            num_recs = RECORD_LAYER_get_numrpipes(&s->rlayer);
+            if (num_recs == 0) {
+                /* Shouldn't happen */
+                al = SSL_AD_INTERNAL_ERROR;
+                SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR);
+                goto f_err;
+            }
+        }
+        /* Skip over any records we have already read */
+        for (curr_rec = 0;
+             curr_rec < num_recs && SSL3_RECORD_is_read(&rr[curr_rec]);
+             curr_rec++) ;
+        if (curr_rec == num_recs) {
+            RECORD_LAYER_set_numrpipes(&s->rlayer, 0);
+            num_recs = 0;
+            curr_rec = 0;
+        }
+    } while (num_recs == 0);
+    rr = &rr[curr_rec];
+
+    /*
+     * Reset the count of consecutive warning alerts if we've got a non-empty
+     * record that isn't an alert.
+     */
+    if (SSL3_RECORD_get_type(rr) != SSL3_RT_ALERT
+            && SSL3_RECORD_get_length(rr) != 0)
+        s->rlayer.alert_count = 0;
+
+    /* we now have a packet which can be read and processed */
+
+    if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
+                                   * reset by ssl3_get_finished */
+        && (SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE)) {
+        al = SSL_AD_UNEXPECTED_MESSAGE;
+        SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);
+        goto f_err;
+    }
+
+    /*
+     * If the other end has shut down, throw anything we read away (even in
+     * 'peek' mode)
+     */
+    if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
+        SSL3_RECORD_set_length(rr, 0);
+        s->rwstate = SSL_NOTHING;
+        return (0);
+    }
+
+    if (type == SSL3_RECORD_get_type(rr)
+        || (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC
+            && type == SSL3_RT_HANDSHAKE && recvd_type != NULL)) {
+        /*
+         * SSL3_RT_APPLICATION_DATA or
+         * SSL3_RT_HANDSHAKE or
+         * SSL3_RT_CHANGE_CIPHER_SPEC
+         */
+        /*
+         * make sure that we are not getting application data when we are
+         * doing a handshake for the first time
+         */
+        if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&
+            (s->enc_read_ctx == NULL)) {
+            al = SSL_AD_UNEXPECTED_MESSAGE;
+            SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_APP_DATA_IN_HANDSHAKE);
+            goto f_err;
+        }
+
+        if (type == SSL3_RT_HANDSHAKE
+            && SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC
+            && s->rlayer.handshake_fragment_len > 0) {
+            al = SSL_AD_UNEXPECTED_MESSAGE;
+            SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_CCS_RECEIVED_EARLY);
+            goto f_err;
+        }
+
+        if (recvd_type != NULL)
+            *recvd_type = SSL3_RECORD_get_type(rr);
+
+        if (len <= 0)
+            return (len);
+
+        read_bytes = 0;
+        do {
+            if ((unsigned int)len - read_bytes > SSL3_RECORD_get_length(rr))
+                n = SSL3_RECORD_get_length(rr);
+            else
+                n = (unsigned int)len - read_bytes;
+
+            memcpy(buf, &(rr->data[rr->off]), n);
+            buf += n;
+            if (peek) {
+                /* Mark any zero length record as consumed CVE-2016-6305 */
+                if (SSL3_RECORD_get_length(rr) == 0)
+                    SSL3_RECORD_set_read(rr);
+            } else {
+                SSL3_RECORD_sub_length(rr, n);
+                SSL3_RECORD_add_off(rr, n);
+                if (SSL3_RECORD_get_length(rr) == 0) {
+                    s->rlayer.rstate = SSL_ST_READ_HEADER;
+                    SSL3_RECORD_set_off(rr, 0);
+                    SSL3_RECORD_set_read(rr);
+                }
+            }
+            if (SSL3_RECORD_get_length(rr) == 0
+                || (peek && n == SSL3_RECORD_get_length(rr))) {
+                curr_rec++;
+                rr++;
+            }
+            read_bytes += n;
+        } while (type == SSL3_RT_APPLICATION_DATA && curr_rec < num_recs
+                 && read_bytes < (unsigned int)len);
+        if (read_bytes == 0) {
+            /* We must have read empty records. Get more data */
+            goto start;
+        }
+        if (!peek && curr_rec == num_recs
+            && (s->mode & SSL_MODE_RELEASE_BUFFERS)
+            && SSL3_BUFFER_get_left(rbuf) == 0)
+            ssl3_release_read_buffer(s);
+        return read_bytes;
+    }
+
+    /*
+     * If we get here, then type != rr->type; if we have a handshake message,
+     * then it was unexpected (Hello Request or Client Hello) or invalid (we
+     * were actually expecting a CCS).
+     */
+
+    /*
+     * Lets just double check that we've not got an SSLv2 record
+     */
+    if (rr->rec_version == SSL2_VERSION) {
+        /*
+         * Should never happen. ssl3_get_record() should only give us an SSLv2
+         * record back if this is the first packet and we are looking for an
+         * initial ClientHello. Therefore |type| should always be equal to
+         * |rr->type|. If not then something has gone horribly wrong
+         */
+        al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR);
+        goto f_err;
+    }
+
+    if (s->method->version == TLS_ANY_VERSION
+        && (s->server || rr->type != SSL3_RT_ALERT)) {
+        /*
+         * If we've got this far and still haven't decided on what version
+         * we're using then this must be a client side alert we're dealing with
+         * (we don't allow heartbeats yet). We shouldn't be receiving anything
+         * other than a ClientHello if we are a server.
+         */
+        s->version = rr->rec_version;
+        al = SSL_AD_UNEXPECTED_MESSAGE;
+        SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_MESSAGE);
+        goto f_err;
+    }
+
+    /*
+     * In case of record types for which we have 'fragment' storage, fill
+     * that so that we can process the data at a fixed place.
+     */
+    {
+        unsigned int dest_maxlen = 0;
+        unsigned char *dest = NULL;
+        unsigned int *dest_len = NULL;
+
+        if (SSL3_RECORD_get_type(rr) == SSL3_RT_HANDSHAKE) {
+            dest_maxlen = sizeof s->rlayer.handshake_fragment;
+            dest = s->rlayer.handshake_fragment;
+            dest_len = &s->rlayer.handshake_fragment_len;
+        } else if (SSL3_RECORD_get_type(rr) == SSL3_RT_ALERT) {
+            dest_maxlen = sizeof s->rlayer.alert_fragment;
+            dest = s->rlayer.alert_fragment;
+            dest_len = &s->rlayer.alert_fragment_len;
+        }
+
+        if (dest_maxlen > 0) {
+            n = dest_maxlen - *dest_len; /* available space in 'dest' */
+            if (SSL3_RECORD_get_length(rr) < n)
+                n = SSL3_RECORD_get_length(rr); /* available bytes */
+
+            /* now move 'n' bytes: */
+            while (n-- > 0) {
+                dest[(*dest_len)++] =
+                    SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)];
+                SSL3_RECORD_add_off(rr, 1);
+                SSL3_RECORD_add_length(rr, -1);
+            }
+
+            if (*dest_len < dest_maxlen) {
+                SSL3_RECORD_set_read(rr);
+                goto start;     /* fragment was too small */
+            }
+        }
+    }
+
+    /*-
+     * s->rlayer.handshake_fragment_len == 4  iff  rr->type == SSL3_RT_HANDSHAKE;
+     * s->rlayer.alert_fragment_len == 2      iff  rr->type == SSL3_RT_ALERT.
+     * (Possibly rr is 'empty' now, i.e. rr->length may be 0.)
+     */
+
+    /* If we are a client, check for an incoming 'Hello Request': */
+    if ((!s->server) &&
+        (s->rlayer.handshake_fragment_len >= 4) &&
+        (s->rlayer.handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&
+        (s->session != NULL) && (s->session->cipher != NULL)) {
+        s->rlayer.handshake_fragment_len = 0;
+
+        if ((s->rlayer.handshake_fragment[1] != 0) ||
+            (s->rlayer.handshake_fragment[2] != 0) ||
+            (s->rlayer.handshake_fragment[3] != 0)) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_BAD_HELLO_REQUEST);
+            goto f_err;
+        }
+
+        if (s->msg_callback)
+            s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
+                            s->rlayer.handshake_fragment, 4, s,
+                            s->msg_callback_arg);
+
+        if (SSL_is_init_finished(s) &&
+            !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
+            !s->s3->renegotiate) {
+            ssl3_renegotiate(s);
+            if (ssl3_renegotiate_check(s)) {
+                i = s->handshake_func(s);
+                if (i < 0)
+                    return (i);
+                if (i == 0) {
+                    SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE);
+                    return (-1);
+                }
+
+                if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
+                    if (SSL3_BUFFER_get_left(rbuf) == 0) {
+                        /* no read-ahead left? */
+                        BIO *bio;
+                        /*
+                         * In the case where we try to read application data,
+                         * but we trigger an SSL handshake, we return -1 with
+                         * the retry option set.  Otherwise renegotiation may
+                         * cause nasty problems in the blocking world
+                         */
+                        s->rwstate = SSL_READING;
+                        bio = SSL_get_rbio(s);
+                        BIO_clear_retry_flags(bio);
+                        BIO_set_retry_read(bio);
+                        return (-1);
+                    }
+                }
+            } else {
+                SSL3_RECORD_set_read(rr);
+            }
+        } else {
+            /* Does this ever happen? */
+            SSL3_RECORD_set_read(rr);
+        }
+        /*
+         * we either finished a handshake or ignored the request, now try
+         * again to obtain the (application) data we were asked for
+         */
+        goto start;
+    }
+    /*
+     * If we are a server and get a client hello when renegotiation isn't
+     * allowed send back a no renegotiation alert and carry on. WARNING:
+     * experimental code, needs reviewing (steve)
+     */
+    if (s->server &&
+        SSL_is_init_finished(s) &&
+        !s->s3->send_connection_binding &&
+        (s->version > SSL3_VERSION) &&
+        (s->rlayer.handshake_fragment_len >= 4) &&
+        (s->rlayer.handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) &&
+        (s->session != NULL) && (s->session->cipher != NULL) &&
+        !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
+        SSL3_RECORD_set_length(rr, 0);
+        SSL3_RECORD_set_read(rr);
+        ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
+        goto start;
+    }
+    if (s->rlayer.alert_fragment_len >= 2) {
+        int alert_level = s->rlayer.alert_fragment[0];
+        int alert_descr = s->rlayer.alert_fragment[1];
+
+        s->rlayer.alert_fragment_len = 0;
+
+        if (s->msg_callback)
+            s->msg_callback(0, s->version, SSL3_RT_ALERT,
+                            s->rlayer.alert_fragment, 2, s,
+                            s->msg_callback_arg);
+
+        if (s->info_callback != NULL)
+            cb = s->info_callback;
+        else if (s->ctx->info_callback != NULL)
+            cb = s->ctx->info_callback;
+
+        if (cb != NULL) {
+            j = (alert_level << 8) | alert_descr;
+            cb(s, SSL_CB_READ_ALERT, j);
+        }
+
+        if (alert_level == SSL3_AL_WARNING) {
+            s->s3->warn_alert = alert_descr;
+            SSL3_RECORD_set_read(rr);
+
+            s->rlayer.alert_count++;
+            if (s->rlayer.alert_count == MAX_WARN_ALERT_COUNT) {
+                al = SSL_AD_UNEXPECTED_MESSAGE;
+                SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS);
+                goto f_err;
+            }
+
+            if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
+                s->shutdown |= SSL_RECEIVED_SHUTDOWN;
+                return (0);
+            }
+            /*
+             * This is a warning but we receive it if we requested
+             * renegotiation and the peer denied it. Terminate with a fatal
+             * alert because if application tried to renegotiate it
+             * presumably had a good reason and expects it to succeed. In
+             * future we might have a renegotiation where we don't care if
+             * the peer refused it where we carry on.
+             */
+            else if (alert_descr == SSL_AD_NO_RENEGOTIATION) {
+                al = SSL_AD_HANDSHAKE_FAILURE;
+                SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_NO_RENEGOTIATION);
+                goto f_err;
+            }
+#ifdef SSL_AD_MISSING_SRP_USERNAME
+            else if (alert_descr == SSL_AD_MISSING_SRP_USERNAME)
+                return (0);
+#endif
+        } else if (alert_level == SSL3_AL_FATAL) {
+            char tmp[16];
+
+            s->rwstate = SSL_NOTHING;
+            s->s3->fatal_alert = alert_descr;
+            SSLerr(SSL_F_SSL3_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr);
+            BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr);
+            ERR_add_error_data(2, "SSL alert number ", tmp);
+            s->shutdown |= SSL_RECEIVED_SHUTDOWN;
+            SSL3_RECORD_set_read(rr);
+            SSL_CTX_remove_session(s->session_ctx, s->session);
+            return (0);
+        } else {
+            al = SSL_AD_ILLEGAL_PARAMETER;
+            SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNKNOWN_ALERT_TYPE);
+            goto f_err;
+        }
+
+        goto start;
+    }
+
+    if (s->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a
+                                            * shutdown */
+        s->rwstate = SSL_NOTHING;
+        SSL3_RECORD_set_length(rr, 0);
+        SSL3_RECORD_set_read(rr);
+        return (0);
+    }
+
+    if (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC) {
+        al = SSL_AD_UNEXPECTED_MESSAGE;
+        SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_CCS_RECEIVED_EARLY);
+        goto f_err;
+    }
+
+    /*
+     * Unexpected handshake message (Client Hello, or protocol violation)
+     */
+    if ((s->rlayer.handshake_fragment_len >= 4)
+        && !ossl_statem_get_in_handshake(s)) {
+        if (SSL_is_init_finished(s) &&
+            !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) {
+            ossl_statem_set_in_init(s, 1);
+            s->renegotiate = 1;
+            s->new_session = 1;
+        }
+        i = s->handshake_func(s);
+        if (i < 0)
+            return (i);
+        if (i == 0) {
+            SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE);
+            return (-1);
+        }
+
+        if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
+            if (SSL3_BUFFER_get_left(rbuf) == 0) {
+                /* no read-ahead left? */
+                BIO *bio;
+                /*
+                 * In the case where we try to read application data, but we
+                 * trigger an SSL handshake, we return -1 with the retry
+                 * option set.  Otherwise renegotiation may cause nasty
+                 * problems in the blocking world
+                 */
+                s->rwstate = SSL_READING;
+                bio = SSL_get_rbio(s);
+                BIO_clear_retry_flags(bio);
+                BIO_set_retry_read(bio);
+                return (-1);
+            }
+        }
+        goto start;
+    }
+
+    switch (SSL3_RECORD_get_type(rr)) {
+    default:
+        /*
+         * TLS 1.0 and 1.1 say you SHOULD ignore unrecognised record types, but
+         * TLS 1.2 says you MUST send an unexpected message alert. We use the
+         * TLS 1.2 behaviour for all protocol versions to prevent issues where
+         * no progress is being made and the peer continually sends unrecognised
+         * record types, using up resources processing them.
+         */
+        al = SSL_AD_UNEXPECTED_MESSAGE;
+        SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD);
+        goto f_err;
+    case SSL3_RT_CHANGE_CIPHER_SPEC:
+    case SSL3_RT_ALERT:
+    case SSL3_RT_HANDSHAKE:
+        /*
+         * we already handled all of these, with the possible exception of
+         * SSL3_RT_HANDSHAKE when ossl_statem_get_in_handshake(s) is true, but
+         * that should not happen when type != rr->type
+         */
+        al = SSL_AD_UNEXPECTED_MESSAGE;
+        SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR);
+        goto f_err;
+    case SSL3_RT_APPLICATION_DATA:
+        /*
+         * At this point, we were expecting handshake data, but have
+         * application data.  If the library was running inside ssl3_read()
+         * (i.e. in_read_app_data is set) and it makes sense to read
+         * application data at this point (session renegotiation not yet
+         * started), we will indulge it.
+         */
+        if (ossl_statem_app_data_allowed(s)) {
+            s->s3->in_read_app_data = 2;
+            return (-1);
+        } else {
+            al = SSL_AD_UNEXPECTED_MESSAGE;
+            SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD);
+            goto f_err;
+        }
+    }
+    /* not reached */
+
+ f_err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    return (-1);
+}
+
+void ssl3_record_sequence_update(unsigned char *seq)
+{
+    int i;
+
+    for (i = 7; i >= 0; i--) {
+        ++seq[i];
+        if (seq[i] != 0)
+            break;
+    }
+}
+
+/*
+ * Returns true if the current rrec was sent in SSLv2 backwards compatible
+ * format and false otherwise.
+ */
+int RECORD_LAYER_is_sslv2_record(RECORD_LAYER *rl)
+{
+    return SSL3_RECORD_is_sslv2_record(&rl->rrec[0]);
+}
+
+/*
+ * Returns the length in bytes of the current rrec
+ */
+unsigned int RECORD_LAYER_get_rrec_length(RECORD_LAYER *rl)
+{
+    return SSL3_RECORD_get_length(&rl->rrec[0]);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/record.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/record.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/record.h	(revision 331)
@@ -0,0 +1,242 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*****************************************************************************
+ *                                                                           *
+ * These structures should be considered PRIVATE to the record layer. No     *
+ * non-record layer code should be using these structures in any way.        *
+ *                                                                           *
+ *****************************************************************************/
+
+typedef struct ssl3_buffer_st {
+    /* at least SSL3_RT_MAX_PACKET_SIZE bytes, see ssl3_setup_buffers() */
+    unsigned char *buf;
+    /* default buffer size (or 0 if no default set) */
+    size_t default_len;
+    /* buffer size */
+    size_t len;
+    /* where to 'copy from' */
+    int offset;
+    /* how many bytes left */
+    int left;
+} SSL3_BUFFER;
+
+#define SEQ_NUM_SIZE                            8
+
+typedef struct ssl3_record_st {
+    /* Record layer version */
+    /* r */
+    int rec_version;
+    /* type of record */
+    /* r */
+    int type;
+    /* How many bytes available */
+    /* rw */
+    unsigned int length;
+    /*
+     * How many bytes were available before padding was removed? This is used
+     * to implement the MAC check in constant time for CBC records.
+     */
+    /* rw */
+    unsigned int orig_len;
+    /* read/write offset into 'buf' */
+    /* r */
+    unsigned int off;
+    /* pointer to the record data */
+    /* rw */
+    unsigned char *data;
+    /* where the decode bytes are */
+    /* rw */
+    unsigned char *input;
+    /* only used with decompression - malloc()ed */
+    /* r */
+    unsigned char *comp;
+    /* Whether the data from this record has already been read or not */
+    /* r */
+    unsigned int read;
+    /* epoch number, needed by DTLS1 */
+    /* r */
+    unsigned long epoch;
+    /* sequence number, needed by DTLS1 */
+    /* r */
+    unsigned char seq_num[SEQ_NUM_SIZE];
+} SSL3_RECORD;
+
+typedef struct dtls1_bitmap_st {
+    /* Track 32 packets on 32-bit systems and 64 - on 64-bit systems */
+    unsigned long map;
+    /* Max record number seen so far, 64-bit value in big-endian encoding */
+    unsigned char max_seq_num[SEQ_NUM_SIZE];
+} DTLS1_BITMAP;
+
+typedef struct record_pqueue_st {
+    unsigned short epoch;
+    struct pqueue_st *q;
+} record_pqueue;
+
+typedef struct dtls1_record_data_st {
+    unsigned char *packet;
+    unsigned int packet_length;
+    SSL3_BUFFER rbuf;
+    SSL3_RECORD rrec;
+#ifndef OPENSSL_NO_SCTP
+    struct bio_dgram_sctp_rcvinfo recordinfo;
+#endif
+} DTLS1_RECORD_DATA;
+
+typedef struct dtls_record_layer_st {
+    /*
+     * The current data and handshake epoch.  This is initially
+     * undefined, and starts at zero once the initial handshake is
+     * completed
+     */
+    unsigned short r_epoch;
+    unsigned short w_epoch;
+    /* records being received in the current epoch */
+    DTLS1_BITMAP bitmap;
+    /* renegotiation starts a new set of sequence numbers */
+    DTLS1_BITMAP next_bitmap;
+    /* Received handshake records (processed and unprocessed) */
+    record_pqueue unprocessed_rcds;
+    record_pqueue processed_rcds;
+    /*
+     * Buffered application records. Only for records between CCS and
+     * Finished to prevent either protocol violation or unnecessary message
+     * loss.
+     */
+    record_pqueue buffered_app_data;
+    /*
+     * storage for Alert/Handshake protocol data received but not yet
+     * processed by ssl3_read_bytes:
+     */
+    unsigned char alert_fragment[DTLS1_AL_HEADER_LENGTH];
+    unsigned int alert_fragment_len;
+    unsigned char handshake_fragment[DTLS1_HM_HEADER_LENGTH];
+    unsigned int handshake_fragment_len;
+    /* save last and current sequence numbers for retransmissions */
+    unsigned char last_write_sequence[8];
+    unsigned char curr_write_sequence[8];
+} DTLS_RECORD_LAYER;
+
+/*****************************************************************************
+ *                                                                           *
+ * This structure should be considered "opaque" to anything outside of the   *
+ * record layer. No non-record layer code should be accessing the members of *
+ * this structure.                                                           *
+ *                                                                           *
+ *****************************************************************************/
+
+typedef struct record_layer_st {
+    /* The parent SSL structure */
+    SSL *s;
+    /*
+     * Read as many input bytes as possible (for
+     * non-blocking reads)
+     */
+    int read_ahead;
+    /* where we are when reading */
+    int rstate;
+    /* How many pipelines can be used to read data */
+    unsigned int numrpipes;
+    /* How many pipelines can be used to write data */
+    unsigned int numwpipes;
+    /* read IO goes into here */
+    SSL3_BUFFER rbuf;
+    /* write IO goes into here */
+    SSL3_BUFFER wbuf[SSL_MAX_PIPELINES];
+    /* each decoded record goes in here */
+    SSL3_RECORD rrec[SSL_MAX_PIPELINES];
+    /* used internally to point at a raw packet */
+    unsigned char *packet;
+    unsigned int packet_length;
+    /* number of bytes sent so far */
+    unsigned int wnum;
+    /*
+     * storage for Alert/Handshake protocol data received but not yet
+     * processed by ssl3_read_bytes:
+     */
+    unsigned char alert_fragment[2];
+    unsigned int alert_fragment_len;
+    unsigned char handshake_fragment[4];
+    unsigned int handshake_fragment_len;
+    /* The number of consecutive empty records we have received */
+    unsigned int empty_record_count;
+    /* partial write - check the numbers match */
+    /* number bytes written */
+    int wpend_tot;
+    int wpend_type;
+    /* number of bytes submitted */
+    int wpend_ret;
+    const unsigned char *wpend_buf;
+    unsigned char read_sequence[SEQ_NUM_SIZE];
+    unsigned char write_sequence[SEQ_NUM_SIZE];
+    /* Set to true if this is the first record in a connection */
+    unsigned int is_first_record;
+    /* Count of the number of consecutive warning alerts received */
+    unsigned int alert_count;
+    DTLS_RECORD_LAYER *d;
+} RECORD_LAYER;
+
+/*****************************************************************************
+ *                                                                           *
+ * The following macros/functions represent the libssl internal API to the   *
+ * record layer. Any libssl code may call these functions/macros             *
+ *                                                                           *
+ *****************************************************************************/
+
+#define MIN_SSL2_RECORD_LEN     9
+
+#define RECORD_LAYER_set_read_ahead(rl, ra)     ((rl)->read_ahead = (ra))
+#define RECORD_LAYER_get_read_ahead(rl)         ((rl)->read_ahead)
+#define RECORD_LAYER_get_packet(rl)             ((rl)->packet)
+#define RECORD_LAYER_get_packet_length(rl)      ((rl)->packet_length)
+#define RECORD_LAYER_add_packet_length(rl, inc) ((rl)->packet_length += (inc))
+#define DTLS_RECORD_LAYER_get_w_epoch(rl)       ((rl)->d->w_epoch)
+#define DTLS_RECORD_LAYER_get_processed_rcds(rl) \
+                                                ((rl)->d->processed_rcds)
+#define DTLS_RECORD_LAYER_get_unprocessed_rcds(rl) \
+                                                ((rl)->d->unprocessed_rcds)
+
+void RECORD_LAYER_init(RECORD_LAYER *rl, SSL *s);
+void RECORD_LAYER_clear(RECORD_LAYER *rl);
+void RECORD_LAYER_release(RECORD_LAYER *rl);
+int RECORD_LAYER_read_pending(const RECORD_LAYER *rl);
+int RECORD_LAYER_write_pending(const RECORD_LAYER *rl);
+int RECORD_LAYER_set_data(RECORD_LAYER *rl, const unsigned char *buf, int len);
+void RECORD_LAYER_reset_read_sequence(RECORD_LAYER *rl);
+void RECORD_LAYER_reset_write_sequence(RECORD_LAYER *rl);
+int RECORD_LAYER_is_sslv2_record(RECORD_LAYER *rl);
+unsigned int RECORD_LAYER_get_rrec_length(RECORD_LAYER *rl);
+__owur int ssl3_pending(const SSL *s);
+__owur int ssl3_write_bytes(SSL *s, int type, const void *buf, int len);
+__owur int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+                         unsigned int *pipelens, unsigned int numpipes,
+                         int create_empty_fragment);
+__owur int ssl3_read_bytes(SSL *s, int type, int *recvd_type,
+                           unsigned char *buf, int len, int peek);
+__owur int ssl3_setup_buffers(SSL *s);
+__owur int ssl3_enc(SSL *s, SSL3_RECORD *inrecs, unsigned int n_recs, int send);
+__owur int n_ssl3_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int send);
+__owur int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
+                              unsigned int len);
+__owur int tls1_enc(SSL *s, SSL3_RECORD *recs, unsigned int n_recs, int send);
+__owur int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int send);
+int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl);
+void DTLS_RECORD_LAYER_free(RECORD_LAYER *rl);
+void DTLS_RECORD_LAYER_clear(RECORD_LAYER *rl);
+void DTLS_RECORD_LAYER_set_saved_w_epoch(RECORD_LAYER *rl, unsigned short e);
+void DTLS_RECORD_LAYER_clear(RECORD_LAYER *rl);
+void DTLS_RECORD_LAYER_resync_write(RECORD_LAYER *rl);
+void DTLS_RECORD_LAYER_set_write_sequence(RECORD_LAYER *rl, unsigned char *seq);
+__owur int dtls1_read_bytes(SSL *s, int type, int *recvd_type,
+                            unsigned char *buf, int len, int peek);
+__owur int dtls1_write_bytes(SSL *s, int type, const void *buf, int len);
+__owur int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
+                          unsigned int len, int create_empty_fragement);
+void dtls1_reset_seq_numbers(SSL *s, int rw);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/record_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/record_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/record_locl.h	(revision 331)
@@ -0,0 +1,116 @@
+/*
+ * Copyright 1995-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
+ */
+
+/*****************************************************************************
+ *                                                                           *
+ * The following macros/functions are PRIVATE to the record layer. They      *
+ * should NOT be used outside of the record layer.                           *
+ *                                                                           *
+ *****************************************************************************/
+
+#define MAX_WARN_ALERT_COUNT    5
+
+/* Functions/macros provided by the RECORD_LAYER component */
+
+#define RECORD_LAYER_get_rbuf(rl)               (&(rl)->rbuf)
+#define RECORD_LAYER_get_wbuf(rl)               ((rl)->wbuf)
+#define RECORD_LAYER_get_rrec(rl)               ((rl)->rrec)
+#define RECORD_LAYER_set_packet(rl, p)          ((rl)->packet = (p))
+#define RECORD_LAYER_reset_packet_length(rl)    ((rl)->packet_length = 0)
+#define RECORD_LAYER_get_rstate(rl)             ((rl)->rstate)
+#define RECORD_LAYER_set_rstate(rl, st)         ((rl)->rstate = (st))
+#define RECORD_LAYER_get_read_sequence(rl)      ((rl)->read_sequence)
+#define RECORD_LAYER_get_write_sequence(rl)     ((rl)->write_sequence)
+#define RECORD_LAYER_get_numrpipes(rl)          ((rl)->numrpipes)
+#define RECORD_LAYER_set_numrpipes(rl, n)       ((rl)->numrpipes = (n))
+#define RECORD_LAYER_inc_empty_record_count(rl) ((rl)->empty_record_count++)
+#define RECORD_LAYER_reset_empty_record_count(rl) \
+                                                ((rl)->empty_record_count = 0)
+#define RECORD_LAYER_get_empty_record_count(rl) ((rl)->empty_record_count)
+#define RECORD_LAYER_is_first_record(rl)        ((rl)->is_first_record)
+#define RECORD_LAYER_set_first_record(rl)       ((rl)->is_first_record = 1)
+#define RECORD_LAYER_clear_first_record(rl)     ((rl)->is_first_record = 0)
+#define DTLS_RECORD_LAYER_get_r_epoch(rl)       ((rl)->d->r_epoch)
+
+__owur int ssl3_read_n(SSL *s, int n, int max, int extend, int clearold);
+
+void RECORD_LAYER_set_write_sequence(RECORD_LAYER *rl, const unsigned char *ws);
+DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr,
+                               unsigned int *is_next_epoch);
+int dtls1_process_buffered_records(SSL *s);
+int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue);
+int dtls1_buffer_record(SSL *s, record_pqueue *q, unsigned char *priority);
+void ssl3_record_sequence_update(unsigned char *seq);
+
+/* Functions provided by the DTLS1_BITMAP component */
+
+int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap);
+void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap);
+
+/* Macros/functions provided by the SSL3_BUFFER component */
+
+#define SSL3_BUFFER_get_buf(b)              ((b)->buf)
+#define SSL3_BUFFER_set_buf(b, n)           ((b)->buf = (n))
+#define SSL3_BUFFER_get_len(b)              ((b)->len)
+#define SSL3_BUFFER_set_len(b, l)           ((b)->len = (l))
+#define SSL3_BUFFER_get_left(b)             ((b)->left)
+#define SSL3_BUFFER_set_left(b, l)          ((b)->left = (l))
+#define SSL3_BUFFER_add_left(b, l)          ((b)->left += (l))
+#define SSL3_BUFFER_get_offset(b)           ((b)->offset)
+#define SSL3_BUFFER_set_offset(b, o)        ((b)->offset = (o))
+#define SSL3_BUFFER_add_offset(b, o)        ((b)->offset += (o))
+#define SSL3_BUFFER_is_initialised(b)       ((b)->buf != NULL)
+#define SSL3_BUFFER_set_default_len(b, l)   ((b)->default_len = (l))
+
+void SSL3_BUFFER_clear(SSL3_BUFFER *b);
+void SSL3_BUFFER_set_data(SSL3_BUFFER *b, const unsigned char *d, int n);
+void SSL3_BUFFER_release(SSL3_BUFFER *b);
+__owur int ssl3_setup_read_buffer(SSL *s);
+__owur int ssl3_setup_write_buffer(SSL *s, unsigned int numwpipes, size_t len);
+int ssl3_release_read_buffer(SSL *s);
+int ssl3_release_write_buffer(SSL *s);
+
+/* Macros/functions provided by the SSL3_RECORD component */
+
+#define SSL3_RECORD_get_type(r)                 ((r)->type)
+#define SSL3_RECORD_set_type(r, t)              ((r)->type = (t))
+#define SSL3_RECORD_get_length(r)               ((r)->length)
+#define SSL3_RECORD_set_length(r, l)            ((r)->length = (l))
+#define SSL3_RECORD_add_length(r, l)            ((r)->length += (l))
+#define SSL3_RECORD_sub_length(r, l)            ((r)->length -= (l))
+#define SSL3_RECORD_get_data(r)                 ((r)->data)
+#define SSL3_RECORD_set_data(r, d)              ((r)->data = (d))
+#define SSL3_RECORD_get_input(r)                ((r)->input)
+#define SSL3_RECORD_set_input(r, i)             ((r)->input = (i))
+#define SSL3_RECORD_reset_input(r)              ((r)->input = (r)->data)
+#define SSL3_RECORD_get_seq_num(r)              ((r)->seq_num)
+#define SSL3_RECORD_get_off(r)                  ((r)->off)
+#define SSL3_RECORD_set_off(r, o)               ((r)->off = (o))
+#define SSL3_RECORD_add_off(r, o)               ((r)->off += (o))
+#define SSL3_RECORD_get_epoch(r)                ((r)->epoch)
+#define SSL3_RECORD_is_sslv2_record(r) \
+            ((r)->rec_version == SSL2_VERSION)
+#define SSL3_RECORD_is_read(r)                  ((r)->read)
+#define SSL3_RECORD_set_read(r)                 ((r)->read = 1)
+
+void SSL3_RECORD_clear(SSL3_RECORD *r, unsigned int num_recs);
+void SSL3_RECORD_release(SSL3_RECORD *r, unsigned int num_recs);
+void SSL3_RECORD_set_seq_num(SSL3_RECORD *r, const unsigned char *seq_num);
+int ssl3_get_record(SSL *s);
+__owur int ssl3_do_compress(SSL *ssl, SSL3_RECORD *wr);
+__owur int ssl3_do_uncompress(SSL *ssl, SSL3_RECORD *rr);
+void ssl3_cbc_copy_mac(unsigned char *out,
+                       const SSL3_RECORD *rec, unsigned md_size);
+__owur int ssl3_cbc_remove_padding(SSL3_RECORD *rec,
+                                   unsigned block_size, unsigned mac_size);
+__owur int tls1_cbc_remove_padding(const SSL *s,
+                                   SSL3_RECORD *rec,
+                                   unsigned block_size, unsigned mac_size);
+int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap);
+__owur int dtls1_get_record(SSL *s);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/ssl3_buffer.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/ssl3_buffer.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/ssl3_buffer.c	(revision 331)
@@ -0,0 +1,163 @@
+/*
+ * Copyright 1995-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 "../ssl_locl.h"
+#include "record_locl.h"
+
+void SSL3_BUFFER_set_data(SSL3_BUFFER *b, const unsigned char *d, int n)
+{
+    if (d != NULL)
+        memcpy(b->buf, d, n);
+    b->left = n;
+    b->offset = 0;
+}
+
+/*
+ * Clear the contents of an SSL3_BUFFER but retain any memory allocated. Also
+ * retains the default_len setting
+ */
+void SSL3_BUFFER_clear(SSL3_BUFFER *b)
+{
+    b->offset = 0;
+    b->left = 0;
+}
+
+void SSL3_BUFFER_release(SSL3_BUFFER *b)
+{
+    OPENSSL_free(b->buf);
+    b->buf = NULL;
+}
+
+int ssl3_setup_read_buffer(SSL *s)
+{
+    unsigned char *p;
+    size_t len, align = 0, headerlen;
+    SSL3_BUFFER *b;
+
+    b = RECORD_LAYER_get_rbuf(&s->rlayer);
+
+    if (SSL_IS_DTLS(s))
+        headerlen = DTLS1_RT_HEADER_LENGTH;
+    else
+        headerlen = SSL3_RT_HEADER_LENGTH;
+
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+    align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
+#endif
+
+    if (b->buf == NULL) {
+        len = SSL3_RT_MAX_PLAIN_LENGTH
+            + SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
+#ifndef OPENSSL_NO_COMP
+        if (ssl_allow_compression(s))
+            len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
+#endif
+        if (b->default_len > len)
+            len = b->default_len;
+        if ((p = OPENSSL_malloc(len)) == NULL)
+            goto err;
+        b->buf = p;
+        b->len = len;
+    }
+
+    RECORD_LAYER_set_packet(&s->rlayer, &(b->buf[0]));
+    return 1;
+
+ err:
+    SSLerr(SSL_F_SSL3_SETUP_READ_BUFFER, ERR_R_MALLOC_FAILURE);
+    return 0;
+}
+
+int ssl3_setup_write_buffer(SSL *s, unsigned int numwpipes, size_t len)
+{
+    unsigned char *p;
+    size_t align = 0, headerlen;
+    SSL3_BUFFER *wb;
+    unsigned int currpipe;
+
+    s->rlayer.numwpipes = numwpipes;
+
+    if (len == 0) {
+        if (SSL_IS_DTLS(s))
+            headerlen = DTLS1_RT_HEADER_LENGTH + 1;
+        else
+            headerlen = SSL3_RT_HEADER_LENGTH;
+
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+        align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
+#endif
+
+        len = s->max_send_fragment
+            + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
+#ifndef OPENSSL_NO_COMP
+        if (ssl_allow_compression(s))
+            len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
+#endif
+        if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
+            len += headerlen + align + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
+    }
+
+    wb = RECORD_LAYER_get_wbuf(&s->rlayer);
+    for (currpipe = 0; currpipe < numwpipes; currpipe++) {
+        SSL3_BUFFER *thiswb = &wb[currpipe];
+
+        if (thiswb->buf == NULL) {
+            p = OPENSSL_malloc(len);
+            if (p == NULL) {
+                s->rlayer.numwpipes = currpipe;
+                goto err;
+            }
+            memset(thiswb, 0, sizeof(SSL3_BUFFER));
+            thiswb->buf = p;
+            thiswb->len = len;
+        }
+    }
+
+    return 1;
+
+ err:
+    SSLerr(SSL_F_SSL3_SETUP_WRITE_BUFFER, ERR_R_MALLOC_FAILURE);
+    return 0;
+}
+
+int ssl3_setup_buffers(SSL *s)
+{
+    if (!ssl3_setup_read_buffer(s))
+        return 0;
+    if (!ssl3_setup_write_buffer(s, 1, 0))
+        return 0;
+    return 1;
+}
+
+int ssl3_release_write_buffer(SSL *s)
+{
+    SSL3_BUFFER *wb;
+    unsigned int pipes;
+
+    pipes = s->rlayer.numwpipes;
+    while (pipes > 0) {
+        wb = &RECORD_LAYER_get_wbuf(&s->rlayer)[pipes - 1];
+
+        OPENSSL_free(wb->buf);
+        wb->buf = NULL;
+        pipes--;
+    }
+    s->rlayer.numwpipes = 0;
+    return 1;
+}
+
+int ssl3_release_read_buffer(SSL *s)
+{
+    SSL3_BUFFER *b;
+
+    b = RECORD_LAYER_get_rbuf(&s->rlayer);
+    OPENSSL_free(b->buf);
+    b->buf = NULL;
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/ssl3_record.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/ssl3_record.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/record/ssl3_record.c	(revision 331)
@@ -0,0 +1,1634 @@
+/*
+ * Copyright 1995-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 <assert.h>
+#include "../ssl_locl.h"
+#include "internal/constant_time_locl.h"
+#include <openssl/rand.h>
+#include "record_locl.h"
+
+static const unsigned char ssl3_pad_1[48] = {
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+    0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
+};
+
+static const unsigned char ssl3_pad_2[48] = {
+    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+    0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
+};
+
+/*
+ * Clear the contents of an SSL3_RECORD but retain any memory allocated
+ */
+void SSL3_RECORD_clear(SSL3_RECORD *r, unsigned int num_recs)
+{
+    unsigned char *comp;
+    unsigned int i;
+
+    for (i = 0; i < num_recs; i++) {
+        comp = r[i].comp;
+
+        memset(&r[i], 0, sizeof(*r));
+        r[i].comp = comp;
+    }
+}
+
+void SSL3_RECORD_release(SSL3_RECORD *r, unsigned int num_recs)
+{
+    unsigned int i;
+
+    for (i = 0; i < num_recs; i++) {
+        OPENSSL_free(r[i].comp);
+        r[i].comp = NULL;
+    }
+}
+
+void SSL3_RECORD_set_seq_num(SSL3_RECORD *r, const unsigned char *seq_num)
+{
+    memcpy(r->seq_num, seq_num, SEQ_NUM_SIZE);
+}
+
+/*
+ * Peeks ahead into "read_ahead" data to see if we have a whole record waiting
+ * for us in the buffer.
+ */
+static int ssl3_record_app_data_waiting(SSL *s)
+{
+    SSL3_BUFFER *rbuf;
+    int left, len;
+    unsigned char *p;
+
+    rbuf = RECORD_LAYER_get_rbuf(&s->rlayer);
+
+    p = SSL3_BUFFER_get_buf(rbuf);
+    if (p == NULL)
+        return 0;
+
+    left = SSL3_BUFFER_get_left(rbuf);
+
+    if (left < SSL3_RT_HEADER_LENGTH)
+        return 0;
+
+    p += SSL3_BUFFER_get_offset(rbuf);
+
+    /*
+     * We only check the type and record length, we will sanity check version
+     * etc later
+     */
+    if (*p != SSL3_RT_APPLICATION_DATA)
+        return 0;
+
+    p += 3;
+    n2s(p, len);
+
+    if (left < SSL3_RT_HEADER_LENGTH + len)
+        return 0;
+
+    return 1;
+}
+
+/*
+ * MAX_EMPTY_RECORDS defines the number of consecutive, empty records that
+ * will be processed per call to ssl3_get_record. Without this limit an
+ * attacker could send empty records at a faster rate than we can process and
+ * cause ssl3_get_record to loop forever.
+ */
+#define MAX_EMPTY_RECORDS 32
+
+#define SSL2_RT_HEADER_LENGTH   2
+/*-
+ * Call this to get new input records.
+ * It will return <= 0 if more data is needed, normally due to an error
+ * or non-blocking IO.
+ * When it finishes, |numrpipes| records have been decoded. For each record 'i':
+ * rr[i].type    - is the type of record
+ * rr[i].data,   - data
+ * rr[i].length, - number of bytes
+ * Multiple records will only be returned if the record types are all
+ * SSL3_RT_APPLICATION_DATA. The number of records returned will always be <=
+ * |max_pipelines|
+ */
+/* used only by ssl3_read_bytes */
+int ssl3_get_record(SSL *s)
+{
+    int ssl_major, ssl_minor, al;
+    int enc_err, n, i, ret = -1;
+    SSL3_RECORD *rr;
+    SSL3_BUFFER *rbuf;
+    SSL_SESSION *sess;
+    unsigned char *p;
+    unsigned char md[EVP_MAX_MD_SIZE];
+    short version;
+    unsigned mac_size;
+    int imac_size;
+    unsigned int num_recs = 0;
+    unsigned int max_recs;
+    unsigned int j;
+
+    rr = RECORD_LAYER_get_rrec(&s->rlayer);
+    rbuf = RECORD_LAYER_get_rbuf(&s->rlayer);
+    max_recs = s->max_pipelines;
+    if (max_recs == 0)
+        max_recs = 1;
+    sess = s->session;
+
+    do {
+        /* check if we have the header */
+        if ((RECORD_LAYER_get_rstate(&s->rlayer) != SSL_ST_READ_BODY) ||
+            (RECORD_LAYER_get_packet_length(&s->rlayer)
+             < SSL3_RT_HEADER_LENGTH)) {
+            n = ssl3_read_n(s, SSL3_RT_HEADER_LENGTH,
+                            SSL3_BUFFER_get_len(rbuf), 0,
+                            num_recs == 0 ? 1 : 0);
+            if (n <= 0)
+                return (n);     /* error or non-blocking */
+            RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_BODY);
+
+            p = RECORD_LAYER_get_packet(&s->rlayer);
+
+            /*
+             * The first record received by the server may be a V2ClientHello.
+             */
+            if (s->server && RECORD_LAYER_is_first_record(&s->rlayer)
+                && (p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO)) {
+                /*
+                 *  SSLv2 style record
+                 *
+                 * |num_recs| here will actually always be 0 because
+                 * |num_recs > 0| only ever occurs when we are processing
+                 * multiple app data records - which we know isn't the case here
+                 * because it is an SSLv2ClientHello. We keep it using
+                 * |num_recs| for the sake of consistency
+                 */
+                rr[num_recs].type = SSL3_RT_HANDSHAKE;
+                rr[num_recs].rec_version = SSL2_VERSION;
+
+                rr[num_recs].length = ((p[0] & 0x7f) << 8) | p[1];
+
+                if (rr[num_recs].length > SSL3_BUFFER_get_len(rbuf)
+                    - SSL2_RT_HEADER_LENGTH) {
+                    al = SSL_AD_RECORD_OVERFLOW;
+                    SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG);
+                    goto f_err;
+                }
+
+                if (rr[num_recs].length < MIN_SSL2_RECORD_LEN) {
+                    al = SSL_AD_HANDSHAKE_FAILURE;
+                    SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_LENGTH_TOO_SHORT);
+                    goto f_err;
+                }
+            } else {
+                /* SSLv3+ style record */
+                if (s->msg_callback)
+                    s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, s,
+                                    s->msg_callback_arg);
+
+                /* Pull apart the header into the SSL3_RECORD */
+                rr[num_recs].type = *(p++);
+                ssl_major = *(p++);
+                ssl_minor = *(p++);
+                version = (ssl_major << 8) | ssl_minor;
+                rr[num_recs].rec_version = version;
+                n2s(p, rr[num_recs].length);
+
+                /* Lets check version */
+                if (!s->first_packet && version != s->version) {
+                    SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER);
+                    if ((s->version & 0xFF00) == (version & 0xFF00)
+                        && !s->enc_write_ctx && !s->write_hash) {
+                        if (rr->type == SSL3_RT_ALERT) {
+                            /*
+                             * The record is using an incorrect version number,
+                             * but what we've got appears to be an alert. We
+                             * haven't read the body yet to check whether its a
+                             * fatal or not - but chances are it is. We probably
+                             * shouldn't send a fatal alert back. We'll just
+                             * end.
+                             */
+                            goto err;
+                        }
+                        /*
+                         * Send back error using their minor version number :-)
+                         */
+                        s->version = (unsigned short)version;
+                    }
+                    al = SSL_AD_PROTOCOL_VERSION;
+                    goto f_err;
+                }
+
+                if ((version >> 8) != SSL3_VERSION_MAJOR) {
+                    if (RECORD_LAYER_is_first_record(&s->rlayer)) {
+                        /* Go back to start of packet, look at the five bytes
+                         * that we have. */
+                        p = RECORD_LAYER_get_packet(&s->rlayer);
+                        if (strncmp((char *)p, "GET ", 4) == 0 ||
+                            strncmp((char *)p, "POST ", 5) == 0 ||
+                            strncmp((char *)p, "HEAD ", 5) == 0 ||
+                            strncmp((char *)p, "PUT ", 4) == 0) {
+                            SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_HTTP_REQUEST);
+                            goto err;
+                        } else if (strncmp((char *)p, "CONNE", 5) == 0) {
+                            SSLerr(SSL_F_SSL3_GET_RECORD,
+                                   SSL_R_HTTPS_PROXY_REQUEST);
+                            goto err;
+                        }
+
+                        /* Doesn't look like TLS - don't send an alert */
+                        SSLerr(SSL_F_SSL3_GET_RECORD,
+                               SSL_R_WRONG_VERSION_NUMBER);
+                        goto err;
+                    } else {
+                        SSLerr(SSL_F_SSL3_GET_RECORD,
+                               SSL_R_WRONG_VERSION_NUMBER);
+                        al = SSL_AD_PROTOCOL_VERSION;
+                        goto f_err;
+                    }
+                }
+
+                if (rr[num_recs].length >
+                    SSL3_BUFFER_get_len(rbuf) - SSL3_RT_HEADER_LENGTH) {
+                    al = SSL_AD_RECORD_OVERFLOW;
+                    SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG);
+                    goto f_err;
+                }
+            }
+
+            /* now s->rlayer.rstate == SSL_ST_READ_BODY */
+        }
+
+        /*
+         * s->rlayer.rstate == SSL_ST_READ_BODY, get and decode the data.
+         * Calculate how much more data we need to read for the rest of the
+         * record
+         */
+        if (rr[num_recs].rec_version == SSL2_VERSION) {
+            i = rr[num_recs].length + SSL2_RT_HEADER_LENGTH
+                - SSL3_RT_HEADER_LENGTH;
+        } else {
+            i = rr[num_recs].length;
+        }
+        if (i > 0) {
+            /* now s->packet_length == SSL3_RT_HEADER_LENGTH */
+
+            n = ssl3_read_n(s, i, i, 1, 0);
+            if (n <= 0)
+                return (n);     /* error or non-blocking io */
+        }
+
+        /* set state for later operations */
+        RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_HEADER);
+
+        /*
+         * At this point, s->packet_length == SSL3_RT_HEADER_LENGTH + rr->length,
+         * or s->packet_length == SSL2_RT_HEADER_LENGTH + rr->length
+         * and we have that many bytes in s->packet
+         */
+        if (rr[num_recs].rec_version == SSL2_VERSION) {
+            rr[num_recs].input =
+                &(RECORD_LAYER_get_packet(&s->rlayer)[SSL2_RT_HEADER_LENGTH]);
+        } else {
+            rr[num_recs].input =
+                &(RECORD_LAYER_get_packet(&s->rlayer)[SSL3_RT_HEADER_LENGTH]);
+        }
+
+        /*
+         * ok, we can now read from 's->packet' data into 'rr' rr->input points
+         * at rr->length bytes, which need to be copied into rr->data by either
+         * the decryption or by the decompression When the data is 'copied' into
+         * the rr->data buffer, rr->input will be pointed at the new buffer
+         */
+
+        /*
+         * We now have - encrypted [ MAC [ compressed [ plain ] ] ] rr->length
+         * bytes of encrypted compressed stuff.
+         */
+
+        /* check is not needed I believe */
+        if (rr[num_recs].length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
+            al = SSL_AD_RECORD_OVERFLOW;
+            SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
+            goto f_err;
+        }
+
+        /* decrypt in place in 'rr->input' */
+        rr[num_recs].data = rr[num_recs].input;
+        rr[num_recs].orig_len = rr[num_recs].length;
+
+        /* Mark this record as not read by upper layers yet */
+        rr[num_recs].read = 0;
+
+        num_recs++;
+
+        /* we have pulled in a full packet so zero things */
+        RECORD_LAYER_reset_packet_length(&s->rlayer);
+        RECORD_LAYER_clear_first_record(&s->rlayer);
+    } while (num_recs < max_recs
+             && rr[num_recs - 1].type == SSL3_RT_APPLICATION_DATA
+             && SSL_USE_EXPLICIT_IV(s)
+             && s->enc_read_ctx != NULL
+             && (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_read_ctx))
+                 & EVP_CIPH_FLAG_PIPELINE)
+             && ssl3_record_app_data_waiting(s));
+
+    /*
+     * If in encrypt-then-mac mode calculate mac from encrypted record. All
+     * the details below are public so no timing details can leak.
+     */
+    if (SSL_READ_ETM(s) && s->read_hash) {
+        unsigned char *mac;
+
+        imac_size = EVP_MD_CTX_size(s->read_hash);
+        assert(imac_size >= 0 && imac_size <= EVP_MAX_MD_SIZE);
+        if (imac_size < 0 || imac_size > EVP_MAX_MD_SIZE) {
+                al = SSL_AD_INTERNAL_ERROR;
+                SSLerr(SSL_F_SSL3_GET_RECORD, ERR_LIB_EVP);
+                goto f_err;
+        }
+        mac_size = (unsigned)imac_size;
+
+        for (j = 0; j < num_recs; j++) {
+            if (rr[j].length < mac_size) {
+                al = SSL_AD_DECODE_ERROR;
+                SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_LENGTH_TOO_SHORT);
+                goto f_err;
+            }
+            rr[j].length -= mac_size;
+            mac = rr[j].data + rr[j].length;
+            i = s->method->ssl3_enc->mac(s, &rr[j], md, 0 /* not send */ );
+            if (i < 0 || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) {
+                al = SSL_AD_BAD_RECORD_MAC;
+                SSLerr(SSL_F_SSL3_GET_RECORD,
+                       SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
+                goto f_err;
+            }
+        }
+    }
+
+    enc_err = s->method->ssl3_enc->enc(s, rr, num_recs, 0);
+    /*-
+     * enc_err is:
+     *    0: (in non-constant time) if the record is publically invalid.
+     *    1: if the padding is valid
+     *    -1: if the padding is invalid
+     */
+    if (enc_err == 0) {
+        al = SSL_AD_DECRYPTION_FAILED;
+        SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
+        goto f_err;
+    }
+#ifdef SSL_DEBUG
+    printf("dec %d\n", rr->length);
+    {
+        unsigned int z;
+        for (z = 0; z < rr->length; z++)
+            printf("%02X%c", rr->data[z], ((z + 1) % 16) ? ' ' : '\n');
+    }
+    printf("\n");
+#endif
+
+    /* r->length is now the compressed data plus mac */
+    if ((sess != NULL) &&
+        (s->enc_read_ctx != NULL) &&
+        (!SSL_READ_ETM(s) && EVP_MD_CTX_md(s->read_hash) != NULL)) {
+        /* s->read_hash != NULL => mac_size != -1 */
+        unsigned char *mac = NULL;
+        unsigned char mac_tmp[EVP_MAX_MD_SIZE];
+
+        mac_size = EVP_MD_CTX_size(s->read_hash);
+        OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
+
+        for (j = 0; j < num_recs; j++) {
+            /*
+             * orig_len is the length of the record before any padding was
+             * removed. This is public information, as is the MAC in use,
+             * therefore we can safely process the record in a different amount
+             * of time if it's too short to possibly contain a MAC.
+             */
+            if (rr[j].orig_len < mac_size ||
+                /* CBC records must have a padding length byte too. */
+                (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+                 rr[j].orig_len < mac_size + 1)) {
+                al = SSL_AD_DECODE_ERROR;
+                SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_LENGTH_TOO_SHORT);
+                goto f_err;
+            }
+
+            if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) {
+                /*
+                 * We update the length so that the TLS header bytes can be
+                 * constructed correctly but we need to extract the MAC in
+                 * constant time from within the record, without leaking the
+                 * contents of the padding bytes.
+                 */
+                mac = mac_tmp;
+                ssl3_cbc_copy_mac(mac_tmp, &rr[j], mac_size);
+                rr[j].length -= mac_size;
+            } else {
+                /*
+                 * In this case there's no padding, so |rec->orig_len| equals
+                 * |rec->length| and we checked that there's enough bytes for
+                 * |mac_size| above.
+                 */
+                rr[j].length -= mac_size;
+                mac = &rr[j].data[rr[j].length];
+            }
+
+            i = s->method->ssl3_enc->mac(s, &rr[j], md, 0 /* not send */ );
+            if (i < 0 || mac == NULL
+                || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0)
+                enc_err = -1;
+            if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size)
+                enc_err = -1;
+        }
+    }
+
+    if (enc_err < 0) {
+        /*
+         * A separate 'decryption_failed' alert was introduced with TLS 1.0,
+         * SSL 3.0 only has 'bad_record_mac'.  But unless a decryption
+         * failure is directly visible from the ciphertext anyway, we should
+         * not reveal which kind of error occurred -- this might become
+         * visible to an attacker (e.g. via a logfile)
+         */
+        al = SSL_AD_BAD_RECORD_MAC;
+        SSLerr(SSL_F_SSL3_GET_RECORD,
+               SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
+        goto f_err;
+    }
+
+    for (j = 0; j < num_recs; j++) {
+        /* rr[j].length is now just compressed */
+        if (s->expand != NULL) {
+            if (rr[j].length > SSL3_RT_MAX_COMPRESSED_LENGTH) {
+                al = SSL_AD_RECORD_OVERFLOW;
+                SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_COMPRESSED_LENGTH_TOO_LONG);
+                goto f_err;
+            }
+            if (!ssl3_do_uncompress(s, &rr[j])) {
+                al = SSL_AD_DECOMPRESSION_FAILURE;
+                SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_BAD_DECOMPRESSION);
+                goto f_err;
+            }
+        }
+
+        if (rr[j].length > SSL3_RT_MAX_PLAIN_LENGTH) {
+            al = SSL_AD_RECORD_OVERFLOW;
+            SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_DATA_LENGTH_TOO_LONG);
+            goto f_err;
+        }
+
+        rr[j].off = 0;
+        /*-
+         * So at this point the following is true
+         * rr[j].type   is the type of record
+         * rr[j].length == number of bytes in record
+         * rr[j].off    == offset to first valid byte
+         * rr[j].data   == where to take bytes from, increment after use :-).
+         */
+
+        /* just read a 0 length packet */
+        if (rr[j].length == 0) {
+            RECORD_LAYER_inc_empty_record_count(&s->rlayer);
+            if (RECORD_LAYER_get_empty_record_count(&s->rlayer)
+                > MAX_EMPTY_RECORDS) {
+                al = SSL_AD_UNEXPECTED_MESSAGE;
+                SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_RECORD_TOO_SMALL);
+                goto f_err;
+            }
+        } else {
+            RECORD_LAYER_reset_empty_record_count(&s->rlayer);
+        }
+    }
+
+    RECORD_LAYER_set_numrpipes(&s->rlayer, num_recs);
+    return 1;
+
+ f_err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ err:
+    return ret;
+}
+
+int ssl3_do_uncompress(SSL *ssl, SSL3_RECORD *rr)
+{
+#ifndef OPENSSL_NO_COMP
+    int i;
+
+    if (rr->comp == NULL) {
+        rr->comp = (unsigned char *)
+            OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH);
+    }
+    if (rr->comp == NULL)
+        return 0;
+
+    i = COMP_expand_block(ssl->expand, rr->comp,
+                          SSL3_RT_MAX_PLAIN_LENGTH, rr->data, (int)rr->length);
+    if (i < 0)
+        return 0;
+    else
+        rr->length = i;
+    rr->data = rr->comp;
+#endif
+    return 1;
+}
+
+int ssl3_do_compress(SSL *ssl, SSL3_RECORD *wr)
+{
+#ifndef OPENSSL_NO_COMP
+    int i;
+
+    i = COMP_compress_block(ssl->compress, wr->data,
+                            SSL3_RT_MAX_COMPRESSED_LENGTH,
+                            wr->input, (int)wr->length);
+    if (i < 0)
+        return (0);
+    else
+        wr->length = i;
+
+    wr->input = wr->data;
+#endif
+    return (1);
+}
+
+/*-
+ * ssl3_enc encrypts/decrypts |n_recs| records in |inrecs|
+ *
+ * Returns:
+ *   0: (in non-constant time) if the record is publically invalid (i.e. too
+ *       short etc).
+ *   1: if the record's padding is valid / the encryption was successful.
+ *   -1: if the record's padding is invalid or, if sending, an internal error
+ *       occurred.
+ */
+int ssl3_enc(SSL *s, SSL3_RECORD *inrecs, unsigned int n_recs, int send)
+{
+    SSL3_RECORD *rec;
+    EVP_CIPHER_CTX *ds;
+    unsigned long l;
+    int bs, i, mac_size = 0;
+    const EVP_CIPHER *enc;
+
+    rec = inrecs;
+    /*
+     * We shouldn't ever be called with more than one record in the SSLv3 case
+     */
+    if (n_recs != 1)
+        return 0;
+    if (send) {
+        ds = s->enc_write_ctx;
+        if (s->enc_write_ctx == NULL)
+            enc = NULL;
+        else
+            enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
+    } else {
+        ds = s->enc_read_ctx;
+        if (s->enc_read_ctx == NULL)
+            enc = NULL;
+        else
+            enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
+    }
+
+    if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) {
+        memmove(rec->data, rec->input, rec->length);
+        rec->input = rec->data;
+    } else {
+        l = rec->length;
+        bs = EVP_CIPHER_CTX_block_size(ds);
+
+        /* COMPRESS */
+
+        if ((bs != 1) && send) {
+            i = bs - ((int)l % bs);
+
+            /* we need to add 'i-1' padding bytes */
+            l += i;
+            /*
+             * the last of these zero bytes will be overwritten with the
+             * padding length.
+             */
+            memset(&rec->input[rec->length], 0, i);
+            rec->length += i;
+            rec->input[l - 1] = (i - 1);
+        }
+
+        if (!send) {
+            if (l == 0 || l % bs != 0)
+                return 0;
+            /* otherwise, rec->length >= bs */
+        }
+
+        if (EVP_Cipher(ds, rec->data, rec->input, l) < 1)
+            return -1;
+
+        if (EVP_MD_CTX_md(s->read_hash) != NULL)
+            mac_size = EVP_MD_CTX_size(s->read_hash);
+        if ((bs != 1) && !send)
+            return ssl3_cbc_remove_padding(rec, bs, mac_size);
+    }
+    return (1);
+}
+
+/*-
+ * tls1_enc encrypts/decrypts |n_recs| in |recs|.
+ *
+ * Returns:
+ *   0: (in non-constant time) if the record is publically invalid (i.e. too
+ *       short etc).
+ *   1: if the record's padding is valid / the encryption was successful.
+ *   -1: if the record's padding/AEAD-authenticator is invalid or, if sending,
+ *       an internal error occurred.
+ */
+int tls1_enc(SSL *s, SSL3_RECORD *recs, unsigned int n_recs, int send)
+{
+    EVP_CIPHER_CTX *ds;
+    size_t reclen[SSL_MAX_PIPELINES];
+    unsigned char buf[SSL_MAX_PIPELINES][EVP_AEAD_TLS1_AAD_LEN];
+    int bs, i, j, k, pad = 0, ret, mac_size = 0;
+    const EVP_CIPHER *enc;
+    unsigned int ctr;
+
+    if (send) {
+        if (EVP_MD_CTX_md(s->write_hash)) {
+            int n = EVP_MD_CTX_size(s->write_hash);
+            OPENSSL_assert(n >= 0);
+        }
+        ds = s->enc_write_ctx;
+        if (s->enc_write_ctx == NULL)
+            enc = NULL;
+        else {
+            int ivlen;
+            enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
+            /* For TLSv1.1 and later explicit IV */
+            if (SSL_USE_EXPLICIT_IV(s)
+                && EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE)
+                ivlen = EVP_CIPHER_iv_length(enc);
+            else
+                ivlen = 0;
+            if (ivlen > 1) {
+                for (ctr = 0; ctr < n_recs; ctr++) {
+                    if (recs[ctr].data != recs[ctr].input) {
+                        /*
+                         * we can't write into the input stream: Can this ever
+                         * happen?? (steve)
+                         */
+                        SSLerr(SSL_F_TLS1_ENC, ERR_R_INTERNAL_ERROR);
+                        return -1;
+                    } else if (RAND_bytes(recs[ctr].input, ivlen) <= 0) {
+                        SSLerr(SSL_F_TLS1_ENC, ERR_R_INTERNAL_ERROR);
+                        return -1;
+                    }
+                }
+            }
+        }
+    } else {
+        if (EVP_MD_CTX_md(s->read_hash)) {
+            int n = EVP_MD_CTX_size(s->read_hash);
+            OPENSSL_assert(n >= 0);
+        }
+        ds = s->enc_read_ctx;
+        if (s->enc_read_ctx == NULL)
+            enc = NULL;
+        else
+            enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
+    }
+
+    if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) {
+        for (ctr = 0; ctr < n_recs; ctr++) {
+            memmove(recs[ctr].data, recs[ctr].input, recs[ctr].length);
+            recs[ctr].input = recs[ctr].data;
+        }
+        ret = 1;
+    } else {
+        bs = EVP_CIPHER_block_size(EVP_CIPHER_CTX_cipher(ds));
+
+        if (n_recs > 1) {
+            if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ds))
+                  & EVP_CIPH_FLAG_PIPELINE)) {
+                /*
+                 * We shouldn't have been called with pipeline data if the
+                 * cipher doesn't support pipelining
+                 */
+                SSLerr(SSL_F_TLS1_ENC, SSL_R_PIPELINE_FAILURE);
+                return -1;
+            }
+        }
+        for (ctr = 0; ctr < n_recs; ctr++) {
+            reclen[ctr] = recs[ctr].length;
+
+            if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ds))
+                & EVP_CIPH_FLAG_AEAD_CIPHER) {
+                unsigned char *seq;
+
+                seq = send ? RECORD_LAYER_get_write_sequence(&s->rlayer)
+                    : RECORD_LAYER_get_read_sequence(&s->rlayer);
+
+                if (SSL_IS_DTLS(s)) {
+                    /* DTLS does not support pipelining */
+                    unsigned char dtlsseq[9], *p = dtlsseq;
+
+                    s2n(send ? DTLS_RECORD_LAYER_get_w_epoch(&s->rlayer) :
+                        DTLS_RECORD_LAYER_get_r_epoch(&s->rlayer), p);
+                    memcpy(p, &seq[2], 6);
+                    memcpy(buf[ctr], dtlsseq, 8);
+                } else {
+                    memcpy(buf[ctr], seq, 8);
+                    for (i = 7; i >= 0; i--) { /* increment */
+                        ++seq[i];
+                        if (seq[i] != 0)
+                            break;
+                    }
+                }
+
+                buf[ctr][8] = recs[ctr].type;
+                buf[ctr][9] = (unsigned char)(s->version >> 8);
+                buf[ctr][10] = (unsigned char)(s->version);
+                buf[ctr][11] = recs[ctr].length >> 8;
+                buf[ctr][12] = recs[ctr].length & 0xff;
+                pad = EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_AEAD_TLS1_AAD,
+                                          EVP_AEAD_TLS1_AAD_LEN, buf[ctr]);
+                if (pad <= 0)
+                    return -1;
+
+                if (send) {
+                    reclen[ctr] += pad;
+                    recs[ctr].length += pad;
+                }
+
+            } else if ((bs != 1) && send) {
+                i = bs - ((int)reclen[ctr] % bs);
+
+                /* Add weird padding of upto 256 bytes */
+
+                /* we need to add 'i' padding bytes of value j */
+                j = i - 1;
+                for (k = (int)reclen[ctr]; k < (int)(reclen[ctr] + i); k++)
+                    recs[ctr].input[k] = j;
+                reclen[ctr] += i;
+                recs[ctr].length += i;
+            }
+
+            if (!send) {
+                if (reclen[ctr] == 0 || reclen[ctr] % bs != 0)
+                    return 0;
+            }
+        }
+        if (n_recs > 1) {
+            unsigned char *data[SSL_MAX_PIPELINES];
+
+            /* Set the output buffers */
+            for (ctr = 0; ctr < n_recs; ctr++) {
+                data[ctr] = recs[ctr].data;
+            }
+            if (EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS,
+                                    n_recs, data) <= 0) {
+                SSLerr(SSL_F_TLS1_ENC, SSL_R_PIPELINE_FAILURE);
+            }
+            /* Set the input buffers */
+            for (ctr = 0; ctr < n_recs; ctr++) {
+                data[ctr] = recs[ctr].input;
+            }
+            if (EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_SET_PIPELINE_INPUT_BUFS,
+                                    n_recs, data) <= 0
+                || EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_SET_PIPELINE_INPUT_LENS,
+                                       n_recs, reclen) <= 0) {
+                SSLerr(SSL_F_TLS1_ENC, SSL_R_PIPELINE_FAILURE);
+                return -1;
+            }
+        }
+
+        i = EVP_Cipher(ds, recs[0].data, recs[0].input, reclen[0]);
+        if ((EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ds))
+             & EVP_CIPH_FLAG_CUSTOM_CIPHER)
+            ? (i < 0)
+            : (i == 0))
+            return -1;          /* AEAD can fail to verify MAC */
+        if (send == 0) {
+            if (EVP_CIPHER_mode(enc) == EVP_CIPH_GCM_MODE) {
+                for (ctr = 0; ctr < n_recs; ctr++) {
+                    recs[ctr].data += EVP_GCM_TLS_EXPLICIT_IV_LEN;
+                    recs[ctr].input += EVP_GCM_TLS_EXPLICIT_IV_LEN;
+                    recs[ctr].length -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
+                }
+            } else if (EVP_CIPHER_mode(enc) == EVP_CIPH_CCM_MODE) {
+                for (ctr = 0; ctr < n_recs; ctr++) {
+                    recs[ctr].data += EVP_CCM_TLS_EXPLICIT_IV_LEN;
+                    recs[ctr].input += EVP_CCM_TLS_EXPLICIT_IV_LEN;
+                    recs[ctr].length -= EVP_CCM_TLS_EXPLICIT_IV_LEN;
+                }
+            }
+        }
+
+        ret = 1;
+        if (!SSL_READ_ETM(s) && EVP_MD_CTX_md(s->read_hash) != NULL)
+            mac_size = EVP_MD_CTX_size(s->read_hash);
+        if ((bs != 1) && !send) {
+            int tmpret;
+            for (ctr = 0; ctr < n_recs; ctr++) {
+                tmpret = tls1_cbc_remove_padding(s, &recs[ctr], bs, mac_size);
+                /*
+                 * If tmpret == 0 then this means publicly invalid so we can
+                 * short circuit things here. Otherwise we must respect constant
+                 * time behaviour.
+                 */
+                if (tmpret == 0)
+                    return 0;
+                ret = constant_time_select_int(constant_time_eq_int(tmpret, 1),
+                                               ret, -1);
+            }
+        }
+        if (pad && !send) {
+            for (ctr = 0; ctr < n_recs; ctr++) {
+                recs[ctr].length -= pad;
+            }
+        }
+    }
+    return ret;
+}
+
+int n_ssl3_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int send)
+{
+    unsigned char *mac_sec, *seq;
+    const EVP_MD_CTX *hash;
+    unsigned char *p, rec_char;
+    size_t md_size;
+    int npad;
+    int t;
+
+    if (send) {
+        mac_sec = &(ssl->s3->write_mac_secret[0]);
+        seq = RECORD_LAYER_get_write_sequence(&ssl->rlayer);
+        hash = ssl->write_hash;
+    } else {
+        mac_sec = &(ssl->s3->read_mac_secret[0]);
+        seq = RECORD_LAYER_get_read_sequence(&ssl->rlayer);
+        hash = ssl->read_hash;
+    }
+
+    t = EVP_MD_CTX_size(hash);
+    if (t < 0)
+        return -1;
+    md_size = t;
+    npad = (48 / md_size) * md_size;
+
+    if (!send &&
+        EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+        ssl3_cbc_record_digest_supported(hash)) {
+        /*
+         * This is a CBC-encrypted record. We must avoid leaking any
+         * timing-side channel information about how many blocks of data we
+         * are hashing because that gives an attacker a timing-oracle.
+         */
+
+        /*-
+         * npad is, at most, 48 bytes and that's with MD5:
+         *   16 + 48 + 8 (sequence bytes) + 1 + 2 = 75.
+         *
+         * With SHA-1 (the largest hash speced for SSLv3) the hash size
+         * goes up 4, but npad goes down by 8, resulting in a smaller
+         * total size.
+         */
+        unsigned char header[75];
+        unsigned j = 0;
+        memcpy(header + j, mac_sec, md_size);
+        j += md_size;
+        memcpy(header + j, ssl3_pad_1, npad);
+        j += npad;
+        memcpy(header + j, seq, 8);
+        j += 8;
+        header[j++] = rec->type;
+        header[j++] = rec->length >> 8;
+        header[j++] = rec->length & 0xff;
+
+        /* Final param == is SSLv3 */
+        if (ssl3_cbc_digest_record(hash,
+                                   md, &md_size,
+                                   header, rec->input,
+                                   rec->length + md_size, rec->orig_len,
+                                   mac_sec, md_size, 1) <= 0)
+            return -1;
+    } else {
+        unsigned int md_size_u;
+        /* Chop the digest off the end :-) */
+        EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
+
+        if (md_ctx == NULL)
+            return -1;
+
+        rec_char = rec->type;
+        p = md;
+        s2n(rec->length, p);
+        if (EVP_MD_CTX_copy_ex(md_ctx, hash) <= 0
+            || EVP_DigestUpdate(md_ctx, mac_sec, md_size) <= 0
+            || EVP_DigestUpdate(md_ctx, ssl3_pad_1, npad) <= 0
+            || EVP_DigestUpdate(md_ctx, seq, 8) <= 0
+            || EVP_DigestUpdate(md_ctx, &rec_char, 1) <= 0
+            || EVP_DigestUpdate(md_ctx, md, 2) <= 0
+            || EVP_DigestUpdate(md_ctx, rec->input, rec->length) <= 0
+            || EVP_DigestFinal_ex(md_ctx, md, NULL) <= 0
+            || EVP_MD_CTX_copy_ex(md_ctx, hash) <= 0
+            || EVP_DigestUpdate(md_ctx, mac_sec, md_size) <= 0
+            || EVP_DigestUpdate(md_ctx, ssl3_pad_2, npad) <= 0
+            || EVP_DigestUpdate(md_ctx, md, md_size) <= 0
+            || EVP_DigestFinal_ex(md_ctx, md, &md_size_u) <= 0) {
+            EVP_MD_CTX_reset(md_ctx);
+            return -1;
+        }
+        md_size = md_size_u;
+
+        EVP_MD_CTX_free(md_ctx);
+    }
+
+    ssl3_record_sequence_update(seq);
+    return (md_size);
+}
+
+int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int send)
+{
+    unsigned char *seq;
+    EVP_MD_CTX *hash;
+    size_t md_size;
+    int i;
+    EVP_MD_CTX *hmac = NULL, *mac_ctx;
+    unsigned char header[13];
+    int stream_mac = (send ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM)
+                      : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM));
+    int t;
+
+    if (send) {
+        seq = RECORD_LAYER_get_write_sequence(&ssl->rlayer);
+        hash = ssl->write_hash;
+    } else {
+        seq = RECORD_LAYER_get_read_sequence(&ssl->rlayer);
+        hash = ssl->read_hash;
+    }
+
+    t = EVP_MD_CTX_size(hash);
+    OPENSSL_assert(t >= 0);
+    md_size = t;
+
+    /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */
+    if (stream_mac) {
+        mac_ctx = hash;
+    } else {
+        hmac = EVP_MD_CTX_new();
+        if (hmac == NULL || !EVP_MD_CTX_copy(hmac, hash))
+            return -1;
+        mac_ctx = hmac;
+    }
+
+    if (SSL_IS_DTLS(ssl)) {
+        unsigned char dtlsseq[8], *p = dtlsseq;
+
+        s2n(send ? DTLS_RECORD_LAYER_get_w_epoch(&ssl->rlayer) :
+            DTLS_RECORD_LAYER_get_r_epoch(&ssl->rlayer), p);
+        memcpy(p, &seq[2], 6);
+
+        memcpy(header, dtlsseq, 8);
+    } else
+        memcpy(header, seq, 8);
+
+    header[8] = rec->type;
+    header[9] = (unsigned char)(ssl->version >> 8);
+    header[10] = (unsigned char)(ssl->version);
+    header[11] = (rec->length) >> 8;
+    header[12] = (rec->length) & 0xff;
+
+    if (!send && !SSL_READ_ETM(ssl) &&
+        EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+        ssl3_cbc_record_digest_supported(mac_ctx)) {
+        /*
+         * This is a CBC-encrypted record. We must avoid leaking any
+         * timing-side channel information about how many blocks of data we
+         * are hashing because that gives an attacker a timing-oracle.
+         */
+        /* Final param == not SSLv3 */
+        if (ssl3_cbc_digest_record(mac_ctx,
+                                   md, &md_size,
+                                   header, rec->input,
+                                   rec->length + md_size, rec->orig_len,
+                                   ssl->s3->read_mac_secret,
+                                   ssl->s3->read_mac_secret_size, 0) <= 0) {
+            EVP_MD_CTX_free(hmac);
+            return -1;
+        }
+    } else {
+        if (EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)) <= 0
+            || EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length) <= 0
+            || EVP_DigestSignFinal(mac_ctx, md, &md_size) <= 0) {
+            EVP_MD_CTX_free(hmac);
+            return -1;
+        }
+        if (!send && !SSL_READ_ETM(ssl) && FIPS_mode())
+            if (!tls_fips_digest_extra(ssl->enc_read_ctx,
+                                       mac_ctx, rec->input,
+                                       rec->length, rec->orig_len)) {
+                EVP_MD_CTX_free(hmac);
+                return -1;
+            }
+    }
+
+    EVP_MD_CTX_free(hmac);
+
+#ifdef SSL_DEBUG
+    fprintf(stderr, "seq=");
+    {
+        int z;
+        for (z = 0; z < 8; z++)
+            fprintf(stderr, "%02X ", seq[z]);
+        fprintf(stderr, "\n");
+    }
+    fprintf(stderr, "rec=");
+    {
+        unsigned int z;
+        for (z = 0; z < rec->length; z++)
+            fprintf(stderr, "%02X ", rec->data[z]);
+        fprintf(stderr, "\n");
+    }
+#endif
+
+    if (!SSL_IS_DTLS(ssl)) {
+        for (i = 7; i >= 0; i--) {
+            ++seq[i];
+            if (seq[i] != 0)
+                break;
+        }
+    }
+#ifdef SSL_DEBUG
+    {
+        unsigned int z;
+        for (z = 0; z < md_size; z++)
+            fprintf(stderr, "%02X ", md[z]);
+        fprintf(stderr, "\n");
+    }
+#endif
+    return (md_size);
+}
+
+/*-
+ * ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC
+ * record in |rec| by updating |rec->length| in constant time.
+ *
+ * block_size: the block size of the cipher used to encrypt the record.
+ * returns:
+ *   0: (in non-constant time) if the record is publicly invalid.
+ *   1: if the padding was valid
+ *  -1: otherwise.
+ */
+int ssl3_cbc_remove_padding(SSL3_RECORD *rec,
+                            unsigned block_size, unsigned mac_size)
+{
+    unsigned padding_length, good;
+    const unsigned overhead = 1 /* padding length byte */  + mac_size;
+
+    /*
+     * These lengths are all public so we can test them in non-constant time.
+     */
+    if (overhead > rec->length)
+        return 0;
+
+    padding_length = rec->data[rec->length - 1];
+    good = constant_time_ge(rec->length, padding_length + overhead);
+    /* SSLv3 requires that the padding is minimal. */
+    good &= constant_time_ge(block_size, padding_length + 1);
+    rec->length -= good & (padding_length + 1);
+    return constant_time_select_int(good, 1, -1);
+}
+
+/*-
+ * tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC
+ * record in |rec| in constant time and returns 1 if the padding is valid and
+ * -1 otherwise. It also removes any explicit IV from the start of the record
+ * without leaking any timing about whether there was enough space after the
+ * padding was removed.
+ *
+ * block_size: the block size of the cipher used to encrypt the record.
+ * returns:
+ *   0: (in non-constant time) if the record is publicly invalid.
+ *   1: if the padding was valid
+ *  -1: otherwise.
+ */
+int tls1_cbc_remove_padding(const SSL *s,
+                            SSL3_RECORD *rec,
+                            unsigned block_size, unsigned mac_size)
+{
+    unsigned padding_length, good, to_check, i;
+    const unsigned overhead = 1 /* padding length byte */  + mac_size;
+    /* Check if version requires explicit IV */
+    if (SSL_USE_EXPLICIT_IV(s)) {
+        /*
+         * These lengths are all public so we can test them in non-constant
+         * time.
+         */
+        if (overhead + block_size > rec->length)
+            return 0;
+        /* We can now safely skip explicit IV */
+        rec->data += block_size;
+        rec->input += block_size;
+        rec->length -= block_size;
+        rec->orig_len -= block_size;
+    } else if (overhead > rec->length)
+        return 0;
+
+    padding_length = rec->data[rec->length - 1];
+
+    if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_read_ctx)) &
+        EVP_CIPH_FLAG_AEAD_CIPHER) {
+        /* padding is already verified */
+        rec->length -= padding_length + 1;
+        return 1;
+    }
+
+    good = constant_time_ge(rec->length, overhead + padding_length);
+    /*
+     * The padding consists of a length byte at the end of the record and
+     * then that many bytes of padding, all with the same value as the length
+     * byte. Thus, with the length byte included, there are i+1 bytes of
+     * padding. We can't check just |padding_length+1| bytes because that
+     * leaks decrypted information. Therefore we always have to check the
+     * maximum amount of padding possible. (Again, the length of the record
+     * is public information so we can use it.)
+     */
+    to_check = 256;            /* maximum amount of padding, inc length byte. */
+    if (to_check > rec->length)
+        to_check = rec->length;
+
+    for (i = 0; i < to_check; i++) {
+        unsigned char mask = constant_time_ge_8(padding_length, i);
+        unsigned char b = rec->data[rec->length - 1 - i];
+        /*
+         * The final |padding_length+1| bytes should all have the value
+         * |padding_length|. Therefore the XOR should be zero.
+         */
+        good &= ~(mask & (padding_length ^ b));
+    }
+
+    /*
+     * If any of the final |padding_length+1| bytes had the wrong value, one
+     * or more of the lower eight bits of |good| will be cleared.
+     */
+    good = constant_time_eq(0xff, good & 0xff);
+    rec->length -= good & (padding_length + 1);
+
+    return constant_time_select_int(good, 1, -1);
+}
+
+/*-
+ * ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in
+ * constant time (independent of the concrete value of rec->length, which may
+ * vary within a 256-byte window).
+ *
+ * ssl3_cbc_remove_padding or tls1_cbc_remove_padding must be called prior to
+ * this function.
+ *
+ * On entry:
+ *   rec->orig_len >= md_size
+ *   md_size <= EVP_MAX_MD_SIZE
+ *
+ * If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with
+ * variable accesses in a 64-byte-aligned buffer. Assuming that this fits into
+ * a single or pair of cache-lines, then the variable memory accesses don't
+ * actually affect the timing. CPUs with smaller cache-lines [if any] are
+ * not multi-core and are not considered vulnerable to cache-timing attacks.
+ */
+#define CBC_MAC_ROTATE_IN_PLACE
+
+void ssl3_cbc_copy_mac(unsigned char *out,
+                       const SSL3_RECORD *rec, unsigned md_size)
+{
+#if defined(CBC_MAC_ROTATE_IN_PLACE)
+    unsigned char rotated_mac_buf[64 + EVP_MAX_MD_SIZE];
+    unsigned char *rotated_mac;
+#else
+    unsigned char rotated_mac[EVP_MAX_MD_SIZE];
+#endif
+
+    /*
+     * mac_end is the index of |rec->data| just after the end of the MAC.
+     */
+    unsigned mac_end = rec->length;
+    unsigned mac_start = mac_end - md_size;
+    unsigned in_mac;
+    /*
+     * scan_start contains the number of bytes that we can ignore because the
+     * MAC's position can only vary by 255 bytes.
+     */
+    unsigned scan_start = 0;
+    unsigned i, j;
+    unsigned rotate_offset;
+
+    OPENSSL_assert(rec->orig_len >= md_size);
+    OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE);
+
+#if defined(CBC_MAC_ROTATE_IN_PLACE)
+    rotated_mac = rotated_mac_buf + ((0 - (size_t)rotated_mac_buf) & 63);
+#endif
+
+    /* This information is public so it's safe to branch based on it. */
+    if (rec->orig_len > md_size + 255 + 1)
+        scan_start = rec->orig_len - (md_size + 255 + 1);
+
+    in_mac = 0;
+    rotate_offset = 0;
+    memset(rotated_mac, 0, md_size);
+    for (i = scan_start, j = 0; i < rec->orig_len; i++) {
+        unsigned mac_started = constant_time_eq(i, mac_start);
+        unsigned mac_ended = constant_time_lt(i, mac_end);
+        unsigned char b = rec->data[i];
+
+        in_mac |= mac_started;
+        in_mac &= mac_ended;
+        rotate_offset |= j & mac_started;
+        rotated_mac[j++] |= b & in_mac;
+        j &= constant_time_lt(j, md_size);
+    }
+
+    /* Now rotate the MAC */
+#if defined(CBC_MAC_ROTATE_IN_PLACE)
+    j = 0;
+    for (i = 0; i < md_size; i++) {
+        /* in case cache-line is 32 bytes, touch second line */
+        ((volatile unsigned char *)rotated_mac)[rotate_offset ^ 32];
+        out[j++] = rotated_mac[rotate_offset++];
+        rotate_offset &= constant_time_lt(rotate_offset, md_size);
+    }
+#else
+    memset(out, 0, md_size);
+    rotate_offset = md_size - rotate_offset;
+    rotate_offset &= constant_time_lt(rotate_offset, md_size);
+    for (i = 0; i < md_size; i++) {
+        for (j = 0; j < md_size; j++)
+            out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset);
+        rotate_offset++;
+        rotate_offset &= constant_time_lt(rotate_offset, md_size);
+    }
+#endif
+}
+
+int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap)
+{
+    int i, al;
+    int enc_err;
+    SSL_SESSION *sess;
+    SSL3_RECORD *rr;
+    unsigned int mac_size;
+    unsigned char md[EVP_MAX_MD_SIZE];
+
+    rr = RECORD_LAYER_get_rrec(&s->rlayer);
+    sess = s->session;
+
+    /*
+     * At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
+     * and we have that many bytes in s->packet
+     */
+    rr->input = &(RECORD_LAYER_get_packet(&s->rlayer)[DTLS1_RT_HEADER_LENGTH]);
+
+    /*
+     * ok, we can now read from 's->packet' data into 'rr' rr->input points
+     * at rr->length bytes, which need to be copied into rr->data by either
+     * the decryption or by the decompression When the data is 'copied' into
+     * the rr->data buffer, rr->input will be pointed at the new buffer
+     */
+
+    /*
+     * We now have - encrypted [ MAC [ compressed [ plain ] ] ] rr->length
+     * bytes of encrypted compressed stuff.
+     */
+
+    /* check is not needed I believe */
+    if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
+        al = SSL_AD_RECORD_OVERFLOW;
+        SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
+        goto f_err;
+    }
+
+    /* decrypt in place in 'rr->input' */
+    rr->data = rr->input;
+    rr->orig_len = rr->length;
+
+    enc_err = s->method->ssl3_enc->enc(s, rr, 1, 0);
+    /*-
+     * enc_err is:
+     *    0: (in non-constant time) if the record is publically invalid.
+     *    1: if the padding is valid
+     *   -1: if the padding is invalid
+     */
+    if (enc_err == 0) {
+        /* For DTLS we simply ignore bad packets. */
+        rr->length = 0;
+        RECORD_LAYER_reset_packet_length(&s->rlayer);
+        goto err;
+    }
+#ifdef SSL_DEBUG
+    printf("dec %d\n", rr->length);
+    {
+        unsigned int z;
+        for (z = 0; z < rr->length; z++)
+            printf("%02X%c", rr->data[z], ((z + 1) % 16) ? ' ' : '\n');
+    }
+    printf("\n");
+#endif
+
+    /* r->length is now the compressed data plus mac */
+    if ((sess != NULL) &&
+        (s->enc_read_ctx != NULL) && (EVP_MD_CTX_md(s->read_hash) != NULL)) {
+        /* s->read_hash != NULL => mac_size != -1 */
+        unsigned char *mac = NULL;
+        unsigned char mac_tmp[EVP_MAX_MD_SIZE];
+        mac_size = EVP_MD_CTX_size(s->read_hash);
+        OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
+
+        /*
+         * orig_len is the length of the record before any padding was
+         * removed. This is public information, as is the MAC in use,
+         * therefore we can safely process the record in a different amount
+         * of time if it's too short to possibly contain a MAC.
+         */
+        if (rr->orig_len < mac_size ||
+            /* CBC records must have a padding length byte too. */
+            (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+             rr->orig_len < mac_size + 1)) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_LENGTH_TOO_SHORT);
+            goto f_err;
+        }
+
+        if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) {
+            /*
+             * We update the length so that the TLS header bytes can be
+             * constructed correctly but we need to extract the MAC in
+             * constant time from within the record, without leaking the
+             * contents of the padding bytes.
+             */
+            mac = mac_tmp;
+            ssl3_cbc_copy_mac(mac_tmp, rr, mac_size);
+            rr->length -= mac_size;
+        } else {
+            /*
+             * In this case there's no padding, so |rec->orig_len| equals
+             * |rec->length| and we checked that there's enough bytes for
+             * |mac_size| above.
+             */
+            rr->length -= mac_size;
+            mac = &rr->data[rr->length];
+        }
+
+        i = s->method->ssl3_enc->mac(s, rr, md, 0 /* not send */ );
+        if (i < 0 || mac == NULL
+            || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0)
+            enc_err = -1;
+        if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size)
+            enc_err = -1;
+    }
+
+    if (enc_err < 0) {
+        /* decryption failed, silently discard message */
+        rr->length = 0;
+        RECORD_LAYER_reset_packet_length(&s->rlayer);
+        goto err;
+    }
+
+    /* r->length is now just compressed */
+    if (s->expand != NULL) {
+        if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH) {
+            al = SSL_AD_RECORD_OVERFLOW;
+            SSLerr(SSL_F_DTLS1_PROCESS_RECORD,
+                   SSL_R_COMPRESSED_LENGTH_TOO_LONG);
+            goto f_err;
+        }
+        if (!ssl3_do_uncompress(s, rr)) {
+            al = SSL_AD_DECOMPRESSION_FAILURE;
+            SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_BAD_DECOMPRESSION);
+            goto f_err;
+        }
+    }
+
+    if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH) {
+        al = SSL_AD_RECORD_OVERFLOW;
+        SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_DATA_LENGTH_TOO_LONG);
+        goto f_err;
+    }
+
+    rr->off = 0;
+    /*-
+     * So at this point the following is true
+     * ssl->s3->rrec.type   is the type of record
+     * ssl->s3->rrec.length == number of bytes in record
+     * ssl->s3->rrec.off    == offset to first valid byte
+     * ssl->s3->rrec.data   == where to take bytes from, increment
+     *                         after use :-).
+     */
+
+    /* we have pulled in a full packet so zero things */
+    RECORD_LAYER_reset_packet_length(&s->rlayer);
+
+    /* Mark receipt of record. */
+    dtls1_record_bitmap_update(s, bitmap);
+
+    return (1);
+
+ f_err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ err:
+    return (0);
+}
+
+/*
+ * retrieve a buffered record that belongs to the current epoch, ie,
+ * processed
+ */
+#define dtls1_get_processed_record(s) \
+                   dtls1_retrieve_buffered_record((s), \
+                   &(DTLS_RECORD_LAYER_get_processed_rcds(&s->rlayer)))
+
+/*-
+ * Call this to get a new input record.
+ * It will return <= 0 if more data is needed, normally due to an error
+ * or non-blocking IO.
+ * When it finishes, one packet has been decoded and can be found in
+ * ssl->s3->rrec.type    - is the type of record
+ * ssl->s3->rrec.data,   - data
+ * ssl->s3->rrec.length, - number of bytes
+ */
+/* used only by dtls1_read_bytes */
+int dtls1_get_record(SSL *s)
+{
+    int ssl_major, ssl_minor;
+    int i, n;
+    SSL3_RECORD *rr;
+    unsigned char *p = NULL;
+    unsigned short version;
+    DTLS1_BITMAP *bitmap;
+    unsigned int is_next_epoch;
+
+    rr = RECORD_LAYER_get_rrec(&s->rlayer);
+
+ again:
+    /*
+     * The epoch may have changed.  If so, process all the pending records.
+     * This is a non-blocking operation.
+     */
+    if (!dtls1_process_buffered_records(s))
+        return -1;
+
+    /* if we're renegotiating, then there may be buffered records */
+    if (dtls1_get_processed_record(s))
+        return 1;
+
+    /* get something from the wire */
+
+    /* check if we have the header */
+    if ((RECORD_LAYER_get_rstate(&s->rlayer) != SSL_ST_READ_BODY) ||
+        (RECORD_LAYER_get_packet_length(&s->rlayer) < DTLS1_RT_HEADER_LENGTH)) {
+        n = ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH,
+                        SSL3_BUFFER_get_len(&s->rlayer.rbuf), 0, 1);
+        /* read timeout is handled by dtls1_read_bytes */
+        if (n <= 0)
+            return (n);         /* error or non-blocking */
+
+        /* this packet contained a partial record, dump it */
+        if (RECORD_LAYER_get_packet_length(&s->rlayer) !=
+            DTLS1_RT_HEADER_LENGTH) {
+            RECORD_LAYER_reset_packet_length(&s->rlayer);
+            goto again;
+        }
+
+        RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_BODY);
+
+        p = RECORD_LAYER_get_packet(&s->rlayer);
+
+        if (s->msg_callback)
+            s->msg_callback(0, 0, SSL3_RT_HEADER, p, DTLS1_RT_HEADER_LENGTH,
+                            s, s->msg_callback_arg);
+
+        /* Pull apart the header into the DTLS1_RECORD */
+        rr->type = *(p++);
+        ssl_major = *(p++);
+        ssl_minor = *(p++);
+        version = (ssl_major << 8) | ssl_minor;
+
+        /* sequence number is 64 bits, with top 2 bytes = epoch */
+        n2s(p, rr->epoch);
+
+        memcpy(&(RECORD_LAYER_get_read_sequence(&s->rlayer)[2]), p, 6);
+        p += 6;
+
+        n2s(p, rr->length);
+
+        /* Lets check version */
+        if (!s->first_packet) {
+            if (version != s->version) {
+                /* unexpected version, silently discard */
+                rr->length = 0;
+                RECORD_LAYER_reset_packet_length(&s->rlayer);
+                goto again;
+            }
+        }
+
+        if ((version & 0xff00) != (s->version & 0xff00)) {
+            /* wrong version, silently discard record */
+            rr->length = 0;
+            RECORD_LAYER_reset_packet_length(&s->rlayer);
+            goto again;
+        }
+
+        if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
+            /* record too long, silently discard it */
+            rr->length = 0;
+            RECORD_LAYER_reset_packet_length(&s->rlayer);
+            goto again;
+        }
+
+        /* now s->rlayer.rstate == SSL_ST_READ_BODY */
+    }
+
+    /* s->rlayer.rstate == SSL_ST_READ_BODY, get and decode the data */
+
+    if (rr->length >
+        RECORD_LAYER_get_packet_length(&s->rlayer) - DTLS1_RT_HEADER_LENGTH) {
+        /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */
+        i = rr->length;
+        n = ssl3_read_n(s, i, i, 1, 1);
+        /* this packet contained a partial record, dump it */
+        if (n != i) {
+            rr->length = 0;
+            RECORD_LAYER_reset_packet_length(&s->rlayer);
+            goto again;
+        }
+
+        /*
+         * now n == rr->length, and s->packet_length ==
+         * DTLS1_RT_HEADER_LENGTH + rr->length
+         */
+    }
+    /* set state for later operations */
+    RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_HEADER);
+
+    /* match epochs.  NULL means the packet is dropped on the floor */
+    bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
+    if (bitmap == NULL) {
+        rr->length = 0;
+        RECORD_LAYER_reset_packet_length(&s->rlayer); /* dump this record */
+        goto again;             /* get another record */
+    }
+#ifndef OPENSSL_NO_SCTP
+    /* Only do replay check if no SCTP bio */
+    if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) {
+#endif
+        /* Check whether this is a repeat, or aged record. */
+        /*
+         * TODO: Does it make sense to have replay protection in epoch 0 where
+         * we have no integrity negotiated yet?
+         */
+        if (!dtls1_record_replay_check(s, bitmap)) {
+            rr->length = 0;
+            RECORD_LAYER_reset_packet_length(&s->rlayer); /* dump this record */
+            goto again;         /* get another record */
+        }
+#ifndef OPENSSL_NO_SCTP
+    }
+#endif
+
+    /* just read a 0 length packet */
+    if (rr->length == 0)
+        goto again;
+
+    /*
+     * If this record is from the next epoch (either HM or ALERT), and a
+     * handshake is currently in progress, buffer it since it cannot be
+     * processed at this time.
+     */
+    if (is_next_epoch) {
+        if ((SSL_in_init(s) || ossl_statem_get_in_handshake(s))) {
+            if (dtls1_buffer_record
+                (s, &(DTLS_RECORD_LAYER_get_unprocessed_rcds(&s->rlayer)),
+                 rr->seq_num) < 0)
+                return -1;
+        }
+        rr->length = 0;
+        RECORD_LAYER_reset_packet_length(&s->rlayer);
+        goto again;
+    }
+
+    if (!dtls1_process_record(s, bitmap)) {
+        rr->length = 0;
+        RECORD_LAYER_reset_packet_length(&s->rlayer); /* dump this record */
+        goto again;             /* get another record */
+    }
+
+    return (1);
+
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/s3_cbc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/s3_cbc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/s3_cbc.c	(revision 331)
@@ -0,0 +1,529 @@
+/*
+ * Copyright 2012-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 "internal/constant_time_locl.h"
+#include "ssl_locl.h"
+
+#include <openssl/md5.h>
+#include <openssl/sha.h>
+
+/*
+ * MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's
+ * length field. (SHA-384/512 have 128-bit length.)
+ */
+#define MAX_HASH_BIT_COUNT_BYTES 16
+
+/*
+ * MAX_HASH_BLOCK_SIZE is the maximum hash block size that we'll support.
+ * Currently SHA-384/512 has a 128-byte block size and that's the largest
+ * supported by TLS.)
+ */
+#define MAX_HASH_BLOCK_SIZE 128
+
+/*
+ * u32toLE serialises an unsigned, 32-bit number (n) as four bytes at (p) in
+ * little-endian order. The value of p is advanced by four.
+ */
+#define u32toLE(n, p) \
+        (*((p)++)=(unsigned char)(n), \
+         *((p)++)=(unsigned char)(n>>8), \
+         *((p)++)=(unsigned char)(n>>16), \
+         *((p)++)=(unsigned char)(n>>24))
+
+/*
+ * These functions serialize the state of a hash and thus perform the
+ * standard "final" operation without adding the padding and length that such
+ * a function typically does.
+ */
+static void tls1_md5_final_raw(void *ctx, unsigned char *md_out)
+{
+    MD5_CTX *md5 = ctx;
+    u32toLE(md5->A, md_out);
+    u32toLE(md5->B, md_out);
+    u32toLE(md5->C, md_out);
+    u32toLE(md5->D, md_out);
+}
+
+static void tls1_sha1_final_raw(void *ctx, unsigned char *md_out)
+{
+    SHA_CTX *sha1 = ctx;
+    l2n(sha1->h0, md_out);
+    l2n(sha1->h1, md_out);
+    l2n(sha1->h2, md_out);
+    l2n(sha1->h3, md_out);
+    l2n(sha1->h4, md_out);
+}
+
+static void tls1_sha256_final_raw(void *ctx, unsigned char *md_out)
+{
+    SHA256_CTX *sha256 = ctx;
+    unsigned i;
+
+    for (i = 0; i < 8; i++) {
+        l2n(sha256->h[i], md_out);
+    }
+}
+
+static void tls1_sha512_final_raw(void *ctx, unsigned char *md_out)
+{
+    SHA512_CTX *sha512 = ctx;
+    unsigned i;
+
+    for (i = 0; i < 8; i++) {
+        l2n8(sha512->h[i], md_out);
+    }
+}
+
+#undef  LARGEST_DIGEST_CTX
+#define LARGEST_DIGEST_CTX SHA512_CTX
+
+/*
+ * ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function
+ * which ssl3_cbc_digest_record supports.
+ */
+char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx)
+{
+    if (FIPS_mode())
+        return 0;
+    switch (EVP_MD_CTX_type(ctx)) {
+    case NID_md5:
+    case NID_sha1:
+    case NID_sha224:
+    case NID_sha256:
+    case NID_sha384:
+    case NID_sha512:
+        return 1;
+    default:
+        return 0;
+    }
+}
+
+/*-
+ * ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS
+ * record.
+ *
+ *   ctx: the EVP_MD_CTX from which we take the hash function.
+ *     ssl3_cbc_record_digest_supported must return true for this EVP_MD_CTX.
+ *   md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written.
+ *   md_out_size: if non-NULL, the number of output bytes is written here.
+ *   header: the 13-byte, TLS record header.
+ *   data: the record data itself, less any preceding explicit IV.
+ *   data_plus_mac_size: the secret, reported length of the data and MAC
+ *     once the padding has been removed.
+ *   data_plus_mac_plus_padding_size: the public length of the whole
+ *     record, including padding.
+ *   is_sslv3: non-zero if we are to use SSLv3. Otherwise, TLS.
+ *
+ * On entry: by virtue of having been through one of the remove_padding
+ * functions, above, we know that data_plus_mac_size is large enough to contain
+ * a padding byte and MAC. (If the padding was invalid, it might contain the
+ * padding too. )
+ * Returns 1 on success or 0 on error
+ */
+int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
+                           unsigned char *md_out,
+                           size_t *md_out_size,
+                           const unsigned char header[13],
+                           const unsigned char *data,
+                           size_t data_plus_mac_size,
+                           size_t data_plus_mac_plus_padding_size,
+                           const unsigned char *mac_secret,
+                           unsigned mac_secret_length, char is_sslv3)
+{
+    union {
+        double align;
+        unsigned char c[sizeof(LARGEST_DIGEST_CTX)];
+    } md_state;
+    void (*md_final_raw) (void *ctx, unsigned char *md_out);
+    void (*md_transform) (void *ctx, const unsigned char *block);
+    unsigned md_size, md_block_size = 64;
+    unsigned sslv3_pad_length = 40, header_length, variance_blocks,
+        len, max_mac_bytes, num_blocks,
+        num_starting_blocks, k, mac_end_offset, c, index_a, index_b;
+    unsigned int bits;          /* at most 18 bits */
+    unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES];
+    /* hmac_pad is the masked HMAC key. */
+    unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE];
+    unsigned char first_block[MAX_HASH_BLOCK_SIZE];
+    unsigned char mac_out[EVP_MAX_MD_SIZE];
+    unsigned i, j, md_out_size_u;
+    EVP_MD_CTX *md_ctx = NULL;
+    /*
+     * mdLengthSize is the number of bytes in the length field that
+     * terminates * the hash.
+     */
+    unsigned md_length_size = 8;
+    char length_is_big_endian = 1;
+    int ret;
+
+    /*
+     * This is a, hopefully redundant, check that allows us to forget about
+     * many possible overflows later in this function.
+     */
+    OPENSSL_assert(data_plus_mac_plus_padding_size < 1024 * 1024);
+
+    switch (EVP_MD_CTX_type(ctx)) {
+    case NID_md5:
+        if (MD5_Init((MD5_CTX *)md_state.c) <= 0)
+            return 0;
+        md_final_raw = tls1_md5_final_raw;
+        md_transform =
+            (void (*)(void *ctx, const unsigned char *block))MD5_Transform;
+        md_size = 16;
+        sslv3_pad_length = 48;
+        length_is_big_endian = 0;
+        break;
+    case NID_sha1:
+        if (SHA1_Init((SHA_CTX *)md_state.c) <= 0)
+            return 0;
+        md_final_raw = tls1_sha1_final_raw;
+        md_transform =
+            (void (*)(void *ctx, const unsigned char *block))SHA1_Transform;
+        md_size = 20;
+        break;
+    case NID_sha224:
+        if (SHA224_Init((SHA256_CTX *)md_state.c) <= 0)
+            return 0;
+        md_final_raw = tls1_sha256_final_raw;
+        md_transform =
+            (void (*)(void *ctx, const unsigned char *block))SHA256_Transform;
+        md_size = 224 / 8;
+        break;
+    case NID_sha256:
+        if (SHA256_Init((SHA256_CTX *)md_state.c) <= 0)
+            return 0;
+        md_final_raw = tls1_sha256_final_raw;
+        md_transform =
+            (void (*)(void *ctx, const unsigned char *block))SHA256_Transform;
+        md_size = 32;
+        break;
+    case NID_sha384:
+        if (SHA384_Init((SHA512_CTX *)md_state.c) <= 0)
+            return 0;
+        md_final_raw = tls1_sha512_final_raw;
+        md_transform =
+            (void (*)(void *ctx, const unsigned char *block))SHA512_Transform;
+        md_size = 384 / 8;
+        md_block_size = 128;
+        md_length_size = 16;
+        break;
+    case NID_sha512:
+        if (SHA512_Init((SHA512_CTX *)md_state.c) <= 0)
+            return 0;
+        md_final_raw = tls1_sha512_final_raw;
+        md_transform =
+            (void (*)(void *ctx, const unsigned char *block))SHA512_Transform;
+        md_size = 64;
+        md_block_size = 128;
+        md_length_size = 16;
+        break;
+    default:
+        /*
+         * ssl3_cbc_record_digest_supported should have been called first to
+         * check that the hash function is supported.
+         */
+        OPENSSL_assert(0);
+        if (md_out_size)
+            *md_out_size = 0;
+        return 0;
+    }
+
+    OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES);
+    OPENSSL_assert(md_block_size <= MAX_HASH_BLOCK_SIZE);
+    OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE);
+
+    header_length = 13;
+    if (is_sslv3) {
+        header_length = mac_secret_length + sslv3_pad_length + 8 /* sequence
+                                                                  * number */  +
+            1 /* record type */  +
+            2 /* record length */ ;
+    }
+
+    /*
+     * variance_blocks is the number of blocks of the hash that we have to
+     * calculate in constant time because they could be altered by the
+     * padding value. In SSLv3, the padding must be minimal so the end of
+     * the plaintext varies by, at most, 15+20 = 35 bytes. (We conservatively
+     * assume that the MAC size varies from 0..20 bytes.) In case the 9 bytes
+     * of hash termination (0x80 + 64-bit length) don't fit in the final
+     * block, we say that the final two blocks can vary based on the padding.
+     * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not
+     * required to be minimal. Therefore we say that the final six blocks can
+     * vary based on the padding. Later in the function, if the message is
+     * short and there obviously cannot be this many blocks then
+     * variance_blocks can be reduced.
+     */
+    variance_blocks = is_sslv3 ? 2 : 6;
+    /*
+     * From now on we're dealing with the MAC, which conceptually has 13
+     * bytes of `header' before the start of the data (TLS) or 71/75 bytes
+     * (SSLv3)
+     */
+    len = data_plus_mac_plus_padding_size + header_length;
+    /*
+     * max_mac_bytes contains the maximum bytes of bytes in the MAC,
+     * including * |header|, assuming that there's no padding.
+     */
+    max_mac_bytes = len - md_size - 1;
+    /* num_blocks is the maximum number of hash blocks. */
+    num_blocks =
+        (max_mac_bytes + 1 + md_length_size + md_block_size -
+         1) / md_block_size;
+    /*
+     * In order to calculate the MAC in constant time we have to handle the
+     * final blocks specially because the padding value could cause the end
+     * to appear somewhere in the final |variance_blocks| blocks and we can't
+     * leak where. However, |num_starting_blocks| worth of data can be hashed
+     * right away because no padding value can affect whether they are
+     * plaintext.
+     */
+    num_starting_blocks = 0;
+    /*
+     * k is the starting byte offset into the conceptual header||data where
+     * we start processing.
+     */
+    k = 0;
+    /*
+     * mac_end_offset is the index just past the end of the data to be MACed.
+     */
+    mac_end_offset = data_plus_mac_size + header_length - md_size;
+    /*
+     * c is the index of the 0x80 byte in the final hash block that contains
+     * application data.
+     */
+    c = mac_end_offset % md_block_size;
+    /*
+     * index_a is the hash block number that contains the 0x80 terminating
+     * value.
+     */
+    index_a = mac_end_offset / md_block_size;
+    /*
+     * index_b is the hash block number that contains the 64-bit hash length,
+     * in bits.
+     */
+    index_b = (mac_end_offset + md_length_size) / md_block_size;
+    /*
+     * bits is the hash-length in bits. It includes the additional hash block
+     * for the masked HMAC key, or whole of |header| in the case of SSLv3.
+     */
+
+    /*
+     * For SSLv3, if we're going to have any starting blocks then we need at
+     * least two because the header is larger than a single block.
+     */
+    if (num_blocks > variance_blocks + (is_sslv3 ? 1 : 0)) {
+        num_starting_blocks = num_blocks - variance_blocks;
+        k = md_block_size * num_starting_blocks;
+    }
+
+    bits = 8 * mac_end_offset;
+    if (!is_sslv3) {
+        /*
+         * Compute the initial HMAC block. For SSLv3, the padding and secret
+         * bytes are included in |header| because they take more than a
+         * single block.
+         */
+        bits += 8 * md_block_size;
+        memset(hmac_pad, 0, md_block_size);
+        OPENSSL_assert(mac_secret_length <= sizeof(hmac_pad));
+        memcpy(hmac_pad, mac_secret, mac_secret_length);
+        for (i = 0; i < md_block_size; i++)
+            hmac_pad[i] ^= 0x36;
+
+        md_transform(md_state.c, hmac_pad);
+    }
+
+    if (length_is_big_endian) {
+        memset(length_bytes, 0, md_length_size - 4);
+        length_bytes[md_length_size - 4] = (unsigned char)(bits >> 24);
+        length_bytes[md_length_size - 3] = (unsigned char)(bits >> 16);
+        length_bytes[md_length_size - 2] = (unsigned char)(bits >> 8);
+        length_bytes[md_length_size - 1] = (unsigned char)bits;
+    } else {
+        memset(length_bytes, 0, md_length_size);
+        length_bytes[md_length_size - 5] = (unsigned char)(bits >> 24);
+        length_bytes[md_length_size - 6] = (unsigned char)(bits >> 16);
+        length_bytes[md_length_size - 7] = (unsigned char)(bits >> 8);
+        length_bytes[md_length_size - 8] = (unsigned char)bits;
+    }
+
+    if (k > 0) {
+        if (is_sslv3) {
+            unsigned overhang;
+
+            /*
+             * The SSLv3 header is larger than a single block. overhang is
+             * the number of bytes beyond a single block that the header
+             * consumes: either 7 bytes (SHA1) or 11 bytes (MD5). There are no
+             * ciphersuites in SSLv3 that are not SHA1 or MD5 based and
+             * therefore we can be confident that the header_length will be
+             * greater than |md_block_size|. However we add a sanity check just
+             * in case
+             */
+            if (header_length <= md_block_size) {
+                /* Should never happen */
+                return 0;
+            }
+            overhang = header_length - md_block_size;
+            md_transform(md_state.c, header);
+            memcpy(first_block, header + md_block_size, overhang);
+            memcpy(first_block + overhang, data, md_block_size - overhang);
+            md_transform(md_state.c, first_block);
+            for (i = 1; i < k / md_block_size - 1; i++)
+                md_transform(md_state.c, data + md_block_size * i - overhang);
+        } else {
+            /* k is a multiple of md_block_size. */
+            memcpy(first_block, header, 13);
+            memcpy(first_block + 13, data, md_block_size - 13);
+            md_transform(md_state.c, first_block);
+            for (i = 1; i < k / md_block_size; i++)
+                md_transform(md_state.c, data + md_block_size * i - 13);
+        }
+    }
+
+    memset(mac_out, 0, sizeof(mac_out));
+
+    /*
+     * We now process the final hash blocks. For each block, we construct it
+     * in constant time. If the |i==index_a| then we'll include the 0x80
+     * bytes and zero pad etc. For each block we selectively copy it, in
+     * constant time, to |mac_out|.
+     */
+    for (i = num_starting_blocks; i <= num_starting_blocks + variance_blocks;
+         i++) {
+        unsigned char block[MAX_HASH_BLOCK_SIZE];
+        unsigned char is_block_a = constant_time_eq_8(i, index_a);
+        unsigned char is_block_b = constant_time_eq_8(i, index_b);
+        for (j = 0; j < md_block_size; j++) {
+            unsigned char b = 0, is_past_c, is_past_cp1;
+            if (k < header_length)
+                b = header[k];
+            else if (k < data_plus_mac_plus_padding_size + header_length)
+                b = data[k - header_length];
+            k++;
+
+            is_past_c = is_block_a & constant_time_ge_8(j, c);
+            is_past_cp1 = is_block_a & constant_time_ge_8(j, c + 1);
+            /*
+             * If this is the block containing the end of the application
+             * data, and we are at the offset for the 0x80 value, then
+             * overwrite b with 0x80.
+             */
+            b = constant_time_select_8(is_past_c, 0x80, b);
+            /*
+             * If this the the block containing the end of the application
+             * data and we're past the 0x80 value then just write zero.
+             */
+            b = b & ~is_past_cp1;
+            /*
+             * If this is index_b (the final block), but not index_a (the end
+             * of the data), then the 64-bit length didn't fit into index_a
+             * and we're having to add an extra block of zeros.
+             */
+            b &= ~is_block_b | is_block_a;
+
+            /*
+             * The final bytes of one of the blocks contains the length.
+             */
+            if (j >= md_block_size - md_length_size) {
+                /* If this is index_b, write a length byte. */
+                b = constant_time_select_8(is_block_b,
+                                           length_bytes[j -
+                                                        (md_block_size -
+                                                         md_length_size)], b);
+            }
+            block[j] = b;
+        }
+
+        md_transform(md_state.c, block);
+        md_final_raw(md_state.c, block);
+        /* If this is index_b, copy the hash value to |mac_out|. */
+        for (j = 0; j < md_size; j++)
+            mac_out[j] |= block[j] & is_block_b;
+    }
+
+    md_ctx = EVP_MD_CTX_new();
+    if (md_ctx == NULL)
+        goto err;
+    if (EVP_DigestInit_ex(md_ctx, EVP_MD_CTX_md(ctx), NULL /* engine */ ) <= 0)
+        goto err;
+    if (is_sslv3) {
+        /* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */
+        memset(hmac_pad, 0x5c, sslv3_pad_length);
+
+        if (EVP_DigestUpdate(md_ctx, mac_secret, mac_secret_length) <= 0
+            || EVP_DigestUpdate(md_ctx, hmac_pad, sslv3_pad_length) <= 0
+            || EVP_DigestUpdate(md_ctx, mac_out, md_size) <= 0)
+            goto err;
+    } else {
+        /* Complete the HMAC in the standard manner. */
+        for (i = 0; i < md_block_size; i++)
+            hmac_pad[i] ^= 0x6a;
+
+        if (EVP_DigestUpdate(md_ctx, hmac_pad, md_block_size) <= 0
+            || EVP_DigestUpdate(md_ctx, mac_out, md_size) <= 0)
+            goto err;
+    }
+    ret = EVP_DigestFinal(md_ctx, md_out, &md_out_size_u);
+    if (ret && md_out_size)
+        *md_out_size = md_out_size_u;
+    EVP_MD_CTX_free(md_ctx);
+
+    return 1;
+ err:
+    EVP_MD_CTX_free(md_ctx);
+    return 0;
+}
+
+/*
+ * Due to the need to use EVP in FIPS mode we can't reimplement digests but
+ * we can ensure the number of blocks processed is equal for all cases by
+ * digesting additional data.
+ */
+
+int tls_fips_digest_extra(const EVP_CIPHER_CTX *cipher_ctx,
+                          EVP_MD_CTX *mac_ctx, const unsigned char *data,
+                          size_t data_len, size_t orig_len)
+{
+    size_t block_size, digest_pad, blocks_data, blocks_orig;
+    if (EVP_CIPHER_CTX_mode(cipher_ctx) != EVP_CIPH_CBC_MODE)
+        return 1;
+    block_size = EVP_MD_CTX_block_size(mac_ctx);
+    /*-
+     * We are in FIPS mode if we get this far so we know we have only SHA*
+     * digests and TLS to deal with.
+     * Minimum digest padding length is 17 for SHA384/SHA512 and 9
+     * otherwise.
+     * Additional header is 13 bytes. To get the number of digest blocks
+     * processed round up the amount of data plus padding to the nearest
+     * block length. Block length is 128 for SHA384/SHA512 and 64 otherwise.
+     * So we have:
+     * blocks = (payload_len + digest_pad + 13 + block_size - 1)/block_size
+     * equivalently:
+     * blocks = (payload_len + digest_pad + 12)/block_size + 1
+     * HMAC adds a constant overhead.
+     * We're ultimately only interested in differences so this becomes
+     * blocks = (payload_len + 29)/128
+     * for SHA384/SHA512 and
+     * blocks = (payload_len + 21)/64
+     * otherwise.
+     */
+    digest_pad = block_size == 64 ? 21 : 29;
+    blocks_orig = (orig_len + digest_pad) / block_size;
+    blocks_data = (data_len + digest_pad) / block_size;
+    /*
+     * MAC enough blocks to make up the difference between the original and
+     * actual lengths plus one extra block to ensure this is never a no op.
+     * The "data" pointer should always have enough space to perform this
+     * operation as it is large enough for a maximum length TLS buffer.
+     */
+    return EVP_DigestSignUpdate(mac_ctx, data,
+                                (blocks_orig - blocks_data + 1) * block_size);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/s3_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/s3_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/s3_enc.c	(revision 331)
@@ -0,0 +1,585 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <stdio.h>
+#include "ssl_locl.h"
+#include <openssl/evp.h>
+#include <openssl/md5.h>
+
+static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
+{
+    EVP_MD_CTX *m5;
+    EVP_MD_CTX *s1;
+    unsigned char buf[16], smd[SHA_DIGEST_LENGTH];
+    unsigned char c = 'A';
+    unsigned int i, j, k;
+    int ret = 0;
+
+#ifdef CHARSET_EBCDIC
+    c = os_toascii[c];          /* 'A' in ASCII */
+#endif
+    k = 0;
+    m5 = EVP_MD_CTX_new();
+    s1 = EVP_MD_CTX_new();
+    if (m5 == NULL || s1 == NULL) {
+        SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    EVP_MD_CTX_set_flags(m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+    for (i = 0; (int)i < num; i += MD5_DIGEST_LENGTH) {
+        k++;
+        if (k > sizeof(buf)) {
+            /* bug: 'buf' is too small for this ciphersuite */
+            SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+
+        for (j = 0; j < k; j++)
+            buf[j] = c;
+        c++;
+        if (!EVP_DigestInit_ex(s1, EVP_sha1(), NULL)
+            || !EVP_DigestUpdate(s1, buf, k)
+            || !EVP_DigestUpdate(s1, s->session->master_key,
+                                 s->session->master_key_length)
+            || !EVP_DigestUpdate(s1, s->s3->server_random, SSL3_RANDOM_SIZE)
+            || !EVP_DigestUpdate(s1, s->s3->client_random, SSL3_RANDOM_SIZE)
+            || !EVP_DigestFinal_ex(s1, smd, NULL)
+            || !EVP_DigestInit_ex(m5, EVP_md5(), NULL)
+            || !EVP_DigestUpdate(m5, s->session->master_key,
+                                 s->session->master_key_length)
+            || !EVP_DigestUpdate(m5, smd, SHA_DIGEST_LENGTH))
+            goto err;
+        if ((int)(i + MD5_DIGEST_LENGTH) > num) {
+            if (!EVP_DigestFinal_ex(m5, smd, NULL))
+                goto err;
+            memcpy(km, smd, (num - i));
+        } else {
+            if (!EVP_DigestFinal_ex(m5, km, NULL))
+                goto err;
+        }
+
+        km += MD5_DIGEST_LENGTH;
+    }
+    OPENSSL_cleanse(smd, sizeof(smd));
+    ret = 1;
+ err:
+    EVP_MD_CTX_free(m5);
+    EVP_MD_CTX_free(s1);
+    return ret;
+}
+
+int ssl3_change_cipher_state(SSL *s, int which)
+{
+    unsigned char *p, *mac_secret;
+    unsigned char exp_key[EVP_MAX_KEY_LENGTH];
+    unsigned char exp_iv[EVP_MAX_IV_LENGTH];
+    unsigned char *ms, *key, *iv;
+    EVP_CIPHER_CTX *dd;
+    const EVP_CIPHER *c;
+#ifndef OPENSSL_NO_COMP
+    COMP_METHOD *comp;
+#endif
+    const EVP_MD *m;
+    int n, i, j, k, cl;
+    int reuse_dd = 0;
+
+    c = s->s3->tmp.new_sym_enc;
+    m = s->s3->tmp.new_hash;
+    /* m == NULL will lead to a crash later */
+    OPENSSL_assert(m);
+#ifndef OPENSSL_NO_COMP
+    if (s->s3->tmp.new_compression == NULL)
+        comp = NULL;
+    else
+        comp = s->s3->tmp.new_compression->method;
+#endif
+
+    if (which & SSL3_CC_READ) {
+        if (s->enc_read_ctx != NULL)
+            reuse_dd = 1;
+        else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL)
+            goto err;
+        else
+            /*
+             * make sure it's initialised in case we exit later with an error
+             */
+            EVP_CIPHER_CTX_reset(s->enc_read_ctx);
+        dd = s->enc_read_ctx;
+
+        if (ssl_replace_hash(&s->read_hash, m) == NULL) {
+            SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+            goto err2;
+        }
+#ifndef OPENSSL_NO_COMP
+        /* COMPRESS */
+        COMP_CTX_free(s->expand);
+        s->expand = NULL;
+        if (comp != NULL) {
+            s->expand = COMP_CTX_new(comp);
+            if (s->expand == NULL) {
+                SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,
+                       SSL_R_COMPRESSION_LIBRARY_ERROR);
+                goto err2;
+            }
+        }
+#endif
+        RECORD_LAYER_reset_read_sequence(&s->rlayer);
+        mac_secret = &(s->s3->read_mac_secret[0]);
+    } else {
+        if (s->enc_write_ctx != NULL)
+            reuse_dd = 1;
+        else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL)
+            goto err;
+        else
+            /*
+             * make sure it's initialised in case we exit later with an error
+             */
+            EVP_CIPHER_CTX_reset(s->enc_write_ctx);
+        dd = s->enc_write_ctx;
+        if (ssl_replace_hash(&s->write_hash, m) == NULL) {
+            SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+            goto err2;
+        }
+#ifndef OPENSSL_NO_COMP
+        /* COMPRESS */
+        COMP_CTX_free(s->compress);
+        s->compress = NULL;
+        if (comp != NULL) {
+            s->compress = COMP_CTX_new(comp);
+            if (s->compress == NULL) {
+                SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,
+                       SSL_R_COMPRESSION_LIBRARY_ERROR);
+                goto err2;
+            }
+        }
+#endif
+        RECORD_LAYER_reset_write_sequence(&s->rlayer);
+        mac_secret = &(s->s3->write_mac_secret[0]);
+    }
+
+    if (reuse_dd)
+        EVP_CIPHER_CTX_reset(dd);
+
+    p = s->s3->tmp.key_block;
+    i = EVP_MD_size(m);
+    if (i < 0)
+        goto err2;
+    cl = EVP_CIPHER_key_length(c);
+    j = cl;
+    k = EVP_CIPHER_iv_length(c);
+    if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
+        (which == SSL3_CHANGE_CIPHER_SERVER_READ)) {
+        ms = &(p[0]);
+        n = i + i;
+        key = &(p[n]);
+        n += j + j;
+        iv = &(p[n]);
+        n += k + k;
+    } else {
+        n = i;
+        ms = &(p[n]);
+        n += i + j;
+        key = &(p[n]);
+        n += j + k;
+        iv = &(p[n]);
+        n += k;
+    }
+
+    if (n > s->s3->tmp.key_block_length) {
+        SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+        goto err2;
+    }
+
+    memcpy(mac_secret, ms, i);
+
+    if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE)))
+        goto err2;
+
+#ifdef OPENSSL_SSL_TRACE_CRYPTO
+    if (s->msg_callback) {
+
+        int wh = which & SSL3_CC_WRITE ?
+            TLS1_RT_CRYPTO_WRITE : TLS1_RT_CRYPTO_READ;
+        s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_MAC,
+                        mac_secret, EVP_MD_size(m), s, s->msg_callback_arg);
+        if (c->key_len)
+            s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY,
+                            key, c->key_len, s, s->msg_callback_arg);
+        if (k) {
+            s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_IV,
+                            iv, k, s, s->msg_callback_arg);
+        }
+    }
+#endif
+
+    OPENSSL_cleanse(exp_key, sizeof(exp_key));
+    OPENSSL_cleanse(exp_iv, sizeof(exp_iv));
+    return (1);
+ err:
+    SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE);
+ err2:
+    OPENSSL_cleanse(exp_key, sizeof(exp_key));
+    OPENSSL_cleanse(exp_iv, sizeof(exp_iv));
+    return (0);
+}
+
+int ssl3_setup_key_block(SSL *s)
+{
+    unsigned char *p;
+    const EVP_CIPHER *c;
+    const EVP_MD *hash;
+    int num;
+    int ret = 0;
+    SSL_COMP *comp;
+
+    if (s->s3->tmp.key_block_length != 0)
+        return (1);
+
+    if (!ssl_cipher_get_evp(s->session, &c, &hash, NULL, NULL, &comp, 0)) {
+        SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
+        return (0);
+    }
+
+    s->s3->tmp.new_sym_enc = c;
+    s->s3->tmp.new_hash = hash;
+#ifdef OPENSSL_NO_COMP
+    s->s3->tmp.new_compression = NULL;
+#else
+    s->s3->tmp.new_compression = comp;
+#endif
+
+    num = EVP_MD_size(hash);
+    if (num < 0)
+        return 0;
+
+    num = EVP_CIPHER_key_length(c) + num + EVP_CIPHER_iv_length(c);
+    num *= 2;
+
+    ssl3_cleanup_key_block(s);
+
+    if ((p = OPENSSL_malloc(num)) == NULL)
+        goto err;
+
+    s->s3->tmp.key_block_length = num;
+    s->s3->tmp.key_block = p;
+
+    ret = ssl3_generate_key_block(s, p, num);
+
+    if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) {
+        /*
+         * enable vulnerability countermeasure for CBC ciphers with known-IV
+         * problem (http://www.openssl.org/~bodo/tls-cbc.txt)
+         */
+        s->s3->need_empty_fragments = 1;
+
+        if (s->session->cipher != NULL) {
+            if (s->session->cipher->algorithm_enc == SSL_eNULL)
+                s->s3->need_empty_fragments = 0;
+
+#ifndef OPENSSL_NO_RC4
+            if (s->session->cipher->algorithm_enc == SSL_RC4)
+                s->s3->need_empty_fragments = 0;
+#endif
+        }
+    }
+
+    return ret;
+
+ err:
+    SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE);
+    return (0);
+}
+
+void ssl3_cleanup_key_block(SSL *s)
+{
+    OPENSSL_clear_free(s->s3->tmp.key_block, s->s3->tmp.key_block_length);
+    s->s3->tmp.key_block = NULL;
+    s->s3->tmp.key_block_length = 0;
+}
+
+int ssl3_init_finished_mac(SSL *s)
+{
+    BIO *buf = BIO_new(BIO_s_mem());
+
+    if (buf == NULL) {
+        SSLerr(SSL_F_SSL3_INIT_FINISHED_MAC, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    ssl3_free_digest_list(s);
+    s->s3->handshake_buffer = buf;
+    (void)BIO_set_close(s->s3->handshake_buffer, BIO_CLOSE);
+    return 1;
+}
+
+/*
+ * Free digest list. Also frees handshake buffer since they are always freed
+ * together.
+ */
+
+void ssl3_free_digest_list(SSL *s)
+{
+    BIO_free(s->s3->handshake_buffer);
+    s->s3->handshake_buffer = NULL;
+    EVP_MD_CTX_free(s->s3->handshake_dgst);
+    s->s3->handshake_dgst = NULL;
+}
+
+int ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
+{
+    if (s->s3->handshake_dgst == NULL)
+        /* Note: this writes to a memory BIO so a failure is a fatal error */
+        return BIO_write(s->s3->handshake_buffer, (void *)buf, len) == len;
+    else
+        return EVP_DigestUpdate(s->s3->handshake_dgst, buf, len);
+}
+
+int ssl3_digest_cached_records(SSL *s, int keep)
+{
+    const EVP_MD *md;
+    long hdatalen;
+    void *hdata;
+
+    if (s->s3->handshake_dgst == NULL) {
+        hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
+        if (hdatalen <= 0) {
+            SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS,
+                   SSL_R_BAD_HANDSHAKE_LENGTH);
+            return 0;
+        }
+
+        s->s3->handshake_dgst = EVP_MD_CTX_new();
+        if (s->s3->handshake_dgst == NULL) {
+            SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+
+        md = ssl_handshake_md(s);
+        if (md == NULL || !EVP_DigestInit_ex(s->s3->handshake_dgst, md, NULL)
+            || !EVP_DigestUpdate(s->s3->handshake_dgst, hdata, hdatalen)) {
+            SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+    }
+    if (keep == 0) {
+        BIO_free(s->s3->handshake_buffer);
+        s->s3->handshake_buffer = NULL;
+    }
+
+    return 1;
+}
+
+int ssl3_final_finish_mac(SSL *s, const char *sender, int len, unsigned char *p)
+{
+    int ret;
+    EVP_MD_CTX *ctx = NULL;
+
+    if (!ssl3_digest_cached_records(s, 0))
+        return 0;
+
+    if (EVP_MD_CTX_type(s->s3->handshake_dgst) != NID_md5_sha1) {
+        SSLerr(SSL_F_SSL3_FINAL_FINISH_MAC, SSL_R_NO_REQUIRED_DIGEST);
+        return 0;
+    }
+
+    ctx = EVP_MD_CTX_new();
+    if (ctx == NULL) {
+        SSLerr(SSL_F_SSL3_FINAL_FINISH_MAC, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    if (!EVP_MD_CTX_copy_ex(ctx, s->s3->handshake_dgst)) {
+        SSLerr(SSL_F_SSL3_FINAL_FINISH_MAC, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    ret = EVP_MD_CTX_size(ctx);
+    if (ret < 0) {
+        EVP_MD_CTX_reset(ctx);
+        return 0;
+    }
+
+    if ((sender != NULL && EVP_DigestUpdate(ctx, sender, len) <= 0)
+        || EVP_MD_CTX_ctrl(ctx, EVP_CTRL_SSL3_MASTER_SECRET,
+                           s->session->master_key_length,
+                           s->session->master_key) <= 0
+        || EVP_DigestFinal_ex(ctx, p, NULL) <= 0) {
+        SSLerr(SSL_F_SSL3_FINAL_FINISH_MAC, ERR_R_INTERNAL_ERROR);
+        ret = 0;
+    }
+
+    EVP_MD_CTX_free(ctx);
+
+    return ret;
+}
+
+int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
+                                int len)
+{
+    static const unsigned char *salt[3] = {
+#ifndef CHARSET_EBCDIC
+        (const unsigned char *)"A",
+        (const unsigned char *)"BB",
+        (const unsigned char *)"CCC",
+#else
+        (const unsigned char *)"\x41",
+        (const unsigned char *)"\x42\x42",
+        (const unsigned char *)"\x43\x43\x43",
+#endif
+    };
+    unsigned char buf[EVP_MAX_MD_SIZE];
+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+    int i, ret = 0;
+    unsigned int n;
+#ifdef OPENSSL_SSL_TRACE_CRYPTO
+    unsigned char *tmpout = out;
+#endif
+
+    if (ctx == NULL) {
+        SSLerr(SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    for (i = 0; i < 3; i++) {
+        if (EVP_DigestInit_ex(ctx, s->ctx->sha1, NULL) <= 0
+            || EVP_DigestUpdate(ctx, salt[i],
+                                strlen((const char *)salt[i])) <= 0
+            || EVP_DigestUpdate(ctx, p, len) <= 0
+            || EVP_DigestUpdate(ctx, &(s->s3->client_random[0]),
+                                SSL3_RANDOM_SIZE) <= 0
+            || EVP_DigestUpdate(ctx, &(s->s3->server_random[0]),
+                                SSL3_RANDOM_SIZE) <= 0
+            || EVP_DigestFinal_ex(ctx, buf, &n) <= 0
+            || EVP_DigestInit_ex(ctx, s->ctx->md5, NULL) <= 0
+            || EVP_DigestUpdate(ctx, p, len) <= 0
+            || EVP_DigestUpdate(ctx, buf, n) <= 0
+            || EVP_DigestFinal_ex(ctx, out, &n) <= 0) {
+            SSLerr(SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_INTERNAL_ERROR);
+            ret = 0;
+            break;
+        }
+        out += n;
+        ret += n;
+    }
+    EVP_MD_CTX_free(ctx);
+
+#ifdef OPENSSL_SSL_TRACE_CRYPTO
+    if (ret > 0 && s->msg_callback) {
+        s->msg_callback(2, s->version, TLS1_RT_CRYPTO_PREMASTER,
+                        p, len, s, s->msg_callback_arg);
+        s->msg_callback(2, s->version, TLS1_RT_CRYPTO_CLIENT_RANDOM,
+                        s->s3->client_random, SSL3_RANDOM_SIZE,
+                        s, s->msg_callback_arg);
+        s->msg_callback(2, s->version, TLS1_RT_CRYPTO_SERVER_RANDOM,
+                        s->s3->server_random, SSL3_RANDOM_SIZE,
+                        s, s->msg_callback_arg);
+        s->msg_callback(2, s->version, TLS1_RT_CRYPTO_MASTER,
+                        tmpout, SSL3_MASTER_SECRET_SIZE,
+                        s, s->msg_callback_arg);
+    }
+#endif
+    OPENSSL_cleanse(buf, sizeof(buf));
+    return (ret);
+}
+
+int ssl3_alert_code(int code)
+{
+    switch (code) {
+    case SSL_AD_CLOSE_NOTIFY:
+        return (SSL3_AD_CLOSE_NOTIFY);
+    case SSL_AD_UNEXPECTED_MESSAGE:
+        return (SSL3_AD_UNEXPECTED_MESSAGE);
+    case SSL_AD_BAD_RECORD_MAC:
+        return (SSL3_AD_BAD_RECORD_MAC);
+    case SSL_AD_DECRYPTION_FAILED:
+        return (SSL3_AD_BAD_RECORD_MAC);
+    case SSL_AD_RECORD_OVERFLOW:
+        return (SSL3_AD_BAD_RECORD_MAC);
+    case SSL_AD_DECOMPRESSION_FAILURE:
+        return (SSL3_AD_DECOMPRESSION_FAILURE);
+    case SSL_AD_HANDSHAKE_FAILURE:
+        return (SSL3_AD_HANDSHAKE_FAILURE);
+    case SSL_AD_NO_CERTIFICATE:
+        return (SSL3_AD_NO_CERTIFICATE);
+    case SSL_AD_BAD_CERTIFICATE:
+        return (SSL3_AD_BAD_CERTIFICATE);
+    case SSL_AD_UNSUPPORTED_CERTIFICATE:
+        return (SSL3_AD_UNSUPPORTED_CERTIFICATE);
+    case SSL_AD_CERTIFICATE_REVOKED:
+        return (SSL3_AD_CERTIFICATE_REVOKED);
+    case SSL_AD_CERTIFICATE_EXPIRED:
+        return (SSL3_AD_CERTIFICATE_EXPIRED);
+    case SSL_AD_CERTIFICATE_UNKNOWN:
+        return (SSL3_AD_CERTIFICATE_UNKNOWN);
+    case SSL_AD_ILLEGAL_PARAMETER:
+        return (SSL3_AD_ILLEGAL_PARAMETER);
+    case SSL_AD_UNKNOWN_CA:
+        return (SSL3_AD_BAD_CERTIFICATE);
+    case SSL_AD_ACCESS_DENIED:
+        return (SSL3_AD_HANDSHAKE_FAILURE);
+    case SSL_AD_DECODE_ERROR:
+        return (SSL3_AD_HANDSHAKE_FAILURE);
+    case SSL_AD_DECRYPT_ERROR:
+        return (SSL3_AD_HANDSHAKE_FAILURE);
+    case SSL_AD_EXPORT_RESTRICTION:
+        return (SSL3_AD_HANDSHAKE_FAILURE);
+    case SSL_AD_PROTOCOL_VERSION:
+        return (SSL3_AD_HANDSHAKE_FAILURE);
+    case SSL_AD_INSUFFICIENT_SECURITY:
+        return (SSL3_AD_HANDSHAKE_FAILURE);
+    case SSL_AD_INTERNAL_ERROR:
+        return (SSL3_AD_HANDSHAKE_FAILURE);
+    case SSL_AD_USER_CANCELLED:
+        return (SSL3_AD_HANDSHAKE_FAILURE);
+    case SSL_AD_NO_RENEGOTIATION:
+        return (-1);            /* Don't send it :-) */
+    case SSL_AD_UNSUPPORTED_EXTENSION:
+        return (SSL3_AD_HANDSHAKE_FAILURE);
+    case SSL_AD_CERTIFICATE_UNOBTAINABLE:
+        return (SSL3_AD_HANDSHAKE_FAILURE);
+    case SSL_AD_UNRECOGNIZED_NAME:
+        return (SSL3_AD_HANDSHAKE_FAILURE);
+    case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
+        return (SSL3_AD_HANDSHAKE_FAILURE);
+    case SSL_AD_BAD_CERTIFICATE_HASH_VALUE:
+        return (SSL3_AD_HANDSHAKE_FAILURE);
+    case SSL_AD_UNKNOWN_PSK_IDENTITY:
+        return (TLS1_AD_UNKNOWN_PSK_IDENTITY);
+    case SSL_AD_INAPPROPRIATE_FALLBACK:
+        return (TLS1_AD_INAPPROPRIATE_FALLBACK);
+    case SSL_AD_NO_APPLICATION_PROTOCOL:
+        return (TLS1_AD_NO_APPLICATION_PROTOCOL);
+    default:
+        return (-1);
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/s3_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/s3_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/s3_lib.c	(revision 331)
@@ -0,0 +1,4121 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * ECC cipher suite support in OpenSSL originally written by
+ * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <stdio.h>
+#include <openssl/objects.h>
+#include "ssl_locl.h"
+#include <openssl/md5.h>
+#include <openssl/dh.h>
+#include <openssl/rand.h>
+
+#define SSL3_NUM_CIPHERS        OSSL_NELEM(ssl3_ciphers)
+
+/*
+ * The list of available ciphers, mostly organized into the following
+ * groups:
+ *      Always there
+ *      EC
+ *      PSK
+ *      SRP (within that: RSA EC PSK)
+ *      Cipher families: Chacha/poly, Camellila, Gost, IDEA, SEED
+ *      Weak ciphers
+ */
+static SSL_CIPHER ssl3_ciphers[] = {
+    {
+     1,
+     SSL3_TXT_RSA_NULL_MD5,
+     SSL3_CK_RSA_NULL_MD5,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_eNULL,
+     SSL_MD5,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_STRONG_NONE,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     0,
+     0,
+     },
+    {
+     1,
+     SSL3_TXT_RSA_NULL_SHA,
+     SSL3_CK_RSA_NULL_SHA,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_eNULL,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_STRONG_NONE | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     0,
+     0,
+     },
+#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
+    {
+     1,
+     SSL3_TXT_RSA_DES_192_CBC3_SHA,
+     SSL3_CK_RSA_DES_192_CBC3_SHA,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_3DES,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_MEDIUM | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     112,
+     168,
+     },
+    {
+     1,
+     SSL3_TXT_DHE_DSS_DES_192_CBC3_SHA,
+     SSL3_CK_DHE_DSS_DES_192_CBC3_SHA,
+     SSL_kDHE,
+     SSL_aDSS,
+     SSL_3DES,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_MEDIUM | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     112,
+     168,
+     },
+    {
+     1,
+     SSL3_TXT_DHE_RSA_DES_192_CBC3_SHA,
+     SSL3_CK_DHE_RSA_DES_192_CBC3_SHA,
+     SSL_kDHE,
+     SSL_aRSA,
+     SSL_3DES,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_MEDIUM | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     112,
+     168,
+     },
+    {
+     1,
+     SSL3_TXT_ADH_DES_192_CBC_SHA,
+     SSL3_CK_ADH_DES_192_CBC_SHA,
+     SSL_kDHE,
+     SSL_aNULL,
+     SSL_3DES,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_MEDIUM | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     112,
+     168,
+     },
+#endif
+    {
+     1,
+     TLS1_TXT_RSA_WITH_AES_128_SHA,
+     TLS1_CK_RSA_WITH_AES_128_SHA,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_AES128,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_DSS_WITH_AES_128_SHA,
+     TLS1_CK_DHE_DSS_WITH_AES_128_SHA,
+     SSL_kDHE,
+     SSL_aDSS,
+     SSL_AES128,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_RSA_WITH_AES_128_SHA,
+     TLS1_CK_DHE_RSA_WITH_AES_128_SHA,
+     SSL_kDHE,
+     SSL_aRSA,
+     SSL_AES128,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ADH_WITH_AES_128_SHA,
+     TLS1_CK_ADH_WITH_AES_128_SHA,
+     SSL_kDHE,
+     SSL_aNULL,
+     SSL_AES128,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_WITH_AES_256_SHA,
+     TLS1_CK_RSA_WITH_AES_256_SHA,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_AES256,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_DSS_WITH_AES_256_SHA,
+     TLS1_CK_DHE_DSS_WITH_AES_256_SHA,
+     SSL_kDHE,
+     SSL_aDSS,
+     SSL_AES256,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_RSA_WITH_AES_256_SHA,
+     TLS1_CK_DHE_RSA_WITH_AES_256_SHA,
+     SSL_kDHE,
+     SSL_aRSA,
+     SSL_AES256,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_ADH_WITH_AES_256_SHA,
+     TLS1_CK_ADH_WITH_AES_256_SHA,
+     SSL_kDHE,
+     SSL_aNULL,
+     SSL_AES256,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_WITH_NULL_SHA256,
+     TLS1_CK_RSA_WITH_NULL_SHA256,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_eNULL,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_STRONG_NONE | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     0,
+     0,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_WITH_AES_128_SHA256,
+     TLS1_CK_RSA_WITH_AES_128_SHA256,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_AES128,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_WITH_AES_256_SHA256,
+     TLS1_CK_RSA_WITH_AES_256_SHA256,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_AES256,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256,
+     TLS1_CK_DHE_DSS_WITH_AES_128_SHA256,
+     SSL_kDHE,
+     SSL_aDSS,
+     SSL_AES128,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256,
+     TLS1_CK_DHE_RSA_WITH_AES_128_SHA256,
+     SSL_kDHE,
+     SSL_aRSA,
+     SSL_AES128,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256,
+     TLS1_CK_DHE_DSS_WITH_AES_256_SHA256,
+     SSL_kDHE,
+     SSL_aDSS,
+     SSL_AES256,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256,
+     TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
+     SSL_kDHE,
+     SSL_aRSA,
+     SSL_AES256,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_ADH_WITH_AES_128_SHA256,
+     TLS1_CK_ADH_WITH_AES_128_SHA256,
+     SSL_kDHE,
+     SSL_aNULL,
+     SSL_AES128,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ADH_WITH_AES_256_SHA256,
+     TLS1_CK_ADH_WITH_AES_256_SHA256,
+     SSL_kDHE,
+     SSL_aNULL,
+     SSL_AES256,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256,
+     TLS1_CK_RSA_WITH_AES_128_GCM_SHA256,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_AES128GCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384,
+     TLS1_CK_RSA_WITH_AES_256_GCM_SHA384,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_AES256GCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256,
+     TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256,
+     SSL_kDHE,
+     SSL_aRSA,
+     SSL_AES128GCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384,
+     TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384,
+     SSL_kDHE,
+     SSL_aRSA,
+     SSL_AES256GCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256,
+     TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256,
+     SSL_kDHE,
+     SSL_aDSS,
+     SSL_AES128GCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384,
+     TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384,
+     SSL_kDHE,
+     SSL_aDSS,
+     SSL_AES256GCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256,
+     TLS1_CK_ADH_WITH_AES_128_GCM_SHA256,
+     SSL_kDHE,
+     SSL_aNULL,
+     SSL_AES128GCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384,
+     TLS1_CK_ADH_WITH_AES_256_GCM_SHA384,
+     SSL_kDHE,
+     SSL_aNULL,
+     SSL_AES256GCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_WITH_AES_128_CCM,
+     TLS1_CK_RSA_WITH_AES_128_CCM,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_AES128CCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_WITH_AES_256_CCM,
+     TLS1_CK_RSA_WITH_AES_256_CCM,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_AES256CCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_RSA_WITH_AES_128_CCM,
+     TLS1_CK_DHE_RSA_WITH_AES_128_CCM,
+     SSL_kDHE,
+     SSL_aRSA,
+     SSL_AES128CCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_RSA_WITH_AES_256_CCM,
+     TLS1_CK_DHE_RSA_WITH_AES_256_CCM,
+     SSL_kDHE,
+     SSL_aRSA,
+     SSL_AES256CCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_WITH_AES_128_CCM_8,
+     TLS1_CK_RSA_WITH_AES_128_CCM_8,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_AES128CCM8,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_WITH_AES_256_CCM_8,
+     TLS1_CK_RSA_WITH_AES_256_CCM_8,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_AES256CCM8,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_RSA_WITH_AES_128_CCM_8,
+     TLS1_CK_DHE_RSA_WITH_AES_128_CCM_8,
+     SSL_kDHE,
+     SSL_aRSA,
+     SSL_AES128CCM8,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_RSA_WITH_AES_256_CCM_8,
+     TLS1_CK_DHE_RSA_WITH_AES_256_CCM_8,
+     SSL_kDHE,
+     SSL_aRSA,
+     SSL_AES256CCM8,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_PSK_WITH_AES_128_CCM,
+     TLS1_CK_PSK_WITH_AES_128_CCM,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_AES128CCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_PSK_WITH_AES_256_CCM,
+     TLS1_CK_PSK_WITH_AES_256_CCM,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_AES256CCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_PSK_WITH_AES_128_CCM,
+     TLS1_CK_DHE_PSK_WITH_AES_128_CCM,
+     SSL_kDHEPSK,
+     SSL_aPSK,
+     SSL_AES128CCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_PSK_WITH_AES_256_CCM,
+     TLS1_CK_DHE_PSK_WITH_AES_256_CCM,
+     SSL_kDHEPSK,
+     SSL_aPSK,
+     SSL_AES256CCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_PSK_WITH_AES_128_CCM_8,
+     TLS1_CK_PSK_WITH_AES_128_CCM_8,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_AES128CCM8,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_PSK_WITH_AES_256_CCM_8,
+     TLS1_CK_PSK_WITH_AES_256_CCM_8,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_AES256CCM8,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_PSK_WITH_AES_128_CCM_8,
+     TLS1_CK_DHE_PSK_WITH_AES_128_CCM_8,
+     SSL_kDHEPSK,
+     SSL_aPSK,
+     SSL_AES128CCM8,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_PSK_WITH_AES_256_CCM_8,
+     TLS1_CK_DHE_PSK_WITH_AES_256_CCM_8,
+     SSL_kDHEPSK,
+     SSL_aPSK,
+     SSL_AES256CCM8,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CCM,
+     TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CCM,
+     SSL_kECDHE,
+     SSL_aECDSA,
+     SSL_AES128CCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CCM,
+     TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CCM,
+     SSL_kECDHE,
+     SSL_aECDSA,
+     SSL_AES256CCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CCM_8,
+     TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CCM_8,
+     SSL_kECDHE,
+     SSL_aECDSA,
+     SSL_AES128CCM8,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CCM_8,
+     TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CCM_8,
+     SSL_kECDHE,
+     SSL_aECDSA,
+     SSL_AES256CCM8,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+
+#ifndef OPENSSL_NO_EC
+    {
+     1,
+     TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA,
+     TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA,
+     SSL_kECDHE,
+     SSL_aECDSA,
+     SSL_eNULL,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_STRONG_NONE | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     0,
+     0,
+     },
+# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
+    {
+     1,
+     TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA,
+     TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA,
+     SSL_kECDHE,
+     SSL_aECDSA,
+     SSL_3DES,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_MEDIUM | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     112,
+     168,
+     },
+# endif
+    {
+     1,
+     TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+     TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+     SSL_kECDHE,
+     SSL_aECDSA,
+     SSL_AES128,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+     TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+     SSL_kECDHE,
+     SSL_aECDSA,
+     SSL_AES256,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA,
+     TLS1_CK_ECDHE_RSA_WITH_NULL_SHA,
+     SSL_kECDHE,
+     SSL_aRSA,
+     SSL_eNULL,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_STRONG_NONE | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     0,
+     0,
+     },
+# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
+    {
+     1,
+     TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA,
+     TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA,
+     SSL_kECDHE,
+     SSL_aRSA,
+     SSL_3DES,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_MEDIUM | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     112,
+     168,
+     },
+# endif
+    {
+     1,
+     TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+     TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+     SSL_kECDHE,
+     SSL_aRSA,
+     SSL_AES128,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+     TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+     SSL_kECDHE,
+     SSL_aRSA,
+     SSL_AES256,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_ECDH_anon_WITH_NULL_SHA,
+     TLS1_CK_ECDH_anon_WITH_NULL_SHA,
+     SSL_kECDHE,
+     SSL_aNULL,
+     SSL_eNULL,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_STRONG_NONE | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     0,
+     0,
+     },
+# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
+    {
+     1,
+     TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA,
+     TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA,
+     SSL_kECDHE,
+     SSL_aNULL,
+     SSL_3DES,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_MEDIUM | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     112,
+     168,
+     },
+# endif
+    {
+     1,
+     TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA,
+     TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA,
+     SSL_kECDHE,
+     SSL_aNULL,
+     SSL_AES128,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA,
+     TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA,
+     SSL_kECDHE,
+     SSL_aNULL,
+     SSL_AES256,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256,
+     TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256,
+     SSL_kECDHE,
+     SSL_aECDSA,
+     SSL_AES128,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384,
+     TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384,
+     SSL_kECDHE,
+     SSL_aECDSA,
+     SSL_AES256,
+     SSL_SHA384,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256,
+     TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
+     SSL_kECDHE,
+     SSL_aRSA,
+     SSL_AES128,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384,
+     TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
+     SSL_kECDHE,
+     SSL_aRSA,
+     SSL_AES256,
+     SSL_SHA384,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+     TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+     SSL_kECDHE,
+     SSL_aECDSA,
+     SSL_AES128GCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+     TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+     SSL_kECDHE,
+     SSL_aECDSA,
+     SSL_AES256GCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+     TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+     SSL_kECDHE,
+     SSL_aRSA,
+     SSL_AES128GCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+     TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+     SSL_kECDHE,
+     SSL_aRSA,
+     SSL_AES256GCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+#endif                          /* OPENSSL_NO_EC */
+
+#ifndef OPENSSL_NO_PSK
+    {
+     1,
+     TLS1_TXT_PSK_WITH_NULL_SHA,
+     TLS1_CK_PSK_WITH_NULL_SHA,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_eNULL,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_STRONG_NONE | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     0,
+     0,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_PSK_WITH_NULL_SHA,
+     TLS1_CK_DHE_PSK_WITH_NULL_SHA,
+     SSL_kDHEPSK,
+     SSL_aPSK,
+     SSL_eNULL,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_STRONG_NONE | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     0,
+     0,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_PSK_WITH_NULL_SHA,
+     TLS1_CK_RSA_PSK_WITH_NULL_SHA,
+     SSL_kRSAPSK,
+     SSL_aRSA,
+     SSL_eNULL,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_STRONG_NONE | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     0,
+     0,
+     },
+# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
+    {
+     1,
+     TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA,
+     TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_3DES,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_MEDIUM | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     112,
+     168,
+     },
+# endif
+    {
+     1,
+     TLS1_TXT_PSK_WITH_AES_128_CBC_SHA,
+     TLS1_CK_PSK_WITH_AES_128_CBC_SHA,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_AES128,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_PSK_WITH_AES_256_CBC_SHA,
+     TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_AES256,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
+    {
+     1,
+     TLS1_TXT_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
+     TLS1_CK_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
+     SSL_kDHEPSK,
+     SSL_aPSK,
+     SSL_3DES,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_MEDIUM | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     112,
+     168,
+     },
+# endif
+    {
+     1,
+     TLS1_TXT_DHE_PSK_WITH_AES_128_CBC_SHA,
+     TLS1_CK_DHE_PSK_WITH_AES_128_CBC_SHA,
+     SSL_kDHEPSK,
+     SSL_aPSK,
+     SSL_AES128,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_PSK_WITH_AES_256_CBC_SHA,
+     TLS1_CK_DHE_PSK_WITH_AES_256_CBC_SHA,
+     SSL_kDHEPSK,
+     SSL_aPSK,
+     SSL_AES256,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
+    {
+     1,
+     TLS1_TXT_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
+     TLS1_CK_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
+     SSL_kRSAPSK,
+     SSL_aRSA,
+     SSL_3DES,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_MEDIUM | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     112,
+     168,
+     },
+# endif
+    {
+     1,
+     TLS1_TXT_RSA_PSK_WITH_AES_128_CBC_SHA,
+     TLS1_CK_RSA_PSK_WITH_AES_128_CBC_SHA,
+     SSL_kRSAPSK,
+     SSL_aRSA,
+     SSL_AES128,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_PSK_WITH_AES_256_CBC_SHA,
+     TLS1_CK_RSA_PSK_WITH_AES_256_CBC_SHA,
+     SSL_kRSAPSK,
+     SSL_aRSA,
+     SSL_AES256,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_PSK_WITH_AES_128_GCM_SHA256,
+     TLS1_CK_PSK_WITH_AES_128_GCM_SHA256,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_AES128GCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_PSK_WITH_AES_256_GCM_SHA384,
+     TLS1_CK_PSK_WITH_AES_256_GCM_SHA384,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_AES256GCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_PSK_WITH_AES_128_GCM_SHA256,
+     TLS1_CK_DHE_PSK_WITH_AES_128_GCM_SHA256,
+     SSL_kDHEPSK,
+     SSL_aPSK,
+     SSL_AES128GCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_PSK_WITH_AES_256_GCM_SHA384,
+     TLS1_CK_DHE_PSK_WITH_AES_256_GCM_SHA384,
+     SSL_kDHEPSK,
+     SSL_aPSK,
+     SSL_AES256GCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_PSK_WITH_AES_128_GCM_SHA256,
+     TLS1_CK_RSA_PSK_WITH_AES_128_GCM_SHA256,
+     SSL_kRSAPSK,
+     SSL_aRSA,
+     SSL_AES128GCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_PSK_WITH_AES_256_GCM_SHA384,
+     TLS1_CK_RSA_PSK_WITH_AES_256_GCM_SHA384,
+     SSL_kRSAPSK,
+     SSL_aRSA,
+     SSL_AES256GCM,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_PSK_WITH_AES_128_CBC_SHA256,
+     TLS1_CK_PSK_WITH_AES_128_CBC_SHA256,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_AES128,
+     SSL_SHA256,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_PSK_WITH_AES_256_CBC_SHA384,
+     TLS1_CK_PSK_WITH_AES_256_CBC_SHA384,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_AES256,
+     SSL_SHA384,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_PSK_WITH_NULL_SHA256,
+     TLS1_CK_PSK_WITH_NULL_SHA256,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_eNULL,
+     SSL_SHA256,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_STRONG_NONE | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     0,
+     0,
+     },
+    {
+     1,
+     TLS1_TXT_PSK_WITH_NULL_SHA384,
+     TLS1_CK_PSK_WITH_NULL_SHA384,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_eNULL,
+     SSL_SHA384,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_STRONG_NONE | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     0,
+     0,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_PSK_WITH_AES_128_CBC_SHA256,
+     TLS1_CK_DHE_PSK_WITH_AES_128_CBC_SHA256,
+     SSL_kDHEPSK,
+     SSL_aPSK,
+     SSL_AES128,
+     SSL_SHA256,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_PSK_WITH_AES_256_CBC_SHA384,
+     TLS1_CK_DHE_PSK_WITH_AES_256_CBC_SHA384,
+     SSL_kDHEPSK,
+     SSL_aPSK,
+     SSL_AES256,
+     SSL_SHA384,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_PSK_WITH_NULL_SHA256,
+     TLS1_CK_DHE_PSK_WITH_NULL_SHA256,
+     SSL_kDHEPSK,
+     SSL_aPSK,
+     SSL_eNULL,
+     SSL_SHA256,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_STRONG_NONE | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     0,
+     0,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_PSK_WITH_NULL_SHA384,
+     TLS1_CK_DHE_PSK_WITH_NULL_SHA384,
+     SSL_kDHEPSK,
+     SSL_aPSK,
+     SSL_eNULL,
+     SSL_SHA384,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_STRONG_NONE | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     0,
+     0,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_PSK_WITH_AES_128_CBC_SHA256,
+     TLS1_CK_RSA_PSK_WITH_AES_128_CBC_SHA256,
+     SSL_kRSAPSK,
+     SSL_aRSA,
+     SSL_AES128,
+     SSL_SHA256,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_PSK_WITH_AES_256_CBC_SHA384,
+     TLS1_CK_RSA_PSK_WITH_AES_256_CBC_SHA384,
+     SSL_kRSAPSK,
+     SSL_aRSA,
+     SSL_AES256,
+     SSL_SHA384,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_PSK_WITH_NULL_SHA256,
+     TLS1_CK_RSA_PSK_WITH_NULL_SHA256,
+     SSL_kRSAPSK,
+     SSL_aRSA,
+     SSL_eNULL,
+     SSL_SHA256,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_STRONG_NONE | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     0,
+     0,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_PSK_WITH_NULL_SHA384,
+     TLS1_CK_RSA_PSK_WITH_NULL_SHA384,
+     SSL_kRSAPSK,
+     SSL_aRSA,
+     SSL_eNULL,
+     SSL_SHA384,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_STRONG_NONE | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     0,
+     0,
+     },
+# ifndef OPENSSL_NO_EC
+#  ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
+    {
+     1,
+     TLS1_TXT_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
+     TLS1_CK_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
+     SSL_kECDHEPSK,
+     SSL_aPSK,
+     SSL_3DES,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_MEDIUM | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     112,
+     168,
+     },
+#  endif
+    {
+     1,
+     TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA,
+     TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
+     SSL_kECDHEPSK,
+     SSL_aPSK,
+     SSL_AES128,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA,
+     TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA,
+     SSL_kECDHEPSK,
+     SSL_aPSK,
+     SSL_AES256,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
+     TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
+     SSL_kECDHEPSK,
+     SSL_aPSK,
+     SSL_AES128,
+     SSL_SHA256,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
+     TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
+     SSL_kECDHEPSK,
+     SSL_aPSK,
+     SSL_AES256,
+     SSL_SHA384,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_PSK_WITH_NULL_SHA,
+     TLS1_CK_ECDHE_PSK_WITH_NULL_SHA,
+     SSL_kECDHEPSK,
+     SSL_aPSK,
+     SSL_eNULL,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_STRONG_NONE | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     0,
+     0,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_PSK_WITH_NULL_SHA256,
+     TLS1_CK_ECDHE_PSK_WITH_NULL_SHA256,
+     SSL_kECDHEPSK,
+     SSL_aPSK,
+     SSL_eNULL,
+     SSL_SHA256,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_STRONG_NONE | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     0,
+     0,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_PSK_WITH_NULL_SHA384,
+     TLS1_CK_ECDHE_PSK_WITH_NULL_SHA384,
+     SSL_kECDHEPSK,
+     SSL_aPSK,
+     SSL_eNULL,
+     SSL_SHA384,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_STRONG_NONE | SSL_FIPS,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     0,
+     0,
+     },
+# endif                         /* OPENSSL_NO_EC */
+#endif                          /* OPENSSL_NO_PSK */
+
+#ifndef OPENSSL_NO_SRP
+# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
+    {
+     1,
+     TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
+     TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
+     SSL_kSRP,
+     SSL_aSRP,
+     SSL_3DES,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     112,
+     168,
+     },
+    {
+     1,
+     TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
+     TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
+     SSL_kSRP,
+     SSL_aRSA,
+     SSL_3DES,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     112,
+     168,
+     },
+    {
+     1,
+     TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
+     TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
+     SSL_kSRP,
+     SSL_aDSS,
+     SSL_3DES,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     112,
+     168,
+     },
+# endif
+    {
+     1,
+     TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA,
+     TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA,
+     SSL_kSRP,
+     SSL_aSRP,
+     SSL_AES128,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
+     TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
+     SSL_kSRP,
+     SSL_aRSA,
+     SSL_AES128,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
+     TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
+     SSL_kSRP,
+     SSL_aDSS,
+     SSL_AES128,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA,
+     TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA,
+     SSL_kSRP,
+     SSL_aSRP,
+     SSL_AES256,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
+     TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
+     SSL_kSRP,
+     SSL_aRSA,
+     SSL_AES256,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_HIGH,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
+     TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
+     SSL_kSRP,
+     SSL_aDSS,
+     SSL_AES256,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+#endif                          /* OPENSSL_NO_SRP */
+
+#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
+# ifndef OPENSSL_NO_RSA
+    {
+     1,
+     TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305,
+     TLS1_CK_DHE_RSA_WITH_CHACHA20_POLY1305,
+     SSL_kDHE,
+     SSL_aRSA,
+     SSL_CHACHA20POLY1305,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+# endif                         /* OPENSSL_NO_RSA */
+
+# ifndef OPENSSL_NO_EC
+    {
+     1,
+     TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+     TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+     SSL_kECDHE,
+     SSL_aRSA,
+     SSL_CHACHA20POLY1305,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
+     TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
+     SSL_kECDHE,
+     SSL_aECDSA,
+     SSL_CHACHA20POLY1305,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+# endif                         /* OPENSSL_NO_EC */
+
+# ifndef OPENSSL_NO_PSK
+    {
+     1,
+     TLS1_TXT_PSK_WITH_CHACHA20_POLY1305,
+     TLS1_CK_PSK_WITH_CHACHA20_POLY1305,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_CHACHA20POLY1305,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_PSK_WITH_CHACHA20_POLY1305,
+     TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305,
+     SSL_kECDHEPSK,
+     SSL_aPSK,
+     SSL_CHACHA20POLY1305,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_PSK_WITH_CHACHA20_POLY1305,
+     TLS1_CK_DHE_PSK_WITH_CHACHA20_POLY1305,
+     SSL_kDHEPSK,
+     SSL_aPSK,
+     SSL_CHACHA20POLY1305,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_PSK_WITH_CHACHA20_POLY1305,
+     TLS1_CK_RSA_PSK_WITH_CHACHA20_POLY1305,
+     SSL_kRSAPSK,
+     SSL_aRSA,
+     SSL_CHACHA20POLY1305,
+     SSL_AEAD,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+# endif                         /* OPENSSL_NO_PSK */
+#endif                          /* !defined(OPENSSL_NO_CHACHA) &&
+                                 * !defined(OPENSSL_NO_POLY1305) */
+
+#ifndef OPENSSL_NO_CAMELLIA
+    {
+     1,
+     TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA256,
+     TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA256,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_CAMELLIA128,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256,
+     TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256,
+     SSL_kEDH,
+     SSL_aDSS,
+     SSL_CAMELLIA128,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
+     TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
+     SSL_kEDH,
+     SSL_aRSA,
+     SSL_CAMELLIA128,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA256,
+     TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA256,
+     SSL_kEDH,
+     SSL_aNULL,
+     SSL_CAMELLIA128,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA256,
+     TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA256,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_CAMELLIA256,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256,
+     TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256,
+     SSL_kEDH,
+     SSL_aDSS,
+     SSL_CAMELLIA256,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
+     TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
+     SSL_kEDH,
+     SSL_aRSA,
+     SSL_CAMELLIA256,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA256,
+     TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA256,
+     SSL_kEDH,
+     SSL_aNULL,
+     SSL_CAMELLIA256,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA,
+     TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_CAMELLIA256,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
+     TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
+     SSL_kDHE,
+     SSL_aDSS,
+     SSL_CAMELLIA256,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
+     TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
+     SSL_kDHE,
+     SSL_aRSA,
+     SSL_CAMELLIA256,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA,
+     TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA,
+     SSL_kDHE,
+     SSL_aNULL,
+     SSL_CAMELLIA256,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA,
+     TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_CAMELLIA128,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
+     TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
+     SSL_kDHE,
+     SSL_aDSS,
+     SSL_CAMELLIA128,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
+     TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
+     SSL_kDHE,
+     SSL_aRSA,
+     SSL_CAMELLIA128,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA,
+     TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA,
+     SSL_kDHE,
+     SSL_aNULL,
+     SSL_CAMELLIA128,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+
+# ifndef OPENSSL_NO_EC
+    {
+     1,
+     TLS1_TXT_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
+     TLS1_CK_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
+     SSL_kECDHE,
+     SSL_aECDSA,
+     SSL_CAMELLIA128,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
+     TLS1_CK_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
+     SSL_kECDHE,
+     SSL_aECDSA,
+     SSL_CAMELLIA256,
+     SSL_SHA384,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
+     TLS1_CK_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
+     SSL_kECDHE,
+     SSL_aRSA,
+     SSL_CAMELLIA128,
+     SSL_SHA256,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,
+     TLS1_CK_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,
+     SSL_kECDHE,
+     SSL_aRSA,
+     SSL_CAMELLIA256,
+     SSL_SHA384,
+     TLS1_2_VERSION, TLS1_2_VERSION,
+     DTLS1_2_VERSION, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+# endif                         /* OPENSSL_NO_EC */
+
+# ifndef OPENSSL_NO_PSK
+    {
+     1,
+     TLS1_TXT_PSK_WITH_CAMELLIA_128_CBC_SHA256,
+     TLS1_CK_PSK_WITH_CAMELLIA_128_CBC_SHA256,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_CAMELLIA128,
+     SSL_SHA256,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_PSK_WITH_CAMELLIA_256_CBC_SHA384,
+     TLS1_CK_PSK_WITH_CAMELLIA_256_CBC_SHA384,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_CAMELLIA256,
+     SSL_SHA384,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
+     TLS1_CK_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
+     SSL_kDHEPSK,
+     SSL_aPSK,
+     SSL_CAMELLIA128,
+     SSL_SHA256,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
+     TLS1_CK_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
+     SSL_kDHEPSK,
+     SSL_aPSK,
+     SSL_CAMELLIA256,
+     SSL_SHA384,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256,
+     TLS1_CK_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256,
+     SSL_kRSAPSK,
+     SSL_aRSA,
+     SSL_CAMELLIA128,
+     SSL_SHA256,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384,
+     TLS1_CK_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384,
+     SSL_kRSAPSK,
+     SSL_aRSA,
+     SSL_CAMELLIA256,
+     SSL_SHA384,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
+     TLS1_CK_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
+     SSL_kECDHEPSK,
+     SSL_aPSK,
+     SSL_CAMELLIA128,
+     SSL_SHA256,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
+     TLS1_CK_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
+     SSL_kECDHEPSK,
+     SSL_aPSK,
+     SSL_CAMELLIA256,
+     SSL_SHA384,
+     TLS1_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_HIGH,
+     SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
+     256,
+     256,
+     },
+# endif                         /* OPENSSL_NO_PSK */
+
+#endif                          /* OPENSSL_NO_CAMELLIA */
+
+#ifndef OPENSSL_NO_GOST
+    {
+     1,
+     "GOST2001-GOST89-GOST89",
+     0x3000081,
+     SSL_kGOST,
+     SSL_aGOST01,
+     SSL_eGOST2814789CNT,
+     SSL_GOST89MAC,
+     TLS1_VERSION, TLS1_2_VERSION,
+     0, 0,
+     SSL_HIGH,
+     SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94 | TLS1_STREAM_MAC,
+     256,
+     256,
+     },
+    {
+     1,
+     "GOST2001-NULL-GOST94",
+     0x3000083,
+     SSL_kGOST,
+     SSL_aGOST01,
+     SSL_eNULL,
+     SSL_GOST94,
+     TLS1_VERSION, TLS1_2_VERSION,
+     0, 0,
+     SSL_STRONG_NONE,
+     SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94,
+     0,
+     0,
+     },
+    {
+     1,
+     "GOST2012-GOST8912-GOST8912",
+     0x0300ff85,
+     SSL_kGOST,
+     SSL_aGOST12 | SSL_aGOST01,
+     SSL_eGOST2814789CNT12,
+     SSL_GOST89MAC12,
+     TLS1_VERSION, TLS1_2_VERSION,
+     0, 0,
+     SSL_HIGH,
+     SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_PRF_GOST12_256 | TLS1_STREAM_MAC,
+     256,
+     256,
+     },
+    {
+     1,
+     "GOST2012-NULL-GOST12",
+     0x0300ff87,
+     SSL_kGOST,
+     SSL_aGOST12 | SSL_aGOST01,
+     SSL_eNULL,
+     SSL_GOST12_256,
+     TLS1_VERSION, TLS1_2_VERSION,
+     0, 0,
+     SSL_STRONG_NONE,
+     SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_PRF_GOST12_256 | TLS1_STREAM_MAC,
+     0,
+     0,
+     },
+#endif                          /* OPENSSL_NO_GOST */
+
+#ifndef OPENSSL_NO_IDEA
+    {
+     1,
+     SSL3_TXT_RSA_IDEA_128_SHA,
+     SSL3_CK_RSA_IDEA_128_SHA,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_IDEA,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_1_VERSION,
+     DTLS1_BAD_VER, DTLS1_VERSION,
+     SSL_NOT_DEFAULT | SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+#endif
+
+#ifndef OPENSSL_NO_SEED
+    {
+     1,
+     TLS1_TXT_RSA_WITH_SEED_SHA,
+     TLS1_CK_RSA_WITH_SEED_SHA,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_SEED,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_DSS_WITH_SEED_SHA,
+     TLS1_CK_DHE_DSS_WITH_SEED_SHA,
+     SSL_kDHE,
+     SSL_aDSS,
+     SSL_SEED,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_RSA_WITH_SEED_SHA,
+     TLS1_CK_DHE_RSA_WITH_SEED_SHA,
+     SSL_kDHE,
+     SSL_aRSA,
+     SSL_SEED,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ADH_WITH_SEED_SHA,
+     TLS1_CK_ADH_WITH_SEED_SHA,
+     SSL_kDHE,
+     SSL_aNULL,
+     SSL_SEED,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     DTLS1_BAD_VER, DTLS1_2_VERSION,
+     SSL_NOT_DEFAULT | SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+#endif                          /* OPENSSL_NO_SEED */
+
+#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
+    {
+     1,
+     SSL3_TXT_RSA_RC4_128_MD5,
+     SSL3_CK_RSA_RC4_128_MD5,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_RC4,
+     SSL_MD5,
+     SSL3_VERSION, TLS1_2_VERSION,
+     0, 0,
+     SSL_NOT_DEFAULT | SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     SSL3_TXT_RSA_RC4_128_SHA,
+     SSL3_CK_RSA_RC4_128_SHA,
+     SSL_kRSA,
+     SSL_aRSA,
+     SSL_RC4,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     0, 0,
+     SSL_NOT_DEFAULT | SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     SSL3_TXT_ADH_RC4_128_MD5,
+     SSL3_CK_ADH_RC4_128_MD5,
+     SSL_kDHE,
+     SSL_aNULL,
+     SSL_RC4,
+     SSL_MD5,
+     SSL3_VERSION, TLS1_2_VERSION,
+     0, 0,
+     SSL_NOT_DEFAULT | SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+
+# ifndef OPENSSL_NO_EC
+    {
+     1,
+     TLS1_TXT_ECDHE_PSK_WITH_RC4_128_SHA,
+     TLS1_CK_ECDHE_PSK_WITH_RC4_128_SHA,
+     SSL_kECDHEPSK,
+     SSL_aPSK,
+     SSL_RC4,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     0, 0,
+     SSL_NOT_DEFAULT | SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA,
+     TLS1_CK_ECDH_anon_WITH_RC4_128_SHA,
+     SSL_kECDHE,
+     SSL_aNULL,
+     SSL_RC4,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     0, 0,
+     SSL_NOT_DEFAULT | SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA,
+     TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA,
+     SSL_kECDHE,
+     SSL_aECDSA,
+     SSL_RC4,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     0, 0,
+     SSL_NOT_DEFAULT | SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA,
+     TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA,
+     SSL_kECDHE,
+     SSL_aRSA,
+     SSL_RC4,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     0, 0,
+     SSL_NOT_DEFAULT | SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+# endif                         /* OPENSSL_NO_EC */
+
+# ifndef OPENSSL_NO_PSK
+    {
+     1,
+     TLS1_TXT_PSK_WITH_RC4_128_SHA,
+     TLS1_CK_PSK_WITH_RC4_128_SHA,
+     SSL_kPSK,
+     SSL_aPSK,
+     SSL_RC4,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     0, 0,
+     SSL_NOT_DEFAULT | SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_RSA_PSK_WITH_RC4_128_SHA,
+     TLS1_CK_RSA_PSK_WITH_RC4_128_SHA,
+     SSL_kRSAPSK,
+     SSL_aRSA,
+     SSL_RC4,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     0, 0,
+     SSL_NOT_DEFAULT | SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+    {
+     1,
+     TLS1_TXT_DHE_PSK_WITH_RC4_128_SHA,
+     TLS1_CK_DHE_PSK_WITH_RC4_128_SHA,
+     SSL_kDHEPSK,
+     SSL_aPSK,
+     SSL_RC4,
+     SSL_SHA1,
+     SSL3_VERSION, TLS1_2_VERSION,
+     0, 0,
+     SSL_NOT_DEFAULT | SSL_MEDIUM,
+     SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
+     128,
+     128,
+     },
+# endif                         /* OPENSSL_NO_PSK */
+
+#endif                          /* OPENSSL_NO_WEAK_SSL_CIPHERS */
+
+};
+
+static int cipher_compare(const void *a, const void *b)
+{
+    const SSL_CIPHER *ap = (const SSL_CIPHER *)a;
+    const SSL_CIPHER *bp = (const SSL_CIPHER *)b;
+
+    return ap->id - bp->id;
+}
+
+void ssl_sort_cipher_list(void)
+{
+    qsort(ssl3_ciphers, OSSL_NELEM(ssl3_ciphers), sizeof ssl3_ciphers[0],
+          cipher_compare);
+}
+
+const SSL3_ENC_METHOD SSLv3_enc_data = {
+    ssl3_enc,
+    n_ssl3_mac,
+    ssl3_setup_key_block,
+    ssl3_generate_master_secret,
+    ssl3_change_cipher_state,
+    ssl3_final_finish_mac,
+    MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH,
+    SSL3_MD_CLIENT_FINISHED_CONST, 4,
+    SSL3_MD_SERVER_FINISHED_CONST, 4,
+    ssl3_alert_code,
+    (int (*)(SSL *, unsigned char *, size_t, const char *,
+             size_t, const unsigned char *, size_t,
+             int use_context))ssl_undefined_function,
+    0,
+    SSL3_HM_HEADER_LENGTH,
+    ssl3_set_handshake_header,
+    ssl3_handshake_write
+};
+
+long ssl3_default_timeout(void)
+{
+    /*
+     * 2 hours, the 24 hours mentioned in the SSLv3 spec is way too long for
+     * http, the cache would over fill
+     */
+    return (60 * 60 * 2);
+}
+
+int ssl3_num_ciphers(void)
+{
+    return (SSL3_NUM_CIPHERS);
+}
+
+const SSL_CIPHER *ssl3_get_cipher(unsigned int u)
+{
+    if (u < SSL3_NUM_CIPHERS)
+        return (&(ssl3_ciphers[SSL3_NUM_CIPHERS - 1 - u]));
+    else
+        return (NULL);
+}
+
+int ssl3_set_handshake_header(SSL *s, int htype, unsigned long len)
+{
+    unsigned char *p = (unsigned char *)s->init_buf->data;
+    *(p++) = htype;
+    l2n3(len, p);
+    s->init_num = (int)len + SSL3_HM_HEADER_LENGTH;
+    s->init_off = 0;
+
+    return 1;
+}
+
+int ssl3_handshake_write(SSL *s)
+{
+    return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
+}
+
+int ssl3_new(SSL *s)
+{
+    SSL3_STATE *s3;
+
+    if ((s3 = OPENSSL_zalloc(sizeof(*s3))) == NULL)
+        goto err;
+    s->s3 = s3;
+
+#ifndef OPENSSL_NO_SRP
+    if (!SSL_SRP_CTX_init(s))
+        goto err;
+#endif
+    s->method->ssl_clear(s);
+    return (1);
+ err:
+    return (0);
+}
+
+void ssl3_free(SSL *s)
+{
+    if (s == NULL || s->s3 == NULL)
+        return;
+
+    ssl3_cleanup_key_block(s);
+
+#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
+    EVP_PKEY_free(s->s3->peer_tmp);
+    s->s3->peer_tmp = NULL;
+    EVP_PKEY_free(s->s3->tmp.pkey);
+    s->s3->tmp.pkey = NULL;
+#endif
+
+    sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
+    OPENSSL_free(s->s3->tmp.ciphers_raw);
+    OPENSSL_clear_free(s->s3->tmp.pms, s->s3->tmp.pmslen);
+    OPENSSL_free(s->s3->tmp.peer_sigalgs);
+    ssl3_free_digest_list(s);
+    OPENSSL_free(s->s3->alpn_selected);
+    OPENSSL_free(s->s3->alpn_proposed);
+
+#ifndef OPENSSL_NO_SRP
+    SSL_SRP_CTX_free(s);
+#endif
+    OPENSSL_clear_free(s->s3, sizeof(*s->s3));
+    s->s3 = NULL;
+}
+
+void ssl3_clear(SSL *s)
+{
+    ssl3_cleanup_key_block(s);
+    sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
+    OPENSSL_free(s->s3->tmp.ciphers_raw);
+    OPENSSL_clear_free(s->s3->tmp.pms, s->s3->tmp.pmslen);
+    OPENSSL_free(s->s3->tmp.peer_sigalgs);
+
+#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
+    EVP_PKEY_free(s->s3->tmp.pkey);
+    EVP_PKEY_free(s->s3->peer_tmp);
+#endif                          /* !OPENSSL_NO_EC */
+
+    ssl3_free_digest_list(s);
+
+    OPENSSL_free(s->s3->alpn_selected);
+    OPENSSL_free(s->s3->alpn_proposed);
+
+    /* NULL/zero-out everything in the s3 struct */
+    memset(s->s3, 0, sizeof(*s->s3));
+
+    ssl_free_wbio_buffer(s);
+
+    s->version = SSL3_VERSION;
+
+#if !defined(OPENSSL_NO_NEXTPROTONEG)
+    OPENSSL_free(s->next_proto_negotiated);
+    s->next_proto_negotiated = NULL;
+    s->next_proto_negotiated_len = 0;
+#endif
+}
+
+#ifndef OPENSSL_NO_SRP
+static char *srp_password_from_info_cb(SSL *s, void *arg)
+{
+    return OPENSSL_strdup(s->srp_ctx.info);
+}
+#endif
+
+static int ssl3_set_req_cert_type(CERT *c, const unsigned char *p, size_t len);
+
+long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
+{
+    int ret = 0;
+
+    switch (cmd) {
+    case SSL_CTRL_GET_CLIENT_CERT_REQUEST:
+        break;
+    case SSL_CTRL_GET_NUM_RENEGOTIATIONS:
+        ret = s->s3->num_renegotiations;
+        break;
+    case SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS:
+        ret = s->s3->num_renegotiations;
+        s->s3->num_renegotiations = 0;
+        break;
+    case SSL_CTRL_GET_TOTAL_RENEGOTIATIONS:
+        ret = s->s3->total_renegotiations;
+        break;
+    case SSL_CTRL_GET_FLAGS:
+        ret = (int)(s->s3->flags);
+        break;
+#ifndef OPENSSL_NO_DH
+    case SSL_CTRL_SET_TMP_DH:
+        {
+            DH *dh = (DH *)parg;
+            EVP_PKEY *pkdh = NULL;
+            if (dh == NULL) {
+                SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER);
+                return (ret);
+            }
+            pkdh = ssl_dh_to_pkey(dh);
+            if (pkdh == NULL) {
+                SSLerr(SSL_F_SSL3_CTRL, ERR_R_MALLOC_FAILURE);
+                return 0;
+            }
+            if (!ssl_security(s, SSL_SECOP_TMP_DH,
+                              EVP_PKEY_security_bits(pkdh), 0, pkdh)) {
+                SSLerr(SSL_F_SSL3_CTRL, SSL_R_DH_KEY_TOO_SMALL);
+                EVP_PKEY_free(pkdh);
+                return ret;
+            }
+            EVP_PKEY_free(s->cert->dh_tmp);
+            s->cert->dh_tmp = pkdh;
+            ret = 1;
+        }
+        break;
+    case SSL_CTRL_SET_TMP_DH_CB:
+        {
+            SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+            return (ret);
+        }
+    case SSL_CTRL_SET_DH_AUTO:
+        s->cert->dh_tmp_auto = larg;
+        return 1;
+#endif
+#ifndef OPENSSL_NO_EC
+    case SSL_CTRL_SET_TMP_ECDH:
+        {
+            const EC_GROUP *group = NULL;
+            int nid;
+
+            if (parg == NULL) {
+                SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER);
+                return 0;
+            }
+            group = EC_KEY_get0_group((const EC_KEY *)parg);
+            if (group == NULL) {
+                SSLerr(SSL_F_SSL3_CTRL, EC_R_MISSING_PARAMETERS);
+                return 0;
+            }
+            nid = EC_GROUP_get_curve_name(group);
+            if (nid == NID_undef)
+                return 0;
+            return tls1_set_curves(&s->tlsext_ellipticcurvelist,
+                                   &s->tlsext_ellipticcurvelist_length,
+                                   &nid, 1);
+        }
+        break;
+#endif                          /* !OPENSSL_NO_EC */
+    case SSL_CTRL_SET_TLSEXT_HOSTNAME:
+        if (larg == TLSEXT_NAMETYPE_host_name) {
+            size_t len;
+
+            OPENSSL_free(s->tlsext_hostname);
+            s->tlsext_hostname = NULL;
+
+            ret = 1;
+            if (parg == NULL)
+                break;
+            len = strlen((char *)parg);
+            if (len == 0 || len > TLSEXT_MAXLEN_host_name) {
+                SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME);
+                return 0;
+            }
+            if ((s->tlsext_hostname = OPENSSL_strdup((char *)parg)) == NULL) {
+                SSLerr(SSL_F_SSL3_CTRL, ERR_R_INTERNAL_ERROR);
+                return 0;
+            }
+        } else {
+            SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE);
+            return 0;
+        }
+        break;
+    case SSL_CTRL_SET_TLSEXT_DEBUG_ARG:
+        s->tlsext_debug_arg = parg;
+        ret = 1;
+        break;
+
+    case SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE:
+        ret = s->tlsext_status_type;
+        break;
+
+    case SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE:
+        s->tlsext_status_type = larg;
+        ret = 1;
+        break;
+
+    case SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS:
+        *(STACK_OF(X509_EXTENSION) **)parg = s->tlsext_ocsp_exts;
+        ret = 1;
+        break;
+
+    case SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS:
+        s->tlsext_ocsp_exts = parg;
+        ret = 1;
+        break;
+
+    case SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS:
+        *(STACK_OF(OCSP_RESPID) **)parg = s->tlsext_ocsp_ids;
+        ret = 1;
+        break;
+
+    case SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS:
+        s->tlsext_ocsp_ids = parg;
+        ret = 1;
+        break;
+
+    case SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP:
+        *(unsigned char **)parg = s->tlsext_ocsp_resp;
+        return s->tlsext_ocsp_resplen;
+
+    case SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP:
+        OPENSSL_free(s->tlsext_ocsp_resp);
+        s->tlsext_ocsp_resp = parg;
+        s->tlsext_ocsp_resplen = larg;
+        ret = 1;
+        break;
+
+#ifndef OPENSSL_NO_HEARTBEATS
+    case SSL_CTRL_DTLS_EXT_SEND_HEARTBEAT:
+        if (SSL_IS_DTLS(s))
+            ret = dtls1_heartbeat(s);
+        break;
+
+    case SSL_CTRL_GET_DTLS_EXT_HEARTBEAT_PENDING:
+        if (SSL_IS_DTLS(s))
+            ret = s->tlsext_hb_pending;
+        break;
+
+    case SSL_CTRL_SET_DTLS_EXT_HEARTBEAT_NO_REQUESTS:
+        if (SSL_IS_DTLS(s)) {
+            if (larg)
+                s->tlsext_heartbeat |= SSL_DTLSEXT_HB_DONT_RECV_REQUESTS;
+            else
+                s->tlsext_heartbeat &= ~SSL_DTLSEXT_HB_DONT_RECV_REQUESTS;
+            ret = 1;
+        }
+        break;
+#endif
+
+    case SSL_CTRL_CHAIN:
+        if (larg)
+            return ssl_cert_set1_chain(s, NULL, (STACK_OF(X509) *)parg);
+        else
+            return ssl_cert_set0_chain(s, NULL, (STACK_OF(X509) *)parg);
+
+    case SSL_CTRL_CHAIN_CERT:
+        if (larg)
+            return ssl_cert_add1_chain_cert(s, NULL, (X509 *)parg);
+        else
+            return ssl_cert_add0_chain_cert(s, NULL, (X509 *)parg);
+
+    case SSL_CTRL_GET_CHAIN_CERTS:
+        *(STACK_OF(X509) **)parg = s->cert->key->chain;
+        break;
+
+    case SSL_CTRL_SELECT_CURRENT_CERT:
+        return ssl_cert_select_current(s->cert, (X509 *)parg);
+
+    case SSL_CTRL_SET_CURRENT_CERT:
+        if (larg == SSL_CERT_SET_SERVER) {
+            CERT_PKEY *cpk;
+            const SSL_CIPHER *cipher;
+            if (!s->server)
+                return 0;
+            cipher = s->s3->tmp.new_cipher;
+            if (!cipher)
+                return 0;
+            /*
+             * No certificate for unauthenticated ciphersuites or using SRP
+             * authentication
+             */
+            if (cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP))
+                return 2;
+            cpk = ssl_get_server_send_pkey(s);
+            if (!cpk)
+                return 0;
+            s->cert->key = cpk;
+            return 1;
+        }
+        return ssl_cert_set_current(s->cert, larg);
+
+#ifndef OPENSSL_NO_EC
+    case SSL_CTRL_GET_CURVES:
+        {
+            unsigned char *clist;
+            size_t clistlen;
+            if (!s->session)
+                return 0;
+            clist = s->session->tlsext_ellipticcurvelist;
+            clistlen = s->session->tlsext_ellipticcurvelist_length / 2;
+            if (parg) {
+                size_t i;
+                int *cptr = parg;
+                unsigned int cid, nid;
+                for (i = 0; i < clistlen; i++) {
+                    n2s(clist, cid);
+                    nid = tls1_ec_curve_id2nid(cid, NULL);
+                    if (nid != 0)
+                        cptr[i] = nid;
+                    else
+                        cptr[i] = TLSEXT_nid_unknown | cid;
+                }
+            }
+            return (int)clistlen;
+        }
+
+    case SSL_CTRL_SET_CURVES:
+        return tls1_set_curves(&s->tlsext_ellipticcurvelist,
+                               &s->tlsext_ellipticcurvelist_length, parg, larg);
+
+    case SSL_CTRL_SET_CURVES_LIST:
+        return tls1_set_curves_list(&s->tlsext_ellipticcurvelist,
+                                    &s->tlsext_ellipticcurvelist_length, parg);
+
+    case SSL_CTRL_GET_SHARED_CURVE:
+        return tls1_shared_curve(s, larg);
+
+#endif
+    case SSL_CTRL_SET_SIGALGS:
+        return tls1_set_sigalgs(s->cert, parg, larg, 0);
+
+    case SSL_CTRL_SET_SIGALGS_LIST:
+        return tls1_set_sigalgs_list(s->cert, parg, 0);
+
+    case SSL_CTRL_SET_CLIENT_SIGALGS:
+        return tls1_set_sigalgs(s->cert, parg, larg, 1);
+
+    case SSL_CTRL_SET_CLIENT_SIGALGS_LIST:
+        return tls1_set_sigalgs_list(s->cert, parg, 1);
+
+    case SSL_CTRL_GET_CLIENT_CERT_TYPES:
+        {
+            const unsigned char **pctype = parg;
+            if (s->server || !s->s3->tmp.cert_req)
+                return 0;
+            if (s->cert->ctypes) {
+                if (pctype)
+                    *pctype = s->cert->ctypes;
+                return (int)s->cert->ctype_num;
+            }
+            if (pctype)
+                *pctype = (unsigned char *)s->s3->tmp.ctype;
+            return s->s3->tmp.ctype_num;
+        }
+
+    case SSL_CTRL_SET_CLIENT_CERT_TYPES:
+        if (!s->server)
+            return 0;
+        return ssl3_set_req_cert_type(s->cert, parg, larg);
+
+    case SSL_CTRL_BUILD_CERT_CHAIN:
+        return ssl_build_cert_chain(s, NULL, larg);
+
+    case SSL_CTRL_SET_VERIFY_CERT_STORE:
+        return ssl_cert_set_cert_store(s->cert, parg, 0, larg);
+
+    case SSL_CTRL_SET_CHAIN_CERT_STORE:
+        return ssl_cert_set_cert_store(s->cert, parg, 1, larg);
+
+    case SSL_CTRL_GET_PEER_SIGNATURE_NID:
+        if (SSL_USE_SIGALGS(s)) {
+            if (s->session) {
+                const EVP_MD *sig;
+                sig = s->s3->tmp.peer_md;
+                if (sig) {
+                    *(int *)parg = EVP_MD_type(sig);
+                    return 1;
+                }
+            }
+            return 0;
+        }
+        /* Might want to do something here for other versions */
+        else
+            return 0;
+
+    case SSL_CTRL_GET_SERVER_TMP_KEY:
+#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC)
+        if (s->server || s->session == NULL || s->s3->peer_tmp == NULL) {
+            return 0;
+        } else {
+            EVP_PKEY_up_ref(s->s3->peer_tmp);
+            *(EVP_PKEY **)parg = s->s3->peer_tmp;
+            return 1;
+        }
+#else
+        return 0;
+#endif
+#ifndef OPENSSL_NO_EC
+    case SSL_CTRL_GET_EC_POINT_FORMATS:
+        {
+            SSL_SESSION *sess = s->session;
+            const unsigned char **pformat = parg;
+            if (!sess || !sess->tlsext_ecpointformatlist)
+                return 0;
+            *pformat = sess->tlsext_ecpointformatlist;
+            return (int)sess->tlsext_ecpointformatlist_length;
+        }
+#endif
+
+    default:
+        break;
+    }
+    return (ret);
+}
+
+long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void))
+{
+    int ret = 0;
+
+    switch (cmd) {
+#ifndef OPENSSL_NO_DH
+    case SSL_CTRL_SET_TMP_DH_CB:
+        {
+            s->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp;
+        }
+        break;
+#endif
+    case SSL_CTRL_SET_TLSEXT_DEBUG_CB:
+        s->tlsext_debug_cb = (void (*)(SSL *, int, int,
+                                       const unsigned char *, int, void *))fp;
+        break;
+
+    case SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB:
+        {
+            s->not_resumable_session_cb = (int (*)(SSL *, int))fp;
+        }
+        break;
+    default:
+        break;
+    }
+    return (ret);
+}
+
+long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
+{
+    switch (cmd) {
+#ifndef OPENSSL_NO_DH
+    case SSL_CTRL_SET_TMP_DH:
+        {
+            DH *dh = (DH *)parg;
+            EVP_PKEY *pkdh = NULL;
+            if (dh == NULL) {
+                SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_PASSED_NULL_PARAMETER);
+                return 0;
+            }
+            pkdh = ssl_dh_to_pkey(dh);
+            if (pkdh == NULL) {
+                SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_MALLOC_FAILURE);
+                return 0;
+            }
+            if (!ssl_ctx_security(ctx, SSL_SECOP_TMP_DH,
+                                  EVP_PKEY_security_bits(pkdh), 0, pkdh)) {
+                SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_DH_KEY_TOO_SMALL);
+                EVP_PKEY_free(pkdh);
+                return 1;
+            }
+            EVP_PKEY_free(ctx->cert->dh_tmp);
+            ctx->cert->dh_tmp = pkdh;
+            return 1;
+        }
+        /*
+         * break;
+         */
+    case SSL_CTRL_SET_TMP_DH_CB:
+        {
+            SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+            return (0);
+        }
+    case SSL_CTRL_SET_DH_AUTO:
+        ctx->cert->dh_tmp_auto = larg;
+        return 1;
+#endif
+#ifndef OPENSSL_NO_EC
+    case SSL_CTRL_SET_TMP_ECDH:
+        {
+            const EC_GROUP *group = NULL;
+            int nid;
+
+            if (parg == NULL) {
+                SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_PASSED_NULL_PARAMETER);
+                return 0;
+            }
+            group = EC_KEY_get0_group((const EC_KEY *)parg);
+            if (group == NULL) {
+                SSLerr(SSL_F_SSL3_CTX_CTRL, EC_R_MISSING_PARAMETERS);
+                return 0;
+            }
+            nid = EC_GROUP_get_curve_name(group);
+            if (nid == NID_undef)
+                return 0;
+            return tls1_set_curves(&ctx->tlsext_ellipticcurvelist,
+                                   &ctx->tlsext_ellipticcurvelist_length,
+                                   &nid, 1);
+        }
+        /* break; */
+#endif                          /* !OPENSSL_NO_EC */
+    case SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG:
+        ctx->tlsext_servername_arg = parg;
+        break;
+    case SSL_CTRL_SET_TLSEXT_TICKET_KEYS:
+    case SSL_CTRL_GET_TLSEXT_TICKET_KEYS:
+        {
+            unsigned char *keys = parg;
+            long tlsext_tick_keylen = (sizeof(ctx->tlsext_tick_key_name) +
+                                       sizeof(ctx->tlsext_tick_hmac_key) +
+                                       sizeof(ctx->tlsext_tick_aes_key));
+            if (keys == NULL)
+                return tlsext_tick_keylen;
+            if (larg != tlsext_tick_keylen) {
+                SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_TICKET_KEYS_LENGTH);
+                return 0;
+            }
+            if (cmd == SSL_CTRL_SET_TLSEXT_TICKET_KEYS) {
+                memcpy(ctx->tlsext_tick_key_name, keys,
+                       sizeof(ctx->tlsext_tick_key_name));
+                memcpy(ctx->tlsext_tick_hmac_key,
+                       keys + sizeof(ctx->tlsext_tick_key_name),
+                       sizeof(ctx->tlsext_tick_hmac_key));
+                memcpy(ctx->tlsext_tick_aes_key,
+                       keys + sizeof(ctx->tlsext_tick_key_name) +
+                       sizeof(ctx->tlsext_tick_hmac_key),
+                       sizeof(ctx->tlsext_tick_aes_key));
+            } else {
+                memcpy(keys, ctx->tlsext_tick_key_name,
+                       sizeof(ctx->tlsext_tick_key_name));
+                memcpy(keys + sizeof(ctx->tlsext_tick_key_name),
+                       ctx->tlsext_tick_hmac_key,
+                       sizeof(ctx->tlsext_tick_hmac_key));
+                memcpy(keys + sizeof(ctx->tlsext_tick_key_name) +
+                       sizeof(ctx->tlsext_tick_hmac_key),
+                       ctx->tlsext_tick_aes_key,
+                       sizeof(ctx->tlsext_tick_aes_key));
+            }
+            return 1;
+        }
+
+    case SSL_CTRL_GET_TLSEXT_STATUS_REQ_TYPE:
+        return ctx->tlsext_status_type;
+
+    case SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE:
+        ctx->tlsext_status_type = larg;
+        break;
+
+    case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG:
+        ctx->tlsext_status_arg = parg;
+        return 1;
+
+    case SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG:
+        *(void**)parg = ctx->tlsext_status_arg;
+        break;
+
+    case SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB:
+        *(int (**)(SSL*, void*))parg = ctx->tlsext_status_cb;
+        break;
+
+#ifndef OPENSSL_NO_SRP
+    case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME:
+        ctx->srp_ctx.srp_Mask |= SSL_kSRP;
+        OPENSSL_free(ctx->srp_ctx.login);
+        ctx->srp_ctx.login = NULL;
+        if (parg == NULL)
+            break;
+        if (strlen((const char *)parg) > 255 || strlen((const char *)parg) < 1) {
+            SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_SRP_USERNAME);
+            return 0;
+        }
+        if ((ctx->srp_ctx.login = OPENSSL_strdup((char *)parg)) == NULL) {
+            SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_INTERNAL_ERROR);
+            return 0;
+        }
+        break;
+    case SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD:
+        ctx->srp_ctx.SRP_give_srp_client_pwd_callback =
+            srp_password_from_info_cb;
+        ctx->srp_ctx.info = parg;
+        break;
+    case SSL_CTRL_SET_SRP_ARG:
+        ctx->srp_ctx.srp_Mask |= SSL_kSRP;
+        ctx->srp_ctx.SRP_cb_arg = parg;
+        break;
+
+    case SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH:
+        ctx->srp_ctx.strength = larg;
+        break;
+#endif
+
+#ifndef OPENSSL_NO_EC
+    case SSL_CTRL_SET_CURVES:
+        return tls1_set_curves(&ctx->tlsext_ellipticcurvelist,
+                               &ctx->tlsext_ellipticcurvelist_length,
+                               parg, larg);
+
+    case SSL_CTRL_SET_CURVES_LIST:
+        return tls1_set_curves_list(&ctx->tlsext_ellipticcurvelist,
+                                    &ctx->tlsext_ellipticcurvelist_length,
+                                    parg);
+#endif
+    case SSL_CTRL_SET_SIGALGS:
+        return tls1_set_sigalgs(ctx->cert, parg, larg, 0);
+
+    case SSL_CTRL_SET_SIGALGS_LIST:
+        return tls1_set_sigalgs_list(ctx->cert, parg, 0);
+
+    case SSL_CTRL_SET_CLIENT_SIGALGS:
+        return tls1_set_sigalgs(ctx->cert, parg, larg, 1);
+
+    case SSL_CTRL_SET_CLIENT_SIGALGS_LIST:
+        return tls1_set_sigalgs_list(ctx->cert, parg, 1);
+
+    case SSL_CTRL_SET_CLIENT_CERT_TYPES:
+        return ssl3_set_req_cert_type(ctx->cert, parg, larg);
+
+    case SSL_CTRL_BUILD_CERT_CHAIN:
+        return ssl_build_cert_chain(NULL, ctx, larg);
+
+    case SSL_CTRL_SET_VERIFY_CERT_STORE:
+        return ssl_cert_set_cert_store(ctx->cert, parg, 0, larg);
+
+    case SSL_CTRL_SET_CHAIN_CERT_STORE:
+        return ssl_cert_set_cert_store(ctx->cert, parg, 1, larg);
+
+        /* A Thawte special :-) */
+    case SSL_CTRL_EXTRA_CHAIN_CERT:
+        if (ctx->extra_certs == NULL) {
+            if ((ctx->extra_certs = sk_X509_new_null()) == NULL) {
+                SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_MALLOC_FAILURE);
+                return 0;
+            }
+        }
+        if (!sk_X509_push(ctx->extra_certs, (X509 *)parg)) {
+            SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        break;
+
+    case SSL_CTRL_GET_EXTRA_CHAIN_CERTS:
+        if (ctx->extra_certs == NULL && larg == 0)
+            *(STACK_OF(X509) **)parg = ctx->cert->key->chain;
+        else
+            *(STACK_OF(X509) **)parg = ctx->extra_certs;
+        break;
+
+    case SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS:
+        sk_X509_pop_free(ctx->extra_certs, X509_free);
+        ctx->extra_certs = NULL;
+        break;
+
+    case SSL_CTRL_CHAIN:
+        if (larg)
+            return ssl_cert_set1_chain(NULL, ctx, (STACK_OF(X509) *)parg);
+        else
+            return ssl_cert_set0_chain(NULL, ctx, (STACK_OF(X509) *)parg);
+
+    case SSL_CTRL_CHAIN_CERT:
+        if (larg)
+            return ssl_cert_add1_chain_cert(NULL, ctx, (X509 *)parg);
+        else
+            return ssl_cert_add0_chain_cert(NULL, ctx, (X509 *)parg);
+
+    case SSL_CTRL_GET_CHAIN_CERTS:
+        *(STACK_OF(X509) **)parg = ctx->cert->key->chain;
+        break;
+
+    case SSL_CTRL_SELECT_CURRENT_CERT:
+        return ssl_cert_select_current(ctx->cert, (X509 *)parg);
+
+    case SSL_CTRL_SET_CURRENT_CERT:
+        return ssl_cert_set_current(ctx->cert, larg);
+
+    default:
+        return (0);
+    }
+    return (1);
+}
+
+long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void))
+{
+    switch (cmd) {
+#ifndef OPENSSL_NO_DH
+    case SSL_CTRL_SET_TMP_DH_CB:
+        {
+            ctx->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp;
+        }
+        break;
+#endif
+    case SSL_CTRL_SET_TLSEXT_SERVERNAME_CB:
+        ctx->tlsext_servername_callback = (int (*)(SSL *, int *, void *))fp;
+        break;
+
+    case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB:
+        ctx->tlsext_status_cb = (int (*)(SSL *, void *))fp;
+        break;
+
+    case SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB:
+        ctx->tlsext_ticket_key_cb = (int (*)(SSL *, unsigned char *,
+                                             unsigned char *,
+                                             EVP_CIPHER_CTX *,
+                                             HMAC_CTX *, int))fp;
+        break;
+
+#ifndef OPENSSL_NO_SRP
+    case SSL_CTRL_SET_SRP_VERIFY_PARAM_CB:
+        ctx->srp_ctx.srp_Mask |= SSL_kSRP;
+        ctx->srp_ctx.SRP_verify_param_callback = (int (*)(SSL *, void *))fp;
+        break;
+    case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB:
+        ctx->srp_ctx.srp_Mask |= SSL_kSRP;
+        ctx->srp_ctx.TLS_ext_srp_username_callback =
+            (int (*)(SSL *, int *, void *))fp;
+        break;
+    case SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB:
+        ctx->srp_ctx.srp_Mask |= SSL_kSRP;
+        ctx->srp_ctx.SRP_give_srp_client_pwd_callback =
+            (char *(*)(SSL *, void *))fp;
+        break;
+#endif
+    case SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB:
+        {
+            ctx->not_resumable_session_cb = (int (*)(SSL *, int))fp;
+        }
+        break;
+    default:
+        return (0);
+    }
+    return (1);
+}
+
+/*
+ * This function needs to check if the ciphers required are actually
+ * available
+ */
+const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p)
+{
+    SSL_CIPHER c;
+    const SSL_CIPHER *cp;
+    uint32_t id;
+
+    id = 0x03000000 | ((uint32_t)p[0] << 8L) | (uint32_t)p[1];
+    c.id = id;
+    cp = OBJ_bsearch_ssl_cipher_id(&c, ssl3_ciphers, SSL3_NUM_CIPHERS);
+    return cp;
+}
+
+int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
+{
+    long l;
+
+    if (p != NULL) {
+        l = c->id;
+        if ((l & 0xff000000) != 0x03000000)
+            return (0);
+        p[0] = ((unsigned char)(l >> 8L)) & 0xFF;
+        p[1] = ((unsigned char)(l)) & 0xFF;
+    }
+    return (2);
+}
+
+/*
+ * ssl3_choose_cipher - choose a cipher from those offered by the client
+ * @s: SSL connection
+ * @clnt: ciphers offered by the client
+ * @srvr: ciphers enabled on the server?
+ *
+ * Returns the selected cipher or NULL when no common ciphers.
+ */
+const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
+                                     STACK_OF(SSL_CIPHER) *srvr)
+{
+    const SSL_CIPHER *c, *ret = NULL;
+    STACK_OF(SSL_CIPHER) *prio, *allow;
+    int i, ii, ok;
+    unsigned long alg_k, alg_a, mask_k, mask_a;
+
+    /* Let's see which ciphers we can support */
+
+#if 0
+    /*
+     * Do not set the compare functions, because this may lead to a
+     * reordering by "id". We want to keep the original ordering. We may pay
+     * a price in performance during sk_SSL_CIPHER_find(), but would have to
+     * pay with the price of sk_SSL_CIPHER_dup().
+     */
+    sk_SSL_CIPHER_set_cmp_func(srvr, ssl_cipher_ptr_id_cmp);
+    sk_SSL_CIPHER_set_cmp_func(clnt, ssl_cipher_ptr_id_cmp);
+#endif
+
+#ifdef CIPHER_DEBUG
+    fprintf(stderr, "Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr),
+            (void *)srvr);
+    for (i = 0; i < sk_SSL_CIPHER_num(srvr); ++i) {
+        c = sk_SSL_CIPHER_value(srvr, i);
+        fprintf(stderr, "%p:%s\n", (void *)c, c->name);
+    }
+    fprintf(stderr, "Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt),
+            (void *)clnt);
+    for (i = 0; i < sk_SSL_CIPHER_num(clnt); ++i) {
+        c = sk_SSL_CIPHER_value(clnt, i);
+        fprintf(stderr, "%p:%s\n", (void *)c, c->name);
+    }
+#endif
+
+    if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || tls1_suiteb(s)) {
+        prio = srvr;
+        allow = clnt;
+    } else {
+        prio = clnt;
+        allow = srvr;
+    }
+
+    tls1_set_cert_validity(s);
+    ssl_set_masks(s);
+
+    for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) {
+        c = sk_SSL_CIPHER_value(prio, i);
+
+        /* Skip ciphers not supported by the protocol version */
+        if (!SSL_IS_DTLS(s) &&
+            ((s->version < c->min_tls) || (s->version > c->max_tls)))
+            continue;
+        if (SSL_IS_DTLS(s) &&
+            (DTLS_VERSION_LT(s->version, c->min_dtls) ||
+             DTLS_VERSION_GT(s->version, c->max_dtls)))
+            continue;
+
+        mask_k = s->s3->tmp.mask_k;
+        mask_a = s->s3->tmp.mask_a;
+#ifndef OPENSSL_NO_SRP
+        if (s->srp_ctx.srp_Mask & SSL_kSRP) {
+            mask_k |= SSL_kSRP;
+            mask_a |= SSL_aSRP;
+        }
+#endif
+
+        alg_k = c->algorithm_mkey;
+        alg_a = c->algorithm_auth;
+
+#ifndef OPENSSL_NO_PSK
+        /* with PSK there must be server callback set */
+        if ((alg_k & SSL_PSK) && s->psk_server_callback == NULL)
+            continue;
+#endif                          /* OPENSSL_NO_PSK */
+
+        ok = (alg_k & mask_k) && (alg_a & mask_a);
+#ifdef CIPHER_DEBUG
+        fprintf(stderr, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n", ok, alg_k,
+                alg_a, mask_k, mask_a, (void *)c, c->name);
+#endif
+
+#ifndef OPENSSL_NO_EC
+        /*
+         * if we are considering an ECC cipher suite that uses an ephemeral
+         * EC key check it
+         */
+        if (alg_k & SSL_kECDHE)
+            ok = ok && tls1_check_ec_tmp_key(s, c->id);
+#endif                          /* OPENSSL_NO_EC */
+
+        if (!ok)
+            continue;
+        ii = sk_SSL_CIPHER_find(allow, c);
+        if (ii >= 0) {
+            /* Check security callback permits this cipher */
+            if (!ssl_security(s, SSL_SECOP_CIPHER_SHARED,
+                              c->strength_bits, 0, (void *)c))
+                continue;
+#if !defined(OPENSSL_NO_EC)
+            if ((alg_k & SSL_kECDHE) && (alg_a & SSL_aECDSA)
+                && s->s3->is_probably_safari) {
+                if (!ret)
+                    ret = sk_SSL_CIPHER_value(allow, ii);
+                continue;
+            }
+#endif
+            ret = sk_SSL_CIPHER_value(allow, ii);
+            break;
+        }
+    }
+    return (ret);
+}
+
+int ssl3_get_req_cert_type(SSL *s, unsigned char *p)
+{
+    int ret = 0;
+    uint32_t alg_k, alg_a = 0;
+
+    /* If we have custom certificate types set, use them */
+    if (s->cert->ctypes) {
+        memcpy(p, s->cert->ctypes, s->cert->ctype_num);
+        return (int)s->cert->ctype_num;
+    }
+    /* Get mask of algorithms disabled by signature list */
+    ssl_set_sig_mask(&alg_a, s, SSL_SECOP_SIGALG_MASK);
+
+    alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+
+#ifndef OPENSSL_NO_GOST
+    if (s->version >= TLS1_VERSION) {
+        if (alg_k & SSL_kGOST) {
+            p[ret++] = TLS_CT_GOST01_SIGN;
+            p[ret++] = TLS_CT_GOST12_SIGN;
+            p[ret++] = TLS_CT_GOST12_512_SIGN;
+            return (ret);
+        }
+    }
+#endif
+
+    if ((s->version == SSL3_VERSION) && (alg_k & SSL_kDHE)) {
+#ifndef OPENSSL_NO_DH
+# ifndef OPENSSL_NO_RSA
+        p[ret++] = SSL3_CT_RSA_EPHEMERAL_DH;
+# endif
+# ifndef OPENSSL_NO_DSA
+        p[ret++] = SSL3_CT_DSS_EPHEMERAL_DH;
+# endif
+#endif                          /* !OPENSSL_NO_DH */
+    }
+#ifndef OPENSSL_NO_RSA
+    if (!(alg_a & SSL_aRSA))
+        p[ret++] = SSL3_CT_RSA_SIGN;
+#endif
+#ifndef OPENSSL_NO_DSA
+    if (!(alg_a & SSL_aDSS))
+        p[ret++] = SSL3_CT_DSS_SIGN;
+#endif
+#ifndef OPENSSL_NO_EC
+    /*
+     * ECDSA certs can be used with RSA cipher suites too so we don't
+     * need to check for SSL_kECDH or SSL_kECDHE
+     */
+    if (s->version >= TLS1_VERSION) {
+        if (!(alg_a & SSL_aECDSA))
+            p[ret++] = TLS_CT_ECDSA_SIGN;
+    }
+#endif
+    return (ret);
+}
+
+static int ssl3_set_req_cert_type(CERT *c, const unsigned char *p, size_t len)
+{
+    OPENSSL_free(c->ctypes);
+    c->ctypes = NULL;
+    if (!p || !len)
+        return 1;
+    if (len > 0xff)
+        return 0;
+    c->ctypes = OPENSSL_malloc(len);
+    if (c->ctypes == NULL)
+        return 0;
+    memcpy(c->ctypes, p, len);
+    c->ctype_num = len;
+    return 1;
+}
+
+int ssl3_shutdown(SSL *s)
+{
+    int ret;
+
+    /*
+     * Don't do anything much if we have not done the handshake or we don't
+     * want to send messages :-)
+     */
+    if (s->quiet_shutdown || SSL_in_before(s)) {
+        s->shutdown = (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
+        return (1);
+    }
+
+    if (!(s->shutdown & SSL_SENT_SHUTDOWN)) {
+        s->shutdown |= SSL_SENT_SHUTDOWN;
+        ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY);
+        /*
+         * our shutdown alert has been sent now, and if it still needs to be
+         * written, s->s3->alert_dispatch will be true
+         */
+        if (s->s3->alert_dispatch)
+            return (-1);        /* return WANT_WRITE */
+    } else if (s->s3->alert_dispatch) {
+        /* resend it if not sent */
+        ret = s->method->ssl_dispatch_alert(s);
+        if (ret == -1) {
+            /*
+             * we only get to return -1 here the 2nd/Nth invocation, we must
+             * have already signalled return 0 upon a previous invocation,
+             * return WANT_WRITE
+             */
+            return (ret);
+        }
+    } else if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) {
+        /*
+         * If we are waiting for a close from our peer, we are closed
+         */
+        s->method->ssl_read_bytes(s, 0, NULL, NULL, 0, 0);
+        if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) {
+            return (-1);        /* return WANT_READ */
+        }
+    }
+
+    if ((s->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN)) &&
+        !s->s3->alert_dispatch)
+        return (1);
+    else
+        return (0);
+}
+
+int ssl3_write(SSL *s, const void *buf, int len)
+{
+    clear_sys_error();
+    if (s->s3->renegotiate)
+        ssl3_renegotiate_check(s);
+
+    return s->method->ssl_write_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len);
+}
+
+static int ssl3_read_internal(SSL *s, void *buf, int len, int peek)
+{
+    int ret;
+
+    clear_sys_error();
+    if (s->s3->renegotiate)
+        ssl3_renegotiate_check(s);
+    s->s3->in_read_app_data = 1;
+    ret =
+        s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, NULL, buf, len,
+                                  peek);
+    if ((ret == -1) && (s->s3->in_read_app_data == 2)) {
+        /*
+         * ssl3_read_bytes decided to call s->handshake_func, which called
+         * ssl3_read_bytes to read handshake data. However, ssl3_read_bytes
+         * actually found application data and thinks that application data
+         * makes sense here; so disable handshake processing and try to read
+         * application data again.
+         */
+        ossl_statem_set_in_handshake(s, 1);
+        ret =
+            s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, NULL, buf,
+                                      len, peek);
+        ossl_statem_set_in_handshake(s, 0);
+    } else
+        s->s3->in_read_app_data = 0;
+
+    return (ret);
+}
+
+int ssl3_read(SSL *s, void *buf, int len)
+{
+    return ssl3_read_internal(s, buf, len, 0);
+}
+
+int ssl3_peek(SSL *s, void *buf, int len)
+{
+    return ssl3_read_internal(s, buf, len, 1);
+}
+
+int ssl3_renegotiate(SSL *s)
+{
+    if (s->handshake_func == NULL)
+        return (1);
+
+    if (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)
+        return (0);
+
+    s->s3->renegotiate = 1;
+    return (1);
+}
+
+int ssl3_renegotiate_check(SSL *s)
+{
+    int ret = 0;
+
+    if (s->s3->renegotiate) {
+        if (!RECORD_LAYER_read_pending(&s->rlayer)
+            && !RECORD_LAYER_write_pending(&s->rlayer)
+            && !SSL_in_init(s)) {
+            /*
+             * if we are the server, and we have sent a 'RENEGOTIATE'
+             * message, we need to set the state machine into the renegotiate
+             * state.
+             */
+            ossl_statem_set_renegotiate(s);
+            s->s3->renegotiate = 0;
+            s->s3->num_renegotiations++;
+            s->s3->total_renegotiations++;
+            ret = 1;
+        }
+    }
+    return (ret);
+}
+
+/*
+ * If we are using default SHA1+MD5 algorithms switch to new SHA256 PRF and
+ * handshake macs if required.
+ *
+ * If PSK and using SHA384 for TLS < 1.2 switch to default.
+ */
+long ssl_get_algorithm2(SSL *s)
+{
+    long alg2;
+    if (s->s3 == NULL || s->s3->tmp.new_cipher == NULL)
+        return -1;
+    alg2 = s->s3->tmp.new_cipher->algorithm2;
+    if (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF) {
+        if (alg2 == (SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF))
+            return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
+    } else if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK) {
+        if (alg2 == (SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384))
+            return SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF;
+    }
+    return alg2;
+}
+
+/*
+ * Fill a ClientRandom or ServerRandom field of length len. Returns <= 0 on
+ * failure, 1 on success.
+ */
+int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, int len)
+{
+    int send_time = 0;
+
+    if (len < 4)
+        return 0;
+    if (server)
+        send_time = (s->mode & SSL_MODE_SEND_SERVERHELLO_TIME) != 0;
+    else
+        send_time = (s->mode & SSL_MODE_SEND_CLIENTHELLO_TIME) != 0;
+    if (send_time) {
+        unsigned long Time = (unsigned long)time(NULL);
+        unsigned char *p = result;
+        l2n(Time, p);
+        return RAND_bytes(p, len - 4);
+    } else
+        return RAND_bytes(result, len);
+}
+
+int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
+                               int free_pms)
+{
+    unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+    if (alg_k & SSL_PSK) {
+#ifndef OPENSSL_NO_PSK
+        unsigned char *pskpms, *t;
+        size_t psklen = s->s3->tmp.psklen;
+        size_t pskpmslen;
+
+        /* create PSK premaster_secret */
+
+        /* For plain PSK "other_secret" is psklen zeroes */
+        if (alg_k & SSL_kPSK)
+            pmslen = psklen;
+
+        pskpmslen = 4 + pmslen + psklen;
+        pskpms = OPENSSL_malloc(pskpmslen);
+        if (pskpms == NULL) {
+            s->session->master_key_length = 0;
+            goto err;
+        }
+        t = pskpms;
+        s2n(pmslen, t);
+        if (alg_k & SSL_kPSK)
+            memset(t, 0, pmslen);
+        else
+            memcpy(t, pms, pmslen);
+        t += pmslen;
+        s2n(psklen, t);
+        memcpy(t, s->s3->tmp.psk, psklen);
+
+        OPENSSL_clear_free(s->s3->tmp.psk, psklen);
+        s->s3->tmp.psk = NULL;
+        s->session->master_key_length =
+            s->method->ssl3_enc->generate_master_secret(s,
+                                                        s->session->master_key,
+                                                        pskpms, pskpmslen);
+        OPENSSL_clear_free(pskpms, pskpmslen);
+#else
+        /* Should never happen */
+        s->session->master_key_length = 0;
+        goto err;
+#endif
+    } else {
+        s->session->master_key_length =
+            s->method->ssl3_enc->generate_master_secret(s,
+                                                        s->session->master_key,
+                                                        pms, pmslen);
+    }
+
+ err:
+    if (pms) {
+        if (free_pms)
+            OPENSSL_clear_free(pms, pmslen);
+        else
+            OPENSSL_cleanse(pms, pmslen);
+    }
+    if (s->server == 0)
+        s->s3->tmp.pms = NULL;
+    return s->session->master_key_length >= 0;
+}
+
+/* Generate a private key from parameters */
+EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm)
+{
+    EVP_PKEY_CTX *pctx = NULL;
+    EVP_PKEY *pkey = NULL;
+
+    if (pm == NULL)
+        return NULL;
+    pctx = EVP_PKEY_CTX_new(pm, NULL);
+    if (pctx == NULL)
+        goto err;
+    if (EVP_PKEY_keygen_init(pctx) <= 0)
+        goto err;
+    if (EVP_PKEY_keygen(pctx, &pkey) <= 0) {
+        EVP_PKEY_free(pkey);
+        pkey = NULL;
+    }
+
+    err:
+    EVP_PKEY_CTX_free(pctx);
+    return pkey;
+}
+#ifndef OPENSSL_NO_EC
+/* Generate a private key a curve ID */
+EVP_PKEY *ssl_generate_pkey_curve(int id)
+{
+    EVP_PKEY_CTX *pctx = NULL;
+    EVP_PKEY *pkey = NULL;
+    unsigned int curve_flags;
+    int nid = tls1_ec_curve_id2nid(id, &curve_flags);
+
+    if (nid == 0)
+        goto err;
+    if ((curve_flags & TLS_CURVE_TYPE) == TLS_CURVE_CUSTOM) {
+        pctx = EVP_PKEY_CTX_new_id(nid, NULL);
+        nid = 0;
+    } else {
+        pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
+    }
+    if (pctx == NULL)
+        goto err;
+    if (EVP_PKEY_keygen_init(pctx) <= 0)
+        goto err;
+    if (nid != 0 && EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid) <= 0)
+        goto err;
+    if (EVP_PKEY_keygen(pctx, &pkey) <= 0) {
+        EVP_PKEY_free(pkey);
+        pkey = NULL;
+    }
+
+ err:
+    EVP_PKEY_CTX_free(pctx);
+    return pkey;
+}
+#endif
+
+/* Derive premaster or master secret for ECDH/DH */
+int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey)
+{
+    int rv = 0;
+    unsigned char *pms = NULL;
+    size_t pmslen = 0;
+    EVP_PKEY_CTX *pctx;
+
+    if (privkey == NULL || pubkey == NULL)
+        return 0;
+
+    pctx = EVP_PKEY_CTX_new(privkey, NULL);
+
+    if (EVP_PKEY_derive_init(pctx) <= 0
+        || EVP_PKEY_derive_set_peer(pctx, pubkey) <= 0
+        || EVP_PKEY_derive(pctx, NULL, &pmslen) <= 0) {
+        goto err;
+    }
+
+    pms = OPENSSL_malloc(pmslen);
+    if (pms == NULL)
+        goto err;
+
+    if (EVP_PKEY_derive(pctx, pms, &pmslen) <= 0)
+        goto err;
+
+    if (s->server) {
+        /* For server generate master secret and discard premaster */
+        rv = ssl_generate_master_secret(s, pms, pmslen, 1);
+        pms = NULL;
+    } else {
+        /* For client just save premaster secret */
+        s->s3->tmp.pms = pms;
+        s->s3->tmp.pmslen = pmslen;
+        pms = NULL;
+        rv = 1;
+    }
+
+ err:
+    OPENSSL_clear_free(pms, pmslen);
+    EVP_PKEY_CTX_free(pctx);
+    return rv;
+}
+
+#ifndef OPENSSL_NO_DH
+EVP_PKEY *ssl_dh_to_pkey(DH *dh)
+{
+    EVP_PKEY *ret;
+    if (dh == NULL)
+        return NULL;
+    ret = EVP_PKEY_new();
+    if (EVP_PKEY_set1_DH(ret, dh) <= 0) {
+        EVP_PKEY_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/s3_msg.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/s3_msg.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/s3_msg.c	(revision 331)
@@ -0,0 +1,125 @@
+/*
+ * Copyright 1995-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
+ */
+
+#define USE_SOCKETS
+#include "ssl_locl.h"
+
+int ssl3_do_change_cipher_spec(SSL *s)
+{
+    int i;
+    const char *sender;
+    int slen;
+
+    if (s->server)
+        i = SSL3_CHANGE_CIPHER_SERVER_READ;
+    else
+        i = SSL3_CHANGE_CIPHER_CLIENT_READ;
+
+    if (s->s3->tmp.key_block == NULL) {
+        if (s->session == NULL || s->session->master_key_length == 0) {
+            /* might happen if dtls1_read_bytes() calls this */
+            SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, SSL_R_CCS_RECEIVED_EARLY);
+            return (0);
+        }
+
+        s->session->cipher = s->s3->tmp.new_cipher;
+        if (!s->method->ssl3_enc->setup_key_block(s))
+            return (0);
+    }
+
+    if (!s->method->ssl3_enc->change_cipher_state(s, i))
+        return (0);
+
+    /*
+     * we have to record the message digest at this point so we can get it
+     * before we read the finished message
+     */
+    if (!s->server) {
+        sender = s->method->ssl3_enc->server_finished_label;
+        slen = s->method->ssl3_enc->server_finished_label_len;
+    } else {
+        sender = s->method->ssl3_enc->client_finished_label;
+        slen = s->method->ssl3_enc->client_finished_label_len;
+    }
+
+    i = s->method->ssl3_enc->final_finish_mac(s,
+                                              sender, slen,
+                                              s->s3->tmp.peer_finish_md);
+    if (i == 0) {
+        SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+    s->s3->tmp.peer_finish_md_len = i;
+
+    return (1);
+}
+
+int ssl3_send_alert(SSL *s, int level, int desc)
+{
+    /* Map tls/ssl alert value to correct one */
+    desc = s->method->ssl3_enc->alert_value(desc);
+    if (s->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION)
+        desc = SSL_AD_HANDSHAKE_FAILURE; /* SSL 3.0 does not have
+                                          * protocol_version alerts */
+    if (desc < 0)
+        return -1;
+    /* If a fatal one, remove from cache */
+    if ((level == SSL3_AL_FATAL) && (s->session != NULL))
+        SSL_CTX_remove_session(s->session_ctx, s->session);
+
+    s->s3->alert_dispatch = 1;
+    s->s3->send_alert[0] = level;
+    s->s3->send_alert[1] = desc;
+    if (!RECORD_LAYER_write_pending(&s->rlayer)) {
+        /* data still being written out? */
+        return s->method->ssl_dispatch_alert(s);
+    }
+    /*
+     * else data is still being written out, we will get written some time in
+     * the future
+     */
+    return -1;
+}
+
+int ssl3_dispatch_alert(SSL *s)
+{
+    int i, j;
+    unsigned int alertlen;
+    void (*cb) (const SSL *ssl, int type, int val) = NULL;
+
+    s->s3->alert_dispatch = 0;
+    alertlen = 2;
+    i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], &alertlen, 1, 0);
+    if (i <= 0) {
+        s->s3->alert_dispatch = 1;
+    } else {
+        /*
+         * Alert sent to BIO.  If it is important, flush it now. If the
+         * message does not get sent due to non-blocking IO, we will not
+         * worry too much.
+         */
+        if (s->s3->send_alert[0] == SSL3_AL_FATAL)
+            (void)BIO_flush(s->wbio);
+
+        if (s->msg_callback)
+            s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert,
+                            2, s, s->msg_callback_arg);
+
+        if (s->info_callback != NULL)
+            cb = s->info_callback;
+        else if (s->ctx->info_callback != NULL)
+            cb = s->ctx->info_callback;
+
+        if (cb != NULL) {
+            j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1];
+            cb(s, SSL_CB_WRITE_ALERT, j);
+        }
+    }
+    return (i);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_asn1.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_asn1.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_asn1.c	(revision 331)
@@ -0,0 +1,367 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "ssl_locl.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+
+typedef struct {
+    long version;
+    long ssl_version;
+    ASN1_OCTET_STRING *cipher;
+    ASN1_OCTET_STRING *comp_id;
+    ASN1_OCTET_STRING *master_key;
+    ASN1_OCTET_STRING *session_id;
+    ASN1_OCTET_STRING *key_arg;
+    long time;
+    long timeout;
+    X509 *peer;
+    ASN1_OCTET_STRING *session_id_context;
+    long verify_result;
+    ASN1_OCTET_STRING *tlsext_hostname;
+    long tlsext_tick_lifetime_hint;
+    ASN1_OCTET_STRING *tlsext_tick;
+#ifndef OPENSSL_NO_PSK
+    ASN1_OCTET_STRING *psk_identity_hint;
+    ASN1_OCTET_STRING *psk_identity;
+#endif
+#ifndef OPENSSL_NO_SRP
+    ASN1_OCTET_STRING *srp_username;
+#endif
+    long flags;
+} SSL_SESSION_ASN1;
+
+ASN1_SEQUENCE(SSL_SESSION_ASN1) = {
+    ASN1_SIMPLE(SSL_SESSION_ASN1, version, LONG),
+    ASN1_SIMPLE(SSL_SESSION_ASN1, ssl_version, LONG),
+    ASN1_SIMPLE(SSL_SESSION_ASN1, cipher, ASN1_OCTET_STRING),
+    ASN1_SIMPLE(SSL_SESSION_ASN1, session_id, ASN1_OCTET_STRING),
+    ASN1_SIMPLE(SSL_SESSION_ASN1, master_key, ASN1_OCTET_STRING),
+    ASN1_IMP_OPT(SSL_SESSION_ASN1, key_arg, ASN1_OCTET_STRING, 0),
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, time, ZLONG, 1),
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, timeout, ZLONG, 2),
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, peer, X509, 3),
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, session_id_context, ASN1_OCTET_STRING, 4),
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, verify_result, ZLONG, 5),
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, tlsext_hostname, ASN1_OCTET_STRING, 6),
+#ifndef OPENSSL_NO_PSK
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, psk_identity_hint, ASN1_OCTET_STRING, 7),
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, psk_identity, ASN1_OCTET_STRING, 8),
+#endif
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, tlsext_tick_lifetime_hint, ZLONG, 9),
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, tlsext_tick, ASN1_OCTET_STRING, 10),
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, comp_id, ASN1_OCTET_STRING, 11),
+#ifndef OPENSSL_NO_SRP
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, srp_username, ASN1_OCTET_STRING, 12),
+#endif
+    ASN1_EXP_OPT(SSL_SESSION_ASN1, flags, ZLONG, 13)
+} static_ASN1_SEQUENCE_END(SSL_SESSION_ASN1)
+
+IMPLEMENT_STATIC_ASN1_ENCODE_FUNCTIONS(SSL_SESSION_ASN1)
+
+/* Utility functions for i2d_SSL_SESSION */
+
+/* Initialise OCTET STRING from buffer and length */
+
+static void ssl_session_oinit(ASN1_OCTET_STRING **dest, ASN1_OCTET_STRING *os,
+                              unsigned char *data, size_t len)
+{
+    os->data = data;
+    os->length = len;
+    os->flags = 0;
+    *dest = os;
+}
+
+/* Initialise OCTET STRING from string */
+static void ssl_session_sinit(ASN1_OCTET_STRING **dest, ASN1_OCTET_STRING *os,
+                              char *data)
+{
+    if (data != NULL)
+        ssl_session_oinit(dest, os, (unsigned char *)data, strlen(data));
+    else
+        *dest = NULL;
+}
+
+int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp)
+{
+
+    SSL_SESSION_ASN1 as;
+
+    ASN1_OCTET_STRING cipher;
+    unsigned char cipher_data[2];
+    ASN1_OCTET_STRING master_key, session_id, sid_ctx;
+
+#ifndef OPENSSL_NO_COMP
+    ASN1_OCTET_STRING comp_id;
+    unsigned char comp_id_data;
+#endif
+
+    ASN1_OCTET_STRING tlsext_hostname, tlsext_tick;
+
+#ifndef OPENSSL_NO_SRP
+    ASN1_OCTET_STRING srp_username;
+#endif
+
+#ifndef OPENSSL_NO_PSK
+    ASN1_OCTET_STRING psk_identity, psk_identity_hint;
+#endif
+
+    long l;
+
+    if ((in == NULL) || ((in->cipher == NULL) && (in->cipher_id == 0)))
+        return 0;
+
+    memset(&as, 0, sizeof(as));
+
+    as.version = SSL_SESSION_ASN1_VERSION;
+    as.ssl_version = in->ssl_version;
+
+    if (in->cipher == NULL)
+        l = in->cipher_id;
+    else
+        l = in->cipher->id;
+    cipher_data[0] = ((unsigned char)(l >> 8L)) & 0xff;
+    cipher_data[1] = ((unsigned char)(l)) & 0xff;
+
+    ssl_session_oinit(&as.cipher, &cipher, cipher_data, 2);
+
+#ifndef OPENSSL_NO_COMP
+    if (in->compress_meth) {
+        comp_id_data = (unsigned char)in->compress_meth;
+        ssl_session_oinit(&as.comp_id, &comp_id, &comp_id_data, 1);
+    }
+#endif
+
+    ssl_session_oinit(&as.master_key, &master_key,
+                      in->master_key, in->master_key_length);
+
+    ssl_session_oinit(&as.session_id, &session_id,
+                      in->session_id, in->session_id_length);
+
+    ssl_session_oinit(&as.session_id_context, &sid_ctx,
+                      in->sid_ctx, in->sid_ctx_length);
+
+    as.time = in->time;
+    as.timeout = in->timeout;
+    as.verify_result = in->verify_result;
+
+    as.peer = in->peer;
+
+    ssl_session_sinit(&as.tlsext_hostname, &tlsext_hostname,
+                      in->tlsext_hostname);
+    if (in->tlsext_tick) {
+        ssl_session_oinit(&as.tlsext_tick, &tlsext_tick,
+                          in->tlsext_tick, in->tlsext_ticklen);
+    }
+    if (in->tlsext_tick_lifetime_hint > 0)
+        as.tlsext_tick_lifetime_hint = in->tlsext_tick_lifetime_hint;
+#ifndef OPENSSL_NO_PSK
+    ssl_session_sinit(&as.psk_identity_hint, &psk_identity_hint,
+                      in->psk_identity_hint);
+    ssl_session_sinit(&as.psk_identity, &psk_identity, in->psk_identity);
+#endif                          /* OPENSSL_NO_PSK */
+#ifndef OPENSSL_NO_SRP
+    ssl_session_sinit(&as.srp_username, &srp_username, in->srp_username);
+#endif                          /* OPENSSL_NO_SRP */
+
+    as.flags = in->flags;
+
+    return i2d_SSL_SESSION_ASN1(&as, pp);
+
+}
+
+/* Utility functions for d2i_SSL_SESSION */
+
+/* OPENSSL_strndup an OCTET STRING */
+
+static int ssl_session_strndup(char **pdst, ASN1_OCTET_STRING *src)
+{
+    OPENSSL_free(*pdst);
+    *pdst = NULL;
+    if (src == NULL)
+        return 1;
+    *pdst = OPENSSL_strndup((char *)src->data, src->length);
+    if (*pdst == NULL)
+        return 0;
+    return 1;
+}
+
+/* Copy an OCTET STRING, return error if it exceeds maximum length */
+
+static int ssl_session_memcpy(unsigned char *dst, unsigned int *pdstlen,
+                              ASN1_OCTET_STRING *src, int maxlen)
+{
+    if (src == NULL) {
+        *pdstlen = 0;
+        return 1;
+    }
+    if (src->length > maxlen)
+        return 0;
+    memcpy(dst, src->data, src->length);
+    *pdstlen = src->length;
+    return 1;
+}
+
+SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
+                             long length)
+{
+    long id;
+    unsigned int tmpl;
+    const unsigned char *p = *pp;
+    SSL_SESSION_ASN1 *as = NULL;
+    SSL_SESSION *ret = NULL;
+
+    as = d2i_SSL_SESSION_ASN1(NULL, &p, length);
+    /* ASN.1 code returns suitable error */
+    if (as == NULL)
+        goto err;
+
+    if (!a || !*a) {
+        ret = SSL_SESSION_new();
+        if (ret == NULL)
+            goto err;
+    } else {
+        ret = *a;
+    }
+
+    if (as->version != SSL_SESSION_ASN1_VERSION) {
+        SSLerr(SSL_F_D2I_SSL_SESSION, SSL_R_UNKNOWN_SSL_VERSION);
+        goto err;
+    }
+
+    if ((as->ssl_version >> 8) != SSL3_VERSION_MAJOR
+        && (as->ssl_version >> 8) != DTLS1_VERSION_MAJOR
+        && as->ssl_version != DTLS1_BAD_VER) {
+        SSLerr(SSL_F_D2I_SSL_SESSION, SSL_R_UNSUPPORTED_SSL_VERSION);
+        goto err;
+    }
+
+    ret->ssl_version = (int)as->ssl_version;
+
+    if (as->cipher->length != 2) {
+        SSLerr(SSL_F_D2I_SSL_SESSION, SSL_R_CIPHER_CODE_WRONG_LENGTH);
+        goto err;
+    }
+
+    p = as->cipher->data;
+    id = 0x03000000L | ((unsigned long)p[0] << 8L) | (unsigned long)p[1];
+
+    ret->cipher = NULL;
+    ret->cipher_id = id;
+
+    if (!ssl_session_memcpy(ret->session_id, &ret->session_id_length,
+                            as->session_id, SSL3_MAX_SSL_SESSION_ID_LENGTH))
+        goto err;
+
+    if (!ssl_session_memcpy(ret->master_key, &tmpl,
+                            as->master_key, SSL_MAX_MASTER_KEY_LENGTH))
+        goto err;
+
+    ret->master_key_length = tmpl;
+
+    if (as->time != 0)
+        ret->time = as->time;
+    else
+        ret->time = (unsigned long)time(NULL);
+
+    if (as->timeout != 0)
+        ret->timeout = as->timeout;
+    else
+        ret->timeout = 3;
+
+    X509_free(ret->peer);
+    ret->peer = as->peer;
+    as->peer = NULL;
+
+    if (!ssl_session_memcpy(ret->sid_ctx, &ret->sid_ctx_length,
+                            as->session_id_context, SSL_MAX_SID_CTX_LENGTH))
+        goto err;
+
+    /* NB: this defaults to zero which is X509_V_OK */
+    ret->verify_result = as->verify_result;
+
+    if (!ssl_session_strndup(&ret->tlsext_hostname, as->tlsext_hostname))
+        goto err;
+
+#ifndef OPENSSL_NO_PSK
+    if (!ssl_session_strndup(&ret->psk_identity_hint, as->psk_identity_hint))
+        goto err;
+    if (!ssl_session_strndup(&ret->psk_identity, as->psk_identity))
+        goto err;
+#endif
+
+    ret->tlsext_tick_lifetime_hint = as->tlsext_tick_lifetime_hint;
+    if (as->tlsext_tick) {
+        ret->tlsext_tick = as->tlsext_tick->data;
+        ret->tlsext_ticklen = as->tlsext_tick->length;
+        as->tlsext_tick->data = NULL;
+    } else {
+        ret->tlsext_tick = NULL;
+    }
+#ifndef OPENSSL_NO_COMP
+    if (as->comp_id) {
+        if (as->comp_id->length != 1) {
+            SSLerr(SSL_F_D2I_SSL_SESSION, SSL_R_BAD_LENGTH);
+            goto err;
+        }
+        ret->compress_meth = as->comp_id->data[0];
+    } else {
+        ret->compress_meth = 0;
+    }
+#endif
+
+#ifndef OPENSSL_NO_SRP
+    if (!ssl_session_strndup(&ret->srp_username, as->srp_username))
+        goto err;
+#endif                          /* OPENSSL_NO_SRP */
+    /* Flags defaults to zero which is fine */
+    ret->flags = as->flags;
+
+    M_ASN1_free_of(as, SSL_SESSION_ASN1);
+
+    if ((a != NULL) && (*a == NULL))
+        *a = ret;
+    *pp = p;
+    return ret;
+
+ err:
+    M_ASN1_free_of(as, SSL_SESSION_ASN1);
+    if ((a == NULL) || (*a != ret))
+        SSL_SESSION_free(ret);
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_cert.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_cert.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_cert.c	(revision 331)
@@ -0,0 +1,1090 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include <stdio.h>
+
+#include "e_os.h"
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#include "internal/o_dir.h"
+#include <openssl/lhash.h>
+#include <openssl/bio.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/dh.h>
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
+#include "ssl_locl.h"
+#include "internal/thread_once.h"
+
+static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx,
+                                         int op, int bits, int nid, void *other,
+                                         void *ex);
+
+static CRYPTO_ONCE ssl_x509_store_ctx_once = CRYPTO_ONCE_STATIC_INIT;
+static volatile int ssl_x509_store_ctx_idx = -1;
+
+DEFINE_RUN_ONCE_STATIC(ssl_x509_store_ctx_init)
+{
+    ssl_x509_store_ctx_idx = X509_STORE_CTX_get_ex_new_index(0,
+                                                             "SSL for verify callback",
+                                                             NULL, NULL, NULL);
+    return ssl_x509_store_ctx_idx >= 0;
+}
+
+int SSL_get_ex_data_X509_STORE_CTX_idx(void)
+{
+
+    if (!RUN_ONCE(&ssl_x509_store_ctx_once, ssl_x509_store_ctx_init))
+        return -1;
+    return ssl_x509_store_ctx_idx;
+}
+
+CERT *ssl_cert_new(void)
+{
+    CERT *ret = OPENSSL_zalloc(sizeof(*ret));
+
+    if (ret == NULL) {
+        SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    ret->key = &(ret->pkeys[SSL_PKEY_RSA_ENC]);
+    ret->references = 1;
+    ret->sec_cb = ssl_security_default_callback;
+    ret->sec_level = OPENSSL_TLS_SECURITY_LEVEL;
+    ret->sec_ex = NULL;
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ret);
+        return NULL;
+    }
+
+    return ret;
+}
+
+CERT *ssl_cert_dup(CERT *cert)
+{
+    CERT *ret = OPENSSL_zalloc(sizeof(*ret));
+    int i;
+
+    if (ret == NULL) {
+        SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    ret->references = 1;
+    ret->key = &ret->pkeys[cert->key - cert->pkeys];
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ret);
+        return NULL;
+    }
+#ifndef OPENSSL_NO_DH
+    if (cert->dh_tmp != NULL) {
+        ret->dh_tmp = cert->dh_tmp;
+        EVP_PKEY_up_ref(ret->dh_tmp);
+    }
+    ret->dh_tmp_cb = cert->dh_tmp_cb;
+    ret->dh_tmp_auto = cert->dh_tmp_auto;
+#endif
+
+    for (i = 0; i < SSL_PKEY_NUM; i++) {
+        CERT_PKEY *cpk = cert->pkeys + i;
+        CERT_PKEY *rpk = ret->pkeys + i;
+        if (cpk->x509 != NULL) {
+            rpk->x509 = cpk->x509;
+            X509_up_ref(rpk->x509);
+        }
+
+        if (cpk->privatekey != NULL) {
+            rpk->privatekey = cpk->privatekey;
+            EVP_PKEY_up_ref(cpk->privatekey);
+        }
+
+        if (cpk->chain) {
+            rpk->chain = X509_chain_up_ref(cpk->chain);
+            if (!rpk->chain) {
+                SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+        }
+        if (cert->pkeys[i].serverinfo != NULL) {
+            /* Just copy everything. */
+            ret->pkeys[i].serverinfo =
+                OPENSSL_malloc(cert->pkeys[i].serverinfo_length);
+            if (ret->pkeys[i].serverinfo == NULL) {
+                SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+            ret->pkeys[i].serverinfo_length = cert->pkeys[i].serverinfo_length;
+            memcpy(ret->pkeys[i].serverinfo,
+                   cert->pkeys[i].serverinfo, cert->pkeys[i].serverinfo_length);
+        }
+    }
+
+    /* Configured sigalgs copied across */
+    if (cert->conf_sigalgs) {
+        ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen);
+        if (ret->conf_sigalgs == NULL)
+            goto err;
+        memcpy(ret->conf_sigalgs, cert->conf_sigalgs, cert->conf_sigalgslen);
+        ret->conf_sigalgslen = cert->conf_sigalgslen;
+    } else
+        ret->conf_sigalgs = NULL;
+
+    if (cert->client_sigalgs) {
+        ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen);
+        if (ret->client_sigalgs == NULL)
+            goto err;
+        memcpy(ret->client_sigalgs, cert->client_sigalgs,
+               cert->client_sigalgslen);
+        ret->client_sigalgslen = cert->client_sigalgslen;
+    } else
+        ret->client_sigalgs = NULL;
+    /* Shared sigalgs also NULL */
+    ret->shared_sigalgs = NULL;
+    /* Copy any custom client certificate types */
+    if (cert->ctypes) {
+        ret->ctypes = OPENSSL_malloc(cert->ctype_num);
+        if (ret->ctypes == NULL)
+            goto err;
+        memcpy(ret->ctypes, cert->ctypes, cert->ctype_num);
+        ret->ctype_num = cert->ctype_num;
+    }
+
+    ret->cert_flags = cert->cert_flags;
+
+    ret->cert_cb = cert->cert_cb;
+    ret->cert_cb_arg = cert->cert_cb_arg;
+
+    if (cert->verify_store) {
+        X509_STORE_up_ref(cert->verify_store);
+        ret->verify_store = cert->verify_store;
+    }
+
+    if (cert->chain_store) {
+        X509_STORE_up_ref(cert->chain_store);
+        ret->chain_store = cert->chain_store;
+    }
+
+    ret->sec_cb = cert->sec_cb;
+    ret->sec_level = cert->sec_level;
+    ret->sec_ex = cert->sec_ex;
+
+    if (!custom_exts_copy(&ret->cli_ext, &cert->cli_ext))
+        goto err;
+    if (!custom_exts_copy(&ret->srv_ext, &cert->srv_ext))
+        goto err;
+#ifndef OPENSSL_NO_PSK
+    if (cert->psk_identity_hint) {
+        ret->psk_identity_hint = OPENSSL_strdup(cert->psk_identity_hint);
+        if (ret->psk_identity_hint == NULL)
+            goto err;
+    }
+#endif
+    return ret;
+
+ err:
+    ssl_cert_free(ret);
+
+    return NULL;
+}
+
+/* Free up and clear all certificates and chains */
+
+void ssl_cert_clear_certs(CERT *c)
+{
+    int i;
+    if (c == NULL)
+        return;
+    for (i = 0; i < SSL_PKEY_NUM; i++) {
+        CERT_PKEY *cpk = c->pkeys + i;
+        X509_free(cpk->x509);
+        cpk->x509 = NULL;
+        EVP_PKEY_free(cpk->privatekey);
+        cpk->privatekey = NULL;
+        sk_X509_pop_free(cpk->chain, X509_free);
+        cpk->chain = NULL;
+        OPENSSL_free(cpk->serverinfo);
+        cpk->serverinfo = NULL;
+        cpk->serverinfo_length = 0;
+    }
+}
+
+void ssl_cert_free(CERT *c)
+{
+    int i;
+
+    if (c == NULL)
+        return;
+
+    CRYPTO_atomic_add(&c->references, -1, &i, c->lock);
+    REF_PRINT_COUNT("CERT", c);
+    if (i > 0)
+        return;
+    REF_ASSERT_ISNT(i < 0);
+
+#ifndef OPENSSL_NO_DH
+    EVP_PKEY_free(c->dh_tmp);
+#endif
+
+    ssl_cert_clear_certs(c);
+    OPENSSL_free(c->conf_sigalgs);
+    OPENSSL_free(c->client_sigalgs);
+    OPENSSL_free(c->shared_sigalgs);
+    OPENSSL_free(c->ctypes);
+    X509_STORE_free(c->verify_store);
+    X509_STORE_free(c->chain_store);
+    custom_exts_free(&c->cli_ext);
+    custom_exts_free(&c->srv_ext);
+#ifndef OPENSSL_NO_PSK
+    OPENSSL_free(c->psk_identity_hint);
+#endif
+    CRYPTO_THREAD_lock_free(c->lock);
+    OPENSSL_free(c);
+}
+
+int ssl_cert_set0_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain)
+{
+    int i, r;
+    CERT_PKEY *cpk = s ? s->cert->key : ctx->cert->key;
+    if (!cpk)
+        return 0;
+    for (i = 0; i < sk_X509_num(chain); i++) {
+        r = ssl_security_cert(s, ctx, sk_X509_value(chain, i), 0, 0);
+        if (r != 1) {
+            SSLerr(SSL_F_SSL_CERT_SET0_CHAIN, r);
+            return 0;
+        }
+    }
+    sk_X509_pop_free(cpk->chain, X509_free);
+    cpk->chain = chain;
+    return 1;
+}
+
+int ssl_cert_set1_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain)
+{
+    STACK_OF(X509) *dchain;
+    if (!chain)
+        return ssl_cert_set0_chain(s, ctx, NULL);
+    dchain = X509_chain_up_ref(chain);
+    if (!dchain)
+        return 0;
+    if (!ssl_cert_set0_chain(s, ctx, dchain)) {
+        sk_X509_pop_free(dchain, X509_free);
+        return 0;
+    }
+    return 1;
+}
+
+int ssl_cert_add0_chain_cert(SSL *s, SSL_CTX *ctx, X509 *x)
+{
+    int r;
+    CERT_PKEY *cpk = s ? s->cert->key : ctx->cert->key;
+    if (!cpk)
+        return 0;
+    r = ssl_security_cert(s, ctx, x, 0, 0);
+    if (r != 1) {
+        SSLerr(SSL_F_SSL_CERT_ADD0_CHAIN_CERT, r);
+        return 0;
+    }
+    if (!cpk->chain)
+        cpk->chain = sk_X509_new_null();
+    if (!cpk->chain || !sk_X509_push(cpk->chain, x))
+        return 0;
+    return 1;
+}
+
+int ssl_cert_add1_chain_cert(SSL *s, SSL_CTX *ctx, X509 *x)
+{
+    if (!ssl_cert_add0_chain_cert(s, ctx, x))
+        return 0;
+    X509_up_ref(x);
+    return 1;
+}
+
+int ssl_cert_select_current(CERT *c, X509 *x)
+{
+    int i;
+    if (x == NULL)
+        return 0;
+    for (i = 0; i < SSL_PKEY_NUM; i++) {
+        CERT_PKEY *cpk = c->pkeys + i;
+        if (cpk->x509 == x && cpk->privatekey) {
+            c->key = cpk;
+            return 1;
+        }
+    }
+
+    for (i = 0; i < SSL_PKEY_NUM; i++) {
+        CERT_PKEY *cpk = c->pkeys + i;
+        if (cpk->privatekey && cpk->x509 && !X509_cmp(cpk->x509, x)) {
+            c->key = cpk;
+            return 1;
+        }
+    }
+    return 0;
+}
+
+int ssl_cert_set_current(CERT *c, long op)
+{
+    int i, idx;
+    if (!c)
+        return 0;
+    if (op == SSL_CERT_SET_FIRST)
+        idx = 0;
+    else if (op == SSL_CERT_SET_NEXT) {
+        idx = (int)(c->key - c->pkeys + 1);
+        if (idx >= SSL_PKEY_NUM)
+            return 0;
+    } else
+        return 0;
+    for (i = idx; i < SSL_PKEY_NUM; i++) {
+        CERT_PKEY *cpk = c->pkeys + i;
+        if (cpk->x509 && cpk->privatekey) {
+            c->key = cpk;
+            return 1;
+        }
+    }
+    return 0;
+}
+
+void ssl_cert_set_cert_cb(CERT *c, int (*cb) (SSL *ssl, void *arg), void *arg)
+{
+    c->cert_cb = cb;
+    c->cert_cb_arg = arg;
+}
+
+int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk)
+{
+    X509 *x;
+    int i = 0;
+    X509_STORE *verify_store;
+    X509_STORE_CTX *ctx = NULL;
+    X509_VERIFY_PARAM *param;
+
+    if ((sk == NULL) || (sk_X509_num(sk) == 0))
+        return 0;
+
+    if (s->cert->verify_store)
+        verify_store = s->cert->verify_store;
+    else
+        verify_store = s->ctx->cert_store;
+
+    ctx = X509_STORE_CTX_new();
+    if (ctx == NULL) {
+        SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    x = sk_X509_value(sk, 0);
+    if (!X509_STORE_CTX_init(ctx, verify_store, x, sk)) {
+        SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_X509_LIB);
+        goto end;
+    }
+    param = X509_STORE_CTX_get0_param(ctx);
+    /*
+     * XXX: Separate @AUTHSECLEVEL and @TLSSECLEVEL would be useful at some
+     * point, for now a single @SECLEVEL sets the same policy for TLS crypto
+     * and PKI authentication.
+     */
+    X509_VERIFY_PARAM_set_auth_level(param, SSL_get_security_level(s));
+
+    /* Set suite B flags if needed */
+    X509_STORE_CTX_set_flags(ctx, tls1_suiteb(s));
+    if (!X509_STORE_CTX_set_ex_data
+        (ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s)) {
+        goto end;
+    }
+
+    /* Verify via DANE if enabled */
+    if (DANETLS_ENABLED(&s->dane))
+        X509_STORE_CTX_set0_dane(ctx, &s->dane);
+
+    /*
+     * We need to inherit the verify parameters. These can be determined by
+     * the context: if its a server it will verify SSL client certificates or
+     * vice versa.
+     */
+
+    X509_STORE_CTX_set_default(ctx, s->server ? "ssl_client" : "ssl_server");
+    /*
+     * Anything non-default in "s->param" should overwrite anything in the ctx.
+     */
+    X509_VERIFY_PARAM_set1(param, s->param);
+
+    if (s->verify_callback)
+        X509_STORE_CTX_set_verify_cb(ctx, s->verify_callback);
+
+    if (s->ctx->app_verify_callback != NULL)
+        i = s->ctx->app_verify_callback(ctx, s->ctx->app_verify_arg);
+    else
+        i = X509_verify_cert(ctx);
+
+    s->verify_result = X509_STORE_CTX_get_error(ctx);
+    sk_X509_pop_free(s->verified_chain, X509_free);
+    s->verified_chain = NULL;
+    if (X509_STORE_CTX_get0_chain(ctx) != NULL) {
+        s->verified_chain = X509_STORE_CTX_get1_chain(ctx);
+        if (s->verified_chain == NULL) {
+            SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_MALLOC_FAILURE);
+            i = 0;
+        }
+    }
+
+    /* Move peername from the store context params to the SSL handle's */
+    X509_VERIFY_PARAM_move_peername(s->param, param);
+
+ end:
+    X509_STORE_CTX_free(ctx);
+    return i;
+}
+
+static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,
+                               STACK_OF(X509_NAME) *name_list)
+{
+    sk_X509_NAME_pop_free(*ca_list, X509_NAME_free);
+    *ca_list = name_list;
+}
+
+STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk)
+{
+    int i;
+    STACK_OF(X509_NAME) *ret;
+    X509_NAME *name;
+
+    ret = sk_X509_NAME_new_null();
+    if (ret == NULL) {
+        SSLerr(SSL_F_SSL_DUP_CA_LIST, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    for (i = 0; i < sk_X509_NAME_num(sk); i++) {
+        name = X509_NAME_dup(sk_X509_NAME_value(sk, i));
+        if (name == NULL || !sk_X509_NAME_push(ret, name)) {
+            sk_X509_NAME_pop_free(ret, X509_NAME_free);
+            X509_NAME_free(name);
+            return NULL;
+        }
+    }
+    return (ret);
+}
+
+void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list)
+{
+    set_client_CA_list(&(s->client_CA), name_list);
+}
+
+void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list)
+{
+    set_client_CA_list(&(ctx->client_CA), name_list);
+}
+
+STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx)
+{
+    return (ctx->client_CA);
+}
+
+STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s)
+{
+    if (!s->server) {           /* we are in the client */
+        if (((s->version >> 8) == SSL3_VERSION_MAJOR) && (s->s3 != NULL))
+            return (s->s3->tmp.ca_names);
+        else
+            return (NULL);
+    } else {
+        if (s->client_CA != NULL)
+            return (s->client_CA);
+        else
+            return (s->ctx->client_CA);
+    }
+}
+
+static int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x)
+{
+    X509_NAME *name;
+
+    if (x == NULL)
+        return (0);
+    if ((*sk == NULL) && ((*sk = sk_X509_NAME_new_null()) == NULL))
+        return (0);
+
+    if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL)
+        return (0);
+
+    if (!sk_X509_NAME_push(*sk, name)) {
+        X509_NAME_free(name);
+        return (0);
+    }
+    return (1);
+}
+
+int SSL_add_client_CA(SSL *ssl, X509 *x)
+{
+    return (add_client_CA(&(ssl->client_CA), x));
+}
+
+int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x)
+{
+    return (add_client_CA(&(ctx->client_CA), x));
+}
+
+static int xname_sk_cmp(const X509_NAME *const *a, const X509_NAME *const *b)
+{
+    return (X509_NAME_cmp(*a, *b));
+}
+
+static int xname_cmp(const X509_NAME *a, const X509_NAME *b)
+{
+    return X509_NAME_cmp(a, b);
+}
+
+static unsigned long xname_hash(const X509_NAME *a)
+{
+    return X509_NAME_hash((X509_NAME *)a);
+}
+
+/**
+ * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed;
+ * it doesn't really have anything to do with clients (except that a common use
+ * for a stack of CAs is to send it to the client). Actually, it doesn't have
+ * much to do with CAs, either, since it will load any old cert.
+ * \param file the file containing one or more certs.
+ * \return a ::STACK containing the certs.
+ */
+STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file)
+{
+    BIO *in = BIO_new(BIO_s_file());
+    X509 *x = NULL;
+    X509_NAME *xn = NULL;
+    STACK_OF(X509_NAME) *ret = NULL;
+    LHASH_OF(X509_NAME) *name_hash = lh_X509_NAME_new(xname_hash, xname_cmp);
+
+    if ((name_hash == NULL) || (in == NULL)) {
+        SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (!BIO_read_filename(in, file))
+        goto err;
+
+    for (;;) {
+        if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
+            break;
+        if (ret == NULL) {
+            ret = sk_X509_NAME_new_null();
+            if (ret == NULL) {
+                SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE);
+                goto err;
+            }
+        }
+        if ((xn = X509_get_subject_name(x)) == NULL)
+            goto err;
+        /* check for duplicates */
+        xn = X509_NAME_dup(xn);
+        if (xn == NULL)
+            goto err;
+        if (lh_X509_NAME_retrieve(name_hash, xn) != NULL) {
+            /* Duplicate. */
+            X509_NAME_free(xn);
+            xn = NULL;
+        } else {
+            lh_X509_NAME_insert(name_hash, xn);
+            if (!sk_X509_NAME_push(ret, xn))
+                goto err;
+        }
+    }
+    goto done;
+
+ err:
+    X509_NAME_free(xn);
+    sk_X509_NAME_pop_free(ret, X509_NAME_free);
+    ret = NULL;
+ done:
+    BIO_free(in);
+    X509_free(x);
+    lh_X509_NAME_free(name_hash);
+    if (ret != NULL)
+        ERR_clear_error();
+    return (ret);
+}
+
+/**
+ * Add a file of certs to a stack.
+ * \param stack the stack to add to.
+ * \param file the file to add from. All certs in this file that are not
+ * already in the stack will be added.
+ * \return 1 for success, 0 for failure. Note that in the case of failure some
+ * certs may have been added to \c stack.
+ */
+
+int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
+                                        const char *file)
+{
+    BIO *in;
+    X509 *x = NULL;
+    X509_NAME *xn = NULL;
+    int ret = 1;
+    int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b);
+
+    oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_sk_cmp);
+
+    in = BIO_new(BIO_s_file());
+
+    if (in == NULL) {
+        SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (!BIO_read_filename(in, file))
+        goto err;
+
+    for (;;) {
+        if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
+            break;
+        if ((xn = X509_get_subject_name(x)) == NULL)
+            goto err;
+        xn = X509_NAME_dup(xn);
+        if (xn == NULL)
+            goto err;
+        if (sk_X509_NAME_find(stack, xn) >= 0) {
+            /* Duplicate. */
+            X509_NAME_free(xn);
+        } else if (!sk_X509_NAME_push(stack, xn)) {
+            X509_NAME_free(xn);
+            goto err;
+        }
+    }
+
+    ERR_clear_error();
+    goto done;
+
+ err:
+    ret = 0;
+ done:
+    BIO_free(in);
+    X509_free(x);
+    (void)sk_X509_NAME_set_cmp_func(stack, oldcmp);
+    return ret;
+}
+
+/**
+ * Add a directory of certs to a stack.
+ * \param stack the stack to append to.
+ * \param dir the directory to append from. All files in this directory will be
+ * examined as potential certs. Any that are acceptable to
+ * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will be
+ * included.
+ * \return 1 for success, 0 for failure. Note that in the case of failure some
+ * certs may have been added to \c stack.
+ */
+
+int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
+                                       const char *dir)
+{
+    OPENSSL_DIR_CTX *d = NULL;
+    const char *filename;
+    int ret = 0;
+
+    /* Note that a side effect is that the CAs will be sorted by name */
+
+    while ((filename = OPENSSL_DIR_read(&d, dir))) {
+        char buf[1024];
+        int r;
+
+        if (strlen(dir) + strlen(filename) + 2 > sizeof buf) {
+            SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,
+                   SSL_R_PATH_TOO_LONG);
+            goto err;
+        }
+#ifdef OPENSSL_SYS_VMS
+        r = BIO_snprintf(buf, sizeof buf, "%s%s", dir, filename);
+#else
+        r = BIO_snprintf(buf, sizeof buf, "%s/%s", dir, filename);
+#endif
+        if (r <= 0 || r >= (int)sizeof(buf))
+            goto err;
+        if (!SSL_add_file_cert_subjects_to_stack(stack, buf))
+            goto err;
+    }
+
+    if (errno) {
+        SYSerr(SYS_F_OPENDIR, get_last_sys_error());
+        ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')");
+        SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB);
+        goto err;
+    }
+
+    ret = 1;
+
+ err:
+    if (d)
+        OPENSSL_DIR_end(&d);
+
+    return ret;
+}
+
+/* Add a certificate to a BUF_MEM structure */
+
+static int ssl_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
+{
+    int n;
+    unsigned char *p;
+
+    n = i2d_X509(x, NULL);
+    if (n < 0 || !BUF_MEM_grow_clean(buf, (int)(n + (*l) + 3))) {
+        SSLerr(SSL_F_SSL_ADD_CERT_TO_BUF, ERR_R_BUF_LIB);
+        return 0;
+    }
+    p = (unsigned char *)&(buf->data[*l]);
+    l2n3(n, p);
+    n = i2d_X509(x, &p);
+    if (n < 0) {
+        /* Shouldn't happen */
+        SSLerr(SSL_F_SSL_ADD_CERT_TO_BUF, ERR_R_BUF_LIB);
+        return 0;
+    }
+    *l += n + 3;
+
+    return 1;
+}
+
+/* Add certificate chain to internal SSL BUF_MEM structure */
+int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l)
+{
+    BUF_MEM *buf = s->init_buf;
+    int i, chain_count;
+    X509 *x;
+    STACK_OF(X509) *extra_certs;
+    STACK_OF(X509) *chain = NULL;
+    X509_STORE *chain_store;
+
+    /* TLSv1 sends a chain with nothing in it, instead of an alert */
+    if (!BUF_MEM_grow_clean(buf, 10)) {
+        SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, ERR_R_BUF_LIB);
+        return 0;
+    }
+
+    if (!cpk || !cpk->x509)
+        return 1;
+
+    x = cpk->x509;
+
+    /*
+     * If we have a certificate specific chain use it, else use parent ctx.
+     */
+    if (cpk->chain)
+        extra_certs = cpk->chain;
+    else
+        extra_certs = s->ctx->extra_certs;
+
+    if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || extra_certs)
+        chain_store = NULL;
+    else if (s->cert->chain_store)
+        chain_store = s->cert->chain_store;
+    else
+        chain_store = s->ctx->cert_store;
+
+    if (chain_store) {
+        X509_STORE_CTX *xs_ctx = X509_STORE_CTX_new();
+
+        if (xs_ctx == NULL) {
+            SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, ERR_R_MALLOC_FAILURE);
+            return (0);
+        }
+        if (!X509_STORE_CTX_init(xs_ctx, chain_store, x, NULL)) {
+            X509_STORE_CTX_free(xs_ctx);
+            SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, ERR_R_X509_LIB);
+            return (0);
+        }
+        /*
+         * It is valid for the chain not to be complete (because normally we
+         * don't include the root cert in the chain). Therefore we deliberately
+         * ignore the error return from this call. We're not actually verifying
+         * the cert - we're just building as much of the chain as we can
+         */
+        (void)X509_verify_cert(xs_ctx);
+        /* Don't leave errors in the queue */
+        ERR_clear_error();
+        chain = X509_STORE_CTX_get0_chain(xs_ctx);
+        i = ssl_security_cert_chain(s, chain, NULL, 0);
+        if (i != 1) {
+#if 0
+            /* Dummy error calls so mkerr generates them */
+            SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, SSL_R_EE_KEY_TOO_SMALL);
+            SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, SSL_R_CA_KEY_TOO_SMALL);
+            SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, SSL_R_CA_MD_TOO_WEAK);
+#endif
+            X509_STORE_CTX_free(xs_ctx);
+            SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, i);
+            return 0;
+        }
+        chain_count = sk_X509_num(chain);
+        for (i = 0; i < chain_count; i++) {
+            x = sk_X509_value(chain, i);
+
+            if (!ssl_add_cert_to_buf(buf, l, x)) {
+                X509_STORE_CTX_free(xs_ctx);
+                return 0;
+            }
+        }
+        X509_STORE_CTX_free(xs_ctx);
+    } else {
+        i = ssl_security_cert_chain(s, extra_certs, x, 0);
+        if (i != 1) {
+            SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, i);
+            return 0;
+        }
+        if (!ssl_add_cert_to_buf(buf, l, x))
+            return 0;
+        for (i = 0; i < sk_X509_num(extra_certs); i++) {
+            x = sk_X509_value(extra_certs, i);
+            if (!ssl_add_cert_to_buf(buf, l, x))
+                return 0;
+        }
+    }
+    return 1;
+}
+
+/* Build a certificate chain for current certificate */
+int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags)
+{
+    CERT *c = s ? s->cert : ctx->cert;
+    CERT_PKEY *cpk = c->key;
+    X509_STORE *chain_store = NULL;
+    X509_STORE_CTX *xs_ctx = NULL;
+    STACK_OF(X509) *chain = NULL, *untrusted = NULL;
+    X509 *x;
+    int i, rv = 0;
+    unsigned long error;
+
+    if (!cpk->x509) {
+        SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_NO_CERTIFICATE_SET);
+        goto err;
+    }
+    /* Rearranging and check the chain: add everything to a store */
+    if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) {
+        chain_store = X509_STORE_new();
+        if (chain_store == NULL)
+            goto err;
+        for (i = 0; i < sk_X509_num(cpk->chain); i++) {
+            x = sk_X509_value(cpk->chain, i);
+            if (!X509_STORE_add_cert(chain_store, x)) {
+                error = ERR_peek_last_error();
+                if (ERR_GET_LIB(error) != ERR_LIB_X509 ||
+                    ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE)
+                    goto err;
+                ERR_clear_error();
+            }
+        }
+        /* Add EE cert too: it might be self signed */
+        if (!X509_STORE_add_cert(chain_store, cpk->x509)) {
+            error = ERR_peek_last_error();
+            if (ERR_GET_LIB(error) != ERR_LIB_X509 ||
+                ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE)
+                goto err;
+            ERR_clear_error();
+        }
+    } else {
+        if (c->chain_store)
+            chain_store = c->chain_store;
+        else if (s)
+            chain_store = s->ctx->cert_store;
+        else
+            chain_store = ctx->cert_store;
+
+        if (flags & SSL_BUILD_CHAIN_FLAG_UNTRUSTED)
+            untrusted = cpk->chain;
+    }
+
+    xs_ctx = X509_STORE_CTX_new();
+    if (xs_ctx == NULL) {
+        SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if (!X509_STORE_CTX_init(xs_ctx, chain_store, cpk->x509, untrusted)) {
+        SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, ERR_R_X509_LIB);
+        goto err;
+    }
+    /* Set suite B flags if needed */
+    X509_STORE_CTX_set_flags(xs_ctx,
+                             c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS);
+
+    i = X509_verify_cert(xs_ctx);
+    if (i <= 0 && flags & SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR) {
+        if (flags & SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR)
+            ERR_clear_error();
+        i = 1;
+        rv = 2;
+    }
+    if (i > 0)
+        chain = X509_STORE_CTX_get1_chain(xs_ctx);
+    if (i <= 0) {
+        SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_CERTIFICATE_VERIFY_FAILED);
+        i = X509_STORE_CTX_get_error(xs_ctx);
+        ERR_add_error_data(2, "Verify error:",
+                           X509_verify_cert_error_string(i));
+
+        goto err;
+    }
+    /* Remove EE certificate from chain */
+    x = sk_X509_shift(chain);
+    X509_free(x);
+    if (flags & SSL_BUILD_CHAIN_FLAG_NO_ROOT) {
+        if (sk_X509_num(chain) > 0) {
+            /* See if last cert is self signed */
+            x = sk_X509_value(chain, sk_X509_num(chain) - 1);
+            if (X509_get_extension_flags(x) & EXFLAG_SS) {
+                x = sk_X509_pop(chain);
+                X509_free(x);
+            }
+        }
+    }
+    /*
+     * Check security level of all CA certificates: EE will have been checked
+     * already.
+     */
+    for (i = 0; i < sk_X509_num(chain); i++) {
+        x = sk_X509_value(chain, i);
+        rv = ssl_security_cert(s, ctx, x, 0, 0);
+        if (rv != 1) {
+            SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, rv);
+            sk_X509_pop_free(chain, X509_free);
+            rv = 0;
+            goto err;
+        }
+    }
+    sk_X509_pop_free(cpk->chain, X509_free);
+    cpk->chain = chain;
+    if (rv == 0)
+        rv = 1;
+ err:
+    if (flags & SSL_BUILD_CHAIN_FLAG_CHECK)
+        X509_STORE_free(chain_store);
+    X509_STORE_CTX_free(xs_ctx);
+
+    return rv;
+}
+
+int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref)
+{
+    X509_STORE **pstore;
+    if (chain)
+        pstore = &c->chain_store;
+    else
+        pstore = &c->verify_store;
+    X509_STORE_free(*pstore);
+    *pstore = store;
+    if (ref && store)
+        X509_STORE_up_ref(store);
+    return 1;
+}
+
+static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx,
+                                         int op, int bits, int nid, void *other,
+                                         void *ex)
+{
+    int level, minbits;
+    static const int minbits_table[5] = { 80, 112, 128, 192, 256 };
+    if (ctx)
+        level = SSL_CTX_get_security_level(ctx);
+    else
+        level = SSL_get_security_level(s);
+
+    if (level <= 0) {
+        /*
+         * No EDH keys weaker than 1024-bits even at level 0, otherwise,
+         * anything goes.
+         */
+        if (op == SSL_SECOP_TMP_DH && bits < 80)
+            return 0;
+        return 1;
+    }
+    if (level > 5)
+        level = 5;
+    minbits = minbits_table[level - 1];
+    switch (op) {
+    case SSL_SECOP_CIPHER_SUPPORTED:
+    case SSL_SECOP_CIPHER_SHARED:
+    case SSL_SECOP_CIPHER_CHECK:
+        {
+            const SSL_CIPHER *c = other;
+            /* No ciphers below security level */
+            if (bits < minbits)
+                return 0;
+            /* No unauthenticated ciphersuites */
+            if (c->algorithm_auth & SSL_aNULL)
+                return 0;
+            /* No MD5 mac ciphersuites */
+            if (c->algorithm_mac & SSL_MD5)
+                return 0;
+            /* SHA1 HMAC is 160 bits of security */
+            if (minbits > 160 && c->algorithm_mac & SSL_SHA1)
+                return 0;
+            /* Level 2: no RC4 */
+            if (level >= 2 && c->algorithm_enc == SSL_RC4)
+                return 0;
+            /* Level 3: forward secure ciphersuites only */
+            if (level >= 3 && !(c->algorithm_mkey & (SSL_kEDH | SSL_kEECDH)))
+                return 0;
+            break;
+        }
+    case SSL_SECOP_VERSION:
+        if (!SSL_IS_DTLS(s)) {
+            /* SSLv3 not allowed at level 2 */
+            if (nid <= SSL3_VERSION && level >= 2)
+                return 0;
+            /* TLS v1.1 and above only for level 3 */
+            if (nid <= TLS1_VERSION && level >= 3)
+                return 0;
+            /* TLS v1.2 only for level 4 and above */
+            if (nid <= TLS1_1_VERSION && level >= 4)
+                return 0;
+        } else {
+            /* DTLS v1.2 only for level 4 and above */
+            if (DTLS_VERSION_LT(nid, DTLS1_2_VERSION) && level >= 4)
+                return 0;
+        }
+        break;
+
+    case SSL_SECOP_COMPRESSION:
+        if (level >= 2)
+            return 0;
+        break;
+    case SSL_SECOP_TICKET:
+        if (level >= 3)
+            return 0;
+        break;
+    default:
+        if (bits < minbits)
+            return 0;
+    }
+    return 1;
+}
+
+int ssl_security(const SSL *s, int op, int bits, int nid, void *other)
+{
+    return s->cert->sec_cb(s, NULL, op, bits, nid, other, s->cert->sec_ex);
+}
+
+int ssl_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid, void *other)
+{
+    return ctx->cert->sec_cb(NULL, ctx, op, bits, nid, other,
+                             ctx->cert->sec_ex);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_ciph.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_ciph.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_ciph.c	(revision 331)
@@ -0,0 +1,1965 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <openssl/objects.h>
+#include <openssl/comp.h>
+#include <openssl/engine.h>
+#include <openssl/crypto.h>
+#include "ssl_locl.h"
+#include "internal/thread_once.h"
+
+#define SSL_ENC_DES_IDX         0
+#define SSL_ENC_3DES_IDX        1
+#define SSL_ENC_RC4_IDX         2
+#define SSL_ENC_RC2_IDX         3
+#define SSL_ENC_IDEA_IDX        4
+#define SSL_ENC_NULL_IDX        5
+#define SSL_ENC_AES128_IDX      6
+#define SSL_ENC_AES256_IDX      7
+#define SSL_ENC_CAMELLIA128_IDX 8
+#define SSL_ENC_CAMELLIA256_IDX 9
+#define SSL_ENC_GOST89_IDX      10
+#define SSL_ENC_SEED_IDX        11
+#define SSL_ENC_AES128GCM_IDX   12
+#define SSL_ENC_AES256GCM_IDX   13
+#define SSL_ENC_AES128CCM_IDX   14
+#define SSL_ENC_AES256CCM_IDX   15
+#define SSL_ENC_AES128CCM8_IDX  16
+#define SSL_ENC_AES256CCM8_IDX  17
+#define SSL_ENC_GOST8912_IDX    18
+#define SSL_ENC_CHACHA_IDX      19
+#define SSL_ENC_NUM_IDX         20
+
+/* NB: make sure indices in these tables match values above */
+
+typedef struct {
+    uint32_t mask;
+    int nid;
+} ssl_cipher_table;
+
+/* Table of NIDs for each cipher */
+static const ssl_cipher_table ssl_cipher_table_cipher[SSL_ENC_NUM_IDX] = {
+    {SSL_DES, NID_des_cbc},     /* SSL_ENC_DES_IDX 0 */
+    {SSL_3DES, NID_des_ede3_cbc}, /* SSL_ENC_3DES_IDX 1 */
+    {SSL_RC4, NID_rc4},         /* SSL_ENC_RC4_IDX 2 */
+    {SSL_RC2, NID_rc2_cbc},     /* SSL_ENC_RC2_IDX 3 */
+    {SSL_IDEA, NID_idea_cbc},   /* SSL_ENC_IDEA_IDX 4 */
+    {SSL_eNULL, NID_undef},     /* SSL_ENC_NULL_IDX 5 */
+    {SSL_AES128, NID_aes_128_cbc}, /* SSL_ENC_AES128_IDX 6 */
+    {SSL_AES256, NID_aes_256_cbc}, /* SSL_ENC_AES256_IDX 7 */
+    {SSL_CAMELLIA128, NID_camellia_128_cbc}, /* SSL_ENC_CAMELLIA128_IDX 8 */
+    {SSL_CAMELLIA256, NID_camellia_256_cbc}, /* SSL_ENC_CAMELLIA256_IDX 9 */
+    {SSL_eGOST2814789CNT, NID_gost89_cnt}, /* SSL_ENC_GOST89_IDX 10 */
+    {SSL_SEED, NID_seed_cbc},   /* SSL_ENC_SEED_IDX 11 */
+    {SSL_AES128GCM, NID_aes_128_gcm}, /* SSL_ENC_AES128GCM_IDX 12 */
+    {SSL_AES256GCM, NID_aes_256_gcm}, /* SSL_ENC_AES256GCM_IDX 13 */
+    {SSL_AES128CCM, NID_aes_128_ccm}, /* SSL_ENC_AES128CCM_IDX 14 */
+    {SSL_AES256CCM, NID_aes_256_ccm}, /* SSL_ENC_AES256CCM_IDX 15 */
+    {SSL_AES128CCM8, NID_aes_128_ccm}, /* SSL_ENC_AES128CCM8_IDX 16 */
+    {SSL_AES256CCM8, NID_aes_256_ccm}, /* SSL_ENC_AES256CCM8_IDX 17 */
+    {SSL_eGOST2814789CNT12, NID_gost89_cnt_12}, /* SSL_ENC_GOST8912_IDX */
+    {SSL_CHACHA20POLY1305, NID_chacha20_poly1305},
+};
+
+static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX] = {
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL
+};
+
+#define SSL_COMP_NULL_IDX       0
+#define SSL_COMP_ZLIB_IDX       1
+#define SSL_COMP_NUM_IDX        2
+
+static STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
+
+#ifndef OPENSSL_NO_COMP
+static CRYPTO_ONCE ssl_load_builtin_comp_once = CRYPTO_ONCE_STATIC_INIT;
+#endif
+
+/*
+ * Constant SSL_MAX_DIGEST equal to size of digests array should be defined
+ * in the ssl_locl.h
+ */
+
+#define SSL_MD_NUM_IDX  SSL_MAX_DIGEST
+
+/* NB: make sure indices in this table matches values above */
+static const ssl_cipher_table ssl_cipher_table_mac[SSL_MD_NUM_IDX] = {
+    {SSL_MD5, NID_md5},         /* SSL_MD_MD5_IDX 0 */
+    {SSL_SHA1, NID_sha1},       /* SSL_MD_SHA1_IDX 1 */
+    {SSL_GOST94, NID_id_GostR3411_94}, /* SSL_MD_GOST94_IDX 2 */
+    {SSL_GOST89MAC, NID_id_Gost28147_89_MAC}, /* SSL_MD_GOST89MAC_IDX 3 */
+    {SSL_SHA256, NID_sha256},   /* SSL_MD_SHA256_IDX 4 */
+    {SSL_SHA384, NID_sha384},   /* SSL_MD_SHA384_IDX 5 */
+    {SSL_GOST12_256, NID_id_GostR3411_2012_256}, /* SSL_MD_GOST12_256_IDX 6 */
+    {SSL_GOST89MAC12, NID_gost_mac_12}, /* SSL_MD_GOST89MAC12_IDX 7 */
+    {SSL_GOST12_512, NID_id_GostR3411_2012_512}, /* SSL_MD_GOST12_512_IDX 8 */
+    {0, NID_md5_sha1},          /* SSL_MD_MD5_SHA1_IDX 9 */
+    {0, NID_sha224},            /* SSL_MD_SHA224_IDX 10 */
+    {0, NID_sha512}             /* SSL_MD_SHA512_IDX 11 */
+};
+
+static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = {
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+/* *INDENT-OFF* */
+static const ssl_cipher_table ssl_cipher_table_kx[] = {
+    {SSL_kRSA,      NID_kx_rsa},
+    {SSL_kECDHE,    NID_kx_ecdhe},
+    {SSL_kDHE,      NID_kx_dhe},
+    {SSL_kECDHEPSK, NID_kx_ecdhe_psk},
+    {SSL_kDHEPSK,   NID_kx_dhe_psk},
+    {SSL_kRSAPSK,   NID_kx_rsa_psk},
+    {SSL_kPSK,      NID_kx_psk},
+    {SSL_kSRP,      NID_kx_srp},
+    {SSL_kGOST,     NID_kx_gost}
+};
+
+static const ssl_cipher_table ssl_cipher_table_auth[] = {
+    {SSL_aRSA,    NID_auth_rsa},
+    {SSL_aECDSA,  NID_auth_ecdsa},
+    {SSL_aPSK,    NID_auth_psk},
+    {SSL_aDSS,    NID_auth_dss},
+    {SSL_aGOST01, NID_auth_gost01},
+    {SSL_aGOST12, NID_auth_gost12},
+    {SSL_aSRP,    NID_auth_srp},
+    {SSL_aNULL,   NID_auth_null}
+};
+/* *INDENT-ON* */
+
+/* Utility function for table lookup */
+static int ssl_cipher_info_find(const ssl_cipher_table * table,
+                                size_t table_cnt, uint32_t mask)
+{
+    size_t i;
+    for (i = 0; i < table_cnt; i++, table++) {
+        if (table->mask == mask)
+            return i;
+    }
+    return -1;
+}
+
+#define ssl_cipher_info_lookup(table, x) \
+    ssl_cipher_info_find(table, OSSL_NELEM(table), x)
+
+/*
+ * PKEY_TYPE for GOST89MAC is known in advance, but, because implementation
+ * is engine-provided, we'll fill it only if corresponding EVP_PKEY_METHOD is
+ * found
+ */
+static int ssl_mac_pkey_id[SSL_MD_NUM_IDX] = {
+    /* MD5, SHA, GOST94, MAC89 */
+    EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, NID_undef,
+    /* SHA256, SHA384, GOST2012_256, MAC89-12 */
+    EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, NID_undef,
+    /* GOST2012_512 */
+    EVP_PKEY_HMAC,
+};
+
+static int ssl_mac_secret_size[SSL_MD_NUM_IDX];
+
+#define CIPHER_ADD      1
+#define CIPHER_KILL     2
+#define CIPHER_DEL      3
+#define CIPHER_ORD      4
+#define CIPHER_SPECIAL  5
+/*
+ * Bump the ciphers to the top of the list.
+ * This rule isn't currently supported by the public cipherstring API.
+ */
+#define CIPHER_BUMP     6
+
+typedef struct cipher_order_st {
+    const SSL_CIPHER *cipher;
+    int active;
+    int dead;
+    struct cipher_order_st *next, *prev;
+} CIPHER_ORDER;
+
+static const SSL_CIPHER cipher_aliases[] = {
+    /* "ALL" doesn't include eNULL (must be specifically enabled) */
+    {0, SSL_TXT_ALL, 0, 0, 0, ~SSL_eNULL},
+    /* "COMPLEMENTOFALL" */
+    {0, SSL_TXT_CMPALL, 0, 0, 0, SSL_eNULL},
+
+    /*
+     * "COMPLEMENTOFDEFAULT" (does *not* include ciphersuites not found in
+     * ALL!)
+     */
+    {0, SSL_TXT_CMPDEF, 0, 0, 0, 0, 0, 0, 0, 0, 0, SSL_NOT_DEFAULT},
+
+    /*
+     * key exchange aliases (some of those using only a single bit here
+     * combine multiple key exchange algs according to the RFCs, e.g. kDHE
+     * combines DHE_DSS and DHE_RSA)
+     */
+    {0, SSL_TXT_kRSA, 0, SSL_kRSA},
+
+    {0, SSL_TXT_kEDH, 0, SSL_kDHE},
+    {0, SSL_TXT_kDHE, 0, SSL_kDHE},
+    {0, SSL_TXT_DH, 0, SSL_kDHE},
+
+    {0, SSL_TXT_kEECDH, 0, SSL_kECDHE},
+    {0, SSL_TXT_kECDHE, 0, SSL_kECDHE},
+    {0, SSL_TXT_ECDH, 0, SSL_kECDHE},
+
+    {0, SSL_TXT_kPSK, 0, SSL_kPSK},
+    {0, SSL_TXT_kRSAPSK, 0, SSL_kRSAPSK},
+    {0, SSL_TXT_kECDHEPSK, 0, SSL_kECDHEPSK},
+    {0, SSL_TXT_kDHEPSK, 0, SSL_kDHEPSK},
+    {0, SSL_TXT_kSRP, 0, SSL_kSRP},
+    {0, SSL_TXT_kGOST, 0, SSL_kGOST},
+
+    /* server authentication aliases */
+    {0, SSL_TXT_aRSA, 0, 0, SSL_aRSA},
+    {0, SSL_TXT_aDSS, 0, 0, SSL_aDSS},
+    {0, SSL_TXT_DSS, 0, 0, SSL_aDSS},
+    {0, SSL_TXT_aNULL, 0, 0, SSL_aNULL},
+    {0, SSL_TXT_aECDSA, 0, 0, SSL_aECDSA},
+    {0, SSL_TXT_ECDSA, 0, 0, SSL_aECDSA},
+    {0, SSL_TXT_aPSK, 0, 0, SSL_aPSK},
+    {0, SSL_TXT_aGOST01, 0, 0, SSL_aGOST01},
+    {0, SSL_TXT_aGOST12, 0, 0, SSL_aGOST12},
+    {0, SSL_TXT_aGOST, 0, 0, SSL_aGOST01 | SSL_aGOST12},
+    {0, SSL_TXT_aSRP, 0, 0, SSL_aSRP},
+
+    /* aliases combining key exchange and server authentication */
+    {0, SSL_TXT_EDH, 0, SSL_kDHE, ~SSL_aNULL},
+    {0, SSL_TXT_DHE, 0, SSL_kDHE, ~SSL_aNULL},
+    {0, SSL_TXT_EECDH, 0, SSL_kECDHE, ~SSL_aNULL},
+    {0, SSL_TXT_ECDHE, 0, SSL_kECDHE, ~SSL_aNULL},
+    {0, SSL_TXT_NULL, 0, 0, 0, SSL_eNULL},
+    {0, SSL_TXT_RSA, 0, SSL_kRSA, SSL_aRSA},
+    {0, SSL_TXT_ADH, 0, SSL_kDHE, SSL_aNULL},
+    {0, SSL_TXT_AECDH, 0, SSL_kECDHE, SSL_aNULL},
+    {0, SSL_TXT_PSK, 0, SSL_PSK},
+    {0, SSL_TXT_SRP, 0, SSL_kSRP},
+
+    /* symmetric encryption aliases */
+    {0, SSL_TXT_3DES, 0, 0, 0, SSL_3DES},
+    {0, SSL_TXT_RC4, 0, 0, 0, SSL_RC4},
+    {0, SSL_TXT_RC2, 0, 0, 0, SSL_RC2},
+    {0, SSL_TXT_IDEA, 0, 0, 0, SSL_IDEA},
+    {0, SSL_TXT_SEED, 0, 0, 0, SSL_SEED},
+    {0, SSL_TXT_eNULL, 0, 0, 0, SSL_eNULL},
+    {0, SSL_TXT_GOST, 0, 0, 0, SSL_eGOST2814789CNT | SSL_eGOST2814789CNT12},
+    {0, SSL_TXT_AES128, 0, 0, 0,
+     SSL_AES128 | SSL_AES128GCM | SSL_AES128CCM | SSL_AES128CCM8},
+    {0, SSL_TXT_AES256, 0, 0, 0,
+     SSL_AES256 | SSL_AES256GCM | SSL_AES256CCM | SSL_AES256CCM8},
+    {0, SSL_TXT_AES, 0, 0, 0, SSL_AES},
+    {0, SSL_TXT_AES_GCM, 0, 0, 0, SSL_AES128GCM | SSL_AES256GCM},
+    {0, SSL_TXT_AES_CCM, 0, 0, 0,
+     SSL_AES128CCM | SSL_AES256CCM | SSL_AES128CCM8 | SSL_AES256CCM8},
+    {0, SSL_TXT_AES_CCM_8, 0, 0, 0, SSL_AES128CCM8 | SSL_AES256CCM8},
+    {0, SSL_TXT_CAMELLIA128, 0, 0, 0, SSL_CAMELLIA128},
+    {0, SSL_TXT_CAMELLIA256, 0, 0, 0, SSL_CAMELLIA256},
+    {0, SSL_TXT_CAMELLIA, 0, 0, 0, SSL_CAMELLIA},
+    {0, SSL_TXT_CHACHA20, 0, 0, 0, SSL_CHACHA20},
+
+    /* MAC aliases */
+    {0, SSL_TXT_MD5, 0, 0, 0, 0, SSL_MD5},
+    {0, SSL_TXT_SHA1, 0, 0, 0, 0, SSL_SHA1},
+    {0, SSL_TXT_SHA, 0, 0, 0, 0, SSL_SHA1},
+    {0, SSL_TXT_GOST94, 0, 0, 0, 0, SSL_GOST94},
+    {0, SSL_TXT_GOST89MAC, 0, 0, 0, 0, SSL_GOST89MAC | SSL_GOST89MAC12},
+    {0, SSL_TXT_SHA256, 0, 0, 0, 0, SSL_SHA256},
+    {0, SSL_TXT_SHA384, 0, 0, 0, 0, SSL_SHA384},
+    {0, SSL_TXT_GOST12, 0, 0, 0, 0, SSL_GOST12_256},
+
+    /* protocol version aliases */
+    {0, SSL_TXT_SSLV3, 0, 0, 0, 0, 0, SSL3_VERSION},
+    {0, SSL_TXT_TLSV1, 0, 0, 0, 0, 0, TLS1_VERSION},
+    {0, "TLSv1.0", 0, 0, 0, 0, 0, TLS1_VERSION},
+    {0, SSL_TXT_TLSV1_2, 0, 0, 0, 0, 0, TLS1_2_VERSION},
+
+    /* strength classes */
+    {0, SSL_TXT_LOW, 0, 0, 0, 0, 0, 0, 0, 0, 0, SSL_LOW},
+    {0, SSL_TXT_MEDIUM, 0, 0, 0, 0, 0, 0, 0, 0, 0, SSL_MEDIUM},
+    {0, SSL_TXT_HIGH, 0, 0, 0, 0, 0, 0, 0, 0, 0, SSL_HIGH},
+    /* FIPS 140-2 approved ciphersuite */
+    {0, SSL_TXT_FIPS, 0, 0, 0, ~SSL_eNULL, 0, 0, 0, 0, 0, SSL_FIPS},
+
+    /* "EDH-" aliases to "DHE-" labels (for backward compatibility) */
+    {0, SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA, 0,
+     SSL_kDHE, SSL_aDSS, SSL_3DES, SSL_SHA1, 0, 0, 0, 0, SSL_HIGH | SSL_FIPS},
+    {0, SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA, 0,
+     SSL_kDHE, SSL_aRSA, SSL_3DES, SSL_SHA1, 0, 0, 0, 0, SSL_HIGH | SSL_FIPS},
+
+};
+
+/*
+ * Search for public key algorithm with given name and return its pkey_id if
+ * it is available. Otherwise return 0
+ */
+#ifdef OPENSSL_NO_ENGINE
+
+static int get_optional_pkey_id(const char *pkey_name)
+{
+    const EVP_PKEY_ASN1_METHOD *ameth;
+    int pkey_id = 0;
+    ameth = EVP_PKEY_asn1_find_str(NULL, pkey_name, -1);
+    if (ameth && EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL,
+                                         ameth) > 0) {
+        return pkey_id;
+    }
+    return 0;
+}
+
+#else
+
+static int get_optional_pkey_id(const char *pkey_name)
+{
+    const EVP_PKEY_ASN1_METHOD *ameth;
+    ENGINE *tmpeng = NULL;
+    int pkey_id = 0;
+    ameth = EVP_PKEY_asn1_find_str(&tmpeng, pkey_name, -1);
+    if (ameth) {
+        if (EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL,
+                                    ameth) <= 0)
+            pkey_id = 0;
+    }
+    ENGINE_finish(tmpeng);
+    return pkey_id;
+}
+
+#endif
+
+/* masks of disabled algorithms */
+static uint32_t disabled_enc_mask;
+static uint32_t disabled_mac_mask;
+static uint32_t disabled_mkey_mask;
+static uint32_t disabled_auth_mask;
+
+void ssl_load_ciphers(void)
+{
+    size_t i;
+    const ssl_cipher_table *t;
+
+    disabled_enc_mask = 0;
+    ssl_sort_cipher_list();
+    for (i = 0, t = ssl_cipher_table_cipher; i < SSL_ENC_NUM_IDX; i++, t++) {
+        if (t->nid == NID_undef) {
+            ssl_cipher_methods[i] = NULL;
+        } else {
+            const EVP_CIPHER *cipher = EVP_get_cipherbynid(t->nid);
+            ssl_cipher_methods[i] = cipher;
+            if (cipher == NULL)
+                disabled_enc_mask |= t->mask;
+        }
+    }
+#ifdef SSL_FORBID_ENULL
+    disabled_enc_mask |= SSL_eNULL;
+#endif
+    disabled_mac_mask = 0;
+    for (i = 0, t = ssl_cipher_table_mac; i < SSL_MD_NUM_IDX; i++, t++) {
+        const EVP_MD *md = EVP_get_digestbynid(t->nid);
+        ssl_digest_methods[i] = md;
+        if (md == NULL) {
+            disabled_mac_mask |= t->mask;
+        } else {
+            ssl_mac_secret_size[i] = EVP_MD_size(md);
+            OPENSSL_assert(ssl_mac_secret_size[i] >= 0);
+        }
+    }
+    /* Make sure we can access MD5 and SHA1 */
+    OPENSSL_assert(ssl_digest_methods[SSL_MD_MD5_IDX] != NULL);
+    OPENSSL_assert(ssl_digest_methods[SSL_MD_SHA1_IDX] != NULL);
+
+    disabled_mkey_mask = 0;
+    disabled_auth_mask = 0;
+
+#ifdef OPENSSL_NO_RSA
+    disabled_mkey_mask |= SSL_kRSA | SSL_kRSAPSK;
+    disabled_auth_mask |= SSL_aRSA;
+#endif
+#ifdef OPENSSL_NO_DSA
+    disabled_auth_mask |= SSL_aDSS;
+#endif
+#ifdef OPENSSL_NO_DH
+    disabled_mkey_mask |= SSL_kDHE | SSL_kDHEPSK;
+#endif
+#ifdef OPENSSL_NO_EC
+    disabled_mkey_mask |= SSL_kECDHEPSK;
+    disabled_auth_mask |= SSL_aECDSA;
+#endif
+#ifdef OPENSSL_NO_PSK
+    disabled_mkey_mask |= SSL_PSK;
+    disabled_auth_mask |= SSL_aPSK;
+#endif
+#ifdef OPENSSL_NO_SRP
+    disabled_mkey_mask |= SSL_kSRP;
+#endif
+
+    /*
+     * Check for presence of GOST 34.10 algorithms, and if they are not
+     * present, disable appropriate auth and key exchange
+     */
+    ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] = get_optional_pkey_id("gost-mac");
+    if (ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]) {
+        ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX] = 32;
+    } else {
+        disabled_mac_mask |= SSL_GOST89MAC;
+    }
+
+    ssl_mac_pkey_id[SSL_MD_GOST89MAC12_IDX] =
+        get_optional_pkey_id("gost-mac-12");
+    if (ssl_mac_pkey_id[SSL_MD_GOST89MAC12_IDX]) {
+        ssl_mac_secret_size[SSL_MD_GOST89MAC12_IDX] = 32;
+    } else {
+        disabled_mac_mask |= SSL_GOST89MAC12;
+    }
+
+    if (!get_optional_pkey_id("gost2001"))
+        disabled_auth_mask |= SSL_aGOST01 | SSL_aGOST12;
+    if (!get_optional_pkey_id("gost2012_256"))
+        disabled_auth_mask |= SSL_aGOST12;
+    if (!get_optional_pkey_id("gost2012_512"))
+        disabled_auth_mask |= SSL_aGOST12;
+    /*
+     * Disable GOST key exchange if no GOST signature algs are available *
+     */
+    if ((disabled_auth_mask & (SSL_aGOST01 | SSL_aGOST12)) ==
+        (SSL_aGOST01 | SSL_aGOST12))
+        disabled_mkey_mask |= SSL_kGOST;
+}
+
+#ifndef OPENSSL_NO_COMP
+
+static int sk_comp_cmp(const SSL_COMP *const *a, const SSL_COMP *const *b)
+{
+    return ((*a)->id - (*b)->id);
+}
+
+DEFINE_RUN_ONCE_STATIC(do_load_builtin_compressions)
+{
+    SSL_COMP *comp = NULL;
+    COMP_METHOD *method = COMP_zlib();
+
+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
+    ssl_comp_methods = sk_SSL_COMP_new(sk_comp_cmp);
+
+    if (COMP_get_type(method) != NID_undef && ssl_comp_methods != NULL) {
+        comp = OPENSSL_malloc(sizeof(*comp));
+        if (comp != NULL) {
+            comp->method = method;
+            comp->id = SSL_COMP_ZLIB_IDX;
+            comp->name = COMP_get_name(method);
+            sk_SSL_COMP_push(ssl_comp_methods, comp);
+            sk_SSL_COMP_sort(ssl_comp_methods);
+        }
+    }
+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
+    return 1;
+}
+
+static int load_builtin_compressions(void)
+{
+    return RUN_ONCE(&ssl_load_builtin_comp_once, do_load_builtin_compressions);
+}
+#endif
+
+int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
+                       const EVP_MD **md, int *mac_pkey_type,
+                       int *mac_secret_size, SSL_COMP **comp, int use_etm)
+{
+    int i;
+    const SSL_CIPHER *c;
+
+    c = s->cipher;
+    if (c == NULL)
+        return (0);
+    if (comp != NULL) {
+        SSL_COMP ctmp;
+#ifndef OPENSSL_NO_COMP
+        if (!load_builtin_compressions()) {
+            /*
+             * Currently don't care, since a failure only means that
+             * ssl_comp_methods is NULL, which is perfectly OK
+             */
+        }
+#endif
+        *comp = NULL;
+        ctmp.id = s->compress_meth;
+        if (ssl_comp_methods != NULL) {
+            i = sk_SSL_COMP_find(ssl_comp_methods, &ctmp);
+            if (i >= 0)
+                *comp = sk_SSL_COMP_value(ssl_comp_methods, i);
+            else
+                *comp = NULL;
+        }
+        /* If were only interested in comp then return success */
+        if ((enc == NULL) && (md == NULL))
+            return 1;
+    }
+
+    if ((enc == NULL) || (md == NULL))
+        return 0;
+
+    i = ssl_cipher_info_lookup(ssl_cipher_table_cipher, c->algorithm_enc);
+
+    if (i == -1)
+        *enc = NULL;
+    else {
+        if (i == SSL_ENC_NULL_IDX)
+            *enc = EVP_enc_null();
+        else
+            *enc = ssl_cipher_methods[i];
+    }
+
+    i = ssl_cipher_info_lookup(ssl_cipher_table_mac, c->algorithm_mac);
+    if (i == -1) {
+        *md = NULL;
+        if (mac_pkey_type != NULL)
+            *mac_pkey_type = NID_undef;
+        if (mac_secret_size != NULL)
+            *mac_secret_size = 0;
+        if (c->algorithm_mac == SSL_AEAD)
+            mac_pkey_type = NULL;
+    } else {
+        *md = ssl_digest_methods[i];
+        if (mac_pkey_type != NULL)
+            *mac_pkey_type = ssl_mac_pkey_id[i];
+        if (mac_secret_size != NULL)
+            *mac_secret_size = ssl_mac_secret_size[i];
+    }
+
+    if ((*enc != NULL) &&
+        (*md != NULL || (EVP_CIPHER_flags(*enc) & EVP_CIPH_FLAG_AEAD_CIPHER))
+        && (!mac_pkey_type || *mac_pkey_type != NID_undef)) {
+        const EVP_CIPHER *evp;
+
+        if (use_etm)
+            return 1;
+
+        if (s->ssl_version >> 8 != TLS1_VERSION_MAJOR ||
+            s->ssl_version < TLS1_VERSION)
+            return 1;
+
+        if (FIPS_mode())
+            return 1;
+
+        if (c->algorithm_enc == SSL_RC4 &&
+            c->algorithm_mac == SSL_MD5 &&
+            (evp = EVP_get_cipherbyname("RC4-HMAC-MD5")))
+            *enc = evp, *md = NULL;
+        else if (c->algorithm_enc == SSL_AES128 &&
+                 c->algorithm_mac == SSL_SHA1 &&
+                 (evp = EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA1")))
+            *enc = evp, *md = NULL;
+        else if (c->algorithm_enc == SSL_AES256 &&
+                 c->algorithm_mac == SSL_SHA1 &&
+                 (evp = EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1")))
+            *enc = evp, *md = NULL;
+        else if (c->algorithm_enc == SSL_AES128 &&
+                 c->algorithm_mac == SSL_SHA256 &&
+                 (evp = EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA256")))
+            *enc = evp, *md = NULL;
+        else if (c->algorithm_enc == SSL_AES256 &&
+                 c->algorithm_mac == SSL_SHA256 &&
+                 (evp = EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA256")))
+            *enc = evp, *md = NULL;
+        return (1);
+    } else
+        return (0);
+}
+
+const EVP_MD *ssl_md(int idx)
+{
+    idx &= SSL_HANDSHAKE_MAC_MASK;
+    if (idx < 0 || idx >= SSL_MD_NUM_IDX)
+        return NULL;
+    return ssl_digest_methods[idx];
+}
+
+const EVP_MD *ssl_handshake_md(SSL *s)
+{
+    return ssl_md(ssl_get_algorithm2(s));
+}
+
+const EVP_MD *ssl_prf_md(SSL *s)
+{
+    return ssl_md(ssl_get_algorithm2(s) >> TLS1_PRF_DGST_SHIFT);
+}
+
+#define ITEM_SEP(a) \
+        (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ','))
+
+static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr,
+                           CIPHER_ORDER **tail)
+{
+    if (curr == *tail)
+        return;
+    if (curr == *head)
+        *head = curr->next;
+    if (curr->prev != NULL)
+        curr->prev->next = curr->next;
+    if (curr->next != NULL)
+        curr->next->prev = curr->prev;
+    (*tail)->next = curr;
+    curr->prev = *tail;
+    curr->next = NULL;
+    *tail = curr;
+}
+
+static void ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr,
+                           CIPHER_ORDER **tail)
+{
+    if (curr == *head)
+        return;
+    if (curr == *tail)
+        *tail = curr->prev;
+    if (curr->next != NULL)
+        curr->next->prev = curr->prev;
+    if (curr->prev != NULL)
+        curr->prev->next = curr->next;
+    (*head)->prev = curr;
+    curr->next = *head;
+    curr->prev = NULL;
+    *head = curr;
+}
+
+static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
+                                       int num_of_ciphers,
+                                       uint32_t disabled_mkey,
+                                       uint32_t disabled_auth,
+                                       uint32_t disabled_enc,
+                                       uint32_t disabled_mac,
+                                       CIPHER_ORDER *co_list,
+                                       CIPHER_ORDER **head_p,
+                                       CIPHER_ORDER **tail_p)
+{
+    int i, co_list_num;
+    const SSL_CIPHER *c;
+
+    /*
+     * We have num_of_ciphers descriptions compiled in, depending on the
+     * method selected (SSLv3, TLSv1 etc).
+     * These will later be sorted in a linked list with at most num
+     * entries.
+     */
+
+    /* Get the initial list of ciphers */
+    co_list_num = 0;            /* actual count of ciphers */
+    for (i = 0; i < num_of_ciphers; i++) {
+        c = ssl_method->get_cipher(i);
+        /* drop those that use any of that is not available */
+        if (c == NULL || !c->valid)
+            continue;
+        if (FIPS_mode() && (c->algo_strength & SSL_FIPS))
+            continue;
+        if ((c->algorithm_mkey & disabled_mkey) ||
+            (c->algorithm_auth & disabled_auth) ||
+            (c->algorithm_enc & disabled_enc) ||
+            (c->algorithm_mac & disabled_mac))
+            continue;
+        if (((ssl_method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) == 0) &&
+            c->min_tls == 0)
+            continue;
+        if (((ssl_method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) != 0) &&
+            c->min_dtls == 0)
+            continue;
+
+        co_list[co_list_num].cipher = c;
+        co_list[co_list_num].next = NULL;
+        co_list[co_list_num].prev = NULL;
+        co_list[co_list_num].active = 0;
+        co_list_num++;
+        /*
+         * if (!sk_push(ca_list,(char *)c)) goto err;
+         */
+    }
+
+    /*
+     * Prepare linked list from list entries
+     */
+    if (co_list_num > 0) {
+        co_list[0].prev = NULL;
+
+        if (co_list_num > 1) {
+            co_list[0].next = &co_list[1];
+
+            for (i = 1; i < co_list_num - 1; i++) {
+                co_list[i].prev = &co_list[i - 1];
+                co_list[i].next = &co_list[i + 1];
+            }
+
+            co_list[co_list_num - 1].prev = &co_list[co_list_num - 2];
+        }
+
+        co_list[co_list_num - 1].next = NULL;
+
+        *head_p = &co_list[0];
+        *tail_p = &co_list[co_list_num - 1];
+    }
+}
+
+static void ssl_cipher_collect_aliases(const SSL_CIPHER **ca_list,
+                                       int num_of_group_aliases,
+                                       uint32_t disabled_mkey,
+                                       uint32_t disabled_auth,
+                                       uint32_t disabled_enc,
+                                       uint32_t disabled_mac,
+                                       CIPHER_ORDER *head)
+{
+    CIPHER_ORDER *ciph_curr;
+    const SSL_CIPHER **ca_curr;
+    int i;
+    uint32_t mask_mkey = ~disabled_mkey;
+    uint32_t mask_auth = ~disabled_auth;
+    uint32_t mask_enc = ~disabled_enc;
+    uint32_t mask_mac = ~disabled_mac;
+
+    /*
+     * First, add the real ciphers as already collected
+     */
+    ciph_curr = head;
+    ca_curr = ca_list;
+    while (ciph_curr != NULL) {
+        *ca_curr = ciph_curr->cipher;
+        ca_curr++;
+        ciph_curr = ciph_curr->next;
+    }
+
+    /*
+     * Now we add the available ones from the cipher_aliases[] table.
+     * They represent either one or more algorithms, some of which
+     * in any affected category must be supported (set in enabled_mask),
+     * or represent a cipher strength value (will be added in any case because algorithms=0).
+     */
+    for (i = 0; i < num_of_group_aliases; i++) {
+        uint32_t algorithm_mkey = cipher_aliases[i].algorithm_mkey;
+        uint32_t algorithm_auth = cipher_aliases[i].algorithm_auth;
+        uint32_t algorithm_enc = cipher_aliases[i].algorithm_enc;
+        uint32_t algorithm_mac = cipher_aliases[i].algorithm_mac;
+
+        if (algorithm_mkey)
+            if ((algorithm_mkey & mask_mkey) == 0)
+                continue;
+
+        if (algorithm_auth)
+            if ((algorithm_auth & mask_auth) == 0)
+                continue;
+
+        if (algorithm_enc)
+            if ((algorithm_enc & mask_enc) == 0)
+                continue;
+
+        if (algorithm_mac)
+            if ((algorithm_mac & mask_mac) == 0)
+                continue;
+
+        *ca_curr = (SSL_CIPHER *)(cipher_aliases + i);
+        ca_curr++;
+    }
+
+    *ca_curr = NULL;            /* end of list */
+}
+
+static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey,
+                                  uint32_t alg_auth, uint32_t alg_enc,
+                                  uint32_t alg_mac, int min_tls,
+                                  uint32_t algo_strength, int rule,
+                                  int32_t strength_bits, CIPHER_ORDER **head_p,
+                                  CIPHER_ORDER **tail_p)
+{
+    CIPHER_ORDER *head, *tail, *curr, *next, *last;
+    const SSL_CIPHER *cp;
+    int reverse = 0;
+
+#ifdef CIPHER_DEBUG
+    fprintf(stderr,
+            "Applying rule %d with %08x/%08x/%08x/%08x/%08x %08x (%d)\n",
+            rule, alg_mkey, alg_auth, alg_enc, alg_mac, min_tls,
+            algo_strength, strength_bits);
+#endif
+
+    if (rule == CIPHER_DEL || rule == CIPHER_BUMP)
+        reverse = 1;            /* needed to maintain sorting between currently
+                                 * deleted ciphers */
+
+    head = *head_p;
+    tail = *tail_p;
+
+    if (reverse) {
+        next = tail;
+        last = head;
+    } else {
+        next = head;
+        last = tail;
+    }
+
+    curr = NULL;
+    for (;;) {
+        if (curr == last)
+            break;
+
+        curr = next;
+
+        if (curr == NULL)
+            break;
+
+        next = reverse ? curr->prev : curr->next;
+
+        cp = curr->cipher;
+
+        /*
+         * Selection criteria is either the value of strength_bits
+         * or the algorithms used.
+         */
+        if (strength_bits >= 0) {
+            if (strength_bits != cp->strength_bits)
+                continue;
+        } else {
+#ifdef CIPHER_DEBUG
+            fprintf(stderr,
+                    "\nName: %s:\nAlgo = %08x/%08x/%08x/%08x/%08x Algo_strength = %08x\n",
+                    cp->name, cp->algorithm_mkey, cp->algorithm_auth,
+                    cp->algorithm_enc, cp->algorithm_mac, cp->min_tls,
+                    cp->algo_strength);
+#endif
+            if (alg_mkey && !(alg_mkey & cp->algorithm_mkey))
+                continue;
+            if (alg_auth && !(alg_auth & cp->algorithm_auth))
+                continue;
+            if (alg_enc && !(alg_enc & cp->algorithm_enc))
+                continue;
+            if (alg_mac && !(alg_mac & cp->algorithm_mac))
+                continue;
+            if (min_tls && (min_tls != cp->min_tls))
+                continue;
+            if ((algo_strength & SSL_STRONG_MASK)
+                && !(algo_strength & SSL_STRONG_MASK & cp->algo_strength))
+                continue;
+            if ((algo_strength & SSL_DEFAULT_MASK)
+                && !(algo_strength & SSL_DEFAULT_MASK & cp->algo_strength))
+                continue;
+        }
+
+#ifdef CIPHER_DEBUG
+        fprintf(stderr, "Action = %d\n", rule);
+#endif
+
+        /* add the cipher if it has not been added yet. */
+        if (rule == CIPHER_ADD) {
+            /* reverse == 0 */
+            if (!curr->active) {
+                ll_append_tail(&head, curr, &tail);
+                curr->active = 1;
+            }
+        }
+        /* Move the added cipher to this location */
+        else if (rule == CIPHER_ORD) {
+            /* reverse == 0 */
+            if (curr->active) {
+                ll_append_tail(&head, curr, &tail);
+            }
+        } else if (rule == CIPHER_DEL) {
+            /* reverse == 1 */
+            if (curr->active) {
+                /*
+                 * most recently deleted ciphersuites get best positions for
+                 * any future CIPHER_ADD (note that the CIPHER_DEL loop works
+                 * in reverse to maintain the order)
+                 */
+                ll_append_head(&head, curr, &tail);
+                curr->active = 0;
+            }
+        } else if (rule == CIPHER_BUMP) {
+            if (curr->active)
+                ll_append_head(&head, curr, &tail);
+        } else if (rule == CIPHER_KILL) {
+            /* reverse == 0 */
+            if (head == curr)
+                head = curr->next;
+            else
+                curr->prev->next = curr->next;
+            if (tail == curr)
+                tail = curr->prev;
+            curr->active = 0;
+            if (curr->next != NULL)
+                curr->next->prev = curr->prev;
+            if (curr->prev != NULL)
+                curr->prev->next = curr->next;
+            curr->next = NULL;
+            curr->prev = NULL;
+        }
+    }
+
+    *head_p = head;
+    *tail_p = tail;
+}
+
+static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p,
+                                    CIPHER_ORDER **tail_p)
+{
+    int32_t max_strength_bits;
+    int i, *number_uses;
+    CIPHER_ORDER *curr;
+
+    /*
+     * This routine sorts the ciphers with descending strength. The sorting
+     * must keep the pre-sorted sequence, so we apply the normal sorting
+     * routine as '+' movement to the end of the list.
+     */
+    max_strength_bits = 0;
+    curr = *head_p;
+    while (curr != NULL) {
+        if (curr->active && (curr->cipher->strength_bits > max_strength_bits))
+            max_strength_bits = curr->cipher->strength_bits;
+        curr = curr->next;
+    }
+
+    number_uses = OPENSSL_zalloc(sizeof(int) * (max_strength_bits + 1));
+    if (number_uses == NULL) {
+        SSLerr(SSL_F_SSL_CIPHER_STRENGTH_SORT, ERR_R_MALLOC_FAILURE);
+        return (0);
+    }
+
+    /*
+     * Now find the strength_bits values actually used
+     */
+    curr = *head_p;
+    while (curr != NULL) {
+        if (curr->active)
+            number_uses[curr->cipher->strength_bits]++;
+        curr = curr->next;
+    }
+    /*
+     * Go through the list of used strength_bits values in descending
+     * order.
+     */
+    for (i = max_strength_bits; i >= 0; i--)
+        if (number_uses[i] > 0)
+            ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, head_p,
+                                  tail_p);
+
+    OPENSSL_free(number_uses);
+    return (1);
+}
+
+static int ssl_cipher_process_rulestr(const char *rule_str,
+                                      CIPHER_ORDER **head_p,
+                                      CIPHER_ORDER **tail_p,
+                                      const SSL_CIPHER **ca_list, CERT *c)
+{
+    uint32_t alg_mkey, alg_auth, alg_enc, alg_mac, algo_strength;
+    int min_tls;
+    const char *l, *buf;
+    int j, multi, found, rule, retval, ok, buflen;
+    uint32_t cipher_id = 0;
+    char ch;
+
+    retval = 1;
+    l = rule_str;
+    for (;;) {
+        ch = *l;
+
+        if (ch == '\0')
+            break;              /* done */
+        if (ch == '-') {
+            rule = CIPHER_DEL;
+            l++;
+        } else if (ch == '+') {
+            rule = CIPHER_ORD;
+            l++;
+        } else if (ch == '!') {
+            rule = CIPHER_KILL;
+            l++;
+        } else if (ch == '@') {
+            rule = CIPHER_SPECIAL;
+            l++;
+        } else {
+            rule = CIPHER_ADD;
+        }
+
+        if (ITEM_SEP(ch)) {
+            l++;
+            continue;
+        }
+
+        alg_mkey = 0;
+        alg_auth = 0;
+        alg_enc = 0;
+        alg_mac = 0;
+        min_tls = 0;
+        algo_strength = 0;
+
+        for (;;) {
+            ch = *l;
+            buf = l;
+            buflen = 0;
+#ifndef CHARSET_EBCDIC
+            while (((ch >= 'A') && (ch <= 'Z')) ||
+                   ((ch >= '0') && (ch <= '9')) ||
+                   ((ch >= 'a') && (ch <= 'z')) ||
+                   (ch == '-') || (ch == '.') || (ch == '='))
+#else
+            while (isalnum(ch) || (ch == '-') || (ch == '.') || (ch == '='))
+#endif
+            {
+                ch = *(++l);
+                buflen++;
+            }
+
+            if (buflen == 0) {
+                /*
+                 * We hit something we cannot deal with,
+                 * it is no command or separator nor
+                 * alphanumeric, so we call this an error.
+                 */
+                SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_INVALID_COMMAND);
+                retval = found = 0;
+                l++;
+                break;
+            }
+
+            if (rule == CIPHER_SPECIAL) {
+                found = 0;      /* unused -- avoid compiler warning */
+                break;          /* special treatment */
+            }
+
+            /* check for multi-part specification */
+            if (ch == '+') {
+                multi = 1;
+                l++;
+            } else
+                multi = 0;
+
+            /*
+             * Now search for the cipher alias in the ca_list. Be careful
+             * with the strncmp, because the "buflen" limitation
+             * will make the rule "ADH:SOME" and the cipher
+             * "ADH-MY-CIPHER" look like a match for buflen=3.
+             * So additionally check whether the cipher name found
+             * has the correct length. We can save a strlen() call:
+             * just checking for the '\0' at the right place is
+             * sufficient, we have to strncmp() anyway. (We cannot
+             * use strcmp(), because buf is not '\0' terminated.)
+             */
+            j = found = 0;
+            cipher_id = 0;
+            while (ca_list[j]) {
+                if (strncmp(buf, ca_list[j]->name, buflen) == 0
+                    && (ca_list[j]->name[buflen] == '\0')) {
+                    found = 1;
+                    break;
+                } else
+                    j++;
+            }
+
+            if (!found)
+                break;          /* ignore this entry */
+
+            if (ca_list[j]->algorithm_mkey) {
+                if (alg_mkey) {
+                    alg_mkey &= ca_list[j]->algorithm_mkey;
+                    if (!alg_mkey) {
+                        found = 0;
+                        break;
+                    }
+                } else
+                    alg_mkey = ca_list[j]->algorithm_mkey;
+            }
+
+            if (ca_list[j]->algorithm_auth) {
+                if (alg_auth) {
+                    alg_auth &= ca_list[j]->algorithm_auth;
+                    if (!alg_auth) {
+                        found = 0;
+                        break;
+                    }
+                } else
+                    alg_auth = ca_list[j]->algorithm_auth;
+            }
+
+            if (ca_list[j]->algorithm_enc) {
+                if (alg_enc) {
+                    alg_enc &= ca_list[j]->algorithm_enc;
+                    if (!alg_enc) {
+                        found = 0;
+                        break;
+                    }
+                } else
+                    alg_enc = ca_list[j]->algorithm_enc;
+            }
+
+            if (ca_list[j]->algorithm_mac) {
+                if (alg_mac) {
+                    alg_mac &= ca_list[j]->algorithm_mac;
+                    if (!alg_mac) {
+                        found = 0;
+                        break;
+                    }
+                } else
+                    alg_mac = ca_list[j]->algorithm_mac;
+            }
+
+            if (ca_list[j]->algo_strength & SSL_STRONG_MASK) {
+                if (algo_strength & SSL_STRONG_MASK) {
+                    algo_strength &=
+                        (ca_list[j]->algo_strength & SSL_STRONG_MASK) |
+                        ~SSL_STRONG_MASK;
+                    if (!(algo_strength & SSL_STRONG_MASK)) {
+                        found = 0;
+                        break;
+                    }
+                } else
+                    algo_strength = ca_list[j]->algo_strength & SSL_STRONG_MASK;
+            }
+
+            if (ca_list[j]->algo_strength & SSL_DEFAULT_MASK) {
+                if (algo_strength & SSL_DEFAULT_MASK) {
+                    algo_strength &=
+                        (ca_list[j]->algo_strength & SSL_DEFAULT_MASK) |
+                        ~SSL_DEFAULT_MASK;
+                    if (!(algo_strength & SSL_DEFAULT_MASK)) {
+                        found = 0;
+                        break;
+                    }
+                } else
+                    algo_strength |=
+                        ca_list[j]->algo_strength & SSL_DEFAULT_MASK;
+            }
+
+            if (ca_list[j]->valid) {
+                /*
+                 * explicit ciphersuite found; its protocol version does not
+                 * become part of the search pattern!
+                 */
+
+                cipher_id = ca_list[j]->id;
+            } else {
+                /*
+                 * not an explicit ciphersuite; only in this case, the
+                 * protocol version is considered part of the search pattern
+                 */
+
+                if (ca_list[j]->min_tls) {
+                    if (min_tls != 0 && min_tls != ca_list[j]->min_tls) {
+                        found = 0;
+                        break;
+                    } else {
+                        min_tls = ca_list[j]->min_tls;
+                    }
+                }
+            }
+
+            if (!multi)
+                break;
+        }
+
+        /*
+         * Ok, we have the rule, now apply it
+         */
+        if (rule == CIPHER_SPECIAL) { /* special command */
+            ok = 0;
+            if ((buflen == 8) && strncmp(buf, "STRENGTH", 8) == 0)
+                ok = ssl_cipher_strength_sort(head_p, tail_p);
+            else if (buflen == 10 && strncmp(buf, "SECLEVEL=", 9) == 0) {
+                int level = buf[9] - '0';
+                if (level < 0 || level > 5) {
+                    SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,
+                           SSL_R_INVALID_COMMAND);
+                } else {
+                    c->sec_level = level;
+                    ok = 1;
+                }
+            } else
+                SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_INVALID_COMMAND);
+            if (ok == 0)
+                retval = 0;
+            /*
+             * We do not support any "multi" options
+             * together with "@", so throw away the
+             * rest of the command, if any left, until
+             * end or ':' is found.
+             */
+            while ((*l != '\0') && !ITEM_SEP(*l))
+                l++;
+        } else if (found) {
+            ssl_cipher_apply_rule(cipher_id,
+                                  alg_mkey, alg_auth, alg_enc, alg_mac,
+                                  min_tls, algo_strength, rule, -1, head_p,
+                                  tail_p);
+        } else {
+            while ((*l != '\0') && !ITEM_SEP(*l))
+                l++;
+        }
+        if (*l == '\0')
+            break;              /* done */
+    }
+
+    return (retval);
+}
+
+#ifndef OPENSSL_NO_EC
+static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c,
+                                    const char **prule_str)
+{
+    unsigned int suiteb_flags = 0, suiteb_comb2 = 0;
+    if (strncmp(*prule_str, "SUITEB128ONLY", 13) == 0) {
+        suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS_ONLY;
+    } else if (strncmp(*prule_str, "SUITEB128C2", 11) == 0) {
+        suiteb_comb2 = 1;
+        suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS;
+    } else if (strncmp(*prule_str, "SUITEB128", 9) == 0) {
+        suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS;
+    } else if (strncmp(*prule_str, "SUITEB192", 9) == 0) {
+        suiteb_flags = SSL_CERT_FLAG_SUITEB_192_LOS;
+    }
+
+    if (suiteb_flags) {
+        c->cert_flags &= ~SSL_CERT_FLAG_SUITEB_128_LOS;
+        c->cert_flags |= suiteb_flags;
+    } else
+        suiteb_flags = c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS;
+
+    if (!suiteb_flags)
+        return 1;
+    /* Check version: if TLS 1.2 ciphers allowed we can use Suite B */
+
+    if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS)) {
+        SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST,
+               SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE);
+        return 0;
+    }
+# ifndef OPENSSL_NO_EC
+    switch (suiteb_flags) {
+    case SSL_CERT_FLAG_SUITEB_128_LOS:
+        if (suiteb_comb2)
+            *prule_str = "ECDHE-ECDSA-AES256-GCM-SHA384";
+        else
+            *prule_str =
+                "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384";
+        break;
+    case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY:
+        *prule_str = "ECDHE-ECDSA-AES128-GCM-SHA256";
+        break;
+    case SSL_CERT_FLAG_SUITEB_192_LOS:
+        *prule_str = "ECDHE-ECDSA-AES256-GCM-SHA384";
+        break;
+    }
+    return 1;
+# else
+    SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE);
+    return 0;
+# endif
+}
+#endif
+
+STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, STACK_OF(SSL_CIPHER)
+                                             **cipher_list, STACK_OF(SSL_CIPHER)
+                                             **cipher_list_by_id,
+                                             const char *rule_str, CERT *c)
+{
+    int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases;
+    uint32_t disabled_mkey, disabled_auth, disabled_enc, disabled_mac;
+    STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list;
+    const char *rule_p;
+    CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
+    const SSL_CIPHER **ca_list = NULL;
+
+    /*
+     * Return with error if nothing to do.
+     */
+    if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL)
+        return NULL;
+#ifndef OPENSSL_NO_EC
+    if (!check_suiteb_cipher_list(ssl_method, c, &rule_str))
+        return NULL;
+#endif
+
+    /*
+     * To reduce the work to do we only want to process the compiled
+     * in algorithms, so we first get the mask of disabled ciphers.
+     */
+
+    disabled_mkey = disabled_mkey_mask;
+    disabled_auth = disabled_auth_mask;
+    disabled_enc = disabled_enc_mask;
+    disabled_mac = disabled_mac_mask;
+
+    /*
+     * Now we have to collect the available ciphers from the compiled
+     * in ciphers. We cannot get more than the number compiled in, so
+     * it is used for allocation.
+     */
+    num_of_ciphers = ssl_method->num_ciphers();
+
+    co_list = OPENSSL_malloc(sizeof(*co_list) * num_of_ciphers);
+    if (co_list == NULL) {
+        SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
+        return (NULL);          /* Failure */
+    }
+
+    ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers,
+                               disabled_mkey, disabled_auth, disabled_enc,
+                               disabled_mac, co_list, &head, &tail);
+
+    /* Now arrange all ciphers by preference. */
+
+    /*
+     * Everything else being equal, prefer ephemeral ECDH over other key
+     * exchange mechanisms.
+     * For consistency, prefer ECDSA over RSA (though this only matters if the
+     * server has both certificates, and is using the DEFAULT, or a client
+     * preference).
+     */
+    ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, 0, 0, 0, 0, CIPHER_ADD,
+                          -1, &head, &tail);
+    ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head,
+                          &tail);
+    ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head,
+                          &tail);
+
+    /* Within each strength group, we prefer GCM over CHACHA... */
+    ssl_cipher_apply_rule(0, 0, 0, SSL_AESGCM, 0, 0, 0, CIPHER_ADD, -1,
+                          &head, &tail);
+    ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20, 0, 0, 0, CIPHER_ADD, -1,
+                          &head, &tail);
+
+    /*
+     * ...and generally, our preferred cipher is AES.
+     * Note that AEADs will be bumped to take preference after sorting by
+     * strength.
+     */
+    ssl_cipher_apply_rule(0, 0, 0, SSL_AES ^ SSL_AESGCM, 0, 0, 0, CIPHER_ADD,
+                          -1, &head, &tail);
+
+    /* Temporarily enable everything else for sorting */
+    ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
+
+    /* Low priority for MD5 */
+    ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head,
+                          &tail);
+
+    /*
+     * Move anonymous ciphers to the end.  Usually, these will remain
+     * disabled. (For applications that allow them, they aren't too bad, but
+     * we prefer authenticated ciphers.)
+     */
+    ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head,
+                          &tail);
+
+    /*
+     * ssl_cipher_apply_rule(0, 0, SSL_aDH, 0, 0, 0, 0, CIPHER_ORD, -1,
+     * &head, &tail);
+     */
+    ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head,
+                          &tail);
+    ssl_cipher_apply_rule(0, SSL_kPSK, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head,
+                          &tail);
+
+    /* RC4 is sort-of broken -- move the the end */
+    ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head,
+                          &tail);
+
+    /*
+     * Now sort by symmetric encryption strength.  The above ordering remains
+     * in force within each class
+     */
+    if (!ssl_cipher_strength_sort(&head, &tail)) {
+        OPENSSL_free(co_list);
+        return NULL;
+    }
+
+    /*
+     * Partially overrule strength sort to prefer TLS 1.2 ciphers/PRFs.
+     * TODO(openssl-team): is there an easier way to accomplish all this?
+     */
+    ssl_cipher_apply_rule(0, 0, 0, 0, 0, TLS1_2_VERSION, 0, CIPHER_BUMP, -1,
+                          &head, &tail);
+
+    /*
+     * Irrespective of strength, enforce the following order:
+     * (EC)DHE + AEAD > (EC)DHE > rest of AEAD > rest.
+     * Within each group, ciphers remain sorted by strength and previous
+     * preference, i.e.,
+     * 1) ECDHE > DHE
+     * 2) GCM > CHACHA
+     * 3) AES > rest
+     * 4) TLS 1.2 > legacy
+     *
+     * Because we now bump ciphers to the top of the list, we proceed in
+     * reverse order of preference.
+     */
+    ssl_cipher_apply_rule(0, 0, 0, 0, SSL_AEAD, 0, 0, CIPHER_BUMP, -1,
+                          &head, &tail);
+    ssl_cipher_apply_rule(0, SSL_kDHE | SSL_kECDHE, 0, 0, 0, 0, 0,
+                          CIPHER_BUMP, -1, &head, &tail);
+    ssl_cipher_apply_rule(0, SSL_kDHE | SSL_kECDHE, 0, 0, SSL_AEAD, 0, 0,
+                          CIPHER_BUMP, -1, &head, &tail);
+
+    /* Now disable everything (maintaining the ordering!) */
+    ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail);
+
+    /*
+     * We also need cipher aliases for selecting based on the rule_str.
+     * There might be two types of entries in the rule_str: 1) names
+     * of ciphers themselves 2) aliases for groups of ciphers.
+     * For 1) we need the available ciphers and for 2) the cipher
+     * groups of cipher_aliases added together in one list (otherwise
+     * we would be happy with just the cipher_aliases table).
+     */
+    num_of_group_aliases = OSSL_NELEM(cipher_aliases);
+    num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1;
+    ca_list = OPENSSL_malloc(sizeof(*ca_list) * num_of_alias_max);
+    if (ca_list == NULL) {
+        OPENSSL_free(co_list);
+        SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
+        return (NULL);          /* Failure */
+    }
+    ssl_cipher_collect_aliases(ca_list, num_of_group_aliases,
+                               disabled_mkey, disabled_auth, disabled_enc,
+                               disabled_mac, head);
+
+    /*
+     * If the rule_string begins with DEFAULT, apply the default rule
+     * before using the (possibly available) additional rules.
+     */
+    ok = 1;
+    rule_p = rule_str;
+    if (strncmp(rule_str, "DEFAULT", 7) == 0) {
+        ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST,
+                                        &head, &tail, ca_list, c);
+        rule_p += 7;
+        if (*rule_p == ':')
+            rule_p++;
+    }
+
+    if (ok && (strlen(rule_p) > 0))
+        ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list, c);
+
+    OPENSSL_free(ca_list);      /* Not needed anymore */
+
+    if (!ok) {                  /* Rule processing failure */
+        OPENSSL_free(co_list);
+        return (NULL);
+    }
+
+    /*
+     * Allocate new "cipherstack" for the result, return with error
+     * if we cannot get one.
+     */
+    if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) {
+        OPENSSL_free(co_list);
+        return (NULL);
+    }
+
+    /*
+     * The cipher selection for the list is done. The ciphers are added
+     * to the resulting precedence to the STACK_OF(SSL_CIPHER).
+     */
+    for (curr = head; curr != NULL; curr = curr->next) {
+        if (curr->active
+            && (!FIPS_mode() || curr->cipher->algo_strength & SSL_FIPS)) {
+            if (!sk_SSL_CIPHER_push(cipherstack, curr->cipher)) {
+                OPENSSL_free(co_list);
+                sk_SSL_CIPHER_free(cipherstack);
+                return NULL;
+            }
+#ifdef CIPHER_DEBUG
+            fprintf(stderr, "<%s>\n", curr->cipher->name);
+#endif
+        }
+    }
+    OPENSSL_free(co_list);      /* Not needed any longer */
+
+    tmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack);
+    if (tmp_cipher_list == NULL) {
+        sk_SSL_CIPHER_free(cipherstack);
+        return NULL;
+    }
+    sk_SSL_CIPHER_free(*cipher_list);
+    *cipher_list = cipherstack;
+    if (*cipher_list_by_id != NULL)
+        sk_SSL_CIPHER_free(*cipher_list_by_id);
+    *cipher_list_by_id = tmp_cipher_list;
+    (void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id, ssl_cipher_ptr_id_cmp);
+
+    sk_SSL_CIPHER_sort(*cipher_list_by_id);
+    return (cipherstack);
+}
+
+char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
+{
+    const char *ver;
+    const char *kx, *au, *enc, *mac;
+    uint32_t alg_mkey, alg_auth, alg_enc, alg_mac;
+    static const char *format = "%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n";
+
+    if (buf == NULL) {
+        len = 128;
+        buf = OPENSSL_malloc(len);
+        if (buf == NULL)
+            return NULL;
+    } else if (len < 128)
+        return NULL;
+
+    alg_mkey = cipher->algorithm_mkey;
+    alg_auth = cipher->algorithm_auth;
+    alg_enc = cipher->algorithm_enc;
+    alg_mac = cipher->algorithm_mac;
+
+    ver = ssl_protocol_to_string(cipher->min_tls);
+
+    switch (alg_mkey) {
+    case SSL_kRSA:
+        kx = "RSA";
+        break;
+    case SSL_kDHE:
+        kx = "DH";
+        break;
+    case SSL_kECDHE:
+        kx = "ECDH";
+        break;
+    case SSL_kPSK:
+        kx = "PSK";
+        break;
+    case SSL_kRSAPSK:
+        kx = "RSAPSK";
+        break;
+    case SSL_kECDHEPSK:
+        kx = "ECDHEPSK";
+        break;
+    case SSL_kDHEPSK:
+        kx = "DHEPSK";
+        break;
+    case SSL_kSRP:
+        kx = "SRP";
+        break;
+    case SSL_kGOST:
+        kx = "GOST";
+        break;
+    default:
+        kx = "unknown";
+    }
+
+    switch (alg_auth) {
+    case SSL_aRSA:
+        au = "RSA";
+        break;
+    case SSL_aDSS:
+        au = "DSS";
+        break;
+    case SSL_aNULL:
+        au = "None";
+        break;
+    case SSL_aECDSA:
+        au = "ECDSA";
+        break;
+    case SSL_aPSK:
+        au = "PSK";
+        break;
+    case SSL_aSRP:
+        au = "SRP";
+        break;
+    case SSL_aGOST01:
+        au = "GOST01";
+        break;
+        /* New GOST ciphersuites have both SSL_aGOST12 and SSL_aGOST01 bits */
+    case (SSL_aGOST12 | SSL_aGOST01):
+        au = "GOST12";
+        break;
+    default:
+        au = "unknown";
+        break;
+    }
+
+    switch (alg_enc) {
+    case SSL_DES:
+        enc = "DES(56)";
+        break;
+    case SSL_3DES:
+        enc = "3DES(168)";
+        break;
+    case SSL_RC4:
+        enc = "RC4(128)";
+        break;
+    case SSL_RC2:
+        enc = "RC2(128)";
+        break;
+    case SSL_IDEA:
+        enc = "IDEA(128)";
+        break;
+    case SSL_eNULL:
+        enc = "None";
+        break;
+    case SSL_AES128:
+        enc = "AES(128)";
+        break;
+    case SSL_AES256:
+        enc = "AES(256)";
+        break;
+    case SSL_AES128GCM:
+        enc = "AESGCM(128)";
+        break;
+    case SSL_AES256GCM:
+        enc = "AESGCM(256)";
+        break;
+    case SSL_AES128CCM:
+        enc = "AESCCM(128)";
+        break;
+    case SSL_AES256CCM:
+        enc = "AESCCM(256)";
+        break;
+    case SSL_AES128CCM8:
+        enc = "AESCCM8(128)";
+        break;
+    case SSL_AES256CCM8:
+        enc = "AESCCM8(256)";
+        break;
+    case SSL_CAMELLIA128:
+        enc = "Camellia(128)";
+        break;
+    case SSL_CAMELLIA256:
+        enc = "Camellia(256)";
+        break;
+    case SSL_SEED:
+        enc = "SEED(128)";
+        break;
+    case SSL_eGOST2814789CNT:
+    case SSL_eGOST2814789CNT12:
+        enc = "GOST89(256)";
+        break;
+    case SSL_CHACHA20POLY1305:
+        enc = "CHACHA20/POLY1305(256)";
+        break;
+    default:
+        enc = "unknown";
+        break;
+    }
+
+    switch (alg_mac) {
+    case SSL_MD5:
+        mac = "MD5";
+        break;
+    case SSL_SHA1:
+        mac = "SHA1";
+        break;
+    case SSL_SHA256:
+        mac = "SHA256";
+        break;
+    case SSL_SHA384:
+        mac = "SHA384";
+        break;
+    case SSL_AEAD:
+        mac = "AEAD";
+        break;
+    case SSL_GOST89MAC:
+    case SSL_GOST89MAC12:
+        mac = "GOST89";
+        break;
+    case SSL_GOST94:
+        mac = "GOST94";
+        break;
+    case SSL_GOST12_256:
+    case SSL_GOST12_512:
+        mac = "GOST2012";
+        break;
+    default:
+        mac = "unknown";
+        break;
+    }
+
+    BIO_snprintf(buf, len, format, cipher->name, ver, kx, au, enc, mac);
+
+    return (buf);
+}
+
+const char *SSL_CIPHER_get_version(const SSL_CIPHER *c)
+{
+    if (c == NULL)
+        return "(NONE)";
+
+    /*
+     * Backwards-compatibility crutch.  In almost all contexts we report TLS
+     * 1.0 as "TLSv1", but for ciphers we report "TLSv1.0".
+     */
+    if (c->min_tls == TLS1_VERSION)
+        return "TLSv1.0";
+    return ssl_protocol_to_string(c->min_tls);
+}
+
+/* return the actual cipher being used */
+const char *SSL_CIPHER_get_name(const SSL_CIPHER *c)
+{
+    if (c != NULL)
+        return (c->name);
+    return ("(NONE)");
+}
+
+/* number of bits for symmetric cipher */
+int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits)
+{
+    int ret = 0;
+
+    if (c != NULL) {
+        if (alg_bits != NULL)
+            *alg_bits = (int)c->alg_bits;
+        ret = (int)c->strength_bits;
+    }
+    return ret;
+}
+
+uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *c)
+{
+    return c->id;
+}
+
+SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n)
+{
+    SSL_COMP *ctmp;
+    int i, nn;
+
+    if ((n == 0) || (sk == NULL))
+        return (NULL);
+    nn = sk_SSL_COMP_num(sk);
+    for (i = 0; i < nn; i++) {
+        ctmp = sk_SSL_COMP_value(sk, i);
+        if (ctmp->id == n)
+            return (ctmp);
+    }
+    return (NULL);
+}
+
+#ifdef OPENSSL_NO_COMP
+STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void)
+{
+    return NULL;
+}
+
+STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP)
+                                                      *meths)
+{
+    return meths;
+}
+
+int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm)
+{
+    return 1;
+}
+
+#else
+STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void)
+{
+    load_builtin_compressions();
+    return (ssl_comp_methods);
+}
+
+STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP)
+                                                      *meths)
+{
+    STACK_OF(SSL_COMP) *old_meths = ssl_comp_methods;
+    ssl_comp_methods = meths;
+    return old_meths;
+}
+
+static void cmeth_free(SSL_COMP *cm)
+{
+    OPENSSL_free(cm);
+}
+
+void ssl_comp_free_compression_methods_int(void)
+{
+    STACK_OF(SSL_COMP) *old_meths = ssl_comp_methods;
+    ssl_comp_methods = NULL;
+    sk_SSL_COMP_pop_free(old_meths, cmeth_free);
+}
+
+int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm)
+{
+    SSL_COMP *comp;
+
+    if (cm == NULL || COMP_get_type(cm) == NID_undef)
+        return 1;
+
+    /*-
+     * According to draft-ietf-tls-compression-04.txt, the
+     * compression number ranges should be the following:
+     *
+     *   0 to  63:  methods defined by the IETF
+     *  64 to 192:  external party methods assigned by IANA
+     * 193 to 255:  reserved for private use
+     */
+    if (id < 193 || id > 255) {
+        SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,
+               SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE);
+        return 1;
+    }
+
+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
+    comp = OPENSSL_malloc(sizeof(*comp));
+    if (comp == NULL) {
+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
+        SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, ERR_R_MALLOC_FAILURE);
+        return (1);
+    }
+
+    comp->id = id;
+    comp->method = cm;
+    load_builtin_compressions();
+    if (ssl_comp_methods && sk_SSL_COMP_find(ssl_comp_methods, comp) >= 0) {
+        OPENSSL_free(comp);
+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
+        SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,
+               SSL_R_DUPLICATE_COMPRESSION_ID);
+        return (1);
+    }
+    if (ssl_comp_methods == NULL || !sk_SSL_COMP_push(ssl_comp_methods, comp)) {
+        OPENSSL_free(comp);
+        CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
+        SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, ERR_R_MALLOC_FAILURE);
+        return (1);
+    }
+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
+    return (0);
+}
+#endif
+
+const char *SSL_COMP_get_name(const COMP_METHOD *comp)
+{
+#ifndef OPENSSL_NO_COMP
+    return comp ? COMP_get_name(comp) : NULL;
+#else
+    return NULL;
+#endif
+}
+
+const char *SSL_COMP_get0_name(const SSL_COMP *comp)
+{
+#ifndef OPENSSL_NO_COMP
+    return comp->name;
+#else
+    return NULL;
+#endif
+}
+
+int SSL_COMP_get_id(const SSL_COMP *comp)
+{
+#ifndef OPENSSL_NO_COMP
+    return comp->id;
+#else
+    return -1;
+#endif
+}
+
+/* For a cipher return the index corresponding to the certificate type */
+int ssl_cipher_get_cert_index(const SSL_CIPHER *c)
+{
+    uint32_t alg_a;
+
+    alg_a = c->algorithm_auth;
+
+    if (alg_a & SSL_aECDSA)
+        return SSL_PKEY_ECC;
+    else if (alg_a & SSL_aDSS)
+        return SSL_PKEY_DSA_SIGN;
+    else if (alg_a & SSL_aRSA)
+        return SSL_PKEY_RSA_ENC;
+    else if (alg_a & SSL_aGOST12)
+        return SSL_PKEY_GOST_EC;
+    else if (alg_a & SSL_aGOST01)
+        return SSL_PKEY_GOST01;
+
+    return -1;
+}
+
+const SSL_CIPHER *ssl_get_cipher_by_char(SSL *ssl, const unsigned char *ptr)
+{
+    const SSL_CIPHER *c = ssl->method->get_cipher_by_char(ptr);
+
+    if (c == NULL || c->valid == 0)
+        return NULL;
+    return c;
+}
+
+const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr)
+{
+    return ssl->method->get_cipher_by_char(ptr);
+}
+
+int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *c)
+{
+    int i;
+    if (c == NULL)
+        return NID_undef;
+    i = ssl_cipher_info_lookup(ssl_cipher_table_cipher, c->algorithm_enc);
+    if (i == -1)
+        return NID_undef;
+    return ssl_cipher_table_cipher[i].nid;
+}
+
+int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *c)
+{
+    int i = ssl_cipher_info_lookup(ssl_cipher_table_mac, c->algorithm_mac);
+
+    if (i == -1)
+        return NID_undef;
+    return ssl_cipher_table_mac[i].nid;
+}
+
+int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *c)
+{
+    int i = ssl_cipher_info_lookup(ssl_cipher_table_kx, c->algorithm_mkey);
+
+    if (i == -1)
+        return NID_undef;
+    return ssl_cipher_table_kx[i].nid;
+}
+
+int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *c)
+{
+    int i = ssl_cipher_info_lookup(ssl_cipher_table_auth, c->algorithm_auth);
+
+    if (i == -1)
+        return NID_undef;
+    return ssl_cipher_table_auth[i].nid;
+}
+
+int SSL_CIPHER_is_aead(const SSL_CIPHER *c)
+{
+    return (c->algorithm_mac & SSL_AEAD) ? 1 : 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_conf.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_conf.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_conf.c	(revision 331)
@@ -0,0 +1,880 @@
+/*
+ * Copyright 2012-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 <stdio.h>
+#include "ssl_locl.h"
+#include <openssl/conf.h>
+#include <openssl/objects.h>
+#include <openssl/dh.h>
+
+/*
+ * structure holding name tables. This is used for permitted elements in lists
+ * such as TLSv1.
+ */
+
+typedef struct {
+    const char *name;
+    int namelen;
+    unsigned int name_flags;
+    unsigned long option_value;
+} ssl_flag_tbl;
+
+/* Switch table: use for single command line switches like no_tls2 */
+typedef struct {
+    unsigned long option_value;
+    unsigned int name_flags;
+} ssl_switch_tbl;
+
+/* Sense of name is inverted e.g. "TLSv1" will clear SSL_OP_NO_TLSv1 */
+#define SSL_TFLAG_INV   0x1
+/* Mask for type of flag referred to */
+#define SSL_TFLAG_TYPE_MASK 0xf00
+/* Flag is for options */
+#define SSL_TFLAG_OPTION    0x000
+/* Flag is for cert_flags */
+#define SSL_TFLAG_CERT      0x100
+/* Flag is for verify mode */
+#define SSL_TFLAG_VFY       0x200
+/* Option can only be used for clients */
+#define SSL_TFLAG_CLIENT SSL_CONF_FLAG_CLIENT
+/* Option can only be used for servers */
+#define SSL_TFLAG_SERVER SSL_CONF_FLAG_SERVER
+#define SSL_TFLAG_BOTH (SSL_TFLAG_CLIENT|SSL_TFLAG_SERVER)
+
+#define SSL_FLAG_TBL(str, flag) \
+        {str, (int)(sizeof(str) - 1), SSL_TFLAG_BOTH, flag}
+#define SSL_FLAG_TBL_SRV(str, flag) \
+        {str, (int)(sizeof(str) - 1), SSL_TFLAG_SERVER, flag}
+#define SSL_FLAG_TBL_CLI(str, flag) \
+        {str, (int)(sizeof(str) - 1), SSL_TFLAG_CLIENT, flag}
+#define SSL_FLAG_TBL_INV(str, flag) \
+        {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_BOTH, flag}
+#define SSL_FLAG_TBL_SRV_INV(str, flag) \
+        {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_SERVER, flag}
+#define SSL_FLAG_TBL_CERT(str, flag) \
+        {str, (int)(sizeof(str) - 1), SSL_TFLAG_CERT|SSL_TFLAG_BOTH, flag}
+
+#define SSL_FLAG_VFY_CLI(str, flag) \
+        {str, (int)(sizeof(str) - 1), SSL_TFLAG_VFY | SSL_TFLAG_CLIENT, flag}
+#define SSL_FLAG_VFY_SRV(str, flag) \
+        {str, (int)(sizeof(str) - 1), SSL_TFLAG_VFY | SSL_TFLAG_SERVER, flag}
+
+/*
+ * Opaque structure containing SSL configuration context.
+ */
+
+struct ssl_conf_ctx_st {
+    /*
+     * Various flags indicating (among other things) which options we will
+     * recognise.
+     */
+    unsigned int flags;
+    /* Prefix and length of commands */
+    char *prefix;
+    size_t prefixlen;
+    /* SSL_CTX or SSL structure to perform operations on */
+    SSL_CTX *ctx;
+    SSL *ssl;
+    /* Pointer to SSL or SSL_CTX options field or NULL if none */
+    uint32_t *poptions;
+    /* Certificate filenames for each type */
+    char *cert_filename[SSL_PKEY_NUM];
+    /* Pointer to SSL or SSL_CTX cert_flags or NULL if none */
+    uint32_t *pcert_flags;
+    /* Pointer to SSL or SSL_CTX verify_mode or NULL if none */
+    uint32_t *pvfy_flags;
+    /* Pointer to SSL or SSL_CTX min_version field or NULL if none */
+    int *min_version;
+    /* Pointer to SSL or SSL_CTX max_version field or NULL if none */
+    int *max_version;
+    /* Current flag table being worked on */
+    const ssl_flag_tbl *tbl;
+    /* Size of table */
+    size_t ntbl;
+    /* Client CA names */
+    STACK_OF(X509_NAME) *canames;
+};
+
+static void ssl_set_option(SSL_CONF_CTX *cctx, unsigned int name_flags,
+                           unsigned long option_value, int onoff)
+{
+    uint32_t *pflags;
+    if (cctx->poptions == NULL)
+        return;
+    if (name_flags & SSL_TFLAG_INV)
+        onoff ^= 1;
+    switch (name_flags & SSL_TFLAG_TYPE_MASK) {
+
+    case SSL_TFLAG_CERT:
+        pflags = cctx->pcert_flags;
+        break;
+
+    case SSL_TFLAG_VFY:
+        pflags = cctx->pvfy_flags;
+        break;
+
+    case SSL_TFLAG_OPTION:
+        pflags = cctx->poptions;
+        break;
+
+    default:
+        return;
+
+    }
+    if (onoff)
+        *pflags |= option_value;
+    else
+        *pflags &= ~option_value;
+}
+
+static int ssl_match_option(SSL_CONF_CTX *cctx, const ssl_flag_tbl *tbl,
+                            const char *name, int namelen, int onoff)
+{
+    /* If name not relevant for context skip */
+    if (!(cctx->flags & tbl->name_flags & SSL_TFLAG_BOTH))
+        return 0;
+    if (namelen == -1) {
+        if (strcmp(tbl->name, name))
+            return 0;
+    } else if (tbl->namelen != namelen || strncasecmp(tbl->name, name, namelen))
+        return 0;
+    ssl_set_option(cctx, tbl->name_flags, tbl->option_value, onoff);
+    return 1;
+}
+
+static int ssl_set_option_list(const char *elem, int len, void *usr)
+{
+    SSL_CONF_CTX *cctx = usr;
+    size_t i;
+    const ssl_flag_tbl *tbl;
+    int onoff = 1;
+    /*
+     * len == -1 indicates not being called in list context, just for single
+     * command line switches, so don't allow +, -.
+     */
+    if (elem == NULL)
+        return 0;
+    if (len != -1) {
+        if (*elem == '+') {
+            elem++;
+            len--;
+            onoff = 1;
+        } else if (*elem == '-') {
+            elem++;
+            len--;
+            onoff = 0;
+        }
+    }
+    for (i = 0, tbl = cctx->tbl; i < cctx->ntbl; i++, tbl++) {
+        if (ssl_match_option(cctx, tbl, elem, len, onoff))
+            return 1;
+    }
+    return 0;
+}
+
+/* Set supported signature algorithms */
+static int cmd_SignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value)
+{
+    int rv;
+    if (cctx->ssl)
+        rv = SSL_set1_sigalgs_list(cctx->ssl, value);
+    /* NB: ctx == NULL performs syntax checking only */
+    else
+        rv = SSL_CTX_set1_sigalgs_list(cctx->ctx, value);
+    return rv > 0;
+}
+
+/* Set supported client signature algorithms */
+static int cmd_ClientSignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value)
+{
+    int rv;
+    if (cctx->ssl)
+        rv = SSL_set1_client_sigalgs_list(cctx->ssl, value);
+    /* NB: ctx == NULL performs syntax checking only */
+    else
+        rv = SSL_CTX_set1_client_sigalgs_list(cctx->ctx, value);
+    return rv > 0;
+}
+
+static int cmd_Curves(SSL_CONF_CTX *cctx, const char *value)
+{
+    int rv;
+    if (cctx->ssl)
+        rv = SSL_set1_curves_list(cctx->ssl, value);
+    /* NB: ctx == NULL performs syntax checking only */
+    else
+        rv = SSL_CTX_set1_curves_list(cctx->ctx, value);
+    return rv > 0;
+}
+
+#ifndef OPENSSL_NO_EC
+/* ECDH temporary parameters */
+static int cmd_ECDHParameters(SSL_CONF_CTX *cctx, const char *value)
+{
+    int rv = 1;
+    EC_KEY *ecdh;
+    int nid;
+
+    nid = EC_curve_nist2nid(value);
+    if (nid == NID_undef)
+        nid = OBJ_sn2nid(value);
+    if (nid == 0)
+        return 0;
+    ecdh = EC_KEY_new_by_curve_name(nid);
+    if (!ecdh)
+        return 0;
+    if (cctx->ctx)
+        rv = SSL_CTX_set_tmp_ecdh(cctx->ctx, ecdh);
+    else if (cctx->ssl)
+        rv = SSL_set_tmp_ecdh(cctx->ssl, ecdh);
+    EC_KEY_free(ecdh);
+
+    return rv > 0;
+}
+#endif
+static int cmd_CipherString(SSL_CONF_CTX *cctx, const char *value)
+{
+    int rv = 1;
+    if (cctx->ctx)
+        rv = SSL_CTX_set_cipher_list(cctx->ctx, value);
+    if (cctx->ssl)
+        rv = SSL_set_cipher_list(cctx->ssl, value);
+    return rv > 0;
+}
+
+static int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value)
+{
+    static const ssl_flag_tbl ssl_protocol_list[] = {
+        SSL_FLAG_TBL_INV("ALL", SSL_OP_NO_SSL_MASK),
+        SSL_FLAG_TBL_INV("SSLv2", SSL_OP_NO_SSLv2),
+        SSL_FLAG_TBL_INV("SSLv3", SSL_OP_NO_SSLv3),
+        SSL_FLAG_TBL_INV("TLSv1", SSL_OP_NO_TLSv1),
+        SSL_FLAG_TBL_INV("TLSv1.1", SSL_OP_NO_TLSv1_1),
+        SSL_FLAG_TBL_INV("TLSv1.2", SSL_OP_NO_TLSv1_2),
+        SSL_FLAG_TBL_INV("DTLSv1", SSL_OP_NO_DTLSv1),
+        SSL_FLAG_TBL_INV("DTLSv1.2", SSL_OP_NO_DTLSv1_2)
+    };
+    cctx->tbl = ssl_protocol_list;
+    cctx->ntbl = OSSL_NELEM(ssl_protocol_list);
+    return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
+}
+
+/*
+ * protocol_from_string - converts a protocol version string to a number
+ *
+ * Returns -1 on failure or the version on success
+ */
+static int protocol_from_string(const char *value)
+{
+    struct protocol_versions {
+        const char *name;
+        int version;
+    };
+    static const struct protocol_versions versions[] = {
+        {"None", 0},
+        {"SSLv3", SSL3_VERSION},
+        {"TLSv1", TLS1_VERSION},
+        {"TLSv1.1", TLS1_1_VERSION},
+        {"TLSv1.2", TLS1_2_VERSION},
+        {"DTLSv1", DTLS1_VERSION},
+        {"DTLSv1.2", DTLS1_2_VERSION}
+    };
+    size_t i;
+    size_t n = OSSL_NELEM(versions);
+
+    for (i = 0; i < n; i++)
+        if (strcmp(versions[i].name, value) == 0)
+            return versions[i].version;
+    return -1;
+}
+
+static int min_max_proto(SSL_CONF_CTX *cctx, const char *value, int *bound)
+{
+    int method_version;
+    int new_version;
+
+    if (cctx->ctx != NULL)
+        method_version = cctx->ctx->method->version;
+    else if (cctx->ssl != NULL)
+        method_version = cctx->ssl->ctx->method->version;
+    else
+        return 0;
+    if ((new_version = protocol_from_string(value)) < 0)
+        return 0;
+    return ssl_set_version_bound(method_version, new_version, bound);
+}
+
+/*
+ * cmd_MinProtocol - Set min protocol version
+ * @cctx: config structure to save settings in
+ * @value: The min protocol version in string form
+ *
+ * Returns 1 on success and 0 on failure.
+ */
+static int cmd_MinProtocol(SSL_CONF_CTX *cctx, const char *value)
+{
+    return min_max_proto(cctx, value, cctx->min_version);
+}
+
+/*
+ * cmd_MaxProtocol - Set max protocol version
+ * @cctx: config structure to save settings in
+ * @value: The max protocol version in string form
+ *
+ * Returns 1 on success and 0 on failure.
+ */
+static int cmd_MaxProtocol(SSL_CONF_CTX *cctx, const char *value)
+{
+    return min_max_proto(cctx, value, cctx->max_version);
+}
+
+static int cmd_Options(SSL_CONF_CTX *cctx, const char *value)
+{
+    static const ssl_flag_tbl ssl_option_list[] = {
+        SSL_FLAG_TBL_INV("SessionTicket", SSL_OP_NO_TICKET),
+        SSL_FLAG_TBL_INV("EmptyFragments",
+                         SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS),
+        SSL_FLAG_TBL("Bugs", SSL_OP_ALL),
+        SSL_FLAG_TBL_INV("Compression", SSL_OP_NO_COMPRESSION),
+        SSL_FLAG_TBL_SRV("ServerPreference", SSL_OP_CIPHER_SERVER_PREFERENCE),
+        SSL_FLAG_TBL_SRV("NoResumptionOnRenegotiation",
+                         SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION),
+        SSL_FLAG_TBL_SRV("DHSingle", SSL_OP_SINGLE_DH_USE),
+        SSL_FLAG_TBL_SRV("ECDHSingle", SSL_OP_SINGLE_ECDH_USE),
+        SSL_FLAG_TBL("UnsafeLegacyRenegotiation",
+                     SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION),
+    };
+    if (value == NULL)
+        return -3;
+    cctx->tbl = ssl_option_list;
+    cctx->ntbl = OSSL_NELEM(ssl_option_list);
+    return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
+}
+
+static int cmd_VerifyMode(SSL_CONF_CTX *cctx, const char *value)
+{
+    static const ssl_flag_tbl ssl_vfy_list[] = {
+        SSL_FLAG_VFY_CLI("Peer", SSL_VERIFY_PEER),
+        SSL_FLAG_VFY_SRV("Request", SSL_VERIFY_PEER),
+        SSL_FLAG_VFY_SRV("Require",
+                         SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT),
+        SSL_FLAG_VFY_SRV("Once", SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE)
+    };
+    if (value == NULL)
+        return -3;
+    cctx->tbl = ssl_vfy_list;
+    cctx->ntbl = OSSL_NELEM(ssl_vfy_list);
+    return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx);
+}
+
+static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value)
+{
+    int rv = 1;
+    CERT *c = NULL;
+    if (cctx->ctx) {
+        rv = SSL_CTX_use_certificate_chain_file(cctx->ctx, value);
+        c = cctx->ctx->cert;
+    }
+    if (cctx->ssl) {
+        rv = SSL_use_certificate_chain_file(cctx->ssl, value);
+        c = cctx->ssl->cert;
+    }
+    if (rv > 0 && c && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) {
+        char **pfilename = &cctx->cert_filename[c->key - c->pkeys];
+        OPENSSL_free(*pfilename);
+        *pfilename = OPENSSL_strdup(value);
+        if (!*pfilename)
+            rv = 0;
+    }
+
+    return rv > 0;
+}
+
+static int cmd_PrivateKey(SSL_CONF_CTX *cctx, const char *value)
+{
+    int rv = 1;
+    if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE))
+        return -2;
+    if (cctx->ctx)
+        rv = SSL_CTX_use_PrivateKey_file(cctx->ctx, value, SSL_FILETYPE_PEM);
+    if (cctx->ssl)
+        rv = SSL_use_PrivateKey_file(cctx->ssl, value, SSL_FILETYPE_PEM);
+    return rv > 0;
+}
+
+static int cmd_ServerInfoFile(SSL_CONF_CTX *cctx, const char *value)
+{
+    int rv = 1;
+    if (cctx->ctx)
+        rv = SSL_CTX_use_serverinfo_file(cctx->ctx, value);
+    return rv > 0;
+}
+
+static int do_store(SSL_CONF_CTX *cctx,
+                    const char *CAfile, const char *CApath, int verify_store)
+{
+    CERT *cert;
+    X509_STORE **st;
+    if (cctx->ctx)
+        cert = cctx->ctx->cert;
+    else if (cctx->ssl)
+        cert = cctx->ssl->cert;
+    else
+        return 1;
+    st = verify_store ? &cert->verify_store : &cert->chain_store;
+    if (*st == NULL) {
+        *st = X509_STORE_new();
+        if (*st == NULL)
+            return 0;
+    }
+    return X509_STORE_load_locations(*st, CAfile, CApath) > 0;
+}
+
+static int cmd_ChainCAPath(SSL_CONF_CTX *cctx, const char *value)
+{
+    return do_store(cctx, NULL, value, 0);
+}
+
+static int cmd_ChainCAFile(SSL_CONF_CTX *cctx, const char *value)
+{
+    return do_store(cctx, value, NULL, 0);
+}
+
+static int cmd_VerifyCAPath(SSL_CONF_CTX *cctx, const char *value)
+{
+    return do_store(cctx, NULL, value, 1);
+}
+
+static int cmd_VerifyCAFile(SSL_CONF_CTX *cctx, const char *value)
+{
+    return do_store(cctx, value, NULL, 1);
+}
+
+static int cmd_ClientCAFile(SSL_CONF_CTX *cctx, const char *value)
+{
+    if (cctx->canames == NULL)
+        cctx->canames = sk_X509_NAME_new_null();
+    if (cctx->canames == NULL)
+        return 0;
+    return SSL_add_file_cert_subjects_to_stack(cctx->canames, value);
+}
+
+static int cmd_ClientCAPath(SSL_CONF_CTX *cctx, const char *value)
+{
+    if (cctx->canames == NULL)
+        cctx->canames = sk_X509_NAME_new_null();
+    if (cctx->canames == NULL)
+        return 0;
+    return SSL_add_dir_cert_subjects_to_stack(cctx->canames, value);
+}
+
+#ifndef OPENSSL_NO_DH
+static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value)
+{
+    int rv = 0;
+    DH *dh = NULL;
+    BIO *in = NULL;
+    if (cctx->ctx || cctx->ssl) {
+        in = BIO_new(BIO_s_file());
+        if (in == NULL)
+            goto end;
+        if (BIO_read_filename(in, value) <= 0)
+            goto end;
+        dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
+        if (dh == NULL)
+            goto end;
+    } else
+        return 1;
+    if (cctx->ctx)
+        rv = SSL_CTX_set_tmp_dh(cctx->ctx, dh);
+    if (cctx->ssl)
+        rv = SSL_set_tmp_dh(cctx->ssl, dh);
+ end:
+    DH_free(dh);
+    BIO_free(in);
+    return rv > 0;
+}
+#endif
+typedef struct {
+    int (*cmd) (SSL_CONF_CTX *cctx, const char *value);
+    const char *str_file;
+    const char *str_cmdline;
+    unsigned short flags;
+    unsigned short value_type;
+} ssl_conf_cmd_tbl;
+
+/* Table of supported parameters */
+
+#define SSL_CONF_CMD(name, cmdopt, flags, type) \
+        {cmd_##name, #name, cmdopt, flags, type}
+
+#define SSL_CONF_CMD_STRING(name, cmdopt, flags) \
+        SSL_CONF_CMD(name, cmdopt, flags, SSL_CONF_TYPE_STRING)
+
+#define SSL_CONF_CMD_SWITCH(name, flags) \
+        {0, NULL, name, flags, SSL_CONF_TYPE_NONE}
+
+/* See apps/apps.h if you change this table. */
+static const ssl_conf_cmd_tbl ssl_conf_cmds[] = {
+    SSL_CONF_CMD_SWITCH("no_ssl3", 0),
+    SSL_CONF_CMD_SWITCH("no_tls1", 0),
+    SSL_CONF_CMD_SWITCH("no_tls1_1", 0),
+    SSL_CONF_CMD_SWITCH("no_tls1_2", 0),
+    SSL_CONF_CMD_SWITCH("bugs", 0),
+    SSL_CONF_CMD_SWITCH("no_comp", 0),
+    SSL_CONF_CMD_SWITCH("comp", 0),
+    SSL_CONF_CMD_SWITCH("ecdh_single", SSL_CONF_FLAG_SERVER),
+    SSL_CONF_CMD_SWITCH("no_ticket", 0),
+    SSL_CONF_CMD_SWITCH("serverpref", SSL_CONF_FLAG_SERVER),
+    SSL_CONF_CMD_SWITCH("legacy_renegotiation", 0),
+    SSL_CONF_CMD_SWITCH("legacy_server_connect", SSL_CONF_FLAG_SERVER),
+    SSL_CONF_CMD_SWITCH("no_resumption_on_reneg", SSL_CONF_FLAG_SERVER),
+    SSL_CONF_CMD_SWITCH("no_legacy_server_connect", SSL_CONF_FLAG_SERVER),
+    SSL_CONF_CMD_SWITCH("strict", 0),
+    SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs", 0),
+    SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs", 0),
+    SSL_CONF_CMD_STRING(Curves, "curves", 0),
+#ifndef OPENSSL_NO_EC
+    SSL_CONF_CMD_STRING(ECDHParameters, "named_curve", SSL_CONF_FLAG_SERVER),
+#endif
+    SSL_CONF_CMD_STRING(CipherString, "cipher", 0),
+    SSL_CONF_CMD_STRING(Protocol, NULL, 0),
+    SSL_CONF_CMD_STRING(MinProtocol, "min_protocol", 0),
+    SSL_CONF_CMD_STRING(MaxProtocol, "max_protocol", 0),
+    SSL_CONF_CMD_STRING(Options, NULL, 0),
+    SSL_CONF_CMD_STRING(VerifyMode, NULL, 0),
+    SSL_CONF_CMD(Certificate, "cert", SSL_CONF_FLAG_CERTIFICATE,
+                 SSL_CONF_TYPE_FILE),
+    SSL_CONF_CMD(PrivateKey, "key", SSL_CONF_FLAG_CERTIFICATE,
+                 SSL_CONF_TYPE_FILE),
+    SSL_CONF_CMD(ServerInfoFile, NULL,
+                 SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
+                 SSL_CONF_TYPE_FILE),
+    SSL_CONF_CMD(ChainCAPath, "chainCApath", SSL_CONF_FLAG_CERTIFICATE,
+                 SSL_CONF_TYPE_DIR),
+    SSL_CONF_CMD(ChainCAFile, "chainCAfile", SSL_CONF_FLAG_CERTIFICATE,
+                 SSL_CONF_TYPE_FILE),
+    SSL_CONF_CMD(VerifyCAPath, "verifyCApath", SSL_CONF_FLAG_CERTIFICATE,
+                 SSL_CONF_TYPE_DIR),
+    SSL_CONF_CMD(VerifyCAFile, "verifyCAfile", SSL_CONF_FLAG_CERTIFICATE,
+                 SSL_CONF_TYPE_FILE),
+    SSL_CONF_CMD(ClientCAFile, NULL,
+                 SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
+                 SSL_CONF_TYPE_FILE),
+    SSL_CONF_CMD(ClientCAPath, NULL,
+                 SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
+                 SSL_CONF_TYPE_DIR),
+#ifndef OPENSSL_NO_DH
+    SSL_CONF_CMD(DHParameters, "dhparam",
+                 SSL_CONF_FLAG_SERVER | SSL_CONF_FLAG_CERTIFICATE,
+                 SSL_CONF_TYPE_FILE)
+#endif
+};
+
+/* Supported switches: must match order of switches in ssl_conf_cmds */
+static const ssl_switch_tbl ssl_cmd_switches[] = {
+    {SSL_OP_NO_SSLv3, 0},       /* no_ssl3 */
+    {SSL_OP_NO_TLSv1, 0},       /* no_tls1 */
+    {SSL_OP_NO_TLSv1_1, 0},     /* no_tls1_1 */
+    {SSL_OP_NO_TLSv1_2, 0},     /* no_tls1_2 */
+    {SSL_OP_ALL, 0},            /* bugs */
+    {SSL_OP_NO_COMPRESSION, 0}, /* no_comp */
+    {SSL_OP_NO_COMPRESSION, SSL_TFLAG_INV}, /* comp */
+    {SSL_OP_SINGLE_ECDH_USE, 0}, /* ecdh_single */
+    {SSL_OP_NO_TICKET, 0},      /* no_ticket */
+    {SSL_OP_CIPHER_SERVER_PREFERENCE, 0}, /* serverpref */
+    /* legacy_renegotiation */
+    {SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION, 0},
+    /* legacy_server_connect */
+    {SSL_OP_LEGACY_SERVER_CONNECT, 0},
+    /* no_resumption_on_reneg */
+    {SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION, 0},
+    /* no_legacy_server_connect */
+    {SSL_OP_LEGACY_SERVER_CONNECT, SSL_TFLAG_INV},
+    {SSL_CERT_FLAG_TLS_STRICT, SSL_TFLAG_CERT}, /* strict */
+};
+
+static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd)
+{
+    if (!pcmd || !*pcmd)
+        return 0;
+    /* If a prefix is set, check and skip */
+    if (cctx->prefix) {
+        if (strlen(*pcmd) <= cctx->prefixlen)
+            return 0;
+        if (cctx->flags & SSL_CONF_FLAG_CMDLINE &&
+            strncmp(*pcmd, cctx->prefix, cctx->prefixlen))
+            return 0;
+        if (cctx->flags & SSL_CONF_FLAG_FILE &&
+            strncasecmp(*pcmd, cctx->prefix, cctx->prefixlen))
+            return 0;
+        *pcmd += cctx->prefixlen;
+    } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
+        if (**pcmd != '-' || !(*pcmd)[1])
+            return 0;
+        *pcmd += 1;
+    }
+    return 1;
+}
+
+/* Determine if a command is allowed according to cctx flags */
+static int ssl_conf_cmd_allowed(SSL_CONF_CTX *cctx, const ssl_conf_cmd_tbl * t)
+{
+    unsigned int tfl = t->flags;
+    unsigned int cfl = cctx->flags;
+    if ((tfl & SSL_CONF_FLAG_SERVER) && !(cfl & SSL_CONF_FLAG_SERVER))
+        return 0;
+    if ((tfl & SSL_CONF_FLAG_CLIENT) && !(cfl & SSL_CONF_FLAG_CLIENT))
+        return 0;
+    if ((tfl & SSL_CONF_FLAG_CERTIFICATE)
+        && !(cfl & SSL_CONF_FLAG_CERTIFICATE))
+        return 0;
+    return 1;
+}
+
+static const ssl_conf_cmd_tbl *ssl_conf_cmd_lookup(SSL_CONF_CTX *cctx,
+                                                   const char *cmd)
+{
+    const ssl_conf_cmd_tbl *t;
+    size_t i;
+    if (cmd == NULL)
+        return NULL;
+
+    /* Look for matching parameter name in table */
+    for (i = 0, t = ssl_conf_cmds; i < OSSL_NELEM(ssl_conf_cmds); i++, t++) {
+        if (ssl_conf_cmd_allowed(cctx, t)) {
+            if (cctx->flags & SSL_CONF_FLAG_CMDLINE) {
+                if (t->str_cmdline && strcmp(t->str_cmdline, cmd) == 0)
+                    return t;
+            }
+            if (cctx->flags & SSL_CONF_FLAG_FILE) {
+                if (t->str_file && strcasecmp(t->str_file, cmd) == 0)
+                    return t;
+            }
+        }
+    }
+    return NULL;
+}
+
+static int ctrl_switch_option(SSL_CONF_CTX *cctx, const ssl_conf_cmd_tbl * cmd)
+{
+    /* Find index of command in table */
+    size_t idx = cmd - ssl_conf_cmds;
+    const ssl_switch_tbl *scmd;
+    /* Sanity check index */
+    if (idx >= OSSL_NELEM(ssl_cmd_switches))
+        return 0;
+    /* Obtain switches entry with same index */
+    scmd = ssl_cmd_switches + idx;
+    ssl_set_option(cctx, scmd->name_flags, scmd->option_value, 1);
+    return 1;
+}
+
+int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value)
+{
+    const ssl_conf_cmd_tbl *runcmd;
+    if (cmd == NULL) {
+        SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_INVALID_NULL_CMD_NAME);
+        return 0;
+    }
+
+    if (!ssl_conf_cmd_skip_prefix(cctx, &cmd))
+        return -2;
+
+    runcmd = ssl_conf_cmd_lookup(cctx, cmd);
+
+    if (runcmd) {
+        int rv;
+        if (runcmd->value_type == SSL_CONF_TYPE_NONE) {
+            return ctrl_switch_option(cctx, runcmd);
+        }
+        if (value == NULL)
+            return -3;
+        rv = runcmd->cmd(cctx, value);
+        if (rv > 0)
+            return 2;
+        if (rv == -2)
+            return -2;
+        if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) {
+            SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_BAD_VALUE);
+            ERR_add_error_data(4, "cmd=", cmd, ", value=", value);
+        }
+        return 0;
+    }
+
+    if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) {
+        SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_UNKNOWN_CMD_NAME);
+        ERR_add_error_data(2, "cmd=", cmd);
+    }
+
+    return -2;
+}
+
+int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv)
+{
+    int rv;
+    const char *arg = NULL, *argn;
+    if (pargc && *pargc == 0)
+        return 0;
+    if (!pargc || *pargc > 0)
+        arg = **pargv;
+    if (arg == NULL)
+        return 0;
+    if (!pargc || *pargc > 1)
+        argn = (*pargv)[1];
+    else
+        argn = NULL;
+    cctx->flags &= ~SSL_CONF_FLAG_FILE;
+    cctx->flags |= SSL_CONF_FLAG_CMDLINE;
+    rv = SSL_CONF_cmd(cctx, arg, argn);
+    if (rv > 0) {
+        /* Success: update pargc, pargv */
+        (*pargv) += rv;
+        if (pargc)
+            (*pargc) -= rv;
+        return rv;
+    }
+    /* Unknown switch: indicate no arguments processed */
+    if (rv == -2)
+        return 0;
+    /* Some error occurred processing command, return fatal error */
+    if (rv == 0)
+        return -1;
+    return rv;
+}
+
+int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd)
+{
+    if (ssl_conf_cmd_skip_prefix(cctx, &cmd)) {
+        const ssl_conf_cmd_tbl *runcmd;
+        runcmd = ssl_conf_cmd_lookup(cctx, cmd);
+        if (runcmd)
+            return runcmd->value_type;
+    }
+    return SSL_CONF_TYPE_UNKNOWN;
+}
+
+SSL_CONF_CTX *SSL_CONF_CTX_new(void)
+{
+    SSL_CONF_CTX *ret = OPENSSL_zalloc(sizeof(*ret));
+
+    return ret;
+}
+
+int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx)
+{
+    /* See if any certificates are missing private keys */
+    size_t i;
+    CERT *c = NULL;
+    if (cctx->ctx)
+        c = cctx->ctx->cert;
+    else if (cctx->ssl)
+        c = cctx->ssl->cert;
+    if (c && cctx->flags & SSL_CONF_FLAG_REQUIRE_PRIVATE) {
+        for (i = 0; i < SSL_PKEY_NUM; i++) {
+            const char *p = cctx->cert_filename[i];
+            /*
+             * If missing private key try to load one from certificate file
+             */
+            if (p && !c->pkeys[i].privatekey) {
+                if (!cmd_PrivateKey(cctx, p))
+                    return 0;
+            }
+        }
+    }
+    if (cctx->canames) {
+        if (cctx->ssl)
+            SSL_set_client_CA_list(cctx->ssl, cctx->canames);
+        else if (cctx->ctx)
+            SSL_CTX_set_client_CA_list(cctx->ctx, cctx->canames);
+        else
+            sk_X509_NAME_pop_free(cctx->canames, X509_NAME_free);
+        cctx->canames = NULL;
+    }
+    return 1;
+}
+
+void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx)
+{
+    if (cctx) {
+        size_t i;
+        for (i = 0; i < SSL_PKEY_NUM; i++)
+            OPENSSL_free(cctx->cert_filename[i]);
+        OPENSSL_free(cctx->prefix);
+        sk_X509_NAME_pop_free(cctx->canames, X509_NAME_free);
+        OPENSSL_free(cctx);
+    }
+}
+
+unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags)
+{
+    cctx->flags |= flags;
+    return cctx->flags;
+}
+
+unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags)
+{
+    cctx->flags &= ~flags;
+    return cctx->flags;
+}
+
+int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre)
+{
+    char *tmp = NULL;
+    if (pre) {
+        tmp = OPENSSL_strdup(pre);
+        if (tmp == NULL)
+            return 0;
+    }
+    OPENSSL_free(cctx->prefix);
+    cctx->prefix = tmp;
+    if (tmp)
+        cctx->prefixlen = strlen(tmp);
+    else
+        cctx->prefixlen = 0;
+    return 1;
+}
+
+void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl)
+{
+    cctx->ssl = ssl;
+    cctx->ctx = NULL;
+    if (ssl) {
+        cctx->poptions = &ssl->options;
+        cctx->min_version = &ssl->min_proto_version;
+        cctx->max_version = &ssl->max_proto_version;
+        cctx->pcert_flags = &ssl->cert->cert_flags;
+        cctx->pvfy_flags = &ssl->verify_mode;
+    } else {
+        cctx->poptions = NULL;
+        cctx->min_version = NULL;
+        cctx->max_version = NULL;
+        cctx->pcert_flags = NULL;
+        cctx->pvfy_flags = NULL;
+    }
+}
+
+void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx)
+{
+    cctx->ctx = ctx;
+    cctx->ssl = NULL;
+    if (ctx) {
+        cctx->poptions = &ctx->options;
+        cctx->min_version = &ctx->min_proto_version;
+        cctx->max_version = &ctx->max_proto_version;
+        cctx->pcert_flags = &ctx->cert->cert_flags;
+        cctx->pvfy_flags = &ctx->verify_mode;
+    } else {
+        cctx->poptions = NULL;
+        cctx->min_version = NULL;
+        cctx->max_version = NULL;
+        cctx->pcert_flags = NULL;
+        cctx->pvfy_flags = NULL;
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_err.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_err.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_err.c	(revision 331)
@@ -0,0 +1,682 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_SSL,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_SSL,0,reason)
+
+static ERR_STRING_DATA SSL_str_functs[] = {
+    {ERR_FUNC(SSL_F_CHECK_SUITEB_CIPHER_LIST), "check_suiteb_cipher_list"},
+    {ERR_FUNC(SSL_F_CT_MOVE_SCTS), "ct_move_scts"},
+    {ERR_FUNC(SSL_F_CT_STRICT), "ct_strict"},
+    {ERR_FUNC(SSL_F_D2I_SSL_SESSION), "d2i_SSL_SESSION"},
+    {ERR_FUNC(SSL_F_DANE_CTX_ENABLE), "dane_ctx_enable"},
+    {ERR_FUNC(SSL_F_DANE_MTYPE_SET), "dane_mtype_set"},
+    {ERR_FUNC(SSL_F_DANE_TLSA_ADD), "dane_tlsa_add"},
+    {ERR_FUNC(SSL_F_DO_DTLS1_WRITE), "do_dtls1_write"},
+    {ERR_FUNC(SSL_F_DO_SSL3_WRITE), "do_ssl3_write"},
+    {ERR_FUNC(SSL_F_DTLS1_BUFFER_RECORD), "dtls1_buffer_record"},
+    {ERR_FUNC(SSL_F_DTLS1_CHECK_TIMEOUT_NUM), "dtls1_check_timeout_num"},
+    {ERR_FUNC(SSL_F_DTLS1_HEARTBEAT), "dtls1_heartbeat"},
+    {ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "dtls1_preprocess_fragment"},
+    {ERR_FUNC(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS),
+     "dtls1_process_buffered_records"},
+    {ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD), "dtls1_process_record"},
+    {ERR_FUNC(SSL_F_DTLS1_READ_BYTES), "dtls1_read_bytes"},
+    {ERR_FUNC(SSL_F_DTLS1_READ_FAILED), "dtls1_read_failed"},
+    {ERR_FUNC(SSL_F_DTLS1_RETRANSMIT_MESSAGE), "dtls1_retransmit_message"},
+    {ERR_FUNC(SSL_F_DTLS1_WRITE_APP_DATA_BYTES),
+     "dtls1_write_app_data_bytes"},
+    {ERR_FUNC(SSL_F_DTLSV1_LISTEN), "DTLSv1_listen"},
+    {ERR_FUNC(SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC),
+     "dtls_construct_change_cipher_spec"},
+    {ERR_FUNC(SSL_F_DTLS_CONSTRUCT_HELLO_VERIFY_REQUEST),
+     "dtls_construct_hello_verify_request"},
+    {ERR_FUNC(SSL_F_DTLS_GET_REASSEMBLED_MESSAGE),
+     "dtls_get_reassembled_message"},
+    {ERR_FUNC(SSL_F_DTLS_PROCESS_HELLO_VERIFY), "dtls_process_hello_verify"},
+    {ERR_FUNC(SSL_F_OPENSSL_INIT_SSL), "OPENSSL_init_ssl"},
+    {ERR_FUNC(SSL_F_OSSL_STATEM_CLIENT_READ_TRANSITION),
+     "ossl_statem_client_read_transition"},
+    {ERR_FUNC(SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION),
+     "ossl_statem_server_read_transition"},
+    {ERR_FUNC(SSL_F_READ_STATE_MACHINE), "read_state_machine"},
+    {ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE), "ssl3_change_cipher_state"},
+    {ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM),
+     "ssl3_check_cert_and_algorithm"},
+    {ERR_FUNC(SSL_F_SSL3_CTRL), "ssl3_ctrl"},
+    {ERR_FUNC(SSL_F_SSL3_CTX_CTRL), "ssl3_ctx_ctrl"},
+    {ERR_FUNC(SSL_F_SSL3_DIGEST_CACHED_RECORDS),
+     "ssl3_digest_cached_records"},
+    {ERR_FUNC(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC),
+     "ssl3_do_change_cipher_spec"},
+    {ERR_FUNC(SSL_F_SSL3_FINAL_FINISH_MAC), "ssl3_final_finish_mac"},
+    {ERR_FUNC(SSL_F_SSL3_GENERATE_KEY_BLOCK), "ssl3_generate_key_block"},
+    {ERR_FUNC(SSL_F_SSL3_GENERATE_MASTER_SECRET),
+     "ssl3_generate_master_secret"},
+    {ERR_FUNC(SSL_F_SSL3_GET_RECORD), "ssl3_get_record"},
+    {ERR_FUNC(SSL_F_SSL3_INIT_FINISHED_MAC), "ssl3_init_finished_mac"},
+    {ERR_FUNC(SSL_F_SSL3_OUTPUT_CERT_CHAIN), "ssl3_output_cert_chain"},
+    {ERR_FUNC(SSL_F_SSL3_READ_BYTES), "ssl3_read_bytes"},
+    {ERR_FUNC(SSL_F_SSL3_READ_N), "ssl3_read_n"},
+    {ERR_FUNC(SSL_F_SSL3_SETUP_KEY_BLOCK), "ssl3_setup_key_block"},
+    {ERR_FUNC(SSL_F_SSL3_SETUP_READ_BUFFER), "ssl3_setup_read_buffer"},
+    {ERR_FUNC(SSL_F_SSL3_SETUP_WRITE_BUFFER), "ssl3_setup_write_buffer"},
+    {ERR_FUNC(SSL_F_SSL3_WRITE_BYTES), "ssl3_write_bytes"},
+    {ERR_FUNC(SSL_F_SSL3_WRITE_PENDING), "ssl3_write_pending"},
+    {ERR_FUNC(SSL_F_SSL_ADD_CERT_CHAIN), "ssl_add_cert_chain"},
+    {ERR_FUNC(SSL_F_SSL_ADD_CERT_TO_BUF), "ssl_add_cert_to_buf"},
+    {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT),
+     "ssl_add_clienthello_renegotiate_ext"},
+    {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT),
+     "ssl_add_clienthello_tlsext"},
+    {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT),
+     "ssl_add_clienthello_use_srtp_ext"},
+    {ERR_FUNC(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK),
+     "SSL_add_dir_cert_subjects_to_stack"},
+    {ERR_FUNC(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK),
+     "SSL_add_file_cert_subjects_to_stack"},
+    {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT),
+     "ssl_add_serverhello_renegotiate_ext"},
+    {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT),
+     "ssl_add_serverhello_tlsext"},
+    {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT),
+     "ssl_add_serverhello_use_srtp_ext"},
+    {ERR_FUNC(SSL_F_SSL_BAD_METHOD), "ssl_bad_method"},
+    {ERR_FUNC(SSL_F_SSL_BUILD_CERT_CHAIN), "ssl_build_cert_chain"},
+    {ERR_FUNC(SSL_F_SSL_BYTES_TO_CIPHER_LIST), "ssl_bytes_to_cipher_list"},
+    {ERR_FUNC(SSL_F_SSL_CERT_ADD0_CHAIN_CERT), "ssl_cert_add0_chain_cert"},
+    {ERR_FUNC(SSL_F_SSL_CERT_DUP), "ssl_cert_dup"},
+    {ERR_FUNC(SSL_F_SSL_CERT_NEW), "ssl_cert_new"},
+    {ERR_FUNC(SSL_F_SSL_CERT_SET0_CHAIN), "ssl_cert_set0_chain"},
+    {ERR_FUNC(SSL_F_SSL_CHECK_PRIVATE_KEY), "SSL_check_private_key"},
+    {ERR_FUNC(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT),
+     "ssl_check_serverhello_tlsext"},
+    {ERR_FUNC(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG),
+     "ssl_check_srvr_ecc_cert_and_alg"},
+    {ERR_FUNC(SSL_F_SSL_CIPHER_PROCESS_RULESTR),
+     "ssl_cipher_process_rulestr"},
+    {ERR_FUNC(SSL_F_SSL_CIPHER_STRENGTH_SORT), "ssl_cipher_strength_sort"},
+    {ERR_FUNC(SSL_F_SSL_CLEAR), "SSL_clear"},
+    {ERR_FUNC(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD),
+     "SSL_COMP_add_compression_method"},
+    {ERR_FUNC(SSL_F_SSL_CONF_CMD), "SSL_CONF_cmd"},
+    {ERR_FUNC(SSL_F_SSL_CREATE_CIPHER_LIST), "ssl_create_cipher_list"},
+    {ERR_FUNC(SSL_F_SSL_CTRL), "SSL_ctrl"},
+    {ERR_FUNC(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY), "SSL_CTX_check_private_key"},
+    {ERR_FUNC(SSL_F_SSL_CTX_ENABLE_CT), "SSL_CTX_enable_ct"},
+    {ERR_FUNC(SSL_F_SSL_CTX_MAKE_PROFILES), "ssl_ctx_make_profiles"},
+    {ERR_FUNC(SSL_F_SSL_CTX_NEW), "SSL_CTX_new"},
+    {ERR_FUNC(SSL_F_SSL_CTX_SET_ALPN_PROTOS), "SSL_CTX_set_alpn_protos"},
+    {ERR_FUNC(SSL_F_SSL_CTX_SET_CIPHER_LIST), "SSL_CTX_set_cipher_list"},
+    {ERR_FUNC(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE),
+     "SSL_CTX_set_client_cert_engine"},
+    {ERR_FUNC(SSL_F_SSL_CTX_SET_CT_VALIDATION_CALLBACK),
+     "SSL_CTX_set_ct_validation_callback"},
+    {ERR_FUNC(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT),
+     "SSL_CTX_set_session_id_context"},
+    {ERR_FUNC(SSL_F_SSL_CTX_SET_SSL_VERSION), "SSL_CTX_set_ssl_version"},
+    {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE), "SSL_CTX_use_certificate"},
+    {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1),
+     "SSL_CTX_use_certificate_ASN1"},
+    {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE),
+     "SSL_CTX_use_certificate_file"},
+    {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY), "SSL_CTX_use_PrivateKey"},
+    {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1),
+     "SSL_CTX_use_PrivateKey_ASN1"},
+    {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE),
+     "SSL_CTX_use_PrivateKey_file"},
+    {ERR_FUNC(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT),
+     "SSL_CTX_use_psk_identity_hint"},
+    {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY), "SSL_CTX_use_RSAPrivateKey"},
+    {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1),
+     "SSL_CTX_use_RSAPrivateKey_ASN1"},
+    {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE),
+     "SSL_CTX_use_RSAPrivateKey_file"},
+    {ERR_FUNC(SSL_F_SSL_CTX_USE_SERVERINFO), "SSL_CTX_use_serverinfo"},
+    {ERR_FUNC(SSL_F_SSL_CTX_USE_SERVERINFO_FILE),
+     "SSL_CTX_use_serverinfo_file"},
+    {ERR_FUNC(SSL_F_SSL_DANE_DUP), "ssl_dane_dup"},
+    {ERR_FUNC(SSL_F_SSL_DANE_ENABLE), "SSL_dane_enable"},
+    {ERR_FUNC(SSL_F_SSL_DO_CONFIG), "ssl_do_config"},
+    {ERR_FUNC(SSL_F_SSL_DO_HANDSHAKE), "SSL_do_handshake"},
+    {ERR_FUNC(SSL_F_SSL_DUP_CA_LIST), "SSL_dup_CA_list"},
+    {ERR_FUNC(SSL_F_SSL_ENABLE_CT), "SSL_enable_ct"},
+    {ERR_FUNC(SSL_F_SSL_GET_NEW_SESSION), "ssl_get_new_session"},
+    {ERR_FUNC(SSL_F_SSL_GET_PREV_SESSION), "ssl_get_prev_session"},
+    {ERR_FUNC(SSL_F_SSL_GET_SERVER_CERT_INDEX), "ssl_get_server_cert_index"},
+    {ERR_FUNC(SSL_F_SSL_GET_SIGN_PKEY), "ssl_get_sign_pkey"},
+    {ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER), "ssl_init_wbio_buffer"},
+    {ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE), "SSL_load_client_CA_file"},
+    {ERR_FUNC(SSL_F_SSL_MODULE_INIT), "ssl_module_init"},
+    {ERR_FUNC(SSL_F_SSL_NEW), "SSL_new"},
+    {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT),
+     "ssl_parse_clienthello_renegotiate_ext"},
+    {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT),
+     "ssl_parse_clienthello_tlsext"},
+    {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT),
+     "ssl_parse_clienthello_use_srtp_ext"},
+    {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT),
+     "ssl_parse_serverhello_renegotiate_ext"},
+    {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT),
+     "ssl_parse_serverhello_tlsext"},
+    {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT),
+     "ssl_parse_serverhello_use_srtp_ext"},
+    {ERR_FUNC(SSL_F_SSL_PEEK), "SSL_peek"},
+    {ERR_FUNC(SSL_F_SSL_READ), "SSL_read"},
+    {ERR_FUNC(SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT),
+     "ssl_scan_clienthello_tlsext"},
+    {ERR_FUNC(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT),
+     "ssl_scan_serverhello_tlsext"},
+    {ERR_FUNC(SSL_F_SSL_SESSION_DUP), "ssl_session_dup"},
+    {ERR_FUNC(SSL_F_SSL_SESSION_NEW), "SSL_SESSION_new"},
+    {ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"},
+    {ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID), "SSL_SESSION_set1_id"},
+    {ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT),
+     "SSL_SESSION_set1_id_context"},
+    {ERR_FUNC(SSL_F_SSL_SET_ALPN_PROTOS), "SSL_set_alpn_protos"},
+    {ERR_FUNC(SSL_F_SSL_SET_CERT), "ssl_set_cert"},
+    {ERR_FUNC(SSL_F_SSL_SET_CIPHER_LIST), "SSL_set_cipher_list"},
+    {ERR_FUNC(SSL_F_SSL_SET_CT_VALIDATION_CALLBACK),
+     "SSL_set_ct_validation_callback"},
+    {ERR_FUNC(SSL_F_SSL_SET_FD), "SSL_set_fd"},
+    {ERR_FUNC(SSL_F_SSL_SET_PKEY), "ssl_set_pkey"},
+    {ERR_FUNC(SSL_F_SSL_SET_RFD), "SSL_set_rfd"},
+    {ERR_FUNC(SSL_F_SSL_SET_SESSION), "SSL_set_session"},
+    {ERR_FUNC(SSL_F_SSL_SET_SESSION_ID_CONTEXT),
+     "SSL_set_session_id_context"},
+    {ERR_FUNC(SSL_F_SSL_SET_SESSION_TICKET_EXT),
+     "SSL_set_session_ticket_ext"},
+    {ERR_FUNC(SSL_F_SSL_SET_WFD), "SSL_set_wfd"},
+    {ERR_FUNC(SSL_F_SSL_SHUTDOWN), "SSL_shutdown"},
+    {ERR_FUNC(SSL_F_SSL_SRP_CTX_INIT), "SSL_SRP_CTX_init"},
+    {ERR_FUNC(SSL_F_SSL_START_ASYNC_JOB), "ssl_start_async_job"},
+    {ERR_FUNC(SSL_F_SSL_UNDEFINED_FUNCTION), "ssl_undefined_function"},
+    {ERR_FUNC(SSL_F_SSL_UNDEFINED_VOID_FUNCTION),
+     "ssl_undefined_void_function"},
+    {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE), "SSL_use_certificate"},
+    {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_ASN1), "SSL_use_certificate_ASN1"},
+    {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_FILE), "SSL_use_certificate_file"},
+    {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY), "SSL_use_PrivateKey"},
+    {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_ASN1), "SSL_use_PrivateKey_ASN1"},
+    {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_FILE), "SSL_use_PrivateKey_file"},
+    {ERR_FUNC(SSL_F_SSL_USE_PSK_IDENTITY_HINT), "SSL_use_psk_identity_hint"},
+    {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY), "SSL_use_RSAPrivateKey"},
+    {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1),
+     "SSL_use_RSAPrivateKey_ASN1"},
+    {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE),
+     "SSL_use_RSAPrivateKey_file"},
+    {ERR_FUNC(SSL_F_SSL_VALIDATE_CT), "ssl_validate_ct"},
+    {ERR_FUNC(SSL_F_SSL_VERIFY_CERT_CHAIN), "ssl_verify_cert_chain"},
+    {ERR_FUNC(SSL_F_SSL_WRITE), "SSL_write"},
+    {ERR_FUNC(SSL_F_STATE_MACHINE), "state_machine"},
+    {ERR_FUNC(SSL_F_TLS12_CHECK_PEER_SIGALG), "tls12_check_peer_sigalg"},
+    {ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE), "tls1_change_cipher_state"},
+    {ERR_FUNC(SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS),
+     "tls1_check_duplicate_extensions"},
+    {ERR_FUNC(SSL_F_TLS1_ENC), "tls1_enc"},
+    {ERR_FUNC(SSL_F_TLS1_EXPORT_KEYING_MATERIAL),
+     "tls1_export_keying_material"},
+    {ERR_FUNC(SSL_F_TLS1_GET_CURVELIST), "tls1_get_curvelist"},
+    {ERR_FUNC(SSL_F_TLS1_PRF), "tls1_PRF"},
+    {ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "tls1_setup_key_block"},
+    {ERR_FUNC(SSL_F_TLS1_SET_SERVER_SIGALGS), "tls1_set_server_sigalgs"},
+    {ERR_FUNC(SSL_F_TLS_CLIENT_KEY_EXCHANGE_POST_WORK),
+     "tls_client_key_exchange_post_work"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST),
+     "tls_construct_certificate_request"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CKE_DHE), "tls_construct_cke_dhe"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CKE_ECDHE), "tls_construct_cke_ecdhe"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CKE_GOST), "tls_construct_cke_gost"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE),
+     "tls_construct_cke_psk_preamble"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CKE_RSA), "tls_construct_cke_rsa"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CKE_SRP), "tls_construct_cke_srp"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE),
+     "tls_construct_client_certificate"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO),
+     "tls_construct_client_hello"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE),
+     "tls_construct_client_key_exchange"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY),
+     "tls_construct_client_verify"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_FINISHED), "tls_construct_finished"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_HELLO_REQUEST),
+     "tls_construct_hello_request"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET),
+     "tls_construct_new_session_ticket"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_SERVER_CERTIFICATE),
+     "tls_construct_server_certificate"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_SERVER_DONE), "tls_construct_server_done"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_SERVER_HELLO),
+     "tls_construct_server_hello"},
+    {ERR_FUNC(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE),
+     "tls_construct_server_key_exchange"},
+    {ERR_FUNC(SSL_F_TLS_GET_MESSAGE_BODY), "tls_get_message_body"},
+    {ERR_FUNC(SSL_F_TLS_GET_MESSAGE_HEADER), "tls_get_message_header"},
+    {ERR_FUNC(SSL_F_TLS_POST_PROCESS_CLIENT_HELLO),
+     "tls_post_process_client_hello"},
+    {ERR_FUNC(SSL_F_TLS_POST_PROCESS_CLIENT_KEY_EXCHANGE),
+     "tls_post_process_client_key_exchange"},
+    {ERR_FUNC(SSL_F_TLS_PREPARE_CLIENT_CERTIFICATE),
+     "tls_prepare_client_certificate"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST),
+     "tls_process_certificate_request"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_CERT_STATUS), "tls_process_cert_status"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_CERT_VERIFY), "tls_process_cert_verify"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC),
+     "tls_process_change_cipher_spec"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_CKE_DHE), "tls_process_cke_dhe"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_CKE_ECDHE), "tls_process_cke_ecdhe"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_CKE_GOST), "tls_process_cke_gost"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE),
+     "tls_process_cke_psk_preamble"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_CKE_RSA), "tls_process_cke_rsa"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_CKE_SRP), "tls_process_cke_srp"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE),
+     "tls_process_client_certificate"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_CLIENT_HELLO), "tls_process_client_hello"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE),
+     "tls_process_client_key_exchange"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_FINISHED), "tls_process_finished"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_KEY_EXCHANGE), "tls_process_key_exchange"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET),
+     "tls_process_new_session_ticket"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_NEXT_PROTO), "tls_process_next_proto"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE),
+     "tls_process_server_certificate"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_SERVER_DONE), "tls_process_server_done"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_SERVER_HELLO), "tls_process_server_hello"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_SKE_DHE), "tls_process_ske_dhe"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_SKE_ECDHE), "tls_process_ske_ecdhe"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_SKE_PSK_PREAMBLE),
+     "tls_process_ske_psk_preamble"},
+    {ERR_FUNC(SSL_F_TLS_PROCESS_SKE_SRP), "tls_process_ske_srp"},
+    {ERR_FUNC(SSL_F_USE_CERTIFICATE_CHAIN_FILE),
+     "use_certificate_chain_file"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA SSL_str_reasons[] = {
+    {ERR_REASON(SSL_R_APP_DATA_IN_HANDSHAKE), "app data in handshake"},
+    {ERR_REASON(SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT),
+     "attempt to reuse session in different context"},
+    {ERR_REASON(SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE),
+     "at least TLS 1.0 needed in FIPS mode"},
+    {ERR_REASON(SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE),
+     "at least (D)TLS 1.2 needed in Suite B mode"},
+    {ERR_REASON(SSL_R_BAD_CHANGE_CIPHER_SPEC), "bad change cipher spec"},
+    {ERR_REASON(SSL_R_BAD_DATA), "bad data"},
+    {ERR_REASON(SSL_R_BAD_DATA_RETURNED_BY_CALLBACK),
+     "bad data returned by callback"},
+    {ERR_REASON(SSL_R_BAD_DECOMPRESSION), "bad decompression"},
+    {ERR_REASON(SSL_R_BAD_DH_VALUE), "bad dh value"},
+    {ERR_REASON(SSL_R_BAD_DIGEST_LENGTH), "bad digest length"},
+    {ERR_REASON(SSL_R_BAD_ECC_CERT), "bad ecc cert"},
+    {ERR_REASON(SSL_R_BAD_ECPOINT), "bad ecpoint"},
+    {ERR_REASON(SSL_R_BAD_HANDSHAKE_LENGTH), "bad handshake length"},
+    {ERR_REASON(SSL_R_BAD_HELLO_REQUEST), "bad hello request"},
+    {ERR_REASON(SSL_R_BAD_LENGTH), "bad length"},
+    {ERR_REASON(SSL_R_BAD_PACKET_LENGTH), "bad packet length"},
+    {ERR_REASON(SSL_R_BAD_PROTOCOL_VERSION_NUMBER),
+     "bad protocol version number"},
+    {ERR_REASON(SSL_R_BAD_RSA_ENCRYPT), "bad rsa encrypt"},
+    {ERR_REASON(SSL_R_BAD_SIGNATURE), "bad signature"},
+    {ERR_REASON(SSL_R_BAD_SRP_A_LENGTH), "bad srp a length"},
+    {ERR_REASON(SSL_R_BAD_SRP_PARAMETERS), "bad srp parameters"},
+    {ERR_REASON(SSL_R_BAD_SRTP_MKI_VALUE), "bad srtp mki value"},
+    {ERR_REASON(SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST),
+     "bad srtp protection profile list"},
+    {ERR_REASON(SSL_R_BAD_SSL_FILETYPE), "bad ssl filetype"},
+    {ERR_REASON(SSL_R_BAD_VALUE), "bad value"},
+    {ERR_REASON(SSL_R_BAD_WRITE_RETRY), "bad write retry"},
+    {ERR_REASON(SSL_R_BIO_NOT_SET), "bio not set"},
+    {ERR_REASON(SSL_R_BLOCK_CIPHER_PAD_IS_WRONG),
+     "block cipher pad is wrong"},
+    {ERR_REASON(SSL_R_BN_LIB), "bn lib"},
+    {ERR_REASON(SSL_R_CA_DN_LENGTH_MISMATCH), "ca dn length mismatch"},
+    {ERR_REASON(SSL_R_CA_KEY_TOO_SMALL), "ca key too small"},
+    {ERR_REASON(SSL_R_CA_MD_TOO_WEAK), "ca md too weak"},
+    {ERR_REASON(SSL_R_CCS_RECEIVED_EARLY), "ccs received early"},
+    {ERR_REASON(SSL_R_CERTIFICATE_VERIFY_FAILED),
+     "certificate verify failed"},
+    {ERR_REASON(SSL_R_CERT_CB_ERROR), "cert cb error"},
+    {ERR_REASON(SSL_R_CERT_LENGTH_MISMATCH), "cert length mismatch"},
+    {ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH), "cipher code wrong length"},
+    {ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE),
+     "cipher or hash unavailable"},
+    {ERR_REASON(SSL_R_CLIENTHELLO_TLSEXT), "clienthello tlsext"},
+    {ERR_REASON(SSL_R_COMPRESSED_LENGTH_TOO_LONG),
+     "compressed length too long"},
+    {ERR_REASON(SSL_R_COMPRESSION_DISABLED), "compression disabled"},
+    {ERR_REASON(SSL_R_COMPRESSION_FAILURE), "compression failure"},
+    {ERR_REASON(SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE),
+     "compression id not within private range"},
+    {ERR_REASON(SSL_R_COMPRESSION_LIBRARY_ERROR),
+     "compression library error"},
+    {ERR_REASON(SSL_R_CONNECTION_TYPE_NOT_SET), "connection type not set"},
+    {ERR_REASON(SSL_R_CONTEXT_NOT_DANE_ENABLED), "context not dane enabled"},
+    {ERR_REASON(SSL_R_COOKIE_GEN_CALLBACK_FAILURE),
+     "cookie gen callback failure"},
+    {ERR_REASON(SSL_R_COOKIE_MISMATCH), "cookie mismatch"},
+    {ERR_REASON(SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED),
+     "custom ext handler already installed"},
+    {ERR_REASON(SSL_R_DANE_ALREADY_ENABLED), "dane already enabled"},
+    {ERR_REASON(SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL),
+     "dane cannot override mtype full"},
+    {ERR_REASON(SSL_R_DANE_NOT_ENABLED), "dane not enabled"},
+    {ERR_REASON(SSL_R_DANE_TLSA_BAD_CERTIFICATE),
+     "dane tlsa bad certificate"},
+    {ERR_REASON(SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE),
+     "dane tlsa bad certificate usage"},
+    {ERR_REASON(SSL_R_DANE_TLSA_BAD_DATA_LENGTH),
+     "dane tlsa bad data length"},
+    {ERR_REASON(SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH),
+     "dane tlsa bad digest length"},
+    {ERR_REASON(SSL_R_DANE_TLSA_BAD_MATCHING_TYPE),
+     "dane tlsa bad matching type"},
+    {ERR_REASON(SSL_R_DANE_TLSA_BAD_PUBLIC_KEY), "dane tlsa bad public key"},
+    {ERR_REASON(SSL_R_DANE_TLSA_BAD_SELECTOR), "dane tlsa bad selector"},
+    {ERR_REASON(SSL_R_DANE_TLSA_NULL_DATA), "dane tlsa null data"},
+    {ERR_REASON(SSL_R_DATA_BETWEEN_CCS_AND_FINISHED),
+     "data between ccs and finished"},
+    {ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG), "data length too long"},
+    {ERR_REASON(SSL_R_DECRYPTION_FAILED), "decryption failed"},
+    {ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC),
+     "decryption failed or bad record mac"},
+    {ERR_REASON(SSL_R_DH_KEY_TOO_SMALL), "dh key too small"},
+    {ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG),
+     "dh public value length is wrong"},
+    {ERR_REASON(SSL_R_DIGEST_CHECK_FAILED), "digest check failed"},
+    {ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG), "dtls message too big"},
+    {ERR_REASON(SSL_R_DUPLICATE_COMPRESSION_ID), "duplicate compression id"},
+    {ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_SIGNING), "ecc cert not for signing"},
+    {ERR_REASON(SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE),
+     "ecdh required for suiteb mode"},
+    {ERR_REASON(SSL_R_EE_KEY_TOO_SMALL), "ee key too small"},
+    {ERR_REASON(SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST),
+     "empty srtp protection profile list"},
+    {ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG),
+     "encrypted length too long"},
+    {ERR_REASON(SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST),
+     "error in received cipher list"},
+    {ERR_REASON(SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN),
+     "error setting tlsa base domain"},
+    {ERR_REASON(SSL_R_EXCESSIVE_MESSAGE_SIZE), "excessive message size"},
+    {ERR_REASON(SSL_R_EXTRA_DATA_IN_MESSAGE), "extra data in message"},
+    {ERR_REASON(SSL_R_FAILED_TO_INIT_ASYNC), "failed to init async"},
+    {ERR_REASON(SSL_R_FRAGMENTED_CLIENT_HELLO), "fragmented client hello"},
+    {ERR_REASON(SSL_R_GOT_A_FIN_BEFORE_A_CCS), "got a fin before a ccs"},
+    {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST), "https proxy request"},
+    {ERR_REASON(SSL_R_HTTP_REQUEST), "http request"},
+    {ERR_REASON(SSL_R_ILLEGAL_SUITEB_DIGEST), "illegal Suite B digest"},
+    {ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK), "inappropriate fallback"},
+    {ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION), "inconsistent compression"},
+    {ERR_REASON(SSL_R_INCONSISTENT_EXTMS), "inconsistent extms"},
+    {ERR_REASON(SSL_R_INVALID_COMMAND), "invalid command"},
+    {ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),
+     "invalid compression algorithm"},
+    {ERR_REASON(SSL_R_INVALID_CONFIGURATION_NAME),
+     "invalid configuration name"},
+    {ERR_REASON(SSL_R_INVALID_CT_VALIDATION_TYPE),
+     "invalid ct validation type"},
+    {ERR_REASON(SSL_R_INVALID_NULL_CMD_NAME), "invalid null cmd name"},
+    {ERR_REASON(SSL_R_INVALID_SEQUENCE_NUMBER), "invalid sequence number"},
+    {ERR_REASON(SSL_R_INVALID_SERVERINFO_DATA), "invalid serverinfo data"},
+    {ERR_REASON(SSL_R_INVALID_SRP_USERNAME), "invalid srp username"},
+    {ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE), "invalid status response"},
+    {ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH),
+     "invalid ticket keys length"},
+    {ERR_REASON(SSL_R_LENGTH_MISMATCH), "length mismatch"},
+    {ERR_REASON(SSL_R_LENGTH_TOO_LONG), "length too long"},
+    {ERR_REASON(SSL_R_LENGTH_TOO_SHORT), "length too short"},
+    {ERR_REASON(SSL_R_LIBRARY_BUG), "library bug"},
+    {ERR_REASON(SSL_R_LIBRARY_HAS_NO_CIPHERS), "library has no ciphers"},
+    {ERR_REASON(SSL_R_MISSING_DSA_SIGNING_CERT), "missing dsa signing cert"},
+    {ERR_REASON(SSL_R_MISSING_ECDSA_SIGNING_CERT),
+     "missing ecdsa signing cert"},
+    {ERR_REASON(SSL_R_MISSING_RSA_CERTIFICATE), "missing rsa certificate"},
+    {ERR_REASON(SSL_R_MISSING_RSA_ENCRYPTING_CERT),
+     "missing rsa encrypting cert"},
+    {ERR_REASON(SSL_R_MISSING_RSA_SIGNING_CERT), "missing rsa signing cert"},
+    {ERR_REASON(SSL_R_MISSING_SRP_PARAM), "can't find SRP server param"},
+    {ERR_REASON(SSL_R_MISSING_TMP_DH_KEY), "missing tmp dh key"},
+    {ERR_REASON(SSL_R_MISSING_TMP_ECDH_KEY), "missing tmp ecdh key"},
+    {ERR_REASON(SSL_R_NO_CERTIFICATES_RETURNED), "no certificates returned"},
+    {ERR_REASON(SSL_R_NO_CERTIFICATE_ASSIGNED), "no certificate assigned"},
+    {ERR_REASON(SSL_R_NO_CERTIFICATE_SET), "no certificate set"},
+    {ERR_REASON(SSL_R_NO_CIPHERS_AVAILABLE), "no ciphers available"},
+    {ERR_REASON(SSL_R_NO_CIPHERS_SPECIFIED), "no ciphers specified"},
+    {ERR_REASON(SSL_R_NO_CIPHER_MATCH), "no cipher match"},
+    {ERR_REASON(SSL_R_NO_CLIENT_CERT_METHOD), "no client cert method"},
+    {ERR_REASON(SSL_R_NO_COMPRESSION_SPECIFIED), "no compression specified"},
+    {ERR_REASON(SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER),
+     "Peer haven't sent GOST certificate, required for selected ciphersuite"},
+    {ERR_REASON(SSL_R_NO_METHOD_SPECIFIED), "no method specified"},
+    {ERR_REASON(SSL_R_NO_PEM_EXTENSIONS), "no pem extensions"},
+    {ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED), "no private key assigned"},
+    {ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE), "no protocols available"},
+    {ERR_REASON(SSL_R_NO_RENEGOTIATION), "no renegotiation"},
+    {ERR_REASON(SSL_R_NO_REQUIRED_DIGEST), "no required digest"},
+    {ERR_REASON(SSL_R_NO_SHARED_CIPHER), "no shared cipher"},
+    {ERR_REASON(SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS),
+     "no shared signature algorithms"},
+    {ERR_REASON(SSL_R_NO_SRTP_PROFILES), "no srtp profiles"},
+    {ERR_REASON(SSL_R_NO_VALID_SCTS), "no valid scts"},
+    {ERR_REASON(SSL_R_NO_VERIFY_COOKIE_CALLBACK),
+     "no verify cookie callback"},
+    {ERR_REASON(SSL_R_NULL_SSL_CTX), "null ssl ctx"},
+    {ERR_REASON(SSL_R_NULL_SSL_METHOD_PASSED), "null ssl method passed"},
+    {ERR_REASON(SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED),
+     "old session cipher not returned"},
+    {ERR_REASON(SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED),
+     "old session compression algorithm not returned"},
+    {ERR_REASON(SSL_R_PACKET_LENGTH_TOO_LONG), "packet length too long"},
+    {ERR_REASON(SSL_R_PARSE_TLSEXT), "parse tlsext"},
+    {ERR_REASON(SSL_R_PATH_TOO_LONG), "path too long"},
+    {ERR_REASON(SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE),
+     "peer did not return a certificate"},
+    {ERR_REASON(SSL_R_PEM_NAME_BAD_PREFIX), "pem name bad prefix"},
+    {ERR_REASON(SSL_R_PEM_NAME_TOO_SHORT), "pem name too short"},
+    {ERR_REASON(SSL_R_PIPELINE_FAILURE), "pipeline failure"},
+    {ERR_REASON(SSL_R_PROTOCOL_IS_SHUTDOWN), "protocol is shutdown"},
+    {ERR_REASON(SSL_R_PSK_IDENTITY_NOT_FOUND), "psk identity not found"},
+    {ERR_REASON(SSL_R_PSK_NO_CLIENT_CB), "psk no client cb"},
+    {ERR_REASON(SSL_R_PSK_NO_SERVER_CB), "psk no server cb"},
+    {ERR_REASON(SSL_R_READ_BIO_NOT_SET), "read bio not set"},
+    {ERR_REASON(SSL_R_READ_TIMEOUT_EXPIRED), "read timeout expired"},
+    {ERR_REASON(SSL_R_RECORD_LENGTH_MISMATCH), "record length mismatch"},
+    {ERR_REASON(SSL_R_RECORD_TOO_SMALL), "record too small"},
+    {ERR_REASON(SSL_R_RENEGOTIATE_EXT_TOO_LONG), "renegotiate ext too long"},
+    {ERR_REASON(SSL_R_RENEGOTIATION_ENCODING_ERR),
+     "renegotiation encoding err"},
+    {ERR_REASON(SSL_R_RENEGOTIATION_MISMATCH), "renegotiation mismatch"},
+    {ERR_REASON(SSL_R_REQUIRED_CIPHER_MISSING), "required cipher missing"},
+    {ERR_REASON(SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING),
+     "required compression algorithm missing"},
+    {ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING),
+     "scsv received when renegotiating"},
+    {ERR_REASON(SSL_R_SCT_VERIFICATION_FAILED), "sct verification failed"},
+    {ERR_REASON(SSL_R_SERVERHELLO_TLSEXT), "serverhello tlsext"},
+    {ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),
+     "session id context uninitialized"},
+    {ERR_REASON(SSL_R_SHUTDOWN_WHILE_IN_INIT), "shutdown while in init"},
+    {ERR_REASON(SSL_R_SIGNATURE_ALGORITHMS_ERROR),
+     "signature algorithms error"},
+    {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),
+     "signature for non signing certificate"},
+    {ERR_REASON(SSL_R_SRP_A_CALC), "error with the srp params"},
+    {ERR_REASON(SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES),
+     "srtp could not allocate profiles"},
+    {ERR_REASON(SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG),
+     "srtp protection profile list too long"},
+    {ERR_REASON(SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE),
+     "srtp unknown protection profile"},
+    {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME),
+     "ssl3 ext invalid servername"},
+    {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE),
+     "ssl3 ext invalid servername type"},
+    {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_LONG), "ssl3 session id too long"},
+    {ERR_REASON(SSL_R_SSLV3_ALERT_BAD_CERTIFICATE),
+     "sslv3 alert bad certificate"},
+    {ERR_REASON(SSL_R_SSLV3_ALERT_BAD_RECORD_MAC),
+     "sslv3 alert bad record mac"},
+    {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED),
+     "sslv3 alert certificate expired"},
+    {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED),
+     "sslv3 alert certificate revoked"},
+    {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN),
+     "sslv3 alert certificate unknown"},
+    {ERR_REASON(SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE),
+     "sslv3 alert decompression failure"},
+    {ERR_REASON(SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE),
+     "sslv3 alert handshake failure"},
+    {ERR_REASON(SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER),
+     "sslv3 alert illegal parameter"},
+    {ERR_REASON(SSL_R_SSLV3_ALERT_NO_CERTIFICATE),
+     "sslv3 alert no certificate"},
+    {ERR_REASON(SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE),
+     "sslv3 alert unexpected message"},
+    {ERR_REASON(SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE),
+     "sslv3 alert unsupported certificate"},
+    {ERR_REASON(SSL_R_SSL_COMMAND_SECTION_EMPTY),
+     "ssl command section empty"},
+    {ERR_REASON(SSL_R_SSL_COMMAND_SECTION_NOT_FOUND),
+     "ssl command section not found"},
+    {ERR_REASON(SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION),
+     "ssl ctx has no default ssl version"},
+    {ERR_REASON(SSL_R_SSL_HANDSHAKE_FAILURE), "ssl handshake failure"},
+    {ERR_REASON(SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS),
+     "ssl library has no ciphers"},
+    {ERR_REASON(SSL_R_SSL_NEGATIVE_LENGTH), "ssl negative length"},
+    {ERR_REASON(SSL_R_SSL_SECTION_EMPTY), "ssl section empty"},
+    {ERR_REASON(SSL_R_SSL_SECTION_NOT_FOUND), "ssl section not found"},
+    {ERR_REASON(SSL_R_SSL_SESSION_ID_CALLBACK_FAILED),
+     "ssl session id callback failed"},
+    {ERR_REASON(SSL_R_SSL_SESSION_ID_CONFLICT), "ssl session id conflict"},
+    {ERR_REASON(SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG),
+     "ssl session id context too long"},
+    {ERR_REASON(SSL_R_SSL_SESSION_ID_TOO_LONG),
+     "ssl session id too long"},
+    {ERR_REASON(SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH),
+     "ssl session id has bad length"},
+    {ERR_REASON(SSL_R_SSL_SESSION_VERSION_MISMATCH),
+     "ssl session version mismatch"},
+    {ERR_REASON(SSL_R_TLSV1_ALERT_ACCESS_DENIED),
+     "tlsv1 alert access denied"},
+    {ERR_REASON(SSL_R_TLSV1_ALERT_DECODE_ERROR), "tlsv1 alert decode error"},
+    {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED),
+     "tlsv1 alert decryption failed"},
+    {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR),
+     "tlsv1 alert decrypt error"},
+    {ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION),
+     "tlsv1 alert export restriction"},
+    {ERR_REASON(SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK),
+     "tlsv1 alert inappropriate fallback"},
+    {ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY),
+     "tlsv1 alert insufficient security"},
+    {ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR),
+     "tlsv1 alert internal error"},
+    {ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION),
+     "tlsv1 alert no renegotiation"},
+    {ERR_REASON(SSL_R_TLSV1_ALERT_PROTOCOL_VERSION),
+     "tlsv1 alert protocol version"},
+    {ERR_REASON(SSL_R_TLSV1_ALERT_RECORD_OVERFLOW),
+     "tlsv1 alert record overflow"},
+    {ERR_REASON(SSL_R_TLSV1_ALERT_UNKNOWN_CA), "tlsv1 alert unknown ca"},
+    {ERR_REASON(SSL_R_TLSV1_ALERT_USER_CANCELLED),
+     "tlsv1 alert user cancelled"},
+    {ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE),
+     "tlsv1 bad certificate hash value"},
+    {ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE),
+     "tlsv1 bad certificate status response"},
+    {ERR_REASON(SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE),
+     "tlsv1 certificate unobtainable"},
+    {ERR_REASON(SSL_R_TLSV1_UNRECOGNIZED_NAME), "tlsv1 unrecognized name"},
+    {ERR_REASON(SSL_R_TLSV1_UNSUPPORTED_EXTENSION),
+     "tlsv1 unsupported extension"},
+    {ERR_REASON(SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT),
+     "peer does not accept heartbeats"},
+    {ERR_REASON(SSL_R_TLS_HEARTBEAT_PENDING),
+     "heartbeat request already pending"},
+    {ERR_REASON(SSL_R_TLS_ILLEGAL_EXPORTER_LABEL),
+     "tls illegal exporter label"},
+    {ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST),
+     "tls invalid ecpointformat list"},
+    {ERR_REASON(SSL_R_TOO_MANY_WARN_ALERTS), "too many warn alerts"},
+    {ERR_REASON(SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS),
+     "unable to find ecdh parameters"},
+    {ERR_REASON(SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS),
+     "unable to find public key parameters"},
+    {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES),
+     "unable to load ssl3 md5 routines"},
+    {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES),
+     "unable to load ssl3 sha1 routines"},
+    {ERR_REASON(SSL_R_UNEXPECTED_MESSAGE), "unexpected message"},
+    {ERR_REASON(SSL_R_UNEXPECTED_RECORD), "unexpected record"},
+    {ERR_REASON(SSL_R_UNINITIALIZED), "uninitialized"},
+    {ERR_REASON(SSL_R_UNKNOWN_ALERT_TYPE), "unknown alert type"},
+    {ERR_REASON(SSL_R_UNKNOWN_CERTIFICATE_TYPE), "unknown certificate type"},
+    {ERR_REASON(SSL_R_UNKNOWN_CIPHER_RETURNED), "unknown cipher returned"},
+    {ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE), "unknown cipher type"},
+    {ERR_REASON(SSL_R_UNKNOWN_CMD_NAME), "unknown cmd name"},
+    {ERR_REASON(SSL_R_UNKNOWN_COMMAND), "unknown command"},
+    {ERR_REASON(SSL_R_UNKNOWN_DIGEST), "unknown digest"},
+    {ERR_REASON(SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE),
+     "unknown key exchange type"},
+    {ERR_REASON(SSL_R_UNKNOWN_PKEY_TYPE), "unknown pkey type"},
+    {ERR_REASON(SSL_R_UNKNOWN_PROTOCOL), "unknown protocol"},
+    {ERR_REASON(SSL_R_UNKNOWN_SSL_VERSION), "unknown ssl version"},
+    {ERR_REASON(SSL_R_UNKNOWN_STATE), "unknown state"},
+    {ERR_REASON(SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED),
+     "unsafe legacy renegotiation disabled"},
+    {ERR_REASON(SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM),
+     "unsupported compression algorithm"},
+    {ERR_REASON(SSL_R_UNSUPPORTED_ELLIPTIC_CURVE),
+     "unsupported elliptic curve"},
+    {ERR_REASON(SSL_R_UNSUPPORTED_PROTOCOL), "unsupported protocol"},
+    {ERR_REASON(SSL_R_UNSUPPORTED_SSL_VERSION), "unsupported ssl version"},
+    {ERR_REASON(SSL_R_UNSUPPORTED_STATUS_TYPE), "unsupported status type"},
+    {ERR_REASON(SSL_R_USE_SRTP_NOT_NEGOTIATED), "use srtp not negotiated"},
+    {ERR_REASON(SSL_R_VERSION_TOO_HIGH), "version too high"},
+    {ERR_REASON(SSL_R_VERSION_TOO_LOW), "version too low"},
+    {ERR_REASON(SSL_R_WRONG_CERTIFICATE_TYPE), "wrong certificate type"},
+    {ERR_REASON(SSL_R_WRONG_CIPHER_RETURNED), "wrong cipher returned"},
+    {ERR_REASON(SSL_R_WRONG_CURVE), "wrong curve"},
+    {ERR_REASON(SSL_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"},
+    {ERR_REASON(SSL_R_WRONG_SIGNATURE_SIZE), "wrong signature size"},
+    {ERR_REASON(SSL_R_WRONG_SIGNATURE_TYPE), "wrong signature type"},
+    {ERR_REASON(SSL_R_WRONG_SSL_VERSION), "wrong ssl version"},
+    {ERR_REASON(SSL_R_WRONG_VERSION_NUMBER), "wrong version number"},
+    {ERR_REASON(SSL_R_X509_LIB), "x509 lib"},
+    {ERR_REASON(SSL_R_X509_VERIFICATION_SETUP_PROBLEMS),
+     "x509 verification setup problems"},
+    {0, NULL}
+};
+
+#endif
+
+int ERR_load_SSL_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(SSL_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, SSL_str_functs);
+        ERR_load_strings(0, SSL_str_reasons);
+    }
+#endif
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_init.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_init.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_init.c	(revision 331)
@@ -0,0 +1,210 @@
+/*
+ * 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 "e_os.h"
+
+#include "internal/err.h"
+#include <openssl/crypto.h>
+#include <openssl/evp.h>
+#include <assert.h>
+#include "ssl_locl.h"
+#include "internal/thread_once.h"
+
+static int stopped;
+
+static void ssl_library_stop(void);
+
+static CRYPTO_ONCE ssl_base = CRYPTO_ONCE_STATIC_INIT;
+static int ssl_base_inited = 0;
+DEFINE_RUN_ONCE_STATIC(ossl_init_ssl_base)
+{
+#ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr, "OPENSSL_INIT: ossl_init_ssl_base: "
+            "Adding SSL ciphers and digests\n");
+#endif
+#ifndef OPENSSL_NO_DES
+    EVP_add_cipher(EVP_des_cbc());
+    EVP_add_cipher(EVP_des_ede3_cbc());
+#endif
+#ifndef OPENSSL_NO_IDEA
+    EVP_add_cipher(EVP_idea_cbc());
+#endif
+#ifndef OPENSSL_NO_RC4
+    EVP_add_cipher(EVP_rc4());
+# ifndef OPENSSL_NO_MD5
+    EVP_add_cipher(EVP_rc4_hmac_md5());
+# endif
+#endif
+#ifndef OPENSSL_NO_RC2
+    EVP_add_cipher(EVP_rc2_cbc());
+    /*
+     * Not actually used for SSL/TLS but this makes PKCS#12 work if an
+     * application only calls SSL_library_init().
+     */
+    EVP_add_cipher(EVP_rc2_40_cbc());
+#endif
+    EVP_add_cipher(EVP_aes_128_cbc());
+    EVP_add_cipher(EVP_aes_192_cbc());
+    EVP_add_cipher(EVP_aes_256_cbc());
+    EVP_add_cipher(EVP_aes_128_gcm());
+    EVP_add_cipher(EVP_aes_256_gcm());
+    EVP_add_cipher(EVP_aes_128_ccm());
+    EVP_add_cipher(EVP_aes_256_ccm());
+    EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1());
+    EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
+    EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256());
+    EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256());
+#ifndef OPENSSL_NO_CAMELLIA
+    EVP_add_cipher(EVP_camellia_128_cbc());
+    EVP_add_cipher(EVP_camellia_256_cbc());
+#endif
+#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305)
+    EVP_add_cipher(EVP_chacha20_poly1305());
+#endif
+
+#ifndef OPENSSL_NO_SEED
+    EVP_add_cipher(EVP_seed_cbc());
+#endif
+
+#ifndef OPENSSL_NO_MD5
+    EVP_add_digest(EVP_md5());
+    EVP_add_digest_alias(SN_md5, "ssl3-md5");
+    EVP_add_digest(EVP_md5_sha1());
+#endif
+    EVP_add_digest(EVP_sha1()); /* RSA with sha1 */
+    EVP_add_digest_alias(SN_sha1, "ssl3-sha1");
+    EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA);
+    EVP_add_digest(EVP_sha224());
+    EVP_add_digest(EVP_sha256());
+    EVP_add_digest(EVP_sha384());
+    EVP_add_digest(EVP_sha512());
+#ifndef OPENSSL_NO_COMP
+# ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr, "OPENSSL_INIT: ossl_init_ssl_base: "
+            "SSL_COMP_get_compression_methods()\n");
+# endif
+    /*
+     * This will initialise the built-in compression algorithms. The value
+     * returned is a STACK_OF(SSL_COMP), but that can be discarded safely
+     */
+    SSL_COMP_get_compression_methods();
+#endif
+    /* initialize cipher/digest methods table */
+    ssl_load_ciphers();
+
+#ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr, "OPENSSL_INIT: ossl_init_ssl_base: "
+            "SSL_add_ssl_module()\n");
+#endif
+    SSL_add_ssl_module();
+    /*
+     * We ignore an error return here. Not much we can do - but not that bad
+     * either. We can still safely continue.
+     */
+    OPENSSL_atexit(ssl_library_stop);
+    ssl_base_inited = 1;
+    return 1;
+}
+
+static CRYPTO_ONCE ssl_strings = CRYPTO_ONCE_STATIC_INIT;
+static int ssl_strings_inited = 0;
+DEFINE_RUN_ONCE_STATIC(ossl_init_load_ssl_strings)
+{
+    /*
+     * OPENSSL_NO_AUTOERRINIT is provided here to prevent at compile time
+     * pulling in all the error strings during static linking
+     */
+#if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT)
+# ifdef OPENSSL_INIT_DEBUG
+    fprintf(stderr, "OPENSSL_INIT: ossl_init_load_ssl_strings: "
+            "ERR_load_SSL_strings()\n");
+# endif
+    ERR_load_SSL_strings();
+#endif
+    ssl_strings_inited = 1;
+    return 1;
+}
+
+DEFINE_RUN_ONCE_STATIC(ossl_init_no_load_ssl_strings)
+{
+    /* Do nothing in this case */
+    return 1;
+}
+
+static void ssl_library_stop(void)
+{
+    /* Might be explicitly called and also by atexit */
+    if (stopped)
+        return;
+    stopped = 1;
+
+    if (ssl_base_inited) {
+#ifndef OPENSSL_NO_COMP
+# ifdef OPENSSL_INIT_DEBUG
+        fprintf(stderr, "OPENSSL_INIT: ssl_library_stop: "
+                "ssl_comp_free_compression_methods_int()\n");
+# endif
+        ssl_comp_free_compression_methods_int();
+#endif
+    }
+
+    if (ssl_strings_inited) {
+#ifdef OPENSSL_INIT_DEBUG
+        fprintf(stderr, "OPENSSL_INIT: ssl_library_stop: "
+                "err_free_strings_int()\n");
+#endif
+        /*
+         * If both crypto and ssl error strings are inited we will end up
+         * calling err_free_strings_int() twice - but that's ok. The second
+         * time will be a no-op. It's easier to do that than to try and track
+         * between the two libraries whether they have both been inited.
+         */
+        err_free_strings_int();
+    }
+}
+
+/*
+ * If this function is called with a non NULL settings value then it must be
+ * called prior to any threads making calls to any OpenSSL functions,
+ * i.e. passing a non-null settings value is assumed to be single-threaded.
+ */
+int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS * settings)
+{
+    static int stoperrset = 0;
+
+    if (stopped) {
+        if (!stoperrset) {
+            /*
+             * We only ever set this once to avoid getting into an infinite
+             * loop where the error system keeps trying to init and fails so
+             * sets an error etc
+             */
+            stoperrset = 1;
+            SSLerr(SSL_F_OPENSSL_INIT_SSL, ERR_R_INIT_FAIL);
+        }
+        return 0;
+    }
+
+    if (!OPENSSL_init_crypto(opts | OPENSSL_INIT_ADD_ALL_CIPHERS
+                             | OPENSSL_INIT_ADD_ALL_DIGESTS, settings))
+        return 0;
+
+    if (!RUN_ONCE(&ssl_base, ossl_init_ssl_base))
+        return 0;
+
+    if ((opts & OPENSSL_INIT_NO_LOAD_SSL_STRINGS)
+        && !RUN_ONCE(&ssl_strings, ossl_init_no_load_ssl_strings))
+        return 0;
+
+    if ((opts & OPENSSL_INIT_LOAD_SSL_STRINGS)
+        && !RUN_ONCE(&ssl_strings, ossl_init_load_ssl_strings))
+        return 0;
+
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_lib.c	(revision 331)
@@ -0,0 +1,4282 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include "ssl_locl.h"
+#include <openssl/objects.h>
+#include <openssl/lhash.h>
+#include <openssl/x509v3.h>
+#include <openssl/rand.h>
+#include <openssl/ocsp.h>
+#include <openssl/dh.h>
+#include <openssl/engine.h>
+#include <openssl/async.h>
+#include <openssl/ct.h>
+
+const char SSL_version_str[] = OPENSSL_VERSION_TEXT;
+
+SSL3_ENC_METHOD ssl3_undef_enc_method = {
+    /*
+     * evil casts, but these functions are only called if there's a library
+     * bug
+     */
+    (int (*)(SSL *, SSL3_RECORD *, unsigned int, int))ssl_undefined_function,
+    (int (*)(SSL *, SSL3_RECORD *, unsigned char *, int))ssl_undefined_function,
+    ssl_undefined_function,
+    (int (*)(SSL *, unsigned char *, unsigned char *, int))
+        ssl_undefined_function,
+    (int (*)(SSL *, int))ssl_undefined_function,
+    (int (*)(SSL *, const char *, int, unsigned char *))
+        ssl_undefined_function,
+    0,                          /* finish_mac_length */
+    NULL,                       /* client_finished_label */
+    0,                          /* client_finished_label_len */
+    NULL,                       /* server_finished_label */
+    0,                          /* server_finished_label_len */
+    (int (*)(int))ssl_undefined_function,
+    (int (*)(SSL *, unsigned char *, size_t, const char *,
+             size_t, const unsigned char *, size_t,
+             int use_context))ssl_undefined_function,
+};
+
+struct ssl_async_args {
+    SSL *s;
+    void *buf;
+    int num;
+    enum { READFUNC, WRITEFUNC, OTHERFUNC } type;
+    union {
+        int (*func_read) (SSL *, void *, int);
+        int (*func_write) (SSL *, const void *, int);
+        int (*func_other) (SSL *);
+    } f;
+};
+
+static const struct {
+    uint8_t mtype;
+    uint8_t ord;
+    int nid;
+} dane_mds[] = {
+    {
+        DANETLS_MATCHING_FULL, 0, NID_undef
+    },
+    {
+        DANETLS_MATCHING_2256, 1, NID_sha256
+    },
+    {
+        DANETLS_MATCHING_2512, 2, NID_sha512
+    },
+};
+
+static int dane_ctx_enable(struct dane_ctx_st *dctx)
+{
+    const EVP_MD **mdevp;
+    uint8_t *mdord;
+    uint8_t mdmax = DANETLS_MATCHING_LAST;
+    int n = ((int)mdmax) + 1;   /* int to handle PrivMatch(255) */
+    size_t i;
+
+    if (dctx->mdevp != NULL)
+        return 1;
+
+    mdevp = OPENSSL_zalloc(n * sizeof(*mdevp));
+    mdord = OPENSSL_zalloc(n * sizeof(*mdord));
+
+    if (mdord == NULL || mdevp == NULL) {
+        OPENSSL_free(mdord);
+        OPENSSL_free(mdevp);
+        SSLerr(SSL_F_DANE_CTX_ENABLE, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    /* Install default entries */
+    for (i = 0; i < OSSL_NELEM(dane_mds); ++i) {
+        const EVP_MD *md;
+
+        if (dane_mds[i].nid == NID_undef ||
+            (md = EVP_get_digestbynid(dane_mds[i].nid)) == NULL)
+            continue;
+        mdevp[dane_mds[i].mtype] = md;
+        mdord[dane_mds[i].mtype] = dane_mds[i].ord;
+    }
+
+    dctx->mdevp = mdevp;
+    dctx->mdord = mdord;
+    dctx->mdmax = mdmax;
+
+    return 1;
+}
+
+static void dane_ctx_final(struct dane_ctx_st *dctx)
+{
+    OPENSSL_free(dctx->mdevp);
+    dctx->mdevp = NULL;
+
+    OPENSSL_free(dctx->mdord);
+    dctx->mdord = NULL;
+    dctx->mdmax = 0;
+}
+
+static void tlsa_free(danetls_record *t)
+{
+    if (t == NULL)
+        return;
+    OPENSSL_free(t->data);
+    EVP_PKEY_free(t->spki);
+    OPENSSL_free(t);
+}
+
+static void dane_final(SSL_DANE *dane)
+{
+    sk_danetls_record_pop_free(dane->trecs, tlsa_free);
+    dane->trecs = NULL;
+
+    sk_X509_pop_free(dane->certs, X509_free);
+    dane->certs = NULL;
+
+    X509_free(dane->mcert);
+    dane->mcert = NULL;
+    dane->mtlsa = NULL;
+    dane->mdpth = -1;
+    dane->pdpth = -1;
+}
+
+/*
+ * dane_copy - Copy dane configuration, sans verification state.
+ */
+static int ssl_dane_dup(SSL *to, SSL *from)
+{
+    int num;
+    int i;
+
+    if (!DANETLS_ENABLED(&from->dane))
+        return 1;
+
+    dane_final(&to->dane);
+    to->dane.flags = from->dane.flags;
+    to->dane.dctx = &to->ctx->dane;
+    to->dane.trecs = sk_danetls_record_new_null();
+
+    if (to->dane.trecs == NULL) {
+        SSLerr(SSL_F_SSL_DANE_DUP, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    num = sk_danetls_record_num(from->dane.trecs);
+    for (i = 0; i < num; ++i) {
+        danetls_record *t = sk_danetls_record_value(from->dane.trecs, i);
+
+        if (SSL_dane_tlsa_add(to, t->usage, t->selector, t->mtype,
+                              t->data, t->dlen) <= 0)
+            return 0;
+    }
+    return 1;
+}
+
+static int dane_mtype_set(struct dane_ctx_st *dctx,
+                          const EVP_MD *md, uint8_t mtype, uint8_t ord)
+{
+    int i;
+
+    if (mtype == DANETLS_MATCHING_FULL && md != NULL) {
+        SSLerr(SSL_F_DANE_MTYPE_SET, SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL);
+        return 0;
+    }
+
+    if (mtype > dctx->mdmax) {
+        const EVP_MD **mdevp;
+        uint8_t *mdord;
+        int n = ((int)mtype) + 1;
+
+        mdevp = OPENSSL_realloc(dctx->mdevp, n * sizeof(*mdevp));
+        if (mdevp == NULL) {
+            SSLerr(SSL_F_DANE_MTYPE_SET, ERR_R_MALLOC_FAILURE);
+            return -1;
+        }
+        dctx->mdevp = mdevp;
+
+        mdord = OPENSSL_realloc(dctx->mdord, n * sizeof(*mdord));
+        if (mdord == NULL) {
+            SSLerr(SSL_F_DANE_MTYPE_SET, ERR_R_MALLOC_FAILURE);
+            return -1;
+        }
+        dctx->mdord = mdord;
+
+        /* Zero-fill any gaps */
+        for (i = dctx->mdmax + 1; i < mtype; ++i) {
+            mdevp[i] = NULL;
+            mdord[i] = 0;
+        }
+
+        dctx->mdmax = mtype;
+    }
+
+    dctx->mdevp[mtype] = md;
+    /* Coerce ordinal of disabled matching types to 0 */
+    dctx->mdord[mtype] = (md == NULL) ? 0 : ord;
+
+    return 1;
+}
+
+static const EVP_MD *tlsa_md_get(SSL_DANE *dane, uint8_t mtype)
+{
+    if (mtype > dane->dctx->mdmax)
+        return NULL;
+    return dane->dctx->mdevp[mtype];
+}
+
+static int dane_tlsa_add(SSL_DANE *dane,
+                         uint8_t usage,
+                         uint8_t selector,
+                         uint8_t mtype, unsigned char *data, size_t dlen)
+{
+    danetls_record *t;
+    const EVP_MD *md = NULL;
+    int ilen = (int)dlen;
+    int i;
+    int num;
+
+    if (dane->trecs == NULL) {
+        SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_NOT_ENABLED);
+        return -1;
+    }
+
+    if (ilen < 0 || dlen != (size_t)ilen) {
+        SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_DATA_LENGTH);
+        return 0;
+    }
+
+    if (usage > DANETLS_USAGE_LAST) {
+        SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE);
+        return 0;
+    }
+
+    if (selector > DANETLS_SELECTOR_LAST) {
+        SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_SELECTOR);
+        return 0;
+    }
+
+    if (mtype != DANETLS_MATCHING_FULL) {
+        md = tlsa_md_get(dane, mtype);
+        if (md == NULL) {
+            SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_MATCHING_TYPE);
+            return 0;
+        }
+    }
+
+    if (md != NULL && dlen != (size_t)EVP_MD_size(md)) {
+        SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH);
+        return 0;
+    }
+    if (!data) {
+        SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_NULL_DATA);
+        return 0;
+    }
+
+    if ((t = OPENSSL_zalloc(sizeof(*t))) == NULL) {
+        SSLerr(SSL_F_DANE_TLSA_ADD, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+
+    t->usage = usage;
+    t->selector = selector;
+    t->mtype = mtype;
+    t->data = OPENSSL_malloc(ilen);
+    if (t->data == NULL) {
+        tlsa_free(t);
+        SSLerr(SSL_F_DANE_TLSA_ADD, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+    memcpy(t->data, data, ilen);
+    t->dlen = ilen;
+
+    /* Validate and cache full certificate or public key */
+    if (mtype == DANETLS_MATCHING_FULL) {
+        const unsigned char *p = data;
+        X509 *cert = NULL;
+        EVP_PKEY *pkey = NULL;
+
+        switch (selector) {
+        case DANETLS_SELECTOR_CERT:
+            if (!d2i_X509(&cert, &p, dlen) || p < data ||
+                dlen != (size_t)(p - data)) {
+                tlsa_free(t);
+                SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_CERTIFICATE);
+                return 0;
+            }
+            if (X509_get0_pubkey(cert) == NULL) {
+                tlsa_free(t);
+                SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_CERTIFICATE);
+                return 0;
+            }
+
+            if ((DANETLS_USAGE_BIT(usage) & DANETLS_TA_MASK) == 0) {
+                X509_free(cert);
+                break;
+            }
+
+            /*
+             * For usage DANE-TA(2), we support authentication via "2 0 0" TLSA
+             * records that contain full certificates of trust-anchors that are
+             * not present in the wire chain.  For usage PKIX-TA(0), we augment
+             * the chain with untrusted Full(0) certificates from DNS, in case
+             * they are missing from the chain.
+             */
+            if ((dane->certs == NULL &&
+                 (dane->certs = sk_X509_new_null()) == NULL) ||
+                !sk_X509_push(dane->certs, cert)) {
+                SSLerr(SSL_F_DANE_TLSA_ADD, ERR_R_MALLOC_FAILURE);
+                X509_free(cert);
+                tlsa_free(t);
+                return -1;
+            }
+            break;
+
+        case DANETLS_SELECTOR_SPKI:
+            if (!d2i_PUBKEY(&pkey, &p, dlen) || p < data ||
+                dlen != (size_t)(p - data)) {
+                tlsa_free(t);
+                SSLerr(SSL_F_DANE_TLSA_ADD, SSL_R_DANE_TLSA_BAD_PUBLIC_KEY);
+                return 0;
+            }
+
+            /*
+             * For usage DANE-TA(2), we support authentication via "2 1 0" TLSA
+             * records that contain full bare keys of trust-anchors that are
+             * not present in the wire chain.
+             */
+            if (usage == DANETLS_USAGE_DANE_TA)
+                t->spki = pkey;
+            else
+                EVP_PKEY_free(pkey);
+            break;
+        }
+    }
+
+    /*-
+     * Find the right insertion point for the new record.
+     *
+     * See crypto/x509/x509_vfy.c.  We sort DANE-EE(3) records first, so that
+     * they can be processed first, as they require no chain building, and no
+     * expiration or hostname checks.  Because DANE-EE(3) is numerically
+     * largest, this is accomplished via descending sort by "usage".
+     *
+     * We also sort in descending order by matching ordinal to simplify
+     * the implementation of digest agility in the verification code.
+     *
+     * The choice of order for the selector is not significant, so we
+     * use the same descending order for consistency.
+     */
+    num = sk_danetls_record_num(dane->trecs);
+    for (i = 0; i < num; ++i) {
+        danetls_record *rec = sk_danetls_record_value(dane->trecs, i);
+
+        if (rec->usage > usage)
+            continue;
+        if (rec->usage < usage)
+            break;
+        if (rec->selector > selector)
+            continue;
+        if (rec->selector < selector)
+            break;
+        if (dane->dctx->mdord[rec->mtype] > dane->dctx->mdord[mtype])
+            continue;
+        break;
+    }
+
+    if (!sk_danetls_record_insert(dane->trecs, t, i)) {
+        tlsa_free(t);
+        SSLerr(SSL_F_DANE_TLSA_ADD, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+    dane->umask |= DANETLS_USAGE_BIT(usage);
+
+    return 1;
+}
+
+static void clear_ciphers(SSL *s)
+{
+    /* clear the current cipher */
+    ssl_clear_cipher_ctx(s);
+    ssl_clear_hash_ctx(&s->read_hash);
+    ssl_clear_hash_ctx(&s->write_hash);
+}
+
+int SSL_clear(SSL *s)
+{
+    if (s->method == NULL) {
+        SSLerr(SSL_F_SSL_CLEAR, SSL_R_NO_METHOD_SPECIFIED);
+        return (0);
+    }
+
+    if (ssl_clear_bad_session(s)) {
+        SSL_SESSION_free(s->session);
+        s->session = NULL;
+    }
+
+    s->error = 0;
+    s->hit = 0;
+    s->shutdown = 0;
+
+    if (s->renegotiate) {
+        SSLerr(SSL_F_SSL_CLEAR, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    ossl_statem_clear(s);
+
+    s->version = s->method->version;
+    s->client_version = s->version;
+    s->rwstate = SSL_NOTHING;
+
+    BUF_MEM_free(s->init_buf);
+    s->init_buf = NULL;
+    clear_ciphers(s);
+    s->first_packet = 0;
+
+    /* Reset DANE verification result state */
+    s->dane.mdpth = -1;
+    s->dane.pdpth = -1;
+    X509_free(s->dane.mcert);
+    s->dane.mcert = NULL;
+    s->dane.mtlsa = NULL;
+
+    /* Clear the verification result peername */
+    X509_VERIFY_PARAM_move_peername(s->param, NULL);
+
+    /*
+     * Check to see if we were changed into a different method, if so, revert
+     * back if we are not doing session-id reuse.
+     */
+    if (!ossl_statem_get_in_handshake(s) && (s->session == NULL)
+        && (s->method != s->ctx->method)) {
+        s->method->ssl_free(s);
+        s->method = s->ctx->method;
+        if (!s->method->ssl_new(s))
+            return (0);
+    } else
+        s->method->ssl_clear(s);
+
+    RECORD_LAYER_clear(&s->rlayer);
+
+    return (1);
+}
+
+/** Used to change an SSL_CTXs default SSL method type */
+int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth)
+{
+    STACK_OF(SSL_CIPHER) *sk;
+
+    ctx->method = meth;
+
+    sk = ssl_create_cipher_list(ctx->method, &(ctx->cipher_list),
+                                &(ctx->cipher_list_by_id),
+                                SSL_DEFAULT_CIPHER_LIST, ctx->cert);
+    if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0)) {
+        SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION, SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS);
+        return (0);
+    }
+    return (1);
+}
+
+SSL *SSL_new(SSL_CTX *ctx)
+{
+    SSL *s;
+
+    if (ctx == NULL) {
+        SSLerr(SSL_F_SSL_NEW, SSL_R_NULL_SSL_CTX);
+        return (NULL);
+    }
+    if (ctx->method == NULL) {
+        SSLerr(SSL_F_SSL_NEW, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION);
+        return (NULL);
+    }
+
+    s = OPENSSL_zalloc(sizeof(*s));
+    if (s == NULL)
+        goto err;
+
+    s->lock = CRYPTO_THREAD_lock_new();
+    if (s->lock == NULL) {
+        SSLerr(SSL_F_SSL_NEW, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(s);
+        return NULL;
+    }
+
+    RECORD_LAYER_init(&s->rlayer, s);
+
+    s->options = ctx->options;
+    s->dane.flags = ctx->dane.flags;
+    s->min_proto_version = ctx->min_proto_version;
+    s->max_proto_version = ctx->max_proto_version;
+    s->mode = ctx->mode;
+    s->max_cert_list = ctx->max_cert_list;
+    s->references = 1;
+
+    /*
+     * Earlier library versions used to copy the pointer to the CERT, not
+     * its contents; only when setting new parameters for the per-SSL
+     * copy, ssl_cert_new would be called (and the direct reference to
+     * the per-SSL_CTX settings would be lost, but those still were
+     * indirectly accessed for various purposes, and for that reason they
+     * used to be known as s->ctx->default_cert). Now we don't look at the
+     * SSL_CTX's CERT after having duplicated it once.
+     */
+    s->cert = ssl_cert_dup(ctx->cert);
+    if (s->cert == NULL)
+        goto err;
+
+    RECORD_LAYER_set_read_ahead(&s->rlayer, ctx->read_ahead);
+    s->msg_callback = ctx->msg_callback;
+    s->msg_callback_arg = ctx->msg_callback_arg;
+    s->verify_mode = ctx->verify_mode;
+    s->not_resumable_session_cb = ctx->not_resumable_session_cb;
+    s->sid_ctx_length = ctx->sid_ctx_length;
+    OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx);
+    memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx));
+    s->verify_callback = ctx->default_verify_callback;
+    s->generate_session_id = ctx->generate_session_id;
+
+    s->param = X509_VERIFY_PARAM_new();
+    if (s->param == NULL)
+        goto err;
+    X509_VERIFY_PARAM_inherit(s->param, ctx->param);
+    s->quiet_shutdown = ctx->quiet_shutdown;
+    s->max_send_fragment = ctx->max_send_fragment;
+    s->split_send_fragment = ctx->split_send_fragment;
+    s->max_pipelines = ctx->max_pipelines;
+    if (s->max_pipelines > 1)
+        RECORD_LAYER_set_read_ahead(&s->rlayer, 1);
+    if (ctx->default_read_buf_len > 0)
+        SSL_set_default_read_buffer_len(s, ctx->default_read_buf_len);
+
+    SSL_CTX_up_ref(ctx);
+    s->ctx = ctx;
+    s->tlsext_debug_cb = 0;
+    s->tlsext_debug_arg = NULL;
+    s->tlsext_ticket_expected = 0;
+    s->tlsext_status_type = ctx->tlsext_status_type;
+    s->tlsext_status_expected = 0;
+    s->tlsext_ocsp_ids = NULL;
+    s->tlsext_ocsp_exts = NULL;
+    s->tlsext_ocsp_resp = NULL;
+    s->tlsext_ocsp_resplen = -1;
+    SSL_CTX_up_ref(ctx);
+    s->session_ctx = ctx;
+#ifndef OPENSSL_NO_EC
+    if (ctx->tlsext_ecpointformatlist) {
+        s->tlsext_ecpointformatlist =
+            OPENSSL_memdup(ctx->tlsext_ecpointformatlist,
+                           ctx->tlsext_ecpointformatlist_length);
+        if (!s->tlsext_ecpointformatlist)
+            goto err;
+        s->tlsext_ecpointformatlist_length =
+            ctx->tlsext_ecpointformatlist_length;
+    }
+    if (ctx->tlsext_ellipticcurvelist) {
+        s->tlsext_ellipticcurvelist =
+            OPENSSL_memdup(ctx->tlsext_ellipticcurvelist,
+                           ctx->tlsext_ellipticcurvelist_length);
+        if (!s->tlsext_ellipticcurvelist)
+            goto err;
+        s->tlsext_ellipticcurvelist_length =
+            ctx->tlsext_ellipticcurvelist_length;
+    }
+#endif
+#ifndef OPENSSL_NO_NEXTPROTONEG
+    s->next_proto_negotiated = NULL;
+#endif
+
+    if (s->ctx->alpn_client_proto_list) {
+        s->alpn_client_proto_list =
+            OPENSSL_malloc(s->ctx->alpn_client_proto_list_len);
+        if (s->alpn_client_proto_list == NULL)
+            goto err;
+        memcpy(s->alpn_client_proto_list, s->ctx->alpn_client_proto_list,
+               s->ctx->alpn_client_proto_list_len);
+        s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len;
+    }
+
+    s->verified_chain = NULL;
+    s->verify_result = X509_V_OK;
+
+    s->default_passwd_callback = ctx->default_passwd_callback;
+    s->default_passwd_callback_userdata = ctx->default_passwd_callback_userdata;
+
+    s->method = ctx->method;
+
+    if (!s->method->ssl_new(s))
+        goto err;
+
+    s->server = (ctx->method->ssl_accept == ssl_undefined_function) ? 0 : 1;
+
+    if (!SSL_clear(s))
+        goto err;
+
+    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data))
+        goto err;
+
+#ifndef OPENSSL_NO_PSK
+    s->psk_client_callback = ctx->psk_client_callback;
+    s->psk_server_callback = ctx->psk_server_callback;
+#endif
+
+    s->job = NULL;
+
+#ifndef OPENSSL_NO_CT
+    if (!SSL_set_ct_validation_callback(s, ctx->ct_validation_callback,
+                                        ctx->ct_validation_callback_arg))
+        goto err;
+#endif
+
+    return s;
+ err:
+    SSL_free(s);
+    SSLerr(SSL_F_SSL_NEW, ERR_R_MALLOC_FAILURE);
+    return NULL;
+}
+
+int SSL_is_dtls(const SSL *s)
+{
+    return SSL_IS_DTLS(s) ? 1 : 0;
+}
+
+int SSL_up_ref(SSL *s)
+{
+    int i;
+
+    if (CRYPTO_atomic_add(&s->references, 1, &i, s->lock) <= 0)
+        return 0;
+
+    REF_PRINT_COUNT("SSL", s);
+    REF_ASSERT_ISNT(i < 2);
+    return ((i > 1) ? 1 : 0);
+}
+
+int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx,
+                                   unsigned int sid_ctx_len)
+{
+    if (sid_ctx_len > sizeof ctx->sid_ctx) {
+        SSLerr(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT,
+               SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
+        return 0;
+    }
+    ctx->sid_ctx_length = sid_ctx_len;
+    memcpy(ctx->sid_ctx, sid_ctx, sid_ctx_len);
+
+    return 1;
+}
+
+int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx,
+                               unsigned int sid_ctx_len)
+{
+    if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
+        SSLerr(SSL_F_SSL_SET_SESSION_ID_CONTEXT,
+               SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
+        return 0;
+    }
+    ssl->sid_ctx_length = sid_ctx_len;
+    memcpy(ssl->sid_ctx, sid_ctx, sid_ctx_len);
+
+    return 1;
+}
+
+int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb)
+{
+    CRYPTO_THREAD_write_lock(ctx->lock);
+    ctx->generate_session_id = cb;
+    CRYPTO_THREAD_unlock(ctx->lock);
+    return 1;
+}
+
+int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb)
+{
+    CRYPTO_THREAD_write_lock(ssl->lock);
+    ssl->generate_session_id = cb;
+    CRYPTO_THREAD_unlock(ssl->lock);
+    return 1;
+}
+
+int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
+                                unsigned int id_len)
+{
+    /*
+     * A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how
+     * we can "construct" a session to give us the desired check - ie. to
+     * find if there's a session in the hash table that would conflict with
+     * any new session built out of this id/id_len and the ssl_version in use
+     * by this SSL.
+     */
+    SSL_SESSION r, *p;
+
+    if (id_len > sizeof r.session_id)
+        return 0;
+
+    r.ssl_version = ssl->version;
+    r.session_id_length = id_len;
+    memcpy(r.session_id, id, id_len);
+
+    CRYPTO_THREAD_read_lock(ssl->session_ctx->lock);
+    p = lh_SSL_SESSION_retrieve(ssl->session_ctx->sessions, &r);
+    CRYPTO_THREAD_unlock(ssl->session_ctx->lock);
+    return (p != NULL);
+}
+
+int SSL_CTX_set_purpose(SSL_CTX *s, int purpose)
+{
+    return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
+}
+
+int SSL_set_purpose(SSL *s, int purpose)
+{
+    return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
+}
+
+int SSL_CTX_set_trust(SSL_CTX *s, int trust)
+{
+    return X509_VERIFY_PARAM_set_trust(s->param, trust);
+}
+
+int SSL_set_trust(SSL *s, int trust)
+{
+    return X509_VERIFY_PARAM_set_trust(s->param, trust);
+}
+
+int SSL_set1_host(SSL *s, const char *hostname)
+{
+    return X509_VERIFY_PARAM_set1_host(s->param, hostname, 0);
+}
+
+int SSL_add1_host(SSL *s, const char *hostname)
+{
+    return X509_VERIFY_PARAM_add1_host(s->param, hostname, 0);
+}
+
+void SSL_set_hostflags(SSL *s, unsigned int flags)
+{
+    X509_VERIFY_PARAM_set_hostflags(s->param, flags);
+}
+
+const char *SSL_get0_peername(SSL *s)
+{
+    return X509_VERIFY_PARAM_get0_peername(s->param);
+}
+
+int SSL_CTX_dane_enable(SSL_CTX *ctx)
+{
+    return dane_ctx_enable(&ctx->dane);
+}
+
+unsigned long SSL_CTX_dane_set_flags(SSL_CTX *ctx, unsigned long flags)
+{
+    unsigned long orig = ctx->dane.flags;
+
+    ctx->dane.flags |= flags;
+    return orig;
+}
+
+unsigned long SSL_CTX_dane_clear_flags(SSL_CTX *ctx, unsigned long flags)
+{
+    unsigned long orig = ctx->dane.flags;
+
+    ctx->dane.flags &= ~flags;
+    return orig;
+}
+
+int SSL_dane_enable(SSL *s, const char *basedomain)
+{
+    SSL_DANE *dane = &s->dane;
+
+    if (s->ctx->dane.mdmax == 0) {
+        SSLerr(SSL_F_SSL_DANE_ENABLE, SSL_R_CONTEXT_NOT_DANE_ENABLED);
+        return 0;
+    }
+    if (dane->trecs != NULL) {
+        SSLerr(SSL_F_SSL_DANE_ENABLE, SSL_R_DANE_ALREADY_ENABLED);
+        return 0;
+    }
+
+    /*
+     * Default SNI name.  This rejects empty names, while set1_host below
+     * accepts them and disables host name checks.  To avoid side-effects with
+     * invalid input, set the SNI name first.
+     */
+    if (s->tlsext_hostname == NULL) {
+        if (!SSL_set_tlsext_host_name(s, basedomain)) {
+            SSLerr(SSL_F_SSL_DANE_ENABLE, SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN);
+            return -1;
+        }
+    }
+
+    /* Primary RFC6125 reference identifier */
+    if (!X509_VERIFY_PARAM_set1_host(s->param, basedomain, 0)) {
+        SSLerr(SSL_F_SSL_DANE_ENABLE, SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN);
+        return -1;
+    }
+
+    dane->mdpth = -1;
+    dane->pdpth = -1;
+    dane->dctx = &s->ctx->dane;
+    dane->trecs = sk_danetls_record_new_null();
+
+    if (dane->trecs == NULL) {
+        SSLerr(SSL_F_SSL_DANE_ENABLE, ERR_R_MALLOC_FAILURE);
+        return -1;
+    }
+    return 1;
+}
+
+unsigned long SSL_dane_set_flags(SSL *ssl, unsigned long flags)
+{
+    unsigned long orig = ssl->dane.flags;
+
+    ssl->dane.flags |= flags;
+    return orig;
+}
+
+unsigned long SSL_dane_clear_flags(SSL *ssl, unsigned long flags)
+{
+    unsigned long orig = ssl->dane.flags;
+
+    ssl->dane.flags &= ~flags;
+    return orig;
+}
+
+int SSL_get0_dane_authority(SSL *s, X509 **mcert, EVP_PKEY **mspki)
+{
+    SSL_DANE *dane = &s->dane;
+
+    if (!DANETLS_ENABLED(dane) || s->verify_result != X509_V_OK)
+        return -1;
+    if (dane->mtlsa) {
+        if (mcert)
+            *mcert = dane->mcert;
+        if (mspki)
+            *mspki = (dane->mcert == NULL) ? dane->mtlsa->spki : NULL;
+    }
+    return dane->mdpth;
+}
+
+int SSL_get0_dane_tlsa(SSL *s, uint8_t *usage, uint8_t *selector,
+                       uint8_t *mtype, unsigned const char **data, size_t *dlen)
+{
+    SSL_DANE *dane = &s->dane;
+
+    if (!DANETLS_ENABLED(dane) || s->verify_result != X509_V_OK)
+        return -1;
+    if (dane->mtlsa) {
+        if (usage)
+            *usage = dane->mtlsa->usage;
+        if (selector)
+            *selector = dane->mtlsa->selector;
+        if (mtype)
+            *mtype = dane->mtlsa->mtype;
+        if (data)
+            *data = dane->mtlsa->data;
+        if (dlen)
+            *dlen = dane->mtlsa->dlen;
+    }
+    return dane->mdpth;
+}
+
+SSL_DANE *SSL_get0_dane(SSL *s)
+{
+    return &s->dane;
+}
+
+int SSL_dane_tlsa_add(SSL *s, uint8_t usage, uint8_t selector,
+                      uint8_t mtype, unsigned char *data, size_t dlen)
+{
+    return dane_tlsa_add(&s->dane, usage, selector, mtype, data, dlen);
+}
+
+int SSL_CTX_dane_mtype_set(SSL_CTX *ctx, const EVP_MD *md, uint8_t mtype,
+                           uint8_t ord)
+{
+    return dane_mtype_set(&ctx->dane, md, mtype, ord);
+}
+
+int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm)
+{
+    return X509_VERIFY_PARAM_set1(ctx->param, vpm);
+}
+
+int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm)
+{
+    return X509_VERIFY_PARAM_set1(ssl->param, vpm);
+}
+
+X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx)
+{
+    return ctx->param;
+}
+
+X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl)
+{
+    return ssl->param;
+}
+
+void SSL_certs_clear(SSL *s)
+{
+    ssl_cert_clear_certs(s->cert);
+}
+
+void SSL_free(SSL *s)
+{
+    int i;
+
+    if (s == NULL)
+        return;
+
+    CRYPTO_atomic_add(&s->references, -1, &i, s->lock);
+    REF_PRINT_COUNT("SSL", s);
+    if (i > 0)
+        return;
+    REF_ASSERT_ISNT(i < 0);
+
+    X509_VERIFY_PARAM_free(s->param);
+    dane_final(&s->dane);
+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
+
+    ssl_free_wbio_buffer(s);
+
+    BIO_free_all(s->wbio);
+    BIO_free_all(s->rbio);
+
+    BUF_MEM_free(s->init_buf);
+
+    /* add extra stuff */
+    sk_SSL_CIPHER_free(s->cipher_list);
+    sk_SSL_CIPHER_free(s->cipher_list_by_id);
+
+    /* Make the next call work :-) */
+    if (s->session != NULL) {
+        ssl_clear_bad_session(s);
+        SSL_SESSION_free(s->session);
+    }
+
+    clear_ciphers(s);
+
+    ssl_cert_free(s->cert);
+    /* Free up if allocated */
+
+    OPENSSL_free(s->tlsext_hostname);
+    SSL_CTX_free(s->session_ctx);
+#ifndef OPENSSL_NO_EC
+    OPENSSL_free(s->tlsext_ecpointformatlist);
+    OPENSSL_free(s->tlsext_ellipticcurvelist);
+#endif                          /* OPENSSL_NO_EC */
+    sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, X509_EXTENSION_free);
+#ifndef OPENSSL_NO_OCSP
+    sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free);
+#endif
+#ifndef OPENSSL_NO_CT
+    SCT_LIST_free(s->scts);
+    OPENSSL_free(s->tlsext_scts);
+#endif
+    OPENSSL_free(s->tlsext_ocsp_resp);
+    OPENSSL_free(s->alpn_client_proto_list);
+
+    sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free);
+
+    sk_X509_pop_free(s->verified_chain, X509_free);
+
+    if (s->method != NULL)
+        s->method->ssl_free(s);
+
+    RECORD_LAYER_release(&s->rlayer);
+
+    SSL_CTX_free(s->ctx);
+
+    ASYNC_WAIT_CTX_free(s->waitctx);
+
+#if !defined(OPENSSL_NO_NEXTPROTONEG)
+    OPENSSL_free(s->next_proto_negotiated);
+#endif
+
+#ifndef OPENSSL_NO_SRTP
+    sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
+#endif
+
+    CRYPTO_THREAD_lock_free(s->lock);
+
+    OPENSSL_free(s);
+}
+
+void SSL_set0_rbio(SSL *s, BIO *rbio)
+{
+    BIO_free_all(s->rbio);
+    s->rbio = rbio;
+}
+
+void SSL_set0_wbio(SSL *s, BIO *wbio)
+{
+    /*
+     * If the output buffering BIO is still in place, remove it
+     */
+    if (s->bbio != NULL)
+        s->wbio = BIO_pop(s->wbio);
+
+    BIO_free_all(s->wbio);
+    s->wbio = wbio;
+
+    /* Re-attach |bbio| to the new |wbio|. */
+    if (s->bbio != NULL)
+        s->wbio = BIO_push(s->bbio, s->wbio);
+}
+
+void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio)
+{
+    /*
+     * For historical reasons, this function has many different cases in
+     * ownership handling.
+     */
+
+    /* If nothing has changed, do nothing */
+    if (rbio == SSL_get_rbio(s) && wbio == SSL_get_wbio(s))
+        return;
+
+    /*
+     * If the two arguments are equal then one fewer reference is granted by the
+     * caller than we want to take
+     */
+    if (rbio != NULL && rbio == wbio)
+        BIO_up_ref(rbio);
+
+    /*
+     * If only the wbio is changed only adopt one reference.
+     */
+    if (rbio == SSL_get_rbio(s)) {
+        SSL_set0_wbio(s, wbio);
+        return;
+    }
+    /*
+     * There is an asymmetry here for historical reasons. If only the rbio is
+     * changed AND the rbio and wbio were originally different, then we only
+     * adopt one reference.
+     */
+    if (wbio == SSL_get_wbio(s) && SSL_get_rbio(s) != SSL_get_wbio(s)) {
+        SSL_set0_rbio(s, rbio);
+        return;
+    }
+
+    /* Otherwise, adopt both references. */
+    SSL_set0_rbio(s, rbio);
+    SSL_set0_wbio(s, wbio);
+}
+
+BIO *SSL_get_rbio(const SSL *s)
+{
+    return s->rbio;
+}
+
+BIO *SSL_get_wbio(const SSL *s)
+{
+    if (s->bbio != NULL) {
+        /*
+         * If |bbio| is active, the true caller-configured BIO is its
+         * |next_bio|.
+         */
+        return BIO_next(s->bbio);
+    }
+    return s->wbio;
+}
+
+int SSL_get_fd(const SSL *s)
+{
+    return SSL_get_rfd(s);
+}
+
+int SSL_get_rfd(const SSL *s)
+{
+    int ret = -1;
+    BIO *b, *r;
+
+    b = SSL_get_rbio(s);
+    r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR);
+    if (r != NULL)
+        BIO_get_fd(r, &ret);
+    return (ret);
+}
+
+int SSL_get_wfd(const SSL *s)
+{
+    int ret = -1;
+    BIO *b, *r;
+
+    b = SSL_get_wbio(s);
+    r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR);
+    if (r != NULL)
+        BIO_get_fd(r, &ret);
+    return (ret);
+}
+
+#ifndef OPENSSL_NO_SOCK
+int SSL_set_fd(SSL *s, int fd)
+{
+    int ret = 0;
+    BIO *bio = NULL;
+
+    bio = BIO_new(BIO_s_socket());
+
+    if (bio == NULL) {
+        SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
+        goto err;
+    }
+    BIO_set_fd(bio, fd, BIO_NOCLOSE);
+    SSL_set_bio(s, bio, bio);
+    ret = 1;
+ err:
+    return (ret);
+}
+
+int SSL_set_wfd(SSL *s, int fd)
+{
+    BIO *rbio = SSL_get_rbio(s);
+
+    if (rbio == NULL || BIO_method_type(rbio) != BIO_TYPE_SOCKET
+        || (int)BIO_get_fd(rbio, NULL) != fd) {
+        BIO *bio = BIO_new(BIO_s_socket());
+
+        if (bio == NULL) {
+            SSLerr(SSL_F_SSL_SET_WFD, ERR_R_BUF_LIB);
+            return 0;
+        }
+        BIO_set_fd(bio, fd, BIO_NOCLOSE);
+        SSL_set0_wbio(s, bio);
+    } else {
+        BIO_up_ref(rbio);
+        SSL_set0_wbio(s, rbio);
+    }
+    return 1;
+}
+
+int SSL_set_rfd(SSL *s, int fd)
+{
+    BIO *wbio = SSL_get_wbio(s);
+
+    if (wbio == NULL || BIO_method_type(wbio) != BIO_TYPE_SOCKET
+        || ((int)BIO_get_fd(wbio, NULL) != fd)) {
+        BIO *bio = BIO_new(BIO_s_socket());
+
+        if (bio == NULL) {
+            SSLerr(SSL_F_SSL_SET_RFD, ERR_R_BUF_LIB);
+            return 0;
+        }
+        BIO_set_fd(bio, fd, BIO_NOCLOSE);
+        SSL_set0_rbio(s, bio);
+    } else {
+        BIO_up_ref(wbio);
+        SSL_set0_rbio(s, wbio);
+    }
+
+    return 1;
+}
+#endif
+
+/* return length of latest Finished message we sent, copy to 'buf' */
+size_t SSL_get_finished(const SSL *s, void *buf, size_t count)
+{
+    size_t ret = 0;
+
+    if (s->s3 != NULL) {
+        ret = s->s3->tmp.finish_md_len;
+        if (count > ret)
+            count = ret;
+        memcpy(buf, s->s3->tmp.finish_md, count);
+    }
+    return ret;
+}
+
+/* return length of latest Finished message we expected, copy to 'buf' */
+size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count)
+{
+    size_t ret = 0;
+
+    if (s->s3 != NULL) {
+        ret = s->s3->tmp.peer_finish_md_len;
+        if (count > ret)
+            count = ret;
+        memcpy(buf, s->s3->tmp.peer_finish_md, count);
+    }
+    return ret;
+}
+
+int SSL_get_verify_mode(const SSL *s)
+{
+    return (s->verify_mode);
+}
+
+int SSL_get_verify_depth(const SSL *s)
+{
+    return X509_VERIFY_PARAM_get_depth(s->param);
+}
+
+int (*SSL_get_verify_callback(const SSL *s)) (int, X509_STORE_CTX *) {
+    return (s->verify_callback);
+}
+
+int SSL_CTX_get_verify_mode(const SSL_CTX *ctx)
+{
+    return (ctx->verify_mode);
+}
+
+int SSL_CTX_get_verify_depth(const SSL_CTX *ctx)
+{
+    return X509_VERIFY_PARAM_get_depth(ctx->param);
+}
+
+int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx)) (int, X509_STORE_CTX *) {
+    return (ctx->default_verify_callback);
+}
+
+void SSL_set_verify(SSL *s, int mode,
+                    int (*callback) (int ok, X509_STORE_CTX *ctx))
+{
+    s->verify_mode = mode;
+    if (callback != NULL)
+        s->verify_callback = callback;
+}
+
+void SSL_set_verify_depth(SSL *s, int depth)
+{
+    X509_VERIFY_PARAM_set_depth(s->param, depth);
+}
+
+void SSL_set_read_ahead(SSL *s, int yes)
+{
+    RECORD_LAYER_set_read_ahead(&s->rlayer, yes);
+}
+
+int SSL_get_read_ahead(const SSL *s)
+{
+    return RECORD_LAYER_get_read_ahead(&s->rlayer);
+}
+
+int SSL_pending(const SSL *s)
+{
+    /*
+     * SSL_pending cannot work properly if read-ahead is enabled
+     * (SSL_[CTX_]ctrl(..., SSL_CTRL_SET_READ_AHEAD, 1, NULL)), and it is
+     * impossible to fix since SSL_pending cannot report errors that may be
+     * observed while scanning the new data. (Note that SSL_pending() is
+     * often used as a boolean value, so we'd better not return -1.)
+     */
+    return (s->method->ssl_pending(s));
+}
+
+int SSL_has_pending(const SSL *s)
+{
+    /*
+     * Similar to SSL_pending() but returns a 1 to indicate that we have
+     * unprocessed data available or 0 otherwise (as opposed to the number of
+     * bytes available). Unlike SSL_pending() this will take into account
+     * read_ahead data. A 1 return simply indicates that we have unprocessed
+     * data. That data may not result in any application data, or we may fail
+     * to parse the records for some reason.
+     */
+    if (SSL_pending(s))
+        return 1;
+
+    return RECORD_LAYER_read_pending(&s->rlayer);
+}
+
+X509 *SSL_get_peer_certificate(const SSL *s)
+{
+    X509 *r;
+
+    if ((s == NULL) || (s->session == NULL))
+        r = NULL;
+    else
+        r = s->session->peer;
+
+    if (r == NULL)
+        return (r);
+
+    X509_up_ref(r);
+
+    return (r);
+}
+
+STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s)
+{
+    STACK_OF(X509) *r;
+
+    if ((s == NULL) || (s->session == NULL))
+        r = NULL;
+    else
+        r = s->session->peer_chain;
+
+    /*
+     * If we are a client, cert_chain includes the peer's own certificate; if
+     * we are a server, it does not.
+     */
+
+    return (r);
+}
+
+/*
+ * Now in theory, since the calling process own 't' it should be safe to
+ * modify.  We need to be able to read f without being hassled
+ */
+int SSL_copy_session_id(SSL *t, const SSL *f)
+{
+    int i;
+    /* Do we need to to SSL locking? */
+    if (!SSL_set_session(t, SSL_get_session(f))) {
+        return 0;
+    }
+
+    /*
+     * what if we are setup for one protocol version but want to talk another
+     */
+    if (t->method != f->method) {
+        t->method->ssl_free(t);
+        t->method = f->method;
+        if (t->method->ssl_new(t) == 0)
+            return 0;
+    }
+
+    CRYPTO_atomic_add(&f->cert->references, 1, &i, f->cert->lock);
+    ssl_cert_free(t->cert);
+    t->cert = f->cert;
+    if (!SSL_set_session_id_context(t, f->sid_ctx, f->sid_ctx_length)) {
+        return 0;
+    }
+
+    return 1;
+}
+
+/* Fix this so it checks all the valid key/cert options */
+int SSL_CTX_check_private_key(const SSL_CTX *ctx)
+{
+    if ((ctx == NULL) || (ctx->cert->key->x509 == NULL)) {
+        SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED);
+        return (0);
+    }
+    if (ctx->cert->key->privatekey == NULL) {
+        SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
+        return (0);
+    }
+    return (X509_check_private_key
+            (ctx->cert->key->x509, ctx->cert->key->privatekey));
+}
+
+/* Fix this function so that it takes an optional type parameter */
+int SSL_check_private_key(const SSL *ssl)
+{
+    if (ssl == NULL) {
+        SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
+        return (0);
+    }
+    if (ssl->cert->key->x509 == NULL) {
+        SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED);
+        return (0);
+    }
+    if (ssl->cert->key->privatekey == NULL) {
+        SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
+        return (0);
+    }
+    return (X509_check_private_key(ssl->cert->key->x509,
+                                   ssl->cert->key->privatekey));
+}
+
+int SSL_waiting_for_async(SSL *s)
+{
+    if (s->job)
+        return 1;
+
+    return 0;
+}
+
+int SSL_get_all_async_fds(SSL *s, OSSL_ASYNC_FD *fds, size_t *numfds)
+{
+    ASYNC_WAIT_CTX *ctx = s->waitctx;
+
+    if (ctx == NULL)
+        return 0;
+    return ASYNC_WAIT_CTX_get_all_fds(ctx, fds, numfds);
+}
+
+int SSL_get_changed_async_fds(SSL *s, OSSL_ASYNC_FD *addfd, size_t *numaddfds,
+                              OSSL_ASYNC_FD *delfd, size_t *numdelfds)
+{
+    ASYNC_WAIT_CTX *ctx = s->waitctx;
+
+    if (ctx == NULL)
+        return 0;
+    return ASYNC_WAIT_CTX_get_changed_fds(ctx, addfd, numaddfds, delfd,
+                                          numdelfds);
+}
+
+int SSL_accept(SSL *s)
+{
+    if (s->handshake_func == NULL) {
+        /* Not properly initialized yet */
+        SSL_set_accept_state(s);
+    }
+
+    return SSL_do_handshake(s);
+}
+
+int SSL_connect(SSL *s)
+{
+    if (s->handshake_func == NULL) {
+        /* Not properly initialized yet */
+        SSL_set_connect_state(s);
+    }
+
+    return SSL_do_handshake(s);
+}
+
+long SSL_get_default_timeout(const SSL *s)
+{
+    return (s->method->get_timeout());
+}
+
+static int ssl_start_async_job(SSL *s, struct ssl_async_args *args,
+                               int (*func) (void *))
+{
+    int ret;
+    if (s->waitctx == NULL) {
+        s->waitctx = ASYNC_WAIT_CTX_new();
+        if (s->waitctx == NULL)
+            return -1;
+    }
+    switch (ASYNC_start_job(&s->job, s->waitctx, &ret, func, args,
+                            sizeof(struct ssl_async_args))) {
+    case ASYNC_ERR:
+        s->rwstate = SSL_NOTHING;
+        SSLerr(SSL_F_SSL_START_ASYNC_JOB, SSL_R_FAILED_TO_INIT_ASYNC);
+        return -1;
+    case ASYNC_PAUSE:
+        s->rwstate = SSL_ASYNC_PAUSED;
+        return -1;
+    case ASYNC_NO_JOBS:
+        s->rwstate = SSL_ASYNC_NO_JOBS;
+        return -1;
+    case ASYNC_FINISH:
+        s->job = NULL;
+        return ret;
+    default:
+        s->rwstate = SSL_NOTHING;
+        SSLerr(SSL_F_SSL_START_ASYNC_JOB, ERR_R_INTERNAL_ERROR);
+        /* Shouldn't happen */
+        return -1;
+    }
+}
+
+static int ssl_io_intern(void *vargs)
+{
+    struct ssl_async_args *args;
+    SSL *s;
+    void *buf;
+    int num;
+
+    args = (struct ssl_async_args *)vargs;
+    s = args->s;
+    buf = args->buf;
+    num = args->num;
+    switch (args->type) {
+    case READFUNC:
+        return args->f.func_read(s, buf, num);
+    case WRITEFUNC:
+        return args->f.func_write(s, buf, num);
+    case OTHERFUNC:
+        return args->f.func_other(s);
+    }
+    return -1;
+}
+
+int SSL_read(SSL *s, void *buf, int num)
+{
+    if (s->handshake_func == NULL) {
+        SSLerr(SSL_F_SSL_READ, SSL_R_UNINITIALIZED);
+        return -1;
+    }
+
+    if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
+        s->rwstate = SSL_NOTHING;
+        return (0);
+    }
+
+    if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
+        struct ssl_async_args args;
+
+        args.s = s;
+        args.buf = buf;
+        args.num = num;
+        args.type = READFUNC;
+        args.f.func_read = s->method->ssl_read;
+
+        return ssl_start_async_job(s, &args, ssl_io_intern);
+    } else {
+        return s->method->ssl_read(s, buf, num);
+    }
+}
+
+int SSL_peek(SSL *s, void *buf, int num)
+{
+    if (s->handshake_func == NULL) {
+        SSLerr(SSL_F_SSL_PEEK, SSL_R_UNINITIALIZED);
+        return -1;
+    }
+
+    if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
+        return (0);
+    }
+    if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
+        struct ssl_async_args args;
+
+        args.s = s;
+        args.buf = buf;
+        args.num = num;
+        args.type = READFUNC;
+        args.f.func_read = s->method->ssl_peek;
+
+        return ssl_start_async_job(s, &args, ssl_io_intern);
+    } else {
+        return s->method->ssl_peek(s, buf, num);
+    }
+}
+
+int SSL_write(SSL *s, const void *buf, int num)
+{
+    if (s->handshake_func == NULL) {
+        SSLerr(SSL_F_SSL_WRITE, SSL_R_UNINITIALIZED);
+        return -1;
+    }
+
+    if (s->shutdown & SSL_SENT_SHUTDOWN) {
+        s->rwstate = SSL_NOTHING;
+        SSLerr(SSL_F_SSL_WRITE, SSL_R_PROTOCOL_IS_SHUTDOWN);
+        return (-1);
+    }
+
+    if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
+        struct ssl_async_args args;
+
+        args.s = s;
+        args.buf = (void *)buf;
+        args.num = num;
+        args.type = WRITEFUNC;
+        args.f.func_write = s->method->ssl_write;
+
+        return ssl_start_async_job(s, &args, ssl_io_intern);
+    } else {
+        return s->method->ssl_write(s, buf, num);
+    }
+}
+
+int SSL_shutdown(SSL *s)
+{
+    /*
+     * Note that this function behaves differently from what one might
+     * expect.  Return values are 0 for no success (yet), 1 for success; but
+     * calling it once is usually not enough, even if blocking I/O is used
+     * (see ssl3_shutdown).
+     */
+
+    if (s->handshake_func == NULL) {
+        SSLerr(SSL_F_SSL_SHUTDOWN, SSL_R_UNINITIALIZED);
+        return -1;
+    }
+
+    if (!SSL_in_init(s)) {
+        if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
+            struct ssl_async_args args;
+
+            args.s = s;
+            args.type = OTHERFUNC;
+            args.f.func_other = s->method->ssl_shutdown;
+
+            return ssl_start_async_job(s, &args, ssl_io_intern);
+        } else {
+            return s->method->ssl_shutdown(s);
+        }
+    } else {
+        SSLerr(SSL_F_SSL_SHUTDOWN, SSL_R_SHUTDOWN_WHILE_IN_INIT);
+        return -1;
+    }
+}
+
+int SSL_renegotiate(SSL *s)
+{
+    if (s->renegotiate == 0)
+        s->renegotiate = 1;
+
+    s->new_session = 1;
+
+    return (s->method->ssl_renegotiate(s));
+}
+
+int SSL_renegotiate_abbreviated(SSL *s)
+{
+    if (s->renegotiate == 0)
+        s->renegotiate = 1;
+
+    s->new_session = 0;
+
+    return (s->method->ssl_renegotiate(s));
+}
+
+int SSL_renegotiate_pending(SSL *s)
+{
+    /*
+     * becomes true when negotiation is requested; false again once a
+     * handshake has finished
+     */
+    return (s->renegotiate != 0);
+}
+
+long SSL_ctrl(SSL *s, int cmd, long larg, void *parg)
+{
+    long l;
+
+    switch (cmd) {
+    case SSL_CTRL_GET_READ_AHEAD:
+        return (RECORD_LAYER_get_read_ahead(&s->rlayer));
+    case SSL_CTRL_SET_READ_AHEAD:
+        l = RECORD_LAYER_get_read_ahead(&s->rlayer);
+        RECORD_LAYER_set_read_ahead(&s->rlayer, larg);
+        return (l);
+
+    case SSL_CTRL_SET_MSG_CALLBACK_ARG:
+        s->msg_callback_arg = parg;
+        return 1;
+
+    case SSL_CTRL_MODE:
+        return (s->mode |= larg);
+    case SSL_CTRL_CLEAR_MODE:
+        return (s->mode &= ~larg);
+    case SSL_CTRL_GET_MAX_CERT_LIST:
+        return (s->max_cert_list);
+    case SSL_CTRL_SET_MAX_CERT_LIST:
+        l = s->max_cert_list;
+        s->max_cert_list = larg;
+        return (l);
+    case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
+        if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
+            return 0;
+        s->max_send_fragment = larg;
+        if (s->max_send_fragment < s->split_send_fragment)
+            s->split_send_fragment = s->max_send_fragment;
+        return 1;
+    case SSL_CTRL_SET_SPLIT_SEND_FRAGMENT:
+        if ((unsigned int)larg > s->max_send_fragment || larg == 0)
+            return 0;
+        s->split_send_fragment = larg;
+        return 1;
+    case SSL_CTRL_SET_MAX_PIPELINES:
+        if (larg < 1 || larg > SSL_MAX_PIPELINES)
+            return 0;
+        s->max_pipelines = larg;
+        if (larg > 1)
+            RECORD_LAYER_set_read_ahead(&s->rlayer, 1);
+        return 1;
+    case SSL_CTRL_GET_RI_SUPPORT:
+        if (s->s3)
+            return s->s3->send_connection_binding;
+        else
+            return 0;
+    case SSL_CTRL_CERT_FLAGS:
+        return (s->cert->cert_flags |= larg);
+    case SSL_CTRL_CLEAR_CERT_FLAGS:
+        return (s->cert->cert_flags &= ~larg);
+
+    case SSL_CTRL_GET_RAW_CIPHERLIST:
+        if (parg) {
+            if (s->s3->tmp.ciphers_raw == NULL)
+                return 0;
+            *(unsigned char **)parg = s->s3->tmp.ciphers_raw;
+            return (int)s->s3->tmp.ciphers_rawlen;
+        } else {
+            return TLS_CIPHER_LEN;
+        }
+    case SSL_CTRL_GET_EXTMS_SUPPORT:
+        if (!s->session || SSL_in_init(s) || ossl_statem_get_in_handshake(s))
+            return -1;
+        if (s->session->flags & SSL_SESS_FLAG_EXTMS)
+            return 1;
+        else
+            return 0;
+    case SSL_CTRL_SET_MIN_PROTO_VERSION:
+        return ssl_set_version_bound(s->ctx->method->version, (int)larg,
+                                     &s->min_proto_version);
+    case SSL_CTRL_SET_MAX_PROTO_VERSION:
+        return ssl_set_version_bound(s->ctx->method->version, (int)larg,
+                                     &s->max_proto_version);
+    default:
+        return (s->method->ssl_ctrl(s, cmd, larg, parg));
+    }
+}
+
+long SSL_callback_ctrl(SSL *s, int cmd, void (*fp) (void))
+{
+    switch (cmd) {
+    case SSL_CTRL_SET_MSG_CALLBACK:
+        s->msg_callback = (void (*)
+                           (int write_p, int version, int content_type,
+                            const void *buf, size_t len, SSL *ssl,
+                            void *arg))(fp);
+        return 1;
+
+    default:
+        return (s->method->ssl_callback_ctrl(s, cmd, fp));
+    }
+}
+
+LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx)
+{
+    return ctx->sessions;
+}
+
+long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
+{
+    long l;
+    /* For some cases with ctx == NULL perform syntax checks */
+    if (ctx == NULL) {
+        switch (cmd) {
+#ifndef OPENSSL_NO_EC
+        case SSL_CTRL_SET_CURVES_LIST:
+            return tls1_set_curves_list(NULL, NULL, parg);
+#endif
+        case SSL_CTRL_SET_SIGALGS_LIST:
+        case SSL_CTRL_SET_CLIENT_SIGALGS_LIST:
+            return tls1_set_sigalgs_list(NULL, parg, 0);
+        default:
+            return 0;
+        }
+    }
+
+    switch (cmd) {
+    case SSL_CTRL_GET_READ_AHEAD:
+        return (ctx->read_ahead);
+    case SSL_CTRL_SET_READ_AHEAD:
+        l = ctx->read_ahead;
+        ctx->read_ahead = larg;
+        return (l);
+
+    case SSL_CTRL_SET_MSG_CALLBACK_ARG:
+        ctx->msg_callback_arg = parg;
+        return 1;
+
+    case SSL_CTRL_GET_MAX_CERT_LIST:
+        return (ctx->max_cert_list);
+    case SSL_CTRL_SET_MAX_CERT_LIST:
+        l = ctx->max_cert_list;
+        ctx->max_cert_list = larg;
+        return (l);
+
+    case SSL_CTRL_SET_SESS_CACHE_SIZE:
+        l = ctx->session_cache_size;
+        ctx->session_cache_size = larg;
+        return (l);
+    case SSL_CTRL_GET_SESS_CACHE_SIZE:
+        return (ctx->session_cache_size);
+    case SSL_CTRL_SET_SESS_CACHE_MODE:
+        l = ctx->session_cache_mode;
+        ctx->session_cache_mode = larg;
+        return (l);
+    case SSL_CTRL_GET_SESS_CACHE_MODE:
+        return (ctx->session_cache_mode);
+
+    case SSL_CTRL_SESS_NUMBER:
+        return (lh_SSL_SESSION_num_items(ctx->sessions));
+    case SSL_CTRL_SESS_CONNECT:
+        return (ctx->stats.sess_connect);
+    case SSL_CTRL_SESS_CONNECT_GOOD:
+        return (ctx->stats.sess_connect_good);
+    case SSL_CTRL_SESS_CONNECT_RENEGOTIATE:
+        return (ctx->stats.sess_connect_renegotiate);
+    case SSL_CTRL_SESS_ACCEPT:
+        return (ctx->stats.sess_accept);
+    case SSL_CTRL_SESS_ACCEPT_GOOD:
+        return (ctx->stats.sess_accept_good);
+    case SSL_CTRL_SESS_ACCEPT_RENEGOTIATE:
+        return (ctx->stats.sess_accept_renegotiate);
+    case SSL_CTRL_SESS_HIT:
+        return (ctx->stats.sess_hit);
+    case SSL_CTRL_SESS_CB_HIT:
+        return (ctx->stats.sess_cb_hit);
+    case SSL_CTRL_SESS_MISSES:
+        return (ctx->stats.sess_miss);
+    case SSL_CTRL_SESS_TIMEOUTS:
+        return (ctx->stats.sess_timeout);
+    case SSL_CTRL_SESS_CACHE_FULL:
+        return (ctx->stats.sess_cache_full);
+    case SSL_CTRL_MODE:
+        return (ctx->mode |= larg);
+    case SSL_CTRL_CLEAR_MODE:
+        return (ctx->mode &= ~larg);
+    case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
+        if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
+            return 0;
+        ctx->max_send_fragment = larg;
+        if (ctx->max_send_fragment < ctx->split_send_fragment)
+            ctx->split_send_fragment = ctx->max_send_fragment;
+        return 1;
+    case SSL_CTRL_SET_SPLIT_SEND_FRAGMENT:
+        if ((unsigned int)larg > ctx->max_send_fragment || larg == 0)
+            return 0;
+        ctx->split_send_fragment = larg;
+        return 1;
+    case SSL_CTRL_SET_MAX_PIPELINES:
+        if (larg < 1 || larg > SSL_MAX_PIPELINES)
+            return 0;
+        ctx->max_pipelines = larg;
+        return 1;
+    case SSL_CTRL_CERT_FLAGS:
+        return (ctx->cert->cert_flags |= larg);
+    case SSL_CTRL_CLEAR_CERT_FLAGS:
+        return (ctx->cert->cert_flags &= ~larg);
+    case SSL_CTRL_SET_MIN_PROTO_VERSION:
+        return ssl_set_version_bound(ctx->method->version, (int)larg,
+                                     &ctx->min_proto_version);
+    case SSL_CTRL_SET_MAX_PROTO_VERSION:
+        return ssl_set_version_bound(ctx->method->version, (int)larg,
+                                     &ctx->max_proto_version);
+    default:
+        return (ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg));
+    }
+}
+
+long SSL_CTX_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void))
+{
+    switch (cmd) {
+    case SSL_CTRL_SET_MSG_CALLBACK:
+        ctx->msg_callback = (void (*)
+                             (int write_p, int version, int content_type,
+                              const void *buf, size_t len, SSL *ssl,
+                              void *arg))(fp);
+        return 1;
+
+    default:
+        return (ctx->method->ssl_ctx_callback_ctrl(ctx, cmd, fp));
+    }
+}
+
+int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b)
+{
+    if (a->id > b->id)
+        return 1;
+    if (a->id < b->id)
+        return -1;
+    return 0;
+}
+
+int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap,
+                          const SSL_CIPHER *const *bp)
+{
+    if ((*ap)->id > (*bp)->id)
+        return 1;
+    if ((*ap)->id < (*bp)->id)
+        return -1;
+    return 0;
+}
+
+/** return a STACK of the ciphers available for the SSL and in order of
+ * preference */
+STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s)
+{
+    if (s != NULL) {
+        if (s->cipher_list != NULL) {
+            return (s->cipher_list);
+        } else if ((s->ctx != NULL) && (s->ctx->cipher_list != NULL)) {
+            return (s->ctx->cipher_list);
+        }
+    }
+    return (NULL);
+}
+
+STACK_OF(SSL_CIPHER) *SSL_get_client_ciphers(const SSL *s)
+{
+    if ((s == NULL) || (s->session == NULL) || !s->server)
+        return NULL;
+    return s->session->ciphers;
+}
+
+STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s)
+{
+    STACK_OF(SSL_CIPHER) *sk = NULL, *ciphers;
+    int i;
+    ciphers = SSL_get_ciphers(s);
+    if (!ciphers)
+        return NULL;
+    ssl_set_client_disabled(s);
+    for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
+        const SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i);
+        if (!ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED)) {
+            if (!sk)
+                sk = sk_SSL_CIPHER_new_null();
+            if (!sk)
+                return NULL;
+            if (!sk_SSL_CIPHER_push(sk, c)) {
+                sk_SSL_CIPHER_free(sk);
+                return NULL;
+            }
+        }
+    }
+    return sk;
+}
+
+/** return a STACK of the ciphers available for the SSL and in order of
+ * algorithm id */
+STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s)
+{
+    if (s != NULL) {
+        if (s->cipher_list_by_id != NULL) {
+            return (s->cipher_list_by_id);
+        } else if ((s->ctx != NULL) && (s->ctx->cipher_list_by_id != NULL)) {
+            return (s->ctx->cipher_list_by_id);
+        }
+    }
+    return (NULL);
+}
+
+/** The old interface to get the same thing as SSL_get_ciphers() */
+const char *SSL_get_cipher_list(const SSL *s, int n)
+{
+    const SSL_CIPHER *c;
+    STACK_OF(SSL_CIPHER) *sk;
+
+    if (s == NULL)
+        return (NULL);
+    sk = SSL_get_ciphers(s);
+    if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= n))
+        return (NULL);
+    c = sk_SSL_CIPHER_value(sk, n);
+    if (c == NULL)
+        return (NULL);
+    return (c->name);
+}
+
+/** return a STACK of the ciphers available for the SSL_CTX and in order of
+ * preference */
+STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx)
+{
+    if (ctx != NULL)
+        return ctx->cipher_list;
+    return NULL;
+}
+
+/** specify the ciphers to be used by default by the SSL_CTX */
+int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str)
+{
+    STACK_OF(SSL_CIPHER) *sk;
+
+    sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list,
+                                &ctx->cipher_list_by_id, str, ctx->cert);
+    /*
+     * ssl_create_cipher_list may return an empty stack if it was unable to
+     * find a cipher matching the given rule string (for example if the rule
+     * string specifies a cipher which has been disabled). This is not an
+     * error as far as ssl_create_cipher_list is concerned, and hence
+     * ctx->cipher_list and ctx->cipher_list_by_id has been updated.
+     */
+    if (sk == NULL)
+        return 0;
+    else if (sk_SSL_CIPHER_num(sk) == 0) {
+        SSLerr(SSL_F_SSL_CTX_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH);
+        return 0;
+    }
+    return 1;
+}
+
+/** specify the ciphers to be used by the SSL */
+int SSL_set_cipher_list(SSL *s, const char *str)
+{
+    STACK_OF(SSL_CIPHER) *sk;
+
+    sk = ssl_create_cipher_list(s->ctx->method, &s->cipher_list,
+                                &s->cipher_list_by_id, str, s->cert);
+    /* see comment in SSL_CTX_set_cipher_list */
+    if (sk == NULL)
+        return 0;
+    else if (sk_SSL_CIPHER_num(sk) == 0) {
+        SSLerr(SSL_F_SSL_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH);
+        return 0;
+    }
+    return 1;
+}
+
+char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len)
+{
+    char *p;
+    STACK_OF(SSL_CIPHER) *sk;
+    const SSL_CIPHER *c;
+    int i;
+
+    if ((s->session == NULL) || (s->session->ciphers == NULL) || (len < 2))
+        return (NULL);
+
+    p = buf;
+    sk = s->session->ciphers;
+
+    if (sk_SSL_CIPHER_num(sk) == 0)
+        return NULL;
+
+    for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
+        int n;
+
+        c = sk_SSL_CIPHER_value(sk, i);
+        n = strlen(c->name);
+        if (n + 1 > len) {
+            if (p != buf)
+                --p;
+            *p = '\0';
+            return buf;
+        }
+        memcpy(p, c->name, n + 1);
+        p += n;
+        *(p++) = ':';
+        len -= n + 1;
+    }
+    p[-1] = '\0';
+    return (buf);
+}
+
+/** return a servername extension value if provided in Client Hello, or NULL.
+ * So far, only host_name types are defined (RFC 3546).
+ */
+
+const char *SSL_get_servername(const SSL *s, const int type)
+{
+    if (type != TLSEXT_NAMETYPE_host_name)
+        return NULL;
+
+    return s->session && !s->tlsext_hostname ?
+        s->session->tlsext_hostname : s->tlsext_hostname;
+}
+
+int SSL_get_servername_type(const SSL *s)
+{
+    if (s->session
+        && (!s->tlsext_hostname ? s->session->
+            tlsext_hostname : s->tlsext_hostname))
+        return TLSEXT_NAMETYPE_host_name;
+    return -1;
+}
+
+/*
+ * SSL_select_next_proto implements the standard protocol selection. It is
+ * expected that this function is called from the callback set by
+ * SSL_CTX_set_next_proto_select_cb. The protocol data is assumed to be a
+ * vector of 8-bit, length prefixed byte strings. The length byte itself is
+ * not included in the length. A byte string of length 0 is invalid. No byte
+ * string may be truncated. The current, but experimental algorithm for
+ * selecting the protocol is: 1) If the server doesn't support NPN then this
+ * is indicated to the callback. In this case, the client application has to
+ * abort the connection or have a default application level protocol. 2) If
+ * the server supports NPN, but advertises an empty list then the client
+ * selects the first protocol in its list, but indicates via the API that this
+ * fallback case was enacted. 3) Otherwise, the client finds the first
+ * protocol in the server's list that it supports and selects this protocol.
+ * This is because it's assumed that the server has better information about
+ * which protocol a client should use. 4) If the client doesn't support any
+ * of the server's advertised protocols, then this is treated the same as
+ * case 2. It returns either OPENSSL_NPN_NEGOTIATED if a common protocol was
+ * found, or OPENSSL_NPN_NO_OVERLAP if the fallback case was reached.
+ */
+int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
+                          const unsigned char *server,
+                          unsigned int server_len,
+                          const unsigned char *client, unsigned int client_len)
+{
+    unsigned int i, j;
+    const unsigned char *result;
+    int status = OPENSSL_NPN_UNSUPPORTED;
+
+    /*
+     * For each protocol in server preference order, see if we support it.
+     */
+    for (i = 0; i < server_len;) {
+        for (j = 0; j < client_len;) {
+            if (server[i] == client[j] &&
+                memcmp(&server[i + 1], &client[j + 1], server[i]) == 0) {
+                /* We found a match */
+                result = &server[i];
+                status = OPENSSL_NPN_NEGOTIATED;
+                goto found;
+            }
+            j += client[j];
+            j++;
+        }
+        i += server[i];
+        i++;
+    }
+
+    /* There's no overlap between our protocols and the server's list. */
+    result = client;
+    status = OPENSSL_NPN_NO_OVERLAP;
+
+ found:
+    *out = (unsigned char *)result + 1;
+    *outlen = result[0];
+    return status;
+}
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+/*
+ * SSL_get0_next_proto_negotiated sets *data and *len to point to the
+ * client's requested protocol for this connection and returns 0. If the
+ * client didn't request any protocol, then *data is set to NULL. Note that
+ * the client can request any protocol it chooses. The value returned from
+ * this function need not be a member of the list of supported protocols
+ * provided by the callback.
+ */
+void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data,
+                                    unsigned *len)
+{
+    *data = s->next_proto_negotiated;
+    if (!*data) {
+        *len = 0;
+    } else {
+        *len = s->next_proto_negotiated_len;
+    }
+}
+
+/*
+ * SSL_CTX_set_next_protos_advertised_cb sets a callback that is called when
+ * a TLS server needs a list of supported protocols for Next Protocol
+ * Negotiation. The returned list must be in wire format.  The list is
+ * returned by setting |out| to point to it and |outlen| to its length. This
+ * memory will not be modified, but one should assume that the SSL* keeps a
+ * reference to it. The callback should return SSL_TLSEXT_ERR_OK if it
+ * wishes to advertise. Otherwise, no such extension will be included in the
+ * ServerHello.
+ */
+void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *ctx,
+                                           int (*cb) (SSL *ssl,
+                                                      const unsigned char
+                                                      **out,
+                                                      unsigned int *outlen,
+                                                      void *arg), void *arg)
+{
+    ctx->next_protos_advertised_cb = cb;
+    ctx->next_protos_advertised_cb_arg = arg;
+}
+
+/*
+ * SSL_CTX_set_next_proto_select_cb sets a callback that is called when a
+ * client needs to select a protocol from the server's provided list. |out|
+ * must be set to point to the selected protocol (which may be within |in|).
+ * The length of the protocol name must be written into |outlen|. The
+ * server's advertised protocols are provided in |in| and |inlen|. The
+ * callback can assume that |in| is syntactically valid. The client must
+ * select a protocol. It is fatal to the connection if this callback returns
+ * a value other than SSL_TLSEXT_ERR_OK.
+ */
+void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx,
+                                      int (*cb) (SSL *s, unsigned char **out,
+                                                 unsigned char *outlen,
+                                                 const unsigned char *in,
+                                                 unsigned int inlen,
+                                                 void *arg), void *arg)
+{
+    ctx->next_proto_select_cb = cb;
+    ctx->next_proto_select_cb_arg = arg;
+}
+#endif
+
+/*
+ * SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|.
+ * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
+ * length-prefixed strings). Returns 0 on success.
+ */
+int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos,
+                            unsigned int protos_len)
+{
+    OPENSSL_free(ctx->alpn_client_proto_list);
+    ctx->alpn_client_proto_list = OPENSSL_memdup(protos, protos_len);
+    if (ctx->alpn_client_proto_list == NULL) {
+        SSLerr(SSL_F_SSL_CTX_SET_ALPN_PROTOS, ERR_R_MALLOC_FAILURE);
+        return 1;
+    }
+    ctx->alpn_client_proto_list_len = protos_len;
+
+    return 0;
+}
+
+/*
+ * SSL_set_alpn_protos sets the ALPN protocol list on |ssl| to |protos|.
+ * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
+ * length-prefixed strings). Returns 0 on success.
+ */
+int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos,
+                        unsigned int protos_len)
+{
+    OPENSSL_free(ssl->alpn_client_proto_list);
+    ssl->alpn_client_proto_list = OPENSSL_memdup(protos, protos_len);
+    if (ssl->alpn_client_proto_list == NULL) {
+        SSLerr(SSL_F_SSL_SET_ALPN_PROTOS, ERR_R_MALLOC_FAILURE);
+        return 1;
+    }
+    ssl->alpn_client_proto_list_len = protos_len;
+
+    return 0;
+}
+
+/*
+ * SSL_CTX_set_alpn_select_cb sets a callback function on |ctx| that is
+ * called during ClientHello processing in order to select an ALPN protocol
+ * from the client's list of offered protocols.
+ */
+void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx,
+                                int (*cb) (SSL *ssl,
+                                           const unsigned char **out,
+                                           unsigned char *outlen,
+                                           const unsigned char *in,
+                                           unsigned int inlen,
+                                           void *arg), void *arg)
+{
+    ctx->alpn_select_cb = cb;
+    ctx->alpn_select_cb_arg = arg;
+}
+
+/*
+ * SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from
+ * |ssl|. On return it sets |*data| to point to |*len| bytes of protocol name
+ * (not including the leading length-prefix byte). If the server didn't
+ * respond with a negotiated protocol then |*len| will be zero.
+ */
+void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
+                            unsigned int *len)
+{
+    *data = NULL;
+    if (ssl->s3)
+        *data = ssl->s3->alpn_selected;
+    if (*data == NULL)
+        *len = 0;
+    else
+        *len = ssl->s3->alpn_selected_len;
+}
+
+int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
+                               const char *label, size_t llen,
+                               const unsigned char *p, size_t plen,
+                               int use_context)
+{
+    if (s->version < TLS1_VERSION && s->version != DTLS1_BAD_VER)
+        return -1;
+
+    return s->method->ssl3_enc->export_keying_material(s, out, olen, label,
+                                                       llen, p, plen,
+                                                       use_context);
+}
+
+static unsigned long ssl_session_hash(const SSL_SESSION *a)
+{
+    const unsigned char *session_id = a->session_id;
+    unsigned long l;
+    unsigned char tmp_storage[4];
+
+    if (a->session_id_length < sizeof(tmp_storage)) {
+        memset(tmp_storage, 0, sizeof(tmp_storage));
+        memcpy(tmp_storage, a->session_id, a->session_id_length);
+        session_id = tmp_storage;
+    }
+
+    l = (unsigned long)
+        ((unsigned long)session_id[0]) |
+        ((unsigned long)session_id[1] << 8L) |
+        ((unsigned long)session_id[2] << 16L) |
+        ((unsigned long)session_id[3] << 24L);
+    return (l);
+}
+
+/*
+ * NB: If this function (or indeed the hash function which uses a sort of
+ * coarser function than this one) is changed, ensure
+ * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on
+ * being able to construct an SSL_SESSION that will collide with any existing
+ * session with a matching session ID.
+ */
+static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b)
+{
+    if (a->ssl_version != b->ssl_version)
+        return (1);
+    if (a->session_id_length != b->session_id_length)
+        return (1);
+    return (memcmp(a->session_id, b->session_id, a->session_id_length));
+}
+
+/*
+ * These wrapper functions should remain rather than redeclaring
+ * SSL_SESSION_hash and SSL_SESSION_cmp for void* types and casting each
+ * variable. The reason is that the functions aren't static, they're exposed
+ * via ssl.h.
+ */
+
+SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
+{
+    SSL_CTX *ret = NULL;
+
+    if (meth == NULL) {
+        SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_NULL_SSL_METHOD_PASSED);
+        return (NULL);
+    }
+
+    if (!OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL))
+        return NULL;
+
+    if (FIPS_mode() && (meth->version < TLS1_VERSION)) {
+        SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE);
+        return NULL;
+    }
+
+    if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) {
+        SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
+        goto err;
+    }
+    ret = OPENSSL_zalloc(sizeof(*ret));
+    if (ret == NULL)
+        goto err;
+
+    ret->method = meth;
+    ret->min_proto_version = 0;
+    ret->max_proto_version = 0;
+    ret->session_cache_mode = SSL_SESS_CACHE_SERVER;
+    ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
+    /* We take the system default. */
+    ret->session_timeout = meth->get_timeout();
+    ret->references = 1;
+    ret->lock = CRYPTO_THREAD_lock_new();
+    if (ret->lock == NULL) {
+        SSLerr(SSL_F_SSL_CTX_NEW, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ret);
+        return NULL;
+    }
+    ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT;
+    ret->verify_mode = SSL_VERIFY_NONE;
+    if ((ret->cert = ssl_cert_new()) == NULL)
+        goto err;
+
+    ret->sessions = lh_SSL_SESSION_new(ssl_session_hash, ssl_session_cmp);
+    if (ret->sessions == NULL)
+        goto err;
+    ret->cert_store = X509_STORE_new();
+    if (ret->cert_store == NULL)
+        goto err;
+#ifndef OPENSSL_NO_CT
+    ret->ctlog_store = CTLOG_STORE_new();
+    if (ret->ctlog_store == NULL)
+        goto err;
+#endif
+    if (!ssl_create_cipher_list(ret->method,
+                                &ret->cipher_list, &ret->cipher_list_by_id,
+                                SSL_DEFAULT_CIPHER_LIST, ret->cert)
+        || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) {
+        SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_LIBRARY_HAS_NO_CIPHERS);
+        goto err2;
+    }
+
+    ret->param = X509_VERIFY_PARAM_new();
+    if (ret->param == NULL)
+        goto err;
+
+    if ((ret->md5 = EVP_get_digestbyname("ssl3-md5")) == NULL) {
+        SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES);
+        goto err2;
+    }
+    if ((ret->sha1 = EVP_get_digestbyname("ssl3-sha1")) == NULL) {
+        SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES);
+        goto err2;
+    }
+
+    if ((ret->client_CA = sk_X509_NAME_new_null()) == NULL)
+        goto err;
+
+    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data))
+        goto err;
+
+    /* No compression for DTLS */
+    if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS))
+        ret->comp_methods = SSL_COMP_get_compression_methods();
+
+    ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
+    ret->split_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
+
+    /* Setup RFC5077 ticket keys */
+    if ((RAND_bytes(ret->tlsext_tick_key_name,
+                    sizeof(ret->tlsext_tick_key_name)) <= 0)
+        || (RAND_bytes(ret->tlsext_tick_hmac_key,
+                       sizeof(ret->tlsext_tick_hmac_key)) <= 0)
+        || (RAND_bytes(ret->tlsext_tick_aes_key,
+                       sizeof(ret->tlsext_tick_aes_key)) <= 0))
+        ret->options |= SSL_OP_NO_TICKET;
+
+#ifndef OPENSSL_NO_SRP
+    if (!SSL_CTX_SRP_CTX_init(ret))
+        goto err;
+#endif
+#ifndef OPENSSL_NO_ENGINE
+# ifdef OPENSSL_SSL_CLIENT_ENGINE_AUTO
+#  define eng_strx(x)     #x
+#  define eng_str(x)      eng_strx(x)
+    /* Use specific client engine automatically... ignore errors */
+    {
+        ENGINE *eng;
+        eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO));
+        if (!eng) {
+            ERR_clear_error();
+            ENGINE_load_builtin_engines();
+            eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO));
+        }
+        if (!eng || !SSL_CTX_set_client_cert_engine(ret, eng))
+            ERR_clear_error();
+    }
+# endif
+#endif
+    /*
+     * Default is to connect to non-RI servers. When RI is more widely
+     * deployed might change this.
+     */
+    ret->options |= SSL_OP_LEGACY_SERVER_CONNECT;
+    /*
+     * Disable compression by default to prevent CRIME. Applications can
+     * re-enable compression by configuring
+     * SSL_CTX_clear_options(ctx, SSL_OP_NO_COMPRESSION);
+     * or by using the SSL_CONF library.
+     */
+    ret->options |= SSL_OP_NO_COMPRESSION;
+
+    ret->tlsext_status_type = -1;
+
+    return ret;
+ err:
+    SSLerr(SSL_F_SSL_CTX_NEW, ERR_R_MALLOC_FAILURE);
+ err2:
+    SSL_CTX_free(ret);
+    return NULL;
+}
+
+int SSL_CTX_up_ref(SSL_CTX *ctx)
+{
+    int i;
+
+    if (CRYPTO_atomic_add(&ctx->references, 1, &i, ctx->lock) <= 0)
+        return 0;
+
+    REF_PRINT_COUNT("SSL_CTX", ctx);
+    REF_ASSERT_ISNT(i < 2);
+    return ((i > 1) ? 1 : 0);
+}
+
+void SSL_CTX_free(SSL_CTX *a)
+{
+    int i;
+
+    if (a == NULL)
+        return;
+
+    CRYPTO_atomic_add(&a->references, -1, &i, a->lock);
+    REF_PRINT_COUNT("SSL_CTX", a);
+    if (i > 0)
+        return;
+    REF_ASSERT_ISNT(i < 0);
+
+    X509_VERIFY_PARAM_free(a->param);
+    dane_ctx_final(&a->dane);
+
+    /*
+     * Free internal session cache. However: the remove_cb() may reference
+     * the ex_data of SSL_CTX, thus the ex_data store can only be removed
+     * after the sessions were flushed.
+     * As the ex_data handling routines might also touch the session cache,
+     * the most secure solution seems to be: empty (flush) the cache, then
+     * free ex_data, then finally free the cache.
+     * (See ticket [openssl.org #212].)
+     */
+    if (a->sessions != NULL)
+        SSL_CTX_flush_sessions(a, 0);
+
+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data);
+    lh_SSL_SESSION_free(a->sessions);
+    X509_STORE_free(a->cert_store);
+#ifndef OPENSSL_NO_CT
+    CTLOG_STORE_free(a->ctlog_store);
+#endif
+    sk_SSL_CIPHER_free(a->cipher_list);
+    sk_SSL_CIPHER_free(a->cipher_list_by_id);
+    ssl_cert_free(a->cert);
+    sk_X509_NAME_pop_free(a->client_CA, X509_NAME_free);
+    sk_X509_pop_free(a->extra_certs, X509_free);
+    a->comp_methods = NULL;
+#ifndef OPENSSL_NO_SRTP
+    sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles);
+#endif
+#ifndef OPENSSL_NO_SRP
+    SSL_CTX_SRP_CTX_free(a);
+#endif
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE_finish(a->client_cert_engine);
+#endif
+
+#ifndef OPENSSL_NO_EC
+    OPENSSL_free(a->tlsext_ecpointformatlist);
+    OPENSSL_free(a->tlsext_ellipticcurvelist);
+#endif
+    OPENSSL_free(a->alpn_client_proto_list);
+
+    CRYPTO_THREAD_lock_free(a->lock);
+
+    OPENSSL_free(a);
+}
+
+void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb)
+{
+    ctx->default_passwd_callback = cb;
+}
+
+void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u)
+{
+    ctx->default_passwd_callback_userdata = u;
+}
+
+pem_password_cb *SSL_CTX_get_default_passwd_cb(SSL_CTX *ctx)
+{
+    return ctx->default_passwd_callback;
+}
+
+void *SSL_CTX_get_default_passwd_cb_userdata(SSL_CTX *ctx)
+{
+    return ctx->default_passwd_callback_userdata;
+}
+
+void SSL_set_default_passwd_cb(SSL *s, pem_password_cb *cb)
+{
+    s->default_passwd_callback = cb;
+}
+
+void SSL_set_default_passwd_cb_userdata(SSL *s, void *u)
+{
+    s->default_passwd_callback_userdata = u;
+}
+
+pem_password_cb *SSL_get_default_passwd_cb(SSL *s)
+{
+    return s->default_passwd_callback;
+}
+
+void *SSL_get_default_passwd_cb_userdata(SSL *s)
+{
+    return s->default_passwd_callback_userdata;
+}
+
+void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,
+                                      int (*cb) (X509_STORE_CTX *, void *),
+                                      void *arg)
+{
+    ctx->app_verify_callback = cb;
+    ctx->app_verify_arg = arg;
+}
+
+void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
+                        int (*cb) (int, X509_STORE_CTX *))
+{
+    ctx->verify_mode = mode;
+    ctx->default_verify_callback = cb;
+}
+
+void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth)
+{
+    X509_VERIFY_PARAM_set_depth(ctx->param, depth);
+}
+
+void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb) (SSL *ssl, void *arg), void *arg)
+{
+    ssl_cert_set_cert_cb(c->cert, cb, arg);
+}
+
+void SSL_set_cert_cb(SSL *s, int (*cb) (SSL *ssl, void *arg), void *arg)
+{
+    ssl_cert_set_cert_cb(s->cert, cb, arg);
+}
+
+void ssl_set_masks(SSL *s)
+{
+#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_GOST)
+    CERT_PKEY *cpk;
+#endif
+    CERT *c = s->cert;
+    uint32_t *pvalid = s->s3->tmp.valid_flags;
+    int rsa_enc, rsa_sign, dh_tmp, dsa_sign;
+    unsigned long mask_k, mask_a;
+#ifndef OPENSSL_NO_EC
+    int have_ecc_cert, ecdsa_ok;
+    X509 *x = NULL;
+#endif
+    if (c == NULL)
+        return;
+
+#ifndef OPENSSL_NO_DH
+    dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL || c->dh_tmp_auto);
+#else
+    dh_tmp = 0;
+#endif
+
+    rsa_enc = pvalid[SSL_PKEY_RSA_ENC] & CERT_PKEY_VALID;
+    rsa_sign = pvalid[SSL_PKEY_RSA_SIGN] & CERT_PKEY_SIGN;
+    dsa_sign = pvalid[SSL_PKEY_DSA_SIGN] & CERT_PKEY_SIGN;
+#ifndef OPENSSL_NO_EC
+    have_ecc_cert = pvalid[SSL_PKEY_ECC] & CERT_PKEY_VALID;
+#endif
+    mask_k = 0;
+    mask_a = 0;
+
+#ifdef CIPHER_DEBUG
+    fprintf(stderr, "dht=%d re=%d rs=%d ds=%d\n",
+            dh_tmp, rsa_enc, rsa_sign, dsa_sign);
+#endif
+
+#ifndef OPENSSL_NO_GOST
+    cpk = &(c->pkeys[SSL_PKEY_GOST12_512]);
+    if (cpk->x509 != NULL && cpk->privatekey != NULL) {
+        mask_k |= SSL_kGOST;
+        mask_a |= SSL_aGOST12;
+    }
+    cpk = &(c->pkeys[SSL_PKEY_GOST12_256]);
+    if (cpk->x509 != NULL && cpk->privatekey != NULL) {
+        mask_k |= SSL_kGOST;
+        mask_a |= SSL_aGOST12;
+    }
+    cpk = &(c->pkeys[SSL_PKEY_GOST01]);
+    if (cpk->x509 != NULL && cpk->privatekey != NULL) {
+        mask_k |= SSL_kGOST;
+        mask_a |= SSL_aGOST01;
+    }
+#endif
+
+    if (rsa_enc)
+        mask_k |= SSL_kRSA;
+
+    if (dh_tmp)
+        mask_k |= SSL_kDHE;
+
+    if (rsa_enc || rsa_sign) {
+        mask_a |= SSL_aRSA;
+    }
+
+    if (dsa_sign) {
+        mask_a |= SSL_aDSS;
+    }
+
+    mask_a |= SSL_aNULL;
+
+    /*
+     * An ECC certificate may be usable for ECDH and/or ECDSA cipher suites
+     * depending on the key usage extension.
+     */
+#ifndef OPENSSL_NO_EC
+    if (have_ecc_cert) {
+        uint32_t ex_kusage;
+        cpk = &c->pkeys[SSL_PKEY_ECC];
+        x = cpk->x509;
+        ex_kusage = X509_get_key_usage(x);
+        ecdsa_ok = ex_kusage & X509v3_KU_DIGITAL_SIGNATURE;
+        if (!(pvalid[SSL_PKEY_ECC] & CERT_PKEY_SIGN))
+            ecdsa_ok = 0;
+        if (ecdsa_ok)
+            mask_a |= SSL_aECDSA;
+    }
+#endif
+
+#ifndef OPENSSL_NO_EC
+    mask_k |= SSL_kECDHE;
+#endif
+
+#ifndef OPENSSL_NO_PSK
+    mask_k |= SSL_kPSK;
+    mask_a |= SSL_aPSK;
+    if (mask_k & SSL_kRSA)
+        mask_k |= SSL_kRSAPSK;
+    if (mask_k & SSL_kDHE)
+        mask_k |= SSL_kDHEPSK;
+    if (mask_k & SSL_kECDHE)
+        mask_k |= SSL_kECDHEPSK;
+#endif
+
+    s->s3->tmp.mask_k = mask_k;
+    s->s3->tmp.mask_a = mask_a;
+}
+
+#ifndef OPENSSL_NO_EC
+
+int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)
+{
+    if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aECDSA) {
+        /* key usage, if present, must allow signing */
+        if (!(X509_get_key_usage(x) & X509v3_KU_DIGITAL_SIGNATURE)) {
+            SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG,
+                   SSL_R_ECC_CERT_NOT_FOR_SIGNING);
+            return 0;
+        }
+    }
+    return 1;                   /* all checks are ok */
+}
+
+#endif
+
+static int ssl_get_server_cert_index(const SSL *s)
+{
+    int idx;
+    idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
+    if (idx == SSL_PKEY_RSA_ENC && !s->cert->pkeys[SSL_PKEY_RSA_ENC].x509)
+        idx = SSL_PKEY_RSA_SIGN;
+    if (idx == SSL_PKEY_GOST_EC) {
+        if (s->cert->pkeys[SSL_PKEY_GOST12_512].x509)
+            idx = SSL_PKEY_GOST12_512;
+        else if (s->cert->pkeys[SSL_PKEY_GOST12_256].x509)
+            idx = SSL_PKEY_GOST12_256;
+        else if (s->cert->pkeys[SSL_PKEY_GOST01].x509)
+            idx = SSL_PKEY_GOST01;
+        else
+            idx = -1;
+    }
+    if (idx == -1)
+        SSLerr(SSL_F_SSL_GET_SERVER_CERT_INDEX, ERR_R_INTERNAL_ERROR);
+    return idx;
+}
+
+CERT_PKEY *ssl_get_server_send_pkey(SSL *s)
+{
+    CERT *c;
+    int i;
+
+    c = s->cert;
+    if (!s->s3 || !s->s3->tmp.new_cipher)
+        return NULL;
+    ssl_set_masks(s);
+
+    i = ssl_get_server_cert_index(s);
+
+    /* This may or may not be an error. */
+    if (i < 0)
+        return NULL;
+
+    /* May be NULL. */
+    return &c->pkeys[i];
+}
+
+EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher,
+                            const EVP_MD **pmd)
+{
+    unsigned long alg_a;
+    CERT *c;
+    int idx = -1;
+
+    alg_a = cipher->algorithm_auth;
+    c = s->cert;
+
+    if ((alg_a & SSL_aDSS) && (c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL))
+        idx = SSL_PKEY_DSA_SIGN;
+    else if (alg_a & SSL_aRSA) {
+        if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL)
+            idx = SSL_PKEY_RSA_SIGN;
+        else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL)
+            idx = SSL_PKEY_RSA_ENC;
+    } else if ((alg_a & SSL_aECDSA) &&
+               (c->pkeys[SSL_PKEY_ECC].privatekey != NULL))
+        idx = SSL_PKEY_ECC;
+    if (idx == -1) {
+        SSLerr(SSL_F_SSL_GET_SIGN_PKEY, ERR_R_INTERNAL_ERROR);
+        return (NULL);
+    }
+    if (pmd)
+        *pmd = s->s3->tmp.md[idx];
+    return c->pkeys[idx].privatekey;
+}
+
+int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo,
+                                   size_t *serverinfo_length)
+{
+    CERT *c = NULL;
+    int i = 0;
+    *serverinfo_length = 0;
+
+    c = s->cert;
+    i = ssl_get_server_cert_index(s);
+
+    if (i == -1)
+        return 0;
+    if (c->pkeys[i].serverinfo == NULL)
+        return 0;
+
+    *serverinfo = c->pkeys[i].serverinfo;
+    *serverinfo_length = c->pkeys[i].serverinfo_length;
+    return 1;
+}
+
+void ssl_update_cache(SSL *s, int mode)
+{
+    int i;
+
+    /*
+     * If the session_id_length is 0, we are not supposed to cache it, and it
+     * would be rather hard to do anyway :-)
+     */
+    if (s->session->session_id_length == 0)
+        return;
+
+    i = s->session_ctx->session_cache_mode;
+    if ((i & mode) && (!s->hit)
+        && ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE)
+            || SSL_CTX_add_session(s->session_ctx, s->session))
+        && (s->session_ctx->new_session_cb != NULL)) {
+        SSL_SESSION_up_ref(s->session);
+        if (!s->session_ctx->new_session_cb(s, s->session))
+            SSL_SESSION_free(s->session);
+    }
+
+    /* auto flush every 255 connections */
+    if ((!(i & SSL_SESS_CACHE_NO_AUTO_CLEAR)) && ((i & mode) == mode)) {
+        if ((((mode & SSL_SESS_CACHE_CLIENT)
+              ? s->session_ctx->stats.sess_connect_good
+              : s->session_ctx->stats.sess_accept_good) & 0xff) == 0xff) {
+            SSL_CTX_flush_sessions(s->session_ctx, (unsigned long)time(NULL));
+        }
+    }
+}
+
+const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx)
+{
+    return ctx->method;
+}
+
+const SSL_METHOD *SSL_get_ssl_method(SSL *s)
+{
+    return (s->method);
+}
+
+int SSL_set_ssl_method(SSL *s, const SSL_METHOD *meth)
+{
+    int ret = 1;
+
+    if (s->method != meth) {
+        const SSL_METHOD *sm = s->method;
+        int (*hf) (SSL *) = s->handshake_func;
+
+        if (sm->version == meth->version)
+            s->method = meth;
+        else {
+            sm->ssl_free(s);
+            s->method = meth;
+            ret = s->method->ssl_new(s);
+        }
+
+        if (hf == sm->ssl_connect)
+            s->handshake_func = meth->ssl_connect;
+        else if (hf == sm->ssl_accept)
+            s->handshake_func = meth->ssl_accept;
+    }
+    return (ret);
+}
+
+int SSL_get_error(const SSL *s, int i)
+{
+    int reason;
+    unsigned long l;
+    BIO *bio;
+
+    if (i > 0)
+        return (SSL_ERROR_NONE);
+
+    /*
+     * Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc,
+     * where we do encode the error
+     */
+    if ((l = ERR_peek_error()) != 0) {
+        if (ERR_GET_LIB(l) == ERR_LIB_SYS)
+            return (SSL_ERROR_SYSCALL);
+        else
+            return (SSL_ERROR_SSL);
+    }
+
+    if (i < 0) {
+        if (SSL_want_read(s)) {
+            bio = SSL_get_rbio(s);
+            if (BIO_should_read(bio))
+                return (SSL_ERROR_WANT_READ);
+            else if (BIO_should_write(bio))
+                /*
+                 * This one doesn't make too much sense ... We never try to write
+                 * to the rbio, and an application program where rbio and wbio
+                 * are separate couldn't even know what it should wait for.
+                 * However if we ever set s->rwstate incorrectly (so that we have
+                 * SSL_want_read(s) instead of SSL_want_write(s)) and rbio and
+                 * wbio *are* the same, this test works around that bug; so it
+                 * might be safer to keep it.
+                 */
+                return (SSL_ERROR_WANT_WRITE);
+            else if (BIO_should_io_special(bio)) {
+                reason = BIO_get_retry_reason(bio);
+                if (reason == BIO_RR_CONNECT)
+                    return (SSL_ERROR_WANT_CONNECT);
+                else if (reason == BIO_RR_ACCEPT)
+                    return (SSL_ERROR_WANT_ACCEPT);
+                else
+                    return (SSL_ERROR_SYSCALL); /* unknown */
+            }
+        }
+
+        if (SSL_want_write(s)) {
+            /*
+             * Access wbio directly - in order to use the buffered bio if
+             * present
+             */
+            bio = s->wbio;
+            if (BIO_should_write(bio))
+                return (SSL_ERROR_WANT_WRITE);
+            else if (BIO_should_read(bio))
+                /*
+                 * See above (SSL_want_read(s) with BIO_should_write(bio))
+                 */
+                return (SSL_ERROR_WANT_READ);
+            else if (BIO_should_io_special(bio)) {
+                reason = BIO_get_retry_reason(bio);
+                if (reason == BIO_RR_CONNECT)
+                    return (SSL_ERROR_WANT_CONNECT);
+                else if (reason == BIO_RR_ACCEPT)
+                    return (SSL_ERROR_WANT_ACCEPT);
+                else
+                    return (SSL_ERROR_SYSCALL);
+            }
+        }
+        if (SSL_want_x509_lookup(s)) {
+            return (SSL_ERROR_WANT_X509_LOOKUP);
+        }
+        if (SSL_want_async(s)) {
+            return SSL_ERROR_WANT_ASYNC;
+        }
+        if (SSL_want_async_job(s)) {
+            return SSL_ERROR_WANT_ASYNC_JOB;
+        }
+    }
+
+    if (i == 0) {
+        if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) &&
+            (s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY))
+            return (SSL_ERROR_ZERO_RETURN);
+    }
+    return (SSL_ERROR_SYSCALL);
+}
+
+static int ssl_do_handshake_intern(void *vargs)
+{
+    struct ssl_async_args *args;
+    SSL *s;
+
+    args = (struct ssl_async_args *)vargs;
+    s = args->s;
+
+    return s->handshake_func(s);
+}
+
+int SSL_do_handshake(SSL *s)
+{
+    int ret = 1;
+
+    if (s->handshake_func == NULL) {
+        SSLerr(SSL_F_SSL_DO_HANDSHAKE, SSL_R_CONNECTION_TYPE_NOT_SET);
+        return -1;
+    }
+
+    s->method->ssl_renegotiate_check(s);
+
+    if (SSL_in_init(s) || SSL_in_before(s)) {
+        if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) {
+            struct ssl_async_args args;
+
+            args.s = s;
+
+            ret = ssl_start_async_job(s, &args, ssl_do_handshake_intern);
+        } else {
+            ret = s->handshake_func(s);
+        }
+    }
+    return ret;
+}
+
+void SSL_set_accept_state(SSL *s)
+{
+    s->server = 1;
+    s->shutdown = 0;
+    ossl_statem_clear(s);
+    s->handshake_func = s->method->ssl_accept;
+    clear_ciphers(s);
+}
+
+void SSL_set_connect_state(SSL *s)
+{
+    s->server = 0;
+    s->shutdown = 0;
+    ossl_statem_clear(s);
+    s->handshake_func = s->method->ssl_connect;
+    clear_ciphers(s);
+}
+
+int ssl_undefined_function(SSL *s)
+{
+    SSLerr(SSL_F_SSL_UNDEFINED_FUNCTION, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    return (0);
+}
+
+int ssl_undefined_void_function(void)
+{
+    SSLerr(SSL_F_SSL_UNDEFINED_VOID_FUNCTION,
+           ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    return (0);
+}
+
+int ssl_undefined_const_function(const SSL *s)
+{
+    return (0);
+}
+
+const SSL_METHOD *ssl_bad_method(int ver)
+{
+    SSLerr(SSL_F_SSL_BAD_METHOD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+    return (NULL);
+}
+
+const char *ssl_protocol_to_string(int version)
+{
+    if (version == TLS1_2_VERSION)
+        return "TLSv1.2";
+    else if (version == TLS1_1_VERSION)
+        return "TLSv1.1";
+    else if (version == TLS1_VERSION)
+        return "TLSv1";
+    else if (version == SSL3_VERSION)
+        return "SSLv3";
+    else if (version == DTLS1_BAD_VER)
+        return "DTLSv0.9";
+    else if (version == DTLS1_VERSION)
+        return "DTLSv1";
+    else if (version == DTLS1_2_VERSION)
+        return "DTLSv1.2";
+    else
+        return ("unknown");
+}
+
+const char *SSL_get_version(const SSL *s)
+{
+    return ssl_protocol_to_string(s->version);
+}
+
+SSL *SSL_dup(SSL *s)
+{
+    STACK_OF(X509_NAME) *sk;
+    X509_NAME *xn;
+    SSL *ret;
+    int i;
+
+    /* If we're not quiescent, just up_ref! */
+    if (!SSL_in_init(s) || !SSL_in_before(s)) {
+        CRYPTO_atomic_add(&s->references, 1, &i, s->lock);
+        return s;
+    }
+
+    /*
+     * Otherwise, copy configuration state, and session if set.
+     */
+    if ((ret = SSL_new(SSL_get_SSL_CTX(s))) == NULL)
+        return (NULL);
+
+    if (s->session != NULL) {
+        /*
+         * Arranges to share the same session via up_ref.  This "copies"
+         * session-id, SSL_METHOD, sid_ctx, and 'cert'
+         */
+        if (!SSL_copy_session_id(ret, s))
+            goto err;
+    } else {
+        /*
+         * No session has been established yet, so we have to expect that
+         * s->cert or ret->cert will be changed later -- they should not both
+         * point to the same object, and thus we can't use
+         * SSL_copy_session_id.
+         */
+        if (!SSL_set_ssl_method(ret, s->method))
+            goto err;
+
+        if (s->cert != NULL) {
+            ssl_cert_free(ret->cert);
+            ret->cert = ssl_cert_dup(s->cert);
+            if (ret->cert == NULL)
+                goto err;
+        }
+
+        if (!SSL_set_session_id_context(ret, s->sid_ctx, s->sid_ctx_length))
+            goto err;
+    }
+
+    if (!ssl_dane_dup(ret, s))
+        goto err;
+    ret->version = s->version;
+    ret->options = s->options;
+    ret->mode = s->mode;
+    SSL_set_max_cert_list(ret, SSL_get_max_cert_list(s));
+    SSL_set_read_ahead(ret, SSL_get_read_ahead(s));
+    ret->msg_callback = s->msg_callback;
+    ret->msg_callback_arg = s->msg_callback_arg;
+    SSL_set_verify(ret, SSL_get_verify_mode(s), SSL_get_verify_callback(s));
+    SSL_set_verify_depth(ret, SSL_get_verify_depth(s));
+    ret->generate_session_id = s->generate_session_id;
+
+    SSL_set_info_callback(ret, SSL_get_info_callback(s));
+
+    /* copy app data, a little dangerous perhaps */
+    if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL, &ret->ex_data, &s->ex_data))
+        goto err;
+
+    /* setup rbio, and wbio */
+    if (s->rbio != NULL) {
+        if (!BIO_dup_state(s->rbio, (char *)&ret->rbio))
+            goto err;
+    }
+    if (s->wbio != NULL) {
+        if (s->wbio != s->rbio) {
+            if (!BIO_dup_state(s->wbio, (char *)&ret->wbio))
+                goto err;
+        } else {
+            BIO_up_ref(ret->rbio);
+            ret->wbio = ret->rbio;
+        }
+    }
+
+    ret->server = s->server;
+    if (s->handshake_func) {
+        if (s->server)
+            SSL_set_accept_state(ret);
+        else
+            SSL_set_connect_state(ret);
+    }
+    ret->shutdown = s->shutdown;
+    ret->hit = s->hit;
+
+    ret->default_passwd_callback = s->default_passwd_callback;
+    ret->default_passwd_callback_userdata = s->default_passwd_callback_userdata;
+
+    X509_VERIFY_PARAM_inherit(ret->param, s->param);
+
+    /* dup the cipher_list and cipher_list_by_id stacks */
+    if (s->cipher_list != NULL) {
+        if ((ret->cipher_list = sk_SSL_CIPHER_dup(s->cipher_list)) == NULL)
+            goto err;
+    }
+    if (s->cipher_list_by_id != NULL)
+        if ((ret->cipher_list_by_id = sk_SSL_CIPHER_dup(s->cipher_list_by_id))
+            == NULL)
+            goto err;
+
+    /* Dup the client_CA list */
+    if (s->client_CA != NULL) {
+        if ((sk = sk_X509_NAME_dup(s->client_CA)) == NULL)
+            goto err;
+        ret->client_CA = sk;
+        for (i = 0; i < sk_X509_NAME_num(sk); i++) {
+            xn = sk_X509_NAME_value(sk, i);
+            if (sk_X509_NAME_set(sk, i, X509_NAME_dup(xn)) == NULL) {
+                X509_NAME_free(xn);
+                goto err;
+            }
+        }
+    }
+    return ret;
+
+ err:
+    SSL_free(ret);
+    return NULL;
+}
+
+void ssl_clear_cipher_ctx(SSL *s)
+{
+    if (s->enc_read_ctx != NULL) {
+        EVP_CIPHER_CTX_free(s->enc_read_ctx);
+        s->enc_read_ctx = NULL;
+    }
+    if (s->enc_write_ctx != NULL) {
+        EVP_CIPHER_CTX_free(s->enc_write_ctx);
+        s->enc_write_ctx = NULL;
+    }
+#ifndef OPENSSL_NO_COMP
+    COMP_CTX_free(s->expand);
+    s->expand = NULL;
+    COMP_CTX_free(s->compress);
+    s->compress = NULL;
+#endif
+}
+
+X509 *SSL_get_certificate(const SSL *s)
+{
+    if (s->cert != NULL)
+        return (s->cert->key->x509);
+    else
+        return (NULL);
+}
+
+EVP_PKEY *SSL_get_privatekey(const SSL *s)
+{
+    if (s->cert != NULL)
+        return (s->cert->key->privatekey);
+    else
+        return (NULL);
+}
+
+X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx)
+{
+    if (ctx->cert != NULL)
+        return ctx->cert->key->x509;
+    else
+        return NULL;
+}
+
+EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx)
+{
+    if (ctx->cert != NULL)
+        return ctx->cert->key->privatekey;
+    else
+        return NULL;
+}
+
+const SSL_CIPHER *SSL_get_current_cipher(const SSL *s)
+{
+    if ((s->session != NULL) && (s->session->cipher != NULL))
+        return (s->session->cipher);
+    return (NULL);
+}
+
+const COMP_METHOD *SSL_get_current_compression(SSL *s)
+{
+#ifndef OPENSSL_NO_COMP
+    return s->compress ? COMP_CTX_get_method(s->compress) : NULL;
+#else
+    return NULL;
+#endif
+}
+
+const COMP_METHOD *SSL_get_current_expansion(SSL *s)
+{
+#ifndef OPENSSL_NO_COMP
+    return s->expand ? COMP_CTX_get_method(s->expand) : NULL;
+#else
+    return NULL;
+#endif
+}
+
+int ssl_init_wbio_buffer(SSL *s)
+{
+    BIO *bbio;
+
+    if (s->bbio != NULL) {
+        /* Already buffered. */
+        return 1;
+    }
+
+    bbio = BIO_new(BIO_f_buffer());
+    if (bbio == NULL || !BIO_set_read_buffer_size(bbio, 1)) {
+        BIO_free(bbio);
+        SSLerr(SSL_F_SSL_INIT_WBIO_BUFFER, ERR_R_BUF_LIB);
+        return 0;
+    }
+    s->bbio = bbio;
+    s->wbio = BIO_push(bbio, s->wbio);
+
+    return 1;
+}
+
+void ssl_free_wbio_buffer(SSL *s)
+{
+    /* callers ensure s is never null */
+    if (s->bbio == NULL)
+        return;
+
+    s->wbio = BIO_pop(s->wbio);
+    assert(s->wbio != NULL);
+    BIO_free(s->bbio);
+    s->bbio = NULL;
+}
+
+void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode)
+{
+    ctx->quiet_shutdown = mode;
+}
+
+int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx)
+{
+    return (ctx->quiet_shutdown);
+}
+
+void SSL_set_quiet_shutdown(SSL *s, int mode)
+{
+    s->quiet_shutdown = mode;
+}
+
+int SSL_get_quiet_shutdown(const SSL *s)
+{
+    return (s->quiet_shutdown);
+}
+
+void SSL_set_shutdown(SSL *s, int mode)
+{
+    s->shutdown = mode;
+}
+
+int SSL_get_shutdown(const SSL *s)
+{
+    return s->shutdown;
+}
+
+int SSL_version(const SSL *s)
+{
+    return s->version;
+}
+
+int SSL_client_version(const SSL *s)
+{
+    return s->client_version;
+}
+
+SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl)
+{
+    return ssl->ctx;
+}
+
+SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx)
+{
+    CERT *new_cert;
+    if (ssl->ctx == ctx)
+        return ssl->ctx;
+    if (ctx == NULL)
+        ctx = ssl->session_ctx;
+    new_cert = ssl_cert_dup(ctx->cert);
+    if (new_cert == NULL) {
+        return NULL;
+    }
+    ssl_cert_free(ssl->cert);
+    ssl->cert = new_cert;
+
+    /*
+     * Program invariant: |sid_ctx| has fixed size (SSL_MAX_SID_CTX_LENGTH),
+     * so setter APIs must prevent invalid lengths from entering the system.
+     */
+    OPENSSL_assert(ssl->sid_ctx_length <= sizeof(ssl->sid_ctx));
+
+    /*
+     * If the session ID context matches that of the parent SSL_CTX,
+     * inherit it from the new SSL_CTX as well. If however the context does
+     * not match (i.e., it was set per-ssl with SSL_set_session_id_context),
+     * leave it unchanged.
+     */
+    if ((ssl->ctx != NULL) &&
+        (ssl->sid_ctx_length == ssl->ctx->sid_ctx_length) &&
+        (memcmp(ssl->sid_ctx, ssl->ctx->sid_ctx, ssl->sid_ctx_length) == 0)) {
+        ssl->sid_ctx_length = ctx->sid_ctx_length;
+        memcpy(&ssl->sid_ctx, &ctx->sid_ctx, sizeof(ssl->sid_ctx));
+    }
+
+    SSL_CTX_up_ref(ctx);
+    SSL_CTX_free(ssl->ctx);     /* decrement reference count */
+    ssl->ctx = ctx;
+
+    return ssl->ctx;
+}
+
+int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx)
+{
+    return (X509_STORE_set_default_paths(ctx->cert_store));
+}
+
+int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx)
+{
+    X509_LOOKUP *lookup;
+
+    lookup = X509_STORE_add_lookup(ctx->cert_store, X509_LOOKUP_hash_dir());
+    if (lookup == NULL)
+        return 0;
+    X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
+
+    /* Clear any errors if the default directory does not exist */
+    ERR_clear_error();
+
+    return 1;
+}
+
+int SSL_CTX_set_default_verify_file(SSL_CTX *ctx)
+{
+    X509_LOOKUP *lookup;
+
+    lookup = X509_STORE_add_lookup(ctx->cert_store, X509_LOOKUP_file());
+    if (lookup == NULL)
+        return 0;
+
+    X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
+
+    /* Clear any errors if the default file does not exist */
+    ERR_clear_error();
+
+    return 1;
+}
+
+int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
+                                  const char *CApath)
+{
+    return (X509_STORE_load_locations(ctx->cert_store, CAfile, CApath));
+}
+
+void SSL_set_info_callback(SSL *ssl,
+                           void (*cb) (const SSL *ssl, int type, int val))
+{
+    ssl->info_callback = cb;
+}
+
+/*
+ * One compiler (Diab DCC) doesn't like argument names in returned function
+ * pointer.
+ */
+void (*SSL_get_info_callback(const SSL *ssl)) (const SSL * /* ssl */ ,
+                                               int /* type */ ,
+                                               int /* val */ ) {
+    return ssl->info_callback;
+}
+
+void SSL_set_verify_result(SSL *ssl, long arg)
+{
+    ssl->verify_result = arg;
+}
+
+long SSL_get_verify_result(const SSL *ssl)
+{
+    return (ssl->verify_result);
+}
+
+size_t SSL_get_client_random(const SSL *ssl, unsigned char *out, size_t outlen)
+{
+    if (outlen == 0)
+        return sizeof(ssl->s3->client_random);
+    if (outlen > sizeof(ssl->s3->client_random))
+        outlen = sizeof(ssl->s3->client_random);
+    memcpy(out, ssl->s3->client_random, outlen);
+    return outlen;
+}
+
+size_t SSL_get_server_random(const SSL *ssl, unsigned char *out, size_t outlen)
+{
+    if (outlen == 0)
+        return sizeof(ssl->s3->server_random);
+    if (outlen > sizeof(ssl->s3->server_random))
+        outlen = sizeof(ssl->s3->server_random);
+    memcpy(out, ssl->s3->server_random, outlen);
+    return outlen;
+}
+
+size_t SSL_SESSION_get_master_key(const SSL_SESSION *session,
+                                  unsigned char *out, size_t outlen)
+{
+    if (session->master_key_length < 0) {
+        /* Should never happen */
+        return 0;
+    }
+    if (outlen == 0)
+        return session->master_key_length;
+    if (outlen > (size_t)session->master_key_length)
+        outlen = session->master_key_length;
+    memcpy(out, session->master_key, outlen);
+    return outlen;
+}
+
+int SSL_set_ex_data(SSL *s, int idx, void *arg)
+{
+    return (CRYPTO_set_ex_data(&s->ex_data, idx, arg));
+}
+
+void *SSL_get_ex_data(const SSL *s, int idx)
+{
+    return (CRYPTO_get_ex_data(&s->ex_data, idx));
+}
+
+int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, void *arg)
+{
+    return (CRYPTO_set_ex_data(&s->ex_data, idx, arg));
+}
+
+void *SSL_CTX_get_ex_data(const SSL_CTX *s, int idx)
+{
+    return (CRYPTO_get_ex_data(&s->ex_data, idx));
+}
+
+int ssl_ok(SSL *s)
+{
+    return (1);
+}
+
+X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx)
+{
+    return (ctx->cert_store);
+}
+
+void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store)
+{
+    X509_STORE_free(ctx->cert_store);
+    ctx->cert_store = store;
+}
+
+int SSL_want(const SSL *s)
+{
+    return (s->rwstate);
+}
+
+/**
+ * \brief Set the callback for generating temporary DH keys.
+ * \param ctx the SSL context.
+ * \param dh the callback
+ */
+
+#ifndef OPENSSL_NO_DH
+void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
+                                 DH *(*dh) (SSL *ssl, int is_export,
+                                            int keylength))
+{
+    SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh);
+}
+
+void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*dh) (SSL *ssl, int is_export,
+                                                  int keylength))
+{
+    SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh);
+}
+#endif
+
+#ifndef OPENSSL_NO_PSK
+int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint)
+{
+    if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
+        SSLerr(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG);
+        return 0;
+    }
+    OPENSSL_free(ctx->cert->psk_identity_hint);
+    if (identity_hint != NULL) {
+        ctx->cert->psk_identity_hint = OPENSSL_strdup(identity_hint);
+        if (ctx->cert->psk_identity_hint == NULL)
+            return 0;
+    } else
+        ctx->cert->psk_identity_hint = NULL;
+    return 1;
+}
+
+int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint)
+{
+    if (s == NULL)
+        return 0;
+
+    if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
+        SSLerr(SSL_F_SSL_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG);
+        return 0;
+    }
+    OPENSSL_free(s->cert->psk_identity_hint);
+    if (identity_hint != NULL) {
+        s->cert->psk_identity_hint = OPENSSL_strdup(identity_hint);
+        if (s->cert->psk_identity_hint == NULL)
+            return 0;
+    } else
+        s->cert->psk_identity_hint = NULL;
+    return 1;
+}
+
+const char *SSL_get_psk_identity_hint(const SSL *s)
+{
+    if (s == NULL || s->session == NULL)
+        return NULL;
+    return (s->session->psk_identity_hint);
+}
+
+const char *SSL_get_psk_identity(const SSL *s)
+{
+    if (s == NULL || s->session == NULL)
+        return NULL;
+    return (s->session->psk_identity);
+}
+
+void SSL_set_psk_client_callback(SSL *s,
+                                 unsigned int (*cb) (SSL *ssl,
+                                                     const char *hint,
+                                                     char *identity,
+                                                     unsigned int
+                                                     max_identity_len,
+                                                     unsigned char *psk,
+                                                     unsigned int max_psk_len))
+{
+    s->psk_client_callback = cb;
+}
+
+void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx,
+                                     unsigned int (*cb) (SSL *ssl,
+                                                         const char *hint,
+                                                         char *identity,
+                                                         unsigned int
+                                                         max_identity_len,
+                                                         unsigned char *psk,
+                                                         unsigned int
+                                                         max_psk_len))
+{
+    ctx->psk_client_callback = cb;
+}
+
+void SSL_set_psk_server_callback(SSL *s,
+                                 unsigned int (*cb) (SSL *ssl,
+                                                     const char *identity,
+                                                     unsigned char *psk,
+                                                     unsigned int max_psk_len))
+{
+    s->psk_server_callback = cb;
+}
+
+void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx,
+                                     unsigned int (*cb) (SSL *ssl,
+                                                         const char *identity,
+                                                         unsigned char *psk,
+                                                         unsigned int
+                                                         max_psk_len))
+{
+    ctx->psk_server_callback = cb;
+}
+#endif
+
+void SSL_CTX_set_msg_callback(SSL_CTX *ctx,
+                              void (*cb) (int write_p, int version,
+                                          int content_type, const void *buf,
+                                          size_t len, SSL *ssl, void *arg))
+{
+    SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
+}
+
+void SSL_set_msg_callback(SSL *ssl,
+                          void (*cb) (int write_p, int version,
+                                      int content_type, const void *buf,
+                                      size_t len, SSL *ssl, void *arg))
+{
+    SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
+}
+
+void SSL_CTX_set_not_resumable_session_callback(SSL_CTX *ctx,
+                                                int (*cb) (SSL *ssl,
+                                                           int
+                                                           is_forward_secure))
+{
+    SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB,
+                          (void (*)(void))cb);
+}
+
+void SSL_set_not_resumable_session_callback(SSL *ssl,
+                                            int (*cb) (SSL *ssl,
+                                                       int is_forward_secure))
+{
+    SSL_callback_ctrl(ssl, SSL_CTRL_SET_NOT_RESUMABLE_SESS_CB,
+                      (void (*)(void))cb);
+}
+
+/*
+ * Allocates new EVP_MD_CTX and sets pointer to it into given pointer
+ * variable, freeing EVP_MD_CTX previously stored in that variable, if any.
+ * If EVP_MD pointer is passed, initializes ctx with this md Returns newly
+ * allocated ctx;
+ */
+
+EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md)
+{
+    ssl_clear_hash_ctx(hash);
+    *hash = EVP_MD_CTX_new();
+    if (*hash == NULL || (md && EVP_DigestInit_ex(*hash, md, NULL) <= 0)) {
+        EVP_MD_CTX_free(*hash);
+        *hash = NULL;
+        return NULL;
+    }
+    return *hash;
+}
+
+void ssl_clear_hash_ctx(EVP_MD_CTX **hash)
+{
+
+    if (*hash)
+        EVP_MD_CTX_free(*hash);
+    *hash = NULL;
+}
+
+/* Retrieve handshake hashes */
+int ssl_handshake_hash(SSL *s, unsigned char *out, int outlen)
+{
+    EVP_MD_CTX *ctx = NULL;
+    EVP_MD_CTX *hdgst = s->s3->handshake_dgst;
+    int ret = EVP_MD_CTX_size(hdgst);
+    if (ret < 0 || ret > outlen) {
+        ret = 0;
+        goto err;
+    }
+    ctx = EVP_MD_CTX_new();
+    if (ctx == NULL) {
+        ret = 0;
+        goto err;
+    }
+    if (!EVP_MD_CTX_copy_ex(ctx, hdgst)
+        || EVP_DigestFinal_ex(ctx, out, NULL) <= 0)
+        ret = 0;
+ err:
+    EVP_MD_CTX_free(ctx);
+    return ret;
+}
+
+int SSL_session_reused(SSL *s)
+{
+    return s->hit;
+}
+
+int SSL_is_server(SSL *s)
+{
+    return s->server;
+}
+
+#if OPENSSL_API_COMPAT < 0x10100000L
+void SSL_set_debug(SSL *s, int debug)
+{
+    /* Old function was do-nothing anyway... */
+    (void)s;
+    (void)debug;
+}
+#endif
+
+void SSL_set_security_level(SSL *s, int level)
+{
+    s->cert->sec_level = level;
+}
+
+int SSL_get_security_level(const SSL *s)
+{
+    return s->cert->sec_level;
+}
+
+void SSL_set_security_callback(SSL *s,
+                               int (*cb) (const SSL *s, const SSL_CTX *ctx,
+                                          int op, int bits, int nid,
+                                          void *other, void *ex))
+{
+    s->cert->sec_cb = cb;
+}
+
+int (*SSL_get_security_callback(const SSL *s)) (const SSL *s,
+                                                const SSL_CTX *ctx, int op,
+                                                int bits, int nid, void *other,
+                                                void *ex) {
+    return s->cert->sec_cb;
+}
+
+void SSL_set0_security_ex_data(SSL *s, void *ex)
+{
+    s->cert->sec_ex = ex;
+}
+
+void *SSL_get0_security_ex_data(const SSL *s)
+{
+    return s->cert->sec_ex;
+}
+
+void SSL_CTX_set_security_level(SSL_CTX *ctx, int level)
+{
+    ctx->cert->sec_level = level;
+}
+
+int SSL_CTX_get_security_level(const SSL_CTX *ctx)
+{
+    return ctx->cert->sec_level;
+}
+
+void SSL_CTX_set_security_callback(SSL_CTX *ctx,
+                                   int (*cb) (const SSL *s, const SSL_CTX *ctx,
+                                              int op, int bits, int nid,
+                                              void *other, void *ex))
+{
+    ctx->cert->sec_cb = cb;
+}
+
+int (*SSL_CTX_get_security_callback(const SSL_CTX *ctx)) (const SSL *s,
+                                                          const SSL_CTX *ctx,
+                                                          int op, int bits,
+                                                          int nid,
+                                                          void *other,
+                                                          void *ex) {
+    return ctx->cert->sec_cb;
+}
+
+void SSL_CTX_set0_security_ex_data(SSL_CTX *ctx, void *ex)
+{
+    ctx->cert->sec_ex = ex;
+}
+
+void *SSL_CTX_get0_security_ex_data(const SSL_CTX *ctx)
+{
+    return ctx->cert->sec_ex;
+}
+
+/*
+ * Get/Set/Clear options in SSL_CTX or SSL, formerly macros, now functions that
+ * can return unsigned long, instead of the generic long return value from the
+ * control interface.
+ */
+unsigned long SSL_CTX_get_options(const SSL_CTX *ctx)
+{
+    return ctx->options;
+}
+
+unsigned long SSL_get_options(const SSL *s)
+{
+    return s->options;
+}
+
+unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long op)
+{
+    return ctx->options |= op;
+}
+
+unsigned long SSL_set_options(SSL *s, unsigned long op)
+{
+    return s->options |= op;
+}
+
+unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op)
+{
+    return ctx->options &= ~op;
+}
+
+unsigned long SSL_clear_options(SSL *s, unsigned long op)
+{
+    return s->options &= ~op;
+}
+
+STACK_OF(X509) *SSL_get0_verified_chain(const SSL *s)
+{
+    return s->verified_chain;
+}
+
+IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id);
+
+#ifndef OPENSSL_NO_CT
+
+/*
+ * Moves SCTs from the |src| stack to the |dst| stack.
+ * The source of each SCT will be set to |origin|.
+ * If |dst| points to a NULL pointer, a new stack will be created and owned by
+ * the caller.
+ * Returns the number of SCTs moved, or a negative integer if an error occurs.
+ */
+static int ct_move_scts(STACK_OF(SCT) **dst, STACK_OF(SCT) *src,
+                        sct_source_t origin)
+{
+    int scts_moved = 0;
+    SCT *sct = NULL;
+
+    if (*dst == NULL) {
+        *dst = sk_SCT_new_null();
+        if (*dst == NULL) {
+            SSLerr(SSL_F_CT_MOVE_SCTS, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    }
+
+    while ((sct = sk_SCT_pop(src)) != NULL) {
+        if (SCT_set_source(sct, origin) != 1)
+            goto err;
+
+        if (sk_SCT_push(*dst, sct) <= 0)
+            goto err;
+        scts_moved += 1;
+    }
+
+    return scts_moved;
+ err:
+    if (sct != NULL)
+        sk_SCT_push(src, sct);  /* Put the SCT back */
+    return -1;
+}
+
+/*
+ * Look for data collected during ServerHello and parse if found.
+ * Returns the number of SCTs extracted.
+ */
+static int ct_extract_tls_extension_scts(SSL *s)
+{
+    int scts_extracted = 0;
+
+    if (s->tlsext_scts != NULL) {
+        const unsigned char *p = s->tlsext_scts;
+        STACK_OF(SCT) *scts = o2i_SCT_LIST(NULL, &p, s->tlsext_scts_len);
+
+        scts_extracted = ct_move_scts(&s->scts, scts, SCT_SOURCE_TLS_EXTENSION);
+
+        SCT_LIST_free(scts);
+    }
+
+    return scts_extracted;
+}
+
+/*
+ * Checks for an OCSP response and then attempts to extract any SCTs found if it
+ * contains an SCT X509 extension. They will be stored in |s->scts|.
+ * Returns:
+ * - The number of SCTs extracted, assuming an OCSP response exists.
+ * - 0 if no OCSP response exists or it contains no SCTs.
+ * - A negative integer if an error occurs.
+ */
+static int ct_extract_ocsp_response_scts(SSL *s)
+{
+# ifndef OPENSSL_NO_OCSP
+    int scts_extracted = 0;
+    const unsigned char *p;
+    OCSP_BASICRESP *br = NULL;
+    OCSP_RESPONSE *rsp = NULL;
+    STACK_OF(SCT) *scts = NULL;
+    int i;
+
+    if (s->tlsext_ocsp_resp == NULL || s->tlsext_ocsp_resplen == 0)
+        goto err;
+
+    p = s->tlsext_ocsp_resp;
+    rsp = d2i_OCSP_RESPONSE(NULL, &p, s->tlsext_ocsp_resplen);
+    if (rsp == NULL)
+        goto err;
+
+    br = OCSP_response_get1_basic(rsp);
+    if (br == NULL)
+        goto err;
+
+    for (i = 0; i < OCSP_resp_count(br); ++i) {
+        OCSP_SINGLERESP *single = OCSP_resp_get0(br, i);
+
+        if (single == NULL)
+            continue;
+
+        scts =
+            OCSP_SINGLERESP_get1_ext_d2i(single, NID_ct_cert_scts, NULL, NULL);
+        scts_extracted =
+            ct_move_scts(&s->scts, scts, SCT_SOURCE_OCSP_STAPLED_RESPONSE);
+        if (scts_extracted < 0)
+            goto err;
+    }
+ err:
+    SCT_LIST_free(scts);
+    OCSP_BASICRESP_free(br);
+    OCSP_RESPONSE_free(rsp);
+    return scts_extracted;
+# else
+    /* Behave as if no OCSP response exists */
+    return 0;
+# endif
+}
+
+/*
+ * Attempts to extract SCTs from the peer certificate.
+ * Return the number of SCTs extracted, or a negative integer if an error
+ * occurs.
+ */
+static int ct_extract_x509v3_extension_scts(SSL *s)
+{
+    int scts_extracted = 0;
+    X509 *cert = s->session != NULL ? s->session->peer : NULL;
+
+    if (cert != NULL) {
+        STACK_OF(SCT) *scts =
+            X509_get_ext_d2i(cert, NID_ct_precert_scts, NULL, NULL);
+
+        scts_extracted =
+            ct_move_scts(&s->scts, scts, SCT_SOURCE_X509V3_EXTENSION);
+
+        SCT_LIST_free(scts);
+    }
+
+    return scts_extracted;
+}
+
+/*
+ * Attempts to find all received SCTs by checking TLS extensions, the OCSP
+ * response (if it exists) and X509v3 extensions in the certificate.
+ * Returns NULL if an error occurs.
+ */
+const STACK_OF(SCT) *SSL_get0_peer_scts(SSL *s)
+{
+    if (!s->scts_parsed) {
+        if (ct_extract_tls_extension_scts(s) < 0 ||
+            ct_extract_ocsp_response_scts(s) < 0 ||
+            ct_extract_x509v3_extension_scts(s) < 0)
+            goto err;
+
+        s->scts_parsed = 1;
+    }
+    return s->scts;
+ err:
+    return NULL;
+}
+
+static int ct_permissive(const CT_POLICY_EVAL_CTX * ctx,
+                         const STACK_OF(SCT) *scts, void *unused_arg)
+{
+    return 1;
+}
+
+static int ct_strict(const CT_POLICY_EVAL_CTX * ctx,
+                     const STACK_OF(SCT) *scts, void *unused_arg)
+{
+    int count = scts != NULL ? sk_SCT_num(scts) : 0;
+    int i;
+
+    for (i = 0; i < count; ++i) {
+        SCT *sct = sk_SCT_value(scts, i);
+        int status = SCT_get_validation_status(sct);
+
+        if (status == SCT_VALIDATION_STATUS_VALID)
+            return 1;
+    }
+    SSLerr(SSL_F_CT_STRICT, SSL_R_NO_VALID_SCTS);
+    return 0;
+}
+
+int SSL_set_ct_validation_callback(SSL *s, ssl_ct_validation_cb callback,
+                                   void *arg)
+{
+    /*
+     * Since code exists that uses the custom extension handler for CT, look
+     * for this and throw an error if they have already registered to use CT.
+     */
+    if (callback != NULL && SSL_CTX_has_client_custom_ext(s->ctx,
+                                                          TLSEXT_TYPE_signed_certificate_timestamp))
+    {
+        SSLerr(SSL_F_SSL_SET_CT_VALIDATION_CALLBACK,
+               SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED);
+        return 0;
+    }
+
+    if (callback != NULL) {
+        /*
+         * If we are validating CT, then we MUST accept SCTs served via OCSP
+         */
+        if (!SSL_set_tlsext_status_type(s, TLSEXT_STATUSTYPE_ocsp))
+            return 0;
+    }
+
+    s->ct_validation_callback = callback;
+    s->ct_validation_callback_arg = arg;
+
+    return 1;
+}
+
+int SSL_CTX_set_ct_validation_callback(SSL_CTX *ctx,
+                                       ssl_ct_validation_cb callback, void *arg)
+{
+    /*
+     * Since code exists that uses the custom extension handler for CT, look for
+     * this and throw an error if they have already registered to use CT.
+     */
+    if (callback != NULL && SSL_CTX_has_client_custom_ext(ctx,
+                                                          TLSEXT_TYPE_signed_certificate_timestamp))
+    {
+        SSLerr(SSL_F_SSL_CTX_SET_CT_VALIDATION_CALLBACK,
+               SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED);
+        return 0;
+    }
+
+    ctx->ct_validation_callback = callback;
+    ctx->ct_validation_callback_arg = arg;
+    return 1;
+}
+
+int SSL_ct_is_enabled(const SSL *s)
+{
+    return s->ct_validation_callback != NULL;
+}
+
+int SSL_CTX_ct_is_enabled(const SSL_CTX *ctx)
+{
+    return ctx->ct_validation_callback != NULL;
+}
+
+int ssl_validate_ct(SSL *s)
+{
+    int ret = 0;
+    X509 *cert = s->session != NULL ? s->session->peer : NULL;
+    X509 *issuer;
+    SSL_DANE *dane = &s->dane;
+    CT_POLICY_EVAL_CTX *ctx = NULL;
+    const STACK_OF(SCT) *scts;
+
+    /*
+     * If no callback is set, the peer is anonymous, or its chain is invalid,
+     * skip SCT validation - just return success.  Applications that continue
+     * handshakes without certificates, with unverified chains, or pinned leaf
+     * certificates are outside the scope of the WebPKI and CT.
+     *
+     * The above exclusions notwithstanding the vast majority of peers will
+     * have rather ordinary certificate chains validated by typical
+     * applications that perform certificate verification and therefore will
+     * process SCTs when enabled.
+     */
+    if (s->ct_validation_callback == NULL || cert == NULL ||
+        s->verify_result != X509_V_OK ||
+        s->verified_chain == NULL || sk_X509_num(s->verified_chain) <= 1)
+        return 1;
+
+    /*
+     * CT not applicable for chains validated via DANE-TA(2) or DANE-EE(3)
+     * trust-anchors.  See https://tools.ietf.org/html/rfc7671#section-4.2
+     */
+    if (DANETLS_ENABLED(dane) && dane->mtlsa != NULL) {
+        switch (dane->mtlsa->usage) {
+        case DANETLS_USAGE_DANE_TA:
+        case DANETLS_USAGE_DANE_EE:
+            return 1;
+        }
+    }
+
+    ctx = CT_POLICY_EVAL_CTX_new();
+    if (ctx == NULL) {
+        SSLerr(SSL_F_SSL_VALIDATE_CT, ERR_R_MALLOC_FAILURE);
+        goto end;
+    }
+
+    issuer = sk_X509_value(s->verified_chain, 1);
+    CT_POLICY_EVAL_CTX_set1_cert(ctx, cert);
+    CT_POLICY_EVAL_CTX_set1_issuer(ctx, issuer);
+    CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE(ctx, s->ctx->ctlog_store);
+    CT_POLICY_EVAL_CTX_set_time(ctx, SSL_SESSION_get_time(SSL_get0_session(s)));
+
+    scts = SSL_get0_peer_scts(s);
+
+    /*
+     * This function returns success (> 0) only when all the SCTs are valid, 0
+     * when some are invalid, and < 0 on various internal errors (out of
+     * memory, etc.).  Having some, or even all, invalid SCTs is not sufficient
+     * reason to abort the handshake, that decision is up to the callback.
+     * Therefore, we error out only in the unexpected case that the return
+     * value is negative.
+     *
+     * XXX: One might well argue that the return value of this function is an
+     * unfortunate design choice.  Its job is only to determine the validation
+     * status of each of the provided SCTs.  So long as it correctly separates
+     * the wheat from the chaff it should return success.  Failure in this case
+     * ought to correspond to an inability to carry out its duties.
+     */
+    if (SCT_LIST_validate(scts, ctx) < 0) {
+        SSLerr(SSL_F_SSL_VALIDATE_CT, SSL_R_SCT_VERIFICATION_FAILED);
+        goto end;
+    }
+
+    ret = s->ct_validation_callback(ctx, scts, s->ct_validation_callback_arg);
+    if (ret < 0)
+        ret = 0;                /* This function returns 0 on failure */
+
+ end:
+    CT_POLICY_EVAL_CTX_free(ctx);
+    /*
+     * With SSL_VERIFY_NONE the session may be cached and re-used despite a
+     * failure return code here.  Also the application may wish the complete
+     * the handshake, and then disconnect cleanly at a higher layer, after
+     * checking the verification status of the completed connection.
+     *
+     * We therefore force a certificate verification failure which will be
+     * visible via SSL_get_verify_result() and cached as part of any resumed
+     * session.
+     *
+     * Note: the permissive callback is for information gathering only, always
+     * returns success, and does not affect verification status.  Only the
+     * strict callback or a custom application-specified callback can trigger
+     * connection failure or record a verification error.
+     */
+    if (ret <= 0)
+        s->verify_result = X509_V_ERR_NO_VALID_SCTS;
+    return ret;
+}
+
+int SSL_CTX_enable_ct(SSL_CTX *ctx, int validation_mode)
+{
+    switch (validation_mode) {
+    default:
+        SSLerr(SSL_F_SSL_CTX_ENABLE_CT, SSL_R_INVALID_CT_VALIDATION_TYPE);
+        return 0;
+    case SSL_CT_VALIDATION_PERMISSIVE:
+        return SSL_CTX_set_ct_validation_callback(ctx, ct_permissive, NULL);
+    case SSL_CT_VALIDATION_STRICT:
+        return SSL_CTX_set_ct_validation_callback(ctx, ct_strict, NULL);
+    }
+}
+
+int SSL_enable_ct(SSL *s, int validation_mode)
+{
+    switch (validation_mode) {
+    default:
+        SSLerr(SSL_F_SSL_ENABLE_CT, SSL_R_INVALID_CT_VALIDATION_TYPE);
+        return 0;
+    case SSL_CT_VALIDATION_PERMISSIVE:
+        return SSL_set_ct_validation_callback(s, ct_permissive, NULL);
+    case SSL_CT_VALIDATION_STRICT:
+        return SSL_set_ct_validation_callback(s, ct_strict, NULL);
+    }
+}
+
+int SSL_CTX_set_default_ctlog_list_file(SSL_CTX *ctx)
+{
+    return CTLOG_STORE_load_default_file(ctx->ctlog_store);
+}
+
+int SSL_CTX_set_ctlog_list_file(SSL_CTX *ctx, const char *path)
+{
+    return CTLOG_STORE_load_file(ctx->ctlog_store, path);
+}
+
+void SSL_CTX_set0_ctlog_store(SSL_CTX *ctx, CTLOG_STORE * logs)
+{
+    CTLOG_STORE_free(ctx->ctlog_store);
+    ctx->ctlog_store = logs;
+}
+
+const CTLOG_STORE *SSL_CTX_get0_ctlog_store(const SSL_CTX *ctx)
+{
+    return ctx->ctlog_store;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_locl.h	(revision 331)
@@ -0,0 +1,2131 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#ifndef HEADER_SSL_LOCL_H
+# define HEADER_SSL_LOCL_H
+# include <stdlib.h>
+# include <time.h>
+# include <string.h>
+# include <errno.h>
+
+# include "e_os.h"
+# if defined(__unix) || defined(__unix__)
+#  include <sys/time.h>         /* struct timeval for DTLS */
+# endif
+
+# include <openssl/buffer.h>
+# include <openssl/comp.h>
+# include <openssl/bio.h>
+# include <openssl/stack.h>
+# include <openssl/rsa.h>
+# include <openssl/dsa.h>
+# include <openssl/err.h>
+# include <openssl/ssl.h>
+# include <openssl/async.h>
+# include <openssl/symhacks.h>
+# include <openssl/ct.h>
+# include "record/record.h"
+# include "statem/statem.h"
+# include "packet_locl.h"
+# include "internal/dane.h"
+
+# ifdef OPENSSL_BUILD_SHLIBSSL
+#  undef OPENSSL_EXTERN
+#  define OPENSSL_EXTERN OPENSSL_EXPORT
+# endif
+
+# undef PKCS1_CHECK
+
+# define c2l(c,l)        (l = ((unsigned long)(*((c)++)))     , \
+                         l|=(((unsigned long)(*((c)++)))<< 8), \
+                         l|=(((unsigned long)(*((c)++)))<<16), \
+                         l|=(((unsigned long)(*((c)++)))<<24))
+
+/* NOTE - c is not incremented as per c2l */
+# define c2ln(c,l1,l2,n) { \
+                        c+=n; \
+                        l1=l2=0; \
+                        switch (n) { \
+                        case 8: l2 =((unsigned long)(*(--(c))))<<24; \
+                        case 7: l2|=((unsigned long)(*(--(c))))<<16; \
+                        case 6: l2|=((unsigned long)(*(--(c))))<< 8; \
+                        case 5: l2|=((unsigned long)(*(--(c))));     \
+                        case 4: l1 =((unsigned long)(*(--(c))))<<24; \
+                        case 3: l1|=((unsigned long)(*(--(c))))<<16; \
+                        case 2: l1|=((unsigned long)(*(--(c))))<< 8; \
+                        case 1: l1|=((unsigned long)(*(--(c))));     \
+                                } \
+                        }
+
+# define l2c(l,c)        (*((c)++)=(unsigned char)(((l)    )&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>24)&0xff))
+
+# define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24, \
+                         l|=((unsigned long)(*((c)++)))<<16, \
+                         l|=((unsigned long)(*((c)++)))<< 8, \
+                         l|=((unsigned long)(*((c)++))))
+
+# define n2l8(c,l)       (l =((uint64_t)(*((c)++)))<<56, \
+                         l|=((uint64_t)(*((c)++)))<<48, \
+                         l|=((uint64_t)(*((c)++)))<<40, \
+                         l|=((uint64_t)(*((c)++)))<<32, \
+                         l|=((uint64_t)(*((c)++)))<<24, \
+                         l|=((uint64_t)(*((c)++)))<<16, \
+                         l|=((uint64_t)(*((c)++)))<< 8, \
+                         l|=((uint64_t)(*((c)++))))
+
+
+# define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+                         *((c)++)=(unsigned char)(((l)    )&0xff))
+
+# define l2n6(l,c)       (*((c)++)=(unsigned char)(((l)>>40)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>32)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>24)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+                         *((c)++)=(unsigned char)(((l)    )&0xff))
+
+# define l2n8(l,c)       (*((c)++)=(unsigned char)(((l)>>56)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>48)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>40)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>32)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>24)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+                         *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+                         *((c)++)=(unsigned char)(((l)    )&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+# define l2cn(l1,l2,c,n) { \
+                        c+=n; \
+                        switch (n) { \
+                        case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+                        case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+                        case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+                        case 5: *(--(c))=(unsigned char)(((l2)    )&0xff); \
+                        case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+                        case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+                        case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+                        case 1: *(--(c))=(unsigned char)(((l1)    )&0xff); \
+                                } \
+                        }
+
+# define n2s(c,s)        ((s=(((unsigned int)((c)[0]))<< 8)| \
+                             (((unsigned int)((c)[1]))    )),(c)+=2)
+# define s2n(s,c)        (((c)[0]=(unsigned char)(((s)>> 8)&0xff), \
+                           (c)[1]=(unsigned char)(((s)    )&0xff)),(c)+=2)
+
+# define n2l3(c,l)       ((l =(((unsigned long)((c)[0]))<<16)| \
+                              (((unsigned long)((c)[1]))<< 8)| \
+                              (((unsigned long)((c)[2]))    )),(c)+=3)
+
+# define l2n3(l,c)       (((c)[0]=(unsigned char)(((l)>>16)&0xff), \
+                           (c)[1]=(unsigned char)(((l)>> 8)&0xff), \
+                           (c)[2]=(unsigned char)(((l)    )&0xff)),(c)+=3)
+
+/*
+ * DTLS version numbers are strange because they're inverted. Except for
+ * DTLS1_BAD_VER, which should be considered "lower" than the rest.
+ */
+# define dtls_ver_ordinal(v1) (((v1) == DTLS1_BAD_VER) ? 0xff00 : (v1))
+# define DTLS_VERSION_GT(v1, v2) (dtls_ver_ordinal(v1) < dtls_ver_ordinal(v2))
+# define DTLS_VERSION_GE(v1, v2) (dtls_ver_ordinal(v1) <= dtls_ver_ordinal(v2))
+# define DTLS_VERSION_LT(v1, v2) (dtls_ver_ordinal(v1) > dtls_ver_ordinal(v2))
+# define DTLS_VERSION_LE(v1, v2) (dtls_ver_ordinal(v1) >= dtls_ver_ordinal(v2))
+
+/* LOCAL STUFF */
+
+# define SSL_DECRYPT     0
+# define SSL_ENCRYPT     1
+
+# define TWO_BYTE_BIT    0x80
+# define SEC_ESC_BIT     0x40
+# define TWO_BYTE_MASK   0x7fff
+# define THREE_BYTE_MASK 0x3fff
+
+# define INC32(a)        ((a)=((a)+1)&0xffffffffL)
+# define DEC32(a)        ((a)=((a)-1)&0xffffffffL)
+# define MAX_MAC_SIZE    20     /* up from 16 for SSLv3 */
+
+/*
+ * Define the Bitmasks for SSL_CIPHER.algorithms.
+ * This bits are used packed as dense as possible. If new methods/ciphers
+ * etc will be added, the bits a likely to change, so this information
+ * is for internal library use only, even though SSL_CIPHER.algorithms
+ * can be publicly accessed.
+ * Use the according functions for cipher management instead.
+ *
+ * The bit mask handling in the selection and sorting scheme in
+ * ssl_create_cipher_list() has only limited capabilities, reflecting
+ * that the different entities within are mutually exclusive:
+ * ONLY ONE BIT PER MASK CAN BE SET AT A TIME.
+ */
+
+/* Bits for algorithm_mkey (key exchange algorithm) */
+/* RSA key exchange */
+# define SSL_kRSA                0x00000001U
+/* tmp DH key no DH cert */
+# define SSL_kDHE                0x00000002U
+/* synonym */
+# define SSL_kEDH                SSL_kDHE
+/* ephemeral ECDH */
+# define SSL_kECDHE              0x00000004U
+/* synonym */
+# define SSL_kEECDH              SSL_kECDHE
+/* PSK */
+# define SSL_kPSK                0x00000008U
+/* GOST key exchange */
+# define SSL_kGOST               0x00000010U
+/* SRP */
+# define SSL_kSRP                0x00000020U
+
+# define SSL_kRSAPSK             0x00000040U
+# define SSL_kECDHEPSK           0x00000080U
+# define SSL_kDHEPSK             0x00000100U
+
+/* all PSK */
+
+# define SSL_PSK     (SSL_kPSK | SSL_kRSAPSK | SSL_kECDHEPSK | SSL_kDHEPSK)
+
+/* Bits for algorithm_auth (server authentication) */
+/* RSA auth */
+# define SSL_aRSA                0x00000001U
+/* DSS auth */
+# define SSL_aDSS                0x00000002U
+/* no auth (i.e. use ADH or AECDH) */
+# define SSL_aNULL               0x00000004U
+/* ECDSA auth*/
+# define SSL_aECDSA              0x00000008U
+/* PSK auth */
+# define SSL_aPSK                0x00000010U
+/* GOST R 34.10-2001 signature auth */
+# define SSL_aGOST01             0x00000020U
+/* SRP auth */
+# define SSL_aSRP                0x00000040U
+/* GOST R 34.10-2012 signature auth */
+# define SSL_aGOST12             0x00000080U
+
+/* Bits for algorithm_enc (symmetric encryption) */
+# define SSL_DES                 0x00000001U
+# define SSL_3DES                0x00000002U
+# define SSL_RC4                 0x00000004U
+# define SSL_RC2                 0x00000008U
+# define SSL_IDEA                0x00000010U
+# define SSL_eNULL               0x00000020U
+# define SSL_AES128              0x00000040U
+# define SSL_AES256              0x00000080U
+# define SSL_CAMELLIA128         0x00000100U
+# define SSL_CAMELLIA256         0x00000200U
+# define SSL_eGOST2814789CNT     0x00000400U
+# define SSL_SEED                0x00000800U
+# define SSL_AES128GCM           0x00001000U
+# define SSL_AES256GCM           0x00002000U
+# define SSL_AES128CCM           0x00004000U
+# define SSL_AES256CCM           0x00008000U
+# define SSL_AES128CCM8          0x00010000U
+# define SSL_AES256CCM8          0x00020000U
+# define SSL_eGOST2814789CNT12   0x00040000U
+# define SSL_CHACHA20POLY1305    0x00080000U
+
+# define SSL_AESGCM              (SSL_AES128GCM | SSL_AES256GCM)
+# define SSL_AESCCM              (SSL_AES128CCM | SSL_AES256CCM | SSL_AES128CCM8 | SSL_AES256CCM8)
+# define SSL_AES                 (SSL_AES128|SSL_AES256|SSL_AESGCM|SSL_AESCCM)
+# define SSL_CAMELLIA            (SSL_CAMELLIA128|SSL_CAMELLIA256)
+# define SSL_CHACHA20            (SSL_CHACHA20POLY1305)
+
+/* Bits for algorithm_mac (symmetric authentication) */
+
+# define SSL_MD5                 0x00000001U
+# define SSL_SHA1                0x00000002U
+# define SSL_GOST94      0x00000004U
+# define SSL_GOST89MAC   0x00000008U
+# define SSL_SHA256              0x00000010U
+# define SSL_SHA384              0x00000020U
+/* Not a real MAC, just an indication it is part of cipher */
+# define SSL_AEAD                0x00000040U
+# define SSL_GOST12_256          0x00000080U
+# define SSL_GOST89MAC12         0x00000100U
+# define SSL_GOST12_512          0x00000200U
+
+/*
+ * When adding new digest in the ssl_ciph.c and increment SSL_MD_NUM_IDX make
+ * sure to update this constant too
+ */
+
+# define SSL_MD_MD5_IDX  0
+# define SSL_MD_SHA1_IDX 1
+# define SSL_MD_GOST94_IDX 2
+# define SSL_MD_GOST89MAC_IDX 3
+# define SSL_MD_SHA256_IDX 4
+# define SSL_MD_SHA384_IDX 5
+# define SSL_MD_GOST12_256_IDX  6
+# define SSL_MD_GOST89MAC12_IDX 7
+# define SSL_MD_GOST12_512_IDX  8
+# define SSL_MD_MD5_SHA1_IDX 9
+# define SSL_MD_SHA224_IDX 10
+# define SSL_MD_SHA512_IDX 11
+# define SSL_MAX_DIGEST 12
+
+/* Bits for algorithm2 (handshake digests and other extra flags) */
+
+/* Bits 0-7 are handshake MAC */
+# define SSL_HANDSHAKE_MAC_MASK  0xFF
+# define SSL_HANDSHAKE_MAC_MD5_SHA1 SSL_MD_MD5_SHA1_IDX
+# define SSL_HANDSHAKE_MAC_SHA256   SSL_MD_SHA256_IDX
+# define SSL_HANDSHAKE_MAC_SHA384   SSL_MD_SHA384_IDX
+# define SSL_HANDSHAKE_MAC_GOST94 SSL_MD_GOST94_IDX
+# define SSL_HANDSHAKE_MAC_GOST12_256 SSL_MD_GOST12_256_IDX
+# define SSL_HANDSHAKE_MAC_GOST12_512 SSL_MD_GOST12_512_IDX
+# define SSL_HANDSHAKE_MAC_DEFAULT  SSL_HANDSHAKE_MAC_MD5_SHA1
+
+/* Bits 8-15 bits are PRF */
+# define TLS1_PRF_DGST_SHIFT 8
+# define TLS1_PRF_SHA1_MD5 (SSL_MD_MD5_SHA1_IDX << TLS1_PRF_DGST_SHIFT)
+# define TLS1_PRF_SHA256 (SSL_MD_SHA256_IDX << TLS1_PRF_DGST_SHIFT)
+# define TLS1_PRF_SHA384 (SSL_MD_SHA384_IDX << TLS1_PRF_DGST_SHIFT)
+# define TLS1_PRF_GOST94 (SSL_MD_GOST94_IDX << TLS1_PRF_DGST_SHIFT)
+# define TLS1_PRF_GOST12_256 (SSL_MD_GOST12_256_IDX << TLS1_PRF_DGST_SHIFT)
+# define TLS1_PRF_GOST12_512 (SSL_MD_GOST12_512_IDX << TLS1_PRF_DGST_SHIFT)
+# define TLS1_PRF            (SSL_MD_MD5_SHA1_IDX << TLS1_PRF_DGST_SHIFT)
+
+/*
+ * Stream MAC for GOST ciphersuites from cryptopro draft (currently this also
+ * goes into algorithm2)
+ */
+# define TLS1_STREAM_MAC 0x10000
+
+# define SSL_STRONG_MASK         0x0000001FU
+# define SSL_DEFAULT_MASK        0X00000020U
+
+# define SSL_STRONG_NONE         0x00000001U
+# define SSL_LOW                 0x00000002U
+# define SSL_MEDIUM              0x00000004U
+# define SSL_HIGH                0x00000008U
+# define SSL_FIPS                0x00000010U
+# define SSL_NOT_DEFAULT         0x00000020U
+
+/* we have used 0000003f - 26 bits left to go */
+
+/* Check if an SSL structure is using DTLS */
+# define SSL_IS_DTLS(s)  (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS)
+/* See if we need explicit IV */
+# define SSL_USE_EXPLICIT_IV(s)  \
+                (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_EXPLICIT_IV)
+/*
+ * See if we use signature algorithms extension and signature algorithm
+ * before signatures.
+ */
+# define SSL_USE_SIGALGS(s)      \
+                        (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SIGALGS)
+/*
+ * Allow TLS 1.2 ciphersuites: applies to DTLS 1.2 as well as TLS 1.2: may
+ * apply to others in future.
+ */
+# define SSL_USE_TLS1_2_CIPHERS(s)       \
+                (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS)
+/*
+ * Determine if a client can use TLS 1.2 ciphersuites: can't rely on method
+ * flags because it may not be set to correct version yet.
+ */
+# define SSL_CLIENT_USE_TLS1_2_CIPHERS(s)        \
+    ((!SSL_IS_DTLS(s) && s->client_version >= TLS1_2_VERSION) || \
+     (SSL_IS_DTLS(s) && DTLS_VERSION_GE(s->client_version, DTLS1_2_VERSION)))
+/*
+ * Determine if a client should send signature algorithms extension:
+ * as with TLS1.2 cipher we can't rely on method flags.
+ */
+# define SSL_CLIENT_USE_SIGALGS(s)        \
+    SSL_CLIENT_USE_TLS1_2_CIPHERS(s)
+
+# define SSL_READ_ETM(s) (s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC_READ)
+# define SSL_WRITE_ETM(s) (s->s3->flags & TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE)
+
+/* Mostly for SSLv3 */
+# define SSL_PKEY_RSA_ENC        0
+# define SSL_PKEY_RSA_SIGN       1
+# define SSL_PKEY_DSA_SIGN       2
+# define SSL_PKEY_ECC            3
+# define SSL_PKEY_GOST01         4
+# define SSL_PKEY_GOST12_256     5
+# define SSL_PKEY_GOST12_512     6
+# define SSL_PKEY_NUM            7
+/*
+ * Pseudo-constant. GOST cipher suites can use different certs for 1
+ * SSL_CIPHER. So let's see which one we have in fact.
+ */
+# define SSL_PKEY_GOST_EC SSL_PKEY_NUM+1
+
+/*-
+ * SSL_kRSA <- RSA_ENC
+ * SSL_kDH  <- DH_ENC & (RSA_ENC | RSA_SIGN | DSA_SIGN)
+ * SSL_kDHE <- RSA_ENC | RSA_SIGN | DSA_SIGN
+ * SSL_aRSA <- RSA_ENC | RSA_SIGN
+ * SSL_aDSS <- DSA_SIGN
+ */
+
+/*-
+#define CERT_INVALID            0
+#define CERT_PUBLIC_KEY         1
+#define CERT_PRIVATE_KEY        2
+*/
+
+/* CipherSuite length. SSLv3 and all TLS versions. */
+# define TLS_CIPHER_LEN 2
+/* used to hold info on the particular ciphers used */
+struct ssl_cipher_st {
+    uint32_t valid;
+    const char *name;           /* text name */
+    uint32_t id;                /* id, 4 bytes, first is version */
+    /*
+     * changed in 1.0.0: these four used to be portions of a single value
+     * 'algorithms'
+     */
+    uint32_t algorithm_mkey;    /* key exchange algorithm */
+    uint32_t algorithm_auth;    /* server authentication */
+    uint32_t algorithm_enc;     /* symmetric encryption */
+    uint32_t algorithm_mac;     /* symmetric authentication */
+    int min_tls;                /* minimum SSL/TLS protocol version */
+    int max_tls;                /* maximum SSL/TLS protocol version */
+    int min_dtls;               /* minimum DTLS protocol version */
+    int max_dtls;               /* maximum DTLS protocol version */
+    uint32_t algo_strength;     /* strength and export flags */
+    uint32_t algorithm2;        /* Extra flags */
+    int32_t strength_bits;      /* Number of bits really used */
+    uint32_t alg_bits;          /* Number of bits for algorithm */
+};
+
+/* Used to hold SSL/TLS functions */
+struct ssl_method_st {
+    int version;
+    unsigned flags;
+    unsigned long mask;
+    int (*ssl_new) (SSL *s);
+    void (*ssl_clear) (SSL *s);
+    void (*ssl_free) (SSL *s);
+    int (*ssl_accept) (SSL *s);
+    int (*ssl_connect) (SSL *s);
+    int (*ssl_read) (SSL *s, void *buf, int len);
+    int (*ssl_peek) (SSL *s, void *buf, int len);
+    int (*ssl_write) (SSL *s, const void *buf, int len);
+    int (*ssl_shutdown) (SSL *s);
+    int (*ssl_renegotiate) (SSL *s);
+    int (*ssl_renegotiate_check) (SSL *s);
+    int (*ssl_read_bytes) (SSL *s, int type, int *recvd_type,
+                           unsigned char *buf, int len, int peek);
+    int (*ssl_write_bytes) (SSL *s, int type, const void *buf_, int len);
+    int (*ssl_dispatch_alert) (SSL *s);
+    long (*ssl_ctrl) (SSL *s, int cmd, long larg, void *parg);
+    long (*ssl_ctx_ctrl) (SSL_CTX *ctx, int cmd, long larg, void *parg);
+    const SSL_CIPHER *(*get_cipher_by_char) (const unsigned char *ptr);
+    int (*put_cipher_by_char) (const SSL_CIPHER *cipher, unsigned char *ptr);
+    int (*ssl_pending) (const SSL *s);
+    int (*num_ciphers) (void);
+    const SSL_CIPHER *(*get_cipher) (unsigned ncipher);
+    long (*get_timeout) (void);
+    const struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */
+    int (*ssl_version) (void);
+    long (*ssl_callback_ctrl) (SSL *s, int cb_id, void (*fp) (void));
+    long (*ssl_ctx_callback_ctrl) (SSL_CTX *s, int cb_id, void (*fp) (void));
+};
+
+/*-
+ * Lets make this into an ASN.1 type structure as follows
+ * SSL_SESSION_ID ::= SEQUENCE {
+ *      version                 INTEGER,        -- structure version number
+ *      SSLversion              INTEGER,        -- SSL version number
+ *      Cipher                  OCTET STRING,   -- the 3 byte cipher ID
+ *      Session_ID              OCTET STRING,   -- the Session ID
+ *      Master_key              OCTET STRING,   -- the master key
+ *      Key_Arg [ 0 ] IMPLICIT  OCTET STRING,   -- the optional Key argument
+ *      Time [ 1 ] EXPLICIT     INTEGER,        -- optional Start Time
+ *      Timeout [ 2 ] EXPLICIT  INTEGER,        -- optional Timeout ins seconds
+ *      Peer [ 3 ] EXPLICIT     X509,           -- optional Peer Certificate
+ *      Session_ID_context [ 4 ] EXPLICIT OCTET STRING,   -- the Session ID context
+ *      Verify_result [ 5 ] EXPLICIT INTEGER,   -- X509_V_... code for `Peer'
+ *      HostName [ 6 ] EXPLICIT OCTET STRING,   -- optional HostName from servername TLS extension
+ *      PSK_identity_hint [ 7 ] EXPLICIT OCTET STRING, -- optional PSK identity hint
+ *      PSK_identity [ 8 ] EXPLICIT OCTET STRING,  -- optional PSK identity
+ *      Ticket_lifetime_hint [9] EXPLICIT INTEGER, -- server's lifetime hint for session ticket
+ *      Ticket [10]             EXPLICIT OCTET STRING, -- session ticket (clients only)
+ *      Compression_meth [11]   EXPLICIT OCTET STRING, -- optional compression method
+ *      SRP_username [ 12 ] EXPLICIT OCTET STRING -- optional SRP username
+ *      flags [ 13 ] EXPLICIT INTEGER -- optional flags
+ *      }
+ * Look in ssl/ssl_asn1.c for more details
+ * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-).
+ */
+struct ssl_session_st {
+    int ssl_version;            /* what ssl version session info is being kept
+                                 * in here? */
+    int master_key_length;
+    unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
+    /* session_id - valid? */
+    unsigned int session_id_length;
+    unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH];
+    /*
+     * this is used to determine whether the session is being reused in the
+     * appropriate context. It is up to the application to set this, via
+     * SSL_new
+     */
+    unsigned int sid_ctx_length;
+    unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
+# ifndef OPENSSL_NO_PSK
+    char *psk_identity_hint;
+    char *psk_identity;
+# endif
+    /*
+     * Used to indicate that session resumption is not allowed. Applications
+     * can also set this bit for a new session via not_resumable_session_cb
+     * to disable session caching and tickets.
+     */
+    int not_resumable;
+    /* This is the cert and type for the other end. */
+    X509 *peer;
+    int peer_type;
+    /* Certificate chain peer sent */
+    STACK_OF(X509) *peer_chain;
+    /*
+     * when app_verify_callback accepts a session where the peer's
+     * certificate is not ok, we must remember the error for session reuse:
+     */
+    long verify_result;         /* only for servers */
+    int references;
+    long timeout;
+    long time;
+    unsigned int compress_meth; /* Need to lookup the method */
+    const SSL_CIPHER *cipher;
+    unsigned long cipher_id;    /* when ASN.1 loaded, this needs to be used to
+                                 * load the 'cipher' structure */
+    STACK_OF(SSL_CIPHER) *ciphers; /* shared ciphers? */
+    CRYPTO_EX_DATA ex_data;     /* application specific data */
+    /*
+     * These are used to make removal of session-ids more efficient and to
+     * implement a maximum cache size.
+     */
+    struct ssl_session_st *prev, *next;
+    char *tlsext_hostname;
+# ifndef OPENSSL_NO_EC
+    size_t tlsext_ecpointformatlist_length;
+    unsigned char *tlsext_ecpointformatlist; /* peer's list */
+    size_t tlsext_ellipticcurvelist_length;
+    unsigned char *tlsext_ellipticcurvelist; /* peer's list */
+# endif                         /* OPENSSL_NO_EC */
+    /* RFC4507 info */
+    unsigned char *tlsext_tick; /* Session ticket */
+    size_t tlsext_ticklen;      /* Session ticket length */
+    unsigned long tlsext_tick_lifetime_hint; /* Session lifetime hint in
+                                              * seconds */
+# ifndef OPENSSL_NO_SRP
+    char *srp_username;
+# endif
+    uint32_t flags;
+    CRYPTO_RWLOCK *lock;
+};
+
+/* Extended master secret support */
+# define SSL_SESS_FLAG_EXTMS             0x1
+
+# ifndef OPENSSL_NO_SRP
+
+typedef struct srp_ctx_st {
+    /* param for all the callbacks */
+    void *SRP_cb_arg;
+    /* set client Hello login callback */
+    int (*TLS_ext_srp_username_callback) (SSL *, int *, void *);
+    /* set SRP N/g param callback for verification */
+    int (*SRP_verify_param_callback) (SSL *, void *);
+    /* set SRP client passwd callback */
+    char *(*SRP_give_srp_client_pwd_callback) (SSL *, void *);
+    char *login;
+    BIGNUM *N, *g, *s, *B, *A;
+    BIGNUM *a, *b, *v;
+    char *info;
+    int strength;
+    unsigned long srp_Mask;
+} SRP_CTX;
+
+# endif
+
+struct ssl_comp_st {
+    int id;
+    const char *name;
+    COMP_METHOD *method;
+};
+
+DEFINE_LHASH_OF(SSL_SESSION);
+/* Needed in ssl_cert.c */
+DEFINE_LHASH_OF(X509_NAME);
+
+# define TLSEXT_KEYNAME_LENGTH 16
+
+struct ssl_ctx_st {
+    const SSL_METHOD *method;
+    STACK_OF(SSL_CIPHER) *cipher_list;
+    /* same as above but sorted for lookup */
+    STACK_OF(SSL_CIPHER) *cipher_list_by_id;
+    struct x509_store_st /* X509_STORE */ *cert_store;
+    LHASH_OF(SSL_SESSION) *sessions;
+    /*
+     * Most session-ids that will be cached, default is
+     * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited.
+     */
+    unsigned long session_cache_size;
+    struct ssl_session_st *session_cache_head;
+    struct ssl_session_st *session_cache_tail;
+    /*
+     * This can have one of 2 values, ored together, SSL_SESS_CACHE_CLIENT,
+     * SSL_SESS_CACHE_SERVER, Default is SSL_SESSION_CACHE_SERVER, which
+     * means only SSL_accept which cache SSL_SESSIONS.
+     */
+    uint32_t session_cache_mode;
+    /*
+     * If timeout is not 0, it is the default timeout value set when
+     * SSL_new() is called.  This has been put in to make life easier to set
+     * things up
+     */
+    long session_timeout;
+    /*
+     * If this callback is not null, it will be called each time a session id
+     * is added to the cache.  If this function returns 1, it means that the
+     * callback will do a SSL_SESSION_free() when it has finished using it.
+     * Otherwise, on 0, it means the callback has finished with it. If
+     * remove_session_cb is not null, it will be called when a session-id is
+     * removed from the cache.  After the call, OpenSSL will
+     * SSL_SESSION_free() it.
+     */
+    int (*new_session_cb) (struct ssl_st *ssl, SSL_SESSION *sess);
+    void (*remove_session_cb) (struct ssl_ctx_st *ctx, SSL_SESSION *sess);
+    SSL_SESSION *(*get_session_cb) (struct ssl_st *ssl,
+                                    const unsigned char *data, int len,
+                                    int *copy);
+    struct {
+        int sess_connect;       /* SSL new conn - started */
+        int sess_connect_renegotiate; /* SSL reneg - requested */
+        int sess_connect_good;  /* SSL new conne/reneg - finished */
+        int sess_accept;        /* SSL new accept - started */
+        int sess_accept_renegotiate; /* SSL reneg - requested */
+        int sess_accept_good;   /* SSL accept/reneg - finished */
+        int sess_miss;          /* session lookup misses */
+        int sess_timeout;       /* reuse attempt on timeouted session */
+        int sess_cache_full;    /* session removed due to full cache */
+        int sess_hit;           /* session reuse actually done */
+        int sess_cb_hit;        /* session-id that was not in the cache was
+                                 * passed back via the callback.  This
+                                 * indicates that the application is supplying
+                                 * session-id's from other processes - spooky
+                                 * :-) */
+    } stats;
+
+    int references;
+
+    /* if defined, these override the X509_verify_cert() calls */
+    int (*app_verify_callback) (X509_STORE_CTX *, void *);
+    void *app_verify_arg;
+    /*
+     * before OpenSSL 0.9.7, 'app_verify_arg' was ignored
+     * ('app_verify_callback' was called with just one argument)
+     */
+
+    /* Default password callback. */
+    pem_password_cb *default_passwd_callback;
+
+    /* Default password callback user data. */
+    void *default_passwd_callback_userdata;
+
+    /* get client cert callback */
+    int (*client_cert_cb) (SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+
+    /* cookie generate callback */
+    int (*app_gen_cookie_cb) (SSL *ssl, unsigned char *cookie,
+                              unsigned int *cookie_len);
+
+    /* verify cookie callback */
+    int (*app_verify_cookie_cb) (SSL *ssl, const unsigned char *cookie,
+                                 unsigned int cookie_len);
+
+    CRYPTO_EX_DATA ex_data;
+
+    const EVP_MD *md5;          /* For SSLv3/TLSv1 'ssl3-md5' */
+    const EVP_MD *sha1;         /* For SSLv3/TLSv1 'ssl3->sha1' */
+
+    STACK_OF(X509) *extra_certs;
+    STACK_OF(SSL_COMP) *comp_methods; /* stack of SSL_COMP, SSLv3/TLSv1 */
+
+    /* Default values used when no per-SSL value is defined follow */
+
+    /* used if SSL's info_callback is NULL */
+    void (*info_callback) (const SSL *ssl, int type, int val);
+
+    /* what we put in client cert requests */
+    STACK_OF(X509_NAME) *client_CA;
+
+    /*
+     * Default values to use in SSL structures follow (these are copied by
+     * SSL_new)
+     */
+
+    uint32_t options;
+    uint32_t mode;
+    int min_proto_version;
+    int max_proto_version;
+    long max_cert_list;
+
+    struct cert_st /* CERT */ *cert;
+    int read_ahead;
+
+    /* callback that allows applications to peek at protocol messages */
+    void (*msg_callback) (int write_p, int version, int content_type,
+                          const void *buf, size_t len, SSL *ssl, void *arg);
+    void *msg_callback_arg;
+
+    uint32_t verify_mode;
+    unsigned int sid_ctx_length;
+    unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
+    /* called 'verify_callback' in the SSL */
+    int (*default_verify_callback) (int ok, X509_STORE_CTX *ctx);
+
+    /* Default generate session ID callback. */
+    GEN_SESSION_CB generate_session_id;
+
+    X509_VERIFY_PARAM *param;
+
+    int quiet_shutdown;
+
+# ifndef OPENSSL_NO_CT
+    CTLOG_STORE *ctlog_store;   /* CT Log Store */
+    /*
+     * Validates that the SCTs (Signed Certificate Timestamps) are sufficient.
+     * If they are not, the connection should be aborted.
+     */
+    ssl_ct_validation_cb ct_validation_callback;
+    void *ct_validation_callback_arg;
+# endif
+
+    /*
+     * If we're using more than one pipeline how should we divide the data
+     * up between the pipes?
+     */
+    unsigned int split_send_fragment;
+    /*
+     * Maximum amount of data to send in one fragment. actual record size can
+     * be more than this due to padding and MAC overheads.
+     */
+    unsigned int max_send_fragment;
+
+    /* Up to how many pipelines should we use? If 0 then 1 is assumed */
+    unsigned int max_pipelines;
+
+    /* The default read buffer length to use (0 means not set) */
+    size_t default_read_buf_len;
+
+# ifndef OPENSSL_NO_ENGINE
+    /*
+     * Engine to pass requests for client certs to
+     */
+    ENGINE *client_cert_engine;
+# endif
+
+    /* TLS extensions servername callback */
+    int (*tlsext_servername_callback) (SSL *, int *, void *);
+    void *tlsext_servername_arg;
+    /* RFC 4507 session ticket keys */
+    unsigned char tlsext_tick_key_name[TLSEXT_KEYNAME_LENGTH];
+    unsigned char tlsext_tick_hmac_key[32];
+    unsigned char tlsext_tick_aes_key[32];
+    /* Callback to support customisation of ticket key setting */
+    int (*tlsext_ticket_key_cb) (SSL *ssl,
+                                 unsigned char *name, unsigned char *iv,
+                                 EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc);
+
+    /* certificate status request info */
+    /* Callback for status request */
+    int (*tlsext_status_cb) (SSL *ssl, void *arg);
+    void *tlsext_status_arg;
+
+# ifndef OPENSSL_NO_PSK
+    unsigned int (*psk_client_callback) (SSL *ssl, const char *hint,
+                                         char *identity,
+                                         unsigned int max_identity_len,
+                                         unsigned char *psk,
+                                         unsigned int max_psk_len);
+    unsigned int (*psk_server_callback) (SSL *ssl, const char *identity,
+                                         unsigned char *psk,
+                                         unsigned int max_psk_len);
+# endif
+
+# ifndef OPENSSL_NO_SRP
+    SRP_CTX srp_ctx;            /* ctx for SRP authentication */
+# endif
+
+# ifndef OPENSSL_NO_NEXTPROTONEG
+    /* Next protocol negotiation information */
+
+    /*
+     * For a server, this contains a callback function by which the set of
+     * advertised protocols can be provided.
+     */
+    int (*next_protos_advertised_cb) (SSL *s, const unsigned char **buf,
+                                      unsigned int *len, void *arg);
+    void *next_protos_advertised_cb_arg;
+    /*
+     * For a client, this contains a callback function that selects the next
+     * protocol from the list provided by the server.
+     */
+    int (*next_proto_select_cb) (SSL *s, unsigned char **out,
+                                 unsigned char *outlen,
+                                 const unsigned char *in,
+                                 unsigned int inlen, void *arg);
+    void *next_proto_select_cb_arg;
+# endif
+
+    /*
+     * ALPN information (we are in the process of transitioning from NPN to
+     * ALPN.)
+     */
+
+        /*-
+         * For a server, this contains a callback function that allows the
+         * server to select the protocol for the connection.
+         *   out: on successful return, this must point to the raw protocol
+         *        name (without the length prefix).
+         *   outlen: on successful return, this contains the length of |*out|.
+         *   in: points to the client's list of supported protocols in
+         *       wire-format.
+         *   inlen: the length of |in|.
+         */
+    int (*alpn_select_cb) (SSL *s,
+                           const unsigned char **out,
+                           unsigned char *outlen,
+                           const unsigned char *in,
+                           unsigned int inlen, void *arg);
+    void *alpn_select_cb_arg;
+
+    /*
+     * For a client, this contains the list of supported protocols in wire
+     * format.
+     */
+    unsigned char *alpn_client_proto_list;
+    unsigned alpn_client_proto_list_len;
+
+    /* Shared DANE context */
+    struct dane_ctx_st dane;
+
+    /* SRTP profiles we are willing to do from RFC 5764 */
+    STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
+    /*
+     * Callback for disabling session caching and ticket support on a session
+     * basis, depending on the chosen cipher.
+     */
+    int (*not_resumable_session_cb) (SSL *ssl, int is_forward_secure);
+# ifndef OPENSSL_NO_EC
+    /* EC extension values inherited by SSL structure */
+    size_t tlsext_ecpointformatlist_length;
+    unsigned char *tlsext_ecpointformatlist;
+    size_t tlsext_ellipticcurvelist_length;
+    unsigned char *tlsext_ellipticcurvelist;
+# endif                         /* OPENSSL_NO_EC */
+
+    /* ext status type used for CSR extension (OCSP Stapling) */
+    int tlsext_status_type;
+
+    CRYPTO_RWLOCK *lock;
+};
+
+struct ssl_st {
+    /*
+     * protocol version (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION,
+     * DTLS1_VERSION)
+     */
+    int version;
+    /* SSLv3 */
+    const SSL_METHOD *method;
+    /*
+     * There are 2 BIO's even though they are normally both the same.  This
+     * is so data can be read and written to different handlers
+     */
+    /* used by SSL_read */
+    BIO *rbio;
+    /* used by SSL_write */
+    BIO *wbio;
+    /* used during session-id reuse to concatenate messages */
+    BIO *bbio;
+    /*
+     * This holds a variable that indicates what we were doing when a 0 or -1
+     * is returned.  This is needed for non-blocking IO so we know what
+     * request needs re-doing when in SSL_accept or SSL_connect
+     */
+    int rwstate;
+    int (*handshake_func) (SSL *);
+    /*
+     * Imagine that here's a boolean member "init" that is switched as soon
+     * as SSL_set_{accept/connect}_state is called for the first time, so
+     * that "state" and "handshake_func" are properly initialized.  But as
+     * handshake_func is == 0 until then, we use this test instead of an
+     * "init" member.
+     */
+    /* are we the server side? */
+    int server;
+    /*
+     * Generate a new session or reuse an old one.
+     * NB: For servers, the 'new' session may actually be a previously
+     * cached session or even the previous session unless
+     * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set
+     */
+    int new_session;
+    /* don't send shutdown packets */
+    int quiet_shutdown;
+    /* we have shut things down, 0x01 sent, 0x02 for received */
+    int shutdown;
+    /* where we are */
+    OSSL_STATEM statem;
+    BUF_MEM *init_buf;          /* buffer used during init */
+    void *init_msg;             /* pointer to handshake message body, set by
+                                 * ssl3_get_message() */
+    int init_num;               /* amount read/written */
+    int init_off;               /* amount read/written */
+    struct ssl3_state_st *s3;   /* SSLv3 variables */
+    struct dtls1_state_st *d1;  /* DTLSv1 variables */
+    /* callback that allows applications to peek at protocol messages */
+    void (*msg_callback) (int write_p, int version, int content_type,
+                          const void *buf, size_t len, SSL *ssl, void *arg);
+    void *msg_callback_arg;
+    int hit;                    /* reusing a previous session */
+    X509_VERIFY_PARAM *param;
+    /* Per connection DANE state */
+    SSL_DANE dane;
+    /* crypto */
+    STACK_OF(SSL_CIPHER) *cipher_list;
+    STACK_OF(SSL_CIPHER) *cipher_list_by_id;
+    /*
+     * These are the ones being used, the ones in SSL_SESSION are the ones to
+     * be 'copied' into these ones
+     */
+    uint32_t mac_flags;
+    EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */
+    EVP_MD_CTX *read_hash;      /* used for mac generation */
+    COMP_CTX *compress;         /* compression */
+    COMP_CTX *expand;           /* uncompress */
+    EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */
+    EVP_MD_CTX *write_hash;     /* used for mac generation */
+    /* session info */
+    /* client cert? */
+    /* This is used to hold the server certificate used */
+    struct cert_st /* CERT */ *cert;
+    /*
+     * the session_id_context is used to ensure sessions are only reused in
+     * the appropriate context
+     */
+    unsigned int sid_ctx_length;
+    unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
+    /* This can also be in the session once a session is established */
+    SSL_SESSION *session;
+    /* Default generate session ID callback. */
+    GEN_SESSION_CB generate_session_id;
+    /* Used in SSL3 */
+    /*
+     * 0 don't care about verify failure.
+     * 1 fail if verify fails
+     */
+    uint32_t verify_mode;
+    /* fail if callback returns 0 */
+    int (*verify_callback) (int ok, X509_STORE_CTX *ctx);
+    /* optional informational callback */
+    void (*info_callback) (const SSL *ssl, int type, int val);
+    /* error bytes to be written */
+    int error;
+    /* actual code */
+    int error_code;
+# ifndef OPENSSL_NO_PSK
+    unsigned int (*psk_client_callback) (SSL *ssl, const char *hint,
+                                         char *identity,
+                                         unsigned int max_identity_len,
+                                         unsigned char *psk,
+                                         unsigned int max_psk_len);
+    unsigned int (*psk_server_callback) (SSL *ssl, const char *identity,
+                                         unsigned char *psk,
+                                         unsigned int max_psk_len);
+# endif
+    SSL_CTX *ctx;
+    /* Verified chain of peer */
+    STACK_OF(X509) *verified_chain;
+    long verify_result;
+    /* extra application data */
+    CRYPTO_EX_DATA ex_data;
+    /* for server side, keep the list of CA_dn we can use */
+    STACK_OF(X509_NAME) *client_CA;
+    int references;
+    /* protocol behaviour */
+    uint32_t options;
+    /* API behaviour */
+    uint32_t mode;
+    int min_proto_version;
+    int max_proto_version;
+    long max_cert_list;
+    int first_packet;
+    /* what was passed, used for SSLv3/TLS rollback check */
+    int client_version;
+    /*
+     * If we're using more than one pipeline how should we divide the data
+     * up between the pipes?
+     */
+    unsigned int split_send_fragment;
+    /*
+     * Maximum amount of data to send in one fragment. actual record size can
+     * be more than this due to padding and MAC overheads.
+     */
+    unsigned int max_send_fragment;
+    /* Up to how many pipelines should we use? If 0 then 1 is assumed */
+    unsigned int max_pipelines;
+    /* TLS extension debug callback */
+    void (*tlsext_debug_cb) (SSL *s, int client_server, int type,
+                             const unsigned char *data, int len, void *arg);
+    void *tlsext_debug_arg;
+    char *tlsext_hostname;
+    /*-
+     * no further mod of servername
+     * 0 : call the servername extension callback.
+     * 1 : prepare 2, allow last ack just after in server callback.
+     * 2 : don't call servername callback, no ack in server hello
+     */
+    int servername_done;
+    /* certificate status request info */
+    /* Status type or -1 if no status type */
+    int tlsext_status_type;
+# ifndef OPENSSL_NO_CT
+    /*
+     * Validates that the SCTs (Signed Certificate Timestamps) are sufficient.
+     * If they are not, the connection should be aborted.
+     */
+    ssl_ct_validation_cb ct_validation_callback;
+    /* User-supplied argument tha tis passed to the ct_validation_callback */
+    void *ct_validation_callback_arg;
+    /*
+     * Consolidated stack of SCTs from all sources.
+     * Lazily populated by CT_get_peer_scts(SSL*)
+     */
+    STACK_OF(SCT) *scts;
+    /* Raw extension data, if seen */
+    unsigned char *tlsext_scts;
+    /* Length of raw extension data, if seen */
+    uint16_t tlsext_scts_len;
+    /* Have we attempted to find/parse SCTs yet? */
+    int scts_parsed;
+# endif
+    /* Expect OCSP CertificateStatus message */
+    int tlsext_status_expected;
+    /* OCSP status request only */
+    STACK_OF(OCSP_RESPID) *tlsext_ocsp_ids;
+    X509_EXTENSIONS *tlsext_ocsp_exts;
+    /* OCSP response received or to be sent */
+    unsigned char *tlsext_ocsp_resp;
+    int tlsext_ocsp_resplen;
+    /* RFC4507 session ticket expected to be received or sent */
+    int tlsext_ticket_expected;
+# ifndef OPENSSL_NO_EC
+    size_t tlsext_ecpointformatlist_length;
+    /* our list */
+    unsigned char *tlsext_ecpointformatlist;
+    size_t tlsext_ellipticcurvelist_length;
+    /* our list */
+    unsigned char *tlsext_ellipticcurvelist;
+# endif                         /* OPENSSL_NO_EC */
+    /* TLS Session Ticket extension override */
+    TLS_SESSION_TICKET_EXT *tlsext_session_ticket;
+    /* TLS Session Ticket extension callback */
+    tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb;
+    void *tls_session_ticket_ext_cb_arg;
+    /* TLS pre-shared secret session resumption */
+    tls_session_secret_cb_fn tls_session_secret_cb;
+    void *tls_session_secret_cb_arg;
+    SSL_CTX *session_ctx;       /* initial ctx, used to store sessions */
+# ifndef OPENSSL_NO_NEXTPROTONEG
+    /*
+     * Next protocol negotiation. For the client, this is the protocol that
+     * we sent in NextProtocol and is set when handling ServerHello
+     * extensions. For a server, this is the client's selected_protocol from
+     * NextProtocol and is set when handling the NextProtocol message, before
+     * the Finished message.
+     */
+    unsigned char *next_proto_negotiated;
+    unsigned char next_proto_negotiated_len;
+# endif
+    /* What we'll do */
+    STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
+    /* What's been chosen */
+    SRTP_PROTECTION_PROFILE *srtp_profile;
+        /*-
+         * Is use of the Heartbeat extension negotiated?
+         *  0: disabled
+         *  1: enabled
+         *  2: enabled, but not allowed to send Requests
+         */
+    unsigned int tlsext_heartbeat;
+    /* Indicates if a HeartbeatRequest is in flight */
+    unsigned int tlsext_hb_pending;
+    /* HeartbeatRequest sequence number */
+    unsigned int tlsext_hb_seq;
+    /*
+     * For a client, this contains the list of supported protocols in wire
+     * format.
+     */
+    unsigned char *alpn_client_proto_list;
+    unsigned alpn_client_proto_list_len;
+
+    /* Set to one if we have negotiated ETM */
+    int tlsext_use_etm;
+
+    /*-
+     * 1 if we are renegotiating.
+     * 2 if we are a server and are inside a handshake
+     * (i.e. not just sending a HelloRequest)
+     */
+    int renegotiate;
+# ifndef OPENSSL_NO_SRP
+    /* ctx for SRP authentication */
+    SRP_CTX srp_ctx;
+# endif
+    /*
+     * Callback for disabling session caching and ticket support on a session
+     * basis, depending on the chosen cipher.
+     */
+    int (*not_resumable_session_cb) (SSL *ssl, int is_forward_secure);
+    RECORD_LAYER rlayer;
+    /* Default password callback. */
+    pem_password_cb *default_passwd_callback;
+    /* Default password callback user data. */
+    void *default_passwd_callback_userdata;
+    /* Async Job info */
+    ASYNC_JOB *job;
+    ASYNC_WAIT_CTX *waitctx;
+    CRYPTO_RWLOCK *lock;
+};
+
+typedef struct ssl3_state_st {
+    long flags;
+    int read_mac_secret_size;
+    unsigned char read_mac_secret[EVP_MAX_MD_SIZE];
+    int write_mac_secret_size;
+    unsigned char write_mac_secret[EVP_MAX_MD_SIZE];
+    unsigned char server_random[SSL3_RANDOM_SIZE];
+    unsigned char client_random[SSL3_RANDOM_SIZE];
+    /* flags for countermeasure against known-IV weakness */
+    int need_empty_fragments;
+    int empty_fragment_done;
+    /* used during startup, digest all incoming/outgoing packets */
+    BIO *handshake_buffer;
+    /*
+     * When handshake digest is determined, buffer is hashed and
+     * freed and MD_CTX for the required digest is stored here.
+     */
+    EVP_MD_CTX *handshake_dgst;
+    /*
+     * Set whenever an expected ChangeCipherSpec message is processed.
+     * Unset when the peer's Finished message is received.
+     * Unexpected ChangeCipherSpec messages trigger a fatal alert.
+     */
+    int change_cipher_spec;
+    int warn_alert;
+    int fatal_alert;
+    /*
+     * we allow one fatal and one warning alert to be outstanding, send close
+     * alert via the warning alert
+     */
+    int alert_dispatch;
+    unsigned char send_alert[2];
+    /*
+     * This flag is set when we should renegotiate ASAP, basically when there
+     * is no more data in the read or write buffers
+     */
+    int renegotiate;
+    int total_renegotiations;
+    int num_renegotiations;
+    int in_read_app_data;
+    struct {
+        /* actually only need to be 16+20 for SSLv3 and 12 for TLS */
+        unsigned char finish_md[EVP_MAX_MD_SIZE * 2];
+        int finish_md_len;
+        unsigned char peer_finish_md[EVP_MAX_MD_SIZE * 2];
+        int peer_finish_md_len;
+        unsigned long message_size;
+        int message_type;
+        /* used to hold the new cipher we are going to use */
+        const SSL_CIPHER *new_cipher;
+# if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
+        EVP_PKEY *pkey;         /* holds short lived DH/ECDH key */
+# endif
+        /* used for certificate requests */
+        int cert_req;
+        int ctype_num;
+        char ctype[SSL3_CT_NUMBER];
+        STACK_OF(X509_NAME) *ca_names;
+        int key_block_length;
+        unsigned char *key_block;
+        const EVP_CIPHER *new_sym_enc;
+        const EVP_MD *new_hash;
+        int new_mac_pkey_type;
+        int new_mac_secret_size;
+# ifndef OPENSSL_NO_COMP
+        const SSL_COMP *new_compression;
+# else
+        char *new_compression;
+# endif
+        int cert_request;
+        /* Raw values of the cipher list from a client */
+        unsigned char *ciphers_raw;
+        size_t ciphers_rawlen;
+        /* Temporary storage for premaster secret */
+        unsigned char *pms;
+        size_t pmslen;
+# ifndef OPENSSL_NO_PSK
+        /* Temporary storage for PSK key */
+        unsigned char *psk;
+        size_t psklen;
+# endif
+        /*
+         * signature algorithms peer reports: e.g. supported signature
+         * algorithms extension for server or as part of a certificate
+         * request for client.
+         */
+        unsigned char *peer_sigalgs;
+        /* Size of above array */
+        size_t peer_sigalgslen;
+        /* Digest peer uses for signing */
+        const EVP_MD *peer_md;
+        /* Array of digests used for signing */
+        const EVP_MD *md[SSL_PKEY_NUM];
+        /*
+         * Set if corresponding CERT_PKEY can be used with current
+         * SSL session: e.g. appropriate curve, signature algorithms etc.
+         * If zero it can't be used at all.
+         */
+        uint32_t valid_flags[SSL_PKEY_NUM];
+        /*
+         * For servers the following masks are for the key and auth algorithms
+         * that are supported by the certs below. For clients they are masks of
+         * *disabled* algorithms based on the current session.
+         */
+        uint32_t mask_k;
+        uint32_t mask_a;
+        /*
+         * The following are used by the client to see if a cipher is allowed or
+         * not.  It contains the minimum and maximum version the client's using
+         * based on what it knows so far.
+         */
+        int min_ver;
+        int max_ver;
+    } tmp;
+
+    /* Connection binding to prevent renegotiation attacks */
+    unsigned char previous_client_finished[EVP_MAX_MD_SIZE];
+    unsigned char previous_client_finished_len;
+    unsigned char previous_server_finished[EVP_MAX_MD_SIZE];
+    unsigned char previous_server_finished_len;
+    int send_connection_binding; /* TODOEKR */
+
+# ifndef OPENSSL_NO_NEXTPROTONEG
+    /*
+     * Set if we saw the Next Protocol Negotiation extension from our peer.
+     */
+    int next_proto_neg_seen;
+# endif
+
+    /*
+     * ALPN information (we are in the process of transitioning from NPN to
+     * ALPN.)
+     */
+
+    /*
+     * In a server these point to the selected ALPN protocol after the
+     * ClientHello has been processed. In a client these contain the protocol
+     * that the server selected once the ServerHello has been processed.
+     */
+    unsigned char *alpn_selected;
+    size_t alpn_selected_len;
+    /* used by the server to know what options were proposed */
+    unsigned char *alpn_proposed;
+    size_t alpn_proposed_len;
+    /* used by the client to know if it actually sent alpn */
+    int alpn_sent;
+
+# ifndef OPENSSL_NO_EC
+    /*
+     * This is set to true if we believe that this is a version of Safari
+     * running on OS X 10.6 or newer. We wish to know this because Safari on
+     * 10.8 .. 10.8.3 has broken ECDHE-ECDSA support.
+     */
+    char is_probably_safari;
+# endif                         /* !OPENSSL_NO_EC */
+
+    /* For clients: peer temporary key */
+# if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
+    EVP_PKEY *peer_tmp;
+# endif
+
+} SSL3_STATE;
+
+/* DTLS structures */
+
+# ifndef OPENSSL_NO_SCTP
+#  define DTLS1_SCTP_AUTH_LABEL   "EXPORTER_DTLS_OVER_SCTP"
+# endif
+
+/* Max MTU overhead we know about so far is 40 for IPv6 + 8 for UDP */
+# define DTLS1_MAX_MTU_OVERHEAD                   48
+
+/*
+ * Flag used in message reuse to indicate the buffer contains the record
+ * header as well as the the handshake message header.
+ */
+# define DTLS1_SKIP_RECORD_HEADER                 2
+
+struct dtls1_retransmit_state {
+    EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */
+    EVP_MD_CTX *write_hash;     /* used for mac generation */
+    COMP_CTX *compress;         /* compression */
+    SSL_SESSION *session;
+    unsigned short epoch;
+};
+
+struct hm_header_st {
+    unsigned char type;
+    unsigned long msg_len;
+    unsigned short seq;
+    unsigned long frag_off;
+    unsigned long frag_len;
+    unsigned int is_ccs;
+    struct dtls1_retransmit_state saved_retransmit_state;
+};
+
+struct dtls1_timeout_st {
+    /* Number of read timeouts so far */
+    unsigned int read_timeouts;
+    /* Number of write timeouts so far */
+    unsigned int write_timeouts;
+    /* Number of alerts received so far */
+    unsigned int num_alerts;
+};
+
+typedef struct hm_fragment_st {
+    struct hm_header_st msg_header;
+    unsigned char *fragment;
+    unsigned char *reassembly;
+} hm_fragment;
+
+typedef struct pqueue_st pqueue;
+typedef struct pitem_st pitem;
+
+struct pitem_st {
+    unsigned char priority[8];  /* 64-bit value in big-endian encoding */
+    void *data;
+    pitem *next;
+};
+
+typedef struct pitem_st *piterator;
+
+pitem *pitem_new(unsigned char *prio64be, void *data);
+void pitem_free(pitem *item);
+pqueue *pqueue_new(void);
+void pqueue_free(pqueue *pq);
+pitem *pqueue_insert(pqueue *pq, pitem *item);
+pitem *pqueue_peek(pqueue *pq);
+pitem *pqueue_pop(pqueue *pq);
+pitem *pqueue_find(pqueue *pq, unsigned char *prio64be);
+pitem *pqueue_iterator(pqueue *pq);
+pitem *pqueue_next(piterator *iter);
+int pqueue_size(pqueue *pq);
+
+typedef struct dtls1_state_st {
+    unsigned char cookie[DTLS1_COOKIE_LENGTH];
+    unsigned int cookie_len;
+    unsigned int cookie_verified;
+    /* handshake message numbers */
+    unsigned short handshake_write_seq;
+    unsigned short next_handshake_write_seq;
+    unsigned short handshake_read_seq;
+    /* Buffered handshake messages */
+    pqueue *buffered_messages;
+    /* Buffered (sent) handshake records */
+    pqueue *sent_messages;
+    unsigned int link_mtu;      /* max on-the-wire DTLS packet size */
+    unsigned int mtu;           /* max DTLS packet size */
+    struct hm_header_st w_msg_hdr;
+    struct hm_header_st r_msg_hdr;
+    struct dtls1_timeout_st timeout;
+    /*
+     * Indicates when the last handshake msg or heartbeat sent will timeout
+     */
+    struct timeval next_timeout;
+    /* Timeout duration */
+    unsigned short timeout_duration;
+    unsigned int retransmitting;
+# ifndef OPENSSL_NO_SCTP
+    int shutdown_received;
+# endif
+} DTLS1_STATE;
+
+# ifndef OPENSSL_NO_EC
+/*
+ * From ECC-TLS draft, used in encoding the curve type in ECParameters
+ */
+#  define EXPLICIT_PRIME_CURVE_TYPE  1
+#  define EXPLICIT_CHAR2_CURVE_TYPE  2
+#  define NAMED_CURVE_TYPE           3
+# endif                         /* OPENSSL_NO_EC */
+
+typedef struct cert_pkey_st {
+    X509 *x509;
+    EVP_PKEY *privatekey;
+    /* Chain for this certificate */
+    STACK_OF(X509) *chain;
+    /*-
+     * serverinfo data for this certificate.  The data is in TLS Extension
+     * wire format, specifically it's a series of records like:
+     *   uint16_t extension_type; // (RFC 5246, 7.4.1.4, Extension)
+     *   uint16_t length;
+     *   uint8_t data[length];
+     */
+    unsigned char *serverinfo;
+    size_t serverinfo_length;
+} CERT_PKEY;
+/* Retrieve Suite B flags */
+# define tls1_suiteb(s)  (s->cert->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS)
+/* Uses to check strict mode: suite B modes are always strict */
+# define SSL_CERT_FLAGS_CHECK_TLS_STRICT \
+        (SSL_CERT_FLAG_SUITEB_128_LOS|SSL_CERT_FLAG_TLS_STRICT)
+
+typedef struct {
+    unsigned short ext_type;
+    /*
+     * Per-connection flags relating to this extension type: not used if
+     * part of an SSL_CTX structure.
+     */
+    uint32_t ext_flags;
+    custom_ext_add_cb add_cb;
+    custom_ext_free_cb free_cb;
+    void *add_arg;
+    custom_ext_parse_cb parse_cb;
+    void *parse_arg;
+} custom_ext_method;
+
+/* ext_flags values */
+
+/*
+ * Indicates an extension has been received. Used to check for unsolicited or
+ * duplicate extensions.
+ */
+# define SSL_EXT_FLAG_RECEIVED   0x1
+/*
+ * Indicates an extension has been sent: used to enable sending of
+ * corresponding ServerHello extension.
+ */
+# define SSL_EXT_FLAG_SENT       0x2
+
+typedef struct {
+    custom_ext_method *meths;
+    size_t meths_count;
+} custom_ext_methods;
+
+typedef struct cert_st {
+    /* Current active set */
+    /*
+     * ALWAYS points to an element of the pkeys array
+     * Probably it would make more sense to store
+     * an index, not a pointer.
+     */
+    CERT_PKEY *key;
+# ifndef OPENSSL_NO_DH
+    EVP_PKEY *dh_tmp;
+    DH *(*dh_tmp_cb) (SSL *ssl, int is_export, int keysize);
+    int dh_tmp_auto;
+# endif
+    /* Flags related to certificates */
+    uint32_t cert_flags;
+    CERT_PKEY pkeys[SSL_PKEY_NUM];
+    /*
+     * Certificate types (received or sent) in certificate request message.
+     * On receive this is only set if number of certificate types exceeds
+     * SSL3_CT_NUMBER.
+     */
+    unsigned char *ctypes;
+    size_t ctype_num;
+    /*
+     * supported signature algorithms. When set on a client this is sent in
+     * the client hello as the supported signature algorithms extension. For
+     * servers it represents the signature algorithms we are willing to use.
+     */
+    unsigned char *conf_sigalgs;
+    /* Size of above array */
+    size_t conf_sigalgslen;
+    /*
+     * Client authentication signature algorithms, if not set then uses
+     * conf_sigalgs. On servers these will be the signature algorithms sent
+     * to the client in a cerificate request for TLS 1.2. On a client this
+     * represents the signature algortithms we are willing to use for client
+     * authentication.
+     */
+    unsigned char *client_sigalgs;
+    /* Size of above array */
+    size_t client_sigalgslen;
+    /*
+     * Signature algorithms shared by client and server: cached because these
+     * are used most often.
+     */
+    TLS_SIGALGS *shared_sigalgs;
+    size_t shared_sigalgslen;
+    /*
+     * Certificate setup callback: if set is called whenever a certificate
+     * may be required (client or server). the callback can then examine any
+     * appropriate parameters and setup any certificates required. This
+     * allows advanced applications to select certificates on the fly: for
+     * example based on supported signature algorithms or curves.
+     */
+    int (*cert_cb) (SSL *ssl, void *arg);
+    void *cert_cb_arg;
+    /*
+     * Optional X509_STORE for chain building or certificate validation If
+     * NULL the parent SSL_CTX store is used instead.
+     */
+    X509_STORE *chain_store;
+    X509_STORE *verify_store;
+    /* Custom extension methods for server and client */
+    custom_ext_methods cli_ext;
+    custom_ext_methods srv_ext;
+    /* Security callback */
+    int (*sec_cb) (const SSL *s, const SSL_CTX *ctx, int op, int bits, int nid,
+                   void *other, void *ex);
+    /* Security level */
+    int sec_level;
+    void *sec_ex;
+# ifndef OPENSSL_NO_PSK
+    /* If not NULL psk identity hint to use for servers */
+    char *psk_identity_hint;
+# endif
+    int references;             /* >1 only if SSL_copy_session_id is used */
+    CRYPTO_RWLOCK *lock;
+} CERT;
+
+/* Structure containing decoded values of signature algorithms extension */
+struct tls_sigalgs_st {
+    /* NID of hash algorithm */
+    int hash_nid;
+    /* NID of signature algorithm */
+    int sign_nid;
+    /* Combined hash and signature NID */
+    int signandhash_nid;
+    /* Raw values used in extension */
+    unsigned char rsign;
+    unsigned char rhash;
+};
+
+# define FP_ICC  (int (*)(const void *,const void *))
+
+/*
+ * This is for the SSLv3/TLSv1.0 differences in crypto/hash stuff It is a bit
+ * of a mess of functions, but hell, think of it as an opaque structure :-)
+ */
+typedef struct ssl3_enc_method {
+    int (*enc) (SSL *, SSL3_RECORD *, unsigned int, int);
+    int (*mac) (SSL *, SSL3_RECORD *, unsigned char *, int);
+    int (*setup_key_block) (SSL *);
+    int (*generate_master_secret) (SSL *, unsigned char *, unsigned char *,
+                                   int);
+    int (*change_cipher_state) (SSL *, int);
+    int (*final_finish_mac) (SSL *, const char *, int, unsigned char *);
+    int finish_mac_length;
+    const char *client_finished_label;
+    int client_finished_label_len;
+    const char *server_finished_label;
+    int server_finished_label_len;
+    int (*alert_value) (int);
+    int (*export_keying_material) (SSL *, unsigned char *, size_t,
+                                   const char *, size_t,
+                                   const unsigned char *, size_t,
+                                   int use_context);
+    /* Various flags indicating protocol version requirements */
+    uint32_t enc_flags;
+    /* Handshake header length */
+    unsigned int hhlen;
+    /* Set the handshake header */
+    int (*set_handshake_header) (SSL *s, int type, unsigned long len);
+    /* Write out handshake message */
+    int (*do_write) (SSL *s);
+} SSL3_ENC_METHOD;
+
+# define SSL_HM_HEADER_LENGTH(s) s->method->ssl3_enc->hhlen
+# define ssl_handshake_start(s) \
+        (((unsigned char *)s->init_buf->data) + s->method->ssl3_enc->hhlen)
+# define ssl_set_handshake_header(s, htype, len) \
+        s->method->ssl3_enc->set_handshake_header(s, htype, len)
+# define ssl_do_write(s)  s->method->ssl3_enc->do_write(s)
+
+/* Values for enc_flags */
+
+/* Uses explicit IV for CBC mode */
+# define SSL_ENC_FLAG_EXPLICIT_IV        0x1
+/* Uses signature algorithms extension */
+# define SSL_ENC_FLAG_SIGALGS            0x2
+/* Uses SHA256 default PRF */
+# define SSL_ENC_FLAG_SHA256_PRF         0x4
+/* Is DTLS */
+# define SSL_ENC_FLAG_DTLS               0x8
+/*
+ * Allow TLS 1.2 ciphersuites: applies to DTLS 1.2 as well as TLS 1.2: may
+ * apply to others in future.
+ */
+# define SSL_ENC_FLAG_TLS1_2_CIPHERS     0x10
+
+# ifndef OPENSSL_NO_COMP
+/* Used for holding the relevant compression methods loaded into SSL_CTX */
+typedef struct ssl3_comp_st {
+    int comp_id;                /* The identifier byte for this compression
+                                 * type */
+    char *name;                 /* Text name used for the compression type */
+    COMP_METHOD *method;        /* The method :-) */
+} SSL3_COMP;
+# endif
+
+extern SSL3_ENC_METHOD ssl3_undef_enc_method;
+
+__owur const SSL_METHOD *ssl_bad_method(int ver);
+__owur const SSL_METHOD *sslv3_method(void);
+__owur const SSL_METHOD *sslv3_server_method(void);
+__owur const SSL_METHOD *sslv3_client_method(void);
+__owur const SSL_METHOD *tlsv1_method(void);
+__owur const SSL_METHOD *tlsv1_server_method(void);
+__owur const SSL_METHOD *tlsv1_client_method(void);
+__owur const SSL_METHOD *tlsv1_1_method(void);
+__owur const SSL_METHOD *tlsv1_1_server_method(void);
+__owur const SSL_METHOD *tlsv1_1_client_method(void);
+__owur const SSL_METHOD *tlsv1_2_method(void);
+__owur const SSL_METHOD *tlsv1_2_server_method(void);
+__owur const SSL_METHOD *tlsv1_2_client_method(void);
+__owur const SSL_METHOD *dtlsv1_method(void);
+__owur const SSL_METHOD *dtlsv1_server_method(void);
+__owur const SSL_METHOD *dtlsv1_client_method(void);
+__owur const SSL_METHOD *dtls_bad_ver_client_method(void);
+__owur const SSL_METHOD *dtlsv1_2_method(void);
+__owur const SSL_METHOD *dtlsv1_2_server_method(void);
+__owur const SSL_METHOD *dtlsv1_2_client_method(void);
+
+extern const SSL3_ENC_METHOD TLSv1_enc_data;
+extern const SSL3_ENC_METHOD TLSv1_1_enc_data;
+extern const SSL3_ENC_METHOD TLSv1_2_enc_data;
+extern const SSL3_ENC_METHOD SSLv3_enc_data;
+extern const SSL3_ENC_METHOD DTLSv1_enc_data;
+extern const SSL3_ENC_METHOD DTLSv1_2_enc_data;
+
+/*
+ * Flags for SSL methods
+ */
+# define SSL_METHOD_NO_FIPS      (1U<<0)
+# define SSL_METHOD_NO_SUITEB    (1U<<1)
+
+# define IMPLEMENT_tls_meth_func(version, flags, mask, func_name, s_accept, \
+                                 s_connect, enc_data) \
+const SSL_METHOD *func_name(void)  \
+        { \
+        static const SSL_METHOD func_name##_data= { \
+                version, \
+                flags, \
+                mask, \
+                tls1_new, \
+                tls1_clear, \
+                tls1_free, \
+                s_accept, \
+                s_connect, \
+                ssl3_read, \
+                ssl3_peek, \
+                ssl3_write, \
+                ssl3_shutdown, \
+                ssl3_renegotiate, \
+                ssl3_renegotiate_check, \
+                ssl3_read_bytes, \
+                ssl3_write_bytes, \
+                ssl3_dispatch_alert, \
+                ssl3_ctrl, \
+                ssl3_ctx_ctrl, \
+                ssl3_get_cipher_by_char, \
+                ssl3_put_cipher_by_char, \
+                ssl3_pending, \
+                ssl3_num_ciphers, \
+                ssl3_get_cipher, \
+                tls1_default_timeout, \
+                &enc_data, \
+                ssl_undefined_void_function, \
+                ssl3_callback_ctrl, \
+                ssl3_ctx_callback_ctrl, \
+        }; \
+        return &func_name##_data; \
+        }
+
+# define IMPLEMENT_ssl3_meth_func(func_name, s_accept, s_connect) \
+const SSL_METHOD *func_name(void)  \
+        { \
+        static const SSL_METHOD func_name##_data= { \
+                SSL3_VERSION, \
+                SSL_METHOD_NO_FIPS | SSL_METHOD_NO_SUITEB, \
+                SSL_OP_NO_SSLv3, \
+                ssl3_new, \
+                ssl3_clear, \
+                ssl3_free, \
+                s_accept, \
+                s_connect, \
+                ssl3_read, \
+                ssl3_peek, \
+                ssl3_write, \
+                ssl3_shutdown, \
+                ssl3_renegotiate, \
+                ssl3_renegotiate_check, \
+                ssl3_read_bytes, \
+                ssl3_write_bytes, \
+                ssl3_dispatch_alert, \
+                ssl3_ctrl, \
+                ssl3_ctx_ctrl, \
+                ssl3_get_cipher_by_char, \
+                ssl3_put_cipher_by_char, \
+                ssl3_pending, \
+                ssl3_num_ciphers, \
+                ssl3_get_cipher, \
+                ssl3_default_timeout, \
+                &SSLv3_enc_data, \
+                ssl_undefined_void_function, \
+                ssl3_callback_ctrl, \
+                ssl3_ctx_callback_ctrl, \
+        }; \
+        return &func_name##_data; \
+        }
+
+# define IMPLEMENT_dtls1_meth_func(version, flags, mask, func_name, s_accept, \
+                                        s_connect, enc_data) \
+const SSL_METHOD *func_name(void)  \
+        { \
+        static const SSL_METHOD func_name##_data= { \
+                version, \
+                flags, \
+                mask, \
+                dtls1_new, \
+                dtls1_clear, \
+                dtls1_free, \
+                s_accept, \
+                s_connect, \
+                ssl3_read, \
+                ssl3_peek, \
+                ssl3_write, \
+                dtls1_shutdown, \
+                ssl3_renegotiate, \
+                ssl3_renegotiate_check, \
+                dtls1_read_bytes, \
+                dtls1_write_app_data_bytes, \
+                dtls1_dispatch_alert, \
+                dtls1_ctrl, \
+                ssl3_ctx_ctrl, \
+                ssl3_get_cipher_by_char, \
+                ssl3_put_cipher_by_char, \
+                ssl3_pending, \
+                ssl3_num_ciphers, \
+                ssl3_get_cipher, \
+                dtls1_default_timeout, \
+                &enc_data, \
+                ssl_undefined_void_function, \
+                ssl3_callback_ctrl, \
+                ssl3_ctx_callback_ctrl, \
+        }; \
+        return &func_name##_data; \
+        }
+
+struct openssl_ssl_test_functions {
+    int (*p_ssl_init_wbio_buffer) (SSL *s);
+    int (*p_ssl3_setup_buffers) (SSL *s);
+# ifndef OPENSSL_NO_HEARTBEATS
+    int (*p_dtls1_process_heartbeat) (SSL *s,
+                                      unsigned char *p, unsigned int length);
+# endif
+};
+
+const char *ssl_protocol_to_string(int version);
+
+# ifndef OPENSSL_UNIT_TEST
+
+void ssl_clear_cipher_ctx(SSL *s);
+int ssl_clear_bad_session(SSL *s);
+__owur CERT *ssl_cert_new(void);
+__owur CERT *ssl_cert_dup(CERT *cert);
+void ssl_cert_clear_certs(CERT *c);
+void ssl_cert_free(CERT *c);
+__owur int ssl_get_new_session(SSL *s, int session);
+__owur int ssl_get_prev_session(SSL *s, const PACKET *ext,
+                                const PACKET *session_id);
+__owur SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket);
+__owur int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b);
+DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id);
+__owur int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap,
+                                 const SSL_CIPHER *const *bp);
+__owur STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *meth,
+                                                    STACK_OF(SSL_CIPHER) **pref,
+                                                    STACK_OF(SSL_CIPHER)
+                                                    **sorted,
+                                                    const char *rule_str,
+                                                    CERT *c);
+void ssl_update_cache(SSL *s, int mode);
+__owur int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
+                              const EVP_MD **md, int *mac_pkey_type,
+                              int *mac_secret_size, SSL_COMP **comp,
+                              int use_etm);
+__owur int ssl_cipher_get_cert_index(const SSL_CIPHER *c);
+__owur const SSL_CIPHER *ssl_get_cipher_by_char(SSL *ssl,
+                                                const unsigned char *ptr);
+__owur int ssl_cert_set0_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain);
+__owur int ssl_cert_set1_chain(SSL *s, SSL_CTX *ctx, STACK_OF(X509) *chain);
+__owur int ssl_cert_add0_chain_cert(SSL *s, SSL_CTX *ctx, X509 *x);
+__owur int ssl_cert_add1_chain_cert(SSL *s, SSL_CTX *ctx, X509 *x);
+__owur int ssl_cert_select_current(CERT *c, X509 *x);
+__owur int ssl_cert_set_current(CERT *c, long arg);
+__owur X509 *ssl_cert_get0_next_certificate(CERT *c, int first);
+void ssl_cert_set_cert_cb(CERT *c, int (*cb) (SSL *ssl, void *arg), void *arg);
+
+__owur int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk);
+__owur int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l);
+__owur int ssl_build_cert_chain(SSL *s, SSL_CTX *ctx, int flags);
+__owur int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain,
+                                   int ref);
+
+__owur int ssl_security(const SSL *s, int op, int bits, int nid, void *other);
+__owur int ssl_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid,
+                            void *other);
+
+int ssl_undefined_function(SSL *s);
+__owur int ssl_undefined_void_function(void);
+__owur int ssl_undefined_const_function(const SSL *s);
+__owur CERT_PKEY *ssl_get_server_send_pkey(SSL *s);
+__owur int ssl_get_server_cert_serverinfo(SSL *s,
+                                          const unsigned char **serverinfo,
+                                          size_t *serverinfo_length);
+__owur EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *c,
+                                   const EVP_MD **pmd);
+__owur int ssl_cert_type(const X509 *x, const EVP_PKEY *pkey);
+void ssl_set_masks(SSL *s);
+__owur STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s);
+__owur int ssl_verify_alarm_type(long type);
+void ssl_sort_cipher_list(void);
+void ssl_load_ciphers(void);
+__owur int ssl_fill_hello_random(SSL *s, int server, unsigned char *field,
+                                 int len);
+__owur int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
+                                      int free_pms);
+__owur EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm);
+__owur int ssl_derive(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey);
+__owur EVP_PKEY *ssl_dh_to_pkey(DH *dh);
+
+__owur const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p);
+__owur int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p);
+int ssl3_init_finished_mac(SSL *s);
+__owur int ssl3_setup_key_block(SSL *s);
+__owur int ssl3_change_cipher_state(SSL *s, int which);
+void ssl3_cleanup_key_block(SSL *s);
+__owur int ssl3_do_write(SSL *s, int type);
+int ssl3_send_alert(SSL *s, int level, int desc);
+__owur int ssl3_generate_master_secret(SSL *s, unsigned char *out,
+                                       unsigned char *p, int len);
+__owur int ssl3_get_req_cert_type(SSL *s, unsigned char *p);
+__owur int ssl3_num_ciphers(void);
+__owur const SSL_CIPHER *ssl3_get_cipher(unsigned int u);
+int ssl3_renegotiate(SSL *ssl);
+int ssl3_renegotiate_check(SSL *ssl);
+__owur int ssl3_dispatch_alert(SSL *s);
+__owur int ssl3_final_finish_mac(SSL *s, const char *sender, int slen,
+                                 unsigned char *p);
+__owur int ssl3_finish_mac(SSL *s, const unsigned char *buf, int len);
+void ssl3_free_digest_list(SSL *s);
+__owur unsigned long ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk);
+__owur const SSL_CIPHER *ssl3_choose_cipher(SSL *ssl,
+                                            STACK_OF(SSL_CIPHER) *clnt,
+                                            STACK_OF(SSL_CIPHER) *srvr);
+__owur int ssl3_digest_cached_records(SSL *s, int keep);
+__owur int ssl3_new(SSL *s);
+void ssl3_free(SSL *s);
+__owur int ssl3_read(SSL *s, void *buf, int len);
+__owur int ssl3_peek(SSL *s, void *buf, int len);
+__owur int ssl3_write(SSL *s, const void *buf, int len);
+__owur int ssl3_shutdown(SSL *s);
+void ssl3_clear(SSL *s);
+__owur long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg);
+__owur long ssl3_ctx_ctrl(SSL_CTX *s, int cmd, long larg, void *parg);
+__owur long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void));
+__owur long ssl3_ctx_callback_ctrl(SSL_CTX *s, int cmd, void (*fp) (void));
+
+__owur int ssl3_do_change_cipher_spec(SSL *ssl);
+__owur long ssl3_default_timeout(void);
+
+__owur int ssl3_set_handshake_header(SSL *s, int htype, unsigned long len);
+__owur int ssl3_handshake_write(SSL *s);
+
+__owur int ssl_allow_compression(SSL *s);
+
+__owur int ssl_version_supported(const SSL *s, int version);
+
+__owur int ssl_set_client_hello_version(SSL *s);
+__owur int ssl_check_version_downgrade(SSL *s);
+__owur int ssl_set_version_bound(int method_version, int version, int *bound);
+__owur int ssl_choose_server_version(SSL *s);
+__owur int ssl_choose_client_version(SSL *s, int version);
+int ssl_get_client_min_max_version(const SSL *s, int *min_version,
+                                   int *max_version);
+
+__owur long tls1_default_timeout(void);
+__owur int dtls1_do_write(SSL *s, int type);
+void dtls1_set_message_header(SSL *s,
+                              unsigned char mt,
+                              unsigned long len,
+                              unsigned long frag_off, unsigned long frag_len);
+
+__owur int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf,
+                                      int len);
+
+__owur int dtls1_read_failed(SSL *s, int code);
+__owur int dtls1_buffer_message(SSL *s, int ccs);
+__owur int dtls1_retransmit_message(SSL *s, unsigned short seq, int *found);
+__owur int dtls1_get_queue_priority(unsigned short seq, int is_ccs);
+int dtls1_retransmit_buffered_messages(SSL *s);
+void dtls1_clear_received_buffer(SSL *s);
+void dtls1_clear_sent_buffer(SSL *s);
+void dtls1_get_message_header(unsigned char *data,
+                              struct hm_header_st *msg_hdr);
+__owur long dtls1_default_timeout(void);
+__owur struct timeval *dtls1_get_timeout(SSL *s, struct timeval *timeleft);
+__owur int dtls1_check_timeout_num(SSL *s);
+__owur int dtls1_handle_timeout(SSL *s);
+void dtls1_start_timer(SSL *s);
+void dtls1_stop_timer(SSL *s);
+__owur int dtls1_is_timer_expired(SSL *s);
+void dtls1_double_timeout(SSL *s);
+__owur unsigned int dtls_raw_hello_verify_request(unsigned char *buf,
+                                                  unsigned char *cookie,
+                                                  unsigned char cookie_len);
+__owur int dtls1_send_newsession_ticket(SSL *s);
+__owur unsigned int dtls1_min_mtu(SSL *s);
+void dtls1_hm_fragment_free(hm_fragment *frag);
+__owur int dtls1_query_mtu(SSL *s);
+
+__owur int tls1_new(SSL *s);
+void tls1_free(SSL *s);
+void tls1_clear(SSL *s);
+long tls1_ctrl(SSL *s, int cmd, long larg, void *parg);
+long tls1_callback_ctrl(SSL *s, int cmd, void (*fp) (void));
+
+__owur int dtls1_new(SSL *s);
+void dtls1_free(SSL *s);
+void dtls1_clear(SSL *s);
+long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg);
+__owur int dtls1_shutdown(SSL *s);
+
+__owur int dtls1_dispatch_alert(SSL *s);
+
+__owur int ssl_init_wbio_buffer(SSL *s);
+void ssl_free_wbio_buffer(SSL *s);
+
+__owur int tls1_change_cipher_state(SSL *s, int which);
+__owur int tls1_setup_key_block(SSL *s);
+__owur int tls1_final_finish_mac(SSL *s,
+                                 const char *str, int slen, unsigned char *p);
+__owur int tls1_generate_master_secret(SSL *s, unsigned char *out,
+                                       unsigned char *p, int len);
+__owur int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
+                                       const char *label, size_t llen,
+                                       const unsigned char *p, size_t plen,
+                                       int use_context);
+__owur int tls1_alert_code(int code);
+__owur int ssl3_alert_code(int code);
+__owur int ssl_ok(SSL *s);
+
+#  ifndef OPENSSL_NO_EC
+__owur int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s);
+#  endif
+
+SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n);
+
+#  ifndef OPENSSL_NO_EC
+/* Flags values from tls1_ec_curve_id2nid() */
+/* Mask for curve type */
+# define TLS_CURVE_TYPE          0x3
+# define TLS_CURVE_PRIME         0x0
+# define TLS_CURVE_CHAR2         0x1
+# define TLS_CURVE_CUSTOM        0x2
+__owur int tls1_ec_curve_id2nid(int curve_id, unsigned int *pflags);
+__owur int tls1_ec_nid2curve_id(int nid);
+__owur int tls1_check_curve(SSL *s, const unsigned char *p, size_t len);
+__owur int tls1_shared_curve(SSL *s, int nmatch);
+__owur int tls1_set_curves(unsigned char **pext, size_t *pextlen,
+                           int *curves, size_t ncurves);
+__owur int tls1_set_curves_list(unsigned char **pext, size_t *pextlen,
+                                const char *str);
+__owur int tls1_check_ec_tmp_key(SSL *s, unsigned long id);
+__owur EVP_PKEY *ssl_generate_pkey_curve(int id);
+#  endif                        /* OPENSSL_NO_EC */
+
+__owur int tls1_shared_list(SSL *s,
+                            const unsigned char *l1, size_t l1len,
+                            const unsigned char *l2, size_t l2len, int nmatch);
+__owur unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
+                                                 unsigned char *limit, int *al);
+__owur unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
+                                                 unsigned char *limit, int *al);
+__owur int ssl_parse_clienthello_tlsext(SSL *s, PACKET *pkt);
+void ssl_set_default_md(SSL *s);
+__owur int tls1_set_server_sigalgs(SSL *s);
+__owur int ssl_check_clienthello_tlsext_late(SSL *s, int *al);
+__owur int ssl_parse_serverhello_tlsext(SSL *s, PACKET *pkt);
+__owur int ssl_prepare_clienthello_tlsext(SSL *s);
+__owur int ssl_prepare_serverhello_tlsext(SSL *s);
+
+#  ifndef OPENSSL_NO_HEARTBEATS
+__owur int dtls1_heartbeat(SSL *s);
+__owur int dtls1_process_heartbeat(SSL *s, unsigned char *p,
+                                   unsigned int length);
+#  endif
+
+__owur int tls_check_serverhello_tlsext_early(SSL *s, const PACKET *ext,
+                                              const PACKET *session_id,
+                                              SSL_SESSION **ret);
+
+__owur int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk,
+                                const EVP_MD *md);
+__owur int tls12_get_sigid(const EVP_PKEY *pk);
+__owur const EVP_MD *tls12_get_hash(unsigned char hash_alg);
+void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op);
+
+__owur int tls1_set_sigalgs_list(CERT *c, const char *str, int client);
+__owur int tls1_set_sigalgs(CERT *c, const int *salg, size_t salglen,
+                            int client);
+int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
+                     int idx);
+void tls1_set_cert_validity(SSL *s);
+
+#  ifndef OPENSSL_NO_CT
+__owur int ssl_validate_ct(SSL *s);
+#  endif
+
+#  ifndef OPENSSL_NO_DH
+__owur DH *ssl_get_auto_dh(SSL *s);
+#  endif
+
+__owur int ssl_security_cert(SSL *s, SSL_CTX *ctx, X509 *x, int vfy, int is_ee);
+__owur int ssl_security_cert_chain(SSL *s, STACK_OF(X509) *sk, X509 *ex,
+                                   int vfy);
+
+__owur EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md);
+void ssl_clear_hash_ctx(EVP_MD_CTX **hash);
+__owur int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p,
+                                               int *len, int maxlen);
+__owur int ssl_parse_serverhello_renegotiate_ext(SSL *s, PACKET *pkt, int *al);
+__owur int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p,
+                                               int *len, int maxlen);
+__owur int ssl_parse_clienthello_renegotiate_ext(SSL *s, PACKET *pkt, int *al);
+__owur long ssl_get_algorithm2(SSL *s);
+__owur size_t tls12_copy_sigalgs(SSL *s, unsigned char *out,
+                                 const unsigned char *psig, size_t psiglen);
+__owur int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize);
+__owur int tls1_process_sigalgs(SSL *s);
+__owur size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs);
+__owur int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s,
+                                   const unsigned char *sig, EVP_PKEY *pkey);
+void ssl_set_client_disabled(SSL *s);
+__owur int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op);
+
+__owur int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len,
+                                            int maxlen);
+__owur int ssl_parse_clienthello_use_srtp_ext(SSL *s, PACKET *pkt, int *al);
+__owur int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len,
+                                            int maxlen);
+__owur int ssl_parse_serverhello_use_srtp_ext(SSL *s, PACKET *pkt, int *al);
+
+__owur int ssl_handshake_hash(SSL *s, unsigned char *out, int outlen);
+__owur const EVP_MD *ssl_md(int idx);
+__owur const EVP_MD *ssl_handshake_md(SSL *s);
+__owur const EVP_MD *ssl_prf_md(SSL *s);
+
+/* s3_cbc.c */
+__owur char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx);
+__owur int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
+                                  unsigned char *md_out,
+                                  size_t *md_out_size,
+                                  const unsigned char header[13],
+                                  const unsigned char *data,
+                                  size_t data_plus_mac_size,
+                                  size_t data_plus_mac_plus_padding_size,
+                                  const unsigned char *mac_secret,
+                                  unsigned mac_secret_length, char is_sslv3);
+
+__owur int tls_fips_digest_extra(const EVP_CIPHER_CTX *cipher_ctx,
+                                 EVP_MD_CTX *mac_ctx, const unsigned char *data,
+                                 size_t data_len, size_t orig_len);
+
+__owur int srp_generate_server_master_secret(SSL *s);
+__owur int srp_generate_client_master_secret(SSL *s);
+__owur int srp_verify_server_param(SSL *s, int *al);
+
+/* t1_ext.c */
+
+void custom_ext_init(custom_ext_methods *meths);
+
+__owur int custom_ext_parse(SSL *s, int server,
+                            unsigned int ext_type,
+                            const unsigned char *ext_data, size_t ext_size,
+                            int *al);
+__owur int custom_ext_add(SSL *s, int server, unsigned char **pret,
+                          unsigned char *limit, int *al);
+
+__owur int custom_exts_copy(custom_ext_methods *dst,
+                            const custom_ext_methods *src);
+void custom_exts_free(custom_ext_methods *exts);
+
+void ssl_comp_free_compression_methods_int(void);
+
+# else
+
+#  define ssl_init_wbio_buffer SSL_test_functions()->p_ssl_init_wbio_buffer
+#  define ssl3_setup_buffers SSL_test_functions()->p_ssl3_setup_buffers
+#  define dtls1_process_heartbeat SSL_test_functions()->p_dtls1_process_heartbeat
+
+# endif
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_mcnf.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_mcnf.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_mcnf.c	(revision 331)
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2015-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 <stdio.h>
+#include <openssl/conf.h>
+#include <openssl/ssl.h>
+#include "ssl_locl.h"
+
+/* SSL library configuration module. */
+
+struct ssl_conf_name {
+    /* Name of this set of commands */
+    char *name;
+    /* List of commands */
+    struct ssl_conf_cmd *cmds;
+    /* Number of commands */
+    size_t cmd_count;
+};
+
+struct ssl_conf_cmd {
+    /* Command */
+    char *cmd;
+    /* Argument */
+    char *arg;
+};
+
+static struct ssl_conf_name *ssl_names;
+static size_t ssl_names_count;
+
+static void ssl_module_free(CONF_IMODULE *md)
+{
+    size_t i, j;
+    if (ssl_names == NULL)
+        return;
+    for (i = 0; i < ssl_names_count; i++) {
+        struct ssl_conf_name *tname = ssl_names + i;
+        OPENSSL_free(tname->name);
+        for (j = 0; j < tname->cmd_count; j++) {
+            OPENSSL_free(tname->cmds[j].cmd);
+            OPENSSL_free(tname->cmds[j].arg);
+        }
+        OPENSSL_free(tname->cmds);
+    }
+    OPENSSL_free(ssl_names);
+    ssl_names = NULL;
+    ssl_names_count = 0;
+}
+
+static int ssl_module_init(CONF_IMODULE *md, const CONF *cnf)
+{
+    size_t i, j, cnt;
+    int rv = 0;
+    const char *ssl_conf_section;
+    STACK_OF(CONF_VALUE) *cmd_lists;
+    ssl_conf_section = CONF_imodule_get_value(md);
+    cmd_lists = NCONF_get_section(cnf, ssl_conf_section);
+    if (sk_CONF_VALUE_num(cmd_lists) <= 0) {
+        if (cmd_lists == NULL)
+            SSLerr(SSL_F_SSL_MODULE_INIT, SSL_R_SSL_SECTION_NOT_FOUND);
+        else
+            SSLerr(SSL_F_SSL_MODULE_INIT, SSL_R_SSL_SECTION_EMPTY);
+        ERR_add_error_data(2, "section=", ssl_conf_section);
+        goto err;
+    }
+    cnt = sk_CONF_VALUE_num(cmd_lists);
+    ssl_names = OPENSSL_zalloc(sizeof(*ssl_names) * cnt);
+    ssl_names_count = cnt;
+    for (i = 0; i < ssl_names_count; i++) {
+        struct ssl_conf_name *ssl_name = ssl_names + i;
+        CONF_VALUE *sect = sk_CONF_VALUE_value(cmd_lists, i);
+        STACK_OF(CONF_VALUE) *cmds = NCONF_get_section(cnf, sect->value);
+        if (sk_CONF_VALUE_num(cmds) <= 0) {
+            if (cmds == NULL)
+                SSLerr(SSL_F_SSL_MODULE_INIT,
+                       SSL_R_SSL_COMMAND_SECTION_NOT_FOUND);
+            else
+                SSLerr(SSL_F_SSL_MODULE_INIT, SSL_R_SSL_COMMAND_SECTION_EMPTY);
+            ERR_add_error_data(4, "name=", sect->name, ", value=", sect->value);
+            goto err;
+        }
+        ssl_name->name = BUF_strdup(sect->name);
+        if (ssl_name->name == NULL)
+            goto err;
+        cnt = sk_CONF_VALUE_num(cmds);
+        ssl_name->cmds = OPENSSL_zalloc(cnt * sizeof(struct ssl_conf_cmd));
+        if (ssl_name->cmds == NULL)
+            goto err;
+        ssl_name->cmd_count = cnt;
+        for (j = 0; j < cnt; j++) {
+            const char *name;
+            CONF_VALUE *cmd_conf = sk_CONF_VALUE_value(cmds, j);
+            struct ssl_conf_cmd *cmd = ssl_name->cmds + j;
+            /* Skip any initial dot in name */
+            name = strchr(cmd_conf->name, '.');
+            if (name != NULL)
+                name++;
+            else
+                name = cmd_conf->name;
+            cmd->cmd = BUF_strdup(name);
+            cmd->arg = BUF_strdup(cmd_conf->value);
+            if (cmd->cmd == NULL || cmd->arg == NULL)
+                goto err;
+        }
+
+    }
+    rv = 1;
+ err:
+    if (rv == 0)
+        ssl_module_free(md);
+    return rv;
+}
+
+void SSL_add_ssl_module(void)
+{
+    CONF_module_add("ssl_conf", ssl_module_init, ssl_module_free);
+}
+
+static const struct ssl_conf_name *ssl_name_find(const char *name)
+{
+    size_t i;
+    const struct ssl_conf_name *nm;
+    if (name == NULL)
+        return NULL;
+    for (i = 0, nm = ssl_names; i < ssl_names_count; i++, nm++) {
+        if (strcmp(nm->name, name) == 0)
+            return nm;
+    }
+    return NULL;
+}
+
+static int ssl_do_config(SSL *s, SSL_CTX *ctx, const char *name)
+{
+    SSL_CONF_CTX *cctx = NULL;
+    size_t i;
+    int rv = 0;
+    unsigned int flags;
+    const SSL_METHOD *meth;
+    const struct ssl_conf_name *nm;
+    struct ssl_conf_cmd *cmd;
+    if (s == NULL && ctx == NULL) {
+        SSLerr(SSL_F_SSL_DO_CONFIG, ERR_R_PASSED_NULL_PARAMETER);
+        goto err;
+    }
+    nm = ssl_name_find(name);
+    if (nm == NULL) {
+        SSLerr(SSL_F_SSL_DO_CONFIG, SSL_R_INVALID_CONFIGURATION_NAME);
+        ERR_add_error_data(2, "name=", name);
+        goto err;
+    }
+    cctx = SSL_CONF_CTX_new();
+    if (cctx == NULL)
+        goto err;
+    flags = SSL_CONF_FLAG_FILE;
+    flags |= SSL_CONF_FLAG_CERTIFICATE | SSL_CONF_FLAG_REQUIRE_PRIVATE;
+    if (s != NULL) {
+        meth = s->method;
+        SSL_CONF_CTX_set_ssl(cctx, s);
+    } else {
+        meth = ctx->method;
+        SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);
+    }
+    if (meth->ssl_accept != ssl_undefined_function)
+        flags |= SSL_CONF_FLAG_SERVER;
+    if (meth->ssl_connect != ssl_undefined_function)
+        flags |= SSL_CONF_FLAG_CLIENT;
+    SSL_CONF_CTX_set_flags(cctx, flags);
+    for (i = 0, cmd = nm->cmds; i < nm->cmd_count; i++, cmd++) {
+        rv = SSL_CONF_cmd(cctx, cmd->cmd, cmd->arg);
+        if (rv <= 0) {
+            if (rv == -2)
+                SSLerr(SSL_F_SSL_DO_CONFIG, SSL_R_UNKNOWN_COMMAND);
+            else
+                SSLerr(SSL_F_SSL_DO_CONFIG, SSL_R_BAD_VALUE);
+            ERR_add_error_data(6, "section=", name, ", cmd=", cmd->cmd,
+                               ", arg=", cmd->arg);
+            goto err;
+        }
+    }
+    rv = SSL_CONF_CTX_finish(cctx);
+ err:
+    SSL_CONF_CTX_free(cctx);
+    return rv <= 0 ? 0 : 1;
+}
+
+int SSL_config(SSL *s, const char *name)
+{
+    return ssl_do_config(s, NULL, name);
+}
+
+int SSL_CTX_config(SSL_CTX *ctx, const char *name)
+{
+    return ssl_do_config(NULL, ctx, name);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_rsa.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_rsa.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_rsa.c	(revision 331)
@@ -0,0 +1,966 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include "ssl_locl.h"
+#include <openssl/bio.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+
+static int ssl_set_cert(CERT *c, X509 *x509);
+static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
+int SSL_use_certificate(SSL *ssl, X509 *x)
+{
+    int rv;
+    if (x == NULL) {
+        SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER);
+        return (0);
+    }
+    rv = ssl_security_cert(ssl, NULL, x, 0, 1);
+    if (rv != 1) {
+        SSLerr(SSL_F_SSL_USE_CERTIFICATE, rv);
+        return 0;
+    }
+
+    return (ssl_set_cert(ssl->cert, x));
+}
+
+int SSL_use_certificate_file(SSL *ssl, const char *file, int type)
+{
+    int j;
+    BIO *in;
+    int ret = 0;
+    X509 *x = NULL;
+
+    in = BIO_new(BIO_s_file());
+    if (in == NULL) {
+        SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB);
+        goto end;
+    }
+
+    if (BIO_read_filename(in, file) <= 0) {
+        SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB);
+        goto end;
+    }
+    if (type == SSL_FILETYPE_ASN1) {
+        j = ERR_R_ASN1_LIB;
+        x = d2i_X509_bio(in, NULL);
+    } else if (type == SSL_FILETYPE_PEM) {
+        j = ERR_R_PEM_LIB;
+        x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback,
+                              ssl->ctx->default_passwd_callback_userdata);
+    } else {
+        SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE);
+        goto end;
+    }
+
+    if (x == NULL) {
+        SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, j);
+        goto end;
+    }
+
+    ret = SSL_use_certificate(ssl, x);
+ end:
+    X509_free(x);
+    BIO_free(in);
+    return (ret);
+}
+
+int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len)
+{
+    X509 *x;
+    int ret;
+
+    x = d2i_X509(NULL, &d, (long)len);
+    if (x == NULL) {
+        SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB);
+        return (0);
+    }
+
+    ret = SSL_use_certificate(ssl, x);
+    X509_free(x);
+    return (ret);
+}
+
+#ifndef OPENSSL_NO_RSA
+int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa)
+{
+    EVP_PKEY *pkey;
+    int ret;
+
+    if (rsa == NULL) {
+        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
+        return (0);
+    }
+    if ((pkey = EVP_PKEY_new()) == NULL) {
+        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB);
+        return (0);
+    }
+
+    RSA_up_ref(rsa);
+    if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) {
+        RSA_free(rsa);
+        EVP_PKEY_free(pkey);
+        return 0;
+    }
+
+    ret = ssl_set_pkey(ssl->cert, pkey);
+    EVP_PKEY_free(pkey);
+    return (ret);
+}
+#endif
+
+static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
+{
+    int i;
+    i = ssl_cert_type(NULL, pkey);
+    if (i < 0) {
+        SSLerr(SSL_F_SSL_SET_PKEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
+        return (0);
+    }
+
+    if (c->pkeys[i].x509 != NULL) {
+        EVP_PKEY *pktmp;
+        pktmp = X509_get0_pubkey(c->pkeys[i].x509);
+        if (pktmp == NULL) {
+            SSLerr(SSL_F_SSL_SET_PKEY, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+        /*
+         * The return code from EVP_PKEY_copy_parameters is deliberately
+         * ignored. Some EVP_PKEY types cannot do this.
+         */
+        EVP_PKEY_copy_parameters(pktmp, pkey);
+        ERR_clear_error();
+
+#ifndef OPENSSL_NO_RSA
+        /*
+         * Don't check the public/private key, this is mostly for smart
+         * cards.
+         */
+        if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA
+            && RSA_flags(EVP_PKEY_get0_RSA(pkey)) & RSA_METHOD_FLAG_NO_CHECK) ;
+        else
+#endif
+        if (!X509_check_private_key(c->pkeys[i].x509, pkey)) {
+            X509_free(c->pkeys[i].x509);
+            c->pkeys[i].x509 = NULL;
+            return 0;
+        }
+    }
+
+    EVP_PKEY_free(c->pkeys[i].privatekey);
+    EVP_PKEY_up_ref(pkey);
+    c->pkeys[i].privatekey = pkey;
+    c->key = &(c->pkeys[i]);
+    return (1);
+}
+
+#ifndef OPENSSL_NO_RSA
+int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type)
+{
+    int j, ret = 0;
+    BIO *in;
+    RSA *rsa = NULL;
+
+    in = BIO_new(BIO_s_file());
+    if (in == NULL) {
+        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB);
+        goto end;
+    }
+
+    if (BIO_read_filename(in, file) <= 0) {
+        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB);
+        goto end;
+    }
+    if (type == SSL_FILETYPE_ASN1) {
+        j = ERR_R_ASN1_LIB;
+        rsa = d2i_RSAPrivateKey_bio(in, NULL);
+    } else if (type == SSL_FILETYPE_PEM) {
+        j = ERR_R_PEM_LIB;
+        rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
+                                         ssl->ctx->default_passwd_callback,
+                                         ssl->
+                                         ctx->default_passwd_callback_userdata);
+    } else {
+        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE);
+        goto end;
+    }
+    if (rsa == NULL) {
+        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, j);
+        goto end;
+    }
+    ret = SSL_use_RSAPrivateKey(ssl, rsa);
+    RSA_free(rsa);
+ end:
+    BIO_free(in);
+    return (ret);
+}
+
+int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len)
+{
+    int ret;
+    const unsigned char *p;
+    RSA *rsa;
+
+    p = d;
+    if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) {
+        SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB);
+        return (0);
+    }
+
+    ret = SSL_use_RSAPrivateKey(ssl, rsa);
+    RSA_free(rsa);
+    return (ret);
+}
+#endif                          /* !OPENSSL_NO_RSA */
+
+int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
+{
+    int ret;
+
+    if (pkey == NULL) {
+        SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
+        return (0);
+    }
+    ret = ssl_set_pkey(ssl->cert, pkey);
+    return (ret);
+}
+
+int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type)
+{
+    int j, ret = 0;
+    BIO *in;
+    EVP_PKEY *pkey = NULL;
+
+    in = BIO_new(BIO_s_file());
+    if (in == NULL) {
+        SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB);
+        goto end;
+    }
+
+    if (BIO_read_filename(in, file) <= 0) {
+        SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB);
+        goto end;
+    }
+    if (type == SSL_FILETYPE_PEM) {
+        j = ERR_R_PEM_LIB;
+        pkey = PEM_read_bio_PrivateKey(in, NULL,
+                                       ssl->ctx->default_passwd_callback,
+                                       ssl->
+                                       ctx->default_passwd_callback_userdata);
+    } else if (type == SSL_FILETYPE_ASN1) {
+        j = ERR_R_ASN1_LIB;
+        pkey = d2i_PrivateKey_bio(in, NULL);
+    } else {
+        SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE);
+        goto end;
+    }
+    if (pkey == NULL) {
+        SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, j);
+        goto end;
+    }
+    ret = SSL_use_PrivateKey(ssl, pkey);
+    EVP_PKEY_free(pkey);
+ end:
+    BIO_free(in);
+    return (ret);
+}
+
+int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d,
+                            long len)
+{
+    int ret;
+    const unsigned char *p;
+    EVP_PKEY *pkey;
+
+    p = d;
+    if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) {
+        SSLerr(SSL_F_SSL_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB);
+        return (0);
+    }
+
+    ret = SSL_use_PrivateKey(ssl, pkey);
+    EVP_PKEY_free(pkey);
+    return (ret);
+}
+
+int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
+{
+    int rv;
+    if (x == NULL) {
+        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER);
+        return (0);
+    }
+    rv = ssl_security_cert(NULL, ctx, x, 0, 1);
+    if (rv != 1) {
+        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, rv);
+        return 0;
+    }
+    return (ssl_set_cert(ctx->cert, x));
+}
+
+static int ssl_set_cert(CERT *c, X509 *x)
+{
+    EVP_PKEY *pkey;
+    int i;
+
+    pkey = X509_get0_pubkey(x);
+    if (pkey == NULL) {
+        SSLerr(SSL_F_SSL_SET_CERT, SSL_R_X509_LIB);
+        return (0);
+    }
+
+    i = ssl_cert_type(x, pkey);
+    if (i < 0) {
+        SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
+        return 0;
+    }
+#ifndef OPENSSL_NO_EC
+    if (i == SSL_PKEY_ECC && !EC_KEY_can_sign(EVP_PKEY_get0_EC_KEY(pkey))) {
+        SSLerr(SSL_F_SSL_SET_CERT, SSL_R_ECC_CERT_NOT_FOR_SIGNING);
+        return 0;
+    }
+#endif
+    if (c->pkeys[i].privatekey != NULL) {
+        /*
+         * The return code from EVP_PKEY_copy_parameters is deliberately
+         * ignored. Some EVP_PKEY types cannot do this.
+         */
+        EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey);
+        ERR_clear_error();
+
+#ifndef OPENSSL_NO_RSA
+        /*
+         * Don't check the public/private key, this is mostly for smart
+         * cards.
+         */
+        if (EVP_PKEY_id(c->pkeys[i].privatekey) == EVP_PKEY_RSA
+            && RSA_flags(EVP_PKEY_get0_RSA(c->pkeys[i].privatekey)) &
+            RSA_METHOD_FLAG_NO_CHECK) ;
+        else
+#endif                          /* OPENSSL_NO_RSA */
+        if (!X509_check_private_key(x, c->pkeys[i].privatekey)) {
+            /*
+             * don't fail for a cert/key mismatch, just free current private
+             * key (when switching to a different cert & key, first this
+             * function should be used, then ssl_set_pkey
+             */
+            EVP_PKEY_free(c->pkeys[i].privatekey);
+            c->pkeys[i].privatekey = NULL;
+            /* clear error queue */
+            ERR_clear_error();
+        }
+    }
+
+    X509_free(c->pkeys[i].x509);
+    X509_up_ref(x);
+    c->pkeys[i].x509 = x;
+    c->key = &(c->pkeys[i]);
+
+    return 1;
+}
+
+int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
+{
+    int j;
+    BIO *in;
+    int ret = 0;
+    X509 *x = NULL;
+
+    in = BIO_new(BIO_s_file());
+    if (in == NULL) {
+        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB);
+        goto end;
+    }
+
+    if (BIO_read_filename(in, file) <= 0) {
+        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB);
+        goto end;
+    }
+    if (type == SSL_FILETYPE_ASN1) {
+        j = ERR_R_ASN1_LIB;
+        x = d2i_X509_bio(in, NULL);
+    } else if (type == SSL_FILETYPE_PEM) {
+        j = ERR_R_PEM_LIB;
+        x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
+                              ctx->default_passwd_callback_userdata);
+    } else {
+        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE);
+        goto end;
+    }
+
+    if (x == NULL) {
+        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, j);
+        goto end;
+    }
+
+    ret = SSL_CTX_use_certificate(ctx, x);
+ end:
+    X509_free(x);
+    BIO_free(in);
+    return (ret);
+}
+
+int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d)
+{
+    X509 *x;
+    int ret;
+
+    x = d2i_X509(NULL, &d, (long)len);
+    if (x == NULL) {
+        SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB);
+        return (0);
+    }
+
+    ret = SSL_CTX_use_certificate(ctx, x);
+    X509_free(x);
+    return (ret);
+}
+
+#ifndef OPENSSL_NO_RSA
+int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
+{
+    int ret;
+    EVP_PKEY *pkey;
+
+    if (rsa == NULL) {
+        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
+        return (0);
+    }
+    if ((pkey = EVP_PKEY_new()) == NULL) {
+        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB);
+        return (0);
+    }
+
+    RSA_up_ref(rsa);
+    if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) {
+        RSA_free(rsa);
+        EVP_PKEY_free(pkey);
+        return 0;
+    }
+
+    ret = ssl_set_pkey(ctx->cert, pkey);
+    EVP_PKEY_free(pkey);
+    return (ret);
+}
+
+int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type)
+{
+    int j, ret = 0;
+    BIO *in;
+    RSA *rsa = NULL;
+
+    in = BIO_new(BIO_s_file());
+    if (in == NULL) {
+        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB);
+        goto end;
+    }
+
+    if (BIO_read_filename(in, file) <= 0) {
+        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB);
+        goto end;
+    }
+    if (type == SSL_FILETYPE_ASN1) {
+        j = ERR_R_ASN1_LIB;
+        rsa = d2i_RSAPrivateKey_bio(in, NULL);
+    } else if (type == SSL_FILETYPE_PEM) {
+        j = ERR_R_PEM_LIB;
+        rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
+                                         ctx->default_passwd_callback,
+                                         ctx->default_passwd_callback_userdata);
+    } else {
+        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE);
+        goto end;
+    }
+    if (rsa == NULL) {
+        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, j);
+        goto end;
+    }
+    ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
+    RSA_free(rsa);
+ end:
+    BIO_free(in);
+    return (ret);
+}
+
+int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d,
+                                   long len)
+{
+    int ret;
+    const unsigned char *p;
+    RSA *rsa;
+
+    p = d;
+    if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) {
+        SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB);
+        return (0);
+    }
+
+    ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
+    RSA_free(rsa);
+    return (ret);
+}
+#endif                          /* !OPENSSL_NO_RSA */
+
+int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
+{
+    if (pkey == NULL) {
+        SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER);
+        return (0);
+    }
+    return (ssl_set_pkey(ctx->cert, pkey));
+}
+
+int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
+{
+    int j, ret = 0;
+    BIO *in;
+    EVP_PKEY *pkey = NULL;
+
+    in = BIO_new(BIO_s_file());
+    if (in == NULL) {
+        SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB);
+        goto end;
+    }
+
+    if (BIO_read_filename(in, file) <= 0) {
+        SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB);
+        goto end;
+    }
+    if (type == SSL_FILETYPE_PEM) {
+        j = ERR_R_PEM_LIB;
+        pkey = PEM_read_bio_PrivateKey(in, NULL,
+                                       ctx->default_passwd_callback,
+                                       ctx->default_passwd_callback_userdata);
+    } else if (type == SSL_FILETYPE_ASN1) {
+        j = ERR_R_ASN1_LIB;
+        pkey = d2i_PrivateKey_bio(in, NULL);
+    } else {
+        SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE);
+        goto end;
+    }
+    if (pkey == NULL) {
+        SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, j);
+        goto end;
+    }
+    ret = SSL_CTX_use_PrivateKey(ctx, pkey);
+    EVP_PKEY_free(pkey);
+ end:
+    BIO_free(in);
+    return (ret);
+}
+
+int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx,
+                                const unsigned char *d, long len)
+{
+    int ret;
+    const unsigned char *p;
+    EVP_PKEY *pkey;
+
+    p = d;
+    if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) {
+        SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB);
+        return (0);
+    }
+
+    ret = SSL_CTX_use_PrivateKey(ctx, pkey);
+    EVP_PKEY_free(pkey);
+    return (ret);
+}
+
+/*
+ * Read a file that contains our certificate in "PEM" format, possibly
+ * followed by a sequence of CA certificates that should be sent to the peer
+ * in the Certificate message.
+ */
+static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file)
+{
+    BIO *in;
+    int ret = 0;
+    X509 *x = NULL;
+    pem_password_cb *passwd_callback;
+    void *passwd_callback_userdata;
+
+    ERR_clear_error();          /* clear error stack for
+                                 * SSL_CTX_use_certificate() */
+
+    if (ctx != NULL) {
+        passwd_callback = ctx->default_passwd_callback;
+        passwd_callback_userdata = ctx->default_passwd_callback_userdata;
+    } else {
+        passwd_callback = ssl->default_passwd_callback;
+        passwd_callback_userdata = ssl->default_passwd_callback_userdata;
+    }
+
+    in = BIO_new(BIO_s_file());
+    if (in == NULL) {
+        SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB);
+        goto end;
+    }
+
+    if (BIO_read_filename(in, file) <= 0) {
+        SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_SYS_LIB);
+        goto end;
+    }
+
+    x = PEM_read_bio_X509_AUX(in, NULL, passwd_callback,
+                              passwd_callback_userdata);
+    if (x == NULL) {
+        SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
+        goto end;
+    }
+
+    if (ctx)
+        ret = SSL_CTX_use_certificate(ctx, x);
+    else
+        ret = SSL_use_certificate(ssl, x);
+
+    if (ERR_peek_error() != 0)
+        ret = 0;                /* Key/certificate mismatch doesn't imply
+                                 * ret==0 ... */
+    if (ret) {
+        /*
+         * If we could set up our certificate, now proceed to the CA
+         * certificates.
+         */
+        X509 *ca;
+        int r;
+        unsigned long err;
+
+        if (ctx)
+            r = SSL_CTX_clear_chain_certs(ctx);
+        else
+            r = SSL_clear_chain_certs(ssl);
+
+        if (r == 0) {
+            ret = 0;
+            goto end;
+        }
+
+        while ((ca = PEM_read_bio_X509(in, NULL, passwd_callback,
+                                       passwd_callback_userdata))
+               != NULL) {
+            if (ctx)
+                r = SSL_CTX_add0_chain_cert(ctx, ca);
+            else
+                r = SSL_add0_chain_cert(ssl, ca);
+            /*
+             * Note that we must not free ca if it was successfully added to
+             * the chain (while we must free the main certificate, since its
+             * reference count is increased by SSL_CTX_use_certificate).
+             */
+            if (!r) {
+                X509_free(ca);
+                ret = 0;
+                goto end;
+            }
+        }
+        /* When the while loop ends, it's usually just EOF. */
+        err = ERR_peek_last_error();
+        if (ERR_GET_LIB(err) == ERR_LIB_PEM
+            && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)
+            ERR_clear_error();
+        else
+            ret = 0;            /* some real error */
+    }
+
+ end:
+    X509_free(x);
+    BIO_free(in);
+    return (ret);
+}
+
+int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
+{
+    return use_certificate_chain_file(ctx, NULL, file);
+}
+
+int SSL_use_certificate_chain_file(SSL *ssl, const char *file)
+{
+    return use_certificate_chain_file(NULL, ssl, file);
+}
+
+static int serverinfo_find_extension(const unsigned char *serverinfo,
+                                     size_t serverinfo_length,
+                                     unsigned int extension_type,
+                                     const unsigned char **extension_data,
+                                     size_t *extension_length)
+{
+    *extension_data = NULL;
+    *extension_length = 0;
+    if (serverinfo == NULL || serverinfo_length == 0)
+        return -1;
+    for (;;) {
+        unsigned int type = 0;
+        size_t len = 0;
+
+        /* end of serverinfo */
+        if (serverinfo_length == 0)
+            return 0;           /* Extension not found */
+
+        /* read 2-byte type field */
+        if (serverinfo_length < 2)
+            return -1;          /* Error */
+        type = (serverinfo[0] << 8) + serverinfo[1];
+        serverinfo += 2;
+        serverinfo_length -= 2;
+
+        /* read 2-byte len field */
+        if (serverinfo_length < 2)
+            return -1;          /* Error */
+        len = (serverinfo[0] << 8) + serverinfo[1];
+        serverinfo += 2;
+        serverinfo_length -= 2;
+
+        if (len > serverinfo_length)
+            return -1;          /* Error */
+
+        if (type == extension_type) {
+            *extension_data = serverinfo;
+            *extension_length = len;
+            return 1;           /* Success */
+        }
+
+        serverinfo += len;
+        serverinfo_length -= len;
+    }
+    /* Unreachable */
+}
+
+static int serverinfo_srv_parse_cb(SSL *s, unsigned int ext_type,
+                                   const unsigned char *in,
+                                   size_t inlen, int *al, void *arg)
+{
+
+    if (inlen != 0) {
+        *al = SSL_AD_DECODE_ERROR;
+        return 0;
+    }
+
+    return 1;
+}
+
+static int serverinfo_srv_add_cb(SSL *s, unsigned int ext_type,
+                                 const unsigned char **out, size_t *outlen,
+                                 int *al, void *arg)
+{
+    const unsigned char *serverinfo = NULL;
+    size_t serverinfo_length = 0;
+
+    /* Is there serverinfo data for the chosen server cert? */
+    if ((ssl_get_server_cert_serverinfo(s, &serverinfo,
+                                        &serverinfo_length)) != 0) {
+        /* Find the relevant extension from the serverinfo */
+        int retval = serverinfo_find_extension(serverinfo, serverinfo_length,
+                                               ext_type, out, outlen);
+        if (retval == -1) {
+            *al = SSL_AD_DECODE_ERROR;
+            return -1;          /* Error */
+        }
+        if (retval == 0)
+            return 0;           /* No extension found, don't send extension */
+        return 1;               /* Send extension */
+    }
+    return 0;                   /* No serverinfo data found, don't send
+                                 * extension */
+}
+
+/*
+ * With a NULL context, this function just checks that the serverinfo data
+ * parses correctly.  With a non-NULL context, it registers callbacks for
+ * the included extensions.
+ */
+static int serverinfo_process_buffer(const unsigned char *serverinfo,
+                                     size_t serverinfo_length, SSL_CTX *ctx)
+{
+    if (serverinfo == NULL || serverinfo_length == 0)
+        return 0;
+    for (;;) {
+        unsigned int ext_type = 0;
+        size_t len = 0;
+
+        /* end of serverinfo */
+        if (serverinfo_length == 0)
+            return 1;
+
+        /* read 2-byte type field */
+        if (serverinfo_length < 2)
+            return 0;
+        /* FIXME: check for types we understand explicitly? */
+
+        /* Register callbacks for extensions */
+        ext_type = (serverinfo[0] << 8) + serverinfo[1];
+        if (ctx) {
+            int have_ext_cbs = 0;
+            size_t i;
+            custom_ext_methods *exts = &ctx->cert->srv_ext;
+            custom_ext_method *meth = exts->meths;
+
+            for (i = 0; i < exts->meths_count; i++, meth++) {
+                if (ext_type == meth->ext_type) {
+                    have_ext_cbs = 1;
+                    break;
+                }
+            }
+
+            if (!have_ext_cbs && !SSL_CTX_add_server_custom_ext(ctx, ext_type,
+                                                                serverinfo_srv_add_cb,
+                                                                NULL, NULL,
+                                                                serverinfo_srv_parse_cb,
+                                                                NULL))
+                return 0;
+        }
+
+        serverinfo += 2;
+        serverinfo_length -= 2;
+
+        /* read 2-byte len field */
+        if (serverinfo_length < 2)
+            return 0;
+        len = (serverinfo[0] << 8) + serverinfo[1];
+        serverinfo += 2;
+        serverinfo_length -= 2;
+
+        if (len > serverinfo_length)
+            return 0;
+
+        serverinfo += len;
+        serverinfo_length -= len;
+    }
+}
+
+int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
+                           size_t serverinfo_length)
+{
+    unsigned char *new_serverinfo;
+
+    if (ctx == NULL || serverinfo == NULL || serverinfo_length == 0) {
+        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    if (!serverinfo_process_buffer(serverinfo, serverinfo_length, NULL)) {
+        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, SSL_R_INVALID_SERVERINFO_DATA);
+        return 0;
+    }
+    if (ctx->cert->key == NULL) {
+        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+    new_serverinfo = OPENSSL_realloc(ctx->cert->key->serverinfo,
+                                     serverinfo_length);
+    if (new_serverinfo == NULL) {
+        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    ctx->cert->key->serverinfo = new_serverinfo;
+    memcpy(ctx->cert->key->serverinfo, serverinfo, serverinfo_length);
+    ctx->cert->key->serverinfo_length = serverinfo_length;
+
+    /*
+     * Now that the serverinfo is validated and stored, go ahead and
+     * register callbacks.
+     */
+    if (!serverinfo_process_buffer(serverinfo, serverinfo_length, ctx)) {
+        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, SSL_R_INVALID_SERVERINFO_DATA);
+        return 0;
+    }
+    return 1;
+}
+
+int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file)
+{
+    unsigned char *serverinfo = NULL;
+    unsigned char *tmp;
+    size_t serverinfo_length = 0;
+    unsigned char *extension = 0;
+    long extension_length = 0;
+    char *name = NULL;
+    char *header = NULL;
+    char namePrefix[] = "SERVERINFO FOR ";
+    int ret = 0;
+    BIO *bin = NULL;
+    size_t num_extensions = 0;
+
+    if (ctx == NULL || file == NULL) {
+        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_PASSED_NULL_PARAMETER);
+        goto end;
+    }
+
+    bin = BIO_new(BIO_s_file());
+    if (bin == NULL) {
+        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_BUF_LIB);
+        goto end;
+    }
+    if (BIO_read_filename(bin, file) <= 0) {
+        SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_SYS_LIB);
+        goto end;
+    }
+
+    for (num_extensions = 0;; num_extensions++) {
+        if (PEM_read_bio(bin, &name, &header, &extension, &extension_length)
+            == 0) {
+            /*
+             * There must be at least one extension in this file
+             */
+            if (num_extensions == 0) {
+                SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE,
+                       SSL_R_NO_PEM_EXTENSIONS);
+                goto end;
+            } else              /* End of file, we're done */
+                break;
+        }
+        /* Check that PEM name starts with "BEGIN SERVERINFO FOR " */
+        if (strlen(name) < strlen(namePrefix)) {
+            SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_PEM_NAME_TOO_SHORT);
+            goto end;
+        }
+        if (strncmp(name, namePrefix, strlen(namePrefix)) != 0) {
+            SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE,
+                   SSL_R_PEM_NAME_BAD_PREFIX);
+            goto end;
+        }
+        /*
+         * Check that the decoded PEM data is plausible (valid length field)
+         */
+        if (extension_length < 4
+            || (extension[2] << 8) + extension[3] != extension_length - 4) {
+            SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_BAD_DATA);
+            goto end;
+        }
+        /* Append the decoded extension to the serverinfo buffer */
+        tmp = OPENSSL_realloc(serverinfo, serverinfo_length + extension_length);
+        if (tmp == NULL) {
+            SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_MALLOC_FAILURE);
+            goto end;
+        }
+        serverinfo = tmp;
+        memcpy(serverinfo + serverinfo_length, extension, extension_length);
+        serverinfo_length += extension_length;
+
+        OPENSSL_free(name);
+        name = NULL;
+        OPENSSL_free(header);
+        header = NULL;
+        OPENSSL_free(extension);
+        extension = NULL;
+    }
+
+    ret = SSL_CTX_use_serverinfo(ctx, serverinfo, serverinfo_length);
+ end:
+    /* SSL_CTX_use_serverinfo makes a local copy of the serverinfo. */
+    OPENSSL_free(name);
+    OPENSSL_free(header);
+    OPENSSL_free(extension);
+    OPENSSL_free(serverinfo);
+    BIO_free(bin);
+    return ret;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_sess.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_sess.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_sess.c	(revision 331)
@@ -0,0 +1,1169 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <stdio.h>
+#include <openssl/lhash.h>
+#include <openssl/rand.h>
+#include <openssl/engine.h>
+#include "ssl_locl.h"
+
+static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
+static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s);
+static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
+
+SSL_SESSION *SSL_get_session(const SSL *ssl)
+/* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */
+{
+    return (ssl->session);
+}
+
+SSL_SESSION *SSL_get1_session(SSL *ssl)
+/* variant of SSL_get_session: caller really gets something */
+{
+    SSL_SESSION *sess;
+    /*
+     * Need to lock this all up rather than just use CRYPTO_add so that
+     * somebody doesn't free ssl->session between when we check it's non-null
+     * and when we up the reference count.
+     */
+    CRYPTO_THREAD_read_lock(ssl->lock);
+    sess = ssl->session;
+    if (sess)
+        SSL_SESSION_up_ref(sess);
+    CRYPTO_THREAD_unlock(ssl->lock);
+    return sess;
+}
+
+int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg)
+{
+    return (CRYPTO_set_ex_data(&s->ex_data, idx, arg));
+}
+
+void *SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx)
+{
+    return (CRYPTO_get_ex_data(&s->ex_data, idx));
+}
+
+SSL_SESSION *SSL_SESSION_new(void)
+{
+    SSL_SESSION *ss;
+
+    ss = OPENSSL_zalloc(sizeof(*ss));
+    if (ss == NULL) {
+        SSLerr(SSL_F_SSL_SESSION_NEW, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    ss->verify_result = 1;      /* avoid 0 (= X509_V_OK) just in case */
+    ss->references = 1;
+    ss->timeout = 60 * 5 + 4;   /* 5 minute timeout by default */
+    ss->time = (unsigned long)time(NULL);
+    ss->lock = CRYPTO_THREAD_lock_new();
+    if (ss->lock == NULL) {
+        SSLerr(SSL_F_SSL_SESSION_NEW, ERR_R_MALLOC_FAILURE);
+        OPENSSL_free(ss);
+        return NULL;
+    }
+
+    if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data)) {
+        CRYPTO_THREAD_lock_free(ss->lock);
+        OPENSSL_free(ss);
+        return NULL;
+    }
+    return ss;
+}
+
+/*
+ * Create a new SSL_SESSION and duplicate the contents of |src| into it. If
+ * ticket == 0 then no ticket information is duplicated, otherwise it is.
+ */
+SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
+{
+    SSL_SESSION *dest;
+
+    dest = OPENSSL_malloc(sizeof(*src));
+    if (dest == NULL) {
+        goto err;
+    }
+    memcpy(dest, src, sizeof(*dest));
+
+    /*
+     * Set the various pointers to NULL so that we can call SSL_SESSION_free in
+     * the case of an error whilst halfway through constructing dest
+     */
+#ifndef OPENSSL_NO_PSK
+    dest->psk_identity_hint = NULL;
+    dest->psk_identity = NULL;
+#endif
+    dest->ciphers = NULL;
+    dest->tlsext_hostname = NULL;
+#ifndef OPENSSL_NO_EC
+    dest->tlsext_ecpointformatlist = NULL;
+    dest->tlsext_ellipticcurvelist = NULL;
+#endif
+    dest->tlsext_tick = NULL;
+#ifndef OPENSSL_NO_SRP
+    dest->srp_username = NULL;
+#endif
+    memset(&dest->ex_data, 0, sizeof(dest->ex_data));
+
+    /* We deliberately don't copy the prev and next pointers */
+    dest->prev = NULL;
+    dest->next = NULL;
+
+    dest->references = 1;
+
+    dest->lock = CRYPTO_THREAD_lock_new();
+    if (dest->lock == NULL)
+        goto err;
+
+    if (src->peer != NULL)
+        X509_up_ref(src->peer);
+
+    if (src->peer_chain != NULL) {
+        dest->peer_chain = X509_chain_up_ref(src->peer_chain);
+        if (dest->peer_chain == NULL)
+            goto err;
+    }
+#ifndef OPENSSL_NO_PSK
+    if (src->psk_identity_hint) {
+        dest->psk_identity_hint = OPENSSL_strdup(src->psk_identity_hint);
+        if (dest->psk_identity_hint == NULL) {
+            goto err;
+        }
+    }
+    if (src->psk_identity) {
+        dest->psk_identity = OPENSSL_strdup(src->psk_identity);
+        if (dest->psk_identity == NULL) {
+            goto err;
+        }
+    }
+#endif
+
+    if (src->ciphers != NULL) {
+        dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers);
+        if (dest->ciphers == NULL)
+            goto err;
+    }
+
+    if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION,
+                            &dest->ex_data, &src->ex_data)) {
+        goto err;
+    }
+
+    if (src->tlsext_hostname) {
+        dest->tlsext_hostname = OPENSSL_strdup(src->tlsext_hostname);
+        if (dest->tlsext_hostname == NULL) {
+            goto err;
+        }
+    }
+#ifndef OPENSSL_NO_EC
+    if (src->tlsext_ecpointformatlist) {
+        dest->tlsext_ecpointformatlist =
+            OPENSSL_memdup(src->tlsext_ecpointformatlist,
+                           src->tlsext_ecpointformatlist_length);
+        if (dest->tlsext_ecpointformatlist == NULL)
+            goto err;
+    }
+    if (src->tlsext_ellipticcurvelist) {
+        dest->tlsext_ellipticcurvelist =
+            OPENSSL_memdup(src->tlsext_ellipticcurvelist,
+                           src->tlsext_ellipticcurvelist_length);
+        if (dest->tlsext_ellipticcurvelist == NULL)
+            goto err;
+    }
+#endif
+
+    if (ticket != 0) {
+        dest->tlsext_tick =
+            OPENSSL_memdup(src->tlsext_tick, src->tlsext_ticklen);
+        if (dest->tlsext_tick == NULL)
+            goto err;
+    } else {
+        dest->tlsext_tick_lifetime_hint = 0;
+        dest->tlsext_ticklen = 0;
+    }
+
+#ifndef OPENSSL_NO_SRP
+    if (src->srp_username) {
+        dest->srp_username = OPENSSL_strdup(src->srp_username);
+        if (dest->srp_username == NULL) {
+            goto err;
+        }
+    }
+#endif
+
+    return dest;
+ err:
+    SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE);
+    SSL_SESSION_free(dest);
+    return NULL;
+}
+
+const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
+{
+    if (len)
+        *len = s->session_id_length;
+    return s->session_id;
+}
+const unsigned char *SSL_SESSION_get0_id_context(const SSL_SESSION *s,
+                                                unsigned int *len)
+{
+    if (len != NULL)
+        *len = s->sid_ctx_length;
+    return s->sid_ctx;
+}
+
+unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s)
+{
+    return s->compress_meth;
+}
+
+/*
+ * SSLv3/TLSv1 has 32 bytes (256 bits) of session ID space. As such, filling
+ * the ID with random junk repeatedly until we have no conflict is going to
+ * complete in one iteration pretty much "most" of the time (btw:
+ * understatement). So, if it takes us 10 iterations and we still can't avoid
+ * a conflict - well that's a reasonable point to call it quits. Either the
+ * RAND code is broken or someone is trying to open roughly very close to
+ * 2^256 SSL sessions to our server. How you might store that many sessions
+ * is perhaps a more interesting question ...
+ */
+
+#define MAX_SESS_ID_ATTEMPTS 10
+static int def_generate_session_id(const SSL *ssl, unsigned char *id,
+                                   unsigned int *id_len)
+{
+    unsigned int retry = 0;
+    do
+        if (RAND_bytes(id, *id_len) <= 0)
+            return 0;
+    while (SSL_has_matching_session_id(ssl, id, *id_len) &&
+           (++retry < MAX_SESS_ID_ATTEMPTS)) ;
+    if (retry < MAX_SESS_ID_ATTEMPTS)
+        return 1;
+    /* else - woops a session_id match */
+    /*
+     * XXX We should also check the external cache -- but the probability of
+     * a collision is negligible, and we could not prevent the concurrent
+     * creation of sessions with identical IDs since we currently don't have
+     * means to atomically check whether a session ID already exists and make
+     * a reservation for it if it does not (this problem applies to the
+     * internal cache as well).
+     */
+    return 0;
+}
+
+int ssl_get_new_session(SSL *s, int session)
+{
+    /* This gets used by clients and servers. */
+
+    unsigned int tmp;
+    SSL_SESSION *ss = NULL;
+    GEN_SESSION_CB cb = def_generate_session_id;
+
+    if ((ss = SSL_SESSION_new()) == NULL)
+        return (0);
+
+    /* If the context has a default timeout, use it */
+    if (s->session_ctx->session_timeout == 0)
+        ss->timeout = SSL_get_default_timeout(s);
+    else
+        ss->timeout = s->session_ctx->session_timeout;
+
+    SSL_SESSION_free(s->session);
+    s->session = NULL;
+
+    if (session) {
+        if (s->version == SSL3_VERSION) {
+            ss->ssl_version = SSL3_VERSION;
+            ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
+        } else if (s->version == TLS1_VERSION) {
+            ss->ssl_version = TLS1_VERSION;
+            ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
+        } else if (s->version == TLS1_1_VERSION) {
+            ss->ssl_version = TLS1_1_VERSION;
+            ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
+        } else if (s->version == TLS1_2_VERSION) {
+            ss->ssl_version = TLS1_2_VERSION;
+            ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
+        } else if (s->version == DTLS1_BAD_VER) {
+            ss->ssl_version = DTLS1_BAD_VER;
+            ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
+        } else if (s->version == DTLS1_VERSION) {
+            ss->ssl_version = DTLS1_VERSION;
+            ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
+        } else if (s->version == DTLS1_2_VERSION) {
+            ss->ssl_version = DTLS1_2_VERSION;
+            ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
+        } else {
+            SSLerr(SSL_F_SSL_GET_NEW_SESSION, SSL_R_UNSUPPORTED_SSL_VERSION);
+            SSL_SESSION_free(ss);
+            return (0);
+        }
+
+        /*-
+         * If RFC5077 ticket, use empty session ID (as server).
+         * Note that:
+         * (a) ssl_get_prev_session() does lookahead into the
+         *     ClientHello extensions to find the session ticket.
+         *     When ssl_get_prev_session() fails, statem_srvr.c calls
+         *     ssl_get_new_session() in tls_process_client_hello().
+         *     At that point, it has not yet parsed the extensions,
+         *     however, because of the lookahead, it already knows
+         *     whether a ticket is expected or not.
+         *
+         * (b) statem_clnt.c calls ssl_get_new_session() before parsing
+         *     ServerHello extensions, and before recording the session
+         *     ID received from the server, so this block is a noop.
+         */
+        if (s->tlsext_ticket_expected) {
+            ss->session_id_length = 0;
+            goto sess_id_done;
+        }
+
+        /* Choose which callback will set the session ID */
+        CRYPTO_THREAD_read_lock(s->lock);
+        CRYPTO_THREAD_read_lock(s->session_ctx->lock);
+        if (s->generate_session_id)
+            cb = s->generate_session_id;
+        else if (s->session_ctx->generate_session_id)
+            cb = s->session_ctx->generate_session_id;
+        CRYPTO_THREAD_unlock(s->session_ctx->lock);
+        CRYPTO_THREAD_unlock(s->lock);
+        /* Choose a session ID */
+        memset(ss->session_id, 0, ss->session_id_length);
+        tmp = ss->session_id_length;
+        if (!cb(s, ss->session_id, &tmp)) {
+            /* The callback failed */
+            SSLerr(SSL_F_SSL_GET_NEW_SESSION,
+                   SSL_R_SSL_SESSION_ID_CALLBACK_FAILED);
+            SSL_SESSION_free(ss);
+            return (0);
+        }
+        /*
+         * Don't allow the callback to set the session length to zero. nor
+         * set it higher than it was.
+         */
+        if (tmp == 0 || tmp > ss->session_id_length) {
+            /* The callback set an illegal length */
+            SSLerr(SSL_F_SSL_GET_NEW_SESSION,
+                   SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH);
+            SSL_SESSION_free(ss);
+            return (0);
+        }
+        ss->session_id_length = tmp;
+        /* Finally, check for a conflict */
+        if (SSL_has_matching_session_id(s, ss->session_id,
+                                        ss->session_id_length)) {
+            SSLerr(SSL_F_SSL_GET_NEW_SESSION, SSL_R_SSL_SESSION_ID_CONFLICT);
+            SSL_SESSION_free(ss);
+            return (0);
+        }
+
+ sess_id_done:
+        if (s->tlsext_hostname) {
+            ss->tlsext_hostname = OPENSSL_strdup(s->tlsext_hostname);
+            if (ss->tlsext_hostname == NULL) {
+                SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR);
+                SSL_SESSION_free(ss);
+                return 0;
+            }
+        }
+    } else {
+        ss->session_id_length = 0;
+    }
+
+    if (s->sid_ctx_length > sizeof ss->sid_ctx) {
+        SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR);
+        SSL_SESSION_free(ss);
+        return 0;
+    }
+    memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length);
+    ss->sid_ctx_length = s->sid_ctx_length;
+    s->session = ss;
+    ss->ssl_version = s->version;
+    ss->verify_result = X509_V_OK;
+
+    /* If client supports extended master secret set it in session */
+    if (s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS)
+        ss->flags |= SSL_SESS_FLAG_EXTMS;
+
+    return (1);
+}
+
+/*-
+ * ssl_get_prev attempts to find an SSL_SESSION to be used to resume this
+ * connection. It is only called by servers.
+ *
+ *   ext: ClientHello extensions (including length prefix)
+ *   session_id: ClientHello session ID.
+ *
+ * Returns:
+ *   -1: error
+ *    0: a session may have been found.
+ *
+ * Side effects:
+ *   - If a session is found then s->session is pointed at it (after freeing an
+ *     existing session if need be) and s->verify_result is set from the session.
+ *   - Both for new and resumed sessions, s->tlsext_ticket_expected is set to 1
+ *     if the server should issue a new session ticket (to 0 otherwise).
+ */
+int ssl_get_prev_session(SSL *s, const PACKET *ext, const PACKET *session_id)
+{
+    /* This is used only by servers. */
+
+    SSL_SESSION *ret = NULL;
+    int fatal = 0;
+    int try_session_cache = 1;
+    int r;
+
+    if (PACKET_remaining(session_id) == 0)
+        try_session_cache = 0;
+
+    /* sets s->tlsext_ticket_expected and extended master secret flag */
+    r = tls_check_serverhello_tlsext_early(s, ext, session_id, &ret);
+    switch (r) {
+    case -1:                   /* Error during processing */
+        fatal = 1;
+        goto err;
+    case 0:                    /* No ticket found */
+    case 1:                    /* Zero length ticket found */
+        break;                  /* Ok to carry on processing session id. */
+    case 2:                    /* Ticket found but not decrypted. */
+    case 3:                    /* Ticket decrypted, *ret has been set. */
+        try_session_cache = 0;
+        break;
+    default:
+        abort();
+    }
+
+    if (try_session_cache &&
+        ret == NULL &&
+        !(s->session_ctx->session_cache_mode &
+          SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) {
+        SSL_SESSION data;
+        size_t local_len;
+        data.ssl_version = s->version;
+        memset(data.session_id, 0, sizeof(data.session_id));
+        if (!PACKET_copy_all(session_id, data.session_id,
+                             sizeof(data.session_id), &local_len)) {
+            goto err;
+        }
+        data.session_id_length = local_len;
+        CRYPTO_THREAD_read_lock(s->session_ctx->lock);
+        ret = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data);
+        if (ret != NULL) {
+            /* don't allow other threads to steal it: */
+            SSL_SESSION_up_ref(ret);
+        }
+        CRYPTO_THREAD_unlock(s->session_ctx->lock);
+        if (ret == NULL)
+            s->session_ctx->stats.sess_miss++;
+    }
+
+    if (try_session_cache &&
+        ret == NULL && s->session_ctx->get_session_cb != NULL) {
+        int copy = 1;
+        ret = s->session_ctx->get_session_cb(s, PACKET_data(session_id),
+                                             PACKET_remaining(session_id),
+                                             &copy);
+
+        if (ret != NULL) {
+            s->session_ctx->stats.sess_cb_hit++;
+
+            /*
+             * Increment reference count now if the session callback asks us
+             * to do so (note that if the session structures returned by the
+             * callback are shared between threads, it must handle the
+             * reference count itself [i.e. copy == 0], or things won't be
+             * thread-safe).
+             */
+            if (copy)
+                SSL_SESSION_up_ref(ret);
+
+            /*
+             * Add the externally cached session to the internal cache as
+             * well if and only if we are supposed to.
+             */
+            if (!
+                (s->session_ctx->session_cache_mode &
+                 SSL_SESS_CACHE_NO_INTERNAL_STORE)) {
+                /*
+                 * The following should not return 1, otherwise, things are
+                 * very strange
+                 */
+                if (SSL_CTX_add_session(s->session_ctx, ret))
+                    goto err;
+            }
+        }
+    }
+
+    if (ret == NULL)
+        goto err;
+
+    /* Now ret is non-NULL and we own one of its reference counts. */
+
+    if (ret->sid_ctx_length != s->sid_ctx_length
+        || memcmp(ret->sid_ctx, s->sid_ctx, ret->sid_ctx_length)) {
+        /*
+         * We have the session requested by the client, but we don't want to
+         * use it in this context.
+         */
+        goto err;               /* treat like cache miss */
+    }
+
+    if ((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) {
+        /*
+         * We can't be sure if this session is being used out of context,
+         * which is especially important for SSL_VERIFY_PEER. The application
+         * should have used SSL[_CTX]_set_session_id_context. For this error
+         * case, we generate an error instead of treating the event like a
+         * cache miss (otherwise it would be easy for applications to
+         * effectively disable the session cache by accident without anyone
+         * noticing).
+         */
+
+        SSLerr(SSL_F_SSL_GET_PREV_SESSION,
+               SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
+        fatal = 1;
+        goto err;
+    }
+
+    if (ret->cipher == NULL) {
+        unsigned char buf[5], *p;
+        unsigned long l;
+
+        p = buf;
+        l = ret->cipher_id;
+        l2n(l, p);
+        if ((ret->ssl_version >> 8) >= SSL3_VERSION_MAJOR)
+            ret->cipher = ssl_get_cipher_by_char(s, &(buf[2]));
+        else
+            ret->cipher = ssl_get_cipher_by_char(s, &(buf[1]));
+        if (ret->cipher == NULL)
+            goto err;
+    }
+
+    if (ret->timeout < (long)(time(NULL) - ret->time)) { /* timeout */
+        s->session_ctx->stats.sess_timeout++;
+        if (try_session_cache) {
+            /* session was from the cache, so remove it */
+            SSL_CTX_remove_session(s->session_ctx, ret);
+        }
+        goto err;
+    }
+
+    /* Check extended master secret extension consistency */
+    if (ret->flags & SSL_SESS_FLAG_EXTMS) {
+        /* If old session includes extms, but new does not: abort handshake */
+        if (!(s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS)) {
+            SSLerr(SSL_F_SSL_GET_PREV_SESSION, SSL_R_INCONSISTENT_EXTMS);
+            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+            fatal = 1;
+            goto err;
+        }
+    } else if (s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) {
+        /* If new session includes extms, but old does not: do not resume */
+        goto err;
+    }
+
+    s->session_ctx->stats.sess_hit++;
+
+    SSL_SESSION_free(s->session);
+    s->session = ret;
+    s->verify_result = s->session->verify_result;
+    return 1;
+
+ err:
+    if (ret != NULL) {
+        SSL_SESSION_free(ret);
+
+        if (!try_session_cache) {
+            /*
+             * The session was from a ticket, so we should issue a ticket for
+             * the new session
+             */
+            s->tlsext_ticket_expected = 1;
+        }
+    }
+    if (fatal)
+        return -1;
+    else
+        return 0;
+}
+
+int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
+{
+    int ret = 0;
+    SSL_SESSION *s;
+
+    /*
+     * add just 1 reference count for the SSL_CTX's session cache even though
+     * it has two ways of access: each session is in a doubly linked list and
+     * an lhash
+     */
+    SSL_SESSION_up_ref(c);
+    /*
+     * if session c is in already in cache, we take back the increment later
+     */
+
+    CRYPTO_THREAD_write_lock(ctx->lock);
+    s = lh_SSL_SESSION_insert(ctx->sessions, c);
+
+    /*
+     * s != NULL iff we already had a session with the given PID. In this
+     * case, s == c should hold (then we did not really modify
+     * ctx->sessions), or we're in trouble.
+     */
+    if (s != NULL && s != c) {
+        /* We *are* in trouble ... */
+        SSL_SESSION_list_remove(ctx, s);
+        SSL_SESSION_free(s);
+        /*
+         * ... so pretend the other session did not exist in cache (we cannot
+         * handle two SSL_SESSION structures with identical session ID in the
+         * same cache, which could happen e.g. when two threads concurrently
+         * obtain the same session from an external cache)
+         */
+        s = NULL;
+    } else if (s == NULL &&
+               lh_SSL_SESSION_retrieve(ctx->sessions, c) == NULL) {
+        /* s == NULL can also mean OOM error in lh_SSL_SESSION_insert ... */
+
+        /*
+         * ... so take back the extra reference and also don't add
+         * the session to the SSL_SESSION_list at this time
+         */
+        s = c;
+    }
+
+    /* Put at the head of the queue unless it is already in the cache */
+    if (s == NULL)
+        SSL_SESSION_list_add(ctx, c);
+
+    if (s != NULL) {
+        /*
+         * existing cache entry -- decrement previously incremented reference
+         * count because it already takes into account the cache
+         */
+
+        SSL_SESSION_free(s);    /* s == c */
+        ret = 0;
+    } else {
+        /*
+         * new cache entry -- remove old ones if cache has become too large
+         */
+
+        ret = 1;
+
+        if (SSL_CTX_sess_get_cache_size(ctx) > 0) {
+            while (SSL_CTX_sess_number(ctx) > SSL_CTX_sess_get_cache_size(ctx)) {
+                if (!remove_session_lock(ctx, ctx->session_cache_tail, 0))
+                    break;
+                else
+                    ctx->stats.sess_cache_full++;
+            }
+        }
+    }
+    CRYPTO_THREAD_unlock(ctx->lock);
+    return ret;
+}
+
+int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c)
+{
+    return remove_session_lock(ctx, c, 1);
+}
+
+static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck)
+{
+    SSL_SESSION *r;
+    int ret = 0;
+
+    if ((c != NULL) && (c->session_id_length != 0)) {
+        if (lck)
+            CRYPTO_THREAD_write_lock(ctx->lock);
+        if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) == c) {
+            ret = 1;
+            r = lh_SSL_SESSION_delete(ctx->sessions, c);
+            SSL_SESSION_list_remove(ctx, c);
+        }
+        c->not_resumable = 1;
+
+        if (lck)
+            CRYPTO_THREAD_unlock(ctx->lock);
+
+        if (ret)
+            SSL_SESSION_free(r);
+
+        if (ctx->remove_session_cb != NULL)
+            ctx->remove_session_cb(ctx, c);
+    } else
+        ret = 0;
+    return (ret);
+}
+
+void SSL_SESSION_free(SSL_SESSION *ss)
+{
+    int i;
+
+    if (ss == NULL)
+        return;
+
+    CRYPTO_atomic_add(&ss->references, -1, &i, ss->lock);
+    REF_PRINT_COUNT("SSL_SESSION", ss);
+    if (i > 0)
+        return;
+    REF_ASSERT_ISNT(i < 0);
+
+    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
+
+    OPENSSL_cleanse(ss->master_key, sizeof ss->master_key);
+    OPENSSL_cleanse(ss->session_id, sizeof ss->session_id);
+    X509_free(ss->peer);
+    sk_X509_pop_free(ss->peer_chain, X509_free);
+    sk_SSL_CIPHER_free(ss->ciphers);
+    OPENSSL_free(ss->tlsext_hostname);
+    OPENSSL_free(ss->tlsext_tick);
+#ifndef OPENSSL_NO_EC
+    ss->tlsext_ecpointformatlist_length = 0;
+    OPENSSL_free(ss->tlsext_ecpointformatlist);
+    ss->tlsext_ellipticcurvelist_length = 0;
+    OPENSSL_free(ss->tlsext_ellipticcurvelist);
+#endif                          /* OPENSSL_NO_EC */
+#ifndef OPENSSL_NO_PSK
+    OPENSSL_free(ss->psk_identity_hint);
+    OPENSSL_free(ss->psk_identity);
+#endif
+#ifndef OPENSSL_NO_SRP
+    OPENSSL_free(ss->srp_username);
+#endif
+    CRYPTO_THREAD_lock_free(ss->lock);
+    OPENSSL_clear_free(ss, sizeof(*ss));
+}
+
+int SSL_SESSION_up_ref(SSL_SESSION *ss)
+{
+    int i;
+
+    if (CRYPTO_atomic_add(&ss->references, 1, &i, ss->lock) <= 0)
+        return 0;
+
+    REF_PRINT_COUNT("SSL_SESSION", ss);
+    REF_ASSERT_ISNT(i < 2);
+    return ((i > 1) ? 1 : 0);
+}
+
+int SSL_set_session(SSL *s, SSL_SESSION *session)
+{
+    ssl_clear_bad_session(s);
+    if (s->ctx->method != s->method) {
+        if (!SSL_set_ssl_method(s, s->ctx->method))
+            return 0;
+    }
+
+    if (session != NULL) {
+        SSL_SESSION_up_ref(session);
+        s->verify_result = session->verify_result;
+    }
+    SSL_SESSION_free(s->session);
+    s->session = session;
+
+    return 1;
+}
+
+int SSL_SESSION_set1_id(SSL_SESSION *s, const unsigned char *sid,
+                        unsigned int sid_len)
+{
+    if (sid_len > SSL_MAX_SSL_SESSION_ID_LENGTH) {
+      SSLerr(SSL_F_SSL_SESSION_SET1_ID,
+             SSL_R_SSL_SESSION_ID_TOO_LONG);
+      return 0;
+    }
+    s->session_id_length = sid_len;
+    memcpy(s->session_id, sid, sid_len);
+    return 1;
+}
+
+long SSL_SESSION_set_timeout(SSL_SESSION *s, long t)
+{
+    if (s == NULL)
+        return (0);
+    s->timeout = t;
+    return (1);
+}
+
+long SSL_SESSION_get_timeout(const SSL_SESSION *s)
+{
+    if (s == NULL)
+        return (0);
+    return (s->timeout);
+}
+
+long SSL_SESSION_get_time(const SSL_SESSION *s)
+{
+    if (s == NULL)
+        return (0);
+    return (s->time);
+}
+
+long SSL_SESSION_set_time(SSL_SESSION *s, long t)
+{
+    if (s == NULL)
+        return (0);
+    s->time = t;
+    return (t);
+}
+
+int SSL_SESSION_get_protocol_version(const SSL_SESSION *s)
+{
+    return s->ssl_version;
+}
+
+const SSL_CIPHER *SSL_SESSION_get0_cipher(const SSL_SESSION *s)
+{
+    return s->cipher;
+}
+
+const char *SSL_SESSION_get0_hostname(const SSL_SESSION *s)
+{
+    return s->tlsext_hostname;
+}
+
+int SSL_SESSION_has_ticket(const SSL_SESSION *s)
+{
+    return (s->tlsext_ticklen > 0) ? 1 : 0;
+}
+
+unsigned long SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *s)
+{
+    return s->tlsext_tick_lifetime_hint;
+}
+
+void SSL_SESSION_get0_ticket(const SSL_SESSION *s, const unsigned char **tick,
+                             size_t *len)
+{
+    *len = s->tlsext_ticklen;
+    if (tick != NULL)
+        *tick = s->tlsext_tick;
+}
+
+X509 *SSL_SESSION_get0_peer(SSL_SESSION *s)
+{
+    return s->peer;
+}
+
+int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx,
+                                unsigned int sid_ctx_len)
+{
+    if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
+        SSLerr(SSL_F_SSL_SESSION_SET1_ID_CONTEXT,
+               SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
+        return 0;
+    }
+    s->sid_ctx_length = sid_ctx_len;
+    memcpy(s->sid_ctx, sid_ctx, sid_ctx_len);
+
+    return 1;
+}
+
+long SSL_CTX_set_timeout(SSL_CTX *s, long t)
+{
+    long l;
+    if (s == NULL)
+        return (0);
+    l = s->session_timeout;
+    s->session_timeout = t;
+    return (l);
+}
+
+long SSL_CTX_get_timeout(const SSL_CTX *s)
+{
+    if (s == NULL)
+        return (0);
+    return (s->session_timeout);
+}
+
+int SSL_set_session_secret_cb(SSL *s,
+                              int (*tls_session_secret_cb) (SSL *s,
+                                                            void *secret,
+                                                            int *secret_len,
+                                                            STACK_OF(SSL_CIPHER)
+                                                            *peer_ciphers,
+                                                            const SSL_CIPHER
+                                                            **cipher,
+                                                            void *arg),
+                              void *arg)
+{
+    if (s == NULL)
+        return (0);
+    s->tls_session_secret_cb = tls_session_secret_cb;
+    s->tls_session_secret_cb_arg = arg;
+    return (1);
+}
+
+int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
+                                  void *arg)
+{
+    if (s == NULL)
+        return (0);
+    s->tls_session_ticket_ext_cb = cb;
+    s->tls_session_ticket_ext_cb_arg = arg;
+    return (1);
+}
+
+int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len)
+{
+    if (s->version >= TLS1_VERSION) {
+        OPENSSL_free(s->tlsext_session_ticket);
+        s->tlsext_session_ticket = NULL;
+        s->tlsext_session_ticket =
+            OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len);
+        if (s->tlsext_session_ticket == NULL) {
+            SSLerr(SSL_F_SSL_SET_SESSION_TICKET_EXT, ERR_R_MALLOC_FAILURE);
+            return 0;
+        }
+
+        if (ext_data) {
+            s->tlsext_session_ticket->length = ext_len;
+            s->tlsext_session_ticket->data = s->tlsext_session_ticket + 1;
+            memcpy(s->tlsext_session_ticket->data, ext_data, ext_len);
+        } else {
+            s->tlsext_session_ticket->length = 0;
+            s->tlsext_session_ticket->data = NULL;
+        }
+
+        return 1;
+    }
+
+    return 0;
+}
+
+typedef struct timeout_param_st {
+    SSL_CTX *ctx;
+    long time;
+    LHASH_OF(SSL_SESSION) *cache;
+} TIMEOUT_PARAM;
+
+static void timeout_cb(SSL_SESSION *s, TIMEOUT_PARAM *p)
+{
+    if ((p->time == 0) || (p->time > (s->time + s->timeout))) { /* timeout */
+        /*
+         * The reason we don't call SSL_CTX_remove_session() is to save on
+         * locking overhead
+         */
+        (void)lh_SSL_SESSION_delete(p->cache, s);
+        SSL_SESSION_list_remove(p->ctx, s);
+        s->not_resumable = 1;
+        if (p->ctx->remove_session_cb != NULL)
+            p->ctx->remove_session_cb(p->ctx, s);
+        SSL_SESSION_free(s);
+    }
+}
+
+IMPLEMENT_LHASH_DOALL_ARG(SSL_SESSION, TIMEOUT_PARAM);
+
+void SSL_CTX_flush_sessions(SSL_CTX *s, long t)
+{
+    unsigned long i;
+    TIMEOUT_PARAM tp;
+
+    tp.ctx = s;
+    tp.cache = s->sessions;
+    if (tp.cache == NULL)
+        return;
+    tp.time = t;
+    CRYPTO_THREAD_write_lock(s->lock);
+    i = lh_SSL_SESSION_get_down_load(s->sessions);
+    lh_SSL_SESSION_set_down_load(s->sessions, 0);
+    lh_SSL_SESSION_doall_TIMEOUT_PARAM(tp.cache, timeout_cb, &tp);
+    lh_SSL_SESSION_set_down_load(s->sessions, i);
+    CRYPTO_THREAD_unlock(s->lock);
+}
+
+int ssl_clear_bad_session(SSL *s)
+{
+    if ((s->session != NULL) &&
+        !(s->shutdown & SSL_SENT_SHUTDOWN) &&
+        !(SSL_in_init(s) || SSL_in_before(s))) {
+        SSL_CTX_remove_session(s->session_ctx, s->session);
+        return (1);
+    } else
+        return (0);
+}
+
+/* locked by SSL_CTX in the calling function */
+static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s)
+{
+    if ((s->next == NULL) || (s->prev == NULL))
+        return;
+
+    if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail)) {
+        /* last element in list */
+        if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) {
+            /* only one element in list */
+            ctx->session_cache_head = NULL;
+            ctx->session_cache_tail = NULL;
+        } else {
+            ctx->session_cache_tail = s->prev;
+            s->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail);
+        }
+    } else {
+        if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) {
+            /* first element in list */
+            ctx->session_cache_head = s->next;
+            s->next->prev = (SSL_SESSION *)&(ctx->session_cache_head);
+        } else {
+            /* middle of list */
+            s->next->prev = s->prev;
+            s->prev->next = s->next;
+        }
+    }
+    s->prev = s->next = NULL;
+}
+
+static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s)
+{
+    if ((s->next != NULL) && (s->prev != NULL))
+        SSL_SESSION_list_remove(ctx, s);
+
+    if (ctx->session_cache_head == NULL) {
+        ctx->session_cache_head = s;
+        ctx->session_cache_tail = s;
+        s->prev = (SSL_SESSION *)&(ctx->session_cache_head);
+        s->next = (SSL_SESSION *)&(ctx->session_cache_tail);
+    } else {
+        s->next = ctx->session_cache_head;
+        s->next->prev = s;
+        s->prev = (SSL_SESSION *)&(ctx->session_cache_head);
+        ctx->session_cache_head = s;
+    }
+}
+
+void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
+                             int (*cb) (struct ssl_st *ssl, SSL_SESSION *sess))
+{
+    ctx->new_session_cb = cb;
+}
+
+int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (SSL *ssl, SSL_SESSION *sess) {
+    return ctx->new_session_cb;
+}
+
+void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,
+                                void (*cb) (SSL_CTX *ctx, SSL_SESSION *sess))
+{
+    ctx->remove_session_cb = cb;
+}
+
+void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (SSL_CTX *ctx,
+                                                  SSL_SESSION *sess) {
+    return ctx->remove_session_cb;
+}
+
+void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
+                             SSL_SESSION *(*cb) (struct ssl_st *ssl,
+                                                 const unsigned char *data,
+                                                 int len, int *copy))
+{
+    ctx->get_session_cb = cb;
+}
+
+SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (SSL *ssl,
+                                                       const unsigned char
+                                                       *data, int len,
+                                                       int *copy) {
+    return ctx->get_session_cb;
+}
+
+void SSL_CTX_set_info_callback(SSL_CTX *ctx,
+                               void (*cb) (const SSL *ssl, int type, int val))
+{
+    ctx->info_callback = cb;
+}
+
+void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type,
+                                                 int val) {
+    return ctx->info_callback;
+}
+
+void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx,
+                                int (*cb) (SSL *ssl, X509 **x509,
+                                           EVP_PKEY **pkey))
+{
+    ctx->client_cert_cb = cb;
+}
+
+int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509,
+                                                 EVP_PKEY **pkey) {
+    return ctx->client_cert_cb;
+}
+
+#ifndef OPENSSL_NO_ENGINE
+int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e)
+{
+    if (!ENGINE_init(e)) {
+        SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, ERR_R_ENGINE_LIB);
+        return 0;
+    }
+    if (!ENGINE_get_ssl_client_cert_function(e)) {
+        SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE,
+               SSL_R_NO_CLIENT_CERT_METHOD);
+        ENGINE_finish(e);
+        return 0;
+    }
+    ctx->client_cert_engine = e;
+    return 1;
+}
+#endif
+
+void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx,
+                                    int (*cb) (SSL *ssl,
+                                               unsigned char *cookie,
+                                               unsigned int *cookie_len))
+{
+    ctx->app_gen_cookie_cb = cb;
+}
+
+void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx,
+                                  int (*cb) (SSL *ssl,
+                                             const unsigned char *cookie,
+                                             unsigned int cookie_len))
+{
+    ctx->app_verify_cookie_cb = cb;
+}
+
+IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_stat.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_stat.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_stat.c	(revision 331)
@@ -0,0 +1,362 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <stdio.h>
+#include "ssl_locl.h"
+
+const char *SSL_state_string_long(const SSL *s)
+{
+    if (ossl_statem_in_error(s))
+        return "error";
+
+    switch (SSL_get_state(s)) {
+    case TLS_ST_CR_CERT_STATUS:
+        return "SSLv3/TLS read certificate status";
+    case TLS_ST_CW_NEXT_PROTO:
+        return "SSLv3/TLS write next proto";
+    case TLS_ST_SR_NEXT_PROTO:
+        return "SSLv3/TLS write next proto";
+    case TLS_ST_SW_CERT_STATUS:
+        return "SSLv3/TLS write next proto";
+    case TLS_ST_BEFORE:
+        return "before SSL initialization";
+    case TLS_ST_OK:
+        return "SSL negotiation finished successfully";
+    case TLS_ST_CW_CLNT_HELLO:
+        return "SSLv3/TLS write client hello";
+    case TLS_ST_CR_SRVR_HELLO:
+        return "SSLv3/TLS read server hello";
+    case TLS_ST_CR_CERT:
+        return "SSLv3/TLS read server certificate";
+    case TLS_ST_CR_KEY_EXCH:
+        return "SSLv3/TLS read server key exchange";
+    case TLS_ST_CR_CERT_REQ:
+        return "SSLv3/TLS read server certificate request";
+    case TLS_ST_CR_SESSION_TICKET:
+        return "SSLv3/TLS read server session ticket";
+    case TLS_ST_CR_SRVR_DONE:
+        return "SSLv3/TLS read server done";
+    case TLS_ST_CW_CERT:
+        return "SSLv3/TLS write client certificate";
+    case TLS_ST_CW_KEY_EXCH:
+        return "SSLv3/TLS write client key exchange";
+    case TLS_ST_CW_CERT_VRFY:
+        return "SSLv3/TLS write certificate verify";
+    case TLS_ST_CW_CHANGE:
+    case TLS_ST_SW_CHANGE:
+        return "SSLv3/TLS write change cipher spec";
+    case TLS_ST_CW_FINISHED:
+    case TLS_ST_SW_FINISHED:
+        return "SSLv3/TLS write finished";
+    case TLS_ST_CR_CHANGE:
+    case TLS_ST_SR_CHANGE:
+        return "SSLv3/TLS read change cipher spec";
+    case TLS_ST_CR_FINISHED:
+    case TLS_ST_SR_FINISHED:
+        return "SSLv3/TLS read finished";
+    case TLS_ST_SR_CLNT_HELLO:
+        return "SSLv3/TLS read client hello";
+    case TLS_ST_SW_HELLO_REQ:
+        return "SSLv3/TLS write hello request";
+    case TLS_ST_SW_SRVR_HELLO:
+        return "SSLv3/TLS write server hello";
+    case TLS_ST_SW_CERT:
+        return "SSLv3/TLS write certificate";
+    case TLS_ST_SW_KEY_EXCH:
+        return "SSLv3/TLS write key exchange";
+    case TLS_ST_SW_CERT_REQ:
+        return "SSLv3/TLS write certificate request";
+    case TLS_ST_SW_SESSION_TICKET:
+        return "SSLv3/TLS write session ticket";
+    case TLS_ST_SW_SRVR_DONE:
+        return "SSLv3/TLS write server done";
+    case TLS_ST_SR_CERT:
+        return "SSLv3/TLS read client certificate";
+    case TLS_ST_SR_KEY_EXCH:
+        return "SSLv3/TLS read client key exchange";
+    case TLS_ST_SR_CERT_VRFY:
+        return "SSLv3/TLS read certificate verify";
+    case DTLS_ST_CR_HELLO_VERIFY_REQUEST:
+        return "DTLS1 read hello verify request";
+    case DTLS_ST_SW_HELLO_VERIFY_REQUEST:
+        return "DTLS1 write hello verify request";
+    default:
+        return "unknown state";
+    }
+}
+
+const char *SSL_state_string(const SSL *s)
+{
+    if (ossl_statem_in_error(s))
+        return "SSLERR";
+
+    switch (SSL_get_state(s)) {
+    case TLS_ST_SR_NEXT_PROTO:
+        return "TRNP";
+    case TLS_ST_SW_SESSION_TICKET:
+        return "TWST";
+    case TLS_ST_SW_CERT_STATUS:
+        return "TWCS";
+    case TLS_ST_CR_CERT_STATUS:
+        return "TRCS";
+    case TLS_ST_CR_SESSION_TICKET:
+        return "TRST";
+    case TLS_ST_CW_NEXT_PROTO:
+        return "TWNP";
+    case TLS_ST_BEFORE:
+        return "PINIT ";
+    case TLS_ST_OK:
+        return "SSLOK ";
+    case TLS_ST_CW_CLNT_HELLO:
+        return "TWCH";
+    case TLS_ST_CR_SRVR_HELLO:
+        return "TRSH";
+    case TLS_ST_CR_CERT:
+        return "TRSC";
+    case TLS_ST_CR_KEY_EXCH:
+        return "TRSKE";
+    case TLS_ST_CR_CERT_REQ:
+        return "TRCR";
+    case TLS_ST_CR_SRVR_DONE:
+        return "TRSD";
+    case TLS_ST_CW_CERT:
+        return "TWCC";
+    case TLS_ST_CW_KEY_EXCH:
+        return "TWCKE";
+    case TLS_ST_CW_CERT_VRFY:
+        return "TWCV";
+    case TLS_ST_SW_CHANGE:
+    case TLS_ST_CW_CHANGE:
+        return "TWCCS";
+    case TLS_ST_SW_FINISHED:
+    case TLS_ST_CW_FINISHED:
+        return "TWFIN";
+    case TLS_ST_SR_CHANGE:
+    case TLS_ST_CR_CHANGE:
+        return "TRCCS";
+    case TLS_ST_SR_FINISHED:
+    case TLS_ST_CR_FINISHED:
+        return "TRFIN";
+    case TLS_ST_SW_HELLO_REQ:
+        return "TWHR";
+    case TLS_ST_SR_CLNT_HELLO:
+        return "TRCH";
+    case TLS_ST_SW_SRVR_HELLO:
+        return "TWSH";
+    case TLS_ST_SW_CERT:
+        return "TWSC";
+    case TLS_ST_SW_KEY_EXCH:
+        return "TWSKE";
+    case TLS_ST_SW_CERT_REQ:
+        return "TWCR";
+    case TLS_ST_SW_SRVR_DONE:
+        return "TWSD";
+    case TLS_ST_SR_CERT:
+        return "TRCC";
+    case TLS_ST_SR_KEY_EXCH:
+        return "TRCKE";
+    case TLS_ST_SR_CERT_VRFY:
+        return "TRCV";
+    case DTLS_ST_CR_HELLO_VERIFY_REQUEST:
+        return "DRCHV";
+    case DTLS_ST_SW_HELLO_VERIFY_REQUEST:
+        return "DWCHV";
+    default:
+        return "UNKWN ";
+    }
+}
+
+const char *SSL_alert_type_string_long(int value)
+{
+    switch (value >> 8) {
+    case SSL3_AL_WARNING:
+        return "warning";
+    case SSL3_AL_FATAL:
+        return "fatal";
+    default:
+        return "unknown";
+    }
+}
+
+const char *SSL_alert_type_string(int value)
+{
+    switch (value >> 8) {
+    case SSL3_AL_WARNING:
+        return "W";
+    case SSL3_AL_FATAL:
+        return "F";
+    default:
+        return "U";
+    }
+}
+
+const char *SSL_alert_desc_string(int value)
+{
+    switch (value & 0xff) {
+    case SSL3_AD_CLOSE_NOTIFY:
+        return "CN";
+    case SSL3_AD_UNEXPECTED_MESSAGE:
+        return "UM";
+    case SSL3_AD_BAD_RECORD_MAC:
+        return "BM";
+    case SSL3_AD_DECOMPRESSION_FAILURE:
+        return "DF";
+    case SSL3_AD_HANDSHAKE_FAILURE:
+        return "HF";
+    case SSL3_AD_NO_CERTIFICATE:
+        return "NC";
+    case SSL3_AD_BAD_CERTIFICATE:
+        return "BC";
+    case SSL3_AD_UNSUPPORTED_CERTIFICATE:
+        return "UC";
+    case SSL3_AD_CERTIFICATE_REVOKED:
+        return "CR";
+    case SSL3_AD_CERTIFICATE_EXPIRED:
+        return "CE";
+    case SSL3_AD_CERTIFICATE_UNKNOWN:
+        return "CU";
+    case SSL3_AD_ILLEGAL_PARAMETER:
+        return "IP";
+    case TLS1_AD_DECRYPTION_FAILED:
+        return "DC";
+    case TLS1_AD_RECORD_OVERFLOW:
+        return "RO";
+    case TLS1_AD_UNKNOWN_CA:
+        return "CA";
+    case TLS1_AD_ACCESS_DENIED:
+        return "AD";
+    case TLS1_AD_DECODE_ERROR:
+        return "DE";
+    case TLS1_AD_DECRYPT_ERROR:
+        return "CY";
+    case TLS1_AD_EXPORT_RESTRICTION:
+        return "ER";
+    case TLS1_AD_PROTOCOL_VERSION:
+        return "PV";
+    case TLS1_AD_INSUFFICIENT_SECURITY:
+        return "IS";
+    case TLS1_AD_INTERNAL_ERROR:
+        return "IE";
+    case TLS1_AD_USER_CANCELLED:
+        return "US";
+    case TLS1_AD_NO_RENEGOTIATION:
+        return "NR";
+    case TLS1_AD_UNSUPPORTED_EXTENSION:
+        return "UE";
+    case TLS1_AD_CERTIFICATE_UNOBTAINABLE:
+        return "CO";
+    case TLS1_AD_UNRECOGNIZED_NAME:
+        return "UN";
+    case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
+        return "BR";
+    case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE:
+        return "BH";
+    case TLS1_AD_UNKNOWN_PSK_IDENTITY:
+        return "UP";
+    default:
+        return "UK";
+    }
+}
+
+const char *SSL_alert_desc_string_long(int value)
+{
+    switch (value & 0xff) {
+    case SSL3_AD_CLOSE_NOTIFY:
+        return "close notify";
+    case SSL3_AD_UNEXPECTED_MESSAGE:
+        return "unexpected_message";
+    case SSL3_AD_BAD_RECORD_MAC:
+        return "bad record mac";
+    case SSL3_AD_DECOMPRESSION_FAILURE:
+        return "decompression failure";
+    case SSL3_AD_HANDSHAKE_FAILURE:
+        return "handshake failure";
+    case SSL3_AD_NO_CERTIFICATE:
+        return "no certificate";
+    case SSL3_AD_BAD_CERTIFICATE:
+        return "bad certificate";
+    case SSL3_AD_UNSUPPORTED_CERTIFICATE:
+        return "unsupported certificate";
+    case SSL3_AD_CERTIFICATE_REVOKED:
+        return "certificate revoked";
+    case SSL3_AD_CERTIFICATE_EXPIRED:
+        return "certificate expired";
+    case SSL3_AD_CERTIFICATE_UNKNOWN:
+        return "certificate unknown";
+    case SSL3_AD_ILLEGAL_PARAMETER:
+        return "illegal parameter";
+    case TLS1_AD_DECRYPTION_FAILED:
+        return "decryption failed";
+    case TLS1_AD_RECORD_OVERFLOW:
+        return "record overflow";
+    case TLS1_AD_UNKNOWN_CA:
+        return "unknown CA";
+    case TLS1_AD_ACCESS_DENIED:
+        return "access denied";
+    case TLS1_AD_DECODE_ERROR:
+        return "decode error";
+    case TLS1_AD_DECRYPT_ERROR:
+        return "decrypt error";
+    case TLS1_AD_EXPORT_RESTRICTION:
+        return "export restriction";
+    case TLS1_AD_PROTOCOL_VERSION:
+        return "protocol version";
+    case TLS1_AD_INSUFFICIENT_SECURITY:
+        return "insufficient security";
+    case TLS1_AD_INTERNAL_ERROR:
+        return "internal error";
+    case TLS1_AD_USER_CANCELLED:
+        return "user canceled";
+    case TLS1_AD_NO_RENEGOTIATION:
+        return "no renegotiation";
+    case TLS1_AD_UNSUPPORTED_EXTENSION:
+        return "unsupported extension";
+    case TLS1_AD_CERTIFICATE_UNOBTAINABLE:
+        return "certificate unobtainable";
+    case TLS1_AD_UNRECOGNIZED_NAME:
+        return "unrecognized name";
+    case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
+        return "bad certificate status response";
+    case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE:
+        return "bad certificate hash value";
+    case TLS1_AD_UNKNOWN_PSK_IDENTITY:
+        return "unknown PSK identity";
+    case TLS1_AD_NO_APPLICATION_PROTOCOL:
+        return "no application protocol";
+    default:
+        return "unknown";
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_txt.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_txt.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_txt.c	(revision 331)
@@ -0,0 +1,217 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <stdio.h>
+#include <openssl/buffer.h>
+#include "ssl_locl.h"
+
+#ifndef OPENSSL_NO_STDIO
+int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *x)
+{
+    BIO *b;
+    int ret;
+
+    if ((b = BIO_new(BIO_s_file())) == NULL) {
+        SSLerr(SSL_F_SSL_SESSION_PRINT_FP, ERR_R_BUF_LIB);
+        return (0);
+    }
+    BIO_set_fp(b, fp, BIO_NOCLOSE);
+    ret = SSL_SESSION_print(b, x);
+    BIO_free(b);
+    return (ret);
+}
+#endif
+
+int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
+{
+    unsigned int i;
+    const char *s;
+
+    if (x == NULL)
+        goto err;
+    if (BIO_puts(bp, "SSL-Session:\n") <= 0)
+        goto err;
+    s = ssl_protocol_to_string(x->ssl_version);
+    if (BIO_printf(bp, "    Protocol  : %s\n", s) <= 0)
+        goto err;
+
+    if (x->cipher == NULL) {
+        if (((x->cipher_id) & 0xff000000) == 0x02000000) {
+            if (BIO_printf
+                (bp, "    Cipher    : %06lX\n", x->cipher_id & 0xffffff) <= 0)
+                goto err;
+        } else {
+            if (BIO_printf
+                (bp, "    Cipher    : %04lX\n", x->cipher_id & 0xffff) <= 0)
+                goto err;
+        }
+    } else {
+        if (BIO_printf
+            (bp, "    Cipher    : %s\n",
+             ((x->cipher == NULL) ? "unknown" : x->cipher->name)) <= 0)
+            goto err;
+    }
+    if (BIO_puts(bp, "    Session-ID: ") <= 0)
+        goto err;
+    for (i = 0; i < x->session_id_length; i++) {
+        if (BIO_printf(bp, "%02X", x->session_id[i]) <= 0)
+            goto err;
+    }
+    if (BIO_puts(bp, "\n    Session-ID-ctx: ") <= 0)
+        goto err;
+    for (i = 0; i < x->sid_ctx_length; i++) {
+        if (BIO_printf(bp, "%02X", x->sid_ctx[i]) <= 0)
+            goto err;
+    }
+    if (BIO_puts(bp, "\n    Master-Key: ") <= 0)
+        goto err;
+    for (i = 0; i < (unsigned int)x->master_key_length; i++) {
+        if (BIO_printf(bp, "%02X", x->master_key[i]) <= 0)
+            goto err;
+    }
+#ifndef OPENSSL_NO_PSK
+    if (BIO_puts(bp, "\n    PSK identity: ") <= 0)
+        goto err;
+    if (BIO_printf(bp, "%s", x->psk_identity ? x->psk_identity : "None") <= 0)
+        goto err;
+    if (BIO_puts(bp, "\n    PSK identity hint: ") <= 0)
+        goto err;
+    if (BIO_printf
+        (bp, "%s", x->psk_identity_hint ? x->psk_identity_hint : "None") <= 0)
+        goto err;
+#endif
+#ifndef OPENSSL_NO_SRP
+    if (BIO_puts(bp, "\n    SRP username: ") <= 0)
+        goto err;
+    if (BIO_printf(bp, "%s", x->srp_username ? x->srp_username : "None") <= 0)
+        goto err;
+#endif
+    if (x->tlsext_tick_lifetime_hint) {
+        if (BIO_printf(bp,
+                       "\n    TLS session ticket lifetime hint: %ld (seconds)",
+                       x->tlsext_tick_lifetime_hint) <= 0)
+            goto err;
+    }
+    if (x->tlsext_tick) {
+        if (BIO_puts(bp, "\n    TLS session ticket:\n") <= 0)
+            goto err;
+        if (BIO_dump_indent
+            (bp, (const char *)x->tlsext_tick, x->tlsext_ticklen, 4)
+            <= 0)
+            goto err;
+    }
+#ifndef OPENSSL_NO_COMP
+    if (x->compress_meth != 0) {
+        SSL_COMP *comp = NULL;
+
+        if (!ssl_cipher_get_evp(x, NULL, NULL, NULL, NULL, &comp, 0))
+            goto err;
+        if (comp == NULL) {
+            if (BIO_printf(bp, "\n    Compression: %d", x->compress_meth) <= 0)
+                goto err;
+        } else {
+            if (BIO_printf(bp, "\n    Compression: %d (%s)", comp->id,
+                           comp->name) <= 0)
+                goto err;
+        }
+    }
+#endif
+    if (x->time != 0L) {
+        if (BIO_printf(bp, "\n    Start Time: %ld", x->time) <= 0)
+            goto err;
+    }
+    if (x->timeout != 0L) {
+        if (BIO_printf(bp, "\n    Timeout   : %ld (sec)", x->timeout) <= 0)
+            goto err;
+    }
+    if (BIO_puts(bp, "\n") <= 0)
+        goto err;
+
+    if (BIO_puts(bp, "    Verify return code: ") <= 0)
+        goto err;
+    if (BIO_printf(bp, "%ld (%s)\n", x->verify_result,
+                   X509_verify_cert_error_string(x->verify_result)) <= 0)
+        goto err;
+
+    if (BIO_printf(bp, "    Extended master secret: %s\n",
+                   x->flags & SSL_SESS_FLAG_EXTMS ? "yes" : "no") <= 0)
+        goto err;
+
+    return (1);
+ err:
+    return (0);
+}
+
+/*
+ * print session id and master key in NSS keylog format (RSA
+ * Session-ID:<session id> Master-Key:<master key>)
+ */
+int SSL_SESSION_print_keylog(BIO *bp, const SSL_SESSION *x)
+{
+    unsigned int i;
+
+    if (x == NULL)
+        goto err;
+    if (x->session_id_length == 0 || x->master_key_length == 0)
+        goto err;
+
+    /*
+     * the RSA prefix is required by the format's definition although there's
+     * nothing RSA-specific in the output, therefore, we don't have to check if
+     * the cipher suite is based on RSA
+     */
+    if (BIO_puts(bp, "RSA ") <= 0)
+        goto err;
+
+    if (BIO_puts(bp, "Session-ID:") <= 0)
+        goto err;
+    for (i = 0; i < x->session_id_length; i++) {
+        if (BIO_printf(bp, "%02X", x->session_id[i]) <= 0)
+            goto err;
+    }
+    if (BIO_puts(bp, " Master-Key:") <= 0)
+        goto err;
+    for (i = 0; i < (unsigned int)x->master_key_length; i++) {
+        if (BIO_printf(bp, "%02X", x->master_key[i]) <= 0)
+            goto err;
+    }
+    if (BIO_puts(bp, "\n") <= 0)
+        goto err;
+
+    return (1);
+ err:
+    return (0);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_utst.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_utst.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/ssl_utst.c	(revision 331)
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2014-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 "ssl_locl.h"
+
+#ifndef OPENSSL_NO_UNIT_TEST
+
+static const struct openssl_ssl_test_functions ssl_test_functions = {
+    ssl_init_wbio_buffer,
+    ssl3_setup_buffers,
+# ifndef OPENSSL_NO_HEARTBEATS
+#  undef dtls1_process_heartbeat
+    dtls1_process_heartbeat
+# endif
+};
+
+const struct openssl_ssl_test_functions *SSL_test_functions(void)
+{
+    return &ssl_test_functions;
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem.c	(revision 331)
@@ -0,0 +1,875 @@
+/*
+ * Copyright 2015-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 <openssl/rand.h>
+#include "../ssl_locl.h"
+#include "statem_locl.h"
+
+/*
+ * This file implements the SSL/TLS/DTLS state machines.
+ *
+ * There are two primary state machines:
+ *
+ * 1) Message flow state machine
+ * 2) Handshake state machine
+ *
+ * The Message flow state machine controls the reading and sending of messages
+ * including handling of non-blocking IO events, flushing of the underlying
+ * write BIO, handling unexpected messages, etc. It is itself broken into two
+ * separate sub-state machines which control reading and writing respectively.
+ *
+ * The Handshake state machine keeps track of the current SSL/TLS handshake
+ * state. Transitions of the handshake state are the result of events that
+ * occur within the Message flow state machine.
+ *
+ * Overall it looks like this:
+ *
+ * ---------------------------------------------            -------------------
+ * |                                           |            |                 |
+ * | Message flow state machine                |            |                 |
+ * |                                           |            |                 |
+ * | -------------------- -------------------- | Transition | Handshake state |
+ * | | MSG_FLOW_READING | | MSG_FLOW_WRITING | | Event      | machine         |
+ * | | sub-state        | | sub-state        | |----------->|                 |
+ * | | machine for      | | machine for      | |            |                 |
+ * | | reading messages | | writing messages | |            |                 |
+ * | -------------------- -------------------- |            |                 |
+ * |                                           |            |                 |
+ * ---------------------------------------------            -------------------
+ *
+ */
+
+/* Sub state machine return values */
+typedef enum {
+    /* Something bad happened or NBIO */
+    SUB_STATE_ERROR,
+    /* Sub state finished go to the next sub state */
+    SUB_STATE_FINISHED,
+    /* Sub state finished and handshake was completed */
+    SUB_STATE_END_HANDSHAKE
+} SUB_STATE_RETURN;
+
+static int state_machine(SSL *s, int server);
+static void init_read_state_machine(SSL *s);
+static SUB_STATE_RETURN read_state_machine(SSL *s);
+static void init_write_state_machine(SSL *s);
+static SUB_STATE_RETURN write_state_machine(SSL *s);
+
+OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl)
+{
+    return ssl->statem.hand_state;
+}
+
+int SSL_in_init(SSL *s)
+{
+    return s->statem.in_init;
+}
+
+int SSL_is_init_finished(SSL *s)
+{
+    return !(s->statem.in_init) && (s->statem.hand_state == TLS_ST_OK);
+}
+
+int SSL_in_before(SSL *s)
+{
+    /*
+     * Historically being "in before" meant before anything had happened. In the
+     * current code though we remain in the "before" state for a while after we
+     * have started the handshake process (e.g. as a server waiting for the
+     * first message to arrive). There "in before" is taken to mean "in before"
+     * and not started any handshake process yet.
+     */
+    return (s->statem.hand_state == TLS_ST_BEFORE)
+        && (s->statem.state == MSG_FLOW_UNINITED);
+}
+
+/*
+ * Clear the state machine state and reset back to MSG_FLOW_UNINITED
+ */
+void ossl_statem_clear(SSL *s)
+{
+    s->statem.state = MSG_FLOW_UNINITED;
+    s->statem.hand_state = TLS_ST_BEFORE;
+    s->statem.in_init = 1;
+    s->statem.no_cert_verify = 0;
+}
+
+/*
+ * Set the state machine up ready for a renegotiation handshake
+ */
+void ossl_statem_set_renegotiate(SSL *s)
+{
+    s->statem.state = MSG_FLOW_RENEGOTIATE;
+    s->statem.in_init = 1;
+}
+
+/*
+ * Put the state machine into an error state. This is a permanent error for
+ * the current connection.
+ */
+void ossl_statem_set_error(SSL *s)
+{
+    s->statem.state = MSG_FLOW_ERROR;
+}
+
+/*
+ * Discover whether the current connection is in the error state.
+ *
+ * Valid return values are:
+ *   1: Yes
+ *   0: No
+ */
+int ossl_statem_in_error(const SSL *s)
+{
+    if (s->statem.state == MSG_FLOW_ERROR)
+        return 1;
+
+    return 0;
+}
+
+void ossl_statem_set_in_init(SSL *s, int init)
+{
+    s->statem.in_init = init;
+}
+
+int ossl_statem_get_in_handshake(SSL *s)
+{
+    return s->statem.in_handshake;
+}
+
+void ossl_statem_set_in_handshake(SSL *s, int inhand)
+{
+    if (inhand)
+        s->statem.in_handshake++;
+    else
+        s->statem.in_handshake--;
+}
+
+void ossl_statem_set_hello_verify_done(SSL *s)
+{
+    s->statem.state = MSG_FLOW_UNINITED;
+    s->statem.in_init = 1;
+    /*
+     * This will get reset (briefly) back to TLS_ST_BEFORE when we enter
+     * state_machine() because |state| is MSG_FLOW_UNINITED, but until then any
+     * calls to SSL_in_before() will return false. Also calls to
+     * SSL_state_string() and SSL_state_string_long() will return something
+     * sensible.
+     */
+    s->statem.hand_state = TLS_ST_SR_CLNT_HELLO;
+}
+
+int ossl_statem_connect(SSL *s)
+{
+    return state_machine(s, 0);
+}
+
+int ossl_statem_accept(SSL *s)
+{
+    return state_machine(s, 1);
+}
+
+typedef void (*info_cb) (const SSL *, int, int);
+
+static info_cb get_callback(SSL *s)
+{
+    if (s->info_callback != NULL)
+        return s->info_callback;
+    else if (s->ctx->info_callback != NULL)
+        return s->ctx->info_callback;
+
+    return NULL;
+}
+
+/*
+ * The main message flow state machine. We start in the MSG_FLOW_UNINITED or
+ * MSG_FLOW_RENEGOTIATE state and finish in MSG_FLOW_FINISHED. Valid states and
+ * transitions are as follows:
+ *
+ * MSG_FLOW_UNINITED     MSG_FLOW_RENEGOTIATE
+ *        |                       |
+ *        +-----------------------+
+ *        v
+ * MSG_FLOW_WRITING <---> MSG_FLOW_READING
+ *        |
+ *        V
+ * MSG_FLOW_FINISHED
+ *        |
+ *        V
+ *    [SUCCESS]
+ *
+ * We may exit at any point due to an error or NBIO event. If an NBIO event
+ * occurs then we restart at the point we left off when we are recalled.
+ * MSG_FLOW_WRITING and MSG_FLOW_READING have sub-state machines associated with them.
+ *
+ * In addition to the above there is also the MSG_FLOW_ERROR state. We can move
+ * into that state at any point in the event that an irrecoverable error occurs.
+ *
+ * Valid return values are:
+ *   1: Success
+ * <=0: NBIO or error
+ */
+static int state_machine(SSL *s, int server)
+{
+    BUF_MEM *buf = NULL;
+    unsigned long Time = (unsigned long)time(NULL);
+    void (*cb) (const SSL *ssl, int type, int val) = NULL;
+    OSSL_STATEM *st = &s->statem;
+    int ret = -1;
+    int ssret;
+
+    if (st->state == MSG_FLOW_ERROR) {
+        /* Shouldn't have been called if we're already in the error state */
+        return -1;
+    }
+
+    RAND_add(&Time, sizeof(Time), 0);
+    ERR_clear_error();
+    clear_sys_error();
+
+    cb = get_callback(s);
+
+    st->in_handshake++;
+    if (!SSL_in_init(s) || SSL_in_before(s)) {
+        if (!SSL_clear(s))
+            return -1;
+    }
+#ifndef OPENSSL_NO_SCTP
+    if (SSL_IS_DTLS(s)) {
+        /*
+         * Notify SCTP BIO socket to enter handshake mode and prevent stream
+         * identifier other than 0. Will be ignored if no SCTP is used.
+         */
+        BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE,
+                 st->in_handshake, NULL);
+    }
+#endif
+
+#ifndef OPENSSL_NO_HEARTBEATS
+    /*
+     * If we're awaiting a HeartbeatResponse, pretend we already got and
+     * don't await it anymore, because Heartbeats don't make sense during
+     * handshakes anyway.
+     */
+    if (s->tlsext_hb_pending) {
+        if (SSL_IS_DTLS(s))
+            dtls1_stop_timer(s);
+        s->tlsext_hb_pending = 0;
+        s->tlsext_hb_seq++;
+    }
+#endif
+
+    /* Initialise state machine */
+
+    if (st->state == MSG_FLOW_RENEGOTIATE) {
+        s->renegotiate = 1;
+        if (!server)
+            s->ctx->stats.sess_connect_renegotiate++;
+    }
+
+    if (st->state == MSG_FLOW_UNINITED || st->state == MSG_FLOW_RENEGOTIATE) {
+        if (st->state == MSG_FLOW_UNINITED) {
+            st->hand_state = TLS_ST_BEFORE;
+        }
+
+        s->server = server;
+        if (cb != NULL)
+            cb(s, SSL_CB_HANDSHAKE_START, 1);
+
+        if (SSL_IS_DTLS(s)) {
+            if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00) &&
+                (server || (s->version & 0xff00) != (DTLS1_BAD_VER & 0xff00))) {
+                SSLerr(SSL_F_STATE_MACHINE, ERR_R_INTERNAL_ERROR);
+                goto end;
+            }
+        } else {
+            if ((s->version >> 8) != SSL3_VERSION_MAJOR) {
+                SSLerr(SSL_F_STATE_MACHINE, ERR_R_INTERNAL_ERROR);
+                goto end;
+            }
+        }
+
+        if (!ssl_security(s, SSL_SECOP_VERSION, 0, s->version, NULL)) {
+            SSLerr(SSL_F_STATE_MACHINE, SSL_R_VERSION_TOO_LOW);
+            goto end;
+        }
+
+        if (s->init_buf == NULL) {
+            if ((buf = BUF_MEM_new()) == NULL) {
+                goto end;
+            }
+            if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
+                goto end;
+            }
+            s->init_buf = buf;
+            buf = NULL;
+        }
+
+        if (!ssl3_setup_buffers(s)) {
+            goto end;
+        }
+        s->init_num = 0;
+
+        /*
+         * Should have been reset by tls_process_finished, too.
+         */
+        s->s3->change_cipher_spec = 0;
+
+        /*
+         * Ok, we now need to push on a buffering BIO ...but not with
+         * SCTP
+         */
+#ifndef OPENSSL_NO_SCTP
+        if (!SSL_IS_DTLS(s) || !BIO_dgram_is_sctp(SSL_get_wbio(s)))
+#endif
+            if (!ssl_init_wbio_buffer(s)) {
+                goto end;
+            }
+
+        if (!server || st->state != MSG_FLOW_RENEGOTIATE) {
+            if (!ssl3_init_finished_mac(s)) {
+                ossl_statem_set_error(s);
+                goto end;
+            }
+        }
+
+        if (server) {
+            if (st->state != MSG_FLOW_RENEGOTIATE) {
+                s->ctx->stats.sess_accept++;
+            } else if (!s->s3->send_connection_binding &&
+                       !(s->options &
+                         SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
+                /*
+                 * Server attempting to renegotiate with client that doesn't
+                 * support secure renegotiation.
+                 */
+                SSLerr(SSL_F_STATE_MACHINE,
+                       SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+                ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+                ossl_statem_set_error(s);
+                goto end;
+            } else {
+                /*
+                 * st->state == MSG_FLOW_RENEGOTIATE, we will just send a
+                 * HelloRequest
+                 */
+                s->ctx->stats.sess_accept_renegotiate++;
+            }
+
+            s->s3->tmp.cert_request = 0;
+        } else {
+            s->ctx->stats.sess_connect++;
+
+            /* mark client_random uninitialized */
+            memset(s->s3->client_random, 0, sizeof(s->s3->client_random));
+            s->hit = 0;
+
+            s->s3->tmp.cert_req = 0;
+
+            if (SSL_IS_DTLS(s)) {
+                st->use_timer = 1;
+            }
+        }
+
+        st->state = MSG_FLOW_WRITING;
+        init_write_state_machine(s);
+        st->read_state_first_init = 1;
+    }
+
+    while (st->state != MSG_FLOW_FINISHED) {
+        if (st->state == MSG_FLOW_READING) {
+            ssret = read_state_machine(s);
+            if (ssret == SUB_STATE_FINISHED) {
+                st->state = MSG_FLOW_WRITING;
+                init_write_state_machine(s);
+            } else {
+                /* NBIO or error */
+                goto end;
+            }
+        } else if (st->state == MSG_FLOW_WRITING) {
+            ssret = write_state_machine(s);
+            if (ssret == SUB_STATE_FINISHED) {
+                st->state = MSG_FLOW_READING;
+                init_read_state_machine(s);
+            } else if (ssret == SUB_STATE_END_HANDSHAKE) {
+                st->state = MSG_FLOW_FINISHED;
+            } else {
+                /* NBIO or error */
+                goto end;
+            }
+        } else {
+            /* Error */
+            ossl_statem_set_error(s);
+            goto end;
+        }
+    }
+
+    st->state = MSG_FLOW_UNINITED;
+    ret = 1;
+
+ end:
+    st->in_handshake--;
+
+#ifndef OPENSSL_NO_SCTP
+    if (SSL_IS_DTLS(s)) {
+        /*
+         * Notify SCTP BIO socket to leave handshake mode and allow stream
+         * identifier other than 0. Will be ignored if no SCTP is used.
+         */
+        BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE,
+                 st->in_handshake, NULL);
+    }
+#endif
+
+    BUF_MEM_free(buf);
+    if (cb != NULL) {
+        if (server)
+            cb(s, SSL_CB_ACCEPT_EXIT, ret);
+        else
+            cb(s, SSL_CB_CONNECT_EXIT, ret);
+    }
+    return ret;
+}
+
+/*
+ * Initialise the MSG_FLOW_READING sub-state machine
+ */
+static void init_read_state_machine(SSL *s)
+{
+    OSSL_STATEM *st = &s->statem;
+
+    st->read_state = READ_STATE_HEADER;
+}
+
+static int grow_init_buf(SSL *s, size_t size) {
+
+    size_t msg_offset = (char *)s->init_msg - s->init_buf->data;
+
+    if (!BUF_MEM_grow_clean(s->init_buf, (int)size))
+        return 0;
+
+    if (size < msg_offset)
+        return 0;
+
+    s->init_msg = s->init_buf->data + msg_offset;
+
+    return 1;
+}
+
+/*
+ * This function implements the sub-state machine when the message flow is in
+ * MSG_FLOW_READING. The valid sub-states and transitions are:
+ *
+ * READ_STATE_HEADER <--+<-------------+
+ *        |             |              |
+ *        v             |              |
+ * READ_STATE_BODY -----+-->READ_STATE_POST_PROCESS
+ *        |                            |
+ *        +----------------------------+
+ *        v
+ * [SUB_STATE_FINISHED]
+ *
+ * READ_STATE_HEADER has the responsibility for reading in the message header
+ * and transitioning the state of the handshake state machine.
+ *
+ * READ_STATE_BODY reads in the rest of the message and then subsequently
+ * processes it.
+ *
+ * READ_STATE_POST_PROCESS is an optional step that may occur if some post
+ * processing activity performed on the message may block.
+ *
+ * Any of the above states could result in an NBIO event occurring in which case
+ * control returns to the calling application. When this function is recalled we
+ * will resume in the same state where we left off.
+ */
+static SUB_STATE_RETURN read_state_machine(SSL *s)
+{
+    OSSL_STATEM *st = &s->statem;
+    int ret, mt;
+    unsigned long len = 0;
+    int (*transition) (SSL *s, int mt);
+    PACKET pkt;
+    MSG_PROCESS_RETURN(*process_message) (SSL *s, PACKET *pkt);
+    WORK_STATE(*post_process_message) (SSL *s, WORK_STATE wst);
+    unsigned long (*max_message_size) (SSL *s);
+    void (*cb) (const SSL *ssl, int type, int val) = NULL;
+
+    cb = get_callback(s);
+
+    if (s->server) {
+        transition = ossl_statem_server_read_transition;
+        process_message = ossl_statem_server_process_message;
+        max_message_size = ossl_statem_server_max_message_size;
+        post_process_message = ossl_statem_server_post_process_message;
+    } else {
+        transition = ossl_statem_client_read_transition;
+        process_message = ossl_statem_client_process_message;
+        max_message_size = ossl_statem_client_max_message_size;
+        post_process_message = ossl_statem_client_post_process_message;
+    }
+
+    if (st->read_state_first_init) {
+        s->first_packet = 1;
+        st->read_state_first_init = 0;
+    }
+
+    while (1) {
+        switch (st->read_state) {
+        case READ_STATE_HEADER:
+            /* Get the state the peer wants to move to */
+            if (SSL_IS_DTLS(s)) {
+                /*
+                 * In DTLS we get the whole message in one go - header and body
+                 */
+                ret = dtls_get_message(s, &mt, &len);
+            } else {
+                ret = tls_get_message_header(s, &mt);
+            }
+
+            if (ret == 0) {
+                /* Could be non-blocking IO */
+                return SUB_STATE_ERROR;
+            }
+
+            if (cb != NULL) {
+                /* Notify callback of an impending state change */
+                if (s->server)
+                    cb(s, SSL_CB_ACCEPT_LOOP, 1);
+                else
+                    cb(s, SSL_CB_CONNECT_LOOP, 1);
+            }
+            /*
+             * Validate that we are allowed to move to the new state and move
+             * to that state if so
+             */
+            if (!transition(s, mt)) {
+                ossl_statem_set_error(s);
+                return SUB_STATE_ERROR;
+            }
+
+            if (s->s3->tmp.message_size > max_message_size(s)) {
+                ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+                SSLerr(SSL_F_READ_STATE_MACHINE, SSL_R_EXCESSIVE_MESSAGE_SIZE);
+                return SUB_STATE_ERROR;
+            }
+
+            /* dtls_get_message already did this */
+            if (!SSL_IS_DTLS(s)
+                    && s->s3->tmp.message_size > 0
+                    && !grow_init_buf(s, s->s3->tmp.message_size
+                                         + SSL3_HM_HEADER_LENGTH)) {
+                ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+                SSLerr(SSL_F_READ_STATE_MACHINE, ERR_R_BUF_LIB);
+                return SUB_STATE_ERROR;
+            }
+
+            st->read_state = READ_STATE_BODY;
+            /* Fall through */
+
+        case READ_STATE_BODY:
+            if (!SSL_IS_DTLS(s)) {
+                /* We already got this above for DTLS */
+                ret = tls_get_message_body(s, &len);
+                if (ret == 0) {
+                    /* Could be non-blocking IO */
+                    return SUB_STATE_ERROR;
+                }
+            }
+
+            s->first_packet = 0;
+            if (!PACKET_buf_init(&pkt, s->init_msg, len)) {
+                ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+                SSLerr(SSL_F_READ_STATE_MACHINE, ERR_R_INTERNAL_ERROR);
+                return SUB_STATE_ERROR;
+            }
+            ret = process_message(s, &pkt);
+
+            /* Discard the packet data */
+            s->init_num = 0;
+
+            switch (ret) {
+            case MSG_PROCESS_ERROR:
+                return SUB_STATE_ERROR;
+
+            case MSG_PROCESS_FINISHED_READING:
+                if (SSL_IS_DTLS(s)) {
+                    dtls1_stop_timer(s);
+                }
+                return SUB_STATE_FINISHED;
+
+            case MSG_PROCESS_CONTINUE_PROCESSING:
+                st->read_state = READ_STATE_POST_PROCESS;
+                st->read_state_work = WORK_MORE_A;
+                break;
+
+            default:
+                st->read_state = READ_STATE_HEADER;
+                break;
+            }
+            break;
+
+        case READ_STATE_POST_PROCESS:
+            st->read_state_work = post_process_message(s, st->read_state_work);
+            switch (st->read_state_work) {
+            default:
+                return SUB_STATE_ERROR;
+
+            case WORK_FINISHED_CONTINUE:
+                st->read_state = READ_STATE_HEADER;
+                break;
+
+            case WORK_FINISHED_STOP:
+                if (SSL_IS_DTLS(s)) {
+                    dtls1_stop_timer(s);
+                }
+                return SUB_STATE_FINISHED;
+            }
+            break;
+
+        default:
+            /* Shouldn't happen */
+            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+            SSLerr(SSL_F_READ_STATE_MACHINE, ERR_R_INTERNAL_ERROR);
+            ossl_statem_set_error(s);
+            return SUB_STATE_ERROR;
+        }
+    }
+}
+
+/*
+ * Send a previously constructed message to the peer.
+ */
+static int statem_do_write(SSL *s)
+{
+    OSSL_STATEM *st = &s->statem;
+
+    if (st->hand_state == TLS_ST_CW_CHANGE
+        || st->hand_state == TLS_ST_SW_CHANGE) {
+        if (SSL_IS_DTLS(s))
+            return dtls1_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC);
+        else
+            return ssl3_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC);
+    } else {
+        return ssl_do_write(s);
+    }
+}
+
+/*
+ * Initialise the MSG_FLOW_WRITING sub-state machine
+ */
+static void init_write_state_machine(SSL *s)
+{
+    OSSL_STATEM *st = &s->statem;
+
+    st->write_state = WRITE_STATE_TRANSITION;
+}
+
+/*
+ * This function implements the sub-state machine when the message flow is in
+ * MSG_FLOW_WRITING. The valid sub-states and transitions are:
+ *
+ * +-> WRITE_STATE_TRANSITION ------> [SUB_STATE_FINISHED]
+ * |             |
+ * |             v
+ * |      WRITE_STATE_PRE_WORK -----> [SUB_STATE_END_HANDSHAKE]
+ * |             |
+ * |             v
+ * |       WRITE_STATE_SEND
+ * |             |
+ * |             v
+ * |     WRITE_STATE_POST_WORK
+ * |             |
+ * +-------------+
+ *
+ * WRITE_STATE_TRANSITION transitions the state of the handshake state machine
+
+ * WRITE_STATE_PRE_WORK performs any work necessary to prepare the later
+ * sending of the message. This could result in an NBIO event occurring in
+ * which case control returns to the calling application. When this function
+ * is recalled we will resume in the same state where we left off.
+ *
+ * WRITE_STATE_SEND sends the message and performs any work to be done after
+ * sending.
+ *
+ * WRITE_STATE_POST_WORK performs any work necessary after the sending of the
+ * message has been completed. As for WRITE_STATE_PRE_WORK this could also
+ * result in an NBIO event.
+ */
+static SUB_STATE_RETURN write_state_machine(SSL *s)
+{
+    OSSL_STATEM *st = &s->statem;
+    int ret;
+    WRITE_TRAN(*transition) (SSL *s);
+    WORK_STATE(*pre_work) (SSL *s, WORK_STATE wst);
+    WORK_STATE(*post_work) (SSL *s, WORK_STATE wst);
+    int (*construct_message) (SSL *s);
+    void (*cb) (const SSL *ssl, int type, int val) = NULL;
+
+    cb = get_callback(s);
+
+    if (s->server) {
+        transition = ossl_statem_server_write_transition;
+        pre_work = ossl_statem_server_pre_work;
+        post_work = ossl_statem_server_post_work;
+        construct_message = ossl_statem_server_construct_message;
+    } else {
+        transition = ossl_statem_client_write_transition;
+        pre_work = ossl_statem_client_pre_work;
+        post_work = ossl_statem_client_post_work;
+        construct_message = ossl_statem_client_construct_message;
+    }
+
+    while (1) {
+        switch (st->write_state) {
+        case WRITE_STATE_TRANSITION:
+            if (cb != NULL) {
+                /* Notify callback of an impending state change */
+                if (s->server)
+                    cb(s, SSL_CB_ACCEPT_LOOP, 1);
+                else
+                    cb(s, SSL_CB_CONNECT_LOOP, 1);
+            }
+            switch (transition(s)) {
+            case WRITE_TRAN_CONTINUE:
+                st->write_state = WRITE_STATE_PRE_WORK;
+                st->write_state_work = WORK_MORE_A;
+                break;
+
+            case WRITE_TRAN_FINISHED:
+                return SUB_STATE_FINISHED;
+                break;
+
+            default:
+                return SUB_STATE_ERROR;
+            }
+            break;
+
+        case WRITE_STATE_PRE_WORK:
+            switch (st->write_state_work = pre_work(s, st->write_state_work)) {
+            default:
+                return SUB_STATE_ERROR;
+
+            case WORK_FINISHED_CONTINUE:
+                st->write_state = WRITE_STATE_SEND;
+                break;
+
+            case WORK_FINISHED_STOP:
+                return SUB_STATE_END_HANDSHAKE;
+            }
+            if (construct_message(s) == 0)
+                return SUB_STATE_ERROR;
+
+            /* Fall through */
+
+        case WRITE_STATE_SEND:
+            if (SSL_IS_DTLS(s) && st->use_timer) {
+                dtls1_start_timer(s);
+            }
+            ret = statem_do_write(s);
+            if (ret <= 0) {
+                return SUB_STATE_ERROR;
+            }
+            st->write_state = WRITE_STATE_POST_WORK;
+            st->write_state_work = WORK_MORE_A;
+            /* Fall through */
+
+        case WRITE_STATE_POST_WORK:
+            switch (st->write_state_work = post_work(s, st->write_state_work)) {
+            default:
+                return SUB_STATE_ERROR;
+
+            case WORK_FINISHED_CONTINUE:
+                st->write_state = WRITE_STATE_TRANSITION;
+                break;
+
+            case WORK_FINISHED_STOP:
+                return SUB_STATE_END_HANDSHAKE;
+            }
+            break;
+
+        default:
+            return SUB_STATE_ERROR;
+        }
+    }
+}
+
+/*
+ * Flush the write BIO
+ */
+int statem_flush(SSL *s)
+{
+    s->rwstate = SSL_WRITING;
+    if (BIO_flush(s->wbio) <= 0) {
+        return 0;
+    }
+    s->rwstate = SSL_NOTHING;
+
+    return 1;
+}
+
+/*
+ * Called by the record layer to determine whether application data is
+ * allowed to be sent in the current handshake state or not.
+ *
+ * Return values are:
+ *   1: Yes (application data allowed)
+ *   0: No (application data not allowed)
+ */
+int ossl_statem_app_data_allowed(SSL *s)
+{
+    OSSL_STATEM *st = &s->statem;
+
+    if (st->state == MSG_FLOW_UNINITED || st->state == MSG_FLOW_RENEGOTIATE)
+        return 0;
+
+    if (!s->s3->in_read_app_data || (s->s3->total_renegotiations == 0))
+        return 0;
+
+    if (s->server) {
+        /*
+         * If we're a server and we haven't got as far as writing our
+         * ServerHello yet then we allow app data
+         */
+        if (st->hand_state == TLS_ST_BEFORE
+            || st->hand_state == TLS_ST_SR_CLNT_HELLO)
+            return 1;
+    } else {
+        /*
+         * If we're a client and we haven't read the ServerHello yet then we
+         * allow app data
+         */
+        if (st->hand_state == TLS_ST_CW_CLNT_HELLO)
+            return 1;
+    }
+
+    return 0;
+}
+
+#ifndef OPENSSL_NO_SCTP
+/*
+ * Set flag used by SCTP to determine whether we are in the read sock state
+ */
+void ossl_statem_set_sctp_read_sock(SSL *s, int read_sock)
+{
+    s->statem.in_sctp_read_sock = read_sock;
+}
+
+/*
+ * Called by the record layer to determine whether we are in the read sock
+ * state or not.
+ *
+ * Return values are:
+ *   1: Yes (we are in the read sock state)
+ *   0: No (we are not in the read sock state)
+ */
+int ossl_statem_in_sctp_read_sock(SSL *s)
+{
+    return s->statem.in_sctp_read_sock;
+}
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem.h	(revision 331)
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2015-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
+ */
+
+/*****************************************************************************
+ *                                                                           *
+ * These enums should be considered PRIVATE to the state machine. No         *
+ * non-state machine code should need to use these                           *
+ *                                                                           *
+ *****************************************************************************/
+/*
+ * Valid return codes used for functions performing work prior to or after
+ * sending or receiving a message
+ */
+typedef enum {
+    /* Something went wrong */
+    WORK_ERROR,
+    /* We're done working and there shouldn't be anything else to do after */
+    WORK_FINISHED_STOP,
+    /* We're done working move onto the next thing */
+    WORK_FINISHED_CONTINUE,
+    /* We're working on phase A */
+    WORK_MORE_A,
+    /* We're working on phase B */
+    WORK_MORE_B
+} WORK_STATE;
+
+/* Write transition return codes */
+typedef enum {
+    /* Something went wrong */
+    WRITE_TRAN_ERROR,
+    /* A transition was successfully completed and we should continue */
+    WRITE_TRAN_CONTINUE,
+    /* There is no more write work to be done */
+    WRITE_TRAN_FINISHED
+} WRITE_TRAN;
+
+/* Message flow states */
+typedef enum {
+    /* No handshake in progress */
+    MSG_FLOW_UNINITED,
+    /* A permanent error with this connection */
+    MSG_FLOW_ERROR,
+    /* We are about to renegotiate */
+    MSG_FLOW_RENEGOTIATE,
+    /* We are reading messages */
+    MSG_FLOW_READING,
+    /* We are writing messages */
+    MSG_FLOW_WRITING,
+    /* Handshake has finished */
+    MSG_FLOW_FINISHED
+} MSG_FLOW_STATE;
+
+/* Read states */
+typedef enum {
+    READ_STATE_HEADER,
+    READ_STATE_BODY,
+    READ_STATE_POST_PROCESS
+} READ_STATE;
+
+/* Write states */
+typedef enum {
+    WRITE_STATE_TRANSITION,
+    WRITE_STATE_PRE_WORK,
+    WRITE_STATE_SEND,
+    WRITE_STATE_POST_WORK
+} WRITE_STATE;
+
+/*****************************************************************************
+ *                                                                           *
+ * This structure should be considered "opaque" to anything outside of the   *
+ * state machine. No non-state machine code should be accessing the members  *
+ * of this structure.                                                        *
+ *                                                                           *
+ *****************************************************************************/
+
+struct ossl_statem_st {
+    MSG_FLOW_STATE state;
+    WRITE_STATE write_state;
+    WORK_STATE write_state_work;
+    READ_STATE read_state;
+    WORK_STATE read_state_work;
+    OSSL_HANDSHAKE_STATE hand_state;
+    int in_init;
+    int read_state_first_init;
+    /* true when we are actually in SSL_accept() or SSL_connect() */
+    int in_handshake;
+    /* Should we skip the CertificateVerify message? */
+    unsigned int no_cert_verify;
+    int use_timer;
+#ifndef OPENSSL_NO_SCTP
+    int in_sctp_read_sock;
+#endif
+};
+typedef struct ossl_statem_st OSSL_STATEM;
+
+/*****************************************************************************
+ *                                                                           *
+ * The following macros/functions represent the libssl internal API to the   *
+ * state machine. Any libssl code may call these functions/macros            *
+ *                                                                           *
+ *****************************************************************************/
+
+__owur int ossl_statem_accept(SSL *s);
+__owur int ossl_statem_connect(SSL *s);
+void ossl_statem_clear(SSL *s);
+void ossl_statem_set_renegotiate(SSL *s);
+void ossl_statem_set_error(SSL *s);
+int ossl_statem_in_error(const SSL *s);
+void ossl_statem_set_in_init(SSL *s, int init);
+int ossl_statem_get_in_handshake(SSL *s);
+void ossl_statem_set_in_handshake(SSL *s, int inhand);
+void ossl_statem_set_hello_verify_done(SSL *s);
+__owur int ossl_statem_app_data_allowed(SSL *s);
+#ifndef OPENSSL_NO_SCTP
+void ossl_statem_set_sctp_read_sock(SSL *s, int read_sock);
+__owur int ossl_statem_in_sctp_read_sock(SSL *s);
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem_clnt.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem_clnt.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem_clnt.c	(revision 331)
@@ -0,0 +1,2971 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * ECC cipher suite support in OpenSSL originally written by
+ * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <stdio.h>
+#include "../ssl_locl.h"
+#include "statem_locl.h"
+#include <openssl/buffer.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/md5.h>
+#include <openssl/dh.h>
+#include <openssl/bn.h>
+#include <openssl/engine.h>
+
+static ossl_inline int cert_req_allowed(SSL *s);
+static int key_exchange_expected(SSL *s);
+static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b);
+static int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk,
+                                    unsigned char *p);
+
+/*
+ * Is a CertificateRequest message allowed at the moment or not?
+ *
+ *  Return values are:
+ *  1: Yes
+ *  0: No
+ */
+static ossl_inline int cert_req_allowed(SSL *s)
+{
+    /* TLS does not like anon-DH with client cert */
+    if ((s->version > SSL3_VERSION
+         && (s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL))
+        || (s->s3->tmp.new_cipher->algorithm_auth & (SSL_aSRP | SSL_aPSK)))
+        return 0;
+
+    return 1;
+}
+
+/*
+ * Should we expect the ServerKeyExchange message or not?
+ *
+ *  Return values are:
+ *  1: Yes
+ *  0: No
+ */
+static int key_exchange_expected(SSL *s)
+{
+    long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+
+    /*
+     * Can't skip server key exchange if this is an ephemeral
+     * ciphersuite or for SRP
+     */
+    if (alg_k & (SSL_kDHE | SSL_kECDHE | SSL_kDHEPSK | SSL_kECDHEPSK
+                 | SSL_kSRP)) {
+        return 1;
+    }
+
+    return 0;
+}
+
+/*
+ * ossl_statem_client_read_transition() encapsulates the logic for the allowed
+ * handshake state transitions when the client is reading messages from the
+ * server. The message type that the server has sent is provided in |mt|. The
+ * current state is in |s->statem.hand_state|.
+ *
+ *  Return values are:
+ *  1: Success (transition allowed)
+ *  0: Error (transition not allowed)
+ */
+int ossl_statem_client_read_transition(SSL *s, int mt)
+{
+    OSSL_STATEM *st = &s->statem;
+    int ske_expected;
+
+    switch (st->hand_state) {
+    case TLS_ST_CW_CLNT_HELLO:
+        if (mt == SSL3_MT_SERVER_HELLO) {
+            st->hand_state = TLS_ST_CR_SRVR_HELLO;
+            return 1;
+        }
+
+        if (SSL_IS_DTLS(s)) {
+            if (mt == DTLS1_MT_HELLO_VERIFY_REQUEST) {
+                st->hand_state = DTLS_ST_CR_HELLO_VERIFY_REQUEST;
+                return 1;
+            }
+        }
+        break;
+
+    case TLS_ST_CR_SRVR_HELLO:
+        if (s->hit) {
+            if (s->tlsext_ticket_expected) {
+                if (mt == SSL3_MT_NEWSESSION_TICKET) {
+                    st->hand_state = TLS_ST_CR_SESSION_TICKET;
+                    return 1;
+                }
+            } else if (mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
+                st->hand_state = TLS_ST_CR_CHANGE;
+                return 1;
+            }
+        } else {
+            if (SSL_IS_DTLS(s) && mt == DTLS1_MT_HELLO_VERIFY_REQUEST) {
+                st->hand_state = DTLS_ST_CR_HELLO_VERIFY_REQUEST;
+                return 1;
+            } else if (s->version >= TLS1_VERSION
+                       && s->tls_session_secret_cb != NULL
+                       && s->session->tlsext_tick != NULL
+                       && mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
+                /*
+                 * Normally, we can tell if the server is resuming the session
+                 * from the session ID. EAP-FAST (RFC 4851), however, relies on
+                 * the next server message after the ServerHello to determine if
+                 * the server is resuming.
+                 */
+                s->hit = 1;
+                st->hand_state = TLS_ST_CR_CHANGE;
+                return 1;
+            } else if (!(s->s3->tmp.new_cipher->algorithm_auth
+                         & (SSL_aNULL | SSL_aSRP | SSL_aPSK))) {
+                if (mt == SSL3_MT_CERTIFICATE) {
+                    st->hand_state = TLS_ST_CR_CERT;
+                    return 1;
+                }
+            } else {
+                ske_expected = key_exchange_expected(s);
+                /* SKE is optional for some PSK ciphersuites */
+                if (ske_expected
+                    || ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK)
+                        && mt == SSL3_MT_SERVER_KEY_EXCHANGE)) {
+                    if (mt == SSL3_MT_SERVER_KEY_EXCHANGE) {
+                        st->hand_state = TLS_ST_CR_KEY_EXCH;
+                        return 1;
+                    }
+                } else if (mt == SSL3_MT_CERTIFICATE_REQUEST
+                           && cert_req_allowed(s)) {
+                    st->hand_state = TLS_ST_CR_CERT_REQ;
+                    return 1;
+                } else if (mt == SSL3_MT_SERVER_DONE) {
+                    st->hand_state = TLS_ST_CR_SRVR_DONE;
+                    return 1;
+                }
+            }
+        }
+        break;
+
+    case TLS_ST_CR_CERT:
+        /*
+         * The CertificateStatus message is optional even if
+         * |tlsext_status_expected| is set
+         */
+        if (s->tlsext_status_expected && mt == SSL3_MT_CERTIFICATE_STATUS) {
+            st->hand_state = TLS_ST_CR_CERT_STATUS;
+            return 1;
+        }
+        /* Fall through */
+
+    case TLS_ST_CR_CERT_STATUS:
+        ske_expected = key_exchange_expected(s);
+        /* SKE is optional for some PSK ciphersuites */
+        if (ske_expected || ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK)
+                             && mt == SSL3_MT_SERVER_KEY_EXCHANGE)) {
+            if (mt == SSL3_MT_SERVER_KEY_EXCHANGE) {
+                st->hand_state = TLS_ST_CR_KEY_EXCH;
+                return 1;
+            }
+            goto err;
+        }
+        /* Fall through */
+
+    case TLS_ST_CR_KEY_EXCH:
+        if (mt == SSL3_MT_CERTIFICATE_REQUEST) {
+            if (cert_req_allowed(s)) {
+                st->hand_state = TLS_ST_CR_CERT_REQ;
+                return 1;
+            }
+            goto err;
+        }
+        /* Fall through */
+
+    case TLS_ST_CR_CERT_REQ:
+        if (mt == SSL3_MT_SERVER_DONE) {
+            st->hand_state = TLS_ST_CR_SRVR_DONE;
+            return 1;
+        }
+        break;
+
+    case TLS_ST_CW_FINISHED:
+        if (s->tlsext_ticket_expected) {
+            if (mt == SSL3_MT_NEWSESSION_TICKET) {
+                st->hand_state = TLS_ST_CR_SESSION_TICKET;
+                return 1;
+            }
+        } else if (mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
+            st->hand_state = TLS_ST_CR_CHANGE;
+            return 1;
+        }
+        break;
+
+    case TLS_ST_CR_SESSION_TICKET:
+        if (mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
+            st->hand_state = TLS_ST_CR_CHANGE;
+            return 1;
+        }
+        break;
+
+    case TLS_ST_CR_CHANGE:
+        if (mt == SSL3_MT_FINISHED) {
+            st->hand_state = TLS_ST_CR_FINISHED;
+            return 1;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+ err:
+    /* No valid transition found */
+    ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_UNEXPECTED_MESSAGE);
+    SSLerr(SSL_F_OSSL_STATEM_CLIENT_READ_TRANSITION, SSL_R_UNEXPECTED_MESSAGE);
+    return 0;
+}
+
+/*
+ * client_write_transition() works out what handshake state to move to next
+ * when the client is writing messages to be sent to the server.
+ */
+WRITE_TRAN ossl_statem_client_write_transition(SSL *s)
+{
+    OSSL_STATEM *st = &s->statem;
+
+    switch (st->hand_state) {
+    case TLS_ST_OK:
+        /* Renegotiation - fall through */
+    case TLS_ST_BEFORE:
+        st->hand_state = TLS_ST_CW_CLNT_HELLO;
+        return WRITE_TRAN_CONTINUE;
+
+    case TLS_ST_CW_CLNT_HELLO:
+        /*
+         * No transition at the end of writing because we don't know what
+         * we will be sent
+         */
+        return WRITE_TRAN_FINISHED;
+
+    case DTLS_ST_CR_HELLO_VERIFY_REQUEST:
+        st->hand_state = TLS_ST_CW_CLNT_HELLO;
+        return WRITE_TRAN_CONTINUE;
+
+    case TLS_ST_CR_SRVR_DONE:
+        if (s->s3->tmp.cert_req)
+            st->hand_state = TLS_ST_CW_CERT;
+        else
+            st->hand_state = TLS_ST_CW_KEY_EXCH;
+        return WRITE_TRAN_CONTINUE;
+
+    case TLS_ST_CW_CERT:
+        st->hand_state = TLS_ST_CW_KEY_EXCH;
+        return WRITE_TRAN_CONTINUE;
+
+    case TLS_ST_CW_KEY_EXCH:
+        /*
+         * For TLS, cert_req is set to 2, so a cert chain of nothing is
+         * sent, but no verify packet is sent
+         */
+        /*
+         * XXX: For now, we do not support client authentication in ECDH
+         * cipher suites with ECDH (rather than ECDSA) certificates. We
+         * need to skip the certificate verify message when client's
+         * ECDH public key is sent inside the client certificate.
+         */
+        if (s->s3->tmp.cert_req == 1) {
+            st->hand_state = TLS_ST_CW_CERT_VRFY;
+        } else {
+            st->hand_state = TLS_ST_CW_CHANGE;
+        }
+        if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) {
+            st->hand_state = TLS_ST_CW_CHANGE;
+        }
+        return WRITE_TRAN_CONTINUE;
+
+    case TLS_ST_CW_CERT_VRFY:
+        st->hand_state = TLS_ST_CW_CHANGE;
+        return WRITE_TRAN_CONTINUE;
+
+    case TLS_ST_CW_CHANGE:
+#if defined(OPENSSL_NO_NEXTPROTONEG)
+        st->hand_state = TLS_ST_CW_FINISHED;
+#else
+        if (!SSL_IS_DTLS(s) && s->s3->next_proto_neg_seen)
+            st->hand_state = TLS_ST_CW_NEXT_PROTO;
+        else
+            st->hand_state = TLS_ST_CW_FINISHED;
+#endif
+        return WRITE_TRAN_CONTINUE;
+
+#if !defined(OPENSSL_NO_NEXTPROTONEG)
+    case TLS_ST_CW_NEXT_PROTO:
+        st->hand_state = TLS_ST_CW_FINISHED;
+        return WRITE_TRAN_CONTINUE;
+#endif
+
+    case TLS_ST_CW_FINISHED:
+        if (s->hit) {
+            st->hand_state = TLS_ST_OK;
+            ossl_statem_set_in_init(s, 0);
+            return WRITE_TRAN_CONTINUE;
+        } else {
+            return WRITE_TRAN_FINISHED;
+        }
+
+    case TLS_ST_CR_FINISHED:
+        if (s->hit) {
+            st->hand_state = TLS_ST_CW_CHANGE;
+            return WRITE_TRAN_CONTINUE;
+        } else {
+            st->hand_state = TLS_ST_OK;
+            ossl_statem_set_in_init(s, 0);
+            return WRITE_TRAN_CONTINUE;
+        }
+
+    default:
+        /* Shouldn't happen */
+        return WRITE_TRAN_ERROR;
+    }
+}
+
+/*
+ * Perform any pre work that needs to be done prior to sending a message from
+ * the client to the server.
+ */
+WORK_STATE ossl_statem_client_pre_work(SSL *s, WORK_STATE wst)
+{
+    OSSL_STATEM *st = &s->statem;
+
+    switch (st->hand_state) {
+    case TLS_ST_CW_CLNT_HELLO:
+        s->shutdown = 0;
+        if (SSL_IS_DTLS(s)) {
+            /* every DTLS ClientHello resets Finished MAC */
+            if (!ssl3_init_finished_mac(s)) {
+                ossl_statem_set_error(s);
+                return WORK_ERROR;
+            }
+        }
+        break;
+
+    case TLS_ST_CW_CHANGE:
+        if (SSL_IS_DTLS(s)) {
+            if (s->hit) {
+                /*
+                 * We're into the last flight so we don't retransmit these
+                 * messages unless we need to.
+                 */
+                st->use_timer = 0;
+            }
+#ifndef OPENSSL_NO_SCTP
+            if (BIO_dgram_is_sctp(SSL_get_wbio(s)))
+                return dtls_wait_for_dry(s);
+#endif
+        }
+        return WORK_FINISHED_CONTINUE;
+
+    case TLS_ST_OK:
+        return tls_finish_handshake(s, wst);
+
+    default:
+        /* No pre work to be done */
+        break;
+    }
+
+    return WORK_FINISHED_CONTINUE;
+}
+
+/*
+ * Perform any work that needs to be done after sending a message from the
+ * client to the server.
+ */
+WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst)
+{
+    OSSL_STATEM *st = &s->statem;
+
+    s->init_num = 0;
+
+    switch (st->hand_state) {
+    case TLS_ST_CW_CLNT_HELLO:
+        if (wst == WORK_MORE_A && statem_flush(s) != 1)
+            return WORK_MORE_A;
+
+        if (SSL_IS_DTLS(s)) {
+            /* Treat the next message as the first packet */
+            s->first_packet = 1;
+        }
+        break;
+
+    case TLS_ST_CW_KEY_EXCH:
+        if (tls_client_key_exchange_post_work(s) == 0)
+            return WORK_ERROR;
+        break;
+
+    case TLS_ST_CW_CHANGE:
+        s->session->cipher = s->s3->tmp.new_cipher;
+#ifdef OPENSSL_NO_COMP
+        s->session->compress_meth = 0;
+#else
+        if (s->s3->tmp.new_compression == NULL)
+            s->session->compress_meth = 0;
+        else
+            s->session->compress_meth = s->s3->tmp.new_compression->id;
+#endif
+        if (!s->method->ssl3_enc->setup_key_block(s))
+            return WORK_ERROR;
+
+        if (!s->method->ssl3_enc->change_cipher_state(s,
+                                                      SSL3_CHANGE_CIPHER_CLIENT_WRITE))
+            return WORK_ERROR;
+
+        if (SSL_IS_DTLS(s)) {
+#ifndef OPENSSL_NO_SCTP
+            if (s->hit) {
+                /*
+                 * Change to new shared key of SCTP-Auth, will be ignored if
+                 * no SCTP used.
+                 */
+                BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY,
+                         0, NULL);
+            }
+#endif
+
+            dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);
+        }
+        break;
+
+    case TLS_ST_CW_FINISHED:
+#ifndef OPENSSL_NO_SCTP
+        if (wst == WORK_MORE_A && SSL_IS_DTLS(s) && s->hit == 0) {
+            /*
+             * Change to new shared key of SCTP-Auth, will be ignored if
+             * no SCTP used.
+             */
+            BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY,
+                     0, NULL);
+        }
+#endif
+        if (statem_flush(s) != 1)
+            return WORK_MORE_B;
+        break;
+
+    default:
+        /* No post work to be done */
+        break;
+    }
+
+    return WORK_FINISHED_CONTINUE;
+}
+
+/*
+ * Construct a message to be sent from the client to the server.
+ *
+ * Valid return values are:
+ *   1: Success
+ *   0: Error
+ */
+int ossl_statem_client_construct_message(SSL *s)
+{
+    OSSL_STATEM *st = &s->statem;
+
+    switch (st->hand_state) {
+    case TLS_ST_CW_CLNT_HELLO:
+        return tls_construct_client_hello(s);
+
+    case TLS_ST_CW_CERT:
+        return tls_construct_client_certificate(s);
+
+    case TLS_ST_CW_KEY_EXCH:
+        return tls_construct_client_key_exchange(s);
+
+    case TLS_ST_CW_CERT_VRFY:
+        return tls_construct_client_verify(s);
+
+    case TLS_ST_CW_CHANGE:
+        if (SSL_IS_DTLS(s))
+            return dtls_construct_change_cipher_spec(s);
+        else
+            return tls_construct_change_cipher_spec(s);
+
+#if !defined(OPENSSL_NO_NEXTPROTONEG)
+    case TLS_ST_CW_NEXT_PROTO:
+        return tls_construct_next_proto(s);
+#endif
+    case TLS_ST_CW_FINISHED:
+        return tls_construct_finished(s,
+                                      s->method->
+                                      ssl3_enc->client_finished_label,
+                                      s->method->
+                                      ssl3_enc->client_finished_label_len);
+
+    default:
+        /* Shouldn't happen */
+        break;
+    }
+
+    return 0;
+}
+
+/*
+ * Returns the maximum allowed length for the current message that we are
+ * reading. Excludes the message header.
+ */
+unsigned long ossl_statem_client_max_message_size(SSL *s)
+{
+    OSSL_STATEM *st = &s->statem;
+
+    switch (st->hand_state) {
+    case TLS_ST_CR_SRVR_HELLO:
+        return SERVER_HELLO_MAX_LENGTH;
+
+    case DTLS_ST_CR_HELLO_VERIFY_REQUEST:
+        return HELLO_VERIFY_REQUEST_MAX_LENGTH;
+
+    case TLS_ST_CR_CERT:
+        return s->max_cert_list;
+
+    case TLS_ST_CR_CERT_STATUS:
+        return SSL3_RT_MAX_PLAIN_LENGTH;
+
+    case TLS_ST_CR_KEY_EXCH:
+        return SERVER_KEY_EXCH_MAX_LENGTH;
+
+    case TLS_ST_CR_CERT_REQ:
+        /*
+         * Set to s->max_cert_list for compatibility with previous releases. In
+         * practice these messages can get quite long if servers are configured
+         * to provide a long list of acceptable CAs
+         */
+        return s->max_cert_list;
+
+    case TLS_ST_CR_SRVR_DONE:
+        return SERVER_HELLO_DONE_MAX_LENGTH;
+
+    case TLS_ST_CR_CHANGE:
+        if (s->version == DTLS1_BAD_VER)
+            return 3;
+        return CCS_MAX_LENGTH;
+
+    case TLS_ST_CR_SESSION_TICKET:
+        return SSL3_RT_MAX_PLAIN_LENGTH;
+
+    case TLS_ST_CR_FINISHED:
+        return FINISHED_MAX_LENGTH;
+
+    default:
+        /* Shouldn't happen */
+        break;
+    }
+
+    return 0;
+}
+
+/*
+ * Process a message that the client has been received from the server.
+ */
+MSG_PROCESS_RETURN ossl_statem_client_process_message(SSL *s, PACKET *pkt)
+{
+    OSSL_STATEM *st = &s->statem;
+
+    switch (st->hand_state) {
+    case TLS_ST_CR_SRVR_HELLO:
+        return tls_process_server_hello(s, pkt);
+
+    case DTLS_ST_CR_HELLO_VERIFY_REQUEST:
+        return dtls_process_hello_verify(s, pkt);
+
+    case TLS_ST_CR_CERT:
+        return tls_process_server_certificate(s, pkt);
+
+    case TLS_ST_CR_CERT_STATUS:
+        return tls_process_cert_status(s, pkt);
+
+    case TLS_ST_CR_KEY_EXCH:
+        return tls_process_key_exchange(s, pkt);
+
+    case TLS_ST_CR_CERT_REQ:
+        return tls_process_certificate_request(s, pkt);
+
+    case TLS_ST_CR_SRVR_DONE:
+        return tls_process_server_done(s, pkt);
+
+    case TLS_ST_CR_CHANGE:
+        return tls_process_change_cipher_spec(s, pkt);
+
+    case TLS_ST_CR_SESSION_TICKET:
+        return tls_process_new_session_ticket(s, pkt);
+
+    case TLS_ST_CR_FINISHED:
+        return tls_process_finished(s, pkt);
+
+    default:
+        /* Shouldn't happen */
+        break;
+    }
+
+    return MSG_PROCESS_ERROR;
+}
+
+/*
+ * Perform any further processing required following the receipt of a message
+ * from the server
+ */
+WORK_STATE ossl_statem_client_post_process_message(SSL *s, WORK_STATE wst)
+{
+    OSSL_STATEM *st = &s->statem;
+
+    switch (st->hand_state) {
+    case TLS_ST_CR_CERT_REQ:
+        return tls_prepare_client_certificate(s, wst);
+
+#ifndef OPENSSL_NO_SCTP
+    case TLS_ST_CR_SRVR_DONE:
+        /* We only get here if we are using SCTP and we are renegotiating */
+        if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) {
+            s->s3->in_read_app_data = 2;
+            s->rwstate = SSL_READING;
+            BIO_clear_retry_flags(SSL_get_rbio(s));
+            BIO_set_retry_read(SSL_get_rbio(s));
+            ossl_statem_set_sctp_read_sock(s, 1);
+            return WORK_MORE_A;
+        }
+        ossl_statem_set_sctp_read_sock(s, 0);
+        return WORK_FINISHED_STOP;
+#endif
+
+    default:
+        break;
+    }
+
+    /* Shouldn't happen */
+    return WORK_ERROR;
+}
+
+int tls_construct_client_hello(SSL *s)
+{
+    unsigned char *buf;
+    unsigned char *p, *d;
+    int i;
+    int protverr;
+    unsigned long l;
+    int al = 0;
+#ifndef OPENSSL_NO_COMP
+    int j;
+    SSL_COMP *comp;
+#endif
+    SSL_SESSION *sess = s->session;
+
+    buf = (unsigned char *)s->init_buf->data;
+
+    /* Work out what SSL/TLS/DTLS version to use */
+    protverr = ssl_set_client_hello_version(s);
+    if (protverr != 0) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, protverr);
+        goto err;
+    }
+
+    if ((sess == NULL) || !ssl_version_supported(s, sess->ssl_version) ||
+        /*
+         * In the case of EAP-FAST, we can have a pre-shared
+         * "ticket" without a session ID.
+         */
+        (!sess->session_id_length && !sess->tlsext_tick) ||
+        (sess->not_resumable)) {
+        if (!ssl_get_new_session(s, 0))
+            goto err;
+    }
+    /* else use the pre-loaded session */
+
+    p = s->s3->client_random;
+
+    /*
+     * for DTLS if client_random is initialized, reuse it, we are
+     * required to use same upon reply to HelloVerify
+     */
+    if (SSL_IS_DTLS(s)) {
+        size_t idx;
+        i = 1;
+        for (idx = 0; idx < sizeof(s->s3->client_random); idx++) {
+            if (p[idx]) {
+                i = 0;
+                break;
+            }
+        }
+    } else
+        i = 1;
+
+    if (i && ssl_fill_hello_random(s, 0, p, sizeof(s->s3->client_random)) <= 0)
+        goto err;
+
+    /* Do the message type and length last */
+    d = p = ssl_handshake_start(s);
+
+    /*-
+     * version indicates the negotiated version: for example from
+     * an SSLv2/v3 compatible client hello). The client_version
+     * field is the maximum version we permit and it is also
+     * used in RSA encrypted premaster secrets. Some servers can
+     * choke if we initially report a higher version then
+     * renegotiate to a lower one in the premaster secret. This
+     * didn't happen with TLS 1.0 as most servers supported it
+     * but it can with TLS 1.1 or later if the server only supports
+     * 1.0.
+     *
+     * Possible scenario with previous logic:
+     *      1. Client hello indicates TLS 1.2
+     *      2. Server hello says TLS 1.0
+     *      3. RSA encrypted premaster secret uses 1.2.
+     *      4. Handshake proceeds using TLS 1.0.
+     *      5. Server sends hello request to renegotiate.
+     *      6. Client hello indicates TLS v1.0 as we now
+     *         know that is maximum server supports.
+     *      7. Server chokes on RSA encrypted premaster secret
+     *         containing version 1.0.
+     *
+     * For interoperability it should be OK to always use the
+     * maximum version we support in client hello and then rely
+     * on the checking of version to ensure the servers isn't
+     * being inconsistent: for example initially negotiating with
+     * TLS 1.0 and renegotiating with TLS 1.2. We do this by using
+     * client_version in client hello and not resetting it to
+     * the negotiated version.
+     */
+    *(p++) = s->client_version >> 8;
+    *(p++) = s->client_version & 0xff;
+
+    /* Random stuff */
+    memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE);
+    p += SSL3_RANDOM_SIZE;
+
+    /* Session ID */
+    if (s->new_session)
+        i = 0;
+    else
+        i = s->session->session_id_length;
+    *(p++) = i;
+    if (i != 0) {
+        if (i > (int)sizeof(s->session->session_id)) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+        memcpy(p, s->session->session_id, i);
+        p += i;
+    }
+
+    /* cookie stuff for DTLS */
+    if (SSL_IS_DTLS(s)) {
+        if (s->d1->cookie_len > sizeof(s->d1->cookie)) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+        *(p++) = s->d1->cookie_len;
+        memcpy(p, s->d1->cookie, s->d1->cookie_len);
+        p += s->d1->cookie_len;
+    }
+
+    /* Ciphers supported */
+    i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &(p[2]));
+    if (i == 0) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE);
+        goto err;
+    }
+#ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH
+    /*
+     * Some servers hang if client hello > 256 bytes as hack workaround
+     * chop number of supported ciphers to keep it well below this if we
+     * use TLS v1.2
+     */
+    if (TLS1_get_version(s) >= TLS1_2_VERSION
+        && i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH)
+        i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1;
+#endif
+    s2n(i, p);
+    p += i;
+
+    /* COMPRESSION */
+#ifdef OPENSSL_NO_COMP
+    *(p++) = 1;
+#else
+
+    if (!ssl_allow_compression(s) || !s->ctx->comp_methods)
+        j = 0;
+    else
+        j = sk_SSL_COMP_num(s->ctx->comp_methods);
+    *(p++) = 1 + j;
+    for (i = 0; i < j; i++) {
+        comp = sk_SSL_COMP_value(s->ctx->comp_methods, i);
+        *(p++) = comp->id;
+    }
+#endif
+    *(p++) = 0;                 /* Add the NULL method */
+
+    /* TLS extensions */
+    if (ssl_prepare_clienthello_tlsext(s) <= 0) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
+        goto err;
+    }
+    if ((p =
+         ssl_add_clienthello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH,
+                                    &al)) == NULL) {
+        ssl3_send_alert(s, SSL3_AL_FATAL, al);
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
+    l = p - d;
+    if (!ssl_set_handshake_header(s, SSL3_MT_CLIENT_HELLO, l)) {
+        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
+    return 1;
+ err:
+    ossl_statem_set_error(s);
+    return 0;
+}
+
+MSG_PROCESS_RETURN dtls_process_hello_verify(SSL *s, PACKET *pkt)
+{
+    int al;
+    unsigned int cookie_len;
+    PACKET cookiepkt;
+
+    if (!PACKET_forward(pkt, 2)
+        || !PACKET_get_length_prefixed_1(pkt, &cookiepkt)) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_DTLS_PROCESS_HELLO_VERIFY, SSL_R_LENGTH_MISMATCH);
+        goto f_err;
+    }
+
+    cookie_len = PACKET_remaining(&cookiepkt);
+    if (cookie_len > sizeof(s->d1->cookie)) {
+        al = SSL_AD_ILLEGAL_PARAMETER;
+        SSLerr(SSL_F_DTLS_PROCESS_HELLO_VERIFY, SSL_R_LENGTH_TOO_LONG);
+        goto f_err;
+    }
+
+    if (!PACKET_copy_bytes(&cookiepkt, s->d1->cookie, cookie_len)) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_DTLS_PROCESS_HELLO_VERIFY, SSL_R_LENGTH_MISMATCH);
+        goto f_err;
+    }
+    s->d1->cookie_len = cookie_len;
+
+    return MSG_PROCESS_FINISHED_READING;
+ f_err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    ossl_statem_set_error(s);
+    return MSG_PROCESS_ERROR;
+}
+
+MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt)
+{
+    STACK_OF(SSL_CIPHER) *sk;
+    const SSL_CIPHER *c;
+    PACKET session_id;
+    size_t session_id_len;
+    const unsigned char *cipherchars;
+    int i, al = SSL_AD_INTERNAL_ERROR;
+    unsigned int compression;
+    unsigned int sversion;
+    int protverr;
+#ifndef OPENSSL_NO_COMP
+    SSL_COMP *comp;
+#endif
+
+    if (!PACKET_get_net_2(pkt, &sversion)) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
+        goto f_err;
+    }
+
+    protverr = ssl_choose_client_version(s, sversion);
+    if (protverr != 0) {
+        al = SSL_AD_PROTOCOL_VERSION;
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, protverr);
+        goto f_err;
+    }
+
+    /* load the server hello data */
+    /* load the server random */
+    if (!PACKET_copy_bytes(pkt, s->s3->server_random, SSL3_RANDOM_SIZE)) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
+        goto f_err;
+    }
+
+    s->hit = 0;
+
+    /* Get the session-id. */
+    if (!PACKET_get_length_prefixed_1(pkt, &session_id)) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
+        goto f_err;
+    }
+    session_id_len = PACKET_remaining(&session_id);
+    if (session_id_len > sizeof s->session->session_id
+        || session_id_len > SSL3_SESSION_ID_SIZE) {
+        al = SSL_AD_ILLEGAL_PARAMETER;
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_SSL3_SESSION_ID_TOO_LONG);
+        goto f_err;
+    }
+
+    if (!PACKET_get_bytes(pkt, &cipherchars, TLS_CIPHER_LEN)) {
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
+        al = SSL_AD_DECODE_ERROR;
+        goto f_err;
+    }
+
+    /*
+     * Check if we can resume the session based on external pre-shared secret.
+     * EAP-FAST (RFC 4851) supports two types of session resumption.
+     * Resumption based on server-side state works with session IDs.
+     * Resumption based on pre-shared Protected Access Credentials (PACs)
+     * works by overriding the SessionTicket extension at the application
+     * layer, and does not send a session ID. (We do not know whether EAP-FAST
+     * servers would honour the session ID.) Therefore, the session ID alone
+     * is not a reliable indicator of session resumption, so we first check if
+     * we can resume, and later peek at the next handshake message to see if the
+     * server wants to resume.
+     */
+    if (s->version >= TLS1_VERSION && s->tls_session_secret_cb &&
+        s->session->tlsext_tick) {
+        const SSL_CIPHER *pref_cipher = NULL;
+        s->session->master_key_length = sizeof(s->session->master_key);
+        if (s->tls_session_secret_cb(s, s->session->master_key,
+                                     &s->session->master_key_length,
+                                     NULL, &pref_cipher,
+                                     s->tls_session_secret_cb_arg)) {
+            s->session->cipher = pref_cipher ?
+                pref_cipher : ssl_get_cipher_by_char(s, cipherchars);
+        } else {
+            SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
+            al = SSL_AD_INTERNAL_ERROR;
+            goto f_err;
+        }
+    }
+
+    if (session_id_len != 0 && session_id_len == s->session->session_id_length
+        && memcmp(PACKET_data(&session_id), s->session->session_id,
+                  session_id_len) == 0) {
+        if (s->sid_ctx_length != s->session->sid_ctx_length
+            || memcmp(s->session->sid_ctx, s->sid_ctx, s->sid_ctx_length)) {
+            /* actually a client application bug */
+            al = SSL_AD_ILLEGAL_PARAMETER;
+            SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO,
+                   SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
+            goto f_err;
+        }
+        s->hit = 1;
+    } else {
+        /*
+         * If we were trying for session-id reuse but the server
+         * didn't echo the ID, make a new SSL_SESSION.
+         * In the case of EAP-FAST and PAC, we do not send a session ID,
+         * so the PAC-based session secret is always preserved. It'll be
+         * overwritten if the server refuses resumption.
+         */
+        if (s->session->session_id_length > 0) {
+            s->ctx->stats.sess_miss++;
+            if (!ssl_get_new_session(s, 0)) {
+                goto f_err;
+            }
+        }
+
+        s->session->ssl_version = s->version;
+        s->session->session_id_length = session_id_len;
+        /* session_id_len could be 0 */
+        if (session_id_len > 0)
+            memcpy(s->session->session_id, PACKET_data(&session_id),
+                   session_id_len);
+    }
+
+    /* Session version and negotiated protocol version should match */
+    if (s->version != s->session->ssl_version) {
+        al = SSL_AD_PROTOCOL_VERSION;
+
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO,
+               SSL_R_SSL_SESSION_VERSION_MISMATCH);
+        goto f_err;
+    }
+
+    c = ssl_get_cipher_by_char(s, cipherchars);
+    if (c == NULL) {
+        /* unknown cipher */
+        al = SSL_AD_ILLEGAL_PARAMETER;
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_UNKNOWN_CIPHER_RETURNED);
+        goto f_err;
+    }
+    /*
+     * Now that we know the version, update the check to see if it's an allowed
+     * version.
+     */
+    s->s3->tmp.min_ver = s->version;
+    s->s3->tmp.max_ver = s->version;
+    /*
+     * If it is a disabled cipher we either didn't send it in client hello,
+     * or it's not allowed for the selected protocol. So we return an error.
+     */
+    if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_CHECK)) {
+        al = SSL_AD_ILLEGAL_PARAMETER;
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_WRONG_CIPHER_RETURNED);
+        goto f_err;
+    }
+
+    sk = ssl_get_ciphers_by_id(s);
+    i = sk_SSL_CIPHER_find(sk, c);
+    if (i < 0) {
+        /* we did not say we would use this cipher */
+        al = SSL_AD_ILLEGAL_PARAMETER;
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_WRONG_CIPHER_RETURNED);
+        goto f_err;
+    }
+
+    /*
+     * Depending on the session caching (internal/external), the cipher
+     * and/or cipher_id values may not be set. Make sure that cipher_id is
+     * set and use it for comparison.
+     */
+    if (s->session->cipher)
+        s->session->cipher_id = s->session->cipher->id;
+    if (s->hit && (s->session->cipher_id != c->id)) {
+        al = SSL_AD_ILLEGAL_PARAMETER;
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO,
+               SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
+        goto f_err;
+    }
+    s->s3->tmp.new_cipher = c;
+    /* lets get the compression algorithm */
+    /* COMPRESSION */
+    if (!PACKET_get_1(pkt, &compression)) {
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_LENGTH_MISMATCH);
+        al = SSL_AD_DECODE_ERROR;
+        goto f_err;
+    }
+#ifdef OPENSSL_NO_COMP
+    if (compression != 0) {
+        al = SSL_AD_ILLEGAL_PARAMETER;
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO,
+               SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+        goto f_err;
+    }
+    /*
+     * If compression is disabled we'd better not try to resume a session
+     * using compression.
+     */
+    if (s->session->compress_meth != 0) {
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_INCONSISTENT_COMPRESSION);
+        goto f_err;
+    }
+#else
+    if (s->hit && compression != s->session->compress_meth) {
+        al = SSL_AD_ILLEGAL_PARAMETER;
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO,
+               SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED);
+        goto f_err;
+    }
+    if (compression == 0)
+        comp = NULL;
+    else if (!ssl_allow_compression(s)) {
+        al = SSL_AD_ILLEGAL_PARAMETER;
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_COMPRESSION_DISABLED);
+        goto f_err;
+    } else {
+        comp = ssl3_comp_find(s->ctx->comp_methods, compression);
+    }
+
+    if (compression != 0 && comp == NULL) {
+        al = SSL_AD_ILLEGAL_PARAMETER;
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO,
+               SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+        goto f_err;
+    } else {
+        s->s3->tmp.new_compression = comp;
+    }
+#endif
+
+    /* TLS extensions */
+    if (!ssl_parse_serverhello_tlsext(s, pkt)) {
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_PARSE_TLSEXT);
+        goto err;
+    }
+
+    if (PACKET_remaining(pkt) != 0) {
+        /* wrong packet length */
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_HELLO, SSL_R_BAD_PACKET_LENGTH);
+        goto f_err;
+    }
+#ifndef OPENSSL_NO_SCTP
+    if (SSL_IS_DTLS(s) && s->hit) {
+        unsigned char sctpauthkey[64];
+        char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
+
+        /*
+         * Add new shared key for SCTP-Auth, will be ignored if
+         * no SCTP used.
+         */
+        memcpy(labelbuffer, DTLS1_SCTP_AUTH_LABEL,
+               sizeof(DTLS1_SCTP_AUTH_LABEL));
+
+        if (SSL_export_keying_material(s, sctpauthkey,
+                                       sizeof(sctpauthkey),
+                                       labelbuffer,
+                                       sizeof(labelbuffer), NULL, 0, 0) <= 0)
+            goto err;
+
+        BIO_ctrl(SSL_get_wbio(s),
+                 BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
+                 sizeof(sctpauthkey), sctpauthkey);
+    }
+#endif
+
+    return MSG_PROCESS_CONTINUE_READING;
+ f_err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ err:
+    ossl_statem_set_error(s);
+    return MSG_PROCESS_ERROR;
+}
+
+MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt)
+{
+    int al, i, ret = MSG_PROCESS_ERROR, exp_idx;
+    unsigned long cert_list_len, cert_len;
+    X509 *x = NULL;
+    const unsigned char *certstart, *certbytes;
+    STACK_OF(X509) *sk = NULL;
+    EVP_PKEY *pkey = NULL;
+
+    if ((sk = sk_X509_new_null()) == NULL) {
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (!PACKET_get_net_3(pkt, &cert_list_len)
+        || PACKET_remaining(pkt) != cert_list_len) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, SSL_R_LENGTH_MISMATCH);
+        goto f_err;
+    }
+    while (PACKET_remaining(pkt)) {
+        if (!PACKET_get_net_3(pkt, &cert_len)
+            || !PACKET_get_bytes(pkt, &certbytes, cert_len)) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE,
+                   SSL_R_CERT_LENGTH_MISMATCH);
+            goto f_err;
+        }
+
+        certstart = certbytes;
+        x = d2i_X509(NULL, (const unsigned char **)&certbytes, cert_len);
+        if (x == NULL) {
+            al = SSL_AD_BAD_CERTIFICATE;
+            SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, ERR_R_ASN1_LIB);
+            goto f_err;
+        }
+        if (certbytes != (certstart + cert_len)) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE,
+                   SSL_R_CERT_LENGTH_MISMATCH);
+            goto f_err;
+        }
+        if (!sk_X509_push(sk, x)) {
+            SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        x = NULL;
+    }
+
+    i = ssl_verify_cert_chain(s, sk);
+    /*
+     * The documented interface is that SSL_VERIFY_PEER should be set in order
+     * for client side verification of the server certificate to take place.
+     * However, historically the code has only checked that *any* flag is set
+     * to cause server verification to take place. Use of the other flags makes
+     * no sense in client mode. An attempt to clean up the semantics was
+     * reverted because at least one application *only* set
+     * SSL_VERIFY_FAIL_IF_NO_PEER_CERT. Prior to the clean up this still caused
+     * server verification to take place, after the clean up it silently did
+     * nothing. SSL_CTX_set_verify()/SSL_set_verify() cannot validate the flags
+     * sent to them because they are void functions. Therefore, we now use the
+     * (less clean) historic behaviour of performing validation if any flag is
+     * set. The *documented* interface remains the same.
+     */
+    if (s->verify_mode != SSL_VERIFY_NONE && i <= 0) {
+        al = ssl_verify_alarm_type(s->verify_result);
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE,
+               SSL_R_CERTIFICATE_VERIFY_FAILED);
+        goto f_err;
+    }
+    ERR_clear_error();          /* but we keep s->verify_result */
+    if (i > 1) {
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE, i);
+        al = SSL_AD_HANDSHAKE_FAILURE;
+        goto f_err;
+    }
+
+    s->session->peer_chain = sk;
+    /*
+     * Inconsistency alert: cert_chain does include the peer's certificate,
+     * which we don't include in statem_srvr.c
+     */
+    x = sk_X509_value(sk, 0);
+    sk = NULL;
+    /*
+     * VRS 19990621: possible memory leak; sk=null ==> !sk_pop_free() @end
+     */
+
+    pkey = X509_get0_pubkey(x);
+
+    if (pkey == NULL || EVP_PKEY_missing_parameters(pkey)) {
+        x = NULL;
+        al = SSL3_AL_FATAL;
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE,
+               SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS);
+        goto f_err;
+    }
+
+    i = ssl_cert_type(x, pkey);
+    if (i < 0) {
+        x = NULL;
+        al = SSL3_AL_FATAL;
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE,
+               SSL_R_UNKNOWN_CERTIFICATE_TYPE);
+        goto f_err;
+    }
+
+    exp_idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
+    if (exp_idx >= 0 && i != exp_idx
+        && (exp_idx != SSL_PKEY_GOST_EC ||
+            (i != SSL_PKEY_GOST12_512 && i != SSL_PKEY_GOST12_256
+             && i != SSL_PKEY_GOST01))) {
+        x = NULL;
+        al = SSL_AD_ILLEGAL_PARAMETER;
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_CERTIFICATE,
+               SSL_R_WRONG_CERTIFICATE_TYPE);
+        goto f_err;
+    }
+    s->session->peer_type = i;
+
+    X509_free(s->session->peer);
+    X509_up_ref(x);
+    s->session->peer = x;
+    s->session->verify_result = s->verify_result;
+
+    x = NULL;
+    ret = MSG_PROCESS_CONTINUE_READING;
+    goto done;
+
+ f_err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ err:
+    ossl_statem_set_error(s);
+ done:
+    X509_free(x);
+    sk_X509_pop_free(sk, X509_free);
+    return ret;
+}
+
+static int tls_process_ske_psk_preamble(SSL *s, PACKET *pkt, int *al)
+{
+#ifndef OPENSSL_NO_PSK
+    PACKET psk_identity_hint;
+
+    /* PSK ciphersuites are preceded by an identity hint */
+
+    if (!PACKET_get_length_prefixed_2(pkt, &psk_identity_hint)) {
+        *al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SKE_PSK_PREAMBLE, SSL_R_LENGTH_MISMATCH);
+        return 0;
+    }
+
+    /*
+     * Store PSK identity hint for later use, hint is used in
+     * tls_construct_client_key_exchange.  Assume that the maximum length of
+     * a PSK identity hint can be as long as the maximum length of a PSK
+     * identity.
+     */
+    if (PACKET_remaining(&psk_identity_hint) > PSK_MAX_IDENTITY_LEN) {
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        SSLerr(SSL_F_TLS_PROCESS_SKE_PSK_PREAMBLE, SSL_R_DATA_LENGTH_TOO_LONG);
+        return 0;
+    }
+
+    if (PACKET_remaining(&psk_identity_hint) == 0) {
+        OPENSSL_free(s->session->psk_identity_hint);
+        s->session->psk_identity_hint = NULL;
+    } else if (!PACKET_strndup(&psk_identity_hint,
+                               &s->session->psk_identity_hint)) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        return 0;
+    }
+
+    return 1;
+#else
+    SSLerr(SSL_F_TLS_PROCESS_SKE_PSK_PREAMBLE, ERR_R_INTERNAL_ERROR);
+    *al = SSL_AD_INTERNAL_ERROR;
+    return 0;
+#endif
+}
+
+static int tls_process_ske_srp(SSL *s, PACKET *pkt, EVP_PKEY **pkey, int *al)
+{
+#ifndef OPENSSL_NO_SRP
+    PACKET prime, generator, salt, server_pub;
+
+    if (!PACKET_get_length_prefixed_2(pkt, &prime)
+        || !PACKET_get_length_prefixed_2(pkt, &generator)
+        || !PACKET_get_length_prefixed_1(pkt, &salt)
+        || !PACKET_get_length_prefixed_2(pkt, &server_pub)) {
+        *al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SKE_SRP, SSL_R_LENGTH_MISMATCH);
+        return 0;
+    }
+
+    if ((s->srp_ctx.N =
+         BN_bin2bn(PACKET_data(&prime),
+                   PACKET_remaining(&prime), NULL)) == NULL
+        || (s->srp_ctx.g =
+            BN_bin2bn(PACKET_data(&generator),
+                      PACKET_remaining(&generator), NULL)) == NULL
+        || (s->srp_ctx.s =
+            BN_bin2bn(PACKET_data(&salt),
+                      PACKET_remaining(&salt), NULL)) == NULL
+        || (s->srp_ctx.B =
+            BN_bin2bn(PACKET_data(&server_pub),
+                      PACKET_remaining(&server_pub), NULL)) == NULL) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SKE_SRP, ERR_R_BN_LIB);
+        return 0;
+    }
+
+    if (!srp_verify_server_param(s, al)) {
+        *al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SKE_SRP, SSL_R_BAD_SRP_PARAMETERS);
+        return 0;
+    }
+
+    /* We must check if there is a certificate */
+    if (s->s3->tmp.new_cipher->algorithm_auth & (SSL_aRSA | SSL_aDSS))
+        *pkey = X509_get0_pubkey(s->session->peer);
+
+    return 1;
+#else
+    SSLerr(SSL_F_TLS_PROCESS_SKE_SRP, ERR_R_INTERNAL_ERROR);
+    *al = SSL_AD_INTERNAL_ERROR;
+    return 0;
+#endif
+}
+
+static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey, int *al)
+{
+#ifndef OPENSSL_NO_DH
+    PACKET prime, generator, pub_key;
+    EVP_PKEY *peer_tmp = NULL;
+
+    DH *dh = NULL;
+    BIGNUM *p = NULL, *g = NULL, *bnpub_key = NULL;
+
+    int check_bits = 0;
+
+    if (!PACKET_get_length_prefixed_2(pkt, &prime)
+        || !PACKET_get_length_prefixed_2(pkt, &generator)
+        || !PACKET_get_length_prefixed_2(pkt, &pub_key)) {
+        *al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SKE_DHE, SSL_R_LENGTH_MISMATCH);
+        return 0;
+    }
+
+    peer_tmp = EVP_PKEY_new();
+    dh = DH_new();
+
+    if (peer_tmp == NULL || dh == NULL) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SKE_DHE, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    p = BN_bin2bn(PACKET_data(&prime), PACKET_remaining(&prime), NULL);
+    g = BN_bin2bn(PACKET_data(&generator), PACKET_remaining(&generator), NULL);
+    bnpub_key = BN_bin2bn(PACKET_data(&pub_key), PACKET_remaining(&pub_key),
+                          NULL);
+    if (p == NULL || g == NULL || bnpub_key == NULL) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SKE_DHE, ERR_R_BN_LIB);
+        goto err;
+    }
+
+    /* test non-zero pupkey */
+    if (BN_is_zero(bnpub_key)) {
+        *al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SKE_DHE, SSL_R_BAD_DH_VALUE);
+        goto err;
+    }
+
+    if (!DH_set0_pqg(dh, p, NULL, g)) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SKE_DHE, ERR_R_BN_LIB);
+        goto err;
+    }
+    p = g = NULL;
+
+    if (DH_check_params(dh, &check_bits) == 0 || check_bits != 0) {
+        *al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SKE_DHE, SSL_R_BAD_DH_VALUE);
+        goto err;
+    }
+
+    if (!DH_set0_key(dh, bnpub_key, NULL)) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SKE_DHE, ERR_R_BN_LIB);
+        goto err;
+    }
+    bnpub_key = NULL;
+
+    if (!ssl_security(s, SSL_SECOP_TMP_DH, DH_security_bits(dh), 0, dh)) {
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        SSLerr(SSL_F_TLS_PROCESS_SKE_DHE, SSL_R_DH_KEY_TOO_SMALL);
+        goto err;
+    }
+
+    if (EVP_PKEY_assign_DH(peer_tmp, dh) == 0) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SKE_DHE, ERR_R_EVP_LIB);
+        goto err;
+    }
+
+    s->s3->peer_tmp = peer_tmp;
+
+    /*
+     * FIXME: This makes assumptions about which ciphersuites come with
+     * public keys. We should have a less ad-hoc way of doing this
+     */
+    if (s->s3->tmp.new_cipher->algorithm_auth & (SSL_aRSA | SSL_aDSS))
+        *pkey = X509_get0_pubkey(s->session->peer);
+    /* else anonymous DH, so no certificate or pkey. */
+
+    return 1;
+
+ err:
+    BN_free(p);
+    BN_free(g);
+    BN_free(bnpub_key);
+    DH_free(dh);
+    EVP_PKEY_free(peer_tmp);
+
+    return 0;
+#else
+    SSLerr(SSL_F_TLS_PROCESS_SKE_DHE, ERR_R_INTERNAL_ERROR);
+    *al = SSL_AD_INTERNAL_ERROR;
+    return 0;
+#endif
+}
+
+static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey, int *al)
+{
+#ifndef OPENSSL_NO_EC
+    PACKET encoded_pt;
+    const unsigned char *ecparams;
+    int curve_nid;
+    unsigned int curve_flags;
+    EVP_PKEY_CTX *pctx = NULL;
+
+    /*
+     * Extract elliptic curve parameters and the server's ephemeral ECDH
+     * public key. For now we only support named (not generic) curves and
+     * ECParameters in this case is just three bytes.
+     */
+    if (!PACKET_get_bytes(pkt, &ecparams, 3)) {
+        *al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, SSL_R_LENGTH_TOO_SHORT);
+        return 0;
+    }
+    /*
+     * Check curve is one of our preferences, if not server has sent an
+     * invalid curve. ECParameters is 3 bytes.
+     */
+    if (!tls1_check_curve(s, ecparams, 3)) {
+        *al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, SSL_R_WRONG_CURVE);
+        return 0;
+    }
+
+    curve_nid = tls1_ec_curve_id2nid(*(ecparams + 2), &curve_flags);
+
+    if (curve_nid == 0) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE,
+               SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
+        return 0;
+    }
+
+    if ((curve_flags & TLS_CURVE_TYPE) == TLS_CURVE_CUSTOM) {
+        EVP_PKEY *key = EVP_PKEY_new();
+
+        if (key == NULL || !EVP_PKEY_set_type(key, curve_nid)) {
+            *al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, ERR_R_EVP_LIB);
+            EVP_PKEY_free(key);
+            return 0;
+        }
+        s->s3->peer_tmp = key;
+    } else {
+        /* Set up EVP_PKEY with named curve as parameters */
+        pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
+        if (pctx == NULL
+            || EVP_PKEY_paramgen_init(pctx) <= 0
+            || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, curve_nid) <= 0
+            || EVP_PKEY_paramgen(pctx, &s->s3->peer_tmp) <= 0) {
+            *al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, ERR_R_EVP_LIB);
+            EVP_PKEY_CTX_free(pctx);
+            return 0;
+        }
+        EVP_PKEY_CTX_free(pctx);
+        pctx = NULL;
+    }
+
+    if (!PACKET_get_length_prefixed_1(pkt, &encoded_pt)) {
+        *al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, SSL_R_LENGTH_MISMATCH);
+        return 0;
+    }
+
+    if (!EVP_PKEY_set1_tls_encodedpoint(s->s3->peer_tmp,
+                                        PACKET_data(&encoded_pt),
+                                        PACKET_remaining(&encoded_pt))) {
+        *al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, SSL_R_BAD_ECPOINT);
+        return 0;
+    }
+
+    /*
+     * The ECC/TLS specification does not mention the use of DSA to sign
+     * ECParameters in the server key exchange message. We do support RSA
+     * and ECDSA.
+     */
+    if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aECDSA)
+        *pkey = X509_get0_pubkey(s->session->peer);
+    else if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aRSA)
+        *pkey = X509_get0_pubkey(s->session->peer);
+    /* else anonymous ECDH, so no certificate or pkey. */
+
+    return 1;
+#else
+    SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, ERR_R_INTERNAL_ERROR);
+    *al = SSL_AD_INTERNAL_ERROR;
+    return 0;
+#endif
+}
+
+MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
+{
+    int al = -1;
+    long alg_k;
+    EVP_PKEY *pkey = NULL;
+    PACKET save_param_start, signature;
+
+    alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+
+    save_param_start = *pkt;
+
+#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
+    EVP_PKEY_free(s->s3->peer_tmp);
+    s->s3->peer_tmp = NULL;
+#endif
+
+    if (alg_k & SSL_PSK) {
+        if (!tls_process_ske_psk_preamble(s, pkt, &al))
+            goto err;
+    }
+
+    /* Nothing else to do for plain PSK or RSAPSK */
+    if (alg_k & (SSL_kPSK | SSL_kRSAPSK)) {
+    } else if (alg_k & SSL_kSRP) {
+        if (!tls_process_ske_srp(s, pkt, &pkey, &al))
+            goto err;
+    } else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
+        if (!tls_process_ske_dhe(s, pkt, &pkey, &al))
+            goto err;
+    } else if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) {
+        if (!tls_process_ske_ecdhe(s, pkt, &pkey, &al))
+            goto err;
+    } else if (alg_k) {
+        al = SSL_AD_UNEXPECTED_MESSAGE;
+        SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE);
+        goto err;
+    }
+
+    /* if it was signed, check the signature */
+    if (pkey != NULL) {
+        PACKET params;
+        int maxsig;
+        const EVP_MD *md = NULL;
+        EVP_MD_CTX *md_ctx;
+
+        /*
+         * |pkt| now points to the beginning of the signature, so the difference
+         * equals the length of the parameters.
+         */
+        if (!PACKET_get_sub_packet(&save_param_start, &params,
+                                   PACKET_remaining(&save_param_start) -
+                                   PACKET_remaining(pkt))) {
+            al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+
+        if (SSL_USE_SIGALGS(s)) {
+            const unsigned char *sigalgs;
+            int rv;
+            if (!PACKET_get_bytes(pkt, &sigalgs, 2)) {
+                al = SSL_AD_DECODE_ERROR;
+                SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
+                goto err;
+            }
+            rv = tls12_check_peer_sigalg(&md, s, sigalgs, pkey);
+            if (rv == -1) {
+                al = SSL_AD_INTERNAL_ERROR;
+                goto err;
+            } else if (rv == 0) {
+                al = SSL_AD_DECODE_ERROR;
+                goto err;
+            }
+#ifdef SSL_DEBUG
+            fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
+#endif
+        } else if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) {
+            md = EVP_md5_sha1();
+        } else {
+            md = EVP_sha1();
+        }
+
+        if (!PACKET_get_length_prefixed_2(pkt, &signature)
+            || PACKET_remaining(pkt) != 0) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
+            goto err;
+        }
+        maxsig = EVP_PKEY_size(pkey);
+        if (maxsig < 0) {
+            al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+
+        /*
+         * Check signature length
+         */
+        if (PACKET_remaining(&signature) > (size_t)maxsig) {
+            /* wrong packet length */
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE,
+                   SSL_R_WRONG_SIGNATURE_LENGTH);
+            goto err;
+        }
+
+        md_ctx = EVP_MD_CTX_new();
+        if (md_ctx == NULL) {
+            al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+
+        if (EVP_VerifyInit_ex(md_ctx, md, NULL) <= 0
+            || EVP_VerifyUpdate(md_ctx, &(s->s3->client_random[0]),
+                                SSL3_RANDOM_SIZE) <= 0
+            || EVP_VerifyUpdate(md_ctx, &(s->s3->server_random[0]),
+                                SSL3_RANDOM_SIZE) <= 0
+            || EVP_VerifyUpdate(md_ctx, PACKET_data(&params),
+                                PACKET_remaining(&params)) <= 0) {
+            EVP_MD_CTX_free(md_ctx);
+            al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB);
+            goto err;
+        }
+        if (EVP_VerifyFinal(md_ctx, PACKET_data(&signature),
+                            PACKET_remaining(&signature), pkey) <= 0) {
+            /* bad signature */
+            EVP_MD_CTX_free(md_ctx);
+            al = SSL_AD_DECRYPT_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_BAD_SIGNATURE);
+            goto err;
+        }
+        EVP_MD_CTX_free(md_ctx);
+    } else {
+        /* aNULL, aSRP or PSK do not need public keys */
+        if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP))
+            && !(alg_k & SSL_PSK)) {
+            /* Might be wrong key type, check it */
+            if (ssl3_check_cert_and_algorithm(s)) {
+                /* Otherwise this shouldn't happen */
+                al = SSL_AD_INTERNAL_ERROR;
+                SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+            } else {
+                al = SSL_AD_DECODE_ERROR;
+            }
+            goto err;
+        }
+        /* still data left over */
+        if (PACKET_remaining(pkt) != 0) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_EXTRA_DATA_IN_MESSAGE);
+            goto err;
+        }
+    }
+
+    return MSG_PROCESS_CONTINUE_READING;
+ err:
+    if (al != -1)
+        ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    ossl_statem_set_error(s);
+    return MSG_PROCESS_ERROR;
+}
+
+MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
+{
+    int ret = MSG_PROCESS_ERROR;
+    unsigned int list_len, ctype_num, i, name_len;
+    X509_NAME *xn = NULL;
+    const unsigned char *data;
+    const unsigned char *namestart, *namebytes;
+    STACK_OF(X509_NAME) *ca_sk = NULL;
+
+    if ((ca_sk = sk_X509_NAME_new(ca_dn_cmp)) == NULL) {
+        SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    /* get the certificate types */
+    if (!PACKET_get_1(pkt, &ctype_num)
+        || !PACKET_get_bytes(pkt, &data, ctype_num)) {
+        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+        SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH);
+        goto err;
+    }
+    OPENSSL_free(s->cert->ctypes);
+    s->cert->ctypes = NULL;
+    if (ctype_num > SSL3_CT_NUMBER) {
+        /* If we exceed static buffer copy all to cert structure */
+        s->cert->ctypes = OPENSSL_malloc(ctype_num);
+        if (s->cert->ctypes == NULL) {
+            SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        memcpy(s->cert->ctypes, data, ctype_num);
+        s->cert->ctype_num = (size_t)ctype_num;
+        ctype_num = SSL3_CT_NUMBER;
+    }
+    for (i = 0; i < ctype_num; i++)
+        s->s3->tmp.ctype[i] = data[i];
+
+    if (SSL_USE_SIGALGS(s)) {
+        if (!PACKET_get_net_2(pkt, &list_len)
+            || !PACKET_get_bytes(pkt, &data, list_len)) {
+            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+            SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
+                   SSL_R_LENGTH_MISMATCH);
+            goto err;
+        }
+
+        /* Clear certificate digests and validity flags */
+        for (i = 0; i < SSL_PKEY_NUM; i++) {
+            s->s3->tmp.md[i] = NULL;
+            s->s3->tmp.valid_flags[i] = 0;
+        }
+        if ((list_len & 1) || !tls1_save_sigalgs(s, data, list_len)) {
+            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+            SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
+                   SSL_R_SIGNATURE_ALGORITHMS_ERROR);
+            goto err;
+        }
+        if (!tls1_process_sigalgs(s)) {
+            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+            SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+    } else {
+        ssl_set_default_md(s);
+    }
+
+    /* get the CA RDNs */
+    if (!PACKET_get_net_2(pkt, &list_len)
+        || PACKET_remaining(pkt) != list_len) {
+        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+        SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH);
+        goto err;
+    }
+
+    while (PACKET_remaining(pkt)) {
+        if (!PACKET_get_net_2(pkt, &name_len)
+            || !PACKET_get_bytes(pkt, &namebytes, name_len)) {
+            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+            SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
+                   SSL_R_LENGTH_MISMATCH);
+            goto err;
+        }
+
+        namestart = namebytes;
+
+        if ((xn = d2i_X509_NAME(NULL, (const unsigned char **)&namebytes,
+                                name_len)) == NULL) {
+            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+            SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_ASN1_LIB);
+            goto err;
+        }
+
+        if (namebytes != (namestart + name_len)) {
+            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+            SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
+                   SSL_R_CA_DN_LENGTH_MISMATCH);
+            goto err;
+        }
+        if (!sk_X509_NAME_push(ca_sk, xn)) {
+            SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        xn = NULL;
+    }
+
+    /* we should setup a certificate to return.... */
+    s->s3->tmp.cert_req = 1;
+    s->s3->tmp.ctype_num = ctype_num;
+    sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
+    s->s3->tmp.ca_names = ca_sk;
+    ca_sk = NULL;
+
+    ret = MSG_PROCESS_CONTINUE_PROCESSING;
+    goto done;
+ err:
+    ossl_statem_set_error(s);
+ done:
+    X509_NAME_free(xn);
+    sk_X509_NAME_pop_free(ca_sk, X509_NAME_free);
+    return ret;
+}
+
+static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b)
+{
+    return (X509_NAME_cmp(*a, *b));
+}
+
+MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt)
+{
+    int al;
+    unsigned int ticklen;
+    unsigned long ticket_lifetime_hint;
+
+    if (!PACKET_get_net_4(pkt, &ticket_lifetime_hint)
+        || !PACKET_get_net_2(pkt, &ticklen)
+        || PACKET_remaining(pkt) != ticklen) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH);
+        goto f_err;
+    }
+
+    /* Server is allowed to change its mind and send an empty ticket. */
+    if (ticklen == 0)
+        return MSG_PROCESS_CONTINUE_READING;
+
+    if (s->session->session_id_length > 0) {
+        int i = s->session_ctx->session_cache_mode;
+        SSL_SESSION *new_sess;
+        /*
+         * We reused an existing session, so we need to replace it with a new
+         * one
+         */
+        if (i & SSL_SESS_CACHE_CLIENT) {
+            /*
+             * Remove the old session from the cache. We carry on if this fails
+             */
+            SSL_CTX_remove_session(s->session_ctx, s->session);
+        }
+
+        if ((new_sess = ssl_session_dup(s->session, 0)) == 0) {
+            al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE);
+            goto f_err;
+        }
+
+        SSL_SESSION_free(s->session);
+        s->session = new_sess;
+    }
+
+    OPENSSL_free(s->session->tlsext_tick);
+    s->session->tlsext_ticklen = 0;
+
+    s->session->tlsext_tick = OPENSSL_malloc(ticklen);
+    if (s->session->tlsext_tick == NULL) {
+        SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if (!PACKET_copy_bytes(pkt, s->session->tlsext_tick, ticklen)) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH);
+        goto f_err;
+    }
+
+    s->session->tlsext_tick_lifetime_hint = ticket_lifetime_hint;
+    s->session->tlsext_ticklen = ticklen;
+    /*
+     * There are two ways to detect a resumed ticket session. One is to set
+     * an appropriate session ID and then the server must return a match in
+     * ServerHello. This allows the normal client session ID matching to work
+     * and we know much earlier that the ticket has been accepted. The
+     * other way is to set zero length session ID when the ticket is
+     * presented and rely on the handshake to determine session resumption.
+     * We choose the former approach because this fits in with assumptions
+     * elsewhere in OpenSSL. The session ID is set to the SHA256 (or SHA1 is
+     * SHA256 is disabled) hash of the ticket.
+     */
+    if (!EVP_Digest(s->session->tlsext_tick, ticklen,
+                    s->session->session_id, &s->session->session_id_length,
+                    EVP_sha256(), NULL)) {
+        SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, ERR_R_EVP_LIB);
+        goto err;
+    }
+    return MSG_PROCESS_CONTINUE_READING;
+ f_err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ err:
+    ossl_statem_set_error(s);
+    return MSG_PROCESS_ERROR;
+}
+
+MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, PACKET *pkt)
+{
+    int al;
+    unsigned long resplen;
+    unsigned int type;
+
+    if (!PACKET_get_1(pkt, &type)
+        || type != TLSEXT_STATUSTYPE_ocsp) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, SSL_R_UNSUPPORTED_STATUS_TYPE);
+        goto f_err;
+    }
+    if (!PACKET_get_net_3(pkt, &resplen)
+        || PACKET_remaining(pkt) != resplen) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, SSL_R_LENGTH_MISMATCH);
+        goto f_err;
+    }
+    s->tlsext_ocsp_resp = OPENSSL_malloc(resplen);
+    if (s->tlsext_ocsp_resp == NULL) {
+        al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, ERR_R_MALLOC_FAILURE);
+        goto f_err;
+    }
+    if (!PACKET_copy_bytes(pkt, s->tlsext_ocsp_resp, resplen)) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CERT_STATUS, SSL_R_LENGTH_MISMATCH);
+        goto f_err;
+    }
+    s->tlsext_ocsp_resplen = resplen;
+    return MSG_PROCESS_CONTINUE_READING;
+ f_err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    ossl_statem_set_error(s);
+    return MSG_PROCESS_ERROR;
+}
+
+MSG_PROCESS_RETURN tls_process_server_done(SSL *s, PACKET *pkt)
+{
+    if (PACKET_remaining(pkt) > 0) {
+        /* should contain no data */
+        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+        SSLerr(SSL_F_TLS_PROCESS_SERVER_DONE, SSL_R_LENGTH_MISMATCH);
+        ossl_statem_set_error(s);
+        return MSG_PROCESS_ERROR;
+    }
+#ifndef OPENSSL_NO_SRP
+    if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) {
+        if (SRP_Calc_A_param(s) <= 0) {
+            SSLerr(SSL_F_TLS_PROCESS_SERVER_DONE, SSL_R_SRP_A_CALC);
+            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+            ossl_statem_set_error(s);
+            return MSG_PROCESS_ERROR;
+        }
+    }
+#endif
+
+    /*
+     * at this point we check that we have the required stuff from
+     * the server
+     */
+    if (!ssl3_check_cert_and_algorithm(s)) {
+        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+        ossl_statem_set_error(s);
+        return MSG_PROCESS_ERROR;
+    }
+
+    /*
+     * Call the ocsp status callback if needed. The |tlsext_ocsp_resp| and
+     * |tlsext_ocsp_resplen| values will be set if we actually received a status
+     * message, or NULL and -1 otherwise
+     */
+    if (s->tlsext_status_type != -1 && s->ctx->tlsext_status_cb != NULL) {
+        int ret;
+        ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
+        if (ret == 0) {
+            ssl3_send_alert(s, SSL3_AL_FATAL,
+                            SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE);
+            SSLerr(SSL_F_TLS_PROCESS_SERVER_DONE,
+                   SSL_R_INVALID_STATUS_RESPONSE);
+            return MSG_PROCESS_ERROR;
+        }
+        if (ret < 0) {
+            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+            SSLerr(SSL_F_TLS_PROCESS_SERVER_DONE, ERR_R_MALLOC_FAILURE);
+            return MSG_PROCESS_ERROR;
+        }
+    }
+#ifndef OPENSSL_NO_CT
+    if (s->ct_validation_callback != NULL) {
+        /* Note we validate the SCTs whether or not we abort on error */
+        if (!ssl_validate_ct(s) && (s->verify_mode & SSL_VERIFY_PEER)) {
+            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+            return MSG_PROCESS_ERROR;
+        }
+    }
+#endif
+
+#ifndef OPENSSL_NO_SCTP
+    /* Only applies to renegotiation */
+    if (SSL_IS_DTLS(s) && BIO_dgram_is_sctp(SSL_get_wbio(s))
+        && s->renegotiate != 0)
+        return MSG_PROCESS_CONTINUE_PROCESSING;
+    else
+#endif
+        return MSG_PROCESS_FINISHED_READING;
+}
+
+static int tls_construct_cke_psk_preamble(SSL *s, unsigned char **p,
+                                          size_t *pskhdrlen, int *al)
+{
+#ifndef OPENSSL_NO_PSK
+    int ret = 0;
+    /*
+     * The callback needs PSK_MAX_IDENTITY_LEN + 1 bytes to return a
+     * \0-terminated identity. The last byte is for us for simulating
+     * strnlen.
+     */
+    char identity[PSK_MAX_IDENTITY_LEN + 1];
+    size_t identitylen = 0;
+    unsigned char psk[PSK_MAX_PSK_LEN];
+    unsigned char *tmppsk = NULL;
+    char *tmpidentity = NULL;
+    size_t psklen = 0;
+
+    if (s->psk_client_callback == NULL) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, SSL_R_PSK_NO_CLIENT_CB);
+        *al = SSL_AD_INTERNAL_ERROR;
+        goto err;
+    }
+
+    memset(identity, 0, sizeof(identity));
+
+    psklen = s->psk_client_callback(s, s->session->psk_identity_hint,
+                                    identity, sizeof(identity) - 1,
+                                    psk, sizeof(psk));
+
+    if (psklen > PSK_MAX_PSK_LEN) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, ERR_R_INTERNAL_ERROR);
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        goto err;
+    } else if (psklen == 0) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE,
+               SSL_R_PSK_IDENTITY_NOT_FOUND);
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        goto err;
+    }
+
+    identitylen = strlen(identity);
+    if (identitylen > PSK_MAX_IDENTITY_LEN) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, ERR_R_INTERNAL_ERROR);
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        goto err;
+    }
+
+    tmppsk = OPENSSL_memdup(psk, psklen);
+    tmpidentity = OPENSSL_strdup(identity);
+    if (tmppsk == NULL || tmpidentity == NULL) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, ERR_R_MALLOC_FAILURE);
+        *al = SSL_AD_INTERNAL_ERROR;
+        goto err;
+    }
+
+    OPENSSL_free(s->s3->tmp.psk);
+    s->s3->tmp.psk = tmppsk;
+    s->s3->tmp.psklen = psklen;
+    tmppsk = NULL;
+    OPENSSL_free(s->session->psk_identity);
+    s->session->psk_identity = tmpidentity;
+    tmpidentity = NULL;
+    s2n(identitylen, *p);
+    memcpy(*p, identity, identitylen);
+    *pskhdrlen = 2 + identitylen;
+    *p += identitylen;
+
+    ret = 1;
+
+ err:
+    OPENSSL_cleanse(psk, psklen);
+    OPENSSL_cleanse(identity, sizeof(identity));
+    OPENSSL_clear_free(tmppsk, psklen);
+    OPENSSL_clear_free(tmpidentity, identitylen);
+
+    return ret;
+#else
+    SSLerr(SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, ERR_R_INTERNAL_ERROR);
+    *al = SSL_AD_INTERNAL_ERROR;
+    return 0;
+#endif
+}
+
+static int tls_construct_cke_rsa(SSL *s, unsigned char **p, int *len, int *al)
+{
+#ifndef OPENSSL_NO_RSA
+    unsigned char *q;
+    EVP_PKEY *pkey = NULL;
+    EVP_PKEY_CTX *pctx = NULL;
+    size_t enclen;
+    unsigned char *pms = NULL;
+    size_t pmslen = 0;
+
+    if (s->session->peer == NULL) {
+        /*
+         * We should always have a server certificate with SSL_kRSA.
+         */
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_RSA, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    pkey = X509_get0_pubkey(s->session->peer);
+    if (EVP_PKEY_get0_RSA(pkey) == NULL) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_RSA, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    pmslen = SSL_MAX_MASTER_KEY_LENGTH;
+    pms = OPENSSL_malloc(pmslen);
+    if (pms == NULL) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_RSA, ERR_R_MALLOC_FAILURE);
+        *al = SSL_AD_INTERNAL_ERROR;
+        return 0;
+    }
+
+    pms[0] = s->client_version >> 8;
+    pms[1] = s->client_version & 0xff;
+    if (RAND_bytes(pms + 2, pmslen - 2) <= 0) {
+        goto err;
+    }
+
+    q = *p;
+    /* Fix buf for TLS and beyond */
+    if (s->version > SSL3_VERSION)
+        *p += 2;
+    pctx = EVP_PKEY_CTX_new(pkey, NULL);
+    if (pctx == NULL || EVP_PKEY_encrypt_init(pctx) <= 0
+        || EVP_PKEY_encrypt(pctx, NULL, &enclen, pms, pmslen) <= 0) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_RSA, ERR_R_EVP_LIB);
+        goto err;
+    }
+    if (EVP_PKEY_encrypt(pctx, *p, &enclen, pms, pmslen) <= 0) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_RSA, SSL_R_BAD_RSA_ENCRYPT);
+        goto err;
+    }
+    *len = enclen;
+    EVP_PKEY_CTX_free(pctx);
+    pctx = NULL;
+# ifdef PKCS1_CHECK
+    if (s->options & SSL_OP_PKCS1_CHECK_1)
+        (*p)[1]++;
+    if (s->options & SSL_OP_PKCS1_CHECK_2)
+        tmp_buf[0] = 0x70;
+# endif
+
+    /* Fix buf for TLS and beyond */
+    if (s->version > SSL3_VERSION) {
+        s2n(*len, q);
+        *len += 2;
+    }
+
+    s->s3->tmp.pms = pms;
+    s->s3->tmp.pmslen = pmslen;
+
+    return 1;
+ err:
+    OPENSSL_clear_free(pms, pmslen);
+    EVP_PKEY_CTX_free(pctx);
+
+    return 0;
+#else
+    SSLerr(SSL_F_TLS_CONSTRUCT_CKE_RSA, ERR_R_INTERNAL_ERROR);
+    *al = SSL_AD_INTERNAL_ERROR;
+    return 0;
+#endif
+}
+
+static int tls_construct_cke_dhe(SSL *s, unsigned char **p, int *len, int *al)
+{
+#ifndef OPENSSL_NO_DH
+    DH *dh_clnt = NULL;
+    const BIGNUM *pub_key;
+    EVP_PKEY *ckey = NULL, *skey = NULL;
+
+    skey = s->s3->peer_tmp;
+    if (skey == NULL) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_DHE, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+    ckey = ssl_generate_pkey(skey);
+    if (ckey == NULL) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_DHE, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    dh_clnt = EVP_PKEY_get0_DH(ckey);
+
+    if (dh_clnt == NULL || ssl_derive(s, ckey, skey) == 0) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_DHE, ERR_R_INTERNAL_ERROR);
+        EVP_PKEY_free(ckey);
+        return 0;
+    }
+
+    /* send off the data */
+    DH_get0_key(dh_clnt, &pub_key, NULL);
+    *len = BN_num_bytes(pub_key);
+    s2n(*len, *p);
+    BN_bn2bin(pub_key, *p);
+    *len += 2;
+    EVP_PKEY_free(ckey);
+
+    return 1;
+#else
+    SSLerr(SSL_F_TLS_CONSTRUCT_CKE_DHE, ERR_R_INTERNAL_ERROR);
+    *al = SSL_AD_INTERNAL_ERROR;
+    return 0;
+#endif
+}
+
+static int tls_construct_cke_ecdhe(SSL *s, unsigned char **p, int *len, int *al)
+{
+#ifndef OPENSSL_NO_EC
+    unsigned char *encodedPoint = NULL;
+    int encoded_pt_len = 0;
+    EVP_PKEY *ckey = NULL, *skey = NULL;
+
+    skey = s->s3->peer_tmp;
+    if (skey == NULL) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_ECDHE, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    ckey = ssl_generate_pkey(skey);
+    if (ckey == NULL) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_ECDHE, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
+    if (ssl_derive(s, ckey, skey) == 0) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_ECDHE, ERR_R_EVP_LIB);
+        goto err;
+    }
+
+    /* Generate encoding of client key */
+    encoded_pt_len = EVP_PKEY_get1_tls_encodedpoint(ckey, &encodedPoint);
+
+    if (encoded_pt_len == 0) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_ECDHE, ERR_R_EC_LIB);
+        goto err;
+    }
+
+    EVP_PKEY_free(ckey);
+    ckey = NULL;
+
+    *len = encoded_pt_len;
+
+    /* length of encoded point */
+    **p = *len;
+    *p += 1;
+    /* copy the point */
+    memcpy(*p, encodedPoint, *len);
+    /* increment len to account for length field */
+    *len += 1;
+
+    OPENSSL_free(encodedPoint);
+
+    return 1;
+ err:
+    EVP_PKEY_free(ckey);
+    return 0;
+#else
+    SSLerr(SSL_F_TLS_CONSTRUCT_CKE_ECDHE, ERR_R_INTERNAL_ERROR);
+    *al = SSL_AD_INTERNAL_ERROR;
+    return 0;
+#endif
+}
+
+static int tls_construct_cke_gost(SSL *s, unsigned char **p, int *len, int *al)
+{
+#ifndef OPENSSL_NO_GOST
+    /* GOST key exchange message creation */
+    EVP_PKEY_CTX *pkey_ctx = NULL;
+    X509 *peer_cert;
+    size_t msglen;
+    unsigned int md_len;
+    unsigned char shared_ukm[32], tmp[256];
+    EVP_MD_CTX *ukm_hash = NULL;
+    int dgst_nid = NID_id_GostR3411_94;
+    unsigned char *pms = NULL;
+    size_t pmslen = 0;
+
+    if ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aGOST12) != 0)
+        dgst_nid = NID_id_GostR3411_2012_256;
+
+    /*
+     * Get server sertificate PKEY and create ctx from it
+     */
+    peer_cert = s->session->peer;
+    if (!peer_cert) {
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_GOST,
+               SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER);
+        return 0;
+    }
+
+    pkey_ctx = EVP_PKEY_CTX_new(X509_get0_pubkey(peer_cert), NULL);
+    if (pkey_ctx == NULL) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_GOST, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    /*
+     * If we have send a certificate, and certificate key
+     * parameters match those of server certificate, use
+     * certificate key for key exchange
+     */
+
+    /* Otherwise, generate ephemeral key pair */
+    pmslen = 32;
+    pms = OPENSSL_malloc(pmslen);
+    if (pms == NULL) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_GOST, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (EVP_PKEY_encrypt_init(pkey_ctx) <= 0
+        /* Generate session key */
+        || RAND_bytes(pms, pmslen) <= 0) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_GOST, ERR_R_INTERNAL_ERROR);
+        goto err;
+    };
+    /*
+     * Compute shared IV and store it in algorithm-specific context
+     * data
+     */
+    ukm_hash = EVP_MD_CTX_new();
+    if (ukm_hash == NULL
+        || EVP_DigestInit(ukm_hash, EVP_get_digestbynid(dgst_nid)) <= 0
+        || EVP_DigestUpdate(ukm_hash, s->s3->client_random,
+                            SSL3_RANDOM_SIZE) <= 0
+        || EVP_DigestUpdate(ukm_hash, s->s3->server_random,
+                            SSL3_RANDOM_SIZE) <= 0
+        || EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len) <= 0) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_GOST, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+    EVP_MD_CTX_free(ukm_hash);
+    ukm_hash = NULL;
+    if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT,
+                          EVP_PKEY_CTRL_SET_IV, 8, shared_ukm) < 0) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_GOST, SSL_R_LIBRARY_BUG);
+        goto err;
+    }
+    /* Make GOST keytransport blob message */
+    /*
+     * Encapsulate it into sequence
+     */
+    *((*p)++) = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED;
+    msglen = 255;
+    if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, pms, pmslen) <= 0) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_GOST, SSL_R_LIBRARY_BUG);
+        goto err;
+    }
+    if (msglen >= 0x80) {
+        *((*p)++) = 0x81;
+        *((*p)++) = msglen & 0xff;
+        *len = msglen + 3;
+    } else {
+        *((*p)++) = msglen & 0xff;
+        *len = msglen + 2;
+    }
+    memcpy(*p, tmp, msglen);
+
+    EVP_PKEY_CTX_free(pkey_ctx);
+    s->s3->tmp.pms = pms;
+    s->s3->tmp.pmslen = pmslen;
+
+    return 1;
+ err:
+    EVP_PKEY_CTX_free(pkey_ctx);
+    OPENSSL_clear_free(pms, pmslen);
+    EVP_MD_CTX_free(ukm_hash);
+    return 0;
+#else
+    SSLerr(SSL_F_TLS_CONSTRUCT_CKE_GOST, ERR_R_INTERNAL_ERROR);
+    *al = SSL_AD_INTERNAL_ERROR;
+    return 0;
+#endif
+}
+
+static int tls_construct_cke_srp(SSL *s, unsigned char **p, int *len, int *al)
+{
+#ifndef OPENSSL_NO_SRP
+    if (s->srp_ctx.A != NULL) {
+        /* send off the data */
+        *len = BN_num_bytes(s->srp_ctx.A);
+        s2n(*len, *p);
+        BN_bn2bin(s->srp_ctx.A, *p);
+        *len += 2;
+    } else {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_SRP, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+    OPENSSL_free(s->session->srp_username);
+    s->session->srp_username = OPENSSL_strdup(s->srp_ctx.login);
+    if (s->session->srp_username == NULL) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CKE_SRP, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    return 1;
+#else
+    SSLerr(SSL_F_TLS_CONSTRUCT_CKE_SRP, ERR_R_INTERNAL_ERROR);
+    *al = SSL_AD_INTERNAL_ERROR;
+    return 0;
+#endif
+}
+
+int tls_construct_client_key_exchange(SSL *s)
+{
+    unsigned char *p;
+    int len;
+    size_t pskhdrlen = 0;
+    unsigned long alg_k;
+    int al = -1;
+
+    alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+
+    p = ssl_handshake_start(s);
+
+    if ((alg_k & SSL_PSK)
+        && !tls_construct_cke_psk_preamble(s, &p, &pskhdrlen, &al))
+        goto err;
+
+    if (alg_k & SSL_kPSK) {
+        len = 0;
+    } else if (alg_k & (SSL_kRSA | SSL_kRSAPSK)) {
+        if (!tls_construct_cke_rsa(s, &p, &len, &al))
+            goto err;
+    } else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
+        if (!tls_construct_cke_dhe(s, &p, &len, &al))
+            goto err;
+    } else if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) {
+        if (!tls_construct_cke_ecdhe(s, &p, &len, &al))
+            goto err;
+    } else if (alg_k & SSL_kGOST) {
+        if (!tls_construct_cke_gost(s, &p, &len, &al))
+            goto err;
+    } else if (alg_k & SSL_kSRP) {
+        if (!tls_construct_cke_srp(s, &p, &len, &al))
+            goto err;
+    } else {
+        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
+    len += pskhdrlen;
+
+    if (!ssl_set_handshake_header(s, SSL3_MT_CLIENT_KEY_EXCHANGE, len)) {
+        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
+    return 1;
+ err:
+    if (al != -1)
+        ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    OPENSSL_clear_free(s->s3->tmp.pms, s->s3->tmp.pmslen);
+    s->s3->tmp.pms = NULL;
+#ifndef OPENSSL_NO_PSK
+    OPENSSL_clear_free(s->s3->tmp.psk, s->s3->tmp.psklen);
+    s->s3->tmp.psk = NULL;
+#endif
+    ossl_statem_set_error(s);
+    return 0;
+}
+
+int tls_client_key_exchange_post_work(SSL *s)
+{
+    unsigned char *pms = NULL;
+    size_t pmslen = 0;
+
+    pms = s->s3->tmp.pms;
+    pmslen = s->s3->tmp.pmslen;
+
+#ifndef OPENSSL_NO_SRP
+    /* Check for SRP */
+    if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) {
+        if (!srp_generate_client_master_secret(s)) {
+            SSLerr(SSL_F_TLS_CLIENT_KEY_EXCHANGE_POST_WORK,
+                   ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+        return 1;
+    }
+#endif
+
+    if (pms == NULL && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
+        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+        SSLerr(SSL_F_TLS_CLIENT_KEY_EXCHANGE_POST_WORK, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+    if (!ssl_generate_master_secret(s, pms, pmslen, 1)) {
+        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+        SSLerr(SSL_F_TLS_CLIENT_KEY_EXCHANGE_POST_WORK, ERR_R_INTERNAL_ERROR);
+        /* ssl_generate_master_secret frees the pms even on error */
+        pms = NULL;
+        pmslen = 0;
+        goto err;
+    }
+    pms = NULL;
+    pmslen = 0;
+
+#ifndef OPENSSL_NO_SCTP
+    if (SSL_IS_DTLS(s)) {
+        unsigned char sctpauthkey[64];
+        char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
+
+        /*
+         * Add new shared key for SCTP-Auth, will be ignored if no SCTP
+         * used.
+         */
+        memcpy(labelbuffer, DTLS1_SCTP_AUTH_LABEL,
+               sizeof(DTLS1_SCTP_AUTH_LABEL));
+
+        if (SSL_export_keying_material(s, sctpauthkey,
+                                       sizeof(sctpauthkey), labelbuffer,
+                                       sizeof(labelbuffer), NULL, 0, 0) <= 0)
+            goto err;
+
+        BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
+                 sizeof(sctpauthkey), sctpauthkey);
+    }
+#endif
+
+    return 1;
+ err:
+    OPENSSL_clear_free(pms, pmslen);
+    s->s3->tmp.pms = NULL;
+    return 0;
+}
+
+int tls_construct_client_verify(SSL *s)
+{
+    unsigned char *p;
+    EVP_PKEY *pkey;
+    const EVP_MD *md = s->s3->tmp.md[s->cert->key - s->cert->pkeys];
+    EVP_MD_CTX *mctx;
+    unsigned u = 0;
+    unsigned long n = 0;
+    long hdatalen = 0;
+    void *hdata;
+
+    mctx = EVP_MD_CTX_new();
+    if (mctx == NULL) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    p = ssl_handshake_start(s);
+    pkey = s->cert->key->privatekey;
+
+    hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
+    if (hdatalen <= 0) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+    if (SSL_USE_SIGALGS(s)) {
+        if (!tls12_get_sigandhash(p, pkey, md)) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+        p += 2;
+        n = 2;
+    }
+#ifdef SSL_DEBUG
+    fprintf(stderr, "Using client alg %s\n", EVP_MD_name(md));
+#endif
+    if (!EVP_SignInit_ex(mctx, md, NULL)
+        || !EVP_SignUpdate(mctx, hdata, hdatalen)
+        || (s->version == SSL3_VERSION
+            && !EVP_MD_CTX_ctrl(mctx, EVP_CTRL_SSL3_MASTER_SECRET,
+                                s->session->master_key_length,
+                                s->session->master_key))
+        || !EVP_SignFinal(mctx, p + 2, &u, pkey)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_EVP_LIB);
+        goto err;
+    }
+#ifndef OPENSSL_NO_GOST
+    {
+        int pktype = EVP_PKEY_id(pkey);
+        if (pktype == NID_id_GostR3410_2001
+            || pktype == NID_id_GostR3410_2012_256
+            || pktype == NID_id_GostR3410_2012_512)
+            BUF_reverse(p + 2, NULL, u);
+    }
+#endif
+
+    s2n(u, p);
+    n += u + 2;
+    /* Digest cached records and discard handshake buffer */
+    if (!ssl3_digest_cached_records(s, 0))
+        goto err;
+    if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_VERIFY, n)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
+    EVP_MD_CTX_free(mctx);
+    return 1;
+ err:
+    EVP_MD_CTX_free(mctx);
+    return 0;
+}
+
+/*
+ * Check a certificate can be used for client authentication. Currently check
+ * cert exists, if we have a suitable digest for TLS 1.2 if static DH client
+ * certificates can be used and optionally checks suitability for Suite B.
+ */
+static int ssl3_check_client_certificate(SSL *s)
+{
+    if (!s->cert || !s->cert->key->x509 || !s->cert->key->privatekey)
+        return 0;
+    /* If no suitable signature algorithm can't use certificate */
+    if (SSL_USE_SIGALGS(s) && !s->s3->tmp.md[s->cert->key - s->cert->pkeys])
+        return 0;
+    /*
+     * If strict mode check suitability of chain before using it. This also
+     * adjusts suite B digest if necessary.
+     */
+    if (s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT &&
+        !tls1_check_chain(s, NULL, NULL, NULL, -2))
+        return 0;
+    return 1;
+}
+
+WORK_STATE tls_prepare_client_certificate(SSL *s, WORK_STATE wst)
+{
+    X509 *x509 = NULL;
+    EVP_PKEY *pkey = NULL;
+    int i;
+
+    if (wst == WORK_MORE_A) {
+        /* Let cert callback update client certificates if required */
+        if (s->cert->cert_cb) {
+            i = s->cert->cert_cb(s, s->cert->cert_cb_arg);
+            if (i < 0) {
+                s->rwstate = SSL_X509_LOOKUP;
+                return WORK_MORE_A;
+            }
+            if (i == 0) {
+                ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+                ossl_statem_set_error(s);
+                return 0;
+            }
+            s->rwstate = SSL_NOTHING;
+        }
+        if (ssl3_check_client_certificate(s))
+            return WORK_FINISHED_CONTINUE;
+
+        /* Fall through to WORK_MORE_B */
+        wst = WORK_MORE_B;
+    }
+
+    /* We need to get a client cert */
+    if (wst == WORK_MORE_B) {
+        /*
+         * If we get an error, we need to ssl->rwstate=SSL_X509_LOOKUP;
+         * return(-1); We then get retied later
+         */
+        i = ssl_do_client_cert_cb(s, &x509, &pkey);
+        if (i < 0) {
+            s->rwstate = SSL_X509_LOOKUP;
+            return WORK_MORE_B;
+        }
+        s->rwstate = SSL_NOTHING;
+        if ((i == 1) && (pkey != NULL) && (x509 != NULL)) {
+            if (!SSL_use_certificate(s, x509) || !SSL_use_PrivateKey(s, pkey))
+                i = 0;
+        } else if (i == 1) {
+            i = 0;
+            SSLerr(SSL_F_TLS_PREPARE_CLIENT_CERTIFICATE,
+                   SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
+        }
+
+        X509_free(x509);
+        EVP_PKEY_free(pkey);
+        if (i && !ssl3_check_client_certificate(s))
+            i = 0;
+        if (i == 0) {
+            if (s->version == SSL3_VERSION) {
+                s->s3->tmp.cert_req = 0;
+                ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE);
+                return WORK_FINISHED_CONTINUE;
+            } else {
+                s->s3->tmp.cert_req = 2;
+                if (!ssl3_digest_cached_records(s, 0)) {
+                    ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+                    ossl_statem_set_error(s);
+                    return 0;
+                }
+            }
+        }
+
+        return WORK_FINISHED_CONTINUE;
+    }
+
+    /* Shouldn't ever get here */
+    return WORK_ERROR;
+}
+
+int tls_construct_client_certificate(SSL *s)
+{
+    if (!ssl3_output_cert_chain(s,
+                                (s->s3->tmp.cert_req ==
+                                 2) ? NULL : s->cert->key)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
+        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+        ossl_statem_set_error(s);
+        return 0;
+    }
+
+    return 1;
+}
+
+#define has_bits(i,m)   (((i)&(m)) == (m))
+
+int ssl3_check_cert_and_algorithm(SSL *s)
+{
+    int i;
+#ifndef OPENSSL_NO_EC
+    int idx;
+#endif
+    long alg_k, alg_a;
+    EVP_PKEY *pkey = NULL;
+    int al = SSL_AD_HANDSHAKE_FAILURE;
+
+    alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+    alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+
+    /* we don't have a certificate */
+    if ((alg_a & SSL_aNULL) || (alg_k & SSL_kPSK))
+        return (1);
+
+    /* This is the passed certificate */
+
+#ifndef OPENSSL_NO_EC
+    idx = s->session->peer_type;
+    if (idx == SSL_PKEY_ECC) {
+        if (ssl_check_srvr_ecc_cert_and_alg(s->session->peer, s) == 0) {
+            /* check failed */
+            SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_BAD_ECC_CERT);
+            goto f_err;
+        } else {
+            return 1;
+        }
+    } else if (alg_a & SSL_aECDSA) {
+        SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
+               SSL_R_MISSING_ECDSA_SIGNING_CERT);
+        goto f_err;
+    }
+#endif
+    pkey = X509_get0_pubkey(s->session->peer);
+    i = X509_certificate_type(s->session->peer, pkey);
+
+    /* Check that we have a certificate if we require one */
+    if ((alg_a & SSL_aRSA) && !has_bits(i, EVP_PK_RSA | EVP_PKT_SIGN)) {
+        SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
+               SSL_R_MISSING_RSA_SIGNING_CERT);
+        goto f_err;
+    }
+#ifndef OPENSSL_NO_DSA
+    else if ((alg_a & SSL_aDSS) && !has_bits(i, EVP_PK_DSA | EVP_PKT_SIGN)) {
+        SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
+               SSL_R_MISSING_DSA_SIGNING_CERT);
+        goto f_err;
+    }
+#endif
+#ifndef OPENSSL_NO_RSA
+    if (alg_k & (SSL_kRSA | SSL_kRSAPSK) &&
+        !has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) {
+        SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
+               SSL_R_MISSING_RSA_ENCRYPTING_CERT);
+        goto f_err;
+    }
+#endif
+#ifndef OPENSSL_NO_DH
+    if ((alg_k & SSL_kDHE) && (s->s3->peer_tmp == NULL)) {
+        al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR);
+        goto f_err;
+    }
+#endif
+
+    return (1);
+ f_err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    return (0);
+}
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+int tls_construct_next_proto(SSL *s)
+{
+    unsigned int len, padding_len;
+    unsigned char *d;
+
+    len = s->next_proto_negotiated_len;
+    padding_len = 32 - ((len + 2) % 32);
+    d = (unsigned char *)s->init_buf->data;
+    d[4] = len;
+    memcpy(d + 5, s->next_proto_negotiated, len);
+    d[5 + len] = padding_len;
+    memset(d + 6 + len, 0, padding_len);
+    *(d++) = SSL3_MT_NEXT_PROTO;
+    l2n3(2 + len + padding_len, d);
+    s->init_num = 4 + 2 + len + padding_len;
+    s->init_off = 0;
+
+    return 1;
+}
+#endif
+
+int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)
+{
+    int i = 0;
+#ifndef OPENSSL_NO_ENGINE
+    if (s->ctx->client_cert_engine) {
+        i = ENGINE_load_ssl_client_cert(s->ctx->client_cert_engine, s,
+                                        SSL_get_client_CA_list(s),
+                                        px509, ppkey, NULL, NULL, NULL);
+        if (i != 0)
+            return i;
+    }
+#endif
+    if (s->ctx->client_cert_cb)
+        i = s->ctx->client_cert_cb(s, px509, ppkey);
+    return i;
+}
+
+int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, unsigned char *p)
+{
+    int i, j = 0;
+    const SSL_CIPHER *c;
+    unsigned char *q;
+    int empty_reneg_info_scsv = !s->renegotiate;
+    /* Set disabled masks for this session */
+    ssl_set_client_disabled(s);
+
+    if (sk == NULL)
+        return (0);
+    q = p;
+
+    for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
+        c = sk_SSL_CIPHER_value(sk, i);
+        /* Skip disabled ciphers */
+        if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED))
+            continue;
+        j = s->method->put_cipher_by_char(c, p);
+        p += j;
+    }
+    /*
+     * If p == q, no ciphers; caller indicates an error. Otherwise, add
+     * applicable SCSVs.
+     */
+    if (p != q) {
+        if (empty_reneg_info_scsv) {
+            static SSL_CIPHER scsv = {
+                0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
+            };
+            j = s->method->put_cipher_by_char(&scsv, p);
+            p += j;
+        }
+        if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) {
+            static SSL_CIPHER scsv = {
+                0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
+            };
+            j = s->method->put_cipher_by_char(&scsv, p);
+            p += j;
+        }
+    }
+
+    return (p - q);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem_dtls.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem_dtls.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem_dtls.c	(revision 331)
@@ -0,0 +1,1193 @@
+/*
+ * Copyright 2005-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 <limits.h>
+#include <string.h>
+#include <stdio.h>
+#include "../ssl_locl.h"
+#include "statem_locl.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+#define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8)
+
+#define RSMBLY_BITMASK_MARK(bitmask, start, end) { \
+                        if ((end) - (start) <= 8) { \
+                                long ii; \
+                                for (ii = (start); ii < (end); ii++) bitmask[((ii) >> 3)] |= (1 << ((ii) & 7)); \
+                        } else { \
+                                long ii; \
+                                bitmask[((start) >> 3)] |= bitmask_start_values[((start) & 7)]; \
+                                for (ii = (((start) >> 3) + 1); ii < ((((end) - 1)) >> 3); ii++) bitmask[ii] = 0xff; \
+                                bitmask[(((end) - 1) >> 3)] |= bitmask_end_values[((end) & 7)]; \
+                        } }
+
+#define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete) { \
+                        long ii; \
+                        OPENSSL_assert((msg_len) > 0); \
+                        is_complete = 1; \
+                        if (bitmask[(((msg_len) - 1) >> 3)] != bitmask_end_values[((msg_len) & 7)]) is_complete = 0; \
+                        if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \
+                                if (bitmask[ii] != 0xff) { is_complete = 0; break; } }
+
+static unsigned char bitmask_start_values[] =
+    { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80 };
+static unsigned char bitmask_end_values[] =
+    { 0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f };
+
+static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,
+                                     unsigned long frag_len);
+static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p);
+static void dtls1_set_message_header_int(SSL *s, unsigned char mt,
+                                         unsigned long len,
+                                         unsigned short seq_num,
+                                         unsigned long frag_off,
+                                         unsigned long frag_len);
+static int dtls_get_reassembled_message(SSL *s, long *len);
+
+static hm_fragment *dtls1_hm_fragment_new(unsigned long frag_len,
+                                          int reassembly)
+{
+    hm_fragment *frag = NULL;
+    unsigned char *buf = NULL;
+    unsigned char *bitmask = NULL;
+
+    frag = OPENSSL_malloc(sizeof(*frag));
+    if (frag == NULL)
+        return NULL;
+
+    if (frag_len) {
+        buf = OPENSSL_malloc(frag_len);
+        if (buf == NULL) {
+            OPENSSL_free(frag);
+            return NULL;
+        }
+    }
+
+    /* zero length fragment gets zero frag->fragment */
+    frag->fragment = buf;
+
+    /* Initialize reassembly bitmask if necessary */
+    if (reassembly) {
+        bitmask = OPENSSL_zalloc(RSMBLY_BITMASK_SIZE(frag_len));
+        if (bitmask == NULL) {
+            OPENSSL_free(buf);
+            OPENSSL_free(frag);
+            return NULL;
+        }
+    }
+
+    frag->reassembly = bitmask;
+
+    return frag;
+}
+
+void dtls1_hm_fragment_free(hm_fragment *frag)
+{
+    if (!frag)
+        return;
+    if (frag->msg_header.is_ccs) {
+        EVP_CIPHER_CTX_free(frag->msg_header.
+                            saved_retransmit_state.enc_write_ctx);
+        EVP_MD_CTX_free(frag->msg_header.saved_retransmit_state.write_hash);
+    }
+    OPENSSL_free(frag->fragment);
+    OPENSSL_free(frag->reassembly);
+    OPENSSL_free(frag);
+}
+
+/*
+ * send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or
+ * SSL3_RT_CHANGE_CIPHER_SPEC)
+ */
+int dtls1_do_write(SSL *s, int type)
+{
+    int ret;
+    unsigned int curr_mtu;
+    int retry = 1;
+    unsigned int len, frag_off, mac_size, blocksize, used_len;
+
+    if (!dtls1_query_mtu(s))
+        return -1;
+
+    if (s->d1->mtu < dtls1_min_mtu(s))
+        /* should have something reasonable now */
+        return -1;
+
+    if (s->init_off == 0 && type == SSL3_RT_HANDSHAKE)
+        OPENSSL_assert(s->init_num ==
+                       (int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
+
+    if (s->write_hash) {
+        if (s->enc_write_ctx
+            && (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_write_ctx)) &
+                EVP_CIPH_FLAG_AEAD_CIPHER) != 0)
+            mac_size = 0;
+        else
+            mac_size = EVP_MD_CTX_size(s->write_hash);
+    } else
+        mac_size = 0;
+
+    if (s->enc_write_ctx &&
+        (EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_CBC_MODE))
+        blocksize = 2 * EVP_CIPHER_CTX_block_size(s->enc_write_ctx);
+    else
+        blocksize = 0;
+
+    frag_off = 0;
+    s->rwstate = SSL_NOTHING;
+
+    /* s->init_num shouldn't ever be < 0...but just in case */
+    while (s->init_num > 0) {
+        if (type == SSL3_RT_HANDSHAKE && s->init_off != 0) {
+            /* We must be writing a fragment other than the first one */
+
+            if (frag_off > 0) {
+                /* This is the first attempt at writing out this fragment */
+
+                if (s->init_off <= DTLS1_HM_HEADER_LENGTH) {
+                    /*
+                     * Each fragment that was already sent must at least have
+                     * contained the message header plus one other byte.
+                     * Therefore |init_off| must have progressed by at least
+                     * |DTLS1_HM_HEADER_LENGTH + 1| bytes. If not something went
+                     * wrong.
+                     */
+                    return -1;
+                }
+
+                /*
+                 * Adjust |init_off| and |init_num| to allow room for a new
+                 * message header for this fragment.
+                 */
+                s->init_off -= DTLS1_HM_HEADER_LENGTH;
+                s->init_num += DTLS1_HM_HEADER_LENGTH;
+            } else {
+                /*
+                 * We must have been called again after a retry so use the
+                 * fragment offset from our last attempt. We do not need
+                 * to adjust |init_off| and |init_num| as above, because
+                 * that should already have been done before the retry.
+                 */
+                frag_off = s->d1->w_msg_hdr.frag_off;
+            }
+        }
+
+        used_len = BIO_wpending(s->wbio) + DTLS1_RT_HEADER_LENGTH
+            + mac_size + blocksize;
+        if (s->d1->mtu > used_len)
+            curr_mtu = s->d1->mtu - used_len;
+        else
+            curr_mtu = 0;
+
+        if (curr_mtu <= DTLS1_HM_HEADER_LENGTH) {
+            /*
+             * grr.. we could get an error if MTU picked was wrong
+             */
+            ret = BIO_flush(s->wbio);
+            if (ret <= 0) {
+                s->rwstate = SSL_WRITING;
+                return ret;
+            }
+            used_len = DTLS1_RT_HEADER_LENGTH + mac_size + blocksize;
+            if (s->d1->mtu > used_len + DTLS1_HM_HEADER_LENGTH) {
+                curr_mtu = s->d1->mtu - used_len;
+            } else {
+                /* Shouldn't happen */
+                return -1;
+            }
+        }
+
+        /*
+         * We just checked that s->init_num > 0 so this cast should be safe
+         */
+        if (((unsigned int)s->init_num) > curr_mtu)
+            len = curr_mtu;
+        else
+            len = s->init_num;
+
+        /* Shouldn't ever happen */
+        if (len > INT_MAX)
+            len = INT_MAX;
+
+        /*
+         * XDTLS: this function is too long.  split out the CCS part
+         */
+        if (type == SSL3_RT_HANDSHAKE) {
+            if (len < DTLS1_HM_HEADER_LENGTH) {
+                /*
+                 * len is so small that we really can't do anything sensible
+                 * so fail
+                 */
+                return -1;
+            }
+            dtls1_fix_message_header(s, frag_off, len - DTLS1_HM_HEADER_LENGTH);
+
+            dtls1_write_message_header(s,
+                                       (unsigned char *)&s->init_buf->
+                                       data[s->init_off]);
+        }
+
+        ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off], len);
+        if (ret < 0) {
+            /*
+             * might need to update MTU here, but we don't know which
+             * previous packet caused the failure -- so can't really
+             * retransmit anything.  continue as if everything is fine and
+             * wait for an alert to handle the retransmit
+             */
+            if (retry && BIO_ctrl(SSL_get_wbio(s),
+                                  BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0) {
+                if (!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) {
+                    if (!dtls1_query_mtu(s))
+                        return -1;
+                    /* Have one more go */
+                    retry = 0;
+                } else
+                    return -1;
+            } else {
+                return (-1);
+            }
+        } else {
+
+            /*
+             * bad if this assert fails, only part of the handshake message
+             * got sent.  but why would this happen?
+             */
+            OPENSSL_assert(len == (unsigned int)ret);
+
+            if (type == SSL3_RT_HANDSHAKE && !s->d1->retransmitting) {
+                /*
+                 * should not be done for 'Hello Request's, but in that case
+                 * we'll ignore the result anyway
+                 */
+                unsigned char *p =
+                    (unsigned char *)&s->init_buf->data[s->init_off];
+                const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
+                int xlen;
+
+                if (frag_off == 0 && s->version != DTLS1_BAD_VER) {
+                    /*
+                     * reconstruct message header is if it is being sent in
+                     * single fragment
+                     */
+                    *p++ = msg_hdr->type;
+                    l2n3(msg_hdr->msg_len, p);
+                    s2n(msg_hdr->seq, p);
+                    l2n3(0, p);
+                    l2n3(msg_hdr->msg_len, p);
+                    p -= DTLS1_HM_HEADER_LENGTH;
+                    xlen = ret;
+                } else {
+                    p += DTLS1_HM_HEADER_LENGTH;
+                    xlen = ret - DTLS1_HM_HEADER_LENGTH;
+                }
+
+                if (!ssl3_finish_mac(s, p, xlen))
+                    return -1;
+            }
+
+            if (ret == s->init_num) {
+                if (s->msg_callback)
+                    s->msg_callback(1, s->version, type, s->init_buf->data,
+                                    (size_t)(s->init_off + s->init_num), s,
+                                    s->msg_callback_arg);
+
+                s->init_off = 0; /* done writing this message */
+                s->init_num = 0;
+
+                return (1);
+            }
+            s->init_off += ret;
+            s->init_num -= ret;
+            ret -= DTLS1_HM_HEADER_LENGTH;
+            frag_off += ret;
+
+            /*
+             * We save the fragment offset for the next fragment so we have it
+             * available in case of an IO retry. We don't know the length of the
+             * next fragment yet so just set that to 0 for now. It will be
+             * updated again later.
+             */
+            dtls1_fix_message_header(s, frag_off, 0);
+        }
+    }
+    return (0);
+}
+
+int dtls_get_message(SSL *s, int *mt, unsigned long *len)
+{
+    struct hm_header_st *msg_hdr;
+    unsigned char *p;
+    unsigned long msg_len;
+    int ok;
+    long tmplen;
+
+    msg_hdr = &s->d1->r_msg_hdr;
+    memset(msg_hdr, 0, sizeof(*msg_hdr));
+
+ again:
+    ok = dtls_get_reassembled_message(s, &tmplen);
+    if (tmplen == DTLS1_HM_BAD_FRAGMENT || tmplen == DTLS1_HM_FRAGMENT_RETRY) {
+        /* bad fragment received */
+        goto again;
+    } else if (tmplen <= 0 && !ok) {
+        return 0;
+    }
+
+    *mt = s->s3->tmp.message_type;
+
+    p = (unsigned char *)s->init_buf->data;
+
+    if (*mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
+        if (s->msg_callback) {
+            s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC,
+                            p, 1, s, s->msg_callback_arg);
+        }
+        /*
+         * This isn't a real handshake message so skip the processing below.
+         */
+        *len = (unsigned long)tmplen;
+        return 1;
+    }
+
+    msg_len = msg_hdr->msg_len;
+
+    /* reconstruct message header */
+    *(p++) = msg_hdr->type;
+    l2n3(msg_len, p);
+    s2n(msg_hdr->seq, p);
+    l2n3(0, p);
+    l2n3(msg_len, p);
+    if (s->version != DTLS1_BAD_VER) {
+        p -= DTLS1_HM_HEADER_LENGTH;
+        msg_len += DTLS1_HM_HEADER_LENGTH;
+    }
+
+    if (!ssl3_finish_mac(s, p, msg_len))
+        return 0;
+    if (s->msg_callback)
+        s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
+                        p, msg_len, s, s->msg_callback_arg);
+
+    memset(msg_hdr, 0, sizeof(*msg_hdr));
+
+    s->d1->handshake_read_seq++;
+
+    s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
+    *len = s->init_num;
+
+    return 1;
+}
+
+/*
+ * dtls1_max_handshake_message_len returns the maximum number of bytes
+ * permitted in a DTLS handshake message for |s|. The minimum is 16KB, but
+ * may be greater if the maximum certificate list size requires it.
+ */
+static unsigned long dtls1_max_handshake_message_len(const SSL *s)
+{
+    unsigned long max_len =
+        DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
+    if (max_len < (unsigned long)s->max_cert_list)
+        return s->max_cert_list;
+    return max_len;
+}
+
+static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr)
+{
+    size_t frag_off, frag_len, msg_len;
+
+    msg_len = msg_hdr->msg_len;
+    frag_off = msg_hdr->frag_off;
+    frag_len = msg_hdr->frag_len;
+
+    /* sanity checking */
+    if ((frag_off + frag_len) > msg_len
+            || msg_len > dtls1_max_handshake_message_len(s)) {
+        SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, SSL_R_EXCESSIVE_MESSAGE_SIZE);
+        return SSL_AD_ILLEGAL_PARAMETER;
+    }
+
+    if (s->d1->r_msg_hdr.frag_off == 0) { /* first fragment */
+        /*
+         * msg_len is limited to 2^24, but is effectively checked against
+         * dtls_max_handshake_message_len(s) above
+         */
+        if (!BUF_MEM_grow_clean(s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH)) {
+            SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, ERR_R_BUF_LIB);
+            return SSL_AD_INTERNAL_ERROR;
+        }
+
+        s->s3->tmp.message_size = msg_len;
+        s->d1->r_msg_hdr.msg_len = msg_len;
+        s->s3->tmp.message_type = msg_hdr->type;
+        s->d1->r_msg_hdr.type = msg_hdr->type;
+        s->d1->r_msg_hdr.seq = msg_hdr->seq;
+    } else if (msg_len != s->d1->r_msg_hdr.msg_len) {
+        /*
+         * They must be playing with us! BTW, failure to enforce upper limit
+         * would open possibility for buffer overrun.
+         */
+        SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, SSL_R_EXCESSIVE_MESSAGE_SIZE);
+        return SSL_AD_ILLEGAL_PARAMETER;
+    }
+
+    return 0;                   /* no error */
+}
+
+static int dtls1_retrieve_buffered_fragment(SSL *s, int *ok)
+{
+    /*-
+     * (0) check whether the desired fragment is available
+     * if so:
+     * (1) copy over the fragment to s->init_buf->data[]
+     * (2) update s->init_num
+     */
+    pitem *item;
+    hm_fragment *frag;
+    int al;
+
+    *ok = 0;
+
+    do {
+        item = pqueue_peek(s->d1->buffered_messages);
+        if (item == NULL)
+            return 0;
+
+        frag = (hm_fragment *)item->data;
+
+        if (frag->msg_header.seq < s->d1->handshake_read_seq) {
+            /* This is a stale message that has been buffered so clear it */
+            pqueue_pop(s->d1->buffered_messages);
+            dtls1_hm_fragment_free(frag);
+            pitem_free(item);
+            item = NULL;
+            frag = NULL;
+        }
+    } while (item == NULL);
+
+    /* Don't return if reassembly still in progress */
+    if (frag->reassembly != NULL)
+        return 0;
+
+    if (s->d1->handshake_read_seq == frag->msg_header.seq) {
+        unsigned long frag_len = frag->msg_header.frag_len;
+        pqueue_pop(s->d1->buffered_messages);
+
+        al = dtls1_preprocess_fragment(s, &frag->msg_header);
+
+        if (al == 0) {          /* no alert */
+            unsigned char *p =
+                (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
+            memcpy(&p[frag->msg_header.frag_off], frag->fragment,
+                   frag->msg_header.frag_len);
+        }
+
+        dtls1_hm_fragment_free(frag);
+        pitem_free(item);
+
+        if (al == 0) {
+            *ok = 1;
+            return frag_len;
+        }
+
+        ssl3_send_alert(s, SSL3_AL_FATAL, al);
+        s->init_num = 0;
+        *ok = 0;
+        return -1;
+    } else
+        return 0;
+}
+
+static int
+dtls1_reassemble_fragment(SSL *s, const struct hm_header_st *msg_hdr, int *ok)
+{
+    hm_fragment *frag = NULL;
+    pitem *item = NULL;
+    int i = -1, is_complete;
+    unsigned char seq64be[8];
+    unsigned long frag_len = msg_hdr->frag_len;
+
+    if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len ||
+        msg_hdr->msg_len > dtls1_max_handshake_message_len(s))
+        goto err;
+
+    if (frag_len == 0)
+        return DTLS1_HM_FRAGMENT_RETRY;
+
+    /* Try to find item in queue */
+    memset(seq64be, 0, sizeof(seq64be));
+    seq64be[6] = (unsigned char)(msg_hdr->seq >> 8);
+    seq64be[7] = (unsigned char)msg_hdr->seq;
+    item = pqueue_find(s->d1->buffered_messages, seq64be);
+
+    if (item == NULL) {
+        frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1);
+        if (frag == NULL)
+            goto err;
+        memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
+        frag->msg_header.frag_len = frag->msg_header.msg_len;
+        frag->msg_header.frag_off = 0;
+    } else {
+        frag = (hm_fragment *)item->data;
+        if (frag->msg_header.msg_len != msg_hdr->msg_len) {
+            item = NULL;
+            frag = NULL;
+            goto err;
+        }
+    }
+
+    /*
+     * If message is already reassembled, this must be a retransmit and can
+     * be dropped. In this case item != NULL and so frag does not need to be
+     * freed.
+     */
+    if (frag->reassembly == NULL) {
+        unsigned char devnull[256];
+
+        while (frag_len) {
+            i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL,
+                                          devnull,
+                                          frag_len >
+                                          sizeof(devnull) ? sizeof(devnull) :
+                                          frag_len, 0);
+            if (i <= 0)
+                goto err;
+            frag_len -= i;
+        }
+        return DTLS1_HM_FRAGMENT_RETRY;
+    }
+
+    /* read the body of the fragment (header has already been read */
+    i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL,
+                                  frag->fragment + msg_hdr->frag_off,
+                                  frag_len, 0);
+    if ((unsigned long)i != frag_len)
+        i = -1;
+    if (i <= 0)
+        goto err;
+
+    RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off,
+                        (long)(msg_hdr->frag_off + frag_len));
+
+    RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len,
+                               is_complete);
+
+    if (is_complete) {
+        OPENSSL_free(frag->reassembly);
+        frag->reassembly = NULL;
+    }
+
+    if (item == NULL) {
+        item = pitem_new(seq64be, frag);
+        if (item == NULL) {
+            i = -1;
+            goto err;
+        }
+
+        item = pqueue_insert(s->d1->buffered_messages, item);
+        /*
+         * pqueue_insert fails iff a duplicate item is inserted. However,
+         * |item| cannot be a duplicate. If it were, |pqueue_find|, above,
+         * would have returned it and control would never have reached this
+         * branch.
+         */
+        OPENSSL_assert(item != NULL);
+    }
+
+    return DTLS1_HM_FRAGMENT_RETRY;
+
+ err:
+    if (item == NULL)
+        dtls1_hm_fragment_free(frag);
+    *ok = 0;
+    return i;
+}
+
+static int
+dtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st *msg_hdr,
+                                 int *ok)
+{
+    int i = -1;
+    hm_fragment *frag = NULL;
+    pitem *item = NULL;
+    unsigned char seq64be[8];
+    unsigned long frag_len = msg_hdr->frag_len;
+
+    if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len)
+        goto err;
+
+    /* Try to find item in queue, to prevent duplicate entries */
+    memset(seq64be, 0, sizeof(seq64be));
+    seq64be[6] = (unsigned char)(msg_hdr->seq >> 8);
+    seq64be[7] = (unsigned char)msg_hdr->seq;
+    item = pqueue_find(s->d1->buffered_messages, seq64be);
+
+    /*
+     * If we already have an entry and this one is a fragment, don't discard
+     * it and rather try to reassemble it.
+     */
+    if (item != NULL && frag_len != msg_hdr->msg_len)
+        item = NULL;
+
+    /*
+     * Discard the message if sequence number was already there, is too far
+     * in the future, already in the queue or if we received a FINISHED
+     * before the SERVER_HELLO, which then must be a stale retransmit.
+     */
+    if (msg_hdr->seq <= s->d1->handshake_read_seq ||
+        msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL ||
+        (s->d1->handshake_read_seq == 0 && msg_hdr->type == SSL3_MT_FINISHED)) {
+        unsigned char devnull[256];
+
+        while (frag_len) {
+            i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL,
+                                          devnull,
+                                          frag_len >
+                                          sizeof(devnull) ? sizeof(devnull) :
+                                          frag_len, 0);
+            if (i <= 0)
+                goto err;
+            frag_len -= i;
+        }
+    } else {
+        if (frag_len != msg_hdr->msg_len)
+            return dtls1_reassemble_fragment(s, msg_hdr, ok);
+
+        if (frag_len > dtls1_max_handshake_message_len(s))
+            goto err;
+
+        frag = dtls1_hm_fragment_new(frag_len, 0);
+        if (frag == NULL)
+            goto err;
+
+        memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
+
+        if (frag_len) {
+            /*
+             * read the body of the fragment (header has already been read
+             */
+            i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL,
+                                          frag->fragment, frag_len, 0);
+            if ((unsigned long)i != frag_len)
+                i = -1;
+            if (i <= 0)
+                goto err;
+        }
+
+        item = pitem_new(seq64be, frag);
+        if (item == NULL)
+            goto err;
+
+        item = pqueue_insert(s->d1->buffered_messages, item);
+        /*
+         * pqueue_insert fails iff a duplicate item is inserted. However,
+         * |item| cannot be a duplicate. If it were, |pqueue_find|, above,
+         * would have returned it. Then, either |frag_len| !=
+         * |msg_hdr->msg_len| in which case |item| is set to NULL and it will
+         * have been processed with |dtls1_reassemble_fragment|, above, or
+         * the record will have been discarded.
+         */
+        OPENSSL_assert(item != NULL);
+    }
+
+    return DTLS1_HM_FRAGMENT_RETRY;
+
+ err:
+    if (item == NULL)
+        dtls1_hm_fragment_free(frag);
+    *ok = 0;
+    return i;
+}
+
+static int dtls_get_reassembled_message(SSL *s, long *len)
+{
+    unsigned char wire[DTLS1_HM_HEADER_LENGTH];
+    unsigned long mlen, frag_off, frag_len;
+    int i, al, recvd_type;
+    struct hm_header_st msg_hdr;
+    int ok;
+
+ redo:
+    /* see if we have the required fragment already */
+    if ((frag_len = dtls1_retrieve_buffered_fragment(s, &ok)) || ok) {
+        if (ok)
+            s->init_num = frag_len;
+        *len = frag_len;
+        return ok;
+    }
+
+    /* read handshake message header */
+    i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &recvd_type, wire,
+                                  DTLS1_HM_HEADER_LENGTH, 0);
+    if (i <= 0) {               /* nbio, or an error */
+        s->rwstate = SSL_READING;
+        *len = i;
+        return 0;
+    }
+    if (recvd_type == SSL3_RT_CHANGE_CIPHER_SPEC) {
+        if (wire[0] != SSL3_MT_CCS) {
+            al = SSL_AD_UNEXPECTED_MESSAGE;
+            SSLerr(SSL_F_DTLS_GET_REASSEMBLED_MESSAGE,
+                   SSL_R_BAD_CHANGE_CIPHER_SPEC);
+            goto f_err;
+        }
+
+        memcpy(s->init_buf->data, wire, i);
+        s->init_num = i - 1;
+        s->init_msg = s->init_buf->data + 1;
+        s->s3->tmp.message_type = SSL3_MT_CHANGE_CIPHER_SPEC;
+        s->s3->tmp.message_size = i - 1;
+        *len = i - 1;
+        return 1;
+    }
+
+    /* Handshake fails if message header is incomplete */
+    if (i != DTLS1_HM_HEADER_LENGTH) {
+        al = SSL_AD_UNEXPECTED_MESSAGE;
+        SSLerr(SSL_F_DTLS_GET_REASSEMBLED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE);
+        goto f_err;
+    }
+
+    /* parse the message fragment header */
+    dtls1_get_message_header(wire, &msg_hdr);
+
+    mlen = msg_hdr.msg_len;
+    frag_off = msg_hdr.frag_off;
+    frag_len = msg_hdr.frag_len;
+
+    /*
+     * We must have at least frag_len bytes left in the record to be read.
+     * Fragments must not span records.
+     */
+    if (frag_len > RECORD_LAYER_get_rrec_length(&s->rlayer)) {
+        al = SSL3_AD_ILLEGAL_PARAMETER;
+        SSLerr(SSL_F_DTLS_GET_REASSEMBLED_MESSAGE, SSL_R_BAD_LENGTH);
+        goto f_err;
+    }
+
+    /*
+     * if this is a future (or stale) message it gets buffered
+     * (or dropped)--no further processing at this time
+     * While listening, we accept seq 1 (ClientHello with cookie)
+     * although we're still expecting seq 0 (ClientHello)
+     */
+    if (msg_hdr.seq != s->d1->handshake_read_seq) {
+        *len = dtls1_process_out_of_seq_message(s, &msg_hdr, &ok);
+        return ok;
+    }
+
+    if (frag_len && frag_len < mlen) {
+        *len = dtls1_reassemble_fragment(s, &msg_hdr, &ok);
+        return ok;
+    }
+
+    if (!s->server && s->d1->r_msg_hdr.frag_off == 0 &&
+        wire[0] == SSL3_MT_HELLO_REQUEST) {
+        /*
+         * The server may always send 'Hello Request' messages -- we are
+         * doing a handshake anyway now, so ignore them if their format is
+         * correct. Does not count for 'Finished' MAC.
+         */
+        if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) {
+            if (s->msg_callback)
+                s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
+                                wire, DTLS1_HM_HEADER_LENGTH, s,
+                                s->msg_callback_arg);
+
+            s->init_num = 0;
+            goto redo;
+        } else {                /* Incorrectly formatted Hello request */
+
+            al = SSL_AD_UNEXPECTED_MESSAGE;
+            SSLerr(SSL_F_DTLS_GET_REASSEMBLED_MESSAGE,
+                   SSL_R_UNEXPECTED_MESSAGE);
+            goto f_err;
+        }
+    }
+
+    if ((al = dtls1_preprocess_fragment(s, &msg_hdr)))
+        goto f_err;
+
+    if (frag_len > 0) {
+        unsigned char *p =
+            (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
+
+        i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL,
+                                      &p[frag_off], frag_len, 0);
+
+        /*
+         * This shouldn't ever fail due to NBIO because we already checked
+         * that we have enough data in the record
+         */
+        if (i <= 0) {
+            s->rwstate = SSL_READING;
+            *len = i;
+            return 0;
+        }
+    } else
+        i = 0;
+
+    /*
+     * XDTLS: an incorrectly formatted fragment should cause the handshake
+     * to fail
+     */
+    if (i != (int)frag_len) {
+        al = SSL3_AD_ILLEGAL_PARAMETER;
+        SSLerr(SSL_F_DTLS_GET_REASSEMBLED_MESSAGE, SSL3_AD_ILLEGAL_PARAMETER);
+        goto f_err;
+    }
+
+    /*
+     * Note that s->init_num is *not* used as current offset in
+     * s->init_buf->data, but as a counter summing up fragments' lengths: as
+     * soon as they sum up to handshake packet length, we assume we have got
+     * all the fragments.
+     */
+    *len = s->init_num = frag_len;
+    return 1;
+
+ f_err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    s->init_num = 0;
+    *len = -1;
+    return 0;
+}
+
+/*-
+ * for these 2 messages, we need to
+ * ssl->enc_read_ctx                    re-init
+ * ssl->rlayer.read_sequence            zero
+ * ssl->s3->read_mac_secret             re-init
+ * ssl->session->read_sym_enc           assign
+ * ssl->session->read_compression       assign
+ * ssl->session->read_hash              assign
+ */
+int dtls_construct_change_cipher_spec(SSL *s)
+{
+    unsigned char *p;
+
+    p = (unsigned char *)s->init_buf->data;
+    *p++ = SSL3_MT_CCS;
+    s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
+    s->init_num = DTLS1_CCS_HEADER_LENGTH;
+
+    if (s->version == DTLS1_BAD_VER) {
+        s->d1->next_handshake_write_seq++;
+        s2n(s->d1->handshake_write_seq, p);
+        s->init_num += 2;
+    }
+
+    s->init_off = 0;
+
+    dtls1_set_message_header_int(s, SSL3_MT_CCS, 0,
+                                 s->d1->handshake_write_seq, 0, 0);
+
+    /* buffer the message to handle re-xmits */
+    if (!dtls1_buffer_message(s, 1)) {
+        SSLerr(SSL_F_DTLS_CONSTRUCT_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+
+#ifndef OPENSSL_NO_SCTP
+WORK_STATE dtls_wait_for_dry(SSL *s)
+{
+    int ret;
+
+    /* read app data until dry event */
+    ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
+    if (ret < 0)
+        return WORK_ERROR;
+
+    if (ret == 0) {
+        s->s3->in_read_app_data = 2;
+        s->rwstate = SSL_READING;
+        BIO_clear_retry_flags(SSL_get_rbio(s));
+        BIO_set_retry_read(SSL_get_rbio(s));
+        return WORK_MORE_A;
+    }
+    return WORK_FINISHED_CONTINUE;
+}
+#endif
+
+int dtls1_read_failed(SSL *s, int code)
+{
+    if (code > 0) {
+        SSLerr(SSL_F_DTLS1_READ_FAILED, ERR_R_INTERNAL_ERROR);
+        return 1;
+    }
+
+    if (!dtls1_is_timer_expired(s)) {
+        /*
+         * not a timeout, none of our business, let higher layers handle
+         * this.  in fact it's probably an error
+         */
+        return code;
+    }
+#ifndef OPENSSL_NO_HEARTBEATS
+    /* done, no need to send a retransmit */
+    if (!SSL_in_init(s) && !s->tlsext_hb_pending)
+#else
+    /* done, no need to send a retransmit */
+    if (!SSL_in_init(s))
+#endif
+    {
+        BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ);
+        return code;
+    }
+
+    return dtls1_handle_timeout(s);
+}
+
+int dtls1_get_queue_priority(unsigned short seq, int is_ccs)
+{
+    /*
+     * The index of the retransmission queue actually is the message sequence
+     * number, since the queue only contains messages of a single handshake.
+     * However, the ChangeCipherSpec has no message sequence number and so
+     * using only the sequence will result in the CCS and Finished having the
+     * same index. To prevent this, the sequence number is multiplied by 2.
+     * In case of a CCS 1 is subtracted. This does not only differ CSS and
+     * Finished, it also maintains the order of the index (important for
+     * priority queues) and fits in the unsigned short variable.
+     */
+    return seq * 2 - is_ccs;
+}
+
+int dtls1_retransmit_buffered_messages(SSL *s)
+{
+    pqueue *sent = s->d1->sent_messages;
+    piterator iter;
+    pitem *item;
+    hm_fragment *frag;
+    int found = 0;
+
+    iter = pqueue_iterator(sent);
+
+    for (item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) {
+        frag = (hm_fragment *)item->data;
+        if (dtls1_retransmit_message(s, (unsigned short)
+                                     dtls1_get_queue_priority
+                                     (frag->msg_header.seq,
+                                      frag->msg_header.is_ccs), &found) <= 0)
+            return -1;
+    }
+
+    return 1;
+}
+
+int dtls1_buffer_message(SSL *s, int is_ccs)
+{
+    pitem *item;
+    hm_fragment *frag;
+    unsigned char seq64be[8];
+
+    /*
+     * this function is called immediately after a message has been
+     * serialized
+     */
+    OPENSSL_assert(s->init_off == 0);
+
+    frag = dtls1_hm_fragment_new(s->init_num, 0);
+    if (frag == NULL)
+        return 0;
+
+    memcpy(frag->fragment, s->init_buf->data, s->init_num);
+
+    if (is_ccs) {
+        /* For DTLS1_BAD_VER the header length is non-standard */
+        OPENSSL_assert(s->d1->w_msg_hdr.msg_len +
+                       ((s->version ==
+                         DTLS1_BAD_VER) ? 3 : DTLS1_CCS_HEADER_LENGTH)
+                       == (unsigned int)s->init_num);
+    } else {
+        OPENSSL_assert(s->d1->w_msg_hdr.msg_len +
+                       DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num);
+    }
+
+    frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len;
+    frag->msg_header.seq = s->d1->w_msg_hdr.seq;
+    frag->msg_header.type = s->d1->w_msg_hdr.type;
+    frag->msg_header.frag_off = 0;
+    frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len;
+    frag->msg_header.is_ccs = is_ccs;
+
+    /* save current state */
+    frag->msg_header.saved_retransmit_state.enc_write_ctx = s->enc_write_ctx;
+    frag->msg_header.saved_retransmit_state.write_hash = s->write_hash;
+    frag->msg_header.saved_retransmit_state.compress = s->compress;
+    frag->msg_header.saved_retransmit_state.session = s->session;
+    frag->msg_header.saved_retransmit_state.epoch =
+        DTLS_RECORD_LAYER_get_w_epoch(&s->rlayer);
+
+    memset(seq64be, 0, sizeof(seq64be));
+    seq64be[6] =
+        (unsigned
+         char)(dtls1_get_queue_priority(frag->msg_header.seq,
+                                        frag->msg_header.is_ccs) >> 8);
+    seq64be[7] =
+        (unsigned
+         char)(dtls1_get_queue_priority(frag->msg_header.seq,
+                                        frag->msg_header.is_ccs));
+
+    item = pitem_new(seq64be, frag);
+    if (item == NULL) {
+        dtls1_hm_fragment_free(frag);
+        return 0;
+    }
+
+    pqueue_insert(s->d1->sent_messages, item);
+    return 1;
+}
+
+int dtls1_retransmit_message(SSL *s, unsigned short seq, int *found)
+{
+    int ret;
+    /* XDTLS: for now assuming that read/writes are blocking */
+    pitem *item;
+    hm_fragment *frag;
+    unsigned long header_length;
+    unsigned char seq64be[8];
+    struct dtls1_retransmit_state saved_state;
+
+    /*-
+      OPENSSL_assert(s->init_num == 0);
+      OPENSSL_assert(s->init_off == 0);
+     */
+
+    /* XDTLS:  the requested message ought to be found, otherwise error */
+    memset(seq64be, 0, sizeof(seq64be));
+    seq64be[6] = (unsigned char)(seq >> 8);
+    seq64be[7] = (unsigned char)seq;
+
+    item = pqueue_find(s->d1->sent_messages, seq64be);
+    if (item == NULL) {
+        SSLerr(SSL_F_DTLS1_RETRANSMIT_MESSAGE, ERR_R_INTERNAL_ERROR);
+        *found = 0;
+        return 0;
+    }
+
+    *found = 1;
+    frag = (hm_fragment *)item->data;
+
+    if (frag->msg_header.is_ccs)
+        header_length = DTLS1_CCS_HEADER_LENGTH;
+    else
+        header_length = DTLS1_HM_HEADER_LENGTH;
+
+    memcpy(s->init_buf->data, frag->fragment,
+           frag->msg_header.msg_len + header_length);
+    s->init_num = frag->msg_header.msg_len + header_length;
+
+    dtls1_set_message_header_int(s, frag->msg_header.type,
+                                 frag->msg_header.msg_len,
+                                 frag->msg_header.seq, 0,
+                                 frag->msg_header.frag_len);
+
+    /* save current state */
+    saved_state.enc_write_ctx = s->enc_write_ctx;
+    saved_state.write_hash = s->write_hash;
+    saved_state.compress = s->compress;
+    saved_state.session = s->session;
+    saved_state.epoch = DTLS_RECORD_LAYER_get_w_epoch(&s->rlayer);
+
+    s->d1->retransmitting = 1;
+
+    /* restore state in which the message was originally sent */
+    s->enc_write_ctx = frag->msg_header.saved_retransmit_state.enc_write_ctx;
+    s->write_hash = frag->msg_header.saved_retransmit_state.write_hash;
+    s->compress = frag->msg_header.saved_retransmit_state.compress;
+    s->session = frag->msg_header.saved_retransmit_state.session;
+    DTLS_RECORD_LAYER_set_saved_w_epoch(&s->rlayer,
+                                        frag->msg_header.
+                                        saved_retransmit_state.epoch);
+
+    ret = dtls1_do_write(s, frag->msg_header.is_ccs ?
+                         SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE);
+
+    /* restore current state */
+    s->enc_write_ctx = saved_state.enc_write_ctx;
+    s->write_hash = saved_state.write_hash;
+    s->compress = saved_state.compress;
+    s->session = saved_state.session;
+    DTLS_RECORD_LAYER_set_saved_w_epoch(&s->rlayer, saved_state.epoch);
+
+    s->d1->retransmitting = 0;
+
+    (void)BIO_flush(s->wbio);
+    return ret;
+}
+
+void dtls1_set_message_header(SSL *s,
+                              unsigned char mt, unsigned long len,
+                              unsigned long frag_off, unsigned long frag_len)
+{
+    if (frag_off == 0) {
+        s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
+        s->d1->next_handshake_write_seq++;
+    }
+
+    dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq,
+                                 frag_off, frag_len);
+}
+
+/* don't actually do the writing, wait till the MTU has been retrieved */
+static void
+dtls1_set_message_header_int(SSL *s, unsigned char mt,
+                             unsigned long len, unsigned short seq_num,
+                             unsigned long frag_off, unsigned long frag_len)
+{
+    struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
+
+    msg_hdr->type = mt;
+    msg_hdr->msg_len = len;
+    msg_hdr->seq = seq_num;
+    msg_hdr->frag_off = frag_off;
+    msg_hdr->frag_len = frag_len;
+}
+
+static void
+dtls1_fix_message_header(SSL *s, unsigned long frag_off, unsigned long frag_len)
+{
+    struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
+
+    msg_hdr->frag_off = frag_off;
+    msg_hdr->frag_len = frag_len;
+}
+
+static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p)
+{
+    struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
+
+    *p++ = msg_hdr->type;
+    l2n3(msg_hdr->msg_len, p);
+
+    s2n(msg_hdr->seq, p);
+    l2n3(msg_hdr->frag_off, p);
+    l2n3(msg_hdr->frag_len, p);
+
+    return p;
+}
+
+void dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr)
+{
+    memset(msg_hdr, 0, sizeof(*msg_hdr));
+    msg_hdr->type = *(data++);
+    n2l3(data, msg_hdr->msg_len);
+
+    n2s(data, msg_hdr->seq);
+    n2l3(data, msg_hdr->frag_off);
+    n2l3(data, msg_hdr->frag_len);
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem_lib.c	(revision 331)
@@ -0,0 +1,1092 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include <limits.h>
+#include <string.h>
+#include <stdio.h>
+#include "../ssl_locl.h"
+#include "statem_locl.h"
+#include <openssl/buffer.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+
+/*
+ * send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or
+ * SSL3_RT_CHANGE_CIPHER_SPEC)
+ */
+int ssl3_do_write(SSL *s, int type)
+{
+    int ret;
+
+    ret = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off],
+                           s->init_num);
+    if (ret < 0)
+        return (-1);
+    if (type == SSL3_RT_HANDSHAKE)
+        /*
+         * should not be done for 'Hello Request's, but in that case we'll
+         * ignore the result anyway
+         */
+        if (!ssl3_finish_mac(s,
+                             (unsigned char *)&s->init_buf->data[s->init_off],
+                             ret))
+            return -1;
+
+    if (ret == s->init_num) {
+        if (s->msg_callback)
+            s->msg_callback(1, s->version, type, s->init_buf->data,
+                            (size_t)(s->init_off + s->init_num), s,
+                            s->msg_callback_arg);
+        return (1);
+    }
+    s->init_off += ret;
+    s->init_num -= ret;
+    return (0);
+}
+
+int tls_construct_finished(SSL *s, const char *sender, int slen)
+{
+    unsigned char *p;
+    int i;
+    unsigned long l;
+
+    p = ssl_handshake_start(s);
+
+    i = s->method->ssl3_enc->final_finish_mac(s,
+                                              sender, slen,
+                                              s->s3->tmp.finish_md);
+    if (i <= 0)
+        return 0;
+    s->s3->tmp.finish_md_len = i;
+    memcpy(p, s->s3->tmp.finish_md, i);
+    l = i;
+
+    /*
+     * Copy the finished so we can use it for renegotiation checks
+     */
+    if (!s->server) {
+        OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
+        memcpy(s->s3->previous_client_finished, s->s3->tmp.finish_md, i);
+        s->s3->previous_client_finished_len = i;
+    } else {
+        OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
+        memcpy(s->s3->previous_server_finished, s->s3->tmp.finish_md, i);
+        s->s3->previous_server_finished_len = i;
+    }
+
+    if (!ssl_set_handshake_header(s, SSL3_MT_FINISHED, l)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_FINISHED, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+}
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+/*
+ * ssl3_take_mac calculates the Finished MAC for the handshakes messages seen
+ * to far.
+ */
+static void ssl3_take_mac(SSL *s)
+{
+    const char *sender;
+    int slen;
+    /*
+     * If no new cipher setup return immediately: other functions will set
+     * the appropriate error.
+     */
+    if (s->s3->tmp.new_cipher == NULL)
+        return;
+    if (!s->server) {
+        sender = s->method->ssl3_enc->server_finished_label;
+        slen = s->method->ssl3_enc->server_finished_label_len;
+    } else {
+        sender = s->method->ssl3_enc->client_finished_label;
+        slen = s->method->ssl3_enc->client_finished_label_len;
+    }
+
+    s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
+                                                                          sender,
+                                                                          slen,
+                                                                          s->s3->tmp.peer_finish_md);
+}
+#endif
+
+MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, PACKET *pkt)
+{
+    int al;
+    long remain;
+
+    remain = PACKET_remaining(pkt);
+    /*
+     * 'Change Cipher Spec' is just a single byte, which should already have
+     * been consumed by ssl_get_message() so there should be no bytes left,
+     * unless we're using DTLS1_BAD_VER, which has an extra 2 bytes
+     */
+    if (SSL_IS_DTLS(s)) {
+        if ((s->version == DTLS1_BAD_VER
+             && remain != DTLS1_CCS_HEADER_LENGTH + 1)
+            || (s->version != DTLS1_BAD_VER
+                && remain != DTLS1_CCS_HEADER_LENGTH - 1)) {
+            al = SSL_AD_ILLEGAL_PARAMETER;
+            SSLerr(SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC,
+                   SSL_R_BAD_CHANGE_CIPHER_SPEC);
+            goto f_err;
+        }
+    } else {
+        if (remain != 0) {
+            al = SSL_AD_ILLEGAL_PARAMETER;
+            SSLerr(SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC,
+                   SSL_R_BAD_CHANGE_CIPHER_SPEC);
+            goto f_err;
+        }
+    }
+
+    /* Check we have a cipher to change to */
+    if (s->s3->tmp.new_cipher == NULL) {
+        al = SSL_AD_UNEXPECTED_MESSAGE;
+        SSLerr(SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC, SSL_R_CCS_RECEIVED_EARLY);
+        goto f_err;
+    }
+
+    s->s3->change_cipher_spec = 1;
+    if (!ssl3_do_change_cipher_spec(s)) {
+        al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR);
+        goto f_err;
+    }
+
+    if (SSL_IS_DTLS(s)) {
+        dtls1_reset_seq_numbers(s, SSL3_CC_READ);
+
+        if (s->version == DTLS1_BAD_VER)
+            s->d1->handshake_read_seq++;
+
+#ifndef OPENSSL_NO_SCTP
+        /*
+         * Remember that a CCS has been received, so that an old key of
+         * SCTP-Auth can be deleted when a CCS is sent. Will be ignored if no
+         * SCTP is used
+         */
+        BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD, 1, NULL);
+#endif
+    }
+
+    return MSG_PROCESS_CONTINUE_READING;
+ f_err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    ossl_statem_set_error(s);
+    return MSG_PROCESS_ERROR;
+}
+
+MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt)
+{
+    int al, i;
+
+    /* If this occurs, we have missed a message */
+    if (!s->s3->change_cipher_spec) {
+        al = SSL_AD_UNEXPECTED_MESSAGE;
+        SSLerr(SSL_F_TLS_PROCESS_FINISHED, SSL_R_GOT_A_FIN_BEFORE_A_CCS);
+        goto f_err;
+    }
+    s->s3->change_cipher_spec = 0;
+
+    i = s->s3->tmp.peer_finish_md_len;
+
+    if ((unsigned long)i != PACKET_remaining(pkt)) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_FINISHED, SSL_R_BAD_DIGEST_LENGTH);
+        goto f_err;
+    }
+
+    if (CRYPTO_memcmp(PACKET_data(pkt), s->s3->tmp.peer_finish_md, i) != 0) {
+        al = SSL_AD_DECRYPT_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_FINISHED, SSL_R_DIGEST_CHECK_FAILED);
+        goto f_err;
+    }
+
+    /*
+     * Copy the finished so we can use it for renegotiation checks
+     */
+    if (s->server) {
+        OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
+        memcpy(s->s3->previous_client_finished, s->s3->tmp.peer_finish_md, i);
+        s->s3->previous_client_finished_len = i;
+    } else {
+        OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
+        memcpy(s->s3->previous_server_finished, s->s3->tmp.peer_finish_md, i);
+        s->s3->previous_server_finished_len = i;
+    }
+
+    return MSG_PROCESS_FINISHED_READING;
+ f_err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    ossl_statem_set_error(s);
+    return MSG_PROCESS_ERROR;
+}
+
+int tls_construct_change_cipher_spec(SSL *s)
+{
+    unsigned char *p;
+
+    p = (unsigned char *)s->init_buf->data;
+    *p = SSL3_MT_CCS;
+    s->init_num = 1;
+    s->init_off = 0;
+
+    return 1;
+}
+
+unsigned long ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk)
+{
+    unsigned char *p;
+    unsigned long l = 3 + SSL_HM_HEADER_LENGTH(s);
+
+    if (!ssl_add_cert_chain(s, cpk, &l))
+        return 0;
+
+    l -= 3 + SSL_HM_HEADER_LENGTH(s);
+    p = ssl_handshake_start(s);
+    l2n3(l, p);
+    l += 3;
+
+    if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE, l)) {
+        SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+    return l + SSL_HM_HEADER_LENGTH(s);
+}
+
+WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst)
+{
+    void (*cb) (const SSL *ssl, int type, int val) = NULL;
+
+#ifndef OPENSSL_NO_SCTP
+    if (SSL_IS_DTLS(s) && BIO_dgram_is_sctp(SSL_get_wbio(s))) {
+        WORK_STATE ret;
+        ret = dtls_wait_for_dry(s);
+        if (ret != WORK_FINISHED_CONTINUE)
+            return ret;
+    }
+#endif
+
+    /* clean a few things up */
+    ssl3_cleanup_key_block(s);
+
+    if (!SSL_IS_DTLS(s)) {
+        /*
+         * We don't do this in DTLS because we may still need the init_buf
+         * in case there are any unexpected retransmits
+         */
+        BUF_MEM_free(s->init_buf);
+        s->init_buf = NULL;
+    }
+
+    ssl_free_wbio_buffer(s);
+
+    s->init_num = 0;
+
+    if (!s->server || s->renegotiate == 2) {
+        /* skipped if we just sent a HelloRequest */
+        s->renegotiate = 0;
+        s->new_session = 0;
+
+        if (s->server) {
+            ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
+
+            s->ctx->stats.sess_accept_good++;
+            s->handshake_func = ossl_statem_accept;
+        } else {
+            ssl_update_cache(s, SSL_SESS_CACHE_CLIENT);
+            if (s->hit)
+                s->ctx->stats.sess_hit++;
+
+            s->handshake_func = ossl_statem_connect;
+            s->ctx->stats.sess_connect_good++;
+        }
+
+        if (s->info_callback != NULL)
+            cb = s->info_callback;
+        else if (s->ctx->info_callback != NULL)
+            cb = s->ctx->info_callback;
+
+        if (cb != NULL)
+            cb(s, SSL_CB_HANDSHAKE_DONE, 1);
+
+        if (SSL_IS_DTLS(s)) {
+            /* done with handshaking */
+            s->d1->handshake_read_seq = 0;
+            s->d1->handshake_write_seq = 0;
+            s->d1->next_handshake_write_seq = 0;
+            dtls1_clear_received_buffer(s);
+        }
+    }
+
+    return WORK_FINISHED_STOP;
+}
+
+int tls_get_message_header(SSL *s, int *mt)
+{
+    /* s->init_num < SSL3_HM_HEADER_LENGTH */
+    int skip_message, i, recvd_type, al;
+    unsigned char *p;
+    unsigned long l;
+
+    p = (unsigned char *)s->init_buf->data;
+
+    do {
+        while (s->init_num < SSL3_HM_HEADER_LENGTH) {
+            i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &recvd_type,
+                                          &p[s->init_num],
+                                          SSL3_HM_HEADER_LENGTH - s->init_num,
+                                          0);
+            if (i <= 0) {
+                s->rwstate = SSL_READING;
+                return 0;
+            }
+            if (recvd_type == SSL3_RT_CHANGE_CIPHER_SPEC) {
+                /*
+                 * A ChangeCipherSpec must be a single byte and may not occur
+                 * in the middle of a handshake message.
+                 */
+                if (s->init_num != 0 || i != 1 || p[0] != SSL3_MT_CCS) {
+                    al = SSL_AD_UNEXPECTED_MESSAGE;
+                    SSLerr(SSL_F_TLS_GET_MESSAGE_HEADER,
+                           SSL_R_BAD_CHANGE_CIPHER_SPEC);
+                    goto f_err;
+                }
+                s->s3->tmp.message_type = *mt = SSL3_MT_CHANGE_CIPHER_SPEC;
+                s->init_num = i - 1;
+                s->init_msg = s->init_buf->data;
+                s->s3->tmp.message_size = i;
+                return 1;
+            } else if (recvd_type != SSL3_RT_HANDSHAKE) {
+                al = SSL_AD_UNEXPECTED_MESSAGE;
+                SSLerr(SSL_F_TLS_GET_MESSAGE_HEADER, SSL_R_CCS_RECEIVED_EARLY);
+                goto f_err;
+            }
+            s->init_num += i;
+        }
+
+        skip_message = 0;
+        if (!s->server)
+            if (p[0] == SSL3_MT_HELLO_REQUEST)
+                /*
+                 * The server may always send 'Hello Request' messages --
+                 * we are doing a handshake anyway now, so ignore them if
+                 * their format is correct. Does not count for 'Finished'
+                 * MAC.
+                 */
+                if (p[1] == 0 && p[2] == 0 && p[3] == 0) {
+                    s->init_num = 0;
+                    skip_message = 1;
+
+                    if (s->msg_callback)
+                        s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
+                                        p, SSL3_HM_HEADER_LENGTH, s,
+                                        s->msg_callback_arg);
+                }
+    } while (skip_message);
+    /* s->init_num == SSL3_HM_HEADER_LENGTH */
+
+    *mt = *p;
+    s->s3->tmp.message_type = *(p++);
+
+    if (RECORD_LAYER_is_sslv2_record(&s->rlayer)) {
+        /*
+         * Only happens with SSLv3+ in an SSLv2 backward compatible
+         * ClientHello
+         *
+         * Total message size is the remaining record bytes to read
+         * plus the SSL3_HM_HEADER_LENGTH bytes that we already read
+         */
+        l = RECORD_LAYER_get_rrec_length(&s->rlayer)
+            + SSL3_HM_HEADER_LENGTH;
+        s->s3->tmp.message_size = l;
+
+        s->init_msg = s->init_buf->data;
+        s->init_num = SSL3_HM_HEADER_LENGTH;
+    } else {
+        n2l3(p, l);
+        /* BUF_MEM_grow takes an 'int' parameter */
+        if (l > (INT_MAX - SSL3_HM_HEADER_LENGTH)) {
+            al = SSL_AD_ILLEGAL_PARAMETER;
+            SSLerr(SSL_F_TLS_GET_MESSAGE_HEADER, SSL_R_EXCESSIVE_MESSAGE_SIZE);
+            goto f_err;
+        }
+        s->s3->tmp.message_size = l;
+
+        s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH;
+        s->init_num = 0;
+    }
+
+    return 1;
+ f_err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    return 0;
+}
+
+int tls_get_message_body(SSL *s, unsigned long *len)
+{
+    long n;
+    unsigned char *p;
+    int i;
+
+    if (s->s3->tmp.message_type == SSL3_MT_CHANGE_CIPHER_SPEC) {
+        /* We've already read everything in */
+        *len = (unsigned long)s->init_num;
+        return 1;
+    }
+
+    p = s->init_msg;
+    n = s->s3->tmp.message_size - s->init_num;
+    while (n > 0) {
+        i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, NULL,
+                                      &p[s->init_num], n, 0);
+        if (i <= 0) {
+            s->rwstate = SSL_READING;
+            *len = 0;
+            return 0;
+        }
+        s->init_num += i;
+        n -= i;
+    }
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+    /*
+     * If receiving Finished, record MAC of prior handshake messages for
+     * Finished verification.
+     */
+    if (*s->init_buf->data == SSL3_MT_FINISHED)
+        ssl3_take_mac(s);
+#endif
+
+    /* Feed this message into MAC computation. */
+    if (RECORD_LAYER_is_sslv2_record(&s->rlayer)) {
+        if (!ssl3_finish_mac(s, (unsigned char *)s->init_buf->data,
+                             s->init_num)) {
+            SSLerr(SSL_F_TLS_GET_MESSAGE_BODY, ERR_R_EVP_LIB);
+            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+            *len = 0;
+            return 0;
+        }
+        if (s->msg_callback)
+            s->msg_callback(0, SSL2_VERSION, 0, s->init_buf->data,
+                            (size_t)s->init_num, s, s->msg_callback_arg);
+    } else {
+        if (!ssl3_finish_mac(s, (unsigned char *)s->init_buf->data,
+                             s->init_num + SSL3_HM_HEADER_LENGTH)) {
+            SSLerr(SSL_F_TLS_GET_MESSAGE_BODY, ERR_R_EVP_LIB);
+            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+            *len = 0;
+            return 0;
+        }
+        if (s->msg_callback)
+            s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data,
+                            (size_t)s->init_num + SSL3_HM_HEADER_LENGTH, s,
+                            s->msg_callback_arg);
+    }
+
+    /*
+     * init_num should never be negative...should probably be declared
+     * unsigned
+     */
+    if (s->init_num < 0) {
+        SSLerr(SSL_F_TLS_GET_MESSAGE_BODY, ERR_R_INTERNAL_ERROR);
+        ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+        *len = 0;
+        return 0;
+    }
+    *len = (unsigned long)s->init_num;
+    return 1;
+}
+
+int ssl_cert_type(const X509 *x, const EVP_PKEY *pk)
+{
+    if (pk == NULL && (pk = X509_get0_pubkey(x)) == NULL)
+        return -1;
+
+    switch (EVP_PKEY_id(pk)) {
+    default:
+        return -1;
+    case EVP_PKEY_RSA:
+        return SSL_PKEY_RSA_ENC;
+    case EVP_PKEY_DSA:
+        return SSL_PKEY_DSA_SIGN;
+#ifndef OPENSSL_NO_EC
+    case EVP_PKEY_EC:
+        return SSL_PKEY_ECC;
+#endif
+#ifndef OPENSSL_NO_GOST
+    case NID_id_GostR3410_2001:
+        return SSL_PKEY_GOST01;
+    case NID_id_GostR3410_2012_256:
+        return SSL_PKEY_GOST12_256;
+    case NID_id_GostR3410_2012_512:
+        return SSL_PKEY_GOST12_512;
+#endif
+    }
+}
+
+int ssl_verify_alarm_type(long type)
+{
+    int al;
+
+    switch (type) {
+    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+    case X509_V_ERR_UNABLE_TO_GET_CRL:
+    case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
+        al = SSL_AD_UNKNOWN_CA;
+        break;
+    case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
+    case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
+    case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
+    case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+    case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+    case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
+    case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
+    case X509_V_ERR_CERT_NOT_YET_VALID:
+    case X509_V_ERR_CRL_NOT_YET_VALID:
+    case X509_V_ERR_CERT_UNTRUSTED:
+    case X509_V_ERR_CERT_REJECTED:
+    case X509_V_ERR_HOSTNAME_MISMATCH:
+    case X509_V_ERR_EMAIL_MISMATCH:
+    case X509_V_ERR_IP_ADDRESS_MISMATCH:
+    case X509_V_ERR_DANE_NO_MATCH:
+    case X509_V_ERR_EE_KEY_TOO_SMALL:
+    case X509_V_ERR_CA_KEY_TOO_SMALL:
+    case X509_V_ERR_CA_MD_TOO_WEAK:
+        al = SSL_AD_BAD_CERTIFICATE;
+        break;
+    case X509_V_ERR_CERT_SIGNATURE_FAILURE:
+    case X509_V_ERR_CRL_SIGNATURE_FAILURE:
+        al = SSL_AD_DECRYPT_ERROR;
+        break;
+    case X509_V_ERR_CERT_HAS_EXPIRED:
+    case X509_V_ERR_CRL_HAS_EXPIRED:
+        al = SSL_AD_CERTIFICATE_EXPIRED;
+        break;
+    case X509_V_ERR_CERT_REVOKED:
+        al = SSL_AD_CERTIFICATE_REVOKED;
+        break;
+    case X509_V_ERR_UNSPECIFIED:
+    case X509_V_ERR_OUT_OF_MEM:
+    case X509_V_ERR_INVALID_CALL:
+    case X509_V_ERR_STORE_LOOKUP:
+        al = SSL_AD_INTERNAL_ERROR;
+        break;
+    case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+    case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
+    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
+    case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
+    case X509_V_ERR_CERT_CHAIN_TOO_LONG:
+    case X509_V_ERR_PATH_LENGTH_EXCEEDED:
+    case X509_V_ERR_INVALID_CA:
+        al = SSL_AD_UNKNOWN_CA;
+        break;
+    case X509_V_ERR_APPLICATION_VERIFICATION:
+        al = SSL_AD_HANDSHAKE_FAILURE;
+        break;
+    case X509_V_ERR_INVALID_PURPOSE:
+        al = SSL_AD_UNSUPPORTED_CERTIFICATE;
+        break;
+    default:
+        al = SSL_AD_CERTIFICATE_UNKNOWN;
+        break;
+    }
+    return (al);
+}
+
+int ssl_allow_compression(SSL *s)
+{
+    if (s->options & SSL_OP_NO_COMPRESSION)
+        return 0;
+    return ssl_security(s, SSL_SECOP_COMPRESSION, 0, 0, NULL);
+}
+
+static int version_cmp(const SSL *s, int a, int b)
+{
+    int dtls = SSL_IS_DTLS(s);
+
+    if (a == b)
+        return 0;
+    if (!dtls)
+        return a < b ? -1 : 1;
+    return DTLS_VERSION_LT(a, b) ? -1 : 1;
+}
+
+typedef struct {
+    int version;
+    const SSL_METHOD *(*cmeth) (void);
+    const SSL_METHOD *(*smeth) (void);
+} version_info;
+
+#if TLS_MAX_VERSION != TLS1_2_VERSION
+# error Code needs update for TLS_method() support beyond TLS1_2_VERSION.
+#endif
+
+static const version_info tls_version_table[] = {
+#ifndef OPENSSL_NO_TLS1_2
+    {TLS1_2_VERSION, tlsv1_2_client_method, tlsv1_2_server_method},
+#else
+    {TLS1_2_VERSION, NULL, NULL},
+#endif
+#ifndef OPENSSL_NO_TLS1_1
+    {TLS1_1_VERSION, tlsv1_1_client_method, tlsv1_1_server_method},
+#else
+    {TLS1_1_VERSION, NULL, NULL},
+#endif
+#ifndef OPENSSL_NO_TLS1
+    {TLS1_VERSION, tlsv1_client_method, tlsv1_server_method},
+#else
+    {TLS1_VERSION, NULL, NULL},
+#endif
+#ifndef OPENSSL_NO_SSL3
+    {SSL3_VERSION, sslv3_client_method, sslv3_server_method},
+#else
+    {SSL3_VERSION, NULL, NULL},
+#endif
+    {0, NULL, NULL},
+};
+
+#if DTLS_MAX_VERSION != DTLS1_2_VERSION
+# error Code needs update for DTLS_method() support beyond DTLS1_2_VERSION.
+#endif
+
+static const version_info dtls_version_table[] = {
+#ifndef OPENSSL_NO_DTLS1_2
+    {DTLS1_2_VERSION, dtlsv1_2_client_method, dtlsv1_2_server_method},
+#else
+    {DTLS1_2_VERSION, NULL, NULL},
+#endif
+#ifndef OPENSSL_NO_DTLS1
+    {DTLS1_VERSION, dtlsv1_client_method, dtlsv1_server_method},
+    {DTLS1_BAD_VER, dtls_bad_ver_client_method, NULL},
+#else
+    {DTLS1_VERSION, NULL, NULL},
+    {DTLS1_BAD_VER, NULL, NULL},
+#endif
+    {0, NULL, NULL},
+};
+
+/*
+ * ssl_method_error - Check whether an SSL_METHOD is enabled.
+ *
+ * @s: The SSL handle for the candidate method
+ * @method: the intended method.
+ *
+ * Returns 0 on success, or an SSL error reason on failure.
+ */
+static int ssl_method_error(const SSL *s, const SSL_METHOD *method)
+{
+    int version = method->version;
+
+    if ((s->min_proto_version != 0 &&
+         version_cmp(s, version, s->min_proto_version) < 0) ||
+        ssl_security(s, SSL_SECOP_VERSION, 0, version, NULL) == 0)
+        return SSL_R_VERSION_TOO_LOW;
+
+    if (s->max_proto_version != 0 &&
+        version_cmp(s, version, s->max_proto_version) > 0)
+        return SSL_R_VERSION_TOO_HIGH;
+
+    if ((s->options & method->mask) != 0)
+        return SSL_R_UNSUPPORTED_PROTOCOL;
+    if ((method->flags & SSL_METHOD_NO_SUITEB) != 0 && tls1_suiteb(s))
+        return SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE;
+    else if ((method->flags & SSL_METHOD_NO_FIPS) != 0 && FIPS_mode())
+        return SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE;
+
+    return 0;
+}
+
+/*
+ * ssl_version_supported - Check that the specified `version` is supported by
+ * `SSL *` instance
+ *
+ * @s: The SSL handle for the candidate method
+ * @version: Protocol version to test against
+ *
+ * Returns 1 when supported, otherwise 0
+ */
+int ssl_version_supported(const SSL *s, int version)
+{
+    const version_info *vent;
+    const version_info *table;
+
+    switch (s->method->version) {
+    default:
+        /* Version should match method version for non-ANY method */
+        return version_cmp(s, version, s->version) == 0;
+    case TLS_ANY_VERSION:
+        table = tls_version_table;
+        break;
+    case DTLS_ANY_VERSION:
+        table = dtls_version_table;
+        break;
+    }
+
+    for (vent = table;
+         vent->version != 0 && version_cmp(s, version, vent->version) <= 0;
+         ++vent) {
+        if (vent->cmeth != NULL &&
+            version_cmp(s, version, vent->version) == 0 &&
+            ssl_method_error(s, vent->cmeth()) == 0) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+/*
+ * ssl_check_version_downgrade - In response to RFC7507 SCSV version
+ * fallback indication from a client check whether we're using the highest
+ * supported protocol version.
+ *
+ * @s server SSL handle.
+ *
+ * Returns 1 when using the highest enabled version, 0 otherwise.
+ */
+int ssl_check_version_downgrade(SSL *s)
+{
+    const version_info *vent;
+    const version_info *table;
+
+    /*
+     * Check that the current protocol is the highest enabled version
+     * (according to s->ctx->method, as version negotiation may have changed
+     * s->method).
+     */
+    if (s->version == s->ctx->method->version)
+        return 1;
+
+    /*
+     * Apparently we're using a version-flexible SSL_METHOD (not at its
+     * highest protocol version).
+     */
+    if (s->ctx->method->version == TLS_method()->version)
+        table = tls_version_table;
+    else if (s->ctx->method->version == DTLS_method()->version)
+        table = dtls_version_table;
+    else {
+        /* Unexpected state; fail closed. */
+        return 0;
+    }
+
+    for (vent = table; vent->version != 0; ++vent) {
+        if (vent->smeth != NULL && ssl_method_error(s, vent->smeth()) == 0)
+            return s->version == vent->version;
+    }
+    return 0;
+}
+
+/*
+ * ssl_set_version_bound - set an upper or lower bound on the supported (D)TLS
+ * protocols, provided the initial (D)TLS method is version-flexible.  This
+ * function sanity-checks the proposed value and makes sure the method is
+ * version-flexible, then sets the limit if all is well.
+ *
+ * @method_version: The version of the current SSL_METHOD.
+ * @version: the intended limit.
+ * @bound: pointer to limit to be updated.
+ *
+ * Returns 1 on success, 0 on failure.
+ */
+int ssl_set_version_bound(int method_version, int version, int *bound)
+{
+    if (version == 0) {
+        *bound = version;
+        return 1;
+    }
+
+    /*-
+     * Restrict TLS methods to TLS protocol versions.
+     * Restrict DTLS methods to DTLS protocol versions.
+     * Note, DTLS version numbers are decreasing, use comparison macros.
+     *
+     * Note that for both lower-bounds we use explicit versions, not
+     * (D)TLS_MIN_VERSION.  This is because we don't want to break user
+     * configurations.  If the MIN (supported) version ever rises, the user's
+     * "floor" remains valid even if no longer available.  We don't expect the
+     * MAX ceiling to ever get lower, so making that variable makes sense.
+     */
+    switch (method_version) {
+    default:
+        /*
+         * XXX For fixed version methods, should we always fail and not set any
+         * bounds, always succeed and not set any bounds, or set the bounds and
+         * arrange to fail later if they are not met?  At present fixed-version
+         * methods are not subject to controls that disable individual protocol
+         * versions.
+         */
+        return 0;
+
+    case TLS_ANY_VERSION:
+        if (version < SSL3_VERSION || version > TLS_MAX_VERSION)
+            return 0;
+        break;
+
+    case DTLS_ANY_VERSION:
+        if (DTLS_VERSION_GT(version, DTLS_MAX_VERSION) ||
+            DTLS_VERSION_LT(version, DTLS1_BAD_VER))
+            return 0;
+        break;
+    }
+
+    *bound = version;
+    return 1;
+}
+
+/*
+ * ssl_choose_server_version - Choose server (D)TLS version.  Called when the
+ * client HELLO is received to select the final server protocol version and
+ * the version specific method.
+ *
+ * @s: server SSL handle.
+ *
+ * Returns 0 on success or an SSL error reason number on failure.
+ */
+int ssl_choose_server_version(SSL *s)
+{
+    /*-
+     * With version-flexible methods we have an initial state with:
+     *
+     *   s->method->version == (D)TLS_ANY_VERSION,
+     *   s->version == (D)TLS_MAX_VERSION.
+     *
+     * So we detect version-flexible methods via the method version, not the
+     * handle version.
+     */
+    int server_version = s->method->version;
+    int client_version = s->client_version;
+    const version_info *vent;
+    const version_info *table;
+    int disabled = 0;
+
+    switch (server_version) {
+    default:
+        if (version_cmp(s, client_version, s->version) < 0)
+            return SSL_R_WRONG_SSL_VERSION;
+        /*
+         * If this SSL handle is not from a version flexible method we don't
+         * (and never did) check min/max FIPS or Suite B constraints.  Hope
+         * that's OK.  It is up to the caller to not choose fixed protocol
+         * versions they don't want.  If not, then easy to fix, just return
+         * ssl_method_error(s, s->method)
+         */
+        return 0;
+    case TLS_ANY_VERSION:
+        table = tls_version_table;
+        break;
+    case DTLS_ANY_VERSION:
+        table = dtls_version_table;
+        break;
+    }
+
+    for (vent = table; vent->version != 0; ++vent) {
+        const SSL_METHOD *method;
+
+        if (vent->smeth == NULL ||
+            version_cmp(s, client_version, vent->version) < 0)
+            continue;
+        method = vent->smeth();
+        if (ssl_method_error(s, method) == 0) {
+            s->version = vent->version;
+            s->method = method;
+            return 0;
+        }
+        disabled = 1;
+    }
+    return disabled ? SSL_R_UNSUPPORTED_PROTOCOL : SSL_R_VERSION_TOO_LOW;
+}
+
+/*
+ * ssl_choose_client_version - Choose client (D)TLS version.  Called when the
+ * server HELLO is received to select the final client protocol version and
+ * the version specific method.
+ *
+ * @s: client SSL handle.
+ * @version: The proposed version from the server's HELLO.
+ *
+ * Returns 0 on success or an SSL error reason number on failure.
+ */
+int ssl_choose_client_version(SSL *s, int version)
+{
+    const version_info *vent;
+    const version_info *table;
+
+    switch (s->method->version) {
+    default:
+        if (version != s->version)
+            return SSL_R_WRONG_SSL_VERSION;
+        /*
+         * If this SSL handle is not from a version flexible method we don't
+         * (and never did) check min/max, FIPS or Suite B constraints.  Hope
+         * that's OK.  It is up to the caller to not choose fixed protocol
+         * versions they don't want.  If not, then easy to fix, just return
+         * ssl_method_error(s, s->method)
+         */
+        return 0;
+    case TLS_ANY_VERSION:
+        table = tls_version_table;
+        break;
+    case DTLS_ANY_VERSION:
+        table = dtls_version_table;
+        break;
+    }
+
+    for (vent = table; vent->version != 0; ++vent) {
+        const SSL_METHOD *method;
+        int err;
+
+        if (version != vent->version)
+            continue;
+        if (vent->cmeth == NULL)
+            break;
+        method = vent->cmeth();
+        err = ssl_method_error(s, method);
+        if (err != 0)
+            return err;
+        s->method = method;
+        s->version = version;
+        return 0;
+    }
+
+    return SSL_R_UNSUPPORTED_PROTOCOL;
+}
+
+/*
+ * ssl_get_client_min_max_version - get minimum and maximum client version
+ * @s: The SSL connection
+ * @min_version: The minimum supported version
+ * @max_version: The maximum supported version
+ *
+ * Work out what version we should be using for the initial ClientHello if the
+ * version is initially (D)TLS_ANY_VERSION.  We apply any explicit SSL_OP_NO_xxx
+ * options, the MinProtocol and MaxProtocol configuration commands, any Suite B
+ * or FIPS_mode() constraints and any floor imposed by the security level here,
+ * so we don't advertise the wrong protocol version to only reject the outcome later.
+ *
+ * Computing the right floor matters.  If, e.g., TLS 1.0 and 1.2 are enabled,
+ * TLS 1.1 is disabled, but the security level, Suite-B  and/or MinProtocol
+ * only allow TLS 1.2, we want to advertise TLS1.2, *not* TLS1.
+ *
+ * Returns 0 on success or an SSL error reason number on failure.  On failure
+ * min_version and max_version will also be set to 0.
+ */
+int ssl_get_client_min_max_version(const SSL *s, int *min_version,
+                                   int *max_version)
+{
+    int version;
+    int hole;
+    const SSL_METHOD *single = NULL;
+    const SSL_METHOD *method;
+    const version_info *table;
+    const version_info *vent;
+
+    switch (s->method->version) {
+    default:
+        /*
+         * If this SSL handle is not from a version flexible method we don't
+         * (and never did) check min/max FIPS or Suite B constraints.  Hope
+         * that's OK.  It is up to the caller to not choose fixed protocol
+         * versions they don't want.  If not, then easy to fix, just return
+         * ssl_method_error(s, s->method)
+         */
+        *min_version = *max_version = s->version;
+        return 0;
+    case TLS_ANY_VERSION:
+        table = tls_version_table;
+        break;
+    case DTLS_ANY_VERSION:
+        table = dtls_version_table;
+        break;
+    }
+
+    /*
+     * SSL_OP_NO_X disables all protocols above X *if* there are some protocols
+     * below X enabled. This is required in order to maintain the "version
+     * capability" vector contiguous. Any versions with a NULL client method
+     * (protocol version client is disabled at compile-time) is also a "hole".
+     *
+     * Our initial state is hole == 1, version == 0.  That is, versions above
+     * the first version in the method table are disabled (a "hole" above
+     * the valid protocol entries) and we don't have a selected version yet.
+     *
+     * Whenever "hole == 1", and we hit an enabled method, its version becomes
+     * the selected version, and the method becomes a candidate "single"
+     * method.  We're no longer in a hole, so "hole" becomes 0.
+     *
+     * If "hole == 0" and we hit an enabled method, then "single" is cleared,
+     * as we support a contiguous range of at least two methods.  If we hit
+     * a disabled method, then hole becomes true again, but nothing else
+     * changes yet, because all the remaining methods may be disabled too.
+     * If we again hit an enabled method after the new hole, it becomes
+     * selected, as we start from scratch.
+     */
+    *min_version = version = 0;
+    hole = 1;
+    for (vent = table; vent->version != 0; ++vent) {
+        /*
+         * A table entry with a NULL client method is still a hole in the
+         * "version capability" vector.
+         */
+        if (vent->cmeth == NULL) {
+            hole = 1;
+            continue;
+        }
+        method = vent->cmeth();
+        if (ssl_method_error(s, method) != 0) {
+            hole = 1;
+        } else if (!hole) {
+            single = NULL;
+            *min_version = method->version;
+        } else {
+            version = (single = method)->version;
+            *min_version = version;
+            hole = 0;
+        }
+    }
+
+    *max_version = version;
+
+    /* Fail if everything is disabled */
+    if (version == 0)
+        return SSL_R_NO_PROTOCOLS_AVAILABLE;
+
+    return 0;
+}
+
+/*
+ * ssl_set_client_hello_version - Work out what version we should be using for
+ * the initial ClientHello.
+ *
+ * @s: client SSL handle.
+ *
+ * Returns 0 on success or an SSL error reason number on failure.
+ */
+int ssl_set_client_hello_version(SSL *s)
+{
+    int ver_min, ver_max, ret;
+
+    ret = ssl_get_client_min_max_version(s, &ver_min, &ver_max);
+
+    if (ret != 0)
+        return ret;
+
+    s->client_version = s->version = ver_max;
+    return 0;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem_locl.h
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem_locl.h	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem_locl.h	(revision 331)
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2015-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
+ */
+
+/*****************************************************************************
+ *                                                                           *
+ * The following definitions are PRIVATE to the state machine. They should   *
+ * NOT be used outside of the state machine.                                 *
+ *                                                                           *
+ *****************************************************************************/
+
+/* Max message length definitions */
+
+/* The spec allows for a longer length than this, but we limit it */
+#define HELLO_VERIFY_REQUEST_MAX_LENGTH 258
+#define SERVER_HELLO_MAX_LENGTH         20000
+#define SERVER_KEY_EXCH_MAX_LENGTH      102400
+#define SERVER_HELLO_DONE_MAX_LENGTH    0
+#define CCS_MAX_LENGTH                  1
+/* Max should actually be 36 but we are generous */
+#define FINISHED_MAX_LENGTH             64
+
+/* Message processing return codes */
+typedef enum {
+    /* Something bad happened */
+    MSG_PROCESS_ERROR,
+    /* We've finished reading - swap to writing */
+    MSG_PROCESS_FINISHED_READING,
+    /*
+     * We've completed the main processing of this message but there is some
+     * post processing to be done.
+     */
+    MSG_PROCESS_CONTINUE_PROCESSING,
+    /* We've finished this message - read the next message */
+    MSG_PROCESS_CONTINUE_READING
+} MSG_PROCESS_RETURN;
+
+/* Flush the write BIO */
+int statem_flush(SSL *s);
+
+/*
+ * TLS/DTLS client state machine functions
+ */
+int ossl_statem_client_read_transition(SSL *s, int mt);
+WRITE_TRAN ossl_statem_client_write_transition(SSL *s);
+WORK_STATE ossl_statem_client_pre_work(SSL *s, WORK_STATE wst);
+WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst);
+int ossl_statem_client_construct_message(SSL *s);
+unsigned long ossl_statem_client_max_message_size(SSL *s);
+MSG_PROCESS_RETURN ossl_statem_client_process_message(SSL *s, PACKET *pkt);
+WORK_STATE ossl_statem_client_post_process_message(SSL *s, WORK_STATE wst);
+
+/*
+ * TLS/DTLS server state machine functions
+ */
+int ossl_statem_server_read_transition(SSL *s, int mt);
+WRITE_TRAN ossl_statem_server_write_transition(SSL *s);
+WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst);
+WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst);
+int ossl_statem_server_construct_message(SSL *s);
+unsigned long ossl_statem_server_max_message_size(SSL *s);
+MSG_PROCESS_RETURN ossl_statem_server_process_message(SSL *s, PACKET *pkt);
+WORK_STATE ossl_statem_server_post_process_message(SSL *s, WORK_STATE wst);
+
+/* Functions for getting new message data */
+__owur int tls_get_message_header(SSL *s, int *mt);
+__owur int tls_get_message_body(SSL *s, unsigned long *len);
+__owur int dtls_get_message(SSL *s, int *mt, unsigned long *len);
+
+/* Message construction and processing functions */
+__owur MSG_PROCESS_RETURN tls_process_change_cipher_spec(SSL *s, PACKET *pkt);
+__owur MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt);
+__owur int tls_construct_change_cipher_spec(SSL *s);
+__owur int dtls_construct_change_cipher_spec(SSL *s);
+
+__owur int tls_construct_finished(SSL *s, const char *sender, int slen);
+__owur WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst);
+__owur WORK_STATE dtls_wait_for_dry(SSL *s);
+
+/* some client-only functions */
+__owur int tls_construct_client_hello(SSL *s);
+__owur MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt);
+__owur MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt);
+__owur MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt);
+__owur MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, PACKET *pkt);
+__owur MSG_PROCESS_RETURN tls_process_server_done(SSL *s, PACKET *pkt);
+__owur int tls_construct_client_verify(SSL *s);
+__owur WORK_STATE tls_prepare_client_certificate(SSL *s, WORK_STATE wst);
+__owur int tls_construct_client_certificate(SSL *s);
+__owur int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey);
+__owur int tls_construct_client_key_exchange(SSL *s);
+__owur int tls_client_key_exchange_post_work(SSL *s);
+__owur int tls_construct_cert_status(SSL *s);
+__owur MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt);
+__owur MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt);
+__owur int ssl3_check_cert_and_algorithm(SSL *s);
+#ifndef OPENSSL_NO_NEXTPROTONEG
+__owur int tls_construct_next_proto(SSL *s);
+#endif
+__owur MSG_PROCESS_RETURN dtls_process_hello_verify(SSL *s, PACKET *pkt);
+
+/* some server-only functions */
+__owur MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt);
+__owur WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst);
+__owur int tls_construct_server_hello(SSL *s);
+__owur int tls_construct_hello_request(SSL *s);
+__owur int dtls_construct_hello_verify_request(SSL *s);
+__owur int tls_construct_server_certificate(SSL *s);
+__owur int tls_construct_server_key_exchange(SSL *s);
+__owur int tls_construct_certificate_request(SSL *s);
+__owur int tls_construct_server_done(SSL *s);
+__owur MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt);
+__owur MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt);
+__owur WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst);
+__owur MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt);
+#ifndef OPENSSL_NO_NEXTPROTONEG
+__owur MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt);
+#endif
+__owur int tls_construct_new_session_ticket(SSL *s);
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem_srvr.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem_srvr.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/statem/statem_srvr.c	(revision 331)
@@ -0,0 +1,3375 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * ECC cipher suite support in OpenSSL originally written by
+ * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <stdio.h>
+#include "../ssl_locl.h"
+#include "statem_locl.h"
+#include "internal/constant_time_locl.h"
+#include <openssl/buffer.h>
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/x509.h>
+#include <openssl/dh.h>
+#include <openssl/bn.h>
+#include <openssl/md5.h>
+
+static STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,
+                                                      PACKET *cipher_suites,
+                                                      STACK_OF(SSL_CIPHER)
+                                                      **skp, int sslv2format,
+                                                      int *al);
+
+/*
+ * server_read_transition() encapsulates the logic for the allowed handshake
+ * state transitions when the server is reading messages from the client. The
+ * message type that the client has sent is provided in |mt|. The current state
+ * is in |s->statem.hand_state|.
+ *
+ *  Valid return values are:
+ *  1: Success (transition allowed)
+ *  0: Error (transition not allowed)
+ */
+int ossl_statem_server_read_transition(SSL *s, int mt)
+{
+    OSSL_STATEM *st = &s->statem;
+
+    switch (st->hand_state) {
+    case TLS_ST_BEFORE:
+    case DTLS_ST_SW_HELLO_VERIFY_REQUEST:
+        if (mt == SSL3_MT_CLIENT_HELLO) {
+            st->hand_state = TLS_ST_SR_CLNT_HELLO;
+            return 1;
+        }
+        break;
+
+    case TLS_ST_SW_SRVR_DONE:
+        /*
+         * If we get a CKE message after a ServerDone then either
+         * 1) We didn't request a Certificate
+         * OR
+         * 2) If we did request one then
+         *      a) We allow no Certificate to be returned
+         *      AND
+         *      b) We are running SSL3 (in TLS1.0+ the client must return a 0
+         *         list if we requested a certificate)
+         */
+        if (mt == SSL3_MT_CLIENT_KEY_EXCHANGE) {
+            if (s->s3->tmp.cert_request) {
+                if (s->version == SSL3_VERSION) {
+                    if ((s->verify_mode & SSL_VERIFY_PEER)
+                        && (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) {
+                        /*
+                         * This isn't an unexpected message as such - we're just
+                         * not going to accept it because we require a client
+                         * cert.
+                         */
+                        ssl3_send_alert(s, SSL3_AL_FATAL,
+                                        SSL3_AD_HANDSHAKE_FAILURE);
+                        SSLerr(SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION,
+                               SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
+                        return 0;
+                    }
+                    st->hand_state = TLS_ST_SR_KEY_EXCH;
+                    return 1;
+                }
+            } else {
+                st->hand_state = TLS_ST_SR_KEY_EXCH;
+                return 1;
+            }
+        } else if (s->s3->tmp.cert_request) {
+            if (mt == SSL3_MT_CERTIFICATE) {
+                st->hand_state = TLS_ST_SR_CERT;
+                return 1;
+            }
+        }
+        break;
+
+    case TLS_ST_SR_CERT:
+        if (mt == SSL3_MT_CLIENT_KEY_EXCHANGE) {
+            st->hand_state = TLS_ST_SR_KEY_EXCH;
+            return 1;
+        }
+        break;
+
+    case TLS_ST_SR_KEY_EXCH:
+        /*
+         * We should only process a CertificateVerify message if we have
+         * received a Certificate from the client. If so then |s->session->peer|
+         * will be non NULL. In some instances a CertificateVerify message is
+         * not required even if the peer has sent a Certificate (e.g. such as in
+         * the case of static DH). In that case |st->no_cert_verify| should be
+         * set.
+         */
+        if (s->session->peer == NULL || st->no_cert_verify) {
+            if (mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
+                /*
+                 * For the ECDH ciphersuites when the client sends its ECDH
+                 * pub key in a certificate, the CertificateVerify message is
+                 * not sent. Also for GOST ciphersuites when the client uses
+                 * its key from the certificate for key exchange.
+                 */
+                st->hand_state = TLS_ST_SR_CHANGE;
+                return 1;
+            }
+        } else {
+            if (mt == SSL3_MT_CERTIFICATE_VERIFY) {
+                st->hand_state = TLS_ST_SR_CERT_VRFY;
+                return 1;
+            }
+        }
+        break;
+
+    case TLS_ST_SR_CERT_VRFY:
+        if (mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
+            st->hand_state = TLS_ST_SR_CHANGE;
+            return 1;
+        }
+        break;
+
+    case TLS_ST_SR_CHANGE:
+#ifndef OPENSSL_NO_NEXTPROTONEG
+        if (s->s3->next_proto_neg_seen) {
+            if (mt == SSL3_MT_NEXT_PROTO) {
+                st->hand_state = TLS_ST_SR_NEXT_PROTO;
+                return 1;
+            }
+        } else {
+#endif
+            if (mt == SSL3_MT_FINISHED) {
+                st->hand_state = TLS_ST_SR_FINISHED;
+                return 1;
+            }
+#ifndef OPENSSL_NO_NEXTPROTONEG
+        }
+#endif
+        break;
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+    case TLS_ST_SR_NEXT_PROTO:
+        if (mt == SSL3_MT_FINISHED) {
+            st->hand_state = TLS_ST_SR_FINISHED;
+            return 1;
+        }
+        break;
+#endif
+
+    case TLS_ST_SW_FINISHED:
+        if (mt == SSL3_MT_CHANGE_CIPHER_SPEC) {
+            st->hand_state = TLS_ST_SR_CHANGE;
+            return 1;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    /* No valid transition found */
+    ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_UNEXPECTED_MESSAGE);
+    SSLerr(SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION, SSL_R_UNEXPECTED_MESSAGE);
+    return 0;
+}
+
+/*
+ * Should we send a ServerKeyExchange message?
+ *
+ * Valid return values are:
+ *   1: Yes
+ *   0: No
+ */
+static int send_server_key_exchange(SSL *s)
+{
+    unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+
+    /*
+     * only send a ServerKeyExchange if DH or fortezza but we have a
+     * sign only certificate PSK: may send PSK identity hints For
+     * ECC ciphersuites, we send a serverKeyExchange message only if
+     * the cipher suite is either ECDH-anon or ECDHE. In other cases,
+     * the server certificate contains the server's public key for
+     * key exchange.
+     */
+    if (alg_k & (SSL_kDHE | SSL_kECDHE)
+        /*
+         * PSK: send ServerKeyExchange if PSK identity hint if
+         * provided
+         */
+#ifndef OPENSSL_NO_PSK
+        /* Only send SKE if we have identity hint for plain PSK */
+        || ((alg_k & (SSL_kPSK | SSL_kRSAPSK))
+            && s->cert->psk_identity_hint)
+        /* For other PSK always send SKE */
+        || (alg_k & (SSL_PSK & (SSL_kDHEPSK | SSL_kECDHEPSK)))
+#endif
+#ifndef OPENSSL_NO_SRP
+        /* SRP: send ServerKeyExchange */
+        || (alg_k & SSL_kSRP)
+#endif
+        ) {
+        return 1;
+    }
+
+    return 0;
+}
+
+/*
+ * Should we send a CertificateRequest message?
+ *
+ * Valid return values are:
+ *   1: Yes
+ *   0: No
+ */
+static int send_certificate_request(SSL *s)
+{
+    if (
+           /* don't request cert unless asked for it: */
+           s->verify_mode & SSL_VERIFY_PEER
+           /*
+            * if SSL_VERIFY_CLIENT_ONCE is set, don't request cert
+            * during re-negotiation:
+            */
+           && (s->s3->tmp.finish_md_len == 0 ||
+               !(s->verify_mode & SSL_VERIFY_CLIENT_ONCE))
+           /*
+            * never request cert in anonymous ciphersuites (see
+            * section "Certificate request" in SSL 3 drafts and in
+            * RFC 2246):
+            */
+           && (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
+               /*
+                * ... except when the application insists on
+                * verification (against the specs, but statem_clnt.c accepts
+                * this for SSL 3)
+                */
+               || (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT))
+           /* don't request certificate for SRP auth */
+           && !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aSRP)
+           /*
+            * With normal PSK Certificates and Certificate Requests
+            * are omitted
+            */
+           && !(s->s3->tmp.new_cipher->algorithm_auth & SSL_aPSK)) {
+        return 1;
+    }
+
+    return 0;
+}
+
+/*
+ * server_write_transition() works out what handshake state to move to next
+ * when the server is writing messages to be sent to the client.
+ */
+WRITE_TRAN ossl_statem_server_write_transition(SSL *s)
+{
+    OSSL_STATEM *st = &s->statem;
+
+    switch (st->hand_state) {
+    case TLS_ST_BEFORE:
+        /* Just go straight to trying to read from the client */
+        return WRITE_TRAN_FINISHED;
+
+    case TLS_ST_OK:
+        /* We must be trying to renegotiate */
+        st->hand_state = TLS_ST_SW_HELLO_REQ;
+        return WRITE_TRAN_CONTINUE;
+
+    case TLS_ST_SW_HELLO_REQ:
+        st->hand_state = TLS_ST_OK;
+        ossl_statem_set_in_init(s, 0);
+        return WRITE_TRAN_CONTINUE;
+
+    case TLS_ST_SR_CLNT_HELLO:
+        if (SSL_IS_DTLS(s) && !s->d1->cookie_verified
+            && (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE))
+            st->hand_state = DTLS_ST_SW_HELLO_VERIFY_REQUEST;
+        else
+            st->hand_state = TLS_ST_SW_SRVR_HELLO;
+        return WRITE_TRAN_CONTINUE;
+
+    case DTLS_ST_SW_HELLO_VERIFY_REQUEST:
+        return WRITE_TRAN_FINISHED;
+
+    case TLS_ST_SW_SRVR_HELLO:
+        if (s->hit) {
+            if (s->tlsext_ticket_expected)
+                st->hand_state = TLS_ST_SW_SESSION_TICKET;
+            else
+                st->hand_state = TLS_ST_SW_CHANGE;
+        } else {
+            /* Check if it is anon DH or anon ECDH, */
+            /* normal PSK or SRP */
+            if (!(s->s3->tmp.new_cipher->algorithm_auth &
+                  (SSL_aNULL | SSL_aSRP | SSL_aPSK))) {
+                st->hand_state = TLS_ST_SW_CERT;
+            } else if (send_server_key_exchange(s)) {
+                st->hand_state = TLS_ST_SW_KEY_EXCH;
+            } else if (send_certificate_request(s)) {
+                st->hand_state = TLS_ST_SW_CERT_REQ;
+            } else {
+                st->hand_state = TLS_ST_SW_SRVR_DONE;
+            }
+        }
+        return WRITE_TRAN_CONTINUE;
+
+    case TLS_ST_SW_CERT:
+        if (s->tlsext_status_expected) {
+            st->hand_state = TLS_ST_SW_CERT_STATUS;
+            return WRITE_TRAN_CONTINUE;
+        }
+        /* Fall through */
+
+    case TLS_ST_SW_CERT_STATUS:
+        if (send_server_key_exchange(s)) {
+            st->hand_state = TLS_ST_SW_KEY_EXCH;
+            return WRITE_TRAN_CONTINUE;
+        }
+        /* Fall through */
+
+    case TLS_ST_SW_KEY_EXCH:
+        if (send_certificate_request(s)) {
+            st->hand_state = TLS_ST_SW_CERT_REQ;
+            return WRITE_TRAN_CONTINUE;
+        }
+        /* Fall through */
+
+    case TLS_ST_SW_CERT_REQ:
+        st->hand_state = TLS_ST_SW_SRVR_DONE;
+        return WRITE_TRAN_CONTINUE;
+
+    case TLS_ST_SW_SRVR_DONE:
+        return WRITE_TRAN_FINISHED;
+
+    case TLS_ST_SR_FINISHED:
+        if (s->hit) {
+            st->hand_state = TLS_ST_OK;
+            ossl_statem_set_in_init(s, 0);
+            return WRITE_TRAN_CONTINUE;
+        } else if (s->tlsext_ticket_expected) {
+            st->hand_state = TLS_ST_SW_SESSION_TICKET;
+        } else {
+            st->hand_state = TLS_ST_SW_CHANGE;
+        }
+        return WRITE_TRAN_CONTINUE;
+
+    case TLS_ST_SW_SESSION_TICKET:
+        st->hand_state = TLS_ST_SW_CHANGE;
+        return WRITE_TRAN_CONTINUE;
+
+    case TLS_ST_SW_CHANGE:
+        st->hand_state = TLS_ST_SW_FINISHED;
+        return WRITE_TRAN_CONTINUE;
+
+    case TLS_ST_SW_FINISHED:
+        if (s->hit) {
+            return WRITE_TRAN_FINISHED;
+        }
+        st->hand_state = TLS_ST_OK;
+        ossl_statem_set_in_init(s, 0);
+        return WRITE_TRAN_CONTINUE;
+
+    default:
+        /* Shouldn't happen */
+        return WRITE_TRAN_ERROR;
+    }
+}
+
+/*
+ * Perform any pre work that needs to be done prior to sending a message from
+ * the server to the client.
+ */
+WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst)
+{
+    OSSL_STATEM *st = &s->statem;
+
+    switch (st->hand_state) {
+    case TLS_ST_SW_HELLO_REQ:
+        s->shutdown = 0;
+        if (SSL_IS_DTLS(s))
+            dtls1_clear_sent_buffer(s);
+        break;
+
+    case DTLS_ST_SW_HELLO_VERIFY_REQUEST:
+        s->shutdown = 0;
+        if (SSL_IS_DTLS(s)) {
+            dtls1_clear_sent_buffer(s);
+            /* We don't buffer this message so don't use the timer */
+            st->use_timer = 0;
+        }
+        break;
+
+    case TLS_ST_SW_SRVR_HELLO:
+        if (SSL_IS_DTLS(s)) {
+            /*
+             * Messages we write from now on should be bufferred and
+             * retransmitted if necessary, so we need to use the timer now
+             */
+            st->use_timer = 1;
+        }
+        break;
+
+    case TLS_ST_SW_SRVR_DONE:
+#ifndef OPENSSL_NO_SCTP
+        if (SSL_IS_DTLS(s) && BIO_dgram_is_sctp(SSL_get_wbio(s)))
+            return dtls_wait_for_dry(s);
+#endif
+        return WORK_FINISHED_CONTINUE;
+
+    case TLS_ST_SW_SESSION_TICKET:
+        if (SSL_IS_DTLS(s)) {
+            /*
+             * We're into the last flight. We don't retransmit the last flight
+             * unless we need to, so we don't use the timer
+             */
+            st->use_timer = 0;
+        }
+        break;
+
+    case TLS_ST_SW_CHANGE:
+        s->session->cipher = s->s3->tmp.new_cipher;
+        if (!s->method->ssl3_enc->setup_key_block(s)) {
+            ossl_statem_set_error(s);
+            return WORK_ERROR;
+        }
+        if (SSL_IS_DTLS(s)) {
+            /*
+             * We're into the last flight. We don't retransmit the last flight
+             * unless we need to, so we don't use the timer. This might have
+             * already been set to 0 if we sent a NewSessionTicket message,
+             * but we'll set it again here in case we didn't.
+             */
+            st->use_timer = 0;
+        }
+        return WORK_FINISHED_CONTINUE;
+
+    case TLS_ST_OK:
+        return tls_finish_handshake(s, wst);
+
+    default:
+        /* No pre work to be done */
+        break;
+    }
+
+    return WORK_FINISHED_CONTINUE;
+}
+
+/*
+ * Perform any work that needs to be done after sending a message from the
+ * server to the client.
+ */
+WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst)
+{
+    OSSL_STATEM *st = &s->statem;
+
+    s->init_num = 0;
+
+    switch (st->hand_state) {
+    case TLS_ST_SW_HELLO_REQ:
+        if (statem_flush(s) != 1)
+            return WORK_MORE_A;
+        if (!ssl3_init_finished_mac(s)) {
+            ossl_statem_set_error(s);
+            return WORK_ERROR;
+        }
+        break;
+
+    case DTLS_ST_SW_HELLO_VERIFY_REQUEST:
+        if (statem_flush(s) != 1)
+            return WORK_MORE_A;
+        /* HelloVerifyRequest resets Finished MAC */
+        if (s->version != DTLS1_BAD_VER && !ssl3_init_finished_mac(s)) {
+            ossl_statem_set_error(s);
+            return WORK_ERROR;
+        }
+        /*
+         * The next message should be another ClientHello which we need to
+         * treat like it was the first packet
+         */
+        s->first_packet = 1;
+        break;
+
+    case TLS_ST_SW_SRVR_HELLO:
+#ifndef OPENSSL_NO_SCTP
+        if (SSL_IS_DTLS(s) && s->hit) {
+            unsigned char sctpauthkey[64];
+            char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
+
+            /*
+             * Add new shared key for SCTP-Auth, will be ignored if no
+             * SCTP used.
+             */
+            memcpy(labelbuffer, DTLS1_SCTP_AUTH_LABEL,
+                   sizeof(DTLS1_SCTP_AUTH_LABEL));
+
+            if (SSL_export_keying_material(s, sctpauthkey,
+                                           sizeof(sctpauthkey), labelbuffer,
+                                           sizeof(labelbuffer), NULL, 0,
+                                           0) <= 0) {
+                ossl_statem_set_error(s);
+                return WORK_ERROR;
+            }
+
+            BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
+                     sizeof(sctpauthkey), sctpauthkey);
+        }
+#endif
+        break;
+
+    case TLS_ST_SW_CHANGE:
+#ifndef OPENSSL_NO_SCTP
+        if (SSL_IS_DTLS(s) && !s->hit) {
+            /*
+             * Change to new shared key of SCTP-Auth, will be ignored if
+             * no SCTP used.
+             */
+            BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY,
+                     0, NULL);
+        }
+#endif
+        if (!s->method->ssl3_enc->change_cipher_state(s,
+                                                      SSL3_CHANGE_CIPHER_SERVER_WRITE))
+        {
+            ossl_statem_set_error(s);
+            return WORK_ERROR;
+        }
+
+        if (SSL_IS_DTLS(s))
+            dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);
+        break;
+
+    case TLS_ST_SW_SRVR_DONE:
+        if (statem_flush(s) != 1)
+            return WORK_MORE_A;
+        break;
+
+    case TLS_ST_SW_FINISHED:
+        if (statem_flush(s) != 1)
+            return WORK_MORE_A;
+#ifndef OPENSSL_NO_SCTP
+        if (SSL_IS_DTLS(s) && s->hit) {
+            /*
+             * Change to new shared key of SCTP-Auth, will be ignored if
+             * no SCTP used.
+             */
+            BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY,
+                     0, NULL);
+        }
+#endif
+        break;
+
+    default:
+        /* No post work to be done */
+        break;
+    }
+
+    return WORK_FINISHED_CONTINUE;
+}
+
+/*
+ * Construct a message to be sent from the server to the client.
+ *
+ * Valid return values are:
+ *   1: Success
+ *   0: Error
+ */
+int ossl_statem_server_construct_message(SSL *s)
+{
+    OSSL_STATEM *st = &s->statem;
+
+    switch (st->hand_state) {
+    case DTLS_ST_SW_HELLO_VERIFY_REQUEST:
+        return dtls_construct_hello_verify_request(s);
+
+    case TLS_ST_SW_HELLO_REQ:
+        return tls_construct_hello_request(s);
+
+    case TLS_ST_SW_SRVR_HELLO:
+        return tls_construct_server_hello(s);
+
+    case TLS_ST_SW_CERT:
+        return tls_construct_server_certificate(s);
+
+    case TLS_ST_SW_KEY_EXCH:
+        return tls_construct_server_key_exchange(s);
+
+    case TLS_ST_SW_CERT_REQ:
+        return tls_construct_certificate_request(s);
+
+    case TLS_ST_SW_SRVR_DONE:
+        return tls_construct_server_done(s);
+
+    case TLS_ST_SW_SESSION_TICKET:
+        return tls_construct_new_session_ticket(s);
+
+    case TLS_ST_SW_CERT_STATUS:
+        return tls_construct_cert_status(s);
+
+    case TLS_ST_SW_CHANGE:
+        if (SSL_IS_DTLS(s))
+            return dtls_construct_change_cipher_spec(s);
+        else
+            return tls_construct_change_cipher_spec(s);
+
+    case TLS_ST_SW_FINISHED:
+        return tls_construct_finished(s,
+                                      s->method->
+                                      ssl3_enc->server_finished_label,
+                                      s->method->
+                                      ssl3_enc->server_finished_label_len);
+
+    default:
+        /* Shouldn't happen */
+        break;
+    }
+
+    return 0;
+}
+
+/*
+ * Maximum size (excluding the Handshake header) of a ClientHello message,
+ * calculated as follows:
+ *
+ *  2 + # client_version
+ *  32 + # only valid length for random
+ *  1 + # length of session_id
+ *  32 + # maximum size for session_id
+ *  2 + # length of cipher suites
+ *  2^16-2 + # maximum length of cipher suites array
+ *  1 + # length of compression_methods
+ *  2^8-1 + # maximum length of compression methods
+ *  2 + # length of extensions
+ *  2^16-1 # maximum length of extensions
+ */
+#define CLIENT_HELLO_MAX_LENGTH         131396
+
+#define CLIENT_KEY_EXCH_MAX_LENGTH      2048
+#define NEXT_PROTO_MAX_LENGTH           514
+
+/*
+ * Returns the maximum allowed length for the current message that we are
+ * reading. Excludes the message header.
+ */
+unsigned long ossl_statem_server_max_message_size(SSL *s)
+{
+    OSSL_STATEM *st = &s->statem;
+
+    switch (st->hand_state) {
+    case TLS_ST_SR_CLNT_HELLO:
+        return CLIENT_HELLO_MAX_LENGTH;
+
+    case TLS_ST_SR_CERT:
+        return s->max_cert_list;
+
+    case TLS_ST_SR_KEY_EXCH:
+        return CLIENT_KEY_EXCH_MAX_LENGTH;
+
+    case TLS_ST_SR_CERT_VRFY:
+        return SSL3_RT_MAX_PLAIN_LENGTH;
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+    case TLS_ST_SR_NEXT_PROTO:
+        return NEXT_PROTO_MAX_LENGTH;
+#endif
+
+    case TLS_ST_SR_CHANGE:
+        return CCS_MAX_LENGTH;
+
+    case TLS_ST_SR_FINISHED:
+        return FINISHED_MAX_LENGTH;
+
+    default:
+        /* Shouldn't happen */
+        break;
+    }
+
+    return 0;
+}
+
+/*
+ * Process a message that the server has received from the client.
+ */
+MSG_PROCESS_RETURN ossl_statem_server_process_message(SSL *s, PACKET *pkt)
+{
+    OSSL_STATEM *st = &s->statem;
+
+    switch (st->hand_state) {
+    case TLS_ST_SR_CLNT_HELLO:
+        return tls_process_client_hello(s, pkt);
+
+    case TLS_ST_SR_CERT:
+        return tls_process_client_certificate(s, pkt);
+
+    case TLS_ST_SR_KEY_EXCH:
+        return tls_process_client_key_exchange(s, pkt);
+
+    case TLS_ST_SR_CERT_VRFY:
+        return tls_process_cert_verify(s, pkt);
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+    case TLS_ST_SR_NEXT_PROTO:
+        return tls_process_next_proto(s, pkt);
+#endif
+
+    case TLS_ST_SR_CHANGE:
+        return tls_process_change_cipher_spec(s, pkt);
+
+    case TLS_ST_SR_FINISHED:
+        return tls_process_finished(s, pkt);
+
+    default:
+        /* Shouldn't happen */
+        break;
+    }
+
+    return MSG_PROCESS_ERROR;
+}
+
+/*
+ * Perform any further processing required following the receipt of a message
+ * from the client
+ */
+WORK_STATE ossl_statem_server_post_process_message(SSL *s, WORK_STATE wst)
+{
+    OSSL_STATEM *st = &s->statem;
+
+    switch (st->hand_state) {
+    case TLS_ST_SR_CLNT_HELLO:
+        return tls_post_process_client_hello(s, wst);
+
+    case TLS_ST_SR_KEY_EXCH:
+        return tls_post_process_client_key_exchange(s, wst);
+
+    case TLS_ST_SR_CERT_VRFY:
+#ifndef OPENSSL_NO_SCTP
+        if (                    /* Is this SCTP? */
+               BIO_dgram_is_sctp(SSL_get_wbio(s))
+               /* Are we renegotiating? */
+               && s->renegotiate && BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) {
+            s->s3->in_read_app_data = 2;
+            s->rwstate = SSL_READING;
+            BIO_clear_retry_flags(SSL_get_rbio(s));
+            BIO_set_retry_read(SSL_get_rbio(s));
+            ossl_statem_set_sctp_read_sock(s, 1);
+            return WORK_MORE_A;
+        } else {
+            ossl_statem_set_sctp_read_sock(s, 0);
+        }
+#endif
+        return WORK_FINISHED_CONTINUE;
+
+    default:
+        break;
+    }
+
+    /* Shouldn't happen */
+    return WORK_ERROR;
+}
+
+#ifndef OPENSSL_NO_SRP
+static int ssl_check_srp_ext_ClientHello(SSL *s, int *al)
+{
+    int ret = SSL_ERROR_NONE;
+
+    *al = SSL_AD_UNRECOGNIZED_NAME;
+
+    if ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) &&
+        (s->srp_ctx.TLS_ext_srp_username_callback != NULL)) {
+        if (s->srp_ctx.login == NULL) {
+            /*
+             * RFC 5054 says SHOULD reject, we do so if There is no srp
+             * login name
+             */
+            ret = SSL3_AL_FATAL;
+            *al = SSL_AD_UNKNOWN_PSK_IDENTITY;
+        } else {
+            ret = SSL_srp_server_param_with_username(s, al);
+        }
+    }
+    return ret;
+}
+#endif
+
+int tls_construct_hello_request(SSL *s)
+{
+    if (!ssl_set_handshake_header(s, SSL3_MT_HELLO_REQUEST, 0)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_HELLO_REQUEST, ERR_R_INTERNAL_ERROR);
+        ossl_statem_set_error(s);
+        return 0;
+    }
+
+    return 1;
+}
+
+unsigned int dtls_raw_hello_verify_request(unsigned char *buf,
+                                           unsigned char *cookie,
+                                           unsigned char cookie_len)
+{
+    unsigned int msg_len;
+    unsigned char *p;
+
+    p = buf;
+    /* Always use DTLS 1.0 version: see RFC 6347 */
+    *(p++) = DTLS1_VERSION >> 8;
+    *(p++) = DTLS1_VERSION & 0xFF;
+
+    *(p++) = (unsigned char)cookie_len;
+    memcpy(p, cookie, cookie_len);
+    p += cookie_len;
+    msg_len = p - buf;
+
+    return msg_len;
+}
+
+int dtls_construct_hello_verify_request(SSL *s)
+{
+    unsigned int len;
+    unsigned char *buf;
+
+    buf = (unsigned char *)s->init_buf->data;
+
+    if (s->ctx->app_gen_cookie_cb == NULL ||
+        s->ctx->app_gen_cookie_cb(s, s->d1->cookie,
+                                  &(s->d1->cookie_len)) == 0 ||
+        s->d1->cookie_len > 255) {
+        SSLerr(SSL_F_DTLS_CONSTRUCT_HELLO_VERIFY_REQUEST,
+               SSL_R_COOKIE_GEN_CALLBACK_FAILURE);
+        ossl_statem_set_error(s);
+        return 0;
+    }
+
+    len = dtls_raw_hello_verify_request(&buf[DTLS1_HM_HEADER_LENGTH],
+                                        s->d1->cookie, s->d1->cookie_len);
+
+    dtls1_set_message_header(s, DTLS1_MT_HELLO_VERIFY_REQUEST, len, 0, len);
+    len += DTLS1_HM_HEADER_LENGTH;
+
+    /* number of bytes to write */
+    s->init_num = len;
+    s->init_off = 0;
+
+    return 1;
+}
+
+MSG_PROCESS_RETURN tls_process_client_hello(SSL *s, PACKET *pkt)
+{
+    int i, al = SSL_AD_INTERNAL_ERROR;
+    unsigned int j, complen = 0;
+    unsigned long id;
+    const SSL_CIPHER *c;
+#ifndef OPENSSL_NO_COMP
+    SSL_COMP *comp = NULL;
+#endif
+    STACK_OF(SSL_CIPHER) *ciphers = NULL;
+    int protverr;
+    /* |cookie| will only be initialized for DTLS. */
+    PACKET session_id, cipher_suites, compression, extensions, cookie;
+    int is_v2_record;
+    static const unsigned char null_compression = 0;
+
+    is_v2_record = RECORD_LAYER_is_sslv2_record(&s->rlayer);
+
+    PACKET_null_init(&cookie);
+    /* First lets get s->client_version set correctly */
+    if (is_v2_record) {
+        unsigned int version;
+        unsigned int mt;
+        /*-
+         * An SSLv3/TLSv1 backwards-compatible CLIENT-HELLO in an SSLv2
+         * header is sent directly on the wire, not wrapped as a TLS
+         * record. Our record layer just processes the message length and passes
+         * the rest right through. Its format is:
+         * Byte  Content
+         * 0-1   msg_length - decoded by the record layer
+         * 2     msg_type - s->init_msg points here
+         * 3-4   version
+         * 5-6   cipher_spec_length
+         * 7-8   session_id_length
+         * 9-10  challenge_length
+         * ...   ...
+         */
+
+        if (!PACKET_get_1(pkt, &mt)
+            || mt != SSL2_MT_CLIENT_HELLO) {
+            /*
+             * Should never happen. We should have tested this in the record
+             * layer in order to have determined that this is a SSLv2 record
+             * in the first place
+             */
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+
+        if (!PACKET_get_net_2(pkt, &version)) {
+            /* No protocol version supplied! */
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL);
+            goto err;
+        }
+        if (version == 0x0002) {
+            /* This is real SSLv2. We don't support it. */
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL);
+            goto err;
+        } else if ((version & 0xff00) == (SSL3_VERSION_MAJOR << 8)) {
+            /* SSLv3/TLS */
+            s->client_version = version;
+        } else {
+            /* No idea what protocol this is */
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL);
+            goto err;
+        }
+    } else {
+        /*
+         * use version from inside client hello, not from record header (may
+         * differ: see RFC 2246, Appendix E, second paragraph)
+         */
+        if (!PACKET_get_net_2(pkt, (unsigned int *)&s->client_version)) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
+            goto f_err;
+        }
+    }
+
+    /*
+     * Do SSL/TLS version negotiation if applicable. For DTLS we just check
+     * versions are potentially compatible. Version negotiation comes later.
+     */
+    if (!SSL_IS_DTLS(s)) {
+        protverr = ssl_choose_server_version(s);
+    } else if (s->method->version != DTLS_ANY_VERSION &&
+               DTLS_VERSION_LT(s->client_version, s->version)) {
+        protverr = SSL_R_VERSION_TOO_LOW;
+    } else {
+        protverr = 0;
+    }
+
+    if (protverr) {
+        SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, protverr);
+        if ((!s->enc_write_ctx && !s->write_hash)) {
+            /*
+             * similar to ssl3_get_record, send alert using remote version
+             * number
+             */
+            s->version = s->client_version;
+        }
+        al = SSL_AD_PROTOCOL_VERSION;
+        goto f_err;
+    }
+
+    /* Parse the message and load client random. */
+    if (is_v2_record) {
+        /*
+         * Handle an SSLv2 backwards compatible ClientHello
+         * Note, this is only for SSLv3+ using the backward compatible format.
+         * Real SSLv2 is not supported, and is rejected above.
+         */
+        unsigned int cipher_len, session_id_len, challenge_len;
+        PACKET challenge;
+
+        if (!PACKET_get_net_2(pkt, &cipher_len)
+            || !PACKET_get_net_2(pkt, &session_id_len)
+            || !PACKET_get_net_2(pkt, &challenge_len)) {
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO,
+                   SSL_R_RECORD_LENGTH_MISMATCH);
+            al = SSL_AD_DECODE_ERROR;
+            goto f_err;
+        }
+
+        if (session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
+            goto f_err;
+        }
+
+        if (!PACKET_get_sub_packet(pkt, &cipher_suites, cipher_len)
+            || !PACKET_get_sub_packet(pkt, &session_id, session_id_len)
+            || !PACKET_get_sub_packet(pkt, &challenge, challenge_len)
+            /* No extensions. */
+            || PACKET_remaining(pkt) != 0) {
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO,
+                   SSL_R_RECORD_LENGTH_MISMATCH);
+            al = SSL_AD_DECODE_ERROR;
+            goto f_err;
+        }
+
+        /* Load the client random and compression list. */
+        challenge_len = challenge_len > SSL3_RANDOM_SIZE ? SSL3_RANDOM_SIZE :
+            challenge_len;
+        memset(s->s3->client_random, 0, SSL3_RANDOM_SIZE);
+        if (!PACKET_copy_bytes(&challenge,
+                               s->s3->client_random + SSL3_RANDOM_SIZE -
+                               challenge_len, challenge_len)
+            /* Advertise only null compression. */
+            || !PACKET_buf_init(&compression, &null_compression, 1)) {
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
+            al = SSL_AD_INTERNAL_ERROR;
+            goto f_err;
+        }
+
+        PACKET_null_init(&extensions);
+    } else {
+        /* Regular ClientHello. */
+        if (!PACKET_copy_bytes(pkt, s->s3->client_random, SSL3_RANDOM_SIZE)
+            || !PACKET_get_length_prefixed_1(pkt, &session_id)) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
+            goto f_err;
+        }
+
+        if (PACKET_remaining(&session_id) > SSL_MAX_SSL_SESSION_ID_LENGTH) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
+            goto f_err;
+        }
+
+        if (SSL_IS_DTLS(s)) {
+            if (!PACKET_get_length_prefixed_1(pkt, &cookie)) {
+                al = SSL_AD_DECODE_ERROR;
+                SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
+                goto f_err;
+            }
+            /*
+             * If we require cookies and this ClientHello doesn't contain one,
+             * just return since we do not want to allocate any memory yet.
+             * So check cookie length...
+             */
+            if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) {
+                if (PACKET_remaining(&cookie) == 0)
+                    return 1;
+            }
+        }
+
+        if (!PACKET_get_length_prefixed_2(pkt, &cipher_suites)
+            || !PACKET_get_length_prefixed_1(pkt, &compression)) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
+            goto f_err;
+        }
+        /* Could be empty. */
+        extensions = *pkt;
+    }
+
+    if (SSL_IS_DTLS(s)) {
+        /* Empty cookie was already handled above by returning early. */
+        if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) {
+            if (s->ctx->app_verify_cookie_cb != NULL) {
+                if (s->ctx->app_verify_cookie_cb(s, PACKET_data(&cookie),
+                                                 PACKET_remaining(&cookie)) ==
+                    0) {
+                    al = SSL_AD_HANDSHAKE_FAILURE;
+                    SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO,
+                           SSL_R_COOKIE_MISMATCH);
+                    goto f_err;
+                    /* else cookie verification succeeded */
+                }
+                /* default verification */
+            } else if (!PACKET_equal(&cookie, s->d1->cookie, s->d1->cookie_len)) {
+                al = SSL_AD_HANDSHAKE_FAILURE;
+                SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH);
+                goto f_err;
+            }
+            s->d1->cookie_verified = 1;
+        }
+        if (s->method->version == DTLS_ANY_VERSION) {
+            protverr = ssl_choose_server_version(s);
+            if (protverr != 0) {
+                SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, protverr);
+                s->version = s->client_version;
+                al = SSL_AD_PROTOCOL_VERSION;
+                goto f_err;
+            }
+        }
+    }
+
+    s->hit = 0;
+
+    /*
+     * We don't allow resumption in a backwards compatible ClientHello.
+     * TODO(openssl-team): in TLS1.1+, session_id MUST be empty.
+     *
+     * Versions before 0.9.7 always allow clients to resume sessions in
+     * renegotiation. 0.9.7 and later allow this by default, but optionally
+     * ignore resumption requests with flag
+     * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION (it's a new flag rather
+     * than a change to default behavior so that applications relying on
+     * this for security won't even compile against older library versions).
+     * 1.0.1 and later also have a function SSL_renegotiate_abbreviated() to
+     * request renegotiation but not a new session (s->new_session remains
+     * unset): for servers, this essentially just means that the
+     * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION setting will be
+     * ignored.
+     */
+    if (is_v2_record ||
+        (s->new_session &&
+         (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION))) {
+        if (!ssl_get_new_session(s, 1))
+            goto err;
+    } else {
+        i = ssl_get_prev_session(s, &extensions, &session_id);
+        /*
+         * Only resume if the session's version matches the negotiated
+         * version.
+         * RFC 5246 does not provide much useful advice on resumption
+         * with a different protocol version. It doesn't forbid it but
+         * the sanity of such behaviour would be questionable.
+         * In practice, clients do not accept a version mismatch and
+         * will abort the handshake with an error.
+         */
+        if (i == 1 && s->version == s->session->ssl_version) {
+            /* previous session */
+            s->hit = 1;
+        } else if (i == -1) {
+            goto err;
+        } else {
+            /* i == 0 */
+            if (!ssl_get_new_session(s, 1))
+                goto err;
+        }
+    }
+
+    if (ssl_bytes_to_cipher_list(s, &cipher_suites, &(ciphers),
+                                 is_v2_record, &al) == NULL) {
+        goto f_err;
+    }
+
+    /* If it is a hit, check that the cipher is in the list */
+    if (s->hit) {
+        j = 0;
+        id = s->session->cipher->id;
+
+#ifdef CIPHER_DEBUG
+        fprintf(stderr, "client sent %d ciphers\n", sk_SSL_CIPHER_num(ciphers));
+#endif
+        for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
+            c = sk_SSL_CIPHER_value(ciphers, i);
+#ifdef CIPHER_DEBUG
+            fprintf(stderr, "client [%2d of %2d]:%s\n",
+                    i, sk_SSL_CIPHER_num(ciphers), SSL_CIPHER_get_name(c));
+#endif
+            if (c->id == id) {
+                j = 1;
+                break;
+            }
+        }
+        if (j == 0) {
+            /*
+             * we need to have the cipher in the cipher list if we are asked
+             * to reuse it
+             */
+            al = SSL_AD_ILLEGAL_PARAMETER;
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO,
+                   SSL_R_REQUIRED_CIPHER_MISSING);
+            goto f_err;
+        }
+    }
+
+    complen = PACKET_remaining(&compression);
+    for (j = 0; j < complen; j++) {
+        if (PACKET_data(&compression)[j] == 0)
+            break;
+    }
+
+    if (j >= complen) {
+        /* no compress */
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_NO_COMPRESSION_SPECIFIED);
+        goto f_err;
+    }
+
+    /* TLS extensions */
+    if (s->version >= SSL3_VERSION) {
+        if (!ssl_parse_clienthello_tlsext(s, &extensions)) {
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_PARSE_TLSEXT);
+            goto err;
+        }
+    }
+
+    /*
+     * Check if we want to use external pre-shared secret for this handshake
+     * for not reused session only. We need to generate server_random before
+     * calling tls_session_secret_cb in order to allow SessionTicket
+     * processing to use it in key derivation.
+     */
+    {
+        unsigned char *pos;
+        pos = s->s3->server_random;
+        if (ssl_fill_hello_random(s, 1, pos, SSL3_RANDOM_SIZE) <= 0) {
+            goto f_err;
+        }
+    }
+
+    if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb) {
+        const SSL_CIPHER *pref_cipher = NULL;
+
+        s->session->master_key_length = sizeof(s->session->master_key);
+        if (s->tls_session_secret_cb(s, s->session->master_key,
+                                     &s->session->master_key_length, ciphers,
+                                     &pref_cipher,
+                                     s->tls_session_secret_cb_arg)) {
+            s->hit = 1;
+            s->session->ciphers = ciphers;
+            s->session->verify_result = X509_V_OK;
+
+            ciphers = NULL;
+
+            /* check if some cipher was preferred by call back */
+            pref_cipher =
+                pref_cipher ? pref_cipher : ssl3_choose_cipher(s,
+                                                               s->
+                                                               session->ciphers,
+                                                               SSL_get_ciphers
+                                                               (s));
+            if (pref_cipher == NULL) {
+                al = SSL_AD_HANDSHAKE_FAILURE;
+                SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_NO_SHARED_CIPHER);
+                goto f_err;
+            }
+
+            s->session->cipher = pref_cipher;
+            sk_SSL_CIPHER_free(s->cipher_list);
+            s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers);
+            sk_SSL_CIPHER_free(s->cipher_list_by_id);
+            s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
+        }
+    }
+
+    /*
+     * Worst case, we will use the NULL compression, but if we have other
+     * options, we will now look for them.  We have complen-1 compression
+     * algorithms from the client, starting at q.
+     */
+    s->s3->tmp.new_compression = NULL;
+#ifndef OPENSSL_NO_COMP
+    /* This only happens if we have a cache hit */
+    if (s->session->compress_meth != 0) {
+        int m, comp_id = s->session->compress_meth;
+        unsigned int k;
+        /* Perform sanity checks on resumed compression algorithm */
+        /* Can't disable compression */
+        if (!ssl_allow_compression(s)) {
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO,
+                   SSL_R_INCONSISTENT_COMPRESSION);
+            goto f_err;
+        }
+        /* Look for resumed compression method */
+        for (m = 0; m < sk_SSL_COMP_num(s->ctx->comp_methods); m++) {
+            comp = sk_SSL_COMP_value(s->ctx->comp_methods, m);
+            if (comp_id == comp->id) {
+                s->s3->tmp.new_compression = comp;
+                break;
+            }
+        }
+        if (s->s3->tmp.new_compression == NULL) {
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO,
+                   SSL_R_INVALID_COMPRESSION_ALGORITHM);
+            goto f_err;
+        }
+        /* Look for resumed method in compression list */
+        for (k = 0; k < complen; k++) {
+            if (PACKET_data(&compression)[k] == comp_id)
+                break;
+        }
+        if (k >= complen) {
+            al = SSL_AD_ILLEGAL_PARAMETER;
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO,
+                   SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING);
+            goto f_err;
+        }
+    } else if (s->hit)
+        comp = NULL;
+    else if (ssl_allow_compression(s) && s->ctx->comp_methods) {
+        /* See if we have a match */
+        int m, nn, v, done = 0;
+        unsigned int o;
+
+        nn = sk_SSL_COMP_num(s->ctx->comp_methods);
+        for (m = 0; m < nn; m++) {
+            comp = sk_SSL_COMP_value(s->ctx->comp_methods, m);
+            v = comp->id;
+            for (o = 0; o < complen; o++) {
+                if (v == PACKET_data(&compression)[o]) {
+                    done = 1;
+                    break;
+                }
+            }
+            if (done)
+                break;
+        }
+        if (done)
+            s->s3->tmp.new_compression = comp;
+        else
+            comp = NULL;
+    }
+#else
+    /*
+     * If compression is disabled we'd better not try to resume a session
+     * using compression.
+     */
+    if (s->session->compress_meth != 0) {
+        SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_INCONSISTENT_COMPRESSION);
+        goto f_err;
+    }
+#endif
+
+    /*
+     * Given s->session->ciphers and SSL_get_ciphers, we must pick a cipher
+     */
+
+    if (!s->hit) {
+#ifdef OPENSSL_NO_COMP
+        s->session->compress_meth = 0;
+#else
+        s->session->compress_meth = (comp == NULL) ? 0 : comp->id;
+#endif
+        sk_SSL_CIPHER_free(s->session->ciphers);
+        s->session->ciphers = ciphers;
+        if (ciphers == NULL) {
+            al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
+            goto f_err;
+        }
+        ciphers = NULL;
+        if (!tls1_set_server_sigalgs(s)) {
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
+            goto err;
+        }
+    }
+
+    sk_SSL_CIPHER_free(ciphers);
+    return MSG_PROCESS_CONTINUE_PROCESSING;
+ f_err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ err:
+    ossl_statem_set_error(s);
+
+    sk_SSL_CIPHER_free(ciphers);
+    return MSG_PROCESS_ERROR;
+
+}
+
+WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst)
+{
+    int al = SSL_AD_HANDSHAKE_FAILURE;
+    const SSL_CIPHER *cipher;
+
+    if (wst == WORK_MORE_A) {
+        if (!s->hit) {
+            /* Let cert callback update server certificates if required */
+            if (s->cert->cert_cb) {
+                int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg);
+                if (rv == 0) {
+                    al = SSL_AD_INTERNAL_ERROR;
+                    SSLerr(SSL_F_TLS_POST_PROCESS_CLIENT_HELLO,
+                           SSL_R_CERT_CB_ERROR);
+                    goto f_err;
+                }
+                if (rv < 0) {
+                    s->rwstate = SSL_X509_LOOKUP;
+                    return WORK_MORE_A;
+                }
+                s->rwstate = SSL_NOTHING;
+            }
+            cipher =
+                ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s));
+
+            if (cipher == NULL) {
+                SSLerr(SSL_F_TLS_POST_PROCESS_CLIENT_HELLO,
+                       SSL_R_NO_SHARED_CIPHER);
+                goto f_err;
+            }
+            s->s3->tmp.new_cipher = cipher;
+            /* check whether we should disable session resumption */
+            if (s->not_resumable_session_cb != NULL)
+                s->session->not_resumable = s->not_resumable_session_cb(s,
+                                                                        ((cipher->algorithm_mkey & (SSL_kDHE | SSL_kECDHE)) != 0));
+            if (s->session->not_resumable)
+                /* do not send a session ticket */
+                s->tlsext_ticket_expected = 0;
+        } else {
+            /* Session-id reuse */
+            s->s3->tmp.new_cipher = s->session->cipher;
+        }
+
+        if (!(s->verify_mode & SSL_VERIFY_PEER)) {
+            if (!ssl3_digest_cached_records(s, 0)) {
+                al = SSL_AD_INTERNAL_ERROR;
+                goto f_err;
+            }
+        }
+
+        /*-
+         * we now have the following setup.
+         * client_random
+         * cipher_list          - our preferred list of ciphers
+         * ciphers              - the clients preferred list of ciphers
+         * compression          - basically ignored right now
+         * ssl version is set   - sslv3
+         * s->session           - The ssl session has been setup.
+         * s->hit               - session reuse flag
+         * s->s3->tmp.new_cipher- the new cipher to use.
+         */
+
+        /* Handles TLS extensions that we couldn't check earlier */
+        if (s->version >= SSL3_VERSION) {
+            if (!ssl_check_clienthello_tlsext_late(s, &al)) {
+                SSLerr(SSL_F_TLS_POST_PROCESS_CLIENT_HELLO,
+                       SSL_R_CLIENTHELLO_TLSEXT);
+                goto f_err;
+            }
+        }
+
+        wst = WORK_MORE_B;
+    }
+#ifndef OPENSSL_NO_SRP
+    if (wst == WORK_MORE_B) {
+        int ret;
+        if ((ret = ssl_check_srp_ext_ClientHello(s, &al)) < 0) {
+            /*
+             * callback indicates further work to be done
+             */
+            s->rwstate = SSL_X509_LOOKUP;
+            return WORK_MORE_B;
+        }
+        if (ret != SSL_ERROR_NONE) {
+            /*
+             * This is not really an error but the only means to for
+             * a client to detect whether srp is supported.
+             */
+            if (al != TLS1_AD_UNKNOWN_PSK_IDENTITY)
+                SSLerr(SSL_F_TLS_POST_PROCESS_CLIENT_HELLO,
+                       SSL_R_CLIENTHELLO_TLSEXT);
+            else
+                SSLerr(SSL_F_TLS_POST_PROCESS_CLIENT_HELLO,
+                       SSL_R_PSK_IDENTITY_NOT_FOUND);
+            goto f_err;
+        }
+    }
+#endif
+    s->renegotiate = 2;
+
+    return WORK_FINISHED_STOP;
+ f_err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    ossl_statem_set_error(s);
+    return WORK_ERROR;
+}
+
+int tls_construct_server_hello(SSL *s)
+{
+    unsigned char *buf;
+    unsigned char *p, *d;
+    int i, sl;
+    int al = 0;
+    unsigned long l;
+
+    buf = (unsigned char *)s->init_buf->data;
+
+    /* Do the message type and length last */
+    d = p = ssl_handshake_start(s);
+
+    *(p++) = s->version >> 8;
+    *(p++) = s->version & 0xff;
+
+    /*
+     * Random stuff. Filling of the server_random takes place in
+     * tls_process_client_hello()
+     */
+    memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE);
+    p += SSL3_RANDOM_SIZE;
+
+    /*-
+     * There are several cases for the session ID to send
+     * back in the server hello:
+     * - For session reuse from the session cache,
+     *   we send back the old session ID.
+     * - If stateless session reuse (using a session ticket)
+     *   is successful, we send back the client's "session ID"
+     *   (which doesn't actually identify the session).
+     * - If it is a new session, we send back the new
+     *   session ID.
+     * - However, if we want the new session to be single-use,
+     *   we send back a 0-length session ID.
+     * s->hit is non-zero in either case of session reuse,
+     * so the following won't overwrite an ID that we're supposed
+     * to send back.
+     */
+    if (s->session->not_resumable ||
+        (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)
+         && !s->hit))
+        s->session->session_id_length = 0;
+
+    sl = s->session->session_id_length;
+    if (sl > (int)sizeof(s->session->session_id)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
+        ossl_statem_set_error(s);
+        return 0;
+    }
+    *(p++) = sl;
+    memcpy(p, s->session->session_id, sl);
+    p += sl;
+
+    /* put the cipher */
+    i = ssl3_put_cipher_by_char(s->s3->tmp.new_cipher, p);
+    p += i;
+
+    /* put the compression method */
+#ifdef OPENSSL_NO_COMP
+    *(p++) = 0;
+#else
+    if (s->s3->tmp.new_compression == NULL)
+        *(p++) = 0;
+    else
+        *(p++) = s->s3->tmp.new_compression->id;
+#endif
+
+    if (ssl_prepare_serverhello_tlsext(s) <= 0) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_HELLO, SSL_R_SERVERHELLO_TLSEXT);
+        ossl_statem_set_error(s);
+        return 0;
+    }
+    if ((p =
+         ssl_add_serverhello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH,
+                                    &al)) == NULL) {
+        ssl3_send_alert(s, SSL3_AL_FATAL, al);
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
+        ossl_statem_set_error(s);
+        return 0;
+    }
+
+    /* do the header */
+    l = (p - d);
+    if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_HELLO, l)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
+        ossl_statem_set_error(s);
+        return 0;
+    }
+
+    return 1;
+}
+
+int tls_construct_server_done(SSL *s)
+{
+    if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_DONE, 0)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_DONE, ERR_R_INTERNAL_ERROR);
+        ossl_statem_set_error(s);
+        return 0;
+    }
+
+    if (!s->s3->tmp.cert_request) {
+        if (!ssl3_digest_cached_records(s, 0)) {
+            ossl_statem_set_error(s);
+        }
+    }
+
+    return 1;
+}
+
+int tls_construct_server_key_exchange(SSL *s)
+{
+#ifndef OPENSSL_NO_DH
+    EVP_PKEY *pkdh = NULL;
+    int j;
+#endif
+#ifndef OPENSSL_NO_EC
+    unsigned char *encodedPoint = NULL;
+    int encodedlen = 0;
+    int curve_id = 0;
+#endif
+    EVP_PKEY *pkey;
+    const EVP_MD *md = NULL;
+    unsigned char *p, *d;
+    int al, i;
+    unsigned long type;
+    int n;
+    const BIGNUM *r[4];
+    int nr[4], kn;
+    BUF_MEM *buf;
+    EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
+
+    if (md_ctx == NULL) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
+        al = SSL_AD_INTERNAL_ERROR;
+        goto f_err;
+    }
+
+    type = s->s3->tmp.new_cipher->algorithm_mkey;
+
+    buf = s->init_buf;
+
+    r[0] = r[1] = r[2] = r[3] = NULL;
+    n = 0;
+#ifndef OPENSSL_NO_PSK
+    if (type & SSL_PSK) {
+        /*
+         * reserve size for record length and PSK identity hint
+         */
+        n += 2;
+        if (s->cert->psk_identity_hint)
+            n += strlen(s->cert->psk_identity_hint);
+    }
+    /* Plain PSK or RSAPSK nothing to do */
+    if (type & (SSL_kPSK | SSL_kRSAPSK)) {
+    } else
+#endif                          /* !OPENSSL_NO_PSK */
+#ifndef OPENSSL_NO_DH
+    if (type & (SSL_kDHE | SSL_kDHEPSK)) {
+        CERT *cert = s->cert;
+
+        EVP_PKEY *pkdhp = NULL;
+        DH *dh;
+
+        if (s->cert->dh_tmp_auto) {
+            DH *dhp = ssl_get_auto_dh(s);
+            pkdh = EVP_PKEY_new();
+            if (pkdh == NULL || dhp == NULL) {
+                DH_free(dhp);
+                al = SSL_AD_INTERNAL_ERROR;
+                SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
+                       ERR_R_INTERNAL_ERROR);
+                goto f_err;
+            }
+            EVP_PKEY_assign_DH(pkdh, dhp);
+            pkdhp = pkdh;
+        } else {
+            pkdhp = cert->dh_tmp;
+        }
+        if ((pkdhp == NULL) && (s->cert->dh_tmp_cb != NULL)) {
+            DH *dhp = s->cert->dh_tmp_cb(s, 0, 1024);
+            pkdh = ssl_dh_to_pkey(dhp);
+            if (pkdh == NULL) {
+                al = SSL_AD_INTERNAL_ERROR;
+                SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
+                       ERR_R_INTERNAL_ERROR);
+                goto f_err;
+            }
+            pkdhp = pkdh;
+        }
+        if (pkdhp == NULL) {
+            al = SSL_AD_HANDSHAKE_FAILURE;
+            SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
+                   SSL_R_MISSING_TMP_DH_KEY);
+            goto f_err;
+        }
+        if (!ssl_security(s, SSL_SECOP_TMP_DH,
+                          EVP_PKEY_security_bits(pkdhp), 0, pkdhp)) {
+            al = SSL_AD_HANDSHAKE_FAILURE;
+            SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
+                   SSL_R_DH_KEY_TOO_SMALL);
+            goto f_err;
+        }
+        if (s->s3->tmp.pkey != NULL) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
+                   ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+
+        s->s3->tmp.pkey = ssl_generate_pkey(pkdhp);
+
+        if (s->s3->tmp.pkey == NULL) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_EVP_LIB);
+            goto err;
+        }
+
+        dh = EVP_PKEY_get0_DH(s->s3->tmp.pkey);
+
+        EVP_PKEY_free(pkdh);
+        pkdh = NULL;
+
+        DH_get0_pqg(dh, &r[0], NULL, &r[1]);
+        DH_get0_key(dh, &r[2], NULL);
+    } else
+#endif
+#ifndef OPENSSL_NO_EC
+    if (type & (SSL_kECDHE | SSL_kECDHEPSK)) {
+        int nid;
+
+        if (s->s3->tmp.pkey != NULL) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
+                   ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+
+        /* Get NID of appropriate shared curve */
+        nid = tls1_shared_curve(s, -2);
+        curve_id = tls1_ec_nid2curve_id(nid);
+        if (curve_id == 0) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
+                   SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
+            goto err;
+        }
+        s->s3->tmp.pkey = ssl_generate_pkey_curve(curve_id);
+        /* Generate a new key for this curve */
+        if (s->s3->tmp.pkey == NULL) {
+            al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_EVP_LIB);
+            goto f_err;
+        }
+
+        /* Encode the public key. */
+        encodedlen = EVP_PKEY_get1_tls_encodedpoint(s->s3->tmp.pkey,
+                                                    &encodedPoint);
+        if (encodedlen == 0) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_EC_LIB);
+            goto err;
+        }
+
+        /*
+         * We only support named (not generic) curves in ECDH ephemeral key
+         * exchanges. In this situation, we need four additional bytes to
+         * encode the entire ServerECDHParams structure.
+         */
+        n += 4 + encodedlen;
+
+        /*
+         * We'll generate the serverKeyExchange message explicitly so we
+         * can set these to NULLs
+         */
+        r[0] = NULL;
+        r[1] = NULL;
+        r[2] = NULL;
+        r[3] = NULL;
+    } else
+#endif                          /* !OPENSSL_NO_EC */
+#ifndef OPENSSL_NO_SRP
+    if (type & SSL_kSRP) {
+        if ((s->srp_ctx.N == NULL) ||
+            (s->srp_ctx.g == NULL) ||
+            (s->srp_ctx.s == NULL) || (s->srp_ctx.B == NULL)) {
+            SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
+                   SSL_R_MISSING_SRP_PARAM);
+            goto err;
+        }
+        r[0] = s->srp_ctx.N;
+        r[1] = s->srp_ctx.g;
+        r[2] = s->srp_ctx.s;
+        r[3] = s->srp_ctx.B;
+    } else
+#endif
+    {
+        al = SSL_AD_HANDSHAKE_FAILURE;
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
+               SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
+        goto f_err;
+    }
+    for (i = 0; i < 4 && r[i] != NULL; i++) {
+        nr[i] = BN_num_bytes(r[i]);
+#ifndef OPENSSL_NO_SRP
+        if ((i == 2) && (type & SSL_kSRP))
+            n += 1 + nr[i];
+        else
+#endif
+#ifndef OPENSSL_NO_DH
+        /*-
+         * for interoperability with some versions of the Microsoft TLS
+         * stack, we need to zero pad the DHE pub key to the same length
+         * as the prime, so use the length of the prime here
+         */
+        if ((i == 2) && (type & (SSL_kDHE | SSL_kDHEPSK)))
+            n += 2 + nr[0];
+        else
+#endif
+            n += 2 + nr[i];
+    }
+
+    if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP))
+        && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK)) {
+        if ((pkey = ssl_get_sign_pkey(s, s->s3->tmp.new_cipher, &md))
+            == NULL) {
+            al = SSL_AD_DECODE_ERROR;
+            goto f_err;
+        }
+        kn = EVP_PKEY_size(pkey);
+        /* Allow space for signature algorithm */
+        if (SSL_USE_SIGALGS(s))
+            kn += 2;
+        /* Allow space for signature length */
+        kn += 2;
+    } else {
+        pkey = NULL;
+        kn = 0;
+    }
+
+    if (!BUF_MEM_grow_clean(buf, n + SSL_HM_HEADER_LENGTH(s) + kn)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_LIB_BUF);
+        goto err;
+    }
+    d = p = ssl_handshake_start(s);
+
+#ifndef OPENSSL_NO_PSK
+    if (type & SSL_PSK) {
+        /* copy PSK identity hint */
+        if (s->cert->psk_identity_hint) {
+            size_t len = strlen(s->cert->psk_identity_hint);
+            if (len > PSK_MAX_IDENTITY_LEN) {
+                /*
+                 * Should not happen - we already checked this when we set
+                 * the identity hint
+                 */
+                SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
+                       ERR_R_INTERNAL_ERROR);
+                goto err;
+            }
+            s2n(len, p);
+            memcpy(p, s->cert->psk_identity_hint, len);
+            p += len;
+        } else {
+            s2n(0, p);
+        }
+    }
+#endif
+
+    for (i = 0; i < 4 && r[i] != NULL; i++) {
+#ifndef OPENSSL_NO_SRP
+        if ((i == 2) && (type & SSL_kSRP)) {
+            *p = nr[i];
+            p++;
+        } else
+#endif
+#ifndef OPENSSL_NO_DH
+        /*-
+         * for interoperability with some versions of the Microsoft TLS
+         * stack, we need to zero pad the DHE pub key to the same length
+         * as the prime
+         */
+        if ((i == 2) && (type & (SSL_kDHE | SSL_kDHEPSK))) {
+            s2n(nr[0], p);
+            for (j = 0; j < (nr[0] - nr[2]); ++j) {
+                *p = 0;
+                ++p;
+            }
+        } else
+#endif
+            s2n(nr[i], p);
+        BN_bn2bin(r[i], p);
+        p += nr[i];
+    }
+
+#ifndef OPENSSL_NO_EC
+    if (type & (SSL_kECDHE | SSL_kECDHEPSK)) {
+        /*
+         * XXX: For now, we only support named (not generic) curves. In
+         * this situation, the serverKeyExchange message has: [1 byte
+         * CurveType], [2 byte CurveName] [1 byte length of encoded
+         * point], followed by the actual encoded point itself
+         */
+        *p = NAMED_CURVE_TYPE;
+        p += 1;
+        *p = 0;
+        p += 1;
+        *p = curve_id;
+        p += 1;
+        *p = encodedlen;
+        p += 1;
+        memcpy(p, encodedPoint, encodedlen);
+        OPENSSL_free(encodedPoint);
+        encodedPoint = NULL;
+        p += encodedlen;
+    }
+#endif
+
+    /* not anonymous */
+    if (pkey != NULL) {
+        /*
+         * n is the length of the params, they start at &(d[4]) and p
+         * points to the space at the end.
+         */
+        if (md) {
+            /* send signature algorithm */
+            if (SSL_USE_SIGALGS(s)) {
+                if (!tls12_get_sigandhash(p, pkey, md)) {
+                    /* Should never happen */
+                    al = SSL_AD_INTERNAL_ERROR;
+                    SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
+                           ERR_R_INTERNAL_ERROR);
+                    goto f_err;
+                }
+                p += 2;
+            }
+#ifdef SSL_DEBUG
+            fprintf(stderr, "Using hash %s\n", EVP_MD_name(md));
+#endif
+            if (EVP_SignInit_ex(md_ctx, md, NULL) <= 0
+                || EVP_SignUpdate(md_ctx, &(s->s3->client_random[0]),
+                                  SSL3_RANDOM_SIZE) <= 0
+                || EVP_SignUpdate(md_ctx, &(s->s3->server_random[0]),
+                                  SSL3_RANDOM_SIZE) <= 0
+                || EVP_SignUpdate(md_ctx, d, n) <= 0
+                || EVP_SignFinal(md_ctx, &(p[2]),
+                                 (unsigned int *)&i, pkey) <= 0) {
+                SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_LIB_EVP);
+                al = SSL_AD_INTERNAL_ERROR;
+                goto f_err;
+            }
+            s2n(i, p);
+            n += i + 2;
+            if (SSL_USE_SIGALGS(s))
+                n += 2;
+        } else {
+            /* Is this error check actually needed? */
+            al = SSL_AD_HANDSHAKE_FAILURE;
+            SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
+                   SSL_R_UNKNOWN_PKEY_TYPE);
+            goto f_err;
+        }
+    }
+
+    if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_KEY_EXCHANGE, n)) {
+        al = SSL_AD_HANDSHAKE_FAILURE;
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+        goto f_err;
+    }
+
+    EVP_MD_CTX_free(md_ctx);
+    return 1;
+ f_err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ err:
+#ifndef OPENSSL_NO_DH
+    EVP_PKEY_free(pkdh);
+#endif
+#ifndef OPENSSL_NO_EC
+    OPENSSL_free(encodedPoint);
+#endif
+    EVP_MD_CTX_free(md_ctx);
+    ossl_statem_set_error(s);
+    return 0;
+}
+
+int tls_construct_certificate_request(SSL *s)
+{
+    unsigned char *p, *d;
+    int i, j, nl, off, n;
+    STACK_OF(X509_NAME) *sk = NULL;
+    X509_NAME *name;
+    BUF_MEM *buf;
+
+    buf = s->init_buf;
+
+    d = p = ssl_handshake_start(s);
+
+    /* get the list of acceptable cert types */
+    p++;
+    n = ssl3_get_req_cert_type(s, p);
+    d[0] = n;
+    p += n;
+    n++;
+
+    if (SSL_USE_SIGALGS(s)) {
+        const unsigned char *psigs;
+        unsigned char *etmp = p;
+        nl = tls12_get_psigalgs(s, 1, &psigs);
+        /* Skip over length for now */
+        p += 2;
+        nl = tls12_copy_sigalgs(s, p, psigs, nl);
+        /* Now fill in length */
+        s2n(nl, etmp);
+        p += nl;
+        n += nl + 2;
+    }
+
+    off = n;
+    p += 2;
+    n += 2;
+
+    sk = SSL_get_client_CA_list(s);
+    nl = 0;
+    if (sk != NULL) {
+        for (i = 0; i < sk_X509_NAME_num(sk); i++) {
+            name = sk_X509_NAME_value(sk, i);
+            j = i2d_X509_NAME(name, NULL);
+            if (!BUF_MEM_grow_clean(buf, SSL_HM_HEADER_LENGTH(s) + n + j + 2)) {
+                SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_BUF_LIB);
+                goto err;
+            }
+            p = ssl_handshake_start(s) + n;
+            s2n(j, p);
+            i2d_X509_NAME(name, &p);
+            n += 2 + j;
+            nl += 2 + j;
+        }
+    }
+    /* else no CA names */
+    p = ssl_handshake_start(s) + off;
+    s2n(nl, p);
+
+    if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_REQUEST, n)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
+    s->s3->tmp.cert_request = 1;
+
+    return 1;
+ err:
+    ossl_statem_set_error(s);
+    return 0;
+}
+
+static int tls_process_cke_psk_preamble(SSL *s, PACKET *pkt, int *al)
+{
+#ifndef OPENSSL_NO_PSK
+    unsigned char psk[PSK_MAX_PSK_LEN];
+    size_t psklen;
+    PACKET psk_identity;
+
+    if (!PACKET_get_length_prefixed_2(pkt, &psk_identity)) {
+        *al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE, SSL_R_LENGTH_MISMATCH);
+        return 0;
+    }
+    if (PACKET_remaining(&psk_identity) > PSK_MAX_IDENTITY_LEN) {
+        *al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE, SSL_R_DATA_LENGTH_TOO_LONG);
+        return 0;
+    }
+    if (s->psk_server_callback == NULL) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE, SSL_R_PSK_NO_SERVER_CB);
+        return 0;
+    }
+
+    if (!PACKET_strndup(&psk_identity, &s->session->psk_identity)) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    psklen = s->psk_server_callback(s, s->session->psk_identity,
+                                    psk, sizeof(psk));
+
+    if (psklen > PSK_MAX_PSK_LEN) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE, ERR_R_INTERNAL_ERROR);
+        return 0;
+    } else if (psklen == 0) {
+        /*
+         * PSK related to the given identity not found
+         */
+        *al = SSL_AD_UNKNOWN_PSK_IDENTITY;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE,
+               SSL_R_PSK_IDENTITY_NOT_FOUND);
+        return 0;
+    }
+
+    OPENSSL_free(s->s3->tmp.psk);
+    s->s3->tmp.psk = OPENSSL_memdup(psk, psklen);
+    OPENSSL_cleanse(psk, psklen);
+
+    if (s->s3->tmp.psk == NULL) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    s->s3->tmp.psklen = psklen;
+
+    return 1;
+#else
+    /* Should never happen */
+    *al = SSL_AD_INTERNAL_ERROR;
+    SSLerr(SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE, ERR_R_INTERNAL_ERROR);
+    return 0;
+#endif
+}
+
+static int tls_process_cke_rsa(SSL *s, PACKET *pkt, int *al)
+{
+#ifndef OPENSSL_NO_RSA
+    unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH];
+    int decrypt_len;
+    unsigned char decrypt_good, version_good;
+    size_t j, padding_len;
+    PACKET enc_premaster;
+    RSA *rsa = NULL;
+    unsigned char *rsa_decrypt = NULL;
+    int ret = 0;
+
+    rsa = EVP_PKEY_get0_RSA(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey);
+    if (rsa == NULL) {
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_RSA, SSL_R_MISSING_RSA_CERTIFICATE);
+        return 0;
+    }
+
+    /* SSLv3 and pre-standard DTLS omit the length bytes. */
+    if (s->version == SSL3_VERSION || s->version == DTLS1_BAD_VER) {
+        enc_premaster = *pkt;
+    } else {
+        if (!PACKET_get_length_prefixed_2(pkt, &enc_premaster)
+            || PACKET_remaining(pkt) != 0) {
+            *al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_CKE_RSA, SSL_R_LENGTH_MISMATCH);
+            return 0;
+        }
+    }
+
+    /*
+     * We want to be sure that the plaintext buffer size makes it safe to
+     * iterate over the entire size of a premaster secret
+     * (SSL_MAX_MASTER_KEY_LENGTH). Reject overly short RSA keys because
+     * their ciphertext cannot accommodate a premaster secret anyway.
+     */
+    if (RSA_size(rsa) < SSL_MAX_MASTER_KEY_LENGTH) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_RSA, RSA_R_KEY_SIZE_TOO_SMALL);
+        return 0;
+    }
+
+    rsa_decrypt = OPENSSL_malloc(RSA_size(rsa));
+    if (rsa_decrypt == NULL) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_RSA, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    /*
+     * We must not leak whether a decryption failure occurs because of
+     * Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246,
+     * section 7.4.7.1). The code follows that advice of the TLS RFC and
+     * generates a random premaster secret for the case that the decrypt
+     * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1
+     */
+
+    if (RAND_bytes(rand_premaster_secret, sizeof(rand_premaster_secret)) <= 0)
+        goto err;
+
+    /*
+     * Decrypt with no padding. PKCS#1 padding will be removed as part of
+     * the timing-sensitive code below.
+     */
+    decrypt_len = RSA_private_decrypt(PACKET_remaining(&enc_premaster),
+                                      PACKET_data(&enc_premaster),
+                                      rsa_decrypt, rsa, RSA_NO_PADDING);
+    if (decrypt_len < 0)
+        goto err;
+
+    /* Check the padding. See RFC 3447, section 7.2.2. */
+
+    /*
+     * The smallest padded premaster is 11 bytes of overhead. Small keys
+     * are publicly invalid, so this may return immediately. This ensures
+     * PS is at least 8 bytes.
+     */
+    if (decrypt_len < 11 + SSL_MAX_MASTER_KEY_LENGTH) {
+        *al = SSL_AD_DECRYPT_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_RSA, SSL_R_DECRYPTION_FAILED);
+        goto err;
+    }
+
+    padding_len = decrypt_len - SSL_MAX_MASTER_KEY_LENGTH;
+    decrypt_good = constant_time_eq_int_8(rsa_decrypt[0], 0) &
+        constant_time_eq_int_8(rsa_decrypt[1], 2);
+    for (j = 2; j < padding_len - 1; j++) {
+        decrypt_good &= ~constant_time_is_zero_8(rsa_decrypt[j]);
+    }
+    decrypt_good &= constant_time_is_zero_8(rsa_decrypt[padding_len - 1]);
+
+    /*
+     * If the version in the decrypted pre-master secret is correct then
+     * version_good will be 0xff, otherwise it'll be zero. The
+     * Klima-Pokorny-Rosa extension of Bleichenbacher's attack
+     * (http://eprint.iacr.org/2003/052/) exploits the version number
+     * check as a "bad version oracle". Thus version checks are done in
+     * constant time and are treated like any other decryption error.
+     */
+    version_good =
+        constant_time_eq_8(rsa_decrypt[padding_len],
+                           (unsigned)(s->client_version >> 8));
+    version_good &=
+        constant_time_eq_8(rsa_decrypt[padding_len + 1],
+                           (unsigned)(s->client_version & 0xff));
+
+    /*
+     * The premaster secret must contain the same version number as the
+     * ClientHello to detect version rollback attacks (strangely, the
+     * protocol does not offer such protection for DH ciphersuites).
+     * However, buggy clients exist that send the negotiated protocol
+     * version instead if the server does not support the requested
+     * protocol version. If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such
+     * clients.
+     */
+    if (s->options & SSL_OP_TLS_ROLLBACK_BUG) {
+        unsigned char workaround_good;
+        workaround_good = constant_time_eq_8(rsa_decrypt[padding_len],
+                                             (unsigned)(s->version >> 8));
+        workaround_good &=
+            constant_time_eq_8(rsa_decrypt[padding_len + 1],
+                               (unsigned)(s->version & 0xff));
+        version_good |= workaround_good;
+    }
+
+    /*
+     * Both decryption and version must be good for decrypt_good to
+     * remain non-zero (0xff).
+     */
+    decrypt_good &= version_good;
+
+    /*
+     * Now copy rand_premaster_secret over from p using
+     * decrypt_good_mask. If decryption failed, then p does not
+     * contain valid plaintext, however, a check above guarantees
+     * it is still sufficiently large to read from.
+     */
+    for (j = 0; j < sizeof(rand_premaster_secret); j++) {
+        rsa_decrypt[padding_len + j] =
+            constant_time_select_8(decrypt_good,
+                                   rsa_decrypt[padding_len + j],
+                                   rand_premaster_secret[j]);
+    }
+
+    if (!ssl_generate_master_secret(s, rsa_decrypt + padding_len,
+                                    sizeof(rand_premaster_secret), 0)) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_RSA, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
+    ret = 1;
+ err:
+    OPENSSL_free(rsa_decrypt);
+    return ret;
+#else
+    /* Should never happen */
+    *al = SSL_AD_INTERNAL_ERROR;
+    SSLerr(SSL_F_TLS_PROCESS_CKE_RSA, ERR_R_INTERNAL_ERROR);
+    return 0;
+#endif
+}
+
+static int tls_process_cke_dhe(SSL *s, PACKET *pkt, int *al)
+{
+#ifndef OPENSSL_NO_DH
+    EVP_PKEY *skey = NULL;
+    DH *cdh;
+    unsigned int i;
+    BIGNUM *pub_key;
+    const unsigned char *data;
+    EVP_PKEY *ckey = NULL;
+    int ret = 0;
+
+    if (!PACKET_get_net_2(pkt, &i) || PACKET_remaining(pkt) != i) {
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_DHE,
+               SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
+        goto err;
+    }
+    skey = s->s3->tmp.pkey;
+    if (skey == NULL) {
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_DHE, SSL_R_MISSING_TMP_DH_KEY);
+        goto err;
+    }
+
+    if (PACKET_remaining(pkt) == 0L) {
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_DHE, SSL_R_MISSING_TMP_DH_KEY);
+        goto err;
+    }
+    if (!PACKET_get_bytes(pkt, &data, i)) {
+        /* We already checked we have enough data */
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_DHE, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+    ckey = EVP_PKEY_new();
+    if (ckey == NULL || EVP_PKEY_copy_parameters(ckey, skey) == 0) {
+        SSLerr(SSL_F_TLS_PROCESS_CKE_DHE, SSL_R_BN_LIB);
+        goto err;
+    }
+    cdh = EVP_PKEY_get0_DH(ckey);
+    pub_key = BN_bin2bn(data, i, NULL);
+
+    if (pub_key == NULL || !DH_set0_key(cdh, pub_key, NULL)) {
+        SSLerr(SSL_F_TLS_PROCESS_CKE_DHE, ERR_R_INTERNAL_ERROR);
+        if (pub_key != NULL)
+            BN_free(pub_key);
+        goto err;
+    }
+
+    if (ssl_derive(s, skey, ckey) == 0) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_DHE, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
+    ret = 1;
+    EVP_PKEY_free(s->s3->tmp.pkey);
+    s->s3->tmp.pkey = NULL;
+ err:
+    EVP_PKEY_free(ckey);
+    return ret;
+#else
+    /* Should never happen */
+    *al = SSL_AD_INTERNAL_ERROR;
+    SSLerr(SSL_F_TLS_PROCESS_CKE_DHE, ERR_R_INTERNAL_ERROR);
+    return 0;
+#endif
+}
+
+static int tls_process_cke_ecdhe(SSL *s, PACKET *pkt, int *al)
+{
+#ifndef OPENSSL_NO_EC
+    EVP_PKEY *skey = s->s3->tmp.pkey;
+    EVP_PKEY *ckey = NULL;
+    int ret = 0;
+
+    if (PACKET_remaining(pkt) == 0L) {
+        /* We don't support ECDH client auth */
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_ECDHE, SSL_R_MISSING_TMP_ECDH_KEY);
+        goto err;
+    } else {
+        unsigned int i;
+        const unsigned char *data;
+
+        /*
+         * Get client's public key from encoded point in the
+         * ClientKeyExchange message.
+         */
+
+        /* Get encoded point length */
+        if (!PACKET_get_1(pkt, &i) || !PACKET_get_bytes(pkt, &data, i)
+            || PACKET_remaining(pkt) != 0) {
+            *al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_CKE_ECDHE, SSL_R_LENGTH_MISMATCH);
+            goto err;
+        }
+        ckey = EVP_PKEY_new();
+        if (ckey == NULL || EVP_PKEY_copy_parameters(ckey, skey) <= 0) {
+            SSLerr(SSL_F_TLS_PROCESS_CKE_ECDHE, ERR_R_EVP_LIB);
+            goto err;
+        }
+        if (EVP_PKEY_set1_tls_encodedpoint(ckey, data, i) == 0) {
+            *al = SSL_AD_HANDSHAKE_FAILURE;
+            SSLerr(SSL_F_TLS_PROCESS_CKE_ECDHE, ERR_R_EC_LIB);
+            goto err;
+        }
+    }
+
+    if (ssl_derive(s, skey, ckey) == 0) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_ECDHE, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
+    ret = 1;
+    EVP_PKEY_free(s->s3->tmp.pkey);
+    s->s3->tmp.pkey = NULL;
+ err:
+    EVP_PKEY_free(ckey);
+
+    return ret;
+#else
+    /* Should never happen */
+    *al = SSL_AD_INTERNAL_ERROR;
+    SSLerr(SSL_F_TLS_PROCESS_CKE_ECDHE, ERR_R_INTERNAL_ERROR);
+    return 0;
+#endif
+}
+
+static int tls_process_cke_srp(SSL *s, PACKET *pkt, int *al)
+{
+#ifndef OPENSSL_NO_SRP
+    unsigned int i;
+    const unsigned char *data;
+
+    if (!PACKET_get_net_2(pkt, &i)
+        || !PACKET_get_bytes(pkt, &data, i)) {
+        *al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_SRP, SSL_R_BAD_SRP_A_LENGTH);
+        return 0;
+    }
+    if ((s->srp_ctx.A = BN_bin2bn(data, i, NULL)) == NULL) {
+        SSLerr(SSL_F_TLS_PROCESS_CKE_SRP, ERR_R_BN_LIB);
+        return 0;
+    }
+    if (BN_ucmp(s->srp_ctx.A, s->srp_ctx.N) >= 0 || BN_is_zero(s->srp_ctx.A)) {
+        *al = SSL_AD_ILLEGAL_PARAMETER;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_SRP, SSL_R_BAD_SRP_PARAMETERS);
+        return 0;
+    }
+    OPENSSL_free(s->session->srp_username);
+    s->session->srp_username = OPENSSL_strdup(s->srp_ctx.login);
+    if (s->session->srp_username == NULL) {
+        SSLerr(SSL_F_TLS_PROCESS_CKE_SRP, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    if (!srp_generate_server_master_secret(s)) {
+        SSLerr(SSL_F_TLS_PROCESS_CKE_SRP, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+
+    return 1;
+#else
+    /* Should never happen */
+    *al = SSL_AD_INTERNAL_ERROR;
+    SSLerr(SSL_F_TLS_PROCESS_CKE_SRP, ERR_R_INTERNAL_ERROR);
+    return 0;
+#endif
+}
+
+static int tls_process_cke_gost(SSL *s, PACKET *pkt, int *al)
+{
+#ifndef OPENSSL_NO_GOST
+    EVP_PKEY_CTX *pkey_ctx;
+    EVP_PKEY *client_pub_pkey = NULL, *pk = NULL;
+    unsigned char premaster_secret[32];
+    const unsigned char *start;
+    size_t outlen = 32, inlen;
+    unsigned long alg_a;
+    int Ttag, Tclass;
+    long Tlen;
+    long sess_key_len;
+    const unsigned char *data;
+    int ret = 0;
+
+    /* Get our certificate private key */
+    alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+    if (alg_a & SSL_aGOST12) {
+        /*
+         * New GOST ciphersuites have SSL_aGOST01 bit too
+         */
+        pk = s->cert->pkeys[SSL_PKEY_GOST12_512].privatekey;
+        if (pk == NULL) {
+            pk = s->cert->pkeys[SSL_PKEY_GOST12_256].privatekey;
+        }
+        if (pk == NULL) {
+            pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey;
+        }
+    } else if (alg_a & SSL_aGOST01) {
+        pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey;
+    }
+
+    pkey_ctx = EVP_PKEY_CTX_new(pk, NULL);
+    if (pkey_ctx == NULL) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_GOST, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_GOST, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+    /*
+     * If client certificate is present and is of the same type, maybe
+     * use it for key exchange.  Don't mind errors from
+     * EVP_PKEY_derive_set_peer, because it is completely valid to use a
+     * client certificate for authorization only.
+     */
+    client_pub_pkey = X509_get0_pubkey(s->session->peer);
+    if (client_pub_pkey) {
+        if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0)
+            ERR_clear_error();
+    }
+    /* Decrypt session key */
+    sess_key_len = PACKET_remaining(pkt);
+    if (!PACKET_get_bytes(pkt, &data, sess_key_len)) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_GOST, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+    if (ASN1_get_object((const unsigned char **)&data, &Tlen, &Ttag,
+                        &Tclass, sess_key_len) != V_ASN1_CONSTRUCTED
+        || Ttag != V_ASN1_SEQUENCE || Tclass != V_ASN1_UNIVERSAL) {
+        *al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_GOST, SSL_R_DECRYPTION_FAILED);
+        goto err;
+    }
+    start = data;
+    inlen = Tlen;
+    if (EVP_PKEY_decrypt
+        (pkey_ctx, premaster_secret, &outlen, start, inlen) <= 0) {
+        *al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_GOST, SSL_R_DECRYPTION_FAILED);
+        goto err;
+    }
+    /* Generate master secret */
+    if (!ssl_generate_master_secret(s, premaster_secret,
+                                    sizeof(premaster_secret), 0)) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CKE_GOST, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+    /* Check if pubkey from client certificate was used */
+    if (EVP_PKEY_CTX_ctrl
+        (pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0)
+        s->statem.no_cert_verify = 1;
+
+    ret = 1;
+ err:
+    EVP_PKEY_CTX_free(pkey_ctx);
+    return ret;
+#else
+    /* Should never happen */
+    *al = SSL_AD_INTERNAL_ERROR;
+    SSLerr(SSL_F_TLS_PROCESS_CKE_GOST, ERR_R_INTERNAL_ERROR);
+    return 0;
+#endif
+}
+
+MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
+{
+    int al = -1;
+    unsigned long alg_k;
+
+    alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+
+    /* For PSK parse and retrieve identity, obtain PSK key */
+    if ((alg_k & SSL_PSK) && !tls_process_cke_psk_preamble(s, pkt, &al))
+        goto err;
+
+    if (alg_k & SSL_kPSK) {
+        /* Identity extracted earlier: should be nothing left */
+        if (PACKET_remaining(pkt) != 0) {
+            al = SSL_AD_HANDSHAKE_FAILURE;
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
+                   SSL_R_LENGTH_MISMATCH);
+            goto err;
+        }
+        /* PSK handled by ssl_generate_master_secret */
+        if (!ssl_generate_master_secret(s, NULL, 0, 0)) {
+            al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+            goto err;
+        }
+    } else if (alg_k & (SSL_kRSA | SSL_kRSAPSK)) {
+        if (!tls_process_cke_rsa(s, pkt, &al))
+            goto err;
+    } else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
+        if (!tls_process_cke_dhe(s, pkt, &al))
+            goto err;
+    } else if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) {
+        if (!tls_process_cke_ecdhe(s, pkt, &al))
+            goto err;
+    } else if (alg_k & SSL_kSRP) {
+        if (!tls_process_cke_srp(s, pkt, &al))
+            goto err;
+    } else if (alg_k & SSL_kGOST) {
+        if (!tls_process_cke_gost(s, pkt, &al))
+            goto err;
+    } else {
+        al = SSL_AD_HANDSHAKE_FAILURE;
+        SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
+               SSL_R_UNKNOWN_CIPHER_TYPE);
+        goto err;
+    }
+
+    return MSG_PROCESS_CONTINUE_PROCESSING;
+ err:
+    if (al != -1)
+        ssl3_send_alert(s, SSL3_AL_FATAL, al);
+#ifndef OPENSSL_NO_PSK
+    OPENSSL_clear_free(s->s3->tmp.psk, s->s3->tmp.psklen);
+    s->s3->tmp.psk = NULL;
+#endif
+    ossl_statem_set_error(s);
+    return MSG_PROCESS_ERROR;
+}
+
+WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst)
+{
+#ifndef OPENSSL_NO_SCTP
+    if (wst == WORK_MORE_A) {
+        if (SSL_IS_DTLS(s)) {
+            unsigned char sctpauthkey[64];
+            char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
+            /*
+             * Add new shared key for SCTP-Auth, will be ignored if no SCTP
+             * used.
+             */
+            memcpy(labelbuffer, DTLS1_SCTP_AUTH_LABEL,
+                   sizeof(DTLS1_SCTP_AUTH_LABEL));
+
+            if (SSL_export_keying_material(s, sctpauthkey,
+                                           sizeof(sctpauthkey), labelbuffer,
+                                           sizeof(labelbuffer), NULL, 0,
+                                           0) <= 0) {
+                ossl_statem_set_error(s);
+                return WORK_ERROR;;
+            }
+
+            BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
+                     sizeof(sctpauthkey), sctpauthkey);
+        }
+        wst = WORK_MORE_B;
+    }
+
+    if ((wst == WORK_MORE_B)
+        /* Is this SCTP? */
+        && BIO_dgram_is_sctp(SSL_get_wbio(s))
+        /* Are we renegotiating? */
+        && s->renegotiate
+        /* Are we going to skip the CertificateVerify? */
+        && (s->session->peer == NULL || s->statem.no_cert_verify)
+        && BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) {
+        s->s3->in_read_app_data = 2;
+        s->rwstate = SSL_READING;
+        BIO_clear_retry_flags(SSL_get_rbio(s));
+        BIO_set_retry_read(SSL_get_rbio(s));
+        ossl_statem_set_sctp_read_sock(s, 1);
+        return WORK_MORE_B;
+    } else {
+        ossl_statem_set_sctp_read_sock(s, 0);
+    }
+#endif
+
+    if (s->statem.no_cert_verify || !s->session->peer) {
+        /*
+         * No certificate verify or no peer certificate so we no longer need
+         * the handshake_buffer
+         */
+        if (!ssl3_digest_cached_records(s, 0)) {
+            ossl_statem_set_error(s);
+            return WORK_ERROR;
+        }
+        return WORK_FINISHED_CONTINUE;
+    } else {
+        if (!s->s3->handshake_buffer) {
+            SSLerr(SSL_F_TLS_POST_PROCESS_CLIENT_KEY_EXCHANGE,
+                   ERR_R_INTERNAL_ERROR);
+            ossl_statem_set_error(s);
+            return WORK_ERROR;
+        }
+        /*
+         * For sigalgs freeze the handshake buffer. If we support
+         * extms we've done this already so this is a no-op
+         */
+        if (!ssl3_digest_cached_records(s, 1)) {
+            ossl_statem_set_error(s);
+            return WORK_ERROR;
+        }
+    }
+
+    return WORK_FINISHED_CONTINUE;
+}
+
+MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
+{
+    EVP_PKEY *pkey = NULL;
+    const unsigned char *sig, *data;
+#ifndef OPENSSL_NO_GOST
+    unsigned char *gost_data = NULL;
+#endif
+    int al, ret = MSG_PROCESS_ERROR;
+    int type = 0, j;
+    unsigned int len;
+    X509 *peer;
+    const EVP_MD *md = NULL;
+    long hdatalen = 0;
+    void *hdata;
+
+    EVP_MD_CTX *mctx = EVP_MD_CTX_new();
+
+    if (mctx == NULL) {
+        SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_MALLOC_FAILURE);
+        al = SSL_AD_INTERNAL_ERROR;
+        goto f_err;
+    }
+
+    peer = s->session->peer;
+    pkey = X509_get0_pubkey(peer);
+    if (pkey == NULL) {
+        al = SSL_AD_INTERNAL_ERROR;
+        goto f_err;
+    }
+
+    type = X509_certificate_type(peer, pkey);
+
+    if (!(type & EVP_PKT_SIGN)) {
+        SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY,
+               SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE);
+        al = SSL_AD_ILLEGAL_PARAMETER;
+        goto f_err;
+    }
+
+    /* Check for broken implementations of GOST ciphersuites */
+    /*
+     * If key is GOST and n is exactly 64, it is bare signature without
+     * length field (CryptoPro implementations at least till CSP 4.0)
+     */
+#ifndef OPENSSL_NO_GOST
+    if (PACKET_remaining(pkt) == 64
+        && EVP_PKEY_id(pkey) == NID_id_GostR3410_2001) {
+        len = 64;
+    } else
+#endif
+    {
+        if (SSL_USE_SIGALGS(s)) {
+            int rv;
+
+            if (!PACKET_get_bytes(pkt, &sig, 2)) {
+                al = SSL_AD_DECODE_ERROR;
+                goto f_err;
+            }
+            rv = tls12_check_peer_sigalg(&md, s, sig, pkey);
+            if (rv == -1) {
+                al = SSL_AD_INTERNAL_ERROR;
+                goto f_err;
+            } else if (rv == 0) {
+                al = SSL_AD_DECODE_ERROR;
+                goto f_err;
+            }
+#ifdef SSL_DEBUG
+            fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
+#endif
+        } else {
+            /* Use default digest for this key type */
+            int idx = ssl_cert_type(NULL, pkey);
+            if (idx >= 0)
+                md = s->s3->tmp.md[idx];
+            if (md == NULL) {
+                al = SSL_AD_INTERNAL_ERROR;
+                goto f_err;
+            }
+        }
+
+        if (!PACKET_get_net_2(pkt, &len)) {
+            SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_LENGTH_MISMATCH);
+            al = SSL_AD_DECODE_ERROR;
+            goto f_err;
+        }
+    }
+    j = EVP_PKEY_size(pkey);
+    if (((int)len > j) || ((int)PACKET_remaining(pkt) > j)
+        || (PACKET_remaining(pkt) == 0)) {
+        SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_WRONG_SIGNATURE_SIZE);
+        al = SSL_AD_DECODE_ERROR;
+        goto f_err;
+    }
+    if (!PACKET_get_bytes(pkt, &data, len)) {
+        SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_LENGTH_MISMATCH);
+        al = SSL_AD_DECODE_ERROR;
+        goto f_err;
+    }
+
+    hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
+    if (hdatalen <= 0) {
+        SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
+        al = SSL_AD_INTERNAL_ERROR;
+        goto f_err;
+    }
+#ifdef SSL_DEBUG
+    fprintf(stderr, "Using client verify alg %s\n", EVP_MD_name(md));
+#endif
+    if (!EVP_VerifyInit_ex(mctx, md, NULL)
+        || !EVP_VerifyUpdate(mctx, hdata, hdatalen)) {
+        SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
+        al = SSL_AD_INTERNAL_ERROR;
+        goto f_err;
+    }
+#ifndef OPENSSL_NO_GOST
+    {
+        int pktype = EVP_PKEY_id(pkey);
+        if (pktype == NID_id_GostR3410_2001
+            || pktype == NID_id_GostR3410_2012_256
+            || pktype == NID_id_GostR3410_2012_512) {
+            if ((gost_data = OPENSSL_malloc(len)) == NULL) {
+                SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_MALLOC_FAILURE);
+                al = SSL_AD_INTERNAL_ERROR;
+                goto f_err;
+            }
+            BUF_reverse(gost_data, data, len);
+            data = gost_data;
+        }
+    }
+#endif
+
+    if (s->version == SSL3_VERSION
+        && !EVP_MD_CTX_ctrl(mctx, EVP_CTRL_SSL3_MASTER_SECRET,
+                            s->session->master_key_length,
+                            s->session->master_key)) {
+        SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
+        al = SSL_AD_INTERNAL_ERROR;
+        goto f_err;
+    }
+
+    if (EVP_VerifyFinal(mctx, data, len, pkey) <= 0) {
+        al = SSL_AD_DECRYPT_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_SIGNATURE);
+        goto f_err;
+    }
+
+    ret = MSG_PROCESS_CONTINUE_PROCESSING;
+    if (0) {
+ f_err:
+        ssl3_send_alert(s, SSL3_AL_FATAL, al);
+        ossl_statem_set_error(s);
+    }
+    BIO_free(s->s3->handshake_buffer);
+    s->s3->handshake_buffer = NULL;
+    EVP_MD_CTX_free(mctx);
+#ifndef OPENSSL_NO_GOST
+    OPENSSL_free(gost_data);
+#endif
+    return ret;
+}
+
+MSG_PROCESS_RETURN tls_process_client_certificate(SSL *s, PACKET *pkt)
+{
+    int i, al = SSL_AD_INTERNAL_ERROR, ret = MSG_PROCESS_ERROR;
+    X509 *x = NULL;
+    unsigned long l, llen;
+    const unsigned char *certstart, *certbytes;
+    STACK_OF(X509) *sk = NULL;
+    PACKET spkt;
+
+    if ((sk = sk_X509_new_null()) == NULL) {
+        SSLerr(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE);
+        goto f_err;
+    }
+
+    if (!PACKET_get_net_3(pkt, &llen)
+        || !PACKET_get_sub_packet(pkt, &spkt, llen)
+        || PACKET_remaining(pkt) != 0) {
+        al = SSL_AD_DECODE_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, SSL_R_LENGTH_MISMATCH);
+        goto f_err;
+    }
+
+    while (PACKET_remaining(&spkt) > 0) {
+        if (!PACKET_get_net_3(&spkt, &l)
+            || !PACKET_get_bytes(&spkt, &certbytes, l)) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE,
+                   SSL_R_CERT_LENGTH_MISMATCH);
+            goto f_err;
+        }
+
+        certstart = certbytes;
+        x = d2i_X509(NULL, (const unsigned char **)&certbytes, l);
+        if (x == NULL) {
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, ERR_R_ASN1_LIB);
+            goto f_err;
+        }
+        if (certbytes != (certstart + l)) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE,
+                   SSL_R_CERT_LENGTH_MISMATCH);
+            goto f_err;
+        }
+        if (!sk_X509_push(sk, x)) {
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE);
+            goto f_err;
+        }
+        x = NULL;
+    }
+
+    if (sk_X509_num(sk) <= 0) {
+        /* TLS does not mind 0 certs returned */
+        if (s->version == SSL3_VERSION) {
+            al = SSL_AD_HANDSHAKE_FAILURE;
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE,
+                   SSL_R_NO_CERTIFICATES_RETURNED);
+            goto f_err;
+        }
+        /* Fail for TLS only if we required a certificate */
+        else if ((s->verify_mode & SSL_VERIFY_PEER) &&
+                 (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) {
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE,
+                   SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
+            al = SSL_AD_HANDSHAKE_FAILURE;
+            goto f_err;
+        }
+        /* No client certificate so digest cached records */
+        if (s->s3->handshake_buffer && !ssl3_digest_cached_records(s, 0)) {
+            goto f_err;
+        }
+    } else {
+        EVP_PKEY *pkey;
+        i = ssl_verify_cert_chain(s, sk);
+        if (i <= 0) {
+            al = ssl_verify_alarm_type(s->verify_result);
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE,
+                   SSL_R_CERTIFICATE_VERIFY_FAILED);
+            goto f_err;
+        }
+        if (i > 1) {
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, i);
+            al = SSL_AD_HANDSHAKE_FAILURE;
+            goto f_err;
+        }
+        pkey = X509_get0_pubkey(sk_X509_value(sk, 0));
+        if (pkey == NULL) {
+            al = SSL3_AD_HANDSHAKE_FAILURE;
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE,
+                   SSL_R_UNKNOWN_CERTIFICATE_TYPE);
+            goto f_err;
+        }
+    }
+
+    X509_free(s->session->peer);
+    s->session->peer = sk_X509_shift(sk);
+    s->session->verify_result = s->verify_result;
+
+    sk_X509_pop_free(s->session->peer_chain, X509_free);
+    s->session->peer_chain = sk;
+    /*
+     * Inconsistency alert: cert_chain does *not* include the peer's own
+     * certificate, while we do include it in statem_clnt.c
+     */
+    sk = NULL;
+    ret = MSG_PROCESS_CONTINUE_READING;
+    goto done;
+
+ f_err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    ossl_statem_set_error(s);
+ done:
+    X509_free(x);
+    sk_X509_pop_free(sk, X509_free);
+    return ret;
+}
+
+int tls_construct_server_certificate(SSL *s)
+{
+    CERT_PKEY *cpk;
+
+    cpk = ssl_get_server_send_pkey(s);
+    if (cpk == NULL) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR);
+        ossl_statem_set_error(s);
+        return 0;
+    }
+
+    if (!ssl3_output_cert_chain(s, cpk)) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR);
+        ossl_statem_set_error(s);
+        return 0;
+    }
+
+    return 1;
+}
+
+int tls_construct_new_session_ticket(SSL *s)
+{
+    unsigned char *senc = NULL;
+    EVP_CIPHER_CTX *ctx = NULL;
+    HMAC_CTX *hctx = NULL;
+    unsigned char *p, *macstart;
+    const unsigned char *const_p;
+    int len, slen_full, slen;
+    SSL_SESSION *sess;
+    unsigned int hlen;
+    SSL_CTX *tctx = s->session_ctx;
+    unsigned char iv[EVP_MAX_IV_LENGTH];
+    unsigned char key_name[TLSEXT_KEYNAME_LENGTH];
+    int iv_len;
+
+    /* get session encoding length */
+    slen_full = i2d_SSL_SESSION(s->session, NULL);
+    /*
+     * Some length values are 16 bits, so forget it if session is too
+     * long
+     */
+    if (slen_full == 0 || slen_full > 0xFF00) {
+        ossl_statem_set_error(s);
+        return 0;
+    }
+    senc = OPENSSL_malloc(slen_full);
+    if (senc == NULL) {
+        ossl_statem_set_error(s);
+        return 0;
+    }
+
+    ctx = EVP_CIPHER_CTX_new();
+    hctx = HMAC_CTX_new();
+    if (ctx == NULL || hctx == NULL) {
+        SSLerr(SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    p = senc;
+    if (!i2d_SSL_SESSION(s->session, &p))
+        goto err;
+
+    /*
+     * create a fresh copy (not shared with other threads) to clean up
+     */
+    const_p = senc;
+    sess = d2i_SSL_SESSION(NULL, &const_p, slen_full);
+    if (sess == NULL)
+        goto err;
+    sess->session_id_length = 0; /* ID is irrelevant for the ticket */
+
+    slen = i2d_SSL_SESSION(sess, NULL);
+    if (slen == 0 || slen > slen_full) { /* shouldn't ever happen */
+        SSL_SESSION_free(sess);
+        goto err;
+    }
+    p = senc;
+    if (!i2d_SSL_SESSION(sess, &p)) {
+        SSL_SESSION_free(sess);
+        goto err;
+    }
+    SSL_SESSION_free(sess);
+
+    /*-
+     * Grow buffer if need be: the length calculation is as
+     * follows handshake_header_length +
+     * 4 (ticket lifetime hint) + 2 (ticket length) +
+     * sizeof(keyname) + max_iv_len (iv length) +
+     * max_enc_block_size (max encrypted session * length) +
+     * max_md_size (HMAC) + session_length.
+     */
+    if (!BUF_MEM_grow(s->init_buf,
+                      SSL_HM_HEADER_LENGTH(s) + 6 + sizeof(key_name) +
+                      EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH +
+                      EVP_MAX_MD_SIZE + slen))
+        goto err;
+
+    p = ssl_handshake_start(s);
+    /*
+     * Initialize HMAC and cipher contexts. If callback present it does
+     * all the work otherwise use generated values from parent ctx.
+     */
+    if (tctx->tlsext_ticket_key_cb) {
+        /* if 0 is returned, write an empty ticket */
+        int ret = tctx->tlsext_ticket_key_cb(s, key_name, iv, ctx,
+                                             hctx, 1);
+
+        if (ret == 0) {
+            l2n(0, p);          /* timeout */
+            s2n(0, p);          /* length */
+            if (!ssl_set_handshake_header
+                (s, SSL3_MT_NEWSESSION_TICKET, p - ssl_handshake_start(s)))
+                goto err;
+            OPENSSL_free(senc);
+            EVP_CIPHER_CTX_free(ctx);
+            HMAC_CTX_free(hctx);
+            return 1;
+        }
+        if (ret < 0)
+            goto err;
+        iv_len = EVP_CIPHER_CTX_iv_length(ctx);
+    } else {
+        const EVP_CIPHER *cipher = EVP_aes_256_cbc();
+
+        iv_len = EVP_CIPHER_iv_length(cipher);
+        if (RAND_bytes(iv, iv_len) <= 0)
+            goto err;
+        if (!EVP_EncryptInit_ex(ctx, cipher, NULL,
+                                tctx->tlsext_tick_aes_key, iv))
+            goto err;
+        if (!HMAC_Init_ex(hctx, tctx->tlsext_tick_hmac_key,
+                          sizeof(tctx->tlsext_tick_hmac_key),
+                          EVP_sha256(), NULL))
+            goto err;
+        memcpy(key_name, tctx->tlsext_tick_key_name,
+               sizeof(tctx->tlsext_tick_key_name));
+    }
+
+    /*
+     * Ticket lifetime hint (advisory only): We leave this unspecified
+     * for resumed session (for simplicity), and guess that tickets for
+     * new sessions will live as long as their sessions.
+     */
+    l2n(s->hit ? 0 : s->session->timeout, p);
+
+    /* Skip ticket length for now */
+    p += 2;
+    /* Output key name */
+    macstart = p;
+    memcpy(p, key_name, sizeof(key_name));
+    p += sizeof(key_name);
+    /* output IV */
+    memcpy(p, iv, iv_len);
+    p += iv_len;
+    /* Encrypt session data */
+    if (!EVP_EncryptUpdate(ctx, p, &len, senc, slen))
+        goto err;
+    p += len;
+    if (!EVP_EncryptFinal(ctx, p, &len))
+        goto err;
+    p += len;
+
+    if (!HMAC_Update(hctx, macstart, p - macstart))
+        goto err;
+    if (!HMAC_Final(hctx, p, &hlen))
+        goto err;
+
+    EVP_CIPHER_CTX_free(ctx);
+    HMAC_CTX_free(hctx);
+    ctx = NULL;
+    hctx = NULL;
+
+    p += hlen;
+    /* Now write out lengths: p points to end of data written */
+    /* Total length */
+    len = p - ssl_handshake_start(s);
+    /* Skip ticket lifetime hint */
+    p = ssl_handshake_start(s) + 4;
+    s2n(len - 6, p);
+    if (!ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len))
+        goto err;
+    OPENSSL_free(senc);
+
+    return 1;
+ err:
+    OPENSSL_free(senc);
+    EVP_CIPHER_CTX_free(ctx);
+    HMAC_CTX_free(hctx);
+    ossl_statem_set_error(s);
+    return 0;
+}
+
+int tls_construct_cert_status(SSL *s)
+{
+    unsigned char *p;
+    size_t msglen;
+
+    /*-
+     * Grow buffer if need be: the length calculation is as
+     * follows handshake_header_length +
+     * 1 (ocsp response type) + 3 (ocsp response length)
+     * + (ocsp response)
+     */
+    msglen = 4 + s->tlsext_ocsp_resplen;
+    if (!BUF_MEM_grow(s->init_buf, SSL_HM_HEADER_LENGTH(s) + msglen))
+        goto err;
+
+    p = ssl_handshake_start(s);
+
+    /* status type */
+    *(p++) = s->tlsext_status_type;
+    /* length of OCSP response */
+    l2n3(s->tlsext_ocsp_resplen, p);
+    /* actual response */
+    memcpy(p, s->tlsext_ocsp_resp, s->tlsext_ocsp_resplen);
+
+    if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_STATUS, msglen))
+        goto err;
+
+    return 1;
+
+ err:
+    ossl_statem_set_error(s);
+    return 0;
+}
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+/*
+ * tls_process_next_proto reads a Next Protocol Negotiation handshake message.
+ * It sets the next_proto member in s if found
+ */
+MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt)
+{
+    PACKET next_proto, padding;
+    size_t next_proto_len;
+
+    /*-
+     * The payload looks like:
+     *   uint8 proto_len;
+     *   uint8 proto[proto_len];
+     *   uint8 padding_len;
+     *   uint8 padding[padding_len];
+     */
+    if (!PACKET_get_length_prefixed_1(pkt, &next_proto)
+        || !PACKET_get_length_prefixed_1(pkt, &padding)
+        || PACKET_remaining(pkt) > 0) {
+        SSLerr(SSL_F_TLS_PROCESS_NEXT_PROTO, SSL_R_LENGTH_MISMATCH);
+        goto err;
+    }
+
+    if (!PACKET_memdup(&next_proto, &s->next_proto_negotiated, &next_proto_len)) {
+        s->next_proto_negotiated_len = 0;
+        goto err;
+    }
+
+    s->next_proto_negotiated_len = (unsigned char)next_proto_len;
+
+    return MSG_PROCESS_CONTINUE_READING;
+ err:
+    ossl_statem_set_error(s);
+    return MSG_PROCESS_ERROR;
+}
+#endif
+
+#define SSLV2_CIPHER_LEN    3
+
+STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s,
+                                               PACKET *cipher_suites,
+                                               STACK_OF(SSL_CIPHER) **skp,
+                                               int sslv2format, int *al)
+{
+    const SSL_CIPHER *c;
+    STACK_OF(SSL_CIPHER) *sk;
+    int n;
+    /* 3 = SSLV2_CIPHER_LEN > TLS_CIPHER_LEN = 2. */
+    unsigned char cipher[SSLV2_CIPHER_LEN];
+
+    s->s3->send_connection_binding = 0;
+
+    n = sslv2format ? SSLV2_CIPHER_LEN : TLS_CIPHER_LEN;
+
+    if (PACKET_remaining(cipher_suites) == 0) {
+        SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, SSL_R_NO_CIPHERS_SPECIFIED);
+        *al = SSL_AD_ILLEGAL_PARAMETER;
+        return NULL;
+    }
+
+    if (PACKET_remaining(cipher_suites) % n != 0) {
+        SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,
+               SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
+        *al = SSL_AD_DECODE_ERROR;
+        return NULL;
+    }
+
+    sk = sk_SSL_CIPHER_new_null();
+    if (sk == NULL) {
+        SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
+        *al = SSL_AD_INTERNAL_ERROR;
+        return NULL;
+    }
+
+    if (sslv2format) {
+        size_t numciphers = PACKET_remaining(cipher_suites) / n;
+        PACKET sslv2ciphers = *cipher_suites;
+        unsigned int leadbyte;
+        unsigned char *raw;
+
+        /*
+         * We store the raw ciphers list in SSLv3+ format so we need to do some
+         * preprocessing to convert the list first. If there are any SSLv2 only
+         * ciphersuites with a non-zero leading byte then we are going to
+         * slightly over allocate because we won't store those. But that isn't a
+         * problem.
+         */
+        raw = OPENSSL_malloc(numciphers * TLS_CIPHER_LEN);
+        s->s3->tmp.ciphers_raw = raw;
+        if (raw == NULL) {
+            *al = SSL_AD_INTERNAL_ERROR;
+            goto err;
+        }
+        for (s->s3->tmp.ciphers_rawlen = 0;
+             PACKET_remaining(&sslv2ciphers) > 0;
+             raw += TLS_CIPHER_LEN) {
+            if (!PACKET_get_1(&sslv2ciphers, &leadbyte)
+                    || (leadbyte == 0
+                        && !PACKET_copy_bytes(&sslv2ciphers, raw,
+                                              TLS_CIPHER_LEN))
+                    || (leadbyte != 0
+                        && !PACKET_forward(&sslv2ciphers, TLS_CIPHER_LEN))) {
+                *al = SSL_AD_INTERNAL_ERROR;
+                OPENSSL_free(s->s3->tmp.ciphers_raw);
+                s->s3->tmp.ciphers_raw = NULL;
+                s->s3->tmp.ciphers_rawlen = 0;
+                goto err;
+            }
+            if (leadbyte == 0)
+                s->s3->tmp.ciphers_rawlen += TLS_CIPHER_LEN;
+        }
+    } else if (!PACKET_memdup(cipher_suites, &s->s3->tmp.ciphers_raw,
+                           &s->s3->tmp.ciphers_rawlen)) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        goto err;
+    }
+
+    while (PACKET_copy_bytes(cipher_suites, cipher, n)) {
+        /*
+         * SSLv3 ciphers wrapped in an SSLv2-compatible ClientHello have the
+         * first byte set to zero, while true SSLv2 ciphers have a non-zero
+         * first byte. We don't support any true SSLv2 ciphers, so skip them.
+         */
+        if (sslv2format && cipher[0] != '\0')
+            continue;
+
+        /* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */
+        if ((cipher[n - 2] == ((SSL3_CK_SCSV >> 8) & 0xff)) &&
+            (cipher[n - 1] == (SSL3_CK_SCSV & 0xff))) {
+            /* SCSV fatal if renegotiating */
+            if (s->renegotiate) {
+                SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,
+                       SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
+                *al = SSL_AD_HANDSHAKE_FAILURE;
+                goto err;
+            }
+            s->s3->send_connection_binding = 1;
+            continue;
+        }
+
+        /* Check for TLS_FALLBACK_SCSV */
+        if ((cipher[n - 2] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) &&
+            (cipher[n - 1] == (SSL3_CK_FALLBACK_SCSV & 0xff))) {
+            /*
+             * The SCSV indicates that the client previously tried a higher
+             * version. Fail if the current version is an unexpected
+             * downgrade.
+             */
+            if (!ssl_check_version_downgrade(s)) {
+                SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,
+                       SSL_R_INAPPROPRIATE_FALLBACK);
+                *al = SSL_AD_INAPPROPRIATE_FALLBACK;
+                goto err;
+            }
+            continue;
+        }
+
+        /* For SSLv2-compat, ignore leading 0-byte. */
+        c = ssl_get_cipher_by_char(s, sslv2format ? &cipher[1] : cipher);
+        if (c != NULL) {
+            if (!sk_SSL_CIPHER_push(sk, c)) {
+                SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
+                *al = SSL_AD_INTERNAL_ERROR;
+                goto err;
+            }
+        }
+    }
+    if (PACKET_remaining(cipher_suites) > 0) {
+        *al = SSL_AD_INTERNAL_ERROR;
+        SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+
+    *skp = sk;
+    return sk;
+ err:
+    sk_SSL_CIPHER_free(sk);
+    return NULL;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/t1_enc.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/t1_enc.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/t1_enc.c	(revision 331)
@@ -0,0 +1,703 @@
+/*
+ * Copyright 1995-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
+ */
+
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <stdio.h>
+#include "ssl_locl.h"
+#include <openssl/comp.h>
+#include <openssl/evp.h>
+#include <openssl/kdf.h>
+#include <openssl/rand.h>
+
+/* seed1 through seed5 are concatenated */
+static int tls1_PRF(SSL *s,
+                    const void *seed1, int seed1_len,
+                    const void *seed2, int seed2_len,
+                    const void *seed3, int seed3_len,
+                    const void *seed4, int seed4_len,
+                    const void *seed5, int seed5_len,
+                    const unsigned char *sec, int slen,
+                    unsigned char *out, int olen)
+{
+    const EVP_MD *md = ssl_prf_md(s);
+    EVP_PKEY_CTX *pctx = NULL;
+
+    int ret = 0;
+    size_t outlen = olen;
+
+    if (md == NULL) {
+        /* Should never happen */
+        SSLerr(SSL_F_TLS1_PRF, ERR_R_INTERNAL_ERROR);
+        return 0;
+    }
+    pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, NULL);
+    if (pctx == NULL || EVP_PKEY_derive_init(pctx) <= 0
+        || EVP_PKEY_CTX_set_tls1_prf_md(pctx, md) <= 0
+        || EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, sec, slen) <= 0)
+        goto err;
+
+    if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed1, seed1_len) <= 0)
+        goto err;
+    if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed2, seed2_len) <= 0)
+        goto err;
+    if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed3, seed3_len) <= 0)
+        goto err;
+    if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed4, seed4_len) <= 0)
+        goto err;
+    if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, seed5, seed5_len) <= 0)
+        goto err;
+
+    if (EVP_PKEY_derive(pctx, out, &outlen) <= 0)
+        goto err;
+    ret = 1;
+
+ err:
+    EVP_PKEY_CTX_free(pctx);
+    return ret;
+}
+
+static int tls1_generate_key_block(SSL *s, unsigned char *km, int num)
+{
+    int ret;
+    ret = tls1_PRF(s,
+                   TLS_MD_KEY_EXPANSION_CONST,
+                   TLS_MD_KEY_EXPANSION_CONST_SIZE, s->s3->server_random,
+                   SSL3_RANDOM_SIZE, s->s3->client_random, SSL3_RANDOM_SIZE,
+                   NULL, 0, NULL, 0, s->session->master_key,
+                   s->session->master_key_length, km, num);
+
+    return ret;
+}
+
+int tls1_change_cipher_state(SSL *s, int which)
+{
+    unsigned char *p, *mac_secret;
+    unsigned char tmp1[EVP_MAX_KEY_LENGTH];
+    unsigned char tmp2[EVP_MAX_KEY_LENGTH];
+    unsigned char iv1[EVP_MAX_IV_LENGTH * 2];
+    unsigned char iv2[EVP_MAX_IV_LENGTH * 2];
+    unsigned char *ms, *key, *iv;
+    EVP_CIPHER_CTX *dd;
+    const EVP_CIPHER *c;
+#ifndef OPENSSL_NO_COMP
+    const SSL_COMP *comp;
+#endif
+    const EVP_MD *m;
+    int mac_type;
+    int *mac_secret_size;
+    EVP_MD_CTX *mac_ctx;
+    EVP_PKEY *mac_key;
+    int n, i, j, k, cl;
+    int reuse_dd = 0;
+
+    c = s->s3->tmp.new_sym_enc;
+    m = s->s3->tmp.new_hash;
+    mac_type = s->s3->tmp.new_mac_pkey_type;
+#ifndef OPENSSL_NO_COMP
+    comp = s->s3->tmp.new_compression;
+#endif
+
+    if (which & SSL3_CC_READ) {
+        if (s->tlsext_use_etm)
+            s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_READ;
+        else
+            s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC_READ;
+
+        if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
+            s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM;
+        else
+            s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM;
+
+        if (s->enc_read_ctx != NULL)
+            reuse_dd = 1;
+        else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL)
+            goto err;
+        else
+            /*
+             * make sure it's initialised in case we exit later with an error
+             */
+            EVP_CIPHER_CTX_reset(s->enc_read_ctx);
+        dd = s->enc_read_ctx;
+        mac_ctx = ssl_replace_hash(&s->read_hash, NULL);
+        if (mac_ctx == NULL)
+            goto err;
+#ifndef OPENSSL_NO_COMP
+        COMP_CTX_free(s->expand);
+        s->expand = NULL;
+        if (comp != NULL) {
+            s->expand = COMP_CTX_new(comp->method);
+            if (s->expand == NULL) {
+                SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,
+                       SSL_R_COMPRESSION_LIBRARY_ERROR);
+                goto err2;
+            }
+        }
+#endif
+        /*
+         * this is done by dtls1_reset_seq_numbers for DTLS
+         */
+        if (!SSL_IS_DTLS(s))
+            RECORD_LAYER_reset_read_sequence(&s->rlayer);
+        mac_secret = &(s->s3->read_mac_secret[0]);
+        mac_secret_size = &(s->s3->read_mac_secret_size);
+    } else {
+        if (s->tlsext_use_etm)
+            s->s3->flags |= TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE;
+        else
+            s->s3->flags &= ~TLS1_FLAGS_ENCRYPT_THEN_MAC_WRITE;
+
+        if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
+            s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM;
+        else
+            s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM;
+        if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s))
+            reuse_dd = 1;
+        else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL)
+            goto err;
+        dd = s->enc_write_ctx;
+        if (SSL_IS_DTLS(s)) {
+            mac_ctx = EVP_MD_CTX_new();
+            if (mac_ctx == NULL)
+                goto err;
+            s->write_hash = mac_ctx;
+        } else {
+            mac_ctx = ssl_replace_hash(&s->write_hash, NULL);
+            if (mac_ctx == NULL)
+                goto err;
+        }
+#ifndef OPENSSL_NO_COMP
+        COMP_CTX_free(s->compress);
+        s->compress = NULL;
+        if (comp != NULL) {
+            s->compress = COMP_CTX_new(comp->method);
+            if (s->compress == NULL) {
+                SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,
+                       SSL_R_COMPRESSION_LIBRARY_ERROR);
+                goto err2;
+            }
+        }
+#endif
+        /*
+         * this is done by dtls1_reset_seq_numbers for DTLS
+         */
+        if (!SSL_IS_DTLS(s))
+            RECORD_LAYER_reset_write_sequence(&s->rlayer);
+        mac_secret = &(s->s3->write_mac_secret[0]);
+        mac_secret_size = &(s->s3->write_mac_secret_size);
+    }
+
+    if (reuse_dd)
+        EVP_CIPHER_CTX_reset(dd);
+
+    p = s->s3->tmp.key_block;
+    i = *mac_secret_size = s->s3->tmp.new_mac_secret_size;
+
+    cl = EVP_CIPHER_key_length(c);
+    j = cl;
+    /* Was j=(exp)?5:EVP_CIPHER_key_length(c); */
+    /* If GCM/CCM mode only part of IV comes from PRF */
+    if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE)
+        k = EVP_GCM_TLS_FIXED_IV_LEN;
+    else if (EVP_CIPHER_mode(c) == EVP_CIPH_CCM_MODE)
+        k = EVP_CCM_TLS_FIXED_IV_LEN;
+    else
+        k = EVP_CIPHER_iv_length(c);
+    if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
+        (which == SSL3_CHANGE_CIPHER_SERVER_READ)) {
+        ms = &(p[0]);
+        n = i + i;
+        key = &(p[n]);
+        n += j + j;
+        iv = &(p[n]);
+        n += k + k;
+    } else {
+        n = i;
+        ms = &(p[n]);
+        n += i + j;
+        key = &(p[n]);
+        n += j + k;
+        iv = &(p[n]);
+        n += k;
+    }
+
+    if (n > s->s3->tmp.key_block_length) {
+        SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+        goto err2;
+    }
+
+    memcpy(mac_secret, ms, i);
+
+    if (!(EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER)) {
+        mac_key = EVP_PKEY_new_mac_key(mac_type, NULL,
+                                       mac_secret, *mac_secret_size);
+        if (mac_key == NULL
+            || EVP_DigestSignInit(mac_ctx, NULL, m, NULL, mac_key) <= 0) {
+            EVP_PKEY_free(mac_key);
+            SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+            goto err2;
+        }
+        EVP_PKEY_free(mac_key);
+    }
+#ifdef SSL_DEBUG
+    printf("which = %04X\nmac key=", which);
+    {
+        int z;
+        for (z = 0; z < i; z++)
+            printf("%02X%c", ms[z], ((z + 1) % 16) ? ' ' : '\n');
+    }
+#endif
+
+    if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) {
+        if (!EVP_CipherInit_ex(dd, c, NULL, key, NULL, (which & SSL3_CC_WRITE))
+            || !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GCM_SET_IV_FIXED, k, iv)) {
+            SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+            goto err2;
+        }
+    } else if (EVP_CIPHER_mode(c) == EVP_CIPH_CCM_MODE) {
+        int taglen;
+        if (s->s3->tmp.
+            new_cipher->algorithm_enc & (SSL_AES128CCM8 | SSL_AES256CCM8))
+            taglen = 8;
+        else
+            taglen = 16;
+        if (!EVP_CipherInit_ex(dd, c, NULL, NULL, NULL, (which & SSL3_CC_WRITE))
+            || !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_IVLEN, 12, NULL)
+            || !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_TAG, taglen, NULL)
+            || !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_CCM_SET_IV_FIXED, k, iv)
+            || !EVP_CipherInit_ex(dd, NULL, NULL, key, NULL, -1)) {
+            SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+            goto err2;
+        }
+    } else {
+        if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) {
+            SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+            goto err2;
+        }
+    }
+    /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */
+    if ((EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER) && *mac_secret_size
+        && !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_MAC_KEY,
+                                *mac_secret_size, mac_secret)) {
+        SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+        goto err2;
+    }
+#ifdef OPENSSL_SSL_TRACE_CRYPTO
+    if (s->msg_callback) {
+        int wh = which & SSL3_CC_WRITE ? TLS1_RT_CRYPTO_WRITE : 0;
+        if (*mac_secret_size)
+            s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_MAC,
+                            mac_secret, *mac_secret_size,
+                            s, s->msg_callback_arg);
+        if (c->key_len)
+            s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY,
+                            key, c->key_len, s, s->msg_callback_arg);
+        if (k) {
+            if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE)
+                wh |= TLS1_RT_CRYPTO_FIXED_IV;
+            else
+                wh |= TLS1_RT_CRYPTO_IV;
+            s->msg_callback(2, s->version, wh, iv, k, s, s->msg_callback_arg);
+        }
+    }
+#endif
+
+#ifdef SSL_DEBUG
+    printf("which = %04X\nkey=", which);
+    {
+        int z;
+        for (z = 0; z < EVP_CIPHER_key_length(c); z++)
+            printf("%02X%c", key[z], ((z + 1) % 16) ? ' ' : '\n');
+    }
+    printf("\niv=");
+    {
+        int z;
+        for (z = 0; z < k; z++)
+            printf("%02X%c", iv[z], ((z + 1) % 16) ? ' ' : '\n');
+    }
+    printf("\n");
+#endif
+
+    OPENSSL_cleanse(tmp1, sizeof(tmp1));
+    OPENSSL_cleanse(tmp2, sizeof(tmp1));
+    OPENSSL_cleanse(iv1, sizeof(iv1));
+    OPENSSL_cleanse(iv2, sizeof(iv2));
+    return (1);
+ err:
+    SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE);
+ err2:
+    OPENSSL_cleanse(tmp1, sizeof(tmp1));
+    OPENSSL_cleanse(tmp2, sizeof(tmp1));
+    OPENSSL_cleanse(iv1, sizeof(iv1));
+    OPENSSL_cleanse(iv2, sizeof(iv2));
+    return (0);
+}
+
+int tls1_setup_key_block(SSL *s)
+{
+    unsigned char *p;
+    const EVP_CIPHER *c;
+    const EVP_MD *hash;
+    int num;
+    SSL_COMP *comp;
+    int mac_type = NID_undef, mac_secret_size = 0;
+    int ret = 0;
+
+    if (s->s3->tmp.key_block_length != 0)
+        return (1);
+
+    if (!ssl_cipher_get_evp(s->session, &c, &hash, &mac_type, &mac_secret_size,
+                            &comp, s->tlsext_use_etm)) {
+        SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
+        return (0);
+    }
+
+    s->s3->tmp.new_sym_enc = c;
+    s->s3->tmp.new_hash = hash;
+    s->s3->tmp.new_mac_pkey_type = mac_type;
+    s->s3->tmp.new_mac_secret_size = mac_secret_size;
+    num = EVP_CIPHER_key_length(c) + mac_secret_size + EVP_CIPHER_iv_length(c);
+    num *= 2;
+
+    ssl3_cleanup_key_block(s);
+
+    if ((p = OPENSSL_malloc(num)) == NULL) {
+        SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    s->s3->tmp.key_block_length = num;
+    s->s3->tmp.key_block = p;
+
+#ifdef SSL_DEBUG
+    printf("client random\n");
+    {
+        int z;
+        for (z = 0; z < SSL3_RANDOM_SIZE; z++)
+            printf("%02X%c", s->s3->client_random[z],
+                   ((z + 1) % 16) ? ' ' : '\n');
+    }
+    printf("server random\n");
+    {
+        int z;
+        for (z = 0; z < SSL3_RANDOM_SIZE; z++)
+            printf("%02X%c", s->s3->server_random[z],
+                   ((z + 1) % 16) ? ' ' : '\n');
+    }
+    printf("master key\n");
+    {
+        int z;
+        for (z = 0; z < s->session->master_key_length; z++)
+            printf("%02X%c", s->session->master_key[z],
+                   ((z + 1) % 16) ? ' ' : '\n');
+    }
+#endif
+    if (!tls1_generate_key_block(s, p, num))
+        goto err;
+#ifdef SSL_DEBUG
+    printf("\nkey block\n");
+    {
+        int z;
+        for (z = 0; z < num; z++)
+            printf("%02X%c", p[z], ((z + 1) % 16) ? ' ' : '\n');
+    }
+#endif
+
+    if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)
+        && s->method->version <= TLS1_VERSION) {
+        /*
+         * enable vulnerability countermeasure for CBC ciphers with known-IV
+         * problem (http://www.openssl.org/~bodo/tls-cbc.txt)
+         */
+        s->s3->need_empty_fragments = 1;
+
+        if (s->session->cipher != NULL) {
+            if (s->session->cipher->algorithm_enc == SSL_eNULL)
+                s->s3->need_empty_fragments = 0;
+
+#ifndef OPENSSL_NO_RC4
+            if (s->session->cipher->algorithm_enc == SSL_RC4)
+                s->s3->need_empty_fragments = 0;
+#endif
+        }
+    }
+
+    ret = 1;
+ err:
+    return (ret);
+}
+
+int tls1_final_finish_mac(SSL *s, const char *str, int slen, unsigned char *out)
+{
+    int hashlen;
+    unsigned char hash[EVP_MAX_MD_SIZE];
+
+    if (!ssl3_digest_cached_records(s, 0))
+        return 0;
+
+    hashlen = ssl_handshake_hash(s, hash, sizeof(hash));
+
+    if (hashlen == 0)
+        return 0;
+
+    if (!tls1_PRF(s, str, slen, hash, hashlen, NULL, 0, NULL, 0, NULL, 0,
+                  s->session->master_key, s->session->master_key_length,
+                  out, TLS1_FINISH_MAC_LENGTH))
+        return 0;
+    OPENSSL_cleanse(hash, hashlen);
+    return TLS1_FINISH_MAC_LENGTH;
+}
+
+int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
+                                int len)
+{
+    if (s->session->flags & SSL_SESS_FLAG_EXTMS) {
+        unsigned char hash[EVP_MAX_MD_SIZE * 2];
+        int hashlen;
+        /*
+         * Digest cached records keeping record buffer (if present): this wont
+         * affect client auth because we're freezing the buffer at the same
+         * point (after client key exchange and before certificate verify)
+         */
+        if (!ssl3_digest_cached_records(s, 1))
+            return -1;
+        hashlen = ssl_handshake_hash(s, hash, sizeof(hash));
+#ifdef SSL_DEBUG
+        fprintf(stderr, "Handshake hashes:\n");
+        BIO_dump_fp(stderr, (char *)hash, hashlen);
+#endif
+        tls1_PRF(s,
+                 TLS_MD_EXTENDED_MASTER_SECRET_CONST,
+                 TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE,
+                 hash, hashlen,
+                 NULL, 0,
+                 NULL, 0,
+                 NULL, 0, p, len, s->session->master_key,
+                 SSL3_MASTER_SECRET_SIZE);
+        OPENSSL_cleanse(hash, hashlen);
+    } else {
+        tls1_PRF(s,
+                 TLS_MD_MASTER_SECRET_CONST,
+                 TLS_MD_MASTER_SECRET_CONST_SIZE,
+                 s->s3->client_random, SSL3_RANDOM_SIZE,
+                 NULL, 0,
+                 s->s3->server_random, SSL3_RANDOM_SIZE,
+                 NULL, 0, p, len, s->session->master_key,
+                 SSL3_MASTER_SECRET_SIZE);
+    }
+#ifdef SSL_DEBUG
+    fprintf(stderr, "Premaster Secret:\n");
+    BIO_dump_fp(stderr, (char *)p, len);
+    fprintf(stderr, "Client Random:\n");
+    BIO_dump_fp(stderr, (char *)s->s3->client_random, SSL3_RANDOM_SIZE);
+    fprintf(stderr, "Server Random:\n");
+    BIO_dump_fp(stderr, (char *)s->s3->server_random, SSL3_RANDOM_SIZE);
+    fprintf(stderr, "Master Secret:\n");
+    BIO_dump_fp(stderr, (char *)s->session->master_key,
+                SSL3_MASTER_SECRET_SIZE);
+#endif
+
+#ifdef OPENSSL_SSL_TRACE_CRYPTO
+    if (s->msg_callback) {
+        s->msg_callback(2, s->version, TLS1_RT_CRYPTO_PREMASTER,
+                        p, len, s, s->msg_callback_arg);
+        s->msg_callback(2, s->version, TLS1_RT_CRYPTO_CLIENT_RANDOM,
+                        s->s3->client_random, SSL3_RANDOM_SIZE,
+                        s, s->msg_callback_arg);
+        s->msg_callback(2, s->version, TLS1_RT_CRYPTO_SERVER_RANDOM,
+                        s->s3->server_random, SSL3_RANDOM_SIZE,
+                        s, s->msg_callback_arg);
+        s->msg_callback(2, s->version, TLS1_RT_CRYPTO_MASTER,
+                        s->session->master_key,
+                        SSL3_MASTER_SECRET_SIZE, s, s->msg_callback_arg);
+    }
+#endif
+
+    return (SSL3_MASTER_SECRET_SIZE);
+}
+
+int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
+                                const char *label, size_t llen,
+                                const unsigned char *context,
+                                size_t contextlen, int use_context)
+{
+    unsigned char *val = NULL;
+    size_t vallen = 0, currentvalpos;
+    int rv;
+
+    /*
+     * construct PRF arguments we construct the PRF argument ourself rather
+     * than passing separate values into the TLS PRF to ensure that the
+     * concatenation of values does not create a prohibited label.
+     */
+    vallen = llen + SSL3_RANDOM_SIZE * 2;
+    if (use_context) {
+        vallen += 2 + contextlen;
+    }
+
+    val = OPENSSL_malloc(vallen);
+    if (val == NULL)
+        goto err2;
+    currentvalpos = 0;
+    memcpy(val + currentvalpos, (unsigned char *)label, llen);
+    currentvalpos += llen;
+    memcpy(val + currentvalpos, s->s3->client_random, SSL3_RANDOM_SIZE);
+    currentvalpos += SSL3_RANDOM_SIZE;
+    memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE);
+    currentvalpos += SSL3_RANDOM_SIZE;
+
+    if (use_context) {
+        val[currentvalpos] = (contextlen >> 8) & 0xff;
+        currentvalpos++;
+        val[currentvalpos] = contextlen & 0xff;
+        currentvalpos++;
+        if ((contextlen > 0) || (context != NULL)) {
+            memcpy(val + currentvalpos, context, contextlen);
+        }
+    }
+
+    /*
+     * disallow prohibited labels note that SSL3_RANDOM_SIZE > max(prohibited
+     * label len) = 15, so size of val > max(prohibited label len) = 15 and
+     * the comparisons won't have buffer overflow
+     */
+    if (memcmp(val, TLS_MD_CLIENT_FINISH_CONST,
+               TLS_MD_CLIENT_FINISH_CONST_SIZE) == 0)
+        goto err1;
+    if (memcmp(val, TLS_MD_SERVER_FINISH_CONST,
+               TLS_MD_SERVER_FINISH_CONST_SIZE) == 0)
+        goto err1;
+    if (memcmp(val, TLS_MD_MASTER_SECRET_CONST,
+               TLS_MD_MASTER_SECRET_CONST_SIZE) == 0)
+        goto err1;
+    if (memcmp(val, TLS_MD_EXTENDED_MASTER_SECRET_CONST,
+               TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE) == 0)
+        goto err1;
+    if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST,
+               TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0)
+        goto err1;
+
+    rv = tls1_PRF(s,
+                  val, vallen,
+                  NULL, 0,
+                  NULL, 0,
+                  NULL, 0,
+                  NULL, 0,
+                  s->session->master_key, s->session->master_key_length,
+                  out, olen);
+
+    goto ret;
+ err1:
+    SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL);
+    rv = 0;
+    goto ret;
+ err2:
+    SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, ERR_R_MALLOC_FAILURE);
+    rv = 0;
+ ret:
+    OPENSSL_clear_free(val, vallen);
+    return (rv);
+}
+
+int tls1_alert_code(int code)
+{
+    switch (code) {
+    case SSL_AD_CLOSE_NOTIFY:
+        return (SSL3_AD_CLOSE_NOTIFY);
+    case SSL_AD_UNEXPECTED_MESSAGE:
+        return (SSL3_AD_UNEXPECTED_MESSAGE);
+    case SSL_AD_BAD_RECORD_MAC:
+        return (SSL3_AD_BAD_RECORD_MAC);
+    case SSL_AD_DECRYPTION_FAILED:
+        return (TLS1_AD_DECRYPTION_FAILED);
+    case SSL_AD_RECORD_OVERFLOW:
+        return (TLS1_AD_RECORD_OVERFLOW);
+    case SSL_AD_DECOMPRESSION_FAILURE:
+        return (SSL3_AD_DECOMPRESSION_FAILURE);
+    case SSL_AD_HANDSHAKE_FAILURE:
+        return (SSL3_AD_HANDSHAKE_FAILURE);
+    case SSL_AD_NO_CERTIFICATE:
+        return (-1);
+    case SSL_AD_BAD_CERTIFICATE:
+        return (SSL3_AD_BAD_CERTIFICATE);
+    case SSL_AD_UNSUPPORTED_CERTIFICATE:
+        return (SSL3_AD_UNSUPPORTED_CERTIFICATE);
+    case SSL_AD_CERTIFICATE_REVOKED:
+        return (SSL3_AD_CERTIFICATE_REVOKED);
+    case SSL_AD_CERTIFICATE_EXPIRED:
+        return (SSL3_AD_CERTIFICATE_EXPIRED);
+    case SSL_AD_CERTIFICATE_UNKNOWN:
+        return (SSL3_AD_CERTIFICATE_UNKNOWN);
+    case SSL_AD_ILLEGAL_PARAMETER:
+        return (SSL3_AD_ILLEGAL_PARAMETER);
+    case SSL_AD_UNKNOWN_CA:
+        return (TLS1_AD_UNKNOWN_CA);
+    case SSL_AD_ACCESS_DENIED:
+        return (TLS1_AD_ACCESS_DENIED);
+    case SSL_AD_DECODE_ERROR:
+        return (TLS1_AD_DECODE_ERROR);
+    case SSL_AD_DECRYPT_ERROR:
+        return (TLS1_AD_DECRYPT_ERROR);
+    case SSL_AD_EXPORT_RESTRICTION:
+        return (TLS1_AD_EXPORT_RESTRICTION);
+    case SSL_AD_PROTOCOL_VERSION:
+        return (TLS1_AD_PROTOCOL_VERSION);
+    case SSL_AD_INSUFFICIENT_SECURITY:
+        return (TLS1_AD_INSUFFICIENT_SECURITY);
+    case SSL_AD_INTERNAL_ERROR:
+        return (TLS1_AD_INTERNAL_ERROR);
+    case SSL_AD_USER_CANCELLED:
+        return (TLS1_AD_USER_CANCELLED);
+    case SSL_AD_NO_RENEGOTIATION:
+        return (TLS1_AD_NO_RENEGOTIATION);
+    case SSL_AD_UNSUPPORTED_EXTENSION:
+        return (TLS1_AD_UNSUPPORTED_EXTENSION);
+    case SSL_AD_CERTIFICATE_UNOBTAINABLE:
+        return (TLS1_AD_CERTIFICATE_UNOBTAINABLE);
+    case SSL_AD_UNRECOGNIZED_NAME:
+        return (TLS1_AD_UNRECOGNIZED_NAME);
+    case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
+        return (TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE);
+    case SSL_AD_BAD_CERTIFICATE_HASH_VALUE:
+        return (TLS1_AD_BAD_CERTIFICATE_HASH_VALUE);
+    case SSL_AD_UNKNOWN_PSK_IDENTITY:
+        return (TLS1_AD_UNKNOWN_PSK_IDENTITY);
+    case SSL_AD_INAPPROPRIATE_FALLBACK:
+        return (TLS1_AD_INAPPROPRIATE_FALLBACK);
+    case SSL_AD_NO_APPLICATION_PROTOCOL:
+        return (TLS1_AD_NO_APPLICATION_PROTOCOL);
+    default:
+        return (-1);
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/t1_ext.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/t1_ext.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/t1_ext.c	(revision 331)
@@ -0,0 +1,264 @@
+/*
+ * Copyright 2014-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
+ */
+
+/* Custom extension utility functions */
+
+#include <openssl/ct.h>
+#include "ssl_locl.h"
+
+/* Find a custom extension from the list. */
+static custom_ext_method *custom_ext_find(const custom_ext_methods *exts,
+                                          unsigned int ext_type)
+{
+    size_t i;
+    custom_ext_method *meth = exts->meths;
+    for (i = 0; i < exts->meths_count; i++, meth++) {
+        if (ext_type == meth->ext_type)
+            return meth;
+    }
+    return NULL;
+}
+
+/*
+ * Initialise custom extensions flags to indicate neither sent nor received.
+ */
+void custom_ext_init(custom_ext_methods *exts)
+{
+    size_t i;
+    custom_ext_method *meth = exts->meths;
+    for (i = 0; i < exts->meths_count; i++, meth++)
+        meth->ext_flags = 0;
+}
+
+/* Pass received custom extension data to the application for parsing. */
+int custom_ext_parse(SSL *s, int server,
+                     unsigned int ext_type,
+                     const unsigned char *ext_data, size_t ext_size, int *al)
+{
+    custom_ext_methods *exts = server ? &s->cert->srv_ext : &s->cert->cli_ext;
+    custom_ext_method *meth;
+    meth = custom_ext_find(exts, ext_type);
+    /* If not found return success */
+    if (!meth)
+        return 1;
+    if (!server) {
+        /*
+         * If it's ServerHello we can't have any extensions not sent in
+         * ClientHello.
+         */
+        if (!(meth->ext_flags & SSL_EXT_FLAG_SENT)) {
+            *al = TLS1_AD_UNSUPPORTED_EXTENSION;
+            return 0;
+        }
+    }
+    /* If already present it's a duplicate */
+    if (meth->ext_flags & SSL_EXT_FLAG_RECEIVED) {
+        *al = TLS1_AD_DECODE_ERROR;
+        return 0;
+    }
+    meth->ext_flags |= SSL_EXT_FLAG_RECEIVED;
+    /* If no parse function set return success */
+    if (!meth->parse_cb)
+        return 1;
+
+    return meth->parse_cb(s, ext_type, ext_data, ext_size, al, meth->parse_arg);
+}
+
+/*
+ * Request custom extension data from the application and add to the return
+ * buffer.
+ */
+int custom_ext_add(SSL *s, int server,
+                   unsigned char **pret, unsigned char *limit, int *al)
+{
+    custom_ext_methods *exts = server ? &s->cert->srv_ext : &s->cert->cli_ext;
+    custom_ext_method *meth;
+    unsigned char *ret = *pret;
+    size_t i;
+
+    for (i = 0; i < exts->meths_count; i++) {
+        const unsigned char *out = NULL;
+        size_t outlen = 0;
+        meth = exts->meths + i;
+
+        if (server) {
+            /*
+             * For ServerHello only send extensions present in ClientHello.
+             */
+            if (!(meth->ext_flags & SSL_EXT_FLAG_RECEIVED))
+                continue;
+            /* If callback absent for server skip it */
+            if (!meth->add_cb)
+                continue;
+        }
+        if (meth->add_cb) {
+            int cb_retval = 0;
+            cb_retval = meth->add_cb(s, meth->ext_type,
+                                     &out, &outlen, al, meth->add_arg);
+            if (cb_retval < 0)
+                return 0;       /* error */
+            if (cb_retval == 0)
+                continue;       /* skip this extension */
+        }
+        if (4 > limit - ret || outlen > (size_t)(limit - ret - 4))
+            return 0;
+        s2n(meth->ext_type, ret);
+        s2n(outlen, ret);
+        if (outlen) {
+            memcpy(ret, out, outlen);
+            ret += outlen;
+        }
+        /*
+         * We can't send duplicates: code logic should prevent this.
+         */
+        OPENSSL_assert(!(meth->ext_flags & SSL_EXT_FLAG_SENT));
+        /*
+         * Indicate extension has been sent: this is both a sanity check to
+         * ensure we don't send duplicate extensions and indicates that it is
+         * not an error if the extension is present in ServerHello.
+         */
+        meth->ext_flags |= SSL_EXT_FLAG_SENT;
+        if (meth->free_cb)
+            meth->free_cb(s, meth->ext_type, out, meth->add_arg);
+    }
+    *pret = ret;
+    return 1;
+}
+
+/* Copy table of custom extensions */
+int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src)
+{
+    if (src->meths_count) {
+        dst->meths =
+            OPENSSL_memdup(src->meths,
+                           sizeof(custom_ext_method) * src->meths_count);
+        if (dst->meths == NULL)
+            return 0;
+        dst->meths_count = src->meths_count;
+    }
+    return 1;
+}
+
+void custom_exts_free(custom_ext_methods *exts)
+{
+    OPENSSL_free(exts->meths);
+}
+
+/* Set callbacks for a custom extension. */
+static int custom_ext_meth_add(custom_ext_methods *exts,
+                               unsigned int ext_type,
+                               custom_ext_add_cb add_cb,
+                               custom_ext_free_cb free_cb,
+                               void *add_arg,
+                               custom_ext_parse_cb parse_cb, void *parse_arg)
+{
+    custom_ext_method *meth, *tmp;
+    /*
+     * Check application error: if add_cb is not set free_cb will never be
+     * called.
+     */
+    if (!add_cb && free_cb)
+        return 0;
+    /*
+     * Don't add if extension supported internally, but make exception
+     * for extension types that previously were not supported, but now are.
+     */
+    if (SSL_extension_supported(ext_type) &&
+        ext_type != TLSEXT_TYPE_signed_certificate_timestamp)
+        return 0;
+    /* Extension type must fit in 16 bits */
+    if (ext_type > 0xffff)
+        return 0;
+    /* Search for duplicate */
+    if (custom_ext_find(exts, ext_type))
+        return 0;
+    tmp = OPENSSL_realloc(exts->meths,
+                          (exts->meths_count + 1) * sizeof(custom_ext_method));
+
+    if (tmp == NULL)
+        return 0;
+
+    exts->meths = tmp;
+    meth = exts->meths + exts->meths_count;
+    memset(meth, 0, sizeof(*meth));
+    meth->parse_cb = parse_cb;
+    meth->add_cb = add_cb;
+    meth->free_cb = free_cb;
+    meth->ext_type = ext_type;
+    meth->add_arg = add_arg;
+    meth->parse_arg = parse_arg;
+    exts->meths_count++;
+    return 1;
+}
+
+/* Return true if a client custom extension exists, false otherwise */
+int SSL_CTX_has_client_custom_ext(const SSL_CTX *ctx, unsigned int ext_type)
+{
+    return custom_ext_find(&ctx->cert->cli_ext, ext_type) != NULL;
+}
+
+/* Application level functions to add custom extension callbacks */
+int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, unsigned int ext_type,
+                                  custom_ext_add_cb add_cb,
+                                  custom_ext_free_cb free_cb,
+                                  void *add_arg,
+                                  custom_ext_parse_cb parse_cb, void *parse_arg)
+{
+#ifndef OPENSSL_NO_CT
+    /*
+     * We don't want applications registering callbacks for SCT extensions
+     * whilst simultaneously using the built-in SCT validation features, as
+     * these two things may not play well together.
+     */
+    if (ext_type == TLSEXT_TYPE_signed_certificate_timestamp &&
+        SSL_CTX_ct_is_enabled(ctx))
+        return 0;
+#endif
+    return custom_ext_meth_add(&ctx->cert->cli_ext, ext_type, add_cb,
+                               free_cb, add_arg, parse_cb, parse_arg);
+}
+
+int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, unsigned int ext_type,
+                                  custom_ext_add_cb add_cb,
+                                  custom_ext_free_cb free_cb,
+                                  void *add_arg,
+                                  custom_ext_parse_cb parse_cb, void *parse_arg)
+{
+    return custom_ext_meth_add(&ctx->cert->srv_ext, ext_type,
+                               add_cb, free_cb, add_arg, parse_cb, parse_arg);
+}
+
+int SSL_extension_supported(unsigned int ext_type)
+{
+    switch (ext_type) {
+        /* Internally supported extensions. */
+    case TLSEXT_TYPE_application_layer_protocol_negotiation:
+    case TLSEXT_TYPE_ec_point_formats:
+    case TLSEXT_TYPE_elliptic_curves:
+    case TLSEXT_TYPE_heartbeat:
+#ifndef OPENSSL_NO_NEXTPROTONEG
+    case TLSEXT_TYPE_next_proto_neg:
+#endif
+    case TLSEXT_TYPE_padding:
+    case TLSEXT_TYPE_renegotiate:
+    case TLSEXT_TYPE_server_name:
+    case TLSEXT_TYPE_session_ticket:
+    case TLSEXT_TYPE_signature_algorithms:
+    case TLSEXT_TYPE_srp:
+    case TLSEXT_TYPE_status_request:
+    case TLSEXT_TYPE_signed_certificate_timestamp:
+    case TLSEXT_TYPE_use_srtp:
+#ifdef TLSEXT_TYPE_encrypt_then_mac
+    case TLSEXT_TYPE_encrypt_then_mac:
+#endif
+        return 1;
+    default:
+        return 0;
+    }
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/t1_lib.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/t1_lib.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/t1_lib.c	(revision 331)
@@ -0,0 +1,4188 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <stdlib.h>
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/ocsp.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+#include <openssl/dh.h>
+#include <openssl/bn.h>
+#include "ssl_locl.h"
+#include <openssl/ct.h>
+
+
+#define CHECKLEN(curr, val, limit) \
+    (((curr) >= (limit)) || (size_t)((limit) - (curr)) < (size_t)(val))
+
+static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen,
+                              const unsigned char *sess_id, int sesslen,
+                              SSL_SESSION **psess);
+static int ssl_check_clienthello_tlsext_early(SSL *s);
+static int ssl_check_serverhello_tlsext(SSL *s);
+
+SSL3_ENC_METHOD const TLSv1_enc_data = {
+    tls1_enc,
+    tls1_mac,
+    tls1_setup_key_block,
+    tls1_generate_master_secret,
+    tls1_change_cipher_state,
+    tls1_final_finish_mac,
+    TLS1_FINISH_MAC_LENGTH,
+    TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
+    TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
+    tls1_alert_code,
+    tls1_export_keying_material,
+    0,
+    SSL3_HM_HEADER_LENGTH,
+    ssl3_set_handshake_header,
+    ssl3_handshake_write
+};
+
+SSL3_ENC_METHOD const TLSv1_1_enc_data = {
+    tls1_enc,
+    tls1_mac,
+    tls1_setup_key_block,
+    tls1_generate_master_secret,
+    tls1_change_cipher_state,
+    tls1_final_finish_mac,
+    TLS1_FINISH_MAC_LENGTH,
+    TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
+    TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
+    tls1_alert_code,
+    tls1_export_keying_material,
+    SSL_ENC_FLAG_EXPLICIT_IV,
+    SSL3_HM_HEADER_LENGTH,
+    ssl3_set_handshake_header,
+    ssl3_handshake_write
+};
+
+SSL3_ENC_METHOD const TLSv1_2_enc_data = {
+    tls1_enc,
+    tls1_mac,
+    tls1_setup_key_block,
+    tls1_generate_master_secret,
+    tls1_change_cipher_state,
+    tls1_final_finish_mac,
+    TLS1_FINISH_MAC_LENGTH,
+    TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
+    TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
+    tls1_alert_code,
+    tls1_export_keying_material,
+    SSL_ENC_FLAG_EXPLICIT_IV | SSL_ENC_FLAG_SIGALGS | SSL_ENC_FLAG_SHA256_PRF
+        | SSL_ENC_FLAG_TLS1_2_CIPHERS,
+    SSL3_HM_HEADER_LENGTH,
+    ssl3_set_handshake_header,
+    ssl3_handshake_write
+};
+
+long tls1_default_timeout(void)
+{
+    /*
+     * 2 hours, the 24 hours mentioned in the TLSv1 spec is way too long for
+     * http, the cache would over fill
+     */
+    return (60 * 60 * 2);
+}
+
+int tls1_new(SSL *s)
+{
+    if (!ssl3_new(s))
+        return (0);
+    s->method->ssl_clear(s);
+    return (1);
+}
+
+void tls1_free(SSL *s)
+{
+    OPENSSL_free(s->tlsext_session_ticket);
+    ssl3_free(s);
+}
+
+void tls1_clear(SSL *s)
+{
+    ssl3_clear(s);
+    if (s->method->version == TLS_ANY_VERSION)
+        s->version = TLS_MAX_VERSION;
+    else
+        s->version = s->method->version;
+}
+
+#ifndef OPENSSL_NO_EC
+
+typedef struct {
+    int nid;                    /* Curve NID */
+    int secbits;                /* Bits of security (from SP800-57) */
+    unsigned int flags;         /* Flags: currently just field type */
+} tls_curve_info;
+
+/*
+ * Table of curve information.
+ * Do not delete entries or reorder this array! It is used as a lookup
+ * table: the index of each entry is one less than the TLS curve id.
+ */
+static const tls_curve_info nid_list[] = {
+    {NID_sect163k1, 80, TLS_CURVE_CHAR2}, /* sect163k1 (1) */
+    {NID_sect163r1, 80, TLS_CURVE_CHAR2}, /* sect163r1 (2) */
+    {NID_sect163r2, 80, TLS_CURVE_CHAR2}, /* sect163r2 (3) */
+    {NID_sect193r1, 80, TLS_CURVE_CHAR2}, /* sect193r1 (4) */
+    {NID_sect193r2, 80, TLS_CURVE_CHAR2}, /* sect193r2 (5) */
+    {NID_sect233k1, 112, TLS_CURVE_CHAR2}, /* sect233k1 (6) */
+    {NID_sect233r1, 112, TLS_CURVE_CHAR2}, /* sect233r1 (7) */
+    {NID_sect239k1, 112, TLS_CURVE_CHAR2}, /* sect239k1 (8) */
+    {NID_sect283k1, 128, TLS_CURVE_CHAR2}, /* sect283k1 (9) */
+    {NID_sect283r1, 128, TLS_CURVE_CHAR2}, /* sect283r1 (10) */
+    {NID_sect409k1, 192, TLS_CURVE_CHAR2}, /* sect409k1 (11) */
+    {NID_sect409r1, 192, TLS_CURVE_CHAR2}, /* sect409r1 (12) */
+    {NID_sect571k1, 256, TLS_CURVE_CHAR2}, /* sect571k1 (13) */
+    {NID_sect571r1, 256, TLS_CURVE_CHAR2}, /* sect571r1 (14) */
+    {NID_secp160k1, 80, TLS_CURVE_PRIME}, /* secp160k1 (15) */
+    {NID_secp160r1, 80, TLS_CURVE_PRIME}, /* secp160r1 (16) */
+    {NID_secp160r2, 80, TLS_CURVE_PRIME}, /* secp160r2 (17) */
+    {NID_secp192k1, 80, TLS_CURVE_PRIME}, /* secp192k1 (18) */
+    {NID_X9_62_prime192v1, 80, TLS_CURVE_PRIME}, /* secp192r1 (19) */
+    {NID_secp224k1, 112, TLS_CURVE_PRIME}, /* secp224k1 (20) */
+    {NID_secp224r1, 112, TLS_CURVE_PRIME}, /* secp224r1 (21) */
+    {NID_secp256k1, 128, TLS_CURVE_PRIME}, /* secp256k1 (22) */
+    {NID_X9_62_prime256v1, 128, TLS_CURVE_PRIME}, /* secp256r1 (23) */
+    {NID_secp384r1, 192, TLS_CURVE_PRIME}, /* secp384r1 (24) */
+    {NID_secp521r1, 256, TLS_CURVE_PRIME}, /* secp521r1 (25) */
+    {NID_brainpoolP256r1, 128, TLS_CURVE_PRIME}, /* brainpoolP256r1 (26) */
+    {NID_brainpoolP384r1, 192, TLS_CURVE_PRIME}, /* brainpoolP384r1 (27) */
+    {NID_brainpoolP512r1, 256, TLS_CURVE_PRIME}, /* brainpool512r1 (28) */
+    {NID_X25519, 128, TLS_CURVE_CUSTOM}, /* X25519 (29) */
+};
+
+static const unsigned char ecformats_default[] = {
+    TLSEXT_ECPOINTFORMAT_uncompressed,
+    TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime,
+    TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2
+};
+
+/* The default curves */
+static const unsigned char eccurves_default[] = {
+    0, 29,                      /* X25519 (29) */
+    0, 23,                      /* secp256r1 (23) */
+    0, 25,                      /* secp521r1 (25) */
+    0, 24,                      /* secp384r1 (24) */
+};
+
+static const unsigned char suiteb_curves[] = {
+    0, TLSEXT_curve_P_256,
+    0, TLSEXT_curve_P_384
+};
+
+int tls1_ec_curve_id2nid(int curve_id, unsigned int *pflags)
+{
+    const tls_curve_info *cinfo;
+    /* ECC curves from RFC 4492 and RFC 7027 */
+    if ((curve_id < 1) || ((unsigned int)curve_id > OSSL_NELEM(nid_list)))
+        return 0;
+    cinfo = nid_list + curve_id - 1;
+    if (pflags)
+        *pflags = cinfo->flags;
+    return cinfo->nid;
+}
+
+int tls1_ec_nid2curve_id(int nid)
+{
+    size_t i;
+    for (i = 0; i < OSSL_NELEM(nid_list); i++) {
+        if (nid_list[i].nid == nid)
+            return i + 1;
+    }
+    return 0;
+}
+
+/*
+ * Get curves list, if "sess" is set return client curves otherwise
+ * preferred list.
+ * Sets |num_curves| to the number of curves in the list, i.e.,
+ * the length of |pcurves| is 2 * num_curves.
+ * Returns 1 on success and 0 if the client curves list has invalid format.
+ * The latter indicates an internal error: we should not be accepting such
+ * lists in the first place.
+ * TODO(emilia): we should really be storing the curves list in explicitly
+ * parsed form instead. (However, this would affect binary compatibility
+ * so cannot happen in the 1.0.x series.)
+ */
+static int tls1_get_curvelist(SSL *s, int sess,
+                              const unsigned char **pcurves, size_t *num_curves)
+{
+    size_t pcurveslen = 0;
+
+    if (sess) {
+        *pcurves = s->session->tlsext_ellipticcurvelist;
+        pcurveslen = s->session->tlsext_ellipticcurvelist_length;
+    } else {
+        /* For Suite B mode only include P-256, P-384 */
+        switch (tls1_suiteb(s)) {
+        case SSL_CERT_FLAG_SUITEB_128_LOS:
+            *pcurves = suiteb_curves;
+            pcurveslen = sizeof(suiteb_curves);
+            break;
+
+        case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY:
+            *pcurves = suiteb_curves;
+            pcurveslen = 2;
+            break;
+
+        case SSL_CERT_FLAG_SUITEB_192_LOS:
+            *pcurves = suiteb_curves + 2;
+            pcurveslen = 2;
+            break;
+        default:
+            *pcurves = s->tlsext_ellipticcurvelist;
+            pcurveslen = s->tlsext_ellipticcurvelist_length;
+        }
+        if (!*pcurves) {
+            *pcurves = eccurves_default;
+            pcurveslen = sizeof(eccurves_default);
+        }
+    }
+
+    /* We do not allow odd length arrays to enter the system. */
+    if (pcurveslen & 1) {
+        SSLerr(SSL_F_TLS1_GET_CURVELIST, ERR_R_INTERNAL_ERROR);
+        *num_curves = 0;
+        return 0;
+    }
+    *num_curves = pcurveslen / 2;
+    return 1;
+}
+
+/* See if curve is allowed by security callback */
+static int tls_curve_allowed(SSL *s, const unsigned char *curve, int op)
+{
+    const tls_curve_info *cinfo;
+    if (curve[0])
+        return 1;
+    if ((curve[1] < 1) || ((size_t)curve[1] > OSSL_NELEM(nid_list)))
+        return 0;
+    cinfo = &nid_list[curve[1] - 1];
+# ifdef OPENSSL_NO_EC2M
+    if (cinfo->flags & TLS_CURVE_CHAR2)
+        return 0;
+# endif
+    return ssl_security(s, op, cinfo->secbits, cinfo->nid, (void *)curve);
+}
+
+/* Check a curve is one of our preferences */
+int tls1_check_curve(SSL *s, const unsigned char *p, size_t len)
+{
+    const unsigned char *curves;
+    size_t num_curves, i;
+    unsigned int suiteb_flags = tls1_suiteb(s);
+    if (len != 3 || p[0] != NAMED_CURVE_TYPE)
+        return 0;
+    /* Check curve matches Suite B preferences */
+    if (suiteb_flags) {
+        unsigned long cid = s->s3->tmp.new_cipher->id;
+        if (p[1])
+            return 0;
+        if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) {
+            if (p[2] != TLSEXT_curve_P_256)
+                return 0;
+        } else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) {
+            if (p[2] != TLSEXT_curve_P_384)
+                return 0;
+        } else                  /* Should never happen */
+            return 0;
+    }
+    if (!tls1_get_curvelist(s, 0, &curves, &num_curves))
+        return 0;
+    for (i = 0; i < num_curves; i++, curves += 2) {
+        if (p[1] == curves[0] && p[2] == curves[1])
+            return tls_curve_allowed(s, p + 1, SSL_SECOP_CURVE_CHECK);
+    }
+    return 0;
+}
+
+/*-
+ * For nmatch >= 0, return the NID of the |nmatch|th shared curve or NID_undef
+ * if there is no match.
+ * For nmatch == -1, return number of matches
+ * For nmatch == -2, return the NID of the curve to use for
+ * an EC tmp key, or NID_undef if there is no match.
+ */
+int tls1_shared_curve(SSL *s, int nmatch)
+{
+    const unsigned char *pref, *supp;
+    size_t num_pref, num_supp, i, j;
+    int k;
+
+    /* Can't do anything on client side */
+    if (s->server == 0)
+        return -1;
+    if (nmatch == -2) {
+        if (tls1_suiteb(s)) {
+            /*
+             * For Suite B ciphersuite determines curve: we already know
+             * these are acceptable due to previous checks.
+             */
+            unsigned long cid = s->s3->tmp.new_cipher->id;
+
+            if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
+                return NID_X9_62_prime256v1; /* P-256 */
+            if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
+                return NID_secp384r1; /* P-384 */
+            /* Should never happen */
+            return NID_undef;
+        }
+        /* If not Suite B just return first preference shared curve */
+        nmatch = 0;
+    }
+    /*
+     * Avoid truncation. tls1_get_curvelist takes an int
+     * but s->options is a long...
+     */
+    if (!tls1_get_curvelist(s,
+            (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0,
+            &supp, &num_supp))
+        /* In practice, NID_undef == 0 but let's be precise. */
+        return nmatch == -1 ? 0 : NID_undef;
+    if (!tls1_get_curvelist(s,
+            (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) == 0,
+            &pref, &num_pref))
+        return nmatch == -1 ? 0 : NID_undef;
+
+    for (k = 0, i = 0; i < num_pref; i++, pref += 2) {
+        const unsigned char *tsupp = supp;
+
+        for (j = 0; j < num_supp; j++, tsupp += 2) {
+            if (pref[0] == tsupp[0] && pref[1] == tsupp[1]) {
+                if (!tls_curve_allowed(s, pref, SSL_SECOP_CURVE_SHARED))
+                    continue;
+                if (nmatch == k) {
+                    int id = (pref[0] << 8) | pref[1];
+
+                    return tls1_ec_curve_id2nid(id, NULL);
+                }
+                k++;
+            }
+        }
+    }
+    if (nmatch == -1)
+        return k;
+    /* Out of range (nmatch > k). */
+    return NID_undef;
+}
+
+int tls1_set_curves(unsigned char **pext, size_t *pextlen,
+                    int *curves, size_t ncurves)
+{
+    unsigned char *clist, *p;
+    size_t i;
+    /*
+     * Bitmap of curves included to detect duplicates: only works while curve
+     * ids < 32
+     */
+    unsigned long dup_list = 0;
+    clist = OPENSSL_malloc(ncurves * 2);
+    if (clist == NULL)
+        return 0;
+    for (i = 0, p = clist; i < ncurves; i++) {
+        unsigned long idmask;
+        int id;
+        id = tls1_ec_nid2curve_id(curves[i]);
+        idmask = 1L << id;
+        if (!id || (dup_list & idmask)) {
+            OPENSSL_free(clist);
+            return 0;
+        }
+        dup_list |= idmask;
+        s2n(id, p);
+    }
+    OPENSSL_free(*pext);
+    *pext = clist;
+    *pextlen = ncurves * 2;
+    return 1;
+}
+
+# define MAX_CURVELIST   28
+
+typedef struct {
+    size_t nidcnt;
+    int nid_arr[MAX_CURVELIST];
+} nid_cb_st;
+
+static int nid_cb(const char *elem, int len, void *arg)
+{
+    nid_cb_st *narg = arg;
+    size_t i;
+    int nid;
+    char etmp[20];
+    if (elem == NULL)
+        return 0;
+    if (narg->nidcnt == MAX_CURVELIST)
+        return 0;
+    if (len > (int)(sizeof(etmp) - 1))
+        return 0;
+    memcpy(etmp, elem, len);
+    etmp[len] = 0;
+    nid = EC_curve_nist2nid(etmp);
+    if (nid == NID_undef)
+        nid = OBJ_sn2nid(etmp);
+    if (nid == NID_undef)
+        nid = OBJ_ln2nid(etmp);
+    if (nid == NID_undef)
+        return 0;
+    for (i = 0; i < narg->nidcnt; i++)
+        if (narg->nid_arr[i] == nid)
+            return 0;
+    narg->nid_arr[narg->nidcnt++] = nid;
+    return 1;
+}
+
+/* Set curves based on a colon separate list */
+int tls1_set_curves_list(unsigned char **pext, size_t *pextlen, const char *str)
+{
+    nid_cb_st ncb;
+    ncb.nidcnt = 0;
+    if (!CONF_parse_list(str, ':', 1, nid_cb, &ncb))
+        return 0;
+    if (pext == NULL)
+        return 1;
+    return tls1_set_curves(pext, pextlen, ncb.nid_arr, ncb.nidcnt);
+}
+
+/* For an EC key set TLS id and required compression based on parameters */
+static int tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id,
+                          EC_KEY *ec)
+{
+    int id;
+    const EC_GROUP *grp;
+    if (!ec)
+        return 0;
+    /* Determine if it is a prime field */
+    grp = EC_KEY_get0_group(ec);
+    if (!grp)
+        return 0;
+    /* Determine curve ID */
+    id = EC_GROUP_get_curve_name(grp);
+    id = tls1_ec_nid2curve_id(id);
+    /* If no id return error: we don't support arbitrary explicit curves */
+    if (id == 0)
+        return 0;
+    curve_id[0] = 0;
+    curve_id[1] = (unsigned char)id;
+    if (comp_id) {
+        if (EC_KEY_get0_public_key(ec) == NULL)
+            return 0;
+        if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_UNCOMPRESSED) {
+            *comp_id = TLSEXT_ECPOINTFORMAT_uncompressed;
+        } else {
+            if ((nid_list[id - 1].flags & TLS_CURVE_TYPE) == TLS_CURVE_PRIME)
+                *comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
+            else
+                *comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2;
+        }
+    }
+    return 1;
+}
+
+/* Check an EC key is compatible with extensions */
+static int tls1_check_ec_key(SSL *s,
+                             unsigned char *curve_id, unsigned char *comp_id)
+{
+    const unsigned char *pformats, *pcurves;
+    size_t num_formats, num_curves, i;
+    int j;
+    /*
+     * If point formats extension present check it, otherwise everything is
+     * supported (see RFC4492).
+     */
+    if (comp_id && s->session->tlsext_ecpointformatlist) {
+        pformats = s->session->tlsext_ecpointformatlist;
+        num_formats = s->session->tlsext_ecpointformatlist_length;
+        for (i = 0; i < num_formats; i++, pformats++) {
+            if (*comp_id == *pformats)
+                break;
+        }
+        if (i == num_formats)
+            return 0;
+    }
+    if (!curve_id)
+        return 1;
+    /* Check curve is consistent with client and server preferences */
+    for (j = 0; j <= 1; j++) {
+        if (!tls1_get_curvelist(s, j, &pcurves, &num_curves))
+            return 0;
+        if (j == 1 && num_curves == 0) {
+            /*
+             * If we've not received any curves then skip this check.
+             * RFC 4492 does not require the supported elliptic curves extension
+             * so if it is not sent we can just choose any curve.
+             * It is invalid to send an empty list in the elliptic curves
+             * extension, so num_curves == 0 always means no extension.
+             */
+            break;
+        }
+        for (i = 0; i < num_curves; i++, pcurves += 2) {
+            if (pcurves[0] == curve_id[0] && pcurves[1] == curve_id[1])
+                break;
+        }
+        if (i == num_curves)
+            return 0;
+        /* For clients can only check sent curve list */
+        if (!s->server)
+            break;
+    }
+    return 1;
+}
+
+static void tls1_get_formatlist(SSL *s, const unsigned char **pformats,
+                                size_t *num_formats)
+{
+    /*
+     * If we have a custom point format list use it otherwise use default
+     */
+    if (s->tlsext_ecpointformatlist) {
+        *pformats = s->tlsext_ecpointformatlist;
+        *num_formats = s->tlsext_ecpointformatlist_length;
+    } else {
+        *pformats = ecformats_default;
+        /* For Suite B we don't support char2 fields */
+        if (tls1_suiteb(s))
+            *num_formats = sizeof(ecformats_default) - 1;
+        else
+            *num_formats = sizeof(ecformats_default);
+    }
+}
+
+/*
+ * Check cert parameters compatible with extensions: currently just checks EC
+ * certificates have compatible curves and compression.
+ */
+static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
+{
+    unsigned char comp_id, curve_id[2];
+    EVP_PKEY *pkey;
+    int rv;
+    pkey = X509_get0_pubkey(x);
+    if (!pkey)
+        return 0;
+    /* If not EC nothing to do */
+    if (EVP_PKEY_id(pkey) != EVP_PKEY_EC)
+        return 1;
+    rv = tls1_set_ec_id(curve_id, &comp_id, EVP_PKEY_get0_EC_KEY(pkey));
+    if (!rv)
+        return 0;
+    /*
+     * Can't check curve_id for client certs as we don't have a supported
+     * curves extension.
+     */
+    rv = tls1_check_ec_key(s, s->server ? curve_id : NULL, &comp_id);
+    if (!rv)
+        return 0;
+    /*
+     * Special case for suite B. We *MUST* sign using SHA256+P-256 or
+     * SHA384+P-384, adjust digest if necessary.
+     */
+    if (set_ee_md && tls1_suiteb(s)) {
+        int check_md;
+        size_t i;
+        CERT *c = s->cert;
+        if (curve_id[0])
+            return 0;
+        /* Check to see we have necessary signing algorithm */
+        if (curve_id[1] == TLSEXT_curve_P_256)
+            check_md = NID_ecdsa_with_SHA256;
+        else if (curve_id[1] == TLSEXT_curve_P_384)
+            check_md = NID_ecdsa_with_SHA384;
+        else
+            return 0;           /* Should never happen */
+        for (i = 0; i < c->shared_sigalgslen; i++)
+            if (check_md == c->shared_sigalgs[i].signandhash_nid)
+                break;
+        if (i == c->shared_sigalgslen)
+            return 0;
+        if (set_ee_md == 2) {
+            if (check_md == NID_ecdsa_with_SHA256)
+                s->s3->tmp.md[SSL_PKEY_ECC] = EVP_sha256();
+            else
+                s->s3->tmp.md[SSL_PKEY_ECC] = EVP_sha384();
+        }
+    }
+    return rv;
+}
+
+# ifndef OPENSSL_NO_EC
+/*
+ * tls1_check_ec_tmp_key - Check EC temporary key compatibility
+ * @s: SSL connection
+ * @cid: Cipher ID we're considering using
+ *
+ * Checks that the kECDHE cipher suite we're considering using
+ * is compatible with the client extensions.
+ *
+ * Returns 0 when the cipher can't be used or 1 when it can.
+ */
+int tls1_check_ec_tmp_key(SSL *s, unsigned long cid)
+{
+    /*
+     * If Suite B, AES128 MUST use P-256 and AES256 MUST use P-384, no other
+     * curves permitted.
+     */
+    if (tls1_suiteb(s)) {
+        unsigned char curve_id[2];
+        /* Curve to check determined by ciphersuite */
+        if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
+            curve_id[1] = TLSEXT_curve_P_256;
+        else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384)
+            curve_id[1] = TLSEXT_curve_P_384;
+        else
+            return 0;
+        curve_id[0] = 0;
+        /* Check this curve is acceptable */
+        if (!tls1_check_ec_key(s, curve_id, NULL))
+            return 0;
+        return 1;
+    }
+    /* Need a shared curve */
+    if (tls1_shared_curve(s, 0))
+        return 1;
+    return 0;
+}
+# endif                         /* OPENSSL_NO_EC */
+
+#else
+
+static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md)
+{
+    return 1;
+}
+
+#endif                          /* OPENSSL_NO_EC */
+
+/*
+ * List of supported signature algorithms and hashes. Should make this
+ * customisable at some point, for now include everything we support.
+ */
+
+#ifdef OPENSSL_NO_RSA
+# define tlsext_sigalg_rsa(md)  /* */
+#else
+# define tlsext_sigalg_rsa(md) md, TLSEXT_signature_rsa,
+#endif
+
+#ifdef OPENSSL_NO_DSA
+# define tlsext_sigalg_dsa(md)  /* */
+#else
+# define tlsext_sigalg_dsa(md) md, TLSEXT_signature_dsa,
+#endif
+
+#ifdef OPENSSL_NO_EC
+# define tlsext_sigalg_ecdsa(md)/* */
+#else
+# define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa,
+#endif
+
+#define tlsext_sigalg(md) \
+                tlsext_sigalg_rsa(md) \
+                tlsext_sigalg_dsa(md) \
+                tlsext_sigalg_ecdsa(md)
+
+static const unsigned char tls12_sigalgs[] = {
+    tlsext_sigalg(TLSEXT_hash_sha512)
+        tlsext_sigalg(TLSEXT_hash_sha384)
+        tlsext_sigalg(TLSEXT_hash_sha256)
+        tlsext_sigalg(TLSEXT_hash_sha224)
+        tlsext_sigalg(TLSEXT_hash_sha1)
+#ifndef OPENSSL_NO_GOST
+        TLSEXT_hash_gostr3411, TLSEXT_signature_gostr34102001,
+    TLSEXT_hash_gostr34112012_256, TLSEXT_signature_gostr34102012_256,
+    TLSEXT_hash_gostr34112012_512, TLSEXT_signature_gostr34102012_512
+#endif
+};
+
+#ifndef OPENSSL_NO_EC
+static const unsigned char suiteb_sigalgs[] = {
+    tlsext_sigalg_ecdsa(TLSEXT_hash_sha256)
+        tlsext_sigalg_ecdsa(TLSEXT_hash_sha384)
+};
+#endif
+size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs)
+{
+    /*
+     * If Suite B mode use Suite B sigalgs only, ignore any other
+     * preferences.
+     */
+#ifndef OPENSSL_NO_EC
+    switch (tls1_suiteb(s)) {
+    case SSL_CERT_FLAG_SUITEB_128_LOS:
+        *psigs = suiteb_sigalgs;
+        return sizeof(suiteb_sigalgs);
+
+    case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY:
+        *psigs = suiteb_sigalgs;
+        return 2;
+
+    case SSL_CERT_FLAG_SUITEB_192_LOS:
+        *psigs = suiteb_sigalgs + 2;
+        return 2;
+    }
+#endif
+    /* If server use client authentication sigalgs if not NULL */
+    if (s->server == sent && s->cert->client_sigalgs) {
+        *psigs = s->cert->client_sigalgs;
+        return s->cert->client_sigalgslen;
+    } else if (s->cert->conf_sigalgs) {
+        *psigs = s->cert->conf_sigalgs;
+        return s->cert->conf_sigalgslen;
+    } else {
+        *psigs = tls12_sigalgs;
+        return sizeof(tls12_sigalgs);
+    }
+}
+
+/*
+ * Check signature algorithm is consistent with sent supported signature
+ * algorithms and if so return relevant digest.
+ */
+int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s,
+                            const unsigned char *sig, EVP_PKEY *pkey)
+{
+    const unsigned char *sent_sigs;
+    size_t sent_sigslen, i;
+    int sigalg = tls12_get_sigid(pkey);
+    /* Should never happen */
+    if (sigalg == -1)
+        return -1;
+    /* Check key type is consistent with signature */
+    if (sigalg != (int)sig[1]) {
+        SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
+        return 0;
+    }
+#ifndef OPENSSL_NO_EC
+    if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) {
+        unsigned char curve_id[2], comp_id;
+        /* Check compression and curve matches extensions */
+        if (!tls1_set_ec_id(curve_id, &comp_id, EVP_PKEY_get0_EC_KEY(pkey)))
+            return 0;
+        if (!s->server && !tls1_check_ec_key(s, curve_id, &comp_id)) {
+            SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE);
+            return 0;
+        }
+        /* If Suite B only P-384+SHA384 or P-256+SHA-256 allowed */
+        if (tls1_suiteb(s)) {
+            if (curve_id[0])
+                return 0;
+            if (curve_id[1] == TLSEXT_curve_P_256) {
+                if (sig[0] != TLSEXT_hash_sha256) {
+                    SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG,
+                           SSL_R_ILLEGAL_SUITEB_DIGEST);
+                    return 0;
+                }
+            } else if (curve_id[1] == TLSEXT_curve_P_384) {
+                if (sig[0] != TLSEXT_hash_sha384) {
+                    SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG,
+                           SSL_R_ILLEGAL_SUITEB_DIGEST);
+                    return 0;
+                }
+            } else
+                return 0;
+        }
+    } else if (tls1_suiteb(s))
+        return 0;
+#endif
+
+    /* Check signature matches a type we sent */
+    sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs);
+    for (i = 0; i < sent_sigslen; i += 2, sent_sigs += 2) {
+        if (sig[0] == sent_sigs[0] && sig[1] == sent_sigs[1])
+            break;
+    }
+    /* Allow fallback to SHA1 if not strict mode */
+    if (i == sent_sigslen
+        && (sig[0] != TLSEXT_hash_sha1
+            || s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) {
+        SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
+        return 0;
+    }
+    *pmd = tls12_get_hash(sig[0]);
+    if (*pmd == NULL) {
+        SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_UNKNOWN_DIGEST);
+        return 0;
+    }
+    /* Make sure security callback allows algorithm */
+    if (!ssl_security(s, SSL_SECOP_SIGALG_CHECK,
+                      EVP_MD_size(*pmd) * 4, EVP_MD_type(*pmd), (void *)sig)) {
+        SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE);
+        return 0;
+    }
+    /*
+     * Store the digest used so applications can retrieve it if they wish.
+     */
+    s->s3->tmp.peer_md = *pmd;
+    return 1;
+}
+
+/*
+ * Set a mask of disabled algorithms: an algorithm is disabled if it isn't
+ * supported, doesn't appear in supported signature algorithms, isn't supported
+ * by the enabled protocol versions or by the security level.
+ *
+ * This function should only be used for checking which ciphers are supported
+ * by the client.
+ *
+ * Call ssl_cipher_disabled() to check that it's enabled or not.
+ */
+void ssl_set_client_disabled(SSL *s)
+{
+    s->s3->tmp.mask_a = 0;
+    s->s3->tmp.mask_k = 0;
+    ssl_set_sig_mask(&s->s3->tmp.mask_a, s, SSL_SECOP_SIGALG_MASK);
+    ssl_get_client_min_max_version(s, &s->s3->tmp.min_ver, &s->s3->tmp.max_ver);
+#ifndef OPENSSL_NO_PSK
+    /* with PSK there must be client callback set */
+    if (!s->psk_client_callback) {
+        s->s3->tmp.mask_a |= SSL_aPSK;
+        s->s3->tmp.mask_k |= SSL_PSK;
+    }
+#endif                          /* OPENSSL_NO_PSK */
+#ifndef OPENSSL_NO_SRP
+    if (!(s->srp_ctx.srp_Mask & SSL_kSRP)) {
+        s->s3->tmp.mask_a |= SSL_aSRP;
+        s->s3->tmp.mask_k |= SSL_kSRP;
+    }
+#endif
+}
+
+/*
+ * ssl_cipher_disabled - check that a cipher is disabled or not
+ * @s: SSL connection that you want to use the cipher on
+ * @c: cipher to check
+ * @op: Security check that you want to do
+ *
+ * Returns 1 when it's disabled, 0 when enabled.
+ */
+int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op)
+{
+    if (c->algorithm_mkey & s->s3->tmp.mask_k
+        || c->algorithm_auth & s->s3->tmp.mask_a)
+        return 1;
+    if (s->s3->tmp.max_ver == 0)
+        return 1;
+    if (!SSL_IS_DTLS(s) && ((c->min_tls > s->s3->tmp.max_ver)
+                            || (c->max_tls < s->s3->tmp.min_ver)))
+        return 1;
+    if (SSL_IS_DTLS(s) && (DTLS_VERSION_GT(c->min_dtls, s->s3->tmp.max_ver)
+                           || DTLS_VERSION_LT(c->max_dtls, s->s3->tmp.min_ver)))
+        return 1;
+
+    return !ssl_security(s, op, c->strength_bits, 0, (void *)c);
+}
+
+static int tls_use_ticket(SSL *s)
+{
+    if (s->options & SSL_OP_NO_TICKET)
+        return 0;
+    return ssl_security(s, SSL_SECOP_TICKET, 0, 0, NULL);
+}
+
+static int compare_uint(const void *p1, const void *p2)
+{
+    unsigned int u1 = *((const unsigned int *)p1);
+    unsigned int u2 = *((const unsigned int *)p2);
+    if (u1 < u2)
+        return -1;
+    else if (u1 > u2)
+        return 1;
+    else
+        return 0;
+}
+
+/*
+ * Per http://tools.ietf.org/html/rfc5246#section-7.4.1.4, there may not be
+ * more than one extension of the same type in a ClientHello or ServerHello.
+ * This function does an initial scan over the extensions block to filter those
+ * out. It returns 1 if all extensions are unique, and 0 if the extensions
+ * contain duplicates, could not be successfully parsed, or an internal error
+ * occurred.
+ */
+static int tls1_check_duplicate_extensions(const PACKET *packet)
+{
+    PACKET extensions = *packet;
+    size_t num_extensions = 0, i = 0;
+    unsigned int *extension_types = NULL;
+    int ret = 0;
+
+    /* First pass: count the extensions. */
+    while (PACKET_remaining(&extensions) > 0) {
+        unsigned int type;
+        PACKET extension;
+        if (!PACKET_get_net_2(&extensions, &type) ||
+            !PACKET_get_length_prefixed_2(&extensions, &extension)) {
+            goto done;
+        }
+        num_extensions++;
+    }
+
+    if (num_extensions <= 1)
+        return 1;
+
+    extension_types = OPENSSL_malloc(sizeof(unsigned int) * num_extensions);
+    if (extension_types == NULL) {
+        SSLerr(SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS, ERR_R_MALLOC_FAILURE);
+        goto done;
+    }
+
+    /* Second pass: gather the extension types. */
+    extensions = *packet;
+    for (i = 0; i < num_extensions; i++) {
+        PACKET extension;
+        if (!PACKET_get_net_2(&extensions, &extension_types[i]) ||
+            !PACKET_get_length_prefixed_2(&extensions, &extension)) {
+            /* This should not happen. */
+            SSLerr(SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS, ERR_R_INTERNAL_ERROR);
+            goto done;
+        }
+    }
+
+    if (PACKET_remaining(&extensions) != 0) {
+        SSLerr(SSL_F_TLS1_CHECK_DUPLICATE_EXTENSIONS, ERR_R_INTERNAL_ERROR);
+        goto done;
+    }
+    /* Sort the extensions and make sure there are no duplicates. */
+    qsort(extension_types, num_extensions, sizeof(unsigned int), compare_uint);
+    for (i = 1; i < num_extensions; i++) {
+        if (extension_types[i - 1] == extension_types[i])
+            goto done;
+    }
+    ret = 1;
+ done:
+    OPENSSL_free(extension_types);
+    return ret;
+}
+
+unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
+                                          unsigned char *limit, int *al)
+{
+    int extdatalen = 0;
+    unsigned char *orig = buf;
+    unsigned char *ret = buf;
+#ifndef OPENSSL_NO_EC
+    /* See if we support any ECC ciphersuites */
+    int using_ecc = 0;
+    if (s->version >= TLS1_VERSION || SSL_IS_DTLS(s)) {
+        int i;
+        unsigned long alg_k, alg_a;
+        STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
+
+        for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
+            const SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
+
+            alg_k = c->algorithm_mkey;
+            alg_a = c->algorithm_auth;
+            if ((alg_k & (SSL_kECDHE | SSL_kECDHEPSK))
+                || (alg_a & SSL_aECDSA)) {
+                using_ecc = 1;
+                break;
+            }
+        }
+    }
+#endif
+
+    ret += 2;
+
+    if (ret >= limit)
+        return NULL;            /* this really never occurs, but ... */
+
+    /* Add RI if renegotiating */
+    if (s->renegotiate) {
+        int el;
+
+        if (!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0)) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return NULL;
+        }
+
+        if (CHECKLEN(ret, 4 + el, limit))
+            return NULL;
+
+        s2n(TLSEXT_TYPE_renegotiate, ret);
+        s2n(el, ret);
+
+        if (!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el)) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return NULL;
+        }
+
+        ret += el;
+    }
+    /* Only add RI for SSLv3 */
+    if (s->client_version == SSL3_VERSION)
+        goto done;
+
+    if (s->tlsext_hostname != NULL) {
+        /* Add TLS extension servername to the Client Hello message */
+        size_t size_str;
+
+        /*-
+         * check for enough space.
+         * 4 for the servername type and extension length
+         * 2 for servernamelist length
+         * 1 for the hostname type
+         * 2 for hostname length
+         * + hostname length
+         */
+        size_str = strlen(s->tlsext_hostname);
+        if (CHECKLEN(ret, 9 + size_str, limit))
+            return NULL;
+
+        /* extension type and length */
+        s2n(TLSEXT_TYPE_server_name, ret);
+        s2n(size_str + 5, ret);
+
+        /* length of servername list */
+        s2n(size_str + 3, ret);
+
+        /* hostname type, length and hostname */
+        *(ret++) = (unsigned char)TLSEXT_NAMETYPE_host_name;
+        s2n(size_str, ret);
+        memcpy(ret, s->tlsext_hostname, size_str);
+        ret += size_str;
+    }
+#ifndef OPENSSL_NO_SRP
+    /* Add SRP username if there is one */
+    if (s->srp_ctx.login != NULL) { /* Add TLS extension SRP username to the
+                                     * Client Hello message */
+
+        size_t login_len = strlen(s->srp_ctx.login);
+        if (login_len > 255 || login_len == 0) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return NULL;
+        }
+
+        /*-
+         * check for enough space.
+         * 4 for the srp type type and extension length
+         * 1 for the srp user identity
+         * + srp user identity length
+         */
+        if (CHECKLEN(ret, 5 + login_len, limit))
+            return NULL;
+
+        /* fill in the extension */
+        s2n(TLSEXT_TYPE_srp, ret);
+        s2n(login_len + 1, ret);
+        (*ret++) = (unsigned char)login_len;
+        memcpy(ret, s->srp_ctx.login, login_len);
+        ret += login_len;
+    }
+#endif
+
+#ifndef OPENSSL_NO_EC
+    if (using_ecc) {
+        /*
+         * Add TLS extension ECPointFormats to the ClientHello message
+         */
+        const unsigned char *pcurves, *pformats;
+        size_t num_curves, num_formats, curves_list_len;
+        size_t i;
+        unsigned char *etmp;
+
+        tls1_get_formatlist(s, &pformats, &num_formats);
+
+        if (num_formats > 255) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return NULL;
+        }
+        /*-
+         * check for enough space.
+         * 4 bytes for the ec point formats type and extension length
+         * 1 byte for the length of the formats
+         * + formats length
+         */
+        if (CHECKLEN(ret, 5 + num_formats, limit))
+            return NULL;
+
+        s2n(TLSEXT_TYPE_ec_point_formats, ret);
+        /* The point format list has 1-byte length. */
+        s2n(num_formats + 1, ret);
+        *(ret++) = (unsigned char)num_formats;
+        memcpy(ret, pformats, num_formats);
+        ret += num_formats;
+
+        /*
+         * Add TLS extension EllipticCurves to the ClientHello message
+         */
+        pcurves = s->tlsext_ellipticcurvelist;
+        if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves))
+            return NULL;
+
+        if (num_curves > 65532 / 2) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return NULL;
+        }
+        /*-
+         * check for enough space.
+         * 4 bytes for the ec curves type and extension length
+         * 2 bytes for the curve list length
+         * + curve list length
+         */
+        if (CHECKLEN(ret, 6 + (num_curves * 2), limit))
+            return NULL;
+
+        s2n(TLSEXT_TYPE_elliptic_curves, ret);
+        etmp = ret + 4;
+        /* Copy curve ID if supported */
+        for (i = 0; i < num_curves; i++, pcurves += 2) {
+            if (tls_curve_allowed(s, pcurves, SSL_SECOP_CURVE_SUPPORTED)) {
+                *etmp++ = pcurves[0];
+                *etmp++ = pcurves[1];
+            }
+        }
+
+        curves_list_len = etmp - ret - 4;
+
+        s2n(curves_list_len + 2, ret);
+        s2n(curves_list_len, ret);
+        ret += curves_list_len;
+    }
+#endif                          /* OPENSSL_NO_EC */
+
+    if (tls_use_ticket(s)) {
+        size_t ticklen;
+        if (!s->new_session && s->session && s->session->tlsext_tick)
+            ticklen = s->session->tlsext_ticklen;
+        else if (s->session && s->tlsext_session_ticket &&
+                 s->tlsext_session_ticket->data) {
+            ticklen = s->tlsext_session_ticket->length;
+            s->session->tlsext_tick = OPENSSL_malloc(ticklen);
+            if (s->session->tlsext_tick == NULL)
+                return NULL;
+            memcpy(s->session->tlsext_tick,
+                   s->tlsext_session_ticket->data, ticklen);
+            s->session->tlsext_ticklen = ticklen;
+        } else
+            ticklen = 0;
+        if (ticklen == 0 && s->tlsext_session_ticket &&
+            s->tlsext_session_ticket->data == NULL)
+            goto skip_ext;
+        /*
+         * Check for enough room 2 for extension type, 2 for len rest for
+         * ticket
+         */
+        if (CHECKLEN(ret, 4 + ticklen, limit))
+            return NULL;
+        s2n(TLSEXT_TYPE_session_ticket, ret);
+        s2n(ticklen, ret);
+        if (ticklen > 0) {
+            memcpy(ret, s->session->tlsext_tick, ticklen);
+            ret += ticklen;
+        }
+    }
+ skip_ext:
+
+    if (SSL_CLIENT_USE_SIGALGS(s)) {
+        size_t salglen;
+        const unsigned char *salg;
+        unsigned char *etmp;
+        salglen = tls12_get_psigalgs(s, 1, &salg);
+
+        /*-
+         * check for enough space.
+         * 4 bytes for the sigalgs type and extension length
+         * 2 bytes for the sigalg list length
+         * + sigalg list length
+         */
+        if (CHECKLEN(ret, salglen + 6, limit))
+            return NULL;
+        s2n(TLSEXT_TYPE_signature_algorithms, ret);
+        etmp = ret;
+        /* Skip over lengths for now */
+        ret += 4;
+        salglen = tls12_copy_sigalgs(s, ret, salg, salglen);
+        /* Fill in lengths */
+        s2n(salglen + 2, etmp);
+        s2n(salglen, etmp);
+        ret += salglen;
+    }
+#ifndef OPENSSL_NO_OCSP
+    if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
+        int i;
+        size_t extlen, idlen;
+        int lentmp;
+        OCSP_RESPID *id;
+
+        idlen = 0;
+        for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {
+            id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
+            lentmp = i2d_OCSP_RESPID(id, NULL);
+            if (lentmp <= 0)
+                return NULL;
+            idlen += (size_t)lentmp + 2;
+        }
+
+        if (s->tlsext_ocsp_exts) {
+            lentmp = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
+            if (lentmp < 0)
+                return NULL;
+            extlen = (size_t)lentmp;
+        } else
+            extlen = 0;
+
+        if (extlen + idlen > 0xFFF0)
+            return NULL;
+        /*
+         * 2 bytes for status request type
+         * 2 bytes for status request len
+         * 1 byte for OCSP request type
+         * 2 bytes for length of ids
+         * 2 bytes for length of extensions
+         * + length of ids
+         * + length of extensions
+         */
+        if (CHECKLEN(ret, 9 + idlen + extlen, limit))
+            return NULL;
+
+        s2n(TLSEXT_TYPE_status_request, ret);
+        s2n(extlen + idlen + 5, ret);
+        *(ret++) = TLSEXT_STATUSTYPE_ocsp;
+        s2n(idlen, ret);
+        for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {
+            /* save position of id len */
+            unsigned char *q = ret;
+            id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
+            /* skip over id len */
+            ret += 2;
+            lentmp = i2d_OCSP_RESPID(id, &ret);
+            /* write id len */
+            s2n(lentmp, q);
+        }
+        s2n(extlen, ret);
+        if (extlen > 0)
+            i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret);
+    }
+#endif
+#ifndef OPENSSL_NO_HEARTBEATS
+    if (SSL_IS_DTLS(s)) {
+        /* Add Heartbeat extension */
+
+        /*-
+         * check for enough space.
+         * 4 bytes for the heartbeat ext type and extension length
+         * 1 byte for the mode
+         */
+        if (CHECKLEN(ret, 5, limit))
+            return NULL;
+
+        s2n(TLSEXT_TYPE_heartbeat, ret);
+        s2n(1, ret);
+        /*-
+         * Set mode:
+         * 1: peer may send requests
+         * 2: peer not allowed to send requests
+         */
+        if (s->tlsext_heartbeat & SSL_DTLSEXT_HB_DONT_RECV_REQUESTS)
+            *(ret++) = SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;
+        else
+            *(ret++) = SSL_DTLSEXT_HB_ENABLED;
+    }
+#endif
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+    if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len) {
+        /*
+         * The client advertises an empty extension to indicate its support
+         * for Next Protocol Negotiation
+         */
+
+        /*-
+         * check for enough space.
+         * 4 bytes for the NPN ext type and extension length
+         */
+        if (CHECKLEN(ret, 4, limit))
+            return NULL;
+        s2n(TLSEXT_TYPE_next_proto_neg, ret);
+        s2n(0, ret);
+    }
+#endif
+
+    /*
+     * finish_md_len is non-zero during a renegotiation, so
+     * this avoids sending ALPN during the renegotiation
+     * (see longer comment below)
+     */
+    if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) {
+        /*-
+         * check for enough space.
+         * 4 bytes for the ALPN type and extension length
+         * 2 bytes for the ALPN protocol list length
+         * + ALPN protocol list length
+         */
+        if (CHECKLEN(ret, 6 + s->alpn_client_proto_list_len, limit))
+            return NULL;
+        s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
+        s2n(2 + s->alpn_client_proto_list_len, ret);
+        s2n(s->alpn_client_proto_list_len, ret);
+        memcpy(ret, s->alpn_client_proto_list, s->alpn_client_proto_list_len);
+        ret += s->alpn_client_proto_list_len;
+        s->s3->alpn_sent = 1;
+    }
+#ifndef OPENSSL_NO_SRTP
+    if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) {
+        int el;
+
+        /* Returns 0 on success!! */
+        if (ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0)) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return NULL;
+        }
+
+        /*-
+         * check for enough space.
+         * 4 bytes for the SRTP type and extension length
+         * + SRTP profiles length
+         */
+        if (CHECKLEN(ret, 4 + el, limit))
+            return NULL;
+
+        s2n(TLSEXT_TYPE_use_srtp, ret);
+        s2n(el, ret);
+
+        if (ssl_add_clienthello_use_srtp_ext(s, ret, &el, el)) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return NULL;
+        }
+        ret += el;
+    }
+#endif
+    custom_ext_init(&s->cert->cli_ext);
+    /* Add custom TLS Extensions to ClientHello */
+    if (!custom_ext_add(s, 0, &ret, limit, al))
+        return NULL;
+    /*
+     * In 1.1.0 before 1.1.0c we negotiated EtM with DTLS, then just
+     * silently failed to actually do it. It is fixed in 1.1.1 but to
+     * ease the transition especially from 1.1.0b to 1.1.0c, we just
+     * disable it in 1.1.0.
+     */
+    if (!SSL_IS_DTLS(s)) {
+        /*-
+         * check for enough space.
+         * 4 bytes for the ETM type and extension length
+         */
+        if (CHECKLEN(ret, 4, limit))
+            return NULL;
+        s2n(TLSEXT_TYPE_encrypt_then_mac, ret);
+        s2n(0, ret);
+    }
+
+#ifndef OPENSSL_NO_CT
+    if (s->ct_validation_callback != NULL) {
+        /*-
+         * check for enough space.
+         * 4 bytes for the SCT type and extension length
+         */
+        if (CHECKLEN(ret, 4, limit))
+            return NULL;
+
+        s2n(TLSEXT_TYPE_signed_certificate_timestamp, ret);
+        s2n(0, ret);
+    }
+#endif
+
+    /*-
+     * check for enough space.
+     * 4 bytes for the EMS type and extension length
+     */
+    if (CHECKLEN(ret, 4, limit))
+        return NULL;
+    s2n(TLSEXT_TYPE_extended_master_secret, ret);
+    s2n(0, ret);
+
+    /*
+     * Add padding to workaround bugs in F5 terminators. See
+     * https://tools.ietf.org/html/draft-agl-tls-padding-03 NB: because this
+     * code works out the length of all existing extensions it MUST always
+     * appear last.
+     */
+    if (s->options & SSL_OP_TLSEXT_PADDING) {
+        int hlen = ret - (unsigned char *)s->init_buf->data;
+
+        if (hlen > 0xff && hlen < 0x200) {
+            hlen = 0x200 - hlen;
+            if (hlen >= 4)
+                hlen -= 4;
+            else
+                hlen = 0;
+
+            /*-
+             * check for enough space. Strictly speaking we know we've already
+             * got enough space because to get here the message size is < 0x200,
+             * but we know that we've allocated far more than that in the buffer
+             * - but for consistency and robustness we're going to check anyway.
+             *
+             * 4 bytes for the padding type and extension length
+             * + padding length
+             */
+            if (CHECKLEN(ret, 4 + hlen, limit))
+                return NULL;
+            s2n(TLSEXT_TYPE_padding, ret);
+            s2n(hlen, ret);
+            memset(ret, 0, hlen);
+            ret += hlen;
+        }
+    }
+
+ done:
+
+    if ((extdatalen = ret - orig - 2) == 0)
+        return orig;
+
+    s2n(extdatalen, orig);
+    return ret;
+}
+
+unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
+                                          unsigned char *limit, int *al)
+{
+    int extdatalen = 0;
+    unsigned char *orig = buf;
+    unsigned char *ret = buf;
+#ifndef OPENSSL_NO_NEXTPROTONEG
+    int next_proto_neg_seen;
+#endif
+#ifndef OPENSSL_NO_EC
+    unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+    unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+    int using_ecc = (alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA);
+    using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL);
+#endif
+
+    ret += 2;
+    if (ret >= limit)
+        return NULL;            /* this really never occurs, but ... */
+
+    if (s->s3->send_connection_binding) {
+        int el;
+
+        if (!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0)) {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return NULL;
+        }
+
+        /*-
+         * check for enough space.
+         * 4 bytes for the reneg type and extension length
+         * + reneg data length
+         */
+        if (CHECKLEN(ret, 4 + el, limit))
+            return NULL;
+
+        s2n(TLSEXT_TYPE_renegotiate, ret);
+        s2n(el, ret);
+
+        if (!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el)) {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return NULL;
+        }
+
+        ret += el;
+    }
+
+    /* Only add RI for SSLv3 */
+    if (s->version == SSL3_VERSION)
+        goto done;
+
+    if (!s->hit && s->servername_done == 1
+        && s->session->tlsext_hostname != NULL) {
+        /*-
+         * check for enough space.
+         * 4 bytes for the server name type and extension length
+         */
+        if (CHECKLEN(ret, 4, limit))
+            return NULL;
+
+        s2n(TLSEXT_TYPE_server_name, ret);
+        s2n(0, ret);
+    }
+#ifndef OPENSSL_NO_EC
+    if (using_ecc) {
+        const unsigned char *plist;
+        size_t plistlen;
+        /*
+         * Add TLS extension ECPointFormats to the ServerHello message
+         */
+
+        tls1_get_formatlist(s, &plist, &plistlen);
+
+        if (plistlen > 255) {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return NULL;
+        }
+
+        /*-
+         * check for enough space.
+         * 4 bytes for the ec points format type and extension length
+         * 1 byte for the points format list length
+         * + length of points format list
+         */
+        if (CHECKLEN(ret, 5 + plistlen, limit))
+            return NULL;
+
+        s2n(TLSEXT_TYPE_ec_point_formats, ret);
+        s2n(plistlen + 1, ret);
+        *(ret++) = (unsigned char)plistlen;
+        memcpy(ret, plist, plistlen);
+        ret += plistlen;
+
+    }
+    /*
+     * Currently the server should not respond with a SupportedCurves
+     * extension
+     */
+#endif                          /* OPENSSL_NO_EC */
+
+    if (s->tlsext_ticket_expected && tls_use_ticket(s)) {
+        /*-
+         * check for enough space.
+         * 4 bytes for the Ticket type and extension length
+         */
+        if (CHECKLEN(ret, 4, limit))
+            return NULL;
+        s2n(TLSEXT_TYPE_session_ticket, ret);
+        s2n(0, ret);
+    } else {
+        /*
+         * if we don't add the above TLSEXT, we can't add a session ticket
+         * later
+         */
+        s->tlsext_ticket_expected = 0;
+    }
+
+    if (s->tlsext_status_expected) {
+        /*-
+         * check for enough space.
+         * 4 bytes for the Status request type and extension length
+         */
+        if (CHECKLEN(ret, 4, limit))
+            return NULL;
+        s2n(TLSEXT_TYPE_status_request, ret);
+        s2n(0, ret);
+    }
+#ifndef OPENSSL_NO_SRTP
+    if (SSL_IS_DTLS(s) && s->srtp_profile) {
+        int el;
+
+        /* Returns 0 on success!! */
+        if (ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0)) {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return NULL;
+        }
+        /*-
+         * check for enough space.
+         * 4 bytes for the SRTP profiles type and extension length
+         * + length of the SRTP profiles list
+         */
+        if (CHECKLEN(ret, 4 + el, limit))
+            return NULL;
+
+        s2n(TLSEXT_TYPE_use_srtp, ret);
+        s2n(el, ret);
+
+        if (ssl_add_serverhello_use_srtp_ext(s, ret, &el, el)) {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
+            return NULL;
+        }
+        ret += el;
+    }
+#endif
+
+    if (((s->s3->tmp.new_cipher->id & 0xFFFF) == 0x80
+         || (s->s3->tmp.new_cipher->id & 0xFFFF) == 0x81)
+        && (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG)) {
+        const unsigned char cryptopro_ext[36] = {
+            0xfd, 0xe8,         /* 65000 */
+            0x00, 0x20,         /* 32 bytes length */
+            0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85,
+            0x03, 0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06,
+            0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08,
+            0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17
+        };
+
+        /* check for enough space. */
+        if (CHECKLEN(ret, sizeof(cryptopro_ext), limit))
+            return NULL;
+        memcpy(ret, cryptopro_ext, sizeof(cryptopro_ext));
+        ret += sizeof(cryptopro_ext);
+
+    }
+#ifndef OPENSSL_NO_HEARTBEATS
+    /* Add Heartbeat extension if we've received one */
+    if (SSL_IS_DTLS(s) && (s->tlsext_heartbeat & SSL_DTLSEXT_HB_ENABLED)) {
+        /*-
+         * check for enough space.
+         * 4 bytes for the Heartbeat type and extension length
+         * 1 byte for the mode
+         */
+        if (CHECKLEN(ret, 5, limit))
+            return NULL;
+        s2n(TLSEXT_TYPE_heartbeat, ret);
+        s2n(1, ret);
+        /*-
+         * Set mode:
+         * 1: peer may send requests
+         * 2: peer not allowed to send requests
+         */
+        if (s->tlsext_heartbeat & SSL_DTLSEXT_HB_DONT_RECV_REQUESTS)
+            *(ret++) = SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;
+        else
+            *(ret++) = SSL_DTLSEXT_HB_ENABLED;
+
+    }
+#endif
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+    next_proto_neg_seen = s->s3->next_proto_neg_seen;
+    s->s3->next_proto_neg_seen = 0;
+    if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb) {
+        const unsigned char *npa;
+        unsigned int npalen;
+        int r;
+
+        r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen,
+                                              s->
+                                              ctx->next_protos_advertised_cb_arg);
+        if (r == SSL_TLSEXT_ERR_OK) {
+            /*-
+             * check for enough space.
+             * 4 bytes for the NPN type and extension length
+             * + length of protocols list
+             */
+            if (CHECKLEN(ret, 4 + npalen, limit))
+                return NULL;
+            s2n(TLSEXT_TYPE_next_proto_neg, ret);
+            s2n(npalen, ret);
+            memcpy(ret, npa, npalen);
+            ret += npalen;
+            s->s3->next_proto_neg_seen = 1;
+        }
+    }
+#endif
+    if (!custom_ext_add(s, 1, &ret, limit, al))
+        return NULL;
+    if (s->tlsext_use_etm) {
+        /*
+         * Don't use encrypt_then_mac if AEAD or RC4 might want to disable
+         * for other cases too.
+         */
+        if (SSL_IS_DTLS(s) || s->s3->tmp.new_cipher->algorithm_mac == SSL_AEAD
+            || s->s3->tmp.new_cipher->algorithm_enc == SSL_RC4
+            || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT
+            || s->s3->tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT12)
+            s->tlsext_use_etm = 0;
+        else {
+            /*-
+             * check for enough space.
+             * 4 bytes for the ETM type and extension length
+             */
+            if (CHECKLEN(ret, 4, limit))
+                return NULL;
+            s2n(TLSEXT_TYPE_encrypt_then_mac, ret);
+            s2n(0, ret);
+        }
+    }
+    if (s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) {
+        /*-
+         * check for enough space.
+         * 4 bytes for the EMS type and extension length
+         */
+        if (CHECKLEN(ret, 4, limit))
+            return NULL;
+        s2n(TLSEXT_TYPE_extended_master_secret, ret);
+        s2n(0, ret);
+    }
+
+    if (s->s3->alpn_selected != NULL) {
+        const unsigned char *selected = s->s3->alpn_selected;
+        size_t len = s->s3->alpn_selected_len;
+
+        /*-
+         * check for enough space.
+         * 4 bytes for the ALPN type and extension length
+         * 2 bytes for ALPN data length
+         * 1 byte for selected protocol length
+         * + length of the selected protocol
+         */
+        if (CHECKLEN(ret, 7 + len, limit))
+            return NULL;
+        s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
+        s2n(3 + len, ret);
+        s2n(1 + len, ret);
+        *ret++ = len;
+        memcpy(ret, selected, len);
+        ret += len;
+    }
+
+ done:
+
+    if ((extdatalen = ret - orig - 2) == 0)
+        return orig;
+
+    s2n(extdatalen, orig);
+    return ret;
+}
+
+/*
+ * Save the ALPN extension in a ClientHello.
+ * pkt: the contents of the ALPN extension, not including type and length.
+ * al: a pointer to the  alert value to send in the event of a failure.
+ * returns: 1 on success, 0 on error.
+ */
+static int tls1_alpn_handle_client_hello(SSL *s, PACKET *pkt, int *al)
+{
+    PACKET protocol_list, save_protocol_list, protocol;
+
+    *al = SSL_AD_DECODE_ERROR;
+
+    if (!PACKET_as_length_prefixed_2(pkt, &protocol_list)
+        || PACKET_remaining(&protocol_list) < 2) {
+        return 0;
+    }
+
+    save_protocol_list = protocol_list;
+    do {
+        /* Protocol names can't be empty. */
+        if (!PACKET_get_length_prefixed_1(&protocol_list, &protocol)
+            || PACKET_remaining(&protocol) == 0) {
+            return 0;
+        }
+    } while (PACKET_remaining(&protocol_list) != 0);
+
+    if (!PACKET_memdup(&save_protocol_list,
+                       &s->s3->alpn_proposed, &s->s3->alpn_proposed_len)) {
+        *al = TLS1_AD_INTERNAL_ERROR;
+        return 0;
+    }
+
+    return 1;
+}
+
+/*
+ * Process the ALPN extension in a ClientHello.
+ * al: a pointer to the alert value to send in the event of a failure.
+ * returns 1 on success, 0 on error.
+ */
+static int tls1_alpn_handle_client_hello_late(SSL *s, int *al)
+{
+    const unsigned char *selected = NULL;
+    unsigned char selected_len = 0;
+
+    if (s->ctx->alpn_select_cb != NULL && s->s3->alpn_proposed != NULL) {
+        int r = s->ctx->alpn_select_cb(s, &selected, &selected_len,
+                                       s->s3->alpn_proposed,
+                                       s->s3->alpn_proposed_len,
+                                       s->ctx->alpn_select_cb_arg);
+
+        if (r == SSL_TLSEXT_ERR_OK) {
+            OPENSSL_free(s->s3->alpn_selected);
+            s->s3->alpn_selected = OPENSSL_memdup(selected, selected_len);
+            if (s->s3->alpn_selected == NULL) {
+                *al = SSL_AD_INTERNAL_ERROR;
+                return 0;
+            }
+            s->s3->alpn_selected_len = selected_len;
+#ifndef OPENSSL_NO_NEXTPROTONEG
+            /* ALPN takes precedence over NPN. */
+            s->s3->next_proto_neg_seen = 0;
+#endif
+        } else {
+            *al = SSL_AD_NO_APPLICATION_PROTOCOL;
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+#ifndef OPENSSL_NO_EC
+/*-
+ * ssl_check_for_safari attempts to fingerprint Safari using OS X
+ * SecureTransport using the TLS extension block in |pkt|.
+ * Safari, since 10.6, sends exactly these extensions, in this order:
+ *   SNI,
+ *   elliptic_curves
+ *   ec_point_formats
+ *
+ * We wish to fingerprint Safari because they broke ECDHE-ECDSA support in 10.8,
+ * but they advertise support. So enabling ECDHE-ECDSA ciphers breaks them.
+ * Sadly we cannot differentiate 10.6, 10.7 and 10.8.4 (which work), from
+ * 10.8..10.8.3 (which don't work).
+ */
+static void ssl_check_for_safari(SSL *s, const PACKET *pkt)
+{
+    unsigned int type;
+    PACKET sni, tmppkt;
+    size_t ext_len;
+
+    static const unsigned char kSafariExtensionsBlock[] = {
+        0x00, 0x0a,             /* elliptic_curves extension */
+        0x00, 0x08,             /* 8 bytes */
+        0x00, 0x06,             /* 6 bytes of curve ids */
+        0x00, 0x17,             /* P-256 */
+        0x00, 0x18,             /* P-384 */
+        0x00, 0x19,             /* P-521 */
+
+        0x00, 0x0b,             /* ec_point_formats */
+        0x00, 0x02,             /* 2 bytes */
+        0x01,                   /* 1 point format */
+        0x00,                   /* uncompressed */
+        /* The following is only present in TLS 1.2 */
+        0x00, 0x0d,             /* signature_algorithms */
+        0x00, 0x0c,             /* 12 bytes */
+        0x00, 0x0a,             /* 10 bytes */
+        0x05, 0x01,             /* SHA-384/RSA */
+        0x04, 0x01,             /* SHA-256/RSA */
+        0x02, 0x01,             /* SHA-1/RSA */
+        0x04, 0x03,             /* SHA-256/ECDSA */
+        0x02, 0x03,             /* SHA-1/ECDSA */
+    };
+
+    /* Length of the common prefix (first two extensions). */
+    static const size_t kSafariCommonExtensionsLength = 18;
+
+    tmppkt = *pkt;
+
+    if (!PACKET_forward(&tmppkt, 2)
+        || !PACKET_get_net_2(&tmppkt, &type)
+        || !PACKET_get_length_prefixed_2(&tmppkt, &sni)) {
+        return;
+    }
+
+    if (type != TLSEXT_TYPE_server_name)
+        return;
+
+    ext_len = TLS1_get_client_version(s) >= TLS1_2_VERSION ?
+        sizeof(kSafariExtensionsBlock) : kSafariCommonExtensionsLength;
+
+    s->s3->is_probably_safari = PACKET_equal(&tmppkt, kSafariExtensionsBlock,
+                                             ext_len);
+}
+#endif                          /* !OPENSSL_NO_EC */
+
+/*
+ * Parse ClientHello extensions and stash extension info in various parts of
+ * the SSL object. Verify that there are no duplicate extensions.
+ *
+ * Behaviour upon resumption is extension-specific. If the extension has no
+ * effect during resumption, it is parsed (to verify its format) but otherwise
+ * ignored.
+ *
+ * Consumes the entire packet in |pkt|. Returns 1 on success and 0 on failure.
+ * Upon failure, sets |al| to the appropriate alert.
+ */
+static int ssl_scan_clienthello_tlsext(SSL *s, PACKET *pkt, int *al)
+{
+    unsigned int type;
+    int renegotiate_seen = 0;
+    PACKET extensions;
+
+    *al = SSL_AD_DECODE_ERROR;
+    s->servername_done = 0;
+    s->tlsext_status_type = -1;
+#ifndef OPENSSL_NO_NEXTPROTONEG
+    s->s3->next_proto_neg_seen = 0;
+#endif
+
+    OPENSSL_free(s->s3->alpn_selected);
+    s->s3->alpn_selected = NULL;
+    s->s3->alpn_selected_len = 0;
+    OPENSSL_free(s->s3->alpn_proposed);
+    s->s3->alpn_proposed = NULL;
+    s->s3->alpn_proposed_len = 0;
+#ifndef OPENSSL_NO_HEARTBEATS
+    s->tlsext_heartbeat &= ~(SSL_DTLSEXT_HB_ENABLED |
+                             SSL_DTLSEXT_HB_DONT_SEND_REQUESTS);
+#endif
+
+#ifndef OPENSSL_NO_EC
+    if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
+        ssl_check_for_safari(s, pkt);
+#endif                          /* !OPENSSL_NO_EC */
+
+    /* Clear any signature algorithms extension received */
+    OPENSSL_free(s->s3->tmp.peer_sigalgs);
+    s->s3->tmp.peer_sigalgs = NULL;
+    s->tlsext_use_etm = 0;
+
+#ifndef OPENSSL_NO_SRP
+    OPENSSL_free(s->srp_ctx.login);
+    s->srp_ctx.login = NULL;
+#endif
+
+    s->srtp_profile = NULL;
+
+    if (PACKET_remaining(pkt) == 0)
+        goto ri_check;
+
+    if (!PACKET_as_length_prefixed_2(pkt, &extensions))
+        return 0;
+
+    if (!tls1_check_duplicate_extensions(&extensions))
+        return 0;
+
+    /*
+     * We parse all extensions to ensure the ClientHello is well-formed but,
+     * unless an extension specifies otherwise, we ignore extensions upon
+     * resumption.
+     */
+    while (PACKET_get_net_2(&extensions, &type)) {
+        PACKET extension;
+        if (!PACKET_get_length_prefixed_2(&extensions, &extension))
+            return 0;
+
+        if (s->tlsext_debug_cb)
+            s->tlsext_debug_cb(s, 0, type, PACKET_data(&extension),
+                               PACKET_remaining(&extension),
+                               s->tlsext_debug_arg);
+
+        if (type == TLSEXT_TYPE_renegotiate) {
+            if (!ssl_parse_clienthello_renegotiate_ext(s, &extension, al))
+                return 0;
+            renegotiate_seen = 1;
+        } else if (s->version == SSL3_VERSION) {
+        }
+/*-
+ * The servername extension is treated as follows:
+ *
+ * - Only the hostname type is supported with a maximum length of 255.
+ * - The servername is rejected if too long or if it contains zeros,
+ *   in which case an fatal alert is generated.
+ * - The servername field is maintained together with the session cache.
+ * - When a session is resumed, the servername call back invoked in order
+ *   to allow the application to position itself to the right context.
+ * - The servername is acknowledged if it is new for a session or when
+ *   it is identical to a previously used for the same session.
+ *   Applications can control the behaviour.  They can at any time
+ *   set a 'desirable' servername for a new SSL object. This can be the
+ *   case for example with HTTPS when a Host: header field is received and
+ *   a renegotiation is requested. In this case, a possible servername
+ *   presented in the new client hello is only acknowledged if it matches
+ *   the value of the Host: field.
+ * - Applications must  use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
+ *   if they provide for changing an explicit servername context for the
+ *   session, i.e. when the session has been established with a servername
+ *   extension.
+ * - On session reconnect, the servername extension may be absent.
+ *
+ */
+
+        else if (type == TLSEXT_TYPE_server_name) {
+            unsigned int servname_type;
+            PACKET sni, hostname;
+
+            if (!PACKET_as_length_prefixed_2(&extension, &sni)
+                /* ServerNameList must be at least 1 byte long. */
+                || PACKET_remaining(&sni) == 0) {
+                return 0;
+            }
+
+            /*
+             * Although the server_name extension was intended to be
+             * extensible to new name types, RFC 4366 defined the
+             * syntax inextensibility and OpenSSL 1.0.x parses it as
+             * such.
+             * RFC 6066 corrected the mistake but adding new name types
+             * is nevertheless no longer feasible, so act as if no other
+             * SNI types can exist, to simplify parsing.
+             *
+             * Also note that the RFC permits only one SNI value per type,
+             * i.e., we can only have a single hostname.
+             */
+            if (!PACKET_get_1(&sni, &servname_type)
+                || servname_type != TLSEXT_NAMETYPE_host_name
+                || !PACKET_as_length_prefixed_2(&sni, &hostname)) {
+                return 0;
+            }
+
+            if (!s->hit) {
+                if (PACKET_remaining(&hostname) > TLSEXT_MAXLEN_host_name) {
+                    *al = TLS1_AD_UNRECOGNIZED_NAME;
+                    return 0;
+                }
+
+                if (PACKET_contains_zero_byte(&hostname)) {
+                    *al = TLS1_AD_UNRECOGNIZED_NAME;
+                    return 0;
+                }
+
+                if (!PACKET_strndup(&hostname, &s->session->tlsext_hostname)) {
+                    *al = TLS1_AD_INTERNAL_ERROR;
+                    return 0;
+                }
+
+                s->servername_done = 1;
+            } else {
+                /*
+                 * TODO(openssl-team): if the SNI doesn't match, we MUST
+                 * fall back to a full handshake.
+                 */
+                s->servername_done = s->session->tlsext_hostname
+                    && PACKET_equal(&hostname, s->session->tlsext_hostname,
+                                    strlen(s->session->tlsext_hostname));
+            }
+        }
+#ifndef OPENSSL_NO_SRP
+        else if (type == TLSEXT_TYPE_srp) {
+            PACKET srp_I;
+
+            if (!PACKET_as_length_prefixed_1(&extension, &srp_I))
+                return 0;
+
+            if (PACKET_contains_zero_byte(&srp_I))
+                return 0;
+
+            /*
+             * TODO(openssl-team): currently, we re-authenticate the user
+             * upon resumption. Instead, we MUST ignore the login.
+             */
+            if (!PACKET_strndup(&srp_I, &s->srp_ctx.login)) {
+                *al = TLS1_AD_INTERNAL_ERROR;
+                return 0;
+            }
+        }
+#endif
+
+#ifndef OPENSSL_NO_EC
+        else if (type == TLSEXT_TYPE_ec_point_formats) {
+            PACKET ec_point_format_list;
+
+            if (!PACKET_as_length_prefixed_1(&extension, &ec_point_format_list)
+                || PACKET_remaining(&ec_point_format_list) == 0) {
+                return 0;
+            }
+
+            if (!s->hit) {
+                if (!PACKET_memdup(&ec_point_format_list,
+                                   &s->session->tlsext_ecpointformatlist,
+                                   &s->
+                                   session->tlsext_ecpointformatlist_length)) {
+                    *al = TLS1_AD_INTERNAL_ERROR;
+                    return 0;
+                }
+            }
+        } else if (type == TLSEXT_TYPE_elliptic_curves) {
+            PACKET elliptic_curve_list;
+
+            /* Each NamedCurve is 2 bytes and we must have at least 1. */
+            if (!PACKET_as_length_prefixed_2(&extension, &elliptic_curve_list)
+                || PACKET_remaining(&elliptic_curve_list) == 0
+                || (PACKET_remaining(&elliptic_curve_list) % 2) != 0) {
+                return 0;
+            }
+
+            if (!s->hit) {
+                if (!PACKET_memdup(&elliptic_curve_list,
+                                   &s->session->tlsext_ellipticcurvelist,
+                                   &s->
+                                   session->tlsext_ellipticcurvelist_length)) {
+                    *al = TLS1_AD_INTERNAL_ERROR;
+                    return 0;
+                }
+            }
+        }
+#endif                          /* OPENSSL_NO_EC */
+        else if (type == TLSEXT_TYPE_session_ticket) {
+            if (s->tls_session_ticket_ext_cb &&
+                !s->tls_session_ticket_ext_cb(s, PACKET_data(&extension),
+                                              PACKET_remaining(&extension),
+                                              s->tls_session_ticket_ext_cb_arg))
+            {
+                *al = TLS1_AD_INTERNAL_ERROR;
+                return 0;
+            }
+        } else if (type == TLSEXT_TYPE_signature_algorithms) {
+            PACKET supported_sig_algs;
+
+            if (!PACKET_as_length_prefixed_2(&extension, &supported_sig_algs)
+                || (PACKET_remaining(&supported_sig_algs) % 2) != 0
+                || PACKET_remaining(&supported_sig_algs) == 0) {
+                return 0;
+            }
+
+            if (!s->hit) {
+                if (!tls1_save_sigalgs(s, PACKET_data(&supported_sig_algs),
+                                       PACKET_remaining(&supported_sig_algs))) {
+                    return 0;
+                }
+            }
+        } else if (type == TLSEXT_TYPE_status_request) {
+            if (!PACKET_get_1(&extension,
+                              (unsigned int *)&s->tlsext_status_type)) {
+                return 0;
+            }
+#ifndef OPENSSL_NO_OCSP
+            if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
+                const unsigned char *ext_data;
+                PACKET responder_id_list, exts;
+                if (!PACKET_get_length_prefixed_2
+                    (&extension, &responder_id_list))
+                    return 0;
+
+                /*
+                 * We remove any OCSP_RESPIDs from a previous handshake
+                 * to prevent unbounded memory growth - CVE-2016-6304
+                 */
+                sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids,
+                                        OCSP_RESPID_free);
+                if (PACKET_remaining(&responder_id_list) > 0) {
+                    s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null();
+                    if (s->tlsext_ocsp_ids == NULL) {
+                        *al = SSL_AD_INTERNAL_ERROR;
+                        return 0;
+                    }
+                } else {
+                    s->tlsext_ocsp_ids = NULL;
+                }
+
+                while (PACKET_remaining(&responder_id_list) > 0) {
+                    OCSP_RESPID *id;
+                    PACKET responder_id;
+                    const unsigned char *id_data;
+
+                    if (!PACKET_get_length_prefixed_2(&responder_id_list,
+                                                      &responder_id)
+                        || PACKET_remaining(&responder_id) == 0) {
+                        return 0;
+                    }
+
+                    id_data = PACKET_data(&responder_id);
+                    id = d2i_OCSP_RESPID(NULL, &id_data,
+                                         PACKET_remaining(&responder_id));
+                    if (id == NULL)
+                        return 0;
+
+                    if (id_data != PACKET_end(&responder_id)) {
+                        OCSP_RESPID_free(id);
+                        return 0;
+                    }
+
+                    if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) {
+                        OCSP_RESPID_free(id);
+                        *al = SSL_AD_INTERNAL_ERROR;
+                        return 0;
+                    }
+                }
+
+                /* Read in request_extensions */
+                if (!PACKET_as_length_prefixed_2(&extension, &exts))
+                    return 0;
+
+                if (PACKET_remaining(&exts) > 0) {
+                    ext_data = PACKET_data(&exts);
+                    sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts,
+                                               X509_EXTENSION_free);
+                    s->tlsext_ocsp_exts =
+                        d2i_X509_EXTENSIONS(NULL, &ext_data,
+                                            PACKET_remaining(&exts));
+                    if (s->tlsext_ocsp_exts == NULL
+                        || ext_data != PACKET_end(&exts)) {
+                        return 0;
+                    }
+                }
+            } else
+#endif
+            {
+                /*
+                 * We don't know what to do with any other type so ignore it.
+                 */
+                s->tlsext_status_type = -1;
+            }
+        }
+#ifndef OPENSSL_NO_HEARTBEATS
+        else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_heartbeat) {
+            unsigned int hbtype;
+
+            if (!PACKET_get_1(&extension, &hbtype)
+                || PACKET_remaining(&extension)) {
+                *al = SSL_AD_DECODE_ERROR;
+                return 0;
+            }
+            switch (hbtype) {
+            case 0x01:         /* Client allows us to send HB requests */
+                s->tlsext_heartbeat |= SSL_DTLSEXT_HB_ENABLED;
+                break;
+            case 0x02:         /* Client doesn't accept HB requests */
+                s->tlsext_heartbeat |= SSL_DTLSEXT_HB_ENABLED;
+                s->tlsext_heartbeat |= SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;
+                break;
+            default:
+                *al = SSL_AD_ILLEGAL_PARAMETER;
+                return 0;
+            }
+        }
+#endif
+#ifndef OPENSSL_NO_NEXTPROTONEG
+        else if (type == TLSEXT_TYPE_next_proto_neg &&
+                 s->s3->tmp.finish_md_len == 0) {
+            /*-
+             * We shouldn't accept this extension on a
+             * renegotiation.
+             *
+             * s->new_session will be set on renegotiation, but we
+             * probably shouldn't rely that it couldn't be set on
+             * the initial renegotiation too in certain cases (when
+             * there's some other reason to disallow resuming an
+             * earlier session -- the current code won't be doing
+             * anything like that, but this might change).
+             *
+             * A valid sign that there's been a previous handshake
+             * in this connection is if s->s3->tmp.finish_md_len >
+             * 0.  (We are talking about a check that will happen
+             * in the Hello protocol round, well before a new
+             * Finished message could have been computed.)
+             */
+            s->s3->next_proto_neg_seen = 1;
+        }
+#endif
+
+        else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation &&
+                 s->s3->tmp.finish_md_len == 0) {
+            if (!tls1_alpn_handle_client_hello(s, &extension, al))
+                return 0;
+        }
+
+        /* session ticket processed earlier */
+#ifndef OPENSSL_NO_SRTP
+        else if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)
+                 && type == TLSEXT_TYPE_use_srtp) {
+            if (ssl_parse_clienthello_use_srtp_ext(s, &extension, al))
+                return 0;
+        }
+#endif
+        else if (type == TLSEXT_TYPE_encrypt_then_mac)
+            s->tlsext_use_etm = 1;
+        /*
+         * Note: extended master secret extension handled in
+         * tls_check_serverhello_tlsext_early()
+         */
+
+        /*
+         * If this ClientHello extension was unhandled and this is a
+         * nonresumed connection, check whether the extension is a custom
+         * TLS Extension (has a custom_srv_ext_record), and if so call the
+         * callback and record the extension number so that an appropriate
+         * ServerHello may be later returned.
+         */
+        else if (!s->hit) {
+            if (custom_ext_parse(s, 1, type, PACKET_data(&extension),
+                                 PACKET_remaining(&extension), al) <= 0)
+                return 0;
+        }
+    }
+
+    if (PACKET_remaining(pkt) != 0) {
+        /*
+         * tls1_check_duplicate_extensions should ensure this never happens.
+         */
+        *al = SSL_AD_INTERNAL_ERROR;
+        return 0;
+    }
+
+ ri_check:
+
+    /* Need RI if renegotiating */
+
+    if (!renegotiate_seen && s->renegotiate &&
+        !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        SSLerr(SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT,
+               SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+        return 0;
+    }
+
+    /*
+     * This function currently has no state to clean up, so it returns directly.
+     * If parsing fails at any point, the function returns early.
+     * The SSL object may be left with partial data from extensions, but it must
+     * then no longer be used, and clearing it up will free the leftovers.
+     */
+    return 1;
+}
+
+int ssl_parse_clienthello_tlsext(SSL *s, PACKET *pkt)
+{
+    int al = -1;
+    custom_ext_init(&s->cert->srv_ext);
+    if (ssl_scan_clienthello_tlsext(s, pkt, &al) <= 0) {
+        ssl3_send_alert(s, SSL3_AL_FATAL, al);
+        return 0;
+    }
+    if (ssl_check_clienthello_tlsext_early(s) <= 0) {
+        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, SSL_R_CLIENTHELLO_TLSEXT);
+        return 0;
+    }
+    return 1;
+}
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+/*
+ * ssl_next_proto_validate validates a Next Protocol Negotiation block. No
+ * elements of zero length are allowed and the set of elements must exactly
+ * fill the length of the block.
+ */
+static char ssl_next_proto_validate(PACKET *pkt)
+{
+    PACKET tmp_protocol;
+
+    while (PACKET_remaining(pkt)) {
+        if (!PACKET_get_length_prefixed_1(pkt, &tmp_protocol)
+            || PACKET_remaining(&tmp_protocol) == 0)
+            return 0;
+    }
+
+    return 1;
+}
+#endif
+
+static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al)
+{
+    unsigned int length, type, size;
+    int tlsext_servername = 0;
+    int renegotiate_seen = 0;
+
+#ifndef OPENSSL_NO_NEXTPROTONEG
+    s->s3->next_proto_neg_seen = 0;
+#endif
+    s->tlsext_ticket_expected = 0;
+
+    OPENSSL_free(s->s3->alpn_selected);
+    s->s3->alpn_selected = NULL;
+#ifndef OPENSSL_NO_HEARTBEATS
+    s->tlsext_heartbeat &= ~(SSL_DTLSEXT_HB_ENABLED |
+                             SSL_DTLSEXT_HB_DONT_SEND_REQUESTS);
+#endif
+
+    s->tlsext_use_etm = 0;
+
+    s->s3->flags &= ~TLS1_FLAGS_RECEIVED_EXTMS;
+
+    if (!PACKET_get_net_2(pkt, &length))
+        goto ri_check;
+
+    if (PACKET_remaining(pkt) != length) {
+        *al = SSL_AD_DECODE_ERROR;
+        return 0;
+    }
+
+    if (!tls1_check_duplicate_extensions(pkt)) {
+        *al = SSL_AD_DECODE_ERROR;
+        return 0;
+    }
+
+    while (PACKET_get_net_2(pkt, &type) && PACKET_get_net_2(pkt, &size)) {
+        const unsigned char *data;
+        PACKET spkt;
+
+        if (!PACKET_get_sub_packet(pkt, &spkt, size)
+            || !PACKET_peek_bytes(&spkt, &data, size))
+            goto ri_check;
+
+        if (s->tlsext_debug_cb)
+            s->tlsext_debug_cb(s, 1, type, data, size, s->tlsext_debug_arg);
+
+        if (type == TLSEXT_TYPE_renegotiate) {
+            if (!ssl_parse_serverhello_renegotiate_ext(s, &spkt, al))
+                return 0;
+            renegotiate_seen = 1;
+        } else if (s->version == SSL3_VERSION) {
+        } else if (type == TLSEXT_TYPE_server_name) {
+            if (s->tlsext_hostname == NULL || size > 0) {
+                *al = TLS1_AD_UNRECOGNIZED_NAME;
+                return 0;
+            }
+            tlsext_servername = 1;
+        }
+#ifndef OPENSSL_NO_EC
+        else if (type == TLSEXT_TYPE_ec_point_formats) {
+            unsigned int ecpointformatlist_length;
+            if (!PACKET_get_1(&spkt, &ecpointformatlist_length)
+                || ecpointformatlist_length != size - 1) {
+                *al = TLS1_AD_DECODE_ERROR;
+                return 0;
+            }
+            if (!s->hit) {
+                s->session->tlsext_ecpointformatlist_length = 0;
+                OPENSSL_free(s->session->tlsext_ecpointformatlist);
+                if ((s->session->tlsext_ecpointformatlist =
+                     OPENSSL_malloc(ecpointformatlist_length)) == NULL) {
+                    *al = TLS1_AD_INTERNAL_ERROR;
+                    return 0;
+                }
+                s->session->tlsext_ecpointformatlist_length =
+                    ecpointformatlist_length;
+                if (!PACKET_copy_bytes(&spkt,
+                                       s->session->tlsext_ecpointformatlist,
+                                       ecpointformatlist_length)) {
+                    *al = TLS1_AD_DECODE_ERROR;
+                    return 0;
+                }
+
+            }
+        }
+#endif                          /* OPENSSL_NO_EC */
+
+        else if (type == TLSEXT_TYPE_session_ticket) {
+            if (s->tls_session_ticket_ext_cb &&
+                !s->tls_session_ticket_ext_cb(s, data, size,
+                                              s->tls_session_ticket_ext_cb_arg))
+            {
+                *al = TLS1_AD_INTERNAL_ERROR;
+                return 0;
+            }
+            if (!tls_use_ticket(s) || (size > 0)) {
+                *al = TLS1_AD_UNSUPPORTED_EXTENSION;
+                return 0;
+            }
+            s->tlsext_ticket_expected = 1;
+        } else if (type == TLSEXT_TYPE_status_request) {
+            /*
+             * MUST be empty and only sent if we've requested a status
+             * request message.
+             */
+            if ((s->tlsext_status_type == -1) || (size > 0)) {
+                *al = TLS1_AD_UNSUPPORTED_EXTENSION;
+                return 0;
+            }
+            /* Set flag to expect CertificateStatus message */
+            s->tlsext_status_expected = 1;
+        }
+#ifndef OPENSSL_NO_CT
+        /*
+         * Only take it if we asked for it - i.e if there is no CT validation
+         * callback set, then a custom extension MAY be processing it, so we
+         * need to let control continue to flow to that.
+         */
+        else if (type == TLSEXT_TYPE_signed_certificate_timestamp &&
+                 s->ct_validation_callback != NULL) {
+            /* Simply copy it off for later processing */
+            if (s->tlsext_scts != NULL) {
+                OPENSSL_free(s->tlsext_scts);
+                s->tlsext_scts = NULL;
+            }
+            s->tlsext_scts_len = size;
+            if (size > 0) {
+                s->tlsext_scts = OPENSSL_malloc(size);
+                if (s->tlsext_scts == NULL) {
+                    *al = TLS1_AD_INTERNAL_ERROR;
+                    return 0;
+                }
+                memcpy(s->tlsext_scts, data, size);
+            }
+        }
+#endif
+#ifndef OPENSSL_NO_NEXTPROTONEG
+        else if (type == TLSEXT_TYPE_next_proto_neg &&
+                 s->s3->tmp.finish_md_len == 0) {
+            unsigned char *selected;
+            unsigned char selected_len;
+            /* We must have requested it. */
+            if (s->ctx->next_proto_select_cb == NULL) {
+                *al = TLS1_AD_UNSUPPORTED_EXTENSION;
+                return 0;
+            }
+            /* The data must be valid */
+            if (!ssl_next_proto_validate(&spkt)) {
+                *al = TLS1_AD_DECODE_ERROR;
+                return 0;
+            }
+            if (s->ctx->next_proto_select_cb(s, &selected, &selected_len, data,
+                                             size,
+                                             s->
+                                             ctx->next_proto_select_cb_arg) !=
+                SSL_TLSEXT_ERR_OK) {
+                *al = TLS1_AD_INTERNAL_ERROR;
+                return 0;
+            }
+            /*
+             * Could be non-NULL if server has sent multiple NPN extensions in
+             * a single Serverhello
+             */
+            OPENSSL_free(s->next_proto_negotiated);
+            s->next_proto_negotiated = OPENSSL_malloc(selected_len);
+            if (s->next_proto_negotiated == NULL) {
+                *al = TLS1_AD_INTERNAL_ERROR;
+                return 0;
+            }
+            memcpy(s->next_proto_negotiated, selected, selected_len);
+            s->next_proto_negotiated_len = selected_len;
+            s->s3->next_proto_neg_seen = 1;
+        }
+#endif
+
+        else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation) {
+            unsigned len;
+            /* We must have requested it. */
+            if (!s->s3->alpn_sent) {
+                *al = TLS1_AD_UNSUPPORTED_EXTENSION;
+                return 0;
+            }
+            /*-
+             * The extension data consists of:
+             *   uint16 list_length
+             *   uint8 proto_length;
+             *   uint8 proto[proto_length];
+             */
+            if (!PACKET_get_net_2(&spkt, &len)
+                || PACKET_remaining(&spkt) != len || !PACKET_get_1(&spkt, &len)
+                || PACKET_remaining(&spkt) != len) {
+                *al = TLS1_AD_DECODE_ERROR;
+                return 0;
+            }
+            OPENSSL_free(s->s3->alpn_selected);
+            s->s3->alpn_selected = OPENSSL_malloc(len);
+            if (s->s3->alpn_selected == NULL) {
+                *al = TLS1_AD_INTERNAL_ERROR;
+                return 0;
+            }
+            if (!PACKET_copy_bytes(&spkt, s->s3->alpn_selected, len)) {
+                *al = TLS1_AD_DECODE_ERROR;
+                return 0;
+            }
+            s->s3->alpn_selected_len = len;
+        }
+#ifndef OPENSSL_NO_HEARTBEATS
+        else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_heartbeat) {
+            unsigned int hbtype;
+            if (!PACKET_get_1(&spkt, &hbtype)) {
+                *al = SSL_AD_DECODE_ERROR;
+                return 0;
+            }
+            switch (hbtype) {
+            case 0x01:         /* Server allows us to send HB requests */
+                s->tlsext_heartbeat |= SSL_DTLSEXT_HB_ENABLED;
+                break;
+            case 0x02:         /* Server doesn't accept HB requests */
+                s->tlsext_heartbeat |= SSL_DTLSEXT_HB_ENABLED;
+                s->tlsext_heartbeat |= SSL_DTLSEXT_HB_DONT_SEND_REQUESTS;
+                break;
+            default:
+                *al = SSL_AD_ILLEGAL_PARAMETER;
+                return 0;
+            }
+        }
+#endif
+#ifndef OPENSSL_NO_SRTP
+        else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) {
+            if (ssl_parse_serverhello_use_srtp_ext(s, &spkt, al))
+                return 0;
+        }
+#endif
+        else if (type == TLSEXT_TYPE_encrypt_then_mac) {
+            /* Ignore if inappropriate ciphersuite */
+            if (s->s3->tmp.new_cipher->algorithm_mac != SSL_AEAD
+                && s->s3->tmp.new_cipher->algorithm_enc != SSL_RC4)
+                s->tlsext_use_etm = 1;
+        } else if (type == TLSEXT_TYPE_extended_master_secret) {
+            s->s3->flags |= TLS1_FLAGS_RECEIVED_EXTMS;
+            if (!s->hit)
+                s->session->flags |= SSL_SESS_FLAG_EXTMS;
+        }
+        /*
+         * If this extension type was not otherwise handled, but matches a
+         * custom_cli_ext_record, then send it to the c callback
+         */
+        else if (custom_ext_parse(s, 0, type, data, size, al) <= 0)
+            return 0;
+    }
+
+    if (PACKET_remaining(pkt) != 0) {
+        *al = SSL_AD_DECODE_ERROR;
+        return 0;
+    }
+
+    if (!s->hit && tlsext_servername == 1) {
+        if (s->tlsext_hostname) {
+            if (s->session->tlsext_hostname == NULL) {
+                s->session->tlsext_hostname =
+                    OPENSSL_strdup(s->tlsext_hostname);
+                if (!s->session->tlsext_hostname) {
+                    *al = SSL_AD_UNRECOGNIZED_NAME;
+                    return 0;
+                }
+            } else {
+                *al = SSL_AD_DECODE_ERROR;
+                return 0;
+            }
+        }
+    }
+
+ ri_check:
+
+    /*
+     * Determine if we need to see RI. Strictly speaking if we want to avoid
+     * an attack we should *always* see RI even on initial server hello
+     * because the client doesn't see any renegotiation during an attack.
+     * However this would mean we could not connect to any server which
+     * doesn't support RI so for the immediate future tolerate RI absence
+     */
+    if (!renegotiate_seen && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT)
+        && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT,
+               SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+        return 0;
+    }
+
+    if (s->hit) {
+        /*
+         * Check extended master secret extension is consistent with
+         * original session.
+         */
+        if (!(s->s3->flags & TLS1_FLAGS_RECEIVED_EXTMS) !=
+            !(s->session->flags & SSL_SESS_FLAG_EXTMS)) {
+            *al = SSL_AD_HANDSHAKE_FAILURE;
+            SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, SSL_R_INCONSISTENT_EXTMS);
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+int ssl_prepare_clienthello_tlsext(SSL *s)
+{
+    s->s3->alpn_sent = 0;
+    return 1;
+}
+
+int ssl_prepare_serverhello_tlsext(SSL *s)
+{
+    return 1;
+}
+
+static int ssl_check_clienthello_tlsext_early(SSL *s)
+{
+    int ret = SSL_TLSEXT_ERR_NOACK;
+    int al = SSL_AD_UNRECOGNIZED_NAME;
+
+#ifndef OPENSSL_NO_EC
+    /*
+     * The handling of the ECPointFormats extension is done elsewhere, namely
+     * in ssl3_choose_cipher in s3_lib.c.
+     */
+    /*
+     * The handling of the EllipticCurves extension is done elsewhere, namely
+     * in ssl3_choose_cipher in s3_lib.c.
+     */
+#endif
+
+    if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
+        ret =
+            s->ctx->tlsext_servername_callback(s, &al,
+                                               s->ctx->tlsext_servername_arg);
+    else if (s->session_ctx != NULL
+             && s->session_ctx->tlsext_servername_callback != 0)
+        ret =
+            s->session_ctx->tlsext_servername_callback(s, &al,
+                                                       s->
+                                                       session_ctx->tlsext_servername_arg);
+
+    switch (ret) {
+    case SSL_TLSEXT_ERR_ALERT_FATAL:
+        ssl3_send_alert(s, SSL3_AL_FATAL, al);
+        return -1;
+
+    case SSL_TLSEXT_ERR_ALERT_WARNING:
+        ssl3_send_alert(s, SSL3_AL_WARNING, al);
+        return 1;
+
+    case SSL_TLSEXT_ERR_NOACK:
+        s->servername_done = 0;
+    default:
+        return 1;
+    }
+}
+
+/* Initialise digests to default values */
+void ssl_set_default_md(SSL *s)
+{
+    const EVP_MD **pmd = s->s3->tmp.md;
+#ifndef OPENSSL_NO_DSA
+    pmd[SSL_PKEY_DSA_SIGN] = ssl_md(SSL_MD_SHA1_IDX);
+#endif
+#ifndef OPENSSL_NO_RSA
+    if (SSL_USE_SIGALGS(s))
+        pmd[SSL_PKEY_RSA_SIGN] = ssl_md(SSL_MD_SHA1_IDX);
+    else
+        pmd[SSL_PKEY_RSA_SIGN] = ssl_md(SSL_MD_MD5_SHA1_IDX);
+    pmd[SSL_PKEY_RSA_ENC] = pmd[SSL_PKEY_RSA_SIGN];
+#endif
+#ifndef OPENSSL_NO_EC
+    pmd[SSL_PKEY_ECC] = ssl_md(SSL_MD_SHA1_IDX);
+#endif
+#ifndef OPENSSL_NO_GOST
+    pmd[SSL_PKEY_GOST01] = ssl_md(SSL_MD_GOST94_IDX);
+    pmd[SSL_PKEY_GOST12_256] = ssl_md(SSL_MD_GOST12_256_IDX);
+    pmd[SSL_PKEY_GOST12_512] = ssl_md(SSL_MD_GOST12_512_IDX);
+#endif
+}
+
+int tls1_set_server_sigalgs(SSL *s)
+{
+    int al;
+    size_t i;
+
+    /* Clear any shared signature algorithms */
+    OPENSSL_free(s->cert->shared_sigalgs);
+    s->cert->shared_sigalgs = NULL;
+    s->cert->shared_sigalgslen = 0;
+    /* Clear certificate digests and validity flags */
+    for (i = 0; i < SSL_PKEY_NUM; i++) {
+        s->s3->tmp.md[i] = NULL;
+        s->s3->tmp.valid_flags[i] = 0;
+    }
+
+    /* If sigalgs received process it. */
+    if (s->s3->tmp.peer_sigalgs) {
+        if (!tls1_process_sigalgs(s)) {
+            SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_MALLOC_FAILURE);
+            al = SSL_AD_INTERNAL_ERROR;
+            goto err;
+        }
+        /* Fatal error is no shared signature algorithms */
+        if (!s->cert->shared_sigalgs) {
+            SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS,
+                   SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS);
+            al = SSL_AD_ILLEGAL_PARAMETER;
+            goto err;
+        }
+    } else {
+        ssl_set_default_md(s);
+    }
+    return 1;
+ err:
+    ssl3_send_alert(s, SSL3_AL_FATAL, al);
+    return 0;
+}
+
+/*
+ * Upon success, returns 1.
+ * Upon failure, returns 0 and sets |al| to the appropriate fatal alert.
+ */
+int ssl_check_clienthello_tlsext_late(SSL *s, int *al)
+{
+    s->tlsext_status_expected = 0;
+
+    /*
+     * If status request then ask callback what to do. Note: this must be
+     * called after servername callbacks in case the certificate has changed,
+     * and must be called after the cipher has been chosen because this may
+     * influence which certificate is sent
+     */
+    if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) {
+        int ret;
+        CERT_PKEY *certpkey;
+        certpkey = ssl_get_server_send_pkey(s);
+        /* If no certificate can't return certificate status */
+        if (certpkey != NULL) {
+            /*
+             * Set current certificate to one we will use so SSL_get_certificate
+             * et al can pick it up.
+             */
+            s->cert->key = certpkey;
+            ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
+            switch (ret) {
+                /* We don't want to send a status request response */
+            case SSL_TLSEXT_ERR_NOACK:
+                s->tlsext_status_expected = 0;
+                break;
+                /* status request response should be sent */
+            case SSL_TLSEXT_ERR_OK:
+                if (s->tlsext_ocsp_resp)
+                    s->tlsext_status_expected = 1;
+                break;
+                /* something bad happened */
+            case SSL_TLSEXT_ERR_ALERT_FATAL:
+            default:
+                *al = SSL_AD_INTERNAL_ERROR;
+                return 0;
+            }
+        }
+    }
+
+    if (!tls1_alpn_handle_client_hello_late(s, al)) {
+        return 0;
+    }
+
+    return 1;
+}
+
+int ssl_check_serverhello_tlsext(SSL *s)
+{
+    int ret = SSL_TLSEXT_ERR_NOACK;
+    int al = SSL_AD_UNRECOGNIZED_NAME;
+
+#ifndef OPENSSL_NO_EC
+    /*
+     * If we are client and using an elliptic curve cryptography cipher
+     * suite, then if server returns an EC point formats lists extension it
+     * must contain uncompressed.
+     */
+    unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+    unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth;
+    if ((s->tlsext_ecpointformatlist != NULL)
+        && (s->tlsext_ecpointformatlist_length > 0)
+        && (s->session->tlsext_ecpointformatlist != NULL)
+        && (s->session->tlsext_ecpointformatlist_length > 0)
+        && ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA))) {
+        /* we are using an ECC cipher */
+        size_t i;
+        unsigned char *list;
+        int found_uncompressed = 0;
+        list = s->session->tlsext_ecpointformatlist;
+        for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) {
+            if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed) {
+                found_uncompressed = 1;
+                break;
+            }
+        }
+        if (!found_uncompressed) {
+            SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT,
+                   SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
+            return -1;
+        }
+    }
+    ret = SSL_TLSEXT_ERR_OK;
+#endif                          /* OPENSSL_NO_EC */
+
+    if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0)
+        ret =
+            s->ctx->tlsext_servername_callback(s, &al,
+                                               s->ctx->tlsext_servername_arg);
+    else if (s->session_ctx != NULL
+             && s->session_ctx->tlsext_servername_callback != 0)
+        ret =
+            s->session_ctx->tlsext_servername_callback(s, &al,
+                                                       s->
+                                                       session_ctx->tlsext_servername_arg);
+
+    /*
+     * Ensure we get sensible values passed to tlsext_status_cb in the event
+     * that we don't receive a status message
+     */
+    OPENSSL_free(s->tlsext_ocsp_resp);
+    s->tlsext_ocsp_resp = NULL;
+    s->tlsext_ocsp_resplen = -1;
+
+    switch (ret) {
+    case SSL_TLSEXT_ERR_ALERT_FATAL:
+        ssl3_send_alert(s, SSL3_AL_FATAL, al);
+        return -1;
+
+    case SSL_TLSEXT_ERR_ALERT_WARNING:
+        ssl3_send_alert(s, SSL3_AL_WARNING, al);
+        return 1;
+
+    case SSL_TLSEXT_ERR_NOACK:
+        s->servername_done = 0;
+    default:
+        return 1;
+    }
+}
+
+int ssl_parse_serverhello_tlsext(SSL *s, PACKET *pkt)
+{
+    int al = -1;
+    if (s->version < SSL3_VERSION)
+        return 1;
+    if (ssl_scan_serverhello_tlsext(s, pkt, &al) <= 0) {
+        ssl3_send_alert(s, SSL3_AL_FATAL, al);
+        return 0;
+    }
+
+    if (ssl_check_serverhello_tlsext(s) <= 0) {
+        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, SSL_R_SERVERHELLO_TLSEXT);
+        return 0;
+    }
+    return 1;
+}
+
+/*-
+ * Since the server cache lookup is done early on in the processing of the
+ * ClientHello and other operations depend on the result some extensions
+ * need to be handled at the same time.
+ *
+ * Two extensions are currently handled, session ticket and extended master
+ * secret.
+ *
+ *   session_id: ClientHello session ID.
+ *   ext: ClientHello extensions (including length prefix)
+ *   ret: (output) on return, if a ticket was decrypted, then this is set to
+ *       point to the resulting session.
+ *
+ * If s->tls_session_secret_cb is set then we are expecting a pre-shared key
+ * ciphersuite, in which case we have no use for session tickets and one will
+ * never be decrypted, nor will s->tlsext_ticket_expected be set to 1.
+ *
+ * Returns:
+ *   -1: fatal error, either from parsing or decrypting the ticket.
+ *    0: no ticket was found (or was ignored, based on settings).
+ *    1: a zero length extension was found, indicating that the client supports
+ *       session tickets but doesn't currently have one to offer.
+ *    2: either s->tls_session_secret_cb was set, or a ticket was offered but
+ *       couldn't be decrypted because of a non-fatal error.
+ *    3: a ticket was successfully decrypted and *ret was set.
+ *
+ * Side effects:
+ *   Sets s->tlsext_ticket_expected to 1 if the server will have to issue
+ *   a new session ticket to the client because the client indicated support
+ *   (and s->tls_session_secret_cb is NULL) but the client either doesn't have
+ *   a session ticket or we couldn't use the one it gave us, or if
+ *   s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket.
+ *   Otherwise, s->tlsext_ticket_expected is set to 0.
+ *
+ *   For extended master secret flag is set if the extension is present.
+ *
+ */
+int tls_check_serverhello_tlsext_early(SSL *s, const PACKET *ext,
+                                       const PACKET *session_id,
+                                       SSL_SESSION **ret)
+{
+    unsigned int i;
+    PACKET local_ext = *ext;
+    int retv = -1;
+
+    int have_ticket = 0;
+    int use_ticket = tls_use_ticket(s);
+
+    *ret = NULL;
+    s->tlsext_ticket_expected = 0;
+    s->s3->flags &= ~TLS1_FLAGS_RECEIVED_EXTMS;
+
+    /*
+     * If tickets disabled behave as if no ticket present to permit stateful
+     * resumption.
+     */
+    if ((s->version <= SSL3_VERSION))
+        return 0;
+
+    if (!PACKET_get_net_2(&local_ext, &i)) {
+        retv = 0;
+        goto end;
+    }
+    while (PACKET_remaining(&local_ext) >= 4) {
+        unsigned int type, size;
+
+        if (!PACKET_get_net_2(&local_ext, &type)
+            || !PACKET_get_net_2(&local_ext, &size)) {
+            /* Shouldn't ever happen */
+            retv = -1;
+            goto end;
+        }
+        if (PACKET_remaining(&local_ext) < size) {
+            retv = 0;
+            goto end;
+        }
+        if (type == TLSEXT_TYPE_session_ticket && use_ticket) {
+            int r;
+            const unsigned char *etick;
+
+            /* Duplicate extension */
+            if (have_ticket != 0) {
+                retv = -1;
+                goto end;
+            }
+            have_ticket = 1;
+
+            if (size == 0) {
+                /*
+                 * The client will accept a ticket but doesn't currently have
+                 * one.
+                 */
+                s->tlsext_ticket_expected = 1;
+                retv = 1;
+                continue;
+            }
+            if (s->tls_session_secret_cb) {
+                /*
+                 * Indicate that the ticket couldn't be decrypted rather than
+                 * generating the session from ticket now, trigger
+                 * abbreviated handshake based on external mechanism to
+                 * calculate the master secret later.
+                 */
+                retv = 2;
+                continue;
+            }
+            if (!PACKET_get_bytes(&local_ext, &etick, size)) {
+                /* Shouldn't ever happen */
+                retv = -1;
+                goto end;
+            }
+            r = tls_decrypt_ticket(s, etick, size, PACKET_data(session_id),
+                                   PACKET_remaining(session_id), ret);
+            switch (r) {
+            case 2:            /* ticket couldn't be decrypted */
+                s->tlsext_ticket_expected = 1;
+                retv = 2;
+                break;
+            case 3:            /* ticket was decrypted */
+                retv = r;
+                break;
+            case 4:            /* ticket decrypted but need to renew */
+                s->tlsext_ticket_expected = 1;
+                retv = 3;
+                break;
+            default:           /* fatal error */
+                retv = -1;
+                break;
+            }
+            continue;
+        } else {
+            if (type == TLSEXT_TYPE_extended_master_secret)
+                s->s3->flags |= TLS1_FLAGS_RECEIVED_EXTMS;
+            if (!PACKET_forward(&local_ext, size)) {
+                retv = -1;
+                goto end;
+            }
+        }
+    }
+    if (have_ticket == 0)
+        retv = 0;
+ end:
+    return retv;
+}
+
+/*-
+ * tls_decrypt_ticket attempts to decrypt a session ticket.
+ *
+ *   etick: points to the body of the session ticket extension.
+ *   eticklen: the length of the session tickets extension.
+ *   sess_id: points at the session ID.
+ *   sesslen: the length of the session ID.
+ *   psess: (output) on return, if a ticket was decrypted, then this is set to
+ *       point to the resulting session.
+ *
+ * Returns:
+ *   -2: fatal error, malloc failure.
+ *   -1: fatal error, either from parsing or decrypting the ticket.
+ *    2: the ticket couldn't be decrypted.
+ *    3: a ticket was successfully decrypted and *psess was set.
+ *    4: same as 3, but the ticket needs to be renewed.
+ */
+static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
+                              int eticklen, const unsigned char *sess_id,
+                              int sesslen, SSL_SESSION **psess)
+{
+    SSL_SESSION *sess;
+    unsigned char *sdec;
+    const unsigned char *p;
+    int slen, mlen, renew_ticket = 0, ret = -1;
+    unsigned char tick_hmac[EVP_MAX_MD_SIZE];
+    HMAC_CTX *hctx = NULL;
+    EVP_CIPHER_CTX *ctx;
+    SSL_CTX *tctx = s->session_ctx;
+
+    /* Initialize session ticket encryption and HMAC contexts */
+    hctx = HMAC_CTX_new();
+    if (hctx == NULL)
+        return -2;
+    ctx = EVP_CIPHER_CTX_new();
+    if (ctx == NULL) {
+        ret = -2;
+        goto err;
+    }
+    if (tctx->tlsext_ticket_key_cb) {
+        unsigned char *nctick = (unsigned char *)etick;
+        int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16,
+                                            ctx, hctx, 0);
+        if (rv < 0)
+            goto err;
+        if (rv == 0) {
+            ret = 2;
+            goto err;
+        }
+        if (rv == 2)
+            renew_ticket = 1;
+    } else {
+        /* Check key name matches */
+        if (memcmp(etick, tctx->tlsext_tick_key_name,
+                   sizeof(tctx->tlsext_tick_key_name)) != 0) {
+            ret = 2;
+            goto err;
+        }
+        if (HMAC_Init_ex(hctx, tctx->tlsext_tick_hmac_key,
+                         sizeof(tctx->tlsext_tick_hmac_key),
+                         EVP_sha256(), NULL) <= 0
+            || EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL,
+                                  tctx->tlsext_tick_aes_key,
+                                  etick + sizeof(tctx->tlsext_tick_key_name)) <=
+            0) {
+            goto err;
+        }
+    }
+    /*
+     * Attempt to process session ticket, first conduct sanity and integrity
+     * checks on ticket.
+     */
+    mlen = HMAC_size(hctx);
+    if (mlen < 0) {
+        goto err;
+    }
+    /* Sanity check ticket length: must exceed keyname + IV + HMAC */
+    if (eticklen <=
+        TLSEXT_KEYNAME_LENGTH + EVP_CIPHER_CTX_iv_length(ctx) + mlen) {
+        ret = 2;
+        goto err;
+    }
+    eticklen -= mlen;
+    /* Check HMAC of encrypted ticket */
+    if (HMAC_Update(hctx, etick, eticklen) <= 0
+        || HMAC_Final(hctx, tick_hmac, NULL) <= 0) {
+        goto err;
+    }
+    HMAC_CTX_free(hctx);
+    if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) {
+        EVP_CIPHER_CTX_free(ctx);
+        return 2;
+    }
+    /* Attempt to decrypt session data */
+    /* Move p after IV to start of encrypted ticket, update length */
+    p = etick + TLSEXT_KEYNAME_LENGTH + EVP_CIPHER_CTX_iv_length(ctx);
+    eticklen -= TLSEXT_KEYNAME_LENGTH + EVP_CIPHER_CTX_iv_length(ctx);
+    sdec = OPENSSL_malloc(eticklen);
+    if (sdec == NULL || EVP_DecryptUpdate(ctx, sdec, &slen, p, eticklen) <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
+        OPENSSL_free(sdec);
+        return -1;
+    }
+    if (EVP_DecryptFinal(ctx, sdec + slen, &mlen) <= 0) {
+        EVP_CIPHER_CTX_free(ctx);
+        OPENSSL_free(sdec);
+        return 2;
+    }
+    slen += mlen;
+    EVP_CIPHER_CTX_free(ctx);
+    ctx = NULL;
+    p = sdec;
+
+    sess = d2i_SSL_SESSION(NULL, &p, slen);
+    OPENSSL_free(sdec);
+    if (sess) {
+        /*
+         * The session ID, if non-empty, is used by some clients to detect
+         * that the ticket has been accepted. So we copy it to the session
+         * structure. If it is empty set length to zero as required by
+         * standard.
+         */
+        if (sesslen)
+            memcpy(sess->session_id, sess_id, sesslen);
+        sess->session_id_length = sesslen;
+        *psess = sess;
+        if (renew_ticket)
+            return 4;
+        else
+            return 3;
+    }
+    ERR_clear_error();
+    /*
+     * For session parse failure, indicate that we need to send a new ticket.
+     */
+    return 2;
+ err:
+    EVP_CIPHER_CTX_free(ctx);
+    HMAC_CTX_free(hctx);
+    return ret;
+}
+
+/* Tables to translate from NIDs to TLS v1.2 ids */
+
+typedef struct {
+    int nid;
+    int id;
+} tls12_lookup;
+
+static const tls12_lookup tls12_md[] = {
+    {NID_md5, TLSEXT_hash_md5},
+    {NID_sha1, TLSEXT_hash_sha1},
+    {NID_sha224, TLSEXT_hash_sha224},
+    {NID_sha256, TLSEXT_hash_sha256},
+    {NID_sha384, TLSEXT_hash_sha384},
+    {NID_sha512, TLSEXT_hash_sha512},
+    {NID_id_GostR3411_94, TLSEXT_hash_gostr3411},
+    {NID_id_GostR3411_2012_256, TLSEXT_hash_gostr34112012_256},
+    {NID_id_GostR3411_2012_512, TLSEXT_hash_gostr34112012_512},
+};
+
+static const tls12_lookup tls12_sig[] = {
+    {EVP_PKEY_RSA, TLSEXT_signature_rsa},
+    {EVP_PKEY_DSA, TLSEXT_signature_dsa},
+    {EVP_PKEY_EC, TLSEXT_signature_ecdsa},
+    {NID_id_GostR3410_2001, TLSEXT_signature_gostr34102001},
+    {NID_id_GostR3410_2012_256, TLSEXT_signature_gostr34102012_256},
+    {NID_id_GostR3410_2012_512, TLSEXT_signature_gostr34102012_512}
+};
+
+static int tls12_find_id(int nid, const tls12_lookup *table, size_t tlen)
+{
+    size_t i;
+    for (i = 0; i < tlen; i++) {
+        if (table[i].nid == nid)
+            return table[i].id;
+    }
+    return -1;
+}
+
+static int tls12_find_nid(int id, const tls12_lookup *table, size_t tlen)
+{
+    size_t i;
+    for (i = 0; i < tlen; i++) {
+        if ((table[i].id) == id)
+            return table[i].nid;
+    }
+    return NID_undef;
+}
+
+int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, const EVP_MD *md)
+{
+    int sig_id, md_id;
+    if (!md)
+        return 0;
+    md_id = tls12_find_id(EVP_MD_type(md), tls12_md, OSSL_NELEM(tls12_md));
+    if (md_id == -1)
+        return 0;
+    sig_id = tls12_get_sigid(pk);
+    if (sig_id == -1)
+        return 0;
+    p[0] = (unsigned char)md_id;
+    p[1] = (unsigned char)sig_id;
+    return 1;
+}
+
+int tls12_get_sigid(const EVP_PKEY *pk)
+{
+    return tls12_find_id(EVP_PKEY_id(pk), tls12_sig, OSSL_NELEM(tls12_sig));
+}
+
+typedef struct {
+    int nid;
+    int secbits;
+    int md_idx;
+    unsigned char tlsext_hash;
+} tls12_hash_info;
+
+static const tls12_hash_info tls12_md_info[] = {
+    {NID_md5, 64, SSL_MD_MD5_IDX, TLSEXT_hash_md5},
+    {NID_sha1, 80, SSL_MD_SHA1_IDX, TLSEXT_hash_sha1},
+    {NID_sha224, 112, SSL_MD_SHA224_IDX, TLSEXT_hash_sha224},
+    {NID_sha256, 128, SSL_MD_SHA256_IDX, TLSEXT_hash_sha256},
+    {NID_sha384, 192, SSL_MD_SHA384_IDX, TLSEXT_hash_sha384},
+    {NID_sha512, 256, SSL_MD_SHA512_IDX, TLSEXT_hash_sha512},
+    {NID_id_GostR3411_94, 128, SSL_MD_GOST94_IDX, TLSEXT_hash_gostr3411},
+    {NID_id_GostR3411_2012_256, 128, SSL_MD_GOST12_256_IDX,
+     TLSEXT_hash_gostr34112012_256},
+    {NID_id_GostR3411_2012_512, 256, SSL_MD_GOST12_512_IDX,
+     TLSEXT_hash_gostr34112012_512},
+};
+
+static const tls12_hash_info *tls12_get_hash_info(unsigned char hash_alg)
+{
+    unsigned int i;
+    if (hash_alg == 0)
+        return NULL;
+
+    for (i = 0; i < OSSL_NELEM(tls12_md_info); i++) {
+        if (tls12_md_info[i].tlsext_hash == hash_alg)
+            return tls12_md_info + i;
+    }
+
+    return NULL;
+}
+
+const EVP_MD *tls12_get_hash(unsigned char hash_alg)
+{
+    const tls12_hash_info *inf;
+    if (hash_alg == TLSEXT_hash_md5 && FIPS_mode())
+        return NULL;
+    inf = tls12_get_hash_info(hash_alg);
+    if (!inf)
+        return NULL;
+    return ssl_md(inf->md_idx);
+}
+
+static int tls12_get_pkey_idx(unsigned char sig_alg)
+{
+    switch (sig_alg) {
+#ifndef OPENSSL_NO_RSA
+    case TLSEXT_signature_rsa:
+        return SSL_PKEY_RSA_SIGN;
+#endif
+#ifndef OPENSSL_NO_DSA
+    case TLSEXT_signature_dsa:
+        return SSL_PKEY_DSA_SIGN;
+#endif
+#ifndef OPENSSL_NO_EC
+    case TLSEXT_signature_ecdsa:
+        return SSL_PKEY_ECC;
+#endif
+#ifndef OPENSSL_NO_GOST
+    case TLSEXT_signature_gostr34102001:
+        return SSL_PKEY_GOST01;
+
+    case TLSEXT_signature_gostr34102012_256:
+        return SSL_PKEY_GOST12_256;
+
+    case TLSEXT_signature_gostr34102012_512:
+        return SSL_PKEY_GOST12_512;
+#endif
+    }
+    return -1;
+}
+
+/* Convert TLS 1.2 signature algorithm extension values into NIDs */
+static void tls1_lookup_sigalg(int *phash_nid, int *psign_nid,
+                               int *psignhash_nid, const unsigned char *data)
+{
+    int sign_nid = NID_undef, hash_nid = NID_undef;
+    if (!phash_nid && !psign_nid && !psignhash_nid)
+        return;
+    if (phash_nid || psignhash_nid) {
+        hash_nid = tls12_find_nid(data[0], tls12_md, OSSL_NELEM(tls12_md));
+        if (phash_nid)
+            *phash_nid = hash_nid;
+    }
+    if (psign_nid || psignhash_nid) {
+        sign_nid = tls12_find_nid(data[1], tls12_sig, OSSL_NELEM(tls12_sig));
+        if (psign_nid)
+            *psign_nid = sign_nid;
+    }
+    if (psignhash_nid) {
+        if (sign_nid == NID_undef || hash_nid == NID_undef
+            || OBJ_find_sigid_by_algs(psignhash_nid, hash_nid, sign_nid) <= 0)
+            *psignhash_nid = NID_undef;
+    }
+}
+
+/* Check to see if a signature algorithm is allowed */
+static int tls12_sigalg_allowed(SSL *s, int op, const unsigned char *ptmp)
+{
+    /* See if we have an entry in the hash table and it is enabled */
+    const tls12_hash_info *hinf = tls12_get_hash_info(ptmp[0]);
+    if (hinf == NULL || ssl_md(hinf->md_idx) == NULL)
+        return 0;
+    /* See if public key algorithm allowed */
+    if (tls12_get_pkey_idx(ptmp[1]) == -1)
+        return 0;
+    /* Finally see if security callback allows it */
+    return ssl_security(s, op, hinf->secbits, hinf->nid, (void *)ptmp);
+}
+
+/*
+ * Get a mask of disabled public key algorithms based on supported signature
+ * algorithms. For example if no signature algorithm supports RSA then RSA is
+ * disabled.
+ */
+
+void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op)
+{
+    const unsigned char *sigalgs;
+    size_t i, sigalgslen;
+    int have_rsa = 0, have_dsa = 0, have_ecdsa = 0;
+    /*
+     * Now go through all signature algorithms seeing if we support any for
+     * RSA, DSA, ECDSA. Do this for all versions not just TLS 1.2. To keep
+     * down calls to security callback only check if we have to.
+     */
+    sigalgslen = tls12_get_psigalgs(s, 1, &sigalgs);
+    for (i = 0; i < sigalgslen; i += 2, sigalgs += 2) {
+        switch (sigalgs[1]) {
+#ifndef OPENSSL_NO_RSA
+        case TLSEXT_signature_rsa:
+            if (!have_rsa && tls12_sigalg_allowed(s, op, sigalgs))
+                have_rsa = 1;
+            break;
+#endif
+#ifndef OPENSSL_NO_DSA
+        case TLSEXT_signature_dsa:
+            if (!have_dsa && tls12_sigalg_allowed(s, op, sigalgs))
+                have_dsa = 1;
+            break;
+#endif
+#ifndef OPENSSL_NO_EC
+        case TLSEXT_signature_ecdsa:
+            if (!have_ecdsa && tls12_sigalg_allowed(s, op, sigalgs))
+                have_ecdsa = 1;
+            break;
+#endif
+        }
+    }
+    if (!have_rsa)
+        *pmask_a |= SSL_aRSA;
+    if (!have_dsa)
+        *pmask_a |= SSL_aDSS;
+    if (!have_ecdsa)
+        *pmask_a |= SSL_aECDSA;
+}
+
+size_t tls12_copy_sigalgs(SSL *s, unsigned char *out,
+                          const unsigned char *psig, size_t psiglen)
+{
+    unsigned char *tmpout = out;
+    size_t i;
+    for (i = 0; i < psiglen; i += 2, psig += 2) {
+        if (tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, psig)) {
+            *tmpout++ = psig[0];
+            *tmpout++ = psig[1];
+        }
+    }
+    return tmpout - out;
+}
+
+/* Given preference and allowed sigalgs set shared sigalgs */
+static int tls12_shared_sigalgs(SSL *s, TLS_SIGALGS *shsig,
+                                const unsigned char *pref, size_t preflen,
+                                const unsigned char *allow, size_t allowlen)
+{
+    const unsigned char *ptmp, *atmp;
+    size_t i, j, nmatch = 0;
+    for (i = 0, ptmp = pref; i < preflen; i += 2, ptmp += 2) {
+        /* Skip disabled hashes or signature algorithms */
+        if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SHARED, ptmp))
+            continue;
+        for (j = 0, atmp = allow; j < allowlen; j += 2, atmp += 2) {
+            if (ptmp[0] == atmp[0] && ptmp[1] == atmp[1]) {
+                nmatch++;
+                if (shsig) {
+                    shsig->rhash = ptmp[0];
+                    shsig->rsign = ptmp[1];
+                    tls1_lookup_sigalg(&shsig->hash_nid,
+                                       &shsig->sign_nid,
+                                       &shsig->signandhash_nid, ptmp);
+                    shsig++;
+                }
+                break;
+            }
+        }
+    }
+    return nmatch;
+}
+
+/* Set shared signature algorithms for SSL structures */
+static int tls1_set_shared_sigalgs(SSL *s)
+{
+    const unsigned char *pref, *allow, *conf;
+    size_t preflen, allowlen, conflen;
+    size_t nmatch;
+    TLS_SIGALGS *salgs = NULL;
+    CERT *c = s->cert;
+    unsigned int is_suiteb = tls1_suiteb(s);
+
+    OPENSSL_free(c->shared_sigalgs);
+    c->shared_sigalgs = NULL;
+    c->shared_sigalgslen = 0;
+    /* If client use client signature algorithms if not NULL */
+    if (!s->server && c->client_sigalgs && !is_suiteb) {
+        conf = c->client_sigalgs;
+        conflen = c->client_sigalgslen;
+    } else if (c->conf_sigalgs && !is_suiteb) {
+        conf = c->conf_sigalgs;
+        conflen = c->conf_sigalgslen;
+    } else
+        conflen = tls12_get_psigalgs(s, 0, &conf);
+    if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) {
+        pref = conf;
+        preflen = conflen;
+        allow = s->s3->tmp.peer_sigalgs;
+        allowlen = s->s3->tmp.peer_sigalgslen;
+    } else {
+        allow = conf;
+        allowlen = conflen;
+        pref = s->s3->tmp.peer_sigalgs;
+        preflen = s->s3->tmp.peer_sigalgslen;
+    }
+    nmatch = tls12_shared_sigalgs(s, NULL, pref, preflen, allow, allowlen);
+    if (nmatch) {
+        salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS));
+        if (salgs == NULL)
+            return 0;
+        nmatch = tls12_shared_sigalgs(s, salgs, pref, preflen, allow, allowlen);
+    } else {
+        salgs = NULL;
+    }
+    c->shared_sigalgs = salgs;
+    c->shared_sigalgslen = nmatch;
+    return 1;
+}
+
+/* Set preferred digest for each key type */
+
+int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize)
+{
+    CERT *c = s->cert;
+    /* Extension ignored for inappropriate versions */
+    if (!SSL_USE_SIGALGS(s))
+        return 1;
+    /* Should never happen */
+    if (!c)
+        return 0;
+
+    OPENSSL_free(s->s3->tmp.peer_sigalgs);
+    s->s3->tmp.peer_sigalgs = OPENSSL_malloc(dsize);
+    if (s->s3->tmp.peer_sigalgs == NULL)
+        return 0;
+    s->s3->tmp.peer_sigalgslen = dsize;
+    memcpy(s->s3->tmp.peer_sigalgs, data, dsize);
+    return 1;
+}
+
+int tls1_process_sigalgs(SSL *s)
+{
+    int idx;
+    size_t i;
+    const EVP_MD *md;
+    const EVP_MD **pmd = s->s3->tmp.md;
+    uint32_t *pvalid = s->s3->tmp.valid_flags;
+    CERT *c = s->cert;
+    TLS_SIGALGS *sigptr;
+    if (!tls1_set_shared_sigalgs(s))
+        return 0;
+
+    for (i = 0, sigptr = c->shared_sigalgs;
+         i < c->shared_sigalgslen; i++, sigptr++) {
+        idx = tls12_get_pkey_idx(sigptr->rsign);
+        if (idx > 0 && pmd[idx] == NULL) {
+            md = tls12_get_hash(sigptr->rhash);
+            pmd[idx] = md;
+            pvalid[idx] = CERT_PKEY_EXPLICIT_SIGN;
+            if (idx == SSL_PKEY_RSA_SIGN) {
+                pvalid[SSL_PKEY_RSA_ENC] = CERT_PKEY_EXPLICIT_SIGN;
+                pmd[SSL_PKEY_RSA_ENC] = md;
+            }
+        }
+
+    }
+    /*
+     * In strict mode leave unset digests as NULL to indicate we can't use
+     * the certificate for signing.
+     */
+    if (!(s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) {
+        /*
+         * Set any remaining keys to default values. NOTE: if alg is not
+         * supported it stays as NULL.
+         */
+#ifndef OPENSSL_NO_DSA
+        if (pmd[SSL_PKEY_DSA_SIGN] == NULL)
+            pmd[SSL_PKEY_DSA_SIGN] = EVP_sha1();
+#endif
+#ifndef OPENSSL_NO_RSA
+        if (pmd[SSL_PKEY_RSA_SIGN] == NULL) {
+            pmd[SSL_PKEY_RSA_SIGN] = EVP_sha1();
+            pmd[SSL_PKEY_RSA_ENC] = EVP_sha1();
+        }
+#endif
+#ifndef OPENSSL_NO_EC
+        if (pmd[SSL_PKEY_ECC] == NULL)
+            pmd[SSL_PKEY_ECC] = EVP_sha1();
+#endif
+#ifndef OPENSSL_NO_GOST
+        if (pmd[SSL_PKEY_GOST01] == NULL)
+            pmd[SSL_PKEY_GOST01] = EVP_get_digestbynid(NID_id_GostR3411_94);
+        if (pmd[SSL_PKEY_GOST12_256] == NULL)
+            pmd[SSL_PKEY_GOST12_256] =
+                EVP_get_digestbynid(NID_id_GostR3411_2012_256);
+        if (pmd[SSL_PKEY_GOST12_512] == NULL)
+            pmd[SSL_PKEY_GOST12_512] =
+                EVP_get_digestbynid(NID_id_GostR3411_2012_512);
+#endif
+    }
+    return 1;
+}
+
+int SSL_get_sigalgs(SSL *s, int idx,
+                    int *psign, int *phash, int *psignhash,
+                    unsigned char *rsig, unsigned char *rhash)
+{
+    const unsigned char *psig = s->s3->tmp.peer_sigalgs;
+    if (psig == NULL)
+        return 0;
+    if (idx >= 0) {
+        idx <<= 1;
+        if (idx >= (int)s->s3->tmp.peer_sigalgslen)
+            return 0;
+        psig += idx;
+        if (rhash)
+            *rhash = psig[0];
+        if (rsig)
+            *rsig = psig[1];
+        tls1_lookup_sigalg(phash, psign, psignhash, psig);
+    }
+    return s->s3->tmp.peer_sigalgslen / 2;
+}
+
+int SSL_get_shared_sigalgs(SSL *s, int idx,
+                           int *psign, int *phash, int *psignhash,
+                           unsigned char *rsig, unsigned char *rhash)
+{
+    TLS_SIGALGS *shsigalgs = s->cert->shared_sigalgs;
+    if (!shsigalgs || idx >= (int)s->cert->shared_sigalgslen)
+        return 0;
+    shsigalgs += idx;
+    if (phash)
+        *phash = shsigalgs->hash_nid;
+    if (psign)
+        *psign = shsigalgs->sign_nid;
+    if (psignhash)
+        *psignhash = shsigalgs->signandhash_nid;
+    if (rsig)
+        *rsig = shsigalgs->rsign;
+    if (rhash)
+        *rhash = shsigalgs->rhash;
+    return s->cert->shared_sigalgslen;
+}
+
+#define MAX_SIGALGLEN   (TLSEXT_hash_num * TLSEXT_signature_num * 2)
+
+typedef struct {
+    size_t sigalgcnt;
+    int sigalgs[MAX_SIGALGLEN];
+} sig_cb_st;
+
+static void get_sigorhash(int *psig, int *phash, const char *str)
+{
+    if (strcmp(str, "RSA") == 0) {
+        *psig = EVP_PKEY_RSA;
+    } else if (strcmp(str, "DSA") == 0) {
+        *psig = EVP_PKEY_DSA;
+    } else if (strcmp(str, "ECDSA") == 0) {
+        *psig = EVP_PKEY_EC;
+    } else {
+        *phash = OBJ_sn2nid(str);
+        if (*phash == NID_undef)
+            *phash = OBJ_ln2nid(str);
+    }
+}
+
+static int sig_cb(const char *elem, int len, void *arg)
+{
+    sig_cb_st *sarg = arg;
+    size_t i;
+    char etmp[20], *p;
+    int sig_alg = NID_undef, hash_alg = NID_undef;
+    if (elem == NULL)
+        return 0;
+    if (sarg->sigalgcnt == MAX_SIGALGLEN)
+        return 0;
+    if (len > (int)(sizeof(etmp) - 1))
+        return 0;
+    memcpy(etmp, elem, len);
+    etmp[len] = 0;
+    p = strchr(etmp, '+');
+    if (!p)
+        return 0;
+    *p = 0;
+    p++;
+    if (!*p)
+        return 0;
+
+    get_sigorhash(&sig_alg, &hash_alg, etmp);
+    get_sigorhash(&sig_alg, &hash_alg, p);
+
+    if (sig_alg == NID_undef || hash_alg == NID_undef)
+        return 0;
+
+    for (i = 0; i < sarg->sigalgcnt; i += 2) {
+        if (sarg->sigalgs[i] == sig_alg && sarg->sigalgs[i + 1] == hash_alg)
+            return 0;
+    }
+    sarg->sigalgs[sarg->sigalgcnt++] = hash_alg;
+    sarg->sigalgs[sarg->sigalgcnt++] = sig_alg;
+    return 1;
+}
+
+/*
+ * Set supported signature algorithms based on a colon separated list of the
+ * form sig+hash e.g. RSA+SHA512:DSA+SHA512
+ */
+int tls1_set_sigalgs_list(CERT *c, const char *str, int client)
+{
+    sig_cb_st sig;
+    sig.sigalgcnt = 0;
+    if (!CONF_parse_list(str, ':', 1, sig_cb, &sig))
+        return 0;
+    if (c == NULL)
+        return 1;
+    return tls1_set_sigalgs(c, sig.sigalgs, sig.sigalgcnt, client);
+}
+
+int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client)
+{
+    unsigned char *sigalgs, *sptr;
+    int rhash, rsign;
+    size_t i;
+    if (salglen & 1)
+        return 0;
+    sigalgs = OPENSSL_malloc(salglen);
+    if (sigalgs == NULL)
+        return 0;
+    for (i = 0, sptr = sigalgs; i < salglen; i += 2) {
+        rhash = tls12_find_id(*psig_nids++, tls12_md, OSSL_NELEM(tls12_md));
+        rsign = tls12_find_id(*psig_nids++, tls12_sig, OSSL_NELEM(tls12_sig));
+
+        if (rhash == -1 || rsign == -1)
+            goto err;
+        *sptr++ = rhash;
+        *sptr++ = rsign;
+    }
+
+    if (client) {
+        OPENSSL_free(c->client_sigalgs);
+        c->client_sigalgs = sigalgs;
+        c->client_sigalgslen = salglen;
+    } else {
+        OPENSSL_free(c->conf_sigalgs);
+        c->conf_sigalgs = sigalgs;
+        c->conf_sigalgslen = salglen;
+    }
+
+    return 1;
+
+ err:
+    OPENSSL_free(sigalgs);
+    return 0;
+}
+
+static int tls1_check_sig_alg(CERT *c, X509 *x, int default_nid)
+{
+    int sig_nid;
+    size_t i;
+    if (default_nid == -1)
+        return 1;
+    sig_nid = X509_get_signature_nid(x);
+    if (default_nid)
+        return sig_nid == default_nid ? 1 : 0;
+    for (i = 0; i < c->shared_sigalgslen; i++)
+        if (sig_nid == c->shared_sigalgs[i].signandhash_nid)
+            return 1;
+    return 0;
+}
+
+/* Check to see if a certificate issuer name matches list of CA names */
+static int ssl_check_ca_name(STACK_OF(X509_NAME) *names, X509 *x)
+{
+    X509_NAME *nm;
+    int i;
+    nm = X509_get_issuer_name(x);
+    for (i = 0; i < sk_X509_NAME_num(names); i++) {
+        if (!X509_NAME_cmp(nm, sk_X509_NAME_value(names, i)))
+            return 1;
+    }
+    return 0;
+}
+
+/*
+ * Check certificate chain is consistent with TLS extensions and is usable by
+ * server. This servers two purposes: it allows users to check chains before
+ * passing them to the server and it allows the server to check chains before
+ * attempting to use them.
+ */
+
+/* Flags which need to be set for a certificate when stict mode not set */
+
+#define CERT_PKEY_VALID_FLAGS \
+        (CERT_PKEY_EE_SIGNATURE|CERT_PKEY_EE_PARAM)
+/* Strict mode flags */
+#define CERT_PKEY_STRICT_FLAGS \
+         (CERT_PKEY_VALID_FLAGS|CERT_PKEY_CA_SIGNATURE|CERT_PKEY_CA_PARAM \
+         | CERT_PKEY_ISSUER_NAME|CERT_PKEY_CERT_TYPE)
+
+int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain,
+                     int idx)
+{
+    int i;
+    int rv = 0;
+    int check_flags = 0, strict_mode;
+    CERT_PKEY *cpk = NULL;
+    CERT *c = s->cert;
+    uint32_t *pvalid;
+    unsigned int suiteb_flags = tls1_suiteb(s);
+    /* idx == -1 means checking server chains */
+    if (idx != -1) {
+        /* idx == -2 means checking client certificate chains */
+        if (idx == -2) {
+            cpk = c->key;
+            idx = cpk - c->pkeys;
+        } else
+            cpk = c->pkeys + idx;
+        pvalid = s->s3->tmp.valid_flags + idx;
+        x = cpk->x509;
+        pk = cpk->privatekey;
+        chain = cpk->chain;
+        strict_mode = c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT;
+        /* If no cert or key, forget it */
+        if (!x || !pk)
+            goto end;
+    } else {
+        if (!x || !pk)
+            return 0;
+        idx = ssl_cert_type(x, pk);
+        if (idx == -1)
+            return 0;
+        pvalid = s->s3->tmp.valid_flags + idx;
+
+        if (c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)
+            check_flags = CERT_PKEY_STRICT_FLAGS;
+        else
+            check_flags = CERT_PKEY_VALID_FLAGS;
+        strict_mode = 1;
+    }
+
+    if (suiteb_flags) {
+        int ok;
+        if (check_flags)
+            check_flags |= CERT_PKEY_SUITEB;
+        ok = X509_chain_check_suiteb(NULL, x, chain, suiteb_flags);
+        if (ok == X509_V_OK)
+            rv |= CERT_PKEY_SUITEB;
+        else if (!check_flags)
+            goto end;
+    }
+
+    /*
+     * Check all signature algorithms are consistent with signature
+     * algorithms extension if TLS 1.2 or later and strict mode.
+     */
+    if (TLS1_get_version(s) >= TLS1_2_VERSION && strict_mode) {
+        int default_nid;
+        unsigned char rsign = 0;
+        if (s->s3->tmp.peer_sigalgs)
+            default_nid = 0;
+        /* If no sigalgs extension use defaults from RFC5246 */
+        else {
+            switch (idx) {
+            case SSL_PKEY_RSA_ENC:
+            case SSL_PKEY_RSA_SIGN:
+                rsign = TLSEXT_signature_rsa;
+                default_nid = NID_sha1WithRSAEncryption;
+                break;
+
+            case SSL_PKEY_DSA_SIGN:
+                rsign = TLSEXT_signature_dsa;
+                default_nid = NID_dsaWithSHA1;
+                break;
+
+            case SSL_PKEY_ECC:
+                rsign = TLSEXT_signature_ecdsa;
+                default_nid = NID_ecdsa_with_SHA1;
+                break;
+
+            case SSL_PKEY_GOST01:
+                rsign = TLSEXT_signature_gostr34102001;
+                default_nid = NID_id_GostR3411_94_with_GostR3410_2001;
+                break;
+
+            case SSL_PKEY_GOST12_256:
+                rsign = TLSEXT_signature_gostr34102012_256;
+                default_nid = NID_id_tc26_signwithdigest_gost3410_2012_256;
+                break;
+
+            case SSL_PKEY_GOST12_512:
+                rsign = TLSEXT_signature_gostr34102012_512;
+                default_nid = NID_id_tc26_signwithdigest_gost3410_2012_512;
+                break;
+
+            default:
+                default_nid = -1;
+                break;
+            }
+        }
+        /*
+         * If peer sent no signature algorithms extension and we have set
+         * preferred signature algorithms check we support sha1.
+         */
+        if (default_nid > 0 && c->conf_sigalgs) {
+            size_t j;
+            const unsigned char *p = c->conf_sigalgs;
+            for (j = 0; j < c->conf_sigalgslen; j += 2, p += 2) {
+                if (p[0] == TLSEXT_hash_sha1 && p[1] == rsign)
+                    break;
+            }
+            if (j == c->conf_sigalgslen) {
+                if (check_flags)
+                    goto skip_sigs;
+                else
+                    goto end;
+            }
+        }
+        /* Check signature algorithm of each cert in chain */
+        if (!tls1_check_sig_alg(c, x, default_nid)) {
+            if (!check_flags)
+                goto end;
+        } else
+            rv |= CERT_PKEY_EE_SIGNATURE;
+        rv |= CERT_PKEY_CA_SIGNATURE;
+        for (i = 0; i < sk_X509_num(chain); i++) {
+            if (!tls1_check_sig_alg(c, sk_X509_value(chain, i), default_nid)) {
+                if (check_flags) {
+                    rv &= ~CERT_PKEY_CA_SIGNATURE;
+                    break;
+                } else
+                    goto end;
+            }
+        }
+    }
+    /* Else not TLS 1.2, so mark EE and CA signing algorithms OK */
+    else if (check_flags)
+        rv |= CERT_PKEY_EE_SIGNATURE | CERT_PKEY_CA_SIGNATURE;
+ skip_sigs:
+    /* Check cert parameters are consistent */
+    if (tls1_check_cert_param(s, x, check_flags ? 1 : 2))
+        rv |= CERT_PKEY_EE_PARAM;
+    else if (!check_flags)
+        goto end;
+    if (!s->server)
+        rv |= CERT_PKEY_CA_PARAM;
+    /* In strict mode check rest of chain too */
+    else if (strict_mode) {
+        rv |= CERT_PKEY_CA_PARAM;
+        for (i = 0; i < sk_X509_num(chain); i++) {
+            X509 *ca = sk_X509_value(chain, i);
+            if (!tls1_check_cert_param(s, ca, 0)) {
+                if (check_flags) {
+                    rv &= ~CERT_PKEY_CA_PARAM;
+                    break;
+                } else
+                    goto end;
+            }
+        }
+    }
+    if (!s->server && strict_mode) {
+        STACK_OF(X509_NAME) *ca_dn;
+        int check_type = 0;
+        switch (EVP_PKEY_id(pk)) {
+        case EVP_PKEY_RSA:
+            check_type = TLS_CT_RSA_SIGN;
+            break;
+        case EVP_PKEY_DSA:
+            check_type = TLS_CT_DSS_SIGN;
+            break;
+        case EVP_PKEY_EC:
+            check_type = TLS_CT_ECDSA_SIGN;
+            break;
+        }
+        if (check_type) {
+            const unsigned char *ctypes;
+            int ctypelen;
+            if (c->ctypes) {
+                ctypes = c->ctypes;
+                ctypelen = (int)c->ctype_num;
+            } else {
+                ctypes = (unsigned char *)s->s3->tmp.ctype;
+                ctypelen = s->s3->tmp.ctype_num;
+            }
+            for (i = 0; i < ctypelen; i++) {
+                if (ctypes[i] == check_type) {
+                    rv |= CERT_PKEY_CERT_TYPE;
+                    break;
+                }
+            }
+            if (!(rv & CERT_PKEY_CERT_TYPE) && !check_flags)
+                goto end;
+        } else
+            rv |= CERT_PKEY_CERT_TYPE;
+
+        ca_dn = s->s3->tmp.ca_names;
+
+        if (!sk_X509_NAME_num(ca_dn))
+            rv |= CERT_PKEY_ISSUER_NAME;
+
+        if (!(rv & CERT_PKEY_ISSUER_NAME)) {
+            if (ssl_check_ca_name(ca_dn, x))
+                rv |= CERT_PKEY_ISSUER_NAME;
+        }
+        if (!(rv & CERT_PKEY_ISSUER_NAME)) {
+            for (i = 0; i < sk_X509_num(chain); i++) {
+                X509 *xtmp = sk_X509_value(chain, i);
+                if (ssl_check_ca_name(ca_dn, xtmp)) {
+                    rv |= CERT_PKEY_ISSUER_NAME;
+                    break;
+                }
+            }
+        }
+        if (!check_flags && !(rv & CERT_PKEY_ISSUER_NAME))
+            goto end;
+    } else
+        rv |= CERT_PKEY_ISSUER_NAME | CERT_PKEY_CERT_TYPE;
+
+    if (!check_flags || (rv & check_flags) == check_flags)
+        rv |= CERT_PKEY_VALID;
+
+ end:
+
+    if (TLS1_get_version(s) >= TLS1_2_VERSION) {
+        if (*pvalid & CERT_PKEY_EXPLICIT_SIGN)
+            rv |= CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN;
+        else if (s->s3->tmp.md[idx] != NULL)
+            rv |= CERT_PKEY_SIGN;
+    } else
+        rv |= CERT_PKEY_SIGN | CERT_PKEY_EXPLICIT_SIGN;
+
+    /*
+     * When checking a CERT_PKEY structure all flags are irrelevant if the
+     * chain is invalid.
+     */
+    if (!check_flags) {
+        if (rv & CERT_PKEY_VALID)
+            *pvalid = rv;
+        else {
+            /* Preserve explicit sign flag, clear rest */
+            *pvalid &= CERT_PKEY_EXPLICIT_SIGN;
+            return 0;
+        }
+    }
+    return rv;
+}
+
+/* Set validity of certificates in an SSL structure */
+void tls1_set_cert_validity(SSL *s)
+{
+    tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_ENC);
+    tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_SIGN);
+    tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DSA_SIGN);
+    tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ECC);
+    tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_GOST01);
+    tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_GOST12_256);
+    tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_GOST12_512);
+}
+
+/* User level utiity function to check a chain is suitable */
+int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain)
+{
+    return tls1_check_chain(s, x, pk, chain, -1);
+}
+
+#ifndef OPENSSL_NO_DH
+DH *ssl_get_auto_dh(SSL *s)
+{
+    int dh_secbits = 80;
+    if (s->cert->dh_tmp_auto == 2)
+        return DH_get_1024_160();
+    if (s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aPSK)) {
+        if (s->s3->tmp.new_cipher->strength_bits == 256)
+            dh_secbits = 128;
+        else
+            dh_secbits = 80;
+    } else {
+        CERT_PKEY *cpk = ssl_get_server_send_pkey(s);
+        dh_secbits = EVP_PKEY_security_bits(cpk->privatekey);
+    }
+
+    if (dh_secbits >= 128) {
+        DH *dhp = DH_new();
+        BIGNUM *p, *g;
+        if (dhp == NULL)
+            return NULL;
+        g = BN_new();
+        if (g != NULL)
+            BN_set_word(g, 2);
+        if (dh_secbits >= 192)
+            p = BN_get_rfc3526_prime_8192(NULL);
+        else
+            p = BN_get_rfc3526_prime_3072(NULL);
+        if (p == NULL || g == NULL || !DH_set0_pqg(dhp, p, NULL, g)) {
+            DH_free(dhp);
+            BN_free(p);
+            BN_free(g);
+            return NULL;
+        }
+        return dhp;
+    }
+    if (dh_secbits >= 112)
+        return DH_get_2048_224();
+    return DH_get_1024_160();
+}
+#endif
+
+static int ssl_security_cert_key(SSL *s, SSL_CTX *ctx, X509 *x, int op)
+{
+    int secbits = -1;
+    EVP_PKEY *pkey = X509_get0_pubkey(x);
+    if (pkey) {
+        /*
+         * If no parameters this will return -1 and fail using the default
+         * security callback for any non-zero security level. This will
+         * reject keys which omit parameters but this only affects DSA and
+         * omission of parameters is never (?) done in practice.
+         */
+        secbits = EVP_PKEY_security_bits(pkey);
+    }
+    if (s)
+        return ssl_security(s, op, secbits, 0, x);
+    else
+        return ssl_ctx_security(ctx, op, secbits, 0, x);
+}
+
+static int ssl_security_cert_sig(SSL *s, SSL_CTX *ctx, X509 *x, int op)
+{
+    /* Lookup signature algorithm digest */
+    int secbits = -1, md_nid = NID_undef, sig_nid;
+    /* Don't check signature if self signed */
+    if ((X509_get_extension_flags(x) & EXFLAG_SS) != 0)
+        return 1;
+    sig_nid = X509_get_signature_nid(x);
+    if (sig_nid && OBJ_find_sigid_algs(sig_nid, &md_nid, NULL)) {
+        const EVP_MD *md;
+        if (md_nid && (md = EVP_get_digestbynid(md_nid)))
+            secbits = EVP_MD_size(md) * 4;
+    }
+    if (s)
+        return ssl_security(s, op, secbits, md_nid, x);
+    else
+        return ssl_ctx_security(ctx, op, secbits, md_nid, x);
+}
+
+int ssl_security_cert(SSL *s, SSL_CTX *ctx, X509 *x, int vfy, int is_ee)
+{
+    if (vfy)
+        vfy = SSL_SECOP_PEER;
+    if (is_ee) {
+        if (!ssl_security_cert_key(s, ctx, x, SSL_SECOP_EE_KEY | vfy))
+            return SSL_R_EE_KEY_TOO_SMALL;
+    } else {
+        if (!ssl_security_cert_key(s, ctx, x, SSL_SECOP_CA_KEY | vfy))
+            return SSL_R_CA_KEY_TOO_SMALL;
+    }
+    if (!ssl_security_cert_sig(s, ctx, x, SSL_SECOP_CA_MD | vfy))
+        return SSL_R_CA_MD_TOO_WEAK;
+    return 1;
+}
+
+/*
+ * Check security of a chain, if sk includes the end entity certificate then
+ * x is NULL. If vfy is 1 then we are verifying a peer chain and not sending
+ * one to the peer. Return values: 1 if ok otherwise error code to use
+ */
+
+int ssl_security_cert_chain(SSL *s, STACK_OF(X509) *sk, X509 *x, int vfy)
+{
+    int rv, start_idx, i;
+    if (x == NULL) {
+        x = sk_X509_value(sk, 0);
+        start_idx = 1;
+    } else
+        start_idx = 0;
+
+    rv = ssl_security_cert(s, NULL, x, vfy, 1);
+    if (rv != 1)
+        return rv;
+
+    for (i = start_idx; i < sk_X509_num(sk); i++) {
+        x = sk_X509_value(sk, i);
+        rv = ssl_security_cert(s, NULL, x, vfy, 0);
+        if (rv != 1)
+            return rv;
+    }
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/t1_reneg.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/t1_reneg.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/t1_reneg.c	(revision 331)
@@ -0,0 +1,165 @@
+/*
+ * Copyright 1995-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 <stdio.h>
+#include <openssl/objects.h>
+#include "ssl_locl.h"
+
+/* Add the client's renegotiation binding */
+int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
+                                        int maxlen)
+{
+    if (p) {
+        if ((s->s3->previous_client_finished_len + 1) > maxlen) {
+            SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT,
+                   SSL_R_RENEGOTIATE_EXT_TOO_LONG);
+            return 0;
+        }
+
+        /* Length byte */
+        *p = s->s3->previous_client_finished_len;
+        p++;
+
+        memcpy(p, s->s3->previous_client_finished,
+               s->s3->previous_client_finished_len);
+    }
+
+    *len = s->s3->previous_client_finished_len + 1;
+
+    return 1;
+}
+
+/*
+ * Parse the client's renegotiation binding and abort if it's not right
+ */
+int ssl_parse_clienthello_renegotiate_ext(SSL *s, PACKET *pkt, int *al)
+{
+    unsigned int ilen;
+    const unsigned char *d;
+
+    /* Parse the length byte */
+    if (!PACKET_get_1(pkt, &ilen)
+        || !PACKET_get_bytes(pkt, &d, ilen)) {
+        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,
+               SSL_R_RENEGOTIATION_ENCODING_ERR);
+        *al = SSL_AD_ILLEGAL_PARAMETER;
+        return 0;
+    }
+
+    /* Check that the extension matches */
+    if (ilen != s->s3->previous_client_finished_len) {
+        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,
+               SSL_R_RENEGOTIATION_MISMATCH);
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        return 0;
+    }
+
+    if (memcmp(d, s->s3->previous_client_finished,
+               s->s3->previous_client_finished_len)) {
+        SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT,
+               SSL_R_RENEGOTIATION_MISMATCH);
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        return 0;
+    }
+
+    s->s3->send_connection_binding = 1;
+
+    return 1;
+}
+
+/* Add the server's renegotiation binding */
+int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
+                                        int maxlen)
+{
+    if (p) {
+        if ((s->s3->previous_client_finished_len +
+             s->s3->previous_server_finished_len + 1) > maxlen) {
+            SSLerr(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT,
+                   SSL_R_RENEGOTIATE_EXT_TOO_LONG);
+            return 0;
+        }
+
+        /* Length byte */
+        *p = s->s3->previous_client_finished_len +
+            s->s3->previous_server_finished_len;
+        p++;
+
+        memcpy(p, s->s3->previous_client_finished,
+               s->s3->previous_client_finished_len);
+        p += s->s3->previous_client_finished_len;
+
+        memcpy(p, s->s3->previous_server_finished,
+               s->s3->previous_server_finished_len);
+    }
+
+    *len = s->s3->previous_client_finished_len
+        + s->s3->previous_server_finished_len + 1;
+
+    return 1;
+}
+
+/*
+ * Parse the server's renegotiation binding and abort if it's not right
+ */
+int ssl_parse_serverhello_renegotiate_ext(SSL *s, PACKET *pkt, int *al)
+{
+    unsigned int expected_len = s->s3->previous_client_finished_len
+        + s->s3->previous_server_finished_len;
+    unsigned int ilen;
+    const unsigned char *data;
+
+    /* Check for logic errors */
+    OPENSSL_assert(!expected_len || s->s3->previous_client_finished_len);
+    OPENSSL_assert(!expected_len || s->s3->previous_server_finished_len);
+
+    /* Parse the length byte */
+    if (!PACKET_get_1(pkt, &ilen)) {
+        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,
+               SSL_R_RENEGOTIATION_ENCODING_ERR);
+        *al = SSL_AD_ILLEGAL_PARAMETER;
+        return 0;
+    }
+
+    /* Consistency check */
+    if (PACKET_remaining(pkt) != ilen) {
+        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,
+               SSL_R_RENEGOTIATION_ENCODING_ERR);
+        *al = SSL_AD_ILLEGAL_PARAMETER;
+        return 0;
+    }
+
+    /* Check that the extension matches */
+    if (ilen != expected_len) {
+        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,
+               SSL_R_RENEGOTIATION_MISMATCH);
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        return 0;
+    }
+
+    if (!PACKET_get_bytes(pkt, &data, s->s3->previous_client_finished_len)
+        || memcmp(data, s->s3->previous_client_finished,
+                  s->s3->previous_client_finished_len) != 0) {
+        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,
+               SSL_R_RENEGOTIATION_MISMATCH);
+        *al = SSL_AD_HANDSHAKE_FAILURE;
+        return 0;
+    }
+
+    if (!PACKET_get_bytes(pkt, &data, s->s3->previous_server_finished_len)
+        || memcmp(data, s->s3->previous_server_finished,
+                  s->s3->previous_server_finished_len) != 0) {
+        SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT,
+               SSL_R_RENEGOTIATION_MISMATCH);
+        *al = SSL_AD_ILLEGAL_PARAMETER;
+        return 0;
+    }
+    s->s3->send_connection_binding = 1;
+
+    return 1;
+}
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/t1_trce.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/t1_trce.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/t1_trce.c	(revision 331)
@@ -0,0 +1,1341 @@
+/*
+ * Copyright 2012-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 "ssl_locl.h"
+
+#ifndef OPENSSL_NO_SSL_TRACE
+
+/* Packet trace support for OpenSSL */
+
+typedef struct {
+    int num;
+    const char *name;
+} ssl_trace_tbl;
+
+# define ssl_trace_str(val, tbl) \
+        do_ssl_trace_str(val, tbl, OSSL_NELEM(tbl))
+
+# define ssl_trace_list(bio, indent, msg, msglen, value, table) \
+        do_ssl_trace_list(bio, indent, msg, msglen, value, \
+         table, OSSL_NELEM(table))
+
+static const char *do_ssl_trace_str(int val, ssl_trace_tbl *tbl, size_t ntbl)
+{
+    size_t i;
+    for (i = 0; i < ntbl; i++, tbl++) {
+        if (tbl->num == val)
+            return tbl->name;
+    }
+    return "UNKNOWN";
+}
+
+static int do_ssl_trace_list(BIO *bio, int indent,
+                             const unsigned char *msg, size_t msglen,
+                             size_t vlen, ssl_trace_tbl *tbl, size_t ntbl)
+{
+    int val;
+    if (msglen % vlen)
+        return 0;
+    while (msglen) {
+        val = msg[0];
+        if (vlen == 2)
+            val = (val << 8) | msg[1];
+        BIO_indent(bio, indent, 80);
+        BIO_printf(bio, "%s (%d)\n", do_ssl_trace_str(val, tbl, ntbl), val);
+        msg += vlen;
+        msglen -= vlen;
+    }
+    return 1;
+}
+
+/* Version number */
+
+static ssl_trace_tbl ssl_version_tbl[] = {
+    {SSL3_VERSION, "SSL 3.0"},
+    {TLS1_VERSION, "TLS 1.0"},
+    {TLS1_1_VERSION, "TLS 1.1"},
+    {TLS1_2_VERSION, "TLS 1.2"},
+    {DTLS1_VERSION, "DTLS 1.0"},
+    {DTLS1_2_VERSION, "DTLS 1.2"},
+    {DTLS1_BAD_VER, "DTLS 1.0 (bad)"}
+};
+
+static ssl_trace_tbl ssl_content_tbl[] = {
+    {SSL3_RT_CHANGE_CIPHER_SPEC, "ChangeCipherSpec"},
+    {SSL3_RT_ALERT, "Alert"},
+    {SSL3_RT_HANDSHAKE, "Handshake"},
+    {SSL3_RT_APPLICATION_DATA, "ApplicationData"},
+    {DTLS1_RT_HEARTBEAT, "HeartBeat"}
+};
+
+/* Handshake types */
+static ssl_trace_tbl ssl_handshake_tbl[] = {
+    {SSL3_MT_HELLO_REQUEST, "HelloRequest"},
+    {SSL3_MT_CLIENT_HELLO, "ClientHello"},
+    {SSL3_MT_SERVER_HELLO, "ServerHello"},
+    {DTLS1_MT_HELLO_VERIFY_REQUEST, "HelloVerifyRequest"},
+    {SSL3_MT_NEWSESSION_TICKET, "NewSessionTicket"},
+    {SSL3_MT_CERTIFICATE, "Certificate"},
+    {SSL3_MT_SERVER_KEY_EXCHANGE, "ServerKeyExchange"},
+    {SSL3_MT_CERTIFICATE_REQUEST, "CertificateRequest"},
+    {SSL3_MT_CLIENT_KEY_EXCHANGE, "ClientKeyExchange"},
+    {SSL3_MT_CERTIFICATE_STATUS, "CertificateStatus"},
+    {SSL3_MT_SERVER_DONE, "ServerHelloDone"},
+    {SSL3_MT_CERTIFICATE_VERIFY, "CertificateVerify"},
+    {SSL3_MT_CLIENT_KEY_EXCHANGE, "ClientKeyExchange"},
+    {SSL3_MT_FINISHED, "Finished"},
+    {SSL3_MT_CERTIFICATE_STATUS, "CertificateStatus"}
+};
+
+/* Cipher suites */
+static ssl_trace_tbl ssl_ciphers_tbl[] = {
+    {0x0000, "SSL_NULL_WITH_NULL_NULL"},
+    {0x0001, "SSL_RSA_WITH_NULL_MD5"},
+    {0x0002, "SSL_RSA_WITH_NULL_SHA"},
+    {0x0003, "SSL_RSA_EXPORT_WITH_RC4_40_MD5"},
+    {0x0004, "SSL_RSA_WITH_RC4_128_MD5"},
+    {0x0005, "SSL_RSA_WITH_RC4_128_SHA"},
+    {0x0006, "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5"},
+    {0x0007, "SSL_RSA_WITH_IDEA_CBC_SHA"},
+    {0x0008, "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA"},
+    {0x0009, "SSL_RSA_WITH_DES_CBC_SHA"},
+    {0x000A, "SSL_RSA_WITH_3DES_EDE_CBC_SHA"},
+    {0x000B, "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"},
+    {0x000C, "SSL_DH_DSS_WITH_DES_CBC_SHA"},
+    {0x000D, "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA"},
+    {0x000E, "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"},
+    {0x000F, "SSL_DH_RSA_WITH_DES_CBC_SHA"},
+    {0x0010, "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA"},
+    {0x0011, "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"},
+    {0x0012, "SSL_DHE_DSS_WITH_DES_CBC_SHA"},
+    {0x0013, "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"},
+    {0x0014, "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"},
+    {0x0015, "SSL_DHE_RSA_WITH_DES_CBC_SHA"},
+    {0x0016, "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"},
+    {0x0017, "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5"},
+    {0x0018, "SSL_DH_anon_WITH_RC4_128_MD5"},
+    {0x0019, "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"},
+    {0x001A, "SSL_DH_anon_WITH_DES_CBC_SHA"},
+    {0x001B, "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA"},
+    {0x001D, "SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA"},
+    {0x001E, "SSL_FORTEZZA_KEA_WITH_RC4_128_SHA"},
+    {0x001F, "TLS_KRB5_WITH_3DES_EDE_CBC_SHA"},
+    {0x0020, "TLS_KRB5_WITH_RC4_128_SHA"},
+    {0x0021, "TLS_KRB5_WITH_IDEA_CBC_SHA"},
+    {0x0022, "TLS_KRB5_WITH_DES_CBC_MD5"},
+    {0x0023, "TLS_KRB5_WITH_3DES_EDE_CBC_MD5"},
+    {0x0024, "TLS_KRB5_WITH_RC4_128_MD5"},
+    {0x0025, "TLS_KRB5_WITH_IDEA_CBC_MD5"},
+    {0x0026, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA"},
+    {0x0027, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA"},
+    {0x0028, "TLS_KRB5_EXPORT_WITH_RC4_40_SHA"},
+    {0x0029, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5"},
+    {0x002A, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5"},
+    {0x002B, "TLS_KRB5_EXPORT_WITH_RC4_40_MD5"},
+    {0x002C, "TLS_PSK_WITH_NULL_SHA"},
+    {0x002D, "TLS_DHE_PSK_WITH_NULL_SHA"},
+    {0x002E, "TLS_RSA_PSK_WITH_NULL_SHA"},
+    {0x002F, "TLS_RSA_WITH_AES_128_CBC_SHA"},
+    {0x0030, "TLS_DH_DSS_WITH_AES_128_CBC_SHA"},
+    {0x0031, "TLS_DH_RSA_WITH_AES_128_CBC_SHA"},
+    {0x0032, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"},
+    {0x0033, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"},
+    {0x0034, "TLS_DH_anon_WITH_AES_128_CBC_SHA"},
+    {0x0035, "TLS_RSA_WITH_AES_256_CBC_SHA"},
+    {0x0036, "TLS_DH_DSS_WITH_AES_256_CBC_SHA"},
+    {0x0037, "TLS_DH_RSA_WITH_AES_256_CBC_SHA"},
+    {0x0038, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"},
+    {0x0039, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
+    {0x003A, "TLS_DH_anon_WITH_AES_256_CBC_SHA"},
+    {0x003B, "TLS_RSA_WITH_NULL_SHA256"},
+    {0x003C, "TLS_RSA_WITH_AES_128_CBC_SHA256"},
+    {0x003D, "TLS_RSA_WITH_AES_256_CBC_SHA256"},
+    {0x003E, "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"},
+    {0x003F, "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"},
+    {0x0040, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"},
+    {0x0041, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA"},
+    {0x0042, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA"},
+    {0x0043, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA"},
+    {0x0044, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA"},
+    {0x0045, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA"},
+    {0x0046, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA"},
+    {0x0067, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"},
+    {0x0068, "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"},
+    {0x0069, "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"},
+    {0x006A, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"},
+    {0x006B, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
+    {0x006C, "TLS_DH_anon_WITH_AES_128_CBC_SHA256"},
+    {0x006D, "TLS_DH_anon_WITH_AES_256_CBC_SHA256"},
+    {0x0084, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA"},
+    {0x0085, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA"},
+    {0x0086, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA"},
+    {0x0087, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA"},
+    {0x0088, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA"},
+    {0x0089, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA"},
+    {0x008A, "TLS_PSK_WITH_RC4_128_SHA"},
+    {0x008B, "TLS_PSK_WITH_3DES_EDE_CBC_SHA"},
+    {0x008C, "TLS_PSK_WITH_AES_128_CBC_SHA"},
+    {0x008D, "TLS_PSK_WITH_AES_256_CBC_SHA"},
+    {0x008E, "TLS_DHE_PSK_WITH_RC4_128_SHA"},
+    {0x008F, "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA"},
+    {0x0090, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA"},
+    {0x0091, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA"},
+    {0x0092, "TLS_RSA_PSK_WITH_RC4_128_SHA"},
+    {0x0093, "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA"},
+    {0x0094, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA"},
+    {0x0095, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA"},
+    {0x0096, "TLS_RSA_WITH_SEED_CBC_SHA"},
+    {0x0097, "TLS_DH_DSS_WITH_SEED_CBC_SHA"},
+    {0x0098, "TLS_DH_RSA_WITH_SEED_CBC_SHA"},
+    {0x0099, "TLS_DHE_DSS_WITH_SEED_CBC_SHA"},
+    {0x009A, "TLS_DHE_RSA_WITH_SEED_CBC_SHA"},
+    {0x009B, "TLS_DH_anon_WITH_SEED_CBC_SHA"},
+    {0x009C, "TLS_RSA_WITH_AES_128_GCM_SHA256"},
+    {0x009D, "TLS_RSA_WITH_AES_256_GCM_SHA384"},
+    {0x009E, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"},
+    {0x009F, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"},
+    {0x00A0, "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"},
+    {0x00A1, "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"},
+    {0x00A2, "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"},
+    {0x00A3, "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"},
+    {0x00A4, "TLS_DH_DSS_WITH_AES_128_GCM_SHA256"},
+    {0x00A5, "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"},
+    {0x00A6, "TLS_DH_anon_WITH_AES_128_GCM_SHA256"},
+    {0x00A7, "TLS_DH_anon_WITH_AES_256_GCM_SHA384"},
+    {0x00A8, "TLS_PSK_WITH_AES_128_GCM_SHA256"},
+    {0x00A9, "TLS_PSK_WITH_AES_256_GCM_SHA384"},
+    {0x00AA, "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256"},
+    {0x00AB, "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384"},
+    {0x00AC, "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256"},
+    {0x00AD, "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384"},
+    {0x00AE, "TLS_PSK_WITH_AES_128_CBC_SHA256"},
+    {0x00AF, "TLS_PSK_WITH_AES_256_CBC_SHA384"},
+    {0x00B0, "TLS_PSK_WITH_NULL_SHA256"},
+    {0x00B1, "TLS_PSK_WITH_NULL_SHA384"},
+    {0x00B2, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256"},
+    {0x00B3, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384"},
+    {0x00B4, "TLS_DHE_PSK_WITH_NULL_SHA256"},
+    {0x00B5, "TLS_DHE_PSK_WITH_NULL_SHA384"},
+    {0x00B6, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256"},
+    {0x00B7, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384"},
+    {0x00B8, "TLS_RSA_PSK_WITH_NULL_SHA256"},
+    {0x00B9, "TLS_RSA_PSK_WITH_NULL_SHA384"},
+    {0x00BA, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256"},
+    {0x00BB, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256"},
+    {0x00BC, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256"},
+    {0x00BD, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256"},
+    {0x00BE, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256"},
+    {0x00BF, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256"},
+    {0x00C0, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256"},
+    {0x00C1, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256"},
+    {0x00C2, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256"},
+    {0x00C3, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256"},
+    {0x00C4, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256"},
+    {0x00C5, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256"},
+    {0x00FF, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"},
+    {0x5600, "TLS_FALLBACK_SCSV"},
+    {0xC001, "TLS_ECDH_ECDSA_WITH_NULL_SHA"},
+    {0xC002, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"},
+    {0xC003, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"},
+    {0xC004, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"},
+    {0xC005, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"},
+    {0xC006, "TLS_ECDHE_ECDSA_WITH_NULL_SHA"},
+    {0xC007, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"},
+    {0xC008, "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"},
+    {0xC009, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"},
+    {0xC00A, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"},
+    {0xC00B, "TLS_ECDH_RSA_WITH_NULL_SHA"},
+    {0xC00C, "TLS_ECDH_RSA_WITH_RC4_128_SHA"},
+    {0xC00D, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"},
+    {0xC00E, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"},
+    {0xC00F, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"},
+    {0xC010, "TLS_ECDHE_RSA_WITH_NULL_SHA"},
+    {0xC011, "TLS_ECDHE_RSA_WITH_RC4_128_SHA"},
+    {0xC012, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"},
+    {0xC013, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"},
+    {0xC014, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"},
+    {0xC015, "TLS_ECDH_anon_WITH_NULL_SHA"},
+    {0xC016, "TLS_ECDH_anon_WITH_RC4_128_SHA"},
+    {0xC017, "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"},
+    {0xC018, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"},
+    {0xC019, "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"},
+    {0xC01A, "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA"},
+    {0xC01B, "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA"},
+    {0xC01C, "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA"},
+    {0xC01D, "TLS_SRP_SHA_WITH_AES_128_CBC_SHA"},
+    {0xC01E, "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA"},
+    {0xC01F, "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA"},
+    {0xC020, "TLS_SRP_SHA_WITH_AES_256_CBC_SHA"},
+    {0xC021, "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA"},
+    {0xC022, "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA"},
+    {0xC023, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"},
+    {0xC024, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"},
+    {0xC025, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"},
+    {0xC026, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"},
+    {0xC027, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"},
+    {0xC028, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"},
+    {0xC029, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"},
+    {0xC02A, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"},
+    {0xC02B, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"},
+    {0xC02C, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"},
+    {0xC02D, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"},
+    {0xC02E, "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"},
+    {0xC02F, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"},
+    {0xC030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"},
+    {0xC031, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"},
+    {0xC032, "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"},
+    {0xC033, "TLS_ECDHE_PSK_WITH_RC4_128_SHA"},
+    {0xC034, "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA"},
+    {0xC035, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA"},
+    {0xC036, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA"},
+    {0xC037, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256"},
+    {0xC038, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384"},
+    {0xC039, "TLS_ECDHE_PSK_WITH_NULL_SHA"},
+    {0xC03A, "TLS_ECDHE_PSK_WITH_NULL_SHA256"},
+    {0xC03B, "TLS_ECDHE_PSK_WITH_NULL_SHA384"},
+    {0xC03C, "TLS_RSA_WITH_ARIA_128_CBC_SHA256"},
+    {0xC03D, "TLS_RSA_WITH_ARIA_256_CBC_SHA384"},
+    {0xC03E, "TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256"},
+    {0xC03F, "TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384"},
+    {0xC040, "TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256"},
+    {0xC041, "TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384"},
+    {0xC042, "TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256"},
+    {0xC043, "TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384"},
+    {0xC044, "TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256"},
+    {0xC045, "TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384"},
+    {0xC046, "TLS_DH_anon_WITH_ARIA_128_CBC_SHA256"},
+    {0xC047, "TLS_DH_anon_WITH_ARIA_256_CBC_SHA384"},
+    {0xC048, "TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256"},
+    {0xC049, "TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384"},
+    {0xC04A, "TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256"},
+    {0xC04B, "TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384"},
+    {0xC04C, "TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256"},
+    {0xC04D, "TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384"},
+    {0xC04E, "TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256"},
+    {0xC04F, "TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384"},
+    {0xC050, "TLS_RSA_WITH_ARIA_128_GCM_SHA256"},
+    {0xC051, "TLS_RSA_WITH_ARIA_256_GCM_SHA384"},
+    {0xC052, "TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256"},
+    {0xC053, "TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384"},
+    {0xC054, "TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256"},
+    {0xC055, "TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384"},
+    {0xC056, "TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256"},
+    {0xC057, "TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384"},
+    {0xC058, "TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256"},
+    {0xC059, "TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384"},
+    {0xC05A, "TLS_DH_anon_WITH_ARIA_128_GCM_SHA256"},
+    {0xC05B, "TLS_DH_anon_WITH_ARIA_256_GCM_SHA384"},
+    {0xC05C, "TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256"},
+    {0xC05D, "TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384"},
+    {0xC05E, "TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256"},
+    {0xC05F, "TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384"},
+    {0xC060, "TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256"},
+    {0xC061, "TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384"},
+    {0xC062, "TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256"},
+    {0xC063, "TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384"},
+    {0xC064, "TLS_PSK_WITH_ARIA_128_CBC_SHA256"},
+    {0xC065, "TLS_PSK_WITH_ARIA_256_CBC_SHA384"},
+    {0xC066, "TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256"},
+    {0xC067, "TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384"},
+    {0xC068, "TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256"},
+    {0xC069, "TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384"},
+    {0xC06A, "TLS_PSK_WITH_ARIA_128_GCM_SHA256"},
+    {0xC06B, "TLS_PSK_WITH_ARIA_256_GCM_SHA384"},
+    {0xC06C, "TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256"},
+    {0xC06D, "TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384"},
+    {0xC06E, "TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256"},
+    {0xC06F, "TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384"},
+    {0xC070, "TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256"},
+    {0xC071, "TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384"},
+    {0xC072, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256"},
+    {0xC073, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384"},
+    {0xC074, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256"},
+    {0xC075, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384"},
+    {0xC076, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256"},
+    {0xC077, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384"},
+    {0xC078, "TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256"},
+    {0xC079, "TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384"},
+    {0xC07A, "TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256"},
+    {0xC07B, "TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384"},
+    {0xC07C, "TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256"},
+    {0xC07D, "TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384"},
+    {0xC07E, "TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256"},
+    {0xC07F, "TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384"},
+    {0xC080, "TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256"},
+    {0xC081, "TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384"},
+    {0xC082, "TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256"},
+    {0xC083, "TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384"},
+    {0xC084, "TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256"},
+    {0xC085, "TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384"},
+    {0xC086, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256"},
+    {0xC087, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384"},
+    {0xC088, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256"},
+    {0xC089, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384"},
+    {0xC08A, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256"},
+    {0xC08B, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384"},
+    {0xC08C, "TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256"},
+    {0xC08D, "TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384"},
+    {0xC08E, "TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256"},
+    {0xC08F, "TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384"},
+    {0xC090, "TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256"},
+    {0xC091, "TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384"},
+    {0xC092, "TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256"},
+    {0xC093, "TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384"},
+    {0xC094, "TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256"},
+    {0xC095, "TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384"},
+    {0xC096, "TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256"},
+    {0xC097, "TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384"},
+    {0xC098, "TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256"},
+    {0xC099, "TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384"},
+    {0xC09A, "TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256"},
+    {0xC09B, "TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384"},
+    {0xC09C, "TLS_RSA_WITH_AES_128_CCM"},
+    {0xC09D, "TLS_RSA_WITH_AES_256_CCM"},
+    {0xC09E, "TLS_DHE_RSA_WITH_AES_128_CCM"},
+    {0xC09F, "TLS_DHE_RSA_WITH_AES_256_CCM"},
+    {0xC0A0, "TLS_RSA_WITH_AES_128_CCM_8"},
+    {0xC0A1, "TLS_RSA_WITH_AES_256_CCM_8"},
+    {0xC0A2, "TLS_DHE_RSA_WITH_AES_128_CCM_8"},
+    {0xC0A3, "TLS_DHE_RSA_WITH_AES_256_CCM_8"},
+    {0xC0A4, "TLS_PSK_WITH_AES_128_CCM"},
+    {0xC0A5, "TLS_PSK_WITH_AES_256_CCM"},
+    {0xC0A6, "TLS_DHE_PSK_WITH_AES_128_CCM"},
+    {0xC0A7, "TLS_DHE_PSK_WITH_AES_256_CCM"},
+    {0xC0A8, "TLS_PSK_WITH_AES_128_CCM_8"},
+    {0xC0A9, "TLS_PSK_WITH_AES_256_CCM_8"},
+    {0xC0AA, "TLS_PSK_DHE_WITH_AES_128_CCM_8"},
+    {0xC0AB, "TLS_PSK_DHE_WITH_AES_256_CCM_8"},
+    {0xC0AC, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM"},
+    {0xC0AD, "TLS_ECDHE_ECDSA_WITH_AES_256_CCM"},
+    {0xC0AE, "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8"},
+    {0xC0AF, "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8"},
+    {0xCCA8, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305"},
+    {0xCCA9, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305"},
+    {0xCCAA, "TLS_DHE_RSA_WITH_CHACHA20_POLY1305"},
+    {0xCCAB, "TLS_PSK_WITH_CHACHA20_POLY1305"},
+    {0xCCAC, "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305"},
+    {0xCCAD, "TLS_DHE_PSK_WITH_CHACHA20_POLY1305"},
+    {0xCCAE, "TLS_RSA_PSK_WITH_CHACHA20_POLY1305"},
+    {0xFEFE, "SSL_RSA_FIPS_WITH_DES_CBC_SHA"},
+    {0xFEFF, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA"},
+};
+
+/* Compression methods */
+static ssl_trace_tbl ssl_comp_tbl[] = {
+    {0x0000, "No Compression"},
+    {0x0001, "Zlib Compression"}
+};
+
+/* Extensions */
+static ssl_trace_tbl ssl_exts_tbl[] = {
+    {TLSEXT_TYPE_server_name, "server_name"},
+    {TLSEXT_TYPE_max_fragment_length, "max_fragment_length"},
+    {TLSEXT_TYPE_client_certificate_url, "client_certificate_url"},
+    {TLSEXT_TYPE_trusted_ca_keys, "trusted_ca_keys"},
+    {TLSEXT_TYPE_truncated_hmac, "truncated_hmac"},
+    {TLSEXT_TYPE_status_request, "status_request"},
+    {TLSEXT_TYPE_user_mapping, "user_mapping"},
+    {TLSEXT_TYPE_client_authz, "client_authz"},
+    {TLSEXT_TYPE_server_authz, "server_authz"},
+    {TLSEXT_TYPE_cert_type, "cert_type"},
+    {TLSEXT_TYPE_elliptic_curves, "elliptic_curves"},
+    {TLSEXT_TYPE_ec_point_formats, "ec_point_formats"},
+    {TLSEXT_TYPE_srp, "srp"},
+    {TLSEXT_TYPE_signature_algorithms, "signature_algorithms"},
+    {TLSEXT_TYPE_use_srtp, "use_srtp"},
+    {TLSEXT_TYPE_heartbeat, "heartbeat"},
+    {TLSEXT_TYPE_session_ticket, "session_ticket"},
+    {TLSEXT_TYPE_renegotiate, "renegotiate"},
+# ifndef OPENSSL_NO_NEXTPROTONEG
+    {TLSEXT_TYPE_next_proto_neg, "next_proto_neg"},
+# endif
+    {TLSEXT_TYPE_signed_certificate_timestamp, "signed_certificate_timestamps"},
+    {TLSEXT_TYPE_padding, "padding"},
+    {TLSEXT_TYPE_encrypt_then_mac, "encrypt_then_mac"},
+    {TLSEXT_TYPE_extended_master_secret, "extended_master_secret"}
+};
+
+static ssl_trace_tbl ssl_curve_tbl[] = {
+    {1, "sect163k1 (K-163)"},
+    {2, "sect163r1"},
+    {3, "sect163r2 (B-163)"},
+    {4, "sect193r1"},
+    {5, "sect193r2"},
+    {6, "sect233k1 (K-233)"},
+    {7, "sect233r1 (B-233)"},
+    {8, "sect239k1"},
+    {9, "sect283k1 (K-283)"},
+    {10, "sect283r1 (B-283)"},
+    {11, "sect409k1 (K-409)"},
+    {12, "sect409r1 (B-409)"},
+    {13, "sect571k1 (K-571)"},
+    {14, "sect571r1 (B-571)"},
+    {15, "secp160k1"},
+    {16, "secp160r1"},
+    {17, "secp160r2"},
+    {18, "secp192k1"},
+    {19, "secp192r1 (P-192)"},
+    {20, "secp224k1"},
+    {21, "secp224r1 (P-224)"},
+    {22, "secp256k1"},
+    {23, "secp256r1 (P-256)"},
+    {24, "secp384r1 (P-384)"},
+    {25, "secp521r1 (P-521)"},
+    {26, "brainpoolP256r1"},
+    {27, "brainpoolP384r1"},
+    {28, "brainpoolP512r1"},
+    {29, "ecdh_x25519"},
+    {0xFF01, "arbitrary_explicit_prime_curves"},
+    {0xFF02, "arbitrary_explicit_char2_curves"}
+};
+
+static ssl_trace_tbl ssl_point_tbl[] = {
+    {0, "uncompressed"},
+    {1, "ansiX962_compressed_prime"},
+    {2, "ansiX962_compressed_char2"}
+};
+
+static ssl_trace_tbl ssl_md_tbl[] = {
+    {TLSEXT_hash_none, "none"},
+    {TLSEXT_hash_md5, "md5"},
+    {TLSEXT_hash_sha1, "sha1"},
+    {TLSEXT_hash_sha224, "sha224"},
+    {TLSEXT_hash_sha256, "sha256"},
+    {TLSEXT_hash_sha384, "sha384"},
+    {TLSEXT_hash_sha512, "sha512"},
+    {TLSEXT_hash_gostr3411, "md_gost94"},
+    {TLSEXT_hash_gostr34112012_256, "md_gost2012_256"},
+    {TLSEXT_hash_gostr34112012_512, "md_gost2012_512"}
+};
+
+static ssl_trace_tbl ssl_sig_tbl[] = {
+    {TLSEXT_signature_anonymous, "anonymous"},
+    {TLSEXT_signature_rsa, "rsa"},
+    {TLSEXT_signature_dsa, "dsa"},
+    {TLSEXT_signature_ecdsa, "ecdsa"},
+    {TLSEXT_signature_gostr34102001, "gost2001"},
+    {TLSEXT_signature_gostr34102012_256, "gost2012_256"},
+    {TLSEXT_signature_gostr34102012_512, "gost2012_512"}
+};
+
+static ssl_trace_tbl ssl_hb_tbl[] = {
+    {1, "peer_allowed_to_send"},
+    {2, "peer_not_allowed_to_send"}
+};
+
+static ssl_trace_tbl ssl_hb_type_tbl[] = {
+    {1, "heartbeat_request"},
+    {2, "heartbeat_response"}
+};
+
+static ssl_trace_tbl ssl_ctype_tbl[] = {
+    {1, "rsa_sign"},
+    {2, "dss_sign"},
+    {3, "rsa_fixed_dh"},
+    {4, "dss_fixed_dh"},
+    {5, "rsa_ephemeral_dh"},
+    {6, "dss_ephemeral_dh"},
+    {20, "fortezza_dms"},
+    {64, "ecdsa_sign"},
+    {65, "rsa_fixed_ecdh"},
+    {66, "ecdsa_fixed_ecdh"}
+};
+
+static ssl_trace_tbl ssl_crypto_tbl[] = {
+    {TLS1_RT_CRYPTO_PREMASTER, "Premaster Secret"},
+    {TLS1_RT_CRYPTO_CLIENT_RANDOM, "Client Random"},
+    {TLS1_RT_CRYPTO_SERVER_RANDOM, "Server Random"},
+    {TLS1_RT_CRYPTO_MASTER, "Master Secret"},
+    {TLS1_RT_CRYPTO_MAC | TLS1_RT_CRYPTO_WRITE, "Write Mac Secret"},
+    {TLS1_RT_CRYPTO_MAC | TLS1_RT_CRYPTO_READ, "Read Mac Secret"},
+    {TLS1_RT_CRYPTO_KEY | TLS1_RT_CRYPTO_WRITE, "Write Key"},
+    {TLS1_RT_CRYPTO_KEY | TLS1_RT_CRYPTO_READ, "Read Key"},
+    {TLS1_RT_CRYPTO_IV | TLS1_RT_CRYPTO_WRITE, "Write IV"},
+    {TLS1_RT_CRYPTO_IV | TLS1_RT_CRYPTO_READ, "Read IV"},
+    {TLS1_RT_CRYPTO_FIXED_IV | TLS1_RT_CRYPTO_WRITE, "Write IV (fixed part)"},
+    {TLS1_RT_CRYPTO_FIXED_IV | TLS1_RT_CRYPTO_READ, "Read IV (fixed part)"}
+};
+
+static void ssl_print_hex(BIO *bio, int indent, const char *name,
+                          const unsigned char *msg, size_t msglen)
+{
+    size_t i;
+    BIO_indent(bio, indent, 80);
+    BIO_printf(bio, "%s (len=%d): ", name, (int)msglen);
+    for (i = 0; i < msglen; i++)
+        BIO_printf(bio, "%02X", msg[i]);
+    BIO_puts(bio, "\n");
+}
+
+static int ssl_print_hexbuf(BIO *bio, int indent,
+                            const char *name, size_t nlen,
+                            const unsigned char **pmsg, size_t *pmsglen)
+{
+    size_t blen;
+    const unsigned char *p = *pmsg;
+    if (*pmsglen < nlen)
+        return 0;
+    blen = p[0];
+    if (nlen > 1)
+        blen = (blen << 8) | p[1];
+    if (*pmsglen < nlen + blen)
+        return 0;
+    p += nlen;
+    ssl_print_hex(bio, indent, name, p, blen);
+    *pmsg += blen + nlen;
+    *pmsglen -= blen + nlen;
+    return 1;
+}
+
+static int ssl_print_version(BIO *bio, int indent, const char *name,
+                             const unsigned char **pmsg, size_t *pmsglen)
+{
+    int vers;
+    if (*pmsglen < 2)
+        return 0;
+    vers = ((*pmsg)[0] << 8) | (*pmsg)[1];
+    BIO_indent(bio, indent, 80);
+    BIO_printf(bio, "%s=0x%x (%s)\n",
+               name, vers, ssl_trace_str(vers, ssl_version_tbl));
+    *pmsg += 2;
+    *pmsglen -= 2;
+    return 1;
+}
+
+static int ssl_print_random(BIO *bio, int indent,
+                            const unsigned char **pmsg, size_t *pmsglen)
+{
+    unsigned int tm;
+    const unsigned char *p = *pmsg;
+    if (*pmsglen < 32)
+        return 0;
+    tm = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+    p += 4;
+    BIO_indent(bio, indent, 80);
+    BIO_puts(bio, "Random:\n");
+    BIO_indent(bio, indent + 2, 80);
+    BIO_printf(bio, "gmt_unix_time=0x%08X\n", tm);
+    ssl_print_hex(bio, indent + 2, "random_bytes", p, 28);
+    *pmsg += 32;
+    *pmsglen -= 32;
+    return 1;
+}
+
+static int ssl_print_signature(BIO *bio, int indent, SSL *s,
+                               const unsigned char **pmsg, size_t *pmsglen)
+{
+    if (*pmsglen < 2)
+        return 0;
+    if (SSL_USE_SIGALGS(s)) {
+        const unsigned char *p = *pmsg;
+        BIO_indent(bio, indent, 80);
+        BIO_printf(bio, "Signature Algorithm %s+%s (%d+%d)\n",
+                   ssl_trace_str(p[0], ssl_md_tbl),
+                   ssl_trace_str(p[1], ssl_sig_tbl), p[0], p[1]);
+        *pmsg += 2;
+        *pmsglen -= 2;
+    }
+    return ssl_print_hexbuf(bio, indent, "Signature", 2, pmsg, pmsglen);
+}
+
+static int ssl_print_extension(BIO *bio, int indent, int server, int extype,
+                               const unsigned char *ext, size_t extlen)
+{
+    size_t xlen;
+    BIO_indent(bio, indent, 80);
+    BIO_printf(bio, "extension_type=%s(%d), length=%d\n",
+               ssl_trace_str(extype, ssl_exts_tbl), extype, (int)extlen);
+    switch (extype) {
+    case TLSEXT_TYPE_ec_point_formats:
+        if (extlen < 1)
+            return 0;
+        xlen = ext[0];
+        if (extlen != xlen + 1)
+            return 0;
+        return ssl_trace_list(bio, indent + 2, ext + 1, xlen, 1, ssl_point_tbl);
+
+    case TLSEXT_TYPE_elliptic_curves:
+        if (extlen < 2)
+            return 0;
+        xlen = (ext[0] << 8) | ext[1];
+        if (extlen != xlen + 2)
+            return 0;
+        return ssl_trace_list(bio, indent + 2, ext + 2, xlen, 2, ssl_curve_tbl);
+
+    case TLSEXT_TYPE_signature_algorithms:
+
+        if (extlen < 2)
+            return 0;
+        xlen = (ext[0] << 8) | ext[1];
+        if (extlen != xlen + 2)
+            return 0;
+        if (xlen & 1)
+            return 0;
+        ext += 2;
+        while (xlen > 0) {
+            BIO_indent(bio, indent + 2, 80);
+            BIO_printf(bio, "%s+%s (%d+%d)\n",
+                       ssl_trace_str(ext[0], ssl_md_tbl),
+                       ssl_trace_str(ext[1], ssl_sig_tbl), ext[0], ext[1]);
+            xlen -= 2;
+            ext += 2;
+        }
+        break;
+
+    case TLSEXT_TYPE_renegotiate:
+        if (extlen < 1)
+            return 0;
+        xlen = ext[0];
+        if (xlen + 1 != extlen)
+            return 0;
+        ext++;
+        if (xlen) {
+            if (server) {
+                if (xlen & 1)
+                    return 0;
+                xlen >>= 1;
+            }
+            ssl_print_hex(bio, indent + 4, "client_verify_data", ext, xlen);
+            if (server) {
+                ext += xlen;
+                ssl_print_hex(bio, indent + 4, "server_verify_data", ext, xlen);
+            }
+        } else {
+            BIO_indent(bio, indent + 4, 80);
+            BIO_puts(bio, "<EMPTY>\n");
+        }
+        break;
+
+    case TLSEXT_TYPE_heartbeat:
+        if (extlen != 1)
+            return 0;
+        BIO_indent(bio, indent + 2, 80);
+        BIO_printf(bio, "HeartbeatMode: %s\n",
+                   ssl_trace_str(ext[0], ssl_hb_tbl));
+        break;
+
+    case TLSEXT_TYPE_session_ticket:
+        if (extlen != 0)
+            ssl_print_hex(bio, indent + 4, "ticket", ext, extlen);
+        break;
+
+    default:
+        BIO_dump_indent(bio, (const char *)ext, extlen, indent + 2);
+    }
+    return 1;
+}
+
+static int ssl_print_extensions(BIO *bio, int indent, int server,
+                                const unsigned char *msg, size_t msglen)
+{
+    size_t extslen;
+    BIO_indent(bio, indent, 80);
+    if (msglen == 0) {
+        BIO_puts(bio, "No Extensions\n");
+        return 1;
+    }
+    extslen = (msg[0] << 8) | msg[1];
+    if (extslen != msglen - 2)
+        return 0;
+    msg += 2;
+    msglen = extslen;
+    BIO_printf(bio, "extensions, length = %d\n", (int)msglen);
+    while (msglen > 0) {
+        int extype;
+        size_t extlen;
+        if (msglen < 4)
+            return 0;
+        extype = (msg[0] << 8) | msg[1];
+        extlen = (msg[2] << 8) | msg[3];
+        if (msglen < extlen + 4)
+            return 0;
+        msg += 4;
+        if (!ssl_print_extension(bio, indent + 2, server, extype, msg, extlen))
+            return 0;
+        msg += extlen;
+        msglen -= extlen + 4;
+    }
+    return 1;
+}
+
+static int ssl_print_client_hello(BIO *bio, SSL *ssl, int indent,
+                                  const unsigned char *msg, size_t msglen)
+{
+    size_t len;
+    unsigned int cs;
+    if (!ssl_print_version(bio, indent, "client_version", &msg, &msglen))
+        return 0;
+    if (!ssl_print_random(bio, indent, &msg, &msglen))
+        return 0;
+    if (!ssl_print_hexbuf(bio, indent, "session_id", 1, &msg, &msglen))
+        return 0;
+    if (SSL_IS_DTLS(ssl)) {
+        if (!ssl_print_hexbuf(bio, indent, "cookie", 1, &msg, &msglen))
+            return 0;
+    }
+    if (msglen < 2)
+        return 0;
+    len = (msg[0] << 8) | msg[1];
+    msg += 2;
+    msglen -= 2;
+    BIO_indent(bio, indent, 80);
+    BIO_printf(bio, "cipher_suites (len=%d)\n", (int)len);
+    if (msglen < len || len & 1)
+        return 0;
+    while (len > 0) {
+        cs = (msg[0] << 8) | msg[1];
+        BIO_indent(bio, indent + 2, 80);
+        BIO_printf(bio, "{0x%02X, 0x%02X} %s\n",
+                   msg[0], msg[1], ssl_trace_str(cs, ssl_ciphers_tbl));
+        msg += 2;
+        msglen -= 2;
+        len -= 2;
+    }
+    if (msglen < 1)
+        return 0;
+    len = msg[0];
+    msg++;
+    msglen--;
+    if (msglen < len)
+        return 0;
+    BIO_indent(bio, indent, 80);
+    BIO_printf(bio, "compression_methods (len=%d)\n", (int)len);
+    while (len > 0) {
+        BIO_indent(bio, indent + 2, 80);
+        BIO_printf(bio, "%s (0x%02X)\n",
+                   ssl_trace_str(msg[0], ssl_comp_tbl), msg[0]);
+        msg++;
+        msglen--;
+        len--;
+    }
+    if (!ssl_print_extensions(bio, indent, 0, msg, msglen))
+        return 0;
+    return 1;
+}
+
+static int dtls_print_hello_vfyrequest(BIO *bio, int indent,
+                                       const unsigned char *msg, size_t msglen)
+{
+    if (!ssl_print_version(bio, indent, "server_version", &msg, &msglen))
+        return 0;
+    if (!ssl_print_hexbuf(bio, indent, "cookie", 1, &msg, &msglen))
+        return 0;
+    return 1;
+}
+
+static int ssl_print_server_hello(BIO *bio, int indent,
+                                  const unsigned char *msg, size_t msglen)
+{
+    unsigned int cs;
+    if (!ssl_print_version(bio, indent, "server_version", &msg, &msglen))
+        return 0;
+    if (!ssl_print_random(bio, indent, &msg, &msglen))
+        return 0;
+    if (!ssl_print_hexbuf(bio, indent, "session_id", 1, &msg, &msglen))
+        return 0;
+    if (msglen < 2)
+        return 0;
+    cs = (msg[0] << 8) | msg[1];
+    BIO_indent(bio, indent, 80);
+    BIO_printf(bio, "cipher_suite {0x%02X, 0x%02X} %s\n",
+               msg[0], msg[1], ssl_trace_str(cs, ssl_ciphers_tbl));
+    msg += 2;
+    msglen -= 2;
+    if (msglen < 1)
+        return 0;
+    BIO_indent(bio, indent, 80);
+    BIO_printf(bio, "compression_method: %s (0x%02X)\n",
+               ssl_trace_str(msg[0], ssl_comp_tbl), msg[0]);
+    msg++;
+    msglen--;
+    if (!ssl_print_extensions(bio, indent, 1, msg, msglen))
+        return 0;
+    return 1;
+}
+
+static int ssl_get_keyex(const char **pname, SSL *ssl)
+{
+    unsigned long alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey;
+    if (alg_k & SSL_kRSA) {
+        *pname = "rsa";
+        return SSL_kRSA;
+    }
+    if (alg_k & SSL_kDHE) {
+        *pname = "DHE";
+        return SSL_kDHE;
+    }
+    if (alg_k & SSL_kECDHE) {
+        *pname = "ECDHE";
+        return SSL_kECDHE;
+    }
+    if (alg_k & SSL_kPSK) {
+        *pname = "PSK";
+        return SSL_kPSK;
+    }
+    if (alg_k & SSL_kRSAPSK) {
+        *pname = "RSAPSK";
+        return SSL_kRSAPSK;
+    }
+    if (alg_k & SSL_kDHEPSK) {
+        *pname = "DHEPSK";
+        return SSL_kDHEPSK;
+    }
+    if (alg_k & SSL_kECDHEPSK) {
+        *pname = "ECDHEPSK";
+        return SSL_kECDHEPSK;
+    }
+    if (alg_k & SSL_kSRP) {
+        *pname = "SRP";
+        return SSL_kSRP;
+    }
+    if (alg_k & SSL_kGOST) {
+        *pname = "GOST";
+        return SSL_kGOST;
+    }
+    *pname = "UNKNOWN";
+    return 0;
+}
+
+static int ssl_print_client_keyex(BIO *bio, int indent, SSL *ssl,
+                                  const unsigned char *msg, size_t msglen)
+{
+    const char *algname;
+    int id;
+    id = ssl_get_keyex(&algname, ssl);
+    BIO_indent(bio, indent, 80);
+    BIO_printf(bio, "KeyExchangeAlgorithm=%s\n", algname);
+    if (id & SSL_PSK) {
+        if (!ssl_print_hexbuf(bio, indent + 2,
+                              "psk_identity", 2, &msg, &msglen))
+            return 0;
+    }
+    switch (id) {
+
+    case SSL_kRSA:
+    case SSL_kRSAPSK:
+        if (TLS1_get_version(ssl) == SSL3_VERSION) {
+            ssl_print_hex(bio, indent + 2,
+                          "EncyptedPreMasterSecret", msg, msglen);
+        } else {
+            if (!ssl_print_hexbuf(bio, indent + 2,
+                                  "EncyptedPreMasterSecret", 2, &msg, &msglen))
+                return 0;
+        }
+        break;
+
+    case SSL_kDHE:
+    case SSL_kDHEPSK:
+        if (!ssl_print_hexbuf(bio, indent + 2, "dh_Yc", 2, &msg, &msglen))
+            return 0;
+        break;
+
+    case SSL_kECDHE:
+    case SSL_kECDHEPSK:
+        if (!ssl_print_hexbuf(bio, indent + 2, "ecdh_Yc", 1, &msg, &msglen))
+            return 0;
+        break;
+
+    }
+
+    return !msglen;
+}
+
+static int ssl_print_server_keyex(BIO *bio, int indent, SSL *ssl,
+                                  const unsigned char *msg, size_t msglen)
+{
+    const char *algname;
+    int id;
+    id = ssl_get_keyex(&algname, ssl);
+    BIO_indent(bio, indent, 80);
+    BIO_printf(bio, "KeyExchangeAlgorithm=%s\n", algname);
+    if (id & SSL_PSK) {
+        if (!ssl_print_hexbuf(bio, indent + 2,
+                              "psk_identity_hint", 2, &msg, &msglen))
+            return 0;
+    }
+    switch (id) {
+    case SSL_kRSA:
+
+        if (!ssl_print_hexbuf(bio, indent + 2, "rsa_modulus", 2, &msg, &msglen))
+            return 0;
+        if (!ssl_print_hexbuf(bio, indent + 2, "rsa_exponent", 2,
+                              &msg, &msglen))
+            return 0;
+        break;
+
+    case SSL_kDHE:
+    case SSL_kDHEPSK:
+        if (!ssl_print_hexbuf(bio, indent + 2, "dh_p", 2, &msg, &msglen))
+            return 0;
+        if (!ssl_print_hexbuf(bio, indent + 2, "dh_g", 2, &msg, &msglen))
+            return 0;
+        if (!ssl_print_hexbuf(bio, indent + 2, "dh_Ys", 2, &msg, &msglen))
+            return 0;
+        break;
+
+# ifndef OPENSSL_NO_EC
+    case SSL_kECDHE:
+    case SSL_kECDHEPSK:
+        if (msglen < 1)
+            return 0;
+        BIO_indent(bio, indent + 2, 80);
+        if (msg[0] == EXPLICIT_PRIME_CURVE_TYPE)
+            BIO_puts(bio, "explicit_prime\n");
+        else if (msg[0] == EXPLICIT_CHAR2_CURVE_TYPE)
+            BIO_puts(bio, "explicit_char2\n");
+        else if (msg[0] == NAMED_CURVE_TYPE) {
+            int curve;
+            if (msglen < 3)
+                return 0;
+            curve = (msg[1] << 8) | msg[2];
+            BIO_printf(bio, "named_curve: %s (%d)\n",
+                       ssl_trace_str(curve, ssl_curve_tbl), curve);
+            msg += 3;
+            msglen -= 3;
+            if (!ssl_print_hexbuf(bio, indent + 2, "point", 1, &msg, &msglen))
+                return 0;
+        } else {
+            BIO_printf(bio, "UNKNOWN CURVE PARAMETER TYPE %d\n", msg[0]);
+            return 0;
+        }
+        break;
+# endif
+
+    case SSL_kPSK:
+    case SSL_kRSAPSK:
+        break;
+    }
+    if (!(id & SSL_PSK))
+        ssl_print_signature(bio, indent, ssl, &msg, &msglen);
+    return !msglen;
+}
+
+static int ssl_print_certificate(BIO *bio, int indent,
+                                 const unsigned char **pmsg, size_t *pmsglen)
+{
+    size_t msglen = *pmsglen;
+    size_t clen;
+    X509 *x;
+    const unsigned char *p = *pmsg, *q;
+    if (msglen < 3)
+        return 0;
+    clen = (p[0] << 16) | (p[1] << 8) | p[2];
+    if (msglen < clen + 3)
+        return 0;
+    q = p + 3;
+    BIO_indent(bio, indent, 80);
+    BIO_printf(bio, "ASN.1Cert, length=%d", (int)clen);
+    x = d2i_X509(NULL, &q, clen);
+    if (!x)
+        BIO_puts(bio, "<UNPARSEABLE CERTIFICATE>\n");
+    else {
+        BIO_puts(bio, "\n------details-----\n");
+        X509_print_ex(bio, x, XN_FLAG_ONELINE, 0);
+        PEM_write_bio_X509(bio, x);
+        /* Print certificate stuff */
+        BIO_puts(bio, "------------------\n");
+        X509_free(x);
+    }
+    if (q != p + 3 + clen) {
+        BIO_puts(bio, "<TRAILING GARBAGE AFTER CERTIFICATE>\n");
+    }
+    *pmsg += clen + 3;
+    *pmsglen -= clen + 3;
+    return 1;
+}
+
+static int ssl_print_certificates(BIO *bio, int indent,
+                                  const unsigned char *msg, size_t msglen)
+{
+    size_t clen;
+    if (msglen < 3)
+        return 0;
+    clen = (msg[0] << 16) | (msg[1] << 8) | msg[2];
+    if (msglen != clen + 3)
+        return 0;
+    msg += 3;
+    BIO_indent(bio, indent, 80);
+    BIO_printf(bio, "certificate_list, length=%d\n", (int)clen);
+    while (clen > 0) {
+        if (!ssl_print_certificate(bio, indent + 2, &msg, &clen))
+            return 0;
+    }
+    return 1;
+}
+
+static int ssl_print_cert_request(BIO *bio, int indent, SSL *s,
+                                  const unsigned char *msg, size_t msglen)
+{
+    size_t xlen;
+    if (msglen < 1)
+        return 0;
+    xlen = msg[0];
+    if (msglen < xlen + 1)
+        return 0;
+    msg++;
+    BIO_indent(bio, indent, 80);
+    BIO_printf(bio, "certificate_types (len=%d)\n", (int)xlen);
+    if (!ssl_trace_list(bio, indent + 2, msg, xlen, 1, ssl_ctype_tbl))
+        return 0;
+    msg += xlen;
+    msglen -= xlen + 1;
+    if (!SSL_USE_SIGALGS(s))
+        goto skip_sig;
+    if (msglen < 2)
+        return 0;
+    xlen = (msg[0] << 8) | msg[1];
+    if (msglen < xlen + 2 || (xlen & 1))
+        return 0;
+    msg += 2;
+    BIO_indent(bio, indent, 80);
+    BIO_printf(bio, "signature_algorithms (len=%d)\n", (int)xlen);
+    while (xlen > 0) {
+        BIO_indent(bio, indent + 2, 80);
+        BIO_printf(bio, "%s+%s (%d+%d)\n",
+                   ssl_trace_str(msg[0], ssl_md_tbl),
+                   ssl_trace_str(msg[1], ssl_sig_tbl), msg[0], msg[1]);
+        xlen -= 2;
+        msg += 2;
+    }
+    msg += xlen;
+    msglen -= xlen + 2;
+
+ skip_sig:
+    xlen = (msg[0] << 8) | msg[1];
+    BIO_indent(bio, indent, 80);
+    if (msglen < xlen + 2)
+        return 0;
+    msg += 2;
+    msglen -= 2;
+    BIO_printf(bio, "certificate_authorities (len=%d)\n", (int)xlen);
+    while (xlen > 0) {
+        size_t dlen;
+        X509_NAME *nm;
+        const unsigned char *p;
+        if (xlen < 2)
+            return 0;
+        dlen = (msg[0] << 8) | msg[1];
+        if (xlen < dlen + 2)
+            return 0;
+        msg += 2;
+        BIO_indent(bio, indent + 2, 80);
+        BIO_printf(bio, "DistinguishedName (len=%d): ", (int)dlen);
+        p = msg;
+        nm = d2i_X509_NAME(NULL, &p, dlen);
+        if (!nm) {
+            BIO_puts(bio, "<UNPARSEABLE DN>\n");
+        } else {
+            X509_NAME_print_ex(bio, nm, 0, XN_FLAG_ONELINE);
+            BIO_puts(bio, "\n");
+            X509_NAME_free(nm);
+        }
+        xlen -= dlen + 2;
+        msg += dlen;
+    }
+    return 1;
+}
+
+static int ssl_print_ticket(BIO *bio, int indent,
+                            const unsigned char *msg, size_t msglen)
+{
+    unsigned int tick_life;
+    if (msglen == 0) {
+        BIO_indent(bio, indent + 2, 80);
+        BIO_puts(bio, "No Ticket\n");
+        return 1;
+    }
+    if (msglen < 4)
+        return 0;
+    tick_life = (msg[0] << 24) | (msg[1] << 16) | (msg[2] << 8) | msg[3];
+    msglen -= 4;
+    msg += 4;
+    BIO_indent(bio, indent + 2, 80);
+    BIO_printf(bio, "ticket_lifetime_hint=%u\n", tick_life);
+    if (!ssl_print_hexbuf(bio, indent + 2, "ticket", 2, &msg, &msglen))
+        return 0;
+    if (msglen)
+        return 0;
+    return 1;
+}
+
+static int ssl_print_handshake(BIO *bio, SSL *ssl,
+                               const unsigned char *msg, size_t msglen,
+                               int indent)
+{
+    size_t hlen;
+    unsigned char htype;
+    if (msglen < 4)
+        return 0;
+    htype = msg[0];
+    hlen = (msg[1] << 16) | (msg[2] << 8) | msg[3];
+    BIO_indent(bio, indent, 80);
+    BIO_printf(bio, "%s, Length=%d\n",
+               ssl_trace_str(htype, ssl_handshake_tbl), (int)hlen);
+    msg += 4;
+    msglen -= 4;
+    if (SSL_IS_DTLS(ssl)) {
+        if (msglen < 8)
+            return 0;
+        BIO_indent(bio, indent, 80);
+        BIO_printf(bio, "message_seq=%d, fragment_offset=%d, "
+                   "fragment_length=%d\n",
+                   (msg[0] << 8) | msg[1],
+                   (msg[2] << 16) | (msg[3] << 8) | msg[4],
+                   (msg[5] << 16) | (msg[6] << 8) | msg[7]);
+        msg += 8;
+        msglen -= 8;
+    }
+    if (msglen < hlen)
+        return 0;
+    switch (htype) {
+    case SSL3_MT_CLIENT_HELLO:
+        if (!ssl_print_client_hello(bio, ssl, indent + 2, msg, msglen))
+            return 0;
+        break;
+
+    case DTLS1_MT_HELLO_VERIFY_REQUEST:
+        if (!dtls_print_hello_vfyrequest(bio, indent + 2, msg, msglen))
+            return 0;
+        break;
+
+    case SSL3_MT_SERVER_HELLO:
+        if (!ssl_print_server_hello(bio, indent + 2, msg, msglen))
+            return 0;
+        break;
+
+    case SSL3_MT_SERVER_KEY_EXCHANGE:
+        if (!ssl_print_server_keyex(bio, indent + 2, ssl, msg, msglen))
+            return 0;
+        break;
+
+    case SSL3_MT_CLIENT_KEY_EXCHANGE:
+        if (!ssl_print_client_keyex(bio, indent + 2, ssl, msg, msglen))
+            return 0;
+        break;
+
+    case SSL3_MT_CERTIFICATE:
+        if (!ssl_print_certificates(bio, indent + 2, msg, msglen))
+            return 0;
+        break;
+
+    case SSL3_MT_CERTIFICATE_VERIFY:
+        if (!ssl_print_signature(bio, indent + 2, ssl, &msg, &msglen))
+            return 0;
+        break;
+
+    case SSL3_MT_CERTIFICATE_REQUEST:
+        if (!ssl_print_cert_request(bio, indent + 2, ssl, msg, msglen))
+            return 0;
+        break;
+
+    case SSL3_MT_FINISHED:
+        ssl_print_hex(bio, indent + 2, "verify_data", msg, msglen);
+        break;
+
+    case SSL3_MT_SERVER_DONE:
+        if (msglen != 0)
+            ssl_print_hex(bio, indent + 2, "unexpected value", msg, msglen);
+        break;
+
+    case SSL3_MT_NEWSESSION_TICKET:
+        if (!ssl_print_ticket(bio, indent + 2, msg, msglen))
+            return 0;
+        break;
+
+    default:
+        BIO_indent(bio, indent + 2, 80);
+        BIO_puts(bio, "Unsupported, hex dump follows:\n");
+        BIO_dump_indent(bio, (const char *)msg, msglen, indent + 4);
+    }
+    return 1;
+}
+
+static int ssl_print_heartbeat(BIO *bio, int indent,
+                               const unsigned char *msg, size_t msglen)
+{
+    if (msglen < 3)
+        return 0;
+    BIO_indent(bio, indent, 80);
+    BIO_printf(bio, "HeartBeatMessageType: %s\n",
+               ssl_trace_str(msg[0], ssl_hb_type_tbl));
+    msg++;
+    msglen--;
+    if (!ssl_print_hexbuf(bio, indent, "payload", 2, &msg, &msglen))
+        return 0;
+    ssl_print_hex(bio, indent, "padding", msg, msglen);
+    return 1;
+}
+
+const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c)
+{
+    return ssl_trace_str(c->id & 0xFFFF, ssl_ciphers_tbl);
+}
+
+void SSL_trace(int write_p, int version, int content_type,
+               const void *buf, size_t msglen, SSL *ssl, void *arg)
+{
+    const unsigned char *msg = buf;
+    BIO *bio = arg;
+
+    if (write_p == 2) {
+        BIO_puts(bio, "Session ");
+        ssl_print_hex(bio, 0,
+                      ssl_trace_str(content_type, ssl_crypto_tbl), msg, msglen);
+        return;
+    }
+    switch (content_type) {
+    case SSL3_RT_HEADER:
+        {
+            int hvers = msg[1] << 8 | msg[2];
+            BIO_puts(bio, write_p ? "Sent" : "Received");
+            BIO_printf(bio, " Record\nHeader:\n  Version = %s (0x%x)\n",
+                       ssl_trace_str(hvers, ssl_version_tbl), hvers);
+            if (SSL_IS_DTLS(ssl)) {
+                BIO_printf(bio,
+                           "  epoch=%d, sequence_number=%04x%04x%04x\n",
+                           (msg[3] << 8 | msg[4]),
+                           (msg[5] << 8 | msg[6]),
+                           (msg[7] << 8 | msg[8]), (msg[9] << 8 | msg[10]));
+            }
+
+            BIO_printf(bio, "  Content Type = %s (%d)\n  Length = %d",
+                       ssl_trace_str(msg[0], ssl_content_tbl), msg[0],
+                       msg[msglen - 2] << 8 | msg[msglen - 1]);
+        }
+        break;
+    case SSL3_RT_HANDSHAKE:
+        if (!ssl_print_handshake(bio, ssl, msg, msglen, 4))
+            BIO_printf(bio, "Message length parse error!\n");
+        break;
+
+    case SSL3_RT_CHANGE_CIPHER_SPEC:
+        if (msglen == 1 && msg[0] == 1)
+            BIO_puts(bio, "    change_cipher_spec (1)\n");
+        else
+            ssl_print_hex(bio, 4, "unknown value", msg, msglen);
+        break;
+
+    case SSL3_RT_ALERT:
+        if (msglen != 2)
+            BIO_puts(bio, "    Illegal Alert Length\n");
+        else {
+            BIO_printf(bio, "    Level=%s(%d), description=%s(%d)\n",
+                       SSL_alert_type_string_long(msg[0] << 8),
+                       msg[0], SSL_alert_desc_string_long(msg[1]), msg[1]);
+        }
+    case DTLS1_RT_HEARTBEAT:
+        ssl_print_heartbeat(bio, 4, msg, msglen);
+        break;
+
+    }
+
+    BIO_puts(bio, "\n");
+}
+
+#endif
Index: EcnlProtoTool/trunk/openssl-1.1.0e/ssl/tls_srp.c
===================================================================
--- EcnlProtoTool/trunk/openssl-1.1.0e/ssl/tls_srp.c	(revision 331)
+++ EcnlProtoTool/trunk/openssl-1.1.0e/ssl/tls_srp.c	(revision 331)
@@ -0,0 +1,469 @@
+/*
+ * Copyright 2004-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 <openssl/crypto.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include "ssl_locl.h"
+
+#ifndef OPENSSL_NO_SRP
+# include <openssl/srp.h>
+
+int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st *ctx)
+{
+    if (ctx == NULL)
+        return 0;
+    OPENSSL_free(ctx->srp_ctx.login);
+    BN_free(ctx->srp_ctx.N);
+    BN_free(ctx->srp_ctx.g);
+    BN_free(ctx->srp_ctx.s);
+    BN_free(ctx->srp_ctx.B);
+    BN_free(ctx->srp_ctx.A);
+    BN_free(ctx->srp_ctx.a);
+    BN_free(ctx->srp_ctx.b);
+    BN_free(ctx->srp_ctx.v);
+    ctx->srp_ctx.TLS_ext_srp_username_callback = NULL;
+    ctx->srp_ctx.SRP_cb_arg = NULL;
+    ctx->srp_ctx.SRP_verify_param_callback = NULL;
+    ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
+    ctx->srp_ctx.N = NULL;
+    ctx->srp_ctx.g = NULL;
+    ctx->srp_ctx.s = NULL;
+    ctx->srp_ctx.B = NULL;
+    ctx->srp_ctx.A = NULL;
+    ctx->srp_ctx.a = NULL;
+    ctx->srp_ctx.b = NULL;
+    ctx->srp_ctx.v = NULL;
+    ctx->srp_ctx.login = NULL;
+    ctx->srp_ctx.info = NULL;
+    ctx->srp_ctx.strength = SRP_MINIMAL_N;
+    ctx->srp_ctx.srp_Mask = 0;
+    return (1);
+}
+
+int SSL_SRP_CTX_free(struct ssl_st *s)
+{
+    if (s == NULL)
+        return 0;
+    OPENSSL_free(s->srp_ctx.login);
+    BN_free(s->srp_ctx.N);
+    BN_free(s->srp_ctx.g);
+    BN_free(s->srp_ctx.s);
+    BN_free(s->srp_ctx.B);
+    BN_free(s->srp_ctx.A);
+    BN_free(s->srp_ctx.a);
+    BN_free(s->srp_ctx.b);
+    BN_free(s->srp_ctx.v);
+    s->srp_ctx.TLS_ext_srp_username_callback = NULL;
+    s->srp_ctx.SRP_cb_arg = NULL;
+    s->srp_ctx.SRP_verify_param_callback = NULL;
+    s->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
+    s->srp_ctx.N = NULL;
+    s->srp_ctx.g = NULL;
+    s->srp_ctx.s = NULL;
+    s->srp_ctx.B = NULL;
+    s->srp_ctx.A = NULL;
+    s->srp_ctx.a = NULL;
+    s->srp_ctx.b = NULL;
+    s->srp_ctx.v = NULL;
+    s->srp_ctx.login = NULL;
+    s->srp_ctx.info = NULL;
+    s->srp_ctx.strength = SRP_MINIMAL_N;
+    s->srp_ctx.srp_Mask = 0;
+    return (1);
+}
+
+int SSL_SRP_CTX_init(struct ssl_st *s)
+{
+    SSL_CTX *ctx;
+
+    if ((s == NULL) || ((ctx = s->ctx) == NULL))
+        return 0;
+    s->srp_ctx.SRP_cb_arg = ctx->srp_ctx.SRP_cb_arg;
+    /* set client Hello login callback */
+    s->srp_ctx.TLS_ext_srp_username_callback =
+        ctx->srp_ctx.TLS_ext_srp_username_callback;
+    /* set SRP N/g param callback for verification */
+    s->srp_ctx.SRP_verify_param_callback =
+        ctx->srp_ctx.SRP_verify_param_callback;
+    /* set SRP client passwd callback */
+    s->srp_ctx.SRP_give_srp_client_pwd_callback =
+        ctx->srp_ctx.SRP_give_srp_client_pwd_callback;
+
+    s->srp_ctx.N = NULL;
+    s->srp_ctx.g = NULL;
+    s->srp_ctx.s = NULL;
+    s->srp_ctx.B = NULL;
+    s->srp_ctx.A = NULL;
+    s->srp_ctx.a = NULL;
+    s->srp_ctx.b = NULL;
+    s->srp_ctx.v = NULL;
+    s->srp_ctx.login = NULL;
+    s->srp_ctx.info = ctx->srp_ctx.info;
+    s->srp_ctx.strength = ctx->srp_ctx.strength;
+
+    if (((ctx->srp_ctx.N != NULL) &&
+         ((s->srp_ctx.N = BN_dup(ctx->srp_ctx.N)) == NULL)) ||
+        ((ctx->srp_ctx.g != NULL) &&
+         ((s->srp_ctx.g = BN_dup(ctx->srp_ctx.g)) == NULL)) ||
+        ((ctx->srp_ctx.s != NULL) &&
+         ((s->srp_ctx.s = BN_dup(ctx->srp_ctx.s)) == NULL)) ||
+        ((ctx->srp_ctx.B != NULL) &&
+         ((s->srp_ctx.B = BN_dup(ctx->srp_ctx.B)) == NULL)) ||
+        ((ctx->srp_ctx.A != NULL) &&
+         ((s->srp_ctx.A = BN_dup(ctx->srp_ctx.A)) == NULL)) ||
+        ((ctx->srp_ctx.a != NULL) &&
+         ((s->srp_ctx.a = BN_dup(ctx->srp_ctx.a)) == NULL)) ||
+        ((ctx->srp_ctx.v != NULL) &&
+         ((s->srp_ctx.v = BN_dup(ctx->srp_ctx.v)) == NULL)) ||
+        ((ctx->srp_ctx.b != NULL) &&
+         ((s->srp_ctx.b = BN_dup(ctx->srp_ctx.b)) == NULL))) {
+        SSLerr(SSL_F_SSL_SRP_CTX_INIT, ERR_R_BN_LIB);
+        goto err;
+    }
+    if ((ctx->srp_ctx.login != NULL) &&
+        ((s->srp_ctx.login = OPENSSL_strdup(ctx->srp_ctx.login)) == NULL)) {
+        SSLerr(SSL_F_SSL_SRP_CTX_INIT, ERR_R_INTERNAL_ERROR);
+        goto err;
+    }
+    s->srp_ctx.srp_Mask = ctx->srp_ctx.srp_Mask;
+
+    return (1);
+ err:
+    OPENSSL_free(s->srp_ctx.login);
+    BN_free(s->srp_ctx.N);
+    BN_free(s->srp_ctx.g);
+    BN_free(s->srp_ctx.s);
+    BN_free(s->srp_ctx.B);
+    BN_free(s->srp_ctx.A);
+    BN_free(s->srp_ctx.a);
+    BN_free(s->srp_ctx.b);
+    BN_free(s->srp_ctx.v);
+    return (0);
+}
+
+int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st *ctx)
+{
+    if (ctx == NULL)
+        return 0;
+
+    ctx->srp_ctx.SRP_cb_arg = NULL;
+    /* set client Hello login callback */
+    ctx->srp_ctx.TLS_ext_srp_username_callback = NULL;
+    /* set SRP N/g param callback for verification */
+    ctx->srp_ctx.SRP_verify_param_callback = NULL;
+    /* set SRP client passwd callback */
+    ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL;
+
+    ctx->srp_ctx.N = NULL;
+    ctx->srp_ctx.g = NULL;
+    ctx->srp_ctx.s = NULL;
+    ctx->srp_ctx.B = NULL;
+    ctx->srp_ctx.A = NULL;
+    ctx->srp_ctx.a = NULL;
+    ctx->srp_ctx.b = NULL;
+    ctx->srp_ctx.v = NULL;
+    ctx->srp_ctx.login = NULL;
+    ctx->srp_ctx.srp_Mask = 0;
+    ctx->srp_ctx.info = NULL;
+    ctx->srp_ctx.strength = SRP_MINIMAL_N;
+
+    return (1);
+}
+
+/* server side */
+int SSL_srp_server_param_with_username(SSL *s, int *ad)
+{
+    unsigned char b[SSL_MAX_MASTER_KEY_LENGTH];
+    int al;
+
+    *ad = SSL_AD_UNKNOWN_PSK_IDENTITY;
+    if ((s->srp_ctx.TLS_ext_srp_username_callback != NULL) &&
+        ((al =
+          s->srp_ctx.TLS_ext_srp_username_callback(s, ad,
+                                                   s->srp_ctx.SRP_cb_arg)) !=
+         SSL_ERROR_NONE))
+        return al;
+
+    *ad = SSL_AD_INTERNAL_ERROR;
+    if ((s->srp_ctx.N == NULL) ||
+        (s->srp_ctx.g == NULL) ||
+        (s->srp_ctx.s == NULL) || (s->srp_ctx.v == NULL))
+        return SSL3_AL_FATAL;
+
+    if (RAND_bytes(b, sizeof(b)) <= 0)
+        return SSL3_AL_FATAL;
+    s->srp_ctx.b = BN_bin2bn(b, sizeof(b), NULL);
+    OPENSSL_cleanse(b, sizeof(b));
+
+    /* Calculate:  B = (kv + g^b) % N  */
+
+    return ((s->srp_ctx.B =
+             SRP_Calc_B(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g,
+                        s->srp_ctx.v)) !=
+            NULL) ? SSL_ERROR_NONE : SSL3_AL_FATAL;
+}
+
+/*
+ * If the server just has the raw password, make up a verifier entry on the
+ * fly
+ */
+int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass,
+                                const char *grp)
+{
+    SRP_gN *GN = SRP_get_default_gN(grp);
+    if (GN == NULL)
+        return -1;
+    s->srp_ctx.N = BN_dup(GN->N);
+    s->srp_ctx.g = BN_dup(GN->g);
+    BN_clear_free(s->srp_ctx.v);
+    s->srp_ctx.v = NULL;
+    BN_clear_free(s->srp_ctx.s);
+    s->srp_ctx.s = NULL;
+    if (!SRP_create_verifier_BN
+        (user, pass, &s->srp_ctx.s, &s->srp_ctx.v, GN->N, GN->g))
+        return -1;
+
+    return 1;
+}
+
+int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g,
+                             BIGNUM *sa, BIGNUM *v, char *info)
+{
+    if (N != NULL) {
+        if (s->srp_ctx.N != NULL) {
+            if (!BN_copy(s->srp_ctx.N, N)) {
+                BN_free(s->srp_ctx.N);
+                s->srp_ctx.N = NULL;
+            }
+        } else
+            s->srp_ctx.N = BN_dup(N);
+    }
+    if (g != NULL) {
+        if (s->srp_ctx.g != NULL) {
+            if (!BN_copy(s->srp_ctx.g, g)) {
+                BN_free(s->srp_ctx.g);
+                s->srp_ctx.g = NULL;
+            }
+        } else
+            s->srp_ctx.g = BN_dup(g);
+    }
+    if (sa != NULL) {
+        if (s->srp_ctx.s != NULL) {
+            if (!BN_copy(s->srp_ctx.s, sa)) {
+                BN_free(s->srp_ctx.s);
+                s->srp_ctx.s = NULL;
+            }
+        } else
+            s->srp_ctx.s = BN_dup(sa);
+    }
+    if (v != NULL) {
+        if (s->srp_ctx.v != NULL) {
+            if (!BN_copy(s->srp_ctx.v, v)) {
+                BN_free(s->srp_ctx.v);
+                s->srp_ctx.v = NULL;
+            }
+        } else
+            s->srp_ctx.v = BN_dup(v);
+    }
+    s->srp_ctx.info = info;
+
+    if (!(s->srp_ctx.N) ||
+        !(s->srp_ctx.g) || !(s->srp_ctx.s) || !(s->srp_ctx.v))
+        return -1;
+
+    return 1;
+}
+
+int srp_generate_server_master_secret(SSL *s)
+{
+    BIGNUM *K = NULL, *u = NULL;
+    int ret = -1, tmp_len = 0;
+    unsigned char *tmp = NULL;
+
+    if (!SRP_Verify_A_mod_N(s->srp_ctx.A, s->srp_ctx.N))
+        goto err;
+    if ((u = SRP_Calc_u(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N)) == NULL)
+        goto err;
+    if ((K = SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b,
+                                 s->srp_ctx.N)) == NULL)
+        goto err;
+
+    tmp_len = BN_num_bytes(K);
+    if ((tmp = OPENSSL_malloc(tmp_len)) == NULL)
+        goto err;
+    BN_bn2bin(K, tmp);
+    ret = ssl_generate_master_secret(s, tmp, tmp_len, 1);
+ err:
+    BN_clear_free(K);
+    BN_clear_free(u);
+    return ret;
+}
+
+/* client side */
+int srp_generate_client_master_secret(SSL *s)
+{
+    BIGNUM *x = NULL, *u = NULL, *K = NULL;
+    int ret = -1, tmp_len = 0;
+    char *passwd = NULL;
+    unsigned char *tmp = NULL;
+
+    /*
+     * Checks if b % n == 0
+     */
+    if (SRP_Verify_B_mod_N(s->srp_ctx.B, s->srp_ctx.N) == 0)
+        goto err;
+    if ((u = SRP_Calc_u(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N)) == NULL)
+        goto err;
+    if (s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL)
+        goto err;
+    if (!
+        (passwd =
+         s->srp_ctx.SRP_give_srp_client_pwd_callback(s, s->srp_ctx.SRP_cb_arg)))
+        goto err;
+    if ((x = SRP_Calc_x(s->srp_ctx.s, s->srp_ctx.login, passwd)) == NULL)
+        goto err;
+    if ((K = SRP_Calc_client_key(s->srp_ctx.N, s->srp_ctx.B, s->srp_ctx.g, x,
+                                 s->srp_ctx.a, u)) == NULL)
+        goto err;
+
+    tmp_len = BN_num_bytes(K);
+    if ((tmp = OPENSSL_malloc(tmp_len)) == NULL)
+        goto err;
+    BN_bn2bin(K, tmp);
+    ret = ssl_generate_master_secret(s, tmp, tmp_len, 1);
+ err:
+    BN_clear_free(K);
+    BN_clear_free(x);
+    if (passwd != NULL)
+        OPENSSL_clear_free(passwd, strlen(passwd));
+    BN_clear_free(u);
+    return ret;
+}
+
+int srp_verify_server_param(SSL *s, int *al)
+{
+    SRP_CTX *srp = &s->srp_ctx;
+    /*
+     * Sanity check parameters: we can quickly check B % N == 0 by checking B
+     * != 0 since B < N
+     */
+    if (BN_ucmp(srp->g, srp->N) >= 0 || BN_ucmp(srp->B, srp->N) >= 0
+        || BN_is_zero(srp->B)) {
+        *al = SSL3_AD_ILLEGAL_PARAMETER;
+        return 0;
+    }
+
+    if (BN_num_bits(srp->N) < srp->strength) {
+        *al = TLS1_AD_INSUFFICIENT_SECURITY;
+        return 0;
+    }
+
+    if (srp->SRP_verify_param_callback) {
+        if (srp->SRP_verify_param_callback(s, srp->SRP_cb_arg) <= 0) {
+            *al = TLS1_AD_INSUFFICIENT_SECURITY;
+            return 0;
+        }
+    } else if (!SRP_check_known_gN_param(srp->g, srp->N)) {
+        *al = TLS1_AD_INSUFFICIENT_SECURITY;
+        return 0;
+    }
+
+    return 1;
+}
+
+int SRP_Calc_A_param(SSL *s)
+{
+    unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH];
+
+    if (RAND_bytes(rnd, sizeof(rnd)) <= 0)
+        return 0;
+    s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a);
+    OPENSSL_cleanse(rnd, sizeof(rnd));
+
+    if (!(s->srp_ctx.A = SRP_Calc_A(s->srp_ctx.a, s->srp_ctx.N, s->srp_ctx.g)))
+        return 0;
+
+    return 1;
+}
+
+BIGNUM *SSL_get_srp_g(SSL *s)
+{
+    if (s->srp_ctx.g != NULL)
+        return s->srp_ctx.g;
+    return s->ctx->srp_ctx.g;
+}
+
+BIGNUM *SSL_get_srp_N(SSL *s)
+{
+    if (s->srp_ctx.N != NULL)
+        return s->srp_ctx.N;
+    return s->ctx->srp_ctx.N;
+}
+
+char *SSL_get_srp_username(SSL *s)
+{
+    if (s->srp_ctx.login != NULL)
+        return s->srp_ctx.login;
+    return s->ctx->srp_ctx.login;
+}
+
+char *SSL_get_srp_userinfo(SSL *s)
+{
+    if (s->srp_ctx.info != NULL)
+        return s->srp_ctx.info;
+    return s->ctx->srp_ctx.info;
+}
+
+# define tls1_ctx_ctrl ssl3_ctx_ctrl
+# define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl
+
+int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name)
+{
+    return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME, 0, name);
+}
+
+int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password)
+{
+    return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD, 0, password);
+}
+
+int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength)
+{
+    return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH, strength,
+                         NULL);
+}
+
+int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx,
+                                          int (*cb) (SSL *, void *))
+{
+    return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_VERIFY_PARAM_CB,
+                                  (void (*)(void))cb);
+}
+
+int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg)
+{
+    return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_SRP_ARG, 0, arg);
+}
+
+int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx,
+                                      int (*cb) (SSL *, int *, void *))
+{
+    return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB,
+                                  (void (*)(void))cb);
+}
+
+int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx,
+                                        char *(*cb) (SSL *, void *))
+{
+    return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB,
+                                  (void (*)(void))cb);
+}
+
+#endif
Index: EcnlProtoTool/trunk/prototool/.cproject
===================================================================
--- EcnlProtoTool/trunk/prototool/.cproject	(revision 321)
+++ EcnlProtoTool/trunk/prototool/.cproject	(revision 331)
@@ -41,5 +41,5 @@
 							</tool>
 							<tool id="com.renesas.cdt.rz.debug.win32.tool.compiler.Id.1599684796" name="Compiler" superClass="com.renesas.cdt.rz.debug.win32.tool.compiler.Id">
-								<option defaultValue="true" id="com.renesas.cdt.core.Compiler.option.misc2.705849748" name="æ¨æºã·ã¹ãã ã»ãã£ã¬ã¯ããªã¼ã§ãããã¼ã»ãã¡ã¤ã«ãæ¤ç´¢ããªã (-nostdinc)" superClass="com.renesas.cdt.core.Compiler.option.misc2" value="false" valueType="boolean"/>
+								<option defaultValue="true" id="com.renesas.cdt.core.Compiler.option.misc2.705849748" name="æ¨æºã·ã¹ãã ã»ãã£ã¬ã¯ããªã¼ã§ãããã¼ã»ãã¡ã¤ã«ãæ¤ç´¢ããªã (-nostdinc)" superClass="com.renesas.cdt.core.Compiler.option.misc2" value="true" valueType="boolean"/>
 								<option id="com.renesas.cdt.rz.Debug.Compiler.option.architecture.1326747160" name="ã¢ã¼ã­ãã¯ãã£ã¼" superClass="com.renesas.cdt.rz.Debug.Compiler.option.architecture" value="com.renesas.cdt.rz.Debug.Compiler.option.architecture.armv7a" valueType="enumerated"/>
 								<option id="com.renesas.cdt.rz.Debug.Compiler.option.cpuType.1644847738" name="CPU ã¿ã¤ã" superClass="com.renesas.cdt.rz.Debug.Compiler.option.cpuType" value="com.renesas.cdt.rz.Debug.Compiler.option.cpuType.rza" valueType="enumerated"/>
@@ -53,18 +53,12 @@
 								<option id="com.renesas.cdt.core.Compiler.option.device.443282008" name="Device" superClass="com.renesas.cdt.core.Compiler.option.device" value="R7S721001" valueType="string"/>
 								<option id="com.renesas.cdt.core.Compiler.option.deviceShortName.752035440" name="DeviceShortName" superClass="com.renesas.cdt.core.Compiler.option.deviceShortName" value="R7S721001" valueType="string"/>
-								<option id="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal.1821950522" name="Decimal representation of '-Wsatck-usage'" superClass="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal" value="256" valueType="string"/>
+								<option id="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal.1821950522" name="Decimal representation of '-Wstack-usage'" superClass="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal" value="256" valueType="string"/>
 								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.core.Compiler.option.includeFileDir.461834980" name="ã¤ã³ã¯ã«ã¼ãã»ãã¡ã¤ã«ã»ãã£ã¬ã¯ããªã¼" superClass="com.renesas.cdt.core.Compiler.option.includeFileDir" valueType="includePath">
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:}/musl-1.1.12/include&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:}/onigmo-5.15.0/src&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre/mbed/hal}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre/mbed/api}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre/mbed/targets/cmsis}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre/mbed/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre/mbed/targets/cmsis/TARGET_RENESAS/TARGET_RZ_A1H}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre/mbed/targets/cmsis/TARGET_RENESAS/TARGET_RZ_A1H/inc}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/asp3_dcre/mbed/targets/cmsis/TARGET_RENESAS/TARGET_RZ_A1H/inc/iodefines}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mruby-1.2.0/include}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/musl-1.1.18/include}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:}/onigmo-6.1.3/src&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mruby-1.3.0/include}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mbed_api/src}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/src}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:}/ntshell/ntshell&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:}/ntshell&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:}/ntshell/gr_peach&quot;"/>
 								</option>
@@ -72,5 +66,4 @@
 									<listOptionValue builtIn="false" value="MRB_GC_STRESS"/>
 									<listOptionValue builtIn="false" value="MRB_ENABLE_DEBUG_HOOK"/>
-									<listOptionValue builtIn="false" value="FD_SETSIZE=32"/>
 								</option>
 								<option id="com.renesas.cdt.core.Compiler.option.stdWarnings.1803476376" name="æ¨æºã®è­¦å" superClass="com.renesas.cdt.core.Compiler.option.stdWarnings" value="com.renesas.cdt.core.Compiler.option.stdWarnings.enableAll" valueType="enumerated"/>
@@ -118,4 +111,5 @@
 ã®å¯¾å¿ããã»ã¯ã·ã§ã³ã«é
 ç½®ãã (-ffunction-sections)" superClass="com.renesas.cdt.core.Compiler.option.misc19" value="true" valueType="boolean"/>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.renesas.cdt.rz.Debug.Compiler.option.userDefinedOptions.203692350" name="ã¦ã¼ã¶ã¼å®ç¾©ãªãã·ã§ã³" superClass="com.renesas.cdt.rz.Debug.Compiler.option.userDefinedOptions" valueType="stringList"/>
 								<inputType id="%Base.Compiler.C.InputType.Id.347710053" name="C å
 ¥å" superClass="%Base.Compiler.C.InputType.Id"/>
@@ -138,8 +132,13 @@
 							<tool command="arm-none-eabi-gcc" id="com.renesas.cdt.rz.debug.win32.tool.linker.Id.68534288" name="Linker" superClass="com.renesas.cdt.rz.debug.win32.tool.linker.Id">
 								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.rz.Debug.Linker.option.archiveSearchDirectories.1048191791" name="ã¢ã¼ã«ã¤ãæ¤ç´¢ãã£ã¬ã¯ããªã¼" superClass="com.renesas.cdt.rz.Debug.Linker.option.archiveSearchDirectories" valueType="stringList">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/musl-1.1.18/lib}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/lib}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/tcc-0.9.26/Debug}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/onigmo-5.15.0/Debug}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mruby-1.2.0/build/arm-none-eabi/lib}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/openssl-1.1.0e/Debug}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/zlib-1.2.11/Debug}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/curl-7.57.0/Debug}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/tcc-0.9.27/Debug}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/onigmo-6.1.3/Debug}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mbed_api/Debug}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/mruby-1.3.0/build/arm-none-eabi/lib}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${TCINSTALL}/lib/gcc/arm-none-eabi/${GCC_VERSION}/armv7-ar/thumb/fpu&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${TCINSTALL}/arm-none-eabi/lib/armv7-ar/thumb/fpu&quot;"/>
@@ -164,13 +163,5 @@
 									<listOptionValue builtIn="false" value="&quot;.\src\xprintf.o&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;.\src\arduino.o&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;.\src\shellif.o&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ntshell/Debug/ntshell_bin.o}&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;.\src/musl\freeaddrinfo.o&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;.\src/musl\gai_strerror.o&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;.\src/musl\getaddrinfo.o&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;.\src/musl\inet_aton.o&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;.\src/musl\lookup_ipliteral.o&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;.\src/musl\lookup_name.o&quot;"/>
-									<listOptionValue builtIn="false" value="&quot;.\src/musl\lookup_serv.o&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;.\src/libbb\bb_strtonum.o&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;.\src/libbb\bb_time.o&quot;"/>
@@ -194,18 +185,26 @@
 									<listOptionValue builtIn="false" value="&quot;.\src/libbb\xfuncs.o&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;.\src/libbb\xfuncs_printf.o&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;.\src\shellif.o&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/musl-1.1.18/lib/crt1.o}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/musl-1.1.18/lib/libc.a}&quot;"/>
 								</option>
 								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.core.Linker.option.additionalInputFiles.1022783886" name="è¿½å å
 ¥åãã¡ã¤ã«" superClass="com.renesas.cdt.core.Linker.option.additionalInputFiles" valueType="userObjs">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/musl-1.1.18/lib/crt1.o}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/musl-1.1.18/lib/libc.a}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/ntshell/Debug/ntshell_bin.o}&quot;"/>
 								</option>
 								<option id="com.renesas.cdt.core.Linker.option.linkOrderUsed.1088314581" name="ãªã³ã¯é ã®ã«ã¹ã¿ãã¤ãºä½¿ç¨" superClass="com.renesas.cdt.core.Linker.option.linkOrderUsed" value="false" valueType="boolean"/>
 								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.rz.Debug.Linker.option.archiveLibraryFiles.397699621" name="ã¢ã¼ã«ã¤ã ( ã©ã¤ãã©ãªã¼ ) ãã¡ã¤ã«" superClass="com.renesas.cdt.rz.Debug.Linker.option.archiveLibraryFiles" valueType="stringList">
-									<listOptionValue builtIn="false" value="out"/>
-									<listOptionValue builtIn="false" value="m"/>
 									<listOptionValue builtIn="false" value="gcc"/>
+									<listOptionValue builtIn="false" value="ce"/>
+									<listOptionValue builtIn="false" value="openssl"/>
+									<listOptionValue builtIn="false" value="z"/>
+									<listOptionValue builtIn="false" value="curl"/>
+									<listOptionValue builtIn="false" value="tcc"/>
 									<listOptionValue builtIn="false" value="onigmo"/>
 									<listOptionValue builtIn="false" value="mruby"/>
 									<listOptionValue builtIn="false" value="mrbcode"/>
-									<listOptionValue builtIn="false" value="tcc"/>
+									<listOptionValue builtIn="false" value="mbed_api"/>
 								</option>
 								<option command="-Wl,--gc-sections" id="com.renesas.cdt.core.Linker.option.misc19.807194175" name="æªä½¿ç¨ã®å
@@ -249,3 +248,4 @@
 		</buildTargets>
 	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
 </cproject>
Index: EcnlProtoTool/trunk/prototool/.info
===================================================================
--- EcnlProtoTool/trunk/prototool/.info	(revision 321)
+++ EcnlProtoTool/trunk/prototool/.info	(revision 331)
@@ -4,4 +4,4 @@
 GCC_STRING=5.2-GNUARM-NONE_v16.01
 VERSION_IDE=
-E2STUDIO_VERSION=5.3.1.002
+E2STUDIO_VERSION=5.4.0.018
 ACTIVE_CONFIGURATION=Debug
Index: EcnlProtoTool/trunk/prototool/.project
===================================================================
--- EcnlProtoTool/trunk/prototool/.project	(revision 321)
+++ EcnlProtoTool/trunk/prototool/.project	(revision 331)
@@ -4,8 +4,12 @@
 	<comment></comment>
 	<projects>
-		<project>mruby-1.2.0</project>
+		<project>curl-7.57.0</project>
+		<project>mbed_api</project>
+		<project>mruby-1.3.0</project>
 		<project>ntshell</project>
-		<project>onigmo-5.15.0</project>
-		<project>tcc-0.9.26</project>
+		<project>onigmo-6.1.3</project>
+		<project>openssl-1.1.0e</project>
+		<project>tcc-0.9.27</project>
+		<project>zlib-1.2.11</project>
 	</projects>
 	<buildSpec>
Index: EcnlProtoTool/trunk/prototool/build_newlib.bat
===================================================================
--- EcnlProtoTool/trunk/prototool/build_newlib.bat	(revision 321)
+++ 	(revision )
@@ -1,15 +1,0 @@
-@ECHO OFF
-set PATH=%PATH%;C:\Program Files (x86)\KPIT\GNUARM-NONEv16.01-EABI\arm-none-eabi\arm-none-eabi\bin
-
-copy "C:\Program Files (x86)\KPIT\GNUARM-NONEv16.01-EABI\arm-none-eabi\arm-none-eabi\arm-none-eabi\lib\armv7-ar\thumb\fpu\libc.a" .\libout.a
-arm-none-eabi-ar d libout.a lib_a-abort.o lib_a-syscalls.o lib_a-localtime.o lib_a-svfprintf.o lib_a-vfprintf.o lib_a-svfiprintf.o lib_a-vfiprintf.o
-
-copy libout.a lib
-rem copy libout.a libopt.a 
-rem arm-none-eabi-ar x libopt.a lib_a-setjmp.o
-
-rem arm-none-eabi-libgen --select-lib=newlib --header-files=all --compiler-options=-mcpu=cortex-a9,-march=armv7-a,-mlittle-endian,-mthumb-interwork,-mfloat-abi=hard,-mfpu=vfp,-Os,-ffunction-sections,-fdata-sections,-fno-function-cse,-funit-at-a-time,-falign-jumps --assembler-options=-mcpu=cortex-a9,-march=armv7-a,-mlittle-endian,-mthumb-interwork,-mfloat-abi=hard,-mfpu=vfp --output=libopt.a
-rem arm-none-eabi-libgen --select-lib=optlib --header-files=all --compiler-options=-mcpu=cortex-a9,-march=armv7-a,-mlittle-endian,-mthumb-interwork,-mfloat-abi=hard,-mfpu=vfp,-Os,-ffunction-sections,-fdata-sections,-fno-function-cse,-funit-at-a-time,-falign-jumps --assembler-options=-mcpu=cortex-a9,-march=armv7-a,-mlittle-endian,-mthumb-interwork,-mfloat-abi=hard,-mfpu=vfp --output=libopt.a
-rem arm-none-eabi-ar r libopt.a lib_a-setjmp.o
-
-rem copy libopt.a lib
Index: EcnlProtoTool/trunk/prototool/lib/makefile.mrbc
===================================================================
--- EcnlProtoTool/trunk/prototool/lib/makefile.mrbc	(revision 321)
+++ EcnlProtoTool/trunk/prototool/lib/makefile.mrbc	(revision 331)
@@ -2,7 +2,7 @@
 CC=arm-none-eabi-gcc
 AR=arm-none-eabi-ar
-MRBC=../../mruby-1.2.0/bin/mrbc
+MRBC=../../mruby-1.3.0/bin/mrbc
 
-CFLAGS=-mcpu=cortex-a9 -march=armv7-a -mlittle-endian -marm -mthumb-interwork -mfloat-abi=hard -mfpu=vfpv3 -I../../mruby-1.2.0/include
+CFLAGS=-mcpu=cortex-a9 -march=armv7-a -mlittle-endian -marm -mthumb-interwork -mfloat-abi=hard -mfpu=vfpv3 -I../../mruby-1.3.0/include
 COBJS=echo_server.o echo_client.o
 CSRCS=$(foreach file,$(COBJS),$(file:.o=.c))
Index: EcnlProtoTool/trunk/prototool/llbruby.h
===================================================================
--- EcnlProtoTool/trunk/prototool/llbruby.h	(revision 321)
+++ EcnlProtoTool/trunk/prototool/llbruby.h	(revision 331)
@@ -106,8 +106,8 @@
 #define RB_PIN25	25
 
-#define PIN_LED0	LED1
-#define PIN_LED1	LED2
-#define PIN_LED2	LED3
-#define PIN_LED3	LED4
+#define PIN_LED0	111
+#define PIN_LED1	112
+#define PIN_LED2	113
+#define PIN_LED3	114
 #define RB_LED	PIN_LED0
 
Index: EcnlProtoTool/trunk/prototool/src/arduino.c
===================================================================
--- EcnlProtoTool/trunk/prototool/src/arduino.c	(revision 321)
+++ EcnlProtoTool/trunk/prototool/src/arduino.c	(revision 331)
@@ -4,4 +4,5 @@
 #include <stdio.h>
 #include <fcntl.h>
+#include <sys/stat.h>
 #include "../llbruby.h"
 
@@ -544,2 +545,68 @@
 	return 0;
 }
+
+unsigned int Utf8_to_Utf16(const char *src, int *code_size)
+{
+	int i;
+	unsigned int uc = 0;
+	unsigned char len = 0;
+
+	len = 0;
+	if ((src[0] & 0x80) == 0) { uc = src[0] & 0x7F; len = 0; }
+	else if ((src[0] & 0xE0) == 0xC0) { uc = src[0] & 0x1F; len = 1; }
+	else if ((src[0] & 0xF0) == 0xE0) { uc = src[0] & 0x0F; len = 2; }
+	else if ((src[0] & 0xF8) == 0xF0) { uc = src[0] & 0x07; len = 3; }
+	else if ((src[0] & 0xFC) == 0xF8) { uc = src[0] & 0x03; len = 4; }
+	else if ((src[0] & 0xFE) == 0xFC) { uc = src[0] & 0x01; len = 5; }
+
+	i = 1;
+	while ((i <= len) && ((src[i] & 0xC0) == 0x80)) {
+		uc = (uc << 6) | (src[i] & 0x3F);
+		i++;
+	}
+
+	//消費文字数設定
+	*code_size = i;
+
+	//現状、2バイト限定
+	return uc;
+}
+
+int bs_char_count(char *str, int pos)
+{
+	int num = 1, local_pos = pos;
+	char *c;
+
+	while (1) {
+		c = str + local_pos;
+
+		if ((*c & 0x80) != 0x80)
+			return num;
+
+		if (((*c & 0xE0) == 0xC0) && (num == 2)) {
+			return num;
+		}
+		else if (((*c & 0xF0) == 0xE0) && (num == 3)) {
+			return num;
+		}
+		else if (((*c & 0xF8) == 0xF0) && (num == 4)) {
+			return num;
+		}
+		else if (((*c & 0xFC) == 0xF8) && (num == 5)) {
+			return num;
+		}
+		else if (((*c & 0xFE) == 0xFC) && (num == 6)) {
+			return num;
+		}
+		else {
+			if (local_pos > 0) {
+				local_pos--;
+				num++;
+			}
+			else
+				return 0;
+		}
+	}
+
+	return 0;
+}
Index: EcnlProtoTool/trunk/prototool/src/arduino.h
===================================================================
--- EcnlProtoTool/trunk/prototool/src/arduino.h	(revision 321)
+++ EcnlProtoTool/trunk/prototool/src/arduino.h	(revision 331)
@@ -10,24 +10,5 @@
 #include <string.h>
 #include <time.h>
-#include <analogin_api.h>
-#include <analogout_api.h>
-#include <buffer.h>
-#include <can_api.h>
-#include <dma_api.h>
-#include <ethernet_api.h>
-#include <gpio_api.h>
-#include <gpio_irq_api.h>
-#include <i2c_api.h>
-#include <lp_ticker_api.h>
-#include <pinmap.h>
-#include <port_api.h>
-#include <pwmout_api.h>
-#include <rtc_api.h>
-#include <serial_api.h>
-#include <sleep_api.h>
-#include <spi_api.h>
-#include <ticker_api.h>
-#include <us_ticker_api.h>
-#include <wait_api.h>
+#include <mbed_api.h>
 
 #ifndef bool
Index: EcnlProtoTool/trunk/prototool/src/libbb/libbb.h
===================================================================
--- EcnlProtoTool/trunk/prototool/src/libbb/libbb.h	(revision 321)
+++ EcnlProtoTool/trunk/prototool/src/libbb/libbb.h	(revision 331)
@@ -25,5 +25,5 @@
 
 #include <ctype.h>
-#include "_dirent.h"
+#include "dirent.h"
 #include <errno.h>
 #include <fcntl.h>
@@ -61,5 +61,5 @@
 #endif
 #include <sys/wait.h>
-#include "_termios.h"
+#include <termios.h>
 #include <time.h>
 #include <sys/param.h>
Index: EcnlProtoTool/trunk/prototool/src/libbb/vi.c
===================================================================
--- EcnlProtoTool/trunk/prototool/src/libbb/vi.c	(revision 321)
+++ EcnlProtoTool/trunk/prototool/src/libbb/vi.c	(revision 331)
@@ -210,4 +210,5 @@
 # define Isprint(c) ((unsigned char)(c) >= ' ' && (c) != 0x7f && (unsigned char)(c) != 0x9b)
 #else
+#define MULTI_BYTE_MULTIPLE	3
 bool Isprint(unsigned char c)
 {
@@ -228,4 +229,17 @@
 	mbc_st--;
 	return true;
+}
+bool IsMultiByteChar(unsigned char c, int *bytes)
+{
+	bool ret = false;
+	*bytes = 1;
+	if ((c & 0xE0) == 0xC0) { *bytes = 2; }
+	else if ((c & 0xF0) == 0xE0) { *bytes = 3; }
+	else if ((c & 0xF8) == 0xF0) { *bytes = 4; }
+	else if ((c & 0xFC) == 0xF8) { *bytes = 5; }
+	else if ((c & 0xFE) == 0xFC) { *bytes = 6; }
+	if (*bytes != 1)
+		ret = true;
+	return ret;
 }
 #endif
@@ -583,5 +597,9 @@
 static int format_edit_status(void);	// format file status on status line
 static void redraw(int);	// force a full screen refresh
+#ifndef ENABLE_BASIC_MULTI_CHAR_CODE
 static char* format_line(char* /*, int*/);
+#else
+static char* format_line(char* , int*, int*);
+#endif
 static void refresh(int);	// update the terminal from screen[]
 
@@ -1590,4 +1608,7 @@
 	char *tp;
 	int cnt, ro, co;
+#ifdef ENABLE_BASIC_MULTI_CHAR_CODE
+	int last_code_size = 0;
+#endif
 
 	beg_cur = begin_line(d);	// first char of cur line
@@ -1654,4 +1675,5 @@
 		co += (code_size > 1 ? 2 : code_size);
 		tp += code_size;
+		last_code_size = code_size;
 #endif
 	}
@@ -1674,5 +1696,9 @@
 	}
 	if (co >= columns + offset) {
+#ifndef ENABLE_BASIC_MULTI_CHAR_CODE
 		offset = co - columns + 1;
+#else
+		offset = co - columns + (last_code_size > 1 ? 2 : 1);
+#endif
 	}
 	// if the first char of the line is a tab, and "dot" is sitting on it
@@ -1831,5 +1857,10 @@
 			break;
 		if (*p == '\t') {
+#ifndef ENABLE_BASIC_MULTI_CHAR_CODE
 			co = next_tabstop(co);
+#else
+			co += tabstop;
+			p++;
+#endif
 		}
 #ifndef ENABLE_BASIC_MULTI_CHAR_CODE
@@ -1933,7 +1964,11 @@
 {
 	int li;
+	int internal_co = co;
+#ifdef ENABLE_BASIC_MULTI_CHAR_CODE
+	internal_co *= MULTI_BYTE_MULTIPLE;
+#endif
 
 	free(screen);
-	screensize = ro * co + 8;
+	screensize = ro * internal_co + 8;
 	screen = xmalloc(screensize);
 	// initialize the new screen. assume this will be a empty file.
@@ -1941,5 +1976,5 @@
 	//   non-existent text[] lines start with a tilde (~).
 	for (li = 1; li < ro - 1; li++) {
-		screen[(li * co) + 0] = '~';
+		screen[(li * internal_co) + 0] = '~';
 	}
 	return screen;
@@ -3361,6 +3396,43 @@
 }
 
+#ifdef ENABLE_BASIC_MULTI_CHAR_CODE
+//----- get screen column number of string ---------------------
+int get_view_col_from_bytes(char *st, char bytes, int max_size)
+{
+	char *buf_end = st + max_size;
+	int tmp_bytes = 0, tmp_total_bytes = 0, view_col = 0;
+	while (tmp_total_bytes < bytes) {
+		Utf8_to_Utf16(st, &tmp_bytes);
+		tmp_total_bytes += tmp_bytes;
+		view_col += tmp_bytes > 1 ? 2 : 1;
+		st += tmp_bytes;
+		if (st >= buf_end)
+			break;
+	}
+	return view_col;
+}
+//----- get string bytes of screen column ----------------------
+int get_bytes_from_view_col(char *st, int view_col, int max_size)
+{
+	char *buf_end = st + max_size;
+	int tmp_view_col = 0, bytes = 0, tmp_bytes;
+	while (tmp_view_col < view_col) {
+		Utf8_to_Utf16(st, &tmp_bytes);
+		bytes += tmp_bytes;
+		tmp_view_col += tmp_bytes > 1 ? 2 : 1;
+		st += tmp_bytes;
+		if (st >= buf_end)
+			break;
+	}
+	return bytes;
+}
+#endif
+
 //----- Format a text[] line into a buffer ---------------------
+#ifndef ENABLE_BASIC_MULTI_CHAR_CODE
 static char* format_line(char *src /*, int li*/)
+#else
+static char* format_line(char *src , int *bytes, int *view_co)
+#endif
 {
 	unsigned char c;
@@ -3368,8 +3440,16 @@
 	int ofs = offset;
 	char *dest = scr_out_buf; // [MAX_SCR_COLS + MAX_TABSTOP * 2]
+#ifdef ENABLE_BASIC_MULTI_CHAR_CODE
+	int tmp_bytes, tmp_columns_count, total_bytes = 0, view_columns = 0;
+	memset(scr_out_buf, 0x00, sizeof(scr_out_buf));
+#endif
 
 	c = '~'; // char in col 0 in non-existent lines is '~'
 	co = 0;
+#ifndef ENABLE_BASIC_MULTI_CHAR_CODE
 	while (co < columns + tabstop) {
+#else
+	while (view_columns < columns + ofs/* + tabstop*/) {
+#endif
 		// have we gone past the end?
 		if (src < end) {
@@ -3386,4 +3466,8 @@
 					while ((co % tabstop) != (tabstop - 1)) {
 						dest[co++] = c;
+#ifdef ENABLE_BASIC_MULTI_CHAR_CODE
+						total_bytes++;
+						view_columns++;
+#endif
 					}
 				} else {
@@ -3397,4 +3481,22 @@
 		}
 		dest[co++] = c;
+#ifdef ENABLE_BASIC_MULTI_CHAR_CODE
+		total_bytes++;
+		view_columns++;
+		if (IsMultiByteChar(c, &tmp_bytes)) {
+			if (view_columns + 1 > columns + ofs) {
+				dest[--co] = ' ';
+			}
+			else {
+				view_columns++;
+				int i;
+				for (i = 0; i < tmp_bytes - 1; i++) {
+					dest[co++] = *src++;
+					total_bytes++;
+				}
+			}
+		}
+#endif
+#ifndef ENABLE_BASIC_MULTI_CHAR_CODE
 		// discard scrolled-off-to-the-left portion,
 		// in tabstop-sized pieces
@@ -3404,7 +3506,9 @@
 			ofs -= tabstop;
 		}
+#endif
 		if (src >= end)
 			break;
 	}
+#ifndef ENABLE_BASIC_MULTI_CHAR_CODE
 	// check "short line, gigantic offset" case
 	if (co < ofs)
@@ -3416,4 +3520,26 @@
 	if (co < columns)
 		memset(&dest[co], ' ', columns - co);
+#else
+	// check "short line, gigantic offset" case
+	if (view_columns < ofs)
+		ofs = view_columns;
+	// discard last scrolled off part
+	view_columns -= ofs;
+	tmp_columns_count = 0;
+	while (tmp_columns_count < ofs) {
+		IsMultiByteChar(*dest, &tmp_bytes);
+		dest += tmp_bytes;
+		total_bytes -= tmp_bytes;
+		tmp_columns_count += tmp_bytes > 1 ? 2 : 1;
+	}
+	// fill the rest with spaces
+	if (view_columns < columns) {
+		int ofs_bytes = get_bytes_from_view_col(scr_out_buf, ofs, co);
+		memset(&dest[co - ofs_bytes], ' ', columns - view_columns);
+		total_bytes = total_bytes + (columns - view_columns);
+	}
+	*bytes = total_bytes;
+	*view_co = view_columns;
+#endif
 	return dest;
 }
@@ -3430,4 +3556,7 @@
 	int li, changed;
 	char *tp, *sp;		// pointer into text[] and screen[]
+#ifdef ENABLE_BASIC_MULTI_CHAR_CODE
+	int bytes, view_co;
+#endif
 
 	if (ENABLE_FEATURE_VI_WIN_RESIZE IF_FEATURE_VI_ASK_TERMINAL(&& !G.get_rowcol_error) ) {
@@ -3444,5 +3573,9 @@
 		char *out_buf;
 		// format current text line
+#ifndef ENABLE_BASIC_MULTI_CHAR_CODE
 		out_buf = format_line(tp /*, li*/);
+#else
+		out_buf = format_line(tp , &bytes, &view_co);
+#endif
 
 		// skip to the end of the current text[] line
@@ -3456,7 +3589,13 @@
 		changed = FALSE;	// assume no change
 		cs = 0;
+#ifndef ENABLE_BASIC_MULTI_CHAR_CODE
 		ce = columns - 1;
 		int cursor_column = 0;
 		sp = &screen[li * columns];	// start of screen line
+#else
+		ce = bytes - 1;
+		int cursor_column = 0;
+		sp = &screen[li * columns * MULTI_BYTE_MULTIPLE];	// start of screen line
+#endif
 		if (full_screen) {
 			// force re-draw of every single column from 0 - columns-1
@@ -3494,5 +3633,5 @@
 #else
 		while (ce >= cs) {
-			int code_size = bs_char_count(sp, ce);
+			int code_size = bs_char_count(out_buf, ce);
 			if (memcmp(&out_buf[ce], &sp[ce], code_size)) {
 				changed = TRUE;	// mark for redraw
@@ -3501,4 +3640,6 @@
 			ce -= code_size;
 		}
+		if (view_co < columns - 1)
+			ce = bytes;
 #endif
 		// now, cs is index of first diff, and ce is index of last diff
@@ -3511,7 +3652,18 @@
 
 		// make a sanity check of columns indexes
+#ifndef ENABLE_BASIC_MULTI_CHAR_CODE
 		if (cs < 0) { cs = 0; cursor_column = 0; }
 		if (ce > columns - 1) ce = columns - 1;
 		if (cs > ce) { cs = 0; ce = columns - 1; cursor_column = 0; }
+#else
+		if (cs < 0) { cs = 0; cursor_column = 0; }
+		if (get_view_col_from_bytes(out_buf, ce, (columns * MULTI_BYTE_MULTIPLE)) > columns - 1)
+			ce = get_bytes_from_view_col(out_buf, columns, (columns * MULTI_BYTE_MULTIPLE)) - 1;
+		if (cs > ce) {
+			cs = 0;
+			ce = get_bytes_from_view_col(out_buf, columns, (columns * MULTI_BYTE_MULTIPLE)) - 1;
+			cursor_column = 0;
+		}
+#endif
 		// is there a change between virtual screen and out_buf
 		if (changed) {
Index: EcnlProtoTool/trunk/prototool/src/main.c
===================================================================
--- EcnlProtoTool/trunk/prototool/src/main.c	(revision 321)
+++ EcnlProtoTool/trunk/prototool/src/main.c	(revision 331)
@@ -49,9 +49,8 @@
 #include <netdb.h>
 #include <unistd.h>
-#include <setjmp.h>
 #include <signal.h>
 #include <time.h>
 #include <sys/time.h>
-#include <sys/unistd.h>
+#include <unistd.h>
 #include <errno.h>
 
@@ -65,5 +64,5 @@
 #include <mruby/dump.h>
 #include <mruby/string.h>
-#include <usrcmd.h>
+#include <ntshell/usrcmd.h>
 
 #define ETHER_MAX_LEN 1518
@@ -89,4 +88,5 @@
 extern int mruby_main(int argc, char **argv);
 extern int mirb_main(int argc, char **argv);
+extern int curl_main(int argc, char **argv);
 extern int tcc_main(int argc, char **argv);
 extern int vi_main(int argc, char **argv);
@@ -101,18 +101,10 @@
 	{"mruby","mruby command", mruby_main},
 	{"mirb", "Embeddable Interactive Ruby Shell", mirb_main},
+	{"curl", "Command lines or scripts to transfer data", curl_main},
 	{"tcc", "Tiny C compiler", tcc_main},
 	{"vi", "Text editor", vi_main},
-	{"cd", "change directory", usrcmd_cd },
-	{"ls", "list files", usrcmd_ls },
-	{"cp", "copy file", usrcmd_cp },
-	{"rm", "remove file", usrcmd_rm },
-	{"mv", "move file", usrcmd_mv },
-	{"mkdir", "Make directory", usrcmd_mkdir},
-	{"hexdump", "Hex dump", usrcmd_hexdump},
 	{"onitest", "Onigumo Test", onitest_main},
 	{"tcp_echo", "TCP echo server/client", tcp_echo_main},
 	{"help", "This is a description text string for help command.", usrcmd_help},
-	{"info", "This is a description text string for info command.", usrcmd_info},
-	{"exit", "Exit Natural Tyny Shell", usrcmd_exit},
 };
 cmd_table_info_t cmd_table_info = { &cmdlist, sizeof(cmdlist) / sizeof(cmdlist[0]) };
@@ -521,43 +513,14 @@
 }
 
-// Provide implementation of _sbrk (low-level dynamic memory allocation
-// routine) for GCC_ARM which compares new heap pointer with MSP instead of
-// SP.  This make it compatible with RTX RTOS thread stacks.
-
-// Linker defined symbol used by _sbrk to indicate where heap should start.
-int _end;
-uint32_t  _stack;
-
-// Turn off the errno macro and use actual global variable instead.
-#undef errno
-int errno;
-
-static unsigned char* heap = (unsigned char*)&_end;
-
-// Dynamic memory allocation related syscall.
-caddr_t _sbrk(int incr) {
-	unsigned char*        prev_heap = heap;
-	unsigned char*        new_heap = heap + incr;
-
-	if (new_heap >= (unsigned char*)&_stack) {     /* _stack is end of heap section */
-		errno = ENOMEM;
-		return (caddr_t)-1;
-	}
-
-	heap = new_heap;
-	return (caddr_t) prev_heap;
-}
-
-char *optarg;
+void _start_c(long *p);
 int _data, _mdata, _edata;
 int _bss, _ebss;
 
-int _PowerON_Reset(int argc, char **argv)
+void _PowerON_Reset(long *args)
 {
 	memcpy(&_data, &_mdata, (size_t)&_edata - (size_t)&_data);
 	memset(&_bss, 0, (size_t)&_ebss - (size_t)&_bss);
 
-	optarg = *argv;
-	return main(argc, argv);
+	_start_c(args);
 }
 
Index: EcnlProtoTool/trunk/prototool/src/onitest.c
===================================================================
--- EcnlProtoTool/trunk/prototool/src/onitest.c	(revision 321)
+++ EcnlProtoTool/trunk/prototool/src/onitest.c	(revision 331)
@@ -9,7 +9,7 @@
 
 #ifdef POSIX_TEST
-#include "onigposix.h"
+#include "onigmoposix.h"
 #else
-#include "oniguruma.h"
+#include "onigmo.h"
 #endif
 
@@ -197,5 +197,5 @@
 	x2("\\x1f", "\x1f", 0, 1);
 	x2("a(?#....\\\\JJJJ)b", "ab", 0, 2);
-	x2("(?x)  G (o O(?-x)oO) g ", "GoOoOgLe", 0, 7);
+	x2("(?x)  G (o O(?-x)oO) g L", "GoOoOgLe", 0, 7);
 	x2(".", "a", 0, 1);
 	n(".", "");
Index: EcnlProtoTool/trunk/prototool/src/shellif.c
===================================================================
--- EcnlProtoTool/trunk/prototool/src/shellif.c	(revision 321)
+++ 	(revision )
@@ -1,748 +1,0 @@
-/*
- *  TOPPERS ECHONET Lite Communication Middleware
- * 
- *  Copyright (C) 2017 Cores Co., Ltd. Japan
- * 
- *  ãLì ÒÍCÈºÌ(1)`(4)Ìðð½·êÉÀèC{\tgEF
- *  Ai{\tgEFAðüÏµ½àÌðÜÞDÈº¯¶jðgpE¡»Eü
- *  ÏEÄzziÈºCpÆÄÔj·é±Æð³Åø·éD
- *  (1) {\tgEFAð\[XR[hÌ`Åp·éêÉÍCãLÌì
- *       \¦C±Ìpð¨æÑºLÌ³ÛØKèªC»ÌÜÜÌ`Å\[
- *      XR[hÉÜÜêÄ¢é±ÆD
- *  (2) {\tgEFAðCCu`®ÈÇC¼Ì\tgEFAJ­Ég
- *      pÅ«é`ÅÄzz·éêÉÍCÄzzÉº¤hL
-gip
- *      Ò}j
-AÈÇjÉCãLÌì \¦C±Ìpð¨æÑºL
- *      Ì³ÛØKèðfÚ·é±ÆD
- *  (3) {\tgEFAðC@íÉgÝÞÈÇC¼Ì\tgEFAJ­Ég
- *      pÅ«È¢`ÅÄzz·éêÉÍCÌ¢¸ê©Ìðð½·±
- *      ÆD
- *    (a) ÄzzÉº¤hL
-gipÒ}j
-AÈÇjÉCãLÌ
- *        ì \¦C±Ìpð¨æÑºLÌ³ÛØKèðfÚ·é±ÆD
- *    (b) ÄzzÌ`ÔðCÊÉèßéû@ÉæÁÄCTOPPERSvWFNgÉ
- *        ñ·é±ÆD
- *  (4) {\tgEFAÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶é¢©Èé¹
- *      Q©çàCãLì Ò¨æÑTOPPERSvWFNgðÆÓ·é±ÆD
- *      Ü½C{\tgEFAÌ[UÜ½ÍGh[U©çÌ¢©Èé
- *      RÉîÃ­¿©çàCãLì Ò¨æÑTOPPERSvWFNgð
- *      ÆÓ·é±ÆD
- * 
- *  {\tgEFAÍC³ÛØÅñ³êÄ¢éàÌÅ éDãLì Ò¨
- *  æÑTOPPERSvWFNgÍC{\tgEFAÉÖµÄCÁèÌgpÚI
- *  ÉÎ·éK«àÜßÄC¢©ÈéÛØàsíÈ¢DÜ½C{\tgEF
- *  AÌpÉæè¼ÚIÜ½ÍÔÚIÉ¶¶½¢©Èé¹QÉÖµÄàC»
- *  ÌÓCðíÈ¢D
- * 
- *  @(#) $Id$
- */
-#include <setjmp.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/select.h>
-#include <poll.h>
-#include <stdarg.h>
-#include "shellif.h"
-#include "analogin_api.h"
-#include "gpio_api.h"
-#include "i2c_api.h"
-#include "pwmout_api.h"
-#include "rtc_api.h"
-#include "serial_api.h"
-#include "us_ticker_api.h"
-#include "wait_api.h"
-#include "arduino.h"
-#include "usrcmd.h"
-#include <sys/mman.h>
-#include <signal.h>
-
-typedef struct __dirstream DIR;
-
-typedef void (*analogin_init_t)(analogin_t *obj, PinName pin);
-typedef uint16_t (*analogin_read_u16_t)(analogin_t *obj);
-typedef void (*gpio_init_t)(gpio_t *obj, PinName pin);
-typedef void (*gpio_dir_t)(gpio_t *obj, PinDirection direction);
-typedef int (*i2c_start_t)(i2c_t *obj);
-typedef int (*i2c_stop_t)(i2c_t *obj);
-typedef void (*i2c_init_t)(i2c_t *obj, PinName sda, PinName scl);
-typedef int (*i2c_read_t)(i2c_t *obj, int address, char *data, int length, int stop);
-typedef int (*i2c_write_t)(i2c_t *obj, int address, const char *data, int length, int stop);
-typedef int (*i2c_byte_read_t)(i2c_t *obj, int last);
-typedef int (*i2c_byte_write_t)(i2c_t *obj, int data);
-typedef void (*pwmout_free_t)(pwmout_t* obj);
-typedef void (*pwmout_init_t)(pwmout_t* obj, PinName pin);
-typedef void (*pwmout_pulsewidth_us_t)(pwmout_t* obj, int us);
-typedef void (*rtc_init_t)(void);
-typedef void (*rtc_free_t)(void);
-typedef int (*rtc_isenabled_t)(void);
-typedef time_t (*rtc_read_t)(void);
-typedef void (*rtc_write_t)(time_t t);
-typedef void (*serial_baud_t)(serial_t *obj, int baudrate);
-typedef void (*serial_init_t)(serial_t *obj, PinName tx, PinName rx);
-typedef int (*serial_readable_t)(serial_t *obj);
-typedef int (*serial_getc_t)(serial_t *obj);
-typedef void (*serial_putc_t)(serial_t *obj, int c);
-typedef uint32_t (*us_ticker_read_t)(void);
-typedef void (*wait_ms_t)(int ms);
-typedef bool (*SD_begin_t)();
-typedef int (*usrcmd_cd_t)(int argc, char **argv);
-typedef int (*usrcmd_ls_t)(int argc, char **argv);
-typedef int (*usrcmd_cp_t)(int argc, char **argv);
-typedef int (*usrcmd_rm_t)(int argc, char **argv);
-typedef int (*usrcmd_mv_t)(int argc, char **argv);
-typedef int (*usrcmd_mkdir_t)(int argc, char **argv);
-typedef int (*usrcmd_hexdump_t)(int argc, char **argv);
-typedef int (*usrcmd_info_t)(int argc, char **argv);
-typedef int (*usrcmd_exit_t)(int argc, char **argv);
-typedef void(*shell_abort_t)();
-typedef void(*shell_exit_t)(int exitcd);
-typedef int (*shell_kill_t)(int pid, int sig);
-typedef int (*shell_gettimeofday_t)(struct timeval * tp, void * tzvp);
-typedef void (*vsyslog_t)(int priority, const char *format, va_list ap);
-typedef int (*shell_open_t)(const char * path, int flags);
-typedef int (*shell_close_t)(int fd);
-typedef int (*shell_read_t)(int fd, char *data, int len);
-typedef int (*shell_write_t)(int fd, char *data, int len);
-typedef int (*shell_lseek_t)(int fd, int ptr, int dir);
-typedef int (*shell_fstat_t)(int fd, struct stat * st);
-typedef int (*shell_stat_t)(const char *fname, struct stat *st);
-typedef int (*shell_link_t)(void);
-typedef int (*shell_unlink_t)(const char *path);
-typedef int (*shell_isatty_t)(int fd);
-typedef int (*fsync_t)(int fd);
-typedef int (*ftruncate_t)(int fd, off_t length);
-typedef int (*ioctl_t)(int fd, int request, va_list ap);
-typedef int (*tcgetattr_t)(int fd, struct termios *termios_p);
-typedef int (*tcsetattr_t)(int fd, int optional_actions, const struct termios *termios_p);
-typedef int (*shell_rename_t)(const char *oldpath, const char *newpath);
-typedef int (*rmdir_t)(const char *path);
-typedef int (*mkdir_t)(const char *path, mode_t mode);
-typedef int (*chmod_t)(const char *path, mode_t mode);
-typedef char *(*getcwd_t)(char *buf, size_t size);
-typedef int (*chdir_t)(const char *path);
-typedef int (*chroot_t)(const char *path);
-typedef int (*closedir_t)(DIR *dir);
-typedef DIR *(*opendir_t)(const char *path);
-typedef struct dirent *(*readdir_t)(DIR *dir);
-typedef void (*rewinddir_t)(DIR *dir);
-typedef void (*seekdir_t)(DIR *dir, long pos);
-typedef long (*telldir_t)(DIR *dir);
-typedef int (*shell_getpid_t)();
-typedef int (*socket_t)(int family, int type, int protocol);
-typedef int (*bind_t)(int fd, const struct sockaddr *addr, socklen_t len);
-typedef int (*listen_t)(int fd, int backlog);
-typedef int (*connect_t)(int fd, const struct sockaddr *addr, socklen_t len);
-typedef int (*accept_t)(int fd, struct sockaddr *addr, socklen_t *len);
-typedef ssize_t (*send_t)(int fd, const void *buf, size_t len, int flags);
-typedef ssize_t (*sendto_t)(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t alen);
-typedef ssize_t (*recv_t)(int fd, void *buf, size_t len, int flags);
-typedef ssize_t (*recvfrom_t)(int fd, void *buf, size_t len, int flags, struct sockaddr *addr, socklen_t *alen);
-typedef int (*shutdown_t)(int fd, int how);
-typedef int (*getsockopt_t)(int fd, int level, int optname, void *optval, socklen_t *optlen);
-typedef int (*setsockopt_t)(int fd, int level, int optname, const void *optval, socklen_t optlen);
-typedef int (*select_t)(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv);
-typedef int (*poll_t)(struct pollfd *fds, nfds_t nfds, int timeout);
-typedef int (*gethostname_t)(char *name, size_t len);
-typedef int (*getnameinfo_t)(const struct sockaddr *sa, socklen_t sl, char *node, socklen_t nodelen, char *serv, socklen_t servlen, int flags);
-typedef int (*getpeername_t)(int fd, struct sockaddr *addr, socklen_t *len);
-typedef int (*getsockname_t)(int fd, struct sockaddr *addr, socklen_t *len);
-typedef int (*socketpair_t)(int family, int type, int protocol, int fd[2]);
-
-void analogin_init(analogin_t *obj, PinName pin)
-{
-	__imp_analogin_init(obj, pin);
-}
-
-uint16_t analogin_read_u16(analogin_t *obj)
-{
-	return __imp_analogin_read_u16(obj);
-}
-
-void gpio_init(gpio_t *obj, PinName pin)
-{
-	__imp_gpio_init(obj, pin);
-}
-
-void gpio_dir(gpio_t *obj, PinDirection direction)
-{
-	__imp_gpio_dir(obj, direction);
-}
-
-int i2c_start(i2c_t *obj)
-{
-	return __imp_i2c_start(obj);
-}
-
-int i2c_stop(i2c_t *obj)
-{
-	return __imp_i2c_stop(obj);
-}
-
-void i2c_init(i2c_t *obj, PinName sda, PinName scl)
-{
-	__imp_i2c_init(obj, sda, scl);
-}
-
-int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
-{
-	return __imp_i2c_read(obj, address, data, length, stop);
-}
-
-int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
-{
-	return __imp_i2c_write(obj, address, data, length, stop);
-}
-
-int i2c_byte_read(i2c_t *obj, int last)
-{
-	return __imp_i2c_byte_read(obj, last);
-}
-
-int i2c_byte_write(i2c_t *obj, int data)
-{
-	return __imp_i2c_byte_write(obj, data);
-}
-
-void pwmout_free(pwmout_t* obj)
-{
-	__imp_pwmout_free(obj);
-}
-
-void pwmout_init(pwmout_t* obj, PinName pin)
-{
-	__imp_pwmout_init(obj, pin);
-}
-
-void pwmout_pulsewidth_us(pwmout_t* obj, int us)
-{
-	__imp_pwmout_pulsewidth_us(obj, us);
-}
-
-void rtc_init(void)
-{
-	__imp_rtc_init();
-}
-
-void rtc_free(void)
-{
-	__imp_rtc_free();
-}
-
-int rtc_isenabled(void)
-{
-	return __imp_rtc_isenabled();
-}
-
-time_t rtc_read(void)
-{
-	return __imp_rtc_read();
-}
-
-void rtc_write(time_t t)
-{
-	__imp_rtc_write(t);
-}
-
-void serial_baud(serial_t *obj, int baudrate)
-{
-	__imp_serial_baud(obj, baudrate);
-}
-
-void serial_init(serial_t *obj, PinName tx, PinName rx)
-{
-	__imp_serial_init(obj, tx, rx);
-}
-
-int serial_readable(serial_t *obj)
-{
-	return __imp_serial_readable(obj);
-}
-
-int serial_getc(serial_t *obj)
-{
-	return __imp_serial_getc(obj);
-}
-
-void serial_putc(serial_t *obj, int c)
-{
-	__imp_serial_putc(obj, c);
-}
-
-uint32_t us_ticker_read(void)
-{
-	return __imp_us_ticker_read();
-}
-
-void wait_ms(int ms)
-{
-	__imp_wait_ms(ms);
-}
-
-bool SD_begin()
-{
-	return __imp_SD_begin();
-}
-
-int usrcmd_cd(int argc, char **argv)
-{
-	return __imp_usrcmd_cd(argc, argv);
-}
-
-int usrcmd_ls(int argc, char **argv)
-{
-	return __imp_usrcmd_ls(argc, argv);
-}
-
-int usrcmd_cp(int argc, char **argv)
-{
-	return __imp_usrcmd_cp(argc, argv);
-}
-
-int usrcmd_rm(int argc, char **argv)
-{
-	return __imp_usrcmd_rm(argc, argv);
-}
-
-int usrcmd_mv(int argc, char **argv)
-{
-	return __imp_usrcmd_mv(argc, argv);
-}
-
-int usrcmd_mkdir(int argc, char **argv)
-{
-	return __imp_usrcmd_mkdir(argc, argv);
-}
-
-int usrcmd_hexdump(int argc, char **argv)
-{
-	return __imp_usrcmd_hexdump(argc, argv);
-}
-
-int usrcmd_info(int argc, char **argv)
-{
-	return __imp_usrcmd_info(argc, argv);
-}
-
-int usrcmd_exit(int argc, char **argv)
-{
-	return __imp_usrcmd_exit(argc, argv);
-}
-
-void abort()
-{
-	__imp_shell_abort();
-}
-
-void _exit(int exitcd)
-{
-	__imp_shell_exit(exitcd);
-}
-
-int _kill(int pid, int sig)
-{
-	return __imp_shell_kill(pid, sig);
-}
-
-int _gettimeofday(struct timeval * tp, void * tzvp)
-{
-	return __imp_shell_gettimeofday(tp, tzvp);
-}
-
-void vsyslog(int priority, const char *format, va_list ap)
-{
-	__imp_vsyslog(priority, format, ap);
-}
-
-void syslog(int priority, const char *format, ...)
-{
-	va_list ap;
-	va_start(ap, format);
-	vsyslog(priority, format, ap);
-	va_end(ap);
-}
-
-int _open(const char * path, int flags)
-{
-	return __imp_shell_open(path, flags);
-}
-
-int _close(int fd)
-{
-	return __imp_shell_close(fd);
-}
-
-int _read(int fd, char *data, int len)
-{
-	return __imp_shell_read(fd, data, len);
-}
-
-int _write(int fd, char *data, int len)
-{
-	return __imp_shell_write(fd, data, len);
-}
-
-int _lseek(int fd, int ptr, int dir)
-{
-	return __imp_shell_lseek(fd, ptr, dir);
-}
-
-int _fstat(int fd, struct stat * st)
-{
-	return __imp_shell_fstat(fd, st);
-}
-
-int _stat(const char *fname, struct stat *st)
-{
-	return __imp_shell_stat(fname, st);
-}
-
-int _link(void)
-{
-	return __imp_shell_link();
-}
-
-int _unlink(const char *path)
-{
-	return __imp_shell_unlink(path);
-}
-
-int _isatty(int fd)
-{
-	return __imp_shell_isatty(fd);
-}
-
-int fsync(int fd)
-{
-	return __imp_fsync(fd);
-}
-
-int ftruncate(int fd, off_t length)
-{
-	return __imp_ftruncate(fd, length);
-}
-
-int ioctl(int fd, int request, ...)
-{
-	int result;
-	va_list ap;
-	va_start(ap, request);
-	result = __imp_ioctl(fd, request, ap);
-	va_end(ap);
-	return result;
-}
-
-int tcgetattr(int fd, struct termios *termios_p)
-{
-	return __imp_tcgetattr(fd, termios_p);
-}
-
-int tcsetattr(int fd, int optional_actions, const struct termios *termios_p)
-{
-	return __imp_tcsetattr(fd, optional_actions, termios_p);
-}
-
-int _rename(const char *oldpath, const char *newpath)
-{
-	return __imp_shell_rename(oldpath, newpath);
-}
-
-int rmdir(const char *path)
-{
-	return __imp_rmdir(path);
-}
-
-int mkdir(const char *path, mode_t mode)
-{
-	return __imp_mkdir(path, mode);
-}
-
-int chmod(const char *path, mode_t mode)
-{
-	return __imp_chmod(path, mode);
-}
-
-char *getcwd(char *buf, size_t size)
-{
-	return __imp_getcwd(buf, size);
-}
-
-int chdir(const char *path)
-{
-	return __imp_chdir(path);
-}
-
-int chroot(const char *path)
-{
-	return __imp_chroot(path);
-}
-
-int closedir(DIR *dir)
-{
-	return __imp_closedir(dir);
-}
-
-DIR *opendir(const char *path)
-{
-	return __imp_opendir(path);
-}
-
-struct dirent *readdir(DIR *dir)
-{
-	return __imp_readdir(dir);
-}
-
-void rewinddir(DIR *dir)
-{
-	__imp_rewinddir(dir);
-}
-
-void seekdir(DIR *dir, long pos)
-{
-	__imp_seekdir(dir, pos);
-}
-
-long telldir(DIR *dir)
-{
-	return __imp_telldir(dir);
-}
-
-int _getpid()
-{
-	return __imp_shell_getpid();
-}
-
-int socket(int family, int type, int protocol)
-{
-	return __imp_socket(family, type, protocol);
-}
-
-int bind(int fd, const struct sockaddr *addr, socklen_t len)
-{
-	return __imp_bind(fd, addr, len);
-}
-
-int listen(int fd, int backlog)
-{
-	return __imp_listen(fd, backlog);
-}
-
-int connect(int fd, const struct sockaddr *addr, socklen_t len)
-{
-	return __imp_connect(fd, addr, len);
-}
-
-int accept(int fd, struct sockaddr *addr, socklen_t *len)
-{
-	return __imp_accept(fd, addr, len);
-}
-
-ssize_t send(int fd, const void *buf, size_t len, int flags)
-{
-	return __imp_send(fd, buf, len, flags);
-}
-
-ssize_t sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t alen)
-{
-	return __imp_sendto(fd, buf, len, flags, addr, alen);
-}
-
-ssize_t recv(int fd, void *buf, size_t len, int flags)
-{
-	return __imp_recv(fd, buf, len, flags);
-}
-
-ssize_t recvfrom(int fd, void *buf, size_t len, int flags, struct sockaddr *addr, socklen_t *alen)
-{
-	return __imp_recvfrom(fd, buf, len, flags, addr, alen);
-}
-
-int shutdown(int fd, int how)
-{
-	return __imp_shutdown(fd, how);
-}
-
-int getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen)
-{
-	return __imp_getsockopt(fd, level, optname, optval, optlen);
-}
-
-int setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
-{
-	return __imp_setsockopt(fd, level, optname, optval, optlen);
-}
-
-int select(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv)
-{
-	return __imp_select(n, rfds, wfds, efds, tv);
-}
-
-int poll(struct pollfd *fds, nfds_t nfds, int timeout)
-{
-	return __imp_poll(fds, nfds, timeout);
-}
-
-unsigned if_nametoindex(const char *name)
-{
-	return 1;
-}
-
-int gethostname(char *name, size_t len)
-{
-	return __imp_gethostname(name, len);
-}
-
-int getnameinfo(const struct sockaddr *sa, socklen_t sl,
-	char *node, socklen_t nodelen,
-	char *serv, socklen_t servlen,
-	int flags)
-{
-	return __imp_getnameinfo(sa, sl, node, nodelen, serv, servlen, flags);
-}
-
-int getpeername(int fd, struct sockaddr *addr, socklen_t *len)
-{
-	return __imp_getpeername(fd, addr, len);
-}
-
-int getsockname(int fd, struct sockaddr *addr, socklen_t *len)
-{
-	return __imp_getsockname(fd, addr, len);
-}
-
-int socketpair(int family, int type, int protocol, int fd[2])
-{
-	return __imp_socketpair(family, type, protocol, fd);
-}
-
-char *basename(char *s)
-{
-	size_t i, j;
-	if (!s || !*s) return ".";
-	i = strlen(s) - 1;
-	for (j = 0; j <= i; j++) if (s[j] == ':') { s = &s[j + 1]; i -= j; break; }
-	for (; i&&s[i] == '/'; i--) s[i] = 0;
-	for (; i&&s[i - 1] != '/'; i--);
-	return s + i;
-}
-
-char *dirname(char *_s)
-{
-	char *s = _s;
-	size_t i, j;
-	if (!s || !*s) return ".";
-	i = strlen(s) - 1;
-	for (j = 0; j <= i; j++) if (s[j] == ':') { s = &s[j + 1]; i -= j; break; }
-	for (; s[i] == '/'; i--) if (!i) return (s == _s) ? "/" : _s;
-	for (; s[i] != '/'; i--) if (!i) return (s == _s) ? "." : _s;
-	for (; s[i] == '/'; i--) if (!i) if (s == _s) return "/"; else break;
-	s[i + 1] = 0;
-	return _s;
-}
-
-char *realpath(const char *filename, char *resolved)
-{
-	char *path = getcwd(resolved, 256);
-
-	if (path != NULL)
-		strcat(path, filename);
-
-	return path;
-}
-
-uint32_t htonl(uint32_t n)
-{
-	return (n >> 24) | ((n >> 8) & 0xFF00) | ((n << 8) & 0xFF0000) | (n << 24);
-}
-
-uint32_t ntohl(uint32_t n)
-{
-	return (n >> 24) | ((n >> 8) & 0xFF00) | ((n << 8) & 0xFF0000) | (n << 24);
-}
-
-uint16_t htons(uint16_t n)
-{
-	return ((n >> 8) & 0xFF) | ((n << 8) & 0xFF00);
-}
-
-uint16_t ntohs(uint16_t n)
-{
-	return ((n >> 8) & 0xFF) | ((n << 8) & 0xFF00);
-}
-
-int mprotect(void *addr, size_t len, int prot)
-{
-	return 0;
-}
-
-int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
-{
-	return 0;
-}
-
-unsigned int Utf8_to_Utf16(const char *src, int *code_size)
-{
-	int i;
-	unsigned int uc = 0;
-	unsigned char len = 0;
-
-	len = 0;
-	if ((src[0] & 0x80) == 0) { uc = src[0] & 0x7F; len = 0; }
-	else if ((src[0] & 0xE0) == 0xC0) { uc = src[0] & 0x1F; len = 1; }
-	else if ((src[0] & 0xF0) == 0xE0) { uc = src[0] & 0x0F; len = 2; }
-	else if ((src[0] & 0xF8) == 0xF0) { uc = src[0] & 0x07; len = 3; }
-	else if ((src[0] & 0xFC) == 0xF8) { uc = src[0] & 0x03; len = 4; }
-	else if ((src[0] & 0xFE) == 0xFC) { uc = src[0] & 0x01; len = 5; }
-
-	i = 1;
-	while ((i <= len) && ((src[i] & 0xC0) == 0x80)) {
-		uc = (uc << 6) | (src[i] & 0x3F);
-		i++;
-	}
-
-	//Áï¶Ýè
-	*code_size = i;
-
-	//»óA2oCgÀè
-	return uc;
-}
-
-int bs_char_count(char *str, int pos)
-{
-	int num = 1, local_pos = pos;
-	char *c;
-
-	while (1) {
-		c = str + local_pos;
-
-		if ((*c & 0x80) != 0x80)
-			return num;
-
-		if (((*c & 0xE0) == 0xC0) && (num == 2)) {
-			return num;
-		}
-		else if (((*c & 0xF0) == 0xE0) && (num == 3)) {
-			return num;
-		}
-		else if (((*c & 0xF8) == 0xF0) && (num == 4)) {
-			return num;
-		}
-		else if (((*c & 0xFC) == 0xF8) && (num == 5)) {
-			return num;
-		}
-		else if (((*c & 0xFE) == 0xFC) && (num == 6)) {
-			return num;
-		}
-		else {
-			if (local_pos > 0) {
-				local_pos--;
-				num++;
-			}
-			else
-				return 0;
-		}
-	}
-
-	return 0;
-}
Index: EcnlProtoTool/trunk/prototool/src/xprintf.c
===================================================================
--- EcnlProtoTool/trunk/prototool/src/xprintf.c	(revision 321)
+++ 	(revision )
@@ -1,385 +1,0 @@
-/***************************************************************************
- *                                  _   _ ____  _
- *  Project                     ___| | | |  _ \| |
- *                             / __| | | | |_) | |
- *                            | (__| |_| |  _ <| |___
- *                             \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1999 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at https://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- *
- * Purpose:
- *  A merge of Bjorn Reese's format() function and Daniel's dsprintf()
- *  1.0. A full blooded printf() clone with full support for <num>$
- *  everywhere (parameters, widths and precisions) including variabled
- *  sized parameters (like doubles, long longs, long doubles and even
- *  void * in 64-bit architectures).
- *
- * Current restrictions:
- * - Max 128 parameters
- * - No 'long double' support.
- *
- * If you ever want truly portable and good *printf() clones, the project that
- * took on from here is named 'Trio' and you find more details on the trio web
- * page at https://daniel.haxx.se/trio/
- */
-
-/*------------------------------------------------------------------------/
-/  Universal string handler for user console interface
-/-------------------------------------------------------------------------/
-/
-/  Copyright (C) 2011, ChaN, all right reserved.
-/
-/ * This software is a free software and there is NO WARRANTY.
-/ * No restriction on use. You can use, modify and redistribute it for
-/   personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
-/ * Redistributions of source code must retain the above copyright notice.
-/
-/-------------------------------------------------------------------------*/
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-struct nsprintf {
-  char *buffer;
-  size_t length;
-  size_t max;
-};
-
-struct asprintf {
-  char *buffer; /* allocated buffer */
-  size_t len;   /* length of string */
-  size_t alloc; /* length of alloc */
-  int fail;     /* (!= 0) if an alloc has failed and thus
-                   the output is not the complete data */
-};
-
-#define OUTCHAR(x) \
-  do{ \
-    if(stream((unsigned char)(x), (FILE *)data) != -1) \
-      done++; \
-    else \
-     return done; /* return immediately on failure */ \
-  } while(0)
-
-
-static int dprintf_formatf(
-	void *data,
-	int(*stream)(int, FILE *),
-	const char *fmt,
-	va_list arp)
-{
-	unsigned int r, i, j, w, f;
-	unsigned long v;
-	char s[16], c, d, *p;
-
-	/* Number of characters written.  */
-	int done = 0;
-
-	for (;;) {
-		c = *fmt++;					/* Get a char */
-		if (!c) break;				/* End of format? */
-		if (c != '%') {				/* Pass through it if not a % sequense */
-			OUTCHAR(c); continue;
-		}
-		f = 0;
-		c = *fmt++;					/* Get first char of the sequense */
-		if (c == '0') {				/* Flag: '0' padded */
-			f = 1; c = *fmt++;
-		}
-		else {
-			if (c == '-') {			/* Flag: left justified */
-				f = 2; c = *fmt++;
-			}
-		}
-		for (w = 0; c >= '0' && c <= '9'; c = *fmt++)	/* Minimum width */
-			w = w * 10 + c - '0';
-		if (c == 'l' || c == 'L') {	/* Prefix: Size is long int */
-			f |= 4; c = *fmt++;
-		}
-		else if (c == 'h') {	/* Prefix: Size is short int */
-			f |= 16; c = *fmt++;
-		}
-		if (!c) break;				/* End of format? */
-		d = c;
-		if (d >= 'a') d -= 0x20;
-		switch (d) {				/* Type is... */
-		case 'S':					/* String */
-			p = va_arg(arp, char*);
-			for (j = 0; p[j]; j++);
-			while (!(f & 2) && j++ < w) OUTCHAR(' ');
-			for (; *p; p++)
-				OUTCHAR(*p);
-			while (j++ < w) OUTCHAR(' ');
-			continue;
-		case 'C':					/* Character */
-			OUTCHAR((char)va_arg(arp, int)); continue;
-		case 'B':					/* Binary */
-			r = 2; break;
-		case 'O':					/* Octal */
-			r = 8; break;
-		case 'D':					/* Signed decimal */
-		case 'U':					/* Unsigned decimal */
-			r = 10; break;
-		case 'X':					/* Hexdecimal */
-			r = 16; break;
-		default:					/* Unknown type (passthrough) */
-			OUTCHAR(c); continue;
-		}
-
-		/* Get an argument and put it in numeral */
-		v = (f & 4) ? va_arg(arp, long)
-			: ((f & 16) ? ((d == 'D') ? (long)va_arg(arp, short) : (long)va_arg(arp, unsigned short))
-				: ((d == 'D') ? (long)va_arg(arp, int) : (long)va_arg(arp, unsigned int)));
-		if (d == 'D' && (v & 0x80000000)) {
-			v = 0 - v;
-			f |= 8;
-		}
-		i = 0;
-		do {
-			d = (char)(v % r); v /= r;
-			if (d > 9) d += (c == 'x') ? 0x27 : 0x07;
-			s[i++] = d + '0';
-		} while (v && i < sizeof(s));
-		if (f & 8) s[i++] = '-';
-		j = i; d = (f & 1) ? '0' : ' ';
-		while (!(f & 2) && j++ < w) OUTCHAR(d);
-		do OUTCHAR(s[--i]); while (i);
-		while (j++ < w) OUTCHAR(' ');
-	}
-	return done;
-}
-/* fputc() look-alike */
-static int addbyter(int output, FILE *data)
-{
-  struct nsprintf *infop=(struct nsprintf *)data;
-  unsigned char outc = (unsigned char)output;
-
-  if(infop->length < infop->max) {
-    /* only do this if we haven't reached max length yet */
-    infop->buffer[0] = outc; /* store */
-    infop->buffer++; /* increase pointer */
-    infop->length++; /* we are now one byte larger */
-    return outc;     /* fputc() returns like this on success */
-  }
-  return -1;
-}
-
-int vsnprintf(char *buffer, size_t maxlength, const char *format,
-                    va_list ap_save)
-{
-  int retcode;
-  struct nsprintf info;
-
-  info.buffer = buffer;
-  info.length = 0;
-  info.max = maxlength;
-
-  retcode = dprintf_formatf(&info, addbyter, format, ap_save);
-  if(info.max) {
-    /* we terminate this with a zero byte */
-    if(info.max == info.length)
-      /* we're at maximum, scrap the last letter */
-      info.buffer[-1] = 0;
-    else
-      info.buffer[0] = 0;
-  }
-  return retcode;
-}
-
-int snprintf(char *buffer, size_t maxlength, const char *format, ...)
-{
-  int retcode;
-  va_list ap_save; /* argument pointer */
-  va_start(ap_save, format);
-  retcode = vsnprintf(buffer, maxlength, format, ap_save);
-  va_end(ap_save);
-  return retcode;
-}
-
-/* fputc() look-alike */
-static int alloc_addbyter(int output, FILE *data)
-{
-  struct asprintf *infop=(struct asprintf *)data;
-  unsigned char outc = (unsigned char)output;
-
-  if(!infop->buffer) {
-    infop->buffer = malloc(32);
-    if(!infop->buffer) {
-      infop->fail = 1;
-      return -1; /* fail */
-    }
-    infop->alloc = 32;
-    infop->len =0;
-  }
-  else if(infop->len+1 >= infop->alloc) {
-    char *newptr;
-
-    newptr = realloc(infop->buffer, infop->alloc*2);
-
-    if(!newptr) {
-      infop->fail = 1;
-      return -1; /* fail */
-    }
-    infop->buffer = newptr;
-    infop->alloc *= 2;
-  }
-
-  infop->buffer[ infop->len ] = outc;
-
-  infop->len++;
-
-  return outc; /* fputc() returns like this on success */
-}
-
-char *aprintf(const char *format, ...)
-{
-  va_list ap_save; /* argument pointer */
-  int retcode;
-  struct asprintf info;
-
-  info.buffer = NULL;
-  info.len = 0;
-  info.alloc = 0;
-  info.fail = 0;
-
-  va_start(ap_save, format);
-  retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
-  va_end(ap_save);
-  if((-1 == retcode) || info.fail) {
-    if(info.alloc)
-      free(info.buffer);
-    return NULL;
-  }
-  if(info.alloc) {
-    info.buffer[info.len] = 0; /* we terminate this with a zero byte */
-    return info.buffer;
-  }
-  else
-    return strdup("");
-}
-
-char *vaprintf(const char *format, va_list ap_save)
-{
-  int retcode;
-  struct asprintf info;
-
-  info.buffer = NULL;
-  info.len = 0;
-  info.alloc = 0;
-  info.fail = 0;
-
-  retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
-  if((-1 == retcode) || info.fail) {
-    if(info.alloc)
-      free(info.buffer);
-    return NULL;
-  }
-
-  if(info.alloc) {
-    info.buffer[info.len] = 0; /* we terminate this with a zero byte */
-    return info.buffer;
-  }
-  else
-    return strdup("");
-}
-
-int vasprintf(char **dst, const char *format, va_list ap_save)
-{
-	int retcode;
-	struct asprintf info;
-
-	info.buffer = NULL;
-	info.len = 0;
-	info.alloc = 0;
-	info.fail = 0;
-
-	retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
-	if ((-1 == retcode) || info.fail) {
-		if (info.alloc)
-			free(info.buffer);
-		return -1;
-	}
-
-	if (info.alloc) {
-		info.buffer[info.len] = 0; /* we terminate this with a zero byte */
-		*dst = info.buffer;
-		return info.len;
-	}
-	else {
-		*dst = strdup("");
-		return 0;
-	}
-}
-
-static int storebuffer(int output, FILE *data)
-{
-  char **buffer = (char **)data;
-  unsigned char outc = (unsigned char)output;
-  **buffer = outc;
-  (*buffer)++;
-  return outc; /* act like fputc() ! */
-}
-
-int sprintf(char *buffer, const char *format, ...)
-{
-  va_list ap_save; /* argument pointer */
-  int retcode;
-  va_start(ap_save, format);
-  retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save);
-  va_end(ap_save);
-  *buffer=0; /* we terminate this with a zero byte */
-  return retcode;
-}
-
-int printf(const char *format, ...)
-{
-  int retcode;
-  va_list ap_save; /* argument pointer */
-  va_start(ap_save, format);
-
-  retcode = dprintf_formatf(stdout, fputc, format, ap_save);
-  va_end(ap_save);
-  return retcode;
-}
-
-int fprintf(FILE *whereto, const char *format, ...)
-{
-  int retcode;
-  va_list ap_save; /* argument pointer */
-  va_start(ap_save, format);
-  retcode = dprintf_formatf(whereto, fputc, format, ap_save);
-  va_end(ap_save);
-  return retcode;
-}
-
-int vsprintf(char *buffer, const char *format, va_list ap_save)
-{
-  int retcode;
-  retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save);
-  *buffer=0; /* we terminate this with a zero byte */
-  return retcode;
-}
-
-int vprintf(const char *format, va_list ap_save)
-{
-  return dprintf_formatf(stdout, fputc, format, ap_save);
-}
-
-int vfprintf(FILE *whereto, const char *format, va_list ap_save)
-{
-  return dprintf_formatf(whereto, fputc, format, ap_save);
-}
Index: EcnlProtoTool/trunk/tcc-0.9.27/.cproject
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/.cproject	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/.cproject	(revision 331)
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.1798168813">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.1798168813" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactExtension="a" artifactName="tcc" buildArtefactType="com.renesas.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=com.renesas.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf *.lst *.lis *.lpp *.map" description="" id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.1798168813" name="Debug" parent="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id">
+					<folderInfo id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.1798168813." name="/" resourcePath="">
+						<toolChain id="com.renesas.cdt.library.rz.debug.win32.toolchain.Id.513805226" name="KPIT GNUARM-NONE-EABI Toolchain" superClass="com.renesas.cdt.library.rz.debug.win32.toolchain.Id">
+							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.PE" id="com.renesas.cdt.rz.libraryProject.debug.win32.targetplatform.Id.1603870523" name="Target Platform" osList="win32,linux" superClass="com.renesas.cdt.rz.libraryProject.debug.win32.targetplatform.Id"/>
+							<builder buildPath="${workspace_loc:/tcc}/Debug" id="com.renesas.cdt.rz.library.project.debug.win32.builder.Id.1947549202" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.renesas.cdt.rz.library.project.debug.win32.builder.Id"/>
+							<tool id="com.renesas.cdt.rz.libraryProject.debug.win32.tool.compiler.Id.1351770923" name="Compiler" superClass="com.renesas.cdt.rz.libraryProject.debug.win32.tool.compiler.Id">
+								<option defaultValue="true" id="com.renesas.cdt.core.Compiler.option.misc2.373654238" name="æ¨æºã·ã¹ãã ã»ãã£ã¬ã¯ããªã¼ã§ãããã¼ã»ãã¡ã¤ã«ãæ¤ç´¢ããªã (-nostdinc)" superClass="com.renesas.cdt.core.Compiler.option.misc2" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.dataEndian.1091726519" name="ã¨ã³ãã£ã¢ã³" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.dataEndian" value="Little-endian" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.instructionset.1331241682" name="å½ä»¤ã»ãã" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.instructionset" value="ARM" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.interworking.404979942" name="ã¤ã³ã¿ã¼ã»ã¯ã¼ã­ã³ã°" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.interworking" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.targetfpu.1883231980" name="ã¿ã¼ã²ãã FPU (-mfpu)" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.targetfpu" value="vfp" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.floatingpointabi.1001946086" name="æµ®åå°æ°ç¹ ABI (-mfloat-abi=name)" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.floatingpointabi" value="Hard" valueType="enumerated"/>
+								<option id="com.renesas.cdt.core.Compiler.option.warnStackSize.1222102532" name="Warn if stack size exceeds the limit (-Wstack-usage) (H')" superClass="com.renesas.cdt.core.Compiler.option.warnStackSize" value="100" valueType="string"/>
+								<option id="com.renesas.cdt.core.Compiler.option.CPUSeries.657838384" name="CPU ã·ãªã¼ãº" superClass="com.renesas.cdt.core.Compiler.option.CPUSeries" value="RZ/A" valueType="string"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.architecture.401098680" name="ã¢ã¼ã­ãã¯ãã£ã¼" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.architecture" value="armv7-a" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.cpuType.1123397289" name="CPU ã¿ã¤ã" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.cpuType" value="cortex-a9" valueType="enumerated"/>
+								<option id="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal.1138208172" name="Decimal representation of '-Wstack-usage'" superClass="com.renesas.cdt.core.Compiler.option.stackSizeInDecimal" value="256" valueType="string"/>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.core.Compiler.option.includeFileDir.276254572" name="ã¤ã³ã¯ã«ã¼ãã»ãã¡ã¤ã«ã»ãã£ã¬ã¯ããªã¼" superClass="com.renesas.cdt.core.Compiler.option.includeFileDir" valueType="includePath">
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/musl-1.1.18/include}&quot;"/>
+								</option>
+								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.renesas.cdt.rz.Debug.Compiler.option.library.macroDefines.1180675084" name="ãã¯ã­å®ç¾©" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.macroDefines" valueType="definedSymbols">
+									<listOptionValue builtIn="false" value="TCC_CPU_VERSION=7"/>
+									<listOptionValue builtIn="false" value="TCC_MUSL"/>
+									<listOptionValue builtIn="false" value="TCC_TARGET_ARM"/>
+									<listOptionValue builtIn="false" value="TCC_ARM_EABI"/>
+									<listOptionValue builtIn="false" value="TCC_ARM_VFP"/>
+									<listOptionValue builtIn="false" value="TCC_ARM_HARDFLOAT"/>
+									<listOptionValue builtIn="false" value="ONE_SOURCE=0"/>
+									<listOptionValue builtIn="false" value="CONFIG_TCC_STATIC"/>
+								</option>
+								<inputType id="%Base.Compiler.C.InputType.Id.1716911779" name="C å
+¥å" superClass="%Base.Compiler.C.InputType.Id"/>
+								<inputType id="Base.Compiler.CPP.InputType.Id.626465714" name="C++ å
+¥å" superClass="Base.Compiler.CPP.InputType.Id"/>
+							</tool>
+							<tool id="com.renesas.cdt.library.rz.Debug.win32.tool.assembler.Id.1658961068" name="Assembler" superClass="com.renesas.cdt.library.rz.Debug.win32.tool.assembler.Id">
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.dataEndian.992648775" name="ã¨ã³ãã£ã¢ã³" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.dataEndian" value="Little-endian" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.instructionset.1760881271" name="å½ä»¤ã»ãã" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.instructionset" value="ARM" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.targetfpu.1986508057" name="ã¿ã¼ã²ãã FPU (-mfpu)" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.targetfpu" value="vfp" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.floatingpointabi.659487149" name="æµ®åå°æ°ç¹ ABI (-mfloat-abi=name)" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.floatingpointabi" value="Hard" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.architecture.1028163560" name="ã¢ã¼ã­ãã¯ãã£ã¼" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.architecture" value="armv7-a" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.cpuType.1481182175" name="CPU ã¿ã¤ã" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.cpuType" value="cortex-a9" valueType="enumerated"/>
+								<inputType id="%Base.Assembler.inputType.Id.199268857" name="ã¢ã»ã³ãã©ã¼å
+¥åã¿ã¤ã" superClass="%Base.Assembler.inputType.Id"/>
+							</tool>
+							<tool id="com.renesas.cdt.library.rz.debug.win32.tool.archive.Id.340844013" name="Archive Generator" superClass="com.renesas.cdt.library.rz.debug.win32.tool.archive.Id"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry excluding="lib/armeabi.c|lib/alloca-arm.S|tcctools.c|lib/va_list.c|lib/libtcc1.c|lib/lib-arm64.c|lib/bcheck.c|lib/alloca86-bt.S|lib/alloca86.S|lib/alloca86_64-bt.S|lib/alloca86_64.S|i386-link.c|conftest.c|c67-link.c|win32|x86_64-link.c|arm64-link.c|arm64-gen.c|tests|examples|tccpe.c|tcccoff.c|x86_64-gen.c|x86_64-asm.h|il-opcodes.h|il-gen.c|i386-tok.h|i386-gen.c|i386-asm.h|i386-asm.c|c67-gen.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="tcc.com.renesas.cdt.rz.library.projectType.Id.95769190" name="Static Library (Renesas)" projectType="com.renesas.cdt.rz.library.projectType.Id"/>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+	<storageModule moduleId="refreshScope" versionNumber="2">
+		<configuration configurationName="Debug">
+			<resource resourceType="PROJECT" workspacePath="/tcc-0.9.27"/>
+		</configuration>
+	</storageModule>
+</cproject>
Index: EcnlProtoTool/trunk/tcc-0.9.27/.gitignore
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/.gitignore	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/.gitignore	(revision 331)
@@ -0,0 +1,57 @@
+*~
+\#*
+.#*
+*.o
+*.a
+*.exe
+*.dll
+*.obj
+*.pdb
+*.lib
+*.exp
+*.log
+*.bz2
+*.zip
+.gdb_history
+a.out
+tcc_g
+tcc
+*-tcc
+libtcc*.def
+
+config*.h
+config*.mak
+config.texi
+conftest*
+tags
+TAGS
+tcc.1
+tcc.pod
+tcc-doc.html
+tcc-doc.info
+
+win32/doc
+win32/libtcc
+win32/lib/32
+win32/lib/64
+win32/include/float.h
+win32/include/stdarg.h
+win32/include/stdbool.h
+win32/include/stddef.h
+win32/include/varargs.h
+win32/include/tcclib.h
+
+tests/tcctest[1234]
+tests/tcctest.gcc
+tests/*.out*
+tests/*.ref
+tests/*.txt
+tests/*.gcc
+tests/*-cc*
+tests/*-tcc*
+tests/libtcc_test
+tests/asm-c-connect
+tests/asm-c-connect-sep
+tests/vla_test
+tests/hello
+tests/tests2/fred.txt
Index: EcnlProtoTool/trunk/tcc-0.9.27/.info
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/.info	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/.info	(revision 331)
@@ -0,0 +1,7 @@
+TOOL_CHAIN=KPIT GNUARM-NONE-EABI Toolchain
+VERSION=v16.01
+TC_INSTALL=C:\Program Files (x86)\KPIT\GNUARM-NONEv16.01-EABI\arm-none-eabi\arm-none-eabi\
+GCC_STRING=5.2-GNUARM-NONE_v16.01
+VERSION_IDE=
+E2STUDIO_VERSION=5.4.0.018
+ACTIVE_CONFIGURATION=Debug
Index: EcnlProtoTool/trunk/tcc-0.9.27/.project
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/.project	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/.project	(revision 331)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>tcc-0.9.27</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>com.renesas.cdt.core.genmakebuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>com.renesas.cdt.core.kpitcnature</nature>
+		<nature>com.renesas.cdt.core.kpitccnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+	</natures>
+</projectDescription>
Index: EcnlProtoTool/trunk/tcc-0.9.27/COPYING
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/COPYING	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/COPYING	(revision 331)
@@ -0,0 +1,513 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
Index: EcnlProtoTool/trunk/tcc-0.9.27/Changelog
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/Changelog	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/Changelog	(revision 331)
@@ -0,0 +1,439 @@
+Version 0.9.27:
+
+User interface:
+- -x[c|a|n] filetype option (Sergey Korshunoff)
+- -P[1], -dD, -dM preprocessor options (Sergey Korshunoff)
+- -Wl,-(no-)whole-archive linker option (Reuben Thomas)
+- -mms-bitfields option (David Mertens)
+- -include <file> option (Michael Matz)
+- -mno-sse on x86-64 disables use of SSE instructions
+- @listfile support (Vlad Vissoultchev)
+- tcc -ar/-impdef - formerly tiny_xxx tools integrated (grischka)
+- CPATH, C_INCLUDE_PATH and LIBRARY_PATH environment variables support
+  (Andrew Aladjev, Urs Janssen)
+
+Platforms:
+- new AARCH64 (arm64) target (Edmund Grimley Evans)
+- vastly improved support for ARM hard float calling convention
+   (Thomas Preud'homme, Daniel Gl旦ckner)
+- provide a runtime library for ARM (Thomas Preud'homme)
+- many x86_64 ABI fixes incl. XMM register passing and tests (James Lyon)
+- ABI tests with native compiler using libtcc (James Lyon)
+- UNICODE startup code supports wmain and wWinMain (YX Hao)
+- shared libraries for x86_64 (Michael Matz)
+- Bootstrap native Windows 32/64 compiler using Cygwin+gcc (Christian Jullien)
+
+Features:
+- VLA (variable length array) improved (James Lyon, Pip Cet)
+- import functions by ordinal in .def files on windows (YX Hao)
+- x86/x86_64 assembler much improved (Michael Matz)
+- simple dead code suppression (Edmund Grimley Evans, Michael Matz, grischka)
+- implement round/fmin/fmax etc. math on windows (Avi Halachmi)
+- #pragma once support (Sergey Korshunoff, Vlad Vissoultchev, ...)
+- switch/case code improved (Zdenek Pavlas)
+- ~15% faster by TinyAlloc fast memory allocator (Vlad Vissoultchev)
+- standard conforming (and GCC compatible) struct initialization
+   (Michael Matz)
+- bit-field layout made compatible with GCC (Michael Matz)
+- UTF8 in string literals supported (Zdenek Pavlas)
+_ _Generic(...) supported (Matthias Gatto)
+
+Licensing:
+- TinyCC partly relicensed to MIT license (See RELICENSING file).
+
+version 0.9.26:
+
+User interface:
+- -MD/-MF (automatically generate dependencies for make)
+- -pthread option (same as -D_REENTRANT -lpthread) (Henry Kroll III)
+- -m32/-m64 to re-exec cross compiler (Henry Kroll III)
+- -Wl, Mimic all GNU -option forms supported by ld (Kirill Smelkov)
+- new LIBTCCAPI tcc_set_options() (grischka)
+
+Platforms:
+- Many improvements for x86-64 target (Shinichiro Hamaji, Michael Matz, grischka)
+- x86-64 assembler (Frederic Feret)
+- Many improvements for ARM target (Daniel Gl旦ckner, Thomas Preud'homme)
+- Support WinCE PE ARM (Timo VJ Lahde)
+- Support ARM hardfloat calling convention (Thomas Preud'homme)
+- Support SELinux (Security-Enhanced Linux) (Henry Kroll III)
+- Support Debian GNU/kFreeBSD kernels (Pierre Chifflier)
+- Support GNU/Hurd kernels (Thomas Preud'homme)
+- Support OSX (tcc -run only) (Milutin Jovanovic)
+- Support multiarch configuration (Thomas Preud'homme)
+- Support out-of-tree build (Akim Demaille)
+
+Features:
+- C99 variable length arrays (Thomas Preud'homme & Joe Soroka)
+- Asm labels for variables and functions (Thomas Preud'homme)
+- STT_GNU_IFUNC (Indirect functions as externals) (Thomas Preud'homme)
+- More tests (tests2) (Milutin Jovanovic)
+
+version 0.9.25:
+
+- first support for x86-64 target (Shinichiro Hamaji)
+- support 袖Clibc
+- split tcc.c into tcc.h libtcc.c tccpp.c tccgen.c tcc.c
+- improved preprocess output with linenumbers and spaces preserved
+- tcc_relocate now copies code into user buffer
+- fix bitfields with non-int types and in unions
+- improve ARM cross-compiling (Daniel Gl旦ckner)
+- link stabstr sections from multiple objects
+- better (still limited) support for multiple TCCStates
+
+version 0.9.24:
+
+- added verbosity levels -v, -vv, -vvv
+- Accept standard input as an inputstream (Hanzac Chen)
+- Support c89 compilers other than gcc (Hanzac Chen)
+- -soname linker option (Marc Andre Tanner)
+- Just warn about unknown directives, ignore quotes in #error/#warning
+- Define __STDC_VERSION__=199901L (477)
+- Switch to newer tccpe.c (includes support for resources)
+- Handle backslashes within #include/#error/#warning
+- Import changesets (part 4) 428,457,460,467: defines for openbsd etc.
+- Use _WIN32 for a windows hosted tcc and define it for the PE target,
+  otherwise define __unix / __linux (Detlef Riekenberg)
+- Import changesets (part 3) 409,410: ARM EABI by Daniel Gl旦ckner
+- Some in-between fixes:
+  TCC -E no longer hangs with macro calls involving newlines.
+  (next_nomacro1 now advances the read-pointer with TOK_LINEFEED)
+  Global cast (int g_i = 1LL;) no longer crashes tcc.
+  (nocode_wanted is initially 1, and only 0 for gen_function)
+  On win32 now tcc.exe finds 'include' & 'lib' even if itself is in 'bin'.
+  (new function w32_tcc_lib_path removes 'bin' if detected)
+  Added quick build batch file for mingw (win32/build-tcc.bat)
+  Last added case label optimization (455) produced wrong code. Reverted.
+
+- Import more changesets from Rob Landley's fork (part 2):
+  487: Handle long long constants in gen_opic() (Rob Landley)
+  484: Handle parentheses within __attribute__((...)) (Rob Landley)
+  480: Remove a goto in decl_initializer_alloc (Rob Landley)
+  475: Fix dereferences in inline assembly output (Joshua Phillips)
+  474: Cast ptrs to ints of different sizes correctly (Joshua Phillips)
+  473: Fix size of structs with empty array member (Joshua Phillips)
+  470: No warning for && and || with mixed pointers/integers (Rob Landley)
+  469: Fix symbol visibility problems in the linker (Vincent Pit)
+  468: Allow && and || involving pointer arguments (Rob Landley)
+  455: Optimize case labels with no code in between (Zdenek Pavlas)
+  450: Implement alloca for x86 (grischka)
+  415: Parse unicode escape sequences (Axel Liljencrantz)
+  407: Add a simple va_copy() in stdarg.h (Hasso Tepper)
+  400: Allow typedef names as symbols (Dave Dodge)
+
+- Import some changesets from Rob Landley's fork (part 1):
+  462: Use LGPL with bcheck.c and il-gen.c
+  458: Fix global compound literals (in unary: case '&':) (Andrew Johnson)
+  456: Use return code from tcc_output_file in main() (Michael Somos)
+  442: Fix indirections with function pointers (***fn)() (grischka)
+  441: Fix LL left shift in libtcc1.c:__shldi3 (grischka)
+  440: Pass structures and function ptrs through ?: (grischka)
+  439: Keep rvalue in bit assignment (bit2 = bit1 = x) (grischka)
+  438: Degrade nonportable pointer assignment to warning (grischka)
+  437: Call 'saveregs()' before jumping with logical and/or/not (grischka)
+  435: Put local static variables into global memory (grischka)
+  432/434: Cast double and ptr to bool (grischka)
+  420: Zero pad x87 tenbyte long doubles (Felix Nawothnig)
+  417: Make 'sizeof' unsigned (Rob Landley)
+  397: Fix save_reg for longlongs (Daniel Gl旦ckner)
+  396: Fix "invalid relocation entry" problem on ubuntu - (Bernhard Fischer)
+
+- ignore AS_NEEDED ld command
+- mark executable sections as executable when running in memory
+- added support for win32 wchar_t (Filip Navara)
+- segment override prefix support (Filip Navara)
+- normalized slashes in paths (Filip Navara)
+- windows style fastcall (Filip Navara)
+- support for empty input register section in asm (Filip Navara)
+- anonymous union/struct support (Filip Navara)
+- fixed parsing of function parameters
+- workaround for function pointers in conditional expressions (Dave Dodge)
+- initial '-E' option support to use the C preprocessor alone
+- discard type qualifiers when comparing function parameters (Dave Dodge)
+- Bug fix: A long long value used as a test expression ignores the
+  upper 32 bits at runtime (Dave Dodge)
+- fixed multiple concatenation of PPNUM tokens (initial patch by Dave Dodge)
+- fixed multiple typedef specifiers handling
+- fixed sign extension in some type conversions (Dave Dodge)
+
+version 0.9.23:
+
+- initial PE executable format for windows version (grischka)
+- '#pragma pack' support (grischka)
+- '#include_next' support (Bernhard Fischer)
+- ignore '-pipe' option
+- added -f[no-]leading-underscore
+- preprocessor function macro parsing fix (grischka)
+
+version 0.9.22:
+
+- simple memory optimisations: kernel compilation is 30% faster
+- linker symbol definitions fixes
+- gcc 3.4 fixes
+- fixed value stack full error
+- 'packed' attribute support for variables and structure fields
+- ignore 'const' and 'volatile' in function prototypes
+- allow '_Bool' in bit fields
+
+version 0.9.21:
+
+- ARM target support (Daniel Gl旦ckner)
+- added '-funsigned-char, '-fsigned-char' and
+  '-Wimplicit-function-declaration'
+- fixed assignment of const struct in struct
+- line comment fix (reported by Bertram Felgenhauer)
+- initial TMS320C67xx target support (TK)
+- win32 configure
+- regparm() attribute
+- many built-in assembler fixes
+- added '.org', '.fill' and '.previous' assembler directives
+- '-fno-common' option
+- '-Ttext' linker option
+- section alignment fixes
+- bit fields fixes
+- do not generate code for unused inline functions
+- '-oformat' linker option. 
+- added 'binary' output format.
+
+version 0.9.20:
+
+- added '-w' option
+- added '.gnu.linkonce' ELF sections support
+- fixed libc linking when running in memory (avoid 'stat' function
+  errors).
+- extended '-run' option to be able to give several arguments to a C
+  script.
+
+version 0.9.19:
+
+- "alacarte" linking (Dave Long)
+- simpler function call
+- more strict type checks
+- added 'const' and 'volatile' support and associated warnings
+- added -Werror, -Wunsupported, -Wwrite-strings, -Wall.
+- added __builtin_types_compatible_p() and __builtin_constant_p()
+- chars support in assembler (Dave Long)
+- .string, .globl, .section, .text, .data and .bss asm directive
+  support (Dave Long)
+- man page generated from tcc-doc.texi
+- fixed macro argument substitution
+- fixed zero argument macro parsing
+- changed license to LGPL
+- added -rdynamic option support
+
+version 0.9.18:
+
+- header fix (time.h)
+- fixed inline asm without operand case
+- fixed 'default:' or 'case x:' with '}' after (incorrect C construct accepted
+  by gcc)
+- added 'A' inline asm constraint.
+
+version 0.9.17:
+
+- PLT generation fix
+- tcc doc fixes (Peter Lund)
+- struct parse fix (signaled by Pedro A. Aranda Gutierrez)
+- better _Bool lvalue support (signaled by Alex Measday)
+- function parameters must be converted to pointers (signaled by Neil Brown)
+- sanitized string and character constant parsing
+- fixed comment parse (signaled by Damian M Gryski)
+- fixed macro function bug (signaled by Philippe Ribet)
+- added configure (initial patch by Mitchell N Charity)
+- added '-run' and '-v' options (initial patch by vlindos)
+- added real date report in __DATE__ and __TIME__ macros
+
+version 0.9.16:
+
+- added assembler language support
+- added GCC inline asm() support
+- fixed multiple variable definitions : uninitialized variables are
+  created as COMMON symbols.
+- optimized macro processing
+- added GCC statement expressions support
+- added GCC local labels support
+- fixed array declaration in old style function parameters
+- support casts in static structure initializations
+- added various __xxx[__] keywords for GCC compatibility
+- ignore __extension__ GCC in an expression or in a type (still not perfect)
+- added '? :' GCC extension support
+
+version 0.9.15:
+
+- compilation fixes for glibc 2.2, gcc 2.95.3 and gcc 3.2.
+- FreeBSD compile fixes. Makefile patches still missing (Carl Drougge).
+- fixed file type guessing if '.' is in the path.
+- fixed tcc_compile_string()
+- add a dummy page in ELF files to fix RX/RW accesses (pageexec at
+  freemail dot hu).
+
+version 0.9.14:
+
+- added #warning. error message if invalid preprocessing directive.
+- added CType structure to ease typing (faster parse).
+- suppressed secondary hash tables (faster parse).
+- rewrote parser by optimizing common cases (faster parse).
+- fixed signed long long comparisons.
+- fixed 'int a(), b();' declaration case.
+- fixed structure init without '{}'.
+- correct alignment support in structures.
+- empty structures support.
+- gcc testsuite now supported.
+- output only warning if implicit integer/pointer conversions.
+- added static bitfield init.
+
+version 0.9.13:
+
+- correct preprocessing token pasting (## operator) in all cases (added
+  preprocessing number token).
+- fixed long long register spill.
+- fixed signed long long '>>'.
+- removed memory leaks.
+- better error handling : processing can continue on link errors. A
+  custom callback can be added to display error messages. Most
+  errors do not call exit() now.
+- ignore -O, -W, -m and -f options
+- added old style function declarations
+- added GCC __alignof__ support.
+- added GCC typeof support.
+- added GCC computed gotos support.
+- added stack backtrace in runtime error message. Improved runtime
+  error position display.
+
+version 0.9.12:
+
+- more fixes for || and && handling.
+- improved '? :' type handling.
+- fixed bound checking generation with structures
+- force '#endif' to be in same file as matching '#if'
+- #include file optimization with '#ifndef #endif' construct detection
+- macro handling optimization
+- added tcc_relocate() and tcc_get_symbol() in libtcc.
+
+version 0.9.11:
+
+- stdarg.h fix for double type (thanks to Philippe Ribet).
+- correct white space characters and added MSDOS newline support.
+- fixed invalid implicit function call type declaration.
+- special macros such as __LINE__ are defined if tested with defined().
+- fixed '!' operator with relocated address.
+- added symbol + offset relocation (fixes some static variable initializers)
+- '-l' option can be specified anywhere. '-c' option yields default
+  output name. added '-r' option for relocatable output.
+- fixed '\nnn' octal parsing.
+- fixed local extern variables declarations.
+
+version 0.9.10:
+
+- fixed lvalue type when saved in local stack.
+- fixed '#include' syntax when using macros.
+- fixed '#line' bug.
+- removed size limit on strings. Unified string constants handling
+  with variable declarations.
+- added correct support for '\xX' in wchar_t strings.
+- added support for bound checking in generated executables
+- fixed -I include order.
+- fixed incorrect function displayed in runtime error.
+
+version 0.9.9:
+
+- fixed preprocessor expression parsing for #if/#elif.
+- relocated debug info (.stab section).
+- relocated bounds info (.bounds section).
+- fixed cast to char of char constants ('\377' is -1 instead of 255)
+- fixed implicit cast for unary plus.
+- strings and '__func__' have now 'char[]' type instead of 'char *'
+  (fixes sizeof() return value).
+- added __start_xxx and __stop_xxx symbols in linker.
+- better DLL creation support (option -shared begins to work).
+- ELF sections and hash tables are resized dynamically.
+- executables and DLLs are stripped by default.
+
+version 0.9.8:
+
+- First version of full ELF linking support (generate objects, static
+  executable, dynamic executable, dynamic libraries). Dynamic library
+  support is not finished (need PIC support in compiler and some
+  patches in symbol exporting).
+- First version of ELF loader for object (.o) and archive (.a) files.
+- Support of simple GNU ld scripts (GROUP and FILE commands)
+- Separated runtime library and bound check code from TCC (smaller
+  compiler core).
+- fixed register reload in float compare.
+- fixed implicit char/short to int casting.
+- allow array type for address of ('&') operator.
+- fixed unused || or && result.
+- added GCC style variadic macro support.
+- optimized bound checking code for array access.
+- tcc includes are now in $(prefix)/lib/tcc/include.
+- more command line options - more consistent handling of multiple
+  input files.
+- added tcc man page (thanks to Cyril Bouthors).
+- uClibc Makefile update
+- converted documentation to texinfo format.
+- added developper's guide in documentation.
+
+version 0.9.7:
+
+- added library API for easy dynamic compilation (see libtcc.h - first
+  draft).
+- fixed long long register spill bug.
+- fixed '? :' register spill bug.
+
+version 0.9.6:
+
+- added floating point constant propagation (fixes negative floating
+  point constants bug).
+
+version 0.9.5:
+
+ - uClibc patches (submitted by Alfonso Martone).
+ - error reporting fix
+ - added CONFIG_TCC_BCHECK to get smaller code if needed.
+
+version 0.9.4:
+
+ - windows port (currently cannot use -g, -b and dll functions).
+ - faster and simpler I/O handling.
+ - '-D' option works in all cases.
+ - preprocessor fixes (#elif and empty macro args)
+ - floating point fixes
+ - first code for CIL generation (does not work yet)
+
+version 0.9.3:
+
+ - better and smaller code generator.
+ - full ISOC99 64 bit 'long long' support.
+ - full 32 bit 'float', 64 bit 'double' and 96 bit 'long double' support.
+ - added '-U' option.
+ - added assembly sections support. 
+ - even faster startup time by mmaping sections instead of mallocing them.
+ - added GNUC __attribute__ keyword support (currently supports
+    'section' and 'aligned' attributes).
+ - added ELF file output (only usable for debugging now)
+ - added debug symbol generation (STAB format).
+ - added integrated runtime error analysis ('-g' option: print clear
+   run time error messages instead of "Segmentation fault").
+ - added first version of tiny memory and bound checker ('-b' option).
+
+version 0.9.2:
+
+ - even faster parsing.
+ - various syntax parsing fixes.
+ - fixed external relocation handling for variables or functions pointers.
+ - better function pointers type handling.
+ - can compile multiple files (-i option).
+ - ANSI C bit fields are supported.
+ - beginning of float/double/long double support.
+ - beginning of long long support.
+
+version 0.9.1:
+
+ - full ISOC99 initializers handling.
+ - compound literals.
+ - structures handle in assignments and as function param or return value.
+ - wide chars and strings.
+ - macro bug fix
+
+version 0.9:
+ - initial version.
Index: EcnlProtoTool/trunk/tcc-0.9.27/CodingStyle
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/CodingStyle	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/CodingStyle	(revision 331)
@@ -0,0 +1,71 @@
+
+In general, use the same coding style as the surrounding code.
+
+However, do not make any unnecessary changes as that complicates
+the VCS (git) history and makes it harder to merge patches. So
+do not modify code just to make it conform to a coding style.
+
+    Indentation
+
+Turn on a "fill tabs with spaces" option in your editor.
+
+Remove tabs and trailing spaces from any lines that are modified.
+
+Note that some files are indented with 2 spaces (when they
+have large indentation) while most are indented with 4 spaces.
+
+    Language
+
+TCC is mostly implemented in C90. Do not use any non-C90 features
+that are not already in use.
+
+Non-C90 features currently in use, as revealed by
+./configure --extra-cflags="-std=c90 -Wpedantic":
+
+- long long (including "LL" constants)
+- inline
+- very long string constants
+- assignment between function pointer and 'void *'
+- "//" comments
+- empty macro arguments (DEF_ASMTEST in i386-tok.h)
+- unnamed struct and union fields (in struct Sym), a C11 feature
+
+    Testing
+
+A simple "make test" is sufficient for some simple changes. However,
+before committing a change consider performing some of the following
+additional tests:
+
+- Build and run "make test" on several architectures.
+
+- Build with ./configure --enable-cross.
+
+- If the generation of relocations has been changed, try compiling
+  with TCC and linking with GCC/Clang. If the linker has been
+  modified, try compiling with GCC/Clang and linking with TCC.
+
+- Test with ASan/UBSan to detect memory corruption and undefined behaviour:
+
+make clean
+./configure
+make
+make test
+cp libtcc.a libtcc.a.hide
+
+make clean
+./configure --extra-cflags="-fsanitize=address,undefined -g"
+make
+cp libtcc.a.hide libtcc.a
+make test
+
+- Test with Valgrind to detect some uses of uninitialised values:
+
+make clean
+./configure
+make
+# On Intel, because Valgrind does floating-point arithmetic differently:
+( cd tests && gcc -I.. tcctest.c && valgrind -q ./a.out > test.ref )
+make test TCC="valgrind -q --leak-check=full `pwd`/tcc -B`pwd` -I`pwd`"
+
+  (Because of how VLAs are implemented, invalid reads are expected
+  with 79_vla_continue.)
Index: EcnlProtoTool/trunk/tcc-0.9.27/Makefile
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/Makefile	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/Makefile	(revision 331)
@@ -0,0 +1,403 @@
+# --------------------------------------------------------------------------
+#
+# Tiny C Compiler Makefile
+#
+
+ifndef TOP
+ TOP = .
+ INCLUDED = no
+endif
+
+include $(TOP)/config.mak
+
+ifeq (-$(CC)-$(GCC_MAJOR)-$(findstring $(GCC_MINOR),56789)-,-gcc-4--)
+ CFLAGS += -D_FORTIFY_SOURCE=0
+endif
+
+LIBTCC = libtcc.a
+LIBTCC1 = libtcc1.a
+LINK_LIBTCC =
+LIBS =
+CFLAGS += -I$(TOP)
+CFLAGS += $(CPPFLAGS)
+VPATH = $(TOPSRC)
+
+ifdef CONFIG_WIN32
+ ifneq ($(CONFIG_static),yes)
+  LIBTCC = libtcc$(DLLSUF)
+  LIBTCCDEF = libtcc.def
+ endif
+ CFGWIN = -win
+ NATIVE_TARGET = $(ARCH)-win$(if $(findstring arm,$(ARCH)),ce,32)
+else
+ LIBS=-lm
+ ifneq ($(CONFIG_ldl),no)
+  LIBS+=-ldl
+ endif
+ # make libtcc as static or dynamic library?
+ ifeq ($(CONFIG_static),no)
+  LIBTCC=libtcc$(DLLSUF)
+  export LD_LIBRARY_PATH := $(CURDIR)/$(TOP)
+  ifneq ($(CONFIG_rpath),no)
+   LINK_LIBTCC += -Wl,-rpath,"$(libdir)"
+  endif
+ endif
+ CFGWIN =-unx
+ NATIVE_TARGET = $(ARCH)
+ ifdef CONFIG_OSX
+  NATIVE_TARGET = $(ARCH)-osx
+  LDFLAGS += -flat_namespace -undefined warning
+  export MACOSX_DEPLOYMENT_TARGET := 10.2
+ endif
+endif
+
+# run local version of tcc with local libraries and includes
+TCCFLAGS-unx = -B$(TOP) -I$(TOPSRC)/include -I$(TOPSRC) -I$(TOP)
+TCCFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include -I$(TOPSRC) -I$(TOP) -L$(TOP)
+TCCFLAGS = $(TCCFLAGS$(CFGWIN))
+TCC = $(TOP)/tcc$(EXESUF) $(TCCFLAGS)
+ifdef CONFIG_OSX
+ TCCFLAGS += -D_ANSI_SOURCE
+endif
+
+CFLAGS_P = $(CFLAGS) -pg -static -DCONFIG_TCC_STATIC -DTCC_PROFILE
+LIBS_P = $(LIBS)
+LDFLAGS_P = $(LDFLAGS)
+
+CONFIG_$(ARCH) = yes
+NATIVE_DEFINES_$(CONFIG_i386) += -DTCC_TARGET_I386
+NATIVE_DEFINES_$(CONFIG_x86_64) += -DTCC_TARGET_X86_64
+NATIVE_DEFINES_$(CONFIG_WIN32) += -DTCC_TARGET_PE
+NATIVE_DEFINES_$(CONFIG_OSX) += -DTCC_TARGET_MACHO
+NATIVE_DEFINES_$(CONFIG_uClibc) += -DTCC_UCLIBC
+NATIVE_DEFINES_$(CONFIG_musl) += -DTCC_MUSL
+NATIVE_DEFINES_$(CONFIG_libgcc) += -DCONFIG_USE_LIBGCC
+NATIVE_DEFINES_$(CONFIG_selinux) += -DHAVE_SELINUX
+NATIVE_DEFINES_$(CONFIG_arm) += -DTCC_TARGET_ARM
+NATIVE_DEFINES_$(CONFIG_arm_eabihf) += -DTCC_ARM_EABI -DTCC_ARM_HARDFLOAT
+NATIVE_DEFINES_$(CONFIG_arm_eabi) += -DTCC_ARM_EABI
+NATIVE_DEFINES_$(CONFIG_arm_vfp) += -DTCC_ARM_VFP
+NATIVE_DEFINES_$(CONFIG_arm64) += -DTCC_TARGET_ARM64
+NATIVE_DEFINES += $(NATIVE_DEFINES_yes)
+
+ifeq ($(INCLUDED),no)
+# --------------------------------------------------------------------------
+# running top Makefile
+
+PROGS = tcc$(EXESUF)
+TCCLIBS = $(LIBTCC1) $(LIBTCC) $(LIBTCCDEF)
+TCCDOCS = tcc.1 tcc-doc.html tcc-doc.info
+
+all: $(PROGS) $(TCCLIBS) $(TCCDOCS)
+
+# cross compiler targets to build
+TCC_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince c67
+# TCC_X += arm-fpa arm-fpa-ld arm-vfp arm-eabi
+
+# cross libtcc1.a targets to build
+LIBTCC1_X = i386 x86_64 i386-win32 x86_64-win32 x86_64-osx arm arm64 arm-wince
+
+PROGS_CROSS = $(foreach X,$(TCC_X),$X-tcc$(EXESUF))
+LIBTCC1_CROSS = $(foreach X,$(LIBTCC1_X),$X-libtcc1.a)
+
+# build cross compilers & libs
+cross: $(LIBTCC1_CROSS) $(PROGS_CROSS)
+
+# build specific cross compiler & lib
+cross-%: %-tcc$(EXESUF) %-libtcc1.a ;
+
+install: ; @$(MAKE) --no-print-directory install$(CFGWIN)
+install-strip: ; @$(MAKE) --no-print-directory install$(CFGWIN) CONFIG_strip=yes
+uninstall: ; @$(MAKE) --no-print-directory uninstall$(CFGWIN)
+
+ifdef CONFIG_cross
+all : cross
+endif
+
+# --------------------------------------------
+
+T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown)
+X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-)
+
+DEF-i386        = -DTCC_TARGET_I386
+DEF-x86_64      = -DTCC_TARGET_X86_64
+DEF-i386-win32  = -DTCC_TARGET_PE -DTCC_TARGET_I386
+DEF-x86_64-win32= -DTCC_TARGET_PE -DTCC_TARGET_X86_64
+DEF-x86_64-osx  = -DTCC_TARGET_MACHO -DTCC_TARGET_X86_64
+DEF-arm-wince   = -DTCC_TARGET_PE -DTCC_TARGET_ARM -DTCC_ARM_EABI -DTCC_ARM_VFP -DTCC_ARM_HARDFLOAT
+DEF-arm64       = -DTCC_TARGET_ARM64
+DEF-c67         = -DTCC_TARGET_C67 -w # disable warnigs
+DEF-arm-fpa     = -DTCC_TARGET_ARM
+DEF-arm-fpa-ld  = -DTCC_TARGET_ARM -DLDOUBLE_SIZE=12
+DEF-arm-vfp     = -DTCC_TARGET_ARM -DTCC_ARM_VFP
+DEF-arm-eabi    = -DTCC_TARGET_ARM -DTCC_ARM_VFP -DTCC_ARM_EABI
+DEF-arm-eabihf  = -DTCC_TARGET_ARM -DTCC_ARM_VFP -DTCC_ARM_EABI -DTCC_ARM_HARDFLOAT
+DEF-arm         = $(DEF-arm-eabihf)
+DEF-$(NATIVE_TARGET) = $(NATIVE_DEFINES)
+
+DEFINES += $(DEF-$T) $(DEF-all)
+DEFINES += $(if $(ROOT-$T),-DCONFIG_SYSROOT="\"$(ROOT-$T)\"")
+DEFINES += $(if $(CRT-$T),-DCONFIG_TCC_CRTPREFIX="\"$(CRT-$T)\"")
+DEFINES += $(if $(LIB-$T),-DCONFIG_TCC_LIBPATHS="\"$(LIB-$T)\"")
+DEFINES += $(if $(INC-$T),-DCONFIG_TCC_SYSINCLUDEPATHS="\"$(INC-$T)\"")
+DEFINES += $(DEF-$(or $(findstring win,$T),unx))
+
+ifneq ($(X),)
+ifeq ($(CONFIG_WIN32),yes)
+DEF-win += -DTCC_LIBTCC1="\"$(X)libtcc1.a\""
+DEF-unx += -DTCC_LIBTCC1="\"lib/$(X)libtcc1.a\""
+else
+DEF-all += -DTCC_LIBTCC1="\"$(X)libtcc1.a\""
+DEF-win += -DCONFIG_TCCDIR="\"$(tccdir)/win32\""
+endif
+endif
+
+# include custom configuration (see make help)
+-include config-extra.mak
+
+CORE_FILES = tcc.c tcctools.c libtcc.c tccpp.c tccgen.c tccelf.c tccasm.c tccrun.c
+CORE_FILES += tcc.h config.h libtcc.h tcctok.h
+i386_FILES = $(CORE_FILES) i386-gen.c i386-link.c i386-asm.c i386-asm.h i386-tok.h
+i386-win32_FILES = $(i386_FILES) tccpe.c
+x86_64_FILES = $(CORE_FILES) x86_64-gen.c x86_64-link.c i386-asm.c x86_64-asm.h
+x86_64-win32_FILES = $(x86_64_FILES) tccpe.c
+x86_64-osx_FILES = $(x86_64_FILES)
+arm_FILES = $(CORE_FILES) arm-gen.c arm-link.c arm-asm.c
+arm-wince_FILES = $(arm_FILES) tccpe.c
+arm64_FILES = $(CORE_FILES) arm64-gen.c arm64-link.c
+c67_FILES = $(CORE_FILES) c67-gen.c c67-link.c tcccoff.c
+
+# libtcc sources
+LIBTCC_SRC = $(filter-out tcc.c tcctools.c,$(filter %.c,$($T_FILES)))
+
+ifeq ($(ONE_SOURCE),yes)
+LIBTCC_OBJ = $(X)libtcc.o
+LIBTCC_INC = $($T_FILES)
+TCC_FILES = $(X)tcc.o
+tcc.o : DEFINES += -DONE_SOURCE=0
+else
+LIBTCC_OBJ = $(patsubst %.c,$(X)%.o,$(LIBTCC_SRC))
+LIBTCC_INC = $(filter %.h %-gen.c %-link.c,$($T_FILES))
+TCC_FILES = $(X)tcc.o $(LIBTCC_OBJ)
+$(TCC_FILES) : DEFINES += -DONE_SOURCE=0
+endif
+
+# target specific object rule
+$(X)%.o : %.c $(LIBTCC_INC)
+	$(CC) -o $@ -c $< $(DEFINES) $(CFLAGS)
+
+# additional dependencies
+$(X)tcc.o : tcctools.c
+
+# Host Tiny C Compiler
+tcc$(EXESUF): tcc.o $(LIBTCC)
+	$(CC) -o $@ $^ $(LIBS) $(LDFLAGS) $(LINK_LIBTCC)
+
+# Cross Tiny C Compilers
+%-tcc$(EXESUF): FORCE
+	@$(MAKE) --no-print-directory $@ CROSS_TARGET=$* ONE_SOURCE=$(or $(ONE_SOURCE),yes)
+
+$(CROSS_TARGET)-tcc$(EXESUF): $(TCC_FILES)
+	$(CC) -o $@ $^ $(LIBS) $(LDFLAGS)
+
+# profiling version
+tcc_p$(EXESUF): $($T_FILES)
+	$(CC) -o $@ $< $(DEFINES) $(CFLAGS_P) $(LIBS_P) $(LDFLAGS_P)
+
+# static libtcc library
+libtcc.a: $(LIBTCC_OBJ)
+	$(AR) rcs $@ $^
+
+# dynamic libtcc library
+libtcc.so: $(LIBTCC_OBJ)
+	$(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS)
+
+libtcc.so: CFLAGS+=-fPIC
+libtcc.so: LDFLAGS+=-fPIC
+
+# windows dynamic libtcc library
+libtcc.dll : $(LIBTCC_OBJ)
+	$(CC) -shared -o $@ $^ $(LDFLAGS)
+libtcc.dll : DEFINES += -DLIBTCC_AS_DLL
+
+# import file for windows libtcc.dll
+libtcc.def : libtcc.dll tcc$(EXESUF)
+	$(XTCC) -impdef $< -o $@
+XTCC ?= ./tcc$(EXESUF)
+
+# TinyCC runtime libraries
+libtcc1.a : tcc$(EXESUF) FORCE
+	@$(MAKE) -C lib DEFINES='$(DEF-$T)'
+
+# Cross libtcc1.a
+%-libtcc1.a : %-tcc$(EXESUF) FORCE
+	@$(MAKE) -C lib DEFINES='$(DEF-$*)' CROSS_TARGET=$*
+
+.PRECIOUS: %-libtcc1.a
+FORCE:
+
+# --------------------------------------------------------------------------
+# documentation and man page
+tcc-doc.html: tcc-doc.texi
+	makeinfo --no-split --html --number-sections -o $@ $< || true
+
+tcc.1: tcc-doc.texi
+	$(TOPSRC)/texi2pod.pl $< tcc.pod \
+	&& pod2man --section=1 --center="Tiny C Compiler" --release="$(VERSION)" tcc.pod >tmp.1 \
+	&& mv tmp.1 $@ || rm -f tmp.1
+
+tcc-doc.info: tcc-doc.texi
+	makeinfo $< || true
+
+# --------------------------------------------------------------------------
+# install
+
+INSTALL = install -m644
+INSTALLBIN = install -m755 $(STRIP_$(CONFIG_strip))
+STRIP_yes = -s
+
+LIBTCC1_W = $(filter %-win32-libtcc1.a %-wince-libtcc1.a,$(LIBTCC1_CROSS))
+LIBTCC1_U = $(filter-out $(LIBTCC1_W),$(LIBTCC1_CROSS))
+IB = $(if $1,mkdir -p $2 && $(INSTALLBIN) $1 $2)
+IBw = $(call IB,$(wildcard $1),$2)
+IF = $(if $1,mkdir -p $2 && $(INSTALL) $1 $2)
+IFw = $(call IF,$(wildcard $1),$2)
+IR = mkdir -p $2 && cp -r $1/. $2
+
+# install progs & libs
+install-unx:
+	$(call IBw,$(PROGS) $(PROGS_CROSS),"$(bindir)")
+	$(call IFw,$(LIBTCC1) $(LIBTCC1_U),"$(tccdir)")
+	$(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include")
+	$(call $(if $(findstring .so,$(LIBTCC)),IBw,IFw),$(LIBTCC),"$(libdir)")
+	$(call IF,$(TOPSRC)/libtcc.h,"$(includedir)")
+	$(call IFw,tcc.1,"$(mandir)/man1")
+	$(call IFw,tcc-doc.info,"$(infodir)")
+	$(call IFw,tcc-doc.html,"$(docdir)")
+ifneq "$(wildcard $(LIBTCC1_W))" ""
+	$(call IFw,$(TOPSRC)/win32/lib/*.def $(LIBTCC1_W),"$(tccdir)/win32/lib")
+	$(call IR,$(TOPSRC)/win32/include,"$(tccdir)/win32/include")
+	$(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/win32/include")
+endif
+
+# uninstall
+uninstall-unx:
+	@rm -fv $(foreach P,$(PROGS) $(PROGS_CROSS),"$(bindir)/$P")
+	@rm -fv "$(libdir)/libtcc.a" "$(libdir)/libtcc.so" "$(includedir)/libtcc.h"
+	@rm -fv "$(mandir)/man1/tcc.1" "$(infodir)/tcc-doc.info"
+	@rm -fv "$(docdir)/tcc-doc.html"
+	rm -r "$(tccdir)"
+
+# install progs & libs on windows
+install-win:
+	$(call IBw,$(PROGS) $(PROGS_CROSS) $(subst libtcc.a,,$(LIBTCC)),"$(bindir)")
+	$(call IF,$(TOPSRC)/win32/lib/*.def,"$(tccdir)/lib")
+	$(call IFw,libtcc1.a $(LIBTCC1_W),"$(tccdir)/lib")
+	$(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/include")
+	$(call IR,$(TOPSRC)/win32/include,"$(tccdir)/include")
+	$(call IR,$(TOPSRC)/win32/examples,"$(tccdir)/examples")
+	$(call IF,$(TOPSRC)/tests/libtcc_test.c,"$(tccdir)/examples")
+	$(call IFw,$(TOPSRC)/libtcc.h $(subst .dll,.def,$(LIBTCC)),"$(libdir)")
+	$(call IFw,$(TOPSRC)/win32/tcc-win32.txt tcc-doc.html,"$(docdir)")
+ifneq "$(wildcard $(LIBTCC1_U))" ""
+	$(call IFw,$(LIBTCC1_U),"$(tccdir)/lib")
+	$(call IF,$(TOPSRC)/include/*.h $(TOPSRC)/tcclib.h,"$(tccdir)/lib/include")
+endif
+
+# the msys-git shell works to configure && make except it does not have install
+ifeq "$(and $(CONFIG_WIN32),$(shell which install >/dev/null 2>&1 || echo no))" "no"
+install-win : INSTALL = cp
+install-win : INSTALLBIN = cp
+endif
+
+# uninstall on windows
+uninstall-win:
+	@rm -fv $(foreach P,$(PROGS) $(PROGS_CROSS) libtcc.dll,"$(bindir)/$P")
+	@rm -fv $(foreach F,tcc-doc.html tcc-win32.txt,"$(docdir)/$F")
+	@rm -fv $(foreach F,libtcc.h libtcc.def libtcc.a,"$(libdir)/$F")
+	rm -r "$(tccdir)"
+
+# --------------------------------------------------------------------------
+# other stuff
+
+TAGFILES = *.[ch] include/*.h lib/*.[chS]
+tags : ; ctags $(TAGFILES)
+# cannot have both tags and TAGS on windows
+ETAGS : ; etags $(TAGFILES)
+
+# create release tarball from *current* git branch (including tcc-doc.html
+# and converting two files to CRLF)
+TCC-VERSION = tcc-$(VERSION)
+tar:    tcc-doc.html
+	mkdir $(TCC-VERSION)
+	( cd $(TCC-VERSION) && git --git-dir ../.git checkout -f )
+	cp tcc-doc.html $(TCC-VERSION)
+	for f in tcc-win32.txt build-tcc.bat ; do \
+	    cat win32/$$f | sed 's,\(.*\),\1\r,g' > $(TCC-VERSION)/win32/$$f ; \
+	done
+	tar cjf $(TCC-VERSION).tar.bz2 $(TCC-VERSION)
+	rm -rf $(TCC-VERSION)
+	git reset
+
+config.mak:
+	$(if $(wildcard $@),,@echo "Please run ./configure." && exit 1)
+
+# run all tests
+test:
+	$(MAKE) -C tests
+# run test(s) from tests2 subdir (see make help)
+tests2.%:
+	$(MAKE) -C tests/tests2 $@
+
+clean:
+	rm -f tcc$(EXESUF) tcc_p$(EXESUF) *-tcc$(EXESUF) tcc.pod
+	rm -f  *~ *.o *.a *.so* *.out *.log lib*.def *.exe *.dll a.out tags TAGS
+	@$(MAKE) -C lib $@
+	@$(MAKE) -C tests $@
+
+distclean: clean
+	rm -f config.h config.mak config.texi tcc.1 tcc-doc.info tcc-doc.html
+
+.PHONY: all clean test tar tags ETAGS distclean install uninstall FORCE
+
+help:
+	@echo "make"
+	@echo "   build native compiler (from separate objects)"
+	@echo ""
+	@echo "make cross"
+	@echo "   build cross compilers (from one source)"
+	@echo ""
+	@echo "make ONE_SOURCE=yes / no"
+	@echo "   force building from one source / separate objects"
+	@echo ""
+	@echo "make cross-TARGET"
+	@echo "   build one specific cross compiler for 'TARGET', as in"
+	@echo "   $(TCC_X)"
+	@echo ""
+	@echo "Custom configuration:"
+	@echo "   The makefile includes a file 'config-extra.mak' if it is present."
+	@echo "   This file may contain some custom configuration.  For example:"
+	@echo ""
+	@echo "      NATIVE_DEFINES += -D..."
+	@echo ""
+	@echo "   Or for example to configure the search paths for a cross-compiler"
+	@echo "   that expects the linux files in <tccdir>/i386-linux:"
+	@echo ""
+	@echo "      ROOT-i386 = {B}/i386-linux"
+	@echo "      CRT-i386  = {B}/i386-linux/usr/lib"
+	@echo "      LIB-i386  = {B}/i386-linux/lib:{B}/i386-linux/usr/lib"
+	@echo "      INC-i386  = {B}/lib/include:{B}/i386-linux/usr/include"
+	@echo "      DEF-i386  += -D__linux__"
+	@echo ""
+	@echo "make test"
+	@echo "   run all tests"
+	@echo ""
+	@echo "make tests2.all / make tests2.37 / make tests2.37+"
+	@echo "   run all/single test(s) from tests2, optionally update .expect"
+	@echo ""
+	@echo "Other supported make targets:"
+	@echo "   install install-strip tags ETAGS tar clean distclean help"
+	@echo ""
+
+# --------------------------------------------------------------------------
+endif # ($(INCLUDED),no)
Index: EcnlProtoTool/trunk/tcc-0.9.27/README
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/README	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/README	(revision 331)
@@ -0,0 +1,95 @@
+Tiny C Compiler - C Scripting Everywhere - The Smallest ANSI C compiler
+-----------------------------------------------------------------------
+
+Features:
+--------
+
+- SMALL! You can compile and execute C code everywhere, for example on
+  rescue disks.
+
+- FAST! tcc generates optimized x86 code. No byte code
+  overhead. Compile, assemble and link about 7 times faster than 'gcc
+  -O0'.
+
+- UNLIMITED! Any C dynamic library can be used directly. TCC is
+  heading torward full ISOC99 compliance. TCC can of course compile
+  itself.
+
+- SAFE! tcc includes an optional memory and bound checker. Bound
+  checked code can be mixed freely with standard code.
+
+- Compile and execute C source directly. No linking or assembly
+  necessary. Full C preprocessor included. 
+
+- C script supported : just add '#!/usr/local/bin/tcc -run' at the first
+  line of your C source, and execute it directly from the command
+  line.
+
+Documentation:
+-------------
+
+1) Installation on a i386/x86_64/arm Linux/OSX/FreeBSD host
+
+   ./configure
+   make
+   make test
+   make install
+
+   Notes: For OSX and FreeBSD, gmake should be used instead of make.
+   For Windows read tcc-win32.txt.
+
+makeinfo must be installed to compile the doc.  By default, tcc is
+installed in /usr/local/bin.  ./configure --help  shows configuration
+options.
+
+
+2) Introduction
+
+We assume here that you know ANSI C. Look at the example ex1.c to know
+what the programs look like.
+
+The include file <tcclib.h> can be used if you want a small basic libc
+include support (especially useful for floppy disks). Of course, you
+can also use standard headers, although they are slower to compile.
+
+You can begin your C script with '#!/usr/local/bin/tcc -run' on the first
+line and set its execute bits (chmod a+x your_script). Then, you can
+launch the C code as a shell or perl script :-) The command line
+arguments are put in 'argc' and 'argv' of the main functions, as in
+ANSI C.
+
+3) Examples
+
+ex1.c: simplest example (hello world). Can also be launched directly
+as a script: './ex1.c'.
+
+ex2.c: more complicated example: find a number with the four
+operations given a list of numbers (benchmark).
+
+ex3.c: compute fibonacci numbers (benchmark).
+
+ex4.c: more complicated: X11 program. Very complicated test in fact
+because standard headers are being used ! As for ex1.c, can also be launched
+directly as a script: './ex4.c'.
+
+ex5.c: 'hello world' with standard glibc headers.
+
+tcc.c: TCC can of course compile itself. Used to check the code
+generator.
+
+tcctest.c: auto test for TCC which tests many subtle possible bugs. Used
+when doing 'make test'.
+
+4) Full Documentation
+
+Please read tcc-doc.html to have all the features of TCC.
+
+Additional information is available for the Windows port in tcc-win32.txt.
+
+License:
+-------
+
+TCC is distributed under the GNU Lesser General Public License (see
+COPYING file).
+
+Fabrice Bellard.
Index: EcnlProtoTool/trunk/tcc-0.9.27/RELICENSING
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/RELICENSING	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/RELICENSING	(revision 331)
@@ -0,0 +1,60 @@
+
+ Relicensing TinyCC
+ ------------------
+
+ The authors listed below hereby confirm their agreement to relicense TinyCC
+ including their past contributions under the following terms:
+
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+
+
+ Author (name)              I agree (YES/NO)    Files/Features (optional)
+ ------------------------------------------------------------------------------
+ Adam Sampson               YES                 makefiles
+ Daniel Gl旦ckner            NO                  arm-gen.c
+ Daniel Gl旦ckner            YES                 not arm-gen.c
+ Edmund Grimley Evans       YES                 arm64
+ Fabrice Bellard            YES                 original author
+ Fr辿d辿ric F辿ret             YES                 x86 64/16 bit asm
+ grischka                   YES                 tccpe.c
+ Henry Kroll                YES
+ Joe Soroka                 YES
+ Kirill Smelkov             YES
+ mingodad                   YES
+ Pip Cet                    YES
+ Shinichiro Hamaji          YES                 x86_64-gen.c
+ Vincent Lef竪vre            YES
+ Thomas Preud'homme         YES                 arm-gen.c
+ Timo VJ L辰hde (Timppa)     ?                   tiny_libmaker.c
+ TK                         ?                   tcccoff.c c67-gen.c
+ Urs Janssen                YES
+ waddlesplash               YES
+ Christian Jullien          YES                 Windows Cygwin build and tests
+
+
+ ------------------------------------------------------------------------------
+
+ Please add yourself to the list above (rsp. replace the question mark)
+ and (after fetching the latest version) commit to the "mob" branch with
+ commit message:
+
+     Relicensing TinyCC
+
+ Thanks.
Index: EcnlProtoTool/trunk/tcc-0.9.27/TODO
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/TODO	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/TODO	(revision 331)
@@ -0,0 +1,100 @@
+TODO list:
+
+Bugs:
+
+- i386 fastcall is mostly wrong
+- FPU st(0) is left unclean (kwisatz haderach). Incompatible with
+  optimized gcc/msc code
+- see transparent union pb in /urs/include/sys/socket.h
+- precise behaviour of typeof with arrays ? (__put_user macro)
+  but should suffice for most cases)
+- handle '? x, y : z' in unsized variable initialization (',' is
+  considered incorrectly as separator in preparser)
+- transform functions to function pointers in function parameters
+  (net/ipv4/ip_output.c)
+- fix function pointer type display
+- check section alignment in C
+- fix invalid cast in comparison 'if (v == (int8_t)v)'
+- finish varargs.h support (gcc 3.2 testsuite issue)
+- fix static functions declared inside block
+- fix multiple unions init
+- make libtcc fully reentrant (except for the compilation stage itself).
+- struct/union/enum definitions in nested scopes (see also Debian bug #770657)
+- __STDC_IEC_559__: float f(void) { static float x = 0.0 / 0.0; return x; }
+- memory may be leaked after errors (longjmp).
+
+Portability:
+
+- it is assumed that int is 32-bit and sizeof(int) == 4
+- int is used when host or target size_t would make more sense
+- TCC handles target floating-point (fp) values using the host's fp
+  arithmetic, which is simple and fast but may lead to exceptions
+  and inaccuracy and wrong representations when cross-compiling
+
+Linking:
+
+- static linking (-static) does not work
+
+Bound checking:
+
+- fix bound exit on RedHat 7.3
+- setjmp is not supported properly in bound checking.
+- fix bound check code with '&' on local variables (currently done
+  only for local arrays).
+- bound checking and float/long long/struct copy code. bound
+  checking and symbol + offset optimization
+
+Missing features:
+
+- disable-asm and disable-bcheck options
+- __builtin_expect()
+- atexit (Nigel Horne)
+- C99: add complex types (gcc 3.2 testsuite issue)
+- postfix compound literals (see 20010124-1.c)
+- interactive mode / integrated debugger
+
+Optimizations:
+
+- suppress specific anonymous symbol handling
+- more parse optimizations (=even faster compilation)
+- memory alloc optimizations (=even faster compilation)
+- optimize VT_LOCAL + const
+- better local variables handling (needed for other targets)
+
+Not critical:
+
+- C99: fix multiple compound literals inits in blocks (ISOC99
+  normative example - only relevant when using gotos! -> must add
+  boolean variable to tell if compound literal was already
+  initialized).
+- add PowerPC generator and improve codegen for RISC (need
+  to suppress VT_LOCAL and use a base register instead).
+- fix preprocessor symbol redefinition
+- add portable byte code generator and interpreter for other
+  unsupported architectures.
+- C++: variable declaration in for, minimal 'class' support.
+- win32: __intxx. use resolve for bchecked malloc et al.
+  check exception code (exception filter func).
+- handle void (__attribute__() *ptr)()
+- VLAs are implemented in a way that is not compatible with signals:
+  http://lists.gnu.org/archive/html/tinycc-devel/2015-11/msg00018.html
+
+Fixed (probably):
+
+- bug with defines:
+    #define spin_lock(lock) do { } while (0)
+    #define wq_spin_lock spin_lock
+    #define TEST() wq_spin_lock(a)
+- typedefs can be structure fields
+- see bugfixes.diff + improvement.diff from Daniel Glockner
+- long long constant evaluation
+- add alloca()
+- gcc '-E' option.
+- #include_next support for /usr/include/limits ?
+- function pointers/lvalues in ? : (linux kernel net/core/dev.c)
+- win32: add __stdcall, check GetModuleHandle for dlls.
+- macro substitution with nested definitions (ShangHongzhang)
+- with "-run" and libtcc, a PLT is now built.
+- '-E' option was improved
+- packed attribute is now supported
+- ARM and ARM64 code generators have been added.
Index: EcnlProtoTool/trunk/tcc-0.9.27/VERSION
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/VERSION	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/VERSION	(revision 331)
@@ -0,0 +1,1 @@
+0.9.27
Index: EcnlProtoTool/trunk/tcc-0.9.27/arm-asm.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/arm-asm.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/arm-asm.c	(revision 331)
@@ -0,0 +1,94 @@
+/*************************************************************/
+/*
+ *  ARM dummy assembler for TCC
+ *
+ */
+
+#ifdef TARGET_DEFS_ONLY
+
+#define CONFIG_TCC_ASM
+#define NB_ASM_REGS 16
+
+ST_FUNC void g(int c);
+ST_FUNC void gen_le16(int c);
+ST_FUNC void gen_le32(int c);
+
+/*************************************************************/
+#else
+/*************************************************************/
+
+#include "tcc.h"
+
+static void asm_error(void)
+{
+    tcc_error("ARM asm not implemented.");
+}
+
+/* XXX: make it faster ? */
+ST_FUNC void g(int c)
+{
+    int ind1;
+    if (nocode_wanted)
+        return;
+    ind1 = ind + 1;
+    if (ind1 > cur_text_section->data_allocated)
+        section_realloc(cur_text_section, ind1);
+    cur_text_section->data[ind] = c;
+    ind = ind1;
+}
+
+ST_FUNC void gen_le16 (int i)
+{
+    g(i);
+    g(i>>8);
+}
+
+ST_FUNC void gen_le32 (int i)
+{
+    gen_le16(i);
+    gen_le16(i>>16);
+}
+
+ST_FUNC void gen_expr32(ExprValue *pe)
+{
+    gen_le32(pe->v);
+}
+
+ST_FUNC void asm_opcode(TCCState *s1, int opcode)
+{
+    asm_error();
+}
+
+ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier)
+{
+    asm_error();
+}
+
+/* generate prolog and epilog code for asm statement */
+ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
+                         int nb_outputs, int is_output,
+                         uint8_t *clobber_regs,
+                         int out_reg)
+{
+}
+
+ST_FUNC void asm_compute_constraints(ASMOperand *operands,
+                                    int nb_operands, int nb_outputs,
+                                    const uint8_t *clobber_regs,
+                                    int *pout_reg)
+{
+}
+
+ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)
+{
+    asm_error();
+}
+
+ST_FUNC int asm_parse_regvar (int t)
+{
+    asm_error();
+    return -1;
+}
+
+/*************************************************************/
+#endif /* ndef TARGET_DEFS_ONLY */
Index: EcnlProtoTool/trunk/tcc-0.9.27/arm-gen.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/arm-gen.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/arm-gen.c	(revision 331)
@@ -0,0 +1,2151 @@
+/*
+ *  ARMv4 code generator for TCC
+ *
+ *  Copyright (c) 2003 Daniel Glöckner
+ *  Copyright (c) 2012 Thomas Preud'homme
+ *
+ *  Based on i386-gen.c by Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef TARGET_DEFS_ONLY
+
+#if defined(TCC_ARM_EABI) && !defined(TCC_ARM_VFP)
+#error "Currently TinyCC only supports float computation with VFP instructions"
+#endif
+
+/* number of available registers */
+#ifdef TCC_ARM_VFP
+#define NB_REGS            13
+#else
+#define NB_REGS             9
+#endif
+
+#ifndef TCC_CPU_VERSION
+# define TCC_CPU_VERSION 5
+#endif
+
+/* a register can belong to several classes. The classes must be
+   sorted from more general to more precise (see gv2() code which does
+   assumptions on it). */
+#define RC_INT     0x0001 /* generic integer register */
+#define RC_FLOAT   0x0002 /* generic float register */
+#define RC_R0      0x0004
+#define RC_R1      0x0008
+#define RC_R2      0x0010
+#define RC_R3      0x0020
+#define RC_R12     0x0040
+#define RC_F0      0x0080
+#define RC_F1      0x0100
+#define RC_F2      0x0200
+#define RC_F3      0x0400
+#ifdef TCC_ARM_VFP
+#define RC_F4      0x0800
+#define RC_F5      0x1000
+#define RC_F6      0x2000
+#define RC_F7      0x4000
+#endif
+#define RC_IRET    RC_R0  /* function return: integer register */
+#define RC_LRET    RC_R1  /* function return: second integer register */
+#define RC_FRET    RC_F0  /* function return: float register */
+
+/* pretty names for the registers */
+enum {
+    TREG_R0 = 0,
+    TREG_R1,
+    TREG_R2,
+    TREG_R3,
+    TREG_R12,
+    TREG_F0,
+    TREG_F1,
+    TREG_F2,
+    TREG_F3,
+#ifdef TCC_ARM_VFP
+    TREG_F4,
+    TREG_F5,
+    TREG_F6,
+    TREG_F7,
+#endif
+    TREG_SP = 13,
+    TREG_LR,
+};
+
+#ifdef TCC_ARM_VFP
+#define T2CPR(t) (((t) & VT_BTYPE) != VT_FLOAT ? 0x100 : 0)
+#endif
+
+/* return registers for function */
+#define REG_IRET TREG_R0 /* single word int return register */
+#define REG_LRET TREG_R1 /* second word return register (for long long) */
+#define REG_FRET TREG_F0 /* float return register */
+
+#ifdef TCC_ARM_EABI
+#define TOK___divdi3 TOK___aeabi_ldivmod
+#define TOK___moddi3 TOK___aeabi_ldivmod
+#define TOK___udivdi3 TOK___aeabi_uldivmod
+#define TOK___umoddi3 TOK___aeabi_uldivmod
+#endif
+
+/* defined if function parameters must be evaluated in reverse order */
+#define INVERT_FUNC_PARAMS
+
+/* defined if structures are passed as pointers. Otherwise structures
+   are directly pushed on stack. */
+/* #define FUNC_STRUCT_PARAM_AS_PTR */
+
+/* pointer size, in bytes */
+#define PTR_SIZE 4
+
+/* long double size and alignment, in bytes */
+#ifdef TCC_ARM_VFP
+#define LDOUBLE_SIZE  8
+#endif
+
+#ifndef LDOUBLE_SIZE
+#define LDOUBLE_SIZE  8
+#endif
+
+#ifdef TCC_ARM_EABI
+#define LDOUBLE_ALIGN 8
+#else
+#define LDOUBLE_ALIGN 4
+#endif
+
+/* maximum alignment (for aligned attribute support) */
+#define MAX_ALIGN     8
+
+#define CHAR_IS_UNSIGNED
+
+/******************************************************/
+#else /* ! TARGET_DEFS_ONLY */
+/******************************************************/
+#include "tcc.h"
+
+enum float_abi float_abi;
+
+ST_DATA const int reg_classes[NB_REGS] = {
+    /* r0 */ RC_INT | RC_R0,
+    /* r1 */ RC_INT | RC_R1,
+    /* r2 */ RC_INT | RC_R2,
+    /* r3 */ RC_INT | RC_R3,
+    /* r12 */ RC_INT | RC_R12,
+    /* f0 */ RC_FLOAT | RC_F0,
+    /* f1 */ RC_FLOAT | RC_F1,
+    /* f2 */ RC_FLOAT | RC_F2,
+    /* f3 */ RC_FLOAT | RC_F3,
+#ifdef TCC_ARM_VFP
+ /* d4/s8 */ RC_FLOAT | RC_F4,
+/* d5/s10 */ RC_FLOAT | RC_F5,
+/* d6/s12 */ RC_FLOAT | RC_F6,
+/* d7/s14 */ RC_FLOAT | RC_F7,
+#endif
+};
+
+static int func_sub_sp_offset, last_itod_magic;
+static int leaffunc;
+
+#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
+static CType float_type, double_type, func_float_type, func_double_type;
+ST_FUNC void arm_init(struct TCCState *s)
+{
+    float_type.t = VT_FLOAT;
+    double_type.t = VT_DOUBLE;
+    func_float_type.t = VT_FUNC;
+    func_float_type.ref = sym_push(SYM_FIELD, &float_type, FUNC_CDECL, FUNC_OLD);
+    func_double_type.t = VT_FUNC;
+    func_double_type.ref = sym_push(SYM_FIELD, &double_type, FUNC_CDECL, FUNC_OLD);
+
+    float_abi = s->float_abi;
+#ifndef TCC_ARM_HARDFLOAT
+    tcc_warning("soft float ABI currently not supported: default to softfp");
+#endif
+}
+#else
+#define func_float_type func_old_type
+#define func_double_type func_old_type
+#define func_ldouble_type func_old_type
+ST_FUNC void arm_init(struct TCCState *s)
+{
+#if 0
+#if !defined (TCC_ARM_VFP)
+    tcc_warning("Support for FPA is deprecated and will be removed in next"
+                " release");
+#endif
+#if !defined (TCC_ARM_EABI)
+    tcc_warning("Support for OABI is deprecated and will be removed in next"
+                " release");
+#endif
+#endif
+}
+#endif
+
+static int two2mask(int a,int b) {
+  return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT);
+}
+
+static int regmask(int r) {
+  return reg_classes[r]&~(RC_INT|RC_FLOAT);
+}
+
+/******************************************************/
+
+#if defined(TCC_ARM_EABI) && !defined(CONFIG_TCC_ELFINTERP)
+const char *default_elfinterp(struct TCCState *s)
+{
+    if (s->float_abi == ARM_HARD_FLOAT)
+        return "/lib/ld-linux-armhf.so.3";
+    else
+        return "/lib/ld-linux.so.3";
+}
+#endif
+
+void o(uint32_t i)
+{
+  /* this is a good place to start adding big-endian support*/
+  int ind1;
+  if (nocode_wanted)
+    return;
+  ind1 = ind + 4;
+  if (!cur_text_section)
+    tcc_error("compiler error! This happens f.ex. if the compiler\n"
+         "can't evaluate constant expressions outside of a function.");
+  if (ind1 > cur_text_section->data_allocated)
+    section_realloc(cur_text_section, ind1);
+  cur_text_section->data[ind++] = i&255;
+  i>>=8;
+  cur_text_section->data[ind++] = i&255;
+  i>>=8;
+  cur_text_section->data[ind++] = i&255;
+  i>>=8;
+  cur_text_section->data[ind++] = i;
+}
+
+static uint32_t stuff_const(uint32_t op, uint32_t c)
+{
+  int try_neg=0;
+  uint32_t nc = 0, negop = 0;
+
+  switch(op&0x1F00000)
+  {
+    case 0x800000: //add
+    case 0x400000: //sub
+      try_neg=1;
+      negop=op^0xC00000;
+      nc=-c;
+      break;
+    case 0x1A00000: //mov
+    case 0x1E00000: //mvn
+      try_neg=1;
+      negop=op^0x400000;
+      nc=~c;
+      break;
+    case 0x200000: //xor
+      if(c==~0)
+	return (op&0xF010F000)|((op>>16)&0xF)|0x1E00000;
+      break;
+    case 0x0: //and
+      if(c==~0)
+	return (op&0xF010F000)|((op>>16)&0xF)|0x1A00000;
+    case 0x1C00000: //bic
+      try_neg=1;
+      negop=op^0x1C00000;
+      nc=~c;
+      break;
+    case 0x1800000: //orr
+      if(c==~0)
+	return (op&0xFFF0FFFF)|0x1E00000;
+      break;
+  }
+  do {
+    uint32_t m;
+    int i;
+    if(c<256) /* catch undefined <<32 */
+      return op|c;
+    for(i=2;i<32;i+=2) {
+      m=(0xff>>i)|(0xff<<(32-i));
+      if(!(c&~m))
+	return op|(i<<7)|(c<<i)|(c>>(32-i));
+    }
+    op=negop;
+    c=nc;
+  } while(try_neg--);
+  return 0;
+}
+
+
+//only add,sub
+void stuff_const_harder(uint32_t op, uint32_t v) {
+  uint32_t x;
+  x=stuff_const(op,v);
+  if(x)
+    o(x);
+  else {
+    uint32_t a[16], nv, no, o2, n2;
+    int i,j,k;
+    a[0]=0xff;
+    o2=(op&0xfff0ffff)|((op&0xf000)<<4);;
+    for(i=1;i<16;i++)
+      a[i]=(a[i-1]>>2)|(a[i-1]<<30);
+    for(i=0;i<12;i++)
+      for(j=i<4?i+12:15;j>=i+4;j--)
+	if((v&(a[i]|a[j]))==v) {
+	  o(stuff_const(op,v&a[i]));
+	  o(stuff_const(o2,v&a[j]));
+	  return;
+	}
+    no=op^0xC00000;
+    n2=o2^0xC00000;
+    nv=-v;
+    for(i=0;i<12;i++)
+      for(j=i<4?i+12:15;j>=i+4;j--)
+	if((nv&(a[i]|a[j]))==nv) {
+	  o(stuff_const(no,nv&a[i]));
+	  o(stuff_const(n2,nv&a[j]));
+	  return;
+	}
+    for(i=0;i<8;i++)
+      for(j=i+4;j<12;j++)
+	for(k=i<4?i+12:15;k>=j+4;k--)
+	  if((v&(a[i]|a[j]|a[k]))==v) {
+	    o(stuff_const(op,v&a[i]));
+	    o(stuff_const(o2,v&a[j]));
+	    o(stuff_const(o2,v&a[k]));
+	    return;
+	  }
+    no=op^0xC00000;
+    nv=-v;
+    for(i=0;i<8;i++)
+      for(j=i+4;j<12;j++)
+	for(k=i<4?i+12:15;k>=j+4;k--)
+	  if((nv&(a[i]|a[j]|a[k]))==nv) {
+	    o(stuff_const(no,nv&a[i]));
+	    o(stuff_const(n2,nv&a[j]));
+	    o(stuff_const(n2,nv&a[k]));
+	    return;
+	  }
+    o(stuff_const(op,v&a[0]));
+    o(stuff_const(o2,v&a[4]));
+    o(stuff_const(o2,v&a[8]));
+    o(stuff_const(o2,v&a[12]));
+  }
+}
+
+uint32_t encbranch(int pos, int addr, int fail)
+{
+  addr-=pos+8;
+  addr/=4;
+  if(addr>=0x1000000 || addr<-0x1000000) {
+    if(fail)
+      tcc_error("FIXME: function bigger than 32MB");
+    return 0;
+  }
+  return 0x0A000000|(addr&0xffffff);
+}
+
+int decbranch(int pos)
+{
+  int x;
+  x=*(uint32_t *)(cur_text_section->data + pos);
+  x&=0x00ffffff;
+  if(x&0x800000)
+    x-=0x1000000;
+  return x*4+pos+8;
+}
+
+/* output a symbol and patch all calls to it */
+void gsym_addr(int t, int a)
+{
+  uint32_t *x;
+  int lt;
+  while(t) {
+    x=(uint32_t *)(cur_text_section->data + t);
+    t=decbranch(lt=t);
+    if(a==lt+4)
+      *x=0xE1A00000; // nop
+    else {
+      *x &= 0xff000000;
+      *x |= encbranch(lt,a,1);
+    }
+  }
+}
+
+void gsym(int t)
+{
+  gsym_addr(t, ind);
+}
+
+#ifdef TCC_ARM_VFP
+static uint32_t vfpr(int r)
+{
+  if(r<TREG_F0 || r>TREG_F7)
+    tcc_error("compiler error! register %i is no vfp register",r);
+  return r - TREG_F0;
+}
+#else
+static uint32_t fpr(int r)
+{
+  if(r<TREG_F0 || r>TREG_F3)
+    tcc_error("compiler error! register %i is no fpa register",r);
+  return r - TREG_F0;
+}
+#endif
+
+static uint32_t intr(int r)
+{
+  if(r == TREG_R12)
+    return 12;
+  if(r >= TREG_R0 && r <= TREG_R3)
+    return r - TREG_R0;
+  if (r >= TREG_SP && r <= TREG_LR)
+    return r + (13 - TREG_SP);
+  tcc_error("compiler error! register %i is no int register",r);
+}
+
+static void calcaddr(uint32_t *base, int *off, int *sgn, int maxoff, unsigned shift)
+{
+  if(*off>maxoff || *off&((1<<shift)-1)) {
+    uint32_t x, y;
+    x=0xE280E000;
+    if(*sgn)
+      x=0xE240E000;
+    x|=(*base)<<16;
+    *base=14; // lr
+    y=stuff_const(x,*off&~maxoff);
+    if(y) {
+      o(y);
+      *off&=maxoff;
+      return;
+    }
+    y=stuff_const(x,(*off+maxoff)&~maxoff);
+    if(y) {
+      o(y);
+      *sgn=!*sgn;
+      *off=((*off+maxoff)&~maxoff)-*off;
+      return;
+    }
+    stuff_const_harder(x,*off&~maxoff);
+    *off&=maxoff;
+  }
+}
+
+static uint32_t mapcc(int cc)
+{
+  switch(cc)
+  {
+    case TOK_ULT:
+      return 0x30000000; /* CC/LO */
+    case TOK_UGE:
+      return 0x20000000; /* CS/HS */
+    case TOK_EQ:
+      return 0x00000000; /* EQ */
+    case TOK_NE:
+      return 0x10000000; /* NE */
+    case TOK_ULE:
+      return 0x90000000; /* LS */
+    case TOK_UGT:
+      return 0x80000000; /* HI */
+    case TOK_Nset:
+      return 0x40000000; /* MI */
+    case TOK_Nclear:
+      return 0x50000000; /* PL */
+    case TOK_LT:
+      return 0xB0000000; /* LT */
+    case TOK_GE:
+      return 0xA0000000; /* GE */
+    case TOK_LE:
+      return 0xD0000000; /* LE */
+    case TOK_GT:
+      return 0xC0000000; /* GT */
+  }
+  tcc_error("unexpected condition code");
+  return 0xE0000000; /* AL */
+}
+
+static int negcc(int cc)
+{
+  switch(cc)
+  {
+    case TOK_ULT:
+      return TOK_UGE;
+    case TOK_UGE:
+      return TOK_ULT;
+    case TOK_EQ:
+      return TOK_NE;
+    case TOK_NE:
+      return TOK_EQ;
+    case TOK_ULE:
+      return TOK_UGT;
+    case TOK_UGT:
+      return TOK_ULE;
+    case TOK_Nset:
+      return TOK_Nclear;
+    case TOK_Nclear:
+      return TOK_Nset;
+    case TOK_LT:
+      return TOK_GE;
+    case TOK_GE:
+      return TOK_LT;
+    case TOK_LE:
+      return TOK_GT;
+    case TOK_GT:
+      return TOK_LE;
+  }
+  tcc_error("unexpected condition code");
+  return TOK_NE;
+}
+
+/* load 'r' from value 'sv' */
+void load(int r, SValue *sv)
+{
+  int v, ft, fc, fr, sign;
+  uint32_t op;
+  SValue v1;
+
+  fr = sv->r;
+  ft = sv->type.t;
+  fc = sv->c.i;
+
+  if(fc>=0)
+    sign=0;
+  else {
+    sign=1;
+    fc=-fc;
+  }
+
+  v = fr & VT_VALMASK;
+  if (fr & VT_LVAL) {
+    uint32_t base = 0xB; // fp
+    if(v == VT_LLOCAL) {
+      v1.type.t = VT_PTR;
+      v1.r = VT_LOCAL | VT_LVAL;
+      v1.c.i = sv->c.i;
+      load(TREG_LR, &v1);
+      base = 14; /* lr */
+      fc=sign=0;
+      v=VT_LOCAL;
+    } else if(v == VT_CONST) {
+      v1.type.t = VT_PTR;
+      v1.r = fr&~VT_LVAL;
+      v1.c.i = sv->c.i;
+      v1.sym=sv->sym;
+      load(TREG_LR, &v1);
+      base = 14; /* lr */
+      fc=sign=0;
+      v=VT_LOCAL;
+    } else if(v < VT_CONST) {
+      base=intr(v);
+      fc=sign=0;
+      v=VT_LOCAL;
+    }
+    if(v == VT_LOCAL) {
+      if(is_float(ft)) {
+	calcaddr(&base,&fc,&sign,1020,2);
+#ifdef TCC_ARM_VFP
+        op=0xED100A00; /* flds */
+        if(!sign)
+          op|=0x800000;
+        if ((ft & VT_BTYPE) != VT_FLOAT)
+          op|=0x100;   /* flds -> fldd */
+        o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16));
+#else
+	op=0xED100100;
+	if(!sign)
+	  op|=0x800000;
+#if LDOUBLE_SIZE == 8
+	if ((ft & VT_BTYPE) != VT_FLOAT)
+	  op|=0x8000;
+#else
+	if ((ft & VT_BTYPE) == VT_DOUBLE)
+	  op|=0x8000;
+	else if ((ft & VT_BTYPE) == VT_LDOUBLE)
+	  op|=0x400000;
+#endif
+	o(op|(fpr(r)<<12)|(fc>>2)|(base<<16));
+#endif
+      } else if((ft & (VT_BTYPE|VT_UNSIGNED)) == VT_BYTE
+                || (ft & VT_BTYPE) == VT_SHORT) {
+	calcaddr(&base,&fc,&sign,255,0);
+	op=0xE1500090;
+	if ((ft & VT_BTYPE) == VT_SHORT)
+	  op|=0x20;
+	if ((ft & VT_UNSIGNED) == 0)
+	  op|=0x40;
+	if(!sign)
+	  op|=0x800000;
+	o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));
+      } else {
+	calcaddr(&base,&fc,&sign,4095,0);
+	op=0xE5100000;
+	if(!sign)
+	  op|=0x800000;
+        if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)
+          op|=0x400000;
+        o(op|(intr(r)<<12)|fc|(base<<16));
+      }
+      return;
+    }
+  } else {
+    if (v == VT_CONST) {
+      op=stuff_const(0xE3A00000|(intr(r)<<12),sv->c.i);
+      if (fr & VT_SYM || !op) {
+        o(0xE59F0000|(intr(r)<<12));
+        o(0xEA000000);
+        if(fr & VT_SYM)
+	  greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
+        o(sv->c.i);
+      } else
+        o(op);
+      return;
+    } else if (v == VT_LOCAL) {
+      op=stuff_const(0xE28B0000|(intr(r)<<12),sv->c.i);
+      if (fr & VT_SYM || !op) {
+	o(0xE59F0000|(intr(r)<<12));
+	o(0xEA000000);
+	if(fr & VT_SYM) // needed ?
+	  greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
+	o(sv->c.i);
+	o(0xE08B0000|(intr(r)<<12)|intr(r));
+      } else
+	o(op);
+      return;
+    } else if(v == VT_CMP) {
+      o(mapcc(sv->c.i)|0x3A00001|(intr(r)<<12));
+      o(mapcc(negcc(sv->c.i))|0x3A00000|(intr(r)<<12));
+      return;
+    } else if (v == VT_JMP || v == VT_JMPI) {
+      int t;
+      t = v & 1;
+      o(0xE3A00000|(intr(r)<<12)|t);
+      o(0xEA000000);
+      gsym(sv->c.i);
+      o(0xE3A00000|(intr(r)<<12)|(t^1));
+      return;
+    } else if (v < VT_CONST) {
+      if(is_float(ft))
+#ifdef TCC_ARM_VFP
+        o(0xEEB00A40|(vfpr(r)<<12)|vfpr(v)|T2CPR(ft)); /* fcpyX */
+#else
+	o(0xEE008180|(fpr(r)<<12)|fpr(v));
+#endif
+      else
+	o(0xE1A00000|(intr(r)<<12)|intr(v));
+      return;
+    }
+  }
+  tcc_error("load unimplemented!");
+}
+
+/* store register 'r' in lvalue 'v' */
+void store(int r, SValue *sv)
+{
+  SValue v1;
+  int v, ft, fc, fr, sign;
+  uint32_t op;
+
+  fr = sv->r;
+  ft = sv->type.t;
+  fc = sv->c.i;
+
+  if(fc>=0)
+    sign=0;
+  else {
+    sign=1;
+    fc=-fc;
+  }
+
+  v = fr & VT_VALMASK;
+  if (fr & VT_LVAL || fr == VT_LOCAL) {
+    uint32_t base = 0xb; /* fp */
+    if(v < VT_CONST) {
+      base=intr(v);
+      v=VT_LOCAL;
+      fc=sign=0;
+    } else if(v == VT_CONST) {
+      v1.type.t = ft;
+      v1.r = fr&~VT_LVAL;
+      v1.c.i = sv->c.i;
+      v1.sym=sv->sym;
+      load(TREG_LR, &v1);
+      base = 14; /* lr */
+      fc=sign=0;
+      v=VT_LOCAL;
+    }
+    if(v == VT_LOCAL) {
+       if(is_float(ft)) {
+	calcaddr(&base,&fc,&sign,1020,2);
+#ifdef TCC_ARM_VFP
+        op=0xED000A00; /* fsts */
+        if(!sign)
+          op|=0x800000;
+        if ((ft & VT_BTYPE) != VT_FLOAT)
+          op|=0x100;   /* fsts -> fstd */
+        o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16));
+#else
+	op=0xED000100;
+	if(!sign)
+	  op|=0x800000;
+#if LDOUBLE_SIZE == 8
+	if ((ft & VT_BTYPE) != VT_FLOAT)
+	  op|=0x8000;
+#else
+	if ((ft & VT_BTYPE) == VT_DOUBLE)
+	  op|=0x8000;
+	if ((ft & VT_BTYPE) == VT_LDOUBLE)
+	  op|=0x400000;
+#endif
+	o(op|(fpr(r)<<12)|(fc>>2)|(base<<16));
+#endif
+	return;
+      } else if((ft & VT_BTYPE) == VT_SHORT) {
+	calcaddr(&base,&fc,&sign,255,0);
+	op=0xE14000B0;
+	if(!sign)
+	  op|=0x800000;
+	o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));
+      } else {
+	calcaddr(&base,&fc,&sign,4095,0);
+	op=0xE5000000;
+	if(!sign)
+	  op|=0x800000;
+        if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)
+          op|=0x400000;
+        o(op|(intr(r)<<12)|fc|(base<<16));
+      }
+      return;
+    }
+  }
+  tcc_error("store unimplemented");
+}
+
+static void gadd_sp(int val)
+{
+  stuff_const_harder(0xE28DD000,val);
+}
+
+/* 'is_jmp' is '1' if it is a jump */
+static void gcall_or_jmp(int is_jmp)
+{
+  int r;
+  if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+    uint32_t x;
+    /* constant case */
+    x=encbranch(ind,ind+vtop->c.i,0);
+    if(x) {
+      if (vtop->r & VT_SYM) {
+	/* relocation case */
+	greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24);
+      } else
+	put_elf_reloc(symtab_section, cur_text_section, ind, R_ARM_PC24, 0);
+      o(x|(is_jmp?0xE0000000:0xE1000000));
+    } else {
+      if(!is_jmp)
+	o(0xE28FE004); // add lr,pc,#4
+      o(0xE51FF004);   // ldr pc,[pc,#-4]
+      if (vtop->r & VT_SYM)
+	greloc(cur_text_section, vtop->sym, ind, R_ARM_ABS32);
+      o(vtop->c.i);
+    }
+  } else {
+    /* otherwise, indirect call */
+    r = gv(RC_INT);
+    if(!is_jmp)
+      o(0xE1A0E00F);       // mov lr,pc
+    o(0xE1A0F000|intr(r)); // mov pc,r
+  }
+}
+
+static int unalias_ldbl(int btype)
+{
+#if LDOUBLE_SIZE == 8
+    if (btype == VT_LDOUBLE)
+      btype = VT_DOUBLE;
+#endif
+    return btype;
+}
+
+/* Return whether a structure is an homogeneous float aggregate or not.
+   The answer is true if all the elements of the structure are of the same
+   primitive float type and there is less than 4 elements.
+
+   type: the type corresponding to the structure to be tested */
+static int is_hgen_float_aggr(CType *type)
+{
+  if ((type->t & VT_BTYPE) == VT_STRUCT) {
+    struct Sym *ref;
+    int btype, nb_fields = 0;
+
+    ref = type->ref->next;
+    btype = unalias_ldbl(ref->type.t & VT_BTYPE);
+    if (btype == VT_FLOAT || btype == VT_DOUBLE) {
+      for(; ref && btype == unalias_ldbl(ref->type.t & VT_BTYPE); ref = ref->next, nb_fields++);
+      return !ref && nb_fields <= 4;
+    }
+  }
+  return 0;
+}
+
+struct avail_regs {
+  signed char avail[3]; /* 3 holes max with only float and double alignments */
+  int first_hole; /* first available hole */
+  int last_hole; /* last available hole (none if equal to first_hole) */
+  int first_free_reg; /* next free register in the sequence, hole excluded */
+};
+
+#define AVAIL_REGS_INITIALIZER (struct avail_regs) { { 0, 0, 0}, 0, 0, 0 }
+
+/* Find suitable registers for a VFP Co-Processor Register Candidate (VFP CPRC
+   param) according to the rules described in the procedure call standard for
+   the ARM architecture (AAPCS). If found, the registers are assigned to this
+   VFP CPRC parameter. Registers are allocated in sequence unless a hole exists
+   and the parameter is a single float.
+
+   avregs: opaque structure to keep track of available VFP co-processor regs
+   align: alignment constraints for the param, as returned by type_size()
+   size: size of the parameter, as returned by type_size() */
+int assign_vfpreg(struct avail_regs *avregs, int align, int size)
+{
+  int first_reg = 0;
+
+  if (avregs->first_free_reg == -1)
+    return -1;
+  if (align >> 3) { /* double alignment */
+    first_reg = avregs->first_free_reg;
+    /* alignment constraint not respected so use next reg and record hole */
+    if (first_reg & 1)
+      avregs->avail[avregs->last_hole++] = first_reg++;
+  } else { /* no special alignment (float or array of float) */
+    /* if single float and a hole is available, assign the param to it */
+    if (size == 4 && avregs->first_hole != avregs->last_hole)
+      return avregs->avail[avregs->first_hole++];
+    else
+      first_reg = avregs->first_free_reg;
+  }
+  if (first_reg + size / 4 <= 16) {
+    avregs->first_free_reg = first_reg + size / 4;
+    return first_reg;
+  }
+  avregs->first_free_reg = -1;
+  return -1;
+}
+
+/* Returns whether all params need to be passed in core registers or not.
+   This is the case for function part of the runtime ABI. */
+int floats_in_core_regs(SValue *sval)
+{
+  if (!sval->sym)
+    return 0;
+
+  switch (sval->sym->v) {
+    case TOK___floatundisf:
+    case TOK___floatundidf:
+    case TOK___fixunssfdi:
+    case TOK___fixunsdfdi:
+#ifndef TCC_ARM_VFP
+    case TOK___fixunsxfdi:
+#endif
+    case TOK___floatdisf:
+    case TOK___floatdidf:
+    case TOK___fixsfdi:
+    case TOK___fixdfdi:
+      return 1;
+
+    default:
+      return 0;
+  }
+}
+
+/* Return the number of registers needed to return the struct, or 0 if
+   returning via struct pointer. */
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize) {
+#ifdef TCC_ARM_EABI
+    int size, align;
+    size = type_size(vt, &align);
+    if (float_abi == ARM_HARD_FLOAT && !variadic &&
+        (is_float(vt->t) || is_hgen_float_aggr(vt))) {
+        *ret_align = 8;
+	*regsize = 8;
+        ret->ref = NULL;
+        ret->t = VT_DOUBLE;
+        return (size + 7) >> 3;
+    } else if (size <= 4) {
+        *ret_align = 4;
+	*regsize = 4;
+        ret->ref = NULL;
+        ret->t = VT_INT;
+        return 1;
+    } else
+        return 0;
+#else
+    return 0;
+#endif
+}
+
+/* Parameters are classified according to how they are copied to their final
+   destination for the function call. Because the copying is performed class
+   after class according to the order in the union below, it is important that
+   some constraints about the order of the members of this union are respected:
+   - CORE_STRUCT_CLASS must come after STACK_CLASS;
+   - CORE_CLASS must come after STACK_CLASS, CORE_STRUCT_CLASS and
+     VFP_STRUCT_CLASS;
+   - VFP_STRUCT_CLASS must come after VFP_CLASS.
+   See the comment for the main loop in copy_params() for the reason. */
+enum reg_class {
+	STACK_CLASS = 0,
+	CORE_STRUCT_CLASS,
+	VFP_CLASS,
+	VFP_STRUCT_CLASS,
+	CORE_CLASS,
+	NB_CLASSES
+};
+
+struct param_plan {
+    int start; /* first reg or addr used depending on the class */
+    int end; /* last reg used or next free addr depending on the class */
+    SValue *sval; /* pointer to SValue on the value stack */
+    struct param_plan *prev; /*  previous element in this class */
+};
+
+struct plan {
+    struct param_plan *pplans; /* array of all the param plans */
+    struct param_plan *clsplans[NB_CLASSES]; /* per class lists of param plans */
+};
+
+#define add_param_plan(plan,pplan,class)                        \
+    do {                                                        \
+        pplan.prev = plan->clsplans[class];                     \
+        plan->pplans[plan ## _nb] = pplan;                      \
+        plan->clsplans[class] = &plan->pplans[plan ## _nb++];   \
+    } while(0)
+
+/* Assign parameters to registers and stack with alignment according to the
+   rules in the procedure call standard for the ARM architecture (AAPCS).
+   The overall assignment is recorded in an array of per parameter structures
+   called parameter plans. The parameter plans are also further organized in a
+   number of linked lists, one per class of parameter (see the comment for the
+   definition of union reg_class).
+
+   nb_args: number of parameters of the function for which a call is generated
+   float_abi: float ABI in use for this function call
+   plan: the structure where the overall assignment is recorded
+   todo: a bitmap that record which core registers hold a parameter
+
+   Returns the amount of stack space needed for parameter passing
+
+   Note: this function allocated an array in plan->pplans with tcc_malloc. It
+   is the responsibility of the caller to free this array once used (ie not
+   before copy_params). */
+static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo)
+{
+  int i, size, align;
+  int ncrn /* next core register number */, nsaa /* next stacked argument address*/;
+  int plan_nb = 0;
+  struct param_plan pplan;
+  struct avail_regs avregs = AVAIL_REGS_INITIALIZER;
+
+  ncrn = nsaa = 0;
+  *todo = 0;
+  plan->pplans = tcc_malloc(nb_args * sizeof(*plan->pplans));
+  memset(plan->clsplans, 0, sizeof(plan->clsplans));
+  for(i = nb_args; i-- ;) {
+    int j, start_vfpreg = 0;
+    CType type = vtop[-i].type;
+    type.t &= ~VT_ARRAY;
+    size = type_size(&type, &align);
+    size = (size + 3) & ~3;
+    align = (align + 3) & ~3;
+    switch(vtop[-i].type.t & VT_BTYPE) {
+      case VT_STRUCT:
+      case VT_FLOAT:
+      case VT_DOUBLE:
+      case VT_LDOUBLE:
+      if (float_abi == ARM_HARD_FLOAT) {
+        int is_hfa = 0; /* Homogeneous float aggregate */
+
+        if (is_float(vtop[-i].type.t)
+            || (is_hfa = is_hgen_float_aggr(&vtop[-i].type))) {
+          int end_vfpreg;
+
+          start_vfpreg = assign_vfpreg(&avregs, align, size);
+          end_vfpreg = start_vfpreg + ((size - 1) >> 2);
+          if (start_vfpreg >= 0) {
+            pplan = (struct param_plan) {start_vfpreg, end_vfpreg, &vtop[-i]};
+            if (is_hfa)
+              add_param_plan(plan, pplan, VFP_STRUCT_CLASS);
+            else
+              add_param_plan(plan, pplan, VFP_CLASS);
+            continue;
+          } else
+            break;
+        }
+      }
+      ncrn = (ncrn + (align-1)/4) & ~((align/4) - 1);
+      if (ncrn + size/4 <= 4 || (ncrn < 4 && start_vfpreg != -1)) {
+        /* The parameter is allocated both in core register and on stack. As
+	 * such, it can be of either class: it would either be the last of
+	 * CORE_STRUCT_CLASS or the first of STACK_CLASS. */
+        for (j = ncrn; j < 4 && j < ncrn + size / 4; j++)
+          *todo|=(1<<j);
+        pplan = (struct param_plan) {ncrn, j, &vtop[-i]};
+        add_param_plan(plan, pplan, CORE_STRUCT_CLASS);
+        ncrn += size/4;
+        if (ncrn > 4)
+          nsaa = (ncrn - 4) * 4;
+      } else {
+        ncrn = 4;
+        break;
+      }
+      continue;
+      default:
+      if (ncrn < 4) {
+        int is_long = (vtop[-i].type.t & VT_BTYPE) == VT_LLONG;
+
+        if (is_long) {
+          ncrn = (ncrn + 1) & -2;
+          if (ncrn == 4)
+            break;
+        }
+        pplan = (struct param_plan) {ncrn, ncrn, &vtop[-i]};
+        ncrn++;
+        if (is_long)
+          pplan.end = ncrn++;
+        add_param_plan(plan, pplan, CORE_CLASS);
+        continue;
+      }
+    }
+    nsaa = (nsaa + (align - 1)) & ~(align - 1);
+    pplan = (struct param_plan) {nsaa, nsaa + size, &vtop[-i]};
+    add_param_plan(plan, pplan, STACK_CLASS);
+    nsaa += size; /* size already rounded up before */
+  }
+  return nsaa;
+}
+
+#undef add_param_plan
+
+/* Copy parameters to their final destination (core reg, VFP reg or stack) for
+   function call.
+
+   nb_args: number of parameters the function take
+   plan: the overall assignment plan for parameters
+   todo: a bitmap indicating what core reg will hold a parameter
+
+   Returns the number of SValue added by this function on the value stack */
+static int copy_params(int nb_args, struct plan *plan, int todo)
+{
+  int size, align, r, i, nb_extra_sval = 0;
+  struct param_plan *pplan;
+  int pass = 0;
+
+   /* Several constraints require parameters to be copied in a specific order:
+      - structures are copied to the stack before being loaded in a reg;
+      - floats loaded to an odd numbered VFP reg are first copied to the
+        preceding even numbered VFP reg and then moved to the next VFP reg.
+
+      It is thus important that:
+      - structures assigned to core regs must be copied after parameters
+        assigned to the stack but before structures assigned to VFP regs because
+        a structure can lie partly in core registers and partly on the stack;
+      - parameters assigned to the stack and all structures be copied before
+        parameters assigned to a core reg since copying a parameter to the stack
+        require using a core reg;
+      - parameters assigned to VFP regs be copied before structures assigned to
+        VFP regs as the copy might use an even numbered VFP reg that already
+        holds part of a structure. */
+again:
+  for(i = 0; i < NB_CLASSES; i++) {
+    for(pplan = plan->clsplans[i]; pplan; pplan = pplan->prev) {
+
+      if (pass
+          && (i != CORE_CLASS || pplan->sval->r < VT_CONST))
+        continue;
+
+      vpushv(pplan->sval);
+      pplan->sval->r = pplan->sval->r2 = VT_CONST; /* disable entry */
+      switch(i) {
+        case STACK_CLASS:
+        case CORE_STRUCT_CLASS:
+        case VFP_STRUCT_CLASS:
+          if ((pplan->sval->type.t & VT_BTYPE) == VT_STRUCT) {
+            int padding = 0;
+            size = type_size(&pplan->sval->type, &align);
+            /* align to stack align size */
+            size = (size + 3) & ~3;
+            if (i == STACK_CLASS && pplan->prev)
+              padding = pplan->start - pplan->prev->end;
+            size += padding; /* Add padding if any */
+            /* allocate the necessary size on stack */
+            gadd_sp(-size);
+            /* generate structure store */
+            r = get_reg(RC_INT);
+            o(0xE28D0000|(intr(r)<<12)|padding); /* add r, sp, padding */
+            vset(&vtop->type, r | VT_LVAL, 0);
+            vswap();
+            vstore(); /* memcpy to current sp + potential padding */
+
+            /* Homogeneous float aggregate are loaded to VFP registers
+               immediately since there is no way of loading data in multiple
+               non consecutive VFP registers as what is done for other
+               structures (see the use of todo). */
+            if (i == VFP_STRUCT_CLASS) {
+              int first = pplan->start, nb = pplan->end - first + 1;
+              /* vpop.32 {pplan->start, ..., pplan->end} */
+              o(0xECBD0A00|(first&1)<<22|(first>>1)<<12|nb);
+              /* No need to write the register used to a SValue since VFP regs
+                 cannot be used for gcall_or_jmp */
+            }
+          } else {
+            if (is_float(pplan->sval->type.t)) {
+#ifdef TCC_ARM_VFP
+              r = vfpr(gv(RC_FLOAT)) << 12;
+              if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)
+                size = 4;
+              else {
+                size = 8;
+                r |= 0x101; /* vpush.32 -> vpush.64 */
+              }
+              o(0xED2D0A01 + r); /* vpush */
+#else
+              r = fpr(gv(RC_FLOAT)) << 12;
+              if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)
+                size = 4;
+              else if ((pplan->sval->type.t & VT_BTYPE) == VT_DOUBLE)
+                size = 8;
+              else
+                size = LDOUBLE_SIZE;
+
+              if (size == 12)
+                r |= 0x400000;
+              else if(size == 8)
+                r|=0x8000;
+
+              o(0xED2D0100|r|(size>>2)); /* some kind of vpush for FPA */
+#endif
+            } else {
+              /* simple type (currently always same size) */
+              /* XXX: implicit cast ? */
+              size=4;
+              if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {
+                lexpand_nr();
+                size = 8;
+                r = gv(RC_INT);
+                o(0xE52D0004|(intr(r)<<12)); /* push r */
+                vtop--;
+              }
+              r = gv(RC_INT);
+              o(0xE52D0004|(intr(r)<<12)); /* push r */
+            }
+            if (i == STACK_CLASS && pplan->prev)
+              gadd_sp(pplan->prev->end - pplan->start); /* Add padding if any */
+          }
+          break;
+
+        case VFP_CLASS:
+          gv(regmask(TREG_F0 + (pplan->start >> 1)));
+          if (pplan->start & 1) { /* Must be in upper part of double register */
+            o(0xEEF00A40|((pplan->start>>1)<<12)|(pplan->start>>1)); /* vmov.f32 s(n+1), sn */
+            vtop->r = VT_CONST; /* avoid being saved on stack by gv for next float */
+          }
+          break;
+
+        case CORE_CLASS:
+          if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {
+            lexpand_nr();
+            gv(regmask(pplan->end));
+            pplan->sval->r2 = vtop->r;
+            vtop--;
+          }
+          gv(regmask(pplan->start));
+          /* Mark register as used so that gcall_or_jmp use another one
+             (regs >=4 are free as never used to pass parameters) */
+          pplan->sval->r = vtop->r;
+          break;
+      }
+      vtop--;
+    }
+  }
+
+  /* second pass to restore registers that were saved on stack by accident.
+     Maybe redundant after the "lvalue_save" patch in tccgen.c:gv() */
+  if (++pass < 2)
+    goto again;
+
+  /* Manually free remaining registers since next parameters are loaded
+   * manually, without the help of gv(int). */
+  save_regs(nb_args);
+
+  if(todo) {
+    o(0xE8BD0000|todo); /* pop {todo} */
+    for(pplan = plan->clsplans[CORE_STRUCT_CLASS]; pplan; pplan = pplan->prev) {
+      int r;
+      pplan->sval->r = pplan->start;
+      /* An SValue can only pin 2 registers at best (r and r2) but a structure
+         can occupy more than 2 registers. Thus, we need to push on the value
+         stack some fake parameter to have on SValue for each registers used
+         by a structure (r2 is not used). */
+      for (r = pplan->start + 1; r <= pplan->end; r++) {
+        if (todo & (1 << r)) {
+          nb_extra_sval++;
+          vpushi(0);
+          vtop->r = r;
+        }
+      }
+    }
+  }
+  return nb_extra_sval;
+}
+
+/* Generate function call. The function address is pushed first, then
+   all the parameters in call order. This functions pops all the
+   parameters and the function address. */
+void gfunc_call(int nb_args)
+{
+  int r, args_size;
+  int def_float_abi = float_abi;
+  int todo;
+  struct plan plan;
+
+#ifdef TCC_ARM_EABI
+  int variadic;
+
+  if (float_abi == ARM_HARD_FLOAT) {
+    variadic = (vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS);
+    if (variadic || floats_in_core_regs(&vtop[-nb_args]))
+      float_abi = ARM_SOFTFP_FLOAT;
+  }
+#endif
+  /* cannot let cpu flags if other instruction are generated. Also avoid leaving
+     VT_JMP anywhere except on the top of the stack because it would complicate
+     the code generator. */
+  r = vtop->r & VT_VALMASK;
+  if (r == VT_CMP || (r & ~1) == VT_JMP)
+    gv(RC_INT);
+
+  args_size = assign_regs(nb_args, float_abi, &plan, &todo);
+
+#ifdef TCC_ARM_EABI
+  if (args_size & 7) { /* Stack must be 8 byte aligned at fct call for EABI */
+    args_size = (args_size + 7) & ~7;
+    o(0xE24DD004); /* sub sp, sp, #4 */
+  }
+#endif
+
+  nb_args += copy_params(nb_args, &plan, todo);
+  tcc_free(plan.pplans);
+
+  /* Move fct SValue on top as required by gcall_or_jmp */
+  vrotb(nb_args + 1);
+  gcall_or_jmp(0);
+  if (args_size)
+      gadd_sp(args_size); /* pop all parameters passed on the stack */
+#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
+  if(float_abi == ARM_SOFTFP_FLOAT && is_float(vtop->type.ref->type.t)) {
+    if((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {
+      o(0xEE000A10); /*vmov s0, r0 */
+    } else {
+      o(0xEE000B10); /* vmov.32 d0[0], r0 */
+      o(0xEE201B10); /* vmov.32 d0[1], r1 */
+    }
+  }
+#endif
+  vtop -= nb_args + 1; /* Pop all params and fct address from value stack */
+  leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */
+  float_abi = def_float_abi;
+}
+
+/* generate function prolog of type 't' */
+void gfunc_prolog(CType *func_type)
+{
+  Sym *sym,*sym2;
+  int n, nf, size, align, rs, struct_ret = 0;
+  int addr, pn, sn; /* pn=core, sn=stack */
+  CType ret_type;
+
+#ifdef TCC_ARM_EABI
+  struct avail_regs avregs = AVAIL_REGS_INITIALIZER;
+#endif
+
+  sym = func_type->ref;
+  func_vt = sym->type;
+  func_var = (func_type->ref->f.func_type == FUNC_ELLIPSIS);
+
+  n = nf = 0;
+  if ((func_vt.t & VT_BTYPE) == VT_STRUCT &&
+      !gfunc_sret(&func_vt, func_var, &ret_type, &align, &rs))
+  {
+    n++;
+    struct_ret = 1;
+    func_vc = 12; /* Offset from fp of the place to store the result */
+  }
+  for(sym2 = sym->next; sym2 && (n < 4 || nf < 16); sym2 = sym2->next) {
+    size = type_size(&sym2->type, &align);
+#ifdef TCC_ARM_EABI
+    if (float_abi == ARM_HARD_FLOAT && !func_var &&
+        (is_float(sym2->type.t) || is_hgen_float_aggr(&sym2->type))) {
+      int tmpnf = assign_vfpreg(&avregs, align, size);
+      tmpnf += (size + 3) / 4;
+      nf = (tmpnf > nf) ? tmpnf : nf;
+    } else
+#endif
+    if (n < 4)
+      n += (size + 3) / 4;
+  }
+  o(0xE1A0C00D); /* mov ip,sp */
+  if (func_var)
+    n=4;
+  if (n) {
+    if(n>4)
+      n=4;
+#ifdef TCC_ARM_EABI
+    n=(n+1)&-2;
+#endif
+    o(0xE92D0000|((1<<n)-1)); /* save r0-r4 on stack if needed */
+  }
+  if (nf) {
+    if (nf>16)
+      nf=16;
+    nf=(nf+1)&-2; /* nf => HARDFLOAT => EABI */
+    o(0xED2D0A00|nf); /* save s0-s15 on stack if needed */
+  }
+  o(0xE92D5800); /* save fp, ip, lr */
+  o(0xE1A0B00D); /* mov fp, sp */
+  func_sub_sp_offset = ind;
+  o(0xE1A00000); /* nop, leave space for stack adjustment in epilog */
+
+#ifdef TCC_ARM_EABI
+  if (float_abi == ARM_HARD_FLOAT) {
+    func_vc += nf * 4;
+    avregs = AVAIL_REGS_INITIALIZER;
+  }
+#endif
+  pn = struct_ret, sn = 0;
+  while ((sym = sym->next)) {
+    CType *type;
+    type = &sym->type;
+    size = type_size(type, &align);
+    size = (size + 3) >> 2;
+    align = (align + 3) & ~3;
+#ifdef TCC_ARM_EABI
+    if (float_abi == ARM_HARD_FLOAT && !func_var && (is_float(sym->type.t)
+        || is_hgen_float_aggr(&sym->type))) {
+      int fpn = assign_vfpreg(&avregs, align, size << 2);
+      if (fpn >= 0)
+        addr = fpn * 4;
+      else
+        goto from_stack;
+    } else
+#endif
+    if (pn < 4) {
+#ifdef TCC_ARM_EABI
+        pn = (pn + (align-1)/4) & -(align/4);
+#endif
+      addr = (nf + pn) * 4;
+      pn += size;
+      if (!sn && pn > 4)
+        sn = (pn - 4);
+    } else {
+#ifdef TCC_ARM_EABI
+from_stack:
+        sn = (sn + (align-1)/4) & -(align/4);
+#endif
+      addr = (n + nf + sn) * 4;
+      sn += size;
+    }
+    sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t),
+             addr + 12);
+  }
+  last_itod_magic=0;
+  leaffunc = 1;
+  loc = 0;
+}
+
+/* generate function epilog */
+void gfunc_epilog(void)
+{
+  uint32_t x;
+  int diff;
+  /* Copy float return value to core register if base standard is used and
+     float computation is made with VFP */
+#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
+  if ((float_abi == ARM_SOFTFP_FLOAT || func_var) && is_float(func_vt.t)) {
+    if((func_vt.t & VT_BTYPE) == VT_FLOAT)
+      o(0xEE100A10); /* fmrs r0, s0 */
+    else {
+      o(0xEE100B10); /* fmrdl r0, d0 */
+      o(0xEE301B10); /* fmrdh r1, d0 */
+    }
+  }
+#endif
+  o(0xE89BA800); /* restore fp, sp, pc */
+  diff = (-loc + 3) & -4;
+#ifdef TCC_ARM_EABI
+  if(!leaffunc)
+    diff = ((diff + 11) & -8) - 4;
+#endif
+  if(diff > 0) {
+    x=stuff_const(0xE24BD000, diff); /* sub sp,fp,# */
+    if(x)
+      *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = x;
+    else {
+      int addr;
+      addr=ind;
+      o(0xE59FC004); /* ldr ip,[pc+4] */
+      o(0xE04BD00C); /* sub sp,fp,ip  */
+      o(0xE1A0F00E); /* mov pc,lr */
+      o(diff);
+      *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = 0xE1000000|encbranch(func_sub_sp_offset,addr,1);
+    }
+  }
+}
+
+/* generate a jump to a label */
+int gjmp(int t)
+{
+  int r;
+  if (nocode_wanted)
+    return t;
+  r=ind;
+  o(0xE0000000|encbranch(r,t,1));
+  return r;
+}
+
+/* generate a jump to a fixed address */
+void gjmp_addr(int a)
+{
+  gjmp(a);
+}
+
+/* generate a test. set 'inv' to invert test. Stack entry is popped */
+int gtst(int inv, int t)
+{
+  int v, r;
+  uint32_t op;
+
+  v = vtop->r & VT_VALMASK;
+  r=ind;
+
+  if (nocode_wanted) {
+    ;
+  } else if (v == VT_CMP) {
+    op=mapcc(inv?negcc(vtop->c.i):vtop->c.i);
+    op|=encbranch(r,t,1);
+    o(op);
+    t=r;
+  } else if (v == VT_JMP || v == VT_JMPI) {
+    if ((v & 1) == inv) {
+      if(!vtop->c.i)
+	vtop->c.i=t;
+      else {
+	uint32_t *x;
+	int p,lp;
+	if(t) {
+          p = vtop->c.i;
+          do {
+	    p = decbranch(lp=p);
+          } while(p);
+	  x = (uint32_t *)(cur_text_section->data + lp);
+	  *x &= 0xff000000;
+	  *x |= encbranch(lp,t,1);
+	}
+	t = vtop->c.i;
+      }
+    } else {
+      t = gjmp(t);
+      gsym(vtop->c.i);
+    }
+  }
+  vtop--;
+  return t;
+}
+
+/* generate an integer binary operation */
+void gen_opi(int op)
+{
+  int c, func = 0;
+  uint32_t opc = 0, r, fr;
+  unsigned short retreg = REG_IRET;
+
+  c=0;
+  switch(op) {
+    case '+':
+      opc = 0x8;
+      c=1;
+      break;
+    case TOK_ADDC1: /* add with carry generation */
+      opc = 0x9;
+      c=1;
+      break;
+    case '-':
+      opc = 0x4;
+      c=1;
+      break;
+    case TOK_SUBC1: /* sub with carry generation */
+      opc = 0x5;
+      c=1;
+      break;
+    case TOK_ADDC2: /* add with carry use */
+      opc = 0xA;
+      c=1;
+      break;
+    case TOK_SUBC2: /* sub with carry use */
+      opc = 0xC;
+      c=1;
+      break;
+    case '&':
+      opc = 0x0;
+      c=1;
+      break;
+    case '^':
+      opc = 0x2;
+      c=1;
+      break;
+    case '|':
+      opc = 0x18;
+      c=1;
+      break;
+    case '*':
+      gv2(RC_INT, RC_INT);
+      r = vtop[-1].r;
+      fr = vtop[0].r;
+      vtop--;
+      o(0xE0000090|(intr(r)<<16)|(intr(r)<<8)|intr(fr));
+      return;
+    case TOK_SHL:
+      opc = 0;
+      c=2;
+      break;
+    case TOK_SHR:
+      opc = 1;
+      c=2;
+      break;
+    case TOK_SAR:
+      opc = 2;
+      c=2;
+      break;
+    case '/':
+    case TOK_PDIV:
+      func=TOK___divsi3;
+      c=3;
+      break;
+    case TOK_UDIV:
+      func=TOK___udivsi3;
+      c=3;
+      break;
+    case '%':
+#ifdef TCC_ARM_EABI
+      func=TOK___aeabi_idivmod;
+      retreg=REG_LRET;
+#else
+      func=TOK___modsi3;
+#endif
+      c=3;
+      break;
+    case TOK_UMOD:
+#ifdef TCC_ARM_EABI
+      func=TOK___aeabi_uidivmod;
+      retreg=REG_LRET;
+#else
+      func=TOK___umodsi3;
+#endif
+      c=3;
+      break;
+    case TOK_UMULL:
+      gv2(RC_INT, RC_INT);
+      r=intr(vtop[-1].r2=get_reg(RC_INT));
+      c=vtop[-1].r;
+      vtop[-1].r=get_reg_ex(RC_INT,regmask(c));
+      vtop--;
+      o(0xE0800090|(r<<16)|(intr(vtop->r)<<12)|(intr(c)<<8)|intr(vtop[1].r));
+      return;
+    default:
+      opc = 0x15;
+      c=1;
+      break;
+  }
+  switch(c) {
+    case 1:
+      if((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+	if(opc == 4 || opc == 5 || opc == 0xc) {
+	  vswap();
+	  opc|=2; // sub -> rsb
+	}
+      }
+      if ((vtop->r & VT_VALMASK) == VT_CMP ||
+          (vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
+        gv(RC_INT);
+      vswap();
+      c=intr(gv(RC_INT));
+      vswap();
+      opc=0xE0000000|(opc<<20)|(c<<16);
+      if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+	uint32_t x;
+	x=stuff_const(opc|0x2000000,vtop->c.i);
+	if(x) {
+	  r=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r)));
+	  o(x|(r<<12));
+	  goto done;
+	}
+      }
+      fr=intr(gv(RC_INT));
+      r=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r)));
+      o(opc|(r<<12)|fr);
+done:
+      vtop--;
+      if (op >= TOK_ULT && op <= TOK_GT) {
+        vtop->r = VT_CMP;
+        vtop->c.i = op;
+      }
+      break;
+    case 2:
+      opc=0xE1A00000|(opc<<5);
+      if ((vtop->r & VT_VALMASK) == VT_CMP ||
+          (vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
+        gv(RC_INT);
+      vswap();
+      r=intr(gv(RC_INT));
+      vswap();
+      opc|=r;
+      if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+	fr=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r)));
+	c = vtop->c.i & 0x1f;
+	o(opc|(c<<7)|(fr<<12));
+      } else {
+        fr=intr(gv(RC_INT));
+	c=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r)));
+	o(opc|(c<<12)|(fr<<8)|0x10);
+      }
+      vtop--;
+      break;
+    case 3:
+      vpush_global_sym(&func_old_type, func);
+      vrott(3);
+      gfunc_call(2);
+      vpushi(0);
+      vtop->r = retreg;
+      break;
+    default:
+      tcc_error("gen_opi %i unimplemented!",op);
+  }
+}
+
+#ifdef TCC_ARM_VFP
+static int is_zero(int i)
+{
+  if((vtop[i].r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
+    return 0;
+  if (vtop[i].type.t == VT_FLOAT)
+    return (vtop[i].c.f == 0.f);
+  else if (vtop[i].type.t == VT_DOUBLE)
+    return (vtop[i].c.d == 0.0);
+  return (vtop[i].c.ld == 0.l);
+}
+
+/* generate a floating point operation 'v = t1 op t2' instruction. The
+ *    two operands are guaranteed to have the same floating point type */
+void gen_opf(int op)
+{
+  uint32_t x;
+  int fneg=0,r;
+  x=0xEE000A00|T2CPR(vtop->type.t);
+  switch(op) {
+    case '+':
+      if(is_zero(-1))
+        vswap();
+      if(is_zero(0)) {
+        vtop--;
+        return;
+      }
+      x|=0x300000;
+      break;
+    case '-':
+      x|=0x300040;
+      if(is_zero(0)) {
+        vtop--;
+        return;
+      }
+      if(is_zero(-1)) {
+        x|=0x810000; /* fsubX -> fnegX */
+        vswap();
+        vtop--;
+        fneg=1;
+      }
+      break;
+    case '*':
+      x|=0x200000;
+      break;
+    case '/':
+      x|=0x800000;
+      break;
+    default:
+      if(op < TOK_ULT || op > TOK_GT) {
+        tcc_error("unknown fp op %x!",op);
+        return;
+      }
+      if(is_zero(-1)) {
+        vswap();
+        switch(op) {
+          case TOK_LT: op=TOK_GT; break;
+          case TOK_GE: op=TOK_ULE; break;
+          case TOK_LE: op=TOK_GE; break;
+          case TOK_GT: op=TOK_ULT; break;
+        }
+      }
+      x|=0xB40040; /* fcmpX */
+      if(op!=TOK_EQ && op!=TOK_NE)
+        x|=0x80; /* fcmpX -> fcmpeX */
+      if(is_zero(0)) {
+        vtop--;
+        o(x|0x10000|(vfpr(gv(RC_FLOAT))<<12)); /* fcmp(e)X -> fcmp(e)zX */
+      } else {
+        x|=vfpr(gv(RC_FLOAT));
+        vswap();
+        o(x|(vfpr(gv(RC_FLOAT))<<12));
+        vtop--;
+      }
+      o(0xEEF1FA10); /* fmstat */
+
+      switch(op) {
+        case TOK_LE: op=TOK_ULE; break;
+        case TOK_LT: op=TOK_ULT; break;
+        case TOK_UGE: op=TOK_GE; break;
+        case TOK_UGT: op=TOK_GT; break;
+      }
+
+      vtop->r = VT_CMP;
+      vtop->c.i = op;
+      return;
+  }
+  r=gv(RC_FLOAT);
+  x|=vfpr(r);
+  r=regmask(r);
+  if(!fneg) {
+    int r2;
+    vswap();
+    r2=gv(RC_FLOAT);
+    x|=vfpr(r2)<<16;
+    r|=regmask(r2);
+  }
+  vtop->r=get_reg_ex(RC_FLOAT,r);
+  if(!fneg)
+    vtop--;
+  o(x|(vfpr(vtop->r)<<12));
+}
+
+#else
+static uint32_t is_fconst()
+{
+  long double f;
+  uint32_t r;
+  if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
+    return 0;
+  if (vtop->type.t == VT_FLOAT)
+    f = vtop->c.f;
+  else if (vtop->type.t == VT_DOUBLE)
+    f = vtop->c.d;
+  else
+    f = vtop->c.ld;
+  if(!ieee_finite(f))
+    return 0;
+  r=0x8;
+  if(f<0.0) {
+    r=0x18;
+    f=-f;
+  }
+  if(f==0.0)
+    return r;
+  if(f==1.0)
+    return r|1;
+  if(f==2.0)
+    return r|2;
+  if(f==3.0)
+    return r|3;
+  if(f==4.0)
+    return r|4;
+  if(f==5.0)
+    return r|5;
+  if(f==0.5)
+    return r|6;
+  if(f==10.0)
+    return r|7;
+  return 0;
+}
+
+/* generate a floating point operation 'v = t1 op t2' instruction. The
+   two operands are guaranteed to have the same floating point type */
+void gen_opf(int op)
+{
+  uint32_t x, r, r2, c1, c2;
+  //fputs("gen_opf\n",stderr);
+  vswap();
+  c1 = is_fconst();
+  vswap();
+  c2 = is_fconst();
+  x=0xEE000100;
+#if LDOUBLE_SIZE == 8
+  if ((vtop->type.t & VT_BTYPE) != VT_FLOAT)
+    x|=0x80;
+#else
+  if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
+    x|=0x80;
+  else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE)
+    x|=0x80000;
+#endif
+  switch(op)
+  {
+    case '+':
+      if(!c2) {
+	vswap();
+	c2=c1;
+      }
+      vswap();
+      r=fpr(gv(RC_FLOAT));
+      vswap();
+      if(c2) {
+	if(c2>0xf)
+	  x|=0x200000; // suf
+	r2=c2&0xf;
+      } else {
+	r2=fpr(gv(RC_FLOAT));
+      }
+      break;
+    case '-':
+      if(c2) {
+	if(c2<=0xf)
+	  x|=0x200000; // suf
+	r2=c2&0xf;
+	vswap();
+	r=fpr(gv(RC_FLOAT));
+	vswap();
+      } else if(c1 && c1<=0xf) {
+	x|=0x300000; // rsf
+	r2=c1;
+	r=fpr(gv(RC_FLOAT));
+	vswap();
+      } else {
+	x|=0x200000; // suf
+	vswap();
+	r=fpr(gv(RC_FLOAT));
+	vswap();
+	r2=fpr(gv(RC_FLOAT));
+      }
+      break;
+    case '*':
+      if(!c2 || c2>0xf) {
+	vswap();
+	c2=c1;
+      }
+      vswap();
+      r=fpr(gv(RC_FLOAT));
+      vswap();
+      if(c2 && c2<=0xf)
+	r2=c2;
+      else
+	r2=fpr(gv(RC_FLOAT));
+      x|=0x100000; // muf
+      break;
+    case '/':
+      if(c2 && c2<=0xf) {
+	x|=0x400000; // dvf
+	r2=c2;
+	vswap();
+	r=fpr(gv(RC_FLOAT));
+	vswap();
+      } else if(c1 && c1<=0xf) {
+	x|=0x500000; // rdf
+	r2=c1;
+	r=fpr(gv(RC_FLOAT));
+	vswap();
+      } else {
+	x|=0x400000; // dvf
+	vswap();
+	r=fpr(gv(RC_FLOAT));
+	vswap();
+	r2=fpr(gv(RC_FLOAT));
+      }
+      break;
+    default:
+      if(op >= TOK_ULT && op <= TOK_GT) {
+	x|=0xd0f110; // cmfe
+/* bug (intention?) in Linux FPU emulator
+   doesn't set carry if equal */
+	switch(op) {
+	  case TOK_ULT:
+	  case TOK_UGE:
+	  case TOK_ULE:
+	  case TOK_UGT:
+            tcc_error("unsigned comparison on floats?");
+	    break;
+	  case TOK_LT:
+            op=TOK_Nset;
+	    break;
+	  case TOK_LE:
+            op=TOK_ULE; /* correct in unordered case only if AC bit in FPSR set */
+	    break;
+	  case TOK_EQ:
+	  case TOK_NE:
+	    x&=~0x400000; // cmfe -> cmf
+	    break;
+	}
+	if(c1 && !c2) {
+	  c2=c1;
+	  vswap();
+	  switch(op) {
+            case TOK_Nset:
+              op=TOK_GT;
+	      break;
+            case TOK_GE:
+	      op=TOK_ULE;
+	      break;
+	    case TOK_ULE:
+              op=TOK_GE;
+	      break;
+            case TOK_GT:
+              op=TOK_Nset;
+	      break;
+	  }
+	}
+	vswap();
+	r=fpr(gv(RC_FLOAT));
+	vswap();
+	if(c2) {
+	  if(c2>0xf)
+	    x|=0x200000;
+	  r2=c2&0xf;
+	} else {
+	  r2=fpr(gv(RC_FLOAT));
+	}
+	vtop[-1].r = VT_CMP;
+	vtop[-1].c.i = op;
+      } else {
+        tcc_error("unknown fp op %x!",op);
+	return;
+      }
+  }
+  if(vtop[-1].r == VT_CMP)
+    c1=15;
+  else {
+    c1=vtop->r;
+    if(r2&0x8)
+      c1=vtop[-1].r;
+    vtop[-1].r=get_reg_ex(RC_FLOAT,two2mask(vtop[-1].r,c1));
+    c1=fpr(vtop[-1].r);
+  }
+  vtop--;
+  o(x|(r<<16)|(c1<<12)|r2);
+}
+#endif
+
+/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
+   and 'long long' cases. */
+ST_FUNC void gen_cvt_itof1(int t)
+{
+  uint32_t r, r2;
+  int bt;
+  bt=vtop->type.t & VT_BTYPE;
+  if(bt == VT_INT || bt == VT_SHORT || bt == VT_BYTE) {
+#ifndef TCC_ARM_VFP
+    uint32_t dsize = 0;
+#endif
+    r=intr(gv(RC_INT));
+#ifdef TCC_ARM_VFP
+    r2=vfpr(vtop->r=get_reg(RC_FLOAT));
+    o(0xEE000A10|(r<<12)|(r2<<16)); /* fmsr */
+    r2|=r2<<12;
+    if(!(vtop->type.t & VT_UNSIGNED))
+      r2|=0x80;                /* fuitoX -> fsituX */
+    o(0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/
+#else
+    r2=fpr(vtop->r=get_reg(RC_FLOAT));
+    if((t & VT_BTYPE) != VT_FLOAT)
+      dsize=0x80;    /* flts -> fltd */
+    o(0xEE000110|dsize|(r2<<16)|(r<<12)); /* flts */
+    if((vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) {
+      uint32_t off = 0;
+      o(0xE3500000|(r<<12));        /* cmp */
+      r=fpr(get_reg(RC_FLOAT));
+      if(last_itod_magic) {
+	off=ind+8-last_itod_magic;
+	off/=4;
+	if(off>255)
+	  off=0;
+      }
+      o(0xBD1F0100|(r<<12)|off);    /* ldflts */
+      if(!off) {
+        o(0xEA000000);              /* b */
+        last_itod_magic=ind;
+        o(0x4F800000);              /* 4294967296.0f */
+      }
+      o(0xBE000100|dsize|(r2<<16)|(r2<<12)|r); /* adflt */
+    }
+#endif
+    return;
+  } else if(bt == VT_LLONG) {
+    int func;
+    CType *func_type = 0;
+    if((t & VT_BTYPE) == VT_FLOAT) {
+      func_type = &func_float_type;
+      if(vtop->type.t & VT_UNSIGNED)
+        func=TOK___floatundisf;
+      else
+        func=TOK___floatdisf;
+#if LDOUBLE_SIZE != 8
+    } else if((t & VT_BTYPE) == VT_LDOUBLE) {
+      func_type = &func_ldouble_type;
+      if(vtop->type.t & VT_UNSIGNED)
+        func=TOK___floatundixf;
+      else
+        func=TOK___floatdixf;
+    } else if((t & VT_BTYPE) == VT_DOUBLE) {
+#else
+    } else if((t & VT_BTYPE) == VT_DOUBLE || (t & VT_BTYPE) == VT_LDOUBLE) {
+#endif
+      func_type = &func_double_type;
+      if(vtop->type.t & VT_UNSIGNED)
+        func=TOK___floatundidf;
+      else
+        func=TOK___floatdidf;
+    }
+    if(func_type) {
+      vpush_global_sym(func_type, func);
+      vswap();
+      gfunc_call(1);
+      vpushi(0);
+      vtop->r=TREG_F0;
+      return;
+    }
+  }
+  tcc_error("unimplemented gen_cvt_itof %x!",vtop->type.t);
+}
+
+/* convert fp to int 't' type */
+void gen_cvt_ftoi(int t)
+{
+  uint32_t r, r2;
+  int u, func = 0;
+  u=t&VT_UNSIGNED;
+  t&=VT_BTYPE;
+  r2=vtop->type.t & VT_BTYPE;
+  if(t==VT_INT) {
+#ifdef TCC_ARM_VFP
+    r=vfpr(gv(RC_FLOAT));
+    u=u?0:0x10000;
+    o(0xEEBC0AC0|(r<<12)|r|T2CPR(r2)|u); /* ftoXizY */
+    r2=intr(vtop->r=get_reg(RC_INT));
+    o(0xEE100A10|(r<<16)|(r2<<12));
+    return;
+#else
+    if(u) {
+      if(r2 == VT_FLOAT)
+        func=TOK___fixunssfsi;
+#if LDOUBLE_SIZE != 8
+      else if(r2 == VT_LDOUBLE)
+	func=TOK___fixunsxfsi;
+      else if(r2 == VT_DOUBLE)
+#else
+      else if(r2 == VT_LDOUBLE || r2 == VT_DOUBLE)
+#endif
+	func=TOK___fixunsdfsi;
+    } else {
+      r=fpr(gv(RC_FLOAT));
+      r2=intr(vtop->r=get_reg(RC_INT));
+      o(0xEE100170|(r2<<12)|r);
+      return;
+    }
+#endif
+  } else if(t == VT_LLONG) { // unsigned handled in gen_cvt_ftoi1
+    if(r2 == VT_FLOAT)
+      func=TOK___fixsfdi;
+#if LDOUBLE_SIZE != 8
+    else if(r2 == VT_LDOUBLE)
+      func=TOK___fixxfdi;
+    else if(r2 == VT_DOUBLE)
+#else
+    else if(r2 == VT_LDOUBLE || r2 == VT_DOUBLE)
+#endif
+      func=TOK___fixdfdi;
+  }
+  if(func) {
+    vpush_global_sym(&func_old_type, func);
+    vswap();
+    gfunc_call(1);
+    vpushi(0);
+    if(t == VT_LLONG)
+      vtop->r2 = REG_LRET;
+    vtop->r = REG_IRET;
+    return;
+  }
+  tcc_error("unimplemented gen_cvt_ftoi!");
+}
+
+/* convert from one floating point type to another */
+void gen_cvt_ftof(int t)
+{
+#ifdef TCC_ARM_VFP
+  if(((vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) {
+    uint32_t r = vfpr(gv(RC_FLOAT));
+    o(0xEEB70AC0|(r<<12)|r|T2CPR(vtop->type.t));
+  }
+#else
+  /* all we have to do on i386 and FPA ARM is to put the float in a register */
+  gv(RC_FLOAT);
+#endif
+}
+
+/* computed goto support */
+void ggoto(void)
+{
+  gcall_or_jmp(1);
+  vtop--;
+}
+
+/* Save the stack pointer onto the stack and return the location of its address */
+ST_FUNC void gen_vla_sp_save(int addr) {
+    SValue v;
+    v.type.t = VT_PTR;
+    v.r = VT_LOCAL | VT_LVAL;
+    v.c.i = addr;
+    store(TREG_SP, &v);
+}
+
+/* Restore the SP from a location on the stack */
+ST_FUNC void gen_vla_sp_restore(int addr) {
+    SValue v;
+    v.type.t = VT_PTR;
+    v.r = VT_LOCAL | VT_LVAL;
+    v.c.i = addr;
+    load(TREG_SP, &v);
+}
+
+/* Subtract from the stack pointer, and push the resulting value onto the stack */
+ST_FUNC void gen_vla_alloc(CType *type, int align) {
+    int r = intr(gv(RC_INT));
+    o(0xE04D0000|(r<<12)|r); /* sub r, sp, r */
+#ifdef TCC_ARM_EABI
+    if (align < 8)
+        align = 8;
+#else
+    if (align < 4)
+        align = 4;
+#endif
+    if (align & (align - 1))
+        tcc_error("alignment is not a power of 2: %i", align);
+    o(stuff_const(0xE3C0D000|(r<<16), align - 1)); /* bic sp, r, #align-1 */
+    vpop();
+}
+
+/* end of ARM code generator */
+/*************************************************************/
+#endif
+/*************************************************************/
Index: EcnlProtoTool/trunk/tcc-0.9.27/arm-link.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/arm-link.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/arm-link.c	(revision 331)
@@ -0,0 +1,398 @@
+#ifdef TARGET_DEFS_ONLY
+
+#define EM_TCC_TARGET EM_ARM
+
+/* relocation type for 32 bit data relocation */
+#define R_DATA_32   R_ARM_ABS32
+#define R_DATA_PTR  R_ARM_ABS32
+#define R_JMP_SLOT  R_ARM_JUMP_SLOT
+#define R_GLOB_DAT  R_ARM_GLOB_DAT
+#define R_COPY      R_ARM_COPY
+#define R_RELATIVE  R_ARM_RELATIVE
+
+#define R_NUM       R_ARM_NUM
+
+#define ELF_START_ADDR 0x00008000
+#define ELF_PAGE_SIZE  0x1000
+
+#define PCRELATIVE_DLLPLT 1
+#define RELOCATE_DLLPLT 0
+
+enum float_abi {
+    ARM_SOFTFP_FLOAT,
+    ARM_HARD_FLOAT,
+};
+
+#else /* !TARGET_DEFS_ONLY */
+
+#include "tcc.h"
+
+/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
+   relocations, returns -1. */
+int code_reloc (int reloc_type)
+{
+    switch (reloc_type) {
+	case R_ARM_MOVT_ABS:
+	case R_ARM_MOVW_ABS_NC:
+	case R_ARM_THM_MOVT_ABS:
+	case R_ARM_THM_MOVW_ABS_NC:
+	case R_ARM_ABS32:
+	case R_ARM_REL32:
+	case R_ARM_GOTPC:
+	case R_ARM_GOTOFF:
+	case R_ARM_GOT32:
+	case R_ARM_COPY:
+	case R_ARM_GLOB_DAT:
+	case R_ARM_NONE:
+            return 0;
+
+        case R_ARM_PC24:
+        case R_ARM_CALL:
+	case R_ARM_JUMP24:
+	case R_ARM_PLT32:
+	case R_ARM_THM_PC22:
+	case R_ARM_THM_JUMP24:
+	case R_ARM_PREL31:
+	case R_ARM_V4BX:
+	case R_ARM_JUMP_SLOT:
+            return 1;
+    }
+
+    tcc_error ("Unknown relocation type: %d", reloc_type);
+    return -1;
+}
+
+/* Returns an enumerator to describe whether and when the relocation needs a
+   GOT and/or PLT entry to be created. See tcc.h for a description of the
+   different values. */
+int gotplt_entry_type (int reloc_type)
+{
+    switch (reloc_type) {
+	case R_ARM_NONE:
+	case R_ARM_COPY:
+	case R_ARM_GLOB_DAT:
+	case R_ARM_JUMP_SLOT:
+            return NO_GOTPLT_ENTRY;
+
+        case R_ARM_PC24:
+        case R_ARM_CALL:
+	case R_ARM_JUMP24:
+	case R_ARM_PLT32:
+	case R_ARM_THM_PC22:
+	case R_ARM_THM_JUMP24:
+	case R_ARM_MOVT_ABS:
+	case R_ARM_MOVW_ABS_NC:
+	case R_ARM_THM_MOVT_ABS:
+	case R_ARM_THM_MOVW_ABS_NC:
+	case R_ARM_PREL31:
+	case R_ARM_ABS32:
+	case R_ARM_REL32:
+	case R_ARM_V4BX:
+            return AUTO_GOTPLT_ENTRY;
+
+	case R_ARM_GOTPC:
+	case R_ARM_GOTOFF:
+            return BUILD_GOT_ONLY;
+
+	case R_ARM_GOT32:
+            return ALWAYS_GOTPLT_ENTRY;
+    }
+
+    tcc_error ("Unknown relocation type: %d", reloc_type);
+    return -1;
+}
+
+ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
+{
+    Section *plt = s1->plt;
+    uint8_t *p;
+    unsigned plt_offset;
+
+    /* when building a DLL, GOT entry accesses must be done relative to
+       start of GOT (see x86_64 example above)  */
+    if (s1->output_type == TCC_OUTPUT_DLL)
+        tcc_error("DLLs unimplemented!");
+
+    /* empty PLT: create PLT0 entry that push address of call site and
+       jump to ld.so resolution routine (GOT + 8) */
+    if (plt->data_offset == 0) {
+        p = section_ptr_add(plt, 20);
+        write32le(p,    0xe52de004); /* push {lr}         */
+        write32le(p+4,  0xe59fe004); /* ldr lr, [pc, #4] */
+        write32le(p+8,  0xe08fe00e); /* add lr, pc, lr    */
+        write32le(p+12, 0xe5bef008); /* ldr pc, [lr, #8]! */
+        /* p+16 is set in relocate_plt */
+    }
+    plt_offset = plt->data_offset;
+
+    if (attr->plt_thumb_stub) {
+        p = section_ptr_add(plt, 4);
+        write32le(p,   0x4778); /* bx pc */
+        write32le(p+2, 0x46c0); /* nop   */
+    }
+    p = section_ptr_add(plt, 16);
+    /* Jump to GOT entry where ld.so initially put address of PLT0 */
+    write32le(p,   0xe59fc004); /* ldr ip, [pc, #4] */
+    write32le(p+4, 0xe08fc00c); /* add ip, pc, ip */
+    write32le(p+8, 0xe59cf000); /* ldr pc, [ip] */
+    /* p + 12 contains offset to GOT entry once patched by relocate_plt */
+    write32le(p+12, got_offset);
+    return plt_offset;
+}
+
+/* relocate the PLT: compute addresses and offsets in the PLT now that final
+   address for PLT and GOT are known (see fill_program_header) */
+ST_FUNC void relocate_plt(TCCState *s1)
+{
+    uint8_t *p, *p_end;
+
+    if (!s1->plt)
+      return;
+
+    p = s1->plt->data;
+    p_end = p + s1->plt->data_offset;
+
+    if (p < p_end) {
+        int x = s1->got->sh_addr - s1->plt->sh_addr - 12;
+        write32le(s1->plt->data + 16, x - 16);
+        p += 20;
+        while (p < p_end) {
+            if (read32le(p) == 0x46c04778) /* PLT Thumb stub present */
+                p += 4;
+            add32le(p + 12, x + s1->plt->data - p);
+            p += 16;
+        }
+    }
+}
+
+void relocate_init(Section *sr) {}
+
+void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
+{
+    ElfW(Sym) *sym;
+    int sym_index;
+
+    sym_index = ELFW(R_SYM)(rel->r_info);
+    sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+
+    switch(type) {
+        case R_ARM_PC24:
+        case R_ARM_CALL:
+        case R_ARM_JUMP24:
+        case R_ARM_PLT32:
+            {
+                int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko;
+                x = (*(int *) ptr) & 0xffffff;
+#ifdef DEBUG_RELOC
+		printf ("reloc %d: x=0x%x val=0x%x ", type, x, val);
+#endif
+                (*(int *)ptr) &= 0xff000000;
+                if (x & 0x800000)
+                    x -= 0x1000000;
+                x <<= 2;
+                blx_avail = (TCC_CPU_VERSION >= 5);
+                is_thumb = val & 1;
+                is_bl = (*(unsigned *) ptr) >> 24 == 0xeb;
+                is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl));
+                x += val - addr;
+#ifdef DEBUG_RELOC
+		printf (" newx=0x%x name=%s\n", x,
+			(char *) symtab_section->link->data + sym->st_name);
+#endif
+                h = x & 2;
+                th_ko = (x & 3) && (!blx_avail || !is_call);
+                if (th_ko || x >= 0x2000000 || x < -0x2000000)
+                    tcc_error("can't relocate value at %x,%d",addr, type);
+                x >>= 2;
+                x &= 0xffffff;
+                /* Only reached if blx is avail and it is a call */
+                if (is_thumb) {
+                    x |= h << 24;
+                    (*(int *)ptr) = 0xfa << 24; /* bl -> blx */
+                }
+                (*(int *) ptr) |= x;
+            }
+            return;
+        /* Since these relocations only concern Thumb-2 and blx instruction was
+           introduced before Thumb-2, we can assume blx is available and not
+           guard its use */
+        case R_ARM_THM_PC22:
+        case R_ARM_THM_JUMP24:
+            {
+                int x, hi, lo, s, j1, j2, i1, i2, imm10, imm11;
+                int to_thumb, is_call, to_plt, blx_bit = 1 << 12;
+                Section *plt;
+
+                /* weak reference */
+                if (sym->st_shndx == SHN_UNDEF &&
+                    ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
+                    return;
+
+                /* Get initial offset */
+                hi = (*(uint16_t *)ptr);
+                lo = (*(uint16_t *)(ptr+2));
+                s = (hi >> 10) & 1;
+                j1 = (lo >> 13) & 1;
+                j2 = (lo >> 11) & 1;
+                i1 = (j1 ^ s) ^ 1;
+                i2 = (j2 ^ s) ^ 1;
+                imm10 = hi & 0x3ff;
+                imm11 = lo & 0x7ff;
+                x = (s << 24) | (i1 << 23) | (i2 << 22) |
+                    (imm10 << 12) | (imm11 << 1);
+                if (x & 0x01000000)
+                    x -= 0x02000000;
+
+                /* Relocation infos */
+                to_thumb = val & 1;
+                plt = s1->plt;
+                to_plt = (val >= plt->sh_addr) &&
+                         (val < plt->sh_addr + plt->data_offset);
+                is_call = (type == R_ARM_THM_PC22);
+
+                if (!to_thumb && !to_plt && !is_call) {
+                    int index;
+                    uint8_t *p;
+                    char *name, buf[1024];
+                    Section *text_section;
+
+                    name = (char *) symtab_section->link->data + sym->st_name;
+                    text_section = s1->sections[sym->st_shndx];
+                    /* Modify reloc to target a thumb stub to switch to ARM */
+                    snprintf(buf, sizeof(buf), "%s_from_thumb", name);
+                    index = put_elf_sym(symtab_section,
+                                        text_section->data_offset + 1,
+                                        sym->st_size, sym->st_info, 0,
+                                        sym->st_shndx, buf);
+                    to_thumb = 1;
+                    val = text_section->data_offset + 1;
+                    rel->r_info = ELFW(R_INFO)(index, type);
+                    /* Create a thumb stub function to switch to ARM mode */
+                    put_elf_reloc(symtab_section, text_section,
+                                  text_section->data_offset + 4, R_ARM_JUMP24,
+                                  sym_index);
+                    p = section_ptr_add(text_section, 8);
+                    write32le(p,   0x4778); /* bx pc */
+                    write32le(p+2, 0x46c0); /* nop   */
+                    write32le(p+4, 0xeafffffe); /* b $sym */
+                }
+
+                /* Compute final offset */
+                x += val - addr;
+                if (!to_thumb && is_call) {
+                    blx_bit = 0; /* bl -> blx */
+                    x = (x + 3) & -4; /* Compute offset from aligned PC */
+                }
+
+                /* Check that relocation is possible
+                   * offset must not be out of range
+                   * if target is to be entered in arm mode:
+                     - bit 1 must not set
+                     - instruction must be a call (bl) or a jump to PLT */
+                if (!to_thumb || x >= 0x1000000 || x < -0x1000000)
+                    if (to_thumb || (val & 2) || (!is_call && !to_plt))
+                        tcc_error("can't relocate value at %x,%d",addr, type);
+
+                /* Compute and store final offset */
+                s = (x >> 24) & 1;
+                i1 = (x >> 23) & 1;
+                i2 = (x >> 22) & 1;
+                j1 = s ^ (i1 ^ 1);
+                j2 = s ^ (i2 ^ 1);
+                imm10 = (x >> 12) & 0x3ff;
+                imm11 = (x >> 1) & 0x7ff;
+                (*(uint16_t *)ptr) = (uint16_t) ((hi & 0xf800) |
+                                     (s << 10) | imm10);
+                (*(uint16_t *)(ptr+2)) = (uint16_t) ((lo & 0xc000) |
+                                (j1 << 13) | blx_bit | (j2 << 11) |
+                                imm11);
+            }
+            return;
+        case R_ARM_MOVT_ABS:
+        case R_ARM_MOVW_ABS_NC:
+            {
+                int x, imm4, imm12;
+                if (type == R_ARM_MOVT_ABS)
+                    val >>= 16;
+                imm12 = val & 0xfff;
+                imm4 = (val >> 12) & 0xf;
+                x = (imm4 << 16) | imm12;
+                if (type == R_ARM_THM_MOVT_ABS)
+                    *(int *)ptr |= x;
+                else
+                    *(int *)ptr += x;
+            }
+            return;
+        case R_ARM_THM_MOVT_ABS:
+        case R_ARM_THM_MOVW_ABS_NC:
+            {
+                int x, i, imm4, imm3, imm8;
+                if (type == R_ARM_THM_MOVT_ABS)
+                    val >>= 16;
+                imm8 = val & 0xff;
+                imm3 = (val >> 8) & 0x7;
+                i = (val >> 11) & 1;
+                imm4 = (val >> 12) & 0xf;
+                x = (imm3 << 28) | (imm8 << 16) | (i << 10) | imm4;
+                if (type == R_ARM_THM_MOVT_ABS)
+                    *(int *)ptr |= x;
+                else
+                    *(int *)ptr += x;
+            }
+            return;
+        case R_ARM_PREL31:
+            {
+                int x;
+                x = (*(int *)ptr) & 0x7fffffff;
+                (*(int *)ptr) &= 0x80000000;
+                x = (x * 2) / 2;
+                x += val - addr;
+                if((x^(x>>1))&0x40000000)
+                    tcc_error("can't relocate value at %x,%d",addr, type);
+                (*(int *)ptr) |= x & 0x7fffffff;
+            }
+        case R_ARM_ABS32:
+            *(int *)ptr += val;
+            return;
+        case R_ARM_REL32:
+            *(int *)ptr += val - addr;
+            return;
+        case R_ARM_GOTPC:
+            *(int *)ptr += s1->got->sh_addr - addr;
+            return;
+        case R_ARM_GOTOFF:
+            *(int *)ptr += val - s1->got->sh_addr;
+            return;
+        case R_ARM_GOT32:
+            /* we load the got offset */
+            *(int *)ptr += s1->sym_attrs[sym_index].got_offset;
+            return;
+        case R_ARM_COPY:
+            return;
+        case R_ARM_V4BX:
+            /* trade Thumb support for ARMv4 support */
+            if ((0x0ffffff0 & *(int*)ptr) == 0x012FFF10)
+                *(int*)ptr ^= 0xE12FFF10 ^ 0xE1A0F000; /* BX Rm -> MOV PC, Rm */
+            return;
+        case R_ARM_GLOB_DAT:
+        case R_ARM_JUMP_SLOT:
+            *(addr_t *)ptr = val;
+            return;
+        case R_ARM_NONE:
+            /* Nothing to do.  Normally used to indicate a dependency
+               on a certain symbol (like for exception handling under EABI).  */
+            return;
+        case R_ARM_RELATIVE:
+#ifdef TCC_TARGET_PE
+            add32le(ptr, val - s1->pe_imagebase);
+#endif
+            /* do nothing */
+            return;
+        default:
+            fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
+                type, (unsigned)addr, ptr, (unsigned)val);
+            return;
+    }
+}
+
+#endif /* !TARGET_DEFS_ONLY */
Index: EcnlProtoTool/trunk/tcc-0.9.27/arm64-gen.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/arm64-gen.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/arm64-gen.c	(revision 331)
@@ -0,0 +1,1837 @@
+/*
+ *  A64 code generator for TCC
+ *
+ *  Copyright (c) 2014-2015 Edmund Grimley Evans
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.  This file is offered as-is,
+ * without any warranty.
+ */
+
+#ifdef TARGET_DEFS_ONLY
+
+// Number of registers available to allocator:
+#define NB_REGS 28 // x0-x18, x30, v0-v7
+
+#define TREG_R(x) (x) // x = 0..18
+#define TREG_R30  19
+#define TREG_F(x) (x + 20) // x = 0..7
+
+// Register classes sorted from more general to more precise:
+#define RC_INT (1 << 0)
+#define RC_FLOAT (1 << 1)
+#define RC_R(x) (1 << (2 + (x))) // x = 0..18
+#define RC_R30  (1 << 21)
+#define RC_F(x) (1 << (22 + (x))) // x = 0..7
+
+#define RC_IRET (RC_R(0)) // int return register class
+#define RC_FRET (RC_F(0)) // float return register class
+
+#define REG_IRET (TREG_R(0)) // int return register number
+#define REG_FRET (TREG_F(0)) // float return register number
+
+#define PTR_SIZE 8
+
+#define LDOUBLE_SIZE 16
+#define LDOUBLE_ALIGN 16
+
+#define MAX_ALIGN 16
+
+#define CHAR_IS_UNSIGNED
+
+/******************************************************/
+#else /* ! TARGET_DEFS_ONLY */
+/******************************************************/
+#include "tcc.h"
+#include <assert.h>
+
+ST_DATA const int reg_classes[NB_REGS] = {
+  RC_INT | RC_R(0),
+  RC_INT | RC_R(1),
+  RC_INT | RC_R(2),
+  RC_INT | RC_R(3),
+  RC_INT | RC_R(4),
+  RC_INT | RC_R(5),
+  RC_INT | RC_R(6),
+  RC_INT | RC_R(7),
+  RC_INT | RC_R(8),
+  RC_INT | RC_R(9),
+  RC_INT | RC_R(10),
+  RC_INT | RC_R(11),
+  RC_INT | RC_R(12),
+  RC_INT | RC_R(13),
+  RC_INT | RC_R(14),
+  RC_INT | RC_R(15),
+  RC_INT | RC_R(16),
+  RC_INT | RC_R(17),
+  RC_INT | RC_R(18),
+  RC_R30, // not in RC_INT as we make special use of x30
+  RC_FLOAT | RC_F(0),
+  RC_FLOAT | RC_F(1),
+  RC_FLOAT | RC_F(2),
+  RC_FLOAT | RC_F(3),
+  RC_FLOAT | RC_F(4),
+  RC_FLOAT | RC_F(5),
+  RC_FLOAT | RC_F(6),
+  RC_FLOAT | RC_F(7)
+};
+
+#define IS_FREG(x) ((x) >= TREG_F(0))
+
+static uint32_t intr(int r)
+{
+    assert(TREG_R(0) <= r && r <= TREG_R30);
+    return r < TREG_R30 ? r : 30;
+}
+
+static uint32_t fltr(int r)
+{
+    assert(TREG_F(0) <= r && r <= TREG_F(7));
+    return r - TREG_F(0);
+}
+
+// Add an instruction to text section:
+ST_FUNC void o(unsigned int c)
+{
+    int ind1 = ind + 4;
+    if (nocode_wanted)
+        return;
+    if (ind1 > cur_text_section->data_allocated)
+        section_realloc(cur_text_section, ind1);
+    write32le(cur_text_section->data + ind, c);
+    ind = ind1;
+}
+
+static int arm64_encode_bimm64(uint64_t x)
+{
+    int neg = x & 1;
+    int rep, pos, len;
+
+    if (neg)
+        x = ~x;
+    if (!x)
+        return -1;
+
+    if (x >> 2 == (x & (((uint64_t)1 << (64 - 2)) - 1)))
+        rep = 2, x &= ((uint64_t)1 << 2) - 1;
+    else if (x >> 4 == (x & (((uint64_t)1 << (64 - 4)) - 1)))
+        rep = 4, x &= ((uint64_t)1 <<  4) - 1;
+    else if (x >> 8 == (x & (((uint64_t)1 << (64 - 8)) - 1)))
+        rep = 8, x &= ((uint64_t)1 <<  8) - 1;
+    else if (x >> 16 == (x & (((uint64_t)1 << (64 - 16)) - 1)))
+        rep = 16, x &= ((uint64_t)1 << 16) - 1;
+    else if (x >> 32 == (x & (((uint64_t)1 << (64 - 32)) - 1)))
+        rep = 32, x &= ((uint64_t)1 << 32) - 1;
+    else
+        rep = 64;
+
+    pos = 0;
+    if (!(x & (((uint64_t)1 << 32) - 1))) x >>= 32, pos += 32;
+    if (!(x & (((uint64_t)1 << 16) - 1))) x >>= 16, pos += 16;
+    if (!(x & (((uint64_t)1 <<  8) - 1))) x >>= 8, pos += 8;
+    if (!(x & (((uint64_t)1 <<  4) - 1))) x >>= 4, pos += 4;
+    if (!(x & (((uint64_t)1 <<  2) - 1))) x >>= 2, pos += 2;
+    if (!(x & (((uint64_t)1 <<  1) - 1))) x >>= 1, pos += 1;
+
+    len = 0;
+    if (!(~x & (((uint64_t)1 << 32) - 1))) x >>= 32, len += 32;
+    if (!(~x & (((uint64_t)1 << 16) - 1))) x >>= 16, len += 16;
+    if (!(~x & (((uint64_t)1 << 8) - 1))) x >>= 8, len += 8;
+    if (!(~x & (((uint64_t)1 << 4) - 1))) x >>= 4, len += 4;
+    if (!(~x & (((uint64_t)1 << 2) - 1))) x >>= 2, len += 2;
+    if (!(~x & (((uint64_t)1 << 1) - 1))) x >>= 1, len += 1;
+
+    if (x)
+        return -1;
+    if (neg) {
+        pos = (pos + len) & (rep - 1);
+        len = rep - len;
+    }
+    return ((0x1000 & rep << 6) | (((rep - 1) ^ 31) << 1 & 63) |
+            ((rep - pos) & (rep - 1)) << 6 | (len - 1));
+}
+
+static uint32_t arm64_movi(int r, uint64_t x)
+{
+    uint64_t m = 0xffff;
+    int e;
+    if (!(x & ~m))
+        return 0x52800000 | r | x << 5; // movz w(r),#(x)
+    if (!(x & ~(m << 16)))
+        return 0x52a00000 | r | x >> 11; // movz w(r),#(x >> 16),lsl #16
+    if (!(x & ~(m << 32)))
+        return 0xd2c00000 | r | x >> 27; // movz x(r),#(x >> 32),lsl #32
+    if (!(x & ~(m << 48)))
+        return 0xd2e00000 | r | x >> 43; // movz x(r),#(x >> 48),lsl #48
+    if ((x & ~m) == m << 16)
+        return (0x12800000 | r |
+                (~x << 5 & 0x1fffe0)); // movn w(r),#(~x)
+    if ((x & ~(m << 16)) == m)
+        return (0x12a00000 | r |
+                (~x >> 11 & 0x1fffe0)); // movn w(r),#(~x >> 16),lsl #16
+    if (!~(x | m))
+        return (0x92800000 | r |
+                (~x << 5 & 0x1fffe0)); // movn x(r),#(~x)
+    if (!~(x | m << 16))
+        return (0x92a00000 | r |
+                (~x >> 11 & 0x1fffe0)); // movn x(r),#(~x >> 16),lsl #16
+    if (!~(x | m << 32))
+        return (0x92c00000 | r |
+                (~x >> 27 & 0x1fffe0)); // movn x(r),#(~x >> 32),lsl #32
+    if (!~(x | m << 48))
+        return (0x92e00000 | r |
+                (~x >> 43 & 0x1fffe0)); // movn x(r),#(~x >> 32),lsl #32
+    if (!(x >> 32) && (e = arm64_encode_bimm64(x | x << 32)) >= 0)
+        return 0x320003e0 | r | (uint32_t)e << 10; // movi w(r),#(x)
+    if ((e = arm64_encode_bimm64(x)) >= 0)
+        return 0xb20003e0 | r | (uint32_t)e << 10; // movi x(r),#(x)
+    return 0;
+}
+
+static void arm64_movimm(int r, uint64_t x)
+{
+    uint32_t i;
+    if ((i = arm64_movi(r, x)))
+        o(i); // a single MOV
+    else {
+        // MOVZ/MOVN and 1-3 MOVKs
+        int z = 0, m = 0;
+        uint32_t mov1 = 0xd2800000; // movz
+        uint64_t x1 = x;
+        for (i = 0; i < 64; i += 16) {
+            z += !(x >> i & 0xffff);
+            m += !(~x >> i & 0xffff);
+        }
+        if (m > z) {
+            x1 = ~x;
+            mov1 = 0x92800000; // movn
+        }
+        for (i = 0; i < 64; i += 16)
+            if (x1 >> i & 0xffff) {
+                o(mov1 | r | (x1 >> i & 0xffff) << 5 | i << 17);
+                // movz/movn x(r),#(*),lsl #(i)
+                break;
+            }
+        for (i += 16; i < 64; i += 16)
+            if (x1 >> i & 0xffff)
+                o(0xf2800000 | r | (x >> i & 0xffff) << 5 | i << 17);
+                // movk x(r),#(*),lsl #(i)
+    }
+}
+
+// Patch all branches in list pointed to by t to branch to a:
+ST_FUNC void gsym_addr(int t_, int a_)
+{
+    uint32_t t = t_;
+    uint32_t a = a_;
+    while (t) {
+        unsigned char *ptr = cur_text_section->data + t;
+        uint32_t next = read32le(ptr);
+        if (a - t + 0x8000000 >= 0x10000000)
+            tcc_error("branch out of range");
+        write32le(ptr, (a - t == 4 ? 0xd503201f : // nop
+                        0x14000000 | ((a - t) >> 2 & 0x3ffffff))); // b
+        t = next;
+    }
+}
+
+// Patch all branches in list pointed to by t to branch to current location:
+ST_FUNC void gsym(int t)
+{
+    gsym_addr(t, ind);
+}
+
+static int arm64_type_size(int t)
+{
+    switch (t & VT_BTYPE) {
+    case VT_INT: return 2;
+    case VT_BYTE: return 0;
+    case VT_SHORT: return 1;
+    case VT_PTR: return 3;
+    case VT_FUNC: return 3;
+    case VT_FLOAT: return 2;
+    case VT_DOUBLE: return 3;
+    case VT_LDOUBLE: return 4;
+    case VT_BOOL: return 0;
+    case VT_LLONG: return 3;
+    }
+    assert(0);
+    return 0;
+}
+
+static void arm64_spoff(int reg, uint64_t off)
+{
+    uint32_t sub = off >> 63;
+    if (sub)
+        off = -off;
+    if (off < 4096)
+        o(0x910003e0 | sub << 30 | reg | off << 10);
+        // (add|sub) x(reg),sp,#(off)
+    else {
+        arm64_movimm(30, off); // use x30 for offset
+        o(0x8b3e63e0 | sub << 30 | reg); // (add|sub) x(reg),sp,x30
+    }
+}
+
+static void arm64_ldrx(int sg, int sz_, int dst, int bas, uint64_t off)
+{
+    uint32_t sz = sz_;
+    if (sz >= 2)
+        sg = 0;
+    if (!(off & ~((uint32_t)0xfff << sz)))
+        o(0x39400000 | dst | bas << 5 | off << (10 - sz) |
+          (uint32_t)!!sg << 23 | sz << 30); // ldr(*) x(dst),[x(bas),#(off)]
+    else if (off < 256 || -off <= 256)
+        o(0x38400000 | dst | bas << 5 | (off & 511) << 12 |
+          (uint32_t)!!sg << 23 | sz << 30); // ldur(*) x(dst),[x(bas),#(off)]
+    else {
+        arm64_movimm(30, off); // use x30 for offset
+        o(0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 |
+          (uint32_t)(!!sg + 1) << 22 | sz << 30); // ldr(*) x(dst),[x(bas),x30]
+    }
+}
+
+static void arm64_ldrv(int sz_, int dst, int bas, uint64_t off)
+{
+    uint32_t sz = sz_;
+    if (!(off & ~((uint32_t)0xfff << sz)))
+        o(0x3d400000 | dst | bas << 5 | off << (10 - sz) |
+          (sz & 4) << 21 | (sz & 3) << 30); // ldr (s|d|q)(dst),[x(bas),#(off)]
+    else if (off < 256 || -off <= 256)
+        o(0x3c400000 | dst | bas << 5 | (off & 511) << 12 |
+          (sz & 4) << 21 | (sz & 3) << 30); // ldur (s|d|q)(dst),[x(bas),#(off)]
+    else {
+        arm64_movimm(30, off); // use x30 for offset
+        o(0x3c606800 | dst | bas << 5 | (uint32_t)30 << 16 |
+          sz << 30 | (sz & 4) << 21); // ldr (s|d|q)(dst),[x(bas),x30]
+    }
+}
+
+static void arm64_ldrs(int reg_, int size)
+{
+    uint32_t reg = reg_;
+    // Use x30 for intermediate value in some cases.
+    switch (size) {
+    default: assert(0); break;
+    case 1:
+        arm64_ldrx(0, 0, reg, reg, 0);
+        break;
+    case 2:
+        arm64_ldrx(0, 1, reg, reg, 0);
+        break;
+    case 3:
+        arm64_ldrx(0, 1, 30, reg, 0);
+        arm64_ldrx(0, 0, reg, reg, 2);
+        o(0x2a0043c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #16
+        break;
+    case 4:
+        arm64_ldrx(0, 2, reg, reg, 0);
+        break;
+    case 5:
+        arm64_ldrx(0, 2, 30, reg, 0);
+        arm64_ldrx(0, 0, reg, reg, 4);
+        o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32
+        break;
+    case 6:
+        arm64_ldrx(0, 2, 30, reg, 0);
+        arm64_ldrx(0, 1, reg, reg, 4);
+        o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32
+        break;
+    case 7:
+        arm64_ldrx(0, 2, 30, reg, 0);
+        arm64_ldrx(0, 2, reg, reg, 3);
+        o(0x53087c00 | reg | reg << 5); // lsr w(reg), w(reg), #8
+        o(0xaa0083c0 | reg | reg << 16); // orr x(reg),x30,x(reg),lsl #32
+        break;
+    case 8:
+        arm64_ldrx(0, 3, reg, reg, 0);
+        break;
+    case 9:
+        arm64_ldrx(0, 0, reg + 1, reg, 8);
+        arm64_ldrx(0, 3, reg, reg, 0);
+        break;
+    case 10:
+        arm64_ldrx(0, 1, reg + 1, reg, 8);
+        arm64_ldrx(0, 3, reg, reg, 0);
+        break;
+    case 11:
+        arm64_ldrx(0, 2, reg + 1, reg, 7);
+        o(0x53087c00 | (reg+1) | (reg+1) << 5); // lsr w(reg+1), w(reg+1), #8
+        arm64_ldrx(0, 3, reg, reg, 0);
+        break;
+    case 12:
+        arm64_ldrx(0, 2, reg + 1, reg, 8);
+        arm64_ldrx(0, 3, reg, reg, 0);
+        break;
+    case 13:
+        arm64_ldrx(0, 3, reg + 1, reg, 5);
+        o(0xd358fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #24
+        arm64_ldrx(0, 3, reg, reg, 0);
+        break;
+    case 14:
+        arm64_ldrx(0, 3, reg + 1, reg, 6);
+        o(0xd350fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #16
+        arm64_ldrx(0, 3, reg, reg, 0);
+        break;
+    case 15:
+        arm64_ldrx(0, 3, reg + 1, reg, 7);
+        o(0xd348fc00 | (reg+1) | (reg+1) << 5); // lsr x(reg+1), x(reg+1), #8
+        arm64_ldrx(0, 3, reg, reg, 0);
+        break;
+    case 16:
+        o(0xa9400000 | reg | (reg+1) << 10 | reg << 5);
+        // ldp x(reg),x(reg+1),[x(reg)]
+        break;
+    }
+}
+
+static void arm64_strx(int sz_, int dst, int bas, uint64_t off)
+{
+    uint32_t sz = sz_;
+    if (!(off & ~((uint32_t)0xfff << sz)))
+        o(0x39000000 | dst | bas << 5 | off << (10 - sz) | sz << 30);
+        // str(*) x(dst),[x(bas],#(off)]
+    else if (off < 256 || -off <= 256)
+        o(0x38000000 | dst | bas << 5 | (off & 511) << 12 | sz << 30);
+        // stur(*) x(dst),[x(bas],#(off)]
+    else {
+        arm64_movimm(30, off); // use x30 for offset
+        o(0x38206800 | dst | bas << 5 | (uint32_t)30 << 16 | sz << 30);
+        // str(*) x(dst),[x(bas),x30]
+    }
+}
+
+static void arm64_strv(int sz_, int dst, int bas, uint64_t off)
+{
+    uint32_t sz = sz_;
+    if (!(off & ~((uint32_t)0xfff << sz)))
+        o(0x3d000000 | dst | bas << 5 | off << (10 - sz) |
+          (sz & 4) << 21 | (sz & 3) << 30); // str (s|d|q)(dst),[x(bas),#(off)]
+    else if (off < 256 || -off <= 256)
+        o(0x3c000000 | dst | bas << 5 | (off & 511) << 12 |
+          (sz & 4) << 21 | (sz & 3) << 30); // stur (s|d|q)(dst),[x(bas),#(off)]
+    else {
+        arm64_movimm(30, off); // use x30 for offset
+        o(0x3c206800 | dst | bas << 5 | (uint32_t)30 << 16 |
+          sz << 30 | (sz & 4) << 21); // str (s|d|q)(dst),[x(bas),x30]
+    }
+}
+
+static void arm64_sym(int r, Sym *sym, unsigned long addend)
+{
+    // Currently TCC's linker does not generate COPY relocations for
+    // STT_OBJECTs when tcc is invoked with "-run". This typically
+    // results in "R_AARCH64_ADR_PREL_PG_HI21 relocation failed" when
+    // a program refers to stdin. A workaround is to avoid that
+    // relocation and use only relocations with unlimited range.
+    int avoid_adrp = 1;
+
+    if (avoid_adrp || sym->a.weak) {
+        // (GCC uses a R_AARCH64_ABS64 in this case.)
+        greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G0_NC, addend);
+        o(0xd2800000 | r); // mov x(rt),#0,lsl #0
+        greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G1_NC, addend);
+        o(0xf2a00000 | r); // movk x(rt),#0,lsl #16
+        greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G2_NC, addend);
+        o(0xf2c00000 | r); // movk x(rt),#0,lsl #32
+        greloca(cur_text_section, sym, ind, R_AARCH64_MOVW_UABS_G3, addend);
+        o(0xf2e00000 | r); // movk x(rt),#0,lsl #48
+    }
+    else {
+        greloca(cur_text_section, sym, ind, R_AARCH64_ADR_PREL_PG_HI21, addend);
+        o(0x90000000 | r);
+        greloca(cur_text_section, sym, ind, R_AARCH64_ADD_ABS_LO12_NC, addend);
+        o(0x91000000 | r | r << 5);
+    }
+}
+
+ST_FUNC void load(int r, SValue *sv)
+{
+    int svtt = sv->type.t;
+    int svr = sv->r & ~VT_LVAL_TYPE;
+    int svrv = svr & VT_VALMASK;
+    uint64_t svcul = (uint32_t)sv->c.i;
+    svcul = svcul >> 31 & 1 ? svcul - ((uint64_t)1 << 32) : svcul;
+
+    if (svr == (VT_LOCAL | VT_LVAL)) {
+        if (IS_FREG(r))
+            arm64_ldrv(arm64_type_size(svtt), fltr(r), 29, svcul);
+        else
+            arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt),
+                       intr(r), 29, svcul);
+        return;
+    }
+
+    if ((svr & ~VT_VALMASK) == VT_LVAL && svrv < VT_CONST) {
+        if (IS_FREG(r))
+            arm64_ldrv(arm64_type_size(svtt), fltr(r), intr(svrv), 0);
+        else
+            arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt),
+                       intr(r), intr(svrv), 0);
+        return;
+    }
+
+    if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {
+        arm64_sym(30, sv->sym, svcul); // use x30 for address
+        if (IS_FREG(r))
+            arm64_ldrv(arm64_type_size(svtt), fltr(r), 30, 0);
+        else
+            arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt),
+                       intr(r), 30, 0);
+        return;
+    }
+
+    if (svr == (VT_CONST | VT_SYM)) {
+        arm64_sym(intr(r), sv->sym, svcul);
+        return;
+    }
+
+    if (svr == VT_CONST) {
+        if ((svtt & VT_BTYPE) != VT_VOID)
+            arm64_movimm(intr(r), arm64_type_size(svtt) == 3 ?
+                         sv->c.i : (uint32_t)svcul);
+        return;
+    }
+
+    if (svr < VT_CONST) {
+        if (IS_FREG(r) && IS_FREG(svr))
+            if (svtt == VT_LDOUBLE)
+                o(0x4ea01c00 | fltr(r) | fltr(svr) << 5);
+                    // mov v(r).16b,v(svr).16b
+            else
+                o(0x1e604000 | fltr(r) | fltr(svr) << 5); // fmov d(r),d(svr)
+        else if (!IS_FREG(r) && !IS_FREG(svr))
+            o(0xaa0003e0 | intr(r) | intr(svr) << 16); // mov x(r),x(svr)
+        else
+            assert(0);
+      return;
+    }
+
+    if (svr == VT_LOCAL) {
+        if (-svcul < 0x1000)
+            o(0xd10003a0 | intr(r) | -svcul << 10); // sub x(r),x29,#...
+        else {
+            arm64_movimm(30, -svcul); // use x30 for offset
+            o(0xcb0003a0 | intr(r) | (uint32_t)30 << 16); // sub x(r),x29,x30
+        }
+        return;
+    }
+
+    if (svr == VT_JMP || svr == VT_JMPI) {
+        int t = (svr == VT_JMPI);
+        arm64_movimm(intr(r), t);
+        o(0x14000002); // b .+8
+        gsym(svcul);
+        arm64_movimm(intr(r), t ^ 1);
+        return;
+    }
+
+    if (svr == (VT_LLOCAL | VT_LVAL)) {
+        arm64_ldrx(0, 3, 30, 29, svcul); // use x30 for offset
+        if (IS_FREG(r))
+            arm64_ldrv(arm64_type_size(svtt), fltr(r), 30, 0);
+        else
+            arm64_ldrx(!(svtt & VT_UNSIGNED), arm64_type_size(svtt),
+                       intr(r), 30, 0);
+        return;
+    }
+
+    printf("load(%x, (%x, %x, %llx))\n", r, svtt, sv->r, (long long)svcul);
+    assert(0);
+}
+
+ST_FUNC void store(int r, SValue *sv)
+{
+    int svtt = sv->type.t;
+    int svr = sv->r & ~VT_LVAL_TYPE;
+    int svrv = svr & VT_VALMASK;
+    uint64_t svcul = (uint32_t)sv->c.i;
+    svcul = svcul >> 31 & 1 ? svcul - ((uint64_t)1 << 32) : svcul;
+
+    if (svr == (VT_LOCAL | VT_LVAL)) {
+        if (IS_FREG(r))
+            arm64_strv(arm64_type_size(svtt), fltr(r), 29, svcul);
+        else
+            arm64_strx(arm64_type_size(svtt), intr(r), 29, svcul);
+        return;
+    }
+
+    if ((svr & ~VT_VALMASK) == VT_LVAL && svrv < VT_CONST) {
+        if (IS_FREG(r))
+            arm64_strv(arm64_type_size(svtt), fltr(r), intr(svrv), 0);
+        else
+            arm64_strx(arm64_type_size(svtt), intr(r), intr(svrv), 0);
+        return;
+    }
+
+    if (svr == (VT_CONST | VT_LVAL | VT_SYM)) {
+        arm64_sym(30, sv->sym, svcul); // use x30 for address
+        if (IS_FREG(r))
+            arm64_strv(arm64_type_size(svtt), fltr(r), 30, 0);
+        else
+            arm64_strx(arm64_type_size(svtt), intr(r), 30, 0);
+        return;
+    }
+
+    printf("store(%x, (%x, %x, %llx))\n", r, svtt, sv->r, (long long)svcul);
+    assert(0);
+}
+
+static void arm64_gen_bl_or_b(int b)
+{
+    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+        assert(!b && (vtop->r & VT_SYM));
+	greloca(cur_text_section, vtop->sym, ind, R_AARCH64_CALL26, 0);
+	o(0x94000000); // bl .
+    }
+    else
+        o(0xd61f0000 | (uint32_t)!b << 21 | intr(gv(RC_R30)) << 5); // br/blr
+}
+
+static int arm64_hfa_aux(CType *type, int *fsize, int num)
+{
+    if (is_float(type->t)) {
+        int a, n = type_size(type, &a);
+        if (num >= 4 || (*fsize && *fsize != n))
+            return -1;
+        *fsize = n;
+        return num + 1;
+    }
+    else if ((type->t & VT_BTYPE) == VT_STRUCT) {
+        int is_struct = 0; // rather than union
+        Sym *field;
+        for (field = type->ref->next; field; field = field->next)
+            if (field->c) {
+                is_struct = 1;
+                break;
+            }
+        if (is_struct) {
+            int num0 = num;
+            for (field = type->ref->next; field; field = field->next) {
+                if (field->c != (num - num0) * *fsize)
+                    return -1;
+                num = arm64_hfa_aux(&field->type, fsize, num);
+                if (num == -1)
+                    return -1;
+            }
+            if (type->ref->c != (num - num0) * *fsize)
+                return -1;
+            return num;
+        }
+        else { // union
+            int num0 = num;
+            for (field = type->ref->next; field; field = field->next) {
+                int num1 = arm64_hfa_aux(&field->type, fsize, num0);
+                if (num1 == -1)
+                    return -1;
+                num = num1 < num ? num : num1;
+            }
+            if (type->ref->c != (num - num0) * *fsize)
+                return -1;
+            return num;
+        }
+    }
+    else if (type->t & VT_ARRAY) {
+        int num1;
+        if (!type->ref->c)
+            return num;
+        num1 = arm64_hfa_aux(&type->ref->type, fsize, num);
+        if (num1 == -1 || (num1 != num && type->ref->c > 4))
+            return -1;
+        num1 = num + type->ref->c * (num1 - num);
+        if (num1 > 4)
+            return -1;
+        return num1;
+    }
+    return -1;
+}
+
+static int arm64_hfa(CType *type, int *fsize)
+{
+    if ((type->t & VT_BTYPE) == VT_STRUCT || (type->t & VT_ARRAY)) {
+        int sz = 0;
+        int n = arm64_hfa_aux(type, &sz, 0);
+        if (0 < n && n <= 4) {
+            if (fsize)
+                *fsize = sz;
+            return n;
+        }
+    }
+    return 0;
+}
+
+static unsigned long arm64_pcs_aux(int n, CType **type, unsigned long *a)
+{
+    int nx = 0; // next integer register
+    int nv = 0; // next vector register
+    unsigned long ns = 32; // next stack offset
+    int i;
+
+    for (i = 0; i < n; i++) {
+        int hfa = arm64_hfa(type[i], 0);
+        int size, align;
+
+        if ((type[i]->t & VT_ARRAY) ||
+            (type[i]->t & VT_BTYPE) == VT_FUNC)
+            size = align = 8;
+        else
+            size = type_size(type[i], &align);
+
+        if (hfa)
+            // B.2
+            ;
+        else if (size > 16) {
+            // B.3: replace with pointer
+            if (nx < 8)
+                a[i] = nx++ << 1 | 1;
+            else {
+                ns = (ns + 7) & ~7;
+                a[i] = ns | 1;
+                ns += 8;
+            }
+            continue;
+        }
+        else if ((type[i]->t & VT_BTYPE) == VT_STRUCT)
+            // B.4
+            size = (size + 7) & ~7;
+
+        // C.1
+        if (is_float(type[i]->t) && nv < 8) {
+            a[i] = 16 + (nv++ << 1);
+            continue;
+        }
+
+        // C.2
+        if (hfa && nv + hfa <= 8) {
+            a[i] = 16 + (nv << 1);
+            nv += hfa;
+            continue;
+        }
+
+        // C.3
+        if (hfa) {
+            nv = 8;
+            size = (size + 7) & ~7;
+        }
+
+        // C.4
+        if (hfa || (type[i]->t & VT_BTYPE) == VT_LDOUBLE) {
+            ns = (ns + 7) & ~7;
+            ns = (ns + align - 1) & -align;
+        }
+
+        // C.5
+        if ((type[i]->t & VT_BTYPE) == VT_FLOAT)
+            size = 8;
+
+        // C.6
+        if (hfa || is_float(type[i]->t)) {
+            a[i] = ns;
+            ns += size;
+            continue;
+        }
+
+        // C.7
+        if ((type[i]->t & VT_BTYPE) != VT_STRUCT && size <= 8 && nx < 8) {
+            a[i] = nx++ << 1;
+            continue;
+        }
+
+        // C.8
+        if (align == 16)
+            nx = (nx + 1) & ~1;
+
+        // C.9
+        if ((type[i]->t & VT_BTYPE) != VT_STRUCT && size == 16 && nx < 7) {
+            a[i] = nx << 1;
+            nx += 2;
+            continue;
+        }
+
+        // C.10
+        if ((type[i]->t & VT_BTYPE) == VT_STRUCT && size <= (8 - nx) * 8) {
+            a[i] = nx << 1;
+            nx += (size + 7) >> 3;
+            continue;
+        }
+
+        // C.11
+        nx = 8;
+
+        // C.12
+        ns = (ns + 7) & ~7;
+        ns = (ns + align - 1) & -align;
+
+        // C.13
+        if ((type[i]->t & VT_BTYPE) == VT_STRUCT) {
+            a[i] = ns;
+            ns += size;
+            continue;
+        }
+
+        // C.14
+        if (size < 8)
+            size = 8;
+
+        // C.15
+        a[i] = ns;
+        ns += size;
+    }
+
+    return ns - 32;
+}
+
+static unsigned long arm64_pcs(int n, CType **type, unsigned long *a)
+{
+    unsigned long stack;
+
+    // Return type:
+    if ((type[0]->t & VT_BTYPE) == VT_VOID)
+        a[0] = -1;
+    else {
+        arm64_pcs_aux(1, type, a);
+        assert(a[0] == 0 || a[0] == 1 || a[0] == 16);
+    }
+
+    // Argument types:
+    stack = arm64_pcs_aux(n, type + 1, a + 1);
+
+    if (0) {
+        int i;
+        for (i = 0; i <= n; i++) {
+            if (!i)
+                printf("arm64_pcs return: ");
+            else
+                printf("arm64_pcs arg %d: ", i);
+            if (a[i] == (unsigned long)-1)
+                printf("void\n");
+            else if (a[i] == 1 && !i)
+                printf("X8 pointer\n");
+            else if (a[i] < 16)
+                printf("X%lu%s\n", a[i] / 2, a[i] & 1 ? " pointer" : "");
+            else if (a[i] < 32)
+                printf("V%lu\n", a[i] / 2 - 8);
+            else
+                printf("stack %lu%s\n",
+                       (a[i] - 32) & ~1, a[i] & 1 ? " pointer" : "");
+        }
+    }
+
+    return stack;
+}
+
+ST_FUNC void gfunc_call(int nb_args)
+{
+    CType *return_type;
+    CType **t;
+    unsigned long *a, *a1;
+    unsigned long stack;
+    int i;
+
+    return_type = &vtop[-nb_args].type.ref->type;
+    if ((return_type->t & VT_BTYPE) == VT_STRUCT)
+        --nb_args;
+
+    t = tcc_malloc((nb_args + 1) * sizeof(*t));
+    a = tcc_malloc((nb_args + 1) * sizeof(*a));
+    a1 = tcc_malloc((nb_args + 1) * sizeof(*a1));
+
+    t[0] = return_type;
+    for (i = 0; i < nb_args; i++)
+        t[nb_args - i] = &vtop[-i].type;
+
+    stack = arm64_pcs(nb_args, t, a);
+
+    // Allocate space for structs replaced by pointer:
+    for (i = nb_args; i; i--)
+        if (a[i] & 1) {
+            SValue *arg = &vtop[i - nb_args];
+            int align, size = type_size(&arg->type, &align);
+            assert((arg->type.t & VT_BTYPE) == VT_STRUCT);
+            stack = (stack + align - 1) & -align;
+            a1[i] = stack;
+            stack += size;
+        }
+
+    stack = (stack + 15) >> 4 << 4;
+
+    assert(stack < 0x1000);
+    if (stack)
+        o(0xd10003ff | stack << 10); // sub sp,sp,#(n)
+
+    // First pass: set all values on stack
+    for (i = nb_args; i; i--) {
+        vpushv(vtop - nb_args + i);
+
+        if (a[i] & 1) {
+            // struct replaced by pointer
+            int r = get_reg(RC_INT);
+            arm64_spoff(intr(r), a1[i]);
+            vset(&vtop->type, r | VT_LVAL, 0);
+            vswap();
+            vstore();
+            if (a[i] >= 32) {
+                // pointer on stack
+                r = get_reg(RC_INT);
+                arm64_spoff(intr(r), a1[i]);
+                arm64_strx(3, intr(r), 31, (a[i] - 32) >> 1 << 1);
+            }
+        }
+        else if (a[i] >= 32) {
+            // value on stack
+            if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
+                int r = get_reg(RC_INT);
+                arm64_spoff(intr(r), a[i] - 32);
+                vset(&vtop->type, r | VT_LVAL, 0);
+                vswap();
+                vstore();
+            }
+            else if (is_float(vtop->type.t)) {
+                gv(RC_FLOAT);
+                arm64_strv(arm64_type_size(vtop[0].type.t),
+                           fltr(vtop[0].r), 31, a[i] - 32);
+            }
+            else {
+                gv(RC_INT);
+                arm64_strx(arm64_type_size(vtop[0].type.t),
+                           intr(vtop[0].r), 31, a[i] - 32);
+            }
+        }
+
+        --vtop;
+    }
+
+    // Second pass: assign values to registers
+    for (i = nb_args; i; i--, vtop--) {
+        if (a[i] < 16 && !(a[i] & 1)) {
+            // value in general-purpose registers
+            if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
+                int align, size = type_size(&vtop->type, &align);
+                vtop->type.t = VT_PTR;
+                gaddrof();
+                gv(RC_R(a[i] / 2));
+                arm64_ldrs(a[i] / 2, size);
+            }
+            else
+                gv(RC_R(a[i] / 2));
+        }
+        else if (a[i] < 16)
+            // struct replaced by pointer in register
+            arm64_spoff(a[i] / 2, a1[i]);
+        else if (a[i] < 32) {
+            // value in floating-point registers
+            if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
+                uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz);
+                vtop->type.t = VT_PTR;
+                gaddrof();
+                gv(RC_R30);
+                for (j = 0; j < n; j++)
+                    o(0x3d4003c0 |
+                      (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |
+                      (a[i] / 2 - 8 + j) |
+                      j << 10); // ldr ([sdq])(*),[x30,#(j * sz)]
+            }
+            else
+                gv(RC_F(a[i] / 2 - 8));
+        }
+    }
+
+    if ((return_type->t & VT_BTYPE) == VT_STRUCT) {
+        if (a[0] == 1) {
+            // indirect return: set x8 and discard the stack value
+            gv(RC_R(8));
+            --vtop;
+        }
+        else
+            // return in registers: keep the address for after the call
+            vswap();
+    }
+
+    save_regs(0);
+    arm64_gen_bl_or_b(0);
+    --vtop;
+    if (stack)
+        o(0x910003ff | stack << 10); // add sp,sp,#(n)
+
+    {
+        int rt = return_type->t;
+        int bt = rt & VT_BTYPE;
+        if (bt == VT_BYTE || bt == VT_SHORT)
+            // Promote small integers:
+            o(0x13001c00 | (bt == VT_SHORT) << 13 |
+              (uint32_t)!!(rt & VT_UNSIGNED) << 30); // [su]xt[bh] w0,w0
+        else if (bt == VT_STRUCT && !(a[0] & 1)) {
+            // A struct was returned in registers, so write it out:
+            gv(RC_R(8));
+            --vtop;
+            if (a[0] == 0) {
+                int align, size = type_size(return_type, &align);
+                assert(size <= 16);
+                if (size > 8)
+                    o(0xa9000500); // stp x0,x1,[x8]
+                else if (size)
+                    arm64_strx(size > 4 ? 3 : size > 2 ? 2 : size > 1, 0, 8, 0);
+
+            }
+            else if (a[0] == 16) {
+                uint32_t j, sz, n = arm64_hfa(return_type, &sz);
+                for (j = 0; j < n; j++)
+                    o(0x3d000100 |
+                      (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |
+                      (a[i] / 2 - 8 + j) |
+                      j << 10); // str ([sdq])(*),[x8,#(j * sz)]
+            }
+        }
+    }
+
+    tcc_free(a1);
+    tcc_free(a);
+    tcc_free(t);
+}
+
+static unsigned long arm64_func_va_list_stack;
+static int arm64_func_va_list_gr_offs;
+static int arm64_func_va_list_vr_offs;
+static int arm64_func_sub_sp_offset;
+
+ST_FUNC void gfunc_prolog(CType *func_type)
+{
+    int n = 0;
+    int i = 0;
+    Sym *sym;
+    CType **t;
+    unsigned long *a;
+
+    // Why doesn't the caller (gen_function) set func_vt?
+    func_vt = func_type->ref->type;
+    func_vc = 144; // offset of where x8 is stored
+
+    for (sym = func_type->ref; sym; sym = sym->next)
+        ++n;
+    t = tcc_malloc(n * sizeof(*t));
+    a = tcc_malloc(n * sizeof(*a));
+
+    for (sym = func_type->ref; sym; sym = sym->next)
+        t[i++] = &sym->type;
+
+    arm64_func_va_list_stack = arm64_pcs(n - 1, t, a);
+
+    o(0xa9b27bfd); // stp x29,x30,[sp,#-224]!
+    o(0xad0087e0); // stp q0,q1,[sp,#16]
+    o(0xad018fe2); // stp q2,q3,[sp,#48]
+    o(0xad0297e4); // stp q4,q5,[sp,#80]
+    o(0xad039fe6); // stp q6,q7,[sp,#112]
+    o(0xa90923e8); // stp x8,x8,[sp,#144]
+    o(0xa90a07e0); // stp x0,x1,[sp,#160]
+    o(0xa90b0fe2); // stp x2,x3,[sp,#176]
+    o(0xa90c17e4); // stp x4,x5,[sp,#192]
+    o(0xa90d1fe6); // stp x6,x7,[sp,#208]
+
+    arm64_func_va_list_gr_offs = -64;
+    arm64_func_va_list_vr_offs = -128;
+
+    for (i = 1, sym = func_type->ref->next; sym; i++, sym = sym->next) {
+        int off = (a[i] < 16 ? 160 + a[i] / 2 * 8 :
+                   a[i] < 32 ? 16 + (a[i] - 16) / 2 * 16 :
+                   224 + ((a[i] - 32) >> 1 << 1));
+        sym_push(sym->v & ~SYM_FIELD, &sym->type,
+                 (a[i] & 1 ? VT_LLOCAL : VT_LOCAL) | lvalue_type(sym->type.t),
+                 off);
+
+        if (a[i] < 16) {
+            int align, size = type_size(&sym->type, &align);
+            arm64_func_va_list_gr_offs = (a[i] / 2 - 7 +
+                                          (!(a[i] & 1) && size > 8)) * 8;
+        }
+        else if (a[i] < 32) {
+            uint32_t hfa = arm64_hfa(&sym->type, 0);
+            arm64_func_va_list_vr_offs = (a[i] / 2 - 16 +
+                                          (hfa ? hfa : 1)) * 16;
+        }
+
+        // HFAs of float and double need to be written differently:
+        if (16 <= a[i] && a[i] < 32 && (sym->type.t & VT_BTYPE) == VT_STRUCT) {
+            uint32_t j, sz, k = arm64_hfa(&sym->type, &sz);
+            if (sz < 16)
+                for (j = 0; j < k; j++) {
+                    o(0x3d0003e0 | -(sz & 8) << 27 | (sz & 4) << 29 |
+                      ((a[i] - 16) / 2 + j) | (off / sz + j) << 10);
+                    // str ([sdq])(*),[sp,#(j * sz)]
+                }
+        }
+    }
+
+    tcc_free(a);
+    tcc_free(t);
+
+    o(0x910003fd); // mov x29,sp
+    arm64_func_sub_sp_offset = ind;
+    // In gfunc_epilog these will be replaced with code to decrement SP:
+    o(0xd503201f); // nop
+    o(0xd503201f); // nop
+    loc = 0;
+}
+
+ST_FUNC void gen_va_start(void)
+{
+    int r;
+    --vtop; // we don't need the "arg"
+    gaddrof();
+    r = intr(gv(RC_INT));
+
+    if (arm64_func_va_list_stack) {
+        //xx could use add (immediate) here
+        arm64_movimm(30, arm64_func_va_list_stack + 224);
+        o(0x8b1e03be); // add x30,x29,x30
+    }
+    else
+        o(0x910383be); // add x30,x29,#224
+    o(0xf900001e | r << 5); // str x30,[x(r)]
+
+    if (arm64_func_va_list_gr_offs) {
+        if (arm64_func_va_list_stack)
+            o(0x910383be); // add x30,x29,#224
+        o(0xf900041e | r << 5); // str x30,[x(r),#8]
+    }
+
+    if (arm64_func_va_list_vr_offs) {
+        o(0x910243be); // add x30,x29,#144
+        o(0xf900081e | r << 5); // str x30,[x(r),#16]
+    }
+
+    arm64_movimm(30, arm64_func_va_list_gr_offs);
+    o(0xb900181e | r << 5); // str w30,[x(r),#24]
+
+    arm64_movimm(30, arm64_func_va_list_vr_offs);
+    o(0xb9001c1e | r << 5); // str w30,[x(r),#28]
+
+    --vtop;
+}
+
+ST_FUNC void gen_va_arg(CType *t)
+{
+    int align, size = type_size(t, &align);
+    int fsize, hfa = arm64_hfa(t, &fsize);
+    uint32_t r0, r1;
+
+    if (is_float(t->t)) {
+        hfa = 1;
+        fsize = size;
+    }
+
+    gaddrof();
+    r0 = intr(gv(RC_INT));
+    r1 = get_reg(RC_INT);
+    vtop[0].r = r1 | lvalue_type(t->t);
+    r1 = intr(r1);
+
+    if (!hfa) {
+        uint32_t n = size > 16 ? 8 : (size + 7) & -8;
+        o(0xb940181e | r0 << 5); // ldr w30,[x(r0),#24] // __gr_offs
+        if (align == 16) {
+            assert(0); // this path untested but needed for __uint128_t
+            o(0x11003fde); // add w30,w30,#15
+            o(0x121c6fde); // and w30,w30,#-16
+        }
+        o(0x310003c0 | r1 | n << 10); // adds w(r1),w30,#(n)
+        o(0x540000ad); // b.le .+20
+        o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack
+        o(0x9100001e | r1 << 5 | n << 10); // add x30,x(r1),#(n)
+        o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
+        o(0x14000004); // b .+16
+        o(0xb9001800 | r1 | r0 << 5); // str w(r1),[x(r0),#24] // __gr_offs
+        o(0xf9400400 | r1 | r0 << 5); // ldr x(r1),[x(r0),#8] // __gr_top
+        o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw
+        if (size > 16)
+            o(0xf9400000 | r1 | r1 << 5); // ldr x(r1),[x(r1)]
+    }
+    else {
+        uint32_t rsz = hfa << 4;
+        uint32_t ssz = (size + 7) & -(uint32_t)8;
+        uint32_t b1, b2;
+        o(0xb9401c1e | r0 << 5); // ldr w30,[x(r0),#28] // __vr_offs
+        o(0x310003c0 | r1 | rsz << 10); // adds w(r1),w30,#(rsz)
+        b1 = ind; o(0x5400000d); // b.le lab1
+        o(0xf9400000 | r1 | r0 << 5); // ldr x(r1),[x(r0)] // __stack
+        if (fsize == 16) {
+            o(0x91003c00 | r1 | r1 << 5); // add x(r1),x(r1),#15
+            o(0x927cec00 | r1 | r1 << 5); // and x(r1),x(r1),#-16
+        }
+        o(0x9100001e | r1 << 5 | ssz << 10); // add x30,x(r1),#(ssz)
+        o(0xf900001e | r0 << 5); // str x30,[x(r0)] // __stack
+        b2 = ind; o(0x14000000); // b lab2
+        // lab1:
+        write32le(cur_text_section->data + b1, 0x5400000d | (ind - b1) << 3);
+        o(0xb9001c00 | r1 | r0 << 5); // str w(r1),[x(r0),#28] // __vr_offs
+        o(0xf9400800 | r1 | r0 << 5); // ldr x(r1),[x(r0),#16] // __vr_top
+        if (hfa == 1 || fsize == 16)
+            o(0x8b3ec000 | r1 | r1 << 5); // add x(r1),x(r1),w30,sxtw
+        else {
+            // We need to change the layout of this HFA.
+            // Get some space on the stack using global variable "loc":
+            loc = (loc - size) & -(uint32_t)align;
+            o(0x8b3ec000 | 30 | r1 << 5); // add x30,x(r1),w30,sxtw
+            arm64_movimm(r1, loc);
+            o(0x8b0003a0 | r1 | r1 << 16); // add x(r1),x29,x(r1)
+            o(0x4c402bdc | (uint32_t)fsize << 7 |
+              (uint32_t)(hfa == 2) << 15 |
+              (uint32_t)(hfa == 3) << 14); // ld1 {v28.(4s|2d),...},[x30]
+            o(0x0d00801c | r1 << 5 | (fsize == 8) << 10 |
+              (uint32_t)(hfa != 2) << 13 |
+              (uint32_t)(hfa != 3) << 21); // st(hfa) {v28.(s|d),...}[0],[x(r1)]
+        }
+        // lab2:
+        write32le(cur_text_section->data + b2, 0x14000000 | (ind - b2) >> 2);
+    }
+}
+
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret,
+                       int *align, int *regsize)
+{
+    return 0;
+}
+
+ST_FUNC void gfunc_return(CType *func_type)
+{
+    CType *t = func_type;
+    unsigned long a;
+
+    arm64_pcs(0, &t, &a);
+    switch (a) {
+    case -1:
+        break;
+    case 0:
+        if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
+            int align, size = type_size(func_type, &align);
+            gaddrof();
+            gv(RC_R(0));
+            arm64_ldrs(0, size);
+        }
+        else
+            gv(RC_IRET);
+        break;
+    case 1: {
+        CType type = *func_type;
+        mk_pointer(&type);
+        vset(&type, VT_LOCAL | VT_LVAL, func_vc);
+        indir();
+        vswap();
+        vstore();
+        break;
+    }
+    case 16:
+        if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
+          uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz);
+          gaddrof();
+          gv(RC_R(0));
+          for (j = 0; j < n; j++)
+              o(0x3d400000 |
+                (sz & 16) << 19 | -(sz & 8) << 27 | (sz & 4) << 29 |
+                j | j << 10); // ldr ([sdq])(*),[x0,#(j * sz)]
+        }
+        else
+            gv(RC_FRET);
+        break;
+    default:
+      assert(0);
+    }
+    vtop--;
+}
+
+ST_FUNC void gfunc_epilog(void)
+{
+    if (loc) {
+        // Insert instructions to subtract size of stack frame from SP.
+        unsigned char *ptr = cur_text_section->data + arm64_func_sub_sp_offset;
+        uint64_t diff = (-loc + 15) & ~15;
+        if (!(diff >> 24)) {
+            if (diff & 0xfff) // sub sp,sp,#(diff & 0xfff)
+                write32le(ptr, 0xd10003ff | (diff & 0xfff) << 10);
+            if (diff >> 12) // sub sp,sp,#(diff >> 12),lsl #12
+                write32le(ptr + 4, 0xd14003ff | (diff >> 12) << 10);
+        }
+        else {
+            // In this case we may subtract more than necessary,
+            // but always less than 17/16 of what we were aiming for.
+            int i = 0;
+            int j = 0;
+            while (diff >> 20) {
+                diff = (diff + 0xffff) >> 16;
+                ++i;
+            }
+            while (diff >> 16) {
+                diff = (diff + 1) >> 1;
+                ++j;
+            }
+            write32le(ptr, 0xd2800010 | diff << 5 | i << 21);
+            // mov x16,#(diff),lsl #(16 * i)
+            write32le(ptr + 4, 0xcb3063ff | j << 10);
+            // sub sp,sp,x16,lsl #(j)
+        }
+    }
+    o(0x910003bf); // mov sp,x29
+    o(0xa8ce7bfd); // ldp x29,x30,[sp],#224
+
+    o(0xd65f03c0); // ret
+}
+
+// Generate forward branch to label:
+ST_FUNC int gjmp(int t)
+{
+    int r = ind;
+    if (nocode_wanted)
+        return t;
+    o(t);
+    return r;
+}
+
+// Generate branch to known address:
+ST_FUNC void gjmp_addr(int a)
+{
+    assert(a - ind + 0x8000000 < 0x10000000);
+    o(0x14000000 | ((a - ind) >> 2 & 0x3ffffff));
+}
+
+ST_FUNC int gtst(int inv, int t)
+{
+    int bt = vtop->type.t & VT_BTYPE;
+    if (bt == VT_LDOUBLE) {
+        uint32_t a, b, f = fltr(gv(RC_FLOAT));
+        a = get_reg(RC_INT);
+        vpushi(0);
+        vtop[0].r = a;
+        b = get_reg(RC_INT);
+        a = intr(a);
+        b = intr(b);
+        o(0x4e083c00 | a | f << 5); // mov x(a),v(f).d[0]
+        o(0x4e183c00 | b | f << 5); // mov x(b),v(f).d[1]
+        o(0xaa000400 | a | a << 5 | b << 16); // orr x(a),x(a),x(b),lsl #1
+        o(0xb4000040 | a | !!inv << 24); // cbz/cbnz x(a),.+8
+        --vtop;
+    }
+    else if (bt == VT_FLOAT || bt == VT_DOUBLE) {
+        uint32_t a = fltr(gv(RC_FLOAT));
+        o(0x1e202008 | a << 5 | (bt != VT_FLOAT) << 22); // fcmp
+        o(0x54000040 | !!inv); // b.eq/b.ne .+8
+    }
+    else {
+        uint32_t ll = (bt == VT_PTR || bt == VT_LLONG);
+        uint32_t a = intr(gv(RC_INT));
+        o(0x34000040 | a | !!inv << 24 | ll << 31); // cbz/cbnz wA,.+8
+    }
+    --vtop;
+    return gjmp(t);
+}
+
+static int arm64_iconst(uint64_t *val, SValue *sv)
+{
+    if ((sv->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
+        return 0;
+    if (val) {
+        int t = sv->type.t;
+	int bt = t & VT_BTYPE;
+        *val = ((bt == VT_LLONG || bt == VT_PTR) ? sv->c.i :
+                (uint32_t)sv->c.i |
+                (t & VT_UNSIGNED ? 0 : -(sv->c.i & 0x80000000)));
+    }
+    return 1;
+}
+
+static int arm64_gen_opic(int op, uint32_t l, int rev, uint64_t val,
+                          uint32_t x, uint32_t a)
+{
+    if (op == '-' && !rev) {
+        val = -val;
+        op = '+';
+    }
+    val = l ? val : (uint32_t)val;
+
+    switch (op) {
+
+    case '+': {
+        uint32_t s = l ? val >> 63 : val >> 31;
+        val = s ? -val : val;
+        val = l ? val : (uint32_t)val;
+        if (!(val & ~(uint64_t)0xfff))
+            o(0x11000000 | l << 31 | s << 30 | x | a << 5 | val << 10);
+        else if (!(val & ~(uint64_t)0xfff000))
+            o(0x11400000 | l << 31 | s << 30 | x | a << 5 | val >> 12 << 10);
+        else {
+            arm64_movimm(30, val); // use x30
+            o(0x0b1e0000 | l << 31 | s << 30 | x | a << 5);
+        }
+        return 1;
+      }
+
+    case '-':
+        if (!val)
+            o(0x4b0003e0 | l << 31 | x | a << 16); // neg
+        else if (val == (l ? (uint64_t)-1 : (uint32_t)-1))
+            o(0x2a2003e0 | l << 31 | x | a << 16); // mvn
+        else {
+            arm64_movimm(30, val); // use x30
+            o(0x4b0003c0 | l << 31 | x | a << 16); // sub
+        }
+        return 1;
+
+    case '^':
+        if (val == -1 || (val == 0xffffffff && !l)) {
+            o(0x2a2003e0 | l << 31 | x | a << 16); // mvn
+            return 1;
+        }
+        // fall through
+    case '&':
+    case '|': {
+        int e = arm64_encode_bimm64(l ? val : val | val << 32);
+        if (e < 0)
+            return 0;
+        o((op == '&' ? 0x12000000 :
+           op == '|' ? 0x32000000 : 0x52000000) |
+          l << 31 | x | a << 5 | (uint32_t)e << 10);
+        return 1;
+    }
+
+    case TOK_SAR:
+    case TOK_SHL:
+    case TOK_SHR: {
+        uint32_t n = 32 << l;
+        val = val & (n - 1);
+        if (rev)
+            return 0;
+        if (!val)
+            assert(0);
+        else if (op == TOK_SHL)
+            o(0x53000000 | l << 31 | l << 22 | x | a << 5 |
+              (n - val) << 16 | (n - 1 - val) << 10); // lsl
+        else
+            o(0x13000000 | (op == TOK_SHR) << 30 | l << 31 | l << 22 |
+              x | a << 5 | val << 16 | (n - 1) << 10); // lsr/asr
+        return 1;
+    }
+
+    }
+    return 0;
+}
+
+static void arm64_gen_opil(int op, uint32_t l)
+{
+    uint32_t x, a, b;
+
+    // Special treatment for operations with a constant operand:
+    {
+        uint64_t val;
+        int rev = 1;
+
+        if (arm64_iconst(0, &vtop[0])) {
+            vswap();
+            rev = 0;
+        }
+        if (arm64_iconst(&val, &vtop[-1])) {
+            gv(RC_INT);
+            a = intr(vtop[0].r);
+            --vtop;
+            x = get_reg(RC_INT);
+            ++vtop;
+            if (arm64_gen_opic(op, l, rev, val, intr(x), a)) {
+                vtop[0].r = x;
+                vswap();
+                --vtop;
+                return;
+            }
+        }
+        if (!rev)
+            vswap();
+    }
+
+    gv2(RC_INT, RC_INT);
+    assert(vtop[-1].r < VT_CONST && vtop[0].r < VT_CONST);
+    a = intr(vtop[-1].r);
+    b = intr(vtop[0].r);
+    vtop -= 2;
+    x = get_reg(RC_INT);
+    ++vtop;
+    vtop[0].r = x;
+    x = intr(x);
+
+    switch (op) {
+    case '%':
+        // Use x30 for quotient:
+        o(0x1ac00c00 | l << 31 | 30 | a << 5 | b << 16); // sdiv
+        o(0x1b008000 | l << 31 | x | (uint32_t)30 << 5 |
+          b << 16 | a << 10); // msub
+        break;
+    case '&':
+        o(0x0a000000 | l << 31 | x | a << 5 | b << 16); // and
+        break;
+    case '*':
+        o(0x1b007c00 | l << 31 | x | a << 5 | b << 16); // mul
+        break;
+    case '+':
+        o(0x0b000000 | l << 31 | x | a << 5 | b << 16); // add
+        break;
+    case '-':
+        o(0x4b000000 | l << 31 | x | a << 5 | b << 16); // sub
+        break;
+    case '/':
+        o(0x1ac00c00 | l << 31 | x | a << 5 | b << 16); // sdiv
+        break;
+    case '^':
+        o(0x4a000000 | l << 31 | x | a << 5 | b << 16); // eor
+        break;
+    case '|':
+        o(0x2a000000 | l << 31 | x | a << 5 | b << 16); // orr
+        break;
+    case TOK_EQ:
+        o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+        o(0x1a9f17e0 | x); // cset wA,eq
+        break;
+    case TOK_GE:
+        o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+        o(0x1a9fb7e0 | x); // cset wA,ge
+        break;
+    case TOK_GT:
+        o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+        o(0x1a9fd7e0 | x); // cset wA,gt
+        break;
+    case TOK_LE:
+        o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+        o(0x1a9fc7e0 | x); // cset wA,le
+        break;
+    case TOK_LT:
+        o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+        o(0x1a9fa7e0 | x); // cset wA,lt
+        break;
+    case TOK_NE:
+        o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+        o(0x1a9f07e0 | x); // cset wA,ne
+        break;
+    case TOK_SAR:
+        o(0x1ac02800 | l << 31 | x | a << 5 | b << 16); // asr
+        break;
+    case TOK_SHL:
+        o(0x1ac02000 | l << 31 | x | a << 5 | b << 16); // lsl
+        break;
+    case TOK_SHR:
+        o(0x1ac02400 | l << 31 | x | a << 5 | b << 16); // lsr
+        break;
+    case TOK_UDIV:
+    case TOK_PDIV:
+        o(0x1ac00800 | l << 31 | x | a << 5 | b << 16); // udiv
+        break;
+    case TOK_UGE:
+        o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+        o(0x1a9f37e0 | x); // cset wA,cs
+        break;
+    case TOK_UGT:
+        o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+        o(0x1a9f97e0 | x); // cset wA,hi
+        break;
+    case TOK_ULT:
+        o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+        o(0x1a9f27e0 | x); // cset wA,cc
+        break;
+    case TOK_ULE:
+        o(0x6b00001f | l << 31 | a << 5 | b << 16); // cmp
+        o(0x1a9f87e0 | x); // cset wA,ls
+        break;
+    case TOK_UMOD:
+        // Use x30 for quotient:
+        o(0x1ac00800 | l << 31 | 30 | a << 5 | b << 16); // udiv
+        o(0x1b008000 | l << 31 | x | (uint32_t)30 << 5 |
+          b << 16 | a << 10); // msub
+        break;
+    default:
+        assert(0);
+    }
+}
+
+ST_FUNC void gen_opi(int op)
+{
+    arm64_gen_opil(op, 0);
+}
+
+ST_FUNC void gen_opl(int op)
+{
+    arm64_gen_opil(op, 1);
+}
+
+ST_FUNC void gen_opf(int op)
+{
+    uint32_t x, a, b, dbl;
+
+    if (vtop[0].type.t == VT_LDOUBLE) {
+        CType type = vtop[0].type;
+        int func = 0;
+        int cond = -1;
+        switch (op) {
+        case '*': func = TOK___multf3; break;
+        case '+': func = TOK___addtf3; break;
+        case '-': func = TOK___subtf3; break;
+        case '/': func = TOK___divtf3; break;
+        case TOK_EQ: func = TOK___eqtf2; cond = 1; break;
+        case TOK_NE: func = TOK___netf2; cond = 0; break;
+        case TOK_LT: func = TOK___lttf2; cond = 10; break;
+        case TOK_GE: func = TOK___getf2; cond = 11; break;
+        case TOK_LE: func = TOK___letf2; cond = 12; break;
+        case TOK_GT: func = TOK___gttf2; cond = 13; break;
+        default: assert(0); break;
+        }
+        vpush_global_sym(&func_old_type, func);
+        vrott(3);
+        gfunc_call(2);
+        vpushi(0);
+        vtop->r = cond < 0 ? REG_FRET : REG_IRET;
+        if (cond < 0)
+            vtop->type = type;
+        else {
+            o(0x7100001f); // cmp w0,#0
+            o(0x1a9f07e0 | (uint32_t)cond << 12); // cset w0,(cond)
+        }
+        return;
+    }
+
+    dbl = vtop[0].type.t != VT_FLOAT;
+    gv2(RC_FLOAT, RC_FLOAT);
+    assert(vtop[-1].r < VT_CONST && vtop[0].r < VT_CONST);
+    a = fltr(vtop[-1].r);
+    b = fltr(vtop[0].r);
+    vtop -= 2;
+    switch (op) {
+    case TOK_EQ: case TOK_NE:
+    case TOK_LT: case TOK_GE: case TOK_LE: case TOK_GT:
+        x = get_reg(RC_INT);
+        ++vtop;
+        vtop[0].r = x;
+        x = intr(x);
+        break;
+    default:
+        x = get_reg(RC_FLOAT);
+        ++vtop;
+        vtop[0].r = x;
+        x = fltr(x);
+        break;
+    }
+
+    switch (op) {
+    case '*':
+        o(0x1e200800 | dbl << 22 | x | a << 5 | b << 16); // fmul
+        break;
+    case '+':
+        o(0x1e202800 | dbl << 22 | x | a << 5 | b << 16); // fadd
+        break;
+    case '-':
+        o(0x1e203800 | dbl << 22 | x | a << 5 | b << 16); // fsub
+        break;
+    case '/':
+        o(0x1e201800 | dbl << 22 | x | a << 5 | b << 16); // fdiv
+        break;
+    case TOK_EQ:
+        o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
+        o(0x1a9f17e0 | x); // cset w(x),eq
+        break;
+    case TOK_GE:
+        o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
+        o(0x1a9fb7e0 | x); // cset w(x),ge
+        break;
+    case TOK_GT:
+        o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
+        o(0x1a9fd7e0 | x); // cset w(x),gt
+        break;
+    case TOK_LE:
+        o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
+        o(0x1a9f87e0 | x); // cset w(x),ls
+        break;
+    case TOK_LT:
+        o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
+        o(0x1a9f57e0 | x); // cset w(x),mi
+        break;
+    case TOK_NE:
+        o(0x1e202000 | dbl << 22 | a << 5 | b << 16); // fcmp
+        o(0x1a9f07e0 | x); // cset w(x),ne
+        break;
+    default:
+        assert(0);
+    }
+}
+
+// Generate sign extension from 32 to 64 bits:
+ST_FUNC void gen_cvt_sxtw(void)
+{
+    uint32_t r = intr(gv(RC_INT));
+    o(0x93407c00 | r | r << 5); // sxtw x(r),w(r)
+}
+
+ST_FUNC void gen_cvt_itof(int t)
+{
+    if (t == VT_LDOUBLE) {
+        int f = vtop->type.t;
+        int func = (f & VT_BTYPE) == VT_LLONG ?
+          (f & VT_UNSIGNED ? TOK___floatunditf : TOK___floatditf) :
+          (f & VT_UNSIGNED ? TOK___floatunsitf : TOK___floatsitf);
+        vpush_global_sym(&func_old_type, func);
+        vrott(2);
+        gfunc_call(1);
+        vpushi(0);
+        vtop->type.t = t;
+        vtop->r = REG_FRET;
+        return;
+    }
+    else {
+        int d, n = intr(gv(RC_INT));
+        int s = !(vtop->type.t & VT_UNSIGNED);
+        uint32_t l = ((vtop->type.t & VT_BTYPE) == VT_LLONG);
+        --vtop;
+        d = get_reg(RC_FLOAT);
+        ++vtop;
+        vtop[0].r = d;
+        o(0x1e220000 | (uint32_t)!s << 16 |
+          (uint32_t)(t != VT_FLOAT) << 22 | fltr(d) |
+          l << 31 | n << 5); // [us]cvtf [sd](d),[wx](n)
+    }
+}
+
+ST_FUNC void gen_cvt_ftoi(int t)
+{
+    if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
+        int func = (t & VT_BTYPE) == VT_LLONG ?
+          (t & VT_UNSIGNED ? TOK___fixunstfdi : TOK___fixtfdi) :
+          (t & VT_UNSIGNED ? TOK___fixunstfsi : TOK___fixtfsi);
+        vpush_global_sym(&func_old_type, func);
+        vrott(2);
+        gfunc_call(1);
+        vpushi(0);
+        vtop->type.t = t;
+        vtop->r = REG_IRET;
+        return;
+    }
+    else {
+        int d, n = fltr(gv(RC_FLOAT));
+        uint32_t l = ((vtop->type.t & VT_BTYPE) != VT_FLOAT);
+        --vtop;
+        d = get_reg(RC_INT);
+        ++vtop;
+        vtop[0].r = d;
+        o(0x1e380000 |
+          (uint32_t)!!(t & VT_UNSIGNED) << 16 |
+          (uint32_t)((t & VT_BTYPE) == VT_LLONG) << 31 | intr(d) |
+          l << 22 | n << 5); // fcvtz[su] [wx](d),[sd](n)
+    }
+}
+
+ST_FUNC void gen_cvt_ftof(int t)
+{
+    int f = vtop[0].type.t;
+    assert(t == VT_FLOAT || t == VT_DOUBLE || t == VT_LDOUBLE);
+    assert(f == VT_FLOAT || f == VT_DOUBLE || f == VT_LDOUBLE);
+    if (t == f)
+        return;
+
+    if (t == VT_LDOUBLE || f == VT_LDOUBLE) {
+        int func = (t == VT_LDOUBLE) ?
+            (f == VT_FLOAT ? TOK___extendsftf2 : TOK___extenddftf2) :
+            (t == VT_FLOAT ? TOK___trunctfsf2 : TOK___trunctfdf2);
+        vpush_global_sym(&func_old_type, func);
+        vrott(2);
+        gfunc_call(1);
+        vpushi(0);
+        vtop->type.t = t;
+        vtop->r = REG_FRET;
+    }
+    else {
+        int x, a;
+        gv(RC_FLOAT);
+        assert(vtop[0].r < VT_CONST);
+        a = fltr(vtop[0].r);
+        --vtop;
+        x = get_reg(RC_FLOAT);
+        ++vtop;
+        vtop[0].r = x;
+        x = fltr(x);
+
+        if (f == VT_FLOAT)
+            o(0x1e22c000 | x | a << 5); // fcvt d(x),s(a)
+        else
+            o(0x1e624000 | x | a << 5); // fcvt s(x),d(a)
+    }
+}
+
+ST_FUNC void ggoto(void)
+{
+    arm64_gen_bl_or_b(1);
+    --vtop;
+}
+
+ST_FUNC void gen_clear_cache(void)
+{
+    uint32_t beg, end, dsz, isz, p, lab1, b1;
+    gv2(RC_INT, RC_INT);
+    vpushi(0);
+    vtop->r = get_reg(RC_INT);
+    vpushi(0);
+    vtop->r = get_reg(RC_INT);
+    vpushi(0);
+    vtop->r = get_reg(RC_INT);
+    beg = intr(vtop[-4].r); // x0
+    end = intr(vtop[-3].r); // x1
+    dsz = intr(vtop[-2].r); // x2
+    isz = intr(vtop[-1].r); // x3
+    p = intr(vtop[0].r);    // x4
+    vtop -= 5;
+
+    o(0xd53b0020 | isz); // mrs x(isz),ctr_el0
+    o(0x52800080 | p); // mov w(p),#4
+    o(0x53104c00 | dsz | isz << 5); // ubfx w(dsz),w(isz),#16,#4
+    o(0x1ac02000 | dsz | p << 5 | dsz << 16); // lsl w(dsz),w(p),w(dsz)
+    o(0x12000c00 | isz | isz << 5); // and w(isz),w(isz),#15
+    o(0x1ac02000 | isz | p << 5 | isz << 16); // lsl w(isz),w(p),w(isz)
+    o(0x51000400 | p | dsz << 5); // sub w(p),w(dsz),#1
+    o(0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)
+    b1 = ind; o(0x14000000); // b
+    lab1 = ind;
+    o(0xd50b7b20 | p); // dc cvau,x(p)
+    o(0x8b000000 | p | p << 5 | dsz << 16); // add x(p),x(p),x(dsz)
+    write32le(cur_text_section->data + b1, 0x14000000 | (ind - b1) >> 2);
+    o(0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)
+    o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab1
+    o(0xd5033b9f); // dsb ish
+    o(0x51000400 | p | isz << 5); // sub w(p),w(isz),#1
+    o(0x8a240004 | p | beg << 5 | p << 16); // bic x(p),x(beg),x(p)
+    b1 = ind; o(0x14000000); // b
+    lab1 = ind;
+    o(0xd50b7520 | p); // ic ivau,x(p)
+    o(0x8b000000 | p | p << 5 | isz << 16); // add x(p),x(p),x(isz)
+    write32le(cur_text_section->data + b1, 0x14000000 | (ind - b1) >> 2);
+    o(0xeb00001f | p << 5 | end << 16); // cmp x(p),x(end)
+    o(0x54ffffa3 | ((lab1 - ind) << 3 & 0xffffe0)); // b.cc lab1
+    o(0xd5033b9f); // dsb ish
+    o(0xd5033fdf); // isb
+}
+
+ST_FUNC void gen_vla_sp_save(int addr) {
+    uint32_t r = intr(get_reg(RC_INT));
+    o(0x910003e0 | r); // mov x(r),sp
+    arm64_strx(3, r, 29, addr);
+}
+
+ST_FUNC void gen_vla_sp_restore(int addr) {
+    // Use x30 because this function can be called when there
+    // is a live return value in x0 but there is nothing on
+    // the value stack to prevent get_reg from returning x0.
+    uint32_t r = 30;
+    arm64_ldrx(0, 3, r, 29, addr);
+    o(0x9100001f | r << 5); // mov sp,x(r)
+}
+
+ST_FUNC void gen_vla_alloc(CType *type, int align) {
+    uint32_t r = intr(gv(RC_INT));
+    o(0x91003c00 | r | r << 5); // add x(r),x(r),#15
+    o(0x927cec00 | r | r << 5); // bic x(r),x(r),#15
+    o(0xcb2063ff | r << 16); // sub sp,sp,x(r)
+    vpop();
+}
+
+/* end of A64 code generator */
+/*************************************************************/
+#endif
+/*************************************************************/
Index: EcnlProtoTool/trunk/tcc-0.9.27/arm64-link.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/arm64-link.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/arm64-link.c	(revision 331)
@@ -0,0 +1,256 @@
+#ifdef TARGET_DEFS_ONLY
+
+#define EM_TCC_TARGET EM_AARCH64
+
+#define R_DATA_32  R_AARCH64_ABS32
+#define R_DATA_PTR R_AARCH64_ABS64
+#define R_JMP_SLOT R_AARCH64_JUMP_SLOT
+#define R_GLOB_DAT R_AARCH64_GLOB_DAT
+#define R_COPY     R_AARCH64_COPY
+#define R_RELATIVE R_AARCH64_RELATIVE
+
+#define R_NUM      R_AARCH64_NUM
+
+#define ELF_START_ADDR 0x00400000
+#define ELF_PAGE_SIZE 0x1000
+
+#define PCRELATIVE_DLLPLT 1
+#define RELOCATE_DLLPLT 1
+
+#else /* !TARGET_DEFS_ONLY */
+
+#include "tcc.h"
+
+/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
+   relocations, returns -1. */
+int code_reloc (int reloc_type)
+{
+    switch (reloc_type) {
+        case R_AARCH64_ABS32:
+        case R_AARCH64_ABS64:
+	case R_AARCH64_PREL32:
+        case R_AARCH64_MOVW_UABS_G0_NC:
+        case R_AARCH64_MOVW_UABS_G1_NC:
+        case R_AARCH64_MOVW_UABS_G2_NC:
+        case R_AARCH64_MOVW_UABS_G3:
+        case R_AARCH64_ADR_PREL_PG_HI21:
+        case R_AARCH64_ADD_ABS_LO12_NC:
+        case R_AARCH64_ADR_GOT_PAGE:
+        case R_AARCH64_LD64_GOT_LO12_NC:
+        case R_AARCH64_GLOB_DAT:
+        case R_AARCH64_COPY:
+            return 0;
+
+        case R_AARCH64_JUMP26:
+        case R_AARCH64_CALL26:
+        case R_AARCH64_JUMP_SLOT:
+            return 1;
+    }
+
+    tcc_error ("Unknown relocation type: %d", reloc_type);
+    return -1;
+}
+
+/* Returns an enumerator to describe whether and when the relocation needs a
+   GOT and/or PLT entry to be created. See tcc.h for a description of the
+   different values. */
+int gotplt_entry_type (int reloc_type)
+{
+    switch (reloc_type) {
+	case R_AARCH64_PREL32:
+        case R_AARCH64_MOVW_UABS_G0_NC:
+        case R_AARCH64_MOVW_UABS_G1_NC:
+        case R_AARCH64_MOVW_UABS_G2_NC:
+        case R_AARCH64_MOVW_UABS_G3:
+        case R_AARCH64_ADR_PREL_PG_HI21:
+        case R_AARCH64_ADD_ABS_LO12_NC:
+        case R_AARCH64_GLOB_DAT:
+        case R_AARCH64_JUMP_SLOT:
+        case R_AARCH64_COPY:
+            return NO_GOTPLT_ENTRY;
+
+        case R_AARCH64_ABS32:
+        case R_AARCH64_ABS64:
+        case R_AARCH64_JUMP26:
+        case R_AARCH64_CALL26:
+            return AUTO_GOTPLT_ENTRY;
+
+        case R_AARCH64_ADR_GOT_PAGE:
+        case R_AARCH64_LD64_GOT_LO12_NC:
+            return ALWAYS_GOTPLT_ENTRY;
+    }
+
+    tcc_error ("Unknown relocation type: %d", reloc_type);
+    return -1;
+}
+
+ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
+{
+    Section *plt = s1->plt;
+    uint8_t *p;
+    unsigned plt_offset;
+
+    if (s1->output_type == TCC_OUTPUT_DLL)
+        tcc_error("DLLs unimplemented!");
+
+    if (plt->data_offset == 0) {
+        section_ptr_add(plt, 32);
+    }
+    plt_offset = plt->data_offset;
+
+    p = section_ptr_add(plt, 16);
+    write32le(p, got_offset);
+    write32le(p + 4, (uint64_t) got_offset >> 32);
+    return plt_offset;
+}
+
+/* relocate the PLT: compute addresses and offsets in the PLT now that final
+   address for PLT and GOT are known (see fill_program_header) */
+ST_FUNC void relocate_plt(TCCState *s1)
+{
+    uint8_t *p, *p_end;
+
+    if (!s1->plt)
+      return;
+
+    p = s1->plt->data;
+    p_end = p + s1->plt->data_offset;
+
+    if (p < p_end) {
+        uint64_t plt = s1->plt->sh_addr;
+        uint64_t got = s1->got->sh_addr;
+        uint64_t off = (got >> 12) - (plt >> 12);
+        if ((off + ((uint32_t)1 << 20)) >> 21)
+            tcc_error("Failed relocating PLT (off=0x%lx, got=0x%lx, plt=0x%lx)", off, got, plt);
+        write32le(p, 0xa9bf7bf0); // stp x16,x30,[sp,#-16]!
+        write32le(p + 4, (0x90000010 | // adrp x16,...
+			  (off & 0x1ffffc) << 3 | (off & 3) << 29));
+        write32le(p + 8, (0xf9400211 | // ldr x17,[x16,#...]
+			  (got & 0xff8) << 7));
+        write32le(p + 12, (0x91000210 | // add x16,x16,#...
+			   (got & 0xfff) << 10));
+        write32le(p + 16, 0xd61f0220); // br x17
+        write32le(p + 20, 0xd503201f); // nop
+        write32le(p + 24, 0xd503201f); // nop
+        write32le(p + 28, 0xd503201f); // nop
+        p += 32;
+        while (p < p_end) {
+            uint64_t pc = plt + (p - s1->plt->data);
+            uint64_t addr = got + read64le(p);
+            uint64_t off = (addr >> 12) - (pc >> 12);
+            if ((off + ((uint32_t)1 << 20)) >> 21)
+                tcc_error("Failed relocating PLT (off=0x%lx, addr=0x%lx, pc=0x%lx)", off, addr, pc);
+            write32le(p, (0x90000010 | // adrp x16,...
+			  (off & 0x1ffffc) << 3 | (off & 3) << 29));
+            write32le(p + 4, (0xf9400211 | // ldr x17,[x16,#...]
+			      (addr & 0xff8) << 7));
+            write32le(p + 8, (0x91000210 | // add x16,x16,#...
+			      (addr & 0xfff) << 10));
+            write32le(p + 12, 0xd61f0220); // br x17
+            p += 16;
+        }
+    }
+}
+
+void relocate_init(Section *sr) {}
+
+void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
+{
+    int sym_index = ELFW(R_SYM)(rel->r_info);
+#ifdef DEBUG_RELOC
+    ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+#endif
+
+    switch(type) {
+        case R_AARCH64_ABS64:
+            write64le(ptr, val);
+            return;
+        case R_AARCH64_ABS32:
+            write32le(ptr, val);
+            return;
+	case R_AARCH64_PREL32:
+	    write32le(ptr, val - addr);
+	    return;
+        case R_AARCH64_MOVW_UABS_G0_NC:
+            write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
+                            (val & 0xffff) << 5));
+            return;
+        case R_AARCH64_MOVW_UABS_G1_NC:
+            write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
+                            (val >> 16 & 0xffff) << 5));
+            return;
+        case R_AARCH64_MOVW_UABS_G2_NC:
+            write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
+                            (val >> 32 & 0xffff) << 5));
+            return;
+        case R_AARCH64_MOVW_UABS_G3:
+            write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
+                            (val >> 48 & 0xffff) << 5));
+            return;
+        case R_AARCH64_ADR_PREL_PG_HI21: {
+            uint64_t off = (val >> 12) - (addr >> 12);
+            if ((off + ((uint64_t)1 << 20)) >> 21)
+                tcc_error("R_AARCH64_ADR_PREL_PG_HI21 relocation failed");
+            write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
+                            (off & 0x1ffffc) << 3 | (off & 3) << 29));
+            return;
+        }
+        case R_AARCH64_ADD_ABS_LO12_NC:
+            write32le(ptr, ((read32le(ptr) & 0xffc003ff) |
+                            (val & 0xfff) << 10));
+            return;
+        case R_AARCH64_JUMP26:
+        case R_AARCH64_CALL26:
+#ifdef DEBUG_RELOC
+	    printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val,
+		    (char *) symtab_section->link->data + sym->st_name);
+#endif
+            if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc)
+                tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed"
+                          " (val=%lx, addr=%lx)", val, addr);
+            write32le(ptr, (0x14000000 |
+                            (uint32_t)(type == R_AARCH64_CALL26) << 31 |
+                            ((val - addr) >> 2 & 0x3ffffff)));
+            return;
+        case R_AARCH64_ADR_GOT_PAGE: {
+            uint64_t off =
+                (((s1->got->sh_addr +
+                   s1->sym_attrs[sym_index].got_offset) >> 12) - (addr >> 12));
+            if ((off + ((uint64_t)1 << 20)) >> 21)
+                tcc_error("R_AARCH64_ADR_GOT_PAGE relocation failed");
+            write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
+                            (off & 0x1ffffc) << 3 | (off & 3) << 29));
+            return;
+        }
+        case R_AARCH64_LD64_GOT_LO12_NC:
+            write32le(ptr,
+                      ((read32le(ptr) & 0xfff803ff) |
+                       ((s1->got->sh_addr +
+                         s1->sym_attrs[sym_index].got_offset) & 0xff8) << 7));
+            return;
+        case R_AARCH64_COPY:
+            return;
+        case R_AARCH64_GLOB_DAT:
+        case R_AARCH64_JUMP_SLOT:
+            /* They don't need addend */
+#ifdef DEBUG_RELOC
+	    printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr,
+		    val - rel->r_addend,
+		    (char *) symtab_section->link->data + sym->st_name);
+#endif
+            write64le(ptr, val - rel->r_addend);
+            return;
+        case R_AARCH64_RELATIVE:
+#ifdef TCC_TARGET_PE
+            add32le(ptr, val - s1->pe_imagebase);
+#endif
+            /* do nothing */
+            return;
+        default:
+            fprintf(stderr, "FIXME: handle reloc type %x at %x [%p] to %x\n",
+                    type, (unsigned)addr, ptr, (unsigned)val);
+            return;
+    }
+}
+
+#endif /* !TARGET_DEFS_ONLY */
Index: EcnlProtoTool/trunk/tcc-0.9.27/c67-gen.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/c67-gen.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/c67-gen.c	(revision 331)
@@ -0,0 +1,2540 @@
+/*
+ *  TMS320C67xx code generator for TCC
+ * 
+ *  Copyright (c) 2001, 2002 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef TARGET_DEFS_ONLY
+
+/* #define ASSEMBLY_LISTING_C67 */
+
+/* number of available registers */
+#define NB_REGS            24
+
+/* a register can belong to several classes. The classes must be
+   sorted from more general to more precise (see gv2() code which does
+   assumptions on it). */
+#define RC_INT     0x0001	/* generic integer register */
+#define RC_FLOAT   0x0002	/* generic float register */
+#define RC_EAX     0x0004
+#define RC_ST0     0x0008
+#define RC_ECX     0x0010
+#define RC_EDX     0x0020
+#define RC_INT_BSIDE  0x00000040	/* generic integer register  on b side */
+#define RC_C67_A4     0x00000100
+#define RC_C67_A5     0x00000200
+#define RC_C67_B4     0x00000400
+#define RC_C67_B5     0x00000800
+#define RC_C67_A6     0x00001000
+#define RC_C67_A7     0x00002000
+#define RC_C67_B6     0x00004000
+#define RC_C67_B7     0x00008000
+#define RC_C67_A8     0x00010000
+#define RC_C67_A9     0x00020000
+#define RC_C67_B8     0x00040000
+#define RC_C67_B9     0x00080000
+#define RC_C67_A10    0x00100000
+#define RC_C67_A11    0x00200000
+#define RC_C67_B10    0x00400000
+#define RC_C67_B11    0x00800000
+#define RC_C67_A12    0x01000000
+#define RC_C67_A13    0x02000000
+#define RC_C67_B12    0x04000000
+#define RC_C67_B13    0x08000000
+#define RC_IRET    RC_C67_A4	/* function return: integer register */
+#define RC_LRET    RC_C67_A5	/* function return: second integer register */
+#define RC_FRET    RC_C67_A4	/* function return: float register */
+
+/* pretty names for the registers */
+enum {
+    TREG_EAX = 0,		// really A2
+    TREG_ECX,			// really A3
+    TREG_EDX,			// really B0
+    TREG_ST0,			// really B1
+    TREG_C67_A4,
+    TREG_C67_A5,
+    TREG_C67_B4,
+    TREG_C67_B5,
+    TREG_C67_A6,
+    TREG_C67_A7,
+    TREG_C67_B6,
+    TREG_C67_B7,
+    TREG_C67_A8,
+    TREG_C67_A9,
+    TREG_C67_B8,
+    TREG_C67_B9,
+    TREG_C67_A10,
+    TREG_C67_A11,
+    TREG_C67_B10,
+    TREG_C67_B11,
+    TREG_C67_A12,
+    TREG_C67_A13,
+    TREG_C67_B12,
+    TREG_C67_B13,
+};
+
+/* return registers for function */
+#define REG_IRET TREG_C67_A4	/* single word int return register */
+#define REG_LRET TREG_C67_A5	/* second word return register (for long long) */
+#define REG_FRET TREG_C67_A4	/* float return register */
+
+/* defined if function parameters must be evaluated in reverse order */
+/* #define INVERT_FUNC_PARAMS */
+
+/* defined if structures are passed as pointers. Otherwise structures
+   are directly pushed on stack. */
+/* #define FUNC_STRUCT_PARAM_AS_PTR */
+
+/* pointer size, in bytes */
+#define PTR_SIZE 4
+
+/* long double size and alignment, in bytes */
+#define LDOUBLE_SIZE  12
+#define LDOUBLE_ALIGN 4
+/* maximum alignment (for aligned attribute support) */
+#define MAX_ALIGN     8
+
+/******************************************************/
+#else /* ! TARGET_DEFS_ONLY */
+/******************************************************/
+#include "tcc.h"
+
+ST_DATA const int reg_classes[NB_REGS] = {
+    /* eax */ RC_INT | RC_FLOAT | RC_EAX, 
+    // only allow even regs for floats (allow for doubles)
+    /* ecx */ RC_INT | RC_ECX,
+    /* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX,
+    // only allow even regs for floats (allow for doubles)
+    /* st0 */ RC_INT | RC_INT_BSIDE | RC_ST0,
+    /* A4  */ RC_C67_A4,
+    /* A5  */ RC_C67_A5,
+    /* B4  */ RC_C67_B4,
+    /* B5  */ RC_C67_B5,
+    /* A6  */ RC_C67_A6,
+    /* A7  */ RC_C67_A7,
+    /* B6  */ RC_C67_B6,
+    /* B7  */ RC_C67_B7,
+    /* A8  */ RC_C67_A8,
+    /* A9  */ RC_C67_A9,
+    /* B8  */ RC_C67_B8,
+    /* B9  */ RC_C67_B9,
+    /* A10  */ RC_C67_A10,
+    /* A11  */ RC_C67_A11,
+    /* B10  */ RC_C67_B10,
+    /* B11  */ RC_C67_B11,
+    /* A12  */ RC_C67_A10,
+    /* A13  */ RC_C67_A11,
+    /* B12  */ RC_C67_B10,
+    /* B13  */ RC_C67_B11
+};
+
+// although tcc thinks it is passing parameters on the stack,
+// the C67 really passes up to the first 10 params in special
+// regs or regs pairs (for 64 bit params).  So keep track of
+// the stack offsets so we can translate to the appropriate 
+// reg (pair)
+
+#define NoCallArgsPassedOnStack 10
+int NoOfCurFuncArgs;
+int TranslateStackToReg[NoCallArgsPassedOnStack];
+int ParamLocOnStack[NoCallArgsPassedOnStack];
+int TotalBytesPushedOnStack;
+
+#ifndef FALSE
+# define FALSE 0
+# define TRUE 1
+#endif
+
+#undef BOOL
+#define BOOL int
+
+#define ALWAYS_ASSERT(x) \
+do {\
+   if (!(x))\
+       tcc_error("internal compiler error file at %s:%d", __FILE__, __LINE__);\
+} while (0)
+
+/******************************************************/
+static unsigned long func_sub_sp_offset;
+static int func_ret_sub;
+
+static BOOL C67_invert_test;
+static int C67_compare_reg;
+
+#ifdef ASSEMBLY_LISTING_C67
+FILE *f = NULL;
+#endif
+
+void C67_g(int c)
+{
+    int ind1;
+    if (nocode_wanted)
+        return;
+#ifdef ASSEMBLY_LISTING_C67
+    fprintf(f, " %08X", c);
+#endif
+    ind1 = ind + 4;
+    if (ind1 > (int) cur_text_section->data_allocated)
+	section_realloc(cur_text_section, ind1);
+    cur_text_section->data[ind] = c & 0xff;
+    cur_text_section->data[ind + 1] = (c >> 8) & 0xff;
+    cur_text_section->data[ind + 2] = (c >> 16) & 0xff;
+    cur_text_section->data[ind + 3] = (c >> 24) & 0xff;
+    ind = ind1;
+}
+
+
+/* output a symbol and patch all calls to it */
+void gsym_addr(int t, int a)
+{
+    int n, *ptr;
+    while (t) {
+	ptr = (int *) (cur_text_section->data + t);
+	{
+	    Sym *sym;
+
+	    // extract 32 bit address from MVKH/MVKL
+	    n = ((*ptr >> 7) & 0xffff);
+	    n |= ((*(ptr + 1) >> 7) & 0xffff) << 16;
+
+	    // define a label that will be relocated
+
+	    sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0);
+	    greloc(cur_text_section, sym, t, R_C60LO16);
+	    greloc(cur_text_section, sym, t + 4, R_C60HI16);
+
+	    // clear out where the pointer was
+
+	    *ptr &= ~(0xffff << 7);
+	    *(ptr + 1) &= ~(0xffff << 7);
+	}
+	t = n;
+    }
+}
+
+void gsym(int t)
+{
+    gsym_addr(t, ind);
+}
+
+// these are regs that tcc doesn't really know about, 
+// but assign them unique values so the mapping routines
+// can distinguish them
+
+#define C67_A0 105
+#define C67_SP 106
+#define C67_B3 107
+#define C67_FP 108
+#define C67_B2 109
+#define C67_CREG_ZERO -1	/* Special code for no condition reg test */
+
+
+int ConvertRegToRegClass(int r)
+{
+    // only works for A4-B13
+
+    return RC_C67_A4 << (r - TREG_C67_A4);
+}
+
+
+// map TCC reg to C67 reg number
+
+int C67_map_regn(int r)
+{
+    if (r == 0)			// normal tcc regs
+	return 0x2;		// A2
+    else if (r == 1)		// normal tcc regs
+	return 3;		// A3
+    else if (r == 2)		// normal tcc regs
+	return 0;		// B0
+    else if (r == 3)		// normal tcc regs
+	return 1;		// B1
+    else if (r >= TREG_C67_A4 && r <= TREG_C67_B13)	// these form a pattern of alt pairs
+	return (((r & 0xfffffffc) >> 1) | (r & 1)) + 2;
+    else if (r == C67_A0)
+	return 0;		// set to A0 (offset reg)
+    else if (r == C67_B2)
+	return 2;		// set to B2 (offset reg)
+    else if (r == C67_B3)
+	return 3;		// set to B3 (return address reg)
+    else if (r == C67_SP)
+	return 15;		// set to SP (B15) (offset reg)
+    else if (r == C67_FP)
+	return 15;		// set to FP (A15) (offset reg)
+    else if (r == C67_CREG_ZERO)
+	return 0;		// Special code for no condition reg test
+    else
+	ALWAYS_ASSERT(FALSE);
+
+    return 0;
+}
+
+// mapping from tcc reg number to 
+// C67 register to condition code field
+//
+// valid condition code regs are:
+//
+// tcc reg 2 ->B0 -> 1
+// tcc reg 3 ->B1 -> 2
+// tcc reg 0 -> A2 -> 5
+// tcc reg 1 -> A3 -> X
+// tcc reg      B2 -> 3
+
+int C67_map_regc(int r)
+{
+    if (r == 0)			// normal tcc regs
+	return 0x5;
+    else if (r == 2)		// normal tcc regs
+	return 0x1;
+    else if (r == 3)		// normal tcc regs
+	return 0x2;
+    else if (r == C67_B2)	// normal tcc regs
+	return 0x3;
+    else if (r == C67_CREG_ZERO)
+	return 0;		// Special code for no condition reg test
+    else
+	ALWAYS_ASSERT(FALSE);
+
+    return 0;
+}
+
+
+// map TCC reg to C67 reg side A or B
+
+int C67_map_regs(int r)
+{
+    if (r == 0)			// normal tcc regs
+	return 0x0;
+    else if (r == 1)		// normal tcc regs
+	return 0x0;
+    else if (r == 2)		// normal tcc regs
+	return 0x1;
+    else if (r == 3)		// normal tcc regs
+	return 0x1;
+    else if (r >= TREG_C67_A4 && r <= TREG_C67_B13)	// these form a pattern of alt pairs
+	return (r & 2) >> 1;
+    else if (r == C67_A0)
+	return 0;		// set to A side 
+    else if (r == C67_B2)
+	return 1;		// set to B side 
+    else if (r == C67_B3)
+	return 1;		// set to B side
+    else if (r == C67_SP)
+	return 0x1;		// set to SP (B15) B side 
+    else if (r == C67_FP)
+	return 0x0;		// set to FP (A15) A side 
+    else
+	ALWAYS_ASSERT(FALSE);
+
+    return 0;
+}
+
+int C67_map_S12(char *s)
+{
+    if (strstr(s, ".S1") != NULL)
+	return 0;
+    else if (strcmp(s, ".S2"))
+	return 1;
+    else
+	ALWAYS_ASSERT(FALSE);
+
+    return 0;
+}
+
+int C67_map_D12(char *s)
+{
+    if (strstr(s, ".D1") != NULL)
+	return 0;
+    else if (strcmp(s, ".D2"))
+	return 1;
+    else
+	ALWAYS_ASSERT(FALSE);
+
+    return 0;
+}
+
+
+
+void C67_asm(char *s, int a, int b, int c)
+{
+    BOOL xpath;
+
+#ifdef ASSEMBLY_LISTING_C67
+    if (!f) {
+	f = fopen("TCC67_out.txt", "wt");
+    }
+    fprintf(f, "%04X ", ind);
+#endif
+
+    if (strstr(s, "MVKL") == s) {
+	C67_g((C67_map_regn(b) << 23) |
+	      ((a & 0xffff) << 7) | (0x0a << 2) | (C67_map_regs(b) << 1));
+    } else if (strstr(s, "MVKH") == s) {
+	C67_g((C67_map_regn(b) << 23) |
+	      (((a >> 16) & 0xffff) << 7) |
+	      (0x1a << 2) | (C67_map_regs(b) << 1));
+    } else if (strstr(s, "STW.D SP POST DEC") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//src
+	      (15 << 18) |	//SP B15
+	      (2 << 13) |	//ucst5 (must keep 8 byte boundary !!)
+	      (0xa << 9) |	//mode a = post dec ucst
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (1 << 7) |	//y D1/D2 use B side
+	      (7 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of src
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "STB.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//src
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (0 << 7) |	//y D1/D2 A side
+	      (3 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of src
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "STH.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//src
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (0 << 7) |	//y D1/D2 A side
+	      (5 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of src
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "STB.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//src
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (0 << 7) |	//y D1/D2 A side
+	      (3 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of src
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "STH.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//src
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (0 << 7) |	//y D1/D2 A side
+	      (5 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of src
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "STW.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//src
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (0 << 7) |	//y D1/D2 A side
+	      (7 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of src
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "STW.D *") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//src
+	      (C67_map_regn(b) << 18) |	//base reg A0
+	      (0 << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (C67_map_regs(b) << 7) |	//y D1/D2 base reg side
+	      (7 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of src
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "STH.D *") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//src
+	      (C67_map_regn(b) << 18) |	//base reg A0
+	      (0 << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (C67_map_regs(b) << 7) |	//y D1/D2 base reg side
+	      (5 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of src
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "STB.D *") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//src
+	      (C67_map_regn(b) << 18) |	//base reg A0
+	      (0 << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (C67_map_regs(b) << 7) |	//y D1/D2 base reg side
+	      (3 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of src
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "STW.D +*") == s) {
+	ALWAYS_ASSERT(c < 32);
+	C67_g((C67_map_regn(a) << 23) |	//src
+	      (C67_map_regn(b) << 18) |	//base reg A0
+	      (c << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (C67_map_regs(b) << 7) |	//y D1/D2 base reg side
+	      (7 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of src
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDW.D SP PRE INC") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//dst
+	      (15 << 18) |	//base reg B15
+	      (2 << 13) |	//ucst5 (must keep 8 byte boundary)
+	      (9 << 9) |	//mode 9 = pre inc ucst5
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (1 << 7) |	//y D1/D2  B side
+	      (6 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDDW.D SP PRE INC") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//dst
+	      (15 << 18) |	//base reg B15
+	      (1 << 13) |	//ucst5 (must keep 8 byte boundary)
+	      (9 << 9) |	//mode 9 = pre inc ucst5
+	      (1 << 8) |	//r (LDDW bit 1)
+	      (1 << 7) |	//y D1/D2  B side
+	      (6 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDW.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//dst
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (0 << 7) |	//y D1/D2  A side
+	      (6 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDDW.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//dst
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (1 << 8) |	//r (LDDW bit 1)
+	      (0 << 7) |	//y D1/D2  A side
+	      (6 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDH.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//dst
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (0 << 7) |	//y D1/D2  A side
+	      (4 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDB.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//dst
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (0 << 7) |	//y D1/D2  A side
+	      (2 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDHU.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//dst
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (0 << 7) |	//y D1/D2  A side
+	      (0 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDBU.D *+SP[A0]") == s) {
+	C67_g((C67_map_regn(a) << 23) |	//dst
+	      (15 << 18) |	//base reg A15
+	      (0 << 13) |	//offset reg A0
+	      (5 << 9) |	//mode 5 = pos offset, base reg + off reg
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (0 << 7) |	//y D1/D2  A side
+	      (1 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(a) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDW.D *") == s) {
+	C67_g((C67_map_regn(b) << 23) |	//dst
+	      (C67_map_regn(a) << 18) |	//base reg A15
+	      (0 << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (C67_map_regs(a) << 7) |	//y D1/D2  src side
+	      (6 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(b) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDDW.D *") == s) {
+	C67_g((C67_map_regn(b) << 23) |	//dst
+	      (C67_map_regn(a) << 18) |	//base reg A15
+	      (0 << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (1 << 8) |	//r (LDDW bit 1)
+	      (C67_map_regs(a) << 7) |	//y D1/D2  src side
+	      (6 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(b) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDH.D *") == s) {
+	C67_g((C67_map_regn(b) << 23) |	//dst
+	      (C67_map_regn(a) << 18) |	//base reg A15
+	      (0 << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (C67_map_regs(a) << 7) |	//y D1/D2  src side
+	      (4 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(b) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDB.D *") == s) {
+	C67_g((C67_map_regn(b) << 23) |	//dst
+	      (C67_map_regn(a) << 18) |	//base reg A15
+	      (0 << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (C67_map_regs(a) << 7) |	//y D1/D2  src side
+	      (2 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(b) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDHU.D *") == s) {
+	C67_g((C67_map_regn(b) << 23) |	//dst
+	      (C67_map_regn(a) << 18) |	//base reg A15
+	      (0 << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (C67_map_regs(a) << 7) |	//y D1/D2  src side
+	      (0 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(b) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDBU.D *") == s) {
+	C67_g((C67_map_regn(b) << 23) |	//dst
+	      (C67_map_regn(a) << 18) |	//base reg A15
+	      (0 << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (C67_map_regs(a) << 7) |	//y D1/D2  src side
+	      (1 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(b) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "LDW.D +*") == s) {
+	C67_g((C67_map_regn(b) << 23) |	//dst
+	      (C67_map_regn(a) << 18) |	//base reg A15
+	      (1 << 13) |	//cst5
+	      (1 << 9) |	//mode 1 = pos cst offset
+	      (0 << 8) |	//r (LDDW bit 0)
+	      (C67_map_regs(a) << 7) |	//y D1/D2  src side
+	      (6 << 4) |	//ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU 
+	      (1 << 2) |	//opcode
+	      (C67_map_regs(b) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "CMPLTSP") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x3a << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "CMPGTSP") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x39 << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "CMPEQSP") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x38 << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    }
+
+    else if (strstr(s, "CMPLTDP") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x2a << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "CMPGTDP") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x29 << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "CMPEQDP") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x28 << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "CMPLT") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x57 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "CMPGT") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x47 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "CMPEQ") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x53 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "CMPLTU") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x5f << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "CMPGTU") == s) {
+	xpath = C67_map_regs(a) ^ C67_map_regs(b);
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1
+	      (xpath << 12) |	//x use cross path for src2
+	      (0x4f << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side for reg c
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "B DISP") == s) {
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//z
+	      (a << 7) |	//cnst
+	      (0x4 << 2) |	//opcode fixed
+	      (0 << 1) |	//S0/S1
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "B.") == s) {
+	xpath = C67_map_regs(c) ^ 1;
+
+	C67_g((C67_map_regc(b) << 29) |	//creg
+	      (a << 28) |	//inv
+	      (0 << 23) |	//dst
+	      (C67_map_regn(c) << 18) |	//src2
+	      (0 << 13) |	//
+	      (xpath << 12) |	//x cross path if !B side
+	      (0xd << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (1 << 1) |	//must be S2
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "MV.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (0 << 13) |	//src1 (cst5)
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x2 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "SPTRUNC.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (0 << 13) |	//src1 NA
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0xb << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "DPTRUNC.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      ((C67_map_regn(b) + 1) << 18) |	//src2   WEIRD CPU must specify odd reg for some reason
+	      (0 << 13) |	//src1 NA
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x1 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "INTSP.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2   
+	      (0 << 13) |	//src1 NA
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x4a << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "INTSPU.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2  
+	      (0 << 13) |	//src1 NA
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x49 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "INTDP.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2  
+	      (0 << 13) |	//src1 NA
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x39 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "INTDPU.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      ((C67_map_regn(b) + 1) << 18) |	//src2   WEIRD CPU must specify odd reg for some reason
+	      (0 << 13) |	//src1 NA
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x3b << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "SPDP.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (0 << 13) |	//src1 NA
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x2 << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "DPSP.L") == s) {
+	ALWAYS_ASSERT(C67_map_regs(b) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      ((C67_map_regn(b) + 1) << 18) |	//src2 WEIRD CPU must specify odd reg for some reason
+	      (0 << 13) |	//src1 NA
+	      (0 << 12) |	//x cross path if opposite sides
+	      (0x9 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "ADD.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x3 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "SUB.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x7 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "OR.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x7f << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "AND.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x7b << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "XOR.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x6f << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "ADDSP.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x10 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "ADDDP.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x18 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "SUBSP.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x11 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "SUBDP.L") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x19 << 5) |	//opcode
+	      (0x6 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "MPYSP.M") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x1c << 7) |	//opcode
+	      (0x0 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "MPYDP.M") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2 (possible x path)
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x0e << 7) |	//opcode
+	      (0x0 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "MPYI.M") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(a) == C67_map_regs(c));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1 (cst5)
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x4 << 7) |	//opcode
+	      (0x0 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "SHR.S") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x37 << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "SHRU.S") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x27 << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "SHL.S") == s) {
+	xpath = C67_map_regs(b) ^ C67_map_regs(c);
+
+	ALWAYS_ASSERT(C67_map_regs(c) == C67_map_regs(a));
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(c) << 23) |	//dst
+	      (C67_map_regn(b) << 18) |	//src2
+	      (C67_map_regn(a) << 13) |	//src1 
+	      (xpath << 12) |	//x cross path if opposite sides
+	      (0x33 << 6) |	//opcode
+	      (0x8 << 2) |	//opcode fixed
+	      (C67_map_regs(c) << 1) |	//side of dest
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "||ADDK") == s) {
+	xpath = 0;		// no xpath required just use the side of the src/dst
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(b) << 23) |	//dst
+	      (a << 07) |	//scst16
+	      (0x14 << 2) |	//opcode fixed
+	      (C67_map_regs(b) << 1) |	//side of dst
+	      (1 << 0));	//parallel
+    } else if (strstr(s, "ADDK") == s) {
+	xpath = 0;		// no xpath required just use the side of the src/dst
+
+	C67_g((0 << 29) |	//creg
+	      (0 << 28) |	//inv
+	      (C67_map_regn(b) << 23) |	//dst
+	      (a << 07) |	//scst16
+	      (0x14 << 2) |	//opcode fixed
+	      (C67_map_regs(b) << 1) |	//side of dst
+	      (0 << 0));	//parallel
+    } else if (strstr(s, "NOP") == s) {
+	C67_g(((a - 1) << 13) |	//no of cycles
+	      (0 << 0));	//parallel
+    } else
+	ALWAYS_ASSERT(FALSE);
+
+#ifdef ASSEMBLY_LISTING_C67
+    fprintf(f, " %s %d %d %d\n", s, a, b, c);
+#endif
+
+}
+
+//r=reg to load, fr=from reg, symbol for relocation, constant
+
+void C67_MVKL(int r, int fc)
+{
+    C67_asm("MVKL.", fc, r, 0);
+}
+
+void C67_MVKH(int r, int fc)
+{
+    C67_asm("MVKH.", fc, r, 0);
+}
+
+void C67_STB_SP_A0(int r)
+{
+    C67_asm("STB.D *+SP[A0]", r, 0, 0);	// STB  r,*+SP[A0]
+}
+
+void C67_STH_SP_A0(int r)
+{
+    C67_asm("STH.D *+SP[A0]", r, 0, 0);	// STH  r,*+SP[A0]
+}
+
+void C67_STW_SP_A0(int r)
+{
+    C67_asm("STW.D *+SP[A0]", r, 0, 0);	// STW  r,*+SP[A0]
+}
+
+void C67_STB_PTR(int r, int r2)
+{
+    C67_asm("STB.D *", r, r2, 0);	// STB  r, *r2
+}
+
+void C67_STH_PTR(int r, int r2)
+{
+    C67_asm("STH.D *", r, r2, 0);	// STH  r, *r2
+}
+
+void C67_STW_PTR(int r, int r2)
+{
+    C67_asm("STW.D *", r, r2, 0);	// STW  r, *r2
+}
+
+void C67_STW_PTR_PRE_INC(int r, int r2, int n)
+{
+    C67_asm("STW.D +*", r, r2, n);	// STW  r, *+r2
+}
+
+void C67_PUSH(int r)
+{
+    C67_asm("STW.D SP POST DEC", r, 0, 0);	// STW  r,*SP--
+}
+
+void C67_LDW_SP_A0(int r)
+{
+    C67_asm("LDW.D *+SP[A0]", r, 0, 0);	// LDW  *+SP[A0],r
+}
+
+void C67_LDDW_SP_A0(int r)
+{
+    C67_asm("LDDW.D *+SP[A0]", r, 0, 0);	// LDDW  *+SP[A0],r
+}
+
+void C67_LDH_SP_A0(int r)
+{
+    C67_asm("LDH.D *+SP[A0]", r, 0, 0);	// LDH  *+SP[A0],r
+}
+
+void C67_LDB_SP_A0(int r)
+{
+    C67_asm("LDB.D *+SP[A0]", r, 0, 0);	// LDB  *+SP[A0],r
+}
+
+void C67_LDHU_SP_A0(int r)
+{
+    C67_asm("LDHU.D *+SP[A0]", r, 0, 0);	// LDHU  *+SP[A0],r
+}
+
+void C67_LDBU_SP_A0(int r)
+{
+    C67_asm("LDBU.D *+SP[A0]", r, 0, 0);	// LDBU  *+SP[A0],r
+}
+
+void C67_LDW_PTR(int r, int r2)
+{
+    C67_asm("LDW.D *", r, r2, 0);	// LDW  *r,r2
+}
+
+void C67_LDDW_PTR(int r, int r2)
+{
+    C67_asm("LDDW.D *", r, r2, 0);	// LDDW  *r,r2
+}
+
+void C67_LDH_PTR(int r, int r2)
+{
+    C67_asm("LDH.D *", r, r2, 0);	// LDH  *r,r2
+}
+
+void C67_LDB_PTR(int r, int r2)
+{
+    C67_asm("LDB.D *", r, r2, 0);	// LDB  *r,r2
+}
+
+void C67_LDHU_PTR(int r, int r2)
+{
+    C67_asm("LDHU.D *", r, r2, 0);	// LDHU  *r,r2
+}
+
+void C67_LDBU_PTR(int r, int r2)
+{
+    C67_asm("LDBU.D *", r, r2, 0);	// LDBU  *r,r2
+}
+
+void C67_LDW_PTR_PRE_INC(int r, int r2)
+{
+    C67_asm("LDW.D +*", r, r2, 0);	// LDW  *+r,r2
+}
+
+void C67_POP(int r)
+{
+    C67_asm("LDW.D SP PRE INC", r, 0, 0);	// LDW  *++SP,r
+}
+
+void C67_POP_DW(int r)
+{
+    C67_asm("LDDW.D SP PRE INC", r, 0, 0);	// LDDW  *++SP,r
+}
+
+void C67_CMPLT(int s1, int s2, int dst)
+{
+    C67_asm("CMPLT.L1", s1, s2, dst);
+}
+
+void C67_CMPGT(int s1, int s2, int dst)
+{
+    C67_asm("CMPGT.L1", s1, s2, dst);
+}
+
+void C67_CMPEQ(int s1, int s2, int dst)
+{
+    C67_asm("CMPEQ.L1", s1, s2, dst);
+}
+
+void C67_CMPLTU(int s1, int s2, int dst)
+{
+    C67_asm("CMPLTU.L1", s1, s2, dst);
+}
+
+void C67_CMPGTU(int s1, int s2, int dst)
+{
+    C67_asm("CMPGTU.L1", s1, s2, dst);
+}
+
+
+void C67_CMPLTSP(int s1, int s2, int dst)
+{
+    C67_asm("CMPLTSP.S1", s1, s2, dst);
+}
+
+void C67_CMPGTSP(int s1, int s2, int dst)
+{
+    C67_asm("CMPGTSP.S1", s1, s2, dst);
+}
+
+void C67_CMPEQSP(int s1, int s2, int dst)
+{
+    C67_asm("CMPEQSP.S1", s1, s2, dst);
+}
+
+void C67_CMPLTDP(int s1, int s2, int dst)
+{
+    C67_asm("CMPLTDP.S1", s1, s2, dst);
+}
+
+void C67_CMPGTDP(int s1, int s2, int dst)
+{
+    C67_asm("CMPGTDP.S1", s1, s2, dst);
+}
+
+void C67_CMPEQDP(int s1, int s2, int dst)
+{
+    C67_asm("CMPEQDP.S1", s1, s2, dst);
+}
+
+
+void C67_IREG_B_REG(int inv, int r1, int r2)	// [!R] B  r2
+{
+    C67_asm("B.S2", inv, r1, r2);
+}
+
+
+// call with how many 32 bit words to skip
+// (0 would branch to the branch instruction)
+
+void C67_B_DISP(int disp)	//  B  +2  Branch with constant displacement
+{
+    // Branch point is relative to the 8 word fetch packet
+    //
+    // we will assume the text section always starts on an 8 word (32 byte boundary)
+    //
+    // so add in how many words into the fetch packet the branch is
+
+
+    C67_asm("B DISP", disp + ((ind & 31) >> 2), 0, 0);
+}
+
+void C67_NOP(int n)
+{
+    C67_asm("NOP", n, 0, 0);
+}
+
+void C67_ADDK(int n, int r)
+{
+    ALWAYS_ASSERT(abs(n) < 32767);
+
+    C67_asm("ADDK", n, r, 0);
+}
+
+void C67_ADDK_PARALLEL(int n, int r)
+{
+    ALWAYS_ASSERT(abs(n) < 32767);
+
+    C67_asm("||ADDK", n, r, 0);
+}
+
+void C67_Adjust_ADDK(int *inst, int n)
+{
+    ALWAYS_ASSERT(abs(n) < 32767);
+
+    *inst = (*inst & (~(0xffff << 7))) | ((n & 0xffff) << 7);
+}
+
+void C67_MV(int r, int v)
+{
+    C67_asm("MV.L", 0, r, v);
+}
+
+
+void C67_DPTRUNC(int r, int v)
+{
+    C67_asm("DPTRUNC.L", 0, r, v);
+}
+
+void C67_SPTRUNC(int r, int v)
+{
+    C67_asm("SPTRUNC.L", 0, r, v);
+}
+
+void C67_INTSP(int r, int v)
+{
+    C67_asm("INTSP.L", 0, r, v);
+}
+
+void C67_INTDP(int r, int v)
+{
+    C67_asm("INTDP.L", 0, r, v);
+}
+
+void C67_INTSPU(int r, int v)
+{
+    C67_asm("INTSPU.L", 0, r, v);
+}
+
+void C67_INTDPU(int r, int v)
+{
+    C67_asm("INTDPU.L", 0, r, v);
+}
+
+void C67_SPDP(int r, int v)
+{
+    C67_asm("SPDP.L", 0, r, v);
+}
+
+void C67_DPSP(int r, int v)	// note regs must be on the same side
+{
+    C67_asm("DPSP.L", 0, r, v);
+}
+
+void C67_ADD(int r, int v)
+{
+    C67_asm("ADD.L", v, r, v);
+}
+
+void C67_SUB(int r, int v)
+{
+    C67_asm("SUB.L", v, r, v);
+}
+
+void C67_AND(int r, int v)
+{
+    C67_asm("AND.L", v, r, v);
+}
+
+void C67_OR(int r, int v)
+{
+    C67_asm("OR.L", v, r, v);
+}
+
+void C67_XOR(int r, int v)
+{
+    C67_asm("XOR.L", v, r, v);
+}
+
+void C67_ADDSP(int r, int v)
+{
+    C67_asm("ADDSP.L", v, r, v);
+}
+
+void C67_SUBSP(int r, int v)
+{
+    C67_asm("SUBSP.L", v, r, v);
+}
+
+void C67_MPYSP(int r, int v)
+{
+    C67_asm("MPYSP.M", v, r, v);
+}
+
+void C67_ADDDP(int r, int v)
+{
+    C67_asm("ADDDP.L", v, r, v);
+}
+
+void C67_SUBDP(int r, int v)
+{
+    C67_asm("SUBDP.L", v, r, v);
+}
+
+void C67_MPYDP(int r, int v)
+{
+    C67_asm("MPYDP.M", v, r, v);
+}
+
+void C67_MPYI(int r, int v)
+{
+    C67_asm("MPYI.M", v, r, v);
+}
+
+void C67_SHL(int r, int v)
+{
+    C67_asm("SHL.S", r, v, v);
+}
+
+void C67_SHRU(int r, int v)
+{
+    C67_asm("SHRU.S", r, v, v);
+}
+
+void C67_SHR(int r, int v)
+{
+    C67_asm("SHR.S", r, v, v);
+}
+
+
+
+/* load 'r' from value 'sv' */
+void load(int r, SValue * sv)
+{
+    int v, t, ft, fc, fr, size = 0, element;
+    BOOL Unsigned = FALSE;
+    SValue v1;
+
+    fr = sv->r;
+    ft = sv->type.t;
+    fc = sv->c.i;
+
+    v = fr & VT_VALMASK;
+    if (fr & VT_LVAL) {
+	if (v == VT_LLOCAL) {
+	    v1.type.t = VT_INT;
+	    v1.r = VT_LOCAL | VT_LVAL;
+	    v1.c.i = fc;
+	    load(r, &v1);
+	    fr = r;
+	} else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
+	    tcc_error("long double not supported");
+	} else if ((ft & VT_TYPE) == VT_BYTE) {
+	    size = 1;
+	} else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
+	    size = 1;
+	    Unsigned = TRUE;
+	} else if ((ft & VT_TYPE) == VT_SHORT) {
+	    size = 2;
+	} else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {
+	    size = 2;
+	    Unsigned = TRUE;
+	} else if ((ft & VT_BTYPE) == VT_DOUBLE) {
+	    size = 8;
+	} else {
+	    size = 4;
+	}
+
+	// check if fc is a positive reference on the stack, 
+	// if it is tcc is referencing what it thinks is a parameter
+	// on the stack, so check if it is really in a register.
+
+
+	if (v == VT_LOCAL && fc > 0) {
+	    int stack_pos = 8;
+
+	    for (t = 0; t < NoCallArgsPassedOnStack; t++) {
+		if (fc == stack_pos)
+		    break;
+
+		stack_pos += TranslateStackToReg[t];
+	    }
+
+	    // param has been pushed on stack, get it like a local var
+
+	    fc = ParamLocOnStack[t] - 8;
+	}
+
+	if ((fr & VT_VALMASK) < VT_CONST)	// check for pure indirect
+	{
+	    if (size == 1) {
+		if (Unsigned)
+		    C67_LDBU_PTR(v, r);	// LDBU  *v,r
+		else
+		    C67_LDB_PTR(v, r);	// LDB  *v,r
+	    } else if (size == 2) {
+		if (Unsigned)
+		    C67_LDHU_PTR(v, r);	// LDHU  *v,r
+		else
+		    C67_LDH_PTR(v, r);	// LDH  *v,r
+	    } else if (size == 4) {
+		C67_LDW_PTR(v, r);	// LDW  *v,r
+	    } else if (size == 8) {
+		C67_LDDW_PTR(v, r);	// LDDW  *v,r
+	    }
+
+	    C67_NOP(4);		// NOP 4
+	    return;
+	} else if (fr & VT_SYM) {
+	    greloc(cur_text_section, sv->sym, ind, R_C60LO16);	// rem the inst need to be patched
+	    greloc(cur_text_section, sv->sym, ind + 4, R_C60HI16);
+
+
+	    C67_MVKL(C67_A0, fc);	//r=reg to load,  constant
+	    C67_MVKH(C67_A0, fc);	//r=reg to load,  constant
+
+
+	    if (size == 1) {
+		if (Unsigned)
+		    C67_LDBU_PTR(C67_A0, r);	// LDBU  *A0,r
+		else
+		    C67_LDB_PTR(C67_A0, r);	// LDB  *A0,r
+	    } else if (size == 2) {
+		if (Unsigned)
+		    C67_LDHU_PTR(C67_A0, r);	// LDHU  *A0,r
+		else
+		    C67_LDH_PTR(C67_A0, r);	// LDH  *A0,r
+	    } else if (size == 4) {
+		C67_LDW_PTR(C67_A0, r);	// LDW  *A0,r
+	    } else if (size == 8) {
+		C67_LDDW_PTR(C67_A0, r);	// LDDW  *A0,r
+	    }
+
+	    C67_NOP(4);		// NOP 4
+	    return;
+	} else {
+	    element = size;
+
+	    // divide offset in bytes to create element index
+	    C67_MVKL(C67_A0, (fc / element) + 8 / element);	//r=reg to load,  constant
+	    C67_MVKH(C67_A0, (fc / element) + 8 / element);	//r=reg to load,  constant
+
+	    if (size == 1) {
+		if (Unsigned)
+		    C67_LDBU_SP_A0(r);	// LDBU  r, SP[A0]
+		else
+		    C67_LDB_SP_A0(r);	// LDB  r, SP[A0]
+	    } else if (size == 2) {
+		if (Unsigned)
+		    C67_LDHU_SP_A0(r);	// LDHU  r, SP[A0]
+		else
+		    C67_LDH_SP_A0(r);	// LDH  r, SP[A0]
+	    } else if (size == 4) {
+		C67_LDW_SP_A0(r);	// LDW  r, SP[A0]
+	    } else if (size == 8) {
+		C67_LDDW_SP_A0(r);	// LDDW  r, SP[A0]
+	    }
+
+
+	    C67_NOP(4);		// NOP 4
+	    return;
+	}
+    } else {
+	if (v == VT_CONST) {
+	    if (fr & VT_SYM) {
+		greloc(cur_text_section, sv->sym, ind, R_C60LO16);	// rem the inst need to be patched
+		greloc(cur_text_section, sv->sym, ind + 4, R_C60HI16);
+	    }
+	    C67_MVKL(r, fc);	//r=reg to load, constant
+	    C67_MVKH(r, fc);	//r=reg to load, constant
+	} else if (v == VT_LOCAL) {
+	    C67_MVKL(r, fc + 8);	//r=reg to load, constant C67 stack points to next free
+	    C67_MVKH(r, fc + 8);	//r=reg to load, constant
+	    C67_ADD(C67_FP, r);	// MV v,r   v -> r
+	} else if (v == VT_CMP) {
+	    C67_MV(C67_compare_reg, r);	// MV v,r   v -> r
+	} else if (v == VT_JMP || v == VT_JMPI) {
+	    t = v & 1;
+	    C67_B_DISP(4);	//  Branch with constant displacement, skip over this branch, load, nop, load
+	    C67_MVKL(r, t);	//  r=reg to load, 0 or 1 (do this while branching)
+	    C67_NOP(4);		//  NOP 4
+	    gsym(fc);		//  modifies other branches to branch here
+	    C67_MVKL(r, t ^ 1);	//  r=reg to load, 0 or 1
+	} else if (v != r) {
+	    C67_MV(v, r);	// MV v,r   v -> r
+
+	    if ((ft & VT_BTYPE) == VT_DOUBLE)
+		C67_MV(v + 1, r + 1);	// MV v,r   v -> r
+	}
+    }
+}
+
+
+/* store register 'r' in lvalue 'v' */
+void store(int r, SValue * v)
+{
+    int fr, bt, ft, fc, size, t, element;
+
+    ft = v->type.t;
+    fc = v->c.i;
+    fr = v->r & VT_VALMASK;
+    bt = ft & VT_BTYPE;
+    /* XXX: incorrect if float reg to reg */
+
+    if (bt == VT_LDOUBLE) {
+	tcc_error("long double not supported");
+    } else {
+	if (bt == VT_SHORT)
+	    size = 2;
+	else if (bt == VT_BYTE)
+	    size = 1;
+	else if (bt == VT_DOUBLE)
+	    size = 8;
+	else
+	    size = 4;
+
+	if ((v->r & VT_VALMASK) == VT_CONST) {
+	    /* constant memory reference */
+
+	    if (v->r & VT_SYM) {
+		greloc(cur_text_section, v->sym, ind, R_C60LO16);	// rem the inst need to be patched
+		greloc(cur_text_section, v->sym, ind + 4, R_C60HI16);
+	    }
+	    C67_MVKL(C67_A0, fc);	//r=reg to load,  constant
+	    C67_MVKH(C67_A0, fc);	//r=reg to load,  constant
+
+	    if (size == 1)
+		C67_STB_PTR(r, C67_A0);	// STB  r, *A0
+	    else if (size == 2)
+		C67_STH_PTR(r, C67_A0);	// STH  r, *A0
+	    else if (size == 4 || size == 8)
+		C67_STW_PTR(r, C67_A0);	// STW  r, *A0
+
+	    if (size == 8)
+		C67_STW_PTR_PRE_INC(r + 1, C67_A0, 1);	// STW  r, *+A0[1]
+	} else if ((v->r & VT_VALMASK) == VT_LOCAL) {
+	    // check case of storing to passed argument that
+	    // tcc thinks is on the stack but for C67 is
+	    // passed as a reg.  However it may have been
+	    // saved to the stack, if that reg was required
+	    // for a call to a child function
+
+	    if (fc > 0)		// argument ??
+	    {
+		// walk through sizes and figure which param
+
+		int stack_pos = 8;
+
+		for (t = 0; t < NoCallArgsPassedOnStack; t++) {
+		    if (fc == stack_pos)
+			break;
+
+		    stack_pos += TranslateStackToReg[t];
+		}
+
+		// param has been pushed on stack, get it like a local var
+		fc = ParamLocOnStack[t] - 8;
+	    }
+
+	    if (size == 8)
+		element = 4;
+	    else
+		element = size;
+
+	    // divide offset in bytes to create word index
+	    C67_MVKL(C67_A0, (fc / element) + 8 / element);	//r=reg to load,  constant
+	    C67_MVKH(C67_A0, (fc / element) + 8 / element);	//r=reg to load,  constant
+
+
+
+	    if (size == 1)
+		C67_STB_SP_A0(r);	// STB  r, SP[A0]
+	    else if (size == 2)
+		C67_STH_SP_A0(r);	// STH  r, SP[A0]
+	    else if (size == 4 || size == 8)
+		C67_STW_SP_A0(r);	// STW  r, SP[A0]
+
+	    if (size == 8) {
+		C67_ADDK(1, C67_A0);	//  ADDK 1,A0
+		C67_STW_SP_A0(r + 1);	//  STW  r, SP[A0]
+	    }
+	} else {
+	    if (size == 1)
+		C67_STB_PTR(r, fr);	// STB  r, *fr
+	    else if (size == 2)
+		C67_STH_PTR(r, fr);	// STH  r, *fr
+	    else if (size == 4 || size == 8)
+		C67_STW_PTR(r, fr);	// STW  r, *fr
+
+	    if (size == 8) {
+		C67_STW_PTR_PRE_INC(r + 1, fr, 1);	// STW  r, *+fr[1]
+	    }
+	}
+    }
+}
+
+/* 'is_jmp' is '1' if it is a jump */
+static void gcall_or_jmp(int is_jmp)
+{
+    int r;
+    Sym *sym;
+
+    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+	/* constant case */
+	if (vtop->r & VT_SYM) {
+	    /* relocation case */
+
+	    // get add into A0, then start the jump B3
+
+	    greloc(cur_text_section, vtop->sym, ind, R_C60LO16);	// rem the inst need to be patched
+	    greloc(cur_text_section, vtop->sym, ind + 4, R_C60HI16);
+
+	    C67_MVKL(C67_A0, 0);	//r=reg to load, constant
+	    C67_MVKH(C67_A0, 0);	//r=reg to load, constant
+	    C67_IREG_B_REG(0, C67_CREG_ZERO, C67_A0);	//  B.S2x  A0
+
+	    if (is_jmp) {
+		C67_NOP(5);	// simple jump, just put NOP
+	    } else {
+		// Call, must load return address into B3 during delay slots
+
+		sym = get_sym_ref(&char_pointer_type, cur_text_section, ind + 12, 0);	// symbol for return address
+		greloc(cur_text_section, sym, ind, R_C60LO16);	// rem the inst need to be patched
+		greloc(cur_text_section, sym, ind + 4, R_C60HI16);
+		C67_MVKL(C67_B3, 0);	//r=reg to load, constant
+		C67_MVKH(C67_B3, 0);	//r=reg to load, constant
+		C67_NOP(3);	// put remaining NOPs
+	    }
+	} else {
+	    /* put an empty PC32 relocation */
+	    ALWAYS_ASSERT(FALSE);
+	}
+    } else {
+	/* otherwise, indirect call */
+	r = gv(RC_INT);
+	C67_IREG_B_REG(0, C67_CREG_ZERO, r);	//  B.S2x  r
+
+	if (is_jmp) {
+	    C67_NOP(5);		// simple jump, just put NOP
+	} else {
+	    // Call, must load return address into B3 during delay slots
+
+	    sym = get_sym_ref(&char_pointer_type, cur_text_section, ind + 12, 0);	// symbol for return address
+	    greloc(cur_text_section, sym, ind, R_C60LO16);	// rem the inst need to be patched
+	    greloc(cur_text_section, sym, ind + 4, R_C60HI16);
+	    C67_MVKL(C67_B3, 0);	//r=reg to load, constant
+	    C67_MVKH(C67_B3, 0);	//r=reg to load, constant
+	    C67_NOP(3);		// put remaining NOPs
+	}
+    }
+}
+
+/* Return the number of registers needed to return the struct, or 0 if
+   returning via struct pointer. */
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize) {
+    *ret_align = 1; // Never have to re-align return values for x86-64
+    return 0;
+}
+
+/* generate function call with address in (vtop->t, vtop->c) and free function
+   context. Stack entry is popped */
+void gfunc_call(int nb_args)
+{
+    int i, r, size = 0;
+    int args_sizes[NoCallArgsPassedOnStack];
+
+    if (nb_args > NoCallArgsPassedOnStack) {
+	tcc_error("more than 10 function params not currently supported");
+	// handle more than 10, put some on the stack
+    }
+
+    for (i = 0; i < nb_args; i++) {
+	if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
+	    ALWAYS_ASSERT(FALSE);
+	} else {
+	    /* simple type (currently always same size) */
+	    /* XXX: implicit cast ? */
+
+
+	    if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
+		tcc_error("long long not supported");
+	    } else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
+		tcc_error("long double not supported");
+	    } else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
+		size = 8;
+	    } else {
+		size = 4;
+	    }
+
+	    // put the parameter into the corresponding reg (pair)
+
+	    r = gv(RC_C67_A4 << (2 * i));
+
+	    // must put on stack because with 1 pass compiler , no way to tell
+	    // if an up coming nested call might overwrite these regs
+
+	    C67_PUSH(r);
+
+	    if (size == 8) {
+		C67_STW_PTR_PRE_INC(r + 1, C67_SP, 3);	// STW  r, *+SP[3] (go back and put the other)
+	    }
+	    args_sizes[i] = size;
+	}
+	vtop--;
+    }
+    // POP all the params on the stack into registers for the
+    // immediate call (in reverse order)
+
+    for (i = nb_args - 1; i >= 0; i--) {
+
+	if (args_sizes[i] == 8)
+	    C67_POP_DW(TREG_C67_A4 + i * 2);
+	else
+	    C67_POP(TREG_C67_A4 + i * 2);
+    }
+    gcall_or_jmp(0);
+    vtop--;
+}
+
+
+// to be compatible with Code Composer for the C67
+// the first 10 parameters must be passed in registers
+// (pairs for 64 bits) starting wit; A4:A5, then B4:B5 and
+// ending with B12:B13.
+//
+// When a call is made, if the caller has its parameters
+// in regs A4-B13 these must be saved before/as the call 
+// parameters are loaded and restored upon return (or if/when needed).
+
+/* generate function prolog of type 't' */
+void gfunc_prolog(CType * func_type)
+{
+    int addr, align, size, func_call, i;
+    Sym *sym;
+    CType *type;
+
+    sym = func_type->ref;
+    func_call = sym->f.func_call;
+    addr = 8;
+    /* if the function returns a structure, then add an
+       implicit pointer parameter */
+    func_vt = sym->type;
+    func_var = (sym->f.func_type == FUNC_ELLIPSIS);
+    if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
+	func_vc = addr;
+	addr += 4;
+    }
+
+    NoOfCurFuncArgs = 0;
+
+    /* define parameters */
+    while ((sym = sym->next) != NULL) {
+	type = &sym->type;
+	sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | lvalue_type(type->t), addr);
+	size = type_size(type, &align);
+	size = (size + 3) & ~3;
+
+	// keep track of size of arguments so
+	// we can translate where tcc thinks they
+	// are on the stack into the appropriate reg
+
+	TranslateStackToReg[NoOfCurFuncArgs] = size;
+	NoOfCurFuncArgs++;
+
+#ifdef FUNC_STRUCT_PARAM_AS_PTR
+	/* structs are passed as pointer */
+	if ((type->t & VT_BTYPE) == VT_STRUCT) {
+	    size = 4;
+	}
+#endif
+	addr += size;
+    }
+    func_ret_sub = 0;
+    /* pascal type call ? */
+    if (func_call == FUNC_STDCALL)
+	func_ret_sub = addr - 8;
+
+    C67_MV(C67_FP, C67_A0);	//  move FP -> A0
+    C67_MV(C67_SP, C67_FP);	//  move SP -> FP
+
+    // place all the args passed in regs onto the stack
+
+    loc = 0;
+    for (i = 0; i < NoOfCurFuncArgs; i++) {
+
+	ParamLocOnStack[i] = loc;	// remember where the param is
+	loc += -8;
+
+	C67_PUSH(TREG_C67_A4 + i * 2);
+
+	if (TranslateStackToReg[i] == 8) {
+	    C67_STW_PTR_PRE_INC(TREG_C67_A4 + i * 2 + 1, C67_SP, 3);	// STW  r, *+SP[1] (go back and put the other)
+	}
+    }
+
+    TotalBytesPushedOnStack = -loc;
+
+    func_sub_sp_offset = ind;	// remember where we put the stack instruction 
+    C67_ADDK(0, C67_SP);	//  ADDK.L2 loc,SP  (just put zero temporarily)
+
+    C67_PUSH(C67_A0);
+    C67_PUSH(C67_B3);
+}
+
+/* generate function epilog */
+void gfunc_epilog(void)
+{
+    {
+	int local = (-loc + 7) & -8;	// stack must stay aligned to 8 bytes for LDDW instr
+	C67_POP(C67_B3);
+	C67_NOP(4);		// NOP wait for load
+	C67_IREG_B_REG(0, C67_CREG_ZERO, C67_B3);	//  B.S2  B3
+	C67_POP(C67_FP);
+	C67_ADDK(local, C67_SP);	//  ADDK.L2 loc,SP  
+	C67_Adjust_ADDK((int *) (cur_text_section->data +
+				 func_sub_sp_offset),
+			-local + TotalBytesPushedOnStack);
+	C67_NOP(3);		// NOP 
+    }
+}
+
+/* generate a jump to a label */
+int gjmp(int t)
+{
+    int ind1 = ind;
+    if (nocode_wanted)
+        return t;
+
+    C67_MVKL(C67_A0, t);	//r=reg to load,  constant
+    C67_MVKH(C67_A0, t);	//r=reg to load,  constant
+    C67_IREG_B_REG(0, C67_CREG_ZERO, C67_A0);	// [!R] B.S2x  A0
+    C67_NOP(5);
+    return ind1;
+}
+
+/* generate a jump to a fixed address */
+void gjmp_addr(int a)
+{
+    Sym *sym;
+    // I guess this routine is used for relative short
+    // local jumps, for now just handle it as the general
+    // case
+
+    // define a label that will be relocated
+
+    sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0);
+    greloc(cur_text_section, sym, ind, R_C60LO16);
+    greloc(cur_text_section, sym, ind + 4, R_C60HI16);
+
+    gjmp(0);			// place a zero there later the symbol will be added to it
+}
+
+/* generate a test. set 'inv' to invert test. Stack entry is popped */
+int gtst(int inv, int t)
+{
+    int ind1, n;
+    int v, *p;
+
+    v = vtop->r & VT_VALMASK;
+    if (nocode_wanted) {
+        ;
+    } else if (v == VT_CMP) {
+	/* fast case : can jump directly since flags are set */
+	// C67 uses B2 sort of as flags register
+	ind1 = ind;
+	C67_MVKL(C67_A0, t);	//r=reg to load, constant
+	C67_MVKH(C67_A0, t);	//r=reg to load, constant
+
+	if (C67_compare_reg != TREG_EAX &&	// check if not already in a conditional test reg
+	    C67_compare_reg != TREG_EDX &&
+	    C67_compare_reg != TREG_ST0 && C67_compare_reg != C67_B2) {
+	    C67_MV(C67_compare_reg, C67_B2);
+	    C67_compare_reg = C67_B2;
+	}
+
+	C67_IREG_B_REG(C67_invert_test ^ inv, C67_compare_reg, C67_A0);	// [!R] B.S2x  A0
+	C67_NOP(5);
+	t = ind1;		//return where we need to patch
+
+    } else if (v == VT_JMP || v == VT_JMPI) {
+	/* && or || optimization */
+	if ((v & 1) == inv) {
+	    /* insert vtop->c jump list in t */
+
+	    // I guess the idea is to traverse to the
+	    // null at the end of the list and store t
+	    // there
+
+	    n = vtop->c.i;
+	    while (n != 0) {
+		p = (int *) (cur_text_section->data + n);
+
+		// extract 32 bit address from MVKH/MVKL
+		n = ((*p >> 7) & 0xffff);
+		n |= ((*(p + 1) >> 7) & 0xffff) << 16;
+	    }
+	    *p |= (t & 0xffff) << 7;
+	    *(p + 1) |= ((t >> 16) & 0xffff) << 7;
+	    t = vtop->c.i;
+
+	} else {
+	    t = gjmp(t);
+	    gsym(vtop->c.i);
+	}
+    }
+    vtop--;
+    return t;
+}
+
+/* generate an integer binary operation */
+void gen_opi(int op)
+{
+    int r, fr, opc, t;
+
+    switch (op) {
+    case '+':
+    case TOK_ADDC1:		/* add with carry generation */
+	opc = 0;
+      gen_op8:
+
+
+// C67 can't do const compares, must load into a reg
+// so just go to gv2 directly - tktk
+
+
+
+	if (op >= TOK_ULT && op <= TOK_GT)
+	    gv2(RC_INT_BSIDE, RC_INT);	// make sure r (src1) is on the B Side of CPU
+	else
+	    gv2(RC_INT, RC_INT);
+
+	r = vtop[-1].r;
+	fr = vtop[0].r;
+
+	C67_compare_reg = C67_B2;
+
+
+	if (op == TOK_LT) {
+	    C67_CMPLT(r, fr, C67_B2);
+	    C67_invert_test = FALSE;
+	} else if (op == TOK_GE) {
+	    C67_CMPLT(r, fr, C67_B2);
+	    C67_invert_test = TRUE;
+	} else if (op == TOK_GT) {
+	    C67_CMPGT(r, fr, C67_B2);
+	    C67_invert_test = FALSE;
+	} else if (op == TOK_LE) {
+	    C67_CMPGT(r, fr, C67_B2);
+	    C67_invert_test = TRUE;
+	} else if (op == TOK_EQ) {
+	    C67_CMPEQ(r, fr, C67_B2);
+	    C67_invert_test = FALSE;
+	} else if (op == TOK_NE) {
+	    C67_CMPEQ(r, fr, C67_B2);
+	    C67_invert_test = TRUE;
+	} else if (op == TOK_ULT) {
+	    C67_CMPLTU(r, fr, C67_B2);
+	    C67_invert_test = FALSE;
+	} else if (op == TOK_UGE) {
+	    C67_CMPLTU(r, fr, C67_B2);
+	    C67_invert_test = TRUE;
+	} else if (op == TOK_UGT) {
+	    C67_CMPGTU(r, fr, C67_B2);
+	    C67_invert_test = FALSE;
+	} else if (op == TOK_ULE) {
+	    C67_CMPGTU(r, fr, C67_B2);
+	    C67_invert_test = TRUE;
+	} else if (op == '+')
+	    C67_ADD(fr, r);	// ADD  r,fr,r
+	else if (op == '-')
+	    C67_SUB(fr, r);	// SUB  r,fr,r
+	else if (op == '&')
+	    C67_AND(fr, r);	// AND  r,fr,r
+	else if (op == '|')
+	    C67_OR(fr, r);	// OR  r,fr,r
+	else if (op == '^')
+	    C67_XOR(fr, r);	// XOR  r,fr,r
+	else
+	    ALWAYS_ASSERT(FALSE);
+
+	vtop--;
+	if (op >= TOK_ULT && op <= TOK_GT) {
+	    vtop->r = VT_CMP;
+	    vtop->c.i = op;
+	}
+	break;
+    case '-':
+    case TOK_SUBC1:		/* sub with carry generation */
+	opc = 5;
+	goto gen_op8;
+    case TOK_ADDC2:		/* add with carry use */
+	opc = 2;
+	goto gen_op8;
+    case TOK_SUBC2:		/* sub with carry use */
+	opc = 3;
+	goto gen_op8;
+    case '&':
+	opc = 4;
+	goto gen_op8;
+    case '^':
+	opc = 6;
+	goto gen_op8;
+    case '|':
+	opc = 1;
+	goto gen_op8;
+    case '*':
+    case TOK_UMULL:
+	gv2(RC_INT, RC_INT);
+	r = vtop[-1].r;
+	fr = vtop[0].r;
+	vtop--;
+	C67_MPYI(fr, r);	// 32 bit multiply  fr,r,fr
+	C67_NOP(8);		// NOP 8 for worst case
+	break;
+    case TOK_SHL:
+	gv2(RC_INT_BSIDE, RC_INT_BSIDE);	// shift amount must be on same side as dst
+	r = vtop[-1].r;
+	fr = vtop[0].r;
+	vtop--;
+	C67_SHL(fr, r);		// arithmetic/logical shift
+	break;
+
+    case TOK_SHR:
+	gv2(RC_INT_BSIDE, RC_INT_BSIDE);	// shift amount must be on same side as dst
+	r = vtop[-1].r;
+	fr = vtop[0].r;
+	vtop--;
+	C67_SHRU(fr, r);	// logical shift
+	break;
+
+    case TOK_SAR:
+	gv2(RC_INT_BSIDE, RC_INT_BSIDE);	// shift amount must be on same side as dst
+	r = vtop[-1].r;
+	fr = vtop[0].r;
+	vtop--;
+	C67_SHR(fr, r);		// arithmetic shift
+	break;
+
+    case '/':
+	t = TOK__divi;
+      call_func:
+	vswap();
+	/* call generic idiv function */
+	vpush_global_sym(&func_old_type, t);
+	vrott(3);
+	gfunc_call(2);
+	vpushi(0);
+	vtop->r = REG_IRET;
+	vtop->r2 = VT_CONST;
+	break;
+    case TOK_UDIV:
+    case TOK_PDIV:
+	t = TOK__divu;
+	goto call_func;
+    case '%':
+	t = TOK__remi;
+	goto call_func;
+    case TOK_UMOD:
+	t = TOK__remu;
+	goto call_func;
+
+    default:
+	opc = 7;
+	goto gen_op8;
+    }
+}
+
+/* generate a floating point operation 'v = t1 op t2' instruction. The
+   two operands are guaranteed to have the same floating point type */
+/* XXX: need to use ST1 too */
+void gen_opf(int op)
+{
+    int ft, fc, fr, r;
+
+    if (op >= TOK_ULT && op <= TOK_GT)
+	gv2(RC_EDX, RC_EAX);	// make sure src2 is on b side
+    else
+	gv2(RC_FLOAT, RC_FLOAT);	// make sure src2 is on b side
+
+    ft = vtop->type.t;
+    fc = vtop->c.i;
+    r = vtop->r;
+    fr = vtop[-1].r;
+
+
+    if ((ft & VT_BTYPE) == VT_LDOUBLE)
+	tcc_error("long doubles not supported");
+
+    if (op >= TOK_ULT && op <= TOK_GT) {
+
+	r = vtop[-1].r;
+	fr = vtop[0].r;
+
+	C67_compare_reg = C67_B2;
+
+	if (op == TOK_LT) {
+	    if ((ft & VT_BTYPE) == VT_DOUBLE)
+		C67_CMPLTDP(r, fr, C67_B2);
+	    else
+		C67_CMPLTSP(r, fr, C67_B2);
+
+	    C67_invert_test = FALSE;
+	} else if (op == TOK_GE) {
+	    if ((ft & VT_BTYPE) == VT_DOUBLE)
+		C67_CMPLTDP(r, fr, C67_B2);
+	    else
+		C67_CMPLTSP(r, fr, C67_B2);
+
+	    C67_invert_test = TRUE;
+	} else if (op == TOK_GT) {
+	    if ((ft & VT_BTYPE) == VT_DOUBLE)
+		C67_CMPGTDP(r, fr, C67_B2);
+	    else
+		C67_CMPGTSP(r, fr, C67_B2);
+
+	    C67_invert_test = FALSE;
+	} else if (op == TOK_LE) {
+	    if ((ft & VT_BTYPE) == VT_DOUBLE)
+		C67_CMPGTDP(r, fr, C67_B2);
+	    else
+		C67_CMPGTSP(r, fr, C67_B2);
+
+	    C67_invert_test = TRUE;
+	} else if (op == TOK_EQ) {
+	    if ((ft & VT_BTYPE) == VT_DOUBLE)
+		C67_CMPEQDP(r, fr, C67_B2);
+	    else
+		C67_CMPEQSP(r, fr, C67_B2);
+
+	    C67_invert_test = FALSE;
+	} else if (op == TOK_NE) {
+	    if ((ft & VT_BTYPE) == VT_DOUBLE)
+		C67_CMPEQDP(r, fr, C67_B2);
+	    else
+		C67_CMPEQSP(r, fr, C67_B2);
+
+	    C67_invert_test = TRUE;
+	} else {
+	    ALWAYS_ASSERT(FALSE);
+	}
+	vtop->r = VT_CMP;	// tell TCC that result is in "flags" actually B2
+    } else {
+	if (op == '+') {
+	    if ((ft & VT_BTYPE) == VT_DOUBLE) {
+		C67_ADDDP(r, fr);	// ADD  fr,r,fr
+		C67_NOP(6);
+	    } else {
+		C67_ADDSP(r, fr);	// ADD  fr,r,fr
+		C67_NOP(3);
+	    }
+	    vtop--;
+	} else if (op == '-') {
+	    if ((ft & VT_BTYPE) == VT_DOUBLE) {
+		C67_SUBDP(r, fr);	// SUB  fr,r,fr
+		C67_NOP(6);
+	    } else {
+		C67_SUBSP(r, fr);	// SUB  fr,r,fr
+		C67_NOP(3);
+	    }
+	    vtop--;
+	} else if (op == '*') {
+	    if ((ft & VT_BTYPE) == VT_DOUBLE) {
+		C67_MPYDP(r, fr);	// MPY  fr,r,fr
+		C67_NOP(9);
+	    } else {
+		C67_MPYSP(r, fr);	// MPY  fr,r,fr
+		C67_NOP(3);
+	    }
+	    vtop--;
+	} else if (op == '/') {
+	    if ((ft & VT_BTYPE) == VT_DOUBLE) {
+		// must call intrinsic DP floating point divide
+		vswap();
+		/* call generic idiv function */
+		vpush_global_sym(&func_old_type, TOK__divd);
+		vrott(3);
+		gfunc_call(2);
+		vpushi(0);
+		vtop->r = REG_FRET;
+		vtop->r2 = REG_LRET;
+
+	    } else {
+		// must call intrinsic SP floating point divide
+		vswap();
+		/* call generic idiv function */
+		vpush_global_sym(&func_old_type, TOK__divf);
+		vrott(3);
+		gfunc_call(2);
+		vpushi(0);
+		vtop->r = REG_FRET;
+		vtop->r2 = VT_CONST;
+	    }
+	} else
+	    ALWAYS_ASSERT(FALSE);
+
+
+    }
+}
+
+
+/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
+   and 'long long' cases. */
+void gen_cvt_itof(int t)
+{
+    int r;
+
+    gv(RC_INT);
+    r = vtop->r;
+
+    if ((t & VT_BTYPE) == VT_DOUBLE) {
+	if (t & VT_UNSIGNED)
+	    C67_INTDPU(r, r);
+	else
+	    C67_INTDP(r, r);
+
+	C67_NOP(4);
+	vtop->type.t = VT_DOUBLE;
+    } else {
+	if (t & VT_UNSIGNED)
+	    C67_INTSPU(r, r);
+	else
+	    C67_INTSP(r, r);
+	C67_NOP(3);
+	vtop->type.t = VT_FLOAT;
+    }
+
+}
+
+/* convert fp to int 't' type */
+/* XXX: handle long long case */
+void gen_cvt_ftoi(int t)
+{
+    int r;
+
+    gv(RC_FLOAT);
+    r = vtop->r;
+
+    if (t != VT_INT)
+	tcc_error("long long not supported");
+    else {
+	if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) {
+	    C67_DPTRUNC(r, r);
+	    C67_NOP(3);
+	} else {
+	    C67_SPTRUNC(r, r);
+	    C67_NOP(3);
+	}
+
+	vtop->type.t = VT_INT;
+
+    }
+}
+
+/* convert from one floating point type to another */
+void gen_cvt_ftof(int t)
+{
+    int r, r2;
+
+    if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE &&
+	(t & VT_BTYPE) == VT_FLOAT) {
+	// convert double to float
+
+	gv(RC_FLOAT);		// get it in a register pair
+
+	r = vtop->r;
+
+	C67_DPSP(r, r);		// convert it to SP same register
+	C67_NOP(3);
+
+	vtop->type.t = VT_FLOAT;
+	vtop->r2 = VT_CONST;	// set this as unused
+    } else if ((vtop->type.t & VT_BTYPE) == VT_FLOAT &&
+	       (t & VT_BTYPE) == VT_DOUBLE) {
+	// convert float to double
+
+	gv(RC_FLOAT);		// get it in a register
+
+	r = vtop->r;
+
+	if (r == TREG_EAX) {	// make sure the paired reg is avail
+	    r2 = get_reg(RC_ECX);
+	} else if (r == TREG_EDX) {
+	    r2 = get_reg(RC_ST0);
+	} else {
+	    ALWAYS_ASSERT(FALSE);
+            r2 = 0; /* avoid warning */
+        }
+
+	C67_SPDP(r, r);		// convert it to DP same register
+	C67_NOP(1);
+
+	vtop->type.t = VT_DOUBLE;
+	vtop->r2 = r2;		// set this as unused
+    } else {
+	ALWAYS_ASSERT(FALSE);
+    }
+}
+
+/* computed goto support */
+void ggoto(void)
+{
+    gcall_or_jmp(1);
+    vtop--;
+}
+
+/* Save the stack pointer onto the stack and return the location of its address */
+ST_FUNC void gen_vla_sp_save(int addr) {
+    tcc_error("variable length arrays unsupported for this target");
+}
+
+/* Restore the SP from a location on the stack */
+ST_FUNC void gen_vla_sp_restore(int addr) {
+    tcc_error("variable length arrays unsupported for this target");
+}
+
+/* Subtract from the stack pointer, and push the resulting value onto the stack */
+ST_FUNC void gen_vla_alloc(CType *type, int align) {
+    tcc_error("variable length arrays unsupported for this target");
+}
+
+/* end of C67 code generator */
+/*************************************************************/
+#endif
+/*************************************************************/
Index: EcnlProtoTool/trunk/tcc-0.9.27/c67-link.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/c67-link.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/c67-link.c	(revision 331)
@@ -0,0 +1,131 @@
+#ifdef TARGET_DEFS_ONLY
+
+#define EM_TCC_TARGET EM_C60
+
+/* relocation type for 32 bit data relocation */
+#define R_DATA_32   R_C60_32
+#define R_DATA_PTR  R_C60_32
+#define R_JMP_SLOT  R_C60_JMP_SLOT
+#define R_GLOB_DAT  R_C60_GLOB_DAT
+#define R_COPY      R_C60_COPY
+#define R_RELATIVE  R_C60_RELATIVE
+
+#define R_NUM       R_C60_NUM
+
+#define ELF_START_ADDR 0x00000400
+#define ELF_PAGE_SIZE  0x1000
+
+#define PCRELATIVE_DLLPLT 0
+#define RELOCATE_DLLPLT 0
+
+#else /* !TARGET_DEFS_ONLY */
+
+#include "tcc.h"
+
+/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
+   relocations, returns -1. */
+int code_reloc (int reloc_type)
+{
+    switch (reloc_type) {
+        case R_C60_32:
+	case R_C60LO16:
+	case R_C60HI16:
+        case R_C60_GOT32:
+        case R_C60_GOTOFF:
+        case R_C60_GOTPC:
+        case R_C60_COPY:
+            return 0;
+
+        case R_C60_PLT32:
+            return 1;
+    }
+
+    tcc_error ("Unknown relocation type: %d", reloc_type);
+    return -1;
+}
+
+/* Returns an enumerator to describe whether and when the relocation needs a
+   GOT and/or PLT entry to be created. See tcc.h for a description of the
+   different values. */
+int gotplt_entry_type (int reloc_type)
+{
+    switch (reloc_type) {
+        case R_C60_32:
+	case R_C60LO16:
+	case R_C60HI16:
+        case R_C60_COPY:
+            return NO_GOTPLT_ENTRY;
+
+        case R_C60_GOTOFF:
+        case R_C60_GOTPC:
+            return BUILD_GOT_ONLY;
+
+        case R_C60_PLT32:
+        case R_C60_GOT32:
+            return ALWAYS_GOTPLT_ENTRY;
+    }
+
+    tcc_error ("Unknown relocation type: %d", reloc_type);
+    return -1;
+}
+
+ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
+{
+    tcc_error("C67 got not implemented");
+    return 0;
+}
+
+/* relocate the PLT: compute addresses and offsets in the PLT now that final
+   address for PLT and GOT are known (see fill_program_header) */
+ST_FUNC void relocate_plt(TCCState *s1)
+{
+    uint8_t *p, *p_end;
+
+    if (!s1->plt)
+      return;
+
+    p = s1->plt->data;
+    p_end = p + s1->plt->data_offset;
+
+    if (p < p_end) {
+        /* XXX: TODO */
+        while (p < p_end) {
+            /* XXX: TODO */
+        }
+   }
+}
+
+void relocate_init(Section *sr) {}
+
+void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
+{
+    switch(type) {
+        case R_C60_32:
+            *(int *)ptr += val;
+            break;
+        case R_C60LO16:
+            {
+                uint32_t orig;
+
+                /* put the low 16 bits of the absolute address add to what is
+                   already there */
+                orig  =   ((*(int *)(ptr  )) >> 7) & 0xffff;
+                orig |=  (((*(int *)(ptr+4)) >> 7) & 0xffff) << 16;
+
+                /* patch both at once - assumes always in pairs Low - High */
+                *(int *) ptr    = (*(int *) ptr    & (~(0xffff << 7)) ) |
+                                   (((val+orig)      & 0xffff) << 7);
+                *(int *)(ptr+4) = (*(int *)(ptr+4) & (~(0xffff << 7)) ) |
+                                  ((((val+orig)>>16) & 0xffff) << 7);
+            }
+            break;
+        case R_C60HI16:
+            break;
+        default:
+            fprintf(stderr,"FIXME: handle reloc type %x at %x [%p] to %x\n",
+                    type, (unsigned) addr, ptr, (unsigned) val);
+            break;
+    }
+}
+
+#endif /* !TARGET_DEFS_ONLY */
Index: EcnlProtoTool/trunk/tcc-0.9.27/coff.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/coff.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/coff.h	(revision 331)
@@ -0,0 +1,455 @@
+/**************************************************************************/
+/*  COFF.H                                                                */
+/*     COFF data structures and related definitions used by the linker    */
+/**************************************************************************/
+
+/*------------------------------------------------------------------------*/
+/*  COFF FILE HEADER                                                      */
+/*------------------------------------------------------------------------*/
+struct filehdr {
+        unsigned short  f_magic;        /* magic number */
+        unsigned short  f_nscns;        /* number of sections */
+        long            f_timdat;       /* time & date stamp */
+        long            f_symptr;       /* file pointer to symtab */
+        long            f_nsyms;        /* number of symtab entries */
+        unsigned short  f_opthdr;       /* sizeof(optional hdr) */
+        unsigned short  f_flags;        /* flags */
+        unsigned short  f_TargetID;     /* for C6x = 0x0099 */
+        };
+
+/*------------------------------------------------------------------------*/
+/*  File header flags                                                     */
+/*------------------------------------------------------------------------*/
+#define  F_RELFLG   0x01       /* relocation info stripped from file       */
+#define  F_EXEC     0x02       /* file is executable (no unresolved refs)  */
+#define  F_LNNO     0x04       /* line numbers stripped from file          */
+#define  F_LSYMS    0x08       /* local symbols stripped from file         */
+#define  F_GSP10    0x10       /* 34010 version                            */
+#define  F_GSP20    0x20       /* 34020 version                            */
+#define  F_SWABD    0x40       /* bytes swabbed (in names)                 */
+#define  F_AR16WR   0x80       /* byte ordering of an AR16WR (PDP-11)      */
+#define  F_LITTLE   0x100      /* byte ordering of an AR32WR (vax)         */
+#define  F_BIG      0x200      /* byte ordering of an AR32W (3B, maxi)     */
+#define  F_PATCH    0x400      /* contains "patch" list in optional header */
+#define  F_NODF     0x400   
+
+#define F_VERSION    (F_GSP10  | F_GSP20)   
+#define F_BYTE_ORDER (F_LITTLE | F_BIG)
+#define FILHDR  struct filehdr
+
+/* #define FILHSZ  sizeof(FILHDR)  */
+#define FILHSZ  22                /* above rounds to align on 4 bytes which causes problems */
+
+#define COFF_C67_MAGIC 0x00c2
+
+/*------------------------------------------------------------------------*/
+/*  Macros to recognize magic numbers                                     */
+/*------------------------------------------------------------------------*/
+#define ISMAGIC(x)      (((unsigned short)(x))==(unsigned short)magic)
+#define ISARCHIVE(x)    ((((unsigned short)(x))==(unsigned short)ARTYPE))
+#define BADMAGIC(x)     (((unsigned short)(x) & 0x8080) && !ISMAGIC(x))
+
+
+
+/*------------------------------------------------------------------------*/
+/*  OPTIONAL FILE HEADER                                                  */
+/*------------------------------------------------------------------------*/
+typedef struct aouthdr {
+        short   magic;          /* see magic.h                          */
+        short   vstamp;         /* version stamp                        */
+        long    tsize;          /* text size in bytes, padded to FW bdry*/
+        long    dsize;          /* initialized data "  "                */
+        long    bsize;          /* uninitialized data "   "             */
+        long    entrypt;        /* entry pt.                            */
+        long    text_start;     /* base of text used for this file      */
+        long    data_start;     /* base of data used for this file      */
+} AOUTHDR;
+
+#define AOUTSZ  sizeof(AOUTHDR)
+
+/*----------------------------------------------------------------------*/
+/*      When a UNIX aout header is to be built in the optional header,  */
+/*      the following magic numbers can appear in that header:          */ 
+/*                                                                      */
+/*              AOUT1MAGIC : default : readonly sharable text segment   */
+/*              AOUT2MAGIC:          : writable text segment            */
+/*              PAGEMAGIC  :         : configured for paging            */
+/*----------------------------------------------------------------------*/
+#define AOUT1MAGIC 0410
+#define AOUT2MAGIC 0407
+#define PAGEMAGIC  0413
+
+
+
+/*------------------------------------------------------------------------*/
+/*  COMMON ARCHIVE FILE STRUCTURES                                        */
+/*                                                                        */
+/*       ARCHIVE File Organization:                                       */
+/*       _______________________________________________                  */
+/*       |__________ARCHIVE_MAGIC_STRING_______________|                  */
+/*       |__________ARCHIVE_FILE_MEMBER_1______________|                  */
+/*       |                                             |                  */
+/*       |       Archive File Header "ar_hdr"          |                  */
+/*       |.............................................|                  */
+/*       |       Member Contents                       |                  */
+/*       |               1. External symbol directory  |                  */
+/*       |               2. Text file                  |                  */
+/*       |_____________________________________________|                  */
+/*       |________ARCHIVE_FILE_MEMBER_2________________|                  */
+/*       |               "ar_hdr"                      |                  */
+/*       |.............................................|                  */
+/*       |       Member Contents (.o or text file)     |                  */
+/*       |_____________________________________________|                  */
+/*       |       .               .               .     |                  */
+/*       |       .               .               .     |                  */
+/*       |       .               .               .     |                  */
+/*       |_____________________________________________|                  */
+/*       |________ARCHIVE_FILE_MEMBER_n________________|                  */
+/*       |               "ar_hdr"                      |                  */
+/*       |.............................................|                  */
+/*       |               Member Contents               |                  */
+/*       |_____________________________________________|                  */
+/*                                                                        */
+/*------------------------------------------------------------------------*/
+
+#define COFF_ARMAG   "!<arch>\n"
+#define SARMAG  8
+#define ARFMAG  "`\n"
+
+struct ar_hdr           /* archive file member header - printable ascii */
+{
+        char    ar_name[16];    /* file member name - `/' terminated */
+        char    ar_date[12];    /* file member date - decimal */
+        char    ar_uid[6];      /* file member user id - decimal */
+        char    ar_gid[6];      /* file member group id - decimal */
+        char    ar_mode[8];     /* file member mode - octal */
+        char    ar_size[10];    /* file member size - decimal */
+        char    ar_fmag[2];     /* ARFMAG - string to end header */
+};
+
+
+
+/*------------------------------------------------------------------------*/
+/*  SECTION HEADER                                                        */
+/*------------------------------------------------------------------------*/
+struct scnhdr {
+        char            s_name[8];      /* section name */
+        long            s_paddr;        /* physical address */
+        long            s_vaddr;        /* virtual address */
+        long            s_size;         /* section size */
+        long            s_scnptr;       /* file ptr to raw data for section */
+        long            s_relptr;       /* file ptr to relocation */
+        long            s_lnnoptr;      /* file ptr to line numbers */
+        unsigned int	s_nreloc;       /* number of relocation entries */
+        unsigned int	s_nlnno;        /* number of line number entries */
+        unsigned int	s_flags;        /* flags */
+		unsigned short	s_reserved;     /* reserved byte */
+		unsigned short  s_page;         /* memory page id */
+        };
+
+#define SCNHDR  struct scnhdr
+#define SCNHSZ  sizeof(SCNHDR)
+
+/*------------------------------------------------------------------------*/
+/* Define constants for names of "special" sections                       */
+/*------------------------------------------------------------------------*/
+/* #define _TEXT    ".text" */
+#define _DATA    ".data"
+#define _BSS     ".bss"
+#define _CINIT   ".cinit"
+#define _TV      ".tv"
+
+/*------------------------------------------------------------------------*/
+/* The low 4 bits of s_flags is used as a section "type"                  */
+/*------------------------------------------------------------------------*/
+#define STYP_REG    0x00  /* "regular" : allocated, relocated, loaded */
+#define STYP_DSECT  0x01  /* "dummy"   : not allocated, relocated, not loaded */
+#define STYP_NOLOAD 0x02  /* "noload"  : allocated, relocated, not loaded */
+#define STYP_GROUP  0x04  /* "grouped" : formed of input sections */
+#define STYP_PAD    0x08  /* "padding" : not allocated, not relocated, loaded */
+#define STYP_COPY   0x10  /* "copy"    : used for C init tables - 
+                                                not allocated, relocated,
+                                                loaded;  reloc & lineno
+                                                entries processed normally */
+#define STYP_TEXT   0x20   /* section contains text only */
+#define STYP_DATA   0x40   /* section contains data only */
+#define STYP_BSS    0x80   /* section contains bss only */
+
+#define STYP_ALIGN  0x100  /* align flag passed by old version assemblers */
+#define ALIGN_MASK  0x0F00 /* part of s_flags that is used for align vals */
+#define ALIGNSIZE(x) (1 << ((x & ALIGN_MASK) >> 8))
+
+
+
+/*------------------------------------------------------------------------*/
+/*  RELOCATION ENTRIES                                                    */
+/*------------------------------------------------------------------------*/
+struct reloc
+{
+   long            r_vaddr;        /* (virtual) address of reference */
+   short           r_symndx;       /* index into symbol table */
+   unsigned short  r_disp;         /* additional bits for address calculation */
+   unsigned short  r_type;         /* relocation type */
+};
+
+#define RELOC   struct reloc
+#define RELSZ   10                 /* sizeof(RELOC) */
+
+/*--------------------------------------------------------------------------*/
+/*   define all relocation types                                            */
+/*--------------------------------------------------------------------------*/
+
+#define R_ABS           0         /* absolute address - no relocation       */
+#define R_DIR16         01        /* UNUSED                                 */
+#define R_REL16         02        /* UNUSED                                 */
+#define R_DIR24         04        /* UNUSED                                 */
+#define R_REL24         05        /* 24 bits, direct                        */
+#define R_DIR32         06        /* UNUSED                                 */
+#define R_RELBYTE      017        /* 8 bits, direct                         */
+#define R_RELWORD      020        /* 16 bits, direct                        */
+#define R_RELLONG      021        /* 32 bits, direct                        */
+#define R_PCRBYTE      022        /* 8 bits, PC-relative                    */
+#define R_PCRWORD      023        /* 16 bits, PC-relative                   */
+#define R_PCRLONG      024        /* 32 bits, PC-relative                   */
+#define R_OCRLONG      030        /* GSP: 32 bits, one's complement direct  */
+#define R_GSPPCR16     031        /* GSP: 16 bits, PC relative (in words)   */
+#define R_GSPOPR32     032        /* GSP: 32 bits, direct big-endian        */
+#define R_PARTLS16     040        /* Brahma: 16 bit offset of 24 bit address*/
+#define R_PARTMS8      041        /* Brahma: 8 bit page of 24 bit address   */
+#define R_PARTLS7      050        /* DSP: 7 bit offset of 16 bit address    */
+#define R_PARTMS9      051        /* DSP: 9 bit page of 16 bit address      */
+#define R_REL13        052        /* DSP: 13 bits, direct                   */
+
+
+
+/*------------------------------------------------------------------------*/
+/*  LINE NUMBER ENTRIES                                                   */
+/*------------------------------------------------------------------------*/
+struct lineno
+{
+        union
+        {
+                long    l_symndx ;      /* sym. table index of function name
+                                                iff l_lnno == 0      */
+                long    l_paddr ;       /* (physical) address of line number */
+        }               l_addr ;
+        unsigned short  l_lnno ;        /* line number */
+};
+
+#define LINENO  struct lineno
+#define LINESZ  6       /* sizeof(LINENO) */
+
+
+
+/*------------------------------------------------------------------------*/
+/*   STORAGE CLASSES                                                      */
+/*------------------------------------------------------------------------*/
+#define  C_EFCN          -1    /* physical end of function */
+#define  C_NULL          0
+#define  C_AUTO          1     /* automatic variable */
+#define  C_EXT           2     /* external symbol */
+#define  C_STAT          3     /* static */
+#define  C_REG           4     /* register variable */
+#define  C_EXTDEF        5     /* external definition */
+#define  C_LABEL         6     /* label */
+#define  C_ULABEL        7     /* undefined label */
+#define  C_MOS           8     /* member of structure */
+#define  C_ARG           9     /* function argument */
+#define  C_STRTAG        10    /* structure tag */
+#define  C_MOU           11    /* member of union */
+#define  C_UNTAG         12    /* union tag */
+#define  C_TPDEF         13    /* type definition */
+#define C_USTATIC        14    /* undefined static */
+#define  C_ENTAG         15    /* enumeration tag */
+#define  C_MOE           16    /* member of enumeration */
+#define  C_REGPARM       17    /* register parameter */
+#define  C_FIELD         18    /* bit field */
+
+#define  C_BLOCK         100   /* ".bb" or ".eb" */
+#define  C_FCN           101   /* ".bf" or ".ef" */
+#define  C_EOS           102   /* end of structure */
+#define  C_FILE          103   /* file name */
+#define  C_LINE          104   /* dummy sclass for line number entry */
+#define  C_ALIAS         105   /* duplicate tag */
+#define  C_HIDDEN        106   /* special storage class for external */
+                               /* symbols in dmert public libraries  */
+
+
+/*------------------------------------------------------------------------*/
+/*  SYMBOL TABLE ENTRIES                                                  */
+/*------------------------------------------------------------------------*/
+
+#define  SYMNMLEN   8      /*  Number of characters in a symbol name */
+#define  FILNMLEN   14     /*  Number of characters in a file name */
+#define  DIMNUM     4      /*  Number of array dimensions in auxiliary entry */
+
+
+struct syment
+{
+        union
+        {
+                char            _n_name[SYMNMLEN];      /* old COFF version */
+                struct
+                {
+                        long    _n_zeroes;      /* new == 0 */
+                        long    _n_offset;      /* offset into string table */
+                } _n_n;
+                char            *_n_nptr[2];    /* allows for overlaying */
+        } _n;
+        long                    n_value;        /* value of symbol */
+        short                   n_scnum;        /* section number */
+        unsigned short          n_type;         /* type and derived type */
+        char                    n_sclass;       /* storage class */
+        char                    n_numaux;       /* number of aux. entries */
+};
+
+#define n_name          _n._n_name
+#define n_nptr          _n._n_nptr[1]
+#define n_zeroes        _n._n_n._n_zeroes
+#define n_offset        _n._n_n._n_offset
+
+/*------------------------------------------------------------------------*/
+/* Relocatable symbols have a section number of the                       */
+/* section in which they are defined.  Otherwise, section                 */
+/* numbers have the following meanings:                                   */
+/*------------------------------------------------------------------------*/
+#define  N_UNDEF  0                     /* undefined symbol */
+#define  N_ABS    -1                    /* value of symbol is absolute */
+#define  N_DEBUG  -2                    /* special debugging symbol  */
+#define  N_TV     (unsigned short)-3    /* needs transfer vector (preload) */
+#define  P_TV     (unsigned short)-4    /* needs transfer vector (postload) */
+
+
+
+/*------------------------------------------------------------------------*/
+/* The fundamental type of a symbol packed into the low                   */
+/* 4 bits of the word.                                                    */
+/*------------------------------------------------------------------------*/
+#define  _EF    ".ef"
+
+#define  T_NULL     0          /* no type info */
+#define  T_ARG      1          /* function argument (only used by compiler) */
+#define  T_CHAR     2          /* character */
+#define  T_SHORT    3          /* short integer */
+#define  T_INT      4          /* integer */
+#define  T_LONG     5          /* long integer */
+#define  T_FLOAT    6          /* floating point */
+#define  T_DOUBLE   7          /* double word */
+#define  T_STRUCT   8          /* structure  */
+#define  T_UNION    9          /* union  */
+#define  T_ENUM     10         /* enumeration  */
+#define  T_MOE      11         /* member of enumeration */
+#define  T_UCHAR    12         /* unsigned character */
+#define  T_USHORT   13         /* unsigned short */
+#define  T_UINT     14         /* unsigned integer */
+#define  T_ULONG    15         /* unsigned long */
+
+/*------------------------------------------------------------------------*/
+/* derived types are:                                                     */
+/*------------------------------------------------------------------------*/
+#define  DT_NON      0          /* no derived type */
+#define  DT_PTR      1          /* pointer */
+#define  DT_FCN      2          /* function */
+#define  DT_ARY      3          /* array */
+
+#define MKTYPE(basic, d1,d2,d3,d4,d5,d6) \
+       ((basic) | ((d1) <<  4) | ((d2) <<  6) | ((d3) <<  8) |\
+                  ((d4) << 10) | ((d5) << 12) | ((d6) << 14))
+
+/*------------------------------------------------------------------------*/
+/* type packing constants and macros                                      */
+/*------------------------------------------------------------------------*/
+#define  N_BTMASK_COFF     017
+#define  N_TMASK_COFF      060
+#define  N_TMASK1_COFF     0300
+#define  N_TMASK2_COFF     0360
+#define  N_BTSHFT_COFF     4
+#define  N_TSHIFT_COFF     2
+
+#define  BTYPE_COFF(x)  ((x) & N_BTMASK_COFF)  
+#define  ISINT(x)  (((x) >= T_CHAR && (x) <= T_LONG) ||   \
+		    ((x) >= T_UCHAR && (x) <= T_ULONG) || (x) == T_ENUM)
+#define  ISFLT_COFF(x)  ((x) == T_DOUBLE || (x) == T_FLOAT)
+#define  ISPTR_COFF(x)  (((x) & N_TMASK_COFF) == (DT_PTR << N_BTSHFT_COFF)) 
+#define  ISFCN_COFF(x)  (((x) & N_TMASK_COFF) == (DT_FCN << N_BTSHFT_COFF))
+#define  ISARY_COFF(x)  (((x) & N_TMASK_COFF) == (DT_ARY << N_BTSHFT_COFF))
+#define  ISTAG_COFF(x)  ((x)==C_STRTAG || (x)==C_UNTAG || (x)==C_ENTAG)
+
+#define  INCREF_COFF(x) ((((x)&~N_BTMASK_COFF)<<N_TSHIFT_COFF)|(DT_PTR<<N_BTSHFT_COFF)|(x&N_BTMASK_COFF))
+#define  DECREF_COFF(x) ((((x)>>N_TSHIFT_COFF)&~N_BTMASK_COFF)|((x)&N_BTMASK_COFF))
+
+
+
+/*------------------------------------------------------------------------*/
+/*  AUXILIARY SYMBOL ENTRY                                                */
+/*------------------------------------------------------------------------*/
+union auxent
+{
+	struct
+	{
+		long            x_tagndx;       /* str, un, or enum tag indx */
+		union
+		{
+			struct
+			{
+				unsigned short  x_lnno; /* declaration line number */
+				unsigned short  x_size; /* str, union, array size */
+			} x_lnsz;
+			long    x_fsize;        /* size of function */
+		} x_misc;
+		union
+		{
+			struct                  /* if ISFCN, tag, or .bb */
+			{
+				long    x_lnnoptr;      /* ptr to fcn line # */
+				long    x_endndx;       /* entry ndx past block end */
+			}       x_fcn;
+			struct                  /* if ISARY, up to 4 dimen. */
+			{
+				unsigned short  x_dimen[DIMNUM];
+			}       x_ary;
+		}               x_fcnary;
+		unsigned short  x_regcount;   /* number of registers used by func */
+	}       x_sym;
+	struct
+	{
+		char    x_fname[FILNMLEN];
+	}       x_file;
+	struct
+	{
+		long    x_scnlen;          /* section length */
+		unsigned short  x_nreloc;  /* number of relocation entries */
+		unsigned short  x_nlinno;  /* number of line numbers */
+	}       x_scn;
+};
+
+#define SYMENT  struct syment
+#define SYMESZ  18      /* sizeof(SYMENT) */
+
+#define AUXENT  union auxent
+#define AUXESZ  18      /* sizeof(AUXENT) */
+
+/*------------------------------------------------------------------------*/
+/*  NAMES OF "SPECIAL" SYMBOLS                                            */
+/*------------------------------------------------------------------------*/
+#define _STEXT          ".text"
+#define _ETEXT          "etext"
+#define _SDATA          ".data"
+#define _EDATA          "edata"
+#define _SBSS           ".bss"
+#define _END            "end"
+#define _CINITPTR       "cinit"
+
+/*--------------------------------------------------------------------------*/
+/*  ENTRY POINT SYMBOLS                                                     */
+/*--------------------------------------------------------------------------*/
+#define _START          "_start"
+#define _MAIN           "_main"
+    /*  _CSTART         "_c_int00"          (defined in params.h)  */
+
+
+#define _TVORIG         "_tvorig"
+#define _TORIGIN        "_torigin"
+#define _DORIGIN        "_dorigin"
+
+#define _SORIGIN        "_sorigin"
Index: EcnlProtoTool/trunk/tcc-0.9.27/config.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/config.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/config.h	(revision 331)
@@ -0,0 +1,7 @@
+/* Automatically generated by configure - do not modify */
+#ifndef CONFIG_TCCDIR
+# define CONFIG_TCCDIR "1:/lib"
+#endif
+#define CONFIG_TCC_CRTPREFIX "1:/lib"
+#define CONFIG_TCC_SYSINCLUDEPATHS "1:/include"
+#define TCC_VERSION "0.9.27"
Index: EcnlProtoTool/trunk/tcc-0.9.27/config.mak
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/config.mak	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/config.mak	(revision 331)
@@ -0,0 +1,27 @@
+# Automatically generated by configure - do not modify
+prefix=1:
+bindir=$(DESTDIR)1:
+tccdir=$(DESTDIR)1:
+libdir=$(DESTDIR)1:/libtcc
+includedir=$(DESTDIR)
+mandir=$(DESTDIR)
+infodir=$(DESTDIR)
+docdir=$(DESTDIR)1:/doc
+CC=arm-none-eabi-gcc
+GCC_MAJOR=0
+GCC_MINOR=0
+AR=arm-none-eabi-ar
+STRIP=arm-none-eabi-strip -s -R .comment -R .note
+CFLAGS=-Wall -g -Og -nostdinc -I$(TOP)/../musl-1.1.18/include -mcpu=cortex-a9 -march=armv7-a -mlittle-endian -marm -mthumb-interwork -mfloat-abi=hard -mfpu=vfp -Dtcc_main=main -Wdeclaration-after-statement -fno-strict-aliasing -Wno-pointer-sign -Wno-sign-compare -Wno-unused-result
+LDFLAGS=-Wl,-e_start_c -nostdlib $(TOP)/../musl-1.1.18/lib/crtn.o $(TOP)/../musl-1.1.18/lib/crti.o $(TOP)/../musl-1.1.18/lib/rcrt1.o -L$(TOP)/../musl-1.1.18/lib -L. -lc -lgcc
+LIBSUF=.a
+EXESUF=.elf
+DLLSUF=.so
+NATIVE_DEFINES+=-DTCC_CPU_VERSION=7
+ARCH=arm
+TARGETOS=
+#CONFIG_libgcc=yes
+CONFIG_musl=yes
+VERSION = 0.9.27
+TOPSRC=$(TOP)
+arm-libtcc1-usegcc=yes
Index: EcnlProtoTool/trunk/tcc-0.9.27/config.texi
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/config.texi	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/config.texi	(revision 331)
@@ -0,0 +1,1 @@
+@set VERSION 0.9.27
Index: EcnlProtoTool/trunk/tcc-0.9.27/configure
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/configure	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/configure	(revision 331)
@@ -0,0 +1,527 @@
+#!/bin/sh
+#
+# tcc configure script (c) 2003 Fabrice Bellard
+
+# set temporary file name
+# if test ! -z "$TMPDIR" ; then
+#     TMPDIR1="${TMPDIR}"
+# elif test ! -z "$TEMPDIR" ; then
+#     TMPDIR1="${TEMPDIR}"
+# else
+#     TMPDIR1="/tmp"
+# fi
+#
+# bashism: TMPN="${TMPDIR1}/tcc-conf-${RANDOM}-$$-${RANDOM}.c"
+
+TMPN="./conftest-$$"
+TMPH=$TMPN.h
+
+# default parameters
+prefix=""
+execprefix=""
+bindir=""
+libdir=""
+tccdir=""
+includedir=""
+mandir=""
+infodir=""
+sysroot=""
+cross_prefix=""
+cc="gcc"
+ar="ar"
+strip="strip"
+bigendian="no"
+mingw32="no"
+LIBSUF=".a"
+EXESUF=""
+DLLSUF=".so"
+tcc_sysincludepaths=""
+tcc_libpaths=""
+tcc_crtprefix=""
+tcc_elfinterp=""
+triplet=
+tcc_lddir=
+confvars=
+suggest="yes"
+cpu=
+cpuver=
+gcc_major=0
+gcc_minor=0
+
+# OS specific
+targetos=`uname`
+case $targetos in
+  Darwin)
+    confvars="$confvars OSX"
+    DLLSUF=".dylib"
+    ;;
+  MINGW*|MSYS*|CYGWIN*)
+    mingw32=yes
+    ;;
+  DragonFly|OpenBSD|FreeBSD|NetBSD)
+    confvars="$confvars ldl=no"
+    ;;
+  *)
+    ;;
+esac
+
+# find source path
+source_path=${0%configure}
+source_path=${source_path%/}
+source_path_used="yes"
+if test -z "$source_path" -o "$source_path" = "." ; then
+    source_path=`pwd`
+    source_path_used="no"
+fi
+
+for opt do
+  eval opt=\"$opt\"
+  case "$opt" in
+  --prefix=*) prefix=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --exec-prefix=*) execprefix=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --tccdir=*) tccdir=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --bindir=*) bindir=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --libdir=*) libdir=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --includedir=*) includedir=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --sharedir=*) sharedir=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --mandir=*) mandir=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --infodir=*) infodir=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --docdir=*) docdir=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --sysroot=*) sysroot=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --source-path=*) source_path=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --cross-prefix=*) cross_prefix=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --cc=*) cc=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --ar=*) ar=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --extra-cflags=*) CFLAGS="${opt#--extra-cflags=}"
+  ;;
+  --extra-ldflags=*) LDFLAGS="${opt#--extra-ldflags=}"
+  ;;
+  --extra-libs=*) extralibs="${opt#--extra-libs=}"
+  ;;
+  --sysincludepaths=*) tcc_sysincludepaths=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --libpaths=*) tcc_libpaths=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --crtprefix=*) tcc_crtprefix=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --elfinterp=*) tcc_elfinterp=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --triplet=*) triplet=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --cpu=*) cpu=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --enable-cross) confvars="$confvars cross"
+  ;;
+  --disable-static) confvars="$confvars static=no"
+  ;;
+  --enable-static) confvars="$confvars static"
+  ;;
+  --disable-rpath) confvars="$confvars rpath=no"
+  ;;
+  --strip-binaries) confvars="$confvars strip"
+  ;;
+  --with-libgcc) confvars="$confvars libgcc"
+  ;;
+  --with-selinux) confvars="$confvars selinux"
+  ;;
+  --config-mingw32*) mingw32=$(echo "$opt=yes" | cut -d '=' -f 2)
+  ;;
+  --config-*) confvars="$confvars ${opt#--config-}"; suggest="no"
+  ;;
+  --help|-h) show_help="yes"
+  ;;
+  *) echo "configure: WARNING: unrecognized option $opt"
+  ;;
+  esac
+done
+
+if test -z "$cpu" ; then
+    if test -n "$ARCH" ; then
+	cpu="$ARCH"
+    else
+	cpu=`uname -m`
+    fi
+fi
+
+case "$cpu" in
+  x86|i386|i486|i586|i686|i86pc|BePC|i686-AT386)
+    cpu="i386"
+  ;;
+  x86_64|amd64|x86-64)
+    cpu="x86_64"
+  ;;
+  arm*)
+    case "$cpu" in
+      arm|armv4l)
+	cpuver=4
+      ;;
+      armv5tel|armv5tejl)
+	cpuver=5
+      ;;
+      armv6j|armv6l)
+	cpuver=6
+      ;;
+      armv7a|armv7l)
+	cpuver=7
+      ;;
+    esac
+    cpu="arm"
+  ;;
+  aarch64)
+    cpu="aarch64"
+  ;;
+  alpha)
+    cpu="alpha"
+  ;;
+  "Power Macintosh"|ppc|ppc64)
+    cpu="ppc"
+  ;;
+  mips)
+    cpu="mips"
+  ;;
+  s390)
+    cpu="s390"
+  ;;
+  *)
+    echo "Unsupported CPU"
+    exit 1
+  ;;
+esac
+
+# Checking for CFLAGS
+if test -z "$CFLAGS"; then
+    CFLAGS="-Wall -g -O2"
+fi
+
+if test "$mingw32" = "yes" ; then
+    if test "$source_path_used" = "no"; then
+      source_path="."
+    fi
+    if test "$cc" = gcc; then
+      test -z "$LDFLAGS" && LDFLAGS="-static"
+    fi
+    test -z "$prefix" && prefix="C:/Program Files/tcc"
+    test -z "$tccdir" && tccdir="${prefix}"
+    test -z "$bindir" && bindir="${tccdir}"
+    test -z "$docdir" && docdir="${tccdir}/doc"
+    test -z "$libdir" && libdir="${tccdir}/libtcc"
+    confvars="$confvars WIN32"
+    LIBSUF=".lib"
+    EXESUF=".exe"
+    DLLSUF=".dll"
+else
+    if test -z "$prefix" ; then
+      prefix="/usr/local"
+    fi
+    if test -z "$sharedir" ; then
+      sharedir="${prefix}/share"
+    fi
+    if test x"$execprefix" = x""; then
+      execprefix="${prefix}"
+    fi
+    if test x"$libdir" = x""; then
+      libdir="${execprefix}/lib"
+    fi
+    if test x"$bindir" = x""; then
+      bindir="${execprefix}/bin"
+    fi
+    if test x"$docdir" = x""; then
+      docdir="${sharedir}/doc"
+    fi
+    if test x"$mandir" = x""; then
+      mandir="${sharedir}/man"
+    fi
+    if test x"$infodir" = x""; then
+      infodir="${sharedir}/info"
+    fi
+    if test x"$tccdir" = x""; then
+      tccdir="${libdir}/tcc"
+    fi
+    if test x"$includedir" = x""; then
+      includedir="${prefix}/include"
+    fi
+fi # mingw32
+
+if test x"$show_help" = "xyes" ; then
+cat << EOF
+Usage: configure [options]
+Options: [defaults in brackets after descriptions]
+
+Standard options:
+  --help                   print this message
+  --prefix=PREFIX          install in PREFIX [$prefix]
+  --exec-prefix=EPREFIX    install architecture-dependent files in EPREFIX
+			   [same as prefix]
+  --bindir=DIR             user executables in DIR [EPREFIX/bin]
+  --libdir=DIR             object code libraries in DIR [EPREFIX/lib]
+  --tccdir=DIR             installation directory [EPREFIX/lib/tcc]
+  --includedir=DIR         C header files in DIR [PREFIX/include]
+  --sharedir=DIR           documentation root DIR [PREFIX/share]
+  --docdir=DIR             documentation in DIR [SHAREDIR/doc/tcc]
+  --mandir=DIR             man documentation in DIR [SHAREDIR/man]
+  --infodir=DIR            info documentation in DIR [SHAREDIR/info]
+
+Advanced options (experts only):
+  --source-path=PATH       path of source code [$source_path]
+  --cross-prefix=PREFIX    use PREFIX for compile tools [$cross_prefix]
+  --sysroot=PREFIX         prepend PREFIX to library/include paths []
+  --cc=CC                  use C compiler CC [$cc]
+  --ar=AR                  create archives using AR [$ar]
+  --extra-cflags=          specify compiler flags [$CFLAGS]
+  --extra-ldflags=         specify linker options []
+  --cpu=CPU                CPU [$cpu]
+  --strip-binaries         strip symbol tables from resulting binaries
+  --disable-static         make libtcc.so instead of libtcc.a
+  --enable-static          make libtcc.a instead of libtcc.dll (win32)
+  --disable-rpath          disable use of -rpath with the above
+  --with-libgcc            use libgcc_s.so.1 instead of libtcc1.a
+  --enable-cross           build cross compilers
+  --with-selinux           use mmap for executable memory (with tcc -run)
+  --sysincludepaths=...    specify system include paths, colon separated
+  --libpaths=...           specify system library paths, colon separated
+  --crtprefix=...          specify locations of crt?.o, colon separated
+  --elfinterp=...          specify elf interpreter
+  --triplet=...            specify system library/include directory triplet
+  --config-uClibc,-musl,-mingw32... enable system specific configurations
+EOF
+#echo "NOTE: The object files are build at the place where configure is launched"
+exit 1
+fi
+
+cc="${cross_prefix}${cc}"
+ar="${cross_prefix}${ar}"
+strip="${cross_prefix}${strip}"
+
+if test -z "$cross_prefix" ; then
+  CONFTEST=./conftest$EXESUF
+  if ! $cc -o $CONFTEST $source_path/conftest.c 2>/dev/null ; then
+    echo "configure: error: '$cc' failed to compile conftest.c."
+  else
+    gcc_major="$($CONFTEST version)"
+    gcc_minor="$($CONFTEST minor)"
+  fi
+  bigendian="$($CONFTEST bigendian)"
+  if test "$mingw32" = "no" ; then
+
+      if test -z "$triplet"; then
+        tt="$($CONFTEST triplet)"
+        if test -n "$tt" -a -f "/usr/lib/$tt/crti.o" ; then
+          triplet="$tt"
+        fi
+      fi
+
+      if test -z "$triplet"; then
+        if test $cpu = "x86_64" -o $cpu = "aarch64" ; then
+          if test -f "/usr/lib64/crti.o" ; then
+            tcc_lddir="lib64"
+          fi
+        fi
+      fi
+
+      if test "$cpu" = "arm" ; then
+	if test "${triplet%eabihf}" != "$triplet" ; then
+	   confvars="$confvars arm_eabihf"
+	elif test "${triplet%eabi}" != "$triplet" ; then
+	   confvars="$confvars arm_eabi"
+	fi
+	if grep -s -q "^Features.* \(vfp\|iwmmxt\) " /proc/cpuinfo ; then
+	   confvars="$confvars arm_vfp"
+	fi
+      fi
+
+      if test "$suggest" = "yes"; then
+        if test -f "/lib/ld-uClibc.so.0" ; then
+          echo "Perhaps you want ./configure --config-uClibc"
+        fi
+        if test -f "/lib/ld-musl-$cpu.so.1"; then
+          echo "Perhaps you want ./configure --config-musl"
+        fi
+      fi
+  fi
+else
+  # if cross compiling, cannot launch a program, so make a static guess
+  case $cpu in
+    ppc|mips|s390)  bigendian=yes;;
+  esac
+fi
+
+if test "$bigendian" = "yes" ; then
+  confvars="$confvars BIGENDIAN"
+fi
+
+# a final configuration tuning
+if ! echo "$cc" | grep -q "tcc"; then
+  OPT1="-Wdeclaration-after-statement -fno-strict-aliasing"
+  # we want -Wno- but gcc does not always reject unknown -Wno- options
+  OPT2="-Wpointer-sign -Wsign-compare -Wunused-result"
+  if echo "$cc" | grep -q "clang"; then
+    OPT1="$OPT1 -fheinous-gnu-extensions"
+    OPT2="$OPT2 -Wstring-plus-int"
+  fi
+  $cc $OPT1 $OPT2 -o a.out -c -xc - < /dev/null > cc_msg.txt 2>&1
+  for o in $OPT1; do # enable these options
+    if ! grep -q -- $o cc_msg.txt; then CFLAGS="$CFLAGS $o"; fi
+  done
+  for o in $OPT2; do # disable these options
+    if ! grep -q -- $o cc_msg.txt; then CFLAGS="$CFLAGS -Wno-${o#-W*}"; fi
+  done
+  # cat cc_msg.txt
+  # echo $CFLAGS
+  rm -f cc_msg.txt a.out
+fi
+
+fcho() { if test -n "$2"; then echo "$1$2"; fi }
+
+fcho "Binary directory    " "$bindir"
+fcho "TinyCC directory    " "$tccdir"
+fcho "Library directory   " "$libdir"
+fcho "Include directory   " "$includedir"
+fcho "Manual directory    " "$mandir"
+fcho "Info directory      " "$infodir"
+fcho "Doc directory       " "$docdir"
+fcho "Target root prefix  " "$sysroot"
+echo "Source path         $source_path"
+echo "C compiler          $cc ($gcc_major.$gcc_minor)"
+echo "Target OS           $targetos"
+echo "CPU                 $cpu"
+fcho "Triplet             " "$triplet"
+fcho "Config              " "${confvars# }"
+echo "Creating config.mak and config.h"
+
+cat >config.mak <<EOF
+# Automatically generated by configure - do not modify
+prefix=$prefix
+bindir=\$(DESTDIR)$bindir
+tccdir=\$(DESTDIR)$tccdir
+libdir=\$(DESTDIR)$libdir
+includedir=\$(DESTDIR)$includedir
+mandir=\$(DESTDIR)$mandir
+infodir=\$(DESTDIR)$infodir
+docdir=\$(DESTDIR)$docdir
+CC=$cc
+GCC_MAJOR=$gcc_major
+GCC_MINOR=$gcc_minor
+AR=$ar
+STRIP=$strip -s -R .comment -R .note
+CFLAGS=$CFLAGS
+LDFLAGS=$LDFLAGS
+LIBSUF=$LIBSUF
+EXESUF=$EXESUF
+DLLSUF=$DLLSUF
+EOF
+
+print_inc() {
+  if test -n "$2"; then
+    echo "#ifndef $1" >> $TMPH
+    echo "# define $1 \"$2\"" >> $TMPH
+    echo "#endif" >> $TMPH
+  fi
+}
+
+print_mak() {
+  if test -n "$2"; then
+    echo "NATIVE_DEFINES+=-D$1=\"\\\"$2\\\"\"" >> config.mak
+  fi
+}
+
+print_mak_int() {
+  if test -n "$2"; then
+    echo "NATIVE_DEFINES+=-D$1=$2" >> config.mak
+  fi
+}
+
+echo "/* Automatically generated by configure - do not modify */" > $TMPH
+
+print_inc CONFIG_SYSROOT "$sysroot"
+print_inc CONFIG_TCCDIR "$tccdir"
+print_mak CONFIG_TCC_SYSINCLUDEPATHS "$tcc_sysincludepaths"
+print_mak CONFIG_TCC_LIBPATHS "$tcc_libpaths"
+print_mak CONFIG_TCC_CRTPREFIX "$tcc_crtprefix"
+print_mak CONFIG_TCC_ELFINTERP "$tcc_elfinterp"
+print_mak CONFIG_LDDIR "$tcc_lddir"
+print_mak CONFIG_TRIPLET "$triplet"
+print_mak_int TCC_CPU_VERSION "$cpuver"
+
+if test "$cpu" = "aarch64" ; then
+  echo "ARCH=arm64" >> config.mak
+else
+  echo "ARCH=$cpu" >> config.mak
+fi
+echo "TARGETOS=$targetos" >> config.mak
+
+for v in $confvars ; do
+  if test "${v%=*}" = "$v"; then
+    echo "CONFIG_$v=yes" >> config.mak
+  else
+    echo "CONFIG_$v" >> config.mak
+  fi
+done
+
+version=`head $source_path/VERSION`
+echo "VERSION = $version" >> config.mak
+echo "#define TCC_VERSION \"$version\"" >> $TMPH
+echo "@set VERSION $version" > config.texi
+
+if test "$source_path_used" = "yes" ; then
+    case $source_path in
+       /*) echo "TOPSRC=$source_path";;
+	*) echo "TOPSRC=\$(TOP)/$source_path";;
+     esac >>config.mak
+else
+     echo 'TOPSRC=$(TOP)' >>config.mak
+fi
+
+diff $TMPH config.h >/dev/null 2>&1
+if test $? -ne 0 ; then
+    mv -f $TMPH config.h
+else
+    echo "config.h is unchanged"
+fi
+
+rm -f $TMPN* $CONFTEST
+
+# ---------------------------------------------------------------------------
+# build tree in object directory if source path is different from current one
+
+fn_makelink()
+{
+    tgt=$1/$2
+    case $2 in
+    */*) dn=${2%/*}
+	 test -d $dn || mkdir -p $dn
+	 case $1 in
+	 /*) ;;
+	  *) while test $dn ; do
+		tgt=../$tgt; dn=${dn#${dn%%/*}}; dn=${dn#/}
+	     done
+	     ;;
+	 esac
+	 ;;
+    esac
+
+    ln -sfn $tgt $2 || ( echo "ln failed. Using cp instead."; cp -f $1/$2 $2 )
+}
+
+if test "$source_path_used" = "yes" ; then
+  FILES="Makefile lib/Makefile tests/Makefile tests/tests2/Makefile tests/pp/Makefile"
+  for f in $FILES ; do
+    fn_makelink $source_path $f
+  done
+fi
+
+# ---------------------------------------------------------------------------
Index: EcnlProtoTool/trunk/tcc-0.9.27/conftest.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/conftest.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/conftest.c	(revision 331)
@@ -0,0 +1,87 @@
+#include <stdio.h>
+
+/* Define architecture */
+#if defined(__i386__) || defined _M_IX86
+# define TRIPLET_ARCH "i386"
+#elif defined(__x86_64__) || defined _M_AMD64
+# define TRIPLET_ARCH "x86_64"
+#elif defined(__arm__)
+# define TRIPLET_ARCH "arm"
+#elif defined(__aarch64__)
+# define TRIPLET_ARCH "aarch64"
+#else
+# define TRIPLET_ARCH "unknown"
+#endif
+
+/* Define OS */
+#if defined (__linux__)
+# define TRIPLET_OS "linux"
+#elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
+# define TRIPLET_OS "kfreebsd"
+#elif defined _WIN32
+# define TRIPLET_OS "win32"
+#elif !defined (__GNU__)
+# define TRIPLET_OS "unknown"
+#endif
+
+/* Define calling convention and ABI */
+#if defined (__ARM_EABI__)
+# if defined (__ARM_PCS_VFP)
+#  define TRIPLET_ABI "gnueabihf"
+# else
+#  define TRIPLET_ABI "gnueabi"
+# endif
+#else
+# define TRIPLET_ABI "gnu"
+#endif
+
+#if defined _WIN32
+# define TRIPLET TRIPLET_ARCH "-" TRIPLET_OS
+#elif defined __GNU__
+# define TRIPLET TRIPLET_ARCH "-" TRIPLET_ABI
+#else
+# define TRIPLET TRIPLET_ARCH "-" TRIPLET_OS "-" TRIPLET_ABI
+#endif
+
+#if defined(_WIN32)
+int _CRT_glob = 0;
+#endif
+
+int main(int argc, char *argv[])
+{
+    switch(argc == 2 ? argv[1][0] : 0) {
+        case 'b':
+        {
+            volatile unsigned foo = 0x01234567;
+            puts(*(unsigned char*)&foo == 0x67 ? "no" : "yes");
+            break;
+        }
+#ifdef __GNUC__
+        case 'm':
+            printf("%d\n", __GNUC_MINOR__);
+            break;
+        case 'v':
+            printf("%d\n", __GNUC__);
+            break;
+#elif defined __TINYC__
+        case 'v':
+            puts("0");
+            break;
+        case 'm':
+            printf("%d\n", __TINYC__);
+            break;
+#else
+        case 'm':
+        case 'v':
+            puts("0");
+            break;
+#endif
+        case 't':
+            puts(TRIPLET);
+            break;
+
+        default:
+            break;
+    }
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/elf.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/elf.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/elf.h	(revision 331)
@@ -0,0 +1,3237 @@
+/* This file defines standard ELF types, structures, and macros.
+   Copyright (C) 1995-2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _ELF_H
+#define	_ELF_H 1
+
+#ifndef _WIN32
+#include <inttypes.h>
+#else
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef signed char int8_t;
+typedef short int int16_t;
+typedef int int32_t;
+typedef long long int int64_t;
+typedef unsigned char           uint8_t;
+typedef unsigned short int      uint16_t;
+typedef unsigned int            uint32_t;
+typedef unsigned long long int  uint64_t;
+#endif
+#endif
+
+/* Standard ELF types.  */
+
+/* Type for a 16-bit quantity.  */
+typedef uint16_t Elf32_Half;
+typedef uint16_t Elf64_Half;
+
+/* Types for signed and unsigned 32-bit quantities.  */
+typedef uint32_t Elf32_Word;
+typedef	int32_t  Elf32_Sword;
+typedef uint32_t Elf64_Word;
+typedef	int32_t  Elf64_Sword;
+
+/* Types for signed and unsigned 64-bit quantities.  */
+typedef uint64_t Elf32_Xword;
+typedef	int64_t  Elf32_Sxword;
+typedef uint64_t Elf64_Xword;
+typedef	int64_t  Elf64_Sxword;
+
+/* Type of addresses.  */
+typedef uint32_t Elf32_Addr;
+typedef uint64_t Elf64_Addr;
+
+/* Type of file offsets.  */
+typedef uint32_t Elf32_Off;
+typedef uint64_t Elf64_Off;
+
+/* Type for section indices, which are 16-bit quantities.  */
+typedef uint16_t Elf32_Section;
+typedef uint16_t Elf64_Section;
+
+/* Type for version symbol information.  */
+typedef Elf32_Half Elf32_Versym;
+typedef Elf64_Half Elf64_Versym;
+
+
+/* The ELF file header.  This appears at the start of every ELF file.  */
+
+#define EI_NIDENT (16)
+
+typedef struct
+{
+  unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
+  Elf32_Half	e_type;			/* Object file type */
+  Elf32_Half	e_machine;		/* Architecture */
+  Elf32_Word	e_version;		/* Object file version */
+  Elf32_Addr	e_entry;		/* Entry point virtual address */
+  Elf32_Off	e_phoff;		/* Program header table file offset */
+  Elf32_Off	e_shoff;		/* Section header table file offset */
+  Elf32_Word	e_flags;		/* Processor-specific flags */
+  Elf32_Half	e_ehsize;		/* ELF header size in bytes */
+  Elf32_Half	e_phentsize;		/* Program header table entry size */
+  Elf32_Half	e_phnum;		/* Program header table entry count */
+  Elf32_Half	e_shentsize;		/* Section header table entry size */
+  Elf32_Half	e_shnum;		/* Section header table entry count */
+  Elf32_Half	e_shstrndx;		/* Section header string table index */
+} __attribute__((packed)) Elf32_Ehdr;
+
+typedef struct
+{
+  unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
+  Elf64_Half	e_type;			/* Object file type */
+  Elf64_Half	e_machine;		/* Architecture */
+  Elf64_Word	e_version;		/* Object file version */
+  Elf64_Addr	e_entry;		/* Entry point virtual address */
+  Elf64_Off	e_phoff;		/* Program header table file offset */
+  Elf64_Off	e_shoff;		/* Section header table file offset */
+  Elf64_Word	e_flags;		/* Processor-specific flags */
+  Elf64_Half	e_ehsize;		/* ELF header size in bytes */
+  Elf64_Half	e_phentsize;		/* Program header table entry size */
+  Elf64_Half	e_phnum;		/* Program header table entry count */
+  Elf64_Half	e_shentsize;		/* Section header table entry size */
+  Elf64_Half	e_shnum;		/* Section header table entry count */
+  Elf64_Half	e_shstrndx;		/* Section header string table index */
+} __attribute__((packed)) Elf64_Ehdr;
+
+/* Fields in the e_ident array.  The EI_* macros are indices into the
+   array.  The macros under each EI_* macro are the values the byte
+   may have.  */
+
+#define EI_MAG0		0		/* File identification byte 0 index */
+#define ELFMAG0		0x7f		/* Magic number byte 0 */
+
+#define EI_MAG1		1		/* File identification byte 1 index */
+#define ELFMAG1		'E'		/* Magic number byte 1 */
+
+#define EI_MAG2		2		/* File identification byte 2 index */
+#define ELFMAG2		'L'		/* Magic number byte 2 */
+
+#define EI_MAG3		3		/* File identification byte 3 index */
+#define ELFMAG3		'F'		/* Magic number byte 3 */
+
+/* Conglomeration of the identification bytes, for easy testing as a word.  */
+#define	ELFMAG		"\177ELF"
+#define	SELFMAG		4
+
+#define EI_CLASS	4		/* File class byte index */
+#define ELFCLASSNONE	0		/* Invalid class */
+#define ELFCLASS32	1		/* 32-bit objects */
+#define ELFCLASS64	2		/* 64-bit objects */
+#define ELFCLASSNUM	3
+
+#define EI_DATA		5		/* Data encoding byte index */
+#define ELFDATANONE	0		/* Invalid data encoding */
+#define ELFDATA2LSB	1		/* 2's complement, little endian */
+#define ELFDATA2MSB	2		/* 2's complement, big endian */
+#define ELFDATANUM	3
+
+#define EI_VERSION	6		/* File version byte index */
+					/* Value must be EV_CURRENT */
+
+#define EI_OSABI	7		/* OS ABI identification */
+#define ELFOSABI_NONE		0	/* UNIX System V ABI */
+#define ELFOSABI_SYSV		0	/* Alias.  */
+#define ELFOSABI_HPUX		1	/* HP-UX */
+#define ELFOSABI_NETBSD		2	/* NetBSD.  */
+#define ELFOSABI_GNU		3	/* Object uses GNU ELF extensions.  */
+#define ELFOSABI_LINUX		ELFOSABI_GNU /* Compatibility alias.  */
+#define ELFOSABI_SOLARIS	6	/* Sun Solaris.  */
+#define ELFOSABI_AIX		7	/* IBM AIX.  */
+#define ELFOSABI_IRIX		8	/* SGI Irix.  */
+#define ELFOSABI_FREEBSD	9	/* FreeBSD.  */
+#define ELFOSABI_TRU64		10	/* Compaq TRU64 UNIX.  */
+#define ELFOSABI_MODESTO	11	/* Novell Modesto.  */
+#define ELFOSABI_OPENBSD	12	/* OpenBSD.  */
+#define ELFOSABI_ARM_AEABI	64	/* ARM EABI */
+#define ELFOSABI_ARM		97	/* ARM */
+#define ELFOSABI_STANDALONE	255	/* Standalone (embedded) application */
+
+#define EI_ABIVERSION	8		/* ABI version */
+
+#define EI_PAD		9		/* Byte index of padding bytes */
+
+/* Legal values for e_type (object file type).  */
+
+#define ET_NONE		0		/* No file type */
+#define ET_REL		1		/* Relocatable file */
+#define ET_EXEC		2		/* Executable file */
+#define ET_DYN		3		/* Shared object file */
+#define ET_CORE		4		/* Core file */
+#define	ET_NUM		5		/* Number of defined types */
+#define ET_LOOS		0xfe00		/* OS-specific range start */
+#define ET_HIOS		0xfeff		/* OS-specific range end */
+#define ET_LOPROC	0xff00		/* Processor-specific range start */
+#define ET_HIPROC	0xffff		/* Processor-specific range end */
+
+/* Legal values for e_machine (architecture).  */
+
+#define EM_NONE		 0		/* No machine */
+#define EM_M32		 1		/* AT&T WE 32100 */
+#define EM_SPARC	 2		/* SUN SPARC */
+#define EM_386		 3		/* Intel 80386 */
+#define EM_68K		 4		/* Motorola m68k family */
+#define EM_88K		 5		/* Motorola m88k family */
+#define EM_860		 7		/* Intel 80860 */
+#define EM_MIPS		 8		/* MIPS R3000 big-endian */
+#define EM_S370		 9		/* IBM System/370 */
+#define EM_MIPS_RS3_LE	10		/* MIPS R3000 little-endian */
+
+#define EM_PARISC	15		/* HPPA */
+#define EM_VPP500	17		/* Fujitsu VPP500 */
+#define EM_SPARC32PLUS	18		/* Sun's "v8plus" */
+#define EM_960		19		/* Intel 80960 */
+#define EM_PPC		20		/* PowerPC */
+#define EM_PPC64	21		/* PowerPC 64-bit */
+#define EM_S390		22		/* IBM S390 */
+
+#define EM_V800		36		/* NEC V800 series */
+#define EM_FR20		37		/* Fujitsu FR20 */
+#define EM_RH32		38		/* TRW RH-32 */
+#define EM_RCE		39		/* Motorola RCE */
+#define EM_ARM		40		/* ARM */
+#define EM_FAKE_ALPHA	41		/* Digital Alpha */
+#define EM_SH		42		/* Hitachi SH */
+#define EM_SPARCV9	43		/* SPARC v9 64-bit */
+#define EM_TRICORE	44		/* Siemens Tricore */
+#define EM_ARC		45		/* Argonaut RISC Core */
+#define EM_H8_300	46		/* Hitachi H8/300 */
+#define EM_H8_300H	47		/* Hitachi H8/300H */
+#define EM_H8S		48		/* Hitachi H8S */
+#define EM_H8_500	49		/* Hitachi H8/500 */
+#define EM_IA_64	50		/* Intel Merced */
+#define EM_MIPS_X	51		/* Stanford MIPS-X */
+#define EM_COLDFIRE	52		/* Motorola Coldfire */
+#define EM_68HC12	53		/* Motorola M68HC12 */
+#define EM_MMA		54		/* Fujitsu MMA Multimedia Accelerator*/
+#define EM_PCP		55		/* Siemens PCP */
+#define EM_NCPU		56		/* Sony nCPU embedded RISC */
+#define EM_NDR1		57		/* Denso NDR1 microprocessor */
+#define EM_STARCORE	58		/* Motorola Start*Core processor */
+#define EM_ME16		59		/* Toyota ME16 processor */
+#define EM_ST100	60		/* STMicroelectronic ST100 processor */
+#define EM_TINYJ	61		/* Advanced Logic Corp. Tinyj emb.fam*/
+#define EM_X86_64	62		/* AMD x86-64 architecture */
+#define EM_PDSP		63		/* Sony DSP Processor */
+
+#define EM_FX66		66		/* Siemens FX66 microcontroller */
+#define EM_ST9PLUS	67		/* STMicroelectronics ST9+ 8/16 mc */
+#define EM_ST7		68		/* STMicroelectronics ST7 8 bit mc */
+#define EM_68HC16	69		/* Motorola MC68HC16 microcontroller */
+#define EM_68HC11	70		/* Motorola MC68HC11 microcontroller */
+#define EM_68HC08	71		/* Motorola MC68HC08 microcontroller */
+#define EM_68HC05	72		/* Motorola MC68HC05 microcontroller */
+#define EM_SVX		73		/* Silicon Graphics SVx */
+#define EM_ST19		74		/* STMicroelectronics ST19 8 bit mc */
+#define EM_VAX		75		/* Digital VAX */
+#define EM_CRIS		76		/* Axis Communications 32-bit embedded processor */
+#define EM_JAVELIN	77		/* Infineon Technologies 32-bit embedded processor */
+#define EM_FIREPATH	78		/* Element 14 64-bit DSP Processor */
+#define EM_ZSP		79		/* LSI Logic 16-bit DSP Processor */
+#define EM_MMIX		80		/* Donald Knuth's educational 64-bit processor */
+#define EM_HUANY	81		/* Harvard University machine-independent object files */
+#define EM_PRISM	82		/* SiTera Prism */
+#define EM_AVR		83		/* Atmel AVR 8-bit microcontroller */
+#define EM_FR30		84		/* Fujitsu FR30 */
+#define EM_D10V		85		/* Mitsubishi D10V */
+#define EM_D30V		86		/* Mitsubishi D30V */
+#define EM_V850		87		/* NEC v850 */
+#define EM_M32R		88		/* Mitsubishi M32R */
+#define EM_MN10300	89		/* Matsushita MN10300 */
+#define EM_MN10200	90		/* Matsushita MN10200 */
+#define EM_PJ		91		/* picoJava */
+#define EM_OPENRISC	92		/* OpenRISC 32-bit embedded processor */
+#define EM_ARC_A5	93		/* ARC Cores Tangent-A5 */
+#define EM_XTENSA	94		/* Tensilica Xtensa Architecture */
+#define EM_AARCH64	183		/* ARM AARCH64 */
+#define EM_TILEPRO	188		/* Tilera TILEPro */
+#define EM_TILEGX	191		/* Tilera TILE-Gx */
+#define EM_NUM		192
+
+/* If it is necessary to assign new unofficial EM_* values, please
+   pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
+   chances of collision with official or non-GNU unofficial values.  */
+
+#define EM_ALPHA	0x9026
+#define EM_C60		0x9c60
+
+/* Legal values for e_version (version).  */
+
+#define EV_NONE		0		/* Invalid ELF version */
+#define EV_CURRENT	1		/* Current version */
+#define EV_NUM		2
+
+/* Section header.  */
+
+typedef struct
+{
+  Elf32_Word	sh_name;		/* Section name (string tbl index) */
+  Elf32_Word	sh_type;		/* Section type */
+  Elf32_Word	sh_flags;		/* Section flags */
+  Elf32_Addr	sh_addr;		/* Section virtual addr at execution */
+  Elf32_Off	sh_offset;		/* Section file offset */
+  Elf32_Word	sh_size;		/* Section size in bytes */
+  Elf32_Word	sh_link;		/* Link to another section */
+  Elf32_Word	sh_info;		/* Additional section information */
+  Elf32_Word	sh_addralign;		/* Section alignment */
+  Elf32_Word	sh_entsize;		/* Entry size if section holds table */
+} __attribute__((packed)) Elf32_Shdr;
+
+typedef struct
+{
+  Elf64_Word	sh_name;		/* Section name (string tbl index) */
+  Elf64_Word	sh_type;		/* Section type */
+  Elf64_Xword	sh_flags;		/* Section flags */
+  Elf64_Addr	sh_addr;		/* Section virtual addr at execution */
+  Elf64_Off	sh_offset;		/* Section file offset */
+  Elf64_Xword	sh_size;		/* Section size in bytes */
+  Elf64_Word	sh_link;		/* Link to another section */
+  Elf64_Word	sh_info;		/* Additional section information */
+  Elf64_Xword	sh_addralign;		/* Section alignment */
+  Elf64_Xword	sh_entsize;		/* Entry size if section holds table */
+} __attribute__((packed)) Elf64_Shdr;
+
+/* Special section indices.  */
+
+#define SHN_UNDEF	0		/* Undefined section */
+#define SHN_LORESERVE	0xff00		/* Start of reserved indices */
+#define SHN_LOPROC	0xff00		/* Start of processor-specific */
+#define SHN_BEFORE	0xff00		/* Order section before all others
+					   (Solaris).  */
+#define SHN_AFTER	0xff01		/* Order section after all others
+					   (Solaris).  */
+#define SHN_HIPROC	0xff1f		/* End of processor-specific */
+#define SHN_LOOS	0xff20		/* Start of OS-specific */
+#define SHN_HIOS	0xff3f		/* End of OS-specific */
+#define SHN_ABS		0xfff1		/* Associated symbol is absolute */
+#define SHN_COMMON	0xfff2		/* Associated symbol is common */
+#define SHN_XINDEX	0xffff		/* Index is in extra table.  */
+#define SHN_HIRESERVE	0xffff		/* End of reserved indices */
+
+/* Legal values for sh_type (section type).  */
+
+#define SHT_NULL	  0		/* Section header table entry unused */
+#define SHT_PROGBITS	  1		/* Program data */
+#define SHT_SYMTAB	  2		/* Symbol table */
+#define SHT_STRTAB	  3		/* String table */
+#define SHT_RELA	  4		/* Relocation entries with addends */
+#define SHT_HASH	  5		/* Symbol hash table */
+#define SHT_DYNAMIC	  6		/* Dynamic linking information */
+#define SHT_NOTE	  7		/* Notes */
+#define SHT_NOBITS	  8		/* Program space with no data (bss) */
+#define SHT_REL		  9		/* Relocation entries, no addends */
+#define SHT_SHLIB	  10		/* Reserved */
+#define SHT_DYNSYM	  11		/* Dynamic linker symbol table */
+#define SHT_INIT_ARRAY	  14		/* Array of constructors */
+#define SHT_FINI_ARRAY	  15		/* Array of destructors */
+#define SHT_PREINIT_ARRAY 16		/* Array of pre-constructors */
+#define SHT_GROUP	  17		/* Section group */
+#define SHT_SYMTAB_SHNDX  18		/* Extended section indices */
+#define	SHT_NUM		  19		/* Number of defined types.  */
+#define SHT_LOOS	  0x60000000	/* Start OS-specific.  */
+#define SHT_GNU_ATTRIBUTES 0x6ffffff5	/* Object attributes.  */
+#define SHT_GNU_HASH	  0x6ffffff6	/* GNU-style hash table.  */
+#define SHT_GNU_LIBLIST	  0x6ffffff7	/* Prelink library list */
+#define SHT_CHECKSUM	  0x6ffffff8	/* Checksum for DSO content.  */
+#define SHT_LOSUNW	  0x6ffffffa	/* Sun-specific low bound.  */
+#define SHT_SUNW_move	  0x6ffffffa
+#define SHT_SUNW_COMDAT   0x6ffffffb
+#define SHT_SUNW_syminfo  0x6ffffffc
+#define SHT_GNU_verdef	  0x6ffffffd	/* Version definition section.  */
+#define SHT_GNU_verneed	  0x6ffffffe	/* Version needs section.  */
+#define SHT_GNU_versym	  0x6fffffff	/* Version symbol table.  */
+#define SHT_HISUNW	  0x6fffffff	/* Sun-specific high bound.  */
+#define SHT_HIOS	  0x6fffffff	/* End OS-specific type */
+#define SHT_LOPROC	  0x70000000	/* Start of processor-specific */
+#define SHT_HIPROC	  0x7fffffff	/* End of processor-specific */
+#define SHT_LOUSER	  0x80000000	/* Start of application-specific */
+#define SHT_HIUSER	  0x8fffffff	/* End of application-specific */
+
+/* Legal values for sh_flags (section flags).  */
+
+#define SHF_WRITE	     (1 << 0)	/* Writable */
+#define SHF_ALLOC	     (1 << 1)	/* Occupies memory during execution */
+#define SHF_EXECINSTR	     (1 << 2)	/* Executable */
+#define SHF_MERGE	     (1 << 4)	/* Might be merged */
+#define SHF_STRINGS	     (1 << 5)	/* Contains nul-terminated strings */
+#define SHF_INFO_LINK	     (1 << 6)	/* `sh_info' contains SHT index */
+#define SHF_LINK_ORDER	     (1 << 7)	/* Preserve order after combining */
+#define SHF_OS_NONCONFORMING (1 << 8)	/* Non-standard OS specific handling
+					   required */
+#define SHF_GROUP	     (1 << 9)	/* Section is member of a group.  */
+#define SHF_TLS		     (1 << 10)	/* Section hold thread-local data.  */
+#define SHF_COMPRESSED	     (1 << 11)	/* Section with compressed data. */
+#define SHF_MASKOS	     0x0ff00000	/* OS-specific.  */
+#define SHF_MASKPROC	     0xf0000000	/* Processor-specific */
+#define SHF_ORDERED	     (1 << 30)	/* Special ordering requirement
+					   (Solaris).  */
+#define SHF_EXCLUDE	     (1 << 31)	/* Section is excluded unless
+					   referenced or allocated (Solaris).*/
+
+/* Section group handling.  */
+#define GRP_COMDAT	0x1		/* Mark group as COMDAT.  */
+
+/* Symbol table entry.  */
+
+typedef struct
+{
+  Elf32_Word	st_name;		/* Symbol name (string tbl index) */
+  Elf32_Addr	st_value;		/* Symbol value */
+  Elf32_Word	st_size;		/* Symbol size */
+  unsigned char	st_info;		/* Symbol type and binding */
+  unsigned char	st_other;		/* Symbol visibility */
+  Elf32_Section	st_shndx;		/* Section index */
+} __attribute__((packed)) Elf32_Sym;
+
+typedef struct
+{
+  Elf64_Word	st_name;		/* Symbol name (string tbl index) */
+  unsigned char	st_info;		/* Symbol type and binding */
+  unsigned char st_other;		/* Symbol visibility */
+  Elf64_Section	st_shndx;		/* Section index */
+  Elf64_Addr	st_value;		/* Symbol value */
+  Elf64_Xword	st_size;		/* Symbol size */
+} __attribute__((packed)) Elf64_Sym;
+
+/* The syminfo section if available contains additional information about
+   every dynamic symbol.  */
+
+typedef struct
+{
+  Elf32_Half si_boundto;		/* Direct bindings, symbol bound to */
+  Elf32_Half si_flags;			/* Per symbol flags */
+} __attribute__((packed)) Elf32_Syminfo;
+
+typedef struct
+{
+  Elf64_Half si_boundto;		/* Direct bindings, symbol bound to */
+  Elf64_Half si_flags;			/* Per symbol flags */
+} __attribute__((packed)) Elf64_Syminfo;
+
+/* Possible values for si_boundto.  */
+#define SYMINFO_BT_SELF		0xffff	/* Symbol bound to self */
+#define SYMINFO_BT_PARENT	0xfffe	/* Symbol bound to parent */
+#define SYMINFO_BT_LOWRESERVE	0xff00	/* Beginning of reserved entries */
+
+/* Possible bitmasks for si_flags.  */
+#define SYMINFO_FLG_DIRECT	0x0001	/* Direct bound symbol */
+#define SYMINFO_FLG_PASSTHRU	0x0002	/* Pass-thru symbol for translator */
+#define SYMINFO_FLG_COPY	0x0004	/* Symbol is a copy-reloc */
+#define SYMINFO_FLG_LAZYLOAD	0x0008	/* Symbol bound to object to be lazy
+					   loaded */
+/* Syminfo version values.  */
+#define SYMINFO_NONE		0
+#define SYMINFO_CURRENT		1
+#define SYMINFO_NUM		2
+
+
+/* How to extract and insert information held in the st_info field.  */
+
+#define ELF32_ST_BIND(val)		(((unsigned char) (val)) >> 4)
+#define ELF32_ST_TYPE(val)		((val) & 0xf)
+#define ELF32_ST_INFO(bind, type)	(((bind) << 4) + ((type) & 0xf))
+
+/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field.  */
+#define ELF64_ST_BIND(val)		ELF32_ST_BIND (val)
+#define ELF64_ST_TYPE(val)		ELF32_ST_TYPE (val)
+#define ELF64_ST_INFO(bind, type)	ELF32_ST_INFO ((bind), (type))
+
+/* Legal values for ST_BIND subfield of st_info (symbol binding).  */
+
+#define STB_LOCAL	0		/* Local symbol */
+#define STB_GLOBAL	1		/* Global symbol */
+#define STB_WEAK	2		/* Weak symbol */
+#define	STB_NUM		3		/* Number of defined types.  */
+#define STB_LOOS	10		/* Start of OS-specific */
+#define STB_GNU_UNIQUE	10		/* Unique symbol.  */
+#define STB_HIOS	12		/* End of OS-specific */
+#define STB_LOPROC	13		/* Start of processor-specific */
+#define STB_HIPROC	15		/* End of processor-specific */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_NOTYPE	0		/* Symbol type is unspecified */
+#define STT_OBJECT	1		/* Symbol is a data object */
+#define STT_FUNC	2		/* Symbol is a code object */
+#define STT_SECTION	3		/* Symbol associated with a section */
+#define STT_FILE	4		/* Symbol's name is file name */
+#define STT_COMMON	5		/* Symbol is a common data object */
+#define STT_TLS		6		/* Symbol is thread-local data object*/
+#define	STT_NUM		7		/* Number of defined types.  */
+#define STT_LOOS	10		/* Start of OS-specific */
+#define STT_GNU_IFUNC	10		/* Symbol is indirect code object */
+#define STT_HIOS	12		/* End of OS-specific */
+#define STT_LOPROC	13		/* Start of processor-specific */
+#define STT_HIPROC	15		/* End of processor-specific */
+
+
+/* Symbol table indices are found in the hash buckets and chain table
+   of a symbol hash table section.  This special index value indicates
+   the end of a chain, meaning no further symbols are found in that bucket.  */
+
+#define STN_UNDEF	0		/* End of a chain.  */
+
+
+/* How to extract and insert information held in the st_other field.  */
+
+#define ELF32_ST_VISIBILITY(o)	((o) & 0x03)
+
+/* For ELF64 the definitions are the same.  */
+#define ELF64_ST_VISIBILITY(o)	ELF32_ST_VISIBILITY (o)
+
+/* Symbol visibility specification encoded in the st_other field.  */
+#define STV_DEFAULT	0		/* Default symbol visibility rules */
+#define STV_INTERNAL	1		/* Processor specific hidden class */
+#define STV_HIDDEN	2		/* Sym unavailable in other modules */
+#define STV_PROTECTED	3		/* Not preemptible, not exported */
+
+
+/* Relocation table entry without addend (in section of type SHT_REL).  */
+
+typedef struct
+{
+  Elf32_Addr	r_offset;		/* Address */
+  Elf32_Word	r_info;			/* Relocation type and symbol index */
+} __attribute__((packed)) Elf32_Rel;
+
+/* I have seen two different definitions of the Elf64_Rel and
+   Elf64_Rela structures, so we'll leave them out until Novell (or
+   whoever) gets their act together.  */
+/* The following, at least, is used on Sparc v9, MIPS, and Alpha.  */
+
+typedef struct
+{
+  Elf64_Addr	r_offset;		/* Address */
+  Elf64_Xword	r_info;			/* Relocation type and symbol index */
+} __attribute__((packed)) Elf64_Rel;
+
+/* Relocation table entry with addend (in section of type SHT_RELA).  */
+
+typedef struct
+{
+  Elf32_Addr	r_offset;		/* Address */
+  Elf32_Word	r_info;			/* Relocation type and symbol index */
+  Elf32_Sword	r_addend;		/* Addend */
+} __attribute__((packed)) Elf32_Rela;
+
+typedef struct
+{
+  Elf64_Addr	r_offset;		/* Address */
+  Elf64_Xword	r_info;			/* Relocation type and symbol index */
+  Elf64_Sxword	r_addend;		/* Addend */
+} __attribute__((packed)) Elf64_Rela;
+
+/* How to extract and insert information held in the r_info field.  */
+
+#define ELF32_R_SYM(val)		((val) >> 8)
+#define ELF32_R_TYPE(val)		((val) & 0xff)
+#define ELF32_R_INFO(sym, type)		(((sym) << 8) + ((type) & 0xff))
+
+#define ELF64_R_SYM(i)			((i) >> 32)
+#define ELF64_R_TYPE(i)			((i) & 0xffffffff)
+#define ELF64_R_INFO(sym,type)		((((Elf64_Xword) (sym)) << 32) + (type))
+
+/* Program segment header.  */
+
+typedef struct
+{
+  Elf32_Word	p_type;			/* Segment type */
+  Elf32_Off	p_offset;		/* Segment file offset */
+  Elf32_Addr	p_vaddr;		/* Segment virtual address */
+  Elf32_Addr	p_paddr;		/* Segment physical address */
+  Elf32_Word	p_filesz;		/* Segment size in file */
+  Elf32_Word	p_memsz;		/* Segment size in memory */
+  Elf32_Word	p_flags;		/* Segment flags */
+  Elf32_Word	p_align;		/* Segment alignment */
+} __attribute__((packed)) Elf32_Phdr;
+
+typedef struct
+{
+  Elf64_Word	p_type;			/* Segment type */
+  Elf64_Word	p_flags;		/* Segment flags */
+  Elf64_Off	p_offset;		/* Segment file offset */
+  Elf64_Addr	p_vaddr;		/* Segment virtual address */
+  Elf64_Addr	p_paddr;		/* Segment physical address */
+  Elf64_Xword	p_filesz;		/* Segment size in file */
+  Elf64_Xword	p_memsz;		/* Segment size in memory */
+  Elf64_Xword	p_align;		/* Segment alignment */
+} __attribute__((packed)) Elf64_Phdr;
+
+/* Special value for e_phnum.  This indicates that the real number of
+   program headers is too large to fit into e_phnum.  Instead the real
+   value is in the field sh_info of section 0.  */
+
+#define PN_XNUM		0xffff
+
+/* Legal values for p_type (segment type).  */
+
+#define	PT_NULL		0		/* Program header table entry unused */
+#define PT_LOAD		1		/* Loadable program segment */
+#define PT_DYNAMIC	2		/* Dynamic linking information */
+#define PT_INTERP	3		/* Program interpreter */
+#define PT_NOTE		4		/* Auxiliary information */
+#define PT_SHLIB	5		/* Reserved */
+#define PT_PHDR		6		/* Entry for header table itself */
+#define PT_TLS		7		/* Thread-local storage segment */
+#define	PT_NUM		8		/* Number of defined types */
+#define PT_LOOS		0x60000000	/* Start of OS-specific */
+#define PT_GNU_EH_FRAME	0x6474e550	/* GCC .eh_frame_hdr segment */
+#define PT_GNU_STACK	0x6474e551	/* Indicates stack executability */
+#define PT_GNU_RELRO	0x6474e552	/* Read-only after relocation */
+#define PT_LOSUNW	0x6ffffffa
+#define PT_SUNWBSS	0x6ffffffa	/* Sun Specific segment */
+#define PT_SUNWSTACK	0x6ffffffb	/* Stack segment */
+#define PT_HISUNW	0x6fffffff
+#define PT_HIOS		0x6fffffff	/* End of OS-specific */
+#define PT_LOPROC	0x70000000	/* Start of processor-specific */
+#define PT_HIPROC	0x7fffffff	/* End of processor-specific */
+
+/* Legal values for p_flags (segment flags).  */
+
+#define PF_X		(1 << 0)	/* Segment is executable */
+#define PF_W		(1 << 1)	/* Segment is writable */
+#define PF_R		(1 << 2)	/* Segment is readable */
+#define PF_MASKOS	0x0ff00000	/* OS-specific */
+#define PF_MASKPROC	0xf0000000	/* Processor-specific */
+
+/* Legal values for note segment descriptor types for core files. */
+
+#define NT_PRSTATUS	1		/* Contains copy of prstatus struct */
+#define NT_FPREGSET	2		/* Contains copy of fpregset struct */
+#define NT_PRPSINFO	3		/* Contains copy of prpsinfo struct */
+#define NT_PRXREG	4		/* Contains copy of prxregset struct */
+#define NT_TASKSTRUCT	4		/* Contains copy of task structure */
+#define NT_PLATFORM	5		/* String from sysinfo(SI_PLATFORM) */
+#define NT_AUXV		6		/* Contains copy of auxv array */
+#define NT_GWINDOWS	7		/* Contains copy of gwindows struct */
+#define NT_ASRS		8		/* Contains copy of asrset struct */
+#define NT_PSTATUS	10		/* Contains copy of pstatus struct */
+#define NT_PSINFO	13		/* Contains copy of psinfo struct */
+#define NT_PRCRED	14		/* Contains copy of prcred struct */
+#define NT_UTSNAME	15		/* Contains copy of utsname struct */
+#define NT_LWPSTATUS	16		/* Contains copy of lwpstatus struct */
+#define NT_LWPSINFO	17		/* Contains copy of lwpinfo struct */
+#define NT_PRFPXREG	20		/* Contains copy of fprxregset struct */
+#define NT_PRXFPREG	0x46e62b7f	/* Contains copy of user_fxsr_struct */
+#define NT_PPC_VMX	0x100		/* PowerPC Altivec/VMX registers */
+#define NT_PPC_SPE	0x101		/* PowerPC SPE/EVR registers */
+#define NT_PPC_VSX	0x102		/* PowerPC VSX registers */
+#define NT_386_TLS	0x200		/* i386 TLS slots (struct user_desc) */
+#define NT_386_IOPERM	0x201		/* x86 io permission bitmap (1=deny) */
+#define NT_X86_XSTATE	0x202		/* x86 extended state using xsave */
+#define NT_S390_HIGH_GPRS	0x300	/* s390 upper register halves */
+#define NT_S390_TIMER	0x301		/* s390 timer register */
+#define NT_S390_TODCMP	0x302		/* s390 TOD clock comparator register */
+#define NT_S390_TODPREG	0x303		/* s390 TOD programmable register */
+#define NT_S390_CTRS	0x304		/* s390 control registers */
+#define NT_S390_PREFIX	0x305		/* s390 prefix register */
+#define NT_S390_LAST_BREAK	0x306	/* s390 breaking event address */
+#define NT_S390_SYSTEM_CALL	0x307	/* s390 system call restart data */
+#define NT_ARM_VFP	0x400		/* ARM VFP/NEON registers */
+#define NT_ARM_TLS	0x401		/* ARM TLS register */
+#define NT_ARM_HW_BREAK	0x402		/* ARM hardware breakpoint registers */
+#define NT_ARM_HW_WATCH	0x403		/* ARM hardware watchpoint registers */
+
+/* Legal values for the note segment descriptor types for object files.  */
+
+#define NT_VERSION	1		/* Contains a version string.  */
+
+
+/* Dynamic section entry.  */
+
+typedef struct
+{
+  Elf32_Sword	d_tag;			/* Dynamic entry type */
+  union
+    {
+      Elf32_Word d_val;			/* Integer value */
+      Elf32_Addr d_ptr;			/* Address value */
+    } d_un;
+} __attribute__((packed)) Elf32_Dyn;
+
+typedef struct
+{
+  Elf64_Sxword	d_tag;			/* Dynamic entry type */
+  union
+    {
+      Elf64_Xword d_val;		/* Integer value */
+      Elf64_Addr d_ptr;			/* Address value */
+    } d_un;
+} __attribute__((packed)) Elf64_Dyn;
+
+/* Legal values for d_tag (dynamic entry type).  */
+
+#define DT_NULL		0		/* Marks end of dynamic section */
+#define DT_NEEDED	1		/* Name of needed library */
+#define DT_PLTRELSZ	2		/* Size in bytes of PLT relocs */
+#define DT_PLTGOT	3		/* Processor defined value */
+#define DT_HASH		4		/* Address of symbol hash table */
+#define DT_STRTAB	5		/* Address of string table */
+#define DT_SYMTAB	6		/* Address of symbol table */
+#define DT_RELA		7		/* Address of Rela relocs */
+#define DT_RELASZ	8		/* Total size of Rela relocs */
+#define DT_RELAENT	9		/* Size of one Rela reloc */
+#define DT_STRSZ	10		/* Size of string table */
+#define DT_SYMENT	11		/* Size of one symbol table entry */
+#define DT_INIT		12		/* Address of init function */
+#define DT_FINI		13		/* Address of termination function */
+#define DT_SONAME	14		/* Name of shared object */
+#define DT_RPATH	15		/* Library search path (deprecated) */
+#define DT_SYMBOLIC	16		/* Start symbol search here */
+#define DT_REL		17		/* Address of Rel relocs */
+#define DT_RELSZ	18		/* Total size of Rel relocs */
+#define DT_RELENT	19		/* Size of one Rel reloc */
+#define DT_PLTREL	20		/* Type of reloc in PLT */
+#define DT_DEBUG	21		/* For debugging; unspecified */
+#define DT_TEXTREL	22		/* Reloc might modify .text */
+#define DT_JMPREL	23		/* Address of PLT relocs */
+#define	DT_BIND_NOW	24		/* Process relocations of object */
+#define	DT_INIT_ARRAY	25		/* Array with addresses of init fct */
+#define	DT_FINI_ARRAY	26		/* Array with addresses of fini fct */
+#define	DT_INIT_ARRAYSZ	27		/* Size in bytes of DT_INIT_ARRAY */
+#define	DT_FINI_ARRAYSZ	28		/* Size in bytes of DT_FINI_ARRAY */
+#define DT_RUNPATH	29		/* Library search path */
+#define DT_FLAGS	30		/* Flags for the object being loaded */
+#define DT_ENCODING	32		/* Start of encoded range */
+#define DT_PREINIT_ARRAY 32		/* Array with addresses of preinit fct*/
+#define DT_PREINIT_ARRAYSZ 33		/* size in bytes of DT_PREINIT_ARRAY */
+#define	DT_NUM		34		/* Number used */
+#define DT_LOOS		0x6000000d	/* Start of OS-specific */
+#define DT_HIOS		0x6ffff000	/* End of OS-specific */
+#define DT_LOPROC	0x70000000	/* Start of processor-specific */
+#define DT_HIPROC	0x7fffffff	/* End of processor-specific */
+#define	DT_PROCNUM	DT_MIPS_NUM	/* Most used by any processor */
+
+/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
+   Dyn.d_un.d_val field of the Elf*_Dyn structure.  This follows Sun's
+   approach.  */
+#define DT_VALRNGLO	0x6ffffd00
+#define DT_GNU_PRELINKED 0x6ffffdf5	/* Prelinking timestamp */
+#define DT_GNU_CONFLICTSZ 0x6ffffdf6	/* Size of conflict section */
+#define DT_GNU_LIBLISTSZ 0x6ffffdf7	/* Size of library list */
+#define DT_CHECKSUM	0x6ffffdf8
+#define DT_PLTPADSZ	0x6ffffdf9
+#define DT_MOVEENT	0x6ffffdfa
+#define DT_MOVESZ	0x6ffffdfb
+#define DT_FEATURE_1	0x6ffffdfc	/* Feature selection (DTF_*).  */
+#define DT_POSFLAG_1	0x6ffffdfd	/* Flags for DT_* entries, effecting
+					   the following DT_* entry.  */
+#define DT_SYMINSZ	0x6ffffdfe	/* Size of syminfo table (in bytes) */
+#define DT_SYMINENT	0x6ffffdff	/* Entry size of syminfo */
+#define DT_VALRNGHI	0x6ffffdff
+#define DT_VALTAGIDX(tag)	(DT_VALRNGHI - (tag))	/* Reverse order! */
+#define DT_VALNUM 12
+
+/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
+   Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
+
+   If any adjustment is made to the ELF object after it has been
+   built these entries will need to be adjusted.  */
+#define DT_ADDRRNGLO	0x6ffffe00
+#define DT_GNU_HASH	0x6ffffef5	/* GNU-style hash table.  */
+#define DT_TLSDESC_PLT	0x6ffffef6
+#define DT_TLSDESC_GOT	0x6ffffef7
+#define DT_GNU_CONFLICT	0x6ffffef8	/* Start of conflict section */
+#define DT_GNU_LIBLIST	0x6ffffef9	/* Library list */
+#define DT_CONFIG	0x6ffffefa	/* Configuration information.  */
+#define DT_DEPAUDIT	0x6ffffefb	/* Dependency auditing.  */
+#define DT_AUDIT	0x6ffffefc	/* Object auditing.  */
+#define	DT_PLTPAD	0x6ffffefd	/* PLT padding.  */
+#define	DT_MOVETAB	0x6ffffefe	/* Move table.  */
+#define DT_SYMINFO	0x6ffffeff	/* Syminfo table.  */
+#define DT_ADDRRNGHI	0x6ffffeff
+#define DT_ADDRTAGIDX(tag)	(DT_ADDRRNGHI - (tag))	/* Reverse order! */
+#define DT_ADDRNUM 11
+
+/* The versioning entry types.  The next are defined as part of the
+   GNU extension.  */
+#define DT_VERSYM	0x6ffffff0
+
+#define DT_RELACOUNT	0x6ffffff9
+#define DT_RELCOUNT	0x6ffffffa
+
+/* These were chosen by Sun.  */
+#define DT_FLAGS_1	0x6ffffffb	/* State flags, see DF_1_* below.  */
+#define	DT_VERDEF	0x6ffffffc	/* Address of version definition
+					   table */
+#define	DT_VERDEFNUM	0x6ffffffd	/* Number of version definitions */
+#define	DT_VERNEED	0x6ffffffe	/* Address of table with needed
+					   versions */
+#define	DT_VERNEEDNUM	0x6fffffff	/* Number of needed versions */
+#define DT_VERSIONTAGIDX(tag)	(DT_VERNEEDNUM - (tag))	/* Reverse order! */
+#define DT_VERSIONTAGNUM 16
+
+/* Sun added these machine-independent extensions in the "processor-specific"
+   range.  Be compatible.  */
+#define DT_AUXILIARY    0x7ffffffd      /* Shared object to load before self */
+#define DT_FILTER       0x7fffffff      /* Shared object to get values from */
+#define DT_EXTRATAGIDX(tag)	((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
+#define DT_EXTRANUM	3
+
+/* Values of `d_un.d_val' in the DT_FLAGS entry.  */
+#define DF_ORIGIN	0x00000001	/* Object may use DF_ORIGIN */
+#define DF_SYMBOLIC	0x00000002	/* Symbol resolutions starts here */
+#define DF_TEXTREL	0x00000004	/* Object contains text relocations */
+#define DF_BIND_NOW	0x00000008	/* No lazy binding for this object */
+#define DF_STATIC_TLS	0x00000010	/* Module uses the static TLS model */
+
+/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1
+   entry in the dynamic section.  */
+#define DF_1_NOW	0x00000001	/* Set RTLD_NOW for this object.  */
+#define DF_1_GLOBAL	0x00000002	/* Set RTLD_GLOBAL for this object.  */
+#define DF_1_GROUP	0x00000004	/* Set RTLD_GROUP for this object.  */
+#define DF_1_NODELETE	0x00000008	/* Set RTLD_NODELETE for this object.*/
+#define DF_1_LOADFLTR	0x00000010	/* Trigger filtee loading at runtime.*/
+#define DF_1_INITFIRST	0x00000020	/* Set RTLD_INITFIRST for this object*/
+#define DF_1_NOOPEN	0x00000040	/* Set RTLD_NOOPEN for this object.  */
+#define DF_1_ORIGIN	0x00000080	/* $ORIGIN must be handled.  */
+#define DF_1_DIRECT	0x00000100	/* Direct binding enabled.  */
+#define DF_1_TRANS	0x00000200
+#define DF_1_INTERPOSE	0x00000400	/* Object is used to interpose.  */
+#define DF_1_NODEFLIB	0x00000800	/* Ignore default lib search path.  */
+#define DF_1_NODUMP	0x00001000	/* Object can't be dldump'ed.  */
+#define DF_1_CONFALT	0x00002000	/* Configuration alternative created.*/
+#define DF_1_ENDFILTEE	0x00004000	/* Filtee terminates filters search. */
+#define	DF_1_DISPRELDNE	0x00008000	/* Disp reloc applied at build time. */
+#define	DF_1_DISPRELPND	0x00010000	/* Disp reloc applied at run-time.  */
+#define	DF_1_NODIRECT	0x00020000	/* Object has no-direct binding. */
+#define	DF_1_IGNMULDEF	0x00040000
+#define	DF_1_NOKSYMS	0x00080000
+#define	DF_1_NOHDR	0x00100000
+#define	DF_1_EDITED	0x00200000	/* Object is modified after built.  */
+#define	DF_1_NORELOC	0x00400000
+#define	DF_1_SYMINTPOSE	0x00800000	/* Object has individual interposers.  */
+#define	DF_1_GLOBAUDIT	0x01000000	/* Global auditing required.  */
+#define	DF_1_SINGLETON	0x02000000	/* Singleton symbols are used.  */
+
+/* Flags for the feature selection in DT_FEATURE_1.  */
+#define DTF_1_PARINIT	0x00000001
+#define DTF_1_CONFEXP	0x00000002
+
+/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry.  */
+#define DF_P1_LAZYLOAD	0x00000001	/* Lazyload following object.  */
+#define DF_P1_GROUPPERM	0x00000002	/* Symbols from next object are not
+					   generally available.  */
+
+/* Version definition sections.  */
+
+typedef struct
+{
+  Elf32_Half	vd_version;		/* Version revision */
+  Elf32_Half	vd_flags;		/* Version information */
+  Elf32_Half	vd_ndx;			/* Version Index */
+  Elf32_Half	vd_cnt;			/* Number of associated aux entries */
+  Elf32_Word	vd_hash;		/* Version name hash value */
+  Elf32_Word	vd_aux;			/* Offset in bytes to verdaux array */
+  Elf32_Word	vd_next;		/* Offset in bytes to next verdef
+					   entry */
+} __attribute__((packed)) Elf32_Verdef;
+
+typedef struct
+{
+  Elf64_Half	vd_version;		/* Version revision */
+  Elf64_Half	vd_flags;		/* Version information */
+  Elf64_Half	vd_ndx;			/* Version Index */
+  Elf64_Half	vd_cnt;			/* Number of associated aux entries */
+  Elf64_Word	vd_hash;		/* Version name hash value */
+  Elf64_Word	vd_aux;			/* Offset in bytes to verdaux array */
+  Elf64_Word	vd_next;		/* Offset in bytes to next verdef
+					   entry */
+} __attribute__((packed)) Elf64_Verdef;
+
+
+/* Legal values for vd_version (version revision).  */
+#define VER_DEF_NONE	0		/* No version */
+#define VER_DEF_CURRENT	1		/* Current version */
+#define VER_DEF_NUM	2		/* Given version number */
+
+/* Legal values for vd_flags (version information flags).  */
+#define VER_FLG_BASE	0x1		/* Version definition of file itself */
+#define VER_FLG_WEAK	0x2		/* Weak version identifier */
+
+/* Versym symbol index values.  */
+#define	VER_NDX_LOCAL		0	/* Symbol is local.  */
+#define	VER_NDX_GLOBAL		1	/* Symbol is global.  */
+#define	VER_NDX_LORESERVE	0xff00	/* Beginning of reserved entries.  */
+#define	VER_NDX_ELIMINATE	0xff01	/* Symbol is to be eliminated.  */
+
+/* Auxiliary version information.  */
+
+typedef struct
+{
+  Elf32_Word	vda_name;		/* Version or dependency names */
+  Elf32_Word	vda_next;		/* Offset in bytes to next verdaux
+					   entry */
+} __attribute__((packed)) Elf32_Verdaux;
+
+typedef struct
+{
+  Elf64_Word	vda_name;		/* Version or dependency names */
+  Elf64_Word	vda_next;		/* Offset in bytes to next verdaux
+					   entry */
+} __attribute__((packed)) Elf64_Verdaux;
+
+
+/* Version dependency section.  */
+
+typedef struct
+{
+  Elf32_Half	vn_version;		/* Version of structure */
+  Elf32_Half	vn_cnt;			/* Number of associated aux entries */
+  Elf32_Word	vn_file;		/* Offset of filename for this
+					   dependency */
+  Elf32_Word	vn_aux;			/* Offset in bytes to vernaux array */
+  Elf32_Word	vn_next;		/* Offset in bytes to next verneed
+					   entry */
+} __attribute__((packed)) Elf32_Verneed;
+
+typedef struct
+{
+  Elf64_Half	vn_version;		/* Version of structure */
+  Elf64_Half	vn_cnt;			/* Number of associated aux entries */
+  Elf64_Word	vn_file;		/* Offset of filename for this
+					   dependency */
+  Elf64_Word	vn_aux;			/* Offset in bytes to vernaux array */
+  Elf64_Word	vn_next;		/* Offset in bytes to next verneed
+					   entry */
+} __attribute__((packed)) Elf64_Verneed;
+
+
+/* Legal values for vn_version (version revision).  */
+#define VER_NEED_NONE	 0		/* No version */
+#define VER_NEED_CURRENT 1		/* Current version */
+#define VER_NEED_NUM	 2		/* Given version number */
+
+/* Auxiliary needed version information.  */
+
+typedef struct
+{
+  Elf32_Word	vna_hash;		/* Hash value of dependency name */
+  Elf32_Half	vna_flags;		/* Dependency specific information */
+  Elf32_Half	vna_other;		/* Unused */
+  Elf32_Word	vna_name;		/* Dependency name string offset */
+  Elf32_Word	vna_next;		/* Offset in bytes to next vernaux
+					   entry */
+} __attribute__((packed)) Elf32_Vernaux;
+
+typedef struct
+{
+  Elf64_Word	vna_hash;		/* Hash value of dependency name */
+  Elf64_Half	vna_flags;		/* Dependency specific information */
+  Elf64_Half	vna_other;		/* Unused */
+  Elf64_Word	vna_name;		/* Dependency name string offset */
+  Elf64_Word	vna_next;		/* Offset in bytes to next vernaux
+					   entry */
+} __attribute__((packed)) Elf64_Vernaux;
+
+
+/* Legal values for vna_flags.  */
+#define VER_FLG_WEAK	0x2		/* Weak version identifier */
+
+
+/* Auxiliary vector.  */
+
+/* This vector is normally only used by the program interpreter.  The
+   usual definition in an ABI supplement uses the name auxv_t.  The
+   vector is not usually defined in a standard <elf.h> file, but it
+   can't hurt.  We rename it to avoid conflicts.  The sizes of these
+   types are an arrangement between the exec server and the program
+   interpreter, so we don't fully specify them here.  */
+
+typedef struct
+{
+  uint32_t a_type;		/* Entry type */
+  union
+    {
+      uint32_t a_val;		/* Integer value */
+      /* We use to have pointer elements added here.  We cannot do that,
+	 though, since it does not work when using 32-bit definitions
+	 on 64-bit platforms and vice versa.  */
+    } a_un;
+} __attribute__((packed)) Elf32_auxv_t;
+
+typedef struct
+{
+  uint64_t a_type;		/* Entry type */
+  union
+    {
+      uint64_t a_val;		/* Integer value */
+      /* We use to have pointer elements added here.  We cannot do that,
+	 though, since it does not work when using 32-bit definitions
+	 on 64-bit platforms and vice versa.  */
+    } a_un;
+} __attribute__((packed)) Elf64_auxv_t;
+
+/* Legal values for a_type (entry type).  */
+
+#define AT_NULL		0		/* End of vector */
+#define AT_IGNORE	1		/* Entry should be ignored */
+#define AT_EXECFD	2		/* File descriptor of program */
+#define AT_PHDR		3		/* Program headers for program */
+#define AT_PHENT	4		/* Size of program header entry */
+#define AT_PHNUM	5		/* Number of program headers */
+#define AT_PAGESZ	6		/* System page size */
+#define AT_BASE		7		/* Base address of interpreter */
+#define AT_FLAGS	8		/* Flags */
+#define AT_ENTRY	9		/* Entry point of program */
+#define AT_NOTELF	10		/* Program is not ELF */
+#define AT_UID		11		/* Real uid */
+#define AT_EUID		12		/* Effective uid */
+#define AT_GID		13		/* Real gid */
+#define AT_EGID		14		/* Effective gid */
+#define AT_CLKTCK	17		/* Frequency of times() */
+
+/* Some more special a_type values describing the hardware.  */
+#define AT_PLATFORM	15		/* String identifying platform.  */
+#define AT_HWCAP	16		/* Machine dependent hints about
+					   processor capabilities.  */
+
+/* This entry gives some information about the FPU initialization
+   performed by the kernel.  */
+#define AT_FPUCW	18		/* Used FPU control word.  */
+
+/* Cache block sizes.  */
+#define AT_DCACHEBSIZE	19		/* Data cache block size.  */
+#define AT_ICACHEBSIZE	20		/* Instruction cache block size.  */
+#define AT_UCACHEBSIZE	21		/* Unified cache block size.  */
+
+/* A special ignored value for PPC, used by the kernel to control the
+   interpretation of the AUXV. Must be > 16.  */
+#define AT_IGNOREPPC	22		/* Entry should be ignored.  */
+
+#define	AT_SECURE	23		/* Boolean, was exec setuid-like?  */
+
+#define AT_BASE_PLATFORM 24		/* String identifying real platforms.*/
+
+#define AT_RANDOM	25		/* Address of 16 random bytes.  */
+
+#define AT_EXECFN	31		/* Filename of executable.  */
+
+/* Pointer to the global system page used for system calls and other
+   nice things.  */
+#define AT_SYSINFO	32
+#define AT_SYSINFO_EHDR	33
+
+/* Shapes of the caches.  Bits 0-3 contains associativity; bits 4-7 contains
+   log2 of line size; mask those to get cache size.  */
+#define AT_L1I_CACHESHAPE	34
+#define AT_L1D_CACHESHAPE	35
+#define AT_L2_CACHESHAPE	36
+#define AT_L3_CACHESHAPE	37
+
+/* Note section contents.  Each entry in the note section begins with
+   a header of a fixed form.  */
+
+typedef struct
+{
+  Elf32_Word n_namesz;			/* Length of the note's name.  */
+  Elf32_Word n_descsz;			/* Length of the note's descriptor.  */
+  Elf32_Word n_type;			/* Type of the note.  */
+} __attribute__((packed)) Elf32_Nhdr;
+
+typedef struct
+{
+  Elf64_Word n_namesz;			/* Length of the note's name.  */
+  Elf64_Word n_descsz;			/* Length of the note's descriptor.  */
+  Elf64_Word n_type;			/* Type of the note.  */
+} __attribute__((packed)) Elf64_Nhdr;
+
+/* Known names of notes.  */
+
+/* Solaris entries in the note section have this name.  */
+#define ELF_NOTE_SOLARIS	"SUNW Solaris"
+
+/* Note entries for GNU systems have this name.  */
+#define ELF_NOTE_GNU		"GNU"
+
+
+/* Defined types of notes for Solaris.  */
+
+/* Value of descriptor (one word) is desired pagesize for the binary.  */
+#define ELF_NOTE_PAGESIZE_HINT	1
+
+
+/* Defined note types for GNU systems.  */
+
+/* ABI information.  The descriptor consists of words:
+   word 0: OS descriptor
+   word 1: major version of the ABI
+   word 2: minor version of the ABI
+   word 3: subminor version of the ABI
+*/
+#define NT_GNU_ABI_TAG	1
+#define ELF_NOTE_ABI	NT_GNU_ABI_TAG /* Old name.  */
+
+/* Known OSes.  These values can appear in word 0 of an
+   NT_GNU_ABI_TAG note section entry.  */
+#define ELF_NOTE_OS_LINUX	0
+#define ELF_NOTE_OS_GNU		1
+#define ELF_NOTE_OS_SOLARIS2	2
+#define ELF_NOTE_OS_FREEBSD	3
+
+/* Synthetic hwcap information.  The descriptor begins with two words:
+   word 0: number of entries
+   word 1: bitmask of enabled entries
+   Then follow variable-length entries, one byte followed by a
+   '\0'-terminated hwcap name string.  The byte gives the bit
+   number to test if enabled, (1U << bit) & bitmask.  */
+#define NT_GNU_HWCAP	2
+
+/* Build ID bits as generated by ld --build-id.
+   The descriptor consists of any nonzero number of bytes.  */
+#define NT_GNU_BUILD_ID	3
+
+/* Version note generated by GNU gold containing a version string.  */
+#define NT_GNU_GOLD_VERSION	4
+
+
+/* Move records.  */
+typedef struct
+{
+  Elf32_Xword m_value;		/* Symbol value.  */
+  Elf32_Word m_info;		/* Size and index.  */
+  Elf32_Word m_poffset;		/* Symbol offset.  */
+  Elf32_Half m_repeat;		/* Repeat count.  */
+  Elf32_Half m_stride;		/* Stride info.  */
+} __attribute__((packed)) Elf32_Move;
+
+typedef struct
+{
+  Elf64_Xword m_value;		/* Symbol value.  */
+  Elf64_Xword m_info;		/* Size and index.  */
+  Elf64_Xword m_poffset;	/* Symbol offset.  */
+  Elf64_Half m_repeat;		/* Repeat count.  */
+  Elf64_Half m_stride;		/* Stride info.  */
+} __attribute__((packed)) Elf64_Move;
+
+/* Macro to construct move records.  */
+#define ELF32_M_SYM(info)	((info) >> 8)
+#define ELF32_M_SIZE(info)	((unsigned char) (info))
+#define ELF32_M_INFO(sym, size)	(((sym) << 8) + (unsigned char) (size))
+
+#define ELF64_M_SYM(info)	ELF32_M_SYM (info)
+#define ELF64_M_SIZE(info)	ELF32_M_SIZE (info)
+#define ELF64_M_INFO(sym, size)	ELF32_M_INFO (sym, size)
+
+
+/* Motorola 68k specific definitions.  */
+
+/* Values for Elf32_Ehdr.e_flags.  */
+#define EF_CPU32	0x00810000
+
+/* m68k relocs.  */
+
+#define R_68K_NONE	0		/* No reloc */
+#define R_68K_32	1		/* Direct 32 bit  */
+#define R_68K_16	2		/* Direct 16 bit  */
+#define R_68K_8		3		/* Direct 8 bit  */
+#define R_68K_PC32	4		/* PC relative 32 bit */
+#define R_68K_PC16	5		/* PC relative 16 bit */
+#define R_68K_PC8	6		/* PC relative 8 bit */
+#define R_68K_GOT32	7		/* 32 bit PC relative GOT entry */
+#define R_68K_GOT16	8		/* 16 bit PC relative GOT entry */
+#define R_68K_GOT8	9		/* 8 bit PC relative GOT entry */
+#define R_68K_GOT32O	10		/* 32 bit GOT offset */
+#define R_68K_GOT16O	11		/* 16 bit GOT offset */
+#define R_68K_GOT8O	12		/* 8 bit GOT offset */
+#define R_68K_PLT32	13		/* 32 bit PC relative PLT address */
+#define R_68K_PLT16	14		/* 16 bit PC relative PLT address */
+#define R_68K_PLT8	15		/* 8 bit PC relative PLT address */
+#define R_68K_PLT32O	16		/* 32 bit PLT offset */
+#define R_68K_PLT16O	17		/* 16 bit PLT offset */
+#define R_68K_PLT8O	18		/* 8 bit PLT offset */
+#define R_68K_COPY	19		/* Copy symbol at runtime */
+#define R_68K_GLOB_DAT	20		/* Create GOT entry */
+#define R_68K_JMP_SLOT	21		/* Create PLT entry */
+#define R_68K_RELATIVE	22		/* Adjust by program base */
+#define R_68K_TLS_GD32      25          /* 32 bit GOT offset for GD */
+#define R_68K_TLS_GD16      26          /* 16 bit GOT offset for GD */
+#define R_68K_TLS_GD8       27          /* 8 bit GOT offset for GD */
+#define R_68K_TLS_LDM32     28          /* 32 bit GOT offset for LDM */
+#define R_68K_TLS_LDM16     29          /* 16 bit GOT offset for LDM */
+#define R_68K_TLS_LDM8      30          /* 8 bit GOT offset for LDM */
+#define R_68K_TLS_LDO32     31          /* 32 bit module-relative offset */
+#define R_68K_TLS_LDO16     32          /* 16 bit module-relative offset */
+#define R_68K_TLS_LDO8      33          /* 8 bit module-relative offset */
+#define R_68K_TLS_IE32      34          /* 32 bit GOT offset for IE */
+#define R_68K_TLS_IE16      35          /* 16 bit GOT offset for IE */
+#define R_68K_TLS_IE8       36          /* 8 bit GOT offset for IE */
+#define R_68K_TLS_LE32      37          /* 32 bit offset relative to
+					   static TLS block */
+#define R_68K_TLS_LE16      38          /* 16 bit offset relative to
+					   static TLS block */
+#define R_68K_TLS_LE8       39          /* 8 bit offset relative to
+					   static TLS block */
+#define R_68K_TLS_DTPMOD32  40          /* 32 bit module number */
+#define R_68K_TLS_DTPREL32  41          /* 32 bit module-relative offset */
+#define R_68K_TLS_TPREL32   42          /* 32 bit TP-relative offset */
+/* Keep this the last entry.  */
+#define R_68K_NUM	43
+
+/* Intel 80386 specific definitions.  */
+
+/* i386 relocs.  */
+
+#define R_386_NONE	   0		/* No reloc */
+#define R_386_32	   1		/* Direct 32 bit  */
+#define R_386_PC32	   2		/* PC relative 32 bit */
+#define R_386_GOT32	   3		/* 32 bit GOT entry */
+#define R_386_PLT32	   4		/* 32 bit PLT address */
+#define R_386_COPY	   5		/* Copy symbol at runtime */
+#define R_386_GLOB_DAT	   6		/* Create GOT entry */
+#define R_386_JMP_SLOT	   7		/* Create PLT entry */
+#define R_386_RELATIVE	   8		/* Adjust by program base */
+#define R_386_GOTOFF	   9		/* 32 bit offset to GOT */
+#define R_386_GOTPC	   10		/* 32 bit PC relative offset to GOT */
+#define R_386_32PLT	   11
+#define R_386_TLS_TPOFF	   14		/* Offset in static TLS block */
+#define R_386_TLS_IE	   15		/* Address of GOT entry for static TLS
+					   block offset */
+#define R_386_TLS_GOTIE	   16		/* GOT entry for static TLS block
+					   offset */
+#define R_386_TLS_LE	   17		/* Offset relative to static TLS
+					   block */
+#define R_386_TLS_GD	   18		/* Direct 32 bit for GNU version of
+					   general dynamic thread local data */
+#define R_386_TLS_LDM	   19		/* Direct 32 bit for GNU version of
+					   local dynamic thread local data
+					   in LE code */
+#define R_386_16	   20
+#define R_386_PC16	   21
+#define R_386_8		   22
+#define R_386_PC8	   23
+#define R_386_TLS_GD_32	   24		/* Direct 32 bit for general dynamic
+					   thread local data */
+#define R_386_TLS_GD_PUSH  25		/* Tag for pushl in GD TLS code */
+#define R_386_TLS_GD_CALL  26		/* Relocation for call to
+					   __tls_get_addr() */
+#define R_386_TLS_GD_POP   27		/* Tag for popl in GD TLS code */
+#define R_386_TLS_LDM_32   28		/* Direct 32 bit for local dynamic
+					   thread local data in LE code */
+#define R_386_TLS_LDM_PUSH 29		/* Tag for pushl in LDM TLS code */
+#define R_386_TLS_LDM_CALL 30		/* Relocation for call to
+					   __tls_get_addr() in LDM code */
+#define R_386_TLS_LDM_POP  31		/* Tag for popl in LDM TLS code */
+#define R_386_TLS_LDO_32   32		/* Offset relative to TLS block */
+#define R_386_TLS_IE_32	   33		/* GOT entry for negated static TLS
+					   block offset */
+#define R_386_TLS_LE_32	   34		/* Negated offset relative to static
+					   TLS block */
+#define R_386_TLS_DTPMOD32 35		/* ID of module containing symbol */
+#define R_386_TLS_DTPOFF32 36		/* Offset in TLS block */
+#define R_386_TLS_TPOFF32  37		/* Negated offset in static TLS block */
+/* 38? */
+#define R_386_TLS_GOTDESC  39		/* GOT offset for TLS descriptor.  */
+#define R_386_TLS_DESC_CALL 40		/* Marker of call through TLS
+					   descriptor for
+					   relaxation.  */
+#define R_386_TLS_DESC     41		/* TLS descriptor containing
+					   pointer to code and to
+					   argument, returning the TLS
+					   offset for the symbol.  */
+#define R_386_IRELATIVE	   42		/* Adjust indirectly by program base */
+#define R_386_GOT32X       43		/* 32 bit GOT entry, relaxable */
+/* Keep this the last entry.  */
+#define R_386_NUM	   44
+
+/* SUN SPARC specific definitions.  */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_SPARC_REGISTER	13	/* Global register reserved to app. */
+
+/* Values for Elf64_Ehdr.e_flags.  */
+
+#define EF_SPARCV9_MM		3
+#define EF_SPARCV9_TSO		0
+#define EF_SPARCV9_PSO		1
+#define EF_SPARCV9_RMO		2
+#define EF_SPARC_LEDATA		0x800000 /* little endian data */
+#define EF_SPARC_EXT_MASK	0xFFFF00
+#define EF_SPARC_32PLUS		0x000100 /* generic V8+ features */
+#define EF_SPARC_SUN_US1	0x000200 /* Sun UltraSPARC1 extensions */
+#define EF_SPARC_HAL_R1		0x000400 /* HAL R1 extensions */
+#define EF_SPARC_SUN_US3	0x000800 /* Sun UltraSPARCIII extensions */
+
+/* SPARC relocs.  */
+
+#define R_SPARC_NONE		0	/* No reloc */
+#define R_SPARC_8		1	/* Direct 8 bit */
+#define R_SPARC_16		2	/* Direct 16 bit */
+#define R_SPARC_32		3	/* Direct 32 bit */
+#define R_SPARC_DISP8		4	/* PC relative 8 bit */
+#define R_SPARC_DISP16		5	/* PC relative 16 bit */
+#define R_SPARC_DISP32		6	/* PC relative 32 bit */
+#define R_SPARC_WDISP30		7	/* PC relative 30 bit shifted */
+#define R_SPARC_WDISP22		8	/* PC relative 22 bit shifted */
+#define R_SPARC_HI22		9	/* High 22 bit */
+#define R_SPARC_22		10	/* Direct 22 bit */
+#define R_SPARC_13		11	/* Direct 13 bit */
+#define R_SPARC_LO10		12	/* Truncated 10 bit */
+#define R_SPARC_GOT10		13	/* Truncated 10 bit GOT entry */
+#define R_SPARC_GOT13		14	/* 13 bit GOT entry */
+#define R_SPARC_GOT22		15	/* 22 bit GOT entry shifted */
+#define R_SPARC_PC10		16	/* PC relative 10 bit truncated */
+#define R_SPARC_PC22		17	/* PC relative 22 bit shifted */
+#define R_SPARC_WPLT30		18	/* 30 bit PC relative PLT address */
+#define R_SPARC_COPY		19	/* Copy symbol at runtime */
+#define R_SPARC_GLOB_DAT	20	/* Create GOT entry */
+#define R_SPARC_JMP_SLOT	21	/* Create PLT entry */
+#define R_SPARC_RELATIVE	22	/* Adjust by program base */
+#define R_SPARC_UA32		23	/* Direct 32 bit unaligned */
+
+/* Additional Sparc64 relocs.  */
+
+#define R_SPARC_PLT32		24	/* Direct 32 bit ref to PLT entry */
+#define R_SPARC_HIPLT22		25	/* High 22 bit PLT entry */
+#define R_SPARC_LOPLT10		26	/* Truncated 10 bit PLT entry */
+#define R_SPARC_PCPLT32		27	/* PC rel 32 bit ref to PLT entry */
+#define R_SPARC_PCPLT22		28	/* PC rel high 22 bit PLT entry */
+#define R_SPARC_PCPLT10		29	/* PC rel trunc 10 bit PLT entry */
+#define R_SPARC_10		30	/* Direct 10 bit */
+#define R_SPARC_11		31	/* Direct 11 bit */
+#define R_SPARC_64		32	/* Direct 64 bit */
+#define R_SPARC_OLO10		33	/* 10bit with secondary 13bit addend */
+#define R_SPARC_HH22		34	/* Top 22 bits of direct 64 bit */
+#define R_SPARC_HM10		35	/* High middle 10 bits of ... */
+#define R_SPARC_LM22		36	/* Low middle 22 bits of ... */
+#define R_SPARC_PC_HH22		37	/* Top 22 bits of pc rel 64 bit */
+#define R_SPARC_PC_HM10		38	/* High middle 10 bit of ... */
+#define R_SPARC_PC_LM22		39	/* Low middle 22 bits of ... */
+#define R_SPARC_WDISP16		40	/* PC relative 16 bit shifted */
+#define R_SPARC_WDISP19		41	/* PC relative 19 bit shifted */
+#define R_SPARC_GLOB_JMP	42	/* was part of v9 ABI but was removed */
+#define R_SPARC_7		43	/* Direct 7 bit */
+#define R_SPARC_5		44	/* Direct 5 bit */
+#define R_SPARC_6		45	/* Direct 6 bit */
+#define R_SPARC_DISP64		46	/* PC relative 64 bit */
+#define R_SPARC_PLT64		47	/* Direct 64 bit ref to PLT entry */
+#define R_SPARC_HIX22		48	/* High 22 bit complemented */
+#define R_SPARC_LOX10		49	/* Truncated 11 bit complemented */
+#define R_SPARC_H44		50	/* Direct high 12 of 44 bit */
+#define R_SPARC_M44		51	/* Direct mid 22 of 44 bit */
+#define R_SPARC_L44		52	/* Direct low 10 of 44 bit */
+#define R_SPARC_REGISTER	53	/* Global register usage */
+#define R_SPARC_UA64		54	/* Direct 64 bit unaligned */
+#define R_SPARC_UA16		55	/* Direct 16 bit unaligned */
+#define R_SPARC_TLS_GD_HI22	56
+#define R_SPARC_TLS_GD_LO10	57
+#define R_SPARC_TLS_GD_ADD	58
+#define R_SPARC_TLS_GD_CALL	59
+#define R_SPARC_TLS_LDM_HI22	60
+#define R_SPARC_TLS_LDM_LO10	61
+#define R_SPARC_TLS_LDM_ADD	62
+#define R_SPARC_TLS_LDM_CALL	63
+#define R_SPARC_TLS_LDO_HIX22	64
+#define R_SPARC_TLS_LDO_LOX10	65
+#define R_SPARC_TLS_LDO_ADD	66
+#define R_SPARC_TLS_IE_HI22	67
+#define R_SPARC_TLS_IE_LO10	68
+#define R_SPARC_TLS_IE_LD	69
+#define R_SPARC_TLS_IE_LDX	70
+#define R_SPARC_TLS_IE_ADD	71
+#define R_SPARC_TLS_LE_HIX22	72
+#define R_SPARC_TLS_LE_LOX10	73
+#define R_SPARC_TLS_DTPMOD32	74
+#define R_SPARC_TLS_DTPMOD64	75
+#define R_SPARC_TLS_DTPOFF32	76
+#define R_SPARC_TLS_DTPOFF64	77
+#define R_SPARC_TLS_TPOFF32	78
+#define R_SPARC_TLS_TPOFF64	79
+#define R_SPARC_GOTDATA_HIX22	80
+#define R_SPARC_GOTDATA_LOX10	81
+#define R_SPARC_GOTDATA_OP_HIX22	82
+#define R_SPARC_GOTDATA_OP_LOX10	83
+#define R_SPARC_GOTDATA_OP	84
+#define R_SPARC_H34		85
+#define R_SPARC_SIZE32		86
+#define R_SPARC_SIZE64		87
+#define R_SPARC_WDISP10		88
+#define R_SPARC_JMP_IREL	248
+#define R_SPARC_IRELATIVE	249
+#define R_SPARC_GNU_VTINHERIT	250
+#define R_SPARC_GNU_VTENTRY	251
+#define R_SPARC_REV32		252
+/* Keep this the last entry.  */
+#define R_SPARC_NUM		253
+
+/* For Sparc64, legal values for d_tag of Elf64_Dyn.  */
+
+#define DT_SPARC_REGISTER 0x70000001
+#define DT_SPARC_NUM	2
+
+/* MIPS R3000 specific definitions.  */
+
+/* Legal values for e_flags field of Elf32_Ehdr.  */
+
+#define EF_MIPS_NOREORDER   1		/* A .noreorder directive was used */
+#define EF_MIPS_PIC	    2		/* Contains PIC code */
+#define EF_MIPS_CPIC	    4		/* Uses PIC calling sequence */
+#define EF_MIPS_XGOT	    8
+#define EF_MIPS_64BIT_WHIRL 16
+#define EF_MIPS_ABI2	    32
+#define EF_MIPS_ABI_ON32    64
+#define EF_MIPS_ARCH	    0xf0000000	/* MIPS architecture level */
+
+/* Legal values for MIPS architecture level.  */
+
+#define EF_MIPS_ARCH_1	    0x00000000	/* -mips1 code.  */
+#define EF_MIPS_ARCH_2	    0x10000000	/* -mips2 code.  */
+#define EF_MIPS_ARCH_3	    0x20000000	/* -mips3 code.  */
+#define EF_MIPS_ARCH_4	    0x30000000	/* -mips4 code.  */
+#define EF_MIPS_ARCH_5	    0x40000000	/* -mips5 code.  */
+#define EF_MIPS_ARCH_32	    0x60000000	/* MIPS32 code.  */
+#define EF_MIPS_ARCH_64	    0x70000000	/* MIPS64 code.  */
+
+/* The following are non-official names and should not be used.  */
+
+#define E_MIPS_ARCH_1	  0x00000000	/* -mips1 code.  */
+#define E_MIPS_ARCH_2	  0x10000000	/* -mips2 code.  */
+#define E_MIPS_ARCH_3	  0x20000000	/* -mips3 code.  */
+#define E_MIPS_ARCH_4	  0x30000000	/* -mips4 code.  */
+#define E_MIPS_ARCH_5	  0x40000000	/* -mips5 code.  */
+#define E_MIPS_ARCH_32	  0x60000000	/* MIPS32 code.  */
+#define E_MIPS_ARCH_64	  0x70000000	/* MIPS64 code.  */
+
+/* Special section indices.  */
+
+#define SHN_MIPS_ACOMMON    0xff00	/* Allocated common symbols */
+#define SHN_MIPS_TEXT	    0xff01	/* Allocated test symbols.  */
+#define SHN_MIPS_DATA	    0xff02	/* Allocated data symbols.  */
+#define SHN_MIPS_SCOMMON    0xff03	/* Small common symbols */
+#define SHN_MIPS_SUNDEFINED 0xff04	/* Small undefined symbols */
+
+/* Legal values for sh_type field of Elf32_Shdr.  */
+
+#define SHT_MIPS_LIBLIST       0x70000000 /* Shared objects used in link */
+#define SHT_MIPS_MSYM	       0x70000001
+#define SHT_MIPS_CONFLICT      0x70000002 /* Conflicting symbols */
+#define SHT_MIPS_GPTAB	       0x70000003 /* Global data area sizes */
+#define SHT_MIPS_UCODE	       0x70000004 /* Reserved for SGI/MIPS compilers */
+#define SHT_MIPS_DEBUG	       0x70000005 /* MIPS ECOFF debugging information*/
+#define SHT_MIPS_REGINFO       0x70000006 /* Register usage information */
+#define SHT_MIPS_PACKAGE       0x70000007
+#define SHT_MIPS_PACKSYM       0x70000008
+#define SHT_MIPS_RELD	       0x70000009
+#define SHT_MIPS_IFACE         0x7000000b
+#define SHT_MIPS_CONTENT       0x7000000c
+#define SHT_MIPS_OPTIONS       0x7000000d /* Miscellaneous options.  */
+#define SHT_MIPS_SHDR	       0x70000010
+#define SHT_MIPS_FDESC	       0x70000011
+#define SHT_MIPS_EXTSYM	       0x70000012
+#define SHT_MIPS_DENSE	       0x70000013
+#define SHT_MIPS_PDESC	       0x70000014
+#define SHT_MIPS_LOCSYM	       0x70000015
+#define SHT_MIPS_AUXSYM	       0x70000016
+#define SHT_MIPS_OPTSYM	       0x70000017
+#define SHT_MIPS_LOCSTR	       0x70000018
+#define SHT_MIPS_LINE	       0x70000019
+#define SHT_MIPS_RFDESC	       0x7000001a
+#define SHT_MIPS_DELTASYM      0x7000001b
+#define SHT_MIPS_DELTAINST     0x7000001c
+#define SHT_MIPS_DELTACLASS    0x7000001d
+#define SHT_MIPS_DWARF         0x7000001e /* DWARF debugging information.  */
+#define SHT_MIPS_DELTADECL     0x7000001f
+#define SHT_MIPS_SYMBOL_LIB    0x70000020
+#define SHT_MIPS_EVENTS	       0x70000021 /* Event section.  */
+#define SHT_MIPS_TRANSLATE     0x70000022
+#define SHT_MIPS_PIXIE	       0x70000023
+#define SHT_MIPS_XLATE	       0x70000024
+#define SHT_MIPS_XLATE_DEBUG   0x70000025
+#define SHT_MIPS_WHIRL	       0x70000026
+#define SHT_MIPS_EH_REGION     0x70000027
+#define SHT_MIPS_XLATE_OLD     0x70000028
+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+
+/* Legal values for sh_flags field of Elf32_Shdr.  */
+
+#define SHF_MIPS_GPREL	 0x10000000	/* Must be part of global data area */
+#define SHF_MIPS_MERGE	 0x20000000
+#define SHF_MIPS_ADDR	 0x40000000
+#define SHF_MIPS_STRINGS 0x80000000
+#define SHF_MIPS_NOSTRIP 0x08000000
+#define SHF_MIPS_LOCAL	 0x04000000
+#define SHF_MIPS_NAMES	 0x02000000
+#define SHF_MIPS_NODUPE	 0x01000000
+
+
+/* Symbol tables.  */
+
+/* MIPS specific values for `st_other'.  */
+#define STO_MIPS_DEFAULT		0x0
+#define STO_MIPS_INTERNAL		0x1
+#define STO_MIPS_HIDDEN			0x2
+#define STO_MIPS_PROTECTED		0x3
+#define STO_MIPS_PLT			0x8
+#define STO_MIPS_SC_ALIGN_UNUSED	0xff
+
+/* MIPS specific values for `st_info'.  */
+#define STB_MIPS_SPLIT_COMMON		13
+
+/* Entries found in sections of type SHT_MIPS_GPTAB.  */
+
+typedef union
+{
+  struct
+    {
+      Elf32_Word gt_current_g_value;	/* -G value used for compilation */
+      Elf32_Word gt_unused;		/* Not used */
+    } gt_header;			/* First entry in section */
+  struct
+    {
+      Elf32_Word gt_g_value;		/* If this value were used for -G */
+      Elf32_Word gt_bytes;		/* This many bytes would be used */
+    } gt_entry;				/* Subsequent entries in section */
+} __attribute__((packed)) Elf32_gptab;
+
+/* Entry found in sections of type SHT_MIPS_REGINFO.  */
+
+typedef struct
+{
+  Elf32_Word	ri_gprmask;		/* General registers used */
+  Elf32_Word	ri_cprmask[4];		/* Coprocessor registers used */
+  Elf32_Sword	ri_gp_value;		/* $gp register value */
+} __attribute__((packed)) Elf32_RegInfo;
+
+/* Entries found in sections of type SHT_MIPS_OPTIONS.  */
+
+typedef struct
+{
+  unsigned char kind;		/* Determines interpretation of the
+				   variable part of descriptor.  */
+  unsigned char size;		/* Size of descriptor, including header.  */
+  Elf32_Section section;	/* Section header index of section affected,
+				   0 for global options.  */
+  Elf32_Word info;		/* Kind-specific information.  */
+} __attribute__((packed)) Elf_Options;
+
+/* Values for `kind' field in Elf_Options.  */
+
+#define ODK_NULL	0	/* Undefined.  */
+#define ODK_REGINFO	1	/* Register usage information.  */
+#define ODK_EXCEPTIONS	2	/* Exception processing options.  */
+#define ODK_PAD		3	/* Section padding options.  */
+#define ODK_HWPATCH	4	/* Hardware workarounds performed */
+#define ODK_FILL	5	/* record the fill value used by the linker. */
+#define ODK_TAGS	6	/* reserve space for desktop tools to write. */
+#define ODK_HWAND	7	/* HW workarounds.  'AND' bits when merging. */
+#define ODK_HWOR	8	/* HW workarounds.  'OR' bits when merging.  */
+
+/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries.  */
+
+#define OEX_FPU_MIN	0x1f	/* FPE's which MUST be enabled.  */
+#define OEX_FPU_MAX	0x1f00	/* FPE's which MAY be enabled.  */
+#define OEX_PAGE0	0x10000	/* page zero must be mapped.  */
+#define OEX_SMM		0x20000	/* Force sequential memory mode?  */
+#define OEX_FPDBUG	0x40000	/* Force floating point debug mode?  */
+#define OEX_PRECISEFP	OEX_FPDBUG
+#define OEX_DISMISS	0x80000	/* Dismiss invalid address faults?  */
+
+#define OEX_FPU_INVAL	0x10
+#define OEX_FPU_DIV0	0x08
+#define OEX_FPU_OFLO	0x04
+#define OEX_FPU_UFLO	0x02
+#define OEX_FPU_INEX	0x01
+
+/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry.  */
+
+#define OHW_R4KEOP	0x1	/* R4000 end-of-page patch.  */
+#define OHW_R8KPFETCH	0x2	/* may need R8000 prefetch patch.  */
+#define OHW_R5KEOP	0x4	/* R5000 end-of-page patch.  */
+#define OHW_R5KCVTL	0x8	/* R5000 cvt.[ds].l bug.  clean=1.  */
+
+#define OPAD_PREFIX	0x1
+#define OPAD_POSTFIX	0x2
+#define OPAD_SYMBOL	0x4
+
+/* Entry found in `.options' section.  */
+
+typedef struct
+{
+  Elf32_Word hwp_flags1;	/* Extra flags.  */
+  Elf32_Word hwp_flags2;	/* Extra flags.  */
+} __attribute__((packed)) Elf_Options_Hw;
+
+/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries.  */
+
+#define OHWA0_R4KEOP_CHECKED	0x00000001
+#define OHWA1_R4KEOP_CLEAN	0x00000002
+
+/* MIPS relocs.  */
+
+#define R_MIPS_NONE		0	/* No reloc */
+#define R_MIPS_16		1	/* Direct 16 bit */
+#define R_MIPS_32		2	/* Direct 32 bit */
+#define R_MIPS_REL32		3	/* PC relative 32 bit */
+#define R_MIPS_26		4	/* Direct 26 bit shifted */
+#define R_MIPS_HI16		5	/* High 16 bit */
+#define R_MIPS_LO16		6	/* Low 16 bit */
+#define R_MIPS_GPREL16		7	/* GP relative 16 bit */
+#define R_MIPS_LITERAL		8	/* 16 bit literal entry */
+#define R_MIPS_GOT16		9	/* 16 bit GOT entry */
+#define R_MIPS_PC16		10	/* PC relative 16 bit */
+#define R_MIPS_CALL16		11	/* 16 bit GOT entry for function */
+#define R_MIPS_GPREL32		12	/* GP relative 32 bit */
+
+#define R_MIPS_SHIFT5		16
+#define R_MIPS_SHIFT6		17
+#define R_MIPS_64		18
+#define R_MIPS_GOT_DISP		19
+#define R_MIPS_GOT_PAGE		20
+#define R_MIPS_GOT_OFST		21
+#define R_MIPS_GOT_HI16		22
+#define R_MIPS_GOT_LO16		23
+#define R_MIPS_SUB		24
+#define R_MIPS_INSERT_A		25
+#define R_MIPS_INSERT_B		26
+#define R_MIPS_DELETE		27
+#define R_MIPS_HIGHER		28
+#define R_MIPS_HIGHEST		29
+#define R_MIPS_CALL_HI16	30
+#define R_MIPS_CALL_LO16	31
+#define R_MIPS_SCN_DISP		32
+#define R_MIPS_REL16		33
+#define R_MIPS_ADD_IMMEDIATE	34
+#define R_MIPS_PJUMP		35
+#define R_MIPS_RELGOT		36
+#define R_MIPS_JALR		37
+#define R_MIPS_TLS_DTPMOD32	38	/* Module number 32 bit */
+#define R_MIPS_TLS_DTPREL32	39	/* Module-relative offset 32 bit */
+#define R_MIPS_TLS_DTPMOD64	40	/* Module number 64 bit */
+#define R_MIPS_TLS_DTPREL64	41	/* Module-relative offset 64 bit */
+#define R_MIPS_TLS_GD		42	/* 16 bit GOT offset for GD */
+#define R_MIPS_TLS_LDM		43	/* 16 bit GOT offset for LDM */
+#define R_MIPS_TLS_DTPREL_HI16	44	/* Module-relative offset, high 16 bits */
+#define R_MIPS_TLS_DTPREL_LO16	45	/* Module-relative offset, low 16 bits */
+#define R_MIPS_TLS_GOTTPREL	46	/* 16 bit GOT offset for IE */
+#define R_MIPS_TLS_TPREL32	47	/* TP-relative offset, 32 bit */
+#define R_MIPS_TLS_TPREL64	48	/* TP-relative offset, 64 bit */
+#define R_MIPS_TLS_TPREL_HI16	49	/* TP-relative offset, high 16 bits */
+#define R_MIPS_TLS_TPREL_LO16	50	/* TP-relative offset, low 16 bits */
+#define R_MIPS_GLOB_DAT		51
+#define R_MIPS_COPY		126
+#define R_MIPS_JUMP_SLOT        127
+/* Keep this the last entry.  */
+#define R_MIPS_NUM		128
+
+/* Legal values for p_type field of Elf32_Phdr.  */
+
+#define PT_MIPS_REGINFO	0x70000000	/* Register usage information */
+#define PT_MIPS_RTPROC  0x70000001	/* Runtime procedure table. */
+#define PT_MIPS_OPTIONS 0x70000002
+
+/* Special program header types.  */
+
+#define PF_MIPS_LOCAL	0x10000000
+
+/* Legal values for d_tag field of Elf32_Dyn.  */
+
+#define DT_MIPS_RLD_VERSION  0x70000001	/* Runtime linker interface version */
+#define DT_MIPS_TIME_STAMP   0x70000002	/* Timestamp */
+#define DT_MIPS_ICHECKSUM    0x70000003	/* Checksum */
+#define DT_MIPS_IVERSION     0x70000004	/* Version string (string tbl index) */
+#define DT_MIPS_FLAGS	     0x70000005	/* Flags */
+#define DT_MIPS_BASE_ADDRESS 0x70000006	/* Base address */
+#define DT_MIPS_MSYM	     0x70000007
+#define DT_MIPS_CONFLICT     0x70000008	/* Address of CONFLICT section */
+#define DT_MIPS_LIBLIST	     0x70000009	/* Address of LIBLIST section */
+#define DT_MIPS_LOCAL_GOTNO  0x7000000a	/* Number of local GOT entries */
+#define DT_MIPS_CONFLICTNO   0x7000000b	/* Number of CONFLICT entries */
+#define DT_MIPS_LIBLISTNO    0x70000010	/* Number of LIBLIST entries */
+#define DT_MIPS_SYMTABNO     0x70000011	/* Number of DYNSYM entries */
+#define DT_MIPS_UNREFEXTNO   0x70000012	/* First external DYNSYM */
+#define DT_MIPS_GOTSYM	     0x70000013	/* First GOT entry in DYNSYM */
+#define DT_MIPS_HIPAGENO     0x70000014	/* Number of GOT page table entries */
+#define DT_MIPS_RLD_MAP	     0x70000016	/* Address of run time loader map.  */
+#define DT_MIPS_DELTA_CLASS  0x70000017	/* Delta C++ class definition.  */
+#define DT_MIPS_DELTA_CLASS_NO    0x70000018 /* Number of entries in
+						DT_MIPS_DELTA_CLASS.  */
+#define DT_MIPS_DELTA_INSTANCE    0x70000019 /* Delta C++ class instances.  */
+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
+						DT_MIPS_DELTA_INSTANCE.  */
+#define DT_MIPS_DELTA_RELOC  0x7000001b /* Delta relocations.  */
+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
+					     DT_MIPS_DELTA_RELOC.  */
+#define DT_MIPS_DELTA_SYM    0x7000001d /* Delta symbols that Delta
+					   relocations refer to.  */
+#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
+					   DT_MIPS_DELTA_SYM.  */
+#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
+					     class declaration.  */
+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
+						DT_MIPS_DELTA_CLASSSYM.  */
+#define DT_MIPS_CXX_FLAGS    0x70000022 /* Flags indicating for C++ flavor.  */
+#define DT_MIPS_PIXIE_INIT   0x70000023
+#define DT_MIPS_SYMBOL_LIB   0x70000024
+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
+#define DT_MIPS_OPTIONS	     0x70000029 /* Address of .options.  */
+#define DT_MIPS_INTERFACE    0x7000002a /* Address of .interface.  */
+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
+#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
+						    function stored in GOT.  */
+#define DT_MIPS_PERF_SUFFIX  0x7000002e /* Default suffix of dso to be added
+					   by rld on dlopen() calls.  */
+#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
+#define DT_MIPS_GP_VALUE     0x70000030 /* GP value for aux GOTs.  */
+#define DT_MIPS_AUX_DYNAMIC  0x70000031 /* Address of aux .dynamic.  */
+/* The address of .got.plt in an executable using the new non-PIC ABI.  */
+#define DT_MIPS_PLTGOT	     0x70000032
+/* The base of the PLT in an executable using the new non-PIC ABI if that
+   PLT is writable.  For a non-writable PLT, this is omitted or has a zero
+   value.  */
+#define DT_MIPS_RWPLT        0x70000034
+#define DT_MIPS_NUM	     0x35
+
+/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry.  */
+
+#define RHF_NONE		   0		/* No flags */
+#define RHF_QUICKSTART		   (1 << 0)	/* Use quickstart */
+#define RHF_NOTPOT		   (1 << 1)	/* Hash size not power of 2 */
+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)	/* Ignore LD_LIBRARY_PATH */
+#define RHF_NO_MOVE		   (1 << 3)
+#define RHF_SGI_ONLY		   (1 << 4)
+#define RHF_GUARANTEE_INIT	   (1 << 5)
+#define RHF_DELTA_C_PLUS_PLUS	   (1 << 6)
+#define RHF_GUARANTEE_START_INIT   (1 << 7)
+#define RHF_PIXIE		   (1 << 8)
+#define RHF_DEFAULT_DELAY_LOAD	   (1 << 9)
+#define RHF_REQUICKSTART	   (1 << 10)
+#define RHF_REQUICKSTARTED	   (1 << 11)
+#define RHF_CORD		   (1 << 12)
+#define RHF_NO_UNRES_UNDEF	   (1 << 13)
+#define RHF_RLD_ORDER_SAFE	   (1 << 14)
+
+/* Entries found in sections of type SHT_MIPS_LIBLIST.  */
+
+typedef struct
+{
+  Elf32_Word l_name;		/* Name (string table index) */
+  Elf32_Word l_time_stamp;	/* Timestamp */
+  Elf32_Word l_checksum;	/* Checksum */
+  Elf32_Word l_version;		/* Interface version */
+  Elf32_Word l_flags;		/* Flags */
+} __attribute__((packed)) Elf32_Lib;
+
+typedef struct
+{
+  Elf64_Word l_name;		/* Name (string table index) */
+  Elf64_Word l_time_stamp;	/* Timestamp */
+  Elf64_Word l_checksum;	/* Checksum */
+  Elf64_Word l_version;		/* Interface version */
+  Elf64_Word l_flags;		/* Flags */
+} __attribute__((packed)) Elf64_Lib;
+
+
+/* Legal values for l_flags.  */
+
+#define LL_NONE		  0
+#define LL_EXACT_MATCH	  (1 << 0)	/* Require exact match */
+#define LL_IGNORE_INT_VER (1 << 1)	/* Ignore interface version */
+#define LL_REQUIRE_MINOR  (1 << 2)
+#define LL_EXPORTS	  (1 << 3)
+#define LL_DELAY_LOAD	  (1 << 4)
+#define LL_DELTA	  (1 << 5)
+
+/* Entries found in sections of type SHT_MIPS_CONFLICT.  */
+
+typedef Elf32_Addr Elf32_Conflict;
+
+
+/* HPPA specific definitions.  */
+
+/* Legal values for e_flags field of Elf32_Ehdr.  */
+
+#define EF_PARISC_TRAPNIL	0x00010000 /* Trap nil pointer dereference.  */
+#define EF_PARISC_EXT		0x00020000 /* Program uses arch. extensions. */
+#define EF_PARISC_LSB		0x00040000 /* Program expects little endian. */
+#define EF_PARISC_WIDE		0x00080000 /* Program expects wide mode.  */
+#define EF_PARISC_NO_KABP	0x00100000 /* No kernel assisted branch
+					      prediction.  */
+#define EF_PARISC_LAZYSWAP	0x00400000 /* Allow lazy swapping.  */
+#define EF_PARISC_ARCH		0x0000ffff /* Architecture version.  */
+
+/* Defined values for `e_flags & EF_PARISC_ARCH' are:  */
+
+#define EFA_PARISC_1_0		    0x020b /* PA-RISC 1.0 big-endian.  */
+#define EFA_PARISC_1_1		    0x0210 /* PA-RISC 1.1 big-endian.  */
+#define EFA_PARISC_2_0		    0x0214 /* PA-RISC 2.0 big-endian.  */
+
+/* Additional section indices.  */
+
+#define SHN_PARISC_ANSI_COMMON	0xff00	   /* Section for tentatively declared
+					      symbols in ANSI C.  */
+#define SHN_PARISC_HUGE_COMMON	0xff01	   /* Common blocks in huge model.  */
+
+/* Legal values for sh_type field of Elf32_Shdr.  */
+
+#define SHT_PARISC_EXT		0x70000000 /* Contains product specific ext. */
+#define SHT_PARISC_UNWIND	0x70000001 /* Unwind information.  */
+#define SHT_PARISC_DOC		0x70000002 /* Debug info for optimized code. */
+
+/* Legal values for sh_flags field of Elf32_Shdr.  */
+
+#define SHF_PARISC_SHORT	0x20000000 /* Section with short addressing. */
+#define SHF_PARISC_HUGE		0x40000000 /* Section far from gp.  */
+#define SHF_PARISC_SBP		0x80000000 /* Static branch prediction code. */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_PARISC_MILLICODE	13	/* Millicode function entry point.  */
+
+#define STT_HP_OPAQUE		(STT_LOOS + 0x1)
+#define STT_HP_STUB		(STT_LOOS + 0x2)
+
+/* HPPA relocs.  */
+
+#define R_PARISC_NONE		0	/* No reloc.  */
+#define R_PARISC_DIR32		1	/* Direct 32-bit reference.  */
+#define R_PARISC_DIR21L		2	/* Left 21 bits of eff. address.  */
+#define R_PARISC_DIR17R		3	/* Right 17 bits of eff. address.  */
+#define R_PARISC_DIR17F		4	/* 17 bits of eff. address.  */
+#define R_PARISC_DIR14R		6	/* Right 14 bits of eff. address.  */
+#define R_PARISC_PCREL32	9	/* 32-bit rel. address.  */
+#define R_PARISC_PCREL21L	10	/* Left 21 bits of rel. address.  */
+#define R_PARISC_PCREL17R	11	/* Right 17 bits of rel. address.  */
+#define R_PARISC_PCREL17F	12	/* 17 bits of rel. address.  */
+#define R_PARISC_PCREL14R	14	/* Right 14 bits of rel. address.  */
+#define R_PARISC_DPREL21L	18	/* Left 21 bits of rel. address.  */
+#define R_PARISC_DPREL14R	22	/* Right 14 bits of rel. address.  */
+#define R_PARISC_GPREL21L	26	/* GP-relative, left 21 bits.  */
+#define R_PARISC_GPREL14R	30	/* GP-relative, right 14 bits.  */
+#define R_PARISC_LTOFF21L	34	/* LT-relative, left 21 bits.  */
+#define R_PARISC_LTOFF14R	38	/* LT-relative, right 14 bits.  */
+#define R_PARISC_SECREL32	41	/* 32 bits section rel. address.  */
+#define R_PARISC_SEGBASE	48	/* No relocation, set segment base.  */
+#define R_PARISC_SEGREL32	49	/* 32 bits segment rel. address.  */
+#define R_PARISC_PLTOFF21L	50	/* PLT rel. address, left 21 bits.  */
+#define R_PARISC_PLTOFF14R	54	/* PLT rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF_FPTR32	57	/* 32 bits LT-rel. function pointer. */
+#define R_PARISC_LTOFF_FPTR21L	58	/* LT-rel. fct ptr, left 21 bits. */
+#define R_PARISC_LTOFF_FPTR14R	62	/* LT-rel. fct ptr, right 14 bits. */
+#define R_PARISC_FPTR64		64	/* 64 bits function address.  */
+#define R_PARISC_PLABEL32	65	/* 32 bits function address.  */
+#define R_PARISC_PLABEL21L	66	/* Left 21 bits of fdesc address.  */
+#define R_PARISC_PLABEL14R	70	/* Right 14 bits of fdesc address.  */
+#define R_PARISC_PCREL64	72	/* 64 bits PC-rel. address.  */
+#define R_PARISC_PCREL22F	74	/* 22 bits PC-rel. address.  */
+#define R_PARISC_PCREL14WR	75	/* PC-rel. address, right 14 bits.  */
+#define R_PARISC_PCREL14DR	76	/* PC rel. address, right 14 bits.  */
+#define R_PARISC_PCREL16F	77	/* 16 bits PC-rel. address.  */
+#define R_PARISC_PCREL16WF	78	/* 16 bits PC-rel. address.  */
+#define R_PARISC_PCREL16DF	79	/* 16 bits PC-rel. address.  */
+#define R_PARISC_DIR64		80	/* 64 bits of eff. address.  */
+#define R_PARISC_DIR14WR	83	/* 14 bits of eff. address.  */
+#define R_PARISC_DIR14DR	84	/* 14 bits of eff. address.  */
+#define R_PARISC_DIR16F		85	/* 16 bits of eff. address.  */
+#define R_PARISC_DIR16WF	86	/* 16 bits of eff. address.  */
+#define R_PARISC_DIR16DF	87	/* 16 bits of eff. address.  */
+#define R_PARISC_GPREL64	88	/* 64 bits of GP-rel. address.  */
+#define R_PARISC_GPREL14WR	91	/* GP-rel. address, right 14 bits.  */
+#define R_PARISC_GPREL14DR	92	/* GP-rel. address, right 14 bits.  */
+#define R_PARISC_GPREL16F	93	/* 16 bits GP-rel. address.  */
+#define R_PARISC_GPREL16WF	94	/* 16 bits GP-rel. address.  */
+#define R_PARISC_GPREL16DF	95	/* 16 bits GP-rel. address.  */
+#define R_PARISC_LTOFF64	96	/* 64 bits LT-rel. address.  */
+#define R_PARISC_LTOFF14WR	99	/* LT-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF14DR	100	/* LT-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF16F	101	/* 16 bits LT-rel. address.  */
+#define R_PARISC_LTOFF16WF	102	/* 16 bits LT-rel. address.  */
+#define R_PARISC_LTOFF16DF	103	/* 16 bits LT-rel. address.  */
+#define R_PARISC_SECREL64	104	/* 64 bits section rel. address.  */
+#define R_PARISC_SEGREL64	112	/* 64 bits segment rel. address.  */
+#define R_PARISC_PLTOFF14WR	115	/* PLT-rel. address, right 14 bits.  */
+#define R_PARISC_PLTOFF14DR	116	/* PLT-rel. address, right 14 bits.  */
+#define R_PARISC_PLTOFF16F	117	/* 16 bits LT-rel. address.  */
+#define R_PARISC_PLTOFF16WF	118	/* 16 bits PLT-rel. address.  */
+#define R_PARISC_PLTOFF16DF	119	/* 16 bits PLT-rel. address.  */
+#define R_PARISC_LTOFF_FPTR64	120	/* 64 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR14WR	123	/* LT-rel. fct. ptr., right 14 bits. */
+#define R_PARISC_LTOFF_FPTR14DR	124	/* LT-rel. fct. ptr., right 14 bits. */
+#define R_PARISC_LTOFF_FPTR16F	125	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR16WF	126	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR16DF	127	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LORESERVE	128
+#define R_PARISC_COPY		128	/* Copy relocation.  */
+#define R_PARISC_IPLT		129	/* Dynamic reloc, imported PLT */
+#define R_PARISC_EPLT		130	/* Dynamic reloc, exported PLT */
+#define R_PARISC_TPREL32	153	/* 32 bits TP-rel. address.  */
+#define R_PARISC_TPREL21L	154	/* TP-rel. address, left 21 bits.  */
+#define R_PARISC_TPREL14R	158	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF_TP21L	162	/* LT-TP-rel. address, left 21 bits. */
+#define R_PARISC_LTOFF_TP14R	166	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP14F	167	/* 14 bits LT-TP-rel. address.  */
+#define R_PARISC_TPREL64	216	/* 64 bits TP-rel. address.  */
+#define R_PARISC_TPREL14WR	219	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_TPREL14DR	220	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_TPREL16F	221	/* 16 bits TP-rel. address.  */
+#define R_PARISC_TPREL16WF	222	/* 16 bits TP-rel. address.  */
+#define R_PARISC_TPREL16DF	223	/* 16 bits TP-rel. address.  */
+#define R_PARISC_LTOFF_TP64	224	/* 64 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP14WR	227	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP14DR	228	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP16F	229	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP16WF	230	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP16DF	231	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_GNU_VTENTRY	232
+#define R_PARISC_GNU_VTINHERIT	233
+#define R_PARISC_TLS_GD21L	234	/* GD 21-bit left.  */
+#define R_PARISC_TLS_GD14R	235	/* GD 14-bit right.  */
+#define R_PARISC_TLS_GDCALL	236	/* GD call to __t_g_a.  */
+#define R_PARISC_TLS_LDM21L	237	/* LD module 21-bit left.  */
+#define R_PARISC_TLS_LDM14R	238	/* LD module 14-bit right.  */
+#define R_PARISC_TLS_LDMCALL	239	/* LD module call to __t_g_a.  */
+#define R_PARISC_TLS_LDO21L	240	/* LD offset 21-bit left.  */
+#define R_PARISC_TLS_LDO14R	241	/* LD offset 14-bit right.  */
+#define R_PARISC_TLS_DTPMOD32	242	/* DTP module 32-bit.  */
+#define R_PARISC_TLS_DTPMOD64	243	/* DTP module 64-bit.  */
+#define R_PARISC_TLS_DTPOFF32	244	/* DTP offset 32-bit.  */
+#define R_PARISC_TLS_DTPOFF64	245	/* DTP offset 32-bit.  */
+#define R_PARISC_TLS_LE21L	R_PARISC_TPREL21L
+#define R_PARISC_TLS_LE14R	R_PARISC_TPREL14R
+#define R_PARISC_TLS_IE21L	R_PARISC_LTOFF_TP21L
+#define R_PARISC_TLS_IE14R	R_PARISC_LTOFF_TP14R
+#define R_PARISC_TLS_TPREL32	R_PARISC_TPREL32
+#define R_PARISC_TLS_TPREL64	R_PARISC_TPREL64
+#define R_PARISC_HIRESERVE	255
+
+/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr.  */
+
+#define PT_HP_TLS		(PT_LOOS + 0x0)
+#define PT_HP_CORE_NONE		(PT_LOOS + 0x1)
+#define PT_HP_CORE_VERSION	(PT_LOOS + 0x2)
+#define PT_HP_CORE_KERNEL	(PT_LOOS + 0x3)
+#define PT_HP_CORE_COMM		(PT_LOOS + 0x4)
+#define PT_HP_CORE_PROC		(PT_LOOS + 0x5)
+#define PT_HP_CORE_LOADABLE	(PT_LOOS + 0x6)
+#define PT_HP_CORE_STACK	(PT_LOOS + 0x7)
+#define PT_HP_CORE_SHM		(PT_LOOS + 0x8)
+#define PT_HP_CORE_MMF		(PT_LOOS + 0x9)
+#define PT_HP_PARALLEL		(PT_LOOS + 0x10)
+#define PT_HP_FASTBIND		(PT_LOOS + 0x11)
+#define PT_HP_OPT_ANNOT		(PT_LOOS + 0x12)
+#define PT_HP_HSL_ANNOT		(PT_LOOS + 0x13)
+#define PT_HP_STACK		(PT_LOOS + 0x14)
+
+#define PT_PARISC_ARCHEXT	0x70000000
+#define PT_PARISC_UNWIND	0x70000001
+
+/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr.  */
+
+#define PF_PARISC_SBP		0x08000000
+
+#define PF_HP_PAGE_SIZE		0x00100000
+#define PF_HP_FAR_SHARED	0x00200000
+#define PF_HP_NEAR_SHARED	0x00400000
+#define PF_HP_CODE		0x01000000
+#define PF_HP_MODIFY		0x02000000
+#define PF_HP_LAZYSWAP		0x04000000
+#define PF_HP_SBP		0x08000000
+
+
+/* Alpha specific definitions.  */
+
+/* Legal values for e_flags field of Elf64_Ehdr.  */
+
+#define EF_ALPHA_32BIT		1	/* All addresses must be < 2GB.  */
+#define EF_ALPHA_CANRELAX	2	/* Relocations for relaxing exist.  */
+
+/* Legal values for sh_type field of Elf64_Shdr.  */
+
+/* These two are primarily concerned with ECOFF debugging info.  */
+#define SHT_ALPHA_DEBUG		0x70000001
+#define SHT_ALPHA_REGINFO	0x70000002
+
+/* Legal values for sh_flags field of Elf64_Shdr.  */
+
+#define SHF_ALPHA_GPREL		0x10000000
+
+/* Legal values for st_other field of Elf64_Sym.  */
+#define STO_ALPHA_NOPV		0x80	/* No PV required.  */
+#define STO_ALPHA_STD_GPLOAD	0x88	/* PV only used for initial ldgp.  */
+
+/* Alpha relocs.  */
+
+#define R_ALPHA_NONE		0	/* No reloc */
+#define R_ALPHA_REFLONG		1	/* Direct 32 bit */
+#define R_ALPHA_REFQUAD		2	/* Direct 64 bit */
+#define R_ALPHA_GPREL32		3	/* GP relative 32 bit */
+#define R_ALPHA_LITERAL		4	/* GP relative 16 bit w/optimization */
+#define R_ALPHA_LITUSE		5	/* Optimization hint for LITERAL */
+#define R_ALPHA_GPDISP		6	/* Add displacement to GP */
+#define R_ALPHA_BRADDR		7	/* PC+4 relative 23 bit shifted */
+#define R_ALPHA_HINT		8	/* PC+4 relative 16 bit shifted */
+#define R_ALPHA_SREL16		9	/* PC relative 16 bit */
+#define R_ALPHA_SREL32		10	/* PC relative 32 bit */
+#define R_ALPHA_SREL64		11	/* PC relative 64 bit */
+#define R_ALPHA_GPRELHIGH	17	/* GP relative 32 bit, high 16 bits */
+#define R_ALPHA_GPRELLOW	18	/* GP relative 32 bit, low 16 bits */
+#define R_ALPHA_GPREL16		19	/* GP relative 16 bit */
+#define R_ALPHA_COPY		24	/* Copy symbol at runtime */
+#define R_ALPHA_GLOB_DAT	25	/* Create GOT entry */
+#define R_ALPHA_JMP_SLOT	26	/* Create PLT entry */
+#define R_ALPHA_RELATIVE	27	/* Adjust by program base */
+#define R_ALPHA_TLS_GD_HI	28
+#define R_ALPHA_TLSGD		29
+#define R_ALPHA_TLS_LDM		30
+#define R_ALPHA_DTPMOD64	31
+#define R_ALPHA_GOTDTPREL	32
+#define R_ALPHA_DTPREL64	33
+#define R_ALPHA_DTPRELHI	34
+#define R_ALPHA_DTPRELLO	35
+#define R_ALPHA_DTPREL16	36
+#define R_ALPHA_GOTTPREL	37
+#define R_ALPHA_TPREL64		38
+#define R_ALPHA_TPRELHI		39
+#define R_ALPHA_TPRELLO		40
+#define R_ALPHA_TPREL16		41
+/* Keep this the last entry.  */
+#define R_ALPHA_NUM		46
+
+/* Magic values of the LITUSE relocation addend.  */
+#define LITUSE_ALPHA_ADDR	0
+#define LITUSE_ALPHA_BASE	1
+#define LITUSE_ALPHA_BYTOFF	2
+#define LITUSE_ALPHA_JSR	3
+#define LITUSE_ALPHA_TLS_GD	4
+#define LITUSE_ALPHA_TLS_LDM	5
+
+/* Legal values for d_tag of Elf64_Dyn.  */
+#define DT_ALPHA_PLTRO		(DT_LOPROC + 0)
+#define DT_ALPHA_NUM		1
+
+/* PowerPC specific declarations */
+
+/* Values for Elf32/64_Ehdr.e_flags.  */
+#define EF_PPC_EMB		0x80000000	/* PowerPC embedded flag */
+
+/* Cygnus local bits below */
+#define EF_PPC_RELOCATABLE	0x00010000	/* PowerPC -mrelocatable flag*/
+#define EF_PPC_RELOCATABLE_LIB	0x00008000	/* PowerPC -mrelocatable-lib
+						   flag */
+
+/* PowerPC relocations defined by the ABIs */
+#define R_PPC_NONE		0
+#define R_PPC_ADDR32		1	/* 32bit absolute address */
+#define R_PPC_ADDR24		2	/* 26bit address, 2 bits ignored.  */
+#define R_PPC_ADDR16		3	/* 16bit absolute address */
+#define R_PPC_ADDR16_LO		4	/* lower 16bit of absolute address */
+#define R_PPC_ADDR16_HI		5	/* high 16bit of absolute address */
+#define R_PPC_ADDR16_HA		6	/* adjusted high 16bit */
+#define R_PPC_ADDR14		7	/* 16bit address, 2 bits ignored */
+#define R_PPC_ADDR14_BRTAKEN	8
+#define R_PPC_ADDR14_BRNTAKEN	9
+#define R_PPC_REL24		10	/* PC relative 26 bit */
+#define R_PPC_REL14		11	/* PC relative 16 bit */
+#define R_PPC_REL14_BRTAKEN	12
+#define R_PPC_REL14_BRNTAKEN	13
+#define R_PPC_GOT16		14
+#define R_PPC_GOT16_LO		15
+#define R_PPC_GOT16_HI		16
+#define R_PPC_GOT16_HA		17
+#define R_PPC_PLTREL24		18
+#define R_PPC_COPY		19
+#define R_PPC_GLOB_DAT		20
+#define R_PPC_JMP_SLOT		21
+#define R_PPC_RELATIVE		22
+#define R_PPC_LOCAL24PC		23
+#define R_PPC_UADDR32		24
+#define R_PPC_UADDR16		25
+#define R_PPC_REL32		26
+#define R_PPC_PLT32		27
+#define R_PPC_PLTREL32		28
+#define R_PPC_PLT16_LO		29
+#define R_PPC_PLT16_HI		30
+#define R_PPC_PLT16_HA		31
+#define R_PPC_SDAREL16		32
+#define R_PPC_SECTOFF		33
+#define R_PPC_SECTOFF_LO	34
+#define R_PPC_SECTOFF_HI	35
+#define R_PPC_SECTOFF_HA	36
+
+/* PowerPC relocations defined for the TLS access ABI.  */
+#define R_PPC_TLS		67 /* none	(sym+add)@tls */
+#define R_PPC_DTPMOD32		68 /* word32	(sym+add)@dtpmod */
+#define R_PPC_TPREL16		69 /* half16*	(sym+add)@tprel */
+#define R_PPC_TPREL16_LO	70 /* half16	(sym+add)@tprel@l */
+#define R_PPC_TPREL16_HI	71 /* half16	(sym+add)@tprel@h */
+#define R_PPC_TPREL16_HA	72 /* half16	(sym+add)@tprel@ha */
+#define R_PPC_TPREL32		73 /* word32	(sym+add)@tprel */
+#define R_PPC_DTPREL16		74 /* half16*	(sym+add)@dtprel */
+#define R_PPC_DTPREL16_LO	75 /* half16	(sym+add)@dtprel@l */
+#define R_PPC_DTPREL16_HI	76 /* half16	(sym+add)@dtprel@h */
+#define R_PPC_DTPREL16_HA	77 /* half16	(sym+add)@dtprel@ha */
+#define R_PPC_DTPREL32		78 /* word32	(sym+add)@dtprel */
+#define R_PPC_GOT_TLSGD16	79 /* half16*	(sym+add)@got@tlsgd */
+#define R_PPC_GOT_TLSGD16_LO	80 /* half16	(sym+add)@got@tlsgd@l */
+#define R_PPC_GOT_TLSGD16_HI	81 /* half16	(sym+add)@got@tlsgd@h */
+#define R_PPC_GOT_TLSGD16_HA	82 /* half16	(sym+add)@got@tlsgd@ha */
+#define R_PPC_GOT_TLSLD16	83 /* half16*	(sym+add)@got@tlsld */
+#define R_PPC_GOT_TLSLD16_LO	84 /* half16	(sym+add)@got@tlsld@l */
+#define R_PPC_GOT_TLSLD16_HI	85 /* half16	(sym+add)@got@tlsld@h */
+#define R_PPC_GOT_TLSLD16_HA	86 /* half16	(sym+add)@got@tlsld@ha */
+#define R_PPC_GOT_TPREL16	87 /* half16*	(sym+add)@got@tprel */
+#define R_PPC_GOT_TPREL16_LO	88 /* half16	(sym+add)@got@tprel@l */
+#define R_PPC_GOT_TPREL16_HI	89 /* half16	(sym+add)@got@tprel@h */
+#define R_PPC_GOT_TPREL16_HA	90 /* half16	(sym+add)@got@tprel@ha */
+#define R_PPC_GOT_DTPREL16	91 /* half16*	(sym+add)@got@dtprel */
+#define R_PPC_GOT_DTPREL16_LO	92 /* half16*	(sym+add)@got@dtprel@l */
+#define R_PPC_GOT_DTPREL16_HI	93 /* half16*	(sym+add)@got@dtprel@h */
+#define R_PPC_GOT_DTPREL16_HA	94 /* half16*	(sym+add)@got@dtprel@ha */
+
+/* The remaining relocs are from the Embedded ELF ABI, and are not
+   in the SVR4 ELF ABI.  */
+#define R_PPC_EMB_NADDR32	101
+#define R_PPC_EMB_NADDR16	102
+#define R_PPC_EMB_NADDR16_LO	103
+#define R_PPC_EMB_NADDR16_HI	104
+#define R_PPC_EMB_NADDR16_HA	105
+#define R_PPC_EMB_SDAI16	106
+#define R_PPC_EMB_SDA2I16	107
+#define R_PPC_EMB_SDA2REL	108
+#define R_PPC_EMB_SDA21		109	/* 16 bit offset in SDA */
+#define R_PPC_EMB_MRKREF	110
+#define R_PPC_EMB_RELSEC16	111
+#define R_PPC_EMB_RELST_LO	112
+#define R_PPC_EMB_RELST_HI	113
+#define R_PPC_EMB_RELST_HA	114
+#define R_PPC_EMB_BIT_FLD	115
+#define R_PPC_EMB_RELSDA	116	/* 16 bit relative offset in SDA */
+
+/* Diab tool relocations.  */
+#define R_PPC_DIAB_SDA21_LO	180	/* like EMB_SDA21, but lower 16 bit */
+#define R_PPC_DIAB_SDA21_HI	181	/* like EMB_SDA21, but high 16 bit */
+#define R_PPC_DIAB_SDA21_HA	182	/* like EMB_SDA21, adjusted high 16 */
+#define R_PPC_DIAB_RELSDA_LO	183	/* like EMB_RELSDA, but lower 16 bit */
+#define R_PPC_DIAB_RELSDA_HI	184	/* like EMB_RELSDA, but high 16 bit */
+#define R_PPC_DIAB_RELSDA_HA	185	/* like EMB_RELSDA, adjusted high 16 */
+
+/* GNU extension to support local ifunc.  */
+#define R_PPC_IRELATIVE		248
+
+/* GNU relocs used in PIC code sequences.  */
+#define R_PPC_REL16		249	/* half16   (sym+add-.) */
+#define R_PPC_REL16_LO		250	/* half16   (sym+add-.)@l */
+#define R_PPC_REL16_HI		251	/* half16   (sym+add-.)@h */
+#define R_PPC_REL16_HA		252	/* half16   (sym+add-.)@ha */
+
+/* This is a phony reloc to handle any old fashioned TOC16 references
+   that may still be in object files.  */
+#define R_PPC_TOC16		255
+
+/* PowerPC specific values for the Dyn d_tag field.  */
+#define DT_PPC_GOT		(DT_LOPROC + 0)
+#define DT_PPC_NUM		1
+
+/* PowerPC64 relocations defined by the ABIs */
+#define R_PPC64_NONE		R_PPC_NONE
+#define R_PPC64_ADDR32		R_PPC_ADDR32 /* 32bit absolute address */
+#define R_PPC64_ADDR24		R_PPC_ADDR24 /* 26bit address, word aligned */
+#define R_PPC64_ADDR16		R_PPC_ADDR16 /* 16bit absolute address */
+#define R_PPC64_ADDR16_LO	R_PPC_ADDR16_LO	/* lower 16bits of address */
+#define R_PPC64_ADDR16_HI	R_PPC_ADDR16_HI	/* high 16bits of address. */
+#define R_PPC64_ADDR16_HA	R_PPC_ADDR16_HA /* adjusted high 16bits.  */
+#define R_PPC64_ADDR14		R_PPC_ADDR14 /* 16bit address, word aligned */
+#define R_PPC64_ADDR14_BRTAKEN	R_PPC_ADDR14_BRTAKEN
+#define R_PPC64_ADDR14_BRNTAKEN	R_PPC_ADDR14_BRNTAKEN
+#define R_PPC64_REL24		R_PPC_REL24 /* PC-rel. 26 bit, word aligned */
+#define R_PPC64_REL14		R_PPC_REL14 /* PC relative 16 bit */
+#define R_PPC64_REL14_BRTAKEN	R_PPC_REL14_BRTAKEN
+#define R_PPC64_REL14_BRNTAKEN	R_PPC_REL14_BRNTAKEN
+#define R_PPC64_GOT16		R_PPC_GOT16
+#define R_PPC64_GOT16_LO	R_PPC_GOT16_LO
+#define R_PPC64_GOT16_HI	R_PPC_GOT16_HI
+#define R_PPC64_GOT16_HA	R_PPC_GOT16_HA
+
+#define R_PPC64_COPY		R_PPC_COPY
+#define R_PPC64_GLOB_DAT	R_PPC_GLOB_DAT
+#define R_PPC64_JMP_SLOT	R_PPC_JMP_SLOT
+#define R_PPC64_RELATIVE	R_PPC_RELATIVE
+
+#define R_PPC64_UADDR32		R_PPC_UADDR32
+#define R_PPC64_UADDR16		R_PPC_UADDR16
+#define R_PPC64_REL32		R_PPC_REL32
+#define R_PPC64_PLT32		R_PPC_PLT32
+#define R_PPC64_PLTREL32	R_PPC_PLTREL32
+#define R_PPC64_PLT16_LO	R_PPC_PLT16_LO
+#define R_PPC64_PLT16_HI	R_PPC_PLT16_HI
+#define R_PPC64_PLT16_HA	R_PPC_PLT16_HA
+
+#define R_PPC64_SECTOFF		R_PPC_SECTOFF
+#define R_PPC64_SECTOFF_LO	R_PPC_SECTOFF_LO
+#define R_PPC64_SECTOFF_HI	R_PPC_SECTOFF_HI
+#define R_PPC64_SECTOFF_HA	R_PPC_SECTOFF_HA
+#define R_PPC64_ADDR30		37 /* word30 (S + A - P) >> 2 */
+#define R_PPC64_ADDR64		38 /* doubleword64 S + A */
+#define R_PPC64_ADDR16_HIGHER	39 /* half16 #higher(S + A) */
+#define R_PPC64_ADDR16_HIGHERA	40 /* half16 #highera(S + A) */
+#define R_PPC64_ADDR16_HIGHEST	41 /* half16 #highest(S + A) */
+#define R_PPC64_ADDR16_HIGHESTA	42 /* half16 #highesta(S + A) */
+#define R_PPC64_UADDR64		43 /* doubleword64 S + A */
+#define R_PPC64_REL64		44 /* doubleword64 S + A - P */
+#define R_PPC64_PLT64		45 /* doubleword64 L + A */
+#define R_PPC64_PLTREL64	46 /* doubleword64 L + A - P */
+#define R_PPC64_TOC16		47 /* half16* S + A - .TOC */
+#define R_PPC64_TOC16_LO	48 /* half16 #lo(S + A - .TOC.) */
+#define R_PPC64_TOC16_HI	49 /* half16 #hi(S + A - .TOC.) */
+#define R_PPC64_TOC16_HA	50 /* half16 #ha(S + A - .TOC.) */
+#define R_PPC64_TOC		51 /* doubleword64 .TOC */
+#define R_PPC64_PLTGOT16	52 /* half16* M + A */
+#define R_PPC64_PLTGOT16_LO	53 /* half16 #lo(M + A) */
+#define R_PPC64_PLTGOT16_HI	54 /* half16 #hi(M + A) */
+#define R_PPC64_PLTGOT16_HA	55 /* half16 #ha(M + A) */
+
+#define R_PPC64_ADDR16_DS	56 /* half16ds* (S + A) >> 2 */
+#define R_PPC64_ADDR16_LO_DS	57 /* half16ds  #lo(S + A) >> 2 */
+#define R_PPC64_GOT16_DS	58 /* half16ds* (G + A) >> 2 */
+#define R_PPC64_GOT16_LO_DS	59 /* half16ds  #lo(G + A) >> 2 */
+#define R_PPC64_PLT16_LO_DS	60 /* half16ds  #lo(L + A) >> 2 */
+#define R_PPC64_SECTOFF_DS	61 /* half16ds* (R + A) >> 2 */
+#define R_PPC64_SECTOFF_LO_DS	62 /* half16ds  #lo(R + A) >> 2 */
+#define R_PPC64_TOC16_DS	63 /* half16ds* (S + A - .TOC.) >> 2 */
+#define R_PPC64_TOC16_LO_DS	64 /* half16ds  #lo(S + A - .TOC.) >> 2 */
+#define R_PPC64_PLTGOT16_DS	65 /* half16ds* (M + A) >> 2 */
+#define R_PPC64_PLTGOT16_LO_DS	66 /* half16ds  #lo(M + A) >> 2 */
+
+/* PowerPC64 relocations defined for the TLS access ABI.  */
+#define R_PPC64_TLS		67 /* none	(sym+add)@tls */
+#define R_PPC64_DTPMOD64	68 /* doubleword64 (sym+add)@dtpmod */
+#define R_PPC64_TPREL16		69 /* half16*	(sym+add)@tprel */
+#define R_PPC64_TPREL16_LO	70 /* half16	(sym+add)@tprel@l */
+#define R_PPC64_TPREL16_HI	71 /* half16	(sym+add)@tprel@h */
+#define R_PPC64_TPREL16_HA	72 /* half16	(sym+add)@tprel@ha */
+#define R_PPC64_TPREL64		73 /* doubleword64 (sym+add)@tprel */
+#define R_PPC64_DTPREL16	74 /* half16*	(sym+add)@dtprel */
+#define R_PPC64_DTPREL16_LO	75 /* half16	(sym+add)@dtprel@l */
+#define R_PPC64_DTPREL16_HI	76 /* half16	(sym+add)@dtprel@h */
+#define R_PPC64_DTPREL16_HA	77 /* half16	(sym+add)@dtprel@ha */
+#define R_PPC64_DTPREL64	78 /* doubleword64 (sym+add)@dtprel */
+#define R_PPC64_GOT_TLSGD16	79 /* half16*	(sym+add)@got@tlsgd */
+#define R_PPC64_GOT_TLSGD16_LO	80 /* half16	(sym+add)@got@tlsgd@l */
+#define R_PPC64_GOT_TLSGD16_HI	81 /* half16	(sym+add)@got@tlsgd@h */
+#define R_PPC64_GOT_TLSGD16_HA	82 /* half16	(sym+add)@got@tlsgd@ha */
+#define R_PPC64_GOT_TLSLD16	83 /* half16*	(sym+add)@got@tlsld */
+#define R_PPC64_GOT_TLSLD16_LO	84 /* half16	(sym+add)@got@tlsld@l */
+#define R_PPC64_GOT_TLSLD16_HI	85 /* half16	(sym+add)@got@tlsld@h */
+#define R_PPC64_GOT_TLSLD16_HA	86 /* half16	(sym+add)@got@tlsld@ha */
+#define R_PPC64_GOT_TPREL16_DS	87 /* half16ds*	(sym+add)@got@tprel */
+#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */
+#define R_PPC64_GOT_TPREL16_HI	89 /* half16	(sym+add)@got@tprel@h */
+#define R_PPC64_GOT_TPREL16_HA	90 /* half16	(sym+add)@got@tprel@ha */
+#define R_PPC64_GOT_DTPREL16_DS	91 /* half16ds*	(sym+add)@got@dtprel */
+#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */
+#define R_PPC64_GOT_DTPREL16_HI	93 /* half16	(sym+add)@got@dtprel@h */
+#define R_PPC64_GOT_DTPREL16_HA	94 /* half16	(sym+add)@got@dtprel@ha */
+#define R_PPC64_TPREL16_DS	95 /* half16ds*	(sym+add)@tprel */
+#define R_PPC64_TPREL16_LO_DS	96 /* half16ds	(sym+add)@tprel@l */
+#define R_PPC64_TPREL16_HIGHER	97 /* half16	(sym+add)@tprel@higher */
+#define R_PPC64_TPREL16_HIGHERA	98 /* half16	(sym+add)@tprel@highera */
+#define R_PPC64_TPREL16_HIGHEST	99 /* half16	(sym+add)@tprel@highest */
+#define R_PPC64_TPREL16_HIGHESTA 100 /* half16	(sym+add)@tprel@highesta */
+#define R_PPC64_DTPREL16_DS	101 /* half16ds* (sym+add)@dtprel */
+#define R_PPC64_DTPREL16_LO_DS	102 /* half16ds	(sym+add)@dtprel@l */
+#define R_PPC64_DTPREL16_HIGHER	103 /* half16	(sym+add)@dtprel@higher */
+#define R_PPC64_DTPREL16_HIGHERA 104 /* half16	(sym+add)@dtprel@highera */
+#define R_PPC64_DTPREL16_HIGHEST 105 /* half16	(sym+add)@dtprel@highest */
+#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16	(sym+add)@dtprel@highesta */
+
+/* GNU extension to support local ifunc.  */
+#define R_PPC64_JMP_IREL	247
+#define R_PPC64_IRELATIVE	248
+#define R_PPC64_REL16		249	/* half16   (sym+add-.) */
+#define R_PPC64_REL16_LO	250	/* half16   (sym+add-.)@l */
+#define R_PPC64_REL16_HI	251	/* half16   (sym+add-.)@h */
+#define R_PPC64_REL16_HA	252	/* half16   (sym+add-.)@ha */
+
+/* PowerPC64 specific values for the Dyn d_tag field.  */
+#define DT_PPC64_GLINK  (DT_LOPROC + 0)
+#define DT_PPC64_OPD	(DT_LOPROC + 1)
+#define DT_PPC64_OPDSZ	(DT_LOPROC + 2)
+#define DT_PPC64_NUM    3
+
+
+/* ARM specific declarations */
+
+/* Processor specific flags for the ELF header e_flags field.  */
+#define EF_ARM_RELEXEC		0x01
+#define EF_ARM_HASENTRY		0x02
+#define EF_ARM_INTERWORK	0x04
+#define EF_ARM_APCS_26		0x08
+#define EF_ARM_APCS_FLOAT	0x10
+#define EF_ARM_PIC		0x20
+#define EF_ARM_ALIGN8		0x40 /* 8-bit structure alignment is in use */
+#define EF_ARM_NEW_ABI		0x80
+#define EF_ARM_OLD_ABI		0x100
+#define EF_ARM_SOFT_FLOAT	0x200
+#define EF_ARM_VFP_FLOAT	0x400
+#define EF_ARM_MAVERICK_FLOAT	0x800
+
+#define EF_ARM_ABI_FLOAT_SOFT	0x200   /* NB conflicts with EF_ARM_SOFT_FLOAT */
+#define EF_ARM_ABI_FLOAT_HARD	0x400   /* NB conflicts with EF_ARM_VFP_FLOAT */
+
+
+/* Other constants defined in the ARM ELF spec. version B-01.  */
+/* NB. These conflict with values defined above.  */
+#define EF_ARM_SYMSARESORTED	0x04
+#define EF_ARM_DYNSYMSUSESEGIDX	0x08
+#define EF_ARM_MAPSYMSFIRST	0x10
+#define EF_ARM_EABIMASK		0XFF000000
+
+/* Constants defined in AAELF.  */
+#define EF_ARM_BE8	    0x00800000
+#define EF_ARM_LE8	    0x00400000
+
+#define EF_ARM_EABI_VERSION(flags)	((flags) & EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN	0x00000000
+#define EF_ARM_EABI_VER1	0x01000000
+#define EF_ARM_EABI_VER2	0x02000000
+#define EF_ARM_EABI_VER3	0x03000000
+#define EF_ARM_EABI_VER4	0x04000000
+#define EF_ARM_EABI_VER5	0x05000000
+
+/* Additional symbol types for Thumb.  */
+#define STT_ARM_TFUNC		STT_LOPROC /* A Thumb function.  */
+#define STT_ARM_16BIT		STT_HIPROC /* A Thumb label.  */
+
+/* ARM-specific values for sh_flags */
+#define SHF_ARM_ENTRYSECT	0x10000000 /* Section contains an entry point */
+#define SHF_ARM_COMDEF		0x80000000 /* Section may be multiply defined
+					      in the input to a link step.  */
+
+/* ARM-specific program header flags */
+#define PF_ARM_SB		0x10000000 /* Segment contains the location
+					      addressed by the static base. */
+#define PF_ARM_PI		0x20000000 /* Position-independent segment.  */
+#define PF_ARM_ABS		0x40000000 /* Absolute segment.  */
+
+/* Processor specific values for the Phdr p_type field.  */
+#define PT_ARM_EXIDX		(PT_LOPROC + 1)	/* ARM unwind segment.  */
+
+/* Processor specific values for the Shdr sh_type field.  */
+#define SHT_ARM_EXIDX		(SHT_LOPROC + 1) /* ARM unwind section.  */
+#define SHT_ARM_PREEMPTMAP	(SHT_LOPROC + 2) /* Preemption details.  */
+#define SHT_ARM_ATTRIBUTES	(SHT_LOPROC + 3) /* ARM attributes section.  */
+
+
+/* AArch64 relocs.  */
+
+#define R_AARCH64_NONE            0	/* No relocation.  */
+#define R_AARCH64_ABS64         257	/* Direct 64 bit. */
+#define R_AARCH64_ABS32         258	/* Direct 32 bit.  */
+#define R_AARCH64_ABS16         259	/* Direct 16-bit.  */
+#define R_AARCH64_PREL64        260	/* PC-relative 64-bit.  */
+#define R_AARCH64_PREL32        261	/* PC-relative 32-bit.  */
+#define R_AARCH64_PREL16        262	/* PC-relative 16-bit.  */
+#define R_AARCH64_MOVW_UABS_G0  263	/* Dir. MOVZ imm. from bits 15:0.  */
+#define R_AARCH64_MOVW_UABS_G0_NC 264	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_UABS_G1  265	/* Dir. MOVZ imm. from bits 31:16.  */
+#define R_AARCH64_MOVW_UABS_G1_NC 266	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_UABS_G2  267	/* Dir. MOVZ imm. from bits 47:32.  */
+#define R_AARCH64_MOVW_UABS_G2_NC 268	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_UABS_G3  269	/* Dir. MOV{K,Z} imm. from 63:48.  */
+#define R_AARCH64_MOVW_SABS_G0  270	/* Dir. MOV{N,Z} imm. from 15:0.  */
+#define R_AARCH64_MOVW_SABS_G1  271	/* Dir. MOV{N,Z} imm. from 31:16.  */
+#define R_AARCH64_MOVW_SABS_G2  272	/* Dir. MOV{N,Z} imm. from 47:32.  */
+#define R_AARCH64_LD_PREL_LO19  273	/* PC-rel. LD imm. from bits 20:2.  */
+#define R_AARCH64_ADR_PREL_LO21 274	/* PC-rel. ADR imm. from bits 20:0.  */
+#define R_AARCH64_ADR_PREL_PG_HI21 275	/* Page-rel. ADRP imm. from 32:12.  */
+#define R_AARCH64_ADR_PREL_PG_HI21_NC 276	/* Likewise; no overflow check.  */
+#define R_AARCH64_ADD_ABS_LO12_NC 277	/* Dir. ADD imm. from bits 11:0.  */
+#define R_AARCH64_LDST8_ABS_LO12_NC 278	/* Likewise for LD/ST; no check. */
+#define R_AARCH64_TSTBR14       279	/* PC-rel. TBZ/TBNZ imm. from 15:2.  */
+#define R_AARCH64_CONDBR19      280	/* PC-rel. cond. br. imm. from 20:2. */
+#define R_AARCH64_JUMP26        282	/* PC-rel. B imm. from bits 27:2.  */
+#define R_AARCH64_CALL26        283	/* Likewise for CALL.  */
+#define R_AARCH64_LDST16_ABS_LO12_NC 284	/* Dir. ADD imm. from bits 11:1.  */
+#define R_AARCH64_LDST32_ABS_LO12_NC 285	/* Likewise for bits 11:2.  */
+#define R_AARCH64_LDST64_ABS_LO12_NC 286	/* Likewise for bits 11:3.  */
+#define R_AARCH64_MOVW_PREL_G0  287	/* PC-rel. MOV{N,Z} imm. from 15:0.  */
+#define R_AARCH64_MOVW_PREL_G0_NC 288	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_PREL_G1  289	/* PC-rel. MOV{N,Z} imm. from 31:16. */
+#define R_AARCH64_MOVW_PREL_G1_NC 290	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_PREL_G2  291	/* PC-rel. MOV{N,Z} imm. from 47:32. */
+#define R_AARCH64_MOVW_PREL_G2_NC 292	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_PREL_G3  293	/* PC-rel. MOV{N,Z} imm. from 63:48. */
+#define R_AARCH64_LDST128_ABS_LO12_NC 299	/* Dir. ADD imm. from bits 11:4.  */
+#define R_AARCH64_MOVW_GOTOFF_G0 300	/* GOT-rel. off. MOV{N,Z} imm. 15:0. */
+#define R_AARCH64_MOVW_GOTOFF_G0_NC 301	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_GOTOFF_G1 302	/* GOT-rel. o. MOV{N,Z} imm. 31:16.  */
+#define R_AARCH64_MOVW_GOTOFF_G1_NC 303	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_GOTOFF_G2 304	/* GOT-rel. o. MOV{N,Z} imm. 47:32.  */
+#define R_AARCH64_MOVW_GOTOFF_G2_NC 305	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_GOTOFF_G3 306	/* GOT-rel. o. MOV{N,Z} imm. 63:48.  */
+#define R_AARCH64_GOTREL64      307	/* GOT-relative 64-bit.  */
+#define R_AARCH64_GOTREL32      308	/* GOT-relative 32-bit.  */
+#define R_AARCH64_GOT_LD_PREL19 309	/* PC-rel. GOT off. load imm. 20:2.  */
+#define R_AARCH64_LD64_GOTOFF_LO15 310	/* GOT-rel. off. LD/ST imm. 14:3.  */
+#define R_AARCH64_ADR_GOT_PAGE  311	/* P-page-rel. GOT off. ADRP 32:12.  */
+#define R_AARCH64_LD64_GOT_LO12_NC 312	/* Dir. GOT off. LD/ST imm. 11:3.  */
+#define R_AARCH64_LD64_GOTPAGE_LO15 313	/* GOT-page-rel. GOT off. LD/ST 14:3 */
+#define R_AARCH64_TLSGD_ADR_PREL21 512	/* PC-relative ADR imm. 20:0.  */
+#define R_AARCH64_TLSGD_ADR_PAGE21 513	/* page-rel. ADRP imm. 32:12.  */
+#define R_AARCH64_TLSGD_ADD_LO12_NC 514	/* direct ADD imm. from 11:0.  */
+#define R_AARCH64_TLSGD_MOVW_G1 515	/* GOT-rel. MOV{N,Z} 31:16.  */
+#define R_AARCH64_TLSGD_MOVW_G0_NC 516	/* GOT-rel. MOVK imm. 15:0.  */
+#define R_AARCH64_TLSLD_ADR_PREL21 517	/* Like 512; local dynamic model.  */
+#define R_AARCH64_TLSLD_ADR_PAGE21 518	/* Like 513; local dynamic model.  */
+#define R_AARCH64_TLSLD_ADD_LO12_NC 519	/* Like 514; local dynamic model.  */
+#define R_AARCH64_TLSLD_MOVW_G1 520	/* Like 515; local dynamic model.  */
+#define R_AARCH64_TLSLD_MOVW_G0_NC 521	/* Like 516; local dynamic model.  */
+#define R_AARCH64_TLSLD_LD_PREL19 522	/* TLS PC-rel. load imm. 20:2.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523	/* TLS DTP-rel. MOV{N,Z} 47:32.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524	/* TLS DTP-rel. MOV{N,Z} 31:16.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525	/* Likewise; MOVK; no check.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526	/* TLS DTP-rel. MOV{N,Z} 15:0.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527	/* Likewise; MOVK; no check.  */
+#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528	/* DTP-rel. ADD imm. from 23:12. */
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529	/* DTP-rel. ADD imm. from 11:0.  */
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530	/* Likewise; no ovfl. check.  */
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531	/* DTP-rel. LD/ST imm. 11:0.  */
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532	/* Likewise; no check.  */
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533	/* DTP-rel. LD/ST imm. 11:1.  */
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534	/* Likewise; no check.  */
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535	/* DTP-rel. LD/ST imm. 11:2.  */
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536	/* Likewise; no check.  */
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537	/* DTP-rel. LD/ST imm. 11:3.  */
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538	/* Likewise; no check.  */
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539	/* GOT-rel. MOV{N,Z} 31:16.  */
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540	/* GOT-rel. MOVK 15:0.  */
+#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541	/* Page-rel. ADRP 32:12.  */
+#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542	/* Direct LD off. 11:3.  */
+#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543	/* PC-rel. load imm. 20:2.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544	/* TLS TP-rel. MOV{N,Z} 47:32.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545	/* TLS TP-rel. MOV{N,Z} 31:16.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546	/* Likewise; MOVK; no check.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547	/* TLS TP-rel. MOV{N,Z} 15:0.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548	/* Likewise; MOVK; no check.  */
+#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549	/* TP-rel. ADD imm. 23:12.  */
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550	/* TP-rel. ADD imm. 11:0.  */
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551	/* Likewise; no ovfl. check.  */
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552	/* TP-rel. LD/ST off. 11:0.  */
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553	/* Likewise; no ovfl. check. */
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554	/* TP-rel. LD/ST off. 11:1.  */
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555	/* Likewise; no check.  */
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556	/* TP-rel. LD/ST off. 11:2.  */
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557	/* Likewise; no check.  */
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558	/* TP-rel. LD/ST off. 11:3.  */
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559	/* Likewise; no check.  */
+#define R_AARCH64_TLSDESC_LD_PREL19 560	/* PC-rel. load immediate 20:2.  */
+#define R_AARCH64_TLSDESC_ADR_PREL21 561	/* PC-rel. ADR immediate 20:0.  */
+#define R_AARCH64_TLSDESC_ADR_PAGE21 562	/* Page-rel. ADRP imm. 32:12.  */
+#define R_AARCH64_TLSDESC_LD64_LO12 563	/* Direct LD off. from 11:3.  */
+#define R_AARCH64_TLSDESC_ADD_LO12 564	/* Direct ADD imm. from 11:0.  */
+#define R_AARCH64_TLSDESC_OFF_G1 565	/* GOT-rel. MOV{N,Z} imm. 31:16.  */
+#define R_AARCH64_TLSDESC_OFF_G0_NC 566	/* GOT-rel. MOVK imm. 15:0; no ck.  */
+#define R_AARCH64_TLSDESC_LDR   567	/* Relax LDR.  */
+#define R_AARCH64_TLSDESC_ADD   568	/* Relax ADD.  */
+#define R_AARCH64_TLSDESC_CALL  569	/* Relax BLR.  */
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570	/* TP-rel. LD/ST off. 11:4.  */
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571	/* Likewise; no check.  */
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572	/* DTP-rel. LD/ST imm. 11:4. */
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573	/* Likewise; no check.  */
+#define R_AARCH64_COPY         1024	/* Copy symbol at runtime.  */
+#define R_AARCH64_GLOB_DAT     1025	/* Create GOT entry.  */
+#define R_AARCH64_JUMP_SLOT    1026	/* Create PLT entry.  */
+#define R_AARCH64_RELATIVE     1027	/* Adjust by program base.  */
+#define R_AARCH64_TLS_DTPMOD64 1028	/* Module number, 64 bit.  */
+#define R_AARCH64_TLS_DTPREL64 1029	/* Module-relative offset, 64 bit.  */
+#define R_AARCH64_TLS_TPREL64  1030	/* TP-relative offset, 64 bit.  */
+#define R_AARCH64_TLSDESC      1031	/* TLS Descriptor.  */
+#define R_AARCH64_IRELATIVE    1032	/* STT_GNU_IFUNC relocation.  */
+/* Keep this the last entry.  */
+#define R_AARCH64_NUM          1033
+
+/* ARM relocs.  */
+
+#define R_ARM_NONE		0	/* No reloc */
+#define R_ARM_PC24		1	/* PC relative 26 bit branch */
+#define R_ARM_ABS32		2	/* Direct 32 bit  */
+#define R_ARM_REL32		3	/* PC relative 32 bit */
+#define R_ARM_PC13		4
+#define R_ARM_ABS16		5	/* Direct 16 bit */
+#define R_ARM_ABS12		6	/* Direct 12 bit */
+#define R_ARM_THM_ABS5		7
+#define R_ARM_ABS8		8	/* Direct 8 bit */
+#define R_ARM_SBREL32		9
+#define R_ARM_THM_PC22		10
+#define R_ARM_THM_PC8		11
+#define R_ARM_AMP_VCALL9	12
+#define R_ARM_SWI24		13	/* Obsolete static relocation.  */
+#define R_ARM_TLS_DESC		13      /* Dynamic relocation.  */
+#define R_ARM_THM_SWI8		14
+#define R_ARM_XPC25		15
+#define R_ARM_THM_XPC22		16
+#define R_ARM_TLS_DTPMOD32	17	/* ID of module containing symbol */
+#define R_ARM_TLS_DTPOFF32	18	/* Offset in TLS block */
+#define R_ARM_TLS_TPOFF32	19	/* Offset in static TLS block */
+#define R_ARM_COPY		20	/* Copy symbol at runtime */
+#define R_ARM_GLOB_DAT		21	/* Create GOT entry */
+#define R_ARM_JUMP_SLOT		22	/* Create PLT entry */
+#define R_ARM_RELATIVE		23	/* Adjust by program base */
+#define R_ARM_GOTOFF		24	/* 32 bit offset to GOT */
+#define R_ARM_GOTPC		25	/* 32 bit PC relative offset to GOT */
+#define R_ARM_GOT32		26	/* 32 bit GOT entry */
+#define R_ARM_PLT32		27	/* 32 bit PLT address */
+#define R_ARM_CALL		28
+#define R_ARM_JUMP24		29
+#define R_ARM_THM_JUMP24	30
+#define R_ARM_ALU_PCREL_7_0	32
+#define R_ARM_ALU_PCREL_15_8	33
+#define R_ARM_ALU_PCREL_23_15	34
+#define R_ARM_LDR_SBREL_11_0	35
+#define R_ARM_ALU_SBREL_19_12	36
+#define R_ARM_ALU_SBREL_27_20	37
+#define R_ARM_V4BX		40
+#define R_ARM_PREL31		42
+#define R_ARM_MOVW_ABS_NC	43
+#define R_ARM_MOVT_ABS		 44
+#define R_ARM_THM_MOVW_ABS_NC	47
+#define R_ARM_THM_MOVT_ABS	48
+#define R_ARM_TLS_GOTDESC	90
+#define R_ARM_TLS_CALL		91
+#define R_ARM_TLS_DESCSEQ	92
+#define R_ARM_THM_TLS_CALL	93
+#define R_ARM_GNU_VTENTRY	100
+#define R_ARM_GNU_VTINHERIT	101
+#define R_ARM_THM_PC11		102	/* thumb unconditional branch */
+#define R_ARM_THM_PC9		103	/* thumb conditional branch */
+#define R_ARM_TLS_GD32		104	/* PC-rel 32 bit for global dynamic
+					   thread local data */
+#define R_ARM_TLS_LDM32		105	/* PC-rel 32 bit for local dynamic
+					   thread local data */
+#define R_ARM_TLS_LDO32		106	/* 32 bit offset relative to TLS
+					   block */
+#define R_ARM_TLS_IE32		107	/* PC-rel 32 bit for GOT entry of
+					   static TLS block offset */
+#define R_ARM_TLS_LE32		108	/* 32 bit offset relative to static
+					   TLS block */
+#define	R_ARM_THM_TLS_DESCSEQ	129
+#define R_ARM_IRELATIVE		160
+#define R_ARM_RXPC25		249
+#define R_ARM_RSBREL32		250
+#define R_ARM_THM_RPC22		251
+#define R_ARM_RREL32		252
+#define R_ARM_RABS22		253
+#define R_ARM_RPC24		254
+#define R_ARM_RBASE		255
+/* Keep this the last entry.  */
+#define R_ARM_NUM		256
+
+/* TMS320C67xx specific declarations */
+
+/* XXX: no ELF standard yet*/
+
+/* TMS320C67xx relocs. */
+#define R_C60_32       1
+#define R_C60_GOT32     3               /* 32 bit GOT entry */
+#define R_C60_PLT32     4               /* 32 bit PLT address */
+#define R_C60_COPY      5               /* Copy symbol at runtime */
+#define R_C60_GLOB_DAT  6               /* Create GOT entry */
+#define R_C60_JMP_SLOT  7               /* Create PLT entry */
+#define R_C60_RELATIVE  8               /* Adjust by program base */
+#define R_C60_GOTOFF    9               /* 32 bit offset to GOT */
+#define R_C60_GOTPC     10              /* 32 bit PC relative offset to GOT */
+
+#define R_C60LO16      0x54       /* low 16 bit MVKL embedded */
+#define R_C60HI16      0x55       /* high 16 bit MVKH embedded */
+/* Keep this the last entry.  */
+#define R_C60_NUM      0x56
+
+/* IA-64 specific declarations.  */
+
+/* Processor specific flags for the Ehdr e_flags field.  */
+#define EF_IA_64_MASKOS		0x0000000f	/* os-specific flags */
+#define EF_IA_64_ABI64		0x00000010	/* 64-bit ABI */
+#define EF_IA_64_ARCH		0xff000000	/* arch. version mask */
+
+/* Processor specific values for the Phdr p_type field.  */
+#define PT_IA_64_ARCHEXT	(PT_LOPROC + 0)	/* arch extension bits */
+#define PT_IA_64_UNWIND		(PT_LOPROC + 1)	/* ia64 unwind bits */
+#define PT_IA_64_HP_OPT_ANOT	(PT_LOOS + 0x12)
+#define PT_IA_64_HP_HSL_ANOT	(PT_LOOS + 0x13)
+#define PT_IA_64_HP_STACK	(PT_LOOS + 0x14)
+
+/* Processor specific flags for the Phdr p_flags field.  */
+#define PF_IA_64_NORECOV	0x80000000	/* spec insns w/o recovery */
+
+/* Processor specific values for the Shdr sh_type field.  */
+#define SHT_IA_64_EXT		(SHT_LOPROC + 0) /* extension bits */
+#define SHT_IA_64_UNWIND	(SHT_LOPROC + 1) /* unwind bits */
+
+/* Processor specific flags for the Shdr sh_flags field.  */
+#define SHF_IA_64_SHORT		0x10000000	/* section near gp */
+#define SHF_IA_64_NORECOV	0x20000000	/* spec insns w/o recovery */
+
+/* Processor specific values for the Dyn d_tag field.  */
+#define DT_IA_64_PLT_RESERVE	(DT_LOPROC + 0)
+#define DT_IA_64_NUM		1
+
+/* IA-64 relocations.  */
+#define R_IA64_NONE		0x00	/* none */
+#define R_IA64_IMM14		0x21	/* symbol + addend, add imm14 */
+#define R_IA64_IMM22		0x22	/* symbol + addend, add imm22 */
+#define R_IA64_IMM64		0x23	/* symbol + addend, mov imm64 */
+#define R_IA64_DIR32MSB		0x24	/* symbol + addend, data4 MSB */
+#define R_IA64_DIR32LSB		0x25	/* symbol + addend, data4 LSB */
+#define R_IA64_DIR64MSB		0x26	/* symbol + addend, data8 MSB */
+#define R_IA64_DIR64LSB		0x27	/* symbol + addend, data8 LSB */
+#define R_IA64_GPREL22		0x2a	/* @gprel(sym + add), add imm22 */
+#define R_IA64_GPREL64I		0x2b	/* @gprel(sym + add), mov imm64 */
+#define R_IA64_GPREL32MSB	0x2c	/* @gprel(sym + add), data4 MSB */
+#define R_IA64_GPREL32LSB	0x2d	/* @gprel(sym + add), data4 LSB */
+#define R_IA64_GPREL64MSB	0x2e	/* @gprel(sym + add), data8 MSB */
+#define R_IA64_GPREL64LSB	0x2f	/* @gprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF22		0x32	/* @ltoff(sym + add), add imm22 */
+#define R_IA64_LTOFF64I		0x33	/* @ltoff(sym + add), mov imm64 */
+#define R_IA64_PLTOFF22		0x3a	/* @pltoff(sym + add), add imm22 */
+#define R_IA64_PLTOFF64I	0x3b	/* @pltoff(sym + add), mov imm64 */
+#define R_IA64_PLTOFF64MSB	0x3e	/* @pltoff(sym + add), data8 MSB */
+#define R_IA64_PLTOFF64LSB	0x3f	/* @pltoff(sym + add), data8 LSB */
+#define R_IA64_FPTR64I		0x43	/* @fptr(sym + add), mov imm64 */
+#define R_IA64_FPTR32MSB	0x44	/* @fptr(sym + add), data4 MSB */
+#define R_IA64_FPTR32LSB	0x45	/* @fptr(sym + add), data4 LSB */
+#define R_IA64_FPTR64MSB	0x46	/* @fptr(sym + add), data8 MSB */
+#define R_IA64_FPTR64LSB	0x47	/* @fptr(sym + add), data8 LSB */
+#define R_IA64_PCREL60B		0x48	/* @pcrel(sym + add), brl */
+#define R_IA64_PCREL21B		0x49	/* @pcrel(sym + add), ptb, call */
+#define R_IA64_PCREL21M		0x4a	/* @pcrel(sym + add), chk.s */
+#define R_IA64_PCREL21F		0x4b	/* @pcrel(sym + add), fchkf */
+#define R_IA64_PCREL32MSB	0x4c	/* @pcrel(sym + add), data4 MSB */
+#define R_IA64_PCREL32LSB	0x4d	/* @pcrel(sym + add), data4 LSB */
+#define R_IA64_PCREL64MSB	0x4e	/* @pcrel(sym + add), data8 MSB */
+#define R_IA64_PCREL64LSB	0x4f	/* @pcrel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_FPTR22	0x52	/* @ltoff(@fptr(s+a)), imm22 */
+#define R_IA64_LTOFF_FPTR64I	0x53	/* @ltoff(@fptr(s+a)), imm64 */
+#define R_IA64_LTOFF_FPTR32MSB	0x54	/* @ltoff(@fptr(s+a)), data4 MSB */
+#define R_IA64_LTOFF_FPTR32LSB	0x55	/* @ltoff(@fptr(s+a)), data4 LSB */
+#define R_IA64_LTOFF_FPTR64MSB	0x56	/* @ltoff(@fptr(s+a)), data8 MSB */
+#define R_IA64_LTOFF_FPTR64LSB	0x57	/* @ltoff(@fptr(s+a)), data8 LSB */
+#define R_IA64_SEGREL32MSB	0x5c	/* @segrel(sym + add), data4 MSB */
+#define R_IA64_SEGREL32LSB	0x5d	/* @segrel(sym + add), data4 LSB */
+#define R_IA64_SEGREL64MSB	0x5e	/* @segrel(sym + add), data8 MSB */
+#define R_IA64_SEGREL64LSB	0x5f	/* @segrel(sym + add), data8 LSB */
+#define R_IA64_SECREL32MSB	0x64	/* @secrel(sym + add), data4 MSB */
+#define R_IA64_SECREL32LSB	0x65	/* @secrel(sym + add), data4 LSB */
+#define R_IA64_SECREL64MSB	0x66	/* @secrel(sym + add), data8 MSB */
+#define R_IA64_SECREL64LSB	0x67	/* @secrel(sym + add), data8 LSB */
+#define R_IA64_REL32MSB		0x6c	/* data 4 + REL */
+#define R_IA64_REL32LSB		0x6d	/* data 4 + REL */
+#define R_IA64_REL64MSB		0x6e	/* data 8 + REL */
+#define R_IA64_REL64LSB		0x6f	/* data 8 + REL */
+#define R_IA64_LTV32MSB		0x74	/* symbol + addend, data4 MSB */
+#define R_IA64_LTV32LSB		0x75	/* symbol + addend, data4 LSB */
+#define R_IA64_LTV64MSB		0x76	/* symbol + addend, data8 MSB */
+#define R_IA64_LTV64LSB		0x77	/* symbol + addend, data8 LSB */
+#define R_IA64_PCREL21BI	0x79	/* @pcrel(sym + add), 21bit inst */
+#define R_IA64_PCREL22		0x7a	/* @pcrel(sym + add), 22bit inst */
+#define R_IA64_PCREL64I		0x7b	/* @pcrel(sym + add), 64bit inst */
+#define R_IA64_IPLTMSB		0x80	/* dynamic reloc, imported PLT, MSB */
+#define R_IA64_IPLTLSB		0x81	/* dynamic reloc, imported PLT, LSB */
+#define R_IA64_COPY		0x84	/* copy relocation */
+#define R_IA64_SUB		0x85	/* Addend and symbol difference */
+#define R_IA64_LTOFF22X		0x86	/* LTOFF22, relaxable.  */
+#define R_IA64_LDXMOV		0x87	/* Use of LTOFF22X.  */
+#define R_IA64_TPREL14		0x91	/* @tprel(sym + add), imm14 */
+#define R_IA64_TPREL22		0x92	/* @tprel(sym + add), imm22 */
+#define R_IA64_TPREL64I		0x93	/* @tprel(sym + add), imm64 */
+#define R_IA64_TPREL64MSB	0x96	/* @tprel(sym + add), data8 MSB */
+#define R_IA64_TPREL64LSB	0x97	/* @tprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_TPREL22	0x9a	/* @ltoff(@tprel(s+a)), imm2 */
+#define R_IA64_DTPMOD64MSB	0xa6	/* @dtpmod(sym + add), data8 MSB */
+#define R_IA64_DTPMOD64LSB	0xa7	/* @dtpmod(sym + add), data8 LSB */
+#define R_IA64_LTOFF_DTPMOD22	0xaa	/* @ltoff(@dtpmod(sym + add)), imm22 */
+#define R_IA64_DTPREL14		0xb1	/* @dtprel(sym + add), imm14 */
+#define R_IA64_DTPREL22		0xb2	/* @dtprel(sym + add), imm22 */
+#define R_IA64_DTPREL64I	0xb3	/* @dtprel(sym + add), imm64 */
+#define R_IA64_DTPREL32MSB	0xb4	/* @dtprel(sym + add), data4 MSB */
+#define R_IA64_DTPREL32LSB	0xb5	/* @dtprel(sym + add), data4 LSB */
+#define R_IA64_DTPREL64MSB	0xb6	/* @dtprel(sym + add), data8 MSB */
+#define R_IA64_DTPREL64LSB	0xb7	/* @dtprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_DTPREL22	0xba	/* @ltoff(@dtprel(s+a)), imm22 */
+
+/* SH specific declarations */
+
+/* Processor specific flags for the ELF header e_flags field.  */
+#define EF_SH_MACH_MASK		0x1f
+#define EF_SH_UNKNOWN		0x0
+#define EF_SH1			0x1
+#define EF_SH2			0x2
+#define EF_SH3			0x3
+#define EF_SH_DSP		0x4
+#define EF_SH3_DSP		0x5
+#define EF_SH4AL_DSP		0x6
+#define EF_SH3E			0x8
+#define EF_SH4			0x9
+#define EF_SH2E			0xb
+#define EF_SH4A			0xc
+#define EF_SH2A			0xd
+#define EF_SH4_NOFPU		0x10
+#define EF_SH4A_NOFPU		0x11
+#define EF_SH4_NOMMU_NOFPU	0x12
+#define EF_SH2A_NOFPU		0x13
+#define EF_SH3_NOMMU		0x14
+#define EF_SH2A_SH4_NOFPU	0x15
+#define EF_SH2A_SH3_NOFPU	0x16
+#define EF_SH2A_SH4		0x17
+#define EF_SH2A_SH3E		0x18
+
+/* SH relocs.  */
+#define	R_SH_NONE		0
+#define	R_SH_DIR32		1
+#define	R_SH_REL32		2
+#define	R_SH_DIR8WPN		3
+#define	R_SH_IND12W		4
+#define	R_SH_DIR8WPL		5
+#define	R_SH_DIR8WPZ		6
+#define	R_SH_DIR8BP		7
+#define	R_SH_DIR8W		8
+#define	R_SH_DIR8L		9
+#define	R_SH_SWITCH16		25
+#define	R_SH_SWITCH32		26
+#define	R_SH_USES		27
+#define	R_SH_COUNT		28
+#define	R_SH_ALIGN		29
+#define	R_SH_CODE		30
+#define	R_SH_DATA		31
+#define	R_SH_LABEL		32
+#define	R_SH_SWITCH8		33
+#define	R_SH_GNU_VTINHERIT	34
+#define	R_SH_GNU_VTENTRY	35
+#define	R_SH_TLS_GD_32		144
+#define	R_SH_TLS_LD_32		145
+#define	R_SH_TLS_LDO_32		146
+#define	R_SH_TLS_IE_32		147
+#define	R_SH_TLS_LE_32		148
+#define	R_SH_TLS_DTPMOD32	149
+#define	R_SH_TLS_DTPOFF32	150
+#define	R_SH_TLS_TPOFF32	151
+#define	R_SH_GOT32		160
+#define	R_SH_PLT32		161
+#define	R_SH_COPY		162
+#define	R_SH_GLOB_DAT		163
+#define	R_SH_JMP_SLOT		164
+#define	R_SH_RELATIVE		165
+#define	R_SH_GOTOFF		166
+#define	R_SH_GOTPC		167
+/* Keep this the last entry.  */
+#define	R_SH_NUM		256
+
+/* S/390 specific definitions.  */
+
+/* Valid values for the e_flags field.  */
+
+#define EF_S390_HIGH_GPRS    0x00000001  /* High GPRs kernel facility needed.  */
+
+/* Additional s390 relocs */
+
+#define R_390_NONE		0	/* No reloc.  */
+#define R_390_8			1	/* Direct 8 bit.  */
+#define R_390_12		2	/* Direct 12 bit.  */
+#define R_390_16		3	/* Direct 16 bit.  */
+#define R_390_32		4	/* Direct 32 bit.  */
+#define R_390_PC32		5	/* PC relative 32 bit.	*/
+#define R_390_GOT12		6	/* 12 bit GOT offset.  */
+#define R_390_GOT32		7	/* 32 bit GOT offset.  */
+#define R_390_PLT32		8	/* 32 bit PC relative PLT address.  */
+#define R_390_COPY		9	/* Copy symbol at runtime.  */
+#define R_390_GLOB_DAT		10	/* Create GOT entry.  */
+#define R_390_JMP_SLOT		11	/* Create PLT entry.  */
+#define R_390_RELATIVE		12	/* Adjust by program base.  */
+#define R_390_GOTOFF32		13	/* 32 bit offset to GOT.	 */
+#define R_390_GOTPC		14	/* 32 bit PC relative offset to GOT.  */
+#define R_390_GOT16		15	/* 16 bit GOT offset.  */
+#define R_390_PC16		16	/* PC relative 16 bit.	*/
+#define R_390_PC16DBL		17	/* PC relative 16 bit shifted by 1.  */
+#define R_390_PLT16DBL		18	/* 16 bit PC rel. PLT shifted by 1.  */
+#define R_390_PC32DBL		19	/* PC relative 32 bit shifted by 1.  */
+#define R_390_PLT32DBL		20	/* 32 bit PC rel. PLT shifted by 1.  */
+#define R_390_GOTPCDBL		21	/* 32 bit PC rel. GOT shifted by 1.  */
+#define R_390_64		22	/* Direct 64 bit.  */
+#define R_390_PC64		23	/* PC relative 64 bit.	*/
+#define R_390_GOT64		24	/* 64 bit GOT offset.  */
+#define R_390_PLT64		25	/* 64 bit PC relative PLT address.  */
+#define R_390_GOTENT		26	/* 32 bit PC rel. to GOT entry >> 1. */
+#define R_390_GOTOFF16		27	/* 16 bit offset to GOT. */
+#define R_390_GOTOFF64		28	/* 64 bit offset to GOT. */
+#define R_390_GOTPLT12		29	/* 12 bit offset to jump slot.	*/
+#define R_390_GOTPLT16		30	/* 16 bit offset to jump slot.	*/
+#define R_390_GOTPLT32		31	/* 32 bit offset to jump slot.	*/
+#define R_390_GOTPLT64		32	/* 64 bit offset to jump slot.	*/
+#define R_390_GOTPLTENT		33	/* 32 bit rel. offset to jump slot.  */
+#define R_390_PLTOFF16		34	/* 16 bit offset from GOT to PLT. */
+#define R_390_PLTOFF32		35	/* 32 bit offset from GOT to PLT. */
+#define R_390_PLTOFF64		36	/* 16 bit offset from GOT to PLT. */
+#define R_390_TLS_LOAD		37	/* Tag for load insn in TLS code.  */
+#define R_390_TLS_GDCALL	38	/* Tag for function call in general
+					   dynamic TLS code. */
+#define R_390_TLS_LDCALL	39	/* Tag for function call in local
+					   dynamic TLS code. */
+#define R_390_TLS_GD32		40	/* Direct 32 bit for general dynamic
+					   thread local data.  */
+#define R_390_TLS_GD64		41	/* Direct 64 bit for general dynamic
+					  thread local data.  */
+#define R_390_TLS_GOTIE12	42	/* 12 bit GOT offset for static TLS
+					   block offset.  */
+#define R_390_TLS_GOTIE32	43	/* 32 bit GOT offset for static TLS
+					   block offset.  */
+#define R_390_TLS_GOTIE64	44	/* 64 bit GOT offset for static TLS
+					   block offset. */
+#define R_390_TLS_LDM32		45	/* Direct 32 bit for local dynamic
+					   thread local data in LE code.  */
+#define R_390_TLS_LDM64		46	/* Direct 64 bit for local dynamic
+					   thread local data in LE code.  */
+#define R_390_TLS_IE32		47	/* 32 bit address of GOT entry for
+					   negated static TLS block offset.  */
+#define R_390_TLS_IE64		48	/* 64 bit address of GOT entry for
+					   negated static TLS block offset.  */
+#define R_390_TLS_IEENT		49	/* 32 bit rel. offset to GOT entry for
+					   negated static TLS block offset.  */
+#define R_390_TLS_LE32		50	/* 32 bit negated offset relative to
+					   static TLS block.  */
+#define R_390_TLS_LE64		51	/* 64 bit negated offset relative to
+					   static TLS block.  */
+#define R_390_TLS_LDO32		52	/* 32 bit offset relative to TLS
+					   block.  */
+#define R_390_TLS_LDO64		53	/* 64 bit offset relative to TLS
+					   block.  */
+#define R_390_TLS_DTPMOD	54	/* ID of module containing symbol.  */
+#define R_390_TLS_DTPOFF	55	/* Offset in TLS block.	 */
+#define R_390_TLS_TPOFF		56	/* Negated offset in static TLS
+					   block.  */
+#define R_390_20		57	/* Direct 20 bit.  */
+#define R_390_GOT20		58	/* 20 bit GOT offset.  */
+#define R_390_GOTPLT20		59	/* 20 bit offset to jump slot.  */
+#define R_390_TLS_GOTIE20	60	/* 20 bit GOT offset for static TLS
+					   block offset.  */
+#define R_390_IRELATIVE         61      /* STT_GNU_IFUNC relocation.  */
+/* Keep this the last entry.  */
+#define R_390_NUM		62
+
+
+/* CRIS relocations.  */
+#define R_CRIS_NONE		0
+#define R_CRIS_8		1
+#define R_CRIS_16		2
+#define R_CRIS_32		3
+#define R_CRIS_8_PCREL		4
+#define R_CRIS_16_PCREL		5
+#define R_CRIS_32_PCREL		6
+#define R_CRIS_GNU_VTINHERIT	7
+#define R_CRIS_GNU_VTENTRY	8
+#define R_CRIS_COPY		9
+#define R_CRIS_GLOB_DAT		10
+#define R_CRIS_JUMP_SLOT	11
+#define R_CRIS_RELATIVE		12
+#define R_CRIS_16_GOT		13
+#define R_CRIS_32_GOT		14
+#define R_CRIS_16_GOTPLT	15
+#define R_CRIS_32_GOTPLT	16
+#define R_CRIS_32_GOTREL	17
+#define R_CRIS_32_PLT_GOTREL	18
+#define R_CRIS_32_PLT_PCREL	19
+
+#define R_CRIS_NUM		20
+
+
+/* AMD x86-64 relocations.  */
+#define R_X86_64_NONE		0	/* No reloc */
+#define R_X86_64_64		1	/* Direct 64 bit  */
+#define R_X86_64_PC32		2	/* PC relative 32 bit signed */
+#define R_X86_64_GOT32		3	/* 32 bit GOT entry */
+#define R_X86_64_PLT32		4	/* 32 bit PLT address */
+#define R_X86_64_COPY		5	/* Copy symbol at runtime */
+#define R_X86_64_GLOB_DAT	6	/* Create GOT entry */
+#define R_X86_64_JUMP_SLOT	7	/* Create PLT entry */
+#define R_X86_64_RELATIVE	8	/* Adjust by program base */
+#define R_X86_64_GOTPCREL	9	/* 32 bit signed PC relative
+					   offset to GOT */
+#define R_X86_64_32		10	/* Direct 32 bit zero extended */
+#define R_X86_64_32S		11	/* Direct 32 bit sign extended */
+#define R_X86_64_16		12	/* Direct 16 bit zero extended */
+#define R_X86_64_PC16		13	/* 16 bit sign extended pc relative */
+#define R_X86_64_8		14	/* Direct 8 bit sign extended  */
+#define R_X86_64_PC8		15	/* 8 bit sign extended pc relative */
+#define R_X86_64_DTPMOD64	16	/* ID of module containing symbol */
+#define R_X86_64_DTPOFF64	17	/* Offset in module's TLS block */
+#define R_X86_64_TPOFF64	18	/* Offset in initial TLS block */
+#define R_X86_64_TLSGD		19	/* 32 bit signed PC relative offset
+					   to two GOT entries for GD symbol */
+#define R_X86_64_TLSLD		20	/* 32 bit signed PC relative offset
+					   to two GOT entries for LD symbol */
+#define R_X86_64_DTPOFF32	21	/* Offset in TLS block */
+#define R_X86_64_GOTTPOFF	22	/* 32 bit signed PC relative offset
+					   to GOT entry for IE symbol */
+#define R_X86_64_TPOFF32	23	/* Offset in initial TLS block */
+#define R_X86_64_PC64		24	/* PC relative 64 bit */
+#define R_X86_64_GOTOFF64	25	/* 64 bit offset to GOT */
+#define R_X86_64_GOTPC32	26	/* 32 bit signed pc relative
+					   offset to GOT */
+#define R_X86_64_GOT64		27	/* 64-bit GOT entry offset */
+#define R_X86_64_GOTPCREL64	28	/* 64-bit PC relative offset
+					   to GOT entry */
+#define R_X86_64_GOTPC64	29	/* 64-bit PC relative offset to GOT */
+#define R_X86_64_GOTPLT64	30 	/* like GOT64, says PLT entry needed */
+#define R_X86_64_PLTOFF64	31	/* 64-bit GOT relative offset
+					   to PLT entry */
+#define R_X86_64_SIZE32		32	/* Size of symbol plus 32-bit addend */
+#define R_X86_64_SIZE64		33	/* Size of symbol plus 64-bit addend */
+#define R_X86_64_GOTPC32_TLSDESC 34	/* GOT offset for TLS descriptor.  */
+#define R_X86_64_TLSDESC_CALL   35	/* Marker for call through TLS
+					   descriptor.  */
+#define R_X86_64_TLSDESC        36	/* TLS descriptor.  */
+#define R_X86_64_IRELATIVE	37	/* Adjust indirectly by program base */
+#define R_X86_64_RELATIVE64	38	/* 64-bit adjust by program base */
+#define R_X86_64_GOTPCRELX	41	/* like GOTPCREL, but optionally with
+					   linker optimizations */
+#define R_X86_64_REX_GOTPCRELX	42      /* like GOTPCRELX, but a REX prefix
+					   is present */
+
+#define R_X86_64_NUM		43
+
+
+/* AM33 relocations.  */
+#define R_MN10300_NONE		0	/* No reloc.  */
+#define R_MN10300_32		1	/* Direct 32 bit.  */
+#define R_MN10300_16		2	/* Direct 16 bit.  */
+#define R_MN10300_8		3	/* Direct 8 bit.  */
+#define R_MN10300_PCREL32	4	/* PC-relative 32-bit.  */
+#define R_MN10300_PCREL16	5	/* PC-relative 16-bit signed.  */
+#define R_MN10300_PCREL8	6	/* PC-relative 8-bit signed.  */
+#define R_MN10300_GNU_VTINHERIT	7	/* Ancient C++ vtable garbage... */
+#define R_MN10300_GNU_VTENTRY	8	/* ... collection annotation.  */
+#define R_MN10300_24		9	/* Direct 24 bit.  */
+#define R_MN10300_GOTPC32	10	/* 32-bit PCrel offset to GOT.  */
+#define R_MN10300_GOTPC16	11	/* 16-bit PCrel offset to GOT.  */
+#define R_MN10300_GOTOFF32	12	/* 32-bit offset from GOT.  */
+#define R_MN10300_GOTOFF24	13	/* 24-bit offset from GOT.  */
+#define R_MN10300_GOTOFF16	14	/* 16-bit offset from GOT.  */
+#define R_MN10300_PLT32		15	/* 32-bit PCrel to PLT entry.  */
+#define R_MN10300_PLT16		16	/* 16-bit PCrel to PLT entry.  */
+#define R_MN10300_GOT32		17	/* 32-bit offset to GOT entry.  */
+#define R_MN10300_GOT24		18	/* 24-bit offset to GOT entry.  */
+#define R_MN10300_GOT16		19	/* 16-bit offset to GOT entry.  */
+#define R_MN10300_COPY		20	/* Copy symbol at runtime.  */
+#define R_MN10300_GLOB_DAT	21	/* Create GOT entry.  */
+#define R_MN10300_JMP_SLOT	22	/* Create PLT entry.  */
+#define R_MN10300_RELATIVE	23	/* Adjust by program base.  */
+#define R_MN10300_TLS_GD	24	/* 32-bit offset for global dynamic.  */
+#define R_MN10300_TLS_LD	25	/* 32-bit offset for local dynamic.  */
+#define R_MN10300_TLS_LDO	26	/* Module-relative offset.  */
+#define R_MN10300_TLS_GOTIE	27	/* GOT offset for static TLS block
+					   offset.  */
+#define R_MN10300_TLS_IE	28	/* GOT address for static TLS block
+					   offset.  */
+#define R_MN10300_TLS_LE	29	/* Offset relative to static TLS
+					   block.  */
+#define R_MN10300_TLS_DTPMOD	30	/* ID of module containing symbol.  */
+#define R_MN10300_TLS_DTPOFF	31	/* Offset in module TLS block.  */
+#define R_MN10300_TLS_TPOFF	32	/* Offset in static TLS block.  */
+#define R_MN10300_SYM_DIFF	33	/* Adjustment for next reloc as needed
+					   by linker relaxation.  */
+#define R_MN10300_ALIGN		34	/* Alignment requirement for linker
+					   relaxation.  */
+#define R_MN10300_NUM		35
+
+
+/* M32R relocs.  */
+#define R_M32R_NONE		0	/* No reloc. */
+#define R_M32R_16		1	/* Direct 16 bit. */
+#define R_M32R_32		2	/* Direct 32 bit. */
+#define R_M32R_24		3	/* Direct 24 bit. */
+#define R_M32R_10_PCREL		4	/* PC relative 10 bit shifted. */
+#define R_M32R_18_PCREL		5	/* PC relative 18 bit shifted. */
+#define R_M32R_26_PCREL		6	/* PC relative 26 bit shifted. */
+#define R_M32R_HI16_ULO		7	/* High 16 bit with unsigned low. */
+#define R_M32R_HI16_SLO		8	/* High 16 bit with signed low. */
+#define R_M32R_LO16		9	/* Low 16 bit. */
+#define R_M32R_SDA16		10	/* 16 bit offset in SDA. */
+#define R_M32R_GNU_VTINHERIT	11
+#define R_M32R_GNU_VTENTRY	12
+/* M32R relocs use SHT_RELA.  */
+#define R_M32R_16_RELA		33	/* Direct 16 bit. */
+#define R_M32R_32_RELA		34	/* Direct 32 bit. */
+#define R_M32R_24_RELA		35	/* Direct 24 bit. */
+#define R_M32R_10_PCREL_RELA	36	/* PC relative 10 bit shifted. */
+#define R_M32R_18_PCREL_RELA	37	/* PC relative 18 bit shifted. */
+#define R_M32R_26_PCREL_RELA	38	/* PC relative 26 bit shifted. */
+#define R_M32R_HI16_ULO_RELA	39	/* High 16 bit with unsigned low */
+#define R_M32R_HI16_SLO_RELA	40	/* High 16 bit with signed low */
+#define R_M32R_LO16_RELA	41	/* Low 16 bit */
+#define R_M32R_SDA16_RELA	42	/* 16 bit offset in SDA */
+#define R_M32R_RELA_GNU_VTINHERIT	43
+#define R_M32R_RELA_GNU_VTENTRY	44
+#define R_M32R_REL32		45	/* PC relative 32 bit.  */
+
+#define R_M32R_GOT24		48	/* 24 bit GOT entry */
+#define R_M32R_26_PLTREL	49	/* 26 bit PC relative to PLT shifted */
+#define R_M32R_COPY		50	/* Copy symbol at runtime */
+#define R_M32R_GLOB_DAT		51	/* Create GOT entry */
+#define R_M32R_JMP_SLOT		52	/* Create PLT entry */
+#define R_M32R_RELATIVE		53	/* Adjust by program base */
+#define R_M32R_GOTOFF		54	/* 24 bit offset to GOT */
+#define R_M32R_GOTPC24		55	/* 24 bit PC relative offset to GOT */
+#define R_M32R_GOT16_HI_ULO	56	/* High 16 bit GOT entry with unsigned
+					   low */
+#define R_M32R_GOT16_HI_SLO	57	/* High 16 bit GOT entry with signed
+					   low */
+#define R_M32R_GOT16_LO		58	/* Low 16 bit GOT entry */
+#define R_M32R_GOTPC_HI_ULO	59	/* High 16 bit PC relative offset to
+					   GOT with unsigned low */
+#define R_M32R_GOTPC_HI_SLO	60	/* High 16 bit PC relative offset to
+					   GOT with signed low */
+#define R_M32R_GOTPC_LO		61	/* Low 16 bit PC relative offset to
+					   GOT */
+#define R_M32R_GOTOFF_HI_ULO	62	/* High 16 bit offset to GOT
+					   with unsigned low */
+#define R_M32R_GOTOFF_HI_SLO	63	/* High 16 bit offset to GOT
+					   with signed low */
+#define R_M32R_GOTOFF_LO	64	/* Low 16 bit offset to GOT */
+#define R_M32R_NUM		256	/* Keep this the last entry. */
+
+
+/* TILEPro relocations.  */
+#define R_TILEPRO_NONE		0	/* No reloc */
+#define R_TILEPRO_32		1	/* Direct 32 bit */
+#define R_TILEPRO_16		2	/* Direct 16 bit */
+#define R_TILEPRO_8		3	/* Direct 8 bit */
+#define R_TILEPRO_32_PCREL	4	/* PC relative 32 bit */
+#define R_TILEPRO_16_PCREL	5	/* PC relative 16 bit */
+#define R_TILEPRO_8_PCREL	6	/* PC relative 8 bit */
+#define R_TILEPRO_LO16		7	/* Low 16 bit */
+#define R_TILEPRO_HI16		8	/* High 16 bit */
+#define R_TILEPRO_HA16		9	/* High 16 bit, adjusted */
+#define R_TILEPRO_COPY		10	/* Copy relocation */
+#define R_TILEPRO_GLOB_DAT	11	/* Create GOT entry */
+#define R_TILEPRO_JMP_SLOT	12	/* Create PLT entry */
+#define R_TILEPRO_RELATIVE	13	/* Adjust by program base */
+#define R_TILEPRO_BROFF_X1	14	/* X1 pipe branch offset */
+#define R_TILEPRO_JOFFLONG_X1	15	/* X1 pipe jump offset */
+#define R_TILEPRO_JOFFLONG_X1_PLT 16	/* X1 pipe jump offset to PLT */
+#define R_TILEPRO_IMM8_X0	17	/* X0 pipe 8-bit */
+#define R_TILEPRO_IMM8_Y0	18	/* Y0 pipe 8-bit */
+#define R_TILEPRO_IMM8_X1	19	/* X1 pipe 8-bit */
+#define R_TILEPRO_IMM8_Y1	20	/* Y1 pipe 8-bit */
+#define R_TILEPRO_MT_IMM15_X1	21	/* X1 pipe mtspr */
+#define R_TILEPRO_MF_IMM15_X1	22	/* X1 pipe mfspr */
+#define R_TILEPRO_IMM16_X0	23	/* X0 pipe 16-bit */
+#define R_TILEPRO_IMM16_X1	24	/* X1 pipe 16-bit */
+#define R_TILEPRO_IMM16_X0_LO	25	/* X0 pipe low 16-bit */
+#define R_TILEPRO_IMM16_X1_LO	26	/* X1 pipe low 16-bit */
+#define R_TILEPRO_IMM16_X0_HI	27	/* X0 pipe high 16-bit */
+#define R_TILEPRO_IMM16_X1_HI	28	/* X1 pipe high 16-bit */
+#define R_TILEPRO_IMM16_X0_HA	29	/* X0 pipe high 16-bit, adjusted */
+#define R_TILEPRO_IMM16_X1_HA	30	/* X1 pipe high 16-bit, adjusted */
+#define R_TILEPRO_IMM16_X0_PCREL 31	/* X0 pipe PC relative 16 bit */
+#define R_TILEPRO_IMM16_X1_PCREL 32	/* X1 pipe PC relative 16 bit */
+#define R_TILEPRO_IMM16_X0_LO_PCREL 33	/* X0 pipe PC relative low 16 bit */
+#define R_TILEPRO_IMM16_X1_LO_PCREL 34	/* X1 pipe PC relative low 16 bit */
+#define R_TILEPRO_IMM16_X0_HI_PCREL 35	/* X0 pipe PC relative high 16 bit */
+#define R_TILEPRO_IMM16_X1_HI_PCREL 36	/* X1 pipe PC relative high 16 bit */
+#define R_TILEPRO_IMM16_X0_HA_PCREL 37	/* X0 pipe PC relative ha() 16 bit */
+#define R_TILEPRO_IMM16_X1_HA_PCREL 38	/* X1 pipe PC relative ha() 16 bit */
+#define R_TILEPRO_IMM16_X0_GOT	39	/* X0 pipe 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT	40	/* X1 pipe 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_LO 41	/* X0 pipe low 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_LO 42	/* X1 pipe low 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_HI 43	/* X0 pipe high 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_HI 44	/* X1 pipe high 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_HA 45	/* X0 pipe ha() 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_HA 46	/* X1 pipe ha() 16-bit GOT offset */
+#define R_TILEPRO_MMSTART_X0	47	/* X0 pipe mm "start" */
+#define R_TILEPRO_MMEND_X0	48	/* X0 pipe mm "end" */
+#define R_TILEPRO_MMSTART_X1	49	/* X1 pipe mm "start" */
+#define R_TILEPRO_MMEND_X1	50	/* X1 pipe mm "end" */
+#define R_TILEPRO_SHAMT_X0	51	/* X0 pipe shift amount */
+#define R_TILEPRO_SHAMT_X1	52	/* X1 pipe shift amount */
+#define R_TILEPRO_SHAMT_Y0	53	/* Y0 pipe shift amount */
+#define R_TILEPRO_SHAMT_Y1	54	/* Y1 pipe shift amount */
+#define R_TILEPRO_DEST_IMM8_X1	55	/* X1 pipe destination 8-bit */
+/* Relocs 56-59 are currently not defined.  */
+#define R_TILEPRO_TLS_GD_CALL	60	/* "jal" for TLS GD */
+#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61	/* X0 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62	/* X1 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63	/* Y0 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64	/* Y1 pipe "addi" for TLS GD */
+#define R_TILEPRO_TLS_IE_LOAD	65	/* "lw_tls" for TLS IE */
+#define R_TILEPRO_IMM16_X0_TLS_GD 66	/* X0 pipe 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD 67	/* X1 pipe 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68	/* X0 pipe low 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69	/* X1 pipe low 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70	/* X0 pipe high 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71	/* X1 pipe high 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72	/* X0 pipe ha() 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73	/* X1 pipe ha() 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE 74	/* X0 pipe 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE 75	/* X1 pipe 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76	/* X0 pipe low 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77	/* X1 pipe low 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78	/* X0 pipe high 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79	/* X1 pipe high 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80	/* X0 pipe ha() 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81	/* X1 pipe ha() 16-bit TLS IE offset */
+#define R_TILEPRO_TLS_DTPMOD32	82	/* ID of module containing symbol */
+#define R_TILEPRO_TLS_DTPOFF32	83	/* Offset in TLS block */
+#define R_TILEPRO_TLS_TPOFF32	84	/* Offset in static TLS block */
+#define R_TILEPRO_IMM16_X0_TLS_LE 85	/* X0 pipe 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE 86	/* X1 pipe 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87	/* X0 pipe low 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88	/* X1 pipe low 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89	/* X0 pipe high 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90	/* X1 pipe high 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91	/* X0 pipe ha() 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92	/* X1 pipe ha() 16-bit TLS LE offset */
+
+#define R_TILEPRO_GNU_VTINHERIT	128	/* GNU C++ vtable hierarchy */
+#define R_TILEPRO_GNU_VTENTRY	129	/* GNU C++ vtable member usage */
+
+#define R_TILEPRO_NUM		130
+
+
+/* TILE-Gx relocations.  */
+#define R_TILEGX_NONE		0	/* No reloc */
+#define R_TILEGX_64		1	/* Direct 64 bit */
+#define R_TILEGX_32		2	/* Direct 32 bit */
+#define R_TILEGX_16		3	/* Direct 16 bit */
+#define R_TILEGX_8		4	/* Direct 8 bit */
+#define R_TILEGX_64_PCREL	5	/* PC relative 64 bit */
+#define R_TILEGX_32_PCREL	6	/* PC relative 32 bit */
+#define R_TILEGX_16_PCREL	7	/* PC relative 16 bit */
+#define R_TILEGX_8_PCREL	8	/* PC relative 8 bit */
+#define R_TILEGX_HW0		9	/* hword 0 16-bit */
+#define R_TILEGX_HW1		10	/* hword 1 16-bit */
+#define R_TILEGX_HW2		11	/* hword 2 16-bit */
+#define R_TILEGX_HW3		12	/* hword 3 16-bit */
+#define R_TILEGX_HW0_LAST	13	/* last hword 0 16-bit */
+#define R_TILEGX_HW1_LAST	14	/* last hword 1 16-bit */
+#define R_TILEGX_HW2_LAST	15	/* last hword 2 16-bit */
+#define R_TILEGX_COPY		16	/* Copy relocation */
+#define R_TILEGX_GLOB_DAT	17	/* Create GOT entry */
+#define R_TILEGX_JMP_SLOT	18	/* Create PLT entry */
+#define R_TILEGX_RELATIVE	19	/* Adjust by program base */
+#define R_TILEGX_BROFF_X1	20	/* X1 pipe branch offset */
+#define R_TILEGX_JUMPOFF_X1	21	/* X1 pipe jump offset */
+#define R_TILEGX_JUMPOFF_X1_PLT	22	/* X1 pipe jump offset to PLT */
+#define R_TILEGX_IMM8_X0	23	/* X0 pipe 8-bit */
+#define R_TILEGX_IMM8_Y0	24	/* Y0 pipe 8-bit */
+#define R_TILEGX_IMM8_X1	25	/* X1 pipe 8-bit */
+#define R_TILEGX_IMM8_Y1	26	/* Y1 pipe 8-bit */
+#define R_TILEGX_DEST_IMM8_X1	27	/* X1 pipe destination 8-bit */
+#define R_TILEGX_MT_IMM14_X1	28	/* X1 pipe mtspr */
+#define R_TILEGX_MF_IMM14_X1	29	/* X1 pipe mfspr */
+#define R_TILEGX_MMSTART_X0	30	/* X0 pipe mm "start" */
+#define R_TILEGX_MMEND_X0	31	/* X0 pipe mm "end" */
+#define R_TILEGX_SHAMT_X0	32	/* X0 pipe shift amount */
+#define R_TILEGX_SHAMT_X1	33	/* X1 pipe shift amount */
+#define R_TILEGX_SHAMT_Y0	34	/* Y0 pipe shift amount */
+#define R_TILEGX_SHAMT_Y1	35	/* Y1 pipe shift amount */
+#define R_TILEGX_IMM16_X0_HW0	36	/* X0 pipe hword 0 */
+#define R_TILEGX_IMM16_X1_HW0	37	/* X1 pipe hword 0 */
+#define R_TILEGX_IMM16_X0_HW1	38	/* X0 pipe hword 1 */
+#define R_TILEGX_IMM16_X1_HW1	39	/* X1 pipe hword 1 */
+#define R_TILEGX_IMM16_X0_HW2	40	/* X0 pipe hword 2 */
+#define R_TILEGX_IMM16_X1_HW2	41	/* X1 pipe hword 2 */
+#define R_TILEGX_IMM16_X0_HW3	42	/* X0 pipe hword 3 */
+#define R_TILEGX_IMM16_X1_HW3	43	/* X1 pipe hword 3 */
+#define R_TILEGX_IMM16_X0_HW0_LAST 44	/* X0 pipe last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST 45	/* X1 pipe last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST 46	/* X0 pipe last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST 47	/* X1 pipe last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST 48	/* X0 pipe last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST 49	/* X1 pipe last hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_PCREL 50	/* X0 pipe PC relative hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_PCREL 51	/* X1 pipe PC relative hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_PCREL 52	/* X0 pipe PC relative hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_PCREL 53	/* X1 pipe PC relative hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_PCREL 54	/* X0 pipe PC relative hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_PCREL 55	/* X1 pipe PC relative hword 2 */
+#define R_TILEGX_IMM16_X0_HW3_PCREL 56	/* X0 pipe PC relative hword 3 */
+#define R_TILEGX_IMM16_X1_HW3_PCREL 57	/* X1 pipe PC relative hword 3 */
+#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_GOT 64	/* X0 pipe hword 0 GOT offset */
+#define R_TILEGX_IMM16_X1_HW0_GOT 65	/* X1 pipe hword 0 GOT offset */
+#define R_TILEGX_IMM16_X0_HW0_PLT_PCREL 66 /* X0 pipe PC-rel PLT hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_PLT_PCREL 67 /* X1 pipe PC-rel PLT hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_PLT_PCREL 68 /* X0 pipe PC-rel PLT hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_PLT_PCREL 69 /* X1 pipe PC-rel PLT hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_PLT_PCREL 70 /* X0 pipe PC-rel PLT hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_PLT_PCREL 71 /* X1 pipe PC-rel PLT hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */
+#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */
+#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */
+#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */
+#define R_TILEGX_IMM16_X0_HW3_PLT_PCREL 76 /* X0 pipe PC-rel PLT hword 3 */
+#define R_TILEGX_IMM16_X1_HW3_PLT_PCREL 77 /* X1 pipe PC-rel PLT hword 3 */
+#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78	/* X0 pipe hword 0 TLS GD offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79	/* X1 pipe hword 0 TLS GD offset */
+#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80	/* X0 pipe hword 0 TLS LE offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81	/* X1 pipe hword 0 TLS LE offset */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */
+/* Relocs 90-91 are currently not defined.  */
+#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92	/* X0 pipe hword 0 TLS IE offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93	/* X1 pipe hword 0 TLS IE offset */
+#define R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL 94 /* X0 pipe PC-rel PLT last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL 95 /* X1 pipe PC-rel PLT last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL 96 /* X0 pipe PC-rel PLT last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL 97 /* X1 pipe PC-rel PLT last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL 98 /* X0 pipe PC-rel PLT last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL 99 /* X1 pipe PC-rel PLT last hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */
+/* Relocs 104-105 are currently not defined.  */
+#define R_TILEGX_TLS_DTPMOD64	106	/* 64-bit ID of symbol's module */
+#define R_TILEGX_TLS_DTPOFF64	107	/* 64-bit offset in TLS block */
+#define R_TILEGX_TLS_TPOFF64	108	/* 64-bit offset in static TLS block */
+#define R_TILEGX_TLS_DTPMOD32	109	/* 32-bit ID of symbol's module */
+#define R_TILEGX_TLS_DTPOFF32	110	/* 32-bit offset in TLS block */
+#define R_TILEGX_TLS_TPOFF32	111	/* 32-bit offset in static TLS block */
+#define R_TILEGX_TLS_GD_CALL	112	/* "jal" for TLS GD */
+#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113	/* X0 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114	/* X1 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115	/* Y0 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116	/* Y1 pipe "addi" for TLS GD */
+#define R_TILEGX_TLS_IE_LOAD	117	/* "ld_tls" for TLS IE */
+#define R_TILEGX_IMM8_X0_TLS_ADD 118	/* X0 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_X1_TLS_ADD 119	/* X1 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_Y0_TLS_ADD 120	/* Y0 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_Y1_TLS_ADD 121	/* Y1 pipe "addi" for TLS GD/IE */
+
+#define R_TILEGX_GNU_VTINHERIT	128	/* GNU C++ vtable hierarchy */
+#define R_TILEGX_GNU_VTENTRY	129	/* GNU C++ vtable member usage */
+
+#define R_TILEGX_NUM		130
+
+
+#endif	/* elf.h */
Index: EcnlProtoTool/trunk/tcc-0.9.27/examples/ex1.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/examples/ex1.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/examples/ex1.c	(revision 331)
@@ -0,0 +1,8 @@
+#!/usr/local/bin/tcc -run
+#include <tcclib.h>
+
+int main()
+{
+    printf("Hello World\n");
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/examples/ex2.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/examples/ex2.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/examples/ex2.c	(revision 331)
@@ -0,0 +1,98 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#define N 20
+
+int nb_num;
+int tab[N];
+int stack_ptr;
+int stack_op[N];
+int stack_res[60];
+int result;
+
+int find(int n, int i1, int a, int b, int op)
+{
+    int i, j;
+    int c;
+
+    if (stack_ptr >= 0) {
+        stack_res[3*stack_ptr] = a;
+        stack_op[stack_ptr] = op;
+        stack_res[3*stack_ptr+1] = b;
+        stack_res[3*stack_ptr+2] = n;
+        if (n == result)
+            return 1;
+        tab[i1] = n;
+    }
+
+    for(i=0;i<nb_num;i++) {
+        for(j=i+1;j<nb_num;j++) {
+            a = tab[i];
+            b = tab[j];
+            if (a != 0 && b != 0) {
+
+                tab[j] = 0;
+                stack_ptr++;
+
+                if (find(a + b, i, a, b, '+'))
+                    return 1;
+                if (find(a - b, i, a, b, '-'))
+                    return 1;
+                if (find(b - a, i, b, a, '-'))
+                    return 1;
+                if (find(a * b, i, a, b, '*'))
+                    return 1;
+                if (b != 0) {
+                    c = a / b;
+                    if (find(c, i, a, b, '/'))
+                        return 1;
+                }
+
+                if (a != 0) {
+                    c = b / a;
+                    if (find(c, i, b, a, '/'))
+                        return 1;
+                }
+
+                stack_ptr--;
+                tab[i] = a;
+                tab[j] = b;
+            }
+        }
+    }
+
+    return 0;
+}
+
+int main(int argc, char **argv)
+{
+    int i, res, p;
+
+    if (argc < 3) {
+        printf("usage: %s: result numbers...\n"
+               "Try to find result from numbers with the 4 basic operations.\n", argv[0]);
+        exit(1);
+    }
+
+    p = 1;
+    result = atoi(argv[p]);
+    printf("result=%d\n", result);
+    nb_num = 0;
+    for(i=p+1;i<argc;i++) {
+        tab[nb_num++] = atoi(argv[i]);
+    }
+
+    stack_ptr = -1;
+    res = find(0, 0, 0, 0, ' ');
+    if (res) {
+        for(i=0;i<=stack_ptr;i++) {
+            printf("%d %c %d = %d\n",
+                   stack_res[3*i], stack_op[i],
+                   stack_res[3*i+1], stack_res[3*i+2]);
+        }
+        return 0;
+    } else {
+        printf("Impossible\n");
+        return 1;
+    }
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/examples/ex3.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/examples/ex3.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/examples/ex3.c	(revision 331)
@@ -0,0 +1,23 @@
+#include <tcclib.h>
+
+int fib(n)
+{
+    if (n <= 2)
+        return 1;
+    else
+        return fib(n-1) + fib(n-2);
+}
+
+int main(int argc, char **argv)
+{
+    int n;
+    if (argc < 2) {
+        printf("usage: fib n\n"
+               "Compute nth Fibonacci number\n");
+        return 1;
+    }
+
+    n = atoi(argv[1]);
+    printf("fib(%d) = %d\n", n, fib(n, 2));
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/examples/ex4.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/examples/ex4.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/examples/ex4.c	(revision 331)
@@ -0,0 +1,26 @@
+#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
+#include <stdlib.h>
+#include <stdio.h>
+#include <X11/Xlib.h>
+
+/* Yes, TCC can use X11 too ! */
+
+int main(int argc, char **argv)
+{
+    Display *display;
+    Screen *screen;
+
+    display = XOpenDisplay("");
+    if (!display) {
+        fprintf(stderr, "Could not open X11 display\n");
+        exit(1);
+    }
+    printf("X11 display opened.\n");
+    screen = XScreenOfDisplay(display, 0);
+    printf("width = %d\nheight = %d\ndepth = %d\n",
+           screen->width,
+           screen->height,
+           screen->root_depth);
+    XCloseDisplay(display);
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/examples/ex5.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/examples/ex5.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/examples/ex5.c	(revision 331)
@@ -0,0 +1,8 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+int main()
+{
+    printf("Hello World\n");
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/i386-asm.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/i386-asm.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/i386-asm.c	(revision 331)
@@ -0,0 +1,1723 @@
+/*
+ *  i386 specific functions for TCC assembler
+ *
+ *  Copyright (c) 2001, 2002 Fabrice Bellard
+ *  Copyright (c) 2009 Frédéric Feret (x86_64 support)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "tcc.h"
+
+#define MAX_OPERANDS 3
+
+#define TOK_ASM_first TOK_ASM_clc
+#define TOK_ASM_last TOK_ASM_emms
+#define TOK_ASM_alllast TOK_ASM_subps
+
+#define OPC_B          0x01  /* only used with OPC_WL */
+#define OPC_WL         0x02  /* accepts w, l or no suffix */
+#define OPC_BWL        (OPC_B | OPC_WL) /* accepts b, w, l or no suffix */
+#define OPC_REG        0x04 /* register is added to opcode */
+#define OPC_MODRM      0x08 /* modrm encoding */
+
+#define OPCT_MASK      0x70
+#define OPC_FWAIT      0x10 /* add fwait opcode */
+#define OPC_SHIFT      0x20 /* shift opcodes */
+#define OPC_ARITH      0x30 /* arithmetic opcodes */
+#define OPC_FARITH     0x40 /* FPU arithmetic opcodes */
+#define OPC_TEST       0x50 /* test opcodes */
+#define OPCT_IS(v,i) (((v) & OPCT_MASK) == (i))
+
+#define OPC_0F        0x100 /* Is secondary map (0x0f prefix) */
+#define OPC_48        0x200 /* Always has REX prefix */
+#ifdef TCC_TARGET_X86_64
+# define OPC_WLQ     0x1000  /* accepts w, l, q or no suffix */
+# define OPC_BWLQ    (OPC_B | OPC_WLQ) /* accepts b, w, l, q or no suffix */
+# define OPC_WLX     OPC_WLQ
+# define OPC_BWLX    OPC_BWLQ
+#else
+# define OPC_WLX     OPC_WL
+# define OPC_BWLX    OPC_BWL
+#endif
+
+#define OPC_GROUP_SHIFT 13
+
+/* in order to compress the operand type, we use specific operands and
+   we or only with EA  */
+enum {
+    OPT_REG8=0, /* warning: value is hardcoded from TOK_ASM_xxx */
+    OPT_REG16,  /* warning: value is hardcoded from TOK_ASM_xxx */
+    OPT_REG32,  /* warning: value is hardcoded from TOK_ASM_xxx */
+#ifdef TCC_TARGET_X86_64
+    OPT_REG64,  /* warning: value is hardcoded from TOK_ASM_xxx */
+#endif
+    OPT_MMX,    /* warning: value is hardcoded from TOK_ASM_xxx */
+    OPT_SSE,    /* warning: value is hardcoded from TOK_ASM_xxx */
+    OPT_CR,     /* warning: value is hardcoded from TOK_ASM_xxx */
+    OPT_TR,     /* warning: value is hardcoded from TOK_ASM_xxx */
+    OPT_DB,     /* warning: value is hardcoded from TOK_ASM_xxx */
+    OPT_SEG,
+    OPT_ST,
+#ifdef TCC_TARGET_X86_64
+    OPT_REG8_LOW, /* %spl,%bpl,%sil,%dil, encoded like ah,ch,dh,bh, but
+		     with REX prefix, not used in insn templates */
+#endif
+    OPT_IM8,
+    OPT_IM8S,
+    OPT_IM16,
+    OPT_IM32,
+#ifdef TCC_TARGET_X86_64
+    OPT_IM64,
+#endif
+    OPT_EAX,    /* %al, %ax, %eax or %rax register */
+    OPT_ST0,    /* %st(0) register */
+    OPT_CL,     /* %cl register */
+    OPT_DX,     /* %dx register */
+    OPT_ADDR,   /* OP_EA with only offset */
+    OPT_INDIR,  /* *(expr) */
+    /* composite types */
+    OPT_COMPOSITE_FIRST,
+    OPT_IM,     /* IM8 | IM16 | IM32 */
+    OPT_REG,    /* REG8 | REG16 | REG32 | REG64 */
+    OPT_REGW,   /* REG16 | REG32 | REG64 */
+    OPT_IMW,    /* IM16 | IM32 */
+    OPT_MMXSSE, /* MMX | SSE */
+    OPT_DISP,   /* Like OPT_ADDR, but emitted as displacement (for jumps) */
+    OPT_DISP8,  /* Like OPT_ADDR, but only 8bit (short jumps) */
+    /* can be ored with any OPT_xxx */
+    OPT_EA = 0x80
+};
+
+#define OP_REG8   (1 << OPT_REG8)
+#define OP_REG16  (1 << OPT_REG16)
+#define OP_REG32  (1 << OPT_REG32)
+#define OP_MMX    (1 << OPT_MMX)
+#define OP_SSE    (1 << OPT_SSE)
+#define OP_CR     (1 << OPT_CR)
+#define OP_TR     (1 << OPT_TR)
+#define OP_DB     (1 << OPT_DB)
+#define OP_SEG    (1 << OPT_SEG)
+#define OP_ST     (1 << OPT_ST)
+#define OP_IM8    (1 << OPT_IM8)
+#define OP_IM8S   (1 << OPT_IM8S)
+#define OP_IM16   (1 << OPT_IM16)
+#define OP_IM32   (1 << OPT_IM32)
+#define OP_EAX    (1 << OPT_EAX)
+#define OP_ST0    (1 << OPT_ST0)
+#define OP_CL     (1 << OPT_CL)
+#define OP_DX     (1 << OPT_DX)
+#define OP_ADDR   (1 << OPT_ADDR)
+#define OP_INDIR  (1 << OPT_INDIR)
+#ifdef TCC_TARGET_X86_64
+# define OP_REG64 (1 << OPT_REG64)
+# define OP_REG8_LOW (1 << OPT_REG8_LOW)
+# define OP_IM64  (1 << OPT_IM64)
+# define OP_EA32  (OP_EA << 1)
+#else
+# define OP_REG64 0
+# define OP_REG8_LOW 0
+# define OP_IM64  0
+# define OP_EA32  0
+#endif
+
+#define OP_EA     0x40000000
+#define OP_REG    (OP_REG8 | OP_REG16 | OP_REG32 | OP_REG64)
+
+#ifdef TCC_TARGET_X86_64
+# define TREG_XAX   TREG_RAX
+# define TREG_XCX   TREG_RCX
+# define TREG_XDX   TREG_RDX
+#else
+# define TREG_XAX   TREG_EAX
+# define TREG_XCX   TREG_ECX
+# define TREG_XDX   TREG_EDX
+#endif
+
+typedef struct ASMInstr {
+    uint16_t sym;
+    uint16_t opcode;
+    uint16_t instr_type;
+    uint8_t nb_ops;
+    uint8_t op_type[MAX_OPERANDS]; /* see OP_xxx */
+} ASMInstr;
+
+typedef struct Operand {
+    uint32_t type;
+    int8_t  reg; /* register, -1 if none */
+    int8_t  reg2; /* second register, -1 if none */
+    uint8_t shift;
+    ExprValue e;
+} Operand;
+
+static const uint8_t reg_to_size[9] = {
+/*
+    [OP_REG8] = 0,
+    [OP_REG16] = 1,
+    [OP_REG32] = 2,
+#ifdef TCC_TARGET_X86_64
+    [OP_REG64] = 3,
+#endif
+*/
+    0, 0, 1, 0, 2, 0, 0, 0, 3
+};
+
+#define NB_TEST_OPCODES 30
+
+static const uint8_t test_bits[NB_TEST_OPCODES] = {
+ 0x00, /* o */
+ 0x01, /* no */
+ 0x02, /* b */
+ 0x02, /* c */
+ 0x02, /* nae */
+ 0x03, /* nb */
+ 0x03, /* nc */
+ 0x03, /* ae */
+ 0x04, /* e */
+ 0x04, /* z */
+ 0x05, /* ne */
+ 0x05, /* nz */
+ 0x06, /* be */
+ 0x06, /* na */
+ 0x07, /* nbe */
+ 0x07, /* a */
+ 0x08, /* s */
+ 0x09, /* ns */
+ 0x0a, /* p */
+ 0x0a, /* pe */
+ 0x0b, /* np */
+ 0x0b, /* po */
+ 0x0c, /* l */
+ 0x0c, /* nge */
+ 0x0d, /* nl */
+ 0x0d, /* ge */
+ 0x0e, /* le */
+ 0x0e, /* ng */
+ 0x0f, /* nle */
+ 0x0f, /* g */
+};
+
+static const uint8_t segment_prefixes[] = {
+ 0x26, /* es */
+ 0x2e, /* cs */
+ 0x36, /* ss */
+ 0x3e, /* ds */
+ 0x64, /* fs */
+ 0x65  /* gs */
+};
+
+static const ASMInstr asm_instrs[] = {
+#define ALT(x) x
+/* This removes a 0x0f in the second byte */
+#define O(o) ((uint64_t) ((((o) & 0xff00) == 0x0f00) ? ((((o) >> 8) & ~0xff) | ((o) & 0xff)) : (o)))
+/* This constructs instr_type from opcode, type and group.  */
+#define T(o,i,g) ((i) | ((g) << OPC_GROUP_SHIFT) | ((((o) & 0xff00) == 0x0f00) ? OPC_0F : 0))
+#define DEF_ASM_OP0(name, opcode)
+#define DEF_ASM_OP0L(name, opcode, group, instr_type) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 0, { 0 } },
+#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 1, { op0 }},
+#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 2, { op0, op1 }},
+#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) { TOK_ASM_ ## name, O(opcode), T(opcode, instr_type, group), 3, { op0, op1, op2 }},
+#ifdef TCC_TARGET_X86_64
+# include "x86_64-asm.h"
+#else
+# include "i386-asm.h"
+#endif
+    /* last operation */
+    { 0, },
+};
+
+static const uint16_t op0_codes[] = {
+#define ALT(x)
+#define DEF_ASM_OP0(x, opcode) opcode,
+#define DEF_ASM_OP0L(name, opcode, group, instr_type)
+#define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
+#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
+#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
+#ifdef TCC_TARGET_X86_64
+# include "x86_64-asm.h"
+#else
+# include "i386-asm.h"
+#endif
+};
+
+static inline int get_reg_shift(TCCState *s1)
+{
+    int shift, v;
+    v = asm_int_expr(s1);
+    switch(v) {
+    case 1:
+        shift = 0;
+        break;
+    case 2:
+        shift = 1;
+        break;
+    case 4:
+        shift = 2;
+        break;
+    case 8:
+        shift = 3;
+        break;
+    default:
+        expect("1, 2, 4 or 8 constant");
+        shift = 0;
+        break;
+    }
+    return shift;
+}
+
+#ifdef TCC_TARGET_X86_64
+static int asm_parse_numeric_reg(int t, unsigned int *type)
+{
+    int reg = -1;
+    if (t >= TOK_IDENT && t < tok_ident) {
+	const char *s = table_ident[t - TOK_IDENT]->str;
+	char c;
+	*type = OP_REG64;
+	if (*s == 'c') {
+	    s++;
+	    *type = OP_CR;
+	}
+	if (*s++ != 'r')
+	  return -1;
+	/* Don't allow leading '0'.  */
+	if ((c = *s++) >= '1' && c <= '9')
+	  reg = c - '0';
+	else
+	  return -1;
+	if ((c = *s) >= '0' && c <= '5')
+	  s++, reg = reg * 10 + c - '0';
+	if (reg > 15)
+	  return -1;
+	if ((c = *s) == 0)
+	  ;
+	else if (*type != OP_REG64)
+	  return -1;
+	else if (c == 'b' && !s[1])
+	  *type = OP_REG8;
+	else if (c == 'w' && !s[1])
+	  *type = OP_REG16;
+	else if (c == 'd' && !s[1])
+	  *type = OP_REG32;
+	else
+	  return -1;
+    }
+    return reg;
+}
+#endif
+
+static int asm_parse_reg(unsigned int *type)
+{
+    int reg = 0;
+    *type = 0;
+    if (tok != '%')
+        goto error_32;
+    next();
+    if (tok >= TOK_ASM_eax && tok <= TOK_ASM_edi) {
+        reg = tok - TOK_ASM_eax;
+	*type = OP_REG32;
+#ifdef TCC_TARGET_X86_64
+    } else if (tok >= TOK_ASM_rax && tok <= TOK_ASM_rdi) {
+        reg = tok - TOK_ASM_rax;
+	*type = OP_REG64;
+    } else if (tok == TOK_ASM_rip) {
+        reg = -2; /* Probably should use different escape code. */
+	*type = OP_REG64;
+    } else if ((reg = asm_parse_numeric_reg(tok, type)) >= 0
+	       && (*type == OP_REG32 || *type == OP_REG64)) {
+	;
+#endif
+    } else {
+    error_32:
+        expect("register");
+    }
+    next();
+    return reg;
+}
+
+static void parse_operand(TCCState *s1, Operand *op)
+{
+    ExprValue e;
+    int reg, indir;
+    const char *p;
+
+    indir = 0;
+    if (tok == '*') {
+        next();
+        indir = OP_INDIR;
+    }
+
+    if (tok == '%') {
+        next();
+        if (tok >= TOK_ASM_al && tok <= TOK_ASM_db7) {
+            reg = tok - TOK_ASM_al;
+            op->type = 1 << (reg >> 3); /* WARNING: do not change constant order */
+            op->reg = reg & 7;
+            if ((op->type & OP_REG) && op->reg == TREG_XAX)
+                op->type |= OP_EAX;
+            else if (op->type == OP_REG8 && op->reg == TREG_XCX)
+                op->type |= OP_CL;
+            else if (op->type == OP_REG16 && op->reg == TREG_XDX)
+                op->type |= OP_DX;
+        } else if (tok >= TOK_ASM_dr0 && tok <= TOK_ASM_dr7) {
+            op->type = OP_DB;
+            op->reg = tok - TOK_ASM_dr0;
+        } else if (tok >= TOK_ASM_es && tok <= TOK_ASM_gs) {
+            op->type = OP_SEG;
+            op->reg = tok - TOK_ASM_es;
+        } else if (tok == TOK_ASM_st) {
+            op->type = OP_ST;
+            op->reg = 0;
+            next();
+            if (tok == '(') {
+                next();
+                if (tok != TOK_PPNUM)
+                    goto reg_error;
+                p = tokc.str.data;
+                reg = p[0] - '0';
+                if ((unsigned)reg >= 8 || p[1] != '\0')
+                    goto reg_error;
+                op->reg = reg;
+                next();
+                skip(')');
+            }
+            if (op->reg == 0)
+                op->type |= OP_ST0;
+            goto no_skip;
+#ifdef TCC_TARGET_X86_64
+	} else if (tok >= TOK_ASM_spl && tok <= TOK_ASM_dil) {
+	    op->type = OP_REG8 | OP_REG8_LOW;
+	    op->reg = 4 + tok - TOK_ASM_spl;
+        } else if ((op->reg = asm_parse_numeric_reg(tok, &op->type)) >= 0) {
+	    ;
+#endif
+        } else {
+        reg_error:
+            tcc_error("unknown register %%%s", get_tok_str(tok, &tokc));
+        }
+        next();
+    no_skip: ;
+    } else if (tok == '$') {
+        /* constant value */
+        next();
+        asm_expr(s1, &e);
+        op->type = OP_IM32;
+        op->e = e;
+        if (!op->e.sym) {
+            if (op->e.v == (uint8_t)op->e.v)
+                op->type |= OP_IM8;
+            if (op->e.v == (int8_t)op->e.v)
+                op->type |= OP_IM8S;
+            if (op->e.v == (uint16_t)op->e.v)
+                op->type |= OP_IM16;
+#ifdef TCC_TARGET_X86_64
+            if (op->e.v != (int32_t)op->e.v && op->e.v != (uint32_t)op->e.v)
+                op->type = OP_IM64;
+#endif
+        }
+    } else {
+        /* address(reg,reg2,shift) with all variants */
+        op->type = OP_EA;
+        op->reg = -1;
+        op->reg2 = -1;
+        op->shift = 0;
+        if (tok != '(') {
+            asm_expr(s1, &e);
+            op->e = e;
+        } else {
+            next();
+            if (tok == '%') {
+                unget_tok('(');
+                op->e.v = 0;
+                op->e.sym = NULL;
+            } else {
+                /* bracketed offset expression */
+                asm_expr(s1, &e);
+                if (tok != ')')
+                    expect(")");
+                next();
+                op->e.v = e.v;
+                op->e.sym = e.sym;
+            }
+	    op->e.pcrel = 0;
+        }
+        if (tok == '(') {
+	    unsigned int type = 0;
+            next();
+            if (tok != ',') {
+                op->reg = asm_parse_reg(&type);
+            }
+            if (tok == ',') {
+                next();
+                if (tok != ',') {
+                    op->reg2 = asm_parse_reg(&type);
+                }
+                if (tok == ',') {
+                    next();
+                    op->shift = get_reg_shift(s1);
+                }
+            }
+	    if (type & OP_REG32)
+	        op->type |= OP_EA32;
+            skip(')');
+        }
+        if (op->reg == -1 && op->reg2 == -1)
+            op->type |= OP_ADDR;
+    }
+    op->type |= indir;
+}
+
+/* XXX: unify with C code output ? */
+ST_FUNC void gen_expr32(ExprValue *pe)
+{
+    if (pe->pcrel)
+        /* If PC-relative, always set VT_SYM, even without symbol,
+	   so as to force a relocation to be emitted.  */
+	gen_addrpc32(VT_SYM, pe->sym, pe->v);
+    else
+	gen_addr32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
+}
+
+#ifdef TCC_TARGET_X86_64
+ST_FUNC void gen_expr64(ExprValue *pe)
+{
+    gen_addr64(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
+}
+#endif
+
+/* XXX: unify with C code output ? */
+static void gen_disp32(ExprValue *pe)
+{
+    Sym *sym = pe->sym;
+    ElfSym *esym = elfsym(sym);
+    if (esym && esym->st_shndx == cur_text_section->sh_num) {
+        /* same section: we can output an absolute value. Note
+           that the TCC compiler behaves differently here because
+           it always outputs a relocation to ease (future) code
+           elimination in the linker */
+        gen_le32(pe->v + esym->st_value - ind - 4);
+    } else {
+        if (sym && sym->type.t == VT_VOID) {
+            sym->type.t = VT_FUNC;
+            sym->type.ref = NULL;
+        }
+        gen_addrpc32(VT_SYM, sym, pe->v);
+    }
+}
+
+/* generate the modrm operand */
+static inline int asm_modrm(int reg, Operand *op)
+{
+    int mod, reg1, reg2, sib_reg1;
+
+    if (op->type & (OP_REG | OP_MMX | OP_SSE)) {
+        g(0xc0 + (reg << 3) + op->reg);
+    } else if (op->reg == -1 && op->reg2 == -1) {
+        /* displacement only */
+#ifdef TCC_TARGET_X86_64
+	g(0x04 + (reg << 3));
+	g(0x25);
+#else
+	g(0x05 + (reg << 3));
+#endif
+	gen_expr32(&op->e);
+#ifdef TCC_TARGET_X86_64
+    } else if (op->reg == -2) {
+        ExprValue *pe = &op->e;
+        g(0x05 + (reg << 3));
+        gen_addrpc32(pe->sym ? VT_SYM : 0, pe->sym, pe->v);
+        return ind;
+#endif
+    } else {
+        sib_reg1 = op->reg;
+        /* fist compute displacement encoding */
+        if (sib_reg1 == -1) {
+            sib_reg1 = 5;
+            mod = 0x00;
+        } else if (op->e.v == 0 && !op->e.sym && op->reg != 5) {
+            mod = 0x00;
+        } else if (op->e.v == (int8_t)op->e.v && !op->e.sym) {
+            mod = 0x40;
+        } else {
+            mod = 0x80;
+        }
+        /* compute if sib byte needed */
+        reg1 = op->reg;
+        if (op->reg2 != -1)
+            reg1 = 4;
+        g(mod + (reg << 3) + reg1);
+        if (reg1 == 4) {
+            /* add sib byte */
+            reg2 = op->reg2;
+            if (reg2 == -1)
+                reg2 = 4; /* indicate no index */
+            g((op->shift << 6) + (reg2 << 3) + sib_reg1);
+        }
+        /* add offset */
+        if (mod == 0x40) {
+            g(op->e.v);
+        } else if (mod == 0x80 || op->reg == -1) {
+	    gen_expr32(&op->e);
+        }
+    }
+    return 0;
+}
+
+#ifdef TCC_TARGET_X86_64
+#define REX_W 0x48
+#define REX_R 0x44
+#define REX_X 0x42
+#define REX_B 0x41
+
+static void asm_rex(int width64, Operand *ops, int nb_ops, int *op_type,
+		    int regi, int rmi)
+{
+  unsigned char rex = width64 ? 0x48 : 0;
+  int saw_high_8bit = 0;
+  int i;
+  if (rmi == -1) {
+      /* No mod/rm byte, but we might have a register op nevertheless
+         (we will add it to the opcode later).  */
+      for(i = 0; i < nb_ops; i++) {
+	  if (op_type[i] & (OP_REG | OP_ST)) {
+	      if (ops[i].reg >= 8) {
+		  rex |= REX_B;
+		  ops[i].reg -= 8;
+	      } else if (ops[i].type & OP_REG8_LOW)
+		  rex |= 0x40;
+	      else if (ops[i].type & OP_REG8 && ops[i].reg >= 4)
+		  /* An 8 bit reg >= 4 without REG8 is ah/ch/dh/bh */
+		  saw_high_8bit = ops[i].reg;
+	      break;
+	  }
+      }
+  } else {
+      if (regi != -1) {
+	  if (ops[regi].reg >= 8) {
+	      rex |= REX_R;
+	      ops[regi].reg -= 8;
+	  } else if (ops[regi].type & OP_REG8_LOW)
+	      rex |= 0x40;
+	  else if (ops[regi].type & OP_REG8 && ops[regi].reg >= 4)
+	      /* An 8 bit reg >= 4 without REG8 is ah/ch/dh/bh */
+	      saw_high_8bit = ops[regi].reg;
+      }
+      if (ops[rmi].type & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_EA)) {
+	  if (ops[rmi].reg >= 8) {
+	      rex |= REX_B;
+	      ops[rmi].reg -= 8;
+	  } else if (ops[rmi].type & OP_REG8_LOW)
+	      rex |= 0x40;
+	  else if (ops[rmi].type & OP_REG8 && ops[rmi].reg >= 4)
+	      /* An 8 bit reg >= 4 without REG8 is ah/ch/dh/bh */
+	      saw_high_8bit = ops[rmi].reg;
+      }
+      if (ops[rmi].type & OP_EA && ops[rmi].reg2 >= 8) {
+	  rex |= REX_X;
+	  ops[rmi].reg2 -= 8;
+      }
+  }
+  if (rex) {
+      if (saw_high_8bit)
+	  tcc_error("can't encode register %%%ch when REX prefix is required",
+		    "acdb"[saw_high_8bit-4]);
+      g(rex);
+  }
+}
+#endif
+
+static void maybe_print_stats (void)
+{
+  static int already = 1;
+  if (!already)
+    /* print stats about opcodes */
+    {
+        const struct ASMInstr *pa;
+        int freq[4];
+        int op_vals[500];
+        int nb_op_vals, i, j;
+
+	already = 1;
+        nb_op_vals = 0;
+        memset(freq, 0, sizeof(freq));
+        for(pa = asm_instrs; pa->sym != 0; pa++) {
+            freq[pa->nb_ops]++;
+            //for(i=0;i<pa->nb_ops;i++) {
+                for(j=0;j<nb_op_vals;j++) {
+                    //if (pa->op_type[i] == op_vals[j])
+                    if (pa->instr_type == op_vals[j])
+                        goto found;
+                }
+                //op_vals[nb_op_vals++] = pa->op_type[i];
+                op_vals[nb_op_vals++] = pa->instr_type;
+            found: ;
+            //}
+        }
+        for(i=0;i<nb_op_vals;i++) {
+            int v = op_vals[i];
+            //if ((v & (v - 1)) != 0)
+                printf("%3d: %08x\n", i, v);
+        }
+        printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n",
+               (int)sizeof(asm_instrs),
+	       (int)sizeof(asm_instrs) / (int)sizeof(ASMInstr),
+               freq[0], freq[1], freq[2], freq[3]);
+    }
+}
+
+ST_FUNC void asm_opcode(TCCState *s1, int opcode)
+{
+    const ASMInstr *pa;
+    int i, modrm_index, modreg_index, reg, v, op1, seg_prefix, pc;
+    int nb_ops, s;
+    Operand ops[MAX_OPERANDS], *pop;
+    int op_type[3]; /* decoded op type */
+    int alltypes;   /* OR of all operand types */
+    int autosize;
+    int p66;
+#ifdef TCC_TARGET_X86_64
+    int rex64;
+#endif
+
+    maybe_print_stats();
+    /* force synthetic ';' after prefix instruction, so we can handle */
+    /* one-line things like "rep stosb" instead of only "rep\nstosb" */
+    if (opcode >= TOK_ASM_wait && opcode <= TOK_ASM_repnz)
+        unget_tok(';');
+
+    /* get operands */
+    pop = ops;
+    nb_ops = 0;
+    seg_prefix = 0;
+    alltypes = 0;
+    for(;;) {
+        if (tok == ';' || tok == TOK_LINEFEED)
+            break;
+        if (nb_ops >= MAX_OPERANDS) {
+            tcc_error("incorrect number of operands");
+        }
+        parse_operand(s1, pop);
+        if (tok == ':') {
+           if (pop->type != OP_SEG || seg_prefix)
+               tcc_error("incorrect prefix");
+           seg_prefix = segment_prefixes[pop->reg];
+           next();
+           parse_operand(s1, pop);
+           if (!(pop->type & OP_EA)) {
+               tcc_error("segment prefix must be followed by memory reference");
+           }
+        }
+        pop++;
+        nb_ops++;
+        if (tok != ',')
+            break;
+        next();
+    }
+
+    s = 0; /* avoid warning */
+
+again:
+    /* optimize matching by using a lookup table (no hashing is needed
+       !) */
+    for(pa = asm_instrs; pa->sym != 0; pa++) {
+	int it = pa->instr_type & OPCT_MASK;
+        s = 0;
+        if (it == OPC_FARITH) {
+            v = opcode - pa->sym;
+            if (!((unsigned)v < 8 * 6 && (v % 6) == 0))
+                continue;
+        } else if (it == OPC_ARITH) {
+            if (!(opcode >= pa->sym && opcode < pa->sym + 8*NBWLX))
+                continue;
+            s = (opcode - pa->sym) % NBWLX;
+	    if ((pa->instr_type & OPC_BWLX) == OPC_WLX)
+	      {
+		/* We need to reject the xxxb opcodes that we accepted above.
+		   Note that pa->sym for WLX opcodes is the 'w' token,
+		   to get the 'b' token subtract one.  */
+		if (((opcode - pa->sym + 1) % NBWLX) == 0)
+		    continue;
+	        s++;
+	      }
+        } else if (it == OPC_SHIFT) {
+            if (!(opcode >= pa->sym && opcode < pa->sym + 7*NBWLX))
+                continue;
+            s = (opcode - pa->sym) % NBWLX;
+        } else if (it == OPC_TEST) {
+            if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES))
+                continue;
+	    /* cmovxx is a test opcode but accepts multiple sizes.
+	       The suffixes aren't encoded in the table, instead we
+	       simply force size autodetection always and deal with suffixed
+	       variants below when we don't find e.g. "cmovzl".  */
+	    if (pa->instr_type & OPC_WLX)
+	        s = NBWLX - 1;
+        } else if (pa->instr_type & OPC_B) {
+#ifdef TCC_TARGET_X86_64
+	    /* Some instructions don't have the full size but only
+	       bwl form.  insb e.g. */
+	    if ((pa->instr_type & OPC_WLQ) != OPC_WLQ
+		&& !(opcode >= pa->sym && opcode < pa->sym + NBWLX-1))
+	        continue;
+#endif
+            if (!(opcode >= pa->sym && opcode < pa->sym + NBWLX))
+                continue;
+            s = opcode - pa->sym;
+        } else if (pa->instr_type & OPC_WLX) {
+            if (!(opcode >= pa->sym && opcode < pa->sym + NBWLX-1))
+                continue;
+            s = opcode - pa->sym + 1;
+        } else {
+            if (pa->sym != opcode)
+                continue;
+        }
+        if (pa->nb_ops != nb_ops)
+            continue;
+#ifdef TCC_TARGET_X86_64
+	/* Special case for moves.  Selecting the IM64->REG64 form
+	   should only be done if we really have an >32bit imm64, and that
+	   is hardcoded.  Ignore it here.  */
+	if (pa->opcode == 0xb0 && ops[0].type != OP_IM64
+	    && (ops[1].type & OP_REG) == OP_REG64
+	    && !(pa->instr_type & OPC_0F))
+	    continue;
+#endif
+        /* now decode and check each operand */
+	alltypes = 0;
+        for(i = 0; i < nb_ops; i++) {
+            int op1, op2;
+            op1 = pa->op_type[i];
+            op2 = op1 & 0x1f;
+            switch(op2) {
+            case OPT_IM:
+                v = OP_IM8 | OP_IM16 | OP_IM32;
+                break;
+            case OPT_REG:
+                v = OP_REG8 | OP_REG16 | OP_REG32 | OP_REG64;
+                break;
+            case OPT_REGW:
+                v = OP_REG16 | OP_REG32 | OP_REG64;
+                break;
+            case OPT_IMW:
+                v = OP_IM16 | OP_IM32;
+                break;
+	    case OPT_MMXSSE:
+		v = OP_MMX | OP_SSE;
+		break;
+	    case OPT_DISP:
+	    case OPT_DISP8:
+		v = OP_ADDR;
+		break;
+            default:
+                v = 1 << op2;
+                break;
+            }
+            if (op1 & OPT_EA)
+                v |= OP_EA;
+	    op_type[i] = v;
+            if ((ops[i].type & v) == 0)
+                goto next;
+	    alltypes |= ops[i].type;
+        }
+        /* all is matching ! */
+        break;
+    next: ;
+    }
+    if (pa->sym == 0) {
+        if (opcode >= TOK_ASM_first && opcode <= TOK_ASM_last) {
+            int b;
+            b = op0_codes[opcode - TOK_ASM_first];
+            if (b & 0xff00) 
+                g(b >> 8);
+            g(b);
+            return;
+        } else if (opcode <= TOK_ASM_alllast) {
+            tcc_error("bad operand with opcode '%s'",
+                  get_tok_str(opcode, NULL));
+        } else {
+	    /* Special case for cmovcc, we accept size suffixes but ignore
+	       them, but we don't want them to blow up our tables.  */
+	    TokenSym *ts = table_ident[opcode - TOK_IDENT];
+	    if (ts->len >= 6
+		&& strchr("wlq", ts->str[ts->len-1])
+		&& !memcmp(ts->str, "cmov", 4)) {
+		opcode = tok_alloc(ts->str, ts->len-1)->tok;
+		goto again;
+	    }
+            tcc_error("unknown opcode '%s'", ts->str);
+        }
+    }
+    /* if the size is unknown, then evaluate it (OPC_B or OPC_WL case) */
+    autosize = NBWLX-1;
+#ifdef TCC_TARGET_X86_64
+    /* XXX the autosize should rather be zero, to not have to adjust this
+       all the time.  */
+    if ((pa->instr_type & OPC_BWLQ) == OPC_B)
+        autosize = NBWLX-2;
+#endif
+    if (s == autosize) {
+	/* Check for register operands providing hints about the size.
+	   Start from the end, i.e. destination operands.  This matters
+	   only for opcodes accepting different sized registers, lar and lsl
+	   are such opcodes.  */
+        for(i = nb_ops - 1; s == autosize && i >= 0; i--) {
+            if ((ops[i].type & OP_REG) && !(op_type[i] & (OP_CL | OP_DX)))
+                s = reg_to_size[ops[i].type & OP_REG];
+        }
+        if (s == autosize) {
+            if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) &&
+                (ops[0].type & (OP_SEG | OP_IM8S | OP_IM32)))
+                s = 2;
+	    else if ((opcode == TOK_ASM_push || opcode == TOK_ASM_pop) &&
+		     (ops[0].type & OP_EA))
+	        s = NBWLX - 2;
+            else
+                tcc_error("cannot infer opcode suffix");
+        }
+    }
+
+#ifdef TCC_TARGET_X86_64
+    /* Generate addr32 prefix if needed */
+    for(i = 0; i < nb_ops; i++) {
+        if (ops[i].type & OP_EA32) {
+	    g(0x67);
+	    break;
+        }
+    }
+#endif
+    /* generate data16 prefix if needed */
+    p66 = 0;
+    if (s == 1)
+        p66 = 1;
+    else {
+	/* accepting mmx+sse in all operands --> needs 0x66 to
+	   switch to sse mode.  Accepting only sse in an operand --> is
+	   already SSE insn and needs 0x66/f2/f3 handling.  */
+        for (i = 0; i < nb_ops; i++)
+            if ((op_type[i] & (OP_MMX | OP_SSE)) == (OP_MMX | OP_SSE)
+	        && ops[i].type & OP_SSE)
+	        p66 = 1;
+    }
+    if (p66)
+        g(0x66);
+#ifdef TCC_TARGET_X86_64
+    rex64 = 0;
+    if (pa->instr_type & OPC_48)
+        rex64 = 1;
+    else if (s == 3 || (alltypes & OP_REG64)) {
+        /* generate REX prefix */
+	int default64 = 0;
+	for(i = 0; i < nb_ops; i++) {
+	    if (op_type[i] == OP_REG64 && pa->opcode != 0xb8) {
+		/* If only 64bit regs are accepted in one operand
+		   this is a default64 instruction without need for
+		   REX prefixes, except for movabs(0xb8).  */
+		default64 = 1;
+		break;
+	    }
+	}
+	/* XXX find better encoding for the default64 instructions.  */
+        if (((opcode != TOK_ASM_push && opcode != TOK_ASM_pop
+	      && opcode != TOK_ASM_pushw && opcode != TOK_ASM_pushl
+	      && opcode != TOK_ASM_pushq && opcode != TOK_ASM_popw
+	      && opcode != TOK_ASM_popl && opcode != TOK_ASM_popq
+	      && opcode != TOK_ASM_call && opcode != TOK_ASM_jmp))
+	    && !default64)
+            rex64 = 1;
+    }
+#endif
+
+    /* now generates the operation */
+    if (OPCT_IS(pa->instr_type, OPC_FWAIT))
+        g(0x9b);
+    if (seg_prefix)
+        g(seg_prefix);
+
+    v = pa->opcode;
+    if (pa->instr_type & OPC_0F)
+        v = ((v & ~0xff) << 8) | 0x0f00 | (v & 0xff);
+    if ((v == 0x69 || v == 0x6b) && nb_ops == 2) {
+        /* kludge for imul $im, %reg */
+        nb_ops = 3;
+        ops[2] = ops[1];
+        op_type[2] = op_type[1];
+    } else if (v == 0xcd && ops[0].e.v == 3 && !ops[0].e.sym) {
+        v--; /* int $3 case */
+        nb_ops = 0;
+    } else if ((v == 0x06 || v == 0x07)) {
+        if (ops[0].reg >= 4) {
+            /* push/pop %fs or %gs */
+            v = 0x0fa0 + (v - 0x06) + ((ops[0].reg - 4) << 3);
+        } else {
+            v += ops[0].reg << 3;
+        }
+        nb_ops = 0;
+    } else if (v <= 0x05) {
+        /* arith case */
+        v += ((opcode - TOK_ASM_addb) / NBWLX) << 3;
+    } else if ((pa->instr_type & (OPCT_MASK | OPC_MODRM)) == OPC_FARITH) {
+        /* fpu arith case */
+        v += ((opcode - pa->sym) / 6) << 3;
+    }
+
+    /* search which operand will be used for modrm */
+    modrm_index = -1;
+    modreg_index = -1;
+    if (pa->instr_type & OPC_MODRM) {
+	if (!nb_ops) {
+	    /* A modrm opcode without operands is a special case (e.g. mfence).
+	       It has a group and acts as if there's an register operand 0
+	       (ax).  */
+	    i = 0;
+	    ops[i].type = OP_REG;
+	    ops[i].reg = 0;
+	    goto modrm_found;
+	}
+        /* first look for an ea operand */
+        for(i = 0;i < nb_ops; i++) {
+            if (op_type[i] & OP_EA)
+                goto modrm_found;
+        }
+        /* then if not found, a register or indirection (shift instructions) */
+        for(i = 0;i < nb_ops; i++) {
+            if (op_type[i] & (OP_REG | OP_MMX | OP_SSE | OP_INDIR))
+                goto modrm_found;
+        }
+#ifdef ASM_DEBUG
+        tcc_error("bad op table");
+#endif
+    modrm_found:
+        modrm_index = i;
+        /* if a register is used in another operand then it is
+           used instead of group */
+        for(i = 0;i < nb_ops; i++) {
+            int t = op_type[i];
+            if (i != modrm_index &&
+                (t & (OP_REG | OP_MMX | OP_SSE | OP_CR | OP_TR | OP_DB | OP_SEG))) {
+                modreg_index = i;
+                break;
+            }
+        }
+    }
+#ifdef TCC_TARGET_X86_64
+    asm_rex (rex64, ops, nb_ops, op_type, modreg_index, modrm_index);
+#endif
+
+    if (pa->instr_type & OPC_REG) {
+        /* mov $im, %reg case */
+        if (v == 0xb0 && s >= 1)
+            v += 7;
+        for(i = 0; i < nb_ops; i++) {
+            if (op_type[i] & (OP_REG | OP_ST)) {
+                v += ops[i].reg;
+                break;
+            }
+        }
+    }
+    if (pa->instr_type & OPC_B)
+        v += s >= 1;
+    if (nb_ops == 1 && pa->op_type[0] == OPT_DISP8) {
+	ElfSym *esym;
+        int jmp_disp;
+
+        /* see if we can really generate the jump with a byte offset */
+	esym = elfsym(ops[0].e.sym);
+        if (!esym || esym->st_shndx != cur_text_section->sh_num)
+            goto no_short_jump;
+        jmp_disp = ops[0].e.v + esym->st_value - ind - 2 - (v >= 0xff);
+        if (jmp_disp == (int8_t)jmp_disp) {
+            /* OK to generate jump */
+	    ops[0].e.sym = 0;
+            ops[0].e.v = jmp_disp;
+	    op_type[0] = OP_IM8S;
+        } else {
+        no_short_jump:
+	    /* long jump will be allowed. need to modify the
+	       opcode slightly */
+	    if (v == 0xeb) /* jmp */
+	        v = 0xe9;
+	    else if (v == 0x70) /* jcc */
+	        v += 0x0f10;
+	    else
+	        tcc_error("invalid displacement");
+        }
+    }
+    if (OPCT_IS(pa->instr_type, OPC_TEST))
+        v += test_bits[opcode - pa->sym];
+    op1 = v >> 16;
+    if (op1)
+        g(op1);
+    op1 = (v >> 8) & 0xff;
+    if (op1)
+        g(op1);
+    g(v);
+
+    if (OPCT_IS(pa->instr_type, OPC_SHIFT)) {
+        reg = (opcode - pa->sym) / NBWLX;
+        if (reg == 6)
+            reg = 7;
+    } else if (OPCT_IS(pa->instr_type, OPC_ARITH)) {
+        reg = (opcode - pa->sym) / NBWLX;
+    } else if (OPCT_IS(pa->instr_type, OPC_FARITH)) {
+        reg = (opcode - pa->sym) / 6;
+    } else {
+        reg = (pa->instr_type >> OPC_GROUP_SHIFT) & 7;
+    }
+
+    pc = 0;
+    if (pa->instr_type & OPC_MODRM) {
+        /* if a register is used in another operand then it is
+           used instead of group */
+	if (modreg_index >= 0)
+	    reg = ops[modreg_index].reg;
+        pc = asm_modrm(reg, &ops[modrm_index]);
+    }
+
+    /* emit constants */
+#ifndef TCC_TARGET_X86_64
+    if (!(pa->instr_type & OPC_0F)
+	&& (pa->opcode == 0x9a || pa->opcode == 0xea)) {
+        /* ljmp or lcall kludge */
+	gen_expr32(&ops[1].e);
+        if (ops[0].e.sym)
+            tcc_error("cannot relocate");
+        gen_le16(ops[0].e.v);
+        return;
+    }
+#endif
+    for(i = 0;i < nb_ops; i++) {
+        v = op_type[i];
+        if (v & (OP_IM8 | OP_IM16 | OP_IM32 | OP_IM64 | OP_IM8S | OP_ADDR)) {
+            /* if multiple sizes are given it means we must look
+               at the op size */
+            if ((v | OP_IM8 | OP_IM64) == (OP_IM8 | OP_IM16 | OP_IM32 | OP_IM64)) {
+                if (s == 0)
+                    v = OP_IM8;
+                else if (s == 1)
+                    v = OP_IM16;
+                else if (s == 2 || (v & OP_IM64) == 0)
+                    v = OP_IM32;
+                else
+                    v = OP_IM64;
+            }
+
+            if ((v & (OP_IM8 | OP_IM8S | OP_IM16)) && ops[i].e.sym)
+                tcc_error("cannot relocate");
+
+            if (v & (OP_IM8 | OP_IM8S)) {
+                g(ops[i].e.v);
+            } else if (v & OP_IM16) {
+                gen_le16(ops[i].e.v);
+#ifdef TCC_TARGET_X86_64
+            } else if (v & OP_IM64) {
+                gen_expr64(&ops[i].e);
+#endif
+	    } else if (pa->op_type[i] == OPT_DISP || pa->op_type[i] == OPT_DISP8) {
+                gen_disp32(&ops[i].e);
+            } else {
+                gen_expr32(&ops[i].e);
+            }
+        }
+    }
+
+    /* after immediate operands, adjust pc-relative address */
+    if (pc)
+        add32le(cur_text_section->data + pc - 4, pc - ind);
+}
+
+/* return the constraint priority (we allocate first the lowest
+   numbered constraints) */
+static inline int constraint_priority(const char *str)
+{
+    int priority, c, pr;
+
+    /* we take the lowest priority */
+    priority = 0;
+    for(;;) {
+        c = *str;
+        if (c == '\0')
+            break;
+        str++;
+        switch(c) {
+        case 'A':
+            pr = 0;
+            break;
+        case 'a':
+        case 'b':
+        case 'c':
+        case 'd':
+        case 'S':
+        case 'D':
+            pr = 1;
+            break;
+        case 'q':
+            pr = 2;
+            break;
+        case 'r':
+	case 'R':
+	case 'p':
+            pr = 3;
+            break;
+        case 'N':
+        case 'M':
+        case 'I':
+	case 'e':
+        case 'i':
+        case 'm':
+        case 'g':
+            pr = 4;
+            break;
+        default:
+            tcc_error("unknown constraint '%c'", c);
+            pr = 0;
+        }
+        if (pr > priority)
+            priority = pr;
+    }
+    return priority;
+}
+
+static const char *skip_constraint_modifiers(const char *p)
+{
+    while (*p == '=' || *p == '&' || *p == '+' || *p == '%')
+        p++;
+    return p;
+}
+
+/* If T (a token) is of the form "%reg" returns the register
+   number and type, otherwise return -1.  */
+ST_FUNC int asm_parse_regvar (int t)
+{
+    const char *s;
+    Operand op;
+    if (t < TOK_IDENT)
+        return -1;
+    s = table_ident[t - TOK_IDENT]->str;
+    if (s[0] != '%')
+        return -1;
+    t = tok_alloc(s+1, strlen(s)-1)->tok;
+    unget_tok(t);
+    unget_tok('%');
+    parse_operand(tcc_state, &op);
+    /* Accept only integer regs for now.  */
+    if (op.type & OP_REG)
+        return op.reg;
+    else
+        return -1;
+}
+
+#define REG_OUT_MASK 0x01
+#define REG_IN_MASK  0x02
+
+#define is_reg_allocated(reg) (regs_allocated[reg] & reg_mask)
+
+ST_FUNC void asm_compute_constraints(ASMOperand *operands,
+                                    int nb_operands, int nb_outputs,
+                                    const uint8_t *clobber_regs,
+                                    int *pout_reg)
+{
+    ASMOperand *op;
+    int sorted_op[MAX_ASM_OPERANDS];
+    int i, j, k, p1, p2, tmp, reg, c, reg_mask;
+    const char *str;
+    uint8_t regs_allocated[NB_ASM_REGS];
+
+    /* init fields */
+    for(i=0;i<nb_operands;i++) {
+        op = &operands[i];
+        op->input_index = -1;
+        op->ref_index = -1;
+        op->reg = -1;
+        op->is_memory = 0;
+        op->is_rw = 0;
+    }
+    /* compute constraint priority and evaluate references to output
+       constraints if input constraints */
+    for(i=0;i<nb_operands;i++) {
+        op = &operands[i];
+        str = op->constraint;
+        str = skip_constraint_modifiers(str);
+        if (isnum(*str) || *str == '[') {
+            /* this is a reference to another constraint */
+            k = find_constraint(operands, nb_operands, str, NULL);
+            if ((unsigned)k >= i || i < nb_outputs)
+                tcc_error("invalid reference in constraint %d ('%s')",
+                      i, str);
+            op->ref_index = k;
+            if (operands[k].input_index >= 0)
+                tcc_error("cannot reference twice the same operand");
+            operands[k].input_index = i;
+            op->priority = 5;
+	} else if ((op->vt->r & VT_VALMASK) == VT_LOCAL
+		   && op->vt->sym
+		   && (reg = op->vt->sym->r & VT_VALMASK) < VT_CONST) {
+	    op->priority = 1;
+	    op->reg = reg;
+        } else {
+            op->priority = constraint_priority(str);
+        }
+    }
+
+    /* sort operands according to their priority */
+    for(i=0;i<nb_operands;i++)
+        sorted_op[i] = i;
+    for(i=0;i<nb_operands - 1;i++) {
+        for(j=i+1;j<nb_operands;j++) {
+            p1 = operands[sorted_op[i]].priority;
+            p2 = operands[sorted_op[j]].priority;
+            if (p2 < p1) {
+                tmp = sorted_op[i];
+                sorted_op[i] = sorted_op[j];
+                sorted_op[j] = tmp;
+            }
+        }
+    }
+
+    for(i = 0;i < NB_ASM_REGS; i++) {
+        if (clobber_regs[i])
+            regs_allocated[i] = REG_IN_MASK | REG_OUT_MASK;
+        else
+            regs_allocated[i] = 0;
+    }
+    /* esp cannot be used */
+    regs_allocated[4] = REG_IN_MASK | REG_OUT_MASK;
+    /* ebp cannot be used yet */
+    regs_allocated[5] = REG_IN_MASK | REG_OUT_MASK;
+
+    /* allocate registers and generate corresponding asm moves */
+    for(i=0;i<nb_operands;i++) {
+        j = sorted_op[i];
+        op = &operands[j];
+        str = op->constraint;
+        /* no need to allocate references */
+        if (op->ref_index >= 0)
+            continue;
+        /* select if register is used for output, input or both */
+        if (op->input_index >= 0) {
+            reg_mask = REG_IN_MASK | REG_OUT_MASK;
+        } else if (j < nb_outputs) {
+            reg_mask = REG_OUT_MASK;
+        } else {
+            reg_mask = REG_IN_MASK;
+        }
+	if (op->reg >= 0) {
+	    if (is_reg_allocated(op->reg))
+	        tcc_error("asm regvar requests register that's taken already");
+	    reg = op->reg;
+	    goto reg_found;
+	}
+    try_next:
+        c = *str++;
+        switch(c) {
+        case '=':
+            goto try_next;
+        case '+':
+            op->is_rw = 1;
+            /* FALL THRU */
+        case '&':
+            if (j >= nb_outputs)
+                tcc_error("'%c' modifier can only be applied to outputs", c);
+            reg_mask = REG_IN_MASK | REG_OUT_MASK;
+            goto try_next;
+        case 'A':
+            /* allocate both eax and edx */
+            if (is_reg_allocated(TREG_XAX) ||
+                is_reg_allocated(TREG_XDX))
+                goto try_next;
+            op->is_llong = 1;
+            op->reg = TREG_XAX;
+            regs_allocated[TREG_XAX] |= reg_mask;
+            regs_allocated[TREG_XDX] |= reg_mask;
+            break;
+        case 'a':
+            reg = TREG_XAX;
+            goto alloc_reg;
+        case 'b':
+            reg = 3;
+            goto alloc_reg;
+        case 'c':
+            reg = TREG_XCX;
+            goto alloc_reg;
+        case 'd':
+            reg = TREG_XDX;
+            goto alloc_reg;
+        case 'S':
+            reg = 6;
+            goto alloc_reg;
+        case 'D':
+            reg = 7;
+        alloc_reg:
+            if (is_reg_allocated(reg))
+                goto try_next;
+            goto reg_found;
+        case 'q':
+            /* eax, ebx, ecx or edx */
+            for(reg = 0; reg < 4; reg++) {
+                if (!is_reg_allocated(reg))
+                    goto reg_found;
+            }
+            goto try_next;
+        case 'r':
+	case 'R':
+	case 'p': /* A general address, for x86(64) any register is acceptable*/
+            /* any general register */
+            for(reg = 0; reg < 8; reg++) {
+                if (!is_reg_allocated(reg))
+                    goto reg_found;
+            }
+            goto try_next;
+        reg_found:
+            /* now we can reload in the register */
+            op->is_llong = 0;
+            op->reg = reg;
+            regs_allocated[reg] |= reg_mask;
+            break;
+	case 'e':
+        case 'i':
+            if (!((op->vt->r & (VT_VALMASK | VT_LVAL)) == VT_CONST))
+                goto try_next;
+            break;
+        case 'I':
+        case 'N':
+        case 'M':
+            if (!((op->vt->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST))
+                goto try_next;
+            break;
+        case 'm':
+        case 'g':
+            /* nothing special to do because the operand is already in
+               memory, except if the pointer itself is stored in a
+               memory variable (VT_LLOCAL case) */
+            /* XXX: fix constant case */
+            /* if it is a reference to a memory zone, it must lie
+               in a register, so we reserve the register in the
+               input registers and a load will be generated
+               later */
+            if (j < nb_outputs || c == 'm') {
+                if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
+                    /* any general register */
+                    for(reg = 0; reg < 8; reg++) {
+                        if (!(regs_allocated[reg] & REG_IN_MASK))
+                            goto reg_found1;
+                    }
+                    goto try_next;
+                reg_found1:
+                    /* now we can reload in the register */
+                    regs_allocated[reg] |= REG_IN_MASK;
+                    op->reg = reg;
+                    op->is_memory = 1;
+                }
+            }
+            break;
+        default:
+            tcc_error("asm constraint %d ('%s') could not be satisfied",
+                  j, op->constraint);
+            break;
+        }
+        /* if a reference is present for that operand, we assign it too */
+        if (op->input_index >= 0) {
+            operands[op->input_index].reg = op->reg;
+            operands[op->input_index].is_llong = op->is_llong;
+        }
+    }
+
+    /* compute out_reg. It is used to store outputs registers to memory
+       locations references by pointers (VT_LLOCAL case) */
+    *pout_reg = -1;
+    for(i=0;i<nb_operands;i++) {
+        op = &operands[i];
+        if (op->reg >= 0 &&
+            (op->vt->r & VT_VALMASK) == VT_LLOCAL  &&
+            !op->is_memory) {
+            for(reg = 0; reg < 8; reg++) {
+                if (!(regs_allocated[reg] & REG_OUT_MASK))
+                    goto reg_found2;
+            }
+            tcc_error("could not find free output register for reloading");
+        reg_found2:
+            *pout_reg = reg;
+            break;
+        }
+    }
+
+    /* print sorted constraints */
+#ifdef ASM_DEBUG
+    for(i=0;i<nb_operands;i++) {
+        j = sorted_op[i];
+        op = &operands[j];
+        printf("%%%d [%s]: \"%s\" r=0x%04x reg=%d\n",
+               j,
+               op->id ? get_tok_str(op->id, NULL) : "",
+               op->constraint,
+               op->vt->r,
+               op->reg);
+    }
+    if (*pout_reg >= 0)
+        printf("out_reg=%d\n", *pout_reg);
+#endif
+}
+
+ST_FUNC void subst_asm_operand(CString *add_str,
+                              SValue *sv, int modifier)
+{
+    int r, reg, size, val;
+    char buf[64];
+
+    r = sv->r;
+    if ((r & VT_VALMASK) == VT_CONST) {
+        if (!(r & VT_LVAL) && modifier != 'c' && modifier != 'n' &&
+	    modifier != 'P')
+            cstr_ccat(add_str, '$');
+        if (r & VT_SYM) {
+	    const char *name = get_tok_str(sv->sym->v, NULL);
+	    if (sv->sym->v >= SYM_FIRST_ANOM) {
+		/* In case of anonymous symbols ("L.42", used
+		   for static data labels) we can't find them
+		   in the C symbol table when later looking up
+		   this name.  So enter them now into the asm label
+		   list when we still know the symbol.  */
+		get_asm_sym(tok_alloc(name, strlen(name))->tok, sv->sym);
+	    }
+            cstr_cat(add_str, name, -1);
+            if ((uint32_t)sv->c.i == 0)
+                goto no_offset;
+	    cstr_ccat(add_str, '+');
+        }
+        val = sv->c.i;
+        if (modifier == 'n')
+            val = -val;
+        snprintf(buf, sizeof(buf), "%d", (int)sv->c.i);
+        cstr_cat(add_str, buf, -1);
+    no_offset:;
+#ifdef TCC_TARGET_X86_64
+        if (r & VT_LVAL)
+            cstr_cat(add_str, "(%rip)", -1);
+#endif
+    } else if ((r & VT_VALMASK) == VT_LOCAL) {
+#ifdef TCC_TARGET_X86_64
+        snprintf(buf, sizeof(buf), "%d(%%rbp)", (int)sv->c.i);
+#else
+        snprintf(buf, sizeof(buf), "%d(%%ebp)", (int)sv->c.i);
+#endif
+        cstr_cat(add_str, buf, -1);
+    } else if (r & VT_LVAL) {
+        reg = r & VT_VALMASK;
+        if (reg >= VT_CONST)
+            tcc_error("internal compiler error");
+        snprintf(buf, sizeof(buf), "(%%%s)",
+#ifdef TCC_TARGET_X86_64
+                 get_tok_str(TOK_ASM_rax + reg, NULL)
+#else
+                 get_tok_str(TOK_ASM_eax + reg, NULL)
+#endif
+		 );
+        cstr_cat(add_str, buf, -1);
+    } else {
+        /* register case */
+        reg = r & VT_VALMASK;
+        if (reg >= VT_CONST)
+            tcc_error("internal compiler error");
+
+        /* choose register operand size */
+        if ((sv->type.t & VT_BTYPE) == VT_BYTE ||
+	    (sv->type.t & VT_BTYPE) == VT_BOOL)
+            size = 1;
+        else if ((sv->type.t & VT_BTYPE) == VT_SHORT)
+            size = 2;
+#ifdef TCC_TARGET_X86_64
+        else if ((sv->type.t & VT_BTYPE) == VT_LLONG ||
+		 (sv->type.t & VT_BTYPE) == VT_PTR)
+            size = 8;
+#endif
+        else
+            size = 4;
+        if (size == 1 && reg >= 4)
+            size = 4;
+
+        if (modifier == 'b') {
+            if (reg >= 4)
+                tcc_error("cannot use byte register");
+            size = 1;
+        } else if (modifier == 'h') {
+            if (reg >= 4)
+                tcc_error("cannot use byte register");
+            size = -1;
+        } else if (modifier == 'w') {
+            size = 2;
+        } else if (modifier == 'k') {
+            size = 4;
+#ifdef TCC_TARGET_X86_64
+        } else if (modifier == 'q') {
+            size = 8;
+#endif
+        }
+
+        switch(size) {
+        case -1:
+            reg = TOK_ASM_ah + reg;
+            break;
+        case 1:
+            reg = TOK_ASM_al + reg;
+            break;
+        case 2:
+            reg = TOK_ASM_ax + reg;
+            break;
+        default:
+            reg = TOK_ASM_eax + reg;
+            break;
+#ifdef TCC_TARGET_X86_64
+        case 8:
+            reg = TOK_ASM_rax + reg;
+            break;
+#endif
+        }
+        snprintf(buf, sizeof(buf), "%%%s", get_tok_str(reg, NULL));
+        cstr_cat(add_str, buf, -1);
+    }
+}
+
+/* generate prolog and epilog code for asm statement */
+ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
+                         int nb_outputs, int is_output,
+                         uint8_t *clobber_regs,
+                         int out_reg)
+{
+    uint8_t regs_allocated[NB_ASM_REGS];
+    ASMOperand *op;
+    int i, reg;
+
+    /* Strictly speaking %Xbp and %Xsp should be included in the
+       call-preserved registers, but currently it doesn't matter.  */
+#ifdef TCC_TARGET_X86_64
+#ifdef TCC_TARGET_PE
+    static uint8_t reg_saved[] = { 3, 6, 7, 12, 13, 14, 15 };
+#else
+    static uint8_t reg_saved[] = { 3, 12, 13, 14, 15 };
+#endif
+#else
+    static uint8_t reg_saved[] = { 3, 6, 7 };
+#endif
+
+    /* mark all used registers */
+    memcpy(regs_allocated, clobber_regs, sizeof(regs_allocated));
+    for(i = 0; i < nb_operands;i++) {
+        op = &operands[i];
+        if (op->reg >= 0)
+            regs_allocated[op->reg] = 1;
+    }
+    if (!is_output) {
+        /* generate reg save code */
+        for(i = 0; i < sizeof(reg_saved)/sizeof(reg_saved[0]); i++) {
+            reg = reg_saved[i];
+            if (regs_allocated[reg]) {
+		if (reg >= 8)
+		  g(0x41), reg-=8;
+                g(0x50 + reg);
+            }
+        }
+
+        /* generate load code */
+        for(i = 0; i < nb_operands; i++) {
+            op = &operands[i];
+            if (op->reg >= 0) {
+                if ((op->vt->r & VT_VALMASK) == VT_LLOCAL &&
+                    op->is_memory) {
+                    /* memory reference case (for both input and
+                       output cases) */
+                    SValue sv;
+                    sv = *op->vt;
+                    sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL;
+                    sv.type.t = VT_PTR;
+                    load(op->reg, &sv);
+                } else if (i >= nb_outputs || op->is_rw) {
+                    /* load value in register */
+                    load(op->reg, op->vt);
+                    if (op->is_llong) {
+                        SValue sv;
+                        sv = *op->vt;
+                        sv.c.i += 4;
+                        load(TREG_XDX, &sv);
+                    }
+                }
+            }
+        }
+    } else {
+        /* generate save code */
+        for(i = 0 ; i < nb_outputs; i++) {
+            op = &operands[i];
+            if (op->reg >= 0) {
+                if ((op->vt->r & VT_VALMASK) == VT_LLOCAL) {
+                    if (!op->is_memory) {
+                        SValue sv;
+                        sv = *op->vt;
+                        sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
+			sv.type.t = VT_PTR;
+                        load(out_reg, &sv);
+
+			sv = *op->vt;
+                        sv.r = (sv.r & ~VT_VALMASK) | out_reg;
+                        store(op->reg, &sv);
+                    }
+                } else {
+                    store(op->reg, op->vt);
+                    if (op->is_llong) {
+                        SValue sv;
+                        sv = *op->vt;
+                        sv.c.i += 4;
+                        store(TREG_XDX, &sv);
+                    }
+                }
+            }
+        }
+        /* generate reg restore code */
+        for(i = sizeof(reg_saved)/sizeof(reg_saved[0]) - 1; i >= 0; i--) {
+            reg = reg_saved[i];
+            if (regs_allocated[reg]) {
+		if (reg >= 8)
+		  g(0x41), reg-=8;
+                g(0x58 + reg);
+            }
+        }
+    }
+}
+
+ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)
+{
+    int reg;
+    TokenSym *ts;
+#ifdef TCC_TARGET_X86_64
+    unsigned int type;
+#endif
+
+    if (!strcmp(str, "memory") ||
+        !strcmp(str, "cc") ||
+	!strcmp(str, "flags"))
+        return;
+    ts = tok_alloc(str, strlen(str));
+    reg = ts->tok;
+    if (reg >= TOK_ASM_eax && reg <= TOK_ASM_edi) {
+        reg -= TOK_ASM_eax;
+    } else if (reg >= TOK_ASM_ax && reg <= TOK_ASM_di) {
+        reg -= TOK_ASM_ax;
+#ifdef TCC_TARGET_X86_64
+    } else if (reg >= TOK_ASM_rax && reg <= TOK_ASM_rdi) {
+        reg -= TOK_ASM_rax;
+    } else if ((reg = asm_parse_numeric_reg(reg, &type)) >= 0) {
+	;
+#endif
+    } else {
+        tcc_error("invalid clobber register '%s'", str);
+    }
+    clobber_regs[reg] = 1;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/i386-asm.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/i386-asm.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/i386-asm.h	(revision 331)
@@ -0,0 +1,480 @@
+     DEF_ASM_OP0(clc, 0xf8) /* must be first OP0 */
+     DEF_ASM_OP0(cld, 0xfc)
+     DEF_ASM_OP0(cli, 0xfa)
+     DEF_ASM_OP0(clts, 0x0f06)
+     DEF_ASM_OP0(cmc, 0xf5)
+     DEF_ASM_OP0(lahf, 0x9f)
+     DEF_ASM_OP0(sahf, 0x9e)
+     DEF_ASM_OP0(pusha, 0x60)
+     DEF_ASM_OP0(popa, 0x61)
+     DEF_ASM_OP0(pushfl, 0x9c)
+     DEF_ASM_OP0(popfl, 0x9d)
+     DEF_ASM_OP0(pushf, 0x9c)
+     DEF_ASM_OP0(popf, 0x9d)
+     DEF_ASM_OP0(stc, 0xf9)
+     DEF_ASM_OP0(std, 0xfd)
+     DEF_ASM_OP0(sti, 0xfb)
+     DEF_ASM_OP0(aaa, 0x37)
+     DEF_ASM_OP0(aas, 0x3f)
+     DEF_ASM_OP0(daa, 0x27)
+     DEF_ASM_OP0(das, 0x2f)
+     DEF_ASM_OP0(aad, 0xd50a)
+     DEF_ASM_OP0(aam, 0xd40a)
+     DEF_ASM_OP0(cbw, 0x6698)
+     DEF_ASM_OP0(cwd, 0x6699)
+     DEF_ASM_OP0(cwde, 0x98)
+     DEF_ASM_OP0(cdq, 0x99)
+     DEF_ASM_OP0(cbtw, 0x6698)
+     DEF_ASM_OP0(cwtl, 0x98)
+     DEF_ASM_OP0(cwtd, 0x6699)
+     DEF_ASM_OP0(cltd, 0x99)
+     DEF_ASM_OP0(int3, 0xcc)
+     DEF_ASM_OP0(into, 0xce)
+     DEF_ASM_OP0(iret, 0xcf)
+     DEF_ASM_OP0(rsm, 0x0faa)
+     DEF_ASM_OP0(hlt, 0xf4)
+     DEF_ASM_OP0(nop, 0x90)
+     DEF_ASM_OP0(pause, 0xf390)
+     DEF_ASM_OP0(xlat, 0xd7)
+
+     /* strings */
+ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
+ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
+
+ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWLX))
+
+     /* bits */
+     
+ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
+
+ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+     /* prefixes */
+     DEF_ASM_OP0(wait, 0x9b)
+     DEF_ASM_OP0(fwait, 0x9b)
+     DEF_ASM_OP0(aword, 0x67)
+     DEF_ASM_OP0(addr16, 0x67)
+     ALT(DEF_ASM_OP0(word, 0x66))
+     DEF_ASM_OP0(data16, 0x66)
+     DEF_ASM_OP0(lock, 0xf0)
+     DEF_ASM_OP0(rep, 0xf3)
+     DEF_ASM_OP0(repe, 0xf3)
+     DEF_ASM_OP0(repz, 0xf3)
+     DEF_ASM_OP0(repne, 0xf2)
+     DEF_ASM_OP0(repnz, 0xf2)
+             
+     DEF_ASM_OP0(invd, 0x0f08)
+     DEF_ASM_OP0(wbinvd, 0x0f09)
+     DEF_ASM_OP0(cpuid, 0x0fa2)
+     DEF_ASM_OP0(wrmsr, 0x0f30)
+     DEF_ASM_OP0(rdtsc, 0x0f31)
+     DEF_ASM_OP0(rdmsr, 0x0f32)
+     DEF_ASM_OP0(rdpmc, 0x0f33)
+     DEF_ASM_OP0(ud2, 0x0f0b)
+
+     /* NOTE: we took the same order as gas opcode definition order */
+ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWLX, OPT_ADDR, OPT_EAX))
+ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWLX, OPT_EAX, OPT_ADDR))
+ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWLX, OPT_IM, OPT_REG))
+ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WLX, OPT_SEG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_SEG))
+
+ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WLX, OPT_CR, OPT_REG32))
+ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WLX, OPT_DB, OPT_REG32))
+ALT(DEF_ASM_OP2(movw, 0x0f24, 0, OPC_MODRM | OPC_WLX, OPT_TR, OPT_REG32))
+ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WLX, OPT_REG32, OPT_CR))
+ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WLX, OPT_REG32, OPT_DB))
+ALT(DEF_ASM_OP2(movw, 0x0f26, 0, OPC_MODRM | OPC_WLX, OPT_REG32, OPT_TR))
+
+ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(movsbw, 0x660fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG16))
+ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WLX, OPT_REG8 | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
+
+ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WLX, OPT_REGW))
+ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP1(pushw, 0x6a, 0, OPC_WLX, OPT_IM8S))
+ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WLX, OPT_IM32))
+ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WLX, OPT_SEG))
+
+ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WLX, OPT_REGW))
+ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WLX, OPT_SEG))
+
+ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_REGW, OPT_EAX))
+ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_EAX, OPT_REGW))
+ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+
+ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
+ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
+ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
+ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
+
+ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
+ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
+ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
+ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
+
+ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WLX, OPT_EA, OPT_REG))
+
+ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+
+     /* arith */
+ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
+ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWLX, OPT_IM, OPT_EAX))
+ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWLX, OPT_IM, OPT_EAX))
+ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP1(incw, 0x40, 0, OPC_REG | OPC_WLX, OPT_REGW))
+ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(decw, 0x48, 0, OPC_REG | OPC_WLX, OPT_REGW))
+ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG))
+ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW))
+ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW))
+
+ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX))
+ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX))
+
+     /* shifts */
+ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW))
+
+ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
+ALT(DEF_ASM_OP1(call, 0xe8, 0, 0, OPT_DISP))
+ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
+ALT(DEF_ASM_OP1(jmp, 0xeb, 0, 0, OPT_DISP8))
+
+ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
+ALT(DEF_ASM_OP1(lcall, 0xff, 3, OPC_MODRM, OPT_EA))
+ALT(DEF_ASM_OP2(ljmp, 0xea, 0, 0, OPT_IM16, OPT_IM32))
+ALT(DEF_ASM_OP1(ljmp, 0xff, 5, OPC_MODRM, OPT_EA))
+
+ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
+ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
+ALT(DEF_ASM_OP1(setob, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
+    DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
+    DEF_ASM_OP0(leave, 0xc9)
+    DEF_ASM_OP0(ret, 0xc3)
+    DEF_ASM_OP0(retl,0xc3)
+ALT(DEF_ASM_OP1(retl,0xc2, 0, 0, OPT_IM16))
+ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
+    DEF_ASM_OP0(lret, 0xcb)
+ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
+
+ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_TEST, OPT_DISP8))
+    DEF_ASM_OP1(loopne, 0xe0, 0, 0, OPT_DISP8)
+    DEF_ASM_OP1(loopnz, 0xe0, 0, 0, OPT_DISP8)
+    DEF_ASM_OP1(loope, 0xe1, 0, 0, OPT_DISP8)
+    DEF_ASM_OP1(loopz, 0xe1, 0, 0, OPT_DISP8)
+    DEF_ASM_OP1(loop, 0xe2, 0, 0, OPT_DISP8)
+    DEF_ASM_OP1(jecxz, 0xe3, 0, 0, OPT_DISP8)
+     
+     /* float */
+     /* specific fcomp handling */
+ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
+
+ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
+ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
+ALT(DEF_ASM_OP2(fadd, 0xdcc0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
+ALT(DEF_ASM_OP2(fmul, 0xdcc8, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
+ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
+ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
+ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
+ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
+ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
+ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
+ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
+ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
+ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
+
+     DEF_ASM_OP0(fucompp, 0xdae9)
+     DEF_ASM_OP0(ftst, 0xd9e4)
+     DEF_ASM_OP0(fxam, 0xd9e5)
+     DEF_ASM_OP0(fld1, 0xd9e8)
+     DEF_ASM_OP0(fldl2t, 0xd9e9)
+     DEF_ASM_OP0(fldl2e, 0xd9ea)
+     DEF_ASM_OP0(fldpi, 0xd9eb)
+     DEF_ASM_OP0(fldlg2, 0xd9ec)
+     DEF_ASM_OP0(fldln2, 0xd9ed)
+     DEF_ASM_OP0(fldz, 0xd9ee)
+
+     DEF_ASM_OP0(f2xm1, 0xd9f0)
+     DEF_ASM_OP0(fyl2x, 0xd9f1)
+     DEF_ASM_OP0(fptan, 0xd9f2)
+     DEF_ASM_OP0(fpatan, 0xd9f3)
+     DEF_ASM_OP0(fxtract, 0xd9f4)
+     DEF_ASM_OP0(fprem1, 0xd9f5)
+     DEF_ASM_OP0(fdecstp, 0xd9f6)
+     DEF_ASM_OP0(fincstp, 0xd9f7)
+     DEF_ASM_OP0(fprem, 0xd9f8)
+     DEF_ASM_OP0(fyl2xp1, 0xd9f9)
+     DEF_ASM_OP0(fsqrt, 0xd9fa)
+     DEF_ASM_OP0(fsincos, 0xd9fb)
+     DEF_ASM_OP0(frndint, 0xd9fc)
+     DEF_ASM_OP0(fscale, 0xd9fd)
+     DEF_ASM_OP0(fsin, 0xd9fe)
+     DEF_ASM_OP0(fcos, 0xd9ff)
+     DEF_ASM_OP0(fchs, 0xd9e0)
+     DEF_ASM_OP0(fabs, 0xd9e1)
+     DEF_ASM_OP0(fninit, 0xdbe3)
+     DEF_ASM_OP0(fnclex, 0xdbe2)
+     DEF_ASM_OP0(fnop, 0xd9d0)
+
+    /* fp load */
+    DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
+    DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
+    DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
+ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
+    DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
+    DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
+    
+    /* fp store */
+    DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
+    DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
+    DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
+ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
+    DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
+
+    DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
+    DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
+
+    /* exchange */
+    DEF_ASM_OP0(fxch, 0xd9c9)
+ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
+
+    /* misc FPU */
+    DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
+    DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
+
+    DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
+    DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
+    DEF_ASM_OP0(fnstsw, 0xdfe0)
+ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
+ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
+    DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
+ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
+ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
+    DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
+    DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
+    DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
+    DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
+    DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
+    DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
+
+    /* segments */
+    DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
+ALT(DEF_ASM_OP2(larw, 0x0f02, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG))
+    DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
+    DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
+ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_REG))
+    DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG)
+    DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
+    DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
+    DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG16| OPT_EA)
+    DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
+    DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
+
+    /* 486 */
+    DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
+ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA ))
+ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA ))
+    DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
+
+    DEF_ASM_OP2(boundl, 0x62, 0, OPC_MODRM, OPT_REG32, OPT_EA)
+    DEF_ASM_OP2(boundw, 0x6662, 0, OPC_MODRM, OPT_REG16, OPT_EA)
+
+    /* pentium */
+    DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
+    
+    /* pentium pro */
+ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
+    DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+
+    DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+
+    /* mmx */
+    DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
+    DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMXSSE )
+    DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX )
+ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG32 ))
+ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
+ALT(DEF_ASM_OP2(movq, 0x660fd6, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_SSE ))
+ALT(DEF_ASM_OP2(movq, 0xf30f7e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ))
+
+    DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+
+    /* sse */
+    DEF_ASM_OP2(movups, 0x0f10, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
+ALT(DEF_ASM_OP2(movups, 0x0f11, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
+    DEF_ASM_OP2(movaps, 0x0f28, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
+ALT(DEF_ASM_OP2(movaps, 0x0f29, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
+    DEF_ASM_OP2(movhps, 0x0f16, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
+ALT(DEF_ASM_OP2(movhps, 0x0f17, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
+    DEF_ASM_OP2(addps, 0x0f58, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(cvtpi2ps, 0x0f2a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_SSE )
+    DEF_ASM_OP2(cvtps2pi, 0x0f2d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX )
+    DEF_ASM_OP2(cvttps2pi, 0x0f2c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX )
+    DEF_ASM_OP2(divps, 0x0f5e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(maxps, 0x0f5f, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(minps, 0x0f5d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(mulps, 0x0f59, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(pavgb, 0x0fe0, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(pavgw, 0x0fe3, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(pmaxsw, 0x0fee, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pmaxub, 0x0fde, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pminsw, 0x0fea, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pminub, 0x0fda, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(rcpss, 0x0f53, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(rsqrtps, 0x0f52, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(sqrtps, 0x0f51, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(subps, 0x0f5c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+
+#undef ALT
+#undef DEF_ASM_OP0
+#undef DEF_ASM_OP0L
+#undef DEF_ASM_OP1
+#undef DEF_ASM_OP2
+#undef DEF_ASM_OP3
Index: EcnlProtoTool/trunk/tcc-0.9.27/i386-gen.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/i386-gen.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/i386-gen.c	(revision 331)
@@ -0,0 +1,1164 @@
+/*
+ *  X86 code generator for TCC
+ * 
+ *  Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef TARGET_DEFS_ONLY
+
+/* number of available registers */
+#define NB_REGS         5
+#define NB_ASM_REGS     8
+#define CONFIG_TCC_ASM
+
+/* a register can belong to several classes. The classes must be
+   sorted from more general to more precise (see gv2() code which does
+   assumptions on it). */
+#define RC_INT     0x0001 /* generic integer register */
+#define RC_FLOAT   0x0002 /* generic float register */
+#define RC_EAX     0x0004
+#define RC_ST0     0x0008 
+#define RC_ECX     0x0010
+#define RC_EDX     0x0020
+#define RC_EBX     0x0040
+
+#define RC_IRET    RC_EAX /* function return: integer register */
+#define RC_LRET    RC_EDX /* function return: second integer register */
+#define RC_FRET    RC_ST0 /* function return: float register */
+
+/* pretty names for the registers */
+enum {
+    TREG_EAX = 0,
+    TREG_ECX,
+    TREG_EDX,
+    TREG_EBX,
+    TREG_ST0,
+    TREG_ESP = 4
+};
+
+/* return registers for function */
+#define REG_IRET TREG_EAX /* single word int return register */
+#define REG_LRET TREG_EDX /* second word return register (for long long) */
+#define REG_FRET TREG_ST0 /* float return register */
+
+/* defined if function parameters must be evaluated in reverse order */
+#define INVERT_FUNC_PARAMS
+
+/* defined if structures are passed as pointers. Otherwise structures
+   are directly pushed on stack. */
+/* #define FUNC_STRUCT_PARAM_AS_PTR */
+
+/* pointer size, in bytes */
+#define PTR_SIZE 4
+
+/* long double size and alignment, in bytes */
+#define LDOUBLE_SIZE  12
+#define LDOUBLE_ALIGN 4
+/* maximum alignment (for aligned attribute support) */
+#define MAX_ALIGN     8
+
+/******************************************************/
+#else /* ! TARGET_DEFS_ONLY */
+/******************************************************/
+#include "tcc.h"
+
+/* define to 1/0 to [not] have EBX as 4th register */
+#define USE_EBX 0
+
+ST_DATA const int reg_classes[NB_REGS] = {
+    /* eax */ RC_INT | RC_EAX,
+    /* ecx */ RC_INT | RC_ECX,
+    /* edx */ RC_INT | RC_EDX,
+    /* ebx */ (RC_INT | RC_EBX) * USE_EBX,
+    /* st0 */ RC_FLOAT | RC_ST0,
+};
+
+static unsigned long func_sub_sp_offset;
+static int func_ret_sub;
+#ifdef CONFIG_TCC_BCHECK
+static addr_t func_bound_offset;
+static unsigned long func_bound_ind;
+#endif
+
+/* XXX: make it faster ? */
+ST_FUNC void g(int c)
+{
+    int ind1;
+    if (nocode_wanted)
+        return;
+    ind1 = ind + 1;
+    if (ind1 > cur_text_section->data_allocated)
+        section_realloc(cur_text_section, ind1);
+    cur_text_section->data[ind] = c;
+    ind = ind1;
+}
+
+ST_FUNC void o(unsigned int c)
+{
+    while (c) {
+        g(c);
+        c = c >> 8;
+    }
+}
+
+ST_FUNC void gen_le16(int v)
+{
+    g(v);
+    g(v >> 8);
+}
+
+ST_FUNC void gen_le32(int c)
+{
+    g(c);
+    g(c >> 8);
+    g(c >> 16);
+    g(c >> 24);
+}
+
+/* output a symbol and patch all calls to it */
+ST_FUNC void gsym_addr(int t, int a)
+{
+    while (t) {
+        unsigned char *ptr = cur_text_section->data + t;
+        uint32_t n = read32le(ptr); /* next value */
+        write32le(ptr, a - t - 4);
+        t = n;
+    }
+}
+
+ST_FUNC void gsym(int t)
+{
+    gsym_addr(t, ind);
+}
+
+/* instruction + 4 bytes data. Return the address of the data */
+static int oad(int c, int s)
+{
+    int t;
+    if (nocode_wanted)
+        return s;
+    o(c);
+    t = ind;
+    gen_le32(s);
+    return t;
+}
+
+/* generate jmp to a label */
+#define gjmp2(instr,lbl) oad(instr,lbl)
+
+/* output constant with relocation if 'r & VT_SYM' is true */
+ST_FUNC void gen_addr32(int r, Sym *sym, int c)
+{
+    if (r & VT_SYM)
+        greloc(cur_text_section, sym, ind, R_386_32);
+    gen_le32(c);
+}
+
+ST_FUNC void gen_addrpc32(int r, Sym *sym, int c)
+{
+    if (r & VT_SYM)
+        greloc(cur_text_section, sym, ind, R_386_PC32);
+    gen_le32(c - 4);
+}
+
+/* generate a modrm reference. 'op_reg' contains the additional 3
+   opcode bits */
+static void gen_modrm(int op_reg, int r, Sym *sym, int c)
+{
+    op_reg = op_reg << 3;
+    if ((r & VT_VALMASK) == VT_CONST) {
+        /* constant memory reference */
+        o(0x05 | op_reg);
+        gen_addr32(r, sym, c);
+    } else if ((r & VT_VALMASK) == VT_LOCAL) {
+        /* currently, we use only ebp as base */
+        if (c == (char)c) {
+            /* short reference */
+            o(0x45 | op_reg);
+            g(c);
+        } else {
+            oad(0x85 | op_reg, c);
+        }
+    } else {
+        g(0x00 | op_reg | (r & VT_VALMASK));
+    }
+}
+
+/* load 'r' from value 'sv' */
+ST_FUNC void load(int r, SValue *sv)
+{
+    int v, t, ft, fc, fr;
+    SValue v1;
+
+#ifdef TCC_TARGET_PE
+    SValue v2;
+    sv = pe_getimport(sv, &v2);
+#endif
+
+    fr = sv->r;
+    ft = sv->type.t & ~VT_DEFSIGN;
+    fc = sv->c.i;
+
+    ft &= ~(VT_VOLATILE | VT_CONSTANT);
+
+    v = fr & VT_VALMASK;
+    if (fr & VT_LVAL) {
+        if (v == VT_LLOCAL) {
+            v1.type.t = VT_INT;
+            v1.r = VT_LOCAL | VT_LVAL;
+            v1.c.i = fc;
+            fr = r;
+            if (!(reg_classes[fr] & RC_INT))
+                fr = get_reg(RC_INT);
+            load(fr, &v1);
+        }
+        if ((ft & VT_BTYPE) == VT_FLOAT) {
+            o(0xd9); /* flds */
+            r = 0;
+        } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
+            o(0xdd); /* fldl */
+            r = 0;
+        } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
+            o(0xdb); /* fldt */
+            r = 5;
+        } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) {
+            o(0xbe0f);   /* movsbl */
+        } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
+            o(0xb60f);   /* movzbl */
+        } else if ((ft & VT_TYPE) == VT_SHORT) {
+            o(0xbf0f);   /* movswl */
+        } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {
+            o(0xb70f);   /* movzwl */
+        } else {
+            o(0x8b);     /* movl */
+        }
+        gen_modrm(r, fr, sv->sym, fc);
+    } else {
+        if (v == VT_CONST) {
+            o(0xb8 + r); /* mov $xx, r */
+            gen_addr32(fr, sv->sym, fc);
+        } else if (v == VT_LOCAL) {
+            if (fc) {
+                o(0x8d); /* lea xxx(%ebp), r */
+                gen_modrm(r, VT_LOCAL, sv->sym, fc);
+            } else {
+                o(0x89);
+                o(0xe8 + r); /* mov %ebp, r */
+            }
+        } else if (v == VT_CMP) {
+            oad(0xb8 + r, 0); /* mov $0, r */
+            o(0x0f); /* setxx %br */
+            o(fc);
+            o(0xc0 + r);
+        } else if (v == VT_JMP || v == VT_JMPI) {
+            t = v & 1;
+            oad(0xb8 + r, t); /* mov $1, r */
+            o(0x05eb); /* jmp after */
+            gsym(fc);
+            oad(0xb8 + r, t ^ 1); /* mov $0, r */
+        } else if (v != r) {
+            o(0x89);
+            o(0xc0 + r + v * 8); /* mov v, r */
+        }
+    }
+}
+
+/* store register 'r' in lvalue 'v' */
+ST_FUNC void store(int r, SValue *v)
+{
+    int fr, bt, ft, fc;
+
+#ifdef TCC_TARGET_PE
+    SValue v2;
+    v = pe_getimport(v, &v2);
+#endif
+
+    ft = v->type.t;
+    fc = v->c.i;
+    fr = v->r & VT_VALMASK;
+    ft &= ~(VT_VOLATILE | VT_CONSTANT);
+    bt = ft & VT_BTYPE;
+    /* XXX: incorrect if float reg to reg */
+    if (bt == VT_FLOAT) {
+        o(0xd9); /* fsts */
+        r = 2;
+    } else if (bt == VT_DOUBLE) {
+        o(0xdd); /* fstpl */
+        r = 2;
+    } else if (bt == VT_LDOUBLE) {
+        o(0xc0d9); /* fld %st(0) */
+        o(0xdb); /* fstpt */
+        r = 7;
+    } else {
+        if (bt == VT_SHORT)
+            o(0x66);
+        if (bt == VT_BYTE || bt == VT_BOOL)
+            o(0x88);
+        else
+            o(0x89);
+    }
+    if (fr == VT_CONST ||
+        fr == VT_LOCAL ||
+        (v->r & VT_LVAL)) {
+        gen_modrm(r, v->r, v->sym, fc);
+    } else if (fr != r) {
+        o(0xc0 + fr + r * 8); /* mov r, fr */
+    }
+}
+
+static void gadd_sp(int val)
+{
+    if (val == (char)val) {
+        o(0xc483);
+        g(val);
+    } else {
+        oad(0xc481, val); /* add $xxx, %esp */
+    }
+}
+
+#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_PE
+static void gen_static_call(int v)
+{
+    Sym *sym;
+
+    sym = external_global_sym(v, &func_old_type, 0);
+    oad(0xe8, -4);
+    greloc(cur_text_section, sym, ind-4, R_386_PC32);
+}
+#endif
+
+/* 'is_jmp' is '1' if it is a jump */
+static void gcall_or_jmp(int is_jmp)
+{
+    int r;
+    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) {
+        /* constant and relocation case */
+        greloc(cur_text_section, vtop->sym, ind + 1, R_386_PC32);
+        oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */
+    } else {
+        /* otherwise, indirect call */
+        r = gv(RC_INT);
+        o(0xff); /* call/jmp *r */
+        o(0xd0 + r + (is_jmp << 4));
+    }
+    if (!is_jmp) {
+        int rt;
+        /* extend the return value to the whole register if necessary
+           visual studio and gcc do not always set the whole eax register
+           when assigning the return value of a function  */
+        rt = vtop->type.ref->type.t;
+        switch (rt & VT_BTYPE) {
+            case VT_BYTE:
+                if (rt & VT_UNSIGNED) {
+                    o(0xc0b60f); /* movzx %al, %eax */
+                }
+                else {
+                    o(0xc0be0f); /* movsx %al, %eax */
+                }
+                break;
+            case VT_SHORT:
+                if (rt & VT_UNSIGNED) {
+                    o(0xc0b70f); /* movzx %ax, %eax */
+                }
+                else {
+                    o(0xc0bf0f); /* movsx %ax, %eax */
+                }
+                break;
+            default:
+                break;
+        }
+    }
+}
+
+static uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX };
+static uint8_t fastcallw_regs[2] = { TREG_ECX, TREG_EDX };
+
+/* Return the number of registers needed to return the struct, or 0 if
+   returning via struct pointer. */
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize)
+{
+#ifdef TCC_TARGET_PE
+    int size, align;
+    *ret_align = 1; // Never have to re-align return values for x86
+    *regsize = 4;
+    size = type_size(vt, &align);
+    if (size > 8 || (size & (size - 1)))
+        return 0;
+    if (size == 8)
+        ret->t = VT_LLONG;
+    else if (size == 4)
+        ret->t = VT_INT;
+    else if (size == 2)
+        ret->t = VT_SHORT;
+    else
+        ret->t = VT_BYTE;
+    ret->ref = NULL;
+    return 1;
+#else
+    *ret_align = 1; // Never have to re-align return values for x86
+    return 0;
+#endif
+}
+
+/* Generate function call. The function address is pushed first, then
+   all the parameters in call order. This functions pops all the
+   parameters and the function address. */
+ST_FUNC void gfunc_call(int nb_args)
+{
+    int size, align, r, args_size, i, func_call;
+    Sym *func_sym;
+    
+    args_size = 0;
+    for(i = 0;i < nb_args; i++) {
+        if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
+            size = type_size(&vtop->type, &align);
+            /* align to stack align size */
+            size = (size + 3) & ~3;
+            /* allocate the necessary size on stack */
+            oad(0xec81, size); /* sub $xxx, %esp */
+            /* generate structure store */
+            r = get_reg(RC_INT);
+            o(0x89); /* mov %esp, r */
+            o(0xe0 + r);
+            vset(&vtop->type, r | VT_LVAL, 0);
+            vswap();
+            vstore();
+            args_size += size;
+        } else if (is_float(vtop->type.t)) {
+            gv(RC_FLOAT); /* only one float register */
+            if ((vtop->type.t & VT_BTYPE) == VT_FLOAT)
+                size = 4;
+            else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
+                size = 8;
+            else
+                size = 12;
+            oad(0xec81, size); /* sub $xxx, %esp */
+            if (size == 12)
+                o(0x7cdb);
+            else
+                o(0x5cd9 + size - 4); /* fstp[s|l] 0(%esp) */
+            g(0x24);
+            g(0x00);
+            args_size += size;
+        } else {
+            /* simple type (currently always same size) */
+            /* XXX: implicit cast ? */
+            r = gv(RC_INT);
+            if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
+                size = 8;
+                o(0x50 + vtop->r2); /* push r */
+            } else {
+                size = 4;
+            }
+            o(0x50 + r); /* push r */
+            args_size += size;
+        }
+        vtop--;
+    }
+    save_regs(0); /* save used temporary registers */
+    func_sym = vtop->type.ref;
+    func_call = func_sym->f.func_call;
+    /* fast call case */
+    if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
+        func_call == FUNC_FASTCALLW) {
+        int fastcall_nb_regs;
+        uint8_t *fastcall_regs_ptr;
+        if (func_call == FUNC_FASTCALLW) {
+            fastcall_regs_ptr = fastcallw_regs;
+            fastcall_nb_regs = 2;
+        } else {
+            fastcall_regs_ptr = fastcall_regs;
+            fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
+        }
+        for(i = 0;i < fastcall_nb_regs; i++) {
+            if (args_size <= 0)
+                break;
+            o(0x58 + fastcall_regs_ptr[i]); /* pop r */
+            /* XXX: incorrect for struct/floats */
+            args_size -= 4;
+        }
+    }
+#ifndef TCC_TARGET_PE
+    else if ((vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT)
+        args_size -= 4;
+#endif
+    gcall_or_jmp(0);
+
+    if (args_size && func_call != FUNC_STDCALL && func_call != FUNC_FASTCALLW)
+        gadd_sp(args_size);
+    vtop--;
+}
+
+#ifdef TCC_TARGET_PE
+#define FUNC_PROLOG_SIZE (10 + USE_EBX)
+#else
+#define FUNC_PROLOG_SIZE (9 + USE_EBX)
+#endif
+
+/* generate function prolog of type 't' */
+ST_FUNC void gfunc_prolog(CType *func_type)
+{
+    int addr, align, size, func_call, fastcall_nb_regs;
+    int param_index, param_addr;
+    uint8_t *fastcall_regs_ptr;
+    Sym *sym;
+    CType *type;
+
+    sym = func_type->ref;
+    func_call = sym->f.func_call;
+    addr = 8;
+    loc = 0;
+    func_vc = 0;
+
+    if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
+        fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
+        fastcall_regs_ptr = fastcall_regs;
+    } else if (func_call == FUNC_FASTCALLW) {
+        fastcall_nb_regs = 2;
+        fastcall_regs_ptr = fastcallw_regs;
+    } else {
+        fastcall_nb_regs = 0;
+        fastcall_regs_ptr = NULL;
+    }
+    param_index = 0;
+
+    ind += FUNC_PROLOG_SIZE;
+    func_sub_sp_offset = ind;
+    /* if the function returns a structure, then add an
+       implicit pointer parameter */
+    func_vt = sym->type;
+    func_var = (sym->f.func_type == FUNC_ELLIPSIS);
+#ifdef TCC_TARGET_PE
+    size = type_size(&func_vt,&align);
+    if (((func_vt.t & VT_BTYPE) == VT_STRUCT)
+        && (size > 8 || (size & (size - 1)))) {
+#else
+    if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
+#endif
+        /* XXX: fastcall case ? */
+        func_vc = addr;
+        addr += 4;
+        param_index++;
+    }
+    /* define parameters */
+    while ((sym = sym->next) != NULL) {
+        type = &sym->type;
+        size = type_size(type, &align);
+        size = (size + 3) & ~3;
+#ifdef FUNC_STRUCT_PARAM_AS_PTR
+        /* structs are passed as pointer */
+        if ((type->t & VT_BTYPE) == VT_STRUCT) {
+            size = 4;
+        }
+#endif
+        if (param_index < fastcall_nb_regs) {
+            /* save FASTCALL register */
+            loc -= 4;
+            o(0x89);     /* movl */
+            gen_modrm(fastcall_regs_ptr[param_index], VT_LOCAL, NULL, loc);
+            param_addr = loc;
+        } else {
+            param_addr = addr;
+            addr += size;
+        }
+        sym_push(sym->v & ~SYM_FIELD, type,
+                 VT_LOCAL | lvalue_type(type->t), param_addr);
+        param_index++;
+    }
+    func_ret_sub = 0;
+    /* pascal type call or fastcall ? */
+    if (func_call == FUNC_STDCALL || func_call == FUNC_FASTCALLW)
+        func_ret_sub = addr - 8;
+#ifndef TCC_TARGET_PE
+    else if (func_vc)
+        func_ret_sub = 4;
+#endif
+
+#ifdef CONFIG_TCC_BCHECK
+    /* leave some room for bound checking code */
+    if (tcc_state->do_bounds_check) {
+        func_bound_offset = lbounds_section->data_offset;
+        func_bound_ind = ind;
+        oad(0xb8, 0); /* lbound section pointer */
+        oad(0xb8, 0); /* call to function */
+    }
+#endif
+}
+
+/* generate function epilog */
+ST_FUNC void gfunc_epilog(void)
+{
+    addr_t v, saved_ind;
+
+#ifdef CONFIG_TCC_BCHECK
+    if (tcc_state->do_bounds_check
+     && func_bound_offset != lbounds_section->data_offset) {
+        addr_t saved_ind;
+        addr_t *bounds_ptr;
+        Sym *sym_data;
+
+        /* add end of table info */
+        bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
+        *bounds_ptr = 0;
+
+        /* generate bound local allocation */
+        saved_ind = ind;
+        ind = func_bound_ind;
+        sym_data = get_sym_ref(&char_pointer_type, lbounds_section, 
+                               func_bound_offset, lbounds_section->data_offset);
+        greloc(cur_text_section, sym_data,
+               ind + 1, R_386_32);
+        oad(0xb8, 0); /* mov %eax, xxx */
+        gen_static_call(TOK___bound_local_new);
+        ind = saved_ind;
+
+        /* generate bound check local freeing */
+        o(0x5250); /* save returned value, if any */
+        greloc(cur_text_section, sym_data, ind + 1, R_386_32);
+        oad(0xb8, 0); /* mov %eax, xxx */
+        gen_static_call(TOK___bound_local_delete);
+        o(0x585a); /* restore returned value, if any */
+    }
+#endif
+
+    /* align local size to word & save local variables */
+    v = (-loc + 3) & -4;
+
+#if USE_EBX
+    o(0x8b);
+    gen_modrm(TREG_EBX, VT_LOCAL, NULL, -(v+4));
+#endif
+
+    o(0xc9); /* leave */
+    if (func_ret_sub == 0) {
+        o(0xc3); /* ret */
+    } else {
+        o(0xc2); /* ret n */
+        g(func_ret_sub);
+        g(func_ret_sub >> 8);
+    }
+    saved_ind = ind;
+    ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
+#ifdef TCC_TARGET_PE
+    if (v >= 4096) {
+        oad(0xb8, v); /* mov stacksize, %eax */
+        gen_static_call(TOK___chkstk); /* call __chkstk, (does the stackframe too) */
+    } else
+#endif
+    {
+        o(0xe58955);  /* push %ebp, mov %esp, %ebp */
+        o(0xec81);  /* sub esp, stacksize */
+        gen_le32(v);
+#ifdef TCC_TARGET_PE
+        o(0x90);  /* adjust to FUNC_PROLOG_SIZE */
+#endif
+    }
+    o(0x53 * USE_EBX); /* push ebx */
+    ind = saved_ind;
+}
+
+/* generate a jump to a label */
+ST_FUNC int gjmp(int t)
+{
+    return gjmp2(0xe9, t);
+}
+
+/* generate a jump to a fixed address */
+ST_FUNC void gjmp_addr(int a)
+{
+    int r;
+    r = a - ind - 2;
+    if (r == (char)r) {
+        g(0xeb);
+        g(r);
+    } else {
+        oad(0xe9, a - ind - 5);
+    }
+}
+
+ST_FUNC void gtst_addr(int inv, int a)
+{
+    int v = vtop->r & VT_VALMASK;
+    if (v == VT_CMP) {
+	inv ^= (vtop--)->c.i;
+	a -= ind + 2;
+	if (a == (char)a) {
+	    g(inv - 32);
+	    g(a);
+	} else {
+	    g(0x0f);
+	    oad(inv - 16, a - 4);
+	}
+    } else if ((v & ~1) == VT_JMP) {
+	if ((v & 1) != inv) {
+	    gjmp_addr(a);
+	    gsym(vtop->c.i);
+	} else {
+	    gsym(vtop->c.i);
+	    o(0x05eb);
+	    gjmp_addr(a);
+	}
+	vtop--;
+    }
+}
+
+/* generate a test. set 'inv' to invert test. Stack entry is popped */
+ST_FUNC int gtst(int inv, int t)
+{
+    int v = vtop->r & VT_VALMASK;
+    if (nocode_wanted) {
+        ;
+    } else if (v == VT_CMP) {
+        /* fast case : can jump directly since flags are set */
+        g(0x0f);
+        t = gjmp2((vtop->c.i - 16) ^ inv, t);
+    } else if (v == VT_JMP || v == VT_JMPI) {
+        /* && or || optimization */
+        if ((v & 1) == inv) {
+            /* insert vtop->c jump list in t */
+            uint32_t n1, n = vtop->c.i;
+            if (n) {
+                while ((n1 = read32le(cur_text_section->data + n)))
+                    n = n1;
+                write32le(cur_text_section->data + n, t);
+                t = vtop->c.i;
+            }
+        } else {
+            t = gjmp(t);
+            gsym(vtop->c.i);
+        }
+    }
+    vtop--;
+    return t;
+}
+
+/* generate an integer binary operation */
+ST_FUNC void gen_opi(int op)
+{
+    int r, fr, opc, c;
+
+    switch(op) {
+    case '+':
+    case TOK_ADDC1: /* add with carry generation */
+        opc = 0;
+    gen_op8:
+        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+            /* constant case */
+            vswap();
+            r = gv(RC_INT);
+            vswap();
+            c = vtop->c.i;
+            if (c == (char)c) {
+                /* generate inc and dec for smaller code */
+                if (c==1 && opc==0 && op != TOK_ADDC1) {
+                    o (0x40 | r); // inc
+                } else if (c==1 && opc==5 && op != TOK_SUBC1) {
+                    o (0x48 | r); // dec
+                } else {
+                    o(0x83);
+                    o(0xc0 | (opc << 3) | r);
+                    g(c);
+                }
+            } else {
+                o(0x81);
+                oad(0xc0 | (opc << 3) | r, c);
+            }
+        } else {
+            gv2(RC_INT, RC_INT);
+            r = vtop[-1].r;
+            fr = vtop[0].r;
+            o((opc << 3) | 0x01);
+            o(0xc0 + r + fr * 8); 
+        }
+        vtop--;
+        if (op >= TOK_ULT && op <= TOK_GT) {
+            vtop->r = VT_CMP;
+            vtop->c.i = op;
+        }
+        break;
+    case '-':
+    case TOK_SUBC1: /* sub with carry generation */
+        opc = 5;
+        goto gen_op8;
+    case TOK_ADDC2: /* add with carry use */
+        opc = 2;
+        goto gen_op8;
+    case TOK_SUBC2: /* sub with carry use */
+        opc = 3;
+        goto gen_op8;
+    case '&':
+        opc = 4;
+        goto gen_op8;
+    case '^':
+        opc = 6;
+        goto gen_op8;
+    case '|':
+        opc = 1;
+        goto gen_op8;
+    case '*':
+        gv2(RC_INT, RC_INT);
+        r = vtop[-1].r;
+        fr = vtop[0].r;
+        vtop--;
+        o(0xaf0f); /* imul fr, r */
+        o(0xc0 + fr + r * 8);
+        break;
+    case TOK_SHL:
+        opc = 4;
+        goto gen_shift;
+    case TOK_SHR:
+        opc = 5;
+        goto gen_shift;
+    case TOK_SAR:
+        opc = 7;
+    gen_shift:
+        opc = 0xc0 | (opc << 3);
+        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+            /* constant case */
+            vswap();
+            r = gv(RC_INT);
+            vswap();
+            c = vtop->c.i & 0x1f;
+            o(0xc1); /* shl/shr/sar $xxx, r */
+            o(opc | r);
+            g(c);
+        } else {
+            /* we generate the shift in ecx */
+            gv2(RC_INT, RC_ECX);
+            r = vtop[-1].r;
+            o(0xd3); /* shl/shr/sar %cl, r */
+            o(opc | r);
+        }
+        vtop--;
+        break;
+    case '/':
+    case TOK_UDIV:
+    case TOK_PDIV:
+    case '%':
+    case TOK_UMOD:
+    case TOK_UMULL:
+        /* first operand must be in eax */
+        /* XXX: need better constraint for second operand */
+        gv2(RC_EAX, RC_ECX);
+        r = vtop[-1].r;
+        fr = vtop[0].r;
+        vtop--;
+        save_reg(TREG_EDX);
+        /* save EAX too if used otherwise */
+        save_reg_upstack(TREG_EAX, 1);
+        if (op == TOK_UMULL) {
+            o(0xf7); /* mul fr */
+            o(0xe0 + fr);
+            vtop->r2 = TREG_EDX;
+            r = TREG_EAX;
+        } else {
+            if (op == TOK_UDIV || op == TOK_UMOD) {
+                o(0xf7d231); /* xor %edx, %edx, div fr, %eax */
+                o(0xf0 + fr);
+            } else {
+                o(0xf799); /* cltd, idiv fr, %eax */
+                o(0xf8 + fr);
+            }
+            if (op == '%' || op == TOK_UMOD)
+                r = TREG_EDX;
+            else
+                r = TREG_EAX;
+        }
+        vtop->r = r;
+        break;
+    default:
+        opc = 7;
+        goto gen_op8;
+    }
+}
+
+/* generate a floating point operation 'v = t1 op t2' instruction. The
+   two operands are guaranteed to have the same floating point type */
+/* XXX: need to use ST1 too */
+ST_FUNC void gen_opf(int op)
+{
+    int a, ft, fc, swapped, r;
+
+    /* convert constants to memory references */
+    if ((vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+        vswap();
+        gv(RC_FLOAT);
+        vswap();
+    }
+    if ((vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
+        gv(RC_FLOAT);
+
+    /* must put at least one value in the floating point register */
+    if ((vtop[-1].r & VT_LVAL) &&
+        (vtop[0].r & VT_LVAL)) {
+        vswap();
+        gv(RC_FLOAT);
+        vswap();
+    }
+    swapped = 0;
+    /* swap the stack if needed so that t1 is the register and t2 is
+       the memory reference */
+    if (vtop[-1].r & VT_LVAL) {
+        vswap();
+        swapped = 1;
+    }
+    if (op >= TOK_ULT && op <= TOK_GT) {
+        /* load on stack second operand */
+        load(TREG_ST0, vtop);
+        save_reg(TREG_EAX); /* eax is used by FP comparison code */
+        if (op == TOK_GE || op == TOK_GT)
+            swapped = !swapped;
+        else if (op == TOK_EQ || op == TOK_NE)
+            swapped = 0;
+        if (swapped)
+            o(0xc9d9); /* fxch %st(1) */
+        if (op == TOK_EQ || op == TOK_NE)
+            o(0xe9da); /* fucompp */
+        else
+            o(0xd9de); /* fcompp */
+        o(0xe0df); /* fnstsw %ax */
+        if (op == TOK_EQ) {
+            o(0x45e480); /* and $0x45, %ah */
+            o(0x40fC80); /* cmp $0x40, %ah */
+        } else if (op == TOK_NE) {
+            o(0x45e480); /* and $0x45, %ah */
+            o(0x40f480); /* xor $0x40, %ah */
+            op = TOK_NE;
+        } else if (op == TOK_GE || op == TOK_LE) {
+            o(0x05c4f6); /* test $0x05, %ah */
+            op = TOK_EQ;
+        } else {
+            o(0x45c4f6); /* test $0x45, %ah */
+            op = TOK_EQ;
+        }
+        vtop--;
+        vtop->r = VT_CMP;
+        vtop->c.i = op;
+    } else {
+        /* no memory reference possible for long double operations */
+        if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
+            load(TREG_ST0, vtop);
+            swapped = !swapped;
+        }
+        
+        switch(op) {
+        default:
+        case '+':
+            a = 0;
+            break;
+        case '-':
+            a = 4;
+            if (swapped)
+                a++;
+            break;
+        case '*':
+            a = 1;
+            break;
+        case '/':
+            a = 6;
+            if (swapped)
+                a++;
+            break;
+        }
+        ft = vtop->type.t;
+        fc = vtop->c.i;
+        if ((ft & VT_BTYPE) == VT_LDOUBLE) {
+            o(0xde); /* fxxxp %st, %st(1) */
+            o(0xc1 + (a << 3));
+        } else {
+            /* if saved lvalue, then we must reload it */
+            r = vtop->r;
+            if ((r & VT_VALMASK) == VT_LLOCAL) {
+                SValue v1;
+                r = get_reg(RC_INT);
+                v1.type.t = VT_INT;
+                v1.r = VT_LOCAL | VT_LVAL;
+                v1.c.i = fc;
+                load(r, &v1);
+                fc = 0;
+            }
+
+            if ((ft & VT_BTYPE) == VT_DOUBLE)
+                o(0xdc);
+            else
+                o(0xd8);
+            gen_modrm(a, r, vtop->sym, fc);
+        }
+        vtop--;
+    }
+}
+
+/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
+   and 'long long' cases. */
+ST_FUNC void gen_cvt_itof(int t)
+{
+    save_reg(TREG_ST0);
+    gv(RC_INT);
+    if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
+        /* signed long long to float/double/long double (unsigned case
+           is handled generically) */
+        o(0x50 + vtop->r2); /* push r2 */
+        o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
+        o(0x242cdf); /* fildll (%esp) */
+        o(0x08c483); /* add $8, %esp */
+    } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == 
+               (VT_INT | VT_UNSIGNED)) {
+        /* unsigned int to float/double/long double */
+        o(0x6a); /* push $0 */
+        g(0x00);
+        o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
+        o(0x242cdf); /* fildll (%esp) */
+        o(0x08c483); /* add $8, %esp */
+    } else {
+        /* int to float/double/long double */
+        o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
+        o(0x2404db); /* fildl (%esp) */
+        o(0x04c483); /* add $4, %esp */
+    }
+    vtop->r = TREG_ST0;
+}
+
+/* convert fp to int 't' type */
+ST_FUNC void gen_cvt_ftoi(int t)
+{
+    int bt = vtop->type.t & VT_BTYPE;
+    if (bt == VT_FLOAT)
+        vpush_global_sym(&func_old_type, TOK___fixsfdi);
+    else if (bt == VT_LDOUBLE)
+        vpush_global_sym(&func_old_type, TOK___fixxfdi);
+    else
+        vpush_global_sym(&func_old_type, TOK___fixdfdi);
+    vswap();
+    gfunc_call(1);
+    vpushi(0);
+    vtop->r = REG_IRET;
+    vtop->r2 = REG_LRET;
+}
+
+/* convert from one floating point type to another */
+ST_FUNC void gen_cvt_ftof(int t)
+{
+    /* all we have to do on i386 is to put the float in a register */
+    gv(RC_FLOAT);
+}
+
+/* computed goto support */
+ST_FUNC void ggoto(void)
+{
+    gcall_or_jmp(1);
+    vtop--;
+}
+
+/* bound check support functions */
+#ifdef CONFIG_TCC_BCHECK
+
+/* generate a bounded pointer addition */
+ST_FUNC void gen_bounded_ptr_add(void)
+{
+    /* prepare fast i386 function call (args in eax and edx) */
+    gv2(RC_EAX, RC_EDX);
+    /* save all temporary registers */
+    vtop -= 2;
+    save_regs(0);
+    /* do a fast function call */
+    gen_static_call(TOK___bound_ptr_add);
+    /* returned pointer is in eax */
+    vtop++;
+    vtop->r = TREG_EAX | VT_BOUNDED;
+    /* address of bounding function call point */
+    vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel));
+}
+
+/* patch pointer addition in vtop so that pointer dereferencing is
+   also tested */
+ST_FUNC void gen_bounded_ptr_deref(void)
+{
+    addr_t func;
+    int  size, align;
+    Elf32_Rel *rel;
+    Sym *sym;
+
+    size = 0;
+    /* XXX: put that code in generic part of tcc */
+    if (!is_float(vtop->type.t)) {
+        if (vtop->r & VT_LVAL_BYTE)
+            size = 1;
+        else if (vtop->r & VT_LVAL_SHORT)
+            size = 2;
+    }
+    if (!size)
+        size = type_size(&vtop->type, &align);
+    switch(size) {
+    case  1: func = TOK___bound_ptr_indir1; break;
+    case  2: func = TOK___bound_ptr_indir2; break;
+    case  4: func = TOK___bound_ptr_indir4; break;
+    case  8: func = TOK___bound_ptr_indir8; break;
+    case 12: func = TOK___bound_ptr_indir12; break;
+    case 16: func = TOK___bound_ptr_indir16; break;
+    default:
+        tcc_error("unhandled size when dereferencing bounded pointer");
+        func = 0;
+        break;
+    }
+
+    /* patch relocation */
+    /* XXX: find a better solution ? */
+    rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.i);
+    sym = external_global_sym(func, &func_old_type, 0);
+    if (!sym->c)
+        put_extern_sym(sym, NULL, 0, 0);
+    rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info));
+}
+#endif
+
+/* Save the stack pointer onto the stack */
+ST_FUNC void gen_vla_sp_save(int addr) {
+    /* mov %esp,addr(%ebp)*/
+    o(0x89);
+    gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr);
+}
+
+/* Restore the SP from a location on the stack */
+ST_FUNC void gen_vla_sp_restore(int addr) {
+    o(0x8b);
+    gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr);
+}
+
+/* Subtract from the stack pointer, and push the resulting value onto the stack */
+ST_FUNC void gen_vla_alloc(CType *type, int align) {
+#ifdef TCC_TARGET_PE
+    /* alloca does more than just adjust %rsp on Windows */
+    vpush_global_sym(&func_old_type, TOK_alloca);
+    vswap(); /* Move alloca ref past allocation size */
+    gfunc_call(1);
+#else
+    int r;
+    r = gv(RC_INT); /* allocation size */
+    /* sub r,%rsp */
+    o(0x2b);
+    o(0xe0 | r);
+    /* We align to 16 bytes rather than align */
+    /* and ~15, %esp */
+    o(0xf0e483);
+    vpop();
+#endif
+}
+
+/* end of X86 code generator */
+/*************************************************************/
+#endif
+/*************************************************************/
Index: EcnlProtoTool/trunk/tcc-0.9.27/i386-link.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/i386-link.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/i386-link.c	(revision 331)
@@ -0,0 +1,247 @@
+#ifdef TARGET_DEFS_ONLY
+
+#define EM_TCC_TARGET EM_386
+
+/* relocation type for 32 bit data relocation */
+#define R_DATA_32   R_386_32
+#define R_DATA_PTR  R_386_32
+#define R_JMP_SLOT  R_386_JMP_SLOT
+#define R_GLOB_DAT  R_386_GLOB_DAT
+#define R_COPY      R_386_COPY
+#define R_RELATIVE  R_386_RELATIVE
+
+#define R_NUM       R_386_NUM
+
+#define ELF_START_ADDR 0x08048000
+#define ELF_PAGE_SIZE  0x1000
+
+#define PCRELATIVE_DLLPLT 0
+#define RELOCATE_DLLPLT 0
+
+#else /* !TARGET_DEFS_ONLY */
+
+#include "tcc.h"
+
+/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
+   relocations, returns -1. */
+int code_reloc (int reloc_type)
+{
+    switch (reloc_type) {
+	case R_386_RELATIVE:
+	case R_386_16:
+        case R_386_32:
+	case R_386_GOTPC:
+	case R_386_GOTOFF:
+	case R_386_GOT32:
+	case R_386_GOT32X:
+	case R_386_GLOB_DAT:
+	case R_386_COPY:
+            return 0;
+
+	case R_386_PC16:
+	case R_386_PC32:
+	case R_386_PLT32:
+	case R_386_JMP_SLOT:
+            return 1;
+    }
+
+    tcc_error ("Unknown relocation type: %d", reloc_type);
+    return -1;
+}
+
+/* Returns an enumerator to describe whether and when the relocation needs a
+   GOT and/or PLT entry to be created. See tcc.h for a description of the
+   different values. */
+int gotplt_entry_type (int reloc_type)
+{
+    switch (reloc_type) {
+	case R_386_RELATIVE:
+	case R_386_16:
+	case R_386_GLOB_DAT:
+	case R_386_JMP_SLOT:
+	case R_386_COPY:
+            return NO_GOTPLT_ENTRY;
+
+        case R_386_32:
+	    /* This relocations shouldn't normally need GOT or PLT
+	       slots if it weren't for simplicity in the code generator.
+	       See our caller for comments.  */
+            return AUTO_GOTPLT_ENTRY;
+
+	case R_386_PC16:
+	case R_386_PC32:
+            return AUTO_GOTPLT_ENTRY;
+
+	case R_386_GOTPC:
+	case R_386_GOTOFF:
+            return BUILD_GOT_ONLY;
+
+	case R_386_GOT32:
+	case R_386_GOT32X:
+	case R_386_PLT32:
+            return ALWAYS_GOTPLT_ENTRY;
+    }
+
+    tcc_error ("Unknown relocation type: %d", reloc_type);
+    return -1;
+}
+
+ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
+{
+    Section *plt = s1->plt;
+    uint8_t *p;
+    int modrm;
+    unsigned plt_offset, relofs;
+
+    /* on i386 if we build a DLL, we add a %ebx offset */
+    if (s1->output_type == TCC_OUTPUT_DLL)
+        modrm = 0xa3;
+    else
+        modrm = 0x25;
+
+    /* empty PLT: create PLT0 entry that pushes the library identifier
+       (GOT + PTR_SIZE) and jumps to ld.so resolution routine
+       (GOT + 2 * PTR_SIZE) */
+    if (plt->data_offset == 0) {
+        p = section_ptr_add(plt, 16);
+        p[0] = 0xff; /* pushl got + PTR_SIZE */
+        p[1] = modrm + 0x10;
+        write32le(p + 2, PTR_SIZE);
+        p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
+        p[7] = modrm;
+        write32le(p + 8, PTR_SIZE * 2);
+    }
+    plt_offset = plt->data_offset;
+
+    /* The PLT slot refers to the relocation entry it needs via offset.
+       The reloc entry is created below, so its offset is the current
+       data_offset */
+    relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
+
+    /* Jump to GOT entry where ld.so initially put the address of ip + 4 */
+    p = section_ptr_add(plt, 16);
+    p[0] = 0xff; /* jmp *(got + x) */
+    p[1] = modrm;
+    write32le(p + 2, got_offset);
+    p[6] = 0x68; /* push $xxx */
+    write32le(p + 7, relofs);
+    p[11] = 0xe9; /* jmp plt_start */
+    write32le(p + 12, -(plt->data_offset));
+    return plt_offset;
+}
+
+/* relocate the PLT: compute addresses and offsets in the PLT now that final
+   address for PLT and GOT are known (see fill_program_header) */
+ST_FUNC void relocate_plt(TCCState *s1)
+{
+    uint8_t *p, *p_end;
+
+    if (!s1->plt)
+      return;
+
+    p = s1->plt->data;
+    p_end = p + s1->plt->data_offset;
+
+    if (p < p_end) {
+        add32le(p + 2, s1->got->sh_addr);
+        add32le(p + 8, s1->got->sh_addr);
+        p += 16;
+        while (p < p_end) {
+            add32le(p + 2, s1->got->sh_addr);
+            p += 16;
+        }
+    }
+}
+
+static ElfW_Rel *qrel; /* ptr to next reloc entry reused */
+
+void relocate_init(Section *sr)
+{
+    qrel = (ElfW_Rel *) sr->data;
+}
+
+void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
+{
+    int sym_index, esym_index;
+
+    sym_index = ELFW(R_SYM)(rel->r_info);
+
+    switch (type) {
+        case R_386_32:
+            if (s1->output_type == TCC_OUTPUT_DLL) {
+                esym_index = s1->sym_attrs[sym_index].dyn_index;
+                qrel->r_offset = rel->r_offset;
+                if (esym_index) {
+                    qrel->r_info = ELFW(R_INFO)(esym_index, R_386_32);
+                    qrel++;
+                    return;
+                } else {
+                    qrel->r_info = ELFW(R_INFO)(0, R_386_RELATIVE);
+                    qrel++;
+                }
+            }
+            add32le(ptr, val);
+            return;
+        case R_386_PC32:
+            if (s1->output_type == TCC_OUTPUT_DLL) {
+                /* DLL relocation */
+                esym_index = s1->sym_attrs[sym_index].dyn_index;
+                if (esym_index) {
+                    qrel->r_offset = rel->r_offset;
+                    qrel->r_info = ELFW(R_INFO)(esym_index, R_386_PC32);
+                    qrel++;
+                    return;
+                }
+            }
+            add32le(ptr, val - addr);
+            return;
+        case R_386_PLT32:
+            add32le(ptr, val - addr);
+            return;
+        case R_386_GLOB_DAT:
+        case R_386_JMP_SLOT:
+            write32le(ptr, val);
+            return;
+        case R_386_GOTPC:
+            add32le(ptr, s1->got->sh_addr - addr);
+            return;
+        case R_386_GOTOFF:
+            add32le(ptr, val - s1->got->sh_addr);
+            return;
+        case R_386_GOT32:
+        case R_386_GOT32X:
+            /* we load the got offset */
+            add32le(ptr, s1->sym_attrs[sym_index].got_offset);
+            return;
+        case R_386_16:
+            if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY) {
+            output_file:
+                tcc_error("can only produce 16-bit binary files");
+            }
+            write16le(ptr, read16le(ptr) + val);
+            return;
+        case R_386_PC16:
+            if (s1->output_format != TCC_OUTPUT_FORMAT_BINARY)
+                goto output_file;
+            write16le(ptr, read16le(ptr) + val - addr);
+            return;
+        case R_386_RELATIVE:
+#ifdef TCC_TARGET_PE
+            add32le(ptr, val - s1->pe_imagebase);
+#endif
+            /* do nothing */
+            return;
+        case R_386_COPY:
+            /* This relocation must copy initialized data from the library
+            to the program .bss segment. Currently made like for ARM
+            (to remove noise of default case). Is this true?
+            */
+            return;
+        default:
+            fprintf(stderr,"FIXME: handle reloc type %d at %x [%p] to %x\n",
+                type, (unsigned)addr, ptr, (unsigned)val);
+            return;
+    }
+}
+
+#endif /* !TARGET_DEFS_ONLY */
Index: EcnlProtoTool/trunk/tcc-0.9.27/i386-tok.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/i386-tok.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/i386-tok.h	(revision 331)
@@ -0,0 +1,253 @@
+/* ------------------------------------------------------------------ */
+/* WARNING: relative order of tokens is important. */
+
+/* register */
+ DEF_ASM(al)
+ DEF_ASM(cl)
+ DEF_ASM(dl)
+ DEF_ASM(bl)
+ DEF_ASM(ah)
+ DEF_ASM(ch)
+ DEF_ASM(dh)
+ DEF_ASM(bh)
+ DEF_ASM(ax)
+ DEF_ASM(cx)
+ DEF_ASM(dx)
+ DEF_ASM(bx)
+ DEF_ASM(sp)
+ DEF_ASM(bp)
+ DEF_ASM(si)
+ DEF_ASM(di)
+ DEF_ASM(eax)
+ DEF_ASM(ecx)
+ DEF_ASM(edx)
+ DEF_ASM(ebx)
+ DEF_ASM(esp)
+ DEF_ASM(ebp)
+ DEF_ASM(esi)
+ DEF_ASM(edi)
+#ifdef TCC_TARGET_X86_64
+ DEF_ASM(rax)
+ DEF_ASM(rcx)
+ DEF_ASM(rdx)
+ DEF_ASM(rbx)
+ DEF_ASM(rsp)
+ DEF_ASM(rbp)
+ DEF_ASM(rsi)
+ DEF_ASM(rdi)
+#endif
+ DEF_ASM(mm0)
+ DEF_ASM(mm1)
+ DEF_ASM(mm2)
+ DEF_ASM(mm3)
+ DEF_ASM(mm4)
+ DEF_ASM(mm5)
+ DEF_ASM(mm6)
+ DEF_ASM(mm7)
+ DEF_ASM(xmm0)
+ DEF_ASM(xmm1)
+ DEF_ASM(xmm2)
+ DEF_ASM(xmm3)
+ DEF_ASM(xmm4)
+ DEF_ASM(xmm5)
+ DEF_ASM(xmm6)
+ DEF_ASM(xmm7)
+ DEF_ASM(cr0)
+ DEF_ASM(cr1)
+ DEF_ASM(cr2)
+ DEF_ASM(cr3)
+ DEF_ASM(cr4)
+ DEF_ASM(cr5)
+ DEF_ASM(cr6)
+ DEF_ASM(cr7)
+ DEF_ASM(tr0)
+ DEF_ASM(tr1)
+ DEF_ASM(tr2)
+ DEF_ASM(tr3)
+ DEF_ASM(tr4)
+ DEF_ASM(tr5)
+ DEF_ASM(tr6)
+ DEF_ASM(tr7)
+ DEF_ASM(db0)
+ DEF_ASM(db1)
+ DEF_ASM(db2)
+ DEF_ASM(db3)
+ DEF_ASM(db4)
+ DEF_ASM(db5)
+ DEF_ASM(db6)
+ DEF_ASM(db7)
+ DEF_ASM(dr0)
+ DEF_ASM(dr1)
+ DEF_ASM(dr2)
+ DEF_ASM(dr3)
+ DEF_ASM(dr4)
+ DEF_ASM(dr5)
+ DEF_ASM(dr6)
+ DEF_ASM(dr7)
+ DEF_ASM(es)
+ DEF_ASM(cs)
+ DEF_ASM(ss)
+ DEF_ASM(ds)
+ DEF_ASM(fs)
+ DEF_ASM(gs)
+ DEF_ASM(st)
+ DEF_ASM(rip)
+
+#ifdef TCC_TARGET_X86_64
+ /* The four low parts of sp/bp/si/di that exist only on
+    x86-64 (encoding aliased to ah,ch,dh,dh when not using REX). */
+ DEF_ASM(spl)
+ DEF_ASM(bpl)
+ DEF_ASM(sil)
+ DEF_ASM(dil)
+#endif
+ /* generic two operands */
+ DEF_BWLX(mov)
+
+ DEF_BWLX(add)
+ DEF_BWLX(or)
+ DEF_BWLX(adc)
+ DEF_BWLX(sbb)
+ DEF_BWLX(and)
+ DEF_BWLX(sub)
+ DEF_BWLX(xor)
+ DEF_BWLX(cmp)
+
+ /* unary ops */
+ DEF_BWLX(inc)
+ DEF_BWLX(dec)
+ DEF_BWLX(not)
+ DEF_BWLX(neg)
+ DEF_BWLX(mul)
+ DEF_BWLX(imul)
+ DEF_BWLX(div)
+ DEF_BWLX(idiv)
+
+ DEF_BWLX(xchg)
+ DEF_BWLX(test)
+
+ /* shifts */
+ DEF_BWLX(rol)
+ DEF_BWLX(ror)
+ DEF_BWLX(rcl)
+ DEF_BWLX(rcr)
+ DEF_BWLX(shl)
+ DEF_BWLX(shr)
+ DEF_BWLX(sar)
+
+ DEF_WLX(shld)
+ DEF_WLX(shrd)
+
+ DEF_ASM(pushw)
+ DEF_ASM(pushl)
+#ifdef TCC_TARGET_X86_64
+ DEF_ASM(pushq)
+#endif
+ DEF_ASM(push)
+
+ DEF_ASM(popw)
+ DEF_ASM(popl)
+#ifdef TCC_TARGET_X86_64
+ DEF_ASM(popq)
+#endif
+ DEF_ASM(pop)
+
+ DEF_BWL(in)
+ DEF_BWL(out)
+
+ DEF_WLX(movzb)
+ DEF_ASM(movzwl)
+ DEF_ASM(movsbw)
+ DEF_ASM(movsbl)
+ DEF_ASM(movswl)
+#ifdef TCC_TARGET_X86_64
+ DEF_ASM(movsbq)
+ DEF_ASM(movswq)
+ DEF_ASM(movzwq)
+ DEF_ASM(movslq)
+#endif
+
+ DEF_WLX(lea)
+
+ DEF_ASM(les)
+ DEF_ASM(lds)
+ DEF_ASM(lss)
+ DEF_ASM(lfs)
+ DEF_ASM(lgs)
+
+ DEF_ASM(call)
+ DEF_ASM(jmp)
+ DEF_ASM(lcall)
+ DEF_ASM(ljmp)
+
+ DEF_ASMTEST(j,)
+
+ DEF_ASMTEST(set,)
+ DEF_ASMTEST(set,b)
+ DEF_ASMTEST(cmov,)
+
+ DEF_WLX(bsf)
+ DEF_WLX(bsr)
+ DEF_WLX(bt)
+ DEF_WLX(bts)
+ DEF_WLX(btr)
+ DEF_WLX(btc)
+
+ DEF_WLX(lar)
+ DEF_WLX(lsl)
+
+ /* generic FP ops */
+ DEF_FP(add)
+ DEF_FP(mul)
+
+ DEF_ASM(fcom)
+ DEF_ASM(fcom_1) /* non existent op, just to have a regular table */
+ DEF_FP1(com)
+
+ DEF_FP(comp)
+ DEF_FP(sub)
+ DEF_FP(subr)
+ DEF_FP(div)
+ DEF_FP(divr)
+
+ DEF_BWLX(xadd)
+ DEF_BWLX(cmpxchg)
+
+ /* string ops */
+ DEF_BWLX(cmps)
+ DEF_BWLX(scmp)
+ DEF_BWL(ins)
+ DEF_BWL(outs)
+ DEF_BWLX(lods)
+ DEF_BWLX(slod)
+ DEF_BWLX(movs)
+ DEF_BWLX(smov)
+ DEF_BWLX(scas)
+ DEF_BWLX(ssca)
+ DEF_BWLX(stos)
+ DEF_BWLX(ssto)
+
+ /* generic asm ops */
+#define ALT(x)
+#define DEF_ASM_OP0(name, opcode) DEF_ASM(name)
+#define DEF_ASM_OP0L(name, opcode, group, instr_type)
+#define DEF_ASM_OP1(name, opcode, group, instr_type, op0)
+#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1)
+#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2)
+#ifdef TCC_TARGET_X86_64
+# include "x86_64-asm.h"
+#else
+# include "i386-asm.h"
+#endif
+
+#define ALT(x)
+#define DEF_ASM_OP0(name, opcode)
+#define DEF_ASM_OP0L(name, opcode, group, instr_type) DEF_ASM(name)
+#define DEF_ASM_OP1(name, opcode, group, instr_type, op0) DEF_ASM(name)
+#define DEF_ASM_OP2(name, opcode, group, instr_type, op0, op1) DEF_ASM(name)
+#define DEF_ASM_OP3(name, opcode, group, instr_type, op0, op1, op2) DEF_ASM(name)
+#ifdef TCC_TARGET_X86_64
+# include "x86_64-asm.h"
+#else
+# include "i386-asm.h"
+#endif
Index: EcnlProtoTool/trunk/tcc-0.9.27/il-gen.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/il-gen.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/il-gen.c	(revision 331)
@@ -0,0 +1,657 @@
+/*
+ *  CIL code generator for TCC
+ * 
+ *  Copyright (c) 2002 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#error this code has bit-rotted since 2003
+
+/* number of available registers */
+#define NB_REGS             3
+
+/* a register can belong to several classes. The classes must be
+   sorted from more general to more precise (see gv2() code which does
+   assumptions on it). */
+#define RC_ST      0x0001  /* any stack entry */
+#define RC_ST0     0x0002  /* top of stack */
+#define RC_ST1     0x0004  /* top - 1 */
+
+#define RC_INT     RC_ST
+#define RC_FLOAT   RC_ST
+#define RC_IRET    RC_ST0 /* function return: integer register */
+#define RC_LRET    RC_ST0 /* function return: second integer register */
+#define RC_FRET    RC_ST0 /* function return: float register */
+
+/* pretty names for the registers */
+enum {
+    REG_ST0 = 0,
+    REG_ST1,
+    REG_ST2,
+};
+
+const int reg_classes[NB_REGS] = {
+    /* ST0 */ RC_ST | RC_ST0,
+    /* ST1 */ RC_ST | RC_ST1,
+    /* ST2 */ RC_ST,
+};
+
+/* return registers for function */
+#define REG_IRET REG_ST0 /* single word int return register */
+#define REG_LRET REG_ST0 /* second word return register (for long long) */
+#define REG_FRET REG_ST0 /* float return register */
+
+/* defined if function parameters must be evaluated in reverse order */
+/* #define INVERT_FUNC_PARAMS */
+
+/* defined if structures are passed as pointers. Otherwise structures
+   are directly pushed on stack. */
+/* #define FUNC_STRUCT_PARAM_AS_PTR */
+
+/* pointer size, in bytes */
+#define PTR_SIZE 4
+
+/* long double size and alignment, in bytes */
+#define LDOUBLE_SIZE  8
+#define LDOUBLE_ALIGN 8
+
+/* function call context */
+typedef struct GFuncContext {
+    int func_call; /* func call type (FUNC_STDCALL or FUNC_CDECL) */
+} GFuncContext;
+
+/******************************************************/
+/* opcode definitions */
+
+#define IL_OP_PREFIX 0xFE
+
+enum ILOPCodes {
+#define OP(name, str, n) IL_OP_ ## name = n,
+#include "il-opcodes.h"
+#undef OP
+};
+
+char *il_opcodes_str[] = {
+#define OP(name, str, n) [n] = str,
+#include "il-opcodes.h"
+#undef OP
+};
+
+/******************************************************/
+
+/* arguments variable numbers start from there */
+#define ARG_BASE 0x70000000
+
+static FILE *il_outfile;
+
+static void out_byte(int c)
+{
+    *(char *)ind++ = c;
+}
+
+static void out_le32(int c)
+{
+    out_byte(c);
+    out_byte(c >> 8);
+    out_byte(c >> 16);
+    out_byte(c >> 24);
+}
+
+static void init_outfile(void)
+{
+    if (!il_outfile) {
+        il_outfile = stdout;
+        fprintf(il_outfile, 
+                ".assembly extern mscorlib\n"
+                "{\n"
+                ".ver 1:0:2411:0\n"
+                "}\n\n");
+    }
+}
+
+static void out_op1(int op)
+{
+    if (op & 0x100)
+        out_byte(IL_OP_PREFIX);
+    out_byte(op & 0xff);
+}
+
+/* output an opcode with prefix */
+static void out_op(int op)
+{
+    out_op1(op);
+    fprintf(il_outfile, " %s\n", il_opcodes_str[op]);
+}
+
+static void out_opb(int op, int c)
+{
+    out_op1(op);
+    out_byte(c);
+    fprintf(il_outfile, " %s %d\n", il_opcodes_str[op], c);
+}
+
+static void out_opi(int op, int c)
+{
+    out_op1(op);
+    out_le32(c);
+    fprintf(il_outfile, " %s 0x%x\n", il_opcodes_str[op], c);
+}
+
+/* XXX: not complete */
+static void il_type_to_str(char *buf, int buf_size, 
+                           int t, const char *varstr)
+{
+    int bt;
+    Sym *s, *sa;
+    char buf1[256];
+    const char *tstr;
+
+    t = t & VT_TYPE;
+    bt = t & VT_BTYPE;
+    buf[0] = '\0';
+    if (t & VT_UNSIGNED)
+        pstrcat(buf, buf_size, "unsigned ");
+    switch(bt) {
+    case VT_VOID:
+        tstr = "void";
+        goto add_tstr;
+    case VT_BOOL:
+        tstr = "bool";
+        goto add_tstr;
+    case VT_BYTE:
+        tstr = "int8";
+        goto add_tstr;
+    case VT_SHORT:
+        tstr = "int16";
+        goto add_tstr;
+    case VT_ENUM:
+    case VT_INT:
+    case VT_LONG:
+        tstr = "int32";
+        goto add_tstr;
+    case VT_LLONG:
+        tstr = "int64";
+        goto add_tstr;
+    case VT_FLOAT:
+        tstr = "float32";
+        goto add_tstr;
+    case VT_DOUBLE:
+    case VT_LDOUBLE:
+        tstr = "float64";
+    add_tstr:
+        pstrcat(buf, buf_size, tstr);
+        break;
+    case VT_STRUCT:
+        tcc_error("structures not handled yet");
+        break;
+    case VT_FUNC:
+        s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
+        il_type_to_str(buf, buf_size, s->t, varstr);
+        pstrcat(buf, buf_size, "(");
+        sa = s->next;
+        while (sa != NULL) {
+            il_type_to_str(buf1, sizeof(buf1), sa->t, NULL);
+            pstrcat(buf, buf_size, buf1);
+            sa = sa->next;
+            if (sa)
+                pstrcat(buf, buf_size, ", ");
+        }
+        pstrcat(buf, buf_size, ")");
+        goto no_var;
+    case VT_PTR:
+        s = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
+        pstrcpy(buf1, sizeof(buf1), "*");
+        if (varstr)
+            pstrcat(buf1, sizeof(buf1), varstr);
+        il_type_to_str(buf, buf_size, s->t, buf1);
+        goto no_var;
+    }
+    if (varstr) {
+        pstrcat(buf, buf_size, " ");
+        pstrcat(buf, buf_size, varstr);
+    }
+ no_var: ;
+}
+
+
+/* patch relocation entry with value 'val' */
+void greloc_patch1(Reloc *p, int val)
+{
+}
+
+/* output a symbol and patch all calls to it */
+void gsym_addr(t, a)
+{
+}
+
+/* output jump and return symbol */
+static int out_opj(int op, int c)
+{
+    out_op1(op);
+    out_le32(0);
+    if (c == 0) {
+        c = ind - (int)cur_text_section->data;
+    }
+    fprintf(il_outfile, " %s L%d\n", il_opcodes_str[op], c);
+    return c;
+}
+
+void gsym(int t)
+{
+    fprintf(il_outfile, "L%d:\n", t);
+}
+
+/* load 'r' from value 'sv' */
+void load(int r, SValue *sv)
+{
+    int v, fc, ft;
+
+    v = sv->r & VT_VALMASK;
+    fc = sv->c.i;
+    ft = sv->t;
+
+    if (sv->r & VT_LVAL) {
+        if (v == VT_LOCAL) {
+            if (fc >= ARG_BASE) {
+                fc -= ARG_BASE;
+                if (fc >= 0 && fc <= 4) {
+                    out_op(IL_OP_LDARG_0 + fc);
+                } else if (fc <= 0xff) {
+                    out_opb(IL_OP_LDARG_S, fc);
+                } else {
+                    out_opi(IL_OP_LDARG, fc);
+                }
+            } else {
+                if (fc >= 0 && fc <= 4) {
+                    out_op(IL_OP_LDLOC_0 + fc);
+                } else if (fc <= 0xff) {
+                    out_opb(IL_OP_LDLOC_S, fc);
+                } else {
+                    out_opi(IL_OP_LDLOC, fc);
+                }
+            }
+        } else if (v == VT_CONST) {
+                /* XXX: handle globals */
+                out_opi(IL_OP_LDSFLD, 0);
+        } else {
+            if ((ft & VT_BTYPE) == VT_FLOAT) {
+                out_op(IL_OP_LDIND_R4);
+            } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
+                out_op(IL_OP_LDIND_R8);
+            } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
+                out_op(IL_OP_LDIND_R8);
+            } else if ((ft & VT_TYPE) == VT_BYTE)
+                out_op(IL_OP_LDIND_I1);
+            else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED))
+                out_op(IL_OP_LDIND_U1);
+            else if ((ft & VT_TYPE) == VT_SHORT)
+                out_op(IL_OP_LDIND_I2);
+            else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED))
+                out_op(IL_OP_LDIND_U2);
+            else
+                out_op(IL_OP_LDIND_I4);
+        } 
+    } else {
+        if (v == VT_CONST) {
+            /* XXX: handle globals */
+            if (fc >= -1 && fc <= 8) {
+                out_op(IL_OP_LDC_I4_M1 + fc + 1); 
+            } else {
+                out_opi(IL_OP_LDC_I4, fc);
+            }
+        } else if (v == VT_LOCAL) {
+            if (fc >= ARG_BASE) {
+                fc -= ARG_BASE;
+                if (fc <= 0xff) {
+                    out_opb(IL_OP_LDARGA_S, fc);
+                } else {
+                    out_opi(IL_OP_LDARGA, fc);
+                }
+            } else {
+                if (fc <= 0xff) {
+                    out_opb(IL_OP_LDLOCA_S, fc);
+                } else {
+                    out_opi(IL_OP_LDLOCA, fc);
+                }
+            }
+        } else {
+            /* XXX: do it */
+        }
+    }
+}
+
+/* store register 'r' in lvalue 'v' */
+void store(int r, SValue *sv)
+{
+    int v, fc, ft;
+
+    v = sv->r & VT_VALMASK;
+    fc = sv->c.i;
+    ft = sv->t;
+    if (v == VT_LOCAL) {
+        if (fc >= ARG_BASE) {
+            fc -= ARG_BASE;
+            /* XXX: check IL arg store semantics */
+            if (fc <= 0xff) {
+                out_opb(IL_OP_STARG_S, fc);
+            } else {
+                out_opi(IL_OP_STARG, fc);
+            }
+        } else {
+            if (fc >= 0 && fc <= 4) {
+                out_op(IL_OP_STLOC_0 + fc);
+            } else if (fc <= 0xff) {
+                out_opb(IL_OP_STLOC_S, fc);
+            } else {
+                out_opi(IL_OP_STLOC, fc);
+            }
+        }
+    } else if (v == VT_CONST) {
+        /* XXX: handle globals */
+        out_opi(IL_OP_STSFLD, 0);
+    } else {
+        if ((ft & VT_BTYPE) == VT_FLOAT)
+            out_op(IL_OP_STIND_R4);
+        else if ((ft & VT_BTYPE) == VT_DOUBLE)
+            out_op(IL_OP_STIND_R8);
+        else if ((ft & VT_BTYPE) == VT_LDOUBLE)
+            out_op(IL_OP_STIND_R8);
+        else if ((ft & VT_BTYPE) == VT_BYTE)
+            out_op(IL_OP_STIND_I1);
+        else if ((ft & VT_BTYPE) == VT_SHORT)
+            out_op(IL_OP_STIND_I2);
+        else
+            out_op(IL_OP_STIND_I4);
+    }
+}
+
+/* start function call and return function call context */
+void gfunc_start(GFuncContext *c, int func_call)
+{
+    c->func_call = func_call;
+}
+
+/* push function parameter which is in (vtop->t, vtop->c). Stack entry
+   is then popped. */
+void gfunc_param(GFuncContext *c)
+{
+    if ((vtop->t & VT_BTYPE) == VT_STRUCT) {
+        tcc_error("structures passed as value not handled yet");
+    } else {
+        /* simply push on stack */
+        gv(RC_ST0);
+    }
+    vtop--;
+}
+
+/* generate function call with address in (vtop->t, vtop->c) and free function
+   context. Stack entry is popped */
+void gfunc_call(GFuncContext *c)
+{
+    char buf[1024];
+
+    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+        /* XXX: more info needed from tcc */
+        il_type_to_str(buf, sizeof(buf), vtop->t, "xxx");
+        fprintf(il_outfile, " call %s\n", buf);
+    } else {
+        /* indirect call */
+        gv(RC_INT);
+        il_type_to_str(buf, sizeof(buf), vtop->t, NULL);
+        fprintf(il_outfile, " calli %s\n", buf);
+    }
+    vtop--;
+}
+
+/* generate function prolog of type 't' */
+void gfunc_prolog(int t)
+{
+    int addr, u, func_call;
+    Sym *sym;
+    char buf[1024];
+
+    init_outfile();
+
+    /* XXX: pass function name to gfunc_prolog */
+    il_type_to_str(buf, sizeof(buf), t, funcname);
+    fprintf(il_outfile, ".method static %s il managed\n", buf);
+    fprintf(il_outfile, "{\n");
+    /* XXX: cannot do better now */
+    fprintf(il_outfile, " .maxstack %d\n", NB_REGS);
+    fprintf(il_outfile, " .locals (int32, int32, int32, int32, int32, int32, int32, int32)\n");
+    
+    if (!strcmp(funcname, "main"))
+        fprintf(il_outfile, " .entrypoint\n");
+        
+    sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
+    func_call = sym->r;
+
+    addr = ARG_BASE;
+    /* if the function returns a structure, then add an
+       implicit pointer parameter */
+    func_vt = sym->t;
+    func_var = (sym->c == FUNC_ELLIPSIS);
+    if ((func_vt & VT_BTYPE) == VT_STRUCT) {
+        func_vc = addr;
+        addr++;
+    }
+    /* define parameters */
+    while ((sym = sym->next) != NULL) {
+        u = sym->t;
+        sym_push(sym->v & ~SYM_FIELD, u,
+                 VT_LOCAL | lvalue_type(sym->type.t), addr);
+        addr++;
+    }
+}
+
+/* generate function epilog */
+void gfunc_epilog(void)
+{
+    out_op(IL_OP_RET);
+    fprintf(il_outfile, "}\n\n");
+}
+
+/* generate a jump to a label */
+int gjmp(int t)
+{
+    return out_opj(IL_OP_BR, t);
+}
+
+/* generate a jump to a fixed address */
+void gjmp_addr(int a)
+{
+    /* XXX: handle syms */
+    out_opi(IL_OP_BR, a);
+}
+
+/* generate a test. set 'inv' to invert test. Stack entry is popped */
+int gtst(int inv, int t)
+{
+    int v, *p, c;
+
+    v = vtop->r & VT_VALMASK;
+    if (v == VT_CMP) {
+        c = vtop->c.i ^ inv;
+        switch(c) {
+        case TOK_EQ:
+            c = IL_OP_BEQ;
+            break;
+        case TOK_NE:
+            c = IL_OP_BNE_UN;
+            break;
+        case TOK_LT:
+            c = IL_OP_BLT;
+            break;
+        case TOK_LE:
+            c = IL_OP_BLE;
+            break;
+        case TOK_GT:
+            c = IL_OP_BGT;
+            break;
+        case TOK_GE:
+            c = IL_OP_BGE;
+            break;
+        case TOK_ULT:
+            c = IL_OP_BLT_UN;
+            break;
+        case TOK_ULE:
+            c = IL_OP_BLE_UN;
+            break;
+        case TOK_UGT:
+            c = IL_OP_BGT_UN;
+            break;
+        case TOK_UGE:
+            c = IL_OP_BGE_UN;
+            break;
+        }
+        t = out_opj(c, t);
+    } else if (v == VT_JMP || v == VT_JMPI) {
+        /* && or || optimization */
+        if ((v & 1) == inv) {
+            /* insert vtop->c jump list in t */
+            p = &vtop->c.i;
+            while (*p != 0)
+                p = (int *)*p;
+            *p = t;
+            t = vtop->c.i;
+        } else {
+            t = gjmp(t);
+            gsym(vtop->c.i);
+        }
+    }
+    vtop--;
+    return t;
+}
+
+/* generate an integer binary operation */
+void gen_opi(int op)
+{
+    gv2(RC_ST1, RC_ST0);
+    switch(op) {
+    case '+':
+        out_op(IL_OP_ADD);
+        goto std_op;
+    case '-':
+        out_op(IL_OP_SUB);
+        goto std_op;
+    case '&':
+        out_op(IL_OP_AND);
+        goto std_op;
+    case '^':
+        out_op(IL_OP_XOR);
+        goto std_op;
+    case '|':
+        out_op(IL_OP_OR);
+        goto std_op;
+    case '*':
+        out_op(IL_OP_MUL);
+        goto std_op;
+    case TOK_SHL:
+        out_op(IL_OP_SHL);
+        goto std_op;
+    case TOK_SHR:
+        out_op(IL_OP_SHR_UN);
+        goto std_op;
+    case TOK_SAR:
+        out_op(IL_OP_SHR);
+        goto std_op;
+    case '/':
+    case TOK_PDIV:
+        out_op(IL_OP_DIV);
+        goto std_op;
+    case TOK_UDIV:
+        out_op(IL_OP_DIV_UN);
+        goto std_op;
+    case '%':
+        out_op(IL_OP_REM);
+        goto std_op;
+    case TOK_UMOD:
+        out_op(IL_OP_REM_UN);
+    std_op:
+        vtop--;
+        vtop[0].r = REG_ST0;
+        break;
+    case TOK_EQ:
+    case TOK_NE:
+    case TOK_LT:
+    case TOK_LE:
+    case TOK_GT:
+    case TOK_GE:
+    case TOK_ULT:
+    case TOK_ULE:
+    case TOK_UGT:
+    case TOK_UGE:
+        vtop--;
+        vtop[0].r = VT_CMP;
+        vtop[0].c.i = op;
+        break;
+    }
+}
+
+/* generate a floating point operation 'v = t1 op t2' instruction. The
+   two operands are guaranteed to have the same floating point type */
+void gen_opf(int op)
+{
+    /* same as integer */
+    gen_opi(op);
+}
+
+/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
+   and 'long long' cases. */
+void gen_cvt_itof(int t)
+{
+    gv(RC_ST0);
+    if (t == VT_FLOAT)
+        out_op(IL_OP_CONV_R4);
+    else
+        out_op(IL_OP_CONV_R8);
+}
+
+/* convert fp to int 't' type */
+/* XXX: handle long long case */
+void gen_cvt_ftoi(int t)
+{
+    gv(RC_ST0);
+    switch(t) {
+    case VT_INT | VT_UNSIGNED:
+        out_op(IL_OP_CONV_U4);
+        break;
+    case VT_LLONG:
+        out_op(IL_OP_CONV_I8);
+        break;
+    case VT_LLONG | VT_UNSIGNED:
+        out_op(IL_OP_CONV_U8);
+        break;
+    default:
+        out_op(IL_OP_CONV_I4);
+        break;
+    }
+}
+
+/* convert from one floating point type to another */
+void gen_cvt_ftof(int t)
+{
+    gv(RC_ST0);
+    if (t == VT_FLOAT) {
+        out_op(IL_OP_CONV_R4);
+    } else {
+        out_op(IL_OP_CONV_R8);
+    }
+}
+
+/* end of CIL code generator */
+/*************************************************************/
+
Index: EcnlProtoTool/trunk/tcc-0.9.27/il-opcodes.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/il-opcodes.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/il-opcodes.h	(revision 331)
@@ -0,0 +1,251 @@
+/*
+ *  CIL opcode definition
+ * 
+ *  Copyright (c) 2002 Fabrice Bellard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+OP(NOP, "nop", 0x00)
+OP(BREAK, "break", 0x01)
+OP(LDARG_0, "ldarg.0", 0x02)
+OP(LDARG_1, "ldarg.1", 0x03)
+OP(LDARG_2, "ldarg.2", 0x04)
+OP(LDARG_3, "ldarg.3", 0x05)
+OP(LDLOC_0, "ldloc.0", 0x06)
+OP(LDLOC_1, "ldloc.1", 0x07)
+OP(LDLOC_2, "ldloc.2", 0x08)
+OP(LDLOC_3, "ldloc.3", 0x09)
+OP(STLOC_0, "stloc.0", 0x0a)
+OP(STLOC_1, "stloc.1", 0x0b)
+OP(STLOC_2, "stloc.2", 0x0c)
+OP(STLOC_3, "stloc.3", 0x0d)
+OP(LDARG_S, "ldarg.s", 0x0e)
+OP(LDARGA_S, "ldarga.s", 0x0f)
+OP(STARG_S, "starg.s", 0x10)
+OP(LDLOC_S, "ldloc.s", 0x11)
+OP(LDLOCA_S, "ldloca.s", 0x12)
+OP(STLOC_S, "stloc.s", 0x13)
+OP(LDNULL, "ldnull", 0x14)
+OP(LDC_I4_M1, "ldc.i4.m1", 0x15)
+OP(LDC_I4_0, "ldc.i4.0", 0x16)
+OP(LDC_I4_1, "ldc.i4.1", 0x17)
+OP(LDC_I4_2, "ldc.i4.2", 0x18)
+OP(LDC_I4_3, "ldc.i4.3", 0x19)
+OP(LDC_I4_4, "ldc.i4.4", 0x1a)
+OP(LDC_I4_5, "ldc.i4.5", 0x1b)
+OP(LDC_I4_6, "ldc.i4.6", 0x1c)
+OP(LDC_I4_7, "ldc.i4.7", 0x1d)
+OP(LDC_I4_8, "ldc.i4.8", 0x1e)
+OP(LDC_I4_S, "ldc.i4.s", 0x1f)
+OP(LDC_I4, "ldc.i4", 0x20)
+OP(LDC_I8, "ldc.i8", 0x21)
+OP(LDC_R4, "ldc.r4", 0x22)
+OP(LDC_R8, "ldc.r8", 0x23)
+OP(LDPTR, "ldptr", 0x24)
+OP(DUP, "dup", 0x25)
+OP(POP, "pop", 0x26)
+OP(JMP, "jmp", 0x27)
+OP(CALL, "call", 0x28)
+OP(CALLI, "calli", 0x29)
+OP(RET, "ret", 0x2a)
+OP(BR_S, "br.s", 0x2b)
+OP(BRFALSE_S, "brfalse.s", 0x2c)
+OP(BRTRUE_S, "brtrue.s", 0x2d)
+OP(BEQ_S, "beq.s", 0x2e)
+OP(BGE_S, "bge.s", 0x2f)
+OP(BGT_S, "bgt.s", 0x30)
+OP(BLE_S, "ble.s", 0x31)
+OP(BLT_S, "blt.s", 0x32)
+OP(BNE_UN_S, "bne.un.s", 0x33)
+OP(BGE_UN_S, "bge.un.s", 0x34)
+OP(BGT_UN_S, "bgt.un.s", 0x35)
+OP(BLE_UN_S, "ble.un.s", 0x36)
+OP(BLT_UN_S, "blt.un.s", 0x37)
+OP(BR, "br", 0x38)
+OP(BRFALSE, "brfalse", 0x39)
+OP(BRTRUE, "brtrue", 0x3a)
+OP(BEQ, "beq", 0x3b)
+OP(BGE, "bge", 0x3c)
+OP(BGT, "bgt", 0x3d)
+OP(BLE, "ble", 0x3e)
+OP(BLT, "blt", 0x3f)
+OP(BNE_UN, "bne.un", 0x40)
+OP(BGE_UN, "bge.un", 0x41)
+OP(BGT_UN, "bgt.un", 0x42)
+OP(BLE_UN, "ble.un", 0x43)
+OP(BLT_UN, "blt.un", 0x44)
+OP(SWITCH, "switch", 0x45)
+OP(LDIND_I1, "ldind.i1", 0x46)
+OP(LDIND_U1, "ldind.u1", 0x47)
+OP(LDIND_I2, "ldind.i2", 0x48)
+OP(LDIND_U2, "ldind.u2", 0x49)
+OP(LDIND_I4, "ldind.i4", 0x4a)
+OP(LDIND_U4, "ldind.u4", 0x4b)
+OP(LDIND_I8, "ldind.i8", 0x4c)
+OP(LDIND_I, "ldind.i", 0x4d)
+OP(LDIND_R4, "ldind.r4", 0x4e)
+OP(LDIND_R8, "ldind.r8", 0x4f)
+OP(LDIND_REF, "ldind.ref", 0x50)
+OP(STIND_REF, "stind.ref", 0x51)
+OP(STIND_I1, "stind.i1", 0x52)
+OP(STIND_I2, "stind.i2", 0x53)
+OP(STIND_I4, "stind.i4", 0x54)
+OP(STIND_I8, "stind.i8", 0x55)
+OP(STIND_R4, "stind.r4", 0x56)
+OP(STIND_R8, "stind.r8", 0x57)
+OP(ADD, "add", 0x58)
+OP(SUB, "sub", 0x59)
+OP(MUL, "mul", 0x5a)
+OP(DIV, "div", 0x5b)
+OP(DIV_UN, "div.un", 0x5c)
+OP(REM, "rem", 0x5d)
+OP(REM_UN, "rem.un", 0x5e)
+OP(AND, "and", 0x5f)
+OP(OR, "or", 0x60)
+OP(XOR, "xor", 0x61)
+OP(SHL, "shl", 0x62)
+OP(SHR, "shr", 0x63)
+OP(SHR_UN, "shr.un", 0x64)
+OP(NEG, "neg", 0x65)
+OP(NOT, "not", 0x66)
+OP(CONV_I1, "conv.i1", 0x67)
+OP(CONV_I2, "conv.i2", 0x68)
+OP(CONV_I4, "conv.i4", 0x69)
+OP(CONV_I8, "conv.i8", 0x6a)
+OP(CONV_R4, "conv.r4", 0x6b)
+OP(CONV_R8, "conv.r8", 0x6c)
+OP(CONV_U4, "conv.u4", 0x6d)
+OP(CONV_U8, "conv.u8", 0x6e)
+OP(CALLVIRT, "callvirt", 0x6f)
+OP(CPOBJ, "cpobj", 0x70)
+OP(LDOBJ, "ldobj", 0x71)
+OP(LDSTR, "ldstr", 0x72)
+OP(NEWOBJ, "newobj", 0x73)
+OP(CASTCLASS, "castclass", 0x74)
+OP(ISINST, "isinst", 0x75)
+OP(CONV_R_UN, "conv.r.un", 0x76)
+OP(ANN_DATA_S, "ann.data.s", 0x77)
+OP(UNBOX, "unbox", 0x79)
+OP(THROW, "throw", 0x7a)
+OP(LDFLD, "ldfld", 0x7b)
+OP(LDFLDA, "ldflda", 0x7c)
+OP(STFLD, "stfld", 0x7d)
+OP(LDSFLD, "ldsfld", 0x7e)
+OP(LDSFLDA, "ldsflda", 0x7f)
+OP(STSFLD, "stsfld", 0x80)
+OP(STOBJ, "stobj", 0x81)
+OP(CONV_OVF_I1_UN, "conv.ovf.i1.un", 0x82)
+OP(CONV_OVF_I2_UN, "conv.ovf.i2.un", 0x83)
+OP(CONV_OVF_I4_UN, "conv.ovf.i4.un", 0x84)
+OP(CONV_OVF_I8_UN, "conv.ovf.i8.un", 0x85)
+OP(CONV_OVF_U1_UN, "conv.ovf.u1.un", 0x86)
+OP(CONV_OVF_U2_UN, "conv.ovf.u2.un", 0x87)
+OP(CONV_OVF_U4_UN, "conv.ovf.u4.un", 0x88)
+OP(CONV_OVF_U8_UN, "conv.ovf.u8.un", 0x89)
+OP(CONV_OVF_I_UN, "conv.ovf.i.un", 0x8a)
+OP(CONV_OVF_U_UN, "conv.ovf.u.un", 0x8b)
+OP(BOX, "box", 0x8c)
+OP(NEWARR, "newarr", 0x8d)
+OP(LDLEN, "ldlen", 0x8e)
+OP(LDELEMA, "ldelema", 0x8f)
+OP(LDELEM_I1, "ldelem.i1", 0x90)
+OP(LDELEM_U1, "ldelem.u1", 0x91)
+OP(LDELEM_I2, "ldelem.i2", 0x92)
+OP(LDELEM_U2, "ldelem.u2", 0x93)
+OP(LDELEM_I4, "ldelem.i4", 0x94)
+OP(LDELEM_U4, "ldelem.u4", 0x95)
+OP(LDELEM_I8, "ldelem.i8", 0x96)
+OP(LDELEM_I, "ldelem.i", 0x97)
+OP(LDELEM_R4, "ldelem.r4", 0x98)
+OP(LDELEM_R8, "ldelem.r8", 0x99)
+OP(LDELEM_REF, "ldelem.ref", 0x9a)
+OP(STELEM_I, "stelem.i", 0x9b)
+OP(STELEM_I1, "stelem.i1", 0x9c)
+OP(STELEM_I2, "stelem.i2", 0x9d)
+OP(STELEM_I4, "stelem.i4", 0x9e)
+OP(STELEM_I8, "stelem.i8", 0x9f)
+OP(STELEM_R4, "stelem.r4", 0xa0)
+OP(STELEM_R8, "stelem.r8", 0xa1)
+OP(STELEM_REF, "stelem.ref", 0xa2)
+OP(CONV_OVF_I1, "conv.ovf.i1", 0xb3)
+OP(CONV_OVF_U1, "conv.ovf.u1", 0xb4)
+OP(CONV_OVF_I2, "conv.ovf.i2", 0xb5)
+OP(CONV_OVF_U2, "conv.ovf.u2", 0xb6)
+OP(CONV_OVF_I4, "conv.ovf.i4", 0xb7)
+OP(CONV_OVF_U4, "conv.ovf.u4", 0xb8)
+OP(CONV_OVF_I8, "conv.ovf.i8", 0xb9)
+OP(CONV_OVF_U8, "conv.ovf.u8", 0xba)
+OP(REFANYVAL, "refanyval", 0xc2)
+OP(CKFINITE, "ckfinite", 0xc3)
+OP(MKREFANY, "mkrefany", 0xc6)
+OP(ANN_CALL, "ann.call", 0xc7)
+OP(ANN_CATCH, "ann.catch", 0xc8)
+OP(ANN_DEAD, "ann.dead", 0xc9)
+OP(ANN_HOISTED, "ann.hoisted", 0xca)
+OP(ANN_HOISTED_CALL, "ann.hoisted.call", 0xcb)
+OP(ANN_LAB, "ann.lab", 0xcc)
+OP(ANN_DEF, "ann.def", 0xcd)
+OP(ANN_REF_S, "ann.ref.s", 0xce)
+OP(ANN_PHI, "ann.phi", 0xcf)
+OP(LDTOKEN, "ldtoken", 0xd0)
+OP(CONV_U2, "conv.u2", 0xd1)
+OP(CONV_U1, "conv.u1", 0xd2)
+OP(CONV_I, "conv.i", 0xd3)
+OP(CONV_OVF_I, "conv.ovf.i", 0xd4)
+OP(CONV_OVF_U, "conv.ovf.u", 0xd5)
+OP(ADD_OVF, "add.ovf", 0xd6)
+OP(ADD_OVF_UN, "add.ovf.un", 0xd7)
+OP(MUL_OVF, "mul.ovf", 0xd8)
+OP(MUL_OVF_UN, "mul.ovf.un", 0xd9)
+OP(SUB_OVF, "sub.ovf", 0xda)
+OP(SUB_OVF_UN, "sub.ovf.un", 0xdb)
+OP(ENDFINALLY, "endfinally", 0xdc)
+OP(LEAVE, "leave", 0xdd)
+OP(LEAVE_S, "leave.s", 0xde)
+OP(STIND_I, "stind.i", 0xdf)
+OP(CONV_U, "conv.u", 0xe0)
+
+/* prefix instructions. we use an opcode >= 256 to ease coding */
+
+OP(ARGLIST, "arglist", 0x100)
+OP(CEQ, "ceq", 0x101)
+OP(CGT, "cgt", 0x102)
+OP(CGT_UN, "cgt.un", 0x103)
+OP(CLT, "clt", 0x104)
+OP(CLT_UN, "clt.un", 0x105)
+OP(LDFTN, "ldftn", 0x106)
+OP(LDVIRTFTN, "ldvirtftn", 0x107)
+OP(JMPI, "jmpi", 0x108)
+OP(LDARG, "ldarg", 0x109)
+OP(LDARGA, "ldarga", 0x10a)
+OP(STARG, "starg", 0x10b)
+OP(LDLOC, "ldloc", 0x10c)
+OP(LDLOCA, "ldloca", 0x10d)
+OP(STLOC, "stloc", 0x10e)
+OP(LOCALLOC, "localloc", 0x10f)
+OP(ENDFILTER, "endfilter", 0x111)
+OP(UNALIGNED, "unaligned", 0x112)
+OP(VOLATILE, "volatile", 0x113)
+OP(TAIL, "tail", 0x114)
+OP(INITOBJ, "initobj", 0x115)
+OP(ANN_LIVE, "ann.live", 0x116)
+OP(CPBLK, "cpblk", 0x117)
+OP(INITBLK, "initblk", 0x118)
+OP(ANN_REF, "ann.ref", 0x119)
+OP(RETHROW, "rethrow", 0x11a)
+OP(SIZEOF, "sizeof", 0x11c)
+OP(REFANYTYPE, "refanytype", 0x11d)
+OP(ANN_DATA, "ann.data", 0x122)
+OP(ANN_ARG, "ann.arg", 0x123)
Index: EcnlProtoTool/trunk/tcc-0.9.27/include/float.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/include/float.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/include/float.h	(revision 331)
@@ -0,0 +1,57 @@
+#ifndef _FLOAT_H_
+#define _FLOAT_H_
+
+#define FLT_RADIX 2
+
+/* IEEE float */
+#define FLT_MANT_DIG 24
+#define FLT_DIG 6
+#define FLT_ROUNDS 1
+#define FLT_EPSILON 1.19209290e-07F
+#define FLT_MIN_EXP (-125)
+#define FLT_MIN 1.17549435e-38F
+#define FLT_MIN_10_EXP (-37)
+#define FLT_MAX_EXP 128
+#define FLT_MAX 3.40282347e+38F
+#define FLT_MAX_10_EXP 38
+
+/* IEEE double */
+#define DBL_MANT_DIG 53
+#define DBL_DIG 15
+#define DBL_EPSILON 2.2204460492503131e-16
+#define DBL_MIN_EXP (-1021)
+#define DBL_MIN 2.2250738585072014e-308
+#define DBL_MIN_10_EXP (-307)
+#define DBL_MAX_EXP 1024
+#define DBL_MAX 1.7976931348623157e+308
+#define DBL_MAX_10_EXP 308
+
+/* horrible intel long double */
+#if defined __i386__ || defined __x86_64__
+
+#define LDBL_MANT_DIG 64
+#define LDBL_DIG 18
+#define LDBL_EPSILON 1.08420217248550443401e-19L
+#define LDBL_MIN_EXP (-16381)
+#define LDBL_MIN 3.36210314311209350626e-4932L
+#define LDBL_MIN_10_EXP (-4931)
+#define LDBL_MAX_EXP 16384
+#define LDBL_MAX 1.18973149535723176502e+4932L
+#define LDBL_MAX_10_EXP 4932
+
+#else
+
+/* same as IEEE double */
+#define LDBL_MANT_DIG 53
+#define LDBL_DIG 15
+#define LDBL_EPSILON 2.2204460492503131e-16
+#define LDBL_MIN_EXP (-1021)
+#define LDBL_MIN 2.2250738585072014e-308
+#define LDBL_MIN_10_EXP (-307)
+#define LDBL_MAX_EXP 1024
+#define LDBL_MAX 1.7976931348623157e+308
+#define LDBL_MAX_10_EXP 308
+
+#endif
+
+#endif /* _FLOAT_H_ */
Index: EcnlProtoTool/trunk/tcc-0.9.27/include/stdarg.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/include/stdarg.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/include/stdarg.h	(revision 331)
@@ -0,0 +1,79 @@
+#ifndef _STDARG_H
+#define _STDARG_H
+
+#ifdef __x86_64__
+#ifndef _WIN64
+
+//This should be in sync with the declaration on our lib/libtcc1.c
+/* GCC compatible definition of va_list. */
+typedef struct {
+    unsigned int gp_offset;
+    unsigned int fp_offset;
+    union {
+        unsigned int overflow_offset;
+        char *overflow_arg_area;
+    };
+    char *reg_save_area;
+} __va_list_struct;
+
+typedef __va_list_struct va_list[1];
+
+void __va_start(__va_list_struct *ap, void *fp);
+void *__va_arg(__va_list_struct *ap, int arg_type, int size, int align);
+
+#define va_start(ap, last) __va_start(ap, __builtin_frame_address(0))
+#define va_arg(ap, type)                                                \
+    (*(type *)(__va_arg(ap, __builtin_va_arg_types(type), sizeof(type), __alignof__(type))))
+#define va_copy(dest, src) (*(dest) = *(src))
+#define va_end(ap)
+
+/* avoid conflicting definition for va_list on Macs. */
+#define _VA_LIST_T
+
+#else /* _WIN64 */
+typedef char *va_list;
+#define va_start(ap,last) __builtin_va_start(ap,last)
+#define va_arg(ap, t) ((sizeof(t) > 8 || (sizeof(t) & (sizeof(t) - 1))) \
+	? **(t **)((ap += 8) - 8) : *(t  *)((ap += 8) - 8))
+#define va_copy(dest, src) ((dest) = (src))
+#define va_end(ap)
+#endif
+
+#elif __arm__
+typedef char *va_list;
+#define _tcc_alignof(type) ((int)&((struct {char c;type x;} *)0)->x)
+#define _tcc_align(addr,type) (((unsigned)addr + _tcc_alignof(type) - 1) \
+                               & ~(_tcc_alignof(type) - 1))
+#define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+3)&~3)
+#define va_arg(ap,type) (ap = (void *) ((_tcc_align(ap,type)+sizeof(type)+3) \
+                        &~3), *(type *)(ap - ((sizeof(type)+3)&~3)))
+#define va_copy(dest, src) (dest) = (src)
+#define va_end(ap)
+
+#elif defined(__aarch64__)
+typedef struct {
+    void *__stack;
+    void *__gr_top;
+    void *__vr_top;
+    int   __gr_offs;
+    int   __vr_offs;
+} va_list;
+#define va_start(ap, last) __va_start(ap, last)
+#define va_arg(ap, type) __va_arg(ap, type)
+#define va_end(ap)
+#define va_copy(dest, src) ((dest) = (src))
+
+#else /* __i386__ */
+typedef char *va_list;
+/* only correct for i386 */
+#define va_start(ap,last) ap = ((char *)&(last)) + ((sizeof(last)+3)&~3)
+#define va_arg(ap,type) (ap += (sizeof(type)+3)&~3, *(type *)(ap - ((sizeof(type)+3)&~3)))
+#define va_copy(dest, src) (dest) = (src)
+#define va_end(ap)
+#endif
+
+/* fix a buggy dependency on GCC in libio.h */
+typedef va_list __gnuc_va_list;
+#define _VA_LIST_DEFINED
+
+#endif /* _STDARG_H */
Index: EcnlProtoTool/trunk/tcc-0.9.27/include/stdbool.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/include/stdbool.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/include/stdbool.h	(revision 331)
@@ -0,0 +1,11 @@
+#ifndef _STDBOOL_H
+#define _STDBOOL_H
+
+/* ISOC99 boolean */
+
+#define bool	_Bool
+#define true	1
+#define false	0
+#define __bool_true_false_are_defined 1
+
+#endif /* _STDBOOL_H */
Index: EcnlProtoTool/trunk/tcc-0.9.27/include/stddef.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/include/stddef.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/include/stddef.h	(revision 331)
@@ -0,0 +1,54 @@
+#ifndef _STDDEF_H
+#define _STDDEF_H
+
+typedef __SIZE_TYPE__ size_t;
+typedef __PTRDIFF_TYPE__ ssize_t;
+typedef __WCHAR_TYPE__ wchar_t;
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+typedef __PTRDIFF_TYPE__ intptr_t;
+typedef __SIZE_TYPE__ uintptr_t;
+
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef signed char int8_t;
+typedef signed short int int16_t;
+typedef signed int int32_t;
+#ifdef __LP64__
+typedef signed long int int64_t;
+#else
+typedef signed long long int int64_t;
+#endif
+typedef unsigned char uint8_t;
+typedef unsigned short int uint16_t;
+typedef unsigned int uint32_t;
+#ifdef __LP64__
+typedef unsigned long int uint64_t;
+#else
+typedef unsigned long long int uint64_t;
+#endif
+#endif
+
+#ifndef NULL
+#define NULL ((void*)0)
+#endif
+
+#define offsetof(type, field) ((size_t)&((type *)0)->field)
+
+void *alloca(size_t size);
+
+#endif
+
+/* Older glibc require a wint_t from <stddef.h> (when requested
+   by __need_wint_t, as otherwise stddef.h isn't allowed to
+   define this type).   Note that this must be outside the normal
+   _STDDEF_H guard, so that it works even when we've included the file
+   already (without requiring wint_t).  Some other libs define _WINT_T
+   if they've already provided that type, so we can use that as guard.
+   TCC defines __WINT_TYPE__ for us.  */
+#if defined (__need_wint_t)
+#ifndef _WINT_T
+#define _WINT_T
+typedef __WINT_TYPE__ wint_t;
+#endif
+#undef __need_wint_t
+#endif
Index: EcnlProtoTool/trunk/tcc-0.9.27/include/varargs.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/include/varargs.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/include/varargs.h	(revision 331)
@@ -0,0 +1,12 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _VARARGS_H
+#define _VARARGS_H
+
+#error "TinyCC no longer implements <varargs.h>."
+#error "Revise your code to use <stdarg.h>."
+
+#endif
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/Makefile
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/lib/Makefile	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/Makefile	(revision 331)
@@ -0,0 +1,73 @@
+#
+# Tiny C Compiler Makefile for libtcc1.a
+#
+
+TOP = ..
+include $(TOP)/Makefile
+VPATH = $(TOPSRC)/lib $(TOPSRC)/win32/lib
+T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown)
+X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-)
+BIN = $(TOP)/$(X)libtcc1.a
+
+XTCC ?= $(TOP)/$(X)tcc$(EXESUF)
+XCC = $(XTCC)
+XAR = $(XTCC) -ar
+XFLAGS-unx = -B$(TOPSRC)
+XFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include
+XFLAGS = $(XFLAGS$(XCFG))
+XCFG = $(or $(findstring -win,$T),-unx)
+
+# in order to use gcc, tyoe: make <target>-libtcc1-usegcc=yes
+arm-libtcc1-usegcc ?= no
+
+ifeq "$($(T)-libtcc1-usegcc)" "yes"
+ XCC = $(CC)
+ XAR = $(AR)
+ XFLAGS = $(CFLAGS) -fPIC
+endif
+
+# only for native compiler
+$(X)BCHECK_O = bcheck.o
+
+ifeq ($(CONFIG_musl)$(CONFIG_uClibc),yes)
+ BCHECK_O =
+endif
+
+ifdef CONFIG_OSX
+ XFLAGS += -D_ANSI_SOURCE
+endif
+
+I386_O = libtcc1.o alloca86.o alloca86-bt.o
+X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o
+ARM_O = libtcc1.o armeabi.o alloca-arm.o armflush.o
+ARM64_O = lib-arm64.o
+WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o
+
+OBJ-i386 = $(I386_O) $(BCHECK_O)
+OBJ-x86_64 = $(X86_64_O) va_list.o $(BCHECK_O)
+OBJ-x86_64-osx = $(X86_64_O) va_list.o
+OBJ-i386-win32 = $(I386_O) chkstk.o bcheck.o $(WIN_O)
+OBJ-x86_64-win32 = $(X86_64_O) chkstk.o bcheck.o $(WIN_O)
+OBJ-arm64 = $(ARM64_O)
+OBJ-arm = $(ARM_O)
+OBJ-arm-fpa = $(ARM_O)
+OBJ-arm-fpa-ld = $(ARM_O)
+OBJ-arm-vfp = $(ARM_O)
+OBJ-arm-eabi = $(ARM_O)
+OBJ-arm-eabihf = $(ARM_O)
+OBJ-arm-wince = $(ARM_O) $(WIN_O)
+
+$(BIN) : $(patsubst %.o,$(X)%.o,$(OBJ-$T))
+	$(XAR) rcs $@ $^
+
+$(X)%.o : %.c
+	$(XCC) -c $< -o $@ $(XFLAGS)
+
+$(X)%.o : %.S
+	$(XCC) -c $< -o $@ $(XFLAGS)
+
+$(X)crt1w.o : crt1.c
+$(X)wincrt1w.o : wincrt1.c
+
+clean :
+	rm -f *.a *.o $(BIN)
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca-arm.S
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca-arm.S	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca-arm.S	(revision 331)
@@ -0,0 +1,17 @@
+	.text
+	.align	2
+	.global	alloca
+	.type	alloca, %function
+alloca:
+#ifdef __TINYC__
+        .int 0xe060d00d
+        .int 0xe3cdd007
+        .int 0xe1a0000d
+        .int 0xe1a0f00e
+#else
+	rsb	sp, r0, sp
+	bic	sp, sp, #7
+	mov	r0, sp
+	mov	pc, lr
+#endif
+	.size	alloca, .-alloca
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86-bt.S
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86-bt.S	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86-bt.S	(revision 331)
@@ -0,0 +1,47 @@
+/* ---------------------------------------------- */
+/* alloca86-bt.S */
+
+.globl __bound_alloca
+
+__bound_alloca:
+    pop     %edx
+    pop     %eax
+    mov     %eax, %ecx
+    add     $3,%eax
+    and     $-4,%eax
+    jz      p6
+
+#ifdef _WIN32
+p4:
+    cmp     $4096,%eax
+    jbe     p5
+    test    %eax,-4096(%esp)
+    sub     $4096,%esp
+    sub     $4096,%eax
+    jmp p4
+
+p5:
+#endif
+
+    sub     %eax,%esp
+    mov     %esp,%eax
+
+    push    %edx
+    push    %eax
+    push    %ecx
+    push    %eax
+    call   __bound_new_region
+    add    $8, %esp
+    pop     %eax
+    pop     %edx
+
+p6:
+    push    %edx
+    push    %edx
+    ret
+
+/* mark stack as nonexecutable */
+#if defined __ELF__ && defined __linux__
+    .section    .note.GNU-stack,"",@progbits
+#endif
+/* ---------------------------------------------- */
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86.S
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86.S	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86.S	(revision 331)
@@ -0,0 +1,31 @@
+/* ---------------------------------------------- */
+/* alloca86.S */
+
+.globl alloca
+
+alloca:
+    pop     %edx
+    pop     %eax
+    add     $3,%eax
+    and     $-4,%eax
+    jz      p3
+
+#ifdef _WIN32
+p1:
+    cmp     $4096,%eax
+    jbe     p2
+    test    %eax,-4096(%esp)
+    sub     $4096,%esp
+    sub     $4096,%eax
+    jmp p1
+p2:
+#endif
+
+    sub     %eax,%esp
+    mov     %esp,%eax
+p3:
+    push    %edx
+    push    %edx
+    ret
+
+/* ---------------------------------------------- */
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86_64-bt.S
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86_64-bt.S	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86_64-bt.S	(revision 331)
@@ -0,0 +1,56 @@
+/* ---------------------------------------------- */
+/* alloca86_64.S */
+
+.globl __bound_alloca
+__bound_alloca:
+
+#ifdef _WIN32
+    # bound checking is not implemented
+    pop     %rdx
+    mov     %rcx,%rax
+    add     $15,%rax
+    and     $-16,%rax
+    jz      p3
+
+p1:
+    cmp     $4096,%rax
+    jbe     p2
+    test    %rax,-4096(%rsp)
+    sub     $4096,%rsp
+    sub     $4096,%rax
+    jmp p1
+p2:
+
+    sub     %rax,%rsp
+    mov     %rsp,%rax
+    add     $32,%rax
+
+p3:
+    push    %rdx
+    ret
+#else
+    pop     %rdx
+    mov     %rdi,%rax
+    mov     %rax,%rsi	# size, a second parm to the __bound_new_region
+
+    add     $15,%rax
+    and     $-16,%rax
+    jz      p3
+
+
+    sub     %rax,%rsp
+    mov     %rsp,%rdi	# pointer, a first parm to the __bound_new_region
+    mov     %rsp,%rax
+
+    push    %rdx
+    push    %rax
+    call   __bound_new_region
+    pop     %rax
+    pop     %rdx
+
+p3:
+    push    %rdx
+    ret
+#endif
+
+/* ---------------------------------------------- */
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86_64.S
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86_64.S	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/alloca86_64.S	(revision 331)
@@ -0,0 +1,34 @@
+/* ---------------------------------------------- */
+/* alloca86_64.S */
+
+.globl alloca
+
+alloca:
+    pop     %rdx
+#ifdef _WIN32
+    mov     %rcx,%rax
+#else
+    mov     %rdi,%rax
+#endif
+    add     $15,%rax
+    and     $-16,%rax
+    jz      p3
+
+#ifdef _WIN32
+p1:
+    cmp     $4096,%rax
+    jbe     p2
+    test    %rax,-4096(%rsp)
+    sub     $4096,%rsp
+    sub     $4096,%rax
+    jmp p1
+p2:
+#endif
+
+    sub     %rax,%rsp
+    mov     %rsp,%rax
+p3:
+    push    %rdx
+    ret
+
+/* ---------------------------------------------- */
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/armeabi.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/lib/armeabi.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/armeabi.c	(revision 331)
@@ -0,0 +1,501 @@
+/* TCC ARM runtime EABI
+   Copyright (C) 2013 Thomas Preud'homme
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.*/
+
+#ifdef __TINYC__
+#define INT_MIN (-2147483647 - 1)
+#define INT_MAX 2147483647
+#define UINT_MAX 0xffffffff
+#define LONG_MIN (-2147483647L - 1)
+#define LONG_MAX 2147483647L
+#define ULONG_MAX 0xffffffffUL
+#define LLONG_MAX 9223372036854775807LL
+#define LLONG_MIN (-9223372036854775807LL - 1)
+#define ULLONG_MAX 0xffffffffffffffffULL
+#else
+#include <limits.h>
+#endif
+
+/* We rely on the little endianness and EABI calling convention for this to
+   work */
+
+typedef struct double_unsigned_struct {
+    unsigned low;
+    unsigned high;
+} double_unsigned_struct;
+
+typedef struct unsigned_int_struct {
+    unsigned low;
+    int high;
+} unsigned_int_struct;
+
+#define REGS_RETURN(name, type) \
+    void name ## _return(type ret) {}
+
+
+/* Float helper functions */
+
+#define FLOAT_EXP_BITS 8
+#define FLOAT_FRAC_BITS 23
+
+#define DOUBLE_EXP_BITS 11
+#define DOUBLE_FRAC_BITS 52
+
+#define ONE_EXP(type) ((1 << (type ## _EXP_BITS - 1)) - 1)
+
+REGS_RETURN(unsigned_int_struct, unsigned_int_struct)
+REGS_RETURN(double_unsigned_struct, double_unsigned_struct)
+
+/* float -> integer: (sign) 1.fraction x 2^(exponent - exp_for_one) */
+
+
+/* float to [unsigned] long long conversion */
+#define DEFINE__AEABI_F2XLZ(name, with_sign)                                 \
+void __aeabi_ ## name(unsigned val)                                          \
+{                                                                            \
+    int exp, high_shift, sign;                                               \
+    double_unsigned_struct ret;                                              \
+                                                                             \
+    /* compute sign */                                                       \
+    sign = val >> 31;                                                        \
+                                                                             \
+    /* compute real exponent */                                              \
+    exp = val >> FLOAT_FRAC_BITS;                                            \
+    exp &= (1 << FLOAT_EXP_BITS) - 1;                                        \
+    exp -= ONE_EXP(FLOAT);                                                   \
+                                                                             \
+    /* undefined behavior if truncated value cannot be represented */        \
+    if (with_sign) {                                                         \
+        if (exp > 62) /* |val| too big, double cannot represent LLONG_MAX */ \
+            return;                                                          \
+    } else {                                                                 \
+        if ((sign && exp >= 0) || exp > 63) /* if val < 0 || val too big */  \
+            return;                                                          \
+    }                                                                        \
+                                                                             \
+    val &= (1 << FLOAT_FRAC_BITS) - 1;                                       \
+    if (exp >= 32) {                                                         \
+        ret.high = 1 << (exp - 32);                                          \
+        if (exp - 32 >= FLOAT_FRAC_BITS) {                                   \
+            ret.high |= val << (exp - 32 - FLOAT_FRAC_BITS);                 \
+            ret.low = 0;                                                     \
+        } else {                                                             \
+            high_shift = FLOAT_FRAC_BITS - (exp - 32);                       \
+            ret.high |= val >> high_shift;                                   \
+            ret.low = val << (32 - high_shift);                              \
+        }                                                                    \
+    } else {                                                                 \
+        ret.high = 0;                                                        \
+        ret.low = 1 << exp;                                                  \
+        if (exp > FLOAT_FRAC_BITS)                                           \
+            ret.low |= val << (exp - FLOAT_FRAC_BITS);                       \
+        else                                                                 \
+            ret.low |= val >> (FLOAT_FRAC_BITS - exp);                       \
+    }                                                                        \
+                                                                             \
+    /* encode negative integer using 2's complement */                       \
+    if (with_sign && sign) {                                                 \
+        ret.low = ~ret.low;                                                  \
+        ret.high = ~ret.high;                                                \
+        if (ret.low == UINT_MAX) {                                           \
+            ret.low = 0;                                                     \
+            ret.high++;                                                      \
+        } else                                                               \
+            ret.low++;                                                       \
+    }                                                                        \
+                                                                             \
+    double_unsigned_struct_return(ret);                                      \
+}
+
+/* float to unsigned long long conversion */
+DEFINE__AEABI_F2XLZ(f2ulz, 0)
+
+/* float to long long conversion */
+DEFINE__AEABI_F2XLZ(f2lz, 1)
+
+/* double to [unsigned] long long conversion */
+#define DEFINE__AEABI_D2XLZ(name, with_sign)                                 \
+void __aeabi_ ## name(double_unsigned_struct val)                            \
+{                                                                            \
+    int exp, high_shift, sign;                                               \
+    double_unsigned_struct ret;                                              \
+                                                                             \
+    /* compute sign */                                                       \
+    sign = val.high >> 31;                                                   \
+                                                                             \
+    /* compute real exponent */                                              \
+    exp = (val.high >> (DOUBLE_FRAC_BITS - 32));                             \
+    exp &= (1 << DOUBLE_EXP_BITS) - 1;                                       \
+    exp -= ONE_EXP(DOUBLE);                                                  \
+                                                                             \
+    /* undefined behavior if truncated value cannot be represented */        \
+    if (with_sign) {                                                         \
+        if (exp > 62) /* |val| too big, double cannot represent LLONG_MAX */ \
+            return;                                                          \
+    } else {                                                                 \
+        if ((sign && exp >= 0) || exp > 63) /* if val < 0 || val too big */  \
+            return;                                                          \
+    }                                                                        \
+                                                                             \
+    val.high &= (1 << (DOUBLE_FRAC_BITS - 32)) - 1;                          \
+    if (exp >= 32) {                                                         \
+        ret.high = 1 << (exp - 32);                                          \
+        if (exp >= DOUBLE_FRAC_BITS) {                                       \
+            high_shift = exp - DOUBLE_FRAC_BITS;                             \
+            ret.high |= val.high << high_shift;                              \
+            ret.high |= val.low >> (32 - high_shift);                        \
+            ret.low = val.low << high_shift;                                 \
+        } else {                                                             \
+            high_shift = DOUBLE_FRAC_BITS - exp;                             \
+            ret.high |= val.high >> high_shift;                              \
+            ret.low = val.high << (32 - high_shift);                         \
+            ret.low |= val.low >> high_shift;                                \
+        }                                                                    \
+    } else {                                                                 \
+        ret.high = 0;                                                        \
+        ret.low = 1 << exp;                                                  \
+        if (exp > DOUBLE_FRAC_BITS - 32) {                                   \
+            high_shift = exp - DOUBLE_FRAC_BITS - 32;                        \
+            ret.low |= val.high << high_shift;                               \
+            ret.low |= val.low >> (32 - high_shift);                         \
+        } else                                                               \
+            ret.low |= val.high >> (DOUBLE_FRAC_BITS - 32 - exp);            \
+    }                                                                        \
+                                                                             \
+    /* encode negative integer using 2's complement */                       \
+    if (with_sign && sign) {                                                 \
+        ret.low = ~ret.low;                                                  \
+        ret.high = ~ret.high;                                                \
+        if (ret.low == UINT_MAX) {                                           \
+            ret.low = 0;                                                     \
+            ret.high++;                                                      \
+        } else                                                               \
+            ret.low++;                                                       \
+    }                                                                        \
+                                                                             \
+    double_unsigned_struct_return(ret);                                      \
+}
+
+/* double to unsigned long long conversion */
+DEFINE__AEABI_D2XLZ(d2ulz, 0)
+
+/* double to long long conversion */
+DEFINE__AEABI_D2XLZ(d2lz, 1)
+
+/* long long to float conversion */
+#define DEFINE__AEABI_XL2F(name, with_sign)                             \
+unsigned __aeabi_ ## name(unsigned long long v)                         \
+{                                                                       \
+    int s /* shift */, flb /* first lost bit */, sign = 0;              \
+    unsigned p = 0 /* power */, ret;                                    \
+    double_unsigned_struct val;                                         \
+                                                                        \
+    /* fraction in negative float is encoded in 1's complement */       \
+    if (with_sign && (v & (1ULL << 63))) {                              \
+        sign = 1;                                                       \
+        v = ~v + 1;                                                     \
+    }                                                                   \
+    val.low = v;                                                        \
+    val.high = v >> 32;                                                 \
+    /* fill fraction bits */                                            \
+    for (s = 31, p = 1 << 31; p && !(val.high & p); s--, p >>= 1);      \
+    if (p) {                                                            \
+        ret = val.high & (p - 1);                                       \
+        if (s < FLOAT_FRAC_BITS) {                                      \
+            ret <<= FLOAT_FRAC_BITS - s;                                \
+            ret |= val.low >> (32 - (FLOAT_FRAC_BITS - s));             \
+            flb = (val.low >> (32 - (FLOAT_FRAC_BITS - s - 1))) & 1;    \
+        } else {                                                        \
+            flb = (ret >> (s - FLOAT_FRAC_BITS - 1)) & 1;               \
+            ret >>= s - FLOAT_FRAC_BITS;                                \
+        }                                                               \
+        s += 32;                                                        \
+    } else {                                                            \
+        for (s = 31, p = 1 << 31; p && !(val.low & p); s--, p >>= 1);   \
+        if (p) {                                                        \
+            ret = val.low & (p - 1);                                    \
+            if (s <= FLOAT_FRAC_BITS) {                                 \
+                ret <<= FLOAT_FRAC_BITS - s;                            \
+                flb = 0;                                                \
+	    } else {                                                    \
+                flb = (ret >> (s - FLOAT_FRAC_BITS - 1)) & 1;           \
+                ret >>= s - FLOAT_FRAC_BITS;                            \
+	    }                                                           \
+        } else                                                          \
+            return 0;                                                   \
+    }                                                                   \
+    if (flb)                                                            \
+        ret++;                                                          \
+                                                                        \
+    /* fill exponent bits */                                            \
+    ret |= (s + ONE_EXP(FLOAT)) << FLOAT_FRAC_BITS;                     \
+                                                                        \
+    /* fill sign bit */                                                 \
+    ret |= sign << 31;                                                  \
+                                                                        \
+    return ret;                                                         \
+}
+
+/* unsigned long long to float conversion */
+DEFINE__AEABI_XL2F(ul2f, 0)
+
+/* long long to float conversion */
+DEFINE__AEABI_XL2F(l2f, 1)
+
+/* long long to double conversion */
+#define __AEABI_XL2D(name, with_sign)                                   \
+void __aeabi_ ## name(unsigned long long v)                             \
+{                                                                       \
+    int s /* shift */, high_shift, sign = 0;                            \
+    unsigned tmp, p = 0;                                                \
+    double_unsigned_struct val, ret;                                    \
+                                                                        \
+    /* fraction in negative float is encoded in 1's complement */       \
+    if (with_sign && (v & (1ULL << 63))) {                              \
+        sign = 1;                                                       \
+        v = ~v + 1;                                                     \
+    }                                                                   \
+    val.low = v;                                                        \
+    val.high = v >> 32;                                                 \
+                                                                        \
+    /* fill fraction bits */                                            \
+    for (s = 31, p = 1 << 31; p && !(val.high & p); s--, p >>= 1);      \
+    if (p) {                                                            \
+        tmp = val.high & (p - 1);                                       \
+        if (s < DOUBLE_FRAC_BITS - 32) {                                \
+            high_shift = DOUBLE_FRAC_BITS - 32 - s;                     \
+            ret.high = tmp << high_shift;                               \
+            ret.high |= val.low >> (32 - high_shift);                   \
+            ret.low = val.low << high_shift;                            \
+        } else {                                                        \
+            high_shift = s - (DOUBLE_FRAC_BITS - 32);                   \
+            ret.high = tmp >> high_shift;                               \
+            ret.low = tmp << (32 - high_shift);                         \
+            ret.low |= val.low >> high_shift;                           \
+            if ((val.low >> (high_shift - 1)) & 1) {                    \
+                if (ret.low == UINT_MAX) {                              \
+                    ret.high++;                                         \
+                    ret.low = 0;                                        \
+		} else                                                  \
+                    ret.low++;                                          \
+            }                                                           \
+        }                                                               \
+        s += 32;                                                        \
+    } else {                                                            \
+        for (s = 31, p = 1 << 31; p && !(val.low & p); s--, p >>= 1);   \
+        if (p) {                                                        \
+            tmp = val.low & (p - 1);                                    \
+            if (s <= DOUBLE_FRAC_BITS - 32) {                           \
+                high_shift = DOUBLE_FRAC_BITS - 32 - s;                 \
+                ret.high = tmp << high_shift;                           \
+                ret.low = 0;                                            \
+	    } else {                                                    \
+                high_shift = s - (DOUBLE_FRAC_BITS - 32);               \
+                ret.high = tmp >> high_shift;                           \
+                ret.low = tmp << (32 - high_shift);                     \
+            }                                                           \
+        } else {                                                        \
+            ret.high = ret.low = 0;                                     \
+            double_unsigned_struct_return(ret);                         \
+        }                                                               \
+    }                                                                   \
+                                                                        \
+    /* fill exponent bits */                                            \
+    ret.high |= (s + ONE_EXP(DOUBLE)) << (DOUBLE_FRAC_BITS - 32);       \
+                                                                        \
+    /* fill sign bit */                                                 \
+    ret.high |= sign << 31;                                             \
+                                                                        \
+    double_unsigned_struct_return(ret);                                 \
+}
+
+/* unsigned long long to double conversion */
+__AEABI_XL2D(ul2d, 0)
+
+/* long long to double conversion */
+__AEABI_XL2D(l2d, 1)
+
+
+/* Long long helper functions */
+
+/* TODO: add error in case of den == 0 (see 則4.3.1 and 則4.3.2) */
+
+#define define_aeabi_xdivmod_signed_type(basetype, type) \
+typedef struct type {                                    \
+    basetype quot;                                       \
+    unsigned basetype rem;                               \
+} type
+
+#define define_aeabi_xdivmod_unsigned_type(basetype, type) \
+typedef struct type {                                      \
+    basetype quot;                                         \
+    basetype rem;                                          \
+} type
+
+#define AEABI_UXDIVMOD(name,type, rettype, typemacro)                     \
+static inline rettype aeabi_ ## name (type num, type den)                 \
+{                                                                         \
+    rettype ret;                                                          \
+    type quot = 0;                                                        \
+                                                                          \
+    /* Increase quotient while it is less than numerator */               \
+    while (num >= den) {                                                  \
+        type q = 1;                                                       \
+                                                                          \
+        /* Find closest power of two */                                   \
+        while ((q << 1) * den <= num && q * den <= typemacro ## _MAX / 2) \
+            q <<= 1;                                                      \
+                                                                          \
+        /* Compute difference between current quotient and numerator */   \
+        num -= q * den;                                                   \
+        quot += q;                                                        \
+    }                                                                     \
+    ret.quot = quot;                                                      \
+    ret.rem = num;                                                        \
+    return ret;                                                           \
+}
+
+#define __AEABI_XDIVMOD(name, type, uiname, rettype, urettype, typemacro)     \
+void __aeabi_ ## name(type numerator, type denominator)                       \
+{                                                                             \
+    unsigned type num, den;                                                   \
+    urettype uxdiv_ret;                                                       \
+    rettype ret;                                                              \
+                                                                              \
+    if (numerator >= 0)                                                       \
+      num = numerator;                                                        \
+    else                                                                      \
+      num = 0 - numerator;                                                    \
+    if (denominator >= 0)                                                     \
+      den = denominator;                                                      \
+    else                                                                      \
+      den = 0 - denominator;                                                  \
+    uxdiv_ret = aeabi_ ## uiname(num, den);                                   \
+    /* signs differ */                                                        \
+    if ((numerator & typemacro ## _MIN) != (denominator & typemacro ## _MIN)) \
+        ret.quot = 0 - uxdiv_ret.quot;                                        \
+    else                                                                      \
+        ret.quot = uxdiv_ret.quot;                                            \
+    if (numerator < 0)                                                        \
+        ret.rem = 0 - uxdiv_ret.rem;                                          \
+    else                                                                      \
+        ret.rem = uxdiv_ret.rem;                                              \
+                                                                              \
+    rettype ## _return(ret);                                                  \
+}
+
+define_aeabi_xdivmod_signed_type(long long, lldiv_t);
+define_aeabi_xdivmod_unsigned_type(unsigned long long, ulldiv_t);
+define_aeabi_xdivmod_signed_type(int, idiv_t);
+define_aeabi_xdivmod_unsigned_type(unsigned, uidiv_t);
+
+REGS_RETURN(lldiv_t, lldiv_t)
+REGS_RETURN(ulldiv_t, ulldiv_t)
+REGS_RETURN(idiv_t, idiv_t)
+REGS_RETURN(uidiv_t, uidiv_t)
+
+AEABI_UXDIVMOD(uldivmod, unsigned long long, ulldiv_t, ULLONG)
+
+__AEABI_XDIVMOD(ldivmod, long long, uldivmod, lldiv_t, ulldiv_t, LLONG)
+
+void __aeabi_uldivmod(unsigned long long num, unsigned long long den)
+{
+    ulldiv_t_return(aeabi_uldivmod(num, den));
+}
+
+void __aeabi_llsl(double_unsigned_struct val, int shift)
+{
+    double_unsigned_struct ret;
+
+    if (shift >= 32) {
+        val.high = val.low;
+        val.low = 0;
+        shift -= 32;
+    }
+    if (shift > 0) {
+        ret.low = val.low << shift;
+        ret.high = (val.high << shift) | (val.low >> (32 - shift));
+        double_unsigned_struct_return(ret);
+	return;
+    }
+    double_unsigned_struct_return(val);
+}
+
+#define aeabi_lsr(val, shift, fill, type)                          \
+    type ## _struct ret;                                           \
+                                                                   \
+    if (shift >= 32) {                                             \
+        val.low = val.high;                                        \
+        val.high = fill;                                           \
+        shift -= 32;                                               \
+    }                                                              \
+    if (shift > 0) {                                               \
+        ret.high = val.high >> shift;                              \
+        ret.low = (val.high << (32 - shift)) | (val.low >> shift); \
+        type ## _struct_return(ret);                               \
+	return;                                                    \
+    }                                                              \
+    type ## _struct_return(val);
+
+void __aeabi_llsr(double_unsigned_struct val, int shift)
+{
+    aeabi_lsr(val, shift, 0, double_unsigned);
+}
+
+void __aeabi_lasr(unsigned_int_struct val, int shift)
+{
+    aeabi_lsr(val, shift, val.high >> 31, unsigned_int);
+}
+
+
+/* Integer division functions */
+
+AEABI_UXDIVMOD(uidivmod, unsigned, uidiv_t, UINT)
+
+int __aeabi_idiv(int numerator, int denominator)
+{
+    unsigned num, den;
+    uidiv_t ret;
+
+    if (numerator >= 0)
+        num = numerator;
+    else
+        num = 0 - numerator;
+    if (denominator >= 0)
+        den = denominator;
+    else
+        den = 0 - denominator;
+    ret = aeabi_uidivmod(num, den);
+    if ((numerator & INT_MIN) != (denominator & INT_MIN)) /* signs differ */
+        ret.quot *= -1;
+    return ret.quot;
+}
+
+unsigned __aeabi_uidiv(unsigned num, unsigned den)
+{
+    return aeabi_uidivmod(num, den).quot;
+}
+
+__AEABI_XDIVMOD(idivmod, int, uidivmod, idiv_t, uidiv_t, INT)
+
+void __aeabi_uidivmod(unsigned num, unsigned den)
+{
+    uidiv_t_return(aeabi_uidivmod(num, den));
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/armflush.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/lib/armflush.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/armflush.c	(revision 331)
@@ -0,0 +1,58 @@
+/* armflush.c - flush the instruction cache
+
+   __clear_cache is used in tccrun.c,  It is a built-in
+   intrinsic with gcc.  However tcc in order to compile
+   itself needs this function */
+
+#ifdef __TINYC__
+
+/* syscall wrapper */
+unsigned syscall(unsigned syscall_nr, ...);
+
+/* arm-tcc supports only fake asm currently */
+__asm__(
+    ".global syscall\n"
+    "syscall:\n"
+    ".int 0xe92d4080\n"  // push    {r7, lr}
+    ".int 0xe1a07000\n"  // mov     r7, r0
+    ".int 0xe1a00001\n"  // mov     r0, r1
+    ".int 0xe1a01002\n"  // mov     r1, r2
+    ".int 0xe1a02003\n"  // mov     r2, r3
+    ".int 0xef000000\n"  // svc     0x00000000
+    ".int 0xe8bd8080\n"  // pop     {r7, pc}
+    );
+
+/* from unistd.h: */
+#if defined(__thumb__) || defined(__ARM_EABI__)
+# define __NR_SYSCALL_BASE      0x0
+#else
+# define __NR_SYSCALL_BASE      0x900000
+#endif
+#define __ARM_NR_BASE           (__NR_SYSCALL_BASE+0x0f0000)
+#define __ARM_NR_cacheflush     (__ARM_NR_BASE+2)
+
+#else
+
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <stdio.h>
+
+#endif
+
+/* Flushing for tccrun */
+void __clear_cache(void *beginning, void *end)
+{
+/* __ARM_NR_cacheflush is kernel private and should not be used in user space.
+ * However, there is no ARM asm parser in tcc so we use it for now */
+#if 1
+    syscall(__ARM_NR_cacheflush, beginning, end, 0);
+#else
+    __asm__ ("push {r7}\n\t"
+             "mov r7, #0xf0002\n\t"
+             "mov r2, #0\n\t"
+             "swi 0\n\t"
+             "pop {r7}\n\t"
+             "ret");
+#endif
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/bcheck.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/lib/bcheck.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/bcheck.c	(revision 331)
@@ -0,0 +1,979 @@
+/*
+ *  Tiny C Memory and bounds checker
+ * 
+ *  Copyright (c) 2002 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#if !defined(__FreeBSD__) \
+ && !defined(__FreeBSD_kernel__) \
+ && !defined(__DragonFly__) \
+ && !defined(__OpenBSD__) \
+ && !defined(__NetBSD__)
+#include <malloc.h>
+#endif
+
+#if !defined(_WIN32)
+#include <unistd.h>
+#endif
+
+/* #define BOUND_DEBUG */
+
+#ifdef BOUND_DEBUG
+ #define dprintf(a...) fprintf(a)
+#else
+ #define dprintf(a...)
+#endif
+
+/* define so that bound array is static (faster, but use memory if
+   bound checking not used) */
+/* #define BOUND_STATIC */
+
+/* use malloc hooks. Currently the code cannot be reliable if no hooks */
+#define CONFIG_TCC_MALLOC_HOOKS
+#define HAVE_MEMALIGN
+
+#if defined(__FreeBSD__) \
+ || defined(__FreeBSD_kernel__) \
+ || defined(__DragonFly__) \
+ || defined(__OpenBSD__) \
+ || defined(__NetBSD__) \
+ || defined(__dietlibc__) \
+ || defined(_WIN32)
+//#warning Bound checking does not support malloc (etc.) in this environment.
+#undef CONFIG_TCC_MALLOC_HOOKS
+#undef HAVE_MEMALIGN
+#endif
+
+#define BOUND_T1_BITS 13
+#define BOUND_T2_BITS 11
+#define BOUND_T3_BITS (sizeof(size_t)*8 - BOUND_T1_BITS - BOUND_T2_BITS)
+#define BOUND_E_BITS  (sizeof(size_t))
+
+#define BOUND_T1_SIZE ((size_t)1 << BOUND_T1_BITS)
+#define BOUND_T2_SIZE ((size_t)1 << BOUND_T2_BITS)
+#define BOUND_T3_SIZE ((size_t)1 << BOUND_T3_BITS)
+
+#define BOUND_T23_BITS (BOUND_T2_BITS + BOUND_T3_BITS)
+#define BOUND_T23_SIZE ((size_t)1 << BOUND_T23_BITS)
+
+
+/* this pointer is generated when bound check is incorrect */
+#define INVALID_POINTER ((void *)(-2))
+/* size of an empty region */
+#define EMPTY_SIZE  ((size_t)(-1))
+/* size of an invalid region */
+#define INVALID_SIZE      0
+
+typedef struct BoundEntry {
+    size_t start;
+    size_t size;
+    struct BoundEntry *next;
+    size_t is_invalid; /* true if pointers outside region are invalid */
+} BoundEntry;
+
+/* external interface */
+void __bound_init(void);
+void __bound_new_region(void *p, size_t size);
+int __bound_delete_region(void *p);
+
+#ifdef __attribute__
+  /* an __attribute__ macro is defined in the system headers */
+  #undef __attribute__ 
+#endif
+#define FASTCALL __attribute__((regparm(3)))
+
+void *__bound_malloc(size_t size, const void *caller);
+void *__bound_memalign(size_t size, size_t align, const void *caller);
+void __bound_free(void *ptr, const void *caller);
+void *__bound_realloc(void *ptr, size_t size, const void *caller);
+static void *libc_malloc(size_t size);
+static void libc_free(void *ptr);
+static void install_malloc_hooks(void);
+static void restore_malloc_hooks(void);
+
+#ifdef CONFIG_TCC_MALLOC_HOOKS
+static void *saved_malloc_hook;
+static void *saved_free_hook;
+static void *saved_realloc_hook;
+static void *saved_memalign_hook;
+#endif
+
+/* TCC definitions */
+extern char __bounds_start; /* start of static bounds table */
+/* error message, just for TCC */
+const char *__bound_error_msg;
+
+/* runtime error output */
+extern void rt_error(size_t pc, const char *fmt, ...);
+
+#ifdef BOUND_STATIC
+static BoundEntry *__bound_t1[BOUND_T1_SIZE]; /* page table */
+#else
+static BoundEntry **__bound_t1; /* page table */
+#endif
+static BoundEntry *__bound_empty_t2;   /* empty page, for unused pages */
+static BoundEntry *__bound_invalid_t2; /* invalid page, for invalid pointers */
+
+static BoundEntry *__bound_find_region(BoundEntry *e1, void *p)
+{
+    size_t addr, tmp;
+    BoundEntry *e;
+
+    e = e1;
+    while (e != NULL) {
+        addr = (size_t)p;
+        addr -= e->start;
+        if (addr <= e->size) {
+            /* put region at the head */
+            tmp = e1->start;
+            e1->start = e->start;
+            e->start = tmp;
+            tmp = e1->size;
+            e1->size = e->size;
+            e->size = tmp;
+            return e1;
+        }
+        e = e->next;
+    }
+    /* no entry found: return empty entry or invalid entry */
+    if (e1->is_invalid)
+        return __bound_invalid_t2;
+    else
+        return __bound_empty_t2;
+}
+
+/* print a bound error message */
+static void bound_error(const char *fmt, ...)
+{
+    __bound_error_msg = fmt;
+    fprintf(stderr,"%s %s: %s\n", __FILE__, __FUNCTION__, fmt);
+    *(void **)0 = 0; /* force a runtime error */
+}
+
+static void bound_alloc_error(void)
+{
+    bound_error("not enough memory for bound checking code");
+}
+
+/* return '(p + offset)' for pointer arithmetic (a pointer can reach
+   the end of a region in this case */
+void * FASTCALL __bound_ptr_add(void *p, size_t offset)
+{
+    size_t addr = (size_t)p;
+    BoundEntry *e;
+
+    dprintf(stderr, "%s %s: %p %x\n",
+        __FILE__, __FUNCTION__, p, (unsigned)offset);
+
+    __bound_init();
+
+    e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
+    e = (BoundEntry *)((char *)e + 
+                       ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) & 
+                        ((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
+    addr -= e->start;
+    if (addr > e->size) {
+        e = __bound_find_region(e, p);
+        addr = (size_t)p - e->start;
+    }
+    addr += offset;
+    if (addr >= e->size) {
+	fprintf(stderr,"%s %s: %p is outside of the region\n",
+            __FILE__, __FUNCTION__, p + offset);
+        return INVALID_POINTER; /* return an invalid pointer */
+    }
+    return p + offset;
+}
+
+/* return '(p + offset)' for pointer indirection (the resulting must
+   be strictly inside the region */
+#define BOUND_PTR_INDIR(dsize)                                          \
+void * FASTCALL __bound_ptr_indir ## dsize (void *p, size_t offset)     \
+{                                                                       \
+    size_t addr = (size_t)p;                                            \
+    BoundEntry *e;                                                      \
+                                                                        \
+    dprintf(stderr, "%s %s: %p %x start\n",                             \
+        __FILE__, __FUNCTION__, p, (unsigned)offset);	                \
+									\
+    __bound_init();							\
+    e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];            \
+    e = (BoundEntry *)((char *)e +                                      \
+                       ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &      \
+                        ((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));        \
+    addr -= e->start;                                                   \
+    if (addr > e->size) {                                               \
+        e = __bound_find_region(e, p);                                  \
+        addr = (size_t)p - e->start;                                    \
+    }                                                                   \
+    addr += offset + dsize;                                             \
+    if (addr > e->size) {                                               \
+	fprintf(stderr,"%s %s: %p is outside of the region\n",          \
+            __FILE__, __FUNCTION__, p + offset);                        \
+        return INVALID_POINTER; /* return an invalid pointer */         \
+    }									\
+    dprintf(stderr, "%s %s: return p+offset = %p\n",                    \
+        __FILE__, __FUNCTION__, p + offset);                            \
+    return p + offset;                                                  \
+}
+
+BOUND_PTR_INDIR(1)
+BOUND_PTR_INDIR(2)
+BOUND_PTR_INDIR(4)
+BOUND_PTR_INDIR(8)
+BOUND_PTR_INDIR(12)
+BOUND_PTR_INDIR(16)
+
+#if defined(__GNUC__) && (__GNUC__ >= 6)
+/*
+ * At least gcc 6.2 complains when __builtin_frame_address is used with
+ * nonzero argument.
+ */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wframe-address"
+#endif
+
+/* return the frame pointer of the caller */
+#define GET_CALLER_FP(fp)\
+{\
+    fp = (size_t)__builtin_frame_address(1);\
+}
+
+/* called when entering a function to add all the local regions */
+void FASTCALL __bound_local_new(void *p1) 
+{
+    size_t addr, size, fp, *p = p1;
+
+    dprintf(stderr, "%s, %s start p1=%p\n", __FILE__, __FUNCTION__, p);
+    GET_CALLER_FP(fp);
+    for(;;) {
+        addr = p[0];
+        if (addr == 0)
+            break;
+        addr += fp;
+        size = p[1];
+        p += 2;
+        __bound_new_region((void *)addr, size);
+    }
+    dprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__);
+}
+
+/* called when leaving a function to delete all the local regions */
+void FASTCALL __bound_local_delete(void *p1) 
+{
+    size_t addr, fp, *p = p1;
+    GET_CALLER_FP(fp);
+    for(;;) {
+        addr = p[0];
+        if (addr == 0)
+            break;
+        addr += fp;
+        p += 2;
+        __bound_delete_region((void *)addr);
+    }
+}
+
+#if defined(__GNUC__) && (__GNUC__ >= 6)
+#pragma GCC diagnostic pop
+#endif
+
+static BoundEntry *__bound_new_page(void)
+{
+    BoundEntry *page;
+    size_t i;
+
+    page = libc_malloc(sizeof(BoundEntry) * BOUND_T2_SIZE);
+    if (!page)
+        bound_alloc_error();
+    for(i=0;i<BOUND_T2_SIZE;i++) {
+        /* put empty entries */
+        page[i].start = 0;
+        page[i].size = EMPTY_SIZE;
+        page[i].next = NULL;
+        page[i].is_invalid = 0;
+    }
+    return page;
+}
+
+/* currently we use malloc(). Should use bound_new_page() */
+static BoundEntry *bound_new_entry(void)
+{
+    BoundEntry *e;
+    e = libc_malloc(sizeof(BoundEntry));
+    return e;
+}
+
+static void bound_free_entry(BoundEntry *e)
+{
+    libc_free(e);
+}
+
+static BoundEntry *get_page(size_t index)
+{
+    BoundEntry *page;
+    page = __bound_t1[index];
+    if (!page || page == __bound_empty_t2 || page == __bound_invalid_t2) {
+        /* create a new page if necessary */
+        page = __bound_new_page();
+        __bound_t1[index] = page;
+    }
+    return page;
+}
+
+/* mark a region as being invalid (can only be used during init) */
+static void mark_invalid(size_t addr, size_t size)
+{
+    size_t start, end;
+    BoundEntry *page;
+    size_t t1_start, t1_end, i, j, t2_start, t2_end;
+
+    start = addr;
+    end = addr + size;
+
+    t2_start = (start + BOUND_T3_SIZE - 1) >> BOUND_T3_BITS;
+    if (end != 0)
+        t2_end = end >> BOUND_T3_BITS;
+    else
+        t2_end = 1 << (BOUND_T1_BITS + BOUND_T2_BITS);
+
+#if 0
+    dprintf(stderr, "mark_invalid: start = %x %x\n", t2_start, t2_end);
+#endif
+    
+    /* first we handle full pages */
+    t1_start = (t2_start + BOUND_T2_SIZE - 1) >> BOUND_T2_BITS;
+    t1_end = t2_end >> BOUND_T2_BITS;
+
+    i = t2_start & (BOUND_T2_SIZE - 1);
+    j = t2_end & (BOUND_T2_SIZE - 1);
+    
+    if (t1_start == t1_end) {
+        page = get_page(t2_start >> BOUND_T2_BITS);
+        for(; i < j; i++) {
+            page[i].size = INVALID_SIZE;
+            page[i].is_invalid = 1;
+        }
+    } else {
+        if (i > 0) {
+            page = get_page(t2_start >> BOUND_T2_BITS);
+            for(; i < BOUND_T2_SIZE; i++) {
+                page[i].size = INVALID_SIZE;
+                page[i].is_invalid = 1;
+            }
+        }
+        for(i = t1_start; i < t1_end; i++) {
+            __bound_t1[i] = __bound_invalid_t2;
+        }
+        if (j != 0) {
+            page = get_page(t1_end);
+            for(i = 0; i < j; i++) {
+                page[i].size = INVALID_SIZE;
+                page[i].is_invalid = 1;
+            }
+        }
+    }
+}
+
+void __bound_init(void)
+{
+    size_t i;
+    BoundEntry *page;
+    size_t start, size;
+    size_t *p;
+
+    static int inited;
+    if (inited)
+	return;
+
+    inited = 1;
+
+    dprintf(stderr, "%s, %s() start\n", __FILE__, __FUNCTION__);
+
+    /* save malloc hooks and install bound check hooks */
+    install_malloc_hooks();
+
+#ifndef BOUND_STATIC
+    __bound_t1 = libc_malloc(BOUND_T1_SIZE * sizeof(BoundEntry *));
+    if (!__bound_t1)
+        bound_alloc_error();
+#endif
+    __bound_empty_t2 = __bound_new_page();
+    for(i=0;i<BOUND_T1_SIZE;i++) {
+        __bound_t1[i] = __bound_empty_t2;
+    }
+
+    page = __bound_new_page();
+    for(i=0;i<BOUND_T2_SIZE;i++) {
+        /* put invalid entries */
+        page[i].start = 0;
+        page[i].size = INVALID_SIZE;
+        page[i].next = NULL;
+        page[i].is_invalid = 1;
+    }
+    __bound_invalid_t2 = page;
+
+    /* invalid pointer zone */
+    start = (size_t)INVALID_POINTER & ~(BOUND_T23_SIZE - 1);
+    size = BOUND_T23_SIZE;
+    mark_invalid(start, size);
+
+#if defined(CONFIG_TCC_MALLOC_HOOKS)
+    /* malloc zone is also marked invalid. can only use that with
+     * hooks because all libs should use the same malloc. The solution
+     * would be to build a new malloc for tcc.
+     *
+     * usually heap (= malloc zone) comes right after bss, i.e. after _end, but
+     * not always - either if we are running from under `tcc -b -run`, or if
+     * address space randomization is turned on(a), heap start will be separated
+     * from bss end.
+     *
+     * So sbrk(0) will be a good approximation for start_brk:
+     *
+     *   - if we are a separately compiled program, __bound_init() runs early,
+     *     and sbrk(0) should be equal or very near to start_brk(b) (in case other
+     *     constructors malloc something), or
+     *
+     *   - if we are running from under `tcc -b -run`, sbrk(0) will return
+     *     start of heap portion which is under this program control, and not
+     *     mark as invalid earlier allocated memory.
+     *
+     *
+     * (a) /proc/sys/kernel/randomize_va_space = 2, on Linux;
+     *     usually turned on by default.
+     *
+     * (b) on Linux >= v3.3, the alternative is to read
+     *     start_brk from /proc/self/stat
+     */
+    start = (size_t)sbrk(0);
+    size = 128 * 0x100000;
+    mark_invalid(start, size);
+#endif
+
+    /* add all static bound check values */
+    p = (size_t *)&__bounds_start;
+    while (p[0] != 0) {
+        __bound_new_region((void *)p[0], p[1]);
+        p += 2;
+    }
+
+    dprintf(stderr, "%s, %s() end\n\n", __FILE__, __FUNCTION__);
+}
+
+void __bound_main_arg(void **p)
+{
+    void *start = p;
+    while (*p++);
+
+    dprintf(stderr, "%s, %s calling __bound_new_region(%p %x)\n",
+            __FILE__, __FUNCTION__, start, (unsigned)((void *)p - start));
+
+    __bound_new_region(start, (void *) p - start);
+}
+
+void __bound_exit(void)
+{
+    dprintf(stderr, "%s, %s()\n", __FILE__, __FUNCTION__);
+    restore_malloc_hooks();
+}
+
+static inline void add_region(BoundEntry *e, 
+                              size_t start, size_t size)
+{
+    BoundEntry *e1;
+    if (e->start == 0) {
+        /* no region : add it */
+        e->start = start;
+        e->size = size;
+    } else {
+        /* already regions in the list: add it at the head */
+        e1 = bound_new_entry();
+        e1->start = e->start;
+        e1->size = e->size;
+        e1->next = e->next;
+        e->start = start;
+        e->size = size;
+        e->next = e1;
+    }
+}
+
+/* create a new region. It should not already exist in the region list */
+void __bound_new_region(void *p, size_t size)
+{
+    size_t start, end;
+    BoundEntry *page, *e, *e2;
+    size_t t1_start, t1_end, i, t2_start, t2_end;
+
+    dprintf(stderr, "%s, %s(%p, %x) start\n",
+        __FILE__, __FUNCTION__, p, (unsigned)size);
+
+    __bound_init();
+
+    start = (size_t)p;
+    end = start + size;
+    t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
+    t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS);
+
+    /* start */
+    page = get_page(t1_start);
+    t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) & 
+        ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
+    t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) & 
+        ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
+
+
+    e = (BoundEntry *)((char *)page + t2_start);
+    add_region(e, start, size);
+
+    if (t1_end == t1_start) {
+        /* same ending page */
+        e2 = (BoundEntry *)((char *)page + t2_end);
+        if (e2 > e) {
+            e++;
+            for(;e<e2;e++) {
+                e->start = start;
+                e->size = size;
+            }
+            add_region(e, start, size);
+        }
+    } else {
+        /* mark until end of page */
+        e2 = page + BOUND_T2_SIZE;
+        e++;
+        for(;e<e2;e++) {
+            e->start = start;
+            e->size = size;
+        }
+        /* mark intermediate pages, if any */
+        for(i=t1_start+1;i<t1_end;i++) {
+            page = get_page(i);
+            e2 = page + BOUND_T2_SIZE;
+            for(e=page;e<e2;e++) {
+                e->start = start;
+                e->size = size;
+            }
+        }
+        /* last page */
+        page = get_page(t1_end);
+        e2 = (BoundEntry *)((char *)page + t2_end);
+        for(e=page;e<e2;e++) {
+            e->start = start;
+            e->size = size;
+        }
+        add_region(e, start, size);
+    }
+
+    dprintf(stderr, "%s, %s end\n", __FILE__, __FUNCTION__);
+}
+
+/* delete a region */
+static inline void delete_region(BoundEntry *e, void *p, size_t empty_size)
+{
+    size_t addr;
+    BoundEntry *e1;
+
+    addr = (size_t)p;
+    addr -= e->start;
+    if (addr <= e->size) {
+        /* region found is first one */
+        e1 = e->next;
+        if (e1 == NULL) {
+            /* no more region: mark it empty */
+            e->start = 0;
+            e->size = empty_size;
+        } else {
+            /* copy next region in head */
+            e->start = e1->start;
+            e->size = e1->size;
+            e->next = e1->next;
+            bound_free_entry(e1);
+        }
+    } else {
+        /* find the matching region */
+        for(;;) {
+            e1 = e;
+            e = e->next;
+            /* region not found: do nothing */
+            if (e == NULL)
+                break;
+            addr = (size_t)p - e->start;
+            if (addr <= e->size) {
+                /* found: remove entry */
+                e1->next = e->next;
+                bound_free_entry(e);
+                break;
+            }
+        }
+    }
+}
+
+/* WARNING: 'p' must be the starting point of the region. */
+/* return non zero if error */
+int __bound_delete_region(void *p)
+{
+    size_t start, end, addr, size, empty_size;
+    BoundEntry *page, *e, *e2;
+    size_t t1_start, t1_end, t2_start, t2_end, i;
+
+    dprintf(stderr, "%s %s() start\n", __FILE__, __FUNCTION__);
+
+    __bound_init();
+
+    start = (size_t)p;
+    t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
+    t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) & 
+        ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
+    
+    /* find region size */
+    page = __bound_t1[t1_start];
+    e = (BoundEntry *)((char *)page + t2_start);
+    addr = start - e->start;
+    if (addr > e->size)
+        e = __bound_find_region(e, p);
+    /* test if invalid region */
+    if (e->size == EMPTY_SIZE || (size_t)p != e->start) 
+        return -1;
+    /* compute the size we put in invalid regions */
+    if (e->is_invalid)
+        empty_size = INVALID_SIZE;
+    else
+        empty_size = EMPTY_SIZE;
+    size = e->size;
+    end = start + size;
+
+    /* now we can free each entry */
+    t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS);
+    t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) & 
+        ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
+
+    delete_region(e, p, empty_size);
+    if (t1_end == t1_start) {
+        /* same ending page */
+        e2 = (BoundEntry *)((char *)page + t2_end);
+        if (e2 > e) {
+            e++;
+            for(;e<e2;e++) {
+                e->start = 0;
+                e->size = empty_size;
+            }
+            delete_region(e, p, empty_size);
+        }
+    } else {
+        /* mark until end of page */
+        e2 = page + BOUND_T2_SIZE;
+        e++;
+        for(;e<e2;e++) {
+            e->start = 0;
+            e->size = empty_size;
+        }
+        /* mark intermediate pages, if any */
+        /* XXX: should free them */
+        for(i=t1_start+1;i<t1_end;i++) {
+            page = get_page(i);
+            e2 = page + BOUND_T2_SIZE;
+            for(e=page;e<e2;e++) {
+                e->start = 0;
+                e->size = empty_size;
+            }
+        }
+        /* last page */
+        page = get_page(t1_end);
+        e2 = (BoundEntry *)((char *)page + t2_end);
+        for(e=page;e<e2;e++) {
+            e->start = 0;
+            e->size = empty_size;
+        }
+        delete_region(e, p, empty_size);
+    }
+
+    dprintf(stderr, "%s %s() end\n", __FILE__, __FUNCTION__);
+
+    return 0;
+}
+
+/* return the size of the region starting at p, or EMPTY_SIZE if non
+   existent region. */
+static size_t get_region_size(void *p)
+{
+    size_t addr = (size_t)p;
+    BoundEntry *e;
+
+    e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
+    e = (BoundEntry *)((char *)e + 
+                       ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) & 
+                        ((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
+    addr -= e->start;
+    if (addr > e->size)
+        e = __bound_find_region(e, p);
+    if (e->start != (size_t)p)
+        return EMPTY_SIZE;
+    return e->size;
+}
+
+/* patched memory functions */
+
+/* force compiler to perform stores coded up to this point */
+#define barrier()   __asm__ __volatile__ ("": : : "memory")
+
+static void install_malloc_hooks(void)
+{
+#ifdef CONFIG_TCC_MALLOC_HOOKS
+    saved_malloc_hook = __malloc_hook;
+    saved_free_hook = __free_hook;
+    saved_realloc_hook = __realloc_hook;
+    saved_memalign_hook = __memalign_hook;
+    __malloc_hook = __bound_malloc;
+    __free_hook = __bound_free;
+    __realloc_hook = __bound_realloc;
+    __memalign_hook = __bound_memalign;
+
+    barrier();
+#endif
+}
+
+static void restore_malloc_hooks(void)
+{
+#ifdef CONFIG_TCC_MALLOC_HOOKS
+    __malloc_hook = saved_malloc_hook;
+    __free_hook = saved_free_hook;
+    __realloc_hook = saved_realloc_hook;
+    __memalign_hook = saved_memalign_hook;
+
+    barrier();
+#endif
+}
+
+static void *libc_malloc(size_t size)
+{
+    void *ptr;
+    restore_malloc_hooks();
+    ptr = malloc(size);
+    install_malloc_hooks();
+    return ptr;
+}
+
+static void libc_free(void *ptr)
+{
+    restore_malloc_hooks();
+    free(ptr);
+    install_malloc_hooks();
+}
+
+/* XXX: we should use a malloc which ensure that it is unlikely that
+   two malloc'ed data have the same address if 'free' are made in
+   between. */
+void *__bound_malloc(size_t size, const void *caller)
+{
+    void *ptr;
+    
+    /* we allocate one more byte to ensure the regions will be
+       separated by at least one byte. With the glibc malloc, it may
+       be in fact not necessary */
+    ptr = libc_malloc(size + 1);
+    
+    if (!ptr)
+        return NULL;
+
+    dprintf(stderr, "%s, %s calling __bound_new_region(%p, %x)\n",
+           __FILE__, __FUNCTION__, ptr, (unsigned)size);
+
+    __bound_new_region(ptr, size);
+    return ptr;
+}
+
+void *__bound_memalign(size_t size, size_t align, const void *caller)
+{
+    void *ptr;
+
+    restore_malloc_hooks();
+
+#ifndef HAVE_MEMALIGN
+    if (align > 4) {
+        /* XXX: handle it ? */
+        ptr = NULL;
+    } else {
+        /* we suppose that malloc aligns to at least four bytes */
+        ptr = malloc(size + 1);
+    }
+#else
+    /* we allocate one more byte to ensure the regions will be
+       separated by at least one byte. With the glibc malloc, it may
+       be in fact not necessary */
+    ptr = memalign(size + 1, align);
+#endif
+    
+    install_malloc_hooks();
+    
+    if (!ptr)
+        return NULL;
+
+    dprintf(stderr, "%s, %s calling __bound_new_region(%p, %x)\n",
+           __FILE__, __FUNCTION__, ptr, (unsigned)size);
+
+    __bound_new_region(ptr, size);
+    return ptr;
+}
+
+void __bound_free(void *ptr, const void *caller)
+{
+    if (ptr == NULL)
+        return;
+    if (__bound_delete_region(ptr) != 0)
+        bound_error("freeing invalid region");
+
+    libc_free(ptr);
+}
+
+void *__bound_realloc(void *ptr, size_t size, const void *caller)
+{
+    void *ptr1;
+    size_t old_size;
+
+    if (size == 0) {
+        __bound_free(ptr, caller);
+        return NULL;
+    } else {
+        ptr1 = __bound_malloc(size, caller);
+        if (ptr == NULL || ptr1 == NULL)
+            return ptr1;
+        old_size = get_region_size(ptr);
+        if (old_size == EMPTY_SIZE)
+            bound_error("realloc'ing invalid pointer");
+        memcpy(ptr1, ptr, old_size);
+        __bound_free(ptr, caller);
+        return ptr1;
+    }
+}
+
+#ifndef CONFIG_TCC_MALLOC_HOOKS
+void *__bound_calloc(size_t nmemb, size_t size)
+{
+    void *ptr;
+    size = size * nmemb;
+    ptr = __bound_malloc(size, NULL);
+    if (!ptr)
+        return NULL;
+    memset(ptr, 0, size);
+    return ptr;
+}
+#endif
+
+#if 0
+static void bound_dump(void)
+{
+    BoundEntry *page, *e;
+    size_t i, j;
+
+    fprintf(stderr, "region dump:\n");
+    for(i=0;i<BOUND_T1_SIZE;i++) {
+        page = __bound_t1[i];
+        for(j=0;j<BOUND_T2_SIZE;j++) {
+            e = page + j;
+            /* do not print invalid or empty entries */
+            if (e->size != EMPTY_SIZE && e->start != 0) {
+                fprintf(stderr, "%08x:", 
+                       (i << (BOUND_T2_BITS + BOUND_T3_BITS)) + 
+                       (j << BOUND_T3_BITS));
+                do {
+                    fprintf(stderr, " %08lx:%08lx", e->start, e->start + e->size);
+                    e = e->next;
+                } while (e != NULL);
+                fprintf(stderr, "\n");
+            }
+        }
+    }
+}
+#endif
+
+/* some useful checked functions */
+
+/* check that (p ... p + size - 1) lies inside 'p' region, if any */
+static void __bound_check(const void *p, size_t size)
+{
+    if (size == 0)
+        return;
+    p = __bound_ptr_add((void *)p, size - 1);
+    if (p == INVALID_POINTER)
+        bound_error("invalid pointer");
+}
+
+void *__bound_memcpy(void *dst, const void *src, size_t size)
+{
+    void* p;
+
+    dprintf(stderr, "%s %s: start, dst=%p src=%p size=%x\n",
+            __FILE__, __FUNCTION__, dst, src, (unsigned)size);
+
+    __bound_check(dst, size);
+    __bound_check(src, size);
+    /* check also region overlap */
+    if (src >= dst && src < dst + size)
+        bound_error("overlapping regions in memcpy()");
+
+    p = memcpy(dst, src, size);
+
+    dprintf(stderr, "%s %s: end, p=%p\n", __FILE__, __FUNCTION__, p);
+    return p;
+}
+
+void *__bound_memmove(void *dst, const void *src, size_t size)
+{
+    __bound_check(dst, size);
+    __bound_check(src, size);
+    return memmove(dst, src, size);
+}
+
+void *__bound_memset(void *dst, int c, size_t size)
+{
+    __bound_check(dst, size);
+    return memset(dst, c, size);
+}
+
+/* XXX: could be optimized */
+int __bound_strlen(const char *s)
+{
+    const char *p;
+    size_t len;
+
+    len = 0;
+    for(;;) {
+        p = __bound_ptr_indir1((char *)s, len);
+        if (p == INVALID_POINTER)
+            bound_error("bad pointer in strlen()");
+        if (*p == '\0')
+            break;
+        len++;
+    }
+    return len;
+}
+
+char *__bound_strcpy(char *dst, const char *src)
+{
+    size_t len;
+    void *p;
+
+    dprintf(stderr, "%s %s: strcpy start, dst=%p src=%p\n",
+            __FILE__, __FUNCTION__, dst, src);
+    len = __bound_strlen(src);
+    p = __bound_memcpy(dst, src, len + 1);
+    dprintf(stderr, "%s %s: strcpy end, p = %p\n",
+            __FILE__, __FUNCTION__, p);
+    return p;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/lib-arm64.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/lib/lib-arm64.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/lib-arm64.c	(revision 331)
@@ -0,0 +1,664 @@
+/*
+ *  TCC runtime library for arm64.
+ *
+ *  Copyright (c) 2015 Edmund Grimley Evans
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.  This file is offered as-is,
+ * without any warranty.
+ */
+
+#ifdef __TINYC__
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef int int32_t;
+typedef unsigned uint32_t;
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+void *memcpy(void*,void*,__SIZE_TYPE__);
+#else
+#include <stdint.h>
+#include <string.h>
+#endif
+
+void __clear_cache(void *beg, void *end)
+{
+    __arm64_clear_cache(beg, end);
+}
+
+typedef struct {
+    uint64_t x0, x1;
+} u128_t;
+
+static long double f3_zero(int sgn)
+{
+    long double f;
+    u128_t x = { 0, (uint64_t)sgn << 63 };
+    memcpy(&f, &x, 16);
+    return f;
+}
+
+static long double f3_infinity(int sgn)
+{
+    long double f;
+    u128_t x = { 0, (uint64_t)sgn << 63 | 0x7fff000000000000 };
+    memcpy(&f, &x, 16);
+    return f;
+}
+
+static long double f3_NaN(void)
+{
+    long double f;
+#if 0
+    // ARM's default NaN usually has just the top fraction bit set:
+    u128_t x = {  0, 0x7fff800000000000 };
+#else
+    // GCC's library sets all fraction bits:
+    u128_t x = { -1, 0x7fffffffffffffff };
+#endif
+    memcpy(&f, &x, 16);
+    return f;
+}
+
+static int fp3_convert_NaN(long double *f, int sgn, u128_t mnt)
+{
+    u128_t x = { mnt.x0,
+                 mnt.x1 | 0x7fff800000000000 | (uint64_t)sgn << 63 };
+    memcpy(f, &x, 16);
+    return 1;
+}
+
+static int fp3_detect_NaNs(long double *f,
+                           int a_sgn, int a_exp, u128_t a,
+                           int b_sgn, int b_exp, u128_t b)
+{
+    // Detect signalling NaNs:
+    if (a_exp == 32767 && (a.x0 | a.x1 << 16) && !(a.x1 >> 47 & 1))
+        return fp3_convert_NaN(f, a_sgn, a);
+    if (b_exp == 32767 && (b.x0 | b.x1 << 16) && !(b.x1 >> 47 & 1))
+        return fp3_convert_NaN(f, b_sgn, b);
+
+    // Detect quiet NaNs:
+    if (a_exp == 32767 && (a.x0 | a.x1 << 16))
+        return fp3_convert_NaN(f, a_sgn, a);
+    if (b_exp == 32767 && (b.x0 | b.x1 << 16))
+        return fp3_convert_NaN(f, b_sgn, b);
+
+    return 0;
+}
+
+static void f3_unpack(int *sgn, int32_t *exp, u128_t *mnt, long double f)
+{
+    u128_t x;
+    memcpy(&x, &f, 16);
+    *sgn = x.x1 >> 63;
+    *exp = x.x1 >> 48 & 32767;
+    x.x1 = x.x1 << 16 >> 16;
+    if (*exp)
+        x.x1 |= (uint64_t)1 << 48;
+    else
+        *exp = 1;
+    *mnt = x;
+}
+
+static u128_t f3_normalise(int32_t *exp, u128_t mnt)
+{
+    int sh;
+    if (!(mnt.x0 | mnt.x1))
+        return mnt;
+    if (!mnt.x1) {
+        mnt.x1 = mnt.x0;
+        mnt.x0 = 0;
+        *exp -= 64;
+    }
+    for (sh = 32; sh; sh >>= 1) {
+        if (!(mnt.x1 >> (64 - sh))) {
+            mnt.x1 = mnt.x1 << sh | mnt.x0 >> (64 - sh);
+            mnt.x0 = mnt.x0 << sh;
+            *exp -= sh;
+        }
+    }
+    return mnt;
+}
+
+static u128_t f3_sticky_shift(int32_t sh, u128_t x)
+{
+  if (sh >= 128) {
+      x.x0 = !!(x.x0 | x.x1);
+      x.x1 = 0;
+      return x;
+  }
+  if (sh >= 64) {
+      x.x0 = x.x1 | !!x.x0;
+      x.x1 = 0;
+      sh -= 64;
+  }
+  if (sh > 0) {
+      x.x0 = x.x0 >> sh | x.x1 << (64 - sh) | !!(x.x0 << (64 - sh));
+      x.x1 = x.x1 >> sh;
+  }
+  return x;
+}
+
+static long double f3_round(int sgn, int32_t exp, u128_t x)
+{
+    long double f;
+    int error;
+
+    if (exp > 0) {
+        x = f3_sticky_shift(13, x);
+    }
+    else {
+        x = f3_sticky_shift(14 - exp, x);
+        exp = 0;
+    }
+
+    error = x.x0 & 3;
+    x.x0 = x.x0 >> 2 | x.x1 << 62;
+    x.x1 = x.x1 >> 2;
+
+    if (error == 3 || ((error == 2) & (x.x0 & 1))) {
+        if (!++x.x0) {
+            ++x.x1;
+            if (x.x1 == (uint64_t)1 << 48)
+                exp = 1;
+            else if (x.x1 == (uint64_t)1 << 49) {
+                ++exp;
+                x.x0 = x.x0 >> 1 | x.x1 << 63;
+                x.x1 = x.x1 >> 1;
+            }
+        }
+    }
+
+    if (exp >= 32767)
+        return f3_infinity(sgn);
+
+    x.x1 = x.x1 << 16 >> 16 | (uint64_t)exp << 48 | (uint64_t)sgn << 63;
+    memcpy(&f, &x, 16);
+    return f;
+}
+
+static long double f3_add(long double fa, long double fb, int neg)
+{
+    u128_t a, b, x;
+    int32_t a_exp, b_exp, x_exp;
+    int a_sgn, b_sgn, x_sgn;
+    long double fx;
+
+    f3_unpack(&a_sgn, &a_exp, &a, fa);
+    f3_unpack(&b_sgn, &b_exp, &b, fb);
+
+    if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b))
+        return fx;
+
+    b_sgn ^= neg;
+
+    // Handle infinities and zeroes:
+    if (a_exp == 32767 && b_exp == 32767 && a_sgn != b_sgn)
+        return f3_NaN();
+    if (a_exp == 32767)
+        return f3_infinity(a_sgn);
+    if (b_exp == 32767)
+        return f3_infinity(b_sgn);
+    if (!(a.x0 | a.x1 | b.x0 | b.x1))
+        return f3_zero(a_sgn & b_sgn);
+
+    a.x1 = a.x1 << 3 | a.x0 >> 61;
+    a.x0 = a.x0 << 3;
+    b.x1 = b.x1 << 3 | b.x0 >> 61;
+    b.x0 = b.x0 << 3;
+
+    if (a_exp <= b_exp) {
+        a = f3_sticky_shift(b_exp - a_exp, a);
+        a_exp = b_exp;
+    }
+    else {
+        b = f3_sticky_shift(a_exp - b_exp, b);
+        b_exp = a_exp;
+    }
+
+    x_sgn = a_sgn;
+    x_exp = a_exp;
+    if (a_sgn == b_sgn) {
+        x.x0 = a.x0 + b.x0;
+        x.x1 = a.x1 + b.x1 + (x.x0 < a.x0);
+    }
+    else {
+        x.x0 = a.x0 - b.x0;
+        x.x1 = a.x1 - b.x1 - (x.x0 > a.x0);
+        if (x.x1 >> 63) {
+            x_sgn ^= 1;
+            x.x0 = -x.x0;
+            x.x1 = -x.x1 - !!x.x0;
+        }
+    }
+
+    if (!(x.x0 | x.x1))
+        return f3_zero(0);
+
+    x = f3_normalise(&x_exp, x);
+
+    return f3_round(x_sgn, x_exp + 12, x);
+}
+
+long double __addtf3(long double a, long double b)
+{
+    return f3_add(a, b, 0);
+}
+
+long double __subtf3(long double a, long double b)
+{
+    return f3_add(a, b, 1);
+}
+
+long double __multf3(long double fa, long double fb)
+{
+    u128_t a, b, x;
+    int32_t a_exp, b_exp, x_exp;
+    int a_sgn, b_sgn, x_sgn;
+    long double fx;
+
+    f3_unpack(&a_sgn, &a_exp, &a, fa);
+    f3_unpack(&b_sgn, &b_exp, &b, fb);
+
+    if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b))
+        return fx;
+
+    // Handle infinities and zeroes:
+    if ((a_exp == 32767 && !(b.x0 | b.x1)) ||
+        (b_exp == 32767 && !(a.x0 | a.x1)))
+        return f3_NaN();
+    if (a_exp == 32767 || b_exp == 32767)
+        return f3_infinity(a_sgn ^ b_sgn);
+    if (!(a.x0 | a.x1) || !(b.x0 | b.x1))
+        return f3_zero(a_sgn ^ b_sgn);
+
+    a = f3_normalise(&a_exp, a);
+    b = f3_normalise(&b_exp, b);
+
+    x_sgn = a_sgn ^ b_sgn;
+    x_exp = a_exp + b_exp - 16352;
+
+    {
+        // Convert to base (1 << 30), discarding bottom 6 bits, which are zero,
+        // so there are (32, 30, 30, 30) bits in (a3, a2, a1, a0):
+        uint64_t a0 = a.x0 << 28 >> 34;
+        uint64_t b0 = b.x0 << 28 >> 34;
+        uint64_t a1 = a.x0 >> 36 | a.x1 << 62 >> 34;
+        uint64_t b1 = b.x0 >> 36 | b.x1 << 62 >> 34;
+        uint64_t a2 = a.x1 << 32 >> 34;
+        uint64_t b2 = b.x1 << 32 >> 34;
+        uint64_t a3 = a.x1 >> 32;
+        uint64_t b3 = b.x1 >> 32;
+        // Use 16 small multiplications and additions that do not overflow:
+        uint64_t x0 = a0 * b0;
+        uint64_t x1 = (x0 >> 30) + a0 * b1 + a1 * b0;
+        uint64_t x2 = (x1 >> 30) + a0 * b2 + a1 * b1 + a2 * b0;
+        uint64_t x3 = (x2 >> 30) + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0;
+        uint64_t x4 = (x3 >> 30) + a1 * b3 + a2 * b2 + a3 * b1;
+        uint64_t x5 = (x4 >> 30) + a2 * b3 + a3 * b2;
+        uint64_t x6 = (x5 >> 30) + a3 * b3;
+        // We now have (64, 30, 30, ...) bits in (x6, x5, x4, ...).
+        // Take the top 128 bits, setting bottom bit if any lower bits were set:
+        uint64_t y0 = (x5 << 34 | x4 << 34 >> 30 | x3 << 34 >> 60 |
+                       !!(x3 << 38 | (x2 | x1 | x0) << 34));
+        uint64_t y1 = x6;
+        // Top bit may be zero. Renormalise:
+        if (!(y1 >> 63)) {
+            y1 = y1 << 1 | y0 >> 63;
+            y0 = y0 << 1;
+            --x_exp;
+        }
+        x.x0 = y0;
+        x.x1 = y1;
+    }
+
+    return f3_round(x_sgn, x_exp, x);
+}
+
+long double __divtf3(long double fa, long double fb)
+{
+    u128_t a, b, x;
+    int32_t a_exp, b_exp, x_exp;
+    int a_sgn, b_sgn, x_sgn, i;
+    long double fx;
+
+    f3_unpack(&a_sgn, &a_exp, &a, fa);
+    f3_unpack(&b_sgn, &b_exp, &b, fb);
+
+    if (fp3_detect_NaNs(&fx, a_sgn, a_exp, a, b_sgn, b_exp, b))
+        return fx;
+
+    // Handle infinities and zeroes:
+    if ((a_exp == 32767 && b_exp == 32767) ||
+        (!(a.x0 | a.x1) && !(b.x0 | b.x1)))
+        return f3_NaN();
+    if (a_exp == 32767 || !(b.x0 | b.x1))
+        return f3_infinity(a_sgn ^ b_sgn);
+    if (!(a.x0 | a.x1) || b_exp == 32767)
+        return f3_zero(a_sgn ^ b_sgn);
+
+    a = f3_normalise(&a_exp, a);
+    b = f3_normalise(&b_exp, b);
+
+    x_sgn = a_sgn ^ b_sgn;
+    x_exp = a_exp - b_exp + 16395;
+
+    a.x0 = a.x0 >> 1 | a.x1 << 63;
+    a.x1 = a.x1 >> 1;
+    b.x0 = b.x0 >> 1 | b.x1 << 63;
+    b.x1 = b.x1 >> 1;
+    x.x0 = 0;
+    x.x1 = 0;
+    for (i = 0; i < 116; i++) {
+        x.x1 = x.x1 << 1 | x.x0 >> 63;
+        x.x0 = x.x0 << 1;
+        if (a.x1 > b.x1 || (a.x1 == b.x1 && a.x0 >= b.x0)) {
+            a.x1 = a.x1 - b.x1 - (a.x0 < b.x0);
+            a.x0 = a.x0 - b.x0;
+            x.x0 |= 1;
+        }
+        a.x1 = a.x1 << 1 | a.x0 >> 63;
+        a.x0 = a.x0 << 1;
+    }
+    x.x0 |= !!(a.x0 | a.x1);
+
+    x = f3_normalise(&x_exp, x);
+
+    return f3_round(x_sgn, x_exp, x);
+}
+
+long double __extendsftf2(float f)
+{
+    long double fx;
+    u128_t x;
+    uint32_t a;
+    uint64_t aa;
+    memcpy(&a, &f, 4);
+    aa = a;
+    x.x0 = 0;
+    if (!(a << 1))
+        x.x1 = aa << 32;
+    else if (a << 1 >> 24 == 255)
+        x.x1 = (0x7fff000000000000 | aa >> 31 << 63 | aa << 41 >> 16 |
+                (uint64_t)!!(a << 9) << 47);
+    else
+        x.x1 = (aa >> 31 << 63 | ((aa >> 23 & 255) + 16256) << 48 |
+                aa << 41 >> 16);
+    memcpy(&fx, &x, 16);
+    return fx;
+}
+
+long double __extenddftf2(double f)
+{
+    long double fx;
+    u128_t x;
+    uint64_t a;
+    memcpy(&a, &f, 8);
+    x.x0 = a << 60;
+    if (!(a << 1))
+        x.x1 = a;
+    else if (a << 1 >> 53 == 2047)
+        x.x1 = (0x7fff000000000000 | a >> 63 << 63 | a << 12 >> 16 |
+                (uint64_t)!!(a << 12) << 47);
+    else
+        x.x1 = a >> 63 << 63 | ((a >> 52 & 2047) + 15360) << 48 | a << 12 >> 16;
+    memcpy(&fx, &x, 16);
+    return fx;
+}
+
+float __trunctfsf2(long double f)
+{
+    u128_t mnt;
+    int32_t exp;
+    int sgn;
+    uint32_t x;
+    float fx;
+
+    f3_unpack(&sgn, &exp, &mnt, f);
+
+    if (exp == 32767 && (mnt.x0 | mnt.x1 << 16))
+        x = 0x7fc00000 | (uint32_t)sgn << 31 | (mnt.x1 >> 25 & 0x007fffff);
+    else if (exp > 16510)
+        x = 0x7f800000 | (uint32_t)sgn << 31;
+    else if (exp < 16233)
+        x = (uint32_t)sgn << 31;
+    else {
+        exp -= 16257;
+        x = mnt.x1 >> 23 | !!(mnt.x0 | mnt.x1 << 41);
+        if (exp < 0) {
+            x = x >> -exp | !!(x << (32 + exp));
+            exp = 0;
+        }
+        if ((x & 3) == 3 || (x & 7) == 6)
+            x += 4;
+        x = ((x >> 2) + (exp << 23)) | (uint32_t)sgn << 31;
+    }
+    memcpy(&fx, &x, 4);
+    return fx;
+}
+
+double __trunctfdf2(long double f)
+{
+    u128_t mnt;
+    int32_t exp;
+    int sgn;
+    uint64_t x;
+    double fx;
+
+    f3_unpack(&sgn, &exp, &mnt, f);
+
+    if (exp == 32767 && (mnt.x0 | mnt.x1 << 16))
+        x = (0x7ff8000000000000 | (uint64_t)sgn << 63 |
+             mnt.x1 << 16 >> 12 | mnt.x0 >> 60);
+    else if (exp > 17406)
+        x = 0x7ff0000000000000 | (uint64_t)sgn << 63;
+    else if (exp < 15308)
+        x = (uint64_t)sgn << 63;
+    else {
+        exp -= 15361;
+        x = mnt.x1 << 6 | mnt.x0 >> 58 | !!(mnt.x0 << 6);
+        if (exp < 0) {
+            x = x >> -exp | !!(x << (64 + exp));
+            exp = 0;
+        }
+        if ((x & 3) == 3 || (x & 7) == 6)
+            x += 4;
+        x = ((x >> 2) + ((uint64_t)exp << 52)) | (uint64_t)sgn << 63;
+    }
+    memcpy(&fx, &x, 8);
+    return fx;
+}
+
+int32_t __fixtfsi(long double fa)
+{
+    u128_t a;
+    int32_t a_exp;
+    int a_sgn;
+    int32_t x;
+    f3_unpack(&a_sgn, &a_exp, &a, fa);
+    if (a_exp < 16369)
+        return 0;
+    if (a_exp > 16413)
+        return a_sgn ? -0x80000000 : 0x7fffffff;
+    x = a.x1 >> (16431 - a_exp);
+    return a_sgn ? -x : x;
+}
+
+int64_t __fixtfdi(long double fa)
+{
+    u128_t a;
+    int32_t a_exp;
+    int a_sgn;
+    int64_t x;
+    f3_unpack(&a_sgn, &a_exp, &a, fa);
+    if (a_exp < 16383)
+        return 0;
+    if (a_exp > 16445)
+        return a_sgn ? -0x8000000000000000 : 0x7fffffffffffffff;
+    x = (a.x1 << 15 | a.x0 >> 49) >> (16446 - a_exp);
+    return a_sgn ? -x : x;
+}
+
+uint32_t __fixunstfsi(long double fa)
+{
+    u128_t a;
+    int32_t a_exp;
+    int a_sgn;
+    f3_unpack(&a_sgn, &a_exp, &a, fa);
+    if (a_sgn || a_exp < 16369)
+        return 0;
+    if (a_exp > 16414)
+        return -1;
+    return a.x1 >> (16431 - a_exp);
+}
+
+uint64_t __fixunstfdi(long double fa)
+{
+    u128_t a;
+    int32_t a_exp;
+    int a_sgn;
+    f3_unpack(&a_sgn, &a_exp, &a, fa);
+    if (a_sgn || a_exp < 16383)
+        return 0;
+    if (a_exp > 16446)
+        return -1;
+    return (a.x1 << 15 | a.x0 >> 49) >> (16446 - a_exp);
+}
+
+long double __floatsitf(int32_t a)
+{
+    int sgn = 0;
+    int exp = 16414;
+    uint32_t mnt = a;
+    u128_t x = { 0, 0 };
+    long double f;
+    int i;
+    if (a) {
+        if (a < 0) {
+            sgn = 1;
+            mnt = -mnt;
+        }
+        for (i = 16; i; i >>= 1)
+            if (!(mnt >> (32 - i))) {
+                mnt <<= i;
+                exp -= i;
+            }
+        x.x1 = ((uint64_t)sgn << 63 | (uint64_t)exp << 48 |
+                (uint64_t)(mnt << 1) << 16);
+    }
+    memcpy(&f, &x, 16);
+    return f;
+}
+
+long double __floatditf(int64_t a)
+{
+    int sgn = 0;
+    int exp = 16446;
+    uint64_t mnt = a;
+    u128_t x = { 0, 0 };
+    long double f;
+    int i;
+    if (a) {
+        if (a < 0) {
+            sgn = 1;
+            mnt = -mnt;
+        }
+        for (i = 32; i; i >>= 1)
+            if (!(mnt >> (64 - i))) {
+                mnt <<= i;
+                exp -= i;
+            }
+        x.x0 = mnt << 49;
+        x.x1 = (uint64_t)sgn << 63 | (uint64_t)exp << 48 | mnt << 1 >> 16;
+    }
+    memcpy(&f, &x, 16);
+    return f;
+}
+
+long double __floatunsitf(uint32_t a)
+{
+    int exp = 16414;
+    uint32_t mnt = a;
+    u128_t x = { 0, 0 };
+    long double f;
+    int i;
+    if (a) {
+        for (i = 16; i; i >>= 1)
+            if (!(mnt >> (32 - i))) {
+                mnt <<= i;
+                exp -= i;
+            }
+        x.x1 = (uint64_t)exp << 48 | (uint64_t)(mnt << 1) << 16;
+    }
+    memcpy(&f, &x, 16);
+    return f;
+}
+
+long double __floatunditf(uint64_t a)
+{
+    int exp = 16446;
+    uint64_t mnt = a;
+    u128_t x = { 0, 0 };
+    long double f;
+    int i;
+    if (a) {
+        for (i = 32; i; i >>= 1)
+            if (!(mnt >> (64 - i))) {
+                mnt <<= i;
+                exp -= i;
+            }
+        x.x0 = mnt << 49;
+        x.x1 = (uint64_t)exp << 48 | mnt << 1 >> 16;
+    }
+    memcpy(&f, &x, 16);
+    return f;
+}
+
+static int f3_cmp(long double fa, long double fb)
+{
+    u128_t a, b;
+    memcpy(&a, &fa, 16);
+    memcpy(&b, &fb, 16);
+    return (!(a.x0 | a.x1 << 1 | b.x0 | b.x1 << 1) ? 0 :
+            ((a.x1 << 1 >> 49 == 0x7fff && (a.x0 | a.x1 << 16)) ||
+             (b.x1 << 1 >> 49 == 0x7fff && (b.x0 | b.x1 << 16))) ? 2 :
+            a.x1 >> 63 != b.x1 >> 63 ? (int)(b.x1 >> 63) - (int)(a.x1 >> 63) :
+            a.x1 < b.x1 ? (int)(a.x1 >> 63 << 1) - 1 :
+            a.x1 > b.x1 ? 1 - (int)(a.x1 >> 63 << 1) :
+            a.x0 < b.x0 ? (int)(a.x1 >> 63 << 1) - 1 :
+            b.x0 < a.x0 ? 1 - (int)(a.x1 >> 63 << 1) : 0);
+}
+
+int __eqtf2(long double a, long double b)
+{
+    return !!f3_cmp(a, b);
+}
+
+int __netf2(long double a, long double b)
+{
+    return !!f3_cmp(a, b);
+}
+
+int __lttf2(long double a, long double b)
+{
+    return f3_cmp(a, b);
+}
+
+int __letf2(long double a, long double b)
+{
+    return f3_cmp(a, b);
+}
+
+int __gttf2(long double a, long double b)
+{
+    return -f3_cmp(b, a);
+}
+
+int __getf2(long double a, long double b)
+{
+    return -f3_cmp(b, a);
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/libtcc1.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/lib/libtcc1.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/libtcc1.c	(revision 331)
@@ -0,0 +1,622 @@
+/* TCC runtime library. 
+   Parts of this code are (c) 2002 Fabrice Bellard 
+
+   Copyright (C) 1987, 1988, 1992, 1994, 1995 Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  
+*/
+
+#define W_TYPE_SIZE   32
+#define BITS_PER_UNIT 8
+
+typedef int Wtype;
+typedef unsigned int UWtype;
+typedef unsigned int USItype;
+typedef long long DWtype;
+typedef unsigned long long UDWtype;
+
+struct DWstruct {
+    Wtype low, high;
+};
+
+typedef union
+{
+  struct DWstruct s;
+  DWtype ll;
+} DWunion;
+
+typedef long double XFtype;
+#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
+#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
+
+/* the following deal with IEEE single-precision numbers */
+#define EXCESS		126
+#define SIGNBIT		0x80000000
+#define HIDDEN		(1 << 23)
+#define SIGN(fp)	((fp) & SIGNBIT)
+#define EXP(fp)		(((fp) >> 23) & 0xFF)
+#define MANT(fp)	(((fp) & 0x7FFFFF) | HIDDEN)
+#define PACK(s,e,m)	((s) | ((e) << 23) | (m))
+
+/* the following deal with IEEE double-precision numbers */
+#define EXCESSD		1022
+#define HIDDEND		(1 << 20)
+#define EXPD(fp)	(((fp.l.upper) >> 20) & 0x7FF)
+#define SIGND(fp)	((fp.l.upper) & SIGNBIT)
+#define MANTD(fp)	(((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \
+				(fp.l.lower >> 22))
+#define HIDDEND_LL	((long long)1 << 52)
+#define MANTD_LL(fp)	((fp.ll & (HIDDEND_LL-1)) | HIDDEND_LL)
+#define PACKD_LL(s,e,m)	(((long long)((s)+((e)<<20))<<32)|(m))
+
+/* the following deal with x86 long double-precision numbers */
+#define EXCESSLD	16382
+#define EXPLD(fp)	(fp.l.upper & 0x7fff)
+#define SIGNLD(fp)	((fp.l.upper) & 0x8000)
+
+/* only for x86 */
+union ldouble_long {
+    long double ld;
+    struct {
+        unsigned long long lower;
+        unsigned short upper;
+    } l;
+};
+
+union double_long {
+    double d;
+#if 1
+    struct {
+        unsigned int lower;
+        int upper;
+    } l;
+#else
+    struct {
+        int upper;
+        unsigned int lower;
+    } l;
+#endif
+    long long ll;
+};
+
+union float_long {
+    float f;
+    unsigned int l;
+};
+
+/* XXX: we don't support several builtin supports for now */
+#if !defined __x86_64__ && !defined __arm__
+
+/* XXX: use gcc/tcc intrinsic ? */
+#if defined __i386__
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  __asm__ ("subl %5,%1\n\tsbbl %3,%0"					\
+	   : "=r" ((USItype) (sh)),					\
+	     "=&r" ((USItype) (sl))					\
+	   : "0" ((USItype) (ah)),					\
+	     "g" ((USItype) (bh)),					\
+	     "1" ((USItype) (al)),					\
+	     "g" ((USItype) (bl)))
+#define umul_ppmm(w1, w0, u, v) \
+  __asm__ ("mull %3"							\
+	   : "=a" ((USItype) (w0)),					\
+	     "=d" ((USItype) (w1))					\
+	   : "%0" ((USItype) (u)),					\
+	     "rm" ((USItype) (v)))
+#define udiv_qrnnd(q, r, n1, n0, dv) \
+  __asm__ ("divl %4"							\
+	   : "=a" ((USItype) (q)),					\
+	     "=d" ((USItype) (r))					\
+	   : "0" ((USItype) (n0)),					\
+	     "1" ((USItype) (n1)),					\
+	     "rm" ((USItype) (dv)))
+#define count_leading_zeros(count, x) \
+  do {									\
+    USItype __cbtmp;							\
+    __asm__ ("bsrl %1,%0"						\
+	     : "=r" (__cbtmp) : "rm" ((USItype) (x)));			\
+    (count) = __cbtmp ^ 31;						\
+  } while (0)
+#else
+#error unsupported CPU type
+#endif
+
+/* most of this code is taken from libgcc2.c from gcc */
+
+static UDWtype __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
+{
+  DWunion ww;
+  DWunion nn, dd;
+  DWunion rr;
+  UWtype d0, d1, n0, n1, n2;
+  UWtype q0, q1;
+  UWtype b, bm;
+
+  nn.ll = n;
+  dd.ll = d;
+
+  d0 = dd.s.low;
+  d1 = dd.s.high;
+  n0 = nn.s.low;
+  n1 = nn.s.high;
+
+#if !defined(UDIV_NEEDS_NORMALIZATION)
+  if (d1 == 0)
+    {
+      if (d0 > n1)
+	{
+	  /* 0q = nn / 0D */
+
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+	  q1 = 0;
+
+	  /* Remainder in n0.  */
+	}
+      else
+	{
+	  /* qq = NN / 0d */
+
+	  if (d0 == 0)
+	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
+
+	  udiv_qrnnd (q1, n1, 0, n1, d0);
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+
+	  /* Remainder in n0.  */
+	}
+
+      if (rp != 0)
+	{
+	  rr.s.low = n0;
+	  rr.s.high = 0;
+	  *rp = rr.ll;
+	}
+    }
+
+#else /* UDIV_NEEDS_NORMALIZATION */
+
+  if (d1 == 0)
+    {
+      if (d0 > n1)
+	{
+	  /* 0q = nn / 0D */
+
+	  count_leading_zeros (bm, d0);
+
+	  if (bm != 0)
+	    {
+	      /* Normalize, i.e. make the most significant bit of the
+		 denominator set.  */
+
+	      d0 = d0 << bm;
+	      n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
+	      n0 = n0 << bm;
+	    }
+
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+	  q1 = 0;
+
+	  /* Remainder in n0 >> bm.  */
+	}
+      else
+	{
+	  /* qq = NN / 0d */
+
+	  if (d0 == 0)
+	    d0 = 1 / d0;	/* Divide intentionally by zero.  */
+
+	  count_leading_zeros (bm, d0);
+
+	  if (bm == 0)
+	    {
+	      /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
+		 conclude (the most significant bit of n1 is set) /\ (the
+		 leading quotient digit q1 = 1).
+
+		 This special case is necessary, not an optimization.
+		 (Shifts counts of W_TYPE_SIZE are undefined.)  */
+
+	      n1 -= d0;
+	      q1 = 1;
+	    }
+	  else
+	    {
+	      /* Normalize.  */
+
+	      b = W_TYPE_SIZE - bm;
+
+	      d0 = d0 << bm;
+	      n2 = n1 >> b;
+	      n1 = (n1 << bm) | (n0 >> b);
+	      n0 = n0 << bm;
+
+	      udiv_qrnnd (q1, n1, n2, n1, d0);
+	    }
+
+	  /* n1 != d0...  */
+
+	  udiv_qrnnd (q0, n0, n1, n0, d0);
+
+	  /* Remainder in n0 >> bm.  */
+	}
+
+      if (rp != 0)
+	{
+	  rr.s.low = n0 >> bm;
+	  rr.s.high = 0;
+	  *rp = rr.ll;
+	}
+    }
+#endif /* UDIV_NEEDS_NORMALIZATION */
+
+  else
+    {
+      if (d1 > n1)
+	{
+	  /* 00 = nn / DD */
+
+	  q0 = 0;
+	  q1 = 0;
+
+	  /* Remainder in n1n0.  */
+	  if (rp != 0)
+	    {
+	      rr.s.low = n0;
+	      rr.s.high = n1;
+	      *rp = rr.ll;
+	    }
+	}
+      else
+	{
+	  /* 0q = NN / dd */
+
+	  count_leading_zeros (bm, d1);
+	  if (bm == 0)
+	    {
+	      /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
+		 conclude (the most significant bit of n1 is set) /\ (the
+		 quotient digit q0 = 0 or 1).
+
+		 This special case is necessary, not an optimization.  */
+
+	      /* The condition on the next line takes advantage of that
+		 n1 >= d1 (true due to program flow).  */
+	      if (n1 > d1 || n0 >= d0)
+		{
+		  q0 = 1;
+		  sub_ddmmss (n1, n0, n1, n0, d1, d0);
+		}
+	      else
+		q0 = 0;
+
+	      q1 = 0;
+
+	      if (rp != 0)
+		{
+		  rr.s.low = n0;
+		  rr.s.high = n1;
+		  *rp = rr.ll;
+		}
+	    }
+	  else
+	    {
+	      UWtype m1, m0;
+	      /* Normalize.  */
+
+	      b = W_TYPE_SIZE - bm;
+
+	      d1 = (d1 << bm) | (d0 >> b);
+	      d0 = d0 << bm;
+	      n2 = n1 >> b;
+	      n1 = (n1 << bm) | (n0 >> b);
+	      n0 = n0 << bm;
+
+	      udiv_qrnnd (q0, n1, n2, n1, d1);
+	      umul_ppmm (m1, m0, q0, d0);
+
+	      if (m1 > n1 || (m1 == n1 && m0 > n0))
+		{
+		  q0--;
+		  sub_ddmmss (m1, m0, m1, m0, d1, d0);
+		}
+
+	      q1 = 0;
+
+	      /* Remainder in (n1n0 - m1m0) >> bm.  */
+	      if (rp != 0)
+		{
+		  sub_ddmmss (n1, n0, n1, n0, m1, m0);
+		  rr.s.low = (n1 << b) | (n0 >> bm);
+		  rr.s.high = n1 >> bm;
+		  *rp = rr.ll;
+		}
+	    }
+	}
+    }
+
+  ww.s.low = q0;
+  ww.s.high = q1;
+  return ww.ll;
+}
+
+#define __negdi2(a) (-(a))
+
+long long __divdi3(long long u, long long v)
+{
+    int c = 0;
+    DWunion uu, vv;
+    DWtype w;
+    
+    uu.ll = u;
+    vv.ll = v;
+    
+    if (uu.s.high < 0) {
+        c = ~c;
+        uu.ll = __negdi2 (uu.ll);
+    }
+    if (vv.s.high < 0) {
+        c = ~c;
+        vv.ll = __negdi2 (vv.ll);
+    }
+    w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
+    if (c)
+        w = __negdi2 (w);
+    return w;
+}
+
+long long __moddi3(long long u, long long v)
+{
+    int c = 0;
+    DWunion uu, vv;
+    DWtype w;
+    
+    uu.ll = u;
+    vv.ll = v;
+    
+    if (uu.s.high < 0) {
+        c = ~c;
+        uu.ll = __negdi2 (uu.ll);
+    }
+    if (vv.s.high < 0)
+        vv.ll = __negdi2 (vv.ll);
+    
+    __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) &w);
+    if (c)
+        w = __negdi2 (w);
+    return w;
+}
+
+unsigned long long __udivdi3(unsigned long long u, unsigned long long v)
+{
+    return __udivmoddi4 (u, v, (UDWtype *) 0);
+}
+
+unsigned long long __umoddi3(unsigned long long u, unsigned long long v)
+{
+    UDWtype w;
+    
+    __udivmoddi4 (u, v, &w);
+    return w;
+}
+
+/* XXX: fix tcc's code generator to do this instead */
+long long __ashrdi3(long long a, int b)
+{
+#ifdef __TINYC__
+    DWunion u;
+    u.ll = a;
+    if (b >= 32) {
+        u.s.low = u.s.high >> (b - 32);
+        u.s.high = u.s.high >> 31;
+    } else if (b != 0) {
+        u.s.low = ((unsigned)u.s.low >> b) | (u.s.high << (32 - b));
+        u.s.high = u.s.high >> b;
+    }
+    return u.ll;
+#else
+    return a >> b;
+#endif
+}
+
+/* XXX: fix tcc's code generator to do this instead */
+unsigned long long __lshrdi3(unsigned long long a, int b)
+{
+#ifdef __TINYC__
+    DWunion u;
+    u.ll = a;
+    if (b >= 32) {
+        u.s.low = (unsigned)u.s.high >> (b - 32);
+        u.s.high = 0;
+    } else if (b != 0) {
+        u.s.low = ((unsigned)u.s.low >> b) | (u.s.high << (32 - b));
+        u.s.high = (unsigned)u.s.high >> b;
+    }
+    return u.ll;
+#else
+    return a >> b;
+#endif
+}
+
+/* XXX: fix tcc's code generator to do this instead */
+long long __ashldi3(long long a, int b)
+{
+#ifdef __TINYC__
+    DWunion u;
+    u.ll = a;
+    if (b >= 32) {
+        u.s.high = (unsigned)u.s.low << (b - 32);
+        u.s.low = 0;
+    } else if (b != 0) {
+        u.s.high = ((unsigned)u.s.high << b) | ((unsigned)u.s.low >> (32 - b));
+        u.s.low = (unsigned)u.s.low << b;
+    }
+    return u.ll;
+#else
+    return a << b;
+#endif
+}
+
+#endif /* !__x86_64__ */
+
+/* XXX: fix tcc's code generator to do this instead */
+float __floatundisf(unsigned long long a)
+{
+    DWunion uu; 
+    XFtype r;
+
+    uu.ll = a;
+    if (uu.s.high >= 0) {
+        return (float)uu.ll;
+    } else {
+        r = (XFtype)uu.ll;
+        r += 18446744073709551616.0;
+        return (float)r;
+    }
+}
+
+double __floatundidf(unsigned long long a)
+{
+    DWunion uu; 
+    XFtype r;
+
+    uu.ll = a;
+    if (uu.s.high >= 0) {
+        return (double)uu.ll;
+    } else {
+        r = (XFtype)uu.ll;
+        r += 18446744073709551616.0;
+        return (double)r;
+    }
+}
+
+long double __floatundixf(unsigned long long a)
+{
+    DWunion uu; 
+    XFtype r;
+
+    uu.ll = a;
+    if (uu.s.high >= 0) {
+        return (long double)uu.ll;
+    } else {
+        r = (XFtype)uu.ll;
+        r += 18446744073709551616.0;
+        return (long double)r;
+    }
+}
+
+unsigned long long __fixunssfdi (float a1)
+{
+    register union float_long fl1;
+    register int exp;
+    register unsigned long l;
+
+    fl1.f = a1;
+
+    if (fl1.l == 0)
+	return (0);
+
+    exp = EXP (fl1.l) - EXCESS - 24;
+
+    l = MANT(fl1.l);
+    if (exp >= 41)
+	return (unsigned long long)-1;
+    else if (exp >= 0)
+        return (unsigned long long)l << exp;
+    else if (exp >= -23)
+        return l >> -exp;
+    else
+        return 0;
+}
+
+long long __fixsfdi (float a1)
+{
+    long long ret; int s;
+    ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1);
+    return s ? ret : -ret;
+}
+
+unsigned long long __fixunsdfdi (double a1)
+{
+    register union double_long dl1;
+    register int exp;
+    register unsigned long long l;
+
+    dl1.d = a1;
+
+    if (dl1.ll == 0)
+	return (0);
+
+    exp = EXPD (dl1) - EXCESSD - 53;
+
+    l = MANTD_LL(dl1);
+
+    if (exp >= 12)
+	return (unsigned long long)-1;
+    else if (exp >= 0)
+        return l << exp;
+    else if (exp >= -52)
+        return l >> -exp;
+    else
+        return 0;
+}
+
+long long __fixdfdi (double a1)
+{
+    long long ret; int s;
+    ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1);
+    return s ? ret : -ret;
+}
+
+#ifndef __arm__
+unsigned long long __fixunsxfdi (long double a1)
+{
+    register union ldouble_long dl1;
+    register int exp;
+    register unsigned long long l;
+
+    dl1.ld = a1;
+
+    if (dl1.l.lower == 0 && dl1.l.upper == 0)
+	return (0);
+
+    exp = EXPLD (dl1) - EXCESSLD - 64;
+
+    l = dl1.l.lower;
+
+    if (exp > 0)
+	return (unsigned long long)-1;
+    else if (exp >= -63) 
+        return l >> -exp;
+    else
+        return 0;
+}
+
+long long __fixxfdi (long double a1)
+{
+    long long ret; int s;
+    ret = __fixunsxfdi((s = a1 >= 0) ? a1 : -a1);
+    return s ? ret : -ret;
+}
+#endif /* !ARM */
Index: EcnlProtoTool/trunk/tcc-0.9.27/lib/va_list.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/lib/va_list.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/lib/va_list.c	(revision 331)
@@ -0,0 +1,65 @@
+/* va_list.c - tinycc support for va_list on X86_64 */
+
+#if defined __x86_64__
+
+/* Avoid include files, they may not be available when cross compiling */
+extern void *memset(void *s, int c, __SIZE_TYPE__ n);
+extern void abort(void);
+
+/* This should be in sync with our include/stdarg.h */
+enum __va_arg_type {
+    __va_gen_reg, __va_float_reg, __va_stack
+};
+
+/* GCC compatible definition of va_list. */
+typedef struct {
+    unsigned int gp_offset;
+    unsigned int fp_offset;
+    union {
+        unsigned int overflow_offset;
+        char *overflow_arg_area;
+    };
+    char *reg_save_area;
+} __va_list_struct;
+
+void __va_start(__va_list_struct *ap, void *fp)
+{
+    memset(ap, 0, sizeof(__va_list_struct));
+    *ap = *(__va_list_struct *)((char *)fp - 16);
+    ap->overflow_arg_area = (char *)fp + ap->overflow_offset;
+    ap->reg_save_area = (char *)fp - 176 - 16;
+}
+
+void *__va_arg(__va_list_struct *ap,
+               enum __va_arg_type arg_type,
+               int size, int align)
+{
+    size = (size + 7) & ~7;
+    align = (align + 7) & ~7;
+    switch (arg_type) {
+    case __va_gen_reg:
+        if (ap->gp_offset + size <= 48) {
+            ap->gp_offset += size;
+            return ap->reg_save_area + ap->gp_offset - size;
+        }
+        goto use_overflow_area;
+
+    case __va_float_reg:
+        if (ap->fp_offset < 128 + 48) {
+            ap->fp_offset += 16;
+            return ap->reg_save_area + ap->fp_offset - 16;
+        }
+        size = 8;
+        goto use_overflow_area;
+
+    case __va_stack:
+    use_overflow_area:
+        ap->overflow_arg_area += size;
+        ap->overflow_arg_area = (char*)((long long)(ap->overflow_arg_area + align - 1) & -align);
+        return ap->overflow_arg_area - size;
+
+    default: /* should never happen */
+        abort();
+    }
+}
+#endif
Index: EcnlProtoTool/trunk/tcc-0.9.27/libtcc.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/libtcc.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/libtcc.c	(revision 331)
@@ -0,0 +1,1981 @@
+/*
+ *  TCC - Tiny C Compiler
+ *
+ *  Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "tcc.h"
+
+/********************************************************/
+/* global variables */
+
+/* use GNU C extensions */
+ST_DATA int gnu_ext = 1;
+
+/* use TinyCC extensions */
+ST_DATA int tcc_ext = 1;
+
+/* XXX: get rid of this ASAP */
+ST_DATA struct TCCState *tcc_state;
+
+static int nb_states;
+
+/********************************************************/
+
+#if ONE_SOURCE
+#include "tccpp.c"
+#include "tccgen.c"
+#include "tccelf.c"
+#include "tccrun.c"
+#ifdef TCC_TARGET_I386
+#include "i386-gen.c"
+#include "i386-link.c"
+#include "i386-asm.c"
+#endif
+#ifdef TCC_TARGET_ARM
+#include "arm-gen.c"
+#include "arm-link.c"
+#include "arm-asm.c"
+#endif
+#ifdef TCC_TARGET_ARM64
+#include "arm64-gen.c"
+#include "arm64-link.c"
+#endif
+#ifdef TCC_TARGET_C67
+#include "c67-gen.c"
+#include "c67-link.c"
+#include "tcccoff.c"
+#endif
+#ifdef TCC_TARGET_X86_64
+#include "x86_64-gen.c"
+#include "x86_64-link.c"
+#include "i386-asm.c"
+#endif
+#ifdef CONFIG_TCC_ASM
+#include "tccasm.c"
+#endif
+#ifdef TCC_TARGET_PE
+#include "tccpe.c"
+#endif
+#endif /* ONE_SOURCE */
+
+/********************************************************/
+#ifndef CONFIG_TCC_ASM
+ST_FUNC void asm_instr(void)
+{
+    tcc_error("inline asm() not supported");
+}
+ST_FUNC void asm_global_instr(void)
+{
+    tcc_error("inline asm() not supported");
+}
+#endif
+
+/********************************************************/
+#ifdef _WIN32
+ST_FUNC char *normalize_slashes(char *path)
+{
+    char *p;
+    for (p = path; *p; ++p)
+        if (*p == '\\')
+            *p = '/';
+    return path;
+}
+
+static HMODULE tcc_module;
+
+/* on win32, we suppose the lib and includes are at the location of 'tcc.exe' */
+static void tcc_set_lib_path_w32(TCCState *s)
+{
+    char path[1024], *p;
+    GetModuleFileNameA(tcc_module, path, sizeof path);
+    p = tcc_basename(normalize_slashes(strlwr(path)));
+    if (p > path)
+        --p;
+    *p = 0;
+    tcc_set_lib_path(s, path);
+}
+
+#ifdef TCC_TARGET_PE
+static void tcc_add_systemdir(TCCState *s)
+{
+    char buf[1000];
+    GetSystemDirectory(buf, sizeof buf);
+    tcc_add_library_path(s, normalize_slashes(buf));
+}
+#endif
+
+#ifdef LIBTCC_AS_DLL
+BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved)
+{
+    if (DLL_PROCESS_ATTACH == dwReason)
+        tcc_module = hDll;
+    return TRUE;
+}
+#endif
+#endif
+
+/********************************************************/
+/* copy a string and truncate it. */
+ST_FUNC char *pstrcpy(char *buf, int buf_size, const char *s)
+{
+    char *q, *q_end;
+    int c;
+
+    if (buf_size > 0) {
+        q = buf;
+        q_end = buf + buf_size - 1;
+        while (q < q_end) {
+            c = *s++;
+            if (c == '\0')
+                break;
+            *q++ = c;
+        }
+        *q = '\0';
+    }
+    return buf;
+}
+
+/* strcat and truncate. */
+ST_FUNC char *pstrcat(char *buf, int buf_size, const char *s)
+{
+    int len;
+    len = strlen(buf);
+    if (len < buf_size)
+        pstrcpy(buf + len, buf_size - len, s);
+    return buf;
+}
+
+ST_FUNC char *pstrncpy(char *out, const char *in, size_t num)
+{
+    memcpy(out, in, num);
+    out[num] = '\0';
+    return out;
+}
+
+/* extract the basename of a file */
+PUB_FUNC char *tcc_basename(const char *name)
+{
+    char *p = strchr(name, 0);
+    while (p > name && !IS_DIRSEP(p[-1]))
+        --p;
+    return p;
+}
+
+/* extract extension part of a file
+ *
+ * (if no extension, return pointer to end-of-string)
+ */
+PUB_FUNC char *tcc_fileextension (const char *name)
+{
+    char *b = tcc_basename(name);
+    char *e = strrchr(b, '.');
+    return e ? e : strchr(b, 0);
+}
+
+/********************************************************/
+/* memory management */
+
+#undef free
+#undef malloc
+#undef realloc
+
+#ifndef MEM_DEBUG
+
+PUB_FUNC void tcc_free(void *ptr)
+{
+    free(ptr);
+}
+
+PUB_FUNC void *tcc_malloc(unsigned long size)
+{
+    void *ptr;
+    ptr = malloc(size);
+    if (!ptr && size)
+        tcc_error("memory full (malloc)");
+    return ptr;
+}
+
+PUB_FUNC void *tcc_mallocz(unsigned long size)
+{
+    void *ptr;
+    ptr = tcc_malloc(size);
+    memset(ptr, 0, size);
+    return ptr;
+}
+
+PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size)
+{
+    void *ptr1;
+    ptr1 = realloc(ptr, size);
+    if (!ptr1 && size)
+        tcc_error("memory full (realloc)");
+    return ptr1;
+}
+
+PUB_FUNC char *tcc_strdup(const char *str)
+{
+    char *ptr;
+    ptr = tcc_malloc(strlen(str) + 1);
+    strcpy(ptr, str);
+    return ptr;
+}
+
+PUB_FUNC void tcc_memcheck(void)
+{
+}
+
+#else
+
+#define MEM_DEBUG_MAGIC1 0xFEEDDEB1
+#define MEM_DEBUG_MAGIC2 0xFEEDDEB2
+#define MEM_DEBUG_MAGIC3 0xFEEDDEB3
+#define MEM_DEBUG_FILE_LEN 40
+#define MEM_DEBUG_CHECK3(header) \
+    ((mem_debug_header_t*)((char*)header + header->size))->magic3
+#define MEM_USER_PTR(header) \
+    ((char *)header + offsetof(mem_debug_header_t, magic3))
+#define MEM_HEADER_PTR(ptr) \
+    (mem_debug_header_t *)((char*)ptr - offsetof(mem_debug_header_t, magic3))
+
+struct mem_debug_header {
+    unsigned magic1;
+    unsigned size;
+    struct mem_debug_header *prev;
+    struct mem_debug_header *next;
+    int line_num;
+    char file_name[MEM_DEBUG_FILE_LEN + 1];
+    unsigned magic2;
+    ALIGNED(16) unsigned magic3;
+};
+
+typedef struct mem_debug_header mem_debug_header_t;
+
+static mem_debug_header_t *mem_debug_chain;
+static unsigned mem_cur_size;
+static unsigned mem_max_size;
+
+static mem_debug_header_t *malloc_check(void *ptr, const char *msg)
+{
+    mem_debug_header_t * header = MEM_HEADER_PTR(ptr);
+    if (header->magic1 != MEM_DEBUG_MAGIC1 ||
+        header->magic2 != MEM_DEBUG_MAGIC2 ||
+        MEM_DEBUG_CHECK3(header) != MEM_DEBUG_MAGIC3 ||
+        header->size == (unsigned)-1) {
+        fprintf(stderr, "%s check failed\n", msg);
+        if (header->magic1 == MEM_DEBUG_MAGIC1)
+            fprintf(stderr, "%s:%u: block allocated here.\n",
+                header->file_name, header->line_num);
+        exit(1);
+    }
+    return header;
+}
+
+PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line)
+{
+    int ofs;
+    mem_debug_header_t *header;
+
+    header = malloc(sizeof(mem_debug_header_t) + size);
+    if (!header)
+        tcc_error("memory full (malloc)");
+
+    header->magic1 = MEM_DEBUG_MAGIC1;
+    header->magic2 = MEM_DEBUG_MAGIC2;
+    header->size = size;
+    MEM_DEBUG_CHECK3(header) = MEM_DEBUG_MAGIC3;
+    header->line_num = line;
+    ofs = strlen(file) - MEM_DEBUG_FILE_LEN;
+    strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), MEM_DEBUG_FILE_LEN);
+    header->file_name[MEM_DEBUG_FILE_LEN] = 0;
+
+    header->next = mem_debug_chain;
+    header->prev = NULL;
+    if (header->next)
+        header->next->prev = header;
+    mem_debug_chain = header;
+
+    mem_cur_size += size;
+    if (mem_cur_size > mem_max_size)
+        mem_max_size = mem_cur_size;
+
+    return MEM_USER_PTR(header);
+}
+
+PUB_FUNC void tcc_free_debug(void *ptr)
+{
+    mem_debug_header_t *header;
+    if (!ptr)
+        return;
+    header = malloc_check(ptr, "tcc_free");
+    mem_cur_size -= header->size;
+    header->size = (unsigned)-1;
+    if (header->next)
+        header->next->prev = header->prev;
+    if (header->prev)
+        header->prev->next = header->next;
+    if (header == mem_debug_chain)
+        mem_debug_chain = header->next;
+    free(header);
+}
+
+PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line)
+{
+    void *ptr;
+    ptr = tcc_malloc_debug(size,file,line);
+    memset(ptr, 0, size);
+    return ptr;
+}
+
+PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line)
+{
+    mem_debug_header_t *header;
+    int mem_debug_chain_update = 0;
+    if (!ptr)
+        return tcc_malloc_debug(size, file, line);
+    header = malloc_check(ptr, "tcc_realloc");
+    mem_cur_size -= header->size;
+    mem_debug_chain_update = (header == mem_debug_chain);
+    header = realloc(header, sizeof(mem_debug_header_t) + size);
+    if (!header)
+        tcc_error("memory full (realloc)");
+    header->size = size;
+    MEM_DEBUG_CHECK3(header) = MEM_DEBUG_MAGIC3;
+    if (header->next)
+        header->next->prev = header;
+    if (header->prev)
+        header->prev->next = header;
+    if (mem_debug_chain_update)
+        mem_debug_chain = header;
+    mem_cur_size += size;
+    if (mem_cur_size > mem_max_size)
+        mem_max_size = mem_cur_size;
+    return MEM_USER_PTR(header);
+}
+
+PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line)
+{
+    char *ptr;
+    ptr = tcc_malloc_debug(strlen(str) + 1, file, line);
+    strcpy(ptr, str);
+    return ptr;
+}
+
+PUB_FUNC void tcc_memcheck(void)
+{
+    if (mem_cur_size) {
+        mem_debug_header_t *header = mem_debug_chain;
+        fprintf(stderr, "MEM_DEBUG: mem_leak= %d bytes, mem_max_size= %d bytes\n",
+            mem_cur_size, mem_max_size);
+        while (header) {
+            fprintf(stderr, "%s:%u: error: %u bytes leaked\n",
+                header->file_name, header->line_num, header->size);
+            header = header->next;
+        }
+#if MEM_DEBUG-0 == 2
+        exit(2);
+#endif
+    }
+}
+#endif /* MEM_DEBUG */
+
+#define free(p) use_tcc_free(p)
+#define malloc(s) use_tcc_malloc(s)
+#define realloc(p, s) use_tcc_realloc(p, s)
+
+/********************************************************/
+/* dynarrays */
+
+ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data)
+{
+    int nb, nb_alloc;
+    void **pp;
+
+    nb = *nb_ptr;
+    pp = *(void ***)ptab;
+    /* every power of two we double array size */
+    if ((nb & (nb - 1)) == 0) {
+        if (!nb)
+            nb_alloc = 1;
+        else
+            nb_alloc = nb * 2;
+        pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
+        *(void***)ptab = pp;
+    }
+    pp[nb++] = data;
+    *nb_ptr = nb;
+}
+
+ST_FUNC void dynarray_reset(void *pp, int *n)
+{
+    void **p;
+    for (p = *(void***)pp; *n; ++p, --*n)
+        if (*p)
+            tcc_free(*p);
+    tcc_free(*(void**)pp);
+    *(void**)pp = NULL;
+}
+
+static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *in)
+{
+    const char *p;
+    do {
+        int c;
+        CString str;
+
+        cstr_new(&str);
+        for (p = in; c = *p, c != '\0' && c != PATHSEP[0]; ++p) {
+            if (c == '{' && p[1] && p[2] == '}') {
+                c = p[1], p += 2;
+                if (c == 'B')
+                    cstr_cat(&str, s->tcc_lib_path, -1);
+            } else {
+                cstr_ccat(&str, c);
+            }
+        }
+        if (str.size) {
+            cstr_ccat(&str, '\0');
+            dynarray_add(p_ary, p_nb_ary, tcc_strdup(str.data));
+        }
+        cstr_free(&str);
+        in = p+1;
+    } while (*p);
+}
+
+/********************************************************/
+
+static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
+{
+    int len;
+    len = strlen(buf);
+    vsnprintf(buf + len, buf_size - len, fmt, ap);
+}
+
+static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    strcat_vprintf(buf, buf_size, fmt, ap);
+    va_end(ap);
+}
+
+static void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
+{
+    char buf[2048];
+    BufferedFile **pf, *f;
+
+    buf[0] = '\0';
+    /* use upper file if inline ":asm:" or token ":paste:" */
+    for (f = file; f && f->filename[0] == ':'; f = f->prev)
+     ;
+    if (f) {
+        for(pf = s1->include_stack; pf < s1->include_stack_ptr; pf++)
+            strcat_printf(buf, sizeof(buf), "In file included from %s:%d:\n",
+                (*pf)->filename, (*pf)->line_num);
+        if (s1->error_set_jmp_enabled) {
+            strcat_printf(buf, sizeof(buf), "%s:%d: ",
+                f->filename, f->line_num - !!(tok_flags & TOK_FLAG_BOL));
+        } else {
+            strcat_printf(buf, sizeof(buf), "%s: ",
+                f->filename);
+        }
+    } else {
+        strcat_printf(buf, sizeof(buf), "tcc: ");
+    }
+    if (is_warning)
+        strcat_printf(buf, sizeof(buf), "warning: ");
+    else
+        strcat_printf(buf, sizeof(buf), "error: ");
+    strcat_vprintf(buf, sizeof(buf), fmt, ap);
+
+    if (!s1->error_func) {
+        /* default case: stderr */
+        if (s1->output_type == TCC_OUTPUT_PREPROCESS && s1->ppfp == stdout)
+            /* print a newline during tcc -E */
+            printf("\n"), fflush(stdout);
+        fflush(stdout); /* flush -v output */
+        fprintf(stderr, "%s\n", buf);
+        fflush(stderr); /* print error/warning now (win32) */
+    } else {
+        s1->error_func(s1->error_opaque, buf);
+    }
+    if (!is_warning || s1->warn_error)
+        s1->nb_errors++;
+}
+
+LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque,
+                        void (*error_func)(void *opaque, const char *msg))
+{
+    s->error_opaque = error_opaque;
+    s->error_func = error_func;
+}
+
+/* error without aborting current compilation */
+PUB_FUNC void tcc_error_noabort(const char *fmt, ...)
+{
+    TCCState *s1 = tcc_state;
+    va_list ap;
+
+    va_start(ap, fmt);
+    error1(s1, 0, fmt, ap);
+    va_end(ap);
+}
+
+PUB_FUNC void tcc_error(const char *fmt, ...)
+{
+    TCCState *s1 = tcc_state;
+    va_list ap;
+
+    va_start(ap, fmt);
+    error1(s1, 0, fmt, ap);
+    va_end(ap);
+    /* better than nothing: in some cases, we accept to handle errors */
+    if (s1->error_set_jmp_enabled) {
+        longjmp(s1->error_jmp_buf, 1);
+    } else {
+        /* XXX: eliminate this someday */
+        exit(1);
+    }
+}
+
+PUB_FUNC void tcc_warning(const char *fmt, ...)
+{
+    TCCState *s1 = tcc_state;
+    va_list ap;
+
+    if (s1->warn_none)
+        return;
+
+    va_start(ap, fmt);
+    error1(s1, 1, fmt, ap);
+    va_end(ap);
+}
+
+/********************************************************/
+/* I/O layer */
+
+ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen)
+{
+    BufferedFile *bf;
+    int buflen = initlen ? initlen : IO_BUF_SIZE;
+
+    bf = tcc_mallocz(sizeof(BufferedFile) + buflen);
+    bf->buf_ptr = bf->buffer;
+    bf->buf_end = bf->buffer + initlen;
+    bf->buf_end[0] = CH_EOB; /* put eob symbol */
+    pstrcpy(bf->filename, sizeof(bf->filename), filename);
+    bf->true_filename = bf->filename;
+    bf->line_num = 1;
+    bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
+    bf->fd = -1;
+    bf->prev = file;
+    file = bf;
+    tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
+}
+
+ST_FUNC void tcc_close(void)
+{
+    BufferedFile *bf = file;
+    if (bf->fd > 0) {
+        close(bf->fd);
+        total_lines += bf->line_num;
+    }
+    if (bf->true_filename != bf->filename)
+        tcc_free(bf->true_filename);
+    file = bf->prev;
+    tcc_free(bf);
+}
+
+ST_FUNC int tcc_open(TCCState *s1, const char *filename)
+{
+    int fd;
+    if (strcmp(filename, "-") == 0)
+        fd = 0, filename = "<stdin>";
+    else
+        fd = open(filename, O_RDONLY | O_BINARY);
+    if ((s1->verbose == 2 && fd >= 0) || s1->verbose == 3)
+        printf("%s %*s%s\n", fd < 0 ? "nf":"->",
+               (int)(s1->include_stack_ptr - s1->include_stack), "", filename);
+    if (fd < 0)
+        return -1;
+    tcc_open_bf(s1, filename, 0);
+#ifdef _WIN32
+    normalize_slashes(file->filename);
+#endif
+    file->fd = fd;
+    return fd;
+}
+
+/* compile the file opened in 'file'. Return non zero if errors. */
+static int tcc_compile(TCCState *s1)
+{
+    Sym *define_start;
+    int filetype, is_asm;
+
+    define_start = define_stack;
+    filetype = s1->filetype;
+    is_asm = filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP;
+    tccelf_begin_file(s1);
+
+    if (setjmp(s1->error_jmp_buf) == 0) {
+        s1->nb_errors = 0;
+        s1->error_set_jmp_enabled = 1;
+
+        preprocess_start(s1, is_asm);
+        if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
+            tcc_preprocess(s1);
+        } else if (is_asm) {
+#ifdef CONFIG_TCC_ASM
+            tcc_assemble(s1, filetype == AFF_TYPE_ASMPP);
+#else
+            tcc_error_noabort("asm not supported");
+#endif
+        } else {
+            tccgen_compile(s1);
+        }
+    }
+    s1->error_set_jmp_enabled = 0;
+
+    preprocess_end(s1);
+    free_inline_functions(s1);
+    /* reset define stack, but keep -D and built-ins */
+    free_defines(define_start);
+    sym_pop(&global_stack, NULL, 0);
+    sym_pop(&local_stack, NULL, 0);
+    tccelf_end_file(s1);
+    return s1->nb_errors != 0 ? -1 : 0;
+}
+
+LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str)
+{
+    int len, ret;
+
+    len = strlen(str);
+    tcc_open_bf(s, "<string>", len);
+    memcpy(file->buffer, str, len);
+    ret = tcc_compile(s);
+    tcc_close();
+    return ret;
+}
+
+/* define a preprocessor symbol. A value can also be provided with the '=' operator */
+LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
+{
+    int len1, len2;
+    /* default value */
+    if (!value)
+        value = "1";
+    len1 = strlen(sym);
+    len2 = strlen(value);
+
+    /* init file structure */
+    tcc_open_bf(s1, "<define>", len1 + len2 + 1);
+    memcpy(file->buffer, sym, len1);
+    file->buffer[len1] = ' ';
+    memcpy(file->buffer + len1 + 1, value, len2);
+
+    /* parse with define parser */
+    next_nomacro();
+    parse_define();
+    tcc_close();
+}
+
+/* undefine a preprocessor symbol */
+LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym)
+{
+    TokenSym *ts;
+    Sym *s;
+    ts = tok_alloc(sym, strlen(sym));
+    s = define_find(ts->tok);
+    /* undefine symbol by putting an invalid name */
+    if (s)
+        define_undef(s);
+}
+
+/* cleanup all static data used during compilation */
+static void tcc_cleanup(void)
+{
+    if (NULL == tcc_state)
+        return;
+    while (file)
+        tcc_close();
+    tccpp_delete(tcc_state);
+    tcc_state = NULL;
+    /* free sym_pools */
+    dynarray_reset(&sym_pools, &nb_sym_pools);
+    /* reset symbol stack */
+    sym_free_first = NULL;
+}
+
+LIBTCCAPI TCCState *tcc_new(void)
+{
+    TCCState *s;
+
+    tcc_cleanup();
+
+    s = tcc_mallocz(sizeof(TCCState));
+    if (!s)
+        return NULL;
+    tcc_state = s;
+    ++nb_states;
+
+    s->alacarte_link = 1;
+    s->nocommon = 1;
+    s->warn_implicit_function_declaration = 1;
+    s->ms_extensions = 1;
+
+#ifdef CHAR_IS_UNSIGNED
+    s->char_is_unsigned = 1;
+#endif
+#ifdef TCC_TARGET_I386
+    s->seg_size = 32;
+#endif
+    /* enable this if you want symbols with leading underscore on windows: */
+#if 0 /* def TCC_TARGET_PE */
+    s->leading_underscore = 1;
+#endif
+#ifdef _WIN32
+    tcc_set_lib_path_w32(s);
+#else
+    tcc_set_lib_path(s, CONFIG_TCCDIR);
+#endif
+    tccelf_new(s);
+    tccpp_new(s);
+
+    /* we add dummy defines for some special macros to speed up tests
+       and to have working defined() */
+    define_push(TOK___LINE__, MACRO_OBJ, NULL, NULL);
+    define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
+    define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
+    define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
+    define_push(TOK___COUNTER__, MACRO_OBJ, NULL, NULL);
+    {
+        /* define __TINYC__ 92X  */
+        char buffer[32]; int a,b,c;
+        sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c);
+        sprintf(buffer, "%d", a*10000 + b*100 + c);
+        tcc_define_symbol(s, "__TINYC__", buffer);
+    }
+
+    /* standard defines */
+    tcc_define_symbol(s, "__STDC__", NULL);
+    tcc_define_symbol(s, "__STDC_VERSION__", "199901L");
+    tcc_define_symbol(s, "__STDC_HOSTED__", NULL);
+
+    /* target defines */
+#if defined(TCC_TARGET_I386)
+    tcc_define_symbol(s, "__i386__", NULL);
+    tcc_define_symbol(s, "__i386", NULL);
+    tcc_define_symbol(s, "i386", NULL);
+#elif defined(TCC_TARGET_X86_64)
+    tcc_define_symbol(s, "__x86_64__", NULL);
+#elif defined(TCC_TARGET_ARM)
+    tcc_define_symbol(s, "__ARM_ARCH_4__", NULL);
+    tcc_define_symbol(s, "__arm_elf__", NULL);
+    tcc_define_symbol(s, "__arm_elf", NULL);
+    tcc_define_symbol(s, "arm_elf", NULL);
+    tcc_define_symbol(s, "__arm__", NULL);
+    tcc_define_symbol(s, "__arm", NULL);
+    tcc_define_symbol(s, "arm", NULL);
+    tcc_define_symbol(s, "__APCS_32__", NULL);
+    tcc_define_symbol(s, "__ARMEL__", NULL);
+#if defined(TCC_ARM_EABI)
+    tcc_define_symbol(s, "__ARM_EABI__", NULL);
+#endif
+#if defined(TCC_ARM_HARDFLOAT)
+    s->float_abi = ARM_HARD_FLOAT;
+    tcc_define_symbol(s, "__ARM_PCS_VFP", NULL);
+#else
+    s->float_abi = ARM_SOFTFP_FLOAT;
+#endif
+#elif defined(TCC_TARGET_ARM64)
+    tcc_define_symbol(s, "__aarch64__", NULL);
+#elif defined TCC_TARGET_C67
+    tcc_define_symbol(s, "__C67__", NULL);
+#endif
+
+#ifdef TCC_TARGET_PE
+    tcc_define_symbol(s, "_WIN32", NULL);
+# ifdef TCC_TARGET_X86_64
+    tcc_define_symbol(s, "_WIN64", NULL);
+# endif
+#else
+    tcc_define_symbol(s, "__unix__", NULL);
+    tcc_define_symbol(s, "__unix", NULL);
+    tcc_define_symbol(s, "unix", NULL);
+# if defined(__linux__)
+    tcc_define_symbol(s, "__linux__", NULL);
+    tcc_define_symbol(s, "__linux", NULL);
+# endif
+# if defined(__FreeBSD__)
+    tcc_define_symbol(s, "__FreeBSD__", "__FreeBSD__");
+    /* No 'Thread Storage Local' on FreeBSD with tcc */
+    tcc_define_symbol(s, "__NO_TLS", NULL);
+# endif
+# if defined(__FreeBSD_kernel__)
+    tcc_define_symbol(s, "__FreeBSD_kernel__", NULL);
+# endif
+# if defined(__NetBSD__)
+    tcc_define_symbol(s, "__NetBSD__", "__NetBSD__");
+# endif
+# if defined(__OpenBSD__)
+    tcc_define_symbol(s, "__OpenBSD__", "__OpenBSD__");
+# endif
+#endif
+
+    /* TinyCC & gcc defines */
+#if PTR_SIZE == 4
+    /* 32bit systems. */
+    tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
+    tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
+    tcc_define_symbol(s, "__ILP32__", NULL);
+#elif LONG_SIZE == 4
+    /* 64bit Windows. */
+    tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long long");
+    tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long long");
+    tcc_define_symbol(s, "__LLP64__", NULL);
+#else
+    /* Other 64bit systems. */
+    tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long");
+    tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long");
+    tcc_define_symbol(s, "__LP64__", NULL);
+#endif
+
+#ifdef TCC_TARGET_PE
+    tcc_define_symbol(s, "__WCHAR_TYPE__", "unsigned short");
+    tcc_define_symbol(s, "__WINT_TYPE__", "unsigned short");
+#else
+    tcc_define_symbol(s, "__WCHAR_TYPE__", "int");
+    /* wint_t is unsigned int by default, but (signed) int on BSDs
+       and unsigned short on windows.  Other OSes might have still
+       other conventions, sigh.  */
+# if defined(__FreeBSD__) || defined (__FreeBSD_kernel__) \
+  || defined(__NetBSD__) || defined(__OpenBSD__)
+    tcc_define_symbol(s, "__WINT_TYPE__", "int");
+#  ifdef __FreeBSD__
+    /* define __GNUC__ to have some useful stuff from sys/cdefs.h
+       that are unconditionally used in FreeBSDs other system headers :/ */
+    tcc_define_symbol(s, "__GNUC__", "2");
+    tcc_define_symbol(s, "__GNUC_MINOR__", "7");
+    tcc_define_symbol(s, "__builtin_alloca", "alloca");
+#  endif
+# else
+    tcc_define_symbol(s, "__WINT_TYPE__", "unsigned int");
+    /* glibc defines */
+    tcc_define_symbol(s, "__REDIRECT(name, proto, alias)",
+        "name proto __asm__ (#alias)");
+    tcc_define_symbol(s, "__REDIRECT_NTH(name, proto, alias)",
+        "name proto __asm__ (#alias) __THROW");
+# endif
+# if defined(TCC_MUSL)
+    tcc_define_symbol(s, "__DEFINED_va_list", "");
+    tcc_define_symbol(s, "__DEFINED___isoc_va_list", "");
+    tcc_define_symbol(s, "__isoc_va_list", "void *");
+# endif /* TCC_MUSL */
+    /* Some GCC builtins that are simple to express as macros.  */
+    tcc_define_symbol(s, "__builtin_extract_return_addr(x)", "x");
+#endif /* ndef TCC_TARGET_PE */
+    return s;
+}
+
+LIBTCCAPI void tcc_delete(TCCState *s1)
+{
+    tcc_cleanup();
+
+    /* free sections */
+    tccelf_delete(s1);
+
+    /* free library paths */
+    dynarray_reset(&s1->library_paths, &s1->nb_library_paths);
+    dynarray_reset(&s1->crt_paths, &s1->nb_crt_paths);
+
+    /* free include paths */
+    dynarray_reset(&s1->cached_includes, &s1->nb_cached_includes);
+    dynarray_reset(&s1->include_paths, &s1->nb_include_paths);
+    dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths);
+    dynarray_reset(&s1->cmd_include_files, &s1->nb_cmd_include_files);
+
+    tcc_free(s1->tcc_lib_path);
+    tcc_free(s1->soname);
+    tcc_free(s1->rpath);
+    tcc_free(s1->init_symbol);
+    tcc_free(s1->fini_symbol);
+    tcc_free(s1->outfile);
+    tcc_free(s1->deps_outfile);
+    dynarray_reset(&s1->files, &s1->nb_files);
+    dynarray_reset(&s1->target_deps, &s1->nb_target_deps);
+    dynarray_reset(&s1->pragma_libs, &s1->nb_pragma_libs);
+    dynarray_reset(&s1->argv, &s1->argc);
+
+#ifdef TCC_IS_NATIVE
+    /* free runtime memory */
+    tcc_run_free(s1);
+#endif
+
+    tcc_free(s1);
+    if (0 == --nb_states)
+        tcc_memcheck();
+}
+
+LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
+{
+    s->output_type = output_type;
+
+    /* always elf for objects */
+    if (output_type == TCC_OUTPUT_OBJ)
+        s->output_format = TCC_OUTPUT_FORMAT_ELF;
+
+    if (s->char_is_unsigned)
+        tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL);
+
+    if (!s->nostdinc) {
+        /* default include paths */
+        /* -isystem paths have already been handled */
+        tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS);
+    }
+
+#ifdef CONFIG_TCC_BCHECK
+    if (s->do_bounds_check) {
+        /* if bound checking, then add corresponding sections */
+        tccelf_bounds_new(s);
+        /* define symbol */
+        tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
+    }
+#endif
+    if (s->do_debug) {
+        /* add debug sections */
+        tccelf_stab_new(s);
+    }
+
+    tcc_add_library_path(s, CONFIG_TCC_LIBPATHS);
+
+#ifdef TCC_TARGET_PE
+# ifdef _WIN32
+    if (!s->nostdlib && output_type != TCC_OUTPUT_OBJ)
+        tcc_add_systemdir(s);
+# endif
+#else
+    /* paths for crt objects */
+    tcc_split_path(s, &s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX);
+    /* add libc crt1/crti objects */
+    if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
+        !s->nostdlib) {
+        if (output_type != TCC_OUTPUT_DLL)
+            tcc_add_crt(s, "crt1.o");
+        tcc_add_crt(s, "crti.o");
+    }
+#endif
+    return 0;
+}
+
+LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname)
+{
+    tcc_split_path(s, &s->include_paths, &s->nb_include_paths, pathname);
+    return 0;
+}
+
+LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname)
+{
+    tcc_split_path(s, &s->sysinclude_paths, &s->nb_sysinclude_paths, pathname);
+    return 0;
+}
+
+ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
+{
+    int ret;
+
+    /* open the file */
+    ret = tcc_open(s1, filename);
+    if (ret < 0) {
+        if (flags & AFF_PRINT_ERROR)
+            tcc_error_noabort("file '%s' not found", filename);
+        return ret;
+    }
+
+    /* update target deps */
+    dynarray_add(&s1->target_deps, &s1->nb_target_deps,
+            tcc_strdup(filename));
+
+    if (flags & AFF_TYPE_BIN) {
+        ElfW(Ehdr) ehdr;
+        int fd, obj_type;
+
+        fd = file->fd;
+        obj_type = tcc_object_type(fd, &ehdr);
+        lseek(fd, 0, SEEK_SET);
+
+#ifdef TCC_TARGET_MACHO
+        if (0 == obj_type && 0 == strcmp(tcc_fileextension(filename), ".dylib"))
+            obj_type = AFF_BINTYPE_DYN;
+#endif
+
+        switch (obj_type) {
+        case AFF_BINTYPE_REL:
+            ret = tcc_load_object_file(s1, fd, 0);
+            break;
+#ifndef TCC_TARGET_PE
+        case AFF_BINTYPE_DYN:
+            if (s1->output_type == TCC_OUTPUT_MEMORY) {
+                ret = 0;
+#ifdef TCC_IS_NATIVE
+                if (NULL == dlopen(filename, RTLD_GLOBAL | RTLD_LAZY))
+                    ret = -1;
+#endif
+            } else {
+                ret = tcc_load_dll(s1, fd, filename,
+                                   (flags & AFF_REFERENCED_DLL) != 0);
+            }
+            break;
+#endif
+        case AFF_BINTYPE_AR:
+            ret = tcc_load_archive(s1, fd);
+            break;
+#ifdef TCC_TARGET_COFF
+        case AFF_BINTYPE_C67:
+            ret = tcc_load_coff(s1, fd);
+            break;
+#endif
+        default:
+#ifdef TCC_TARGET_PE
+            ret = pe_load_file(s1, filename, fd);
+#else
+            /* as GNU ld, consider it is an ld script if not recognized */
+            ret = tcc_load_ldscript(s1);
+#endif
+            if (ret < 0)
+                tcc_error_noabort("unrecognized file type");
+            break;
+        }
+    } else {
+        ret = tcc_compile(s1);
+    }
+    tcc_close();
+    return ret;
+}
+
+LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
+{
+    int filetype = s->filetype;
+    int flags = AFF_PRINT_ERROR;
+    if (filetype == 0) {
+        /* use a file extension to detect a filetype */
+        const char *ext = tcc_fileextension(filename);
+        if (ext[0]) {
+            ext++;
+            if (!strcmp(ext, "S"))
+                filetype = AFF_TYPE_ASMPP;
+            else if (!strcmp(ext, "s"))
+                filetype = AFF_TYPE_ASM;
+            else if (!PATHCMP(ext, "c") || !PATHCMP(ext, "i"))
+                filetype = AFF_TYPE_C;
+            else
+                flags |= AFF_TYPE_BIN;
+        } else {
+            filetype = AFF_TYPE_C;
+        }
+        s->filetype = filetype;
+    }
+    return tcc_add_file_internal(s, filename, flags);
+}
+
+LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
+{
+    tcc_split_path(s, &s->library_paths, &s->nb_library_paths, pathname);
+    return 0;
+}
+
+static int tcc_add_library_internal(TCCState *s, const char *fmt,
+    const char *filename, int flags, char **paths, int nb_paths)
+{
+    char buf[1024];
+    int i;
+
+    for(i = 0; i < nb_paths; i++) {
+        snprintf(buf, sizeof(buf), fmt, paths[i], filename);
+        if (tcc_add_file_internal(s, buf, flags | AFF_TYPE_BIN) == 0)
+            return 0;
+    }
+    return -1;
+}
+
+/* find and load a dll. Return non zero if not found */
+/* XXX: add '-rpath' option support ? */
+ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags)
+{
+    return tcc_add_library_internal(s, "%s/%s", filename, flags,
+        s->library_paths, s->nb_library_paths);
+}
+
+ST_FUNC int tcc_add_crt(TCCState *s, const char *filename)
+{
+    if (-1 == tcc_add_library_internal(s, "%s/%s",
+        filename, 0, s->crt_paths, s->nb_crt_paths))
+        tcc_error_noabort("file '%s' not found", filename);
+    return 0;
+}
+
+/* the library name is the same as the argument of the '-l' option */
+LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
+{
+#if defined TCC_TARGET_PE
+    const char *libs[] = { "%s/%s.def", "%s/lib%s.def", "%s/%s.dll", "%s/lib%s.dll", "%s/lib%s.a", NULL };
+    const char **pp = s->static_link ? libs + 4 : libs;
+#elif defined TCC_TARGET_MACHO
+    const char *libs[] = { "%s/lib%s.dylib", "%s/lib%s.a", NULL };
+    const char **pp = s->static_link ? libs + 1 : libs;
+#else
+    const char *libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL };
+    const char **pp = s->static_link ? libs + 1 : libs;
+#endif
+    while (*pp) {
+        if (0 == tcc_add_library_internal(s, *pp,
+            libraryname, 0, s->library_paths, s->nb_library_paths))
+            return 0;
+        ++pp;
+    }
+    return -1;
+}
+
+PUB_FUNC int tcc_add_library_err(TCCState *s, const char *libname)
+{
+    int ret = tcc_add_library(s, libname);
+    if (ret < 0)
+        tcc_error_noabort("library '%s' not found", libname);
+    return ret;
+}
+
+/* handle #pragma comment(lib,) */
+ST_FUNC void tcc_add_pragma_libs(TCCState *s1)
+{
+    int i;
+    for (i = 0; i < s1->nb_pragma_libs; i++)
+        tcc_add_library_err(s1, s1->pragma_libs[i]);
+}
+
+LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val)
+{
+#ifdef TCC_TARGET_PE
+    /* On x86_64 'val' might not be reachable with a 32bit offset.
+       So it is handled here as if it were in a DLL. */
+    pe_putimport(s, 0, name, (uintptr_t)val);
+#else
+    set_elf_sym(symtab_section, (uintptr_t)val, 0,
+        ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+        SHN_ABS, name);
+#endif
+    return 0;
+}
+
+LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path)
+{
+    tcc_free(s->tcc_lib_path);
+    s->tcc_lib_path = tcc_strdup(path);
+}
+
+#define WD_ALL    0x0001 /* warning is activated when using -Wall */
+#define FD_INVERT 0x0002 /* invert value before storing */
+
+typedef struct FlagDef {
+    uint16_t offset;
+    uint16_t flags;
+    const char *name;
+} FlagDef;
+
+static int no_flag(const char **pp)
+{
+    const char *p = *pp;
+    if (*p != 'n' || *++p != 'o' || *++p != '-')
+        return 0;
+    *pp = p + 1;
+    return 1;
+}
+
+ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, const char *name)
+{
+    int value, ret;
+    const FlagDef *p;
+    const char *r;
+
+    value = 1;
+    r = name;
+    if (no_flag(&r))
+        value = 0;
+
+    for (ret = -1, p = flags; p->name; ++p) {
+        if (ret) {
+            if (strcmp(r, p->name))
+                continue;
+        } else {
+            if (0 == (p->flags & WD_ALL))
+                continue;
+        }
+        if (p->offset) {
+            *(int*)((char *)s + p->offset) =
+                p->flags & FD_INVERT ? !value : value;
+            if (ret)
+                return 0;
+        } else {
+            ret = 0;
+        }
+    }
+    return ret;
+}
+
+static int strstart(const char *val, const char **str)
+{
+    const char *p, *q;
+    p = *str;
+    q = val;
+    while (*q) {
+        if (*p != *q)
+            return 0;
+        p++;
+        q++;
+    }
+    *str = p;
+    return 1;
+}
+
+/* Like strstart, but automatically takes into account that ld options can
+ *
+ * - start with double or single dash (e.g. '--soname' or '-soname')
+ * - arguments can be given as separate or after '=' (e.g. '-Wl,-soname,x.so'
+ *   or '-Wl,-soname=x.so')
+ *
+ * you provide `val` always in 'option[=]' form (no leading -)
+ */
+static int link_option(const char *str, const char *val, const char **ptr)
+{
+    const char *p, *q;
+    int ret;
+
+    /* there should be 1 or 2 dashes */
+    if (*str++ != '-')
+        return 0;
+    if (*str == '-')
+        str++;
+
+    /* then str & val should match (potentially up to '=') */
+    p = str;
+    q = val;
+
+    ret = 1;
+    if (q[0] == '?') {
+        ++q;
+        if (no_flag(&p))
+            ret = -1;
+    }
+
+    while (*q != '\0' && *q != '=') {
+        if (*p != *q)
+            return 0;
+        p++;
+        q++;
+    }
+
+    /* '=' near eos means ',' or '=' is ok */
+    if (*q == '=') {
+        if (*p == 0)
+            *ptr = p;
+        if (*p != ',' && *p != '=')
+            return 0;
+        p++;
+    } else if (*p) {
+        return 0;
+    }
+    *ptr = p;
+    return ret;
+}
+
+static const char *skip_linker_arg(const char **str)
+{
+    const char *s1 = *str;
+    const char *s2 = strchr(s1, ',');
+    *str = s2 ? s2++ : (s2 = s1 + strlen(s1));
+    return s2;
+}
+
+static void copy_linker_arg(char **pp, const char *s, int sep)
+{
+    const char *q = s;
+    char *p = *pp;
+    int l = 0;
+    if (p && sep)
+        p[l = strlen(p)] = sep, ++l;
+    skip_linker_arg(&q);
+    pstrncpy(l + (*pp = tcc_realloc(p, q - s + l + 1)), s, q - s);
+}
+
+/* set linker options */
+static int tcc_set_linker(TCCState *s, const char *option)
+{
+    while (*option) {
+
+        const char *p = NULL;
+        char *end = NULL;
+        int ignoring = 0;
+        int ret;
+
+        if (link_option(option, "Bsymbolic", &p)) {
+            s->symbolic = 1;
+        } else if (link_option(option, "nostdlib", &p)) {
+            s->nostdlib = 1;
+        } else if (link_option(option, "fini=", &p)) {
+            copy_linker_arg(&s->fini_symbol, p, 0);
+            ignoring = 1;
+        } else if (link_option(option, "image-base=", &p)
+                || link_option(option, "Ttext=", &p)) {
+            s->text_addr = strtoull(p, &end, 16);
+            s->has_text_addr = 1;
+        } else if (link_option(option, "init=", &p)) {
+            copy_linker_arg(&s->init_symbol, p, 0);
+            ignoring = 1;
+        } else if (link_option(option, "oformat=", &p)) {
+#if defined(TCC_TARGET_PE)
+            if (strstart("pe-", &p)) {
+#elif PTR_SIZE == 8
+            if (strstart("elf64-", &p)) {
+#else
+            if (strstart("elf32-", &p)) {
+#endif
+                s->output_format = TCC_OUTPUT_FORMAT_ELF;
+            } else if (!strcmp(p, "binary")) {
+                s->output_format = TCC_OUTPUT_FORMAT_BINARY;
+#ifdef TCC_TARGET_COFF
+            } else if (!strcmp(p, "coff")) {
+                s->output_format = TCC_OUTPUT_FORMAT_COFF;
+#endif
+            } else
+                goto err;
+
+        } else if (link_option(option, "as-needed", &p)) {
+            ignoring = 1;
+        } else if (link_option(option, "O", &p)) {
+            ignoring = 1;
+        } else if (link_option(option, "export-all-symbols", &p)) {
+            s->rdynamic = 1;
+        } else if (link_option(option, "rpath=", &p)) {
+            copy_linker_arg(&s->rpath, p, ':');
+        } else if (link_option(option, "enable-new-dtags", &p)) {
+            s->enable_new_dtags = 1;
+        } else if (link_option(option, "section-alignment=", &p)) {
+            s->section_align = strtoul(p, &end, 16);
+        } else if (link_option(option, "soname=", &p)) {
+            copy_linker_arg(&s->soname, p, 0);
+#ifdef TCC_TARGET_PE
+        } else if (link_option(option, "large-address-aware", &p)) {
+            s->pe_characteristics |= 0x20;
+        } else if (link_option(option, "file-alignment=", &p)) {
+            s->pe_file_align = strtoul(p, &end, 16);
+        } else if (link_option(option, "stack=", &p)) {
+            s->pe_stack_size = strtoul(p, &end, 10);
+        } else if (link_option(option, "subsystem=", &p)) {
+#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
+            if (!strcmp(p, "native")) {
+                s->pe_subsystem = 1;
+            } else if (!strcmp(p, "console")) {
+                s->pe_subsystem = 3;
+            } else if (!strcmp(p, "gui") || !strcmp(p, "windows")) {
+                s->pe_subsystem = 2;
+            } else if (!strcmp(p, "posix")) {
+                s->pe_subsystem = 7;
+            } else if (!strcmp(p, "efiapp")) {
+                s->pe_subsystem = 10;
+            } else if (!strcmp(p, "efiboot")) {
+                s->pe_subsystem = 11;
+            } else if (!strcmp(p, "efiruntime")) {
+                s->pe_subsystem = 12;
+            } else if (!strcmp(p, "efirom")) {
+                s->pe_subsystem = 13;
+#elif defined(TCC_TARGET_ARM)
+            if (!strcmp(p, "wince")) {
+                s->pe_subsystem = 9;
+#endif
+            } else
+                goto err;
+#endif
+        } else if (ret = link_option(option, "?whole-archive", &p), ret) {
+            s->alacarte_link = ret < 0;
+        } else if (p) {
+            return 0;
+        } else {
+    err:
+            tcc_error("unsupported linker option '%s'", option);
+        }
+
+        if (ignoring && s->warn_unsupported)
+            tcc_warning("unsupported linker option '%s'", option);
+
+        option = skip_linker_arg(&p);
+    }
+    return 1;
+}
+
+typedef struct TCCOption {
+    const char *name;
+    uint16_t index;
+    uint16_t flags;
+} TCCOption;
+
+enum {
+    TCC_OPTION_HELP,
+    TCC_OPTION_HELP2,
+    TCC_OPTION_v,
+    TCC_OPTION_I,
+    TCC_OPTION_D,
+    TCC_OPTION_U,
+    TCC_OPTION_P,
+    TCC_OPTION_L,
+    TCC_OPTION_B,
+    TCC_OPTION_l,
+    TCC_OPTION_bench,
+    TCC_OPTION_bt,
+    TCC_OPTION_b,
+    TCC_OPTION_g,
+    TCC_OPTION_c,
+    TCC_OPTION_dumpversion,
+    TCC_OPTION_d,
+    TCC_OPTION_static,
+    TCC_OPTION_std,
+    TCC_OPTION_shared,
+    TCC_OPTION_soname,
+    TCC_OPTION_o,
+    TCC_OPTION_r,
+    TCC_OPTION_s,
+    TCC_OPTION_traditional,
+    TCC_OPTION_Wl,
+    TCC_OPTION_Wp,
+    TCC_OPTION_W,
+    TCC_OPTION_O,
+    TCC_OPTION_mfloat_abi,
+    TCC_OPTION_m,
+    TCC_OPTION_f,
+    TCC_OPTION_isystem,
+    TCC_OPTION_iwithprefix,
+    TCC_OPTION_include,
+    TCC_OPTION_nostdinc,
+    TCC_OPTION_nostdlib,
+    TCC_OPTION_print_search_dirs,
+    TCC_OPTION_rdynamic,
+    TCC_OPTION_param,
+    TCC_OPTION_pedantic,
+    TCC_OPTION_pthread,
+    TCC_OPTION_run,
+    TCC_OPTION_w,
+    TCC_OPTION_pipe,
+    TCC_OPTION_E,
+    TCC_OPTION_MD,
+    TCC_OPTION_MF,
+    TCC_OPTION_x,
+    TCC_OPTION_ar,
+    TCC_OPTION_impdef
+};
+
+#define TCC_OPTION_HAS_ARG 0x0001
+#define TCC_OPTION_NOSEP   0x0002 /* cannot have space before option and arg */
+
+static const TCCOption tcc_options[] = {
+    { "h", TCC_OPTION_HELP, 0 },
+    { "-help", TCC_OPTION_HELP, 0 },
+    { "?", TCC_OPTION_HELP, 0 },
+    { "hh", TCC_OPTION_HELP2, 0 },
+    { "v", TCC_OPTION_v, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "I", TCC_OPTION_I, TCC_OPTION_HAS_ARG },
+    { "D", TCC_OPTION_D, TCC_OPTION_HAS_ARG },
+    { "U", TCC_OPTION_U, TCC_OPTION_HAS_ARG },
+    { "P", TCC_OPTION_P, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "L", TCC_OPTION_L, TCC_OPTION_HAS_ARG },
+    { "B", TCC_OPTION_B, TCC_OPTION_HAS_ARG },
+    { "l", TCC_OPTION_l, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "bench", TCC_OPTION_bench, 0 },
+#ifdef CONFIG_TCC_BACKTRACE
+    { "bt", TCC_OPTION_bt, TCC_OPTION_HAS_ARG },
+#endif
+#ifdef CONFIG_TCC_BCHECK
+    { "b", TCC_OPTION_b, 0 },
+#endif
+    { "g", TCC_OPTION_g, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "c", TCC_OPTION_c, 0 },
+    { "dumpversion", TCC_OPTION_dumpversion, 0},
+    { "d", TCC_OPTION_d, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "static", TCC_OPTION_static, 0 },
+    { "std", TCC_OPTION_std, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "shared", TCC_OPTION_shared, 0 },
+    { "soname", TCC_OPTION_soname, TCC_OPTION_HAS_ARG },
+    { "o", TCC_OPTION_o, TCC_OPTION_HAS_ARG },
+    { "-param", TCC_OPTION_param, TCC_OPTION_HAS_ARG },
+    { "pedantic", TCC_OPTION_pedantic, 0},
+    { "pthread", TCC_OPTION_pthread, 0},
+    { "run", TCC_OPTION_run, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "rdynamic", TCC_OPTION_rdynamic, 0 },
+    { "r", TCC_OPTION_r, 0 },
+    { "s", TCC_OPTION_s, 0 },
+    { "traditional", TCC_OPTION_traditional, 0 },
+    { "Wl,", TCC_OPTION_Wl, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "Wp,", TCC_OPTION_Wp, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "W", TCC_OPTION_W, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "O", TCC_OPTION_O, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+#ifdef TCC_TARGET_ARM
+    { "mfloat-abi", TCC_OPTION_mfloat_abi, TCC_OPTION_HAS_ARG },
+#endif
+    { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
+    { "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG },
+    { "include", TCC_OPTION_include, TCC_OPTION_HAS_ARG },
+    { "nostdinc", TCC_OPTION_nostdinc, 0 },
+    { "nostdlib", TCC_OPTION_nostdlib, 0 },
+    { "print-search-dirs", TCC_OPTION_print_search_dirs, 0 },
+    { "w", TCC_OPTION_w, 0 },
+    { "pipe", TCC_OPTION_pipe, 0},
+    { "E", TCC_OPTION_E, 0},
+    { "MD", TCC_OPTION_MD, 0},
+    { "MF", TCC_OPTION_MF, TCC_OPTION_HAS_ARG },
+    { "x", TCC_OPTION_x, TCC_OPTION_HAS_ARG },
+    { "ar", TCC_OPTION_ar, 0},
+#ifdef TCC_TARGET_PE
+    { "impdef", TCC_OPTION_impdef, 0},
+#endif
+    { NULL, 0, 0 },
+};
+
+static const FlagDef options_W[] = {
+    { 0, 0, "all" },
+    { offsetof(TCCState, warn_unsupported), 0, "unsupported" },
+    { offsetof(TCCState, warn_write_strings), 0, "write-strings" },
+    { offsetof(TCCState, warn_error), 0, "error" },
+    { offsetof(TCCState, warn_gcc_compat), 0, "gcc-compat" },
+    { offsetof(TCCState, warn_implicit_function_declaration), WD_ALL,
+      "implicit-function-declaration" },
+    { 0, 0, NULL }
+};
+
+static const FlagDef options_f[] = {
+    { offsetof(TCCState, char_is_unsigned), 0, "unsigned-char" },
+    { offsetof(TCCState, char_is_unsigned), FD_INVERT, "signed-char" },
+    { offsetof(TCCState, nocommon), FD_INVERT, "common" },
+    { offsetof(TCCState, leading_underscore), 0, "leading-underscore" },
+    { offsetof(TCCState, ms_extensions), 0, "ms-extensions" },
+    { offsetof(TCCState, dollars_in_identifiers), 0, "dollars-in-identifiers" },
+    { 0, 0, NULL }
+};
+
+static const FlagDef options_m[] = {
+    { offsetof(TCCState, ms_bitfields), 0, "ms-bitfields" },
+#ifdef TCC_TARGET_X86_64
+    { offsetof(TCCState, nosse), FD_INVERT, "sse" },
+#endif
+    { 0, 0, NULL }
+};
+
+static void parse_option_D(TCCState *s1, const char *optarg)
+{
+    char *sym = tcc_strdup(optarg);
+    char *value = strchr(sym, '=');
+    if (value)
+        *value++ = '\0';
+    tcc_define_symbol(s1, sym, value);
+    tcc_free(sym);
+}
+
+static void args_parser_add_file(TCCState *s, const char* filename, int filetype)
+{
+    struct filespec *f = tcc_malloc(sizeof *f + strlen(filename));
+    f->type = filetype;
+    f->alacarte = s->alacarte_link;
+    strcpy(f->name, filename);
+    dynarray_add(&s->files, &s->nb_files, f);
+}
+
+static int args_parser_make_argv(const char *r, int *argc, char ***argv)
+{
+    int ret = 0, q, c;
+    CString str;
+    for(;;) {
+        while (c = (unsigned char)*r, c && c <= ' ')
+	    ++r;
+        if (c == 0)
+            break;
+        q = 0;
+        cstr_new(&str);
+        while (c = (unsigned char)*r, c) {
+            ++r;
+            if (c == '\\' && (*r == '"' || *r == '\\')) {
+                c = *r++;
+            } else if (c == '"') {
+                q = !q;
+                continue;
+            } else if (q == 0 && c <= ' ') {
+                break;
+            }
+            cstr_ccat(&str, c);
+        }
+        cstr_ccat(&str, 0);
+        //printf("<%s>\n", str.data), fflush(stdout);
+        dynarray_add(argv, argc, tcc_strdup(str.data));
+        cstr_free(&str);
+        ++ret;
+    }
+    return ret;
+}
+
+/* read list file */
+static void args_parser_listfile(TCCState *s,
+    const char *filename, int optind, int *pargc, char ***pargv)
+{
+    int fd, i;
+    size_t len;
+    char *p;
+    int argc = 0;
+    char **argv = NULL;
+
+    fd = open(filename, O_RDONLY | O_BINARY);
+    if (fd < 0)
+        tcc_error("listfile '%s' not found", filename);
+
+    len = lseek(fd, 0, SEEK_END);
+    p = tcc_malloc(len + 1), p[len] = 0;
+    lseek(fd, 0, SEEK_SET), read(fd, p, len), close(fd);
+
+    for (i = 0; i < *pargc; ++i)
+        if (i == optind)
+            args_parser_make_argv(p, &argc, &argv);
+        else
+            dynarray_add(&argv, &argc, tcc_strdup((*pargv)[i]));
+
+    tcc_free(p);
+    dynarray_reset(&s->argv, &s->argc);
+    *pargc = s->argc = argc, *pargv = s->argv = argv;
+}
+
+PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind)
+{
+    const TCCOption *popt;
+    const char *optarg, *r;
+    const char *run = NULL;
+    int last_o = -1;
+    int x;
+    CString linker_arg; /* collect -Wl options */
+    int tool = 0, arg_start = 0, noaction = optind;
+    char **argv = *pargv;
+    int argc = *pargc;
+
+    cstr_new(&linker_arg);
+
+    while (optind < argc) {
+        r = argv[optind];
+        if (r[0] == '@' && r[1] != '\0') {
+            args_parser_listfile(s, r + 1, optind, &argc, &argv);
+	    continue;
+        }
+        optind++;
+        if (tool) {
+            if (r[0] == '-' && r[1] == 'v' && r[2] == 0)
+                ++s->verbose;
+            continue;
+        }
+reparse:
+        if (r[0] != '-' || r[1] == '\0') {
+            if (r[0] != '@') /* allow "tcc file(s) -run @ args ..." */
+                args_parser_add_file(s, r, s->filetype);
+            if (run) {
+                tcc_set_options(s, run);
+                arg_start = optind - 1;
+                break;
+            }
+            continue;
+        }
+
+        /* find option in table */
+        for(popt = tcc_options; ; ++popt) {
+            const char *p1 = popt->name;
+            const char *r1 = r + 1;
+            if (p1 == NULL)
+                tcc_error("invalid option -- '%s'", r);
+            if (!strstart(p1, &r1))
+                continue;
+            optarg = r1;
+            if (popt->flags & TCC_OPTION_HAS_ARG) {
+                if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) {
+                    if (optind >= argc)
+                arg_err:
+                        tcc_error("argument to '%s' is missing", r);
+                    optarg = argv[optind++];
+                }
+            } else if (*r1 != '\0')
+                continue;
+            break;
+        }
+
+        switch(popt->index) {
+        case TCC_OPTION_HELP:
+            return OPT_HELP;
+        case TCC_OPTION_HELP2:
+            return OPT_HELP2;
+        case TCC_OPTION_I:
+            tcc_add_include_path(s, optarg);
+            break;
+        case TCC_OPTION_D:
+            parse_option_D(s, optarg);
+            break;
+        case TCC_OPTION_U:
+            tcc_undefine_symbol(s, optarg);
+            break;
+        case TCC_OPTION_L:
+            tcc_add_library_path(s, optarg);
+            break;
+        case TCC_OPTION_B:
+            /* set tcc utilities path (mainly for tcc development) */
+            tcc_set_lib_path(s, optarg);
+            break;
+        case TCC_OPTION_l:
+            args_parser_add_file(s, optarg, AFF_TYPE_LIB);
+            s->nb_libraries++;
+            break;
+        case TCC_OPTION_pthread:
+            parse_option_D(s, "_REENTRANT");
+            s->option_pthread = 1;
+            break;
+        case TCC_OPTION_bench:
+            s->do_bench = 1;
+            break;
+#ifdef CONFIG_TCC_BACKTRACE
+        case TCC_OPTION_bt:
+            tcc_set_num_callers(atoi(optarg));
+            break;
+#endif
+#ifdef CONFIG_TCC_BCHECK
+        case TCC_OPTION_b:
+            s->do_bounds_check = 1;
+            s->do_debug = 1;
+            break;
+#endif
+        case TCC_OPTION_g:
+            s->do_debug = 1;
+            break;
+        case TCC_OPTION_c:
+            x = TCC_OUTPUT_OBJ;
+        set_output_type:
+            if (s->output_type)
+                tcc_warning("-%s: overriding compiler action already specified", popt->name);
+            s->output_type = x;
+            break;
+        case TCC_OPTION_d:
+            if (*optarg == 'D')
+                s->dflag = 3;
+            else if (*optarg == 'M')
+                s->dflag = 7;
+            else if (*optarg == 't')
+                s->dflag = 16;
+            else if (isnum(*optarg))
+                g_debug = atoi(optarg);
+            else
+                goto unsupported_option;
+            break;
+        case TCC_OPTION_static:
+            s->static_link = 1;
+            break;
+        case TCC_OPTION_std:
+    	    /* silently ignore, a current purpose:
+    	       allow to use a tcc as a reference compiler for "make test" */
+            break;
+        case TCC_OPTION_shared:
+            x = TCC_OUTPUT_DLL;
+            goto set_output_type;
+        case TCC_OPTION_soname:
+            s->soname = tcc_strdup(optarg);
+            break;
+        case TCC_OPTION_o:
+            if (s->outfile) {
+                tcc_warning("multiple -o option");
+                tcc_free(s->outfile);
+            }
+            s->outfile = tcc_strdup(optarg);
+            break;
+        case TCC_OPTION_r:
+            /* generate a .o merging several output files */
+            s->option_r = 1;
+            x = TCC_OUTPUT_OBJ;
+            goto set_output_type;
+        case TCC_OPTION_isystem:
+            tcc_add_sysinclude_path(s, optarg);
+            break;
+	case TCC_OPTION_include:
+	    dynarray_add(&s->cmd_include_files,
+			 &s->nb_cmd_include_files, tcc_strdup(optarg));
+	    break;
+        case TCC_OPTION_nostdinc:
+            s->nostdinc = 1;
+            break;
+        case TCC_OPTION_nostdlib:
+            s->nostdlib = 1;
+            break;
+        case TCC_OPTION_run:
+#ifndef TCC_IS_NATIVE
+            tcc_error("-run is not available in a cross compiler");
+#endif
+            run = optarg;
+            x = TCC_OUTPUT_MEMORY;
+            goto set_output_type;
+        case TCC_OPTION_v:
+            do ++s->verbose; while (*optarg++ == 'v');
+            ++noaction;
+            break;
+        case TCC_OPTION_f:
+            if (set_flag(s, options_f, optarg) < 0)
+                goto unsupported_option;
+            break;
+#ifdef TCC_TARGET_ARM
+        case TCC_OPTION_mfloat_abi:
+            /* tcc doesn't support soft float yet */
+            if (!strcmp(optarg, "softfp")) {
+                s->float_abi = ARM_SOFTFP_FLOAT;
+                tcc_undefine_symbol(s, "__ARM_PCS_VFP");
+            } else if (!strcmp(optarg, "hard"))
+                s->float_abi = ARM_HARD_FLOAT;
+            else
+                tcc_error("unsupported float abi '%s'", optarg);
+            break;
+#endif
+        case TCC_OPTION_m:
+            if (set_flag(s, options_m, optarg) < 0) {
+                if (x = atoi(optarg), x != 32 && x != 64)
+                    goto unsupported_option;
+                if (PTR_SIZE != x/8)
+                    return x;
+                ++noaction;
+            }
+            break;
+        case TCC_OPTION_W:
+            if (set_flag(s, options_W, optarg) < 0)
+                goto unsupported_option;
+            break;
+        case TCC_OPTION_w:
+            s->warn_none = 1;
+            break;
+        case TCC_OPTION_rdynamic:
+            s->rdynamic = 1;
+            break;
+        case TCC_OPTION_Wl:
+            if (linker_arg.size)
+                --linker_arg.size, cstr_ccat(&linker_arg, ',');
+            cstr_cat(&linker_arg, optarg, 0);
+            if (tcc_set_linker(s, linker_arg.data))
+                cstr_free(&linker_arg);
+            break;
+	case TCC_OPTION_Wp:
+	    r = optarg;
+	    goto reparse;
+        case TCC_OPTION_E:
+            x = TCC_OUTPUT_PREPROCESS;
+            goto set_output_type;
+        case TCC_OPTION_P:
+            s->Pflag = atoi(optarg) + 1;
+            break;
+        case TCC_OPTION_MD:
+            s->gen_deps = 1;
+            break;
+        case TCC_OPTION_MF:
+            s->deps_outfile = tcc_strdup(optarg);
+            break;
+        case TCC_OPTION_dumpversion:
+            printf ("%s\n", TCC_VERSION);
+            exit(0);
+            break;
+        case TCC_OPTION_x:
+            if (*optarg == 'c')
+                s->filetype = AFF_TYPE_C;
+            else if (*optarg == 'a')
+                s->filetype = AFF_TYPE_ASMPP;
+            else if (*optarg == 'n')
+                s->filetype = AFF_TYPE_NONE;
+            else
+                tcc_warning("unsupported language '%s'", optarg);
+            break;
+        case TCC_OPTION_O:
+            last_o = atoi(optarg);
+            break;
+        case TCC_OPTION_print_search_dirs:
+            x = OPT_PRINT_DIRS;
+            goto extra_action;
+        case TCC_OPTION_impdef:
+            x = OPT_IMPDEF;
+            goto extra_action;
+        case TCC_OPTION_ar:
+            x = OPT_AR;
+        extra_action:
+            arg_start = optind - 1;
+            if (arg_start != noaction)
+                tcc_error("cannot parse %s here", r);
+            tool = x;
+            break;
+        case TCC_OPTION_traditional:
+        case TCC_OPTION_pedantic:
+        case TCC_OPTION_pipe:
+        case TCC_OPTION_s:
+            /* ignored */
+            break;
+        default:
+unsupported_option:
+            if (s->warn_unsupported)
+                tcc_warning("unsupported option '%s'", r);
+            break;
+        }
+    }
+    if (last_o > 0)
+        tcc_define_symbol(s, "__OPTIMIZE__", NULL);
+    if (linker_arg.size) {
+        r = linker_arg.data;
+        goto arg_err;
+    }
+    *pargc = argc - arg_start;
+    *pargv = argv + arg_start;
+    if (tool)
+        return tool;
+    if (optind != noaction)
+        return 0;
+    if (s->verbose == 2)
+        return OPT_PRINT_DIRS;
+    if (s->verbose)
+        return OPT_V;
+    return OPT_HELP;
+}
+
+LIBTCCAPI void tcc_set_options(TCCState *s, const char *r)
+{
+    char **argv = NULL;
+    int argc = 0;
+    args_parser_make_argv(r, &argc, &argv);
+    tcc_parse_args(s, &argc, &argv, 0);
+    dynarray_reset(&argv, &argc);
+}
+
+PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time)
+{
+    if (total_time < 1)
+        total_time = 1;
+    if (total_bytes < 1)
+        total_bytes = 1;
+    fprintf(stderr, "* %d idents, %d lines, %d bytes\n"
+                    "* %0.3f s, %u lines/s, %0.1f MB/s\n",
+           tok_ident - TOK_IDENT, total_lines, total_bytes,
+           (double)total_time/1000,
+           (unsigned)total_lines*1000/total_time,
+           (double)total_bytes/1000/total_time);
+#ifdef MEM_DEBUG
+    fprintf(stderr, "* %d bytes memory used\n", mem_max_size);
+#endif
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/libtcc.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/libtcc.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/libtcc.h	(revision 331)
@@ -0,0 +1,100 @@
+#ifndef LIBTCC_H
+#define LIBTCC_H
+
+#ifndef LIBTCCAPI
+# define LIBTCCAPI
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct TCCState;
+
+typedef struct TCCState TCCState;
+
+/* create a new TCC compilation context */
+LIBTCCAPI TCCState *tcc_new(void);
+
+/* free a TCC compilation context */
+LIBTCCAPI void tcc_delete(TCCState *s);
+
+/* set CONFIG_TCCDIR at runtime */
+LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path);
+
+/* set error/warning display callback */
+LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque,
+    void (*error_func)(void *opaque, const char *msg));
+
+/* set options as from command line (multiple supported) */
+LIBTCCAPI void tcc_set_options(TCCState *s, const char *str);
+
+/*****************************/
+/* preprocessor */
+
+/* add include path */
+LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname);
+
+/* add in system include path */
+LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname);
+
+/* define preprocessor symbol 'sym'. Can put optional value */
+LIBTCCAPI void tcc_define_symbol(TCCState *s, const char *sym, const char *value);
+
+/* undefine preprocess symbol 'sym' */
+LIBTCCAPI void tcc_undefine_symbol(TCCState *s, const char *sym);
+
+/*****************************/
+/* compiling */
+
+/* add a file (C file, dll, object, library, ld script). Return -1 if error. */
+LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename);
+
+/* compile a string containing a C source. Return -1 if error. */
+LIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf);
+
+/*****************************/
+/* linking commands */
+
+/* set output type. MUST BE CALLED before any compilation */
+LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type);
+#define TCC_OUTPUT_MEMORY   1 /* output will be run in memory (default) */
+#define TCC_OUTPUT_EXE      2 /* executable file */
+#define TCC_OUTPUT_DLL      3 /* dynamic library */
+#define TCC_OUTPUT_OBJ      4 /* object file */
+#define TCC_OUTPUT_PREPROCESS 5 /* only preprocess (used internally) */
+
+/* equivalent to -Lpath option */
+LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname);
+
+/* the library name is the same as the argument of the '-l' option */
+LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname);
+
+/* add a symbol to the compiled program */
+LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val);
+
+/* output an executable, library or object file. DO NOT call
+   tcc_relocate() before. */
+LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename);
+
+/* link and run main() function and return its value. DO NOT call
+   tcc_relocate() before. */
+LIBTCCAPI int tcc_run(TCCState *s, int argc, char **argv);
+
+/* do all relocations (needed before using tcc_get_symbol()) */
+LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr);
+/* possible values for 'ptr':
+   - TCC_RELOCATE_AUTO : Allocate and manage memory internally
+   - NULL              : return required memory size for the step below
+   - memory address    : copy code to memory passed by the caller
+   returns -1 if error. */
+#define TCC_RELOCATE_AUTO (void*)1
+
+/* return symbol value or NULL if not found */
+LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: EcnlProtoTool/trunk/tcc-0.9.27/stab.def
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/stab.def	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/stab.def	(revision 331)
@@ -0,0 +1,236 @@
+/* Table of DBX symbol codes for the GNU system.
+   Copyright (C) 1988, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* This contains contribution from Cygnus Support.  */
+
+
+/* Global variable.  Only the name is significant.
+   To find the address, look in the corresponding external symbol.  */
+__define_stab (N_GSYM, 0x20, "GSYM")
+
+/* Function name for BSD Fortran.  Only the name is significant.
+   To find the address, look in the corresponding external symbol.  */
+__define_stab (N_FNAME, 0x22, "FNAME")
+
+/* Function name or text-segment variable for C.  Value is its address.
+   Desc is supposedly starting line number, but GCC doesn't set it
+   and DBX seems not to miss it.  */
+__define_stab (N_FUN, 0x24, "FUN")
+
+/* Data-segment variable with internal linkage.  Value is its address.
+   "Static Sym".  */
+__define_stab (N_STSYM, 0x26, "STSYM")
+
+/* BSS-segment variable with internal linkage.  Value is its address.  */
+__define_stab (N_LCSYM, 0x28, "LCSYM")
+
+/* Name of main routine.  Only the name is significant.
+   This is not used in C.  */
+__define_stab (N_MAIN, 0x2a, "MAIN")
+
+/* Global symbol in Pascal.
+   Supposedly the value is its line number; I'm skeptical.  */
+__define_stab (N_PC, 0x30, "PC")
+
+/* Number of symbols:  0, files,,funcs,lines according to Ultrix V4.0. */
+__define_stab (N_NSYMS, 0x32, "NSYMS")
+
+/* "No DST map for sym: name, ,0,type,ignored"  according to Ultrix V4.0. */
+__define_stab (N_NOMAP, 0x34, "NOMAP")
+
+/* New stab from Solaris.  I don't know what it means, but it
+   don't seem to contain useful information.  */
+__define_stab (N_OBJ, 0x38, "OBJ")
+
+/* New stab from Solaris.  I don't know what it means, but it
+   don't seem to contain useful information.  Possibly related to the
+   optimization flags used in this module.  */
+__define_stab (N_OPT, 0x3c, "OPT")
+
+/* Register variable.  Value is number of register.  */
+__define_stab (N_RSYM, 0x40, "RSYM")
+
+/* Modula-2 compilation unit.  Can someone say what info it contains?  */
+__define_stab (N_M2C, 0x42, "M2C")
+
+/* Line number in text segment.  Desc is the line number;
+   value is corresponding address.  */
+__define_stab (N_SLINE, 0x44, "SLINE")
+
+/* Similar, for data segment.  */
+__define_stab (N_DSLINE, 0x46, "DSLINE")
+
+/* Similar, for bss segment.  */
+__define_stab (N_BSLINE, 0x48, "BSLINE")
+
+/* Sun's source-code browser stabs.  ?? Don't know what the fields are.
+   Supposedly the field is "path to associated .cb file".  THIS VALUE
+   OVERLAPS WITH N_BSLINE!  */
+__define_stab (N_BROWS, 0x48, "BROWS")
+
+/* GNU Modula-2 definition module dependency.  Value is the modification time
+   of the definition file.  Other is non-zero if it is imported with the
+   GNU M2 keyword %INITIALIZE.  Perhaps N_M2C can be used if there
+   are enough empty fields? */
+__define_stab(N_DEFD, 0x4a, "DEFD")
+
+/* THE FOLLOWING TWO STAB VALUES CONFLICT.  Happily, one is for Modula-2
+   and one is for C++.   Still,... */
+/* GNU C++ exception variable.  Name is variable name.  */
+__define_stab (N_EHDECL, 0x50, "EHDECL")
+/* Modula2 info "for imc":  name,,0,0,0  according to Ultrix V4.0.  */
+__define_stab (N_MOD2, 0x50, "MOD2")
+
+/* GNU C++ `catch' clause.  Value is its address.  Desc is nonzero if
+   this entry is immediately followed by a CAUGHT stab saying what exception
+   was caught.  Multiple CAUGHT stabs means that multiple exceptions
+   can be caught here.  If Desc is 0, it means all exceptions are caught
+   here.  */
+__define_stab (N_CATCH, 0x54, "CATCH")
+
+/* Structure or union element.  Value is offset in the structure.  */
+__define_stab (N_SSYM, 0x60, "SSYM")
+
+/* Name of main source file.
+   Value is starting text address of the compilation.  */
+__define_stab (N_SO, 0x64, "SO")
+
+/* Automatic variable in the stack.  Value is offset from frame pointer.
+   Also used for type descriptions.  */
+__define_stab (N_LSYM, 0x80, "LSYM")
+
+/* Beginning of an include file.  Only Sun uses this.
+   In an object file, only the name is significant.
+   The Sun linker puts data into some of the other fields.  */
+__define_stab (N_BINCL, 0x82, "BINCL")
+
+/* Name of sub-source file (#include file).
+   Value is starting text address of the compilation.  */
+__define_stab (N_SOL, 0x84, "SOL")
+
+/* Parameter variable.  Value is offset from argument pointer.
+   (On most machines the argument pointer is the same as the frame pointer.  */
+__define_stab (N_PSYM, 0xa0, "PSYM")
+
+/* End of an include file.  No name.
+   This and N_BINCL act as brackets around the file's output.
+   In an object file, there is no significant data in this entry.
+   The Sun linker puts data into some of the fields.  */
+__define_stab (N_EINCL, 0xa2, "EINCL")
+
+/* Alternate entry point.  Value is its address.  */
+__define_stab (N_ENTRY, 0xa4, "ENTRY")
+
+/* Beginning of lexical block.
+   The desc is the nesting level in lexical blocks.
+   The value is the address of the start of the text for the block.
+   The variables declared inside the block *precede* the N_LBRAC symbol.  */
+__define_stab (N_LBRAC, 0xc0, "LBRAC")
+
+/* Place holder for deleted include file.  Replaces a N_BINCL and everything
+   up to the corresponding N_EINCL.  The Sun linker generates these when
+   it finds multiple identical copies of the symbols from an include file.
+   This appears only in output from the Sun linker.  */
+__define_stab (N_EXCL, 0xc2, "EXCL")
+
+/* Modula-2 scope information.  Can someone say what info it contains?  */
+__define_stab (N_SCOPE, 0xc4, "SCOPE")
+
+/* End of a lexical block.  Desc matches the N_LBRAC's desc.
+   The value is the address of the end of the text for the block.  */
+__define_stab (N_RBRAC, 0xe0, "RBRAC")
+
+/* Begin named common block.  Only the name is significant.  */
+__define_stab (N_BCOMM, 0xe2, "BCOMM")
+
+/* End named common block.  Only the name is significant
+   (and it should match the N_BCOMM).  */
+__define_stab (N_ECOMM, 0xe4, "ECOMM")
+
+/* End common (local name): value is address.
+   I'm not sure how this is used.  */
+__define_stab (N_ECOML, 0xe8, "ECOML")
+
+/* These STAB's are used on Gould systems for Non-Base register symbols
+   or something like that.  FIXME.  I have assigned the values at random
+   since I don't have a Gould here.  Fixups from Gould folk welcome... */
+__define_stab (N_NBTEXT, 0xF0, "NBTEXT")
+__define_stab (N_NBDATA, 0xF2, "NBDATA")
+__define_stab (N_NBBSS,  0xF4, "NBBSS")
+__define_stab (N_NBSTS,  0xF6, "NBSTS")
+__define_stab (N_NBLCS,  0xF8, "NBLCS")
+
+/* Second symbol entry containing a length-value for the preceding entry.
+   The value is the length.  */
+__define_stab (N_LENG, 0xfe, "LENG")
+
+
+/* The above information, in matrix format.
+
+			STAB MATRIX
+	_________________________________________________
+	| 00 - 1F are not dbx stab symbols		|
+	| In most cases, the low bit is the EXTernal bit|
+
+	| 00 UNDEF  | 02 ABS	| 04 TEXT   | 06 DATA	|
+	| 01  |EXT  | 03  |EXT	| 05  |EXT  | 07  |EXT	|
+
+	| 08 BSS    | 0A INDR	| 0C FN_SEQ | 0E   	|
+	| 09  |EXT  | 0B 	| 0D	    | 0F	|
+
+	| 10 	    | 12 COMM	| 14 SETA   | 16 SETT	|
+	| 11	    | 13	| 15 	    | 17	|
+
+	| 18 SETD   | 1A SETB	| 1C SETV   | 1E WARNING|
+	| 19	    | 1B	| 1D 	    | 1F FN	|
+
+	|_______________________________________________|
+	| Debug entries with bit 01 set are unused.	|
+	| 20 GSYM   | 22 FNAME	| 24 FUN    | 26 STSYM	|
+	| 28 LCSYM  | 2A MAIN	| 2C	    | 2E	|
+	| 30 PC	    | 32 NSYMS	| 34 NOMAP  | 36	|
+	| 38 OBJ    | 3A	| 3C OPT    | 3E	|
+	| 40 RSYM   | 42 M2C	| 44 SLINE  | 46 DSLINE |
+	| 48 BSLINE*| 4A DEFD	| 4C        | 4E	|
+	| 50 EHDECL*| 52	| 54 CATCH  | 56        |
+	| 58        | 5A        | 5C        | 5E	|
+	| 60 SSYM   | 62	| 64 SO	    | 66 	|
+	| 68 	    | 6A	| 6C	    | 6E	|
+	| 70	    | 72	| 74	    | 76	|
+	| 78	    | 7A	| 7C	    | 7E	|
+	| 80 LSYM   | 82 BINCL	| 84 SOL    | 86	|
+	| 88	    | 8A	| 8C	    | 8E	|
+	| 90	    | 92	| 94	    | 96	|
+	| 98	    | 9A	| 9C	    | 9E	|
+	| A0 PSYM   | A2 EINCL	| A4 ENTRY  | A6	|
+	| A8	    | AA	| AC	    | AE	|
+	| B0	    | B2	| B4	    | B6	|
+	| B8	    | BA	| BC	    | BE	|
+	| C0 LBRAC  | C2 EXCL	| C4 SCOPE  | C6	|
+	| C8	    | CA	| CC	    | CE	|
+	| D0	    | D2	| D4	    | D6	|
+	| D8	    | DA	| DC	    | DE	|
+	| E0 RBRAC  | E2 BCOMM	| E4 ECOMM  | E6	|
+	| E8 ECOML  | EA	| EC	    | EE	|
+	| F0	    | F2	| F4	    | F6	|
+	| F8	    | FA	| FC	    | FE LENG	|
+	+-----------------------------------------------+
+ * 50 EHDECL is also MOD2.
+ * 48 BSLINE is also BROWS.
+ */
Index: EcnlProtoTool/trunk/tcc-0.9.27/stab.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/stab.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/stab.h	(revision 331)
@@ -0,0 +1,17 @@
+#ifndef __GNU_STAB__
+
+/* Indicate the GNU stab.h is in use.  */
+
+#define __GNU_STAB__
+
+#define __define_stab(NAME, CODE, STRING) NAME=CODE,
+
+enum __stab_debug_code
+{
+#include "stab.def"
+LAST_UNUSED_STAB_CODE
+};
+
+#undef __define_stab
+
+#endif /* __GNU_STAB_ */
Index: EcnlProtoTool/trunk/tcc-0.9.27/tcc-doc.html
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tcc-doc.html	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tcc-doc.html	(revision 331)
@@ -0,0 +1,2490 @@
+<HTML>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<!-- Created on December, 17  2017 by texi2html 1.64 -->
+<!-- 
+Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author)
+			Karl Berry  <karl@freefriends.org>
+			Olaf Bachmann <obachman@mathematik.uni-kl.de>
+			and many others.
+Maintained by: Olaf Bachmann <obachman@mathematik.uni-kl.de>
+Send bugs and suggestions to <texi2html@mathematik.uni-kl.de>
+ 
+-->
+<HEAD>
+<TITLE>Tiny C Compiler Reference Documentation: </TITLE>
+
+<META NAME="description" CONTENT="Tiny C Compiler Reference Documentation: ">
+<META NAME="keywords" CONTENT="Tiny C Compiler Reference Documentation: ">
+<META NAME="resource-type" CONTENT="document">
+<META NAME="distribution" CONTENT="global">
+<META NAME="Generator" CONTENT="texi2html 1.64">
+
+</HEAD>
+
+<BODY LANG="" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
+
+<A NAME="SEC_Top"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1>Tiny C Compiler Reference Documentation</H1></P><P>
+
+This manual documents version 0.9.27
+ of the Tiny C Compiler.
+</P><P>
+
+<BLOCKQUOTE><TABLE BORDER=0 CELLSPACING=0> 
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC1">1. Introduction</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Introduction to tcc.</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC2">2. Command line invocation</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Invocation of tcc (command line, options).</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC5">3. C language support</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">ANSI C and extensions.</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC10">4. TinyCC Assembler</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Assembler syntax.</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC16">5. TinyCC Linker</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Output file generation and supported targets.</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Automatic bounds-checking of C code.</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC22">7. The <CODE>libtcc</CODE> library</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">The libtcc library.</TD></TR>
+<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="tcc-doc.html#SEC23">8. Developer's guide</A></TD><TD>&nbsp;&nbsp;</TD><TD ALIGN="left" VALIGN="TOP">Guide for Developers.</TD></TR>
+</TABLE></BLOCKQUOTE>
+<P>
+
+<HR SIZE=1>
+<A NAME="SEC1"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<A NAME="Introduction"></A>
+<H1> 1. Introduction </H1>
+<!--docid::SEC1::-->
+<P>
+
+TinyCC (aka TCC) is a small but hyper fast C compiler. Unlike other C
+compilers, it is meant to be self-relying: you do not need an
+external assembler or linker because TCC does that for you.
+</P><P>
+
+TCC compiles so <EM>fast</EM> that even for big projects <CODE>Makefile</CODE>s may
+not be necessary.
+</P><P>
+
+TCC not only supports ANSI C, but also most of the new ISO C99
+standard and many GNUC extensions including inline assembly.
+</P><P>
+
+TCC can also be used to make <EM>C scripts</EM>, i.e. pieces of C source
+that you run as a Perl or Python script. Compilation is so fast that
+your script will be as fast as if it was an executable.
+</P><P>
+
+TCC can also automatically generate memory and bound checks
+(see section <A HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A>) while allowing all C pointers operations. TCC can do
+these checks even if non patched libraries are used.
+</P><P>
+
+With <CODE>libtcc</CODE>, you can use TCC as a backend for dynamic code
+generation (see section <A HREF="tcc-doc.html#SEC22">7. The <CODE>libtcc</CODE> library</A>).
+</P><P>
+
+TCC mainly supports the i386 target on Linux and Windows. There are alpha
+ports for the ARM (<CODE>arm-tcc</CODE>) and the TMS320C67xx targets
+(<CODE>c67-tcc</CODE>). More information about the ARM port is available at
+<A HREF="http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html">http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html</A>.
+</P><P>
+
+For usage on Windows, see also <A HREF="tcc-win32.txt">tcc-win32.txt</A>.
+</P><P>
+
+<A NAME="Invoke"></A>
+<HR SIZE="6">
+<A NAME="SEC2"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC1"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC3"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 2. Command line invocation </H1>
+<!--docid::SEC2::-->
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC3"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC4"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 2.1 Quick start </H2>
+<!--docid::SEC3::-->
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>usage: tcc [options] [<VAR>infile1</VAR> <VAR>infile2</VAR><small>...</small>] [<SAMP>`-run'</SAMP> <VAR>infile</VAR> <VAR>args</VAR><small>...</small>]
+</pre></td></tr></table></P><P>
+
+TCC options are a very much like gcc options. The main difference is that TCC
+can also execute directly the resulting program and give it runtime
+arguments.
+</P><P>
+
+Here are some examples to understand the logic:
+</P><P>
+
+<DL COMPACT>
+<DT><CODE><SAMP>`tcc -run a.c'</SAMP></CODE>
+<DD>Compile <TT>`a.c'</TT> and execute it directly
+<P>
+
+<DT><CODE><SAMP>`tcc -run a.c arg1'</SAMP></CODE>
+<DD>Compile a.c and execute it directly. arg1 is given as first argument to
+the <CODE>main()</CODE> of a.c.
+<P>
+
+<DT><CODE><SAMP>`tcc a.c -run b.c arg1'</SAMP></CODE>
+<DD>Compile <TT>`a.c'</TT> and <TT>`b.c'</TT>, link them together and execute them. arg1 is given
+as first argument to the <CODE>main()</CODE> of the resulting program. 
+<P>
+
+<DT><CODE><SAMP>`tcc -o myprog a.c b.c'</SAMP></CODE>
+<DD>Compile <TT>`a.c'</TT> and <TT>`b.c'</TT>, link them and generate the executable <TT>`myprog'</TT>.
+<P>
+
+<DT><CODE><SAMP>`tcc -o myprog a.o b.o'</SAMP></CODE>
+<DD>link <TT>`a.o'</TT> and <TT>`b.o'</TT> together and generate the executable <TT>`myprog'</TT>.
+<P>
+
+<DT><CODE><SAMP>`tcc -c a.c'</SAMP></CODE>
+<DD>Compile <TT>`a.c'</TT> and generate object file <TT>`a.o'</TT>.
+<P>
+
+<DT><CODE><SAMP>`tcc -c asmfile.S'</SAMP></CODE>
+<DD>Preprocess with C preprocess and assemble <TT>`asmfile.S'</TT> and generate
+object file <TT>`asmfile.o'</TT>.
+<P>
+
+<DT><CODE><SAMP>`tcc -c asmfile.s'</SAMP></CODE>
+<DD>Assemble (but not preprocess) <TT>`asmfile.s'</TT> and generate object file
+<TT>`asmfile.o'</TT>.
+<P>
+
+<DT><CODE><SAMP>`tcc -r -o ab.o a.c b.c'</SAMP></CODE>
+<DD>Compile <TT>`a.c'</TT> and <TT>`b.c'</TT>, link them together and generate the object file <TT>`ab.o'</TT>.
+<P>
+
+</DL>
+<P>
+
+Scripting:
+</P><P>
+
+TCC can be invoked from <EM>scripts</EM>, just as shell scripts. You just
+need to add <CODE>#!/usr/local/bin/tcc -run</CODE> at the start of your C source:
+</P><P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>#!/usr/local/bin/tcc -run
+#include &#60;stdio.h&#62;
+
+int main() 
+{
+    printf("Hello World\n");
+    return 0;
+}
+</pre></td></tr></table></P><P>
+
+TCC can read C source code from <EM>standard input</EM> when <SAMP>`-'</SAMP> is used in 
+place of <SAMP>`infile'</SAMP>. Example:
+</P><P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>echo 'main(){puts("hello");}' | tcc -run -
+</pre></td></tr></table></P><P>
+
+<HR SIZE="6">
+<A NAME="SEC4"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC3"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC2"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 2.2 Option summary </H2>
+<!--docid::SEC4::-->
+<P>
+
+General Options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-c'</SAMP>
+<DD>Generate an object file.
+<P>
+
+<DT><SAMP>`-o outfile'</SAMP>
+<DD>Put object file, executable, or dll into output file <TT>`outfile'</TT>.
+<P>
+
+<DT><SAMP>`-run source [args...]'</SAMP>
+<DD>Compile file <VAR>source</VAR> and run it with the command line arguments
+<VAR>args</VAR>. In order to be able to give more than one argument to a
+script, several TCC options can be given <EM>after</EM> the
+<SAMP>`-run'</SAMP> option, separated by spaces:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>tcc "-run -L/usr/X11R6/lib -lX11" ex4.c
+</pre></td></tr></table>In a script, it gives the following header:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
+</pre></td></tr></table><P>
+
+<DT><SAMP>`-v'</SAMP>
+<DD>Display TCC version.
+<P>
+
+<DT><SAMP>`-vv'</SAMP>
+<DD>Show included files.  As sole argument, print search dirs.  -vvv shows tries too.
+<P>
+
+<DT><SAMP>`-bench'</SAMP>
+<DD>Display compilation statistics.
+<P>
+
+</DL>
+<P>
+
+Preprocessor options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-Idir'</SAMP>
+<DD>Specify an additional include path. Include paths are searched in the
+order they are specified.
+<P>
+
+System include paths are always searched after. The default system
+include paths are: <TT>`/usr/local/include'</TT>, <TT>`/usr/include'</TT>
+and <TT>`PREFIX/lib/tcc/include'</TT>. (<TT>`PREFIX'</TT> is usually
+<TT>`/usr'</TT> or <TT>`/usr/local'</TT>).
+</P><P>
+
+<DT><SAMP>`-Dsym[=val]'</SAMP>
+<DD>Define preprocessor symbol <SAMP>`sym'</SAMP> to
+val. If val is not present, its value is <SAMP>`1'</SAMP>. Function-like macros can
+also be defined: <SAMP>`-DF(a)=a+1'</SAMP>
+<P>
+
+<DT><SAMP>`-Usym'</SAMP>
+<DD>Undefine preprocessor symbol <SAMP>`sym'</SAMP>.
+<P>
+
+<DT><SAMP>`-E'</SAMP>
+<DD>Preprocess only, to stdout or file (with -o).
+<P>
+
+</DL>
+<P>
+
+Compilation flags:
+</P><P>
+
+Note: each of the following options has a negative form beginning with
+<SAMP>`-fno-'</SAMP>.
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-funsigned-char'</SAMP>
+<DD>Let the <CODE>char</CODE> type be unsigned.
+<P>
+
+<DT><SAMP>`-fsigned-char'</SAMP>
+<DD>Let the <CODE>char</CODE> type be signed.
+<P>
+
+<DT><SAMP>`-fno-common'</SAMP>
+<DD>Do not generate common symbols for uninitialized data.
+<P>
+
+<DT><SAMP>`-fleading-underscore'</SAMP>
+<DD>Add a leading underscore at the beginning of each C symbol.
+<P>
+
+<DT><SAMP>`-fms-extensions'</SAMP>
+<DD>Allow a MS C compiler extensions to the language. Currently this
+assumes a nested named structure declaration without an identifier
+behaves like an unnamed one.
+<P>
+
+<DT><SAMP>`-fdollars-in-identifiers'</SAMP>
+<DD>Allow dollar signs in identifiers
+<P>
+
+</DL>
+<P>
+
+Warning options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-w'</SAMP>
+<DD>Disable all warnings.
+<P>
+
+</DL>
+<P>
+
+Note: each of the following warning options has a negative form beginning with
+<SAMP>`-Wno-'</SAMP>.
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-Wimplicit-function-declaration'</SAMP>
+<DD>Warn about implicit function declaration.
+<P>
+
+<DT><SAMP>`-Wunsupported'</SAMP>
+<DD>Warn about unsupported GCC features that are ignored by TCC.
+<P>
+
+<DT><SAMP>`-Wwrite-strings'</SAMP>
+<DD>Make string constants be of type <CODE>const char *</CODE> instead of <CODE>char
+*</CODE>.
+<P>
+
+<DT><SAMP>`-Werror'</SAMP>
+<DD>Abort compilation if warnings are issued.
+<P>
+
+<DT><SAMP>`-Wall'</SAMP>
+<DD>Activate all warnings, except <SAMP>`-Werror'</SAMP>, <SAMP>`-Wunusupported'</SAMP> and
+<SAMP>`-Wwrite-strings'</SAMP>.
+<P>
+
+</DL>
+<P>
+
+Linker options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-Ldir'</SAMP>
+<DD>Specify an additional static library path for the <SAMP>`-l'</SAMP> option. The
+default library paths are <TT>`/usr/local/lib'</TT>, <TT>`/usr/lib'</TT> and <TT>`/lib'</TT>.
+<P>
+
+<DT><SAMP>`-lxxx'</SAMP>
+<DD>Link your program with dynamic library libxxx.so or static library
+libxxx.a. The library is searched in the paths specified by the
+<SAMP>`-L'</SAMP> option and <CODE>LIBRARY_PATH</CODE> variable.
+<P>
+
+<DT><SAMP>`-Bdir'</SAMP>
+<DD>Set the path where the tcc internal libraries (and include files) can be
+found (default is <TT>`PREFIX/lib/tcc'</TT>).
+<P>
+
+<DT><SAMP>`-shared'</SAMP>
+<DD>Generate a shared library instead of an executable.
+<P>
+
+<DT><SAMP>`-soname name'</SAMP>
+<DD>set name for shared library to be used at runtime
+<P>
+
+<DT><SAMP>`-static'</SAMP>
+<DD>Generate a statically linked executable (default is a shared linked
+executable).
+<P>
+
+<DT><SAMP>`-rdynamic'</SAMP>
+<DD>Export global symbols to the dynamic linker. It is useful when a library
+opened with <CODE>dlopen()</CODE> needs to access executable symbols.
+<P>
+
+<DT><SAMP>`-r'</SAMP>
+<DD>Generate an object file combining all input files.
+<P>
+
+<DT><SAMP>`-Wl,-rpath=path'</SAMP>
+<DD>Put custom search path for dynamic libraries into executable.
+<P>
+
+<DT><SAMP>`-Wl,--enable-new-dtags'</SAMP>
+<DD>When putting a custom search path for dynamic libraries into the executable,
+create the new ELF dynamic tag DT_RUNPATH instead of the old legacy DT_RPATH.
+<P>
+
+<DT><SAMP>`-Wl,--oformat=fmt'</SAMP>
+<DD>Use <VAR>fmt</VAR> as output format. The supported output formats are:
+<DL COMPACT>
+<DT><CODE>elf32-i386</CODE>
+<DD>ELF output format (default)
+<DT><CODE>binary</CODE>
+<DD>Binary image (only for executable output)
+<DT><CODE>coff</CODE>
+<DD>COFF output format (only for executable output for TMS320C67xx target)
+</DL>
+<P>
+
+<DT><SAMP>`-Wl,-subsystem=console/gui/wince/...'</SAMP>
+<DD>Set type for PE (Windows) executables.
+<P>
+
+<DT><SAMP>`-Wl,-[Ttext=# | section-alignment=# | file-alignment=# | image-base=# | stack=#]'</SAMP>
+<DD>Modify executable layout.
+<P>
+
+<DT><SAMP>`-Wl,-Bsymbolic'</SAMP>
+<DD>Set DT_SYMBOLIC tag.
+<P>
+
+<DT><SAMP>`-Wl,-(no-)whole-archive'</SAMP>
+<DD>Turn on/off linking of all objects in archives.
+<P>
+
+</DL>
+<P>
+
+Debugger options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-g'</SAMP>
+<DD>Generate run time debug information so that you get clear run time
+error messages: <CODE> test.c:68: in function 'test5()': dereferencing
+invalid pointer</CODE> instead of the laconic <CODE>Segmentation
+fault</CODE>.
+<P>
+
+<DT><SAMP>`-b'</SAMP>
+<DD>Generate additional support code to check
+memory allocations and array/pointer bounds. <SAMP>`-g'</SAMP> is implied. Note
+that the generated code is slower and bigger in this case.
+<P>
+
+Note: <SAMP>`-b'</SAMP> is only available on i386 when using libtcc for the moment.
+</P><P>
+
+<DT><SAMP>`-bt N'</SAMP>
+<DD>Display N callers in stack traces. This is useful with <SAMP>`-g'</SAMP> or
+<SAMP>`-b'</SAMP>.
+<P>
+
+</DL>
+<P>
+
+Misc options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-MD'</SAMP>
+<DD>Generate makefile fragment with dependencies.
+<P>
+
+<DT><SAMP>`-MF depfile'</SAMP>
+<DD>Use <TT>`depfile'</TT> as output for -MD.
+<P>
+
+<DT><SAMP>`-print-search-dirs'</SAMP>
+<DD>Print the configured installation directory and a list of library
+and include directories tcc will search.
+<P>
+
+<DT><SAMP>`-dumpversion'</SAMP>
+<DD>Print version.
+<P>
+
+</DL>
+<P>
+
+Target specific options:
+</P><P>
+
+<DL COMPACT>
+<DT><SAMP>`-mms-bitfields'</SAMP>
+<DD>Use an algorithm for bitfield alignment consistent with MSVC. Default is
+gcc's algorithm.
+<P>
+
+<DT><SAMP>`-mfloat-abi (ARM only)'</SAMP>
+<DD>Select the float ABI. Possible values: <CODE>softfp</CODE> and <CODE>hard</CODE>
+<P>
+
+<DT><SAMP>`-mno-sse'</SAMP>
+<DD>Do not use sse registers on x86_64
+<P>
+
+<DT><SAMP>`-m32, -m64'</SAMP>
+<DD>Pass command line to the i386/x86_64 cross compiler.
+<P>
+
+</DL>
+<P>
+
+Note: GCC options <SAMP>`-Ox'</SAMP>, <SAMP>`-fx'</SAMP> and <SAMP>`-mx'</SAMP> are
+ignored.
+</P><P>
+
+Environment variables that affect how tcc operates.
+</P><P>
+
+<DL COMPACT>
+
+<DT><SAMP>`CPATH'</SAMP>
+<DD><DT><SAMP>`C_INCLUDE_PATH'</SAMP>
+<DD>A colon-separated list of directories searched for include files,
+directories given with <SAMP>`-I'</SAMP> are searched first.
+<P>
+
+<DT><SAMP>`LIBRARY_PATH'</SAMP>
+<DD>A colon-separated list of directories searched for libraries for the
+<SAMP>`-l'</SAMP> option, directories given with <SAMP>`-L'</SAMP> are searched first.
+<P>
+
+</DL>
+<P>
+
+<A NAME="Clang"></A>
+<HR SIZE="6">
+<A NAME="SEC5"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC4"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC6"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 3. C language support </H1>
+<!--docid::SEC5::-->
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC6"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC7"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 3.1 ANSI C </H2>
+<!--docid::SEC6::-->
+<P>
+
+TCC implements all the ANSI C standard, including structure bit fields
+and floating point numbers (<CODE>long double</CODE>, <CODE>double</CODE>, and
+<CODE>float</CODE> fully supported).
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC7"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC6"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC8"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC8"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 3.2 ISOC99 extensions </H2>
+<!--docid::SEC7::-->
+<P>
+
+TCC implements many features of the new C standard: ISO C99. Currently
+missing items are: complex and imaginary numbers.
+</P><P>
+
+Currently implemented ISOC99 features:
+</P><P>
+
+<UL>
+
+<LI>variable length arrays.
+<P>
+
+<LI>64 bit <CODE>long long</CODE> types are fully supported.
+<P>
+
+<LI>The boolean type <CODE>_Bool</CODE> is supported.
+<P>
+
+<LI><CODE>__func__</CODE> is a string variable containing the current
+function name.
+<P>
+
+<LI>Variadic macros: <CODE>__VA_ARGS__</CODE> can be used for
+   function-like macros:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>    #define dprintf(level, __VA_ARGS__) printf(__VA_ARGS__)
+</pre></td></tr></table><P>
+
+<CODE>dprintf</CODE> can then be used with a variable number of parameters.
+</P><P>
+
+<LI>Declarations can appear anywhere in a block (as in C++).
+<P>
+
+<LI>Array and struct/union elements can be initialized in any order by
+  using designators:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>    struct { int x, y; } st[10] = { [0].x = 1, [0].y = 2 };
+
+    int tab[10] = { 1, 2, [5] = 5, [9] = 9};
+</pre></td></tr></table>    
+<LI>Compound initializers are supported:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>    int *p = (int []){ 1, 2, 3 };
+</pre></td></tr></table>to initialize a pointer pointing to an initialized array. The same
+works for structures and strings.
+<P>
+
+<LI>Hexadecimal floating point constants are supported:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>          double d = 0x1234p10;
+</pre></td></tr></table><P>
+
+is the same as writing 
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>          double d = 4771840.0;
+</pre></td></tr></table></P><P>
+
+<LI><CODE>inline</CODE> keyword is ignored.
+<P>
+
+<LI><CODE>restrict</CODE> keyword is ignored.
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC8"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC7"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC9"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC9"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 3.3 GNU C extensions </H2>
+<!--docid::SEC8::-->
+<P>
+
+TCC implements some GNU C extensions:
+</P><P>
+
+<UL>
+
+<LI>array designators can be used without '=':
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>    int a[10] = { [0] 1, [5] 2, 3, 4 };
+</pre></td></tr></table><P>
+
+<LI>Structure field designators can be a label:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>    struct { int x, y; } st = { x: 1, y: 1};
+</pre></td></tr></table>instead of
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>    struct { int x, y; } st = { .x = 1, .y = 1};
+</pre></td></tr></table><P>
+
+<LI><CODE>\e</CODE> is ASCII character 27.
+<P>
+
+<LI>case ranges : ranges can be used in <CODE>case</CODE>s:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>    switch(a) {
+    case 1 <small>...</small> 9:
+          printf("range 1 to 9\n");
+          break;
+    default:
+          printf("unexpected\n");
+          break;
+    }
+</pre></td></tr></table><P>
+
+<A NAME="IDX1"></A>
+<A NAME="IDX2"></A>
+<A NAME="IDX3"></A>
+<A NAME="IDX4"></A>
+<A NAME="IDX5"></A>
+<A NAME="IDX6"></A>
+<A NAME="IDX7"></A>
+<A NAME="IDX8"></A>
+</P><P>
+
+<LI>The keyword <CODE>__attribute__</CODE> is handled to specify variable or
+function attributes. The following attributes are supported:
+<UL>
+
+<LI><CODE>aligned(n)</CODE>: align a variable or a structure field to n bytes
+(must be a power of two).
+<P>
+
+<LI><CODE>packed</CODE>: force alignment of a variable or a structure field to
+  1.
+<P>
+
+<LI><CODE>section(name)</CODE>: generate function or data in assembly section
+name (name is a string containing the section name) instead of the default
+section.
+<P>
+
+<LI><CODE>unused</CODE>: specify that the variable or the function is unused.
+<P>
+
+<LI><CODE>cdecl</CODE>: use standard C calling convention (default).
+<P>
+
+<LI><CODE>stdcall</CODE>: use Pascal-like calling convention.
+<P>
+
+<LI><CODE>regparm(n)</CODE>: use fast i386 calling convention. <VAR>n</VAR> must be
+between 1 and 3. The first <VAR>n</VAR> function parameters are respectively put in
+registers <CODE>%eax</CODE>, <CODE>%edx</CODE> and <CODE>%ecx</CODE>.
+<P>
+
+<LI><CODE>dllexport</CODE>: export function from dll/executable (win32 only)
+<P>
+
+</UL>
+<P>
+
+Here are some examples:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>    int a __attribute__ ((aligned(8), section(".mysection")));
+</pre></td></tr></table></P><P>
+
+align variable <CODE>a</CODE> to 8 bytes and put it in section <CODE>.mysection</CODE>.
+</P><P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>    int my_add(int a, int b) __attribute__ ((section(".mycodesection"))) 
+    {
+        return a + b;
+    }
+</pre></td></tr></table></P><P>
+
+generate function <CODE>my_add</CODE> in section <CODE>.mycodesection</CODE>.
+</P><P>
+
+<LI>GNU style variadic macros:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>    #define dprintf(fmt, args<small>...</small>) printf(fmt, ## args)
+
+    dprintf("no arg\n");
+    dprintf("one arg %d\n", 1);
+</pre></td></tr></table><P>
+
+<LI><CODE>__FUNCTION__</CODE> is interpreted as C99 <CODE>__func__</CODE>
+(so it has not exactly the same semantics as string literal GNUC
+where it is a string literal).
+<P>
+
+<LI>The <CODE>__alignof__</CODE> keyword can be used as <CODE>sizeof</CODE>
+to get the alignment of a type or an expression.
+<P>
+
+<LI>The <CODE>typeof(x)</CODE> returns the type of <CODE>x</CODE>.
+<CODE>x</CODE> is an expression or a type.
+<P>
+
+<LI>Computed gotos: <CODE>&#38;&#38;label</CODE> returns a pointer of type
+<CODE>void *</CODE> on the goto label <CODE>label</CODE>. <CODE>goto *expr</CODE> can be
+used to jump on the pointer resulting from <CODE>expr</CODE>.
+<P>
+
+<LI>Inline assembly with asm instruction:
+<A NAME="IDX9"></A>
+<A NAME="IDX10"></A>
+<A NAME="IDX11"></A>
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>static inline void * my_memcpy(void * to, const void * from, size_t n)
+{
+int d0, d1, d2;
+__asm__ __volatile__(
+        "rep ; movsl\n\t"
+        "testb $2,%b4\n\t"
+        "je 1f\n\t"
+        "movsw\n"
+        "1:\ttestb $1,%b4\n\t"
+        "je 2f\n\t"
+        "movsb\n"
+        "2:"
+        : "=&c" (d0), "=&#38;D" (d1), "=&#38;S" (d2)
+        :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+        : "memory");
+return (to);
+}
+</pre></td></tr></table><P>
+
+<A NAME="IDX12"></A>
+TCC includes its own x86 inline assembler with a <CODE>gas</CODE>-like (GNU
+assembler) syntax. No intermediate files are generated. GCC 3.x named
+operands are supported.
+</P><P>
+
+<LI><CODE>__builtin_types_compatible_p()</CODE> and <CODE>__builtin_constant_p()</CODE>
+are supported.
+<P>
+
+<LI><CODE>#pragma pack</CODE> is supported for win32 compatibility.
+<P>
+
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC9"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC8"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC5"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 3.4 TinyCC extensions </H2>
+<!--docid::SEC9::-->
+<P>
+
+<UL>
+
+<LI><CODE>__TINYC__</CODE> is a predefined macro to indicate that you use TCC.
+<P>
+
+<LI><CODE>#!</CODE> at the start of a line is ignored to allow scripting.
+<P>
+
+<LI>Binary digits can be entered (<CODE>0b101</CODE> instead of
+<CODE>5</CODE>).
+<P>
+
+<LI><CODE>__BOUNDS_CHECKING_ON</CODE> is defined if bound checking is activated.
+<P>
+
+</UL>
+<P>
+
+<A NAME="asm"></A>
+<HR SIZE="6">
+<A NAME="SEC10"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC9"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC11"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 4. TinyCC Assembler </H1>
+<!--docid::SEC10::-->
+<P>
+
+Since version 0.9.16, TinyCC integrates its own assembler. TinyCC
+assembler supports a gas-like syntax (GNU assembler). You can
+deactivate assembler support if you want a smaller TinyCC executable
+(the C compiler does not rely on the assembler).
+</P><P>
+
+TinyCC Assembler is used to handle files with <TT>`.S'</TT> (C
+preprocessed assembler) and <TT>`.s'</TT> extensions. It is also used to
+handle the GNU inline assembler with the <CODE>asm</CODE> keyword.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC11"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC12"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 4.1 Syntax </H2>
+<!--docid::SEC11::-->
+<P>
+
+TinyCC Assembler supports most of the gas syntax. The tokens are the
+same as C.
+</P><P>
+
+<UL>
+
+<LI>C and C++ comments are supported.
+<P>
+
+<LI>Identifiers are the same as C, so you cannot use '.' or '$'.
+<P>
+
+<LI>Only 32 bit integer numbers are supported.
+<P>
+
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC12"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC11"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC13"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC13"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 4.2 Expressions </H2>
+<!--docid::SEC12::-->
+<P>
+
+<UL>
+
+<LI>Integers in decimal, octal and hexa are supported.
+<P>
+
+<LI>Unary operators: +, -, ~.
+<P>
+
+<LI>Binary operators in decreasing priority order:
+<P>
+
+<OL>
+<LI>*, /, %
+<LI>&#38;, |, ^
+<LI>+, -
+</OL>
+<P>
+
+<LI>A value is either an absolute number or a label plus an offset.
+All operators accept absolute values except '+' and '-'. '+' or '-' can be
+used to add an offset to a label. '-' supports two labels only if they
+are the same or if they are both defined and in the same section.
+<P>
+
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC13"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC12"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC14"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC14"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 4.3 Labels </H2>
+<!--docid::SEC13::-->
+<P>
+
+<UL>
+
+<LI>All labels are considered as local, except undefined ones.
+<P>
+
+<LI>Numeric labels can be used as local <CODE>gas</CODE>-like labels.
+They can be defined several times in the same source. Use 'b'
+(backward) or 'f' (forward) as suffix to reference them:
+<P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre> 1:
+      jmp 1b /* jump to '1' label before */
+      jmp 1f /* jump to '1' label after */
+ 1:
+</pre></td></tr></table></P><P>
+
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC14"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC13"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC15"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC15"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 4.4 Directives </H2>
+<!--docid::SEC14::-->
+<P>
+
+All directives are preceded by a '.'. The following directives are
+supported:
+</P><P>
+
+<UL>
+<LI>.align n[,value]
+<LI>.skip n[,value]
+<LI>.space n[,value]
+<LI>.byte value1[,...]
+<LI>.word value1[,...]
+<LI>.short value1[,...]
+<LI>.int value1[,...]
+<LI>.long value1[,...]
+<LI>.quad immediate_value1[,...]
+<LI>.globl symbol
+<LI>.global symbol
+<LI>.section section
+<LI>.text
+<LI>.data
+<LI>.bss
+<LI>.fill repeat[,size[,value]]
+<LI>.org n
+<LI>.previous
+<LI>.string string[,...]
+<LI>.asciz string[,...]
+<LI>.ascii string[,...]
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC15"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC14"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC10"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 4.5 X86 Assembler </H2>
+<!--docid::SEC15::-->
+<P>
+
+All X86 opcodes are supported. Only ATT syntax is supported (source
+then destination operand order). If no size suffix is given, TinyCC
+tries to guess it from the operand sizes.
+</P><P>
+
+Currently, MMX opcodes are supported but not SSE ones.
+</P><P>
+
+<A NAME="linker"></A>
+<HR SIZE="6">
+<A NAME="SEC16"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC15"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC17"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 5. TinyCC Linker </H1>
+<!--docid::SEC16::-->
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC17"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC18"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 5.1 ELF file generation </H2>
+<!--docid::SEC17::-->
+<P>
+
+TCC can directly output relocatable ELF files (object files),
+executable ELF files and dynamic ELF libraries without relying on an
+external linker.
+</P><P>
+
+Dynamic ELF libraries can be output but the C compiler does not generate
+position independent code (PIC). It means that the dynamic library
+code generated by TCC cannot be factorized among processes yet.
+</P><P>
+
+TCC linker eliminates unreferenced object code in libraries. A single pass is
+done on the object and library list, so the order in which object files and
+libraries are specified is important (same constraint as GNU ld). No grouping
+options (<SAMP>`--start-group'</SAMP> and <SAMP>`--end-group'</SAMP>) are supported.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC18"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC17"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC19"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC19"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 5.2 ELF file loader </H2>
+<!--docid::SEC18::-->
+<P>
+
+TCC can load ELF object files, archives (.a files) and dynamic
+libraries (.so).
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC19"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC18"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC20"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC20"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 5.3 PE-i386 file generation </H2>
+<!--docid::SEC19::-->
+<P>
+
+TCC for Windows supports the native Win32 executable file format (PE-i386).  It
+generates EXE files (console and gui) and DLL files.
+</P><P>
+
+For usage on Windows, see also tcc-win32.txt.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC20"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC19"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC16"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 5.4 GNU Linker Scripts </H2>
+<!--docid::SEC20::-->
+<P>
+
+Because on many Linux systems some dynamic libraries (such as
+<TT>`/usr/lib/libc.so'</TT>) are in fact GNU ld link scripts (horrible!),
+the TCC linker also supports a subset of GNU ld scripts.
+</P><P>
+
+The <CODE>GROUP</CODE> and <CODE>FILE</CODE> commands are supported. <CODE>OUTPUT_FORMAT</CODE>
+and <CODE>TARGET</CODE> are ignored.
+</P><P>
+
+Example from <TT>`/usr/lib/libc.so'</TT>:
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>/* GNU ld script
+   Use the shared library, but some functions are only in
+   the static library, so try that secondarily.  */
+GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a )
+</pre></td></tr></table></P><P>
+
+<A NAME="Bounds"></A>
+<HR SIZE="6">
+<A NAME="SEC21"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC20"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC22"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC22"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC22"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 6. TinyCC Memory and Bound checks </H1>
+<!--docid::SEC21::-->
+<P>
+
+This feature is activated with the <SAMP>`-b'</SAMP> (see section <A HREF="tcc-doc.html#SEC2">2. Command line invocation</A>).
+</P><P>
+
+Note that pointer size is <EM>unchanged</EM> and that code generated
+with bound checks is <EM>fully compatible</EM> with unchecked
+code. When a pointer comes from unchecked code, it is assumed to be
+valid. Even very obscure C code with casts should work correctly.
+</P><P>
+
+For more information about the ideas behind this method, see
+<A HREF="http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html">http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html</A>.
+</P><P>
+
+Here are some examples of caught errors:
+</P><P>
+
+<DL COMPACT>
+
+<DT>Invalid range with standard string function:
+<DD><TABLE><tr><td>&nbsp;</td><td class=example><pre>{
+    char tab[10];
+    memset(tab, 0, 11);
+}
+</pre></td></tr></table><P>
+
+<DT>Out of bounds-error in global or local arrays:
+<DD><TABLE><tr><td>&nbsp;</td><td class=example><pre>{
+    int tab[10];
+    for(i=0;i&#60;11;i++) {
+        sum += tab[i];
+    }
+}
+</pre></td></tr></table><P>
+
+<DT>Out of bounds-error in malloc'ed data:
+<DD><TABLE><tr><td>&nbsp;</td><td class=example><pre>{
+    int *tab;
+    tab = malloc(20 * sizeof(int));
+    for(i=0;i&#60;21;i++) {
+        sum += tab4[i];
+    }
+    free(tab);
+}
+</pre></td></tr></table><P>
+
+<DT>Access of freed memory:
+<DD><TABLE><tr><td>&nbsp;</td><td class=example><pre>{
+    int *tab;
+    tab = malloc(20 * sizeof(int));
+    free(tab);
+    for(i=0;i&#60;20;i++) {
+        sum += tab4[i];
+    }
+}
+</pre></td></tr></table><P>
+
+<DT>Double free:
+<DD><TABLE><tr><td>&nbsp;</td><td class=example><pre>{
+    int *tab;
+    tab = malloc(20 * sizeof(int));
+    free(tab);
+    free(tab);
+}
+</pre></td></tr></table><P>
+
+</DL>
+<P>
+
+<A NAME="Libtcc"></A>
+<HR SIZE="6">
+<A NAME="SEC22"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC21"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 7. The <CODE>libtcc</CODE> library </H1>
+<!--docid::SEC22::-->
+<P>
+
+The <CODE>libtcc</CODE> library enables you to use TCC as a backend for
+dynamic code generation. 
+</P><P>
+
+Read the <TT>`libtcc.h'</TT> to have an overview of the API. Read
+<TT>`libtcc_test.c'</TT> to have a very simple example.
+</P><P>
+
+The idea consists in giving a C string containing the program you want
+to compile directly to <CODE>libtcc</CODE>. Then you can access to any global
+symbol (function or variable) defined.
+</P><P>
+
+<A NAME="devel"></A>
+<HR SIZE="6">
+<A NAME="SEC23"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC22"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC24"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 8. Developer's guide </H1>
+<!--docid::SEC23::-->
+<P>
+
+This chapter gives some hints to understand how TCC works. You can skip
+it if you do not intend to modify the TCC code.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC24"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC25"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.1 File reading </H2>
+<!--docid::SEC24::-->
+<P>
+
+The <CODE>BufferedFile</CODE> structure contains the context needed to read a
+file, including the current line number. <CODE>tcc_open()</CODE> opens a new
+file and <CODE>tcc_close()</CODE> closes it. <CODE>inp()</CODE> returns the next
+character.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC25"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC24"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC26"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC26"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.2 Lexer </H2>
+<!--docid::SEC25::-->
+<P>
+
+<CODE>next()</CODE> reads the next token in the current
+file. <CODE>next_nomacro()</CODE> reads the next token without macro
+expansion.
+</P><P>
+
+<CODE>tok</CODE> contains the current token (see <CODE>TOK_xxx</CODE>)
+constants. Identifiers and keywords are also keywords. <CODE>tokc</CODE>
+contains additional infos about the token (for example a constant value
+if number or string token).
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC26"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC25"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC27"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC27"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.3 Parser </H2>
+<!--docid::SEC26::-->
+<P>
+
+The parser is hardcoded (yacc is not necessary). It does only one pass,
+except:
+</P><P>
+
+<UL>
+
+<LI>For initialized arrays with unknown size, a first pass
+is done to count the number of elements.
+<P>
+
+<LI>For architectures where arguments are evaluated in
+reverse order, a first pass is done to reverse the argument order.
+<P>
+
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC27"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC26"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC28"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC28"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.4 Types </H2>
+<!--docid::SEC27::-->
+<P>
+
+The types are stored in a single 'int' variable. It was chosen in the
+first stages of development when tcc was much simpler. Now, it may not
+be the best solution.
+</P><P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>#define VT_INT        0  /* integer type */
+#define VT_BYTE       1  /* signed byte type */
+#define VT_SHORT      2  /* short type */
+#define VT_VOID       3  /* void type */
+#define VT_PTR        4  /* pointer */
+#define VT_ENUM       5  /* enum definition */
+#define VT_FUNC       6  /* function type */
+#define VT_STRUCT     7  /* struct/union definition */
+#define VT_FLOAT      8  /* IEEE float */
+#define VT_DOUBLE     9  /* IEEE double */
+#define VT_LDOUBLE   10  /* IEEE long double */
+#define VT_BOOL      11  /* ISOC99 boolean type */
+#define VT_LLONG     12  /* 64 bit integer */
+#define VT_LONG      13  /* long integer (NEVER USED as type, only
+                            during parsing) */
+#define VT_BTYPE      0x000f /* mask for basic type */
+#define VT_UNSIGNED   0x0010  /* unsigned type */
+#define VT_ARRAY      0x0020  /* array type (also has VT_PTR) */
+#define VT_VLA        0x20000 /* VLA type (also has VT_PTR and VT_ARRAY) */
+#define VT_BITFIELD   0x0040  /* bitfield modifier */
+#define VT_CONSTANT   0x0800  /* const modifier */
+#define VT_VOLATILE   0x1000  /* volatile modifier */
+#define VT_DEFSIGN    0x2000  /* signed type */
+
+#define VT_STRUCT_SHIFT 18   /* structure/enum name shift (14 bits left) */
+</pre></td></tr></table></P><P>
+
+When a reference to another type is needed (for pointers, functions and
+structures), the <CODE>32 - VT_STRUCT_SHIFT</CODE> high order bits are used to
+store an identifier reference.
+</P><P>
+
+The <CODE>VT_UNSIGNED</CODE> flag can be set for chars, shorts, ints and long
+longs.
+</P><P>
+
+Arrays are considered as pointers <CODE>VT_PTR</CODE> with the flag
+<CODE>VT_ARRAY</CODE> set. Variable length arrays are considered as special
+arrays and have flag <CODE>VT_VLA</CODE> set instead of <CODE>VT_ARRAY</CODE>.
+</P><P>
+
+The <CODE>VT_BITFIELD</CODE> flag can be set for chars, shorts, ints and long
+longs. If it is set, then the bitfield position is stored from bits
+VT_STRUCT_SHIFT to VT_STRUCT_SHIFT + 5 and the bit field size is stored
+from bits VT_STRUCT_SHIFT + 6 to VT_STRUCT_SHIFT + 11.
+</P><P>
+
+<CODE>VT_LONG</CODE> is never used except during parsing.
+</P><P>
+
+During parsing, the storage of an object is also stored in the type
+integer:
+</P><P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>#define VT_EXTERN  0x00000080  /* extern definition */
+#define VT_STATIC  0x00000100  /* static variable */
+#define VT_TYPEDEF 0x00000200  /* typedef definition */
+#define VT_INLINE  0x00000400  /* inline definition */
+#define VT_IMPORT  0x00004000  /* win32: extern data imported from dll */
+#define VT_EXPORT  0x00008000  /* win32: data exported from dll */
+#define VT_WEAK    0x00010000  /* win32: data exported from dll */
+</pre></td></tr></table></P><P>
+
+<HR SIZE="6">
+<A NAME="SEC28"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC27"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC29"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC29"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.5 Symbols </H2>
+<!--docid::SEC28::-->
+<P>
+
+All symbols are stored in hashed symbol stacks. Each symbol stack
+contains <CODE>Sym</CODE> structures.
+</P><P>
+
+<CODE>Sym.v</CODE> contains the symbol name (remember
+an identifier is also a token, so a string is never necessary to store
+it). <CODE>Sym.t</CODE> gives the type of the symbol. <CODE>Sym.r</CODE> is usually
+the register in which the corresponding variable is stored. <CODE>Sym.c</CODE> is
+usually a constant associated to the symbol like its address for normal
+symbols, and the number of entries for symbols representing arrays.
+Variable length array types use <CODE>Sym.c</CODE> as a location on the stack
+which holds the runtime sizeof for the type.
+</P><P>
+
+Four main symbol stacks are defined:
+</P><P>
+
+<DL COMPACT>
+
+<DT><CODE>define_stack</CODE>
+<DD>for the macros (<CODE>#define</CODE>s).
+<P>
+
+<DT><CODE>global_stack</CODE>
+<DD>for the global variables, functions and types.
+<P>
+
+<DT><CODE>local_stack</CODE>
+<DD>for the local variables, functions and types.
+<P>
+
+<DT><CODE>global_label_stack</CODE>
+<DD>for the local labels (for <CODE>goto</CODE>).
+<P>
+
+<DT><CODE>label_stack</CODE>
+<DD>for GCC block local labels (see the <CODE>__label__</CODE> keyword).
+<P>
+
+</DL>
+<P>
+
+<CODE>sym_push()</CODE> is used to add a new symbol in the local symbol
+stack. If no local symbol stack is active, it is added in the global
+symbol stack.
+</P><P>
+
+<CODE>sym_pop(st,b)</CODE> pops symbols from the symbol stack <VAR>st</VAR> until
+the symbol <VAR>b</VAR> is on the top of stack. If <VAR>b</VAR> is NULL, the stack
+is emptied.
+</P><P>
+
+<CODE>sym_find(v)</CODE> return the symbol associated to the identifier
+<VAR>v</VAR>. The local stack is searched first from top to bottom, then the
+global stack.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC29"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC28"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.6 Sections </H2>
+<!--docid::SEC29::-->
+<P>
+
+The generated code and data are written in sections. The structure
+<CODE>Section</CODE> contains all the necessary information for a given
+section. <CODE>new_section()</CODE> creates a new section. ELF file semantics
+is assumed for each section.
+</P><P>
+
+The following sections are predefined:
+</P><P>
+
+<DL COMPACT>
+
+<DT><CODE>text_section</CODE>
+<DD>is the section containing the generated code. <VAR>ind</VAR> contains the
+current position in the code section.
+<P>
+
+<DT><CODE>data_section</CODE>
+<DD>contains initialized data
+<P>
+
+<DT><CODE>bss_section</CODE>
+<DD>contains uninitialized data
+<P>
+
+<DT><CODE>bounds_section</CODE>
+<DD><DT><CODE>lbounds_section</CODE>
+<DD>are used when bound checking is activated
+<P>
+
+<DT><CODE>stab_section</CODE>
+<DD><DT><CODE>stabstr_section</CODE>
+<DD>are used when debugging is active to store debug information
+<P>
+
+<DT><CODE>symtab_section</CODE>
+<DD><DT><CODE>strtab_section</CODE>
+<DD>contain the exported symbols (currently only used for debugging).
+<P>
+
+</DL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC30"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC29"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC31"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.7 Code generation </H2>
+<!--docid::SEC30::-->
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC31"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC32"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 8.7.1 Introduction </H3>
+<!--docid::SEC31::-->
+<P>
+
+The TCC code generator directly generates linked binary code in one
+pass. It is rather unusual these days (see gcc for example which
+generates text assembly), but it can be very fast and surprisingly
+little complicated.
+</P><P>
+
+The TCC code generator is register based. Optimization is only done at
+the expression level. No intermediate representation of expression is
+kept except the current values stored in the <EM>value stack</EM>.
+</P><P>
+
+On x86, three temporary registers are used. When more registers are
+needed, one register is spilled into a new temporary variable on the stack.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC32"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC31"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC33"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC33"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 8.7.2 The value stack </H3>
+<!--docid::SEC32::-->
+<P>
+
+When an expression is parsed, its value is pushed on the value stack
+(<VAR>vstack</VAR>). The top of the value stack is <VAR>vtop</VAR>. Each value
+stack entry is the structure <CODE>SValue</CODE>.
+</P><P>
+
+<CODE>SValue.t</CODE> is the type. <CODE>SValue.r</CODE> indicates how the value is
+currently stored in the generated code. It is usually a CPU register
+index (<CODE>REG_xxx</CODE> constants), but additional values and flags are
+defined:
+</P><P>
+
+<TABLE><tr><td>&nbsp;</td><td class=example><pre>#define VT_CONST     0x00f0
+#define VT_LLOCAL    0x00f1
+#define VT_LOCAL     0x00f2
+#define VT_CMP       0x00f3
+#define VT_JMP       0x00f4
+#define VT_JMPI      0x00f5
+#define VT_LVAL      0x0100
+#define VT_SYM       0x0200
+#define VT_MUSTCAST  0x0400
+#define VT_MUSTBOUND 0x0800
+#define VT_BOUNDED   0x8000
+#define VT_LVAL_BYTE     0x1000
+#define VT_LVAL_SHORT    0x2000
+#define VT_LVAL_UNSIGNED 0x4000
+#define VT_LVAL_TYPE     (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
+</pre></td></tr></table></P><P>
+
+<DL COMPACT>
+
+<DT><CODE>VT_CONST</CODE>
+<DD>indicates that the value is a constant. It is stored in the union
+<CODE>SValue.c</CODE>, depending on its type.
+<P>
+
+<DT><CODE>VT_LOCAL</CODE>
+<DD>indicates a local variable pointer at offset <CODE>SValue.c.i</CODE> in the
+stack.
+<P>
+
+<DT><CODE>VT_CMP</CODE>
+<DD>indicates that the value is actually stored in the CPU flags (i.e. the
+value is the consequence of a test). The value is either 0 or 1. The
+actual CPU flags used is indicated in <CODE>SValue.c.i</CODE>. 
+<P>
+
+If any code is generated which destroys the CPU flags, this value MUST be
+put in a normal register.
+</P><P>
+
+<DT><CODE>VT_JMP</CODE>
+<DD><DT><CODE>VT_JMPI</CODE>
+<DD>indicates that the value is the consequence of a conditional jump. For VT_JMP,
+it is 1 if the jump is taken, 0 otherwise. For VT_JMPI it is inverted.
+<P>
+
+These values are used to compile the <CODE>||</CODE> and <CODE>&#38;&#38;</CODE> logical
+operators.
+</P><P>
+
+If any code is generated, this value MUST be put in a normal
+register. Otherwise, the generated code won't be executed if the jump is
+taken.
+</P><P>
+
+<DT><CODE>VT_LVAL</CODE>
+<DD>is a flag indicating that the value is actually an lvalue (left value of
+an assignment). It means that the value stored is actually a pointer to
+the wanted value. 
+<P>
+
+Understanding the use <CODE>VT_LVAL</CODE> is very important if you want to
+understand how TCC works.
+</P><P>
+
+<DT><CODE>VT_LVAL_BYTE</CODE>
+<DD><DT><CODE>VT_LVAL_SHORT</CODE>
+<DD><DT><CODE>VT_LVAL_UNSIGNED</CODE>
+<DD>if the lvalue has an integer type, then these flags give its real
+type. The type alone is not enough in case of cast optimisations.
+<P>
+
+<DT><CODE>VT_LLOCAL</CODE>
+<DD>is a saved lvalue on the stack. <CODE>VT_LVAL</CODE> must also be set with
+<CODE>VT_LLOCAL</CODE>. <CODE>VT_LLOCAL</CODE> can arise when a <CODE>VT_LVAL</CODE> in
+a register has to be saved to the stack, or it can come from an
+architecture-specific calling convention.
+<P>
+
+<DT><CODE>VT_MUSTCAST</CODE>
+<DD>indicates that a cast to the value type must be performed if the value
+is used (lazy casting).
+<P>
+
+<DT><CODE>VT_SYM</CODE>
+<DD>indicates that the symbol <CODE>SValue.sym</CODE> must be added to the constant.
+<P>
+
+<DT><CODE>VT_MUSTBOUND</CODE>
+<DD><DT><CODE>VT_BOUNDED</CODE>
+<DD>are only used for optional bound checking.
+<P>
+
+</DL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC33"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC32"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC34"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC34"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 8.7.3 Manipulating the value stack </H3>
+<!--docid::SEC33::-->
+<P>
+
+<CODE>vsetc()</CODE> and <CODE>vset()</CODE> pushes a new value on the value
+stack. If the previous <VAR>vtop</VAR> was stored in a very unsafe place(for
+example in the CPU flags), then some code is generated to put the
+previous <VAR>vtop</VAR> in a safe storage.
+</P><P>
+
+<CODE>vpop()</CODE> pops <VAR>vtop</VAR>. In some cases, it also generates cleanup
+code (for example if stacked floating point registers are used as on
+x86).
+</P><P>
+
+The <CODE>gv(rc)</CODE> function generates code to evaluate <VAR>vtop</VAR> (the
+top value of the stack) into registers. <VAR>rc</VAR> selects in which
+register class the value should be put. <CODE>gv()</CODE> is the <EM>most
+important function</EM> of the code generator.
+</P><P>
+
+<CODE>gv2()</CODE> is the same as <CODE>gv()</CODE> but for the top two stack
+entries.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC34"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC33"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &lt;&lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC30"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &gt;&gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 8.7.4 CPU dependent code generation </H3>
+<!--docid::SEC34::-->
+See the <TT>`i386-gen.c'</TT> file to have an example.
+<P>
+
+<DL COMPACT>
+
+<DT><CODE>load()</CODE>
+<DD>must generate the code needed to load a stack value into a register.
+<P>
+
+<DT><CODE>store()</CODE>
+<DD>must generate the code needed to store a register into a stack value
+lvalue.
+<P>
+
+<DT><CODE>gfunc_start()</CODE>
+<DD><DT><CODE>gfunc_param()</CODE>
+<DD><DT><CODE>gfunc_call()</CODE>
+<DD>should generate a function call
+<P>
+
+<DT><CODE>gfunc_prolog()</CODE>
+<DD><DT><CODE>gfunc_epilog()</CODE>
+<DD>should generate a function prolog/epilog.
+<P>
+
+<DT><CODE>gen_opi(op)</CODE>
+<DD>must generate the binary integer operation <VAR>op</VAR> on the two top
+entries of the stack which are guaranteed to contain integer types.
+<P>
+
+The result value should be put on the stack.
+</P><P>
+
+<DT><CODE>gen_opf(op)</CODE>
+<DD>same as <CODE>gen_opi()</CODE> for floating point operations. The two top
+entries of the stack are guaranteed to contain floating point values of
+same types.
+<P>
+
+<DT><CODE>gen_cvt_itof()</CODE>
+<DD>integer to floating point conversion.
+<P>
+
+<DT><CODE>gen_cvt_ftoi()</CODE>
+<DD>floating point to integer conversion.
+<P>
+
+<DT><CODE>gen_cvt_ftof()</CODE>
+<DD>floating point to floating point of different size conversion.
+<P>
+
+<DT><CODE>gen_bounded_ptr_add()</CODE>
+<DD><DT><CODE>gen_bounded_ptr_deref()</CODE>
+<DD>are only used for bounds checking.
+<P>
+
+</DL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC35"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC34"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC23"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 8.8 Optimizations done </H2>
+<!--docid::SEC35::-->
+Constant propagation is done for all operations. Multiplications and
+divisions are optimized to shifts when appropriate. Comparison
+operators are optimized by maintaining a special cache for the
+processor flags. &#38;&#38;, || and ! are optimized by maintaining a special
+'jump target' value. No other jump optimization is currently performed
+because it would require to store the code in a more abstract fashion.
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC36"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC35"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> Concept Index </H1>
+<!--docid::SEC36::-->
+<table><tr><th valign=top>Jump to: &nbsp; </th><td><A HREF="tcc-doc.html#cp__" style="text-decoration:none"><b>_</b></A>
+ &nbsp; 
+<BR>
+<A HREF="tcc-doc.html#cp_A" style="text-decoration:none"><b>A</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_B" style="text-decoration:none"><b>B</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_C" style="text-decoration:none"><b>C</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_D" style="text-decoration:none"><b>D</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_E" style="text-decoration:none"><b>E</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_F" style="text-decoration:none"><b>F</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_G" style="text-decoration:none"><b>G</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_I" style="text-decoration:none"><b>I</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_J" style="text-decoration:none"><b>J</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_L" style="text-decoration:none"><b>L</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_M" style="text-decoration:none"><b>M</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_O" style="text-decoration:none"><b>O</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_P" style="text-decoration:none"><b>P</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_Q" style="text-decoration:none"><b>Q</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_R" style="text-decoration:none"><b>R</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_S" style="text-decoration:none"><b>S</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_T" style="text-decoration:none"><b>T</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_U" style="text-decoration:none"><b>U</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_V" style="text-decoration:none"><b>V</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_W" style="text-decoration:none"><b>W</b></A>
+ &nbsp; 
+</td></tr></table><br><P></P>
+<TABLE border=0>
+<TR><TD></TD><TH ALIGN=LEFT>Index Entry</TH><TH ALIGN=LEFT> Section</TH></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp__"></A>_</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX11">__asm__</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_A"></A>A</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">align directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX1">aligned attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">ascii directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">asciz directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC15">assembler</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC15">4.5 X86 Assembler</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">assembler directives</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX10">assembly, inline</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_B"></A>B</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC21">bound checks</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">bss directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">byte directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_C"></A>C</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">caching processor flags</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX5">cdecl attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC30">code generation</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC30">8.7 Code generation</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">comparison operators</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">constant propagation</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC34">CPU dependent</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC34">8.7.4 CPU dependent code generation</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_D"></A>D</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">data directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">directives, assembler</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX8">dllexport attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_E"></A>E</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC17">ELF</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC17">5.1 ELF file generation</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_F"></A>F</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">FILE, linker command</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">fill directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">flags, caching</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_G"></A>G</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX12">gas</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">global directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">globl directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">GROUP, linker command</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_I"></A>I</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX9">inline assembly</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">int directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_J"></A>J</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">jump optimization</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_L"></A>L</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC16">linker</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC16">5. TinyCC Linker</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">linker scripts</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">long directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_M"></A>M</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC21">memory checks</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_O"></A>O</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">optimizations</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">org directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">OUTPUT_FORMAT, linker command</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_P"></A>P</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX2">packed attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC19">PE-i386</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC19">5.3 PE-i386 file generation</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">previous directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_Q"></A>Q</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">quad directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_R"></A>R</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX7">regparm attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_S"></A>S</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">scripts, linker</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX3">section attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">section directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">short directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">skip directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">space directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX6">stdcall attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">strength reduction</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">string directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_T"></A>T</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">TARGET, linker command</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">text directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_U"></A>U</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#IDX4">unused attribute</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_V"></A>V</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC33">value stack</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC33">8.7.3 Manipulating the value stack</A></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC32">value stack, introduction</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC32">8.7.2 The value stack</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+<TR><TH><A NAME="cp_W"></A>W</TH><TD></TD><TD></TD></TR>
+<TR><TD></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">word directive</A></TD><TD valign=top><A HREF="tcc-doc.html#SEC14">4.4 Directives</A></TD></TR>
+<TR><TD COLSPAN=3> <HR></TD></TR>
+</TABLE><P></P><table><tr><th valign=top>Jump to: &nbsp; </th><td><A HREF="tcc-doc.html#cp__" style="text-decoration:none"><b>_</b></A>
+ &nbsp; 
+<BR>
+<A HREF="tcc-doc.html#cp_A" style="text-decoration:none"><b>A</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_B" style="text-decoration:none"><b>B</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_C" style="text-decoration:none"><b>C</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_D" style="text-decoration:none"><b>D</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_E" style="text-decoration:none"><b>E</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_F" style="text-decoration:none"><b>F</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_G" style="text-decoration:none"><b>G</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_I" style="text-decoration:none"><b>I</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_J" style="text-decoration:none"><b>J</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_L" style="text-decoration:none"><b>L</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_M" style="text-decoration:none"><b>M</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_O" style="text-decoration:none"><b>O</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_P" style="text-decoration:none"><b>P</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_Q" style="text-decoration:none"><b>Q</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_R" style="text-decoration:none"><b>R</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_S" style="text-decoration:none"><b>S</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_T" style="text-decoration:none"><b>T</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_U" style="text-decoration:none"><b>U</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_V" style="text-decoration:none"><b>V</b></A>
+ &nbsp; 
+<A HREF="tcc-doc.html#cp_W" style="text-decoration:none"><b>W</b></A>
+ &nbsp; 
+</td></tr></table><br><P>
+
+<HR SIZE="6">
+<A NAME="SEC_Contents"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1>Table of Contents</H1>
+<UL>
+<A NAME="TOC1" HREF="tcc-doc.html#SEC1">1. Introduction</A>
+<BR>
+<A NAME="TOC2" HREF="tcc-doc.html#SEC2">2. Command line invocation</A>
+<BR>
+<UL>
+<A NAME="TOC3" HREF="tcc-doc.html#SEC3">2.1 Quick start</A>
+<BR>
+<A NAME="TOC4" HREF="tcc-doc.html#SEC4">2.2 Option summary</A>
+<BR>
+</UL>
+<A NAME="TOC5" HREF="tcc-doc.html#SEC5">3. C language support</A>
+<BR>
+<UL>
+<A NAME="TOC6" HREF="tcc-doc.html#SEC6">3.1 ANSI C</A>
+<BR>
+<A NAME="TOC7" HREF="tcc-doc.html#SEC7">3.2 ISOC99 extensions</A>
+<BR>
+<A NAME="TOC8" HREF="tcc-doc.html#SEC8">3.3 GNU C extensions</A>
+<BR>
+<A NAME="TOC9" HREF="tcc-doc.html#SEC9">3.4 TinyCC extensions</A>
+<BR>
+</UL>
+<A NAME="TOC10" HREF="tcc-doc.html#SEC10">4. TinyCC Assembler</A>
+<BR>
+<UL>
+<A NAME="TOC11" HREF="tcc-doc.html#SEC11">4.1 Syntax</A>
+<BR>
+<A NAME="TOC12" HREF="tcc-doc.html#SEC12">4.2 Expressions</A>
+<BR>
+<A NAME="TOC13" HREF="tcc-doc.html#SEC13">4.3 Labels</A>
+<BR>
+<A NAME="TOC14" HREF="tcc-doc.html#SEC14">4.4 Directives</A>
+<BR>
+<A NAME="TOC15" HREF="tcc-doc.html#SEC15">4.5 X86 Assembler</A>
+<BR>
+</UL>
+<A NAME="TOC16" HREF="tcc-doc.html#SEC16">5. TinyCC Linker</A>
+<BR>
+<UL>
+<A NAME="TOC17" HREF="tcc-doc.html#SEC17">5.1 ELF file generation</A>
+<BR>
+<A NAME="TOC18" HREF="tcc-doc.html#SEC18">5.2 ELF file loader</A>
+<BR>
+<A NAME="TOC19" HREF="tcc-doc.html#SEC19">5.3 PE-i386 file generation</A>
+<BR>
+<A NAME="TOC20" HREF="tcc-doc.html#SEC20">5.4 GNU Linker Scripts</A>
+<BR>
+</UL>
+<A NAME="TOC21" HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A>
+<BR>
+<A NAME="TOC22" HREF="tcc-doc.html#SEC22">7. The <CODE>libtcc</CODE> library</A>
+<BR>
+<A NAME="TOC23" HREF="tcc-doc.html#SEC23">8. Developer's guide</A>
+<BR>
+<UL>
+<A NAME="TOC24" HREF="tcc-doc.html#SEC24">8.1 File reading</A>
+<BR>
+<A NAME="TOC25" HREF="tcc-doc.html#SEC25">8.2 Lexer</A>
+<BR>
+<A NAME="TOC26" HREF="tcc-doc.html#SEC26">8.3 Parser</A>
+<BR>
+<A NAME="TOC27" HREF="tcc-doc.html#SEC27">8.4 Types</A>
+<BR>
+<A NAME="TOC28" HREF="tcc-doc.html#SEC28">8.5 Symbols</A>
+<BR>
+<A NAME="TOC29" HREF="tcc-doc.html#SEC29">8.6 Sections</A>
+<BR>
+<A NAME="TOC30" HREF="tcc-doc.html#SEC30">8.7 Code generation</A>
+<BR>
+<UL>
+<A NAME="TOC31" HREF="tcc-doc.html#SEC31">8.7.1 Introduction</A>
+<BR>
+<A NAME="TOC32" HREF="tcc-doc.html#SEC32">8.7.2 The value stack</A>
+<BR>
+<A NAME="TOC33" HREF="tcc-doc.html#SEC33">8.7.3 Manipulating the value stack</A>
+<BR>
+<A NAME="TOC34" HREF="tcc-doc.html#SEC34">8.7.4 CPU dependent code generation</A>
+<BR>
+</UL>
+<A NAME="TOC35" HREF="tcc-doc.html#SEC35">8.8 Optimizations done</A>
+<BR>
+</UL>
+<A NAME="TOC36" HREF="tcc-doc.html#SEC36">Concept Index</A>
+<BR>
+</UL>
+<HR SIZE=1>
+<A NAME="SEC_OVERVIEW"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1>Short Table of Contents</H1>
+<BLOCKQUOTE>
+<A NAME="TOC1" HREF="tcc-doc.html#SEC1">1. Introduction</A>
+<BR>
+<A NAME="TOC2" HREF="tcc-doc.html#SEC2">2. Command line invocation</A>
+<BR>
+<A NAME="TOC5" HREF="tcc-doc.html#SEC5">3. C language support</A>
+<BR>
+<A NAME="TOC10" HREF="tcc-doc.html#SEC10">4. TinyCC Assembler</A>
+<BR>
+<A NAME="TOC16" HREF="tcc-doc.html#SEC16">5. TinyCC Linker</A>
+<BR>
+<A NAME="TOC21" HREF="tcc-doc.html#SEC21">6. TinyCC Memory and Bound checks</A>
+<BR>
+<A NAME="TOC22" HREF="tcc-doc.html#SEC22">7. The <CODE>libtcc</CODE> library</A>
+<BR>
+<A NAME="TOC23" HREF="tcc-doc.html#SEC23">8. Developer's guide</A>
+<BR>
+<A NAME="TOC36" HREF="tcc-doc.html#SEC36">Concept Index</A>
+<BR>
+
+</BLOCKQUOTE>
+<HR SIZE=1>
+<A NAME="SEC_About"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Top">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC36">Index</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="tcc-doc.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1>About this document</H1>
+This document was generated on <I>December, 17  2017</I>
+using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
+"><I>texi2html</I></A>
+<P></P>  
+The buttons in the navigation panels have the following meaning:
+<P></P>
+<table border = "1">
+<TR>
+<TH> Button </TH>
+<TH> Name </TH>
+<TH> Go to </TH>
+<TH> From 1.2.3 go to</TH>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ &lt; ] </TD>
+<TD ALIGN="CENTER">
+Back
+</TD>
+<TD>
+previous section in reading order
+</TD>
+<TD>
+1.2.2
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ &gt; ] </TD>
+<TD ALIGN="CENTER">
+Forward
+</TD>
+<TD>
+next section in reading order
+</TD>
+<TD>
+1.2.4
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ &lt;&lt; ] </TD>
+<TD ALIGN="CENTER">
+FastBack
+</TD>
+<TD>
+previous or up-and-previous section 
+</TD>
+<TD>
+1.1
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ Up ] </TD>
+<TD ALIGN="CENTER">
+Up
+</TD>
+<TD>
+up section
+</TD>
+<TD>
+1.2
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ &gt;&gt; ] </TD>
+<TD ALIGN="CENTER">
+FastForward
+</TD>
+<TD>
+next or up-and-next section
+</TD>
+<TD>
+1.3
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [Top] </TD>
+<TD ALIGN="CENTER">
+Top
+</TD>
+<TD>
+cover (top) of document
+</TD>
+<TD>
+ &nbsp; 
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [Contents] </TD>
+<TD ALIGN="CENTER">
+Contents
+</TD>
+<TD>
+table of contents
+</TD>
+<TD>
+ &nbsp; 
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [Index] </TD>
+<TD ALIGN="CENTER">
+Index
+</TD>
+<TD>
+concept index
+</TD>
+<TD>
+ &nbsp; 
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ ? ] </TD>
+<TD ALIGN="CENTER">
+About
+</TD>
+<TD>
+this page
+</TD>
+<TD>
+ &nbsp; 
+</TD>
+</TR>
+</TABLE>
+<P></P>
+where the <STRONG> Example </STRONG> assumes that the current position 
+is at <STRONG> Subsubsection One-Two-Three </STRONG> of a document of 
+the following structure:
+<UL>
+<LI> 1. Section One  </LI>
+<UL>
+<LI>1.1 Subsection One-One</LI>
+<UL>
+<LI> ... </LI>
+</UL>
+<LI>1.2 Subsection One-Two</LI>
+<UL>
+<LI>1.2.1 Subsubsection One-Two-One
+</LI><LI>1.2.2 Subsubsection One-Two-Two
+</LI><LI>1.2.3 Subsubsection One-Two-Three &nbsp; &nbsp; <STRONG>
+&lt;== Current Position </STRONG>
+</LI><LI>1.2.4 Subsubsection One-Two-Four
+</LI></UL>
+<LI>1.3 Subsection One-Three</LI>
+<UL>
+<LI> ... </LI>
+</UL>
+<LI>1.4 Subsection One-Four</LI>
+</UL>
+</UL>
+
+<HR SIZE=1>
+<BR>  
+<FONT SIZE="-1">
+This document was generated
+on <I>December, 17  2017</I>
+using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
+"><I>texi2html</I></A>
+
+</BODY>
+</HTML>
Index: EcnlProtoTool/trunk/tcc-0.9.27/tcc-doc.texi
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tcc-doc.texi	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tcc-doc.texi	(revision 331)
@@ -0,0 +1,1326 @@
+\input texinfo @c -*- texinfo -*-
+@c %**start of header
+@setfilename tcc-doc.info
+@settitle Tiny C Compiler Reference Documentation
+@dircategory Software development
+@direntry
+* TCC: (tcc-doc).               The Tiny C Compiler.
+@end direntry
+@c %**end of header
+
+@include config.texi
+
+@iftex
+@titlepage
+@afourpaper
+@sp 7
+@center @titlefont{Tiny C Compiler Reference Documentation}
+@sp 3
+@end titlepage
+@headings double
+@end iftex
+
+@contents
+
+@node Top, Introduction, (dir), (dir)
+@top Tiny C Compiler Reference Documentation
+
+This manual documents version @value{VERSION} of the Tiny C Compiler.
+
+@menu
+* Introduction::                Introduction to tcc.
+* Invoke::                      Invocation of tcc (command line, options).
+* Clang::                       ANSI C and extensions.
+* asm::                         Assembler syntax.
+* linker::                      Output file generation and supported targets.
+* Bounds::                      Automatic bounds-checking of C code.
+* Libtcc::                      The libtcc library.
+* devel::                       Guide for Developers.
+@end menu
+
+
+@node Introduction
+@chapter Introduction
+
+TinyCC (aka TCC) is a small but hyper fast C compiler. Unlike other C
+compilers, it is meant to be self-relying: you do not need an
+external assembler or linker because TCC does that for you.
+
+TCC compiles so @emph{fast} that even for big projects @code{Makefile}s may
+not be necessary.
+
+TCC not only supports ANSI C, but also most of the new ISO C99
+standard and many GNUC extensions including inline assembly.
+
+TCC can also be used to make @emph{C scripts}, i.e. pieces of C source
+that you run as a Perl or Python script. Compilation is so fast that
+your script will be as fast as if it was an executable.
+
+TCC can also automatically generate memory and bound checks
+(@pxref{Bounds}) while allowing all C pointers operations. TCC can do
+these checks even if non patched libraries are used.
+
+With @code{libtcc}, you can use TCC as a backend for dynamic code
+generation (@pxref{Libtcc}).
+
+TCC mainly supports the i386 target on Linux and Windows. There are alpha
+ports for the ARM (@code{arm-tcc}) and the TMS320C67xx targets
+(@code{c67-tcc}). More information about the ARM port is available at
+@url{http://lists.gnu.org/archive/html/tinycc-devel/2003-10/msg00044.html}.
+
+For usage on Windows, see also @url{tcc-win32.txt}.
+
+@node Invoke
+@chapter Command line invocation
+
+@section Quick start
+
+@example
+@c man begin SYNOPSIS
+usage: tcc [options] [@var{infile1} @var{infile2}@dots{}] [@option{-run} @var{infile} @var{args}@dots{}]
+@c man end
+@end example
+
+@noindent
+@c man begin DESCRIPTION
+TCC options are a very much like gcc options. The main difference is that TCC
+can also execute directly the resulting program and give it runtime
+arguments.
+
+Here are some examples to understand the logic:
+
+@table @code
+@item @samp{tcc -run a.c}
+Compile @file{a.c} and execute it directly
+
+@item @samp{tcc -run a.c arg1}
+Compile a.c and execute it directly. arg1 is given as first argument to
+the @code{main()} of a.c.
+
+@item @samp{tcc a.c -run b.c arg1}
+Compile @file{a.c} and @file{b.c}, link them together and execute them. arg1 is given
+as first argument to the @code{main()} of the resulting program. 
+@ignore 
+Because multiple C files are specified, @option{--} are necessary to clearly 
+separate the program arguments from the TCC options.
+@end ignore
+
+@item @samp{tcc -o myprog a.c b.c}
+Compile @file{a.c} and @file{b.c}, link them and generate the executable @file{myprog}.
+
+@item @samp{tcc -o myprog a.o b.o}
+link @file{a.o} and @file{b.o} together and generate the executable @file{myprog}.
+
+@item @samp{tcc -c a.c}
+Compile @file{a.c} and generate object file @file{a.o}.
+
+@item @samp{tcc -c asmfile.S}
+Preprocess with C preprocess and assemble @file{asmfile.S} and generate
+object file @file{asmfile.o}.
+
+@item @samp{tcc -c asmfile.s}
+Assemble (but not preprocess) @file{asmfile.s} and generate object file
+@file{asmfile.o}.
+
+@item @samp{tcc -r -o ab.o a.c b.c}
+Compile @file{a.c} and @file{b.c}, link them together and generate the object file @file{ab.o}.
+
+@end table
+
+Scripting:
+
+TCC can be invoked from @emph{scripts}, just as shell scripts. You just
+need to add @code{#!/usr/local/bin/tcc -run} at the start of your C source:
+
+@example
+#!/usr/local/bin/tcc -run
+#include <stdio.h>
+
+int main() 
+@{
+    printf("Hello World\n");
+    return 0;
+@}
+@end example
+
+TCC can read C source code from @emph{standard input} when @option{-} is used in 
+place of @option{infile}. Example:
+
+@example
+echo 'main()@{puts("hello");@}' | tcc -run -
+@end example
+@c man end
+
+@section Option summary
+
+General Options:
+
+@c man begin OPTIONS
+@table @option
+@item -c
+Generate an object file.
+
+@item -o outfile
+Put object file, executable, or dll into output file @file{outfile}.
+
+@item -run source [args...]
+Compile file @var{source} and run it with the command line arguments
+@var{args}. In order to be able to give more than one argument to a
+script, several TCC options can be given @emph{after} the
+@option{-run} option, separated by spaces:
+@example
+tcc "-run -L/usr/X11R6/lib -lX11" ex4.c
+@end example
+In a script, it gives the following header:
+@example
+#!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
+@end example
+
+@item -v
+Display TCC version.
+
+@item -vv
+Show included files.  As sole argument, print search dirs.  -vvv shows tries too.
+
+@item -bench
+Display compilation statistics.
+
+@end table
+
+Preprocessor options:
+
+@table @option
+@item -Idir
+Specify an additional include path. Include paths are searched in the
+order they are specified.
+
+System include paths are always searched after. The default system
+include paths are: @file{/usr/local/include}, @file{/usr/include}
+and @file{PREFIX/lib/tcc/include}. (@file{PREFIX} is usually
+@file{/usr} or @file{/usr/local}).
+
+@item -Dsym[=val]
+Define preprocessor symbol @samp{sym} to
+val. If val is not present, its value is @samp{1}. Function-like macros can
+also be defined: @option{-DF(a)=a+1}
+
+@item -Usym
+Undefine preprocessor symbol @samp{sym}.
+
+@item -E
+Preprocess only, to stdout or file (with -o).
+
+@end table
+
+Compilation flags:
+
+Note: each of the following options has a negative form beginning with
+@option{-fno-}.
+
+@table @option
+@item -funsigned-char
+Let the @code{char} type be unsigned.
+
+@item -fsigned-char
+Let the @code{char} type be signed.
+
+@item -fno-common
+Do not generate common symbols for uninitialized data.
+
+@item -fleading-underscore
+Add a leading underscore at the beginning of each C symbol.
+
+@item -fms-extensions
+Allow a MS C compiler extensions to the language. Currently this
+assumes a nested named structure declaration without an identifier
+behaves like an unnamed one.
+
+@item -fdollars-in-identifiers
+Allow dollar signs in identifiers
+
+@end table
+
+Warning options:
+
+@table @option
+@item -w
+Disable all warnings.
+
+@end table
+
+Note: each of the following warning options has a negative form beginning with
+@option{-Wno-}.
+
+@table @option
+@item -Wimplicit-function-declaration
+Warn about implicit function declaration.
+
+@item -Wunsupported
+Warn about unsupported GCC features that are ignored by TCC.
+
+@item -Wwrite-strings
+Make string constants be of type @code{const char *} instead of @code{char
+*}.
+
+@item -Werror
+Abort compilation if warnings are issued.
+
+@item -Wall 
+Activate all warnings, except @option{-Werror}, @option{-Wunusupported} and
+@option{-Wwrite-strings}.
+
+@end table
+
+Linker options:
+
+@table @option
+@item -Ldir
+Specify an additional static library path for the @option{-l} option. The
+default library paths are @file{/usr/local/lib}, @file{/usr/lib} and @file{/lib}.
+
+@item -lxxx
+Link your program with dynamic library libxxx.so or static library
+libxxx.a. The library is searched in the paths specified by the
+@option{-L} option and @env{LIBRARY_PATH} variable.
+
+@item -Bdir
+Set the path where the tcc internal libraries (and include files) can be
+found (default is @file{PREFIX/lib/tcc}).
+
+@item -shared
+Generate a shared library instead of an executable.
+
+@item -soname name
+set name for shared library to be used at runtime
+
+@item -static
+Generate a statically linked executable (default is a shared linked
+executable).
+
+@item -rdynamic
+Export global symbols to the dynamic linker. It is useful when a library
+opened with @code{dlopen()} needs to access executable symbols.
+
+@item -r
+Generate an object file combining all input files.
+
+@item -Wl,-rpath=path
+Put custom search path for dynamic libraries into executable.
+
+@item -Wl,--enable-new-dtags
+When putting a custom search path for dynamic libraries into the executable,
+create the new ELF dynamic tag DT_RUNPATH instead of the old legacy DT_RPATH.
+
+@item -Wl,--oformat=fmt
+Use @var{fmt} as output format. The supported output formats are:
+@table @code
+@item elf32-i386
+ELF output format (default)
+@item binary
+Binary image (only for executable output)
+@item coff
+COFF output format (only for executable output for TMS320C67xx target)
+@end table
+
+@item -Wl,-subsystem=console/gui/wince/...
+Set type for PE (Windows) executables.
+
+@item -Wl,-[Ttext=# | section-alignment=# | file-alignment=# | image-base=# | stack=#]
+Modify executable layout.
+
+@item -Wl,-Bsymbolic
+Set DT_SYMBOLIC tag.
+
+@item -Wl,-(no-)whole-archive
+Turn on/off linking of all objects in archives.
+
+@end table
+
+Debugger options:
+
+@table @option
+@item -g
+Generate run time debug information so that you get clear run time
+error messages: @code{ test.c:68: in function 'test5()': dereferencing
+invalid pointer} instead of the laconic @code{Segmentation
+fault}.
+
+@item -b
+Generate additional support code to check
+memory allocations and array/pointer bounds. @option{-g} is implied. Note
+that the generated code is slower and bigger in this case.
+
+Note: @option{-b} is only available on i386 when using libtcc for the moment.
+
+@item -bt N
+Display N callers in stack traces. This is useful with @option{-g} or
+@option{-b}.
+
+@end table
+
+Misc options:
+
+@table @option
+@item -MD
+Generate makefile fragment with dependencies.
+
+@item -MF depfile
+Use @file{depfile} as output for -MD.
+
+@item -print-search-dirs
+Print the configured installation directory and a list of library
+and include directories tcc will search.
+
+@item -dumpversion
+Print version.
+
+@end table
+
+Target specific options:
+
+@table @option
+@item -mms-bitfields
+Use an algorithm for bitfield alignment consistent with MSVC. Default is
+gcc's algorithm.
+
+@item -mfloat-abi (ARM only)
+Select the float ABI. Possible values: @code{softfp} and @code{hard}
+
+@item -mno-sse
+Do not use sse registers on x86_64
+
+@item -m32, -m64
+Pass command line to the i386/x86_64 cross compiler.
+
+@end table
+
+Note: GCC options @option{-Ox}, @option{-fx} and @option{-mx} are
+ignored.
+@c man end
+
+@c man begin ENVIRONMENT
+Environment variables that affect how tcc operates.
+
+@table @option
+
+@item CPATH
+@item C_INCLUDE_PATH
+A colon-separated list of directories searched for include files,
+directories given with @option{-I} are searched first.
+
+@item LIBRARY_PATH
+A colon-separated list of directories searched for libraries for the
+@option{-l} option, directories given with @option{-L} are searched first.
+
+@end table
+
+@c man end
+
+@ignore
+
+@setfilename tcc
+@settitle Tiny C Compiler
+
+@c man begin SEEALSO
+cpp(1),
+gcc(1)
+@c man end
+
+@c man begin AUTHOR
+Fabrice Bellard
+@c man end
+
+@end ignore
+
+@node Clang
+@chapter C language support
+
+@section ANSI C
+
+TCC implements all the ANSI C standard, including structure bit fields
+and floating point numbers (@code{long double}, @code{double}, and
+@code{float} fully supported).
+
+@section ISOC99 extensions
+
+TCC implements many features of the new C standard: ISO C99. Currently
+missing items are: complex and imaginary numbers.
+
+Currently implemented ISOC99 features:
+
+@itemize
+
+@item variable length arrays.
+
+@item 64 bit @code{long long} types are fully supported.
+
+@item The boolean type @code{_Bool} is supported.
+
+@item @code{__func__} is a string variable containing the current
+function name.
+
+@item Variadic macros: @code{__VA_ARGS__} can be used for
+   function-like macros:
+@example
+    #define dprintf(level, __VA_ARGS__) printf(__VA_ARGS__)
+@end example
+
+@noindent
+@code{dprintf} can then be used with a variable number of parameters.
+
+@item Declarations can appear anywhere in a block (as in C++).
+
+@item Array and struct/union elements can be initialized in any order by
+  using designators:
+@example
+    struct @{ int x, y; @} st[10] = @{ [0].x = 1, [0].y = 2 @};
+
+    int tab[10] = @{ 1, 2, [5] = 5, [9] = 9@};
+@end example
+    
+@item Compound initializers are supported:
+@example
+    int *p = (int [])@{ 1, 2, 3 @};
+@end example
+to initialize a pointer pointing to an initialized array. The same
+works for structures and strings.
+
+@item Hexadecimal floating point constants are supported:
+@example
+          double d = 0x1234p10;
+@end example
+
+@noindent
+is the same as writing 
+@example
+          double d = 4771840.0;
+@end example
+
+@item @code{inline} keyword is ignored.
+
+@item @code{restrict} keyword is ignored.
+@end itemize
+
+@section GNU C extensions
+
+TCC implements some GNU C extensions:
+
+@itemize
+
+@item array designators can be used without '=': 
+@example
+    int a[10] = @{ [0] 1, [5] 2, 3, 4 @};
+@end example
+
+@item Structure field designators can be a label: 
+@example
+    struct @{ int x, y; @} st = @{ x: 1, y: 1@};
+@end example
+instead of
+@example
+    struct @{ int x, y; @} st = @{ .x = 1, .y = 1@};
+@end example
+
+@item @code{\e} is ASCII character 27.
+
+@item case ranges : ranges can be used in @code{case}s:
+@example
+    switch(a) @{
+    case 1 @dots{} 9:
+          printf("range 1 to 9\n");
+          break;
+    default:
+          printf("unexpected\n");
+          break;
+    @}
+@end example
+
+@cindex aligned attribute
+@cindex packed attribute
+@cindex section attribute
+@cindex unused attribute
+@cindex cdecl attribute
+@cindex stdcall attribute
+@cindex regparm attribute
+@cindex dllexport attribute
+
+@item The keyword @code{__attribute__} is handled to specify variable or
+function attributes. The following attributes are supported:
+  @itemize
+
+  @item @code{aligned(n)}: align a variable or a structure field to n bytes
+(must be a power of two).
+
+  @item @code{packed}: force alignment of a variable or a structure field to
+  1.
+
+  @item @code{section(name)}: generate function or data in assembly section
+name (name is a string containing the section name) instead of the default
+section.
+
+  @item @code{unused}: specify that the variable or the function is unused.
+
+  @item @code{cdecl}: use standard C calling convention (default).
+
+  @item @code{stdcall}: use Pascal-like calling convention.
+
+  @item @code{regparm(n)}: use fast i386 calling convention. @var{n} must be
+between 1 and 3. The first @var{n} function parameters are respectively put in
+registers @code{%eax}, @code{%edx} and @code{%ecx}.
+
+  @item @code{dllexport}: export function from dll/executable (win32 only)
+
+  @end itemize
+
+Here are some examples:
+@example
+    int a __attribute__ ((aligned(8), section(".mysection")));
+@end example
+
+@noindent
+align variable @code{a} to 8 bytes and put it in section @code{.mysection}.
+
+@example
+    int my_add(int a, int b) __attribute__ ((section(".mycodesection"))) 
+    @{
+        return a + b;
+    @}
+@end example
+
+@noindent
+generate function @code{my_add} in section @code{.mycodesection}.
+
+@item GNU style variadic macros:
+@example
+    #define dprintf(fmt, args@dots{}) printf(fmt, ## args)
+
+    dprintf("no arg\n");
+    dprintf("one arg %d\n", 1);
+@end example
+
+@item @code{__FUNCTION__} is interpreted as C99 @code{__func__} 
+(so it has not exactly the same semantics as string literal GNUC
+where it is a string literal).
+
+@item The @code{__alignof__} keyword can be used as @code{sizeof} 
+to get the alignment of a type or an expression.
+
+@item The @code{typeof(x)} returns the type of @code{x}. 
+@code{x} is an expression or a type.
+
+@item Computed gotos: @code{&&label} returns a pointer of type 
+@code{void *} on the goto label @code{label}. @code{goto *expr} can be
+used to jump on the pointer resulting from @code{expr}.
+
+@item Inline assembly with asm instruction:
+@cindex inline assembly
+@cindex assembly, inline
+@cindex __asm__
+@example
+static inline void * my_memcpy(void * to, const void * from, size_t n)
+@{
+int d0, d1, d2;
+__asm__ __volatile__(
+        "rep ; movsl\n\t"
+        "testb $2,%b4\n\t"
+        "je 1f\n\t"
+        "movsw\n"
+        "1:\ttestb $1,%b4\n\t"
+        "je 2f\n\t"
+        "movsb\n"
+        "2:"
+        : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+        :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+        : "memory");
+return (to);
+@}
+@end example
+
+@noindent
+@cindex gas
+TCC includes its own x86 inline assembler with a @code{gas}-like (GNU
+assembler) syntax. No intermediate files are generated. GCC 3.x named
+operands are supported.
+
+@item @code{__builtin_types_compatible_p()} and @code{__builtin_constant_p()} 
+are supported.
+
+@item @code{#pragma pack} is supported for win32 compatibility.
+
+@end itemize
+
+@section TinyCC extensions
+
+@itemize
+
+@item @code{__TINYC__} is a predefined macro to indicate that you use TCC.
+
+@item @code{#!} at the start of a line is ignored to allow scripting.
+
+@item Binary digits can be entered (@code{0b101} instead of
+@code{5}).
+
+@item @code{__BOUNDS_CHECKING_ON} is defined if bound checking is activated.
+
+@end itemize
+
+@node asm
+@chapter TinyCC Assembler
+
+Since version 0.9.16, TinyCC integrates its own assembler. TinyCC
+assembler supports a gas-like syntax (GNU assembler). You can
+deactivate assembler support if you want a smaller TinyCC executable
+(the C compiler does not rely on the assembler).
+
+TinyCC Assembler is used to handle files with @file{.S} (C
+preprocessed assembler) and @file{.s} extensions. It is also used to
+handle the GNU inline assembler with the @code{asm} keyword.
+
+@section Syntax
+
+TinyCC Assembler supports most of the gas syntax. The tokens are the
+same as C.
+
+@itemize
+
+@item C and C++ comments are supported.
+
+@item Identifiers are the same as C, so you cannot use '.' or '$'.
+
+@item Only 32 bit integer numbers are supported.
+
+@end itemize
+
+@section Expressions
+
+@itemize
+
+@item Integers in decimal, octal and hexa are supported.
+
+@item Unary operators: +, -, ~.
+
+@item Binary operators in decreasing priority order:
+
+@enumerate
+@item *, /, %
+@item &, |, ^
+@item +, -
+@end enumerate
+
+@item A value is either an absolute number or a label plus an offset. 
+All operators accept absolute values except '+' and '-'. '+' or '-' can be
+used to add an offset to a label. '-' supports two labels only if they
+are the same or if they are both defined and in the same section.
+
+@end itemize
+
+@section Labels
+
+@itemize
+
+@item All labels are considered as local, except undefined ones.
+
+@item Numeric labels can be used as local @code{gas}-like labels. 
+They can be defined several times in the same source. Use 'b'
+(backward) or 'f' (forward) as suffix to reference them:
+
+@example
+ 1:
+      jmp 1b /* jump to '1' label before */
+      jmp 1f /* jump to '1' label after */
+ 1:
+@end example
+
+@end itemize
+
+@section Directives
+@cindex assembler directives
+@cindex directives, assembler
+@cindex align directive
+@cindex skip directive
+@cindex space directive
+@cindex byte directive
+@cindex word directive
+@cindex short directive
+@cindex int directive
+@cindex long directive
+@cindex quad directive
+@cindex globl directive
+@cindex global directive
+@cindex section directive
+@cindex text directive
+@cindex data directive
+@cindex bss directive
+@cindex fill directive
+@cindex org directive
+@cindex previous directive
+@cindex string directive
+@cindex asciz directive
+@cindex ascii directive
+
+All directives are preceded by a '.'. The following directives are
+supported:
+
+@itemize
+@item .align n[,value]
+@item .skip n[,value]
+@item .space n[,value]
+@item .byte value1[,...]
+@item .word value1[,...]
+@item .short value1[,...]
+@item .int value1[,...]
+@item .long value1[,...]
+@item .quad immediate_value1[,...]
+@item .globl symbol
+@item .global symbol
+@item .section section
+@item .text
+@item .data
+@item .bss
+@item .fill repeat[,size[,value]]
+@item .org n
+@item .previous
+@item .string string[,...]
+@item .asciz string[,...]
+@item .ascii string[,...]
+@end itemize
+
+@section X86 Assembler
+@cindex assembler
+
+All X86 opcodes are supported. Only ATT syntax is supported (source
+then destination operand order). If no size suffix is given, TinyCC
+tries to guess it from the operand sizes.
+
+Currently, MMX opcodes are supported but not SSE ones.
+
+@node linker
+@chapter TinyCC Linker
+@cindex linker
+
+@section ELF file generation
+@cindex ELF
+
+TCC can directly output relocatable ELF files (object files),
+executable ELF files and dynamic ELF libraries without relying on an
+external linker.
+
+Dynamic ELF libraries can be output but the C compiler does not generate
+position independent code (PIC). It means that the dynamic library
+code generated by TCC cannot be factorized among processes yet.
+
+TCC linker eliminates unreferenced object code in libraries. A single pass is
+done on the object and library list, so the order in which object files and
+libraries are specified is important (same constraint as GNU ld). No grouping
+options (@option{--start-group} and @option{--end-group}) are supported.
+
+@section ELF file loader
+
+TCC can load ELF object files, archives (.a files) and dynamic
+libraries (.so).
+
+@section PE-i386 file generation
+@cindex PE-i386
+
+TCC for Windows supports the native Win32 executable file format (PE-i386).  It
+generates EXE files (console and gui) and DLL files.
+
+For usage on Windows, see also tcc-win32.txt.
+
+@section GNU Linker Scripts
+@cindex scripts, linker
+@cindex linker scripts
+@cindex GROUP, linker command
+@cindex FILE, linker command
+@cindex OUTPUT_FORMAT, linker command
+@cindex TARGET, linker command
+
+Because on many Linux systems some dynamic libraries (such as
+@file{/usr/lib/libc.so}) are in fact GNU ld link scripts (horrible!),
+the TCC linker also supports a subset of GNU ld scripts.
+
+The @code{GROUP} and @code{FILE} commands are supported. @code{OUTPUT_FORMAT}
+and @code{TARGET} are ignored.
+
+Example from @file{/usr/lib/libc.so}:
+@example
+/* GNU ld script
+   Use the shared library, but some functions are only in
+   the static library, so try that secondarily.  */
+GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a )
+@end example
+
+@node Bounds
+@chapter TinyCC Memory and Bound checks
+@cindex bound checks
+@cindex memory checks
+
+This feature is activated with the @option{-b} (@pxref{Invoke}).
+
+Note that pointer size is @emph{unchanged} and that code generated
+with bound checks is @emph{fully compatible} with unchecked
+code. When a pointer comes from unchecked code, it is assumed to be
+valid. Even very obscure C code with casts should work correctly.
+
+For more information about the ideas behind this method, see
+@url{http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html}.
+
+Here are some examples of caught errors:
+
+@table @asis
+
+@item Invalid range with standard string function:
+@example
+@{
+    char tab[10];
+    memset(tab, 0, 11);
+@}
+@end example
+
+@item Out of bounds-error in global or local arrays:
+@example
+@{
+    int tab[10];
+    for(i=0;i<11;i++) @{
+        sum += tab[i];
+    @}
+@}
+@end example
+
+@item Out of bounds-error in malloc'ed data:
+@example
+@{
+    int *tab;
+    tab = malloc(20 * sizeof(int));
+    for(i=0;i<21;i++) @{
+        sum += tab4[i];
+    @}
+    free(tab);
+@}
+@end example
+
+@item Access of freed memory:
+@example
+@{
+    int *tab;
+    tab = malloc(20 * sizeof(int));
+    free(tab);
+    for(i=0;i<20;i++) @{
+        sum += tab4[i];
+    @}
+@}
+@end example
+
+@item Double free:
+@example
+@{
+    int *tab;
+    tab = malloc(20 * sizeof(int));
+    free(tab);
+    free(tab);
+@}
+@end example
+
+@end table
+
+@node Libtcc
+@chapter The @code{libtcc} library
+
+The @code{libtcc} library enables you to use TCC as a backend for
+dynamic code generation. 
+
+Read the @file{libtcc.h} to have an overview of the API. Read
+@file{libtcc_test.c} to have a very simple example.
+
+The idea consists in giving a C string containing the program you want
+to compile directly to @code{libtcc}. Then you can access to any global
+symbol (function or variable) defined.
+
+@node devel
+@chapter Developer's guide
+
+This chapter gives some hints to understand how TCC works. You can skip
+it if you do not intend to modify the TCC code.
+
+@section File reading
+
+The @code{BufferedFile} structure contains the context needed to read a
+file, including the current line number. @code{tcc_open()} opens a new
+file and @code{tcc_close()} closes it. @code{inp()} returns the next
+character.
+
+@section Lexer
+
+@code{next()} reads the next token in the current
+file. @code{next_nomacro()} reads the next token without macro
+expansion.
+
+@code{tok} contains the current token (see @code{TOK_xxx})
+constants. Identifiers and keywords are also keywords. @code{tokc}
+contains additional infos about the token (for example a constant value
+if number or string token).
+
+@section Parser
+
+The parser is hardcoded (yacc is not necessary). It does only one pass,
+except:
+
+@itemize
+
+@item For initialized arrays with unknown size, a first pass 
+is done to count the number of elements.
+
+@item For architectures where arguments are evaluated in 
+reverse order, a first pass is done to reverse the argument order.
+
+@end itemize
+
+@section Types
+
+The types are stored in a single 'int' variable. It was chosen in the
+first stages of development when tcc was much simpler. Now, it may not
+be the best solution.
+
+@example
+#define VT_INT        0  /* integer type */
+#define VT_BYTE       1  /* signed byte type */
+#define VT_SHORT      2  /* short type */
+#define VT_VOID       3  /* void type */
+#define VT_PTR        4  /* pointer */
+#define VT_ENUM       5  /* enum definition */
+#define VT_FUNC       6  /* function type */
+#define VT_STRUCT     7  /* struct/union definition */
+#define VT_FLOAT      8  /* IEEE float */
+#define VT_DOUBLE     9  /* IEEE double */
+#define VT_LDOUBLE   10  /* IEEE long double */
+#define VT_BOOL      11  /* ISOC99 boolean type */
+#define VT_LLONG     12  /* 64 bit integer */
+#define VT_LONG      13  /* long integer (NEVER USED as type, only
+                            during parsing) */
+#define VT_BTYPE      0x000f /* mask for basic type */
+#define VT_UNSIGNED   0x0010  /* unsigned type */
+#define VT_ARRAY      0x0020  /* array type (also has VT_PTR) */
+#define VT_VLA        0x20000 /* VLA type (also has VT_PTR and VT_ARRAY) */
+#define VT_BITFIELD   0x0040  /* bitfield modifier */
+#define VT_CONSTANT   0x0800  /* const modifier */
+#define VT_VOLATILE   0x1000  /* volatile modifier */
+#define VT_DEFSIGN    0x2000  /* signed type */
+
+#define VT_STRUCT_SHIFT 18   /* structure/enum name shift (14 bits left) */
+@end example
+
+When a reference to another type is needed (for pointers, functions and
+structures), the @code{32 - VT_STRUCT_SHIFT} high order bits are used to
+store an identifier reference.
+
+The @code{VT_UNSIGNED} flag can be set for chars, shorts, ints and long
+longs.
+
+Arrays are considered as pointers @code{VT_PTR} with the flag
+@code{VT_ARRAY} set. Variable length arrays are considered as special
+arrays and have flag @code{VT_VLA} set instead of @code{VT_ARRAY}.
+
+The @code{VT_BITFIELD} flag can be set for chars, shorts, ints and long
+longs. If it is set, then the bitfield position is stored from bits
+VT_STRUCT_SHIFT to VT_STRUCT_SHIFT + 5 and the bit field size is stored
+from bits VT_STRUCT_SHIFT + 6 to VT_STRUCT_SHIFT + 11.
+
+@code{VT_LONG} is never used except during parsing.
+
+During parsing, the storage of an object is also stored in the type
+integer:
+
+@example
+#define VT_EXTERN  0x00000080  /* extern definition */
+#define VT_STATIC  0x00000100  /* static variable */
+#define VT_TYPEDEF 0x00000200  /* typedef definition */
+#define VT_INLINE  0x00000400  /* inline definition */
+#define VT_IMPORT  0x00004000  /* win32: extern data imported from dll */
+#define VT_EXPORT  0x00008000  /* win32: data exported from dll */
+#define VT_WEAK    0x00010000  /* win32: data exported from dll */
+@end example
+
+@section Symbols
+
+All symbols are stored in hashed symbol stacks. Each symbol stack
+contains @code{Sym} structures.
+
+@code{Sym.v} contains the symbol name (remember
+an identifier is also a token, so a string is never necessary to store
+it). @code{Sym.t} gives the type of the symbol. @code{Sym.r} is usually
+the register in which the corresponding variable is stored. @code{Sym.c} is
+usually a constant associated to the symbol like its address for normal
+symbols, and the number of entries for symbols representing arrays.
+Variable length array types use @code{Sym.c} as a location on the stack
+which holds the runtime sizeof for the type.
+
+Four main symbol stacks are defined:
+
+@table @code
+
+@item define_stack
+for the macros (@code{#define}s).
+
+@item global_stack
+for the global variables, functions and types.
+
+@item local_stack
+for the local variables, functions and types.
+
+@item global_label_stack
+for the local labels (for @code{goto}).
+
+@item label_stack
+for GCC block local labels (see the @code{__label__} keyword).
+
+@end table
+
+@code{sym_push()} is used to add a new symbol in the local symbol
+stack. If no local symbol stack is active, it is added in the global
+symbol stack.
+
+@code{sym_pop(st,b)} pops symbols from the symbol stack @var{st} until
+the symbol @var{b} is on the top of stack. If @var{b} is NULL, the stack
+is emptied.
+
+@code{sym_find(v)} return the symbol associated to the identifier
+@var{v}. The local stack is searched first from top to bottom, then the
+global stack.
+
+@section Sections
+
+The generated code and data are written in sections. The structure
+@code{Section} contains all the necessary information for a given
+section. @code{new_section()} creates a new section. ELF file semantics
+is assumed for each section.
+
+The following sections are predefined:
+
+@table @code
+
+@item text_section
+is the section containing the generated code. @var{ind} contains the
+current position in the code section.
+
+@item data_section
+contains initialized data
+
+@item bss_section
+contains uninitialized data
+
+@item bounds_section
+@itemx lbounds_section
+are used when bound checking is activated
+
+@item stab_section
+@itemx stabstr_section
+are used when debugging is active to store debug information
+
+@item symtab_section
+@itemx strtab_section
+contain the exported symbols (currently only used for debugging).
+
+@end table
+
+@section Code generation
+@cindex code generation
+
+@subsection Introduction
+
+The TCC code generator directly generates linked binary code in one
+pass. It is rather unusual these days (see gcc for example which
+generates text assembly), but it can be very fast and surprisingly
+little complicated.
+
+The TCC code generator is register based. Optimization is only done at
+the expression level. No intermediate representation of expression is
+kept except the current values stored in the @emph{value stack}.
+
+On x86, three temporary registers are used. When more registers are
+needed, one register is spilled into a new temporary variable on the stack.
+
+@subsection The value stack
+@cindex value stack, introduction
+
+When an expression is parsed, its value is pushed on the value stack
+(@var{vstack}). The top of the value stack is @var{vtop}. Each value
+stack entry is the structure @code{SValue}.
+
+@code{SValue.t} is the type. @code{SValue.r} indicates how the value is
+currently stored in the generated code. It is usually a CPU register
+index (@code{REG_xxx} constants), but additional values and flags are
+defined:
+
+@example
+#define VT_CONST     0x00f0
+#define VT_LLOCAL    0x00f1
+#define VT_LOCAL     0x00f2
+#define VT_CMP       0x00f3
+#define VT_JMP       0x00f4
+#define VT_JMPI      0x00f5
+#define VT_LVAL      0x0100
+#define VT_SYM       0x0200
+#define VT_MUSTCAST  0x0400
+#define VT_MUSTBOUND 0x0800
+#define VT_BOUNDED   0x8000
+#define VT_LVAL_BYTE     0x1000
+#define VT_LVAL_SHORT    0x2000
+#define VT_LVAL_UNSIGNED 0x4000
+#define VT_LVAL_TYPE     (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
+@end example
+
+@table @code
+
+@item VT_CONST
+indicates that the value is a constant. It is stored in the union
+@code{SValue.c}, depending on its type.
+
+@item VT_LOCAL
+indicates a local variable pointer at offset @code{SValue.c.i} in the
+stack.
+
+@item VT_CMP
+indicates that the value is actually stored in the CPU flags (i.e. the
+value is the consequence of a test). The value is either 0 or 1. The
+actual CPU flags used is indicated in @code{SValue.c.i}. 
+
+If any code is generated which destroys the CPU flags, this value MUST be
+put in a normal register.
+
+@item VT_JMP
+@itemx VT_JMPI
+indicates that the value is the consequence of a conditional jump. For VT_JMP,
+it is 1 if the jump is taken, 0 otherwise. For VT_JMPI it is inverted.
+
+These values are used to compile the @code{||} and @code{&&} logical
+operators.
+
+If any code is generated, this value MUST be put in a normal
+register. Otherwise, the generated code won't be executed if the jump is
+taken.
+
+@item VT_LVAL
+is a flag indicating that the value is actually an lvalue (left value of
+an assignment). It means that the value stored is actually a pointer to
+the wanted value. 
+
+Understanding the use @code{VT_LVAL} is very important if you want to
+understand how TCC works.
+
+@item VT_LVAL_BYTE
+@itemx VT_LVAL_SHORT
+@itemx VT_LVAL_UNSIGNED
+if the lvalue has an integer type, then these flags give its real
+type. The type alone is not enough in case of cast optimisations.
+
+@item VT_LLOCAL
+is a saved lvalue on the stack. @code{VT_LVAL} must also be set with
+@code{VT_LLOCAL}. @code{VT_LLOCAL} can arise when a @code{VT_LVAL} in
+a register has to be saved to the stack, or it can come from an
+architecture-specific calling convention.
+
+@item VT_MUSTCAST
+indicates that a cast to the value type must be performed if the value
+is used (lazy casting).
+
+@item VT_SYM
+indicates that the symbol @code{SValue.sym} must be added to the constant.
+
+@item VT_MUSTBOUND
+@itemx VT_BOUNDED
+are only used for optional bound checking.
+
+@end table
+
+@subsection Manipulating the value stack
+@cindex value stack
+
+@code{vsetc()} and @code{vset()} pushes a new value on the value
+stack. If the previous @var{vtop} was stored in a very unsafe place(for
+example in the CPU flags), then some code is generated to put the
+previous @var{vtop} in a safe storage.
+
+@code{vpop()} pops @var{vtop}. In some cases, it also generates cleanup
+code (for example if stacked floating point registers are used as on
+x86).
+
+The @code{gv(rc)} function generates code to evaluate @var{vtop} (the
+top value of the stack) into registers. @var{rc} selects in which
+register class the value should be put. @code{gv()} is the @emph{most
+important function} of the code generator.
+
+@code{gv2()} is the same as @code{gv()} but for the top two stack
+entries.
+
+@subsection CPU dependent code generation
+@cindex CPU dependent
+See the @file{i386-gen.c} file to have an example.
+
+@table @code
+
+@item load()
+must generate the code needed to load a stack value into a register.
+
+@item store()
+must generate the code needed to store a register into a stack value
+lvalue.
+
+@item gfunc_start()
+@itemx gfunc_param()
+@itemx gfunc_call()
+should generate a function call
+
+@item gfunc_prolog()
+@itemx gfunc_epilog()
+should generate a function prolog/epilog.
+
+@item gen_opi(op)
+must generate the binary integer operation @var{op} on the two top
+entries of the stack which are guaranteed to contain integer types.
+
+The result value should be put on the stack.
+
+@item gen_opf(op)
+same as @code{gen_opi()} for floating point operations. The two top
+entries of the stack are guaranteed to contain floating point values of
+same types.
+
+@item gen_cvt_itof()
+integer to floating point conversion.
+
+@item gen_cvt_ftoi()
+floating point to integer conversion.
+
+@item gen_cvt_ftof()
+floating point to floating point of different size conversion.
+
+@item gen_bounded_ptr_add()
+@item gen_bounded_ptr_deref()
+are only used for bounds checking.
+
+@end table
+
+@section Optimizations done
+@cindex optimizations
+@cindex constant propagation
+@cindex strength reduction
+@cindex comparison operators
+@cindex caching processor flags
+@cindex flags, caching
+@cindex jump optimization
+Constant propagation is done for all operations. Multiplications and
+divisions are optimized to shifts when appropriate. Comparison
+operators are optimized by maintaining a special cache for the
+processor flags. &&, || and ! are optimized by maintaining a special
+'jump target' value. No other jump optimization is currently performed
+because it would require to store the code in a more abstract fashion.
+
+@unnumbered Concept Index
+@printindex cp
+
+@bye
+
+@c Local variables:
+@c fill-column: 78
+@c texinfo-column-for-description: 32
+@c End:
Index: EcnlProtoTool/trunk/tcc-0.9.27/tcc.1
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tcc.1	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tcc.1	(revision 331)
@@ -0,0 +1,458 @@
+.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.32
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings.  \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote.  | will give a
+.\" real vertical bar.  \*(C+ will give a nicer C++.  Capital omega is used to
+.\" do unbreakable dashes and therefore won't be available.  \*(C` and \*(C'
+.\" expand to `' in nroff, nothing in troff, for use with C<>.
+.tr \(*W-|\(bv\*(Tr
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+.    ds -- \(*W-
+.    ds PI pi
+.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
+.    ds L" ""
+.    ds R" ""
+.    ds C` ""
+.    ds C' ""
+'br\}
+.el\{\
+.    ds -- \|\(em\|
+.    ds PI \(*p
+.    ds L" ``
+.    ds R" ''
+'br\}
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
+.\" entries marked with X<> in POD.  Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.if \nF \{\
+.    de IX
+.    tm Index:\\$1\t\\n%\t"\\$2"
+..
+.    nr % 0
+.    rr F
+.\}
+.\"
+.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.hy 0
+.if n .na
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
+.    \" fudge factors for nroff and troff
+.if n \{\
+.    ds #H 0
+.    ds #V .8m
+.    ds #F .3m
+.    ds #[ \f1
+.    ds #] \fP
+.\}
+.if t \{\
+.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+.    ds #V .6m
+.    ds #F 0
+.    ds #[ \&
+.    ds #] \&
+.\}
+.    \" simple accents for nroff and troff
+.if n \{\
+.    ds ' \&
+.    ds ` \&
+.    ds ^ \&
+.    ds , \&
+.    ds ~ ~
+.    ds /
+.\}
+.if t \{\
+.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+.    \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+.    \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+.    \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+.    ds : e
+.    ds 8 ss
+.    ds o a
+.    ds d- d\h'-1'\(ga
+.    ds D- D\h'-1'\(hy
+.    ds th \o'bp'
+.    ds Th \o'LP'
+.    ds ae ae
+.    ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "TCC 1"
+.TH TCC 1 "2018-01-07" "0.9.27" "Tiny C Compiler"
+.SH "NAME"
+tcc \- Tiny C Compiler
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+usage: tcc [options] [\fIinfile1\fR \fIinfile2\fR...] [\fB\-run\fR \fIinfile\fR \fIargs\fR...]
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+\&\s-1TCC\s0 options are a very much like gcc options. The main difference is that \s-1TCC\s0
+can also execute directly the resulting program and give it runtime
+arguments.
+.PP
+Here are some examples to understand the logic:
+.ie n .IP """\f(CBtcc \-run a.c\f(CW""" 4
+.el .IP "\f(CW\f(CBtcc \-run a.c\f(CW\fR" 4
+.IX Item "tcc -run a.c"
+Compile \fIa.c\fR and execute it directly
+.ie n .IP """\f(CBtcc \-run a.c arg1\f(CW""" 4
+.el .IP "\f(CW\f(CBtcc \-run a.c arg1\f(CW\fR" 4
+.IX Item "tcc -run a.c arg1"
+Compile a.c and execute it directly. arg1 is given as first argument to
+the \f(CW\*(C`main()\*(C'\fR of a.c.
+.ie n .IP """\f(CBtcc a.c \-run b.c arg1\f(CW""" 4
+.el .IP "\f(CW\f(CBtcc a.c \-run b.c arg1\f(CW\fR" 4
+.IX Item "tcc a.c -run b.c arg1"
+Compile \fIa.c\fR and \fIb.c\fR, link them together and execute them. arg1 is given
+as first argument to the \f(CW\*(C`main()\*(C'\fR of the resulting program. 
+.ie n .IP """\f(CBtcc \-o myprog a.c b.c\f(CW""" 4
+.el .IP "\f(CW\f(CBtcc \-o myprog a.c b.c\f(CW\fR" 4
+.IX Item "tcc -o myprog a.c b.c"
+Compile \fIa.c\fR and \fIb.c\fR, link them and generate the executable \fImyprog\fR.
+.ie n .IP """\f(CBtcc \-o myprog a.o b.o\f(CW""" 4
+.el .IP "\f(CW\f(CBtcc \-o myprog a.o b.o\f(CW\fR" 4
+.IX Item "tcc -o myprog a.o b.o"
+link \fIa.o\fR and \fIb.o\fR together and generate the executable \fImyprog\fR.
+.ie n .IP """\f(CBtcc \-c a.c\f(CW""" 4
+.el .IP "\f(CW\f(CBtcc \-c a.c\f(CW\fR" 4
+.IX Item "tcc -c a.c"
+Compile \fIa.c\fR and generate object file \fIa.o\fR.
+.ie n .IP """\f(CBtcc \-c asmfile.S\f(CW""" 4
+.el .IP "\f(CW\f(CBtcc \-c asmfile.S\f(CW\fR" 4
+.IX Item "tcc -c asmfile.S"
+Preprocess with C preprocess and assemble \fIasmfile.S\fR and generate
+object file \fIasmfile.o\fR.
+.ie n .IP """\f(CBtcc \-c asmfile.s\f(CW""" 4
+.el .IP "\f(CW\f(CBtcc \-c asmfile.s\f(CW\fR" 4
+.IX Item "tcc -c asmfile.s"
+Assemble (but not preprocess) \fIasmfile.s\fR and generate object file
+\&\fIasmfile.o\fR.
+.ie n .IP """\f(CBtcc \-r \-o ab.o a.c b.c\f(CW""" 4
+.el .IP "\f(CW\f(CBtcc \-r \-o ab.o a.c b.c\f(CW\fR" 4
+.IX Item "tcc -r -o ab.o a.c b.c"
+Compile \fIa.c\fR and \fIb.c\fR, link them together and generate the object file \fIab.o\fR.
+.PP
+Scripting:
+.PP
+\&\s-1TCC\s0 can be invoked from \fIscripts\fR, just as shell scripts. You just
+need to add \f(CW\*(C`#!/usr/local/bin/tcc \-run\*(C'\fR at the start of your C source:
+.PP
+.Vb 2
+\&        #!/usr/local/bin/tcc -run
+\&        #include <stdio.h>
+.Ve
+.PP
+.Vb 5
+\&        int main() 
+\&        {
+\&            printf("Hello World\en");
+\&            return 0;
+\&        }
+.Ve
+.PP
+\&\s-1TCC\s0 can read C source code from \fIstandard input\fR when \fB\-\fR is used in 
+place of \fBinfile\fR. Example:
+.PP
+.Vb 1
+\&        echo 'main(){puts("hello");}' | tcc -run -
+.Ve
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+.IP "\fB\-c\fR" 4
+.IX Item "-c"
+Generate an object file.
+.IP "\fB\-o outfile\fR" 4
+.IX Item "-o outfile"
+Put object file, executable, or dll into output file \fIoutfile\fR.
+.IP "\fB\-run source [args...]\fR" 4
+.IX Item "-run source [args...]"
+Compile file \fIsource\fR and run it with the command line arguments
+\&\fIargs\fR. In order to be able to give more than one argument to a
+script, several \s-1TCC\s0 options can be given \fIafter\fR the
+\&\fB\-run\fR option, separated by spaces:
+.Sp
+.Vb 1
+\&        tcc "-run -L/usr/X11R6/lib -lX11" ex4.c
+.Ve
+.Sp
+In a script, it gives the following header:
+.Sp
+.Vb 1
+\&        #!/usr/local/bin/tcc -run -L/usr/X11R6/lib -lX11
+.Ve
+.IP "\fB\-v\fR" 4
+.IX Item "-v"
+Display \s-1TCC\s0 version.
+.IP "\fB\-vv\fR" 4
+.IX Item "-vv"
+Show included files.  As sole argument, print search dirs.  \-vvv shows tries too.
+.IP "\fB\-bench\fR" 4
+.IX Item "-bench"
+Display compilation statistics.
+.PP
+Preprocessor options:
+.IP "\fB\-Idir\fR" 4
+.IX Item "-Idir"
+Specify an additional include path. Include paths are searched in the
+order they are specified.
+.Sp
+System include paths are always searched after. The default system
+include paths are: \fI/usr/local/include\fR, \fI/usr/include\fR
+and \fIPREFIX/lib/tcc/include\fR. (\fI\s-1PREFIX\s0\fR is usually
+\&\fI/usr\fR or \fI/usr/local\fR).
+.IP "\fB\-Dsym[=val]\fR" 4
+.IX Item "-Dsym[=val]"
+Define preprocessor symbol \fBsym\fR to
+val. If val is not present, its value is \fB1\fR. Function-like macros can
+also be defined: \fB\-DF(a)=a+1\fR
+.IP "\fB\-Usym\fR" 4
+.IX Item "-Usym"
+Undefine preprocessor symbol \fBsym\fR.
+.IP "\fB\-E\fR" 4
+.IX Item "-E"
+Preprocess only, to stdout or file (with \-o).
+.PP
+Compilation flags:
+.PP
+Note: each of the following options has a negative form beginning with
+\&\fB\-fno\-\fR.
+.IP "\fB\-funsigned\-char\fR" 4
+.IX Item "-funsigned-char"
+Let the \f(CW\*(C`char\*(C'\fR type be unsigned.
+.IP "\fB\-fsigned\-char\fR" 4
+.IX Item "-fsigned-char"
+Let the \f(CW\*(C`char\*(C'\fR type be signed.
+.IP "\fB\-fno\-common\fR" 4
+.IX Item "-fno-common"
+Do not generate common symbols for uninitialized data.
+.IP "\fB\-fleading\-underscore\fR" 4
+.IX Item "-fleading-underscore"
+Add a leading underscore at the beginning of each C symbol.
+.IP "\fB\-fms\-extensions\fR" 4
+.IX Item "-fms-extensions"
+Allow a \s-1MS\s0 C compiler extensions to the language. Currently this
+assumes a nested named structure declaration without an identifier
+behaves like an unnamed one.
+.IP "\fB\-fdollars\-in\-identifiers\fR" 4
+.IX Item "-fdollars-in-identifiers"
+Allow dollar signs in identifiers
+.PP
+Warning options:
+.IP "\fB\-w\fR" 4
+.IX Item "-w"
+Disable all warnings.
+.PP
+Note: each of the following warning options has a negative form beginning with
+\&\fB\-Wno\-\fR.
+.IP "\fB\-Wimplicit\-function\-declaration\fR" 4
+.IX Item "-Wimplicit-function-declaration"
+Warn about implicit function declaration.
+.IP "\fB\-Wunsupported\fR" 4
+.IX Item "-Wunsupported"
+Warn about unsupported \s-1GCC\s0 features that are ignored by \s-1TCC\s0.
+.IP "\fB\-Wwrite\-strings\fR" 4
+.IX Item "-Wwrite-strings"
+Make string constants be of type \f(CW\*(C`const char *\*(C'\fR instead of \f(CW\*(C`char
+*\*(C'\fR.
+.IP "\fB\-Werror\fR" 4
+.IX Item "-Werror"
+Abort compilation if warnings are issued.
+.IP "\fB\-Wall\fR" 4
+.IX Item "-Wall"
+Activate all warnings, except \fB\-Werror\fR, \fB\-Wunusupported\fR and
+\&\fB\-Wwrite\-strings\fR.
+.PP
+Linker options:
+.IP "\fB\-Ldir\fR" 4
+.IX Item "-Ldir"
+Specify an additional static library path for the \fB\-l\fR option. The
+default library paths are \fI/usr/local/lib\fR, \fI/usr/lib\fR and \fI/lib\fR.
+.IP "\fB\-lxxx\fR" 4
+.IX Item "-lxxx"
+Link your program with dynamic library libxxx.so or static library
+libxxx.a. The library is searched in the paths specified by the
+\&\fB\-L\fR option and \fB\s-1LIBRARY_PATH\s0\fR variable.
+.IP "\fB\-Bdir\fR" 4
+.IX Item "-Bdir"
+Set the path where the tcc internal libraries (and include files) can be
+found (default is \fIPREFIX/lib/tcc\fR).
+.IP "\fB\-shared\fR" 4
+.IX Item "-shared"
+Generate a shared library instead of an executable.
+.IP "\fB\-soname name\fR" 4
+.IX Item "-soname name"
+set name for shared library to be used at runtime
+.IP "\fB\-static\fR" 4
+.IX Item "-static"
+Generate a statically linked executable (default is a shared linked
+executable).
+.IP "\fB\-rdynamic\fR" 4
+.IX Item "-rdynamic"
+Export global symbols to the dynamic linker. It is useful when a library
+opened with \f(CW\*(C`dlopen()\*(C'\fR needs to access executable symbols.
+.IP "\fB\-r\fR" 4
+.IX Item "-r"
+Generate an object file combining all input files.
+.IP "\fB\-Wl,\-rpath=path\fR" 4
+.IX Item "-Wl,-rpath=path"
+Put custom search path for dynamic libraries into executable.
+.IP "\fB\-Wl,\-\-enable\-new\-dtags\fR" 4
+.IX Item "-Wl,--enable-new-dtags"
+When putting a custom search path for dynamic libraries into the executable,
+create the new \s-1ELF\s0 dynamic tag \s-1DT_RUNPATH\s0 instead of the old legacy \s-1DT_RPATH\s0.
+.IP "\fB\-Wl,\-\-oformat=fmt\fR" 4
+.IX Item "-Wl,--oformat=fmt"
+Use \fIfmt\fR as output format. The supported output formats are:
+.RS 4
+.ie n .IP """elf32\-i386""" 4
+.el .IP "\f(CWelf32\-i386\fR" 4
+.IX Item "elf32-i386"
+\&\s-1ELF\s0 output format (default)
+.ie n .IP """binary""" 4
+.el .IP "\f(CWbinary\fR" 4
+.IX Item "binary"
+Binary image (only for executable output)
+.ie n .IP """coff""" 4
+.el .IP "\f(CWcoff\fR" 4
+.IX Item "coff"
+\&\s-1COFF\s0 output format (only for executable output for TMS320C67xx target)
+.RE
+.RS 4
+.RE
+.IP "\fB\-Wl,\-subsystem=console/gui/wince/...\fR" 4
+.IX Item "-Wl,-subsystem=console/gui/wince/..."
+Set type for \s-1PE\s0 (Windows) executables.
+.IP "\fB\-Wl,\-[Ttext=# | section\-alignment=# | file\-alignment=# | image\-base=# | stack=#]\fR" 4
+.IX Item "-Wl,-[Ttext=# | section-alignment=# | file-alignment=# | image-base=# | stack=#]"
+Modify executable layout.
+.IP "\fB\-Wl,\-Bsymbolic\fR" 4
+.IX Item "-Wl,-Bsymbolic"
+Set \s-1DT_SYMBOLIC\s0 tag.
+.IP "\fB\-Wl,\-(no\-)whole\-archive\fR" 4
+.IX Item "-Wl,-(no-)whole-archive"
+Turn on/off linking of all objects in archives.
+.PP
+Debugger options:
+.IP "\fB\-g\fR" 4
+.IX Item "-g"
+Generate run time debug information so that you get clear run time
+error messages: \f(CW\*(C` test.c:68: in function 'test5()': dereferencing
+invalid pointer\*(C'\fR instead of the laconic \f(CW\*(C`Segmentation
+fault\*(C'\fR.
+.IP "\fB\-b\fR" 4
+.IX Item "-b"
+Generate additional support code to check
+memory allocations and array/pointer bounds. \fB\-g\fR is implied. Note
+that the generated code is slower and bigger in this case.
+.Sp
+Note: \fB\-b\fR is only available on i386 when using libtcc for the moment.
+.IP "\fB\-bt N\fR" 4
+.IX Item "-bt N"
+Display N callers in stack traces. This is useful with \fB\-g\fR or
+\&\fB\-b\fR.
+.PP
+Misc options:
+.IP "\fB\-MD\fR" 4
+.IX Item "-MD"
+Generate makefile fragment with dependencies.
+.IP "\fB\-MF depfile\fR" 4
+.IX Item "-MF depfile"
+Use \fIdepfile\fR as output for \-MD.
+.IP "\fB\-print\-search\-dirs\fR" 4
+.IX Item "-print-search-dirs"
+Print the configured installation directory and a list of library
+and include directories tcc will search.
+.IP "\fB\-dumpversion\fR" 4
+.IX Item "-dumpversion"
+Print version.
+.PP
+Target specific options:
+.IP "\fB\-mms\-bitfields\fR" 4
+.IX Item "-mms-bitfields"
+Use an algorithm for bitfield alignment consistent with \s-1MSVC\s0. Default is
+gcc's algorithm.
+.IP "\fB\-mfloat\-abi (\s-1ARM\s0 only)\fR" 4
+.IX Item "-mfloat-abi (ARM only)"
+Select the float \s-1ABI\s0. Possible values: \f(CW\*(C`softfp\*(C'\fR and \f(CW\*(C`hard\*(C'\fR
+.IP "\fB\-mno\-sse\fR" 4
+.IX Item "-mno-sse"
+Do not use sse registers on x86_64
+.IP "\fB\-m32, \-m64\fR" 4
+.IX Item "-m32, -m64"
+Pass command line to the i386/x86_64 cross compiler.
+.PP
+Note: \s-1GCC\s0 options \fB\-Ox\fR, \fB\-fx\fR and \fB\-mx\fR are
+ignored.
+.SH "ENVIRONMENT"
+.IX Header "ENVIRONMENT"
+Environment variables that affect how tcc operates.
+.IP "\fB\s-1CPATH\s0\fR" 4
+.IX Item "CPATH"
+.PD 0
+.IP "\fBC_INCLUDE_PATH\fR" 4
+.IX Item "C_INCLUDE_PATH"
+.PD
+A colon-separated list of directories searched for include files,
+directories given with \fB\-I\fR are searched first.
+.IP "\fB\s-1LIBRARY_PATH\s0\fR" 4
+.IX Item "LIBRARY_PATH"
+A colon-separated list of directories searched for libraries for the
+\&\fB\-l\fR option, directories given with \fB\-L\fR are searched first.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\fIcpp\fR\|(1),
+\&\fIgcc\fR\|(1)
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Fabrice Bellard
Index: EcnlProtoTool/trunk/tcc-0.9.27/tcc.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tcc.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tcc.c	(revision 331)
@@ -0,0 +1,371 @@
+/*
+ *  TCC - Tiny C Compiler
+ * 
+ *  Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "tcc.h"
+#if ONE_SOURCE
+# include "libtcc.c"
+#endif
+#include "tcctools.c"
+
+static const char help[] =
+    "Tiny C Compiler "TCC_VERSION" - Copyright (C) 2001-2006 Fabrice Bellard\n"
+    "Usage: tcc [options...] [-o outfile] [-c] infile(s)...\n"
+    "       tcc [options...] -run infile [arguments...]\n"
+    "General options:\n"
+    "  -c          compile only - generate an object file\n"
+    "  -o outfile  set output filename\n"
+    "  -run        run compiled source\n"
+    "  -fflag      set or reset (with 'no-' prefix) 'flag' (see tcc -hh)\n"
+    "  -Wwarning   set or reset (with 'no-' prefix) 'warning' (see tcc -hh)\n"
+    "  -w          disable all warnings\n"
+    "  -v -vv      show version, show search paths or loaded files\n"
+    "  -h -hh      show this, show more help\n"
+    "  -bench      show compilation statistics\n"
+    "  -           use stdin pipe as infile\n"
+    "  @listfile   read arguments from listfile\n"
+    "Preprocessor options:\n"
+    "  -Idir       add include path 'dir'\n"
+    "  -Dsym[=val] define 'sym' with value 'val'\n"
+    "  -Usym       undefine 'sym'\n"
+    "  -E          preprocess only\n"
+    "Linker options:\n"
+    "  -Ldir       add library path 'dir'\n"
+    "  -llib       link with dynamic or static library 'lib'\n"
+    "  -r          generate (relocatable) object file\n"
+    "  -shared     generate a shared library/dll\n"
+    "  -rdynamic   export all global symbols to dynamic linker\n"
+    "  -soname     set name for shared library to be used at runtime\n"
+    "  -Wl,-opt[=val]  set linker option (see tcc -hh)\n"
+    "Debugger options:\n"
+    "  -g          generate runtime debug info\n"
+#ifdef CONFIG_TCC_BCHECK
+    "  -b          compile with built-in memory and bounds checker (implies -g)\n"
+#endif
+#ifdef CONFIG_TCC_BACKTRACE
+    "  -bt N       show N callers in stack traces\n"
+#endif
+    "Misc. options:\n"
+    "  -x[c|a|n]   specify type of the next infile\n"
+    "  -nostdinc   do not use standard system include paths\n"
+    "  -nostdlib   do not link with standard crt and libraries\n"
+    "  -Bdir       set tcc's private include/library dir\n"
+    "  -MD         generate dependency file for make\n"
+    "  -MF file    specify dependency file name\n"
+    "  -m32/64     defer to i386/x86_64 cross compiler\n"
+    "Tools:\n"
+    "  create library  : tcc -ar [rcsv] lib.a files\n"
+#ifdef TCC_TARGET_PE
+    "  create def file : tcc -impdef lib.dll [-v] [-o lib.def]\n"
+#endif
+    ;
+
+static const char help2[] =
+    "Tiny C Compiler "TCC_VERSION" - More Options\n"
+    "Special options:\n"
+    "  -P -P1                        with -E: no/alternative #line output\n"
+    "  -dD -dM                       with -E: output #define directives\n"
+    "  -pthread                      same as -D_REENTRANT and -lpthread\n"
+    "  -On                           same as -D__OPTIMIZE__ for n > 0\n"
+    "  -Wp,-opt                      same as -opt\n"
+    "  -include file                 include 'file' above each input file\n"
+    "  -isystem dir                  add 'dir' to system include path\n"
+    "  -static                       link to static libraries (not recommended)\n"
+    "  -dumpversion                  print version\n"
+    "  -print-search-dirs            print search paths\n"
+    "  -dt                           with -run/-E: auto-define 'test_...' macros\n"
+    "Ignored options:\n"
+    "  --param  -pedantic  -pipe  -s  -std  -traditional\n"
+    "-W... warnings:\n"
+    "  all                           turn on some (*) warnings\n"
+    "  error                         stop after first warning\n"
+    "  unsupported                   warn about ignored options, pragmas, etc.\n"
+    "  write-strings                 strings are const\n"
+    "  implicit-function-declaration warn for missing prototype (*)\n"
+    "-f[no-]... flags:\n"
+    "  unsigned-char                 default char is unsigned\n"
+    "  signed-char                   default char is signed\n"
+    "  common                        use common section instead of bss\n"
+    "  leading-underscore            decorate extern symbols\n"
+    "  ms-extensions                 allow anonymous struct in struct\n"
+    "  dollars-in-identifiers        allow '$' in C symbols\n"
+    "-m... target specific options:\n"
+    "  ms-bitfields                  use MSVC bitfield layout\n"
+#ifdef TCC_TARGET_ARM
+    "  float-abi                     hard/softfp on arm\n"
+#endif
+#ifdef TCC_TARGET_X86_64
+    "  no-sse                        disable floats on x86_64\n"
+#endif
+    "-Wl,... linker options:\n"
+    "  -nostdlib                     do not link with standard crt/libs\n"
+    "  -[no-]whole-archive           load lib(s) fully/only as needed\n"
+    "  -export-all-symbols           same as -rdynamic\n"
+    "  -image-base= -Ttext=          set base address of executable\n"
+    "  -section-alignment=           set section alignment in executable\n"
+#ifdef TCC_TARGET_PE
+    "  -file-alignment=              set PE file alignment\n"
+    "  -stack=                       set PE stack reserve\n"
+    "  -large-address-aware          set related PE option\n"
+    "  -subsystem=[console/windows]  set PE subsystem\n"
+    "  -oformat=[pe-* binary]        set executable output format\n"
+    "Predefined macros:\n"
+    "  tcc -E -dM - < nul\n"
+#else
+    "  -rpath=                       set dynamic library search path\n"
+    "  -enable-new-dtags             set DT_RUNPATH instead of DT_RPATH\n"
+    "  -soname=                      set DT_SONAME elf tag\n"
+    "  -Bsymbolic                    set DT_SYMBOLIC elf tag\n"
+    "  -oformat=[elf32/64-* binary]  set executable output format\n"
+    "  -init= -fini= -as-needed -O   (ignored)\n"
+    "Predefined macros:\n"
+    "  tcc -E -dM - < /dev/null\n"
+#endif
+    "See also the manual for more details.\n"
+    ;
+
+static const char version[] =
+    "tcc version "TCC_VERSION" ("
+#ifdef TCC_TARGET_I386
+        "i386"
+#elif defined TCC_TARGET_X86_64
+        "x86_64"
+#elif defined TCC_TARGET_C67
+        "C67"
+#elif defined TCC_TARGET_ARM
+        "ARM"
+#elif defined TCC_TARGET_ARM64
+        "AArch64"
+#endif
+#ifdef TCC_ARM_HARDFLOAT
+        " Hard Float"
+#endif
+#ifdef TCC_TARGET_PE
+        " Windows"
+#elif defined(TCC_TARGET_MACHO)
+        " Darwin"
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+        " FreeBSD"
+#else
+        " Linux"
+#endif
+    ")\n"
+    ;
+
+static void print_dirs(const char *msg, char **paths, int nb_paths)
+{
+    int i;
+    printf("%s:\n%s", msg, nb_paths ? "" : "  -\n");
+    for(i = 0; i < nb_paths; i++)
+        printf("  %s\n", paths[i]);
+}
+
+static void print_search_dirs(TCCState *s)
+{
+    printf("install: %s\n", s->tcc_lib_path);
+    /* print_dirs("programs", NULL, 0); */
+    print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths);
+    print_dirs("libraries", s->library_paths, s->nb_library_paths);
+    printf("libtcc1:\n  %s/"TCC_LIBTCC1"\n", s->tcc_lib_path);
+#ifndef TCC_TARGET_PE
+    print_dirs("crt", s->crt_paths, s->nb_crt_paths);
+    printf("elfinterp:\n  %s\n",  DEFAULT_ELFINTERP(s));
+#endif
+}
+
+static void set_environment(TCCState *s)
+{
+    char * path;
+
+    path = getenv("C_INCLUDE_PATH");
+    if(path != NULL) {
+        tcc_add_sysinclude_path(s, path);
+    }
+    path = getenv("CPATH");
+    if(path != NULL) {
+        tcc_add_include_path(s, path);
+    }
+    path = getenv("LIBRARY_PATH");
+    if(path != NULL) {
+        tcc_add_library_path(s, path);
+    }
+}
+
+static char *default_outputfile(TCCState *s, const char *first_file)
+{
+    char buf[1024];
+    char *ext;
+    const char *name = "a";
+
+    if (first_file && strcmp(first_file, "-"))
+        name = tcc_basename(first_file);
+    snprintf(buf, sizeof(buf), "%s", name);
+    ext = tcc_fileextension(buf);
+#ifdef TCC_TARGET_PE
+    if (s->output_type == TCC_OUTPUT_DLL)
+        strcpy(ext, ".dll");
+    else
+    if (s->output_type == TCC_OUTPUT_EXE)
+        strcpy(ext, ".exe");
+    else
+#endif
+    if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r && *ext)
+        strcpy(ext, ".o");
+    else
+        strcpy(buf, "a.out");
+    return tcc_strdup(buf);
+}
+
+static unsigned getclock_ms(void)
+{
+#ifdef _WIN32
+    return GetTickCount();
+#else
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec*1000 + (tv.tv_usec+500)/1000;
+#endif
+}
+
+int tcc_main(int argc0, char **argv0)
+{
+    TCCState *s;
+    int ret, opt, n = 0, t = 0;
+    unsigned start_time = 0;
+    const char *first_file;
+    int argc; char **argv;
+    FILE *ppfp = stdout;
+
+redo:
+    argc = argc0, argv = argv0;
+    s = tcc_new();
+    opt = tcc_parse_args(s, &argc, &argv, 1);
+
+    if ((n | t) == 0) {
+        if (opt == OPT_HELP)
+            return printf(help), 1;
+        if (opt == OPT_HELP2)
+            return printf(help2), 1;
+        if (opt == OPT_M32 || opt == OPT_M64)
+            tcc_tool_cross(s, argv, opt); /* never returns */
+        if (s->verbose)
+            printf(version);
+        if (opt == OPT_AR)
+            return tcc_tool_ar(s, argc, argv);
+#ifdef TCC_TARGET_PE
+        if (opt == OPT_IMPDEF)
+            return tcc_tool_impdef(s, argc, argv);
+#endif
+        if (opt == OPT_V)
+            return 0;
+        if (opt == OPT_PRINT_DIRS) {
+            /* initialize search dirs */
+            set_environment(s);
+            tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
+            print_search_dirs(s);
+            return 0;
+        }
+
+        n = s->nb_files;
+        if (n == 0)
+            tcc_error("no input files\n");
+
+        if (s->output_type == TCC_OUTPUT_PREPROCESS) {
+            if (s->outfile) {
+                ppfp = fopen(s->outfile, "w");
+                if (!ppfp)
+                    tcc_error("could not write '%s'", s->outfile);
+            }
+        } else if (s->output_type == TCC_OUTPUT_OBJ && !s->option_r) {
+            if (s->nb_libraries)
+                tcc_error("cannot specify libraries with -c");
+            if (n > 1 && s->outfile)
+                tcc_error("cannot specify output file with -c many files");
+        } else {
+            if (s->option_pthread)
+                tcc_set_options(s, "-lpthread");
+        }
+
+        if (s->do_bench)
+            start_time = getclock_ms();
+    }
+
+    set_environment(s);
+    if (s->output_type == 0)
+        s->output_type = TCC_OUTPUT_EXE;
+    tcc_set_output_type(s, s->output_type);
+    s->ppfp = ppfp;
+
+    if ((s->output_type == TCC_OUTPUT_MEMORY
+      || s->output_type == TCC_OUTPUT_PREPROCESS) && (s->dflag & 16))
+        s->dflag |= t ? 32 : 0, s->run_test = ++t, n = s->nb_files;
+
+    /* compile or add each files or library */
+    for (first_file = NULL, ret = 0;;) {
+        struct filespec *f = s->files[s->nb_files - n];
+        s->filetype = f->type;
+        s->alacarte_link = f->alacarte;
+        if (f->type == AFF_TYPE_LIB) {
+            if (tcc_add_library_err(s, f->name) < 0)
+                ret = 1;
+        } else {
+            if (1 == s->verbose)
+                printf("-> %s\n", f->name);
+            if (!first_file)
+                first_file = f->name;
+            if (tcc_add_file(s, f->name) < 0)
+                ret = 1;
+        }
+        s->filetype = 0;
+        s->alacarte_link = 1;
+        if (--n == 0 || ret
+            || (s->output_type == TCC_OUTPUT_OBJ && !s->option_r))
+            break;
+    }
+
+    if (s->run_test) {
+        t = 0;
+    } else if (s->output_type == TCC_OUTPUT_PREPROCESS) {
+        ;
+    } else if (0 == ret) {
+        if (s->output_type == TCC_OUTPUT_MEMORY) {
+#ifdef TCC_IS_NATIVE
+            ret = tcc_run(s, argc, argv);
+#endif
+        } else {
+            if (!s->outfile)
+                s->outfile = default_outputfile(s, first_file);
+            if (tcc_output_file(s, s->outfile))
+                ret = 1;
+            else if (s->gen_deps)
+                gen_makedeps(s, s->outfile, s->deps_outfile);
+        }
+    }
+
+    if (s->do_bench && (n | t | ret) == 0)
+        tcc_print_stats(s, getclock_ms() - start_time);
+    tcc_delete(s);
+    if (ret == 0 && n)
+        goto redo; /* compile more files with -c */
+    if (t)
+        goto redo; /* run more tests with -dt -run */
+    if (ppfp && ppfp != stdout)
+        fclose(ppfp);
+    return ret;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tcc.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tcc.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tcc.h	(revision 331)
@@ -0,0 +1,1660 @@
+/*
+ *  TCC - Tiny C Compiler
+ *
+ *  Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _TCC_H
+#define _TCC_H
+
+#define _GNU_SOURCE
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <math.h>
+#include <fcntl.h>
+#include <setjmp.h>
+#include <time.h>
+
+#ifndef _WIN32
+# include <unistd.h>
+# include <sys/time.h>
+# ifndef CONFIG_TCC_STATIC
+#  include <dlfcn.h>
+# endif
+/* XXX: need to define this to use them in non ISOC99 context */
+extern float strtof (const char *__nptr, char **__endptr);
+extern long double strtold (const char *__nptr, char **__endptr);
+#endif
+
+#ifdef _WIN32
+# include <windows.h>
+# include <io.h> /* open, close etc. */
+# include <direct.h> /* getcwd */
+# ifdef __GNUC__
+#  include <stdint.h>
+# endif
+# define inline __inline
+# define snprintf _snprintf
+# define vsnprintf _vsnprintf
+# ifndef __GNUC__
+#  define strtold (long double)strtod
+#  define strtof (float)strtod
+#  define strtoll _strtoi64
+#  define strtoull _strtoui64
+# endif
+# ifdef LIBTCC_AS_DLL
+#  define LIBTCCAPI __declspec(dllexport)
+#  define PUB_FUNC LIBTCCAPI
+# endif
+# define inp next_inp /* inp is an intrinsic on msvc/mingw */
+# ifdef _MSC_VER
+#  pragma warning (disable : 4244)  // conversion from 'uint64_t' to 'int', possible loss of data
+#  pragma warning (disable : 4267)  // conversion from 'size_t' to 'int', possible loss of data
+#  pragma warning (disable : 4996)  // The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name
+#  pragma warning (disable : 4018)  // signed/unsigned mismatch
+#  pragma warning (disable : 4146)  // unary minus operator applied to unsigned type, result still unsigned
+#  define ssize_t intptr_t
+# endif
+# undef CONFIG_TCC_STATIC
+#endif
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+
+#ifndef offsetof
+#define offsetof(type, field) ((size_t) &((type *)0)->field)
+#endif
+
+#ifndef countof
+#define countof(tab) (sizeof(tab) / sizeof((tab)[0]))
+#endif
+
+#ifdef _MSC_VER
+# define NORETURN __declspec(noreturn)
+# define ALIGNED(x) __declspec(align(x))
+#else
+# define NORETURN __attribute__((noreturn))
+# define ALIGNED(x) __attribute__((aligned(x)))
+#endif
+
+#ifdef _WIN32
+# define IS_DIRSEP(c) (c == '/' || c == '\\')
+# define IS_ABSPATH(p) (IS_DIRSEP(p[0]) || (p[0] && p[1] == ':' && IS_DIRSEP(p[2])))
+# define PATHCMP stricmp
+# define PATHSEP ";"
+#else
+# define IS_DIRSEP(c) (c == '/')
+# define IS_ABSPATH(p) IS_DIRSEP(p[0])
+# define PATHCMP strcmp
+# define PATHSEP ":"
+#endif
+
+/* -------------------------------------------- */
+
+/* parser debug */
+/* #define PARSE_DEBUG */
+/* preprocessor debug */
+/* #define PP_DEBUG */
+/* include file debug */
+/* #define INC_DEBUG */
+/* memory leak debug */
+/* #define MEM_DEBUG */
+/* assembler debug */
+/* #define ASM_DEBUG */
+
+/* target selection */
+/* #define TCC_TARGET_I386   *//* i386 code generator */
+/* #define TCC_TARGET_X86_64 *//* x86-64 code generator */
+/* #define TCC_TARGET_ARM    *//* ARMv4 code generator */
+/* #define TCC_TARGET_ARM64  *//* ARMv8 code generator */
+/* #define TCC_TARGET_C67    *//* TMS320C67xx code generator */
+
+/* default target is I386 */
+#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_ARM) && \
+    !defined(TCC_TARGET_ARM64) && !defined(TCC_TARGET_C67) && \
+    !defined(TCC_TARGET_X86_64)
+# if defined __x86_64__ || defined _AMD64_
+#  define TCC_TARGET_X86_64
+# elif defined __arm__
+#  define TCC_TARGET_ARM
+#  define TCC_ARM_EABI
+#  define TCC_ARM_HARDFLOAT
+# elif defined __aarch64__
+#  define TCC_TARGET_ARM64
+# else
+#  define TCC_TARGET_I386
+# endif
+# ifdef _WIN32
+#  define TCC_TARGET_PE 1
+# endif
+#endif
+
+/* only native compiler supports -run */
+#if defined _WIN32 == defined TCC_TARGET_PE
+# if (defined __i386__ || defined _X86_) && defined TCC_TARGET_I386
+#  define TCC_IS_NATIVE
+# elif (defined __x86_64__ || defined _AMD64_) && defined TCC_TARGET_X86_64
+#  define TCC_IS_NATIVE
+# elif defined __arm__ && defined TCC_TARGET_ARM
+#  define TCC_IS_NATIVE
+# elif defined __aarch64__ && defined TCC_TARGET_ARM64
+#  define TCC_IS_NATIVE
+# endif
+#endif
+
+#if defined TCC_IS_NATIVE && !defined CONFIG_TCCBOOT
+# define CONFIG_TCC_BACKTRACE
+# if (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64) \
+  && !defined TCC_UCLIBC && !defined TCC_MUSL
+# define CONFIG_TCC_BCHECK /* enable bound checking code */
+# endif
+#endif
+
+/* ------------ path configuration ------------ */
+
+#ifndef CONFIG_SYSROOT
+# define CONFIG_SYSROOT ""
+#endif
+#ifndef CONFIG_TCCDIR
+# define CONFIG_TCCDIR "/usr/local/lib/tcc"
+#endif
+#ifndef CONFIG_LDDIR
+# define CONFIG_LDDIR "lib"
+#endif
+#ifdef CONFIG_TRIPLET
+# define USE_TRIPLET(s) s "/" CONFIG_TRIPLET
+# define ALSO_TRIPLET(s) USE_TRIPLET(s) ":" s
+#else
+# define USE_TRIPLET(s) s
+# define ALSO_TRIPLET(s) s
+#endif
+
+/* path to find crt1.o, crti.o and crtn.o */
+#ifndef CONFIG_TCC_CRTPREFIX
+# define CONFIG_TCC_CRTPREFIX USE_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR)
+#endif
+
+/* Below: {B} is substituted by CONFIG_TCCDIR (rsp. -B option) */
+
+/* system include paths */
+#ifndef CONFIG_TCC_SYSINCLUDEPATHS
+# ifdef TCC_TARGET_PE
+#  define CONFIG_TCC_SYSINCLUDEPATHS "{B}/include"PATHSEP"{B}/include/winapi"
+# else
+#  define CONFIG_TCC_SYSINCLUDEPATHS \
+        "{B}/include" \
+    ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/include") \
+    ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/include")
+# endif
+#endif
+
+/* library search paths */
+#ifndef CONFIG_TCC_LIBPATHS
+# ifdef TCC_TARGET_PE
+#  define CONFIG_TCC_LIBPATHS "{B}/lib"
+# else
+#  define CONFIG_TCC_LIBPATHS \
+        ALSO_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR) \
+    ":" ALSO_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) \
+    ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/" CONFIG_LDDIR)
+# endif
+#endif
+
+/* name of ELF interpreter */
+#ifndef CONFIG_TCC_ELFINTERP
+# if defined __FreeBSD__
+#  define CONFIG_TCC_ELFINTERP "/libexec/ld-elf.so.1"
+# elif defined __FreeBSD_kernel__
+#  if defined(TCC_TARGET_X86_64)
+#   define CONFIG_TCC_ELFINTERP "/lib/ld-kfreebsd-x86-64.so.1"
+#  else
+#   define CONFIG_TCC_ELFINTERP "/lib/ld.so.1"
+#  endif
+# elif defined __DragonFly__
+#  define CONFIG_TCC_ELFINTERP "/usr/libexec/ld-elf.so.2"
+# elif defined __NetBSD__
+#  define CONFIG_TCC_ELFINTERP "/usr/libexec/ld.elf_so"
+# elif defined __GNU__
+#  define CONFIG_TCC_ELFINTERP "/lib/ld.so"
+# elif defined(TCC_TARGET_PE)
+#  define CONFIG_TCC_ELFINTERP "-"
+# elif defined(TCC_UCLIBC)
+#  define CONFIG_TCC_ELFINTERP "/lib/ld-uClibc.so.0" /* is there a uClibc for x86_64 ? */
+# elif defined TCC_TARGET_ARM64
+#  if defined(TCC_MUSL)
+#   define CONFIG_TCC_ELFINTERP "/lib/ld-musl-aarch64.so.1"
+#  else
+#   define CONFIG_TCC_ELFINTERP "/lib/ld-linux-aarch64.so.1"
+#  endif
+# elif defined(TCC_TARGET_X86_64)
+#  if defined(TCC_MUSL)
+#   define CONFIG_TCC_ELFINTERP "/lib/ld-musl-x86_64.so.1"
+#  else
+#   define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2"
+#  endif
+# elif !defined(TCC_ARM_EABI)
+#  if defined(TCC_MUSL)
+#   define CONFIG_TCC_ELFINTERP "/lib/ld-musl-arm.so.1"
+#  else
+#   define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.2"
+#  endif
+# endif
+#endif
+
+/* var elf_interp dans *-gen.c */
+#ifdef CONFIG_TCC_ELFINTERP
+# define DEFAULT_ELFINTERP(s) CONFIG_TCC_ELFINTERP
+#else
+# define DEFAULT_ELFINTERP(s) default_elfinterp(s)
+#endif
+
+/* (target specific) libtcc1.a */
+#ifndef TCC_LIBTCC1
+# define TCC_LIBTCC1 "libtcc1.a"
+#endif
+
+/* library to use with CONFIG_USE_LIBGCC instead of libtcc1.a */
+#if defined CONFIG_USE_LIBGCC && !defined TCC_LIBGCC
+#define TCC_LIBGCC USE_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1"
+#endif
+
+/* -------------------------------------------- */
+
+#include "libtcc.h"
+#include "elf.h"
+#include "stab.h"
+
+/* -------------------------------------------- */
+
+#ifndef PUB_FUNC /* functions used by tcc.c but not in libtcc.h */
+# define PUB_FUNC
+#endif
+
+#ifndef ONE_SOURCE
+# define ONE_SOURCE 1
+#endif
+
+#if ONE_SOURCE
+#define ST_INLN static inline
+#define ST_FUNC static
+#define ST_DATA static
+#else
+#define ST_INLN
+#define ST_FUNC
+#define ST_DATA extern
+#endif
+
+#ifdef TCC_PROFILE /* profile all functions */
+# define static
+#endif
+
+/* -------------------------------------------- */
+/* include the target specific definitions */
+
+#define TARGET_DEFS_ONLY
+#ifdef TCC_TARGET_I386
+# include "i386-gen.c"
+# include "i386-link.c"
+#endif
+#ifdef TCC_TARGET_X86_64
+# include "x86_64-gen.c"
+# include "x86_64-link.c"
+#endif
+#ifdef TCC_TARGET_ARM
+# include "arm-gen.c"
+# include "arm-link.c"
+# include "arm-asm.c"
+#endif
+#ifdef TCC_TARGET_ARM64
+# include "arm64-gen.c"
+# include "arm64-link.c"
+#endif
+#ifdef TCC_TARGET_C67
+# define TCC_TARGET_COFF
+# include "coff.h"
+# include "c67-gen.c"
+# include "c67-link.c"
+#endif
+#undef TARGET_DEFS_ONLY
+
+/* -------------------------------------------- */
+
+#if PTR_SIZE == 8
+# define ELFCLASSW ELFCLASS64
+# define ElfW(type) Elf##64##_##type
+# define ELFW(type) ELF##64##_##type
+# define ElfW_Rel ElfW(Rela)
+# define SHT_RELX SHT_RELA
+# define REL_SECTION_FMT ".rela%s"
+#else
+# define ELFCLASSW ELFCLASS32
+# define ElfW(type) Elf##32##_##type
+# define ELFW(type) ELF##32##_##type
+# define ElfW_Rel ElfW(Rel)
+# define SHT_RELX SHT_REL
+# define REL_SECTION_FMT ".rel%s"
+#endif
+/* target address type */
+#define addr_t ElfW(Addr)
+#define ElfSym ElfW(Sym)
+
+#if PTR_SIZE == 8 && !defined TCC_TARGET_PE
+# define LONG_SIZE 8
+#else
+# define LONG_SIZE 4
+#endif
+
+/* -------------------------------------------- */
+
+#define INCLUDE_STACK_SIZE  32
+#define IFDEF_STACK_SIZE    64
+#define VSTACK_SIZE         256
+#define STRING_MAX_SIZE     1024
+#define TOKSTR_MAX_SIZE     256
+#define PACK_STACK_SIZE     8
+
+#define TOK_HASH_SIZE       16384 /* must be a power of two */
+#define TOK_ALLOC_INCR      512  /* must be a power of two */
+#define TOK_MAX_SIZE        4 /* token max size in int unit when stored in string */
+
+/* token symbol management */
+typedef struct TokenSym {
+    struct TokenSym *hash_next;
+    struct Sym *sym_define; /* direct pointer to define */
+    struct Sym *sym_label; /* direct pointer to label */
+    struct Sym *sym_struct; /* direct pointer to structure */
+    struct Sym *sym_identifier; /* direct pointer to identifier */
+    int tok; /* token number */
+    int len;
+    char str[1];
+} TokenSym;
+
+#ifdef TCC_TARGET_PE
+typedef unsigned short nwchar_t;
+#else
+typedef int nwchar_t;
+#endif
+
+typedef struct CString {
+    int size; /* size in bytes */
+    void *data; /* either 'char *' or 'nwchar_t *' */
+    int size_allocated;
+} CString;
+
+/* type definition */
+typedef struct CType {
+    int t;
+    struct Sym *ref;
+} CType;
+
+/* constant value */
+typedef union CValue {
+    long double ld;
+    double d;
+    float f;
+    uint64_t i;
+    struct {
+        int size;
+        const void *data;
+    } str;
+    int tab[LDOUBLE_SIZE/4];
+} CValue;
+
+/* value on stack */
+typedef struct SValue {
+    CType type;      /* type */
+    unsigned short r;      /* register + flags */
+    unsigned short r2;     /* second register, used for 'long long'
+                              type. If not used, set to VT_CONST */
+    CValue c;              /* constant, if VT_CONST */
+    struct Sym *sym;       /* symbol, if (VT_SYM | VT_CONST), or if
+    			      result of unary() for an identifier. */
+} SValue;
+
+/* symbol attributes */
+struct SymAttr {
+    unsigned short
+    aligned     : 5, /* alignment as log2+1 (0 == unspecified) */
+    packed      : 1,
+    weak        : 1,
+    visibility  : 2,
+    dllexport   : 1,
+    dllimport   : 1,
+    unused      : 5;
+};
+
+/* function attributes or temporary attributes for parsing */
+struct FuncAttr {
+    unsigned
+    func_call   : 3, /* calling convention (0..5), see below */
+    func_type   : 2, /* FUNC_OLD/NEW/ELLIPSIS */
+    func_args   : 8; /* PE __stdcall args */
+};
+
+/* GNUC attribute definition */
+typedef struct AttributeDef {
+    struct SymAttr a;
+    struct FuncAttr f;
+    struct Section *section;
+    int alias_target; /* token */
+    int asm_label; /* associated asm label */
+    char attr_mode; /* __attribute__((__mode__(...))) */
+} AttributeDef;
+
+/* symbol management */
+typedef struct Sym {
+    int v; /* symbol token */
+    unsigned short r; /* associated register or VT_CONST/VT_LOCAL and LVAL type */
+    struct SymAttr a; /* symbol attributes */
+    union {
+        struct {
+            int c; /* associated number or Elf symbol index */
+            union {
+                int sym_scope; /* scope level for locals */
+                int jnext; /* next jump label */
+                struct FuncAttr f; /* function attributes */
+                int auxtype; /* bitfield access type */
+            };
+        };
+        long long enum_val; /* enum constant if IS_ENUM_VAL */
+        int *d; /* define token stream */
+    };
+    CType type; /* associated type */
+    union {
+        struct Sym *next; /* next related symbol (for fields and anoms) */
+        int asm_label; /* associated asm label */
+    };
+    struct Sym *prev; /* prev symbol in stack */
+    struct Sym *prev_tok; /* previous symbol for this token */
+} Sym;
+
+/* section definition */
+typedef struct Section {
+    unsigned long data_offset; /* current data offset */
+    unsigned char *data;       /* section data */
+    unsigned long data_allocated; /* used for realloc() handling */
+    int sh_name;             /* elf section name (only used during output) */
+    int sh_num;              /* elf section number */
+    int sh_type;             /* elf section type */
+    int sh_flags;            /* elf section flags */
+    int sh_info;             /* elf section info */
+    int sh_addralign;        /* elf section alignment */
+    int sh_entsize;          /* elf entry size */
+    unsigned long sh_size;   /* section size (only used during output) */
+    addr_t sh_addr;          /* address at which the section is relocated */
+    unsigned long sh_offset; /* file offset */
+    int nb_hashed_syms;      /* used to resize the hash table */
+    struct Section *link;    /* link to another section */
+    struct Section *reloc;   /* corresponding section for relocation, if any */
+    struct Section *hash;    /* hash table for symbols */
+    struct Section *prev;    /* previous section on section stack */
+    char name[1];           /* section name */
+} Section;
+
+typedef struct DLLReference {
+    int level;
+    void *handle;
+    char name[1];
+} DLLReference;
+
+/* -------------------------------------------------- */
+
+#define SYM_STRUCT     0x40000000 /* struct/union/enum symbol space */
+#define SYM_FIELD      0x20000000 /* struct/union field symbol space */
+#define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */
+
+/* stored in 'Sym->f.func_type' field */
+#define FUNC_NEW       1 /* ansi function prototype */
+#define FUNC_OLD       2 /* old function prototype */
+#define FUNC_ELLIPSIS  3 /* ansi function prototype with ... */
+
+/* stored in 'Sym->f.func_call' field */
+#define FUNC_CDECL     0 /* standard c call */
+#define FUNC_STDCALL   1 /* pascal c call */
+#define FUNC_FASTCALL1 2 /* first param in %eax */
+#define FUNC_FASTCALL2 3 /* first parameters in %eax, %edx */
+#define FUNC_FASTCALL3 4 /* first parameter in %eax, %edx, %ecx */
+#define FUNC_FASTCALLW 5 /* first parameter in %ecx, %edx */
+
+/* field 'Sym.t' for macros */
+#define MACRO_OBJ      0 /* object like macro */
+#define MACRO_FUNC     1 /* function like macro */
+
+/* field 'Sym.r' for C labels */
+#define LABEL_DEFINED  0 /* label is defined */
+#define LABEL_FORWARD  1 /* label is forward defined */
+#define LABEL_DECLARED 2 /* label is declared but never used */
+
+/* type_decl() types */
+#define TYPE_ABSTRACT  1 /* type without variable */
+#define TYPE_DIRECT    2 /* type with variable */
+
+#define IO_BUF_SIZE 8192
+
+typedef struct BufferedFile {
+    uint8_t *buf_ptr;
+    uint8_t *buf_end;
+    int fd;
+    struct BufferedFile *prev;
+    int line_num;    /* current line number - here to simplify code */
+    int line_ref;    /* tcc -E: last printed line */
+    int ifndef_macro;  /* #ifndef macro / #endif search */
+    int ifndef_macro_saved; /* saved ifndef_macro */
+    int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
+    int include_next_index; /* next search path */
+    char filename[1024];    /* filename */
+    char *true_filename; /* filename not modified by # line directive */
+    unsigned char unget[4];
+    unsigned char buffer[1]; /* extra size for CH_EOB char */
+} BufferedFile;
+
+#define CH_EOB   '\\'       /* end of buffer or '\0' char in file */
+#define CH_EOF   (-1)   /* end of file */
+
+/* used to record tokens */
+typedef struct TokenString {
+    int *str;
+    int len;
+    int lastlen;
+    int allocated_len;
+    int last_line_num;
+    int save_line_num;
+    /* used to chain token-strings with begin/end_macro() */
+    struct TokenString *prev;
+    const int *prev_ptr;
+    char alloc;
+} TokenString;
+
+/* inline functions */
+typedef struct InlineFunc {
+    TokenString *func_str;
+    Sym *sym;
+    char filename[1];
+} InlineFunc;
+
+/* include file cache, used to find files faster and also to eliminate
+   inclusion if the include file is protected by #ifndef ... #endif */
+typedef struct CachedInclude {
+    int ifndef_macro;
+    int once;
+    int hash_next; /* -1 if none */
+    char filename[1]; /* path specified in #include */
+} CachedInclude;
+
+#define CACHED_INCLUDES_HASH_SIZE 32
+
+#ifdef CONFIG_TCC_ASM
+typedef struct ExprValue {
+    uint64_t v;
+    Sym *sym;
+    int pcrel;
+} ExprValue;
+
+#define MAX_ASM_OPERANDS 30
+typedef struct ASMOperand {
+    int id; /* GCC 3 optional identifier (0 if number only supported */
+    char *constraint;
+    char asm_str[16]; /* computed asm string for operand */
+    SValue *vt; /* C value of the expression */
+    int ref_index; /* if >= 0, gives reference to a output constraint */
+    int input_index; /* if >= 0, gives reference to an input constraint */
+    int priority; /* priority, used to assign registers */
+    int reg; /* if >= 0, register number used for this operand */
+    int is_llong; /* true if double register value */
+    int is_memory; /* true if memory operand */
+    int is_rw;     /* for '+' modifier */
+} ASMOperand;
+#endif
+
+/* extra symbol attributes (not in symbol table) */
+struct sym_attr {
+    unsigned got_offset;
+    unsigned plt_offset;
+    int plt_sym;
+    int dyn_index;
+#ifdef TCC_TARGET_ARM
+    unsigned char plt_thumb_stub:1;
+#endif
+};
+
+struct TCCState {
+
+    int verbose; /* if true, display some information during compilation */
+    int nostdinc; /* if true, no standard headers are added */
+    int nostdlib; /* if true, no standard libraries are added */
+    int nocommon; /* if true, do not use common symbols for .bss data */
+    int static_link; /* if true, static linking is performed */
+    int rdynamic; /* if true, all symbols are exported */
+    int symbolic; /* if true, resolve symbols in the current module first */
+    int alacarte_link; /* if true, only link in referenced objects from archive */
+
+    char *tcc_lib_path; /* CONFIG_TCCDIR or -B option */
+    char *soname; /* as specified on the command line (-soname) */
+    char *rpath; /* as specified on the command line (-Wl,-rpath=) */
+    int enable_new_dtags; /* ditto, (-Wl,--enable-new-dtags) */
+
+    /* output type, see TCC_OUTPUT_XXX */
+    int output_type;
+    /* output format, see TCC_OUTPUT_FORMAT_xxx */
+    int output_format;
+
+    /* C language options */
+    int char_is_unsigned;
+    int leading_underscore;
+    int ms_extensions;	/* allow nested named struct w/o identifier behave like unnamed */
+    int dollars_in_identifiers;	/* allows '$' char in identifiers */
+    int ms_bitfields; /* if true, emulate MS algorithm for aligning bitfields */
+
+    /* warning switches */
+    int warn_write_strings;
+    int warn_unsupported;
+    int warn_error;
+    int warn_none;
+    int warn_implicit_function_declaration;
+    int warn_gcc_compat;
+
+    /* compile with debug symbol (and use them if error during execution) */
+    int do_debug;
+#ifdef CONFIG_TCC_BCHECK
+    /* compile with built-in memory and bounds checker */
+    int do_bounds_check;
+#endif
+#ifdef TCC_TARGET_ARM
+    enum float_abi float_abi; /* float ABI of the generated code*/
+#endif
+    int run_test; /* nth test to run with -dt -run */
+
+    addr_t text_addr; /* address of text section */
+    int has_text_addr;
+
+    unsigned section_align; /* section alignment */
+
+    char *init_symbol; /* symbols to call at load-time (not used currently) */
+    char *fini_symbol; /* symbols to call at unload-time (not used currently) */
+
+#ifdef TCC_TARGET_I386
+    int seg_size; /* 32. Can be 16 with i386 assembler (.code16) */
+#endif
+#ifdef TCC_TARGET_X86_64
+    int nosse; /* For -mno-sse support. */
+#endif
+
+    /* array of all loaded dlls (including those referenced by loaded dlls) */
+    DLLReference **loaded_dlls;
+    int nb_loaded_dlls;
+
+    /* include paths */
+    char **include_paths;
+    int nb_include_paths;
+
+    char **sysinclude_paths;
+    int nb_sysinclude_paths;
+
+    /* library paths */
+    char **library_paths;
+    int nb_library_paths;
+
+    /* crt?.o object path */
+    char **crt_paths;
+    int nb_crt_paths;
+
+    /* -include files */
+    char **cmd_include_files;
+    int nb_cmd_include_files;
+
+    /* error handling */
+    void *error_opaque;
+    void (*error_func)(void *opaque, const char *msg);
+    int error_set_jmp_enabled;
+    jmp_buf error_jmp_buf;
+    int nb_errors;
+
+    /* output file for preprocessing (-E) */
+    FILE *ppfp;
+    enum {
+	LINE_MACRO_OUTPUT_FORMAT_GCC,
+	LINE_MACRO_OUTPUT_FORMAT_NONE,
+	LINE_MACRO_OUTPUT_FORMAT_STD,
+    LINE_MACRO_OUTPUT_FORMAT_P10 = 11
+    } Pflag; /* -P switch */
+    char dflag; /* -dX value */
+
+    /* for -MD/-MF: collected dependencies for this compilation */
+    char **target_deps;
+    int nb_target_deps;
+
+    /* compilation */
+    BufferedFile *include_stack[INCLUDE_STACK_SIZE];
+    BufferedFile **include_stack_ptr;
+
+    int ifdef_stack[IFDEF_STACK_SIZE];
+    int *ifdef_stack_ptr;
+
+    /* included files enclosed with #ifndef MACRO */
+    int cached_includes_hash[CACHED_INCLUDES_HASH_SIZE];
+    CachedInclude **cached_includes;
+    int nb_cached_includes;
+
+    /* #pragma pack stack */
+    int pack_stack[PACK_STACK_SIZE];
+    int *pack_stack_ptr;
+    char **pragma_libs;
+    int nb_pragma_libs;
+
+    /* inline functions are stored as token lists and compiled last
+       only if referenced */
+    struct InlineFunc **inline_fns;
+    int nb_inline_fns;
+
+    /* sections */
+    Section **sections;
+    int nb_sections; /* number of sections, including first dummy section */
+
+    Section **priv_sections;
+    int nb_priv_sections; /* number of private sections */
+
+    /* got & plt handling */
+    Section *got;
+    Section *plt;
+
+    /* temporary dynamic symbol sections (for dll loading) */
+    Section *dynsymtab_section;
+    /* exported dynamic symbol section */
+    Section *dynsym;
+    /* copy of the global symtab_section variable */
+    Section *symtab;
+    /* extra attributes (eg. GOT/PLT value) for symtab symbols */
+    struct sym_attr *sym_attrs;
+    int nb_sym_attrs;
+
+#ifdef TCC_TARGET_PE
+    /* PE info */
+    int pe_subsystem;
+    unsigned pe_characteristics;
+    unsigned pe_file_align;
+    unsigned pe_stack_size;
+    addr_t pe_imagebase;
+# ifdef TCC_TARGET_X86_64
+    Section *uw_pdata;
+    int uw_sym;
+    unsigned uw_offs;
+# endif
+#endif
+
+#ifdef TCC_IS_NATIVE
+    const char *runtime_main;
+    void **runtime_mem;
+    int nb_runtime_mem;
+#endif
+
+    /* used by main and tcc_parse_args only */
+    struct filespec **files; /* files seen on command line */
+    int nb_files; /* number thereof */
+    int nb_libraries; /* number of libs thereof */
+    int filetype;
+    char *outfile; /* output filename */
+    int option_r; /* option -r */
+    int do_bench; /* option -bench */
+    int gen_deps; /* option -MD  */
+    char *deps_outfile; /* option -MF */
+    int option_pthread; /* -pthread option */
+    int argc;
+    char **argv;
+};
+
+struct filespec {
+    char type;
+    char alacarte;
+    char name[1];
+};
+
+/* The current value can be: */
+#define VT_VALMASK   0x003f  /* mask for value location, register or: */
+#define VT_CONST     0x0030  /* constant in vc (must be first non register value) */
+#define VT_LLOCAL    0x0031  /* lvalue, offset on stack */
+#define VT_LOCAL     0x0032  /* offset on stack */
+#define VT_CMP       0x0033  /* the value is stored in processor flags (in vc) */
+#define VT_JMP       0x0034  /* value is the consequence of jmp true (even) */
+#define VT_JMPI      0x0035  /* value is the consequence of jmp false (odd) */
+#define VT_LVAL      0x0100  /* var is an lvalue */
+#define VT_SYM       0x0200  /* a symbol value is added */
+#define VT_MUSTCAST  0x0400  /* value must be casted to be correct (used for
+                                char/short stored in integer registers) */
+#define VT_MUSTBOUND 0x0800  /* bound checking must be done before
+                                dereferencing value */
+#define VT_BOUNDED   0x8000  /* value is bounded. The address of the
+                                bounding function call point is in vc */
+#define VT_LVAL_BYTE     0x1000  /* lvalue is a byte */
+#define VT_LVAL_SHORT    0x2000  /* lvalue is a short */
+#define VT_LVAL_UNSIGNED 0x4000  /* lvalue is unsigned */
+#define VT_LVAL_TYPE     (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
+
+/* types */
+#define VT_BTYPE       0x000f  /* mask for basic type */
+#define VT_VOID             0  /* void type */
+#define VT_BYTE             1  /* signed byte type */
+#define VT_SHORT            2  /* short type */
+#define VT_INT              3  /* integer type */
+#define VT_LLONG            4  /* 64 bit integer */
+#define VT_PTR              5  /* pointer */
+#define VT_FUNC             6  /* function type */
+#define VT_STRUCT           7  /* struct/union definition */
+#define VT_FLOAT            8  /* IEEE float */
+#define VT_DOUBLE           9  /* IEEE double */
+#define VT_LDOUBLE         10  /* IEEE long double */
+#define VT_BOOL            11  /* ISOC99 boolean type */
+#define VT_QLONG           13  /* 128-bit integer. Only used for x86-64 ABI */
+#define VT_QFLOAT          14  /* 128-bit float. Only used for x86-64 ABI */
+
+#define VT_UNSIGNED    0x0010  /* unsigned type */
+#define VT_DEFSIGN     0x0020  /* explicitly signed or unsigned */
+#define VT_ARRAY       0x0040  /* array type (also has VT_PTR) */
+#define VT_BITFIELD    0x0080  /* bitfield modifier */
+#define VT_CONSTANT    0x0100  /* const modifier */
+#define VT_VOLATILE    0x0200  /* volatile modifier */
+#define VT_VLA         0x0400  /* VLA type (also has VT_PTR and VT_ARRAY) */
+#define VT_LONG        0x0800  /* long type (also has VT_INT rsp. VT_LLONG) */
+
+/* storage */
+#define VT_EXTERN  0x00001000  /* extern definition */
+#define VT_STATIC  0x00002000  /* static variable */
+#define VT_TYPEDEF 0x00004000  /* typedef definition */
+#define VT_INLINE  0x00008000  /* inline definition */
+/* currently unused: 0x000[1248]0000  */
+
+#define VT_STRUCT_SHIFT 20     /* shift for bitfield shift values (32 - 2*6) */
+#define VT_STRUCT_MASK (((1 << (6+6)) - 1) << VT_STRUCT_SHIFT | VT_BITFIELD)
+#define BIT_POS(t) (((t) >> VT_STRUCT_SHIFT) & 0x3f)
+#define BIT_SIZE(t) (((t) >> (VT_STRUCT_SHIFT + 6)) & 0x3f)
+
+#define VT_UNION    (1 << VT_STRUCT_SHIFT | VT_STRUCT)
+#define VT_ENUM     (2 << VT_STRUCT_SHIFT) /* integral type is an enum really */
+#define VT_ENUM_VAL (3 << VT_STRUCT_SHIFT) /* integral type is an enum constant really */
+
+#define IS_ENUM(t) ((t & VT_STRUCT_MASK) == VT_ENUM)
+#define IS_ENUM_VAL(t) ((t & VT_STRUCT_MASK) == VT_ENUM_VAL)
+#define IS_UNION(t) ((t & (VT_STRUCT_MASK|VT_BTYPE)) == VT_UNION)
+
+/* type mask (except storage) */
+#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
+#define VT_TYPE (~(VT_STORAGE|VT_STRUCT_MASK))
+
+/* symbol was created by tccasm.c first */
+#define VT_ASM (VT_VOID | VT_UNSIGNED)
+#define IS_ASM_SYM(sym) (((sym)->type.t & (VT_BTYPE | VT_ASM)) == VT_ASM)
+
+/* token values */
+
+/* warning: the following compare tokens depend on i386 asm code */
+#define TOK_ULT 0x92
+#define TOK_UGE 0x93
+#define TOK_EQ  0x94
+#define TOK_NE  0x95
+#define TOK_ULE 0x96
+#define TOK_UGT 0x97
+#define TOK_Nset 0x98
+#define TOK_Nclear 0x99
+#define TOK_LT  0x9c
+#define TOK_GE  0x9d
+#define TOK_LE  0x9e
+#define TOK_GT  0x9f
+
+#define TOK_LAND  0xa0
+#define TOK_LOR   0xa1
+#define TOK_DEC   0xa2
+#define TOK_MID   0xa3 /* inc/dec, to void constant */
+#define TOK_INC   0xa4
+#define TOK_UDIV  0xb0 /* unsigned division */
+#define TOK_UMOD  0xb1 /* unsigned modulo */
+#define TOK_PDIV  0xb2 /* fast division with undefined rounding for pointers */
+
+/* tokens that carry values (in additional token string space / tokc) --> */
+#define TOK_CCHAR   0xb3 /* char constant in tokc */
+#define TOK_LCHAR   0xb4
+#define TOK_CINT    0xb5 /* number in tokc */
+#define TOK_CUINT   0xb6 /* unsigned int constant */
+#define TOK_CLLONG  0xb7 /* long long constant */
+#define TOK_CULLONG 0xb8 /* unsigned long long constant */
+#define TOK_STR     0xb9 /* pointer to string in tokc */
+#define TOK_LSTR    0xba
+#define TOK_CFLOAT  0xbb /* float constant */
+#define TOK_CDOUBLE 0xbc /* double constant */
+#define TOK_CLDOUBLE 0xbd /* long double constant */
+#define TOK_PPNUM   0xbe /* preprocessor number */
+#define TOK_PPSTR   0xbf /* preprocessor string */
+#define TOK_LINENUM 0xc0 /* line number info */
+#define TOK_TWODOTS 0xa8 /* C++ token ? */
+/* <-- */
+
+#define TOK_UMULL    0xc2 /* unsigned 32x32 -> 64 mul */
+#define TOK_ADDC1    0xc3 /* add with carry generation */
+#define TOK_ADDC2    0xc4 /* add with carry use */
+#define TOK_SUBC1    0xc5 /* add with carry generation */
+#define TOK_SUBC2    0xc6 /* add with carry use */
+#define TOK_ARROW    0xc7
+#define TOK_DOTS     0xc8 /* three dots */
+#define TOK_SHR      0xc9 /* unsigned shift right */
+#define TOK_TWOSHARPS 0xca /* ## preprocessing token */
+#define TOK_PLCHLDR  0xcb /* placeholder token as defined in C99 */
+#define TOK_NOSUBST  0xcc /* means following token has already been pp'd */
+#define TOK_PPJOIN   0xcd /* A '##' in the right position to mean pasting */
+#define TOK_CLONG    0xce /* long constant */
+#define TOK_CULONG   0xcf /* unsigned long constant */
+
+#define TOK_SHL   0x01 /* shift left */
+#define TOK_SAR   0x02 /* signed shift right */
+
+/* assignment operators : normal operator or 0x80 */
+#define TOK_A_MOD 0xa5
+#define TOK_A_AND 0xa6
+#define TOK_A_MUL 0xaa
+#define TOK_A_ADD 0xab
+#define TOK_A_SUB 0xad
+#define TOK_A_DIV 0xaf
+#define TOK_A_XOR 0xde
+#define TOK_A_OR  0xfc
+#define TOK_A_SHL 0x81
+#define TOK_A_SAR 0x82
+
+#define TOK_EOF       (-1)  /* end of file */
+#define TOK_LINEFEED  10    /* line feed */
+
+/* all identifiers and strings have token above that */
+#define TOK_IDENT 256
+
+#define DEF_ASM(x) DEF(TOK_ASM_ ## x, #x)
+#define TOK_ASM_int TOK_INT
+#define DEF_ASMDIR(x) DEF(TOK_ASMDIR_ ## x, "." #x)
+#define TOK_ASMDIR_FIRST TOK_ASMDIR_byte
+#define TOK_ASMDIR_LAST TOK_ASMDIR_section
+
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+/* only used for i386 asm opcodes definitions */
+#define DEF_BWL(x) \
+ DEF(TOK_ASM_ ## x ## b, #x "b") \
+ DEF(TOK_ASM_ ## x ## w, #x "w") \
+ DEF(TOK_ASM_ ## x ## l, #x "l") \
+ DEF(TOK_ASM_ ## x, #x)
+#define DEF_WL(x) \
+ DEF(TOK_ASM_ ## x ## w, #x "w") \
+ DEF(TOK_ASM_ ## x ## l, #x "l") \
+ DEF(TOK_ASM_ ## x, #x)
+#ifdef TCC_TARGET_X86_64
+# define DEF_BWLQ(x) \
+ DEF(TOK_ASM_ ## x ## b, #x "b") \
+ DEF(TOK_ASM_ ## x ## w, #x "w") \
+ DEF(TOK_ASM_ ## x ## l, #x "l") \
+ DEF(TOK_ASM_ ## x ## q, #x "q") \
+ DEF(TOK_ASM_ ## x, #x)
+# define DEF_WLQ(x) \
+ DEF(TOK_ASM_ ## x ## w, #x "w") \
+ DEF(TOK_ASM_ ## x ## l, #x "l") \
+ DEF(TOK_ASM_ ## x ## q, #x "q") \
+ DEF(TOK_ASM_ ## x, #x)
+# define DEF_BWLX DEF_BWLQ
+# define DEF_WLX DEF_WLQ
+/* number of sizes + 1 */
+# define NBWLX 5
+#else
+# define DEF_BWLX DEF_BWL
+# define DEF_WLX DEF_WL
+/* number of sizes + 1 */
+# define NBWLX 4
+#endif
+
+#define DEF_FP1(x) \
+ DEF(TOK_ASM_ ## f ## x ## s, "f" #x "s") \
+ DEF(TOK_ASM_ ## fi ## x ## l, "fi" #x "l") \
+ DEF(TOK_ASM_ ## f ## x ## l, "f" #x "l") \
+ DEF(TOK_ASM_ ## fi ## x ## s, "fi" #x "s")
+
+#define DEF_FP(x) \
+ DEF(TOK_ASM_ ## f ## x, "f" #x ) \
+ DEF(TOK_ASM_ ## f ## x ## p, "f" #x "p") \
+ DEF_FP1(x)
+
+#define DEF_ASMTEST(x,suffix) \
+ DEF_ASM(x ## o ## suffix) \
+ DEF_ASM(x ## no ## suffix) \
+ DEF_ASM(x ## b ## suffix) \
+ DEF_ASM(x ## c ## suffix) \
+ DEF_ASM(x ## nae ## suffix) \
+ DEF_ASM(x ## nb ## suffix) \
+ DEF_ASM(x ## nc ## suffix) \
+ DEF_ASM(x ## ae ## suffix) \
+ DEF_ASM(x ## e ## suffix) \
+ DEF_ASM(x ## z ## suffix) \
+ DEF_ASM(x ## ne ## suffix) \
+ DEF_ASM(x ## nz ## suffix) \
+ DEF_ASM(x ## be ## suffix) \
+ DEF_ASM(x ## na ## suffix) \
+ DEF_ASM(x ## nbe ## suffix) \
+ DEF_ASM(x ## a ## suffix) \
+ DEF_ASM(x ## s ## suffix) \
+ DEF_ASM(x ## ns ## suffix) \
+ DEF_ASM(x ## p ## suffix) \
+ DEF_ASM(x ## pe ## suffix) \
+ DEF_ASM(x ## np ## suffix) \
+ DEF_ASM(x ## po ## suffix) \
+ DEF_ASM(x ## l ## suffix) \
+ DEF_ASM(x ## nge ## suffix) \
+ DEF_ASM(x ## nl ## suffix) \
+ DEF_ASM(x ## ge ## suffix) \
+ DEF_ASM(x ## le ## suffix) \
+ DEF_ASM(x ## ng ## suffix) \
+ DEF_ASM(x ## nle ## suffix) \
+ DEF_ASM(x ## g ## suffix)
+
+#endif /* defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 */
+
+enum tcc_token {
+    TOK_LAST = TOK_IDENT - 1
+#define DEF(id, str) ,id
+#include "tcctok.h"
+#undef DEF
+};
+
+/* keywords: tok >= TOK_IDENT && tok < TOK_UIDENT */
+#define TOK_UIDENT TOK_DEFINE
+
+/* ------------ libtcc.c ------------ */
+
+/* use GNU C extensions */
+ST_DATA int gnu_ext;
+/* use Tiny C extensions */
+ST_DATA int tcc_ext;
+/* XXX: get rid of this ASAP */
+ST_DATA struct TCCState *tcc_state;
+
+/* public functions currently used by the tcc main function */
+ST_FUNC char *pstrcpy(char *buf, int buf_size, const char *s);
+ST_FUNC char *pstrcat(char *buf, int buf_size, const char *s);
+ST_FUNC char *pstrncpy(char *out, const char *in, size_t num);
+PUB_FUNC char *tcc_basename(const char *name);
+PUB_FUNC char *tcc_fileextension (const char *name);
+
+#ifndef MEM_DEBUG
+PUB_FUNC void tcc_free(void *ptr);
+PUB_FUNC void *tcc_malloc(unsigned long size);
+PUB_FUNC void *tcc_mallocz(unsigned long size);
+PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size);
+PUB_FUNC char *tcc_strdup(const char *str);
+#else
+#define tcc_free(ptr)           tcc_free_debug(ptr)
+#define tcc_malloc(size)        tcc_malloc_debug(size, __FILE__, __LINE__)
+#define tcc_mallocz(size)       tcc_mallocz_debug(size, __FILE__, __LINE__)
+#define tcc_realloc(ptr,size)   tcc_realloc_debug(ptr, size, __FILE__, __LINE__)
+#define tcc_strdup(str)         tcc_strdup_debug(str, __FILE__, __LINE__)
+PUB_FUNC void tcc_free_debug(void *ptr);
+PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line);
+PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line);
+PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line);
+PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line);
+#endif
+
+#define free(p) use_tcc_free(p)
+#define malloc(s) use_tcc_malloc(s)
+#define realloc(p, s) use_tcc_realloc(p, s)
+#undef strdup
+#define strdup(s) use_tcc_strdup(s)
+PUB_FUNC void tcc_memcheck(void);
+PUB_FUNC void tcc_error_noabort(const char *fmt, ...);
+PUB_FUNC NORETURN void tcc_error(const char *fmt, ...);
+PUB_FUNC void tcc_warning(const char *fmt, ...);
+
+/* other utilities */
+ST_FUNC void dynarray_add(void *ptab, int *nb_ptr, void *data);
+ST_FUNC void dynarray_reset(void *pp, int *n);
+ST_INLN void cstr_ccat(CString *cstr, int ch);
+ST_FUNC void cstr_cat(CString *cstr, const char *str, int len);
+ST_FUNC void cstr_wccat(CString *cstr, int ch);
+ST_FUNC void cstr_new(CString *cstr);
+ST_FUNC void cstr_free(CString *cstr);
+ST_FUNC void cstr_reset(CString *cstr);
+
+ST_INLN void sym_free(Sym *sym);
+ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, int c);
+ST_FUNC Sym *sym_find2(Sym *s, int v);
+ST_FUNC Sym *sym_push(int v, CType *type, int r, int c);
+ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep);
+ST_INLN Sym *struct_find(int v);
+ST_INLN Sym *sym_find(int v);
+ST_FUNC Sym *global_identifier_push(int v, int t, int c);
+
+ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen);
+ST_FUNC int tcc_open(TCCState *s1, const char *filename);
+ST_FUNC void tcc_close(void);
+
+ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags);
+/* flags: */
+#define AFF_PRINT_ERROR     0x10 /* print error if file not found */
+#define AFF_REFERENCED_DLL  0x20 /* load a referenced dll from another dll */
+#define AFF_TYPE_BIN        0x40 /* file to add is binary */
+/* s->filetype: */
+#define AFF_TYPE_NONE   0
+#define AFF_TYPE_C      1
+#define AFF_TYPE_ASM    2
+#define AFF_TYPE_ASMPP  3
+#define AFF_TYPE_LIB    4
+/* values from tcc_object_type(...) */
+#define AFF_BINTYPE_REL 1
+#define AFF_BINTYPE_DYN 2
+#define AFF_BINTYPE_AR  3
+#define AFF_BINTYPE_C67 4
+
+
+ST_FUNC int tcc_add_crt(TCCState *s, const char *filename);
+ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags);
+ST_FUNC void tcc_add_pragma_libs(TCCState *s1);
+PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f);
+PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time);
+PUB_FUNC int tcc_parse_args(TCCState *s, int *argc, char ***argv, int optind);
+#ifdef _WIN32
+ST_FUNC char *normalize_slashes(char *path);
+#endif
+
+/* tcc_parse_args return codes: */
+#define OPT_HELP 1
+#define OPT_HELP2 2
+#define OPT_V 3
+#define OPT_PRINT_DIRS 4
+#define OPT_AR 5
+#define OPT_IMPDEF 6
+#define OPT_M32 32
+#define OPT_M64 64
+
+/* ------------ tccpp.c ------------ */
+
+ST_DATA struct BufferedFile *file;
+ST_DATA int ch, tok;
+ST_DATA CValue tokc;
+ST_DATA const int *macro_ptr;
+ST_DATA int parse_flags;
+ST_DATA int tok_flags;
+ST_DATA CString tokcstr; /* current parsed string, if any */
+
+/* display benchmark infos */
+ST_DATA int total_lines;
+ST_DATA int total_bytes;
+ST_DATA int tok_ident;
+ST_DATA TokenSym **table_ident;
+
+#define TOK_FLAG_BOL   0x0001 /* beginning of line before */
+#define TOK_FLAG_BOF   0x0002 /* beginning of file before */
+#define TOK_FLAG_ENDIF 0x0004 /* a endif was found matching starting #ifdef */
+#define TOK_FLAG_EOF   0x0008 /* end of file */
+
+#define PARSE_FLAG_PREPROCESS 0x0001 /* activate preprocessing */
+#define PARSE_FLAG_TOK_NUM    0x0002 /* return numbers instead of TOK_PPNUM */
+#define PARSE_FLAG_LINEFEED   0x0004 /* line feed is returned as a
+                                        token. line feed is also
+                                        returned at eof */
+#define PARSE_FLAG_ASM_FILE 0x0008 /* we processing an asm file: '#' can be used for line comment, etc. */
+#define PARSE_FLAG_SPACES     0x0010 /* next() returns space tokens (for -E) */
+#define PARSE_FLAG_ACCEPT_STRAYS 0x0020 /* next() returns '\\' token */
+#define PARSE_FLAG_TOK_STR    0x0040 /* return parsed strings instead of TOK_PPSTR */
+
+/* isidnum_table flags: */
+#define IS_SPC 1
+#define IS_ID  2
+#define IS_NUM 4
+
+ST_FUNC TokenSym *tok_alloc(const char *str, int len);
+ST_FUNC const char *get_tok_str(int v, CValue *cv);
+ST_FUNC void begin_macro(TokenString *str, int alloc);
+ST_FUNC void end_macro(void);
+ST_FUNC int set_idnum(int c, int val);
+ST_INLN void tok_str_new(TokenString *s);
+ST_FUNC TokenString *tok_str_alloc(void);
+ST_FUNC void tok_str_free(TokenString *s);
+ST_FUNC void tok_str_free_str(int *str);
+ST_FUNC void tok_str_add(TokenString *s, int t);
+ST_FUNC void tok_str_add_tok(TokenString *s);
+ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg);
+ST_FUNC void define_undef(Sym *s);
+ST_INLN Sym *define_find(int v);
+ST_FUNC void free_defines(Sym *b);
+ST_FUNC Sym *label_find(int v);
+ST_FUNC Sym *label_push(Sym **ptop, int v, int flags);
+ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep);
+ST_FUNC void parse_define(void);
+ST_FUNC void preprocess(int is_bof);
+ST_FUNC void next_nomacro(void);
+ST_FUNC void next(void);
+ST_INLN void unget_tok(int last_tok);
+ST_FUNC void preprocess_start(TCCState *s1, int is_asm);
+ST_FUNC void preprocess_end(TCCState *s1);
+ST_FUNC void tccpp_new(TCCState *s);
+ST_FUNC void tccpp_delete(TCCState *s);
+ST_FUNC int tcc_preprocess(TCCState *s1);
+ST_FUNC void skip(int c);
+ST_FUNC NORETURN void expect(const char *msg);
+
+/* space excluding newline */
+static inline int is_space(int ch) {
+    return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';
+}
+static inline int isid(int c) {
+    return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
+}
+static inline int isnum(int c) {
+    return c >= '0' && c <= '9';
+}
+static inline int isoct(int c) {
+    return c >= '0' && c <= '7';
+}
+static inline int toup(int c) {
+    return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c;
+}
+
+/* ------------ tccgen.c ------------ */
+
+#define SYM_POOL_NB (8192 / sizeof(Sym))
+ST_DATA Sym *sym_free_first;
+ST_DATA void **sym_pools;
+ST_DATA int nb_sym_pools;
+
+ST_DATA Sym *global_stack;
+ST_DATA Sym *local_stack;
+ST_DATA Sym *local_label_stack;
+ST_DATA Sym *global_label_stack;
+ST_DATA Sym *define_stack;
+ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
+ST_DATA SValue __vstack[1+/*to make bcheck happy*/ VSTACK_SIZE], *vtop, *pvtop;
+#define vstack  (__vstack + 1)
+ST_DATA int rsym, anon_sym, ind, loc;
+
+ST_DATA int const_wanted; /* true if constant wanted */
+ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
+ST_DATA int global_expr;  /* true if compound literals must be allocated globally (used during initializers parsing */
+ST_DATA CType func_vt; /* current function return type (used by return instruction) */
+ST_DATA int func_var; /* true if current function is variadic */
+ST_DATA int func_vc;
+ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
+ST_DATA const char *funcname;
+ST_DATA int g_debug;
+
+ST_FUNC void tcc_debug_start(TCCState *s1);
+ST_FUNC void tcc_debug_end(TCCState *s1);
+ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym);
+ST_FUNC void tcc_debug_funcend(TCCState *s1, int size);
+ST_FUNC void tcc_debug_line(TCCState *s1);
+
+ST_FUNC int tccgen_compile(TCCState *s1);
+ST_FUNC void free_inline_functions(TCCState *s);
+ST_FUNC void check_vstack(void);
+
+ST_INLN int is_float(int t);
+ST_FUNC int ieee_finite(double d);
+ST_FUNC void test_lvalue(void);
+ST_FUNC void vpushi(int v);
+ST_FUNC ElfSym *elfsym(Sym *);
+ST_FUNC void update_storage(Sym *sym);
+ST_FUNC Sym *external_global_sym(int v, CType *type, int r);
+ST_FUNC void vset(CType *type, int r, int v);
+ST_FUNC void vswap(void);
+ST_FUNC void vpush_global_sym(CType *type, int v);
+ST_FUNC void vrote(SValue *e, int n);
+ST_FUNC void vrott(int n);
+ST_FUNC void vrotb(int n);
+#ifdef TCC_TARGET_ARM
+ST_FUNC int get_reg_ex(int rc, int rc2);
+ST_FUNC void lexpand_nr(void);
+#endif
+ST_FUNC void vpushv(SValue *v);
+ST_FUNC void save_reg(int r);
+ST_FUNC void save_reg_upstack(int r, int n);
+ST_FUNC int get_reg(int rc);
+ST_FUNC void save_regs(int n);
+ST_FUNC void gaddrof(void);
+ST_FUNC int gv(int rc);
+ST_FUNC void gv2(int rc1, int rc2);
+ST_FUNC void vpop(void);
+ST_FUNC void gen_op(int op);
+ST_FUNC int type_size(CType *type, int *a);
+ST_FUNC void mk_pointer(CType *type);
+ST_FUNC void vstore(void);
+ST_FUNC void inc(int post, int c);
+ST_FUNC void parse_mult_str (CString *astr, const char *msg);
+ST_FUNC void parse_asm_str(CString *astr);
+ST_FUNC int lvalue_type(int t);
+ST_FUNC void indir(void);
+ST_FUNC void unary(void);
+ST_FUNC void expr_prod(void);
+ST_FUNC void expr_sum(void);
+ST_FUNC void gexpr(void);
+ST_FUNC int expr_const(void);
+#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67
+ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size);
+#endif
+#if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE
+ST_FUNC int classify_x86_64_va_arg(CType *ty);
+#endif
+
+/* ------------ tccelf.c ------------ */
+
+#define TCC_OUTPUT_FORMAT_ELF    0 /* default output format: ELF */
+#define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */
+#define TCC_OUTPUT_FORMAT_COFF   2 /* COFF */
+
+#define ARMAG  "!<arch>\012"    /* For COFF and a.out archives */
+
+typedef struct {
+    unsigned int n_strx;         /* index into string table of name */
+    unsigned char n_type;         /* type of symbol */
+    unsigned char n_other;        /* misc info (usually empty) */
+    unsigned short n_desc;        /* description field */
+    unsigned int n_value;        /* value of symbol */
+} Stab_Sym;
+
+ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
+ST_DATA Section *common_section;
+ST_DATA Section *cur_text_section; /* current section where function code is generated */
+#ifdef CONFIG_TCC_ASM
+ST_DATA Section *last_text_section; /* to handle .previous asm directive */
+#endif
+#ifdef CONFIG_TCC_BCHECK
+/* bound check related sections */
+ST_DATA Section *bounds_section; /* contains global data bound description */
+ST_DATA Section *lbounds_section; /* contains local data bound description */
+ST_FUNC void tccelf_bounds_new(TCCState *s);
+#endif
+/* symbol sections */
+ST_DATA Section *symtab_section;
+/* debug sections */
+ST_DATA Section *stab_section, *stabstr_section;
+
+ST_FUNC void tccelf_new(TCCState *s);
+ST_FUNC void tccelf_delete(TCCState *s);
+ST_FUNC void tccelf_stab_new(TCCState *s);
+ST_FUNC void tccelf_begin_file(TCCState *s1);
+ST_FUNC void tccelf_end_file(TCCState *s1);
+
+ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags);
+ST_FUNC void section_realloc(Section *sec, unsigned long new_size);
+ST_FUNC size_t section_add(Section *sec, addr_t size, int align);
+ST_FUNC void *section_ptr_add(Section *sec, addr_t size);
+ST_FUNC void section_reserve(Section *sec, unsigned long size);
+ST_FUNC Section *find_section(TCCState *s1, const char *name);
+ST_FUNC Section *new_symtab(TCCState *s1, const char *symtab_name, int sh_type, int sh_flags, const char *strtab_name, const char *hash_name, int hash_sh_flags);
+
+ST_FUNC void put_extern_sym2(Sym *sym, int sh_num, addr_t value, unsigned long size, int can_add_underscore);
+ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size);
+#if PTR_SIZE == 4
+ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type);
+#endif
+ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, addr_t addend);
+
+ST_FUNC int put_elf_str(Section *s, const char *sym);
+ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);
+ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int shndx, const char *name);
+ST_FUNC int find_elf_sym(Section *s, const char *name);
+ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol);
+ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, int type, int symbol, addr_t addend);
+
+ST_FUNC void put_stabs(const char *str, int type, int other, int desc, unsigned long value);
+ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc, unsigned long value, Section *sec, int sym_index);
+ST_FUNC void put_stabn(int type, int other, int desc, int value);
+ST_FUNC void put_stabd(int type, int other, int desc);
+
+ST_FUNC void resolve_common_syms(TCCState *s1);
+ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve);
+ST_FUNC void relocate_section(TCCState *s1, Section *s);
+
+ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h);
+ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset);
+ST_FUNC int tcc_load_archive(TCCState *s1, int fd);
+ST_FUNC void tcc_add_bcheck(TCCState *s1);
+ST_FUNC void tcc_add_runtime(TCCState *s1);
+
+ST_FUNC void build_got_entries(TCCState *s1);
+ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc);
+ST_FUNC void squeeze_multi_relocs(Section *sec, size_t oldrelocoffset);
+
+ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err);
+#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
+ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name);
+#endif
+
+#ifndef TCC_TARGET_PE
+ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level);
+ST_FUNC int tcc_load_ldscript(TCCState *s1);
+ST_FUNC uint8_t *parse_comment(uint8_t *p);
+ST_FUNC void minp(void);
+ST_INLN void inp(void);
+ST_FUNC int handle_eob(void);
+#endif
+
+/* ------------ xxx-link.c ------------ */
+
+/* Whether to generate a GOT/PLT entry and when. NO_GOTPLT_ENTRY is first so
+   that unknown relocation don't create a GOT or PLT entry */
+enum gotplt_entry {
+    NO_GOTPLT_ENTRY,	/* never generate (eg. GLOB_DAT & JMP_SLOT relocs) */
+    BUILD_GOT_ONLY,	/* only build GOT (eg. TPOFF relocs) */
+    AUTO_GOTPLT_ENTRY,	/* generate if sym is UNDEF */
+    ALWAYS_GOTPLT_ENTRY	/* always generate (eg. PLTOFF relocs) */
+};
+
+ST_FUNC int code_reloc (int reloc_type);
+ST_FUNC int gotplt_entry_type (int reloc_type);
+ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr);
+ST_FUNC void relocate_init(Section *sr);
+ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val);
+ST_FUNC void relocate_plt(TCCState *s1);
+
+/* ------------ xxx-gen.c ------------ */
+
+ST_DATA const int reg_classes[NB_REGS];
+
+ST_FUNC void gsym_addr(int t, int a);
+ST_FUNC void gsym(int t);
+ST_FUNC void load(int r, SValue *sv);
+ST_FUNC void store(int r, SValue *v);
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *align, int *regsize);
+ST_FUNC void gfunc_call(int nb_args);
+ST_FUNC void gfunc_prolog(CType *func_type);
+ST_FUNC void gfunc_epilog(void);
+ST_FUNC int gjmp(int t);
+ST_FUNC void gjmp_addr(int a);
+ST_FUNC int gtst(int inv, int t);
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+ST_FUNC void gtst_addr(int inv, int a);
+#else
+#define gtst_addr(inv, a) gsym_addr(gtst(inv, 0), a)
+#endif
+ST_FUNC void gen_opi(int op);
+ST_FUNC void gen_opf(int op);
+ST_FUNC void gen_cvt_ftoi(int t);
+ST_FUNC void gen_cvt_ftof(int t);
+ST_FUNC void ggoto(void);
+#ifndef TCC_TARGET_C67
+ST_FUNC void o(unsigned int c);
+#endif
+#ifndef TCC_TARGET_ARM
+ST_FUNC void gen_cvt_itof(int t);
+#endif
+ST_FUNC void gen_vla_sp_save(int addr);
+ST_FUNC void gen_vla_sp_restore(int addr);
+ST_FUNC void gen_vla_alloc(CType *type, int align);
+
+static inline uint16_t read16le(unsigned char *p) {
+    return p[0] | (uint16_t)p[1] << 8;
+}
+static inline void write16le(unsigned char *p, uint16_t x) {
+    p[0] = x & 255;  p[1] = x >> 8 & 255;
+}
+static inline uint32_t read32le(unsigned char *p) {
+  return read16le(p) | (uint32_t)read16le(p + 2) << 16;
+}
+static inline void write32le(unsigned char *p, uint32_t x) {
+    write16le(p, x);  write16le(p + 2, x >> 16);
+}
+static inline void add32le(unsigned char *p, int32_t x) {
+    write32le(p, read32le(p) + x);
+}
+static inline uint64_t read64le(unsigned char *p) {
+  return read32le(p) | (uint64_t)read32le(p + 4) << 32;
+}
+static inline void write64le(unsigned char *p, uint64_t x) {
+    write32le(p, x);  write32le(p + 4, x >> 32);
+}
+static inline void add64le(unsigned char *p, int64_t x) {
+    write64le(p, read64le(p) + x);
+}
+
+/* ------------ i386-gen.c ------------ */
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+ST_FUNC void g(int c);
+ST_FUNC void gen_le16(int c);
+ST_FUNC void gen_le32(int c);
+ST_FUNC void gen_addr32(int r, Sym *sym, int c);
+ST_FUNC void gen_addrpc32(int r, Sym *sym, int c);
+#endif
+
+#ifdef CONFIG_TCC_BCHECK
+ST_FUNC void gen_bounded_ptr_add(void);
+ST_FUNC void gen_bounded_ptr_deref(void);
+#endif
+
+/* ------------ x86_64-gen.c ------------ */
+#ifdef TCC_TARGET_X86_64
+ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c);
+ST_FUNC void gen_opl(int op);
+#ifdef TCC_TARGET_PE
+ST_FUNC void gen_vla_result(int addr);
+#endif
+#endif
+
+/* ------------ arm-gen.c ------------ */
+#ifdef TCC_TARGET_ARM
+#if defined(TCC_ARM_EABI) && !defined(CONFIG_TCC_ELFINTERP)
+PUB_FUNC const char *default_elfinterp(struct TCCState *s);
+#endif
+ST_FUNC void arm_init(struct TCCState *s);
+ST_FUNC void gen_cvt_itof1(int t);
+#endif
+
+/* ------------ arm64-gen.c ------------ */
+#ifdef TCC_TARGET_ARM64
+ST_FUNC void gen_cvt_sxtw(void);
+ST_FUNC void gen_opl(int op);
+ST_FUNC void gfunc_return(CType *func_type);
+ST_FUNC void gen_va_start(void);
+ST_FUNC void gen_va_arg(CType *t);
+ST_FUNC void gen_clear_cache(void);
+#endif
+
+/* ------------ c67-gen.c ------------ */
+#ifdef TCC_TARGET_C67
+#endif
+
+/* ------------ tcccoff.c ------------ */
+
+#ifdef TCC_TARGET_COFF
+ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f);
+ST_FUNC int tcc_load_coff(TCCState * s1, int fd);
+#endif
+
+/* ------------ tccasm.c ------------ */
+ST_FUNC void asm_instr(void);
+ST_FUNC void asm_global_instr(void);
+#ifdef CONFIG_TCC_ASM
+ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, const char *name, const char **pp);
+ST_FUNC Sym* get_asm_sym(int name, Sym *csym);
+ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);
+ST_FUNC int asm_int_expr(TCCState *s1);
+ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess);
+/* ------------ i386-asm.c ------------ */
+ST_FUNC void gen_expr32(ExprValue *pe);
+#ifdef TCC_TARGET_X86_64
+ST_FUNC void gen_expr64(ExprValue *pe);
+#endif
+ST_FUNC void asm_opcode(TCCState *s1, int opcode);
+ST_FUNC int asm_parse_regvar(int t);
+ST_FUNC void asm_compute_constraints(ASMOperand *operands, int nb_operands, int nb_outputs, const uint8_t *clobber_regs, int *pout_reg);
+ST_FUNC void subst_asm_operand(CString *add_str, SValue *sv, int modifier);
+ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands, int nb_outputs, int is_output, uint8_t *clobber_regs, int out_reg);
+ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str);
+#endif
+
+/* ------------ tccpe.c -------------- */
+#ifdef TCC_TARGET_PE
+ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd);
+ST_FUNC int pe_output_file(TCCState * s1, const char *filename);
+ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value);
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2);
+#endif
+#ifdef TCC_TARGET_X86_64
+ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack);
+#endif
+PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp);
+/* symbol properties stored in Elf32_Sym->st_other */
+# define ST_PE_EXPORT 0x10
+# define ST_PE_IMPORT 0x20
+# define ST_PE_STDCALL 0x40
+#endif
+#define ST_ASM_SET 0x04
+
+/* ------------ tccrun.c ----------------- */
+#ifdef TCC_IS_NATIVE
+#ifdef CONFIG_TCC_STATIC
+#define RTLD_LAZY       0x001
+#define RTLD_NOW        0x002
+#define RTLD_GLOBAL     0x100
+#define RTLD_DEFAULT    NULL
+/* dummy function for profiling */
+ST_FUNC void *dlopen(const char *filename, int flag);
+ST_FUNC void dlclose(void *p);
+ST_FUNC const char *dlerror(void);
+ST_FUNC void *dlsym(void *handle, const char *symbol);
+#endif
+#ifdef CONFIG_TCC_BACKTRACE
+ST_DATA int rt_num_callers;
+ST_DATA const char **rt_bound_error_msg;
+ST_DATA void *rt_prog_main;
+ST_FUNC void tcc_set_num_callers(int n);
+#endif
+ST_FUNC void tcc_run_free(TCCState *s1);
+#endif
+
+/* ------------ tcctools.c ----------------- */
+#if 0 /* included in tcc.c */
+ST_FUNC int tcc_tool_ar(TCCState *s, int argc, char **argv);
+#ifdef TCC_TARGET_PE
+ST_FUNC int tcc_tool_impdef(TCCState *s, int argc, char **argv);
+#endif
+ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int option);
+ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename);
+#endif
+
+/********************************************************/
+#undef ST_DATA
+#if ONE_SOURCE
+#define ST_DATA static
+#else
+#define ST_DATA
+#endif
+/********************************************************/
+#endif /* _TCC_H */
Index: EcnlProtoTool/trunk/tcc-0.9.27/tccasm.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tccasm.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tccasm.c	(revision 331)
@@ -0,0 +1,1277 @@
+/*
+ *  GAS like assembler for TCC
+ * 
+ *  Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "tcc.h"
+#ifdef CONFIG_TCC_ASM
+
+ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n)
+{
+    char buf[64];
+    TokenSym *ts;
+
+    snprintf(buf, sizeof(buf), "L..%u", n);
+    ts = tok_alloc(buf, strlen(buf));
+    return ts->tok;
+}
+
+static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global);
+static Sym* asm_new_label(TCCState *s1, int label, int is_local);
+static Sym* asm_new_label1(TCCState *s1, int label, int is_local, int sh_num, int value);
+
+static Sym *asm_label_find(int v)
+{
+    Sym *sym = sym_find(v);
+    while (sym && sym->sym_scope)
+        sym = sym->prev_tok;
+    return sym;
+}
+
+static Sym *asm_label_push(int v)
+{
+    /* We always add VT_EXTERN, for sym definition that's tentative
+       (for .set, removed for real defs), for mere references it's correct
+       as is.  */
+    Sym *sym = global_identifier_push(v, VT_ASM | VT_EXTERN | VT_STATIC, 0);
+    sym->r = VT_CONST | VT_SYM;
+    return sym;
+}
+
+/* Return a symbol we can use inside the assembler, having name NAME.
+   Symbols from asm and C source share a namespace.  If we generate
+   an asm symbol it's also a (file-global) C symbol, but it's
+   either not accessible by name (like "L.123"), or its type information
+   is such that it's not usable without a proper C declaration.
+
+   Sometimes we need symbols accessible by name from asm, which
+   are anonymous in C, in this case CSYM can be used to transfer
+   all information from that symbol to the (possibly newly created)
+   asm symbol.  */
+ST_FUNC Sym* get_asm_sym(int name, Sym *csym)
+{
+    Sym *sym = asm_label_find(name);
+    if (!sym) {
+	sym = asm_label_push(name);
+	if (csym)
+	  sym->c = csym->c;
+    }
+    return sym;
+}
+
+static Sym* asm_section_sym(TCCState *s1, Section *sec)
+{
+    char buf[100];
+    int label = tok_alloc(buf,
+        snprintf(buf, sizeof buf, "L.%s", sec->name)
+        )->tok;
+    Sym *sym = asm_label_find(label);
+    return sym ? sym : asm_new_label1(s1, label, 1, sec->sh_num, 0);
+}
+
+/* We do not use the C expression parser to handle symbols. Maybe the
+   C expression parser could be tweaked to do so. */
+
+static void asm_expr_unary(TCCState *s1, ExprValue *pe)
+{
+    Sym *sym;
+    int op, label;
+    uint64_t n;
+    const char *p;
+
+    switch(tok) {
+    case TOK_PPNUM:
+        p = tokc.str.data;
+        n = strtoull(p, (char **)&p, 0);
+        if (*p == 'b' || *p == 'f') {
+            /* backward or forward label */
+            label = asm_get_local_label_name(s1, n);
+            sym = asm_label_find(label);
+            if (*p == 'b') {
+                /* backward : find the last corresponding defined label */
+                if (sym && (!sym->c || elfsym(sym)->st_shndx == SHN_UNDEF))
+                    sym = sym->prev_tok;
+                if (!sym)
+                    tcc_error("local label '%d' not found backward", n);
+            } else {
+                /* forward */
+                if (!sym || (sym->c && elfsym(sym)->st_shndx != SHN_UNDEF)) {
+                    /* if the last label is defined, then define a new one */
+		    sym = asm_label_push(label);
+                }
+            }
+	    pe->v = 0;
+	    pe->sym = sym;
+	    pe->pcrel = 0;
+        } else if (*p == '\0') {
+            pe->v = n;
+            pe->sym = NULL;
+	    pe->pcrel = 0;
+        } else {
+            tcc_error("invalid number syntax");
+        }
+        next();
+        break;
+    case '+':
+        next();
+        asm_expr_unary(s1, pe);
+        break;
+    case '-':
+    case '~':
+        op = tok;
+        next();
+        asm_expr_unary(s1, pe);
+        if (pe->sym)
+            tcc_error("invalid operation with label");
+        if (op == '-')
+            pe->v = -pe->v;
+        else
+            pe->v = ~pe->v;
+        break;
+    case TOK_CCHAR:
+    case TOK_LCHAR:
+	pe->v = tokc.i;
+	pe->sym = NULL;
+	pe->pcrel = 0;
+	next();
+	break;
+    case '(':
+        next();
+        asm_expr(s1, pe);
+        skip(')');
+        break;
+    case '.':
+        pe->v = ind;
+        pe->sym = asm_section_sym(s1, cur_text_section);
+        pe->pcrel = 0;
+        next();
+        break;
+    default:
+        if (tok >= TOK_IDENT) {
+	    ElfSym *esym;
+            /* label case : if the label was not found, add one */
+	    sym = get_asm_sym(tok, NULL);
+	    esym = elfsym(sym);
+            if (esym && esym->st_shndx == SHN_ABS) {
+                /* if absolute symbol, no need to put a symbol value */
+                pe->v = esym->st_value;
+                pe->sym = NULL;
+		pe->pcrel = 0;
+            } else {
+                pe->v = 0;
+                pe->sym = sym;
+		pe->pcrel = 0;
+            }
+            next();
+        } else {
+            tcc_error("bad expression syntax [%s]", get_tok_str(tok, &tokc));
+        }
+        break;
+    }
+}
+    
+static void asm_expr_prod(TCCState *s1, ExprValue *pe)
+{
+    int op;
+    ExprValue e2;
+
+    asm_expr_unary(s1, pe);
+    for(;;) {
+        op = tok;
+        if (op != '*' && op != '/' && op != '%' && 
+            op != TOK_SHL && op != TOK_SAR)
+            break;
+        next();
+        asm_expr_unary(s1, &e2);
+        if (pe->sym || e2.sym)
+            tcc_error("invalid operation with label");
+        switch(op) {
+        case '*':
+            pe->v *= e2.v;
+            break;
+        case '/':  
+            if (e2.v == 0) {
+            div_error:
+                tcc_error("division by zero");
+            }
+            pe->v /= e2.v;
+            break;
+        case '%':  
+            if (e2.v == 0)
+                goto div_error;
+            pe->v %= e2.v;
+            break;
+        case TOK_SHL:
+            pe->v <<= e2.v;
+            break;
+        default:
+        case TOK_SAR:
+            pe->v >>= e2.v;
+            break;
+        }
+    }
+}
+
+static void asm_expr_logic(TCCState *s1, ExprValue *pe)
+{
+    int op;
+    ExprValue e2;
+
+    asm_expr_prod(s1, pe);
+    for(;;) {
+        op = tok;
+        if (op != '&' && op != '|' && op != '^')
+            break;
+        next();
+        asm_expr_prod(s1, &e2);
+        if (pe->sym || e2.sym)
+            tcc_error("invalid operation with label");
+        switch(op) {
+        case '&':
+            pe->v &= e2.v;
+            break;
+        case '|':  
+            pe->v |= e2.v;
+            break;
+        default:
+        case '^':
+            pe->v ^= e2.v;
+            break;
+        }
+    }
+}
+
+static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
+{
+    int op;
+    ExprValue e2;
+
+    asm_expr_logic(s1, pe);
+    for(;;) {
+        op = tok;
+        if (op != '+' && op != '-')
+            break;
+        next();
+        asm_expr_logic(s1, &e2);
+        if (op == '+') {
+            if (pe->sym != NULL && e2.sym != NULL)
+                goto cannot_relocate;
+            pe->v += e2.v;
+            if (pe->sym == NULL && e2.sym != NULL)
+                pe->sym = e2.sym;
+        } else {
+            pe->v -= e2.v;
+            /* NOTE: we are less powerful than gas in that case
+               because we store only one symbol in the expression */
+	    if (!e2.sym) {
+		/* OK */
+	    } else if (pe->sym == e2.sym) { 
+		/* OK */
+		pe->sym = NULL; /* same symbols can be subtracted to NULL */
+	    } else {
+		ElfSym *esym1, *esym2;
+		esym1 = elfsym(pe->sym);
+		esym2 = elfsym(e2.sym);
+		if (esym1 && esym1->st_shndx == esym2->st_shndx
+		    && esym1->st_shndx != SHN_UNDEF) {
+		    /* we also accept defined symbols in the same section */
+		    pe->v += esym1->st_value - esym2->st_value;
+		    pe->sym = NULL;
+		} else if (esym2->st_shndx == cur_text_section->sh_num) {
+		    /* When subtracting a defined symbol in current section
+		       this actually makes the value PC-relative.  */
+		    pe->v -= esym2->st_value - ind - 4;
+		    pe->pcrel = 1;
+		    e2.sym = NULL;
+		} else {
+cannot_relocate:
+		    tcc_error("invalid operation with label");
+		}
+	    }
+        }
+    }
+}
+
+static inline void asm_expr_cmp(TCCState *s1, ExprValue *pe)
+{
+    int op;
+    ExprValue e2;
+
+    asm_expr_sum(s1, pe);
+    for(;;) {
+        op = tok;
+	if (op != TOK_EQ && op != TOK_NE
+	    && (op > TOK_GT || op < TOK_ULE))
+            break;
+        next();
+        asm_expr_sum(s1, &e2);
+        if (pe->sym || e2.sym)
+            tcc_error("invalid operation with label");
+        switch(op) {
+	case TOK_EQ:
+	    pe->v = pe->v == e2.v;
+	    break;
+	case TOK_NE:
+	    pe->v = pe->v != e2.v;
+	    break;
+	case TOK_LT:
+	    pe->v = (int64_t)pe->v < (int64_t)e2.v;
+	    break;
+	case TOK_GE:
+	    pe->v = (int64_t)pe->v >= (int64_t)e2.v;
+	    break;
+	case TOK_LE:
+	    pe->v = (int64_t)pe->v <= (int64_t)e2.v;
+	    break;
+	case TOK_GT:
+	    pe->v = (int64_t)pe->v > (int64_t)e2.v;
+	    break;
+        default:
+            break;
+        }
+	/* GAS compare results are -1/0 not 1/0.  */
+	pe->v = -(int64_t)pe->v;
+    }
+}
+
+ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe)
+{
+    asm_expr_cmp(s1, pe);
+}
+
+ST_FUNC int asm_int_expr(TCCState *s1)
+{
+    ExprValue e;
+    asm_expr(s1, &e);
+    if (e.sym)
+        expect("constant");
+    return e.v;
+}
+
+static Sym* asm_new_label1(TCCState *s1, int label, int is_local,
+                           int sh_num, int value)
+{
+    Sym *sym;
+    ElfSym *esym;
+
+    sym = asm_label_find(label);
+    if (sym) {
+	esym = elfsym(sym);
+	/* A VT_EXTERN symbol, even if it has a section is considered
+	   overridable.  This is how we "define" .set targets.  Real
+	   definitions won't have VT_EXTERN set.  */
+        if (esym && esym->st_shndx != SHN_UNDEF) {
+            /* the label is already defined */
+            if (IS_ASM_SYM(sym)
+                && (is_local == 1 || (sym->type.t & VT_EXTERN)))
+                goto new_label;
+            if (!(sym->type.t & VT_EXTERN))
+                tcc_error("assembler label '%s' already defined",
+                          get_tok_str(label, NULL));
+        }
+    } else {
+    new_label:
+        sym = asm_label_push(label);
+    }
+    if (!sym->c)
+      put_extern_sym2(sym, SHN_UNDEF, 0, 0, 0);
+    esym = elfsym(sym);
+    esym->st_shndx = sh_num;
+    esym->st_value = value;
+    if (is_local != 2)
+        sym->type.t &= ~VT_EXTERN;
+    return sym;
+}
+
+static Sym* asm_new_label(TCCState *s1, int label, int is_local)
+{
+    return asm_new_label1(s1, label, is_local, cur_text_section->sh_num, ind);
+}
+
+/* Set the value of LABEL to that of some expression (possibly
+   involving other symbols).  LABEL can be overwritten later still.  */
+static Sym* set_symbol(TCCState *s1, int label)
+{
+    long n;
+    ExprValue e;
+    Sym *sym;
+    ElfSym *esym;
+    next();
+    asm_expr(s1, &e);
+    n = e.v;
+    esym = elfsym(e.sym);
+    if (esym)
+	n += esym->st_value;
+    sym = asm_new_label1(s1, label, 2, esym ? esym->st_shndx : SHN_ABS, n);
+    elfsym(sym)->st_other |= ST_ASM_SET;
+    return sym;
+}
+
+static void use_section1(TCCState *s1, Section *sec)
+{
+    cur_text_section->data_offset = ind;
+    cur_text_section = sec;
+    ind = cur_text_section->data_offset;
+}
+
+static void use_section(TCCState *s1, const char *name)
+{
+    Section *sec;
+    sec = find_section(s1, name);
+    use_section1(s1, sec);
+}
+
+static void push_section(TCCState *s1, const char *name)
+{
+    Section *sec = find_section(s1, name);
+    sec->prev = cur_text_section;
+    use_section1(s1, sec);
+}
+
+static void pop_section(TCCState *s1)
+{
+    Section *prev = cur_text_section->prev;
+    if (!prev)
+        tcc_error(".popsection without .pushsection");
+    cur_text_section->prev = NULL;
+    use_section1(s1, prev);
+}
+
+static void asm_parse_directive(TCCState *s1, int global)
+{
+    int n, offset, v, size, tok1;
+    Section *sec;
+    uint8_t *ptr;
+
+    /* assembler directive */
+    sec = cur_text_section;
+    switch(tok) {
+    case TOK_ASMDIR_align:
+    case TOK_ASMDIR_balign:
+    case TOK_ASMDIR_p2align:
+    case TOK_ASMDIR_skip:
+    case TOK_ASMDIR_space:
+        tok1 = tok;
+        next();
+        n = asm_int_expr(s1);
+        if (tok1 == TOK_ASMDIR_p2align)
+        {
+            if (n < 0 || n > 30)
+                tcc_error("invalid p2align, must be between 0 and 30");
+            n = 1 << n;
+            tok1 = TOK_ASMDIR_align;
+        }
+        if (tok1 == TOK_ASMDIR_align || tok1 == TOK_ASMDIR_balign) {
+            if (n < 0 || (n & (n-1)) != 0)
+                tcc_error("alignment must be a positive power of two");
+            offset = (ind + n - 1) & -n;
+            size = offset - ind;
+            /* the section must have a compatible alignment */
+            if (sec->sh_addralign < n)
+                sec->sh_addralign = n;
+        } else {
+	    if (n < 0)
+	        n = 0;
+            size = n;
+        }
+        v = 0;
+        if (tok == ',') {
+            next();
+            v = asm_int_expr(s1);
+        }
+    zero_pad:
+        if (sec->sh_type != SHT_NOBITS) {
+            sec->data_offset = ind;
+            ptr = section_ptr_add(sec, size);
+            memset(ptr, v, size);
+        }
+        ind += size;
+        break;
+    case TOK_ASMDIR_quad:
+#ifdef TCC_TARGET_X86_64
+	size = 8;
+	goto asm_data;
+#else
+        next();
+        for(;;) {
+            uint64_t vl;
+            const char *p;
+
+            p = tokc.str.data;
+            if (tok != TOK_PPNUM) {
+            error_constant:
+                tcc_error("64 bit constant");
+            }
+            vl = strtoll(p, (char **)&p, 0);
+            if (*p != '\0')
+                goto error_constant;
+            next();
+            if (sec->sh_type != SHT_NOBITS) {
+                /* XXX: endianness */
+                gen_le32(vl);
+                gen_le32(vl >> 32);
+            } else {
+                ind += 8;
+            }
+            if (tok != ',')
+                break;
+            next();
+        }
+        break;
+#endif
+    case TOK_ASMDIR_byte:
+        size = 1;
+        goto asm_data;
+    case TOK_ASMDIR_word:
+    case TOK_ASMDIR_short:
+        size = 2;
+        goto asm_data;
+    case TOK_ASMDIR_long:
+    case TOK_ASMDIR_int:
+        size = 4;
+    asm_data:
+        next();
+        for(;;) {
+            ExprValue e;
+            asm_expr(s1, &e);
+            if (sec->sh_type != SHT_NOBITS) {
+                if (size == 4) {
+                    gen_expr32(&e);
+#ifdef TCC_TARGET_X86_64
+		} else if (size == 8) {
+		    gen_expr64(&e);
+#endif
+                } else {
+                    if (e.sym)
+                        expect("constant");
+                    if (size == 1)
+                        g(e.v);
+                    else
+                        gen_le16(e.v);
+                }
+            } else {
+                ind += size;
+            }
+            if (tok != ',')
+                break;
+            next();
+        }
+        break;
+    case TOK_ASMDIR_fill:
+        {
+            int repeat, size, val, i, j;
+            uint8_t repeat_buf[8];
+            next();
+            repeat = asm_int_expr(s1);
+            if (repeat < 0) {
+                tcc_error("repeat < 0; .fill ignored");
+                break;
+            }
+            size = 1;
+            val = 0;
+            if (tok == ',') {
+                next();
+                size = asm_int_expr(s1);
+                if (size < 0) {
+                    tcc_error("size < 0; .fill ignored");
+                    break;
+                }
+                if (size > 8)
+                    size = 8;
+                if (tok == ',') {
+                    next();
+                    val = asm_int_expr(s1);
+                }
+            }
+            /* XXX: endianness */
+            repeat_buf[0] = val;
+            repeat_buf[1] = val >> 8;
+            repeat_buf[2] = val >> 16;
+            repeat_buf[3] = val >> 24;
+            repeat_buf[4] = 0;
+            repeat_buf[5] = 0;
+            repeat_buf[6] = 0;
+            repeat_buf[7] = 0;
+            for(i = 0; i < repeat; i++) {
+                for(j = 0; j < size; j++) {
+                    g(repeat_buf[j]);
+                }
+            }
+        }
+        break;
+    case TOK_ASMDIR_rept:
+        {
+            int repeat;
+            TokenString *init_str;
+            next();
+            repeat = asm_int_expr(s1);
+            init_str = tok_str_alloc();
+            while (next(), tok != TOK_ASMDIR_endr) {
+                if (tok == CH_EOF)
+                    tcc_error("we at end of file, .endr not found");
+                tok_str_add_tok(init_str);
+            }
+            tok_str_add(init_str, -1);
+            tok_str_add(init_str, 0);
+            begin_macro(init_str, 1);
+            while (repeat-- > 0) {
+                tcc_assemble_internal(s1, (parse_flags & PARSE_FLAG_PREPROCESS),
+				      global);
+                macro_ptr = init_str->str;
+            }
+            end_macro();
+            next();
+            break;
+        }
+    case TOK_ASMDIR_org:
+        {
+            unsigned long n;
+	    ExprValue e;
+	    ElfSym *esym;
+            next();
+	    asm_expr(s1, &e);
+	    n = e.v;
+	    esym = elfsym(e.sym);
+	    if (esym) {
+		if (esym->st_shndx != cur_text_section->sh_num)
+		  expect("constant or same-section symbol");
+		n += esym->st_value;
+	    }
+            if (n < ind)
+                tcc_error("attempt to .org backwards");
+            v = 0;
+            size = n - ind;
+            goto zero_pad;
+        }
+        break;
+    case TOK_ASMDIR_set:
+	next();
+	tok1 = tok;
+	next();
+	/* Also accept '.set stuff', but don't do anything with this.
+	   It's used in GAS to set various features like '.set mips16'.  */
+	if (tok == ',')
+	    set_symbol(s1, tok1);
+	break;
+    case TOK_ASMDIR_globl:
+    case TOK_ASMDIR_global:
+    case TOK_ASMDIR_weak:
+    case TOK_ASMDIR_hidden:
+	tok1 = tok;
+	do { 
+            Sym *sym;
+            next();
+            sym = get_asm_sym(tok, NULL);
+	    if (tok1 != TOK_ASMDIR_hidden)
+                sym->type.t &= ~VT_STATIC;
+            if (tok1 == TOK_ASMDIR_weak)
+                sym->a.weak = 1;
+	    else if (tok1 == TOK_ASMDIR_hidden)
+	        sym->a.visibility = STV_HIDDEN;
+            update_storage(sym);
+            next();
+	} while (tok == ',');
+	break;
+    case TOK_ASMDIR_string:
+    case TOK_ASMDIR_ascii:
+    case TOK_ASMDIR_asciz:
+        {
+            const uint8_t *p;
+            int i, size, t;
+
+            t = tok;
+            next();
+            for(;;) {
+                if (tok != TOK_STR)
+                    expect("string constant");
+                p = tokc.str.data;
+                size = tokc.str.size;
+                if (t == TOK_ASMDIR_ascii && size > 0)
+                    size--;
+                for(i = 0; i < size; i++)
+                    g(p[i]);
+                next();
+                if (tok == ',') {
+                    next();
+                } else if (tok != TOK_STR) {
+                    break;
+                }
+            }
+	}
+	break;
+    case TOK_ASMDIR_text:
+    case TOK_ASMDIR_data:
+    case TOK_ASMDIR_bss:
+	{ 
+            char sname[64];
+            tok1 = tok;
+            n = 0;
+            next();
+            if (tok != ';' && tok != TOK_LINEFEED) {
+		n = asm_int_expr(s1);
+		next();
+            }
+            if (n)
+                sprintf(sname, "%s%d", get_tok_str(tok1, NULL), n);
+            else
+                sprintf(sname, "%s", get_tok_str(tok1, NULL));
+            use_section(s1, sname);
+	}
+	break;
+    case TOK_ASMDIR_file:
+        {
+            char filename[512];
+
+            filename[0] = '\0';
+            next();
+
+            if (tok == TOK_STR)
+                pstrcat(filename, sizeof(filename), tokc.str.data);
+            else
+                pstrcat(filename, sizeof(filename), get_tok_str(tok, NULL));
+
+            if (s1->warn_unsupported)
+                tcc_warning("ignoring .file %s", filename);
+
+            next();
+        }
+        break;
+    case TOK_ASMDIR_ident:
+        {
+            char ident[256];
+
+            ident[0] = '\0';
+            next();
+
+            if (tok == TOK_STR)
+                pstrcat(ident, sizeof(ident), tokc.str.data);
+            else
+                pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL));
+
+            if (s1->warn_unsupported)
+                tcc_warning("ignoring .ident %s", ident);
+
+            next();
+        }
+        break;
+    case TOK_ASMDIR_size:
+        { 
+            Sym *sym;
+
+            next();
+            sym = asm_label_find(tok);
+            if (!sym) {
+                tcc_error("label not found: %s", get_tok_str(tok, NULL));
+            }
+
+            /* XXX .size name,label2-label1 */
+            if (s1->warn_unsupported)
+                tcc_warning("ignoring .size %s,*", get_tok_str(tok, NULL));
+
+            next();
+            skip(',');
+            while (tok != TOK_LINEFEED && tok != ';' && tok != CH_EOF) {
+                next();
+            }
+        }
+        break;
+    case TOK_ASMDIR_type:
+        { 
+            Sym *sym;
+            const char *newtype;
+
+            next();
+            sym = get_asm_sym(tok, NULL);
+            next();
+            skip(',');
+            if (tok == TOK_STR) {
+                newtype = tokc.str.data;
+            } else {
+                if (tok == '@' || tok == '%')
+                    next();
+                newtype = get_tok_str(tok, NULL);
+            }
+
+            if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) {
+                sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC;
+            }
+            else if (s1->warn_unsupported)
+                tcc_warning("change type of '%s' from 0x%x to '%s' ignored", 
+                    get_tok_str(sym->v, NULL), sym->type.t, newtype);
+
+            next();
+        }
+        break;
+    case TOK_ASMDIR_pushsection:
+    case TOK_ASMDIR_section:
+        {
+            char sname[256];
+	    int old_nb_section = s1->nb_sections;
+
+	    tok1 = tok;
+            /* XXX: support more options */
+            next();
+            sname[0] = '\0';
+            while (tok != ';' && tok != TOK_LINEFEED && tok != ',') {
+                if (tok == TOK_STR)
+                    pstrcat(sname, sizeof(sname), tokc.str.data);
+                else
+                    pstrcat(sname, sizeof(sname), get_tok_str(tok, NULL));
+                next();
+            }
+            if (tok == ',') {
+                /* skip section options */
+                next();
+                if (tok != TOK_STR)
+                    expect("string constant");
+                next();
+                if (tok == ',') {
+                    next();
+                    if (tok == '@' || tok == '%')
+                        next();
+                    next();
+                }
+            }
+            last_text_section = cur_text_section;
+	    if (tok1 == TOK_ASMDIR_section)
+	        use_section(s1, sname);
+	    else
+	        push_section(s1, sname);
+	    /* If we just allocated a new section reset its alignment to
+	       1.  new_section normally acts for GCC compatibility and
+	       sets alignment to PTR_SIZE.  The assembler behaves different. */
+	    if (old_nb_section != s1->nb_sections)
+	        cur_text_section->sh_addralign = 1;
+        }
+        break;
+    case TOK_ASMDIR_previous:
+        { 
+            Section *sec;
+            next();
+            if (!last_text_section)
+                tcc_error("no previous section referenced");
+            sec = cur_text_section;
+            use_section1(s1, last_text_section);
+            last_text_section = sec;
+        }
+        break;
+    case TOK_ASMDIR_popsection:
+	next();
+	pop_section(s1);
+	break;
+#ifdef TCC_TARGET_I386
+    case TOK_ASMDIR_code16:
+        {
+            next();
+            s1->seg_size = 16;
+        }
+        break;
+    case TOK_ASMDIR_code32:
+        {
+            next();
+            s1->seg_size = 32;
+        }
+        break;
+#endif
+#ifdef TCC_TARGET_X86_64
+    /* added for compatibility with GAS */
+    case TOK_ASMDIR_code64:
+        next();
+        break;
+#endif
+    default:
+        tcc_error("unknown assembler directive '.%s'", get_tok_str(tok, NULL));
+        break;
+    }
+}
+
+
+/* assemble a file */
+static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global)
+{
+    int opcode;
+    int saved_parse_flags = parse_flags;
+
+    parse_flags = PARSE_FLAG_ASM_FILE | PARSE_FLAG_TOK_STR;
+    if (do_preprocess)
+        parse_flags |= PARSE_FLAG_PREPROCESS;
+    for(;;) {
+        next();
+        if (tok == TOK_EOF)
+            break;
+        /* generate line number info */
+        if (global && s1->do_debug)
+            tcc_debug_line(s1);
+        parse_flags |= PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
+    redo:
+        if (tok == '#') {
+            /* horrible gas comment */
+            while (tok != TOK_LINEFEED)
+                next();
+        } else if (tok >= TOK_ASMDIR_FIRST && tok <= TOK_ASMDIR_LAST) {
+            asm_parse_directive(s1, global);
+        } else if (tok == TOK_PPNUM) {
+            const char *p;
+            int n;
+            p = tokc.str.data;
+            n = strtoul(p, (char **)&p, 10);
+            if (*p != '\0')
+                expect("':'");
+            /* new local label */
+            asm_new_label(s1, asm_get_local_label_name(s1, n), 1);
+            next();
+            skip(':');
+            goto redo;
+        } else if (tok >= TOK_IDENT) {
+            /* instruction or label */
+            opcode = tok;
+            next();
+            if (tok == ':') {
+                /* new label */
+                asm_new_label(s1, opcode, 0);
+                next();
+                goto redo;
+            } else if (tok == '=') {
+		set_symbol(s1, opcode);
+                goto redo;
+            } else {
+                asm_opcode(s1, opcode);
+            }
+        }
+        /* end of line */
+        if (tok != ';' && tok != TOK_LINEFEED)
+            expect("end of line");
+        parse_flags &= ~PARSE_FLAG_LINEFEED; /* XXX: suppress that hack */
+    }
+
+    parse_flags = saved_parse_flags;
+    return 0;
+}
+
+/* Assemble the current file */
+ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
+{
+    int ret;
+    tcc_debug_start(s1);
+    /* default section is text */
+    cur_text_section = text_section;
+    ind = cur_text_section->data_offset;
+    nocode_wanted = 0;
+    ret = tcc_assemble_internal(s1, do_preprocess, 1);
+    cur_text_section->data_offset = ind;
+    tcc_debug_end(s1);
+    return ret;
+}
+
+/********************************************************************/
+/* GCC inline asm support */
+
+/* assemble the string 'str' in the current C compilation unit without
+   C preprocessing. NOTE: str is modified by modifying the '\0' at the
+   end */
+static void tcc_assemble_inline(TCCState *s1, char *str, int len, int global)
+{
+    const int *saved_macro_ptr = macro_ptr;
+    int dotid = set_idnum('.', IS_ID);
+
+    tcc_open_bf(s1, ":asm:", len);
+    memcpy(file->buffer, str, len);
+    macro_ptr = NULL;
+    tcc_assemble_internal(s1, 0, global);
+    tcc_close();
+
+    set_idnum('.', dotid);
+    macro_ptr = saved_macro_ptr;
+}
+
+/* find a constraint by its number or id (gcc 3 extended
+   syntax). return -1 if not found. Return in *pp in char after the
+   constraint */
+ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, 
+                           const char *name, const char **pp)
+{
+    int index;
+    TokenSym *ts;
+    const char *p;
+
+    if (isnum(*name)) {
+        index = 0;
+        while (isnum(*name)) {
+            index = (index * 10) + (*name) - '0';
+            name++;
+        }
+        if ((unsigned)index >= nb_operands)
+            index = -1;
+    } else if (*name == '[') {
+        name++;
+        p = strchr(name, ']');
+        if (p) {
+            ts = tok_alloc(name, p - name);
+            for(index = 0; index < nb_operands; index++) {
+                if (operands[index].id == ts->tok)
+                    goto found;
+            }
+            index = -1;
+        found:
+            name = p + 1;
+        } else {
+            index = -1;
+        }
+    } else {
+        index = -1;
+    }
+    if (pp)
+        *pp = name;
+    return index;
+}
+
+static void subst_asm_operands(ASMOperand *operands, int nb_operands, 
+                               CString *out_str, CString *in_str)
+{
+    int c, index, modifier;
+    const char *str;
+    ASMOperand *op;
+    SValue sv;
+
+    cstr_new(out_str);
+    str = in_str->data;
+    for(;;) {
+        c = *str++;
+        if (c == '%') {
+            if (*str == '%') {
+                str++;
+                goto add_char;
+            }
+            modifier = 0;
+            if (*str == 'c' || *str == 'n' ||
+                *str == 'b' || *str == 'w' || *str == 'h' || *str == 'k' ||
+		*str == 'q' ||
+		/* P in GCC would add "@PLT" to symbol refs in PIC mode,
+		   and make literal operands not be decorated with '$'.  */
+		*str == 'P')
+                modifier = *str++;
+            index = find_constraint(operands, nb_operands, str, &str);
+            if (index < 0)
+                tcc_error("invalid operand reference after %%");
+            op = &operands[index];
+            sv = *op->vt;
+            if (op->reg >= 0) {
+                sv.r = op->reg;
+                if ((op->vt->r & VT_VALMASK) == VT_LLOCAL && op->is_memory)
+                    sv.r |= VT_LVAL;
+            }
+            subst_asm_operand(out_str, &sv, modifier);
+        } else {
+        add_char:
+            cstr_ccat(out_str, c);
+            if (c == '\0')
+                break;
+        }
+    }
+}
+
+
+static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr,
+                               int is_output)
+{
+    ASMOperand *op;
+    int nb_operands;
+
+    if (tok != ':') {
+        nb_operands = *nb_operands_ptr;
+        for(;;) {
+	    CString astr;
+            if (nb_operands >= MAX_ASM_OPERANDS)
+                tcc_error("too many asm operands");
+            op = &operands[nb_operands++];
+            op->id = 0;
+            if (tok == '[') {
+                next();
+                if (tok < TOK_IDENT)
+                    expect("identifier");
+                op->id = tok;
+                next();
+                skip(']');
+            }
+	    parse_mult_str(&astr, "string constant");
+            op->constraint = tcc_malloc(astr.size);
+            strcpy(op->constraint, astr.data);
+	    cstr_free(&astr);
+            skip('(');
+            gexpr();
+            if (is_output) {
+                if (!(vtop->type.t & VT_ARRAY))
+                    test_lvalue();
+            } else {
+                /* we want to avoid LLOCAL case, except when the 'm'
+                   constraint is used. Note that it may come from
+                   register storage, so we need to convert (reg)
+                   case */
+                if ((vtop->r & VT_LVAL) &&
+                    ((vtop->r & VT_VALMASK) == VT_LLOCAL ||
+                     (vtop->r & VT_VALMASK) < VT_CONST) &&
+                    !strchr(op->constraint, 'm')) {
+                    gv(RC_INT);
+                }
+            }
+            op->vt = vtop;
+            skip(')');
+            if (tok == ',') {
+                next();
+            } else {
+                break;
+            }
+        }
+        *nb_operands_ptr = nb_operands;
+    }
+}
+
+/* parse the GCC asm() instruction */
+ST_FUNC void asm_instr(void)
+{
+    CString astr, astr1;
+    ASMOperand operands[MAX_ASM_OPERANDS];
+    int nb_outputs, nb_operands, i, must_subst, out_reg;
+    uint8_t clobber_regs[NB_ASM_REGS];
+
+    next();
+    /* since we always generate the asm() instruction, we can ignore
+       volatile */
+    if (tok == TOK_VOLATILE1 || tok == TOK_VOLATILE2 || tok == TOK_VOLATILE3) {
+        next();
+    }
+    parse_asm_str(&astr);
+    nb_operands = 0;
+    nb_outputs = 0;
+    must_subst = 0;
+    memset(clobber_regs, 0, sizeof(clobber_regs));
+    if (tok == ':') {
+        next();
+        must_subst = 1;
+        /* output args */
+        parse_asm_operands(operands, &nb_operands, 1);
+        nb_outputs = nb_operands;
+        if (tok == ':') {
+            next();
+            if (tok != ')') {
+                /* input args */
+                parse_asm_operands(operands, &nb_operands, 0);
+                if (tok == ':') {
+                    /* clobber list */
+                    /* XXX: handle registers */
+                    next();
+                    for(;;) {
+                        if (tok != TOK_STR)
+                            expect("string constant");
+                        asm_clobber(clobber_regs, tokc.str.data);
+                        next();
+                        if (tok == ',') {
+                            next();
+                        } else {
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    skip(')');
+    /* NOTE: we do not eat the ';' so that we can restore the current
+       token after the assembler parsing */
+    if (tok != ';')
+        expect("';'");
+    
+    /* save all values in the memory */
+    save_regs(0);
+
+    /* compute constraints */
+    asm_compute_constraints(operands, nb_operands, nb_outputs, 
+                            clobber_regs, &out_reg);
+
+    /* substitute the operands in the asm string. No substitution is
+       done if no operands (GCC behaviour) */
+#ifdef ASM_DEBUG
+    printf("asm: \"%s\"\n", (char *)astr.data);
+#endif
+    if (must_subst) {
+        subst_asm_operands(operands, nb_operands, &astr1, &astr);
+        cstr_free(&astr);
+    } else {
+        astr1 = astr;
+    }
+#ifdef ASM_DEBUG
+    printf("subst_asm: \"%s\"\n", (char *)astr1.data);
+#endif
+
+    /* generate loads */
+    asm_gen_code(operands, nb_operands, nb_outputs, 0, 
+                 clobber_regs, out_reg);    
+
+    /* assemble the string with tcc internal assembler */
+    tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1, 0);
+
+    /* restore the current C token */
+    next();
+
+    /* store the output values if needed */
+    asm_gen_code(operands, nb_operands, nb_outputs, 1, 
+                 clobber_regs, out_reg);
+    
+    /* free everything */
+    for(i=0;i<nb_operands;i++) {
+        ASMOperand *op;
+        op = &operands[i];
+        tcc_free(op->constraint);
+        vpop();
+    }
+    cstr_free(&astr1);
+}
+
+ST_FUNC void asm_global_instr(void)
+{
+    CString astr;
+    int saved_nocode_wanted = nocode_wanted;
+
+    /* Global asm blocks are always emitted.  */
+    nocode_wanted = 0;
+    next();
+    parse_asm_str(&astr);
+    skip(')');
+    /* NOTE: we do not eat the ';' so that we can restore the current
+       token after the assembler parsing */
+    if (tok != ';')
+        expect("';'");
+    
+#ifdef ASM_DEBUG
+    printf("asm_global: \"%s\"\n", (char *)astr.data);
+#endif
+    cur_text_section = text_section;
+    ind = cur_text_section->data_offset;
+
+    /* assemble the string with tcc internal assembler */
+    tcc_assemble_inline(tcc_state, astr.data, astr.size - 1, 1);
+    
+    cur_text_section->data_offset = ind;
+
+    /* restore the current C token */
+    next();
+
+    cstr_free(&astr);
+    nocode_wanted = saved_nocode_wanted;
+}
+#endif /* CONFIG_TCC_ASM */
Index: EcnlProtoTool/trunk/tcc-0.9.27/tcccoff.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tcccoff.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tcccoff.c	(revision 331)
@@ -0,0 +1,948 @@
+/*
+ *  COFF file handling for TCC
+ * 
+ *  Copyright (c) 2003, 2004 TK
+ *  Copyright (c) 2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "tcc.h"
+
+#define MAXNSCNS 255		/* MAXIMUM NUMBER OF SECTIONS         */
+#define MAX_STR_TABLE 1000000
+AOUTHDR o_filehdr;		/* OPTIONAL (A.OUT) FILE HEADER       */
+
+SCNHDR section_header[MAXNSCNS];
+
+#define MAX_FUNCS 1000
+#define MAX_FUNC_NAME_LENGTH 128
+
+int nFuncs;
+char Func[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
+char AssociatedFile[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
+int LineNoFilePtr[MAX_FUNCS];
+int EndAddress[MAX_FUNCS];
+int LastLineNo[MAX_FUNCS];
+int FuncEntries[MAX_FUNCS];
+
+int OutputTheSection(Section * sect);
+short int GetCoffFlags(const char *s);
+void SortSymbolTable(void);
+Section *FindSection(TCCState * s1, const char *sname);
+
+int C67_main_entry_point;
+
+int FindCoffSymbolIndex(const char *func_name);
+int nb_syms;
+
+typedef struct {
+    long tag;
+    long size;
+    long fileptr;
+    long nextsym;
+    short int dummy;
+} AUXFUNC;
+
+typedef struct {
+    long regmask;
+    unsigned short lineno;
+    unsigned short nentries;
+    int localframe;
+    int nextentry;
+    short int dummy;
+} AUXBF;
+
+typedef struct {
+    long dummy;
+    unsigned short lineno;
+    unsigned short dummy1;
+    int dummy2;
+    int dummy3;
+    unsigned short dummy4;
+} AUXEF;
+
+ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
+{
+    Section *tcc_sect;
+    SCNHDR *coff_sec;
+    int file_pointer;
+    char *Coff_str_table, *pCoff_str_table;
+    int CoffTextSectionNo, coff_nb_syms;
+    FILHDR file_hdr;		/* FILE HEADER STRUCTURE              */
+    Section *stext, *sdata, *sbss;
+    int i, NSectionsToOutput = 0;
+
+    Coff_str_table = pCoff_str_table = NULL;
+
+    stext = FindSection(s1, ".text");
+    sdata = FindSection(s1, ".data");
+    sbss = FindSection(s1, ".bss");
+
+    nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
+    coff_nb_syms = FindCoffSymbolIndex("XXXXXXXXXX1");
+
+    file_hdr.f_magic = COFF_C67_MAGIC;	/* magic number */
+    file_hdr.f_timdat = 0;	/* time & date stamp */
+    file_hdr.f_opthdr = sizeof(AOUTHDR);	/* sizeof(optional hdr) */
+    file_hdr.f_flags = 0x1143;	/* flags (copied from what code composer does) */
+    file_hdr.f_TargetID = 0x99;	/* for C6x = 0x0099 */
+
+    o_filehdr.magic = 0x0108;	/* see magic.h                          */
+    o_filehdr.vstamp = 0x0190;	/* version stamp                        */
+    o_filehdr.tsize = stext->data_offset;	/* text size in bytes, padded to FW bdry */
+    o_filehdr.dsize = sdata->data_offset;	/* initialized data "  "                */
+    o_filehdr.bsize = sbss->data_offset;	/* uninitialized data "   "             */
+    o_filehdr.entrypt = C67_main_entry_point;	/* entry pt.                          */
+    o_filehdr.text_start = stext->sh_addr;	/* base of text used for this file      */
+    o_filehdr.data_start = sdata->sh_addr;	/* base of data used for this file      */
+
+
+    // create all the section headers
+
+    file_pointer = FILHSZ + sizeof(AOUTHDR);
+
+    CoffTextSectionNo = -1;
+
+    for (i = 1; i < s1->nb_sections; i++) {
+	coff_sec = &section_header[i];
+	tcc_sect = s1->sections[i];
+
+	if (OutputTheSection(tcc_sect)) {
+	    NSectionsToOutput++;
+
+	    if (CoffTextSectionNo == -1 && tcc_sect == stext)
+		CoffTextSectionNo = NSectionsToOutput;	// rem which coff sect number the .text sect is
+
+	    strcpy(coff_sec->s_name, tcc_sect->name);	/* section name */
+
+	    coff_sec->s_paddr = tcc_sect->sh_addr;	/* physical address */
+	    coff_sec->s_vaddr = tcc_sect->sh_addr;	/* virtual address */
+	    coff_sec->s_size = tcc_sect->data_offset;	/* section size */
+	    coff_sec->s_scnptr = 0;	/* file ptr to raw data for section */
+	    coff_sec->s_relptr = 0;	/* file ptr to relocation */
+	    coff_sec->s_lnnoptr = 0;	/* file ptr to line numbers */
+	    coff_sec->s_nreloc = 0;	/* number of relocation entries */
+	    coff_sec->s_flags = GetCoffFlags(coff_sec->s_name);	/* flags */
+	    coff_sec->s_reserved = 0;	/* reserved byte */
+	    coff_sec->s_page = 0;	/* memory page id */
+
+	    file_pointer += sizeof(SCNHDR);
+	}
+    }
+
+    file_hdr.f_nscns = NSectionsToOutput;	/* number of sections */
+
+    // now loop through and determine file pointer locations
+    // for the raw data
+
+
+    for (i = 1; i < s1->nb_sections; i++) {
+	coff_sec = &section_header[i];
+	tcc_sect = s1->sections[i];
+
+	if (OutputTheSection(tcc_sect)) {
+	    // put raw data
+	    coff_sec->s_scnptr = file_pointer;	/* file ptr to raw data for section */
+	    file_pointer += coff_sec->s_size;
+	}
+    }
+
+    // now loop through and determine file pointer locations
+    // for the relocation data
+
+    for (i = 1; i < s1->nb_sections; i++) {
+	coff_sec = &section_header[i];
+	tcc_sect = s1->sections[i];
+
+	if (OutputTheSection(tcc_sect)) {
+	    // put relocations data
+	    if (coff_sec->s_nreloc > 0) {
+		coff_sec->s_relptr = file_pointer;	/* file ptr to relocation */
+		file_pointer += coff_sec->s_nreloc * sizeof(struct reloc);
+	    }
+	}
+    }
+
+    // now loop through and determine file pointer locations
+    // for the line number data
+
+    for (i = 1; i < s1->nb_sections; i++) {
+	coff_sec = &section_header[i];
+	tcc_sect = s1->sections[i];
+
+	coff_sec->s_nlnno = 0;
+	coff_sec->s_lnnoptr = 0;
+
+	if (s1->do_debug && tcc_sect == stext) {
+	    // count how many line nos data
+
+	    // also find association between source file name and function
+	    // so we can sort the symbol table
+
+
+	    Stab_Sym *sym, *sym_end;
+	    char func_name[MAX_FUNC_NAME_LENGTH],
+		last_func_name[MAX_FUNC_NAME_LENGTH];
+	    unsigned long func_addr, last_pc, pc;
+	    const char *incl_files[INCLUDE_STACK_SIZE];
+	    int incl_index, len, last_line_num;
+	    const char *str, *p;
+
+	    coff_sec->s_lnnoptr = file_pointer;	/* file ptr to linno */
+
+
+	    func_name[0] = '\0';
+	    func_addr = 0;
+	    incl_index = 0;
+	    last_func_name[0] = '\0';
+	    last_pc = 0xffffffff;
+	    last_line_num = 1;
+	    sym = (Stab_Sym *) stab_section->data + 1;
+	    sym_end =
+		(Stab_Sym *) (stab_section->data +
+			      stab_section->data_offset);
+
+	    nFuncs = 0;
+	    while (sym < sym_end) {
+		switch (sym->n_type) {
+		    /* function start or end */
+		case N_FUN:
+		    if (sym->n_strx == 0) {
+			// end of function
+
+			coff_sec->s_nlnno++;
+			file_pointer += LINESZ;
+
+			pc = sym->n_value + func_addr;
+			func_name[0] = '\0';
+			func_addr = 0;
+			EndAddress[nFuncs] = pc;
+			FuncEntries[nFuncs] =
+			    (file_pointer -
+			     LineNoFilePtr[nFuncs]) / LINESZ - 1;
+			LastLineNo[nFuncs++] = last_line_num + 1;
+		    } else {
+			// beginning of function
+
+			LineNoFilePtr[nFuncs] = file_pointer;
+			coff_sec->s_nlnno++;
+			file_pointer += LINESZ;
+
+			str =
+			    (const char *) stabstr_section->data +
+			    sym->n_strx;
+
+			p = strchr(str, ':');
+			if (!p) {
+			    pstrcpy(func_name, sizeof(func_name), str);
+			    pstrcpy(Func[nFuncs], sizeof(func_name), str);
+			} else {
+			    len = p - str;
+			    if (len > sizeof(func_name) - 1)
+				len = sizeof(func_name) - 1;
+			    memcpy(func_name, str, len);
+			    memcpy(Func[nFuncs], str, len);
+			    func_name[len] = '\0';
+			}
+
+			// save the file that it came in so we can sort later
+			pstrcpy(AssociatedFile[nFuncs], sizeof(func_name),
+				incl_files[incl_index - 1]);
+
+			func_addr = sym->n_value;
+		    }
+		    break;
+
+		    /* line number info */
+		case N_SLINE:
+		    pc = sym->n_value + func_addr;
+
+		    last_pc = pc;
+		    last_line_num = sym->n_desc;
+
+		    /* XXX: slow! */
+		    strcpy(last_func_name, func_name);
+
+		    coff_sec->s_nlnno++;
+		    file_pointer += LINESZ;
+		    break;
+		    /* include files */
+		case N_BINCL:
+		    str =
+			(const char *) stabstr_section->data + sym->n_strx;
+		  add_incl:
+		    if (incl_index < INCLUDE_STACK_SIZE) {
+			incl_files[incl_index++] = str;
+		    }
+		    break;
+		case N_EINCL:
+		    if (incl_index > 1)
+			incl_index--;
+		    break;
+		case N_SO:
+		    if (sym->n_strx == 0) {
+			incl_index = 0;	/* end of translation unit */
+		    } else {
+			str =
+			    (const char *) stabstr_section->data +
+			    sym->n_strx;
+			/* do not add path */
+			len = strlen(str);
+			if (len > 0 && str[len - 1] != '/')
+			    goto add_incl;
+		    }
+		    break;
+		}
+		sym++;
+	    }
+	}
+
+    }
+
+    file_hdr.f_symptr = file_pointer;	/* file pointer to symtab */
+
+    if (s1->do_debug)
+	file_hdr.f_nsyms = coff_nb_syms;	/* number of symtab entries */
+    else
+	file_hdr.f_nsyms = 0;
+
+    file_pointer += file_hdr.f_nsyms * SYMNMLEN;
+
+    // OK now we are all set to write the file
+
+
+    fwrite(&file_hdr, FILHSZ, 1, f);
+    fwrite(&o_filehdr, sizeof(o_filehdr), 1, f);
+
+    // write section headers
+    for (i = 1; i < s1->nb_sections; i++) {
+	coff_sec = &section_header[i];
+	tcc_sect = s1->sections[i];
+
+	if (OutputTheSection(tcc_sect)) {
+	    fwrite(coff_sec, sizeof(SCNHDR), 1, f);
+	}
+    }
+
+    // write raw data
+    for (i = 1; i < s1->nb_sections; i++) {
+	coff_sec = &section_header[i];
+	tcc_sect = s1->sections[i];
+
+	if (OutputTheSection(tcc_sect)) {
+	    fwrite(tcc_sect->data, tcc_sect->data_offset, 1, f);
+	}
+    }
+
+    // write relocation data
+    for (i = 1; i < s1->nb_sections; i++) {
+	coff_sec = &section_header[i];
+	tcc_sect = s1->sections[i];
+
+	if (OutputTheSection(tcc_sect)) {
+	    // put relocations data
+	    if (coff_sec->s_nreloc > 0) {
+		fwrite(tcc_sect->reloc,
+		       coff_sec->s_nreloc * sizeof(struct reloc), 1, f);
+	    }
+	}
+    }
+
+
+    // group the symbols in order of filename, func1, func2, etc
+    // finally global symbols
+
+    if (s1->do_debug)
+	SortSymbolTable();
+
+    // write line no data
+
+    for (i = 1; i < s1->nb_sections; i++) {
+	coff_sec = &section_header[i];
+	tcc_sect = s1->sections[i];
+
+	if (s1->do_debug && tcc_sect == stext) {
+	    // count how many line nos data
+
+
+	    Stab_Sym *sym, *sym_end;
+	    char func_name[128], last_func_name[128];
+	    unsigned long func_addr, last_pc, pc;
+	    const char *incl_files[INCLUDE_STACK_SIZE];
+	    int incl_index, len, last_line_num;
+	    const char *str, *p;
+
+	    LINENO CoffLineNo;
+
+	    func_name[0] = '\0';
+	    func_addr = 0;
+	    incl_index = 0;
+	    last_func_name[0] = '\0';
+	    last_pc = 0;
+	    last_line_num = 1;
+	    sym = (Stab_Sym *) stab_section->data + 1;
+	    sym_end =
+		(Stab_Sym *) (stab_section->data +
+			      stab_section->data_offset);
+
+	    while (sym < sym_end) {
+		switch (sym->n_type) {
+		    /* function start or end */
+		case N_FUN:
+		    if (sym->n_strx == 0) {
+			// end of function
+
+			CoffLineNo.l_addr.l_paddr = last_pc;
+			CoffLineNo.l_lnno = last_line_num + 1;
+			fwrite(&CoffLineNo, 6, 1, f);
+
+			pc = sym->n_value + func_addr;
+			func_name[0] = '\0';
+			func_addr = 0;
+		    } else {
+			// beginning of function
+
+			str =
+			    (const char *) stabstr_section->data +
+			    sym->n_strx;
+
+
+			p = strchr(str, ':');
+			if (!p) {
+			    pstrcpy(func_name, sizeof(func_name), str);
+			} else {
+			    len = p - str;
+			    if (len > sizeof(func_name) - 1)
+				len = sizeof(func_name) - 1;
+			    memcpy(func_name, str, len);
+			    func_name[len] = '\0';
+			}
+			func_addr = sym->n_value;
+			last_pc = func_addr;
+			last_line_num = -1;
+
+			// output a function begin
+
+			CoffLineNo.l_addr.l_symndx =
+			    FindCoffSymbolIndex(func_name);
+			CoffLineNo.l_lnno = 0;
+
+			fwrite(&CoffLineNo, 6, 1, f);
+		    }
+		    break;
+
+		    /* line number info */
+		case N_SLINE:
+		    pc = sym->n_value + func_addr;
+
+
+		    /* XXX: slow! */
+		    strcpy(last_func_name, func_name);
+
+		    // output a line reference
+
+		    CoffLineNo.l_addr.l_paddr = last_pc;
+
+		    if (last_line_num == -1) {
+			CoffLineNo.l_lnno = sym->n_desc;
+		    } else {
+			CoffLineNo.l_lnno = last_line_num + 1;
+		    }
+
+		    fwrite(&CoffLineNo, 6, 1, f);
+
+		    last_pc = pc;
+		    last_line_num = sym->n_desc;
+
+		    break;
+
+		    /* include files */
+		case N_BINCL:
+		    str =
+			(const char *) stabstr_section->data + sym->n_strx;
+		  add_incl2:
+		    if (incl_index < INCLUDE_STACK_SIZE) {
+			incl_files[incl_index++] = str;
+		    }
+		    break;
+		case N_EINCL:
+		    if (incl_index > 1)
+			incl_index--;
+		    break;
+		case N_SO:
+		    if (sym->n_strx == 0) {
+			incl_index = 0;	/* end of translation unit */
+		    } else {
+			str =
+			    (const char *) stabstr_section->data +
+			    sym->n_strx;
+			/* do not add path */
+			len = strlen(str);
+			if (len > 0 && str[len - 1] != '/')
+			    goto add_incl2;
+		    }
+		    break;
+		}
+		sym++;
+	    }
+	}
+    }
+
+    // write symbol table
+    if (s1->do_debug) {
+	int k;
+	struct syment csym;
+	AUXFUNC auxfunc;
+	AUXBF auxbf;
+	AUXEF auxef;
+	int i;
+	Elf32_Sym *p;
+	const char *name;
+	int nstr;
+	int n = 0;
+
+	Coff_str_table = (char *) tcc_malloc(MAX_STR_TABLE);
+	pCoff_str_table = Coff_str_table;
+	nstr = 0;
+
+	p = (Elf32_Sym *) symtab_section->data;
+
+
+	for (i = 0; i < nb_syms; i++) {
+
+	    name = symtab_section->link->data + p->st_name;
+
+	    for (k = 0; k < 8; k++)
+		csym._n._n_name[k] = 0;
+
+	    if (strlen(name) <= 8) {
+		strcpy(csym._n._n_name, name);
+	    } else {
+		if (pCoff_str_table - Coff_str_table + strlen(name) >
+		    MAX_STR_TABLE - 1)
+		    tcc_error("String table too large");
+
+		csym._n._n_n._n_zeroes = 0;
+		csym._n._n_n._n_offset =
+		    pCoff_str_table - Coff_str_table + 4;
+
+		strcpy(pCoff_str_table, name);
+		pCoff_str_table += strlen(name) + 1;	// skip over null
+		nstr++;
+	    }
+
+	    if (p->st_info == 4) {
+		// put a filename symbol
+		csym.n_value = 33;	// ?????
+		csym.n_scnum = N_DEBUG;
+		csym.n_type = 0;
+		csym.n_sclass = C_FILE;
+		csym.n_numaux = 0;
+		fwrite(&csym, 18, 1, f);
+		n++;
+
+	    } else if (p->st_info == 0x12) {
+		// find the function data
+
+		for (k = 0; k < nFuncs; k++) {
+		    if (strcmp(name, Func[k]) == 0)
+			break;
+		}
+
+		if (k >= nFuncs) {
+		    tcc_error("debug info can't find function: %s", name);
+		}
+		// put a Function Name
+
+		csym.n_value = p->st_value;	// physical address
+		csym.n_scnum = CoffTextSectionNo;
+		csym.n_type = MKTYPE(T_INT, DT_FCN, 0, 0, 0, 0, 0);
+		csym.n_sclass = C_EXT;
+		csym.n_numaux = 1;
+		fwrite(&csym, 18, 1, f);
+
+		// now put aux info
+
+		auxfunc.tag = 0;
+		auxfunc.size = EndAddress[k] - p->st_value;
+		auxfunc.fileptr = LineNoFilePtr[k];
+		auxfunc.nextsym = n + 6;	// tktk
+		auxfunc.dummy = 0;
+		fwrite(&auxfunc, 18, 1, f);
+
+		// put a .bf
+
+		strcpy(csym._n._n_name, ".bf");
+		csym.n_value = p->st_value;	// physical address
+		csym.n_scnum = CoffTextSectionNo;
+		csym.n_type = 0;
+		csym.n_sclass = C_FCN;
+		csym.n_numaux = 1;
+		fwrite(&csym, 18, 1, f);
+
+		// now put aux info
+
+		auxbf.regmask = 0;
+		auxbf.lineno = 0;
+		auxbf.nentries = FuncEntries[k];
+		auxbf.localframe = 0;
+		auxbf.nextentry = n + 6;
+		auxbf.dummy = 0;
+		fwrite(&auxbf, 18, 1, f);
+
+		// put a .ef
+
+		strcpy(csym._n._n_name, ".ef");
+		csym.n_value = EndAddress[k];	// physical address  
+		csym.n_scnum = CoffTextSectionNo;
+		csym.n_type = 0;
+		csym.n_sclass = C_FCN;
+		csym.n_numaux = 1;
+		fwrite(&csym, 18, 1, f);
+
+		// now put aux info
+
+		auxef.dummy = 0;
+		auxef.lineno = LastLineNo[k];
+		auxef.dummy1 = 0;
+		auxef.dummy2 = 0;
+		auxef.dummy3 = 0;
+		auxef.dummy4 = 0;
+		fwrite(&auxef, 18, 1, f);
+
+		n += 6;
+
+	    } else {
+		// try an put some type info
+
+		if ((p->st_other & VT_BTYPE) == VT_DOUBLE) {
+		    csym.n_type = T_DOUBLE;	// int
+		    csym.n_sclass = C_EXT;
+		} else if ((p->st_other & VT_BTYPE) == VT_FLOAT) {
+		    csym.n_type = T_FLOAT;
+		    csym.n_sclass = C_EXT;
+		} else if ((p->st_other & VT_BTYPE) == VT_INT) {
+		    csym.n_type = T_INT;	// int
+		    csym.n_sclass = C_EXT;
+		} else if ((p->st_other & VT_BTYPE) == VT_SHORT) {
+		    csym.n_type = T_SHORT;
+		    csym.n_sclass = C_EXT;
+		} else if ((p->st_other & VT_BTYPE) == VT_BYTE) {
+		    csym.n_type = T_CHAR;
+		    csym.n_sclass = C_EXT;
+		} else {
+		    csym.n_type = T_INT;	// just mark as a label
+		    csym.n_sclass = C_LABEL;
+		}
+
+
+		csym.n_value = p->st_value;
+		csym.n_scnum = 2;
+		csym.n_numaux = 1;
+		fwrite(&csym, 18, 1, f);
+
+		auxfunc.tag = 0;
+		auxfunc.size = 0x20;
+		auxfunc.fileptr = 0;
+		auxfunc.nextsym = 0;
+		auxfunc.dummy = 0;
+		fwrite(&auxfunc, 18, 1, f);
+		n++;
+		n++;
+
+	    }
+
+	    p++;
+	}
+    }
+
+    if (s1->do_debug) {
+	// write string table
+
+	// first write the size
+	i = pCoff_str_table - Coff_str_table;
+	fwrite(&i, 4, 1, f);
+
+	// then write the strings
+	fwrite(Coff_str_table, i, 1, f);
+
+	tcc_free(Coff_str_table);
+    }
+
+    return 0;
+}
+
+
+
+// group the symbols in order of filename, func1, func2, etc
+// finally global symbols
+
+void SortSymbolTable(void)
+{
+    int i, j, k, n = 0;
+    Elf32_Sym *p, *p2, *NewTable;
+    char *name, *name2;
+
+    NewTable = (Elf32_Sym *) tcc_malloc(nb_syms * sizeof(Elf32_Sym));
+
+    p = (Elf32_Sym *) symtab_section->data;
+
+
+    // find a file symbol, copy it over
+    // then scan the whole symbol list and copy any function
+    // symbols that match the file association
+
+    for (i = 0; i < nb_syms; i++) {
+	if (p->st_info == 4) {
+	    name = (char *) symtab_section->link->data + p->st_name;
+
+	    // this is a file symbol, copy it over
+
+	    NewTable[n++] = *p;
+
+	    p2 = (Elf32_Sym *) symtab_section->data;
+
+	    for (j = 0; j < nb_syms; j++) {
+		if (p2->st_info == 0x12) {
+		    // this is a func symbol
+
+		    name2 =
+			(char *) symtab_section->link->data + p2->st_name;
+
+		    // find the function data index
+
+		    for (k = 0; k < nFuncs; k++) {
+			if (strcmp(name2, Func[k]) == 0)
+			    break;
+		    }
+
+		    if (k >= nFuncs) {
+                        tcc_error("debug (sort) info can't find function: %s", name2);
+		    }
+
+		    if (strcmp(AssociatedFile[k], name) == 0) {
+			// yes they match copy it over
+
+			NewTable[n++] = *p2;
+		    }
+		}
+		p2++;
+	    }
+	}
+	p++;
+    }
+
+    // now all the filename and func symbols should have been copied over
+    // copy all the rest over (all except file and funcs)
+
+    p = (Elf32_Sym *) symtab_section->data;
+    for (i = 0; i < nb_syms; i++) {
+	if (p->st_info != 4 && p->st_info != 0x12) {
+	    NewTable[n++] = *p;
+	}
+	p++;
+    }
+
+    if (n != nb_syms)
+	tcc_error("Internal Compiler error, debug info");
+
+    // copy it all back
+
+    p = (Elf32_Sym *) symtab_section->data;
+    for (i = 0; i < nb_syms; i++) {
+	*p++ = NewTable[i];
+    }
+
+    tcc_free(NewTable);
+}
+
+
+int FindCoffSymbolIndex(const char *func_name)
+{
+    int i, n = 0;
+    Elf32_Sym *p;
+    char *name;
+
+    p = (Elf32_Sym *) symtab_section->data;
+
+    for (i = 0; i < nb_syms; i++) {
+
+	name = (char *) symtab_section->link->data + p->st_name;
+
+	if (p->st_info == 4) {
+	    // put a filename symbol
+	    n++;
+	} else if (p->st_info == 0x12) {
+
+	    if (strcmp(func_name, name) == 0)
+		return n;
+
+	    n += 6;
+
+	    // put a Function Name
+
+	    // now put aux info
+
+	    // put a .bf
+
+	    // now put aux info
+
+	    // put a .ef
+
+	    // now put aux info
+
+	} else {
+	    n += 2;
+	}
+
+	p++;
+    }
+
+    return n;			// total number of symbols
+}
+
+int OutputTheSection(Section * sect)
+{
+    const char *s = sect->name;
+
+    if (!strcmp(s, ".text"))
+	return 1;
+    else if (!strcmp(s, ".data"))
+	return 1;
+    else
+	return 0;
+}
+
+short int GetCoffFlags(const char *s)
+{
+    if (!strcmp(s, ".text"))
+	return STYP_TEXT | STYP_DATA | STYP_ALIGN | 0x400;
+    else if (!strcmp(s, ".data"))
+	return STYP_DATA;
+    else if (!strcmp(s, ".bss"))
+	return STYP_BSS;
+    else if (!strcmp(s, ".stack"))
+	return STYP_BSS | STYP_ALIGN | 0x200;
+    else if (!strcmp(s, ".cinit"))
+	return STYP_COPY | STYP_DATA | STYP_ALIGN | 0x200;
+    else
+	return 0;
+}
+
+Section *FindSection(TCCState * s1, const char *sname)
+{
+    Section *s;
+    int i;
+
+    for (i = 1; i < s1->nb_sections; i++) {
+	s = s1->sections[i];
+
+	if (!strcmp(sname, s->name))
+	    return s;
+    }
+
+    tcc_error("could not find section %s", sname);
+    return 0;
+}
+
+ST_FUNC int tcc_load_coff(TCCState * s1, int fd)
+{
+// tktk TokenSym *ts;
+
+    FILE *f;
+    unsigned int str_size;
+    char *Coff_str_table, *name;
+    int i, k;
+    struct syment csym;
+    char name2[9];
+    FILHDR file_hdr;		/* FILE HEADER STRUCTURE              */
+
+    f = fdopen(fd, "rb");
+    if (!f) {
+	tcc_error("Unable to open .out file for input");
+    }
+
+    if (fread(&file_hdr, FILHSZ, 1, f) != 1)
+	tcc_error("error reading .out file for input");
+
+    if (fread(&o_filehdr, sizeof(o_filehdr), 1, f) != 1)
+	tcc_error("error reading .out file for input");
+
+    // first read the string table
+
+    if (fseek(f, file_hdr.f_symptr + file_hdr.f_nsyms * SYMESZ, SEEK_SET))
+	tcc_error("error reading .out file for input");
+
+    if (fread(&str_size, sizeof(int), 1, f) != 1)
+	tcc_error("error reading .out file for input");
+
+
+    Coff_str_table = (char *) tcc_malloc(str_size);
+
+    if (fread(Coff_str_table, str_size - 4, 1, f) != 1)
+	tcc_error("error reading .out file for input");
+
+    // read/process all the symbols
+
+    // seek back to symbols
+
+    if (fseek(f, file_hdr.f_symptr, SEEK_SET))
+	tcc_error("error reading .out file for input");
+
+    for (i = 0; i < file_hdr.f_nsyms; i++) {
+	if (fread(&csym, SYMESZ, 1, f) != 1)
+	    tcc_error("error reading .out file for input");
+
+	if (csym._n._n_n._n_zeroes == 0) {
+	    name = Coff_str_table + csym._n._n_n._n_offset - 4;
+	} else {
+	    name = csym._n._n_name;
+
+	    if (name[7] != 0) {
+		for (k = 0; k < 8; k++)
+		    name2[k] = name[k];
+
+		name2[8] = 0;
+
+		name = name2;
+	    }
+	}
+//              if (strcmp("_DAC_Buffer",name)==0)  // tktk
+//                      name[0]=0;
+
+	if (((csym.n_type & 0x30) == 0x20 && csym.n_sclass == 0x2) || ((csym.n_type & 0x30) == 0x30 && csym.n_sclass == 0x2) || (csym.n_type == 0x4 && csym.n_sclass == 0x2) || (csym.n_type == 0x8 && csym.n_sclass == 0x2) ||	// structures
+	    (csym.n_type == 0x18 && csym.n_sclass == 0x2) ||	// pointer to structure
+	    (csym.n_type == 0x7 && csym.n_sclass == 0x2) ||	// doubles
+	    (csym.n_type == 0x6 && csym.n_sclass == 0x2))	// floats
+	{
+	    // strip off any leading underscore (except for other main routine)
+
+	    if (name[0] == '_' && strcmp(name, "_main") != 0)
+		name++;
+
+	    tcc_add_symbol(s1, name, (void*)(uintptr_t)csym.n_value);
+	}
+	// skip any aux records
+
+	if (csym.n_numaux == 1) {
+	    if (fread(&csym, SYMESZ, 1, f) != 1)
+		tcc_error("error reading .out file for input");
+	    i++;
+	}
+    }
+
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tccelf.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tccelf.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tccelf.c	(revision 331)
@@ -0,0 +1,3058 @@
+/*
+ *  ELF file handling for TCC
+ *
+ *  Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "tcc.h"
+
+/* Define this to get some debug output during relocation processing.  */
+#undef DEBUG_RELOC
+
+/********************************************************/
+/* global variables */
+
+ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
+ST_DATA Section *common_section;
+ST_DATA Section *cur_text_section; /* current section where function code is generated */
+#ifdef CONFIG_TCC_ASM
+ST_DATA Section *last_text_section; /* to handle .previous asm directive */
+#endif
+#ifdef CONFIG_TCC_BCHECK
+/* bound check related sections */
+ST_DATA Section *bounds_section; /* contains global data bound description */
+ST_DATA Section *lbounds_section; /* contains local data bound description */
+#endif
+/* symbol sections */
+ST_DATA Section *symtab_section;
+/* debug sections */
+ST_DATA Section *stab_section, *stabstr_section;
+
+/* XXX: avoid static variable */
+static int new_undef_sym = 0; /* Is there a new undefined sym since last new_undef_sym() */
+
+/* special flag to indicate that the section should not be linked to the other ones */
+#define SHF_PRIVATE 0x80000000
+/* section is dynsymtab_section */
+#define SHF_DYNSYM 0x40000000
+
+/* ------------------------------------------------------------------------- */
+
+ST_FUNC void tccelf_new(TCCState *s)
+{
+    /* no section zero */
+    dynarray_add(&s->sections, &s->nb_sections, NULL);
+
+    /* create standard sections */
+    text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
+    data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
+    bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
+    common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
+    common_section->sh_num = SHN_COMMON;
+
+    /* symbols are always generated for linking stage */
+    symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
+                                ".strtab",
+                                ".hashtab", SHF_PRIVATE);
+    s->symtab = symtab_section;
+
+    /* private symbol table for dynamic symbols */
+    s->dynsymtab_section = new_symtab(s, ".dynsymtab", SHT_SYMTAB, SHF_PRIVATE|SHF_DYNSYM,
+                                      ".dynstrtab",
+                                      ".dynhashtab", SHF_PRIVATE);
+    get_sym_attr(s, 0, 1);
+}
+
+#ifdef CONFIG_TCC_BCHECK
+ST_FUNC void tccelf_bounds_new(TCCState *s)
+{
+    /* create bounds sections */
+    bounds_section = new_section(s, ".bounds",
+                                 SHT_PROGBITS, SHF_ALLOC);
+    lbounds_section = new_section(s, ".lbounds",
+                                  SHT_PROGBITS, SHF_ALLOC);
+}
+#endif
+
+ST_FUNC void tccelf_stab_new(TCCState *s)
+{
+    stab_section = new_section(s, ".stab", SHT_PROGBITS, 0);
+    stab_section->sh_entsize = sizeof(Stab_Sym);
+    stabstr_section = new_section(s, ".stabstr", SHT_STRTAB, 0);
+    put_elf_str(stabstr_section, "");
+    stab_section->link = stabstr_section;
+    /* put first entry */
+    put_stabs("", 0, 0, 0, 0);
+}
+
+static void free_section(Section *s)
+{
+    tcc_free(s->data);
+}
+
+ST_FUNC void tccelf_delete(TCCState *s1)
+{
+    int i;
+
+    /* free all sections */
+    for(i = 1; i < s1->nb_sections; i++)
+        free_section(s1->sections[i]);
+    dynarray_reset(&s1->sections, &s1->nb_sections);
+
+    for(i = 0; i < s1->nb_priv_sections; i++)
+        free_section(s1->priv_sections[i]);
+    dynarray_reset(&s1->priv_sections, &s1->nb_priv_sections);
+
+    /* free any loaded DLLs */
+#ifdef TCC_IS_NATIVE
+    for ( i = 0; i < s1->nb_loaded_dlls; i++) {
+        DLLReference *ref = s1->loaded_dlls[i];
+        if ( ref->handle )
+# ifdef _WIN32
+            FreeLibrary((HMODULE)ref->handle);
+# else
+            dlclose(ref->handle);
+# endif
+    }
+#endif
+    /* free loaded dlls array */
+    dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
+    tcc_free(s1->sym_attrs);
+
+    symtab_section = NULL; /* for tccrun.c:rt_printline() */
+}
+
+/* save section data state */
+ST_FUNC void tccelf_begin_file(TCCState *s1)
+{
+    Section *s; int i;
+    for (i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+        s->sh_offset = s->data_offset;
+    }
+    /* disable symbol hashing during compilation */
+    s = s1->symtab, s->reloc = s->hash, s->hash = NULL;
+#if defined TCC_TARGET_X86_64 && defined TCC_TARGET_PE
+    s1->uw_sym = 0;
+#endif
+}
+
+/* At the end of compilation, convert any UNDEF syms to global, and merge
+   with previously existing symbols */
+ST_FUNC void tccelf_end_file(TCCState *s1)
+{
+    Section *s = s1->symtab;
+    int first_sym, nb_syms, *tr, i;
+
+    first_sym = s->sh_offset / sizeof (ElfSym);
+    nb_syms = s->data_offset / sizeof (ElfSym) - first_sym;
+    s->data_offset = s->sh_offset;
+    s->link->data_offset = s->link->sh_offset;
+    s->hash = s->reloc, s->reloc = NULL;
+    tr = tcc_mallocz(nb_syms * sizeof *tr);
+
+    for (i = 0; i < nb_syms; ++i) {
+        ElfSym *sym = (ElfSym*)s->data + first_sym + i;
+        if (sym->st_shndx == SHN_UNDEF
+            && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)
+            sym->st_info = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info));
+        tr[i] = set_elf_sym(s, sym->st_value, sym->st_size, sym->st_info,
+            sym->st_other, sym->st_shndx, s->link->data + sym->st_name);
+    }
+    /* now update relocations */
+    for (i = 1; i < s1->nb_sections; i++) {
+        Section *sr = s1->sections[i];
+        if (sr->sh_type == SHT_RELX && sr->link == s) {
+            ElfW_Rel *rel = (ElfW_Rel*)(sr->data + sr->sh_offset);
+            ElfW_Rel *rel_end = (ElfW_Rel*)(sr->data + sr->data_offset);
+            for (; rel < rel_end; ++rel) {
+                int n = ELFW(R_SYM)(rel->r_info) - first_sym;
+                //if (n < 0) tcc_error("internal: invalid symbol index in relocation");
+                rel->r_info = ELFW(R_INFO)(tr[n], ELFW(R_TYPE)(rel->r_info));
+            }
+        }
+    }
+    tcc_free(tr);
+}
+
+ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags)
+{
+    Section *sec;
+
+    sec = tcc_mallocz(sizeof(Section) + strlen(name));
+    strcpy(sec->name, name);
+    sec->sh_type = sh_type;
+    sec->sh_flags = sh_flags;
+    switch(sh_type) {
+    case SHT_HASH:
+    case SHT_REL:
+    case SHT_RELA:
+    case SHT_DYNSYM:
+    case SHT_SYMTAB:
+    case SHT_DYNAMIC:
+        sec->sh_addralign = 4;
+        break;
+    case SHT_STRTAB:
+        sec->sh_addralign = 1;
+        break;
+    default:
+        sec->sh_addralign =  PTR_SIZE; /* gcc/pcc default alignment */
+        break;
+    }
+
+    if (sh_flags & SHF_PRIVATE) {
+        dynarray_add(&s1->priv_sections, &s1->nb_priv_sections, sec);
+    } else {
+        sec->sh_num = s1->nb_sections;
+        dynarray_add(&s1->sections, &s1->nb_sections, sec);
+    }
+
+    return sec;
+}
+
+ST_FUNC Section *new_symtab(TCCState *s1,
+                           const char *symtab_name, int sh_type, int sh_flags,
+                           const char *strtab_name,
+                           const char *hash_name, int hash_sh_flags)
+{
+    Section *symtab, *strtab, *hash;
+    int *ptr, nb_buckets;
+
+    symtab = new_section(s1, symtab_name, sh_type, sh_flags);
+    symtab->sh_entsize = sizeof(ElfW(Sym));
+    strtab = new_section(s1, strtab_name, SHT_STRTAB, sh_flags);
+    put_elf_str(strtab, "");
+    symtab->link = strtab;
+    put_elf_sym(symtab, 0, 0, 0, 0, 0, NULL);
+
+    nb_buckets = 1;
+
+    hash = new_section(s1, hash_name, SHT_HASH, hash_sh_flags);
+    hash->sh_entsize = sizeof(int);
+    symtab->hash = hash;
+    hash->link = symtab;
+
+    ptr = section_ptr_add(hash, (2 + nb_buckets + 1) * sizeof(int));
+    ptr[0] = nb_buckets;
+    ptr[1] = 1;
+    memset(ptr + 2, 0, (nb_buckets + 1) * sizeof(int));
+    return symtab;
+}
+
+/* realloc section and set its content to zero */
+ST_FUNC void section_realloc(Section *sec, unsigned long new_size)
+{
+    unsigned long size;
+    unsigned char *data;
+
+    size = sec->data_allocated;
+    if (size == 0)
+        size = 1;
+    while (size < new_size)
+        size = size * 2;
+    data = tcc_realloc(sec->data, size);
+    memset(data + sec->data_allocated, 0, size - sec->data_allocated);
+    sec->data = data;
+    sec->data_allocated = size;
+}
+
+/* reserve at least 'size' bytes aligned per 'align' in section
+   'sec' from current offset, and return the aligned offset */
+ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
+{
+    size_t offset, offset1;
+
+    offset = (sec->data_offset + align - 1) & -align;
+    offset1 = offset + size;
+    if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
+        section_realloc(sec, offset1);
+    sec->data_offset = offset1;
+    if (align > sec->sh_addralign)
+        sec->sh_addralign = align;
+    return offset;
+}
+
+/* reserve at least 'size' bytes in section 'sec' from
+   sec->data_offset. */
+ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
+{
+    size_t offset = section_add(sec, size, 1);
+    return sec->data + offset;
+}
+
+/* reserve at least 'size' bytes from section start */
+ST_FUNC void section_reserve(Section *sec, unsigned long size)
+{
+    if (size > sec->data_allocated)
+        section_realloc(sec, size);
+    if (size > sec->data_offset)
+        sec->data_offset = size;
+}
+
+/* return a reference to a section, and create it if it does not
+   exists */
+ST_FUNC Section *find_section(TCCState *s1, const char *name)
+{
+    Section *sec;
+    int i;
+    for(i = 1; i < s1->nb_sections; i++) {
+        sec = s1->sections[i];
+        if (!strcmp(name, sec->name))
+            return sec;
+    }
+    /* sections are created as PROGBITS */
+    return new_section(s1, name, SHT_PROGBITS, SHF_ALLOC);
+}
+
+/* ------------------------------------------------------------------------- */
+
+ST_FUNC int put_elf_str(Section *s, const char *sym)
+{
+    int offset, len;
+    char *ptr;
+
+    len = strlen(sym) + 1;
+    offset = s->data_offset;
+    ptr = section_ptr_add(s, len);
+    memmove(ptr, sym, len);
+    return offset;
+}
+
+/* elf symbol hashing function */
+static unsigned long elf_hash(const unsigned char *name)
+{
+    unsigned long h = 0, g;
+
+    while (*name) {
+        h = (h << 4) + *name++;
+        g = h & 0xf0000000;
+        if (g)
+            h ^= g >> 24;
+        h &= ~g;
+    }
+    return h;
+}
+
+/* rebuild hash table of section s */
+/* NOTE: we do factorize the hash table code to go faster */
+static void rebuild_hash(Section *s, unsigned int nb_buckets)
+{
+    ElfW(Sym) *sym;
+    int *ptr, *hash, nb_syms, sym_index, h;
+    unsigned char *strtab;
+
+    strtab = s->link->data;
+    nb_syms = s->data_offset / sizeof(ElfW(Sym));
+
+    if (!nb_buckets)
+        nb_buckets = ((int*)s->hash->data)[0];
+
+    s->hash->data_offset = 0;
+    ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int));
+    ptr[0] = nb_buckets;
+    ptr[1] = nb_syms;
+    ptr += 2;
+    hash = ptr;
+    memset(hash, 0, (nb_buckets + 1) * sizeof(int));
+    ptr += nb_buckets + 1;
+
+    sym = (ElfW(Sym) *)s->data + 1;
+    for(sym_index = 1; sym_index < nb_syms; sym_index++) {
+        if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
+            h = elf_hash(strtab + sym->st_name) % nb_buckets;
+            *ptr = hash[h];
+            hash[h] = sym_index;
+        } else {
+            *ptr = 0;
+        }
+        ptr++;
+        sym++;
+    }
+}
+
+/* return the symbol number */
+ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size,
+    int info, int other, int shndx, const char *name)
+{
+    int name_offset, sym_index;
+    int nbuckets, h;
+    ElfW(Sym) *sym;
+    Section *hs;
+
+    sym = section_ptr_add(s, sizeof(ElfW(Sym)));
+    if (name && name[0])
+        name_offset = put_elf_str(s->link, name);
+    else
+        name_offset = 0;
+    /* XXX: endianness */
+    sym->st_name = name_offset;
+    sym->st_value = value;
+    sym->st_size = size;
+    sym->st_info = info;
+    sym->st_other = other;
+    sym->st_shndx = shndx;
+    sym_index = sym - (ElfW(Sym) *)s->data;
+    hs = s->hash;
+    if (hs) {
+        int *ptr, *base;
+        ptr = section_ptr_add(hs, sizeof(int));
+        base = (int *)hs->data;
+        /* only add global or weak symbols. */
+        if (ELFW(ST_BIND)(info) != STB_LOCAL) {
+            /* add another hashing entry */
+            nbuckets = base[0];
+            h = elf_hash((unsigned char *)s->link->data + name_offset) % nbuckets;
+            *ptr = base[2 + h];
+            base[2 + h] = sym_index;
+            base[1]++;
+            /* we resize the hash table */
+            hs->nb_hashed_syms++;
+            if (hs->nb_hashed_syms > 2 * nbuckets) {
+                rebuild_hash(s, 2 * nbuckets);
+            }
+        } else {
+            *ptr = 0;
+            base[1]++;
+        }
+    }
+    return sym_index;
+}
+
+ST_FUNC int find_elf_sym(Section *s, const char *name)
+{
+    ElfW(Sym) *sym;
+    Section *hs;
+    int nbuckets, sym_index, h;
+    const char *name1;
+
+    hs = s->hash;
+    if (!hs)
+        return 0;
+    nbuckets = ((int *)hs->data)[0];
+    h = elf_hash((unsigned char *) name) % nbuckets;
+    sym_index = ((int *)hs->data)[2 + h];
+    while (sym_index != 0) {
+        sym = &((ElfW(Sym) *)s->data)[sym_index];
+        name1 = (char *) s->link->data + sym->st_name;
+        if (!strcmp(name, name1))
+            return sym_index;
+        sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
+    }
+    return 0;
+}
+
+/* return elf symbol value, signal error if 'err' is nonzero */
+ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err)
+{
+    int sym_index;
+    ElfW(Sym) *sym;
+
+    sym_index = find_elf_sym(s->symtab, name);
+    sym = &((ElfW(Sym) *)s->symtab->data)[sym_index];
+    if (!sym_index || sym->st_shndx == SHN_UNDEF) {
+        if (err)
+            tcc_error("%s not defined", name);
+        return 0;
+    }
+    return sym->st_value;
+}
+
+/* return elf symbol value */
+LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
+{
+    return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0);
+}
+
+#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
+/* return elf symbol value or error */
+ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
+{
+    return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1);
+}
+#endif
+
+/* add an elf symbol : check if it is already defined and patch
+   it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
+ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
+                       int info, int other, int shndx, const char *name)
+{
+    ElfW(Sym) *esym;
+    int sym_bind, sym_index, sym_type, esym_bind;
+    unsigned char sym_vis, esym_vis, new_vis;
+
+    sym_bind = ELFW(ST_BIND)(info);
+    sym_type = ELFW(ST_TYPE)(info);
+    sym_vis = ELFW(ST_VISIBILITY)(other);
+
+    if (sym_bind != STB_LOCAL) {
+        /* we search global or weak symbols */
+        sym_index = find_elf_sym(s, name);
+        if (!sym_index)
+            goto do_def;
+        esym = &((ElfW(Sym) *)s->data)[sym_index];
+        if (esym->st_value == value && esym->st_size == size && esym->st_info == info
+            && esym->st_other == other && esym->st_shndx == shndx)
+            return sym_index;
+        if (esym->st_shndx != SHN_UNDEF) {
+            esym_bind = ELFW(ST_BIND)(esym->st_info);
+            /* propagate the most constraining visibility */
+            /* STV_DEFAULT(0)<STV_PROTECTED(3)<STV_HIDDEN(2)<STV_INTERNAL(1) */
+            esym_vis = ELFW(ST_VISIBILITY)(esym->st_other);
+            if (esym_vis == STV_DEFAULT) {
+                new_vis = sym_vis;
+            } else if (sym_vis == STV_DEFAULT) {
+                new_vis = esym_vis;
+            } else {
+                new_vis = (esym_vis < sym_vis) ? esym_vis : sym_vis;
+            }
+            esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
+                             | new_vis;
+            other = esym->st_other; /* in case we have to patch esym */
+            if (shndx == SHN_UNDEF) {
+                /* ignore adding of undefined symbol if the
+                   corresponding symbol is already defined */
+            } else if (sym_bind == STB_GLOBAL && esym_bind == STB_WEAK) {
+                /* global overrides weak, so patch */
+                goto do_patch;
+            } else if (sym_bind == STB_WEAK && esym_bind == STB_GLOBAL) {
+                /* weak is ignored if already global */
+            } else if (sym_bind == STB_WEAK && esym_bind == STB_WEAK) {
+                /* keep first-found weak definition, ignore subsequents */
+            } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
+                /* ignore hidden symbols after */
+            } else if ((esym->st_shndx == SHN_COMMON
+                            || esym->st_shndx == bss_section->sh_num)
+                        && (shndx < SHN_LORESERVE
+                            && shndx != bss_section->sh_num)) {
+                /* data symbol gets precedence over common/bss */
+                goto do_patch;
+            } else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
+                /* data symbol keeps precedence over common/bss */
+            } else if (s->sh_flags & SHF_DYNSYM) {
+                /* we accept that two DLL define the same symbol */
+	    } else if (esym->st_other & ST_ASM_SET) {
+		/* If the existing symbol came from an asm .set
+		   we can override.  */
+		goto do_patch;
+            } else {
+#if 0
+                printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
+                       sym_bind, shndx, new_vis, esym_bind, esym->st_shndx, esym_vis);
+#endif
+                tcc_error_noabort("'%s' defined twice", name);
+            }
+        } else {
+        do_patch:
+            esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
+            esym->st_shndx = shndx;
+            new_undef_sym = 1;
+            esym->st_value = value;
+            esym->st_size = size;
+            esym->st_other = other;
+        }
+    } else {
+    do_def:
+        sym_index = put_elf_sym(s, value, size,
+                                ELFW(ST_INFO)(sym_bind, sym_type), other,
+                                shndx, name);
+    }
+    return sym_index;
+}
+
+/* put relocation */
+ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
+                            int type, int symbol, addr_t addend)
+{
+    char buf[256];
+    Section *sr;
+    ElfW_Rel *rel;
+
+    sr = s->reloc;
+    if (!sr) {
+        /* if no relocation section, create it */
+        snprintf(buf, sizeof(buf), REL_SECTION_FMT, s->name);
+        /* if the symtab is allocated, then we consider the relocation
+           are also */
+        sr = new_section(tcc_state, buf, SHT_RELX, symtab->sh_flags);
+        sr->sh_entsize = sizeof(ElfW_Rel);
+        sr->link = symtab;
+        sr->sh_info = s->sh_num;
+        s->reloc = sr;
+    }
+    rel = section_ptr_add(sr, sizeof(ElfW_Rel));
+    rel->r_offset = offset;
+    rel->r_info = ELFW(R_INFO)(symbol, type);
+#if SHT_RELX == SHT_RELA
+    rel->r_addend = addend;
+#else
+    if (addend)
+        tcc_error("non-zero addend on REL architecture");
+#endif
+}
+
+ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
+                           int type, int symbol)
+{
+    put_elf_reloca(symtab, s, offset, type, symbol, 0);
+}
+
+/* Remove relocations for section S->reloc starting at oldrelocoffset
+   that are to the same place, retaining the last of them.  As side effect
+   the relocations are sorted.  Possibly reduces the number of relocs.  */
+ST_FUNC void squeeze_multi_relocs(Section *s, size_t oldrelocoffset)
+{
+    Section *sr = s->reloc;
+    ElfW_Rel *r, *dest;
+    ssize_t a;
+    ElfW(Addr) addr;
+
+    if (oldrelocoffset + sizeof(*r) >= sr->data_offset)
+      return;
+    /* The relocs we're dealing with are the result of initializer parsing.
+       So they will be mostly in order and there aren't many of them.
+       Secondly we need a stable sort (which qsort isn't).  We use
+       a simple insertion sort.  */
+    for (a = oldrelocoffset + sizeof(*r); a < sr->data_offset; a += sizeof(*r)) {
+	ssize_t i = a - sizeof(*r);
+	addr = ((ElfW_Rel*)(sr->data + a))->r_offset;
+	for (; i >= (ssize_t)oldrelocoffset &&
+	       ((ElfW_Rel*)(sr->data + i))->r_offset > addr; i -= sizeof(*r)) {
+	    ElfW_Rel tmp = *(ElfW_Rel*)(sr->data + a);
+	    *(ElfW_Rel*)(sr->data + a) = *(ElfW_Rel*)(sr->data + i);
+	    *(ElfW_Rel*)(sr->data + i) = tmp;
+	}
+    }
+
+    r = (ElfW_Rel*)(sr->data + oldrelocoffset);
+    dest = r;
+    for (; r < (ElfW_Rel*)(sr->data + sr->data_offset); r++) {
+	if (dest->r_offset != r->r_offset)
+	  dest++;
+	*dest = *r;
+    }
+    sr->data_offset = (unsigned char*)dest - sr->data + sizeof(*r);
+}
+
+/* put stab debug information */
+
+ST_FUNC void put_stabs(const char *str, int type, int other, int desc,
+                      unsigned long value)
+{
+    Stab_Sym *sym;
+
+    sym = section_ptr_add(stab_section, sizeof(Stab_Sym));
+    if (str) {
+        sym->n_strx = put_elf_str(stabstr_section, str);
+    } else {
+        sym->n_strx = 0;
+    }
+    sym->n_type = type;
+    sym->n_other = other;
+    sym->n_desc = desc;
+    sym->n_value = value;
+}
+
+ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc,
+                        unsigned long value, Section *sec, int sym_index)
+{
+    put_stabs(str, type, other, desc, value);
+    put_elf_reloc(symtab_section, stab_section,
+                  stab_section->data_offset - sizeof(unsigned int),
+                  R_DATA_32, sym_index);
+}
+
+ST_FUNC void put_stabn(int type, int other, int desc, int value)
+{
+    put_stabs(NULL, type, other, desc, value);
+}
+
+ST_FUNC void put_stabd(int type, int other, int desc)
+{
+    put_stabs(NULL, type, other, desc, 0);
+}
+
+ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc)
+{
+    int n;
+    struct sym_attr *tab;
+
+    if (index >= s1->nb_sym_attrs) {
+        if (!alloc)
+            return s1->sym_attrs;
+        /* find immediately bigger power of 2 and reallocate array */
+        n = 1;
+        while (index >= n)
+            n *= 2;
+        tab = tcc_realloc(s1->sym_attrs, n * sizeof(*s1->sym_attrs));
+        s1->sym_attrs = tab;
+        memset(s1->sym_attrs + s1->nb_sym_attrs, 0,
+               (n - s1->nb_sym_attrs) * sizeof(*s1->sym_attrs));
+        s1->nb_sym_attrs = n;
+    }
+    return &s1->sym_attrs[index];
+}
+
+/* Browse each elem of type <type> in section <sec> starting at elem <startoff>
+   using variable <elem> */
+#define for_each_elem(sec, startoff, elem, type) \
+    for (elem = (type *) sec->data + startoff; \
+         elem < (type *) (sec->data + sec->data_offset); elem++)
+
+/* In an ELF file symbol table, the local symbols must appear below
+   the global and weak ones. Since TCC cannot sort it while generating
+   the code, we must do it after. All the relocation tables are also
+   modified to take into account the symbol table sorting */
+static void sort_syms(TCCState *s1, Section *s)
+{
+    int *old_to_new_syms;
+    ElfW(Sym) *new_syms;
+    int nb_syms, i;
+    ElfW(Sym) *p, *q;
+    ElfW_Rel *rel;
+    Section *sr;
+    int type, sym_index;
+
+    nb_syms = s->data_offset / sizeof(ElfW(Sym));
+    new_syms = tcc_malloc(nb_syms * sizeof(ElfW(Sym)));
+    old_to_new_syms = tcc_malloc(nb_syms * sizeof(int));
+
+    /* first pass for local symbols */
+    p = (ElfW(Sym) *)s->data;
+    q = new_syms;
+    for(i = 0; i < nb_syms; i++) {
+        if (ELFW(ST_BIND)(p->st_info) == STB_LOCAL) {
+            old_to_new_syms[i] = q - new_syms;
+            *q++ = *p;
+        }
+        p++;
+    }
+    /* save the number of local symbols in section header */
+    if( s->sh_size )    /* this 'if' makes IDA happy */
+        s->sh_info = q - new_syms;
+
+    /* then second pass for non local symbols */
+    p = (ElfW(Sym) *)s->data;
+    for(i = 0; i < nb_syms; i++) {
+        if (ELFW(ST_BIND)(p->st_info) != STB_LOCAL) {
+            old_to_new_syms[i] = q - new_syms;
+            *q++ = *p;
+        }
+        p++;
+    }
+
+    /* we copy the new symbols to the old */
+    memcpy(s->data, new_syms, nb_syms * sizeof(ElfW(Sym)));
+    tcc_free(new_syms);
+
+    /* now we modify all the relocations */
+    for(i = 1; i < s1->nb_sections; i++) {
+        sr = s1->sections[i];
+        if (sr->sh_type == SHT_RELX && sr->link == s) {
+            for_each_elem(sr, 0, rel, ElfW_Rel) {
+                sym_index = ELFW(R_SYM)(rel->r_info);
+                type = ELFW(R_TYPE)(rel->r_info);
+                sym_index = old_to_new_syms[sym_index];
+                rel->r_info = ELFW(R_INFO)(sym_index, type);
+            }
+        }
+    }
+
+    tcc_free(old_to_new_syms);
+}
+
+/* relocate symbol table, resolve undefined symbols if do_resolve is
+   true and output error if undefined symbol. */
+ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
+{
+    ElfW(Sym) *sym;
+    int sym_bind, sh_num;
+    const char *name;
+
+    for_each_elem(symtab, 1, sym, ElfW(Sym)) {
+        sh_num = sym->st_shndx;
+        if (sh_num == SHN_UNDEF) {
+            name = (char *) s1->symtab->link->data + sym->st_name;
+            /* Use ld.so to resolve symbol for us (for tcc -run) */
+            if (do_resolve) {
+#if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
+                void *addr = dlsym(RTLD_DEFAULT, name);
+                if (addr) {
+                    sym->st_value = (addr_t) addr;
+#ifdef DEBUG_RELOC
+		    printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
+#endif
+                    goto found;
+                }
+#endif
+            /* if dynamic symbol exist, it will be used in relocate_section */
+            } else if (s1->dynsym && find_elf_sym(s1->dynsym, name))
+                goto found;
+            /* XXX: _fp_hw seems to be part of the ABI, so we ignore
+               it */
+            if (!strcmp(name, "_fp_hw"))
+                goto found;
+            /* only weak symbols are accepted to be undefined. Their
+               value is zero */
+            sym_bind = ELFW(ST_BIND)(sym->st_info);
+            if (sym_bind == STB_WEAK)
+                sym->st_value = 0;
+            else
+                tcc_error_noabort("undefined symbol '%s'", name);
+        } else if (sh_num < SHN_LORESERVE) {
+            /* add section base */
+            sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
+        }
+    found: ;
+    }
+}
+
+/* relocate a given section (CPU dependent) by applying the relocations
+   in the associated relocation section */
+ST_FUNC void relocate_section(TCCState *s1, Section *s)
+{
+    Section *sr = s->reloc;
+    ElfW_Rel *rel;
+    ElfW(Sym) *sym;
+    int type, sym_index;
+    unsigned char *ptr;
+    addr_t tgt, addr;
+
+    relocate_init(sr);
+
+    for_each_elem(sr, 0, rel, ElfW_Rel) {
+        ptr = s->data + rel->r_offset;
+        sym_index = ELFW(R_SYM)(rel->r_info);
+        sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+        type = ELFW(R_TYPE)(rel->r_info);
+        tgt = sym->st_value;
+#if SHT_RELX == SHT_RELA
+        tgt += rel->r_addend;
+#endif
+        addr = s->sh_addr + rel->r_offset;
+        relocate(s1, rel, type, ptr, addr, tgt);
+    }
+    /* if the relocation is allocated, we change its symbol table */
+    if (sr->sh_flags & SHF_ALLOC)
+        sr->link = s1->dynsym;
+}
+
+/* relocate relocation table in 'sr' */
+static void relocate_rel(TCCState *s1, Section *sr)
+{
+    Section *s;
+    ElfW_Rel *rel;
+
+    s = s1->sections[sr->sh_info];
+    for_each_elem(sr, 0, rel, ElfW_Rel)
+        rel->r_offset += s->sh_addr;
+}
+
+/* count the number of dynamic relocations so that we can reserve
+   their space */
+static int prepare_dynamic_rel(TCCState *s1, Section *sr)
+{
+    ElfW_Rel *rel;
+    int sym_index, type, count;
+
+    count = 0;
+    for_each_elem(sr, 0, rel, ElfW_Rel) {
+        sym_index = ELFW(R_SYM)(rel->r_info);
+        type = ELFW(R_TYPE)(rel->r_info);
+        switch(type) {
+#if defined(TCC_TARGET_I386)
+        case R_386_32:
+            if (!get_sym_attr(s1, sym_index, 0)->dyn_index
+                && ((ElfW(Sym)*)symtab_section->data + sym_index)->st_shndx == SHN_UNDEF) {
+                /* don't fixup unresolved (weak) symbols */
+                rel->r_info = ELFW(R_INFO)(sym_index, R_386_RELATIVE);
+                break;
+            }
+#elif defined(TCC_TARGET_X86_64)
+        case R_X86_64_32:
+        case R_X86_64_32S:
+        case R_X86_64_64:
+#endif
+            count++;
+            break;
+#if defined(TCC_TARGET_I386)
+        case R_386_PC32:
+#elif defined(TCC_TARGET_X86_64)
+        case R_X86_64_PC32:
+#endif
+            if (get_sym_attr(s1, sym_index, 0)->dyn_index)
+                count++;
+            break;
+        default:
+            break;
+        }
+    }
+    if (count) {
+        /* allocate the section */
+        sr->sh_flags |= SHF_ALLOC;
+        sr->sh_size = count * sizeof(ElfW_Rel);
+    }
+    return count;
+}
+
+static void build_got(TCCState *s1)
+{
+    /* if no got, then create it */
+    s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
+    s1->got->sh_entsize = 4;
+    set_elf_sym(symtab_section, 0, 4, ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
+                0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
+    /* keep space for _DYNAMIC pointer and two dummy got entries */
+    section_ptr_add(s1->got, 3 * PTR_SIZE);
+}
+
+/* Create a GOT and (for function call) a PLT entry corresponding to a symbol
+   in s1->symtab. When creating the dynamic symbol table entry for the GOT
+   relocation, use 'size' and 'info' for the corresponding symbol metadata.
+   Returns the offset of the GOT or (if any) PLT entry. */
+static struct sym_attr * put_got_entry(TCCState *s1, int dyn_reloc_type,
+                                       unsigned long size,
+                                       int info, int sym_index)
+{
+    int need_plt_entry;
+    const char *name;
+    ElfW(Sym) *sym;
+    struct sym_attr *attr;
+    unsigned got_offset;
+    char plt_name[100];
+    int len;
+
+    need_plt_entry = (dyn_reloc_type == R_JMP_SLOT);
+    attr = get_sym_attr(s1, sym_index, 1);
+
+    /* In case a function is both called and its address taken 2 GOT entries
+       are created, one for taking the address (GOT) and the other for the PLT
+       entry (PLTGOT).  */
+    if (need_plt_entry ? attr->plt_offset : attr->got_offset)
+        return attr;
+
+    /* create the GOT entry */
+    got_offset = s1->got->data_offset;
+    section_ptr_add(s1->got, PTR_SIZE);
+
+    /* Create the GOT relocation that will insert the address of the object or
+       function of interest in the GOT entry. This is a static relocation for
+       memory output (dlsym will give us the address of symbols) and dynamic
+       relocation otherwise (executable and DLLs). The relocation should be
+       done lazily for GOT entry with *_JUMP_SLOT relocation type (the one
+       associated to a PLT entry) but is currently done at load time for an
+       unknown reason. */
+
+    sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
+    name = (char *) symtab_section->link->data + sym->st_name;
+
+    if (s1->dynsym) {
+	if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) {
+	    /* Hack alarm.  We don't want to emit dynamic symbols
+	       and symbol based relocs for STB_LOCAL symbols, but rather
+	       want to resolve them directly.  At this point the symbol
+	       values aren't final yet, so we must defer this.  We will later
+	       have to create a RELATIVE reloc anyway, so we misuse the
+	       relocation slot to smuggle the symbol reference until
+	       fill_local_got_entries.  Not that the sym_index is
+	       relative to symtab_section, not s1->dynsym!  Nevertheless
+	       we use s1->dyn_sym so that if this is the first call
+	       that got->reloc is correctly created.  Also note that
+	       RELATIVE relocs are not normally created for the .got,
+	       so the types serves as a marker for later (and is retained
+	       also for the final output, which is okay because then the
+	       got is just normal data).  */
+	    put_elf_reloc(s1->dynsym, s1->got, got_offset, R_RELATIVE,
+			  sym_index);
+	} else {
+	    if (0 == attr->dyn_index)
+                attr->dyn_index = set_elf_sym(s1->dynsym, sym->st_value, size,
+					      info, 0, sym->st_shndx, name);
+	    put_elf_reloc(s1->dynsym, s1->got, got_offset, dyn_reloc_type,
+			  attr->dyn_index);
+	}
+    } else {
+        put_elf_reloc(symtab_section, s1->got, got_offset, dyn_reloc_type,
+                      sym_index);
+    }
+
+    if (need_plt_entry) {
+        if (!s1->plt) {
+    	    s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
+    			          SHF_ALLOC | SHF_EXECINSTR);
+    	    s1->plt->sh_entsize = 4;
+        }
+
+        attr->plt_offset = create_plt_entry(s1, got_offset, attr);
+
+        /* create a symbol 'sym@plt' for the PLT jump vector */
+        len = strlen(name);
+        if (len > sizeof plt_name - 5)
+            len = sizeof plt_name - 5;
+        memcpy(plt_name, name, len);
+        strcpy(plt_name + len, "@plt");
+        attr->plt_sym = put_elf_sym(s1->symtab, attr->plt_offset, sym->st_size,
+            ELFW(ST_INFO)(STB_GLOBAL, STT_FUNC), 0, s1->plt->sh_num, plt_name);
+
+    } else {
+        attr->got_offset = got_offset;
+    }
+
+    return attr;
+}
+
+/* build GOT and PLT entries */
+ST_FUNC void build_got_entries(TCCState *s1)
+{
+    Section *s;
+    ElfW_Rel *rel;
+    ElfW(Sym) *sym;
+    int i, type, gotplt_entry, reloc_type, sym_index;
+    struct sym_attr *attr;
+
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+        if (s->sh_type != SHT_RELX)
+            continue;
+        /* no need to handle got relocations */
+        if (s->link != symtab_section)
+            continue;
+        for_each_elem(s, 0, rel, ElfW_Rel) {
+            type = ELFW(R_TYPE)(rel->r_info);
+            gotplt_entry = gotplt_entry_type(type);
+            sym_index = ELFW(R_SYM)(rel->r_info);
+            sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+
+            if (gotplt_entry == NO_GOTPLT_ENTRY) {
+                continue;
+            }
+
+            /* Automatically create PLT/GOT [entry] if it is an undefined
+	       reference (resolved at runtime), or the symbol is absolute,
+	       probably created by tcc_add_symbol, and thus on 64-bit
+	       targets might be too far from application code.  */
+            if (gotplt_entry == AUTO_GOTPLT_ENTRY) {
+                if (sym->st_shndx == SHN_UNDEF) {
+                    ElfW(Sym) *esym;
+		    int dynindex;
+                    if (s1->output_type == TCC_OUTPUT_DLL && ! PCRELATIVE_DLLPLT)
+                        continue;
+		    /* Relocations for UNDEF symbols would normally need
+		       to be transferred into the executable or shared object.
+		       If that were done AUTO_GOTPLT_ENTRY wouldn't exist.
+		       But TCC doesn't do that (at least for exes), so we
+		       need to resolve all such relocs locally.  And that
+		       means PLT slots for functions in DLLs and COPY relocs for
+		       data symbols.  COPY relocs were generated in
+		       bind_exe_dynsyms (and the symbol adjusted to be defined),
+		       and for functions we were generated a dynamic symbol
+		       of function type.  */
+		    if (s1->dynsym) {
+			/* dynsym isn't set for -run :-/  */
+			dynindex = get_sym_attr(s1, sym_index, 0)->dyn_index;
+			esym = (ElfW(Sym) *)s1->dynsym->data + dynindex;
+			if (dynindex
+			    && (ELFW(ST_TYPE)(esym->st_info) == STT_FUNC
+				|| (ELFW(ST_TYPE)(esym->st_info) == STT_NOTYPE
+				    && ELFW(ST_TYPE)(sym->st_info) == STT_FUNC)))
+			    goto jmp_slot;
+		    }
+                } else if (!(sym->st_shndx == SHN_ABS
+#ifndef TCC_TARGET_ARM
+			&& PTR_SIZE == 8
+#endif
+			))
+                    continue;
+            }
+
+#ifdef TCC_TARGET_X86_64
+            if ((type == R_X86_64_PLT32 || type == R_X86_64_PC32) &&
+                (ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT ||
+		 ELFW(ST_BIND)(sym->st_info) == STB_LOCAL)) {
+                rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
+                continue;
+            }
+#endif
+            if (code_reloc(type)) {
+            jmp_slot:
+                reloc_type = R_JMP_SLOT;
+            } else
+                reloc_type = R_GLOB_DAT;
+
+            if (!s1->got)
+                build_got(s1);
+
+            if (gotplt_entry == BUILD_GOT_ONLY)
+                continue;
+
+            attr = put_got_entry(s1, reloc_type, sym->st_size, sym->st_info,
+                                 sym_index);
+
+            if (reloc_type == R_JMP_SLOT)
+                rel->r_info = ELFW(R_INFO)(attr->plt_sym, type);
+        }
+    }
+}
+
+/* put dynamic tag */
+static void put_dt(Section *dynamic, int dt, addr_t val)
+{
+    ElfW(Dyn) *dyn;
+    dyn = section_ptr_add(dynamic, sizeof(ElfW(Dyn)));
+    dyn->d_tag = dt;
+    dyn->d_un.d_val = val;
+}
+
+#ifndef TCC_TARGET_PE
+static void add_init_array_defines(TCCState *s1, const char *section_name)
+{
+    Section *s;
+    long end_offset;
+    char sym_start[1024];
+    char sym_end[1024];
+
+    snprintf(sym_start, sizeof(sym_start), "__%s_start", section_name + 1);
+    snprintf(sym_end, sizeof(sym_end), "__%s_end", section_name + 1);
+
+    s = find_section(s1, section_name);
+    if (!s) {
+        end_offset = 0;
+        s = data_section;
+    } else {
+        end_offset = s->data_offset;
+    }
+
+    set_elf_sym(symtab_section,
+                0, 0,
+                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+                s->sh_num, sym_start);
+    set_elf_sym(symtab_section,
+                end_offset, 0,
+                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+                s->sh_num, sym_end);
+}
+#endif
+
+static int tcc_add_support(TCCState *s1, const char *filename)
+{
+    char buf[1024];
+    snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, filename);
+    return tcc_add_file(s1, buf);
+}
+
+ST_FUNC void tcc_add_bcheck(TCCState *s1)
+{
+#ifdef CONFIG_TCC_BCHECK
+    addr_t *ptr;
+    int sym_index;
+
+    if (0 == s1->do_bounds_check)
+        return;
+    /* XXX: add an object file to do that */
+    ptr = section_ptr_add(bounds_section, sizeof(*ptr));
+    *ptr = 0;
+    set_elf_sym(symtab_section, 0, 0,
+                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+                bounds_section->sh_num, "__bounds_start");
+    /* pull bcheck.o from libtcc1.a */
+    sym_index = set_elf_sym(symtab_section, 0, 0,
+                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+                SHN_UNDEF, "__bound_init");
+    if (s1->output_type != TCC_OUTPUT_MEMORY) {
+        /* add 'call __bound_init()' in .init section */
+        Section *init_section = find_section(s1, ".init");
+        unsigned char *pinit = section_ptr_add(init_section, 5);
+        pinit[0] = 0xe8;
+        write32le(pinit + 1, -4);
+        put_elf_reloc(symtab_section, init_section,
+            init_section->data_offset - 4, R_386_PC32, sym_index);
+            /* R_386_PC32 = R_X86_64_PC32 = 2 */
+    }
+#endif
+}
+
+/* add tcc runtime libraries */
+ST_FUNC void tcc_add_runtime(TCCState *s1)
+{
+    tcc_add_bcheck(s1);
+    tcc_add_pragma_libs(s1);
+    /* add libc */
+    if (!s1->nostdlib) {
+        tcc_add_library_err(s1, "c");
+#ifdef TCC_LIBGCC
+        if (!s1->static_link) {
+            if (TCC_LIBGCC[0] == '/')
+                tcc_add_file(s1, TCC_LIBGCC);
+            else
+                tcc_add_dll(s1, TCC_LIBGCC, 0);
+        }
+#endif
+        tcc_add_support(s1, TCC_LIBTCC1);
+        /* add crt end if not memory output */
+        if (s1->output_type != TCC_OUTPUT_MEMORY)
+            tcc_add_crt(s1, "crtn.o");
+    }
+}
+
+/* add various standard linker symbols (must be done after the
+   sections are filled (for example after allocating common
+   symbols)) */
+static void tcc_add_linker_symbols(TCCState *s1)
+{
+    char buf[1024];
+    int i;
+    Section *s;
+
+    set_elf_sym(symtab_section,
+                text_section->data_offset, 0,
+                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+                text_section->sh_num, "_etext");
+    set_elf_sym(symtab_section,
+                data_section->data_offset, 0,
+                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+                data_section->sh_num, "_edata");
+    set_elf_sym(symtab_section,
+                bss_section->data_offset, 0,
+                ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+                bss_section->sh_num, "_end");
+#ifndef TCC_TARGET_PE
+    /* horrible new standard ldscript defines */
+    add_init_array_defines(s1, ".preinit_array");
+    add_init_array_defines(s1, ".init_array");
+    add_init_array_defines(s1, ".fini_array");
+#endif
+
+    /* add start and stop symbols for sections whose name can be
+       expressed in C */
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+        if (s->sh_type == SHT_PROGBITS &&
+            (s->sh_flags & SHF_ALLOC)) {
+            const char *p;
+            int ch;
+
+            /* check if section name can be expressed in C */
+            p = s->name;
+            for(;;) {
+                ch = *p;
+                if (!ch)
+                    break;
+                if (!isid(ch) && !isnum(ch))
+                    goto next_sec;
+                p++;
+            }
+            snprintf(buf, sizeof(buf), "__start_%s", s->name);
+            set_elf_sym(symtab_section,
+                        0, 0,
+                        ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+                        s->sh_num, buf);
+            snprintf(buf, sizeof(buf), "__stop_%s", s->name);
+            set_elf_sym(symtab_section,
+                        s->data_offset, 0,
+                        ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+                        s->sh_num, buf);
+        }
+    next_sec: ;
+    }
+}
+
+ST_FUNC void resolve_common_syms(TCCState *s1)
+{
+    ElfW(Sym) *sym;
+
+    /* Allocate common symbols in BSS.  */
+    for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
+        if (sym->st_shndx == SHN_COMMON) {
+            /* symbol alignment is in st_value for SHN_COMMONs */
+	    sym->st_value = section_add(bss_section, sym->st_size,
+					sym->st_value);
+            sym->st_shndx = bss_section->sh_num;
+        }
+    }
+
+    /* Now assign linker provided symbols their value.  */
+    tcc_add_linker_symbols(s1);
+}
+
+static void tcc_output_binary(TCCState *s1, FILE *f,
+                              const int *sec_order)
+{
+    Section *s;
+    int i, offset, size;
+
+    offset = 0;
+    for(i=1;i<s1->nb_sections;i++) {
+        s = s1->sections[sec_order[i]];
+        if (s->sh_type != SHT_NOBITS &&
+            (s->sh_flags & SHF_ALLOC)) {
+            while (offset < s->sh_offset) {
+                fputc(0, f);
+                offset++;
+            }
+            size = s->sh_size;
+            fwrite(s->data, 1, size, f);
+            offset += size;
+        }
+    }
+}
+
+ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
+{
+    int sym_index = ELFW(R_SYM) (rel->r_info);
+    ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
+    struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
+    unsigned offset = attr->got_offset;
+
+    if (0 == offset)
+        return;
+    section_reserve(s1->got, offset + PTR_SIZE);
+#ifdef TCC_TARGET_X86_64
+    write64le(s1->got->data + offset, sym->st_value);
+#else
+    write32le(s1->got->data + offset, sym->st_value);
+#endif
+}
+
+/* Perform relocation to GOT or PLT entries */
+ST_FUNC void fill_got(TCCState *s1)
+{
+    Section *s;
+    ElfW_Rel *rel;
+    int i;
+
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+        if (s->sh_type != SHT_RELX)
+            continue;
+        /* no need to handle got relocations */
+        if (s->link != symtab_section)
+            continue;
+        for_each_elem(s, 0, rel, ElfW_Rel) {
+            switch (ELFW(R_TYPE) (rel->r_info)) {
+                case R_X86_64_GOT32:
+                case R_X86_64_GOTPCREL:
+		case R_X86_64_GOTPCRELX:
+		case R_X86_64_REX_GOTPCRELX:
+                case R_X86_64_PLT32:
+                    fill_got_entry(s1, rel);
+                    break;
+            }
+        }
+    }
+}
+
+/* See put_got_entry for a description.  This is the second stage
+   where GOT references to local defined symbols are rewritten.  */
+static void fill_local_got_entries(TCCState *s1)
+{
+    ElfW_Rel *rel;
+    for_each_elem(s1->got->reloc, 0, rel, ElfW_Rel) {
+	if (ELFW(R_TYPE)(rel->r_info) == R_RELATIVE) {
+	    int sym_index = ELFW(R_SYM) (rel->r_info);
+	    ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
+	    struct sym_attr *attr = get_sym_attr(s1, sym_index, 0);
+	    unsigned offset = attr->got_offset;
+	    if (offset != rel->r_offset - s1->got->sh_addr)
+	      tcc_error_noabort("huh");
+	    rel->r_info = ELFW(R_INFO)(0, R_RELATIVE);
+#if SHT_RELX == SHT_RELA
+	    rel->r_addend = sym->st_value;
+#else
+	    /* All our REL architectures also happen to be 32bit LE.  */
+	    write32le(s1->got->data + offset, sym->st_value);
+#endif
+	}
+    }
+}
+
+/* Bind symbols of executable: resolve undefined symbols from exported symbols
+   in shared libraries and export non local defined symbols to shared libraries
+   if -rdynamic switch was given on command line */
+static void bind_exe_dynsyms(TCCState *s1)
+{
+    const char *name;
+    int sym_index, index;
+    ElfW(Sym) *sym, *esym;
+    int type;
+
+    /* Resolve undefined symbols from dynamic symbols. When there is a match:
+       - if STT_FUNC or STT_GNU_IFUNC symbol -> add it in PLT
+       - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */
+    for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
+        if (sym->st_shndx == SHN_UNDEF) {
+            name = (char *) symtab_section->link->data + sym->st_name;
+            sym_index = find_elf_sym(s1->dynsymtab_section, name);
+            if (sym_index) {
+                esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index];
+                type = ELFW(ST_TYPE)(esym->st_info);
+                if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
+                    /* Indirect functions shall have STT_FUNC type in executable
+                     * dynsym section. Indeed, a dlsym call following a lazy
+                     * resolution would pick the symbol value from the
+                     * executable dynsym entry which would contain the address
+                     * of the function wanted by the caller of dlsym instead of
+                     * the address of the function that would return that
+                     * address */
+                    int dynindex
+		      = put_elf_sym(s1->dynsym, 0, esym->st_size,
+				    ELFW(ST_INFO)(STB_GLOBAL,STT_FUNC), 0, 0,
+				    name);
+		    int index = sym - (ElfW(Sym) *) symtab_section->data;
+		    get_sym_attr(s1, index, 1)->dyn_index = dynindex;
+                } else if (type == STT_OBJECT) {
+                    unsigned long offset;
+                    ElfW(Sym) *dynsym;
+                    offset = bss_section->data_offset;
+                    /* XXX: which alignment ? */
+                    offset = (offset + 16 - 1) & -16;
+                    set_elf_sym (s1->symtab, offset, esym->st_size,
+                                 esym->st_info, 0, bss_section->sh_num, name);
+                    index = put_elf_sym(s1->dynsym, offset, esym->st_size,
+                                        esym->st_info, 0, bss_section->sh_num,
+                                        name);
+
+                    /* Ensure R_COPY works for weak symbol aliases */
+                    if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) {
+                        for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) {
+                            if ((dynsym->st_value == esym->st_value)
+                                && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) {
+                                char *dynname = (char *) s1->dynsymtab_section->link->data
+                                                + dynsym->st_name;
+                                put_elf_sym(s1->dynsym, offset, dynsym->st_size,
+                                            dynsym->st_info, 0,
+                                            bss_section->sh_num, dynname);
+                                break;
+                            }
+                        }
+                    }
+
+                    put_elf_reloc(s1->dynsym, bss_section,
+                                  offset, R_COPY, index);
+                    offset += esym->st_size;
+                    bss_section->data_offset = offset;
+                }
+            } else {
+                /* STB_WEAK undefined symbols are accepted */
+                /* XXX: _fp_hw seems to be part of the ABI, so we ignore it */
+                if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK ||
+                    !strcmp(name, "_fp_hw")) {
+                } else {
+                    tcc_error_noabort("undefined symbol '%s'", name);
+                }
+            }
+        } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
+            /* if -rdynamic option, then export all non local symbols */
+            name = (char *) symtab_section->link->data + sym->st_name;
+            set_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info,
+                        0, sym->st_shndx, name);
+        }
+    }
+}
+
+/* Bind symbols of libraries: export all non local symbols of executable that
+   are referenced by shared libraries. The reason is that the dynamic loader
+   search symbol first in executable and then in libraries. Therefore a
+   reference to a symbol already defined by a library can still be resolved by
+   a symbol in the executable. */
+static void bind_libs_dynsyms(TCCState *s1)
+{
+    const char *name;
+    int sym_index;
+    ElfW(Sym) *sym, *esym;
+
+    for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) {
+        name = (char *) s1->dynsymtab_section->link->data + esym->st_name;
+        sym_index = find_elf_sym(symtab_section, name);
+        sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+        if (sym_index && sym->st_shndx != SHN_UNDEF
+            && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
+            set_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
+                sym->st_info, 0, sym->st_shndx, name);
+        } else if (esym->st_shndx == SHN_UNDEF) {
+            /* weak symbols can stay undefined */
+            if (ELFW(ST_BIND)(esym->st_info) != STB_WEAK)
+                tcc_warning("undefined dynamic symbol '%s'", name);
+        }
+    }
+}
+
+/* Export all non local symbols. This is used by shared libraries so that the
+   non local symbols they define can resolve a reference in another shared
+   library or in the executable. Correspondingly, it allows undefined local
+   symbols to be resolved by other shared libraries or by the executable. */
+static void export_global_syms(TCCState *s1)
+{
+    int dynindex, index;
+    const char *name;
+    ElfW(Sym) *sym;
+
+    for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
+        if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
+	    name = (char *) symtab_section->link->data + sym->st_name;
+	    dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
+				   sym->st_info, 0, sym->st_shndx, name);
+	    index = sym - (ElfW(Sym) *) symtab_section->data;
+            get_sym_attr(s1, index, 1)->dyn_index = dynindex;
+        }
+    }
+}
+
+/* Allocate strings for section names and decide if an unallocated section
+   should be output.
+   NOTE: the strsec section comes last, so its size is also correct ! */
+static int alloc_sec_names(TCCState *s1, int file_type, Section *strsec)
+{
+    int i;
+    Section *s;
+    int textrel = 0;
+
+    /* Allocate strings for section names */
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+        /* when generating a DLL, we include relocations but we may
+           patch them */
+        if (file_type == TCC_OUTPUT_DLL &&
+            s->sh_type == SHT_RELX &&
+            !(s->sh_flags & SHF_ALLOC) &&
+            (s1->sections[s->sh_info]->sh_flags & SHF_ALLOC) &&
+            prepare_dynamic_rel(s1, s)) {
+                if (s1->sections[s->sh_info]->sh_flags & SHF_EXECINSTR)
+                    textrel = 1;
+        } else if (s1->do_debug ||
+            file_type == TCC_OUTPUT_OBJ ||
+            (s->sh_flags & SHF_ALLOC) ||
+	    i == (s1->nb_sections - 1)) {
+            /* we output all sections if debug or object file */
+            s->sh_size = s->data_offset;
+        }
+	if (s->sh_size || (s->sh_flags & SHF_ALLOC))
+            s->sh_name = put_elf_str(strsec, s->name);
+    }
+    strsec->sh_size = strsec->data_offset;
+    return textrel;
+}
+
+/* Info to be copied in dynamic section */
+struct dyn_inf {
+    Section *dynamic;
+    Section *dynstr;
+    unsigned long data_offset;
+    addr_t rel_addr;
+    addr_t rel_size;
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+    addr_t bss_addr;
+    addr_t bss_size;
+#endif
+};
+
+/* Assign sections to segments and decide how are sections laid out when loaded
+   in memory. This function also fills corresponding program headers. */
+static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
+                           Section *interp, Section* strsec,
+                           struct dyn_inf *dyninf, int *sec_order)
+{
+    int i, j, k, file_type, sh_order_index, file_offset;
+    unsigned long s_align;
+    long long tmp;
+    addr_t addr;
+    ElfW(Phdr) *ph;
+    Section *s;
+
+    file_type = s1->output_type;
+    sh_order_index = 1;
+    file_offset = 0;
+    if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
+        file_offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
+    s_align = ELF_PAGE_SIZE;
+    if (s1->section_align)
+        s_align = s1->section_align;
+
+    if (phnum > 0) {
+        if (s1->has_text_addr) {
+            int a_offset, p_offset;
+            addr = s1->text_addr;
+            /* we ensure that (addr % ELF_PAGE_SIZE) == file_offset %
+               ELF_PAGE_SIZE */
+            a_offset = (int) (addr & (s_align - 1));
+            p_offset = file_offset & (s_align - 1);
+            if (a_offset < p_offset)
+                a_offset += s_align;
+            file_offset += (a_offset - p_offset);
+        } else {
+            if (file_type == TCC_OUTPUT_DLL)
+                addr = 0;
+            else
+                addr = ELF_START_ADDR;
+            /* compute address after headers */
+            addr += (file_offset & (s_align - 1));
+        }
+
+        ph = &phdr[0];
+        /* Leave one program headers for the program interpreter and one for
+           the program header table itself if needed. These are done later as
+           they require section layout to be done first. */
+        if (interp)
+            ph += 2;
+
+        /* dynamic relocation table information, for .dynamic section */
+        dyninf->rel_addr = dyninf->rel_size = 0;
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+        dyninf->bss_addr = dyninf->bss_size = 0;
+#endif
+
+        for(j = 0; j < 2; j++) {
+            ph->p_type = PT_LOAD;
+            if (j == 0)
+                ph->p_flags = PF_R | PF_X;
+            else
+                ph->p_flags = PF_R | PF_W;
+            ph->p_align = s_align;
+
+            /* Decide the layout of sections loaded in memory. This must
+               be done before program headers are filled since they contain
+               info about the layout. We do the following ordering: interp,
+               symbol tables, relocations, progbits, nobits */
+            /* XXX: do faster and simpler sorting */
+            for(k = 0; k < 5; k++) {
+                for(i = 1; i < s1->nb_sections; i++) {
+                    s = s1->sections[i];
+                    /* compute if section should be included */
+                    if (j == 0) {
+                        if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
+                            SHF_ALLOC)
+                            continue;
+                    } else {
+                        if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
+                            (SHF_ALLOC | SHF_WRITE))
+                            continue;
+                    }
+                    if (s == interp) {
+                        if (k != 0)
+                            continue;
+                    } else if (s->sh_type == SHT_DYNSYM ||
+                               s->sh_type == SHT_STRTAB ||
+                               s->sh_type == SHT_HASH) {
+                        if (k != 1)
+                            continue;
+                    } else if (s->sh_type == SHT_RELX) {
+                        if (k != 2)
+                            continue;
+                    } else if (s->sh_type == SHT_NOBITS) {
+                        if (k != 4)
+                            continue;
+                    } else {
+                        if (k != 3)
+                            continue;
+                    }
+                    sec_order[sh_order_index++] = i;
+
+                    /* section matches: we align it and add its size */
+                    tmp = addr;
+                    addr = (addr + s->sh_addralign - 1) &
+                        ~(s->sh_addralign - 1);
+                    file_offset += (int) ( addr - tmp );
+                    s->sh_offset = file_offset;
+                    s->sh_addr = addr;
+
+                    /* update program header infos */
+                    if (ph->p_offset == 0) {
+                        ph->p_offset = file_offset;
+                        ph->p_vaddr = addr;
+                        ph->p_paddr = ph->p_vaddr;
+                    }
+                    /* update dynamic relocation infos */
+                    if (s->sh_type == SHT_RELX) {
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+                        if (!strcmp(strsec->data + s->sh_name, ".rel.got")) {
+                            dyninf->rel_addr = addr;
+                            dyninf->rel_size += s->sh_size; /* XXX only first rel. */
+                        }
+                        if (!strcmp(strsec->data + s->sh_name, ".rel.bss")) {
+                            dyninf->bss_addr = addr;
+                            dyninf->bss_size = s->sh_size; /* XXX only first rel. */
+                        }
+#else
+                        if (dyninf->rel_size == 0)
+                            dyninf->rel_addr = addr;
+                        dyninf->rel_size += s->sh_size;
+#endif
+                    }
+                    addr += s->sh_size;
+                    if (s->sh_type != SHT_NOBITS)
+                        file_offset += s->sh_size;
+                }
+            }
+	    if (j == 0) {
+		/* Make the first PT_LOAD segment include the program
+		   headers itself (and the ELF header as well), it'll
+		   come out with same memory use but will make various
+		   tools like binutils strip work better.  */
+		ph->p_offset &= ~(ph->p_align - 1);
+		ph->p_vaddr &= ~(ph->p_align - 1);
+		ph->p_paddr &= ~(ph->p_align - 1);
+	    }
+            ph->p_filesz = file_offset - ph->p_offset;
+            ph->p_memsz = addr - ph->p_vaddr;
+            ph++;
+            if (j == 0) {
+                if (s1->output_format == TCC_OUTPUT_FORMAT_ELF) {
+                    /* if in the middle of a page, we duplicate the page in
+                       memory so that one copy is RX and the other is RW */
+                    if ((addr & (s_align - 1)) != 0)
+                        addr += s_align;
+                } else {
+                    addr = (addr + s_align - 1) & ~(s_align - 1);
+                    file_offset = (file_offset + s_align - 1) & ~(s_align - 1);
+                }
+            }
+        }
+    }
+
+    /* all other sections come after */
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+        if (phnum > 0 && (s->sh_flags & SHF_ALLOC))
+            continue;
+        sec_order[sh_order_index++] = i;
+
+        file_offset = (file_offset + s->sh_addralign - 1) &
+            ~(s->sh_addralign - 1);
+        s->sh_offset = file_offset;
+        if (s->sh_type != SHT_NOBITS)
+            file_offset += s->sh_size;
+    }
+
+    return file_offset;
+}
+
+static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
+                                 Section *dynamic)
+{
+    ElfW(Phdr) *ph;
+
+    /* if interpreter, then add corresponding program header */
+    if (interp) {
+        ph = &phdr[0];
+
+        ph->p_type = PT_PHDR;
+        ph->p_offset = sizeof(ElfW(Ehdr));
+        ph->p_filesz = ph->p_memsz = phnum * sizeof(ElfW(Phdr));
+        ph->p_vaddr = interp->sh_addr - ph->p_filesz;
+        ph->p_paddr = ph->p_vaddr;
+        ph->p_flags = PF_R | PF_X;
+        ph->p_align = 4; /* interp->sh_addralign; */
+        ph++;
+
+        ph->p_type = PT_INTERP;
+        ph->p_offset = interp->sh_offset;
+        ph->p_vaddr = interp->sh_addr;
+        ph->p_paddr = ph->p_vaddr;
+        ph->p_filesz = interp->sh_size;
+        ph->p_memsz = interp->sh_size;
+        ph->p_flags = PF_R;
+        ph->p_align = interp->sh_addralign;
+    }
+
+    /* if dynamic section, then add corresponding program header */
+    if (dynamic) {
+        ph = &phdr[phnum - 1];
+
+        ph->p_type = PT_DYNAMIC;
+        ph->p_offset = dynamic->sh_offset;
+        ph->p_vaddr = dynamic->sh_addr;
+        ph->p_paddr = ph->p_vaddr;
+        ph->p_filesz = dynamic->sh_size;
+        ph->p_memsz = dynamic->sh_size;
+        ph->p_flags = PF_R | PF_W;
+        ph->p_align = dynamic->sh_addralign;
+    }
+}
+
+/* Fill the dynamic section with tags describing the address and size of
+   sections */
+static void fill_dynamic(TCCState *s1, struct dyn_inf *dyninf)
+{
+    Section *dynamic = dyninf->dynamic;
+
+    /* put dynamic section entries */
+    put_dt(dynamic, DT_HASH, s1->dynsym->hash->sh_addr);
+    put_dt(dynamic, DT_STRTAB, dyninf->dynstr->sh_addr);
+    put_dt(dynamic, DT_SYMTAB, s1->dynsym->sh_addr);
+    put_dt(dynamic, DT_STRSZ, dyninf->dynstr->data_offset);
+    put_dt(dynamic, DT_SYMENT, sizeof(ElfW(Sym)));
+#if PTR_SIZE == 8
+    put_dt(dynamic, DT_RELA, dyninf->rel_addr);
+    put_dt(dynamic, DT_RELASZ, dyninf->rel_size);
+    put_dt(dynamic, DT_RELAENT, sizeof(ElfW_Rel));
+#else
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+    put_dt(dynamic, DT_PLTGOT, s1->got->sh_addr);
+    put_dt(dynamic, DT_PLTRELSZ, dyninf->rel_size);
+    put_dt(dynamic, DT_JMPREL, dyninf->rel_addr);
+    put_dt(dynamic, DT_PLTREL, DT_REL);
+    put_dt(dynamic, DT_REL, dyninf->bss_addr);
+    put_dt(dynamic, DT_RELSZ, dyninf->bss_size);
+#else
+    put_dt(dynamic, DT_REL, dyninf->rel_addr);
+    put_dt(dynamic, DT_RELSZ, dyninf->rel_size);
+    put_dt(dynamic, DT_RELENT, sizeof(ElfW_Rel));
+#endif
+#endif
+    if (s1->do_debug)
+        put_dt(dynamic, DT_DEBUG, 0);
+    put_dt(dynamic, DT_NULL, 0);
+}
+
+/* Relocate remaining sections and symbols (that is those not related to
+   dynamic linking) */
+static int final_sections_reloc(TCCState *s1)
+{
+    int i;
+    Section *s;
+
+    relocate_syms(s1, s1->symtab, 0);
+
+    if (s1->nb_errors != 0)
+        return -1;
+
+    /* relocate sections */
+    /* XXX: ignore sections with allocated relocations ? */
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+#if defined(TCC_TARGET_I386) || defined(TCC_MUSL)
+        if (s->reloc && s != s1->got && (s->sh_flags & SHF_ALLOC)) //gr
+        /* On X86 gdb 7.3 works in any case but gdb 6.6 will crash if SHF_ALLOC
+        checking is removed */
+#else
+        if (s->reloc && s != s1->got)
+        /* On X86_64 gdb 7.3 will crash if SHF_ALLOC checking is present */
+#endif
+            relocate_section(s1, s);
+    }
+
+    /* relocate relocation entries if the relocation tables are
+       allocated in the executable */
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+        if ((s->sh_flags & SHF_ALLOC) &&
+            s->sh_type == SHT_RELX) {
+            relocate_rel(s1, s);
+        }
+    }
+    return 0;
+}
+
+/* Create an ELF file on disk.
+   This function handle ELF specific layout requirements */
+static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
+                           int file_offset, int *sec_order)
+{
+    int i, shnum, offset, size, file_type;
+    Section *s;
+    ElfW(Ehdr) ehdr;
+    ElfW(Shdr) shdr, *sh;
+
+    file_type = s1->output_type;
+    shnum = s1->nb_sections;
+
+    memset(&ehdr, 0, sizeof(ehdr));
+
+    if (phnum > 0) {
+        ehdr.e_phentsize = sizeof(ElfW(Phdr));
+        ehdr.e_phnum = phnum;
+        ehdr.e_phoff = sizeof(ElfW(Ehdr));
+    }
+
+    /* align to 4 */
+    file_offset = (file_offset + 3) & -4;
+
+    /* fill header */
+    ehdr.e_ident[0] = ELFMAG0;
+    ehdr.e_ident[1] = ELFMAG1;
+    ehdr.e_ident[2] = ELFMAG2;
+    ehdr.e_ident[3] = ELFMAG3;
+    ehdr.e_ident[4] = ELFCLASSW;
+    ehdr.e_ident[5] = ELFDATA2LSB;
+    ehdr.e_ident[6] = EV_CURRENT;
+#if !defined(TCC_TARGET_PE) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
+    /* FIXME: should set only for freebsd _target_, but we exclude only PE target */
+    ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
+#endif
+#ifdef TCC_TARGET_ARM
+#ifdef TCC_ARM_EABI
+    ehdr.e_ident[EI_OSABI] = 0;
+    ehdr.e_flags = EF_ARM_EABI_VER4;
+    if (file_type == TCC_OUTPUT_EXE || file_type == TCC_OUTPUT_DLL)
+        ehdr.e_flags |= EF_ARM_HASENTRY;
+    if (s1->float_abi == ARM_HARD_FLOAT)
+        ehdr.e_flags |= EF_ARM_VFP_FLOAT;
+    else
+        ehdr.e_flags |= EF_ARM_SOFT_FLOAT;
+#else
+    ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
+#endif
+#endif
+    switch(file_type) {
+    default:
+    case TCC_OUTPUT_EXE:
+        ehdr.e_type = ET_EXEC;
+        ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1);
+        break;
+    case TCC_OUTPUT_DLL:
+        ehdr.e_type = ET_DYN;
+        ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
+        break;
+    case TCC_OUTPUT_OBJ:
+        ehdr.e_type = ET_REL;
+        break;
+    }
+    ehdr.e_machine = EM_TCC_TARGET;
+    ehdr.e_version = EV_CURRENT;
+    ehdr.e_shoff = file_offset;
+    ehdr.e_ehsize = sizeof(ElfW(Ehdr));
+    ehdr.e_shentsize = sizeof(ElfW(Shdr));
+    ehdr.e_shnum = shnum;
+    ehdr.e_shstrndx = shnum - 1;
+
+    fwrite(&ehdr, 1, sizeof(ElfW(Ehdr)), f);
+    fwrite(phdr, 1, phnum * sizeof(ElfW(Phdr)), f);
+    offset = sizeof(ElfW(Ehdr)) + phnum * sizeof(ElfW(Phdr));
+
+    sort_syms(s1, symtab_section);
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[sec_order[i]];
+        if (s->sh_type != SHT_NOBITS) {
+            while (offset < s->sh_offset) {
+                fputc(0, f);
+                offset++;
+            }
+            size = s->sh_size;
+            if (size)
+                fwrite(s->data, 1, size, f);
+            offset += size;
+        }
+    }
+
+    /* output section headers */
+    while (offset < ehdr.e_shoff) {
+        fputc(0, f);
+        offset++;
+    }
+
+    for(i = 0; i < s1->nb_sections; i++) {
+        sh = &shdr;
+        memset(sh, 0, sizeof(ElfW(Shdr)));
+        s = s1->sections[i];
+        if (s) {
+            sh->sh_name = s->sh_name;
+            sh->sh_type = s->sh_type;
+            sh->sh_flags = s->sh_flags;
+            sh->sh_entsize = s->sh_entsize;
+            sh->sh_info = s->sh_info;
+            if (s->link)
+                sh->sh_link = s->link->sh_num;
+            sh->sh_addralign = s->sh_addralign;
+            sh->sh_addr = s->sh_addr;
+            sh->sh_offset = s->sh_offset;
+            sh->sh_size = s->sh_size;
+        }
+        fwrite(sh, 1, sizeof(ElfW(Shdr)), f);
+    }
+}
+
+/* Write an elf, coff or "binary" file */
+static int tcc_write_elf_file(TCCState *s1, const char *filename, int phnum,
+                              ElfW(Phdr) *phdr, int file_offset, int *sec_order)
+{
+    int fd, mode, file_type;
+    FILE *f;
+
+    file_type = s1->output_type;
+    if (file_type == TCC_OUTPUT_OBJ)
+        mode = 0666;
+    else
+        mode = 0777;
+    unlink(filename);
+    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, mode);
+    if (fd < 0) {
+        tcc_error_noabort("could not write '%s'", filename);
+        return -1;
+    }
+    f = fdopen(fd, "wb");
+    if (s1->verbose)
+        printf("<- %s\n", filename);
+
+#ifdef TCC_TARGET_COFF
+    if (s1->output_format == TCC_OUTPUT_FORMAT_COFF)
+        tcc_output_coff(s1, f);
+    else
+#endif
+    if (s1->output_format == TCC_OUTPUT_FORMAT_ELF)
+        tcc_output_elf(s1, f, phnum, phdr, file_offset, sec_order);
+    else
+        tcc_output_binary(s1, f, sec_order);
+    fclose(f);
+
+    return 0;
+}
+
+/* Sort section headers by assigned sh_addr, remove sections
+   that we aren't going to output.  */
+static void tidy_section_headers(TCCState *s1, int *sec_order)
+{
+    int i, nnew, l, *backmap;
+    Section **snew, *s;
+    ElfW(Sym) *sym;
+
+    snew = tcc_malloc(s1->nb_sections * sizeof(snew[0]));
+    backmap = tcc_malloc(s1->nb_sections * sizeof(backmap[0]));
+    for (i = 0, nnew = 0, l = s1->nb_sections; i < s1->nb_sections; i++) {
+	s = s1->sections[sec_order[i]];
+	if (!i || s->sh_name) {
+	    backmap[sec_order[i]] = nnew;
+	    snew[nnew] = s;
+	    ++nnew;
+	} else {
+	    backmap[sec_order[i]] = 0;
+	    snew[--l] = s;
+	}
+    }
+    for (i = 0; i < nnew; i++) {
+	s = snew[i];
+	if (s) {
+	    s->sh_num = i;
+            if (s->sh_type == SHT_RELX)
+		s->sh_info = backmap[s->sh_info];
+	}
+    }
+
+    for_each_elem(symtab_section, 1, sym, ElfW(Sym))
+	if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
+	    sym->st_shndx = backmap[sym->st_shndx];
+    if( !s1->static_link ) {
+        for_each_elem(s1->dynsym, 1, sym, ElfW(Sym))
+	    if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE)
+	        sym->st_shndx = backmap[sym->st_shndx];
+    }
+    for (i = 0; i < s1->nb_sections; i++)
+	sec_order[i] = i;
+    tcc_free(s1->sections);
+    s1->sections = snew;
+    s1->nb_sections = nnew;
+    tcc_free(backmap);
+}
+
+/* Output an elf, coff or binary file */
+/* XXX: suppress unneeded sections */
+static int elf_output_file(TCCState *s1, const char *filename)
+{
+    int i, ret, phnum, shnum, file_type, file_offset, *sec_order;
+    struct dyn_inf dyninf = {0};
+    ElfW(Phdr) *phdr;
+    ElfW(Sym) *sym;
+    Section *strsec, *interp, *dynamic, *dynstr;
+    int textrel;
+
+    file_type = s1->output_type;
+    s1->nb_errors = 0;
+    ret = -1;
+    phdr = NULL;
+    sec_order = NULL;
+    interp = dynamic = dynstr = NULL; /* avoid warning */
+    textrel = 0;
+
+    if (file_type != TCC_OUTPUT_OBJ) {
+        /* if linking, also link in runtime libraries (libc, libgcc, etc.) */
+        tcc_add_runtime(s1);
+	resolve_common_syms(s1);
+
+        if (!s1->static_link) {
+            if (file_type == TCC_OUTPUT_EXE) {
+                char *ptr;
+                /* allow override the dynamic loader */
+                const char *elfint = getenv("LD_SO");
+                if (elfint == NULL)
+                    elfint = DEFAULT_ELFINTERP(s1);
+                /* add interpreter section only if executable */
+                interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
+                interp->sh_addralign = 1;
+                ptr = section_ptr_add(interp, 1 + strlen(elfint));
+                strcpy(ptr, elfint);
+            }
+
+            /* add dynamic symbol table */
+            s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
+                                    ".dynstr",
+                                    ".hash", SHF_ALLOC);
+            dynstr = s1->dynsym->link;
+
+            /* add dynamic section */
+            dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
+                                  SHF_ALLOC | SHF_WRITE);
+            dynamic->link = dynstr;
+            dynamic->sh_entsize = sizeof(ElfW(Dyn));
+
+            build_got(s1);
+
+            if (file_type == TCC_OUTPUT_EXE) {
+                bind_exe_dynsyms(s1);
+                if (s1->nb_errors)
+                    goto the_end;
+                bind_libs_dynsyms(s1);
+            } else {
+                /* shared library case: simply export all global symbols */
+                export_global_syms(s1);
+            }
+        }
+        build_got_entries(s1);
+    }
+
+    /* we add a section for symbols */
+    strsec = new_section(s1, ".shstrtab", SHT_STRTAB, 0);
+    put_elf_str(strsec, "");
+
+    /* Allocate strings for section names */
+    textrel = alloc_sec_names(s1, file_type, strsec);
+
+    if (dynamic) {
+        /* add a list of needed dlls */
+        for(i = 0; i < s1->nb_loaded_dlls; i++) {
+            DLLReference *dllref = s1->loaded_dlls[i];
+            if (dllref->level == 0)
+                put_dt(dynamic, DT_NEEDED, put_elf_str(dynstr, dllref->name));
+        }
+
+        if (s1->rpath)
+            put_dt(dynamic, s1->enable_new_dtags ? DT_RUNPATH : DT_RPATH,
+                   put_elf_str(dynstr, s1->rpath));
+
+        if (file_type == TCC_OUTPUT_DLL) {
+            if (s1->soname)
+                put_dt(dynamic, DT_SONAME, put_elf_str(dynstr, s1->soname));
+            /* XXX: currently, since we do not handle PIC code, we
+               must relocate the readonly segments */
+            if (textrel)
+                put_dt(dynamic, DT_TEXTREL, 0);
+        }
+
+        if (s1->symbolic)
+            put_dt(dynamic, DT_SYMBOLIC, 0);
+
+        dyninf.dynamic = dynamic;
+        dyninf.dynstr = dynstr;
+        /* remember offset and reserve space for 2nd call below */
+        dyninf.data_offset = dynamic->data_offset;
+        fill_dynamic(s1, &dyninf);
+        dynamic->sh_size = dynamic->data_offset;
+        dynstr->sh_size = dynstr->data_offset;
+    }
+
+    /* compute number of program headers */
+    if (file_type == TCC_OUTPUT_OBJ)
+        phnum = 0;
+    else if (file_type == TCC_OUTPUT_DLL)
+        phnum = 3;
+    else if (s1->static_link)
+        phnum = 2;
+    else
+        phnum = 5;
+
+    /* allocate program segment headers */
+    phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
+
+    /* compute number of sections */
+    shnum = s1->nb_sections;
+
+    /* this array is used to reorder sections in the output file */
+    sec_order = tcc_malloc(sizeof(int) * shnum);
+    sec_order[0] = 0;
+
+    /* compute section to program header mapping */
+    file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
+                                  sec_order);
+
+    /* Fill remaining program header and finalize relocation related to dynamic
+       linking. */
+    if (file_type != TCC_OUTPUT_OBJ) {
+        fill_unloadable_phdr(phdr, phnum, interp, dynamic);
+        if (dynamic) {
+            dynamic->data_offset = dyninf.data_offset;
+            fill_dynamic(s1, &dyninf);
+
+            /* put in GOT the dynamic section address and relocate PLT */
+            write32le(s1->got->data, dynamic->sh_addr);
+            if (file_type == TCC_OUTPUT_EXE
+                || (RELOCATE_DLLPLT && file_type == TCC_OUTPUT_DLL))
+                relocate_plt(s1);
+
+            /* relocate symbols in .dynsym now that final addresses are known */
+            for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
+                if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
+                    /* do symbol relocation */
+                    sym->st_value += s1->sections[sym->st_shndx]->sh_addr;
+                }
+            }
+        }
+
+        /* if building executable or DLL, then relocate each section
+           except the GOT which is already relocated */
+        ret = final_sections_reloc(s1);
+        if (ret)
+            goto the_end;
+	tidy_section_headers(s1, sec_order);
+
+        /* Perform relocation to GOT or PLT entries */
+        if (file_type == TCC_OUTPUT_EXE && s1->static_link)
+            fill_got(s1);
+        else if (s1->got)
+            fill_local_got_entries(s1);
+    }
+
+    /* Create the ELF file with name 'filename' */
+    ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
+    s1->nb_sections = shnum;
+ the_end:
+    tcc_free(sec_order);
+    tcc_free(phdr);
+    return ret;
+}
+
+LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
+{
+    int ret;
+#ifdef TCC_TARGET_PE
+    if (s->output_type != TCC_OUTPUT_OBJ) {
+        ret = pe_output_file(s, filename);
+    } else
+#endif
+        ret = elf_output_file(s, filename);
+    return ret;
+}
+
+static void *load_data(int fd, unsigned long file_offset, unsigned long size)
+{
+    void *data;
+
+    data = tcc_malloc(size);
+    lseek(fd, file_offset, SEEK_SET);
+    read(fd, data, size);
+    return data;
+}
+
+typedef struct SectionMergeInfo {
+    Section *s;            /* corresponding existing section */
+    unsigned long offset;  /* offset of the new section in the existing section */
+    uint8_t new_section;       /* true if section 's' was added */
+    uint8_t link_once;         /* true if link once section */
+} SectionMergeInfo;
+
+ST_FUNC int tcc_object_type(int fd, ElfW(Ehdr) *h)
+{
+    int size = read(fd, h, sizeof *h);
+    if (size == sizeof *h && 0 == memcmp(h, ELFMAG, 4)) {
+        if (h->e_type == ET_REL)
+            return AFF_BINTYPE_REL;
+        if (h->e_type == ET_DYN)
+            return AFF_BINTYPE_DYN;
+    } else if (size >= 8) {
+        if (0 == memcmp(h, ARMAG, 8))
+            return AFF_BINTYPE_AR;
+#ifdef TCC_TARGET_COFF
+        if (((struct filehdr*)h)->f_magic == COFF_C67_MAGIC)
+            return AFF_BINTYPE_C67;
+#endif
+    }
+    return 0;
+}
+
+/* load an object file and merge it with current files */
+/* XXX: handle correctly stab (debug) info */
+ST_FUNC int tcc_load_object_file(TCCState *s1,
+                                int fd, unsigned long file_offset)
+{
+    ElfW(Ehdr) ehdr;
+    ElfW(Shdr) *shdr, *sh;
+    int size, i, j, offset, offseti, nb_syms, sym_index, ret, seencompressed;
+    unsigned char *strsec, *strtab;
+    int *old_to_new_syms;
+    char *sh_name, *name;
+    SectionMergeInfo *sm_table, *sm;
+    ElfW(Sym) *sym, *symtab;
+    ElfW_Rel *rel;
+    Section *s;
+
+    int stab_index;
+    int stabstr_index;
+
+    stab_index = stabstr_index = 0;
+
+    lseek(fd, file_offset, SEEK_SET);
+    if (tcc_object_type(fd, &ehdr) != AFF_BINTYPE_REL)
+        goto fail1;
+    /* test CPU specific stuff */
+    if (ehdr.e_ident[5] != ELFDATA2LSB ||
+        ehdr.e_machine != EM_TCC_TARGET) {
+    fail1:
+        tcc_error_noabort("invalid object file");
+        return -1;
+    }
+    /* read sections */
+    shdr = load_data(fd, file_offset + ehdr.e_shoff,
+                     sizeof(ElfW(Shdr)) * ehdr.e_shnum);
+    sm_table = tcc_mallocz(sizeof(SectionMergeInfo) * ehdr.e_shnum);
+
+    /* load section names */
+    sh = &shdr[ehdr.e_shstrndx];
+    strsec = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
+
+    /* load symtab and strtab */
+    old_to_new_syms = NULL;
+    symtab = NULL;
+    strtab = NULL;
+    nb_syms = 0;
+    seencompressed = 0;
+    for(i = 1; i < ehdr.e_shnum; i++) {
+        sh = &shdr[i];
+        if (sh->sh_type == SHT_SYMTAB) {
+            if (symtab) {
+                tcc_error_noabort("object must contain only one symtab");
+            fail:
+                ret = -1;
+                goto the_end;
+            }
+            nb_syms = sh->sh_size / sizeof(ElfW(Sym));
+            symtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
+            sm_table[i].s = symtab_section;
+
+            /* now load strtab */
+            sh = &shdr[sh->sh_link];
+            strtab = load_data(fd, file_offset + sh->sh_offset, sh->sh_size);
+        }
+	if (sh->sh_flags & SHF_COMPRESSED)
+	    seencompressed = 1;
+    }
+
+    /* now examine each section and try to merge its content with the
+       ones in memory */
+    for(i = 1; i < ehdr.e_shnum; i++) {
+        /* no need to examine section name strtab */
+        if (i == ehdr.e_shstrndx)
+            continue;
+        sh = &shdr[i];
+        sh_name = (char *) strsec + sh->sh_name;
+        /* ignore sections types we do not handle */
+        if (sh->sh_type != SHT_PROGBITS &&
+            sh->sh_type != SHT_RELX &&
+#ifdef TCC_ARM_EABI
+            sh->sh_type != SHT_ARM_EXIDX &&
+#endif
+            sh->sh_type != SHT_NOBITS &&
+            sh->sh_type != SHT_PREINIT_ARRAY &&
+            sh->sh_type != SHT_INIT_ARRAY &&
+            sh->sh_type != SHT_FINI_ARRAY &&
+            strcmp(sh_name, ".stabstr")
+            )
+            continue;
+	if (seencompressed
+	    && (!strncmp(sh_name, ".debug_", sizeof(".debug_")-1)
+		|| (sh->sh_type == SHT_RELX
+		    && !strncmp((char*)strsec + shdr[sh->sh_info].sh_name,
+			        ".debug_", sizeof(".debug_")-1))))
+	  continue;
+        if (sh->sh_addralign < 1)
+            sh->sh_addralign = 1;
+        /* find corresponding section, if any */
+        for(j = 1; j < s1->nb_sections;j++) {
+            s = s1->sections[j];
+            if (!strcmp(s->name, sh_name)) {
+                if (!strncmp(sh_name, ".gnu.linkonce",
+                             sizeof(".gnu.linkonce") - 1)) {
+                    /* if a 'linkonce' section is already present, we
+                       do not add it again. It is a little tricky as
+                       symbols can still be defined in
+                       it. */
+                    sm_table[i].link_once = 1;
+                    goto next;
+                } else {
+                    goto found;
+                }
+            }
+        }
+        /* not found: create new section */
+        s = new_section(s1, sh_name, sh->sh_type, sh->sh_flags & ~SHF_GROUP);
+        /* take as much info as possible from the section. sh_link and
+           sh_info will be updated later */
+        s->sh_addralign = sh->sh_addralign;
+        s->sh_entsize = sh->sh_entsize;
+        sm_table[i].new_section = 1;
+    found:
+        if (sh->sh_type != s->sh_type) {
+            tcc_error_noabort("invalid section type");
+            goto fail;
+        }
+
+        /* align start of section */
+        offset = s->data_offset;
+
+        if (0 == strcmp(sh_name, ".stab")) {
+            stab_index = i;
+            goto no_align;
+        }
+        if (0 == strcmp(sh_name, ".stabstr")) {
+            stabstr_index = i;
+            goto no_align;
+        }
+
+        size = sh->sh_addralign - 1;
+        offset = (offset + size) & ~size;
+        if (sh->sh_addralign > s->sh_addralign)
+            s->sh_addralign = sh->sh_addralign;
+        s->data_offset = offset;
+    no_align:
+        sm_table[i].offset = offset;
+        sm_table[i].s = s;
+        /* concatenate sections */
+        size = sh->sh_size;
+        if (sh->sh_type != SHT_NOBITS) {
+            unsigned char *ptr;
+            lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
+            ptr = section_ptr_add(s, size);
+            read(fd, ptr, size);
+        } else {
+            s->data_offset += size;
+        }
+    next: ;
+    }
+
+    /* gr relocate stab strings */
+    if (stab_index && stabstr_index) {
+        Stab_Sym *a, *b;
+        unsigned o;
+        s = sm_table[stab_index].s;
+        a = (Stab_Sym *)(s->data + sm_table[stab_index].offset);
+        b = (Stab_Sym *)(s->data + s->data_offset);
+        o = sm_table[stabstr_index].offset;
+        while (a < b)
+            a->n_strx += o, a++;
+    }
+
+    /* second short pass to update sh_link and sh_info fields of new
+       sections */
+    for(i = 1; i < ehdr.e_shnum; i++) {
+        s = sm_table[i].s;
+        if (!s || !sm_table[i].new_section)
+            continue;
+        sh = &shdr[i];
+        if (sh->sh_link > 0)
+            s->link = sm_table[sh->sh_link].s;
+        if (sh->sh_type == SHT_RELX) {
+            s->sh_info = sm_table[sh->sh_info].s->sh_num;
+            /* update backward link */
+            s1->sections[s->sh_info]->reloc = s;
+        }
+    }
+    sm = sm_table;
+
+    /* resolve symbols */
+    old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
+
+    sym = symtab + 1;
+    for(i = 1; i < nb_syms; i++, sym++) {
+        if (sym->st_shndx != SHN_UNDEF &&
+            sym->st_shndx < SHN_LORESERVE) {
+            sm = &sm_table[sym->st_shndx];
+            if (sm->link_once) {
+                /* if a symbol is in a link once section, we use the
+                   already defined symbol. It is very important to get
+                   correct relocations */
+                if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
+                    name = (char *) strtab + sym->st_name;
+                    sym_index = find_elf_sym(symtab_section, name);
+                    if (sym_index)
+                        old_to_new_syms[i] = sym_index;
+                }
+                continue;
+            }
+            /* if no corresponding section added, no need to add symbol */
+            if (!sm->s)
+                continue;
+            /* convert section number */
+            sym->st_shndx = sm->s->sh_num;
+            /* offset value */
+            sym->st_value += sm->offset;
+        }
+        /* add symbol */
+        name = (char *) strtab + sym->st_name;
+        sym_index = set_elf_sym(symtab_section, sym->st_value, sym->st_size,
+                                sym->st_info, sym->st_other,
+                                sym->st_shndx, name);
+        old_to_new_syms[i] = sym_index;
+    }
+
+    /* third pass to patch relocation entries */
+    for(i = 1; i < ehdr.e_shnum; i++) {
+        s = sm_table[i].s;
+        if (!s)
+            continue;
+        sh = &shdr[i];
+        offset = sm_table[i].offset;
+        switch(s->sh_type) {
+        case SHT_RELX:
+            /* take relocation offset information */
+            offseti = sm_table[sh->sh_info].offset;
+            for_each_elem(s, (offset / sizeof(*rel)), rel, ElfW_Rel) {
+                int type;
+                unsigned sym_index;
+                /* convert symbol index */
+                type = ELFW(R_TYPE)(rel->r_info);
+                sym_index = ELFW(R_SYM)(rel->r_info);
+                /* NOTE: only one symtab assumed */
+                if (sym_index >= nb_syms)
+                    goto invalid_reloc;
+                sym_index = old_to_new_syms[sym_index];
+                /* ignore link_once in rel section. */
+                if (!sym_index && !sm->link_once
+#ifdef TCC_TARGET_ARM
+                    && type != R_ARM_V4BX
+#endif
+                   ) {
+                invalid_reloc:
+                    tcc_error_noabort("Invalid relocation entry [%2d] '%s' @ %.8x",
+                        i, strsec + sh->sh_name, rel->r_offset);
+                    goto fail;
+                }
+                rel->r_info = ELFW(R_INFO)(sym_index, type);
+                /* offset the relocation offset */
+                rel->r_offset += offseti;
+#ifdef TCC_TARGET_ARM
+                /* Jumps and branches from a Thumb code to a PLT entry need
+                   special handling since PLT entries are ARM code.
+                   Unconditional bl instructions referencing PLT entries are
+                   handled by converting these instructions into blx
+                   instructions. Other case of instructions referencing a PLT
+                   entry require to add a Thumb stub before the PLT entry to
+                   switch to ARM mode. We set bit plt_thumb_stub of the
+                   attribute of a symbol to indicate such a case. */
+                if (type == R_ARM_THM_JUMP24)
+                    get_sym_attr(s1, sym_index, 1)->plt_thumb_stub = 1;
+#endif
+            }
+            break;
+        default:
+            break;
+        }
+    }
+
+    ret = 0;
+ the_end:
+    tcc_free(symtab);
+    tcc_free(strtab);
+    tcc_free(old_to_new_syms);
+    tcc_free(sm_table);
+    tcc_free(strsec);
+    tcc_free(shdr);
+    return ret;
+}
+
+typedef struct ArchiveHeader {
+    char ar_name[16];           /* name of this member */
+    char ar_date[12];           /* file mtime */
+    char ar_uid[6];             /* owner uid; printed as decimal */
+    char ar_gid[6];             /* owner gid; printed as decimal */
+    char ar_mode[8];            /* file mode, printed as octal   */
+    char ar_size[10];           /* file size, printed as decimal */
+    char ar_fmag[2];            /* should contain ARFMAG */
+} ArchiveHeader;
+
+static int get_be32(const uint8_t *b)
+{
+    return b[3] | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
+}
+
+static long get_be64(const uint8_t *b)
+{
+  long long ret = get_be32(b);
+  ret = (ret << 32) | (unsigned)get_be32(b+4);
+  return (long)ret;
+}
+
+/* load only the objects which resolve undefined symbols */
+static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize)
+{
+    long i, bound, nsyms, sym_index, off, ret;
+    uint8_t *data;
+    const char *ar_names, *p;
+    const uint8_t *ar_index;
+    ElfW(Sym) *sym;
+
+    data = tcc_malloc(size);
+    if (read(fd, data, size) != size)
+        goto fail;
+    nsyms = entrysize == 4 ? get_be32(data) : get_be64(data);
+    ar_index = data + entrysize;
+    ar_names = (char *) ar_index + nsyms * entrysize;
+
+    do {
+        bound = 0;
+        for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
+            sym_index = find_elf_sym(symtab_section, p);
+            if(sym_index) {
+                sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
+                if(sym->st_shndx == SHN_UNDEF) {
+                    off = (entrysize == 4
+			   ? get_be32(ar_index + i * 4)
+			   : get_be64(ar_index + i * 8))
+			  + sizeof(ArchiveHeader);
+                    ++bound;
+                    if(tcc_load_object_file(s1, fd, off) < 0) {
+                    fail:
+                        ret = -1;
+                        goto the_end;
+                    }
+                }
+            }
+        }
+    } while(bound);
+    ret = 0;
+ the_end:
+    tcc_free(data);
+    return ret;
+}
+
+/* load a '.a' file */
+ST_FUNC int tcc_load_archive(TCCState *s1, int fd)
+{
+    ArchiveHeader hdr;
+    char ar_size[11];
+    char ar_name[17];
+    char magic[8];
+    int size, len, i;
+    unsigned long file_offset;
+
+    /* skip magic which was already checked */
+    read(fd, magic, sizeof(magic));
+
+    for(;;) {
+        len = read(fd, &hdr, sizeof(hdr));
+        if (len == 0)
+            break;
+        if (len != sizeof(hdr)) {
+            tcc_error_noabort("invalid archive");
+            return -1;
+        }
+        memcpy(ar_size, hdr.ar_size, sizeof(hdr.ar_size));
+        ar_size[sizeof(hdr.ar_size)] = '\0';
+        size = strtol(ar_size, NULL, 0);
+        memcpy(ar_name, hdr.ar_name, sizeof(hdr.ar_name));
+        for(i = sizeof(hdr.ar_name) - 1; i >= 0; i--) {
+            if (ar_name[i] != ' ')
+                break;
+        }
+        ar_name[i + 1] = '\0';
+        file_offset = lseek(fd, 0, SEEK_CUR);
+        /* align to even */
+        size = (size + 1) & ~1;
+        if (!strcmp(ar_name, "/")) {
+            /* coff symbol table : we handle it */
+            if(s1->alacarte_link)
+                return tcc_load_alacarte(s1, fd, size, 4);
+	} else if (!strcmp(ar_name, "/SYM64/")) {
+            if(s1->alacarte_link)
+                return tcc_load_alacarte(s1, fd, size, 8);
+        } else {
+            ElfW(Ehdr) ehdr;
+            if (tcc_object_type(fd, &ehdr) == AFF_BINTYPE_REL) {
+                if (tcc_load_object_file(s1, fd, file_offset) < 0)
+                    return -1;
+            }
+        }
+        lseek(fd, file_offset + size, SEEK_SET);
+    }
+    return 0;
+}
+
+#ifndef TCC_TARGET_PE
+/* load a DLL and all referenced DLLs. 'level = 0' means that the DLL
+   is referenced by the user (so it should be added as DT_NEEDED in
+   the generated ELF file) */
+ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
+{
+    ElfW(Ehdr) ehdr;
+    ElfW(Shdr) *shdr, *sh, *sh1;
+    int i, j, nb_syms, nb_dts, sym_bind, ret;
+    ElfW(Sym) *sym, *dynsym;
+    ElfW(Dyn) *dt, *dynamic;
+    unsigned char *dynstr;
+    const char *name, *soname;
+    DLLReference *dllref;
+
+    read(fd, &ehdr, sizeof(ehdr));
+
+    /* test CPU specific stuff */
+    if (ehdr.e_ident[5] != ELFDATA2LSB ||
+        ehdr.e_machine != EM_TCC_TARGET) {
+        tcc_error_noabort("bad architecture");
+        return -1;
+    }
+
+    /* read sections */
+    shdr = load_data(fd, ehdr.e_shoff, sizeof(ElfW(Shdr)) * ehdr.e_shnum);
+
+    /* load dynamic section and dynamic symbols */
+    nb_syms = 0;
+    nb_dts = 0;
+    dynamic = NULL;
+    dynsym = NULL; /* avoid warning */
+    dynstr = NULL; /* avoid warning */
+    for(i = 0, sh = shdr; i < ehdr.e_shnum; i++, sh++) {
+        switch(sh->sh_type) {
+        case SHT_DYNAMIC:
+            nb_dts = sh->sh_size / sizeof(ElfW(Dyn));
+            dynamic = load_data(fd, sh->sh_offset, sh->sh_size);
+            break;
+        case SHT_DYNSYM:
+            nb_syms = sh->sh_size / sizeof(ElfW(Sym));
+            dynsym = load_data(fd, sh->sh_offset, sh->sh_size);
+            sh1 = &shdr[sh->sh_link];
+            dynstr = load_data(fd, sh1->sh_offset, sh1->sh_size);
+            break;
+        default:
+            break;
+        }
+    }
+
+    /* compute the real library name */
+    soname = tcc_basename(filename);
+
+    for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
+        if (dt->d_tag == DT_SONAME) {
+            soname = (char *) dynstr + dt->d_un.d_val;
+        }
+    }
+
+    /* if the dll is already loaded, do not load it */
+    for(i = 0; i < s1->nb_loaded_dlls; i++) {
+        dllref = s1->loaded_dlls[i];
+        if (!strcmp(soname, dllref->name)) {
+            /* but update level if needed */
+            if (level < dllref->level)
+                dllref->level = level;
+            ret = 0;
+            goto the_end;
+        }
+    }
+
+    /* add the dll and its level */
+    dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
+    dllref->level = level;
+    strcpy(dllref->name, soname);
+    dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
+
+    /* add dynamic symbols in dynsym_section */
+    for(i = 1, sym = dynsym + 1; i < nb_syms; i++, sym++) {
+        sym_bind = ELFW(ST_BIND)(sym->st_info);
+        if (sym_bind == STB_LOCAL)
+            continue;
+        name = (char *) dynstr + sym->st_name;
+        set_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
+                    sym->st_info, sym->st_other, sym->st_shndx, name);
+    }
+
+    /* load all referenced DLLs */
+    for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
+        switch(dt->d_tag) {
+        case DT_NEEDED:
+            name = (char *) dynstr + dt->d_un.d_val;
+            for(j = 0; j < s1->nb_loaded_dlls; j++) {
+                dllref = s1->loaded_dlls[j];
+                if (!strcmp(name, dllref->name))
+                    goto already_loaded;
+            }
+            if (tcc_add_dll(s1, name, AFF_REFERENCED_DLL) < 0) {
+                tcc_error_noabort("referenced dll '%s' not found", name);
+                ret = -1;
+                goto the_end;
+            }
+        already_loaded:
+            break;
+        }
+    }
+    ret = 0;
+ the_end:
+    tcc_free(dynstr);
+    tcc_free(dynsym);
+    tcc_free(dynamic);
+    tcc_free(shdr);
+    return ret;
+}
+
+#define LD_TOK_NAME 256
+#define LD_TOK_EOF  (-1)
+
+/* return next ld script token */
+static int ld_next(TCCState *s1, char *name, int name_size)
+{
+    int c;
+    char *q;
+
+ redo:
+    switch(ch) {
+    case ' ':
+    case '\t':
+    case '\f':
+    case '\v':
+    case '\r':
+    case '\n':
+        inp();
+        goto redo;
+    case '/':
+        minp();
+        if (ch == '*') {
+            file->buf_ptr = parse_comment(file->buf_ptr);
+            ch = file->buf_ptr[0];
+            goto redo;
+        } else {
+            q = name;
+            *q++ = '/';
+            goto parse_name;
+        }
+        break;
+    case '\\':
+        ch = handle_eob();
+        if (ch != '\\')
+            goto redo;
+        /* fall through */
+    /* case 'a' ... 'z': */
+    case 'a':
+       case 'b':
+       case 'c':
+       case 'd':
+       case 'e':
+       case 'f':
+       case 'g':
+       case 'h':
+       case 'i':
+       case 'j':
+       case 'k':
+       case 'l':
+       case 'm':
+       case 'n':
+       case 'o':
+       case 'p':
+       case 'q':
+       case 'r':
+       case 's':
+       case 't':
+       case 'u':
+       case 'v':
+       case 'w':
+       case 'x':
+       case 'y':
+       case 'z':
+    /* case 'A' ... 'z': */
+    case 'A':
+       case 'B':
+       case 'C':
+       case 'D':
+       case 'E':
+       case 'F':
+       case 'G':
+       case 'H':
+       case 'I':
+       case 'J':
+       case 'K':
+       case 'L':
+       case 'M':
+       case 'N':
+       case 'O':
+       case 'P':
+       case 'Q':
+       case 'R':
+       case 'S':
+       case 'T':
+       case 'U':
+       case 'V':
+       case 'W':
+       case 'X':
+       case 'Y':
+       case 'Z':
+    case '_':
+    case '.':
+    case '$':
+    case '~':
+        q = name;
+    parse_name:
+        for(;;) {
+            if (!((ch >= 'a' && ch <= 'z') ||
+                  (ch >= 'A' && ch <= 'Z') ||
+                  (ch >= '0' && ch <= '9') ||
+                  strchr("/.-_+=$:\\,~", ch)))
+                break;
+            if ((q - name) < name_size - 1) {
+                *q++ = ch;
+            }
+            minp();
+        }
+        *q = '\0';
+        c = LD_TOK_NAME;
+        break;
+    case CH_EOF:
+        c = LD_TOK_EOF;
+        break;
+    default:
+        c = ch;
+        inp();
+        break;
+    }
+    return c;
+}
+
+static int ld_add_file(TCCState *s1, const char filename[])
+{
+    if (filename[0] == '/') {
+        if (CONFIG_SYSROOT[0] == '\0'
+            && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)
+            return 0;
+        filename = tcc_basename(filename);
+    }
+    return tcc_add_dll(s1, filename, 0);
+}
+
+static inline int new_undef_syms(void)
+{
+    int ret = 0;
+    ret = new_undef_sym;
+    new_undef_sym = 0;
+    return ret;
+}
+
+static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)
+{
+    char filename[1024], libname[1024];
+    int t, group, nblibs = 0, ret = 0;
+    char **libs = NULL;
+
+    group = !strcmp(cmd, "GROUP");
+    if (!as_needed)
+        new_undef_syms();
+    t = ld_next(s1, filename, sizeof(filename));
+    if (t != '(')
+        expect("(");
+    t = ld_next(s1, filename, sizeof(filename));
+    for(;;) {
+        libname[0] = '\0';
+        if (t == LD_TOK_EOF) {
+            tcc_error_noabort("unexpected end of file");
+            ret = -1;
+            goto lib_parse_error;
+        } else if (t == ')') {
+            break;
+        } else if (t == '-') {
+            t = ld_next(s1, filename, sizeof(filename));
+            if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
+                tcc_error_noabort("library name expected");
+                ret = -1;
+                goto lib_parse_error;
+            }
+            pstrcpy(libname, sizeof libname, &filename[1]);
+            if (s1->static_link) {
+                snprintf(filename, sizeof filename, "lib%s.a", libname);
+            } else {
+                snprintf(filename, sizeof filename, "lib%s.so", libname);
+            }
+        } else if (t != LD_TOK_NAME) {
+            tcc_error_noabort("filename expected");
+            ret = -1;
+            goto lib_parse_error;
+        }
+        if (!strcmp(filename, "AS_NEEDED")) {
+            ret = ld_add_file_list(s1, cmd, 1);
+            if (ret)
+                goto lib_parse_error;
+        } else {
+            /* TODO: Implement AS_NEEDED support. Ignore it for now */
+            if (!as_needed) {
+                ret = ld_add_file(s1, filename);
+                if (ret)
+                    goto lib_parse_error;
+                if (group) {
+                    /* Add the filename *and* the libname to avoid future conversions */
+                    dynarray_add(&libs, &nblibs, tcc_strdup(filename));
+                    if (libname[0] != '\0')
+                        dynarray_add(&libs, &nblibs, tcc_strdup(libname));
+                }
+            }
+        }
+        t = ld_next(s1, filename, sizeof(filename));
+        if (t == ',') {
+            t = ld_next(s1, filename, sizeof(filename));
+        }
+    }
+    if (group && !as_needed) {
+        while (new_undef_syms()) {
+            int i;
+
+            for (i = 0; i < nblibs; i ++)
+                ld_add_file(s1, libs[i]);
+        }
+    }
+lib_parse_error:
+    dynarray_reset(&libs, &nblibs);
+    return ret;
+}
+
+/* interpret a subset of GNU ldscripts to handle the dummy libc.so
+   files */
+ST_FUNC int tcc_load_ldscript(TCCState *s1)
+{
+    char cmd[64];
+    char filename[1024];
+    int t, ret;
+
+    ch = handle_eob();
+    for(;;) {
+        t = ld_next(s1, cmd, sizeof(cmd));
+        if (t == LD_TOK_EOF)
+            return 0;
+        else if (t != LD_TOK_NAME)
+            return -1;
+        if (!strcmp(cmd, "INPUT") ||
+            !strcmp(cmd, "GROUP")) {
+            ret = ld_add_file_list(s1, cmd, 0);
+            if (ret)
+                return ret;
+        } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
+                   !strcmp(cmd, "TARGET")) {
+            /* ignore some commands */
+            t = ld_next(s1, cmd, sizeof(cmd));
+            if (t != '(')
+                expect("(");
+            for(;;) {
+                t = ld_next(s1, filename, sizeof(filename));
+                if (t == LD_TOK_EOF) {
+                    tcc_error_noabort("unexpected end of file");
+                    return -1;
+                } else if (t == ')') {
+                    break;
+                }
+            }
+        } else {
+            return -1;
+        }
+    }
+    return 0;
+}
+#endif /* !TCC_TARGET_PE */
Index: EcnlProtoTool/trunk/tcc-0.9.27/tccgen.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tccgen.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tccgen.c	(revision 331)
@@ -0,0 +1,7386 @@
+/*
+ *  TCC - Tiny C Compiler
+ * 
+ *  Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "tcc.h"
+
+/********************************************************/
+/* global variables */
+
+/* loc : local variable index
+   ind : output code index
+   rsym: return symbol
+   anon_sym: anonymous symbol index
+*/
+ST_DATA int rsym, anon_sym, ind, loc;
+
+ST_DATA Sym *sym_free_first;
+ST_DATA void **sym_pools;
+ST_DATA int nb_sym_pools;
+
+ST_DATA Sym *global_stack;
+ST_DATA Sym *local_stack;
+ST_DATA Sym *define_stack;
+ST_DATA Sym *global_label_stack;
+ST_DATA Sym *local_label_stack;
+static int local_scope;
+static int in_sizeof;
+static int section_sym;
+
+ST_DATA int vlas_in_scope; /* number of VLAs that are currently in scope */
+ST_DATA int vla_sp_root_loc; /* vla_sp_loc for SP before any VLAs were pushed */
+ST_DATA int vla_sp_loc; /* Pointer to variable holding location to store stack pointer on the stack when modifying stack pointer */
+
+ST_DATA SValue __vstack[1+VSTACK_SIZE], *vtop, *pvtop;
+
+ST_DATA int const_wanted; /* true if constant wanted */
+ST_DATA int nocode_wanted; /* no code generation wanted */
+#define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */
+#define STATIC_DATA_WANTED (nocode_wanted & 0xC0000000) /* only static data output */
+ST_DATA int global_expr;  /* true if compound literals must be allocated globally (used during initializers parsing */
+ST_DATA CType func_vt; /* current function return type (used by return instruction) */
+ST_DATA int func_var; /* true if current function is variadic (used by return instruction) */
+ST_DATA int func_vc;
+ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
+ST_DATA const char *funcname;
+ST_DATA int g_debug;
+
+ST_DATA CType char_pointer_type, func_old_type, int_type, size_type, ptrdiff_type;
+
+ST_DATA struct switch_t {
+    struct case_t {
+        int64_t v1, v2;
+	int sym;
+    } **p; int n; /* list of case ranges */
+    int def_sym; /* default symbol */
+} *cur_switch; /* current switch */
+
+/* ------------------------------------------------------------------------- */
+
+static void gen_cast(CType *type);
+static void gen_cast_s(int t);
+static inline CType *pointed_type(CType *type);
+static int is_compatible_types(CType *type1, CType *type2);
+static int parse_btype(CType *type, AttributeDef *ad);
+static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td);
+static void parse_expr_type(CType *type);
+static void init_putv(CType *type, Section *sec, unsigned long c);
+static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
+static void block(int *bsym, int *csym, int is_expr);
+static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
+static void decl(int l);
+static int decl0(int l, int is_for_loop_init, Sym *);
+static void expr_eq(void);
+static void vla_runtime_type_size(CType *type, int *a);
+static void vla_sp_restore(void);
+static void vla_sp_restore_root(void);
+static int is_compatible_unqualified_types(CType *type1, CType *type2);
+static inline int64_t expr_const64(void);
+static void vpush64(int ty, unsigned long long v);
+static void vpush(CType *type);
+static int gvtst(int inv, int t);
+static void gen_inline_functions(TCCState *s);
+static void skip_or_save_block(TokenString **str);
+static void gv_dup(void);
+
+ST_INLN int is_float(int t)
+{
+    int bt;
+    bt = t & VT_BTYPE;
+    return bt == VT_LDOUBLE || bt == VT_DOUBLE || bt == VT_FLOAT || bt == VT_QFLOAT;
+}
+
+/* we use our own 'finite' function to avoid potential problems with
+   non standard math libs */
+/* XXX: endianness dependent */
+ST_FUNC int ieee_finite(double d)
+{
+    int p[4];
+    memcpy(p, &d, sizeof(double));
+    return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
+}
+
+/* compiling intel long double natively */
+#if (defined __i386__ || defined __x86_64__) \
+    && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
+# define TCC_IS_NATIVE_387
+#endif
+
+ST_FUNC void test_lvalue(void)
+{
+    if (!(vtop->r & VT_LVAL))
+        expect("lvalue");
+}
+
+ST_FUNC void check_vstack(void)
+{
+    if (pvtop != vtop)
+        tcc_error("internal compiler error: vstack leak (%d)", vtop - pvtop);
+}
+
+/* ------------------------------------------------------------------------- */
+/* vstack debugging aid */
+
+#if 0
+void pv (const char *lbl, int a, int b)
+{
+    int i;
+    for (i = a; i < a + b; ++i) {
+        SValue *p = &vtop[-i];
+        printf("%s vtop[-%d] : type.t:%04x  r:%04x  r2:%04x  c.i:%d\n",
+            lbl, i, p->type.t, p->r, p->r2, (int)p->c.i);
+    }
+}
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* start of translation unit info */
+ST_FUNC void tcc_debug_start(TCCState *s1)
+{
+    if (s1->do_debug) {
+        char buf[512];
+
+        /* file info: full path + filename */
+        section_sym = put_elf_sym(symtab_section, 0, 0,
+                                  ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
+                                  text_section->sh_num, NULL);
+        getcwd(buf, sizeof(buf));
+#ifdef _WIN32
+        normalize_slashes(buf);
+#endif
+        pstrcat(buf, sizeof(buf), "/");
+        put_stabs_r(buf, N_SO, 0, 0,
+                    text_section->data_offset, text_section, section_sym);
+        put_stabs_r(file->filename, N_SO, 0, 0,
+                    text_section->data_offset, text_section, section_sym);
+        last_ind = 0;
+        last_line_num = 0;
+    }
+
+    /* an elf symbol of type STT_FILE must be put so that STB_LOCAL
+       symbols can be safely used */
+    put_elf_sym(symtab_section, 0, 0,
+                ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
+                SHN_ABS, file->filename);
+}
+
+/* put end of translation unit info */
+ST_FUNC void tcc_debug_end(TCCState *s1)
+{
+    if (!s1->do_debug)
+        return;
+    put_stabs_r(NULL, N_SO, 0, 0,
+        text_section->data_offset, text_section, section_sym);
+
+}
+
+/* generate line number info */
+ST_FUNC void tcc_debug_line(TCCState *s1)
+{
+    if (!s1->do_debug)
+        return;
+    if ((last_line_num != file->line_num || last_ind != ind)) {
+        put_stabn(N_SLINE, 0, file->line_num, ind - func_ind);
+        last_ind = ind;
+        last_line_num = file->line_num;
+    }
+}
+
+/* put function symbol */
+ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym)
+{
+    char buf[512];
+
+    if (!s1->do_debug)
+        return;
+
+    /* stabs info */
+    /* XXX: we put here a dummy type */
+    snprintf(buf, sizeof(buf), "%s:%c1",
+             funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
+    put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
+                cur_text_section, sym->c);
+    /* //gr gdb wants a line at the function */
+    put_stabn(N_SLINE, 0, file->line_num, 0);
+
+    last_ind = 0;
+    last_line_num = 0;
+}
+
+/* put function size */
+ST_FUNC void tcc_debug_funcend(TCCState *s1, int size)
+{
+    if (!s1->do_debug)
+        return;
+    put_stabn(N_FUN, 0, 0, size);
+}
+
+/* ------------------------------------------------------------------------- */
+ST_FUNC int tccgen_compile(TCCState *s1)
+{
+    cur_text_section = NULL;
+    funcname = "";
+    anon_sym = SYM_FIRST_ANOM;
+    section_sym = 0;
+    const_wanted = 0;
+    nocode_wanted = 0x80000000;
+
+    /* define some often used types */
+    int_type.t = VT_INT;
+    char_pointer_type.t = VT_BYTE;
+    mk_pointer(&char_pointer_type);
+#if PTR_SIZE == 4
+    size_type.t = VT_INT | VT_UNSIGNED;
+    ptrdiff_type.t = VT_INT;
+#elif LONG_SIZE == 4
+    size_type.t = VT_LLONG | VT_UNSIGNED;
+    ptrdiff_type.t = VT_LLONG;
+#else
+    size_type.t = VT_LONG | VT_LLONG | VT_UNSIGNED;
+    ptrdiff_type.t = VT_LONG | VT_LLONG;
+#endif
+    func_old_type.t = VT_FUNC;
+    func_old_type.ref = sym_push(SYM_FIELD, &int_type, 0, 0);
+    func_old_type.ref->f.func_call = FUNC_CDECL;
+    func_old_type.ref->f.func_type = FUNC_OLD;
+
+    tcc_debug_start(s1);
+
+#ifdef TCC_TARGET_ARM
+    arm_init(s1);
+#endif
+
+#ifdef INC_DEBUG
+    printf("%s: **** new file\n", file->filename);
+#endif
+
+    parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR;
+    next();
+    decl(VT_CONST);
+    gen_inline_functions(s1);
+    check_vstack();
+    /* end of translation unit info */
+    tcc_debug_end(s1);
+    return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+ST_FUNC ElfSym *elfsym(Sym *s)
+{
+  if (!s || !s->c)
+    return NULL;
+  return &((ElfSym *)symtab_section->data)[s->c];
+}
+
+/* apply storage attributes to Elf symbol */
+ST_FUNC void update_storage(Sym *sym)
+{
+    ElfSym *esym;
+    int sym_bind, old_sym_bind;
+
+    esym = elfsym(sym);
+    if (!esym)
+        return;
+
+    if (sym->a.visibility)
+        esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
+            | sym->a.visibility;
+
+    if (sym->type.t & VT_STATIC)
+        sym_bind = STB_LOCAL;
+    else if (sym->a.weak)
+        sym_bind = STB_WEAK;
+    else
+        sym_bind = STB_GLOBAL;
+    old_sym_bind = ELFW(ST_BIND)(esym->st_info);
+    if (sym_bind != old_sym_bind) {
+        esym->st_info = ELFW(ST_INFO)(sym_bind, ELFW(ST_TYPE)(esym->st_info));
+    }
+
+#ifdef TCC_TARGET_PE
+    if (sym->a.dllimport)
+        esym->st_other |= ST_PE_IMPORT;
+    if (sym->a.dllexport)
+        esym->st_other |= ST_PE_EXPORT;
+#endif
+
+#if 0
+    printf("storage %s: bind=%c vis=%d exp=%d imp=%d\n",
+        get_tok_str(sym->v, NULL),
+        sym_bind == STB_WEAK ? 'w' : sym_bind == STB_LOCAL ? 'l' : 'g',
+        sym->a.visibility,
+        sym->a.dllexport,
+        sym->a.dllimport
+        );
+#endif
+}
+
+/* ------------------------------------------------------------------------- */
+/* update sym->c so that it points to an external symbol in section
+   'section' with value 'value' */
+
+ST_FUNC void put_extern_sym2(Sym *sym, int sh_num,
+                            addr_t value, unsigned long size,
+                            int can_add_underscore)
+{
+    int sym_type, sym_bind, info, other, t;
+    ElfSym *esym;
+    const char *name;
+    char buf1[256];
+#ifdef CONFIG_TCC_BCHECK
+    char buf[32];
+#endif
+
+    if (!sym->c) {
+        name = get_tok_str(sym->v, NULL);
+#ifdef CONFIG_TCC_BCHECK
+        if (tcc_state->do_bounds_check) {
+            /* XXX: avoid doing that for statics ? */
+            /* if bound checking is activated, we change some function
+               names by adding the "__bound" prefix */
+            switch(sym->v) {
+#ifdef TCC_TARGET_PE
+            /* XXX: we rely only on malloc hooks */
+            case TOK_malloc:
+            case TOK_free:
+            case TOK_realloc:
+            case TOK_memalign:
+            case TOK_calloc:
+#endif
+            case TOK_memcpy:
+            case TOK_memmove:
+            case TOK_memset:
+            case TOK_strlen:
+            case TOK_strcpy:
+            case TOK_alloca:
+                strcpy(buf, "__bound_");
+                strcat(buf, name);
+                name = buf;
+                break;
+            }
+        }
+#endif
+        t = sym->type.t;
+        if ((t & VT_BTYPE) == VT_FUNC) {
+            sym_type = STT_FUNC;
+        } else if ((t & VT_BTYPE) == VT_VOID) {
+            sym_type = STT_NOTYPE;
+        } else {
+            sym_type = STT_OBJECT;
+        }
+        if (t & VT_STATIC)
+            sym_bind = STB_LOCAL;
+        else
+            sym_bind = STB_GLOBAL;
+        other = 0;
+#ifdef TCC_TARGET_PE
+        if (sym_type == STT_FUNC && sym->type.ref) {
+            Sym *ref = sym->type.ref;
+            if (ref->f.func_call == FUNC_STDCALL && can_add_underscore) {
+                sprintf(buf1, "_%s@%d", name, ref->f.func_args * PTR_SIZE);
+                name = buf1;
+                other |= ST_PE_STDCALL;
+                can_add_underscore = 0;
+            }
+        }
+#endif
+        if (tcc_state->leading_underscore && can_add_underscore) {
+            buf1[0] = '_';
+            pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
+            name = buf1;
+        }
+        if (sym->asm_label)
+            name = get_tok_str(sym->asm_label, NULL);
+        info = ELFW(ST_INFO)(sym_bind, sym_type);
+        sym->c = put_elf_sym(symtab_section, value, size, info, other, sh_num, name);
+    } else {
+        esym = elfsym(sym);
+        esym->st_value = value;
+        esym->st_size = size;
+        esym->st_shndx = sh_num;
+    }
+    update_storage(sym);
+}
+
+ST_FUNC void put_extern_sym(Sym *sym, Section *section,
+                           addr_t value, unsigned long size)
+{
+    int sh_num = section ? section->sh_num : SHN_UNDEF;
+    put_extern_sym2(sym, sh_num, value, size, 1);
+}
+
+/* add a new relocation entry to symbol 'sym' in section 's' */
+ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type,
+                     addr_t addend)
+{
+    int c = 0;
+
+    if (nocode_wanted && s == cur_text_section)
+        return;
+
+    if (sym) {
+        if (0 == sym->c)
+            put_extern_sym(sym, NULL, 0, 0);
+        c = sym->c;
+    }
+
+    /* now we can add ELF relocation info */
+    put_elf_reloca(symtab_section, s, offset, type, c, addend);
+}
+
+#if PTR_SIZE == 4
+ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
+{
+    greloca(s, sym, offset, type, 0);
+}
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* symbol allocator */
+static Sym *__sym_malloc(void)
+{
+    Sym *sym_pool, *sym, *last_sym;
+    int i;
+
+    sym_pool = tcc_malloc(SYM_POOL_NB * sizeof(Sym));
+    dynarray_add(&sym_pools, &nb_sym_pools, sym_pool);
+
+    last_sym = sym_free_first;
+    sym = sym_pool;
+    for(i = 0; i < SYM_POOL_NB; i++) {
+        sym->next = last_sym;
+        last_sym = sym;
+        sym++;
+    }
+    sym_free_first = last_sym;
+    return last_sym;
+}
+
+static inline Sym *sym_malloc(void)
+{
+    Sym *sym;
+#ifndef SYM_DEBUG
+    sym = sym_free_first;
+    if (!sym)
+        sym = __sym_malloc();
+    sym_free_first = sym->next;
+    return sym;
+#else
+    sym = tcc_malloc(sizeof(Sym));
+    return sym;
+#endif
+}
+
+ST_INLN void sym_free(Sym *sym)
+{
+#ifndef SYM_DEBUG
+    sym->next = sym_free_first;
+    sym_free_first = sym;
+#else
+    tcc_free(sym);
+#endif
+}
+
+/* push, without hashing */
+ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, int c)
+{
+    Sym *s;
+
+    s = sym_malloc();
+    memset(s, 0, sizeof *s);
+    s->v = v;
+    s->type.t = t;
+    s->c = c;
+    /* add in stack */
+    s->prev = *ps;
+    *ps = s;
+    return s;
+}
+
+/* find a symbol and return its associated structure. 's' is the top
+   of the symbol stack */
+ST_FUNC Sym *sym_find2(Sym *s, int v)
+{
+    while (s) {
+        if (s->v == v)
+            return s;
+        else if (s->v == -1)
+            return NULL;
+        s = s->prev;
+    }
+    return NULL;
+}
+
+/* structure lookup */
+ST_INLN Sym *struct_find(int v)
+{
+    v -= TOK_IDENT;
+    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
+        return NULL;
+    return table_ident[v]->sym_struct;
+}
+
+/* find an identifier */
+ST_INLN Sym *sym_find(int v)
+{
+    v -= TOK_IDENT;
+    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
+        return NULL;
+    return table_ident[v]->sym_identifier;
+}
+
+/* push a given symbol on the symbol stack */
+ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
+{
+    Sym *s, **ps;
+    TokenSym *ts;
+
+    if (local_stack)
+        ps = &local_stack;
+    else
+        ps = &global_stack;
+    s = sym_push2(ps, v, type->t, c);
+    s->type.ref = type->ref;
+    s->r = r;
+    /* don't record fields or anonymous symbols */
+    /* XXX: simplify */
+    if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
+        /* record symbol in token array */
+        ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
+        if (v & SYM_STRUCT)
+            ps = &ts->sym_struct;
+        else
+            ps = &ts->sym_identifier;
+        s->prev_tok = *ps;
+        *ps = s;
+        s->sym_scope = local_scope;
+        if (s->prev_tok && s->prev_tok->sym_scope == s->sym_scope)
+            tcc_error("redeclaration of '%s'",
+                get_tok_str(v & ~SYM_STRUCT, NULL));
+    }
+    return s;
+}
+
+/* push a global identifier */
+ST_FUNC Sym *global_identifier_push(int v, int t, int c)
+{
+    Sym *s, **ps;
+    s = sym_push2(&global_stack, v, t, c);
+    /* don't record anonymous symbol */
+    if (v < SYM_FIRST_ANOM) {
+        ps = &table_ident[v - TOK_IDENT]->sym_identifier;
+        /* modify the top most local identifier, so that
+           sym_identifier will point to 's' when popped */
+        while (*ps != NULL && (*ps)->sym_scope)
+            ps = &(*ps)->prev_tok;
+        s->prev_tok = *ps;
+        *ps = s;
+    }
+    return s;
+}
+
+/* pop symbols until top reaches 'b'.  If KEEP is non-zero don't really
+   pop them yet from the list, but do remove them from the token array.  */
+ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep)
+{
+    Sym *s, *ss, **ps;
+    TokenSym *ts;
+    int v;
+
+    s = *ptop;
+    while(s != b) {
+        ss = s->prev;
+        v = s->v;
+        /* remove symbol in token array */
+        /* XXX: simplify */
+        if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
+            ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
+            if (v & SYM_STRUCT)
+                ps = &ts->sym_struct;
+            else
+                ps = &ts->sym_identifier;
+            *ps = s->prev_tok;
+        }
+	if (!keep)
+	    sym_free(s);
+        s = ss;
+    }
+    if (!keep)
+	*ptop = b;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void vsetc(CType *type, int r, CValue *vc)
+{
+    int v;
+
+    if (vtop >= vstack + (VSTACK_SIZE - 1))
+        tcc_error("memory full (vstack)");
+    /* cannot let cpu flags if other instruction are generated. Also
+       avoid leaving VT_JMP anywhere except on the top of the stack
+       because it would complicate the code generator.
+
+       Don't do this when nocode_wanted.  vtop might come from
+       !nocode_wanted regions (see 88_codeopt.c) and transforming
+       it to a register without actually generating code is wrong
+       as their value might still be used for real.  All values
+       we push under nocode_wanted will eventually be popped
+       again, so that the VT_CMP/VT_JMP value will be in vtop
+       when code is unsuppressed again.
+
+       Same logic below in vswap(); */
+    if (vtop >= vstack && !nocode_wanted) {
+        v = vtop->r & VT_VALMASK;
+        if (v == VT_CMP || (v & ~1) == VT_JMP)
+            gv(RC_INT);
+    }
+
+    vtop++;
+    vtop->type = *type;
+    vtop->r = r;
+    vtop->r2 = VT_CONST;
+    vtop->c = *vc;
+    vtop->sym = NULL;
+}
+
+ST_FUNC void vswap(void)
+{
+    SValue tmp;
+    /* cannot vswap cpu flags. See comment at vsetc() above */
+    if (vtop >= vstack && !nocode_wanted) {
+        int v = vtop->r & VT_VALMASK;
+        if (v == VT_CMP || (v & ~1) == VT_JMP)
+            gv(RC_INT);
+    }
+    tmp = vtop[0];
+    vtop[0] = vtop[-1];
+    vtop[-1] = tmp;
+}
+
+/* pop stack value */
+ST_FUNC void vpop(void)
+{
+    int v;
+    v = vtop->r & VT_VALMASK;
+#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
+    /* for x86, we need to pop the FP stack */
+    if (v == TREG_ST0) {
+        o(0xd8dd); /* fstp %st(0) */
+    } else
+#endif
+    if (v == VT_JMP || v == VT_JMPI) {
+        /* need to put correct jump if && or || without test */
+        gsym(vtop->c.i);
+    }
+    vtop--;
+}
+
+/* push constant of type "type" with useless value */
+ST_FUNC void vpush(CType *type)
+{
+    vset(type, VT_CONST, 0);
+}
+
+/* push integer constant */
+ST_FUNC void vpushi(int v)
+{
+    CValue cval;
+    cval.i = v;
+    vsetc(&int_type, VT_CONST, &cval);
+}
+
+/* push a pointer sized constant */
+static void vpushs(addr_t v)
+{
+  CValue cval;
+  cval.i = v;
+  vsetc(&size_type, VT_CONST, &cval);
+}
+
+/* push arbitrary 64bit constant */
+ST_FUNC void vpush64(int ty, unsigned long long v)
+{
+    CValue cval;
+    CType ctype;
+    ctype.t = ty;
+    ctype.ref = NULL;
+    cval.i = v;
+    vsetc(&ctype, VT_CONST, &cval);
+}
+
+/* push long long constant */
+static inline void vpushll(long long v)
+{
+    vpush64(VT_LLONG, v);
+}
+
+ST_FUNC void vset(CType *type, int r, int v)
+{
+    CValue cval;
+
+    cval.i = v;
+    vsetc(type, r, &cval);
+}
+
+static void vseti(int r, int v)
+{
+    CType type;
+    type.t = VT_INT;
+    type.ref = NULL;
+    vset(&type, r, v);
+}
+
+ST_FUNC void vpushv(SValue *v)
+{
+    if (vtop >= vstack + (VSTACK_SIZE - 1))
+        tcc_error("memory full (vstack)");
+    vtop++;
+    *vtop = *v;
+}
+
+static void vdup(void)
+{
+    vpushv(vtop);
+}
+
+/* rotate n first stack elements to the bottom
+   I1 ... In -> I2 ... In I1 [top is right]
+*/
+ST_FUNC void vrotb(int n)
+{
+    int i;
+    SValue tmp;
+
+    tmp = vtop[-n + 1];
+    for(i=-n+1;i!=0;i++)
+        vtop[i] = vtop[i+1];
+    vtop[0] = tmp;
+}
+
+/* rotate the n elements before entry e towards the top
+   I1 ... In ... -> In I1 ... I(n-1) ... [top is right]
+ */
+ST_FUNC void vrote(SValue *e, int n)
+{
+    int i;
+    SValue tmp;
+
+    tmp = *e;
+    for(i = 0;i < n - 1; i++)
+        e[-i] = e[-i - 1];
+    e[-n + 1] = tmp;
+}
+
+/* rotate n first stack elements to the top
+   I1 ... In -> In I1 ... I(n-1)  [top is right]
+ */
+ST_FUNC void vrott(int n)
+{
+    vrote(vtop, n);
+}
+
+/* push a symbol value of TYPE */
+static inline void vpushsym(CType *type, Sym *sym)
+{
+    CValue cval;
+    cval.i = 0;
+    vsetc(type, VT_CONST | VT_SYM, &cval);
+    vtop->sym = sym;
+}
+
+/* Return a static symbol pointing to a section */
+ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
+{
+    int v;
+    Sym *sym;
+
+    v = anon_sym++;
+    sym = global_identifier_push(v, type->t | VT_STATIC, 0);
+    sym->type.ref = type->ref;
+    sym->r = VT_CONST | VT_SYM;
+    put_extern_sym(sym, sec, offset, size);
+    return sym;
+}
+
+/* push a reference to a section offset by adding a dummy symbol */
+static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
+{
+    vpushsym(type, get_sym_ref(type, sec, offset, size));  
+}
+
+/* define a new external reference to a symbol 'v' of type 'u' */
+ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
+{
+    Sym *s;
+
+    s = sym_find(v);
+    if (!s) {
+        /* push forward reference */
+        s = global_identifier_push(v, type->t | VT_EXTERN, 0);
+        s->type.ref = type->ref;
+        s->r = r | VT_CONST | VT_SYM;
+    } else if (IS_ASM_SYM(s)) {
+        s->type.t = type->t | (s->type.t & VT_EXTERN);
+        s->type.ref = type->ref;
+        update_storage(s);
+    }
+    return s;
+}
+
+/* Merge some type attributes.  */
+static void patch_type(Sym *sym, CType *type)
+{
+    if (!(type->t & VT_EXTERN)) {
+        if (!(sym->type.t & VT_EXTERN))
+            tcc_error("redefinition of '%s'", get_tok_str(sym->v, NULL));
+        sym->type.t &= ~VT_EXTERN;
+    }
+
+    if (IS_ASM_SYM(sym)) {
+        /* stay static if both are static */
+        sym->type.t = type->t & (sym->type.t | ~VT_STATIC);
+        sym->type.ref = type->ref;
+    }
+
+    if (!is_compatible_types(&sym->type, type)) {
+        tcc_error("incompatible types for redefinition of '%s'",
+                  get_tok_str(sym->v, NULL));
+
+    } else if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
+        int static_proto = sym->type.t & VT_STATIC;
+        /* warn if static follows non-static function declaration */
+        if ((type->t & VT_STATIC) && !static_proto && !(type->t & VT_INLINE))
+            tcc_warning("static storage ignored for redefinition of '%s'",
+                get_tok_str(sym->v, NULL));
+
+        if (0 == (type->t & VT_EXTERN)) {
+            /* put complete type, use static from prototype */
+            sym->type.t = (type->t & ~VT_STATIC) | static_proto;
+            if (type->t & VT_INLINE)
+                sym->type.t = type->t;
+            sym->type.ref = type->ref;
+        }
+
+    } else {
+        if ((sym->type.t & VT_ARRAY) && type->ref->c >= 0) {
+            /* set array size if it was omitted in extern declaration */
+            if (sym->type.ref->c < 0)
+                sym->type.ref->c = type->ref->c;
+            else if (sym->type.ref->c != type->ref->c)
+                tcc_error("conflicting type for '%s'", get_tok_str(sym->v, NULL));
+        }
+        if ((type->t ^ sym->type.t) & VT_STATIC)
+            tcc_warning("storage mismatch for redefinition of '%s'",
+                get_tok_str(sym->v, NULL));
+    }
+}
+
+
+/* Merge some storage attributes.  */
+static void patch_storage(Sym *sym, AttributeDef *ad, CType *type)
+{
+    if (type)
+        patch_type(sym, type);
+
+#ifdef TCC_TARGET_PE
+    if (sym->a.dllimport != ad->a.dllimport)
+        tcc_error("incompatible dll linkage for redefinition of '%s'",
+            get_tok_str(sym->v, NULL));
+    sym->a.dllexport |= ad->a.dllexport;
+#endif
+    sym->a.weak |= ad->a.weak;
+    if (ad->a.visibility) {
+        int vis = sym->a.visibility;
+        int vis2 = ad->a.visibility;
+        if (vis == STV_DEFAULT)
+            vis = vis2;
+        else if (vis2 != STV_DEFAULT)
+            vis = (vis < vis2) ? vis : vis2;
+        sym->a.visibility = vis;
+    }
+    if (ad->a.aligned)
+        sym->a.aligned = ad->a.aligned;
+    if (ad->asm_label)
+        sym->asm_label = ad->asm_label;
+    update_storage(sym);
+}
+
+/* define a new external reference to a symbol 'v' */
+static Sym *external_sym(int v, CType *type, int r, AttributeDef *ad)
+{
+    Sym *s;
+    s = sym_find(v);
+    if (!s) {
+        /* push forward reference */
+        s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
+        s->type.t |= VT_EXTERN;
+        s->a = ad->a;
+        s->sym_scope = 0;
+    } else {
+        if (s->type.ref == func_old_type.ref) {
+            s->type.ref = type->ref;
+            s->r = r | VT_CONST | VT_SYM;
+            s->type.t |= VT_EXTERN;
+        }
+        patch_storage(s, ad, type);
+    }
+    return s;
+}
+
+/* push a reference to global symbol v */
+ST_FUNC void vpush_global_sym(CType *type, int v)
+{
+    vpushsym(type, external_global_sym(v, type, 0));
+}
+
+/* save registers up to (vtop - n) stack entry */
+ST_FUNC void save_regs(int n)
+{
+    SValue *p, *p1;
+    for(p = vstack, p1 = vtop - n; p <= p1; p++)
+        save_reg(p->r);
+}
+
+/* save r to the memory stack, and mark it as being free */
+ST_FUNC void save_reg(int r)
+{
+    save_reg_upstack(r, 0);
+}
+
+/* save r to the memory stack, and mark it as being free,
+   if seen up to (vtop - n) stack entry */
+ST_FUNC void save_reg_upstack(int r, int n)
+{
+    int l, saved, size, align;
+    SValue *p, *p1, sv;
+    CType *type;
+
+    if ((r &= VT_VALMASK) >= VT_CONST)
+        return;
+    if (nocode_wanted)
+        return;
+
+    /* modify all stack values */
+    saved = 0;
+    l = 0;
+    for(p = vstack, p1 = vtop - n; p <= p1; p++) {
+        if ((p->r & VT_VALMASK) == r ||
+            ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) {
+            /* must save value on stack if not already done */
+            if (!saved) {
+                /* NOTE: must reload 'r' because r might be equal to r2 */
+                r = p->r & VT_VALMASK;
+                /* store register in the stack */
+                type = &p->type;
+                if ((p->r & VT_LVAL) ||
+                    (!is_float(type->t) && (type->t & VT_BTYPE) != VT_LLONG))
+#if PTR_SIZE == 8
+                    type = &char_pointer_type;
+#else
+                    type = &int_type;
+#endif
+                size = type_size(type, &align);
+                loc = (loc - size) & -align;
+                sv.type.t = type->t;
+                sv.r = VT_LOCAL | VT_LVAL;
+                sv.c.i = loc;
+                store(r, &sv);
+#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
+                /* x86 specific: need to pop fp register ST0 if saved */
+                if (r == TREG_ST0) {
+                    o(0xd8dd); /* fstp %st(0) */
+                }
+#endif
+#if PTR_SIZE == 4
+                /* special long long case */
+                if ((type->t & VT_BTYPE) == VT_LLONG) {
+                    sv.c.i += 4;
+                    store(p->r2, &sv);
+                }
+#endif
+                l = loc;
+                saved = 1;
+            }
+            /* mark that stack entry as being saved on the stack */
+            if (p->r & VT_LVAL) {
+                /* also clear the bounded flag because the
+                   relocation address of the function was stored in
+                   p->c.i */
+                p->r = (p->r & ~(VT_VALMASK | VT_BOUNDED)) | VT_LLOCAL;
+            } else {
+                p->r = lvalue_type(p->type.t) | VT_LOCAL;
+            }
+            p->r2 = VT_CONST;
+            p->c.i = l;
+        }
+    }
+}
+
+#ifdef TCC_TARGET_ARM
+/* find a register of class 'rc2' with at most one reference on stack.
+ * If none, call get_reg(rc) */
+ST_FUNC int get_reg_ex(int rc, int rc2)
+{
+    int r;
+    SValue *p;
+    
+    for(r=0;r<NB_REGS;r++) {
+        if (reg_classes[r] & rc2) {
+            int n;
+            n=0;
+            for(p = vstack; p <= vtop; p++) {
+                if ((p->r & VT_VALMASK) == r ||
+                    (p->r2 & VT_VALMASK) == r)
+                    n++;
+            }
+            if (n <= 1)
+                return r;
+        }
+    }
+    return get_reg(rc);
+}
+#endif
+
+/* find a free register of class 'rc'. If none, save one register */
+ST_FUNC int get_reg(int rc)
+{
+    int r;
+    SValue *p;
+
+    /* find a free register */
+    for(r=0;r<NB_REGS;r++) {
+        if (reg_classes[r] & rc) {
+            if (nocode_wanted)
+                return r;
+            for(p=vstack;p<=vtop;p++) {
+                if ((p->r & VT_VALMASK) == r ||
+                    (p->r2 & VT_VALMASK) == r)
+                    goto notfound;
+            }
+            return r;
+        }
+    notfound: ;
+    }
+    
+    /* no register left : free the first one on the stack (VERY
+       IMPORTANT to start from the bottom to ensure that we don't
+       spill registers used in gen_opi()) */
+    for(p=vstack;p<=vtop;p++) {
+        /* look at second register (if long long) */
+        r = p->r2 & VT_VALMASK;
+        if (r < VT_CONST && (reg_classes[r] & rc))
+            goto save_found;
+        r = p->r & VT_VALMASK;
+        if (r < VT_CONST && (reg_classes[r] & rc)) {
+        save_found:
+            save_reg(r);
+            return r;
+        }
+    }
+    /* Should never comes here */
+    return -1;
+}
+
+/* move register 's' (of type 't') to 'r', and flush previous value of r to memory
+   if needed */
+static void move_reg(int r, int s, int t)
+{
+    SValue sv;
+
+    if (r != s) {
+        save_reg(r);
+        sv.type.t = t;
+        sv.type.ref = NULL;
+        sv.r = s;
+        sv.c.i = 0;
+        load(r, &sv);
+    }
+}
+
+/* get address of vtop (vtop MUST BE an lvalue) */
+ST_FUNC void gaddrof(void)
+{
+    vtop->r &= ~VT_LVAL;
+    /* tricky: if saved lvalue, then we can go back to lvalue */
+    if ((vtop->r & VT_VALMASK) == VT_LLOCAL)
+        vtop->r = (vtop->r & ~(VT_VALMASK | VT_LVAL_TYPE)) | VT_LOCAL | VT_LVAL;
+
+
+}
+
+#ifdef CONFIG_TCC_BCHECK
+/* generate lvalue bound code */
+static void gbound(void)
+{
+    int lval_type;
+    CType type1;
+
+    vtop->r &= ~VT_MUSTBOUND;
+    /* if lvalue, then use checking code before dereferencing */
+    if (vtop->r & VT_LVAL) {
+        /* if not VT_BOUNDED value, then make one */
+        if (!(vtop->r & VT_BOUNDED)) {
+            lval_type = vtop->r & (VT_LVAL_TYPE | VT_LVAL);
+            /* must save type because we must set it to int to get pointer */
+            type1 = vtop->type;
+            vtop->type.t = VT_PTR;
+            gaddrof();
+            vpushi(0);
+            gen_bounded_ptr_add();
+            vtop->r |= lval_type;
+            vtop->type = type1;
+        }
+        /* then check for dereferencing */
+        gen_bounded_ptr_deref();
+    }
+}
+#endif
+
+static void incr_bf_adr(int o)
+{
+    vtop->type = char_pointer_type;
+    gaddrof();
+    vpushi(o);
+    gen_op('+');
+    vtop->type.t = (vtop->type.t & ~(VT_BTYPE|VT_DEFSIGN))
+        | (VT_BYTE|VT_UNSIGNED);
+    vtop->r = (vtop->r & ~VT_LVAL_TYPE)
+        | (VT_LVAL_BYTE|VT_LVAL_UNSIGNED|VT_LVAL);
+}
+
+/* single-byte load mode for packed or otherwise unaligned bitfields */
+static void load_packed_bf(CType *type, int bit_pos, int bit_size)
+{
+    int n, o, bits;
+    save_reg_upstack(vtop->r, 1);
+    vpush64(type->t & VT_BTYPE, 0); // B X
+    bits = 0, o = bit_pos >> 3, bit_pos &= 7;
+    do {
+        vswap(); // X B
+        incr_bf_adr(o);
+        vdup(); // X B B
+        n = 8 - bit_pos;
+        if (n > bit_size)
+            n = bit_size;
+        if (bit_pos)
+            vpushi(bit_pos), gen_op(TOK_SHR), bit_pos = 0; // X B Y
+        if (n < 8)
+            vpushi((1 << n) - 1), gen_op('&');
+        gen_cast(type);
+        if (bits)
+            vpushi(bits), gen_op(TOK_SHL);
+        vrotb(3); // B Y X
+        gen_op('|'); // B X
+        bits += n, bit_size -= n, o = 1;
+    } while (bit_size);
+    vswap(), vpop();
+    if (!(type->t & VT_UNSIGNED)) {
+        n = ((type->t & VT_BTYPE) == VT_LLONG ? 64 : 32) - bits;
+        vpushi(n), gen_op(TOK_SHL);
+        vpushi(n), gen_op(TOK_SAR);
+    }
+}
+
+/* single-byte store mode for packed or otherwise unaligned bitfields */
+static void store_packed_bf(int bit_pos, int bit_size)
+{
+    int bits, n, o, m, c;
+
+    c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+    vswap(); // X B
+    save_reg_upstack(vtop->r, 1);
+    bits = 0, o = bit_pos >> 3, bit_pos &= 7;
+    do {
+        incr_bf_adr(o); // X B
+        vswap(); //B X
+        c ? vdup() : gv_dup(); // B V X
+        vrott(3); // X B V
+        if (bits)
+            vpushi(bits), gen_op(TOK_SHR);
+        if (bit_pos)
+            vpushi(bit_pos), gen_op(TOK_SHL);
+        n = 8 - bit_pos;
+        if (n > bit_size)
+            n = bit_size;
+        if (n < 8) {
+            m = ((1 << n) - 1) << bit_pos;
+            vpushi(m), gen_op('&'); // X B V1
+            vpushv(vtop-1); // X B V1 B
+            vpushi(m & 0x80 ? ~m & 0x7f : ~m);
+            gen_op('&'); // X B V1 B1
+            gen_op('|'); // X B V2
+        }
+        vdup(), vtop[-1] = vtop[-2]; // X B B V2
+        vstore(), vpop(); // X B
+        bits += n, bit_size -= n, bit_pos = 0, o = 1;
+    } while (bit_size);
+    vpop(), vpop();
+}
+
+static int adjust_bf(SValue *sv, int bit_pos, int bit_size)
+{
+    int t;
+    if (0 == sv->type.ref)
+        return 0;
+    t = sv->type.ref->auxtype;
+    if (t != -1 && t != VT_STRUCT) {
+        sv->type.t = (sv->type.t & ~VT_BTYPE) | t;
+        sv->r = (sv->r & ~VT_LVAL_TYPE) | lvalue_type(sv->type.t);
+    }
+    return t;
+}
+
+/* store vtop a register belonging to class 'rc'. lvalues are
+   converted to values. Cannot be used if cannot be converted to
+   register value (such as structures). */
+ST_FUNC int gv(int rc)
+{
+    int r, bit_pos, bit_size, size, align, rc2;
+
+    /* NOTE: get_reg can modify vstack[] */
+    if (vtop->type.t & VT_BITFIELD) {
+        CType type;
+
+        bit_pos = BIT_POS(vtop->type.t);
+        bit_size = BIT_SIZE(vtop->type.t);
+        /* remove bit field info to avoid loops */
+        vtop->type.t &= ~VT_STRUCT_MASK;
+
+        type.ref = NULL;
+        type.t = vtop->type.t & VT_UNSIGNED;
+        if ((vtop->type.t & VT_BTYPE) == VT_BOOL)
+            type.t |= VT_UNSIGNED;
+
+        r = adjust_bf(vtop, bit_pos, bit_size);
+
+        if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
+            type.t |= VT_LLONG;
+        else
+            type.t |= VT_INT;
+
+        if (r == VT_STRUCT) {
+            load_packed_bf(&type, bit_pos, bit_size);
+        } else {
+            int bits = (type.t & VT_BTYPE) == VT_LLONG ? 64 : 32;
+            /* cast to int to propagate signedness in following ops */
+            gen_cast(&type);
+            /* generate shifts */
+            vpushi(bits - (bit_pos + bit_size));
+            gen_op(TOK_SHL);
+            vpushi(bits - bit_size);
+            /* NOTE: transformed to SHR if unsigned */
+            gen_op(TOK_SAR);
+        }
+        r = gv(rc);
+    } else {
+        if (is_float(vtop->type.t) && 
+            (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+            unsigned long offset;
+            /* CPUs usually cannot use float constants, so we store them
+               generically in data segment */
+            size = type_size(&vtop->type, &align);
+            if (NODATA_WANTED)
+                size = 0, align = 1;
+            offset = section_add(data_section, size, align);
+            vpush_ref(&vtop->type, data_section, offset, size);
+	    vswap();
+	    init_putv(&vtop->type, data_section, offset);
+	    vtop->r |= VT_LVAL;
+        }
+#ifdef CONFIG_TCC_BCHECK
+        if (vtop->r & VT_MUSTBOUND) 
+            gbound();
+#endif
+
+        r = vtop->r & VT_VALMASK;
+        rc2 = (rc & RC_FLOAT) ? RC_FLOAT : RC_INT;
+#ifndef TCC_TARGET_ARM64
+        if (rc == RC_IRET)
+            rc2 = RC_LRET;
+#ifdef TCC_TARGET_X86_64
+        else if (rc == RC_FRET)
+            rc2 = RC_QRET;
+#endif
+#endif
+        /* need to reload if:
+           - constant
+           - lvalue (need to dereference pointer)
+           - already a register, but not in the right class */
+        if (r >= VT_CONST
+         || (vtop->r & VT_LVAL)
+         || !(reg_classes[r] & rc)
+#if PTR_SIZE == 8
+         || ((vtop->type.t & VT_BTYPE) == VT_QLONG && !(reg_classes[vtop->r2] & rc2))
+         || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT && !(reg_classes[vtop->r2] & rc2))
+#else
+         || ((vtop->type.t & VT_BTYPE) == VT_LLONG && !(reg_classes[vtop->r2] & rc2))
+#endif
+            )
+        {
+            r = get_reg(rc);
+#if PTR_SIZE == 8
+            if (((vtop->type.t & VT_BTYPE) == VT_QLONG) || ((vtop->type.t & VT_BTYPE) == VT_QFLOAT)) {
+                int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
+#else
+            if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
+                int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
+                unsigned long long ll;
+#endif
+                int r2, original_type;
+                original_type = vtop->type.t;
+                /* two register type load : expand to two words
+                   temporarily */
+#if PTR_SIZE == 4
+                if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+                    /* load constant */
+                    ll = vtop->c.i;
+                    vtop->c.i = ll; /* first word */
+                    load(r, vtop);
+                    vtop->r = r; /* save register value */
+                    vpushi(ll >> 32); /* second word */
+                } else
+#endif
+                if (vtop->r & VT_LVAL) {
+                    /* We do not want to modifier the long long
+                       pointer here, so the safest (and less
+                       efficient) is to save all the other registers
+                       in the stack. XXX: totally inefficient. */
+               #if 0
+                    save_regs(1);
+               #else
+                    /* lvalue_save: save only if used further down the stack */
+                    save_reg_upstack(vtop->r, 1);
+               #endif
+                    /* load from memory */
+                    vtop->type.t = load_type;
+                    load(r, vtop);
+                    vdup();
+                    vtop[-1].r = r; /* save register value */
+                    /* increment pointer to get second word */
+                    vtop->type.t = addr_type;
+                    gaddrof();
+                    vpushi(load_size);
+                    gen_op('+');
+                    vtop->r |= VT_LVAL;
+                    vtop->type.t = load_type;
+                } else {
+                    /* move registers */
+                    load(r, vtop);
+                    vdup();
+                    vtop[-1].r = r; /* save register value */
+                    vtop->r = vtop[-1].r2;
+                }
+                /* Allocate second register. Here we rely on the fact that
+                   get_reg() tries first to free r2 of an SValue. */
+                r2 = get_reg(rc2);
+                load(r2, vtop);
+                vpop();
+                /* write second register */
+                vtop->r2 = r2;
+                vtop->type.t = original_type;
+            } else if ((vtop->r & VT_LVAL) && !is_float(vtop->type.t)) {
+                int t1, t;
+                /* lvalue of scalar type : need to use lvalue type
+                   because of possible cast */
+                t = vtop->type.t;
+                t1 = t;
+                /* compute memory access type */
+                if (vtop->r & VT_LVAL_BYTE)
+                    t = VT_BYTE;
+                else if (vtop->r & VT_LVAL_SHORT)
+                    t = VT_SHORT;
+                if (vtop->r & VT_LVAL_UNSIGNED)
+                    t |= VT_UNSIGNED;
+                vtop->type.t = t;
+                load(r, vtop);
+                /* restore wanted type */
+                vtop->type.t = t1;
+            } else {
+                /* one register type load */
+                load(r, vtop);
+            }
+        }
+        vtop->r = r;
+#ifdef TCC_TARGET_C67
+        /* uses register pairs for doubles */
+        if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) 
+            vtop->r2 = r+1;
+#endif
+    }
+    return r;
+}
+
+/* generate vtop[-1] and vtop[0] in resp. classes rc1 and rc2 */
+ST_FUNC void gv2(int rc1, int rc2)
+{
+    int v;
+
+    /* generate more generic register first. But VT_JMP or VT_CMP
+       values must be generated first in all cases to avoid possible
+       reload errors */
+    v = vtop[0].r & VT_VALMASK;
+    if (v != VT_CMP && (v & ~1) != VT_JMP && rc1 <= rc2) {
+        vswap();
+        gv(rc1);
+        vswap();
+        gv(rc2);
+        /* test if reload is needed for first register */
+        if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
+            vswap();
+            gv(rc1);
+            vswap();
+        }
+    } else {
+        gv(rc2);
+        vswap();
+        gv(rc1);
+        vswap();
+        /* test if reload is needed for first register */
+        if ((vtop[0].r & VT_VALMASK) >= VT_CONST) {
+            gv(rc2);
+        }
+    }
+}
+
+#ifndef TCC_TARGET_ARM64
+/* wrapper around RC_FRET to return a register by type */
+static int rc_fret(int t)
+{
+#ifdef TCC_TARGET_X86_64
+    if (t == VT_LDOUBLE) {
+        return RC_ST0;
+    }
+#endif
+    return RC_FRET;
+}
+#endif
+
+/* wrapper around REG_FRET to return a register by type */
+static int reg_fret(int t)
+{
+#ifdef TCC_TARGET_X86_64
+    if (t == VT_LDOUBLE) {
+        return TREG_ST0;
+    }
+#endif
+    return REG_FRET;
+}
+
+#if PTR_SIZE == 4
+/* expand 64bit on stack in two ints */
+static void lexpand(void)
+{
+    int u, v;
+    u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
+    v = vtop->r & (VT_VALMASK | VT_LVAL);
+    if (v == VT_CONST) {
+        vdup();
+        vtop[0].c.i >>= 32;
+    } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
+        vdup();
+        vtop[0].c.i += 4;
+    } else {
+        gv(RC_INT);
+        vdup();
+        vtop[0].r = vtop[-1].r2;
+        vtop[0].r2 = vtop[-1].r2 = VT_CONST;
+    }
+    vtop[0].type.t = vtop[-1].type.t = VT_INT | u;
+}
+#endif
+
+#ifdef TCC_TARGET_ARM
+/* expand long long on stack */
+ST_FUNC void lexpand_nr(void)
+{
+    int u,v;
+
+    u = vtop->type.t & (VT_DEFSIGN | VT_UNSIGNED);
+    vdup();
+    vtop->r2 = VT_CONST;
+    vtop->type.t = VT_INT | u;
+    v=vtop[-1].r & (VT_VALMASK | VT_LVAL);
+    if (v == VT_CONST) {
+      vtop[-1].c.i = vtop->c.i;
+      vtop->c.i = vtop->c.i >> 32;
+      vtop->r = VT_CONST;
+    } else if (v == (VT_LVAL|VT_CONST) || v == (VT_LVAL|VT_LOCAL)) {
+      vtop->c.i += 4;
+      vtop->r = vtop[-1].r;
+    } else if (v > VT_CONST) {
+      vtop--;
+      lexpand();
+    } else
+      vtop->r = vtop[-1].r2;
+    vtop[-1].r2 = VT_CONST;
+    vtop[-1].type.t = VT_INT | u;
+}
+#endif
+
+#if PTR_SIZE == 4
+/* build a long long from two ints */
+static void lbuild(int t)
+{
+    gv2(RC_INT, RC_INT);
+    vtop[-1].r2 = vtop[0].r;
+    vtop[-1].type.t = t;
+    vpop();
+}
+#endif
+
+/* convert stack entry to register and duplicate its value in another
+   register */
+static void gv_dup(void)
+{
+    int rc, t, r, r1;
+    SValue sv;
+
+    t = vtop->type.t;
+#if PTR_SIZE == 4
+    if ((t & VT_BTYPE) == VT_LLONG) {
+        if (t & VT_BITFIELD) {
+            gv(RC_INT);
+            t = vtop->type.t;
+        }
+        lexpand();
+        gv_dup();
+        vswap();
+        vrotb(3);
+        gv_dup();
+        vrotb(4);
+        /* stack: H L L1 H1 */
+        lbuild(t);
+        vrotb(3);
+        vrotb(3);
+        vswap();
+        lbuild(t);
+        vswap();
+    } else
+#endif
+    {
+        /* duplicate value */
+        rc = RC_INT;
+        sv.type.t = VT_INT;
+        if (is_float(t)) {
+            rc = RC_FLOAT;
+#ifdef TCC_TARGET_X86_64
+            if ((t & VT_BTYPE) == VT_LDOUBLE) {
+                rc = RC_ST0;
+            }
+#endif
+            sv.type.t = t;
+        }
+        r = gv(rc);
+        r1 = get_reg(rc);
+        sv.r = r;
+        sv.c.i = 0;
+        load(r1, &sv); /* move r to r1 */
+        vdup();
+        /* duplicates value */
+        if (r != r1)
+            vtop->r = r1;
+    }
+}
+
+/* Generate value test
+ *
+ * Generate a test for any value (jump, comparison and integers) */
+ST_FUNC int gvtst(int inv, int t)
+{
+    int v = vtop->r & VT_VALMASK;
+    if (v != VT_CMP && v != VT_JMP && v != VT_JMPI) {
+        vpushi(0);
+        gen_op(TOK_NE);
+    }
+    if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+        /* constant jmp optimization */
+        if ((vtop->c.i != 0) != inv)
+            t = gjmp(t);
+        vtop--;
+        return t;
+    }
+    return gtst(inv, t);
+}
+
+#if PTR_SIZE == 4
+/* generate CPU independent (unsigned) long long operations */
+static void gen_opl(int op)
+{
+    int t, a, b, op1, c, i;
+    int func;
+    unsigned short reg_iret = REG_IRET;
+    unsigned short reg_lret = REG_LRET;
+    SValue tmp;
+
+    switch(op) {
+    case '/':
+    case TOK_PDIV:
+        func = TOK___divdi3;
+        goto gen_func;
+    case TOK_UDIV:
+        func = TOK___udivdi3;
+        goto gen_func;
+    case '%':
+        func = TOK___moddi3;
+        goto gen_mod_func;
+    case TOK_UMOD:
+        func = TOK___umoddi3;
+    gen_mod_func:
+#ifdef TCC_ARM_EABI
+        reg_iret = TREG_R2;
+        reg_lret = TREG_R3;
+#endif
+    gen_func:
+        /* call generic long long function */
+        vpush_global_sym(&func_old_type, func);
+        vrott(3);
+        gfunc_call(2);
+        vpushi(0);
+        vtop->r = reg_iret;
+        vtop->r2 = reg_lret;
+        break;
+    case '^':
+    case '&':
+    case '|':
+    case '*':
+    case '+':
+    case '-':
+        //pv("gen_opl A",0,2);
+        t = vtop->type.t;
+        vswap();
+        lexpand();
+        vrotb(3);
+        lexpand();
+        /* stack: L1 H1 L2 H2 */
+        tmp = vtop[0];
+        vtop[0] = vtop[-3];
+        vtop[-3] = tmp;
+        tmp = vtop[-2];
+        vtop[-2] = vtop[-3];
+        vtop[-3] = tmp;
+        vswap();
+        /* stack: H1 H2 L1 L2 */
+        //pv("gen_opl B",0,4);
+        if (op == '*') {
+            vpushv(vtop - 1);
+            vpushv(vtop - 1);
+            gen_op(TOK_UMULL);
+            lexpand();
+            /* stack: H1 H2 L1 L2 ML MH */
+            for(i=0;i<4;i++)
+                vrotb(6);
+            /* stack: ML MH H1 H2 L1 L2 */
+            tmp = vtop[0];
+            vtop[0] = vtop[-2];
+            vtop[-2] = tmp;
+            /* stack: ML MH H1 L2 H2 L1 */
+            gen_op('*');
+            vrotb(3);
+            vrotb(3);
+            gen_op('*');
+            /* stack: ML MH M1 M2 */
+            gen_op('+');
+            gen_op('+');
+        } else if (op == '+' || op == '-') {
+            /* XXX: add non carry method too (for MIPS or alpha) */
+            if (op == '+')
+                op1 = TOK_ADDC1;
+            else
+                op1 = TOK_SUBC1;
+            gen_op(op1);
+            /* stack: H1 H2 (L1 op L2) */
+            vrotb(3);
+            vrotb(3);
+            gen_op(op1 + 1); /* TOK_xxxC2 */
+        } else {
+            gen_op(op);
+            /* stack: H1 H2 (L1 op L2) */
+            vrotb(3);
+            vrotb(3);
+            /* stack: (L1 op L2) H1 H2 */
+            gen_op(op);
+            /* stack: (L1 op L2) (H1 op H2) */
+        }
+        /* stack: L H */
+        lbuild(t);
+        break;
+    case TOK_SAR:
+    case TOK_SHR:
+    case TOK_SHL:
+        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+            t = vtop[-1].type.t;
+            vswap();
+            lexpand();
+            vrotb(3);
+            /* stack: L H shift */
+            c = (int)vtop->c.i;
+            /* constant: simpler */
+            /* NOTE: all comments are for SHL. the other cases are
+               done by swapping words */
+            vpop();
+            if (op != TOK_SHL)
+                vswap();
+            if (c >= 32) {
+                /* stack: L H */
+                vpop();
+                if (c > 32) {
+                    vpushi(c - 32);
+                    gen_op(op);
+                }
+                if (op != TOK_SAR) {
+                    vpushi(0);
+                } else {
+                    gv_dup();
+                    vpushi(31);
+                    gen_op(TOK_SAR);
+                }
+                vswap();
+            } else {
+                vswap();
+                gv_dup();
+                /* stack: H L L */
+                vpushi(c);
+                gen_op(op);
+                vswap();
+                vpushi(32 - c);
+                if (op == TOK_SHL)
+                    gen_op(TOK_SHR);
+                else
+                    gen_op(TOK_SHL);
+                vrotb(3);
+                /* stack: L L H */
+                vpushi(c);
+                if (op == TOK_SHL)
+                    gen_op(TOK_SHL);
+                else
+                    gen_op(TOK_SHR);
+                gen_op('|');
+            }
+            if (op != TOK_SHL)
+                vswap();
+            lbuild(t);
+        } else {
+            /* XXX: should provide a faster fallback on x86 ? */
+            switch(op) {
+            case TOK_SAR:
+                func = TOK___ashrdi3;
+                goto gen_func;
+            case TOK_SHR:
+                func = TOK___lshrdi3;
+                goto gen_func;
+            case TOK_SHL:
+                func = TOK___ashldi3;
+                goto gen_func;
+            }
+        }
+        break;
+    default:
+        /* compare operations */
+        t = vtop->type.t;
+        vswap();
+        lexpand();
+        vrotb(3);
+        lexpand();
+        /* stack: L1 H1 L2 H2 */
+        tmp = vtop[-1];
+        vtop[-1] = vtop[-2];
+        vtop[-2] = tmp;
+        /* stack: L1 L2 H1 H2 */
+        /* compare high */
+        op1 = op;
+        /* when values are equal, we need to compare low words. since
+           the jump is inverted, we invert the test too. */
+        if (op1 == TOK_LT)
+            op1 = TOK_LE;
+        else if (op1 == TOK_GT)
+            op1 = TOK_GE;
+        else if (op1 == TOK_ULT)
+            op1 = TOK_ULE;
+        else if (op1 == TOK_UGT)
+            op1 = TOK_UGE;
+        a = 0;
+        b = 0;
+        gen_op(op1);
+        if (op == TOK_NE) {
+            b = gvtst(0, 0);
+        } else {
+            a = gvtst(1, 0);
+            if (op != TOK_EQ) {
+                /* generate non equal test */
+                vpushi(TOK_NE);
+                vtop->r = VT_CMP;
+                b = gvtst(0, 0);
+            }
+        }
+        /* compare low. Always unsigned */
+        op1 = op;
+        if (op1 == TOK_LT)
+            op1 = TOK_ULT;
+        else if (op1 == TOK_LE)
+            op1 = TOK_ULE;
+        else if (op1 == TOK_GT)
+            op1 = TOK_UGT;
+        else if (op1 == TOK_GE)
+            op1 = TOK_UGE;
+        gen_op(op1);
+        a = gvtst(1, a);
+        gsym(b);
+        vseti(VT_JMPI, a);
+        break;
+    }
+}
+#endif
+
+static uint64_t gen_opic_sdiv(uint64_t a, uint64_t b)
+{
+    uint64_t x = (a >> 63 ? -a : a) / (b >> 63 ? -b : b);
+    return (a ^ b) >> 63 ? -x : x;
+}
+
+static int gen_opic_lt(uint64_t a, uint64_t b)
+{
+    return (a ^ (uint64_t)1 << 63) < (b ^ (uint64_t)1 << 63);
+}
+
+/* handle integer constant optimizations and various machine
+   independent opt */
+static void gen_opic(int op)
+{
+    SValue *v1 = vtop - 1;
+    SValue *v2 = vtop;
+    int t1 = v1->type.t & VT_BTYPE;
+    int t2 = v2->type.t & VT_BTYPE;
+    int c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+    int c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+    uint64_t l1 = c1 ? v1->c.i : 0;
+    uint64_t l2 = c2 ? v2->c.i : 0;
+    int shm = (t1 == VT_LLONG) ? 63 : 31;
+
+    if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
+        l1 = ((uint32_t)l1 |
+              (v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
+    if (t2 != VT_LLONG && (PTR_SIZE != 8 || t2 != VT_PTR))
+        l2 = ((uint32_t)l2 |
+              (v2->type.t & VT_UNSIGNED ? 0 : -(l2 & 0x80000000)));
+
+    if (c1 && c2) {
+        switch(op) {
+        case '+': l1 += l2; break;
+        case '-': l1 -= l2; break;
+        case '&': l1 &= l2; break;
+        case '^': l1 ^= l2; break;
+        case '|': l1 |= l2; break;
+        case '*': l1 *= l2; break;
+
+        case TOK_PDIV:
+        case '/':
+        case '%':
+        case TOK_UDIV:
+        case TOK_UMOD:
+            /* if division by zero, generate explicit division */
+            if (l2 == 0) {
+                if (const_wanted)
+                    tcc_error("division by zero in constant");
+                goto general_case;
+            }
+            switch(op) {
+            default: l1 = gen_opic_sdiv(l1, l2); break;
+            case '%': l1 = l1 - l2 * gen_opic_sdiv(l1, l2); break;
+            case TOK_UDIV: l1 = l1 / l2; break;
+            case TOK_UMOD: l1 = l1 % l2; break;
+            }
+            break;
+        case TOK_SHL: l1 <<= (l2 & shm); break;
+        case TOK_SHR: l1 >>= (l2 & shm); break;
+        case TOK_SAR:
+            l1 = (l1 >> 63) ? ~(~l1 >> (l2 & shm)) : l1 >> (l2 & shm);
+            break;
+            /* tests */
+        case TOK_ULT: l1 = l1 < l2; break;
+        case TOK_UGE: l1 = l1 >= l2; break;
+        case TOK_EQ: l1 = l1 == l2; break;
+        case TOK_NE: l1 = l1 != l2; break;
+        case TOK_ULE: l1 = l1 <= l2; break;
+        case TOK_UGT: l1 = l1 > l2; break;
+        case TOK_LT: l1 = gen_opic_lt(l1, l2); break;
+        case TOK_GE: l1 = !gen_opic_lt(l1, l2); break;
+        case TOK_LE: l1 = !gen_opic_lt(l2, l1); break;
+        case TOK_GT: l1 = gen_opic_lt(l2, l1); break;
+            /* logical */
+        case TOK_LAND: l1 = l1 && l2; break;
+        case TOK_LOR: l1 = l1 || l2; break;
+        default:
+            goto general_case;
+        }
+	if (t1 != VT_LLONG && (PTR_SIZE != 8 || t1 != VT_PTR))
+	    l1 = ((uint32_t)l1 |
+		(v1->type.t & VT_UNSIGNED ? 0 : -(l1 & 0x80000000)));
+        v1->c.i = l1;
+        vtop--;
+    } else {
+        /* if commutative ops, put c2 as constant */
+        if (c1 && (op == '+' || op == '&' || op == '^' || 
+                   op == '|' || op == '*')) {
+            vswap();
+            c2 = c1; //c = c1, c1 = c2, c2 = c;
+            l2 = l1; //l = l1, l1 = l2, l2 = l;
+        }
+        if (!const_wanted &&
+            c1 && ((l1 == 0 &&
+                    (op == TOK_SHL || op == TOK_SHR || op == TOK_SAR)) ||
+                   (l1 == -1 && op == TOK_SAR))) {
+            /* treat (0 << x), (0 >> x) and (-1 >> x) as constant */
+            vtop--;
+        } else if (!const_wanted &&
+                   c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
+                          (op == '|' &&
+                            (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))) ||
+                          (l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
+            /* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
+            if (l2 == 1)
+                vtop->c.i = 0;
+            vswap();
+            vtop--;
+        } else if (c2 && (((op == '*' || op == '/' || op == TOK_UDIV ||
+                          op == TOK_PDIV) &&
+                           l2 == 1) ||
+                          ((op == '+' || op == '-' || op == '|' || op == '^' ||
+                            op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
+                           l2 == 0) ||
+                          (op == '&' &&
+                            (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))))) {
+            /* filter out NOP operations like x*1, x-0, x&-1... */
+            vtop--;
+        } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
+            /* try to use shifts instead of muls or divs */
+            if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
+                int n = -1;
+                while (l2) {
+                    l2 >>= 1;
+                    n++;
+                }
+                vtop->c.i = n;
+                if (op == '*')
+                    op = TOK_SHL;
+                else if (op == TOK_PDIV)
+                    op = TOK_SAR;
+                else
+                    op = TOK_SHR;
+            }
+            goto general_case;
+        } else if (c2 && (op == '+' || op == '-') &&
+                   (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM))
+                    || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) {
+            /* symbol + constant case */
+            if (op == '-')
+                l2 = -l2;
+	    l2 += vtop[-1].c.i;
+	    /* The backends can't always deal with addends to symbols
+	       larger than +-1<<31.  Don't construct such.  */
+	    if ((int)l2 != l2)
+	        goto general_case;
+            vtop--;
+            vtop->c.i = l2;
+        } else {
+        general_case:
+                /* call low level op generator */
+                if (t1 == VT_LLONG || t2 == VT_LLONG ||
+                    (PTR_SIZE == 8 && (t1 == VT_PTR || t2 == VT_PTR)))
+                    gen_opl(op);
+                else
+                    gen_opi(op);
+        }
+    }
+}
+
+/* generate a floating point operation with constant propagation */
+static void gen_opif(int op)
+{
+    int c1, c2;
+    SValue *v1, *v2;
+#if defined _MSC_VER && defined _AMD64_
+    /* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */
+    volatile
+#endif
+    long double f1, f2;
+
+    v1 = vtop - 1;
+    v2 = vtop;
+    /* currently, we cannot do computations with forward symbols */
+    c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+    c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+    if (c1 && c2) {
+        if (v1->type.t == VT_FLOAT) {
+            f1 = v1->c.f;
+            f2 = v2->c.f;
+        } else if (v1->type.t == VT_DOUBLE) {
+            f1 = v1->c.d;
+            f2 = v2->c.d;
+        } else {
+            f1 = v1->c.ld;
+            f2 = v2->c.ld;
+        }
+
+        /* NOTE: we only do constant propagation if finite number (not
+           NaN or infinity) (ANSI spec) */
+        if (!ieee_finite(f1) || !ieee_finite(f2))
+            goto general_case;
+
+        switch(op) {
+        case '+': f1 += f2; break;
+        case '-': f1 -= f2; break;
+        case '*': f1 *= f2; break;
+        case '/': 
+            if (f2 == 0.0) {
+                if (const_wanted)
+                    tcc_error("division by zero in constant");
+                goto general_case;
+            }
+            f1 /= f2; 
+            break;
+            /* XXX: also handles tests ? */
+        default:
+            goto general_case;
+        }
+        /* XXX: overflow test ? */
+        if (v1->type.t == VT_FLOAT) {
+            v1->c.f = f1;
+        } else if (v1->type.t == VT_DOUBLE) {
+            v1->c.d = f1;
+        } else {
+            v1->c.ld = f1;
+        }
+        vtop--;
+    } else {
+    general_case:
+        gen_opf(op);
+    }
+}
+
+static int pointed_size(CType *type)
+{
+    int align;
+    return type_size(pointed_type(type), &align);
+}
+
+static void vla_runtime_pointed_size(CType *type)
+{
+    int align;
+    vla_runtime_type_size(pointed_type(type), &align);
+}
+
+static inline int is_null_pointer(SValue *p)
+{
+    if ((p->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
+        return 0;
+    return ((p->type.t & VT_BTYPE) == VT_INT && (uint32_t)p->c.i == 0) ||
+        ((p->type.t & VT_BTYPE) == VT_LLONG && p->c.i == 0) ||
+        ((p->type.t & VT_BTYPE) == VT_PTR &&
+         (PTR_SIZE == 4 ? (uint32_t)p->c.i == 0 : p->c.i == 0));
+}
+
+static inline int is_integer_btype(int bt)
+{
+    return (bt == VT_BYTE || bt == VT_SHORT || 
+            bt == VT_INT || bt == VT_LLONG);
+}
+
+/* check types for comparison or subtraction of pointers */
+static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
+{
+    CType *type1, *type2, tmp_type1, tmp_type2;
+    int bt1, bt2;
+    
+    /* null pointers are accepted for all comparisons as gcc */
+    if (is_null_pointer(p1) || is_null_pointer(p2))
+        return;
+    type1 = &p1->type;
+    type2 = &p2->type;
+    bt1 = type1->t & VT_BTYPE;
+    bt2 = type2->t & VT_BTYPE;
+    /* accept comparison between pointer and integer with a warning */
+    if ((is_integer_btype(bt1) || is_integer_btype(bt2)) && op != '-') {
+        if (op != TOK_LOR && op != TOK_LAND )
+            tcc_warning("comparison between pointer and integer");
+        return;
+    }
+
+    /* both must be pointers or implicit function pointers */
+    if (bt1 == VT_PTR) {
+        type1 = pointed_type(type1);
+    } else if (bt1 != VT_FUNC) 
+        goto invalid_operands;
+
+    if (bt2 == VT_PTR) {
+        type2 = pointed_type(type2);
+    } else if (bt2 != VT_FUNC) { 
+    invalid_operands:
+        tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
+    }
+    if ((type1->t & VT_BTYPE) == VT_VOID || 
+        (type2->t & VT_BTYPE) == VT_VOID)
+        return;
+    tmp_type1 = *type1;
+    tmp_type2 = *type2;
+    tmp_type1.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
+    tmp_type2.t &= ~(VT_DEFSIGN | VT_UNSIGNED | VT_CONSTANT | VT_VOLATILE);
+    if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
+        /* gcc-like error if '-' is used */
+        if (op == '-')
+            goto invalid_operands;
+        else
+            tcc_warning("comparison of distinct pointer types lacks a cast");
+    }
+}
+
+/* generic gen_op: handles types problems */
+ST_FUNC void gen_op(int op)
+{
+    int u, t1, t2, bt1, bt2, t;
+    CType type1;
+
+redo:
+    t1 = vtop[-1].type.t;
+    t2 = vtop[0].type.t;
+    bt1 = t1 & VT_BTYPE;
+    bt2 = t2 & VT_BTYPE;
+        
+    if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
+        tcc_error("operation on a struct");
+    } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
+	if (bt2 == VT_FUNC) {
+	    mk_pointer(&vtop->type);
+	    gaddrof();
+	}
+	if (bt1 == VT_FUNC) {
+	    vswap();
+	    mk_pointer(&vtop->type);
+	    gaddrof();
+	    vswap();
+	}
+	goto redo;
+    } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
+        /* at least one operand is a pointer */
+        /* relational op: must be both pointers */
+        if (op >= TOK_ULT && op <= TOK_LOR) {
+            check_comparison_pointer_types(vtop - 1, vtop, op);
+            /* pointers are handled are unsigned */
+#if PTR_SIZE == 8
+            t = VT_LLONG | VT_UNSIGNED;
+#else
+            t = VT_INT | VT_UNSIGNED;
+#endif
+            goto std_op;
+        }
+        /* if both pointers, then it must be the '-' op */
+        if (bt1 == VT_PTR && bt2 == VT_PTR) {
+            if (op != '-')
+                tcc_error("cannot use pointers here");
+            check_comparison_pointer_types(vtop - 1, vtop, op);
+            /* XXX: check that types are compatible */
+            if (vtop[-1].type.t & VT_VLA) {
+                vla_runtime_pointed_size(&vtop[-1].type);
+            } else {
+                vpushi(pointed_size(&vtop[-1].type));
+            }
+            vrott(3);
+            gen_opic(op);
+            vtop->type.t = ptrdiff_type.t;
+            vswap();
+            gen_op(TOK_PDIV);
+        } else {
+            /* exactly one pointer : must be '+' or '-'. */
+            if (op != '-' && op != '+')
+                tcc_error("cannot use pointers here");
+            /* Put pointer as first operand */
+            if (bt2 == VT_PTR) {
+                vswap();
+                t = t1, t1 = t2, t2 = t;
+            }
+#if PTR_SIZE == 4
+            if ((vtop[0].type.t & VT_BTYPE) == VT_LLONG)
+                /* XXX: truncate here because gen_opl can't handle ptr + long long */
+                gen_cast_s(VT_INT);
+#endif
+            type1 = vtop[-1].type;
+            type1.t &= ~VT_ARRAY;
+            if (vtop[-1].type.t & VT_VLA)
+                vla_runtime_pointed_size(&vtop[-1].type);
+            else {
+                u = pointed_size(&vtop[-1].type);
+                if (u < 0)
+                    tcc_error("unknown array element size");
+#if PTR_SIZE == 8
+                vpushll(u);
+#else
+                /* XXX: cast to int ? (long long case) */
+                vpushi(u);
+#endif
+            }
+            gen_op('*');
+#if 0
+/* #ifdef CONFIG_TCC_BCHECK
+    The main reason to removing this code:
+	#include <stdio.h>
+	int main ()
+	{
+	    int v[10];
+	    int i = 10;
+	    int j = 9;
+	    fprintf(stderr, "v+i-j  = %p\n", v+i-j);
+	    fprintf(stderr, "v+(i-j)  = %p\n", v+(i-j));
+	}
+    When this code is on. then the output looks like 
+	v+i-j = 0xfffffffe
+	v+(i-j) = 0xbff84000
+    */
+            /* if evaluating constant expression, no code should be
+               generated, so no bound check */
+            if (tcc_state->do_bounds_check && !const_wanted) {
+                /* if bounded pointers, we generate a special code to
+                   test bounds */
+                if (op == '-') {
+                    vpushi(0);
+                    vswap();
+                    gen_op('-');
+                }
+                gen_bounded_ptr_add();
+            } else
+#endif
+            {
+                gen_opic(op);
+            }
+            /* put again type if gen_opic() swaped operands */
+            vtop->type = type1;
+        }
+    } else if (is_float(bt1) || is_float(bt2)) {
+        /* compute bigger type and do implicit casts */
+        if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
+            t = VT_LDOUBLE;
+        } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
+            t = VT_DOUBLE;
+        } else {
+            t = VT_FLOAT;
+        }
+        /* floats can only be used for a few operations */
+        if (op != '+' && op != '-' && op != '*' && op != '/' &&
+            (op < TOK_ULT || op > TOK_GT))
+            tcc_error("invalid operands for binary operation");
+        goto std_op;
+    } else if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL) {
+        t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
+        if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (t | VT_UNSIGNED))
+          t |= VT_UNSIGNED;
+        t |= (VT_LONG & t1);
+        goto std_op;
+    } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
+        /* cast to biggest op */
+        t = VT_LLONG | VT_LONG;
+        if (bt1 == VT_LLONG)
+            t &= t1;
+        if (bt2 == VT_LLONG)
+            t &= t2;
+        /* convert to unsigned if it does not fit in a long long */
+        if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
+            (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
+            t |= VT_UNSIGNED;
+        goto std_op;
+    } else {
+        /* integer operations */
+        t = VT_INT | (VT_LONG & (t1 | t2));
+        /* convert to unsigned if it does not fit in an integer */
+        if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
+            (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
+            t |= VT_UNSIGNED;
+    std_op:
+        /* XXX: currently, some unsigned operations are explicit, so
+           we modify them here */
+        if (t & VT_UNSIGNED) {
+            if (op == TOK_SAR)
+                op = TOK_SHR;
+            else if (op == '/')
+                op = TOK_UDIV;
+            else if (op == '%')
+                op = TOK_UMOD;
+            else if (op == TOK_LT)
+                op = TOK_ULT;
+            else if (op == TOK_GT)
+                op = TOK_UGT;
+            else if (op == TOK_LE)
+                op = TOK_ULE;
+            else if (op == TOK_GE)
+                op = TOK_UGE;
+        }
+        vswap();
+        type1.t = t;
+        type1.ref = NULL;
+        gen_cast(&type1);
+        vswap();
+        /* special case for shifts and long long: we keep the shift as
+           an integer */
+        if (op == TOK_SHR || op == TOK_SAR || op == TOK_SHL)
+            type1.t = VT_INT;
+        gen_cast(&type1);
+        if (is_float(t))
+            gen_opif(op);
+        else
+            gen_opic(op);
+        if (op >= TOK_ULT && op <= TOK_GT) {
+            /* relational op: the result is an int */
+            vtop->type.t = VT_INT;
+        } else {
+            vtop->type.t = t;
+        }
+    }
+    // Make sure that we have converted to an rvalue:
+    if (vtop->r & VT_LVAL)
+        gv(is_float(vtop->type.t & VT_BTYPE) ? RC_FLOAT : RC_INT);
+}
+
+#ifndef TCC_TARGET_ARM
+/* generic itof for unsigned long long case */
+static void gen_cvt_itof1(int t)
+{
+#ifdef TCC_TARGET_ARM64
+    gen_cvt_itof(t);
+#else
+    if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == 
+        (VT_LLONG | VT_UNSIGNED)) {
+
+        if (t == VT_FLOAT)
+            vpush_global_sym(&func_old_type, TOK___floatundisf);
+#if LDOUBLE_SIZE != 8
+        else if (t == VT_LDOUBLE)
+            vpush_global_sym(&func_old_type, TOK___floatundixf);
+#endif
+        else
+            vpush_global_sym(&func_old_type, TOK___floatundidf);
+        vrott(2);
+        gfunc_call(1);
+        vpushi(0);
+        vtop->r = reg_fret(t);
+    } else {
+        gen_cvt_itof(t);
+    }
+#endif
+}
+#endif
+
+/* generic ftoi for unsigned long long case */
+static void gen_cvt_ftoi1(int t)
+{
+#ifdef TCC_TARGET_ARM64
+    gen_cvt_ftoi(t);
+#else
+    int st;
+
+    if (t == (VT_LLONG | VT_UNSIGNED)) {
+        /* not handled natively */
+        st = vtop->type.t & VT_BTYPE;
+        if (st == VT_FLOAT)
+            vpush_global_sym(&func_old_type, TOK___fixunssfdi);
+#if LDOUBLE_SIZE != 8
+        else if (st == VT_LDOUBLE)
+            vpush_global_sym(&func_old_type, TOK___fixunsxfdi);
+#endif
+        else
+            vpush_global_sym(&func_old_type, TOK___fixunsdfdi);
+        vrott(2);
+        gfunc_call(1);
+        vpushi(0);
+        vtop->r = REG_IRET;
+        vtop->r2 = REG_LRET;
+    } else {
+        gen_cvt_ftoi(t);
+    }
+#endif
+}
+
+/* force char or short cast */
+static void force_charshort_cast(int t)
+{
+    int bits, dbt;
+
+    /* cannot cast static initializers */
+    if (STATIC_DATA_WANTED)
+	return;
+
+    dbt = t & VT_BTYPE;
+    /* XXX: add optimization if lvalue : just change type and offset */
+    if (dbt == VT_BYTE)
+        bits = 8;
+    else
+        bits = 16;
+    if (t & VT_UNSIGNED) {
+        vpushi((1 << bits) - 1);
+        gen_op('&');
+    } else {
+        if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
+            bits = 64 - bits;
+        else
+            bits = 32 - bits;
+        vpushi(bits);
+        gen_op(TOK_SHL);
+        /* result must be signed or the SAR is converted to an SHL
+           This was not the case when "t" was a signed short
+           and the last value on the stack was an unsigned int */
+        vtop->type.t &= ~VT_UNSIGNED;
+        vpushi(bits);
+        gen_op(TOK_SAR);
+    }
+}
+
+/* cast 'vtop' to 'type'. Casting to bitfields is forbidden. */
+static void gen_cast_s(int t)
+{
+    CType type;
+    type.t = t;
+    type.ref = NULL;
+    gen_cast(&type);
+}
+
+static void gen_cast(CType *type)
+{
+    int sbt, dbt, sf, df, c, p;
+
+    /* special delayed cast for char/short */
+    /* XXX: in some cases (multiple cascaded casts), it may still
+       be incorrect */
+    if (vtop->r & VT_MUSTCAST) {
+        vtop->r &= ~VT_MUSTCAST;
+        force_charshort_cast(vtop->type.t);
+    }
+
+    /* bitfields first get cast to ints */
+    if (vtop->type.t & VT_BITFIELD) {
+        gv(RC_INT);
+    }
+
+    dbt = type->t & (VT_BTYPE | VT_UNSIGNED);
+    sbt = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
+
+    if (sbt != dbt) {
+        sf = is_float(sbt);
+        df = is_float(dbt);
+        c = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+        p = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM);
+#if !defined TCC_IS_NATIVE && !defined TCC_IS_NATIVE_387
+        c &= dbt != VT_LDOUBLE;
+#endif
+        if (c) {
+            /* constant case: we can do it now */
+            /* XXX: in ISOC, cannot do it if error in convert */
+            if (sbt == VT_FLOAT)
+                vtop->c.ld = vtop->c.f;
+            else if (sbt == VT_DOUBLE)
+                vtop->c.ld = vtop->c.d;
+
+            if (df) {
+                if ((sbt & VT_BTYPE) == VT_LLONG) {
+                    if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 63))
+                        vtop->c.ld = vtop->c.i;
+                    else
+                        vtop->c.ld = -(long double)-vtop->c.i;
+                } else if(!sf) {
+                    if ((sbt & VT_UNSIGNED) || !(vtop->c.i >> 31))
+                        vtop->c.ld = (uint32_t)vtop->c.i;
+                    else
+                        vtop->c.ld = -(long double)-(uint32_t)vtop->c.i;
+                }
+
+                if (dbt == VT_FLOAT)
+                    vtop->c.f = (float)vtop->c.ld;
+                else if (dbt == VT_DOUBLE)
+                    vtop->c.d = (double)vtop->c.ld;
+            } else if (sf && dbt == (VT_LLONG|VT_UNSIGNED)) {
+                vtop->c.i = vtop->c.ld;
+            } else if (sf && dbt == VT_BOOL) {
+                vtop->c.i = (vtop->c.ld != 0);
+            } else {
+                if(sf)
+                    vtop->c.i = vtop->c.ld;
+                else if (sbt == (VT_LLONG|VT_UNSIGNED))
+                    ;
+                else if (sbt & VT_UNSIGNED)
+                    vtop->c.i = (uint32_t)vtop->c.i;
+#if PTR_SIZE == 8
+                else if (sbt == VT_PTR)
+                    ;
+#endif
+                else if (sbt != VT_LLONG)
+                    vtop->c.i = ((uint32_t)vtop->c.i |
+                                  -(vtop->c.i & 0x80000000));
+
+                if (dbt == (VT_LLONG|VT_UNSIGNED))
+                    ;
+                else if (dbt == VT_BOOL)
+                    vtop->c.i = (vtop->c.i != 0);
+#if PTR_SIZE == 8
+                else if (dbt == VT_PTR)
+                    ;
+#endif
+                else if (dbt != VT_LLONG) {
+                    uint32_t m = ((dbt & VT_BTYPE) == VT_BYTE ? 0xff :
+                                  (dbt & VT_BTYPE) == VT_SHORT ? 0xffff :
+                                  0xffffffff);
+                    vtop->c.i &= m;
+                    if (!(dbt & VT_UNSIGNED))
+                        vtop->c.i |= -(vtop->c.i & ((m >> 1) + 1));
+                }
+            }
+        } else if (p && dbt == VT_BOOL) {
+            vtop->r = VT_CONST;
+            vtop->c.i = 1;
+        } else {
+            /* non constant case: generate code */
+            if (sf && df) {
+                /* convert from fp to fp */
+                gen_cvt_ftof(dbt);
+            } else if (df) {
+                /* convert int to fp */
+                gen_cvt_itof1(dbt);
+            } else if (sf) {
+                /* convert fp to int */
+                if (dbt == VT_BOOL) {
+                     vpushi(0);
+                     gen_op(TOK_NE);
+                } else {
+                    /* we handle char/short/etc... with generic code */
+                    if (dbt != (VT_INT | VT_UNSIGNED) &&
+                        dbt != (VT_LLONG | VT_UNSIGNED) &&
+                        dbt != VT_LLONG)
+                        dbt = VT_INT;
+                    gen_cvt_ftoi1(dbt);
+                    if (dbt == VT_INT && (type->t & (VT_BTYPE | VT_UNSIGNED)) != dbt) {
+                        /* additional cast for char/short... */
+                        vtop->type.t = dbt;
+                        gen_cast(type);
+                    }
+                }
+#if PTR_SIZE == 4
+            } else if ((dbt & VT_BTYPE) == VT_LLONG) {
+                if ((sbt & VT_BTYPE) != VT_LLONG) {
+                    /* scalar to long long */
+                    /* machine independent conversion */
+                    gv(RC_INT);
+                    /* generate high word */
+                    if (sbt == (VT_INT | VT_UNSIGNED)) {
+                        vpushi(0);
+                        gv(RC_INT);
+                    } else {
+                        if (sbt == VT_PTR) {
+                            /* cast from pointer to int before we apply
+                               shift operation, which pointers don't support*/
+                            gen_cast_s(VT_INT);
+                        }
+                        gv_dup();
+                        vpushi(31);
+                        gen_op(TOK_SAR);
+                    }
+                    /* patch second register */
+                    vtop[-1].r2 = vtop->r;
+                    vpop();
+                }
+#else
+            } else if ((dbt & VT_BTYPE) == VT_LLONG ||
+                       (dbt & VT_BTYPE) == VT_PTR ||
+                       (dbt & VT_BTYPE) == VT_FUNC) {
+                if ((sbt & VT_BTYPE) != VT_LLONG &&
+                    (sbt & VT_BTYPE) != VT_PTR &&
+                    (sbt & VT_BTYPE) != VT_FUNC) {
+                    /* need to convert from 32bit to 64bit */
+                    gv(RC_INT);
+                    if (sbt != (VT_INT | VT_UNSIGNED)) {
+#if defined(TCC_TARGET_ARM64)
+                        gen_cvt_sxtw();
+#elif defined(TCC_TARGET_X86_64)
+                        int r = gv(RC_INT);
+                        /* x86_64 specific: movslq */
+                        o(0x6348);
+                        o(0xc0 + (REG_VALUE(r) << 3) + REG_VALUE(r));
+#else
+#error
+#endif
+                    }
+                }
+#endif
+            } else if (dbt == VT_BOOL) {
+                /* scalar to bool */
+                vpushi(0);
+                gen_op(TOK_NE);
+            } else if ((dbt & VT_BTYPE) == VT_BYTE || 
+                       (dbt & VT_BTYPE) == VT_SHORT) {
+                if (sbt == VT_PTR) {
+                    vtop->type.t = VT_INT;
+                    tcc_warning("nonportable conversion from pointer to char/short");
+                }
+                force_charshort_cast(dbt);
+#if PTR_SIZE == 4
+            } else if ((dbt & VT_BTYPE) == VT_INT) {
+                /* scalar to int */
+                if ((sbt & VT_BTYPE) == VT_LLONG) {
+                    /* from long long: just take low order word */
+                    lexpand();
+                    vpop();
+                } 
+                /* if lvalue and single word type, nothing to do because
+                   the lvalue already contains the real type size (see
+                   VT_LVAL_xxx constants) */
+#endif
+            }
+        }
+    } else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {
+        /* if we are casting between pointer types,
+           we must update the VT_LVAL_xxx size */
+        vtop->r = (vtop->r & ~VT_LVAL_TYPE)
+                  | (lvalue_type(type->ref->type.t) & VT_LVAL_TYPE);
+    }
+    vtop->type = *type;
+}
+
+/* return type size as known at compile time. Put alignment at 'a' */
+ST_FUNC int type_size(CType *type, int *a)
+{
+    Sym *s;
+    int bt;
+
+    bt = type->t & VT_BTYPE;
+    if (bt == VT_STRUCT) {
+        /* struct/union */
+        s = type->ref;
+        *a = s->r;
+        return s->c;
+    } else if (bt == VT_PTR) {
+        if (type->t & VT_ARRAY) {
+            int ts;
+
+            s = type->ref;
+            ts = type_size(&s->type, a);
+
+            if (ts < 0 && s->c < 0)
+                ts = -ts;
+
+            return ts * s->c;
+        } else {
+            *a = PTR_SIZE;
+            return PTR_SIZE;
+        }
+    } else if (IS_ENUM(type->t) && type->ref->c == -1) {
+        return -1; /* incomplete enum */
+    } else if (bt == VT_LDOUBLE) {
+        *a = LDOUBLE_ALIGN;
+        return LDOUBLE_SIZE;
+    } else if (bt == VT_DOUBLE || bt == VT_LLONG) {
+#ifdef TCC_TARGET_I386
+#ifdef TCC_TARGET_PE
+        *a = 8;
+#else
+        *a = 4;
+#endif
+#elif defined(TCC_TARGET_ARM)
+#ifdef TCC_ARM_EABI
+        *a = 8; 
+#else
+        *a = 4;
+#endif
+#else
+        *a = 8;
+#endif
+        return 8;
+    } else if (bt == VT_INT || bt == VT_FLOAT) {
+        *a = 4;
+        return 4;
+    } else if (bt == VT_SHORT) {
+        *a = 2;
+        return 2;
+    } else if (bt == VT_QLONG || bt == VT_QFLOAT) {
+        *a = 8;
+        return 16;
+    } else {
+        /* char, void, function, _Bool */
+        *a = 1;
+        return 1;
+    }
+}
+
+/* push type size as known at runtime time on top of value stack. Put
+   alignment at 'a' */
+ST_FUNC void vla_runtime_type_size(CType *type, int *a)
+{
+    if (type->t & VT_VLA) {
+        type_size(&type->ref->type, a);
+        vset(&int_type, VT_LOCAL|VT_LVAL, type->ref->c);
+    } else {
+        vpushi(type_size(type, a));
+    }
+}
+
+static void vla_sp_restore(void) {
+    if (vlas_in_scope) {
+        gen_vla_sp_restore(vla_sp_loc);
+    }
+}
+
+static void vla_sp_restore_root(void) {
+    if (vlas_in_scope) {
+        gen_vla_sp_restore(vla_sp_root_loc);
+    }
+}
+
+/* return the pointed type of t */
+static inline CType *pointed_type(CType *type)
+{
+    return &type->ref->type;
+}
+
+/* modify type so that its it is a pointer to type. */
+ST_FUNC void mk_pointer(CType *type)
+{
+    Sym *s;
+    s = sym_push(SYM_FIELD, type, 0, -1);
+    type->t = VT_PTR | (type->t & VT_STORAGE);
+    type->ref = s;
+}
+
+/* compare function types. OLD functions match any new functions */
+static int is_compatible_func(CType *type1, CType *type2)
+{
+    Sym *s1, *s2;
+
+    s1 = type1->ref;
+    s2 = type2->ref;
+    if (!is_compatible_types(&s1->type, &s2->type))
+        return 0;
+    /* check func_call */
+    if (s1->f.func_call != s2->f.func_call)
+        return 0;
+    /* XXX: not complete */
+    if (s1->f.func_type == FUNC_OLD || s2->f.func_type == FUNC_OLD)
+        return 1;
+    if (s1->f.func_type != s2->f.func_type)
+        return 0;
+    while (s1 != NULL) {
+        if (s2 == NULL)
+            return 0;
+        if (!is_compatible_unqualified_types(&s1->type, &s2->type))
+            return 0;
+        s1 = s1->next;
+        s2 = s2->next;
+    }
+    if (s2)
+        return 0;
+    return 1;
+}
+
+/* return true if type1 and type2 are the same.  If unqualified is
+   true, qualifiers on the types are ignored.
+
+   - enums are not checked as gcc __builtin_types_compatible_p () 
+ */
+static int compare_types(CType *type1, CType *type2, int unqualified)
+{
+    int bt1, t1, t2;
+
+    t1 = type1->t & VT_TYPE;
+    t2 = type2->t & VT_TYPE;
+    if (unqualified) {
+        /* strip qualifiers before comparing */
+        t1 &= ~(VT_CONSTANT | VT_VOLATILE);
+        t2 &= ~(VT_CONSTANT | VT_VOLATILE);
+    }
+
+    /* Default Vs explicit signedness only matters for char */
+    if ((t1 & VT_BTYPE) != VT_BYTE) {
+        t1 &= ~VT_DEFSIGN;
+        t2 &= ~VT_DEFSIGN;
+    }
+    /* XXX: bitfields ? */
+    if (t1 != t2)
+        return 0;
+    /* test more complicated cases */
+    bt1 = t1 & VT_BTYPE;
+    if (bt1 == VT_PTR) {
+        type1 = pointed_type(type1);
+        type2 = pointed_type(type2);
+        return is_compatible_types(type1, type2);
+    } else if (bt1 == VT_STRUCT) {
+        return (type1->ref == type2->ref);
+    } else if (bt1 == VT_FUNC) {
+        return is_compatible_func(type1, type2);
+    } else {
+        return 1;
+    }
+}
+
+/* return true if type1 and type2 are exactly the same (including
+   qualifiers). 
+*/
+static int is_compatible_types(CType *type1, CType *type2)
+{
+    return compare_types(type1,type2,0);
+}
+
+/* return true if type1 and type2 are the same (ignoring qualifiers).
+*/
+static int is_compatible_unqualified_types(CType *type1, CType *type2)
+{
+    return compare_types(type1,type2,1);
+}
+
+/* print a type. If 'varstr' is not NULL, then the variable is also
+   printed in the type */
+/* XXX: union */
+/* XXX: add array and function pointers */
+static void type_to_str(char *buf, int buf_size, 
+                 CType *type, const char *varstr)
+{
+    int bt, v, t;
+    Sym *s, *sa;
+    char buf1[256];
+    const char *tstr;
+
+    t = type->t;
+    bt = t & VT_BTYPE;
+    buf[0] = '\0';
+
+    if (t & VT_EXTERN)
+        pstrcat(buf, buf_size, "extern ");
+    if (t & VT_STATIC)
+        pstrcat(buf, buf_size, "static ");
+    if (t & VT_TYPEDEF)
+        pstrcat(buf, buf_size, "typedef ");
+    if (t & VT_INLINE)
+        pstrcat(buf, buf_size, "inline ");
+    if (t & VT_VOLATILE)
+        pstrcat(buf, buf_size, "volatile ");
+    if (t & VT_CONSTANT)
+        pstrcat(buf, buf_size, "const ");
+
+    if (((t & VT_DEFSIGN) && bt == VT_BYTE)
+        || ((t & VT_UNSIGNED)
+            && (bt == VT_SHORT || bt == VT_INT || bt == VT_LLONG)
+            && !IS_ENUM(t)
+            ))
+        pstrcat(buf, buf_size, (t & VT_UNSIGNED) ? "unsigned " : "signed ");
+
+    buf_size -= strlen(buf);
+    buf += strlen(buf);
+
+    switch(bt) {
+    case VT_VOID:
+        tstr = "void";
+        goto add_tstr;
+    case VT_BOOL:
+        tstr = "_Bool";
+        goto add_tstr;
+    case VT_BYTE:
+        tstr = "char";
+        goto add_tstr;
+    case VT_SHORT:
+        tstr = "short";
+        goto add_tstr;
+    case VT_INT:
+        tstr = "int";
+        goto maybe_long;
+    case VT_LLONG:
+        tstr = "long long";
+    maybe_long:
+        if (t & VT_LONG)
+            tstr = "long";
+        if (!IS_ENUM(t))
+            goto add_tstr;
+        tstr = "enum ";
+        goto tstruct;
+    case VT_FLOAT:
+        tstr = "float";
+        goto add_tstr;
+    case VT_DOUBLE:
+        tstr = "double";
+        goto add_tstr;
+    case VT_LDOUBLE:
+        tstr = "long double";
+    add_tstr:
+        pstrcat(buf, buf_size, tstr);
+        break;
+    case VT_STRUCT:
+        tstr = "struct ";
+        if (IS_UNION(t))
+            tstr = "union ";
+    tstruct:
+        pstrcat(buf, buf_size, tstr);
+        v = type->ref->v & ~SYM_STRUCT;
+        if (v >= SYM_FIRST_ANOM)
+            pstrcat(buf, buf_size, "<anonymous>");
+        else
+            pstrcat(buf, buf_size, get_tok_str(v, NULL));
+        break;
+    case VT_FUNC:
+        s = type->ref;
+        type_to_str(buf, buf_size, &s->type, varstr);
+        pstrcat(buf, buf_size, "(");
+        sa = s->next;
+        while (sa != NULL) {
+            type_to_str(buf1, sizeof(buf1), &sa->type, NULL);
+            pstrcat(buf, buf_size, buf1);
+            sa = sa->next;
+            if (sa)
+                pstrcat(buf, buf_size, ", ");
+        }
+        pstrcat(buf, buf_size, ")");
+        goto no_var;
+    case VT_PTR:
+        s = type->ref;
+        if (t & VT_ARRAY) {
+            snprintf(buf1, sizeof(buf1), "%s[%d]", varstr ? varstr : "", s->c);
+            type_to_str(buf, buf_size, &s->type, buf1);
+            goto no_var;
+        }
+        pstrcpy(buf1, sizeof(buf1), "*");
+        if (t & VT_CONSTANT)
+            pstrcat(buf1, buf_size, "const ");
+        if (t & VT_VOLATILE)
+            pstrcat(buf1, buf_size, "volatile ");
+        if (varstr)
+            pstrcat(buf1, sizeof(buf1), varstr);
+        type_to_str(buf, buf_size, &s->type, buf1);
+        goto no_var;
+    }
+    if (varstr) {
+        pstrcat(buf, buf_size, " ");
+        pstrcat(buf, buf_size, varstr);
+    }
+ no_var: ;
+}
+
+/* verify type compatibility to store vtop in 'dt' type, and generate
+   casts if needed. */
+static void gen_assign_cast(CType *dt)
+{
+    CType *st, *type1, *type2;
+    char buf1[256], buf2[256];
+    int dbt, sbt;
+
+    st = &vtop->type; /* source type */
+    dbt = dt->t & VT_BTYPE;
+    sbt = st->t & VT_BTYPE;
+    if (sbt == VT_VOID || dbt == VT_VOID) {
+	if (sbt == VT_VOID && dbt == VT_VOID)
+	    ; /*
+	      It is Ok if both are void
+	      A test program:
+	        void func1() {}
+		void func2() {
+		  return func1();
+		}
+	      gcc accepts this program
+	      */
+	else
+    	    tcc_error("cannot cast from/to void");
+    }
+    if (dt->t & VT_CONSTANT)
+        tcc_warning("assignment of read-only location");
+    switch(dbt) {
+    case VT_PTR:
+        /* special cases for pointers */
+        /* '0' can also be a pointer */
+        if (is_null_pointer(vtop))
+            goto type_ok;
+        /* accept implicit pointer to integer cast with warning */
+        if (is_integer_btype(sbt)) {
+            tcc_warning("assignment makes pointer from integer without a cast");
+            goto type_ok;
+        }
+        type1 = pointed_type(dt);
+        /* a function is implicitly a function pointer */
+        if (sbt == VT_FUNC) {
+            if ((type1->t & VT_BTYPE) != VT_VOID &&
+                !is_compatible_types(pointed_type(dt), st))
+                tcc_warning("assignment from incompatible pointer type");
+            goto type_ok;
+        }
+        if (sbt != VT_PTR)
+            goto error;
+        type2 = pointed_type(st);
+        if ((type1->t & VT_BTYPE) == VT_VOID || 
+            (type2->t & VT_BTYPE) == VT_VOID) {
+            /* void * can match anything */
+        } else {
+            //printf("types %08x %08x\n", type1->t, type2->t);
+            /* exact type match, except for qualifiers */
+            if (!is_compatible_unqualified_types(type1, type2)) {
+		/* Like GCC don't warn by default for merely changes
+		   in pointer target signedness.  Do warn for different
+		   base types, though, in particular for unsigned enums
+		   and signed int targets.  */
+		if ((type1->t & (VT_BTYPE|VT_LONG)) != (type2->t & (VT_BTYPE|VT_LONG))
+                    || IS_ENUM(type1->t) || IS_ENUM(type2->t)
+                    )
+		    tcc_warning("assignment from incompatible pointer type");
+	    }
+        }
+        /* check const and volatile */
+        if ((!(type1->t & VT_CONSTANT) && (type2->t & VT_CONSTANT)) ||
+            (!(type1->t & VT_VOLATILE) && (type2->t & VT_VOLATILE)))
+            tcc_warning("assignment discards qualifiers from pointer target type");
+        break;
+    case VT_BYTE:
+    case VT_SHORT:
+    case VT_INT:
+    case VT_LLONG:
+        if (sbt == VT_PTR || sbt == VT_FUNC) {
+            tcc_warning("assignment makes integer from pointer without a cast");
+        } else if (sbt == VT_STRUCT) {
+            goto case_VT_STRUCT;
+        }
+        /* XXX: more tests */
+        break;
+    case VT_STRUCT:
+    case_VT_STRUCT:
+        if (!is_compatible_unqualified_types(dt, st)) {
+        error:
+            type_to_str(buf1, sizeof(buf1), st, NULL);
+            type_to_str(buf2, sizeof(buf2), dt, NULL);
+            tcc_error("cannot cast '%s' to '%s'", buf1, buf2);
+        }
+        break;
+    }
+ type_ok:
+    gen_cast(dt);
+}
+
+/* store vtop in lvalue pushed on stack */
+ST_FUNC void vstore(void)
+{
+    int sbt, dbt, ft, r, t, size, align, bit_size, bit_pos, rc, delayed_cast;
+
+    ft = vtop[-1].type.t;
+    sbt = vtop->type.t & VT_BTYPE;
+    dbt = ft & VT_BTYPE;
+    if ((((sbt == VT_INT || sbt == VT_SHORT) && dbt == VT_BYTE) ||
+         (sbt == VT_INT && dbt == VT_SHORT))
+	&& !(vtop->type.t & VT_BITFIELD)) {
+        /* optimize char/short casts */
+        delayed_cast = VT_MUSTCAST;
+        vtop->type.t = ft & VT_TYPE;
+        /* XXX: factorize */
+        if (ft & VT_CONSTANT)
+            tcc_warning("assignment of read-only location");
+    } else {
+        delayed_cast = 0;
+        if (!(ft & VT_BITFIELD))
+            gen_assign_cast(&vtop[-1].type);
+    }
+
+    if (sbt == VT_STRUCT) {
+        /* if structure, only generate pointer */
+        /* structure assignment : generate memcpy */
+        /* XXX: optimize if small size */
+            size = type_size(&vtop->type, &align);
+
+            /* destination */
+            vswap();
+            vtop->type.t = VT_PTR;
+            gaddrof();
+
+            /* address of memcpy() */
+#ifdef TCC_ARM_EABI
+            if(!(align & 7))
+                vpush_global_sym(&func_old_type, TOK_memcpy8);
+            else if(!(align & 3))
+                vpush_global_sym(&func_old_type, TOK_memcpy4);
+            else
+#endif
+            /* Use memmove, rather than memcpy, as dest and src may be same: */
+            vpush_global_sym(&func_old_type, TOK_memmove);
+
+            vswap();
+            /* source */
+            vpushv(vtop - 2);
+            vtop->type.t = VT_PTR;
+            gaddrof();
+            /* type size */
+            vpushi(size);
+            gfunc_call(3);
+
+        /* leave source on stack */
+    } else if (ft & VT_BITFIELD) {
+        /* bitfield store handling */
+
+        /* save lvalue as expression result (example: s.b = s.a = n;) */
+        vdup(), vtop[-1] = vtop[-2];
+
+        bit_pos = BIT_POS(ft);
+        bit_size = BIT_SIZE(ft);
+        /* remove bit field info to avoid loops */
+        vtop[-1].type.t = ft & ~VT_STRUCT_MASK;
+
+        if ((ft & VT_BTYPE) == VT_BOOL) {
+            gen_cast(&vtop[-1].type);
+            vtop[-1].type.t = (vtop[-1].type.t & ~VT_BTYPE) | (VT_BYTE | VT_UNSIGNED);
+        }
+
+        r = adjust_bf(vtop - 1, bit_pos, bit_size);
+        if (r == VT_STRUCT) {
+            gen_cast_s((ft & VT_BTYPE) == VT_LLONG ? VT_LLONG : VT_INT);
+            store_packed_bf(bit_pos, bit_size);
+        } else {
+            unsigned long long mask = (1ULL << bit_size) - 1;
+            if ((ft & VT_BTYPE) != VT_BOOL) {
+                /* mask source */
+                if ((vtop[-1].type.t & VT_BTYPE) == VT_LLONG)
+                    vpushll(mask);
+                else
+                    vpushi((unsigned)mask);
+                gen_op('&');
+            }
+            /* shift source */
+            vpushi(bit_pos);
+            gen_op(TOK_SHL);
+            vswap();
+            /* duplicate destination */
+            vdup();
+            vrott(3);
+            /* load destination, mask and or with source */
+            if ((vtop->type.t & VT_BTYPE) == VT_LLONG)
+                vpushll(~(mask << bit_pos));
+            else
+                vpushi(~((unsigned)mask << bit_pos));
+            gen_op('&');
+            gen_op('|');
+            /* store result */
+            vstore();
+            /* ... and discard */
+            vpop();
+        }
+    } else if (dbt == VT_VOID) {
+        --vtop;
+    } else {
+#ifdef CONFIG_TCC_BCHECK
+            /* bound check case */
+            if (vtop[-1].r & VT_MUSTBOUND) {
+                vswap();
+                gbound();
+                vswap();
+            }
+#endif
+            rc = RC_INT;
+            if (is_float(ft)) {
+                rc = RC_FLOAT;
+#ifdef TCC_TARGET_X86_64
+                if ((ft & VT_BTYPE) == VT_LDOUBLE) {
+                    rc = RC_ST0;
+                } else if ((ft & VT_BTYPE) == VT_QFLOAT) {
+                    rc = RC_FRET;
+                }
+#endif
+            }
+            r = gv(rc);  /* generate value */
+            /* if lvalue was saved on stack, must read it */
+            if ((vtop[-1].r & VT_VALMASK) == VT_LLOCAL) {
+                SValue sv;
+                t = get_reg(RC_INT);
+#if PTR_SIZE == 8
+                sv.type.t = VT_PTR;
+#else
+                sv.type.t = VT_INT;
+#endif
+                sv.r = VT_LOCAL | VT_LVAL;
+                sv.c.i = vtop[-1].c.i;
+                load(t, &sv);
+                vtop[-1].r = t | VT_LVAL;
+            }
+            /* two word case handling : store second register at word + 4 (or +8 for x86-64)  */
+#if PTR_SIZE == 8
+            if (((ft & VT_BTYPE) == VT_QLONG) || ((ft & VT_BTYPE) == VT_QFLOAT)) {
+                int addr_type = VT_LLONG, load_size = 8, load_type = ((vtop->type.t & VT_BTYPE) == VT_QLONG) ? VT_LLONG : VT_DOUBLE;
+#else
+            if ((ft & VT_BTYPE) == VT_LLONG) {
+                int addr_type = VT_INT, load_size = 4, load_type = VT_INT;
+#endif
+                vtop[-1].type.t = load_type;
+                store(r, vtop - 1);
+                vswap();
+                /* convert to int to increment easily */
+                vtop->type.t = addr_type;
+                gaddrof();
+                vpushi(load_size);
+                gen_op('+');
+                vtop->r |= VT_LVAL;
+                vswap();
+                vtop[-1].type.t = load_type;
+                /* XXX: it works because r2 is spilled last ! */
+                store(vtop->r2, vtop - 1);
+            } else {
+                store(r, vtop - 1);
+            }
+
+        vswap();
+        vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
+        vtop->r |= delayed_cast;
+    }
+}
+
+/* post defines POST/PRE add. c is the token ++ or -- */
+ST_FUNC void inc(int post, int c)
+{
+    test_lvalue();
+    vdup(); /* save lvalue */
+    if (post) {
+        gv_dup(); /* duplicate value */
+        vrotb(3);
+        vrotb(3);
+    }
+    /* add constant */
+    vpushi(c - TOK_MID); 
+    gen_op('+');
+    vstore(); /* store value */
+    if (post)
+        vpop(); /* if post op, return saved value */
+}
+
+ST_FUNC void parse_mult_str (CString *astr, const char *msg)
+{
+    /* read the string */
+    if (tok != TOK_STR)
+        expect(msg);
+    cstr_new(astr);
+    while (tok == TOK_STR) {
+        /* XXX: add \0 handling too ? */
+        cstr_cat(astr, tokc.str.data, -1);
+        next();
+    }
+    cstr_ccat(astr, '\0');
+}
+
+/* If I is >= 1 and a power of two, returns log2(i)+1.
+   If I is 0 returns 0.  */
+static int exact_log2p1(int i)
+{
+  int ret;
+  if (!i)
+    return 0;
+  for (ret = 1; i >= 1 << 8; ret += 8)
+    i >>= 8;
+  if (i >= 1 << 4)
+    ret += 4, i >>= 4;
+  if (i >= 1 << 2)
+    ret += 2, i >>= 2;
+  if (i >= 1 << 1)
+    ret++;
+  return ret;
+}
+
+/* Parse __attribute__((...)) GNUC extension. */
+static void parse_attribute(AttributeDef *ad)
+{
+    int t, n;
+    CString astr;
+    
+redo:
+    if (tok != TOK_ATTRIBUTE1 && tok != TOK_ATTRIBUTE2)
+        return;
+    next();
+    skip('(');
+    skip('(');
+    while (tok != ')') {
+        if (tok < TOK_IDENT)
+            expect("attribute name");
+        t = tok;
+        next();
+        switch(t) {
+        case TOK_SECTION1:
+        case TOK_SECTION2:
+            skip('(');
+	    parse_mult_str(&astr, "section name");
+            ad->section = find_section(tcc_state, (char *)astr.data);
+            skip(')');
+	    cstr_free(&astr);
+            break;
+        case TOK_ALIAS1:
+        case TOK_ALIAS2:
+            skip('(');
+	    parse_mult_str(&astr, "alias(\"target\")");
+            ad->alias_target = /* save string as token, for later */
+              tok_alloc((char*)astr.data, astr.size-1)->tok;
+            skip(')');
+	    cstr_free(&astr);
+            break;
+	case TOK_VISIBILITY1:
+	case TOK_VISIBILITY2:
+            skip('(');
+	    parse_mult_str(&astr,
+			   "visibility(\"default|hidden|internal|protected\")");
+	    if (!strcmp (astr.data, "default"))
+	        ad->a.visibility = STV_DEFAULT;
+	    else if (!strcmp (astr.data, "hidden"))
+	        ad->a.visibility = STV_HIDDEN;
+	    else if (!strcmp (astr.data, "internal"))
+	        ad->a.visibility = STV_INTERNAL;
+	    else if (!strcmp (astr.data, "protected"))
+	        ad->a.visibility = STV_PROTECTED;
+	    else
+                expect("visibility(\"default|hidden|internal|protected\")");
+            skip(')');
+	    cstr_free(&astr);
+            break;
+        case TOK_ALIGNED1:
+        case TOK_ALIGNED2:
+            if (tok == '(') {
+                next();
+                n = expr_const();
+                if (n <= 0 || (n & (n - 1)) != 0) 
+                    tcc_error("alignment must be a positive power of two");
+                skip(')');
+            } else {
+                n = MAX_ALIGN;
+            }
+            ad->a.aligned = exact_log2p1(n);
+	    if (n != 1 << (ad->a.aligned - 1))
+	      tcc_error("alignment of %d is larger than implemented", n);
+            break;
+        case TOK_PACKED1:
+        case TOK_PACKED2:
+            ad->a.packed = 1;
+            break;
+        case TOK_WEAK1:
+        case TOK_WEAK2:
+            ad->a.weak = 1;
+            break;
+        case TOK_UNUSED1:
+        case TOK_UNUSED2:
+            /* currently, no need to handle it because tcc does not
+               track unused objects */
+            break;
+        case TOK_NORETURN1:
+        case TOK_NORETURN2:
+            /* currently, no need to handle it because tcc does not
+               track unused objects */
+            break;
+        case TOK_CDECL1:
+        case TOK_CDECL2:
+        case TOK_CDECL3:
+            ad->f.func_call = FUNC_CDECL;
+            break;
+        case TOK_STDCALL1:
+        case TOK_STDCALL2:
+        case TOK_STDCALL3:
+            ad->f.func_call = FUNC_STDCALL;
+            break;
+#ifdef TCC_TARGET_I386
+        case TOK_REGPARM1:
+        case TOK_REGPARM2:
+            skip('(');
+            n = expr_const();
+            if (n > 3) 
+                n = 3;
+            else if (n < 0)
+                n = 0;
+            if (n > 0)
+                ad->f.func_call = FUNC_FASTCALL1 + n - 1;
+            skip(')');
+            break;
+        case TOK_FASTCALL1:
+        case TOK_FASTCALL2:
+        case TOK_FASTCALL3:
+            ad->f.func_call = FUNC_FASTCALLW;
+            break;            
+#endif
+        case TOK_MODE:
+            skip('(');
+            switch(tok) {
+                case TOK_MODE_DI:
+                    ad->attr_mode = VT_LLONG + 1;
+                    break;
+                case TOK_MODE_QI:
+                    ad->attr_mode = VT_BYTE + 1;
+                    break;
+                case TOK_MODE_HI:
+                    ad->attr_mode = VT_SHORT + 1;
+                    break;
+                case TOK_MODE_SI:
+                case TOK_MODE_word:
+                    ad->attr_mode = VT_INT + 1;
+                    break;
+                default:
+                    tcc_warning("__mode__(%s) not supported\n", get_tok_str(tok, NULL));
+                    break;
+            }
+            next();
+            skip(')');
+            break;
+        case TOK_DLLEXPORT:
+            ad->a.dllexport = 1;
+            break;
+        case TOK_DLLIMPORT:
+            ad->a.dllimport = 1;
+            break;
+        default:
+            if (tcc_state->warn_unsupported)
+                tcc_warning("'%s' attribute ignored", get_tok_str(t, NULL));
+            /* skip parameters */
+            if (tok == '(') {
+                int parenthesis = 0;
+                do {
+                    if (tok == '(') 
+                        parenthesis++;
+                    else if (tok == ')') 
+                        parenthesis--;
+                    next();
+                } while (parenthesis && tok != -1);
+            }
+            break;
+        }
+        if (tok != ',')
+            break;
+        next();
+    }
+    skip(')');
+    skip(')');
+    goto redo;
+}
+
+static Sym * find_field (CType *type, int v)
+{
+    Sym *s = type->ref;
+    v |= SYM_FIELD;
+    while ((s = s->next) != NULL) {
+	if ((s->v & SYM_FIELD) &&
+	    (s->type.t & VT_BTYPE) == VT_STRUCT &&
+	    (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) {
+	    Sym *ret = find_field (&s->type, v);
+	    if (ret)
+	        return ret;
+	}
+	if (s->v == v)
+	  break;
+    }
+    return s;
+}
+
+static void struct_add_offset (Sym *s, int offset)
+{
+    while ((s = s->next) != NULL) {
+	if ((s->v & SYM_FIELD) &&
+	    (s->type.t & VT_BTYPE) == VT_STRUCT &&
+	    (s->v & ~SYM_FIELD) >= SYM_FIRST_ANOM) {
+	    struct_add_offset(s->type.ref, offset);
+	} else
+	  s->c += offset;
+    }
+}
+
+static void struct_layout(CType *type, AttributeDef *ad)
+{
+    int size, align, maxalign, offset, c, bit_pos, bit_size;
+    int packed, a, bt, prevbt, prev_bit_size;
+    int pcc = !tcc_state->ms_bitfields;
+    int pragma_pack = *tcc_state->pack_stack_ptr;
+    Sym *f;
+
+    maxalign = 1;
+    offset = 0;
+    c = 0;
+    bit_pos = 0;
+    prevbt = VT_STRUCT; /* make it never match */
+    prev_bit_size = 0;
+
+//#define BF_DEBUG
+
+    for (f = type->ref->next; f; f = f->next) {
+        if (f->type.t & VT_BITFIELD)
+            bit_size = BIT_SIZE(f->type.t);
+        else
+            bit_size = -1;
+        size = type_size(&f->type, &align);
+        a = f->a.aligned ? 1 << (f->a.aligned - 1) : 0;
+        packed = 0;
+
+        if (pcc && bit_size == 0) {
+            /* in pcc mode, packing does not affect zero-width bitfields */
+
+        } else {
+            /* in pcc mode, attribute packed overrides if set. */
+            if (pcc && (f->a.packed || ad->a.packed))
+                align = packed = 1;
+
+            /* pragma pack overrides align if lesser and packs bitfields always */
+            if (pragma_pack) {
+                packed = 1;
+                if (pragma_pack < align)
+                    align = pragma_pack;
+                /* in pcc mode pragma pack also overrides individual align */
+                if (pcc && pragma_pack < a)
+                    a = 0;
+            }
+        }
+        /* some individual align was specified */
+        if (a)
+            align = a;
+
+        if (type->ref->type.t == VT_UNION) {
+	    if (pcc && bit_size >= 0)
+	        size = (bit_size + 7) >> 3;
+	    offset = 0;
+	    if (size > c)
+	        c = size;
+
+	} else if (bit_size < 0) {
+            if (pcc)
+                c += (bit_pos + 7) >> 3;
+	    c = (c + align - 1) & -align;
+	    offset = c;
+	    if (size > 0)
+	        c += size;
+	    bit_pos = 0;
+	    prevbt = VT_STRUCT;
+	    prev_bit_size = 0;
+
+	} else {
+	    /* A bit-field.  Layout is more complicated.  There are two
+	       options: PCC (GCC) compatible and MS compatible */
+            if (pcc) {
+		/* In PCC layout a bit-field is placed adjacent to the
+                   preceding bit-fields, except if:
+                   - it has zero-width
+                   - an individual alignment was given
+                   - it would overflow its base type container and
+                     there is no packing */
+                if (bit_size == 0) {
+            new_field:
+		    c = (c + ((bit_pos + 7) >> 3) + align - 1) & -align;
+		    bit_pos = 0;
+                } else if (f->a.aligned) {
+                    goto new_field;
+                } else if (!packed) {
+                    int a8 = align * 8;
+	            int ofs = ((c * 8 + bit_pos) % a8 + bit_size + a8 - 1) / a8;
+                    if (ofs > size / align)
+                        goto new_field;
+                }
+
+                /* in pcc mode, long long bitfields have type int if they fit */
+                if (size == 8 && bit_size <= 32)
+                    f->type.t = (f->type.t & ~VT_BTYPE) | VT_INT, size = 4;
+
+                while (bit_pos >= align * 8)
+                    c += align, bit_pos -= align * 8;
+                offset = c;
+
+		/* In PCC layout named bit-fields influence the alignment
+		   of the containing struct using the base types alignment,
+		   except for packed fields (which here have correct align).  */
+		if (f->v & SYM_FIRST_ANOM
+                    // && bit_size // ??? gcc on ARM/rpi does that
+                    )
+		    align = 1;
+
+	    } else {
+		bt = f->type.t & VT_BTYPE;
+		if ((bit_pos + bit_size > size * 8)
+                    || (bit_size > 0) == (bt != prevbt)
+                    ) {
+		    c = (c + align - 1) & -align;
+		    offset = c;
+		    bit_pos = 0;
+		    /* In MS bitfield mode a bit-field run always uses
+		       at least as many bits as the underlying type.
+		       To start a new run it's also required that this
+		       or the last bit-field had non-zero width.  */
+		    if (bit_size || prev_bit_size)
+		        c += size;
+		}
+		/* In MS layout the records alignment is normally
+		   influenced by the field, except for a zero-width
+		   field at the start of a run (but by further zero-width
+		   fields it is again).  */
+		if (bit_size == 0 && prevbt != bt)
+		    align = 1;
+		prevbt = bt;
+                prev_bit_size = bit_size;
+	    }
+
+	    f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
+		        | (bit_pos << VT_STRUCT_SHIFT);
+	    bit_pos += bit_size;
+	}
+	if (align > maxalign)
+	    maxalign = align;
+
+#ifdef BF_DEBUG
+	printf("set field %s offset %-2d size %-2d align %-2d",
+	       get_tok_str(f->v & ~SYM_FIELD, NULL), offset, size, align);
+	if (f->type.t & VT_BITFIELD) {
+	    printf(" pos %-2d bits %-2d",
+                    BIT_POS(f->type.t),
+                    BIT_SIZE(f->type.t)
+                    );
+	}
+	printf("\n");
+#endif
+
+	if (f->v & SYM_FIRST_ANOM && (f->type.t & VT_BTYPE) == VT_STRUCT) {
+	    Sym *ass;
+	    /* An anonymous struct/union.  Adjust member offsets
+	       to reflect the real offset of our containing struct.
+	       Also set the offset of this anon member inside
+	       the outer struct to be zero.  Via this it
+	       works when accessing the field offset directly
+	       (from base object), as well as when recursing
+	       members in initializer handling.  */
+	    int v2 = f->type.ref->v;
+	    if (!(v2 & SYM_FIELD) &&
+		(v2 & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
+		Sym **pps;
+		/* This happens only with MS extensions.  The
+		   anon member has a named struct type, so it
+		   potentially is shared with other references.
+		   We need to unshare members so we can modify
+		   them.  */
+		ass = f->type.ref;
+		f->type.ref = sym_push(anon_sym++ | SYM_FIELD,
+				       &f->type.ref->type, 0,
+				       f->type.ref->c);
+		pps = &f->type.ref->next;
+		while ((ass = ass->next) != NULL) {
+		    *pps = sym_push(ass->v, &ass->type, 0, ass->c);
+		    pps = &((*pps)->next);
+		}
+		*pps = NULL;
+	    }
+	    struct_add_offset(f->type.ref, offset);
+	    f->c = 0;
+	} else {
+	    f->c = offset;
+	}
+
+	f->r = 0;
+    }
+
+    if (pcc)
+        c += (bit_pos + 7) >> 3;
+
+    /* store size and alignment */
+    a = bt = ad->a.aligned ? 1 << (ad->a.aligned - 1) : 1;
+    if (a < maxalign)
+        a = maxalign;
+    type->ref->r = a;
+    if (pragma_pack && pragma_pack < maxalign && 0 == pcc) {
+        /* can happen if individual align for some member was given.  In
+           this case MSVC ignores maxalign when aligning the size */
+        a = pragma_pack;
+        if (a < bt)
+            a = bt;
+    }
+    c = (c + a - 1) & -a;
+    type->ref->c = c;
+
+#ifdef BF_DEBUG
+    printf("struct size %-2d align %-2d\n\n", c, a), fflush(stdout);
+#endif
+
+    /* check whether we can access bitfields by their type */
+    for (f = type->ref->next; f; f = f->next) {
+        int s, px, cx, c0;
+        CType t;
+
+        if (0 == (f->type.t & VT_BITFIELD))
+            continue;
+        f->type.ref = f;
+        f->auxtype = -1;
+        bit_size = BIT_SIZE(f->type.t);
+        if (bit_size == 0)
+            continue;
+        bit_pos = BIT_POS(f->type.t);
+        size = type_size(&f->type, &align);
+        if (bit_pos + bit_size <= size * 8 && f->c + size <= c)
+            continue;
+
+        /* try to access the field using a different type */
+        c0 = -1, s = align = 1;
+        for (;;) {
+            px = f->c * 8 + bit_pos;
+            cx = (px >> 3) & -align;
+            px = px - (cx << 3);
+            if (c0 == cx)
+                break;
+            s = (px + bit_size + 7) >> 3;
+            if (s > 4) {
+                t.t = VT_LLONG;
+            } else if (s > 2) {
+                t.t = VT_INT;
+            } else if (s > 1) {
+                t.t = VT_SHORT;
+            } else {
+                t.t = VT_BYTE;
+            }
+            s = type_size(&t, &align);
+            c0 = cx;
+        }
+
+        if (px + bit_size <= s * 8 && cx + s <= c) {
+            /* update offset and bit position */
+            f->c = cx;
+            bit_pos = px;
+	    f->type.t = (f->type.t & ~(0x3f << VT_STRUCT_SHIFT))
+		        | (bit_pos << VT_STRUCT_SHIFT);
+            if (s != size)
+                f->auxtype = t.t;
+#ifdef BF_DEBUG
+            printf("FIX field %s offset %-2d size %-2d align %-2d "
+                "pos %-2d bits %-2d\n",
+                get_tok_str(f->v & ~SYM_FIELD, NULL),
+                cx, s, align, px, bit_size);
+#endif
+        } else {
+            /* fall back to load/store single-byte wise */
+            f->auxtype = VT_STRUCT;
+#ifdef BF_DEBUG
+            printf("FIX field %s : load byte-wise\n",
+                 get_tok_str(f->v & ~SYM_FIELD, NULL));
+#endif
+        }
+    }
+}
+
+/* enum/struct/union declaration. u is VT_ENUM/VT_STRUCT/VT_UNION */
+static void struct_decl(CType *type, int u)
+{
+    int v, c, size, align, flexible;
+    int bit_size, bsize, bt;
+    Sym *s, *ss, **ps;
+    AttributeDef ad, ad1;
+    CType type1, btype;
+
+    memset(&ad, 0, sizeof ad);
+    next();
+    parse_attribute(&ad);
+    if (tok != '{') {
+        v = tok;
+        next();
+        /* struct already defined ? return it */
+        if (v < TOK_IDENT)
+            expect("struct/union/enum name");
+        s = struct_find(v);
+        if (s && (s->sym_scope == local_scope || tok != '{')) {
+            if (u == s->type.t)
+                goto do_decl;
+            if (u == VT_ENUM && IS_ENUM(s->type.t))
+                goto do_decl;
+            tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
+        }
+    } else {
+        v = anon_sym++;
+    }
+    /* Record the original enum/struct/union token.  */
+    type1.t = u == VT_ENUM ? u | VT_INT | VT_UNSIGNED : u;
+    type1.ref = NULL;
+    /* we put an undefined size for struct/union */
+    s = sym_push(v | SYM_STRUCT, &type1, 0, -1);
+    s->r = 0; /* default alignment is zero as gcc */
+do_decl:
+    type->t = s->type.t;
+    type->ref = s;
+
+    if (tok == '{') {
+        next();
+        if (s->c != -1)
+            tcc_error("struct/union/enum already defined");
+        /* cannot be empty */
+        /* non empty enums are not allowed */
+        ps = &s->next;
+        if (u == VT_ENUM) {
+            long long ll = 0, pl = 0, nl = 0;
+	    CType t;
+            t.ref = s;
+            /* enum symbols have static storage */
+            t.t = VT_INT|VT_STATIC|VT_ENUM_VAL;
+            for(;;) {
+                v = tok;
+                if (v < TOK_UIDENT)
+                    expect("identifier");
+                ss = sym_find(v);
+                if (ss && !local_stack)
+                    tcc_error("redefinition of enumerator '%s'",
+                              get_tok_str(v, NULL));
+                next();
+                if (tok == '=') {
+                    next();
+		    ll = expr_const64();
+                }
+                ss = sym_push(v, &t, VT_CONST, 0);
+                ss->enum_val = ll;
+                *ps = ss, ps = &ss->next;
+                if (ll < nl)
+                    nl = ll;
+                if (ll > pl)
+                    pl = ll;
+                if (tok != ',')
+                    break;
+                next();
+                ll++;
+                /* NOTE: we accept a trailing comma */
+                if (tok == '}')
+                    break;
+            }
+            skip('}');
+            /* set integral type of the enum */
+            t.t = VT_INT;
+            if (nl >= 0) {
+                if (pl != (unsigned)pl)
+                    t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
+                t.t |= VT_UNSIGNED;
+            } else if (pl != (int)pl || nl != (int)nl)
+                t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
+            s->type.t = type->t = t.t | VT_ENUM;
+            s->c = 0;
+            /* set type for enum members */
+            for (ss = s->next; ss; ss = ss->next) {
+                ll = ss->enum_val;
+                if (ll == (int)ll) /* default is int if it fits */
+                    continue;
+                if (t.t & VT_UNSIGNED) {
+                    ss->type.t |= VT_UNSIGNED;
+                    if (ll == (unsigned)ll)
+                        continue;
+                }
+                ss->type.t = (ss->type.t & ~VT_BTYPE)
+                    | (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
+            }
+        } else {
+            c = 0;
+            flexible = 0;
+            while (tok != '}') {
+                if (!parse_btype(&btype, &ad1)) {
+		    skip(';');
+		    continue;
+		}
+                while (1) {
+		    if (flexible)
+		        tcc_error("flexible array member '%s' not at the end of struct",
+                              get_tok_str(v, NULL));
+                    bit_size = -1;
+                    v = 0;
+                    type1 = btype;
+                    if (tok != ':') {
+			if (tok != ';')
+                            type_decl(&type1, &ad1, &v, TYPE_DIRECT);
+                        if (v == 0) {
+                    	    if ((type1.t & VT_BTYPE) != VT_STRUCT)
+                        	expect("identifier");
+                    	    else {
+				int v = btype.ref->v;
+				if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
+				    if (tcc_state->ms_extensions == 0)
+                        		expect("identifier");
+				}
+                    	    }
+                        }
+                        if (type_size(&type1, &align) < 0) {
+			    if ((u == VT_STRUCT) && (type1.t & VT_ARRAY) && c)
+			        flexible = 1;
+			    else
+			        tcc_error("field '%s' has incomplete type",
+                                      get_tok_str(v, NULL));
+                        }
+                        if ((type1.t & VT_BTYPE) == VT_FUNC ||
+                            (type1.t & VT_STORAGE))
+                            tcc_error("invalid type for '%s'", 
+                                  get_tok_str(v, NULL));
+                    }
+                    if (tok == ':') {
+                        next();
+                        bit_size = expr_const();
+                        /* XXX: handle v = 0 case for messages */
+                        if (bit_size < 0)
+                            tcc_error("negative width in bit-field '%s'", 
+                                  get_tok_str(v, NULL));
+                        if (v && bit_size == 0)
+                            tcc_error("zero width for bit-field '%s'", 
+                                  get_tok_str(v, NULL));
+			parse_attribute(&ad1);
+                    }
+                    size = type_size(&type1, &align);
+                    if (bit_size >= 0) {
+                        bt = type1.t & VT_BTYPE;
+                        if (bt != VT_INT && 
+                            bt != VT_BYTE && 
+                            bt != VT_SHORT &&
+                            bt != VT_BOOL &&
+                            bt != VT_LLONG)
+                            tcc_error("bitfields must have scalar type");
+                        bsize = size * 8;
+                        if (bit_size > bsize) {
+                            tcc_error("width of '%s' exceeds its type",
+                                  get_tok_str(v, NULL));
+                        } else if (bit_size == bsize
+                                    && !ad.a.packed && !ad1.a.packed) {
+                            /* no need for bit fields */
+                            ;
+                        } else if (bit_size == 64) {
+                            tcc_error("field width 64 not implemented");
+                        } else {
+                            type1.t = (type1.t & ~VT_STRUCT_MASK)
+                                | VT_BITFIELD
+                                | (bit_size << (VT_STRUCT_SHIFT + 6));
+                        }
+                    }
+                    if (v != 0 || (type1.t & VT_BTYPE) == VT_STRUCT) {
+                        /* Remember we've seen a real field to check
+			   for placement of flexible array member. */
+			c = 1;
+                    }
+		    /* If member is a struct or bit-field, enforce
+		       placing into the struct (as anonymous).  */
+                    if (v == 0 &&
+			((type1.t & VT_BTYPE) == VT_STRUCT ||
+			 bit_size >= 0)) {
+		        v = anon_sym++;
+		    }
+                    if (v) {
+                        ss = sym_push(v | SYM_FIELD, &type1, 0, 0);
+                        ss->a = ad1.a;
+                        *ps = ss;
+                        ps = &ss->next;
+                    }
+                    if (tok == ';' || tok == TOK_EOF)
+                        break;
+                    skip(',');
+                }
+                skip(';');
+            }
+            skip('}');
+	    parse_attribute(&ad);
+	    struct_layout(type, &ad);
+        }
+    }
+}
+
+static void sym_to_attr(AttributeDef *ad, Sym *s)
+{
+    if (s->a.aligned && 0 == ad->a.aligned)
+        ad->a.aligned = s->a.aligned;
+    if (s->f.func_call && 0 == ad->f.func_call)
+        ad->f.func_call = s->f.func_call;
+    if (s->f.func_type && 0 == ad->f.func_type)
+        ad->f.func_type = s->f.func_type;
+    if (s->a.packed)
+        ad->a.packed = 1;
+}
+
+/* Add type qualifiers to a type. If the type is an array then the qualifiers
+   are added to the element type, copied because it could be a typedef. */
+static void parse_btype_qualify(CType *type, int qualifiers)
+{
+    while (type->t & VT_ARRAY) {
+        type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c);
+        type = &type->ref->type;
+    }
+    type->t |= qualifiers;
+}
+
+/* return 0 if no type declaration. otherwise, return the basic type
+   and skip it. 
+ */
+static int parse_btype(CType *type, AttributeDef *ad)
+{
+    int t, u, bt, st, type_found, typespec_found, g;
+    Sym *s;
+    CType type1;
+
+    memset(ad, 0, sizeof(AttributeDef));
+    type_found = 0;
+    typespec_found = 0;
+    t = VT_INT;
+    bt = st = -1;
+    type->ref = NULL;
+
+    while(1) {
+        switch(tok) {
+        case TOK_EXTENSION:
+            /* currently, we really ignore extension */
+            next();
+            continue;
+
+            /* basic types */
+        case TOK_CHAR:
+            u = VT_BYTE;
+        basic_type:
+            next();
+        basic_type1:
+            if (u == VT_SHORT || u == VT_LONG) {
+                if (st != -1 || (bt != -1 && bt != VT_INT))
+                    tmbt: tcc_error("too many basic types");
+                st = u;
+            } else {
+                if (bt != -1 || (st != -1 && u != VT_INT))
+                    goto tmbt;
+                bt = u;
+            }
+            if (u != VT_INT)
+                t = (t & ~(VT_BTYPE|VT_LONG)) | u;
+            typespec_found = 1;
+            break;
+        case TOK_VOID:
+            u = VT_VOID;
+            goto basic_type;
+        case TOK_SHORT:
+            u = VT_SHORT;
+            goto basic_type;
+        case TOK_INT:
+            u = VT_INT;
+            goto basic_type;
+        case TOK_LONG:
+            if ((t & VT_BTYPE) == VT_DOUBLE) {
+                t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
+            } else if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
+                t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LLONG;
+            } else {
+                u = VT_LONG;
+                goto basic_type;
+            }
+            next();
+            break;
+#ifdef TCC_TARGET_ARM64
+        case TOK_UINT128:
+            /* GCC's __uint128_t appears in some Linux header files. Make it a
+               synonym for long double to get the size and alignment right. */
+            u = VT_LDOUBLE;
+            goto basic_type;
+#endif
+        case TOK_BOOL:
+            u = VT_BOOL;
+            goto basic_type;
+        case TOK_FLOAT:
+            u = VT_FLOAT;
+            goto basic_type;
+        case TOK_DOUBLE:
+            if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
+                t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
+            } else {
+                u = VT_DOUBLE;
+                goto basic_type;
+            }
+            next();
+            break;
+        case TOK_ENUM:
+            struct_decl(&type1, VT_ENUM);
+        basic_type2:
+            u = type1.t;
+            type->ref = type1.ref;
+            goto basic_type1;
+        case TOK_STRUCT:
+            struct_decl(&type1, VT_STRUCT);
+            goto basic_type2;
+        case TOK_UNION:
+            struct_decl(&type1, VT_UNION);
+            goto basic_type2;
+
+            /* type modifiers */
+        case TOK_CONST1:
+        case TOK_CONST2:
+        case TOK_CONST3:
+            type->t = t;
+            parse_btype_qualify(type, VT_CONSTANT);
+            t = type->t;
+            next();
+            break;
+        case TOK_VOLATILE1:
+        case TOK_VOLATILE2:
+        case TOK_VOLATILE3:
+            type->t = t;
+            parse_btype_qualify(type, VT_VOLATILE);
+            t = type->t;
+            next();
+            break;
+        case TOK_SIGNED1:
+        case TOK_SIGNED2:
+        case TOK_SIGNED3:
+            if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == (VT_DEFSIGN|VT_UNSIGNED))
+                tcc_error("signed and unsigned modifier");
+            t |= VT_DEFSIGN;
+            next();
+            typespec_found = 1;
+            break;
+        case TOK_REGISTER:
+        case TOK_AUTO:
+        case TOK_RESTRICT1:
+        case TOK_RESTRICT2:
+        case TOK_RESTRICT3:
+            next();
+            break;
+        case TOK_UNSIGNED:
+            if ((t & (VT_DEFSIGN|VT_UNSIGNED)) == VT_DEFSIGN)
+                tcc_error("signed and unsigned modifier");
+            t |= VT_DEFSIGN | VT_UNSIGNED;
+            next();
+            typespec_found = 1;
+            break;
+
+            /* storage */
+        case TOK_EXTERN:
+            g = VT_EXTERN;
+            goto storage;
+        case TOK_STATIC:
+            g = VT_STATIC;
+            goto storage;
+        case TOK_TYPEDEF:
+            g = VT_TYPEDEF;
+            goto storage;
+       storage:
+            if (t & (VT_EXTERN|VT_STATIC|VT_TYPEDEF) & ~g)
+                tcc_error("multiple storage classes");
+            t |= g;
+            next();
+            break;
+        case TOK_INLINE1:
+        case TOK_INLINE2:
+        case TOK_INLINE3:
+            t |= VT_INLINE;
+            next();
+            break;
+
+            /* GNUC attribute */
+        case TOK_ATTRIBUTE1:
+        case TOK_ATTRIBUTE2:
+            parse_attribute(ad);
+            if (ad->attr_mode) {
+                u = ad->attr_mode -1;
+                t = (t & ~(VT_BTYPE|VT_LONG)) | u;
+            }
+            break;
+            /* GNUC typeof */
+        case TOK_TYPEOF1:
+        case TOK_TYPEOF2:
+        case TOK_TYPEOF3:
+            next();
+            parse_expr_type(&type1);
+            /* remove all storage modifiers except typedef */
+            type1.t &= ~(VT_STORAGE&~VT_TYPEDEF);
+	    if (type1.ref)
+                sym_to_attr(ad, type1.ref);
+            goto basic_type2;
+        default:
+            if (typespec_found)
+                goto the_end;
+            s = sym_find(tok);
+            if (!s || !(s->type.t & VT_TYPEDEF))
+                goto the_end;
+            t &= ~(VT_BTYPE|VT_LONG);
+            u = t & ~(VT_CONSTANT | VT_VOLATILE), t ^= u;
+            type->t = (s->type.t & ~VT_TYPEDEF) | u;
+            type->ref = s->type.ref;
+            if (t)
+                parse_btype_qualify(type, t);
+            t = type->t;
+            /* get attributes from typedef */
+            sym_to_attr(ad, s);
+            next();
+            typespec_found = 1;
+            st = bt = -2;
+            break;
+        }
+        type_found = 1;
+    }
+the_end:
+    if (tcc_state->char_is_unsigned) {
+        if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
+            t |= VT_UNSIGNED;
+    }
+    /* VT_LONG is used just as a modifier for VT_INT / VT_LLONG */
+    bt = t & (VT_BTYPE|VT_LONG);
+    if (bt == VT_LONG)
+        t |= LONG_SIZE == 8 ? VT_LLONG : VT_INT;
+#ifdef TCC_TARGET_PE
+    if (bt == VT_LDOUBLE)
+        t = (t & ~(VT_BTYPE|VT_LONG)) | VT_DOUBLE;
+#endif
+    type->t = t;
+    return type_found;
+}
+
+/* convert a function parameter type (array to pointer and function to
+   function pointer) */
+static inline void convert_parameter_type(CType *pt)
+{
+    /* remove const and volatile qualifiers (XXX: const could be used
+       to indicate a const function parameter */
+    pt->t &= ~(VT_CONSTANT | VT_VOLATILE);
+    /* array must be transformed to pointer according to ANSI C */
+    pt->t &= ~VT_ARRAY;
+    if ((pt->t & VT_BTYPE) == VT_FUNC) {
+        mk_pointer(pt);
+    }
+}
+
+ST_FUNC void parse_asm_str(CString *astr)
+{
+    skip('(');
+    parse_mult_str(astr, "string constant");
+}
+
+/* Parse an asm label and return the token */
+static int asm_label_instr(void)
+{
+    int v;
+    CString astr;
+
+    next();
+    parse_asm_str(&astr);
+    skip(')');
+#ifdef ASM_DEBUG
+    printf("asm_alias: \"%s\"\n", (char *)astr.data);
+#endif
+    v = tok_alloc(astr.data, astr.size - 1)->tok;
+    cstr_free(&astr);
+    return v;
+}
+
+static int post_type(CType *type, AttributeDef *ad, int storage, int td)
+{
+    int n, l, t1, arg_size, align;
+    Sym **plast, *s, *first;
+    AttributeDef ad1;
+    CType pt;
+
+    if (tok == '(') {
+        /* function type, or recursive declarator (return if so) */
+        next();
+	if (td && !(td & TYPE_ABSTRACT))
+	  return 0;
+	if (tok == ')')
+	  l = 0;
+	else if (parse_btype(&pt, &ad1))
+	  l = FUNC_NEW;
+	else if (td)
+	  return 0;
+	else
+	  l = FUNC_OLD;
+        first = NULL;
+        plast = &first;
+        arg_size = 0;
+        if (l) {
+            for(;;) {
+                /* read param name and compute offset */
+                if (l != FUNC_OLD) {
+                    if ((pt.t & VT_BTYPE) == VT_VOID && tok == ')')
+                        break;
+                    type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
+                    if ((pt.t & VT_BTYPE) == VT_VOID)
+                        tcc_error("parameter declared as void");
+                    arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
+                } else {
+                    n = tok;
+                    if (n < TOK_UIDENT)
+                        expect("identifier");
+                    pt.t = VT_VOID; /* invalid type */
+                    next();
+                }
+                convert_parameter_type(&pt);
+                s = sym_push(n | SYM_FIELD, &pt, 0, 0);
+                *plast = s;
+                plast = &s->next;
+                if (tok == ')')
+                    break;
+                skip(',');
+                if (l == FUNC_NEW && tok == TOK_DOTS) {
+                    l = FUNC_ELLIPSIS;
+                    next();
+                    break;
+                }
+		if (l == FUNC_NEW && !parse_btype(&pt, &ad1))
+		    tcc_error("invalid type");
+            }
+        } else
+            /* if no parameters, then old type prototype */
+            l = FUNC_OLD;
+        skip(')');
+        /* NOTE: const is ignored in returned type as it has a special
+           meaning in gcc / C++ */
+        type->t &= ~VT_CONSTANT; 
+        /* some ancient pre-K&R C allows a function to return an array
+           and the array brackets to be put after the arguments, such 
+           that "int c()[]" means something like "int[] c()" */
+        if (tok == '[') {
+            next();
+            skip(']'); /* only handle simple "[]" */
+            mk_pointer(type);
+        }
+        /* we push a anonymous symbol which will contain the function prototype */
+        ad->f.func_args = arg_size;
+        ad->f.func_type = l;
+        s = sym_push(SYM_FIELD, type, 0, 0);
+        s->a = ad->a;
+        s->f = ad->f;
+        s->next = first;
+        type->t = VT_FUNC;
+        type->ref = s;
+    } else if (tok == '[') {
+	int saved_nocode_wanted = nocode_wanted;
+        /* array definition */
+        next();
+        if (tok == TOK_RESTRICT1)
+            next();
+        n = -1;
+        t1 = 0;
+        if (tok != ']') {
+            if (!local_stack || (storage & VT_STATIC))
+                vpushi(expr_const());
+            else {
+		/* VLAs (which can only happen with local_stack && !VT_STATIC)
+		   length must always be evaluated, even under nocode_wanted,
+		   so that its size slot is initialized (e.g. under sizeof
+		   or typeof).  */
+		nocode_wanted = 0;
+		gexpr();
+	    }
+            if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+                n = vtop->c.i;
+                if (n < 0)
+                    tcc_error("invalid array size");
+            } else {
+                if (!is_integer_btype(vtop->type.t & VT_BTYPE))
+                    tcc_error("size of variable length array should be an integer");
+                t1 = VT_VLA;
+            }
+        }
+        skip(']');
+        /* parse next post type */
+        post_type(type, ad, storage, 0);
+        if (type->t == VT_FUNC)
+            tcc_error("declaration of an array of functions");
+        t1 |= type->t & VT_VLA;
+        
+        if (t1 & VT_VLA) {
+            loc -= type_size(&int_type, &align);
+            loc &= -align;
+            n = loc;
+
+            vla_runtime_type_size(type, &align);
+            gen_op('*');
+            vset(&int_type, VT_LOCAL|VT_LVAL, n);
+            vswap();
+            vstore();
+        }
+        if (n != -1)
+            vpop();
+	nocode_wanted = saved_nocode_wanted;
+                
+        /* we push an anonymous symbol which will contain the array
+           element type */
+        s = sym_push(SYM_FIELD, type, 0, n);
+        type->t = (t1 ? VT_VLA : VT_ARRAY) | VT_PTR;
+        type->ref = s;
+    }
+    return 1;
+}
+
+/* Parse a type declarator (except basic type), and return the type
+   in 'type'. 'td' is a bitmask indicating which kind of type decl is
+   expected. 'type' should contain the basic type. 'ad' is the
+   attribute definition of the basic type. It can be modified by
+   type_decl().  If this (possibly abstract) declarator is a pointer chain
+   it returns the innermost pointed to type (equals *type, but is a different
+   pointer), otherwise returns type itself, that's used for recursive calls.  */
+static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td)
+{
+    CType *post, *ret;
+    int qualifiers, storage;
+
+    /* recursive type, remove storage bits first, apply them later again */
+    storage = type->t & VT_STORAGE;
+    type->t &= ~VT_STORAGE;
+    post = ret = type;
+
+    while (tok == '*') {
+        qualifiers = 0;
+    redo:
+        next();
+        switch(tok) {
+        case TOK_CONST1:
+        case TOK_CONST2:
+        case TOK_CONST3:
+            qualifiers |= VT_CONSTANT;
+            goto redo;
+        case TOK_VOLATILE1:
+        case TOK_VOLATILE2:
+        case TOK_VOLATILE3:
+            qualifiers |= VT_VOLATILE;
+            goto redo;
+        case TOK_RESTRICT1:
+        case TOK_RESTRICT2:
+        case TOK_RESTRICT3:
+            goto redo;
+	/* XXX: clarify attribute handling */
+	case TOK_ATTRIBUTE1:
+	case TOK_ATTRIBUTE2:
+	    parse_attribute(ad);
+	    break;
+        }
+        mk_pointer(type);
+        type->t |= qualifiers;
+	if (ret == type)
+	    /* innermost pointed to type is the one for the first derivation */
+	    ret = pointed_type(type);
+    }
+
+    if (tok == '(') {
+	/* This is possibly a parameter type list for abstract declarators
+	   ('int ()'), use post_type for testing this.  */
+	if (!post_type(type, ad, 0, td)) {
+	    /* It's not, so it's a nested declarator, and the post operations
+	       apply to the innermost pointed to type (if any).  */
+	    /* XXX: this is not correct to modify 'ad' at this point, but
+	       the syntax is not clear */
+	    parse_attribute(ad);
+	    post = type_decl(type, ad, v, td);
+	    skip(')');
+	}
+    } else if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
+	/* type identifier */
+	*v = tok;
+	next();
+    } else {
+	if (!(td & TYPE_ABSTRACT))
+	  expect("identifier");
+	*v = 0;
+    }
+    post_type(post, ad, storage, 0);
+    parse_attribute(ad);
+    type->t |= storage;
+    return ret;
+}
+
+/* compute the lvalue VT_LVAL_xxx needed to match type t. */
+ST_FUNC int lvalue_type(int t)
+{
+    int bt, r;
+    r = VT_LVAL;
+    bt = t & VT_BTYPE;
+    if (bt == VT_BYTE || bt == VT_BOOL)
+        r |= VT_LVAL_BYTE;
+    else if (bt == VT_SHORT)
+        r |= VT_LVAL_SHORT;
+    else
+        return r;
+    if (t & VT_UNSIGNED)
+        r |= VT_LVAL_UNSIGNED;
+    return r;
+}
+
+/* indirection with full error checking and bound check */
+ST_FUNC void indir(void)
+{
+    if ((vtop->type.t & VT_BTYPE) != VT_PTR) {
+        if ((vtop->type.t & VT_BTYPE) == VT_FUNC)
+            return;
+        expect("pointer");
+    }
+    if (vtop->r & VT_LVAL)
+        gv(RC_INT);
+    vtop->type = *pointed_type(&vtop->type);
+    /* Arrays and functions are never lvalues */
+    if (!(vtop->type.t & VT_ARRAY) && !(vtop->type.t & VT_VLA)
+        && (vtop->type.t & VT_BTYPE) != VT_FUNC) {
+        vtop->r |= lvalue_type(vtop->type.t);
+        /* if bound checking, the referenced pointer must be checked */
+#ifdef CONFIG_TCC_BCHECK
+        if (tcc_state->do_bounds_check)
+            vtop->r |= VT_MUSTBOUND;
+#endif
+    }
+}
+
+/* pass a parameter to a function and do type checking and casting */
+static void gfunc_param_typed(Sym *func, Sym *arg)
+{
+    int func_type;
+    CType type;
+
+    func_type = func->f.func_type;
+    if (func_type == FUNC_OLD ||
+        (func_type == FUNC_ELLIPSIS && arg == NULL)) {
+        /* default casting : only need to convert float to double */
+        if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) {
+            gen_cast_s(VT_DOUBLE);
+        } else if (vtop->type.t & VT_BITFIELD) {
+            type.t = vtop->type.t & (VT_BTYPE | VT_UNSIGNED);
+	    type.ref = vtop->type.ref;
+            gen_cast(&type);
+        }
+    } else if (arg == NULL) {
+        tcc_error("too many arguments to function");
+    } else {
+        type = arg->type;
+        type.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
+        gen_assign_cast(&type);
+    }
+}
+
+/* parse an expression and return its type without any side effect. */
+static void expr_type(CType *type, void (*expr_fn)(void))
+{
+    nocode_wanted++;
+    expr_fn();
+    *type = vtop->type;
+    vpop();
+    nocode_wanted--;
+}
+
+/* parse an expression of the form '(type)' or '(expr)' and return its
+   type */
+static void parse_expr_type(CType *type)
+{
+    int n;
+    AttributeDef ad;
+
+    skip('(');
+    if (parse_btype(type, &ad)) {
+        type_decl(type, &ad, &n, TYPE_ABSTRACT);
+    } else {
+        expr_type(type, gexpr);
+    }
+    skip(')');
+}
+
+static void parse_type(CType *type)
+{
+    AttributeDef ad;
+    int n;
+
+    if (!parse_btype(type, &ad)) {
+        expect("type");
+    }
+    type_decl(type, &ad, &n, TYPE_ABSTRACT);
+}
+
+static void parse_builtin_params(int nc, const char *args)
+{
+    char c, sep = '(';
+    CType t;
+    if (nc)
+        nocode_wanted++;
+    next();
+    while ((c = *args++)) {
+	skip(sep);
+	sep = ',';
+	switch (c) {
+	    case 'e': expr_eq(); continue;
+	    case 't': parse_type(&t); vpush(&t); continue;
+	    default: tcc_error("internal error"); break;
+	}
+    }
+    skip(')');
+    if (nc)
+        nocode_wanted--;
+}
+
+ST_FUNC void unary(void)
+{
+    int n, t, align, size, r, sizeof_caller;
+    CType type;
+    Sym *s;
+    AttributeDef ad;
+
+    sizeof_caller = in_sizeof;
+    in_sizeof = 0;
+    type.ref = NULL;
+    /* XXX: GCC 2.95.3 does not generate a table although it should be
+       better here */
+ tok_next:
+    switch(tok) {
+    case TOK_EXTENSION:
+        next();
+        goto tok_next;
+    case TOK_LCHAR:
+#ifdef TCC_TARGET_PE
+        t = VT_SHORT|VT_UNSIGNED;
+        goto push_tokc;
+#endif
+    case TOK_CINT:
+    case TOK_CCHAR: 
+	t = VT_INT;
+ push_tokc:
+	type.t = t;
+	vsetc(&type, VT_CONST, &tokc);
+        next();
+        break;
+    case TOK_CUINT:
+        t = VT_INT | VT_UNSIGNED;
+        goto push_tokc;
+    case TOK_CLLONG:
+        t = VT_LLONG;
+	goto push_tokc;
+    case TOK_CULLONG:
+        t = VT_LLONG | VT_UNSIGNED;
+	goto push_tokc;
+    case TOK_CFLOAT:
+        t = VT_FLOAT;
+	goto push_tokc;
+    case TOK_CDOUBLE:
+        t = VT_DOUBLE;
+	goto push_tokc;
+    case TOK_CLDOUBLE:
+        t = VT_LDOUBLE;
+	goto push_tokc;
+    case TOK_CLONG:
+        t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG;
+	goto push_tokc;
+    case TOK_CULONG:
+        t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG | VT_UNSIGNED;
+	goto push_tokc;
+    case TOK___FUNCTION__:
+        if (!gnu_ext)
+            goto tok_identifier;
+        /* fall thru */
+    case TOK___FUNC__:
+        {
+            void *ptr;
+            int len;
+            /* special function name identifier */
+            len = strlen(funcname) + 1;
+            /* generate char[len] type */
+            type.t = VT_BYTE;
+            mk_pointer(&type);
+            type.t |= VT_ARRAY;
+            type.ref->c = len;
+            vpush_ref(&type, data_section, data_section->data_offset, len);
+            if (!NODATA_WANTED) {
+                ptr = section_ptr_add(data_section, len);
+                memcpy(ptr, funcname, len);
+            }
+            next();
+        }
+        break;
+    case TOK_LSTR:
+#ifdef TCC_TARGET_PE
+        t = VT_SHORT | VT_UNSIGNED;
+#else
+        t = VT_INT;
+#endif
+        goto str_init;
+    case TOK_STR:
+        /* string parsing */
+        t = VT_BYTE;
+        if (tcc_state->char_is_unsigned)
+            t = VT_BYTE | VT_UNSIGNED;
+    str_init:
+        if (tcc_state->warn_write_strings)
+            t |= VT_CONSTANT;
+        type.t = t;
+        mk_pointer(&type);
+        type.t |= VT_ARRAY;
+        memset(&ad, 0, sizeof(AttributeDef));
+        decl_initializer_alloc(&type, &ad, VT_CONST, 2, 0, 0);
+        break;
+    case '(':
+        next();
+        /* cast ? */
+        if (parse_btype(&type, &ad)) {
+            type_decl(&type, &ad, &n, TYPE_ABSTRACT);
+            skip(')');
+            /* check ISOC99 compound literal */
+            if (tok == '{') {
+                    /* data is allocated locally by default */
+                if (global_expr)
+                    r = VT_CONST;
+                else
+                    r = VT_LOCAL;
+                /* all except arrays are lvalues */
+                if (!(type.t & VT_ARRAY))
+                    r |= lvalue_type(type.t);
+                memset(&ad, 0, sizeof(AttributeDef));
+                decl_initializer_alloc(&type, &ad, r, 1, 0, 0);
+            } else {
+                if (sizeof_caller) {
+                    vpush(&type);
+                    return;
+                }
+                unary();
+                gen_cast(&type);
+            }
+        } else if (tok == '{') {
+	    int saved_nocode_wanted = nocode_wanted;
+            if (const_wanted)
+                tcc_error("expected constant");
+            /* save all registers */
+            save_regs(0);
+            /* statement expression : we do not accept break/continue
+               inside as GCC does.  We do retain the nocode_wanted state,
+	       as statement expressions can't ever be entered from the
+	       outside, so any reactivation of code emission (from labels
+	       or loop heads) can be disabled again after the end of it. */
+            block(NULL, NULL, 1);
+	    nocode_wanted = saved_nocode_wanted;
+            skip(')');
+        } else {
+            gexpr();
+            skip(')');
+        }
+        break;
+    case '*':
+        next();
+        unary();
+        indir();
+        break;
+    case '&':
+        next();
+        unary();
+        /* functions names must be treated as function pointers,
+           except for unary '&' and sizeof. Since we consider that
+           functions are not lvalues, we only have to handle it
+           there and in function calls. */
+        /* arrays can also be used although they are not lvalues */
+        if ((vtop->type.t & VT_BTYPE) != VT_FUNC &&
+            !(vtop->type.t & VT_ARRAY))
+            test_lvalue();
+        mk_pointer(&vtop->type);
+        gaddrof();
+        break;
+    case '!':
+        next();
+        unary();
+        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+            gen_cast_s(VT_BOOL);
+            vtop->c.i = !vtop->c.i;
+        } else if ((vtop->r & VT_VALMASK) == VT_CMP)
+            vtop->c.i ^= 1;
+        else {
+            save_regs(1);
+            vseti(VT_JMP, gvtst(1, 0));
+        }
+        break;
+    case '~':
+        next();
+        unary();
+        vpushi(-1);
+        gen_op('^');
+        break;
+    case '+':
+        next();
+        unary();
+        if ((vtop->type.t & VT_BTYPE) == VT_PTR)
+            tcc_error("pointer not accepted for unary plus");
+        /* In order to force cast, we add zero, except for floating point
+	   where we really need an noop (otherwise -0.0 will be transformed
+	   into +0.0).  */
+	if (!is_float(vtop->type.t)) {
+	    vpushi(0);
+	    gen_op('+');
+	}
+        break;
+    case TOK_SIZEOF:
+    case TOK_ALIGNOF1:
+    case TOK_ALIGNOF2:
+        t = tok;
+        next();
+        in_sizeof++;
+        expr_type(&type, unary); /* Perform a in_sizeof = 0; */
+        s = vtop[1].sym; /* hack: accessing previous vtop */
+        size = type_size(&type, &align);
+        if (s && s->a.aligned)
+            align = 1 << (s->a.aligned - 1);
+        if (t == TOK_SIZEOF) {
+            if (!(type.t & VT_VLA)) {
+                if (size < 0)
+                    tcc_error("sizeof applied to an incomplete type");
+                vpushs(size);
+            } else {
+                vla_runtime_type_size(&type, &align);
+            }
+        } else {
+            vpushs(align);
+        }
+        vtop->type.t |= VT_UNSIGNED;
+        break;
+
+    case TOK_builtin_expect:
+	/* __builtin_expect is a no-op for now */
+	parse_builtin_params(0, "ee");
+	vpop();
+        break;
+    case TOK_builtin_types_compatible_p:
+	parse_builtin_params(0, "tt");
+	vtop[-1].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
+	vtop[0].type.t &= ~(VT_CONSTANT | VT_VOLATILE);
+	n = is_compatible_types(&vtop[-1].type, &vtop[0].type);
+	vtop -= 2;
+	vpushi(n);
+        break;
+    case TOK_builtin_choose_expr:
+	{
+	    int64_t c;
+	    next();
+	    skip('(');
+	    c = expr_const64();
+	    skip(',');
+	    if (!c) {
+		nocode_wanted++;
+	    }
+	    expr_eq();
+	    if (!c) {
+		vpop();
+		nocode_wanted--;
+	    }
+	    skip(',');
+	    if (c) {
+		nocode_wanted++;
+	    }
+	    expr_eq();
+	    if (c) {
+		vpop();
+		nocode_wanted--;
+	    }
+	    skip(')');
+	}
+        break;
+    case TOK_builtin_constant_p:
+	parse_builtin_params(1, "e");
+	n = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+	vtop--;
+	vpushi(n);
+        break;
+    case TOK_builtin_frame_address:
+    case TOK_builtin_return_address:
+        {
+            int tok1 = tok;
+            int level;
+            next();
+            skip('(');
+            if (tok != TOK_CINT) {
+                tcc_error("%s only takes positive integers",
+                          tok1 == TOK_builtin_return_address ?
+                          "__builtin_return_address" :
+                          "__builtin_frame_address");
+            }
+            level = (uint32_t)tokc.i;
+            next();
+            skip(')');
+            type.t = VT_VOID;
+            mk_pointer(&type);
+            vset(&type, VT_LOCAL, 0);       /* local frame */
+            while (level--) {
+                mk_pointer(&vtop->type);
+                indir();                    /* -> parent frame */
+            }
+            if (tok1 == TOK_builtin_return_address) {
+                // assume return address is just above frame pointer on stack
+                vpushi(PTR_SIZE);
+                gen_op('+');
+                mk_pointer(&vtop->type);
+                indir();
+            }
+        }
+        break;
+#ifdef TCC_TARGET_X86_64
+#ifdef TCC_TARGET_PE
+    case TOK_builtin_va_start:
+	parse_builtin_params(0, "ee");
+        r = vtop->r & VT_VALMASK;
+        if (r == VT_LLOCAL)
+            r = VT_LOCAL;
+        if (r != VT_LOCAL)
+            tcc_error("__builtin_va_start expects a local variable");
+        vtop->r = r;
+	vtop->type = char_pointer_type;
+	vtop->c.i += 8;
+	vstore();
+        break;
+#else
+    case TOK_builtin_va_arg_types:
+	parse_builtin_params(0, "t");
+	vpushi(classify_x86_64_va_arg(&vtop->type));
+	vswap();
+	vpop();
+        break;
+#endif
+#endif
+
+#ifdef TCC_TARGET_ARM64
+    case TOK___va_start: {
+	parse_builtin_params(0, "ee");
+        //xx check types
+        gen_va_start();
+        vpushi(0);
+        vtop->type.t = VT_VOID;
+        break;
+    }
+    case TOK___va_arg: {
+	parse_builtin_params(0, "et");
+	type = vtop->type;
+	vpop();
+        //xx check types
+        gen_va_arg(&type);
+        vtop->type = type;
+        break;
+    }
+    case TOK___arm64_clear_cache: {
+	parse_builtin_params(0, "ee");
+        gen_clear_cache();
+        vpushi(0);
+        vtop->type.t = VT_VOID;
+        break;
+    }
+#endif
+    /* pre operations */
+    case TOK_INC:
+    case TOK_DEC:
+        t = tok;
+        next();
+        unary();
+        inc(0, t);
+        break;
+    case '-':
+        next();
+        unary();
+        t = vtop->type.t & VT_BTYPE;
+	if (is_float(t)) {
+            /* In IEEE negate(x) isn't subtract(0,x), but rather
+	       subtract(-0, x).  */
+	    vpush(&vtop->type);
+	    if (t == VT_FLOAT)
+	        vtop->c.f = -1.0 * 0.0;
+	    else if (t == VT_DOUBLE)
+	        vtop->c.d = -1.0 * 0.0;
+	    else
+	        vtop->c.ld = -1.0 * 0.0;
+	} else
+	    vpushi(0);
+	vswap();
+	gen_op('-');
+        break;
+    case TOK_LAND:
+        if (!gnu_ext)
+            goto tok_identifier;
+        next();
+        /* allow to take the address of a label */
+        if (tok < TOK_UIDENT)
+            expect("label identifier");
+        s = label_find(tok);
+        if (!s) {
+            s = label_push(&global_label_stack, tok, LABEL_FORWARD);
+        } else {
+            if (s->r == LABEL_DECLARED)
+                s->r = LABEL_FORWARD;
+        }
+        if (!s->type.t) {
+            s->type.t = VT_VOID;
+            mk_pointer(&s->type);
+            s->type.t |= VT_STATIC;
+        }
+        vpushsym(&s->type, s);
+        next();
+        break;
+
+    case TOK_GENERIC:
+    {
+	CType controlling_type;
+	int has_default = 0;
+	int has_match = 0;
+	int learn = 0;
+	TokenString *str = NULL;
+
+	next();
+	skip('(');
+	expr_type(&controlling_type, expr_eq);
+	controlling_type.t &= ~(VT_CONSTANT | VT_VOLATILE | VT_ARRAY);
+	for (;;) {
+	    learn = 0;
+	    skip(',');
+	    if (tok == TOK_DEFAULT) {
+		if (has_default)
+		    tcc_error("too many 'default'");
+		has_default = 1;
+		if (!has_match)
+		    learn = 1;
+		next();
+	    } else {
+	        AttributeDef ad_tmp;
+		int itmp;
+	        CType cur_type;
+		parse_btype(&cur_type, &ad_tmp);
+		type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
+		if (compare_types(&controlling_type, &cur_type, 0)) {
+		    if (has_match) {
+		      tcc_error("type match twice");
+		    }
+		    has_match = 1;
+		    learn = 1;
+		}
+	    }
+	    skip(':');
+	    if (learn) {
+		if (str)
+		    tok_str_free(str);
+		skip_or_save_block(&str);
+	    } else {
+		skip_or_save_block(NULL);
+	    }
+	    if (tok == ')')
+		break;
+	}
+	if (!str) {
+	    char buf[60];
+	    type_to_str(buf, sizeof buf, &controlling_type, NULL);
+	    tcc_error("type '%s' does not match any association", buf);
+	}
+	begin_macro(str, 1);
+	next();
+	expr_eq();
+	if (tok != TOK_EOF)
+	    expect(",");
+	end_macro();
+        next();
+	break;
+    }
+    // special qnan , snan and infinity values
+    case TOK___NAN__:
+        vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
+        next();
+        break;
+    case TOK___SNAN__:
+        vpush64(VT_DOUBLE, 0x7ff0000000000001ULL);
+        next();
+        break;
+    case TOK___INF__:
+        vpush64(VT_DOUBLE, 0x7ff0000000000000ULL);
+        next();
+        break;
+
+    default:
+    tok_identifier:
+        t = tok;
+        next();
+        if (t < TOK_UIDENT)
+            expect("identifier");
+        s = sym_find(t);
+        if (!s || IS_ASM_SYM(s)) {
+            const char *name = get_tok_str(t, NULL);
+            if (tok != '(')
+                tcc_error("'%s' undeclared", name);
+            /* for simple function calls, we tolerate undeclared
+               external reference to int() function */
+            if (tcc_state->warn_implicit_function_declaration
+#ifdef TCC_TARGET_PE
+                /* people must be warned about using undeclared WINAPI functions
+                   (which usually start with uppercase letter) */
+                || (name[0] >= 'A' && name[0] <= 'Z')
+#endif
+            )
+                tcc_warning("implicit declaration of function '%s'", name);
+            s = external_global_sym(t, &func_old_type, 0); 
+        }
+
+        r = s->r;
+        /* A symbol that has a register is a local register variable,
+           which starts out as VT_LOCAL value.  */
+        if ((r & VT_VALMASK) < VT_CONST)
+            r = (r & ~VT_VALMASK) | VT_LOCAL;
+
+        vset(&s->type, r, s->c);
+        /* Point to s as backpointer (even without r&VT_SYM).
+	   Will be used by at least the x86 inline asm parser for
+	   regvars.  */
+	vtop->sym = s;
+
+        if (r & VT_SYM) {
+            vtop->c.i = 0;
+        } else if (r == VT_CONST && IS_ENUM_VAL(s->type.t)) {
+            vtop->c.i = s->enum_val;
+        }
+        break;
+    }
+    
+    /* post operations */
+    while (1) {
+        if (tok == TOK_INC || tok == TOK_DEC) {
+            inc(1, tok);
+            next();
+        } else if (tok == '.' || tok == TOK_ARROW || tok == TOK_CDOUBLE) {
+            int qualifiers;
+            /* field */ 
+            if (tok == TOK_ARROW) 
+                indir();
+            qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
+            test_lvalue();
+            gaddrof();
+            /* expect pointer on structure */
+            if ((vtop->type.t & VT_BTYPE) != VT_STRUCT)
+                expect("struct or union");
+            if (tok == TOK_CDOUBLE)
+                expect("field name");
+            next();
+            if (tok == TOK_CINT || tok == TOK_CUINT)
+                expect("field name");
+	    s = find_field(&vtop->type, tok);
+            if (!s)
+                tcc_error("field not found: %s",  get_tok_str(tok & ~SYM_FIELD, &tokc));
+            /* add field offset to pointer */
+            vtop->type = char_pointer_type; /* change type to 'char *' */
+            vpushi(s->c);
+            gen_op('+');
+            /* change type to field type, and set to lvalue */
+            vtop->type = s->type;
+            vtop->type.t |= qualifiers;
+            /* an array is never an lvalue */
+            if (!(vtop->type.t & VT_ARRAY)) {
+                vtop->r |= lvalue_type(vtop->type.t);
+#ifdef CONFIG_TCC_BCHECK
+                /* if bound checking, the referenced pointer must be checked */
+                if (tcc_state->do_bounds_check && (vtop->r & VT_VALMASK) != VT_LOCAL)
+                    vtop->r |= VT_MUSTBOUND;
+#endif
+            }
+            next();
+        } else if (tok == '[') {
+            next();
+            gexpr();
+            gen_op('+');
+            indir();
+            skip(']');
+        } else if (tok == '(') {
+            SValue ret;
+            Sym *sa;
+            int nb_args, ret_nregs, ret_align, regsize, variadic;
+
+            /* function call  */
+            if ((vtop->type.t & VT_BTYPE) != VT_FUNC) {
+                /* pointer test (no array accepted) */
+                if ((vtop->type.t & (VT_BTYPE | VT_ARRAY)) == VT_PTR) {
+                    vtop->type = *pointed_type(&vtop->type);
+                    if ((vtop->type.t & VT_BTYPE) != VT_FUNC)
+                        goto error_func;
+                } else {
+                error_func:
+                    expect("function pointer");
+                }
+            } else {
+                vtop->r &= ~VT_LVAL; /* no lvalue */
+            }
+            /* get return type */
+            s = vtop->type.ref;
+            next();
+            sa = s->next; /* first parameter */
+            nb_args = regsize = 0;
+            ret.r2 = VT_CONST;
+            /* compute first implicit argument if a structure is returned */
+            if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
+                variadic = (s->f.func_type == FUNC_ELLIPSIS);
+                ret_nregs = gfunc_sret(&s->type, variadic, &ret.type,
+                                       &ret_align, &regsize);
+                if (!ret_nregs) {
+                    /* get some space for the returned structure */
+                    size = type_size(&s->type, &align);
+#ifdef TCC_TARGET_ARM64
+                /* On arm64, a small struct is return in registers.
+                   It is much easier to write it to memory if we know
+                   that we are allowed to write some extra bytes, so
+                   round the allocated space up to a power of 2: */
+                if (size < 16)
+                    while (size & (size - 1))
+                        size = (size | (size - 1)) + 1;
+#endif
+                    loc = (loc - size) & -align;
+                    ret.type = s->type;
+                    ret.r = VT_LOCAL | VT_LVAL;
+                    /* pass it as 'int' to avoid structure arg passing
+                       problems */
+                    vseti(VT_LOCAL, loc);
+                    ret.c = vtop->c;
+                    nb_args++;
+                }
+            } else {
+                ret_nregs = 1;
+                ret.type = s->type;
+            }
+
+            if (ret_nregs) {
+                /* return in register */
+                if (is_float(ret.type.t)) {
+                    ret.r = reg_fret(ret.type.t);
+#ifdef TCC_TARGET_X86_64
+                    if ((ret.type.t & VT_BTYPE) == VT_QFLOAT)
+                      ret.r2 = REG_QRET;
+#endif
+                } else {
+#ifndef TCC_TARGET_ARM64
+#ifdef TCC_TARGET_X86_64
+                    if ((ret.type.t & VT_BTYPE) == VT_QLONG)
+#else
+                    if ((ret.type.t & VT_BTYPE) == VT_LLONG)
+#endif
+                        ret.r2 = REG_LRET;
+#endif
+                    ret.r = REG_IRET;
+                }
+                ret.c.i = 0;
+            }
+            if (tok != ')') {
+                for(;;) {
+                    expr_eq();
+                    gfunc_param_typed(s, sa);
+                    nb_args++;
+                    if (sa)
+                        sa = sa->next;
+                    if (tok == ')')
+                        break;
+                    skip(',');
+                }
+            }
+            if (sa)
+                tcc_error("too few arguments to function");
+            skip(')');
+            gfunc_call(nb_args);
+
+            /* return value */
+            for (r = ret.r + ret_nregs + !ret_nregs; r-- > ret.r;) {
+                vsetc(&ret.type, r, &ret.c);
+                vtop->r2 = ret.r2; /* Loop only happens when r2 is VT_CONST */
+            }
+
+            /* handle packed struct return */
+            if (((s->type.t & VT_BTYPE) == VT_STRUCT) && ret_nregs) {
+                int addr, offset;
+
+                size = type_size(&s->type, &align);
+		/* We're writing whole regs often, make sure there's enough
+		   space.  Assume register size is power of 2.  */
+		if (regsize > align)
+		  align = regsize;
+                loc = (loc - size) & -align;
+                addr = loc;
+                offset = 0;
+                for (;;) {
+                    vset(&ret.type, VT_LOCAL | VT_LVAL, addr + offset);
+                    vswap();
+                    vstore();
+                    vtop--;
+                    if (--ret_nregs == 0)
+                        break;
+                    offset += regsize;
+                }
+                vset(&s->type, VT_LOCAL | VT_LVAL, addr);
+            }
+        } else {
+            break;
+        }
+    }
+}
+
+ST_FUNC void expr_prod(void)
+{
+    int t;
+
+    unary();
+    while (tok == '*' || tok == '/' || tok == '%') {
+        t = tok;
+        next();
+        unary();
+        gen_op(t);
+    }
+}
+
+ST_FUNC void expr_sum(void)
+{
+    int t;
+
+    expr_prod();
+    while (tok == '+' || tok == '-') {
+        t = tok;
+        next();
+        expr_prod();
+        gen_op(t);
+    }
+}
+
+static void expr_shift(void)
+{
+    int t;
+
+    expr_sum();
+    while (tok == TOK_SHL || tok == TOK_SAR) {
+        t = tok;
+        next();
+        expr_sum();
+        gen_op(t);
+    }
+}
+
+static void expr_cmp(void)
+{
+    int t;
+
+    expr_shift();
+    while ((tok >= TOK_ULE && tok <= TOK_GT) ||
+           tok == TOK_ULT || tok == TOK_UGE) {
+        t = tok;
+        next();
+        expr_shift();
+        gen_op(t);
+    }
+}
+
+static void expr_cmpeq(void)
+{
+    int t;
+
+    expr_cmp();
+    while (tok == TOK_EQ || tok == TOK_NE) {
+        t = tok;
+        next();
+        expr_cmp();
+        gen_op(t);
+    }
+}
+
+static void expr_and(void)
+{
+    expr_cmpeq();
+    while (tok == '&') {
+        next();
+        expr_cmpeq();
+        gen_op('&');
+    }
+}
+
+static void expr_xor(void)
+{
+    expr_and();
+    while (tok == '^') {
+        next();
+        expr_and();
+        gen_op('^');
+    }
+}
+
+static void expr_or(void)
+{
+    expr_xor();
+    while (tok == '|') {
+        next();
+        expr_xor();
+        gen_op('|');
+    }
+}
+
+static void expr_land(void)
+{
+    expr_or();
+    if (tok == TOK_LAND) {
+	int t = 0;
+	for(;;) {
+	    if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+                gen_cast_s(VT_BOOL);
+		if (vtop->c.i) {
+		    vpop();
+		} else {
+		    nocode_wanted++;
+		    while (tok == TOK_LAND) {
+			next();
+			expr_or();
+			vpop();
+		    }
+		    nocode_wanted--;
+		    if (t)
+		      gsym(t);
+		    gen_cast_s(VT_INT);
+		    break;
+		}
+	    } else {
+		if (!t)
+		  save_regs(1);
+		t = gvtst(1, t);
+	    }
+	    if (tok != TOK_LAND) {
+		if (t)
+		  vseti(VT_JMPI, t);
+		else
+		  vpushi(1);
+		break;
+	    }
+	    next();
+	    expr_or();
+	}
+    }
+}
+
+static void expr_lor(void)
+{
+    expr_land();
+    if (tok == TOK_LOR) {
+	int t = 0;
+	for(;;) {
+	    if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+                gen_cast_s(VT_BOOL);
+		if (!vtop->c.i) {
+		    vpop();
+		} else {
+		    nocode_wanted++;
+		    while (tok == TOK_LOR) {
+			next();
+			expr_land();
+			vpop();
+		    }
+		    nocode_wanted--;
+		    if (t)
+		      gsym(t);
+		    gen_cast_s(VT_INT);
+		    break;
+		}
+	    } else {
+		if (!t)
+		  save_regs(1);
+		t = gvtst(0, t);
+	    }
+	    if (tok != TOK_LOR) {
+		if (t)
+		  vseti(VT_JMP, t);
+		else
+		  vpushi(0);
+		break;
+	    }
+	    next();
+	    expr_land();
+	}
+    }
+}
+
+/* Assuming vtop is a value used in a conditional context
+   (i.e. compared with zero) return 0 if it's false, 1 if
+   true and -1 if it can't be statically determined.  */
+static int condition_3way(void)
+{
+    int c = -1;
+    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
+	(!(vtop->r & VT_SYM) || !vtop->sym->a.weak)) {
+	vdup();
+        gen_cast_s(VT_BOOL);
+	c = vtop->c.i;
+	vpop();
+    }
+    return c;
+}
+
+static void expr_cond(void)
+{
+    int tt, u, r1, r2, rc, t1, t2, bt1, bt2, islv, c, g;
+    SValue sv;
+    CType type, type1, type2;
+
+    expr_lor();
+    if (tok == '?') {
+        next();
+	c = condition_3way();
+        g = (tok == ':' && gnu_ext);
+        if (c < 0) {
+            /* needed to avoid having different registers saved in
+               each branch */
+            if (is_float(vtop->type.t)) {
+                rc = RC_FLOAT;
+#ifdef TCC_TARGET_X86_64
+                if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
+                    rc = RC_ST0;
+                }
+#endif
+            } else
+                rc = RC_INT;
+            gv(rc);
+            save_regs(1);
+            if (g)
+                gv_dup();
+            tt = gvtst(1, 0);
+
+        } else {
+            if (!g)
+                vpop();
+            tt = 0;
+        }
+
+        if (1) {
+            if (c == 0)
+                nocode_wanted++;
+            if (!g)
+                gexpr();
+
+            type1 = vtop->type;
+            sv = *vtop; /* save value to handle it later */
+            vtop--; /* no vpop so that FP stack is not flushed */
+            skip(':');
+
+            u = 0;
+            if (c < 0)
+                u = gjmp(0);
+            gsym(tt);
+
+            if (c == 0)
+                nocode_wanted--;
+            if (c == 1)
+                nocode_wanted++;
+            expr_cond();
+            if (c == 1)
+                nocode_wanted--;
+
+            type2 = vtop->type;
+            t1 = type1.t;
+            bt1 = t1 & VT_BTYPE;
+            t2 = type2.t;
+            bt2 = t2 & VT_BTYPE;
+            type.ref = NULL;
+
+            /* cast operands to correct type according to ISOC rules */
+            if (is_float(bt1) || is_float(bt2)) {
+                if (bt1 == VT_LDOUBLE || bt2 == VT_LDOUBLE) {
+                    type.t = VT_LDOUBLE;
+
+                } else if (bt1 == VT_DOUBLE || bt2 == VT_DOUBLE) {
+                    type.t = VT_DOUBLE;
+                } else {
+                    type.t = VT_FLOAT;
+                }
+            } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
+                /* cast to biggest op */
+                type.t = VT_LLONG | VT_LONG;
+                if (bt1 == VT_LLONG)
+                    type.t &= t1;
+                if (bt2 == VT_LLONG)
+                    type.t &= t2;
+                /* convert to unsigned if it does not fit in a long long */
+                if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
+                    (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
+                    type.t |= VT_UNSIGNED;
+            } else if (bt1 == VT_PTR || bt2 == VT_PTR) {
+		/* If one is a null ptr constant the result type
+		   is the other.  */
+		if (is_null_pointer (vtop))
+		  type = type1;
+		else if (is_null_pointer (&sv))
+		  type = type2;
+                /* XXX: test pointer compatibility, C99 has more elaborate
+		   rules here.  */
+		else
+		  type = type1;
+            } else if (bt1 == VT_FUNC || bt2 == VT_FUNC) {
+                /* XXX: test function pointer compatibility */
+                type = bt1 == VT_FUNC ? type1 : type2;
+            } else if (bt1 == VT_STRUCT || bt2 == VT_STRUCT) {
+                /* XXX: test structure compatibility */
+                type = bt1 == VT_STRUCT ? type1 : type2;
+            } else if (bt1 == VT_VOID || bt2 == VT_VOID) {
+                /* NOTE: as an extension, we accept void on only one side */
+                type.t = VT_VOID;
+            } else {
+                /* integer operations */
+                type.t = VT_INT | (VT_LONG & (t1 | t2));
+                /* convert to unsigned if it does not fit in an integer */
+                if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
+                    (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
+                    type.t |= VT_UNSIGNED;
+            }
+            /* keep structs lvalue by transforming `(expr ? a : b)` to `*(expr ? &a : &b)` so
+               that `(expr ? a : b).mem` does not error  with "lvalue expected" */
+            islv = (vtop->r & VT_LVAL) && (sv.r & VT_LVAL) && VT_STRUCT == (type.t & VT_BTYPE);
+            islv &= c < 0;
+
+            /* now we convert second operand */
+            if (c != 1) {
+                gen_cast(&type);
+                if (islv) {
+                    mk_pointer(&vtop->type);
+                    gaddrof();
+                } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
+                    gaddrof();
+            }
+
+            rc = RC_INT;
+            if (is_float(type.t)) {
+                rc = RC_FLOAT;
+#ifdef TCC_TARGET_X86_64
+                if ((type.t & VT_BTYPE) == VT_LDOUBLE) {
+                    rc = RC_ST0;
+                }
+#endif
+            } else if ((type.t & VT_BTYPE) == VT_LLONG) {
+                /* for long longs, we use fixed registers to avoid having
+                   to handle a complicated move */
+                rc = RC_IRET;
+            }
+
+            tt = r2 = 0;
+            if (c < 0) {
+                r2 = gv(rc);
+                tt = gjmp(0);
+            }
+            gsym(u);
+
+            /* this is horrible, but we must also convert first
+               operand */
+            if (c != 0) {
+                *vtop = sv;
+                gen_cast(&type);
+                if (islv) {
+                    mk_pointer(&vtop->type);
+                    gaddrof();
+                } else if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
+                    gaddrof();
+            }
+
+            if (c < 0) {
+                r1 = gv(rc);
+                move_reg(r2, r1, type.t);
+                vtop->r = r2;
+                gsym(tt);
+                if (islv)
+                    indir();
+            }
+        }
+    }
+}
+
+static void expr_eq(void)
+{
+    int t;
+    
+    expr_cond();
+    if (tok == '=' ||
+        (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
+        tok == TOK_A_XOR || tok == TOK_A_OR ||
+        tok == TOK_A_SHL || tok == TOK_A_SAR) {
+        test_lvalue();
+        t = tok;
+        next();
+        if (t == '=') {
+            expr_eq();
+        } else {
+            vdup();
+            expr_eq();
+            gen_op(t & 0x7f);
+        }
+        vstore();
+    }
+}
+
+ST_FUNC void gexpr(void)
+{
+    while (1) {
+        expr_eq();
+        if (tok != ',')
+            break;
+        vpop();
+        next();
+    }
+}
+
+/* parse a constant expression and return value in vtop.  */
+static void expr_const1(void)
+{
+    const_wanted++;
+    nocode_wanted++;
+    expr_cond();
+    nocode_wanted--;
+    const_wanted--;
+}
+
+/* parse an integer constant and return its value. */
+static inline int64_t expr_const64(void)
+{
+    int64_t c;
+    expr_const1();
+    if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
+        expect("constant expression");
+    c = vtop->c.i;
+    vpop();
+    return c;
+}
+
+/* parse an integer constant and return its value.
+   Complain if it doesn't fit 32bit (signed or unsigned).  */
+ST_FUNC int expr_const(void)
+{
+    int c;
+    int64_t wc = expr_const64();
+    c = wc;
+    if (c != wc && (unsigned)c != wc)
+        tcc_error("constant exceeds 32 bit");
+    return c;
+}
+
+/* return the label token if current token is a label, otherwise
+   return zero */
+static int is_label(void)
+{
+    int last_tok;
+
+    /* fast test first */
+    if (tok < TOK_UIDENT)
+        return 0;
+    /* no need to save tokc because tok is an identifier */
+    last_tok = tok;
+    next();
+    if (tok == ':') {
+        return last_tok;
+    } else {
+        unget_tok(last_tok);
+        return 0;
+    }
+}
+
+#ifndef TCC_TARGET_ARM64
+static void gfunc_return(CType *func_type)
+{
+    if ((func_type->t & VT_BTYPE) == VT_STRUCT) {
+        CType type, ret_type;
+        int ret_align, ret_nregs, regsize;
+        ret_nregs = gfunc_sret(func_type, func_var, &ret_type,
+                               &ret_align, &regsize);
+        if (0 == ret_nregs) {
+            /* if returning structure, must copy it to implicit
+               first pointer arg location */
+            type = *func_type;
+            mk_pointer(&type);
+            vset(&type, VT_LOCAL | VT_LVAL, func_vc);
+            indir();
+            vswap();
+            /* copy structure value to pointer */
+            vstore();
+        } else {
+            /* returning structure packed into registers */
+            int r, size, addr, align;
+            size = type_size(func_type,&align);
+            if ((vtop->r != (VT_LOCAL | VT_LVAL) ||
+                 (vtop->c.i & (ret_align-1)))
+                && (align & (ret_align-1))) {
+                loc = (loc - size) & -ret_align;
+                addr = loc;
+                type = *func_type;
+                vset(&type, VT_LOCAL | VT_LVAL, addr);
+                vswap();
+                vstore();
+                vpop();
+                vset(&ret_type, VT_LOCAL | VT_LVAL, addr);
+            }
+            vtop->type = ret_type;
+            if (is_float(ret_type.t))
+                r = rc_fret(ret_type.t);
+            else
+                r = RC_IRET;
+
+            if (ret_nregs == 1)
+                gv(r);
+            else {
+                for (;;) {
+                    vdup();
+                    gv(r);
+                    vpop();
+                    if (--ret_nregs == 0)
+                      break;
+                    /* We assume that when a structure is returned in multiple
+                       registers, their classes are consecutive values of the
+                       suite s(n) = 2^n */
+                    r <<= 1;
+                    vtop->c.i += regsize;
+                }
+            }
+        }
+    } else if (is_float(func_type->t)) {
+        gv(rc_fret(func_type->t));
+    } else {
+        gv(RC_IRET);
+    }
+    vtop--; /* NOT vpop() because on x86 it would flush the fp stack */
+}
+#endif
+
+static int case_cmp(const void *pa, const void *pb)
+{
+    int64_t a = (*(struct case_t**) pa)->v1;
+    int64_t b = (*(struct case_t**) pb)->v1;
+    return a < b ? -1 : a > b;
+}
+
+static void gcase(struct case_t **base, int len, int *bsym)
+{
+    struct case_t *p;
+    int e;
+    int ll = (vtop->type.t & VT_BTYPE) == VT_LLONG;
+    gv(RC_INT);
+    while (len > 4) {
+        /* binary search */
+        p = base[len/2];
+        vdup();
+	if (ll)
+	    vpushll(p->v2);
+	else
+	    vpushi(p->v2);
+        gen_op(TOK_LE);
+        e = gtst(1, 0);
+        vdup();
+	if (ll)
+	    vpushll(p->v1);
+	else
+	    vpushi(p->v1);
+        gen_op(TOK_GE);
+        gtst_addr(0, p->sym); /* v1 <= x <= v2 */
+        /* x < v1 */
+        gcase(base, len/2, bsym);
+        if (cur_switch->def_sym)
+            gjmp_addr(cur_switch->def_sym);
+        else
+            *bsym = gjmp(*bsym);
+        /* x > v2 */
+        gsym(e);
+        e = len/2 + 1;
+        base += e; len -= e;
+    }
+    /* linear scan */
+    while (len--) {
+        p = *base++;
+        vdup();
+	if (ll)
+	    vpushll(p->v2);
+	else
+	    vpushi(p->v2);
+        if (p->v1 == p->v2) {
+            gen_op(TOK_EQ);
+            gtst_addr(0, p->sym);
+        } else {
+            gen_op(TOK_LE);
+            e = gtst(1, 0);
+            vdup();
+	    if (ll)
+	        vpushll(p->v1);
+	    else
+	        vpushi(p->v1);
+            gen_op(TOK_GE);
+            gtst_addr(0, p->sym);
+            gsym(e);
+        }
+    }
+}
+
+static void block(int *bsym, int *csym, int is_expr)
+{
+    int a, b, c, d, cond;
+    Sym *s;
+
+    /* generate line number info */
+    if (tcc_state->do_debug)
+        tcc_debug_line(tcc_state);
+
+    if (is_expr) {
+        /* default return value is (void) */
+        vpushi(0);
+        vtop->type.t = VT_VOID;
+    }
+
+    if (tok == TOK_IF) {
+        /* if test */
+	int saved_nocode_wanted = nocode_wanted;
+        next();
+        skip('(');
+        gexpr();
+        skip(')');
+	cond = condition_3way();
+        if (cond == 1)
+            a = 0, vpop();
+        else
+            a = gvtst(1, 0);
+        if (cond == 0)
+	    nocode_wanted |= 0x20000000;
+        block(bsym, csym, 0);
+	if (cond != 1)
+	    nocode_wanted = saved_nocode_wanted;
+        c = tok;
+        if (c == TOK_ELSE) {
+            next();
+            d = gjmp(0);
+            gsym(a);
+	    if (cond == 1)
+	        nocode_wanted |= 0x20000000;
+            block(bsym, csym, 0);
+            gsym(d); /* patch else jmp */
+	    if (cond != 0)
+		nocode_wanted = saved_nocode_wanted;
+        } else
+            gsym(a);
+    } else if (tok == TOK_WHILE) {
+	int saved_nocode_wanted;
+	nocode_wanted &= ~0x20000000;
+        next();
+        d = ind;
+        vla_sp_restore();
+        skip('(');
+        gexpr();
+        skip(')');
+        a = gvtst(1, 0);
+        b = 0;
+        ++local_scope;
+	saved_nocode_wanted = nocode_wanted;
+        block(&a, &b, 0);
+	nocode_wanted = saved_nocode_wanted;
+        --local_scope;
+        gjmp_addr(d);
+        gsym(a);
+        gsym_addr(b, d);
+    } else if (tok == '{') {
+        Sym *llabel;
+        int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope;
+
+        next();
+        /* record local declaration stack position */
+        s = local_stack;
+        llabel = local_label_stack;
+        ++local_scope;
+        
+        /* handle local labels declarations */
+        if (tok == TOK_LABEL) {
+            next();
+            for(;;) {
+                if (tok < TOK_UIDENT)
+                    expect("label identifier");
+                label_push(&local_label_stack, tok, LABEL_DECLARED);
+                next();
+                if (tok == ',') {
+                    next();
+                } else {
+                    skip(';');
+                    break;
+                }
+            }
+        }
+        while (tok != '}') {
+	    if ((a = is_label()))
+		unget_tok(a);
+	    else
+	        decl(VT_LOCAL);
+            if (tok != '}') {
+                if (is_expr)
+                    vpop();
+                block(bsym, csym, is_expr);
+            }
+        }
+        /* pop locally defined labels */
+        label_pop(&local_label_stack, llabel, is_expr);
+        /* pop locally defined symbols */
+        --local_scope;
+	/* In the is_expr case (a statement expression is finished here),
+	   vtop might refer to symbols on the local_stack.  Either via the
+	   type or via vtop->sym.  We can't pop those nor any that in turn
+	   might be referred to.  To make it easier we don't roll back
+	   any symbols in that case; some upper level call to block() will
+	   do that.  We do have to remove such symbols from the lookup
+	   tables, though.  sym_pop will do that.  */
+	sym_pop(&local_stack, s, is_expr);
+
+        /* Pop VLA frames and restore stack pointer if required */
+        if (vlas_in_scope > saved_vlas_in_scope) {
+            vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc;
+            vla_sp_restore();
+        }
+        vlas_in_scope = saved_vlas_in_scope;
+        
+        next();
+    } else if (tok == TOK_RETURN) {
+        next();
+        if (tok != ';') {
+            gexpr();
+            gen_assign_cast(&func_vt);
+            if ((func_vt.t & VT_BTYPE) == VT_VOID)
+                vtop--;
+            else
+                gfunc_return(&func_vt);
+        }
+        skip(';');
+        /* jump unless last stmt in top-level block */
+        if (tok != '}' || local_scope != 1)
+            rsym = gjmp(rsym);
+	nocode_wanted |= 0x20000000;
+    } else if (tok == TOK_BREAK) {
+        /* compute jump */
+        if (!bsym)
+            tcc_error("cannot break");
+        *bsym = gjmp(*bsym);
+        next();
+        skip(';');
+	nocode_wanted |= 0x20000000;
+    } else if (tok == TOK_CONTINUE) {
+        /* compute jump */
+        if (!csym)
+            tcc_error("cannot continue");
+        vla_sp_restore_root();
+        *csym = gjmp(*csym);
+        next();
+        skip(';');
+    } else if (tok == TOK_FOR) {
+        int e;
+	int saved_nocode_wanted;
+	nocode_wanted &= ~0x20000000;
+        next();
+        skip('(');
+        s = local_stack;
+        ++local_scope;
+        if (tok != ';') {
+            /* c99 for-loop init decl? */
+            if (!decl0(VT_LOCAL, 1, NULL)) {
+                /* no, regular for-loop init expr */
+                gexpr();
+                vpop();
+            }
+        }
+        skip(';');
+        d = ind;
+        c = ind;
+        vla_sp_restore();
+        a = 0;
+        b = 0;
+        if (tok != ';') {
+            gexpr();
+            a = gvtst(1, 0);
+        }
+        skip(';');
+        if (tok != ')') {
+            e = gjmp(0);
+            c = ind;
+            vla_sp_restore();
+            gexpr();
+            vpop();
+            gjmp_addr(d);
+            gsym(e);
+        }
+        skip(')');
+	saved_nocode_wanted = nocode_wanted;
+        block(&a, &b, 0);
+	nocode_wanted = saved_nocode_wanted;
+        gjmp_addr(c);
+        gsym(a);
+        gsym_addr(b, c);
+        --local_scope;
+        sym_pop(&local_stack, s, 0);
+
+    } else 
+    if (tok == TOK_DO) {
+	int saved_nocode_wanted;
+	nocode_wanted &= ~0x20000000;
+        next();
+        a = 0;
+        b = 0;
+        d = ind;
+        vla_sp_restore();
+	saved_nocode_wanted = nocode_wanted;
+        block(&a, &b, 0);
+        skip(TOK_WHILE);
+        skip('(');
+        gsym(b);
+	gexpr();
+	c = gvtst(0, 0);
+	gsym_addr(c, d);
+	nocode_wanted = saved_nocode_wanted;
+        skip(')');
+        gsym(a);
+        skip(';');
+    } else
+    if (tok == TOK_SWITCH) {
+        struct switch_t *saved, sw;
+	int saved_nocode_wanted = nocode_wanted;
+	SValue switchval;
+        next();
+        skip('(');
+        gexpr();
+        skip(')');
+	switchval = *vtop--;
+        a = 0;
+        b = gjmp(0); /* jump to first case */
+        sw.p = NULL; sw.n = 0; sw.def_sym = 0;
+        saved = cur_switch;
+        cur_switch = &sw;
+        block(&a, csym, 0);
+	nocode_wanted = saved_nocode_wanted;
+        a = gjmp(a); /* add implicit break */
+        /* case lookup */
+        gsym(b);
+        qsort(sw.p, sw.n, sizeof(void*), case_cmp);
+        for (b = 1; b < sw.n; b++)
+            if (sw.p[b - 1]->v2 >= sw.p[b]->v1)
+                tcc_error("duplicate case value");
+        /* Our switch table sorting is signed, so the compared
+           value needs to be as well when it's 64bit.  */
+        if ((switchval.type.t & VT_BTYPE) == VT_LLONG)
+            switchval.type.t &= ~VT_UNSIGNED;
+        vpushv(&switchval);
+        gcase(sw.p, sw.n, &a);
+        vpop();
+        if (sw.def_sym)
+          gjmp_addr(sw.def_sym);
+        dynarray_reset(&sw.p, &sw.n);
+        cur_switch = saved;
+        /* break label */
+        gsym(a);
+    } else
+    if (tok == TOK_CASE) {
+        struct case_t *cr = tcc_malloc(sizeof(struct case_t));
+        if (!cur_switch)
+            expect("switch");
+	nocode_wanted &= ~0x20000000;
+        next();
+        cr->v1 = cr->v2 = expr_const64();
+        if (gnu_ext && tok == TOK_DOTS) {
+            next();
+            cr->v2 = expr_const64();
+            if (cr->v2 < cr->v1)
+                tcc_warning("empty case range");
+        }
+        cr->sym = ind;
+        dynarray_add(&cur_switch->p, &cur_switch->n, cr);
+        skip(':');
+        is_expr = 0;
+        goto block_after_label;
+    } else 
+    if (tok == TOK_DEFAULT) {
+        next();
+        skip(':');
+        if (!cur_switch)
+            expect("switch");
+        if (cur_switch->def_sym)
+            tcc_error("too many 'default'");
+        cur_switch->def_sym = ind;
+        is_expr = 0;
+        goto block_after_label;
+    } else
+    if (tok == TOK_GOTO) {
+        next();
+        if (tok == '*' && gnu_ext) {
+            /* computed goto */
+            next();
+            gexpr();
+            if ((vtop->type.t & VT_BTYPE) != VT_PTR)
+                expect("pointer");
+            ggoto();
+        } else if (tok >= TOK_UIDENT) {
+            s = label_find(tok);
+            /* put forward definition if needed */
+            if (!s) {
+                s = label_push(&global_label_stack, tok, LABEL_FORWARD);
+            } else {
+                if (s->r == LABEL_DECLARED)
+                    s->r = LABEL_FORWARD;
+            }
+            vla_sp_restore_root();
+	    if (s->r & LABEL_FORWARD)
+                s->jnext = gjmp(s->jnext);
+            else
+                gjmp_addr(s->jnext);
+            next();
+        } else {
+            expect("label identifier");
+        }
+        skip(';');
+    } else if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
+        asm_instr();
+    } else {
+        b = is_label();
+        if (b) {
+            /* label case */
+	    next();
+            s = label_find(b);
+            if (s) {
+                if (s->r == LABEL_DEFINED)
+                    tcc_error("duplicate label '%s'", get_tok_str(s->v, NULL));
+                gsym(s->jnext);
+                s->r = LABEL_DEFINED;
+            } else {
+                s = label_push(&global_label_stack, b, LABEL_DEFINED);
+            }
+            s->jnext = ind;
+            vla_sp_restore();
+            /* we accept this, but it is a mistake */
+        block_after_label:
+	    nocode_wanted &= ~0x20000000;
+            if (tok == '}') {
+                tcc_warning("deprecated use of label at end of compound statement");
+            } else {
+                if (is_expr)
+                    vpop();
+                block(bsym, csym, is_expr);
+            }
+        } else {
+            /* expression case */
+            if (tok != ';') {
+                if (is_expr) {
+                    vpop();
+                    gexpr();
+                } else {
+                    gexpr();
+                    vpop();
+                }
+            }
+            skip(';');
+        }
+    }
+}
+
+/* This skips over a stream of tokens containing balanced {} and ()
+   pairs, stopping at outer ',' ';' and '}' (or matching '}' if we started
+   with a '{').  If STR then allocates and stores the skipped tokens
+   in *STR.  This doesn't check if () and {} are nested correctly,
+   i.e. "({)}" is accepted.  */
+static void skip_or_save_block(TokenString **str)
+{
+    int braces = tok == '{';
+    int level = 0;
+    if (str)
+      *str = tok_str_alloc();
+
+    while ((level > 0 || (tok != '}' && tok != ',' && tok != ';' && tok != ')'))) {
+	int t;
+	if (tok == TOK_EOF) {
+	     if (str || level > 0)
+	       tcc_error("unexpected end of file");
+	     else
+	       break;
+	}
+	if (str)
+	  tok_str_add_tok(*str);
+	t = tok;
+	next();
+	if (t == '{' || t == '(') {
+	    level++;
+	} else if (t == '}' || t == ')') {
+	    level--;
+	    if (level == 0 && braces && t == '}')
+	      break;
+	}
+    }
+    if (str) {
+	tok_str_add(*str, -1);
+	tok_str_add(*str, 0);
+    }
+}
+
+#define EXPR_CONST 1
+#define EXPR_ANY   2
+
+static void parse_init_elem(int expr_type)
+{
+    int saved_global_expr;
+    switch(expr_type) {
+    case EXPR_CONST:
+        /* compound literals must be allocated globally in this case */
+        saved_global_expr = global_expr;
+        global_expr = 1;
+        expr_const1();
+        global_expr = saved_global_expr;
+        /* NOTE: symbols are accepted, as well as lvalue for anon symbols
+	   (compound literals).  */
+        if (((vtop->r & (VT_VALMASK | VT_LVAL)) != VT_CONST
+	     && ((vtop->r & (VT_SYM|VT_LVAL)) != (VT_SYM|VT_LVAL)
+		 || vtop->sym->v < SYM_FIRST_ANOM))
+#ifdef TCC_TARGET_PE
+                 || ((vtop->r & VT_SYM) && vtop->sym->a.dllimport)
+#endif
+            )
+            tcc_error("initializer element is not constant");
+        break;
+    case EXPR_ANY:
+        expr_eq();
+        break;
+    }
+}
+
+/* put zeros for variable based init */
+static void init_putz(Section *sec, unsigned long c, int size)
+{
+    if (sec) {
+        /* nothing to do because globals are already set to zero */
+    } else {
+        vpush_global_sym(&func_old_type, TOK_memset);
+        vseti(VT_LOCAL, c);
+#ifdef TCC_TARGET_ARM
+        vpushs(size);
+        vpushi(0);
+#else
+        vpushi(0);
+        vpushs(size);
+#endif
+        gfunc_call(3);
+    }
+}
+
+/* t is the array or struct type. c is the array or struct
+   address. cur_field is the pointer to the current
+   field, for arrays the 'c' member contains the current start
+   index.  'size_only' is true if only size info is needed (only used
+   in arrays).  al contains the already initialized length of the
+   current container (starting at c).  This returns the new length of that.  */
+static int decl_designator(CType *type, Section *sec, unsigned long c,
+                           Sym **cur_field, int size_only, int al)
+{
+    Sym *s, *f;
+    int index, index_last, align, l, nb_elems, elem_size;
+    unsigned long corig = c;
+
+    elem_size = 0;
+    nb_elems = 1;
+    if (gnu_ext && (l = is_label()) != 0)
+        goto struct_field;
+    /* NOTE: we only support ranges for last designator */
+    while (nb_elems == 1 && (tok == '[' || tok == '.')) {
+        if (tok == '[') {
+            if (!(type->t & VT_ARRAY))
+                expect("array type");
+            next();
+            index = index_last = expr_const();
+            if (tok == TOK_DOTS && gnu_ext) {
+                next();
+                index_last = expr_const();
+            }
+            skip(']');
+            s = type->ref;
+	    if (index < 0 || (s->c >= 0 && index_last >= s->c) ||
+		index_last < index)
+	        tcc_error("invalid index");
+            if (cur_field)
+		(*cur_field)->c = index_last;
+            type = pointed_type(type);
+            elem_size = type_size(type, &align);
+            c += index * elem_size;
+            nb_elems = index_last - index + 1;
+        } else {
+            next();
+            l = tok;
+        struct_field:
+            next();
+            if ((type->t & VT_BTYPE) != VT_STRUCT)
+                expect("struct/union type");
+	    f = find_field(type, l);
+            if (!f)
+                expect("field");
+            if (cur_field)
+                *cur_field = f;
+	    type = &f->type;
+            c += f->c;
+        }
+        cur_field = NULL;
+    }
+    if (!cur_field) {
+        if (tok == '=') {
+            next();
+        } else if (!gnu_ext) {
+	    expect("=");
+        }
+    } else {
+        if (type->t & VT_ARRAY) {
+	    index = (*cur_field)->c;
+	    if (type->ref->c >= 0 && index >= type->ref->c)
+	        tcc_error("index too large");
+            type = pointed_type(type);
+            c += index * type_size(type, &align);
+        } else {
+            f = *cur_field;
+	    while (f && (f->v & SYM_FIRST_ANOM) && (f->type.t & VT_BITFIELD))
+	        *cur_field = f = f->next;
+            if (!f)
+                tcc_error("too many field init");
+	    type = &f->type;
+            c += f->c;
+        }
+    }
+    /* must put zero in holes (note that doing it that way
+       ensures that it even works with designators) */
+    if (!size_only && c - corig > al)
+	init_putz(sec, corig + al, c - corig - al);
+    decl_initializer(type, sec, c, 0, size_only);
+
+    /* XXX: make it more general */
+    if (!size_only && nb_elems > 1) {
+        unsigned long c_end;
+        uint8_t *src, *dst;
+        int i;
+
+        if (!sec) {
+	    vset(type, VT_LOCAL|VT_LVAL, c);
+	    for (i = 1; i < nb_elems; i++) {
+		vset(type, VT_LOCAL|VT_LVAL, c + elem_size * i);
+		vswap();
+		vstore();
+	    }
+	    vpop();
+        } else if (!NODATA_WANTED) {
+	    c_end = c + nb_elems * elem_size;
+	    if (c_end > sec->data_allocated)
+	        section_realloc(sec, c_end);
+	    src = sec->data + c;
+	    dst = src;
+	    for(i = 1; i < nb_elems; i++) {
+		dst += elem_size;
+		memcpy(dst, src, elem_size);
+	    }
+	}
+    }
+    c += nb_elems * type_size(type, &align);
+    if (c - corig > al)
+      al = c - corig;
+    return al;
+}
+
+/* store a value or an expression directly in global data or in local array */
+static void init_putv(CType *type, Section *sec, unsigned long c)
+{
+    int bt;
+    void *ptr;
+    CType dtype;
+
+    dtype = *type;
+    dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
+
+    if (sec) {
+	int size, align;
+        /* XXX: not portable */
+        /* XXX: generate error if incorrect relocation */
+        gen_assign_cast(&dtype);
+        bt = type->t & VT_BTYPE;
+
+        if ((vtop->r & VT_SYM)
+            && bt != VT_PTR
+            && bt != VT_FUNC
+            && (bt != (PTR_SIZE == 8 ? VT_LLONG : VT_INT)
+                || (type->t & VT_BITFIELD))
+            && !((vtop->r & VT_CONST) && vtop->sym->v >= SYM_FIRST_ANOM)
+            )
+            tcc_error("initializer element is not computable at load time");
+
+        if (NODATA_WANTED) {
+            vtop--;
+            return;
+        }
+
+	size = type_size(type, &align);
+	section_reserve(sec, c + size);
+        ptr = sec->data + c;
+
+        /* XXX: make code faster ? */
+	if ((vtop->r & (VT_SYM|VT_CONST)) == (VT_SYM|VT_CONST) &&
+	    vtop->sym->v >= SYM_FIRST_ANOM &&
+	    /* XXX This rejects compound literals like
+	       '(void *){ptr}'.  The problem is that '&sym' is
+	       represented the same way, which would be ruled out
+	       by the SYM_FIRST_ANOM check above, but also '"string"'
+	       in 'char *p = "string"' is represented the same
+	       with the type being VT_PTR and the symbol being an
+	       anonymous one.  That is, there's no difference in vtop
+	       between '(void *){x}' and '&(void *){x}'.  Ignore
+	       pointer typed entities here.  Hopefully no real code
+	       will every use compound literals with scalar type.  */
+	    (vtop->type.t & VT_BTYPE) != VT_PTR) {
+	    /* These come from compound literals, memcpy stuff over.  */
+	    Section *ssec;
+	    ElfSym *esym;
+	    ElfW_Rel *rel;
+	    esym = elfsym(vtop->sym);
+	    ssec = tcc_state->sections[esym->st_shndx];
+	    memmove (ptr, ssec->data + esym->st_value, size);
+	    if (ssec->reloc) {
+		/* We need to copy over all memory contents, and that
+		   includes relocations.  Use the fact that relocs are
+		   created it order, so look from the end of relocs
+		   until we hit one before the copied region.  */
+		int num_relocs = ssec->reloc->data_offset / sizeof(*rel);
+		rel = (ElfW_Rel*)(ssec->reloc->data + ssec->reloc->data_offset);
+		while (num_relocs--) {
+		    rel--;
+		    if (rel->r_offset >= esym->st_value + size)
+		      continue;
+		    if (rel->r_offset < esym->st_value)
+		      break;
+		    /* Note: if the same fields are initialized multiple
+		       times (possible with designators) then we possibly
+		       add multiple relocations for the same offset here.
+		       That would lead to wrong code, the last reloc needs
+		       to win.  We clean this up later after the whole
+		       initializer is parsed.  */
+		    put_elf_reloca(symtab_section, sec,
+				   c + rel->r_offset - esym->st_value,
+				   ELFW(R_TYPE)(rel->r_info),
+				   ELFW(R_SYM)(rel->r_info),
+#if PTR_SIZE == 8
+				   rel->r_addend
+#else
+				   0
+#endif
+				  );
+		}
+	    }
+	} else {
+            if (type->t & VT_BITFIELD) {
+                int bit_pos, bit_size, bits, n;
+                unsigned char *p, v, m;
+                bit_pos = BIT_POS(vtop->type.t);
+                bit_size = BIT_SIZE(vtop->type.t);
+                p = (unsigned char*)ptr + (bit_pos >> 3);
+                bit_pos &= 7, bits = 0;
+                while (bit_size) {
+                    n = 8 - bit_pos;
+                    if (n > bit_size)
+                        n = bit_size;
+                    v = vtop->c.i >> bits << bit_pos;
+                    m = ((1 << n) - 1) << bit_pos;
+                    *p = (*p & ~m) | (v & m);
+                    bits += n, bit_size -= n, bit_pos = 0, ++p;
+                }
+            } else
+            switch(bt) {
+		/* XXX: when cross-compiling we assume that each type has the
+		   same representation on host and target, which is likely to
+		   be wrong in the case of long double */
+	    case VT_BOOL:
+		vtop->c.i = vtop->c.i != 0;
+	    case VT_BYTE:
+		*(char *)ptr |= vtop->c.i;
+		break;
+	    case VT_SHORT:
+		*(short *)ptr |= vtop->c.i;
+		break;
+	    case VT_FLOAT:
+		*(float*)ptr = vtop->c.f;
+		break;
+	    case VT_DOUBLE:
+		*(double *)ptr = vtop->c.d;
+		break;
+	    case VT_LDOUBLE:
+#if defined TCC_IS_NATIVE_387
+                if (sizeof (long double) >= 10) /* zero pad ten-byte LD */
+                    memcpy(ptr, &vtop->c.ld, 10);
+#ifdef __TINYC__
+                else if (sizeof (long double) == sizeof (double))
+                    __asm__("fldl %1\nfstpt %0\n" : "=m" (*ptr) : "m" (vtop->c.ld));
+#endif
+                else if (vtop->c.ld == 0.0)
+                    ;
+                else
+#endif
+                if (sizeof(long double) == LDOUBLE_SIZE)
+		    *(long double*)ptr = vtop->c.ld;
+                else if (sizeof(double) == LDOUBLE_SIZE)
+		    *(double *)ptr = (double)vtop->c.ld;
+                else
+                    tcc_error("can't cross compile long double constants");
+		break;
+#if PTR_SIZE != 8
+	    case VT_LLONG:
+		*(long long *)ptr |= vtop->c.i;
+		break;
+#else
+	    case VT_LLONG:
+#endif
+	    case VT_PTR:
+		{
+		    addr_t val = vtop->c.i;
+#if PTR_SIZE == 8
+		    if (vtop->r & VT_SYM)
+		      greloca(sec, vtop->sym, c, R_DATA_PTR, val);
+		    else
+		      *(addr_t *)ptr |= val;
+#else
+		    if (vtop->r & VT_SYM)
+		      greloc(sec, vtop->sym, c, R_DATA_PTR);
+		    *(addr_t *)ptr |= val;
+#endif
+		    break;
+		}
+	    default:
+		{
+		    int val = vtop->c.i;
+#if PTR_SIZE == 8
+		    if (vtop->r & VT_SYM)
+		      greloca(sec, vtop->sym, c, R_DATA_PTR, val);
+		    else
+		      *(int *)ptr |= val;
+#else
+		    if (vtop->r & VT_SYM)
+		      greloc(sec, vtop->sym, c, R_DATA_PTR);
+		    *(int *)ptr |= val;
+#endif
+		    break;
+		}
+	    }
+	}
+        vtop--;
+    } else {
+        vset(&dtype, VT_LOCAL|VT_LVAL, c);
+        vswap();
+        vstore();
+        vpop();
+    }
+}
+
+/* 't' contains the type and storage info. 'c' is the offset of the
+   object in section 'sec'. If 'sec' is NULL, it means stack based
+   allocation. 'first' is true if array '{' must be read (multi
+   dimension implicit array init handling). 'size_only' is true if
+   size only evaluation is wanted (only for arrays). */
+static void decl_initializer(CType *type, Section *sec, unsigned long c, 
+                             int first, int size_only)
+{
+    int len, n, no_oblock, nb, i;
+    int size1, align1;
+    int have_elem;
+    Sym *s, *f;
+    Sym indexsym;
+    CType *t1;
+
+    /* If we currently are at an '}' or ',' we have read an initializer
+       element in one of our callers, and not yet consumed it.  */
+    have_elem = tok == '}' || tok == ',';
+    if (!have_elem && tok != '{' &&
+	/* In case of strings we have special handling for arrays, so
+	   don't consume them as initializer value (which would commit them
+	   to some anonymous symbol).  */
+	tok != TOK_LSTR && tok != TOK_STR &&
+	!size_only) {
+	parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
+	have_elem = 1;
+    }
+
+    if (have_elem &&
+	!(type->t & VT_ARRAY) &&
+	/* Use i_c_parameter_t, to strip toplevel qualifiers.
+	   The source type might have VT_CONSTANT set, which is
+	   of course assignable to non-const elements.  */
+	is_compatible_unqualified_types(type, &vtop->type)) {
+        init_putv(type, sec, c);
+    } else if (type->t & VT_ARRAY) {
+        s = type->ref;
+        n = s->c;
+        t1 = pointed_type(type);
+        size1 = type_size(t1, &align1);
+
+        no_oblock = 1;
+        if ((first && tok != TOK_LSTR && tok != TOK_STR) || 
+            tok == '{') {
+            if (tok != '{')
+                tcc_error("character array initializer must be a literal,"
+                    " optionally enclosed in braces");
+            skip('{');
+            no_oblock = 0;
+        }
+
+        /* only parse strings here if correct type (otherwise: handle
+           them as ((w)char *) expressions */
+        if ((tok == TOK_LSTR && 
+#ifdef TCC_TARGET_PE
+             (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
+#else
+             (t1->t & VT_BTYPE) == VT_INT
+#endif
+            ) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
+	    len = 0;
+            while (tok == TOK_STR || tok == TOK_LSTR) {
+                int cstr_len, ch;
+
+                /* compute maximum number of chars wanted */
+                if (tok == TOK_STR)
+                    cstr_len = tokc.str.size;
+                else
+                    cstr_len = tokc.str.size / sizeof(nwchar_t);
+                cstr_len--;
+                nb = cstr_len;
+                if (n >= 0 && nb > (n - len))
+                    nb = n - len;
+                if (!size_only) {
+                    if (cstr_len > nb)
+                        tcc_warning("initializer-string for array is too long");
+                    /* in order to go faster for common case (char
+                       string in global variable, we handle it
+                       specifically */
+                    if (sec && tok == TOK_STR && size1 == 1) {
+                        if (!NODATA_WANTED)
+                            memcpy(sec->data + c + len, tokc.str.data, nb);
+                    } else {
+                        for(i=0;i<nb;i++) {
+                            if (tok == TOK_STR)
+                                ch = ((unsigned char *)tokc.str.data)[i];
+                            else
+                                ch = ((nwchar_t *)tokc.str.data)[i];
+			    vpushi(ch);
+                            init_putv(t1, sec, c + (len + i) * size1);
+                        }
+                    }
+                }
+                len += nb;
+                next();
+            }
+            /* only add trailing zero if enough storage (no
+               warning in this case since it is standard) */
+            if (n < 0 || len < n) {
+                if (!size_only) {
+		    vpushi(0);
+                    init_putv(t1, sec, c + (len * size1));
+                }
+                len++;
+            }
+	    len *= size1;
+        } else {
+	    indexsym.c = 0;
+	    f = &indexsym;
+
+          do_init_list:
+	    len = 0;
+	    while (tok != '}' || have_elem) {
+		len = decl_designator(type, sec, c, &f, size_only, len);
+		have_elem = 0;
+		if (type->t & VT_ARRAY) {
+		    ++indexsym.c;
+		    /* special test for multi dimensional arrays (may not
+		       be strictly correct if designators are used at the
+		       same time) */
+		    if (no_oblock && len >= n*size1)
+		        break;
+		} else {
+		    if (s->type.t == VT_UNION)
+		        f = NULL;
+		    else
+		        f = f->next;
+		    if (no_oblock && f == NULL)
+		        break;
+		}
+
+		if (tok == '}')
+		    break;
+		skip(',');
+	    }
+        }
+        /* put zeros at the end */
+	if (!size_only && len < n*size1)
+	    init_putz(sec, c + len, n*size1 - len);
+        if (!no_oblock)
+            skip('}');
+        /* patch type size if needed, which happens only for array types */
+        if (n < 0)
+            s->c = size1 == 1 ? len : ((len + size1 - 1)/size1);
+    } else if ((type->t & VT_BTYPE) == VT_STRUCT) {
+	size1 = 1;
+        no_oblock = 1;
+        if (first || tok == '{') {
+            skip('{');
+            no_oblock = 0;
+        }
+        s = type->ref;
+        f = s->next;
+        n = s->c;
+	goto do_init_list;
+    } else if (tok == '{') {
+        next();
+        decl_initializer(type, sec, c, first, size_only);
+        skip('}');
+    } else if (size_only) {
+	/* If we supported only ISO C we wouldn't have to accept calling
+	   this on anything than an array size_only==1 (and even then
+	   only on the outermost level, so no recursion would be needed),
+	   because initializing a flex array member isn't supported.
+	   But GNU C supports it, so we need to recurse even into
+	   subfields of structs and arrays when size_only is set.  */
+        /* just skip expression */
+        skip_or_save_block(NULL);
+    } else {
+	if (!have_elem) {
+	    /* This should happen only when we haven't parsed
+	       the init element above for fear of committing a
+	       string constant to memory too early.  */
+	    if (tok != TOK_STR && tok != TOK_LSTR)
+	      expect("string constant");
+	    parse_init_elem(!sec ? EXPR_ANY : EXPR_CONST);
+	}
+        init_putv(type, sec, c);
+    }
+}
+
+/* parse an initializer for type 't' if 'has_init' is non zero, and
+   allocate space in local or global data space ('r' is either
+   VT_LOCAL or VT_CONST). If 'v' is non zero, then an associated
+   variable 'v' of scope 'scope' is declared before initializers
+   are parsed. If 'v' is zero, then a reference to the new object
+   is put in the value stack. If 'has_init' is 2, a special parsing
+   is done to handle string constants. */
+static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, 
+                                   int has_init, int v, int scope)
+{
+    int size, align, addr;
+    TokenString *init_str = NULL;
+
+    Section *sec;
+    Sym *flexible_array;
+    Sym *sym = NULL;
+    int saved_nocode_wanted = nocode_wanted;
+#ifdef CONFIG_TCC_BCHECK
+    int bcheck = tcc_state->do_bounds_check && !NODATA_WANTED;
+#endif
+
+    if (type->t & VT_STATIC)
+        nocode_wanted |= NODATA_WANTED ? 0x40000000 : 0x80000000;
+
+    flexible_array = NULL;
+    if ((type->t & VT_BTYPE) == VT_STRUCT) {
+        Sym *field = type->ref->next;
+        if (field) {
+            while (field->next)
+                field = field->next;
+            if (field->type.t & VT_ARRAY && field->type.ref->c < 0)
+                flexible_array = field;
+        }
+    }
+
+    size = type_size(type, &align);
+    /* If unknown size, we must evaluate it before
+       evaluating initializers because
+       initializers can generate global data too
+       (e.g. string pointers or ISOC99 compound
+       literals). It also simplifies local
+       initializers handling */
+    if (size < 0 || (flexible_array && has_init)) {
+        if (!has_init) 
+            tcc_error("unknown type size");
+        /* get all init string */
+        if (has_init == 2) {
+	    init_str = tok_str_alloc();
+            /* only get strings */
+            while (tok == TOK_STR || tok == TOK_LSTR) {
+                tok_str_add_tok(init_str);
+                next();
+            }
+	    tok_str_add(init_str, -1);
+	    tok_str_add(init_str, 0);
+        } else {
+	    skip_or_save_block(&init_str);
+        }
+        unget_tok(0);
+
+        /* compute size */
+        begin_macro(init_str, 1);
+        next();
+        decl_initializer(type, NULL, 0, 1, 1);
+        /* prepare second initializer parsing */
+        macro_ptr = init_str->str;
+        next();
+        
+        /* if still unknown size, error */
+        size = type_size(type, &align);
+        if (size < 0) 
+            tcc_error("unknown type size");
+    }
+    /* If there's a flex member and it was used in the initializer
+       adjust size.  */
+    if (flexible_array &&
+	flexible_array->type.ref->c > 0)
+        size += flexible_array->type.ref->c
+	        * pointed_size(&flexible_array->type);
+    /* take into account specified alignment if bigger */
+    if (ad->a.aligned) {
+	int speca = 1 << (ad->a.aligned - 1);
+        if (speca > align)
+            align = speca;
+    } else if (ad->a.packed) {
+        align = 1;
+    }
+
+    if (NODATA_WANTED)
+        size = 0, align = 1;
+
+    if ((r & VT_VALMASK) == VT_LOCAL) {
+        sec = NULL;
+#ifdef CONFIG_TCC_BCHECK
+        if (bcheck && (type->t & VT_ARRAY)) {
+            loc--;
+        }
+#endif
+        loc = (loc - size) & -align;
+        addr = loc;
+#ifdef CONFIG_TCC_BCHECK
+        /* handles bounds */
+        /* XXX: currently, since we do only one pass, we cannot track
+           '&' operators, so we add only arrays */
+        if (bcheck && (type->t & VT_ARRAY)) {
+            addr_t *bounds_ptr;
+            /* add padding between regions */
+            loc--;
+            /* then add local bound info */
+            bounds_ptr = section_ptr_add(lbounds_section, 2 * sizeof(addr_t));
+            bounds_ptr[0] = addr;
+            bounds_ptr[1] = size;
+        }
+#endif
+        if (v) {
+            /* local variable */
+#ifdef CONFIG_TCC_ASM
+	    if (ad->asm_label) {
+		int reg = asm_parse_regvar(ad->asm_label);
+		if (reg >= 0)
+		    r = (r & ~VT_VALMASK) | reg;
+	    }
+#endif
+            sym = sym_push(v, type, r, addr);
+            sym->a = ad->a;
+        } else {
+            /* push local reference */
+            vset(type, r, addr);
+        }
+    } else {
+        if (v && scope == VT_CONST) {
+            /* see if the symbol was already defined */
+            sym = sym_find(v);
+            if (sym) {
+                patch_storage(sym, ad, type);
+                /* we accept several definitions of the same global variable. */
+                if (!has_init && sym->c && elfsym(sym)->st_shndx != SHN_UNDEF)
+                    goto no_alloc;
+            }
+        }
+
+        /* allocate symbol in corresponding section */
+        sec = ad->section;
+        if (!sec) {
+            if (has_init)
+                sec = data_section;
+            else if (tcc_state->nocommon)
+                sec = bss_section;
+        }
+
+        if (sec) {
+	    addr = section_add(sec, size, align);
+#ifdef CONFIG_TCC_BCHECK
+            /* add padding if bound check */
+            if (bcheck)
+                section_add(sec, 1, 1);
+#endif
+        } else {
+            addr = align; /* SHN_COMMON is special, symbol value is align */
+	    sec = common_section;
+        }
+
+        if (v) {
+            if (!sym) {
+                sym = sym_push(v, type, r | VT_SYM, 0);
+                patch_storage(sym, ad, NULL);
+            }
+            /* Local statics have a scope until now (for
+               warnings), remove it here.  */
+            sym->sym_scope = 0;
+            /* update symbol definition */
+	    put_extern_sym(sym, sec, addr, size);
+        } else {
+            /* push global reference */
+            sym = get_sym_ref(type, sec, addr, size);
+	    vpushsym(type, sym);
+	    vtop->r |= r;
+        }
+
+#ifdef CONFIG_TCC_BCHECK
+        /* handles bounds now because the symbol must be defined
+           before for the relocation */
+        if (bcheck) {
+            addr_t *bounds_ptr;
+
+            greloca(bounds_section, sym, bounds_section->data_offset, R_DATA_PTR, 0);
+            /* then add global bound info */
+            bounds_ptr = section_ptr_add(bounds_section, 2 * sizeof(addr_t));
+            bounds_ptr[0] = 0; /* relocated */
+            bounds_ptr[1] = size;
+        }
+#endif
+    }
+
+    if (type->t & VT_VLA) {
+        int a;
+
+        if (NODATA_WANTED)
+            goto no_alloc;
+
+        /* save current stack pointer */
+        if (vlas_in_scope == 0) {
+            if (vla_sp_root_loc == -1)
+                vla_sp_root_loc = (loc -= PTR_SIZE);
+            gen_vla_sp_save(vla_sp_root_loc);
+        }
+
+        vla_runtime_type_size(type, &a);
+        gen_vla_alloc(type, a);
+#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
+        /* on _WIN64, because of the function args scratch area, the
+           result of alloca differs from RSP and is returned in RAX.  */
+        gen_vla_result(addr), addr = (loc -= PTR_SIZE);
+#endif
+        gen_vla_sp_save(addr);
+        vla_sp_loc = addr;
+        vlas_in_scope++;
+
+    } else if (has_init) {
+	size_t oldreloc_offset = 0;
+	if (sec && sec->reloc)
+	  oldreloc_offset = sec->reloc->data_offset;
+        decl_initializer(type, sec, addr, 1, 0);
+	if (sec && sec->reloc)
+	  squeeze_multi_relocs(sec, oldreloc_offset);
+        /* patch flexible array member size back to -1, */
+        /* for possible subsequent similar declarations */
+        if (flexible_array)
+            flexible_array->type.ref->c = -1;
+    }
+
+ no_alloc:
+    /* restore parse state if needed */
+    if (init_str) {
+        end_macro();
+        next();
+    }
+
+    nocode_wanted = saved_nocode_wanted;
+}
+
+/* parse a function defined by symbol 'sym' and generate its code in
+   'cur_text_section' */
+static void gen_function(Sym *sym)
+{
+    nocode_wanted = 0;
+    ind = cur_text_section->data_offset;
+    /* NOTE: we patch the symbol size later */
+    put_extern_sym(sym, cur_text_section, ind, 0);
+    funcname = get_tok_str(sym->v, NULL);
+    func_ind = ind;
+    /* Initialize VLA state */
+    vla_sp_loc = -1;
+    vla_sp_root_loc = -1;
+    /* put debug symbol */
+    tcc_debug_funcstart(tcc_state, sym);
+    /* push a dummy symbol to enable local sym storage */
+    sym_push2(&local_stack, SYM_FIELD, 0, 0);
+    local_scope = 1; /* for function parameters */
+    gfunc_prolog(&sym->type);
+    local_scope = 0;
+    rsym = 0;
+    block(NULL, NULL, 0);
+    nocode_wanted = 0;
+    gsym(rsym);
+    gfunc_epilog();
+    cur_text_section->data_offset = ind;
+    label_pop(&global_label_stack, NULL, 0);
+    /* reset local stack */
+    local_scope = 0;
+    sym_pop(&local_stack, NULL, 0);
+    /* end of function */
+    /* patch symbol size */
+    elfsym(sym)->st_size = ind - func_ind;
+    tcc_debug_funcend(tcc_state, ind - func_ind);
+    /* It's better to crash than to generate wrong code */
+    cur_text_section = NULL;
+    funcname = ""; /* for safety */
+    func_vt.t = VT_VOID; /* for safety */
+    func_var = 0; /* for safety */
+    ind = 0; /* for safety */
+    nocode_wanted = 0x80000000;
+    check_vstack();
+}
+
+static void gen_inline_functions(TCCState *s)
+{
+    Sym *sym;
+    int inline_generated, i, ln;
+    struct InlineFunc *fn;
+
+    ln = file->line_num;
+    /* iterate while inline function are referenced */
+    do {
+        inline_generated = 0;
+        for (i = 0; i < s->nb_inline_fns; ++i) {
+            fn = s->inline_fns[i];
+            sym = fn->sym;
+            if (sym && sym->c) {
+                /* the function was used: generate its code and
+                   convert it to a normal function */
+                fn->sym = NULL;
+                if (file)
+                    pstrcpy(file->filename, sizeof file->filename, fn->filename);
+                sym->type.t &= ~VT_INLINE;
+
+                begin_macro(fn->func_str, 1);
+                next();
+                cur_text_section = text_section;
+                gen_function(sym);
+                end_macro();
+
+                inline_generated = 1;
+            }
+        }
+    } while (inline_generated);
+    file->line_num = ln;
+}
+
+ST_FUNC void free_inline_functions(TCCState *s)
+{
+    int i;
+    /* free tokens of unused inline functions */
+    for (i = 0; i < s->nb_inline_fns; ++i) {
+        struct InlineFunc *fn = s->inline_fns[i];
+        if (fn->sym)
+            tok_str_free(fn->func_str);
+    }
+    dynarray_reset(&s->inline_fns, &s->nb_inline_fns);
+}
+
+/* 'l' is VT_LOCAL or VT_CONST to define default storage type, or VT_CMP
+   if parsing old style parameter decl list (and FUNC_SYM is set then) */
+static int decl0(int l, int is_for_loop_init, Sym *func_sym)
+{
+    int v, has_init, r;
+    CType type, btype;
+    Sym *sym;
+    AttributeDef ad;
+
+    while (1) {
+        if (!parse_btype(&btype, &ad)) {
+            if (is_for_loop_init)
+                return 0;
+            /* skip redundant ';' if not in old parameter decl scope */
+            if (tok == ';' && l != VT_CMP) {
+                next();
+                continue;
+            }
+            if (l != VT_CONST)
+                break;
+            if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) {
+                /* global asm block */
+                asm_global_instr();
+                continue;
+            }
+            if (tok >= TOK_UIDENT) {
+               /* special test for old K&R protos without explicit int
+                  type. Only accepted when defining global data */
+                btype.t = VT_INT;
+            } else {
+                if (tok != TOK_EOF)
+                    expect("declaration");
+                break;
+            }
+        }
+        if (tok == ';') {
+	    if ((btype.t & VT_BTYPE) == VT_STRUCT) {
+		int v = btype.ref->v;
+		if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
+        	    tcc_warning("unnamed struct/union that defines no instances");
+                next();
+                continue;
+	    }
+            if (IS_ENUM(btype.t)) {
+                next();
+                continue;
+            }
+        }
+        while (1) { /* iterate thru each declaration */
+            type = btype;
+	    /* If the base type itself was an array type of unspecified
+	       size (like in 'typedef int arr[]; arr x = {1};') then
+	       we will overwrite the unknown size by the real one for
+	       this decl.  We need to unshare the ref symbol holding
+	       that size.  */
+	    if ((type.t & VT_ARRAY) && type.ref->c < 0) {
+		type.ref = sym_push(SYM_FIELD, &type.ref->type, 0, type.ref->c);
+	    }
+            type_decl(&type, &ad, &v, TYPE_DIRECT);
+#if 0
+            {
+                char buf[500];
+                type_to_str(buf, sizeof(buf), &type, get_tok_str(v, NULL));
+                printf("type = '%s'\n", buf);
+            }
+#endif
+            if ((type.t & VT_BTYPE) == VT_FUNC) {
+                if ((type.t & VT_STATIC) && (l == VT_LOCAL)) {
+                    tcc_error("function without file scope cannot be static");
+                }
+                /* if old style function prototype, we accept a
+                   declaration list */
+                sym = type.ref;
+                if (sym->f.func_type == FUNC_OLD && l == VT_CONST)
+                    decl0(VT_CMP, 0, sym);
+            }
+
+            if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
+                ad.asm_label = asm_label_instr();
+                /* parse one last attribute list, after asm label */
+                parse_attribute(&ad);
+                if (tok == '{')
+                    expect(";");
+            }
+
+#ifdef TCC_TARGET_PE
+            if (ad.a.dllimport || ad.a.dllexport) {
+                if (type.t & (VT_STATIC|VT_TYPEDEF))
+                    tcc_error("cannot have dll linkage with static or typedef");
+                if (ad.a.dllimport) {
+                    if ((type.t & VT_BTYPE) == VT_FUNC)
+                        ad.a.dllimport = 0;
+                    else
+                        type.t |= VT_EXTERN;
+                }
+            }
+#endif
+            if (tok == '{') {
+                if (l != VT_CONST)
+                    tcc_error("cannot use local functions");
+                if ((type.t & VT_BTYPE) != VT_FUNC)
+                    expect("function definition");
+
+                /* reject abstract declarators in function definition
+		   make old style params without decl have int type */
+                sym = type.ref;
+                while ((sym = sym->next) != NULL) {
+                    if (!(sym->v & ~SYM_FIELD))
+                        expect("identifier");
+		    if (sym->type.t == VT_VOID)
+		        sym->type = int_type;
+		}
+                
+                /* XXX: cannot do better now: convert extern line to static inline */
+                if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
+                    type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
+
+                /* put function symbol */
+                sym = external_global_sym(v, &type, 0);
+                type.t &= ~VT_EXTERN;
+                patch_storage(sym, &ad, &type);
+
+                /* static inline functions are just recorded as a kind
+                   of macro. Their code will be emitted at the end of
+                   the compilation unit only if they are used */
+                if ((type.t & (VT_INLINE | VT_STATIC)) == 
+                    (VT_INLINE | VT_STATIC)) {
+                    struct InlineFunc *fn;
+                    const char *filename;
+                           
+                    filename = file ? file->filename : "";
+                    fn = tcc_malloc(sizeof *fn + strlen(filename));
+                    strcpy(fn->filename, filename);
+                    fn->sym = sym;
+		    skip_or_save_block(&fn->func_str);
+                    dynarray_add(&tcc_state->inline_fns,
+				 &tcc_state->nb_inline_fns, fn);
+                } else {
+                    /* compute text section */
+                    cur_text_section = ad.section;
+                    if (!cur_text_section)
+                        cur_text_section = text_section;
+                    gen_function(sym);
+                }
+                break;
+            } else {
+		if (l == VT_CMP) {
+		    /* find parameter in function parameter list */
+		    for (sym = func_sym->next; sym; sym = sym->next)
+			if ((sym->v & ~SYM_FIELD) == v)
+			    goto found;
+		    tcc_error("declaration for parameter '%s' but no such parameter",
+			      get_tok_str(v, NULL));
+found:
+		    if (type.t & VT_STORAGE) /* 'register' is okay */
+		        tcc_error("storage class specified for '%s'",
+				  get_tok_str(v, NULL));
+		    if (sym->type.t != VT_VOID)
+		        tcc_error("redefinition of parameter '%s'",
+				  get_tok_str(v, NULL));
+		    convert_parameter_type(&type);
+		    sym->type = type;
+		} else if (type.t & VT_TYPEDEF) {
+                    /* save typedefed type  */
+                    /* XXX: test storage specifiers ? */
+                    sym = sym_find(v);
+                    if (sym && sym->sym_scope == local_scope) {
+                        if (!is_compatible_types(&sym->type, &type)
+                            || !(sym->type.t & VT_TYPEDEF))
+                            tcc_error("incompatible redefinition of '%s'",
+                                get_tok_str(v, NULL));
+                        sym->type = type;
+                    } else {
+                        sym = sym_push(v, &type, 0, 0);
+                    }
+                    sym->a = ad.a;
+                    sym->f = ad.f;
+                } else {
+                    r = 0;
+                    if ((type.t & VT_BTYPE) == VT_FUNC) {
+                        /* external function definition */
+                        /* specific case for func_call attribute */
+                        type.ref->f = ad.f;
+                    } else if (!(type.t & VT_ARRAY)) {
+                        /* not lvalue if array */
+                        r |= lvalue_type(type.t);
+                    }
+                    has_init = (tok == '=');
+                    if (has_init && (type.t & VT_VLA))
+                        tcc_error("variable length array cannot be initialized");
+                    if (((type.t & VT_EXTERN) && (!has_init || l != VT_CONST)) ||
+			((type.t & VT_BTYPE) == VT_FUNC) ||
+                        ((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
+                         !has_init && l == VT_CONST && type.ref->c < 0)) {
+                        /* external variable or function */
+                        /* NOTE: as GCC, uninitialized global static
+                           arrays of null size are considered as
+                           extern */
+                        type.t |= VT_EXTERN;
+                        sym = external_sym(v, &type, r, &ad);
+                        if (ad.alias_target) {
+                            ElfSym *esym;
+                            Sym *alias_target;
+                            alias_target = sym_find(ad.alias_target);
+                            esym = elfsym(alias_target);
+                            if (!esym)
+                                tcc_error("unsupported forward __alias__ attribute");
+                            /* Local statics have a scope until now (for
+                               warnings), remove it here.  */
+                            sym->sym_scope = 0;
+                            put_extern_sym2(sym, esym->st_shndx, esym->st_value, esym->st_size, 0);
+                        }
+                    } else {
+                        if (type.t & VT_STATIC)
+                            r |= VT_CONST;
+                        else
+                            r |= l;
+                        if (has_init)
+                            next();
+                        else if (l == VT_CONST)
+                            /* uninitialized global variables may be overridden */
+                            type.t |= VT_EXTERN;
+                        decl_initializer_alloc(&type, &ad, r, has_init, v, l);
+                    }
+                }
+                if (tok != ',') {
+                    if (is_for_loop_init)
+                        return 1;
+                    skip(';');
+                    break;
+                }
+                next();
+            }
+            ad.a.aligned = 0;
+        }
+    }
+    return 0;
+}
+
+static void decl(int l)
+{
+    decl0(l, 0, NULL);
+}
+
+/* ------------------------------------------------------------------------- */
Index: EcnlProtoTool/trunk/tcc-0.9.27/tcclib.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tcclib.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tcclib.h	(revision 331)
@@ -0,0 +1,80 @@
+/* Simple libc header for TCC 
+ * 
+ * Add any function you want from the libc there. This file is here
+ * only for your convenience so that you do not need to put the whole
+ * glibc include files on your floppy disk 
+ */
+#ifndef _TCCLIB_H
+#define _TCCLIB_H
+
+#include <stddef.h>
+#include <stdarg.h>
+
+/* stdlib.h */
+void *calloc(size_t nmemb, size_t size);
+void *malloc(size_t size);
+void free(void *ptr);
+void *realloc(void *ptr, size_t size);
+int atoi(const char *nptr);
+long int strtol(const char *nptr, char **endptr, int base);
+unsigned long int strtoul(const char *nptr, char **endptr, int base);
+void exit(int);
+
+/* stdio.h */
+typedef struct __FILE FILE;
+#define EOF (-1)
+extern FILE *stdin;
+extern FILE *stdout;
+extern FILE *stderr;
+FILE *fopen(const char *path, const char *mode);
+FILE *fdopen(int fildes, const char *mode);
+FILE *freopen(const  char *path, const char *mode, FILE *stream);
+int fclose(FILE *stream);
+size_t  fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
+size_t  fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream);
+int fgetc(FILE *stream);
+char *fgets(char *s, int size, FILE *stream);
+int getc(FILE *stream);
+int getchar(void);
+char *gets(char *s);
+int ungetc(int c, FILE *stream);
+int fflush(FILE *stream);
+int putchar (int c);
+
+int printf(const char *format, ...);
+int fprintf(FILE *stream, const char *format, ...);
+int sprintf(char *str, const char *format, ...);
+int snprintf(char *str, size_t size, const  char  *format, ...);
+int asprintf(char **strp, const char *format, ...);
+int dprintf(int fd, const char *format, ...);
+int vprintf(const char *format, va_list ap);
+int vfprintf(FILE  *stream,  const  char *format, va_list ap);
+int vsprintf(char *str, const char *format, va_list ap);
+int vsnprintf(char *str, size_t size, const char  *format, va_list ap);
+int vasprintf(char  **strp,  const  char *format, va_list ap);
+int vdprintf(int fd, const char *format, va_list ap);
+
+void perror(const char *s);
+
+/* string.h */
+char *strcat(char *dest, const char *src);
+char *strchr(const char *s, int c);
+char *strrchr(const char *s, int c);
+char *strcpy(char *dest, const char *src);
+void *memcpy(void *dest, const void *src, size_t n);
+void *memmove(void *dest, const void *src, size_t n);
+void *memset(void *s, int c, size_t n);
+char *strdup(const char *s);
+size_t strlen(const char *s);
+
+/* dlfcn.h */
+#define RTLD_LAZY       0x001
+#define RTLD_NOW        0x002
+#define RTLD_GLOBAL     0x100
+
+void *dlopen(const char *filename, int flag);
+const char *dlerror(void);
+void *dlsym(void *handle, char *symbol);
+int dlclose(void *handle);
+
+#endif /* _TCCLIB_H */
Index: EcnlProtoTool/trunk/tcc-0.9.27/tccpe.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tccpe.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tccpe.c	(revision 331)
@@ -0,0 +1,1996 @@
+/*
+ *  TCCPE.C - PE file output for the Tiny C Compiler
+ *
+ *  Copyright (c) 2005-2007 grischka
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "tcc.h"
+
+#define PE_MERGE_DATA
+/* #define PE_PRINT_SECTIONS */
+
+#ifndef _WIN32
+#define stricmp strcasecmp
+#define strnicmp strncasecmp
+#include <sys/stat.h> /* chmod() */
+#endif
+
+#ifdef TCC_TARGET_X86_64
+# define ADDR3264 ULONGLONG
+# define PE_IMAGE_REL IMAGE_REL_BASED_DIR64
+# define REL_TYPE_DIRECT R_X86_64_64
+# define R_XXX_THUNKFIX R_X86_64_PC32
+# define R_XXX_RELATIVE R_X86_64_RELATIVE
+# define IMAGE_FILE_MACHINE 0x8664
+# define RSRC_RELTYPE 3
+
+#elif defined TCC_TARGET_ARM
+# define ADDR3264 DWORD
+# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW
+# define REL_TYPE_DIRECT R_ARM_ABS32
+# define R_XXX_THUNKFIX R_ARM_ABS32
+# define R_XXX_RELATIVE R_ARM_RELATIVE
+# define IMAGE_FILE_MACHINE 0x01C0
+# define RSRC_RELTYPE 7 /* ??? (not tested) */
+
+#elif defined TCC_TARGET_I386
+# define ADDR3264 DWORD
+# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW
+# define REL_TYPE_DIRECT R_386_32
+# define R_XXX_THUNKFIX R_386_32
+# define R_XXX_RELATIVE R_386_RELATIVE
+# define IMAGE_FILE_MACHINE 0x014C
+# define RSRC_RELTYPE 7 /* DIR32NB */
+
+#endif
+
+#ifndef IMAGE_NT_SIGNATURE
+/* ----------------------------------------------------------- */
+/* definitions below are from winnt.h */
+
+typedef unsigned char BYTE;
+typedef unsigned short WORD;
+typedef unsigned int DWORD;
+typedef unsigned long long ULONGLONG;
+#pragma pack(push, 1)
+
+typedef struct _IMAGE_DOS_HEADER {  /* DOS .EXE header */
+    WORD e_magic;         /* Magic number */
+    WORD e_cblp;          /* Bytes on last page of file */
+    WORD e_cp;            /* Pages in file */
+    WORD e_crlc;          /* Relocations */
+    WORD e_cparhdr;       /* Size of header in paragraphs */
+    WORD e_minalloc;      /* Minimum extra paragraphs needed */
+    WORD e_maxalloc;      /* Maximum extra paragraphs needed */
+    WORD e_ss;            /* Initial (relative) SS value */
+    WORD e_sp;            /* Initial SP value */
+    WORD e_csum;          /* Checksum */
+    WORD e_ip;            /* Initial IP value */
+    WORD e_cs;            /* Initial (relative) CS value */
+    WORD e_lfarlc;        /* File address of relocation table */
+    WORD e_ovno;          /* Overlay number */
+    WORD e_res[4];        /* Reserved words */
+    WORD e_oemid;         /* OEM identifier (for e_oeminfo) */
+    WORD e_oeminfo;       /* OEM information; e_oemid specific */
+    WORD e_res2[10];      /* Reserved words */
+    DWORD e_lfanew;        /* File address of new exe header */
+} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
+
+#define IMAGE_NT_SIGNATURE  0x00004550  /* PE00 */
+#define SIZE_OF_NT_SIGNATURE 4
+
+typedef struct _IMAGE_FILE_HEADER {
+    WORD    Machine;
+    WORD    NumberOfSections;
+    DWORD   TimeDateStamp;
+    DWORD   PointerToSymbolTable;
+    DWORD   NumberOfSymbols;
+    WORD    SizeOfOptionalHeader;
+    WORD    Characteristics;
+} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
+
+
+#define IMAGE_SIZEOF_FILE_HEADER 20
+
+typedef struct _IMAGE_DATA_DIRECTORY {
+    DWORD   VirtualAddress;
+    DWORD   Size;
+} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
+
+
+typedef struct _IMAGE_OPTIONAL_HEADER {
+    /* Standard fields. */
+    WORD    Magic;
+    BYTE    MajorLinkerVersion;
+    BYTE    MinorLinkerVersion;
+    DWORD   SizeOfCode;
+    DWORD   SizeOfInitializedData;
+    DWORD   SizeOfUninitializedData;
+    DWORD   AddressOfEntryPoint;
+    DWORD   BaseOfCode;
+#ifndef TCC_TARGET_X86_64
+    DWORD   BaseOfData;
+#endif
+    /* NT additional fields. */
+    ADDR3264 ImageBase;
+    DWORD   SectionAlignment;
+    DWORD   FileAlignment;
+    WORD    MajorOperatingSystemVersion;
+    WORD    MinorOperatingSystemVersion;
+    WORD    MajorImageVersion;
+    WORD    MinorImageVersion;
+    WORD    MajorSubsystemVersion;
+    WORD    MinorSubsystemVersion;
+    DWORD   Win32VersionValue;
+    DWORD   SizeOfImage;
+    DWORD   SizeOfHeaders;
+    DWORD   CheckSum;
+    WORD    Subsystem;
+    WORD    DllCharacteristics;
+    ADDR3264 SizeOfStackReserve;
+    ADDR3264 SizeOfStackCommit;
+    ADDR3264 SizeOfHeapReserve;
+    ADDR3264 SizeOfHeapCommit;
+    DWORD   LoaderFlags;
+    DWORD   NumberOfRvaAndSizes;
+    IMAGE_DATA_DIRECTORY DataDirectory[16];
+} IMAGE_OPTIONAL_HEADER32, IMAGE_OPTIONAL_HEADER64, IMAGE_OPTIONAL_HEADER;
+
+#define IMAGE_DIRECTORY_ENTRY_EXPORT          0   /* Export Directory */
+#define IMAGE_DIRECTORY_ENTRY_IMPORT          1   /* Import Directory */
+#define IMAGE_DIRECTORY_ENTRY_RESOURCE        2   /* Resource Directory */
+#define IMAGE_DIRECTORY_ENTRY_EXCEPTION       3   /* Exception Directory */
+#define IMAGE_DIRECTORY_ENTRY_SECURITY        4   /* Security Directory */
+#define IMAGE_DIRECTORY_ENTRY_BASERELOC       5   /* Base Relocation Table */
+#define IMAGE_DIRECTORY_ENTRY_DEBUG           6   /* Debug Directory */
+/*      IMAGE_DIRECTORY_ENTRY_COPYRIGHT       7      (X86 usage) */
+#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE    7   /* Architecture Specific Data */
+#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR       8   /* RVA of GP */
+#define IMAGE_DIRECTORY_ENTRY_TLS             9   /* TLS Directory */
+#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG    10   /* Load Configuration Directory */
+#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT   11   /* Bound Import Directory in headers */
+#define IMAGE_DIRECTORY_ENTRY_IAT            12   /* Import Address Table */
+#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT   13   /* Delay Load Import Descriptors */
+#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14   /* COM Runtime descriptor */
+
+/* Section header format. */
+#define IMAGE_SIZEOF_SHORT_NAME         8
+
+typedef struct _IMAGE_SECTION_HEADER {
+    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];
+    union {
+            DWORD   PhysicalAddress;
+            DWORD   VirtualSize;
+    } Misc;
+    DWORD   VirtualAddress;
+    DWORD   SizeOfRawData;
+    DWORD   PointerToRawData;
+    DWORD   PointerToRelocations;
+    DWORD   PointerToLinenumbers;
+    WORD    NumberOfRelocations;
+    WORD    NumberOfLinenumbers;
+    DWORD   Characteristics;
+} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
+
+#define IMAGE_SIZEOF_SECTION_HEADER     40
+
+typedef struct _IMAGE_EXPORT_DIRECTORY {
+    DWORD Characteristics;
+    DWORD TimeDateStamp;
+    WORD MajorVersion;
+    WORD MinorVersion;
+    DWORD Name;
+    DWORD Base;
+    DWORD NumberOfFunctions;
+    DWORD NumberOfNames;
+    DWORD AddressOfFunctions;
+    DWORD AddressOfNames;
+    DWORD AddressOfNameOrdinals;
+} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY;
+
+typedef struct _IMAGE_IMPORT_DESCRIPTOR {
+    union {
+        DWORD Characteristics;
+        DWORD OriginalFirstThunk;
+    };
+    DWORD TimeDateStamp;
+    DWORD ForwarderChain;
+    DWORD Name;
+    DWORD FirstThunk;
+} IMAGE_IMPORT_DESCRIPTOR;
+
+typedef struct _IMAGE_BASE_RELOCATION {
+    DWORD   VirtualAddress;
+    DWORD   SizeOfBlock;
+//  WORD    TypeOffset[1];
+} IMAGE_BASE_RELOCATION;
+
+#define IMAGE_SIZEOF_BASE_RELOCATION     8
+
+#define IMAGE_REL_BASED_ABSOLUTE         0
+#define IMAGE_REL_BASED_HIGH             1
+#define IMAGE_REL_BASED_LOW              2
+#define IMAGE_REL_BASED_HIGHLOW          3
+#define IMAGE_REL_BASED_HIGHADJ          4
+#define IMAGE_REL_BASED_MIPS_JMPADDR     5
+#define IMAGE_REL_BASED_SECTION          6
+#define IMAGE_REL_BASED_REL32            7
+#define IMAGE_REL_BASED_DIR64           10
+
+#pragma pack(pop)
+
+/* ----------------------------------------------------------- */
+#endif /* ndef IMAGE_NT_SIGNATURE */
+/* ----------------------------------------------------------- */
+
+#ifndef IMAGE_REL_BASED_DIR64
+# define IMAGE_REL_BASED_DIR64 10
+#endif
+
+#pragma pack(push, 1)
+struct pe_header
+{
+    IMAGE_DOS_HEADER doshdr;
+    BYTE dosstub[0x40];
+    DWORD nt_sig;
+    IMAGE_FILE_HEADER filehdr;
+#ifdef TCC_TARGET_X86_64
+    IMAGE_OPTIONAL_HEADER64 opthdr;
+#else
+#ifdef _WIN64
+    IMAGE_OPTIONAL_HEADER32 opthdr;
+#else
+    IMAGE_OPTIONAL_HEADER opthdr;
+#endif
+#endif
+};
+
+struct pe_reloc_header {
+    DWORD offset;
+    DWORD size;
+};
+
+struct pe_rsrc_header {
+    struct _IMAGE_FILE_HEADER filehdr;
+    struct _IMAGE_SECTION_HEADER sectionhdr;
+};
+
+struct pe_rsrc_reloc {
+    DWORD offset;
+    DWORD size;
+    WORD type;
+};
+#pragma pack(pop)
+
+/* ------------------------------------------------------------- */
+/* internal temporary structures */
+
+/*
+#define IMAGE_SCN_CNT_CODE                  0x00000020
+#define IMAGE_SCN_CNT_INITIALIZED_DATA      0x00000040
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA    0x00000080
+#define IMAGE_SCN_MEM_DISCARDABLE           0x02000000
+#define IMAGE_SCN_MEM_SHARED                0x10000000
+#define IMAGE_SCN_MEM_EXECUTE               0x20000000
+#define IMAGE_SCN_MEM_READ                  0x40000000
+#define IMAGE_SCN_MEM_WRITE                 0x80000000
+*/
+
+enum {
+    sec_text = 0,
+    sec_data ,
+    sec_bss ,
+    sec_idata ,
+    sec_pdata ,
+    sec_other ,
+    sec_rsrc ,
+    sec_stab ,
+    sec_reloc ,
+    sec_last
+};
+
+static const DWORD pe_sec_flags[] = {
+    0x60000020, /* ".text"     , */
+    0xC0000040, /* ".data"     , */
+    0xC0000080, /* ".bss"      , */
+    0x40000040, /* ".idata"    , */
+    0x40000040, /* ".pdata"    , */
+    0xE0000060, /* < other >   , */
+    0x40000040, /* ".rsrc"     , */
+    0x42000802, /* ".stab"     , */
+    0x42000040, /* ".reloc"    , */
+};
+
+struct section_info {
+    int cls, ord;
+    char name[32];
+    DWORD sh_addr;
+    DWORD sh_size;
+    DWORD sh_flags;
+    unsigned char *data;
+    DWORD data_size;
+    IMAGE_SECTION_HEADER ish;
+};
+
+struct import_symbol {
+    int sym_index;
+    int iat_index;
+    int thk_offset;
+};
+
+struct pe_import_info {
+    int dll_index;
+    int sym_count;
+    struct import_symbol **symbols;
+};
+
+struct pe_info {
+    TCCState *s1;
+    Section *reloc;
+    Section *thunk;
+    const char *filename;
+    int type;
+    DWORD sizeofheaders;
+    ADDR3264 imagebase;
+    const char *start_symbol;
+    DWORD start_addr;
+    DWORD imp_offs;
+    DWORD imp_size;
+    DWORD iat_offs;
+    DWORD iat_size;
+    DWORD exp_offs;
+    DWORD exp_size;
+    int subsystem;
+    DWORD section_align;
+    DWORD file_align;
+    struct section_info *sec_info;
+    int sec_count;
+    struct pe_import_info **imp_info;
+    int imp_count;
+};
+
+#define PE_NUL 0
+#define PE_DLL 1
+#define PE_GUI 2
+#define PE_EXE 3
+#define PE_RUN 4
+
+/* --------------------------------------------*/
+
+static const char *pe_export_name(TCCState *s1, ElfW(Sym) *sym)
+{
+    const char *name = (char*)symtab_section->link->data + sym->st_name;
+    if (s1->leading_underscore && name[0] == '_' && !(sym->st_other & ST_PE_STDCALL))
+        return name + 1;
+    return name;
+}
+
+static int pe_find_import(TCCState * s1, ElfW(Sym) *sym)
+{
+    char buffer[200];
+    const char *s, *p;
+    int sym_index = 0, n = 0;
+    int a, err = 0;
+
+    do {
+        s = pe_export_name(s1, sym);
+        a = 0;
+        if (n) {
+            /* second try: */
+	    if (sym->st_other & ST_PE_STDCALL) {
+                /* try w/0 stdcall deco (windows API convention) */
+	        p = strrchr(s, '@');
+	        if (!p || s[0] != '_')
+	            break;
+	        strcpy(buffer, s+1)[p-s-1] = 0;
+	    } else if (s[0] != '_') { /* try non-ansi function */
+	        buffer[0] = '_', strcpy(buffer + 1, s);
+	    } else if (0 == memcmp(s, "__imp_", 6)) { /* mingw 2.0 */
+	        strcpy(buffer, s + 6), a = 1;
+	    } else if (0 == memcmp(s, "_imp__", 6)) { /* mingw 3.7 */
+	        strcpy(buffer, s + 6), a = 1;
+	    } else {
+	        continue;
+	    }
+	    s = buffer;
+        }
+        sym_index = find_elf_sym(s1->dynsymtab_section, s);
+        // printf("find (%d) %d %s\n", n, sym_index, s);
+        if (sym_index
+            && ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT
+            && 0 == (sym->st_other & ST_PE_IMPORT)
+            && 0 == a
+            ) err = -1, sym_index = 0;
+    } while (0 == sym_index && ++n < 2);
+    return n == 2 ? err : sym_index;
+}
+
+/*----------------------------------------------------------------------------*/
+
+static int dynarray_assoc(void **pp, int n, int key)
+{
+    int i;
+    for (i = 0; i < n; ++i, ++pp)
+    if (key == **(int **) pp)
+        return i;
+    return -1;
+}
+
+#if 0
+ST_FN DWORD umin(DWORD a, DWORD b)
+{
+    return a < b ? a : b;
+}
+#endif
+
+static DWORD umax(DWORD a, DWORD b)
+{
+    return a < b ? b : a;
+}
+
+static DWORD pe_file_align(struct pe_info *pe, DWORD n)
+{
+    return (n + (pe->file_align - 1)) & ~(pe->file_align - 1);
+}
+
+static DWORD pe_virtual_align(struct pe_info *pe, DWORD n)
+{
+    return (n + (pe->section_align - 1)) & ~(pe->section_align - 1);
+}
+
+static void pe_align_section(Section *s, int a)
+{
+    int i = s->data_offset & (a-1);
+    if (i)
+        section_ptr_add(s, a - i);
+}
+
+static void pe_set_datadir(struct pe_header *hdr, int dir, DWORD addr, DWORD size)
+{
+    hdr->opthdr.DataDirectory[dir].VirtualAddress = addr;
+    hdr->opthdr.DataDirectory[dir].Size = size;
+}
+
+static int pe_fwrite(void *data, unsigned len, FILE *fp, DWORD *psum)
+{
+    if (psum) {
+        DWORD sum = *psum;
+        WORD *p = data;
+        int i;
+        for (i = len; i > 0; i -= 2) {
+            sum += (i >= 2) ? *p++ : *(BYTE*)p;
+            sum = (sum + (sum >> 16)) & 0xFFFF;
+        }
+        *psum = sum;
+    }
+    return len == fwrite(data, 1, len, fp) ? 0 : -1;
+}
+
+static void pe_fpad(FILE *fp, DWORD new_pos)
+{
+    DWORD pos = ftell(fp);
+    while (++pos <= new_pos)
+        fputc(0, fp);
+}
+
+/*----------------------------------------------------------------------------*/
+static int pe_write(struct pe_info *pe)
+{
+    static const struct pe_header pe_template = {
+    {
+    /* IMAGE_DOS_HEADER doshdr */
+    0x5A4D, /*WORD e_magic;         Magic number */
+    0x0090, /*WORD e_cblp;          Bytes on last page of file */
+    0x0003, /*WORD e_cp;            Pages in file */
+    0x0000, /*WORD e_crlc;          Relocations */
+
+    0x0004, /*WORD e_cparhdr;       Size of header in paragraphs */
+    0x0000, /*WORD e_minalloc;      Minimum extra paragraphs needed */
+    0xFFFF, /*WORD e_maxalloc;      Maximum extra paragraphs needed */
+    0x0000, /*WORD e_ss;            Initial (relative) SS value */
+
+    0x00B8, /*WORD e_sp;            Initial SP value */
+    0x0000, /*WORD e_csum;          Checksum */
+    0x0000, /*WORD e_ip;            Initial IP value */
+    0x0000, /*WORD e_cs;            Initial (relative) CS value */
+    0x0040, /*WORD e_lfarlc;        File address of relocation table */
+    0x0000, /*WORD e_ovno;          Overlay number */
+    {0,0,0,0}, /*WORD e_res[4];     Reserved words */
+    0x0000, /*WORD e_oemid;         OEM identifier (for e_oeminfo) */
+    0x0000, /*WORD e_oeminfo;       OEM information; e_oemid specific */
+    {0,0,0,0,0,0,0,0,0,0}, /*WORD e_res2[10];      Reserved words */
+    0x00000080  /*DWORD   e_lfanew;        File address of new exe header */
+    },{
+    /* BYTE dosstub[0x40] */
+    /* 14 code bytes + "This program cannot be run in DOS mode.\r\r\n$" + 6 * 0x00 */
+    0x0e,0x1f,0xba,0x0e,0x00,0xb4,0x09,0xcd,0x21,0xb8,0x01,0x4c,0xcd,0x21,0x54,0x68,
+    0x69,0x73,0x20,0x70,0x72,0x6f,0x67,0x72,0x61,0x6d,0x20,0x63,0x61,0x6e,0x6e,0x6f,
+    0x74,0x20,0x62,0x65,0x20,0x72,0x75,0x6e,0x20,0x69,0x6e,0x20,0x44,0x4f,0x53,0x20,
+    0x6d,0x6f,0x64,0x65,0x2e,0x0d,0x0d,0x0a,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    },
+    0x00004550, /* DWORD nt_sig = IMAGE_NT_SIGNATURE */
+    {
+    /* IMAGE_FILE_HEADER filehdr */
+    IMAGE_FILE_MACHINE, /*WORD    Machine; */
+    0x0003, /*WORD    NumberOfSections; */
+    0x00000000, /*DWORD   TimeDateStamp; */
+    0x00000000, /*DWORD   PointerToSymbolTable; */
+    0x00000000, /*DWORD   NumberOfSymbols; */
+#if defined(TCC_TARGET_X86_64)
+    0x00F0, /*WORD    SizeOfOptionalHeader; */
+    0x022F  /*WORD    Characteristics; */
+#define CHARACTERISTICS_DLL 0x222E
+#elif defined(TCC_TARGET_I386)
+    0x00E0, /*WORD    SizeOfOptionalHeader; */
+    0x030F  /*WORD    Characteristics; */
+#define CHARACTERISTICS_DLL 0x230E
+#elif defined(TCC_TARGET_ARM)
+    0x00E0, /*WORD    SizeOfOptionalHeader; */
+    0x010F, /*WORD    Characteristics; */
+#define CHARACTERISTICS_DLL 0x230F
+#endif
+},{
+    /* IMAGE_OPTIONAL_HEADER opthdr */
+    /* Standard fields. */
+#ifdef TCC_TARGET_X86_64
+    0x020B, /*WORD    Magic; */
+#else
+    0x010B, /*WORD    Magic; */
+#endif
+    0x06, /*BYTE    MajorLinkerVersion; */
+    0x00, /*BYTE    MinorLinkerVersion; */
+    0x00000000, /*DWORD   SizeOfCode; */
+    0x00000000, /*DWORD   SizeOfInitializedData; */
+    0x00000000, /*DWORD   SizeOfUninitializedData; */
+    0x00000000, /*DWORD   AddressOfEntryPoint; */
+    0x00000000, /*DWORD   BaseOfCode; */
+#ifndef TCC_TARGET_X86_64
+    0x00000000, /*DWORD   BaseOfData; */
+#endif
+    /* NT additional fields. */
+#if defined(TCC_TARGET_ARM)
+    0x00100000,	    /*DWORD   ImageBase; */
+#else
+    0x00400000,	    /*DWORD   ImageBase; */
+#endif
+    0x00001000, /*DWORD   SectionAlignment; */
+    0x00000200, /*DWORD   FileAlignment; */
+    0x0004, /*WORD    MajorOperatingSystemVersion; */
+    0x0000, /*WORD    MinorOperatingSystemVersion; */
+    0x0000, /*WORD    MajorImageVersion; */
+    0x0000, /*WORD    MinorImageVersion; */
+    0x0004, /*WORD    MajorSubsystemVersion; */
+    0x0000, /*WORD    MinorSubsystemVersion; */
+    0x00000000, /*DWORD   Win32VersionValue; */
+    0x00000000, /*DWORD   SizeOfImage; */
+    0x00000200, /*DWORD   SizeOfHeaders; */
+    0x00000000, /*DWORD   CheckSum; */
+    0x0002, /*WORD    Subsystem; */
+    0x0000, /*WORD    DllCharacteristics; */
+    0x00100000, /*DWORD   SizeOfStackReserve; */
+    0x00001000, /*DWORD   SizeOfStackCommit; */
+    0x00100000, /*DWORD   SizeOfHeapReserve; */
+    0x00001000, /*DWORD   SizeOfHeapCommit; */
+    0x00000000, /*DWORD   LoaderFlags; */
+    0x00000010, /*DWORD   NumberOfRvaAndSizes; */
+
+    /* IMAGE_DATA_DIRECTORY DataDirectory[16]; */
+    {{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0},
+     {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}}
+    }};
+
+    struct pe_header pe_header = pe_template;
+
+    int i;
+    FILE *op;
+    DWORD file_offset, sum;
+    struct section_info *si;
+    IMAGE_SECTION_HEADER *psh;
+
+    op = fopen(pe->filename, "wb");
+    if (NULL == op) {
+        tcc_error_noabort("could not write '%s': %s", pe->filename, strerror(errno));
+        return -1;
+    }
+
+    pe->sizeofheaders = pe_file_align(pe,
+        sizeof (struct pe_header)
+        + pe->sec_count * sizeof (IMAGE_SECTION_HEADER)
+        );
+
+    file_offset = pe->sizeofheaders;
+
+    if (2 == pe->s1->verbose)
+        printf("-------------------------------"
+               "\n  virt   file   size  section" "\n");
+    for (i = 0; i < pe->sec_count; ++i) {
+        DWORD addr, size;
+        const char *sh_name;
+
+        si = pe->sec_info + i;
+        sh_name = si->name;
+        addr = si->sh_addr - pe->imagebase;
+        size = si->sh_size;
+        psh = &si->ish;
+
+        if (2 == pe->s1->verbose)
+            printf("%6x %6x %6x  %s\n",
+                (unsigned)addr, (unsigned)file_offset, (unsigned)size, sh_name);
+
+        switch (si->cls) {
+            case sec_text:
+                pe_header.opthdr.BaseOfCode = addr;
+                break;
+
+            case sec_data:
+#ifndef TCC_TARGET_X86_64
+                pe_header.opthdr.BaseOfData = addr;
+#endif
+                break;
+
+            case sec_bss:
+                break;
+
+            case sec_reloc:
+                pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_BASERELOC, addr, size);
+                break;
+
+            case sec_rsrc:
+                pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_RESOURCE, addr, size);
+                break;
+
+            case sec_pdata:
+                pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_EXCEPTION, addr, size);
+                break;
+
+            case sec_stab:
+                break;
+        }
+
+        if (pe->thunk == pe->s1->sections[si->ord]) {
+            if (pe->imp_size) {
+                pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_IMPORT,
+                    pe->imp_offs + addr, pe->imp_size);
+                pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_IAT,
+                    pe->iat_offs + addr, pe->iat_size);
+            }
+            if (pe->exp_size) {
+                pe_set_datadir(&pe_header, IMAGE_DIRECTORY_ENTRY_EXPORT,
+                    pe->exp_offs + addr, pe->exp_size);
+            }
+        }
+
+        strncpy((char*)psh->Name, sh_name, sizeof psh->Name);
+
+        psh->Characteristics = pe_sec_flags[si->cls];
+        psh->VirtualAddress = addr;
+        psh->Misc.VirtualSize = size;
+        pe_header.opthdr.SizeOfImage =
+            umax(pe_virtual_align(pe, size + addr), pe_header.opthdr.SizeOfImage);
+
+        if (si->data_size) {
+            psh->PointerToRawData = file_offset;
+            file_offset = pe_file_align(pe, file_offset + si->data_size);
+            psh->SizeOfRawData = file_offset - psh->PointerToRawData;
+            if (si->cls == sec_text)
+                pe_header.opthdr.SizeOfCode += psh->SizeOfRawData;
+            else
+                pe_header.opthdr.SizeOfInitializedData += psh->SizeOfRawData;
+        }
+    }
+
+    //pe_header.filehdr.TimeDateStamp = time(NULL);
+    pe_header.filehdr.NumberOfSections = pe->sec_count;
+    pe_header.opthdr.AddressOfEntryPoint = pe->start_addr;
+    pe_header.opthdr.SizeOfHeaders = pe->sizeofheaders;
+    pe_header.opthdr.ImageBase = pe->imagebase;
+    pe_header.opthdr.Subsystem = pe->subsystem;
+    if (pe->s1->pe_stack_size)
+        pe_header.opthdr.SizeOfStackReserve = pe->s1->pe_stack_size;
+    if (PE_DLL == pe->type)
+        pe_header.filehdr.Characteristics = CHARACTERISTICS_DLL;
+    pe_header.filehdr.Characteristics |= pe->s1->pe_characteristics;
+
+    sum = 0;
+    pe_fwrite(&pe_header, sizeof pe_header, op, &sum);
+    for (i = 0; i < pe->sec_count; ++i)
+        pe_fwrite(&pe->sec_info[i].ish, sizeof(IMAGE_SECTION_HEADER), op, &sum);
+    pe_fpad(op, pe->sizeofheaders);
+    for (i = 0; i < pe->sec_count; ++i) {
+        si = pe->sec_info + i;
+        psh = &si->ish;
+        if (si->data_size) {
+            pe_fwrite(si->data, si->data_size, op, &sum);
+            file_offset = psh->PointerToRawData + psh->SizeOfRawData;
+            pe_fpad(op, file_offset);
+        }
+    }
+
+    pe_header.opthdr.CheckSum = sum + file_offset;
+    fseek(op, offsetof(struct pe_header, opthdr.CheckSum), SEEK_SET);
+    pe_fwrite(&pe_header.opthdr.CheckSum, sizeof pe_header.opthdr.CheckSum, op, NULL);
+    fclose (op);
+#ifndef _WIN32
+    chmod(pe->filename, 0777);
+#endif
+
+    if (2 == pe->s1->verbose)
+        printf("-------------------------------\n");
+    if (pe->s1->verbose)
+        printf("<- %s (%u bytes)\n", pe->filename, (unsigned)file_offset);
+
+    return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+
+static struct import_symbol *pe_add_import(struct pe_info *pe, int sym_index)
+{
+    int i;
+    int dll_index;
+    struct pe_import_info *p;
+    struct import_symbol *s;
+    ElfW(Sym) *isym;
+
+    isym = (ElfW(Sym) *)pe->s1->dynsymtab_section->data + sym_index;
+    dll_index = isym->st_size;
+
+    i = dynarray_assoc ((void**)pe->imp_info, pe->imp_count, dll_index);
+    if (-1 != i) {
+        p = pe->imp_info[i];
+        goto found_dll;
+    }
+    p = tcc_mallocz(sizeof *p);
+    p->dll_index = dll_index;
+    dynarray_add(&pe->imp_info, &pe->imp_count, p);
+
+found_dll:
+    i = dynarray_assoc ((void**)p->symbols, p->sym_count, sym_index);
+    if (-1 != i)
+        return p->symbols[i];
+
+    s = tcc_mallocz(sizeof *s);
+    dynarray_add(&p->symbols, &p->sym_count, s);
+    s->sym_index = sym_index;
+    return s;
+}
+
+void pe_free_imports(struct pe_info *pe)
+{
+    int i;
+    for (i = 0; i < pe->imp_count; ++i) {
+        struct pe_import_info *p = pe->imp_info[i];
+        dynarray_reset(&p->symbols, &p->sym_count);
+    }
+    dynarray_reset(&pe->imp_info, &pe->imp_count);
+}
+
+/*----------------------------------------------------------------------------*/
+static void pe_build_imports(struct pe_info *pe)
+{
+    int thk_ptr, ent_ptr, dll_ptr, sym_cnt, i;
+    DWORD rva_base = pe->thunk->sh_addr - pe->imagebase;
+    int ndlls = pe->imp_count;
+
+    for (sym_cnt = i = 0; i < ndlls; ++i)
+        sym_cnt += pe->imp_info[i]->sym_count;
+
+    if (0 == sym_cnt)
+        return;
+
+    pe_align_section(pe->thunk, 16);
+
+    pe->imp_offs = dll_ptr = pe->thunk->data_offset;
+    pe->imp_size = (ndlls + 1) * sizeof(IMAGE_IMPORT_DESCRIPTOR);
+    pe->iat_offs = dll_ptr + pe->imp_size;
+    pe->iat_size = (sym_cnt + ndlls) * sizeof(ADDR3264);
+    section_ptr_add(pe->thunk, pe->imp_size + 2*pe->iat_size);
+
+    thk_ptr = pe->iat_offs;
+    ent_ptr = pe->iat_offs + pe->iat_size;
+
+    for (i = 0; i < pe->imp_count; ++i) {
+        IMAGE_IMPORT_DESCRIPTOR *hdr;
+        int k, n, dllindex;
+        ADDR3264 v;
+        struct pe_import_info *p = pe->imp_info[i];
+        const char *name;
+        DLLReference *dllref;
+
+        dllindex = p->dll_index;
+        if (dllindex)
+            name = (dllref = pe->s1->loaded_dlls[dllindex-1])->name;
+        else
+            name = "", dllref = NULL;
+
+        /* put the dll name into the import header */
+        v = put_elf_str(pe->thunk, name);
+        hdr = (IMAGE_IMPORT_DESCRIPTOR*)(pe->thunk->data + dll_ptr);
+        hdr->FirstThunk = thk_ptr + rva_base;
+        hdr->OriginalFirstThunk = ent_ptr + rva_base;
+        hdr->Name = v + rva_base;
+
+        for (k = 0, n = p->sym_count; k <= n; ++k) {
+            if (k < n) {
+                int iat_index = p->symbols[k]->iat_index;
+                int sym_index = p->symbols[k]->sym_index;
+                ElfW(Sym) *imp_sym = (ElfW(Sym) *)pe->s1->dynsymtab_section->data + sym_index;
+                ElfW(Sym) *org_sym = (ElfW(Sym) *)symtab_section->data + iat_index;
+                const char *name = (char*)pe->s1->dynsymtab_section->link->data + imp_sym->st_name;
+                int ordinal;
+
+                org_sym->st_value = thk_ptr;
+                org_sym->st_shndx = pe->thunk->sh_num;
+
+                if (dllref)
+                    v = 0, ordinal = imp_sym->st_value; /* ordinal from pe_load_def */
+                else
+                    ordinal = 0, v = imp_sym->st_value; /* address from tcc_add_symbol() */
+
+#ifdef TCC_IS_NATIVE
+                if (pe->type == PE_RUN) {
+                    if (dllref) {
+                        if ( !dllref->handle )
+                            dllref->handle = LoadLibrary(dllref->name);
+                        v = (ADDR3264)GetProcAddress(dllref->handle, ordinal?(char*)0+ordinal:name);
+                    }
+                    if (!v)
+                        tcc_error_noabort("can't build symbol '%s'", name);
+                } else
+#endif
+                if (ordinal) {
+                    v = ordinal | (ADDR3264)1 << (sizeof(ADDR3264)*8 - 1);
+                } else {
+                    v = pe->thunk->data_offset + rva_base;
+                    section_ptr_add(pe->thunk, sizeof(WORD)); /* hint, not used */
+                    put_elf_str(pe->thunk, name);
+                }
+
+            } else {
+                v = 0; /* last entry is zero */
+            }
+
+            *(ADDR3264*)(pe->thunk->data+thk_ptr) =
+            *(ADDR3264*)(pe->thunk->data+ent_ptr) = v;
+            thk_ptr += sizeof (ADDR3264);
+            ent_ptr += sizeof (ADDR3264);
+        }
+        dll_ptr += sizeof(IMAGE_IMPORT_DESCRIPTOR);
+    }
+}
+
+/* ------------------------------------------------------------- */
+
+struct pe_sort_sym
+{
+    int index;
+    const char *name;
+};
+
+static int sym_cmp(const void *va, const void *vb)
+{
+    const char *ca = (*(struct pe_sort_sym**)va)->name;
+    const char *cb = (*(struct pe_sort_sym**)vb)->name;
+    return strcmp(ca, cb);
+}
+
+static void pe_build_exports(struct pe_info *pe)
+{
+    ElfW(Sym) *sym;
+    int sym_index, sym_end;
+    DWORD rva_base, func_o, name_o, ord_o, str_o;
+    IMAGE_EXPORT_DIRECTORY *hdr;
+    int sym_count, ord;
+    struct pe_sort_sym **sorted, *p;
+
+    FILE *op;
+    char buf[260];
+    const char *dllname;
+    const char *name;
+
+    rva_base = pe->thunk->sh_addr - pe->imagebase;
+    sym_count = 0, sorted = NULL, op = NULL;
+
+    sym_end = symtab_section->data_offset / sizeof(ElfW(Sym));
+    for (sym_index = 1; sym_index < sym_end; ++sym_index) {
+        sym = (ElfW(Sym)*)symtab_section->data + sym_index;
+        name = pe_export_name(pe->s1, sym);
+        if ((sym->st_other & ST_PE_EXPORT)
+            /* export only symbols from actually written sections */
+            && pe->s1->sections[sym->st_shndx]->sh_addr) {
+            p = tcc_malloc(sizeof *p);
+            p->index = sym_index;
+            p->name = name;
+            dynarray_add(&sorted, &sym_count, p);
+        }
+#if 0
+        if (sym->st_other & ST_PE_EXPORT)
+            printf("export: %s\n", name);
+        if (sym->st_other & ST_PE_STDCALL)
+            printf("stdcall: %s\n", name);
+#endif
+    }
+
+    if (0 == sym_count)
+        return;
+
+    qsort (sorted, sym_count, sizeof *sorted, sym_cmp);
+
+    pe_align_section(pe->thunk, 16);
+    dllname = tcc_basename(pe->filename);
+
+    pe->exp_offs = pe->thunk->data_offset;
+    func_o = pe->exp_offs + sizeof(IMAGE_EXPORT_DIRECTORY);
+    name_o = func_o + sym_count * sizeof (DWORD);
+    ord_o = name_o + sym_count * sizeof (DWORD);
+    str_o = ord_o + sym_count * sizeof(WORD);
+
+    hdr = section_ptr_add(pe->thunk, str_o - pe->exp_offs);
+    hdr->Characteristics        = 0;
+    hdr->Base                   = 1;
+    hdr->NumberOfFunctions      = sym_count;
+    hdr->NumberOfNames          = sym_count;
+    hdr->AddressOfFunctions     = func_o + rva_base;
+    hdr->AddressOfNames         = name_o + rva_base;
+    hdr->AddressOfNameOrdinals  = ord_o + rva_base;
+    hdr->Name                   = str_o + rva_base;
+    put_elf_str(pe->thunk, dllname);
+
+#if 1
+    /* automatically write exports to <output-filename>.def */
+    pstrcpy(buf, sizeof buf, pe->filename);
+    strcpy(tcc_fileextension(buf), ".def");
+    op = fopen(buf, "wb");
+    if (NULL == op) {
+        tcc_error_noabort("could not create '%s': %s", buf, strerror(errno));
+    } else {
+        fprintf(op, "LIBRARY %s\n\nEXPORTS\n", dllname);
+        if (pe->s1->verbose)
+            printf("<- %s (%d symbol%s)\n", buf, sym_count, &"s"[sym_count < 2]);
+    }
+#endif
+
+    for (ord = 0; ord < sym_count; ++ord)
+    {
+        p = sorted[ord], sym_index = p->index, name = p->name;
+        /* insert actual address later in relocate_section() */
+        put_elf_reloc(symtab_section, pe->thunk,
+            func_o, R_XXX_RELATIVE, sym_index);
+        *(DWORD*)(pe->thunk->data + name_o)
+            = pe->thunk->data_offset + rva_base;
+        *(WORD*)(pe->thunk->data + ord_o)
+            = ord;
+        put_elf_str(pe->thunk, name);
+        func_o += sizeof (DWORD);
+        name_o += sizeof (DWORD);
+        ord_o += sizeof (WORD);
+        if (op)
+            fprintf(op, "%s\n", name);
+    }
+    pe->exp_size = pe->thunk->data_offset - pe->exp_offs;
+    dynarray_reset(&sorted, &sym_count);
+    if (op)
+        fclose(op);
+}
+
+/* ------------------------------------------------------------- */
+static void pe_build_reloc (struct pe_info *pe)
+{
+    DWORD offset, block_ptr, addr;
+    int count, i;
+    ElfW_Rel *rel, *rel_end;
+    Section *s = NULL, *sr;
+
+    offset = addr = block_ptr = count = i = 0;
+    rel = rel_end = NULL;
+
+    for(;;) {
+        if (rel < rel_end) {
+            int type = ELFW(R_TYPE)(rel->r_info);
+            addr = rel->r_offset + s->sh_addr;
+            ++ rel;
+            if (type != REL_TYPE_DIRECT)
+                continue;
+            if (count == 0) { /* new block */
+                block_ptr = pe->reloc->data_offset;
+                section_ptr_add(pe->reloc, sizeof(struct pe_reloc_header));
+                offset = addr & 0xFFFFFFFF<<12;
+            }
+            if ((addr -= offset)  < (1<<12)) { /* one block spans 4k addresses */
+                WORD *wp = section_ptr_add(pe->reloc, sizeof (WORD));
+                *wp = addr | PE_IMAGE_REL<<12;
+                ++count;
+                continue;
+            }
+            -- rel;
+
+        } else if (i < pe->sec_count) {
+            sr = (s = pe->s1->sections[pe->sec_info[i++].ord])->reloc;
+            if (sr) {
+                rel = (ElfW_Rel *)sr->data;
+                rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
+            }
+            continue;
+        }
+
+        if (count) {
+            /* store the last block and ready for a new one */
+            struct pe_reloc_header *hdr;
+            if (count & 1) /* align for DWORDS */
+                section_ptr_add(pe->reloc, sizeof(WORD)), ++count;
+            hdr = (struct pe_reloc_header *)(pe->reloc->data + block_ptr);
+            hdr -> offset = offset - pe->imagebase;
+            hdr -> size = count * sizeof(WORD) + sizeof(struct pe_reloc_header);
+            count = 0;
+        }
+
+        if (rel >= rel_end)
+            break;
+    }
+}
+
+/* ------------------------------------------------------------- */
+static int pe_section_class(Section *s)
+{
+    int type, flags;
+    const char *name;
+
+    type = s->sh_type;
+    flags = s->sh_flags;
+    name = s->name;
+    if (flags & SHF_ALLOC) {
+        if (type == SHT_PROGBITS) {
+            if (flags & SHF_EXECINSTR)
+                return sec_text;
+            if (flags & SHF_WRITE)
+                return sec_data;
+            if (0 == strcmp(name, ".rsrc"))
+                return sec_rsrc;
+            if (0 == strcmp(name, ".iedat"))
+                return sec_idata;
+            if (0 == strcmp(name, ".pdata"))
+                return sec_pdata;
+            return sec_other;
+        } else if (type == SHT_NOBITS) {
+            if (flags & SHF_WRITE)
+                return sec_bss;
+        }
+    } else {
+        if (0 == strcmp(name, ".reloc"))
+            return sec_reloc;
+        if (0 == strncmp(name, ".stab", 5)) /* .stab and .stabstr */
+            return sec_stab;
+    }
+    return -1;
+}
+
+static int pe_assign_addresses (struct pe_info *pe)
+{
+    int i, k, o, c;
+    DWORD addr;
+    int *section_order;
+    struct section_info *si;
+    Section *s;
+
+    if (PE_DLL == pe->type)
+        pe->reloc = new_section(pe->s1, ".reloc", SHT_PROGBITS, 0);
+
+    // pe->thunk = new_section(pe->s1, ".iedat", SHT_PROGBITS, SHF_ALLOC);
+
+    section_order = tcc_malloc(pe->s1->nb_sections * sizeof (int));
+    for (o = k = 0 ; k < sec_last; ++k) {
+        for (i = 1; i < pe->s1->nb_sections; ++i) {
+            s = pe->s1->sections[i];
+            if (k == pe_section_class(s)) {
+                // printf("%s %d\n", s->name, k);
+                s->sh_addr = pe->imagebase;
+                section_order[o++] = i;
+            }
+        }
+    }
+
+    pe->sec_info = tcc_mallocz(o * sizeof (struct section_info));
+    addr = pe->imagebase + 1;
+
+    for (i = 0; i < o; ++i)
+    {
+        k = section_order[i];
+        s = pe->s1->sections[k];
+        c = pe_section_class(s);
+        si = &pe->sec_info[pe->sec_count];
+
+#ifdef PE_MERGE_DATA
+        if (c == sec_bss && pe->sec_count && si[-1].cls == sec_data) {
+            /* append .bss to .data */
+            s->sh_addr = addr = ((addr-1) | (s->sh_addralign-1)) + 1;
+            addr += s->data_offset;
+            si[-1].sh_size = addr - si[-1].sh_addr;
+            continue;
+        }
+#endif
+        if (c == sec_stab && 0 == pe->s1->do_debug)
+            continue;
+
+        strcpy(si->name, s->name);
+        si->cls = c;
+        si->ord = k;
+        si->sh_addr = s->sh_addr = addr = pe_virtual_align(pe, addr);
+        si->sh_flags = s->sh_flags;
+
+        if (c == sec_data && NULL == pe->thunk)
+            pe->thunk = s;
+
+        if (s == pe->thunk) {
+            pe_build_imports(pe);
+            pe_build_exports(pe);
+        }
+
+        if (c == sec_reloc)
+            pe_build_reloc (pe);
+
+        if (s->data_offset)
+        {
+            if (s->sh_type != SHT_NOBITS) {
+                si->data = s->data;
+                si->data_size = s->data_offset;
+            }
+
+            addr += s->data_offset;
+            si->sh_size = s->data_offset;
+            ++pe->sec_count;
+        }
+        // printf("%08x %05x %s\n", si->sh_addr, si->sh_size, si->name);
+    }
+
+#if 0
+    for (i = 1; i < pe->s1->nb_sections; ++i) {
+        Section *s = pe->s1->sections[i];
+        int type = s->sh_type;
+        int flags = s->sh_flags;
+        printf("section %-16s %-10s %5x %s,%s,%s\n",
+            s->name,
+            type == SHT_PROGBITS ? "progbits" :
+            type == SHT_NOBITS ? "nobits" :
+            type == SHT_SYMTAB ? "symtab" :
+            type == SHT_STRTAB ? "strtab" :
+            type == SHT_RELX ? "rel" : "???",
+            s->data_offset,
+            flags & SHF_ALLOC ? "alloc" : "",
+            flags & SHF_WRITE ? "write" : "",
+            flags & SHF_EXECINSTR ? "exec" : ""
+            );
+    }
+    pe->s1->verbose = 2;
+#endif
+
+    tcc_free(section_order);
+    return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+
+static int pe_isafunc(int sym_index)
+{
+    Section *sr = text_section->reloc;
+    ElfW_Rel *rel, *rel_end;
+    Elf32_Word info = ELF32_R_INFO(sym_index, R_386_PC32);
+    if (!sr)
+        return 0;
+    rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
+    for (rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++)
+        if (rel->r_info == info)
+            return 1;
+    return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+static int pe_check_symbols(struct pe_info *pe)
+{
+    ElfW(Sym) *sym;
+    int sym_index, sym_end;
+    int ret = 0;
+
+    pe_align_section(text_section, 8);
+
+    sym_end = symtab_section->data_offset / sizeof(ElfW(Sym));
+    for (sym_index = 1; sym_index < sym_end; ++sym_index) {
+
+        sym = (ElfW(Sym) *)symtab_section->data + sym_index;
+        if (sym->st_shndx == SHN_UNDEF) {
+
+            const char *name = (char*)symtab_section->link->data + sym->st_name;
+            unsigned type = ELFW(ST_TYPE)(sym->st_info);
+            int imp_sym = pe_find_import(pe->s1, sym);
+            struct import_symbol *is;
+
+            if (imp_sym <= 0)
+                goto not_found;
+
+            if (type == STT_NOTYPE) {
+                /* symbols from assembler have no type, find out which */
+                if (pe_isafunc(sym_index))
+                    type = STT_FUNC;
+                else
+                    type = STT_OBJECT;
+            }
+
+            is = pe_add_import(pe, imp_sym);
+
+            if (type == STT_FUNC) {
+                unsigned long offset = is->thk_offset;
+                if (offset) {
+                    /* got aliased symbol, like stricmp and _stricmp */
+
+                } else {
+                    char buffer[100];
+                    WORD *p;
+
+                    offset = text_section->data_offset;
+                    /* add the 'jmp IAT[x]' instruction */
+#ifdef TCC_TARGET_ARM
+                    p = section_ptr_add(text_section, 8+4); // room for code and address
+                    (*(DWORD*)(p)) = 0xE59FC000; // arm code ldr ip, [pc] ; PC+8+0 = 0001xxxx
+                    (*(DWORD*)(p+2)) = 0xE59CF000; // arm code ldr pc, [ip]
+#else
+                    p = section_ptr_add(text_section, 8);
+                    *p = 0x25FF;
+#ifdef TCC_TARGET_X86_64
+                    *(DWORD*)(p+1) = (DWORD)-4;
+#endif
+#endif
+                    /* add a helper symbol, will be patched later in
+                       pe_build_imports */
+                    sprintf(buffer, "IAT.%s", name);
+                    is->iat_index = put_elf_sym(
+                        symtab_section, 0, sizeof(DWORD),
+                        ELFW(ST_INFO)(STB_GLOBAL, STT_OBJECT),
+                        0, SHN_UNDEF, buffer);
+#ifdef TCC_TARGET_ARM
+                    put_elf_reloc(symtab_section, text_section,
+                        offset + 8, R_XXX_THUNKFIX, is->iat_index); // offset to IAT position
+#else
+                    put_elf_reloc(symtab_section, text_section, 
+                        offset + 2, R_XXX_THUNKFIX, is->iat_index);
+#endif
+                    is->thk_offset = offset;
+                }
+
+                /* tcc_realloc might have altered sym's address */
+                sym = (ElfW(Sym) *)symtab_section->data + sym_index;
+
+                /* patch the original symbol */
+                sym->st_value = offset;
+                sym->st_shndx = text_section->sh_num;
+                sym->st_other &= ~ST_PE_EXPORT; /* do not export */
+                continue;
+            }
+
+            if (type == STT_OBJECT) { /* data, ptr to that should be */
+                if (0 == is->iat_index) {
+                    /* original symbol will be patched later in pe_build_imports */
+                    is->iat_index = sym_index;
+                    continue;
+                }
+            }
+
+        not_found:
+            if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
+                /* STB_WEAK undefined symbols are accepted */
+                continue;
+            tcc_error_noabort("undefined symbol '%s'%s", name,
+                imp_sym < 0 ? ", missing __declspec(dllimport)?":"");
+            ret = -1;
+
+        } else if (pe->s1->rdynamic
+                   && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
+            /* if -rdynamic option, then export all non local symbols */
+            sym->st_other |= ST_PE_EXPORT;
+        }
+    }
+    return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+#ifdef PE_PRINT_SECTIONS
+static void pe_print_section(FILE * f, Section * s)
+{
+    /* just if you're curious */
+    BYTE *p, *e, b;
+    int i, n, l, m;
+    p = s->data;
+    e = s->data + s->data_offset;
+    l = e - p;
+
+    fprintf(f, "section  \"%s\"", s->name);
+    if (s->link)
+        fprintf(f, "\nlink     \"%s\"", s->link->name);
+    if (s->reloc)
+        fprintf(f, "\nreloc    \"%s\"", s->reloc->name);
+    fprintf(f, "\nv_addr   %08X", (unsigned)s->sh_addr);
+    fprintf(f, "\ncontents %08X", (unsigned)l);
+    fprintf(f, "\n\n");
+
+    if (s->sh_type == SHT_NOBITS)
+        return;
+
+    if (0 == l)
+        return;
+
+    if (s->sh_type == SHT_SYMTAB)
+        m = sizeof(ElfW(Sym));
+    else if (s->sh_type == SHT_RELX)
+        m = sizeof(ElfW_Rel);
+    else
+        m = 16;
+
+    fprintf(f, "%-8s", "offset");
+    for (i = 0; i < m; ++i)
+        fprintf(f, " %02x", i);
+    n = 56;
+
+    if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_RELX) {
+        const char *fields1[] = {
+            "name",
+            "value",
+            "size",
+            "bind",
+            "type",
+            "other",
+            "shndx",
+            NULL
+        };
+
+        const char *fields2[] = {
+            "offs",
+            "type",
+            "symb",
+            NULL
+        };
+
+        const char **p;
+
+        if (s->sh_type == SHT_SYMTAB)
+            p = fields1, n = 106;
+        else
+            p = fields2, n = 58;
+
+        for (i = 0; p[i]; ++i)
+            fprintf(f, "%6s", p[i]);
+        fprintf(f, "  symbol");
+    }
+
+    fprintf(f, "\n");
+    for (i = 0; i < n; ++i)
+        fprintf(f, "-");
+    fprintf(f, "\n");
+
+    for (i = 0; i < l;)
+    {
+        fprintf(f, "%08X", i);
+        for (n = 0; n < m; ++n) {
+            if (n + i < l)
+                fprintf(f, " %02X", p[i + n]);
+            else
+                fprintf(f, "   ");
+        }
+
+        if (s->sh_type == SHT_SYMTAB) {
+            ElfW(Sym) *sym = (ElfW(Sym) *) (p + i);
+            const char *name = s->link->data + sym->st_name;
+            fprintf(f, "  %04X  %04X  %04X   %02X    %02X    %02X   %04X  \"%s\"",
+                    (unsigned)sym->st_name,
+                    (unsigned)sym->st_value,
+                    (unsigned)sym->st_size,
+                    (unsigned)ELFW(ST_BIND)(sym->st_info),
+                    (unsigned)ELFW(ST_TYPE)(sym->st_info),
+                    (unsigned)sym->st_other,
+                    (unsigned)sym->st_shndx,
+                    name);
+
+        } else if (s->sh_type == SHT_RELX) {
+            ElfW_Rel *rel = (ElfW_Rel *) (p + i);
+            ElfW(Sym) *sym =
+                (ElfW(Sym) *) s->link->data + ELFW(R_SYM)(rel->r_info);
+            const char *name = s->link->link->data + sym->st_name;
+            fprintf(f, "  %04X   %02X   %04X  \"%s\"",
+                    (unsigned)rel->r_offset,
+                    (unsigned)ELFW(R_TYPE)(rel->r_info),
+                    (unsigned)ELFW(R_SYM)(rel->r_info),
+                    name);
+        } else {
+            fprintf(f, "   ");
+            for (n = 0; n < m; ++n) {
+                if (n + i < l) {
+                    b = p[i + n];
+                    if (b < 32 || b >= 127)
+                        b = '.';
+                    fprintf(f, "%c", b);
+                }
+            }
+        }
+        i += m;
+        fprintf(f, "\n");
+    }
+    fprintf(f, "\n\n");
+}
+
+static void pe_print_sections(TCCState *s1, const char *fname)
+{
+    Section *s;
+    FILE *f;
+    int i;
+    f = fopen(fname, "w");
+    for (i = 1; i < s1->nb_sections; ++i) {
+        s = s1->sections[i];
+        pe_print_section(f, s);
+    }
+    pe_print_section(f, s1->dynsymtab_section);
+    fclose(f);
+}
+#endif
+
+/* ------------------------------------------------------------- */
+/* helper function for load/store to insert one more indirection */
+
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2)
+{
+    int r2;
+    if ((sv->r & (VT_VALMASK|VT_SYM)) != (VT_CONST|VT_SYM) || (sv->r2 != VT_CONST))
+        return sv;
+    if (!sv->sym->a.dllimport)
+        return sv;
+    // printf("import %04x %04x %04x %s\n", sv->type.t, sv->sym->type.t, sv->r, get_tok_str(sv->sym->v, NULL));
+    memset(v2, 0, sizeof *v2);
+    v2->type.t = VT_PTR;
+    v2->r = VT_CONST | VT_SYM | VT_LVAL;
+    v2->sym = sv->sym;
+
+    r2 = get_reg(RC_INT);
+    load(r2, v2);
+    v2->r = r2;
+    if ((uint32_t)sv->c.i) {
+        vpushv(v2);
+        vpushi(sv->c.i);
+        gen_opi('+');
+        *v2 = *vtop--;
+    }
+    v2->type.t = sv->type.t;
+    v2->r |= sv->r & VT_LVAL;
+    return v2;
+}
+#endif
+
+ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value)
+{
+    return set_elf_sym(
+        s1->dynsymtab_section,
+        value,
+        dllindex, /* st_size */
+        ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE),
+        0,
+        value ? SHN_ABS : SHN_UNDEF,
+        name
+        );
+}
+
+static int add_dllref(TCCState *s1, const char *dllname)
+{
+    DLLReference *dllref;
+    int i;
+    for (i = 0; i < s1->nb_loaded_dlls; ++i)
+        if (0 == strcmp(s1->loaded_dlls[i]->name, dllname))
+            return i + 1;
+    dllref = tcc_mallocz(sizeof(DLLReference) + strlen(dllname));
+    strcpy(dllref->name, dllname);
+    dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
+    return s1->nb_loaded_dlls;
+}
+
+/* ------------------------------------------------------------- */
+
+static int read_mem(int fd, unsigned offset, void *buffer, unsigned len)
+{
+    lseek(fd, offset, SEEK_SET);
+    return len == read(fd, buffer, len);
+}
+
+/* ------------------------------------------------------------- */
+
+PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp)
+{
+    int l, i, n, n0, ret;
+    char *p;
+    int fd;
+
+    IMAGE_SECTION_HEADER ish;
+    IMAGE_EXPORT_DIRECTORY ied;
+    IMAGE_DOS_HEADER dh;
+    IMAGE_FILE_HEADER ih;
+    DWORD sig, ref, addr, ptr, namep;
+
+    int pef_hdroffset, opt_hdroffset, sec_hdroffset;
+
+    n = n0 = 0;
+    p = NULL;
+    ret = -1;
+
+    fd = open(filename, O_RDONLY | O_BINARY);
+    if (fd < 0)
+        goto the_end_1;
+    ret = 1;
+    if (!read_mem(fd, 0, &dh, sizeof dh))
+        goto the_end;
+    if (!read_mem(fd, dh.e_lfanew, &sig, sizeof sig))
+        goto the_end;
+    if (sig != 0x00004550)
+        goto the_end;
+    pef_hdroffset = dh.e_lfanew + sizeof sig;
+    if (!read_mem(fd, pef_hdroffset, &ih, sizeof ih))
+        goto the_end;
+    opt_hdroffset = pef_hdroffset + sizeof ih;
+    if (ih.Machine == 0x014C) {
+        IMAGE_OPTIONAL_HEADER32 oh;
+        sec_hdroffset = opt_hdroffset + sizeof oh;
+        if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
+            goto the_end;
+        if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
+            goto the_end_0;
+        addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
+    } else if (ih.Machine == 0x8664) {
+        IMAGE_OPTIONAL_HEADER64 oh;
+        sec_hdroffset = opt_hdroffset + sizeof oh;
+        if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
+            goto the_end;
+        if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
+            goto the_end_0;
+        addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
+    } else
+        goto the_end;
+
+    //printf("addr: %08x\n", addr);
+    for (i = 0; i < ih.NumberOfSections; ++i) {
+        if (!read_mem(fd, sec_hdroffset + i * sizeof ish, &ish, sizeof ish))
+            goto the_end;
+        //printf("vaddr: %08x\n", ish.VirtualAddress);
+        if (addr >= ish.VirtualAddress && addr < ish.VirtualAddress + ish.SizeOfRawData)
+            goto found;
+    }
+    goto the_end_0;
+
+found:
+    ref = ish.VirtualAddress - ish.PointerToRawData;
+    if (!read_mem(fd, addr - ref, &ied, sizeof ied))
+        goto the_end;
+
+    namep = ied.AddressOfNames - ref;
+    for (i = 0; i < ied.NumberOfNames; ++i) {
+        if (!read_mem(fd, namep, &ptr, sizeof ptr))
+            goto the_end;
+        namep += sizeof ptr;
+        for (l = 0;;) {
+            if (n+1 >= n0)
+                p = tcc_realloc(p, n0 = n0 ? n0 * 2 : 256);
+            if (!read_mem(fd, ptr - ref + l++, p + n, 1)) {
+                tcc_free(p), p = NULL;
+                goto the_end;
+            }
+            if (p[n++] == 0)
+                break;
+        }
+    }
+    if (p)
+        p[n] = 0;
+the_end_0:
+    ret = 0;
+the_end:
+    close(fd);
+the_end_1:
+    *pp = p;
+    return ret;
+}
+
+/* -------------------------------------------------------------
+ *  This is for compiled windows resources in 'coff' format
+ *  as generated by 'windres.exe -O coff ...'.
+ */
+
+static int pe_load_res(TCCState *s1, int fd)
+{
+    struct pe_rsrc_header hdr;
+    Section *rsrc_section;
+    int i, ret = -1, sym_index;
+    BYTE *ptr;
+    unsigned offs;
+
+    if (!read_mem(fd, 0, &hdr, sizeof hdr))
+        goto quit;
+
+    if (hdr.filehdr.Machine != IMAGE_FILE_MACHINE
+        || hdr.filehdr.NumberOfSections != 1
+        || strcmp((char*)hdr.sectionhdr.Name, ".rsrc") != 0)
+        goto quit;
+
+    rsrc_section = new_section(s1, ".rsrc", SHT_PROGBITS, SHF_ALLOC);
+    ptr = section_ptr_add(rsrc_section, hdr.sectionhdr.SizeOfRawData);
+    offs = hdr.sectionhdr.PointerToRawData;
+    if (!read_mem(fd, offs, ptr, hdr.sectionhdr.SizeOfRawData))
+        goto quit;
+    offs = hdr.sectionhdr.PointerToRelocations;
+    sym_index = put_elf_sym(symtab_section, 0, 0, 0, 0, rsrc_section->sh_num, ".rsrc");
+    for (i = 0; i < hdr.sectionhdr.NumberOfRelocations; ++i) {
+        struct pe_rsrc_reloc rel;
+        if (!read_mem(fd, offs, &rel, sizeof rel))
+            goto quit;
+        // printf("rsrc_reloc: %x %x %x\n", rel.offset, rel.size, rel.type);
+        if (rel.type != RSRC_RELTYPE)
+            goto quit;
+        put_elf_reloc(symtab_section, rsrc_section,
+            rel.offset, R_XXX_RELATIVE, sym_index);
+        offs += sizeof rel;
+    }
+    ret = 0;
+quit:
+    return ret;
+}
+
+/* ------------------------------------------------------------- */
+
+static char *trimfront(char *p)
+{
+    while (*p && (unsigned char)*p <= ' ')
+	++p;
+    return p;
+}
+
+static char *trimback(char *a, char *e)
+{
+    while (e > a && (unsigned char)e[-1] <= ' ')
+	--e;
+    *e = 0;;
+    return a;
+}
+
+/* ------------------------------------------------------------- */
+static int pe_load_def(TCCState *s1, int fd)
+{
+    int state = 0, ret = -1, dllindex = 0, ord;
+    char line[400], dllname[80], *p, *x;
+    FILE *fp;
+
+    fp = fdopen(dup(fd), "rb");
+    while (fgets(line, sizeof line, fp))
+    {
+        p = trimfront(trimback(line, strchr(line, 0)));
+        if (0 == *p || ';' == *p)
+            continue;
+
+        switch (state) {
+        case 0:
+            if (0 != strnicmp(p, "LIBRARY", 7))
+                goto quit;
+            pstrcpy(dllname, sizeof dllname, trimfront(p+7));
+            ++state;
+            continue;
+
+        case 1:
+            if (0 != stricmp(p, "EXPORTS"))
+                goto quit;
+            ++state;
+            continue;
+
+        case 2:
+            dllindex = add_dllref(s1, dllname);
+            ++state;
+            /* fall through */
+        default:
+            /* get ordinal and will store in sym->st_value */
+            ord = 0;
+            x = strchr(p, ' ');
+            if (x) {
+                *x = 0, x = strrchr(x + 1, '@');
+                if (x) {
+                    char *d;
+                    ord = (int)strtol(x + 1, &d, 10);
+                    if (*d)
+                        ord = 0;
+                }
+            }
+            pe_putimport(s1, dllindex, p, ord);
+            continue;
+        }
+    }
+    ret = 0;
+quit:
+    fclose(fp);
+    return ret;
+}
+
+/* ------------------------------------------------------------- */
+static int pe_load_dll(TCCState *s1, const char *filename)
+{
+    char *p, *q;
+    int index, ret;
+
+    ret = tcc_get_dllexports(filename, &p);
+    if (ret) {
+        return -1;
+    } else if (p) {
+        index = add_dllref(s1, tcc_basename(filename));
+        for (q = p; *q; q += 1 + strlen(q))
+            pe_putimport(s1, index, q, 0);
+        tcc_free(p);
+    }
+    return 0;
+}
+
+/* ------------------------------------------------------------- */
+ST_FUNC int pe_load_file(struct TCCState *s1, const char *filename, int fd)
+{
+    int ret = -1;
+    char buf[10];
+    if (0 == strcmp(tcc_fileextension(filename), ".def"))
+        ret = pe_load_def(s1, fd);
+    else if (pe_load_res(s1, fd) == 0)
+        ret = 0;
+    else if (read_mem(fd, 0, buf, 4) && 0 == memcmp(buf, "MZ\220", 4))
+        ret = pe_load_dll(s1, filename);
+    return ret;
+}
+
+/* ------------------------------------------------------------- */
+#ifdef TCC_TARGET_X86_64
+static unsigned pe_add_uwwind_info(TCCState *s1)
+{
+    if (NULL == s1->uw_pdata) {
+        s1->uw_pdata = find_section(tcc_state, ".pdata");
+        s1->uw_pdata->sh_addralign = 4;
+    }
+    if (0 == s1->uw_sym)
+        s1->uw_sym = put_elf_sym(symtab_section, 0, 0, 0, 0, text_section->sh_num, ".uw_base");
+    if (0 == s1->uw_offs) {
+        /* As our functions all have the same stackframe, we use one entry for all */
+        static const unsigned char uw_info[] = {
+            0x01, // UBYTE: 3 Version , UBYTE: 5 Flags
+            0x04, // UBYTE Size of prolog
+            0x02, // UBYTE Count of unwind codes
+            0x05, // UBYTE: 4 Frame Register (rbp), UBYTE: 4 Frame Register offset (scaled)
+            // USHORT * n Unwind codes array
+            // 0x0b, 0x01, 0xff, 0xff, // stack size
+            0x04, 0x03, // set frame ptr (mov rsp -> rbp)
+            0x01, 0x50  // push reg (rbp)
+        };
+
+        Section *s = text_section;
+        unsigned char *p;
+
+        section_ptr_add(s, -s->data_offset & 3); /* align */
+        s1->uw_offs = s->data_offset;
+        p = section_ptr_add(s, sizeof uw_info);
+        memcpy(p, uw_info, sizeof uw_info);
+    }
+
+    return s1->uw_offs;
+}
+
+ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack)
+{
+    TCCState *s1 = tcc_state;
+    Section *pd;
+    unsigned o, n, d;
+    struct /* _RUNTIME_FUNCTION */ {
+      DWORD BeginAddress;
+      DWORD EndAddress;
+      DWORD UnwindData;
+    } *p;
+
+    d = pe_add_uwwind_info(s1);
+    pd = s1->uw_pdata;
+    o = pd->data_offset;
+    p = section_ptr_add(pd, sizeof *p);
+
+    /* record this function */
+    p->BeginAddress = start;
+    p->EndAddress = end;
+    p->UnwindData = d;
+
+    /* put relocations on it */
+    for (n = o + sizeof *p; o < n; o += sizeof p->BeginAddress)
+        put_elf_reloc(symtab_section, pd, o, R_XXX_RELATIVE, s1->uw_sym);
+}
+#endif
+/* ------------------------------------------------------------- */
+#ifdef TCC_TARGET_X86_64
+#define PE_STDSYM(n,s) n
+#else
+#define PE_STDSYM(n,s) "_" n s
+#endif
+
+static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
+{
+    const char *start_symbol;
+    int pe_type = 0;
+    int unicode_entry = 0;
+
+    if (find_elf_sym(symtab_section, PE_STDSYM("WinMain","@16")))
+        pe_type = PE_GUI;
+    else
+    if (find_elf_sym(symtab_section, PE_STDSYM("wWinMain","@16"))) {
+        pe_type = PE_GUI;
+        unicode_entry = PE_GUI;
+    }
+    else
+    if (TCC_OUTPUT_DLL == s1->output_type) {
+        pe_type = PE_DLL;
+        /* need this for 'tccelf.c:relocate_section()' */
+        s1->output_type = TCC_OUTPUT_EXE;
+    }
+    else {
+        pe_type = PE_EXE;
+        if (find_elf_sym(symtab_section, "wmain"))
+            unicode_entry = PE_EXE;
+    }
+
+    start_symbol =
+        TCC_OUTPUT_MEMORY == s1->output_type
+        ? PE_GUI == pe_type ? (unicode_entry ? "__runwwinmain" : "__runwinmain")
+            : (unicode_entry ? "__runwmain" : "__runmain")
+        : PE_DLL == pe_type ? PE_STDSYM("__dllstart","@12")
+            : PE_GUI == pe_type ? (unicode_entry ? "__wwinstart": "__winstart")
+                : (unicode_entry ? "__wstart" : "__start")
+        ;
+
+    if (!s1->leading_underscore || strchr(start_symbol, '@'))
+        ++start_symbol;
+
+    /* grab the startup code from libtcc1 */
+#ifdef TCC_IS_NATIVE
+    if (TCC_OUTPUT_MEMORY != s1->output_type || s1->runtime_main)
+#endif
+    set_elf_sym(symtab_section,
+        0, 0,
+        ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
+        SHN_UNDEF, start_symbol);
+
+    tcc_add_pragma_libs(s1);
+
+    if (0 == s1->nostdlib) {
+        static const char *libs[] = {
+            TCC_LIBTCC1, "msvcrt", "kernel32", "", "user32", "gdi32", NULL
+        };
+        const char **pp, *p;
+        for (pp = libs; 0 != (p = *pp); ++pp) {
+            if (0 == *p) {
+                if (PE_DLL != pe_type && PE_GUI != pe_type)
+                    break;
+            } else if (pp == libs && tcc_add_dll(s1, p, 0) >= 0) {
+                continue;
+            } else {
+                tcc_add_library_err(s1, p);
+            }
+        }
+    }
+
+    if (TCC_OUTPUT_MEMORY == s1->output_type)
+        pe_type = PE_RUN;
+    pe->type = pe_type;
+    pe->start_symbol = start_symbol;
+}
+
+static void pe_set_options(TCCState * s1, struct pe_info *pe)
+{
+    if (PE_DLL == pe->type) {
+        /* XXX: check if is correct for arm-pe target */
+        pe->imagebase = 0x10000000;
+    } else {
+#if defined(TCC_TARGET_ARM)
+        pe->imagebase = 0x00010000;
+#else
+        pe->imagebase = 0x00400000;
+#endif
+    }
+
+#if defined(TCC_TARGET_ARM)
+    /* we use "console" subsystem by default */
+    pe->subsystem = 9;
+#else
+    if (PE_DLL == pe->type || PE_GUI == pe->type)
+        pe->subsystem = 2;
+    else
+        pe->subsystem = 3;
+#endif
+    /* Allow override via -Wl,-subsystem=... option */
+    if (s1->pe_subsystem != 0)
+        pe->subsystem = s1->pe_subsystem;
+
+    /* set default file/section alignment */
+    if (pe->subsystem == 1) {
+        pe->section_align = 0x20;
+        pe->file_align = 0x20;
+    } else {
+        pe->section_align = 0x1000;
+        pe->file_align = 0x200;
+    }
+
+    if (s1->section_align != 0)
+        pe->section_align = s1->section_align;
+    if (s1->pe_file_align != 0)
+        pe->file_align = s1->pe_file_align;
+
+    if ((pe->subsystem >= 10) && (pe->subsystem <= 12))
+        pe->imagebase = 0;
+
+    if (s1->has_text_addr)
+        pe->imagebase = s1->text_addr;
+}
+
+ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
+{
+    int ret;
+    struct pe_info pe;
+    int i;
+
+    memset(&pe, 0, sizeof pe);
+    pe.filename = filename;
+    pe.s1 = s1;
+
+    tcc_add_bcheck(s1);
+    pe_add_runtime(s1, &pe);
+    resolve_common_syms(s1);
+    pe_set_options(s1, &pe);
+
+    ret = pe_check_symbols(&pe);
+    if (ret)
+        ;
+    else if (filename) {
+        pe_assign_addresses(&pe);
+        relocate_syms(s1, s1->symtab, 0);
+        s1->pe_imagebase = pe.imagebase;
+        for (i = 1; i < s1->nb_sections; ++i) {
+            Section *s = s1->sections[i];
+            if (s->reloc) {
+                relocate_section(s1, s);
+            }
+        }
+        pe.start_addr = (DWORD)
+            ((uintptr_t)tcc_get_symbol_err(s1, pe.start_symbol)
+                - pe.imagebase);
+        if (s1->nb_errors)
+            ret = -1;
+        else
+            ret = pe_write(&pe);
+        tcc_free(pe.sec_info);
+    } else {
+#ifdef TCC_IS_NATIVE
+        pe.thunk = data_section;
+        pe_build_imports(&pe);
+        s1->runtime_main = pe.start_symbol;
+#ifdef TCC_TARGET_X86_64
+        s1->uw_pdata = find_section(s1, ".pdata");
+#endif
+#endif
+    }
+
+    pe_free_imports(&pe);
+
+#ifdef PE_PRINT_SECTIONS
+    pe_print_sections(s1, "tcc.log");
+#endif
+    return ret;
+}
+
+/* ------------------------------------------------------------- */
Index: EcnlProtoTool/trunk/tcc-0.9.27/tccpp.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tccpp.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tccpp.c	(revision 331)
@@ -0,0 +1,3903 @@
+/*
+ *  TCC - Tiny C Compiler
+ * 
+ *  Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "tcc.h"
+
+/********************************************************/
+/* global variables */
+
+ST_DATA int tok_flags;
+ST_DATA int parse_flags;
+
+ST_DATA struct BufferedFile *file;
+ST_DATA int ch, tok;
+ST_DATA CValue tokc;
+ST_DATA const int *macro_ptr;
+ST_DATA CString tokcstr; /* current parsed string, if any */
+
+/* display benchmark infos */
+ST_DATA int total_lines;
+ST_DATA int total_bytes;
+ST_DATA int tok_ident;
+ST_DATA TokenSym **table_ident;
+
+/* ------------------------------------------------------------------------- */
+
+static TokenSym *hash_ident[TOK_HASH_SIZE];
+static char token_buf[STRING_MAX_SIZE + 1];
+static CString cstr_buf;
+static CString macro_equal_buf;
+static TokenString tokstr_buf;
+static unsigned char isidnum_table[256 - CH_EOF];
+static int pp_debug_tok, pp_debug_symv;
+static int pp_once;
+static int pp_expr;
+static int pp_counter;
+static void tok_print(const char *msg, const int *str);
+
+static struct TinyAlloc *toksym_alloc;
+static struct TinyAlloc *tokstr_alloc;
+static struct TinyAlloc *cstr_alloc;
+
+static TokenString *macro_stack;
+
+static const char tcc_keywords[] = 
+#define DEF(id, str) str "\0"
+#include "tcctok.h"
+#undef DEF
+;
+
+/* WARNING: the content of this string encodes token numbers */
+static const unsigned char tok_two_chars[] =
+/* outdated -- gr
+    "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253"
+    "-=\255*=\252/=\257%=\245&=\246^=\336|=\374->\313..\250##\266";
+*/{
+    '<','=', TOK_LE,
+    '>','=', TOK_GE,
+    '!','=', TOK_NE,
+    '&','&', TOK_LAND,
+    '|','|', TOK_LOR,
+    '+','+', TOK_INC,
+    '-','-', TOK_DEC,
+    '=','=', TOK_EQ,
+    '<','<', TOK_SHL,
+    '>','>', TOK_SAR,
+    '+','=', TOK_A_ADD,
+    '-','=', TOK_A_SUB,
+    '*','=', TOK_A_MUL,
+    '/','=', TOK_A_DIV,
+    '%','=', TOK_A_MOD,
+    '&','=', TOK_A_AND,
+    '^','=', TOK_A_XOR,
+    '|','=', TOK_A_OR,
+    '-','>', TOK_ARROW,
+    '.','.', TOK_TWODOTS,
+    '#','#', TOK_TWOSHARPS,
+    0
+};
+
+static void next_nomacro_spc(void);
+
+ST_FUNC void skip(int c)
+{
+    if (tok != c)
+        tcc_error("'%c' expected (got \"%s\")", c, get_tok_str(tok, &tokc));
+    next();
+}
+
+ST_FUNC void expect(const char *msg)
+{
+    tcc_error("%s expected", msg);
+}
+
+/* ------------------------------------------------------------------------- */
+/* Custom allocator for tiny objects */
+
+//#define USE_TAL
+
+#ifndef USE_TAL
+#define tal_free(al, p) tcc_free(p)
+#define tal_realloc(al, p, size) tcc_realloc(p, size)
+#define tal_new(a,b,c)
+#define tal_delete(a)
+#else
+#if !defined(MEM_DEBUG)
+#define tal_free(al, p) tal_free_impl(al, p)
+#define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size)
+#define TAL_DEBUG_PARAMS
+#else
+#define TAL_DEBUG 1
+//#define TAL_INFO 1 /* collect and dump allocators stats */
+#define tal_free(al, p) tal_free_impl(al, p, __FILE__, __LINE__)
+#define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size, __FILE__, __LINE__)
+#define TAL_DEBUG_PARAMS , const char *file, int line
+#define TAL_DEBUG_FILE_LEN 40
+#endif
+
+#define TOKSYM_TAL_SIZE     (768 * 1024) /* allocator for tiny TokenSym in table_ident */
+#define TOKSTR_TAL_SIZE     (768 * 1024) /* allocator for tiny TokenString instances */
+#define CSTR_TAL_SIZE       (256 * 1024) /* allocator for tiny CString instances */
+#define TOKSYM_TAL_LIMIT    256 /* prefer unique limits to distinguish allocators debug msgs */
+#define TOKSTR_TAL_LIMIT    128 /* 32 * sizeof(int) */
+#define CSTR_TAL_LIMIT      1024
+
+typedef struct TinyAlloc {
+    unsigned  limit;
+    unsigned  size;
+    uint8_t *buffer;
+    uint8_t *p;
+    unsigned  nb_allocs;
+    struct TinyAlloc *next, *top;
+#ifdef TAL_INFO
+    unsigned  nb_peak;
+    unsigned  nb_total;
+    unsigned  nb_missed;
+    uint8_t *peak_p;
+#endif
+} TinyAlloc;
+
+typedef struct tal_header_t {
+    unsigned  size;
+#ifdef TAL_DEBUG
+    int     line_num; /* negative line_num used for double free check */
+    char    file_name[TAL_DEBUG_FILE_LEN + 1];
+#endif
+} tal_header_t;
+
+/* ------------------------------------------------------------------------- */
+
+static TinyAlloc *tal_new(TinyAlloc **pal, unsigned limit, unsigned size)
+{
+    TinyAlloc *al = tcc_mallocz(sizeof(TinyAlloc));
+    al->p = al->buffer = tcc_malloc(size);
+    al->limit = limit;
+    al->size = size;
+    if (pal) *pal = al;
+    return al;
+}
+
+static void tal_delete(TinyAlloc *al)
+{
+    TinyAlloc *next;
+
+tail_call:
+    if (!al)
+        return;
+#ifdef TAL_INFO
+    fprintf(stderr, "limit=%5d, size=%5g MB, nb_peak=%6d, nb_total=%8d, nb_missed=%6d, usage=%5.1f%%\n",
+            al->limit, al->size / 1024.0 / 1024.0, al->nb_peak, al->nb_total, al->nb_missed,
+            (al->peak_p - al->buffer) * 100.0 / al->size);
+#endif
+#ifdef TAL_DEBUG
+    if (al->nb_allocs > 0) {
+        uint8_t *p;
+        fprintf(stderr, "TAL_DEBUG: memory leak %d chunk(s) (limit= %d)\n",
+                al->nb_allocs, al->limit);
+        p = al->buffer;
+        while (p < al->p) {
+            tal_header_t *header = (tal_header_t *)p;
+            if (header->line_num > 0) {
+                fprintf(stderr, "%s:%d: chunk of %d bytes leaked\n",
+                        header->file_name, header->line_num, header->size);
+            }
+            p += header->size + sizeof(tal_header_t);
+        }
+#if MEM_DEBUG-0 == 2
+        exit(2);
+#endif
+    }
+#endif
+    next = al->next;
+    tcc_free(al->buffer);
+    tcc_free(al);
+    al = next;
+    goto tail_call;
+}
+
+static void tal_free_impl(TinyAlloc *al, void *p TAL_DEBUG_PARAMS)
+{
+    if (!p)
+        return;
+tail_call:
+    if (al->buffer <= (uint8_t *)p && (uint8_t *)p < al->buffer + al->size) {
+#ifdef TAL_DEBUG
+        tal_header_t *header = (((tal_header_t *)p) - 1);
+        if (header->line_num < 0) {
+            fprintf(stderr, "%s:%d: TAL_DEBUG: double frees chunk from\n",
+                    file, line);
+            fprintf(stderr, "%s:%d: %d bytes\n",
+                    header->file_name, (int)-header->line_num, (int)header->size);
+        } else
+            header->line_num = -header->line_num;
+#endif
+        al->nb_allocs--;
+        if (!al->nb_allocs)
+            al->p = al->buffer;
+    } else if (al->next) {
+        al = al->next;
+        goto tail_call;
+    }
+    else
+        tcc_free(p);
+}
+
+static void *tal_realloc_impl(TinyAlloc **pal, void *p, unsigned size TAL_DEBUG_PARAMS)
+{
+    tal_header_t *header;
+    void *ret;
+    int is_own;
+    unsigned adj_size = (size + 3) & -4;
+    TinyAlloc *al = *pal;
+
+tail_call:
+    is_own = (al->buffer <= (uint8_t *)p && (uint8_t *)p < al->buffer + al->size);
+    if ((!p || is_own) && size <= al->limit) {
+        if (al->p + adj_size + sizeof(tal_header_t) < al->buffer + al->size) {
+            header = (tal_header_t *)al->p;
+            header->size = adj_size;
+#ifdef TAL_DEBUG
+            { int ofs = strlen(file) - TAL_DEBUG_FILE_LEN;
+            strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), TAL_DEBUG_FILE_LEN);
+            header->file_name[TAL_DEBUG_FILE_LEN] = 0;
+            header->line_num = line; }
+#endif
+            ret = al->p + sizeof(tal_header_t);
+            al->p += adj_size + sizeof(tal_header_t);
+            if (is_own) {
+                header = (((tal_header_t *)p) - 1);
+                memcpy(ret, p, header->size);
+#ifdef TAL_DEBUG
+                header->line_num = -header->line_num;
+#endif
+            } else {
+                al->nb_allocs++;
+            }
+#ifdef TAL_INFO
+            if (al->nb_peak < al->nb_allocs)
+                al->nb_peak = al->nb_allocs;
+            if (al->peak_p < al->p)
+                al->peak_p = al->p;
+            al->nb_total++;
+#endif
+            return ret;
+        } else if (is_own) {
+            al->nb_allocs--;
+            ret = tal_realloc(*pal, 0, size);
+            header = (((tal_header_t *)p) - 1);
+            memcpy(ret, p, header->size);
+#ifdef TAL_DEBUG
+            header->line_num = -header->line_num;
+#endif
+            return ret;
+        }
+        if (al->next) {
+            al = al->next;
+        } else {
+            TinyAlloc *bottom = al, *next = al->top ? al->top : al;
+
+            al = tal_new(pal, next->limit, next->size * 2);
+            al->next = next;
+            bottom->top = al;
+        }
+        goto tail_call;
+    }
+    if (is_own) {
+        al->nb_allocs--;
+        ret = tcc_malloc(size);
+        header = (((tal_header_t *)p) - 1);
+        memcpy(ret, p, header->size);
+#ifdef TAL_DEBUG
+        header->line_num = -header->line_num;
+#endif
+    } else if (al->next) {
+        al = al->next;
+        goto tail_call;
+    } else
+        ret = tcc_realloc(p, size);
+#ifdef TAL_INFO
+    al->nb_missed++;
+#endif
+    return ret;
+}
+
+#endif /* USE_TAL */
+
+/* ------------------------------------------------------------------------- */
+/* CString handling */
+static void cstr_realloc(CString *cstr, int new_size)
+{
+    int size;
+
+    size = cstr->size_allocated;
+    if (size < 8)
+        size = 8; /* no need to allocate a too small first string */
+    while (size < new_size)
+        size = size * 2;
+    cstr->data = tal_realloc(cstr_alloc, cstr->data, size);
+    cstr->size_allocated = size;
+}
+
+/* add a byte */
+ST_INLN void cstr_ccat(CString *cstr, int ch)
+{
+    int size;
+    size = cstr->size + 1;
+    if (size > cstr->size_allocated)
+        cstr_realloc(cstr, size);
+    ((unsigned char *)cstr->data)[size - 1] = ch;
+    cstr->size = size;
+}
+
+ST_FUNC void cstr_cat(CString *cstr, const char *str, int len)
+{
+    int size;
+    if (len <= 0)
+        len = strlen(str) + 1 + len;
+    size = cstr->size + len;
+    if (size > cstr->size_allocated)
+        cstr_realloc(cstr, size);
+    memmove(((unsigned char *)cstr->data) + cstr->size, str, len);
+    cstr->size = size;
+}
+
+/* add a wide char */
+ST_FUNC void cstr_wccat(CString *cstr, int ch)
+{
+    int size;
+    size = cstr->size + sizeof(nwchar_t);
+    if (size > cstr->size_allocated)
+        cstr_realloc(cstr, size);
+    *(nwchar_t *)(((unsigned char *)cstr->data) + size - sizeof(nwchar_t)) = ch;
+    cstr->size = size;
+}
+
+ST_FUNC void cstr_new(CString *cstr)
+{
+    memset(cstr, 0, sizeof(CString));
+}
+
+/* free string and reset it to NULL */
+ST_FUNC void cstr_free(CString *cstr)
+{
+    tal_free(cstr_alloc, cstr->data);
+    cstr_new(cstr);
+}
+
+/* reset string to empty */
+ST_FUNC void cstr_reset(CString *cstr)
+{
+    cstr->size = 0;
+}
+
+/* XXX: unicode ? */
+static void add_char(CString *cstr, int c)
+{
+    if (c == '\'' || c == '\"' || c == '\\') {
+        /* XXX: could be more precise if char or string */
+        cstr_ccat(cstr, '\\');
+    }
+    if (c >= 32 && c <= 126) {
+        cstr_ccat(cstr, c);
+    } else {
+        cstr_ccat(cstr, '\\');
+        if (c == '\n') {
+            cstr_ccat(cstr, 'n');
+        } else {
+            cstr_ccat(cstr, '0' + ((c >> 6) & 7));
+            cstr_ccat(cstr, '0' + ((c >> 3) & 7));
+            cstr_ccat(cstr, '0' + (c & 7));
+        }
+    }
+}
+
+/* ------------------------------------------------------------------------- */
+/* allocate a new token */
+static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
+{
+    TokenSym *ts, **ptable;
+    int i;
+
+    if (tok_ident >= SYM_FIRST_ANOM) 
+        tcc_error("memory full (symbols)");
+
+    /* expand token table if needed */
+    i = tok_ident - TOK_IDENT;
+    if ((i % TOK_ALLOC_INCR) == 0) {
+        ptable = tcc_realloc(table_ident, (i + TOK_ALLOC_INCR) * sizeof(TokenSym *));
+        table_ident = ptable;
+    }
+
+    ts = tal_realloc(toksym_alloc, 0, sizeof(TokenSym) + len);
+    table_ident[i] = ts;
+    ts->tok = tok_ident++;
+    ts->sym_define = NULL;
+    ts->sym_label = NULL;
+    ts->sym_struct = NULL;
+    ts->sym_identifier = NULL;
+    ts->len = len;
+    ts->hash_next = NULL;
+    memcpy(ts->str, str, len);
+    ts->str[len] = '\0';
+    *pts = ts;
+    return ts;
+}
+
+#define TOK_HASH_INIT 1
+#define TOK_HASH_FUNC(h, c) ((h) + ((h) << 5) + ((h) >> 27) + (c))
+
+
+/* find a token and add it if not found */
+ST_FUNC TokenSym *tok_alloc(const char *str, int len)
+{
+    TokenSym *ts, **pts;
+    int i;
+    unsigned int h;
+    
+    h = TOK_HASH_INIT;
+    for(i=0;i<len;i++)
+        h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
+    h &= (TOK_HASH_SIZE - 1);
+
+    pts = &hash_ident[h];
+    for(;;) {
+        ts = *pts;
+        if (!ts)
+            break;
+        if (ts->len == len && !memcmp(ts->str, str, len))
+            return ts;
+        pts = &(ts->hash_next);
+    }
+    return tok_alloc_new(pts, str, len);
+}
+
+/* XXX: buffer overflow */
+/* XXX: float tokens */
+ST_FUNC const char *get_tok_str(int v, CValue *cv)
+{
+    char *p;
+    int i, len;
+
+    cstr_reset(&cstr_buf);
+    p = cstr_buf.data;
+
+    switch(v) {
+    case TOK_CINT:
+    case TOK_CUINT:
+    case TOK_CLONG:
+    case TOK_CULONG:
+    case TOK_CLLONG:
+    case TOK_CULLONG:
+        /* XXX: not quite exact, but only useful for testing  */
+#ifdef _WIN32
+        sprintf(p, "%u", (unsigned)cv->i);
+#else
+        sprintf(p, "%llu", (unsigned long long)cv->i);
+#endif
+        break;
+    case TOK_LCHAR:
+        cstr_ccat(&cstr_buf, 'L');
+    case TOK_CCHAR:
+        cstr_ccat(&cstr_buf, '\'');
+        add_char(&cstr_buf, cv->i);
+        cstr_ccat(&cstr_buf, '\'');
+        cstr_ccat(&cstr_buf, '\0');
+        break;
+    case TOK_PPNUM:
+    case TOK_PPSTR:
+        return (char*)cv->str.data;
+    case TOK_LSTR:
+        cstr_ccat(&cstr_buf, 'L');
+    case TOK_STR:
+        cstr_ccat(&cstr_buf, '\"');
+        if (v == TOK_STR) {
+            len = cv->str.size - 1;
+            for(i=0;i<len;i++)
+                add_char(&cstr_buf, ((unsigned char *)cv->str.data)[i]);
+        } else {
+            len = (cv->str.size / sizeof(nwchar_t)) - 1;
+            for(i=0;i<len;i++)
+                add_char(&cstr_buf, ((nwchar_t *)cv->str.data)[i]);
+        }
+        cstr_ccat(&cstr_buf, '\"');
+        cstr_ccat(&cstr_buf, '\0');
+        break;
+
+    case TOK_CFLOAT:
+        cstr_cat(&cstr_buf, "<float>", 0);
+        break;
+    case TOK_CDOUBLE:
+	cstr_cat(&cstr_buf, "<double>", 0);
+	break;
+    case TOK_CLDOUBLE:
+	cstr_cat(&cstr_buf, "<long double>", 0);
+	break;
+    case TOK_LINENUM:
+	cstr_cat(&cstr_buf, "<linenumber>", 0);
+	break;
+
+    /* above tokens have value, the ones below don't */
+    case TOK_LT:
+        v = '<';
+        goto addv;
+    case TOK_GT:
+        v = '>';
+        goto addv;
+    case TOK_DOTS:
+        return strcpy(p, "...");
+    case TOK_A_SHL:
+        return strcpy(p, "<<=");
+    case TOK_A_SAR:
+        return strcpy(p, ">>=");
+    case TOK_EOF:
+        return strcpy(p, "<eof>");
+    default:
+        if (v < TOK_IDENT) {
+            /* search in two bytes table */
+            const unsigned char *q = tok_two_chars;
+            while (*q) {
+                if (q[2] == v) {
+                    *p++ = q[0];
+                    *p++ = q[1];
+                    *p = '\0';
+                    return cstr_buf.data;
+                }
+                q += 3;
+            }
+        if (v >= 127) {
+            sprintf(cstr_buf.data, "<%02x>", v);
+            return cstr_buf.data;
+        }
+        addv:
+            *p++ = v;
+            *p = '\0';
+        } else if (v < tok_ident) {
+            return table_ident[v - TOK_IDENT]->str;
+        } else if (v >= SYM_FIRST_ANOM) {
+            /* special name for anonymous symbol */
+            sprintf(p, "L.%u", v - SYM_FIRST_ANOM);
+        } else {
+            /* should never happen */
+            return NULL;
+        }
+        break;
+    }
+    return cstr_buf.data;
+}
+
+/* return the current character, handling end of block if necessary
+   (but not stray) */
+ST_FUNC int handle_eob(void)
+{
+    BufferedFile *bf = file;
+    int len;
+
+    /* only tries to read if really end of buffer */
+    if (bf->buf_ptr >= bf->buf_end) {
+        if (bf->fd >= 0) {
+#if defined(PARSE_DEBUG)
+            len = 1;
+#else
+            len = IO_BUF_SIZE;
+#endif
+            len = read(bf->fd, bf->buffer, len);
+            if (len < 0)
+                len = 0;
+        } else {
+            len = 0;
+        }
+        total_bytes += len;
+        bf->buf_ptr = bf->buffer;
+        bf->buf_end = bf->buffer + len;
+        *bf->buf_end = CH_EOB;
+    }
+    if (bf->buf_ptr < bf->buf_end) {
+        return bf->buf_ptr[0];
+    } else {
+        bf->buf_ptr = bf->buf_end;
+        return CH_EOF;
+    }
+}
+
+/* read next char from current input file and handle end of input buffer */
+ST_INLN void inp(void)
+{
+    ch = *(++(file->buf_ptr));
+    /* end of buffer/file handling */
+    if (ch == CH_EOB)
+        ch = handle_eob();
+}
+
+/* handle '\[\r]\n' */
+static int handle_stray_noerror(void)
+{
+    while (ch == '\\') {
+        inp();
+        if (ch == '\n') {
+            file->line_num++;
+            inp();
+        } else if (ch == '\r') {
+            inp();
+            if (ch != '\n')
+                goto fail;
+            file->line_num++;
+            inp();
+        } else {
+        fail:
+            return 1;
+        }
+    }
+    return 0;
+}
+
+static void handle_stray(void)
+{
+    if (handle_stray_noerror())
+        tcc_error("stray '\\' in program");
+}
+
+/* skip the stray and handle the \\n case. Output an error if
+   incorrect char after the stray */
+static int handle_stray1(uint8_t *p)
+{
+    int c;
+
+    file->buf_ptr = p;
+    if (p >= file->buf_end) {
+        c = handle_eob();
+        if (c != '\\')
+            return c;
+        p = file->buf_ptr;
+    }
+    ch = *p;
+    if (handle_stray_noerror()) {
+        if (!(parse_flags & PARSE_FLAG_ACCEPT_STRAYS))
+            tcc_error("stray '\\' in program");
+        *--file->buf_ptr = '\\';
+    }
+    p = file->buf_ptr;
+    c = *p;
+    return c;
+}
+
+/* handle just the EOB case, but not stray */
+#define PEEKC_EOB(c, p)\
+{\
+    p++;\
+    c = *p;\
+    if (c == '\\') {\
+        file->buf_ptr = p;\
+        c = handle_eob();\
+        p = file->buf_ptr;\
+    }\
+}
+
+/* handle the complicated stray case */
+#define PEEKC(c, p)\
+{\
+    p++;\
+    c = *p;\
+    if (c == '\\') {\
+        c = handle_stray1(p);\
+        p = file->buf_ptr;\
+    }\
+}
+
+/* input with '\[\r]\n' handling. Note that this function cannot
+   handle other characters after '\', so you cannot call it inside
+   strings or comments */
+ST_FUNC void minp(void)
+{
+    inp();
+    if (ch == '\\') 
+        handle_stray();
+}
+
+/* single line C++ comments */
+static uint8_t *parse_line_comment(uint8_t *p)
+{
+    int c;
+
+    p++;
+    for(;;) {
+        c = *p;
+    redo:
+        if (c == '\n' || c == CH_EOF) {
+            break;
+        } else if (c == '\\') {
+            file->buf_ptr = p;
+            c = handle_eob();
+            p = file->buf_ptr;
+            if (c == '\\') {
+                PEEKC_EOB(c, p);
+                if (c == '\n') {
+                    file->line_num++;
+                    PEEKC_EOB(c, p);
+                } else if (c == '\r') {
+                    PEEKC_EOB(c, p);
+                    if (c == '\n') {
+                        file->line_num++;
+                        PEEKC_EOB(c, p);
+                    }
+                }
+            } else {
+                goto redo;
+            }
+        } else {
+            p++;
+        }
+    }
+    return p;
+}
+
+/* C comments */
+ST_FUNC uint8_t *parse_comment(uint8_t *p)
+{
+    int c;
+
+    p++;
+    for(;;) {
+        /* fast skip loop */
+        for(;;) {
+            c = *p;
+            if (c == '\n' || c == '*' || c == '\\')
+                break;
+            p++;
+            c = *p;
+            if (c == '\n' || c == '*' || c == '\\')
+                break;
+            p++;
+        }
+        /* now we can handle all the cases */
+        if (c == '\n') {
+            file->line_num++;
+            p++;
+        } else if (c == '*') {
+            p++;
+            for(;;) {
+                c = *p;
+                if (c == '*') {
+                    p++;
+                } else if (c == '/') {
+                    goto end_of_comment;
+                } else if (c == '\\') {
+                    file->buf_ptr = p;
+                    c = handle_eob();
+                    p = file->buf_ptr;
+                    if (c == CH_EOF)
+                        tcc_error("unexpected end of file in comment");
+                    if (c == '\\') {
+                        /* skip '\[\r]\n', otherwise just skip the stray */
+                        while (c == '\\') {
+                            PEEKC_EOB(c, p);
+                            if (c == '\n') {
+                                file->line_num++;
+                                PEEKC_EOB(c, p);
+                            } else if (c == '\r') {
+                                PEEKC_EOB(c, p);
+                                if (c == '\n') {
+                                    file->line_num++;
+                                    PEEKC_EOB(c, p);
+                                }
+                            } else {
+                                goto after_star;
+                            }
+                        }
+                    }
+                } else {
+                    break;
+                }
+            }
+        after_star: ;
+        } else {
+            /* stray, eob or eof */
+            file->buf_ptr = p;
+            c = handle_eob();
+            p = file->buf_ptr;
+            if (c == CH_EOF) {
+                tcc_error("unexpected end of file in comment");
+            } else if (c == '\\') {
+                p++;
+            }
+        }
+    }
+ end_of_comment:
+    p++;
+    return p;
+}
+
+ST_FUNC int set_idnum(int c, int val)
+{
+    int prev = isidnum_table[c - CH_EOF];
+    isidnum_table[c - CH_EOF] = val;
+    return prev;
+}
+
+#define cinp minp
+
+static inline void skip_spaces(void)
+{
+    while (isidnum_table[ch - CH_EOF] & IS_SPC)
+        cinp();
+}
+
+static inline int check_space(int t, int *spc) 
+{
+    if (t < 256 && (isidnum_table[t - CH_EOF] & IS_SPC)) {
+        if (*spc) 
+            return 1;
+        *spc = 1;
+    } else 
+        *spc = 0;
+    return 0;
+}
+
+/* parse a string without interpreting escapes */
+static uint8_t *parse_pp_string(uint8_t *p,
+                                int sep, CString *str)
+{
+    int c;
+    p++;
+    for(;;) {
+        c = *p;
+        if (c == sep) {
+            break;
+        } else if (c == '\\') {
+            file->buf_ptr = p;
+            c = handle_eob();
+            p = file->buf_ptr;
+            if (c == CH_EOF) {
+            unterminated_string:
+                /* XXX: indicate line number of start of string */
+                tcc_error("missing terminating %c character", sep);
+            } else if (c == '\\') {
+                /* escape : just skip \[\r]\n */
+                PEEKC_EOB(c, p);
+                if (c == '\n') {
+                    file->line_num++;
+                    p++;
+                } else if (c == '\r') {
+                    PEEKC_EOB(c, p);
+                    if (c != '\n')
+                        expect("'\n' after '\r'");
+                    file->line_num++;
+                    p++;
+                } else if (c == CH_EOF) {
+                    goto unterminated_string;
+                } else {
+                    if (str) {
+                        cstr_ccat(str, '\\');
+                        cstr_ccat(str, c);
+                    }
+                    p++;
+                }
+            }
+        } else if (c == '\n') {
+            file->line_num++;
+            goto add_char;
+        } else if (c == '\r') {
+            PEEKC_EOB(c, p);
+            if (c != '\n') {
+                if (str)
+                    cstr_ccat(str, '\r');
+            } else {
+                file->line_num++;
+                goto add_char;
+            }
+        } else {
+        add_char:
+            if (str)
+                cstr_ccat(str, c);
+            p++;
+        }
+    }
+    p++;
+    return p;
+}
+
+/* skip block of text until #else, #elif or #endif. skip also pairs of
+   #if/#endif */
+static void preprocess_skip(void)
+{
+    int a, start_of_line, c, in_warn_or_error;
+    uint8_t *p;
+
+    p = file->buf_ptr;
+    a = 0;
+redo_start:
+    start_of_line = 1;
+    in_warn_or_error = 0;
+    for(;;) {
+    redo_no_start:
+        c = *p;
+        switch(c) {
+        case ' ':
+        case '\t':
+        case '\f':
+        case '\v':
+        case '\r':
+            p++;
+            goto redo_no_start;
+        case '\n':
+            file->line_num++;
+            p++;
+            goto redo_start;
+        case '\\':
+            file->buf_ptr = p;
+            c = handle_eob();
+            if (c == CH_EOF) {
+                expect("#endif");
+            } else if (c == '\\') {
+                ch = file->buf_ptr[0];
+                handle_stray_noerror();
+            }
+            p = file->buf_ptr;
+            goto redo_no_start;
+        /* skip strings */
+        case '\"':
+        case '\'':
+            if (in_warn_or_error)
+                goto _default;
+            p = parse_pp_string(p, c, NULL);
+            break;
+        /* skip comments */
+        case '/':
+            if (in_warn_or_error)
+                goto _default;
+            file->buf_ptr = p;
+            ch = *p;
+            minp();
+            p = file->buf_ptr;
+            if (ch == '*') {
+                p = parse_comment(p);
+            } else if (ch == '/') {
+                p = parse_line_comment(p);
+            }
+            break;
+        case '#':
+            p++;
+            if (start_of_line) {
+                file->buf_ptr = p;
+                next_nomacro();
+                p = file->buf_ptr;
+                if (a == 0 && 
+                    (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
+                    goto the_end;
+                if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
+                    a++;
+                else if (tok == TOK_ENDIF)
+                    a--;
+                else if( tok == TOK_ERROR || tok == TOK_WARNING)
+                    in_warn_or_error = 1;
+                else if (tok == TOK_LINEFEED)
+                    goto redo_start;
+                else if (parse_flags & PARSE_FLAG_ASM_FILE)
+                    p = parse_line_comment(p - 1);
+            } else if (parse_flags & PARSE_FLAG_ASM_FILE)
+                p = parse_line_comment(p - 1);
+            break;
+_default:
+        default:
+            p++;
+            break;
+        }
+        start_of_line = 0;
+    }
+ the_end: ;
+    file->buf_ptr = p;
+}
+
+#if 0
+/* return the number of additional 'ints' necessary to store the
+   token */
+static inline int tok_size(const int *p)
+{
+    switch(*p) {
+        /* 4 bytes */
+    case TOK_CINT:
+    case TOK_CUINT:
+    case TOK_CCHAR:
+    case TOK_LCHAR:
+    case TOK_CFLOAT:
+    case TOK_LINENUM:
+        return 1 + 1;
+    case TOK_STR:
+    case TOK_LSTR:
+    case TOK_PPNUM:
+    case TOK_PPSTR:
+        return 1 + ((sizeof(CString) + ((CString *)(p+1))->size + 3) >> 2);
+    case TOK_CLONG:
+    case TOK_CULONG:
+	return 1 + LONG_SIZE / 4;
+    case TOK_CDOUBLE:
+    case TOK_CLLONG:
+    case TOK_CULLONG:
+        return 1 + 2;
+    case TOK_CLDOUBLE:
+        return 1 + LDOUBLE_SIZE / 4;
+    default:
+        return 1 + 0;
+    }
+}
+#endif
+
+/* token string handling */
+ST_INLN void tok_str_new(TokenString *s)
+{
+    s->str = NULL;
+    s->len = s->lastlen = 0;
+    s->allocated_len = 0;
+    s->last_line_num = -1;
+}
+
+ST_FUNC TokenString *tok_str_alloc(void)
+{
+    TokenString *str = tal_realloc(tokstr_alloc, 0, sizeof *str);
+    tok_str_new(str);
+    return str;
+}
+
+ST_FUNC int *tok_str_dup(TokenString *s)
+{
+    int *str;
+
+    str = tal_realloc(tokstr_alloc, 0, s->len * sizeof(int));
+    memcpy(str, s->str, s->len * sizeof(int));
+    return str;
+}
+
+ST_FUNC void tok_str_free_str(int *str)
+{
+    tal_free(tokstr_alloc, str);
+}
+
+ST_FUNC void tok_str_free(TokenString *str)
+{
+    tok_str_free_str(str->str);
+    tal_free(tokstr_alloc, str);
+}
+
+ST_FUNC int *tok_str_realloc(TokenString *s, int new_size)
+{
+    int *str, size;
+
+    size = s->allocated_len;
+    if (size < 16)
+        size = 16;
+    while (size < new_size)
+        size = size * 2;
+    if (size > s->allocated_len) {
+        str = tal_realloc(tokstr_alloc, s->str, size * sizeof(int));
+        s->allocated_len = size;
+        s->str = str;
+    }
+    return s->str;
+}
+
+ST_FUNC void tok_str_add(TokenString *s, int t)
+{
+    int len, *str;
+
+    len = s->len;
+    str = s->str;
+    if (len >= s->allocated_len)
+        str = tok_str_realloc(s, len + 1);
+    str[len++] = t;
+    s->len = len;
+}
+
+ST_FUNC void begin_macro(TokenString *str, int alloc)
+{
+    str->alloc = alloc;
+    str->prev = macro_stack;
+    str->prev_ptr = macro_ptr;
+    str->save_line_num = file->line_num;
+    macro_ptr = str->str;
+    macro_stack = str;
+}
+
+ST_FUNC void end_macro(void)
+{
+    TokenString *str = macro_stack;
+    macro_stack = str->prev;
+    macro_ptr = str->prev_ptr;
+    file->line_num = str->save_line_num;
+    if (str->alloc == 2) {
+        str->alloc = 3; /* just mark as finished */
+    } else {
+        tok_str_free(str);
+    }
+}
+
+static void tok_str_add2(TokenString *s, int t, CValue *cv)
+{
+    int len, *str;
+
+    len = s->lastlen = s->len;
+    str = s->str;
+
+    /* allocate space for worst case */
+    if (len + TOK_MAX_SIZE >= s->allocated_len)
+        str = tok_str_realloc(s, len + TOK_MAX_SIZE + 1);
+    str[len++] = t;
+    switch(t) {
+    case TOK_CINT:
+    case TOK_CUINT:
+    case TOK_CCHAR:
+    case TOK_LCHAR:
+    case TOK_CFLOAT:
+    case TOK_LINENUM:
+#if LONG_SIZE == 4
+    case TOK_CLONG:
+    case TOK_CULONG:
+#endif
+        str[len++] = cv->tab[0];
+        break;
+    case TOK_PPNUM:
+    case TOK_PPSTR:
+    case TOK_STR:
+    case TOK_LSTR:
+        {
+            /* Insert the string into the int array. */
+            size_t nb_words =
+                1 + (cv->str.size + sizeof(int) - 1) / sizeof(int);
+            if (len + nb_words >= s->allocated_len)
+                str = tok_str_realloc(s, len + nb_words + 1);
+            str[len] = cv->str.size;
+            memcpy(&str[len + 1], cv->str.data, cv->str.size);
+            len += nb_words;
+        }
+        break;
+    case TOK_CDOUBLE:
+    case TOK_CLLONG:
+    case TOK_CULLONG:
+#if LONG_SIZE == 8
+    case TOK_CLONG:
+    case TOK_CULONG:
+#endif
+#if LDOUBLE_SIZE == 8
+    case TOK_CLDOUBLE:
+#endif
+        str[len++] = cv->tab[0];
+        str[len++] = cv->tab[1];
+        break;
+#if LDOUBLE_SIZE == 12
+    case TOK_CLDOUBLE:
+        str[len++] = cv->tab[0];
+        str[len++] = cv->tab[1];
+        str[len++] = cv->tab[2];
+#elif LDOUBLE_SIZE == 16
+    case TOK_CLDOUBLE:
+        str[len++] = cv->tab[0];
+        str[len++] = cv->tab[1];
+        str[len++] = cv->tab[2];
+        str[len++] = cv->tab[3];
+#elif LDOUBLE_SIZE != 8
+#error add long double size support
+#endif
+        break;
+    default:
+        break;
+    }
+    s->len = len;
+}
+
+/* add the current parse token in token string 's' */
+ST_FUNC void tok_str_add_tok(TokenString *s)
+{
+    CValue cval;
+
+    /* save line number info */
+    if (file->line_num != s->last_line_num) {
+        s->last_line_num = file->line_num;
+        cval.i = s->last_line_num;
+        tok_str_add2(s, TOK_LINENUM, &cval);
+    }
+    tok_str_add2(s, tok, &tokc);
+}
+
+/* get a token from an integer array and increment pointer
+   accordingly. we code it as a macro to avoid pointer aliasing. */
+static inline void TOK_GET(int *t, const int **pp, CValue *cv)
+{
+    const int *p = *pp;
+    int n, *tab;
+
+    tab = cv->tab;
+    switch(*t = *p++) {
+#if LONG_SIZE == 4
+    case TOK_CLONG:
+#endif
+    case TOK_CINT:
+    case TOK_CCHAR:
+    case TOK_LCHAR:
+    case TOK_LINENUM:
+        cv->i = *p++;
+        break;
+#if LONG_SIZE == 4
+    case TOK_CULONG:
+#endif
+    case TOK_CUINT:
+        cv->i = (unsigned)*p++;
+        break;
+    case TOK_CFLOAT:
+	tab[0] = *p++;
+	break;
+    case TOK_STR:
+    case TOK_LSTR:
+    case TOK_PPNUM:
+    case TOK_PPSTR:
+        cv->str.size = *p++;
+        cv->str.data = p;
+        p += (cv->str.size + sizeof(int) - 1) / sizeof(int);
+        break;
+    case TOK_CDOUBLE:
+    case TOK_CLLONG:
+    case TOK_CULLONG:
+#if LONG_SIZE == 8
+    case TOK_CLONG:
+    case TOK_CULONG:
+#endif
+        n = 2;
+        goto copy;
+    case TOK_CLDOUBLE:
+#if LDOUBLE_SIZE == 16
+        n = 4;
+#elif LDOUBLE_SIZE == 12
+        n = 3;
+#elif LDOUBLE_SIZE == 8
+        n = 2;
+#else
+# error add long double size support
+#endif
+    copy:
+        do
+            *tab++ = *p++;
+        while (--n);
+        break;
+    default:
+        break;
+    }
+    *pp = p;
+}
+
+static int macro_is_equal(const int *a, const int *b)
+{
+    CValue cv;
+    int t;
+
+    if (!a || !b)
+        return 1;
+
+    while (*a && *b) {
+        /* first time preallocate macro_equal_buf, next time only reset position to start */
+        cstr_reset(&macro_equal_buf);
+        TOK_GET(&t, &a, &cv);
+        cstr_cat(&macro_equal_buf, get_tok_str(t, &cv), 0);
+        TOK_GET(&t, &b, &cv);
+        if (strcmp(macro_equal_buf.data, get_tok_str(t, &cv)))
+            return 0;
+    }
+    return !(*a || *b);
+}
+
+/* defines handling */
+ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg)
+{
+    Sym *s, *o;
+
+    o = define_find(v);
+    s = sym_push2(&define_stack, v, macro_type, 0);
+    s->d = str;
+    s->next = first_arg;
+    table_ident[v - TOK_IDENT]->sym_define = s;
+
+    if (o && !macro_is_equal(o->d, s->d))
+	tcc_warning("%s redefined", get_tok_str(v, NULL));
+}
+
+/* undefined a define symbol. Its name is just set to zero */
+ST_FUNC void define_undef(Sym *s)
+{
+    int v = s->v;
+    if (v >= TOK_IDENT && v < tok_ident)
+        table_ident[v - TOK_IDENT]->sym_define = NULL;
+}
+
+ST_INLN Sym *define_find(int v)
+{
+    v -= TOK_IDENT;
+    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
+        return NULL;
+    return table_ident[v]->sym_define;
+}
+
+/* free define stack until top reaches 'b' */
+ST_FUNC void free_defines(Sym *b)
+{
+    while (define_stack != b) {
+        Sym *top = define_stack;
+        define_stack = top->prev;
+        tok_str_free_str(top->d);
+        define_undef(top);
+        sym_free(top);
+    }
+
+    /* restore remaining (-D or predefined) symbols if they were
+       #undef'd in the file */
+    while (b) {
+        int v = b->v;
+        if (v >= TOK_IDENT && v < tok_ident) {
+            Sym **d = &table_ident[v - TOK_IDENT]->sym_define;
+            if (!*d)
+                *d = b;
+        }
+        b = b->prev;
+    }
+}
+
+/* label lookup */
+ST_FUNC Sym *label_find(int v)
+{
+    v -= TOK_IDENT;
+    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
+        return NULL;
+    return table_ident[v]->sym_label;
+}
+
+ST_FUNC Sym *label_push(Sym **ptop, int v, int flags)
+{
+    Sym *s, **ps;
+    s = sym_push2(ptop, v, 0, 0);
+    s->r = flags;
+    ps = &table_ident[v - TOK_IDENT]->sym_label;
+    if (ptop == &global_label_stack) {
+        /* modify the top most local identifier, so that
+           sym_identifier will point to 's' when popped */
+        while (*ps != NULL)
+            ps = &(*ps)->prev_tok;
+    }
+    s->prev_tok = *ps;
+    *ps = s;
+    return s;
+}
+
+/* pop labels until element last is reached. Look if any labels are
+   undefined. Define symbols if '&&label' was used. */
+ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep)
+{
+    Sym *s, *s1;
+    for(s = *ptop; s != slast; s = s1) {
+        s1 = s->prev;
+        if (s->r == LABEL_DECLARED) {
+            tcc_warning("label '%s' declared but not used", get_tok_str(s->v, NULL));
+        } else if (s->r == LABEL_FORWARD) {
+                tcc_error("label '%s' used but not defined",
+                      get_tok_str(s->v, NULL));
+        } else {
+            if (s->c) {
+                /* define corresponding symbol. A size of
+                   1 is put. */
+                put_extern_sym(s, cur_text_section, s->jnext, 1);
+            }
+        }
+        /* remove label */
+        table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok;
+        if (!keep)
+            sym_free(s);
+    }
+    if (!keep)
+        *ptop = slast;
+}
+
+/* fake the nth "#if defined test_..." for tcc -dt -run */
+static void maybe_run_test(TCCState *s)
+{
+    const char *p;
+    if (s->include_stack_ptr != s->include_stack)
+        return;
+    p = get_tok_str(tok, NULL);
+    if (0 != memcmp(p, "test_", 5))
+        return;
+    if (0 != --s->run_test)
+        return;
+    fprintf(s->ppfp, "\n[%s]\n" + !(s->dflag & 32), p), fflush(s->ppfp);
+    define_push(tok, MACRO_OBJ, NULL, NULL);
+}
+
+/* eval an expression for #if/#elif */
+static int expr_preprocess(void)
+{
+    int c, t;
+    TokenString *str;
+    
+    str = tok_str_alloc();
+    pp_expr = 1;
+    while (tok != TOK_LINEFEED && tok != TOK_EOF) {
+        next(); /* do macro subst */
+        if (tok == TOK_DEFINED) {
+            next_nomacro();
+            t = tok;
+            if (t == '(') 
+                next_nomacro();
+            if (tok < TOK_IDENT)
+                expect("identifier");
+            if (tcc_state->run_test)
+                maybe_run_test(tcc_state);
+            c = define_find(tok) != 0;
+            if (t == '(') {
+                next_nomacro();
+                if (tok != ')')
+                    expect("')'");
+            }
+            tok = TOK_CINT;
+            tokc.i = c;
+        } else if (tok >= TOK_IDENT) {
+            /* if undefined macro */
+            tok = TOK_CINT;
+            tokc.i = 0;
+        }
+        tok_str_add_tok(str);
+    }
+    pp_expr = 0;
+    tok_str_add(str, -1); /* simulate end of file */
+    tok_str_add(str, 0);
+    /* now evaluate C constant expression */
+    begin_macro(str, 1);
+    next();
+    c = expr_const();
+    end_macro();
+    return c != 0;
+}
+
+
+/* parse after #define */
+ST_FUNC void parse_define(void)
+{
+    Sym *s, *first, **ps;
+    int v, t, varg, is_vaargs, spc;
+    int saved_parse_flags = parse_flags;
+
+    v = tok;
+    if (v < TOK_IDENT || v == TOK_DEFINED)
+        tcc_error("invalid macro name '%s'", get_tok_str(tok, &tokc));
+    /* XXX: should check if same macro (ANSI) */
+    first = NULL;
+    t = MACRO_OBJ;
+    /* We have to parse the whole define as if not in asm mode, in particular
+       no line comment with '#' must be ignored.  Also for function
+       macros the argument list must be parsed without '.' being an ID
+       character.  */
+    parse_flags = ((parse_flags & ~PARSE_FLAG_ASM_FILE) | PARSE_FLAG_SPACES);
+    /* '(' must be just after macro definition for MACRO_FUNC */
+    next_nomacro_spc();
+    if (tok == '(') {
+        int dotid = set_idnum('.', 0);
+        next_nomacro();
+        ps = &first;
+        if (tok != ')') for (;;) {
+            varg = tok;
+            next_nomacro();
+            is_vaargs = 0;
+            if (varg == TOK_DOTS) {
+                varg = TOK___VA_ARGS__;
+                is_vaargs = 1;
+            } else if (tok == TOK_DOTS && gnu_ext) {
+                is_vaargs = 1;
+                next_nomacro();
+            }
+            if (varg < TOK_IDENT)
+        bad_list:
+                tcc_error("bad macro parameter list");
+            s = sym_push2(&define_stack, varg | SYM_FIELD, is_vaargs, 0);
+            *ps = s;
+            ps = &s->next;
+            if (tok == ')')
+                break;
+            if (tok != ',' || is_vaargs)
+                goto bad_list;
+            next_nomacro();
+        }
+        next_nomacro_spc();
+        t = MACRO_FUNC;
+        set_idnum('.', dotid);
+    }
+
+    tokstr_buf.len = 0;
+    spc = 2;
+    parse_flags |= PARSE_FLAG_ACCEPT_STRAYS | PARSE_FLAG_SPACES | PARSE_FLAG_LINEFEED;
+    /* The body of a macro definition should be parsed such that identifiers
+       are parsed like the file mode determines (i.e. with '.' being an
+       ID character in asm mode).  But '#' should be retained instead of
+       regarded as line comment leader, so still don't set ASM_FILE
+       in parse_flags. */
+    while (tok != TOK_LINEFEED && tok != TOK_EOF) {
+        /* remove spaces around ## and after '#' */
+        if (TOK_TWOSHARPS == tok) {
+            if (2 == spc)
+                goto bad_twosharp;
+            if (1 == spc)
+                --tokstr_buf.len;
+            spc = 3;
+	    tok = TOK_PPJOIN;
+        } else if ('#' == tok) {
+            spc = 4;
+        } else if (check_space(tok, &spc)) {
+            goto skip;
+        }
+        tok_str_add2(&tokstr_buf, tok, &tokc);
+    skip:
+        next_nomacro_spc();
+    }
+
+    parse_flags = saved_parse_flags;
+    if (spc == 1)
+        --tokstr_buf.len; /* remove trailing space */
+    tok_str_add(&tokstr_buf, 0);
+    if (3 == spc)
+bad_twosharp:
+        tcc_error("'##' cannot appear at either end of macro");
+    define_push(v, t, tok_str_dup(&tokstr_buf), first);
+}
+
+static CachedInclude *search_cached_include(TCCState *s1, const char *filename, int add)
+{
+    const unsigned char *s;
+    unsigned int h;
+    CachedInclude *e;
+    int i;
+
+    h = TOK_HASH_INIT;
+    s = (unsigned char *) filename;
+    while (*s) {
+#ifdef _WIN32
+        h = TOK_HASH_FUNC(h, toup(*s));
+#else
+        h = TOK_HASH_FUNC(h, *s);
+#endif
+        s++;
+    }
+    h &= (CACHED_INCLUDES_HASH_SIZE - 1);
+
+    i = s1->cached_includes_hash[h];
+    for(;;) {
+        if (i == 0)
+            break;
+        e = s1->cached_includes[i - 1];
+        if (0 == PATHCMP(e->filename, filename))
+            return e;
+        i = e->hash_next;
+    }
+    if (!add)
+        return NULL;
+
+    e = tcc_malloc(sizeof(CachedInclude) + strlen(filename));
+    strcpy(e->filename, filename);
+    e->ifndef_macro = e->once = 0;
+    dynarray_add(&s1->cached_includes, &s1->nb_cached_includes, e);
+    /* add in hash table */
+    e->hash_next = s1->cached_includes_hash[h];
+    s1->cached_includes_hash[h] = s1->nb_cached_includes;
+#ifdef INC_DEBUG
+    printf("adding cached '%s'\n", filename);
+#endif
+    return e;
+}
+
+static void pragma_parse(TCCState *s1)
+{
+    next_nomacro();
+    if (tok == TOK_push_macro || tok == TOK_pop_macro) {
+        int t = tok, v;
+        Sym *s;
+
+        if (next(), tok != '(')
+            goto pragma_err;
+        if (next(), tok != TOK_STR)
+            goto pragma_err;
+        v = tok_alloc(tokc.str.data, tokc.str.size - 1)->tok;
+        if (next(), tok != ')')
+            goto pragma_err;
+        if (t == TOK_push_macro) {
+            while (NULL == (s = define_find(v)))
+                define_push(v, 0, NULL, NULL);
+            s->type.ref = s; /* set push boundary */
+        } else {
+            for (s = define_stack; s; s = s->prev)
+                if (s->v == v && s->type.ref == s) {
+                    s->type.ref = NULL;
+                    break;
+                }
+        }
+        if (s)
+            table_ident[v - TOK_IDENT]->sym_define = s->d ? s : NULL;
+        else
+            tcc_warning("unbalanced #pragma pop_macro");
+        pp_debug_tok = t, pp_debug_symv = v;
+
+    } else if (tok == TOK_once) {
+        search_cached_include(s1, file->filename, 1)->once = pp_once;
+
+    } else if (s1->output_type == TCC_OUTPUT_PREPROCESS) {
+        /* tcc -E: keep pragmas below unchanged */
+        unget_tok(' ');
+        unget_tok(TOK_PRAGMA);
+        unget_tok('#');
+        unget_tok(TOK_LINEFEED);
+
+    } else if (tok == TOK_pack) {
+        /* This may be:
+           #pragma pack(1) // set
+           #pragma pack() // reset to default
+           #pragma pack(push,1) // push & set
+           #pragma pack(pop) // restore previous */
+        next();
+        skip('(');
+        if (tok == TOK_ASM_pop) {
+            next();
+            if (s1->pack_stack_ptr <= s1->pack_stack) {
+            stk_error:
+                tcc_error("out of pack stack");
+            }
+            s1->pack_stack_ptr--;
+        } else {
+            int val = 0;
+            if (tok != ')') {
+                if (tok == TOK_ASM_push) {
+                    next();
+                    if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE - 1)
+                        goto stk_error;
+                    s1->pack_stack_ptr++;
+                    skip(',');
+                }
+                if (tok != TOK_CINT)
+                    goto pragma_err;
+                val = tokc.i;
+                if (val < 1 || val > 16 || (val & (val - 1)) != 0)
+                    goto pragma_err;
+                next();
+            }
+            *s1->pack_stack_ptr = val;
+        }
+        if (tok != ')')
+            goto pragma_err;
+
+    } else if (tok == TOK_comment) {
+        char *p; int t;
+        next();
+        skip('(');
+        t = tok;
+        next();
+        skip(',');
+        if (tok != TOK_STR)
+            goto pragma_err;
+        p = tcc_strdup((char *)tokc.str.data);
+        next();
+        if (tok != ')')
+            goto pragma_err;
+        if (t == TOK_lib) {
+            dynarray_add(&s1->pragma_libs, &s1->nb_pragma_libs, p);
+        } else {
+            if (t == TOK_option)
+                tcc_set_options(s1, p);
+            tcc_free(p);
+        }
+
+    } else if (s1->warn_unsupported) {
+        tcc_warning("#pragma %s is ignored", get_tok_str(tok, &tokc));
+    }
+    return;
+
+pragma_err:
+    tcc_error("malformed #pragma directive");
+    return;
+}
+
+/* is_bof is true if first non space token at beginning of file */
+ST_FUNC void preprocess(int is_bof)
+{
+    TCCState *s1 = tcc_state;
+    int i, c, n, saved_parse_flags;
+    char buf[1024], *q;
+    Sym *s;
+
+    saved_parse_flags = parse_flags;
+    parse_flags = PARSE_FLAG_PREPROCESS
+        | PARSE_FLAG_TOK_NUM
+        | PARSE_FLAG_TOK_STR
+        | PARSE_FLAG_LINEFEED
+        | (parse_flags & PARSE_FLAG_ASM_FILE)
+        ;
+
+    next_nomacro();
+ redo:
+    switch(tok) {
+    case TOK_DEFINE:
+        pp_debug_tok = tok;
+        next_nomacro();
+        pp_debug_symv = tok;
+        parse_define();
+        break;
+    case TOK_UNDEF:
+        pp_debug_tok = tok;
+        next_nomacro();
+        pp_debug_symv = tok;
+        s = define_find(tok);
+        /* undefine symbol by putting an invalid name */
+        if (s)
+            define_undef(s);
+        break;
+    case TOK_INCLUDE:
+    case TOK_INCLUDE_NEXT:
+        ch = file->buf_ptr[0];
+        /* XXX: incorrect if comments : use next_nomacro with a special mode */
+        skip_spaces();
+        if (ch == '<') {
+            c = '>';
+            goto read_name;
+        } else if (ch == '\"') {
+            c = ch;
+        read_name:
+            inp();
+            q = buf;
+            while (ch != c && ch != '\n' && ch != CH_EOF) {
+                if ((q - buf) < sizeof(buf) - 1)
+                    *q++ = ch;
+                if (ch == '\\') {
+                    if (handle_stray_noerror() == 0)
+                        --q;
+                } else
+                    inp();
+            }
+            *q = '\0';
+            minp();
+#if 0
+            /* eat all spaces and comments after include */
+            /* XXX: slightly incorrect */
+            while (ch1 != '\n' && ch1 != CH_EOF)
+                inp();
+#endif
+        } else {
+	    int len;
+            /* computed #include : concatenate everything up to linefeed,
+	       the result must be one of the two accepted forms.
+	       Don't convert pp-tokens to tokens here.  */
+	    parse_flags = (PARSE_FLAG_PREPROCESS
+			   | PARSE_FLAG_LINEFEED
+			   | (parse_flags & PARSE_FLAG_ASM_FILE));
+            next();
+            buf[0] = '\0';
+	    while (tok != TOK_LINEFEED) {
+		pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
+		next();
+	    }
+	    len = strlen(buf);
+	    /* check syntax and remove '<>|""' */
+	    if ((len < 2 || ((buf[0] != '"' || buf[len-1] != '"') &&
+			     (buf[0] != '<' || buf[len-1] != '>'))))
+	        tcc_error("'#include' expects \"FILENAME\" or <FILENAME>");
+	    c = buf[len-1];
+	    memmove(buf, buf + 1, len - 2);
+	    buf[len - 2] = '\0';
+        }
+
+        if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
+            tcc_error("#include recursion too deep");
+        /* store current file in stack, but increment stack later below */
+        *s1->include_stack_ptr = file;
+        i = tok == TOK_INCLUDE_NEXT ? file->include_next_index : 0;
+        n = 2 + s1->nb_include_paths + s1->nb_sysinclude_paths;
+        for (; i < n; ++i) {
+            char buf1[sizeof file->filename];
+            CachedInclude *e;
+            const char *path;
+
+            if (i == 0) {
+                /* check absolute include path */
+                if (!IS_ABSPATH(buf))
+                    continue;
+                buf1[0] = 0;
+
+            } else if (i == 1) {
+                /* search in file's dir if "header.h" */
+                if (c != '\"')
+                    continue;
+                /* https://savannah.nongnu.org/bugs/index.php?50847 */
+                path = file->true_filename;
+                pstrncpy(buf1, path, tcc_basename(path) - path);
+
+            } else {
+                /* search in all the include paths */
+                int j = i - 2, k = j - s1->nb_include_paths;
+                path = k < 0 ? s1->include_paths[j] : s1->sysinclude_paths[k];
+                pstrcpy(buf1, sizeof(buf1), path);
+                pstrcat(buf1, sizeof(buf1), "/");
+            }
+
+            pstrcat(buf1, sizeof(buf1), buf);
+            e = search_cached_include(s1, buf1, 0);
+            if (e && (define_find(e->ifndef_macro) || e->once == pp_once)) {
+                /* no need to parse the include because the 'ifndef macro'
+                   is defined (or had #pragma once) */
+#ifdef INC_DEBUG
+                printf("%s: skipping cached %s\n", file->filename, buf1);
+#endif
+                goto include_done;
+            }
+
+            if (tcc_open(s1, buf1) < 0)
+                continue;
+
+            file->include_next_index = i + 1;
+#ifdef INC_DEBUG
+            printf("%s: including %s\n", file->prev->filename, file->filename);
+#endif
+            /* update target deps */
+            dynarray_add(&s1->target_deps, &s1->nb_target_deps,
+                    tcc_strdup(buf1));
+            /* push current file in stack */
+            ++s1->include_stack_ptr;
+            /* add include file debug info */
+            if (s1->do_debug)
+                put_stabs(file->filename, N_BINCL, 0, 0, 0);
+            tok_flags |= TOK_FLAG_BOF | TOK_FLAG_BOL;
+            ch = file->buf_ptr[0];
+            goto the_end;
+        }
+        tcc_error("include file '%s' not found", buf);
+include_done:
+        break;
+    case TOK_IFNDEF:
+        c = 1;
+        goto do_ifdef;
+    case TOK_IF:
+        c = expr_preprocess();
+        goto do_if;
+    case TOK_IFDEF:
+        c = 0;
+    do_ifdef:
+        next_nomacro();
+        if (tok < TOK_IDENT)
+            tcc_error("invalid argument for '#if%sdef'", c ? "n" : "");
+        if (is_bof) {
+            if (c) {
+#ifdef INC_DEBUG
+                printf("#ifndef %s\n", get_tok_str(tok, NULL));
+#endif
+                file->ifndef_macro = tok;
+            }
+        }
+        c = (define_find(tok) != 0) ^ c;
+    do_if:
+        if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
+            tcc_error("memory full (ifdef)");
+        *s1->ifdef_stack_ptr++ = c;
+        goto test_skip;
+    case TOK_ELSE:
+        if (s1->ifdef_stack_ptr == s1->ifdef_stack)
+            tcc_error("#else without matching #if");
+        if (s1->ifdef_stack_ptr[-1] & 2)
+            tcc_error("#else after #else");
+        c = (s1->ifdef_stack_ptr[-1] ^= 3);
+        goto test_else;
+    case TOK_ELIF:
+        if (s1->ifdef_stack_ptr == s1->ifdef_stack)
+            tcc_error("#elif without matching #if");
+        c = s1->ifdef_stack_ptr[-1];
+        if (c > 1)
+            tcc_error("#elif after #else");
+        /* last #if/#elif expression was true: we skip */
+        if (c == 1) {
+            c = 0;
+        } else {
+            c = expr_preprocess();
+            s1->ifdef_stack_ptr[-1] = c;
+        }
+    test_else:
+        if (s1->ifdef_stack_ptr == file->ifdef_stack_ptr + 1)
+            file->ifndef_macro = 0;
+    test_skip:
+        if (!(c & 1)) {
+            preprocess_skip();
+            is_bof = 0;
+            goto redo;
+        }
+        break;
+    case TOK_ENDIF:
+        if (s1->ifdef_stack_ptr <= file->ifdef_stack_ptr)
+            tcc_error("#endif without matching #if");
+        s1->ifdef_stack_ptr--;
+        /* '#ifndef macro' was at the start of file. Now we check if
+           an '#endif' is exactly at the end of file */
+        if (file->ifndef_macro &&
+            s1->ifdef_stack_ptr == file->ifdef_stack_ptr) {
+            file->ifndef_macro_saved = file->ifndef_macro;
+            /* need to set to zero to avoid false matches if another
+               #ifndef at middle of file */
+            file->ifndef_macro = 0;
+            while (tok != TOK_LINEFEED)
+                next_nomacro();
+            tok_flags |= TOK_FLAG_ENDIF;
+            goto the_end;
+        }
+        break;
+    case TOK_PPNUM:
+        n = strtoul((char*)tokc.str.data, &q, 10);
+        goto _line_num;
+    case TOK_LINE:
+        next();
+        if (tok != TOK_CINT)
+    _line_err:
+            tcc_error("wrong #line format");
+        n = tokc.i;
+    _line_num:
+        next();
+        if (tok != TOK_LINEFEED) {
+            if (tok == TOK_STR) {
+                if (file->true_filename == file->filename)
+                    file->true_filename = tcc_strdup(file->filename);
+                pstrcpy(file->filename, sizeof(file->filename), (char *)tokc.str.data);
+            } else if (parse_flags & PARSE_FLAG_ASM_FILE)
+                break;
+            else
+                goto _line_err;
+            --n;
+        }
+        if (file->fd > 0)
+            total_lines += file->line_num - n;
+        file->line_num = n;
+        if (s1->do_debug)
+    	    put_stabs(file->filename, N_BINCL, 0, 0, 0);
+        break;
+    case TOK_ERROR:
+    case TOK_WARNING:
+        c = tok;
+        ch = file->buf_ptr[0];
+        skip_spaces();
+        q = buf;
+        while (ch != '\n' && ch != CH_EOF) {
+            if ((q - buf) < sizeof(buf) - 1)
+                *q++ = ch;
+            if (ch == '\\') {
+                if (handle_stray_noerror() == 0)
+                    --q;
+            } else
+                inp();
+        }
+        *q = '\0';
+        if (c == TOK_ERROR)
+            tcc_error("#error %s", buf);
+        else
+            tcc_warning("#warning %s", buf);
+        break;
+    case TOK_PRAGMA:
+        pragma_parse(s1);
+        break;
+    case TOK_LINEFEED:
+        goto the_end;
+    default:
+        /* ignore gas line comment in an 'S' file. */
+        if (saved_parse_flags & PARSE_FLAG_ASM_FILE)
+            goto ignore;
+        if (tok == '!' && is_bof)
+            /* '!' is ignored at beginning to allow C scripts. */
+            goto ignore;
+        tcc_warning("Ignoring unknown preprocessing directive #%s", get_tok_str(tok, &tokc));
+    ignore:
+        file->buf_ptr = parse_line_comment(file->buf_ptr - 1);
+        goto the_end;
+    }
+    /* ignore other preprocess commands or #! for C scripts */
+    while (tok != TOK_LINEFEED)
+        next_nomacro();
+ the_end:
+    parse_flags = saved_parse_flags;
+}
+
+/* evaluate escape codes in a string. */
+static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long)
+{
+    int c, n;
+    const uint8_t *p;
+
+    p = buf;
+    for(;;) {
+        c = *p;
+        if (c == '\0')
+            break;
+        if (c == '\\') {
+            p++;
+            /* escape */
+            c = *p;
+            switch(c) {
+            case '0': case '1': case '2': case '3':
+            case '4': case '5': case '6': case '7':
+                /* at most three octal digits */
+                n = c - '0';
+                p++;
+                c = *p;
+                if (isoct(c)) {
+                    n = n * 8 + c - '0';
+                    p++;
+                    c = *p;
+                    if (isoct(c)) {
+                        n = n * 8 + c - '0';
+                        p++;
+                    }
+                }
+                c = n;
+                goto add_char_nonext;
+            case 'x':
+            case 'u':
+            case 'U':
+                p++;
+                n = 0;
+                for(;;) {
+                    c = *p;
+                    if (c >= 'a' && c <= 'f')
+                        c = c - 'a' + 10;
+                    else if (c >= 'A' && c <= 'F')
+                        c = c - 'A' + 10;
+                    else if (isnum(c))
+                        c = c - '0';
+                    else
+                        break;
+                    n = n * 16 + c;
+                    p++;
+                }
+                c = n;
+                goto add_char_nonext;
+            case 'a':
+                c = '\a';
+                break;
+            case 'b':
+                c = '\b';
+                break;
+            case 'f':
+                c = '\f';
+                break;
+            case 'n':
+                c = '\n';
+                break;
+            case 'r':
+                c = '\r';
+                break;
+            case 't':
+                c = '\t';
+                break;
+            case 'v':
+                c = '\v';
+                break;
+            case 'e':
+                if (!gnu_ext)
+                    goto invalid_escape;
+                c = 27;
+                break;
+            case '\'':
+            case '\"':
+            case '\\': 
+            case '?':
+                break;
+            default:
+            invalid_escape:
+                if (c >= '!' && c <= '~')
+                    tcc_warning("unknown escape sequence: \'\\%c\'", c);
+                else
+                    tcc_warning("unknown escape sequence: \'\\x%x\'", c);
+                break;
+            }
+        } else if (is_long && c >= 0x80) {
+            /* assume we are processing UTF-8 sequence */
+            /* reference: The Unicode Standard, Version 10.0, ch3.9 */
+
+            int cont; /* count of continuation bytes */
+            int skip; /* how many bytes should skip when error occurred */
+            int i;
+
+            /* decode leading byte */
+            if (c < 0xC2) {
+	            skip = 1; goto invalid_utf8_sequence;
+            } else if (c <= 0xDF) {
+	            cont = 1; n = c & 0x1f;
+            } else if (c <= 0xEF) {
+	            cont = 2; n = c & 0xf;
+            } else if (c <= 0xF4) {
+	            cont = 3; n = c & 0x7;
+            } else {
+	            skip = 1; goto invalid_utf8_sequence;
+            }
+
+            /* decode continuation bytes */
+            for (i = 1; i <= cont; i++) {
+                int l = 0x80, h = 0xBF;
+
+                /* adjust limit for second byte */
+                if (i == 1) {
+                    switch (c) {
+                    case 0xE0: l = 0xA0; break;
+                    case 0xED: h = 0x9F; break;
+                    case 0xF0: l = 0x90; break;
+                    case 0xF4: h = 0x8F; break;
+                    }
+                }
+
+                if (p[i] < l || p[i] > h) {
+                    skip = i; goto invalid_utf8_sequence;
+                }
+
+                n = (n << 6) | (p[i] & 0x3f);
+            }
+
+            /* advance pointer */
+            p += 1 + cont;
+            c = n;
+            goto add_char_nonext;
+
+            /* error handling */
+        invalid_utf8_sequence:
+            tcc_warning("ill-formed UTF-8 subsequence starting with: \'\\x%x\'", c);
+            c = 0xFFFD;
+            p += skip;
+            goto add_char_nonext;
+
+        }
+        p++;
+    add_char_nonext:
+        if (!is_long)
+            cstr_ccat(outstr, c);
+        else {
+#ifdef TCC_TARGET_PE
+            /* store as UTF-16 */
+            if (c < 0x10000) {
+                cstr_wccat(outstr, c);
+            } else {
+                c -= 0x10000;
+                cstr_wccat(outstr, (c >> 10) + 0xD800);
+                cstr_wccat(outstr, (c & 0x3FF) + 0xDC00);
+            }
+#else
+            cstr_wccat(outstr, c);
+#endif
+        }
+    }
+    /* add a trailing '\0' */
+    if (!is_long)
+        cstr_ccat(outstr, '\0');
+    else
+        cstr_wccat(outstr, '\0');
+}
+
+static void parse_string(const char *s, int len)
+{
+    uint8_t buf[1000], *p = buf;
+    int is_long, sep;
+
+    if ((is_long = *s == 'L'))
+        ++s, --len;
+    sep = *s++;
+    len -= 2;
+    if (len >= sizeof buf)
+        p = tcc_malloc(len + 1);
+    memcpy(p, s, len);
+    p[len] = 0;
+
+    cstr_reset(&tokcstr);
+    parse_escape_string(&tokcstr, p, is_long);
+    if (p != buf)
+        tcc_free(p);
+
+    if (sep == '\'') {
+        int char_size, i, n, c;
+        /* XXX: make it portable */
+        if (!is_long)
+            tok = TOK_CCHAR, char_size = 1;
+        else
+            tok = TOK_LCHAR, char_size = sizeof(nwchar_t);
+        n = tokcstr.size / char_size - 1;
+        if (n < 1)
+            tcc_error("empty character constant");
+        if (n > 1)
+            tcc_warning("multi-character character constant");
+        for (c = i = 0; i < n; ++i) {
+            if (is_long)
+                c = ((nwchar_t *)tokcstr.data)[i];
+            else
+                c = (c << 8) | ((char *)tokcstr.data)[i];
+        }
+        tokc.i = c;
+    } else {
+        tokc.str.size = tokcstr.size;
+        tokc.str.data = tokcstr.data;
+        if (!is_long)
+            tok = TOK_STR;
+        else
+            tok = TOK_LSTR;
+    }
+}
+
+/* we use 64 bit numbers */
+#define BN_SIZE 2
+
+/* bn = (bn << shift) | or_val */
+static void bn_lshift(unsigned int *bn, int shift, int or_val)
+{
+    int i;
+    unsigned int v;
+    for(i=0;i<BN_SIZE;i++) {
+        v = bn[i];
+        bn[i] = (v << shift) | or_val;
+        or_val = v >> (32 - shift);
+    }
+}
+
+static void bn_zero(unsigned int *bn)
+{
+    int i;
+    for(i=0;i<BN_SIZE;i++) {
+        bn[i] = 0;
+    }
+}
+
+/* parse number in null terminated string 'p' and return it in the
+   current token */
+static void parse_number(const char *p)
+{
+    int b, t, shift, frac_bits, s, exp_val, ch;
+    char *q;
+    unsigned int bn[BN_SIZE];
+    double d;
+
+    /* number */
+    q = token_buf;
+    ch = *p++;
+    t = ch;
+    ch = *p++;
+    *q++ = t;
+    b = 10;
+    if (t == '.') {
+        goto float_frac_parse;
+    } else if (t == '0') {
+        if (ch == 'x' || ch == 'X') {
+            q--;
+            ch = *p++;
+            b = 16;
+        } else if (tcc_ext && (ch == 'b' || ch == 'B')) {
+            q--;
+            ch = *p++;
+            b = 2;
+        }
+    }
+    /* parse all digits. cannot check octal numbers at this stage
+       because of floating point constants */
+    while (1) {
+        if (ch >= 'a' && ch <= 'f')
+            t = ch - 'a' + 10;
+        else if (ch >= 'A' && ch <= 'F')
+            t = ch - 'A' + 10;
+        else if (isnum(ch))
+            t = ch - '0';
+        else
+            break;
+        if (t >= b)
+            break;
+        if (q >= token_buf + STRING_MAX_SIZE) {
+        num_too_long:
+            tcc_error("number too long");
+        }
+        *q++ = ch;
+        ch = *p++;
+    }
+    if (ch == '.' ||
+        ((ch == 'e' || ch == 'E') && b == 10) ||
+        ((ch == 'p' || ch == 'P') && (b == 16 || b == 2))) {
+        if (b != 10) {
+            /* NOTE: strtox should support that for hexa numbers, but
+               non ISOC99 libcs do not support it, so we prefer to do
+               it by hand */
+            /* hexadecimal or binary floats */
+            /* XXX: handle overflows */
+            *q = '\0';
+            if (b == 16)
+                shift = 4;
+            else 
+                shift = 1;
+            bn_zero(bn);
+            q = token_buf;
+            while (1) {
+                t = *q++;
+                if (t == '\0') {
+                    break;
+                } else if (t >= 'a') {
+                    t = t - 'a' + 10;
+                } else if (t >= 'A') {
+                    t = t - 'A' + 10;
+                } else {
+                    t = t - '0';
+                }
+                bn_lshift(bn, shift, t);
+            }
+            frac_bits = 0;
+            if (ch == '.') {
+                ch = *p++;
+                while (1) {
+                    t = ch;
+                    if (t >= 'a' && t <= 'f') {
+                        t = t - 'a' + 10;
+                    } else if (t >= 'A' && t <= 'F') {
+                        t = t - 'A' + 10;
+                    } else if (t >= '0' && t <= '9') {
+                        t = t - '0';
+                    } else {
+                        break;
+                    }
+                    if (t >= b)
+                        tcc_error("invalid digit");
+                    bn_lshift(bn, shift, t);
+                    frac_bits += shift;
+                    ch = *p++;
+                }
+            }
+            if (ch != 'p' && ch != 'P')
+                expect("exponent");
+            ch = *p++;
+            s = 1;
+            exp_val = 0;
+            if (ch == '+') {
+                ch = *p++;
+            } else if (ch == '-') {
+                s = -1;
+                ch = *p++;
+            }
+            if (ch < '0' || ch > '9')
+                expect("exponent digits");
+            while (ch >= '0' && ch <= '9') {
+                exp_val = exp_val * 10 + ch - '0';
+                ch = *p++;
+            }
+            exp_val = exp_val * s;
+            
+            /* now we can generate the number */
+            /* XXX: should patch directly float number */
+            d = (double)bn[1] * 4294967296.0 + (double)bn[0];
+            d = ldexp(d, exp_val - frac_bits);
+            t = toup(ch);
+            if (t == 'F') {
+                ch = *p++;
+                tok = TOK_CFLOAT;
+                /* float : should handle overflow */
+                tokc.f = (float)d;
+            } else if (t == 'L') {
+                ch = *p++;
+#ifdef TCC_TARGET_PE
+                tok = TOK_CDOUBLE;
+                tokc.d = d;
+#else
+                tok = TOK_CLDOUBLE;
+                /* XXX: not large enough */
+                tokc.ld = (long double)d;
+#endif
+            } else {
+                tok = TOK_CDOUBLE;
+                tokc.d = d;
+            }
+        } else {
+            /* decimal floats */
+            if (ch == '.') {
+                if (q >= token_buf + STRING_MAX_SIZE)
+                    goto num_too_long;
+                *q++ = ch;
+                ch = *p++;
+            float_frac_parse:
+                while (ch >= '0' && ch <= '9') {
+                    if (q >= token_buf + STRING_MAX_SIZE)
+                        goto num_too_long;
+                    *q++ = ch;
+                    ch = *p++;
+                }
+            }
+            if (ch == 'e' || ch == 'E') {
+                if (q >= token_buf + STRING_MAX_SIZE)
+                    goto num_too_long;
+                *q++ = ch;
+                ch = *p++;
+                if (ch == '-' || ch == '+') {
+                    if (q >= token_buf + STRING_MAX_SIZE)
+                        goto num_too_long;
+                    *q++ = ch;
+                    ch = *p++;
+                }
+                if (ch < '0' || ch > '9')
+                    expect("exponent digits");
+                while (ch >= '0' && ch <= '9') {
+                    if (q >= token_buf + STRING_MAX_SIZE)
+                        goto num_too_long;
+                    *q++ = ch;
+                    ch = *p++;
+                }
+            }
+            *q = '\0';
+            t = toup(ch);
+            errno = 0;
+            if (t == 'F') {
+                ch = *p++;
+                tok = TOK_CFLOAT;
+                tokc.f = strtof(token_buf, NULL);
+            } else if (t == 'L') {
+                ch = *p++;
+#ifdef TCC_TARGET_PE
+                tok = TOK_CDOUBLE;
+                tokc.d = strtod(token_buf, NULL);
+#else
+                tok = TOK_CLDOUBLE;
+                tokc.ld = strtold(token_buf, NULL);
+#endif
+            } else {
+                tok = TOK_CDOUBLE;
+                tokc.d = strtod(token_buf, NULL);
+            }
+        }
+    } else {
+        unsigned long long n, n1;
+        int lcount, ucount, ov = 0;
+        const char *p1;
+
+        /* integer number */
+        *q = '\0';
+        q = token_buf;
+        if (b == 10 && *q == '0') {
+            b = 8;
+            q++;
+        }
+        n = 0;
+        while(1) {
+            t = *q++;
+            /* no need for checks except for base 10 / 8 errors */
+            if (t == '\0')
+                break;
+            else if (t >= 'a')
+                t = t - 'a' + 10;
+            else if (t >= 'A')
+                t = t - 'A' + 10;
+            else
+                t = t - '0';
+            if (t >= b)
+                tcc_error("invalid digit");
+            n1 = n;
+            n = n * b + t;
+            /* detect overflow */
+            if (n1 >= 0x1000000000000000ULL && n / b != n1)
+                ov = 1;
+        }
+
+        /* Determine the characteristics (unsigned and/or 64bit) the type of
+           the constant must have according to the constant suffix(es) */
+        lcount = ucount = 0;
+        p1 = p;
+        for(;;) {
+            t = toup(ch);
+            if (t == 'L') {
+                if (lcount >= 2)
+                    tcc_error("three 'l's in integer constant");
+                if (lcount && *(p - 1) != ch)
+                    tcc_error("incorrect integer suffix: %s", p1);
+                lcount++;
+                ch = *p++;
+            } else if (t == 'U') {
+                if (ucount >= 1)
+                    tcc_error("two 'u's in integer constant");
+                ucount++;
+                ch = *p++;
+            } else {
+                break;
+            }
+        }
+
+        /* Determine if it needs 64 bits and/or unsigned in order to fit */
+        if (ucount == 0 && b == 10) {
+            if (lcount <= (LONG_SIZE == 4)) {
+                if (n >= 0x80000000U)
+                    lcount = (LONG_SIZE == 4) + 1;
+            }
+            if (n >= 0x8000000000000000ULL)
+                ov = 1, ucount = 1;
+        } else {
+            if (lcount <= (LONG_SIZE == 4)) {
+                if (n >= 0x100000000ULL)
+                    lcount = (LONG_SIZE == 4) + 1;
+                else if (n >= 0x80000000U)
+                    ucount = 1;
+            }
+            if (n >= 0x8000000000000000ULL)
+                ucount = 1;
+        }
+
+        if (ov)
+            tcc_warning("integer constant overflow");
+
+        tok = TOK_CINT;
+	if (lcount) {
+            tok = TOK_CLONG;
+            if (lcount == 2)
+                tok = TOK_CLLONG;
+	}
+	if (ucount)
+	    ++tok; /* TOK_CU... */
+        tokc.i = n;
+    }
+    if (ch)
+        tcc_error("invalid number\n");
+}
+
+
+#define PARSE2(c1, tok1, c2, tok2)              \
+    case c1:                                    \
+        PEEKC(c, p);                            \
+        if (c == c2) {                          \
+            p++;                                \
+            tok = tok2;                         \
+        } else {                                \
+            tok = tok1;                         \
+        }                                       \
+        break;
+
+/* return next token without macro substitution */
+static inline void next_nomacro1(void)
+{
+    int t, c, is_long, len;
+    TokenSym *ts;
+    uint8_t *p, *p1;
+    unsigned int h;
+
+    p = file->buf_ptr;
+ redo_no_start:
+    c = *p;
+    switch(c) {
+    case ' ':
+    case '\t':
+        tok = c;
+        p++;
+        if (parse_flags & PARSE_FLAG_SPACES)
+            goto keep_tok_flags;
+        while (isidnum_table[*p - CH_EOF] & IS_SPC)
+            ++p;
+        goto redo_no_start;
+    case '\f':
+    case '\v':
+    case '\r':
+        p++;
+        goto redo_no_start;
+    case '\\':
+        /* first look if it is in fact an end of buffer */
+        c = handle_stray1(p);
+        p = file->buf_ptr;
+        if (c == '\\')
+            goto parse_simple;
+        if (c != CH_EOF)
+            goto redo_no_start;
+        {
+            TCCState *s1 = tcc_state;
+            if ((parse_flags & PARSE_FLAG_LINEFEED)
+                && !(tok_flags & TOK_FLAG_EOF)) {
+                tok_flags |= TOK_FLAG_EOF;
+                tok = TOK_LINEFEED;
+                goto keep_tok_flags;
+            } else if (!(parse_flags & PARSE_FLAG_PREPROCESS)) {
+                tok = TOK_EOF;
+            } else if (s1->ifdef_stack_ptr != file->ifdef_stack_ptr) {
+                tcc_error("missing #endif");
+            } else if (s1->include_stack_ptr == s1->include_stack) {
+                /* no include left : end of file. */
+                tok = TOK_EOF;
+            } else {
+                tok_flags &= ~TOK_FLAG_EOF;
+                /* pop include file */
+                
+                /* test if previous '#endif' was after a #ifdef at
+                   start of file */
+                if (tok_flags & TOK_FLAG_ENDIF) {
+#ifdef INC_DEBUG
+                    printf("#endif %s\n", get_tok_str(file->ifndef_macro_saved, NULL));
+#endif
+                    search_cached_include(s1, file->filename, 1)
+                        ->ifndef_macro = file->ifndef_macro_saved;
+                    tok_flags &= ~TOK_FLAG_ENDIF;
+                }
+
+                /* add end of include file debug info */
+                if (tcc_state->do_debug) {
+                    put_stabd(N_EINCL, 0, 0);
+                }
+                /* pop include stack */
+                tcc_close();
+                s1->include_stack_ptr--;
+                p = file->buf_ptr;
+                if (p == file->buffer)
+                    tok_flags = TOK_FLAG_BOF|TOK_FLAG_BOL;
+                goto redo_no_start;
+            }
+        }
+        break;
+
+    case '\n':
+        file->line_num++;
+        tok_flags |= TOK_FLAG_BOL;
+        p++;
+maybe_newline:
+        if (0 == (parse_flags & PARSE_FLAG_LINEFEED))
+            goto redo_no_start;
+        tok = TOK_LINEFEED;
+        goto keep_tok_flags;
+
+    case '#':
+        /* XXX: simplify */
+        PEEKC(c, p);
+        if ((tok_flags & TOK_FLAG_BOL) && 
+            (parse_flags & PARSE_FLAG_PREPROCESS)) {
+            file->buf_ptr = p;
+            preprocess(tok_flags & TOK_FLAG_BOF);
+            p = file->buf_ptr;
+            goto maybe_newline;
+        } else {
+            if (c == '#') {
+                p++;
+                tok = TOK_TWOSHARPS;
+            } else {
+                if (parse_flags & PARSE_FLAG_ASM_FILE) {
+                    p = parse_line_comment(p - 1);
+                    goto redo_no_start;
+                } else {
+                    tok = '#';
+                }
+            }
+        }
+        break;
+    
+    /* dollar is allowed to start identifiers when not parsing asm */
+    case '$':
+        if (!(isidnum_table[c - CH_EOF] & IS_ID)
+         || (parse_flags & PARSE_FLAG_ASM_FILE))
+            goto parse_simple;
+
+    case 'a': case 'b': case 'c': case 'd':
+    case 'e': case 'f': case 'g': case 'h':
+    case 'i': case 'j': case 'k': case 'l':
+    case 'm': case 'n': case 'o': case 'p':
+    case 'q': case 'r': case 's': case 't':
+    case 'u': case 'v': case 'w': case 'x':
+    case 'y': case 'z': 
+    case 'A': case 'B': case 'C': case 'D':
+    case 'E': case 'F': case 'G': case 'H':
+    case 'I': case 'J': case 'K': 
+    case 'M': case 'N': case 'O': case 'P':
+    case 'Q': case 'R': case 'S': case 'T':
+    case 'U': case 'V': case 'W': case 'X':
+    case 'Y': case 'Z': 
+    case '_':
+    parse_ident_fast:
+        p1 = p;
+        h = TOK_HASH_INIT;
+        h = TOK_HASH_FUNC(h, c);
+        while (c = *++p, isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))
+            h = TOK_HASH_FUNC(h, c);
+        len = p - p1;
+        if (c != '\\') {
+            TokenSym **pts;
+
+            /* fast case : no stray found, so we have the full token
+               and we have already hashed it */
+            h &= (TOK_HASH_SIZE - 1);
+            pts = &hash_ident[h];
+            for(;;) {
+                ts = *pts;
+                if (!ts)
+                    break;
+                if (ts->len == len && !memcmp(ts->str, p1, len))
+                    goto token_found;
+                pts = &(ts->hash_next);
+            }
+            ts = tok_alloc_new(pts, (char *) p1, len);
+        token_found: ;
+        } else {
+            /* slower case */
+            cstr_reset(&tokcstr);
+            cstr_cat(&tokcstr, (char *) p1, len);
+            p--;
+            PEEKC(c, p);
+        parse_ident_slow:
+            while (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))
+            {
+                cstr_ccat(&tokcstr, c);
+                PEEKC(c, p);
+            }
+            ts = tok_alloc(tokcstr.data, tokcstr.size);
+        }
+        tok = ts->tok;
+        break;
+    case 'L':
+        t = p[1];
+        if (t != '\\' && t != '\'' && t != '\"') {
+            /* fast case */
+            goto parse_ident_fast;
+        } else {
+            PEEKC(c, p);
+            if (c == '\'' || c == '\"') {
+                is_long = 1;
+                goto str_const;
+            } else {
+                cstr_reset(&tokcstr);
+                cstr_ccat(&tokcstr, 'L');
+                goto parse_ident_slow;
+            }
+        }
+        break;
+
+    case '0': case '1': case '2': case '3':
+    case '4': case '5': case '6': case '7':
+    case '8': case '9':
+        t = c;
+        PEEKC(c, p);
+        /* after the first digit, accept digits, alpha, '.' or sign if
+           prefixed by 'eEpP' */
+    parse_num:
+        cstr_reset(&tokcstr);
+        for(;;) {
+            cstr_ccat(&tokcstr, t);
+            if (!((isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))
+                  || c == '.'
+                  || ((c == '+' || c == '-')
+                      && (((t == 'e' || t == 'E')
+                            && !(parse_flags & PARSE_FLAG_ASM_FILE
+                                /* 0xe+1 is 3 tokens in asm */
+                                && ((char*)tokcstr.data)[0] == '0'
+                                && toup(((char*)tokcstr.data)[1]) == 'X'))
+                          || t == 'p' || t == 'P'))))
+                break;
+            t = c;
+            PEEKC(c, p);
+        }
+        /* We add a trailing '\0' to ease parsing */
+        cstr_ccat(&tokcstr, '\0');
+        tokc.str.size = tokcstr.size;
+        tokc.str.data = tokcstr.data;
+        tok = TOK_PPNUM;
+        break;
+
+    case '.':
+        /* special dot handling because it can also start a number */
+        PEEKC(c, p);
+        if (isnum(c)) {
+            t = '.';
+            goto parse_num;
+        } else if ((isidnum_table['.' - CH_EOF] & IS_ID)
+                   && (isidnum_table[c - CH_EOF] & (IS_ID|IS_NUM))) {
+            *--p = c = '.';
+            goto parse_ident_fast;
+        } else if (c == '.') {
+            PEEKC(c, p);
+            if (c == '.') {
+                p++;
+                tok = TOK_DOTS;
+            } else {
+                *--p = '.'; /* may underflow into file->unget[] */
+                tok = '.';
+            }
+        } else {
+            tok = '.';
+        }
+        break;
+    case '\'':
+    case '\"':
+        is_long = 0;
+    str_const:
+        cstr_reset(&tokcstr);
+        if (is_long)
+            cstr_ccat(&tokcstr, 'L');
+        cstr_ccat(&tokcstr, c);
+        p = parse_pp_string(p, c, &tokcstr);
+        cstr_ccat(&tokcstr, c);
+        cstr_ccat(&tokcstr, '\0');
+        tokc.str.size = tokcstr.size;
+        tokc.str.data = tokcstr.data;
+        tok = TOK_PPSTR;
+        break;
+
+    case '<':
+        PEEKC(c, p);
+        if (c == '=') {
+            p++;
+            tok = TOK_LE;
+        } else if (c == '<') {
+            PEEKC(c, p);
+            if (c == '=') {
+                p++;
+                tok = TOK_A_SHL;
+            } else {
+                tok = TOK_SHL;
+            }
+        } else {
+            tok = TOK_LT;
+        }
+        break;
+    case '>':
+        PEEKC(c, p);
+        if (c == '=') {
+            p++;
+            tok = TOK_GE;
+        } else if (c == '>') {
+            PEEKC(c, p);
+            if (c == '=') {
+                p++;
+                tok = TOK_A_SAR;
+            } else {
+                tok = TOK_SAR;
+            }
+        } else {
+            tok = TOK_GT;
+        }
+        break;
+        
+    case '&':
+        PEEKC(c, p);
+        if (c == '&') {
+            p++;
+            tok = TOK_LAND;
+        } else if (c == '=') {
+            p++;
+            tok = TOK_A_AND;
+        } else {
+            tok = '&';
+        }
+        break;
+        
+    case '|':
+        PEEKC(c, p);
+        if (c == '|') {
+            p++;
+            tok = TOK_LOR;
+        } else if (c == '=') {
+            p++;
+            tok = TOK_A_OR;
+        } else {
+            tok = '|';
+        }
+        break;
+
+    case '+':
+        PEEKC(c, p);
+        if (c == '+') {
+            p++;
+            tok = TOK_INC;
+        } else if (c == '=') {
+            p++;
+            tok = TOK_A_ADD;
+        } else {
+            tok = '+';
+        }
+        break;
+        
+    case '-':
+        PEEKC(c, p);
+        if (c == '-') {
+            p++;
+            tok = TOK_DEC;
+        } else if (c == '=') {
+            p++;
+            tok = TOK_A_SUB;
+        } else if (c == '>') {
+            p++;
+            tok = TOK_ARROW;
+        } else {
+            tok = '-';
+        }
+        break;
+
+    PARSE2('!', '!', '=', TOK_NE)
+    PARSE2('=', '=', '=', TOK_EQ)
+    PARSE2('*', '*', '=', TOK_A_MUL)
+    PARSE2('%', '%', '=', TOK_A_MOD)
+    PARSE2('^', '^', '=', TOK_A_XOR)
+        
+        /* comments or operator */
+    case '/':
+        PEEKC(c, p);
+        if (c == '*') {
+            p = parse_comment(p);
+            /* comments replaced by a blank */
+            tok = ' ';
+            goto keep_tok_flags;
+        } else if (c == '/') {
+            p = parse_line_comment(p);
+            tok = ' ';
+            goto keep_tok_flags;
+        } else if (c == '=') {
+            p++;
+            tok = TOK_A_DIV;
+        } else {
+            tok = '/';
+        }
+        break;
+        
+        /* simple tokens */
+    case '(':
+    case ')':
+    case '[':
+    case ']':
+    case '{':
+    case '}':
+    case ',':
+    case ';':
+    case ':':
+    case '?':
+    case '~':
+    case '@': /* only used in assembler */
+    parse_simple:
+        tok = c;
+        p++;
+        break;
+    default:
+        if (c >= 0x80 && c <= 0xFF) /* utf8 identifiers */
+	    goto parse_ident_fast;
+        if (parse_flags & PARSE_FLAG_ASM_FILE)
+            goto parse_simple;
+        tcc_error("unrecognized character \\x%02x", c);
+        break;
+    }
+    tok_flags = 0;
+keep_tok_flags:
+    file->buf_ptr = p;
+#if defined(PARSE_DEBUG)
+    printf("token = %d %s\n", tok, get_tok_str(tok, &tokc));
+#endif
+}
+
+/* return next token without macro substitution. Can read input from
+   macro_ptr buffer */
+static void next_nomacro_spc(void)
+{
+    if (macro_ptr) {
+    redo:
+        tok = *macro_ptr;
+        if (tok) {
+            TOK_GET(&tok, &macro_ptr, &tokc);
+            if (tok == TOK_LINENUM) {
+                file->line_num = tokc.i;
+                goto redo;
+            }
+        }
+    } else {
+        next_nomacro1();
+    }
+    //printf("token = %s\n", get_tok_str(tok, &tokc));
+}
+
+ST_FUNC void next_nomacro(void)
+{
+    do {
+        next_nomacro_spc();
+    } while (tok < 256 && (isidnum_table[tok - CH_EOF] & IS_SPC));
+}
+ 
+
+static void macro_subst(
+    TokenString *tok_str,
+    Sym **nested_list,
+    const int *macro_str
+    );
+
+/* substitute arguments in replacement lists in macro_str by the values in
+   args (field d) and return allocated string */
+static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args)
+{
+    int t, t0, t1, spc;
+    const int *st;
+    Sym *s;
+    CValue cval;
+    TokenString str;
+    CString cstr;
+
+    tok_str_new(&str);
+    t0 = t1 = 0;
+    while(1) {
+        TOK_GET(&t, &macro_str, &cval);
+        if (!t)
+            break;
+        if (t == '#') {
+            /* stringize */
+            TOK_GET(&t, &macro_str, &cval);
+            if (!t)
+                goto bad_stringy;
+            s = sym_find2(args, t);
+            if (s) {
+                cstr_new(&cstr);
+                cstr_ccat(&cstr, '\"');
+                st = s->d;
+                spc = 0;
+                while (*st >= 0) {
+                    TOK_GET(&t, &st, &cval);
+                    if (t != TOK_PLCHLDR
+                     && t != TOK_NOSUBST
+                     && 0 == check_space(t, &spc)) {
+                        const char *s = get_tok_str(t, &cval);
+                        while (*s) {
+                            if (t == TOK_PPSTR && *s != '\'')
+                                add_char(&cstr, *s);
+                            else
+                                cstr_ccat(&cstr, *s);
+                            ++s;
+                        }
+                    }
+                }
+                cstr.size -= spc;
+                cstr_ccat(&cstr, '\"');
+                cstr_ccat(&cstr, '\0');
+#ifdef PP_DEBUG
+                printf("\nstringize: <%s>\n", (char *)cstr.data);
+#endif
+                /* add string */
+                cval.str.size = cstr.size;
+                cval.str.data = cstr.data;
+                tok_str_add2(&str, TOK_PPSTR, &cval);
+                cstr_free(&cstr);
+            } else {
+        bad_stringy:
+                expect("macro parameter after '#'");
+            }
+        } else if (t >= TOK_IDENT) {
+            s = sym_find2(args, t);
+            if (s) {
+                int l0 = str.len;
+                st = s->d;
+                /* if '##' is present before or after, no arg substitution */
+                if (*macro_str == TOK_PPJOIN || t1 == TOK_PPJOIN) {
+                    /* special case for var arg macros : ## eats the ','
+                       if empty VA_ARGS variable. */
+                    if (t1 == TOK_PPJOIN && t0 == ',' && gnu_ext && s->type.t) {
+                        if (*st <= 0) {
+                            /* suppress ',' '##' */
+                            str.len -= 2;
+                        } else {
+                            /* suppress '##' and add variable */
+                            str.len--;
+                            goto add_var;
+                        }
+                    }
+                } else {
+            add_var:
+		    if (!s->next) {
+			/* Expand arguments tokens and store them.  In most
+			   cases we could also re-expand each argument if
+			   used multiple times, but not if the argument
+			   contains the __COUNTER__ macro.  */
+			TokenString str2;
+			sym_push2(&s->next, s->v, s->type.t, 0);
+			tok_str_new(&str2);
+			macro_subst(&str2, nested_list, st);
+			tok_str_add(&str2, 0);
+			s->next->d = str2.str;
+		    }
+		    st = s->next->d;
+                }
+                for(;;) {
+                    int t2;
+                    TOK_GET(&t2, &st, &cval);
+                    if (t2 <= 0)
+                        break;
+                    tok_str_add2(&str, t2, &cval);
+                }
+                if (str.len == l0) /* expanded to empty string */
+                    tok_str_add(&str, TOK_PLCHLDR);
+            } else {
+                tok_str_add(&str, t);
+            }
+        } else {
+            tok_str_add2(&str, t, &cval);
+        }
+        t0 = t1, t1 = t;
+    }
+    tok_str_add(&str, 0);
+    return str.str;
+}
+
+static char const ab_month_name[12][4] =
+{
+    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+static int paste_tokens(int t1, CValue *v1, int t2, CValue *v2)
+{
+    CString cstr;
+    int n, ret = 1;
+
+    cstr_new(&cstr);
+    if (t1 != TOK_PLCHLDR)
+        cstr_cat(&cstr, get_tok_str(t1, v1), -1);
+    n = cstr.size;
+    if (t2 != TOK_PLCHLDR)
+        cstr_cat(&cstr, get_tok_str(t2, v2), -1);
+    cstr_ccat(&cstr, '\0');
+
+    tcc_open_bf(tcc_state, ":paste:", cstr.size);
+    memcpy(file->buffer, cstr.data, cstr.size);
+    tok_flags = 0;
+    for (;;) {
+        next_nomacro1();
+        if (0 == *file->buf_ptr)
+            break;
+        if (is_space(tok))
+            continue;
+        tcc_warning("pasting \"%.*s\" and \"%s\" does not give a valid"
+            " preprocessing token", n, cstr.data, (char*)cstr.data + n);
+        ret = 0;
+        break;
+    }
+    tcc_close();
+    //printf("paste <%s>\n", (char*)cstr.data);
+    cstr_free(&cstr);
+    return ret;
+}
+
+/* handle the '##' operator. Return NULL if no '##' seen. Otherwise
+   return the resulting string (which must be freed). */
+static inline int *macro_twosharps(const int *ptr0)
+{
+    int t;
+    CValue cval;
+    TokenString macro_str1;
+    int start_of_nosubsts = -1;
+    const int *ptr;
+
+    /* we search the first '##' */
+    for (ptr = ptr0;;) {
+        TOK_GET(&t, &ptr, &cval);
+        if (t == TOK_PPJOIN)
+            break;
+        if (t == 0)
+            return NULL;
+    }
+
+    tok_str_new(&macro_str1);
+
+    //tok_print(" $$$", ptr0);
+    for (ptr = ptr0;;) {
+        TOK_GET(&t, &ptr, &cval);
+        if (t == 0)
+            break;
+        if (t == TOK_PPJOIN)
+            continue;
+        while (*ptr == TOK_PPJOIN) {
+            int t1; CValue cv1;
+            /* given 'a##b', remove nosubsts preceding 'a' */
+            if (start_of_nosubsts >= 0)
+                macro_str1.len = start_of_nosubsts;
+            /* given 'a##b', remove nosubsts preceding 'b' */
+            while ((t1 = *++ptr) == TOK_NOSUBST)
+                ;
+            if (t1 && t1 != TOK_PPJOIN) {
+                TOK_GET(&t1, &ptr, &cv1);
+                if (t != TOK_PLCHLDR || t1 != TOK_PLCHLDR) {
+                    if (paste_tokens(t, &cval, t1, &cv1)) {
+                        t = tok, cval = tokc;
+                    } else {
+                        tok_str_add2(&macro_str1, t, &cval);
+                        t = t1, cval = cv1;
+                    }
+                }
+            }
+        }
+        if (t == TOK_NOSUBST) {
+            if (start_of_nosubsts < 0)
+                start_of_nosubsts = macro_str1.len;
+        } else {
+            start_of_nosubsts = -1;
+        }
+        tok_str_add2(&macro_str1, t, &cval);
+    }
+    tok_str_add(&macro_str1, 0);
+    //tok_print(" ###", macro_str1.str);
+    return macro_str1.str;
+}
+
+/* peek or read [ws_str == NULL] next token from function macro call,
+   walking up macro levels up to the file if necessary */
+static int next_argstream(Sym **nested_list, TokenString *ws_str)
+{
+    int t;
+    const int *p;
+    Sym *sa;
+
+    for (;;) {
+        if (macro_ptr) {
+            p = macro_ptr, t = *p;
+            if (ws_str) {
+                while (is_space(t) || TOK_LINEFEED == t || TOK_PLCHLDR == t)
+                    tok_str_add(ws_str, t), t = *++p;
+            }
+            if (t == 0) {
+                end_macro();
+                /* also, end of scope for nested defined symbol */
+                sa = *nested_list;
+                while (sa && sa->v == 0)
+                    sa = sa->prev;
+                if (sa)
+                    sa->v = 0;
+                continue;
+            }
+        } else {
+            ch = handle_eob();
+            if (ws_str) {
+                while (is_space(ch) || ch == '\n' || ch == '/') {
+                    if (ch == '/') {
+                        int c;
+                        uint8_t *p = file->buf_ptr;
+                        PEEKC(c, p);
+                        if (c == '*') {
+                            p = parse_comment(p);
+                            file->buf_ptr = p - 1;
+                        } else if (c == '/') {
+                            p = parse_line_comment(p);
+                            file->buf_ptr = p - 1;
+                        } else
+                            break;
+                        ch = ' ';
+                    }
+                    if (ch == '\n')
+                        file->line_num++;
+                    if (!(ch == '\f' || ch == '\v' || ch == '\r'))
+                        tok_str_add(ws_str, ch);
+                    cinp();
+                }
+            }
+            t = ch;
+        }
+
+        if (ws_str)
+            return t;
+        next_nomacro_spc();
+        return tok;
+    }
+}
+
+/* do macro substitution of current token with macro 's' and add
+   result to (tok_str,tok_len). 'nested_list' is the list of all
+   macros we got inside to avoid recursing. Return non zero if no
+   substitution needs to be done */
+static int macro_subst_tok(
+    TokenString *tok_str,
+    Sym **nested_list,
+    Sym *s)
+{
+    Sym *args, *sa, *sa1;
+    int parlevel, t, t1, spc;
+    TokenString str;
+    char *cstrval;
+    CValue cval;
+    CString cstr;
+    char buf[32];
+
+    /* if symbol is a macro, prepare substitution */
+    /* special macros */
+    if (tok == TOK___LINE__ || tok == TOK___COUNTER__) {
+        t = tok == TOK___LINE__ ? file->line_num : pp_counter++;
+        snprintf(buf, sizeof(buf), "%d", t);
+        cstrval = buf;
+        t1 = TOK_PPNUM;
+        goto add_cstr1;
+    } else if (tok == TOK___FILE__) {
+        cstrval = file->filename;
+        goto add_cstr;
+    } else if (tok == TOK___DATE__ || tok == TOK___TIME__) {
+        time_t ti;
+        struct tm *tm;
+
+        time(&ti);
+        tm = localtime(&ti);
+        if (tok == TOK___DATE__) {
+            snprintf(buf, sizeof(buf), "%s %2d %d", 
+                     ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900);
+        } else {
+            snprintf(buf, sizeof(buf), "%02d:%02d:%02d", 
+                     tm->tm_hour, tm->tm_min, tm->tm_sec);
+        }
+        cstrval = buf;
+    add_cstr:
+        t1 = TOK_STR;
+    add_cstr1:
+        cstr_new(&cstr);
+        cstr_cat(&cstr, cstrval, 0);
+        cval.str.size = cstr.size;
+        cval.str.data = cstr.data;
+        tok_str_add2(tok_str, t1, &cval);
+        cstr_free(&cstr);
+    } else if (s->d) {
+        int saved_parse_flags = parse_flags;
+	int *joined_str = NULL;
+        int *mstr = s->d;
+
+        if (s->type.t == MACRO_FUNC) {
+            /* whitespace between macro name and argument list */
+            TokenString ws_str;
+            tok_str_new(&ws_str);
+
+            spc = 0;
+            parse_flags |= PARSE_FLAG_SPACES | PARSE_FLAG_LINEFEED
+                | PARSE_FLAG_ACCEPT_STRAYS;
+
+            /* get next token from argument stream */
+            t = next_argstream(nested_list, &ws_str);
+            if (t != '(') {
+                /* not a macro substitution after all, restore the
+                 * macro token plus all whitespace we've read.
+                 * whitespace is intentionally not merged to preserve
+                 * newlines. */
+                parse_flags = saved_parse_flags;
+                tok_str_add(tok_str, tok);
+                if (parse_flags & PARSE_FLAG_SPACES) {
+                    int i;
+                    for (i = 0; i < ws_str.len; i++)
+                        tok_str_add(tok_str, ws_str.str[i]);
+                }
+                tok_str_free_str(ws_str.str);
+                return 0;
+            } else {
+                tok_str_free_str(ws_str.str);
+            }
+	    do {
+		next_nomacro(); /* eat '(' */
+	    } while (tok == TOK_PLCHLDR);
+
+            /* argument macro */
+            args = NULL;
+            sa = s->next;
+            /* NOTE: empty args are allowed, except if no args */
+            for(;;) {
+                do {
+                    next_argstream(nested_list, NULL);
+                } while (is_space(tok) || TOK_LINEFEED == tok);
+    empty_arg:
+                /* handle '()' case */
+                if (!args && !sa && tok == ')')
+                    break;
+                if (!sa)
+                    tcc_error("macro '%s' used with too many args",
+                          get_tok_str(s->v, 0));
+                tok_str_new(&str);
+                parlevel = spc = 0;
+                /* NOTE: non zero sa->t indicates VA_ARGS */
+                while ((parlevel > 0 || 
+                        (tok != ')' && 
+                         (tok != ',' || sa->type.t)))) {
+                    if (tok == TOK_EOF || tok == 0)
+                        break;
+                    if (tok == '(')
+                        parlevel++;
+                    else if (tok == ')')
+                        parlevel--;
+                    if (tok == TOK_LINEFEED)
+                        tok = ' ';
+                    if (!check_space(tok, &spc))
+                        tok_str_add2(&str, tok, &tokc);
+                    next_argstream(nested_list, NULL);
+                }
+                if (parlevel)
+                    expect(")");
+                str.len -= spc;
+                tok_str_add(&str, -1);
+                tok_str_add(&str, 0);
+                sa1 = sym_push2(&args, sa->v & ~SYM_FIELD, sa->type.t, 0);
+                sa1->d = str.str;
+                sa = sa->next;
+                if (tok == ')') {
+                    /* special case for gcc var args: add an empty
+                       var arg argument if it is omitted */
+                    if (sa && sa->type.t && gnu_ext)
+                        goto empty_arg;
+                    break;
+                }
+                if (tok != ',')
+                    expect(",");
+            }
+            if (sa) {
+                tcc_error("macro '%s' used with too few args",
+                      get_tok_str(s->v, 0));
+            }
+
+            parse_flags = saved_parse_flags;
+
+            /* now subst each arg */
+            mstr = macro_arg_subst(nested_list, mstr, args);
+            /* free memory */
+            sa = args;
+            while (sa) {
+                sa1 = sa->prev;
+                tok_str_free_str(sa->d);
+                if (sa->next) {
+                    tok_str_free_str(sa->next->d);
+                    sym_free(sa->next);
+                }
+                sym_free(sa);
+                sa = sa1;
+            }
+        }
+
+        sym_push2(nested_list, s->v, 0, 0);
+        parse_flags = saved_parse_flags;
+        joined_str = macro_twosharps(mstr);
+        macro_subst(tok_str, nested_list, joined_str ? joined_str : mstr);
+
+        /* pop nested defined symbol */
+        sa1 = *nested_list;
+        *nested_list = sa1->prev;
+        sym_free(sa1);
+	if (joined_str)
+	    tok_str_free_str(joined_str);
+        if (mstr != s->d)
+            tok_str_free_str(mstr);
+    }
+    return 0;
+}
+
+/* do macro substitution of macro_str and add result to
+   (tok_str,tok_len). 'nested_list' is the list of all macros we got
+   inside to avoid recursing. */
+static void macro_subst(
+    TokenString *tok_str,
+    Sym **nested_list,
+    const int *macro_str
+    )
+{
+    Sym *s;
+    int t, spc, nosubst;
+    CValue cval;
+    
+    spc = nosubst = 0;
+
+    while (1) {
+        TOK_GET(&t, &macro_str, &cval);
+        if (t <= 0)
+            break;
+
+        if (t >= TOK_IDENT && 0 == nosubst) {
+            s = define_find(t);
+            if (s == NULL)
+                goto no_subst;
+
+            /* if nested substitution, do nothing */
+            if (sym_find2(*nested_list, t)) {
+                /* and mark it as TOK_NOSUBST, so it doesn't get subst'd again */
+                tok_str_add2(tok_str, TOK_NOSUBST, NULL);
+                goto no_subst;
+            }
+
+            {
+                TokenString str;
+                str.str = (int*)macro_str;
+                begin_macro(&str, 2);
+
+                tok = t;
+                macro_subst_tok(tok_str, nested_list, s);
+
+                if (str.alloc == 3) {
+                    /* already finished by reading function macro arguments */
+                    break;
+                }
+
+                macro_str = macro_ptr;
+                end_macro ();
+            }
+            if (tok_str->len)
+                spc = is_space(t = tok_str->str[tok_str->lastlen]);
+        } else {
+            if (t == '\\' && !(parse_flags & PARSE_FLAG_ACCEPT_STRAYS))
+                tcc_error("stray '\\' in program");
+no_subst:
+            if (!check_space(t, &spc))
+                tok_str_add2(tok_str, t, &cval);
+
+            if (nosubst) {
+                if (nosubst > 1 && (spc || (++nosubst == 3 && t == '(')))
+                    continue;
+                nosubst = 0;
+            }
+            if (t == TOK_NOSUBST)
+                nosubst = 1;
+        }
+        /* GCC supports 'defined' as result of a macro substitution */
+        if (t == TOK_DEFINED && pp_expr)
+            nosubst = 2;
+    }
+}
+
+/* return next token with macro substitution */
+ST_FUNC void next(void)
+{
+ redo:
+    if (parse_flags & PARSE_FLAG_SPACES)
+        next_nomacro_spc();
+    else
+        next_nomacro();
+
+    if (macro_ptr) {
+        if (tok == TOK_NOSUBST || tok == TOK_PLCHLDR) {
+        /* discard preprocessor markers */
+            goto redo;
+        } else if (tok == 0) {
+            /* end of macro or unget token string */
+            end_macro();
+            goto redo;
+        }
+    } else if (tok >= TOK_IDENT && (parse_flags & PARSE_FLAG_PREPROCESS)) {
+        Sym *s;
+        /* if reading from file, try to substitute macros */
+        s = define_find(tok);
+        if (s) {
+            Sym *nested_list = NULL;
+            tokstr_buf.len = 0;
+            macro_subst_tok(&tokstr_buf, &nested_list, s);
+            tok_str_add(&tokstr_buf, 0);
+            begin_macro(&tokstr_buf, 2);
+            goto redo;
+        }
+    }
+    /* convert preprocessor tokens into C tokens */
+    if (tok == TOK_PPNUM) {
+        if  (parse_flags & PARSE_FLAG_TOK_NUM)
+            parse_number((char *)tokc.str.data);
+    } else if (tok == TOK_PPSTR) {
+        if (parse_flags & PARSE_FLAG_TOK_STR)
+            parse_string((char *)tokc.str.data, tokc.str.size - 1);
+    }
+}
+
+/* push back current token and set current token to 'last_tok'. Only
+   identifier case handled for labels. */
+ST_INLN void unget_tok(int last_tok)
+{
+
+    TokenString *str = tok_str_alloc();
+    tok_str_add2(str, tok, &tokc);
+    tok_str_add(str, 0);
+    begin_macro(str, 1);
+    tok = last_tok;
+}
+
+ST_FUNC void preprocess_start(TCCState *s1, int is_asm)
+{
+    CString cstr;
+    int i;
+
+    s1->include_stack_ptr = s1->include_stack;
+    s1->ifdef_stack_ptr = s1->ifdef_stack;
+    file->ifdef_stack_ptr = s1->ifdef_stack_ptr;
+    pp_expr = 0;
+    pp_counter = 0;
+    pp_debug_tok = pp_debug_symv = 0;
+    pp_once++;
+    pvtop = vtop = vstack - 1;
+    s1->pack_stack[0] = 0;
+    s1->pack_stack_ptr = s1->pack_stack;
+
+    set_idnum('$', s1->dollars_in_identifiers ? IS_ID : 0);
+    set_idnum('.', is_asm ? IS_ID : 0);
+
+    cstr_new(&cstr);
+    cstr_cat(&cstr, "\"", -1);
+    cstr_cat(&cstr, file->filename, -1);
+    cstr_cat(&cstr, "\"", 0);
+    tcc_define_symbol(s1, "__BASE_FILE__", cstr.data);
+
+    cstr_reset(&cstr);
+    for (i = 0; i < s1->nb_cmd_include_files; i++) {
+        cstr_cat(&cstr, "#include \"", -1);
+        cstr_cat(&cstr, s1->cmd_include_files[i], -1);
+        cstr_cat(&cstr, "\"\n", -1);
+    }
+    if (cstr.size) {
+        *s1->include_stack_ptr++ = file;
+	tcc_open_bf(s1, "<command line>", cstr.size);
+	memcpy(file->buffer, cstr.data, cstr.size);
+    }
+    cstr_free(&cstr);
+
+    if (is_asm)
+        tcc_define_symbol(s1, "__ASSEMBLER__", NULL);
+
+    parse_flags = is_asm ? PARSE_FLAG_ASM_FILE : 0;
+    tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
+}
+
+/* cleanup from error/setjmp */
+ST_FUNC void preprocess_end(TCCState *s1)
+{
+    while (macro_stack)
+        end_macro();
+    macro_ptr = NULL;
+}
+
+ST_FUNC void tccpp_new(TCCState *s)
+{
+    int i, c;
+    const char *p, *r;
+
+    /* might be used in error() before preprocess_start() */
+    s->include_stack_ptr = s->include_stack;
+    s->ppfp = stdout;
+
+    /* init isid table */
+    for(i = CH_EOF; i<128; i++)
+        set_idnum(i,
+            is_space(i) ? IS_SPC
+            : isid(i) ? IS_ID
+            : isnum(i) ? IS_NUM
+            : 0);
+
+    for(i = 128; i<256; i++)
+        set_idnum(i, IS_ID);
+
+    /* init allocators */
+    tal_new(&toksym_alloc, TOKSYM_TAL_LIMIT, TOKSYM_TAL_SIZE);
+    tal_new(&tokstr_alloc, TOKSTR_TAL_LIMIT, TOKSTR_TAL_SIZE);
+    tal_new(&cstr_alloc, CSTR_TAL_LIMIT, CSTR_TAL_SIZE);
+
+    memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
+    cstr_new(&cstr_buf);
+    cstr_realloc(&cstr_buf, STRING_MAX_SIZE);
+    tok_str_new(&tokstr_buf);
+    tok_str_realloc(&tokstr_buf, TOKSTR_MAX_SIZE);
+    
+    tok_ident = TOK_IDENT;
+    p = tcc_keywords;
+    while (*p) {
+        r = p;
+        for(;;) {
+            c = *r++;
+            if (c == '\0')
+                break;
+        }
+        tok_alloc(p, r - p - 1);
+        p = r;
+    }
+}
+
+ST_FUNC void tccpp_delete(TCCState *s)
+{
+    int i, n;
+
+    /* free -D and compiler defines */
+    free_defines(NULL);
+
+    /* free tokens */
+    n = tok_ident - TOK_IDENT;
+    for(i = 0; i < n; i++)
+        tal_free(toksym_alloc, table_ident[i]);
+    tcc_free(table_ident);
+    table_ident = NULL;
+
+    /* free static buffers */
+    cstr_free(&tokcstr);
+    cstr_free(&cstr_buf);
+    cstr_free(&macro_equal_buf);
+    tok_str_free_str(tokstr_buf.str);
+
+    /* free allocators */
+    tal_delete(toksym_alloc);
+    toksym_alloc = NULL;
+    tal_delete(tokstr_alloc);
+    tokstr_alloc = NULL;
+    tal_delete(cstr_alloc);
+    cstr_alloc = NULL;
+}
+
+/* ------------------------------------------------------------------------- */
+/* tcc -E [-P[1]] [-dD} support */
+
+static void tok_print(const char *msg, const int *str)
+{
+    FILE *fp;
+    int t, s = 0;
+    CValue cval;
+
+    fp = tcc_state->ppfp;
+    fprintf(fp, "%s", msg);
+    while (str) {
+	TOK_GET(&t, &str, &cval);
+	if (!t)
+	    break;
+	fprintf(fp, " %s" + s, get_tok_str(t, &cval)), s = 1;
+    }
+    fprintf(fp, "\n");
+}
+
+static void pp_line(TCCState *s1, BufferedFile *f, int level)
+{
+    int d = f->line_num - f->line_ref;
+
+    if (s1->dflag & 4)
+	return;
+
+    if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_NONE) {
+        ;
+    } else if (level == 0 && f->line_ref && d < 8) {
+	while (d > 0)
+	    fputs("\n", s1->ppfp), --d;
+    } else if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_STD) {
+	fprintf(s1->ppfp, "#line %d \"%s\"\n", f->line_num, f->filename);
+    } else {
+	fprintf(s1->ppfp, "# %d \"%s\"%s\n", f->line_num, f->filename,
+	    level > 0 ? " 1" : level < 0 ? " 2" : "");
+    }
+    f->line_ref = f->line_num;
+}
+
+static void define_print(TCCState *s1, int v)
+{
+    FILE *fp;
+    Sym *s;
+
+    s = define_find(v);
+    if (NULL == s || NULL == s->d)
+        return;
+
+    fp = s1->ppfp;
+    fprintf(fp, "#define %s", get_tok_str(v, NULL));
+    if (s->type.t == MACRO_FUNC) {
+        Sym *a = s->next;
+        fprintf(fp,"(");
+        if (a)
+            for (;;) {
+                fprintf(fp,"%s", get_tok_str(a->v & ~SYM_FIELD, NULL));
+                if (!(a = a->next))
+                    break;
+                fprintf(fp,",");
+            }
+        fprintf(fp,")");
+    }
+    tok_print("", s->d);
+}
+
+static void pp_debug_defines(TCCState *s1)
+{
+    int v, t;
+    const char *vs;
+    FILE *fp;
+
+    t = pp_debug_tok;
+    if (t == 0)
+        return;
+
+    file->line_num--;
+    pp_line(s1, file, 0);
+    file->line_ref = ++file->line_num;
+
+    fp = s1->ppfp;
+    v = pp_debug_symv;
+    vs = get_tok_str(v, NULL);
+    if (t == TOK_DEFINE) {
+        define_print(s1, v);
+    } else if (t == TOK_UNDEF) {
+        fprintf(fp, "#undef %s\n", vs);
+    } else if (t == TOK_push_macro) {
+        fprintf(fp, "#pragma push_macro(\"%s\")\n", vs);
+    } else if (t == TOK_pop_macro) {
+        fprintf(fp, "#pragma pop_macro(\"%s\")\n", vs);
+    }
+    pp_debug_tok = 0;
+}
+
+static void pp_debug_builtins(TCCState *s1)
+{
+    int v;
+    for (v = TOK_IDENT; v < tok_ident; ++v)
+        define_print(s1, v);
+}
+
+/* Add a space between tokens a and b to avoid unwanted textual pasting */
+static int pp_need_space(int a, int b)
+{
+    return 'E' == a ? '+' == b || '-' == b
+        : '+' == a ? TOK_INC == b || '+' == b
+        : '-' == a ? TOK_DEC == b || '-' == b
+        : a >= TOK_IDENT ? b >= TOK_IDENT
+	: a == TOK_PPNUM ? b >= TOK_IDENT
+        : 0;
+}
+
+/* maybe hex like 0x1e */
+static int pp_check_he0xE(int t, const char *p)
+{
+    if (t == TOK_PPNUM && toup(strchr(p, 0)[-1]) == 'E')
+        return 'E';
+    return t;
+}
+
+/* Preprocess the current file */
+ST_FUNC int tcc_preprocess(TCCState *s1)
+{
+    BufferedFile **iptr;
+    int token_seen, spcs, level;
+    const char *p;
+    char white[400];
+
+    parse_flags = PARSE_FLAG_PREPROCESS
+                | (parse_flags & PARSE_FLAG_ASM_FILE)
+                | PARSE_FLAG_LINEFEED
+                | PARSE_FLAG_SPACES
+                | PARSE_FLAG_ACCEPT_STRAYS
+                ;
+    /* Credits to Fabrice Bellard's initial revision to demonstrate its
+       capability to compile and run itself, provided all numbers are
+       given as decimals. tcc -E -P10 will do. */
+    if (s1->Pflag == LINE_MACRO_OUTPUT_FORMAT_P10)
+        parse_flags |= PARSE_FLAG_TOK_NUM, s1->Pflag = 1;
+
+#ifdef PP_BENCH
+    /* for PP benchmarks */
+    do next(); while (tok != TOK_EOF);
+    return 0;
+#endif
+
+    if (s1->dflag & 1) {
+        pp_debug_builtins(s1);
+        s1->dflag &= ~1;
+    }
+
+    token_seen = TOK_LINEFEED, spcs = 0;
+    pp_line(s1, file, 0);
+    for (;;) {
+        iptr = s1->include_stack_ptr;
+        next();
+        if (tok == TOK_EOF)
+            break;
+
+        level = s1->include_stack_ptr - iptr;
+        if (level) {
+            if (level > 0)
+                pp_line(s1, *iptr, 0);
+            pp_line(s1, file, level);
+        }
+        if (s1->dflag & 7) {
+            pp_debug_defines(s1);
+            if (s1->dflag & 4)
+                continue;
+        }
+
+        if (is_space(tok)) {
+            if (spcs < sizeof white - 1)
+                white[spcs++] = tok;
+            continue;
+        } else if (tok == TOK_LINEFEED) {
+            spcs = 0;
+            if (token_seen == TOK_LINEFEED)
+                continue;
+            ++file->line_ref;
+        } else if (token_seen == TOK_LINEFEED) {
+            pp_line(s1, file, 0);
+        } else if (spcs == 0 && pp_need_space(token_seen, tok)) {
+            white[spcs++] = ' ';
+        }
+
+        white[spcs] = 0, fputs(white, s1->ppfp), spcs = 0;
+        fputs(p = get_tok_str(tok, &tokc), s1->ppfp);
+        token_seen = pp_check_he0xE(tok, p);
+    }
+    return 0;
+}
+
+/* ------------------------------------------------------------------------- */
Index: EcnlProtoTool/trunk/tcc-0.9.27/tccrun.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tccrun.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tccrun.c	(revision 331)
@@ -0,0 +1,930 @@
+/*
+ *  TCC - Tiny C Compiler - Support for -run switch
+ *
+ *  Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "tcc.h"
+
+/* only native compiler supports -run */
+#ifdef TCC_IS_NATIVE
+
+#ifndef _WIN32
+# include <sys/mman.h>
+#endif
+
+#ifdef CONFIG_TCC_BACKTRACE
+# ifndef _WIN32
+#  include <signal.h>
+#  ifndef __OpenBSD__
+#   include <sys/ucontext.h>
+#  endif
+# else
+#  define ucontext_t CONTEXT
+# endif
+ST_DATA int rt_num_callers = 6;
+ST_DATA const char **rt_bound_error_msg;
+ST_DATA void *rt_prog_main;
+static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level);
+static void rt_error(ucontext_t *uc, const char *fmt, ...);
+static void set_exception_handler(void);
+#endif
+
+static void set_pages_executable(void *ptr, unsigned long length);
+static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff);
+
+#ifdef _WIN64
+static void *win64_add_function_table(TCCState *s1);
+static void win64_del_function_table(void *);
+#endif
+
+/* ------------------------------------------------------------- */
+/* Do all relocations (needed before using tcc_get_symbol())
+   Returns -1 on error. */
+
+LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr)
+{
+    int size;
+    addr_t ptr_diff = 0;
+
+    if (TCC_RELOCATE_AUTO != ptr)
+        return tcc_relocate_ex(s1, ptr, 0);
+
+    size = tcc_relocate_ex(s1, NULL, 0);
+    if (size < 0)
+        return -1;
+
+#ifdef HAVE_SELINUX
+{
+    /* Using mmap instead of malloc */
+    void *prx;
+    char tmpfname[] = "/tmp/.tccrunXXXXXX";
+    int fd = mkstemp(tmpfname);
+    unlink(tmpfname);
+    ftruncate(fd, size);
+
+    ptr = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+    prx = mmap (NULL, size, PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0);
+    if (ptr == MAP_FAILED || prx == MAP_FAILED)
+	tcc_error("tccrun: could not map memory");
+    dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size);
+    dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, prx);
+    ptr_diff = (char*)prx - (char*)ptr;
+}
+#else
+    ptr = tcc_malloc(size);
+#endif
+    tcc_relocate_ex(s1, ptr, ptr_diff); /* no more errors expected */
+    dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, ptr);
+    return 0;
+}
+
+ST_FUNC void tcc_run_free(TCCState *s1)
+{
+    int i;
+
+    for (i = 0; i < s1->nb_runtime_mem; ++i) {
+#ifdef HAVE_SELINUX
+        unsigned size = (unsigned)(addr_t)s1->runtime_mem[i++];
+        munmap(s1->runtime_mem[i++], size);
+        munmap(s1->runtime_mem[i], size);
+#else
+#ifdef _WIN64
+        win64_del_function_table(*(void**)s1->runtime_mem[i]);
+#endif
+        tcc_free(s1->runtime_mem[i]);
+#endif
+    }
+    tcc_free(s1->runtime_mem);
+}
+
+/* launch the compiled program with the given arguments */
+LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
+{
+    int (*prog_main)(int, char **);
+
+    s1->runtime_main = "main";
+    if ((s1->dflag & 16) && !find_elf_sym(s1->symtab, s1->runtime_main))
+        return 0;
+    if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
+        return -1;
+    prog_main = tcc_get_symbol_err(s1, s1->runtime_main);
+
+#ifdef CONFIG_TCC_BACKTRACE
+    if (s1->do_debug) {
+        set_exception_handler();
+        rt_prog_main = prog_main;
+    }
+#endif
+
+    errno = 0; /* clean errno value */
+
+#ifdef CONFIG_TCC_BCHECK
+    if (s1->do_bounds_check) {
+        void (*bound_init)(void);
+        void (*bound_exit)(void);
+        void (*bound_new_region)(void *p, addr_t size);
+        int  (*bound_delete_region)(void *p);
+        int i, ret;
+
+        /* set error function */
+        rt_bound_error_msg = tcc_get_symbol_err(s1, "__bound_error_msg");
+        /* XXX: use .init section so that it also work in binary ? */
+        bound_init = tcc_get_symbol_err(s1, "__bound_init");
+        bound_exit = tcc_get_symbol_err(s1, "__bound_exit");
+        bound_new_region = tcc_get_symbol_err(s1, "__bound_new_region");
+        bound_delete_region = tcc_get_symbol_err(s1, "__bound_delete_region");
+
+        bound_init();
+        /* mark argv area as valid */
+        bound_new_region(argv, argc*sizeof(argv[0]));
+        for (i=0; i<argc; ++i)
+            bound_new_region(argv[i], strlen(argv[i]) + 1);
+
+        ret = (*prog_main)(argc, argv);
+
+        /* unmark argv area */
+        for (i=0; i<argc; ++i)
+            bound_delete_region(argv[i]);
+        bound_delete_region(argv);
+        bound_exit();
+        return ret;
+    }
+#endif
+    return (*prog_main)(argc, argv);
+}
+
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+ #define RUN_SECTION_ALIGNMENT 63
+#else
+ #define RUN_SECTION_ALIGNMENT 15
+#endif
+
+/* relocate code. Return -1 on error, required size if ptr is NULL,
+   otherwise copy code into buffer passed by the caller */
+static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff)
+{
+    Section *s;
+    unsigned offset, length, fill, i, k;
+    addr_t mem;
+
+    if (NULL == ptr) {
+        s1->nb_errors = 0;
+#ifdef TCC_TARGET_PE
+        pe_output_file(s1, NULL);
+#else
+        tcc_add_runtime(s1);
+	resolve_common_syms(s1);
+        build_got_entries(s1);
+#endif
+        if (s1->nb_errors)
+            return -1;
+    }
+
+    offset = 0, mem = (addr_t)ptr;
+    fill = -mem & RUN_SECTION_ALIGNMENT;
+#ifdef _WIN64
+    offset += sizeof (void*);
+#endif
+    for (k = 0; k < 2; ++k) {
+        for(i = 1; i < s1->nb_sections; i++) {
+            s = s1->sections[i];
+            if (0 == (s->sh_flags & SHF_ALLOC))
+                continue;
+            if (k != !(s->sh_flags & SHF_EXECINSTR))
+                continue;
+            offset += fill;
+            if (!mem)
+                s->sh_addr = 0;
+            else if (s->sh_flags & SHF_EXECINSTR)
+                s->sh_addr = mem + offset + ptr_diff;
+            else
+                s->sh_addr = mem + offset;
+#if 0
+            if (mem)
+                printf("%-16s +%02lx %p %04x\n",
+                    s->name, fill, (void*)s->sh_addr, (unsigned)s->data_offset);
+#endif
+            offset += s->data_offset;
+            fill = -(mem + offset) & 15;
+        }
+#if RUN_SECTION_ALIGNMENT > 15
+        /* To avoid that x86 processors would reload cached instructions each time
+           when data is written in the near, we need to make sure that code and data
+           do not share the same 64 byte unit */
+        fill = -(mem + offset) & RUN_SECTION_ALIGNMENT;
+#endif
+    }
+
+    /* relocate symbols */
+    relocate_syms(s1, s1->symtab, 1);
+    if (s1->nb_errors)
+        return -1;
+
+    if (0 == mem)
+        return offset + RUN_SECTION_ALIGNMENT;
+
+#ifdef TCC_TARGET_PE
+    s1->pe_imagebase = mem;
+#endif
+
+    /* relocate each section */
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+        if (s->reloc)
+            relocate_section(s1, s);
+    }
+    relocate_plt(s1);
+
+    for(i = 1; i < s1->nb_sections; i++) {
+        s = s1->sections[i];
+        if (0 == (s->sh_flags & SHF_ALLOC))
+            continue;
+        length = s->data_offset;
+        ptr = (void*)s->sh_addr;
+        if (s->sh_flags & SHF_EXECINSTR)
+            ptr = (char*)ptr - ptr_diff;
+        if (NULL == s->data || s->sh_type == SHT_NOBITS)
+            memset(ptr, 0, length);
+        else
+            memcpy(ptr, s->data, length);
+        /* mark executable sections as executable in memory */
+        if (s->sh_flags & SHF_EXECINSTR)
+            set_pages_executable((char*)ptr + ptr_diff, length);
+    }
+
+#ifdef _WIN64
+    *(void**)mem = win64_add_function_table(s1);
+#endif
+
+    return 0;
+}
+
+/* ------------------------------------------------------------- */
+/* allow to run code in memory */
+
+static void set_pages_executable(void *ptr, unsigned long length)
+{
+#ifdef _WIN32
+    unsigned long old_protect;
+    VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect);
+#else
+    void __clear_cache(void *beginning, void *end);
+# ifndef HAVE_SELINUX
+    addr_t start, end;
+#  ifndef PAGESIZE
+#   define PAGESIZE 4096
+#  endif
+    start = (addr_t)ptr & ~(PAGESIZE - 1);
+    end = (addr_t)ptr + length;
+    end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1);
+    if (mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC))
+        tcc_error("mprotect failed: did you mean to configure --with-selinux?");
+# endif
+# if defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64
+    __clear_cache(ptr, (char *)ptr + length);
+# endif
+#endif
+}
+
+#ifdef _WIN64
+static void *win64_add_function_table(TCCState *s1)
+{
+    void *p = NULL;
+    if (s1->uw_pdata) {
+        p = (void*)s1->uw_pdata->sh_addr;
+        RtlAddFunctionTable(
+            (RUNTIME_FUNCTION*)p,
+            s1->uw_pdata->data_offset / sizeof (RUNTIME_FUNCTION),
+            s1->pe_imagebase
+            );
+        s1->uw_pdata = NULL;
+    }
+    return p;
+}
+
+static void win64_del_function_table(void *p)
+{
+    if (p) {
+        RtlDeleteFunctionTable((RUNTIME_FUNCTION*)p);
+    }
+}
+#endif
+
+/* ------------------------------------------------------------- */
+#ifdef CONFIG_TCC_BACKTRACE
+
+ST_FUNC void tcc_set_num_callers(int n)
+{
+    rt_num_callers = n;
+}
+
+/* print the position in the source file of PC value 'pc' by reading
+   the stabs debug information */
+static addr_t rt_printline(addr_t wanted_pc, const char *msg)
+{
+    char func_name[128], last_func_name[128];
+    addr_t func_addr, last_pc, pc;
+    const char *incl_files[INCLUDE_STACK_SIZE];
+    int incl_index, len, last_line_num, i;
+    const char *str, *p;
+
+    Stab_Sym *stab_sym = NULL, *stab_sym_end, *sym;
+    int stab_len = 0;
+    char *stab_str = NULL;
+
+    if (stab_section) {
+        stab_len = stab_section->data_offset;
+        stab_sym = (Stab_Sym *)stab_section->data;
+        stab_str = (char *) stabstr_section->data;
+    }
+
+    func_name[0] = '\0';
+    func_addr = 0;
+    incl_index = 0;
+    last_func_name[0] = '\0';
+    last_pc = (addr_t)-1;
+    last_line_num = 1;
+
+    if (!stab_sym)
+        goto no_stabs;
+
+    stab_sym_end = (Stab_Sym*)((char*)stab_sym + stab_len);
+    for (sym = stab_sym + 1; sym < stab_sym_end; ++sym) {
+        switch(sym->n_type) {
+            /* function start or end */
+        case N_FUN:
+            if (sym->n_strx == 0) {
+                /* we test if between last line and end of function */
+                pc = sym->n_value + func_addr;
+                if (wanted_pc >= last_pc && wanted_pc < pc)
+                    goto found;
+                func_name[0] = '\0';
+                func_addr = 0;
+            } else {
+                str = stab_str + sym->n_strx;
+                p = strchr(str, ':');
+                if (!p) {
+                    pstrcpy(func_name, sizeof(func_name), str);
+                } else {
+                    len = p - str;
+                    if (len > sizeof(func_name) - 1)
+                        len = sizeof(func_name) - 1;
+                    memcpy(func_name, str, len);
+                    func_name[len] = '\0';
+                }
+                func_addr = sym->n_value;
+            }
+            break;
+            /* line number info */
+        case N_SLINE:
+            pc = sym->n_value + func_addr;
+            if (wanted_pc >= last_pc && wanted_pc < pc)
+                goto found;
+            last_pc = pc;
+            last_line_num = sym->n_desc;
+            /* XXX: slow! */
+            strcpy(last_func_name, func_name);
+            break;
+            /* include files */
+        case N_BINCL:
+            str = stab_str + sym->n_strx;
+        add_incl:
+            if (incl_index < INCLUDE_STACK_SIZE) {
+                incl_files[incl_index++] = str;
+            }
+            break;
+        case N_EINCL:
+            if (incl_index > 1)
+                incl_index--;
+            break;
+        case N_SO:
+            if (sym->n_strx == 0) {
+                incl_index = 0; /* end of translation unit */
+            } else {
+                str = stab_str + sym->n_strx;
+                /* do not add path */
+                len = strlen(str);
+                if (len > 0 && str[len - 1] != '/')
+                    goto add_incl;
+            }
+            break;
+        }
+    }
+
+no_stabs:
+    /* second pass: we try symtab symbols (no line number info) */
+    incl_index = 0;
+    if (symtab_section)
+    {
+        ElfW(Sym) *sym, *sym_end;
+        int type;
+
+        sym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset);
+        for(sym = (ElfW(Sym) *)symtab_section->data + 1;
+            sym < sym_end;
+            sym++) {
+            type = ELFW(ST_TYPE)(sym->st_info);
+            if (type == STT_FUNC || type == STT_GNU_IFUNC) {
+                if (wanted_pc >= sym->st_value &&
+                    wanted_pc < sym->st_value + sym->st_size) {
+                    pstrcpy(last_func_name, sizeof(last_func_name),
+                            (char *) symtab_section->link->data + sym->st_name);
+                    func_addr = sym->st_value;
+                    goto found;
+                }
+            }
+        }
+    }
+    /* did not find any info: */
+    fprintf(stderr, "%s %p ???\n", msg, (void*)wanted_pc);
+    fflush(stderr);
+    return 0;
+ found:
+    i = incl_index;
+    if (i > 0)
+        fprintf(stderr, "%s:%d: ", incl_files[--i], last_line_num);
+    fprintf(stderr, "%s %p", msg, (void*)wanted_pc);
+    if (last_func_name[0] != '\0')
+        fprintf(stderr, " %s()", last_func_name);
+    if (--i >= 0) {
+        fprintf(stderr, " (included from ");
+        for (;;) {
+            fprintf(stderr, "%s", incl_files[i]);
+            if (--i < 0)
+                break;
+            fprintf(stderr, ", ");
+        }
+        fprintf(stderr, ")");
+    }
+    fprintf(stderr, "\n");
+    fflush(stderr);
+    return func_addr;
+}
+
+/* emit a run time error at position 'pc' */
+static void rt_error(ucontext_t *uc, const char *fmt, ...)
+{
+    va_list ap;
+    addr_t pc;
+    int i;
+
+    fprintf(stderr, "Runtime error: ");
+    va_start(ap, fmt);
+    vfprintf(stderr, fmt, ap);
+    va_end(ap);
+    fprintf(stderr, "\n");
+
+    for(i=0;i<rt_num_callers;i++) {
+        if (rt_get_caller_pc(&pc, uc, i) < 0)
+            break;
+        pc = rt_printline(pc, i ? "by" : "at");
+        if (pc == (addr_t)rt_prog_main && pc)
+            break;
+    }
+}
+
+/* ------------------------------------------------------------- */
+#ifndef _WIN32
+
+/* signal handler for fatal errors */
+static void sig_error(int signum, siginfo_t *siginf, void *puc)
+{
+    ucontext_t *uc = puc;
+
+    switch(signum) {
+    case SIGFPE:
+        switch(siginf->si_code) {
+        case FPE_INTDIV:
+        case FPE_FLTDIV:
+            rt_error(uc, "division by zero");
+            break;
+        default:
+            rt_error(uc, "floating point exception");
+            break;
+        }
+        break;
+    case SIGBUS:
+    case SIGSEGV:
+        if (rt_bound_error_msg && *rt_bound_error_msg)
+            rt_error(uc, *rt_bound_error_msg);
+        else
+            rt_error(uc, "dereferencing invalid pointer");
+        break;
+    case SIGILL:
+        rt_error(uc, "illegal instruction");
+        break;
+    case SIGABRT:
+        rt_error(uc, "abort() called");
+        break;
+    default:
+        rt_error(uc, "caught signal %d", signum);
+        break;
+    }
+    exit(255);
+}
+
+#ifndef SA_SIGINFO
+# define SA_SIGINFO 0x00000004u
+#endif
+
+/* Generate a stack backtrace when a CPU exception occurs. */
+static void set_exception_handler(void)
+{
+    struct sigaction sigact;
+    /* install TCC signal handlers to print debug info on fatal
+       runtime errors */
+    sigact.sa_flags = SA_SIGINFO | SA_RESETHAND;
+    sigact.sa_sigaction = sig_error;
+    sigemptyset(&sigact.sa_mask);
+    sigaction(SIGFPE, &sigact, NULL);
+    sigaction(SIGILL, &sigact, NULL);
+    sigaction(SIGSEGV, &sigact, NULL);
+    sigaction(SIGBUS, &sigact, NULL);
+    sigaction(SIGABRT, &sigact, NULL);
+}
+
+/* ------------------------------------------------------------- */
+#ifdef __i386__
+
+/* fix for glibc 2.1 */
+#ifndef REG_EIP
+#define REG_EIP EIP
+#define REG_EBP EBP
+#endif
+
+/* return the PC at frame level 'level'. Return negative if not found */
+static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
+{
+    addr_t fp;
+    int i;
+
+    if (level == 0) {
+#if defined(__APPLE__)
+        *paddr = uc->uc_mcontext->__ss.__eip;
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+        *paddr = uc->uc_mcontext.mc_eip;
+#elif defined(__dietlibc__)
+        *paddr = uc->uc_mcontext.eip;
+#elif defined(__NetBSD__)
+        *paddr = uc->uc_mcontext.__gregs[_REG_EIP];
+#elif defined(__OpenBSD__)
+        *paddr = uc->sc_eip;
+#else
+        *paddr = uc->uc_mcontext.gregs[REG_EIP];
+#endif
+        return 0;
+    } else {
+#if defined(__APPLE__)
+        fp = uc->uc_mcontext->__ss.__ebp;
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+        fp = uc->uc_mcontext.mc_ebp;
+#elif defined(__dietlibc__)
+        fp = uc->uc_mcontext.ebp;
+#elif defined(__NetBSD__)
+        fp = uc->uc_mcontext.__gregs[_REG_EBP];
+#elif defined(__OpenBSD__)
+        *paddr = uc->sc_ebp;
+#else
+        fp = uc->uc_mcontext.gregs[REG_EBP];
+#endif
+        for(i=1;i<level;i++) {
+            /* XXX: check address validity with program info */
+            if (fp <= 0x1000 || fp >= 0xc0000000)
+                return -1;
+            fp = ((addr_t *)fp)[0];
+        }
+        *paddr = ((addr_t *)fp)[1];
+        return 0;
+    }
+}
+
+/* ------------------------------------------------------------- */
+#elif defined(__x86_64__)
+
+/* return the PC at frame level 'level'. Return negative if not found */
+static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
+{
+    addr_t fp;
+    int i;
+
+    if (level == 0) {
+        /* XXX: only support linux */
+#if defined(__APPLE__)
+        *paddr = uc->uc_mcontext->__ss.__rip;
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+        *paddr = uc->uc_mcontext.mc_rip;
+#elif defined(__NetBSD__)
+        *paddr = uc->uc_mcontext.__gregs[_REG_RIP];
+#else
+        *paddr = uc->uc_mcontext.gregs[REG_RIP];
+#endif
+        return 0;
+    } else {
+#if defined(__APPLE__)
+        fp = uc->uc_mcontext->__ss.__rbp;
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+        fp = uc->uc_mcontext.mc_rbp;
+#elif defined(__NetBSD__)
+        fp = uc->uc_mcontext.__gregs[_REG_RBP];
+#else
+        fp = uc->uc_mcontext.gregs[REG_RBP];
+#endif
+        for(i=1;i<level;i++) {
+            /* XXX: check address validity with program info */
+            if (fp <= 0x1000)
+                return -1;
+            fp = ((addr_t *)fp)[0];
+        }
+        *paddr = ((addr_t *)fp)[1];
+        return 0;
+    }
+}
+
+/* ------------------------------------------------------------- */
+#elif defined(__arm__)
+
+/* return the PC at frame level 'level'. Return negative if not found */
+static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
+{
+    addr_t fp, sp;
+    int i;
+
+    if (level == 0) {
+        /* XXX: only supports linux */
+#if defined(__linux__)
+        *paddr = uc->uc_mcontext.arm_pc;
+#else
+        return -1;
+#endif
+        return 0;
+    } else {
+#if defined(__linux__)
+        fp = uc->uc_mcontext.arm_fp;
+        sp = uc->uc_mcontext.arm_sp;
+        if (sp < 0x1000)
+            sp = 0x1000;
+#else
+        return -1;
+#endif
+        /* XXX: specific to tinycc stack frames */
+        if (fp < sp + 12 || fp & 3)
+            return -1;
+        for(i = 1; i < level; i++) {
+            sp = ((addr_t *)fp)[-2];
+            if (sp < fp || sp - fp > 16 || sp & 3)
+                return -1;
+            fp = ((addr_t *)fp)[-3];
+            if (fp <= sp || fp - sp < 12 || fp & 3)
+                return -1;
+        }
+        /* XXX: check address validity with program info */
+        *paddr = ((addr_t *)fp)[-1];
+        return 0;
+    }
+}
+
+/* ------------------------------------------------------------- */
+#elif defined(__aarch64__)
+
+static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
+{
+    if (level < 0)
+        return -1;
+    else if (level == 0) {
+        *paddr = uc->uc_mcontext.pc;
+        return 0;
+    }
+    else {
+        addr_t *fp = (addr_t *)uc->uc_mcontext.regs[29];
+        int i;
+        for (i = 1; i < level; i++)
+            fp = (addr_t *)fp[0];
+        *paddr = fp[1];
+        return 0;
+    }
+}
+
+/* ------------------------------------------------------------- */
+#else
+
+#warning add arch specific rt_get_caller_pc()
+static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level)
+{
+    return -1;
+}
+
+#endif /* !__i386__ */
+
+/* ------------------------------------------------------------- */
+#else /* WIN32 */
+
+static long __stdcall cpu_exception_handler(EXCEPTION_POINTERS *ex_info)
+{
+    EXCEPTION_RECORD *er = ex_info->ExceptionRecord;
+    CONTEXT *uc = ex_info->ContextRecord;
+    switch (er->ExceptionCode) {
+    case EXCEPTION_ACCESS_VIOLATION:
+        if (rt_bound_error_msg && *rt_bound_error_msg)
+            rt_error(uc, *rt_bound_error_msg);
+        else
+	    rt_error(uc, "access violation");
+        break;
+    case EXCEPTION_STACK_OVERFLOW:
+        rt_error(uc, "stack overflow");
+        break;
+    case EXCEPTION_INT_DIVIDE_BY_ZERO:
+        rt_error(uc, "division by zero");
+        break;
+    default:
+        rt_error(uc, "exception caught");
+        break;
+    }
+    return EXCEPTION_EXECUTE_HANDLER;
+}
+
+/* Generate a stack backtrace when a CPU exception occurs. */
+static void set_exception_handler(void)
+{
+    SetUnhandledExceptionFilter(cpu_exception_handler);
+}
+
+/* return the PC at frame level 'level'. Return non zero if not found */
+static int rt_get_caller_pc(addr_t *paddr, CONTEXT *uc, int level)
+{
+    addr_t fp, pc;
+    int i;
+#ifdef _WIN64
+    pc = uc->Rip;
+    fp = uc->Rbp;
+#else
+    pc = uc->Eip;
+    fp = uc->Ebp;
+#endif
+    if (level > 0) {
+        for(i=1;i<level;i++) {
+	    /* XXX: check address validity with program info */
+	    if (fp <= 0x1000 || fp >= 0xc0000000)
+		return -1;
+	    fp = ((addr_t*)fp)[0];
+	}
+        pc = ((addr_t*)fp)[1];
+    }
+    *paddr = pc;
+    return 0;
+}
+
+#endif /* _WIN32 */
+#endif /* CONFIG_TCC_BACKTRACE */
+/* ------------------------------------------------------------- */
+#ifdef CONFIG_TCC_STATIC
+
+/* dummy function for profiling */
+ST_FUNC void *dlopen(const char *filename, int flag)
+{
+    return NULL;
+}
+
+ST_FUNC void dlclose(void *p)
+{
+}
+
+ST_FUNC const char *dlerror(void)
+{
+    return "error";
+}
+
+typedef struct TCCSyms {
+    char *str;
+    void *ptr;
+} TCCSyms;
+
+#if !defined(CONFIG_TCCBOOT)
+extern int __environ;
+extern int __expand_heap;
+extern int __get_handler_set;
+extern int __get_locale;
+extern int __gmt;
+extern int __h_errno_location;
+extern int __hwcap;
+extern int __init_tls;
+extern int __libc;
+extern int __libc_sigaction;
+extern int __libc_start_main;
+extern int __malloc0;
+extern int __ofl_lock;
+extern int __ofl_unlock;
+extern int __progname;
+extern int __progname_full;
+extern int __secs_to_zone;
+extern int __sigaction;
+extern int __sysinfo;
+extern int __tm_to_tzname;
+//extern int atexit;
+//extern int environ;
+//extern int free;
+extern int gethostbyname2;
+//extern int getopt;
+extern int getpwnam;
+//extern int gmtime;
+//extern int localtime;
+//extern int malloc;
+extern int mbrtowc;
+//extern int optarg;
+extern int optind;
+//extern int rand;
+//extern int realloc;
+//extern int setenv;
+extern int setlocale;
+//extern int sigaction;
+//extern int srand;
+//extern int stderr;
+//extern int stdin;
+//extern int stdout;
+//extern int strtok;
+extern int syslog;
+extern int vsyslog;
+#endif
+
+/* add the symbol you want here if no dynamic linking is done */
+static TCCSyms tcc_syms[] = {
+#if !defined(CONFIG_TCCBOOT)
+#define TCCSYM(a) { #a, &a, },
+    TCCSYM(__environ)
+    TCCSYM(__expand_heap)
+    TCCSYM(__get_handler_set)
+    TCCSYM(__get_locale)
+    TCCSYM(__gmt)
+    TCCSYM(__h_errno_location)
+    TCCSYM(__hwcap)
+    TCCSYM(__init_tls)
+    TCCSYM(__libc)
+    TCCSYM(__libc_sigaction)
+    TCCSYM(__libc_start_main)
+    TCCSYM(__malloc0)
+    TCCSYM(__ofl_lock)
+    TCCSYM(__ofl_unlock)
+    TCCSYM(__progname)
+    TCCSYM(__progname_full)
+    TCCSYM(__secs_to_zone)
+    TCCSYM(__sigaction)
+    TCCSYM(__sysinfo)
+    TCCSYM(__tm_to_tzname)
+    TCCSYM(atexit)
+    TCCSYM(environ)
+    TCCSYM(free)
+    TCCSYM(gethostbyname2)
+    TCCSYM(getopt)
+    TCCSYM(getpwnam)
+    TCCSYM(gmtime)
+    TCCSYM(localtime)
+    TCCSYM(malloc)
+    TCCSYM(mbrtowc)
+    TCCSYM(optarg)
+    TCCSYM(optind)
+    TCCSYM(rand)
+    TCCSYM(realloc)
+    TCCSYM(setenv)
+    TCCSYM(setlocale)
+    TCCSYM(sigaction)
+    TCCSYM(srand)
+    TCCSYM(stderr)
+    TCCSYM(stdin)
+    TCCSYM(stdout)
+    TCCSYM(strtok)
+    TCCSYM(syslog)
+    TCCSYM(vsyslog)
+#undef TCCSYM
+#endif
+    { NULL, NULL },
+};
+
+ST_FUNC void *dlsym(void *handle, const char *symbol)
+{
+    TCCSyms *p;
+    p = tcc_syms;
+    while (p->str != NULL) {
+        if (!strcmp(p->str, symbol))
+            return p->ptr;
+        p++;
+    }
+    return NULL;
+}
+
+#endif /* CONFIG_TCC_STATIC */
+#endif /* TCC_IS_NATIVE */
+/* ------------------------------------------------------------- */
Index: EcnlProtoTool/trunk/tcc-0.9.27/tcctok.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tcctok.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tcctok.h	(revision 331)
@@ -0,0 +1,350 @@
+/* keywords */
+     DEF(TOK_INT, "int")
+     DEF(TOK_VOID, "void")
+     DEF(TOK_CHAR, "char")
+     DEF(TOK_IF, "if")
+     DEF(TOK_ELSE, "else")
+     DEF(TOK_WHILE, "while")
+     DEF(TOK_BREAK, "break")
+     DEF(TOK_RETURN, "return")
+     DEF(TOK_FOR, "for")
+     DEF(TOK_EXTERN, "extern")
+     DEF(TOK_STATIC, "static")
+     DEF(TOK_UNSIGNED, "unsigned")
+     DEF(TOK_GOTO, "goto")
+     DEF(TOK_DO, "do")
+     DEF(TOK_CONTINUE, "continue")
+     DEF(TOK_SWITCH, "switch")
+     DEF(TOK_CASE, "case")
+
+     DEF(TOK_CONST1, "const")
+     DEF(TOK_CONST2, "__const") /* gcc keyword */
+     DEF(TOK_CONST3, "__const__") /* gcc keyword */
+     DEF(TOK_VOLATILE1, "volatile")
+     DEF(TOK_VOLATILE2, "__volatile") /* gcc keyword */
+     DEF(TOK_VOLATILE3, "__volatile__") /* gcc keyword */
+     DEF(TOK_LONG, "long")
+     DEF(TOK_REGISTER, "register")
+     DEF(TOK_SIGNED1, "signed")
+     DEF(TOK_SIGNED2, "__signed") /* gcc keyword */
+     DEF(TOK_SIGNED3, "__signed__") /* gcc keyword */
+     DEF(TOK_AUTO, "auto")
+     DEF(TOK_INLINE1, "inline")
+     DEF(TOK_INLINE2, "__inline") /* gcc keyword */
+     DEF(TOK_INLINE3, "__inline__") /* gcc keyword */
+     DEF(TOK_RESTRICT1, "restrict")
+     DEF(TOK_RESTRICT2, "__restrict")
+     DEF(TOK_RESTRICT3, "__restrict__")
+     DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
+
+     DEF(TOK_GENERIC, "_Generic")
+
+     DEF(TOK_FLOAT, "float")
+     DEF(TOK_DOUBLE, "double")
+     DEF(TOK_BOOL, "_Bool")
+     DEF(TOK_SHORT, "short")
+     DEF(TOK_STRUCT, "struct")
+     DEF(TOK_UNION, "union")
+     DEF(TOK_TYPEDEF, "typedef")
+     DEF(TOK_DEFAULT, "default")
+     DEF(TOK_ENUM, "enum")
+     DEF(TOK_SIZEOF, "sizeof")
+     DEF(TOK_ATTRIBUTE1, "__attribute")
+     DEF(TOK_ATTRIBUTE2, "__attribute__")
+     DEF(TOK_ALIGNOF1, "__alignof")
+     DEF(TOK_ALIGNOF2, "__alignof__")
+     DEF(TOK_TYPEOF1, "typeof")
+     DEF(TOK_TYPEOF2, "__typeof")
+     DEF(TOK_TYPEOF3, "__typeof__")
+     DEF(TOK_LABEL, "__label__")
+     DEF(TOK_ASM1, "asm")
+     DEF(TOK_ASM2, "__asm")
+     DEF(TOK_ASM3, "__asm__")
+
+#ifdef TCC_TARGET_ARM64
+     DEF(TOK_UINT128, "__uint128_t")
+#endif
+
+/*********************************************************************/
+/* the following are not keywords. They are included to ease parsing */
+/* preprocessor only */
+     DEF(TOK_DEFINE, "define")
+     DEF(TOK_INCLUDE, "include")
+     DEF(TOK_INCLUDE_NEXT, "include_next")
+     DEF(TOK_IFDEF, "ifdef")
+     DEF(TOK_IFNDEF, "ifndef")
+     DEF(TOK_ELIF, "elif")
+     DEF(TOK_ENDIF, "endif")
+     DEF(TOK_DEFINED, "defined")
+     DEF(TOK_UNDEF, "undef")
+     DEF(TOK_ERROR, "error")
+     DEF(TOK_WARNING, "warning")
+     DEF(TOK_LINE, "line")
+     DEF(TOK_PRAGMA, "pragma")
+     DEF(TOK___LINE__, "__LINE__")
+     DEF(TOK___FILE__, "__FILE__")
+     DEF(TOK___DATE__, "__DATE__")
+     DEF(TOK___TIME__, "__TIME__")
+     DEF(TOK___FUNCTION__, "__FUNCTION__")
+     DEF(TOK___VA_ARGS__, "__VA_ARGS__")
+     DEF(TOK___COUNTER__, "__COUNTER__")
+
+/* special identifiers */
+     DEF(TOK___FUNC__, "__func__")
+
+/* special floating point values */
+     DEF(TOK___NAN__, "__nan__")
+     DEF(TOK___SNAN__, "__snan__")
+     DEF(TOK___INF__, "__inf__")
+
+/* attribute identifiers */
+/* XXX: handle all tokens generically since speed is not critical */
+     DEF(TOK_SECTION1, "section")
+     DEF(TOK_SECTION2, "__section__")
+     DEF(TOK_ALIGNED1, "aligned")
+     DEF(TOK_ALIGNED2, "__aligned__")
+     DEF(TOK_PACKED1, "packed")
+     DEF(TOK_PACKED2, "__packed__")
+     DEF(TOK_WEAK1, "weak")
+     DEF(TOK_WEAK2, "__weak__")
+     DEF(TOK_ALIAS1, "alias")
+     DEF(TOK_ALIAS2, "__alias__")
+     DEF(TOK_UNUSED1, "unused")
+     DEF(TOK_UNUSED2, "__unused__")
+     DEF(TOK_CDECL1, "cdecl")
+     DEF(TOK_CDECL2, "__cdecl")
+     DEF(TOK_CDECL3, "__cdecl__")
+     DEF(TOK_STDCALL1, "stdcall")
+     DEF(TOK_STDCALL2, "__stdcall")
+     DEF(TOK_STDCALL3, "__stdcall__")
+     DEF(TOK_FASTCALL1, "fastcall")
+     DEF(TOK_FASTCALL2, "__fastcall")
+     DEF(TOK_FASTCALL3, "__fastcall__")
+     DEF(TOK_REGPARM1, "regparm")
+     DEF(TOK_REGPARM2, "__regparm__")
+
+     DEF(TOK_MODE, "__mode__")
+     DEF(TOK_MODE_QI, "__QI__")
+     DEF(TOK_MODE_DI, "__DI__")
+     DEF(TOK_MODE_HI, "__HI__")
+     DEF(TOK_MODE_SI, "__SI__")
+     DEF(TOK_MODE_word, "__word__")
+
+     DEF(TOK_DLLEXPORT, "dllexport")
+     DEF(TOK_DLLIMPORT, "dllimport")
+     DEF(TOK_NORETURN1, "noreturn")
+     DEF(TOK_NORETURN2, "__noreturn__")
+     DEF(TOK_VISIBILITY1, "visibility")
+     DEF(TOK_VISIBILITY2, "__visibility__")
+
+     DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
+     DEF(TOK_builtin_choose_expr, "__builtin_choose_expr")
+     DEF(TOK_builtin_constant_p, "__builtin_constant_p")
+     DEF(TOK_builtin_frame_address, "__builtin_frame_address")
+     DEF(TOK_builtin_return_address, "__builtin_return_address")
+     DEF(TOK_builtin_expect, "__builtin_expect")
+     /*DEF(TOK_builtin_va_list, "__builtin_va_list")*/
+#if defined TCC_TARGET_PE && defined TCC_TARGET_X86_64
+     DEF(TOK_builtin_va_start, "__builtin_va_start")
+#elif defined TCC_TARGET_X86_64
+     DEF(TOK_builtin_va_arg_types, "__builtin_va_arg_types")
+#elif defined TCC_TARGET_ARM64
+     DEF(TOK___va_start, "__va_start")
+     DEF(TOK___va_arg, "__va_arg")
+#endif
+
+/* pragma */
+     DEF(TOK_pack, "pack")
+#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_X86_64)
+     /* already defined for assembler */
+     DEF(TOK_ASM_push, "push")
+     DEF(TOK_ASM_pop, "pop")
+#endif
+     DEF(TOK_comment, "comment")
+     DEF(TOK_lib, "lib")
+     DEF(TOK_push_macro, "push_macro")
+     DEF(TOK_pop_macro, "pop_macro")
+     DEF(TOK_once, "once")
+     DEF(TOK_option, "option")
+
+/* builtin functions or variables */
+#ifndef TCC_ARM_EABI
+     DEF(TOK_memcpy, "memcpy")
+     DEF(TOK_memmove, "memmove")
+     DEF(TOK_memset, "memset")
+     DEF(TOK___divdi3, "__divdi3")
+     DEF(TOK___moddi3, "__moddi3")
+     DEF(TOK___udivdi3, "__udivdi3")
+     DEF(TOK___umoddi3, "__umoddi3")
+     DEF(TOK___ashrdi3, "__ashrdi3")
+     DEF(TOK___lshrdi3, "__lshrdi3")
+     DEF(TOK___ashldi3, "__ashldi3")
+     DEF(TOK___floatundisf, "__floatundisf")
+     DEF(TOK___floatundidf, "__floatundidf")
+# ifndef TCC_ARM_VFP
+     DEF(TOK___floatundixf, "__floatundixf")
+     DEF(TOK___fixunsxfdi, "__fixunsxfdi")
+# endif
+     DEF(TOK___fixunssfdi, "__fixunssfdi")
+     DEF(TOK___fixunsdfdi, "__fixunsdfdi")
+#endif
+
+#if defined TCC_TARGET_ARM
+# ifdef TCC_ARM_EABI
+     DEF(TOK_memcpy, "__aeabi_memcpy")
+     DEF(TOK_memcpy4, "__aeabi_memcpy4")
+     DEF(TOK_memcpy8, "__aeabi_memcpy8")
+     DEF(TOK_memmove, "__aeabi_memmove")
+     DEF(TOK_memset, "__aeabi_memset")
+     DEF(TOK___aeabi_ldivmod, "__aeabi_ldivmod")
+     DEF(TOK___aeabi_uldivmod, "__aeabi_uldivmod")
+     DEF(TOK___aeabi_idivmod, "__aeabi_idivmod")
+     DEF(TOK___aeabi_uidivmod, "__aeabi_uidivmod")
+     DEF(TOK___divsi3, "__aeabi_idiv")
+     DEF(TOK___udivsi3, "__aeabi_uidiv")
+     DEF(TOK___floatdisf, "__aeabi_l2f")
+     DEF(TOK___floatdidf, "__aeabi_l2d")
+     DEF(TOK___fixsfdi, "__aeabi_f2lz")
+     DEF(TOK___fixdfdi, "__aeabi_d2lz")
+     DEF(TOK___ashrdi3, "__aeabi_lasr")
+     DEF(TOK___lshrdi3, "__aeabi_llsr")
+     DEF(TOK___ashldi3, "__aeabi_llsl")
+     DEF(TOK___floatundisf, "__aeabi_ul2f")
+     DEF(TOK___floatundidf, "__aeabi_ul2d")
+     DEF(TOK___fixunssfdi, "__aeabi_f2ulz")
+     DEF(TOK___fixunsdfdi, "__aeabi_d2ulz")
+# else
+     DEF(TOK___modsi3, "__modsi3")
+     DEF(TOK___umodsi3, "__umodsi3")
+     DEF(TOK___divsi3, "__divsi3")
+     DEF(TOK___udivsi3, "__udivsi3")
+     DEF(TOK___floatdisf, "__floatdisf")
+     DEF(TOK___floatdidf, "__floatdidf")
+#  ifndef TCC_ARM_VFP
+     DEF(TOK___floatdixf, "__floatdixf")
+     DEF(TOK___fixunssfsi, "__fixunssfsi")
+     DEF(TOK___fixunsdfsi, "__fixunsdfsi")
+     DEF(TOK___fixunsxfsi, "__fixunsxfsi")
+     DEF(TOK___fixxfdi, "__fixxfdi")
+#  endif
+     DEF(TOK___fixsfdi, "__fixsfdi")
+     DEF(TOK___fixdfdi, "__fixdfdi")
+# endif
+#endif
+
+#if defined TCC_TARGET_C67
+     DEF(TOK__divi, "_divi")
+     DEF(TOK__divu, "_divu")
+     DEF(TOK__divf, "_divf")
+     DEF(TOK__divd, "_divd")
+     DEF(TOK__remi, "_remi")
+     DEF(TOK__remu, "_remu")
+#endif
+
+#if defined TCC_TARGET_I386
+     DEF(TOK___fixsfdi, "__fixsfdi")
+     DEF(TOK___fixdfdi, "__fixdfdi")
+     DEF(TOK___fixxfdi, "__fixxfdi")
+#endif
+
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+     DEF(TOK_alloca, "alloca")
+#endif
+
+#if defined TCC_TARGET_PE
+     DEF(TOK___chkstk, "__chkstk")
+#endif
+#ifdef TCC_TARGET_ARM64
+     DEF(TOK___arm64_clear_cache, "__arm64_clear_cache")
+     DEF(TOK___addtf3, "__addtf3")
+     DEF(TOK___subtf3, "__subtf3")
+     DEF(TOK___multf3, "__multf3")
+     DEF(TOK___divtf3, "__divtf3")
+     DEF(TOK___extendsftf2, "__extendsftf2")
+     DEF(TOK___extenddftf2, "__extenddftf2")
+     DEF(TOK___trunctfsf2, "__trunctfsf2")
+     DEF(TOK___trunctfdf2, "__trunctfdf2")
+     DEF(TOK___fixtfsi, "__fixtfsi")
+     DEF(TOK___fixtfdi, "__fixtfdi")
+     DEF(TOK___fixunstfsi, "__fixunstfsi")
+     DEF(TOK___fixunstfdi, "__fixunstfdi")
+     DEF(TOK___floatsitf, "__floatsitf")
+     DEF(TOK___floatditf, "__floatditf")
+     DEF(TOK___floatunsitf, "__floatunsitf")
+     DEF(TOK___floatunditf, "__floatunditf")
+     DEF(TOK___eqtf2, "__eqtf2")
+     DEF(TOK___netf2, "__netf2")
+     DEF(TOK___lttf2, "__lttf2")
+     DEF(TOK___letf2, "__letf2")
+     DEF(TOK___gttf2, "__gttf2")
+     DEF(TOK___getf2, "__getf2")
+#endif
+
+/* bound checking symbols */
+#ifdef CONFIG_TCC_BCHECK
+     DEF(TOK___bound_ptr_add, "__bound_ptr_add")
+     DEF(TOK___bound_ptr_indir1, "__bound_ptr_indir1")
+     DEF(TOK___bound_ptr_indir2, "__bound_ptr_indir2")
+     DEF(TOK___bound_ptr_indir4, "__bound_ptr_indir4")
+     DEF(TOK___bound_ptr_indir8, "__bound_ptr_indir8")
+     DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12")
+     DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16")
+     DEF(TOK___bound_main_arg, "__bound_main_arg")
+     DEF(TOK___bound_local_new, "__bound_local_new")
+     DEF(TOK___bound_local_delete, "__bound_local_delete")
+# ifdef TCC_TARGET_PE
+     DEF(TOK_malloc, "malloc")
+     DEF(TOK_free, "free")
+     DEF(TOK_realloc, "realloc")
+     DEF(TOK_memalign, "memalign")
+     DEF(TOK_calloc, "calloc")
+# endif
+     DEF(TOK_strlen, "strlen")
+     DEF(TOK_strcpy, "strcpy")
+#endif
+
+/* Tiny Assembler */
+ DEF_ASMDIR(byte)              /* must be first directive */
+ DEF_ASMDIR(word)
+ DEF_ASMDIR(align)
+ DEF_ASMDIR(balign)
+ DEF_ASMDIR(p2align)
+ DEF_ASMDIR(set)
+ DEF_ASMDIR(skip)
+ DEF_ASMDIR(space)
+ DEF_ASMDIR(string)
+ DEF_ASMDIR(asciz)
+ DEF_ASMDIR(ascii)
+ DEF_ASMDIR(file)
+ DEF_ASMDIR(globl)
+ DEF_ASMDIR(global)
+ DEF_ASMDIR(weak)
+ DEF_ASMDIR(hidden)
+ DEF_ASMDIR(ident)
+ DEF_ASMDIR(size)
+ DEF_ASMDIR(type)
+ DEF_ASMDIR(text)
+ DEF_ASMDIR(data)
+ DEF_ASMDIR(bss)
+ DEF_ASMDIR(previous)
+ DEF_ASMDIR(pushsection)
+ DEF_ASMDIR(popsection)
+ DEF_ASMDIR(fill)
+ DEF_ASMDIR(rept)
+ DEF_ASMDIR(endr)
+ DEF_ASMDIR(org)
+ DEF_ASMDIR(quad)
+#if defined(TCC_TARGET_I386)
+ DEF_ASMDIR(code16)
+ DEF_ASMDIR(code32)
+#elif defined(TCC_TARGET_X86_64)
+ DEF_ASMDIR(code64)
+#endif
+ DEF_ASMDIR(short)
+ DEF_ASMDIR(long)
+ DEF_ASMDIR(int)
+ DEF_ASMDIR(section)            /* must be last directive */
+
+#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
+#include "i386-tok.h"
+#endif
Index: EcnlProtoTool/trunk/tcc-0.9.27/tcctools.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tcctools.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tcctools.c	(revision 331)
@@ -0,0 +1,546 @@
+/* -------------------------------------------------------------- */
+/*
+ *  TCC - Tiny C Compiler
+ *
+ *  tcctools.c - extra tools and and -m32/64 support
+ *
+ */
+
+/* -------------------------------------------------------------- */
+/*
+ * This program is for making libtcc1.a without ar
+ * tiny_libmaker - tiny elf lib maker
+ * usage: tiny_libmaker [lib] files...
+ * Copyright (c) 2007 Timppa
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "tcc.h"
+
+//#define ARMAG  "!<arch>\n"
+#define ARFMAG "`\n"
+
+typedef struct {
+    char ar_name[16];
+    char ar_date[12];
+    char ar_uid[6];
+    char ar_gid[6];
+    char ar_mode[8];
+    char ar_size[10];
+    char ar_fmag[2];
+} ArHdr;
+
+static unsigned long le2belong(unsigned long ul) {
+    return ((ul & 0xFF0000)>>8)+((ul & 0xFF000000)>>24) +
+        ((ul & 0xFF)<<24)+((ul & 0xFF00)<<8);
+}
+
+/* Returns 1 if s contains any of the chars of list, else 0 */
+static int contains_any(const char *s, const char *list) {
+  const char *l;
+  for (; *s; s++) {
+      for (l = list; *l; l++) {
+          if (*s == *l)
+              return 1;
+      }
+  }
+  return 0;
+}
+
+static int ar_usage(int ret) {
+    fprintf(stderr, "usage: tcc -ar [rcsv] lib file...\n");
+    fprintf(stderr, "create library ([abdioptxN] not supported).\n");
+    return ret;
+}
+
+ST_FUNC int tcc_tool_ar(TCCState *s1, int argc, char **argv)
+{
+    static ArHdr arhdr = {
+        "/               ",
+        "            ",
+        "0     ",
+        "0     ",
+        "0       ",
+        "          ",
+        ARFMAG
+        };
+
+    static ArHdr arhdro = {
+        "                ",
+        "            ",
+        "0     ",
+        "0     ",
+        "0       ",
+        "          ",
+        ARFMAG
+        };
+
+    FILE *fi, *fh = NULL, *fo = NULL;
+    ElfW(Ehdr) *ehdr;
+    ElfW(Shdr) *shdr;
+    ElfW(Sym) *sym;
+    int i, fsize, i_lib, i_obj;
+    char *buf, *shstr, *symtab = NULL, *strtab = NULL;
+    int symtabsize = 0;//, strtabsize = 0;
+    char *anames = NULL;
+    int *afpos = NULL;
+    int istrlen, strpos = 0, fpos = 0, funccnt = 0, funcmax, hofs;
+    char tfile[260], stmp[20];
+    char *file, *name;
+    int ret = 2;
+    const char *ops_conflict = "habdioptxN";  // unsupported but destructive if ignored.
+    int verbose = 0;
+
+    i_lib = 0; i_obj = 0;  // will hold the index of the lib and first obj
+    for (i = 1; i < argc; i++) {
+        const char *a = argv[i];
+        if (*a == '-' && strstr(a, "."))
+            ret = 1; // -x.y is always invalid (same as gnu ar)
+        if ((*a == '-') || (i == 1 && !strstr(a, "."))) {  // options argument
+            if (contains_any(a, ops_conflict))
+                ret = 1;
+            if (strstr(a, "v"))
+                verbose = 1;
+        } else {  // lib or obj files: don't abort - keep validating all args.
+            if (!i_lib)  // first file is the lib
+                i_lib = i;
+            else if (!i_obj)  // second file is the first obj
+                i_obj = i;
+        }
+    }
+
+    if (!i_obj)  // i_obj implies also i_lib. we require both.
+        ret = 1;
+
+    if (ret == 1)
+        return ar_usage(ret);
+
+    if ((fh = fopen(argv[i_lib], "wb")) == NULL)
+    {
+        fprintf(stderr, "tcc: ar: can't open file %s \n", argv[i_lib]);
+        goto the_end;
+    }
+
+    sprintf(tfile, "%s.tmp", argv[i_lib]);
+    if ((fo = fopen(tfile, "wb+")) == NULL)
+    {
+        fprintf(stderr, "tcc: ar: can't create temporary file %s\n", tfile);
+        goto the_end;
+    }
+
+    funcmax = 250;
+    afpos = tcc_realloc(NULL, funcmax * sizeof *afpos); // 250 func
+    memcpy(&arhdro.ar_mode, "100666", 6);
+
+    // i_obj = first input object file
+    while (i_obj < argc)
+    {
+        if (*argv[i_obj] == '-') {  // by now, all options start with '-'
+            i_obj++;
+            continue;
+        }
+        if ((fi = fopen(argv[i_obj], "rb")) == NULL) {
+            fprintf(stderr, "tcc: ar: can't open file %s \n", argv[i_obj]);
+            goto the_end;
+        }
+        if (verbose)
+            printf("a - %s\n", argv[i_obj]);
+
+        fseek(fi, 0, SEEK_END);
+        fsize = ftell(fi);
+        fseek(fi, 0, SEEK_SET);
+        buf = tcc_malloc(fsize + 1);
+        fread(buf, fsize, 1, fi);
+        fclose(fi);
+
+        // elf header
+        ehdr = (ElfW(Ehdr) *)buf;
+        if (ehdr->e_ident[4] != ELFCLASSW)
+        {
+            fprintf(stderr, "tcc: ar: Unsupported Elf Class: %s\n", argv[i_obj]);
+            goto the_end;
+        }
+
+        shdr = (ElfW(Shdr) *) (buf + ehdr->e_shoff + ehdr->e_shstrndx * ehdr->e_shentsize);
+        shstr = (char *)(buf + shdr->sh_offset);
+        for (i = 0; i < ehdr->e_shnum; i++)
+        {
+            shdr = (ElfW(Shdr) *) (buf + ehdr->e_shoff + i * ehdr->e_shentsize);
+            if (!shdr->sh_offset)
+                continue;
+            if (shdr->sh_type == SHT_SYMTAB)
+            {
+                symtab = (char *)(buf + shdr->sh_offset);
+                symtabsize = shdr->sh_size;
+            }
+            if (shdr->sh_type == SHT_STRTAB)
+            {
+                if (!strcmp(shstr + shdr->sh_name, ".strtab"))
+                {
+                    strtab = (char *)(buf + shdr->sh_offset);
+                    //strtabsize = shdr->sh_size;
+                }
+            }
+        }
+
+        if (symtab && symtabsize)
+        {
+            int nsym = symtabsize / sizeof(ElfW(Sym));
+            //printf("symtab: info size shndx name\n");
+            for (i = 1; i < nsym; i++)
+            {
+                sym = (ElfW(Sym) *) (symtab + i * sizeof(ElfW(Sym)));
+                if (sym->st_shndx &&
+                    (sym->st_info == 0x10
+                    || sym->st_info == 0x11
+                    || sym->st_info == 0x12
+                    )) {
+                    //printf("symtab: %2Xh %4Xh %2Xh %s\n", sym->st_info, sym->st_size, sym->st_shndx, strtab + sym->st_name);
+                    istrlen = strlen(strtab + sym->st_name)+1;
+                    anames = tcc_realloc(anames, strpos+istrlen);
+                    strcpy(anames + strpos, strtab + sym->st_name);
+                    strpos += istrlen;
+                    if (++funccnt >= funcmax) {
+                        funcmax += 250;
+                        afpos = tcc_realloc(afpos, funcmax * sizeof *afpos); // 250 func more
+                    }
+                    afpos[funccnt] = fpos;
+                }
+            }
+        }
+
+        file = argv[i_obj];
+        for (name = strchr(file, 0);
+             name > file && name[-1] != '/' && name[-1] != '\\';
+             --name);
+        istrlen = strlen(name);
+        if (istrlen >= sizeof(arhdro.ar_name))
+            istrlen = sizeof(arhdro.ar_name) - 1;
+        memset(arhdro.ar_name, ' ', sizeof(arhdro.ar_name));
+        memcpy(arhdro.ar_name, name, istrlen);
+        arhdro.ar_name[istrlen] = '/';
+        sprintf(stmp, "%-10d", fsize);
+        memcpy(&arhdro.ar_size, stmp, 10);
+        fwrite(&arhdro, sizeof(arhdro), 1, fo);
+        fwrite(buf, fsize, 1, fo);
+        tcc_free(buf);
+        i_obj++;
+        fpos += (fsize + sizeof(arhdro));
+    }
+    hofs = 8 + sizeof(arhdr) + strpos + (funccnt+1) * sizeof(int);
+    fpos = 0;
+    if ((hofs & 1)) // align
+        hofs++, fpos = 1;
+    // write header
+    fwrite("!<arch>\n", 8, 1, fh);
+    sprintf(stmp, "%-10d", (int)(strpos + (funccnt+1) * sizeof(int)));
+    memcpy(&arhdr.ar_size, stmp, 10);
+    fwrite(&arhdr, sizeof(arhdr), 1, fh);
+    afpos[0] = le2belong(funccnt);
+    for (i=1; i<=funccnt; i++)
+        afpos[i] = le2belong(afpos[i] + hofs);
+    fwrite(afpos, (funccnt+1) * sizeof(int), 1, fh);
+    fwrite(anames, strpos, 1, fh);
+    if (fpos)
+        fwrite("", 1, 1, fh);
+    // write objects
+    fseek(fo, 0, SEEK_END);
+    fsize = ftell(fo);
+    fseek(fo, 0, SEEK_SET);
+    buf = tcc_malloc(fsize + 1);
+    fread(buf, fsize, 1, fo);
+    fwrite(buf, fsize, 1, fh);
+    tcc_free(buf);
+    ret = 0;
+the_end:
+    if (anames)
+        tcc_free(anames);
+    if (afpos)
+        tcc_free(afpos);
+    if (fh)
+        fclose(fh);
+    if (fo)
+        fclose(fo), remove(tfile);
+    return ret;
+}
+
+/* -------------------------------------------------------------- */
+/*
+ * tiny_impdef creates an export definition file (.def) from a dll
+ * on MS-Windows. Usage: tiny_impdef library.dll [-o outputfile]"
+ *
+ *  Copyright (c) 2005,2007 grischka
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef TCC_TARGET_PE
+
+ST_FUNC int tcc_tool_impdef(TCCState *s1, int argc, char **argv)
+{
+    int ret, v, i;
+    char infile[260];
+    char outfile[260];
+
+    const char *file;
+    char *p, *q;
+    FILE *fp, *op;
+
+#ifdef _WIN32
+    char path[260];
+#endif
+
+    infile[0] = outfile[0] = 0;
+    fp = op = NULL;
+    ret = 1;
+    p = NULL;
+    v = 0;
+
+    for (i = 1; i < argc; ++i) {
+        const char *a = argv[i];
+        if ('-' == a[0]) {
+            if (0 == strcmp(a, "-v")) {
+                v = 1;
+            } else if (0 == strcmp(a, "-o")) {
+                if (++i == argc)
+                    goto usage;
+                strcpy(outfile, argv[i]);
+            } else
+                goto usage;
+        } else if (0 == infile[0])
+            strcpy(infile, a);
+        else
+            goto usage;
+    }
+
+    if (0 == infile[0]) {
+usage:
+        fprintf(stderr,
+            "usage: tcc -impdef library.dll [-v] [-o outputfile]\n"
+            "create export definition file (.def) from dll\n"
+            );
+        goto the_end;
+    }
+
+    if (0 == outfile[0]) {
+        strcpy(outfile, tcc_basename(infile));
+        q = strrchr(outfile, '.');
+        if (NULL == q)
+            q = strchr(outfile, 0);
+        strcpy(q, ".def");
+    }
+
+    file = infile;
+#ifdef _WIN32
+    if (SearchPath(NULL, file, ".dll", sizeof path, path, NULL))
+        file = path;
+#endif
+    ret = tcc_get_dllexports(file, &p);
+    if (ret || !p) {
+        fprintf(stderr, "tcc: impdef: %s '%s'\n",
+            ret == -1 ? "can't find file" :
+            ret ==  1 ? "can't read symbols" :
+            ret ==  0 ? "no symbols found in" :
+            "unknown file type", file);
+        ret = 1;
+        goto the_end;
+    }
+
+    if (v)
+        printf("-> %s\n", file);
+
+    op = fopen(outfile, "wb");
+    if (NULL == op) {
+        fprintf(stderr, "tcc: impdef: could not create output file: %s\n", outfile);
+        goto the_end;
+    }
+
+    fprintf(op, "LIBRARY %s\n\nEXPORTS\n", tcc_basename(file));
+    for (q = p, i = 0; *q; ++i) {
+        fprintf(op, "%s\n", q);
+        q += strlen(q) + 1;
+    }
+
+    if (v)
+        printf("<- %s (%d symbol%s)\n", outfile, i, &"s"[i<2]);
+
+    ret = 0;
+
+the_end:
+    /* cannot free memory received from tcc_get_dllexports
+       if it came from a dll */
+    /* if (p)
+        tcc_free(p); */
+    if (fp)
+        fclose(fp);
+    if (op)
+        fclose(op);
+    return ret;
+}
+
+#endif /* TCC_TARGET_PE */
+
+/* -------------------------------------------------------------- */
+/*
+ *  TCC - Tiny C Compiler
+ *
+ *  Copyright (c) 2001-2004 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* re-execute the i386/x86_64 cross-compilers with tcc -m32/-m64: */
+
+#if !defined TCC_TARGET_I386 && !defined TCC_TARGET_X86_64
+
+ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int option)
+{
+    tcc_error("-m%d not implemented.", option);
+}
+
+#else
+#ifdef _WIN32
+#include <process.h>
+
+static char *str_replace(const char *str, const char *p, const char *r)
+{
+    const char *s, *s0;
+    char *d, *d0;
+    int sl, pl, rl;
+
+    sl = strlen(str);
+    pl = strlen(p);
+    rl = strlen(r);
+    for (d0 = NULL;; d0 = tcc_malloc(sl + 1)) {
+        for (d = d0, s = str; s0 = s, s = strstr(s, p), s; s += pl) {
+            if (d) {
+                memcpy(d, s0, sl = s - s0), d += sl;
+                memcpy(d, r, rl), d += rl;
+            } else
+                sl += rl - pl;
+        }
+        if (d) {
+            strcpy(d, s0);
+            return d0;
+        }
+    }
+}
+
+static int execvp_win32(const char *prog, char **argv)
+{
+    int ret; char **p;
+    /* replace all " by \" */
+    for (p = argv; *p; ++p)
+        if (strchr(*p, '"'))
+            *p = str_replace(*p, "\"", "\\\"");
+    ret = _spawnvp(P_NOWAIT, prog, (const char *const*)argv);
+    if (-1 == ret)
+        return ret;
+    _cwait(&ret, ret, WAIT_CHILD);
+    exit(ret);
+}
+#define execvp execvp_win32
+#endif /* _WIN32 */
+
+ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int target)
+{
+    char program[4096];
+    char *a0 = argv[0];
+    int prefix = tcc_basename(a0) - a0;
+
+    snprintf(program, sizeof program,
+        "%.*s%s"
+#ifdef TCC_TARGET_PE
+        "-win32"
+#endif
+        "-tcc"
+#ifdef _WIN32
+        ".exe"
+#endif
+        , prefix, a0, target == 64 ? "x86_64" : "i386");
+
+    if (strcmp(a0, program))
+        execvp(argv[0] = program, argv);
+    tcc_error("could not run '%s'", program);
+}
+
+#endif /* TCC_TARGET_I386 && TCC_TARGET_X86_64 */
+/* -------------------------------------------------------------- */
+/* enable commandline wildcard expansion (tcc -o x.exe *.c) */
+
+#ifdef _WIN32
+int _CRT_glob = 1;
+#ifndef _CRT_glob
+int _dowildcard = 1;
+#endif
+#endif
+
+/* -------------------------------------------------------------- */
+/* generate xxx.d file */
+
+ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename)
+{
+    FILE *depout;
+    char buf[1024];
+    int i;
+
+    if (!filename) {
+        /* compute filename automatically: dir/file.o -> dir/file.d */
+        snprintf(buf, sizeof buf, "%.*s.d",
+            (int)(tcc_fileextension(target) - target), target);
+        filename = buf;
+    }
+
+    if (s->verbose)
+        printf("<- %s\n", filename);
+
+    /* XXX return err codes instead of error() ? */
+    depout = fopen(filename, "w");
+    if (!depout)
+        tcc_error("could not open '%s'", filename);
+
+    fprintf(depout, "%s: \\\n", target);
+    for (i=0; i<s->nb_target_deps; ++i)
+        fprintf(depout, " %s \\\n", s->target_deps[i]);
+    fprintf(depout, "\n");
+    fclose(depout);
+}
+
+/* -------------------------------------------------------------- */
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/42test.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/42test.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/42test.h	(revision 331)
@@ -0,0 +1,13 @@
+/* This file is to test compute #include directives.  It's named so
+   that it starts with a pre-processing number which isn't a valid
+   number (42test.h).  Including this must work.  */
+#ifndef INC42_FIRST
+int have_included_42test_h;
+#define INC42_FIRST
+#elif !defined INC42_SECOND
+#define INC42_SECOND
+int have_included_42test_h_second;
+#else
+#define INC42_THIRD
+int have_included_42test_h_third;
+#endif
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/Makefile
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/Makefile	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/Makefile	(revision 331)
@@ -0,0 +1,289 @@
+#
+# Tiny C Compiler Makefile - tests
+#
+
+TOP = ..
+include $(TOP)/Makefile
+VPATH = $(TOPSRC)/tests $(TOPSRC) $(TOP)
+CFLAGS := $(filter-out -W% -g% -O%,$(CFLAGS)) -I$(TOPSRC) $(LDFLAGS)
+
+# what tests to run
+TESTS = \
+ hello-exe \
+ hello-run \
+ libtest \
+ test3 \
+ memtest \
+ dlltest \
+ abitest \
+ asm-c-connect-test \
+ vla_test-run \
+ cross-test \
+ tests2-dir \
+ pp-dir
+
+BTESTS = test1b test3b btest
+
+# test4 -- problem with -static
+# asmtest / asmtest2 -- minor differences with gcc
+# btest -- works on i386 (including win32)
+
+# bounds-checking is supported only on i386
+ifneq ($(ARCH),i386)
+ TESTS := $(filter-out $(BTESTS),$(TESTS))
+endif
+ifdef CONFIG_WIN32
+ TESTS := $(filter-out $(BTESTS),$(TESTS))
+endif
+ifdef CONFIG_OSX # -run only
+ TESTS := hello-run libtest tests2-dir pp-dir
+endif
+ifeq (,$(filter arm64 i386 x86_64,$(ARCH)))
+ TESTS := $(filter-out vla_test-run,$(TESTS))
+endif
+ifeq ($(CONFIG_arm_eabi),yes)
+ TESTS := $(filter-out test3,$(TESTS))
+endif
+ifeq (,$(filter i386 x86_64,$(ARCH)))
+ TESTS := $(filter-out dlltest asm-c-connect-test,$(TESTS))
+endif
+ifndef CONFIG_cross
+ TESTS := $(filter-out cross-%,$(TESTS))
+endif
+
+ifeq ($(OS),Windows_NT) # for libtcc_test to find libtcc.dll
+ PATH := $(CURDIR)/$(TOP)$(if $(findstring :\,$(PATH)),;,:)$(PATH)
+endif
+
+RUN_TCC = $(NATIVE_DEFINES) -run $(TOPSRC)/tcc.c $(TCCFLAGS)
+DISAS = objdump -d
+DUMPTCC = (set -x; $(TOP)/tcc -vv; ldd $(TOP)/tcc; exit 1)
+
+all test : clean-s $(TESTS)
+
+hello-exe: ../examples/ex1.c
+	@echo ------------ $@ ------------
+	$(TCC) $< -o hello$(EXESUF) && ./hello$(EXESUF) || $(DUMPTCC)
+
+hello-run: ../examples/ex1.c
+	@echo ------------ $@ ------------
+	$(TCC) -run $< || $(DUMPTCC)
+
+libtest: libtcc_test$(EXESUF)
+	@echo ------------ $@ ------------
+	./libtcc_test$(EXESUF) $(TCCFLAGS)
+
+libtcc_test$(EXESUF): libtcc_test.c $(LIBTCC)
+	$(CC) -o $@ $^ $(CFLAGS) $(LIBS)
+
+%-dir:
+	@echo ------------ $@ ------------
+	$(MAKE) -k -C $*
+
+# test.ref - generate using cc
+test.ref: tcctest.c
+	$(CC) -o tcctest.gcc $< $(NATIVE_DEFINES) $(CFLAGS) -w -O0 -std=gnu99 -fno-omit-frame-pointer
+	./tcctest.gcc > $@
+
+# auto test
+test1 test1b: tcctest.c test.ref
+	@echo ------------ $@ ------------
+	$(TCC) -run $< > test.out1
+	@diff -u test.ref test.out1 && echo "Auto Test OK"
+
+# iterated test2 (compile tcc then compile tcctest.c !)
+test2 test2b: tcctest.c test.ref
+	@echo ------------ $@ ------------
+	$(TCC) $(RUN_TCC) $(RUN_TCC) -run $< > test.out2
+	@diff -u test.ref test.out2 && echo "Auto Test2 OK"
+
+# iterated test3 (compile tcc then compile tcc then compile tcctest.c !)
+test3 test3b: tcctest.c test.ref
+	@echo ------------ $@ ------------
+	$(TCC) $(RUN_TCC) $(RUN_TCC) $(RUN_TCC) -run $< > test.out3
+	@diff -u test.ref test.out3 && echo "Auto Test3 OK"
+
+test%b : TCCFLAGS += -b
+
+# binary output test
+test4: tcctest.c test.ref
+	@echo ------------ $@ ------------
+# object + link output
+	$(TCC) -c -o tcctest3.o $<
+	$(TCC) -o tcctest3 tcctest3.o
+	./tcctest3 > test3.out
+	@if diff -u test.ref test3.out ; then echo "Object Auto Test OK"; fi
+# dynamic output
+	$(TCC) -o tcctest1 $<
+	./tcctest1 > test1.out
+	@if diff -u test.ref test1.out ; then echo "Dynamic Auto Test OK"; fi
+# dynamic output + bound check
+	$(TCC) -b -o tcctest4 $<
+	./tcctest4 > test4.out
+	@if diff -u test.ref test4.out ; then echo "BCheck Auto Test OK"; fi
+# static output
+	$(TCC) -static -o tcctest2 $<
+	./tcctest2 > test2.out
+	@if diff -u test.ref test2.out ; then echo "Static Auto Test OK"; fi
+
+# use tcc to create libtcc.so/.dll and the tcc(.exe) frontend and run them
+dlltest:
+	@echo ------------ $@ ------------
+	$(TCC) $(NATIVE_DEFINES) -DLIBTCC_AS_DLL $(TOPSRC)/libtcc.c $(LIBS) -shared -o libtcc2$(DLLSUF)
+	$(TCC) $(NATIVE_DEFINES) -DONE_SOURCE=0 $(TOPSRC)/tcc.c libtcc2$(DLLSUF) $(LIBS) -Wl,-rpath=. -o tcc2$(EXESUF)
+	./tcc2$(EXESUF) $(TCCFLAGS) $(RUN_TCC) -run $(TOPSRC)/examples/ex1.c
+ifndef CONFIG_WIN32
+	@echo ------------ $@ with PIC ------------
+	$(CC) $(CFLAGS) -fPIC $(NATIVE_DEFINES) -DLIBTCC_AS_DLL -c $(TOPSRC)/libtcc.c
+	$(TCC) libtcc.o $(LIBS) -shared -o libtcc2$(DLLSUF)
+	$(TCC) $(NATIVE_DEFINES) -DONE_SOURCE=0 $(TOPSRC)/tcc.c libtcc2$(DLLSUF) $(LIBS) -Wl,-rpath=. -o tcc2$(EXESUF)
+	./tcc2$(EXESUF) $(TCCFLAGS) $(RUN_TCC) -run $(TOPSRC)/examples/ex1.c
+endif
+	@rm tcc2$(EXESUF) libtcc2$(DLLSUF)
+
+memtest:
+	@echo ------------ $@ ------------
+	$(CC) $(CFLAGS) $(NATIVE_DEFINES) -DMEM_DEBUG=2 $(TOPSRC)/tcc.c $(LIBS) -o memtest-tcc$(EXESUF)
+	./memtest-tcc$(EXESUF) $(TCCFLAGS) $(NATIVE_DEFINES) $(TOPSRC)/tcc.c $(LIBS)
+	./memtest-tcc$(EXESUF) $(TCCFLAGS) $(NATIVE_DEFINES) -run $(TOPSRC)/tcc.c $(TCCFLAGS) $(TOPSRC)/tests/tcctest.c
+
+
+# memory and bound check auto test
+BOUNDS_OK  = 1 4 8 10 14
+BOUNDS_FAIL= 2 5 7 9 11 12 13 15
+
+btest: boundtest.c
+	@echo ------------ $@ ------------
+	@for i in $(BOUNDS_OK); do \
+	   echo ; echo --- boundtest $$i ---; \
+	   if $(TCC) -b -run $< $$i ; then \
+	       echo succeeded as expected; \
+	   else\
+	       echo Failed positive test $$i ; exit 1 ; \
+	   fi ;\
+	done ;\
+	for i in $(BOUNDS_FAIL); do \
+	   echo ; echo --- boundtest $$i ---; \
+	   if $(TCC) -b -run $< $$i ; then \
+	       echo Failed negative test $$i ; exit 1 ;\
+	   else\
+	       echo failed as expected; \
+	   fi ;\
+	done ;\
+	echo; echo Bound test OK
+
+# speed test
+speedtest: ex2 ex3
+	@echo ------------ $@ ------------
+	time ./ex2 1238 2 3 4 10 13 4
+	time $(TCC) -run $(TOPSRC)/examples/ex2.c 1238 2 3 4 10 13 4
+	time ./ex3 35
+	time $(TCC) -run $(TOPSRC)/examples/ex3.c 35
+
+weaktest: tcctest.c test.ref
+	$(TCC) -c $< -o weaktest.tcc.o
+	$(CC) -c $< -o weaktest.gcc.o $(NATIVE_DEFINES) $(CFLAGS) -w -O0 -std=gnu99 -fno-omit-frame-pointer
+	objdump -t weaktest.tcc.o | grep ' w ' | sed -e 's/.* \([a-zA-Z0-9_]*\)$$/\1/' | LC_ALL=C sort > weaktest.tcc.o.txt
+	objdump -t weaktest.gcc.o | grep ' w ' | sed -e 's/.* \([a-zA-Z0-9_]*\)$$/\1/' | LC_ALL=C sort > weaktest.gcc.o.txt
+	diff weaktest.gcc.o.txt weaktest.tcc.o.txt && echo "Weak Auto Test OK"
+
+ex%: $(TOPSRC)/examples/ex%.c
+	$(CC) -o $@ $< $(CFLAGS)
+
+# tiny assembler testing
+asmtest.ref: asmtest.S
+	$(CC) -Wa,-W -o asmtest.ref.o -c asmtest.S
+	objdump -D asmtest.ref.o > asmtest.ref
+
+asmtest asmtest2: asmtest.ref
+	@echo ------------ $@ ------------
+	$(TCC) $(MAYBE_RUN_TCC) -c asmtest.S
+	objdump -D asmtest.o > asmtest.out
+	@if diff -u --ignore-matching-lines="file format" asmtest.ref asmtest.out ; then echo "ASM Auto Test OK"; fi
+
+# test assembler with tcc compiled by itself
+asmtest2: MAYBE_RUN_TCC = $(RUN_TCC)
+
+# Check that code generated by libtcc is binary compatible with
+# that generated by CC
+abitest-cc$(EXESUF): abitest.c $(LIBTCC)
+	$(CC) -o $@ $^ $(CFLAGS) $(LIBS) -w
+
+abitest-tcc$(EXESUF): abitest.c libtcc.c
+	$(TCC) -o $@ $^ $(NATIVE_DEFINES) $(LIBS)
+
+ABITESTS := abitest-cc$(EXESUF)
+ifneq ($(CONFIG_arm_eabi),yes) # not ARM soft-float
+ ABITESTS += abitest-tcc$(EXESUF)
+endif
+
+abitest: $(ABITESTS)
+	@echo ------------ $@ ------------
+	./abitest-cc$(EXESUF) $(TCCFLAGS)
+ifneq ($(CONFIG_arm_eabi),yes) # not ARM soft-float
+	./abitest-tcc$(EXESUF) $(TCCFLAGS)
+endif
+
+vla_test$(EXESUF): vla_test.c
+	$(TCC) -o $@ $^
+
+vla_test-run: vla_test$(EXESUF)
+	@echo ------------ $@ ------------
+	./vla_test$(EXESUF)
+
+asm-c-connect$(EXESUF): asm-c-connect-1.c asm-c-connect-2.c
+	$(TCC) -o $@ $^
+
+asm-c-connect-%.o: asm-c-connect-%.c
+	$(TCC) -c -o $@ $<
+
+asm-c-connect-sep$(EXESUF): asm-c-connect-1.o asm-c-connect-2.o
+	$(TCC) -o $@ $^
+
+asm-c-connect-test: asm-c-connect$(EXESUF) asm-c-connect-sep$(EXESUF)
+	@echo ------------ $@ ------------
+	./asm-c-connect$(EXESUF) > asm-c-connect.out1 && cat asm-c-connect.out1
+	./asm-c-connect-sep$(EXESUF) > asm-c-connect.out2 && cat asm-c-connect.out2
+	@diff -u asm-c-connect.out1 asm-c-connect.out2 && echo "ok"
+
+cross-test :
+	@echo ------------ $@ ------------
+	$(TOP)/i386-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+	$(TOP)/i386-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/examples/ex3.c && echo "ok"
+	$(TOP)/x86_64-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+	$(TOP)/x86_64-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/examples/ex3.c && echo "ok"
+	$(TOP)/arm-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+	$(TOP)/arm-wince-tcc$(EXESUF) $(TCCFLAGS-win) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+	$(TOP)/arm64-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+	$(TOP)/c67-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok"
+	$(TOP)/i386-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/win32/examples/hello_win.c && echo "ok"
+	$(TOP)/x86_64-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/win32/examples/hello_win.c && echo "ok"
+	$(TOP)/arm-wince-tcc$(EXESUF) $(TCCFLAGS-win) -c $(TOPSRC)/win32/examples/hello_win.c && echo "ok"
+
+# targets for development
+%.bin: %.c tcc
+	$(TCC) -g -o $@ $<
+	$(DISAS) $@
+
+instr: instr.o
+	objdump -d instr.o
+
+instr.o: instr.S
+	$(CC) -o $@ -c $< -O2 -Wall -g
+
+cache: tcc_g
+	cachegrind ./tcc_g -o /tmp/linpack -lm bench/linpack.c
+	vg_annotate tcc.c > /tmp/linpack.cache.log
+
+# clean
+clean:
+	rm -f *~ *.o *.a *.bin *.i *.ref *.out *.out? *.out?b *.cc *.gcc
+	rm -f *-cc *-gcc *-tcc *.exe hello libtcc_test vla_test tcctest[1234]
+	rm -f asm-c-connect$(EXESUF)
+	rm -f ex? tcc_g weaktest.*.txt *.def
+	@$(MAKE) -C tests2 $@
+	@$(MAKE) -C pp $@
+
+# silent clean, used before running tests
+clean-s:
+	@$(MAKE) -s --no-print-directory clean
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/abitest.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/abitest.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/abitest.c	(revision 331)
@@ -0,0 +1,691 @@
+#include <libtcc.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+// MinGW has 80-bit rather than 64-bit long double which isn't compatible with TCC or MSVC
+#if defined(_WIN32) && defined(__GNUC__)
+#define LONG_DOUBLE double
+#define LONG_DOUBLE_LITERAL(x) x
+#else
+#define LONG_DOUBLE long double
+#define LONG_DOUBLE_LITERAL(x) x ## L
+#endif
+
+static int g_argc;
+static char **g_argv;
+
+static void set_options(TCCState *s, int argc, char **argv)
+{
+    int i;
+    for (i = 1; i < argc; ++i) {
+        char *a = argv[i];
+        if (a[0] == '-') {
+            if (a[1] == 'B')
+                tcc_set_lib_path(s, a+2);
+            else if (a[1] == 'I')
+                tcc_add_include_path(s, a+2);
+            else if (a[1] == 'L')
+                tcc_add_library_path(s, a+2);
+        }
+    }
+}
+
+typedef int (*callback_type) (void*);
+
+/*
+ * Compile source code and call a callback with a pointer to the symbol "f".
+ */
+static int run_callback(const char *src, callback_type callback) {
+  TCCState *s;
+  int result;
+  void *ptr;
+  
+  s = tcc_new();
+  if (!s)
+    return -1;
+
+  set_options(s, g_argc, g_argv);
+
+  if (tcc_set_output_type(s, TCC_OUTPUT_MEMORY) == -1)
+    return -1;
+  if (tcc_compile_string(s, src) == -1)
+    return -1;
+  if (tcc_relocate(s, TCC_RELOCATE_AUTO) == -1)
+    return -1;
+  
+  ptr = tcc_get_symbol(s, "f");
+  if (!ptr)
+    return -1;
+  result = callback(ptr);
+  
+  tcc_delete(s);
+  
+  return result;
+}
+
+#define STR2(x) #x
+#define STR(x) STR2(x)
+
+#define RET_PRIMITIVE_TEST(name, type, val) \
+  static int ret_ ## name ## _test_callback(void *ptr) { \
+    type (*callback) (type) = (type(*)(type))ptr; \
+    type x = val; \
+    type y = callback(x); \
+    return (y == x+x) ? 0 : -1; \
+  } \
+  \
+  static int ret_ ## name ## _test(void) { \
+    const char *src = STR(type) " f(" STR(type) " x) {return x+x;}"; \
+    return run_callback(src, ret_ ## name ## _test_callback); \
+  }
+
+RET_PRIMITIVE_TEST(int, int, 70000)
+RET_PRIMITIVE_TEST(longlong, long long, 4333369356528LL)
+RET_PRIMITIVE_TEST(float, float, 63.0)
+RET_PRIMITIVE_TEST(double, double, 14789798.0)
+RET_PRIMITIVE_TEST(longdouble, LONG_DOUBLE, LONG_DOUBLE_LITERAL(378943892.0))
+
+/*
+ * ret_2float_test:
+ * 
+ * On x86-64, a struct with 2 floats should be packed into a single
+ * SSE register (VT_DOUBLE is used for this purpose).
+ */
+typedef struct ret_2float_test_type_s {float x, y;} ret_2float_test_type;
+typedef ret_2float_test_type (*ret_2float_test_function_type) (ret_2float_test_type);
+
+static int ret_2float_test_callback(void *ptr) {
+  ret_2float_test_function_type f = (ret_2float_test_function_type)ptr;
+  ret_2float_test_type a = {10, 35};
+  ret_2float_test_type r;
+  r = f(a);
+  return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
+}
+
+static int ret_2float_test(void) {
+  const char *src =
+  "typedef struct ret_2float_test_type_s {float x, y;} ret_2float_test_type;"
+  "ret_2float_test_type f(ret_2float_test_type a) {\n"
+  "  ret_2float_test_type r = {a.x*5, a.y*3};\n"
+  "  return r;\n"
+  "}\n";
+
+  return run_callback(src, ret_2float_test_callback);
+}
+
+/*
+ * ret_2double_test:
+ * 
+ * On x86-64, a struct with 2 doubles should be passed in two SSE
+ * registers.
+ */
+typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type;
+typedef ret_2double_test_type (*ret_2double_test_function_type) (ret_2double_test_type);
+
+static int ret_2double_test_callback(void *ptr) {
+  ret_2double_test_function_type f = (ret_2double_test_function_type)ptr;
+  ret_2double_test_type a = {10, 35};
+  ret_2double_test_type r;
+  r = f(a);
+  return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
+}
+
+static int ret_2double_test(void) {
+  const char *src =
+  "typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type;"
+  "ret_2double_test_type f(ret_2double_test_type a) {\n"
+  "  ret_2double_test_type r = {a.x*5, a.y*3};\n"
+  "  return r;\n"
+  "}\n";
+
+  return run_callback(src, ret_2double_test_callback);
+}
+
+/*
+ * ret_8plus2double_test:
+ *
+ * This catches a corner case in the x86_64 ABI code: the first 7
+ * arguments fit into registers, the 8th doesn't, but the 9th argument
+ * fits into the 8th XMM register.
+ *
+ * Note that the purpose of the 10th argument is to avoid a situation
+ * in which gcc would accidentally put the double at the right
+ * address, thus causing a success message even though TCC actually
+ * generated incorrect code.
+ */
+typedef ret_2double_test_type (*ret_8plus2double_test_function_type) (double, double, double, double, double, double, double, ret_2double_test_type, double, double);
+
+static int ret_8plus2double_test_callback(void *ptr) {
+  ret_8plus2double_test_function_type f = (ret_8plus2double_test_function_type)ptr;
+  ret_2double_test_type a = {10, 35};
+  ret_2double_test_type r;
+  r = f(0, 0, 0, 0, 0, 0, 0, a, 37, 38);
+  return ((r.x == 37) && (r.y == 37)) ? 0 : -1;
+}
+
+static int ret_8plus2double_test(void) {
+  const char *src =
+  "typedef struct ret_2double_test_type_s {double x, y;} ret_2double_test_type;"
+  "ret_2double_test_type f(double x1, double x2, double x3, double x4, double x5, double x6, double x7, ret_2double_test_type a, double x8, double x9) {\n"
+  "  ret_2double_test_type r = { x8, x8 };\n"
+  "  return r;\n"
+  "}\n";
+
+  return run_callback(src, ret_8plus2double_test_callback);
+}
+
+/*
+ * ret_mixed_test:
+ *
+ * On x86-64, a struct with a double and a 64-bit integer should be
+ * passed in one SSE register and one integer register.
+ */
+typedef struct ret_mixed_test_type_s {double x; long long y;} ret_mixed_test_type;
+typedef ret_mixed_test_type (*ret_mixed_test_function_type) (ret_mixed_test_type);
+
+static int ret_mixed_test_callback(void *ptr) {
+  ret_mixed_test_function_type f = (ret_mixed_test_function_type)ptr;
+  ret_mixed_test_type a = {10, 35};
+  ret_mixed_test_type r;
+  r = f(a);
+  return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
+}
+
+static int ret_mixed_test(void) {
+  const char *src =
+  "typedef struct ret_mixed_test_type_s {double x; long long y;} ret_mixed_test_type;"
+  "ret_mixed_test_type f(ret_mixed_test_type a) {\n"
+  "  ret_mixed_test_type r = {a.x*5, a.y*3};\n"
+  "  return r;\n"
+  "}\n";
+
+  return run_callback(src, ret_mixed_test_callback);
+}
+
+/*
+ * ret_mixed2_test:
+ *
+ * On x86-64, a struct with two floats and two 32-bit integers should
+ * be passed in one SSE register and one integer register.
+ */
+typedef struct ret_mixed2_test_type_s {float x,x2; int y,y2;} ret_mixed2_test_type;
+typedef ret_mixed2_test_type (*ret_mixed2_test_function_type) (ret_mixed2_test_type);
+
+static int ret_mixed2_test_callback(void *ptr) {
+  ret_mixed2_test_function_type f = (ret_mixed2_test_function_type)ptr;
+  ret_mixed2_test_type a = {10, 5, 35, 7 };
+  ret_mixed2_test_type r;
+  r = f(a);
+  return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
+}
+
+static int ret_mixed2_test(void) {
+  const char *src =
+  "typedef struct ret_mixed2_test_type_s {float x, x2; int y,y2;} ret_mixed2_test_type;"
+  "ret_mixed2_test_type f(ret_mixed2_test_type a) {\n"
+  "  ret_mixed2_test_type r = {a.x*5, 0, a.y*3, 0};\n"
+  "  return r;\n"
+  "}\n";
+
+  return run_callback(src, ret_mixed2_test_callback);
+}
+
+/*
+ * ret_mixed3_test:
+ *
+ * On x86-64, this struct should be passed in two integer registers.
+ */
+typedef struct ret_mixed3_test_type_s {float x; int y; float x2; int y2;} ret_mixed3_test_type;
+typedef ret_mixed3_test_type (*ret_mixed3_test_function_type) (ret_mixed3_test_type);
+
+static int ret_mixed3_test_callback(void *ptr) {
+  ret_mixed3_test_function_type f = (ret_mixed3_test_function_type)ptr;
+  ret_mixed3_test_type a = {10, 5, 35, 7 };
+  ret_mixed3_test_type r;
+  r = f(a);
+  return ((r.x == a.x*5) && (r.y2 == a.y*3)) ? 0 : -1;
+}
+
+static int ret_mixed3_test(void) {
+  const char *src =
+  "typedef struct ret_mixed3_test_type_s {float x; int y; float x2; int y2;} ret_mixed3_test_type;"
+  "ret_mixed3_test_type f(ret_mixed3_test_type a) {\n"
+  "  ret_mixed3_test_type r = {a.x*5, 0, 0, a.y*3};\n"
+  "  return r;\n"
+  "}\n";
+
+  return run_callback(src, ret_mixed3_test_callback);
+}
+
+/*
+ * reg_pack_test: return a small struct which should be packed into
+ * registers (Win32) during return.
+ */
+typedef struct reg_pack_test_type_s {int x, y;} reg_pack_test_type;
+typedef reg_pack_test_type (*reg_pack_test_function_type) (reg_pack_test_type);
+
+static int reg_pack_test_callback(void *ptr) {
+  reg_pack_test_function_type f = (reg_pack_test_function_type)ptr;
+  reg_pack_test_type a = {10, 35};
+  reg_pack_test_type r;
+  r = f(a);
+  return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
+}
+
+static int reg_pack_test(void) {
+  const char *src =
+  "typedef struct reg_pack_test_type_s {int x, y;} reg_pack_test_type;"
+  "reg_pack_test_type f(reg_pack_test_type a) {\n"
+  "  reg_pack_test_type r = {a.x*5, a.y*3};\n"
+  "  return r;\n"
+  "}\n";
+  
+  return run_callback(src, reg_pack_test_callback);
+}
+
+/*
+ * reg_pack_longlong_test: return a small struct which should be packed into
+ * registers (x86-64) during return.
+ */
+typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type;
+typedef reg_pack_longlong_test_type (*reg_pack_longlong_test_function_type) (reg_pack_longlong_test_type);
+
+static int reg_pack_longlong_test_callback(void *ptr) {
+  reg_pack_longlong_test_function_type f = (reg_pack_longlong_test_function_type)ptr;
+  reg_pack_longlong_test_type a = {10, 35};
+  reg_pack_longlong_test_type r;
+  r = f(a);
+  return ((r.x == a.x*5) && (r.y == a.y*3)) ? 0 : -1;
+}
+
+static int reg_pack_longlong_test(void) {
+  const char *src =
+  "typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type;"
+  "reg_pack_longlong_test_type f(reg_pack_longlong_test_type a) {\n"
+  "  reg_pack_longlong_test_type r = {a.x*5, a.y*3};\n"
+  "  return r;\n"
+  "}\n";
+  
+  return run_callback(src, reg_pack_longlong_test_callback);
+}
+
+/*
+ * ret_6plus2longlong_test:
+ *
+ * This catches a corner case in the x86_64 ABI code: the first 5
+ * arguments fit into registers, the 6th doesn't, but the 7th argument
+ * fits into the 6th argument integer register, %r9.
+ *
+ * Note that the purpose of the 10th argument is to avoid a situation
+ * in which gcc would accidentally put the longlong at the right
+ * address, thus causing a success message even though TCC actually
+ * generated incorrect code.
+ */
+typedef reg_pack_longlong_test_type (*ret_6plus2longlong_test_function_type) (long long, long long, long long, long long, long long, reg_pack_longlong_test_type, long long, long long);
+
+static int ret_6plus2longlong_test_callback(void *ptr) {
+  ret_6plus2longlong_test_function_type f = (ret_6plus2longlong_test_function_type)ptr;
+  reg_pack_longlong_test_type a = {10, 35};
+  reg_pack_longlong_test_type r;
+  r = f(0, 0, 0, 0, 0, a, 37, 38);
+  return ((r.x == 37) && (r.y == 37)) ? 0 : -1;
+}
+
+static int ret_6plus2longlong_test(void) {
+  const char *src =
+  "typedef struct reg_pack_longlong_test_type_s {long long x, y;} reg_pack_longlong_test_type;"
+  "reg_pack_longlong_test_type f(long long x1, long long x2, long long x3, long long x4, long long x5, reg_pack_longlong_test_type a, long long x8, long long x9) {\n"
+  "  reg_pack_longlong_test_type r = { x8, x8 };\n"
+  "  return r;\n"
+  "}\n";
+
+  return run_callback(src, ret_6plus2longlong_test_callback);
+}
+
+/*
+ * sret_test: Create a struct large enough to be returned via sret
+ * (hidden pointer as first function argument)
+ */
+typedef struct sret_test_type_s {long long a, b, c;} sret_test_type;
+typedef sret_test_type (*sret_test_function_type) (sret_test_type);
+
+static int sret_test_callback(void *ptr) {
+  sret_test_function_type f = (sret_test_function_type)(ptr);
+  sret_test_type x = {5436LL, 658277698LL, 43878957LL};
+  sret_test_type r = f(x);
+  return ((r.a==x.a*35)&&(r.b==x.b*19)&&(r.c==x.c*21)) ? 0 : -1;
+}
+
+static int sret_test(void) {
+  const char *src =
+  "typedef struct sret_test_type_s {long long a, b, c;} sret_test_type;\n"
+  "sret_test_type f(sret_test_type x) {\n"
+  "  sret_test_type r = {x.a*35, x.b*19, x.c*21};\n"
+  "  return r;\n"
+  "}\n";
+  
+  return run_callback(src, sret_test_callback);
+}
+
+/*
+ * one_member_union_test:
+ * 
+ * In the x86-64 ABI a union should always be passed on the stack. However
+ * it appears that a single member union is treated by GCC as its member.
+ */
+typedef union one_member_union_test_type_u {int x;} one_member_union_test_type;
+typedef one_member_union_test_type (*one_member_union_test_function_type) (one_member_union_test_type);
+
+static int one_member_union_test_callback(void *ptr) {
+  one_member_union_test_function_type f = (one_member_union_test_function_type)ptr;
+  one_member_union_test_type a, b;
+  a.x = 34;
+  b = f(a);
+  return (b.x == a.x*2) ? 0 : -1;
+}
+
+static int one_member_union_test(void) {
+  const char *src =
+  "typedef union one_member_union_test_type_u {int x;} one_member_union_test_type;\n"
+  "one_member_union_test_type f(one_member_union_test_type a) {\n"
+  "  one_member_union_test_type b;\n"
+  "  b.x = a.x * 2;\n"
+  "  return b;\n"
+  "}\n";
+  return run_callback(src, one_member_union_test_callback);
+}
+
+/*
+ * two_member_union_test:
+ * 
+ * In the x86-64 ABI a union should always be passed on the stack.
+ */
+typedef union two_member_union_test_type_u {int x; long y;} two_member_union_test_type;
+typedef two_member_union_test_type (*two_member_union_test_function_type) (two_member_union_test_type);
+
+static int two_member_union_test_callback(void *ptr) {
+  two_member_union_test_function_type f = (two_member_union_test_function_type)ptr;
+  two_member_union_test_type a, b;
+  a.x = 34;
+  b = f(a);
+  return (b.x == a.x*2) ? 0 : -1;
+}
+
+static int two_member_union_test(void) {
+  const char *src =
+  "typedef union two_member_union_test_type_u {int x; long y;} two_member_union_test_type;\n"
+  "two_member_union_test_type f(two_member_union_test_type a) {\n"
+  "  two_member_union_test_type b;\n"
+  "  b.x = a.x * 2;\n"
+  "  return b;\n"
+  "}\n";
+  return run_callback(src, two_member_union_test_callback);
+}
+
+/*
+ * Win64 calling convention test.
+ */
+
+typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type;
+typedef many_struct_test_type (*many_struct_test_function_type) (many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type);
+ 
+static int many_struct_test_callback(void *ptr) {
+  many_struct_test_function_type f = (many_struct_test_function_type)ptr;
+  many_struct_test_type v = {1, 2, 3};
+  many_struct_test_type r = f(v,v,v,v,v,v);
+  return ((r.a == 6) && (r.b == 12) && (r.c == 18))?0:-1;
+}
+
+static int many_struct_test(void) {
+  const char *src =
+  "typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type;\n"
+  "many_struct_test_type f(many_struct_test_type x1, many_struct_test_type x2, many_struct_test_type x3, many_struct_test_type x4, many_struct_test_type x5, many_struct_test_type x6) {\n"
+  "  many_struct_test_type y;\n"
+  "  y.a = x1.a + x2.a + x3.a + x4.a + x5.a + x6.a;\n"
+  "  y.b = x1.b + x2.b + x3.b + x4.b + x5.b + x6.b;\n"
+  "  y.c = x1.c + x2.c + x3.c + x4.c + x5.c + x6.c;\n"
+  "  return y;\n"
+  "}\n";
+  return run_callback(src, many_struct_test_callback);
+}
+
+/*
+ * Win64 calling convention test.
+ */
+
+typedef struct many_struct_test_2_type_s {int a, b;} many_struct_test_2_type;
+typedef many_struct_test_2_type (*many_struct_test_2_function_type) (many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type);
+ 
+static int many_struct_test_2_callback(void *ptr) {
+  many_struct_test_2_function_type f = (many_struct_test_2_function_type)ptr;
+  many_struct_test_2_type v = {1,2};
+  many_struct_test_2_type r = f(v,v,v,v,v,v);
+  return ((r.a == 6) && (r.b == 12))?0:-1;
+}
+
+static int many_struct_test_2(void) {
+  const char *src =
+  "typedef struct many_struct_test_2_type_s {int a, b;} many_struct_test_2_type;\n"
+  "many_struct_test_2_type f(many_struct_test_2_type x1, many_struct_test_2_type x2, many_struct_test_2_type x3, many_struct_test_2_type x4, many_struct_test_2_type x5, many_struct_test_2_type x6) {\n"
+  "  many_struct_test_2_type y;\n"
+  "  y.a = x1.a + x2.a + x3.a + x4.a + x5.a + x6.a;\n"
+  "  y.b = x1.b + x2.b + x3.b + x4.b + x5.b + x6.b;\n"
+  "  return y;\n"
+  "}\n";
+  return run_callback(src, many_struct_test_2_callback);
+}
+
+/*
+ * Win64 calling convention test.
+ */
+
+typedef struct many_struct_test_3_type_s {int a, b;} many_struct_test_3_type;
+typedef many_struct_test_3_type (*many_struct_test_3_function_type) (many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type,many_struct_test_3_type, ...);
+typedef struct many_struct_test_3_struct_type { many_struct_test_3_function_type f; many_struct_test_3_function_type *f2; } many_struct_test_3_struct_type;
+
+static void many_struct_test_3_dummy(double d, ...)
+{
+  volatile double x = d;
+}
+
+static int many_struct_test_3_callback(void *ptr) {
+  many_struct_test_3_struct_type s = { ptr, };
+  many_struct_test_3_struct_type *s2 = &s;
+  s2->f2 = &s2->f;
+  many_struct_test_3_dummy(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, &s2);
+  many_struct_test_3_function_type f = *(s2->f2);
+  many_struct_test_3_type v = {1,2};
+  many_struct_test_3_type r = (*((s2->f2=&f)+0))(v,v,v,v,v,v,1.0);
+  return ((r.a == 6) && (r.b == 12))?0:-1;
+}
+
+static int many_struct_test_3(void) {
+  const char *src =
+  "typedef struct many_struct_test_3_type_s {int a, b;} many_struct_test_3_type;\n"
+  "many_struct_test_3_type f(many_struct_test_3_type x1, many_struct_test_3_type x2, many_struct_test_3_type x3, many_struct_test_3_type x4, many_struct_test_3_type x5, many_struct_test_3_type x6, ...) {\n"
+  "  many_struct_test_3_type y;\n"
+  "  y.a = x1.a + x2.a + x3.a + x4.a + x5.a + x6.a;\n"
+  "  y.b = x1.b + x2.b + x3.b + x4.b + x5.b + x6.b;\n"
+  "  return y;\n"
+  "}\n";
+  return run_callback(src, many_struct_test_3_callback);
+}
+
+/*
+ * stdarg_test: Test variable argument list ABI
+ */
+
+typedef struct {long long a, b, c;} stdarg_test_struct_type;
+typedef void (*stdarg_test_function_type) (int,int,int,...);
+
+static int stdarg_test_callback(void *ptr) {
+  stdarg_test_function_type f = (stdarg_test_function_type)ptr;
+  int x;
+  double y;
+  stdarg_test_struct_type z = {1, 2, 3}, w;
+  f(10, 10, 5,
+    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, &x,
+    1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, &y,
+    z, z, z, z, z, &w);
+  return ((x == 55) && (y == 55) && (w.a == 5) && (w.b == 10) && (w.c == 15)) ? 0 : -1;
+}
+
+static int stdarg_test(void) {
+  const char *src =
+  "#include <stdarg.h>\n"
+  "typedef struct {long long a, b, c;} stdarg_test_struct_type;\n"
+  "void f(int n_int, int n_float, int n_struct, ...) {\n"
+  "  int i, ti = 0;\n"
+  "  double td = 0.0;\n"
+  "  stdarg_test_struct_type ts = {0,0,0}, tmp;\n"
+  "  va_list ap;\n"
+  "  va_start(ap, n_struct);\n"
+  "  for (i = 0, ti = 0; i < n_int; ++i)\n"
+  "    ti += va_arg(ap, int);\n"
+  "  *va_arg(ap, int*) = ti;\n"
+  "  for (i = 0, td = 0; i < n_float; ++i)\n"
+  "    td += va_arg(ap, double);\n"
+  "  *va_arg(ap, double*) = td;\n"
+  "  for (i = 0; i < n_struct; ++i) {\n"
+  "    tmp = va_arg(ap, stdarg_test_struct_type);\n"
+  "    ts.a += tmp.a; ts.b += tmp.b; ts.c += tmp.c;"
+  "  }\n"
+  "  *va_arg(ap, stdarg_test_struct_type*) = ts;\n"
+  "  va_end(ap);"
+  "}\n";
+  return run_callback(src, stdarg_test_callback);
+}
+
+typedef struct {long long a, b;} stdarg_many_test_struct_type;
+typedef void (*stdarg_many_test_function_type) (int, int, int, int, int,
+						stdarg_many_test_struct_type,
+						int, int, ...);
+
+static int stdarg_many_test_callback(void *ptr)
+{
+  stdarg_many_test_function_type f = (stdarg_many_test_function_type)ptr;
+  int x;
+  stdarg_many_test_struct_type l = {10, 11};
+  f(1, 2, 3, 4, 5, l, 6, 7, &x, 44);
+  return x == 44 ? 0 : -1;
+}
+
+static int stdarg_many_test(void)
+{
+  const char *src =
+  "#include <stdarg.h>\n"
+  "typedef struct {long long a, b;} stdarg_many_test_struct_type;\n"
+  "void f (int a, int b, int c, int d, int e, stdarg_many_test_struct_type l, int f, int g, ...){\n"
+  "  va_list ap;\n"
+  "  int *p;\n"
+  "  va_start (ap, g);\n"
+  "  p = va_arg(ap, int*);\n"
+  "  *p = va_arg(ap, int);\n"
+  "  va_end (ap);\n"
+  "}\n";
+  return run_callback(src, stdarg_many_test_callback);
+}
+
+/*
+ * Test Win32 stdarg handling, since the calling convention will pass a pointer
+ * to the struct and the stdarg pointer must point to that pointer initially.
+ */
+
+typedef struct {long long a, b, c;} stdarg_struct_test_struct_type;
+typedef int (*stdarg_struct_test_function_type) (stdarg_struct_test_struct_type a, ...);
+
+static int stdarg_struct_test_callback(void *ptr) {
+  stdarg_struct_test_function_type f = (stdarg_struct_test_function_type)ptr;
+  stdarg_struct_test_struct_type v = {10, 35, 99};
+  int x = f(v, 234);
+  return (x == 378) ? 0 : -1;
+}
+
+static int stdarg_struct_test(void) {
+  const char *src =
+  "#include <stdarg.h>\n"
+  "typedef struct {long long a, b, c;} stdarg_struct_test_struct_type;\n"
+  "int f(stdarg_struct_test_struct_type a, ...) {\n"
+  "  va_list ap;\n"
+  "  va_start(ap, a);\n"
+  "  int z = va_arg(ap, int);\n"
+  "  va_end(ap);\n"
+  "  return z + a.a + a.b + a.c;\n"
+  "}\n";
+  return run_callback(src, stdarg_struct_test_callback);
+}
+
+/* Test that x86-64 arranges the stack correctly for arguments with alignment >8 bytes */
+
+typedef LONG_DOUBLE (*arg_align_test_callback_type) (LONG_DOUBLE,int,LONG_DOUBLE,int,LONG_DOUBLE);
+
+static int arg_align_test_callback(void *ptr) {
+  arg_align_test_callback_type f = (arg_align_test_callback_type)ptr;
+  long double x = f(12, 0, 25, 0, 37);
+  return (x == 74) ? 0 : -1;
+}
+
+static int arg_align_test(void) {
+  const char *src = 
+  "long double f(long double a, int b, long double c, int d, long double e) {\n"
+  "  return a + c + e;\n"
+  "}\n";
+  return run_callback(src, arg_align_test_callback);
+}
+
+#define RUN_TEST(t) \
+  if (!testname || (strcmp(#t, testname) == 0)) { \
+    fputs(#t "... ", stdout); \
+    fflush(stdout); \
+    if (t() == 0) { \
+      fputs("success\n", stdout); \
+    } else { \
+      fputs("failure\n", stdout); \
+      retval = EXIT_FAILURE; \
+    } \
+  }
+
+int main(int argc, char **argv) {
+  int i;
+  const char *testname = NULL;
+  int retval = EXIT_SUCCESS;
+  
+  /* if tcclib.h and libtcc1.a are not installed, where can we find them */
+  for (i = 1; i < argc; ++i) {
+    if (!memcmp(argv[i], "run_test=", 9))
+      testname = argv[i] + 9;
+  }
+
+  g_argv = argv, g_argc = argc;
+
+  RUN_TEST(ret_int_test);
+  RUN_TEST(ret_longlong_test);
+  RUN_TEST(ret_float_test);
+  RUN_TEST(ret_double_test);
+  RUN_TEST(ret_longdouble_test);
+  RUN_TEST(ret_2float_test);
+  RUN_TEST(ret_2double_test);
+  RUN_TEST(ret_8plus2double_test);
+  RUN_TEST(ret_6plus2longlong_test);
+#if !defined __x86_64__ || defined _WIN32
+  /* currently broken on x86_64 linux */
+  RUN_TEST(ret_mixed_test);
+  RUN_TEST(ret_mixed2_test);
+#endif
+  RUN_TEST(ret_mixed3_test);
+  RUN_TEST(reg_pack_test);
+  RUN_TEST(reg_pack_longlong_test);
+  RUN_TEST(sret_test);
+  RUN_TEST(one_member_union_test);
+  RUN_TEST(two_member_union_test);
+  RUN_TEST(many_struct_test);
+  RUN_TEST(many_struct_test_2);
+  RUN_TEST(many_struct_test_3);
+  RUN_TEST(stdarg_test);
+  RUN_TEST(stdarg_many_test);
+  RUN_TEST(stdarg_struct_test);
+  RUN_TEST(arg_align_test);
+  return retval;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/asm-c-connect-1.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/asm-c-connect-1.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/asm-c-connect-1.c	(revision 331)
@@ -0,0 +1,57 @@
+#include <stdio.h>
+
+#if defined _WIN32 && !defined __TINYC__
+# define _ "_"
+#else
+# define _
+#endif
+
+static int x1_c(void)
+{
+    printf(" x1");
+    return 1;
+}
+
+asm(".text;"_"x1: call "_"x1_c; ret");
+
+void callx4(void);
+void callx5_again(void);
+
+void x6()
+{
+    printf(" x6-1");
+}
+
+int main(int argc, char *argv[])
+{
+    printf("*");
+    asm("call "_"x1");
+    asm("call "_"x2");
+    asm("call "_"x3");
+    callx4();
+    asm("call "_"x5");
+    callx5_again();
+    x6();
+    printf(" *\n");
+    return 0;
+}
+
+static
+int x2(void)
+{
+    printf(" x2");
+    return 2;
+}
+
+extern int x3(void);
+
+void x4(void)
+{
+    printf(" x4");
+}
+
+void x5(void);
+void x5(void)
+{
+    printf(" x5");
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/asm-c-connect-2.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/asm-c-connect-2.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/asm-c-connect-2.c	(revision 331)
@@ -0,0 +1,36 @@
+#include <stdio.h>
+
+#if defined _WIN32 && !defined __TINYC__
+# define _ "_"
+#else
+# define _
+#endif
+
+int x3(void)
+{
+    printf(" x3");
+    return 3;
+}
+
+/* That callx4 is defined globally (as if ".globl callx4")
+   is a TCC extension.  GCC doesn't behave like this.  */
+void callx4(void);
+__asm__(_"callx4: call "_"x4; ret;"
+#ifndef __TINYC__
+    " .global "_"callx4"
+#endif
+);
+
+extern void x5(void);
+
+void callx5_again(void);
+void callx5_again(void)
+{
+    x5();
+    asm("call "_"x6");
+}
+
+static void x6()
+{
+    printf(" x6-2");
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/asmtest.S
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/asmtest.S	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/asmtest.S	(revision 331)
@@ -0,0 +1,978 @@
+# gas comment with ``gnu'' style quotes
+
+/* some directive tests */
+
+   .byte 0xff
+   .byte 1, 2, 3
+   .short 1, 2, 3
+   .word 1, 2, 3
+   .long 1, 2, 3
+   .int 1, 2, 3
+   .align 8
+   .byte 1
+/* .align 16, 0x90 gas is too clever for us with 0x90 fill */
+   .balign 4, 0x92
+   .align 16, 0x91 /* 0x91 tests the non-clever behaviour */
+   .skip 3
+   .skip 15, 0x90
+   .string "hello\0world"
+/* Macro expansion should work like with C, the #n shouldn't be parsed
+   as asm line comment */
+#define __stringify(n) #n
+#define stringify(n) __stringify(n)
+   .skip 8,0x90
+   .asciz stringify(BLA)
+   .skip 8,0x90
+
+# 28 "asmtest.S"        # a line directive (and a line comment)
+        movl %eax, %ebx # some more asm comment
+/* some label tests */
+L1:
+        movl %eax, %ebx
+        mov 0x10000, %eax
+L2:
+        movl $L2 - L1, %ecx
+var1:
+        nop ; nop ; nop ; nop
+
+        mov var1, %eax
+
+/* instruction tests */
+movl %eax, %ebx
+mov 0x10000, %eax
+mov 0x10000, %ax
+mov 0x10000, %al
+mov %al, 0x10000
+                
+mov $1, %edx
+mov $1, %dx
+mov $1, %cl
+movb $2, 0x100(%ebx,%edx,2)
+movw $2, 0x100(%ebx,%edx,2)
+movl $2, 0x100(%ebx,%edx,2)
+movl %eax, 0x100(%ebx,%edx,2)
+movl 0x100(%ebx,%edx,2), %edx
+movw %ax, 0x100(%ebx,%edx,2)
+
+movw $0x1122,%si
+movl $0x112233,%edx
+movl $0x80000000, %esi
+movl $-0x7fffffff, %edi
+#ifdef __x86_64__
+mov $0x11223344,%rbx
+movq $0x11223344,%rbx
+mov $0x1122334455,%rbx
+movq $0x1122334455,%rbx
+movl $0x11334455,(%rbx)
+#endif
+
+mov %eax, 0x12(,%edx,2)
+        
+#ifdef __i386__
+mov %cr3, %edx
+mov %ecx, %cr3
+movl %cr3, %eax
+movl %tr3, %eax
+movl %db3, %ebx
+movl %dr6, %eax
+#else
+mov %cr3, %rdx
+mov %rcx, %cr3
+movq %cr3, %rax
+movq %db3, %rbx
+movq %dr6, %rax
+mov %cr8, %rsi
+mov %rdi, %cr8
+#endif
+movl %fs, %ecx
+movl %ebx, %fs
+
+#ifdef __x86_64__
+movq %r8, %r9
+movq %r10, %r11
+movq %r12, %r13
+movq %r14, %r15
+movq %rax, %r9
+movq %r15, %rsi
+inc %r9b
+dec %r10w
+not %r11d
+negq %r12
+decb %r13b
+incw %r14w
+notl %r15d
+#endif
+
+     movsbl 0x1000, %eax
+     movsbw 0x1000, %ax
+     movswl 0x1000, %eax
+
+     movzbl 0x1000, %eax
+     movzbw 0x1000, %ax
+     movzwl 0x1000, %eax
+            
+     movzb 0x1000, %eax
+     movzb 0x1000, %ax
+                
+     mov $0x12345678,%eax
+
+#ifdef __x86_64__
+     movzb 0x1000, %rax
+     movzbq 0x1000, %rbx
+     movsbq 0x1000, %rdx
+     movzwq 0x1000, %rdi
+     movswq 0x1000, %rdx
+     movslq %eax, %rcx
+     mov $0x12345678,%rax
+     mov $0x12345678,%rdx
+     mov $0x12345678,%r10
+     mov $0x123456789abcdef0,%rax
+     mov $0x123456789abcdef0,%rcx
+     mov $0x123456789abcdef0,%r11
+#endif
+        
+#ifdef __i386__
+  pushl %eax
+  push %eax
+  push %cs
+#else
+  pushq %rax
+  push %rax
+#endif
+  pushw %ax
+  push %gs
+  push $1
+  push $100
+  push 0x42(%eax)
+  pop 0x43(%esi)
+                                                
+#ifdef __i386__
+  popl %eax
+  pop %eax
+  pop %ds
+#else
+  popq %rax
+  pop %rax
+#endif
+  popw %ax
+  pop %fs
+          
+  xchg %eax, %ecx
+  xchg %edx, %eax
+  xchg %bx, 0x10000
+  xchg 0x10000, %ebx
+  xchg 0x10000, %dl
+
+  in $100, %al               
+  in $100, %ax               
+  in $100, %eax
+  in %dx, %al
+  in %dx, %ax               
+  in %dx, %eax
+  inb %dx
+  inw %dx               
+  inl %dx
+
+  out %al, $100                       
+  out %ax, $100                       
+  out %eax, $100                       
+
+  /* NOTE: gas is bugged here, so size must be added */
+  outb %al, %dx                       
+  outw %ax, %dx                       
+  outl %eax, %dx                       
+
+  leal 0x1000(%ebx), %ecx
+  lea 0x1000(%ebx), %ecx
+
+#ifdef __i386__
+  les 0x2000, %eax
+  lds 0x2000, %ebx
+  lss 0x2000, %edx
+#endif
+  lfs 0x2000, %ecx
+  lgs 0x2000, %edx
+
+addl $0x123, %eax
+add $0x123, %ebx
+add $-16, %ecx
+add $-0x123, %esi
+add $1, %bx
+add $1, %ebx
+add $-1, %bx
+add $-1, %ebx
+add $127, %bx
+addl $127, %ebx
+addl $-128, %ebx
+addl $-128, %ebx
+addl $-129, %ebx
+addl $128, %ebx
+addl $255, %ebx
+addl $256, %ebx
+andb $0xf, %ah
+andb $-15, %cl
+xorb $127, %dh
+cmpb $42, (%eax)
+addl $0x123, 0x100
+addl $0x123, 0x100(%ebx)
+addl $0x123, 0x100(%ebx,%edx,2)
+addl $0x123, 0x100(%esp)
+addl $0x123, (3*8)(%esp)
+addl $0x123, (%ebp)
+addl $0x123, (%esp)
+cmpl $0x123, (%esp)
+
+#ifdef __x86_64__
+xor %bl,%ah
+xor %bl,%r8b
+xor %r9b,%bl
+xor %sil,%cl
+add %eax,(%r8d)
+add %ebx,(%r9)
+add %edx,(%r10d,%r11d)
+add %ecx,(%r12,%r13)
+add %esi,(%r14,%r15,4)
+add %edi,0x1000(%rbx,%r12,8)
+add %r11,0x1000(%ebp,%r9d,8)
+movb $12, %ah
+movb $13, %bpl
+movb $14, %dil
+movb $15, %r12b
+#endif
+
+add %eax, (%ebx)
+add (%ebx), %eax
+                
+or %dx, (%ebx)
+or (%ebx), %si
+        
+add %cl, (%ebx)
+add (%ebx), %dl
+
+    inc %edx
+    incl 0x10000
+    incb 0x10000
+    dec %dx
+  
+  test $1, %al
+  test $1, %cl
+
+  testl $1, 0x1000
+  testb $1, 0x1000
+  testw $1, 0x1000
+  test %eax, %ebx
+  test %eax, 0x1000
+  test 0x1000, %edx
+
+    not %edx
+    notw 0x10000
+    notl 0x10000
+    notb 0x10000
+
+    neg %edx
+    negw 0x10000
+    negl 0x10000
+    negb 0x10000
+
+    imul %ecx
+    mul %edx
+    mulb %cl
+
+    imul %eax, %ecx
+    imul 0x1000, %cx
+    imul $10, %eax, %ecx
+    imul $10, %ax, %cx
+    imul $10, %eax
+    imul $0x1100000, %eax
+    imul $1, %eax
+    
+    idivw 0x1000
+    div %ecx
+    div %bl
+    div %ecx, %eax
+
+and $15,%bx
+and $-20,%edx
+
+shl %edx
+shl $10, %edx
+shl %cl, %edx
+
+shld $1, %eax, %edx
+shld %cl, %eax, %edx
+shld %eax, %edx
+
+shrd $1, %eax, %edx
+shrd %cl, %eax, %edx
+shrd %eax, %edx
+
+L4:
+call 0x1000
+call L4
+#ifdef __i386__
+call *%eax
+#else
+call *%rax
+#endif
+call *0x1000
+call func1
+
+.global L5,L6
+
+L5:
+L6:
+
+#ifdef __i386__
+lcall $0x100, $0x1000
+#else
+lcall *0x100
+lcall *(%rax)
+#endif
+
+jmp 0x1000
+jmp *(%edi)
+#ifdef __i386__
+jmp *%eax
+#else
+jmp *%rax
+#endif
+jmp *0x1000
+
+#ifdef __i386__
+ljmp $0x100, $0x1000
+#else
+ljmp *0x100
+ljmp *(%rdi)
+ljmpl *(%esi)
+ljmpw *(%esi)
+#endif
+
+ret
+ret $10
+#ifdef __i386__
+retl
+retl $10
+#else
+retq
+retq $10
+#endif
+
+lret
+
+lret $10
+
+enter $1234, $10
+
+L3:
+ jo 0x1000
+ jnp 0x1001
+ jne 0x1002
+ jg 0x1003
+
+ jo L3
+ jnp L3
+ jne L3
+ jg L3
+
+ loopne L3
+ loopnz L3
+ loope L3
+ loopz L3
+ loop L3
+ jecxz L3
+
+        
+ seto %al
+ setc %al
+ setcb %al
+ setnp 0x1000
+ setl 0xaaaa
+ setg %dl
+
+ fadd
+ fadd %st(1), %st
+ fadd %st(0), %st(1)
+ fadd %st(3)
+
+ fmul %st(0),%st(0)
+ fmul %st(0),%st(1)
+
+ faddp %st(5)
+ faddp
+ faddp %st(1), %st
+
+ fadds 0x1000
+ fiadds 0x1002
+ faddl 0x1004
+ fiaddl 0x1006
+
+ fmul
+ fmul %st(1), %st
+ fmul %st(3)
+
+ fmulp %st(5)
+ fmulp
+ fmulp %st(1), %st
+
+ fmuls 0x1000
+ fimuls 0x1002
+ fmull 0x1004
+ fimull 0x1006
+
+ fsub
+ fsub %st(1), %st
+ fsub %st(3)
+
+ fsubp %st(5)
+ fsubp
+ fsubp %st(1), %st
+
+ fsubs 0x1000
+ fisubs 0x1002
+ fsubl 0x1004
+ fisubl 0x1006
+
+ fsubr
+ fsubr %st(1), %st
+ fsubr %st(3)
+
+ fsubrp %st(5)
+ fsubrp
+ fsubrp %st(1), %st
+
+ fsubrs 0x1000
+ fisubrs 0x1002
+ fsubrl 0x1004
+ fisubrl 0x1006
+
+ fdiv
+ fdiv %st(1), %st
+ fdiv %st(3)
+
+ fdivp %st(5)
+ fdivp
+ fdivp %st(1), %st
+
+ fdivs 0x1000
+ fidivs 0x1002
+ fdivl 0x1004
+ fidivl 0x1006
+
+ fcom %st(3)
+
+ fcoms 0x1000
+ ficoms 0x1002
+ fcoml 0x1004
+ ficoml 0x1006
+
+ fcomp %st(5)
+ fcomp
+ fcompp
+
+ fcomps 0x1000
+ ficomps 0x1002
+ fcompl 0x1004
+ ficompl 0x1006
+
+ fld %st(5)
+ fldl 0x1000
+ flds 0x1002
+ fildl 0x1004
+ fst %st(4)
+ fstp %st(6)
+ fstpt 0x1006
+ fbstp 0x1008
+
+ fxch
+ fxch %st(4)
+
+ fucom %st(6)
+ fucomp %st(3)
+ fucompp
+
+ finit
+ fninit
+ fldcw 0x1000
+ fnstcw 0x1002
+ fstcw 0x1002
+ fnstsw 0x1004
+ fnstsw (%eax)
+ fstsw 0x1004
+ fstsw (%eax)
+ fnclex
+ fclex
+ fnstenv 0x1000
+ fstenv 0x1000
+ fldenv 0x1000
+ fnsave 0x1002
+ fsave 0x1000
+ frstor 0x1000
+ ffree %st(7)
+ ffreep %st(6)
+ 
+    ftst
+    fxam
+    fld1
+    fldl2t
+    fldl2e
+    fldpi
+    fldlg2
+    fldln2
+    fldz
+
+    f2xm1
+    fyl2x
+    fptan
+    fpatan
+    fxtract
+    fprem1
+    fdecstp
+    fincstp
+    fprem
+    fyl2xp1
+    fsqrt
+    fsincos
+    frndint
+    fscale
+    fsin
+    fcos
+    fchs
+    fabs
+    fnop
+    fwait
+
+bswap %edx
+bswapl %ecx
+xadd %ecx, %edx
+xaddb %dl, 0x1000
+xaddw %ax, 0x1000
+xaddl %eax, 0x1000
+cmpxchg %ecx, %edx
+cmpxchgb %dl, 0x1000
+cmpxchgw %ax, 0x1000
+cmpxchgl %eax, 0x1000
+invlpg 0x1000
+cmpxchg8b 0x1002
+#ifdef __x86_64__
+cmpxchg16b (%rax)
+cmpxchg16b (%r10,%r11)
+#endif
+
+fcmovb %st(5), %st
+fcmove %st(5), %st
+fcmovbe %st(5), %st
+fcmovu %st(5), %st
+fcmovnb %st(5), %st
+fcmovne %st(5), %st
+fcmovnbe %st(5), %st
+fcmovnu %st(5), %st
+fcomi %st(5), %st
+fucomi %st(5), %st
+fcomip %st(5), %st
+fucomip %st(5), %st
+
+
+
+ cmovo 0x1000, %eax
+ cmovs 0x1000, %eax
+ cmovns %edx, %edi
+ cmovne %ax, %si
+ cmovbw %ax, %di
+ cmovnbel %edx, %ecx
+#ifdef __x86_64__
+ bswapq %rsi
+ bswapq %r10
+ cmovz %rdi,%rbx
+ cmovpeq %rsi, %rdx
+#endif
+
+int $3
+int $0x10
+
+#ifdef __i386__
+    pusha
+    popa
+#endif
+    clc # another comment
+    cld # a comment with embedded ' tick
+    cli
+    clts
+    cmc
+    lahf
+    sahf
+#ifdef __i386__
+    pushfl
+    popfl
+#else
+    pushfq
+    popfq
+#endif
+    pushf
+    popf
+    stc
+    std
+    sti
+#ifdef __i386__
+    aaa
+    aas
+    daa
+    das
+    aad
+    aam
+    into
+#endif
+    cbw
+    cwd
+    cwde
+    cdq
+    cbtw
+    cwtd
+    cwtl
+    cltd
+    leave
+    int3
+    iret
+    rsm
+    hlt
+    wait
+    nop
+
+    /* XXX: handle prefixes */
+#if 0
+    aword
+    addr16
+#endif
+    lock
+    rep
+    repe
+    repz
+    repne
+    repnz
+    nop
+
+    lock ;negl (%eax)
+    wait ;pushf
+    rep  ;stosb
+    repe ;lodsb
+    repz ;cmpsb
+    repne;movsb
+    repnz;outsb
+
+    /* handle one-line prefix + ops */
+    lock  negl (%eax)
+    wait  pushf
+    rep   stosb
+    repe  lodsb
+    repz  cmpsb
+    repne movsb
+    repnz outsb
+    
+    invd
+    wbinvd
+    cpuid
+    wrmsr
+    rdtsc
+    rdmsr
+    rdpmc
+    ud2
+#ifdef __x86_64__
+    syscall
+    sysret
+    sysretq
+    lfence
+    mfence
+    sfence
+    prefetchnta 0x18(%rdx)
+    prefetcht0 (%rcx)
+    prefetcht1 (%rsi)
+    prefetcht2 (%rdi)
+    prefetchw (%rdi)
+    clflush 0x1000(%rax,%rcx)
+    fxsaveq (%rdx)
+    fxsaveq (%r11)
+    fxrstorq (%rcx)
+    fxrstorq (%r10)
+
+#endif
+
+    lar %ax,%dx
+    lar %eax,%dx
+    lar %ax,%edx
+    lar %eax,%edx
+#ifdef __x86_64__
+    lar %ax,%rdx
+    lar %eax,%rdx
+#endif
+    emms
+    movd %edx, %mm3
+    movd 0x1000, %mm2
+    movd %mm4, %ecx
+    movd %mm5, 0x1000
+                    
+    movq 0x1000, %mm2
+    movq %mm4, 0x1000
+    
+    pand 0x1000, %mm3
+    pand %mm4, %mm5
+    
+    psllw $1, %mm6
+    psllw 0x1000, %mm7
+    psllw %mm2, %mm7
+
+    xlat
+    cmpsb
+    scmpw
+    insl
+    outsw
+    lodsb
+    slodl
+    movsb
+    movsl
+    smovb
+    scasb
+    sscaw
+    stosw
+    sstol
+
+    bsf 0x1000, %ebx
+    bsr 0x1000, %ebx
+    bt %edx, 0x1000
+    btl $2, 0x1000
+    btc %edx, 0x1000
+    btcl $2, 0x1000
+    btr %edx, 0x1000
+    btrl $2, 0x1000
+    bts %edx, 0x1000
+    btsl $2, 0x1000
+
+        
+        
+#ifdef __i386__
+    boundl %edx, 0x10000
+    boundw %bx, 0x1000
+
+    arpl %bx, 0x1000
+#endif
+    lar 0x1000, %eax
+    lgdt 0x1000
+    lidt 0x1000
+    lldt 0x1000
+    sgdt 0x1000
+    sidt 0x1000
+    sldt 0x1000
+#ifdef __x86_64__
+    lgdtq 0x1000
+    lidtq 0x1000
+    sgdtq 0x1000
+    sidtq 0x1000
+
+    swapgs
+
+    str %rdx
+    str %r9
+#endif
+
+    lmsw 0x1000
+    lsl 0x1000, %ecx
+    ltr 0x1000
+    ltr %si
+    smsw 0x1000
+    str 0x1000
+    str %ecx
+    str %dx
+    
+    verr 0x1000
+    verw 0x1000
+  
+#ifdef __i386__
+    push %ds
+    pushw %ds
+    pushl %ds
+    pop %ds
+    popw %ds
+    popl %ds
+#endif
+    fxsave 1(%ebx)
+    fxrstor 1(%ecx)
+#ifdef __i386__
+    pushl $1
+#else
+    pushq $1
+#endif
+    pushw $1
+    push $1
+
+#ifdef __ASSEMBLER__ // should be defined, for S files
+    inc %eax
+#endif
+
+#ifndef _WIN32
+ft1: ft2: ft3: ft4: ft5: ft6: ft7: ft8: ft9:
+    xor %eax, %eax
+    ret
+
+.type ft1,STT_FUNC
+.type ft2,@STT_FUNC
+.type ft3,%STT_FUNC
+.type ft4,"STT_FUNC"
+.type ft5,function
+.type ft6,@function
+.type ft7,%function
+.type ft8,"function"
+#endif
+
+    pause
+.rept 6
+    nop
+.endr
+.fill 4,1,0x90
+
+.section .text.one,"ax"
+nop
+.previous
+.pushsection .text.one,"ax"
+nop
+.pushsection .text.two,"ax"
+nop
+.popsection
+.popsection
+
+1: ud2
+.pushsection __bug_table,"a"
+.align 8
+2: .long 1b - 2b
+   .long 0x600000 - 2b
+   .long 1b + 42
+   .long 43 + 1b
+   .long 2b + 144
+   .long 145 + 2b
+   .word 164, 0
+   .org 2b+32
+#ifdef __x86_64__
+   .quad 1b
+#else
+   .long 1b
+#endif
+.popsection
+3: mov %eax,%ecx
+4:
+.pushsection .text.three, "ax"
+nop
+.skip (-((4b-3b) > 0) * 2) , 0x90
+.popsection
+
+.globl overrideme
+.weak overrideme
+  nop
+.globl notimplemented
+notimplemented:
+  ret
+.set overrideme, notimplemented
+overrideme = notimplemented
+overrideme:
+  ret
+
+    movd %esi, %mm1
+    movd %edi, %xmm2
+    movd (%ebx), %mm3
+    movd (%ebx), %xmm3
+    movd %mm1, %esi
+    movd %xmm2, %edi
+    movd %mm3, (%edx)
+    movd %xmm3, (%edx)
+#ifdef __x86_64__
+    movd %rsi, %mm1
+    movd %rdi, %xmm2
+    movd (%rbx), %mm3
+    movd (%rbx), %xmm3
+    movd %mm1, %r12
+    movd %xmm2, %rdi
+    movd %mm3, (%r8)
+    movd %xmm3, (%r13)
+#endif
+
+    movq (%ebp), %mm1
+    movq %mm2, (%edi)
+    movq (%edi), %xmm3
+    movq %mm4, %mm5
+#ifdef __x86_64__
+    movq %rcx, %mm1
+    movq %rdx, %xmm2
+    movq %r13, %xmm3
+    /* movq mem64->xmm is encoded as f30f7e by GAS, but as
+       660f6e by tcc (which really is a movd and would need 
+       a REX.W prefix to be movq).  */
+    movq (%rsi), %xmm3
+    movq %mm1, %rdx
+    movq %xmm3, %rcx
+    movq %xmm4, (%rsi)
+#endif
+
+#define TEST_MMX_SSE(insn) \
+    insn %mm1, %mm2; \
+    insn %xmm2, %xmm3; \
+    insn (%ebx), %xmm3;
+#define TEST_MMX_SSE_I8(insn) \
+    TEST_MMX_SSE(insn) \
+    insn $0x42, %mm4; \
+    insn $0x42, %xmm4;
+
+    TEST_MMX_SSE(packssdw)
+    TEST_MMX_SSE(packsswb)
+    TEST_MMX_SSE(packuswb)
+    TEST_MMX_SSE(paddb)
+    TEST_MMX_SSE(paddw)
+    TEST_MMX_SSE(paddd)
+    TEST_MMX_SSE(paddsb)
+    TEST_MMX_SSE(paddsw)
+    TEST_MMX_SSE(paddusb)
+    TEST_MMX_SSE(paddusw)
+    TEST_MMX_SSE(pand)
+    TEST_MMX_SSE(pandn)
+    TEST_MMX_SSE(pcmpeqb)
+    TEST_MMX_SSE(pcmpeqw)
+    TEST_MMX_SSE(pcmpeqd)
+    TEST_MMX_SSE(pcmpgtb)
+    TEST_MMX_SSE(pcmpgtw)
+    TEST_MMX_SSE(pcmpgtd)
+    TEST_MMX_SSE(pmaddwd)
+    TEST_MMX_SSE(pmulhw)
+    TEST_MMX_SSE(pmullw)
+    TEST_MMX_SSE(por)
+    TEST_MMX_SSE(psllw)
+TEST_MMX_SSE_I8(psllw)
+    TEST_MMX_SSE(pslld)
+TEST_MMX_SSE_I8(pslld)
+    TEST_MMX_SSE(psllq)
+TEST_MMX_SSE_I8(psllq)
+    TEST_MMX_SSE(psraw)
+TEST_MMX_SSE_I8(psraw)
+    TEST_MMX_SSE(psrad)
+TEST_MMX_SSE_I8(psrad)
+    TEST_MMX_SSE(psrlw)
+TEST_MMX_SSE_I8(psrlw)
+    TEST_MMX_SSE(psrld)
+TEST_MMX_SSE_I8(psrld)
+    TEST_MMX_SSE(psrlq)
+TEST_MMX_SSE_I8(psrlq)
+    TEST_MMX_SSE(psubb)
+    TEST_MMX_SSE(psubw)
+    TEST_MMX_SSE(psubd)
+    TEST_MMX_SSE(psubsb)
+    TEST_MMX_SSE(psubsw)
+    TEST_MMX_SSE(psubusb)
+    TEST_MMX_SSE(psubusw)
+    TEST_MMX_SSE(punpckhbw)
+    TEST_MMX_SSE(punpckhwd)
+    TEST_MMX_SSE(punpckhdq)
+    TEST_MMX_SSE(punpcklbw)
+    TEST_MMX_SSE(punpcklwd)
+    TEST_MMX_SSE(punpckldq)
+    TEST_MMX_SSE(pxor)
+
+    cvtpi2ps %mm1, %xmm2
+    cvtpi2ps (%ebx), %xmm2
+    TEST_MMX_SSE(pmaxsw)
+    TEST_MMX_SSE(pmaxub)
+    TEST_MMX_SSE(pminsw)
+    TEST_MMX_SSE(pminub)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/boundtest.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/boundtest.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/boundtest.c	(revision 331)
@@ -0,0 +1,285 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define NB_ITS 1000000
+//#define NB_ITS 1
+#define TAB_SIZE 100
+
+int tab[TAB_SIZE];
+int ret_sum;
+char tab3[256];
+
+int test1(void)
+{
+    int i, sum = 0;
+    for(i=0;i<TAB_SIZE;i++) {
+        sum += tab[i];
+    }
+    return sum;
+}
+
+/* error */
+int test2(void)
+{
+    int i, sum = 0;
+    for(i=0;i<TAB_SIZE + 1;i++) {
+        sum += tab[i];
+    }
+    return sum;
+}
+
+/* actually, profiling test */
+int test3(void)
+{
+    int sum;
+    int i, it;
+
+    sum = 0;
+    for(it=0;it<NB_ITS;it++) {
+        for(i=0;i<TAB_SIZE;i++) {
+            sum += tab[i];
+        }
+    }
+    return sum;
+}
+
+/* ok */
+int test4(void)
+{
+    int i, sum = 0;
+    int *tab4;
+
+    fprintf(stderr, "%s start\n", __FUNCTION__);
+
+    tab4 = malloc(20 * sizeof(int));
+    for(i=0;i<20;i++) {
+        sum += tab4[i];
+    }
+    free(tab4);
+
+    fprintf(stderr, "%s end\n", __FUNCTION__);
+    return sum;
+}
+
+/* error */
+int test5(void)
+{
+    int i, sum = 0;
+    int *tab4;
+
+    fprintf(stderr, "%s start\n", __FUNCTION__);
+
+    tab4 = malloc(20 * sizeof(int));
+    for(i=0;i<21;i++) {
+        sum += tab4[i];
+    }
+    free(tab4);
+
+    fprintf(stderr, "%s end\n", __FUNCTION__);
+    return sum;
+}
+
+/* error */
+/* XXX: currently: bug */
+int test6(void)
+{
+    int i, sum = 0;
+    int *tab4;
+    
+    tab4 = malloc(20 * sizeof(int));
+    free(tab4);
+    for(i=0;i<21;i++) {
+        sum += tab4[i];
+    }
+
+    return sum;
+}
+
+/* error */
+int test7(void)
+{
+    int i, sum = 0;
+    int *p;
+
+    for(i=0;i<TAB_SIZE + 1;i++) {
+        p = &tab[i];
+        if (i == TAB_SIZE)
+            printf("i=%d %x\n", i, p);
+        sum += *p;
+    }
+    return sum;
+}
+
+/* ok */
+int test8(void)
+{
+    int i, sum = 0;
+    int tab[10];
+
+    for(i=0;i<10;i++) {
+        sum += tab[i];
+    }
+    return sum;
+}
+
+/* error */
+int test9(void)
+{
+    int i, sum = 0;
+    char tab[10];
+
+    for(i=0;i<11;i++) {
+        sum += tab[i];
+    }
+    return sum;
+}
+
+/* ok */
+int test10(void)
+{
+    char tab[10];
+    char tab1[10];
+
+    memset(tab, 0, 10);
+    memcpy(tab, tab1, 10);
+    memmove(tab, tab1, 10);
+    return 0;
+}
+
+/* error */
+int test11(void)
+{
+    char tab[10];
+
+    memset(tab, 0, 11);
+    return 0;
+}
+
+/* error */
+int test12(void)
+{
+    void *ptr;
+    ptr = malloc(10);
+    free(ptr);
+    free(ptr);
+    return 0;
+}
+
+/* error */
+int test13(void)
+{
+    char pad1 = 0;
+    char tab[10];
+    char pad2 = 0;
+    memset(tab, 'a', sizeof(tab));
+    return strlen(tab);
+}
+
+int test14(void)
+{
+    char *p = alloca(TAB_SIZE);
+    memset(p, 'a', TAB_SIZE);
+    p[TAB_SIZE-1] = 0;
+    return strlen(p);
+}
+
+/* error */
+int test15(void)
+{
+    char *p = alloca(TAB_SIZE-1);
+    memset(p, 'a', TAB_SIZE);
+    p[TAB_SIZE-1] = 0;
+    return strlen(p);
+}
+
+/* ok */
+int test16()
+{
+    char *demo = "This is only a test.";
+    char *p;
+
+    fprintf(stderr, "%s start\n", __FUNCTION__);
+
+    p = alloca(16);
+    strcpy(p,"12345678901234");
+    printf("alloca: p is %s\n", p);
+
+    /* Test alloca embedded in a larger expression */
+    printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) );
+
+    fprintf(stderr, "%s end\n", __FUNCTION__);
+}
+
+/* error */
+int test17()
+{
+    char *demo = "This is only a test.";
+    char *p;
+
+    fprintf(stderr, "%s start\n", __FUNCTION__);
+
+    p = alloca(16);
+    strcpy(p,"12345678901234");
+    printf("alloca: p is %s\n", p);
+
+    /* Test alloca embedded in a larger expression */
+    printf("alloca: %s\n", strcpy(alloca(strlen(demo)),demo) );
+
+    fprintf(stderr, "%s end\n", __FUNCTION__);
+}
+
+int (*table_test[])(void) = {
+    test1,
+    test2,
+    test3,
+    test4,
+    test5,
+    test6,
+    test7,
+    test8,
+    test9,
+    test10,
+    test11,
+    test12,
+    test13,
+    test14,
+    test15,
+    test16,
+    test17,
+};
+
+int main(int argc, char **argv)
+{
+    int index;
+    int (*ftest)(void);
+    int index_max = sizeof(table_test)/sizeof(table_test[0]);
+
+    if (argc < 2) {
+        printf(
+    	    "test TCC bound checking system\n"
+	    "usage: boundtest N\n"
+            "  1 <= N <= %d\n", index_max);
+        exit(1);
+    }
+
+    index = 0;
+    if (argc >= 2)
+        index = atoi(argv[1]) - 1;
+
+    if ((index < 0) || (index >= index_max)) {
+        printf("N is outside of the valid range (%d)\n", index);
+        exit(2);
+    }
+
+    /* well, we also use bounds on this ! */
+    ftest = table_test[index];
+    ftest();
+
+    return 0;
+}
+
+/*
+ * without bound   0.77 s
+ * with bounds    4.73
+ */  
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/gcctestsuite.sh
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/gcctestsuite.sh	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/gcctestsuite.sh	(revision 331)
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+TESTSUITE_PATH=$HOME/gcc/gcc-3.2/gcc/testsuite/gcc.c-torture
+TCC="./tcc -B. -I. -DNO_TRAMPOLINES" 
+rm -f tcc.sum tcc.log
+nb_failed="0"
+
+for src in $TESTSUITE_PATH/compile/*.c ; do
+  echo $TCC -o /tmp/test.o -c $src 
+  $TCC -o /tmp/test.o -c $src >> tcc.log 2>&1
+  if [ "$?" = "0" ] ; then
+     result="PASS"
+  else
+     result="FAIL"
+     nb_failed=$(( $nb_failed + 1 ))
+  fi
+  echo "$result: $src"  >> tcc.sum
+done
+
+for src in $TESTSUITE_PATH/execute/*.c ; do
+  echo $TCC $src 
+  $TCC $src >> tcc.log 2>&1
+  if [ "$?" = "0" ] ; then
+     result="PASS"
+  else
+     result="FAIL"
+     nb_failed=$(( $nb_failed + 1 ))
+  fi
+  echo "$result: $src"  >> tcc.sum
+done
+
+echo "$nb_failed test(s) failed." >> tcc.sum
+echo "$nb_failed test(s) failed."
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/libtcc_test.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/libtcc_test.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/libtcc_test.c	(revision 331)
@@ -0,0 +1,96 @@
+/*
+ * Simple Test program for libtcc
+ *
+ * libtcc can be useful to use tcc as a "backend" for a code generator.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libtcc.h"
+
+/* this function is called by the generated code */
+int add(int a, int b)
+{
+    return a + b;
+}
+
+/* this strinc is referenced by the generated code */
+const char hello[] = "Hello World!";
+
+char my_program[] =
+"#include <tcclib.h>\n" /* include the "Simple libc header for TCC" */
+"extern int add(int a, int b);\n"
+"#ifdef _WIN32\n" /* dynamically linked data needs 'dllimport' */
+" __attribute__((dllimport))\n"
+"#endif\n"
+"extern const char hello[];\n"
+"int fib(int n)\n"
+"{\n"
+"    if (n <= 2)\n"
+"        return 1;\n"
+"    else\n"
+"        return fib(n-1) + fib(n-2);\n"
+"}\n"
+"\n"
+"int foo(int n)\n"
+"{\n"
+"    printf(\"%s\\n\", hello);\n"
+"    printf(\"fib(%d) = %d\\n\", n, fib(n));\n"
+"    printf(\"add(%d, %d) = %d\\n\", n, 2 * n, add(n, 2 * n));\n"
+"    return 0;\n"
+"}\n";
+
+int main(int argc, char **argv)
+{
+    TCCState *s;
+    int i;
+    int (*func)(int);
+
+    s = tcc_new();
+    if (!s) {
+        fprintf(stderr, "Could not create tcc state\n");
+        exit(1);
+    }
+
+    /* if tcclib.h and libtcc1.a are not installed, where can we find them */
+    for (i = 1; i < argc; ++i) {
+        char *a = argv[i];
+        if (a[0] == '-') {
+            if (a[1] == 'B')
+                tcc_set_lib_path(s, a+2);
+            else if (a[1] == 'I')
+                tcc_add_include_path(s, a+2);
+            else if (a[1] == 'L')
+                tcc_add_library_path(s, a+2);
+        }
+    }
+
+    /* MUST BE CALLED before any compilation */
+    tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
+
+    if (tcc_compile_string(s, my_program) == -1)
+        return 1;
+
+    /* as a test, we add symbols that the compiled program can use.
+       You may also open a dll with tcc_add_dll() and use symbols from that */
+    tcc_add_symbol(s, "add", add);
+    tcc_add_symbol(s, "hello", hello);
+
+    /* relocate the code */
+    if (tcc_relocate(s, TCC_RELOCATE_AUTO) < 0)
+        return 1;
+
+    /* get entry symbol */
+    func = tcc_get_symbol(s, "foo");
+    if (!func)
+        return 1;
+
+    /* run the code */
+    func(32);
+
+    /* delete the state */
+    tcc_delete(s);
+
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/01.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/01.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/01.c	(revision 331)
@@ -0,0 +1,6 @@
+#define hash_hash # ## #
+#define mkstr(a) # a
+#define in_between(a) mkstr(a)
+#define join(c, d) in_between(c hash_hash d)
+char p[] = join(x, y);
+// char p[] = "x ## y";
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/01.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/01.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/01.expect	(revision 331)
@@ -0,0 +1,1 @@
+char p[] = "x ## y";
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/02.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/02.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/02.c	(revision 331)
@@ -0,0 +1,28 @@
+#define x 3
+#define f(a) f(x * (a))
+#undef x
+#define x 2
+#define g f
+#define z z[0]
+#define h g(~
+#define m(a) a(w)
+#define w 0,1
+#define t(a) a
+#define p() int
+#define q(x) x
+#define r(x,y) x ## y
+#define str(x) # x
+f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
+g(x+(3,4)-w) | h 5) & m
+(f)^m(m);
+char c[2][6] = { str(hello), str() };
+/*
+ * f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
+ * f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
+ * char c[2][6] = { "hello", "" };
+ */
+#define L21 f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
+#define L22 g(x+(3,4)-w) | h 5) & m\
+(f)^m(m);
+L21
+L22
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/02.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/02.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/02.expect	(revision 331)
@@ -0,0 +1,5 @@
+f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
+f(2 * (2 +(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
+char c[2][6] = { "hello", "" };
+f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
+f(2 * (2 +(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/03.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/03.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/03.c	(revision 331)
@@ -0,0 +1,15 @@
+#define str(s) # s
+#define xstr(s) str(s)
+#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \
+	x ## s, x ## t)
+#define INCFILE(n) vers ## n
+#define glue(a, b) a ## b
+#define xglue(a, b) glue(a, b)
+#define HIGHLOW "hello"
+#define LOW LOW ", world"
+debug(1, 2);
+fputs(str(strncmp("abc\0d", "abc", '\4') // this goes away
+	== 0) str(: @\n), s);
+\#include xstr(INCFILE(2).h)
+glue(HIGH, LOW);
+xglue(HIGH, LOW)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/03.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/03.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/03.expect	(revision 331)
@@ -0,0 +1,5 @@
+printf("x" "1" "= %d, x" "2" "= %s", x1, x2);
+fputs("strncmp(\"abc\\0d\", \"abc\", '\\4') == 0" ": @\n", s);
+\#include "vers2.h"
+"hello";
+"hello" ", world"
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/04.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/04.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/04.c	(revision 331)
@@ -0,0 +1,4 @@
+#define foobar 1
+#define C(x,y) x##y
+#define D(x) (C(x,bar))
+D(foo)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/04.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/04.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/04.expect	(revision 331)
@@ -0,0 +1,1 @@
+(1)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/05.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/05.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/05.c	(revision 331)
@@ -0,0 +1,7 @@
+#define t(x,y,z) x ## y ## z
+#define xxx(s) int s[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), \
+        t(10,,), t(,11,), t(,,12), t(,,) };
+
+int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,),
+	t(10,,), t(,11,), t(,,12), t(,,) };
+xxx(j)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/05.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/05.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/05.expect	(revision 331)
@@ -0,0 +1,3 @@
+int j[] = { 123, 45, 67, 89,
+ 10, 11, 12, };
+int j[] = { 123, 45, 67, 89, 10, 11, 12, };
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/06.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/06.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/06.c	(revision 331)
@@ -0,0 +1,5 @@
+#define X(a,b, \
+	c,d) \
+	foo
+
+X(1,2,3,4)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/06.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/06.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/06.expect	(revision 331)
@@ -0,0 +1,1 @@
+foo
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/07.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/07.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/07.c	(revision 331)
@@ -0,0 +1,4 @@
+#define a() YES
+#define b() a
+b()
+b()()
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/07.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/07.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/07.expect	(revision 331)
@@ -0,0 +1,2 @@
+a
+YES
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/08.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/08.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/08.c	(revision 331)
@@ -0,0 +1,4 @@
+// test macro expansion in arguments
+#define s_pos              s_s.s_pos
+#define foo(x) (x)
+foo(hej.s_pos)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/08.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/08.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/08.expect	(revision 331)
@@ -0,0 +1,1 @@
+(hej.s_s.s_pos)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/09.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/09.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/09.c	(revision 331)
@@ -0,0 +1,4 @@
+#define C(a,b,c) a##b##c
+#define N(x,y) C(x,_,y)
+#define A_O aaaaoooo
+N(A,O)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/09.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/09.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/09.expect	(revision 331)
@@ -0,0 +1,1 @@
+aaaaoooo
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/10.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/10.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/10.c	(revision 331)
@@ -0,0 +1,10 @@
+#define f(x) x
+#define g(x) f(x) f(x
+#define i(x) g(x)) g(x
+#define h(x) i(x))) i(x
+#define k(x) i(x))) i(x))))
+f(x)
+g(x))
+i(x)))
+h(x))))
+k(x))))
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/10.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/10.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/10.expect	(revision 331)
@@ -0,0 +1,5 @@
+x
+x x
+x x x x
+x x x x x x x x
+x x x x x x x x))))
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/11.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/11.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/11.c	(revision 331)
@@ -0,0 +1,31 @@
+#define D1(s, ...) s
+#define D2(s, ...) s D1(__VA_ARGS__)
+#define D3(s, ...) s D2(__VA_ARGS__)
+#define D4(s, ...) s D3(__VA_ARGS__)
+
+D1(a)
+D2(a, b)
+D3(a, b, c)
+D4(a, b, c, d)
+
+x D4(a, b, c, d) y
+x D4(a, b, c) y
+x D4(a, b) y
+x D4(a) y
+x D4() y
+
+#define GNU_COMMA(X,Y...) X,## Y
+
+x GNU_COMMA(A,B,C) y
+x GNU_COMMA(A,B) y
+x GNU_COMMA(A) y
+x GNU_COMMA() y
+
+#define __sun_attr___noreturn__ __attribute__((__noreturn__))
+#define ___sun_attr_inner(__a) __sun_attr_##__a
+#define __sun_attr__(__a) ___sun_attr_inner __a
+#define __NORETURN __sun_attr__((__noreturn__))
+__NORETURN
+#define X(...)
+#define Y(...)  1 __VA_ARGS__ 2
+Y(X X() ())
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/11.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/11.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/11.expect	(revision 331)
@@ -0,0 +1,15 @@
+a
+a b
+a b c
+a b c d
+x a b c d y
+x a b c y
+x a b y
+x a y
+x y
+x A,B,C y
+x A,B y
+x A y
+x y
+__attribute__((__noreturn__))
+1 2
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/12.S
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/12.S	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/12.S	(revision 331)
@@ -0,0 +1,8 @@
+#define SRC(y...)                       \
+        9999: y;                        \
+        .section __ex_table, "a";       \
+        .long 9999b, 6001f      ;       \
+        // .previous
+
+    SRC(1: movw (%esi), %bx)
+6001:
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/12.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/12.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/12.expect	(revision 331)
@@ -0,0 +1,2 @@
+    9999: 1: movw (%esi), %bx; .section __ex_table, "a"; .long 9999b, 6001f ;
+6001:
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/13.S
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/13.S	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/13.S	(revision 331)
@@ -0,0 +1,6 @@
+# `modelist' label. Each video mode record looks like:
+#ifdef AAA
+# modelist' label. Each video mode record looks like:
+#endif
+.text
+endtext:
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/13.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/13.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/13.expect	(revision 331)
@@ -0,0 +1,2 @@
+.text
+endtext:
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/14.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/14.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/14.c	(revision 331)
@@ -0,0 +1,13 @@
+#define W Z
+#define Z(X) W(X,2)
+#define Y(X) Z(X)
+#define X Y
+return X(X(1));
+
+#define P Q
+#define Q(n) P(n,2)
+return P(1);
+
+#define A (B * B)
+#define B (A + A)
+return A + B;
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/14.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/14.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/14.expect	(revision 331)
@@ -0,0 +1,3 @@
+return Z(Z(1,2),2);
+return Q(1,2);
+return ((A + A) * (A + A)) + ((B * B) + (B * B));
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/15.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/15.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/15.c	(revision 331)
@@ -0,0 +1,18 @@
+// insert a space between two tokens if otherwise they
+// would form a single token when read back
+
+#define n(x) x
+
+return (n(long)n(double))d;
+return n(A)n(++)n(+)n(B);
+return n(A)n(+)n(++)n(B);
+return n(A)n(++)n(+)n(+)n(B);
+
+// not a hex float
+return n(0x1E)n(-1);
+
+// unlike gcc but correct
+// XXX: return n(x)+n(x)-n(1)+n(1)-2;
+
+// unlike gcc, but cannot appear in valid C
+// XXX: return n(x)n(x)n(1)n(2)n(x);
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/15.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/15.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/15.expect	(revision 331)
@@ -0,0 +1,5 @@
+return (long double)d;
+return A+++B;
+return A+ ++B;
+return A+++ +B;
+return 0x1E -1;
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/16.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/16.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/16.c	(revision 331)
@@ -0,0 +1,3 @@
+/* The following should warn */
+#define A ...
+#define A <<=
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/16.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/16.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/16.expect	(revision 331)
@@ -0,0 +1,2 @@
+
+16.c:3: warning: A redefined
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/17.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/17.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/17.c	(revision 331)
@@ -0,0 +1,14 @@
+#define STR1(u) # u
+#define pass(a) a
+#define __ASM_REG(reg)         STR1(one##reg)
+#define _ASM_DX         __ASM_REG(tok)
+X162 pass(__ASM_REG(tok))
+X161 pass(_ASM_DX)
+X163 pass(STR1(one##tok))
+
+X170 pass(x ## y)
+X171 pass(x pass(##) y)
+
+#define Y(x) Z(x)
+#define X Y
+X180 return X(X(1));
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/17.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/17.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/17.expect	(revision 331)
@@ -0,0 +1,6 @@
+X162 "onetok"
+X161 "onetok"
+X163 "one##tok"
+X170 x ## y
+X171 x ## y
+X180 return Z(Z(1));
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/18.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/18.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/18.c	(revision 331)
@@ -0,0 +1,15 @@
+#define M_RETI_ARG27(x,y,z,aa, ...)    aa
+#define M_RET_ARG27(...)        M_RETI_ARG27(__VA_ARGS__)
+#define M_COMMA_P(...)          M_RET_ARG27(__VA_ARGS__, 1, 1, 0, useless)
+#define M_EMPTYI_DETECT(...)    0, 1,
+#define M_EMPTYI_P_C1(...)      M_COMMA_P(M_EMPTYI_DETECT __VA_ARGS__ () )
+#define EX
+#define empty(x)
+#define fnlike(x) yeah x
+/* If the following macro is called with empty arg (X183), the use
+   of 'x' between fnlike and '(' doesn't hinder the recognition of this
+   being a further fnlike macro invocation.  */
+#define usefnlike(x) fnlike x (x)
+X181 M_EMPTYI_P_C1()
+X182 M_EMPTYI_P_C1(x)
+X183 usefnlike()
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/18.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/18.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/18.expect	(revision 331)
@@ -0,0 +1,3 @@
+X181 1
+X182 0
+X183 yeah
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/19.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/19.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/19.c	(revision 331)
@@ -0,0 +1,101 @@
+#define M_C2I(a, ...)       a ## __VA_ARGS__
+#define M_C(a, ...)         M_C2I(a, __VA_ARGS__)
+#define M_C3I(a, b, ...)    a ## b ## __VA_ARGS__
+#define M_C3(a, b, ...)     M_C3I(a ,b, __VA_ARGS__)
+
+#define M_RETI_ARG2(a, b, ...)  b
+#define M_RET_ARG2(...)         M_RETI_ARG2(__VA_ARGS__)
+#define M_RETI_ARG27(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa, ...)    aa
+#define M_RET_ARG27(...)        M_RETI_ARG27(__VA_ARGS__)
+
+#define M_TOBOOLI_0                 1, 0,
+#define M_BOOL(x)                   M_RET_ARG2(M_C(M_TOBOOLI_, x), 1, useless)
+
+#define M_IFI_0(true_macro, ...)    __VA_ARGS__
+#define M_IFI_1(true_macro, ...)    true_macro
+#define M_IF(c)                     M_C(M_IFI_, M_BOOL(c))
+
+#define M_FLAT(...)                 __VA_ARGS__
+#define M_INVI_0                    1
+#define M_INVI_1                    0
+#define M_INV(x)                    M_C(M_INVI_, x)
+
+#define M_ANDI_00                   0
+#define M_ANDI_01                   0
+#define M_ANDI_10                   0
+#define M_ANDI_11                   1
+#define M_AND(x,y)                  M_C3(M_ANDI_, x, y)
+
+#define M_ORI_00                    0
+#define M_ORI_01                    1
+#define M_ORI_10                    1
+#define M_ORI_11                    1
+#define M_OR(x,y)                   M_C3(M_ORI_, x, y)
+
+#define M_COMMA_P(...)              M_RET_ARG27(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, useless)
+
+#define M_EMPTYI_DETECT(...)        0, 1,
+#define M_EMPTYI_P_C1(...)          M_COMMA_P(M_EMPTYI_DETECT __VA_ARGS__ ())
+#define M_EMPTYI_P_C2(...)          M_COMMA_P(M_EMPTYI_DETECT __VA_ARGS__)
+#define M_EMPTYI_P_C3(...)          M_COMMA_P(__VA_ARGS__ () )
+#define M_EMPTY_P(...)              M_AND(M_EMPTYI_P_C1(__VA_ARGS__), M_INV(M_OR(M_OR(M_EMPTYI_P_C2(__VA_ARGS__), M_COMMA_P(__VA_ARGS__)),M_EMPTYI_P_C3(__VA_ARGS__))))
+#define M_APPLY_FUNC2B(func, arg1, arg2)        \
+  M_IF(M_EMPTY_P(arg2))(,func(arg1, arg2))
+#define M_MAP2B_0(func, data, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z,...) \
+  M_APPLY_FUNC2B(func, data, a) M_APPLY_FUNC2B(func, data, b) M_APPLY_FUNC2B(func, data, c) \
+  M_APPLY_FUNC2B(func, data, d) M_APPLY_FUNC2B(func, data, e) M_APPLY_FUNC2B(func, data, f) \
+  M_APPLY_FUNC2B(func, data, g) M_APPLY_FUNC2B(func, data, h) M_APPLY_FUNC2B(func, data, i) \
+  M_APPLY_FUNC2B(func, data, j) M_APPLY_FUNC2B(func, data, k) M_APPLY_FUNC2B(func, data, l) \
+  M_APPLY_FUNC2B(func, data, m) M_APPLY_FUNC2B(func, data, n) M_APPLY_FUNC2B(func, data, o) \
+  M_APPLY_FUNC2B(func, data, p) M_APPLY_FUNC2B(func, data, q) M_APPLY_FUNC2B(func, data, r) \
+  M_APPLY_FUNC2B(func, data, s) M_APPLY_FUNC2B(func, data, t) M_APPLY_FUNC2B(func, data, u) \
+  M_APPLY_FUNC2B(func, data, v) M_APPLY_FUNC2B(func, data, w) M_APPLY_FUNC2B(func, data, x) \
+  M_APPLY_FUNC2B(func, data, y) M_APPLY_FUNC2B(func, data, z)
+#define M_MAP2B(f, ...) M_MAP2B_0(f, __VA_ARGS__, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , )
+#define M_INIT_INIT(a)           ,a,
+
+#define M_GET_METHOD(method, method_default, ...)                       \
+  M_RET_ARG2 (M_MAP2B(M_C, M_C3(M_, method, _), __VA_ARGS__), method_default,)
+
+#define M_TEST_METHOD_P(method, oplist)                         \
+  M_BOOL(M_GET_METHOD (method, 0, M_FLAT oplist))
+
+#define TRUE 1
+#define TEST1(n)                                \
+  M_IF(n)(ok,nok)
+#define TEST2(op)                               \
+  M_TEST_METHOD_P(INIT, op)
+#define TEST3(op)                               \
+  M_IF(M_TEST_METHOD_P(INIT, op))(ok, nok)
+#define TEST4(op) \
+  TEST1(TEST2(op))
+#define KO(a) ((void)1)
+
+/* This checks that the various expansions that ultimately lead to
+   something like 'KO(arg,arg)', where 'KO' comes from a macro
+   expansion reducing from a large macro chain do not are regarded
+   as funclike macro invocation of KO.  E.g. X93 and X94 expand to 'KO',
+   but X95 must not consume the (a,b) arguments outside the M_IF()
+   invocation to reduce the 'KO' macro to an invocation.  Instead
+   X95 should reduce via M_IF(KO)(a,b) to 'a'. 
+   
+   The other lines here are variations on this scheme, with X1 to
+   X6 coming from the bug report at
+   http://lists.nongnu.org/archive/html/tinycc-devel/2017-07/msg00017.html */
+X92 M_IF(KO)
+X93 M_GET_METHOD(INIT, 0, INIT(KO))
+X94 M_GET_METHOD(INIT, 0, M_FLAT (INIT(KO)))
+X95 M_IF(M_GET_METHOD(INIT, 0, INIT(KO)))(a,b)
+X96 M_IF(M_GET_METHOD(INIT, 0, M_FLAT (INIT(KO))))
+X97 M_IF(M_GET_METHOD(INIT, 0, M_FLAT (INIT(KO))))(ok,nok)
+X98 (M_TEST_METHOD_P(INIT, (INIT(KO))))(ok, nok)
+X99 M_IF(M_TEST_METHOD_P(INIT, (INIT(KO))))(ok, nok)
+// test begins
+X1 TEST1(TRUE)          // ==> expect ok, get ok
+// First test with a token which is not a macro
+X2 TEST2((INIT(ok)))    // ==> expect 1, get 1
+X3 TEST3((INIT(ok)))    // ==> expect ok, get ok
+// Then test with a token which is a macro, but should not be expanded.
+X4 TEST2((INIT(KO)))    // ==> expect 1, get 1
+X5 TEST4(INIT(KO))
+X6 TEST3((INIT(KO)))    // ==> expect ok, get "error: macro 'KO' used with too many args"
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/19.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/19.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/19.expect	(revision 331)
@@ -0,0 +1,14 @@
+X92 M_IFI_1
+X93 KO
+X94 KO
+X95 a
+X96 M_IFI_1
+X97 ok
+X98 (1)(ok, nok)
+X99 ok
+X1 ok
+X2 1
+X3 ok
+X4 1
+X5 nok
+X6 ok
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/20.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/20.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/20.c	(revision 331)
@@ -0,0 +1,13 @@
+/* Various things I encountered while hacking the pre processor */
+#define wrap(x) x
+#define pr_warning(fmt, ...) printk(KERN_WARNING fmt, ##__VA_ARGS__)
+#define pr_warn(x,y) pr_warning(x,y)
+#define net_ratelimited_function(function, ...) function(__VA_ARGS__)
+X1 net_ratelimited_function(pr_warn, "pipapo", bla);
+X2 net_ratelimited_function(wrap(pr_warn), "bla", foo);
+#define two m n
+#define chain4(a,b,c,d) a ## b ## c ## d
+X2 chain4(two,o,p,q)
+X3 chain4(o,two,p,q)
+X4 chain4(o,p,two,q)
+X5 chain4(o,p,q,two)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/20.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/20.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/20.expect	(revision 331)
@@ -0,0 +1,6 @@
+X1 printk(KERN_WARNING "pipapo",bla);
+X2 printk(KERN_WARNING "bla",foo);
+X2 twoopq
+X3 otwopq
+X4 optwoq
+X5 opqtwo
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/21.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/21.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/21.c	(revision 331)
@@ -0,0 +1,36 @@
+/* accept 'defined' as result of substitution */
+
+----- 1 ------
+#define AAA 2
+#define BBB
+#define CCC (defined ( AAA ) && AAA > 1 && !defined BBB)
+#if !CCC
+OK
+#else
+NOT OK
+#endif
+
+----- 2 ------
+#undef BBB
+#if CCC
+OK
+#else
+NOT OK
+#endif
+
+----- 3 ------
+#define DEFINED defined
+#define DDD (DEFINED ( AAA ) && AAA > 1 && !DEFINED BBB)
+#if (DDD)
+OK
+#else
+NOT OK
+#endif
+
+----- 4 ------
+#undef AAA
+#if !(DDD)
+OK
+#else
+NOT OK
+#endif
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/21.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/21.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/21.expect	(revision 331)
@@ -0,0 +1,8 @@
+----- 1 ------
+OK
+----- 2 ------
+OK
+----- 3 ------
+OK
+----- 4 ------
+OK
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/Makefile
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/Makefile	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/Makefile	(revision 331)
@@ -0,0 +1,49 @@
+#
+# credits: 01..13.c from the pcc cpp-tests suite
+#
+
+TOP = ../..
+include $(TOP)/Makefile
+SRC = $(TOPSRC)/tests/pp
+VPATH = $(SRC)
+
+files = $(patsubst %.$1,%.test,$(notdir $(wildcard $(SRC)/*.$1)))
+TESTS = $(call files,c) $(call files,S)
+
+all test : $(sort $(TESTS))
+
+DIFF_OPTS = -Nu -b -B
+
+# Filter source directory in warnings/errors (out-of-tree builds)
+FILTER = 2>&1 | sed 's,$(SRC)/,,g'
+
+%.test: %.c %.expect
+	@echo PPTest $* ...
+	-@$(TCC) -E -P $< $(FILTER) >$*.output 2>&1 ; \
+	    diff $(DIFF_OPTS) $(SRC)/$*.expect $*.output \
+	    && rm -f $*.output
+
+%.test: %.S %.expect
+	@echo PPTest $* ...
+	-@$(TCC) -E -P $< $(FILTER) >$*.output 2>&1 ; \
+	    diff $(DIFF_OPTS) $(SRC)/$*.expect $*.output \
+	    && rm -f $*.output
+
+# automatically generate .expect files with gcc:
+%.expect: # %.c
+	gcc -E -P $*.[cS] >$*.expect 2>&1
+
+# tell make not to delete
+.PRECIOUS: %.expect
+
+clean:
+	rm -f *.output
+
+02.test : DIFF_OPTS += -w
+# 15.test : DIFF_OPTS += -I"^XXX:"
+
+# diff options:
+# -b ighore space changes
+# -w ighore all whitespace
+# -B ignore blank lines
+# -I <RE> ignore lines matching RE
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/pp-counter.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/pp-counter.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/pp-counter.c	(revision 331)
@@ -0,0 +1,27 @@
+X1 __COUNTER__
+X2 __COUNTER__
+#if __COUNTER__
+X3 __COUNTER__
+#endif
+#define pass(x) x
+#define a x __COUNTER__ y
+#define a2 pass(__COUNTER__)
+#define f(c) c __COUNTER__
+#define apply(d) d d __COUNTER__ x2 f(d) y2 __COUNTER__
+#define _paste(a,b) a ## b
+#define paste(a,b) _paste(a,b)
+#define _paste3(a,b,c) a ## b ## c
+#define doublepaste(a,b) _paste3(a,b,b)
+#define str(x) #x
+X4 a
+X5 f(a)
+X6 f(b)
+X7 f(__COUNTER__)
+X8 apply(a)
+X9 apply(f(a))
+X10 apply(__COUNTER__)
+X11 apply(a2)
+X12 str(__COUNTER__)
+X13 paste(x,__COUNTER__)
+X14 _paste(x,__COUNTER__)
+X15 doublepaste(x,__COUNTER__)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/pp-counter.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/pp-counter.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/pp/pp-counter.expect	(revision 331)
@@ -0,0 +1,15 @@
+X1 0
+X2 1
+X3 3
+X4 x 4 y
+X5 x 5 y 6
+X6 b 7
+X7 8 9
+X8 x 10 y x 10 y 11 x2 x 10 y 12 y2 13
+X9 x 14 y 15 x 14 y 15 16 x2 x 14 y 15 17 y2 18
+X10 19 19 20 x2 19 21 y2 22
+X11 23 23 24 x2 23 25 y2 26
+X12 "__COUNTER__"
+X13 x27
+X14 x__COUNTER__
+X15 x2828
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tcctest.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tcctest.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tcctest.c	(revision 331)
@@ -0,0 +1,3879 @@
+/*
+ * TCC auto test program
+ */
+#include "config.h"
+
+#if GCC_MAJOR >= 3
+
+/* Unfortunately, gcc version < 3 does not handle that! */
+#define ALL_ISOC99
+
+/* only gcc 3 handles _Bool correctly */
+#define BOOL_ISOC99
+
+/* gcc 2.95.3 does not handle correctly CR in strings or after strays */
+#define CORRECT_CR_HANDLING
+
+#endif
+
+#if defined(_WIN32)
+#define LONG_LONG_FORMAT "%lld"
+#define ULONG_LONG_FORMAT "%llu"
+#else
+#define LONG_LONG_FORMAT "%Ld"
+#define ULONG_LONG_FORMAT "%Lu"
+#endif
+
+// MinGW has 80-bit rather than 64-bit long double which isn't compatible with TCC or MSVC
+#if defined(_WIN32) && defined(__GNUC__)
+#define LONG_DOUBLE double
+#define LONG_DOUBLE_LITERAL(x) x
+#else
+#define LONG_DOUBLE long double
+#define LONG_DOUBLE_LITERAL(x) x ## L
+#endif
+
+/* deprecated and no longer supported in gcc 3.3 */
+//#define ACCEPT_CR_IN_STRINGS
+
+/* __VA_ARGS__ and __func__ support */
+#define C99_MACROS
+
+/* test various include syntaxes */
+
+#define TCCLIB_INC <tcclib.h>
+#define TCCLIB_INC1 <tcclib
+#define TCCLIB_INC2 h>
+#define TCCLIB_INC3 "tcclib.h"
+
+#include TCCLIB_INC
+
+#include TCCLIB_INC1.TCCLIB_INC2
+
+#include TCCLIB_INC1.h>
+
+#include TCCLIB_INC3
+
+#include <tcclib.h>
+
+#include "tcclib.h"
+
+#include "tcctest.h"
+
+/* Test two more ways to include a file named like a pp-number */
+#define INC(name) <tests/name.h>
+#define funnyname 42test.h
+#define incdir tests/
+#define incname < incdir funnyname >
+#define __stringify(x) #x
+#define stringify(x) __stringify(x)
+#include INC(42test)
+#include incname
+#include stringify(funnyname)
+
+void intdiv_test();
+void string_test();
+void expr_test();
+void macro_test();
+void recursive_macro_test();
+void scope_test();
+void forward_test();
+void funcptr_test();
+void loop_test();
+void switch_test();
+void goto_test();
+void enum_test();
+void typedef_test();
+void struct_test();
+void array_test();
+void expr_ptr_test();
+void bool_test();
+void optimize_out();
+void expr2_test();
+void constant_expr_test();
+void expr_cmp_test();
+void char_short_test();
+void init_test(void);
+void compound_literal_test(void);
+int kr_test();
+void struct_assign_test(void);
+void cast_test(void);
+void bitfield_test(void);
+void c99_bool_test(void);
+void float_test(void);
+void longlong_test(void);
+void manyarg_test(void);
+void stdarg_test(void);
+void whitespace_test(void);
+void relocation_test(void);
+void old_style_function(void);
+void alloca_test(void);
+void c99_vla_test(int size1, int size2);
+void sizeof_test(void);
+void typeof_test(void);
+void local_label_test(void);
+void statement_expr_test(void);
+void asm_test(void);
+void builtin_test(void);
+void weak_test(void);
+void global_data_test(void);
+void cmp_comparison_test(void);
+void math_cmp_test(void);
+void callsave_test(void);
+void builtin_frame_address_test(void);
+void attrib_test(void);
+
+int fib(int n);
+void num(int n);
+void forward_ref(void);
+int isid(int c);
+
+/* Line joining happens before tokenization, so the following
+   must be parsed as ellipsis.  */
+void funny_line_continuation (int, ..\
+. );
+
+char via_volatile (char);
+
+#define A 2
+#define N 1234 + A
+#define pf printf
+#define M1(a, b)  (a) + (b)
+
+#define str\
+(s) # s
+#define glue(a, b) a ## b
+#define xglue(a, b) glue(a, b)
+#define HIGHLOW "hello"
+#define LOW LOW ", world"
+
+static int onetwothree = 123;
+#define onetwothree4 onetwothree
+#define onetwothree xglue(onetwothree,4)
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
+#ifdef C99_MACROS
+#define dprintf(level,...) printf(__VA_ARGS__)
+#endif
+
+/* gcc vararg macros */
+#define dprintf1(level, fmt, args...) printf(fmt, ## args)
+
+#define MACRO_NOARGS()
+
+#define AAA 3
+#undef AAA
+#define AAA 4
+
+#if 1
+#define B3 1
+#elif 1
+#define B3 2
+#elif 0
+#define B3 3
+#else
+#define B3 4
+#endif
+
+#ifdef __TINYC__
+/* We try to handle this syntax.  Make at least sure it doesn't segfault.  */
+char invalid_function_def()[] {}
+#endif
+
+#define __INT64_C(c)	c ## LL
+#define INT64_MIN	(-__INT64_C(9223372036854775807)-1)
+
+int qq(int x)
+{
+    return x + 40;
+}
+#define qq(x) x
+
+#define spin_lock(lock) do { } while (0)
+#define wq_spin_lock spin_lock
+#define TEST2() wq_spin_lock(a)
+
+#define UINT_MAX ((unsigned) -1)
+
+void intdiv_test(void)
+{
+    printf("18/21=%u\n", 18/21);
+    printf("18%%21=%u\n", 18%21);
+    printf("41/21=%u\n", 41/21);
+    printf("41%%21=%u\n", 41%21);
+    printf("42/21=%u\n", 42/21);
+    printf("42%%21=%u\n", 42%21);
+    printf("43/21=%u\n", 43/21);
+    printf("43%%21=%u\n", 43%21);
+    printf("126/21=%u\n", 126/21);
+    printf("126%%21=%u\n", 126%21);
+    printf("131/21=%u\n", 131/21);
+    printf("131%%21=%u\n", 131%21);
+    printf("(UINT_MAX/2+3)/2=%u\n", (UINT_MAX/2+3)/2);
+    printf("(UINT_MAX/2+3)%%2=%u\n", (UINT_MAX/2+3)%2);
+
+    printf("18/-21=%u\n", 18/-21);
+    printf("18%%-21=%u\n", 18%-21);
+    printf("41/-21=%u\n", 41/-21);
+    printf("41%%-21=%u\n", 41%-21);
+    printf("42/-21=%u\n", 42/-21);
+    printf("42%%-21=%u\n", 42%-21);
+    printf("43/-21=%u\n", 43/-21);
+    printf("43%%-21=%u\n", 43%-21);
+    printf("126/-21=%u\n", 126/-21);
+    printf("126%%-21=%u\n", 126%-21);
+    printf("131/-21=%u\n", 131/-21);
+    printf("131%%-21=%u\n", 131%-21);
+    printf("(UINT_MAX/2+3)/-2=%u\n", (UINT_MAX/2+3)/-2);
+    printf("(UINT_MAX/2+3)%%-2=%u\n", (UINT_MAX/2+3)%-2);
+
+    printf("-18/21=%u\n", -18/21);
+    printf("-18%%21=%u\n", -18%21);
+    printf("-41/21=%u\n", -41/21);
+    printf("-41%%21=%u\n", -41%21);
+    printf("-42/21=%u\n", -42/21);
+    printf("-42%%21=%u\n", -42%21);
+    printf("-43/21=%u\n", -43/21);
+    printf("-43%%21=%u\n", -43%21);
+    printf("-126/21=%u\n", -126/21);
+    printf("-126%%21=%u\n", -126%21);
+    printf("-131/21=%u\n", -131/21);
+    printf("-131%%21=%u\n", -131%21);
+    printf("-(UINT_MAX/2+3)/2=%u\n", (0-(UINT_MAX/2+3))/2);
+    printf("-(UINT_MAX/2+3)%%2=%u\n", (0-(UINT_MAX/2+3))%2);
+
+    printf("-18/-21=%u\n", -18/-21);
+    printf("-18%%-21=%u\n", -18%-21);
+    printf("-41/-21=%u\n", -41/-21);
+    printf("-41%%-21=%u\n", -41%-21);
+    printf("-42/-21=%u\n", -42/-21);
+    printf("-42%%-21=%u\n", -42%-21);
+    printf("-43/-21=%u\n", -43/-21);
+    printf("-43%%-21=%u\n", -43%-21);
+    printf("-126/-21=%u\n", -126/-21);
+    printf("-126%%-21=%u\n", -126%-21);
+    printf("-131/-21=%u\n", -131/-21);
+    printf("-131%%-21=%u\n", -131%-21);
+    printf("-(UINT_MAX/2+3)/-2=%u\n", (0-(UINT_MAX/2+3))/-2);
+    printf("-(UINT_MAX/2+3)%%-2=%u\n", (0-(UINT_MAX/2+3))%-2);
+}
+
+void macro_test(void)
+{
+    printf("macro:\n");
+
+
+    pf("N=%d\n", N);
+    printf("aaa=%d\n", AAA);
+
+    printf("min=%d\n", min(1, min(2, -1)));
+
+    printf("s1=%s\n", glue(HIGH, LOW));
+    printf("s2=%s\n", xglue(HIGH, LOW));
+    printf("s3=%s\n", str("c"));
+    printf("s4=%s\n", str(a1));
+    printf("B3=%d\n", B3);
+
+    printf("onetwothree=%d\n", onetwothree);
+
+#ifdef A
+    printf("A defined\n");
+#endif
+#ifdef B
+    printf("B defined\n");
+#endif
+#ifdef A
+    printf("A defined\n");
+#else
+    printf("A not defined\n");
+#endif
+#ifdef B
+    printf("B defined\n");
+#else
+    printf("B not defined\n");
+#endif
+
+#ifdef A
+    printf("A defined\n");
+#ifdef B
+    printf("B1 defined\n");
+#else
+    printf("B1 not defined\n");
+#endif
+#else
+    printf("A not defined\n");
+#ifdef B
+    printf("B2 defined\n");
+#else
+    printf("B2 not defined\n");
+#endif
+#endif
+
+#if 1+1
+    printf("test true1\n");
+#endif
+#if 0
+    printf("test true2\n");
+#endif
+#if 1-1
+    printf("test true3\n");
+#endif
+#if defined(A)
+    printf("test trueA\n");
+#endif
+#if defined(B)
+    printf("test trueB\n");
+#endif
+
+#if 0
+    printf("test 0\n");
+#elif 0
+    printf("test 1\n");
+#elif 2
+    printf("test 2\n");
+#else
+    printf("test 3\n");
+#endif
+
+    MACRO_NOARGS();
+
+#ifdef __LINE__
+    printf("__LINE__ defined\n");
+#endif
+
+    printf("__LINE__=%d __FILE__=%s\n",
+           __LINE__, __FILE__);
+#if 0
+#line 200
+    printf("__LINE__=%d __FILE__=%s\n",
+           __LINE__, __FILE__);
+#line 203 "test" 
+    printf("__LINE__=%d __FILE__=%s\n",
+           __LINE__, __FILE__);
+#line 227 "tcctest.c"
+#endif
+
+    /* not strictly preprocessor, but we test it there */
+#ifdef C99_MACROS
+    printf("__func__ = %s\n", __func__);
+    dprintf(1, "vaarg=%d\n", 1);
+#endif
+    dprintf1(1, "vaarg1\n");
+    dprintf1(1, "vaarg1=%d\n", 2);
+    dprintf1(1, "vaarg1=%d %d\n", 1, 2);
+
+    /* gcc extension */
+    printf("func='%s'\n", __FUNCTION__);
+
+    /* complicated macros in glibc */
+    printf("INT64_MIN=" LONG_LONG_FORMAT "\n", INT64_MIN);
+    {
+        int a;
+        a = 1;
+        glue(a+, +);
+        printf("a=%d\n", a);
+        glue(a <, <= 2);
+        printf("a=%d\n", a);
+    }
+    
+    /* macro function with argument outside the macro string */
+#define MF_s MF_hello
+#define MF_hello(msg) printf("%s\n",msg)
+
+#define MF_t printf("tralala\n"); MF_hello
+
+    MF_s("hi");
+    MF_t("hi");
+    
+    /* test macro substitution inside args (should not eat stream) */
+    printf("qq=%d\n", qq(qq)(2));
+
+    /* test zero argument case. NOTE: gcc 2.95.x does not accept a
+       null argument without a space. gcc 3.2 fixes that. */
+
+#define qq1(x) 1
+    printf("qq1=%d\n", qq1( ));
+
+    /* comment with stray handling *\
+/
+       /* this is a valid *\/ comment */
+       /* this is a valid comment *\*/
+    //  this is a valid\
+comment
+
+    /* test function macro substitution when the function name is
+       substituted */
+    TEST2();
+
+    /* And again when the name and parentheses are separated by a
+       comment.  */
+    TEST2 /* the comment */ ();
+
+    printf("%s\n", get_basefile_from_header());
+    printf("%s\n", __BASE_FILE__);
+    printf("%s\n", get_file_from_header());
+    printf("%s\n", __FILE__);
+
+    /* Check that funnily named include was in fact included */
+    have_included_42test_h = 1;
+    have_included_42test_h_second = 1;
+    have_included_42test_h_third = 1;
+}
+
+
+static void print_num(char *fn, int line, int num) {
+    printf("fn %s, line %d, num %d\n", fn, line, num);
+}
+
+void recursive_macro_test(void)
+{
+
+#define ELF32_ST_TYPE(val)              ((val) & 0xf)
+#define ELF32_ST_INFO(bind, type)       (((bind) << 4) + ((type) & 0xf))
+#define STB_WEAK        2               /* Weak symbol */
+#define ELFW(type) ELF##32##_##type
+    printf("%d\n", ELFW(ST_INFO)(STB_WEAK, ELFW(ST_TYPE)(123)));
+
+#define WRAP(x) x
+    
+#define print_num(x) print_num(__FILE__,__LINE__,x)
+    print_num(123);
+    WRAP(print_num(123));
+    WRAP(WRAP(print_num(123)));
+
+static struct recursive_macro { int rm_field; } G;
+#define rm_field (G.rm_field)
+    printf("rm_field = %d\n", rm_field);
+    printf("rm_field = %d\n", WRAP(rm_field));
+    WRAP((printf("rm_field = %d %d\n", rm_field, WRAP(rm_field))));
+}
+
+int op(a,b)
+{
+    return a / b;
+}
+
+int ret(a)
+{
+    if (a == 2)
+        return 1;
+    if (a == 3)
+        return 2;
+    return 0;
+}
+
+void ps(const char *s)
+{
+    int c;
+    while (1) {
+        c = *s;
+        if (c == 0)
+            break;
+        printf("%c", c);
+        s++;
+    }
+}
+
+const char foo1_string[] = "\
+bar\n\
+test\14\
+1";
+
+void string_test()
+{
+    unsigned int b;
+    printf("string:\n");
+    printf("\141\1423\143\n");/* dezdez test */
+    printf("\x41\x42\x43\x3a\n");
+    printf("c=%c\n", 'r');
+    printf("wc=%C 0x%lx %C\n", L'a', L'\x1234', L'c');
+    printf("foo1_string='%s'\n", foo1_string);
+#if 0
+    printf("wstring=%S\n", L"abc");
+    printf("wstring=%S\n", L"abc" L"def" "ghi");
+    printf("'\\377'=%d '\\xff'=%d\n", '\377', '\xff');
+    printf("L'\\377'=%d L'\\xff'=%d\n", L'\377', L'\xff');
+#endif
+    ps("test\n");
+    b = 32;
+    while ((b = b + 1) < 96) {
+        printf("%c", b);
+    }
+    printf("\n");
+    printf("fib=%d\n", fib(33));
+    b = 262144;
+    while (b != 0x80000000) {
+        num(b);
+        b = b * 2;
+    }
+}
+
+void loop_test()
+{
+    int i;
+    i = 0;
+    while (i < 10)
+        printf("%d", i++);
+    printf("\n");
+    for(i = 0; i < 10;i++)
+        printf("%d", i);
+    printf("\n");
+    i = 0;
+    do {
+        printf("%d", i++);
+    } while (i < 10);
+    printf("\n");
+
+    char count = 123;
+    /* c99 for loop init test */
+    for (size_t count = 1; count < 3; count++)
+        printf("count=%d\n", count);
+    printf("count = %d\n", count);
+
+    /* break/continue tests */
+    i = 0;
+    while (1) {
+        if (i == 6)
+            break;
+        i++;
+        if (i == 3)
+            continue;
+        printf("%d", i);
+    }
+    printf("\n");
+
+    /* break/continue tests */
+    i = 0;
+    do {
+        if (i == 6)
+            break;
+        i++;
+        if (i == 3)
+            continue;
+        printf("%d", i);
+    } while(1);
+    printf("\n");
+
+    for(i = 0;i < 10;i++) {
+        if (i == 3)
+            continue;
+        printf("%d", i);
+    }
+    printf("\n");
+}
+
+typedef int typedef_and_label;
+
+void goto_test()
+{
+    int i;
+    static void *label_table[3] = { &&label1, &&label2, &&label3 };
+
+    printf("goto:\n");
+    i = 0;
+    /* This needs to parse as label, not as start of decl.  */
+ typedef_and_label:
+ s_loop:
+    if (i >= 10) 
+        goto s_end;
+    printf("%d", i);
+    i++;
+    goto s_loop;
+ s_end:
+    printf("\n");
+
+    /* we also test computed gotos (GCC extension) */
+    for(i=0;i<3;i++) {
+        goto *label_table[i];
+    label1:
+        printf("label1\n");
+        goto next;
+    label2:
+        printf("label2\n");
+        goto next;
+    label3:
+        printf("label3\n");
+    next: ;
+    }
+}
+
+enum {
+    E0,
+    E1 = 2,
+    E2 = 4,
+    E3,
+    E4,
+};
+
+enum test {
+    E5 = 1000,
+};
+
+struct S_enum {
+    enum {E6 = 42, E7, E8} e:8;
+};
+
+enum ELong {
+    /* This is either 0 on L32 machines, or a large number
+       on L64 machines.  We should be able to store this.  */
+    EL_large = ((unsigned long)0xf000 << 31) << 1,
+};
+
+enum { BIASU = -1U<<31 };
+enum { BIASS = -1 << 31 };
+
+static int getint(int i)
+{
+  if (i)
+    return 0;
+  else
+    return (int)(-1U << 31);
+}
+
+void enum_test()
+{
+    enum test b1;
+    /* The following should give no warning */
+    unsigned *p = &b1;
+    struct S_enum s = {E7};
+    printf("enum: %d\n", s.e);
+    printf("enum:\n%d %d %d %d %d %d\n",
+           E0, E1, E2, E3, E4, E5);
+    b1 = 1;
+    printf("b1=%d\n", b1);
+    printf("enum large: %ld\n", EL_large);
+
+    if (getint(0) == BIASU)
+      printf("enum unsigned: ok\n");
+    else
+      printf("enum unsigned: wrong\n");
+    if (getint(0) == BIASS)
+      printf("enum unsigned: ok\n");
+    else
+      printf("enum unsigned: wrong\n");
+}
+
+typedef int *my_ptr;
+
+typedef int mytype1;
+typedef int mytype2;
+
+void typedef_test()
+{
+    my_ptr a;
+    mytype1 mytype2;
+    int b;
+
+    a = &b;
+    *a = 1234;
+    printf("typedef:\n");
+    printf("a=%d\n", *a);
+    mytype2 = 2;
+    printf("mytype2=%d\n", mytype2);
+}
+
+void forward_test()
+{
+    printf("forward:\n");
+    forward_ref();
+    forward_ref();
+}
+
+
+void forward_ref(void)
+{
+    printf("forward ok\n");
+}
+
+typedef struct struct1 {
+    int f1;
+    int f2, f3;
+    union union1 {
+        int v1;
+        int v2;
+    } u;
+    char str[3];
+} struct1;
+
+struct struct2 {
+    int a;
+    char b;
+};
+
+union union2 {
+    int w1;
+    int w2;
+};
+
+struct struct1 st1, st2;
+
+struct empty_mem {
+    /* nothing */ ;
+    int x;
+};
+
+int main(int argc, char **argv)
+{
+    string_test();
+    expr_test();
+    macro_test();
+    recursive_macro_test();
+    scope_test();
+    forward_test();
+    funcptr_test();
+    loop_test();
+    switch_test();
+    goto_test();
+    enum_test();
+    typedef_test();
+    struct_test();
+    array_test();
+    expr_ptr_test();
+    bool_test();
+    optimize_out();
+    expr2_test();
+    constant_expr_test();
+    expr_cmp_test();
+    char_short_test();
+    init_test();
+    compound_literal_test();
+    kr_test();
+    struct_assign_test();
+    cast_test();
+    bitfield_test();
+    c99_bool_test();
+    float_test();
+    longlong_test();
+    manyarg_test();
+    stdarg_test();
+    whitespace_test();
+    relocation_test();
+    old_style_function();
+    alloca_test();
+    c99_vla_test(5, 2);
+    sizeof_test();
+    typeof_test();
+    statement_expr_test();
+    local_label_test();
+    asm_test();
+    builtin_test();
+#ifndef _WIN32
+    weak_test();
+#endif
+    global_data_test();
+    cmp_comparison_test();
+    math_cmp_test();
+    callsave_test();
+    builtin_frame_address_test();
+    intdiv_test();
+    if (via_volatile (42) != 42)
+      printf ("via_volatile broken\n");
+    attrib_test();
+    return 0; 
+}
+
+int tab[3];
+int tab2[3][2];
+
+int g;
+
+void f1(g)
+{
+    printf("g1=%d\n", g);
+}
+
+void scope_test()
+{
+    printf("scope:\n");
+    g = 2;
+    f1(1);
+    printf("g2=%d\n", g);
+    {
+        int g;
+        g = 3;
+        printf("g3=%d\n", g);
+        {
+            int g;
+            g = 4;
+            printf("g4=%d\n", g);
+        }
+    }
+    printf("g5=%d\n", g);
+}
+
+void array_test()
+{
+    int i, j, a[4];
+
+    printf("array:\n");
+    printf("sizeof(a) = %d\n", sizeof(a));
+    printf("sizeof(\"a\") = %d\n", sizeof("a"));
+#ifdef C99_MACROS
+    printf("sizeof(__func__) = %d\n", sizeof(__func__));
+#endif
+    printf("sizeof tab %d\n", sizeof(tab));
+    printf("sizeof tab2 %d\n", sizeof tab2);
+    tab[0] = 1;
+    tab[1] = 2;
+    tab[2] = 3;
+    printf("%d %d %d\n", tab[0], tab[1], tab[2]);
+    for(i=0;i<3;i++)
+        for(j=0;j<2;j++)
+            tab2[i][j] = 10 * i + j;
+    for(i=0;i<3*2;i++) {
+        printf(" %3d", ((int *)tab2)[i]);
+    }
+    printf("\n");
+    printf("sizeof(size_t)=%d\n", sizeof(size_t));
+    printf("sizeof(ptrdiff_t)=%d\n", sizeof(ptrdiff_t));
+}
+
+void expr_test()
+{
+    int a, b;
+    a = 0;
+    printf("%d\n", a += 1);
+    printf("%d\n", a -= 2);
+    printf("%d\n", a *= 31232132);
+    printf("%d\n", a /= 4);
+    printf("%d\n", a %= 20);
+    printf("%d\n", a &= 6);
+    printf("%d\n", a ^= 7);
+    printf("%d\n", a |= 8);
+    printf("%d\n", a >>= 3);
+    printf("%d\n", a <<= 4);
+
+    a = 22321;
+    b = -22321;
+    printf("%d\n", a + 1);
+    printf("%d\n", a - 2);
+    printf("%d\n", a * 312);
+    printf("%d\n", a / 4);
+    printf("%d\n", b / 4);
+    printf("%d\n", (unsigned)b / 4);
+    printf("%d\n", a % 20);
+    printf("%d\n", b % 20);
+    printf("%d\n", (unsigned)b % 20);
+    printf("%d\n", a & 6);
+    printf("%d\n", a ^ 7);
+    printf("%d\n", a | 8);
+    printf("%d\n", a >> 3);
+    printf("%d\n", b >> 3);
+    printf("%d\n", (unsigned)b >> 3);
+    printf("%d\n", a << 4);
+    printf("%d\n", ~a);
+    printf("%d\n", -a);
+    printf("%d\n", +a);
+
+    printf("%d\n", 12 + 1);
+    printf("%d\n", 12 - 2);
+    printf("%d\n", 12 * 312);
+    printf("%d\n", 12 / 4);
+    printf("%d\n", 12 % 20);
+    printf("%d\n", 12 & 6);
+    printf("%d\n", 12 ^ 7);
+    printf("%d\n", 12 | 8);
+    printf("%d\n", 12 >> 2);
+    printf("%d\n", 12 << 4);
+    printf("%d\n", ~12);
+    printf("%d\n", -12);
+    printf("%d\n", +12);
+    printf("%d %d %d %d\n", 
+           isid('a'), 
+           isid('g'), 
+           isid('T'), 
+           isid('('));
+}
+
+int isid(int c)
+{
+    return (c >= 'a' & c <= 'z') | (c >= 'A' & c <= 'Z') | c == '_';
+}
+
+/**********************/
+
+int vstack[10], *vstack_ptr;
+
+void vpush(int vt, int vc)
+{
+    *vstack_ptr++ = vt;
+    *vstack_ptr++ = vc;
+}
+
+void vpop(int *ft, int *fc)
+{
+    *fc = *--vstack_ptr;
+    *ft = *--vstack_ptr;
+}
+
+void expr2_test()
+{
+    int a, b;
+
+    printf("expr2:\n");
+    vstack_ptr = vstack;
+    vpush(1432432, 2);
+    vstack_ptr[-2] &= ~0xffffff80;
+    vpop(&a, &b);
+    printf("res= %d %d\n", a, b);
+}
+
+void constant_expr_test()
+{
+    int a;
+    printf("constant_expr:\n");
+    a = 3;
+    printf("%d\n", a * 16);
+    printf("%d\n", a * 1);
+    printf("%d\n", a + 0);
+}
+
+int tab4[10];
+
+void expr_ptr_test()
+{
+    int *p, *q;
+    int i = -1;
+
+    printf("expr_ptr:\n");
+    p = tab4;
+    q = tab4 + 10;
+    printf("diff=%d\n", q - p);
+    p++;
+    printf("inc=%d\n", p - tab4);
+    p--;
+    printf("dec=%d\n", p - tab4);
+    ++p;
+    printf("inc=%d\n", p - tab4);
+    --p;
+    printf("dec=%d\n", p - tab4);
+    printf("add=%d\n", p + 3 - tab4);
+    printf("add=%d\n", 3 + p - tab4);
+
+    /* check if 64bit support is ok */
+    q = p = 0;
+    q += i;
+    printf("%p %p %ld\n", q, p, p-q);
+    printf("%d %d %d %d %d %d\n",
+           p == q, p != q, p < q, p <= q, p >= q, p > q);
+    i = 0xf0000000;
+    p += i;
+    printf("%p %p %ld\n", q, p, p-q);
+    printf("%d %d %d %d %d %d\n",
+           p == q, p != q, p < q, p <= q, p >= q, p > q);
+    p = (int *)((char *)p + 0xf0000000);
+    printf("%p %p %ld\n", q, p, p-q);
+    printf("%d %d %d %d %d %d\n",
+           p == q, p != q, p < q, p <= q, p >= q, p > q);
+    p += 0xf0000000;
+    printf("%p %p %ld\n", q, p, p-q);
+    printf("%d %d %d %d %d %d\n",
+           p == q, p != q, p < q, p <= q, p >= q, p > q);
+    {
+        struct size12 {
+            int i, j, k;
+        };
+        struct size12 s[2], *sp = s;
+        int i, j;
+        sp->i = 42;
+        sp++;
+        j = -1;
+        printf("%d\n", sp[j].i);
+    }
+#ifdef __LP64__
+    i = 1;
+    p = (int*)0x100000000UL + i;
+    i = ((long)p) >> 32;
+    printf("largeptr: %p %d\n", p, i);
+#endif
+}
+
+void expr_cmp_test()
+{
+    int a, b;
+    printf("constant_expr:\n");
+    a = -1;
+    b = 1;
+    printf("%d\n", a == a);
+    printf("%d\n", a != a);
+
+    printf("%d\n", a < b);
+    printf("%d\n", a <= b);
+    printf("%d\n", a <= a);
+    printf("%d\n", b >= a);
+    printf("%d\n", a >= a);
+    printf("%d\n", b > a);
+
+    printf("%d\n", (unsigned)a < b);
+    printf("%d\n", (unsigned)a <= b);
+    printf("%d\n", (unsigned)a <= a);
+    printf("%d\n", (unsigned)b >= a);
+    printf("%d\n", (unsigned)a >= a);
+    printf("%d\n", (unsigned)b > a);
+}
+
+struct empty {
+};
+
+struct aligntest1 {
+    char a[10];
+};
+
+struct aligntest2 {
+    int a;
+    char b[10];
+};
+
+struct aligntest3 {
+    double a, b;
+};
+
+struct aligntest4 {
+    double a[0];
+};
+
+struct __attribute__((aligned(16))) aligntest5
+{
+    int i;
+};
+struct aligntest6
+{
+    int i;
+} __attribute__((aligned(16)));
+struct aligntest7
+{
+    int i;
+};
+struct aligntest5 altest5[2];
+struct aligntest6 altest6[2];
+int pad1;
+/* altest7 is correctly aligned to 16 bytes also with TCC,
+   but __alignof__ returns the wrong result (4) because we
+   can't store the alignment yet when specified on symbols
+   directly (it's stored in the type so we'd need to make
+   a copy of it). -- FIXED */
+struct aligntest7 altest7[2] __attribute__((aligned(16)));
+
+struct aligntest8
+{
+  int i;
+} __attribute__((aligned(4096)));
+
+struct Large {
+    unsigned long flags;
+    union {
+	void *u1;
+	int *u2;
+    };
+
+    struct {
+	union {
+	    unsigned long index;
+	    void *freelist;
+	};
+	union {
+	    unsigned long counters;
+	    struct {
+		int bla;
+	    };
+	};
+    };
+
+    union {
+	struct {
+	    long u3;
+	    long u4;
+	};
+	void *u5;
+	struct {
+	    unsigned long compound_head;
+	    unsigned int compound_dtor;
+	    unsigned int compound_order;
+	};
+    };
+} __attribute__((aligned(2 * sizeof(long))));
+
+typedef unsigned long long __attribute__((aligned(4))) unaligned_u64;
+
+struct aligntest9 {
+    unsigned int buf_nr;
+    unaligned_u64 start_lba;
+};
+
+struct aligntest10 {
+    unsigned int buf_nr;
+    unsigned long long start_lba;
+};
+
+void struct_test()
+{
+    struct1 *s;
+    union union2 u;
+    struct Large ls;
+
+    printf("struct:\n");
+    printf("sizes: %d %d %d %d\n",
+           sizeof(struct struct1),
+           sizeof(struct struct2),
+           sizeof(union union1),
+           sizeof(union union2));
+    printf("offsets: %d\n", (int)((char*)&st1.u.v1 - (char*)&st1));
+    st1.f1 = 1;
+    st1.f2 = 2;
+    st1.f3 = 3;
+    printf("st1: %d %d %d\n",
+           st1.f1, st1.f2, st1.f3);
+    st1.u.v1 = 1;
+    st1.u.v2 = 2;
+    printf("union1: %d\n", st1.u.v1);
+    u.w1 = 1;
+    u.w2 = 2;
+    printf("union2: %d\n", u.w1);
+    s = &st2;
+    s->f1 = 3;
+    s->f2 = 2;
+    s->f3 = 1;
+    printf("st2: %d %d %d\n",
+           s->f1, s->f2, s->f3);
+    printf("str_addr=%x\n", (int)st1.str - (int)&st1.f1);
+
+    /* align / size tests */
+    printf("aligntest1 sizeof=%d alignof=%d\n",
+           sizeof(struct aligntest1), __alignof__(struct aligntest1));
+    printf("aligntest2 sizeof=%d alignof=%d\n",
+           sizeof(struct aligntest2), __alignof__(struct aligntest2));
+    printf("aligntest3 sizeof=%d alignof=%d\n",
+           sizeof(struct aligntest3), __alignof__(struct aligntest3));
+    printf("aligntest4 sizeof=%d alignof=%d\n",
+           sizeof(struct aligntest4), __alignof__(struct aligntest4));
+    printf("aligntest5 sizeof=%d alignof=%d\n",
+           sizeof(struct aligntest5), __alignof__(struct aligntest5));
+    printf("aligntest6 sizeof=%d alignof=%d\n",
+           sizeof(struct aligntest6), __alignof__(struct aligntest6));
+    printf("aligntest7 sizeof=%d alignof=%d\n",
+           sizeof(struct aligntest7), __alignof__(struct aligntest7));
+    printf("aligntest8 sizeof=%d alignof=%d\n",
+           sizeof(struct aligntest8), __alignof__(struct aligntest8));
+    printf("aligntest9 sizeof=%d alignof=%d\n",
+           sizeof(struct aligntest9), __alignof__(struct aligntest9));
+    printf("aligntest10 sizeof=%d alignof=%d\n",
+           sizeof(struct aligntest10), __alignof__(struct aligntest10));
+    printf("altest5 sizeof=%d alignof=%d\n",
+           sizeof(altest5), __alignof__(altest5));
+    printf("altest6 sizeof=%d alignof=%d\n",
+           sizeof(altest6), __alignof__(altest6));
+    printf("altest7 sizeof=%d alignof=%d\n",
+           sizeof(altest7), __alignof__(altest7));
+           
+    /* empty structures (GCC extension) */
+    printf("sizeof(struct empty) = %d\n", sizeof(struct empty));
+    printf("alignof(struct empty) = %d\n", __alignof__(struct empty));
+
+    printf("Large: sizeof=%d\n", sizeof(ls));
+    memset(&ls, 0, sizeof(ls));
+    ls.compound_head = 42;
+    printf("Large: offsetof(compound_head)=%d\n", (int)((char*)&ls.compound_head - (char*)&ls));
+}
+
+/* XXX: depend on endianness */
+void char_short_test()
+{
+    int var1, var2;
+
+    printf("char_short:\n");
+
+    var1 = 0x01020304;
+    var2 = 0xfffefdfc;
+    printf("s8=%d %d\n", 
+           *(char *)&var1, *(char *)&var2);
+    printf("u8=%d %d\n", 
+           *(unsigned char *)&var1, *(unsigned char *)&var2);
+    printf("s16=%d %d\n", 
+           *(short *)&var1, *(short *)&var2);
+    printf("u16=%d %d\n", 
+           *(unsigned short *)&var1, *(unsigned short *)&var2);
+    printf("s32=%d %d\n", 
+           *(int *)&var1, *(int *)&var2);
+    printf("u32=%d %d\n", 
+           *(unsigned int *)&var1, *(unsigned int *)&var2);
+    *(char *)&var1 = 0x08;
+    printf("var1=%x\n", var1);
+    *(short *)&var1 = 0x0809;
+    printf("var1=%x\n", var1);
+    *(int *)&var1 = 0x08090a0b;
+    printf("var1=%x\n", var1);
+}
+
+/******************/
+
+typedef struct Sym {
+    int v;
+    int t;
+    int c;
+    struct Sym *next;
+    struct Sym *prev;
+} Sym;
+
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+
+static int toupper1(int a)
+{
+    return TOUPPER(a);
+}
+
+static unsigned int calc_vm_flags(unsigned int prot)
+{
+  unsigned int prot_bits;
+  /* This used to segfault in some revisions: */
+  prot_bits = ((0x1==0x00000001)?(prot&0x1):(prot&0x1)?0x00000001:0);
+  return prot_bits;
+}
+
+void bool_test()
+{
+    int *s, a, b, t, f, i;
+
+    a = 0;
+    s = (void*)0;
+    printf("!s=%d\n", !s);
+
+    if (!s || !s[0])
+        a = 1;
+    printf("a=%d\n", a);
+
+    printf("a=%d %d %d\n", 0 || 0, 0 || 1, 1 || 1);
+    printf("a=%d %d %d\n", 0 && 0, 0 && 1, 1 && 1);
+    printf("a=%d %d\n", 1 ? 1 : 0, 0 ? 1 : 0);
+#if 1 && 1
+    printf("a1\n");
+#endif
+#if 1 || 0
+    printf("a2\n");
+#endif
+#if 1 ? 0 : 1
+    printf("a3\n");
+#endif
+#if 0 ? 0 : 1
+    printf("a4\n");
+#endif
+
+    a = 4;
+    printf("b=%d\n", a + (0 ? 1 : a / 2));
+
+    /* test register spilling */
+    a = 10;
+    b = 10;
+    a = (a + b) * ((a < b) ?
+                   ((b - a) * (a - b)): a + b);
+    printf("a=%d\n", a);
+
+    /* test complex || or && expressions */
+    t = 1;
+    f = 0;
+    a = 32;
+    printf("exp=%d\n", f == (32 <= a && a <= 3));
+    printf("r=%d\n", (t || f) + (t && f));
+
+    /* test ? : cast */
+    {
+        int aspect_on;
+        int aspect_native = 65536;
+        double bfu_aspect = 1.0;
+        int aspect;
+        for(aspect_on = 0; aspect_on < 2; aspect_on++) {
+            aspect=aspect_on?(aspect_native*bfu_aspect+0.5):65535UL;
+            printf("aspect=%d\n", aspect);
+        }
+    }
+
+    /* test ? : GCC extension */
+    {
+        static int v1 = 34 ? : -1; /* constant case */
+        static int v2 = 0 ? : -1; /* constant case */
+        int a = 30;
+        
+        printf("%d %d\n", v1, v2);
+        printf("%d %d\n", a - 30 ? : a * 2, a + 1 ? : a * 2);
+    }
+
+    /* again complex expression */
+    for(i=0;i<256;i++) {
+        if (toupper1 (i) != TOUPPER (i))
+            printf("error %d\n", i);
+    }
+    printf ("bits = 0x%x\n", calc_vm_flags (0x1));
+}
+
+extern int undefined_function(void);
+extern int defined_function(void);
+
+static inline void refer_to_undefined(void)
+{
+  undefined_function();
+}
+
+void optimize_out(void)
+{
+  int i = 0 ? undefined_function() : defined_function();
+  printf ("oo:%d\n", i);
+  int j = 1 ? defined_function() : undefined_function();
+  printf ("oo:%d\n", j);
+  if (0)
+    printf("oo:%d\n", undefined_function());
+  else
+    printf("oo:%d\n", defined_function());
+  if (1)
+    printf("oo:%d\n", defined_function());
+  else
+    printf("oo:%d\n", undefined_function());
+  while (1) {
+      printf("oow:%d\n", defined_function());
+      break;
+      printf("oow:%d\n", undefined_function());
+  }
+  j = 1;
+  /* Following is a switch without {} block intentionally.  */
+  switch (j)
+    case 1: break;
+  printf ("oos:%d\n", defined_function());
+  /* The following break shouldn't lead to disabled code after
+     the while.  */
+  while (1)
+    break;
+  printf ("ool1:%d\n", defined_function());
+  /* Same for the other types of loops.  */
+  do
+    break;
+  while (1);
+  printf ("ool2:%d\n", defined_function());
+  for (;;)
+    break;
+  printf ("ool3:%d\n", defined_function());
+  /* Normal {} blocks without controlling statements
+     shouldn't reactivate code emission */
+  while (1) {
+	{
+	  break;
+	}
+      printf ("ool4:%d\n", undefined_function());
+  }
+  j = 1;
+  while (j) {
+      if (j == 0)
+	break; /* this break shouldn't disable code outside the if. */
+      printf("ool5:%d\n", defined_function());
+      j--;
+  }
+
+  j = 1;
+  while (j) {
+      if (1)
+	j--;
+      else
+	breakhere: break;
+      printf("ool6:%d\n", defined_function());
+      goto breakhere;
+  }
+
+  /* Test that constants in logical && are optimized: */
+  i = 0 && undefined_function();
+  i = defined_function() && 0 && undefined_function();
+  if (0 && undefined_function())
+    undefined_function();
+  if (defined_function() && 0)
+    undefined_function();
+  if (0 && 0)
+    undefined_function();
+  if (defined_function() && 0 && undefined_function())
+    undefined_function();
+  /* The same for || : */
+  i = 1 || undefined_function();
+  i = defined_function() || 1 || undefined_function();
+  if (1 || undefined_function())
+    ;
+  else
+    undefined_function();
+  if (defined_function() || 1)
+    ;
+  else
+    undefined_function();
+  if (1 || 1)
+    ;
+  else
+    undefined_function();
+  if (defined_function() || 1 || undefined_function())
+    ;
+  else
+    undefined_function();
+
+  if (defined_function() && 0)
+    refer_to_undefined();
+
+  if (0) {
+      (void)sizeof( ({
+		     do { } while (0);
+		     0;
+		     }) );
+      undefined_function();
+  }
+
+  /* Leave the "if(1)return; printf()" in this order and last in the function */
+  if (1)
+    return;
+  printf ("oor:%d\n", undefined_function());
+}
+
+int defined_function(void)
+{
+  static int i = 40;
+  return i++;
+}
+
+/* GCC accepts that */
+static int tab_reinit[];
+static int tab_reinit[10];
+
+//int cinit1; /* a global variable can be defined several times without error ! */
+int cinit1; 
+int cinit1; 
+int cinit1 = 0;
+int *cinit2 = (int []){3, 2, 1};
+
+void compound_literal_test(void)
+{
+    int *p, i;
+    char *q, *q3;
+
+    printf("compound_test:\n");
+
+    p = (int []){1, 2, 3};
+    for(i=0;i<3;i++)
+        printf(" %d", p[i]);
+    printf("\n");
+
+    for(i=0;i<3;i++)
+        printf("%d", cinit2[i]);
+    printf("\n");
+
+    q = "tralala1";
+    printf("q1=%s\n", q);
+
+    q = (char *){ "tralala2" };
+    printf("q2=%s\n", q);
+
+    q3 = (char *){ q };
+    printf("q3=%s\n", q3);
+
+    q = (char []){ "tralala3" };
+    printf("q4=%s\n", q);
+
+#ifdef ALL_ISOC99
+    p = (int []){1, 2, cinit1 + 3};
+    for(i=0;i<3;i++)
+        printf(" %d", p[i]);
+    printf("\n");
+
+    for(i=0;i<3;i++) {
+        p = (int []){1, 2, 4 + i};
+        printf("%d %d %d\n", 
+               p[0],
+               p[1],
+               p[2]);
+    }
+#endif
+}
+
+/* K & R protos */
+
+kr_func1(a, b)
+{
+    return a + b;
+}
+
+int kr_func2(a, b)
+{
+    return a + b;
+}
+
+kr_test()
+{
+    printf("kr_test:\n");
+    printf("func1=%d\n", kr_func1(3, 4));
+    printf("func2=%d\n", kr_func2(3, 4));
+    return 0;
+}
+
+void num(int n)
+{
+    char *tab, *p;
+    tab = (char*)malloc(20); 
+    p = tab;
+    while (1) {
+        *p = 48 + (n % 10);
+        p++;
+        n = n / 10;
+        if (n == 0)
+            break;
+    }
+    while (p != tab) {
+        p--;
+        printf("%c", *p);
+    }
+    printf("\n");
+    free(tab);
+}
+
+/* structure assignment tests */
+struct structa1 {
+    int f1;
+    char f2;
+};
+
+struct structa1 ssta1;
+
+void struct_assign_test1(struct structa1 s1, int t, float f)
+{
+    printf("%d %d %d %f\n", s1.f1, s1.f2, t, f);
+}
+
+struct structa1 struct_assign_test2(struct structa1 s1, int t)
+{
+    s1.f1 += t;
+    s1.f2 -= t;
+    return s1;
+}
+
+void struct_assign_test(void)
+{
+    struct S {
+      struct structa1 lsta1, lsta2;
+      int i;
+    } s, *ps;
+    
+    ps = &s;
+    ps->i = 4;
+#if 0
+    printf("struct_assign_test:\n");
+
+    s.lsta1.f1 = 1;
+    s.lsta1.f2 = 2;
+    printf("%d %d\n", s.lsta1.f1, s.lsta1.f2);
+    s.lsta2 = s.lsta1;
+    printf("%d %d\n", s.lsta2.f1, s.lsta2.f2);
+#else
+    s.lsta2.f1 = 1;
+    s.lsta2.f2 = 2;
+#endif
+    struct_assign_test1(ps->lsta2, 3, 4.5);
+    
+    printf("before call: %d %d\n", s.lsta2.f1, s.lsta2.f2);
+    ps->lsta2 = struct_assign_test2(ps->lsta2, ps->i);
+    printf("after call: %d %d\n", ps->lsta2.f1, ps->lsta2.f2);
+
+    static struct {
+        void (*elem)();
+    } t[] = {
+        /* XXX: we should allow this even without braces */
+        { struct_assign_test }
+    };
+    printf("%d\n", struct_assign_test == t[0].elem);
+}
+
+/* casts to short/char */
+
+void cast1(char a, short b, unsigned char c, unsigned short d)
+{
+    printf("%d %d %d %d\n", a, b, c, d);
+}
+
+char bcast;
+short scast;
+
+void cast_test()
+{
+    int a;
+    char c;
+    char tab[10];
+    unsigned b,d;
+    short s;
+    char *p = NULL;
+    p -= 0x700000000042;
+
+    printf("cast_test:\n");
+    a = 0xfffff;
+    cast1(a, a, a, a);
+    a = 0xffffe;
+    printf("%d %d %d %d\n",
+           (char)(a + 1),
+           (short)(a + 1),
+           (unsigned char)(a + 1),
+           (unsigned short)(a + 1));
+    printf("%d %d %d %d\n",
+           (char)0xfffff,
+           (short)0xfffff,
+           (unsigned char)0xfffff,
+           (unsigned short)0xfffff);
+
+    a = (bcast = 128) + 1;
+    printf("%d\n", a);
+    a = (scast = 65536) + 1;
+    printf("%d\n", a);
+    
+    printf("sizeof(c) = %d, sizeof((int)c) = %d\n", sizeof(c), sizeof((int)c));
+    
+    /* test cast from unsigned to signed short to int */
+    b = 0xf000;
+    d = (short)b;
+    printf("((unsigned)(short)0x%08x) = 0x%08x\n", b, d);
+    b = 0xf0f0;
+    d = (char)b;
+    printf("((unsigned)(char)0x%08x) = 0x%08x\n", b, d);
+    
+    /* test implicit int casting for array accesses */
+    c = 0;
+    tab[1] = 2;
+    tab[c] = 1;
+    printf("%d %d\n", tab[0], tab[1]);
+
+    /* test implicit casting on some operators */
+    printf("sizeof(+(char)'a') = %d\n", sizeof(+(char)'a'));
+    printf("sizeof(-(char)'a') = %d\n", sizeof(-(char)'a'));
+    printf("sizeof(~(char)'a') = %d\n", sizeof(-(char)'a'));
+
+    /* from pointer to integer types */
+    printf("%d %d %ld %ld %lld %lld\n",
+           (int)p, (unsigned int)p,
+           (long)p, (unsigned long)p,
+           (long long)p, (unsigned long long)p);
+
+    /* from integers to pointers */
+    printf("%p %p %p %p\n",
+           (void *)a, (void *)b, (void *)c, (void *)d);
+}
+
+/* initializers tests */
+struct structinit1 {
+    int f1;
+    char f2;
+    short f3;
+    int farray[3];
+};
+
+int sinit1 = 2;
+int sinit2 = { 3 };
+int sinit3[3] = { 1, 2, {{3}}, };
+int sinit4[3][2] = { {1, 2}, {3, 4}, {5, 6} };
+int sinit5[3][2] = { 1, 2, 3, 4, 5, 6 };
+int sinit6[] = { 1, 2, 3 };
+int sinit7[] = { [2] = 3, [0] = 1, 2 };
+char sinit8[] = "hello" "trala";
+
+struct structinit1 sinit9 = { 1, 2, 3 };
+struct structinit1 sinit10 = { .f2 = 2, 3, .f1 = 1 };
+struct structinit1 sinit11 = { .f2 = 2, 3, .f1 = 1, 
+#ifdef ALL_ISOC99
+                               .farray[0] = 10,
+                               .farray[1] = 11,
+                               .farray[2] = 12,
+#endif
+};
+
+char *sinit12 = "hello world";
+char *sinit13[] = {
+    "test1",
+    "test2",
+    "test3",
+};
+char sinit14[10] = { "abc" };
+int sinit15[3] = { sizeof(sinit15), 1, 2 };
+
+struct { int a[3], b; } sinit16[] = { { 1 }, 2 };
+
+struct bar {
+        char *s;
+        int len;
+} sinit17[] = {
+        "a1", 4,
+        "a2", 1
+};
+
+int sinit18[10] = {
+    [2 ... 5] = 20,
+    2,
+    [8] = 10,
+};
+
+struct complexinit0 {
+    int a;
+    int b;
+};
+
+struct complexinit {
+    int a;
+    const struct complexinit0 *b;
+};
+
+const static struct complexinit cix[] = {
+    [0] = {
+	.a = 2000,
+	.b = (const struct complexinit0[]) {
+		{ 2001, 2002 },
+		{ 2003, 2003 },
+		{}
+	}
+    }
+};
+
+struct complexinit2 {
+	int a;
+	int b[];
+};
+
+struct complexinit2 cix20;
+
+struct complexinit2 cix21 = {
+	.a = 3000,
+	.b = { 3001, 3002, 3003 }
+};
+
+struct complexinit2 cix22 = {
+	.a = 4000,
+	.b = { 4001, 4002, 4003, 4004, 4005, 4006 }
+};
+
+typedef int arrtype1[];
+arrtype1 sinit19 = {1};
+arrtype1 sinit20 = {2,3};
+typedef int arrtype2[3];
+arrtype2 sinit21 = {4};
+arrtype2 sinit22 = {5,6,7};
+
+/* Address comparisons of non-weak symbols with zero can be const-folded */
+int sinit23[2] = { "astring" ? sizeof("astring") : -1,
+		   &sinit23 ? 42 : -1 };
+
+extern int external_inited = 42;
+
+void init_test(void)
+{
+    int linit1 = 2;
+    int linit2 = { 3 };
+    int linit4[3][2] = { {1, 2}, {3, 4}, {5, 6} };
+    int linit6[] = { 1, 2, 3 };
+    int i, j;
+    char linit8[] = "hello" "trala";
+    int linit12[10] = { 1, 2 };
+    int linit13[10] = { 1, 2, [7] = 3, [3] = 4, };
+    char linit14[10] = "abc";
+    int linit15[10] = { linit1, linit1 + 1, [6] = linit1 + 2, };
+    struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 };
+    int linit17 = sizeof(linit17);
+    int zero = 0;
+    /* Addresses on non-weak symbols are non-zero, but not the access itself */
+    int linit18[2] = {&zero ? 1 : -1, zero ? -1 : 1 };
+    
+    printf("init_test:\n");
+
+    printf("sinit1=%d\n", sinit1);
+    printf("sinit2=%d\n", sinit2);
+    printf("sinit3=%d %d %d %d\n", 
+           sizeof(sinit3),
+           sinit3[0],
+           sinit3[1],
+           sinit3[2]
+           );
+    printf("sinit6=%d\n", sizeof(sinit6));
+    printf("sinit7=%d %d %d %d\n", 
+           sizeof(sinit7),
+           sinit7[0],
+           sinit7[1],
+           sinit7[2]
+           );
+    printf("sinit8=%s\n", sinit8);
+    printf("sinit9=%d %d %d\n", 
+           sinit9.f1,
+           sinit9.f2,
+           sinit9.f3
+           );
+    printf("sinit10=%d %d %d\n", 
+           sinit10.f1,
+           sinit10.f2,
+           sinit10.f3
+           );
+    printf("sinit11=%d %d %d %d %d %d\n", 
+           sinit11.f1,
+           sinit11.f2,
+           sinit11.f3,
+           sinit11.farray[0],
+           sinit11.farray[1],
+           sinit11.farray[2]
+           );
+
+    for(i=0;i<3;i++)
+        for(j=0;j<2;j++)
+            printf("[%d][%d] = %d %d %d\n", 
+                   i, j, sinit4[i][j], sinit5[i][j], linit4[i][j]);
+    printf("linit1=%d\n", linit1);
+    printf("linit2=%d\n", linit2);
+    printf("linit6=%d\n", sizeof(linit6));
+    printf("linit8=%d %s\n", sizeof(linit8), linit8);
+
+    printf("sinit12=%s\n", sinit12);
+    printf("sinit13=%d %s %s %s\n",
+           sizeof(sinit13), 
+           sinit13[0],
+           sinit13[1],
+           sinit13[2]);
+    printf("sinit14=%s\n", sinit14);
+
+    for(i=0;i<10;i++) printf(" %d", linit12[i]);
+    printf("\n");
+    for(i=0;i<10;i++) printf(" %d", linit13[i]);
+    printf("\n");
+    for(i=0;i<10;i++) printf(" %d", linit14[i]);
+    printf("\n");
+    for(i=0;i<10;i++) printf(" %d", linit15[i]);
+    printf("\n");
+    printf("%d %d %d %d\n", 
+           linit16.a1,
+           linit16.a2,
+           linit16.a3,
+           linit16.a4);
+    /* test that initialisation is done after variable declare */
+    printf("linit17=%d\n", linit17);
+    printf("sinit15=%d\n", sinit15[0]);
+    printf("sinit16=%d %d\n", sinit16[0].a[0], sinit16[1].a[0]);
+    printf("sinit17=%s %d %s %d\n",
+           sinit17[0].s, sinit17[0].len,
+           sinit17[1].s, sinit17[1].len);
+    for(i=0;i<10;i++)
+        printf("%x ", sinit18[i]);
+    printf("\n");
+    /* complex init check */
+    printf("cix: %d %d %d %d %d %d %d\n",
+	cix[0].a,
+	cix[0].b[0].a, cix[0].b[0].b,
+	cix[0].b[1].a, cix[0].b[1].b,
+	cix[0].b[2].a, cix[0].b[2].b);
+    printf("cix2: %d %d\n", cix21.b[2], cix22.b[5]);
+    printf("sizeof cix20 %d, cix21 %d, sizeof cix22 %d\n", sizeof cix20, sizeof cix21, sizeof cix22);
+
+    printf("arrtype1: %d %d %d\n", sinit19[0], sinit20[0], sinit20[1]);
+    printf("arrtype2: %d %d\n", sizeof(sinit19), sizeof(sinit20));
+    printf("arrtype3: %d %d %d\n", sinit21[0], sinit21[1], sinit21[2]);
+    printf("arrtype4: %d %d %d\n", sinit22[0], sinit22[1], sinit22[2]);
+    printf("arrtype5: %d %d\n", sizeof(sinit21), sizeof(sinit22));
+    printf("arrtype6: %d\n", sizeof(arrtype2));
+
+    printf("sinit23= %d %d\n", sinit23[0], sinit23[1]);
+    printf("linit18= %d %d\n", linit18[0], linit18[1]);
+}
+
+void switch_uc(unsigned char uc)
+{
+	switch (uc) {
+	    case 0xfb ... 0xfe:
+		printf("ucsw:1\n");
+		break;
+	    case 0xff:
+		printf("ucsw:2\n");
+		break;
+	    case 0 ... 5:
+		printf("ucsw:3\n");
+		break;
+	    default:
+		printf("ucsw: broken!\n");
+	}
+}
+
+void switch_sc(signed char sc)
+{
+	switch (sc) {
+	    case -5 ... -2:
+		printf("scsw:1\n");
+		break;
+	    case -1:
+		printf("scsw:2\n");
+		break;
+	    case 0 ... 5:
+		printf("scsw:3\n");
+		break;
+	    default:
+		printf("scsw: broken!\n");
+	}
+}
+
+void switch_test()
+{
+    int i;
+    unsigned long long ull;
+    long long ll;
+
+    for(i=0;i<15;i++) {
+        switch(i) {
+        case 0:
+        case 1:
+            printf("a");
+            break;
+        default:
+            printf("%d", i);
+            break;
+        case 8 ... 12:
+            printf("c");
+            break;
+        case 3:
+            printf("b");
+            break;
+        case 0xc33c6b9fU:
+        case 0x7c9eeeb9U:
+            break;
+        }
+    }
+    printf("\n");
+
+    for (i = 1; i <= 5; i++) {
+	ull = (unsigned long long)i << 61;
+	switch (ull) {
+	    case 1ULL << 61:
+		printf("ullsw:1\n");
+		break;
+	    case 2ULL << 61:
+		printf("ullsw:2\n");
+		break;
+	    case 3ULL << 61:
+		printf("ullsw:3\n");
+		break;
+	    case 4ULL << 61:
+		printf("ullsw:4\n");
+		break;
+	    case 5ULL << 61:
+		printf("ullsw:5\n");
+		break;
+	    default:
+		printf("ullsw: broken!\n");
+	}
+    }
+
+    for (i = 1; i <= 5; i++) {
+	ll = (long long)i << 61;
+	switch (ll) {
+	    case 1LL << 61:
+		printf("llsw:1\n");
+		break;
+	    case 2LL << 61:
+		printf("llsw:2\n");
+		break;
+	    case 3LL << 61:
+		printf("llsw:3\n");
+		break;
+	    case 4LL << 61:
+		printf("llsw:4\n");
+		break;
+	    case 5LL << 61:
+		printf("llsw:5\n");
+		break;
+	    default:
+		printf("llsw: broken!\n");
+	}
+    }
+
+    for (i = -5; i <= 5; i++) {
+	switch_uc((unsigned char)i);
+    }
+
+    for (i = -5; i <= 5; i++) {
+	switch_sc ((signed char)i);
+    }
+}
+
+/* ISOC99 _Bool type */
+void c99_bool_test(void)
+{
+#ifdef BOOL_ISOC99
+    int a;
+    _Bool b;
+
+    printf("bool_test:\n");
+    printf("sizeof(_Bool) = %d\n", sizeof(_Bool));
+    a = 3;
+    printf("cast: %d %d %d\n", (_Bool)10, (_Bool)0, (_Bool)a);
+    b = 3;
+    printf("b = %d\n", b);
+    b++;
+    printf("b = %d\n", b);
+#endif
+}
+
+void bitfield_test(void)
+{
+    int a;
+    short sa;
+    unsigned char ca;
+    struct sbf1 {
+        int f1 : 3;
+        int : 2;
+        int f2 : 1;
+        int : 0;
+        int f3 : 5;
+        int f4 : 7;
+        unsigned int f5 : 7;
+    } st1;
+    printf("bitfield_test:");
+    printf("sizeof(st1) = %d\n", sizeof(st1));
+
+    st1.f1 = 3;
+    st1.f2 = 1;
+    st1.f3 = 15;
+    a = 120;
+    st1.f4 = a;
+    st1.f5 = a;
+    st1.f5++;
+    printf("%d %d %d %d %d\n",
+           st1.f1, st1.f2, st1.f3, st1.f4, st1.f5);
+    sa = st1.f5;
+    ca = st1.f5;
+    printf("%d %d\n", sa, ca);
+
+    st1.f1 = 7;
+    if (st1.f1 == -1) 
+        printf("st1.f1 == -1\n");
+    else 
+        printf("st1.f1 != -1\n");
+    if (st1.f2 == -1) 
+        printf("st1.f2 == -1\n");
+    else 
+        printf("st1.f2 != -1\n");
+
+    struct sbf2 {
+        long long f1 : 45;
+        long long : 2;
+        long long f2 : 35;
+        unsigned long long f3 : 38;
+    } st2;
+    st2.f1 = 0x123456789ULL;
+    a = 120;
+    st2.f2 = (long long)a << 25;
+    st2.f3 = a;
+    st2.f2++;
+    printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3);
+
+#if 0
+    Disabled for now until further clarification re GCC compatibility
+    struct sbf3 {
+        int f1 : 7;
+        int f2 : 1;
+        char f3;
+        int f4 : 8;
+        int f5 : 1;
+        int f6 : 16;
+    } st3;
+    printf("sizeof(st3) = %d\n", sizeof(st3));
+#endif
+
+    struct sbf4 {
+	int x : 31;
+	char y : 2;
+    } st4;
+    st4.y = 1;
+    printf("st4.y == %d\n", st4.y);
+    struct sbf5 {
+	int a;
+	char b;
+	int x : 12, y : 4, : 0, : 4, z : 3;
+	char c;
+    } st5 = { 1, 2, 3, 4, -3, 6 };
+    printf("st5 = %d %d %d %d %d %d\n", st5.a, st5.b, st5.x, st5.y, st5.z, st5.c);
+    struct sbf6 {
+	short x : 12;
+	unsigned char y : 2;
+    } st6;
+    st6.y = 1;
+    printf("st6.y == %d\n", st6.y);
+}
+
+#ifdef __x86_64__
+#define FLOAT_FMT "%f\n"
+#else
+/* x86's float isn't compatible with GCC */
+#define FLOAT_FMT "%.5f\n"
+#endif
+
+/* declare strto* functions as they are C99 */
+double strtod(const char *nptr, char **endptr);
+
+#if defined(_WIN32)
+float strtof(const char *nptr, char **endptr) {return (float)strtod(nptr, endptr);}
+LONG_DOUBLE strtold(const char *nptr, char **endptr) {return (LONG_DOUBLE)strtod(nptr, endptr);}
+#else
+float strtof(const char *nptr, char **endptr);
+LONG_DOUBLE strtold(const char *nptr, char **endptr);
+#endif
+
+#define FTEST(prefix, typename, type, fmt)\
+void prefix ## cmp(type a, type b)\
+{\
+    printf("%d %d %d %d %d %d\n",\
+           a == b,\
+           a != b,\
+           a < b,\
+           a > b,\
+           a >= b,\
+           a <= b);\
+    printf(fmt " " fmt " " fmt " " fmt " " fmt " " fmt " " fmt "\n",\
+           a,\
+           b,\
+           a + b,\
+           a - b,\
+           a * b,\
+           a / b,\
+           -a);\
+    printf(fmt "\n", ++a);\
+    printf(fmt "\n", a++);\
+    printf(fmt "\n", a);\
+    b = 0;\
+    printf("%d %d\n", !a, !b);\
+}\
+void prefix ## fcast(type a)\
+{\
+    float fa;\
+    double da;\
+    LONG_DOUBLE la;\
+    int ia;\
+    long long llia;\
+    unsigned int ua;\
+    unsigned long long llua;\
+    type b;\
+    fa = a;\
+    da = a;\
+    la = a;\
+    printf("ftof: %f %f %Lf\n", fa, da, la);\
+    ia = (int)a;\
+    llia = (long long)a;\
+    a = (a >= 0) ? a : -a;\
+    ua = (unsigned int)a;\
+    llua = (unsigned long long)a;\
+    printf("ftoi: %d %u %lld %llu\n", ia, ua, llia, llua);\
+    ia = -1234;\
+    ua = 0x81234500;\
+    llia = -0x123456789012345LL;\
+    llua = 0xf123456789012345LLU;\
+    b = ia;\
+    printf("itof: " fmt "\n", b);\
+    b = ua;\
+    printf("utof: " fmt "\n", b);\
+    b = llia;\
+    printf("lltof: " fmt "\n", b);\
+    b = llua;\
+    printf("ulltof: " fmt "\n", b);\
+}\
+\
+float prefix ## retf(type a) { return a; }\
+double prefix ## retd(type a) { return a; }\
+LONG_DOUBLE prefix ## retld(type a) { return a; }\
+\
+void prefix ## call(void)\
+{\
+    printf("float: " FLOAT_FMT, prefix ## retf(42.123456789));\
+    printf("double: %f\n", prefix ## retd(42.123456789));\
+    printf("long double: %Lf\n", prefix ## retld(42.123456789));\
+    printf("strto%s: %f\n", #prefix, (double)strto ## prefix("1.2", NULL));\
+}\
+\
+void prefix ## signed_zeros(void) \
+{\
+  type x = 0.0, y = -0.0, n, p;\
+  if (x == y)\
+    printf ("Test 1.0 / x != 1.0 / y  returns %d (should be 1).\n",\
+            1.0 / x != 1.0 / y);\
+  else\
+    printf ("x != y; this is wrong!\n");\
+\
+  n = -x;\
+  if (x == n)\
+    printf ("Test 1.0 / x != 1.0 / -x returns %d (should be 1).\n",\
+            1.0 / x != 1.0 / n);\
+  else\
+    printf ("x != -x; this is wrong!\n");\
+\
+  p = +y;\
+  if (x == p)\
+    printf ("Test 1.0 / x != 1.0 / +y returns %d (should be 1).\n",\
+            1.0 / x != 1.0 / p);\
+  else\
+    printf ("x != +y; this is wrong!\n");\
+  p = -y;\
+  if (x == p)\
+    printf ("Test 1.0 / x != 1.0 / -y returns %d (should be 0).\n",\
+            1.0 / x != 1.0 / p);\
+  else\
+    printf ("x != -y; this is wrong!\n");\
+}\
+void prefix ## test(void)\
+{\
+    printf("testing '%s'\n", #typename);\
+    prefix ## cmp(1, 2.5);\
+    prefix ## cmp(2, 1.5);\
+    prefix ## cmp(1, 1);\
+    prefix ## fcast(234.6);\
+    prefix ## fcast(-2334.6);\
+    prefix ## call();\
+    prefix ## signed_zeros();\
+}
+
+FTEST(f, float, float, "%f")
+FTEST(d, double, double, "%f")
+FTEST(ld, long double, LONG_DOUBLE, "%Lf")
+
+double ftab1[3] = { 1.2, 3.4, -5.6 };
+
+
+void float_test(void)
+{
+#if !defined(__arm__) || defined(__ARM_PCS_VFP)
+    float fa, fb;
+    double da, db;
+    int a;
+    unsigned int b;
+
+    printf("float_test:\n");
+    printf("sizeof(float) = %d\n", sizeof(float));
+    printf("sizeof(double) = %d\n", sizeof(double));
+    printf("sizeof(long double) = %d\n", sizeof(LONG_DOUBLE));
+    ftest();
+    dtest();
+    ldtest();
+    printf("%f %f %f\n", ftab1[0], ftab1[1], ftab1[2]);
+    printf("%f %f %f\n", 2.12, .5, 2.3e10);
+    //    printf("%f %f %f\n", 0x1234p12, 0x1e23.23p10, 0x12dp-10);
+    da = 123;
+    printf("da=%f\n", da);
+    fa = 123;
+    printf("fa=%f\n", fa);
+    a = 4000000000;
+    da = a;
+    printf("da = %f\n", da);
+    b = 4000000000;
+    db = b;
+    printf("db = %f\n", db);
+#endif
+}
+
+int fib(int n)
+{
+    if (n <= 2)
+        return 1;
+    else
+        return fib(n-1) + fib(n-2);
+}
+
+void funcptr_test()
+{
+    void (*func)(int);
+    int a;
+    struct {
+        int dummy;
+        void (*func)(int);
+    } st1;
+    long diff;
+
+    printf("funcptr:\n");
+    func = &num;
+    (*func)(12345);
+    func = num;
+    a = 1;
+    a = 1;
+    func(12345);
+    /* more complicated pointer computation */
+    st1.func = num;
+    st1.func(12346);
+    printf("sizeof1 = %d\n", sizeof(funcptr_test));
+    printf("sizeof2 = %d\n", sizeof funcptr_test);
+    printf("sizeof3 = %d\n", sizeof(&funcptr_test));
+    printf("sizeof4 = %d\n", sizeof &funcptr_test);
+    a = 0;
+    func = num + a;
+    diff = func - num;
+    func(42);
+    (func + diff)(42);
+    (num + a)(43);
+}
+
+void lloptest(long long a, long long b)
+{
+    unsigned long long ua, ub;
+
+    ua = a;
+    ub = b;
+    /* arith */
+    printf("arith: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
+           a + b,
+           a - b,
+           a * b);
+    
+    if (b != 0) {
+        printf("arith1: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
+           a / b,
+           a % b);
+    }
+
+    /* binary */
+    printf("bin: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
+           a & b,
+           a | b,
+           a ^ b);
+
+    /* tests */
+    printf("test: %d %d %d %d %d %d\n",
+           a == b,
+           a != b,
+           a < b,
+           a > b,
+           a >= b,
+           a <= b);
+    
+    printf("utest: %d %d %d %d %d %d\n",
+           ua == ub,
+           ua != ub,
+           ua < ub,
+           ua > ub,
+           ua >= ub,
+           ua <= ub);
+
+    /* arith2 */
+    a++;
+    b++;
+    printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
+    printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a++, b++);
+    printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", --a, --b);
+    printf("arith2: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
+    b = ub = 0;
+    printf("not: %d %d %d %d\n", !a, !ua, !b, !ub);
+}
+
+void llshift(long long a, int b)
+{
+    printf("shift: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
+           (unsigned long long)a >> b,
+           a >> b,
+           a << b);
+    printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
+           (unsigned long long)a >> 3,
+           a >> 3,
+           a << 3);
+    printf("shiftc: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
+           (unsigned long long)a >> 35,
+           a >> 35,
+           a << 35);
+}
+
+void llfloat(void)
+{
+    float fa;
+    double da;
+    LONG_DOUBLE lda;
+    long long la, lb, lc;
+    unsigned long long ula, ulb, ulc;
+    la = 0x12345678;
+    ula = 0x72345678;
+    la = (la << 20) | 0x12345;
+    ula = ula << 33;
+    printf("la=" LONG_LONG_FORMAT " ula=" ULONG_LONG_FORMAT "\n", la, ula);
+
+    fa = la;
+    da = la;
+    lda = la;
+    printf("lltof: %f %f %Lf\n", fa, da, lda);
+
+    la = fa;
+    lb = da;
+    lc = lda;
+    printf("ftoll: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", la, lb, lc);
+
+    fa = ula;
+    da = ula;
+    lda = ula;
+    printf("ulltof: %f %f %Lf\n", fa, da, lda);
+
+    ula = fa;
+    ulb = da;
+    ulc = lda;
+    printf("ftoull: " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT " " ULONG_LONG_FORMAT "\n", ula, ulb, ulc);
+}
+
+long long llfunc1(int a)
+{
+    return a * 2;
+}
+
+struct S {
+    int id; 
+    char item;
+};
+
+long long int value(struct S *v)
+{
+    return ((long long int)v->item);
+}
+
+long long llfunc2(long long x, long long y, int z)
+{
+    return x * y * z;
+}
+
+void longlong_test(void)
+{
+    long long a, b, c;
+    int ia;
+    unsigned int ua;
+    printf("longlong_test:\n");
+    printf("sizeof(long long) = %d\n", sizeof(long long));
+    ia = -1;
+    ua = -2;
+    a = ia;
+    b = ua;
+    printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
+    printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %Lx\n", 
+           (long long)1, 
+           (long long)-2,
+           1LL,
+           0x1234567812345679);
+    a = llfunc1(-3);
+    printf(LONG_LONG_FORMAT "\n", a);
+
+    lloptest(1000, 23);
+    lloptest(0xff, 0x1234);
+    b = 0x72345678 << 10;
+    lloptest(-3, b);
+    llshift(0x123, 5);
+    llshift(-23, 5);
+    b = 0x72345678LL << 10;
+    llshift(b, 47);
+
+    llfloat();
+#if 1
+    b = 0x12345678;
+    a = -1;
+    c = a + b;
+    printf("%Lx\n", c);
+#endif
+
+    /* long long reg spill test */
+    {
+          struct S a;
+
+          a.item = 3;
+          printf("%lld\n", value(&a));
+    }
+    lloptest(0x80000000, 0);
+
+    {
+        long long *p, v, **pp;
+        v = 1;
+        p = &v;
+        p[0]++;
+        printf("another long long spill test : %lld\n", *p);
+        pp = &p;
+
+        v = llfunc2(**pp, **pp, ia);
+        printf("a long long function (arm-)reg-args test : %lld\n", v);
+    }
+    a = 68719476720LL;
+    b = 4294967295LL;
+    printf("%d %d %d %d\n", a > b, a < b, a >= b, a <= b);
+
+    printf(LONG_LONG_FORMAT "\n", 0x123456789LLU);
+
+    /* long long pointer deref in argument passing test */
+    a = 0x123;
+    long long *p = &a;
+    llshift(*p, 5);
+}
+
+void manyarg_test(void)
+{
+    LONG_DOUBLE ld = 1234567891234LL;
+    printf("manyarg_test:\n");
+    printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n",
+           1, 2, 3, 4, 5, 6, 7, 8,
+           0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0);
+    printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+           LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n",
+           1, 2, 3, 4, 5, 6, 7, 8,
+           0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+           1234567891234LL, 987654321986LL,
+           42.0, 43.0);
+    printf("%Lf %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+           LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f\n",
+           ld, 1, 2, 3, 4, 5, 6, 7, 8,
+           0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+           1234567891234LL, 987654321986LL,
+           42.0, 43.0);
+    printf("%d %d %d %d %d %d %d %d %Lf\n",
+           1, 2, 3, 4, 5, 6, 7, 8, ld);
+    printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+           LONG_LONG_FORMAT " " LONG_LONG_FORMAT "%f %f %Lf\n",
+           1, 2, 3, 4, 5, 6, 7, 8,
+           0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+           1234567891234LL, 987654321986LL,
+           42.0, 43.0, ld);
+    printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+           "%Lf " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %f %f %Lf\n",
+           1, 2, 3, 4, 5, 6, 7, 8,
+           0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+           ld, 1234567891234LL, 987654321986LL,
+           42.0, 43.0, ld);
+}
+
+void vprintf1(const char *fmt, ...)
+{
+    va_list ap, aq;
+    const char *p;
+    int c, i;
+    double d;
+    long long ll;
+    LONG_DOUBLE ld;
+
+    va_start(aq, fmt);
+    va_copy(ap, aq);
+    
+    p = fmt;
+    for(;;) {
+        c = *p;
+        if (c == '\0')
+            break;
+        p++;
+        if (c == '%') {
+            c = *p;
+            switch(c) {
+            case '\0':
+                goto the_end;
+            case 'd':
+                i = va_arg(ap, int);
+                printf("%d", i);
+                break;
+            case 'f':
+                d = va_arg(ap, double);
+                printf("%f", d);
+                break;
+            case 'l':
+                ll = va_arg(ap, long long);
+                printf(LONG_LONG_FORMAT, ll);
+                break;
+            case 'F':
+                ld = va_arg(ap, LONG_DOUBLE);
+                printf("%Lf", ld);
+                break;
+            }
+            p++;
+        } else {
+            putchar(c);
+        }
+    }
+ the_end:
+    va_end(aq);
+    va_end(ap);
+}
+
+struct myspace {
+    short int profile;
+};
+
+void stdarg_for_struct(struct myspace bob, ...)
+{
+    struct myspace george, bill;
+    va_list ap;
+    short int validate;
+
+    va_start(ap, bob);
+    bill     = va_arg(ap, struct myspace);
+    george   = va_arg(ap, struct myspace);
+    validate = va_arg(ap, int);
+    printf("stdarg_for_struct: %d %d %d %d\n",
+           bob.profile, bill.profile, george.profile, validate);
+    va_end(ap);
+}
+
+void stdarg_for_libc(const char *fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+    vprintf(fmt, args);
+    va_end(args);
+}
+
+void stdarg_test(void)
+{
+    LONG_DOUBLE ld = 1234567891234LL;
+    struct myspace bob;
+
+    vprintf1("%d %d %d\n", 1, 2, 3);
+    vprintf1("%f %d %f\n", 1.0, 2, 3.0);
+    vprintf1("%l %l %d %f\n", 1234567891234LL, 987654321986LL, 3, 1234.0);
+    vprintf1("%F %F %F\n", LONG_DOUBLE_LITERAL(1.2), LONG_DOUBLE_LITERAL(2.3), LONG_DOUBLE_LITERAL(3.4));
+    vprintf1("%d %f %l %F %d %f %l %F\n",
+             1, 1.2, 3LL, LONG_DOUBLE_LITERAL(4.5), 6, 7.8, 9LL, LONG_DOUBLE_LITERAL(0.1));
+    vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f\n",
+             1, 2, 3, 4, 5, 6, 7, 8,
+             0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8);
+    vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n",
+             1, 2, 3, 4, 5, 6, 7, 8,
+             0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0);
+    vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+             "%l %l %f %f\n",
+             1, 2, 3, 4, 5, 6, 7, 8,
+             0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+             1234567891234LL, 987654321986LL,
+             42.0, 43.0);
+    vprintf1("%F %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+             "%l %l %f %f\n",
+             ld, 1, 2, 3, 4, 5, 6, 7, 8,
+             0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+             1234567891234LL, 987654321986LL,
+             42.0, 43.0);
+    vprintf1("%d %d %d %d %d %d %d %d %F\n",
+             1, 2, 3, 4, 5, 6, 7, 8, ld);
+    vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+             "%l %l %f %f %F\n",
+             1, 2, 3, 4, 5, 6, 7, 8,
+             0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+             1234567891234LL, 987654321986LL,
+             42.0, 43.0, ld);
+    vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f "
+             "%F %l %l %f %f %F\n",
+             1, 2, 3, 4, 5, 6, 7, 8,
+             0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0,
+             ld, 1234567891234LL, 987654321986LL,
+             42.0, 43.0, ld);
+
+    bob.profile = 42;
+    stdarg_for_struct(bob, bob, bob, bob.profile);
+    stdarg_for_libc("stdarg_for_libc: %s %.2f %d\n", "string", 1.23, 456);
+}
+
+void whitespace_test(void)
+{
+    char *str;
+
+
+
+
+#if 1
+    pri\
+ntf("whitspace:\n");
+
+
+#endif
+    pf("N=%d\n", 2);
+
+#ifdef CORRECT_CR_HANDLING
+    pri\
+ntf("aaa=%d\n", 3);
+#endif
+
+    pri\
+\
+ntf("min=%d\n", 4);
+
+#ifdef ACCEPT_CR_IN_STRINGS
+    printf("len1=%d\n", strlen("
+"));
+#ifdef CORRECT_CR_HANDLING
+    str = "
+";
+    printf("len1=%d str[0]=%d\n", strlen(str), str[0]);
+#endif
+    printf("len1=%d\n", strlen("
+a
+"));
+#endif /* ACCEPT_CR_IN_STRINGS */
+}
+
+int reltab[3] = { 1, 2, 3 };
+
+int *rel1 = &reltab[1];
+int *rel2 = &reltab[2];
+
+#ifdef _WIN64
+void relocation_test(void) {}
+#else
+void getmyaddress(void)
+{
+    printf("in getmyaddress\n");
+}
+
+#ifdef __LP64__
+long __pa_symbol(void)
+{
+    /* This 64bit constant was handled incorrectly, it was used as addend
+       (which can hold 64bit just fine) in connection with a symbol,
+       and TCC generates wrong code for that (displacements are 32bit only).
+       This effectively is "+ 0x80000000", and if addresses of globals
+       are below 2GB the result should be a number without high 32 bits set.  */
+       return ((long)(((unsigned long)(&rel1))) - (0xffffffff80000000UL));
+}
+#endif
+
+unsigned long theaddress = (unsigned long)getmyaddress;
+void relocation_test(void)
+{
+    void (*fptr)(void) = (void (*)(void))theaddress;
+    printf("*rel1=%d\n", *rel1);
+    printf("*rel2=%d\n", *rel2);
+    fptr();
+#ifdef __LP64__
+    printf("pa_symbol=0x%lx\n", __pa_symbol() >> 63);
+#endif
+}
+#endif
+
+void old_style_f(a,b,c)
+     int a, b;
+     double c;
+{
+    printf("a=%d b=%d b=%f\n", a, b, c);
+}
+
+void decl_func1(int cmpfn())
+{
+    printf("cmpfn=%lx\n", (long)cmpfn);
+}
+
+void decl_func2(cmpfn)
+int cmpfn();
+{
+    printf("cmpfn=%lx\n", (long)cmpfn);
+}
+
+void old_style_function(void)
+{
+    old_style_f((void *)1, 2, 3.0);
+    decl_func1(NULL);
+    decl_func2(NULL);
+}
+
+void alloca_test()
+{
+#if defined __i386__ || defined __x86_64__ || defined __arm__
+    char *p = alloca(16);
+    strcpy(p,"123456789012345");
+    printf("alloca: p is %s\n", p);
+    char *demo = "This is only a test.\n";
+    /* Test alloca embedded in a larger expression */
+    printf("alloca: %s\n", strcpy(alloca(strlen(demo)+1),demo) );
+#endif
+}
+
+void *bounds_checking_is_enabled()
+{
+    char ca[10], *cp = ca-1;
+    return (ca != cp + 1) ? cp : NULL;
+}
+
+typedef int constant_negative_array_size_as_compile_time_assertion_idiom[(1 ? 2 : 0) - 1];
+
+void c99_vla_test(int size1, int size2)
+{
+#if defined __i386__ || defined __x86_64__
+    int size = size1 * size2;
+    int tab1[size][2], tab2[10][2];
+    void *tab1_ptr, *tab2_ptr, *bad_ptr;
+
+    /* "size" should have been 'captured' at tab1 declaration, 
+        so modifying it should have no effect on VLA behaviour. */
+    size = size-1;
+    
+    printf("Test C99 VLA 1 (sizeof): ");
+    printf("%s\n", (sizeof tab1 == size1 * size2 * 2 * sizeof(int)) ? "PASSED" : "FAILED");
+    tab1_ptr = tab1;
+    tab2_ptr = tab2;
+    printf("Test C99 VLA 2 (ptrs subtract): ");
+    printf("%s\n", (tab2 - tab1 == (tab2_ptr - tab1_ptr) / (sizeof(int) * 2)) ? "PASSED" : "FAILED");
+    printf("Test C99 VLA 3 (ptr add): ");
+    printf("%s\n", &tab1[5][1] == (tab1_ptr + (5 * 2 + 1) * sizeof(int)) ? "PASSED" : "FAILED");
+    printf("Test C99 VLA 4 (ptr access): ");
+    tab1[size1][1] = 42;
+    printf("%s\n", (*((int *) (tab1_ptr + (size1 * 2 + 1) * sizeof(int))) == 42) ? "PASSED" : "FAILED");
+
+    printf("Test C99 VLA 5 (bounds checking (might be disabled)): ");
+    if (bad_ptr = bounds_checking_is_enabled()) {
+        int *t1 = &tab1[size1 * size2 - 1][3];
+        int *t2 = &tab2[9][3];
+        printf("%s ", bad_ptr == t1 ? "PASSED" : "FAILED");
+        printf("%s ", bad_ptr == t2 ? "PASSED" : "FAILED");
+
+        char*c1 = 1 + sizeof(tab1) + (char*)tab1;
+        char*c2 = 1 + sizeof(tab2) + (char*)tab2;
+        printf("%s ", bad_ptr == c1 ? "PASSED" : "FAILED");
+        printf("%s ", bad_ptr == c2 ? "PASSED" : "FAILED");
+
+        int *i1 = tab1[-1];
+        int *i2 = tab2[-1];
+        printf("%s ", bad_ptr == i1 ? "PASSED" : "FAILED");
+        printf("%s ", bad_ptr == i2 ? "PASSED" : "FAILED");
+
+        int *x1 = tab1[size1 * size2 + 1];
+        int *x2 = tab2[10 + 1];
+        printf("%s ", bad_ptr == x1 ? "PASSED" : "FAILED");
+        printf("%s ", bad_ptr == x2 ? "PASSED" : "FAILED");
+    } else {
+        printf("PASSED PASSED PASSED PASSED PASSED PASSED PASSED PASSED ");
+    }
+    printf("\n");
+#endif
+}
+
+#ifndef __TINYC__
+typedef __SIZE_TYPE__ uintptr_t;
+#endif
+
+void sizeof_test(void)
+{
+    int a;
+    int **ptr;
+
+    printf("sizeof(int) = %d\n", sizeof(int));
+    printf("sizeof(unsigned int) = %d\n", sizeof(unsigned int));
+    printf("sizeof(long) = %d\n", sizeof(long));
+    printf("sizeof(unsigned long) = %d\n", sizeof(unsigned long));
+    printf("sizeof(short) = %d\n", sizeof(short));
+    printf("sizeof(unsigned short) = %d\n", sizeof(unsigned short));
+    printf("sizeof(char) = %d\n", sizeof(char));
+    printf("sizeof(unsigned char) = %d\n", sizeof(unsigned char));
+    printf("sizeof(func) = %d\n", sizeof sizeof_test());
+    a = 1;
+    printf("sizeof(a++) = %d\n", sizeof a++);
+    printf("a=%d\n", a);
+    ptr = NULL;
+    printf("sizeof(**ptr) = %d\n", sizeof (**ptr));
+
+    /* The type of sizeof should be as large as a pointer, actually
+       it should be size_t.  */
+    printf("sizeof(sizeof(int) = %d\n", sizeof(sizeof(int)));
+    uintptr_t t = 1;
+    uintptr_t t2;
+    /* Effectively <<32, but defined also on 32bit machines.  */
+    t <<= 16;
+    t <<= 16;
+    t++;
+    /* This checks that sizeof really can be used to manipulate 
+       uintptr_t objects, without truncation.  */
+    t2 = t & -sizeof(uintptr_t);
+    printf ("%lu %lu\n", t, t2);
+
+    /* some alignof tests */
+    printf("__alignof__(int) = %d\n", __alignof__(int));
+    printf("__alignof__(unsigned int) = %d\n", __alignof__(unsigned int));
+    printf("__alignof__(short) = %d\n", __alignof__(short));
+    printf("__alignof__(unsigned short) = %d\n", __alignof__(unsigned short));
+    printf("__alignof__(char) = %d\n", __alignof__(char));
+    printf("__alignof__(unsigned char) = %d\n", __alignof__(unsigned char));
+    printf("__alignof__(func) = %d\n", __alignof__ sizeof_test());
+
+    /* sizes of VLAs need to be evaluated even inside sizeof: */
+    a = 2;
+    printf("sizeof(char[1+2*a]) = %d\n", sizeof(char[1+2*a]));
+    /* And checking if sizeof compound literal works.  Parenthesized: */
+    printf("sizeof( (struct {int i; int j;}){4,5} ) = %d\n",
+	   sizeof( (struct {int i; int j;}){4,5} ));
+    /* And as direct sizeof argument (as unary expression): */
+    printf("sizeof (struct {short i; short j;}){4,5} = %d\n",
+	   sizeof (struct {short i; short j;}){4,5} );
+
+    /* sizeof(x && y) should be sizeof(int), even if constant
+       evaluating is possible. */
+    printf("sizeof(t && 0) = %d\n", sizeof(t && 0));
+    printf("sizeof(1 && 1) = %d\n", sizeof(1 && 1));
+    printf("sizeof(t || 1) = %d\n", sizeof(t || 1));
+    printf("sizeof(0 || 0) = %d\n", sizeof(0 || 0));
+}
+
+void typeof_test(void)
+{
+    double a;
+    typeof(a) b;
+    typeof(float) c;
+
+    a = 1.5;
+    b = 2.5;
+    c = 3.5;
+    printf("a=%f b=%f c=%f\n", a, b, c);
+}
+
+
+struct hlist_node;
+struct hlist_head {
+    struct hlist_node *first, *last;
+};
+
+void consume_ulong (unsigned long i)
+{
+    i = 0;
+}
+
+void statement_expr_test(void)
+{
+    int a, i;
+
+    /* Basic stmt expr test */
+    a = 0;
+    for(i=0;i<10;i++) {
+        a += 1 + 
+            ( { int b, j; 
+                b = 0; 
+                for(j=0;j<5;j++) 
+                    b += j; b; 
+            } );
+    }
+    printf("a=%d\n", a);
+    
+    /* Test that symbols aren't freed prematurely.
+       With SYM_DEBUG valgrind will show a read from a freed
+       symbol, and tcc will show an (invalid) warning on the initialization
+       of 'ptr' below, if symbols are popped after the stmt expr.  */
+    void *v = (void*)39;
+    typeof(({
+	    (struct hlist_node *)v;
+	    })) x;
+    typeof (x)
+	ptr = (struct hlist_node *)v;
+
+    /* This part used to segfault when symbols were popped prematurely.
+       The symbols for the static local would be overwritten with
+       helper symbols from the pre-processor expansions in between.  */
+#define some_attr     __attribute__((aligned(1)))
+#define tps(str) ({                  \
+            static const char *t some_attr = str; \
+            t;                                    \
+          })
+    printf ("stmtexpr: %s %s\n",
+	    tps("somerandomlongstring"),
+	    tps("anotherlongstring"));
+
+    /* Test that the three decls of 't' don't interact.  */
+    int t = 40;
+    int b = ({ int t = 41; t; });
+    int c = ({ int t = 42; t; });
+
+    /* Test that aggregate return values work.  */
+    struct hlist_head h
+	= ({
+	   typedef struct hlist_head T;
+	   long pre = 48;
+	   T t = { (void*)43, (void*)44 };
+	   long post = 49;
+	   t;
+	   });
+    printf ("stmtexpr: %d %d %d\n", t, b, c);
+    printf ("stmtexpr: %ld %ld\n", (long)h.first, (long)h.last);
+
+    /* Test that we can give out addresses of local labels.  */
+    consume_ulong(({ __label__ __here; __here: (unsigned long)&&__here; }));
+}
+
+void local_label_test(void)
+{
+    int a;
+    goto l1;
+ l2:
+    a = 1 + ({
+        __label__ l1, l2, l3, l4;
+        goto l1;
+    l4:
+        printf("aa1\n");
+        goto l3;
+    l2:
+        printf("aa3\n");
+        goto l4;
+    l1:
+        printf("aa2\n");
+        goto l2;
+    l3:;
+        1;
+    });
+    printf("a=%d\n", a);
+    return;
+ l4:
+    printf("bb1\n");
+    goto l2;
+ l1:
+    printf("bb2\n");
+    goto l4;
+}
+
+/* inline assembler test */
+#if defined(__i386__) || defined(__x86_64__)
+
+/* from linux kernel */
+static char * strncat1(char * dest,const char * src,size_t count)
+{
+long d0, d1, d2, d3;
+__asm__ __volatile__(
+	"repne\n\t"
+	"scasb\n\t"
+	"dec %1\n\t"
+	"mov %8,%3\n"
+	"1:\tdec %3\n\t"
+	"js 2f\n\t"
+	"lodsb\n\t"
+	"stosb\n\t"
+	"testb %%al,%%al\n\t"
+	"jne 1b\n"
+	"2:\txor %2,%2\n\t"
+	"stosb"
+	: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
+	: "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
+	: "memory");
+return dest;
+}
+
+static char * strncat2(char * dest,const char * src,size_t count)
+{
+long d0, d1, d2, d3;
+__asm__ __volatile__(
+	"repne scasb\n\t" /* one-line repne prefix + string op */
+	"dec %1\n\t"
+	"mov %8,%3\n"
+	"1:\tdec %3\n\t"
+	"js 2f\n\t"
+	"lodsb\n\t"
+	"stosb\n\t"
+	"testb %%al,%%al\n\t"
+	"jne 1b\n"
+	"2:\txor %2,%2\n\t"
+	"stosb"
+	: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
+	: "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
+	: "memory");
+return dest;
+}
+
+static inline void * memcpy1(void * to, const void * from, size_t n)
+{
+long d0, d1, d2;
+__asm__ __volatile__(
+	"rep ; movsl\n\t"
+	"testb $2,%b4\n\t"
+	"je 1f\n\t"
+	"movsw\n"
+	"1:\ttestb $1,%b4\n\t"
+	"je 2f\n\t"
+	"movsb\n"
+	"2:"
+	: "=&c" (d0), "=&D" (d1), "=&S" (d2)
+	:"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+	: "memory");
+return (to);
+}
+
+static inline void * memcpy2(void * to, const void * from, size_t n)
+{
+long d0, d1, d2;
+__asm__ __volatile__(
+	"rep movsl\n\t"  /* one-line rep prefix + string op */
+	"testb $2,%b4\n\t"
+	"je 1f\n\t"
+	"movsw\n"
+	"1:\ttestb $1,%b4\n\t"
+	"je 2f\n\t"
+	"movsb\n"
+	"2:"
+	: "=&c" (d0), "=&D" (d1), "=&S" (d2)
+	:"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+	: "memory");
+return (to);
+}
+
+static __inline__ void sigaddset1(unsigned int *set, int _sig)
+{
+	__asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc");
+}
+
+static __inline__ void sigdelset1(unsigned int *set, int _sig)
+{
+	asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc", "flags");
+}
+
+static __inline__ __const__ unsigned int swab32(unsigned int x)
+{
+	__asm__("xchgb %b0,%h0\n\t"	/* swap lower bytes	*/
+		"rorl $16,%0\n\t"	/* swap words		*/
+		"xchgb %b0,%h0"		/* swap higher bytes	*/
+		:"=" "q" (x)
+		: "0" (x));
+	return x;
+}
+
+static __inline__ unsigned long long mul64(unsigned int a, unsigned int b)
+{
+    unsigned long long res;
+#ifdef __x86_64__
+    /* Using the A constraint is wrong (it means rdx:rax, which is too large)
+       but still test the 32bit->64bit mull.  */
+    unsigned int resh, resl;
+    __asm__("mull %2" : "=a" (resl), "=d" (resh) : "a" (a), "r" (b));
+    res = ((unsigned long long)resh << 32) | resl;
+#else
+    __asm__("mull %2" : "=A" (res) : "a" (a), "r" (b));
+#endif
+    return res;
+}
+
+static __inline__ unsigned long long inc64(unsigned long long a)
+{
+    unsigned long long res;
+#ifdef __x86_64__
+    /* Using the A constraint is wrong, and increments are tested
+       elsewhere.  */
+    res = a + 1;
+#else
+    __asm__("addl $1, %%eax ; adcl $0, %%edx" : "=A" (res) : "A" (a));
+#endif
+    return res;
+}
+
+struct struct123 {
+    int a;
+    int b;
+};
+struct struct1231 {
+    unsigned long addr;
+};
+
+unsigned long mconstraint_test(struct struct1231 *r)
+{
+    unsigned long ret;
+    unsigned int a[2];
+    a[0] = 0;
+    __asm__ volatile ("lea %2,%0; movl 4(%0),%k0; addl %2,%k0; movl $51,%2; movl $52,4%2; movl $63,%1"
+	             : "=&r" (ret), "=m" (a)
+	             : "m" (*(struct struct123 *)r->addr));
+    return ret + a[0];
+}
+
+#ifdef __x86_64__
+int fls64(unsigned long long x)
+{
+  int bitpos = -1;
+  asm("bsrq %1,%q0"
+      : "+r" (bitpos)
+      : "rm" (x));
+  return bitpos + 1;
+}
+#endif
+
+void other_constraints_test(void)
+{
+    unsigned long ret;
+    int var;
+#ifndef _WIN64
+    __asm__ volatile ("mov %P1,%0" : "=r" (ret) : "p" (&var));
+    printf ("oc1: %d\n", ret == (unsigned long)&var);
+#endif
+}
+
+#ifndef _WIN32
+/* Test global asm blocks playing with aliases.  */
+void base_func(void)
+{
+  printf ("asmc: base\n");
+}
+
+extern void override_func1 (void);
+extern void override_func2 (void);
+
+asm(".weak override_func1\n.set override_func1, base_func");
+asm(".set override_func1, base_func");
+asm(".set override_func2, base_func");
+
+void override_func2 (void)
+{
+  printf ("asmc: override2\n");
+}
+
+/* This checks a construct used by the linux kernel to encode
+   references to strings by PC relative references.  */
+extern int bug_table[] __attribute__((section("__bug_table")));
+char * get_asm_string (void)
+{
+  extern int some_symbol;
+  asm volatile (".globl some_symbol\n"
+		"jmp .+6\n"
+		"1:\n"
+		"some_symbol: .long 0\n"
+		".pushsection __bug_table, \"a\"\n"
+		".globl bug_table\n"
+		"bug_table:\n"
+		/* The first entry (1b-2b) is unused in this test,
+		   but we include it to check if cross-section
+		   PC-relative references work.  */
+		"2:\t.long 1b - 2b, %c0 - 2b\n"
+		".popsection\n" : : "i" ("A string"));
+  char * str = ((char*)bug_table) + bug_table[1];
+  return str;
+}
+
+/* This checks another constructs with local labels.  */
+extern unsigned char alld_stuff[];
+asm(".data\n"
+    ".byte 41\n"
+    "alld_stuff:\n"
+    "661:\n"
+    ".byte 42\n"
+    "662:\n"
+    ".pushsection .data.ignore\n"
+    ".long 661b - .\n" /* This reference to 661 generates an external sym
+                          which shouldn't somehow overwrite the offset that's
+                          already determined for it.  */
+    ".popsection\n"
+    ".byte 662b - 661b\n"  /* So that this value is undeniably 1.  */);
+
+void asm_local_label_diff (void)
+{
+  printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]);
+}
+
+/* This checks that static local variables are available from assembler.  */
+void asm_local_statics (void)
+{
+  static int localint = 41;
+  asm("incl %0" : "+m" (localint));
+  printf ("asm_local_statics: %d\n", localint);
+}
+#endif
+
+static
+unsigned int set;
+
+void fancy_copy (unsigned *in, unsigned *out)
+{
+  asm volatile ("" : "=r" (*out) : "0" (*in));
+}
+
+void fancy_copy2 (unsigned *in, unsigned *out)
+{
+  asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory");
+}
+
+#if defined __x86_64__ && !defined _WIN64
+void clobber_r12(void)
+{
+    asm volatile("mov $1, %%r12" ::: "r12");
+}
+#endif
+
+void test_high_clobbers(void)
+{
+#if defined __x86_64__ && !defined _WIN64
+    register long val asm("r12");
+    long val2;
+    /* This tests if asm clobbers correctly save/restore callee saved
+       registers if they are clobbered and if it's the high 8 x86-64
+       registers.  This is fragile for GCC as the constraints do not
+       correctly capture the data flow, but good enough for us.  */
+    asm volatile("mov $0x4542, %%r12" : "=r" (val):: "memory");
+    clobber_r12();
+    asm volatile("mov %%r12, %0" : "=r" (val2) : "r" (val): "memory");
+    printf("asmhc: 0x%x\n", val2);
+#endif
+}
+
+static long cpu_number;
+void trace_console(long len, long len2)
+{
+#ifdef __x86_64__
+    /* This generated invalid code when the emission of the switch
+       table isn't disabled.  The asms are necessary to show the bug,
+       normal statements don't work (they need to generate some code
+       even under nocode_wanted, which normal statements don't do,
+       but asms do).  Also at least these number of cases is necessary
+       to generate enough "random" bytes.  They ultimately are enough
+       to create invalid instruction patterns to which the first
+       skip-to-decision-table jump jumps.  If decision table emission
+       is disabled all of this is no problem.
+
+       It also is necessary that the switches are in a statement expression
+       (which has the property of not being enterable from outside. no
+       matter what).  */
+    if (0
+        &&
+            ({
+              long pscr_ret__;
+              switch(len) {
+                case 4:
+                    {
+                       long pfo_ret__;
+                       switch (len2) {
+                         case 8:	printf("bla"); pfo_ret__ = 42; break;
+                       }
+                       pscr_ret__ = pfo_ret__;
+                    }
+                  break;
+                case 8:
+                    {
+                       long pfo_ret__;
+                       switch (len2) {
+                         case 1:asm("movq %1,%0": "=r" (pfo_ret__)	: "m" (cpu_number));	break;
+                         case 2:asm("movq %1,%0": "=r" (pfo_ret__)	: "m" (cpu_number));	break;
+                         case 4:asm("movq %1,%0": "=r" (pfo_ret__)	: "m" (cpu_number));	break;
+                         case 8:asm("movq %1,%0": "=r" (pfo_ret__)	: "m" (cpu_number));	break;
+                         default: printf("impossible\n");
+                       }
+                       pscr_ret__ = pfo_ret__;
+                    };
+                  break;
+              }
+              pscr_ret__;
+            }))
+      {
+        printf("huh?\n");
+      }
+#endif
+}
+
+void test_asm_dead_code(void)
+{
+  long rdi;
+  /* Try to make sure that xdi contains a zero, and hence will
+     lead to a segfault if the next asm is evaluated without
+     arguments being set up.  */
+  asm volatile ("" : "=D" (rdi) : "0" (0));
+  (void)sizeof (({
+      int var;
+      /* This shouldn't trigger a segfault, either the argument
+         registers need to be set up and the asm emitted despite
+	 this being in an unevaluated context, or both the argument
+	 setup _and_ the asm emission need to be suppressed.  The latter
+	 is better.  Disabling asm code gen when suppression is on
+	 also fixes the above trace_console bug, but that came earlier
+	 than asm suppression.  */
+      asm volatile ("movl $0,(%0)" : : "D" (&var) : "memory");
+      var;
+  }));
+}
+
+void test_asm_call(void)
+{
+#if defined __x86_64__ && !defined _WIN64
+  static char str[] = "PATH";
+  char *s;
+  /* This tests if a reference to an undefined symbol from an asm
+     block, which isn't otherwise referenced in this file, is correctly
+     regarded as global symbol, so that it's resolved by other object files
+     or libraries.  We chose getenv here, which isn't used anywhere else
+     in this file.  (If we used e.g. printf, which is used we already
+     would have a global symbol entry, not triggering the bug which is
+     tested here).  */
+  /* two pushes so stack remains aligned */
+  asm volatile ("push %%rdi; push %%rdi; mov %0, %%rdi;"
+#if 1 && !defined(__TINYC__) && (defined(__PIC__) || defined(__PIE__))
+		"call getenv@plt;"
+#else
+		"call getenv;"
+#endif
+		"pop %%rdi; pop %%rdi"
+		: "=a" (s) : "r" (str));
+  printf("asmd: %s\n", s);
+#endif
+}
+
+#if defined __x86_64__
+# define RX "(%rip)"
+#else
+# define RX
+#endif
+
+void asm_dot_test(void)
+{
+    int x;
+    for (x = 1;; ++x) {
+        int r = x;
+        switch (x) {
+        case 1:
+            asm(".text; lea S"RX",%eax; lea ."RX",%ecx; sub %ecx,%eax; S=.; jmp p0");
+        case 2:
+            asm(".text; jmp .+6; .int 123; mov .-4"RX",%eax; jmp p0");
+	case 3:
+            asm(".data; Y=.; .int 999; X=Y; .int 456; X=.-4");
+            asm(".text; mov X"RX",%eax; jmp p0");
+        case 4:
+            asm(".data; X=.; .int 789; Y=.; .int 999");
+            asm(".text; mov X"RX",%eax; X=Y; jmp p0");
+        case 0:
+	    asm(".text; p0=.; mov %%eax,%0;" : "=m"(r)); break;
+	}
+        if (r == x)
+            break;
+        printf("asm_dot_test %d: %d\n", x, r);
+    }
+}
+
+void asm_test(void)
+{
+    char buf[128];
+    unsigned int val, val2;
+    struct struct123 s1;
+    struct struct1231 s2 = { (unsigned long)&s1 };
+    /* Hide the outer base_func, but check later that the inline
+       asm block gets the outer one.  */
+    int base_func = 42;
+    void override_func3 (void);
+    unsigned long asmret;
+#ifdef BOOL_ISOC99
+    _Bool somebool;
+#endif
+    register int regvar asm("%esi");
+
+    printf("inline asm:\n");
+
+    // parse 0x1E-1 as 3 tokens in asm mode
+    asm volatile ("mov $0x1E-1,%eax");
+
+    /* test the no operand case */
+    asm volatile ("xorl %eax, %eax");
+
+    memcpy1(buf, "hello", 6);
+    strncat1(buf, " worldXXXXX", 3);
+    printf("%s\n", buf);
+
+    memcpy2(buf, "hello", 6);
+    strncat2(buf, " worldXXXXX", 3);
+    printf("%s\n", buf);
+
+    /* 'A' constraint test */
+    printf("mul64=0x%Lx\n", mul64(0x12345678, 0xabcd1234));
+    printf("inc64=0x%Lx\n", inc64(0x12345678ffffffff));
+
+    s1.a = 42;
+    s1.b = 43;
+    printf("mconstraint: %d", mconstraint_test(&s2));
+    printf(" %d %d\n", s1.a, s1.b);
+    other_constraints_test();
+    set = 0xff;
+    sigdelset1(&set, 2);
+    sigaddset1(&set, 16);
+    /* NOTE: we test here if C labels are correctly restored after the
+       asm statement */
+    goto label1;
+ label2:
+    __asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc");
+    printf("set=0x%x\n", set);
+    val = 0x01020304;
+    printf("swab32(0x%08x) = 0x%0x\n", val, swab32(val));
+#ifndef _WIN32
+    override_func1();
+    override_func2();
+    /* The base_func ref from the following inline asm should find
+       the global one, not the local decl from this function.  */
+    asm volatile(".weak override_func3\n.set override_func3, base_func");
+    override_func3();
+    printf("asmstr: %s\n", get_asm_string());
+    asm_local_label_diff();
+    asm_local_statics();
+#endif
+    /* Check that we can also load structs of appropriate layout
+       into registers.  */
+    asm volatile("" : "=r" (asmret) : "0"(s2));
+    if (asmret != s2.addr)
+      printf("asmstr: failed\n");
+#ifdef BOOL_ISOC99
+    /* Check that the typesize correctly sets the register size to
+       8 bit.  */
+    asm volatile("cmp %1,%2; sete %0" : "=a"(somebool) : "r"(1), "r"(2));
+    if (!somebool)
+      printf("asmbool: failed\n");
+#endif
+    val = 43;
+    fancy_copy (&val, &val2);
+    printf ("fancycpy(%d)=%d\n", val, val2);
+    val = 44;
+    fancy_copy2 (&val, &val2);
+    printf ("fancycpy2(%d)=%d\n", val, val2);
+    asm volatile ("mov $0x4243, %%esi" : "=r" (regvar));
+    printf ("regvar=%x\n", regvar);
+    test_high_clobbers();
+    trace_console(8, 8);
+    test_asm_dead_code();
+    test_asm_call();
+    asm_dot_test();
+    return;
+ label1:
+    goto label2;
+}
+
+#else
+
+void asm_test(void)
+{
+}
+
+#endif
+
+#define COMPAT_TYPE(type1, type2) \
+{\
+    printf("__builtin_types_compatible_p(%s, %s) = %d\n", #type1, #type2, \
+           __builtin_types_compatible_p (type1, type2));\
+}
+
+int constant_p_var;
+
+void builtin_test(void)
+{
+    short s;
+    int i;
+    long long ll;
+#if GCC_MAJOR >= 3
+    COMPAT_TYPE(int, int);
+    COMPAT_TYPE(int, unsigned int);
+    COMPAT_TYPE(int, char);
+    COMPAT_TYPE(int, const int);
+    COMPAT_TYPE(int, volatile int);
+    COMPAT_TYPE(int *, int *);
+    COMPAT_TYPE(int *, void *);
+    COMPAT_TYPE(int *, const int *);
+    COMPAT_TYPE(char *, unsigned char *);
+    COMPAT_TYPE(char *, signed char *);
+    COMPAT_TYPE(char *, char *);
+/* space is needed because tcc preprocessor introduces a space between each token */
+    COMPAT_TYPE(char * *, void *); 
+#endif
+    printf("res = %d\n", __builtin_constant_p(1));
+    printf("res = %d\n", __builtin_constant_p(1 + 2));
+    printf("res = %d\n", __builtin_constant_p(&constant_p_var));
+    printf("res = %d\n", __builtin_constant_p(constant_p_var));
+    printf("res = %d\n", __builtin_constant_p(100000 / constant_p_var));
+    s = 1;
+    ll = 2;
+    i = __builtin_choose_expr (1 != 0, ll, s);
+    printf("bce: %d\n", i);
+    i = __builtin_choose_expr (1 != 1, ll, s);
+    printf("bce: %d\n", i);
+    i = sizeof (__builtin_choose_expr (1, ll, s));
+    printf("bce: %d\n", i);
+    i = sizeof (__builtin_choose_expr (0, ll, s));
+    printf("bce: %d\n", i);
+
+    //printf("bera: %p\n", __builtin_extract_return_addr((void*)43));
+}
+
+#ifndef _WIN32
+extern int __attribute__((weak)) weak_f1(void);
+extern int __attribute__((weak)) weak_f2(void);
+extern int                       weak_f3(void);
+extern int __attribute__((weak)) weak_v1;
+extern int __attribute__((weak)) weak_v2;
+extern int                       weak_v3;
+
+extern int                           (*weak_fpa)() __attribute__((weak));
+extern int __attribute__((weak))     (*weak_fpb)();
+extern     __attribute__((weak)) int (*weak_fpc)();
+
+extern int                     weak_asm_f1(void) asm("weak_asm_f1x") __attribute((weak));
+extern int __attribute((weak)) weak_asm_f2(void) asm("weak_asm_f2x")                    ;
+extern int __attribute((weak)) weak_asm_f3(void) asm("weak_asm_f3x") __attribute((weak));
+extern int                     weak_asm_v1       asm("weak_asm_v1x") __attribute((weak));
+extern int __attribute((weak)) weak_asm_v2       asm("weak_asm_v2x")                    ;
+extern int __attribute((weak)) weak_asm_v3(void) asm("weak_asm_v3x") __attribute((weak));
+
+static const size_t dummy = 0;
+extern __typeof(dummy) weak_dummy1 __attribute__((weak, alias("dummy")));
+extern __typeof(dummy) __attribute__((weak, alias("dummy"))) weak_dummy2;
+extern __attribute__((weak, alias("dummy"))) __typeof(dummy) weak_dummy3;
+
+int some_lib_func(void);
+int dummy_impl_of_slf(void) { return 444; }
+int some_lib_func(void) __attribute__((weak, alias("dummy_impl_of_slf")));
+
+int weak_toolate() __attribute__((weak));
+int weak_toolate() { return 0; }
+
+void __attribute__((weak)) weak_test(void)
+{
+	printf("weak_f1=%d\n", weak_f1 ? weak_f1() : 123);
+	printf("weak_f2=%d\n", weak_f2 ? weak_f2() : 123);
+	printf("weak_f3=%d\n", weak_f3 ? weak_f3() : 123);
+	printf("weak_v1=%d\n",&weak_v1 ? weak_v1   : 123);
+	printf("weak_v2=%d\n",&weak_v2 ? weak_v2   : 123);
+	printf("weak_v3=%d\n",&weak_v3 ? weak_v3   : 123);
+
+	printf("weak_fpa=%d\n",&weak_fpa ? weak_fpa() : 123);
+	printf("weak_fpb=%d\n",&weak_fpb ? weak_fpb() : 123);
+	printf("weak_fpc=%d\n",&weak_fpc ? weak_fpc() : 123);
+	
+	printf("weak_asm_f1=%d\n", weak_asm_f1 != NULL);
+	printf("weak_asm_f2=%d\n", weak_asm_f2 != NULL);
+	printf("weak_asm_f3=%d\n", weak_asm_f3 != NULL);
+	printf("weak_asm_v1=%d\n",&weak_asm_v1 != NULL);
+	printf("weak_asm_v2=%d\n",&weak_asm_v2 != NULL);
+	printf("weak_asm_v3=%d\n",&weak_asm_v3 != NULL);
+	printf("some_lib_func=%d\n", &some_lib_func ? some_lib_func() : 0);
+}
+
+int __attribute__((weak)) weak_f2() { return 222; }
+int __attribute__((weak)) weak_f3() { return 333; }
+int __attribute__((weak)) weak_v2 = 222;
+int __attribute__((weak)) weak_v3 = 333;
+#endif
+
+void const_func(const int a)
+{
+}
+
+void const_warn_test(void)
+{
+    const_func(1);
+}
+
+struct condstruct {
+  int i;
+};
+
+int getme (struct condstruct *s, int i)
+{
+  int i1 = (i == 0 ? 0 : s)->i;
+  int i2 = (i == 0 ? s : 0)->i;
+  int i3 = (i == 0 ? (void*)0 : s)->i;
+  int i4 = (i == 0 ? s : (void*)0)->i;
+  return i1 + i2 + i3 + i4;
+}
+
+struct global_data
+{
+  int a[40];
+  int *b[40];
+};
+
+struct global_data global_data;
+
+int global_data_getstuff (int *, int);
+
+void global_data_callit (int i)
+{
+  *global_data.b[i] = global_data_getstuff (global_data.b[i], 1);
+}
+
+int global_data_getstuff (int *p, int i)
+{
+  return *p + i;
+}
+
+void global_data_test (void)
+{
+  global_data.a[0] = 42;
+  global_data.b[0] = &global_data.a[0];
+  global_data_callit (0);
+  printf ("%d\n", global_data.a[0]);
+}
+
+struct cmpcmpS
+{
+  unsigned char fill : 3;
+  unsigned char b1 : 1;
+  unsigned char b2 : 1;
+  unsigned char fill2 : 3;
+};
+
+int glob1, glob2, glob3;
+
+void compare_comparisons (struct cmpcmpS *s)
+{
+  if (s->b1 != (glob1 == glob2)
+      || (s->b2 != (glob1 == glob3)))
+    printf ("comparing comparisons broken\n");
+}
+
+void cmp_comparison_test(void)
+{
+  struct cmpcmpS s;
+  s.b1 = 1;
+  glob1 = 42; glob2 = 42;
+  s.b2 = 0;
+  glob3 = 43;
+  compare_comparisons (&s);
+}
+
+int fcompare (double a, double b, int code)
+{
+  switch (code) {
+    case 0: return a == b;
+    case 1: return a != b;
+    case 2: return a < b;
+    case 3: return a >= b;
+    case 4: return a > b;
+    case 5: return a <= b;
+  }
+}
+
+void math_cmp_test(void)
+{
+  double nan = 0.0/0.0;
+  double one = 1.0;
+  double two = 2.0;
+  int comp = 0;
+#define bug(a,b,op,iop,part) printf("Test broken: %s %s %s %s %d\n", #a, #b, #op, #iop, part)
+
+  /* This asserts that "a op b" is _not_ true, but "a iop b" is true.
+     And it does this in various ways so that all code generation paths
+     are checked (generating inverted tests, or non-inverted tests, or
+     producing a 0/1 value without jumps (that's done in the fcompare
+     function).  */
+#define FCMP(a,b,op,iop,code) \
+  if (fcompare (a,b,code))    \
+    bug (a,b,op,iop,1); \
+  if (a op b) \
+    bug (a,b,op,iop,2); \
+  if (a iop b) \
+    ; \
+  else \
+    bug (a,b,op,iop,3); \
+  if ((a op b) || comp) \
+    bug (a,b,op,iop,4); \
+  if ((a iop b) || comp) \
+    ; \
+  else \
+    bug (a,b,op,iop,5);
+
+  /* Equality tests.  */
+  FCMP(nan, nan, ==, !=, 0);
+  FCMP(one, two, ==, !=, 0);
+  FCMP(one, one, !=, ==, 1);
+  /* Non-equality is a bit special.  */
+  if (!fcompare (nan, nan, 1))
+    bug (nan, nan, !=, ==, 6);
+
+  /* Relational tests on numbers.  */
+  FCMP(two, one, <, >=, 2);
+  FCMP(one, two, >=, <, 3);
+  FCMP(one, two, >, <=, 4);
+  FCMP(two, one, <=, >, 5);
+
+  /* Relational tests on NaNs.  Note that the inverse op here is
+     always !=, there's no operator in C that is equivalent to !(a < b),
+     when NaNs are involved, same for the other relational ops.  */
+  FCMP(nan, nan, <, !=, 2);
+  FCMP(nan, nan, >=, !=, 3);
+  FCMP(nan, nan, >, !=, 4);
+  FCMP(nan, nan, <=, !=, 5);
+}
+
+double get100 () { return 100.0; }
+
+void callsave_test(void)
+{
+#if defined __i386__ || defined __x86_64__ || defined __arm__
+  int i, s; double *d; double t;
+  s = sizeof (double);
+  printf ("callsavetest: %d\n", s);
+  d = alloca (sizeof(double));
+  d[0] = 10.0;
+  /* x86-64 had a bug were the next call to get100 would evict
+     the lvalue &d[0] as VT_LLOCAL, and the reload would be done
+     in int type, not pointer type.  When alloca returns a pointer
+     with the high 32 bit set (which is likely on x86-64) the access
+     generates a segfault.  */
+  i = d[0] > get100 ();
+  printf ("%d\n", i);
+#endif
+}
+
+
+void bfa3(ptrdiff_t str_offset)
+{
+    printf("bfa3: %s\n", (char *)__builtin_frame_address(3) + str_offset);
+}
+void bfa2(ptrdiff_t str_offset)
+{
+    printf("bfa2: %s\n", (char *)__builtin_frame_address(2) + str_offset);
+    bfa3(str_offset);
+}
+void bfa1(ptrdiff_t str_offset)
+{
+    printf("bfa1: %s\n", (char *)__builtin_frame_address(1) + str_offset);
+    bfa2(str_offset);
+}
+
+void builtin_frame_address_test(void)
+{
+/* builtin_frame_address fails on ARM with gcc which make test3 fail */
+#ifndef __arm__
+    char str[] = "__builtin_frame_address";
+    char *fp0 = __builtin_frame_address(0);
+
+    printf("str: %s\n", str);
+    bfa1(str-fp0);
+#endif
+}
+
+char via_volatile (char i)
+{
+  char volatile vi;
+  vi = i;
+  return vi;
+}
+
+struct __attribute__((__packed__)) Spacked {
+    char a;
+    short b;
+    int c;
+};
+struct Spacked spacked;
+typedef struct __attribute__((__packed__)) {
+    char a;
+    short b;
+    int c;
+} Spacked2;
+Spacked2 spacked2;
+typedef struct Spacked3_s {
+    char a;
+    short b;
+    int c;
+} __attribute__((__packed__)) Spacked3;
+Spacked3 spacked3;
+struct gate_struct64 {
+    unsigned short offset_low;
+    unsigned short segment;
+    unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1;
+    unsigned short offset_middle;
+    unsigned offset_high;
+    unsigned zero1;
+} __attribute__((packed));
+typedef struct gate_struct64 gate_desc;
+gate_desc a_gate_desc;
+void attrib_test(void)
+{
+#ifndef _WIN32
+  printf("attr: %d %d %d %d\n", sizeof(struct Spacked),
+	 sizeof(spacked), sizeof(Spacked2), sizeof(spacked2));
+  printf("attr: %d %d\n", sizeof(Spacked3), sizeof(spacked3));
+  printf("attr: %d %d\n", sizeof(gate_desc), sizeof(a_gate_desc));
+#endif
+}
+extern __attribute__((__unused__)) char * __attribute__((__unused__)) *
+strange_attrib_placement (void);
+
+void * __attribute__((__unused__)) get_void_ptr (void *a)
+{
+  return a;
+}
+
+/* This part checks for a bug in TOK_GET (used for inline expansion),
+   where the large long long constant left the the high bits set for
+   the integer constant token.  */
+static inline
+int __get_order(unsigned long long size)
+{
+  int order;
+  size -= 0xffff880000000000ULL; // this const left high bits set in the token
+    {
+      struct S { int i : 1; } s; // constructed for this '1'
+    }
+  order = size;
+  return order;
+}
+
+/* This just forces the above inline function to be actually emitted.  */
+int force_get_order(unsigned long s)
+{
+    return __get_order(s);
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tcctest.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tcctest.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tcctest.h	(revision 331)
@@ -0,0 +1,9 @@
+static inline const char *get_basefile_from_header(void)
+{
+  return __BASE_FILE__;
+}
+
+static inline const char *get_file_from_header(void)
+{
+  return __FILE__;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/testfp.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/testfp.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/testfp.c	(revision 331)
@@ -0,0 +1,510 @@
+/*
+ *  Test 128-bit floating-point arithmetic on arm64:
+ *  build with two different compilers and compare the output.
+ *
+ *  Copyright (c) 2015 Edmund Grimley Evans
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.  This file is offered as-is,
+ * without any warranty.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define check(x) ((x) ? (void)0 : check_fail(#x, __FILE__, __LINE__))
+
+void check_fail(const char *assertion, const char *file, unsigned int line)
+{
+    printf("%s:%d: Check (%s) failed.", file, line, assertion);
+    exit(1);
+}
+
+typedef struct {
+    unsigned long long x0, x1;
+} u128_t;
+
+float copy_fi(uint32_t x)
+{
+    float f;
+    memcpy(&f, &x, 4);
+    return f;
+}
+
+double copy_di(uint64_t x)
+{
+    double f;
+    memcpy(&f, &x, 8);
+    return f;
+}
+
+long double copy_ldi(u128_t x)
+{
+    long double f;
+    memcpy(&f, &x, 16);
+    return f;
+}
+
+uint32_t copy_if(float f)
+{
+    uint32_t x;
+    memcpy(&x, &f, 4);
+    return x;
+}
+
+uint64_t copy_id(double f)
+{
+    uint64_t x;
+    memcpy(&x, &f, 8);
+    return x;
+}
+
+u128_t copy_ild(long double f)
+{
+    u128_t x;
+    memcpy(&x, &f, 16);
+    return x;
+}
+
+long double make(int sgn, int exp, uint64_t high, uint64_t low)
+{
+    u128_t x = { low,
+                 (0x0000ffffffffffff & high) |
+                 (0x7fff000000000000 & (uint64_t)exp << 48) |
+                 (0x8000000000000000 & (uint64_t)sgn << 63) };
+    return copy_ldi(x);
+}
+
+void cmp(long double a, long double b)
+{
+    u128_t ax = copy_ild(a);
+    u128_t bx = copy_ild(b);
+    int eq = (a == b);
+    int ne = (a != b);
+    int lt = (a < b);
+    int le = (a <= b);
+    int gt = (a > b);
+    int ge = (a >= b);
+
+    check(eq == 0 || eq == 1);
+    check(lt == 0 || lt == 1);
+    check(gt == 0 || gt == 1);
+    check(ne == !eq && le == (lt | eq) && ge == (gt | eq));
+    check(eq + lt + gt < 2);
+
+    printf("cmp %016llx%016llx %016llx%016llx %d %d %d\n",
+           ax.x1, ax.x0, bx.x1, bx.x0, lt, eq, gt);
+}
+
+void cmps(void)
+{
+    int i, j;
+
+    for (i = 0; i < 2; i++)
+        for (j = 0; j < 2; j++)
+            cmp(make(i, 0, 0, 0), make(j, 0, 0, 0));
+
+    for (i = 0; i < 2; i++) {
+        for (j = 0; j < 64; j++) {
+            long double f1 = make(i, 32767, (uint64_t)1 << j, 0);
+            long double f2 = make(i, 32767, 0, (uint64_t)1 << j);
+            cmp(f1, 0);
+            cmp(f2, 0);
+            cmp(0, f1);
+            cmp(0, f2);
+        }
+    }
+
+    for (i = 0; i < 6; i++)
+        for (j = 0; j < 6; j++)
+            cmp(make(i & 1, i >> 1, 0, 0),
+                make(j & 1, j >> 1, 0, 0));
+
+    for (i = 0; i < 2; i++) {
+        for (j = 0; j < 2; j++) {
+            int a, b;
+            for (a = 0; a < 2; a++) {
+                for (b = 0; b < 2; b++) {
+                    cmp(make(i, j, a, b), make(i, j, 0, 0));
+                    cmp(make(i, j, 0, 0), make(i, j, a, b));
+                }
+            }
+        }
+    }
+}
+
+void xop(const char *name, long double a, long double b, long double c)
+{
+    u128_t ax = copy_ild(a);
+    u128_t bx = copy_ild(b);
+    u128_t cx = copy_ild(c);
+    printf("%s %016llx%016llx %016llx%016llx %016llx%016llx\n",
+           name, ax.x1, ax.x0, bx.x1, bx.x0, cx.x1, cx.x0);
+}
+
+void fadd(long double a, long double b)
+{
+    xop("add", a, b, a + b);
+}
+
+void fsub(long double a, long double b)
+{
+    xop("sub", a, b, a - b);
+}
+
+void fmul(long double a, long double b)
+{
+    xop("mul", a, b, a * b);
+}
+
+void fdiv(long double a, long double b)
+{
+    xop("div", a, b, a / b);
+}
+
+void nanz(void)
+{
+    // Check NaNs:
+    {
+        long double x[7];
+        int i, j, n = 0;
+        x[n++] = make(0, 32000, 0x95132b76effc, 0xd79035214b4f8d53);
+        x[n++] = make(1, 32001, 0xbe71d7a51587, 0x30601c6815d6c3ac);
+        x[n++] = make(0, 32767, 0, 1);
+        x[n++] = make(0, 32767, (uint64_t)1 << 46, 0);
+        x[n++] = make(1, 32767, (uint64_t)1 << 47, 0);
+        x[n++] = make(1, 32767, 0x7596c7099ad5, 0xe25fed2c58f73fc9);
+        x[n++] = make(0, 32767, 0x835d143360f9, 0x5e315efb35630666);
+        check(n == sizeof(x) / sizeof(*x));
+        for (i = 0; i < n; i++) {
+            for (j = 0; j < n; j++) {
+                fadd(x[i], x[j]);
+                fsub(x[i], x[j]);
+                fmul(x[i], x[j]);
+                fdiv(x[i], x[j]);
+            }
+        }
+    }
+
+    // Check infinities and zeroes:
+    {
+        long double x[6];
+        int i, j, n = 0;
+        x[n++] = make(1, 32000, 0x62acda85f700, 0x47b6c9f35edc4044);
+        x[n++] = make(0, 32001, 0x94b7abf55af7, 0x9f425fe354428e19);
+        x[n++] = make(0, 32767, 0, 0);
+        x[n++] = make(1, 32767, 0, 0);
+        x[n++] = make(0, 0, 0, 0);
+        x[n++] = make(1, 0, 0, 0);
+        check(n == sizeof(x) / sizeof(*x));
+        for (i = 0; i < n; i++) {
+            for (j = 0; j < n; j++) {
+                fadd(x[i], x[j]);
+                fsub(x[i], x[j]);
+                fmul(x[i], x[j]);
+                fdiv(x[i], x[j]);
+            }
+        }
+    }
+}
+
+void adds(void)
+{
+    // Check shifting and add/sub:
+    {
+        int i;
+        for (i = -130; i <= 130; i++) {
+            int s1 = (uint32_t)i % 3 < 1;
+            int s2 = (uint32_t)i % 5 < 2;
+            fadd(make(s1, 16384    , 0x502c065e4f71a65d, 0xd2f9bdb031f4f031),
+                 make(s2, 16384 + i, 0xae267395a9bc1033, 0xb56b5800da1ba448));
+        }
+    }
+
+    // Check normalisation:
+    {
+        uint64_t a0 = 0xc6bab0a6afbef5ed;
+        uint64_t a1 = 0x4f84136c4a2e9b52;
+        int ee[] = { 0, 1, 10000 };
+        int e, i;
+        for (e = 0; e < sizeof(ee) / sizeof(*ee); e++) {
+            int exp = ee[e];
+            fsub(make(0, exp, a1, a0), make(0, 0, 0, 0));
+            for (i = 63; i >= 0; i--)
+                fsub(make(0, exp, a1 | (uint64_t)1 << i >> 1, a0),
+                     make(0, exp, a1 >> i << i, 0));
+            for (i = 63; i >=0; i--)
+                fsub(make(0, exp, a1, a0 | (uint64_t)1 << i >> 1),
+                     make(0, exp, a1, a0 >> i << i));
+        }
+    }
+
+    // Carry/overflow from rounding:
+    {
+        fadd(make(0, 114, -1, -1), make(0, 1, 0, 0));
+        fadd(make(0, 32766, -1, -1), make(0, 32653, 0, 0));
+        fsub(make(1, 32766, -1, -1), make(0, 32653, 0, 0));
+    }
+}
+
+void muls(void)
+{
+    int i, j;
+
+    {
+        long double max = make(0, 32766, -1, -1);
+        long double min = make(0, 0, 0, 1);
+        fmul(max, max);
+        fmul(max, min);
+        fmul(min, min);
+    }
+
+    for (i = 117; i > 0; i--)
+        fmul(make(0, 16268, 0x643dcea76edc, 0xe0877a598403627a),
+             make(i & 1, i, 0, 0));
+
+    fmul(make(0, 16383, -1, -3), make(0, 16383, 0, 1));
+    // Round to next exponent:
+    fmul(make(0, 16383, -1, -2), make(0, 16383, 0, 1));
+    // Round from subnormal to normal:
+    fmul(make(0, 1, -1, -1), make(0, 16382, 0, 0));
+
+    for (i = 0; i < 2; i++)
+        for (j = 0; j < 112; j++)
+            fmul(make(0, 16383, (uint64_t)1 << i, 0),
+                 make(0, 16383,
+                      j < 64 ? 0 : (uint64_t)1 << (j - 64),
+                      j < 64 ? (uint64_t)1 << j : 0));
+}
+
+void divs(void)
+{
+    int i;
+
+    {
+        long double max = make(0, 32766, -1, -1);
+        long double min = make(0, 0, 0, 1);
+        fdiv(max, max);
+        fdiv(max, min);
+        fdiv(min, max);
+        fdiv(min, min);
+    }
+
+    for (i = 0; i < 64; i++)
+        fdiv(make(0, 16383, -1, -1), make(0, 16383, -1, -(uint64_t)1 << i));
+    for (i = 0; i < 48; i++)
+        fdiv(make(0, 16383, -1, -1), make(0, 16383, -(uint64_t)1 << i, 0));
+}
+
+void cvtlsw(int32_t a)
+{
+    long double f = a;
+    u128_t x = copy_ild(f);
+    printf("cvtlsw %08lx %016llx%016llx\n", (long)(uint32_t)a, x.x1, x.x0);
+}
+
+void cvtlsx(int64_t a)
+{
+    long double f = a;
+    u128_t x = copy_ild(f);
+    printf("cvtlsx %016llx %016llx%016llx\n",
+           (long long)(uint64_t)a, x.x1, x.x0);
+}
+
+void cvtluw(uint32_t a)
+{
+    long double f = a;
+    u128_t x = copy_ild(f);
+    printf("cvtluw %08lx %016llx%016llx\n", (long)a, x.x1, x.x0);
+}
+
+void cvtlux(uint64_t a)
+{
+    long double f = a;
+    u128_t x = copy_ild(f);
+    printf("cvtlux %016llx %016llx%016llx\n", (long long)a, x.x1, x.x0);
+}
+
+void cvtil(long double a)
+{
+    u128_t x = copy_ild(a);
+    int32_t b1 = a;
+    int64_t b2 = a;
+    uint32_t b3 = a;
+    uint64_t b4 = a;
+    printf("cvtswl %016llx%016llx %08lx\n",
+           x.x1, x.x0, (long)(uint32_t)b1);
+    printf("cvtsxl %016llx%016llx %016llx\n",
+           x.x1, x.x0, (long long)(uint64_t)b2);
+    printf("cvtuwl %016llx%016llx %08lx\n",
+           x.x1, x.x0, (long)b3);
+    printf("cvtuxl %016llx%016llx %016llx\n",
+           x.x1, x.x0, (long long)b4);
+}
+
+void cvtlf(float a)
+{
+    uint32_t ax = copy_if(a);
+    long double b = a;
+    u128_t bx = copy_ild(b);
+    printf("cvtlf %08lx %016llx%016llx\n", (long)ax, bx.x1, bx.x0);
+}
+
+void cvtld(double a)
+{
+    uint64_t ax = copy_id(a);
+    long double b = a;
+    u128_t bx = copy_ild(b);
+    printf("cvtld %016llx %016llx%016llx\n", (long long)ax, bx.x1, bx.x0);
+}
+
+void cvtfl(long double a)
+{
+    u128_t ax = copy_ild(a);
+    float b = a;
+    uint32_t bx = copy_if(b);
+    printf("cvtfl %016llx%016llx %08lx\n", ax.x1, ax.x0, (long)bx);
+}
+
+void cvtdl(long double a)
+{
+    u128_t ax = copy_ild(a);
+    double b = a;
+    uint64_t bx = copy_id(b);
+    printf("cvtdl %016llx%016llx %016llx\n", ax.x1, ax.x0, (long long)bx);
+}
+
+void cvts(void)
+{
+    int i, j;
+
+    {
+        uint32_t x = 0xad040c5b;
+        cvtlsw(0);
+        for (i = 0; i < 31; i++)
+            cvtlsw(x >> (31 - i));
+        for (i = 0; i < 31; i++)
+            cvtlsw(-(x >> (31 - i)));
+        cvtlsw(0x80000000);
+    }
+    {
+        uint64_t x = 0xb630a248cad9afd2;
+        cvtlsx(0);
+        for (i = 0; i < 63; i++)
+            cvtlsx(x >> (63 - i));
+        for (i = 0; i < 63; i++)
+            cvtlsx(-(x >> (63 - i)));
+        cvtlsx(0x8000000000000000);
+    }
+    {
+        uint32_t x = 0xad040c5b;
+        cvtluw(0);
+        for (i = 0; i < 32; i++)
+            cvtluw(x >> (31 - i));
+    }
+    {
+        uint64_t x = 0xb630a248cad9afd2;
+        cvtlux(0);
+        for (i = 0; i < 64; i++)
+            cvtlux(x >> (63 - i));
+    }
+
+    for (i = 0; i < 2; i++) {
+        cvtil(make(i, 32767, 0, 1));
+        cvtil(make(i, 32767, (uint64_t)1 << 47, 0));
+        cvtil(make(i, 32767, 123, 456));
+        cvtil(make(i, 32767, 0, 0));
+        cvtil(make(i, 16382, -1, -1));
+        cvtil(make(i, 16383, -1, -1));
+        cvtil(make(i, 16384, 0x7fffffffffff, -1));
+        cvtil(make(i, 16384, 0x800000000000, 0));
+        for (j = 0; j < 68; j++)
+            cvtil(make(i, 16381 + j, 0xd4822c0a10ec, 0x1fe2f8b2669f5c9d));
+    }
+
+    cvtlf(copy_fi(0x00000000));
+    cvtlf(copy_fi(0x456789ab));
+    cvtlf(copy_fi(0x7f800000));
+    cvtlf(copy_fi(0x7f923456));
+    cvtlf(copy_fi(0x7fdbcdef));
+    cvtlf(copy_fi(0x80000000));
+    cvtlf(copy_fi(0xabcdef12));
+    cvtlf(copy_fi(0xff800000));
+    cvtlf(copy_fi(0xff923456));
+    cvtlf(copy_fi(0xffdbcdef));
+
+    cvtld(copy_di(0x0000000000000000));
+    cvtld(copy_di(0x456789abcdef0123));
+    cvtld(copy_di(0x7ff0000000000000));
+    cvtld(copy_di(0x7ff123456789abcd));
+    cvtld(copy_di(0x7ffabcdef1234567));
+    cvtld(copy_di(0x8000000000000000));
+    cvtld(copy_di(0xcdef123456789abc));
+    cvtld(copy_di(0xfff0000000000000));
+    cvtld(copy_di(0xfff123456789abcd));
+    cvtld(copy_di(0xfffabcdef1234567));
+
+    for (i = 0; i < 2; i++) {                   \
+        cvtfl(make(i, 0, 0, 0));
+        cvtfl(make(i, 16232, -1, -1));
+        cvtfl(make(i, 16233, 0, 0));
+        cvtfl(make(i, 16233, 0, 1));
+        cvtfl(make(i, 16383, 0xab0ffd000000, 0));
+        cvtfl(make(i, 16383, 0xab0ffd000001, 0));
+        cvtfl(make(i, 16383, 0xab0ffeffffff, 0));
+        cvtfl(make(i, 16383, 0xab0fff000000, 0));
+        cvtfl(make(i, 16383, 0xab0fff000001, 0));
+        cvtfl(make(i, 16510, 0xfffffeffffff, -1));
+        cvtfl(make(i, 16510, 0xffffff000000, 0));
+        cvtfl(make(i, 16511, 0, 0));
+        cvtfl(make(i, 32767, 0, 0));
+        cvtfl(make(i, 32767, 0, 1));
+        cvtfl(make(i, 32767, 0x4cbe01ac5f40, 0x75cee3c6afbb00b5));
+        cvtfl(make(i, 32767, 0x800000000000, 1));
+        cvtfl(make(i, 32767, 0xa11caaaf6a52, 0x696033e871eab099));
+    }
+
+    for (i = 0; i < 2; i++) {
+        cvtdl(make(i, 0, 0, 0));
+        cvtdl(make(i, 15307, -1, -1));
+        cvtdl(make(i, 15308, 0, 0));
+        cvtdl(make(i, 15308, 0, 1));
+        cvtdl(make(i, 16383, 0xabc123abc0ff, 0xe800000000000000));
+        cvtdl(make(i, 16383, 0xabc123abc0ff, 0xe800000000000001));
+        cvtdl(make(i, 16383, 0xabc123abc0ff, 0xf7ffffffffffffff));
+        cvtdl(make(i, 16383, 0xabc123abc0ff, 0xf800000000000000));
+        cvtdl(make(i, 16383, 0xabc123abc0ff, 0xf800000000000001));
+        cvtdl(make(i, 17406, 0xffffffffffff, 0xf7ffffffffffffff));
+        cvtdl(make(i, 17406, 0xffffffffffff, 0xf800000000000000));
+        cvtdl(make(i, 17407, 0, 0));
+        cvtdl(make(i, 32767, 0, 0));
+        cvtdl(make(i, 32767, 0, 1));
+        cvtdl(make(i, 32767, 0x4cbe01ac5f40, 0x75cee3c6afbb00b5));
+        cvtdl(make(i, 32767, 0x800000000000, 1));
+        cvtdl(make(i, 32767, 0xa11caaaf6a52, 0x696033e871eab099));
+    }
+}
+
+void tests(void)
+{
+    cmps();
+    nanz();
+    adds();
+    muls();
+    divs();
+    cvts();
+}
+
+int main()
+{
+#ifdef __aarch64__
+    tests();
+#else
+    printf("This test program is intended for a little-endian architecture\n"
+           "with an IEEE-standard 128-bit long double.\n");
+#endif
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/00_assignment.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/00_assignment.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/00_assignment.c	(revision 331)
@@ -0,0 +1,18 @@
+#include <stdio.h>
+
+int main() 
+{
+   int a;
+   a = 42;
+   printf("%d\n", a);
+
+   int b = 64;
+   printf("%d\n", b);
+
+   int c = 12, d = 34;
+   printf("%d, %d\n", c, d);
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/00_assignment.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/00_assignment.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/00_assignment.expect	(revision 331)
@@ -0,0 +1,3 @@
+42
+64
+12, 34
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/01_comment.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/01_comment.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/01_comment.c	(revision 331)
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+int main() 
+{
+   printf("Hello\n");
+   printf("Hello\n"); /* this is a comment */ printf("Hello\n");
+   printf("Hello\n");
+   // this is also a comment sayhello();
+   printf("Hello\n");
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/01_comment.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/01_comment.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/01_comment.expect	(revision 331)
@@ -0,0 +1,5 @@
+Hello
+Hello
+Hello
+Hello
+Hello
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/02_printf.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/02_printf.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/02_printf.c	(revision 331)
@@ -0,0 +1,18 @@
+#include <stdio.h>
+
+int main() 
+{
+   printf("Hello world\n");
+
+   int Count;
+   for (Count = -5; Count <= 5; Count++)
+      printf("Count = %d\n", Count);
+
+   printf("String 'hello', 'there' is '%s', '%s'\n", "hello", "there");
+   printf("Character 'A' is '%c'\n", 65);
+   printf("Character 'a' is '%c'\n", 'a');
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/02_printf.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/02_printf.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/02_printf.expect	(revision 331)
@@ -0,0 +1,15 @@
+Hello world
+Count = -5
+Count = -4
+Count = -3
+Count = -2
+Count = -1
+Count = 0
+Count = 1
+Count = 2
+Count = 3
+Count = 4
+Count = 5
+String 'hello', 'there' is 'hello', 'there'
+Character 'A' is 'A'
+Character 'a' is 'a'
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/03_struct.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/03_struct.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/03_struct.c	(revision 331)
@@ -0,0 +1,31 @@
+#include <stdio.h>
+
+struct fred
+{
+   int boris;
+   int natasha;
+};
+
+int main()
+{
+   struct fred bloggs;
+
+   bloggs.boris = 12;
+   bloggs.natasha = 34;
+
+   printf("%d\n", bloggs.boris);
+   printf("%d\n", bloggs.natasha);
+
+   struct fred jones[2];
+   jones[0].boris = 12;
+   jones[0].natasha = 34;
+   jones[1].boris = 56;
+   jones[1].natasha = 78;
+
+   printf("%d\n", jones[0].boris);
+   printf("%d\n", jones[0].natasha);
+   printf("%d\n", jones[1].boris);
+   printf("%d\n", jones[1].natasha);
+
+   return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/03_struct.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/03_struct.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/03_struct.expect	(revision 331)
@@ -0,0 +1,6 @@
+12
+34
+12
+34
+56
+78
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/04_for.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/04_for.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/04_for.c	(revision 331)
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int main() 
+{
+   int Count;
+
+   for (Count = 1; Count <= 10; Count++)
+   {
+      printf("%d\n", Count);
+   }
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/04_for.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/04_for.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/04_for.expect	(revision 331)
@@ -0,0 +1,10 @@
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/05_array.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/05_array.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/05_array.c	(revision 331)
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int main() 
+{
+   int Count;
+   int Array[10];
+
+   for (Count = 1; Count <= 10; Count++)
+   {
+      Array[Count-1] = Count * Count;
+   }
+
+   for (Count = 0; Count < 10; Count++)
+   {
+      printf("%d\n", Array[Count]);
+   }
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/05_array.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/05_array.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/05_array.expect	(revision 331)
@@ -0,0 +1,10 @@
+1
+4
+9
+16
+25
+36
+49
+64
+81
+100
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/06_case.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/06_case.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/06_case.c	(revision 331)
@@ -0,0 +1,29 @@
+#include <stdio.h>
+
+int main()
+{
+   int Count;
+
+   for (Count = 0; Count < 4; Count++)
+   {
+      printf("%d\n", Count);
+      switch (Count)
+      {
+         case 1:
+            printf("%d\n", 1);
+            break;
+
+         case 2:
+            printf("%d\n", 2);
+            break;
+
+         default:
+            printf("%d\n", 0);
+            break;
+      }
+   }
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/06_case.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/06_case.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/06_case.expect	(revision 331)
@@ -0,0 +1,8 @@
+0
+0
+1
+1
+2
+2
+3
+0
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/07_function.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/07_function.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/07_function.c	(revision 331)
@@ -0,0 +1,30 @@
+#include <stdio.h>
+
+int myfunc(int x)
+{
+   return x * x;
+}
+
+void vfunc(int a)
+{
+   printf("a=%d\n", a);
+}
+
+void qfunc()
+{
+   printf("qfunc()\n");
+}
+
+int main()
+{
+   printf("%d\n", myfunc(3));
+   printf("%d\n", myfunc(4));
+
+   vfunc(1234);
+
+   qfunc();
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/07_function.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/07_function.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/07_function.expect	(revision 331)
@@ -0,0 +1,4 @@
+9
+16
+a=1234
+qfunc()
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/08_while.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/08_while.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/08_while.c	(revision 331)
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+int main()
+{
+   int a;
+   int p;
+   int t;
+
+   a = 1;
+   p = 0;
+   t = 0;
+
+   while (a < 100)
+   {
+      printf("%d\n", a);
+      t = a;
+      a = t + p;
+      p = t;
+   }
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/08_while.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/08_while.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/08_while.expect	(revision 331)
@@ -0,0 +1,11 @@
+1
+1
+2
+3
+5
+8
+13
+21
+34
+55
+89
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/09_do_while.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/09_do_while.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/09_do_while.c	(revision 331)
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+int main()
+{
+   int a;
+   int p;
+   int t;
+
+   a = 1;
+   p = 0;
+   t = 0;
+
+   do
+   {
+      printf("%d\n", a);
+      t = a;
+      a = t + p;
+      p = t;
+   } while (a < 100);
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/09_do_while.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/09_do_while.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/09_do_while.expect	(revision 331)
@@ -0,0 +1,11 @@
+1
+1
+2
+3
+5
+8
+13
+21
+34
+55
+89
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/10_pointer.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/10_pointer.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/10_pointer.c	(revision 331)
@@ -0,0 +1,40 @@
+#include <stdio.h>
+
+struct ziggy
+{
+   int a;
+   int b;
+   int c;
+} bolshevic;
+
+int main()
+{
+   int a;
+   int *b;
+   int c;
+
+   a = 42;
+   b = &a;
+   printf("a = %d\n", *b);
+
+   bolshevic.a = 12;
+   bolshevic.b = 34;
+   bolshevic.c = 56;
+
+   printf("bolshevic.a = %d\n", bolshevic.a);
+   printf("bolshevic.b = %d\n", bolshevic.b);
+   printf("bolshevic.c = %d\n", bolshevic.c);
+
+   struct ziggy *tsar = &bolshevic;
+
+   printf("tsar->a = %d\n", tsar->a);
+   printf("tsar->b = %d\n", tsar->b);
+   printf("tsar->c = %d\n", tsar->c);
+
+   b = &(bolshevic.b);
+   printf("bolshevic.b = %d\n", *b);
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/10_pointer.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/10_pointer.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/10_pointer.expect	(revision 331)
@@ -0,0 +1,8 @@
+a = 42
+bolshevic.a = 12
+bolshevic.b = 34
+bolshevic.c = 56
+tsar->a = 12
+tsar->b = 34
+tsar->c = 56
+bolshevic.b = 34
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/11_precedence.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/11_precedence.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/11_precedence.c	(revision 331)
@@ -0,0 +1,40 @@
+#include <stdio.h>
+
+int main()
+{
+   int a;
+   int b;
+   int c;
+   int d;
+   int e;
+   int f;
+   int x;
+   int y;
+
+   a = 12;
+   b = 34;
+   c = 56;
+   d = 78;
+   e = 0;
+   f = 1;
+
+   printf("%d\n", c + d);
+   printf("%d\n", (y = c + d));
+   printf("%d\n", e || e && f);
+   printf("%d\n", e || f && f);
+   printf("%d\n", e && e || f);
+   printf("%d\n", e && f || f);
+   printf("%d\n", a && f | f);
+   printf("%d\n", a | b ^ c & d);
+   printf("%d, %d\n", a == a, a == b);
+   printf("%d, %d\n", a != a, a != b);
+   printf("%d\n", a != b && c != d);
+   printf("%d\n", a + b * c / f);
+   printf("%d\n", a + b * c / f);
+   printf("%d\n", (4 << 4));
+   printf("%d\n", (64 >> 4));
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/11_precedence.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/11_precedence.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/11_precedence.expect	(revision 331)
@@ -0,0 +1,15 @@
+134
+134
+0
+1
+1
+1
+1
+46
+1, 0
+0, 1
+1
+1916
+1916
+64
+4
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/12_hashdefine.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/12_hashdefine.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/12_hashdefine.c	(revision 331)
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+#define FRED 12
+#define BLOGGS(x) (12*(x))
+
+int main()
+{
+   printf("%d\n", FRED);
+   printf("%d, %d, %d\n", BLOGGS(1), BLOGGS(2), BLOGGS(3));
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/12_hashdefine.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/12_hashdefine.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/12_hashdefine.expect	(revision 331)
@@ -0,0 +1,2 @@
+12
+12, 24, 36
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/13_integer_literals.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/13_integer_literals.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/13_integer_literals.c	(revision 331)
@@ -0,0 +1,20 @@
+#include <stdio.h>
+
+int main()
+{
+   int a = 24680;
+   int b = 01234567;
+   int c = 0x2468ac;
+   int d = 0x2468AC;
+   int e = 0b010101010101;
+
+   printf("%d\n", a);
+   printf("%d\n", b);
+   printf("%d\n", c);
+   printf("%d\n", d);
+   printf("%d\n", e);
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/13_integer_literals.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/13_integer_literals.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/13_integer_literals.expect	(revision 331)
@@ -0,0 +1,5 @@
+24680
+342391
+2386092
+2386092
+1365
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/14_if.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/14_if.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/14_if.c	(revision 331)
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int main()
+{
+   int a = 1;
+
+   if (a)
+      printf("a is true\n");
+   else
+      printf("a is false\n");
+
+   int b = 0;
+   if (b)
+      printf("b is true\n");
+   else
+      printf("b is false\n");
+
+   return 0;
+}
+
+// vim: set expandtab ts=4 sw=3 sts=3 tw=80 :
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/14_if.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/14_if.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/14_if.expect	(revision 331)
@@ -0,0 +1,2 @@
+a is true
+b is false
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/15_recursion.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/15_recursion.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/15_recursion.c	(revision 331)
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int factorial(int i) 
+{
+   if (i < 2)
+      return i;
+   else
+      return i * factorial(i - 1);
+}
+
+int main()
+{
+   int Count;
+
+   for (Count = 1; Count <= 10; Count++)
+      printf("%d\n", factorial(Count));
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/15_recursion.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/15_recursion.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/15_recursion.expect	(revision 331)
@@ -0,0 +1,10 @@
+1
+2
+6
+24
+120
+720
+5040
+40320
+362880
+3628800
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/16_nesting.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/16_nesting.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/16_nesting.c	(revision 331)
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int main()
+{
+   int x, y, z;
+
+   for (x = 0; x < 2; x++)
+   {
+      for (y = 0; y < 3; y++)
+      {
+         for (z = 0; z < 3; z++)
+         {
+            printf("%d %d %d\n", x, y, z);
+         }
+      }
+   }
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/16_nesting.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/16_nesting.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/16_nesting.expect	(revision 331)
@@ -0,0 +1,18 @@
+0 0 0
+0 0 1
+0 0 2
+0 1 0
+0 1 1
+0 1 2
+0 2 0
+0 2 1
+0 2 2
+1 0 0
+1 0 1
+1 0 2
+1 1 0
+1 1 1
+1 1 2
+1 2 0
+1 2 1
+1 2 2
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/17_enum.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/17_enum.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/17_enum.c	(revision 331)
@@ -0,0 +1,72 @@
+#include <stdio.h>
+
+enum fred
+{
+   a,
+   b,
+   c,
+   d,
+   e = 54,
+   f = 73,
+   g,
+   h
+};
+
+/* All following uses of enum efoo should compile
+   without warning.  While forward enums aren't ISO C,
+   it's accepted by GCC also in strict mode, and only warned
+   about with -pedantic.  This happens in the real world.  */
+/* Strict ISO C doesn't allow this kind of forward declaration of
+   enums, but GCC accepts it (and gives only pedantic warning), and
+   it occurs in the wild.  */
+enum efoo;
+struct Sforward_use {
+    int (*fmember) (enum efoo x);
+};
+
+extern enum efoo it_real_fn(void);
+enum efoo {
+  ONE,
+  TWO,
+};
+struct S2 {
+  enum efoo (*f2) (void);
+};
+void should_compile(struct S2 *s)
+{
+  s->f2 = it_real_fn;
+}
+
+enum efoo it_real_fn(void)
+{
+  return TWO;
+}
+
+static unsigned int deref_uintptr(unsigned int *p)
+{
+  return *p;
+}
+
+enum Epositive {
+    epos_one, epos_two
+};
+
+int main()
+{
+   enum fred frod;
+   enum Epositive epos = epos_two;
+
+   printf("%d %d %d %d %d %d %d %d\n", a, b, c, d, e, f, g, h);
+   /* printf("%d\n", frod); */
+   frod = 12;
+   printf("%d\n", frod);
+   frod = e;
+   printf("%d\n", frod);
+
+   /* Following should compile without warning.  */
+   printf ("enum to int: %u\n", deref_uintptr(&epos));
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/17_enum.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/17_enum.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/17_enum.expect	(revision 331)
@@ -0,0 +1,4 @@
+0 1 2 3 54 73 74 75
+12
+54
+enum to int: 1
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/18_include.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/18_include.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/18_include.c	(revision 331)
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+int main()
+{
+   printf("including\n");
+#include "18_include.h"
+   printf("done\n");
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/18_include.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/18_include.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/18_include.expect	(revision 331)
@@ -0,0 +1,3 @@
+including
+included
+done
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/18_include.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/18_include.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/18_include.h	(revision 331)
@@ -0,0 +1,1 @@
+printf("included\n");
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.c	(revision 331)
@@ -0,0 +1,28 @@
+#include <stdio.h>
+
+int main()
+{
+   int a;
+   int *b;
+   int *c;
+
+   a = 42;
+   b = &a;
+   c = NULL;
+
+   printf("%d\n", *b);
+
+   if (b == NULL)
+      printf("b is NULL\n");
+   else
+      printf("b is not NULL\n");
+
+   if (c == NULL)
+      printf("c is NULL\n");
+   else
+      printf("c is not NULL\n");
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/19_pointer_arithmetic.expect	(revision 331)
@@ -0,0 +1,3 @@
+42
+b is not NULL
+c is NULL
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/20_pointer_comparison.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/20_pointer_comparison.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/20_pointer_comparison.c	(revision 331)
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+int main()
+{
+   int a;
+   int b;
+   int *d;
+   int *e;
+   d = &a;
+   e = &b;
+   a = 12;
+   b = 34;
+   printf("%d\n", *d);
+   printf("%d\n", *e);
+   printf("%d\n", d == e);
+   printf("%d\n", d != e);
+   d = e;
+   printf("%d\n", d == e);
+   printf("%d\n", d != e);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/20_pointer_comparison.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/20_pointer_comparison.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/20_pointer_comparison.expect	(revision 331)
@@ -0,0 +1,6 @@
+12
+34
+0
+1
+1
+0
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/21_char_array.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/21_char_array.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/21_char_array.c	(revision 331)
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+int main()
+{
+   int x = 'a';
+   char y = x;
+
+   char *a = "hello";
+
+   printf("%s\n", a);
+
+   int c;
+   c = *a;
+
+   char *b;
+   for (b = a; *b != 0; b++)
+      printf("%c: %d\n", *b, *b);
+
+   char destarray[10];
+   char *dest = &destarray[0];
+   char *src = a;
+
+   while (*src != 0)
+      *dest++ = *src++;
+
+   *dest = 0;
+
+   printf("copied string is %s\n", destarray);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/21_char_array.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/21_char_array.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/21_char_array.expect	(revision 331)
@@ -0,0 +1,7 @@
+hello
+h: 104
+e: 101
+l: 108
+l: 108
+o: 111
+copied string is hello
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/22_floating_point.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/22_floating_point.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/22_floating_point.c	(revision 331)
@@ -0,0 +1,50 @@
+#include <stdio.h>
+#include <math.h>
+
+int main()
+{
+   // variables
+   float a = 12.34 + 56.78;
+   printf("%f\n", a);
+
+   // infix operators
+   printf("%f\n", 12.34 + 56.78);
+   printf("%f\n", 12.34 - 56.78);
+   printf("%f\n", 12.34 * 56.78);
+   printf("%f\n", 12.34 / 56.78);
+
+   // comparison operators
+   printf("%d %d %d %d %d %d\n", 12.34 < 56.78, 12.34 <= 56.78, 12.34 == 56.78, 12.34 >= 56.78, 12.34 > 56.78, 12.34 != 56.78);
+   printf("%d %d %d %d %d %d\n", 12.34 < 12.34, 12.34 <= 12.34, 12.34 == 12.34, 12.34 >= 12.34, 12.34 > 12.34, 12.34 != 12.34);
+   printf("%d %d %d %d %d %d\n", 56.78 < 12.34, 56.78 <= 12.34, 56.78 == 12.34, 56.78 >= 12.34, 56.78 > 12.34, 56.78 != 12.34);
+
+   // assignment operators
+   a = 12.34;
+   a += 56.78;
+   printf("%f\n", a);
+
+   a = 12.34;
+   a -= 56.78;
+   printf("%f\n", a);
+
+   a = 12.34;
+   a *= 56.78;
+   printf("%f\n", a);
+
+   a = 12.34;
+   a /= 56.78;
+   printf("%f\n", a);
+
+   // prefix operators
+   printf("%f\n", +12.34);
+   printf("%f\n", -12.34);
+
+   // type coercion
+   a = 2;
+   printf("%f\n", a);
+   printf("%f\n", sin(2));
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/22_floating_point.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/22_floating_point.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/22_floating_point.expect	(revision 331)
@@ -0,0 +1,16 @@
+69.120003
+69.120000
+-44.440000
+700.665200
+0.217330
+1 1 0 0 0 1
+0 1 1 1 0 0
+0 0 0 1 1 1
+69.120003
+-44.439999
+700.665222
+0.217330
+12.340000
+-12.340000
+2.000000
+0.909297
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/23_type_coercion.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/23_type_coercion.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/23_type_coercion.c	(revision 331)
@@ -0,0 +1,54 @@
+#include <stdio.h>
+
+void charfunc(char a)
+{
+   printf("char: %c\n", a);
+}
+
+void intfunc(int a)
+{
+   printf("int: %d\n", a);
+}
+
+void floatfunc(float a)
+{
+   printf("float: %f\n", a);
+}
+
+int main()
+{
+   charfunc('a');
+   charfunc(98);
+   charfunc(99.0);
+
+   intfunc('a');
+   intfunc(98);
+   intfunc(99.0);
+
+   floatfunc('a');
+   floatfunc(98);
+   floatfunc(99.0);
+
+   /* printf("%c %d %f\n", 'a', 'b', 'c'); */
+   /* printf("%c %d %f\n", 97, 98, 99); */
+   /* printf("%c %d %f\n", 97.0, 98.0, 99.0); */
+
+   char b = 97;
+   char c = 97.0;
+
+   printf("%d %d\n", b, c);
+
+   int d = 'a';
+   int e = 97.0;
+
+   printf("%d %d\n", d, e);
+
+   float f = 'a';
+   float g = 97;
+
+   printf("%f %f\n", f, g);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/23_type_coercion.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/23_type_coercion.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/23_type_coercion.expect	(revision 331)
@@ -0,0 +1,12 @@
+char: a
+char: b
+char: c
+int: 97
+int: 98
+int: 99
+float: 97.000000
+float: 98.000000
+float: 99.000000
+97 97
+97 97
+97.000000 97.000000
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/24_math_library.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/24_math_library.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/24_math_library.c	(revision 331)
@@ -0,0 +1,30 @@
+#define _ISOC99_SOURCE 1
+
+#include <stdio.h>
+#include <math.h>
+
+int main()
+{
+   printf("%f\n", sin(0.12));
+   printf("%f\n", cos(0.12));
+   printf("%f\n", tan(0.12));
+   printf("%f\n", asin(0.12));
+   printf("%f\n", acos(0.12));
+   printf("%f\n", atan(0.12));
+   printf("%f\n", sinh(0.12));
+   printf("%f\n", cosh(0.12));
+   printf("%f\n", tanh(0.12));
+   printf("%f\n", exp(0.12));
+   printf("%f\n", fabs(-0.12));
+   printf("%f\n", log(0.12));
+   printf("%f\n", log10(0.12));
+   printf("%f\n", pow(0.12, 0.12));
+   printf("%f\n", sqrt(0.12));
+   printf("%f\n", round(12.34));
+   printf("%f\n", ceil(12.34));
+   printf("%f\n", floor(12.34));
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/24_math_library.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/24_math_library.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/24_math_library.expect	(revision 331)
@@ -0,0 +1,18 @@
+0.119712
+0.992809
+0.120579
+0.120290
+1.450506
+0.119429
+0.120288
+1.007209
+0.119427
+1.127497
+0.120000
+-2.120264
+-0.920819
+0.775357
+0.346410
+12.000000
+13.000000
+12.000000
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/25_quicksort.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/25_quicksort.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/25_quicksort.c	(revision 331)
@@ -0,0 +1,83 @@
+#include <stdio.h>
+
+int array[16];
+
+//Swap integer values by array indexes
+void swap(int a, int b)
+{
+   int tmp  = array[a];
+   array[a] = array[b];
+   array[b] = tmp;
+}
+
+//Partition the array into two halves and return the
+//index about which the array is partitioned
+int partition(int left, int right)
+{
+   int pivotIndex = left;
+   int pivotValue = array[pivotIndex];
+   int index = left;
+   int i;
+
+   swap(pivotIndex, right);
+   for(i = left; i < right; i++)
+   {
+      if(array[i] < pivotValue)
+      {
+         swap(i, index);
+         index += 1;
+      }
+   }
+   swap(right, index);
+
+   return index;
+}
+
+//Quicksort the array
+void quicksort(int left, int right)
+{
+   if(left >= right)
+      return;
+
+   int index = partition(left, right);
+   quicksort(left, index - 1);
+   quicksort(index + 1, right);
+}
+
+int main()
+{
+   int i;
+
+   array[0] = 62;
+   array[1] = 83;
+   array[2] = 4;
+   array[3] = 89;
+   array[4] = 36;
+   array[5] = 21;
+   array[6] = 74;
+   array[7] = 37;
+   array[8] = 65;
+   array[9] = 33;
+   array[10] = 96;
+   array[11] = 38;
+   array[12] = 53;
+   array[13] = 16;
+   array[14] = 74;
+   array[15] = 55;
+
+   for (i = 0; i < 16; i++)
+      printf("%d ", array[i]);
+
+   printf("\n");
+
+   quicksort(0, 15);
+
+   for (i = 0; i < 16; i++)
+      printf("%d ", array[i]);
+
+   printf("\n");
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/25_quicksort.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/25_quicksort.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/25_quicksort.expect	(revision 331)
@@ -0,0 +1,2 @@
+62 83 4 89 36 21 74 37 65 33 96 38 53 16 74 55 
+4 16 21 33 36 37 38 53 55 62 65 74 74 83 89 96 
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/26_character_constants.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/26_character_constants.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/26_character_constants.c	(revision 331)
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+int main()
+{
+   printf("%d\n", '\1');
+   printf("%d\n", '\10');
+   printf("%d\n", '\100');
+   printf("%d\n", '\x01');
+   printf("%d\n", '\x0e');
+   printf("%d\n", '\x10');
+   printf("%d\n", '\x40');
+   printf("test \x40\n");
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/26_character_constants.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/26_character_constants.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/26_character_constants.expect	(revision 331)
@@ -0,0 +1,8 @@
+1
+8
+64
+1
+14
+16
+64
+test @
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/27_sizeof.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/27_sizeof.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/27_sizeof.c	(revision 331)
@@ -0,0 +1,18 @@
+#include <stdio.h>
+
+int main()
+{
+   char a;
+   int b;
+   double c;
+
+   printf("%d\n", sizeof(a));
+   printf("%d\n", sizeof(b));
+   printf("%d\n", sizeof(c));
+
+   printf("%d\n", sizeof(!a));
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/27_sizeof.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/27_sizeof.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/27_sizeof.expect	(revision 331)
@@ -0,0 +1,4 @@
+1
+4
+8
+4
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/28_strings.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/28_strings.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/28_strings.c	(revision 331)
@@ -0,0 +1,45 @@
+#include <stdio.h>
+#include <string.h>
+
+int main()
+{
+   char a[10];
+
+   strcpy(a, "hello");
+   printf("%s\n", a);
+
+   strncpy(a, "gosh", 2);
+   printf("%s\n", a);
+
+   printf("%d\n", strcmp(a, "apple") > 0);
+   printf("%d\n", strcmp(a, "goere") > 0);
+   printf("%d\n", strcmp(a, "zebra") < 0);
+
+   printf("%d\n", strlen(a));
+
+   strcat(a, "!");
+   printf("%s\n", a);
+
+   printf("%d\n", strncmp(a, "apple", 2) > 0);
+   printf("%d\n", strncmp(a, "goere", 2) == 0);
+   printf("%d\n", strncmp(a, "goerg", 2) == 0);
+   printf("%d\n", strncmp(a, "zebra", 2) < 0);
+
+   printf("%s\n", strchr(a, 'o'));
+   printf("%s\n", strrchr(a, 'l'));
+   printf("%d\n", strrchr(a, 'x') == NULL);
+
+   memset(&a[1], 'r', 4);
+   printf("%s\n", a);
+
+   memcpy(&a[2], a, 2);
+   printf("%s\n", a);
+
+   printf("%d\n", memcmp(a, "apple", 4) > 0);
+   printf("%d\n", memcmp(a, "grgr", 4) == 0);
+   printf("%d\n", memcmp(a, "zebra", 4) < 0);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/28_strings.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/28_strings.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/28_strings.expect	(revision 331)
@@ -0,0 +1,19 @@
+hello
+gollo
+1
+1
+1
+5
+gollo!
+1
+1
+1
+1
+ollo!
+lo!
+1
+grrrr!
+grgrr!
+1
+1
+1
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/29_array_address.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/29_array_address.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/29_array_address.c	(revision 331)
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <string.h>
+
+int main()
+{
+   char a[10];
+   strcpy(a, "abcdef");
+   printf("%s\n", &a[1]);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/29_array_address.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/29_array_address.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/29_array_address.expect	(revision 331)
@@ -0,0 +1,1 @@
+bcdef
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/30_hanoi.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/30_hanoi.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/30_hanoi.c	(revision 331)
@@ -0,0 +1,122 @@
+/* example from http://barnyard.syr.edu/quickies/hanoi.c */
+
+/* hanoi.c: solves the tower of hanoi problem. (Programming exercise.) */
+/* By Terry R. McConnell (12/2/97) */
+/* Compile: cc -o hanoi hanoi.c */
+
+/* This program does no error checking. But then, if it's right, 
+   it's right ... right ? */
+
+
+/* The original towers of hanoi problem seems to have been originally posed
+   by one M. Claus in 1883. There is a popular legend that goes along with
+   it that has been often repeated and paraphrased. It goes something like this:
+   In the great temple at Benares there are 3 golden spikes. On one of them,
+   God placed 64 disks increasing in size from bottom to top, at the beginning
+   of time. Since then, and to this day, the priest on duty constantly transfers
+   disks, one at a time, in such a way that no larger disk is ever put on top
+   of a smaller one. When the disks have been transferred entirely to another
+   spike the Universe will come to an end in a large thunderclap.
+
+   This paraphrases the original legend due to DeParville, La Nature, Paris 1884,
+   Part I, 285-286. For this and further information see: Mathematical 
+   Recreations & Essays, W.W. Rouse Ball, MacMillan, NewYork, 11th Ed. 1967,
+   303-305.
+ *
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define TRUE 1
+#define FALSE 0
+
+/* This is the number of "disks" on tower A initially. Taken to be 64 in the
+ * legend. The number of moves required, in general, is 2^N - 1. For N = 64,
+ * this is 18,446,744,073,709,551,615 */
+#define N 4
+
+/* These are the three towers. For example if the state of A is 0,1,3,4, that
+ * means that there are three discs on A of sizes 1, 3, and 4. (Think of right
+ * as being the "down" direction.) */
+int A[N], B[N], C[N]; 
+
+void Hanoi(int,int*,int*,int*);
+
+/* Print the current configuration of A, B, and C to the screen */
+void PrintAll()
+{
+   int i;
+
+   printf("A: ");
+   for(i=0;i<N;i++)printf(" %d ",A[i]);
+   printf("\n");
+
+   printf("B: ");
+   for(i=0;i<N;i++)printf(" %d ",B[i]);
+   printf("\n");
+
+   printf("C: ");
+   for(i=0;i<N;i++)printf(" %d ",C[i]);
+   printf("\n");
+   printf("------------------------------------------\n");
+   return;
+}
+
+/* Move the leftmost nonzero element of source to dest, leave behind 0. */
+/* Returns the value moved (not used.) */
+int Move(int *source, int *dest)
+{
+   int i = 0, j = 0;
+
+   while (i<N && (source[i])==0) i++;
+   while (j<N && (dest[j])==0) j++;
+
+   dest[j-1] = source[i];
+   source[i] = 0;
+   PrintAll();       /* Print configuration after each move. */
+   return dest[j-1];
+}
+
+
+/* Moves first n nonzero numbers from source to dest using the rules of Hanoi.
+   Calls itself recursively.
+   */
+void Hanoi(int n,int *source, int *dest, int *spare)
+{
+   int i;
+   if(n==1){
+      Move(source,dest);
+      return;
+   }
+
+   Hanoi(n-1,source,spare,dest);
+   Move(source,dest);
+   Hanoi(n-1,spare,dest,source);	
+   return;
+}
+
+int main()
+{
+   int i;
+
+   /* initialize the towers */
+   for(i=0;i<N;i++)A[i]=i+1;
+   for(i=0;i<N;i++)B[i]=0;
+   for(i=0;i<N;i++)C[i]=0;
+
+   printf("Solution of Tower of Hanoi Problem with %d Disks\n\n",N);
+
+   /* Print the starting state */
+   printf("Starting state:\n");
+   PrintAll();
+   printf("\n\nSubsequent states:\n\n");
+
+   /* Do it! Use A = Source, B = Destination, C = Spare */
+   Hanoi(N,A,B,C);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/30_hanoi.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/30_hanoi.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/30_hanoi.expect	(revision 331)
@@ -0,0 +1,71 @@
+Solution of Tower of Hanoi Problem with 4 Disks
+
+Starting state:
+A:  1  2  3  4 
+B:  0  0  0  0 
+C:  0  0  0  0 
+------------------------------------------
+
+
+Subsequent states:
+
+A:  0  2  3  4 
+B:  0  0  0  0 
+C:  0  0  0  1 
+------------------------------------------
+A:  0  0  3  4 
+B:  0  0  0  2 
+C:  0  0  0  1 
+------------------------------------------
+A:  0  0  3  4 
+B:  0  0  1  2 
+C:  0  0  0  0 
+------------------------------------------
+A:  0  0  0  4 
+B:  0  0  1  2 
+C:  0  0  0  3 
+------------------------------------------
+A:  0  0  1  4 
+B:  0  0  0  2 
+C:  0  0  0  3 
+------------------------------------------
+A:  0  0  1  4 
+B:  0  0  0  0 
+C:  0  0  2  3 
+------------------------------------------
+A:  0  0  0  4 
+B:  0  0  0  0 
+C:  0  1  2  3 
+------------------------------------------
+A:  0  0  0  0 
+B:  0  0  0  4 
+C:  0  1  2  3 
+------------------------------------------
+A:  0  0  0  0 
+B:  0  0  1  4 
+C:  0  0  2  3 
+------------------------------------------
+A:  0  0  0  2 
+B:  0  0  1  4 
+C:  0  0  0  3 
+------------------------------------------
+A:  0  0  1  2 
+B:  0  0  0  4 
+C:  0  0  0  3 
+------------------------------------------
+A:  0  0  1  2 
+B:  0  0  3  4 
+C:  0  0  0  0 
+------------------------------------------
+A:  0  0  0  2 
+B:  0  0  3  4 
+C:  0  0  0  1 
+------------------------------------------
+A:  0  0  0  0 
+B:  0  2  3  4 
+C:  0  0  0  1 
+------------------------------------------
+A:  0  0  0  0 
+B:  1  2  3  4 
+C:  0  0  0  0 
+------------------------------------------
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/31_args.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/31_args.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/31_args.c	(revision 331)
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+   int Count;
+
+   printf("hello world %d\n", argc);
+   for (Count = 1; Count < argc; Count++)
+      printf("arg %d: %s\n", Count, argv[Count]);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/31_args.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/31_args.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/31_args.expect	(revision 331)
@@ -0,0 +1,6 @@
+hello world 6
+arg 1: arg1
+arg 2: arg2
+arg 3: arg3
+arg 4: arg4
+arg 5: arg5
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/32_led.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/32_led.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/32_led.c	(revision 331)
@@ -0,0 +1,266 @@
+/* example from http://barnyard.syr.edu/quickies/led.c */
+
+/* led.c: print out number as if on 7 line led display. I.e., write integer
+   given on command line like this:  
+      _   _       _  
+   |  _|  _| |_| |_  
+   | |_   _|   |  _| etc.
+
+   We assume the terminal behaves like a classical teletype. So the top
+   lines of all digits have to be printed first, then the middle lines of
+   all digits, etc.
+
+   By Terry R. McConnell
+
+compile: cc -o led led.c
+
+If you just want to link in the subroutine print_led that does all the
+work, compile with -DNO_MAIN, and declare the following in any source file
+that uses the call:
+
+extern void print_led(unsigned long x, char *buf);
+
+Bug: you cannot call repeatedly to print more than one number to a line.
+That would require curses or some other terminal API that allows moving the
+cursor to a previous line.
+
+*/
+
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define MAX_DIGITS 32
+#define NO_MAIN
+
+
+/* Print the top line of the digit d into buffer. 
+   Does not null terminate buffer. */
+
+void topline(int d, char *p){
+
+   *p++ = ' ';
+   switch(d){
+
+      /* all these have _ on top line */
+
+      case 0:
+      case 2:
+      case 3:
+      case 5:
+      case 7:
+      case 8:
+      case 9:
+         *p++ = '_';
+         break;
+      default:
+         *p++=' ';
+
+   }
+   *p++=' ';
+}
+
+/* Print the middle line of the digit d into the buffer. 
+   Does not null terminate. */
+
+void midline(int d, char *p){
+
+   switch(d){
+
+      /* those that have leading | on middle line */
+
+      case 0:
+      case 4:
+      case 5:
+      case 6:
+      case 8:
+      case 9:
+         *p++='|';
+         break;
+      default:
+         *p++=' ';	
+   }
+   switch(d){
+
+      /* those that have _ on middle line */
+
+      case 2:
+      case 3:
+      case 4:
+      case 5:
+      case 6:
+      case 8:
+      case 9:
+         *p++='_';
+         break;
+      default:
+         *p++=' ';
+
+   }
+   switch(d){
+
+      /* those that have closing | on middle line */
+
+      case 0:
+      case 1:
+      case 2:
+      case 3:
+      case 4:
+      case 7:
+      case 8:
+      case 9:
+         *p++='|';
+         break;
+      default:
+         *p++=' ';
+
+   }
+}
+
+/* Print the bottom line of the digit d. Does not null terminate. */
+
+void botline(int d, char *p){
+
+
+   switch(d){
+
+      /* those that have leading | on bottom line */
+
+      case 0:
+      case 2:
+      case 6:
+      case 8:
+         *p++='|';
+         break;
+      default:
+         *p++=' ';	
+   }
+   switch(d){
+
+      /* those that have _ on bottom line */
+
+      case 0:
+      case 2:
+      case 3:
+      case 5:
+      case 6:
+      case 8:
+         *p++='_';
+         break;
+      default:
+         *p++=' ';
+
+   }
+   switch(d){
+
+      /* those that have closing | on bottom line */
+
+      case 0:
+      case 1:
+      case 3:
+      case 4:
+      case 5:
+      case 6:
+      case 7:
+      case 8:
+      case 9:
+         *p++='|';
+         break;
+      default:
+         *p++=' ';
+
+   }
+}
+
+/* Write the led representation of integer to string buffer. */
+
+void print_led(unsigned long x, char *buf)
+{
+
+   int i=0,n;
+   static int d[MAX_DIGITS];
+
+
+   /* extract digits from x */
+
+   n = ( x == 0L ? 1 : 0 );  /* 0 is a digit, hence a special case */
+
+   while(x){
+      d[n++] = (int)(x%10L);
+      if(n >= MAX_DIGITS)break;
+      x = x/10L;
+   }
+
+   /* print top lines of all digits */
+
+   for(i=n-1;i>=0;i--){
+      topline(d[i],buf);
+      buf += 3;
+      *buf++=' ';
+   }
+   *buf++='\n'; /* move teletype to next line */
+
+   /* print middle lines of all digits */
+
+   for(i=n-1;i>=0;i--){
+      midline(d[i],buf);
+      buf += 3;
+      *buf++=' ';
+   }
+   *buf++='\n';
+
+   /* print bottom lines of all digits */
+
+   for(i=n-1;i>=0;i--){
+      botline(d[i],buf);
+      buf += 3;
+      *buf++=' ';
+   }
+   *buf++='\n';
+   *buf='\0';
+}
+
+int main()
+{
+   char buf[5*MAX_DIGITS];
+   print_led(1234567, buf);
+   printf("%s\n",buf);
+
+   return 0;
+}
+
+#ifndef NO_MAIN
+int main(int argc, char **argv)
+{
+
+   int i=0,n;
+   long x;
+   static int d[MAX_DIGITS];
+   char buf[5*MAX_DIGITS];
+
+   if(argc != 2){
+      fprintf(stderr,"led: usage: led integer\n");
+      return 1;
+   }
+
+   /* fetch argument from command line */
+
+   x = atol(argv[1]);
+
+   /* sanity check */
+
+   if(x<0){
+      fprintf(stderr,"led: %d must be non-negative\n",x);
+      return 1;
+   }
+
+   print_led(x,buf);
+   printf("%s\n",buf);
+
+   return 0;
+
+}
+#endif
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/32_led.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/32_led.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/32_led.expect	(revision 331)
@@ -0,0 +1,4 @@
+     _   _       _       _  
+  |  _|  _| |_| |_  |_    | 
+  | |_   _|   |  _| |_|   | 
+
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/33_ternary_op.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/33_ternary_op.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/33_ternary_op.c	(revision 331)
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int main()
+{
+   int Count;
+
+   for (Count = 0; Count < 10; Count++)
+   {
+      printf("%d\n", (Count < 5) ? (Count*Count) : (Count * 3));
+   }
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/33_ternary_op.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/33_ternary_op.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/33_ternary_op.expect	(revision 331)
@@ -0,0 +1,10 @@
+0
+1
+4
+9
+16
+15
+18
+21
+24
+27
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/34_array_assignment.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/34_array_assignment.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/34_array_assignment.c	(revision 331)
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+int main()
+{
+   int a[4];
+
+   a[0] = 12;
+   a[1] = 23;
+   a[2] = 34;
+   a[3] = 45;
+
+   printf("%d %d %d %d\n", a[0], a[1], a[2], a[3]);
+
+   int b[4];
+
+   b = a;
+
+   printf("%d %d %d %d\n", b[0], b[1], b[2], b[3]);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/34_array_assignment.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/34_array_assignment.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/34_array_assignment.expect	(revision 331)
@@ -0,0 +1,2 @@
+12 23 34 45
+12 23 34 45
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/35_sizeof.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/35_sizeof.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/35_sizeof.c	(revision 331)
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+int main()
+{
+   char a;
+   short b;
+
+   printf("%d %d\n", sizeof(char), sizeof(a));
+   printf("%d %d\n", sizeof(short), sizeof(b));
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/35_sizeof.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/35_sizeof.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/35_sizeof.expect	(revision 331)
@@ -0,0 +1,2 @@
+1 1
+2 2
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/36_array_initialisers.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/36_array_initialisers.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/36_array_initialisers.c	(revision 331)
@@ -0,0 +1,21 @@
+#include <stdio.h>
+
+int main()
+{
+   int Count;
+
+   int Array[10] = { 12, 34, 56, 78, 90, 123, 456, 789, 8642, 9753 };
+
+   for (Count = 0; Count < 10; Count++)
+      printf("%d: %d\n", Count, Array[Count]);
+
+   int Array2[10] = { 12, 34, 56, 78, 90, 123, 456, 789, 8642, 9753, };
+
+   for (Count = 0; Count < 10; Count++)
+      printf("%d: %d\n", Count, Array2[Count]);
+
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/36_array_initialisers.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/36_array_initialisers.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/36_array_initialisers.expect	(revision 331)
@@ -0,0 +1,20 @@
+0: 12
+1: 34
+2: 56
+3: 78
+4: 90
+5: 123
+6: 456
+7: 789
+8: 8642
+9: 9753
+0: 12
+1: 34
+2: 56
+3: 78
+4: 90
+5: 123
+6: 456
+7: 789
+8: 8642
+9: 9753
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/37_sprintf.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/37_sprintf.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/37_sprintf.c	(revision 331)
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+int main()
+{
+   char Buf[100];
+   int Count;
+
+   for (Count = 1; Count <= 20; Count++)
+   {
+      sprintf(Buf, "->%02d<-\n", Count);
+      printf("%s", Buf);
+   }
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/37_sprintf.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/37_sprintf.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/37_sprintf.expect	(revision 331)
@@ -0,0 +1,20 @@
+->01<-
+->02<-
+->03<-
+->04<-
+->05<-
+->06<-
+->07<-
+->08<-
+->09<-
+->10<-
+->11<-
+->12<-
+->13<-
+->14<-
+->15<-
+->16<-
+->17<-
+->18<-
+->19<-
+->20<-
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/38_multiple_array_index.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/38_multiple_array_index.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/38_multiple_array_index.c	(revision 331)
@@ -0,0 +1,32 @@
+#include <stdio.h>
+
+int main()
+{
+   int a[4][4];
+   int b = 0;
+   int x;
+   int y;
+
+   for (x = 0; x < 4; x++)
+   {
+      for (y = 0; y < 4; y++)
+      {
+         b++;
+         a[x][y] = b;
+      }
+   }
+
+   for (x = 0; x < 4; x++)
+   {
+      printf("x=%d: ", x);
+      for (y = 0; y < 4; y++)
+      {
+         printf("%d ", a[x][y]);
+      }
+      printf("\n");
+   }
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/38_multiple_array_index.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/38_multiple_array_index.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/38_multiple_array_index.expect	(revision 331)
@@ -0,0 +1,4 @@
+x=0: 1 2 3 4
+x=1: 5 6 7 8
+x=2: 9 10 11 12
+x=3: 13 14 15 16 
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/39_typedef.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/39_typedef.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/39_typedef.c	(revision 331)
@@ -0,0 +1,65 @@
+#include <stdio.h>
+
+typedef int MyInt;
+
+struct FunStruct
+{
+   int i;
+   int j;
+};
+
+typedef struct FunStruct MyFunStruct;
+
+typedef MyFunStruct *MoreFunThanEver;
+
+int main()
+{
+   MyInt a = 1;
+   printf("%d\n", a);
+
+   MyFunStruct b;
+   b.i = 12;
+   b.j = 34;
+   printf("%d,%d\n", b.i, b.j);
+
+   MoreFunThanEver c = &b;
+   printf("%d,%d\n", c->i, c->j);
+
+   return 0;
+}
+
+/* "If the specification of an array type includes any type qualifiers,
+   the element type is so-qualified, not the array type." */
+
+typedef int A[3];
+extern A const ca;
+extern const A ca;
+extern const int ca[3];
+
+typedef A B[1][2];
+extern B const cb;
+extern const B cb;
+extern const int cb[1][2][3];
+
+extern B b;
+extern int b[1][2][3];
+
+/* Funny but valid function declaration.  */
+typedef int functype (int);
+extern functype func;
+int func(int i)
+{
+   return i + 1;
+}
+
+/* Even funnier function decl and definition using typeof.  */
+int set_anon_super(void);
+int set_anon_super(void)
+{
+   return 42;
+}
+typedef int sas_type (void);
+extern typeof(set_anon_super) set_anon_super;
+extern sas_type set_anon_super;
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/39_typedef.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/39_typedef.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/39_typedef.expect	(revision 331)
@@ -0,0 +1,3 @@
+1
+12,34
+12,34
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/40_stdio.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/40_stdio.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/40_stdio.c	(revision 331)
@@ -0,0 +1,52 @@
+#include <stdio.h>
+
+int main()
+{
+   FILE *f = fopen("fred.txt", "w");
+   fwrite("hello\nhello\n", 1, 12, f);
+   fclose(f);
+
+   char freddy[7];
+   f = fopen("fred.txt", "r");
+   if (fread(freddy, 1, 6, f) != 6)
+      printf("couldn't read fred.txt\n");
+
+   freddy[6] = '\0';
+   fclose(f);
+
+   printf("%s", freddy);
+
+   int InChar;
+   char ShowChar;
+   f = fopen("fred.txt", "r");
+   while ( (InChar = fgetc(f)) != EOF)
+   {
+      ShowChar = InChar;
+      if (ShowChar < ' ')
+         ShowChar = '.';
+
+      printf("ch: %d '%c'\n", InChar, ShowChar);
+   }
+   fclose(f);
+
+   f = fopen("fred.txt", "r");
+   while ( (InChar = getc(f)) != EOF)
+   {
+      ShowChar = InChar;
+      if (ShowChar < ' ')
+         ShowChar = '.';
+
+      printf("ch: %d '%c'\n", InChar, ShowChar);
+   }
+   fclose(f);
+
+   f = fopen("fred.txt", "r");
+   while (fgets(freddy, sizeof(freddy), f) != NULL)
+      printf("x: %s", freddy);
+
+   fclose(f);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/40_stdio.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/40_stdio.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/40_stdio.expect	(revision 331)
@@ -0,0 +1,27 @@
+hello
+ch: 104 'h'
+ch: 101 'e'
+ch: 108 'l'
+ch: 108 'l'
+ch: 111 'o'
+ch: 10 '.'
+ch: 104 'h'
+ch: 101 'e'
+ch: 108 'l'
+ch: 108 'l'
+ch: 111 'o'
+ch: 10 '.'
+ch: 104 'h'
+ch: 101 'e'
+ch: 108 'l'
+ch: 108 'l'
+ch: 111 'o'
+ch: 10 '.'
+ch: 104 'h'
+ch: 101 'e'
+ch: 108 'l'
+ch: 108 'l'
+ch: 111 'o'
+ch: 10 '.'
+x: hello
+x: hello
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/41_hashif.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/41_hashif.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/41_hashif.c	(revision 331)
@@ -0,0 +1,85 @@
+#include <stdio.h>
+
+int main()
+{
+   printf("#include test\n");
+
+#if 1
+#if 0
+   printf("a\n");
+#else
+   printf("b\n");
+#endif
+#else
+#if 0
+   printf("c\n");
+#else
+   printf("d\n");
+#endif
+#endif
+
+#if 0
+#if 1
+   printf("e\n");
+#else
+   printf("f\n");
+#endif
+#else
+#if 1
+   printf("g\n");
+#else
+   printf("h\n");
+#endif
+#endif
+
+#define DEF
+
+#ifdef DEF
+#ifdef DEF
+   printf("i\n");
+#else
+   printf("j\n");
+#endif
+#else
+#ifdef DEF
+   printf("k\n");
+#else
+   printf("l\n");
+#endif
+#endif
+
+#ifndef DEF
+#ifndef DEF
+   printf("m\n");
+#else
+   printf("n\n");
+#endif
+#else
+#ifndef DEF
+   printf("o\n");
+#else
+   printf("p\n");
+#endif
+#endif
+
+#define ONE 1
+#define ZERO 0
+
+#if ONE
+#if ZERO
+   printf("q\n");
+#else
+   printf("r\n");
+#endif
+#else
+#if ZERO
+   printf("s\n");
+#else
+   printf("t\n");
+#endif
+#endif
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/41_hashif.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/41_hashif.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/41_hashif.expect	(revision 331)
@@ -0,0 +1,6 @@
+#include test
+b
+g
+i
+p
+r
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/42_function_pointer.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/42_function_pointer.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/42_function_pointer.c	(revision 331)
@@ -0,0 +1,22 @@
+#include <stdio.h>
+
+int fred(int p)
+{
+   printf("yo %d\n", p);
+   return 42;
+}
+
+int (*f)(int) = &fred;
+
+/* To test what this is supposed to test the destination function
+   (fprint here) must not be called directly anywhere in the test.  */
+int (*fprintfptr)(FILE *, const char *, ...) = &fprintf;
+
+int main()
+{
+   fprintfptr(stdout, "%d\n", (*f)(24));
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/42_function_pointer.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/42_function_pointer.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/42_function_pointer.expect	(revision 331)
@@ -0,0 +1,2 @@
+yo 24
+42
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/43_void_param.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/43_void_param.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/43_void_param.c	(revision 331)
@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+void fred(void)
+{
+   printf("yo\n");
+}
+
+int main()
+{
+   fred();
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/43_void_param.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/43_void_param.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/43_void_param.expect	(revision 331)
@@ -0,0 +1,1 @@
+yo
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/44_scoped_declarations.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/44_scoped_declarations.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/44_scoped_declarations.c	(revision 331)
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+int main()
+{
+   int a;
+
+   for (a = 0; a < 2; a++)
+   {
+      int b = a;
+   }
+
+   printf("it's all good\n");
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/44_scoped_declarations.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/44_scoped_declarations.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/44_scoped_declarations.expect	(revision 331)
@@ -0,0 +1,1 @@
+it's all good
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/45_empty_for.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/45_empty_for.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/45_empty_for.c	(revision 331)
@@ -0,0 +1,18 @@
+#include <stdio.h>
+
+int main()
+{
+   int Count = 0;
+
+   for (;;)
+   {
+      Count++;
+      printf("%d\n", Count);
+      if (Count >= 10)
+         break;
+   }
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/45_empty_for.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/45_empty_for.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/45_empty_for.expect	(revision 331)
@@ -0,0 +1,10 @@
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/46_grep.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/46_grep.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/46_grep.c	(revision 331)
@@ -0,0 +1,568 @@
+/*
+ * The  information  in  this  document  is  subject  to  change
+ * without  notice  and  should not be construed as a commitment
+ * by Digital Equipment Corporation or by DECUS.
+ *
+ * Neither Digital Equipment Corporation, DECUS, nor the authors
+ * assume any responsibility for the use or reliability of  this
+ * document or the described software.
+ *
+ *      Copyright (C) 1980, DECUS
+ *
+ * General permission to copy or modify, but not for profit,  is
+ * hereby  granted,  provided that the above copyright notice is
+ * included and reference made to  the  fact  that  reproduction
+ * privileges were granted by DECUS.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>	// tolower()
+
+/*
+ * grep
+ *
+ * Runs on the Decus compiler or on vms, On vms, define as:
+ *      grep :== "$disk:[account]grep"      (native)
+ *      grep :== "$disk:[account]grep grep" (Decus)
+ * See below for more information.
+ */
+
+char    *documentation[] = {
+   "grep searches a file for a given pattern.  Execute by",
+   "   grep [flags] regular_expression file_list\n",
+   "Flags are single characters preceded by '-':",
+   "   -c      Only a count of matching lines is printed",
+   "   -f      Print file name for matching lines switch, see below",
+   "   -n      Each line is preceded by its line number",
+   "   -v      Only print non-matching lines\n",
+   "The file_list is a list of files (wildcards are acceptable on RSX modes).",
+   "\nThe file name is normally printed if there is a file given.",
+   "The -f flag reverses this action (print name no file, not if more).\n",
+   0 };
+
+char    *patdoc[] = {
+   "The regular_expression defines the pattern to search for.  Upper- and",
+   "lower-case are always ignored.  Blank lines never match.  The expression",
+   "should be quoted to prevent file-name translation.",
+   "x      An ordinary character (not mentioned below) matches that character.",
+   "'\\'    The backslash quotes any character.  \"\\$\" matches a dollar-sign.",
+   "'^'    A circumflex at the beginning of an expression matches the",
+   "       beginning of a line.",
+   "'$'    A dollar-sign at the end of an expression matches the end of a line.",
+   "'.'    A period matches any character except \"new-line\".",
+   "':a'   A colon matches a class of characters described by the following",
+   "':d'     character.  \":a\" matches any alphabetic, \":d\" matches digits,",
+   "':n'     \":n\" matches alphanumerics, \": \" matches spaces, tabs, and",
+   "': '     other control characters, such as new-line.",
+   "'*'    An expression followed by an asterisk matches zero or more",
+   "       occurrences of that expression: \"fo*\" matches \"f\", \"fo\"",
+   "       \"foo\", etc.",
+   "'+'    An expression followed by a plus sign matches one or more",
+   "       occurrences of that expression: \"fo+\" matches \"fo\", etc.",
+   "'-'    An expression followed by a minus sign optionally matches",
+   "       the expression.",
+   "'[]'   A string enclosed in square brackets matches any character in",
+   "       that string, but no others.  If the first character in the",
+   "       string is a circumflex, the expression matches any character",
+   "       except \"new-line\" and the characters in the string.  For",
+   "       example, \"[xyz]\" matches \"xx\" and \"zyx\", while \"[^xyz]\"",
+   "       matches \"abc\" but not \"axb\".  A range of characters may be",
+   "       specified by two characters separated by \"-\".  Note that,",
+   "       [a-z] matches alphabetics, while [z-a] never matches.",
+   "The concatenation of regular expressions is a regular expression.",
+   0};
+
+#define LMAX    512
+#define PMAX    256
+
+#define CHAR    1
+#define BOL     2
+#define EOL     3
+#define ANY     4
+#define CLASS   5
+#define NCLASS  6
+#define STAR    7
+#define PLUS    8
+#define MINUS   9
+#define ALPHA   10
+#define DIGIT   11
+#define NALPHA  12
+#define PUNCT   13
+#define RANGE   14
+#define ENDPAT  15
+
+int cflag=0, fflag=0, nflag=0, vflag=0, nfile=0, debug=0;
+
+char *pp, lbuf[LMAX], pbuf[PMAX];
+
+char *cclass();
+char *pmatch();
+void store(int);
+void error(char *);
+void badpat(char *, char *, char *);
+int match(void);
+
+
+/*** Display a file name *******************************/
+void file(char *s)
+{
+   printf("File %s:\n", s);
+}
+
+/*** Report unopenable file ****************************/
+void cant(char *s)
+{
+   fprintf(stderr, "%s: cannot open\n", s);
+}
+
+/*** Give good help ************************************/
+void help(char **hp)
+{
+   char   **dp;
+
+   for (dp = hp; *dp; ++dp)
+      printf("%s\n", *dp);
+}
+
+/*** Display usage summary *****************************/
+void usage(char *s)
+{
+   fprintf(stderr, "?GREP-E-%s\n", s);
+   fprintf(stderr,
+         "Usage: grep [-cfnv] pattern [file ...].  grep ? for help\n");
+   exit(1);
+}
+
+/*** Compile the pattern into global pbuf[] ************/
+void compile(char *source)
+{
+   char  *s;         /* Source string pointer     */
+   char  *lp;        /* Last pattern pointer      */
+   int   c;          /* Current character         */
+   int            o;          /* Temp                      */
+   char           *spp;       /* Save beginning of pattern */
+
+   s = source;
+   if (debug)
+      printf("Pattern = \"%s\"\n", s);
+   pp = pbuf;
+   while (c = *s++) {
+      /*
+       * STAR, PLUS and MINUS are special.
+       */
+      if (c == '*' || c == '+' || c == '-') {
+         if (pp == pbuf ||
+               (o=pp[-1]) == BOL ||
+               o == EOL ||
+               o == STAR ||
+               o == PLUS ||
+               o == MINUS)
+            badpat("Illegal occurrence op.", source, s);
+         store(ENDPAT);
+         store(ENDPAT);
+         spp = pp;               /* Save pattern end     */
+         while (--pp > lp)       /* Move pattern down    */
+            *pp = pp[-1];        /* one byte             */
+         *pp =   (c == '*') ? STAR :
+            (c == '-') ? MINUS : PLUS;
+         pp = spp;               /* Restore pattern end  */
+         continue;
+      }
+      /*
+       * All the rest.
+       */
+      lp = pp;         /* Remember start       */
+      switch(c) {
+
+         case '^':
+            store(BOL);
+            break;
+
+         case '$':
+            store(EOL);
+            break;
+
+         case '.':
+            store(ANY);
+            break;
+
+         case '[':
+            s = cclass(source, s);
+            break;
+
+         case ':':
+            if (*s) {
+               switch(tolower(c = *s++)) {
+
+                  case 'a':
+                  case 'A':
+                     store(ALPHA);
+                     break;
+
+                  case 'd':
+                  case 'D':
+                     store(DIGIT);
+                     break;
+
+                  case 'n':
+                  case 'N':
+                     store(NALPHA);
+                     break;
+
+                  case ' ':
+                     store(PUNCT);
+                     break;
+
+                  default:
+                     badpat("Unknown : type", source, s);
+
+               }
+               break;
+            }
+            else    badpat("No : type", source, s);
+
+         case '\\':
+            if (*s)
+               c = *s++;
+
+         default:
+            store(CHAR);
+            store(tolower(c));
+      }
+   }
+   store(ENDPAT);
+   store(0);                /* Terminate string     */
+   if (debug) {
+      for (lp = pbuf; lp < pp;) {
+         if ((c = (*lp++ & 0377)) < ' ')
+            printf("\\%o ", c);
+         else    printf("%c ", c);
+      }
+      printf("\n");
+   }
+}
+
+/*** Compile a class (within []) ***********************/
+char *cclass(char *source, char *src)
+   /* char       *source;   // Pattern start -- for error msg. */
+   /* char       *src;      // Class start */
+{
+   char   *s;        /* Source pointer    */
+   char   *cp;       /* Pattern start     */
+   int    c;         /* Current character */
+   int             o;         /* Temp              */
+
+   s = src;
+   o = CLASS;
+   if (*s == '^') {
+      ++s;
+      o = NCLASS;
+   }
+   store(o);
+   cp = pp;
+   store(0);                          /* Byte count      */
+   while ((c = *s++) && c!=']') {
+      if (c == '\\') {                /* Store quoted char    */
+         if ((c = *s++) == '\0')      /* Gotta get something  */
+            badpat("Class terminates badly", source, s);
+         else    store(tolower(c));
+      }
+      else if (c == '-' &&
+            (pp - cp) > 1 && *s != ']' && *s != '\0') {
+         c = pp[-1];             /* Range start     */
+         pp[-1] = RANGE;         /* Range signal    */
+         store(c);               /* Re-store start  */
+         c = *s++;               /* Get end char and*/
+         store(tolower(c));      /* Store it        */
+      }
+      else {
+         store(tolower(c));      /* Store normal char */
+      }
+   }
+   if (c != ']')
+      badpat("Unterminated class", source, s);
+   if ((c = (pp - cp)) >= 256)
+      badpat("Class too large", source, s);
+   if (c == 0)
+      badpat("Empty class", source, s);
+   *cp = c;
+   return(s);
+}
+
+/*** Store an entry in the pattern buffer **************/
+void store(int op)
+{
+   if (pp >= &pbuf[PMAX])
+      error("Pattern too complex\n");
+   *pp++ = op;
+}
+
+/*** Report a bad pattern specification ****************/
+void badpat(char *message, char *source, char *stop)
+   /* char  *message;       // Error message */
+   /* char  *source;        // Pattern start */
+   /* char  *stop;          // Pattern end   */
+{
+   fprintf(stderr, "-GREP-E-%s, pattern is\"%s\"\n", message, source);
+   fprintf(stderr, "-GREP-E-Stopped at byte %ld, '%c'\n",
+         stop-source, stop[-1]);
+   error("?GREP-E-Bad pattern\n");
+}
+
+/*** Scan the file for the pattern in pbuf[] ***********/
+void grep(FILE *fp, char *fn)
+   /* FILE       *fp;       // File to process            */
+   /* char       *fn;       // File name (for -f option)  */
+{
+   int lno, count, m;
+
+   lno = 0;
+   count = 0;
+   while (fgets(lbuf, LMAX, fp)) {
+      ++lno;
+      m = match();
+      if ((m && !vflag) || (!m && vflag)) {
+         ++count;
+         if (!cflag) {
+            if (fflag && fn) {
+               file(fn);
+               fn = 0;
+            }
+            if (nflag)
+               printf("%d\t", lno);
+            printf("%s\n", lbuf);
+         }
+      }
+   }
+   if (cflag) {
+      if (fflag && fn)
+         file(fn);
+      printf("%d\n", count);
+   }
+}
+
+/*** Match line (lbuf) with pattern (pbuf) return 1 if match ***/
+int match()
+{
+   char   *l;        /* Line pointer       */
+
+   for (l = lbuf; *l; ++l) {
+      if (pmatch(l, pbuf))
+         return(1);
+   }
+   return(0);
+}
+
+/*** Match partial line with pattern *******************/
+char *pmatch(char *line, char *pattern)
+   /* char               *line;     // (partial) line to match      */
+   /* char               *pattern;  // (partial) pattern to match   */
+{
+   char   *l;        /* Current line pointer         */
+   char   *p;        /* Current pattern pointer      */
+   char   c;         /* Current character            */
+   char            *e;        /* End for STAR and PLUS match  */
+   int             op;        /* Pattern operation            */
+   int             n;         /* Class counter                */
+   char            *are;      /* Start of STAR match          */
+
+   l = line;
+   if (debug > 1)
+      printf("pmatch(\"%s\")\n", line);
+   p = pattern;
+   while ((op = *p++) != ENDPAT) {
+      if (debug > 1)
+         printf("byte[%ld] = 0%o, '%c', op = 0%o\n",
+               l-line, *l, *l, op);
+      switch(op) {
+
+         case CHAR:
+            if (tolower(*l++) != *p++)
+               return(0);
+            break;
+
+         case BOL:
+            if (l != lbuf)
+               return(0);
+            break;
+
+         case EOL:
+            if (*l != '\0')
+               return(0);
+            break;
+
+         case ANY:
+            if (*l++ == '\0')
+               return(0);
+            break;
+
+         case DIGIT:
+            if ((c = *l++) < '0' || (c > '9'))
+               return(0);
+            break;
+
+         case ALPHA:
+            c = tolower(*l++);
+            if (c < 'a' || c > 'z')
+               return(0);
+            break;
+
+         case NALPHA:
+            c = tolower(*l++);
+            if (c >= 'a' && c <= 'z')
+               break;
+            else if (c < '0' || c > '9')
+               return(0);
+            break;
+
+         case PUNCT:
+            c = *l++;
+            if (c == 0 || c > ' ')
+               return(0);
+            break;
+
+         case CLASS:
+         case NCLASS:
+            c = tolower(*l++);
+            n = *p++ & 0377;
+            do {
+               if (*p == RANGE) {
+                  p += 3;
+                  n -= 2;
+                  if (c >= p[-2] && c <= p[-1])
+                     break;
+               }
+               else if (c == *p++)
+                  break;
+            } while (--n > 1);
+            if ((op == CLASS) == (n <= 1))
+               return(0);
+            if (op == CLASS)
+               p += n - 2;
+            break;
+
+         case MINUS:
+            e = pmatch(l, p);       /* Look for a match    */
+            while (*p++ != ENDPAT); /* Skip over pattern   */
+            if (e)                  /* Got a match?        */
+               l = e;               /* Yes, update string  */
+            break;                  /* Always succeeds     */
+
+         case PLUS:                 /* One or more ...     */
+            if ((l = pmatch(l, p)) == 0)
+               return(0);           /* Gotta have a match  */
+         case STAR:                 /* Zero or more ...    */
+            are = l;                /* Remember line start */
+            while (*l && (e = pmatch(l, p)))
+               l = e;               /* Get longest match   */
+            while (*p++ != ENDPAT); /* Skip over pattern   */
+            while (l >= are) {      /* Try to match rest   */
+               if (e = pmatch(l, p))
+                  return(e);
+               --l;                 /* Nope, try earlier   */
+            }
+            return(0);              /* Nothing else worked */
+
+         default:
+            printf("Bad op code %d\n", op);
+            error("Cannot happen -- match\n");
+      }
+   }
+   return(l);
+}
+
+/*** Report an error ***********************************/
+void error(char *s)
+{
+   fprintf(stderr, "%s", s);
+   exit(1);
+}
+
+/*** Main program - parse arguments & grep *************/
+int main(int argc, char **argv)
+{
+   char   *p;
+   int    c, i;
+   int             gotpattern;
+
+   FILE            *f;
+
+   if (argc <= 1)
+      usage("No arguments");
+   if (argc == 2 && argv[1][0] == '?' && argv[1][1] == 0) {
+      help(documentation);
+      help(patdoc);
+      return 0;
+   }
+   nfile = argc-1;
+   gotpattern = 0;
+   for (i=1; i < argc; ++i) {
+      p = argv[i];
+      if (*p == '-') {
+         ++p;
+         while (c = *p++) {
+            switch(tolower(c)) {
+
+               case '?':
+                  help(documentation);
+                  break;
+
+               case 'C':
+               case 'c':
+                  ++cflag;
+                  break;
+
+               case 'D':
+               case 'd':
+                  ++debug;
+                  break;
+
+               case 'F':
+               case 'f':
+                  ++fflag;
+                  break;
+
+               case 'n':
+               case 'N':
+                  ++nflag;
+                  break;
+
+               case 'v':
+               case 'V':
+                  ++vflag;
+                  break;
+
+               default:
+                  usage("Unknown flag");
+            }
+         }
+         argv[i] = 0;
+         --nfile;
+      } else if (!gotpattern) {
+         compile(p);
+         argv[i] = 0;
+         ++gotpattern;
+         --nfile;
+      }
+   }
+   if (!gotpattern)
+      usage("No pattern");
+   if (nfile == 0)
+      grep(stdin, 0);
+   else {
+      fflag = fflag ^ (nfile > 0);
+      for (i=1; i < argc; ++i) {
+         if (p = argv[i]) {
+            if ((f=fopen(p, "r")) == NULL)
+               cant(p);
+            else {
+               grep(f, p);
+               fclose(f);
+            }
+         }
+      }
+   }
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/46_grep.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/46_grep.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/46_grep.expect	(revision 331)
@@ -0,0 +1,3 @@
+File 46_grep.c:
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
+
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/47_switch_return.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/47_switch_return.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/47_switch_return.c	(revision 331)
@@ -0,0 +1,24 @@
+#include <stdio.h>
+
+void fred(int x)
+{
+   switch (x)
+   {
+      case 1: printf("1\n"); return;
+      case 2: printf("2\n"); break;
+      case 3: printf("3\n"); return;
+   }
+
+   printf("out\n");
+}
+
+int main()
+{
+   fred(1);
+   fred(2);
+   fred(3);
+
+   return 0;
+}    
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/47_switch_return.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/47_switch_return.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/47_switch_return.expect	(revision 331)
@@ -0,0 +1,4 @@
+1
+2
+out
+3
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/48_nested_break.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/48_nested_break.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/48_nested_break.c	(revision 331)
@@ -0,0 +1,26 @@
+#include <stdio.h>
+
+int main()
+{
+   int a;
+   char b;
+
+   a = 0;
+   while (a < 2)
+   {
+      printf("%d", a++);
+      break;
+
+      b = 'A';
+      while (b < 'C')
+      {
+         printf("%c", b++);
+      }
+      printf("e");
+   }
+   printf("\n");
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/48_nested_break.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/48_nested_break.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/48_nested_break.expect	(revision 331)
@@ -0,0 +1,1 @@
+0
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/49_bracket_evaluation.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/49_bracket_evaluation.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/49_bracket_evaluation.c	(revision 331)
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+struct point
+{
+   double x;
+   double y;
+};
+
+struct point point_array[100];
+
+int main()
+{
+   int my_point = 10;
+
+   point_array[my_point].x = 12.34;
+   point_array[my_point].y = 56.78;
+
+   printf("%f, %f\n", point_array[my_point].x, point_array[my_point].y);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/49_bracket_evaluation.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/49_bracket_evaluation.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/49_bracket_evaluation.expect	(revision 331)
@@ -0,0 +1,1 @@
+12.340000, 56.780000
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/50_logical_second_arg.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/50_logical_second_arg.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/50_logical_second_arg.c	(revision 331)
@@ -0,0 +1,29 @@
+#include <stdio.h>
+
+int fred()
+{
+   printf("fred\n");
+   return 0;
+}
+
+int joe()
+{
+   printf("joe\n");
+   return 1;
+}
+
+int main()
+{
+   printf("%d\n", fred() && joe());
+   printf("%d\n", fred() || joe());
+   printf("%d\n", joe() && fred());
+   printf("%d\n", joe() || fred());
+   printf("%d\n", fred() && (1 + joe()));
+   printf("%d\n", fred() || (0 + joe()));
+   printf("%d\n", joe() && (0 + fred()));
+   printf("%d\n", joe() || (1 + fred()));
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/50_logical_second_arg.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/50_logical_second_arg.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/50_logical_second_arg.expect	(revision 331)
@@ -0,0 +1,20 @@
+fred
+0
+fred
+joe
+1
+joe
+fred
+0
+joe
+1
+fred
+0
+fred
+joe
+1
+joe
+fred
+0
+joe
+1
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/51_static.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/51_static.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/51_static.c	(revision 331)
@@ -0,0 +1,30 @@
+#include <stdio.h>
+
+static int fred = 1234;
+static int joe;
+
+void henry()
+{
+   static int fred = 4567;
+
+   printf("%d\n", fred);
+   fred++;
+}
+
+int main()
+{
+   printf("%d\n", fred);
+   henry();
+   henry();
+   henry();
+   henry();
+   printf("%d\n", fred);
+   fred = 8901;
+   joe = 2345;
+   printf("%d\n", fred);
+   printf("%d\n", joe);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/51_static.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/51_static.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/51_static.expect	(revision 331)
@@ -0,0 +1,8 @@
+1234
+4567
+4568
+4569
+4570
+1234
+8901
+2345
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/52_unnamed_enum.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/52_unnamed_enum.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/52_unnamed_enum.c	(revision 331)
@@ -0,0 +1,27 @@
+#include <stdio.h>
+
+enum fred { a, b, c };
+
+int main()
+{
+   printf("a=%d\n", a);
+   printf("b=%d\n", b);
+   printf("c=%d\n", c);
+
+   enum fred d;
+
+   typedef enum { e, f, g } h;
+   typedef enum { i, j, k } m;
+
+   printf("e=%d\n", e);
+   printf("f=%d\n", f);
+   printf("g=%d\n", g);
+
+   printf("i=%d\n", i);
+   printf("j=%d\n", j);
+   printf("k=%d\n", k);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/52_unnamed_enum.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/52_unnamed_enum.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/52_unnamed_enum.expect	(revision 331)
@@ -0,0 +1,9 @@
+a=0
+b=1
+c=2
+e=0
+f=1
+g=2
+i=0
+j=1
+k=2
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/54_goto.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/54_goto.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/54_goto.c	(revision 331)
@@ -0,0 +1,56 @@
+#include <stdio.h>
+
+void fred()
+{
+   printf("In fred()\n");
+   goto done;
+   printf("In middle\n");
+done:
+   printf("At end\n");
+}
+
+void joe()
+{
+   int b = 5678;
+
+   printf("In joe()\n");
+
+   {
+      int c = 1234;
+      printf("c = %d\n", c);
+      goto outer;
+      printf("uh-oh\n");
+   }
+
+outer:    
+
+   printf("done\n");
+}
+
+void henry()
+{
+   int a;
+
+   printf("In henry()\n");
+   goto inner;
+
+   {
+      int b;
+inner:    
+      b = 1234;
+      printf("b = %d\n", b);
+   }
+
+   printf("done\n");
+}
+
+int main()
+{
+   fred();
+   joe();
+   henry();
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/54_goto.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/54_goto.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/54_goto.expect	(revision 331)
@@ -0,0 +1,8 @@
+In fred()
+At end
+In joe()
+c = 1234
+done
+In henry()
+b = 1234
+done
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/55_lshift_type.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/55_lshift_type.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/55_lshift_type.c	(revision 331)
@@ -0,0 +1,52 @@
+/* $Id$
+
+Tests on left-shift type, written by Vincent Lefevre <vincent@vinc17.net>.
+
+ISO C99 TC3 says: [6.5.7#3] "The integer promotions are performed on
+each of the operands. The type of the result is that of the promoted
+left operand."
+*/
+
+#include <stdio.h>
+
+#define PTYPE(M) ((M) < 0 || -(M) < 0 ? -1 : 1) * (int) sizeof((M)+0)
+#define CHECK(X,T) check(#X, PTYPE(X), PTYPE((X) << (T) 1))
+#define TEST1(X,T) do { CHECK(X,T); CHECK(X,unsigned T); } while (0)
+#define TEST2(X)                 \
+  do                             \
+    {                            \
+      TEST1((X),short);          \
+      TEST1((X),int);            \
+      TEST1((X),long);           \
+      TEST1((X),long long);      \
+    }                            \
+  while (0)
+#define TEST3(X,T) do { TEST2((T)(X)); TEST2((unsigned T)(X)); } while (0)
+#define TEST4(X)                 \
+  do                             \
+    {                            \
+      TEST3((X),short);          \
+      TEST3((X),int);            \
+      TEST3((X),long);           \
+      TEST3((X),long long);      \
+    }                            \
+ while (0)
+
+static int debug, nfailed = 0;
+
+static void check (const char *s, int arg1, int shift)
+{
+  int failed = arg1 != shift;
+  if (debug || failed)
+    printf ("%s %d %d\n", s, arg1, shift);
+  nfailed += failed;
+}
+
+int main (int argc, char **argv)
+{
+  debug = argc > 1;
+  TEST4(1);
+  TEST4(-1);
+  printf ("%d test(s) failed\n", nfailed);
+  return nfailed != 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/55_lshift_type.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/55_lshift_type.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/55_lshift_type.expect	(revision 331)
@@ -0,0 +1,1 @@
+0 test(s) failed
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/60_errors_and_warnings.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/60_errors_and_warnings.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/60_errors_and_warnings.c	(revision 331)
@@ -0,0 +1,51 @@
+#if defined test_56_btype_excess_1
+struct A {} int i;
+
+#elif defined test_57_btype_excess_2
+char int i;
+
+#elif defined test_58_function_redefinition
+int f(void) { return 0; }
+int f(void) { return 1; }
+
+#elif defined test_global_redefinition
+int xxx = 1;
+int xxx;
+int xxx = 2;
+
+#elif defined test_59_function_array
+int (*fct)[42](int x);
+
+#elif defined test_60_enum_redefinition
+enum color { RED, GREEN, BLUE };
+enum color { R, G, B };
+enum color c;
+
+#elif defined test_62_enumerator_redefinition
+enum color { RED, GREEN, BLUE };
+enum rgb { RED, G, B};
+enum color c = RED;
+
+#elif defined test_63_local_enumerator_redefinition
+enum {
+    FOO,
+    BAR
+};
+
+int main(void)
+{
+    enum {
+        FOO = 2,
+        BAR
+    };
+
+    return BAR - FOO;
+}
+
+#elif defined test_61_undefined_enum
+enum rgb3 c = 42;
+
+#elif defined test_74_non_const_init
+int i = i++;
+
+#endif
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/60_errors_and_warnings.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/60_errors_and_warnings.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/60_errors_and_warnings.expect	(revision 331)
@@ -0,0 +1,28 @@
+[test_56_btype_excess_1]
+60_errors_and_warnings.c:2: error: too many basic types
+
+[test_57_btype_excess_2]
+60_errors_and_warnings.c:5: error: too many basic types
+
+[test_58_function_redefinition]
+60_errors_and_warnings.c:9: error: redefinition of 'f'
+
+[test_global_redefinition]
+60_errors_and_warnings.c:14: error: redefinition of 'xxx'
+
+[test_59_function_array]
+60_errors_and_warnings.c:17: error: declaration of an array of functions
+
+[test_60_enum_redefinition]
+60_errors_and_warnings.c:21: error: struct/union/enum already defined
+
+[test_62_enumerator_redefinition]
+60_errors_and_warnings.c:26: error: redefinition of enumerator 'RED'
+
+[test_63_local_enumerator_redefinition]
+
+[test_61_undefined_enum]
+60_errors_and_warnings.c:46: error: unknown type size
+
+[test_74_non_const_init]
+60_errors_and_warnings.c:49: error: initializer element is not constant
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/64_macro_nesting.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/64_macro_nesting.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/64_macro_nesting.c	(revision 331)
@@ -0,0 +1,12 @@
+#include <stdio.h>	// printf()
+
+#define CAT2(a,b) a##b
+#define CAT(a,b) CAT2(a,b)
+#define AB(x) CAT(x,y)
+
+int main(void)
+{
+  int xy = 42;
+  printf("%d\n", CAT(A,B)(x));
+  return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/64_macro_nesting.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/64_macro_nesting.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/64_macro_nesting.expect	(revision 331)
@@ -0,0 +1,1 @@
+42
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/67_macro_concat.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/67_macro_concat.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/67_macro_concat.c	(revision 331)
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+#define P(A,B) A ## B ; bob
+#define Q(A,B) A ## B+
+
+int main(void)
+{
+    int bob, jim = 21;
+    bob = P(jim,) *= 2;
+    printf("jim: %d, bob: %d\n", jim, bob);
+    jim = 60 Q(+,)3;
+    printf("jim: %d\n", jim);
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/67_macro_concat.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/67_macro_concat.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/67_macro_concat.expect	(revision 331)
@@ -0,0 +1,2 @@
+jim: 21, bob: 42
+jim: 63
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/70_floating_point_literals.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/70_floating_point_literals.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/70_floating_point_literals.c	(revision 331)
@@ -0,0 +1,77 @@
+#include <stdio.h>
+
+int main()
+{
+    /* decimal floating constant */
+    float fa0 = .123f;
+    float fa1 = .123E12F;
+    float fa2 = .123e-12f;
+    float fa3 = .123e+12f;
+    printf("%f\n%f\n%f\n%f\n\n", fa0, fa1, fa2, fa3);
+
+    float fb0 = 123.123f;
+    float fb1 = 123.123E12F;
+    float fb2 = 123.123e-12f;
+    float fb3 = 123.123e+12f;
+    printf("%f\n%f\n%f\n%f\n\n", fb0, fb1, fb2, fb3);
+
+    float fc0 = 123.f;
+    float fc1 = 123.E12F;
+    float fc2 = 123.e-12f;
+    float fc3 = 123.e+12f;
+    printf("%f\n%f\n%f\n%f\n\n", fc0, fc1, fc2, fc3);
+
+    float fd0 = 123E12F;
+    float fd1 = 123e-12f;
+    float fd2 = 123e+12f;
+    printf("%f\n%f\n%f\n\n", fd0, fd1, fd2);
+    printf("\n");
+
+    /* hexadecimal floating constant */
+    double da0 = 0X.1ACP12;
+    double da1 = 0x.1acp-12;
+    double da2 = 0x.1acp+12;
+    printf("%f\n%f\n%f\n\n", da0, da1, da2);
+
+    double db0 = 0X1AC.BDP12;
+    double db1 = 0x1ac.bdp-12;
+    double db2 = 0x1ac.dbp+12;
+    printf("%f\n%f\n%f\n\n", db0, db1, db2);
+
+    double dc0 = 0X1AC.P12;
+    double dc1 = 0x1ac.p-12;
+    double dc2 = 0x1ac.p+12;
+    printf("%f\n%f\n%f\n\n", dc0, dc1, dc2);
+
+    double dd0 = 0X1ACP12;
+    double dd1 = 0x1acp-12;
+    double dd2 = 0x1acp+12;
+    printf("%f\n%f\n%f\n\n", dd0, dd1, dd2);
+    printf("\n");
+
+#ifdef __TINYC__
+    /* TCC extension
+       binary floating constant */
+    long double la0 = 0B.110101100P12L;
+    long double la1 = 0b.110101100p-12l;
+    long double la2 = 0b.110101100p+12l;
+    printf("%Lf\n%Lf\n%Lf\n\n", la0, la1, la2);
+
+    long double lb0 = 0B110101100.10111101P12L;
+    long double lb1 = 0b110101100.10111101p-12l;
+    long double lb2 = 0b110101100.10111101p+12l;
+    printf("%Lf\n%Lf\n%Lf\n\n", lb0, lb1, lb2);
+
+    long double lc0 = 0B110101100.P12L;
+    long double lc1 = 0b110101100.p-12l;
+    long double lc2 = 0b110101100.p+12l;
+    printf("%Lf\n%Lf\n%Lf\n\n", lc0, lc1, lc2);
+
+    long double ld0 = 0B110101100P12L;
+    long double ld1 = 0b110101100p-12l;
+    long double ld2 = 0b110101100p+12l;
+    printf("%Lf\n%Lf\n%Lf\n\n", ld0, ld1, ld2);
+#endif
+
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/70_floating_point_literals.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/70_floating_point_literals.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/70_floating_point_literals.expect	(revision 331)
@@ -0,0 +1,53 @@
+0.123000
+122999996416.000000
+0.000000
+122999996416.000000
+
+123.123001
+123122997002240.000000
+0.000000
+123122997002240.000000
+
+123.000000
+123000003231744.000000
+0.000000
+123000003231744.000000
+
+123000003231744.000000
+0.000000
+123000003231744.000000
+
+
+428.000000
+0.000026
+428.000000
+
+1756112.000000
+0.104672
+1756592.000000
+
+1753088.000000
+0.104492
+1753088.000000
+
+1753088.000000
+0.104492
+1753088.000000
+
+
+3424.000000
+0.000204
+3424.000000
+
+1756112.000000
+0.104672
+1756112.000000
+
+1753088.000000
+0.104492
+1753088.000000
+
+1753088.000000
+0.104492
+1753088.000000
+
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/71_macro_empty_arg.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/71_macro_empty_arg.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/71_macro_empty_arg.c	(revision 331)
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+#define T(a,b,c) a b c
+
+int main(void)
+{
+    printf("%d", T(1,+,2) T(+,,) T(,2,*) T(,7,) T(,,));
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/71_macro_empty_arg.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/71_macro_empty_arg.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/71_macro_empty_arg.expect	(revision 331)
@@ -0,0 +1,1 @@
+17
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/72_long_long_constant.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/72_long_long_constant.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/72_long_long_constant.c	(revision 331)
@@ -0,0 +1,19 @@
+#include <stdio.h>
+
+int main()
+{
+    long long int res = 0;
+
+    if (res < -2147483648LL) {
+        printf("Error: 0 < -2147483648\n");
+        return 1;
+    }
+    else
+    if (2147483647LL < res) {
+        printf("Error: 2147483647 < 0\n");
+        return 2;
+    }
+    else
+        printf("long long constant test ok.\n");
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/72_long_long_constant.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/72_long_long_constant.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/72_long_long_constant.expect	(revision 331)
@@ -0,0 +1,1 @@
+long long constant test ok.
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/73_arm64.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/73_arm64.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/73_arm64.c	(revision 331)
@@ -0,0 +1,527 @@
+// This program is designed to test some arm64-specific things, such as the
+// calling convention, but should give the same results on any architecture.
+
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+
+struct s1 { char x[1]; } s1 = { "0" };
+struct s2 { char x[2]; } s2 = { "12" };
+struct s3 { char x[3]; } s3 = { "345" };
+struct s4 { char x[4]; } s4 = { "6789" };
+struct s5 { char x[5]; } s5 = { "abcde" };
+struct s6 { char x[6]; } s6 = { "fghijk" };
+struct s7 { char x[7]; } s7 = { "lmnopqr" };
+struct s8 { char x[8]; } s8 = { "stuvwxyz" };
+struct s9 { char x[9]; } s9 = { "ABCDEFGHI" };
+struct s10 { char x[10]; } s10 = { "JKLMNOPQRS" };
+struct s11 { char x[11]; } s11 = { "TUVWXYZ0123" };
+struct s12 { char x[12]; } s12 = { "456789abcdef" };
+struct s13 { char x[13]; } s13 = { "ghijklmnopqrs" };
+struct s14 { char x[14]; } s14 = { "tuvwxyzABCDEFG" };
+struct s15 { char x[15]; } s15 = { "HIJKLMNOPQRSTUV" };
+struct s16 { char x[16]; } s16 = { "WXYZ0123456789ab" };
+struct s17 { char x[17]; } s17 = { "cdefghijklmnopqrs" };
+
+struct hfa11 { float a; } hfa11 = { 11.1 };
+struct hfa12 { float a, b; } hfa12 = { 12.1, 12.2 };
+struct hfa13 { float a, b, c; } hfa13 = { 13.1, 13.2, 13.3 };
+struct hfa14 { float a, b, c, d; } hfa14 = { 14.1, 14.2, 14.3, 14.4 };
+
+struct hfa21 { double a; } hfa21 = { 21.1 };
+struct hfa22 { double a, b; } hfa22 = { 22.1, 22.2 };
+struct hfa23 { double a, b, c; } hfa23 = { 23.1, 23.2, 23.3 };
+struct hfa24 { double a, b, c, d; } hfa24 = { 24.1, 24.2, 24.3, 24.4 };
+
+struct hfa31 { long double a; } hfa31 = { 31.1 };
+struct hfa32 { long double a, b; } hfa32 = { 32.1, 32.2 };
+struct hfa33 { long double a, b, c; } hfa33 = { 33.1, 33.2, 33.3 };
+struct hfa34 { long double a, b, c, d; } hfa34 = { 34.1, 34.2, 34.3, 34.4 };
+
+void fa_s1(struct s1 a) { printf("%.1s\n", a.x); }
+void fa_s2(struct s2 a) { printf("%.2s\n", a.x); }
+void fa_s3(struct s3 a) { printf("%.3s\n", a.x); }
+void fa_s4(struct s4 a) { printf("%.4s\n", a.x); }
+void fa_s5(struct s5 a) { printf("%.5s\n", a.x); }
+void fa_s6(struct s6 a) { printf("%.6s\n", a.x); }
+void fa_s7(struct s7 a) { printf("%.7s\n", a.x); }
+void fa_s8(struct s8 a) { printf("%.8s\n", a.x); }
+void fa_s9(struct s9 a) { printf("%.9s\n", a.x); }
+void fa_s10(struct s10 a) { printf("%.10s\n", a.x); }
+void fa_s11(struct s11 a) { printf("%.11s\n", a.x); }
+void fa_s12(struct s12 a) { printf("%.12s\n", a.x); }
+void fa_s13(struct s13 a) { printf("%.13s\n", a.x); }
+void fa_s14(struct s14 a) { printf("%.14s\n", a.x); }
+void fa_s15(struct s15 a) { printf("%.15s\n", a.x); }
+void fa_s16(struct s16 a) { printf("%.16s\n", a.x); }
+void fa_s17(struct s17 a) { printf("%.17s\n", a.x); }
+
+void fa_hfa11(struct hfa11 a)
+{ printf("%.1f\n", a.a); }
+void fa_hfa12(struct hfa12 a)
+{ printf("%.1f %.1f\n", a.a, a.a); }
+void fa_hfa13(struct hfa13 a)
+{ printf("%.1f %.1f %.1f\n", a.a, a.b, a.c); }
+void fa_hfa14(struct hfa14 a)
+{ printf("%.1f %.1f %.1f %.1f\n", a.a, a.b, a.c, a.d); }
+
+void fa_hfa21(struct hfa21 a)
+{ printf("%.1f\n", a.a); }
+void fa_hfa22(struct hfa22 a)
+{ printf("%.1f %.1f\n", a.a, a.a); }
+void fa_hfa23(struct hfa23 a)
+{ printf("%.1f %.1f %.1f\n", a.a, a.b, a.c); }
+void fa_hfa24(struct hfa24 a)
+{ printf("%.1f %.1f %.1f %.1f\n", a.a, a.b, a.c, a.d); }
+
+void fa_hfa31(struct hfa31 a)
+{ printf("%.1Lf\n", a.a); }
+void fa_hfa32(struct hfa32 a)
+{ printf("%.1Lf %.1Lf\n", a.a, a.a); }
+void fa_hfa33(struct hfa33 a)
+{ printf("%.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c); }
+void fa_hfa34(struct hfa34 a)
+{ printf("%.1Lf %.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c, a.d); }
+
+void fa1(struct s8 a, struct s9 b, struct s10 c, struct s11 d,
+         struct s12 e, struct s13 f)
+{
+    printf("%.3s %.3s %.3s %.3s %.3s %.3s\n", a.x, b.x, c.x, d.x, e.x, f.x);
+}
+
+void fa2(struct s9 a, struct s10 b, struct s11 c, struct s12 d,
+         struct s13 e, struct s14 f)
+{
+    printf("%.3s %.3s %.3s %.3s %.3s %.3s\n", a.x, b.x, c.x, d.x, e.x, f.x);
+}
+
+void fa3(struct hfa14 a, struct hfa23 b, struct hfa32 c)
+{
+    printf("%.1f %.1f %.1f %.1f %.1Lf %.1Lf\n",
+           a.a, a.d, b.a, b.c, c.a, c.b);
+}
+
+void fa4(struct s1 a, struct hfa14 b, struct s2 c, struct hfa24 d,
+         struct s3 e, struct hfa34 f)
+{
+    printf("%.1s %.1f %.1f %.2s %.1f %.1f %.3s %.1Lf %.1Lf\n",
+           a.x, b.a, b.d, c.x, d.a, d.d, e.x, f.a, f.d);
+}
+
+void arg(void)
+{
+    printf("Arguments:\n");
+    fa_s1(s1);
+    fa_s2(s2);
+    fa_s3(s3);
+    fa_s4(s4);
+    fa_s5(s5);
+    fa_s6(s6);
+    fa_s7(s7);
+    fa_s8(s8);
+    fa_s9(s9);
+    fa_s10(s10);
+    fa_s11(s11);
+    fa_s12(s12);
+    fa_s13(s13);
+    fa_s14(s14);
+    fa_s15(s15);
+    fa_s16(s16);
+    fa_s17(s17);
+    fa_hfa11(hfa11);
+    fa_hfa12(hfa12);
+    fa_hfa13(hfa13);
+    fa_hfa14(hfa14);
+    fa_hfa21(hfa21);
+    fa_hfa22(hfa22);
+    fa_hfa23(hfa23);
+    fa_hfa24(hfa24);
+    fa_hfa31(hfa31);
+    fa_hfa32(hfa32);
+    fa_hfa33(hfa33);
+    fa_hfa34(hfa34);
+    fa1(s8, s9, s10, s11, s12, s13);
+    fa2(s9, s10, s11, s12, s13, s14);
+    fa3(hfa14, hfa23, hfa32);
+    fa4(s1, hfa14, s2, hfa24, s3, hfa34);
+}
+
+struct s1 fr_s1(void) { return s1; }
+struct s2 fr_s2(void) { return s2; }
+struct s3 fr_s3(void) { return s3; }
+struct s4 fr_s4(void) { return s4; }
+struct s5 fr_s5(void) { return s5; }
+struct s6 fr_s6(void) { return s6; }
+struct s7 fr_s7(void) { return s7; }
+struct s8 fr_s8(void) { return s8; }
+struct s9 fr_s9(void) { return s9; }
+struct s10 fr_s10(void) { return s10; }
+struct s11 fr_s11(void) { return s11; }
+struct s12 fr_s12(void) { return s12; }
+struct s13 fr_s13(void) { return s13; }
+struct s14 fr_s14(void) { return s14; }
+struct s15 fr_s15(void) { return s15; }
+struct s16 fr_s16(void) { return s16; }
+struct s17 fr_s17(void) { return s17; }
+
+struct hfa11 fr_hfa11(void) { return hfa11; }
+struct hfa12 fr_hfa12(void) { return hfa12; }
+struct hfa13 fr_hfa13(void) { return hfa13; }
+struct hfa14 fr_hfa14(void) { return hfa14; }
+
+struct hfa21 fr_hfa21(void) { return hfa21; }
+struct hfa22 fr_hfa22(void) { return hfa22; }
+struct hfa23 fr_hfa23(void) { return hfa23; }
+struct hfa24 fr_hfa24(void) { return hfa24; }
+
+struct hfa31 fr_hfa31(void) { return hfa31; }
+struct hfa32 fr_hfa32(void) { return hfa32; }
+struct hfa33 fr_hfa33(void) { return hfa33; }
+struct hfa34 fr_hfa34(void) { return hfa34; }
+
+void ret(void)
+{
+    struct s1 t1 = fr_s1();
+    struct s2 t2 = fr_s2();
+    struct s3 t3 = fr_s3();
+    struct s4 t4 = fr_s4();
+    struct s5 t5 = fr_s5();
+    struct s6 t6 = fr_s6();
+    struct s7 t7 = fr_s7();
+    struct s8 t8 = fr_s8();
+    struct s9 t9 = fr_s9();
+    struct s10 t10 = fr_s10();
+    struct s11 t11 = fr_s11();
+    struct s12 t12 = fr_s12();
+    struct s13 t13 = fr_s13();
+    struct s14 t14 = fr_s14();
+    struct s15 t15 = fr_s15();
+    struct s16 t16 = fr_s16();
+    struct s17 t17 = fr_s17();
+    printf("Return values:\n");
+    printf("%.1s\n", t1.x);
+    printf("%.2s\n", t2.x);
+    printf("%.3s\n", t3.x);
+    printf("%.4s\n", t4.x);
+    printf("%.5s\n", t5.x);
+    printf("%.6s\n", t6.x);
+    printf("%.7s\n", t7.x);
+    printf("%.8s\n", t8.x);
+    printf("%.9s\n", t9.x);
+    printf("%.10s\n", t10.x);
+    printf("%.11s\n", t11.x);
+    printf("%.12s\n", t12.x);
+    printf("%.13s\n", t13.x);
+    printf("%.14s\n", t14.x);
+    printf("%.15s\n", t15.x);
+    printf("%.16s\n", t16.x);
+    printf("%.17s\n", t17.x);
+    printf("%.1f\n", fr_hfa11().a);
+    printf("%.1f %.1f\n", fr_hfa12().a, fr_hfa12().b);
+    printf("%.1f %.1f\n", fr_hfa13().a, fr_hfa13().c);
+    printf("%.1f %.1f\n", fr_hfa14().a, fr_hfa14().d);
+    printf("%.1f\n", fr_hfa21().a);
+    printf("%.1f %.1f\n", fr_hfa22().a, fr_hfa22().b);
+    printf("%.1f %.1f\n", fr_hfa23().a, fr_hfa23().c);
+    printf("%.1f %.1f\n", fr_hfa24().a, fr_hfa24().d);
+    printf("%.1Lf\n", fr_hfa31().a);
+    printf("%.1Lf %.1Lf\n", fr_hfa32().a, fr_hfa32().b);
+    printf("%.1Lf %.1Lf\n", fr_hfa33().a, fr_hfa33().c);
+    printf("%.1Lf %.1Lf\n", fr_hfa34().a, fr_hfa34().d);
+}
+
+int match(const char **s, const char *f)
+{
+    const char *p = *s;
+    for (p = *s; *f && *f == *p; f++, p++)
+        ;
+    if (!*f) {
+        *s = p - 1;
+        return 1;
+    }
+    return 0;
+}
+
+void myprintf(const char *format, ...)
+{
+    const char *s;
+    va_list ap;
+    va_start(ap, format);
+    for (s = format; *s; s++) {
+        if (match(&s, "%7s")) {
+            struct s7 t7 = va_arg(ap, struct s7);
+            printf("%.7s", t7.x);
+        }
+        else if (match(&s, "%9s")) {
+            struct s9 t9 = va_arg(ap, struct s9);
+            printf("%.9s", t9.x);
+        }
+        else if (match(&s, "%hfa11")) {
+            struct hfa11 x = va_arg(ap, struct hfa11);
+            printf("%.1f,%.1f", x.a, x.a);
+        }
+        else if (match(&s, "%hfa12")) {
+            struct hfa12 x = va_arg(ap, struct hfa12);
+            printf("%.1f,%.1f", x.a, x.b);
+        }
+        else if (match(&s, "%hfa13")) {
+            struct hfa13 x = va_arg(ap, struct hfa13);
+            printf("%.1f,%.1f", x.a, x.c);
+        }
+        else if (match(&s, "%hfa14")) {
+            struct hfa14 x = va_arg(ap, struct hfa14);
+            printf("%.1f,%.1f", x.a, x.d);
+        }
+        else if (match(&s, "%hfa21")) {
+            struct hfa21 x = va_arg(ap, struct hfa21);
+            printf("%.1f,%.1f", x.a, x.a);
+        }
+        else if (match(&s, "%hfa22")) {
+            struct hfa22 x = va_arg(ap, struct hfa22);
+            printf("%.1f,%.1f", x.a, x.b);
+        }
+        else if (match(&s, "%hfa23")) {
+            struct hfa23 x = va_arg(ap, struct hfa23);
+            printf("%.1f,%.1f", x.a, x.c);
+        }
+        else if (match(&s, "%hfa24")) {
+            struct hfa24 x = va_arg(ap, struct hfa24);
+            printf("%.1f,%.1f", x.a, x.d);
+        }
+        else if (match(&s, "%hfa31")) {
+            struct hfa31 x = va_arg(ap, struct hfa31);
+            printf("%.1Lf,%.1Lf", x.a, x.a);
+        }
+        else if (match(&s, "%hfa32")) {
+            struct hfa32 x = va_arg(ap, struct hfa32);
+            printf("%.1Lf,%.1Lf", x.a, x.b);
+        }
+        else if (match(&s, "%hfa33")) {
+            struct hfa33 x = va_arg(ap, struct hfa33);
+            printf("%.1Lf,%.1Lf", x.a, x.c);
+        }
+        else if (match(&s, "%hfa34")) {
+            struct hfa34 x = va_arg(ap, struct hfa34);
+            printf("%.1Lf,%.1Lf", x.a, x.d);
+        }
+        else
+            putchar(*s);
+    }
+    putchar('\n');
+}
+
+void stdarg(void)
+{
+    printf("stdarg:\n");
+    myprintf("%9s %9s %9s %9s %9s %9s", s9, s9, s9, s9, s9, s9);
+    myprintf("%7s %9s %9s %9s %9s %9s", s7, s9, s9, s9, s9, s9);
+
+    myprintf("HFA long double:");
+    myprintf("%hfa34 %hfa34 %hfa34 %hfa34", hfa34, hfa34, hfa34, hfa34);
+    myprintf("%hfa33 %hfa34 %hfa34 %hfa34", hfa33, hfa34, hfa34, hfa34);
+    myprintf("%hfa32 %hfa34 %hfa34 %hfa34", hfa32, hfa34, hfa34, hfa34);
+    myprintf("%hfa31 %hfa34 %hfa34 %hfa34", hfa31, hfa34, hfa34, hfa34);
+
+    myprintf("%hfa32 %hfa33 %hfa33 %hfa33 %hfa33",
+             hfa32, hfa33, hfa33, hfa33, hfa33);
+    myprintf("%hfa31 %hfa33 %hfa33 %hfa33 %hfa33",
+             hfa31, hfa33, hfa33, hfa33, hfa33);
+    myprintf("%hfa33 %hfa33 %hfa33 %hfa33",
+             hfa33, hfa33, hfa33, hfa33);
+
+    myprintf("%hfa34 %hfa32 %hfa32 %hfa32 %hfa32",
+             hfa34, hfa32, hfa32, hfa32, hfa32);
+    myprintf("%hfa33 %hfa32 %hfa32 %hfa32 %hfa32",
+             hfa33, hfa32, hfa32, hfa32, hfa32);
+
+    myprintf("%hfa34 %hfa32 %hfa31 %hfa31 %hfa31 %hfa31",
+             hfa34, hfa32, hfa31, hfa31, hfa31, hfa31);
+
+    myprintf("HFA double:");
+    myprintf("%hfa24 %hfa24 %hfa24 %hfa24", hfa24, hfa24, hfa24, hfa24);
+    myprintf("%hfa23 %hfa24 %hfa24 %hfa24", hfa23, hfa24, hfa24, hfa24);
+    myprintf("%hfa22 %hfa24 %hfa24 %hfa24", hfa22, hfa24, hfa24, hfa24);
+    myprintf("%hfa21 %hfa24 %hfa24 %hfa24", hfa21, hfa24, hfa24, hfa24);
+
+    myprintf("%hfa22 %hfa23 %hfa23 %hfa23 %hfa23",
+             hfa22, hfa23, hfa23, hfa23, hfa23);
+    myprintf("%hfa21 %hfa23 %hfa23 %hfa23 %hfa23",
+             hfa21, hfa23, hfa23, hfa23, hfa23);
+    myprintf("%hfa23 %hfa23 %hfa23 %hfa23",
+             hfa23, hfa23, hfa23, hfa23);
+
+    myprintf("%hfa24 %hfa22 %hfa22 %hfa22 %hfa22",
+             hfa24, hfa22, hfa22, hfa22, hfa22);
+    myprintf("%hfa23 %hfa22 %hfa22 %hfa22 %hfa22",
+             hfa23, hfa22, hfa22, hfa22, hfa22);
+
+    myprintf("%hfa24 %hfa22 %hfa21 %hfa21 %hfa21 %hfa21",
+             hfa24, hfa22, hfa21, hfa21, hfa21, hfa21);
+
+    myprintf("HFA float:");
+    myprintf("%hfa14 %hfa14 %hfa14 %hfa14", hfa14, hfa14, hfa14, hfa14);
+    myprintf("%hfa13 %hfa14 %hfa14 %hfa14", hfa13, hfa14, hfa14, hfa14);
+    myprintf("%hfa12 %hfa14 %hfa14 %hfa14", hfa12, hfa14, hfa14, hfa14);
+    myprintf("%hfa11 %hfa14 %hfa14 %hfa14", hfa11, hfa14, hfa14, hfa14);
+
+    myprintf("%hfa12 %hfa13 %hfa13 %hfa13 %hfa13",
+             hfa12, hfa13, hfa13, hfa13, hfa13);
+    myprintf("%hfa11 %hfa13 %hfa13 %hfa13 %hfa13",
+             hfa11, hfa13, hfa13, hfa13, hfa13);
+    myprintf("%hfa13 %hfa13 %hfa13 %hfa13",
+             hfa13, hfa13, hfa13, hfa13);
+
+    myprintf("%hfa14 %hfa12 %hfa12 %hfa12 %hfa12",
+             hfa14, hfa12, hfa12, hfa12, hfa12);
+    myprintf("%hfa13 %hfa12 %hfa12 %hfa12 %hfa12",
+             hfa13, hfa12, hfa12, hfa12, hfa12);
+
+    myprintf("%hfa14 %hfa12 %hfa11 %hfa11 %hfa11 %hfa11",
+             hfa14, hfa12, hfa11, hfa11, hfa11, hfa11);
+}
+
+void pll(unsigned long long x)
+{
+    printf("%llx\n", x);
+}
+
+void movi(void)
+{
+    printf("MOVI:\n");
+    pll(0);
+    pll(0xabcd);
+    pll(0xabcd0000);
+    pll(0xabcd00000000);
+    pll(0xabcd000000000000);
+    pll(0xffffabcd);
+    pll(0xabcdffff);
+    pll(0xffffffffffffabcd);
+    pll(0xffffffffabcdffff);
+    pll(0xffffabcdffffffff);
+    pll(0xabcdffffffffffff);
+    pll(0xaaaaaaaa);
+    pll(0x5555555555555555);
+    pll(0x77777777);
+    pll(0x3333333333333333);
+    pll(0xf8f8f8f8);
+    pll(0x1e1e1e1e1e1e1e1e);
+    pll(0x3f803f80);
+    pll(0x01ff01ff01ff01ff);
+    pll(0x007fffc0);
+    pll(0x03fff80003fff800);
+    pll(0x0007fffffffffe00);
+
+    pll(0xabcd1234);
+    pll(0xabcd00001234);
+    pll(0xabcd000000001234);
+    pll(0xabcd12340000);
+    pll(0xabcd000012340000);
+    pll(0xabcd123400000000);
+    pll(0xffffffffabcd1234);
+    pll(0xffffabcdffff1234);
+    pll(0xabcdffffffff1234);
+    pll(0xffffabcd1234ffff);
+    pll(0xabcdffff1234ffff);
+    pll(0xabcd1234ffffffff);
+
+    pll(0xffffef0123456789);
+    pll(0xabcdef012345ffff);
+
+    pll(0xabcdef0123456789);
+}
+
+static uint32_t addip0(uint32_t x) { return x + 0; }
+static uint64_t sublp0(uint64_t x) { return x - 0; }
+static uint32_t addip123(uint32_t x) { return x + 123; }
+static uint64_t addlm123(uint64_t x) { return x + -123; }
+static uint64_t sublp4095(uint64_t x) { return x - 4095; }
+static uint32_t subim503808(uint32_t x) { return x - -503808; }
+static uint64_t addp12345(uint64_t x) { return x + 12345; }
+static uint32_t subp12345(uint32_t x) { return x - 12345; }
+
+static uint32_t mvni(uint32_t x) { return 0xffffffff - x; }
+static uint64_t negl(uint64_t x) { return 0 - x; }
+static uint32_t rsbi123(uint32_t x) { return 123 - x; }
+static uint64_t rsbl123(uint64_t x) { return 123 - x; }
+
+static uint32_t andi0(uint32_t x) { return x & 0; }
+static uint64_t andlm1(uint64_t x) { return x & -1; }
+static uint64_t orrl0(uint64_t x) { return x | 0; }
+static uint32_t orrim1(uint32_t x) { return x | -1; }
+static uint32_t eori0(uint32_t x) { return x ^ 0; }
+static uint64_t eorlm1(uint64_t x) { return x ^ -1; }
+static uint32_t and0xf0(uint32_t x) { return x & 0xf0; }
+static uint64_t orr0xf0(uint64_t x) { return x | 0xf0; }
+static uint64_t eor0xf0(uint64_t x) { return x ^ 0xf0; }
+
+static uint32_t lsli0(uint32_t x) { return x << 0; }
+static uint32_t lsri0(uint32_t x) { return x >> 0; }
+static int64_t asrl0(int64_t x) { return x >> 0; }
+static uint32_t lsli1(uint32_t x) { return x << 1; }
+static uint32_t lsli31(uint32_t x) { return x << 31; }
+static uint64_t lsll1(uint64_t x) { return x << 1; }
+static uint64_t lsll63(uint64_t x) { return x << 63; }
+static uint32_t lsri1(uint32_t x) { return x >> 1; }
+static uint32_t lsri31(uint32_t x) { return x >> 31; }
+static uint64_t lsrl1(uint64_t x) { return x >> 1; }
+static uint64_t lsrl63(uint64_t x) { return x >> 63; }
+static int32_t asri1(int32_t x) { return x >> 1; }
+static int32_t asri31(int32_t x) { return x >> 31; }
+static int64_t asrl1(int64_t x) { return x >> 1; }
+static int64_t asrl63(int64_t x) { return x >> 63; }
+
+void opi(void)
+{
+    int x = 1000;
+    pll(addip0(x));
+    pll(sublp0(x));
+    pll(addip123(x));
+    pll(addlm123(x));
+    pll(sublp4095(x));
+    pll(subim503808(x));
+    pll(addp12345(x));
+    pll(subp12345(x));
+    pll(mvni(x));
+    pll(negl(x));
+    pll(rsbi123(x));
+    pll(rsbl123(x));
+    pll(andi0(x));
+    pll(andlm1(x));
+    pll(orrl0(x));
+    pll(orrim1(x));
+    pll(eori0(x));
+    pll(eorlm1(x));
+    pll(and0xf0(x));
+    pll(orr0xf0(x));
+    pll(eor0xf0(x));
+    pll(lsli0(x));
+    pll(lsri0(x));
+    pll(asrl0(x));
+    pll(lsli1(x));
+    pll(lsli31(x));
+    pll(lsll1(x));
+    pll(lsll63(x));
+    pll(lsri1(x));
+    pll(lsri31(x));
+    pll(lsrl1(x));
+    pll(lsrl63(x));
+    pll(asri1(x));
+    pll(asri31(x));
+    pll(asrl1(x));
+    pll(asrl63(x));
+}
+
+void pcs(void)
+{
+    arg();
+    ret();
+    stdarg();
+    movi();
+    opi();
+}
+
+int main()
+{
+    pcs();
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/73_arm64.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/73_arm64.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/73_arm64.expect	(revision 331)
@@ -0,0 +1,174 @@
+Arguments:
+0
+12
+345
+6789
+abcde
+fghijk
+lmnopqr
+stuvwxyz
+ABCDEFGHI
+JKLMNOPQRS
+TUVWXYZ0123
+456789abcdef
+ghijklmnopqrs
+tuvwxyzABCDEFG
+HIJKLMNOPQRSTUV
+WXYZ0123456789ab
+cdefghijklmnopqrs
+11.1
+12.1 12.1
+13.1 13.2 13.3
+14.1 14.2 14.3 14.4
+21.1
+22.1 22.1
+23.1 23.2 23.3
+24.1 24.2 24.3 24.4
+31.1
+32.1 32.1
+33.1 33.2 33.3
+34.1 34.2 34.3 34.4
+stu ABC JKL TUV 456 ghi
+ABC JKL TUV 456 ghi tuv
+14.1 14.4 23.1 23.3 32.1 32.2
+0 14.1 14.4 12 24.1 24.4 345 34.1 34.4
+Return values:
+0
+12
+345
+6789
+abcde
+fghijk
+lmnopqr
+stuvwxyz
+ABCDEFGHI
+JKLMNOPQRS
+TUVWXYZ0123
+456789abcdef
+ghijklmnopqrs
+tuvwxyzABCDEFG
+HIJKLMNOPQRSTUV
+WXYZ0123456789ab
+cdefghijklmnopqrs
+11.1
+12.1 12.2
+13.1 13.3
+14.1 14.4
+21.1
+22.1 22.2
+23.1 23.3
+24.1 24.4
+31.1
+32.1 32.2
+33.1 33.3
+34.1 34.4
+stdarg:
+ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI
+lmnopqr ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI
+HFA long double:
+34.1,34.4 34.1,34.4 34.1,34.4 34.1,34.4
+33.1,33.3 34.1,34.4 34.1,34.4 34.1,34.4
+32.1,32.2 34.1,34.4 34.1,34.4 34.1,34.4
+31.1,31.1 34.1,34.4 34.1,34.4 34.1,34.4
+32.1,32.2 33.1,33.3 33.1,33.3 33.1,33.3 33.1,33.3
+31.1,31.1 33.1,33.3 33.1,33.3 33.1,33.3 33.1,33.3
+33.1,33.3 33.1,33.3 33.1,33.3 33.1,33.3
+34.1,34.4 32.1,32.2 32.1,32.2 32.1,32.2 32.1,32.2
+33.1,33.3 32.1,32.2 32.1,32.2 32.1,32.2 32.1,32.2
+34.1,34.4 32.1,32.2 31.1,31.1 31.1,31.1 31.1,31.1 31.1,31.1
+HFA double:
+24.1,24.4 24.1,24.4 24.1,24.4 24.1,24.4
+23.1,23.3 24.1,24.4 24.1,24.4 24.1,24.4
+22.1,22.2 24.1,24.4 24.1,24.4 24.1,24.4
+21.1,21.1 24.1,24.4 24.1,24.4 24.1,24.4
+22.1,22.2 23.1,23.3 23.1,23.3 23.1,23.3 23.1,23.3
+21.1,21.1 23.1,23.3 23.1,23.3 23.1,23.3 23.1,23.3
+23.1,23.3 23.1,23.3 23.1,23.3 23.1,23.3
+24.1,24.4 22.1,22.2 22.1,22.2 22.1,22.2 22.1,22.2
+23.1,23.3 22.1,22.2 22.1,22.2 22.1,22.2 22.1,22.2
+24.1,24.4 22.1,22.2 21.1,21.1 21.1,21.1 21.1,21.1 21.1,21.1
+HFA float:
+14.1,14.4 14.1,14.4 14.1,14.4 14.1,14.4
+13.1,13.3 14.1,14.4 14.1,14.4 14.1,14.4
+12.1,12.2 14.1,14.4 14.1,14.4 14.1,14.4
+11.1,11.1 14.1,14.4 14.1,14.4 14.1,14.4
+12.1,12.2 13.1,13.3 13.1,13.3 13.1,13.3 13.1,13.3
+11.1,11.1 13.1,13.3 13.1,13.3 13.1,13.3 13.1,13.3
+13.1,13.3 13.1,13.3 13.1,13.3 13.1,13.3
+14.1,14.4 12.1,12.2 12.1,12.2 12.1,12.2 12.1,12.2
+13.1,13.3 12.1,12.2 12.1,12.2 12.1,12.2 12.1,12.2
+14.1,14.4 12.1,12.2 11.1,11.1 11.1,11.1 11.1,11.1 11.1,11.1
+MOVI:
+0
+abcd
+abcd0000
+abcd00000000
+abcd000000000000
+ffffabcd
+abcdffff
+ffffffffffffabcd
+ffffffffabcdffff
+ffffabcdffffffff
+abcdffffffffffff
+aaaaaaaa
+5555555555555555
+77777777
+3333333333333333
+f8f8f8f8
+1e1e1e1e1e1e1e1e
+3f803f80
+1ff01ff01ff01ff
+7fffc0
+3fff80003fff800
+7fffffffffe00
+abcd1234
+abcd00001234
+abcd000000001234
+abcd12340000
+abcd000012340000
+abcd123400000000
+ffffffffabcd1234
+ffffabcdffff1234
+abcdffffffff1234
+ffffabcd1234ffff
+abcdffff1234ffff
+abcd1234ffffffff
+ffffef0123456789
+abcdef012345ffff
+abcdef0123456789
+3e8
+3e8
+463
+36d
+fffffffffffff3e9
+7b3e8
+3421
+ffffd3af
+fffffc17
+fffffffffffffc18
+fffffc93
+fffffffffffffc93
+0
+3e8
+3e8
+ffffffff
+3e8
+fffffffffffffc17
+e0
+3f8
+318
+3e8
+3e8
+3e8
+7d0
+0
+7d0
+0
+1f4
+0
+1f4
+0
+1f4
+0
+1f4
+0
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/75_array_in_struct_init.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/75_array_in_struct_init.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/75_array_in_struct_init.c	(revision 331)
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+/* This test is a snippet from the J interpreter */
+
+typedef long I;
+typedef struct{I c[4];I b,e,k;} PT;
+
+PT cases[] = {
+ ((I)4194304L +(I)2097152L +(I)67108864L), (I)262144L, (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), -1L, 1,2,1,
+ ((I)+4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L, (I)262144L, (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), 2,3,2,
+ ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)262144L, (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), 1,3,2,
+ ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)524288L, -1L, 1,2,1,
+ ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)1048576L, (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), 1,3,1,
+ ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)262144L, (I)262144L, 1,3,1,
+ ((I)4194304L +(I)2097152L +(I)67108864L), ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), -1L, 1,2,1,
+ (I)33554432L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)2097152L, ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), -1L, 0,2,1,
+ (I)67108864L, ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)134217728L, -1L, 0,2,0,
+};
+
+int main() {
+    int i, j;
+
+    for(j=0; j < sizeof(cases)/sizeof(cases[0]); j++) {
+	for(i=0; i < sizeof(cases->c)/sizeof(cases->c[0]); i++)
+	    printf("cases[%d].c[%d]=%ld\n", j, i, cases[j].c[i]);
+
+	printf("cases[%d].b=%ld\n", j, cases[j].b);
+	printf("cases[%d].e=%ld\n", j, cases[j].e);
+	printf("cases[%d].k=%ld\n", j, cases[j].k);
+	printf("\n");
+    }
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/75_array_in_struct_init.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/75_array_in_struct_init.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/75_array_in_struct_init.expect	(revision 331)
@@ -0,0 +1,72 @@
+cases[0].c[0]=73400320
+cases[0].c[1]=262144
+cases[0].c[2]=805567999
+cases[0].c[3]=-1
+cases[0].b=1
+cases[0].e=2
+cases[0].k=1
+
+cases[1].c[0]=879754751
+cases[1].c[1]=262144
+cases[1].c[2]=262144
+cases[1].c[3]=805567999
+cases[1].b=2
+cases[1].e=3
+cases[1].k=2
+
+cases[2].c[0]=879754751
+cases[2].c[1]=805567999
+cases[2].c[2]=262144
+cases[2].c[3]=805567999
+cases[2].b=1
+cases[2].e=3
+cases[2].k=2
+
+cases[3].c[0]=879754751
+cases[3].c[1]=805830143
+cases[3].c[2]=524288
+cases[3].c[3]=-1
+cases[3].b=1
+cases[3].e=2
+cases[3].k=1
+
+cases[4].c[0]=879754751
+cases[4].c[1]=805830143
+cases[4].c[2]=1048576
+cases[4].c[3]=805830143
+cases[4].b=1
+cases[4].e=3
+cases[4].k=1
+
+cases[5].c[0]=879754751
+cases[5].c[1]=805830143
+cases[5].c[2]=262144
+cases[5].c[3]=262144
+cases[5].b=1
+cases[5].e=3
+cases[5].k=1
+
+cases[6].c[0]=73400320
+cases[6].c[1]=807403007
+cases[6].c[2]=807403007
+cases[6].c[3]=-1
+cases[6].b=1
+cases[6].e=2
+cases[6].k=1
+
+cases[7].c[0]=839122431
+cases[7].c[1]=2097152
+cases[7].c[2]=807403007
+cases[7].c[3]=-1
+cases[7].b=0
+cases[7].e=2
+cases[7].k=1
+
+cases[8].c[0]=67108864
+cases[8].c[1]=807403007
+cases[8].c[2]=134217728
+cases[8].c[3]=-1
+cases[8].b=0
+cases[8].e=2
+cases[8].k=0
+
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.c	(revision 331)
@@ -0,0 +1,41 @@
+#include <stdio.h>
+
+#define $(x) x
+#define $fred 10
+#define joe$ 20
+#define hen$y 30
+
+#define $10(x) x*10
+#define _$10(x) x/10
+
+int main()
+{
+   printf("fred=%d\n", $fred);
+   printf("joe=%d\n", joe$);
+   printf("henry=%d\n", hen$y);
+
+   printf("fred2=%d\n", $($fred));
+   printf("joe2=%d\n", $(joe$));
+   printf("henry2=%d\n", $(hen$y));
+
+   printf("fred10=%d\n", $10($fred));
+   printf("joe_10=%d\n", _$10(joe$));
+
+   int $ = 10;
+   int a100$ = 100;
+   int a$$ = 1000;
+   int a$c$b = 2121;
+   int $100 = 10000;
+   const char *$$$ = "money";
+
+   printf("local=%d\n", $);
+   printf("a100$=%d\n", a100$);
+   printf("a$$=%d\n", a$$);
+   printf("a$c$b=%d\n", a$c$b);
+   printf("$100=%d\n", $100);
+   printf("$$$=%s", $$$);
+
+   return 0;
+}
+
+/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/76_dollars_in_identifiers.expect	(revision 331)
@@ -0,0 +1,14 @@
+fred=10
+joe=20
+henry=30
+fred2=10
+joe2=20
+henry2=30
+fred10=100
+joe_10=2
+local=10
+a100$=100
+a$$=1000
+a$c$b=2121
+$100=10000
+$$$=money
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/77_push_pop_macro.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/77_push_pop_macro.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/77_push_pop_macro.c	(revision 331)
@@ -0,0 +1,30 @@
+#include <stdio.h>
+
+int main()
+{
+    /* must not affect how #pragma ppop_macro works */
+    #define pop_macro foobar1
+
+    /* must not affect how #pragma push_macro works */
+    #define push_macro foobar2
+
+    #undef abort
+    #define abort "111"
+    printf("abort = %s\n", abort);
+
+    #pragma push_macro("abort")
+    #undef abort
+    #define abort "222"
+    printf("abort = %s\n", abort);
+
+    #pragma push_macro("abort")
+    #undef abort
+    #define abort "333"
+    printf("abort = %s\n", abort);
+
+    #pragma pop_macro("abort")
+    printf("abort = %s\n", abort);
+
+    #pragma pop_macro("abort")
+    printf("abort = %s\n", abort);
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/77_push_pop_macro.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/77_push_pop_macro.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/77_push_pop_macro.expect	(revision 331)
@@ -0,0 +1,5 @@
+abort = 111
+abort = 222
+abort = 333
+abort = 222
+abort = 111
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/78_vla_label.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/78_vla_label.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/78_vla_label.c	(revision 331)
@@ -0,0 +1,45 @@
+#include <stdio.h>
+
+/* This test segfaults as of April 27, 2015. */
+void f1(int argc)
+{
+  char test[argc];
+  if(0)
+  label:
+    printf("boom!\n");
+  if(argc-- == 0)
+    return;
+  goto label;
+}
+
+/* This segfaulted on 2015-11-19. */
+void f2(void)
+{
+    goto start;
+    {
+        int a[1 && 1]; /* not a variable-length array */
+        int b[1 || 1]; /* not a variable-length array */
+        int c[1 ? 1 : 1]; /* not a variable-length array */
+    start:
+        a[0] = 0;
+        b[0] = 0;
+        c[0] = 0;
+    }
+}
+
+void f3(void)
+{
+    printf("%d\n", 0 ? printf("x1\n") : 11);
+    printf("%d\n", 1 ? 12 : printf("x2\n"));
+    printf("%d\n", 0 && printf("x3\n"));
+    printf("%d\n", 1 || printf("x4\n"));
+}
+
+int main()
+{
+  f1(2);
+  f2();
+  f3();
+
+  return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/78_vla_label.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/78_vla_label.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/78_vla_label.expect	(revision 331)
@@ -0,0 +1,6 @@
+boom!
+boom!
+11
+12
+0
+1
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/79_vla_continue.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/79_vla_continue.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/79_vla_continue.c	(revision 331)
@@ -0,0 +1,116 @@
+#include <stdio.h>
+
+int f(void)
+{
+  return 5;
+}
+
+void test1()
+{
+  int count = 10;
+  void *addr[10];
+  for(;count--;) {
+    int a[f()];
+
+    addr[count] = a;
+
+    continue;
+  }
+
+  if(addr[9] == addr[0]) {
+    printf("OK\n");
+  } else {
+    printf("NOT OK\n");
+  }
+}
+
+void test2()
+{
+  int count = 10;
+  void *addr[count];
+  for(;count--;) {
+    int a[f()];
+
+    addr[count] = a;
+
+    continue;
+  }
+
+  if(addr[9] == addr[0]) {
+    printf("OK\n");
+  } else {
+    printf("NOT OK\n");
+  }
+}
+
+void test3()
+{
+  int count = 10;
+  void *addr[count];
+  while(count--) {
+    int a[f()];
+
+    addr[count] = a;
+
+    continue;
+  }
+
+  if(addr[9] == addr[0]) {
+    printf("OK\n");
+  } else {
+    printf("NOT OK\n");
+  }
+}
+
+void test4()
+{
+  int count = 10;
+  void *addr[count];
+  do {
+    int a[f()];
+
+    addr[--count] = a;
+
+    continue;
+  } while (count);
+
+  if(addr[9] == addr[0]) {
+    printf("OK\n");
+  } else {
+    printf("NOT OK\n");
+  }
+}
+
+void test5()
+{
+  int count = 10;
+  int a[f()];
+  int c[f()];
+
+  c[0] = 42;
+
+  for(;count--;) {
+    int b[f()];
+    int i;
+    for (i=0; i<f(); i++) {
+      b[i] = count;
+    }
+  }
+
+  if (c[0] == 42) {
+    printf("OK\n");
+  } else {
+    printf("NOT OK\n");
+  }
+}
+
+int main(void)
+{
+  test1();
+  test2();
+  test3();
+  test4();
+  test5();
+
+  return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/79_vla_continue.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/79_vla_continue.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/79_vla_continue.expect	(revision 331)
@@ -0,0 +1,5 @@
+OK
+OK
+OK
+OK
+OK
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/80_flexarray.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/80_flexarray.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/80_flexarray.c	(revision 331)
@@ -0,0 +1,25 @@
+#include <stdio.h>
+struct wchar {
+    char *data; char mem[];
+};
+struct wint {
+    char *data; int mem[];
+};
+int f1char (void) {
+    char s[9]="nonono";
+    struct wchar q = {"bugs"};
+    return !s[0];
+}
+int f1int (void) {
+    char s[9]="nonono";
+    struct wint q = {"bugs"};
+    return !s[0];
+}
+int main (void) {
+   char s[9]="nonono";
+   static struct wchar q = {"bugs", {'c'}};
+   //printf ("tcc has %s %s\n", s, q.data);
+   if (f1char() || f1int())
+     printf ("bla\n");
+   return !s[0];
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/81_types.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/81_types.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/81_types.c	(revision 331)
@@ -0,0 +1,43 @@
+/* The following are all valid decls, even though some subtypes
+   are incomplete.  */
+enum E *e;
+const enum E *e1;
+enum E const *e2;
+struct S *s;
+const struct S *s1;
+struct S const *s2;
+
+/* Various strangely looking declarators, which are all valid
+   and have to map to the same numbered typedefs. */
+typedef int (*fptr1)();
+int f1 (int (), int);
+typedef int (*fptr2)(int x);
+int f2 (int (int x), int);
+typedef int (*fptr3)(int);
+int f3 (int (int), int);
+typedef int (*fptr4[4])(int);
+int f4 (int (*[4])(int), int);
+typedef int (*fptr5)(fptr1);
+int f5 (int (int()), fptr1);
+int f1 (fptr1 fp, int i)
+{
+  return (*fp)(i);
+}
+int f2 (fptr2 fp, int i)
+{
+  return (*fp)(i);
+}
+int f3 (fptr3 fp, int i)
+{
+  return (*fp)(i);
+}
+int f4 (fptr4 fp, int i)
+{
+  return (*fp[i])(i);
+}
+int f5 (fptr5 fp, fptr1 i)
+{
+  return fp(i);
+}
+int f8 (int ([4]), int);
+int main () { return 0; }
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/82_attribs_position.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/82_attribs_position.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/82_attribs_position.c	(revision 331)
@@ -0,0 +1,19 @@
+typedef unsigned short uint16_t;
+typedef unsigned char uint8_t;
+
+typedef union Unaligned16a {
+  uint16_t u;
+  uint8_t b[2];
+} __attribute__((packed)) Unaligned16a;
+
+typedef union __attribute__((packed)) Unaligned16b {
+  uint16_t u;
+  uint8_t b[2];
+} Unaligned16b;
+
+extern void foo (void) __attribute__((stdcall));
+void __attribute__((stdcall)) foo (void)
+{
+}
+
+int main () { return 0; }
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.c	(revision 331)
@@ -0,0 +1,9 @@
+#include <stdio.h>
+double Ð¿ÑÐ¸Ð²ÐµÑ=0.1;
+int LefÃ¨vre=2;
+int main(){
+    printf("Ð¿ÑÐ¸Ð²ÐµÑ=%g\n",Ð¿ÑÐ¸Ð²ÐµÑ);
+    printf("LefÃ¨vre=%d\n",LefÃ¨vre);
+    return 0;
+}
+// pcc & tcc only
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/83_utf8_in_identifiers.expect	(revision 331)
@@ -0,0 +1,2 @@
+Ð¿ÑÐ¸Ð²ÐµÑ=0.1
+LefÃ¨vre=2
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/84_hex-float.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/84_hex-float.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/84_hex-float.c	(revision 331)
@@ -0,0 +1,12 @@
+extern int printf(const char *format, ...);
+
+#define ACPI_TYPE_INVALID       0x1E
+#define NUM_NS_TYPES            ACPI_TYPE_INVALID+1
+int array[NUM_NS_TYPES];
+
+#define n 0xe
+int main()
+{
+    printf("n+1 = %d\n", n+1);
+//    printf("n+1 = %d\n", 0xe+1);
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/84_hex-float.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/84_hex-float.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/84_hex-float.expect	(revision 331)
@@ -0,0 +1,1 @@
+n+1 = 15
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/85_asm-outside-function.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/85_asm-outside-function.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/85_asm-outside-function.c	(revision 331)
@@ -0,0 +1,9 @@
+extern int printf (const char *, ...);
+extern void vide(void);
+__asm__("vide: ret");
+
+int main() {
+    vide();
+    printf ("okay\n");
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/85_asm-outside-function.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/85_asm-outside-function.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/85_asm-outside-function.expect	(revision 331)
@@ -0,0 +1,1 @@
+okay
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/86_memory-model.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/86_memory-model.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/86_memory-model.c	(revision 331)
@@ -0,0 +1,38 @@
+#include <stdio.h>
+
+int
+main()
+{
+#if defined(__LLP64__)
+	if (sizeof(short) == 2
+	    && sizeof(int) == 4
+	    && sizeof(long int) == 4
+	    && sizeof(long long int) == 8
+	    && sizeof(void*) == 8) {
+		(void)printf("Ok\n");
+	} else {
+		(void)printf("KO __LLP64__\n");
+	}
+#elif defined(__LP64__)
+	if (sizeof(short) == 2
+	    && sizeof(int) == 4
+	    && sizeof(long int) == 8
+	    && sizeof(long long int) == 8
+	    && sizeof(void*) == 8) {
+		(void)printf("Ok\n");
+	} else {
+		(void)printf("KO __LP64__\n");
+	}
+#elif defined(__ILP32__)
+	if (sizeof(short) == 2
+	    && sizeof(int) == 4
+	    && sizeof(long int) == 4
+	    && sizeof(void*) == 4) {
+		(void)printf("Ok\n");
+	} else {
+		(void)printf("KO __ILP32__\n");
+	}
+#else
+	(void)printf("KO no __*LP*__ defined.\n");
+#endif
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/86_memory-model.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/86_memory-model.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/86_memory-model.expect	(revision 331)
@@ -0,0 +1,1 @@
+Ok
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/87_dead_code.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/87_dead_code.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/87_dead_code.c	(revision 331)
@@ -0,0 +1,122 @@
+/* This checks various ways of dead code inside if statements
+   where there are non-obvious ways of how the code is actually
+   not dead due to reachable by labels.  */
+extern int printf (const char *, ...);
+static void kb_wait_1(void)
+{
+  unsigned long timeout = 2;
+  do {
+      /* Here the else arm is a statement expression that's supposed
+         to be suppressed.  The label inside the while would unsuppress
+	 code generation again if not handled correctly.  And that
+	 would wreak havoc to the cond-expression because there's no
+	 jump-around emitted, the whole statement expression really
+	 needs to not generate code (perhaps except useless forward jumps).  */
+      (1 ? 
+       printf("timeout=%ld\n", timeout) :
+       ({
+	int i = 1;
+	while (1)
+	  while (i--)
+	    some_label:
+	      printf("error\n");
+	goto some_label;
+	})
+      );
+      timeout--;
+  } while (timeout);
+}
+int main (void)
+{
+  int i = 1;
+  kb_wait_1();
+
+  /* Simple test of dead code at first sight which isn't actually dead. */
+  if (0) {
+yeah:
+      printf ("yeah\n");
+  } else {
+      printf ("boo\n");
+  }
+  if (i--)
+    goto yeah;
+
+  /* Some more non-obvious uses where the problems are loops, so that even
+     the first loop statements aren't actually dead.  */
+  i = 1;
+  if (0) {
+      while (i--) {
+	  printf ("once\n");
+enterloop:
+	  printf ("twice\n");
+      }
+  }
+  if (i >= 0)
+    goto enterloop;
+
+  /* The same with statement expressions.  One might be tempted to
+     handle them specially by counting if inside statement exprs and
+     not unsuppressing code at loops at all then.
+     See kb_wait_1 for the other side of the medal where that wouldn't work.  */
+  i = ({
+      int j = 1;
+      if (0) {
+	  while (j--) {
+	      printf ("SEonce\n");
+    enterexprloop:
+	      printf ("SEtwice\n");
+	  }
+      }
+      if (j >= 0)
+	goto enterexprloop;
+      j; });
+
+  /* The other two loop forms: */
+  i = 1;
+  if (0) {
+      for (i = 1; i--;) {
+	  printf ("once2\n");
+enterloop2:
+	  printf ("twice2\n");
+      }
+  }
+  if (i > 0)
+    goto enterloop2;
+
+  i = 1;
+  if (0) {
+      do {
+	  printf ("once3\n");
+enterloop3:
+	  printf ("twice3\n");
+      } while (i--);
+  }
+  if (i > 0)
+    goto enterloop3;
+
+  /* And check that case and default labels have the same effect
+     of disabling code suppression.  */
+  i = 41;
+  switch (i) {
+      if (0) {
+	  printf ("error\n");
+      case 42:
+	  printf ("error2\n");
+      case 41:
+	  printf ("caseok\n");
+      }
+  }
+
+  i = 41;
+  switch (i) {
+      if (0) {
+	  printf ("error3\n");
+      default:
+	  printf ("caseok2\n");
+	  break;
+      case 42:
+	  printf ("error4\n");
+      }
+  }
+  return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/87_dead_code.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/87_dead_code.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/87_dead_code.expect	(revision 331)
@@ -0,0 +1,18 @@
+timeout=2
+timeout=1
+boo
+yeah
+twice
+once
+twice
+SEtwice
+SEonce
+SEtwice
+twice2
+once2
+twice2
+twice3
+once3
+twice3
+caseok
+caseok2
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/88_codeopt.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/88_codeopt.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/88_codeopt.c	(revision 331)
@@ -0,0 +1,68 @@
+/* Check some way in where code suppression caused various
+   miscompilations.  */
+extern int printf (const char *, ...);
+typedef unsigned long size_t;
+
+size_t _brk_start, _brk_end;
+void * extend_brk(size_t size, size_t align)
+{
+    size_t mask = align - 1;
+    void *ret = 0;
+
+     do {
+	 if (__builtin_expect(!!(_brk_start == 0), 0))
+	   do {
+	       printf("wrong1\n");
+	   } while (0);
+     } while (0);
+     _brk_end = (_brk_end + mask) & ~mask;
+     ret = (void *)_brk_end;
+     _brk_end += size;
+
+     return ret;
+}
+
+static void get_args (int a, int b)
+{
+  if (a != 1)
+    printf("wrong2\n");
+  else
+    printf("okay\n");
+}
+
+void bla(void)
+{
+  int __ret = 42;
+  ({
+    if (__builtin_expect(!!(0), 0)) {
+      if (__builtin_expect(!!__ret, 0))
+        printf("wrong3\n");
+      int x = !!(__ret);
+    }
+    __ret;
+  });
+  get_args(!!__ret, sizeof(__ret));
+}
+
+_Bool chk(unsigned long addr, unsigned long limit, unsigned long size)
+{
+  _Bool ret;
+  /* This just needs to compile, no runtime test.  (And it doesn't compile
+     only with certain internal checking added that's not committed).  */
+  if (0)
+    ret = 0 != (!!(addr > limit - size));
+}
+
+int main()
+{
+  void *r;
+  _brk_start = 1024;
+  _brk_end = 1024;
+  r = extend_brk (4096, 16);
+  if (!r)
+    printf("wrong4\n");
+  else
+    printf("okay\n");
+  bla();
+  return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/88_codeopt.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/88_codeopt.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/88_codeopt.expect	(revision 331)
@@ -0,0 +1,2 @@
+okay
+okay
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/89_nocode_wanted.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/89_nocode_wanted.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/89_nocode_wanted.c	(revision 331)
@@ -0,0 +1,112 @@
+extern int printf(const char *format, ...);
+static void kb_wait_1(void)
+{
+    unsigned long timeout = 2;
+    do {
+        (1 ?
+            printf("timeout=%ld\n", timeout) :
+            ({
+                while (1)
+                    printf("error\n");
+            })
+        );
+        timeout--;
+    } while (timeout);
+}
+static void kb_wait_2(void)
+{
+    unsigned long timeout = 2;
+    do {
+        (1 ?
+            printf("timeout=%ld\n", timeout) :
+            ({
+                for (;;)
+                    printf("error\n");
+            })
+        );
+        timeout--;
+    } while (timeout);
+}
+static void kb_wait_2_1(void)
+{
+    unsigned long timeout = 2;
+    do {
+        (1 ?
+            printf("timeout=%ld\n", timeout) :
+            ({
+                do {
+                    printf("error\n");
+		} while (1);
+            })
+        );
+        timeout--;
+    } while (timeout);
+}
+static void kb_wait_2_2(void)
+{
+    unsigned long timeout = 2;
+    do {
+        (1 ?
+            printf("timeout=%ld\n", timeout) :
+            ({
+                label:
+                    printf("error\n");
+		goto label;
+            })
+        );
+        timeout--;
+    } while (timeout);
+}
+static void kb_wait_3(void)
+{
+    unsigned long timeout = 2;
+    do {
+        (1 ?
+            printf("timeout=%ld\n", timeout) :
+            ({
+                int i = 1;
+                goto label;
+                i = i + 2;
+            label:
+                i = i + 3;
+            })
+        );
+        timeout--;
+    } while (timeout);
+}
+static void kb_wait_4(void)
+{
+    unsigned long timeout = 2;
+    do {
+        (1 ?
+            printf("timeout=%ld\n", timeout) :
+            ({
+                switch(timeout) {
+                    case 2:
+                        printf("timeout is 2");
+                        break;
+                    case 1:
+                        printf("timeout is 1");
+                        break;
+                    default:
+                        printf("timeout is 0?");
+                        break;
+                };
+                // return;
+            })
+        );
+        timeout--;
+    } while (timeout);
+}
+int main()
+{
+    printf("begin\n");
+    kb_wait_1();
+    kb_wait_2();
+    kb_wait_2_1();
+    kb_wait_2_2();
+    kb_wait_3();
+    kb_wait_4();
+    printf("end\n");
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/89_nocode_wanted.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/89_nocode_wanted.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/89_nocode_wanted.expect	(revision 331)
@@ -0,0 +1,14 @@
+begin
+timeout=2
+timeout=1
+timeout=2
+timeout=1
+timeout=2
+timeout=1
+timeout=2
+timeout=1
+timeout=2
+timeout=1
+timeout=2
+timeout=1
+end
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/90_struct-init.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/90_struct-init.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/90_struct-init.c	(revision 331)
@@ -0,0 +1,284 @@
+typedef unsigned char u8;
+typedef struct {} empty_s;
+struct contains_empty {
+    u8 a;
+    empty_s empty;
+    u8 b;
+};
+struct contains_empty ce = { { (1) }, (empty_s){}, 022, };
+/* The following decl of 'q' would demonstrate the TCC bug in init_putv when
+   handling copying compound literals.  (Compound literals
+   aren't acceptable constant initializers in isoc99, but
+   we accept them like gcc, except for this case)
+//char *q = (char *){ "trara" }; */
+struct SS {u8 a[3], b; };
+struct SS sinit16[] = { { 1 }, 2 };
+struct S
+{
+  u8 a,b;
+  u8 c[2];
+};
+
+struct T
+{
+  u8 s[16];
+  u8 a;
+};
+
+struct U
+{
+  u8 a;
+  struct S s;
+  u8 b;
+  struct T t;
+};
+
+struct V
+{
+  struct S s;
+  struct T t;
+  u8 a;
+};
+
+struct W
+{
+  struct V t;
+  struct S s[];
+};
+
+struct S gs = ((struct S){1, 2, 3, 4});
+struct S gs2 = {1, 2, {3, 4}};
+struct T gt = {"hello", 42};
+struct U gu = {3, 5,6,7,8, 4, "huhu", 43};
+struct U gu2 = {3, {5,6,7,8}, 4, {"huhu", 43}};
+/* Optional braces around scalar initializers.  Accepted, but with
+   a warning.  */
+struct U gu3 = { {3}, {5,6,7,8,}, 4, {"huhu", 43}};
+/* Many superfluous braces and leaving out one initializer for U.s.c[1] */
+struct U gu4 = { 3, {5,6,7,},  5, { "bla", {44}} };
+/* Superfluous braces and useless parens around values */
+struct S gs3 = { (1), {(2)}, {(((3))), {4}}};
+/* Superfluous braces, and leaving out braces for V.t, plus cast */
+struct V gv = {{{3},4,{5,6}}, "haha", (u8)45, 46};
+/* Compound literal */
+struct V gv2 = {(struct S){7,8,{9,10}}, {"hihi", 47}, 48};
+/* Parens around compound literal */
+struct V gv3 = {((struct S){7,8,{9,10}}), {"hoho", 49}, 50};
+/* Initialization of a flex array member (warns in GCC) */
+struct W gw = {{1,2,3,4}, {1,2,3,4,5}};
+
+union UU {
+    u8 a;
+    u8 b;
+};
+struct SU {
+    union UU u;
+    u8 c;
+};
+struct SU gsu = {5,6};
+
+/* Unnamed struct/union members aren't ISO C, but it's a widely accepted
+   extension.  See below for further extensions to that under -fms-extension.*/
+union UV {
+    struct {u8 a,b;};
+    struct S s;
+};
+union UV guv = {{6,5}};
+union UV guv2 = {{.b = 7, .a = 8}};
+union UV guv3 = {.b = 8, .a = 7};
+
+/* Under -fms-extensions also the following is valid:
+union UV2 {
+    struct Anon {u8 a,b;};    // unnamed member, but tagged struct, ...
+    struct S s;
+};
+struct Anon gan = { 10, 11 }; // ... which makes it available here.
+union UV2 guv4 = {{4,3}};     // and the other inits from above as well
+*/
+
+struct in6_addr {
+    union {
+	u8 u6_addr8[16];
+	unsigned short u6_addr16[8];
+    } u;
+};
+struct flowi6 {
+    struct in6_addr saddr, daddr;
+};
+struct pkthdr {
+    struct in6_addr daddr, saddr;
+};
+struct pkthdr phdr = { { { 6,5,4,3 } }, { { 9,8,7,6 } } };
+
+struct Wrap {
+    void *func;
+};
+int global;
+void inc_global (void)
+{
+  global++;
+}
+
+struct Wrap global_wrap[] = {
+    ((struct Wrap) {inc_global}),
+    inc_global,
+};
+
+#include <stdio.h>
+void print_ (const char *name, const u8 *p, long size)
+{
+  printf ("%s:", name);
+  while (size--) {
+      printf (" %x", *p++);
+  }
+  printf ("\n");
+}
+#define print(x) print_(#x, (u8*)&x, sizeof (x))
+#if 1
+void foo (struct W *w, struct pkthdr *phdr_)
+{
+  struct S ls = {1, 2, 3, 4};
+  struct S ls2 = {1, 2, {3, 4}};
+  struct T lt = {"hello", 42};
+  struct U lu = {3, 5,6,7,8, 4, "huhu", 43};
+  struct U lu1 = {3, ls, 4, {"huhu", 43}};
+  struct U lu2 = {3, (ls), 4, {"huhu", 43}};
+  const struct S *pls = &ls;
+  struct S ls21 = *pls;
+  struct U lu22 = {3, *pls, 4, {"huhu", 43}};
+  /* Incomplete bracing.  */
+  struct U lu21 = {3, ls, 4, "huhu", 43};
+  /* Optional braces around scalar initializers.  Accepted, but with
+     a warning.  */
+  struct U lu3 = { 3, {5,6,7,8,}, 4, {"huhu", 43}};
+  /* Many superfluous braces and leaving out one initializer for U.s.c[1] */
+  struct U lu4 = { 3, {5,6,7,},  5, { "bla", 44} };
+  /* Superfluous braces and useless parens around values */
+  struct S ls3 = { (1), (2), {(((3))), 4}};
+  /* Superfluous braces, and leaving out braces for V.t, plus cast */
+  struct V lv = {{3,4,{5,6}}, "haha", (u8)45, 46};
+  /* Compound literal */
+  struct V lv2 = {(struct S)w->t.s, {"hihi", 47}, 48};
+  /* Parens around compound literal */
+  struct V lv3 = {((struct S){7,8,{9,10}}), ((const struct W *)w)->t.t, 50};
+  const struct pkthdr *phdr = phdr_;
+  struct flowi6 flow = { .daddr = phdr->daddr, .saddr = phdr->saddr };
+  int elt = 0x42;
+  /* Range init, overlapping */
+  struct T lt2 = { { [1 ... 5] = 9, [6 ... 10] = elt, [4 ... 7] = elt+1 }, 1 };
+  print(ls);
+  print(ls2);
+  print(lt);
+  print(lu);
+  print(lu1);
+  print(lu2);
+  print(ls21);
+  print(lu21);
+  print(lu22);
+  print(lu3);
+  print(lu4);
+  print(ls3);
+  print(lv);
+  print(lv2);
+  print(lv3);
+  print(lt2);
+  print(flow);
+}
+#endif
+
+void test_compound_with_relocs (void)
+{
+  struct Wrap local_wrap[] = {
+      ((struct Wrap) {inc_global}),
+      inc_global,
+  };
+  void (*p)(void);
+  p = global_wrap[0].func; p();
+  p = global_wrap[1].func; p();
+  p = local_wrap[0].func; p();
+  p = local_wrap[1].func; p();
+}
+
+void sys_ni(void) { printf("ni\n"); }
+void sys_one(void) { printf("one\n"); }
+void sys_two(void) { printf("two\n"); }
+void sys_three(void) { printf("three\n"); }
+typedef void (*fptr)(void);
+const fptr table[3] = {
+    [0 ... 2] = &sys_ni,
+    [0] = sys_one,
+    [1] = sys_two,
+    [2] = sys_three,
+};
+
+void test_multi_relocs(void)
+{
+  int i;
+  for (i = 0; i < sizeof(table)/sizeof(table[0]); i++)
+    table[i]();
+}
+
+
+/* Following is from GCC gcc.c-torture/execute/20050613-1.c.  */
+
+struct SEA { int i; int j; int k; int l; };
+struct SEB { struct SEA a; int r[1]; };
+struct SEC { struct SEA a; int r[0]; };
+struct SED { struct SEA a; int r[]; };
+
+static void
+test_correct_filling (struct SEA *x)
+{
+  static int i;
+  if (x->i != 0 || x->j != 5 || x->k != 0 || x->l != 0)
+    printf("sea_fill%d: wrong\n", i);
+  else
+    printf("sea_fill%d: okay\n", i);
+  i++;
+}
+
+int
+test_zero_init (void)
+{
+  /* The peculiarity here is that only a.j is initialized.  That
+     means that all other members must be zero initialized.  TCC
+     once didn't do that for sub-level designators.  */
+  struct SEB b = { .a.j = 5 };
+  struct SEC c = { .a.j = 5 };
+  struct SED d = { .a.j = 5 };
+  test_correct_filling (&b.a);
+  test_correct_filling (&c.a);
+  test_correct_filling (&d.a);
+  return 0;
+}
+
+
+int main()
+{
+  print(ce);
+  print(gs);
+  print(gs2);
+  print(gt);
+  print(gu);
+  print(gu2);
+  print(gu3);
+  print(gu4);
+  print(gs3);
+  print(gv);
+  print(gv2);
+  print(gv3);
+  print(sinit16);
+  print(gw);
+  print(gsu);
+  print(guv);
+  print(guv.b);
+  print(guv2);
+  print(guv3);
+  print(phdr);
+  foo(&gw, &phdr);
+  //printf("q: %s\n", q);
+  test_compound_with_relocs();
+  test_multi_relocs();
+  test_zero_init();
+  return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/90_struct-init.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/90_struct-init.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/90_struct-init.expect	(revision 331)
@@ -0,0 +1,43 @@
+ce: 1 12
+gs: 1 2 3 4
+gs2: 1 2 3 4
+gt: 68 65 6c 6c 6f 0 0 0 0 0 0 0 0 0 0 0 2a
+gu: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+gu2: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+gu3: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+gu4: 3 5 6 7 0 5 62 6c 61 0 0 0 0 0 0 0 0 0 0 0 0 0 2c
+gs3: 1 2 3 4
+gv: 3 4 5 6 68 61 68 61 0 0 0 0 0 0 0 0 0 0 0 0 2d 2e
+gv2: 7 8 9 a 68 69 68 69 0 0 0 0 0 0 0 0 0 0 0 0 2f 30
+gv3: 7 8 9 a 68 6f 68 6f 0 0 0 0 0 0 0 0 0 0 0 0 31 32
+sinit16: 1 0 0 0 2 0 0 0
+gw: 1 2 3 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+gsu: 5 6
+guv: 6 5 0 0
+guv.b: 5
+guv2: 8 7 0 0
+guv3: 7 8 0 0
+phdr: 6 5 4 3 0 0 0 0 0 0 0 0 0 0 0 0 9 8 7 6 0 0 0 0 0 0 0 0 0 0 0 0
+ls: 1 2 3 4
+ls2: 1 2 3 4
+lt: 68 65 6c 6c 6f 0 0 0 0 0 0 0 0 0 0 0 2a
+lu: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+lu1: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+lu2: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+ls21: 1 2 3 4
+lu21: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+lu22: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+lu3: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b
+lu4: 3 5 6 7 0 5 62 6c 61 0 0 0 0 0 0 0 0 0 0 0 0 0 2c
+ls3: 1 2 3 4
+lv: 3 4 5 6 68 61 68 61 0 0 0 0 0 0 0 0 0 0 0 0 2d 2e
+lv2: 1 2 3 4 68 69 68 69 0 0 0 0 0 0 0 0 0 0 0 0 2f 30
+lv3: 7 8 9 a 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32
+lt2: 0 9 9 9 43 43 43 43 42 42 42 0 0 0 0 0 1
+flow: 9 8 7 6 0 0 0 0 0 0 0 0 0 0 0 0 6 5 4 3 0 0 0 0 0 0 0 0 0 0 0 0
+one
+two
+three
+sea_fill0: okay
+sea_fill1: okay
+sea_fill2: okay
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.c	(revision 331)
@@ -0,0 +1,15 @@
+int printf(const char *, ...);
+char t[] = "012345678";
+
+int main(void)
+{
+    char *data = t;
+    unsigned long long r = 4;
+    unsigned a = 5;
+    unsigned long long b = 12;
+
+    *(unsigned*)(data + r) += a - b;
+
+    printf("data = \"%s\"\n", data);
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/91_ptr_longlong_arith32.expect	(revision 331)
@@ -0,0 +1,1 @@
+data = "0123-5678"
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/92_enum_bitfield.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/92_enum_bitfield.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/92_enum_bitfield.c	(revision 331)
@@ -0,0 +1,57 @@
+/* This checks if enums needing 8 bit but only having positive
+   values are correctly zero extended (instead of sign extended)
+   when stored into/loaded from a 8 bit bit-field of enum type (which
+   itself is implementation defined, so isn't necessarily supported by all
+   other compilers).  */
+enum tree_code {
+  SOME_CODE = 148, /* has bit 7 set, and hence all further enum values as well */
+  LAST_AND_UNUSED_TREE_CODE
+};
+typedef union tree_node *tree;
+struct tree_common
+{
+  union tree_node *chain;
+  union tree_node *type;
+  enum tree_code code : 8;
+  unsigned side_effects_flag : 1;
+};
+union tree_node
+{
+  struct tree_common common;
+ };
+enum c_tree_code {
+  C_DUMMY_TREE_CODE = LAST_AND_UNUSED_TREE_CODE,
+  STMT_EXPR,
+  LAST_C_TREE_CODE
+};
+enum cplus_tree_code {
+  CP_DUMMY_TREE_CODE = LAST_C_TREE_CODE,
+  AMBIG_CONV,
+  LAST_CPLUS_TREE_CODE
+};
+
+extern int printf(const char *, ...);
+int blah(){return 0;}
+
+int convert_like_real (tree convs)
+{
+  switch (((enum tree_code) (convs)->common.code))
+    {
+    case AMBIG_CONV: /* This has bit 7 set, which must not be the sign
+			bit in tree_common.code, i.e. the bitfield must
+			be somehow marked unsigned.  */
+      return blah();
+    default:
+      break;
+    };
+   printf("unsigned enum bit-fields broken\n");
+}
+
+int main()
+{
+  union tree_node convs;
+
+  convs.common.code = AMBIG_CONV;
+  convert_like_real (&convs);
+  return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/93_integer_promotion.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/93_integer_promotion.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/93_integer_promotion.c	(revision 331)
@@ -0,0 +1,71 @@
+/* integer promotion */
+
+int printf(const char*, ...);
+#define promote(s) printf(" %ssigned : %s\n", (s) - 100 < 0 ? "  " : "un", #s);
+
+int main (void)
+{
+    struct {
+        unsigned ub:3;
+        unsigned u:32;
+        unsigned long long ullb:35;
+        unsigned long long ull:64;
+        unsigned char c;
+    } s = { 1, 1, 1 };
+
+    promote(s.ub);
+    promote(s.u);
+    promote(s.ullb);
+    promote(s.ull);
+    promote(s.c);
+    printf("\n");
+
+    promote((1 ? s.ub : 1));
+    promote((1 ? s.u : 1));
+    promote((1 ? s.ullb : 1));
+    promote((1 ? s.ull : 1));
+    promote((1 ? s.c : 1));
+    printf("\n");
+
+    promote(s.ub << 1);
+    promote(s.u << 1);
+    promote(s.ullb << 1);
+    promote(s.ull << 1);
+    promote(s.c << 1);
+    printf("\n");
+
+    promote(+s.ub);
+    promote(+s.u);
+    promote(+s.ullb);
+    promote(+s.ull);
+    promote(+s.c);
+    printf("\n");
+
+    promote(-s.ub);
+    promote(-s.u);
+    promote(-s.ullb);
+    promote(-s.ull);
+    promote(-s.c);
+    printf("\n");
+
+    promote(~s.ub);
+    promote(~s.u);
+    promote(~s.ullb);
+    promote(~s.ull);
+    promote(~s.c);
+    printf("\n");
+
+    promote(!s.ub);
+    promote(!s.u);
+    promote(!s.ullb);
+    promote(!s.ull);
+    promote(!s.c);
+    printf("\n");
+
+    promote(+(unsigned)s.ub);
+    promote(-(unsigned)s.ub);
+    promote(~(unsigned)s.ub);
+    promote(!(unsigned)s.ub);
+
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/93_integer_promotion.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/93_integer_promotion.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/93_integer_promotion.expect	(revision 331)
@@ -0,0 +1,46 @@
+   signed : s.ub
+ unsigned : s.u
+   signed : s.ullb
+ unsigned : s.ull
+   signed : s.c
+
+   signed : (1 ? s.ub : 1)
+ unsigned : (1 ? s.u : 1)
+   signed : (1 ? s.ullb : 1)
+ unsigned : (1 ? s.ull : 1)
+   signed : (1 ? s.c : 1)
+
+   signed : s.ub << 1
+ unsigned : s.u << 1
+   signed : s.ullb << 1
+ unsigned : s.ull << 1
+   signed : s.c << 1
+
+   signed : +s.ub
+ unsigned : +s.u
+   signed : +s.ullb
+ unsigned : +s.ull
+   signed : +s.c
+
+   signed : -s.ub
+ unsigned : -s.u
+   signed : -s.ullb
+ unsigned : -s.ull
+   signed : -s.c
+
+   signed : ~s.ub
+ unsigned : ~s.u
+   signed : ~s.ullb
+ unsigned : ~s.ull
+   signed : ~s.c
+
+   signed : !s.ub
+   signed : !s.u
+   signed : !s.ullb
+   signed : !s.ull
+   signed : !s.c
+
+ unsigned : +(unsigned)s.ub
+ unsigned : -(unsigned)s.ub
+ unsigned : ~(unsigned)s.ub
+   signed : !(unsigned)s.ub
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/94_generic.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/94_generic.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/94_generic.c	(revision 331)
@@ -0,0 +1,64 @@
+#include <stdio.h>
+
+const int a = 0;
+
+struct a {
+	int a;
+};
+
+struct b {
+	int a;
+};
+
+int a_f()
+{
+	return 20;
+}
+
+int b_f()
+{
+	return 10;
+}
+
+typedef int int_type1;
+
+#define gen_sw(a) _Generic(a, const char *: 1, default: 8, int: 123);
+
+int main()
+{
+	int i = 0;
+	signed long int l = 2;
+	struct b titi;
+	const int * const ptr;
+	const char *ti;
+	int_type1 i2;
+
+	i = _Generic(a, int: a_f, const int: b_f)();
+	printf("%d\n", i);
+	i = _Generic(a, int: a_f() / 2, const int: b_f() / 2);
+	printf("%d\n", i);
+	i = _Generic(ptr, int *:1, int * const:2, default:20);
+	printf("%d\n", i);
+	i = gen_sw(a);
+	printf("%d\n", i);
+	i = _Generic(titi, struct a:1, struct b:2, default:20);
+	printf("%d\n", i);
+	i = _Generic(i2, char: 1, int : 0);
+	printf("%d\n", i);
+	i = _Generic(a, char:1, int[4]:2, default:5);
+	printf("%d\n", i);
+	i = _Generic(17, int :1, int **:2);
+	printf("%d\n", i);
+	i = _Generic(17L, int :1, long :2, long long : 3);
+	printf("%d\n", i);
+	i = _Generic("17, io", char *: 3, const char *: 1);
+	printf("%d\n", i);
+	i = _Generic(ti, const unsigned char *:1, const char *:4, char *:3,
+		     const signed char *:2);
+	printf("%d\n", i);
+	printf("%s\n", _Generic(i + 2L, long: "long", int: "int",
+				long long: "long long"));
+	i = _Generic(l, long: 1, int: 2);
+	printf("%d\n", i);
+	return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/94_generic.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/94_generic.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/94_generic.expect	(revision 331)
@@ -0,0 +1,13 @@
+20
+10
+20
+123
+2
+0
+5
+1
+2
+3
+4
+long
+1
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields.c	(revision 331)
@@ -0,0 +1,218 @@
+/* ----------------------------------------------------------------------- */
+#if TEST == 1
+{
+    struct M P A __s
+    {
+        unsigned x : 12;
+        unsigned char y : 7;
+        unsigned z : 28;
+        unsigned a: 4;
+        unsigned b: 5;
+    };
+    TEST_STRUCT(0x333,0x44,0x555555,6,7);
+}
+
+/* ----------------------------------------------------------------------- */
+#elif TEST == 2
+{
+    struct M P __s
+    {
+        int x: 12;
+        char y: 6;
+        long long z:63;
+        A char a:4;
+        long long b:2;
+
+    };
+    TEST_STRUCT(3,30,0x123456789abcdef0LL,5,2);
+}
+
+/* ----------------------------------------------------------------------- */
+#elif TEST == 3
+{
+    struct M P __s
+    {
+        unsigned x:5, y:5, :0, z:5; char a:5; A short b:5;
+    };
+    TEST_STRUCT(21,23,25,6,14);
+}
+
+/* ----------------------------------------------------------------------- */
+#elif TEST == 4
+{
+    struct M P __s {
+        int x : 3;
+        int : 2;
+        int y : 1;
+        int : 0;
+        int z : 5;
+        int a : 7;
+        unsigned int b : 7;
+    };
+    TEST_STRUCT(3,1,15,120,120);
+}
+
+/* ----------------------------------------------------------------------- */
+#elif TEST == 5
+{
+    struct M P __s {
+        long long x : 45;
+        long long : 2;
+        long long y : 30;
+        unsigned long long z : 38;
+        char a; short b;
+    };
+    TEST_STRUCT(0x123456789ULL, 120<<25, 120, 0x44, 0x77);
+}
+
+/* ----------------------------------------------------------------------- */
+#elif TEST == 6
+{
+    struct M P __s {
+	int a;
+	signed char b;
+	int x : 12, y : 4, : 0, : 4, z : 3;
+	char d;
+    };
+    TEST_STRUCT(1,2,3,4,-3);
+}
+
+/* ----------------------------------------------------------------------- */
+#elif defined PACK
+
+#if PACK
+# pragma pack(push,1)
+# define P //_P
+#else
+# define P
+#endif
+
+printf("\n\n" + 2*top);
+#define TEST 1
+#include SELF
+top = 0;
+#define TEST 2
+#include SELF
+#define TEST 3
+#include SELF
+#define TEST 4
+#include SELF
+#define TEST 5
+#include SELF
+#define TEST 6
+#include SELF
+
+#if PACK
+# pragma pack(pop)
+#endif
+
+#undef P
+#undef PACK
+
+/* ----------------------------------------------------------------------- */
+#elif defined ALIGN
+
+#if ALIGN
+# define A _A(16)
+#else
+# define A
+#endif
+
+#define PACK 0
+#include SELF
+#define PACK 1
+#include SELF
+
+#undef A
+#undef ALIGN
+
+/* ----------------------------------------------------------------------- */
+#elif defined MS_BF
+
+#if MS_BF
+# ifdef __TINYC__
+#  pragma comment(option, "-mms-bitfields")
+# elif defined __GNUC__
+#  define M __attribute__((ms_struct))
+# endif
+#else
+# ifdef __TINYC__
+#  pragma comment(option, "-mno-ms-bitfields")
+# elif defined __GNUC__
+#  define M __attribute__((gcc_struct))
+# endif
+#endif
+#ifndef M
+# define M
+#endif
+
+#define ALIGN 0
+#include SELF
+#define ALIGN 1
+#include SELF
+
+#undef M
+#undef MS_BF
+
+/* ----------------------------------------------------------------------- */
+#else
+
+#include <stdio.h>
+#include <string.h>
+/* some gcc headers #define __attribute__ to empty if it's not gcc */
+#undef __attribute__
+
+void dump(void *p, int s)
+{
+    int i;
+    for (i = s; --i >= 0;)
+        printf("%02X", ((unsigned char*)p)[i]);
+    printf("\n");
+}
+
+#define pv(m) \
+    printf(sizeof (s->m + 0) == 8 ? " %016llx" : " %02x", s->m)
+
+#define TEST_STRUCT(v1,v2,v3,v4,v5) { \
+        struct __s _s, *s = & _s; \
+        printf("\n---- TEST %d%s%s%s ----\n" + top, \
+            TEST, MS_BF?" - MS-BITFIELDS":"", \
+            PACK?" - PACKED":"", \
+            ALIGN?" - WITH ALIGN":""); \
+        memset(s, 0, sizeof *s); \
+        s->x = -1, s->y = -1, s->z = -1, s->a = -1, s->b = -1; \
+        printf("bits in use : "), dump(s, sizeof *s); \
+        s->x = v1, s->y = v2, s->z = v3, s->a += v4, ++s->a, s->b = v5; \
+        printf("bits as set : "), dump(s, sizeof *s); \
+        printf("values      :"), pv(x), pv(y), pv(z), pv(a), pv(b), printf("\n"); \
+        printf("align/size  : %d %d\n", alignof(struct __s),sizeof(struct __s)); \
+    }
+
+#ifdef _MSC_VER
+# define _A(n) __declspec(align(n))
+# define _P
+# define alignof(x) __alignof(x)
+#else
+# define _A(n) __attribute__((aligned(n)))
+# define _P __attribute__((packed))
+# define alignof(x) __alignof__(x)
+#endif
+
+#ifndef MS_BITFIELDS
+# define MS_BITFIELDS 0
+#endif
+
+#define SELF "95_bitfields.c"
+
+int top = 1;
+
+int main()
+{
+#define MS_BF MS_BITFIELDS
+#include SELF
+    return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+#endif
+#undef TEST
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields.expect	(revision 331)
@@ -0,0 +1,149 @@
+---- TEST 1 ----
+bits in use : 0000001FFFFFFFFF007F0FFF
+bits as set : 000000076055555500440333
+values      : 333 44 555555 06 07
+align/size  : 4 12
+
+---- TEST 2 ----
+bits in use : 000000000000003F7FFFFFFFFFFFFFFF00000000003F0FFF
+bits as set : 0000000000000025123456789ABCDEF000000000001E0003
+values      : 03 1e 123456789abcdef0 05 fffffffe
+align/size  : 8 24
+
+---- TEST 3 ----
+bits in use : 001F1F1F000003FF
+bits as set : 000E0619000002F5
+values      : 15 17 19 06 0e
+align/size  : 4 8
+
+---- TEST 4 ----
+bits in use : 0007FFFF00000027
+bits as set : 00078F0F00000023
+values      : 03 ffffffff 0f fffffff8 78
+align/size  : 4 8
+
+---- TEST 5 ----
+bits in use : FFFFFF3FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF
+bits as set : 007744000000007800000000300000000000000123456789
+values      : 0000000123456789 f0000000 0000000000000078 44 77
+align/size  : 8 24
+
+---- TEST 6 ----
+bits in use : 0000007000FFFFFFFFFFFFFF
+bits as set : 00000030002001FD00000004
+values      : 01 02 03 04 fffffffd
+align/size  : 4 12
+
+
+
+---- TEST 1 - PACKED ----
+bits in use : FFFFFFFFFFFFFF
+bits as set : 3B02AAAAAC4333
+values      : 333 44 555555 06 07
+align/size  : 1 7
+
+---- TEST 2 - PACKED ----
+bits in use : 7FFFFFFFFFFFFFFFFFFFFF
+bits as set : 4A48D159E26AF37BC1E003
+values      : 03 1e 123456789abcdef0 05 fffffffe
+align/size  : 1 11
+
+---- TEST 3 - PACKED ----
+bits in use : 7FFF000003FF
+bits as set : 38D9000002F5
+values      : 15 17 19 06 0e
+align/size  : 1 6
+
+---- TEST 4 - PACKED ----
+bits in use : 07FFFF00000027
+bits as set : 078F0F00000023
+values      : 03 ffffffff 0f fffffff8 78
+align/size  : 1 7
+
+---- TEST 5 - PACKED ----
+bits in use : FFFFFF07FFFFFFFFFFFFFFFF9FFFFFFFFFFF
+bits as set : 007744000000000F18000000000123456789
+values      : 0000000123456789 f0000000 0000000000000078 44 77
+align/size  : 1 18
+
+---- TEST 6 - PACKED ----
+bits in use : 007000FFFFFFFFFFFFFF
+bits as set : 0030002001FD00000004
+values      : 01 02 03 04 fffffffd
+align/size  : 1 10
+
+
+
+---- TEST 1 - WITH ALIGN ----
+bits in use : 000000000000001FFFFFFFFF007F0FFF
+bits as set : 00000000000000076055555500440333
+values      : 333 44 555555 06 07
+align/size  : 16 16
+
+---- TEST 2 - WITH ALIGN ----
+bits in use : 0000000000000000000000000000003F7FFFFFFFFFFFFFFF00000000003F0FFF
+bits as set : 00000000000000000000000000000025123456789ABCDEF000000000001E0003
+values      : 03 1e 123456789abcdef0 05 fffffffe
+align/size  : 16 32
+
+---- TEST 3 - WITH ALIGN ----
+bits in use : 0000000000000000000000000000001F000000000000000000001F1F000003FF
+bits as set : 0000000000000000000000000000000E000000000000000000000619000002F5
+values      : 15 17 19 06 0e
+align/size  : 16 32
+
+---- TEST 4 - WITH ALIGN ----
+bits in use : 0007FFFF00000027
+bits as set : 00078F0F00000023
+values      : 03 ffffffff 0f fffffff8 78
+align/size  : 4 8
+
+---- TEST 5 - WITH ALIGN ----
+bits in use : FFFFFF3FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF
+bits as set : 007744000000007800000000300000000000000123456789
+values      : 0000000123456789 f0000000 0000000000000078 44 77
+align/size  : 8 24
+
+---- TEST 6 - WITH ALIGN ----
+bits in use : 0000007000FFFFFFFFFFFFFF
+bits as set : 00000030002001FD00000004
+values      : 01 02 03 04 fffffffd
+align/size  : 4 12
+
+
+
+---- TEST 1 - PACKED - WITH ALIGN ----
+bits in use : 000000000000000000FFFFFFFFFFFFFF
+bits as set : 0000000000000000003B02AAAAAC4333
+values      : 333 44 555555 06 07
+align/size  : 16 16
+
+---- TEST 2 - PACKED - WITH ALIGN ----
+bits in use : 3F01FFFFFFFFFFFFFFFFFFFF
+bits as set : 250048D159E26AF37BC1E003
+values      : 03 1e 123456789abcdef0 05 fffffffe
+align/size  : 1 12
+
+---- TEST 3 - PACKED - WITH ALIGN ----
+bits in use : 1F03FF000003FF
+bits as set : 0E00D9000002F5
+values      : 15 17 19 06 0e
+align/size  : 1 7
+
+---- TEST 4 - PACKED - WITH ALIGN ----
+bits in use : 07FFFF00000027
+bits as set : 078F0F00000023
+values      : 03 ffffffff 0f fffffff8 78
+align/size  : 1 7
+
+---- TEST 5 - PACKED - WITH ALIGN ----
+bits in use : FFFFFF07FFFFFFFFFFFFFFFF9FFFFFFFFFFF
+bits as set : 007744000000000F18000000000123456789
+values      : 0000000123456789 f0000000 0000000000000078 44 77
+align/size  : 1 18
+
+---- TEST 6 - PACKED - WITH ALIGN ----
+bits in use : 007000FFFFFFFFFFFFFF
+bits as set : 0030002001FD00000004
+values      : 01 02 03 04 fffffffd
+align/size  : 1 10
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields_ms.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields_ms.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields_ms.c	(revision 331)
@@ -0,0 +1,2 @@
+#define MS_BITFIELDS 1
+#include "95_bitfields.c"
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields_ms.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields_ms.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/95_bitfields_ms.expect	(revision 331)
@@ -0,0 +1,149 @@
+---- TEST 1 - MS-BITFIELDS ----
+bits in use : 0000001FFFFFFFFF0000007F00000FFF
+bits as set : 00000007605555550000004400000333
+values      : 333 44 555555 06 07
+align/size  : 4 16
+
+---- TEST 2 - MS-BITFIELDS ----
+bits in use : 0000000000000003000000000000000F7FFFFFFFFFFFFFFF0000003F00000FFF
+bits as set : 00000000000000020000000000000005123456789ABCDEF00000001E00000003
+values      : 03 1e 123456789abcdef0 05 fffffffffffffffe
+align/size  : 8 32
+
+---- TEST 3 - MS-BITFIELDS ----
+bits in use : 001F001F0000001F000003FF
+bits as set : 000E000600000019000002F5
+values      : 15 17 19 06 0e
+align/size  : 4 12
+
+---- TEST 4 - MS-BITFIELDS ----
+bits in use : 0007FFFF00000027
+bits as set : 00078F0F00000023
+values      : 03 ffffffff 0f fffffff8 78
+align/size  : 4 8
+
+---- TEST 5 - MS-BITFIELDS ----
+bits in use : 00000000FFFF00FF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF
+bits as set : 0000000000770044000000000000007800000000300000000000000123456789
+values      : 0000000123456789 fffffffff0000000 0000000000000078 44 77
+align/size  : 8 32
+
+---- TEST 6 - MS-BITFIELDS ----
+bits in use : 00000000000000700000FFFF000000FFFFFFFFFF
+bits as set : 000000000000003000002001000000FD00000004
+values      : 01 02 03 04 fffffffd
+align/size  : 4 20
+
+
+
+---- TEST 1 - MS-BITFIELDS - PACKED ----
+bits in use : 0000001FFFFFFFFF7F00000FFF
+bits as set : 00000007605555554400000333
+values      : 333 44 555555 06 07
+align/size  : 1 13
+
+---- TEST 2 - MS-BITFIELDS - PACKED ----
+bits in use : 00000000000000030F7FFFFFFFFFFFFFFF3F00000FFF
+bits as set : 000000000000000205123456789ABCDEF01E00000003
+values      : 03 1e 123456789abcdef0 05 fffffffffffffffe
+align/size  : 1 22
+
+---- TEST 3 - MS-BITFIELDS - PACKED ----
+bits in use : 001F1F0000001F000003FF
+bits as set : 000E0600000019000002F5
+values      : 15 17 19 06 0e
+align/size  : 1 11
+
+---- TEST 4 - MS-BITFIELDS - PACKED ----
+bits in use : 0007FFFF00000027
+bits as set : 00078F0F00000023
+values      : 03 ffffffff 0f fffffff8 78
+align/size  : 1 8
+
+---- TEST 5 - MS-BITFIELDS - PACKED ----
+bits in use : FFFFFF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF
+bits as set : 007744000000000000007800000000300000000000000123456789
+values      : 0000000123456789 fffffffff0000000 0000000000000078 44 77
+align/size  : 1 27
+
+---- TEST 6 - MS-BITFIELDS - PACKED ----
+bits in use : 00000000700000FFFFFFFFFFFFFF
+bits as set : 000000003000002001FD00000004
+values      : 01 02 03 04 fffffffd
+align/size  : 1 14
+
+
+
+---- TEST 1 - MS-BITFIELDS - WITH ALIGN ----
+bits in use : 0000001FFFFFFFFF0000007F00000FFF
+bits as set : 00000007605555550000004400000333
+values      : 333 44 555555 06 07
+align/size  : 16 16
+
+---- TEST 2 - MS-BITFIELDS - WITH ALIGN ----
+bits in use : 0000000000000003000000000000000F7FFFFFFFFFFFFFFF0000003F00000FFF
+bits as set : 00000000000000020000000000000005123456789ABCDEF00000001E00000003
+values      : 03 1e 123456789abcdef0 05 fffffffffffffffe
+align/size  : 16 32
+
+---- TEST 3 - MS-BITFIELDS - WITH ALIGN ----
+bits in use : 0000000000000000000000000000001F000000000000001F0000001F000003FF
+bits as set : 0000000000000000000000000000000E000000000000000600000019000002F5
+values      : 15 17 19 06 0e
+align/size  : 16 32
+
+---- TEST 4 - MS-BITFIELDS - WITH ALIGN ----
+bits in use : 0007FFFF00000027
+bits as set : 00078F0F00000023
+values      : 03 ffffffff 0f fffffff8 78
+align/size  : 4 8
+
+---- TEST 5 - MS-BITFIELDS - WITH ALIGN ----
+bits in use : 00000000FFFF00FF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF
+bits as set : 0000000000770044000000000000007800000000300000000000000123456789
+values      : 0000000123456789 fffffffff0000000 0000000000000078 44 77
+align/size  : 8 32
+
+---- TEST 6 - MS-BITFIELDS - WITH ALIGN ----
+bits in use : 00000000000000700000FFFF000000FFFFFFFFFF
+bits as set : 000000000000003000002001000000FD00000004
+values      : 01 02 03 04 fffffffd
+align/size  : 4 20
+
+
+
+---- TEST 1 - MS-BITFIELDS - PACKED - WITH ALIGN ----
+bits in use : 0000000000001FFFFFFFFF7F00000FFF
+bits as set : 00000000000007605555554400000333
+values      : 333 44 555555 06 07
+align/size  : 16 16
+
+---- TEST 2 - MS-BITFIELDS - PACKED - WITH ALIGN ----
+bits in use : 00000000000000030F0000007FFFFFFFFFFFFFFF3F00000FFF
+bits as set : 000000000000000205000000123456789ABCDEF01E00000003
+values      : 03 1e 123456789abcdef0 05 fffffffffffffffe
+align/size  : 16 25
+
+---- TEST 3 - MS-BITFIELDS - PACKED - WITH ALIGN ----
+bits in use : 001F000000000000001F0000001F000003FF
+bits as set : 000E000000000000000600000019000002F5
+values      : 15 17 19 06 0e
+align/size  : 16 18
+
+---- TEST 4 - MS-BITFIELDS - PACKED - WITH ALIGN ----
+bits in use : 0007FFFF00000027
+bits as set : 00078F0F00000023
+values      : 03 ffffffff 0f fffffff8 78
+align/size  : 1 8
+
+---- TEST 5 - MS-BITFIELDS - PACKED - WITH ALIGN ----
+bits in use : FFFFFF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF
+bits as set : 007744000000000000007800000000300000000000000123456789
+values      : 0000000123456789 fffffffff0000000 0000000000000078 44 77
+align/size  : 1 27
+
+---- TEST 6 - MS-BITFIELDS - PACKED - WITH ALIGN ----
+bits in use : 00000000700000FFFFFFFFFFFFFF
+bits as set : 000000003000002001FD00000004
+values      : 01 02 03 04 fffffffd
+align/size  : 1 14
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/96_nodata_wanted.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/96_nodata_wanted.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/96_nodata_wanted.c	(revision 331)
@@ -0,0 +1,84 @@
+/*****************************************************************************/
+/* test 'nodata_wanted' data output suppression */
+
+#if defined test_static_data_error
+void foo() {
+    if (1) {
+	static short w = (int)&foo; /* initializer not computable */
+    }
+}
+
+#elif defined test_static_nodata_error
+void foo() {
+    if (0) {
+	static short w = (int)&foo; /* initializer not computable */
+    }
+}
+
+#elif defined test_global_data_error
+void foo();
+static short w = (int)&foo; /* initializer not computable */
+
+
+#elif defined test_local_data_noerror
+void foo() {
+    short w = &foo; /* 2 cast warnings */
+}
+
+#elif defined test_data_suppression_off || defined test_data_suppression_on
+
+#if defined test_data_suppression_on
+# define SKIP 1
+#else
+# define SKIP 0
+#endif
+
+#include <stdio.h>
+/* some gcc headers #define __attribute__ to empty if it's not gcc */
+#undef __attribute__
+
+int main()
+{
+    __label__ ts0, te0, ts1, te1;
+    int tl, dl;
+
+    static char ds0 = 0;
+    static char de0 = 0;
+    /* get reference size of empty jmp */
+ts0:;
+    if (!SKIP) {}
+te0:;
+    dl = -(&de0 - &ds0);
+    tl = -(&&te0 - &&ts0);
+
+    /* test data and code suppression */
+    static char ds1 = 0;
+ts1:;
+    if (!SKIP) {
+        static void *p = (void*)&main;
+        static char cc[] = "static string";
+        static double d = 8.0;
+
+        static struct __attribute__((packed)) {
+            unsigned x : 12;
+            unsigned char y : 7;
+            unsigned z : 28, a: 4, b: 5;
+        } s = { 0x333,0x44,0x555555,6,7 };
+
+        printf("data:\n");
+        printf("  %d - %.1f - %.1f - %s - %s\n",
+            sizeof 8.0, 8.0, d, __FUNCTION__, cc);
+        printf("  %x %x %x %x %x\n",
+            s.x, s.y, s.z, s.a, s.b);
+    }
+te1:;
+    static char de1 = 0;
+
+    dl += &de1 - &ds1;
+    tl += &&te1 - &&ts1;
+    printf("size of data/text:\n  %s/%s\n",
+        dl ? "non-zero":"zero", tl ? "non-zero":"zero");
+    /*printf("# %d/%d\n", dl, tl);*/
+}
+
+#endif
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/96_nodata_wanted.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/96_nodata_wanted.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/96_nodata_wanted.expect	(revision 331)
@@ -0,0 +1,23 @@
+[test_static_data_error]
+96_nodata_wanted.c:7: error: initializer element is not computable at load time
+
+[test_static_nodata_error]
+96_nodata_wanted.c:14: error: initializer element is not computable at load time
+
+[test_global_data_error]
+96_nodata_wanted.c:20: error: initializer element is not computable at load time
+
+[test_local_data_noerror]
+96_nodata_wanted.c:25: warning: assignment makes integer from pointer without a cast
+96_nodata_wanted.c:25: warning: nonportable conversion from pointer to char/short
+
+[test_data_suppression_off]
+data:
+  8 - 8.0 - 8.0 - main - static string
+  333 44 555555 6 7
+size of data/text:
+  non-zero/non-zero
+
+[test_data_suppression_on]
+size of data/text:
+  zero/zero
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/97_utf8_string_literal.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/97_utf8_string_literal.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/97_utf8_string_literal.c	(revision 331)
@@ -0,0 +1,12 @@
+// this file contains BMP chars encoded in UTF-8
+#include <stdio.h>
+#include <wchar.h>
+
+int main()
+{
+    wchar_t s[] = L"hello$$ä½ å¥½Â¢Â¢ä¸çâ¬â¬world";
+    wchar_t *p;
+    for (p = s; *p; p++) printf("%04X ", (unsigned) *p);
+    printf("\n");
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/97_utf8_string_literal.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/97_utf8_string_literal.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/97_utf8_string_literal.expect	(revision 331)
@@ -0,0 +1,1 @@
+0068 0065 006C 006C 006F 0024 0024 4F60 597D 00A2 00A2 4E16 754C 20AC 20AC 0077 006F 0072 006C 0064 
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/98_al_ax_extend.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/98_al_ax_extend.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/98_al_ax_extend.c	(revision 331)
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <stdlib.h>
+asm (
+    ".text;"
+    ".globl _us;.globl _ss;.globl _uc;.globl _sc;"
+    "_us:;_ss:;_uc:;_sc:;"
+    "movl $0x1234ABCD, %eax;"
+	"ret;"
+);
+
+#if 1
+#define us _us
+#define ss _ss
+#define uc _uc
+#define sc _sc
+#endif
+
+int main()
+{
+    unsigned short us(void);
+    short ss(void);
+    unsigned char uc(void);
+    signed char sc(void);
+
+    unsigned short (*fpus)(void) = us;
+    short (*fpss)(void) = ss;
+    unsigned char (*fpuc)(void) = uc;
+    signed char (*fpsc)(void) = sc;
+
+    printf("%08X %08X\n", us() + 1, fpus() + 1);
+    printf("%08X %08X\n", ss() + 1, fpss() + 1);
+    printf("%08X %08X\n", uc() + 1, fpuc() + 1);
+    printf("%08X %08X\n", sc() + 1, fpsc() + 1);
+    printf("\n");
+    printf("%08X %08X\n", fpus() + 1, us() + 1);
+    printf("%08X %08X\n", fpss() + 1, ss() + 1);
+    printf("%08X %08X\n", fpuc() + 1, uc() + 1);
+    printf("%08X %08X\n", fpsc() + 1, sc() + 1);
+
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/98_al_ax_extend.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/98_al_ax_extend.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/98_al_ax_extend.expect	(revision 331)
@@ -0,0 +1,9 @@
+0000ABCE 0000ABCE
+FFFFABCE FFFFABCE
+000000CE 000000CE
+FFFFFFCE FFFFFFCE
+
+0000ABCE 0000ABCE
+FFFFABCE FFFFABCE
+000000CE 000000CE
+FFFFFFCE FFFFFFCE
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/99_fastcall.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/99_fastcall.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/99_fastcall.c	(revision 331)
@@ -0,0 +1,276 @@
+#include <stdio.h>
+#include <assert.h>
+
+#ifndef _WIN32
+#define __fastcall __attribute((fastcall))
+#endif
+
+#if 1
+#define SYMBOL(x) _##x
+#else
+#define SYMBOL(x) x
+#endif
+
+/////////////////////////////////////////////////////////////////////////
+//////////                TRAP FRAMEWORK
+/////////////////////////////////////////////////////////////////////////
+// if you cast 'TRAP' to a function pointer and call it,
+//   it will save all 8 registers,
+//   and jump into C-code (previously set using 'SET_TRAP_HANDLER(x)'),
+//   in C-code you can pop DWORDs from stack and modify registers
+//
+
+void *SYMBOL(trap_handler);
+
+extern unsigned char SYMBOL(trap)[];
+asm (
+    ".text;"
+    "_trap:;"
+    "pushl %esp;"
+    "pusha;"
+    "addl $0x4, 0xc(%esp);"
+    "pushl %esp;"
+    "call *_trap_handler;"
+    "addl $0x4, %esp;"
+    "movl 0xc(%esp), %eax;"
+    "movl %eax, 0x20(%esp);"
+    "popa;"
+    "popl %esp;"
+	"ret;"
+);
+
+struct trapframe {
+    unsigned edi, esi, ebp, esp, ebx, edx, ecx, eax;
+};
+
+
+#define M_FLOAT(addr) (*(float *)(addr))
+#define M_DWORD(addr) (*(unsigned *)(addr))
+#define M_WORD(addr) (*(unsigned short *)(addr))
+#define M_BYTE(addr) (*(unsigned char *)(addr))
+#define R_EAX ((tf)->eax)
+#define R_ECX ((tf)->ecx)
+#define R_EDX ((tf)->edx)
+#define R_EBX ((tf)->ebx)
+#define R_ESP ((tf)->esp)
+#define R_EBP ((tf)->ebp)
+#define R_ESI ((tf)->esi)
+#define R_EDI ((tf)->edi)
+
+#define ARG(x) (M_DWORD(R_ESP + (x) * 4))
+
+#define RETN(x) do { \
+    M_DWORD(R_ESP + (x)) = M_DWORD(R_ESP); \
+    R_ESP += (x); \
+} while (0)
+
+#define DUMP() do { \
+    unsigned i; \
+    printf("EAX: %08X\n", R_EAX); \
+    printf("ECX: %08X\n", R_ECX); \
+    printf("EDX: %08X\n", R_EDX); \
+    printf("EBX: %08X\n", R_EBX); \
+    printf("ESP: %08X\n", R_ESP); \
+    printf("EBP: %08X\n", R_EBP); \
+    printf("ESI: %08X\n", R_ESI); \
+    printf("EDI: %08X\n", R_EDI); \
+    printf("\n"); \
+    printf("[RETADDR]: %08X\n", M_DWORD(R_ESP)); \
+    for (i = 1; i <= 8; i++) { \
+        printf("[ARG%4d]: %08X\n", i, ARG(i)); \
+    } \
+} while (0)
+
+#define SET_TRAP_HANDLER(x) ((SYMBOL(trap_handler)) = (x))
+#define TRAP ((void *) &SYMBOL(trap))
+
+
+
+/////////////////////////////////////////////////////////////////////////
+//////////                SAFECALL FRAMEWORK
+/////////////////////////////////////////////////////////////////////////
+// this framework will convert any calling convention to cdecl
+// usage: first set call target with 'SET_SAFECALL_TARGET(x)'
+//        then cast 'SAFECALL' to target function pointer type and invoke it
+//        after calling, 'ESPDIFF' is the difference of old and new esp
+
+void *SYMBOL(sc_call_target);
+unsigned SYMBOL(sc_retn_addr);
+unsigned SYMBOL(sc_old_esp);
+unsigned SYMBOL(sc_new_esp);
+
+extern unsigned char SYMBOL(safecall)[];
+asm (
+    ".text;"
+    "_safecall:;"
+    "popl _sc_retn_addr;"
+    "movl %esp, _sc_old_esp;"
+    "call *_sc_call_target;"
+    "movl %esp, _sc_new_esp;"
+    "movl _sc_old_esp, %esp;"
+	"jmp *_sc_retn_addr;"
+);
+
+#define SET_SAFECALL_TARGET(x) ((SYMBOL(sc_call_target)) = (x))
+#define SAFECALL ((void *) &SYMBOL(safecall))
+#define ESPDIFF (SYMBOL(sc_new_esp) - SYMBOL(sc_old_esp))
+
+
+/////////////////////////////////////////////////////////////////////////
+//////////                TEST FASTCALL INVOKE
+/////////////////////////////////////////////////////////////////////////
+
+void check_fastcall_invoke_0(struct trapframe *tf)
+{
+    //DUMP();
+    RETN(0);
+}
+
+void check_fastcall_invoke_1(struct trapframe *tf)
+{
+    //DUMP();
+    assert(R_ECX == 0x11111111);
+    RETN(0);
+}
+void check_fastcall_invoke_2(struct trapframe *tf)
+{
+    //DUMP();
+    assert(R_ECX == 0x11111111);
+    assert(R_EDX == 0x22222222);
+    RETN(0);
+}
+void check_fastcall_invoke_3(struct trapframe *tf)
+{
+    //DUMP();
+    assert(R_ECX == 0x11111111);
+    assert(R_EDX == 0x22222222);
+    assert(ARG(1) == 0x33333333);
+    RETN(1*4);
+}
+void check_fastcall_invoke_4(struct trapframe *tf)
+{
+    //DUMP();
+    assert(R_ECX == 0x11111111);
+    assert(R_EDX == 0x22222222);
+    assert(ARG(1) == 0x33333333);
+    assert(ARG(2) == 0x44444444);
+    RETN(2*4);
+}
+
+void check_fastcall_invoke_5(struct trapframe *tf)
+{
+    //DUMP();
+    assert(R_ECX == 0x11111111);
+    assert(R_EDX == 0x22222222);
+    assert(ARG(1) == 0x33333333);
+    assert(ARG(2) == 0x44444444);
+    assert(ARG(3) == 0x55555555);
+    RETN(3*4);
+}
+
+void test_fastcall_invoke()
+{
+    SET_TRAP_HANDLER(check_fastcall_invoke_0);
+    ((void __fastcall (*)(void)) TRAP)();
+
+    SET_TRAP_HANDLER(check_fastcall_invoke_1);
+    ((void __fastcall (*)(unsigned)) TRAP)(0x11111111);
+
+    SET_TRAP_HANDLER(check_fastcall_invoke_2);
+    ((void __fastcall (*)(unsigned, unsigned)) TRAP)(0x11111111, 0x22222222);
+
+    SET_TRAP_HANDLER(check_fastcall_invoke_3);
+    ((void __fastcall (*)(unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333);
+
+    SET_TRAP_HANDLER(check_fastcall_invoke_4);
+    ((void __fastcall (*)(unsigned, unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333, 0x44444444);
+
+    SET_TRAP_HANDLER(check_fastcall_invoke_5);
+    ((void __fastcall (*)(unsigned, unsigned, unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555);
+}
+
+
+/////////////////////////////////////////////////////////////////////////
+//////////                TEST FUNCTION CODE GENERATION
+/////////////////////////////////////////////////////////////////////////
+
+int __fastcall check_fastcall_espdiff_0(void)
+{
+    return 0;
+}
+
+int __fastcall check_fastcall_espdiff_1(int a)
+{
+    return a;
+}
+
+int __fastcall check_fastcall_espdiff_2(int a, int b)
+{
+    return a + b;
+}
+
+int __fastcall check_fastcall_espdiff_3(int a, int b, int c)
+{
+    return a + b + c;
+}
+
+int __fastcall check_fastcall_espdiff_4(int a, int b, int c, int d)
+{
+    return a + b + c + d;
+}
+
+int __fastcall check_fastcall_espdiff_5(int a, int b, int c, int d, int e)
+{
+    return a + b + c + d + e;
+}
+
+void test_fastcall_espdiff()
+{
+    int x;
+    SET_SAFECALL_TARGET(check_fastcall_espdiff_0);
+    x = ((typeof(&check_fastcall_espdiff_0))SAFECALL)();
+    assert(x == 0);
+    assert(ESPDIFF == 0);
+
+    SET_SAFECALL_TARGET(check_fastcall_espdiff_1);
+    x = ((typeof(&check_fastcall_espdiff_1))SAFECALL)(1);
+    assert(x == 1);
+    assert(ESPDIFF == 0);
+
+    SET_SAFECALL_TARGET(check_fastcall_espdiff_2);
+    x = ((typeof(&check_fastcall_espdiff_2))SAFECALL)(1, 2);
+    assert(x == 1 + 2);
+    assert(ESPDIFF == 0);
+
+    SET_SAFECALL_TARGET(check_fastcall_espdiff_3);
+    x = ((typeof(&check_fastcall_espdiff_3))SAFECALL)(1, 2, 3);
+    assert(x == 1 + 2 + 3);
+    assert(ESPDIFF == 1*4);
+
+    SET_SAFECALL_TARGET(check_fastcall_espdiff_4);
+    x = ((typeof(&check_fastcall_espdiff_4))SAFECALL)(1, 2, 3, 4);
+    assert(x == 1 + 2 + 3 + 4);
+    assert(ESPDIFF == 2*4);
+
+    SET_SAFECALL_TARGET(check_fastcall_espdiff_5);
+    x = ((typeof(&check_fastcall_espdiff_5))SAFECALL)(1, 2, 3, 4, 5);
+    assert(x == 1 + 2 + 3 + 4 + 5);
+    assert(ESPDIFF == 3*4);
+}
+
+int main()
+{
+#define N 10000
+    int i;
+
+    for (i = 1; i <= N; i++) {
+        test_fastcall_espdiff();
+    }
+
+    for (i = 1; i <= N; i++) {
+        test_fastcall_invoke();
+    }
+
+    puts("TEST OK");
+    return 0;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/99_fastcall.expect
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/99_fastcall.expect	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/99_fastcall.expect	(revision 331)
@@ -0,0 +1,1 @@
+TEST OK
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/LICENSE
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/LICENSE	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/LICENSE	(revision 331)
@@ -0,0 +1,37 @@
+The tests in this directory are either directly copied from the picoc project or
+are subsequently modified and added to for the purpose of TinyCC project. All
+these modifications are licensed under the same terms as TinyCC as specified in
+the file COPYING.
+
+=== picoc license ===
+
+Copyright (c) 2009-2011, Zik Saleeba
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without 
+modification, are permitted provided that the following conditions are 
+met:
+
+    * Redistributions of source code must retain the above copyright 
+      notice, this list of conditions and the following disclaimer.
+      
+    * Redistributions in binary form must reproduce the above copyright 
+      notice, this list of conditions and the following disclaimer in 
+      the documentation and/or other materials provided with the 
+      distribution.
+      
+    * Neither the name of the Zik Saleeba nor the names of its 
+      contributors may be used to endorse or promote products derived 
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/Makefile
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/Makefile	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/tests2/Makefile	(revision 331)
@@ -0,0 +1,112 @@
+TOP = ../..
+include $(TOP)/Makefile
+SRC = $(TOPSRC)/tests/tests2
+VPATH = $(SRC)
+
+TESTS = $(patsubst %.c,%.test,$(sort $(notdir $(wildcard $(SRC)/*.c))))
+
+# some tests do not pass on all platforms, remove them for now
+SKIP = 34_array_assignment.test # array assignment is not in C standard
+ifeq ($(CONFIG_arm_eabi),yes) # not ARM soft-float
+ SKIP += 22_floating_point.test
+endif
+ifdef CONFIG_OSX
+ SKIP += 40_stdio.test 42_function_pointer.test
+ FLAGS += -w
+endif
+ifeq ($(ARCH),x86_64)
+ SKIP += 73_arm64.test
+endif
+ifeq (,$(filter i386,$(ARCH)))
+ SKIP += 98_al_ax_extend.test 99_fastcall.test
+endif
+ifeq (,$(filter i386 x86_64,$(ARCH)))
+ SKIP += 85_asm-outside-function.test
+endif
+ifeq (-$(findstring gcc,$(CC))-,--)
+ SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS))
+endif
+ifeq (-$(CONFIG_WIN32)-$(CONFIG_i386)$(CONFIG_arm)-,--yes-)
+ SKIP += 95_bitfields%.test # type_align is different on 32bit-non-windows
+endif
+
+# Some tests might need arguments
+ARGS =
+31_args.test : ARGS = arg1 arg2 arg3 arg4 arg5
+46_grep.test : ARGS = '[^* ]*[:a:d: ]+\:\*-/: $$' $(SRC)/46_grep.c
+
+# And some tests don't test the right thing with -run
+NORUN =
+42_function_pointer.test : NORUN = true
+
+# Some tests might need different flags
+FLAGS =
+76_dollars_in_identifiers.test : FLAGS += -fdollars-in-identifiers
+
+# These tests run several snippets from the same file one by one
+60_errors_and_warnings.test : FLAGS += -dt
+96_nodata_wanted.test : FLAGS += -dt
+
+# Always generate certain .expects (don't put these in the GIT),
+GEN-ALWAYS =
+# GEN-ALWAYS += 95_bitfields.expect # does not work
+
+# using the ms compiler for the really ms-compatible bitfields
+95_bitfields_ms.test : GEN = $(GEN-MSC)
+
+# Filter source directory in warnings/errors (out-of-tree builds)
+FILTER = 2>&1 | sed 's,$(SRC)/,,g'
+# Filter some always-warning
+ifeq (-$(findstring arm,$(ARCH))-,-arm-)
+FILTER += 2>&1 | grep -v 'warning: soft float ABI currently not supported'
+endif
+
+all test tests2.all: $(filter-out $(SKIP),$(TESTS)) ;
+
+%.test: %.c %.expect
+	@echo Test: $*...
+	@$(if $(NORUN),$(T1),$(T2)) $(if $(NODIFF),,$(T3))
+
+T1 = $(TCC) $(FLAGS) $< -o a.exe && ./a.exe $(ARGS)
+T2 = $(TCC) $(FLAGS) -run $< $(ARGS)
+T3 = $(FILTER) >$*.output 2>&1 || true \
+     && diff -Nbu $(filter %.expect,$^) $*.output \
+     && rm -f $*.output $(filter $*.expect,$(GEN-ALWAYS))
+
+# run single test and update .expect file, e.g. "make tests2.37+"
+tests2.%+:
+	@$(MAKE) $(call F2,$(call F1,$*)) --no-print-directory
+
+# just run tcc to see the output, e.g. "make tests2.37-"
+tests2.%-:
+	@$(MAKE) $(call F1,$*) NODIFF=true --no-print-directory
+
+# run single test, e.g. "make tests2.37"
+tests2.%:
+	@$(MAKE) $(call F1,$*) --no-print-directory
+
+F1 = $(or $(filter $1_%,$(TESTS)),$1_???.test)
+F2 = $1 UPDATE="$(patsubst %.test,%.expect,$1)"
+
+# automatically generate .expect files with gcc:
+%.expect :
+	@echo Generating: $@
+	@$(call GEN,$(SRC)/$*.c) $(FILTER) >$@ 2>&1
+	@rm -f *.exe *.obj *.pdb
+
+# using TCC for .expect if -dt in FLAGS
+GEN = $(if $(filter -dt,$(FLAGS)),$(GEN-TCC),$(GEN-CC))
+GEN-CC = $(CC) -w -std=gnu99 $(FLAGS) $1 -o a.exe && ./a.exe $(ARGS)
+GEN-TCC = $(TCC) $(FLAGS) -run $1 $(ARGS)
+GEN-MSC = $(MS-CC) $1 && ./$(basename $@).exe
+MS-CC = cl
+
+# tell make not to delete
+.PRECIOUS: %.expect
+
+# force .expect generation for these files
+$(sort $(GEN-ALWAYS) $(UPDATE)) : force
+force:
+
+clean:
+	rm -f fred.txt *.output a.exe $(GEN-ALWAYS)
Index: EcnlProtoTool/trunk/tcc-0.9.27/tests/vla_test.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/tests/vla_test.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/tests/vla_test.c	(revision 331)
@@ -0,0 +1,84 @@
+/*
+ * Test that allocating a variable length array in a loop
+ * does not use up a linear amount of memory
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define LOOP_COUNT 1000
+#define ARRAY_SIZE 100
+
+/* Overwrite a VLA. This will overwrite the return address if SP is incorrect */
+void smash(char *p, int n) {
+  memset(p, 0, n);
+}
+
+int test1(int n) {
+  int i;
+  char *array_ptrs[LOOP_COUNT];
+  
+  for (i = 0; i < LOOP_COUNT; ++i) {
+    char test[n];
+    smash(test, n);
+    array_ptrs[i] = test;
+  }
+  
+  return (array_ptrs[0]-array_ptrs[LOOP_COUNT-1] < n) ? 0 : 1;
+}
+
+/* ensure goto does not circumvent array free */
+int test2(int n) {
+  char *array_ptrs[LOOP_COUNT];
+
+  int i = 0;
+loop:;
+  char test[n];
+  smash(test, n);
+  if (i >= LOOP_COUNT)
+    goto end;
+  array_ptrs[i] = test;
+  ++i;
+  goto loop;
+
+end:
+  smash(test, n);
+  char test2[n];
+  smash(test2, n);
+  return (array_ptrs[0] - array_ptrs[LOOP_COUNT-1] < n) ? 0 : 1;
+}
+
+int test3(int n) {
+  char test[n];
+  smash(test, n);
+  goto label;
+label:
+  smash(test, n);
+  char test2[n];
+  smash(test2, n);
+  return (test-test2 >= n) ? 0 : 1;
+}
+
+#define RUN_TEST(t) \
+  if (!testname || (strcmp(#t, testname) == 0)) { \
+    fputs(#t "... ", stdout); \
+    fflush(stdout); \
+    if (t(ARRAY_SIZE) == 0) { \
+      fputs("success\n", stdout); \
+    } else { \
+      fputs("failure\n", stdout); \
+      retval = EXIT_FAILURE; \
+    } \
+  }
+
+int main(int argc, char **argv) {
+  const char *testname = NULL;
+  int retval = EXIT_SUCCESS;
+  if (argc > 1)
+    testname = argv[1];
+  RUN_TEST(test1)
+  RUN_TEST(test2)
+  RUN_TEST(test3)
+  return retval;
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/texi2pod.pl
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/texi2pod.pl	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/texi2pod.pl	(revision 331)
@@ -0,0 +1,427 @@
+#! /usr/bin/perl -w
+
+#   Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+
+# This file is part of GNU CC.
+
+# GNU CC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# GNU CC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNU CC; see the file COPYING.  If not, write to
+# the Free Software Foundation, 59 Temple Place - Suite 330,
+# Boston MA 02111-1307, USA.
+
+# This does trivial (and I mean _trivial_) conversion of Texinfo
+# markup to Perl POD format.  It's intended to be used to extract
+# something suitable for a manpage from a Texinfo document.
+
+$output = 0;
+$skipping = 0;
+%sects = ();
+$section = "";
+@icstack = ();
+@endwstack = ();
+@skstack = ();
+@instack = ();
+$shift = "";
+%defs = ();
+$fnno = 1;
+$inf = "";
+$ibase = "";
+
+while ($_ = shift) {
+    if (/^-D(.*)$/) {
+	if ($1 ne "") {
+	    $flag = $1;
+	} else {
+	    $flag = shift;
+	}
+	$value = "";
+	($flag, $value) = ($flag =~ /^([^=]+)(?:=(.+))?/);
+	die "no flag specified for -D\n"
+	    unless $flag ne "";
+	die "flags may only contain letters, digits, hyphens, dashes and underscores\n"
+	    unless $flag =~ /^[a-zA-Z0-9_-]+$/;
+	$defs{$flag} = $value;
+    } elsif (/^-/) {
+	usage();
+    } else {
+	$in = $_, next unless defined $in;
+	$out = $_, next unless defined $out;
+	usage();
+    }
+}
+
+if (defined $in) {
+    $inf = gensym();
+    open($inf, "<$in") or die "opening \"$in\": $!\n";
+    $ibase = $1 if $in =~ m|^(.+)/[^/]+$|;
+} else {
+    $inf = \*STDIN;
+}
+
+if (defined $out) {
+    open(STDOUT, ">$out") or die "opening \"$out\": $!\n";
+}
+
+while(defined $inf) {
+while(<$inf>) {
+    # Certain commands are discarded without further processing.
+    /^\@(?:
+	 [a-z]+index		# @*index: useful only in complete manual
+	 |need			# @need: useful only in printed manual
+	 |(?:end\s+)?group	# @group .. @end group: ditto
+	 |page			# @page: ditto
+	 |node			# @node: useful only in .info file
+	 |(?:end\s+)?ifnottex   # @ifnottex .. @end ifnottex: use contents
+	)\b/x and next;
+
+    chomp;
+
+    # Look for filename and title markers.
+    /^\@setfilename\s+([^.]+)/ and $fn = $1, next;
+    /^\@settitle\s+([^.]+)/ and $tl = postprocess($1), next;
+
+    # Identify a man title but keep only the one we are interested in.
+    /^\@c\s+man\s+title\s+([A-Za-z0-9-]+)\s+(.+)/ and do {
+	if (exists $defs{$1}) {
+	    $fn = $1;
+	    $tl = postprocess($2);
+	}
+	next;
+    };
+
+    # Look for blocks surrounded by @c man begin SECTION ... @c man end.
+    # This really oughta be @ifman ... @end ifman and the like, but such
+    # would require rev'ing all other Texinfo translators.
+    /^\@c\s+man\s+begin\s+([A-Z]+)\s+([A-Za-z0-9-]+)/ and do {
+	$output = 1 if exists $defs{$2};
+        $sect = $1;
+	next;
+    };
+    /^\@c\s+man\s+begin\s+([A-Z]+)/ and $sect = $1, $output = 1, next;
+    /^\@c\s+man\s+end/ and do {
+	$sects{$sect} = "" unless exists $sects{$sect};
+	$sects{$sect} .= postprocess($section);
+	$section = "";
+	$output = 0;
+	next;
+    };
+
+    # handle variables
+    /^\@set\s+([a-zA-Z0-9_-]+)\s*(.*)$/ and do {
+	$defs{$1} = $2;
+	next;
+    };
+    /^\@clear\s+([a-zA-Z0-9_-]+)/ and do {
+	delete $defs{$1};
+	next;
+    };
+
+    next unless $output;
+
+    # Discard comments.  (Can't do it above, because then we'd never see
+    # @c man lines.)
+    /^\@c\b/ and next;
+
+    # End-block handler goes up here because it needs to operate even
+    # if we are skipping.
+    /^\@end\s+([a-z]+)/ and do {
+	# Ignore @end foo, where foo is not an operation which may
+	# cause us to skip, if we are presently skipping.
+	my $ended = $1;
+	next if $skipping && $ended !~ /^(?:ifset|ifclear|ignore|menu|iftex)$/;
+
+	die "\@end $ended without \@$ended at line $.\n" unless defined $endw;
+	die "\@$endw ended by \@end $ended at line $.\n" unless $ended eq $endw;
+
+	$endw = pop @endwstack;
+
+	if ($ended =~ /^(?:ifset|ifclear|ignore|menu|iftex)$/) {
+	    $skipping = pop @skstack;
+	    next;
+	} elsif ($ended =~ /^(?:example|smallexample|display)$/) {
+	    $shift = "";
+	    $_ = "";	# need a paragraph break
+	} elsif ($ended =~ /^(?:itemize|enumerate|[fv]?table)$/) {
+	    $_ = "\n=back\n";
+	    $ic = pop @icstack;
+	} else {
+	    die "unknown command \@end $ended at line $.\n";
+	}
+    };
+
+    # We must handle commands which can cause skipping even while we
+    # are skipping, otherwise we will not process nested conditionals
+    # correctly.
+    /^\@ifset\s+([a-zA-Z0-9_-]+)/ and do {
+	push @endwstack, $endw;
+	push @skstack, $skipping;
+	$endw = "ifset";
+	$skipping = 1 unless exists $defs{$1};
+	next;
+    };
+
+    /^\@ifclear\s+([a-zA-Z0-9_-]+)/ and do {
+	push @endwstack, $endw;
+	push @skstack, $skipping;
+	$endw = "ifclear";
+	$skipping = 1 if exists $defs{$1};
+	next;
+    };
+
+    /^\@(ignore|menu|iftex)\b/ and do {
+	push @endwstack, $endw;
+	push @skstack, $skipping;
+	$endw = $1;
+	$skipping = 1;
+	next;
+    };
+
+    next if $skipping;
+
+    # Character entities.  First the ones that can be replaced by raw text
+    # or discarded outright:
+    s/\@copyright\{\}/(c)/g;
+    s/\@dots\{\}/.../g;
+    s/\@enddots\{\}/..../g;
+    s/\@([.!? ])/$1/g;
+    s/\@[:-]//g;
+    s/\@bullet(?:\{\})?/*/g;
+    s/\@TeX\{\}/TeX/g;
+    s/\@pounds\{\}/\#/g;
+    s/\@minus(?:\{\})?/-/g;
+    s/\\,/,/g;
+
+    # Now the ones that have to be replaced by special escapes
+    # (which will be turned back into text by unmunge())
+    s/&/&amp;/g;
+    s/\@\{/&lbrace;/g;
+    s/\@\}/&rbrace;/g;
+    s/\@\@/&at;/g;
+
+    # Inside a verbatim block, handle @var specially.
+    if ($shift ne "") {
+	s/\@var\{([^\}]*)\}/<$1>/g;
+    }
+
+    # POD doesn't interpret E<> inside a verbatim block.
+    if ($shift eq "") {
+	s/</&lt;/g;
+	s/>/&gt;/g;
+    } else {
+	s/</&LT;/g;
+	s/>/&GT;/g;
+    }
+
+    # Single line command handlers.
+
+    /^\@include\s+(.+)$/ and do {
+	push @instack, $inf;
+	$inf = gensym();
+
+	# Try cwd and $ibase.
+	open($inf, "<" . $1) 
+	    or open($inf, "<" . $ibase . "/" . $1)
+		or die "cannot open $1 or $ibase/$1: $!\n";
+	next;
+    };
+
+    /^\@(?:section|unnumbered|unnumberedsec|center)\s+(.+)$/
+	and $_ = "\n=head2 $1\n";
+    /^\@subsection\s+(.+)$/
+	and $_ = "\n=head3 $1\n";
+
+    # Block command handlers:
+    /^\@itemize\s+(\@[a-z]+|\*|-)/ and do {
+	push @endwstack, $endw;
+	push @icstack, $ic;
+	$ic = $1;
+	$_ = "\n=over 4\n";
+	$endw = "itemize";
+    };
+
+    /^\@enumerate(?:\s+([a-zA-Z0-9]+))?/ and do {
+	push @endwstack, $endw;
+	push @icstack, $ic;
+	if (defined $1) {
+	    $ic = $1 . ".";
+	} else {
+	    $ic = "1.";
+	}
+	$_ = "\n=over 4\n";
+	$endw = "enumerate";
+    };
+
+    /^\@([fv]?table)\s+(\@[a-z]+)/ and do {
+	push @endwstack, $endw;
+	push @icstack, $ic;
+	$endw = $1;
+	$ic = $2;
+	$ic =~ s/\@(?:samp|strong|key|gcctabopt|option|env)/B/;
+	$ic =~ s/\@(?:code|kbd)/C/;
+	$ic =~ s/\@(?:dfn|var|emph|cite|i)/I/;
+	$ic =~ s/\@(?:file)/F/;
+	$_ = "\n=over 4\n";
+    };
+
+    /^\@((?:small)?example|display)/ and do {
+	push @endwstack, $endw;
+	$endw = $1;
+	$shift = "\t";
+	$_ = "";	# need a paragraph break
+    };
+
+    /^\@itemx?\s*(.+)?$/ and do {
+	if (defined $1) {
+	    # Entity escapes prevent munging by the <> processing below.
+	    $_ = "\n=item $ic\&LT;$1\&GT;\n";
+	} else {
+	    $_ = "\n=item $ic\n";
+	    $ic =~ y/A-Ya-y/B-Zb-z/;
+	    $ic =~ s/(\d+)/$1 + 1/eg;
+	}
+    };
+
+    $section .= $shift.$_."\n";
+}
+# End of current file.
+close($inf);
+$inf = pop @instack;
+}
+
+die "No filename or title\n" unless defined $fn && defined $tl;
+
+$sects{NAME} = "$fn \- $tl\n";
+$sects{FOOTNOTES} .= "=back\n" if exists $sects{FOOTNOTES};
+
+for $sect (qw(NAME SYNOPSIS DESCRIPTION OPTIONS ENVIRONMENT FILES
+	      BUGS NOTES FOOTNOTES SEEALSO AUTHOR COPYRIGHT)) {
+    if(exists $sects{$sect}) {
+	$head = $sect;
+	$head =~ s/SEEALSO/SEE ALSO/;
+	print "=head1 $head\n\n";
+	print scalar unmunge ($sects{$sect});
+	print "\n";
+    }
+}
+
+sub usage
+{
+    die "usage: $0 [-D toggle...] [infile [outfile]]\n";
+}
+
+sub postprocess
+{
+    local $_ = $_[0];
+
+    # @value{foo} is replaced by whatever 'foo' is defined as.
+    while (m/(\@value\{([a-zA-Z0-9_-]+)\})/g) {
+	if (! exists $defs{$2}) {
+	    print STDERR "Option $2 not defined\n";
+	    s/\Q$1\E//;
+	} else {
+	    $value = $defs{$2};
+	    s/\Q$1\E/$value/;
+	}
+    }
+
+    # Formatting commands.
+    # Temporary escape for @r.
+    s/\@r\{([^\}]*)\}/R<$1>/g;
+    s/\@(?:dfn|var|emph|cite|i)\{([^\}]*)\}/I<$1>/g;
+    s/\@(?:code|kbd)\{([^\}]*)\}/C<$1>/g;
+    s/\@(?:gccoptlist|samp|strong|key|option|env|command|b)\{([^\}]*)\}/B<$1>/g;
+    s/\@sc\{([^\}]*)\}/\U$1/g;
+    s/\@file\{([^\}]*)\}/F<$1>/g;
+    s/\@w\{([^\}]*)\}/S<$1>/g;
+    s/\@(?:dmn|math)\{([^\}]*)\}/$1/g;
+
+    # Cross references are thrown away, as are @noindent and @refill.
+    # (@noindent is impossible in .pod, and @refill is unnecessary.)
+    # @* is also impossible in .pod; we discard it and any newline that
+    # follows it.  Similarly, our macro @gol must be discarded.
+
+    s/\(?\@xref\{(?:[^\}]*)\}(?:[^.<]|(?:<[^<>]*>))*\.\)?//g;
+    s/\s+\(\@pxref\{(?:[^\}]*)\}\)//g;
+    s/;\s+\@pxref\{(?:[^\}]*)\}//g;
+    s/\@noindent\s*//g;
+    s/\@refill//g;
+    s/\@gol//g;
+    s/\@\*\s*\n?//g;
+
+    # @uref can take one, two, or three arguments, with different
+    # semantics each time.  @url and @email are just like @uref with
+    # one argument, for our purposes.
+    s/\@(?:uref|url|email)\{([^\},]*)\}/&lt;B<$1>&gt;/g;
+    s/\@uref\{([^\},]*),([^\},]*)\}/$2 (C<$1>)/g;
+    s/\@uref\{([^\},]*),([^\},]*),([^\},]*)\}/$3/g;
+
+    # Turn B<blah I<blah> blah> into B<blah> I<blah> B<blah> to
+    # match Texinfo semantics of @emph inside @samp.  Also handle @r
+    # inside bold.
+    s/&LT;/</g;
+    s/&GT;/>/g;
+    1 while s/B<((?:[^<>]|I<[^<>]*>)*)R<([^>]*)>/B<$1>${2}B</g;
+    1 while (s/B<([^<>]*)I<([^>]+)>/B<$1>I<$2>B</g);
+    1 while (s/I<([^<>]*)B<([^>]+)>/I<$1>B<$2>I</g);
+    s/[BI]<>//g;
+    s/([BI])<(\s+)([^>]+)>/$2$1<$3>/g;
+    s/([BI])<([^>]+?)(\s+)>/$1<$2>$3/g;
+
+    # Extract footnotes.  This has to be done after all other
+    # processing because otherwise the regexp will choke on formatting
+    # inside @footnote.
+    while (/\@footnote/g) {
+	s/\@footnote\{([^\}]+)\}/[$fnno]/;
+	add_footnote($1, $fnno);
+	$fnno++;
+    }
+
+    return $_;
+}
+
+sub unmunge
+{
+    # Replace escaped symbols with their equivalents.
+    local $_ = $_[0];
+
+    s/&lt;/E<lt>/g;
+    s/&gt;/E<gt>/g;
+    s/&lbrace;/\{/g;
+    s/&rbrace;/\}/g;
+    s/&at;/\@/g;
+    s/&amp;/&/g;
+    return $_;
+}
+
+sub add_footnote
+{
+    unless (exists $sects{FOOTNOTES}) {
+	$sects{FOOTNOTES} = "\n=over 4\n\n";
+    }
+
+    $sects{FOOTNOTES} .= "=item $fnno.\n\n"; $fnno++;
+    $sects{FOOTNOTES} .= $_[0];
+    $sects{FOOTNOTES} .= "\n\n";
+}
+
+# stolen from Symbol.pm
+{
+    my $genseq = 0;
+    sub gensym
+    {
+	my $name = "GEN" . $genseq++;
+	my $ref = \*{$name};
+	delete $::{$name};
+	return $ref;
+    }
+}
Index: EcnlProtoTool/trunk/tcc-0.9.27/x86_64-asm.h
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/x86_64-asm.h	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/x86_64-asm.h	(revision 331)
@@ -0,0 +1,525 @@
+     DEF_ASM_OP0(clc, 0xf8) /* must be first OP0 */
+     DEF_ASM_OP0(cld, 0xfc)
+     DEF_ASM_OP0(cli, 0xfa)
+     DEF_ASM_OP0(clts, 0x0f06)
+     DEF_ASM_OP0(cmc, 0xf5)
+     DEF_ASM_OP0(lahf, 0x9f)
+     DEF_ASM_OP0(sahf, 0x9e)
+     DEF_ASM_OP0(pushfq, 0x9c)
+     DEF_ASM_OP0(popfq, 0x9d)
+     DEF_ASM_OP0(pushf, 0x9c)
+     DEF_ASM_OP0(popf, 0x9d)
+     DEF_ASM_OP0(stc, 0xf9)
+     DEF_ASM_OP0(std, 0xfd)
+     DEF_ASM_OP0(sti, 0xfb)
+     DEF_ASM_OP0(aaa, 0x37)
+     DEF_ASM_OP0(aas, 0x3f)
+     DEF_ASM_OP0(daa, 0x27)
+     DEF_ASM_OP0(das, 0x2f)
+     DEF_ASM_OP0(aad, 0xd50a)
+     DEF_ASM_OP0(aam, 0xd40a)
+     DEF_ASM_OP0(cbw, 0x6698)
+     DEF_ASM_OP0(cwd, 0x6699)
+     DEF_ASM_OP0(cwde, 0x98)
+     DEF_ASM_OP0(cdq, 0x99)
+     DEF_ASM_OP0(cbtw, 0x6698)
+     DEF_ASM_OP0(cwtl, 0x98)
+     DEF_ASM_OP0(cwtd, 0x6699)
+     DEF_ASM_OP0(cltd, 0x99)
+     DEF_ASM_OP0(cqto, 0x4899)
+     DEF_ASM_OP0(int3, 0xcc)
+     DEF_ASM_OP0(into, 0xce)
+     DEF_ASM_OP0(iret, 0xcf)
+     DEF_ASM_OP0(rsm, 0x0faa)
+     DEF_ASM_OP0(hlt, 0xf4)
+     DEF_ASM_OP0(wait, 0x9b)
+     DEF_ASM_OP0(nop, 0x90)
+     DEF_ASM_OP0(pause, 0xf390)
+     DEF_ASM_OP0(xlat, 0xd7)
+
+     /* strings */
+ALT(DEF_ASM_OP0L(cmpsb, 0xa6, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(scmpb, 0xa6, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(insb, 0x6c, 0, OPC_BWL))
+ALT(DEF_ASM_OP0L(outsb, 0x6e, 0, OPC_BWL))
+
+ALT(DEF_ASM_OP0L(lodsb, 0xac, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(slodb, 0xac, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(movsb, 0xa4, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(smovb, 0xa4, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(scasb, 0xae, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(sscab, 0xae, 0, OPC_BWLX))
+
+ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWLX))
+ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWLX))
+
+     /* bits */
+
+ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
+
+ALT(DEF_ASM_OP2(btw, 0x0fa3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btw, 0x0fba, 4, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btsw, 0x0fab, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btsw, 0x0fba, 5, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btrw, 0x0fb3, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btrw, 0x0fba, 6, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW | OPT_EA))
+
+     /* prefixes */
+     DEF_ASM_OP0(lock, 0xf0)
+     DEF_ASM_OP0(rep, 0xf3)
+     DEF_ASM_OP0(repe, 0xf3)
+     DEF_ASM_OP0(repz, 0xf3)
+     DEF_ASM_OP0(repne, 0xf2)
+     DEF_ASM_OP0(repnz, 0xf2)
+
+     DEF_ASM_OP0(invd, 0x0f08)
+     DEF_ASM_OP0(wbinvd, 0x0f09)
+     DEF_ASM_OP0(cpuid, 0x0fa2)
+     DEF_ASM_OP0(wrmsr, 0x0f30)
+     DEF_ASM_OP0(rdtsc, 0x0f31)
+     DEF_ASM_OP0(rdmsr, 0x0f32)
+     DEF_ASM_OP0(rdpmc, 0x0f33)
+
+     DEF_ASM_OP0(syscall, 0x0f05)
+     DEF_ASM_OP0(sysret, 0x0f07)
+     DEF_ASM_OP0L(sysretq, 0x480f07, 0, 0)
+     DEF_ASM_OP0(ud2, 0x0f0b)
+
+     /* NOTE: we took the same order as gas opcode definition order */
+/* Right now we can't express the fact that 0xa1/0xa3 can't use $eax and a 
+   32 bit moffset as operands.
+ALT(DEF_ASM_OP2(movb, 0xa0, 0, OPC_BWLX, OPT_ADDR, OPT_EAX))
+ALT(DEF_ASM_OP2(movb, 0xa2, 0, OPC_BWLX, OPT_EAX, OPT_ADDR)) */
+ALT(DEF_ASM_OP2(movb, 0x88, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(movb, 0x8a, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+/* The moves are special: the 0xb8 form supports IM64 (the only insn that
+   does) with REG64.  It doesn't support IM32 with REG64, it would use
+   the full movabs form (64bit immediate).  For IM32->REG64 we prefer
+   the 0xc7 opcode.  So disallow all 64bit forms and code the rest by hand. */
+ALT(DEF_ASM_OP2(movb, 0xb0, 0, OPC_REG | OPC_BWLX, OPT_IM, OPT_REG))
+ALT(DEF_ASM_OP2(mov,  0xb8, 0, OPC_REG, OPT_IM64, OPT_REG64))
+ALT(DEF_ASM_OP2(movq, 0xb8, 0, OPC_REG, OPT_IM64, OPT_REG64))
+ALT(DEF_ASM_OP2(movb, 0xc6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP2(movw, 0x8c, 0, OPC_MODRM | OPC_WLX, OPT_SEG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(movw, 0x8e, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_SEG))
+
+ALT(DEF_ASM_OP2(movw, 0x0f20, 0, OPC_MODRM | OPC_WLX, OPT_CR, OPT_REG64))
+ALT(DEF_ASM_OP2(movw, 0x0f21, 0, OPC_MODRM | OPC_WLX, OPT_DB, OPT_REG64))
+ALT(DEF_ASM_OP2(movw, 0x0f22, 0, OPC_MODRM | OPC_WLX, OPT_REG64, OPT_CR))
+ALT(DEF_ASM_OP2(movw, 0x0f23, 0, OPC_MODRM | OPC_WLX, OPT_REG64, OPT_DB))
+
+ALT(DEF_ASM_OP2(movsbw, 0x660fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG16))
+ALT(DEF_ASM_OP2(movsbl, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(movsbq, 0x0fbe, 0, OPC_MODRM, OPT_REG8 | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(movswl, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(movswq, 0x0fbf, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG))
+ALT(DEF_ASM_OP2(movslq, 0x63, 0, OPC_MODRM, OPT_REG32 | OPT_EA, OPT_REG))
+ALT(DEF_ASM_OP2(movzbw, 0x0fb6, 0, OPC_MODRM | OPC_WLX, OPT_REG8 | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(movzwl, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(movzwq, 0x0fb7, 0, OPC_MODRM, OPT_REG16 | OPT_EA, OPT_REG))
+
+ALT(DEF_ASM_OP1(pushq, 0x6a, 0, 0, OPT_IM8S))
+ALT(DEF_ASM_OP1(push, 0x6a, 0, 0, OPT_IM8S))
+ALT(DEF_ASM_OP1(pushw, 0x666a, 0, 0, OPT_IM8S))
+ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WLX, OPT_REG64))
+ALT(DEF_ASM_OP1(pushw, 0x50, 0, OPC_REG | OPC_WLX, OPT_REG16))
+ALT(DEF_ASM_OP1(pushw, 0xff, 6, OPC_MODRM | OPC_WLX, OPT_REG64 | OPT_EA))
+ALT(DEF_ASM_OP1(pushw, 0x6668, 0, 0, OPT_IM16))
+ALT(DEF_ASM_OP1(pushw, 0x68, 0, OPC_WLX, OPT_IM32))
+ALT(DEF_ASM_OP1(pushw, 0x06, 0, OPC_WLX, OPT_SEG))
+
+ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WLX, OPT_REG64))
+ALT(DEF_ASM_OP1(popw, 0x58, 0, OPC_REG | OPC_WLX, OPT_REG16))
+ALT(DEF_ASM_OP1(popw, 0x8f, 0, OPC_MODRM | OPC_WLX, OPT_REGW | OPT_EA))
+ALT(DEF_ASM_OP1(popw, 0x07, 0, OPC_WLX, OPT_SEG))
+
+ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_REGW, OPT_EAX))
+ALT(DEF_ASM_OP2(xchgw, 0x90, 0, OPC_REG | OPC_WLX, OPT_EAX, OPT_REGW))
+ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(xchgb, 0x86, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+
+ALT(DEF_ASM_OP2(inb, 0xe4, 0, OPC_BWL, OPT_IM8, OPT_EAX))
+ALT(DEF_ASM_OP1(inb, 0xe4, 0, OPC_BWL, OPT_IM8))
+ALT(DEF_ASM_OP2(inb, 0xec, 0, OPC_BWL, OPT_DX, OPT_EAX))
+ALT(DEF_ASM_OP1(inb, 0xec, 0, OPC_BWL, OPT_DX))
+
+ALT(DEF_ASM_OP2(outb, 0xe6, 0, OPC_BWL, OPT_EAX, OPT_IM8))
+ALT(DEF_ASM_OP1(outb, 0xe6, 0, OPC_BWL, OPT_IM8))
+ALT(DEF_ASM_OP2(outb, 0xee, 0, OPC_BWL, OPT_EAX, OPT_DX))
+ALT(DEF_ASM_OP1(outb, 0xee, 0, OPC_BWL, OPT_DX))
+
+ALT(DEF_ASM_OP2(leaw, 0x8d, 0, OPC_MODRM | OPC_WLX, OPT_EA, OPT_REG))
+
+ALT(DEF_ASM_OP2(les, 0xc4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(lds, 0xc5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(lss, 0x0fb2, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(lfs, 0x0fb4, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+ALT(DEF_ASM_OP2(lgs, 0x0fb5, 0, OPC_MODRM, OPT_EA, OPT_REG32))
+
+     /* arith */
+ALT(DEF_ASM_OP2(addb, 0x00, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG)) /* XXX: use D bit ? */
+ALT(DEF_ASM_OP2(addb, 0x02, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP2(addb, 0x04, 0, OPC_ARITH | OPC_BWLX, OPT_IM, OPT_EAX))
+ALT(DEF_ASM_OP2(addw, 0x83, 0, OPC_ARITH | OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(addb, 0x80, 0, OPC_ARITH | OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(testb, 0x84, 0, OPC_MODRM | OPC_BWLX, OPT_EA | OPT_REG, OPT_REG))
+ALT(DEF_ASM_OP2(testb, 0xa8, 0, OPC_BWLX, OPT_IM, OPT_EAX))
+ALT(DEF_ASM_OP2(testb, 0xf6, 0, OPC_MODRM | OPC_BWLX, OPT_IM, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP1(incb, 0xfe, 0, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(decb, 0xfe, 1, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP1(notb, 0xf6, 2, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(negb, 0xf6, 3, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP1(mulb, 0xf6, 4, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP1(imulb, 0xf6, 5, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+
+ALT(DEF_ASM_OP2(imulw, 0x0faf, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG))
+ALT(DEF_ASM_OP3(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(imulw, 0x6b, 0, OPC_MODRM | OPC_WLX, OPT_IM8S, OPT_REGW))
+ALT(DEF_ASM_OP3(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW | OPT_EA, OPT_REGW))
+ALT(DEF_ASM_OP2(imulw, 0x69, 0, OPC_MODRM | OPC_WLX, OPT_IMW, OPT_REGW))
+
+ALT(DEF_ASM_OP1(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP2(divb, 0xf6, 6, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX))
+ALT(DEF_ASM_OP1(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA))
+ALT(DEF_ASM_OP2(idivb, 0xf6, 7, OPC_MODRM | OPC_BWLX, OPT_REG | OPT_EA, OPT_EAX))
+
+     /* shifts */
+ALT(DEF_ASM_OP2(rolb, 0xc0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_IM8, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP2(rolb, 0xd2, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_CL, OPT_EA | OPT_REG))
+ALT(DEF_ASM_OP1(rolb, 0xd0, 0, OPC_MODRM | OPC_BWLX | OPC_SHIFT, OPT_EA | OPT_REG))
+
+ALT(DEF_ASM_OP3(shldw, 0x0fa4, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(shldw, 0x0fa5, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shrdw, 0x0fac, 0, OPC_MODRM | OPC_WLX, OPT_IM8, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA | OPT_REGW))
+ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW))
+
+ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR))
+ALT(DEF_ASM_OP1(call, 0xe8, 0, 0, OPT_DISP))
+ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR))
+ALT(DEF_ASM_OP1(jmp, 0xeb, 0, 0, OPT_DISP8))
+
+ALT(DEF_ASM_OP1(lcall, 0xff, 3, OPC_MODRM, OPT_EA))
+ALT(DEF_ASM_OP1(ljmp, 0xff, 5, OPC_MODRM, OPT_EA))
+    DEF_ASM_OP1(ljmpw, 0x66ff, 5, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(ljmpl, 0xff, 5, OPC_MODRM, OPT_EA)
+
+ALT(DEF_ASM_OP1(int, 0xcd, 0, 0, OPT_IM8))
+ALT(DEF_ASM_OP1(seto, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
+ALT(DEF_ASM_OP1(setob, 0x0f90, 0, OPC_MODRM | OPC_TEST, OPT_REG8 | OPT_EA))
+    DEF_ASM_OP2(enter, 0xc8, 0, 0, OPT_IM16, OPT_IM8)
+    DEF_ASM_OP0(leave, 0xc9)
+    DEF_ASM_OP0(ret, 0xc3)
+    DEF_ASM_OP0(retq, 0xc3)
+ALT(DEF_ASM_OP1(retq, 0xc2, 0, 0, OPT_IM16))
+ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16))
+    DEF_ASM_OP0(lret, 0xcb)
+ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
+
+ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_TEST, OPT_DISP8))
+    DEF_ASM_OP1(loopne, 0xe0, 0, 0, OPT_DISP8)
+    DEF_ASM_OP1(loopnz, 0xe0, 0, 0, OPT_DISP8)
+    DEF_ASM_OP1(loope, 0xe1, 0, 0, OPT_DISP8)
+    DEF_ASM_OP1(loopz, 0xe1, 0, 0, OPT_DISP8)
+    DEF_ASM_OP1(loop, 0xe2, 0, 0, OPT_DISP8)
+    DEF_ASM_OP1(jecxz, 0x67e3, 0, 0, OPT_DISP8)
+
+     /* float */
+     /* specific fcomp handling */
+ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
+
+ALT(DEF_ASM_OP1(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST))
+ALT(DEF_ASM_OP2(fadd, 0xd8c0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
+ALT(DEF_ASM_OP2(fadd, 0xdcc0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
+ALT(DEF_ASM_OP2(fmul, 0xdcc8, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
+ALT(DEF_ASM_OP0L(fadd, 0xdec1, 0, OPC_FARITH))
+ALT(DEF_ASM_OP1(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST))
+ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST, OPT_ST0))
+ALT(DEF_ASM_OP2(faddp, 0xdec0, 0, OPC_FARITH | OPC_REG, OPT_ST0, OPT_ST))
+ALT(DEF_ASM_OP0L(faddp, 0xdec1, 0, OPC_FARITH))
+ALT(DEF_ASM_OP1(fadds, 0xd8, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
+ALT(DEF_ASM_OP1(fiaddl, 0xda, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
+ALT(DEF_ASM_OP1(faddl, 0xdc, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
+ALT(DEF_ASM_OP1(fiadds, 0xde, 0, OPC_FARITH | OPC_MODRM, OPT_EA))
+
+     DEF_ASM_OP0(fucompp, 0xdae9)
+     DEF_ASM_OP0(ftst, 0xd9e4)
+     DEF_ASM_OP0(fxam, 0xd9e5)
+     DEF_ASM_OP0(fld1, 0xd9e8)
+     DEF_ASM_OP0(fldl2t, 0xd9e9)
+     DEF_ASM_OP0(fldl2e, 0xd9ea)
+     DEF_ASM_OP0(fldpi, 0xd9eb)
+     DEF_ASM_OP0(fldlg2, 0xd9ec)
+     DEF_ASM_OP0(fldln2, 0xd9ed)
+     DEF_ASM_OP0(fldz, 0xd9ee)
+
+     DEF_ASM_OP0(f2xm1, 0xd9f0)
+     DEF_ASM_OP0(fyl2x, 0xd9f1)
+     DEF_ASM_OP0(fptan, 0xd9f2)
+     DEF_ASM_OP0(fpatan, 0xd9f3)
+     DEF_ASM_OP0(fxtract, 0xd9f4)
+     DEF_ASM_OP0(fprem1, 0xd9f5)
+     DEF_ASM_OP0(fdecstp, 0xd9f6)
+     DEF_ASM_OP0(fincstp, 0xd9f7)
+     DEF_ASM_OP0(fprem, 0xd9f8)
+     DEF_ASM_OP0(fyl2xp1, 0xd9f9)
+     DEF_ASM_OP0(fsqrt, 0xd9fa)
+     DEF_ASM_OP0(fsincos, 0xd9fb)
+     DEF_ASM_OP0(frndint, 0xd9fc)
+     DEF_ASM_OP0(fscale, 0xd9fd)
+     DEF_ASM_OP0(fsin, 0xd9fe)
+     DEF_ASM_OP0(fcos, 0xd9ff)
+     DEF_ASM_OP0(fchs, 0xd9e0)
+     DEF_ASM_OP0(fabs, 0xd9e1)
+     DEF_ASM_OP0(fninit, 0xdbe3)
+     DEF_ASM_OP0(fnclex, 0xdbe2)
+     DEF_ASM_OP0(fnop, 0xd9d0)
+     DEF_ASM_OP0(fwait, 0x9b)
+
+    /* fp load */
+    DEF_ASM_OP1(fld, 0xd9c0, 0, OPC_REG, OPT_ST)
+    DEF_ASM_OP1(fldl, 0xd9c0, 0, OPC_REG, OPT_ST)
+    DEF_ASM_OP1(flds, 0xd9, 0, OPC_MODRM, OPT_EA)
+ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
+    DEF_ASM_OP1(fildl, 0xdb, 0, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fildq, 0xdf, 5, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
+    DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
+
+    /* fp store */
+    DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
+    DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
+    DEF_ASM_OP1(fsts, 0xd9, 2, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fstps, 0xd9, 3, OPC_MODRM, OPT_EA)
+ALT(DEF_ASM_OP1(fstl, 0xdd, 2, OPC_MODRM, OPT_EA))
+    DEF_ASM_OP1(fstpl, 0xdd, 3, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fist, 0xdf, 2, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fistp, 0xdf, 3, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fistl, 0xdb, 2, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fistpl, 0xdb, 3, OPC_MODRM, OPT_EA)
+
+    DEF_ASM_OP1(fstp, 0xddd8, 0, OPC_REG, OPT_ST)
+    DEF_ASM_OP1(fistpq, 0xdf, 7, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fistpll, 0xdf, 7, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fstpt, 0xdb, 7, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(fbstp, 0xdf, 6, OPC_MODRM, OPT_EA)
+
+    /* exchange */
+    DEF_ASM_OP0(fxch, 0xd9c9)
+ALT(DEF_ASM_OP1(fxch, 0xd9c8, 0, OPC_REG, OPT_ST))
+
+    /* misc FPU */
+    DEF_ASM_OP1(fucom, 0xdde0, 0, OPC_REG, OPT_ST )
+    DEF_ASM_OP1(fucomp, 0xdde8, 0, OPC_REG, OPT_ST )
+
+    DEF_ASM_OP0L(finit, 0xdbe3, 0, OPC_FWAIT)
+    DEF_ASM_OP1(fldcw, 0xd9, 5, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(fnstcw, 0xd9, 7, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(fstcw, 0xd9, 7, OPC_MODRM | OPC_FWAIT, OPT_EA )
+    DEF_ASM_OP0(fnstsw, 0xdfe0)
+ALT(DEF_ASM_OP1(fnstsw, 0xdfe0, 0, 0, OPT_EAX ))
+ALT(DEF_ASM_OP1(fnstsw, 0xdd, 7, OPC_MODRM, OPT_EA ))
+    DEF_ASM_OP1(fstsw, 0xdfe0, 0, OPC_FWAIT, OPT_EAX )
+ALT(DEF_ASM_OP0L(fstsw, 0xdfe0, 0, OPC_FWAIT))
+ALT(DEF_ASM_OP1(fstsw, 0xdd, 7, OPC_MODRM | OPC_FWAIT, OPT_EA ))
+    DEF_ASM_OP0L(fclex, 0xdbe2, 0, OPC_FWAIT)
+    DEF_ASM_OP1(fnstenv, 0xd9, 6, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(fstenv, 0xd9, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
+    DEF_ASM_OP1(fldenv, 0xd9, 4, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(fnsave, 0xdd, 6, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(fsave, 0xdd, 6, OPC_MODRM | OPC_FWAIT, OPT_EA )
+    DEF_ASM_OP1(frstor, 0xdd, 4, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(ffree, 0xddc0, 4, OPC_REG, OPT_ST )
+    DEF_ASM_OP1(ffreep, 0xdfc0, 4, OPC_REG, OPT_ST )
+    DEF_ASM_OP1(fxsave, 0x0fae, 0, OPC_MODRM, OPT_EA )
+    DEF_ASM_OP1(fxrstor, 0x0fae, 1, OPC_MODRM, OPT_EA )
+    /* The *q forms of fxrstor/fxsave use a REX prefix.
+       If the operand would use extended registers we would have to modify
+       it instead of generating a second one.  Currently that's no
+       problem with TCC, we don't use extended registers.  */
+    DEF_ASM_OP1(fxsaveq, 0x0fae, 0, OPC_MODRM | OPC_48, OPT_EA )
+    DEF_ASM_OP1(fxrstorq, 0x0fae, 1, OPC_MODRM | OPC_48, OPT_EA )
+
+    /* segments */
+    DEF_ASM_OP2(arpl, 0x63, 0, OPC_MODRM, OPT_REG16, OPT_REG16 | OPT_EA)
+ALT(DEF_ASM_OP2(larw, 0x0f02, 0, OPC_MODRM | OPC_WLX, OPT_REG | OPT_EA, OPT_REG))
+    DEF_ASM_OP1(lgdt, 0x0f01, 2, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(lgdtq, 0x0f01, 2, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(lidt, 0x0f01, 3, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(lidtq, 0x0f01, 3, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(lldt, 0x0f00, 2, OPC_MODRM, OPT_EA | OPT_REG)
+    DEF_ASM_OP1(lmsw, 0x0f01, 6, OPC_MODRM, OPT_EA | OPT_REG)
+ALT(DEF_ASM_OP2(lslw, 0x0f03, 0, OPC_MODRM | OPC_WLX, OPT_EA | OPT_REG, OPT_REG))
+    DEF_ASM_OP1(ltr, 0x0f00, 3, OPC_MODRM, OPT_EA | OPT_REG16)
+    DEF_ASM_OP1(sgdt, 0x0f01, 0, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(sgdtq, 0x0f01, 0, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(sidt, 0x0f01, 1, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(sidtq, 0x0f01, 1, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(sldt, 0x0f00, 0, OPC_MODRM, OPT_REG | OPT_EA)
+    DEF_ASM_OP1(smsw, 0x0f01, 4, OPC_MODRM, OPT_REG | OPT_EA)
+    DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM, OPT_REG32 | OPT_EA)
+ALT(DEF_ASM_OP1(str, 0x660f00, 1, OPC_MODRM, OPT_REG16))
+ALT(DEF_ASM_OP1(str, 0x0f00, 1, OPC_MODRM | OPC_48, OPT_REG64))
+    DEF_ASM_OP1(verr, 0x0f00, 4, OPC_MODRM, OPT_REG | OPT_EA)
+    DEF_ASM_OP1(verw, 0x0f00, 5, OPC_MODRM, OPT_REG | OPT_EA)
+    DEF_ASM_OP0L(swapgs, 0x0f01, 7, OPC_MODRM)
+
+    /* 486 */
+    /* bswap can't be applied to 16bit regs */
+    DEF_ASM_OP1(bswap, 0x0fc8, 0, OPC_REG, OPT_REG32 )
+    DEF_ASM_OP1(bswapl, 0x0fc8, 0, OPC_REG, OPT_REG32 )
+    DEF_ASM_OP1(bswapq, 0x0fc8, 0, OPC_REG | OPC_48, OPT_REG64 )
+
+ALT(DEF_ASM_OP2(xaddb, 0x0fc0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA ))
+ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWLX, OPT_REG, OPT_REG | OPT_EA ))
+    DEF_ASM_OP1(invlpg, 0x0f01, 7, OPC_MODRM, OPT_EA )
+
+    /* pentium */
+    DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
+
+    /* AMD 64 */
+    DEF_ASM_OP1(cmpxchg16b, 0x0fc7, 1, OPC_MODRM | OPC_48, OPT_EA )
+
+    /* pentium pro */
+ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST | OPC_WLX, OPT_REGW | OPT_EA, OPT_REGW))
+
+    DEF_ASM_OP2(fcmovb, 0xdac0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmove, 0xdac8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmovbe, 0xdad0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmovu, 0xdad8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmovnb, 0xdbc0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmovne, 0xdbc8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmovnbe, 0xdbd0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcmovnu, 0xdbd8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+
+    DEF_ASM_OP2(fucomi, 0xdbe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcomi, 0xdbf0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fucomip, 0xdfe8, 0, OPC_REG, OPT_ST, OPT_ST0 )
+    DEF_ASM_OP2(fcomip, 0xdff0, 0, OPC_REG, OPT_ST, OPT_ST0 )
+
+    /* mmx */
+    DEF_ASM_OP0(emms, 0x0f77) /* must be last OP0 */
+    DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_MMXSSE )
+    /* movd shouldn't accept REG64, but AMD64 spec uses it for 32 and 64 bit
+       moves, so let's be compatible. */
+ALT(DEF_ASM_OP2(movd, 0x0f6e, 0, OPC_MODRM, OPT_EA | OPT_REG64, OPT_MMXSSE ))
+ALT(DEF_ASM_OP2(movq, 0x0f6e, 0, OPC_MODRM | OPC_48, OPT_REG64, OPT_MMXSSE ))
+ALT(DEF_ASM_OP2(movq, 0x0f6f, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_MMX ))
+ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG32 ))
+ALT(DEF_ASM_OP2(movd, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG64 ))
+ALT(DEF_ASM_OP2(movq, 0x0f7f, 0, OPC_MODRM, OPT_MMX, OPT_EA | OPT_MMX ))
+ALT(DEF_ASM_OP2(movq, 0x660fd6, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_SSE ))
+ALT(DEF_ASM_OP2(movq, 0xf30f7e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE ))
+ALT(DEF_ASM_OP2(movq, 0x0f7e, 0, OPC_MODRM, OPT_MMXSSE, OPT_EA | OPT_REG64 ))
+
+    DEF_ASM_OP2(packssdw, 0x0f6b, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(packsswb, 0x0f63, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(packuswb, 0x0f67, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddb, 0x0ffc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddw, 0x0ffd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddd, 0x0ffe, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddsb, 0x0fec, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddsw, 0x0fed, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddusb, 0x0fdc, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(paddusw, 0x0fdd, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pand, 0x0fdb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pandn, 0x0fdf, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpeqb, 0x0f74, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpeqw, 0x0f75, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpeqd, 0x0f76, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpgtb, 0x0f64, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpgtw, 0x0f65, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pcmpgtd, 0x0f66, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pmaddwd, 0x0ff5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pmulhw, 0x0fe5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pmullw, 0x0fd5, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(por, 0x0feb, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psllw, 0x0ff1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psllw, 0x0f71, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(pslld, 0x0ff2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(pslld, 0x0f72, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psllq, 0x0ff3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psllq, 0x0f73, 6, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psraw, 0x0fe1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psraw, 0x0f71, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psrad, 0x0fe2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrad, 0x0f72, 4, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psrlw, 0x0fd1, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrlw, 0x0f71, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psrld, 0x0fd2, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrld, 0x0f72, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psrlq, 0x0fd3, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+ALT(DEF_ASM_OP2(psrlq, 0x0f73, 2, OPC_MODRM, OPT_IM8, OPT_MMXSSE ))
+    DEF_ASM_OP2(psubb, 0x0ff8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubw, 0x0ff9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubd, 0x0ffa, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubsb, 0x0fe8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubsw, 0x0fe9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubusb, 0x0fd8, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(psubusw, 0x0fd9, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpckhbw, 0x0f68, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpckhwd, 0x0f69, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpckhdq, 0x0f6a, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpcklbw, 0x0f60, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpcklwd, 0x0f61, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(punpckldq, 0x0f62, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pxor, 0x0fef, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+
+    /* sse */
+    DEF_ASM_OP2(movups, 0x0f10, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
+ALT(DEF_ASM_OP2(movups, 0x0f11, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
+    DEF_ASM_OP2(movaps, 0x0f28, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
+ALT(DEF_ASM_OP2(movaps, 0x0f29, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
+    DEF_ASM_OP2(movhps, 0x0f16, 0, OPC_MODRM, OPT_EA | OPT_REG32, OPT_SSE )
+ALT(DEF_ASM_OP2(movhps, 0x0f17, 0, OPC_MODRM, OPT_SSE, OPT_EA | OPT_REG32 ))
+    DEF_ASM_OP2(addps, 0x0f58, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(cvtpi2ps, 0x0f2a, 0, OPC_MODRM, OPT_EA | OPT_MMX, OPT_SSE )
+    DEF_ASM_OP2(cvtps2pi, 0x0f2d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX )
+    DEF_ASM_OP2(cvttps2pi, 0x0f2c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_MMX )
+    DEF_ASM_OP2(divps, 0x0f5e, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(maxps, 0x0f5f, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(minps, 0x0f5d, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(mulps, 0x0f59, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(pavgb, 0x0fe0, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(pavgw, 0x0fe3, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(pmaxsw, 0x0fee, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pmaxub, 0x0fde, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pminsw, 0x0fea, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(pminub, 0x0fda, 0, OPC_MODRM, OPT_EA | OPT_MMXSSE, OPT_MMXSSE )
+    DEF_ASM_OP2(rcpss, 0x0f53, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(rsqrtps, 0x0f52, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(sqrtps, 0x0f51, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+    DEF_ASM_OP2(subps, 0x0f5c, 0, OPC_MODRM, OPT_EA | OPT_SSE, OPT_SSE )
+
+    DEF_ASM_OP1(prefetchnta, 0x0f18, 0, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(prefetcht0, 0x0f18, 1, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(prefetcht1, 0x0f18, 2, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(prefetcht2, 0x0f18, 3, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP1(prefetchw, 0x0f0d, 1, OPC_MODRM, OPT_EA)
+    DEF_ASM_OP0L(lfence, 0x0fae, 5, OPC_MODRM)
+    DEF_ASM_OP0L(mfence, 0x0fae, 6, OPC_MODRM)
+    DEF_ASM_OP0L(sfence, 0x0fae, 7, OPC_MODRM)
+    DEF_ASM_OP1(clflush, 0x0fae, 7, OPC_MODRM, OPT_EA)
+#undef ALT
+#undef DEF_ASM_OP0
+#undef DEF_ASM_OP0L
+#undef DEF_ASM_OP1
+#undef DEF_ASM_OP2
+#undef DEF_ASM_OP3
Index: EcnlProtoTool/trunk/tcc-0.9.27/x86_64-gen.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/x86_64-gen.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/x86_64-gen.c	(revision 331)
@@ -0,0 +1,2258 @@
+/*
+ *  x86-64 code generator for TCC
+ *
+ *  Copyright (c) 2008 Shinichiro Hamaji
+ *
+ *  Based on i386-gen.c by Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef TARGET_DEFS_ONLY
+
+/* number of available registers */
+#define NB_REGS         25
+#define NB_ASM_REGS     16
+#define CONFIG_TCC_ASM
+
+/* a register can belong to several classes. The classes must be
+   sorted from more general to more precise (see gv2() code which does
+   assumptions on it). */
+#define RC_INT     0x0001 /* generic integer register */
+#define RC_FLOAT   0x0002 /* generic float register */
+#define RC_RAX     0x0004
+#define RC_RCX     0x0008
+#define RC_RDX     0x0010
+#define RC_ST0     0x0080 /* only for long double */
+#define RC_R8      0x0100
+#define RC_R9      0x0200
+#define RC_R10     0x0400
+#define RC_R11     0x0800
+#define RC_XMM0    0x1000
+#define RC_XMM1    0x2000
+#define RC_XMM2    0x4000
+#define RC_XMM3    0x8000
+#define RC_XMM4    0x10000
+#define RC_XMM5    0x20000
+#define RC_XMM6    0x40000
+#define RC_XMM7    0x80000
+#define RC_IRET    RC_RAX /* function return: integer register */
+#define RC_LRET    RC_RDX /* function return: second integer register */
+#define RC_FRET    RC_XMM0 /* function return: float register */
+#define RC_QRET    RC_XMM1 /* function return: second float register */
+
+/* pretty names for the registers */
+enum {
+    TREG_RAX = 0,
+    TREG_RCX = 1,
+    TREG_RDX = 2,
+    TREG_RSP = 4,
+    TREG_RSI = 6,
+    TREG_RDI = 7,
+
+    TREG_R8  = 8,
+    TREG_R9  = 9,
+    TREG_R10 = 10,
+    TREG_R11 = 11,
+
+    TREG_XMM0 = 16,
+    TREG_XMM1 = 17,
+    TREG_XMM2 = 18,
+    TREG_XMM3 = 19,
+    TREG_XMM4 = 20,
+    TREG_XMM5 = 21,
+    TREG_XMM6 = 22,
+    TREG_XMM7 = 23,
+
+    TREG_ST0 = 24,
+
+    TREG_MEM = 0x20
+};
+
+#define REX_BASE(reg) (((reg) >> 3) & 1)
+#define REG_VALUE(reg) ((reg) & 7)
+
+/* return registers for function */
+#define REG_IRET TREG_RAX /* single word int return register */
+#define REG_LRET TREG_RDX /* second word return register (for long long) */
+#define REG_FRET TREG_XMM0 /* float return register */
+#define REG_QRET TREG_XMM1 /* second float return register */
+
+/* defined if function parameters must be evaluated in reverse order */
+#define INVERT_FUNC_PARAMS
+
+/* pointer size, in bytes */
+#define PTR_SIZE 8
+
+/* long double size and alignment, in bytes */
+#define LDOUBLE_SIZE  16
+#define LDOUBLE_ALIGN 16
+/* maximum alignment (for aligned attribute support) */
+#define MAX_ALIGN     16
+
+/******************************************************/
+#else /* ! TARGET_DEFS_ONLY */
+/******************************************************/
+#include "tcc.h"
+#include <assert.h>
+
+ST_DATA const int reg_classes[NB_REGS] = {
+    /* eax */ RC_INT | RC_RAX,
+    /* ecx */ RC_INT | RC_RCX,
+    /* edx */ RC_INT | RC_RDX,
+    0,
+    0,
+    0,
+    0,
+    0,
+    RC_R8,
+    RC_R9,
+    RC_R10,
+    RC_R11,
+    0,
+    0,
+    0,
+    0,
+    /* xmm0 */ RC_FLOAT | RC_XMM0,
+    /* xmm1 */ RC_FLOAT | RC_XMM1,
+    /* xmm2 */ RC_FLOAT | RC_XMM2,
+    /* xmm3 */ RC_FLOAT | RC_XMM3,
+    /* xmm4 */ RC_FLOAT | RC_XMM4,
+    /* xmm5 */ RC_FLOAT | RC_XMM5,
+    /* xmm6 an xmm7 are included so gv() can be used on them,
+       but they are not tagged with RC_FLOAT because they are
+       callee saved on Windows */
+    RC_XMM6,
+    RC_XMM7,
+    /* st0 */ RC_ST0
+};
+
+static unsigned long func_sub_sp_offset;
+static int func_ret_sub;
+
+/* XXX: make it faster ? */
+ST_FUNC void g(int c)
+{
+    int ind1;
+    if (nocode_wanted)
+        return;
+    ind1 = ind + 1;
+    if (ind1 > cur_text_section->data_allocated)
+        section_realloc(cur_text_section, ind1);
+    cur_text_section->data[ind] = c;
+    ind = ind1;
+}
+
+ST_FUNC void o(unsigned int c)
+{
+    while (c) {
+        g(c);
+        c = c >> 8;
+    }
+}
+
+ST_FUNC void gen_le16(int v)
+{
+    g(v);
+    g(v >> 8);
+}
+
+ST_FUNC void gen_le32(int c)
+{
+    g(c);
+    g(c >> 8);
+    g(c >> 16);
+    g(c >> 24);
+}
+
+ST_FUNC void gen_le64(int64_t c)
+{
+    g(c);
+    g(c >> 8);
+    g(c >> 16);
+    g(c >> 24);
+    g(c >> 32);
+    g(c >> 40);
+    g(c >> 48);
+    g(c >> 56);
+}
+
+static void orex(int ll, int r, int r2, int b)
+{
+    if ((r & VT_VALMASK) >= VT_CONST)
+        r = 0;
+    if ((r2 & VT_VALMASK) >= VT_CONST)
+        r2 = 0;
+    if (ll || REX_BASE(r) || REX_BASE(r2))
+        o(0x40 | REX_BASE(r) | (REX_BASE(r2) << 2) | (ll << 3));
+    o(b);
+}
+
+/* output a symbol and patch all calls to it */
+ST_FUNC void gsym_addr(int t, int a)
+{
+    while (t) {
+        unsigned char *ptr = cur_text_section->data + t;
+        uint32_t n = read32le(ptr); /* next value */
+        write32le(ptr, a - t - 4);
+        t = n;
+    }
+}
+
+void gsym(int t)
+{
+    gsym_addr(t, ind);
+}
+
+
+static int is64_type(int t)
+{
+    return ((t & VT_BTYPE) == VT_PTR ||
+            (t & VT_BTYPE) == VT_FUNC ||
+            (t & VT_BTYPE) == VT_LLONG);
+}
+
+/* instruction + 4 bytes data. Return the address of the data */
+static int oad(int c, int s)
+{
+    int t;
+    if (nocode_wanted)
+        return s;
+    o(c);
+    t = ind;
+    gen_le32(s);
+    return t;
+}
+
+/* generate jmp to a label */
+#define gjmp2(instr,lbl) oad(instr,lbl)
+
+ST_FUNC void gen_addr32(int r, Sym *sym, int c)
+{
+    if (r & VT_SYM)
+        greloca(cur_text_section, sym, ind, R_X86_64_32S, c), c=0;
+    gen_le32(c);
+}
+
+/* output constant with relocation if 'r & VT_SYM' is true */
+ST_FUNC void gen_addr64(int r, Sym *sym, int64_t c)
+{
+    if (r & VT_SYM)
+        greloca(cur_text_section, sym, ind, R_X86_64_64, c), c=0;
+    gen_le64(c);
+}
+
+/* output constant with relocation if 'r & VT_SYM' is true */
+ST_FUNC void gen_addrpc32(int r, Sym *sym, int c)
+{
+    if (r & VT_SYM)
+        greloca(cur_text_section, sym, ind, R_X86_64_PC32, c-4), c=4;
+    gen_le32(c-4);
+}
+
+/* output got address with relocation */
+static void gen_gotpcrel(int r, Sym *sym, int c)
+{
+#ifdef TCC_TARGET_PE
+    tcc_error("internal error: no GOT on PE: %s %x %x | %02x %02x %02x\n",
+        get_tok_str(sym->v, NULL), c, r,
+        cur_text_section->data[ind-3],
+        cur_text_section->data[ind-2],
+        cur_text_section->data[ind-1]
+        );
+#endif
+    greloca(cur_text_section, sym, ind, R_X86_64_GOTPCREL, -4);
+    gen_le32(0);
+    if (c) {
+        /* we use add c, %xxx for displacement */
+        orex(1, r, 0, 0x81);
+        o(0xc0 + REG_VALUE(r));
+        gen_le32(c);
+    }
+}
+
+static void gen_modrm_impl(int op_reg, int r, Sym *sym, int c, int is_got)
+{
+    op_reg = REG_VALUE(op_reg) << 3;
+    if ((r & VT_VALMASK) == VT_CONST) {
+        /* constant memory reference */
+	if (!(r & VT_SYM)) {
+	    /* Absolute memory reference */
+	    o(0x04 | op_reg); /* [sib] | destreg */
+	    oad(0x25, c);     /* disp32 */
+	} else {
+	    o(0x05 | op_reg); /* (%rip)+disp32 | destreg */
+	    if (is_got) {
+		gen_gotpcrel(r, sym, c);
+	    } else {
+		gen_addrpc32(r, sym, c);
+	    }
+	}
+    } else if ((r & VT_VALMASK) == VT_LOCAL) {
+        /* currently, we use only ebp as base */
+        if (c == (char)c) {
+            /* short reference */
+            o(0x45 | op_reg);
+            g(c);
+        } else {
+            oad(0x85 | op_reg, c);
+        }
+    } else if ((r & VT_VALMASK) >= TREG_MEM) {
+        if (c) {
+            g(0x80 | op_reg | REG_VALUE(r));
+            gen_le32(c);
+        } else {
+            g(0x00 | op_reg | REG_VALUE(r));
+        }
+    } else {
+        g(0x00 | op_reg | REG_VALUE(r));
+    }
+}
+
+/* generate a modrm reference. 'op_reg' contains the additional 3
+   opcode bits */
+static void gen_modrm(int op_reg, int r, Sym *sym, int c)
+{
+    gen_modrm_impl(op_reg, r, sym, c, 0);
+}
+
+/* generate a modrm reference. 'op_reg' contains the additional 3
+   opcode bits */
+static void gen_modrm64(int opcode, int op_reg, int r, Sym *sym, int c)
+{
+    int is_got;
+    is_got = (op_reg & TREG_MEM) && !(sym->type.t & VT_STATIC);
+    orex(1, r, op_reg, opcode);
+    gen_modrm_impl(op_reg, r, sym, c, is_got);
+}
+
+
+/* load 'r' from value 'sv' */
+void load(int r, SValue *sv)
+{
+    int v, t, ft, fc, fr;
+    SValue v1;
+
+#ifdef TCC_TARGET_PE
+    SValue v2;
+    sv = pe_getimport(sv, &v2);
+#endif
+
+    fr = sv->r;
+    ft = sv->type.t & ~VT_DEFSIGN;
+    fc = sv->c.i;
+    if (fc != sv->c.i && (fr & VT_SYM))
+      tcc_error("64 bit addend in load");
+
+    ft &= ~(VT_VOLATILE | VT_CONSTANT);
+
+#ifndef TCC_TARGET_PE
+    /* we use indirect access via got */
+    if ((fr & VT_VALMASK) == VT_CONST && (fr & VT_SYM) &&
+        (fr & VT_LVAL) && !(sv->sym->type.t & VT_STATIC)) {
+        /* use the result register as a temporal register */
+        int tr = r | TREG_MEM;
+        if (is_float(ft)) {
+            /* we cannot use float registers as a temporal register */
+            tr = get_reg(RC_INT) | TREG_MEM;
+        }
+        gen_modrm64(0x8b, tr, fr, sv->sym, 0);
+
+        /* load from the temporal register */
+        fr = tr | VT_LVAL;
+    }
+#endif
+
+    v = fr & VT_VALMASK;
+    if (fr & VT_LVAL) {
+        int b, ll;
+        if (v == VT_LLOCAL) {
+            v1.type.t = VT_PTR;
+            v1.r = VT_LOCAL | VT_LVAL;
+            v1.c.i = fc;
+            fr = r;
+            if (!(reg_classes[fr] & (RC_INT|RC_R11)))
+                fr = get_reg(RC_INT);
+            load(fr, &v1);
+        }
+	if (fc != sv->c.i) {
+	    /* If the addends doesn't fit into a 32bit signed
+	       we must use a 64bit move.  We've checked above
+	       that this doesn't have a sym associated.  */
+	    v1.type.t = VT_LLONG;
+	    v1.r = VT_CONST;
+	    v1.c.i = sv->c.i;
+	    fr = r;
+	    if (!(reg_classes[fr] & (RC_INT|RC_R11)))
+	        fr = get_reg(RC_INT);
+	    load(fr, &v1);
+	    fc = 0;
+	}
+        ll = 0;
+	/* Like GCC we can load from small enough properly sized
+	   structs and unions as well.
+	   XXX maybe move to generic operand handling, but should
+	   occur only with asm, so tccasm.c might also be a better place */
+	if ((ft & VT_BTYPE) == VT_STRUCT) {
+	    int align;
+	    switch (type_size(&sv->type, &align)) {
+		case 1: ft = VT_BYTE; break;
+		case 2: ft = VT_SHORT; break;
+		case 4: ft = VT_INT; break;
+		case 8: ft = VT_LLONG; break;
+		default:
+		    tcc_error("invalid aggregate type for register load");
+		    break;
+	    }
+	}
+        if ((ft & VT_BTYPE) == VT_FLOAT) {
+            b = 0x6e0f66;
+            r = REG_VALUE(r); /* movd */
+        } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
+            b = 0x7e0ff3; /* movq */
+            r = REG_VALUE(r);
+        } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
+            b = 0xdb, r = 5; /* fldt */
+        } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) {
+            b = 0xbe0f;   /* movsbl */
+        } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
+            b = 0xb60f;   /* movzbl */
+        } else if ((ft & VT_TYPE) == VT_SHORT) {
+            b = 0xbf0f;   /* movswl */
+        } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) {
+            b = 0xb70f;   /* movzwl */
+        } else {
+            assert(((ft & VT_BTYPE) == VT_INT)
+                   || ((ft & VT_BTYPE) == VT_LLONG)
+                   || ((ft & VT_BTYPE) == VT_PTR)
+                   || ((ft & VT_BTYPE) == VT_FUNC)
+                );
+            ll = is64_type(ft);
+            b = 0x8b;
+        }
+        if (ll) {
+            gen_modrm64(b, r, fr, sv->sym, fc);
+        } else {
+            orex(ll, fr, r, b);
+            gen_modrm(r, fr, sv->sym, fc);
+        }
+    } else {
+        if (v == VT_CONST) {
+            if (fr & VT_SYM) {
+#ifdef TCC_TARGET_PE
+                orex(1,0,r,0x8d);
+                o(0x05 + REG_VALUE(r) * 8); /* lea xx(%rip), r */
+                gen_addrpc32(fr, sv->sym, fc);
+#else
+                if (sv->sym->type.t & VT_STATIC) {
+                    orex(1,0,r,0x8d);
+                    o(0x05 + REG_VALUE(r) * 8); /* lea xx(%rip), r */
+                    gen_addrpc32(fr, sv->sym, fc);
+                } else {
+                    orex(1,0,r,0x8b);
+                    o(0x05 + REG_VALUE(r) * 8); /* mov xx(%rip), r */
+                    gen_gotpcrel(r, sv->sym, fc);
+                }
+#endif
+            } else if (is64_type(ft)) {
+                orex(1,r,0, 0xb8 + REG_VALUE(r)); /* mov $xx, r */
+                gen_le64(sv->c.i);
+            } else {
+                orex(0,r,0, 0xb8 + REG_VALUE(r)); /* mov $xx, r */
+                gen_le32(fc);
+            }
+        } else if (v == VT_LOCAL) {
+            orex(1,0,r,0x8d); /* lea xxx(%ebp), r */
+            gen_modrm(r, VT_LOCAL, sv->sym, fc);
+        } else if (v == VT_CMP) {
+            orex(0,r,0,0);
+	    if ((fc & ~0x100) != TOK_NE)
+              oad(0xb8 + REG_VALUE(r), 0); /* mov $0, r */
+	    else
+              oad(0xb8 + REG_VALUE(r), 1); /* mov $1, r */
+	    if (fc & 0x100)
+	      {
+	        /* This was a float compare.  If the parity bit is
+		   set the result was unordered, meaning false for everything
+		   except TOK_NE, and true for TOK_NE.  */
+		fc &= ~0x100;
+		o(0x037a + (REX_BASE(r) << 8));
+	      }
+            orex(0,r,0, 0x0f); /* setxx %br */
+            o(fc);
+            o(0xc0 + REG_VALUE(r));
+        } else if (v == VT_JMP || v == VT_JMPI) {
+            t = v & 1;
+            orex(0,r,0,0);
+            oad(0xb8 + REG_VALUE(r), t); /* mov $1, r */
+            o(0x05eb + (REX_BASE(r) << 8)); /* jmp after */
+            gsym(fc);
+            orex(0,r,0,0);
+            oad(0xb8 + REG_VALUE(r), t ^ 1); /* mov $0, r */
+        } else if (v != r) {
+            if ((r >= TREG_XMM0) && (r <= TREG_XMM7)) {
+                if (v == TREG_ST0) {
+                    /* gen_cvt_ftof(VT_DOUBLE); */
+                    o(0xf0245cdd); /* fstpl -0x10(%rsp) */
+                    /* movsd -0x10(%rsp),%xmmN */
+                    o(0x100ff2);
+                    o(0x44 + REG_VALUE(r)*8); /* %xmmN */
+                    o(0xf024);
+                } else {
+                    assert((v >= TREG_XMM0) && (v <= TREG_XMM7));
+                    if ((ft & VT_BTYPE) == VT_FLOAT) {
+                        o(0x100ff3);
+                    } else {
+                        assert((ft & VT_BTYPE) == VT_DOUBLE);
+                        o(0x100ff2);
+                    }
+                    o(0xc0 + REG_VALUE(v) + REG_VALUE(r)*8);
+                }
+            } else if (r == TREG_ST0) {
+                assert((v >= TREG_XMM0) && (v <= TREG_XMM7));
+                /* gen_cvt_ftof(VT_LDOUBLE); */
+                /* movsd %xmmN,-0x10(%rsp) */
+                o(0x110ff2);
+                o(0x44 + REG_VALUE(r)*8); /* %xmmN */
+                o(0xf024);
+                o(0xf02444dd); /* fldl -0x10(%rsp) */
+            } else {
+                orex(1,r,v, 0x89);
+                o(0xc0 + REG_VALUE(r) + REG_VALUE(v) * 8); /* mov v, r */
+            }
+        }
+    }
+}
+
+/* store register 'r' in lvalue 'v' */
+void store(int r, SValue *v)
+{
+    int fr, bt, ft, fc;
+    int op64 = 0;
+    /* store the REX prefix in this variable when PIC is enabled */
+    int pic = 0;
+
+#ifdef TCC_TARGET_PE
+    SValue v2;
+    v = pe_getimport(v, &v2);
+#endif
+
+    fr = v->r & VT_VALMASK;
+    ft = v->type.t;
+    fc = v->c.i;
+    if (fc != v->c.i && (fr & VT_SYM))
+      tcc_error("64 bit addend in store");
+    ft &= ~(VT_VOLATILE | VT_CONSTANT);
+    bt = ft & VT_BTYPE;
+
+#ifndef TCC_TARGET_PE
+    /* we need to access the variable via got */
+    if (fr == VT_CONST && (v->r & VT_SYM)) {
+        /* mov xx(%rip), %r11 */
+        o(0x1d8b4c);
+        gen_gotpcrel(TREG_R11, v->sym, v->c.i);
+        pic = is64_type(bt) ? 0x49 : 0x41;
+    }
+#endif
+
+    /* XXX: incorrect if float reg to reg */
+    if (bt == VT_FLOAT) {
+        o(0x66);
+        o(pic);
+        o(0x7e0f); /* movd */
+        r = REG_VALUE(r);
+    } else if (bt == VT_DOUBLE) {
+        o(0x66);
+        o(pic);
+        o(0xd60f); /* movq */
+        r = REG_VALUE(r);
+    } else if (bt == VT_LDOUBLE) {
+        o(0xc0d9); /* fld %st(0) */
+        o(pic);
+        o(0xdb); /* fstpt */
+        r = 7;
+    } else {
+        if (bt == VT_SHORT)
+            o(0x66);
+        o(pic);
+        if (bt == VT_BYTE || bt == VT_BOOL)
+            orex(0, 0, r, 0x88);
+        else if (is64_type(bt))
+            op64 = 0x89;
+        else
+            orex(0, 0, r, 0x89);
+    }
+    if (pic) {
+        /* xxx r, (%r11) where xxx is mov, movq, fld, or etc */
+        if (op64)
+            o(op64);
+        o(3 + (r << 3));
+    } else if (op64) {
+        if (fr == VT_CONST || fr == VT_LOCAL || (v->r & VT_LVAL)) {
+            gen_modrm64(op64, r, v->r, v->sym, fc);
+        } else if (fr != r) {
+            /* XXX: don't we really come here? */
+            abort();
+            o(0xc0 + fr + r * 8); /* mov r, fr */
+        }
+    } else {
+        if (fr == VT_CONST || fr == VT_LOCAL || (v->r & VT_LVAL)) {
+            gen_modrm(r, v->r, v->sym, fc);
+        } else if (fr != r) {
+            /* XXX: don't we really come here? */
+            abort();
+            o(0xc0 + fr + r * 8); /* mov r, fr */
+        }
+    }
+}
+
+/* 'is_jmp' is '1' if it is a jump */
+static void gcall_or_jmp(int is_jmp)
+{
+    int r;
+    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
+	((vtop->r & VT_SYM) || (vtop->c.i-4) == (int)(vtop->c.i-4))) {
+        /* constant case */
+        if (vtop->r & VT_SYM) {
+            /* relocation case */
+#ifdef TCC_TARGET_PE
+            greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PC32, (int)(vtop->c.i-4));
+#else
+            greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PLT32, (int)(vtop->c.i-4));
+#endif
+        } else {
+            /* put an empty PC32 relocation */
+            put_elf_reloca(symtab_section, cur_text_section,
+                          ind + 1, R_X86_64_PC32, 0, (int)(vtop->c.i-4));
+        }
+        oad(0xe8 + is_jmp, 0); /* call/jmp im */
+    } else {
+        /* otherwise, indirect call */
+        r = TREG_R11;
+        load(r, vtop);
+        o(0x41); /* REX */
+        o(0xff); /* call/jmp *r */
+        o(0xd0 + REG_VALUE(r) + (is_jmp << 4));
+    }
+}
+
+#if defined(CONFIG_TCC_BCHECK)
+#ifndef TCC_TARGET_PE
+static addr_t func_bound_offset;
+static unsigned long func_bound_ind;
+#endif
+
+static void gen_static_call(int v)
+{
+    Sym *sym = external_global_sym(v, &func_old_type, 0);
+    oad(0xe8, 0);
+    greloca(cur_text_section, sym, ind-4, R_X86_64_PC32, -4);
+}
+
+/* generate a bounded pointer addition */
+ST_FUNC void gen_bounded_ptr_add(void)
+{
+    /* save all temporary registers */
+    save_regs(0);
+
+    /* prepare fast x86_64 function call */
+    gv(RC_RAX);
+    o(0xc68948); // mov  %rax,%rsi ## second arg in %rsi, this must be size
+    vtop--;
+
+    gv(RC_RAX);
+    o(0xc78948); // mov  %rax,%rdi ## first arg in %rdi, this must be ptr
+    vtop--;
+
+    /* do a fast function call */
+    gen_static_call(TOK___bound_ptr_add);
+
+    /* returned pointer is in rax */
+    vtop++;
+    vtop->r = TREG_RAX | VT_BOUNDED;
+
+
+    /* relocation offset of the bounding function call point */
+    vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(ElfW(Rela)));
+}
+
+/* patch pointer addition in vtop so that pointer dereferencing is
+   also tested */
+ST_FUNC void gen_bounded_ptr_deref(void)
+{
+    addr_t func;
+    int size, align;
+    ElfW(Rela) *rel;
+    Sym *sym;
+
+    size = 0;
+    /* XXX: put that code in generic part of tcc */
+    if (!is_float(vtop->type.t)) {
+        if (vtop->r & VT_LVAL_BYTE)
+            size = 1;
+        else if (vtop->r & VT_LVAL_SHORT)
+            size = 2;
+    }
+    if (!size)
+    size = type_size(&vtop->type, &align);
+    switch(size) {
+    case  1: func = TOK___bound_ptr_indir1; break;
+    case  2: func = TOK___bound_ptr_indir2; break;
+    case  4: func = TOK___bound_ptr_indir4; break;
+    case  8: func = TOK___bound_ptr_indir8; break;
+    case 12: func = TOK___bound_ptr_indir12; break;
+    case 16: func = TOK___bound_ptr_indir16; break;
+    default:
+        tcc_error("unhandled size when dereferencing bounded pointer");
+        func = 0;
+        break;
+    }
+
+    sym = external_global_sym(func, &func_old_type, 0);
+    if (!sym->c)
+        put_extern_sym(sym, NULL, 0, 0);
+
+    /* patch relocation */
+    /* XXX: find a better solution ? */
+
+    rel = (ElfW(Rela) *)(cur_text_section->reloc->data + vtop->c.i);
+    rel->r_info = ELF64_R_INFO(sym->c, ELF64_R_TYPE(rel->r_info));
+}
+#endif
+
+#ifdef TCC_TARGET_PE
+
+#define REGN 4
+static const uint8_t arg_regs[REGN] = {
+    TREG_RCX, TREG_RDX, TREG_R8, TREG_R9
+};
+
+/* Prepare arguments in R10 and R11 rather than RCX and RDX
+   because gv() will not ever use these */
+static int arg_prepare_reg(int idx) {
+  if (idx == 0 || idx == 1)
+      /* idx=0: r10, idx=1: r11 */
+      return idx + 10;
+  else
+      return arg_regs[idx];
+}
+
+static int func_scratch, func_alloca;
+
+/* Generate function call. The function address is pushed first, then
+   all the parameters in call order. This functions pops all the
+   parameters and the function address. */
+
+static void gen_offs_sp(int b, int r, int d)
+{
+    orex(1,0,r & 0x100 ? 0 : r, b);
+    if (d == (char)d) {
+        o(0x2444 | (REG_VALUE(r) << 3));
+        g(d);
+    } else {
+        o(0x2484 | (REG_VALUE(r) << 3));
+        gen_le32(d);
+    }
+}
+
+static int using_regs(int size)
+{
+    return !(size > 8 || (size & (size - 1)));
+}
+
+/* Return the number of registers needed to return the struct, or 0 if
+   returning via struct pointer. */
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize)
+{
+    int size, align;
+    *ret_align = 1; // Never have to re-align return values for x86-64
+    *regsize = 8;
+    size = type_size(vt, &align);
+    if (!using_regs(size))
+        return 0;
+    if (size == 8)
+        ret->t = VT_LLONG;
+    else if (size == 4)
+        ret->t = VT_INT;
+    else if (size == 2)
+        ret->t = VT_SHORT;
+    else
+        ret->t = VT_BYTE;
+    ret->ref = NULL;
+    return 1;
+}
+
+static int is_sse_float(int t) {
+    int bt;
+    bt = t & VT_BTYPE;
+    return bt == VT_DOUBLE || bt == VT_FLOAT;
+}
+
+static int gfunc_arg_size(CType *type) {
+    int align;
+    if (type->t & (VT_ARRAY|VT_BITFIELD))
+        return 8;
+    return type_size(type, &align);
+}
+
+void gfunc_call(int nb_args)
+{
+    int size, r, args_size, i, d, bt, struct_size;
+    int arg;
+
+    args_size = (nb_args < REGN ? REGN : nb_args) * PTR_SIZE;
+    arg = nb_args;
+
+    /* for struct arguments, we need to call memcpy and the function
+       call breaks register passing arguments we are preparing.
+       So, we process arguments which will be passed by stack first. */
+    struct_size = args_size;
+    for(i = 0; i < nb_args; i++) {
+        SValue *sv;
+        
+        --arg;
+        sv = &vtop[-i];
+        bt = (sv->type.t & VT_BTYPE);
+        size = gfunc_arg_size(&sv->type);
+
+        if (using_regs(size))
+            continue; /* arguments smaller than 8 bytes passed in registers or on stack */
+
+        if (bt == VT_STRUCT) {
+            /* align to stack align size */
+            size = (size + 15) & ~15;
+            /* generate structure store */
+            r = get_reg(RC_INT);
+            gen_offs_sp(0x8d, r, struct_size);
+            struct_size += size;
+
+            /* generate memcpy call */
+            vset(&sv->type, r | VT_LVAL, 0);
+            vpushv(sv);
+            vstore();
+            --vtop;
+        } else if (bt == VT_LDOUBLE) {
+            gv(RC_ST0);
+            gen_offs_sp(0xdb, 0x107, struct_size);
+            struct_size += 16;
+        }
+    }
+
+    if (func_scratch < struct_size)
+        func_scratch = struct_size;
+
+    arg = nb_args;
+    struct_size = args_size;
+
+    for(i = 0; i < nb_args; i++) {
+        --arg;
+        bt = (vtop->type.t & VT_BTYPE);
+
+        size = gfunc_arg_size(&vtop->type);
+        if (!using_regs(size)) {
+            /* align to stack align size */
+            size = (size + 15) & ~15;
+            if (arg >= REGN) {
+                d = get_reg(RC_INT);
+                gen_offs_sp(0x8d, d, struct_size);
+                gen_offs_sp(0x89, d, arg*8);
+            } else {
+                d = arg_prepare_reg(arg);
+                gen_offs_sp(0x8d, d, struct_size);
+            }
+            struct_size += size;
+        } else {
+            if (is_sse_float(vtop->type.t)) {
+		if (tcc_state->nosse)
+		  tcc_error("SSE disabled");
+                gv(RC_XMM0); /* only use one float register */
+                if (arg >= REGN) {
+                    /* movq %xmm0, j*8(%rsp) */
+                    gen_offs_sp(0xd60f66, 0x100, arg*8);
+                } else {
+                    /* movaps %xmm0, %xmmN */
+                    o(0x280f);
+                    o(0xc0 + (arg << 3));
+                    d = arg_prepare_reg(arg);
+                    /* mov %xmm0, %rxx */
+                    o(0x66);
+                    orex(1,d,0, 0x7e0f);
+                    o(0xc0 + REG_VALUE(d));
+                }
+            } else {
+                if (bt == VT_STRUCT) {
+                    vtop->type.ref = NULL;
+                    vtop->type.t = size > 4 ? VT_LLONG : size > 2 ? VT_INT
+                        : size > 1 ? VT_SHORT : VT_BYTE;
+                }
+                
+                r = gv(RC_INT);
+                if (arg >= REGN) {
+                    gen_offs_sp(0x89, r, arg*8);
+                } else {
+                    d = arg_prepare_reg(arg);
+                    orex(1,d,r,0x89); /* mov */
+                    o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d));
+                }
+            }
+        }
+        vtop--;
+    }
+    save_regs(0);
+    
+    /* Copy R10 and R11 into RCX and RDX, respectively */
+    if (nb_args > 0) {
+        o(0xd1894c); /* mov %r10, %rcx */
+        if (nb_args > 1) {
+            o(0xda894c); /* mov %r11, %rdx */
+        }
+    }
+    
+    gcall_or_jmp(0);
+
+    if ((vtop->r & VT_SYM) && vtop->sym->v == TOK_alloca) {
+        /* need to add the "func_scratch" area after alloca */
+        o(0x0548), gen_le32(func_alloca), func_alloca = ind - 4;
+    }
+
+    /* other compilers don't clear the upper bits when returning char/short */
+    bt = vtop->type.ref->type.t & (VT_BTYPE | VT_UNSIGNED);
+    if (bt == (VT_BYTE | VT_UNSIGNED))
+        o(0xc0b60f);  /* movzbl %al, %eax */
+    else if (bt == VT_BYTE)
+        o(0xc0be0f); /* movsbl %al, %eax */
+    else if (bt == VT_SHORT)
+        o(0x98); /* cwtl */
+    else if (bt == (VT_SHORT | VT_UNSIGNED))
+        o(0xc0b70f);  /* movzbl %al, %eax */
+#if 0 /* handled in gen_cast() */
+    else if (bt == VT_INT)
+        o(0x9848); /* cltq */
+    else if (bt == (VT_INT | VT_UNSIGNED))
+        o(0xc089); /* mov %eax,%eax */
+#endif
+    vtop--;
+}
+
+
+#define FUNC_PROLOG_SIZE 11
+
+/* generate function prolog of type 't' */
+void gfunc_prolog(CType *func_type)
+{
+    int addr, reg_param_index, bt, size;
+    Sym *sym;
+    CType *type;
+
+    func_ret_sub = 0;
+    func_scratch = 0;
+    func_alloca = 0;
+    loc = 0;
+
+    addr = PTR_SIZE * 2;
+    ind += FUNC_PROLOG_SIZE;
+    func_sub_sp_offset = ind;
+    reg_param_index = 0;
+
+    sym = func_type->ref;
+
+    /* if the function returns a structure, then add an
+       implicit pointer parameter */
+    func_vt = sym->type;
+    func_var = (sym->f.func_type == FUNC_ELLIPSIS);
+    size = gfunc_arg_size(&func_vt);
+    if (!using_regs(size)) {
+        gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
+        func_vc = addr;
+        reg_param_index++;
+        addr += 8;
+    }
+
+    /* define parameters */
+    while ((sym = sym->next) != NULL) {
+        type = &sym->type;
+        bt = type->t & VT_BTYPE;
+        size = gfunc_arg_size(type);
+        if (!using_regs(size)) {
+            if (reg_param_index < REGN) {
+                gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
+            }
+            sym_push(sym->v & ~SYM_FIELD, type, VT_LLOCAL | VT_LVAL, addr);
+        } else {
+            if (reg_param_index < REGN) {
+                /* save arguments passed by register */
+                if ((bt == VT_FLOAT) || (bt == VT_DOUBLE)) {
+		    if (tcc_state->nosse)
+		      tcc_error("SSE disabled");
+                    o(0xd60f66); /* movq */
+                    gen_modrm(reg_param_index, VT_LOCAL, NULL, addr);
+                } else {
+                    gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
+                }
+            }
+            sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL, addr);
+        }
+        addr += 8;
+        reg_param_index++;
+    }
+
+    while (reg_param_index < REGN) {
+        if (func_type->ref->f.func_type == FUNC_ELLIPSIS) {
+            gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
+            addr += 8;
+        }
+        reg_param_index++;
+    }
+}
+
+/* generate function epilog */
+void gfunc_epilog(void)
+{
+    int v, saved_ind;
+
+    o(0xc9); /* leave */
+    if (func_ret_sub == 0) {
+        o(0xc3); /* ret */
+    } else {
+        o(0xc2); /* ret n */
+        g(func_ret_sub);
+        g(func_ret_sub >> 8);
+    }
+
+    saved_ind = ind;
+    ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
+    /* align local size to word & save local variables */
+    func_scratch = (func_scratch + 15) & -16;
+    v = (func_scratch + -loc + 15) & -16;
+
+    if (v >= 4096) {
+        Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
+        oad(0xb8, v); /* mov stacksize, %eax */
+        oad(0xe8, 0); /* call __chkstk, (does the stackframe too) */
+        greloca(cur_text_section, sym, ind-4, R_X86_64_PC32, -4);
+        o(0x90); /* fill for FUNC_PROLOG_SIZE = 11 bytes */
+    } else {
+        o(0xe5894855);  /* push %rbp, mov %rsp, %rbp */
+        o(0xec8148);  /* sub rsp, stacksize */
+        gen_le32(v);
+    }
+
+    /* add the "func_scratch" area after each alloca seen */
+    while (func_alloca) {
+        unsigned char *ptr = cur_text_section->data + func_alloca;
+        func_alloca = read32le(ptr);
+        write32le(ptr, func_scratch);
+    }
+
+    cur_text_section->data_offset = saved_ind;
+    pe_add_unwind_data(ind, saved_ind, v);
+    ind = cur_text_section->data_offset;
+}
+
+#else
+
+static void gadd_sp(int val)
+{
+    if (val == (char)val) {
+        o(0xc48348);
+        g(val);
+    } else {
+        oad(0xc48148, val); /* add $xxx, %rsp */
+    }
+}
+
+typedef enum X86_64_Mode {
+  x86_64_mode_none,
+  x86_64_mode_memory,
+  x86_64_mode_integer,
+  x86_64_mode_sse,
+  x86_64_mode_x87
+} X86_64_Mode;
+
+static X86_64_Mode classify_x86_64_merge(X86_64_Mode a, X86_64_Mode b)
+{
+    if (a == b)
+        return a;
+    else if (a == x86_64_mode_none)
+        return b;
+    else if (b == x86_64_mode_none)
+        return a;
+    else if ((a == x86_64_mode_memory) || (b == x86_64_mode_memory))
+        return x86_64_mode_memory;
+    else if ((a == x86_64_mode_integer) || (b == x86_64_mode_integer))
+        return x86_64_mode_integer;
+    else if ((a == x86_64_mode_x87) || (b == x86_64_mode_x87))
+        return x86_64_mode_memory;
+    else
+        return x86_64_mode_sse;
+}
+
+static X86_64_Mode classify_x86_64_inner(CType *ty)
+{
+    X86_64_Mode mode;
+    Sym *f;
+    
+    switch (ty->t & VT_BTYPE) {
+    case VT_VOID: return x86_64_mode_none;
+    
+    case VT_INT:
+    case VT_BYTE:
+    case VT_SHORT:
+    case VT_LLONG:
+    case VT_BOOL:
+    case VT_PTR:
+    case VT_FUNC:
+        return x86_64_mode_integer;
+    
+    case VT_FLOAT:
+    case VT_DOUBLE: return x86_64_mode_sse;
+    
+    case VT_LDOUBLE: return x86_64_mode_x87;
+      
+    case VT_STRUCT:
+        f = ty->ref;
+
+        mode = x86_64_mode_none;
+        for (f = f->next; f; f = f->next)
+            mode = classify_x86_64_merge(mode, classify_x86_64_inner(&f->type));
+        
+        return mode;
+    }
+    assert(0);
+    return 0;
+}
+
+static X86_64_Mode classify_x86_64_arg(CType *ty, CType *ret, int *psize, int *palign, int *reg_count)
+{
+    X86_64_Mode mode;
+    int size, align, ret_t = 0;
+    
+    if (ty->t & (VT_BITFIELD|VT_ARRAY)) {
+        *psize = 8;
+        *palign = 8;
+        *reg_count = 1;
+        ret_t = ty->t;
+        mode = x86_64_mode_integer;
+    } else {
+        size = type_size(ty, &align);
+        *psize = (size + 7) & ~7;
+        *palign = (align + 7) & ~7;
+    
+        if (size > 16) {
+            mode = x86_64_mode_memory;
+        } else {
+            mode = classify_x86_64_inner(ty);
+            switch (mode) {
+            case x86_64_mode_integer:
+                if (size > 8) {
+                    *reg_count = 2;
+                    ret_t = VT_QLONG;
+                } else {
+                    *reg_count = 1;
+                    ret_t = (size > 4) ? VT_LLONG : VT_INT;
+                }
+                break;
+                
+            case x86_64_mode_x87:
+                *reg_count = 1;
+                ret_t = VT_LDOUBLE;
+                break;
+
+            case x86_64_mode_sse:
+                if (size > 8) {
+                    *reg_count = 2;
+                    ret_t = VT_QFLOAT;
+                } else {
+                    *reg_count = 1;
+                    ret_t = (size > 4) ? VT_DOUBLE : VT_FLOAT;
+                }
+                break;
+            default: break; /* nothing to be done for x86_64_mode_memory and x86_64_mode_none*/
+            }
+        }
+    }
+    
+    if (ret) {
+        ret->ref = NULL;
+        ret->t = ret_t;
+    }
+    
+    return mode;
+}
+
+ST_FUNC int classify_x86_64_va_arg(CType *ty)
+{
+    /* This definition must be synced with stdarg.h */
+    enum __va_arg_type {
+        __va_gen_reg, __va_float_reg, __va_stack
+    };
+    int size, align, reg_count;
+    X86_64_Mode mode = classify_x86_64_arg(ty, NULL, &size, &align, &reg_count);
+    switch (mode) {
+    default: return __va_stack;
+    case x86_64_mode_integer: return __va_gen_reg;
+    case x86_64_mode_sse: return __va_float_reg;
+    }
+}
+
+/* Return the number of registers needed to return the struct, or 0 if
+   returning via struct pointer. */
+ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize)
+{
+    int size, align, reg_count;
+    *ret_align = 1; // Never have to re-align return values for x86-64
+    *regsize = 8;
+    return (classify_x86_64_arg(vt, ret, &size, &align, &reg_count) != x86_64_mode_memory);
+}
+
+#define REGN 6
+static const uint8_t arg_regs[REGN] = {
+    TREG_RDI, TREG_RSI, TREG_RDX, TREG_RCX, TREG_R8, TREG_R9
+};
+
+static int arg_prepare_reg(int idx) {
+  if (idx == 2 || idx == 3)
+      /* idx=2: r10, idx=3: r11 */
+      return idx + 8;
+  else
+      return arg_regs[idx];
+}
+
+/* Generate function call. The function address is pushed first, then
+   all the parameters in call order. This functions pops all the
+   parameters and the function address. */
+void gfunc_call(int nb_args)
+{
+    X86_64_Mode mode;
+    CType type;
+    int size, align, r, args_size, stack_adjust, i, reg_count;
+    int nb_reg_args = 0;
+    int nb_sse_args = 0;
+    int sse_reg, gen_reg;
+    char _onstack[nb_args], *onstack = _onstack;
+
+    /* calculate the number of integer/float register arguments, remember
+       arguments to be passed via stack (in onstack[]), and also remember
+       if we have to align the stack pointer to 16 (onstack[i] == 2).  Needs
+       to be done in a left-to-right pass over arguments.  */
+    stack_adjust = 0;
+    for(i = nb_args - 1; i >= 0; i--) {
+        mode = classify_x86_64_arg(&vtop[-i].type, NULL, &size, &align, &reg_count);
+        if (mode == x86_64_mode_sse && nb_sse_args + reg_count <= 8) {
+            nb_sse_args += reg_count;
+	    onstack[i] = 0;
+	} else if (mode == x86_64_mode_integer && nb_reg_args + reg_count <= REGN) {
+            nb_reg_args += reg_count;
+	    onstack[i] = 0;
+	} else if (mode == x86_64_mode_none) {
+	    onstack[i] = 0;
+	} else {
+	    if (align == 16 && (stack_adjust &= 15)) {
+		onstack[i] = 2;
+		stack_adjust = 0;
+	    } else
+	      onstack[i] = 1;
+	    stack_adjust += size;
+	}
+    }
+
+    if (nb_sse_args && tcc_state->nosse)
+      tcc_error("SSE disabled but floating point arguments passed");
+
+    /* fetch cpu flag before generating any code */
+    if (vtop >= vstack && (vtop->r & VT_VALMASK) == VT_CMP)
+      gv(RC_INT);
+
+    /* for struct arguments, we need to call memcpy and the function
+       call breaks register passing arguments we are preparing.
+       So, we process arguments which will be passed by stack first. */
+    gen_reg = nb_reg_args;
+    sse_reg = nb_sse_args;
+    args_size = 0;
+    stack_adjust &= 15;
+    for (i = 0; i < nb_args;) {
+	mode = classify_x86_64_arg(&vtop[-i].type, NULL, &size, &align, &reg_count);
+	if (!onstack[i]) {
+	    ++i;
+	    continue;
+	}
+        /* Possibly adjust stack to align SSE boundary.  We're processing
+	   args from right to left while allocating happens left to right
+	   (stack grows down), so the adjustment needs to happen _after_
+	   an argument that requires it.  */
+        if (stack_adjust) {
+	    o(0x50); /* push %rax; aka sub $8,%rsp */
+            args_size += 8;
+	    stack_adjust = 0;
+        }
+	if (onstack[i] == 2)
+	  stack_adjust = 1;
+
+	vrotb(i+1);
+
+	switch (vtop->type.t & VT_BTYPE) {
+	    case VT_STRUCT:
+		/* allocate the necessary size on stack */
+		o(0x48);
+		oad(0xec81, size); /* sub $xxx, %rsp */
+		/* generate structure store */
+		r = get_reg(RC_INT);
+		orex(1, r, 0, 0x89); /* mov %rsp, r */
+		o(0xe0 + REG_VALUE(r));
+		vset(&vtop->type, r | VT_LVAL, 0);
+		vswap();
+		vstore();
+		break;
+
+	    case VT_LDOUBLE:
+                gv(RC_ST0);
+                oad(0xec8148, size); /* sub $xxx, %rsp */
+                o(0x7cdb); /* fstpt 0(%rsp) */
+                g(0x24);
+                g(0x00);
+		break;
+
+	    case VT_FLOAT:
+	    case VT_DOUBLE:
+		assert(mode == x86_64_mode_sse);
+		r = gv(RC_FLOAT);
+		o(0x50); /* push $rax */
+		/* movq %xmmN, (%rsp) */
+		o(0xd60f66);
+		o(0x04 + REG_VALUE(r)*8);
+		o(0x24);
+		break;
+
+	    default:
+		assert(mode == x86_64_mode_integer);
+		/* simple type */
+		/* XXX: implicit cast ? */
+		r = gv(RC_INT);
+		orex(0,r,0,0x50 + REG_VALUE(r)); /* push r */
+		break;
+	}
+	args_size += size;
+
+	vpop();
+	--nb_args;
+	onstack++;
+    }
+
+    /* XXX This should be superfluous.  */
+    save_regs(0); /* save used temporary registers */
+
+    /* then, we prepare register passing arguments.
+       Note that we cannot set RDX and RCX in this loop because gv()
+       may break these temporary registers. Let's use R10 and R11
+       instead of them */
+    assert(gen_reg <= REGN);
+    assert(sse_reg <= 8);
+    for(i = 0; i < nb_args; i++) {
+        mode = classify_x86_64_arg(&vtop->type, &type, &size, &align, &reg_count);
+        /* Alter stack entry type so that gv() knows how to treat it */
+        vtop->type = type;
+        if (mode == x86_64_mode_sse) {
+            if (reg_count == 2) {
+                sse_reg -= 2;
+                gv(RC_FRET); /* Use pair load into xmm0 & xmm1 */
+                if (sse_reg) { /* avoid redundant movaps %xmm0, %xmm0 */
+                    /* movaps %xmm0, %xmmN */
+                    o(0x280f);
+                    o(0xc0 + (sse_reg << 3));
+                    /* movaps %xmm1, %xmmN */
+                    o(0x280f);
+                    o(0xc1 + ((sse_reg+1) << 3));
+                }
+            } else {
+                assert(reg_count == 1);
+                --sse_reg;
+                /* Load directly to register */
+                gv(RC_XMM0 << sse_reg);
+            }
+        } else if (mode == x86_64_mode_integer) {
+            /* simple type */
+            /* XXX: implicit cast ? */
+            int d;
+            gen_reg -= reg_count;
+            r = gv(RC_INT);
+            d = arg_prepare_reg(gen_reg);
+            orex(1,d,r,0x89); /* mov */
+            o(0xc0 + REG_VALUE(r) * 8 + REG_VALUE(d));
+            if (reg_count == 2) {
+                d = arg_prepare_reg(gen_reg+1);
+                orex(1,d,vtop->r2,0x89); /* mov */
+                o(0xc0 + REG_VALUE(vtop->r2) * 8 + REG_VALUE(d));
+            }
+        }
+        vtop--;
+    }
+    assert(gen_reg == 0);
+    assert(sse_reg == 0);
+
+    /* We shouldn't have many operands on the stack anymore, but the
+       call address itself is still there, and it might be in %eax
+       (or edx/ecx) currently, which the below writes would clobber.
+       So evict all remaining operands here.  */
+    save_regs(0);
+
+    /* Copy R10 and R11 into RDX and RCX, respectively */
+    if (nb_reg_args > 2) {
+        o(0xd2894c); /* mov %r10, %rdx */
+        if (nb_reg_args > 3) {
+            o(0xd9894c); /* mov %r11, %rcx */
+        }
+    }
+
+    if (vtop->type.ref->f.func_type != FUNC_NEW) /* implies FUNC_OLD or FUNC_ELLIPSIS */
+        oad(0xb8, nb_sse_args < 8 ? nb_sse_args : 8); /* mov nb_sse_args, %eax */
+    gcall_or_jmp(0);
+    if (args_size)
+        gadd_sp(args_size);
+    vtop--;
+}
+
+
+#define FUNC_PROLOG_SIZE 11
+
+static void push_arg_reg(int i) {
+    loc -= 8;
+    gen_modrm64(0x89, arg_regs[i], VT_LOCAL, NULL, loc);
+}
+
+/* generate function prolog of type 't' */
+void gfunc_prolog(CType *func_type)
+{
+    X86_64_Mode mode;
+    int i, addr, align, size, reg_count;
+    int param_addr = 0, reg_param_index, sse_param_index;
+    Sym *sym;
+    CType *type;
+
+    sym = func_type->ref;
+    addr = PTR_SIZE * 2;
+    loc = 0;
+    ind += FUNC_PROLOG_SIZE;
+    func_sub_sp_offset = ind;
+    func_ret_sub = 0;
+
+    if (sym->f.func_type == FUNC_ELLIPSIS) {
+        int seen_reg_num, seen_sse_num, seen_stack_size;
+        seen_reg_num = seen_sse_num = 0;
+        /* frame pointer and return address */
+        seen_stack_size = PTR_SIZE * 2;
+        /* count the number of seen parameters */
+        sym = func_type->ref;
+        while ((sym = sym->next) != NULL) {
+            type = &sym->type;
+            mode = classify_x86_64_arg(type, NULL, &size, &align, &reg_count);
+            switch (mode) {
+            default:
+            stack_arg:
+                seen_stack_size = ((seen_stack_size + align - 1) & -align) + size;
+                break;
+                
+            case x86_64_mode_integer:
+                if (seen_reg_num + reg_count > REGN)
+		    goto stack_arg;
+		seen_reg_num += reg_count;
+                break;
+                
+            case x86_64_mode_sse:
+                if (seen_sse_num + reg_count > 8)
+		    goto stack_arg;
+		seen_sse_num += reg_count;
+                break;
+            }
+        }
+
+        loc -= 16;
+        /* movl $0x????????, -0x10(%rbp) */
+        o(0xf045c7);
+        gen_le32(seen_reg_num * 8);
+        /* movl $0x????????, -0xc(%rbp) */
+        o(0xf445c7);
+        gen_le32(seen_sse_num * 16 + 48);
+        /* movl $0x????????, -0x8(%rbp) */
+        o(0xf845c7);
+        gen_le32(seen_stack_size);
+
+        /* save all register passing arguments */
+        for (i = 0; i < 8; i++) {
+            loc -= 16;
+	    if (!tcc_state->nosse) {
+		o(0xd60f66); /* movq */
+		gen_modrm(7 - i, VT_LOCAL, NULL, loc);
+	    }
+            /* movq $0, loc+8(%rbp) */
+            o(0x85c748);
+            gen_le32(loc + 8);
+            gen_le32(0);
+        }
+        for (i = 0; i < REGN; i++) {
+            push_arg_reg(REGN-1-i);
+        }
+    }
+
+    sym = func_type->ref;
+    reg_param_index = 0;
+    sse_param_index = 0;
+
+    /* if the function returns a structure, then add an
+       implicit pointer parameter */
+    func_vt = sym->type;
+    mode = classify_x86_64_arg(&func_vt, NULL, &size, &align, &reg_count);
+    if (mode == x86_64_mode_memory) {
+        push_arg_reg(reg_param_index);
+        func_vc = loc;
+        reg_param_index++;
+    }
+    /* define parameters */
+    while ((sym = sym->next) != NULL) {
+        type = &sym->type;
+        mode = classify_x86_64_arg(type, NULL, &size, &align, &reg_count);
+        switch (mode) {
+        case x86_64_mode_sse:
+	    if (tcc_state->nosse)
+	        tcc_error("SSE disabled but floating point arguments used");
+            if (sse_param_index + reg_count <= 8) {
+                /* save arguments passed by register */
+                loc -= reg_count * 8;
+                param_addr = loc;
+                for (i = 0; i < reg_count; ++i) {
+                    o(0xd60f66); /* movq */
+                    gen_modrm(sse_param_index, VT_LOCAL, NULL, param_addr + i*8);
+                    ++sse_param_index;
+                }
+            } else {
+                addr = (addr + align - 1) & -align;
+                param_addr = addr;
+                addr += size;
+            }
+            break;
+            
+        case x86_64_mode_memory:
+        case x86_64_mode_x87:
+            addr = (addr + align - 1) & -align;
+            param_addr = addr;
+            addr += size;
+            break;
+            
+        case x86_64_mode_integer: {
+            if (reg_param_index + reg_count <= REGN) {
+                /* save arguments passed by register */
+                loc -= reg_count * 8;
+                param_addr = loc;
+                for (i = 0; i < reg_count; ++i) {
+                    gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, param_addr + i*8);
+                    ++reg_param_index;
+                }
+            } else {
+                addr = (addr + align - 1) & -align;
+                param_addr = addr;
+                addr += size;
+            }
+            break;
+        }
+	default: break; /* nothing to be done for x86_64_mode_none */
+        }
+        sym_push(sym->v & ~SYM_FIELD, type,
+                 VT_LOCAL | VT_LVAL, param_addr);
+    }
+
+#ifdef CONFIG_TCC_BCHECK
+    /* leave some room for bound checking code */
+    if (tcc_state->do_bounds_check) {
+        func_bound_offset = lbounds_section->data_offset;
+        func_bound_ind = ind;
+        oad(0xb8, 0); /* lbound section pointer */
+	o(0xc78948);  /* mov  %rax,%rdi ## first arg in %rdi, this must be ptr */
+	oad(0xb8, 0); /* call to function */
+    }
+#endif
+}
+
+/* generate function epilog */
+void gfunc_epilog(void)
+{
+    int v, saved_ind;
+
+#ifdef CONFIG_TCC_BCHECK
+    if (tcc_state->do_bounds_check
+	&& func_bound_offset != lbounds_section->data_offset)
+    {
+        addr_t saved_ind;
+        addr_t *bounds_ptr;
+        Sym *sym_data;
+
+        /* add end of table info */
+        bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
+        *bounds_ptr = 0;
+
+        /* generate bound local allocation */
+        sym_data = get_sym_ref(&char_pointer_type, lbounds_section, 
+                               func_bound_offset, lbounds_section->data_offset);
+        saved_ind = ind;
+        ind = func_bound_ind;
+        greloca(cur_text_section, sym_data, ind + 1, R_X86_64_64, 0);
+        ind = ind + 5 + 3;
+        gen_static_call(TOK___bound_local_new);
+        ind = saved_ind;
+
+        /* generate bound check local freeing */
+        o(0x5250); /* save returned value, if any */
+        greloca(cur_text_section, sym_data, ind + 1, R_X86_64_64, 0);
+        oad(0xb8, 0); /* mov xxx, %rax */
+        o(0xc78948);  /* mov %rax,%rdi # first arg in %rdi, this must be ptr */
+        gen_static_call(TOK___bound_local_delete);
+        o(0x585a); /* restore returned value, if any */
+    }
+#endif
+    o(0xc9); /* leave */
+    if (func_ret_sub == 0) {
+        o(0xc3); /* ret */
+    } else {
+        o(0xc2); /* ret n */
+        g(func_ret_sub);
+        g(func_ret_sub >> 8);
+    }
+    /* align local size to word & save local variables */
+    v = (-loc + 15) & -16;
+    saved_ind = ind;
+    ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
+    o(0xe5894855);  /* push %rbp, mov %rsp, %rbp */
+    o(0xec8148);  /* sub rsp, stacksize */
+    gen_le32(v);
+    ind = saved_ind;
+}
+
+#endif /* not PE */
+
+/* generate a jump to a label */
+int gjmp(int t)
+{
+    return gjmp2(0xe9, t);
+}
+
+/* generate a jump to a fixed address */
+void gjmp_addr(int a)
+{
+    int r;
+    r = a - ind - 2;
+    if (r == (char)r) {
+        g(0xeb);
+        g(r);
+    } else {
+        oad(0xe9, a - ind - 5);
+    }
+}
+
+ST_FUNC void gtst_addr(int inv, int a)
+{
+    int v = vtop->r & VT_VALMASK;
+    if (v == VT_CMP) {
+	inv ^= (vtop--)->c.i;
+	a -= ind + 2;
+	if (a == (char)a) {
+	    g(inv - 32);
+	    g(a);
+	} else {
+	    g(0x0f);
+	    oad(inv - 16, a - 4);
+	}
+    } else if ((v & ~1) == VT_JMP) {
+	if ((v & 1) != inv) {
+	    gjmp_addr(a);
+	    gsym(vtop->c.i);
+	} else {
+	    gsym(vtop->c.i);
+	    o(0x05eb);
+	    gjmp_addr(a);
+	}
+	vtop--;
+    }
+}
+
+/* generate a test. set 'inv' to invert test. Stack entry is popped */
+ST_FUNC int gtst(int inv, int t)
+{
+    int v = vtop->r & VT_VALMASK;
+
+    if (nocode_wanted) {
+        ;
+    } else if (v == VT_CMP) {
+        /* fast case : can jump directly since flags are set */
+	if (vtop->c.i & 0x100)
+	  {
+	    /* This was a float compare.  If the parity flag is set
+	       the result was unordered.  For anything except != this
+	       means false and we don't jump (anding both conditions).
+	       For != this means true (oring both).
+	       Take care about inverting the test.  We need to jump
+	       to our target if the result was unordered and test wasn't NE,
+	       otherwise if unordered we don't want to jump.  */
+	    vtop->c.i &= ~0x100;
+            if (inv == (vtop->c.i == TOK_NE))
+	      o(0x067a);  /* jp +6 */
+	    else
+	      {
+	        g(0x0f);
+		t = gjmp2(0x8a, t); /* jp t */
+	      }
+	  }
+        g(0x0f);
+        t = gjmp2((vtop->c.i - 16) ^ inv, t);
+    } else if (v == VT_JMP || v == VT_JMPI) {
+        /* && or || optimization */
+        if ((v & 1) == inv) {
+            /* insert vtop->c jump list in t */
+            uint32_t n1, n = vtop->c.i;
+            if (n) {
+                while ((n1 = read32le(cur_text_section->data + n)))
+                    n = n1;
+                write32le(cur_text_section->data + n, t);
+                t = vtop->c.i;
+            }
+        } else {
+            t = gjmp(t);
+            gsym(vtop->c.i);
+        }
+    }
+    vtop--;
+    return t;
+}
+
+/* generate an integer binary operation */
+void gen_opi(int op)
+{
+    int r, fr, opc, c;
+    int ll, uu, cc;
+
+    ll = is64_type(vtop[-1].type.t);
+    uu = (vtop[-1].type.t & VT_UNSIGNED) != 0;
+    cc = (vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
+
+    switch(op) {
+    case '+':
+    case TOK_ADDC1: /* add with carry generation */
+        opc = 0;
+    gen_op8:
+        if (cc && (!ll || (int)vtop->c.i == vtop->c.i)) {
+            /* constant case */
+            vswap();
+            r = gv(RC_INT);
+            vswap();
+            c = vtop->c.i;
+            if (c == (char)c) {
+                /* XXX: generate inc and dec for smaller code ? */
+                orex(ll, r, 0, 0x83);
+                o(0xc0 | (opc << 3) | REG_VALUE(r));
+                g(c);
+            } else {
+                orex(ll, r, 0, 0x81);
+                oad(0xc0 | (opc << 3) | REG_VALUE(r), c);
+            }
+        } else {
+            gv2(RC_INT, RC_INT);
+            r = vtop[-1].r;
+            fr = vtop[0].r;
+            orex(ll, r, fr, (opc << 3) | 0x01);
+            o(0xc0 + REG_VALUE(r) + REG_VALUE(fr) * 8);
+        }
+        vtop--;
+        if (op >= TOK_ULT && op <= TOK_GT) {
+            vtop->r = VT_CMP;
+            vtop->c.i = op;
+        }
+        break;
+    case '-':
+    case TOK_SUBC1: /* sub with carry generation */
+        opc = 5;
+        goto gen_op8;
+    case TOK_ADDC2: /* add with carry use */
+        opc = 2;
+        goto gen_op8;
+    case TOK_SUBC2: /* sub with carry use */
+        opc = 3;
+        goto gen_op8;
+    case '&':
+        opc = 4;
+        goto gen_op8;
+    case '^':
+        opc = 6;
+        goto gen_op8;
+    case '|':
+        opc = 1;
+        goto gen_op8;
+    case '*':
+        gv2(RC_INT, RC_INT);
+        r = vtop[-1].r;
+        fr = vtop[0].r;
+        orex(ll, fr, r, 0xaf0f); /* imul fr, r */
+        o(0xc0 + REG_VALUE(fr) + REG_VALUE(r) * 8);
+        vtop--;
+        break;
+    case TOK_SHL:
+        opc = 4;
+        goto gen_shift;
+    case TOK_SHR:
+        opc = 5;
+        goto gen_shift;
+    case TOK_SAR:
+        opc = 7;
+    gen_shift:
+        opc = 0xc0 | (opc << 3);
+        if (cc) {
+            /* constant case */
+            vswap();
+            r = gv(RC_INT);
+            vswap();
+            orex(ll, r, 0, 0xc1); /* shl/shr/sar $xxx, r */
+            o(opc | REG_VALUE(r));
+            g(vtop->c.i & (ll ? 63 : 31));
+        } else {
+            /* we generate the shift in ecx */
+            gv2(RC_INT, RC_RCX);
+            r = vtop[-1].r;
+            orex(ll, r, 0, 0xd3); /* shl/shr/sar %cl, r */
+            o(opc | REG_VALUE(r));
+        }
+        vtop--;
+        break;
+    case TOK_UDIV:
+    case TOK_UMOD:
+        uu = 1;
+        goto divmod;
+    case '/':
+    case '%':
+    case TOK_PDIV:
+        uu = 0;
+    divmod:
+        /* first operand must be in eax */
+        /* XXX: need better constraint for second operand */
+        gv2(RC_RAX, RC_RCX);
+        r = vtop[-1].r;
+        fr = vtop[0].r;
+        vtop--;
+        save_reg(TREG_RDX);
+        orex(ll, 0, 0, uu ? 0xd231 : 0x99); /* xor %edx,%edx : cqto */
+        orex(ll, fr, 0, 0xf7); /* div fr, %eax */
+        o((uu ? 0xf0 : 0xf8) + REG_VALUE(fr));
+        if (op == '%' || op == TOK_UMOD)
+            r = TREG_RDX;
+        else
+            r = TREG_RAX;
+        vtop->r = r;
+        break;
+    default:
+        opc = 7;
+        goto gen_op8;
+    }
+}
+
+void gen_opl(int op)
+{
+    gen_opi(op);
+}
+
+/* generate a floating point operation 'v = t1 op t2' instruction. The
+   two operands are guaranteed to have the same floating point type */
+/* XXX: need to use ST1 too */
+void gen_opf(int op)
+{
+    int a, ft, fc, swapped, r;
+    int float_type =
+        (vtop->type.t & VT_BTYPE) == VT_LDOUBLE ? RC_ST0 : RC_FLOAT;
+
+    /* convert constants to memory references */
+    if ((vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+        vswap();
+        gv(float_type);
+        vswap();
+    }
+    if ((vtop[0].r & (VT_VALMASK | VT_LVAL)) == VT_CONST)
+        gv(float_type);
+
+    /* must put at least one value in the floating point register */
+    if ((vtop[-1].r & VT_LVAL) &&
+        (vtop[0].r & VT_LVAL)) {
+        vswap();
+        gv(float_type);
+        vswap();
+    }
+    swapped = 0;
+    /* swap the stack if needed so that t1 is the register and t2 is
+       the memory reference */
+    if (vtop[-1].r & VT_LVAL) {
+        vswap();
+        swapped = 1;
+    }
+    if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
+        if (op >= TOK_ULT && op <= TOK_GT) {
+            /* load on stack second operand */
+            load(TREG_ST0, vtop);
+            save_reg(TREG_RAX); /* eax is used by FP comparison code */
+            if (op == TOK_GE || op == TOK_GT)
+                swapped = !swapped;
+            else if (op == TOK_EQ || op == TOK_NE)
+                swapped = 0;
+            if (swapped)
+                o(0xc9d9); /* fxch %st(1) */
+            if (op == TOK_EQ || op == TOK_NE)
+                o(0xe9da); /* fucompp */
+            else
+                o(0xd9de); /* fcompp */
+            o(0xe0df); /* fnstsw %ax */
+            if (op == TOK_EQ) {
+                o(0x45e480); /* and $0x45, %ah */
+                o(0x40fC80); /* cmp $0x40, %ah */
+            } else if (op == TOK_NE) {
+                o(0x45e480); /* and $0x45, %ah */
+                o(0x40f480); /* xor $0x40, %ah */
+                op = TOK_NE;
+            } else if (op == TOK_GE || op == TOK_LE) {
+                o(0x05c4f6); /* test $0x05, %ah */
+                op = TOK_EQ;
+            } else {
+                o(0x45c4f6); /* test $0x45, %ah */
+                op = TOK_EQ;
+            }
+            vtop--;
+            vtop->r = VT_CMP;
+            vtop->c.i = op;
+        } else {
+            /* no memory reference possible for long double operations */
+            load(TREG_ST0, vtop);
+            swapped = !swapped;
+
+            switch(op) {
+            default:
+            case '+':
+                a = 0;
+                break;
+            case '-':
+                a = 4;
+                if (swapped)
+                    a++;
+                break;
+            case '*':
+                a = 1;
+                break;
+            case '/':
+                a = 6;
+                if (swapped)
+                    a++;
+                break;
+            }
+            ft = vtop->type.t;
+            fc = vtop->c.i;
+            o(0xde); /* fxxxp %st, %st(1) */
+            o(0xc1 + (a << 3));
+            vtop--;
+        }
+    } else {
+        if (op >= TOK_ULT && op <= TOK_GT) {
+            /* if saved lvalue, then we must reload it */
+            r = vtop->r;
+            fc = vtop->c.i;
+            if ((r & VT_VALMASK) == VT_LLOCAL) {
+                SValue v1;
+                r = get_reg(RC_INT);
+                v1.type.t = VT_PTR;
+                v1.r = VT_LOCAL | VT_LVAL;
+                v1.c.i = fc;
+                load(r, &v1);
+                fc = 0;
+            }
+
+            if (op == TOK_EQ || op == TOK_NE) {
+                swapped = 0;
+            } else {
+                if (op == TOK_LE || op == TOK_LT)
+                    swapped = !swapped;
+                if (op == TOK_LE || op == TOK_GE) {
+                    op = 0x93; /* setae */
+                } else {
+                    op = 0x97; /* seta */
+                }
+            }
+
+            if (swapped) {
+                gv(RC_FLOAT);
+                vswap();
+            }
+            assert(!(vtop[-1].r & VT_LVAL));
+            
+            if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
+                o(0x66);
+            if (op == TOK_EQ || op == TOK_NE)
+                o(0x2e0f); /* ucomisd */
+            else
+                o(0x2f0f); /* comisd */
+
+            if (vtop->r & VT_LVAL) {
+                gen_modrm(vtop[-1].r, r, vtop->sym, fc);
+            } else {
+                o(0xc0 + REG_VALUE(vtop[0].r) + REG_VALUE(vtop[-1].r)*8);
+            }
+
+            vtop--;
+            vtop->r = VT_CMP;
+            vtop->c.i = op | 0x100;
+        } else {
+            assert((vtop->type.t & VT_BTYPE) != VT_LDOUBLE);
+            switch(op) {
+            default:
+            case '+':
+                a = 0;
+                break;
+            case '-':
+                a = 4;
+                break;
+            case '*':
+                a = 1;
+                break;
+            case '/':
+                a = 6;
+                break;
+            }
+            ft = vtop->type.t;
+            fc = vtop->c.i;
+            assert((ft & VT_BTYPE) != VT_LDOUBLE);
+            
+            r = vtop->r;
+            /* if saved lvalue, then we must reload it */
+            if ((vtop->r & VT_VALMASK) == VT_LLOCAL) {
+                SValue v1;
+                r = get_reg(RC_INT);
+                v1.type.t = VT_PTR;
+                v1.r = VT_LOCAL | VT_LVAL;
+                v1.c.i = fc;
+                load(r, &v1);
+                fc = 0;
+            }
+            
+            assert(!(vtop[-1].r & VT_LVAL));
+            if (swapped) {
+                assert(vtop->r & VT_LVAL);
+                gv(RC_FLOAT);
+                vswap();
+            }
+            
+            if ((ft & VT_BTYPE) == VT_DOUBLE) {
+                o(0xf2);
+            } else {
+                o(0xf3);
+            }
+            o(0x0f);
+            o(0x58 + a);
+            
+            if (vtop->r & VT_LVAL) {
+                gen_modrm(vtop[-1].r, r, vtop->sym, fc);
+            } else {
+                o(0xc0 + REG_VALUE(vtop[0].r) + REG_VALUE(vtop[-1].r)*8);
+            }
+
+            vtop--;
+        }
+    }
+}
+
+/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
+   and 'long long' cases. */
+void gen_cvt_itof(int t)
+{
+    if ((t & VT_BTYPE) == VT_LDOUBLE) {
+        save_reg(TREG_ST0);
+        gv(RC_INT);
+        if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
+            /* signed long long to float/double/long double (unsigned case
+               is handled generically) */
+            o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
+            o(0x242cdf); /* fildll (%rsp) */
+            o(0x08c48348); /* add $8, %rsp */
+        } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
+                   (VT_INT | VT_UNSIGNED)) {
+            /* unsigned int to float/double/long double */
+            o(0x6a); /* push $0 */
+            g(0x00);
+            o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
+            o(0x242cdf); /* fildll (%rsp) */
+            o(0x10c48348); /* add $16, %rsp */
+        } else {
+            /* int to float/double/long double */
+            o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
+            o(0x2404db); /* fildl (%rsp) */
+            o(0x08c48348); /* add $8, %rsp */
+        }
+        vtop->r = TREG_ST0;
+    } else {
+        int r = get_reg(RC_FLOAT);
+        gv(RC_INT);
+        o(0xf2 + ((t & VT_BTYPE) == VT_FLOAT?1:0));
+        if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
+            (VT_INT | VT_UNSIGNED) ||
+            (vtop->type.t & VT_BTYPE) == VT_LLONG) {
+            o(0x48); /* REX */
+        }
+        o(0x2a0f);
+        o(0xc0 + (vtop->r & VT_VALMASK) + REG_VALUE(r)*8); /* cvtsi2sd */
+        vtop->r = r;
+    }
+}
+
+/* convert from one floating point type to another */
+void gen_cvt_ftof(int t)
+{
+    int ft, bt, tbt;
+
+    ft = vtop->type.t;
+    bt = ft & VT_BTYPE;
+    tbt = t & VT_BTYPE;
+    
+    if (bt == VT_FLOAT) {
+        gv(RC_FLOAT);
+        if (tbt == VT_DOUBLE) {
+            o(0x140f); /* unpcklps */
+            o(0xc0 + REG_VALUE(vtop->r)*9);
+            o(0x5a0f); /* cvtps2pd */
+            o(0xc0 + REG_VALUE(vtop->r)*9);
+        } else if (tbt == VT_LDOUBLE) {
+            save_reg(RC_ST0);
+            /* movss %xmm0,-0x10(%rsp) */
+            o(0x110ff3);
+            o(0x44 + REG_VALUE(vtop->r)*8);
+            o(0xf024);
+            o(0xf02444d9); /* flds -0x10(%rsp) */
+            vtop->r = TREG_ST0;
+        }
+    } else if (bt == VT_DOUBLE) {
+        gv(RC_FLOAT);
+        if (tbt == VT_FLOAT) {
+            o(0x140f66); /* unpcklpd */
+            o(0xc0 + REG_VALUE(vtop->r)*9);
+            o(0x5a0f66); /* cvtpd2ps */
+            o(0xc0 + REG_VALUE(vtop->r)*9);
+        } else if (tbt == VT_LDOUBLE) {
+            save_reg(RC_ST0);
+            /* movsd %xmm0,-0x10(%rsp) */
+            o(0x110ff2);
+            o(0x44 + REG_VALUE(vtop->r)*8);
+            o(0xf024);
+            o(0xf02444dd); /* fldl -0x10(%rsp) */
+            vtop->r = TREG_ST0;
+        }
+    } else {
+        int r;
+        gv(RC_ST0);
+        r = get_reg(RC_FLOAT);
+        if (tbt == VT_DOUBLE) {
+            o(0xf0245cdd); /* fstpl -0x10(%rsp) */
+            /* movsd -0x10(%rsp),%xmm0 */
+            o(0x100ff2);
+            o(0x44 + REG_VALUE(r)*8);
+            o(0xf024);
+            vtop->r = r;
+        } else if (tbt == VT_FLOAT) {
+            o(0xf0245cd9); /* fstps -0x10(%rsp) */
+            /* movss -0x10(%rsp),%xmm0 */
+            o(0x100ff3);
+            o(0x44 + REG_VALUE(r)*8);
+            o(0xf024);
+            vtop->r = r;
+        }
+    }
+}
+
+/* convert fp to int 't' type */
+void gen_cvt_ftoi(int t)
+{
+    int ft, bt, size, r;
+    ft = vtop->type.t;
+    bt = ft & VT_BTYPE;
+    if (bt == VT_LDOUBLE) {
+        gen_cvt_ftof(VT_DOUBLE);
+        bt = VT_DOUBLE;
+    }
+
+    gv(RC_FLOAT);
+    if (t != VT_INT)
+        size = 8;
+    else
+        size = 4;
+
+    r = get_reg(RC_INT);
+    if (bt == VT_FLOAT) {
+        o(0xf3);
+    } else if (bt == VT_DOUBLE) {
+        o(0xf2);
+    } else {
+        assert(0);
+    }
+    orex(size == 8, r, 0, 0x2c0f); /* cvttss2si or cvttsd2si */
+    o(0xc0 + REG_VALUE(vtop->r) + REG_VALUE(r)*8);
+    vtop->r = r;
+}
+
+/* computed goto support */
+void ggoto(void)
+{
+    gcall_or_jmp(1);
+    vtop--;
+}
+
+/* Save the stack pointer onto the stack and return the location of its address */
+ST_FUNC void gen_vla_sp_save(int addr) {
+    /* mov %rsp,addr(%rbp)*/
+    gen_modrm64(0x89, TREG_RSP, VT_LOCAL, NULL, addr);
+}
+
+/* Restore the SP from a location on the stack */
+ST_FUNC void gen_vla_sp_restore(int addr) {
+    gen_modrm64(0x8b, TREG_RSP, VT_LOCAL, NULL, addr);
+}
+
+#ifdef TCC_TARGET_PE
+/* Save result of gen_vla_alloc onto the stack */
+ST_FUNC void gen_vla_result(int addr) {
+    /* mov %rax,addr(%rbp)*/
+    gen_modrm64(0x89, TREG_RAX, VT_LOCAL, NULL, addr);
+}
+#endif
+
+/* Subtract from the stack pointer, and push the resulting value onto the stack */
+ST_FUNC void gen_vla_alloc(CType *type, int align) {
+#ifdef TCC_TARGET_PE
+    /* alloca does more than just adjust %rsp on Windows */
+    vpush_global_sym(&func_old_type, TOK_alloca);
+    vswap(); /* Move alloca ref past allocation size */
+    gfunc_call(1);
+#else
+    int r;
+    r = gv(RC_INT); /* allocation size */
+    /* sub r,%rsp */
+    o(0x2b48);
+    o(0xe0 | REG_VALUE(r));
+    /* We align to 16 bytes rather than align */
+    /* and ~15, %rsp */
+    o(0xf0e48348);
+    vpop();
+#endif
+}
+
+
+/* end of x86-64 code generator */
+/*************************************************************/
+#endif /* ! TARGET_DEFS_ONLY */
+/******************************************************/
Index: EcnlProtoTool/trunk/tcc-0.9.27/x86_64-link.c
===================================================================
--- EcnlProtoTool/trunk/tcc-0.9.27/x86_64-link.c	(revision 331)
+++ EcnlProtoTool/trunk/tcc-0.9.27/x86_64-link.c	(revision 331)
@@ -0,0 +1,298 @@
+#ifdef TARGET_DEFS_ONLY
+
+#define EM_TCC_TARGET EM_X86_64
+
+/* relocation type for 32 bit data relocation */
+#define R_DATA_32   R_X86_64_32S
+#define R_DATA_PTR  R_X86_64_64
+#define R_JMP_SLOT  R_X86_64_JUMP_SLOT
+#define R_GLOB_DAT  R_X86_64_GLOB_DAT
+#define R_COPY      R_X86_64_COPY
+#define R_RELATIVE  R_X86_64_RELATIVE
+
+#define R_NUM       R_X86_64_NUM
+
+#define ELF_START_ADDR 0x400000
+#define ELF_PAGE_SIZE  0x200000
+
+#define PCRELATIVE_DLLPLT 1
+#define RELOCATE_DLLPLT 1
+
+#else /* !TARGET_DEFS_ONLY */
+
+#include "tcc.h"
+
+/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
+   relocations, returns -1. */
+int code_reloc (int reloc_type)
+{
+    switch (reloc_type) {
+        case R_X86_64_32:
+        case R_X86_64_32S:
+        case R_X86_64_64:
+        case R_X86_64_GOTPC32:
+        case R_X86_64_GOTPC64:
+        case R_X86_64_GOTPCREL:
+        case R_X86_64_GOTPCRELX:
+        case R_X86_64_REX_GOTPCRELX:
+        case R_X86_64_GOTTPOFF:
+        case R_X86_64_GOT32:
+        case R_X86_64_GOT64:
+        case R_X86_64_GLOB_DAT:
+        case R_X86_64_COPY:
+        case R_X86_64_RELATIVE:
+        case R_X86_64_GOTOFF64:
+            return 0;
+
+        case R_X86_64_PC32:
+        case R_X86_64_PC64:
+        case R_X86_64_PLT32:
+        case R_X86_64_PLTOFF64:
+        case R_X86_64_JUMP_SLOT:
+            return 1;
+    }
+
+    tcc_error ("Unknown relocation type: %d", reloc_type);
+    return -1;
+}
+
+/* Returns an enumerator to describe whether and when the relocation needs a
+   GOT and/or PLT entry to be created. See tcc.h for a description of the
+   different values. */
+int gotplt_entry_type (int reloc_type)
+{
+    switch (reloc_type) {
+        case R_X86_64_GLOB_DAT:
+        case R_X86_64_JUMP_SLOT:
+        case R_X86_64_COPY:
+        case R_X86_64_RELATIVE:
+            return NO_GOTPLT_ENTRY;
+
+	/* The following relocs wouldn't normally need GOT or PLT
+	   slots, but we need them for simplicity in the link
+	   editor part.  See our caller for comments.  */
+        case R_X86_64_32:
+        case R_X86_64_32S:
+        case R_X86_64_64:
+        case R_X86_64_PC32:
+        case R_X86_64_PC64:
+            return AUTO_GOTPLT_ENTRY;
+
+        case R_X86_64_GOTTPOFF:
+            return BUILD_GOT_ONLY;
+
+        case R_X86_64_GOT32:
+        case R_X86_64_GOT64:
+        case R_X86_64_GOTPC32:
+        case R_X86_64_GOTPC64:
+        case R_X86_64_GOTOFF64:
+        case R_X86_64_GOTPCREL:
+        case R_X86_64_GOTPCRELX:
+        case R_X86_64_REX_GOTPCRELX:
+        case R_X86_64_PLT32:
+        case R_X86_64_PLTOFF64:
+            return ALWAYS_GOTPLT_ENTRY;
+    }
+
+    tcc_error ("Unknown relocation type: %d", reloc_type);
+    return -1;
+}
+
+ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
+{
+    Section *plt = s1->plt;
+    uint8_t *p;
+    int modrm;
+    unsigned plt_offset, relofs;
+
+    modrm = 0x25;
+
+    /* empty PLT: create PLT0 entry that pushes the library identifier
+       (GOT + PTR_SIZE) and jumps to ld.so resolution routine
+       (GOT + 2 * PTR_SIZE) */
+    if (plt->data_offset == 0) {
+        p = section_ptr_add(plt, 16);
+        p[0] = 0xff; /* pushl got + PTR_SIZE */
+        p[1] = modrm + 0x10;
+        write32le(p + 2, PTR_SIZE);
+        p[6] = 0xff; /* jmp *(got + PTR_SIZE * 2) */
+        p[7] = modrm;
+        write32le(p + 8, PTR_SIZE * 2);
+    }
+    plt_offset = plt->data_offset;
+
+    /* The PLT slot refers to the relocation entry it needs via offset.
+       The reloc entry is created below, so its offset is the current
+       data_offset */
+    relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
+
+    /* Jump to GOT entry where ld.so initially put the address of ip + 4 */
+    p = section_ptr_add(plt, 16);
+    p[0] = 0xff; /* jmp *(got + x) */
+    p[1] = modrm;
+    write32le(p + 2, got_offset);
+    p[6] = 0x68; /* push $xxx */
+    /* On x86-64, the relocation is referred to by _index_ */
+    write32le(p + 7, relofs / sizeof (ElfW_Rel));
+    p[11] = 0xe9; /* jmp plt_start */
+    write32le(p + 12, -(plt->data_offset));
+    return plt_offset;
+}
+
+/* relocate the PLT: compute addresses and offsets in the PLT now that final
+   address for PLT and GOT are known (see fill_program_header) */
+ST_FUNC void relocate_plt(TCCState *s1)
+{
+    uint8_t *p, *p_end;
+
+    if (!s1->plt)
+      return;
+
+    p = s1->plt->data;
+    p_end = p + s1->plt->data_offset;
+
+    if (p < p_end) {
+        int x = s1->got->sh_addr - s1->plt->sh_addr - 6;
+        add32le(p + 2, x);
+        add32le(p + 8, x - 6);
+        p += 16;
+        while (p < p_end) {
+            add32le(p + 2, x + s1->plt->data - p);
+            p += 16;
+        }
+    }
+}
+
+static ElfW_Rel *qrel; /* ptr to next reloc entry reused */
+
+void relocate_init(Section *sr)
+{
+    qrel = (ElfW_Rel *) sr->data;
+}
+
+void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
+{
+    int sym_index, esym_index;
+
+    sym_index = ELFW(R_SYM)(rel->r_info);
+
+    switch (type) {
+        case R_X86_64_64:
+            if (s1->output_type == TCC_OUTPUT_DLL) {
+                esym_index = s1->sym_attrs[sym_index].dyn_index;
+                qrel->r_offset = rel->r_offset;
+                if (esym_index) {
+                    qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_64);
+                    qrel->r_addend = rel->r_addend;
+                    qrel++;
+                    break;
+                } else {
+                    qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
+                    qrel->r_addend = read64le(ptr) + val;
+                    qrel++;
+                }
+            }
+            add64le(ptr, val);
+            break;
+        case R_X86_64_32:
+        case R_X86_64_32S:
+            if (s1->output_type == TCC_OUTPUT_DLL) {
+                /* XXX: this logic may depend on TCC's codegen
+                   now TCC uses R_X86_64_32 even for a 64bit pointer */
+                qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
+                /* Use sign extension! */
+                qrel->r_addend = (int)read32le(ptr) + val;
+                qrel++;
+            }
+            add32le(ptr, val);
+            break;
+
+        case R_X86_64_PC32:
+            if (s1->output_type == TCC_OUTPUT_DLL) {
+                /* DLL relocation */
+                esym_index = s1->sym_attrs[sym_index].dyn_index;
+                if (esym_index) {
+                    qrel->r_offset = rel->r_offset;
+                    qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC32);
+                    /* Use sign extension! */
+                    qrel->r_addend = (int)read32le(ptr) + rel->r_addend;
+                    qrel++;
+                    break;
+                }
+            }
+            goto plt32pc32;
+
+        case R_X86_64_PLT32:
+            /* fallthrough: val already holds the PLT slot address */
+
+        plt32pc32:
+        {
+            long long diff;
+            diff = (long long)val - addr;
+            if (diff < -2147483648LL || diff > 2147483647LL) {
+                tcc_error("internal error: relocation failed");
+            }
+            add32le(ptr, diff);
+        }
+            break;
+
+        case R_X86_64_PLTOFF64:
+            add64le(ptr, val - s1->got->sh_addr + rel->r_addend);
+            break;
+
+        case R_X86_64_PC64:
+            if (s1->output_type == TCC_OUTPUT_DLL) {
+                /* DLL relocation */
+                esym_index = s1->sym_attrs[sym_index].dyn_index;
+                if (esym_index) {
+                    qrel->r_offset = rel->r_offset;
+                    qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_PC64);
+                    qrel->r_addend = read64le(ptr) + rel->r_addend;
+                    qrel++;
+                    break;
+                }
+            }
+            add64le(ptr, val - addr);
+            break;
+
+        case R_X86_64_GLOB_DAT:
+        case R_X86_64_JUMP_SLOT:
+            /* They don't need addend */
+            write64le(ptr, val - rel->r_addend);
+            break;
+        case R_X86_64_GOTPCREL:
+        case R_X86_64_GOTPCRELX:
+        case R_X86_64_REX_GOTPCRELX:
+            add32le(ptr, s1->got->sh_addr - addr +
+                         s1->sym_attrs[sym_index].got_offset - 4);
+            break;
+        case R_X86_64_GOTPC32:
+            add32le(ptr, s1->got->sh_addr - addr + rel->r_addend);
+            break;
+        case R_X86_64_GOTPC64:
+            add64le(ptr, s1->got->sh_addr - addr + rel->r_addend);
+            break;
+        case R_X86_64_GOTTPOFF:
+            add32le(ptr, val - s1->got->sh_addr);
+            break;
+        case R_X86_64_GOT32:
+            /* we load the got offset */
+            add32le(ptr, s1->sym_attrs[sym_index].got_offset);
+            break;
+        case R_X86_64_GOT64:
+            /* we load the got offset */
+            add64le(ptr, s1->sym_attrs[sym_index].got_offset);
+            break;
+        case R_X86_64_GOTOFF64:
+            add64le(ptr, val - s1->got->sh_addr);
+            break;
+        case R_X86_64_RELATIVE:
+#ifdef TCC_TARGET_PE
+            add32le(ptr, val - s1->pe_imagebase);
+#endif
+            /* do nothing */
+            break;
+    }
+}
+
+#endif /* !TARGET_DEFS_ONLY */
Index: EcnlProtoTool/trunk/zlib-1.2.11/.cproject
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/.cproject	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/.cproject	(revision 331)
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+	<storageModule moduleId="org.eclipse.cdt.core.settings">
+		<cconfiguration id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.1394633384">
+			<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.1394633384" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+				<externalSettings/>
+				<extensions>
+					<extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+					<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+					<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+				</extensions>
+			</storageModule>
+			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+				<configuration artifactExtension="a" artifactName="zlib" buildArtefactType="com.renesas.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=com.renesas.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf *.lst *.lis *.lpp *.map" description="" id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.1394633384" name="Debug" parent="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id">
+					<folderInfo id="com.renesas.cdt.rz.libraryProject.base.debug.configuration.Id.1394633384." name="/" resourcePath="">
+						<toolChain id="com.renesas.cdt.library.rz.debug.win32.toolchain.Id.576269587" name="KPIT GNUARM-NONE-EABI Toolchain" superClass="com.renesas.cdt.library.rz.debug.win32.toolchain.Id">
+							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.PE" id="com.renesas.cdt.rz.libraryProject.debug.win32.targetplatform.Id.1600485890" name="Target Platform" osList="win32,linux" superClass="com.renesas.cdt.rz.libraryProject.debug.win32.targetplatform.Id"/>
+							<builder buildPath="${workspace_loc:/zlib-1.2.11}/Debug" id="com.renesas.cdt.rz.library.project.debug.win32.builder.Id.802186889" incrementalBuildTarget="libz.a" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Builder" parallelBuildOn="false" superClass="com.renesas.cdt.rz.library.project.debug.win32.builder.Id"/>
+							<tool id="com.renesas.cdt.rz.libraryProject.debug.win32.tool.compiler.Id.38561871" name="Compiler" superClass="com.renesas.cdt.rz.libraryProject.debug.win32.tool.compiler.Id">
+								<option defaultValue="true" id="com.renesas.cdt.core.Compiler.option.misc2.1224531617" name="æ¨æºã·ã¹ãã ã»ãã£ã¬ã¯ããªã¼ã§ãããã¼ã»ãã¡ã¤ã«ãæ¤ç´¢ããªã (-nostdinc)" superClass="com.renesas.cdt.core.Compiler.option.misc2" valueType="boolean"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.dataEndian.663278525" name="ã¨ã³ãã£ã¢ã³" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.dataEndian" value="Little-endian" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.instructionset.1311682685" name="å½ä»¤ã»ãã" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.instructionset" value="ARM" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.interworking.589113295" name="ã¤ã³ã¿ã¼ã»ã¯ã¼ã­ã³ã°" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.interworking" value="true" valueType="boolean"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.targetfpu.1856553814" name="ã¿ã¼ã²ãã FPU (-mfpu)" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.targetfpu" value="vfp" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.floatingpointabi.160373145" name="æµ®åå°æ°ç¹ ABI (-mfloat-abi=name)" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.floatingpointabi" value="Hard" valueType="enumerated"/>
+								<option id="com.renesas.cdt.core.Compiler.option.warnStackSize.153634591" name="Warn if stack size exceeds the limit (-Wstack-usage) (H')" superClass="com.renesas.cdt.core.Compiler.option.warnStackSize" value="100" valueType="string"/>
+								<option id="com.renesas.cdt.core.Compiler.option.CPUSeries.581941057" name="CPU ã·ãªã¼ãº" superClass="com.renesas.cdt.core.Compiler.option.CPUSeries" value="RZ/A" valueType="string"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.architecture.110958081" name="ã¢ã¼ã­ãã¯ãã£ã¼" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.architecture" value="armv7-a" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Compiler.option.library.cpuType.982269202" name="CPU ã¿ã¤ã" superClass="com.renesas.cdt.rz.Debug.Compiler.option.library.cpuType" value="cortex-a9" valueType="enumerated"/>
+								<inputType id="%Base.Compiler.C.InputType.Id.57252171" name="C å
+¥å" superClass="%Base.Compiler.C.InputType.Id"/>
+								<inputType id="Base.Compiler.CPP.InputType.Id.435331880" name="C++ å
+¥å" superClass="Base.Compiler.CPP.InputType.Id"/>
+							</tool>
+							<tool id="com.renesas.cdt.library.rz.Debug.win32.tool.assembler.Id.449665457" name="Assembler" superClass="com.renesas.cdt.library.rz.Debug.win32.tool.assembler.Id">
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.dataEndian.1369824178" name="ã¨ã³ãã£ã¢ã³" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.dataEndian" value="Little-endian" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.instructionset.1295902223" name="å½ä»¤ã»ãã" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.instructionset" value="ARM" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.targetfpu.67996398" name="ã¿ã¼ã²ãã FPU (-mfpu)" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.targetfpu" value="vfp" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.floatingpointabi.531978731" name="æµ®åå°æ°ç¹ ABI (-mfloat-abi=name)" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.floatingpointabi" value="Hard" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.architecture.1609188325" name="ã¢ã¼ã­ãã¯ãã£ã¼" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.architecture" value="armv7-a" valueType="enumerated"/>
+								<option id="com.renesas.cdt.rz.Debug.Assembler.option.library.cpuType.1165319147" name="CPU ã¿ã¤ã" superClass="com.renesas.cdt.rz.Debug.Assembler.option.library.cpuType" value="cortex-a9" valueType="enumerated"/>
+								<inputType id="%Base.Assembler.inputType.Id.2118865368" name="ã¢ã»ã³ãã©ã¼å
+¥åã¿ã¤ã" superClass="%Base.Assembler.inputType.Id"/>
+							</tool>
+							<tool id="com.renesas.cdt.library.rz.debug.win32.tool.archive.Id.421650300" name="Archive Generator" superClass="com.renesas.cdt.library.rz.debug.win32.tool.archive.Id"/>
+						</toolChain>
+					</folderInfo>
+					<sourceEntries>
+						<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name=""/>
+					</sourceEntries>
+				</configuration>
+			</storageModule>
+			<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+		</cconfiguration>
+	</storageModule>
+	<storageModule moduleId="cdtBuildSystem" version="4.0.0">
+		<project id="zlib.com.renesas.cdt.rz.library.projectType.Id.1380443888" name="Static Library (Renesas)" projectType="com.renesas.cdt.rz.library.projectType.Id"/>
+	</storageModule>
+	<storageModule moduleId="scannerConfiguration">
+		<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+	</storageModule>
+	<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+	<storageModule moduleId="refreshScope" versionNumber="2">
+		<configuration configurationName="Debug">
+			<resource resourceType="PROJECT" workspacePath="/zlib"/>
+		</configuration>
+	</storageModule>
+</cproject>
Index: EcnlProtoTool/trunk/zlib-1.2.11/.info
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/.info	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/.info	(revision 331)
@@ -0,0 +1,7 @@
+TOOL_CHAIN=KPIT GNUARM-NONE-EABI Toolchain
+VERSION=v16.01
+TC_INSTALL=C:\Program Files (x86)\KPIT\GNUARM-NONEv16.01-EABI\arm-none-eabi\arm-none-eabi\
+GCC_STRING=5.2-GNUARM-NONE_v16.01
+VERSION_IDE=
+E2STUDIO_VERSION=5.4.0.018
+ACTIVE_CONFIGURATION=Debug
Index: EcnlProtoTool/trunk/zlib-1.2.11/.project
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/.project	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/.project	(revision 331)
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>zlib</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>com.renesas.cdt.core.genmakebuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>com.renesas.cdt.core.kpitcnature</nature>
+		<nature>com.renesas.cdt.core.kpitccnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+	</natures>
+</projectDescription>
Index: EcnlProtoTool/trunk/zlib-1.2.11/CMakeLists.txt
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/CMakeLists.txt	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/CMakeLists.txt	(revision 331)
@@ -0,0 +1,249 @@
+cmake_minimum_required(VERSION 2.4.4)
+set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
+
+project(zlib C)
+
+set(VERSION "1.2.11")
+
+option(ASM686 "Enable building i686 assembly implementation")
+option(AMD64 "Enable building amd64 assembly implementation")
+
+set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables")
+set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries")
+set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers")
+set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages")
+set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files")
+
+include(CheckTypeSize)
+include(CheckFunctionExists)
+include(CheckIncludeFile)
+include(CheckCSourceCompiles)
+enable_testing()
+
+check_include_file(sys/types.h HAVE_SYS_TYPES_H)
+check_include_file(stdint.h    HAVE_STDINT_H)
+check_include_file(stddef.h    HAVE_STDDEF_H)
+
+#
+# Check to see if we have large file support
+#
+set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1)
+# We add these other definitions here because CheckTypeSize.cmake
+# in CMake 2.4.x does not automatically do so and we want
+# compatibility with CMake 2.4.x.
+if(HAVE_SYS_TYPES_H)
+    list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H)
+endif()
+if(HAVE_STDINT_H)
+    list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H)
+endif()
+if(HAVE_STDDEF_H)
+    list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H)
+endif()
+check_type_size(off64_t OFF64_T)
+if(HAVE_OFF64_T)
+   add_definitions(-D_LARGEFILE64_SOURCE=1)
+endif()
+set(CMAKE_REQUIRED_DEFINITIONS) # clear variable
+
+#
+# Check for fseeko
+#
+check_function_exists(fseeko HAVE_FSEEKO)
+if(NOT HAVE_FSEEKO)
+    add_definitions(-DNO_FSEEKO)
+endif()
+
+#
+# Check for unistd.h
+#
+check_include_file(unistd.h Z_HAVE_UNISTD_H)
+
+if(MSVC)
+    set(CMAKE_DEBUG_POSTFIX "d")
+    add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
+    add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
+    include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+endif()
+
+if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
+    # If we're doing an out of source build and the user has a zconf.h
+    # in their source tree...
+    if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h)
+        message(STATUS "Renaming")
+        message(STATUS "    ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h")
+        message(STATUS "to 'zconf.h.included' because this file is included with zlib")
+        message(STATUS "but CMake generates it automatically in the build directory.")
+        file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.included)
+  endif()
+endif()
+
+set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc)
+configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein
+		${ZLIB_PC} @ONLY)
+configure_file(	${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein
+		${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY)
+include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR})
+
+
+#============================================================================
+# zlib
+#============================================================================
+
+set(ZLIB_PUBLIC_HDRS
+    ${CMAKE_CURRENT_BINARY_DIR}/zconf.h
+    zlib.h
+)
+set(ZLIB_PRIVATE_HDRS
+    crc32.h
+    deflate.h
+    gzguts.h
+    inffast.h
+    inffixed.h
+    inflate.h
+    inftrees.h
+    trees.h
+    zutil.h
+)
+set(ZLIB_SRCS
+    adler32.c
+    compress.c
+    crc32.c
+    deflate.c
+    gzclose.c
+    gzlib.c
+    gzread.c
+    gzwrite.c
+    inflate.c
+    infback.c
+    inftrees.c
+    inffast.c
+    trees.c
+    uncompr.c
+    zutil.c
+)
+
+if(NOT MINGW)
+    set(ZLIB_DLL_SRCS
+        win32/zlib1.rc # If present will override custom build rule below.
+    )
+endif()
+
+if(CMAKE_COMPILER_IS_GNUCC)
+    if(ASM686)
+        set(ZLIB_ASMS contrib/asm686/match.S)
+    elseif (AMD64)
+        set(ZLIB_ASMS contrib/amd64/amd64-match.S)
+    endif ()
+
+	if(ZLIB_ASMS)
+		add_definitions(-DASMV)
+		set_source_files_properties(${ZLIB_ASMS} PROPERTIES LANGUAGE C COMPILE_FLAGS -DNO_UNDERLINE)
+	endif()
+endif()
+
+if(MSVC)
+    if(ASM686)
+		ENABLE_LANGUAGE(ASM_MASM)
+        set(ZLIB_ASMS
+			contrib/masmx86/inffas32.asm
+			contrib/masmx86/match686.asm
+		)
+    elseif (AMD64)
+		ENABLE_LANGUAGE(ASM_MASM)
+        set(ZLIB_ASMS
+			contrib/masmx64/gvmat64.asm
+			contrib/masmx64/inffasx64.asm
+		)
+    endif()
+
+	if(ZLIB_ASMS)
+		add_definitions(-DASMV -DASMINF)
+	endif()
+endif()
+
+# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION
+file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents)
+string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*"
+    "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents})
+
+if(MINGW)
+    # This gets us DLL resource information when compiling on MinGW.
+    if(NOT CMAKE_RC_COMPILER)
+        set(CMAKE_RC_COMPILER windres.exe)
+    endif()
+
+    add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj
+                       COMMAND ${CMAKE_RC_COMPILER}
+                            -D GCC_WINDRES
+                            -I ${CMAKE_CURRENT_SOURCE_DIR}
+                            -I ${CMAKE_CURRENT_BINARY_DIR}
+                            -o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj
+                            -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc)
+    set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj)
+endif(MINGW)
+
+add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
+add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
+set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL)
+set_target_properties(zlib PROPERTIES SOVERSION 1)
+
+if(NOT CYGWIN)
+    # This property causes shared libraries on Linux to have the full version
+    # encoded into their final filename.  We disable this on Cygwin because
+    # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll
+    # seems to be the default.
+    #
+    # This has no effect with MSVC, on that platform the version info for
+    # the DLL comes from the resource file win32/zlib1.rc
+    set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION})
+endif()
+
+if(UNIX)
+    # On unix-like platforms the library is almost always called libz
+   set_target_properties(zlib zlibstatic PROPERTIES OUTPUT_NAME z)
+   if(NOT APPLE)
+     set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"")
+   endif()
+elseif(BUILD_SHARED_LIBS AND WIN32)
+    # Creates zlib1.dll when building shared library version
+    set_target_properties(zlib PROPERTIES SUFFIX "1.dll")
+endif()
+
+if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL )
+    install(TARGETS zlib zlibstatic
+        RUNTIME DESTINATION "${INSTALL_BIN_DIR}"
+        ARCHIVE DESTINATION "${INSTALL_LIB_DIR}"
+        LIBRARY DESTINATION "${INSTALL_LIB_DIR}" )
+endif()
+if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL )
+    install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION "${INSTALL_INC_DIR}")
+endif()
+if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
+    install(FILES zlib.3 DESTINATION "${INSTALL_MAN_DIR}/man3")
+endif()
+if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
+    install(FILES ${ZLIB_PC} DESTINATION "${INSTALL_PKGCONFIG_DIR}")
+endif()
+
+#============================================================================
+# Example binaries
+#============================================================================
+
+add_executable(example test/example.c)
+target_link_libraries(example zlib)
+add_test(example example)
+
+add_executable(minigzip test/minigzip.c)
+target_link_libraries(minigzip zlib)
+
+if(HAVE_OFF64_T)
+    add_executable(example64 test/example.c)
+    target_link_libraries(example64 zlib)
+    set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64")
+    add_test(example64 example64)
+
+    add_executable(minigzip64 test/minigzip.c)
+    target_link_libraries(minigzip64 zlib)
+    set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64")
+endif()
Index: EcnlProtoTool/trunk/zlib-1.2.11/ChangeLog
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/ChangeLog	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/ChangeLog	(revision 331)
@@ -0,0 +1,1515 @@
+
+                ChangeLog file for zlib
+
+Changes in 1.2.11 (15 Jan 2017)
+- Fix deflate stored bug when pulling last block from window
+- Permit immediate deflateParams changes before any deflate input
+
+Changes in 1.2.10 (2 Jan 2017)
+- Avoid warnings on snprintf() return value
+- Fix bug in deflate_stored() for zero-length input
+- Fix bug in gzwrite.c that produced corrupt gzip files
+- Remove files to be installed before copying them in Makefile.in
+- Add warnings when compiling with assembler code
+
+Changes in 1.2.9 (31 Dec 2016)
+- Fix contrib/minizip to permit unzipping with desktop API [Zouzou]
+- Improve contrib/blast to return unused bytes
+- Assure that gzoffset() is correct when appending
+- Improve compress() and uncompress() to support large lengths
+- Fix bug in test/example.c where error code not saved
+- Remedy Coverity warning [Randers-Pehrson]
+- Improve speed of gzprintf() in transparent mode
+- Fix inflateInit2() bug when windowBits is 16 or 32
+- Change DEBUG macro to ZLIB_DEBUG
+- Avoid uninitialized access by gzclose_w()
+- Allow building zlib outside of the source directory
+- Fix bug that accepted invalid zlib header when windowBits is zero
+- Fix gzseek() problem on MinGW due to buggy _lseeki64 there
+- Loop on write() calls in gzwrite.c in case of non-blocking I/O
+- Add --warn (-w) option to ./configure for more compiler warnings
+- Reject a window size of 256 bytes if not using the zlib wrapper
+- Fix bug when level 0 used with Z_HUFFMAN or Z_RLE
+- Add --debug (-d) option to ./configure to define ZLIB_DEBUG
+- Fix bugs in creating a very large gzip header
+- Add uncompress2() function, which returns the input size used
+- Assure that deflateParams() will not switch functions mid-block
+- Dramatically speed up deflation for level 0 (storing)
+- Add gzfread(), duplicating the interface of fread()
+- Add gzfwrite(), duplicating the interface of fwrite()
+- Add deflateGetDictionary() function
+- Use snprintf() for later versions of Microsoft C
+- Fix *Init macros to use z_ prefix when requested
+- Replace as400 with os400 for OS/400 support [Monnerat]
+- Add crc32_z() and adler32_z() functions with size_t lengths
+- Update Visual Studio project files [AraHaan]
+
+Changes in 1.2.8 (28 Apr 2013)
+- Update contrib/minizip/iowin32.c for Windows RT [Vollant]
+- Do not force Z_CONST for C++
+- Clean up contrib/vstudio [RoÃ]
+- Correct spelling error in zlib.h
+- Fix mixed line endings in contrib/vstudio
+
+Changes in 1.2.7.3 (13 Apr 2013)
+- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc
+
+Changes in 1.2.7.2 (13 Apr 2013)
+- Change check for a four-byte type back to hexadecimal
+- Fix typo in win32/Makefile.msc
+- Add casts in gzwrite.c for pointer differences
+
+Changes in 1.2.7.1 (24 Mar 2013)
+- Replace use of unsafe string functions with snprintf if available
+- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink]
+- Fix gzgetc undefine when Z_PREFIX set [Turk]
+- Eliminate use of mktemp in Makefile (not always available)
+- Fix bug in 'F' mode for gzopen()
+- Add inflateGetDictionary() function
+- Correct comment in deflate.h
+- Use _snprintf for snprintf in Microsoft C
+- On Darwin, only use /usr/bin/libtool if libtool is not Apple
+- Delete "--version" file if created by "ar --version" [Richard G.]
+- Fix configure check for veracity of compiler error return codes
+- Fix CMake compilation of static lib for MSVC2010 x64
+- Remove unused variable in infback9.c
+- Fix argument checks in gzlog_compress() and gzlog_write()
+- Clean up the usage of z_const and respect const usage within zlib
+- Clean up examples/gzlog.[ch] comparisons of different types
+- Avoid shift equal to bits in type (caused endless loop)
+- Fix uninitialized value bug in gzputc() introduced by const patches
+- Fix memory allocation error in examples/zran.c [Nor]
+- Fix bug where gzopen(), gzclose() would write an empty file
+- Fix bug in gzclose() when gzwrite() runs out of memory
+- Check for input buffer malloc failure in examples/gzappend.c
+- Add note to contrib/blast to use binary mode in stdio
+- Fix comparisons of differently signed integers in contrib/blast
+- Check for invalid code length codes in contrib/puff
+- Fix serious but very rare decompression bug in inftrees.c
+- Update inflateBack() comments, since inflate() can be faster
+- Use underscored I/O function names for WINAPI_FAMILY
+- Add _tr_flush_bits to the external symbols prefixed by --zprefix
+- Add contrib/vstudio/vc10 pre-build step for static only
+- Quote --version-script argument in CMakeLists.txt
+- Don't specify --version-script on Apple platforms in CMakeLists.txt
+- Fix casting error in contrib/testzlib/testzlib.c
+- Fix types in contrib/minizip to match result of get_crc_table()
+- Simplify contrib/vstudio/vc10 with 'd' suffix
+- Add TOP support to win32/Makefile.msc
+- Suport i686 and amd64 assembler builds in CMakeLists.txt
+- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h
+- Add vc11 and vc12 build files to contrib/vstudio
+- Add gzvprintf() as an undocumented function in zlib
+- Fix configure for Sun shell
+- Remove runtime check in configure for four-byte integer type
+- Add casts and consts to ease user conversion to C++
+- Add man pages for minizip and miniunzip
+- In Makefile uninstall, don't rm if preceding cd fails
+- Do not return Z_BUF_ERROR if deflateParam() has nothing to write
+
+Changes in 1.2.7 (2 May 2012)
+- Replace use of memmove() with a simple copy for portability
+- Test for existence of strerror
+- Restore gzgetc_ for backward compatibility with 1.2.6
+- Fix build with non-GNU make on Solaris
+- Require gcc 4.0 or later on Mac OS X to use the hidden attribute
+- Include unistd.h for Watcom C
+- Use __WATCOMC__ instead of __WATCOM__
+- Do not use the visibility attribute if NO_VIZ defined
+- Improve the detection of no hidden visibility attribute
+- Avoid using __int64 for gcc or solo compilation
+- Cast to char * in gzprintf to avoid warnings [Zinser]
+- Fix make_vms.com for VAX [Zinser]
+- Don't use library or built-in byte swaps
+- Simplify test and use of gcc hidden attribute
+- Fix bug in gzclose_w() when gzwrite() fails to allocate memory
+- Add "x" (O_EXCL) and "e" (O_CLOEXEC) modes support to gzopen()
+- Fix bug in test/minigzip.c for configure --solo
+- Fix contrib/vstudio project link errors [Mohanathas]
+- Add ability to choose the builder in make_vms.com [Schweda]
+- Add DESTDIR support to mingw32 win32/Makefile.gcc
+- Fix comments in win32/Makefile.gcc for proper usage
+- Allow overriding the default install locations for cmake
+- Generate and install the pkg-config file with cmake
+- Build both a static and a shared version of zlib with cmake
+- Include version symbols for cmake builds
+- If using cmake with MSVC, add the source directory to the includes
+- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta]
+- Move obsolete emx makefile to old [Truta]
+- Allow the use of -Wundef when compiling or using zlib
+- Avoid the use of the -u option with mktemp
+- Improve inflate() documentation on the use of Z_FINISH
+- Recognize clang as gcc
+- Add gzopen_w() in Windows for wide character path names
+- Rename zconf.h in CMakeLists.txt to move it out of the way
+- Add source directory in CMakeLists.txt for building examples
+- Look in build directory for zlib.pc in CMakeLists.txt
+- Remove gzflags from zlibvc.def in vc9 and vc10
+- Fix contrib/minizip compilation in the MinGW environment
+- Update ./configure for Solaris, support --64 [Mooney]
+- Remove -R. from Solaris shared build (possible security issue)
+- Avoid race condition for parallel make (-j) running example
+- Fix type mismatch between get_crc_table() and crc_table
+- Fix parsing of version with "-" in CMakeLists.txt [Snider, Ziegler]
+- Fix the path to zlib.map in CMakeLists.txt
+- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe]
+- Add instructions to win32/Makefile.gcc for shared install [Torri]
+
+Changes in 1.2.6.1 (12 Feb 2012)
+- Avoid the use of the Objective-C reserved name "id"
+- Include io.h in gzguts.h for Microsoft compilers
+- Fix problem with ./configure --prefix and gzgetc macro
+- Include gz_header definition when compiling zlib solo
+- Put gzflags() functionality back in zutil.c
+- Avoid library header include in crc32.c for Z_SOLO
+- Use name in GCC_CLASSIC as C compiler for coverage testing, if set
+- Minor cleanup in contrib/minizip/zip.c [Vollant]
+- Update make_vms.com [Zinser]
+- Remove unnecessary gzgetc_ function
+- Use optimized byte swap operations for Microsoft and GNU [Snyder]
+- Fix minor typo in zlib.h comments [Rzesniowiecki]
+
+Changes in 1.2.6 (29 Jan 2012)
+- Update the Pascal interface in contrib/pascal
+- Fix function numbers for gzgetc_ in zlibvc.def files
+- Fix configure.ac for contrib/minizip [Schiffer]
+- Fix large-entry detection in minizip on 64-bit systems [Schiffer]
+- Have ./configure use the compiler return code for error indication
+- Fix CMakeLists.txt for cross compilation [McClure]
+- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes]
+- Fix compilation of contrib/minizip on FreeBSD [Marquez]
+- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath]
+- Include io.h for Turbo C / Borland C on all platforms [Truta]
+- Make version explicit in contrib/minizip/configure.ac [Bosmans]
+- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant]
+- Minor cleanup up contrib/minizip/unzip.c [Vollant]
+- Fix bug when compiling minizip with C++ [Vollant]
+- Protect for long name and extra fields in contrib/minizip [Vollant]
+- Avoid some warnings in contrib/minizip [Vollant]
+- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip
+- Add missing libs to minizip linker command
+- Add support for VPATH builds in contrib/minizip
+- Add an --enable-demos option to contrib/minizip/configure
+- Add the generation of configure.log by ./configure
+- Exit when required parameters not provided to win32/Makefile.gcc
+- Have gzputc return the character written instead of the argument
+- Use the -m option on ldconfig for BSD systems [Tobias]
+- Correct in zlib.map when deflateResetKeep was added
+
+Changes in 1.2.5.3 (15 Jan 2012)
+- Restore gzgetc function for binary compatibility
+- Do not use _lseeki64 under Borland C++ [Truta]
+- Update win32/Makefile.msc to build test/*.c [Truta]
+- Remove old/visualc6 given CMakefile and other alternatives
+- Update AS400 build files and documentation [Monnerat]
+- Update win32/Makefile.gcc to build test/*.c [Truta]
+- Permit stronger flushes after Z_BLOCK flushes
+- Avoid extraneous empty blocks when doing empty flushes
+- Permit Z_NULL arguments to deflatePending
+- Allow deflatePrime() to insert bits in the middle of a stream
+- Remove second empty static block for Z_PARTIAL_FLUSH
+- Write out all of the available bits when using Z_BLOCK
+- Insert the first two strings in the hash table after a flush
+
+Changes in 1.2.5.2 (17 Dec 2011)
+- fix ld error: unable to find version dependency 'ZLIB_1.2.5'
+- use relative symlinks for shared libs
+- Avoid searching past window for Z_RLE strategy
+- Assure that high-water mark initialization is always applied in deflate
+- Add assertions to fill_window() in deflate.c to match comments
+- Update python link in README
+- Correct spelling error in gzread.c
+- Fix bug in gzgets() for a concatenated empty gzip stream
+- Correct error in comment for gz_make()
+- Change gzread() and related to ignore junk after gzip streams
+- Allow gzread() and related to continue after gzclearerr()
+- Allow gzrewind() and gzseek() after a premature end-of-file
+- Simplify gzseek() now that raw after gzip is ignored
+- Change gzgetc() to a macro for speed (~40% speedup in testing)
+- Fix gzclose() to return the actual error last encountered
+- Always add large file support for windows
+- Include zconf.h for windows large file support
+- Include zconf.h.cmakein for windows large file support
+- Update zconf.h.cmakein on make distclean
+- Merge vestigial vsnprintf determination from zutil.h to gzguts.h
+- Clarify how gzopen() appends in zlib.h comments
+- Correct documentation of gzdirect() since junk at end now ignored
+- Add a transparent write mode to gzopen() when 'T' is in the mode
+- Update python link in zlib man page
+- Get inffixed.h and MAKEFIXED result to match
+- Add a ./config --solo option to make zlib subset with no library use
+- Add undocumented inflateResetKeep() function for CAB file decoding
+- Add --cover option to ./configure for gcc coverage testing
+- Add #define ZLIB_CONST option to use const in the z_stream interface
+- Add comment to gzdopen() in zlib.h to use dup() when using fileno()
+- Note behavior of uncompress() to provide as much data as it can
+- Add files in contrib/minizip to aid in building libminizip
+- Split off AR options in Makefile.in and configure
+- Change ON macro to Z_ARG to avoid application conflicts
+- Facilitate compilation with Borland C++ for pragmas and vsnprintf
+- Include io.h for Turbo C / Borland C++
+- Move example.c and minigzip.c to test/
+- Simplify incomplete code table filling in inflate_table()
+- Remove code from inflate.c and infback.c that is impossible to execute
+- Test the inflate code with full coverage
+- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw)
+- Add deflateResetKeep and fix inflateResetKeep to retain dictionary
+- Fix gzwrite.c to accommodate reduced memory zlib compilation
+- Have inflate() with Z_FINISH avoid the allocation of a window
+- Do not set strm->adler when doing raw inflate
+- Fix gzeof() to behave just like feof() when read is not past end of file
+- Fix bug in gzread.c when end-of-file is reached
+- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF
+- Document gzread() capability to read concurrently written files
+- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo]
+
+Changes in 1.2.5.1 (10 Sep 2011)
+- Update FAQ entry on shared builds (#13)
+- Avoid symbolic argument to chmod in Makefile.in
+- Fix bug and add consts in contrib/puff [Oberhumer]
+- Update contrib/puff/zeros.raw test file to have all block types
+- Add full coverage test for puff in contrib/puff/Makefile
+- Fix static-only-build install in Makefile.in
+- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno]
+- Add libz.a dependency to shared in Makefile.in for parallel builds
+- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out
+- Replace $(...) with `...` in configure for non-bash sh [Bowler]
+- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen]
+- Add solaris* to Linux* in configure to allow gcc use [Groffen]
+- Add *bsd* to Linux* case in configure [Bar-Lev]
+- Add inffast.obj to dependencies in win32/Makefile.msc
+- Correct spelling error in deflate.h [Kohler]
+- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc
+- Add test to configure for GNU C looking for gcc in output of $cc -v
+- Add zlib.pc generation to win32/Makefile.gcc [Weigelt]
+- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not
+- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense
+- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser)
+- Make stronger test in zconf.h to include unistd.h for LFS
+- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack]
+- Fix zlib.h LFS support when Z_PREFIX used
+- Add updated as400 support (removed from old) [Monnerat]
+- Avoid deflate sensitivity to volatile input data
+- Avoid division in adler32_combine for NO_DIVIDE
+- Clarify the use of Z_FINISH with deflateBound() amount of space
+- Set binary for output file in puff.c
+- Use u4 type for crc_table to avoid conversion warnings
+- Apply casts in zlib.h to avoid conversion warnings
+- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller]
+- Improve inflateSync() documentation to note indeterminancy
+- Add deflatePending() function to return the amount of pending output
+- Correct the spelling of "specification" in FAQ [Randers-Pehrson]
+- Add a check in configure for stdarg.h, use for gzprintf()
+- Check that pointers fit in ints when gzprint() compiled old style
+- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler]
+- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt]
+- Add debug records in assmebler code [Londer]
+- Update RFC references to use http://tools.ietf.org/html/... [Li]
+- Add --archs option, use of libtool to configure for Mac OS X [Borstel]
+
+Changes in 1.2.5 (19 Apr 2010)
+- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev]
+- Default to libdir as sharedlibdir in configure [Nieder]
+- Update copyright dates on modified source files
+- Update trees.c to be able to generate modified trees.h
+- Exit configure for MinGW, suggesting win32/Makefile.gcc
+- Check for NULL path in gz_open [Homurlu]
+
+Changes in 1.2.4.5 (18 Apr 2010)
+- Set sharedlibdir in configure [Torok]
+- Set LDFLAGS in Makefile.in [Bar-Lev]
+- Avoid mkdir objs race condition in Makefile.in [Bowler]
+- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays
+- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C
+- Don't use hidden attribute when it is a warning generator (e.g. Solaris)
+
+Changes in 1.2.4.4 (18 Apr 2010)
+- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok]
+- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty
+- Try to use bash or ksh regardless of functionality of /bin/sh
+- Fix configure incompatibility with NetBSD sh
+- Remove attempt to run under bash or ksh since have better NetBSD fix
+- Fix win32/Makefile.gcc for MinGW [Bar-Lev]
+- Add diagnostic messages when using CROSS_PREFIX in configure
+- Added --sharedlibdir option to configure [Weigelt]
+- Use hidden visibility attribute when available [Frysinger]
+
+Changes in 1.2.4.3 (10 Apr 2010)
+- Only use CROSS_PREFIX in configure for ar and ranlib if they exist
+- Use CROSS_PREFIX for nm [Bar-Lev]
+- Assume _LARGEFILE64_SOURCE defined is equivalent to true
+- Avoid use of undefined symbols in #if with && and ||
+- Make *64 prototypes in gzguts.h consistent with functions
+- Add -shared load option for MinGW in configure [Bowler]
+- Move z_off64_t to public interface, use instead of off64_t
+- Remove ! from shell test in configure (not portable to Solaris)
+- Change +0 macro tests to -0 for possibly increased portability
+
+Changes in 1.2.4.2 (9 Apr 2010)
+- Add consistent carriage returns to readme.txt's in masmx86 and masmx64
+- Really provide prototypes for *64 functions when building without LFS
+- Only define unlink() in minigzip.c if unistd.h not included
+- Update README to point to contrib/vstudio project files
+- Move projects/vc6 to old/ and remove projects/
+- Include stdlib.h in minigzip.c for setmode() definition under WinCE
+- Clean up assembler builds in win32/Makefile.msc [Rowe]
+- Include sys/types.h for Microsoft for off_t definition
+- Fix memory leak on error in gz_open()
+- Symbolize nm as $NM in configure [Weigelt]
+- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt]
+- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined
+- Fix bug in gzeof() to take into account unused input data
+- Avoid initialization of structures with variables in puff.c
+- Updated win32/README-WIN32.txt [Rowe]
+
+Changes in 1.2.4.1 (28 Mar 2010)
+- Remove the use of [a-z] constructs for sed in configure [gentoo 310225]
+- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech]
+- Restore "for debugging" comment on sprintf() in gzlib.c
+- Remove fdopen for MVS from gzguts.h
+- Put new README-WIN32.txt in win32 [Rowe]
+- Add check for shell to configure and invoke another shell if needed
+- Fix big fat stinking bug in gzseek() on uncompressed files
+- Remove vestigial F_OPEN64 define in zutil.h
+- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE
+- Avoid errors on non-LFS systems when applications define LFS macros
+- Set EXE to ".exe" in configure for MINGW [Kahle]
+- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill]
+- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev]
+- Add DLL install in win32/makefile.gcc [Bar-Lev]
+- Allow Linux* or linux* from uname in configure [Bar-Lev]
+- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev]
+- Add cross-compilation prefixes to configure [Bar-Lev]
+- Match type exactly in gz_load() invocation in gzread.c
+- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func
+- Provide prototypes for *64 functions when building zlib without LFS
+- Don't use -lc when linking shared library on MinGW
+- Remove errno.h check in configure and vestigial errno code in zutil.h
+
+Changes in 1.2.4 (14 Mar 2010)
+- Fix VER3 extraction in configure for no fourth subversion
+- Update zlib.3, add docs to Makefile.in to make .pdf out of it
+- Add zlib.3.pdf to distribution
+- Don't set error code in gzerror() if passed pointer is NULL
+- Apply destination directory fixes to CMakeLists.txt [Lowman]
+- Move #cmakedefine's to a new zconf.in.cmakein
+- Restore zconf.h for builds that don't use configure or cmake
+- Add distclean to dummy Makefile for convenience
+- Update and improve INDEX, README, and FAQ
+- Update CMakeLists.txt for the return of zconf.h [Lowman]
+- Update contrib/vstudio/vc9 and vc10 [Vollant]
+- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc
+- Apply license and readme changes to contrib/asm686 [Raiter]
+- Check file name lengths and add -c option in minigzip.c [Li]
+- Update contrib/amd64 and contrib/masmx86/ [Vollant]
+- Avoid use of "eof" parameter in trees.c to not shadow library variable
+- Update make_vms.com for removal of zlibdefs.h [Zinser]
+- Update assembler code and vstudio projects in contrib [Vollant]
+- Remove outdated assembler code contrib/masm686 and contrib/asm586
+- Remove old vc7 and vc8 from contrib/vstudio
+- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe]
+- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open()
+- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant]
+- Remove *64 functions from win32/zlib.def (they're not 64-bit yet)
+- Fix bug in void-returning vsprintf() case in gzwrite.c
+- Fix name change from inflate.h in contrib/inflate86/inffas86.c
+- Check if temporary file exists before removing in make_vms.com [Zinser]
+- Fix make install and uninstall for --static option
+- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta]
+- Update readme.txt in contrib/masmx64 and masmx86 to assemble
+
+Changes in 1.2.3.9 (21 Feb 2010)
+- Expunge gzio.c
+- Move as400 build information to old
+- Fix updates in contrib/minizip and contrib/vstudio
+- Add const to vsnprintf test in configure to avoid warnings [Weigelt]
+- Delete zconf.h (made by configure) [Weigelt]
+- Change zconf.in.h to zconf.h.in per convention [Weigelt]
+- Check for NULL buf in gzgets()
+- Return empty string for gzgets() with len == 1 (like fgets())
+- Fix description of gzgets() in zlib.h for end-of-file, NULL return
+- Update minizip to 1.1 [Vollant]
+- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c
+- Note in zlib.h that gzerror() should be used to distinguish from EOF
+- Remove use of snprintf() from gzlib.c
+- Fix bug in gzseek()
+- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant]
+- Fix zconf.h generation in CMakeLists.txt [Lowman]
+- Improve comments in zconf.h where modified by configure
+
+Changes in 1.2.3.8 (13 Feb 2010)
+- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer]
+- Use z_off64_t in gz_zero() and gz_skip() to match state->skip
+- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t)
+- Revert to Makefile.in from 1.2.3.6 (live with the clutter)
+- Fix missing error return in gzflush(), add zlib.h note
+- Add *64 functions to zlib.map [Levin]
+- Fix signed/unsigned comparison in gz_comp()
+- Use SFLAGS when testing shared linking in configure
+- Add --64 option to ./configure to use -m64 with gcc
+- Fix ./configure --help to correctly name options
+- Have make fail if a test fails [Levin]
+- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson]
+- Remove assembler object files from contrib
+
+Changes in 1.2.3.7 (24 Jan 2010)
+- Always gzopen() with O_LARGEFILE if available
+- Fix gzdirect() to work immediately after gzopen() or gzdopen()
+- Make gzdirect() more precise when the state changes while reading
+- Improve zlib.h documentation in many places
+- Catch memory allocation failure in gz_open()
+- Complete close operation if seek forward in gzclose_w() fails
+- Return Z_ERRNO from gzclose_r() if close() fails
+- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL
+- Return zero for gzwrite() errors to match zlib.h description
+- Return -1 on gzputs() error to match zlib.h description
+- Add zconf.in.h to allow recovery from configure modification [Weigelt]
+- Fix static library permissions in Makefile.in [Weigelt]
+- Avoid warnings in configure tests that hide functionality [Weigelt]
+- Add *BSD and DragonFly to Linux case in configure [gentoo 123571]
+- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212]
+- Avoid access of uninitialized data for first inflateReset2 call [Gomes]
+- Keep object files in subdirectories to reduce the clutter somewhat
+- Remove default Makefile and zlibdefs.h, add dummy Makefile
+- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_
+- Remove zlibdefs.h completely -- modify zconf.h instead
+
+Changes in 1.2.3.6 (17 Jan 2010)
+- Avoid void * arithmetic in gzread.c and gzwrite.c
+- Make compilers happier with const char * for gz_error message
+- Avoid unused parameter warning in inflate.c
+- Avoid signed-unsigned comparison warning in inflate.c
+- Indent #pragma's for traditional C
+- Fix usage of strwinerror() in glib.c, change to gz_strwinerror()
+- Correct email address in configure for system options
+- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser]
+- Update zlib.map [Brown]
+- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok]
+- Apply various fixes to CMakeLists.txt [Lowman]
+- Add checks on len in gzread() and gzwrite()
+- Add error message for no more room for gzungetc()
+- Remove zlib version check in gzwrite()
+- Defer compression of gzprintf() result until need to
+- Use snprintf() in gzdopen() if available
+- Remove USE_MMAP configuration determination (only used by minigzip)
+- Remove examples/pigz.c (available separately)
+- Update examples/gun.c to 1.6
+
+Changes in 1.2.3.5 (8 Jan 2010)
+- Add space after #if in zutil.h for some compilers
+- Fix relatively harmless bug in deflate_fast() [Exarevsky]
+- Fix same problem in deflate_slow()
+- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown]
+- Add deflate_rle() for faster Z_RLE strategy run-length encoding
+- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding
+- Change name of "write" variable in inffast.c to avoid library collisions
+- Fix premature EOF from gzread() in gzio.c [Brown]
+- Use zlib header window size if windowBits is 0 in inflateInit2()
+- Remove compressBound() call in deflate.c to avoid linking compress.o
+- Replace use of errno in gz* with functions, support WinCE [Alves]
+- Provide alternative to perror() in minigzip.c for WinCE [Alves]
+- Don't use _vsnprintf on later versions of MSVC [Lowman]
+- Add CMake build script and input file [Lowman]
+- Update contrib/minizip to 1.1 [Svensson, Vollant]
+- Moved nintendods directory from contrib to .
+- Replace gzio.c with a new set of routines with the same functionality
+- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above
+- Update contrib/minizip to 1.1b
+- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h
+
+Changes in 1.2.3.4 (21 Dec 2009)
+- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility
+- Update comments in configure and Makefile.in for default --shared
+- Fix test -z's in configure [Marquess]
+- Build examplesh and minigzipsh when not testing
+- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h
+- Import LDFLAGS from the environment in configure
+- Fix configure to populate SFLAGS with discovered CFLAGS options
+- Adapt make_vms.com to the new Makefile.in [Zinser]
+- Add zlib2ansi script for C++ compilation [Marquess]
+- Add _FILE_OFFSET_BITS=64 test to make test (when applicable)
+- Add AMD64 assembler code for longest match to contrib [Teterin]
+- Include options from $SFLAGS when doing $LDSHARED
+- Simplify 64-bit file support by introducing z_off64_t type
+- Make shared object files in objs directory to work around old Sun cc
+- Use only three-part version number for Darwin shared compiles
+- Add rc option to ar in Makefile.in for when ./configure not run
+- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4*
+- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile
+- Protect against _FILE_OFFSET_BITS being defined when compiling zlib
+- Rename Makefile.in targets allstatic to static and allshared to shared
+- Fix static and shared Makefile.in targets to be independent
+- Correct error return bug in gz_open() by setting state [Brown]
+- Put spaces before ;;'s in configure for better sh compatibility
+- Add pigz.c (parallel implementation of gzip) to examples/
+- Correct constant in crc32.c to UL [Leventhal]
+- Reject negative lengths in crc32_combine()
+- Add inflateReset2() function to work like inflateEnd()/inflateInit2()
+- Include sys/types.h for _LARGEFILE64_SOURCE [Brown]
+- Correct typo in doc/algorithm.txt [Janik]
+- Fix bug in adler32_combine() [Zhu]
+- Catch missing-end-of-block-code error in all inflates and in puff
+    Assures that random input to inflate eventually results in an error
+- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/
+- Update ENOUGH and its usage to reflect discovered bounds
+- Fix gzerror() error report on empty input file [Brown]
+- Add ush casts in trees.c to avoid pedantic runtime errors
+- Fix typo in zlib.h uncompress() description [Reiss]
+- Correct inflate() comments with regard to automatic header detection
+- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays)
+- Put new version of gzlog (2.0) in examples with interruption recovery
+- Add puff compile option to permit invalid distance-too-far streams
+- Add puff TEST command options, ability to read piped input
+- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but
+  _LARGEFILE64_SOURCE not defined
+- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart
+- Fix deflateSetDictionary() to use all 32K for output consistency
+- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h)
+- Clear bytes after deflate lookahead to avoid use of uninitialized data
+- Change a limit in inftrees.c to be more transparent to Coverity Prevent
+- Update win32/zlib.def with exported symbols from zlib.h
+- Correct spelling errors in zlib.h [Willem, Sobrado]
+- Allow Z_BLOCK for deflate() to force a new block
+- Allow negative bits in inflatePrime() to delete existing bit buffer
+- Add Z_TREES flush option to inflate() to return at end of trees
+- Add inflateMark() to return current state information for random access
+- Add Makefile for NintendoDS to contrib [Costa]
+- Add -w in configure compile tests to avoid spurious warnings [Beucler]
+- Fix typos in zlib.h comments for deflateSetDictionary()
+- Fix EOF detection in transparent gzread() [Maier]
+
+Changes in 1.2.3.3 (2 October 2006)
+- Make --shared the default for configure, add a --static option
+- Add compile option to permit invalid distance-too-far streams
+- Add inflateUndermine() function which is required to enable above
+- Remove use of "this" variable name for C++ compatibility [Marquess]
+- Add testing of shared library in make test, if shared library built
+- Use ftello() and fseeko() if available instead of ftell() and fseek()
+- Provide two versions of all functions that use the z_off_t type for
+  binary compatibility -- a normal version and a 64-bit offset version,
+  per the Large File Support Extension when _LARGEFILE64_SOURCE is
+  defined; use the 64-bit versions by default when _FILE_OFFSET_BITS
+  is defined to be 64
+- Add a --uname= option to configure to perhaps help with cross-compiling
+
+Changes in 1.2.3.2 (3 September 2006)
+- Turn off silly Borland warnings [Hay]
+- Use off64_t and define _LARGEFILE64_SOURCE when present
+- Fix missing dependency on inffixed.h in Makefile.in
+- Rig configure --shared to build both shared and static [Teredesai, Truta]
+- Remove zconf.in.h and instead create a new zlibdefs.h file
+- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant]
+- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt]
+
+Changes in 1.2.3.1 (16 August 2006)
+- Add watcom directory with OpenWatcom make files [Daniel]
+- Remove #undef of FAR in zconf.in.h for MVS [Fedtke]
+- Update make_vms.com [Zinser]
+- Use -fPIC for shared build in configure [Teredesai, Nicholson]
+- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen]
+- Use fdopen() (not _fdopen()) for Interix in zutil.h [BÃ¤ck]
+- Add some FAQ entries about the contrib directory
+- Update the MVS question in the FAQ
+- Avoid extraneous reads after EOF in gzio.c [Brown]
+- Correct spelling of "successfully" in gzio.c [Randers-Pehrson]
+- Add comments to zlib.h about gzerror() usage [Brown]
+- Set extra flags in gzip header in gzopen() like deflate() does
+- Make configure options more compatible with double-dash conventions
+  [Weigelt]
+- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen]
+- Fix uninstall target in Makefile.in [Truta]
+- Add pkgconfig support [Weigelt]
+- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt]
+- Replace set_data_type() with a more accurate detect_data_type() in
+  trees.c, according to the txtvsbin.txt document [Truta]
+- Swap the order of #include <stdio.h> and #include "zlib.h" in
+  gzio.c, example.c and minigzip.c [Truta]
+- Shut up annoying VS2005 warnings about standard C deprecation [Rowe,
+  Truta] (where?)
+- Fix target "clean" from win32/Makefile.bor [Truta]
+- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe]
+- Update zlib www home address in win32/DLL_FAQ.txt [Truta]
+- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove]
+- Enable browse info in the "Debug" and "ASM Debug" configurations in
+  the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta]
+- Add pkgconfig support [Weigelt]
+- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h,
+  for use in win32/zlib1.rc [Polushin, Rowe, Truta]
+- Add a document that explains the new text detection scheme to
+  doc/txtvsbin.txt [Truta]
+- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta]
+- Move algorithm.txt into doc/ [Truta]
+- Synchronize FAQ with website
+- Fix compressBound(), was low for some pathological cases [Fearnley]
+- Take into account wrapper variations in deflateBound()
+- Set examples/zpipe.c input and output to binary mode for Windows
+- Update examples/zlib_how.html with new zpipe.c (also web site)
+- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems
+  that gcc became pickier in 4.0)
+- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain
+  un-versioned, the patch adds versioning only for symbols introduced in
+  zlib-1.2.0 or later.  It also declares as local those symbols which are
+  not designed to be exported." [Levin]
+- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure
+- Do not initialize global static by default in trees.c, add a response
+  NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess]
+- Don't use strerror() in gzio.c under WinCE [Yakimov]
+- Don't use errno.h in zutil.h under WinCE [Yakimov]
+- Move arguments for AR to its usage to allow replacing ar [Marot]
+- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson]
+- Improve inflateInit() and inflateInit2() documentation
+- Fix structure size comment in inflate.h
+- Change configure help option from --h* to --help [Santos]
+
+Changes in 1.2.3 (18 July 2005)
+- Apply security vulnerability fixes to contrib/infback9 as well
+- Clean up some text files (carriage returns, trailing space)
+- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant]
+
+Changes in 1.2.2.4 (11 July 2005)
+- Add inflatePrime() function for starting inflation at bit boundary
+- Avoid some Visual C warnings in deflate.c
+- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit
+  compile
+- Fix some spelling errors in comments [Betts]
+- Correct inflateInit2() error return documentation in zlib.h
+- Add zran.c example of compressed data random access to examples
+  directory, shows use of inflatePrime()
+- Fix cast for assignments to strm->state in inflate.c and infback.c
+- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer]
+- Move declarations of gf2 functions to right place in crc32.c [Oberhumer]
+- Add cast in trees.c t avoid a warning [Oberhumer]
+- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer]
+- Update make_vms.com [Zinser]
+- Initialize state->write in inflateReset() since copied in inflate_fast()
+- Be more strict on incomplete code sets in inflate_table() and increase
+  ENOUGH and MAXD -- this repairs a possible security vulnerability for
+  invalid inflate input.  Thanks to Tavis Ormandy and Markus Oberhumer for
+  discovering the vulnerability and providing test cases.
+- Add ia64 support to configure for HP-UX [Smith]
+- Add error return to gzread() for format or i/o error [Levin]
+- Use malloc.h for OS/2 [Necasek]
+
+Changes in 1.2.2.3 (27 May 2005)
+- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile
+- Typecast fread() return values in gzio.c [Vollant]
+- Remove trailing space in minigzip.c outmode (VC++ can't deal with it)
+- Fix crc check bug in gzread() after gzungetc() [Heiner]
+- Add the deflateTune() function to adjust internal compression parameters
+- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack)
+- Remove an incorrect assertion in examples/zpipe.c
+- Add C++ wrapper in infback9.h [Donais]
+- Fix bug in inflateCopy() when decoding fixed codes
+- Note in zlib.h how much deflateSetDictionary() actually uses
+- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used)
+- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer]
+- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer]
+- Add gzdirect() function to indicate transparent reads
+- Update contrib/minizip [Vollant]
+- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer]
+- Add casts in crc32.c to avoid warnings [Oberhumer]
+- Add contrib/masmx64 [Vollant]
+- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant]
+
+Changes in 1.2.2.2 (30 December 2004)
+- Replace structure assignments in deflate.c and inflate.c with zmemcpy to
+  avoid implicit memcpy calls (portability for no-library compilation)
+- Increase sprintf() buffer size in gzdopen() to allow for large numbers
+- Add INFLATE_STRICT to check distances against zlib header
+- Improve WinCE errno handling and comments [Chang]
+- Remove comment about no gzip header processing in FAQ
+- Add Z_FIXED strategy option to deflateInit2() to force fixed trees
+- Add updated make_vms.com [Coghlan], update README
+- Create a new "examples" directory, move gzappend.c there, add zpipe.c,
+  fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html.
+- Add FAQ entry and comments in deflate.c on uninitialized memory access
+- Add Solaris 9 make options in configure [Gilbert]
+- Allow strerror() usage in gzio.c for STDC
+- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer]
+- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant]
+- Use z_off_t for adler32_combine() and crc32_combine() lengths
+- Make adler32() much faster for small len
+- Use OS_CODE in deflate() default gzip header
+
+Changes in 1.2.2.1 (31 October 2004)
+- Allow inflateSetDictionary() call for raw inflate
+- Fix inflate header crc check bug for file names and comments
+- Add deflateSetHeader() and gz_header structure for custom gzip headers
+- Add inflateGetheader() to retrieve gzip headers
+- Add crc32_combine() and adler32_combine() functions
+- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list
+- Use zstreamp consistently in zlib.h (inflate_back functions)
+- Remove GUNZIP condition from definition of inflate_mode in inflate.h
+  and in contrib/inflate86/inffast.S [Truta, Anderson]
+- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson]
+- Update projects/README.projects and projects/visualc6 [Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta]
+- Deprecate Z_ASCII; use Z_TEXT instead [Truta]
+- Use a new algorithm for setting strm->data_type in trees.c [Truta]
+- Do not define an exit() prototype in zutil.c unless DEBUG defined
+- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta]
+- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate()
+- Fix Darwin build version identification [Peterson]
+
+Changes in 1.2.2 (3 October 2004)
+- Update zlib.h comments on gzip in-memory processing
+- Set adler to 1 in inflateReset() to support Java test suite [Walles]
+- Add contrib/dotzlib [Ravn]
+- Update win32/DLL_FAQ.txt [Truta]
+- Update contrib/minizip [Vollant]
+- Move contrib/visual-basic.txt to old/ [Truta]
+- Fix assembler builds in projects/visualc6/ [Truta]
+
+Changes in 1.2.1.2 (9 September 2004)
+- Update INDEX file
+- Fix trees.c to update strm->data_type (no one ever noticed!)
+- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown]
+- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE)
+- Add limited multitasking protection to DYNAMIC_CRC_TABLE
+- Add NO_vsnprintf for VMS in zutil.h [Mozilla]
+- Don't declare strerror() under VMS [Mozilla]
+- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize
+- Update contrib/ada [Anisimkov]
+- Update contrib/minizip [Vollant]
+- Fix configure to not hardcode directories for Darwin [Peterson]
+- Fix gzio.c to not return error on empty files [Brown]
+- Fix indentation; update version in contrib/delphi/ZLib.pas and
+  contrib/pascal/zlibpas.pas [Truta]
+- Update mkasm.bat in contrib/masmx86 [Truta]
+- Update contrib/untgz [Truta]
+- Add projects/README.projects [Truta]
+- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta]
+- Remove an unnecessary assignment to curr in inftrees.c [Truta]
+- Add OS/2 to exe builds in configure [Poltorak]
+- Remove err dummy parameter in zlib.h [Kientzle]
+
+Changes in 1.2.1.1 (9 January 2004)
+- Update email address in README
+- Several FAQ updates
+- Fix a big fat bug in inftrees.c that prevented decoding valid
+  dynamic blocks with only literals and no distance codes --
+  Thanks to "Hot Emu" for the bug report and sample file
+- Add a note to puff.c on no distance codes case.
+
+Changes in 1.2.1 (17 November 2003)
+- Remove a tab in contrib/gzappend/gzappend.c
+- Update some interfaces in contrib for new zlib functions
+- Update zlib version number in some contrib entries
+- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta]
+- Support shared libraries on Hurd and KFreeBSD [Brown]
+- Fix error in NO_DIVIDE option of adler32.c
+
+Changes in 1.2.0.8 (4 November 2003)
+- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas
+- Add experimental NO_DIVIDE #define in adler32.c
+    - Possibly faster on some processors (let me know if it is)
+- Correct Z_BLOCK to not return on first inflate call if no wrap
+- Fix strm->data_type on inflate() return to correctly indicate EOB
+- Add deflatePrime() function for appending in the middle of a byte
+- Add contrib/gzappend for an example of appending to a stream
+- Update win32/DLL_FAQ.txt [Truta]
+- Delete Turbo C comment in README [Truta]
+- Improve some indentation in zconf.h [Truta]
+- Fix infinite loop on bad input in configure script [Church]
+- Fix gzeof() for concatenated gzip files [Johnson]
+- Add example to contrib/visual-basic.txt [Michael B.]
+- Add -p to mkdir's in Makefile.in [vda]
+- Fix configure to properly detect presence or lack of printf functions
+- Add AS400 support [Monnerat]
+- Add a little Cygwin support [Wilson]
+
+Changes in 1.2.0.7 (21 September 2003)
+- Correct some debug formats in contrib/infback9
+- Cast a type in a debug statement in trees.c
+- Change search and replace delimiter in configure from % to # [Beebe]
+- Update contrib/untgz to 0.2 with various fixes [Truta]
+- Add build support for Amiga [Nikl]
+- Remove some directories in old that have been updated to 1.2
+- Add dylib building for Mac OS X in configure and Makefile.in
+- Remove old distribution stuff from Makefile
+- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X
+- Update links in README
+
+Changes in 1.2.0.6 (13 September 2003)
+- Minor FAQ updates
+- Update contrib/minizip to 1.00 [Vollant]
+- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta]
+- Update POSTINC comment for 68060 [Nikl]
+- Add contrib/infback9 with deflate64 decoding (unsupported)
+- For MVS define NO_vsnprintf and undefine FAR [van Burik]
+- Add pragma for fdopen on MVS [van Burik]
+
+Changes in 1.2.0.5 (8 September 2003)
+- Add OF to inflateBackEnd() declaration in zlib.h
+- Remember start when using gzdopen in the middle of a file
+- Use internal off_t counters in gz* functions to properly handle seeks
+- Perform more rigorous check for distance-too-far in inffast.c
+- Add Z_BLOCK flush option to return from inflate at block boundary
+- Set strm->data_type on return from inflate
+    - Indicate bits unused, if at block boundary, and if in last block
+- Replace size_t with ptrdiff_t in crc32.c, and check for correct size
+- Add condition so old NO_DEFLATE define still works for compatibility
+- FAQ update regarding the Windows DLL [Truta]
+- INDEX update: add qnx entry, remove aix entry [Truta]
+- Install zlib.3 into mandir [Wilson]
+- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta]
+- Adapt the zlib interface to the new DLL convention guidelines [Truta]
+- Introduce ZLIB_WINAPI macro to allow the export of functions using
+  the WINAPI calling convention, for Visual Basic [Vollant, Truta]
+- Update msdos and win32 scripts and makefiles [Truta]
+- Export symbols by name, not by ordinal, in win32/zlib.def [Truta]
+- Add contrib/ada [Anisimkov]
+- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta]
+- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant]
+- Add contrib/masm686 [Truta]
+- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm
+  [Truta, Vollant]
+- Update contrib/delphi; rename to contrib/pascal; add example [Truta]
+- Remove contrib/delphi2; add a new contrib/delphi [Truta]
+- Avoid inclusion of the nonstandard <memory.h> in contrib/iostream,
+  and fix some method prototypes [Truta]
+- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip
+  [Truta]
+- Avoid the use of backslash (\) in contrib/minizip [Vollant]
+- Fix file time handling in contrib/untgz; update makefiles [Truta]
+- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines
+  [Vollant]
+- Remove contrib/vstudio/vc15_16 [Vollant]
+- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta]
+- Update README.contrib [Truta]
+- Invert the assignment order of match_head and s->prev[...] in
+  INSERT_STRING [Truta]
+- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings
+  [Truta]
+- Compare function pointers with 0, not with NULL or Z_NULL [Truta]
+- Fix prototype of syncsearch in inflate.c [Truta]
+- Introduce ASMINF macro to be enabled when using an ASM implementation
+  of inflate_fast [Truta]
+- Change NO_DEFLATE to NO_GZCOMPRESS [Truta]
+- Modify test_gzio in example.c to take a single file name as a
+  parameter [Truta]
+- Exit the example.c program if gzopen fails [Truta]
+- Add type casts around strlen in example.c [Truta]
+- Remove casting to sizeof in minigzip.c; give a proper type
+  to the variable compared with SUFFIX_LEN [Truta]
+- Update definitions of STDC and STDC99 in zconf.h [Truta]
+- Synchronize zconf.h with the new Windows DLL interface [Truta]
+- Use SYS16BIT instead of __32BIT__ to distinguish between
+  16- and 32-bit platforms [Truta]
+- Use far memory allocators in small 16-bit memory models for
+  Turbo C [Truta]
+- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in
+  zlibCompileFlags [Truta]
+- Cygwin has vsnprintf [Wilson]
+- In Windows16, OS_CODE is 0, as in MSDOS [Truta]
+- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson]
+
+Changes in 1.2.0.4 (10 August 2003)
+- Minor FAQ updates
+- Be more strict when checking inflateInit2's windowBits parameter
+- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well
+- Add gzip wrapper option to deflateInit2 using windowBits
+- Add updated QNX rule in configure and qnx directory [Bonnefoy]
+- Make inflate distance-too-far checks more rigorous
+- Clean up FAR usage in inflate
+- Add casting to sizeof() in gzio.c and minigzip.c
+
+Changes in 1.2.0.3 (19 July 2003)
+- Fix silly error in gzungetc() implementation [Vollant]
+- Update contrib/minizip and contrib/vstudio [Vollant]
+- Fix printf format in example.c
+- Correct cdecl support in zconf.in.h [Anisimkov]
+- Minor FAQ updates
+
+Changes in 1.2.0.2 (13 July 2003)
+- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons
+- Attempt to avoid warnings in crc32.c for pointer-int conversion
+- Add AIX to configure, remove aix directory [Bakker]
+- Add some casts to minigzip.c
+- Improve checking after insecure sprintf() or vsprintf() calls
+- Remove #elif's from crc32.c
+- Change leave label to inf_leave in inflate.c and infback.c to avoid
+  library conflicts
+- Remove inflate gzip decoding by default--only enable gzip decoding by
+  special request for stricter backward compatibility
+- Add zlibCompileFlags() function to return compilation information
+- More typecasting in deflate.c to avoid warnings
+- Remove leading underscore from _Capital #defines [Truta]
+- Fix configure to link shared library when testing
+- Add some Windows CE target adjustments [Mai]
+- Remove #define ZLIB_DLL in zconf.h [Vollant]
+- Add zlib.3 [Rodgers]
+- Update RFC URL in deflate.c and algorithm.txt [Mai]
+- Add zlib_dll_FAQ.txt to contrib [Truta]
+- Add UL to some constants [Truta]
+- Update minizip and vstudio [Vollant]
+- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h
+- Expand use of NO_DUMMY_DECL to avoid all dummy structures
+- Added iostream3 to contrib [Schwardt]
+- Replace rewind() with fseek() for WinCE [Truta]
+- Improve setting of zlib format compression level flags
+    - Report 0 for huffman and rle strategies and for level == 0 or 1
+    - Report 2 only for level == 6
+- Only deal with 64K limit when necessary at compile time [Truta]
+- Allow TOO_FAR check to be turned off at compile time [Truta]
+- Add gzclearerr() function [Souza]
+- Add gzungetc() function
+
+Changes in 1.2.0.1 (17 March 2003)
+- Add Z_RLE strategy for run-length encoding [Truta]
+    - When Z_RLE requested, restrict matches to distance one
+    - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE
+- Correct FASTEST compilation to allow level == 0
+- Clean up what gets compiled for FASTEST
+- Incorporate changes to zconf.in.h [Vollant]
+    - Refine detection of Turbo C need for dummy returns
+    - Refine ZLIB_DLL compilation
+    - Include additional header file on VMS for off_t typedef
+- Try to use _vsnprintf where it supplants vsprintf [Vollant]
+- Add some casts in inffast.c
+- Enchance comments in zlib.h on what happens if gzprintf() tries to
+  write more than 4095 bytes before compression
+- Remove unused state from inflateBackEnd()
+- Remove exit(0) from minigzip.c, example.c
+- Get rid of all those darn tabs
+- Add "check" target to Makefile.in that does the same thing as "test"
+- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in
+- Update contrib/inflate86 [Anderson]
+- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant]
+- Add msdos and win32 directories with makefiles [Truta]
+- More additions and improvements to the FAQ
+
+Changes in 1.2.0 (9 March 2003)
+- New and improved inflate code
+    - About 20% faster
+    - Does not allocate 32K window unless and until needed
+    - Automatically detects and decompresses gzip streams
+    - Raw inflate no longer needs an extra dummy byte at end
+    - Added inflateBack functions using a callback interface--even faster
+      than inflate, useful for file utilities (gzip, zip)
+    - Added inflateCopy() function to record state for random access on
+      externally generated deflate streams (e.g. in gzip files)
+    - More readable code (I hope)
+- New and improved crc32()
+    - About 50% faster, thanks to suggestions from Rodney Brown
+- Add deflateBound() and compressBound() functions
+- Fix memory leak in deflateInit2()
+- Permit setting dictionary for raw deflate (for parallel deflate)
+- Fix const declaration for gzwrite()
+- Check for some malloc() failures in gzio.c
+- Fix bug in gzopen() on single-byte file 0x1f
+- Fix bug in gzread() on concatenated file with 0x1f at end of buffer
+  and next buffer doesn't start with 0x8b
+- Fix uncompress() to return Z_DATA_ERROR on truncated input
+- Free memory at end of example.c
+- Remove MAX #define in trees.c (conflicted with some libraries)
+- Fix static const's in deflate.c, gzio.c, and zutil.[ch]
+- Declare malloc() and free() in gzio.c if STDC not defined
+- Use malloc() instead of calloc() in zutil.c if int big enough
+- Define STDC for AIX
+- Add aix/ with approach for compiling shared library on AIX
+- Add HP-UX support for shared libraries in configure
+- Add OpenUNIX support for shared libraries in configure
+- Use $cc instead of gcc to build shared library
+- Make prefix directory if needed when installing
+- Correct Macintosh avoidance of typedef Byte in zconf.h
+- Correct Turbo C memory allocation when under Linux
+- Use libz.a instead of -lz in Makefile (assure use of compiled library)
+- Update configure to check for snprintf or vsnprintf functions and their
+  return value, warn during make if using an insecure function
+- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that
+  is lost when library is used--resolution is to build new zconf.h
+- Documentation improvements (in zlib.h):
+    - Document raw deflate and inflate
+    - Update RFCs URL
+    - Point out that zlib and gzip formats are different
+    - Note that Z_BUF_ERROR is not fatal
+    - Document string limit for gzprintf() and possible buffer overflow
+    - Note requirement on avail_out when flushing
+    - Note permitted values of flush parameter of inflate()
+- Add some FAQs (and even answers) to the FAQ
+- Add contrib/inflate86/ for x86 faster inflate
+- Add contrib/blast/ for PKWare Data Compression Library decompression
+- Add contrib/puff/ simple inflate for deflate format description
+
+Changes in 1.1.4 (11 March 2002)
+- ZFREE was repeated on same allocation on some error conditions.
+  This creates a security problem described in
+  http://www.zlib.org/advisory-2002-03-11.txt
+- Returned incorrect error (Z_MEM_ERROR) on some invalid data
+- Avoid accesses before window for invalid distances with inflate window
+  less than 32K.
+- force windowBits > 8 to avoid a bug in the encoder for a window size
+  of 256 bytes. (A complete fix will be available in 1.1.5).
+
+Changes in 1.1.3 (9 July 1998)
+- fix "an inflate input buffer bug that shows up on rare but persistent
+  occasions" (Mark)
+- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
+- fix gzseek(..., SEEK_SET) in write mode
+- fix crc check after a gzeek (Frank Faubert)
+- fix miniunzip when the last entry in a zip file is itself a zip file
+  (J Lillge)
+- add contrib/asm586 and contrib/asm686 (Brian Raiter)
+  See http://www.muppetlabs.com/~breadbox/software/assembly.html
+- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
+- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
+- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
+- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
+- added a FAQ file
+
+- Support gzdopen on Mac with Metrowerks (Jason Linhart)
+- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart)
+- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young)
+- avoid some warnings with Borland C (Tom Tanner)
+- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant)
+- emulate utime() for WIN32 in contrib/untgz  (Gilles Vollant)
+- allow several arguments to configure (Tim Mooney, Frodo Looijaard)
+- use libdir and includedir in Makefile.in (Tim Mooney)
+- support shared libraries on OSF1 V4 (Tim Mooney)
+- remove so_locations in "make clean"  (Tim Mooney)
+- fix maketree.c compilation error (Glenn, Mark)
+- Python interface to zlib now in Python 1.5 (Jeremy Hylton)
+- new Makefile.riscos (Rich Walker)
+- initialize static descriptors in trees.c for embedded targets (Nick Smith)
+- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith)
+- add the OS/2 files in Makefile.in too (Andrew Zabolotny)
+- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane)
+- fix maketree.c to allow clean compilation of inffixed.h (Mark)
+- fix parameter check in deflateCopy (Gunther Nikl)
+- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler)
+- Many portability patches by Christian Spieler:
+  . zutil.c, zutil.h: added "const" for zmem*
+  . Make_vms.com: fixed some typos
+  . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists
+  . msdos/Makefile.msc: remove "default rtl link library" info from obj files
+  . msdos/Makefile.*: use model-dependent name for the built zlib library
+  . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc:
+     new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT)
+- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane)
+- replace __far with _far for better portability (Christian Spieler, Tom Lane)
+- fix test for errno.h in configure (Tim Newsham)
+
+Changes in 1.1.2 (19 March 98)
+- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)
+  See http://www.winimage.com/zLibDll/unzip.html
+- preinitialize the inflate tables for fixed codes, to make the code
+  completely thread safe (Mark)
+- some simplifications and slight speed-up to the inflate code (Mark)
+- fix gzeof on non-compressed files (Allan Schrum)
+- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)
+- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)
+- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)
+- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)
+- do not wrap extern "C" around system includes (Tom Lane)
+- mention zlib binding for TCL in README (Andreas Kupries)
+- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)
+- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson)
+- allow "configure --prefix $HOME" (Tim Mooney)
+- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson)
+- move Makefile.sas to amiga/Makefile.sas
+
+Changes in 1.1.1 (27 Feb 98)
+- fix macros _tr_tally_* in deflate.h for debug mode  (Glenn Randers-Pehrson)
+- remove block truncation heuristic which had very marginal effect for zlib
+  (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
+  compression ratio on some files. This also allows inlining _tr_tally for
+  matches in deflate_slow.
+- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
+
+Changes in 1.1.0 (24 Feb 98)
+- do not return STREAM_END prematurely in inflate (John Bowler)
+- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler)
+- compile with -DFASTEST to get compression code optimized for speed only
+- in minigzip, try mmap'ing the input file first (Miguel Albrecht)
+- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain
+  on Sun but significant on HP)
+
+- add a pointer to experimental unzip library in README (Gilles Vollant)
+- initialize variable gcc in configure (Chris Herborth)
+
+Changes in 1.0.9 (17 Feb 1998)
+- added gzputs and gzgets functions
+- do not clear eof flag in gzseek (Mark Diekhans)
+- fix gzseek for files in transparent mode (Mark Diekhans)
+- do not assume that vsprintf returns the number of bytes written (Jens Krinke)
+- replace EXPORT with ZEXPORT to avoid conflict with other programs
+- added compress2 in zconf.h, zlib.def, zlib.dnt
+- new asm code from Gilles Vollant in contrib/asm386
+- simplify the inflate code (Mark):
+ . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new()
+ . ZALLOC the length list in inflate_trees_fixed() instead of using stack
+ . ZALLOC the value area for huft_build() instead of using stack
+ . Simplify Z_FINISH check in inflate()
+
+- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
+- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
+- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
+  the declaration of FAR (Gilles VOllant)
+- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
+- read_buf buf parameter of type Bytef* instead of charf*
+- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
+- do not redeclare unlink in minigzip.c for WIN32 (John Bowler)
+- fix check for presence of directories in "make install" (Ian Willis)
+
+Changes in 1.0.8 (27 Jan 1998)
+- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant)
+- fix gzgetc and gzputc for big endian systems (Markus Oberhumer)
+- added compress2() to allow setting the compression level
+- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
+- use constant arrays for the static trees in trees.c instead of computing
+  them at run time (thanks to Ken Raeburn for this suggestion). To create
+  trees.h, compile with GEN_TREES_H and run "make test".
+- check return code of example in "make test" and display result
+- pass minigzip command line options to file_compress
+- simplifying code of inflateSync to avoid gcc 2.8 bug
+
+- support CC="gcc -Wall" in configure -s (QingLong)
+- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn)
+- fix test for shared library support to avoid compiler warnings
+- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant)
+- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit)
+- do not use fdopen for Metrowerks on Mac (Brad Pettit))
+- add checks for gzputc and gzputc in example.c
+- avoid warnings in gzio.c and deflate.c (Andreas Kleinert)
+- use const for the CRC table (Ken Raeburn)
+- fixed "make uninstall" for shared libraries
+- use Tracev instead of Trace in infblock.c
+- in example.c use correct compressed length for test_sync
+- suppress +vnocompatwarnings in configure for HPUX (not always supported)
+
+Changes in 1.0.7 (20 Jan 1998)
+- fix gzseek which was broken in write mode
+- return error for gzseek to negative absolute position
+- fix configure for Linux (Chun-Chung Chen)
+- increase stack space for MSC (Tim Wegner)
+- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant)
+- define EXPORTVA for gzprintf (Gilles Vollant)
+- added man page zlib.3 (Rick Rodgers)
+- for contrib/untgz, fix makedir() and improve Makefile
+
+- check gzseek in write mode in example.c
+- allocate extra buffer for seeks only if gzseek is actually called
+- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant)
+- add inflateSyncPoint in zconf.h
+- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def
+
+Changes in 1.0.6 (19 Jan 1998)
+- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
+  gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
+- Fix a deflate bug occurring only with compression level 0 (thanks to
+  Andy Buckler for finding this one).
+- In minigzip, pass transparently also the first byte for .Z files.
+- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
+- check Z_FINISH in inflate (thanks to Marc Schluper)
+- Implement deflateCopy (thanks to Adam Costello)
+- make static libraries by default in configure, add --shared option.
+- move MSDOS or Windows specific files to directory msdos
+- suppress the notion of partial flush to simplify the interface
+  (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
+- suppress history buffer provided by application to simplify the interface
+  (this feature was not implemented anyway in 1.0.4)
+- next_in and avail_in must be initialized before calling inflateInit or
+  inflateInit2
+- add EXPORT in all exported functions (for Windows DLL)
+- added Makefile.nt (thanks to Stephen Williams)
+- added the unsupported "contrib" directory:
+   contrib/asm386/ by Gilles Vollant <info@winimage.com>
+        386 asm code replacing longest_match().
+   contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
+        A C++ I/O streams interface to the zlib gz* functions
+   contrib/iostream2/  by Tyge LÃ¸vset <Tyge.Lovset@cmr.no>
+        Another C++ I/O streams interface
+   contrib/untgz/  by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
+        A very simple tar.gz file extractor using zlib
+   contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
+        How to use compress(), uncompress() and the gz* functions from VB.
+- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
+  level) in minigzip (thanks to Tom Lane)
+
+- use const for rommable constants in deflate
+- added test for gzseek and gztell in example.c
+- add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
+- add undocumented function zError to convert error code to string
+  (for Tim Smithers)
+- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.
+- Use default memcpy for Symantec MSDOS compiler.
+- Add EXPORT keyword for check_func (needed for Windows DLL)
+- add current directory to LD_LIBRARY_PATH for "make test"
+- create also a link for libz.so.1
+- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura)
+- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX)
+- added -soname for Linux in configure (Chun-Chung Chen,
+- assign numbers to the exported functions in zlib.def (for Windows DLL)
+- add advice in zlib.h for best usage of deflateSetDictionary
+- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn)
+- allow compilation with ANSI keywords only enabled for TurboC in large model
+- avoid "versionString"[0] (Borland bug)
+- add NEED_DUMMY_RETURN for Borland
+- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
+- allow compilation with CC
+- defined STDC for OS/2 (David Charlap)
+- limit external names to 8 chars for MVS (Thomas Lund)
+- in minigzip.c, use static buffers only for 16-bit systems
+- fix suffix check for "minigzip -d foo.gz"
+- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee)
+- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
+- added makelcc.bat for lcc-win32 (Tom St Denis)
+- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
+- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
+- check for unistd.h in configure (for off_t)
+- remove useless check parameter in inflate_blocks_free
+- avoid useless assignment of s->check to itself in inflate_blocks_new
+- do not flush twice in gzclose (thanks to Ken Raeburn)
+- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h
+- use NO_ERRNO_H instead of enumeration of operating systems with errno.h
+- work around buggy fclose on pipes for HP/UX
+- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson)
+- fix configure if CC is already equal to gcc
+
+Changes in 1.0.5 (3 Jan 98)
+- Fix inflate to terminate gracefully when fed corrupted or invalid data
+- Use const for rommable constants in inflate
+- Eliminate memory leaks on error conditions in inflate
+- Removed some vestigial code in inflate
+- Update web address in README
+
+Changes in 1.0.4 (24 Jul 96)
+- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
+  bit, so the decompressor could decompress all the correct data but went
+  on to attempt decompressing extra garbage data. This affected minigzip too.
+- zlibVersion and gzerror return const char* (needed for DLL)
+- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
+- use z_error only for DEBUG (avoid problem with DLLs)
+
+Changes in 1.0.3 (2 Jul 96)
+- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS
+  small and medium models; this makes the library incompatible with previous
+  versions for these models. (No effect in large model or on other systems.)
+- return OK instead of BUF_ERROR if previous deflate call returned with
+  avail_out as zero but there is nothing to do
+- added memcmp for non STDC compilers
+- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)
+- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)
+- better check for 16-bit mode MSC (avoids problem with Symantec)
+
+Changes in 1.0.2 (23 May 96)
+- added Windows DLL support
+- added a function zlibVersion (for the DLL support)
+- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)
+- Bytef is define's instead of typedef'd only for Borland C
+- avoid reading uninitialized memory in example.c
+- mention in README that the zlib format is now RFC1950
+- updated Makefile.dj2
+- added algorithm.doc
+
+Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
+- fix array overlay in deflate.c which sometimes caused bad compressed data
+- fix inflate bug with empty stored block
+- fix MSDOS medium model which was broken in 0.99
+- fix deflateParams() which could generate bad compressed data.
+- Bytef is define'd instead of typedef'ed (work around Borland bug)
+- added an INDEX file
+- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
+  Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
+- speed up adler32 for modern machines without auto-increment
+- added -ansi for IRIX in configure
+- static_init_done in trees.c is an int
+- define unlink as delete for VMS
+- fix configure for QNX
+- add configure branch for SCO and HPUX
+- avoid many warnings (unused variables, dead assignments, etc...)
+- no fdopen for BeOS
+- fix the Watcom fix for 32 bit mode (define FAR as empty)
+- removed redefinition of Byte for MKWERKS
+- work around an MWKERKS bug (incorrect merge of all .h files)
+
+Changes in 0.99 (27 Jan 96)
+- allow preset dictionary shared between compressor and decompressor
+- allow compression level 0 (no compression)
+- add deflateParams in zlib.h: allow dynamic change of compression level
+  and compression strategy.
+- test large buffers and deflateParams in example.c
+- add optional "configure" to build zlib as a shared library
+- suppress Makefile.qnx, use configure instead
+- fixed deflate for 64-bit systems (detected on Cray)
+- fixed inflate_blocks for 64-bit systems (detected on Alpha)
+- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
+- always return Z_BUF_ERROR when deflate() has nothing to do
+- deflateInit and inflateInit are now macros to allow version checking
+- prefix all global functions and types with z_ with -DZ_PREFIX
+- make falloc completely reentrant (inftrees.c)
+- fixed very unlikely race condition in ct_static_init
+- free in reverse order of allocation to help memory manager
+- use zlib-1.0/* instead of zlib/* inside the tar.gz
+- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
+  -Wconversion -Wstrict-prototypes -Wmissing-prototypes"
+- allow gzread on concatenated .gz files
+- deflateEnd now returns Z_DATA_ERROR if it was premature
+- deflate is finally (?) fully deterministic (no matches beyond end of input)
+- Document Z_SYNC_FLUSH
+- add uninstall in Makefile
+- Check for __cpluplus in zlib.h
+- Better test in ct_align for partial flush
+- avoid harmless warnings for Borland C++
+- initialize hash_head in deflate.c
+- avoid warning on fdopen (gzio.c) for HP cc -Aa
+- include stdlib.h for STDC compilers
+- include errno.h for Cray
+- ignore error if ranlib doesn't exist
+- call ranlib twice for NeXTSTEP
+- use exec_prefix instead of prefix for libz.a
+- renamed ct_* as _tr_* to avoid conflict with applications
+- clear z->msg in inflateInit2 before any error return
+- initialize opaque in example.c, gzio.c, deflate.c and inflate.c
+- fixed typo in zconf.h (_GNUC__ => __GNUC__)
+- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
+- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
+- in fcalloc, normalize pointer if size > 65520 bytes
+- don't use special fcalloc for 32 bit Borland C++
+- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
+- use Z_BINARY instead of BINARY
+- document that gzclose after gzdopen will close the file
+- allow "a" as mode in gzopen.
+- fix error checking in gzread
+- allow skipping .gz extra-field on pipes
+- added reference to Perl interface in README
+- put the crc table in FAR data (I dislike more and more the medium model :)
+- added get_crc_table
+- added a dimension to all arrays (Borland C can't count).
+- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
+- guard against multiple inclusion of *.h (for precompiled header on Mac)
+- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
+- don't use unsized arrays to avoid silly warnings by Visual C++:
+     warning C4746: 'inflate_mask' : unsized array treated as  '__far'
+     (what's wrong with far data in far model?).
+- define enum out of inflate_blocks_state to allow compilation with C++
+
+Changes in 0.95 (16 Aug 95)
+- fix MSDOS small and medium model (now easier to adapt to any compiler)
+- inlined send_bits
+- fix the final (:-) bug for deflate with flush (output was correct but
+  not completely flushed in rare occasions).
+- default window size is same for compression and decompression
+  (it's now sufficient to set MAX_WBITS in zconf.h).
+- voidp -> voidpf and voidnp -> voidp (for consistency with other
+  typedefs and because voidnp was not near in large model).
+
+Changes in 0.94 (13 Aug 95)
+- support MSDOS medium model
+- fix deflate with flush (could sometimes generate bad output)
+- fix deflateReset (zlib header was incorrectly suppressed)
+- added support for VMS
+- allow a compression level in gzopen()
+- gzflush now calls fflush
+- For deflate with flush, flush even if no more input is provided.
+- rename libgz.a as libz.a
+- avoid complex expression in infcodes.c triggering Turbo C bug
+- work around a problem with gcc on Alpha (in INSERT_STRING)
+- don't use inline functions (problem with some gcc versions)
+- allow renaming of Byte, uInt, etc... with #define.
+- avoid warning about (unused) pointer before start of array in deflate.c
+- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
+- avoid reserved word 'new' in trees.c
+
+Changes in 0.93 (25 June 95)
+- temporarily disable inline functions
+- make deflate deterministic
+- give enough lookahead for PARTIAL_FLUSH
+- Set binary mode for stdin/stdout in minigzip.c for OS/2
+- don't even use signed char in inflate (not portable enough)
+- fix inflate memory leak for segmented architectures
+
+Changes in 0.92 (3 May 95)
+- don't assume that char is signed (problem on SGI)
+- Clear bit buffer when starting a stored block
+- no memcpy on Pyramid
+- suppressed inftest.c
+- optimized fill_window, put longest_match inline for gcc
+- optimized inflate on stored blocks.
+- untabify all sources to simplify patches
+
+Changes in 0.91 (2 May 95)
+- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
+- Document the memory requirements in zconf.h
+- added "make install"
+- fix sync search logic in inflateSync
+- deflate(Z_FULL_FLUSH) now works even if output buffer too short
+- after inflateSync, don't scare people with just "lo world"
+- added support for DJGPP
+
+Changes in 0.9 (1 May 95)
+- don't assume that zalloc clears the allocated memory (the TurboC bug
+  was Mark's bug after all :)
+- let again gzread copy uncompressed data unchanged (was working in 0.71)
+- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
+- added a test of inflateSync in example.c
+- moved MAX_WBITS to zconf.h because users might want to change that.
+- document explicitly that zalloc(64K) on MSDOS must return a normalized
+  pointer (zero offset)
+- added Makefiles for Microsoft C, Turbo C, Borland C++
+- faster crc32()
+
+Changes in 0.8 (29 April 95)
+- added fast inflate (inffast.c)
+- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
+  is incompatible with previous versions of zlib which returned Z_OK.
+- work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
+  (actually that was not a compiler bug, see 0.81 above)
+- gzread no longer reads one extra byte in certain cases
+- In gzio destroy(), don't reference a freed structure
+- avoid many warnings for MSDOS
+- avoid the ERROR symbol which is used by MS Windows
+
+Changes in 0.71 (14 April 95)
+- Fixed more MSDOS compilation problems :( There is still a bug with
+  TurboC large model.
+
+Changes in 0.7 (14 April 95)
+- Added full inflate support.
+- Simplified the crc32() interface. The pre- and post-conditioning
+  (one's complement) is now done inside crc32(). WARNING: this is
+  incompatible with previous versions; see zlib.h for the new usage.
+
+Changes in 0.61 (12 April 95)
+- workaround for a bug in TurboC. example and minigzip now work on MSDOS.
+
+Changes in 0.6 (11 April 95)
+- added minigzip.c
+- added gzdopen to reopen a file descriptor as gzFile
+- added transparent reading of non-gziped files in gzread.
+- fixed bug in gzread (don't read crc as data)
+- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
+- don't allocate big arrays in the stack (for MSDOS)
+- fix some MSDOS compilation problems
+
+Changes in 0.5:
+- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
+  not yet Z_FULL_FLUSH.
+- support decompression but only in a single step (forced Z_FINISH)
+- added opaque object for zalloc and zfree.
+- added deflateReset and inflateReset
+- added a variable zlib_version for consistency checking.
+- renamed the 'filter' parameter of deflateInit2 as 'strategy'.
+  Added Z_FILTERED and Z_HUFFMAN_ONLY constants.
+
+Changes in 0.4:
+- avoid "zip" everywhere, use zlib instead of ziplib.
+- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
+  if compression method == 8.
+- added adler32 and crc32
+- renamed deflateOptions as deflateInit2, call one or the other but not both
+- added the method parameter for deflateInit2.
+- added inflateInit2
+- simplied considerably deflateInit and inflateInit by not supporting
+  user-provided history buffer. This is supported only in deflateInit2
+  and inflateInit2.
+
+Changes in 0.3:
+- prefix all macro names with Z_
+- use Z_FINISH instead of deflateEnd to finish compression.
+- added Z_HUFFMAN_ONLY
+- added gzerror()
Index: EcnlProtoTool/trunk/zlib-1.2.11/Debug/Makefile
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/Debug/Makefile	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/Debug/Makefile	(revision 331)
@@ -0,0 +1,410 @@
+# Makefile for zlib
+# Copyright (C) 1995-2017 Jean-loup Gailly, Mark Adler
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile and test, type:
+#    ./configure; make test
+# Normally configure builds both a static and a shared library.
+# If you want to build just a static library, use: ./configure --static
+
+# To use the asm code, type:
+#    cp contrib/asm?86/match.S ./match.S
+#    make LOC=-DASMV OBJA=match.o
+
+# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
+#    make install
+# To install in $HOME instead of /usr/local, use:
+#    make install prefix=$HOME
+
+CC=arm-none-eabi-gcc
+
+CFLAGS=-nostdinc -I../../musl-1.1.18/include -I.. -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing -DSSIZE_MAX=LONG_MAX -D__unix -DNO_FSEEKO -DNO_STRERROR -DNO_vsnprintf -DHAVE_HIDDEN
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-g -DZLIB_DEBUG
+#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+#           -Wstrict-prototypes -Wmissing-prototypes
+
+SFLAGS=-nostdinc -I../../musl-1.1.18/include -I.. -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing -DSSIZE_MAX=LONG_MAX -D__unix -fPIC -DNO_FSEEKO -DNO_STRERROR -DNO_vsnprintf -DHAVE_HIDDEN
+LDFLAGS=-nostdlib -L../../musl-1.1.18/lib -lc -lgcc
+TEST_LDFLAGS=-nostdlib -L../../musl-1.1.18/lib -L. -lc -lgcc libz.a
+LDSHARED=arm-none-eabi-gcc
+CPP=arm-none-eabi-gcc -E
+
+STATICLIB=libz.a
+SHAREDLIB=
+SHAREDLIBV=
+SHAREDLIBM=
+LIBS=$(STATICLIB) $(SHAREDLIBV)
+
+AR=arm-none-eabi-ar
+ARFLAGS=rc
+RANLIB=ranlib
+LDCONFIG=ldconfig
+LDSHAREDLIBC=-lc
+TAR=tar
+SHELL=/bin/sh
+EXE=
+
+prefix =/usr/local
+exec_prefix =${prefix}
+libdir =${exec_prefix}/lib
+sharedlibdir =${libdir}
+includedir =${prefix}/include
+mandir =${prefix}/share/man
+man3dir = ${mandir}/man3
+pkgconfigdir = ${libdir}/pkgconfig
+SRCDIR=../
+ZINC=-include zconf.h
+ZINCOUT=-I. -I$(SRCDIR)
+
+OBJZ = adler32.o crc32.o deflate.o infback.o inffast.o inflate.o inftrees.o trees.o zutil.o
+OBJG = compress.o uncompr.o gzclose.o gzlib.o gzread.o gzwrite.o
+OBJC = $(OBJZ) $(OBJG)
+
+PIC_OBJZ = adler32.lo crc32.lo deflate.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo zutil.lo
+PIC_OBJG = compress.lo uncompr.lo gzclose.lo gzlib.lo gzread.lo gzwrite.lo
+PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG)
+
+# to use the asm code: make OBJA=match.o, PIC_OBJA=match.lo
+OBJA =
+PIC_OBJA =
+
+OBJS = $(OBJC) $(OBJA)
+
+PIC_OBJS = $(PIC_OBJC) $(PIC_OBJA)
+
+all: static
+
+static: example$(EXE) minigzip$(EXE)
+
+shared: examplesh$(EXE) minigzipsh$(EXE)
+
+all64: example64$(EXE) minigzip64$(EXE)
+
+check: test
+
+test: all teststatic
+
+teststatic: static
+	@TMPST=tmpst_$$; \
+	if echo hello world | ./minigzip | ./minigzip -d && ./example $$TMPST ; then \
+	  echo '		*** zlib test OK ***'; \
+	else \
+	  echo '		*** zlib test FAILED ***'; false; \
+	fi; \
+	rm -f $$TMPST
+
+testshared: shared
+	@LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
+	LD_LIBRARYN32_PATH=`pwd`:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \
+	DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \
+	SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \
+	TMPSH=tmpsh_$$; \
+	if echo hello world | ./minigzipsh | ./minigzipsh -d && ./examplesh $$TMPSH; then \
+	  echo '		*** zlib shared test OK ***'; \
+	else \
+	  echo '		*** zlib shared test FAILED ***'; false; \
+	fi; \
+	rm -f $$TMPSH
+
+test64: all64
+	@TMP64=tmp64_$$; \
+	if echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64 $$TMP64; then \
+	  echo '		*** zlib 64-bit test OK ***'; \
+	else \
+	  echo '		*** zlib 64-bit test FAILED ***'; false; \
+	fi; \
+	rm -f $$TMP64
+
+infcover.o: $(SRCDIR)test/infcover.c $(SRCDIR)zlib.h zconf.h
+	$(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/infcover.c
+
+infcover: infcover.o libz.a
+	$(CC) $(CFLAGS) -o $@ infcover.o libz.a
+
+cover: infcover
+	rm -f *.gcda
+	./infcover
+	gcov inf*.c
+
+libz.a: $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+	-@ ($(RANLIB) $@ || true) > nul 2>&1
+
+match.o: match.S
+	$(CPP) match.S > _match.s
+	$(CC) -c _match.s
+	mv _match.o match.o
+	rm -f _match.s
+
+match.lo: match.S
+	$(CPP) match.S > _match.s
+	$(CC) -c -fPIC _match.s
+	mv _match.o match.lo
+	rm -f _match.s
+
+example.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h
+	$(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/example.c
+
+minigzip.o: $(SRCDIR)test/minigzip.c $(SRCDIR)zlib.h zconf.h
+	$(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/minigzip.c
+
+example64.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h
+	$(CC) $(CFLAGS) $(ZINCOUT) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)test/example.c
+
+minigzip64.o: $(SRCDIR)test/minigzip.c $(SRCDIR)zlib.h zconf.h
+	$(CC) $(CFLAGS) $(ZINCOUT) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)test/minigzip.c
+
+
+adler32.o: $(SRCDIR)adler32.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)adler32.c
+
+crc32.o: $(SRCDIR)crc32.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)crc32.c
+
+deflate.o: $(SRCDIR)deflate.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)deflate.c
+
+infback.o: $(SRCDIR)infback.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)infback.c
+
+inffast.o: $(SRCDIR)inffast.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inffast.c
+
+inflate.o: $(SRCDIR)inflate.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inflate.c
+
+inftrees.o: $(SRCDIR)inftrees.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inftrees.c
+
+trees.o: $(SRCDIR)trees.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)trees.c
+
+zutil.o: $(SRCDIR)zutil.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)zutil.c
+
+compress.o: $(SRCDIR)compress.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)compress.c
+
+uncompr.o: $(SRCDIR)uncompr.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)uncompr.c
+
+gzclose.o: $(SRCDIR)gzclose.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzclose.c
+
+gzlib.o: $(SRCDIR)gzlib.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzlib.c
+
+gzread.o: $(SRCDIR)gzread.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzread.c
+
+gzwrite.o: $(SRCDIR)gzwrite.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzwrite.c
+
+
+adler32.lo: $(SRCDIR)adler32.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/adler32.o $(SRCDIR)adler32.c
+	-@mv objs/adler32.o $@
+
+crc32.lo: $(SRCDIR)crc32.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/crc32.o $(SRCDIR)crc32.c
+	-@mv objs/crc32.o $@
+
+deflate.lo: $(SRCDIR)deflate.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/deflate.o $(SRCDIR)deflate.c
+	-@mv objs/deflate.o $@
+
+infback.lo: $(SRCDIR)infback.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/infback.o $(SRCDIR)infback.c
+	-@mv objs/infback.o $@
+
+inffast.lo: $(SRCDIR)inffast.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inffast.o $(SRCDIR)inffast.c
+	-@mv objs/inffast.o $@
+
+inflate.lo: $(SRCDIR)inflate.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inflate.o $(SRCDIR)inflate.c
+	-@mv objs/inflate.o $@
+
+inftrees.lo: $(SRCDIR)inftrees.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inftrees.o $(SRCDIR)inftrees.c
+	-@mv objs/inftrees.o $@
+
+trees.lo: $(SRCDIR)trees.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/trees.o $(SRCDIR)trees.c
+	-@mv objs/trees.o $@
+
+zutil.lo: $(SRCDIR)zutil.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/zutil.o $(SRCDIR)zutil.c
+	-@mv objs/zutil.o $@
+
+compress.lo: $(SRCDIR)compress.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/compress.o $(SRCDIR)compress.c
+	-@mv objs/compress.o $@
+
+uncompr.lo: $(SRCDIR)uncompr.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/uncompr.o $(SRCDIR)uncompr.c
+	-@mv objs/uncompr.o $@
+
+gzclose.lo: $(SRCDIR)gzclose.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzclose.o $(SRCDIR)gzclose.c
+	-@mv objs/gzclose.o $@
+
+gzlib.lo: $(SRCDIR)gzlib.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzlib.o $(SRCDIR)gzlib.c
+	-@mv objs/gzlib.o $@
+
+gzread.lo: $(SRCDIR)gzread.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzread.o $(SRCDIR)gzread.c
+	-@mv objs/gzread.o $@
+
+gzwrite.lo: $(SRCDIR)gzwrite.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzwrite.o $(SRCDIR)gzwrite.c
+	-@mv objs/gzwrite.o $@
+
+
+placebo $(SHAREDLIBV): $(PIC_OBJS) libz.a
+	$(LDSHARED) $(SFLAGS) -o $@ $(PIC_OBJS) $(LDSHAREDLIBC) $(LDFLAGS)
+	rm -f $(SHAREDLIB) $(SHAREDLIBM)
+	ln -s $@ $(SHAREDLIB)
+	ln -s $@ $(SHAREDLIBM)
+	-@rmdir objs
+
+example$(EXE): example.o $(STATICLIB)
+	$(CC) $(CFLAGS) -o $@ example.o $(TEST_LDFLAGS)
+
+minigzip$(EXE): minigzip.o $(STATICLIB)
+	$(CC) $(CFLAGS) -o $@ minigzip.o $(TEST_LDFLAGS)
+
+examplesh$(EXE): example.o $(SHAREDLIBV)
+	$(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDLIBV)
+
+minigzipsh$(EXE): minigzip.o $(SHAREDLIBV)
+	$(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDLIBV)
+
+example64$(EXE): example64.o $(STATICLIB)
+	$(CC) $(CFLAGS) -o $@ example64.o $(TEST_LDFLAGS)
+
+minigzip64$(EXE): minigzip64.o $(STATICLIB)
+	$(CC) $(CFLAGS) -o $@ minigzip64.o $(TEST_LDFLAGS)
+
+install-libs: $(LIBS)
+	-@if [ ! -d $(DESTDIR)$(exec_prefix)  ]; then mkdir -p $(DESTDIR)$(exec_prefix); fi
+	-@if [ ! -d $(DESTDIR)$(libdir)       ]; then mkdir -p $(DESTDIR)$(libdir); fi
+	-@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi
+	-@if [ ! -d $(DESTDIR)$(man3dir)      ]; then mkdir -p $(DESTDIR)$(man3dir); fi
+	-@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi
+	rm -f $(DESTDIR)$(libdir)/$(STATICLIB)
+	cp $(STATICLIB) $(DESTDIR)$(libdir)
+	chmod 644 $(DESTDIR)$(libdir)/$(STATICLIB)
+	-@($(RANLIB) $(DESTDIR)$(libdir)/libz.a || true) >/dev/null 2>&1
+	-@if test -n "$(SHAREDLIBV)"; then \
+	  rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \
+	  cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir); \
+	  echo "cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)"; \
+	  chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \
+	  echo "chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV)"; \
+	  rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \
+	  ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB); \
+	  ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \
+	  ($(LDCONFIG) || true)  >/dev/null 2>&1; \
+	fi
+	rm -f $(DESTDIR)$(man3dir)/zlib.3
+	cp $(SRCDIR)zlib.3 $(DESTDIR)$(man3dir)
+	chmod 644 $(DESTDIR)$(man3dir)/zlib.3
+	rm -f $(DESTDIR)$(pkgconfigdir)/zlib.pc
+	cp zlib.pc $(DESTDIR)$(pkgconfigdir)
+	chmod 644 $(DESTDIR)$(pkgconfigdir)/zlib.pc
+# The ranlib in install is needed on NeXTSTEP which checks file times
+# ldconfig is for Linux
+
+install: install-libs
+	-@if [ ! -d $(DESTDIR)$(includedir)   ]; then mkdir -p $(DESTDIR)$(includedir); fi
+	rm -f $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h
+	cp $(SRCDIR)zlib.h zconf.h $(DESTDIR)$(includedir)
+	chmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h
+
+uninstall:
+	cd $(DESTDIR)$(includedir) && rm -f zlib.h zconf.h
+	cd $(DESTDIR)$(libdir) && rm -f libz.a; \
+	if test -n "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \
+	  rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \
+	fi
+	cd $(DESTDIR)$(man3dir) && rm -f zlib.3
+	cd $(DESTDIR)$(pkgconfigdir) && rm -f zlib.pc
+
+docs: zlib.3.pdf
+
+zlib.3.pdf: $(SRCDIR)zlib.3
+	groff -mandoc -f H -T ps $(SRCDIR)zlib.3 | ps2pdf - $@
+
+zconf.h.cmakein: $(SRCDIR)zconf.h.in
+	-@ TEMPFILE=zconfh_$$; \
+	echo "/#define ZCONF_H/ a\\\\\n#cmakedefine Z_PREFIX\\\\\n#cmakedefine Z_HAVE_UNISTD_H\n" >> $$TEMPFILE &&\
+	sed -f $$TEMPFILE $(SRCDIR)zconf.h.in > $@ &&\
+	touch -r $(SRCDIR)zconf.h.in $@ &&\
+	rm $$TEMPFILE
+
+zconf: $(SRCDIR)zconf.h.in
+	cp -p $(SRCDIR)zconf.h.in zconf.h
+
+mostlyclean: clean
+clean:
+	rm -f *.o *.lo *~ \
+	   example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \
+	   example64$(EXE) minigzip64$(EXE) \
+	   infcover \
+	   libz.* foo.gz so_locations \
+	   _match.s maketree contrib/infback9/*.o
+	rm -rf objs
+	rm -f *.gcda *.gcno *.gcov
+	rm -f contrib/infback9/*.gcda contrib/infback9/*.gcno contrib/infback9/*.gcov
+
+maintainer-clean: distclean
+distclean: clean zconf zconf.h.cmakein docs
+	rm -f Makefile zlib.pc configure.log
+	-@rm -f .DS_Store
+	@if [ -f Makefile.in ]; then \
+	printf 'all:\n\t-@echo "Please use ./configure first.  Thank you."\n' > Makefile ; \
+	printf '\ndistclean:\n\tmake -f Makefile.in distclean\n' >> Makefile ; \
+	touch -r $(SRCDIR)Makefile.in Makefile ; fi
+	@if [ ! -f zconf.h.in ]; then rm -f zconf.h zconf.h.cmakein ; fi
+	@if [ ! -f zlib.3 ]; then rm -f zlib.3.pdf ; fi
+
+tags:
+	etags $(SRCDIR)*.[ch]
+
+adler32.o zutil.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h
+gzclose.o gzlib.o gzread.o gzwrite.o: $(SRCDIR)zlib.h zconf.h $(SRCDIR)gzguts.h
+compress.o example.o minigzip.o uncompr.o: $(SRCDIR)zlib.h zconf.h
+crc32.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)crc32.h
+deflate.o: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h
+infback.o inflate.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h $(SRCDIR)inffixed.h
+inffast.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h
+inftrees.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h
+trees.o: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)trees.h
+
+adler32.lo zutil.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h
+gzclose.lo gzlib.lo gzread.lo gzwrite.lo: $(SRCDIR)zlib.h zconf.h $(SRCDIR)gzguts.h
+compress.lo example.lo minigzip.lo uncompr.lo: $(SRCDIR)zlib.h zconf.h
+crc32.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)crc32.h
+deflate.lo: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h
+infback.lo inflate.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h $(SRCDIR)inffixed.h
+inffast.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h
+inftrees.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h
+trees.lo: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)trees.h
Index: EcnlProtoTool/trunk/zlib-1.2.11/Debug/configure.log
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/Debug/configure.log	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/Debug/configure.log	(revision 331)
@@ -0,0 +1,201 @@
+--------------------
+../configure --static
+2017å¹´  5æ 16æ¥ ç«ææ¥ 23:15:14 DST
+=== ztest52.c ===
+extern int getchar();
+int hello() {return getchar();}
+===
+arm-none-eabi-gcc -c ztest52.c
+... using gcc
+
+Checking for obsessive-compulsive compiler options...
+=== ztest52.c ===
+int foo() { return 0; }
+===
+arm-none-eabi-gcc -c -I../musl-1.1.12/include -I../zlib-1.2.11 -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing -DSSIZE_MAX=LONG_MAX -D__unix ztest52.c
+
+Building static library libz.a version 1.2.11 with arm-none-eabi-gcc.
+
+=== ztest52.c ===
+#include <stdio.h>
+#include <stdlib.h>
+size_t dummy = 0;
+===
+arm-none-eabi-gcc -c -I../musl-1.1.12/include -I../zlib-1.2.11 -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing -DSSIZE_MAX=LONG_MAX -D__unix ztest52.c
+Checking for size_t... Yes.
+
+
+=== ztest52.c ===
+#include <sys/types.h>
+off64_t dummy = 0;
+===
+arm-none-eabi-gcc -c -I../musl-1.1.12/include -I../zlib-1.2.11 -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing -DSSIZE_MAX=LONG_MAX -D__unix -D_LARGEFILE64_SOURCE=1 ztest52.c
+ztest52.c:2:1: error: unknown type name 'off64_t'
+ off64_t dummy = 0;
+ ^
+(exit code 1)
+Checking for off64_t... No.
+
+=== ztest52.c ===
+#include <stdio.h>
+int main(void) {
+  fseeko(NULL, 0, 0);
+  return 0;
+}
+===
+arm-none-eabi-gcc -I../musl-1.1.12/include -I../zlib-1.2.11 -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing -DSSIZE_MAX=LONG_MAX -D__unix -o ztest52 ztest52.c
+/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/armv7-ar/thumb/fpu/libc.a(lib_a-exit.o): In function `exit':
+/build/newlib-5zwpxE/newlib-2.2.0+git20150830.5a3d536/build/arm-none-eabi/armv7-ar/thumb/fpu/newlib/libc/stdlib/../../../../../../../../newlib/libc/stdlib/exit.c:70: undefined reference to `_exit'
+/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/armv7-ar/thumb/fpu/libc.a(lib_a-fstatr.o): In function `_fstat_r':
+/build/newlib-5zwpxE/newlib-2.2.0+git20150830.5a3d536/build/arm-none-eabi/armv7-ar/thumb/fpu/newlib/libc/reent/../../../../../../../../newlib/libc/reent/fstatr.c:62: undefined reference to `_fstat'
+/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/armv7-ar/thumb/fpu/libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
+/build/newlib-5zwpxE/newlib-2.2.0+git20150830.5a3d536/build/arm-none-eabi/armv7-ar/thumb/fpu/newlib/libc/reent/../../../../../../../../newlib/libc/reent/sbrkr.c:58: undefined reference to `_sbrk'
+/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/armv7-ar/thumb/fpu/libc.a(lib_a-writer.o): In function `_write_r':
+/build/newlib-5zwpxE/newlib-2.2.0+git20150830.5a3d536/build/arm-none-eabi/armv7-ar/thumb/fpu/newlib/libc/reent/../../../../../../../../newlib/libc/reent/writer.c:58: undefined reference to `_write'
+/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/armv7-ar/thumb/fpu/libc.a(lib_a-closer.o): In function `_close_r':
+/build/newlib-5zwpxE/newlib-2.2.0+git20150830.5a3d536/build/arm-none-eabi/armv7-ar/thumb/fpu/newlib/libc/reent/../../../../../../../../newlib/libc/reent/closer.c:53: undefined reference to `_close'
+/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/armv7-ar/thumb/fpu/libc.a(lib_a-isattyr.o): In function `_isatty_r':
+/build/newlib-5zwpxE/newlib-2.2.0+git20150830.5a3d536/build/arm-none-eabi/armv7-ar/thumb/fpu/newlib/libc/reent/../../../../../../../../newlib/libc/reent/isattyr.c:58: undefined reference to `_isatty'
+/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/armv7-ar/thumb/fpu/libc.a(lib_a-lseekr.o): In function `_lseek_r':
+/build/newlib-5zwpxE/newlib-2.2.0+git20150830.5a3d536/build/arm-none-eabi/armv7-ar/thumb/fpu/newlib/libc/reent/../../../../../../../../newlib/libc/reent/lseekr.c:58: undefined reference to `_lseek'
+/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/armv7-ar/thumb/fpu/libc.a(lib_a-readr.o): In function `_read_r':
+/build/newlib-5zwpxE/newlib-2.2.0+git20150830.5a3d536/build/arm-none-eabi/armv7-ar/thumb/fpu/newlib/libc/reent/../../../../../../../../newlib/libc/reent/readr.c:58: undefined reference to `_read'
+collect2: error: ld returned 1 exit status
+(exit code 1)
+Checking for fseeko... No.
+
+=== ztest52.c ===
+#include <string.h>
+#include <errno.h>
+int main() { return strlen(strerror(errno)); }
+===
+arm-none-eabi-gcc -I../musl-1.1.12/include -I../zlib-1.2.11 -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing -DSSIZE_MAX=LONG_MAX -D__unix -DNO_FSEEKO -o ztest52 ztest52.c
+/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/armv7-ar/thumb/fpu/libc.a(lib_a-exit.o): In function `exit':
+/build/newlib-5zwpxE/newlib-2.2.0+git20150830.5a3d536/build/arm-none-eabi/armv7-ar/thumb/fpu/newlib/libc/stdlib/../../../../../../../../newlib/libc/stdlib/exit.c:70: undefined reference to `_exit'
+collect2: error: ld returned 1 exit status
+(exit code 1)
+Checking for strerror... No.
+
+=== ztest52.c ===
+#include <unistd.h>
+int main() { return 0; }
+===
+arm-none-eabi-gcc -c -I../musl-1.1.12/include -I../zlib-1.2.11 -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing -DSSIZE_MAX=LONG_MAX -D__unix -DNO_FSEEKO -DNO_STRERROR ztest52.c
+Checking for unistd.h... Yes.
+
+=== ztest52.c ===
+#include <stdarg.h>
+int main() { return 0; }
+===
+arm-none-eabi-gcc -c -I../musl-1.1.12/include -I../zlib-1.2.11 -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing -DSSIZE_MAX=LONG_MAX -D__unix -DNO_FSEEKO -DNO_STRERROR ztest52.c
+Checking for stdarg.h... Yes.
+
+=== ztest52.c ===
+#include <stdio.h>
+#include <stdarg.h>
+#include "zconf.h"
+int main()
+{
+#ifndef STDC
+  choke me
+#endif
+  return 0;
+}
+===
+arm-none-eabi-gcc -c -I../musl-1.1.12/include -I../zlib-1.2.11 -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing -DSSIZE_MAX=LONG_MAX -D__unix -DNO_FSEEKO -DNO_STRERROR ztest52.c
+Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf().
+
+=== ztest52.c ===
+#include <stdio.h>
+#include <stdarg.h>
+int mytest(const char *fmt, ...)
+{
+  char buf[20];
+  va_list ap;
+  va_start(ap, fmt);
+  vsnprintf(buf, sizeof(buf), fmt, ap);
+  va_end(ap);
+  return 0;
+}
+int main()
+{
+  return (mytest("Hello%d\n", 1));
+}
+===
+arm-none-eabi-gcc -I../musl-1.1.12/include -I../zlib-1.2.11 -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing -DSSIZE_MAX=LONG_MAX -D__unix -DNO_FSEEKO -DNO_STRERROR -o ztest52 ztest52.c
+/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/armv7-ar/thumb/fpu/libc.a(lib_a-exit.o): In function `exit':
+/build/newlib-5zwpxE/newlib-2.2.0+git20150830.5a3d536/build/arm-none-eabi/armv7-ar/thumb/fpu/newlib/libc/stdlib/../../../../../../../../newlib/libc/stdlib/exit.c:70: undefined reference to `_exit'
+/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/armv7-ar/thumb/fpu/libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
+/build/newlib-5zwpxE/newlib-2.2.0+git20150830.5a3d536/build/arm-none-eabi/armv7-ar/thumb/fpu/newlib/libc/reent/../../../../../../../../newlib/libc/reent/sbrkr.c:58: undefined reference to `_sbrk'
+collect2: error: ld returned 1 exit status
+(exit code 1)
+Checking for vsnprintf() in stdio.h... No.
+  WARNING: vsnprintf() not found, falling back to vsprintf(). zlib
+  can build but will be open to possible buffer-overflow security
+  vulnerabilities.
+
+=== ztest52.c ===
+#include <stdio.h>
+#include <stdarg.h>
+int mytest(const char *fmt, ...)
+{
+  int n;
+  char buf[20];
+  va_list ap;
+  va_start(ap, fmt);
+  n = vsprintf(buf, fmt, ap);
+  va_end(ap);
+  return n;
+}
+int main()
+{
+  return (mytest("Hello%d\n", 1));
+}
+===
+arm-none-eabi-gcc -c -I../musl-1.1.12/include -I../zlib-1.2.11 -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing -DSSIZE_MAX=LONG_MAX -D__unix -DNO_FSEEKO -DNO_STRERROR -DNO_vsnprintf ztest52.c
+Checking for return value of vsprintf()... Yes.
+
+=== ztest52.c ===
+#define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+int ZLIB_INTERNAL foo;
+int main()
+{
+  return 0;
+}
+===
+arm-none-eabi-gcc -c -I../musl-1.1.12/include -I../zlib-1.2.11 -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing -DSSIZE_MAX=LONG_MAX -D__unix -DNO_FSEEKO -DNO_STRERROR -DNO_vsnprintf ztest52.c
+Checking for attribute(visibility) support... Yes.
+
+ALL = static
+AR = ar
+ARFLAGS = rc
+CC = arm-none-eabi-gcc
+CFLAGS = -I../musl-1.1.12/include -I../zlib-1.2.11 -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing -DSSIZE_MAX=LONG_MAX -D__unix -DNO_FSEEKO -DNO_STRERROR -DNO_vsnprintf -DHAVE_HIDDEN
+CPP = arm-none-eabi-gcc -E
+EXE =
+LDCONFIG = ldconfig
+LDFLAGS =
+LDSHARED = arm-none-eabi-gcc
+LDSHAREDLIBC = -lc
+OBJC = $(OBJZ) $(OBJG)
+PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG)
+RANLIB = ranlib
+SFLAGS = -I../musl-1.1.12/include -I../zlib-1.2.11 -mlittle-endian -mcpu=cortex-a9 -mthumb -mthumb-interwork -marm -march=armv7-a -mfpu=vfpv3 -mfloat-abi=hard -mno-unaligned-access -fno-strict-aliasing -DSSIZE_MAX=LONG_MAX -D__unix -fPIC -DNO_FSEEKO -DNO_STRERROR -DNO_vsnprintf -DHAVE_HIDDEN
+SHAREDLIB =
+SHAREDLIBM =
+SHAREDLIBV =
+STATICLIB = libz.a
+TEST = all teststatic
+VER = 1.2.11
+Z_U4 =
+SRCDIR = ../
+exec_prefix = ${prefix}
+includedir = ${prefix}/include
+libdir = ${exec_prefix}/lib
+mandir = ${prefix}/share/man
+prefix = /usr/local
+sharedlibdir = ${libdir}
+uname = Linux
+--------------------
+
+
Index: EcnlProtoTool/trunk/zlib-1.2.11/Debug/zconf.h
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/Debug/zconf.h	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/Debug/zconf.h	(revision 331)
@@ -0,0 +1,534 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */
+#  define Z_PREFIX_SET
+
+/* all linked symbols and init macros */
+#  define _dist_code            z__dist_code
+#  define _length_code          z__length_code
+#  define _tr_align             z__tr_align
+#  define _tr_flush_bits        z__tr_flush_bits
+#  define _tr_flush_block       z__tr_flush_block
+#  define _tr_init              z__tr_init
+#  define _tr_stored_block      z__tr_stored_block
+#  define _tr_tally             z__tr_tally
+#  define adler32               z_adler32
+#  define adler32_combine       z_adler32_combine
+#  define adler32_combine64     z_adler32_combine64
+#  define adler32_z             z_adler32_z
+#  ifndef Z_SOLO
+#    define compress              z_compress
+#    define compress2             z_compress2
+#    define compressBound         z_compressBound
+#  endif
+#  define crc32                 z_crc32
+#  define crc32_combine         z_crc32_combine
+#  define crc32_combine64       z_crc32_combine64
+#  define crc32_z               z_crc32_z
+#  define deflate               z_deflate
+#  define deflateBound          z_deflateBound
+#  define deflateCopy           z_deflateCopy
+#  define deflateEnd            z_deflateEnd
+#  define deflateGetDictionary  z_deflateGetDictionary
+#  define deflateInit           z_deflateInit
+#  define deflateInit2          z_deflateInit2
+#  define deflateInit2_         z_deflateInit2_
+#  define deflateInit_          z_deflateInit_
+#  define deflateParams         z_deflateParams
+#  define deflatePending        z_deflatePending
+#  define deflatePrime          z_deflatePrime
+#  define deflateReset          z_deflateReset
+#  define deflateResetKeep      z_deflateResetKeep
+#  define deflateSetDictionary  z_deflateSetDictionary
+#  define deflateSetHeader      z_deflateSetHeader
+#  define deflateTune           z_deflateTune
+#  define deflate_copyright     z_deflate_copyright
+#  define get_crc_table         z_get_crc_table
+#  ifndef Z_SOLO
+#    define gz_error              z_gz_error
+#    define gz_intmax             z_gz_intmax
+#    define gz_strwinerror        z_gz_strwinerror
+#    define gzbuffer              z_gzbuffer
+#    define gzclearerr            z_gzclearerr
+#    define gzclose               z_gzclose
+#    define gzclose_r             z_gzclose_r
+#    define gzclose_w             z_gzclose_w
+#    define gzdirect              z_gzdirect
+#    define gzdopen               z_gzdopen
+#    define gzeof                 z_gzeof
+#    define gzerror               z_gzerror
+#    define gzflush               z_gzflush
+#    define gzfread               z_gzfread
+#    define gzfwrite              z_gzfwrite
+#    define gzgetc                z_gzgetc
+#    define gzgetc_               z_gzgetc_
+#    define gzgets                z_gzgets
+#    define gzoffset              z_gzoffset
+#    define gzoffset64            z_gzoffset64
+#    define gzopen                z_gzopen
+#    define gzopen64              z_gzopen64
+#    ifdef _WIN32
+#      define gzopen_w              z_gzopen_w
+#    endif
+#    define gzprintf              z_gzprintf
+#    define gzputc                z_gzputc
+#    define gzputs                z_gzputs
+#    define gzread                z_gzread
+#    define gzrewind              z_gzrewind
+#    define gzseek                z_gzseek
+#    define gzseek64              z_gzseek64
+#    define gzsetparams           z_gzsetparams
+#    define gztell                z_gztell
+#    define gztell64              z_gztell64
+#    define gzungetc              z_gzungetc
+#    define gzvprintf             z_gzvprintf
+#    define gzwrite               z_gzwrite
+#  endif
+#  define inflate               z_inflate
+#  define inflateBack           z_inflateBack
+#  define inflateBackEnd        z_inflateBackEnd
+#  define inflateBackInit       z_inflateBackInit
+#  define inflateBackInit_      z_inflateBackInit_
+#  define inflateCodesUsed      z_inflateCodesUsed
+#  define inflateCopy           z_inflateCopy
+#  define inflateEnd            z_inflateEnd
+#  define inflateGetDictionary  z_inflateGetDictionary
+#  define inflateGetHeader      z_inflateGetHeader
+#  define inflateInit           z_inflateInit
+#  define inflateInit2          z_inflateInit2
+#  define inflateInit2_         z_inflateInit2_
+#  define inflateInit_          z_inflateInit_
+#  define inflateMark           z_inflateMark
+#  define inflatePrime          z_inflatePrime
+#  define inflateReset          z_inflateReset
+#  define inflateReset2         z_inflateReset2
+#  define inflateResetKeep      z_inflateResetKeep
+#  define inflateSetDictionary  z_inflateSetDictionary
+#  define inflateSync           z_inflateSync
+#  define inflateSyncPoint      z_inflateSyncPoint
+#  define inflateUndermine      z_inflateUndermine
+#  define inflateValidate       z_inflateValidate
+#  define inflate_copyright     z_inflate_copyright
+#  define inflate_fast          z_inflate_fast
+#  define inflate_table         z_inflate_table
+#  ifndef Z_SOLO
+#    define uncompress            z_uncompress
+#    define uncompress2           z_uncompress2
+#  endif
+#  define zError                z_zError
+#  ifndef Z_SOLO
+#    define zcalloc               z_zcalloc
+#    define zcfree                z_zcfree
+#  endif
+#  define zlibCompileFlags      z_zlibCompileFlags
+#  define zlibVersion           z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+#  define Byte                  z_Byte
+#  define Bytef                 z_Bytef
+#  define alloc_func            z_alloc_func
+#  define charf                 z_charf
+#  define free_func             z_free_func
+#  ifndef Z_SOLO
+#    define gzFile                z_gzFile
+#  endif
+#  define gz_header             z_gz_header
+#  define gz_headerp            z_gz_headerp
+#  define in_func               z_in_func
+#  define intf                  z_intf
+#  define out_func              z_out_func
+#  define uInt                  z_uInt
+#  define uIntf                 z_uIntf
+#  define uLong                 z_uLong
+#  define uLongf                z_uLongf
+#  define voidp                 z_voidp
+#  define voidpc                z_voidpc
+#  define voidpf                z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+#  define gz_header_s           z_gz_header_s
+#  define internal_state        z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#  ifndef STDC
+#    define STDC
+#  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const       /* note: need a more gentle solution here */
+#  endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+#  define z_const const
+#else
+#  define z_const
+#endif
+
+#ifdef Z_SOLO
+   typedef unsigned long z_size_t;
+#else
+#  define z_longlong long long
+#  if defined(NO_SIZE_T)
+     typedef unsigned NO_SIZE_T z_size_t;
+#  elif defined(STDC)
+#    include <stddef.h>
+     typedef size_t z_size_t;
+#  else
+     typedef unsigned long z_size_t;
+#  endif
+#  undef z_longlong
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus about 7 kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+#  if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#    define Z_ARG(args)  args
+#  else
+#    define Z_ARG(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
+#    else
+#      define ZEXPORTVA FAR CDECL
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
+#else
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
+#endif
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+#  include <limits.h>
+#  if (UINT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned
+#  elif (ULONG_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned long
+#  elif (USHRT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned short
+#  endif
+#endif
+
+#ifdef Z_U4
+   typedef Z_U4 z_crc_t;
+#else
+   typedef unsigned long z_crc_t;
+#endif
+
+#if 1    /* was set to #if 1 by ./configure */
+#  define Z_HAVE_UNISTD_H
+#endif
+
+#if 1    /* was set to #if 1 by ./configure */
+#  define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+#  ifndef Z_SOLO
+#    include <sys/types.h>      /* for off_t */
+#  endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifndef Z_SOLO
+#    include <stdarg.h>         /* for va_list */
+#  endif
+#endif
+
+#ifdef _WIN32
+#  ifndef Z_SOLO
+#    include <stddef.h>         /* for wchar_t */
+#  endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+#  undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+#  define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+#  if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+#    include <unistd.h>         /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+#    ifdef VMS
+#      include <unixio.h>       /* for off_t */
+#    endif
+#    ifndef z_off_t
+#      define z_off_t off_t
+#    endif
+#  endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+#  define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+#  define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+#  define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+#  define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+#  define z_off64_t off64_t
+#else
+#  if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+#    define z_off64_t __int64
+#  else
+#    define z_off64_t z_off_t
+#  endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+  #pragma map(deflateInit_,"DEIN")
+  #pragma map(deflateInit2_,"DEIN2")
+  #pragma map(deflateEnd,"DEEND")
+  #pragma map(deflateBound,"DEBND")
+  #pragma map(inflateInit_,"ININ")
+  #pragma map(inflateInit2_,"ININ2")
+  #pragma map(inflateEnd,"INEND")
+  #pragma map(inflateSync,"INSY")
+  #pragma map(inflateSetDictionary,"INSEDI")
+  #pragma map(compressBound,"CMBND")
+  #pragma map(inflate_table,"INTABL")
+  #pragma map(inflate_fast,"INFA")
+  #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
Index: EcnlProtoTool/trunk/zlib-1.2.11/Debug/zlib.pc
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/Debug/zlib.pc	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/Debug/zlib.pc	(revision 331)
@@ -0,0 +1,13 @@
+prefix=/usr/local
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+sharedlibdir=${libdir}
+includedir=${prefix}/include
+
+Name: zlib
+Description: zlib compression library
+Version: 1.2.11
+
+Requires:
+Libs: -L${libdir} -L${sharedlibdir} -lz
+Cflags: -I${includedir}
Index: EcnlProtoTool/trunk/zlib-1.2.11/FAQ
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/FAQ	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/FAQ	(revision 331)
@@ -0,0 +1,368 @@
+
+                Frequently Asked Questions about zlib
+
+
+If your question is not there, please check the zlib home page
+http://zlib.net/ which may have more recent information.
+The lastest zlib FAQ is at http://zlib.net/zlib_faq.html
+
+
+ 1. Is zlib Y2K-compliant?
+
+    Yes. zlib doesn't handle dates.
+
+ 2. Where can I get a Windows DLL version?
+
+    The zlib sources can be compiled without change to produce a DLL.  See the
+    file win32/DLL_FAQ.txt in the zlib distribution.  Pointers to the
+    precompiled DLL are found in the zlib web site at http://zlib.net/ .
+
+ 3. Where can I get a Visual Basic interface to zlib?
+
+    See
+        * http://marknelson.us/1997/01/01/zlib-engine/
+        * win32/DLL_FAQ.txt in the zlib distribution
+
+ 4. compress() returns Z_BUF_ERROR.
+
+    Make sure that before the call of compress(), the length of the compressed
+    buffer is equal to the available size of the compressed buffer and not
+    zero.  For Visual Basic, check that this parameter is passed by reference
+    ("as any"), not by value ("as long").
+
+ 5. deflate() or inflate() returns Z_BUF_ERROR.
+
+    Before making the call, make sure that avail_in and avail_out are not zero.
+    When setting the parameter flush equal to Z_FINISH, also make sure that
+    avail_out is big enough to allow processing all pending input.  Note that a
+    Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be
+    made with more input or output space.  A Z_BUF_ERROR may in fact be
+    unavoidable depending on how the functions are used, since it is not
+    possible to tell whether or not there is more output pending when
+    strm.avail_out returns with zero.  See http://zlib.net/zlib_how.html for a
+    heavily annotated example.
+
+ 6. Where's the zlib documentation (man pages, etc.)?
+
+    It's in zlib.h .  Examples of zlib usage are in the files test/example.c
+    and test/minigzip.c, with more in examples/ .
+
+ 7. Why don't you use GNU autoconf or libtool or ...?
+
+    Because we would like to keep zlib as a very small and simple package.
+    zlib is rather portable and doesn't need much configuration.
+
+ 8. I found a bug in zlib.
+
+    Most of the time, such problems are due to an incorrect usage of zlib.
+    Please try to reproduce the problem with a small program and send the
+    corresponding source to us at zlib@gzip.org .  Do not send multi-megabyte
+    data files without prior agreement.
+
+ 9. Why do I get "undefined reference to gzputc"?
+
+    If "make test" produces something like
+
+       example.o(.text+0x154): undefined reference to `gzputc'
+
+    check that you don't have old files libz.* in /usr/lib, /usr/local/lib or
+    /usr/X11R6/lib. Remove any old versions, then do "make install".
+
+10. I need a Delphi interface to zlib.
+
+    See the contrib/delphi directory in the zlib distribution.
+
+11. Can zlib handle .zip archives?
+
+    Not by itself, no.  See the directory contrib/minizip in the zlib
+    distribution.
+
+12. Can zlib handle .Z files?
+
+    No, sorry.  You have to spawn an uncompress or gunzip subprocess, or adapt
+    the code of uncompress on your own.
+
+13. How can I make a Unix shared library?
+
+    By default a shared (and a static) library is built for Unix.  So:
+
+    make distclean
+    ./configure
+    make
+
+14. How do I install a shared zlib library on Unix?
+
+    After the above, then:
+
+    make install
+
+    However, many flavors of Unix come with a shared zlib already installed.
+    Before going to the trouble of compiling a shared version of zlib and
+    trying to install it, you may want to check if it's already there!  If you
+    can #include <zlib.h>, it's there.  The -lz option will probably link to
+    it.  You can check the version at the top of zlib.h or with the
+    ZLIB_VERSION symbol defined in zlib.h .
+
+15. I have a question about OttoPDF.
+
+    We are not the authors of OttoPDF. The real author is on the OttoPDF web
+    site: Joel Hainley, jhainley@myndkryme.com.
+
+16. Can zlib decode Flate data in an Adobe PDF file?
+
+    Yes. See http://www.pdflib.com/ . To modify PDF forms, see
+    http://sourceforge.net/projects/acroformtool/ .
+
+17. Why am I getting this "register_frame_info not found" error on Solaris?
+
+    After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib
+    generates an error such as:
+
+        ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so:
+        symbol __register_frame_info: referenced symbol not found
+
+    The symbol __register_frame_info is not part of zlib, it is generated by
+    the C compiler (cc or gcc).  You must recompile applications using zlib
+    which have this problem.  This problem is specific to Solaris.  See
+    http://www.sunfreeware.com for Solaris versions of zlib and applications
+    using zlib.
+
+18. Why does gzip give an error on a file I make with compress/deflate?
+
+    The compress and deflate functions produce data in the zlib format, which
+    is different and incompatible with the gzip format.  The gz* functions in
+    zlib on the other hand use the gzip format.  Both the zlib and gzip formats
+    use the same compressed data format internally, but have different headers
+    and trailers around the compressed data.
+
+19. Ok, so why are there two different formats?
+
+    The gzip format was designed to retain the directory information about a
+    single file, such as the name and last modification date.  The zlib format
+    on the other hand was designed for in-memory and communication channel
+    applications, and has a much more compact header and trailer and uses a
+    faster integrity check than gzip.
+
+20. Well that's nice, but how do I make a gzip file in memory?
+
+    You can request that deflate write the gzip format instead of the zlib
+    format using deflateInit2().  You can also request that inflate decode the
+    gzip format using inflateInit2().  Read zlib.h for more details.
+
+21. Is zlib thread-safe?
+
+    Yes.  However any library routines that zlib uses and any application-
+    provided memory allocation routines must also be thread-safe.  zlib's gz*
+    functions use stdio library routines, and most of zlib's functions use the
+    library memory allocation routines by default.  zlib's *Init* functions
+    allow for the application to provide custom memory allocation routines.
+
+    Of course, you should only operate on any given zlib or gzip stream from a
+    single thread at a time.
+
+22. Can I use zlib in my commercial application?
+
+    Yes.  Please read the license in zlib.h.
+
+23. Is zlib under the GNU license?
+
+    No.  Please read the license in zlib.h.
+
+24. The license says that altered source versions must be "plainly marked". So
+    what exactly do I need to do to meet that requirement?
+
+    You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h.  In
+    particular, the final version number needs to be changed to "f", and an
+    identification string should be appended to ZLIB_VERSION.  Version numbers
+    x.x.x.f are reserved for modifications to zlib by others than the zlib
+    maintainers.  For example, if the version of the base zlib you are altering
+    is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and
+    ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3".  You can also
+    update the version strings in deflate.c and inftrees.c.
+
+    For altered source distributions, you should also note the origin and
+    nature of the changes in zlib.h, as well as in ChangeLog and README, along
+    with the dates of the alterations.  The origin should include at least your
+    name (or your company's name), and an email address to contact for help or
+    issues with the library.
+
+    Note that distributing a compiled zlib library along with zlib.h and
+    zconf.h is also a source distribution, and so you should change
+    ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes
+    in zlib.h as you would for a full source distribution.
+
+25. Will zlib work on a big-endian or little-endian architecture, and can I
+    exchange compressed data between them?
+
+    Yes and yes.
+
+26. Will zlib work on a 64-bit machine?
+
+    Yes.  It has been tested on 64-bit machines, and has no dependence on any
+    data types being limited to 32-bits in length.  If you have any
+    difficulties, please provide a complete problem report to zlib@gzip.org
+
+27. Will zlib decompress data from the PKWare Data Compression Library?
+
+    No.  The PKWare DCL uses a completely different compressed data format than
+    does PKZIP and zlib.  However, you can look in zlib's contrib/blast
+    directory for a possible solution to your problem.
+
+28. Can I access data randomly in a compressed stream?
+
+    No, not without some preparation.  If when compressing you periodically use
+    Z_FULL_FLUSH, carefully write all the pending data at those points, and
+    keep an index of those locations, then you can start decompression at those
+    points.  You have to be careful to not use Z_FULL_FLUSH too often, since it
+    can significantly degrade compression.  Alternatively, you can scan a
+    deflate stream once to generate an index, and then use that index for
+    random access.  See examples/zran.c .
+
+29. Does zlib work on MVS, OS/390, CICS, etc.?
+
+    It has in the past, but we have not heard of any recent evidence.  There
+    were working ports of zlib 1.1.4 to MVS, but those links no longer work.
+    If you know of recent, successful applications of zlib on these operating
+    systems, please let us know.  Thanks.
+
+30. Is there some simpler, easier to read version of inflate I can look at to
+    understand the deflate format?
+
+    First off, you should read RFC 1951.  Second, yes.  Look in zlib's
+    contrib/puff directory.
+
+31. Does zlib infringe on any patents?
+
+    As far as we know, no.  In fact, that was originally the whole point behind
+    zlib.  Look here for some more information:
+
+    http://www.gzip.org/#faq11
+
+32. Can zlib work with greater than 4 GB of data?
+
+    Yes.  inflate() and deflate() will process any amount of data correctly.
+    Each call of inflate() or deflate() is limited to input and output chunks
+    of the maximum value that can be stored in the compiler's "unsigned int"
+    type, but there is no limit to the number of chunks.  Note however that the
+    strm.total_in and strm_total_out counters may be limited to 4 GB.  These
+    counters are provided as a convenience and are not used internally by
+    inflate() or deflate().  The application can easily set up its own counters
+    updated after each call of inflate() or deflate() to count beyond 4 GB.
+    compress() and uncompress() may be limited to 4 GB, since they operate in a
+    single call.  gzseek() and gztell() may be limited to 4 GB depending on how
+    zlib is compiled.  See the zlibCompileFlags() function in zlib.h.
+
+    The word "may" appears several times above since there is a 4 GB limit only
+    if the compiler's "long" type is 32 bits.  If the compiler's "long" type is
+    64 bits, then the limit is 16 exabytes.
+
+33. Does zlib have any security vulnerabilities?
+
+    The only one that we are aware of is potentially in gzprintf().  If zlib is
+    compiled to use sprintf() or vsprintf(), then there is no protection
+    against a buffer overflow of an 8K string space (or other value as set by
+    gzbuffer()), other than the caller of gzprintf() assuring that the output
+    will not exceed 8K.  On the other hand, if zlib is compiled to use
+    snprintf() or vsnprintf(), which should normally be the case, then there is
+    no vulnerability.  The ./configure script will display warnings if an
+    insecure variation of sprintf() will be used by gzprintf().  Also the
+    zlibCompileFlags() function will return information on what variant of
+    sprintf() is used by gzprintf().
+
+    If you don't have snprintf() or vsnprintf() and would like one, you can
+    find a portable implementation here:
+
+        http://www.ijs.si/software/snprintf/
+
+    Note that you should be using the most recent version of zlib.  Versions
+    1.1.3 and before were subject to a double-free vulnerability, and versions
+    1.2.1 and 1.2.2 were subject to an access exception when decompressing
+    invalid compressed data.
+
+34. Is there a Java version of zlib?
+
+    Probably what you want is to use zlib in Java. zlib is already included
+    as part of the Java SDK in the java.util.zip package. If you really want
+    a version of zlib written in the Java language, look on the zlib home
+    page for links: http://zlib.net/ .
+
+35. I get this or that compiler or source-code scanner warning when I crank it
+    up to maximally-pedantic. Can't you guys write proper code?
+
+    Many years ago, we gave up attempting to avoid warnings on every compiler
+    in the universe.  It just got to be a waste of time, and some compilers
+    were downright silly as well as contradicted each other.  So now, we simply
+    make sure that the code always works.
+
+36. Valgrind (or some similar memory access checker) says that deflate is
+    performing a conditional jump that depends on an uninitialized value.
+    Isn't that a bug?
+
+    No.  That is intentional for performance reasons, and the output of deflate
+    is not affected.  This only started showing up recently since zlib 1.2.x
+    uses malloc() by default for allocations, whereas earlier versions used
+    calloc(), which zeros out the allocated memory.  Even though the code was
+    correct, versions 1.2.4 and later was changed to not stimulate these
+    checkers.
+
+37. Will zlib read the (insert any ancient or arcane format here) compressed
+    data format?
+
+    Probably not. Look in the comp.compression FAQ for pointers to various
+    formats and associated software.
+
+38. How can I encrypt/decrypt zip files with zlib?
+
+    zlib doesn't support encryption.  The original PKZIP encryption is very
+    weak and can be broken with freely available programs.  To get strong
+    encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib
+    compression.  For PKZIP compatible "encryption", look at
+    http://www.info-zip.org/
+
+39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
+
+    "gzip" is the gzip format, and "deflate" is the zlib format.  They should
+    probably have called the second one "zlib" instead to avoid confusion with
+    the raw deflate compressed data format.  While the HTTP 1.1 RFC 2616
+    correctly points to the zlib specification in RFC 1950 for the "deflate"
+    transfer encoding, there have been reports of servers and browsers that
+    incorrectly produce or expect raw deflate data per the deflate
+    specification in RFC 1951, most notably Microsoft.  So even though the
+    "deflate" transfer encoding using the zlib format would be the more
+    efficient approach (and in fact exactly what the zlib format was designed
+    for), using the "gzip" transfer encoding is probably more reliable due to
+    an unfortunate choice of name on the part of the HTTP 1.1 authors.
+
+    Bottom line: use the gzip format for HTTP 1.1 encoding.
+
+40. Does zlib support the new "Deflate64" format introduced by PKWare?
+
+    No.  PKWare has apparently decided to keep that format proprietary, since
+    they have not documented it as they have previous compression formats.  In
+    any case, the compression improvements are so modest compared to other more
+    modern approaches, that it's not worth the effort to implement.
+
+41. I'm having a problem with the zip functions in zlib, can you help?
+
+    There are no zip functions in zlib.  You are probably using minizip by
+    Giles Vollant, which is found in the contrib directory of zlib.  It is not
+    part of zlib.  In fact none of the stuff in contrib is part of zlib.  The
+    files in there are not supported by the zlib authors.  You need to contact
+    the authors of the respective contribution for help.
+
+42. The match.asm code in contrib is under the GNU General Public License.
+    Since it's part of zlib, doesn't that mean that all of zlib falls under the
+    GNU GPL?
+
+    No.  The files in contrib are not part of zlib.  They were contributed by
+    other authors and are provided as a convenience to the user within the zlib
+    distribution.  Each item in contrib has its own license.
+
+43. Is zlib subject to export controls?  What is its ECCN?
+
+    zlib is not subject to export controls, and so is classified as EAR99.
+
+44. Can you please sign these lengthy legal documents and fax them back to us
+    so that we can use your software in our product?
+
+    No. Go away. Shoo.
Index: EcnlProtoTool/trunk/zlib-1.2.11/INDEX
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/INDEX	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/INDEX	(revision 331)
@@ -0,0 +1,68 @@
+CMakeLists.txt  cmake build file
+ChangeLog       history of changes
+FAQ             Frequently Asked Questions about zlib
+INDEX           this file
+Makefile        dummy Makefile that tells you to ./configure
+Makefile.in     template for Unix Makefile
+README          guess what
+configure       configure script for Unix
+make_vms.com    makefile for VMS
+test/example.c  zlib usages examples for build testing
+test/minigzip.c minimal gzip-like functionality for build testing
+test/infcover.c inf*.c code coverage for build coverage testing
+treebuild.xml   XML description of source file dependencies
+zconf.h.cmakein zconf.h template for cmake
+zconf.h.in      zconf.h template for configure
+zlib.3          Man page for zlib
+zlib.3.pdf      Man page in PDF format
+zlib.map        Linux symbol information
+zlib.pc.in      Template for pkg-config descriptor
+zlib.pc.cmakein zlib.pc template for cmake
+zlib2ansi       perl script to convert source files for C++ compilation
+
+amiga/          makefiles for Amiga SAS C
+as400/          makefiles for AS/400
+doc/            documentation for formats and algorithms
+msdos/          makefiles for MSDOS
+nintendods/     makefile for Nintendo DS
+old/            makefiles for various architectures and zlib documentation
+                files that have not yet been updated for zlib 1.2.x
+qnx/            makefiles for QNX
+watcom/         makefiles for OpenWatcom
+win32/          makefiles for Windows
+
+                zlib public header files (required for library use):
+zconf.h
+zlib.h
+
+                private source files used to build the zlib library:
+adler32.c
+compress.c
+crc32.c
+crc32.h
+deflate.c
+deflate.h
+gzclose.c
+gzguts.h
+gzlib.c
+gzread.c
+gzwrite.c
+infback.c
+inffast.c
+inffast.h
+inffixed.h
+inflate.c
+inflate.h
+inftrees.c
+inftrees.h
+trees.c
+trees.h
+uncompr.c
+zutil.c
+zutil.h
+
+                source files for sample programs
+See examples/README.examples
+
+                unsupported contributions by third parties
+See contrib/README.contrib
Index: EcnlProtoTool/trunk/zlib-1.2.11/Makefile
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/Makefile	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/Makefile	(revision 331)
@@ -0,0 +1,5 @@
+all:
+	-@echo "Please use ./configure first.  Thank you."
+
+distclean:
+	make -f Makefile.in distclean
Index: EcnlProtoTool/trunk/zlib-1.2.11/Makefile.in
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/Makefile.in	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/Makefile.in	(revision 331)
@@ -0,0 +1,410 @@
+# Makefile for zlib
+# Copyright (C) 1995-2017 Jean-loup Gailly, Mark Adler
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile and test, type:
+#    ./configure; make test
+# Normally configure builds both a static and a shared library.
+# If you want to build just a static library, use: ./configure --static
+
+# To use the asm code, type:
+#    cp contrib/asm?86/match.S ./match.S
+#    make LOC=-DASMV OBJA=match.o
+
+# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
+#    make install
+# To install in $HOME instead of /usr/local, use:
+#    make install prefix=$HOME
+
+CC=cc
+
+CFLAGS=-O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-g -DZLIB_DEBUG
+#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+#           -Wstrict-prototypes -Wmissing-prototypes
+
+SFLAGS=-O
+LDFLAGS=
+TEST_LDFLAGS=-L. libz.a
+LDSHARED=$(CC)
+CPP=$(CC) -E
+
+STATICLIB=libz.a
+SHAREDLIB=libz.so
+SHAREDLIBV=libz.so.1.2.11
+SHAREDLIBM=libz.so.1
+LIBS=$(STATICLIB) $(SHAREDLIBV)
+
+AR=ar
+ARFLAGS=rc
+RANLIB=ranlib
+LDCONFIG=ldconfig
+LDSHAREDLIBC=-lc
+TAR=tar
+SHELL=/bin/sh
+EXE=
+
+prefix = /usr/local
+exec_prefix = ${prefix}
+libdir = ${exec_prefix}/lib
+sharedlibdir = ${libdir}
+includedir = ${prefix}/include
+mandir = ${prefix}/share/man
+man3dir = ${mandir}/man3
+pkgconfigdir = ${libdir}/pkgconfig
+SRCDIR=
+ZINC=
+ZINCOUT=-I.
+
+OBJZ = adler32.o crc32.o deflate.o infback.o inffast.o inflate.o inftrees.o trees.o zutil.o
+OBJG = compress.o uncompr.o gzclose.o gzlib.o gzread.o gzwrite.o
+OBJC = $(OBJZ) $(OBJG)
+
+PIC_OBJZ = adler32.lo crc32.lo deflate.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo zutil.lo
+PIC_OBJG = compress.lo uncompr.lo gzclose.lo gzlib.lo gzread.lo gzwrite.lo
+PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG)
+
+# to use the asm code: make OBJA=match.o, PIC_OBJA=match.lo
+OBJA =
+PIC_OBJA =
+
+OBJS = $(OBJC) $(OBJA)
+
+PIC_OBJS = $(PIC_OBJC) $(PIC_OBJA)
+
+all: static shared
+
+static: example$(EXE) minigzip$(EXE)
+
+shared: examplesh$(EXE) minigzipsh$(EXE)
+
+all64: example64$(EXE) minigzip64$(EXE)
+
+check: test
+
+test: all teststatic testshared
+
+teststatic: static
+	@TMPST=tmpst_$$; \
+	if echo hello world | ./minigzip | ./minigzip -d && ./example $$TMPST ; then \
+	  echo '		*** zlib test OK ***'; \
+	else \
+	  echo '		*** zlib test FAILED ***'; false; \
+	fi; \
+	rm -f $$TMPST
+
+testshared: shared
+	@LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
+	LD_LIBRARYN32_PATH=`pwd`:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \
+	DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \
+	SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \
+	TMPSH=tmpsh_$$; \
+	if echo hello world | ./minigzipsh | ./minigzipsh -d && ./examplesh $$TMPSH; then \
+	  echo '		*** zlib shared test OK ***'; \
+	else \
+	  echo '		*** zlib shared test FAILED ***'; false; \
+	fi; \
+	rm -f $$TMPSH
+
+test64: all64
+	@TMP64=tmp64_$$; \
+	if echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64 $$TMP64; then \
+	  echo '		*** zlib 64-bit test OK ***'; \
+	else \
+	  echo '		*** zlib 64-bit test FAILED ***'; false; \
+	fi; \
+	rm -f $$TMP64
+
+infcover.o: $(SRCDIR)test/infcover.c $(SRCDIR)zlib.h zconf.h
+	$(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/infcover.c
+
+infcover: infcover.o libz.a
+	$(CC) $(CFLAGS) -o $@ infcover.o libz.a
+
+cover: infcover
+	rm -f *.gcda
+	./infcover
+	gcov inf*.c
+
+libz.a: $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+	-@ ($(RANLIB) $@ || true) >/dev/null 2>&1
+
+match.o: match.S
+	$(CPP) match.S > _match.s
+	$(CC) -c _match.s
+	mv _match.o match.o
+	rm -f _match.s
+
+match.lo: match.S
+	$(CPP) match.S > _match.s
+	$(CC) -c -fPIC _match.s
+	mv _match.o match.lo
+	rm -f _match.s
+
+example.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h
+	$(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/example.c
+
+minigzip.o: $(SRCDIR)test/minigzip.c $(SRCDIR)zlib.h zconf.h
+	$(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/minigzip.c
+
+example64.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h
+	$(CC) $(CFLAGS) $(ZINCOUT) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)test/example.c
+
+minigzip64.o: $(SRCDIR)test/minigzip.c $(SRCDIR)zlib.h zconf.h
+	$(CC) $(CFLAGS) $(ZINCOUT) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)test/minigzip.c
+
+
+adler32.o: $(SRCDIR)adler32.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)adler32.c
+
+crc32.o: $(SRCDIR)crc32.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)crc32.c
+
+deflate.o: $(SRCDIR)deflate.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)deflate.c
+
+infback.o: $(SRCDIR)infback.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)infback.c
+
+inffast.o: $(SRCDIR)inffast.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inffast.c
+
+inflate.o: $(SRCDIR)inflate.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inflate.c
+
+inftrees.o: $(SRCDIR)inftrees.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inftrees.c
+
+trees.o: $(SRCDIR)trees.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)trees.c
+
+zutil.o: $(SRCDIR)zutil.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)zutil.c
+
+compress.o: $(SRCDIR)compress.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)compress.c
+
+uncompr.o: $(SRCDIR)uncompr.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)uncompr.c
+
+gzclose.o: $(SRCDIR)gzclose.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzclose.c
+
+gzlib.o: $(SRCDIR)gzlib.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzlib.c
+
+gzread.o: $(SRCDIR)gzread.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzread.c
+
+gzwrite.o: $(SRCDIR)gzwrite.c
+	$(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzwrite.c
+
+
+adler32.lo: $(SRCDIR)adler32.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/adler32.o $(SRCDIR)adler32.c
+	-@mv objs/adler32.o $@
+
+crc32.lo: $(SRCDIR)crc32.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/crc32.o $(SRCDIR)crc32.c
+	-@mv objs/crc32.o $@
+
+deflate.lo: $(SRCDIR)deflate.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/deflate.o $(SRCDIR)deflate.c
+	-@mv objs/deflate.o $@
+
+infback.lo: $(SRCDIR)infback.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/infback.o $(SRCDIR)infback.c
+	-@mv objs/infback.o $@
+
+inffast.lo: $(SRCDIR)inffast.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inffast.o $(SRCDIR)inffast.c
+	-@mv objs/inffast.o $@
+
+inflate.lo: $(SRCDIR)inflate.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inflate.o $(SRCDIR)inflate.c
+	-@mv objs/inflate.o $@
+
+inftrees.lo: $(SRCDIR)inftrees.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inftrees.o $(SRCDIR)inftrees.c
+	-@mv objs/inftrees.o $@
+
+trees.lo: $(SRCDIR)trees.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/trees.o $(SRCDIR)trees.c
+	-@mv objs/trees.o $@
+
+zutil.lo: $(SRCDIR)zutil.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/zutil.o $(SRCDIR)zutil.c
+	-@mv objs/zutil.o $@
+
+compress.lo: $(SRCDIR)compress.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/compress.o $(SRCDIR)compress.c
+	-@mv objs/compress.o $@
+
+uncompr.lo: $(SRCDIR)uncompr.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/uncompr.o $(SRCDIR)uncompr.c
+	-@mv objs/uncompr.o $@
+
+gzclose.lo: $(SRCDIR)gzclose.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzclose.o $(SRCDIR)gzclose.c
+	-@mv objs/gzclose.o $@
+
+gzlib.lo: $(SRCDIR)gzlib.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzlib.o $(SRCDIR)gzlib.c
+	-@mv objs/gzlib.o $@
+
+gzread.lo: $(SRCDIR)gzread.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzread.o $(SRCDIR)gzread.c
+	-@mv objs/gzread.o $@
+
+gzwrite.lo: $(SRCDIR)gzwrite.c
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzwrite.o $(SRCDIR)gzwrite.c
+	-@mv objs/gzwrite.o $@
+
+
+placebo $(SHAREDLIBV): $(PIC_OBJS) libz.a
+	$(LDSHARED) $(SFLAGS) -o $@ $(PIC_OBJS) $(LDSHAREDLIBC) $(LDFLAGS)
+	rm -f $(SHAREDLIB) $(SHAREDLIBM)
+	ln -s $@ $(SHAREDLIB)
+	ln -s $@ $(SHAREDLIBM)
+	-@rmdir objs
+
+example$(EXE): example.o $(STATICLIB)
+	$(CC) $(CFLAGS) -o $@ example.o $(TEST_LDFLAGS)
+
+minigzip$(EXE): minigzip.o $(STATICLIB)
+	$(CC) $(CFLAGS) -o $@ minigzip.o $(TEST_LDFLAGS)
+
+examplesh$(EXE): example.o $(SHAREDLIBV)
+	$(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDLIBV)
+
+minigzipsh$(EXE): minigzip.o $(SHAREDLIBV)
+	$(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDLIBV)
+
+example64$(EXE): example64.o $(STATICLIB)
+	$(CC) $(CFLAGS) -o $@ example64.o $(TEST_LDFLAGS)
+
+minigzip64$(EXE): minigzip64.o $(STATICLIB)
+	$(CC) $(CFLAGS) -o $@ minigzip64.o $(TEST_LDFLAGS)
+
+install-libs: $(LIBS)
+	-@if [ ! -d $(DESTDIR)$(exec_prefix)  ]; then mkdir -p $(DESTDIR)$(exec_prefix); fi
+	-@if [ ! -d $(DESTDIR)$(libdir)       ]; then mkdir -p $(DESTDIR)$(libdir); fi
+	-@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi
+	-@if [ ! -d $(DESTDIR)$(man3dir)      ]; then mkdir -p $(DESTDIR)$(man3dir); fi
+	-@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi
+	rm -f $(DESTDIR)$(libdir)/$(STATICLIB)
+	cp $(STATICLIB) $(DESTDIR)$(libdir)
+	chmod 644 $(DESTDIR)$(libdir)/$(STATICLIB)
+	-@($(RANLIB) $(DESTDIR)$(libdir)/libz.a || true) >/dev/null 2>&1
+	-@if test -n "$(SHAREDLIBV)"; then \
+	  rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \
+	  cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir); \
+	  echo "cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)"; \
+	  chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \
+	  echo "chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV)"; \
+	  rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \
+	  ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB); \
+	  ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \
+	  ($(LDCONFIG) || true)  >/dev/null 2>&1; \
+	fi
+	rm -f $(DESTDIR)$(man3dir)/zlib.3
+	cp $(SRCDIR)zlib.3 $(DESTDIR)$(man3dir)
+	chmod 644 $(DESTDIR)$(man3dir)/zlib.3
+	rm -f $(DESTDIR)$(pkgconfigdir)/zlib.pc
+	cp zlib.pc $(DESTDIR)$(pkgconfigdir)
+	chmod 644 $(DESTDIR)$(pkgconfigdir)/zlib.pc
+# The ranlib in install is needed on NeXTSTEP which checks file times
+# ldconfig is for Linux
+
+install: install-libs
+	-@if [ ! -d $(DESTDIR)$(includedir)   ]; then mkdir -p $(DESTDIR)$(includedir); fi
+	rm -f $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h
+	cp $(SRCDIR)zlib.h zconf.h $(DESTDIR)$(includedir)
+	chmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h
+
+uninstall:
+	cd $(DESTDIR)$(includedir) && rm -f zlib.h zconf.h
+	cd $(DESTDIR)$(libdir) && rm -f libz.a; \
+	if test -n "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \
+	  rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \
+	fi
+	cd $(DESTDIR)$(man3dir) && rm -f zlib.3
+	cd $(DESTDIR)$(pkgconfigdir) && rm -f zlib.pc
+
+docs: zlib.3.pdf
+
+zlib.3.pdf: $(SRCDIR)zlib.3
+	groff -mandoc -f H -T ps $(SRCDIR)zlib.3 | ps2pdf - $@
+
+zconf.h.cmakein: $(SRCDIR)zconf.h.in
+	-@ TEMPFILE=zconfh_$$; \
+	echo "/#define ZCONF_H/ a\\\\\n#cmakedefine Z_PREFIX\\\\\n#cmakedefine Z_HAVE_UNISTD_H\n" >> $$TEMPFILE &&\
+	sed -f $$TEMPFILE $(SRCDIR)zconf.h.in > $@ &&\
+	touch -r $(SRCDIR)zconf.h.in $@ &&\
+	rm $$TEMPFILE
+
+zconf: $(SRCDIR)zconf.h.in
+	cp -p $(SRCDIR)zconf.h.in zconf.h
+
+mostlyclean: clean
+clean:
+	rm -f *.o *.lo *~ \
+	   example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \
+	   example64$(EXE) minigzip64$(EXE) \
+	   infcover \
+	   libz.* foo.gz so_locations \
+	   _match.s maketree contrib/infback9/*.o
+	rm -rf objs
+	rm -f *.gcda *.gcno *.gcov
+	rm -f contrib/infback9/*.gcda contrib/infback9/*.gcno contrib/infback9/*.gcov
+
+maintainer-clean: distclean
+distclean: clean zconf zconf.h.cmakein docs
+	rm -f Makefile zlib.pc configure.log
+	-@rm -f .DS_Store
+	@if [ -f Makefile.in ]; then \
+	printf 'all:\n\t-@echo "Please use ./configure first.  Thank you."\n' > Makefile ; \
+	printf '\ndistclean:\n\tmake -f Makefile.in distclean\n' >> Makefile ; \
+	touch -r $(SRCDIR)Makefile.in Makefile ; fi
+	@if [ ! -f zconf.h.in ]; then rm -f zconf.h zconf.h.cmakein ; fi
+	@if [ ! -f zlib.3 ]; then rm -f zlib.3.pdf ; fi
+
+tags:
+	etags $(SRCDIR)*.[ch]
+
+adler32.o zutil.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h
+gzclose.o gzlib.o gzread.o gzwrite.o: $(SRCDIR)zlib.h zconf.h $(SRCDIR)gzguts.h
+compress.o example.o minigzip.o uncompr.o: $(SRCDIR)zlib.h zconf.h
+crc32.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)crc32.h
+deflate.o: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h
+infback.o inflate.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h $(SRCDIR)inffixed.h
+inffast.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h
+inftrees.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h
+trees.o: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)trees.h
+
+adler32.lo zutil.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h
+gzclose.lo gzlib.lo gzread.lo gzwrite.lo: $(SRCDIR)zlib.h zconf.h $(SRCDIR)gzguts.h
+compress.lo example.lo minigzip.lo uncompr.lo: $(SRCDIR)zlib.h zconf.h
+crc32.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)crc32.h
+deflate.lo: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h
+infback.lo inflate.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h $(SRCDIR)inffixed.h
+inffast.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h
+inftrees.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h
+trees.lo: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)trees.h
Index: EcnlProtoTool/trunk/zlib-1.2.11/README
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/README	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/README	(revision 331)
@@ -0,0 +1,115 @@
+ZLIB DATA COMPRESSION LIBRARY
+
+zlib 1.2.11 is a general purpose data compression library.  All the code is
+thread safe.  The data format used by the zlib library is described by RFCs
+(Request for Comments) 1950 to 1952 in the files
+http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and
+rfc1952 (gzip format).
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact zlib@gzip.org).  A usage example
+of the library is given in the file test/example.c which also tests that
+the library is working correctly.  Another example is given in the file
+test/minigzip.c.  The compression library itself is composed of all source
+files in the root directory.
+
+To compile all files and run the test program, follow the instructions given at
+the top of Makefile.in.  In short "./configure; make test", and if that goes
+well, "make install" should work for most flavors of Unix.  For Windows, use
+one of the special makefiles in win32/ or contrib/vstudio/ .  For VMS, use
+make_vms.com.
+
+Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
+<info@winimage.com> for the Windows DLL version.  The zlib home page is
+http://zlib.net/ .  Before reporting a problem, please check this site to
+verify that you have the latest version of zlib; otherwise get the latest
+version and check whether the problem still exists or not.
+
+PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help.
+
+Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan.  1997
+issue of Dr.  Dobb's Journal; a copy of the article is available at
+http://marknelson.us/1997/01/01/zlib-engine/ .
+
+The changes made in version 1.2.11 are documented in the file ChangeLog.
+
+Unsupported third party contributions are provided in directory contrib/ .
+
+zlib is available in Java using the java.util.zip package, documented at
+http://java.sun.com/developer/technicalArticles/Programming/compression/ .
+
+A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is available
+at CPAN (Comprehensive Perl Archive Network) sites, including
+http://search.cpan.org/~pmqs/IO-Compress-Zlib/ .
+
+A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
+available in Python 1.5 and later versions, see
+http://docs.python.org/library/zlib.html .
+
+zlib is built into tcl: http://wiki.tcl.tk/4610 .
+
+An experimental package to read and write files in .zip format, written on top
+of zlib by Gilles Vollant <info@winimage.com>, is available in the
+contrib/minizip directory of zlib.
+
+
+Notes for some targets:
+
+- For Windows DLL versions, please see win32/DLL_FAQ.txt
+
+- For 64-bit Irix, deflate.c must be compiled without any optimization. With
+  -O, one libpng test fails. The test works in 32 bit mode (with the -n32
+  compiler flag). The compiler bug has been reported to SGI.
+
+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
+  when compiled with cc.
+
+- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
+  necessary to get gzprintf working correctly. This is done by configure.
+
+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
+  other compilers. Use "make test" to check your compiler.
+
+- gzdopen is not supported on RISCOS or BEOS.
+
+- For PalmOs, see http://palmzlib.sourceforge.net/
+
+
+Acknowledgments:
+
+  The deflate format used by zlib was defined by Phil Katz.  The deflate and
+  zlib specifications were written by L.  Peter Deutsch.  Thanks to all the
+  people who reported problems and suggested various improvements in zlib; they
+  are too numerous to cite here.
+
+Copyright notice:
+
+ (C) 1995-2017 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not* receiving
+lengthy legal documents to sign.  The sources are provided for free but without
+warranty of any kind.  The library has been entirely written by Jean-loup
+Gailly and Mark Adler; it does not include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include in
+the file ChangeLog history information documenting your changes.  Please read
+the FAQ for more information on the distribution of modified source versions.
Index: EcnlProtoTool/trunk/zlib-1.2.11/adler32.c
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/adler32.c	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/adler32.c	(revision 331)
@@ -0,0 +1,186 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2011, 2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
+
+#define BASE 65521U     /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}
+#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf)   DO8(buf,0); DO8(buf,8);
+
+/* use NO_DIVIDE if your processor does not do division in hardware --
+   try it both ways to see which is faster */
+#ifdef NO_DIVIDE
+/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
+   (thank you to John Reiser for pointing this out) */
+#  define CHOP(a) \
+    do { \
+        unsigned long tmp = a >> 16; \
+        a &= 0xffffUL; \
+        a += (tmp << 4) - tmp; \
+    } while (0)
+#  define MOD28(a) \
+    do { \
+        CHOP(a); \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
+#  define MOD(a) \
+    do { \
+        CHOP(a); \
+        MOD28(a); \
+    } while (0)
+#  define MOD63(a) \
+    do { /* this assumes a is not negative */ \
+        z_off64_t tmp = a >> 32; \
+        a &= 0xffffffffL; \
+        a += (tmp << 8) - (tmp << 5) + tmp; \
+        tmp = a >> 16; \
+        a &= 0xffffL; \
+        a += (tmp << 4) - tmp; \
+        tmp = a >> 16; \
+        a &= 0xffffL; \
+        a += (tmp << 4) - tmp; \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
+#else
+#  define MOD(a) a %= BASE
+#  define MOD28(a) a %= BASE
+#  define MOD63(a) a %= BASE
+#endif
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_z(adler, buf, len)
+    uLong adler;
+    const Bytef *buf;
+    z_size_t len;
+{
+    unsigned long sum2;
+    unsigned n;
+
+    /* split Adler-32 into component sums */
+    sum2 = (adler >> 16) & 0xffff;
+    adler &= 0xffff;
+
+    /* in case user likes doing a byte at a time, keep it fast */
+    if (len == 1) {
+        adler += buf[0];
+        if (adler >= BASE)
+            adler -= BASE;
+        sum2 += adler;
+        if (sum2 >= BASE)
+            sum2 -= BASE;
+        return adler | (sum2 << 16);
+    }
+
+    /* initial Adler-32 value (deferred check for len == 1 speed) */
+    if (buf == Z_NULL)
+        return 1L;
+
+    /* in case short lengths are provided, keep it somewhat fast */
+    if (len < 16) {
+        while (len--) {
+            adler += *buf++;
+            sum2 += adler;
+        }
+        if (adler >= BASE)
+            adler -= BASE;
+        MOD28(sum2);            /* only added so many BASE's */
+        return adler | (sum2 << 16);
+    }
+
+    /* do length NMAX blocks -- requires just one modulo operation */
+    while (len >= NMAX) {
+        len -= NMAX;
+        n = NMAX / 16;          /* NMAX is divisible by 16 */
+        do {
+            DO16(buf);          /* 16 sums unrolled */
+            buf += 16;
+        } while (--n);
+        MOD(adler);
+        MOD(sum2);
+    }
+
+    /* do remaining bytes (less than NMAX, still just one modulo) */
+    if (len) {                  /* avoid modulos if none remaining */
+        while (len >= 16) {
+            len -= 16;
+            DO16(buf);
+            buf += 16;
+        }
+        while (len--) {
+            adler += *buf++;
+            sum2 += adler;
+        }
+        MOD(adler);
+        MOD(sum2);
+    }
+
+    /* return recombined sums */
+    return adler | (sum2 << 16);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+    uLong adler;
+    const Bytef *buf;
+    uInt len;
+{
+    return adler32_z(adler, buf, len);
+}
+
+/* ========================================================================= */
+local uLong adler32_combine_(adler1, adler2, len2)
+    uLong adler1;
+    uLong adler2;
+    z_off64_t len2;
+{
+    unsigned long sum1;
+    unsigned long sum2;
+    unsigned rem;
+
+    /* for negative len, return invalid adler32 as a clue for debugging */
+    if (len2 < 0)
+        return 0xffffffffUL;
+
+    /* the derivation of this formula is left as an exercise for the reader */
+    MOD63(len2);                /* assumes len2 >= 0 */
+    rem = (unsigned)len2;
+    sum1 = adler1 & 0xffff;
+    sum2 = rem * sum1;
+    MOD(sum2);
+    sum1 += (adler2 & 0xffff) + BASE - 1;
+    sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
+    if (sum1 >= BASE) sum1 -= BASE;
+    if (sum1 >= BASE) sum1 -= BASE;
+    if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1);
+    if (sum2 >= BASE) sum2 -= BASE;
+    return sum1 | (sum2 << 16);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+    uLong adler1;
+    uLong adler2;
+    z_off_t len2;
+{
+    return adler32_combine_(adler1, adler2, len2);
+}
+
+uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
+    uLong adler1;
+    uLong adler2;
+    z_off64_t len2;
+{
+    return adler32_combine_(adler1, adler2, len2);
+}
Index: EcnlProtoTool/trunk/zlib-1.2.11/compress.c
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/compress.c	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/compress.c	(revision 331)
@@ -0,0 +1,86 @@
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+     Compresses the source buffer into the destination buffer. The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer. Upon entry, destLen is the total size of the
+   destination buffer, which must be at least 0.1% larger than sourceLen plus
+   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+    int level;
+{
+    z_stream stream;
+    int err;
+    const uInt max = (uInt)-1;
+    uLong left;
+
+    left = *destLen;
+    *destLen = 0;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+    stream.opaque = (voidpf)0;
+
+    err = deflateInit(&stream, level);
+    if (err != Z_OK) return err;
+
+    stream.next_out = dest;
+    stream.avail_out = 0;
+    stream.next_in = (z_const Bytef *)source;
+    stream.avail_in = 0;
+
+    do {
+        if (stream.avail_out == 0) {
+            stream.avail_out = left > (uLong)max ? max : (uInt)left;
+            left -= stream.avail_out;
+        }
+        if (stream.avail_in == 0) {
+            stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen;
+            sourceLen -= stream.avail_in;
+        }
+        err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH);
+    } while (err == Z_OK);
+
+    *destLen = stream.total_out;
+    deflateEnd(&stream);
+    return err == Z_STREAM_END ? Z_OK : err;
+}
+
+/* ===========================================================================
+ */
+int ZEXPORT compress (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+{
+    return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+}
+
+/* ===========================================================================
+     If the default memLevel or windowBits for deflateInit() is changed, then
+   this function needs to be updated.
+ */
+uLong ZEXPORT compressBound (sourceLen)
+    uLong sourceLen;
+{
+    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+           (sourceLen >> 25) + 13;
+}
Index: EcnlProtoTool/trunk/zlib-1.2.11/configure
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/configure	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/configure	(revision 331)
@@ -0,0 +1,921 @@
+#!/bin/sh
+# configure script for zlib.
+#
+# Normally configure builds both a static and a shared library.
+# If you want to build just a static library, use: ./configure --static
+#
+# To impose specific compiler or flags or install directory, use for example:
+#    prefix=$HOME CC=cc CFLAGS="-O4" ./configure
+# or for csh/tcsh users:
+#    (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure)
+
+# Incorrect settings of CC or CFLAGS may prevent creating a shared library.
+# If you have problems, try without defining CC and CFLAGS before reporting
+# an error.
+
+# start off configure.log
+echo -------------------- >> configure.log
+echo $0 $* >> configure.log
+date >> configure.log
+
+# get source directory
+SRCDIR=`dirname $0`
+if test $SRCDIR = "."; then
+    ZINC=""
+    ZINCOUT="-I."
+    SRCDIR=""
+else
+    ZINC='-include zconf.h'
+    ZINCOUT='-I. -I$(SRCDIR)'
+    SRCDIR="$SRCDIR/"
+fi
+
+# set command prefix for cross-compilation
+if [ -n "${CHOST}" ]; then
+    uname="`echo "${CHOST}" | sed -e 's/^[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)-.*$/\1/'`"
+    CROSS_PREFIX="${CHOST}-"
+fi
+
+# destination name for static library
+STATICLIB=libz.a
+
+# extract zlib version numbers from zlib.h
+VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < ${SRCDIR}zlib.h`
+VER3=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\\.[0-9]*\).*/\1/p' < ${SRCDIR}zlib.h`
+VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < ${SRCDIR}zlib.h`
+VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < ${SRCDIR}zlib.h`
+
+# establish commands for library building
+if "${CROSS_PREFIX}ar" --version >/dev/null 2>/dev/null || test $? -lt 126; then
+    AR=${AR-"${CROSS_PREFIX}ar"}
+    test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log
+else
+    AR=${AR-"ar"}
+    test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log
+fi
+ARFLAGS=${ARFLAGS-"rc"}
+if "${CROSS_PREFIX}ranlib" --version >/dev/null 2>/dev/null || test $? -lt 126; then
+    RANLIB=${RANLIB-"${CROSS_PREFIX}ranlib"}
+    test -n "${CROSS_PREFIX}" && echo Using ${RANLIB} | tee -a configure.log
+else
+    RANLIB=${RANLIB-"ranlib"}
+fi
+if "${CROSS_PREFIX}nm" --version >/dev/null 2>/dev/null || test $? -lt 126; then
+    NM=${NM-"${CROSS_PREFIX}nm"}
+    test -n "${CROSS_PREFIX}" && echo Using ${NM} | tee -a configure.log
+else
+    NM=${NM-"nm"}
+fi
+
+# set defaults before processing command line options
+LDCONFIG=${LDCONFIG-"ldconfig"}
+LDSHAREDLIBC="${LDSHAREDLIBC--lc}"
+ARCHS=
+prefix=${prefix-/usr/local}
+exec_prefix=${exec_prefix-'${prefix}'}
+libdir=${libdir-'${exec_prefix}/lib'}
+sharedlibdir=${sharedlibdir-'${libdir}'}
+includedir=${includedir-'${prefix}/include'}
+mandir=${mandir-'${prefix}/share/man'}
+shared_ext='.so'
+shared=1
+solo=0
+cover=0
+zprefix=0
+zconst=0
+build64=0
+gcc=0
+warn=0
+debug=0
+old_cc="$CC"
+old_cflags="$CFLAGS"
+OBJC='$(OBJZ) $(OBJG)'
+PIC_OBJC='$(PIC_OBJZ) $(PIC_OBJG)'
+
+# leave this script, optionally in a bad way
+leave()
+{
+  if test "$*" != "0"; then
+    echo "** $0 aborting." | tee -a configure.log
+  fi
+  rm -f $test.[co] $test $test$shared_ext $test.gcno ./--version
+  echo -------------------- >> configure.log
+  echo >> configure.log
+  echo >> configure.log
+  exit $1
+}
+
+# process command line options
+while test $# -ge 1
+do
+case "$1" in
+    -h* | --help)
+      echo 'usage:' | tee -a configure.log
+      echo '  configure [--const] [--zprefix] [--prefix=PREFIX]  [--eprefix=EXPREFIX]' | tee -a configure.log
+      echo '    [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log
+      echo '    [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log
+        exit 0 ;;
+    -p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;;
+    -e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;;
+    -l*=* | --libdir=*) libdir=`echo $1 | sed 's/.*=//'`; shift ;;
+    --sharedlibdir=*) sharedlibdir=`echo $1 | sed 's/.*=//'`; shift ;;
+    -i*=* | --includedir=*) includedir=`echo $1 | sed 's/.*=//'`;shift ;;
+    -u*=* | --uname=*) uname=`echo $1 | sed 's/.*=//'`;shift ;;
+    -p* | --prefix) prefix="$2"; shift; shift ;;
+    -e* | --eprefix) exec_prefix="$2"; shift; shift ;;
+    -l* | --libdir) libdir="$2"; shift; shift ;;
+    -i* | --includedir) includedir="$2"; shift; shift ;;
+    -s* | --shared | --enable-shared) shared=1; shift ;;
+    -t | --static) shared=0; shift ;;
+    --solo) solo=1; shift ;;
+    --cover) cover=1; shift ;;
+    -z* | --zprefix) zprefix=1; shift ;;
+    -6* | --64) build64=1; shift ;;
+    -a*=* | --archs=*) ARCHS=`echo $1 | sed 's/.*=//'`; shift ;;
+    --sysconfdir=*) echo "ignored option: --sysconfdir" | tee -a configure.log; shift ;;
+    --localstatedir=*) echo "ignored option: --localstatedir" | tee -a configure.log; shift ;;
+    -c* | --const) zconst=1; shift ;;
+    -w* | --warn) warn=1; shift ;;
+    -d* | --debug) debug=1; shift ;;
+    *)
+      echo "unknown option: $1" | tee -a configure.log
+      echo "$0 --help for help" | tee -a configure.log
+      leave 1;;
+    esac
+done
+
+# temporary file name
+test=ztest$$
+
+# put arguments in log, also put test file in log if used in arguments
+show()
+{
+  case "$*" in
+    *$test.c*)
+      echo === $test.c === >> configure.log
+      cat $test.c >> configure.log
+      echo === >> configure.log;;
+  esac
+  echo $* >> configure.log
+}
+
+# check for gcc vs. cc and set compile and link flags based on the system identified by uname
+cat > $test.c <<EOF
+extern int getchar();
+int hello() {return getchar();}
+EOF
+
+test -z "$CC" && echo Checking for ${CROSS_PREFIX}gcc... | tee -a configure.log
+cc=${CC-${CROSS_PREFIX}gcc}
+cflags=${CFLAGS-"-O3"}
+# to force the asm version use: CFLAGS="-O3 -DASMV" ./configure
+case "$cc" in
+  *gcc*) gcc=1 ;;
+  *clang*) gcc=1 ;;
+esac
+case `$cc -v 2>&1` in
+  *gcc*) gcc=1 ;;
+  *clang*) gcc=1 ;;
+esac
+
+show $cc -c $test.c
+if test "$gcc" -eq 1 && ($cc -c $test.c) >> configure.log 2>&1; then
+  echo ... using gcc >> configure.log
+  CC="$cc"
+  CFLAGS="${CFLAGS--O3}"
+  SFLAGS="${CFLAGS--O3} -fPIC"
+  if test "$ARCHS"; then
+    CFLAGS="${CFLAGS} ${ARCHS}"
+    LDFLAGS="${LDFLAGS} ${ARCHS}"
+  fi
+  if test $build64 -eq 1; then
+    CFLAGS="${CFLAGS} -m64"
+    SFLAGS="${SFLAGS} -m64"
+  fi
+  if test "$warn" -eq 1; then
+    if test "$zconst" -eq 1; then
+      CFLAGS="${CFLAGS} -Wall -Wextra -Wcast-qual -pedantic -DZLIB_CONST"
+    else
+      CFLAGS="${CFLAGS} -Wall -Wextra -pedantic"
+    fi
+  fi
+  if test $debug -eq 1; then
+    CFLAGS="${CFLAGS} -DZLIB_DEBUG"
+    SFLAGS="${SFLAGS} -DZLIB_DEBUG"
+  fi
+  if test -z "$uname"; then
+    uname=`(uname -s || echo unknown) 2>/dev/null`
+  fi
+  case "$uname" in
+  Linux* | linux* | GNU | GNU/* | solaris*)
+        LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,${SRCDIR}zlib.map"} ;;
+  *BSD | *bsd* | DragonFly)
+        LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,${SRCDIR}zlib.map"}
+        LDCONFIG="ldconfig -m" ;;
+  CYGWIN* | Cygwin* | cygwin* | OS/2*)
+        EXE='.exe' ;;
+  MINGW* | mingw*)
+# temporary bypass
+        rm -f $test.[co] $test $test$shared_ext
+        echo "Please use win32/Makefile.gcc instead." | tee -a configure.log
+        leave 1
+        LDSHARED=${LDSHARED-"$cc -shared"}
+        LDSHAREDLIBC=""
+        EXE='.exe' ;;
+  QNX*)  # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4
+         # (alain.bonnefoy@icbt.com)
+                 LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"} ;;
+  HP-UX*)
+         LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"}
+         case `(uname -m || echo unknown) 2>/dev/null` in
+         ia64)
+                 shared_ext='.so'
+                 SHAREDLIB='libz.so' ;;
+         *)
+                 shared_ext='.sl'
+                 SHAREDLIB='libz.sl' ;;
+         esac ;;
+  Darwin* | darwin*)
+             shared_ext='.dylib'
+             SHAREDLIB=libz$shared_ext
+             SHAREDLIBV=libz.$VER$shared_ext
+             SHAREDLIBM=libz.$VER1$shared_ext
+             LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3"}
+             if libtool -V 2>&1 | grep Apple > /dev/null; then
+                 AR="libtool"
+             else
+                 AR="/usr/bin/libtool"
+             fi
+             ARFLAGS="-o" ;;
+  *)             LDSHARED=${LDSHARED-"$cc -shared"} ;;
+  esac
+else
+  # find system name and corresponding cc options
+  CC=${CC-cc}
+  gcc=0
+  echo ... using $CC >> configure.log
+  if test -z "$uname"; then
+    uname=`(uname -sr || echo unknown) 2>/dev/null`
+  fi
+  case "$uname" in
+  HP-UX*)    SFLAGS=${CFLAGS-"-O +z"}
+             CFLAGS=${CFLAGS-"-O"}
+#            LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"}
+             LDSHARED=${LDSHARED-"ld -b"}
+         case `(uname -m || echo unknown) 2>/dev/null` in
+         ia64)
+             shared_ext='.so'
+             SHAREDLIB='libz.so' ;;
+         *)
+             shared_ext='.sl'
+             SHAREDLIB='libz.sl' ;;
+         esac ;;
+  IRIX*)     SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."}
+             CFLAGS=${CFLAGS-"-ansi -O2"}
+             LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;;
+  OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"}
+             CFLAGS=${CFLAGS-"-O -std1"}
+             LDFLAGS="${LDFLAGS} -Wl,-rpath,."
+             LDSHARED=${LDSHARED-"cc -shared  -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"} ;;
+  OSF1*)     SFLAGS=${CFLAGS-"-O -std1"}
+             CFLAGS=${CFLAGS-"-O -std1"}
+             LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;;
+  QNX*)      SFLAGS=${CFLAGS-"-4 -O"}
+             CFLAGS=${CFLAGS-"-4 -O"}
+             LDSHARED=${LDSHARED-"cc"}
+             RANLIB=${RANLIB-"true"}
+             AR="cc"
+             ARFLAGS="-A" ;;
+  SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "}
+             CFLAGS=${CFLAGS-"-O3"}
+             LDSHARED=${LDSHARED-"cc -dy -KPIC -G"} ;;
+  SunOS\ 5* | solaris*)
+         LDSHARED=${LDSHARED-"cc -G -h libz$shared_ext.$VER1"}
+         SFLAGS=${CFLAGS-"-fast -KPIC"}
+         CFLAGS=${CFLAGS-"-fast"}
+         if test $build64 -eq 1; then
+             # old versions of SunPRO/Workshop/Studio don't support -m64,
+             # but newer ones do.  Check for it.
+             flag64=`$CC -flags | egrep -- '^-m64'`
+             if test x"$flag64" != x"" ; then
+                 CFLAGS="${CFLAGS} -m64"
+                 SFLAGS="${SFLAGS} -m64"
+             else
+                 case `(uname -m || echo unknown) 2>/dev/null` in
+                   i86*)
+                     SFLAGS="$SFLAGS -xarch=amd64"
+                     CFLAGS="$CFLAGS -xarch=amd64" ;;
+                   *)
+                     SFLAGS="$SFLAGS -xarch=v9"
+                     CFLAGS="$CFLAGS -xarch=v9" ;;
+                 esac
+             fi
+         fi
+         if test -n "$ZINC"; then
+             ZINC='-I- -I. -I$(SRCDIR)'
+         fi
+         ;;
+  SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"}
+             CFLAGS=${CFLAGS-"-O2"}
+             LDSHARED=${LDSHARED-"ld"} ;;
+  SunStudio\ 9*) SFLAGS=${CFLAGS-"-fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"}
+             CFLAGS=${CFLAGS-"-fast -xtarget=ultra3 -xarch=v9b"}
+             LDSHARED=${LDSHARED-"cc -xarch=v9b"} ;;
+  UNIX_System_V\ 4.2.0)
+             SFLAGS=${CFLAGS-"-KPIC -O"}
+             CFLAGS=${CFLAGS-"-O"}
+             LDSHARED=${LDSHARED-"cc -G"} ;;
+  UNIX_SV\ 4.2MP)
+             SFLAGS=${CFLAGS-"-Kconform_pic -O"}
+             CFLAGS=${CFLAGS-"-O"}
+             LDSHARED=${LDSHARED-"cc -G"} ;;
+  OpenUNIX\ 5)
+             SFLAGS=${CFLAGS-"-KPIC -O"}
+             CFLAGS=${CFLAGS-"-O"}
+             LDSHARED=${LDSHARED-"cc -G"} ;;
+  AIX*)  # Courtesy of dbakker@arrayasolutions.com
+             SFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
+             CFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
+             LDSHARED=${LDSHARED-"xlc -G"} ;;
+  # send working options for other systems to zlib@gzip.org
+  *)         SFLAGS=${CFLAGS-"-O"}
+             CFLAGS=${CFLAGS-"-O"}
+             LDSHARED=${LDSHARED-"cc -shared"} ;;
+  esac
+fi
+
+# destination names for shared library if not defined above
+SHAREDLIB=${SHAREDLIB-"libz$shared_ext"}
+SHAREDLIBV=${SHAREDLIBV-"libz$shared_ext.$VER"}
+SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"}
+
+echo >> configure.log
+
+# define functions for testing compiler and library characteristics and logging the results
+
+cat > $test.c <<EOF
+#error error
+EOF
+if ($CC -c $CFLAGS $test.c) 2>/dev/null; then
+  try()
+  {
+    show $*
+    test "`( $* ) 2>&1 | tee -a configure.log`" = ""
+  }
+  echo - using any output from compiler to indicate an error >> configure.log
+else
+  try()
+  {
+    show $*
+    ( $* ) >> configure.log 2>&1
+    ret=$?
+    if test $ret -ne 0; then
+      echo "(exit code "$ret")" >> configure.log
+    fi
+    return $ret
+  }
+fi
+
+tryboth()
+{
+  show $*
+  got=`( $* ) 2>&1`
+  ret=$?
+  printf %s "$got" >> configure.log
+  if test $ret -ne 0; then
+    return $ret
+  fi
+  test "$got" = ""
+}
+
+cat > $test.c << EOF
+int foo() { return 0; }
+EOF
+echo "Checking for obsessive-compulsive compiler options..." >> configure.log
+if try $CC -c $CFLAGS $test.c; then
+  :
+else
+  echo "Compiler error reporting is too harsh for $0 (perhaps remove -Werror)." | tee -a configure.log
+  leave 1
+fi
+
+echo >> configure.log
+
+# see if shared library build supported
+cat > $test.c <<EOF
+extern int getchar();
+int hello() {return getchar();}
+EOF
+if test $shared -eq 1; then
+  echo Checking for shared library support... | tee -a configure.log
+  # we must test in two steps (cc then ld), required at least on SunOS 4.x
+  if try $CC -w -c $SFLAGS $test.c &&
+     try $LDSHARED $SFLAGS -o $test$shared_ext $test.o; then
+    echo Building shared library $SHAREDLIBV with $CC. | tee -a configure.log
+  elif test -z "$old_cc" -a -z "$old_cflags"; then
+    echo No shared library support. | tee -a configure.log
+    shared=0;
+  else
+    echo 'No shared library support; try without defining CC and CFLAGS' | tee -a configure.log
+    shared=0;
+  fi
+fi
+if test $shared -eq 0; then
+  LDSHARED="$CC"
+  ALL="static"
+  TEST="all teststatic"
+  SHAREDLIB=""
+  SHAREDLIBV=""
+  SHAREDLIBM=""
+  echo Building static library $STATICLIB version $VER with $CC. | tee -a configure.log
+else
+  ALL="static shared"
+  TEST="all teststatic testshared"
+fi
+
+# check for underscores in external names for use by assembler code
+CPP=${CPP-"$CC -E"}
+case $CFLAGS in
+  *ASMV*)
+    echo >> configure.log
+    show "$NM $test.o | grep _hello"
+    if test "`$NM $test.o | grep _hello | tee -a configure.log`" = ""; then
+      CPP="$CPP -DNO_UNDERLINE"
+      echo Checking for underline in external names... No. | tee -a configure.log
+    else
+      echo Checking for underline in external names... Yes. | tee -a configure.log
+    fi ;;
+esac
+
+echo >> configure.log
+
+# check for size_t
+cat > $test.c <<EOF
+#include <stdio.h>
+#include <stdlib.h>
+size_t dummy = 0;
+EOF
+if try $CC -c $CFLAGS $test.c; then
+  echo "Checking for size_t... Yes." | tee -a configure.log
+  need_sizet=0
+else
+  echo "Checking for size_t... No." | tee -a configure.log
+  need_sizet=1
+fi
+
+echo >> configure.log
+
+# find the size_t integer type, if needed
+if test $need_sizet -eq 1; then
+  cat > $test.c <<EOF
+long long dummy = 0;
+EOF
+  if try $CC -c $CFLAGS $test.c; then
+    echo "Checking for long long... Yes." | tee -a configure.log
+    cat > $test.c <<EOF
+#include <stdio.h>
+int main(void) {
+    if (sizeof(void *) <= sizeof(int)) puts("int");
+    else if (sizeof(void *) <= sizeof(long)) puts("long");
+    else puts("z_longlong");
+    return 0;
+}
+EOF
+  else
+    echo "Checking for long long... No." | tee -a configure.log
+    cat > $test.c <<EOF
+#include <stdio.h>
+int main(void) {
+    if (sizeof(void *) <= sizeof(int)) puts("int");
+    else puts("long");
+    return 0;
+}
+EOF
+  fi
+  if try $CC $CFLAGS -o $test $test.c; then
+    sizet=`./$test`
+    echo "Checking for a pointer-size integer type..." $sizet"." | tee -a configure.log
+  else
+    echo "Failed to find a pointer-size integer type." | tee -a configure.log
+    leave 1
+  fi
+fi
+
+if test $need_sizet -eq 1; then
+  CFLAGS="${CFLAGS} -DNO_SIZE_T=${sizet}"
+  SFLAGS="${SFLAGS} -DNO_SIZE_T=${sizet}"
+fi
+
+echo >> configure.log
+
+# check for large file support, and if none, check for fseeko()
+cat > $test.c <<EOF
+#include <sys/types.h>
+off64_t dummy = 0;
+EOF
+if try $CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c; then
+  CFLAGS="${CFLAGS} -D_LARGEFILE64_SOURCE=1"
+  SFLAGS="${SFLAGS} -D_LARGEFILE64_SOURCE=1"
+  ALL="${ALL} all64"
+  TEST="${TEST} test64"
+  echo "Checking for off64_t... Yes." | tee -a configure.log
+  echo "Checking for fseeko... Yes." | tee -a configure.log
+else
+  echo "Checking for off64_t... No." | tee -a configure.log
+  echo >> configure.log
+  cat > $test.c <<EOF
+#include <stdio.h>
+int main(void) {
+  fseeko(NULL, 0, 0);
+  return 0;
+}
+EOF
+  if try $CC $CFLAGS -o $test $test.c; then
+    echo "Checking for fseeko... Yes." | tee -a configure.log
+  else
+    CFLAGS="${CFLAGS} -DNO_FSEEKO"
+    SFLAGS="${SFLAGS} -DNO_FSEEKO"
+    echo "Checking for fseeko... No." | tee -a configure.log
+  fi
+fi
+
+echo >> configure.log
+
+# check for strerror() for use by gz* functions
+cat > $test.c <<EOF
+#include <string.h>
+#include <errno.h>
+int main() { return strlen(strerror(errno)); }
+EOF
+if try $CC $CFLAGS -o $test $test.c; then
+  echo "Checking for strerror... Yes." | tee -a configure.log
+else
+  CFLAGS="${CFLAGS} -DNO_STRERROR"
+  SFLAGS="${SFLAGS} -DNO_STRERROR"
+  echo "Checking for strerror... No." | tee -a configure.log
+fi
+
+# copy clean zconf.h for subsequent edits
+cp -p ${SRCDIR}zconf.h.in zconf.h
+
+echo >> configure.log
+
+# check for unistd.h and save result in zconf.h
+cat > $test.c <<EOF
+#include <unistd.h>
+int main() { return 0; }
+EOF
+if try $CC -c $CFLAGS $test.c; then
+  sed < zconf.h "/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\(.*\) may be/ 1\1 was/" > zconf.temp.h
+  mv zconf.temp.h zconf.h
+  echo "Checking for unistd.h... Yes." | tee -a configure.log
+else
+  echo "Checking for unistd.h... No." | tee -a configure.log
+fi
+
+echo >> configure.log
+
+# check for stdarg.h and save result in zconf.h
+cat > $test.c <<EOF
+#include <stdarg.h>
+int main() { return 0; }
+EOF
+if try $CC -c $CFLAGS $test.c; then
+  sed < zconf.h "/^#ifdef HAVE_STDARG_H.* may be/s/def HAVE_STDARG_H\(.*\) may be/ 1\1 was/" > zconf.temp.h
+  mv zconf.temp.h zconf.h
+  echo "Checking for stdarg.h... Yes." | tee -a configure.log
+else
+  echo "Checking for stdarg.h... No." | tee -a configure.log
+fi
+
+# if the z_ prefix was requested, save that in zconf.h
+if test $zprefix -eq 1; then
+  sed < zconf.h "/#ifdef Z_PREFIX.* may be/s/def Z_PREFIX\(.*\) may be/ 1\1 was/" > zconf.temp.h
+  mv zconf.temp.h zconf.h
+  echo >> configure.log
+  echo "Using z_ prefix on all symbols." | tee -a configure.log
+fi
+
+# if --solo compilation was requested, save that in zconf.h and remove gz stuff from object lists
+if test $solo -eq 1; then
+  sed '/#define ZCONF_H/a\
+#define Z_SOLO
+
+' < zconf.h > zconf.temp.h
+  mv zconf.temp.h zconf.h
+OBJC='$(OBJZ)'
+PIC_OBJC='$(PIC_OBJZ)'
+fi
+
+# if code coverage testing was requested, use older gcc if defined, e.g. "gcc-4.2" on Mac OS X
+if test $cover -eq 1; then
+  CFLAGS="${CFLAGS} -fprofile-arcs -ftest-coverage"
+  if test -n "$GCC_CLASSIC"; then
+    CC=$GCC_CLASSIC
+  fi
+fi
+
+echo >> configure.log
+
+# conduct a series of tests to resolve eight possible cases of using "vs" or "s" printf functions
+# (using stdarg or not), with or without "n" (proving size of buffer), and with or without a
+# return value.  The most secure result is vsnprintf() with a return value.  snprintf() with a
+# return value is secure as well, but then gzprintf() will be limited to 20 arguments.
+cat > $test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+#include "zconf.h"
+int main()
+{
+#ifndef STDC
+  choke me
+#endif
+  return 0;
+}
+EOF
+if try $CC -c $CFLAGS $test.c; then
+  echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()." | tee -a configure.log
+
+  echo >> configure.log
+  cat > $test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+int mytest(const char *fmt, ...)
+{
+  char buf[20];
+  va_list ap;
+  va_start(ap, fmt);
+  vsnprintf(buf, sizeof(buf), fmt, ap);
+  va_end(ap);
+  return 0;
+}
+int main()
+{
+  return (mytest("Hello%d\n", 1));
+}
+EOF
+  if try $CC $CFLAGS -o $test $test.c; then
+    echo "Checking for vsnprintf() in stdio.h... Yes." | tee -a configure.log
+
+    echo >> configure.log
+    cat >$test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+int mytest(const char *fmt, ...)
+{
+  int n;
+  char buf[20];
+  va_list ap;
+  va_start(ap, fmt);
+  n = vsnprintf(buf, sizeof(buf), fmt, ap);
+  va_end(ap);
+  return n;
+}
+int main()
+{
+  return (mytest("Hello%d\n", 1));
+}
+EOF
+
+    if try $CC -c $CFLAGS $test.c; then
+      echo "Checking for return value of vsnprintf()... Yes." | tee -a configure.log
+    else
+      CFLAGS="$CFLAGS -DHAS_vsnprintf_void"
+      SFLAGS="$SFLAGS -DHAS_vsnprintf_void"
+      echo "Checking for return value of vsnprintf()... No." | tee -a configure.log
+      echo "  WARNING: apparently vsnprintf() does not return a value. zlib" | tee -a configure.log
+      echo "  can build but will be open to possible string-format security" | tee -a configure.log
+      echo "  vulnerabilities." | tee -a configure.log
+    fi
+  else
+    CFLAGS="$CFLAGS -DNO_vsnprintf"
+    SFLAGS="$SFLAGS -DNO_vsnprintf"
+    echo "Checking for vsnprintf() in stdio.h... No." | tee -a configure.log
+    echo "  WARNING: vsnprintf() not found, falling back to vsprintf(). zlib" | tee -a configure.log
+    echo "  can build but will be open to possible buffer-overflow security" | tee -a configure.log
+    echo "  vulnerabilities." | tee -a configure.log
+
+    echo >> configure.log
+    cat >$test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+int mytest(const char *fmt, ...)
+{
+  int n;
+  char buf[20];
+  va_list ap;
+  va_start(ap, fmt);
+  n = vsprintf(buf, fmt, ap);
+  va_end(ap);
+  return n;
+}
+int main()
+{
+  return (mytest("Hello%d\n", 1));
+}
+EOF
+
+    if try $CC -c $CFLAGS $test.c; then
+      echo "Checking for return value of vsprintf()... Yes." | tee -a configure.log
+    else
+      CFLAGS="$CFLAGS -DHAS_vsprintf_void"
+      SFLAGS="$SFLAGS -DHAS_vsprintf_void"
+      echo "Checking for return value of vsprintf()... No." | tee -a configure.log
+      echo "  WARNING: apparently vsprintf() does not return a value. zlib" | tee -a configure.log
+      echo "  can build but will be open to possible string-format security" | tee -a configure.log
+      echo "  vulnerabilities." | tee -a configure.log
+    fi
+  fi
+else
+  echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()." | tee -a configure.log
+
+  echo >> configure.log
+  cat >$test.c <<EOF
+#include <stdio.h>
+int mytest()
+{
+  char buf[20];
+  snprintf(buf, sizeof(buf), "%s", "foo");
+  return 0;
+}
+int main()
+{
+  return (mytest());
+}
+EOF
+
+  if try $CC $CFLAGS -o $test $test.c; then
+    echo "Checking for snprintf() in stdio.h... Yes." | tee -a configure.log
+
+    echo >> configure.log
+    cat >$test.c <<EOF
+#include <stdio.h>
+int mytest()
+{
+  char buf[20];
+  return snprintf(buf, sizeof(buf), "%s", "foo");
+}
+int main()
+{
+  return (mytest());
+}
+EOF
+
+    if try $CC -c $CFLAGS $test.c; then
+      echo "Checking for return value of snprintf()... Yes." | tee -a configure.log
+    else
+      CFLAGS="$CFLAGS -DHAS_snprintf_void"
+      SFLAGS="$SFLAGS -DHAS_snprintf_void"
+      echo "Checking for return value of snprintf()... No." | tee -a configure.log
+      echo "  WARNING: apparently snprintf() does not return a value. zlib" | tee -a configure.log
+      echo "  can build but will be open to possible string-format security" | tee -a configure.log
+      echo "  vulnerabilities." | tee -a configure.log
+    fi
+  else
+    CFLAGS="$CFLAGS -DNO_snprintf"
+    SFLAGS="$SFLAGS -DNO_snprintf"
+    echo "Checking for snprintf() in stdio.h... No." | tee -a configure.log
+    echo "  WARNING: snprintf() not found, falling back to sprintf(). zlib" | tee -a configure.log
+    echo "  can build but will be open to possible buffer-overflow security" | tee -a configure.log
+    echo "  vulnerabilities." | tee -a configure.log
+
+    echo >> configure.log
+    cat >$test.c <<EOF
+#include <stdio.h>
+int mytest()
+{
+  char buf[20];
+  return sprintf(buf, "%s", "foo");
+}
+int main()
+{
+  return (mytest());
+}
+EOF
+
+    if try $CC -c $CFLAGS $test.c; then
+      echo "Checking for return value of sprintf()... Yes." | tee -a configure.log
+    else
+      CFLAGS="$CFLAGS -DHAS_sprintf_void"
+      SFLAGS="$SFLAGS -DHAS_sprintf_void"
+      echo "Checking for return value of sprintf()... No." | tee -a configure.log
+      echo "  WARNING: apparently sprintf() does not return a value. zlib" | tee -a configure.log
+      echo "  can build but will be open to possible string-format security" | tee -a configure.log
+      echo "  vulnerabilities." | tee -a configure.log
+    fi
+  fi
+fi
+
+# see if we can hide zlib internal symbols that are linked between separate source files
+if test "$gcc" -eq 1; then
+  echo >> configure.log
+  cat > $test.c <<EOF
+#define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+int ZLIB_INTERNAL foo;
+int main()
+{
+  return 0;
+}
+EOF
+  if tryboth $CC -c $CFLAGS $test.c; then
+    CFLAGS="$CFLAGS -DHAVE_HIDDEN"
+    SFLAGS="$SFLAGS -DHAVE_HIDDEN"
+    echo "Checking for attribute(visibility) support... Yes." | tee -a configure.log
+  else
+    echo "Checking for attribute(visibility) support... No." | tee -a configure.log
+  fi
+fi
+
+# show the results in the log
+echo >> configure.log
+echo ALL = $ALL >> configure.log
+echo AR = $AR >> configure.log
+echo ARFLAGS = $ARFLAGS >> configure.log
+echo CC = $CC >> configure.log
+echo CFLAGS = $CFLAGS >> configure.log
+echo CPP = $CPP >> configure.log
+echo EXE = $EXE >> configure.log
+echo LDCONFIG = $LDCONFIG >> configure.log
+echo LDFLAGS = $LDFLAGS >> configure.log
+echo LDSHARED = $LDSHARED >> configure.log
+echo LDSHAREDLIBC = $LDSHAREDLIBC >> configure.log
+echo OBJC = $OBJC >> configure.log
+echo PIC_OBJC = $PIC_OBJC >> configure.log
+echo RANLIB = $RANLIB >> configure.log
+echo SFLAGS = $SFLAGS >> configure.log
+echo SHAREDLIB = $SHAREDLIB >> configure.log
+echo SHAREDLIBM = $SHAREDLIBM >> configure.log
+echo SHAREDLIBV = $SHAREDLIBV >> configure.log
+echo STATICLIB = $STATICLIB >> configure.log
+echo TEST = $TEST >> configure.log
+echo VER = $VER >> configure.log
+echo Z_U4 = $Z_U4 >> configure.log
+echo SRCDIR = $SRCDIR >> configure.log
+echo exec_prefix = $exec_prefix >> configure.log
+echo includedir = $includedir >> configure.log
+echo libdir = $libdir >> configure.log
+echo mandir = $mandir >> configure.log
+echo prefix = $prefix >> configure.log
+echo sharedlibdir = $sharedlibdir >> configure.log
+echo uname = $uname >> configure.log
+
+# udpate Makefile with the configure results
+sed < ${SRCDIR}Makefile.in "
+/^CC *=/s#=.*#=$CC#
+/^CFLAGS *=/s#=.*#=$CFLAGS#
+/^SFLAGS *=/s#=.*#=$SFLAGS#
+/^LDFLAGS *=/s#=.*#=$LDFLAGS#
+/^LDSHARED *=/s#=.*#=$LDSHARED#
+/^CPP *=/s#=.*#=$CPP#
+/^STATICLIB *=/s#=.*#=$STATICLIB#
+/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
+/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#
+/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#
+/^AR *=/s#=.*#=$AR#
+/^ARFLAGS *=/s#=.*#=$ARFLAGS#
+/^RANLIB *=/s#=.*#=$RANLIB#
+/^LDCONFIG *=/s#=.*#=$LDCONFIG#
+/^LDSHAREDLIBC *=/s#=.*#=$LDSHAREDLIBC#
+/^EXE *=/s#=.*#=$EXE#
+/^SRCDIR *=/s#=.*#=$SRCDIR#
+/^ZINC *=/s#=.*#=$ZINC#
+/^ZINCOUT *=/s#=.*#=$ZINCOUT#
+/^prefix *=/s#=.*#=$prefix#
+/^exec_prefix *=/s#=.*#=$exec_prefix#
+/^libdir *=/s#=.*#=$libdir#
+/^sharedlibdir *=/s#=.*#=$sharedlibdir#
+/^includedir *=/s#=.*#=$includedir#
+/^mandir *=/s#=.*#=$mandir#
+/^OBJC *=/s#=.*#= $OBJC#
+/^PIC_OBJC *=/s#=.*#= $PIC_OBJC#
+/^all: */s#:.*#: $ALL#
+/^test: */s#:.*#: $TEST#
+" > Makefile
+
+# create zlib.pc with the configure results
+sed < ${SRCDIR}zlib.pc.in "
+/^CC *=/s#=.*#=$CC#
+/^CFLAGS *=/s#=.*#=$CFLAGS#
+/^CPP *=/s#=.*#=$CPP#
+/^LDSHARED *=/s#=.*#=$LDSHARED#
+/^STATICLIB *=/s#=.*#=$STATICLIB#
+/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
+/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#
+/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#
+/^AR *=/s#=.*#=$AR#
+/^ARFLAGS *=/s#=.*#=$ARFLAGS#
+/^RANLIB *=/s#=.*#=$RANLIB#
+/^EXE *=/s#=.*#=$EXE#
+/^prefix *=/s#=.*#=$prefix#
+/^exec_prefix *=/s#=.*#=$exec_prefix#
+/^libdir *=/s#=.*#=$libdir#
+/^sharedlibdir *=/s#=.*#=$sharedlibdir#
+/^includedir *=/s#=.*#=$includedir#
+/^mandir *=/s#=.*#=$mandir#
+/^LDFLAGS *=/s#=.*#=$LDFLAGS#
+" | sed -e "
+s/\@VERSION\@/$VER/g;
+" > zlib.pc
+
+# done
+leave 0
Index: EcnlProtoTool/trunk/zlib-1.2.11/crc32.c
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/crc32.c	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/crc32.c	(revision 331)
@@ -0,0 +1,442 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2006, 2010, 2011, 2012, 2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
+ * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
+ * tables for updating the shift register in one step with three exclusive-ors
+ * instead of four steps with four exclusive-ors.  This results in about a
+ * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ */
+
+/* @(#) $Id$ */
+
+/*
+  Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
+  protection on the static variables used to control the first-use generation
+  of the crc tables.  Therefore, if you #define DYNAMIC_CRC_TABLE, you should
+  first call get_crc_table() to initialize the tables before allowing more than
+  one thread to use crc32().
+
+  DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
+ */
+
+#ifdef MAKECRCH
+#  include <stdio.h>
+#  ifndef DYNAMIC_CRC_TABLE
+#    define DYNAMIC_CRC_TABLE
+#  endif /* !DYNAMIC_CRC_TABLE */
+#endif /* MAKECRCH */
+
+#include "zutil.h"      /* for STDC and FAR definitions */
+
+/* Definitions for doing the crc four data bytes at a time. */
+#if !defined(NOBYFOUR) && defined(Z_U4)
+#  define BYFOUR
+#endif
+#ifdef BYFOUR
+   local unsigned long crc32_little OF((unsigned long,
+                        const unsigned char FAR *, z_size_t));
+   local unsigned long crc32_big OF((unsigned long,
+                        const unsigned char FAR *, z_size_t));
+#  define TBLS 8
+#else
+#  define TBLS 1
+#endif /* BYFOUR */
+
+/* Local functions for crc concatenation */
+local unsigned long gf2_matrix_times OF((unsigned long *mat,
+                                         unsigned long vec));
+local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
+local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
+
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local volatile int crc_table_empty = 1;
+local z_crc_t FAR crc_table[TBLS][256];
+local void make_crc_table OF((void));
+#ifdef MAKECRCH
+   local void write_table OF((FILE *, const z_crc_t FAR *));
+#endif /* MAKECRCH */
+/*
+  Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
+  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+  Polynomials over GF(2) are represented in binary, one bit per coefficient,
+  with the lowest powers in the most significant bit.  Then adding polynomials
+  is just exclusive-or, and multiplying a polynomial by x is a right shift by
+  one.  If we call the above polynomial p, and represent a byte as the
+  polynomial q, also with the lowest power in the most significant bit (so the
+  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+  where a mod b means the remainder after dividing a by b.
+
+  This calculation is done using the shift-register method of multiplying and
+  taking the remainder.  The register is initialized to zero, and for each
+  incoming bit, x^32 is added mod p to the register if the bit is a one (where
+  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+  x (which is shifting right by one and adding x^32 mod p if the bit shifted
+  out is a one).  We start with the highest power (least significant bit) of
+  q and repeat for all eight bits of q.
+
+  The first table is simply the CRC of all possible eight bit values.  This is
+  all the information needed to generate CRCs on data a byte at a time for all
+  combinations of CRC register values and incoming bytes.  The remaining tables
+  allow for word-at-a-time CRC calculation for both big-endian and little-
+  endian machines, where a word is four bytes.
+*/
+local void make_crc_table()
+{
+    z_crc_t c;
+    int n, k;
+    z_crc_t poly;                       /* polynomial exclusive-or pattern */
+    /* terms of polynomial defining this crc (except x^32): */
+    static volatile int first = 1;      /* flag to limit concurrent making */
+    static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+    /* See if another task is already doing this (not thread-safe, but better
+       than nothing -- significantly reduces duration of vulnerability in
+       case the advice about DYNAMIC_CRC_TABLE is ignored) */
+    if (first) {
+        first = 0;
+
+        /* make exclusive-or pattern from polynomial (0xedb88320UL) */
+        poly = 0;
+        for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
+            poly |= (z_crc_t)1 << (31 - p[n]);
+
+        /* generate a crc for every 8-bit value */
+        for (n = 0; n < 256; n++) {
+            c = (z_crc_t)n;
+            for (k = 0; k < 8; k++)
+                c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+            crc_table[0][n] = c;
+        }
+
+#ifdef BYFOUR
+        /* generate crc for each value followed by one, two, and three zeros,
+           and then the byte reversal of those as well as the first table */
+        for (n = 0; n < 256; n++) {
+            c = crc_table[0][n];
+            crc_table[4][n] = ZSWAP32(c);
+            for (k = 1; k < 4; k++) {
+                c = crc_table[0][c & 0xff] ^ (c >> 8);
+                crc_table[k][n] = c;
+                crc_table[k + 4][n] = ZSWAP32(c);
+            }
+        }
+#endif /* BYFOUR */
+
+        crc_table_empty = 0;
+    }
+    else {      /* not first */
+        /* wait for the other guy to finish (not efficient, but rare) */
+        while (crc_table_empty)
+            ;
+    }
+
+#ifdef MAKECRCH
+    /* write out CRC tables to crc32.h */
+    {
+        FILE *out;
+
+        out = fopen("crc32.h", "w");
+        if (out == NULL) return;
+        fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
+        fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
+        fprintf(out, "local const z_crc_t FAR ");
+        fprintf(out, "crc_table[TBLS][256] =\n{\n  {\n");
+        write_table(out, crc_table[0]);
+#  ifdef BYFOUR
+        fprintf(out, "#ifdef BYFOUR\n");
+        for (k = 1; k < 8; k++) {
+            fprintf(out, "  },\n  {\n");
+            write_table(out, crc_table[k]);
+        }
+        fprintf(out, "#endif\n");
+#  endif /* BYFOUR */
+        fprintf(out, "  }\n};\n");
+        fclose(out);
+    }
+#endif /* MAKECRCH */
+}
+
+#ifdef MAKECRCH
+local void write_table(out, table)
+    FILE *out;
+    const z_crc_t FAR *table;
+{
+    int n;
+
+    for (n = 0; n < 256; n++)
+        fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : "    ",
+                (unsigned long)(table[n]),
+                n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
+}
+#endif /* MAKECRCH */
+
+#else /* !DYNAMIC_CRC_TABLE */
+/* ========================================================================
+ * Tables of CRC-32s of all single-byte values, made by make_crc_table().
+ */
+#include "crc32.h"
+#endif /* DYNAMIC_CRC_TABLE */
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const z_crc_t FAR * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+        make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+    return (const z_crc_t FAR *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
+#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32_z(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    z_size_t len;
+{
+    if (buf == Z_NULL) return 0UL;
+
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+        make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+
+#ifdef BYFOUR
+    if (sizeof(void *) == sizeof(ptrdiff_t)) {
+        z_crc_t endian;
+
+        endian = 1;
+        if (*((unsigned char *)(&endian)))
+            return crc32_little(crc, buf, len);
+        else
+            return crc32_big(crc, buf, len);
+    }
+#endif /* BYFOUR */
+    crc = crc ^ 0xffffffffUL;
+    while (len >= 8) {
+        DO8;
+        len -= 8;
+    }
+    if (len) do {
+        DO1;
+    } while (--len);
+    return crc ^ 0xffffffffUL;
+}
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    uInt len;
+{
+    return crc32_z(crc, buf, len);
+}
+
+#ifdef BYFOUR
+
+/*
+   This BYFOUR code accesses the passed unsigned char * buffer with a 32-bit
+   integer pointer type. This violates the strict aliasing rule, where a
+   compiler can assume, for optimization purposes, that two pointers to
+   fundamentally different types won't ever point to the same memory. This can
+   manifest as a problem only if one of the pointers is written to. This code
+   only reads from those pointers. So long as this code remains isolated in
+   this compilation unit, there won't be a problem. For this reason, this code
+   should not be copied and pasted into a compilation unit in which other code
+   writes to the buffer that is passed to these routines.
+ */
+
+/* ========================================================================= */
+#define DOLIT4 c ^= *buf4++; \
+        c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
+            crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
+#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
+
+/* ========================================================================= */
+local unsigned long crc32_little(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    z_size_t len;
+{
+    register z_crc_t c;
+    register const z_crc_t FAR *buf4;
+
+    c = (z_crc_t)crc;
+    c = ~c;
+    while (len && ((ptrdiff_t)buf & 3)) {
+        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+        len--;
+    }
+
+    buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
+    while (len >= 32) {
+        DOLIT32;
+        len -= 32;
+    }
+    while (len >= 4) {
+        DOLIT4;
+        len -= 4;
+    }
+    buf = (const unsigned char FAR *)buf4;
+
+    if (len) do {
+        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+    } while (--len);
+    c = ~c;
+    return (unsigned long)c;
+}
+
+/* ========================================================================= */
+#define DOBIG4 c ^= *buf4++; \
+        c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
+            crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
+#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
+
+/* ========================================================================= */
+local unsigned long crc32_big(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    z_size_t len;
+{
+    register z_crc_t c;
+    register const z_crc_t FAR *buf4;
+
+    c = ZSWAP32((z_crc_t)crc);
+    c = ~c;
+    while (len && ((ptrdiff_t)buf & 3)) {
+        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+        len--;
+    }
+
+    buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
+    while (len >= 32) {
+        DOBIG32;
+        len -= 32;
+    }
+    while (len >= 4) {
+        DOBIG4;
+        len -= 4;
+    }
+    buf = (const unsigned char FAR *)buf4;
+
+    if (len) do {
+        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+    } while (--len);
+    c = ~c;
+    return (unsigned long)(ZSWAP32(c));
+}
+
+#endif /* BYFOUR */
+
+#define GF2_DIM 32      /* dimension of GF(2) vectors (length of CRC) */
+
+/* ========================================================================= */
+local unsigned long gf2_matrix_times(mat, vec)
+    unsigned long *mat;
+    unsigned long vec;
+{
+    unsigned long sum;
+
+    sum = 0;
+    while (vec) {
+        if (vec & 1)
+            sum ^= *mat;
+        vec >>= 1;
+        mat++;
+    }
+    return sum;
+}
+
+/* ========================================================================= */
+local void gf2_matrix_square(square, mat)
+    unsigned long *square;
+    unsigned long *mat;
+{
+    int n;
+
+    for (n = 0; n < GF2_DIM; n++)
+        square[n] = gf2_matrix_times(mat, mat[n]);
+}
+
+/* ========================================================================= */
+local uLong crc32_combine_(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off64_t len2;
+{
+    int n;
+    unsigned long row;
+    unsigned long even[GF2_DIM];    /* even-power-of-two zeros operator */
+    unsigned long odd[GF2_DIM];     /* odd-power-of-two zeros operator */
+
+    /* degenerate case (also disallow negative lengths) */
+    if (len2 <= 0)
+        return crc1;
+
+    /* put operator for one zero bit in odd */
+    odd[0] = 0xedb88320UL;          /* CRC-32 polynomial */
+    row = 1;
+    for (n = 1; n < GF2_DIM; n++) {
+        odd[n] = row;
+        row <<= 1;
+    }
+
+    /* put operator for two zero bits in even */
+    gf2_matrix_square(even, odd);
+
+    /* put operator for four zero bits in odd */
+    gf2_matrix_square(odd, even);
+
+    /* apply len2 zeros to crc1 (first square will put the operator for one
+       zero byte, eight zero bits, in even) */
+    do {
+        /* apply zeros operator for this bit of len2 */
+        gf2_matrix_square(even, odd);
+        if (len2 & 1)
+            crc1 = gf2_matrix_times(even, crc1);
+        len2 >>= 1;
+
+        /* if no more bits set, then done */
+        if (len2 == 0)
+            break;
+
+        /* another iteration of the loop with odd and even swapped */
+        gf2_matrix_square(odd, even);
+        if (len2 & 1)
+            crc1 = gf2_matrix_times(odd, crc1);
+        len2 >>= 1;
+
+        /* if no more bits set, then done */
+    } while (len2 != 0);
+
+    /* return combined crc */
+    crc1 ^= crc2;
+    return crc1;
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off_t len2;
+{
+    return crc32_combine_(crc1, crc2, len2);
+}
+
+uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off64_t len2;
+{
+    return crc32_combine_(crc1, crc2, len2);
+}
Index: EcnlProtoTool/trunk/zlib-1.2.11/crc32.h
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/crc32.h	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/crc32.h	(revision 331)
@@ -0,0 +1,441 @@
+/* crc32.h -- tables for rapid CRC calculation
+ * Generated automatically by crc32.c
+ */
+
+local const z_crc_t FAR crc_table[TBLS][256] =
+{
+  {
+    0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
+    0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
+    0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
+    0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
+    0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
+    0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
+    0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
+    0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
+    0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
+    0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
+    0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
+    0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
+    0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
+    0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
+    0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
+    0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
+    0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
+    0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
+    0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
+    0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
+    0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
+    0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
+    0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
+    0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
+    0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
+    0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
+    0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
+    0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
+    0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
+    0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
+    0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
+    0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
+    0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
+    0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
+    0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
+    0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
+    0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
+    0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
+    0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
+    0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
+    0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
+    0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
+    0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
+    0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
+    0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
+    0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
+    0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
+    0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
+    0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
+    0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
+    0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
+    0x2d02ef8dUL
+#ifdef BYFOUR
+  },
+  {
+    0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
+    0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
+    0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
+    0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
+    0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
+    0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
+    0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
+    0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
+    0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
+    0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
+    0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
+    0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
+    0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
+    0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
+    0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
+    0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
+    0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
+    0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
+    0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
+    0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
+    0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
+    0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
+    0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
+    0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
+    0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
+    0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
+    0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
+    0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
+    0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
+    0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
+    0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
+    0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
+    0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
+    0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
+    0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
+    0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
+    0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
+    0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
+    0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
+    0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
+    0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
+    0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
+    0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
+    0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
+    0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
+    0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
+    0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
+    0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
+    0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
+    0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
+    0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
+    0x9324fd72UL
+  },
+  {
+    0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
+    0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
+    0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
+    0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
+    0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
+    0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
+    0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
+    0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
+    0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
+    0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
+    0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
+    0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
+    0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
+    0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
+    0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
+    0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
+    0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
+    0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
+    0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
+    0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
+    0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
+    0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
+    0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
+    0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
+    0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
+    0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
+    0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
+    0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
+    0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
+    0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
+    0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
+    0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
+    0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
+    0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
+    0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
+    0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
+    0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
+    0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
+    0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
+    0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
+    0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
+    0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
+    0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
+    0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
+    0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
+    0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
+    0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
+    0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
+    0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
+    0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
+    0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
+    0xbe9834edUL
+  },
+  {
+    0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
+    0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
+    0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
+    0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
+    0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
+    0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
+    0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
+    0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
+    0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
+    0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
+    0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
+    0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
+    0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
+    0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
+    0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
+    0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
+    0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
+    0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
+    0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
+    0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
+    0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
+    0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
+    0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
+    0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
+    0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
+    0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
+    0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
+    0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
+    0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
+    0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
+    0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
+    0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
+    0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
+    0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
+    0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
+    0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
+    0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
+    0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
+    0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
+    0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
+    0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
+    0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
+    0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
+    0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
+    0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
+    0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
+    0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
+    0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
+    0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
+    0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
+    0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
+    0xde0506f1UL
+  },
+  {
+    0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
+    0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
+    0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
+    0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
+    0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
+    0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
+    0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
+    0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
+    0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
+    0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
+    0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
+    0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
+    0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
+    0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
+    0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
+    0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
+    0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
+    0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
+    0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
+    0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
+    0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
+    0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
+    0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
+    0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
+    0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
+    0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
+    0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
+    0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
+    0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
+    0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
+    0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
+    0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
+    0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
+    0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
+    0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
+    0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
+    0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
+    0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
+    0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
+    0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
+    0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
+    0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
+    0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
+    0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
+    0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
+    0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
+    0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
+    0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
+    0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
+    0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
+    0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
+    0x8def022dUL
+  },
+  {
+    0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
+    0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
+    0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
+    0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
+    0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
+    0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
+    0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
+    0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
+    0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
+    0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
+    0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
+    0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
+    0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
+    0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
+    0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
+    0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
+    0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
+    0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
+    0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
+    0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
+    0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
+    0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
+    0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
+    0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
+    0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
+    0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
+    0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
+    0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
+    0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
+    0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
+    0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
+    0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
+    0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
+    0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
+    0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
+    0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
+    0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
+    0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
+    0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
+    0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
+    0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
+    0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
+    0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
+    0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
+    0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
+    0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
+    0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
+    0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
+    0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
+    0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
+    0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
+    0x72fd2493UL
+  },
+  {
+    0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
+    0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
+    0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
+    0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
+    0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
+    0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
+    0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
+    0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
+    0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
+    0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
+    0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
+    0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
+    0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
+    0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
+    0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
+    0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
+    0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
+    0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
+    0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
+    0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
+    0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
+    0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
+    0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
+    0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
+    0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
+    0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
+    0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
+    0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
+    0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
+    0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
+    0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
+    0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
+    0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
+    0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
+    0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
+    0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
+    0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
+    0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
+    0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
+    0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
+    0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
+    0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
+    0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
+    0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
+    0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
+    0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
+    0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
+    0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
+    0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
+    0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
+    0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
+    0xed3498beUL
+  },
+  {
+    0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
+    0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
+    0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
+    0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
+    0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
+    0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
+    0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
+    0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
+    0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
+    0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
+    0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
+    0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
+    0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
+    0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
+    0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
+    0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
+    0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
+    0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
+    0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
+    0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
+    0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
+    0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
+    0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
+    0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
+    0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
+    0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
+    0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
+    0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
+    0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
+    0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
+    0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
+    0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
+    0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
+    0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
+    0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
+    0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
+    0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
+    0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
+    0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
+    0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
+    0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
+    0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
+    0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
+    0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
+    0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
+    0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
+    0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
+    0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
+    0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
+    0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
+    0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
+    0xf10605deUL
+#endif
+  }
+};
Index: EcnlProtoTool/trunk/zlib-1.2.11/deflate.c
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/deflate.c	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/deflate.c	(revision 331)
@@ -0,0 +1,2163 @@
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process depends on being able to identify portions
+ *      of the input text which are identical to earlier input (within a
+ *      sliding window trailing behind the input currently being processed).
+ *
+ *      The most straightforward technique turns out to be the fastest for
+ *      most input files: try all possible matches and select the longest.
+ *      The key feature of this algorithm is that insertions into the string
+ *      dictionary are very simple and thus fast, and deletions are avoided
+ *      completely. Insertions are performed at each input character, whereas
+ *      string matches are performed only when the previous match ends. So it
+ *      is preferable to spend more time in matches to allow very fast string
+ *      insertions and avoid deletions. The matching algorithm for small
+ *      strings is inspired from that of Rabin & Karp. A brute force approach
+ *      is used to find longer strings when a small match has been found.
+ *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ *      (by Leonid Broukhis).
+ *         A previous version of this file used a more sophisticated algorithm
+ *      (by Fiala and Greene) which is guaranteed to run in linear amortized
+ *      time, but has a larger average cost, uses more memory and is patented.
+ *      However the F&G algorithm may be faster for some highly redundant
+ *      files if the parameter max_chain_length (described below) is too large.
+ *
+ *  ACKNOWLEDGEMENTS
+ *
+ *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ *      I found it in 'freeze' written by Leonid Broukhis.
+ *      Thanks to many people for bug reports and testing.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ *      Available in http://tools.ietf.org/html/rfc1951
+ *
+ *      A description of the Rabin and Karp algorithm is given in the book
+ *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ *      Fiala,E.R., and Greene,D.H.
+ *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $Id$ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+   " deflate 1.2.11 Copyright 1995-2017 Jean-loup Gailly and Mark Adler ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ *  Function prototypes.
+ */
+typedef enum {
+    need_more,      /* block not completed, need more input or more output */
+    block_done,     /* block flush performed */
+    finish_started, /* finish started, need only more output at next deflate */
+    finish_done     /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local int deflateStateCheck      OF((z_streamp strm));
+local void slide_hash     OF((deflate_state *s));
+local void fill_window    OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast   OF((deflate_state *s, int flush));
+#ifndef FASTEST
+local block_state deflate_slow   OF((deflate_state *s, int flush));
+#endif
+local block_state deflate_rle    OF((deflate_state *s, int flush));
+local block_state deflate_huff   OF((deflate_state *s, int flush));
+local void lm_init        OF((deflate_state *s));
+local void putShortMSB    OF((deflate_state *s, uInt b));
+local void flush_pending  OF((z_streamp strm));
+local unsigned read_buf   OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifdef ASMV
+#  pragma message("Assembler code may have bugs -- use at your own risk")
+      void match_init OF((void)); /* asm code initialization */
+      uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#endif
+
+#ifdef ZLIB_DEBUG
+local  void check_match OF((deflate_state *s, IPos start, IPos match,
+                            int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+#  define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+   ush good_length; /* reduce lazy search above this match length */
+   ush max_lazy;    /* do not perform lazy search above this match length */
+   ush nice_length; /* quit search above this match length */
+   ush max_chain;
+   compress_func func;
+} config;
+
+#ifdef FASTEST
+local const config configuration_table[2] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}}; /* max speed, no lazy matches */
+#else
+local const config configuration_table[10] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}, /* max speed, no lazy matches */
+/* 2 */ {4,    5, 16,    8, deflate_fast},
+/* 3 */ {4,    6, 32,   32, deflate_fast},
+
+/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
+/* 5 */ {8,   16, 32,   32, deflate_slow},
+/* 6 */ {8,   16, 128, 128, deflate_slow},
+/* 7 */ {8,   32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
+#endif
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */
+#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0))
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN  assertion: all calls to UPDATE_HASH are made with consecutive input
+ *    characters, so that a running hash key can be computed from the previous
+ *    key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN  assertion: all calls to INSERT_STRING are made with consecutive input
+ *    characters and the first MIN_MATCH bytes of str are valid (except for
+ *    the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    match_head = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+    s->head[s->hash_size-1] = NIL; \
+    zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ===========================================================================
+ * Slide the hash table when sliding the window down (could be avoided with 32
+ * bit values at the expense of memory usage). We slide even when level == 0 to
+ * keep the hash table consistent if we switch back to level > 0 later.
+ */
+local void slide_hash(s)
+    deflate_state *s;
+{
+    unsigned n, m;
+    Posf *p;
+    uInt wsize = s->w_size;
+
+    n = s->hash_size;
+    p = &s->head[n];
+    do {
+        m = *--p;
+        *p = (Pos)(m >= wsize ? m - wsize : NIL);
+    } while (--n);
+    n = wsize;
+#ifndef FASTEST
+    p = &s->prev[n];
+    do {
+        m = *--p;
+        *p = (Pos)(m >= wsize ? m - wsize : NIL);
+        /* If n is not on any hash chain, prev[n] is garbage but
+         * its value will never be used.
+         */
+    } while (--n);
+#endif
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+    z_streamp strm;
+    int level;
+    const char *version;
+    int stream_size;
+{
+    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+                         Z_DEFAULT_STRATEGY, version, stream_size);
+    /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+                  version, stream_size)
+    z_streamp strm;
+    int  level;
+    int  method;
+    int  windowBits;
+    int  memLevel;
+    int  strategy;
+    const char *version;
+    int stream_size;
+{
+    deflate_state *s;
+    int wrap = 1;
+    static const char my_version[] = ZLIB_VERSION;
+
+    ushf *overlay;
+    /* We overlay pending_buf and d_buf+l_buf. This works since the average
+     * output size for (length,distance) codes is <= 24 bits.
+     */
+
+    if (version == Z_NULL || version[0] != my_version[0] ||
+        stream_size != sizeof(z_stream)) {
+        return Z_VERSION_ERROR;
+    }
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+    strm->msg = Z_NULL;
+    if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+        return Z_STREAM_ERROR;
+#else
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+#endif
+    }
+    if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+        return Z_STREAM_ERROR;
+#else
+        strm->zfree = zcfree;
+#endif
+
+#ifdef FASTEST
+    if (level != 0) level = 1;
+#else
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+
+    if (windowBits < 0) { /* suppress zlib wrapper */
+        wrap = 0;
+        windowBits = -windowBits;
+    }
+#ifdef GZIP
+    else if (windowBits > 15) {
+        wrap = 2;       /* write gzip wrapper instead */
+        windowBits -= 16;
+    }
+#endif
+    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+        strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) {
+        return Z_STREAM_ERROR;
+    }
+    if (windowBits == 8) windowBits = 9;  /* until 256-byte window bug fixed */
+    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+    if (s == Z_NULL) return Z_MEM_ERROR;
+    strm->state = (struct internal_state FAR *)s;
+    s->strm = strm;
+    s->status = INIT_STATE;     /* to pass state test in deflateReset() */
+
+    s->wrap = wrap;
+    s->gzhead = Z_NULL;
+    s->w_bits = (uInt)windowBits;
+    s->w_size = 1 << s->w_bits;
+    s->w_mask = s->w_size - 1;
+
+    s->hash_bits = (uInt)memLevel + 7;
+    s->hash_size = 1 << s->hash_bits;
+    s->hash_mask = s->hash_size - 1;
+    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
+    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+    s->high_water = 0;      /* nothing written to s->window yet */
+
+    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+    s->pending_buf = (uchf *) overlay;
+    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+        s->pending_buf == Z_NULL) {
+        s->status = FINISH_STATE;
+        strm->msg = ERR_MSG(Z_MEM_ERROR);
+        deflateEnd (strm);
+        return Z_MEM_ERROR;
+    }
+    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+    s->level = level;
+    s->strategy = strategy;
+    s->method = (Byte)method;
+
+    return deflateReset(strm);
+}
+
+/* =========================================================================
+ * Check for a valid deflate stream state. Return 0 if ok, 1 if not.
+ */
+local int deflateStateCheck (strm)
+    z_streamp strm;
+{
+    deflate_state *s;
+    if (strm == Z_NULL ||
+        strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
+        return 1;
+    s = strm->state;
+    if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE &&
+#ifdef GZIP
+                                           s->status != GZIP_STATE &&
+#endif
+                                           s->status != EXTRA_STATE &&
+                                           s->status != NAME_STATE &&
+                                           s->status != COMMENT_STATE &&
+                                           s->status != HCRC_STATE &&
+                                           s->status != BUSY_STATE &&
+                                           s->status != FINISH_STATE))
+        return 1;
+    return 0;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+    z_streamp strm;
+    const Bytef *dictionary;
+    uInt  dictLength;
+{
+    deflate_state *s;
+    uInt str, n;
+    int wrap;
+    unsigned avail;
+    z_const unsigned char *next;
+
+    if (deflateStateCheck(strm) || dictionary == Z_NULL)
+        return Z_STREAM_ERROR;
+    s = strm->state;
+    wrap = s->wrap;
+    if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)
+        return Z_STREAM_ERROR;
+
+    /* when using zlib wrappers, compute Adler-32 for provided dictionary */
+    if (wrap == 1)
+        strm->adler = adler32(strm->adler, dictionary, dictLength);
+    s->wrap = 0;                    /* avoid computing Adler-32 in read_buf */
+
+    /* if dictionary would fill window, just replace the history */
+    if (dictLength >= s->w_size) {
+        if (wrap == 0) {            /* already empty otherwise */
+            CLEAR_HASH(s);
+            s->strstart = 0;
+            s->block_start = 0L;
+            s->insert = 0;
+        }
+        dictionary += dictLength - s->w_size;  /* use the tail */
+        dictLength = s->w_size;
+    }
+
+    /* insert dictionary into window and hash */
+    avail = strm->avail_in;
+    next = strm->next_in;
+    strm->avail_in = dictLength;
+    strm->next_in = (z_const Bytef *)dictionary;
+    fill_window(s);
+    while (s->lookahead >= MIN_MATCH) {
+        str = s->strstart;
+        n = s->lookahead - (MIN_MATCH-1);
+        do {
+            UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
+#ifndef FASTEST
+            s->prev[str & s->w_mask] = s->head[s->ins_h];
+#endif
+            s->head[s->ins_h] = (Pos)str;
+            str++;
+        } while (--n);
+        s->strstart = str;
+        s->lookahead = MIN_MATCH-1;
+        fill_window(s);
+    }
+    s->strstart += s->lookahead;
+    s->block_start = (long)s->strstart;
+    s->insert = s->lookahead;
+    s->lookahead = 0;
+    s->match_length = s->prev_length = MIN_MATCH-1;
+    s->match_available = 0;
+    strm->next_in = next;
+    strm->avail_in = avail;
+    s->wrap = wrap;
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength)
+    z_streamp strm;
+    Bytef *dictionary;
+    uInt  *dictLength;
+{
+    deflate_state *s;
+    uInt len;
+
+    if (deflateStateCheck(strm))
+        return Z_STREAM_ERROR;
+    s = strm->state;
+    len = s->strstart + s->lookahead;
+    if (len > s->w_size)
+        len = s->w_size;
+    if (dictionary != Z_NULL && len)
+        zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len);
+    if (dictLength != Z_NULL)
+        *dictLength = len;
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateResetKeep (strm)
+    z_streamp strm;
+{
+    deflate_state *s;
+
+    if (deflateStateCheck(strm)) {
+        return Z_STREAM_ERROR;
+    }
+
+    strm->total_in = strm->total_out = 0;
+    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+    strm->data_type = Z_UNKNOWN;
+
+    s = (deflate_state *)strm->state;
+    s->pending = 0;
+    s->pending_out = s->pending_buf;
+
+    if (s->wrap < 0) {
+        s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
+    }
+    s->status =
+#ifdef GZIP
+        s->wrap == 2 ? GZIP_STATE :
+#endif
+        s->wrap ? INIT_STATE : BUSY_STATE;
+    strm->adler =
+#ifdef GZIP
+        s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
+#endif
+        adler32(0L, Z_NULL, 0);
+    s->last_flush = Z_NO_FLUSH;
+
+    _tr_init(s);
+
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+    z_streamp strm;
+{
+    int ret;
+
+    ret = deflateResetKeep(strm);
+    if (ret == Z_OK)
+        lm_init(strm->state);
+    return ret;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetHeader (strm, head)
+    z_streamp strm;
+    gz_headerp head;
+{
+    if (deflateStateCheck(strm) || strm->state->wrap != 2)
+        return Z_STREAM_ERROR;
+    strm->state->gzhead = head;
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePending (strm, pending, bits)
+    unsigned *pending;
+    int *bits;
+    z_streamp strm;
+{
+    if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
+    if (pending != Z_NULL)
+        *pending = strm->state->pending;
+    if (bits != Z_NULL)
+        *bits = strm->state->bi_valid;
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePrime (strm, bits, value)
+    z_streamp strm;
+    int bits;
+    int value;
+{
+    deflate_state *s;
+    int put;
+
+    if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
+    s = strm->state;
+    if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
+        return Z_BUF_ERROR;
+    do {
+        put = Buf_size - s->bi_valid;
+        if (put > bits)
+            put = bits;
+        s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid);
+        s->bi_valid += put;
+        _tr_flush_bits(s);
+        value >>= put;
+        bits -= put;
+    } while (bits);
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+    z_streamp strm;
+    int level;
+    int strategy;
+{
+    deflate_state *s;
+    compress_func func;
+
+    if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
+    s = strm->state;
+
+#ifdef FASTEST
+    if (level != 0) level = 1;
+#else
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
+        return Z_STREAM_ERROR;
+    }
+    func = configuration_table[s->level].func;
+
+    if ((strategy != s->strategy || func != configuration_table[level].func) &&
+        s->high_water) {
+        /* Flush the last buffer: */
+        int err = deflate(strm, Z_BLOCK);
+        if (err == Z_STREAM_ERROR)
+            return err;
+        if (strm->avail_out == 0)
+            return Z_BUF_ERROR;
+    }
+    if (s->level != level) {
+        if (s->level == 0 && s->matches != 0) {
+            if (s->matches == 1)
+                slide_hash(s);
+            else
+                CLEAR_HASH(s);
+            s->matches = 0;
+        }
+        s->level = level;
+        s->max_lazy_match   = configuration_table[level].max_lazy;
+        s->good_match       = configuration_table[level].good_length;
+        s->nice_match       = configuration_table[level].nice_length;
+        s->max_chain_length = configuration_table[level].max_chain;
+    }
+    s->strategy = strategy;
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
+    z_streamp strm;
+    int good_length;
+    int max_lazy;
+    int nice_length;
+    int max_chain;
+{
+    deflate_state *s;
+
+    if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
+    s = strm->state;
+    s->good_match = (uInt)good_length;
+    s->max_lazy_match = (uInt)max_lazy;
+    s->nice_match = nice_length;
+    s->max_chain_length = (uInt)max_chain;
+    return Z_OK;
+}
+
+/* =========================================================================
+ * For the default windowBits of 15 and memLevel of 8, this function returns
+ * a close to exact, as well as small, upper bound on the compressed size.
+ * They are coded as constants here for a reason--if the #define's are
+ * changed, then this function needs to be changed as well.  The return
+ * value for 15 and 8 only works for those exact settings.
+ *
+ * For any setting other than those defaults for windowBits and memLevel,
+ * the value returned is a conservative worst case for the maximum expansion
+ * resulting from using fixed blocks instead of stored blocks, which deflate
+ * can emit on compressed data for some combinations of the parameters.
+ *
+ * This function could be more sophisticated to provide closer upper bounds for
+ * every combination of windowBits and memLevel.  But even the conservative
+ * upper bound of about 14% expansion does not seem onerous for output buffer
+ * allocation.
+ */
+uLong ZEXPORT deflateBound(strm, sourceLen)
+    z_streamp strm;
+    uLong sourceLen;
+{
+    deflate_state *s;
+    uLong complen, wraplen;
+
+    /* conservative upper bound for compressed data */
+    complen = sourceLen +
+              ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
+
+    /* if can't get parameters, return conservative bound plus zlib wrapper */
+    if (deflateStateCheck(strm))
+        return complen + 6;
+
+    /* compute wrapper length */
+    s = strm->state;
+    switch (s->wrap) {
+    case 0:                                 /* raw deflate */
+        wraplen = 0;
+        break;
+    case 1:                                 /* zlib wrapper */
+        wraplen = 6 + (s->strstart ? 4 : 0);
+        break;
+#ifdef GZIP
+    case 2:                                 /* gzip wrapper */
+        wraplen = 18;
+        if (s->gzhead != Z_NULL) {          /* user-supplied gzip header */
+            Bytef *str;
+            if (s->gzhead->extra != Z_NULL)
+                wraplen += 2 + s->gzhead->extra_len;
+            str = s->gzhead->name;
+            if (str != Z_NULL)
+                do {
+                    wraplen++;
+                } while (*str++);
+            str = s->gzhead->comment;
+            if (str != Z_NULL)
+                do {
+                    wraplen++;
+                } while (*str++);
+            if (s->gzhead->hcrc)
+                wraplen += 2;
+        }
+        break;
+#endif
+    default:                                /* for compiler happiness */
+        wraplen = 6;
+    }
+
+    /* if not default parameters, return conservative bound */
+    if (s->w_bits != 15 || s->hash_bits != 8 + 7)
+        return complen + wraplen;
+
+    /* default settings: return tight bound for that case */
+    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+           (sourceLen >> 25) + 13 - 6 + wraplen;
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+    deflate_state *s;
+    uInt b;
+{
+    put_byte(s, (Byte)(b >> 8));
+    put_byte(s, (Byte)(b & 0xff));
+}
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output, except for
+ * some deflate_stored() output, goes through this function so some
+ * applications may wish to modify it to avoid allocating a large
+ * strm->next_out buffer and copying into it. (See also read_buf()).
+ */
+local void flush_pending(strm)
+    z_streamp strm;
+{
+    unsigned len;
+    deflate_state *s = strm->state;
+
+    _tr_flush_bits(s);
+    len = s->pending;
+    if (len > strm->avail_out) len = strm->avail_out;
+    if (len == 0) return;
+
+    zmemcpy(strm->next_out, s->pending_out, len);
+    strm->next_out  += len;
+    s->pending_out  += len;
+    strm->total_out += len;
+    strm->avail_out -= len;
+    s->pending      -= len;
+    if (s->pending == 0) {
+        s->pending_out = s->pending_buf;
+    }
+}
+
+/* ===========================================================================
+ * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1].
+ */
+#define HCRC_UPDATE(beg) \
+    do { \
+        if (s->gzhead->hcrc && s->pending > (beg)) \
+            strm->adler = crc32(strm->adler, s->pending_buf + (beg), \
+                                s->pending - (beg)); \
+    } while (0)
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+    z_streamp strm;
+    int flush;
+{
+    int old_flush; /* value of flush param for previous deflate call */
+    deflate_state *s;
+
+    if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) {
+        return Z_STREAM_ERROR;
+    }
+    s = strm->state;
+
+    if (strm->next_out == Z_NULL ||
+        (strm->avail_in != 0 && strm->next_in == Z_NULL) ||
+        (s->status == FINISH_STATE && flush != Z_FINISH)) {
+        ERR_RETURN(strm, Z_STREAM_ERROR);
+    }
+    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+    old_flush = s->last_flush;
+    s->last_flush = flush;
+
+    /* Flush as much pending output as possible */
+    if (s->pending != 0) {
+        flush_pending(strm);
+        if (strm->avail_out == 0) {
+            /* Since avail_out is 0, deflate will be called again with
+             * more output space, but possibly with both pending and
+             * avail_in equal to zero. There won't be anything to do,
+             * but this is not an error situation so make sure we
+             * return OK instead of BUF_ERROR at next call of deflate:
+             */
+            s->last_flush = -1;
+            return Z_OK;
+        }
+
+    /* Make sure there is something to do and avoid duplicate consecutive
+     * flushes. For repeated and useless calls with Z_FINISH, we keep
+     * returning Z_STREAM_END instead of Z_BUF_ERROR.
+     */
+    } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&
+               flush != Z_FINISH) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* User must not provide more input after the first FINISH: */
+    if (s->status == FINISH_STATE && strm->avail_in != 0) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* Write the header */
+    if (s->status == INIT_STATE) {
+        /* zlib header */
+        uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+        uInt level_flags;
+
+        if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
+            level_flags = 0;
+        else if (s->level < 6)
+            level_flags = 1;
+        else if (s->level == 6)
+            level_flags = 2;
+        else
+            level_flags = 3;
+        header |= (level_flags << 6);
+        if (s->strstart != 0) header |= PRESET_DICT;
+        header += 31 - (header % 31);
+
+        putShortMSB(s, header);
+
+        /* Save the adler32 of the preset dictionary: */
+        if (s->strstart != 0) {
+            putShortMSB(s, (uInt)(strm->adler >> 16));
+            putShortMSB(s, (uInt)(strm->adler & 0xffff));
+        }
+        strm->adler = adler32(0L, Z_NULL, 0);
+        s->status = BUSY_STATE;
+
+        /* Compression must start with an empty pending buffer */
+        flush_pending(strm);
+        if (s->pending != 0) {
+            s->last_flush = -1;
+            return Z_OK;
+        }
+    }
+#ifdef GZIP
+    if (s->status == GZIP_STATE) {
+        /* gzip header */
+        strm->adler = crc32(0L, Z_NULL, 0);
+        put_byte(s, 31);
+        put_byte(s, 139);
+        put_byte(s, 8);
+        if (s->gzhead == Z_NULL) {
+            put_byte(s, 0);
+            put_byte(s, 0);
+            put_byte(s, 0);
+            put_byte(s, 0);
+            put_byte(s, 0);
+            put_byte(s, s->level == 9 ? 2 :
+                     (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+                      4 : 0));
+            put_byte(s, OS_CODE);
+            s->status = BUSY_STATE;
+
+            /* Compression must start with an empty pending buffer */
+            flush_pending(strm);
+            if (s->pending != 0) {
+                s->last_flush = -1;
+                return Z_OK;
+            }
+        }
+        else {
+            put_byte(s, (s->gzhead->text ? 1 : 0) +
+                     (s->gzhead->hcrc ? 2 : 0) +
+                     (s->gzhead->extra == Z_NULL ? 0 : 4) +
+                     (s->gzhead->name == Z_NULL ? 0 : 8) +
+                     (s->gzhead->comment == Z_NULL ? 0 : 16)
+                     );
+            put_byte(s, (Byte)(s->gzhead->time & 0xff));
+            put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
+            put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
+            put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
+            put_byte(s, s->level == 9 ? 2 :
+                     (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+                      4 : 0));
+            put_byte(s, s->gzhead->os & 0xff);
+            if (s->gzhead->extra != Z_NULL) {
+                put_byte(s, s->gzhead->extra_len & 0xff);
+                put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
+            }
+            if (s->gzhead->hcrc)
+                strm->adler = crc32(strm->adler, s->pending_buf,
+                                    s->pending);
+            s->gzindex = 0;
+            s->status = EXTRA_STATE;
+        }
+    }
+    if (s->status == EXTRA_STATE) {
+        if (s->gzhead->extra != Z_NULL) {
+            ulg beg = s->pending;   /* start of bytes to update crc */
+            uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex;
+            while (s->pending + left > s->pending_buf_size) {
+                uInt copy = s->pending_buf_size - s->pending;
+                zmemcpy(s->pending_buf + s->pending,
+                        s->gzhead->extra + s->gzindex, copy);
+                s->pending = s->pending_buf_size;
+                HCRC_UPDATE(beg);
+                s->gzindex += copy;
+                flush_pending(strm);
+                if (s->pending != 0) {
+                    s->last_flush = -1;
+                    return Z_OK;
+                }
+                beg = 0;
+                left -= copy;
+            }
+            zmemcpy(s->pending_buf + s->pending,
+                    s->gzhead->extra + s->gzindex, left);
+            s->pending += left;
+            HCRC_UPDATE(beg);
+            s->gzindex = 0;
+        }
+        s->status = NAME_STATE;
+    }
+    if (s->status == NAME_STATE) {
+        if (s->gzhead->name != Z_NULL) {
+            ulg beg = s->pending;   /* start of bytes to update crc */
+            int val;
+            do {
+                if (s->pending == s->pending_buf_size) {
+                    HCRC_UPDATE(beg);
+                    flush_pending(strm);
+                    if (s->pending != 0) {
+                        s->last_flush = -1;
+                        return Z_OK;
+                    }
+                    beg = 0;
+                }
+                val = s->gzhead->name[s->gzindex++];
+                put_byte(s, val);
+            } while (val != 0);
+            HCRC_UPDATE(beg);
+            s->gzindex = 0;
+        }
+        s->status = COMMENT_STATE;
+    }
+    if (s->status == COMMENT_STATE) {
+        if (s->gzhead->comment != Z_NULL) {
+            ulg beg = s->pending;   /* start of bytes to update crc */
+            int val;
+            do {
+                if (s->pending == s->pending_buf_size) {
+                    HCRC_UPDATE(beg);
+                    flush_pending(strm);
+                    if (s->pending != 0) {
+                        s->last_flush = -1;
+                        return Z_OK;
+                    }
+                    beg = 0;
+                }
+                val = s->gzhead->comment[s->gzindex++];
+                put_byte(s, val);
+            } while (val != 0);
+            HCRC_UPDATE(beg);
+        }
+        s->status = HCRC_STATE;
+    }
+    if (s->status == HCRC_STATE) {
+        if (s->gzhead->hcrc) {
+            if (s->pending + 2 > s->pending_buf_size) {
+                flush_pending(strm);
+                if (s->pending != 0) {
+                    s->last_flush = -1;
+                    return Z_OK;
+                }
+            }
+            put_byte(s, (Byte)(strm->adler & 0xff));
+            put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+            strm->adler = crc32(0L, Z_NULL, 0);
+        }
+        s->status = BUSY_STATE;
+
+        /* Compression must start with an empty pending buffer */
+        flush_pending(strm);
+        if (s->pending != 0) {
+            s->last_flush = -1;
+            return Z_OK;
+        }
+    }
+#endif
+
+    /* Start a new block or continue the current one.
+     */
+    if (strm->avail_in != 0 || s->lookahead != 0 ||
+        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+        block_state bstate;
+
+        bstate = s->level == 0 ? deflate_stored(s, flush) :
+                 s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
+                 s->strategy == Z_RLE ? deflate_rle(s, flush) :
+                 (*(configuration_table[s->level].func))(s, flush);
+
+        if (bstate == finish_started || bstate == finish_done) {
+            s->status = FINISH_STATE;
+        }
+        if (bstate == need_more || bstate == finish_started) {
+            if (strm->avail_out == 0) {
+                s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+            }
+            return Z_OK;
+            /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+             * of deflate should use the same flush parameter to make sure
+             * that the flush is complete. So we don't have to output an
+             * empty block here, this will be done at next call. This also
+             * ensures that for a very small output buffer, we emit at most
+             * one empty block.
+             */
+        }
+        if (bstate == block_done) {
+            if (flush == Z_PARTIAL_FLUSH) {
+                _tr_align(s);
+            } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
+                _tr_stored_block(s, (char*)0, 0L, 0);
+                /* For a full flush, this empty block will be recognized
+                 * as a special marker by inflate_sync().
+                 */
+                if (flush == Z_FULL_FLUSH) {
+                    CLEAR_HASH(s);             /* forget history */
+                    if (s->lookahead == 0) {
+                        s->strstart = 0;
+                        s->block_start = 0L;
+                        s->insert = 0;
+                    }
+                }
+            }
+            flush_pending(strm);
+            if (strm->avail_out == 0) {
+              s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+              return Z_OK;
+            }
+        }
+    }
+
+    if (flush != Z_FINISH) return Z_OK;
+    if (s->wrap <= 0) return Z_STREAM_END;
+
+    /* Write the trailer */
+#ifdef GZIP
+    if (s->wrap == 2) {
+        put_byte(s, (Byte)(strm->adler & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
+        put_byte(s, (Byte)(strm->total_in & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
+    }
+    else
+#endif
+    {
+        putShortMSB(s, (uInt)(strm->adler >> 16));
+        putShortMSB(s, (uInt)(strm->adler & 0xffff));
+    }
+    flush_pending(strm);
+    /* If avail_out is zero, the application will call deflate again
+     * to flush the rest.
+     */
+    if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
+    return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+    z_streamp strm;
+{
+    int status;
+
+    if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
+
+    status = strm->state->status;
+
+    /* Deallocate in reverse order of allocations: */
+    TRY_FREE(strm, strm->state->pending_buf);
+    TRY_FREE(strm, strm->state->head);
+    TRY_FREE(strm, strm->state->prev);
+    TRY_FREE(strm, strm->state->window);
+
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+
+    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (dest, source)
+    z_streamp dest;
+    z_streamp source;
+{
+#ifdef MAXSEG_64K
+    return Z_STREAM_ERROR;
+#else
+    deflate_state *ds;
+    deflate_state *ss;
+    ushf *overlay;
+
+
+    if (deflateStateCheck(source) || dest == Z_NULL) {
+        return Z_STREAM_ERROR;
+    }
+
+    ss = source->state;
+
+    zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
+
+    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+    if (ds == Z_NULL) return Z_MEM_ERROR;
+    dest->state = (struct internal_state FAR *) ds;
+    zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
+    ds->strm = dest;
+
+    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
+    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
+    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+    ds->pending_buf = (uchf *) overlay;
+
+    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+        ds->pending_buf == Z_NULL) {
+        deflateEnd (dest);
+        return Z_MEM_ERROR;
+    }
+    /* following zmemcpy do not work for 16-bit MSDOS */
+    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+    zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
+    zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
+    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+    ds->l_desc.dyn_tree = ds->dyn_ltree;
+    ds->d_desc.dyn_tree = ds->dyn_dtree;
+    ds->bl_desc.dyn_tree = ds->bl_tree;
+
+    return Z_OK;
+#endif /* MAXSEG_64K */
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read.  All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local unsigned read_buf(strm, buf, size)
+    z_streamp strm;
+    Bytef *buf;
+    unsigned size;
+{
+    unsigned len = strm->avail_in;
+
+    if (len > size) len = size;
+    if (len == 0) return 0;
+
+    strm->avail_in  -= len;
+
+    zmemcpy(buf, strm->next_in, len);
+    if (strm->state->wrap == 1) {
+        strm->adler = adler32(strm->adler, buf, len);
+    }
+#ifdef GZIP
+    else if (strm->state->wrap == 2) {
+        strm->adler = crc32(strm->adler, buf, len);
+    }
+#endif
+    strm->next_in  += len;
+    strm->total_in += len;
+
+    return len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+    deflate_state *s;
+{
+    s->window_size = (ulg)2L*s->w_size;
+
+    CLEAR_HASH(s);
+
+    /* Set the default configuration parameters:
+     */
+    s->max_lazy_match   = configuration_table[s->level].max_lazy;
+    s->good_match       = configuration_table[s->level].good_length;
+    s->nice_match       = configuration_table[s->level].nice_length;
+    s->max_chain_length = configuration_table[s->level].max_chain;
+
+    s->strstart = 0;
+    s->block_start = 0L;
+    s->lookahead = 0;
+    s->insert = 0;
+    s->match_length = s->prev_length = MIN_MATCH-1;
+    s->match_available = 0;
+    s->ins_h = 0;
+#ifndef FASTEST
+#ifdef ASMV
+    match_init(); /* initialize the asm code */
+#endif
+#endif
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    unsigned chain_length = s->max_chain_length;/* max hash chain length */
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                      /* matched string */
+    register int len;                           /* length of current match */
+    int best_len = (int)s->prev_length;         /* best match length so far */
+    int nice_match = s->nice_match;             /* stop if match long enough */
+    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+        s->strstart - (IPos)MAX_DIST(s) : NIL;
+    /* Stop when cur_match becomes <= limit. To simplify the code,
+     * we prevent matches with the string of window index 0.
+     */
+    Posf *prev = s->prev;
+    uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+    /* Compare two bytes at a time. Note: this is not always beneficial.
+     * Try with and without -DUNALIGNED_OK to check.
+     */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+    register ush scan_start = *(ushf*)scan;
+    register ush scan_end   = *(ushf*)(scan+best_len-1);
+#else
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+    register Byte scan_end1  = scan[best_len-1];
+    register Byte scan_end   = scan[best_len];
+#endif
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    /* Do not waste too much time if we already have a good match: */
+    if (s->prev_length >= s->good_match) {
+        chain_length >>= 2;
+    }
+    /* Do not look for matches beyond the end of the input. This is necessary
+     * to make deflate deterministic.
+     */
+    if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead;
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    do {
+        Assert(cur_match < s->strstart, "no future");
+        match = s->window + cur_match;
+
+        /* Skip to next match if the match length cannot increase
+         * or if the match length is less than 2.  Note that the checks below
+         * for insufficient lookahead only occur occasionally for performance
+         * reasons.  Therefore uninitialized memory will be accessed, and
+         * conditional jumps will be made that depend on those values.
+         * However the length of the match is limited to the lookahead, so
+         * the output of deflate is not affected by the uninitialized values.
+         */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+        /* This code assumes sizeof(unsigned short) == 2. Do not use
+         * UNALIGNED_OK if your compiler uses a different size.
+         */
+        if (*(ushf*)(match+best_len-1) != scan_end ||
+            *(ushf*)match != scan_start) continue;
+
+        /* It is not necessary to compare scan[2] and match[2] since they are
+         * always equal when the other bytes match, given that the hash keys
+         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+         * strstart+3, +5, ... up to strstart+257. We check for insufficient
+         * lookahead only every 4th comparison; the 128th check will be made
+         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+         * necessary to put more guard bytes at the end of the window, or
+         * to check more often for insufficient lookahead.
+         */
+        Assert(scan[2] == match[2], "scan[2]?");
+        scan++, match++;
+        do {
+        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 scan < strend);
+        /* The funny "do {}" generates better code on most compilers */
+
+        /* Here, scan <= window+strstart+257 */
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+        if (*scan == *match) scan++;
+
+        len = (MAX_MATCH - 1) - (int)(strend-scan);
+        scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+        if (match[best_len]   != scan_end  ||
+            match[best_len-1] != scan_end1 ||
+            *match            != *scan     ||
+            *++match          != scan[1])      continue;
+
+        /* The check at best_len-1 can be removed because it will be made
+         * again later. (This heuristic is not always a win.)
+         * It is not necessary to compare scan[2] and match[2] since they
+         * are always equal when the other bytes match, given that
+         * the hash keys are equal and that HASH_BITS >= 8.
+         */
+        scan += 2, match++;
+        Assert(*scan == *match, "match[2]?");
+
+        /* We check for insufficient lookahead only every 8th comparison;
+         * the 256th check will be made at strstart+258.
+         */
+        do {
+        } while (*++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 scan < strend);
+
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+        len = MAX_MATCH - (int)(strend - scan);
+        scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+        if (len > best_len) {
+            s->match_start = cur_match;
+            best_len = len;
+            if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+            scan_end = *(ushf*)(scan+best_len-1);
+#else
+            scan_end1  = scan[best_len-1];
+            scan_end   = scan[best_len];
+#endif
+        }
+    } while ((cur_match = prev[cur_match & wmask]) > limit
+             && --chain_length != 0);
+
+    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+    return s->lookahead;
+}
+#endif /* ASMV */
+
+#else /* FASTEST */
+
+/* ---------------------------------------------------------------------------
+ * Optimized version for FASTEST only
+ */
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    Assert(cur_match < s->strstart, "no future");
+
+    match = s->window + cur_match;
+
+    /* Return failure if the match length is less than 2:
+     */
+    if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+    /* The check at best_len-1 can be removed because it will be made
+     * again later. (This heuristic is not always a win.)
+     * It is not necessary to compare scan[2] and match[2] since they
+     * are always equal when the other bytes match, given that
+     * the hash keys are equal and that HASH_BITS >= 8.
+     */
+    scan += 2, match += 2;
+    Assert(*scan == *match, "match[2]?");
+
+    /* We check for insufficient lookahead only every 8th comparison;
+     * the 256th check will be made at strstart+258.
+     */
+    do {
+    } while (*++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             scan < strend);
+
+    Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+    len = MAX_MATCH - (int)(strend - scan);
+
+    if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+    s->match_start = cur_match;
+    return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
+}
+
+#endif /* FASTEST */
+
+#ifdef ZLIB_DEBUG
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+    deflate_state *s;
+    IPos start, match;
+    int length;
+{
+    /* check that the match is indeed a match */
+    if (zmemcmp(s->window + match,
+                s->window + start, length) != EQUAL) {
+        fprintf(stderr, " start %u, match %u, length %d\n",
+                start, match, length);
+        do {
+            fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+        } while (--length != 0);
+        z_error("invalid match");
+    }
+    if (z_verbose > 1) {
+        fprintf(stderr,"\\[%d,%d]", start-match, length);
+        do { putc(s->window[start++], stderr); } while (--length != 0);
+    }
+}
+#else
+#  define check_match(s, start, match, length)
+#endif /* ZLIB_DEBUG */
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ *    At least one byte has been read, or avail_in == 0; reads are
+ *    performed for at least two bytes (required for the zip translate_eol
+ *    option -- not supported here).
+ */
+local void fill_window(s)
+    deflate_state *s;
+{
+    unsigned n;
+    unsigned more;    /* Amount of free space at the end of the window. */
+    uInt wsize = s->w_size;
+
+    Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
+
+    do {
+        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+        /* Deal with !@#$% 64K limit: */
+        if (sizeof(int) <= 2) {
+            if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+                more = wsize;
+
+            } else if (more == (unsigned)(-1)) {
+                /* Very unlikely, but possible on 16 bit machine if
+                 * strstart == 0 && lookahead == 1 (input done a byte at time)
+                 */
+                more--;
+            }
+        }
+
+        /* If the window is almost full and there is insufficient lookahead,
+         * move the upper half to the lower one to make room in the upper half.
+         */
+        if (s->strstart >= wsize+MAX_DIST(s)) {
+
+            zmemcpy(s->window, s->window+wsize, (unsigned)wsize - more);
+            s->match_start -= wsize;
+            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
+            s->block_start -= (long) wsize;
+            slide_hash(s);
+            more += wsize;
+        }
+        if (s->strm->avail_in == 0) break;
+
+        /* If there was no sliding:
+         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+         *    more == window_size - lookahead - strstart
+         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+         * => more >= window_size - 2*WSIZE + 2
+         * In the BIG_MEM or MMAP case (not yet supported),
+         *   window_size == input_size + MIN_LOOKAHEAD  &&
+         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+         * Otherwise, window_size == 2*WSIZE so more >= 2.
+         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+         */
+        Assert(more >= 2, "more < 2");
+
+        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+        s->lookahead += n;
+
+        /* Initialize the hash value now that we have some input: */
+        if (s->lookahead + s->insert >= MIN_MATCH) {
+            uInt str = s->strstart - s->insert;
+            s->ins_h = s->window[str];
+            UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
+#if MIN_MATCH != 3
+            Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+            while (s->insert) {
+                UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
+#ifndef FASTEST
+                s->prev[str & s->w_mask] = s->head[s->ins_h];
+#endif
+                s->head[s->ins_h] = (Pos)str;
+                str++;
+                s->insert--;
+                if (s->lookahead + s->insert < MIN_MATCH)
+                    break;
+            }
+        }
+        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+         * but this is not important since only literal bytes will be emitted.
+         */
+
+    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+
+    /* If the WIN_INIT bytes after the end of the current data have never been
+     * written, then zero those bytes in order to avoid memory check reports of
+     * the use of uninitialized (or uninitialised as Julian writes) bytes by
+     * the longest match routines.  Update the high water mark for the next
+     * time through here.  WIN_INIT is set to MAX_MATCH since the longest match
+     * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
+     */
+    if (s->high_water < s->window_size) {
+        ulg curr = s->strstart + (ulg)(s->lookahead);
+        ulg init;
+
+        if (s->high_water < curr) {
+            /* Previous high water mark below current data -- zero WIN_INIT
+             * bytes or up to end of window, whichever is less.
+             */
+            init = s->window_size - curr;
+            if (init > WIN_INIT)
+                init = WIN_INIT;
+            zmemzero(s->window + curr, (unsigned)init);
+            s->high_water = curr + init;
+        }
+        else if (s->high_water < (ulg)curr + WIN_INIT) {
+            /* High water mark at or above current data, but below current data
+             * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
+             * to end of window, whichever is less.
+             */
+            init = (ulg)curr + WIN_INIT - s->high_water;
+            if (init > s->window_size - s->high_water)
+                init = s->window_size - s->high_water;
+            zmemzero(s->window + s->high_water, (unsigned)init);
+            s->high_water += init;
+        }
+    }
+
+    Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
+           "not enough room for search");
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, last) { \
+   _tr_flush_block(s, (s->block_start >= 0L ? \
+                   (charf *)&s->window[(unsigned)s->block_start] : \
+                   (charf *)Z_NULL), \
+                (ulg)((long)s->strstart - s->block_start), \
+                (last)); \
+   s->block_start = s->strstart; \
+   flush_pending(s->strm); \
+   Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, last) { \
+   FLUSH_BLOCK_ONLY(s, last); \
+   if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \
+}
+
+/* Maximum stored block length in deflate format (not including header). */
+#define MAX_STORED 65535
+
+/* Minimum of a and b. */
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ *
+ * In case deflateParams() is used to later switch to a non-zero compression
+ * level, s->matches (otherwise unused when storing) keeps track of the number
+ * of hash table slides to perform. If s->matches is 1, then one hash table
+ * slide will be done when switching. If s->matches is 2, the maximum value
+ * allowed here, then the hash table will be cleared, since two or more slides
+ * is the same as a clear.
+ *
+ * deflate_stored() is written to minimize the number of times an input byte is
+ * copied. It is most efficient with large input and output buffers, which
+ * maximizes the opportunites to have a single copy from next_in to next_out.
+ */
+local block_state deflate_stored(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    /* Smallest worthy block size when not flushing or finishing. By default
+     * this is 32K. This can be as small as 507 bytes for memLevel == 1. For
+     * large input and output buffers, the stored block size will be larger.
+     */
+    unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size);
+
+    /* Copy as many min_block or larger stored blocks directly to next_out as
+     * possible. If flushing, copy the remaining available input to next_out as
+     * stored blocks, if there is enough space.
+     */
+    unsigned len, left, have, last = 0;
+    unsigned used = s->strm->avail_in;
+    do {
+        /* Set len to the maximum size block that we can copy directly with the
+         * available input data and output space. Set left to how much of that
+         * would be copied from what's left in the window.
+         */
+        len = MAX_STORED;       /* maximum deflate stored block length */
+        have = (s->bi_valid + 42) >> 3;         /* number of header bytes */
+        if (s->strm->avail_out < have)          /* need room for header */
+            break;
+            /* maximum stored block length that will fit in avail_out: */
+        have = s->strm->avail_out - have;
+        left = s->strstart - s->block_start;    /* bytes left in window */
+        if (len > (ulg)left + s->strm->avail_in)
+            len = left + s->strm->avail_in;     /* limit len to the input */
+        if (len > have)
+            len = have;                         /* limit len to the output */
+
+        /* If the stored block would be less than min_block in length, or if
+         * unable to copy all of the available input when flushing, then try
+         * copying to the window and the pending buffer instead. Also don't
+         * write an empty block when flushing -- deflate() does that.
+         */
+        if (len < min_block && ((len == 0 && flush != Z_FINISH) ||
+                                flush == Z_NO_FLUSH ||
+                                len != left + s->strm->avail_in))
+            break;
+
+        /* Make a dummy stored block in pending to get the header bytes,
+         * including any pending bits. This also updates the debugging counts.
+         */
+        last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0;
+        _tr_stored_block(s, (char *)0, 0L, last);
+
+        /* Replace the lengths in the dummy stored block with len. */
+        s->pending_buf[s->pending - 4] = len;
+        s->pending_buf[s->pending - 3] = len >> 8;
+        s->pending_buf[s->pending - 2] = ~len;
+        s->pending_buf[s->pending - 1] = ~len >> 8;
+
+        /* Write the stored block header bytes. */
+        flush_pending(s->strm);
+
+#ifdef ZLIB_DEBUG
+        /* Update debugging counts for the data about to be copied. */
+        s->compressed_len += len << 3;
+        s->bits_sent += len << 3;
+#endif
+
+        /* Copy uncompressed bytes from the window to next_out. */
+        if (left) {
+            if (left > len)
+                left = len;
+            zmemcpy(s->strm->next_out, s->window + s->block_start, left);
+            s->strm->next_out += left;
+            s->strm->avail_out -= left;
+            s->strm->total_out += left;
+            s->block_start += left;
+            len -= left;
+        }
+
+        /* Copy uncompressed bytes directly from next_in to next_out, updating
+         * the check value.
+         */
+        if (len) {
+            read_buf(s->strm, s->strm->next_out, len);
+            s->strm->next_out += len;
+            s->strm->avail_out -= len;
+            s->strm->total_out += len;
+        }
+    } while (last == 0);
+
+    /* Update the sliding window with the last s->w_size bytes of the copied
+     * data, or append all of the copied data to the existing window if less
+     * than s->w_size bytes were copied. Also update the number of bytes to
+     * insert in the hash tables, in the event that deflateParams() switches to
+     * a non-zero compression level.
+     */
+    used -= s->strm->avail_in;      /* number of input bytes directly copied */
+    if (used) {
+        /* If any input was used, then no unused input remains in the window,
+         * therefore s->block_start == s->strstart.
+         */
+        if (used >= s->w_size) {    /* supplant the previous history */
+            s->matches = 2;         /* clear hash */
+            zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size);
+            s->strstart = s->w_size;
+        }
+        else {
+            if (s->window_size - s->strstart <= used) {
+                /* Slide the window down. */
+                s->strstart -= s->w_size;
+                zmemcpy(s->window, s->window + s->w_size, s->strstart);
+                if (s->matches < 2)
+                    s->matches++;   /* add a pending slide_hash() */
+            }
+            zmemcpy(s->window + s->strstart, s->strm->next_in - used, used);
+            s->strstart += used;
+        }
+        s->block_start = s->strstart;
+        s->insert += MIN(used, s->w_size - s->insert);
+    }
+    if (s->high_water < s->strstart)
+        s->high_water = s->strstart;
+
+    /* If the last block was written to next_out, then done. */
+    if (last)
+        return finish_done;
+
+    /* If flushing and all input has been consumed, then done. */
+    if (flush != Z_NO_FLUSH && flush != Z_FINISH &&
+        s->strm->avail_in == 0 && (long)s->strstart == s->block_start)
+        return block_done;
+
+    /* Fill the window with any remaining input. */
+    have = s->window_size - s->strstart - 1;
+    if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) {
+        /* Slide the window down. */
+        s->block_start -= s->w_size;
+        s->strstart -= s->w_size;
+        zmemcpy(s->window, s->window + s->w_size, s->strstart);
+        if (s->matches < 2)
+            s->matches++;           /* add a pending slide_hash() */
+        have += s->w_size;          /* more space now */
+    }
+    if (have > s->strm->avail_in)
+        have = s->strm->avail_in;
+    if (have) {
+        read_buf(s->strm, s->window + s->strstart, have);
+        s->strstart += have;
+    }
+    if (s->high_water < s->strstart)
+        s->high_water = s->strstart;
+
+    /* There was not enough avail_out to write a complete worthy or flushed
+     * stored block to next_out. Write a stored block to pending instead, if we
+     * have enough input for a worthy block, or if flushing and there is enough
+     * room for the remaining input as a stored block in the pending buffer.
+     */
+    have = (s->bi_valid + 42) >> 3;         /* number of header bytes */
+        /* maximum stored block length that will fit in pending: */
+    have = MIN(s->pending_buf_size - have, MAX_STORED);
+    min_block = MIN(have, s->w_size);
+    left = s->strstart - s->block_start;
+    if (left >= min_block ||
+        ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH &&
+         s->strm->avail_in == 0 && left <= have)) {
+        len = MIN(left, have);
+        last = flush == Z_FINISH && s->strm->avail_in == 0 &&
+               len == left ? 1 : 0;
+        _tr_stored_block(s, (charf *)s->window + s->block_start, len, last);
+        s->block_start += len;
+        flush_pending(s->strm);
+    }
+
+    /* We've done all we can with the available input and output. */
+    return last ? finish_started : need_more;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head;       /* head of the hash chain */
+    int bflush;           /* set if current block must be flushed */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        hash_head = NIL;
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         * At this point we have always match_length < MIN_MATCH
+         */
+        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            s->match_length = longest_match (s, hash_head);
+            /* longest_match() sets match_start */
+        }
+        if (s->match_length >= MIN_MATCH) {
+            check_match(s, s->strstart, s->match_start, s->match_length);
+
+            _tr_tally_dist(s, s->strstart - s->match_start,
+                           s->match_length - MIN_MATCH, bflush);
+
+            s->lookahead -= s->match_length;
+
+            /* Insert new strings in the hash table only if the match length
+             * is not too large. This saves time but degrades compression.
+             */
+#ifndef FASTEST
+            if (s->match_length <= s->max_insert_length &&
+                s->lookahead >= MIN_MATCH) {
+                s->match_length--; /* string at strstart already in table */
+                do {
+                    s->strstart++;
+                    INSERT_STRING(s, s->strstart, hash_head);
+                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+                     * always MIN_MATCH bytes ahead.
+                     */
+                } while (--s->match_length != 0);
+                s->strstart++;
+            } else
+#endif
+            {
+                s->strstart += s->match_length;
+                s->match_length = 0;
+                s->ins_h = s->window[s->strstart];
+                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+                Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+                 * matter since it will be recomputed at next deflate call.
+                 */
+            }
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            _tr_tally_lit (s, s->window[s->strstart], bflush);
+            s->lookahead--;
+            s->strstart++;
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
+    if (flush == Z_FINISH) {
+        FLUSH_BLOCK(s, 1);
+        return finish_done;
+    }
+    if (s->last_lit)
+        FLUSH_BLOCK(s, 0);
+    return block_done;
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head;          /* head of hash chain */
+    int bflush;              /* set if current block must be flushed */
+
+    /* Process the input block. */
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        hash_head = NIL;
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         */
+        s->prev_length = s->match_length, s->prev_match = s->match_start;
+        s->match_length = MIN_MATCH-1;
+
+        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+            s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            s->match_length = longest_match (s, hash_head);
+            /* longest_match() sets match_start */
+
+            if (s->match_length <= 5 && (s->strategy == Z_FILTERED
+#if TOO_FAR <= 32767
+                || (s->match_length == MIN_MATCH &&
+                    s->strstart - s->match_start > TOO_FAR)
+#endif
+                )) {
+
+                /* If prev_match is also MIN_MATCH, match_start is garbage
+                 * but we will ignore the current match anyway.
+                 */
+                s->match_length = MIN_MATCH-1;
+            }
+        }
+        /* If there was a match at the previous step and the current
+         * match is not better, output the previous match:
+         */
+        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+            /* Do not insert strings in hash table beyond this. */
+
+            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+            _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+                           s->prev_length - MIN_MATCH, bflush);
+
+            /* Insert in hash table all strings up to the end of the match.
+             * strstart-1 and strstart are already inserted. If there is not
+             * enough lookahead, the last two strings are not inserted in
+             * the hash table.
+             */
+            s->lookahead -= s->prev_length-1;
+            s->prev_length -= 2;
+            do {
+                if (++s->strstart <= max_insert) {
+                    INSERT_STRING(s, s->strstart, hash_head);
+                }
+            } while (--s->prev_length != 0);
+            s->match_available = 0;
+            s->match_length = MIN_MATCH-1;
+            s->strstart++;
+
+            if (bflush) FLUSH_BLOCK(s, 0);
+
+        } else if (s->match_available) {
+            /* If there was no match at the previous position, output a
+             * single literal. If there was a match but the current match
+             * is longer, truncate the previous match to a single literal.
+             */
+            Tracevv((stderr,"%c", s->window[s->strstart-1]));
+            _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+            if (bflush) {
+                FLUSH_BLOCK_ONLY(s, 0);
+            }
+            s->strstart++;
+            s->lookahead--;
+            if (s->strm->avail_out == 0) return need_more;
+        } else {
+            /* There is no previous match to compare with, wait for
+             * the next step to decide.
+             */
+            s->match_available = 1;
+            s->strstart++;
+            s->lookahead--;
+        }
+    }
+    Assert (flush != Z_NO_FLUSH, "no flush?");
+    if (s->match_available) {
+        Tracevv((stderr,"%c", s->window[s->strstart-1]));
+        _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+        s->match_available = 0;
+    }
+    s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
+    if (flush == Z_FINISH) {
+        FLUSH_BLOCK(s, 1);
+        return finish_done;
+    }
+    if (s->last_lit)
+        FLUSH_BLOCK(s, 0);
+    return block_done;
+}
+#endif /* FASTEST */
+
+/* ===========================================================================
+ * For Z_RLE, simply look for runs of bytes, generate matches only of distance
+ * one.  Do not maintain a hash table.  (It will be regenerated if this run of
+ * deflate switches away from Z_RLE.)
+ */
+local block_state deflate_rle(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    int bflush;             /* set if current block must be flushed */
+    uInt prev;              /* byte at distance one to match */
+    Bytef *scan, *strend;   /* scan goes up to strend for length of run */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the longest run, plus one for the unrolled loop.
+         */
+        if (s->lookahead <= MAX_MATCH) {
+            fill_window(s);
+            if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* See how many times the previous byte repeats */
+        s->match_length = 0;
+        if (s->lookahead >= MIN_MATCH && s->strstart > 0) {
+            scan = s->window + s->strstart - 1;
+            prev = *scan;
+            if (prev == *++scan && prev == *++scan && prev == *++scan) {
+                strend = s->window + s->strstart + MAX_MATCH;
+                do {
+                } while (prev == *++scan && prev == *++scan &&
+                         prev == *++scan && prev == *++scan &&
+                         prev == *++scan && prev == *++scan &&
+                         prev == *++scan && prev == *++scan &&
+                         scan < strend);
+                s->match_length = MAX_MATCH - (uInt)(strend - scan);
+                if (s->match_length > s->lookahead)
+                    s->match_length = s->lookahead;
+            }
+            Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
+        }
+
+        /* Emit match if have run of MIN_MATCH or longer, else emit literal */
+        if (s->match_length >= MIN_MATCH) {
+            check_match(s, s->strstart, s->strstart - 1, s->match_length);
+
+            _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);
+
+            s->lookahead -= s->match_length;
+            s->strstart += s->match_length;
+            s->match_length = 0;
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            _tr_tally_lit (s, s->window[s->strstart], bflush);
+            s->lookahead--;
+            s->strstart++;
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    s->insert = 0;
+    if (flush == Z_FINISH) {
+        FLUSH_BLOCK(s, 1);
+        return finish_done;
+    }
+    if (s->last_lit)
+        FLUSH_BLOCK(s, 0);
+    return block_done;
+}
+
+/* ===========================================================================
+ * For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.
+ * (It will be regenerated if this run of deflate switches away from Huffman.)
+ */
+local block_state deflate_huff(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    int bflush;             /* set if current block must be flushed */
+
+    for (;;) {
+        /* Make sure that we have a literal to write. */
+        if (s->lookahead == 0) {
+            fill_window(s);
+            if (s->lookahead == 0) {
+                if (flush == Z_NO_FLUSH)
+                    return need_more;
+                break;      /* flush the current block */
+            }
+        }
+
+        /* Output a literal byte */
+        s->match_length = 0;
+        Tracevv((stderr,"%c", s->window[s->strstart]));
+        _tr_tally_lit (s, s->window[s->strstart], bflush);
+        s->lookahead--;
+        s->strstart++;
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    s->insert = 0;
+    if (flush == Z_FINISH) {
+        FLUSH_BLOCK(s, 1);
+        return finish_done;
+    }
+    if (s->last_lit)
+        FLUSH_BLOCK(s, 0);
+    return block_done;
+}
Index: EcnlProtoTool/trunk/zlib-1.2.11/deflate.h
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/deflate.h	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/deflate.h	(revision 331)
@@ -0,0 +1,349 @@
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-2016 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef DEFLATE_H
+#define DEFLATE_H
+
+#include "zutil.h"
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+   trailer creation by deflate().  NO_GZIP would be used to avoid linking in
+   the crc code when it is not needed.  For shared libraries, gzip encoding
+   should be left enabled. */
+#ifndef NO_GZIP
+#  define GZIP
+#endif
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS  256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES   30
+/* number of distance codes */
+
+#define BL_CODES  19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define Buf_size 16
+/* size of bit buffer in bi_buf */
+
+#define INIT_STATE    42    /* zlib header -> BUSY_STATE */
+#ifdef GZIP
+#  define GZIP_STATE  57    /* gzip header -> BUSY_STATE | EXTRA_STATE */
+#endif
+#define EXTRA_STATE   69    /* gzip extra block -> NAME_STATE */
+#define NAME_STATE    73    /* gzip file name -> COMMENT_STATE */
+#define COMMENT_STATE 91    /* gzip comment -> HCRC_STATE */
+#define HCRC_STATE   103    /* gzip header CRC -> BUSY_STATE */
+#define BUSY_STATE   113    /* deflate -> FINISH_STATE */
+#define FINISH_STATE 666    /* stream complete */
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+    union {
+        ush  freq;       /* frequency count */
+        ush  code;       /* bit string */
+    } fc;
+    union {
+        ush  dad;        /* father node in Huffman tree */
+        ush  len;        /* length of bit string */
+    } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad  dl.dad
+#define Len  dl.len
+
+typedef struct static_tree_desc_s  static_tree_desc;
+
+typedef struct tree_desc_s {
+    ct_data *dyn_tree;           /* the dynamic tree */
+    int     max_code;            /* largest code with non zero frequency */
+    const static_tree_desc *stat_desc;  /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+    z_streamp strm;      /* pointer back to this zlib stream */
+    int   status;        /* as the name implies */
+    Bytef *pending_buf;  /* output still pending */
+    ulg   pending_buf_size; /* size of pending_buf */
+    Bytef *pending_out;  /* next pending byte to output to the stream */
+    ulg   pending;       /* nb of bytes in the pending buffer */
+    int   wrap;          /* bit 0 true for zlib, bit 1 true for gzip */
+    gz_headerp  gzhead;  /* gzip header information to write */
+    ulg   gzindex;       /* where in extra, name, or comment */
+    Byte  method;        /* can only be DEFLATED */
+    int   last_flush;    /* value of flush param for previous deflate call */
+
+                /* used by deflate.c: */
+
+    uInt  w_size;        /* LZ77 window size (32K by default) */
+    uInt  w_bits;        /* log2(w_size)  (8..16) */
+    uInt  w_mask;        /* w_size - 1 */
+
+    Bytef *window;
+    /* Sliding window. Input bytes are read into the second half of the window,
+     * and move to the first half later to keep a dictionary of at least wSize
+     * bytes. With this organization, matches are limited to a distance of
+     * wSize-MAX_MATCH bytes, but this ensures that IO is always
+     * performed with a length multiple of the block size. Also, it limits
+     * the window size to 64K, which is quite useful on MSDOS.
+     * To do: use the user input buffer as sliding window.
+     */
+
+    ulg window_size;
+    /* Actual size of window: 2*wSize, except when the user input buffer
+     * is directly used as sliding window.
+     */
+
+    Posf *prev;
+    /* Link to older string with same hash index. To limit the size of this
+     * array to 64K, this link is maintained only for the last 32K strings.
+     * An index in this array is thus a window index modulo 32K.
+     */
+
+    Posf *head; /* Heads of the hash chains or NIL. */
+
+    uInt  ins_h;          /* hash index of string to be inserted */
+    uInt  hash_size;      /* number of elements in hash table */
+    uInt  hash_bits;      /* log2(hash_size) */
+    uInt  hash_mask;      /* hash_size-1 */
+
+    uInt  hash_shift;
+    /* Number of bits by which ins_h must be shifted at each input
+     * step. It must be such that after MIN_MATCH steps, the oldest
+     * byte no longer takes part in the hash key, that is:
+     *   hash_shift * MIN_MATCH >= hash_bits
+     */
+
+    long block_start;
+    /* Window position at the beginning of the current output block. Gets
+     * negative when the window is moved backwards.
+     */
+
+    uInt match_length;           /* length of best match */
+    IPos prev_match;             /* previous match */
+    int match_available;         /* set if previous match exists */
+    uInt strstart;               /* start of string to insert */
+    uInt match_start;            /* start of matching string */
+    uInt lookahead;              /* number of valid bytes ahead in window */
+
+    uInt prev_length;
+    /* Length of the best match at previous step. Matches not greater than this
+     * are discarded. This is used in the lazy match evaluation.
+     */
+
+    uInt max_chain_length;
+    /* To speed up deflation, hash chains are never searched beyond this
+     * length.  A higher limit improves compression ratio but degrades the
+     * speed.
+     */
+
+    uInt max_lazy_match;
+    /* Attempt to find a better match only when the current match is strictly
+     * smaller than this value. This mechanism is used only for compression
+     * levels >= 4.
+     */
+#   define max_insert_length  max_lazy_match
+    /* Insert new strings in the hash table only if the match length is not
+     * greater than this length. This saves time but degrades compression.
+     * max_insert_length is used only for compression levels <= 3.
+     */
+
+    int level;    /* compression level (1..9) */
+    int strategy; /* favor or force Huffman coding*/
+
+    uInt good_match;
+    /* Use a faster search when the previous match is longer than this */
+
+    int nice_match; /* Stop searching when current match exceeds this */
+
+                /* used by trees.c: */
+    /* Didn't use ct_data typedef below to suppress compiler warning */
+    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
+    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
+
+    struct tree_desc_s l_desc;               /* desc. for literal tree */
+    struct tree_desc_s d_desc;               /* desc. for distance tree */
+    struct tree_desc_s bl_desc;              /* desc. for bit length tree */
+
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
+    int heap_len;               /* number of elements in the heap */
+    int heap_max;               /* element of largest frequency */
+    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+     * The same heap array is used to build all trees.
+     */
+
+    uch depth[2*L_CODES+1];
+    /* Depth of each subtree used as tie breaker for trees of equal frequency
+     */
+
+    uchf *l_buf;          /* buffer for literals or lengths */
+
+    uInt  lit_bufsize;
+    /* Size of match buffer for literals/lengths.  There are 4 reasons for
+     * limiting lit_bufsize to 64K:
+     *   - frequencies can be kept in 16 bit counters
+     *   - if compression is not successful for the first block, all input
+     *     data is still in the window so we can still emit a stored block even
+     *     when input comes from standard input.  (This can also be done for
+     *     all blocks if lit_bufsize is not greater than 32K.)
+     *   - if compression is not successful for a file smaller than 64K, we can
+     *     even emit a stored file instead of a stored block (saving 5 bytes).
+     *     This is applicable only for zip (not gzip or zlib).
+     *   - creating new Huffman trees less frequently may not provide fast
+     *     adaptation to changes in the input data statistics. (Take for
+     *     example a binary file with poorly compressible code followed by
+     *     a highly compressible string table.) Smaller buffer sizes give
+     *     fast adaptation but have of course the overhead of transmitting
+     *     trees more frequently.
+     *   - I can't count above 4
+     */
+
+    uInt last_lit;      /* running index in l_buf */
+
+    ushf *d_buf;
+    /* Buffer for distances. To simplify the code, d_buf and l_buf have
+     * the same number of elements. To use different lengths, an extra flag
+     * array would be necessary.
+     */
+
+    ulg opt_len;        /* bit length of current block with optimal trees */
+    ulg static_len;     /* bit length of current block with static trees */
+    uInt matches;       /* number of string matches in current block */
+    uInt insert;        /* bytes at end of window left to insert */
+
+#ifdef ZLIB_DEBUG
+    ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+    ulg bits_sent;      /* bit length of compressed data sent mod 2^32 */
+#endif
+
+    ush bi_buf;
+    /* Output buffer. bits are inserted starting at the bottom (least
+     * significant bits).
+     */
+    int bi_valid;
+    /* Number of valid bits in bi_buf.  All bits above the last valid bit
+     * are always zero.
+     */
+
+    ulg high_water;
+    /* High water mark offset in window for initialized bytes -- bytes above
+     * this are set to zero in order to avoid memory check warnings when
+     * longest match routines access bytes past the input.  This is then
+     * updated to the new high water mark.
+     */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+#define WIN_INIT MAX_MATCH
+/* Number of bytes after end of data in window to initialize in order to avoid
+   memory checker errors from longest match routines */
+
+        /* in trees.c */
+void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
+int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
+                        ulg stored_len, int last));
+void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s));
+void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
+void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
+                        ulg stored_len, int last));
+
+#define d_code(dist) \
+   ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef ZLIB_DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+  extern uch ZLIB_INTERNAL _length_code[];
+  extern uch ZLIB_INTERNAL _dist_code[];
+#else
+  extern const uch ZLIB_INTERNAL _length_code[];
+  extern const uch ZLIB_INTERNAL _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+  { uch cc = (c); \
+    s->d_buf[s->last_lit] = 0; \
+    s->l_buf[s->last_lit++] = cc; \
+    s->dyn_ltree[cc].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+   }
+# define _tr_tally_dist(s, distance, length, flush) \
+  { uch len = (uch)(length); \
+    ush dist = (ush)(distance); \
+    s->d_buf[s->last_lit] = dist; \
+    s->l_buf[s->last_lit++] = len; \
+    dist--; \
+    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+    s->dyn_dtree[d_code(dist)].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+  }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+              flush = _tr_tally(s, distance, length)
+#endif
+
+#endif /* DEFLATE_H */
Index: EcnlProtoTool/trunk/zlib-1.2.11/gzclose.c
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/gzclose.c	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/gzclose.c	(revision 331)
@@ -0,0 +1,25 @@
+/* gzclose.c -- zlib gzclose() function
+ * Copyright (C) 2004, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+/* gzclose() is in a separate file so that it is linked in only if it is used.
+   That way the other gzclose functions can be used instead to avoid linking in
+   unneeded compression or decompression routines. */
+int ZEXPORT gzclose(file)
+    gzFile file;
+{
+#ifndef NO_GZCOMPRESS
+    gz_statep state;
+
+    if (file == NULL)
+        return Z_STREAM_ERROR;
+    state = (gz_statep)file;
+
+    return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file);
+#else
+    return gzclose_r(file);
+#endif
+}
Index: EcnlProtoTool/trunk/zlib-1.2.11/gzguts.h
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/gzguts.h	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/gzguts.h	(revision 331)
@@ -0,0 +1,218 @@
+/* gzguts.h -- zlib internal header definitions for gz* operations
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#ifdef _LARGEFILE64_SOURCE
+#  ifndef _LARGEFILE_SOURCE
+#    define _LARGEFILE_SOURCE 1
+#  endif
+#  ifdef _FILE_OFFSET_BITS
+#    undef _FILE_OFFSET_BITS
+#  endif
+#endif
+
+#ifdef HAVE_HIDDEN
+#  define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+#  define ZLIB_INTERNAL
+#endif
+
+#include <stdio.h>
+#include "zlib.h"
+#ifdef STDC
+#  include <string.h>
+#  include <stdlib.h>
+#  include <limits.h>
+#endif
+
+#ifndef _POSIX_SOURCE
+#  define _POSIX_SOURCE
+#endif
+#include <fcntl.h>
+
+#ifdef _WIN32
+#  include <stddef.h>
+#endif
+
+#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)
+#  include <io.h>
+#endif
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+#  define WIDECHAR
+#endif
+
+#ifdef WINAPI_FAMILY
+#  define open _open
+#  define read _read
+#  define write _write
+#  define close _close
+#endif
+
+#ifdef NO_DEFLATE       /* for compatibility with old definition */
+#  define NO_GZCOMPRESS
+#endif
+
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
+#  ifndef HAVE_VSNPRINTF
+#    define HAVE_VSNPRINTF
+#  endif
+#endif
+
+#if defined(__CYGWIN__)
+#  ifndef HAVE_VSNPRINTF
+#    define HAVE_VSNPRINTF
+#  endif
+#endif
+
+#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410)
+#  ifndef HAVE_VSNPRINTF
+#    define HAVE_VSNPRINTF
+#  endif
+#endif
+
+#ifndef HAVE_VSNPRINTF
+#  ifdef MSDOS
+/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
+   but for now we just assume it doesn't. */
+#    define NO_vsnprintf
+#  endif
+#  ifdef __TURBOC__
+#    define NO_vsnprintf
+#  endif
+#  ifdef WIN32
+/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
+#    if !defined(vsnprintf) && !defined(NO_vsnprintf)
+#      if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
+#         define vsnprintf _vsnprintf
+#      endif
+#    endif
+#  endif
+#  ifdef __SASC
+#    define NO_vsnprintf
+#  endif
+#  ifdef VMS
+#    define NO_vsnprintf
+#  endif
+#  ifdef __OS400__
+#    define NO_vsnprintf
+#  endif
+#  ifdef __MVS__
+#    define NO_vsnprintf
+#  endif
+#endif
+
+/* unlike snprintf (which is required in C99), _snprintf does not guarantee
+   null termination of the result -- however this is only used in gzlib.c where
+   the result is assured to fit in the space provided */
+#if defined(_MSC_VER) && _MSC_VER < 1900
+#  define snprintf _snprintf
+#endif
+
+#ifndef local
+#  define local static
+#endif
+/* since "static" is used to mean two completely different things in C, we
+   define "local" for the non-static meaning of "static", for readability
+   (compile with -Dlocal if your debugger can't find static symbols) */
+
+/* gz* functions always use library allocation functions */
+#ifndef STDC
+  extern voidp  malloc OF((uInt size));
+  extern void   free   OF((voidpf ptr));
+#endif
+
+/* get errno and strerror definition */
+#if defined UNDER_CE
+#  include <windows.h>
+#  define zstrerror() gz_strwinerror((DWORD)GetLastError())
+#else
+#  ifndef NO_STRERROR
+#    include <errno.h>
+#    define zstrerror() strerror(errno)
+#  else
+#    define zstrerror() "stdio error (consult errno)"
+#  endif
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
+    ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+    ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+    ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+    ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+#endif
+
+/* default memLevel */
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+
+/* default i/o buffer size -- double this for output when reading (this and
+   twice this must be able to fit in an unsigned type) */
+#define GZBUFSIZE 8192
+
+/* gzip modes, also provide a little integrity check on the passed structure */
+#define GZ_NONE 0
+#define GZ_READ 7247
+#define GZ_WRITE 31153
+#define GZ_APPEND 1     /* mode set to GZ_WRITE after the file is opened */
+
+/* values for gz_state how */
+#define LOOK 0      /* look for a gzip header */
+#define COPY 1      /* copy input directly */
+#define GZIP 2      /* decompress a gzip stream */
+
+/* internal gzip file state data structure */
+typedef struct {
+        /* exposed contents for gzgetc() macro */
+    struct gzFile_s x;      /* "x" for exposed */
+                            /* x.have: number of bytes available at x.next */
+                            /* x.next: next output data to deliver or write */
+                            /* x.pos: current position in uncompressed data */
+        /* used for both reading and writing */
+    int mode;               /* see gzip modes above */
+    int fd;                 /* file descriptor */
+    char *path;             /* path or fd for error messages */
+    unsigned size;          /* buffer size, zero if not allocated yet */
+    unsigned want;          /* requested buffer size, default is GZBUFSIZE */
+    unsigned char *in;      /* input buffer (double-sized when writing) */
+    unsigned char *out;     /* output buffer (double-sized when reading) */
+    int direct;             /* 0 if processing gzip, 1 if transparent */
+        /* just for reading */
+    int how;                /* 0: get header, 1: copy, 2: decompress */
+    z_off64_t start;        /* where the gzip data started, for rewinding */
+    int eof;                /* true if end of input file reached */
+    int past;               /* true if read requested past end */
+        /* just for writing */
+    int level;              /* compression level */
+    int strategy;           /* compression strategy */
+        /* seek request */
+    z_off64_t skip;         /* amount to skip (already rewound if backwards) */
+    int seek;               /* true if seek request pending */
+        /* error information */
+    int err;                /* error code */
+    char *msg;              /* error message */
+        /* zlib inflate or deflate stream */
+    z_stream strm;          /* stream structure in-place (not a pointer) */
+} gz_state;
+typedef gz_state FAR *gz_statep;
+
+/* shared functions */
+void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
+#if defined UNDER_CE
+char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
+#endif
+
+/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
+   value -- needed when comparing unsigned to z_off64_t, which is signed
+   (possible z_off64_t types off_t, off64_t, and long are all signed) */
+#ifdef INT_MAX
+#  define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
+#else
+unsigned ZLIB_INTERNAL gz_intmax OF((void));
+#  define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
+#endif
Index: EcnlProtoTool/trunk/zlib-1.2.11/gzlib.c
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/gzlib.c	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/gzlib.c	(revision 331)
@@ -0,0 +1,637 @@
+/* gzlib.c -- zlib functions common to reading and writing gzip files
+ * Copyright (C) 2004-2017 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+#if defined(_WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__)
+#  define LSEEK _lseeki64
+#else
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+#  define LSEEK lseek64
+#else
+#  define LSEEK lseek
+#endif
+#endif
+
+/* Local functions */
+local void gz_reset OF((gz_statep));
+local gzFile gz_open OF((const void *, int, const char *));
+
+#if defined UNDER_CE
+
+/* Map the Windows error number in ERROR to a locale-dependent error message
+   string and return a pointer to it.  Typically, the values for ERROR come
+   from GetLastError.
+
+   The string pointed to shall not be modified by the application, but may be
+   overwritten by a subsequent call to gz_strwinerror
+
+   The gz_strwinerror function does not change the current setting of
+   GetLastError. */
+char ZLIB_INTERNAL *gz_strwinerror (error)
+     DWORD error;
+{
+    static char buf[1024];
+
+    wchar_t *msgbuf;
+    DWORD lasterr = GetLastError();
+    DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+        | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+        NULL,
+        error,
+        0, /* Default language */
+        (LPVOID)&msgbuf,
+        0,
+        NULL);
+    if (chars != 0) {
+        /* If there is an \r\n appended, zap it.  */
+        if (chars >= 2
+            && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
+            chars -= 2;
+            msgbuf[chars] = 0;
+        }
+
+        if (chars > sizeof (buf) - 1) {
+            chars = sizeof (buf) - 1;
+            msgbuf[chars] = 0;
+        }
+
+        wcstombs(buf, msgbuf, chars + 1);
+        LocalFree(msgbuf);
+    }
+    else {
+        sprintf(buf, "unknown win32 error (%ld)", error);
+    }
+
+    SetLastError(lasterr);
+    return buf;
+}
+
+#endif /* UNDER_CE */
+
+/* Reset gzip file state */
+local void gz_reset(state)
+    gz_statep state;
+{
+    state->x.have = 0;              /* no output data available */
+    if (state->mode == GZ_READ) {   /* for reading ... */
+        state->eof = 0;             /* not at end of file */
+        state->past = 0;            /* have not read past end yet */
+        state->how = LOOK;          /* look for gzip header */
+    }
+    state->seek = 0;                /* no seek request pending */
+    gz_error(state, Z_OK, NULL);    /* clear error */
+    state->x.pos = 0;               /* no uncompressed data yet */
+    state->strm.avail_in = 0;       /* no input data yet */
+}
+
+/* Open a gzip file either by name or file descriptor. */
+local gzFile gz_open(path, fd, mode)
+    const void *path;
+    int fd;
+    const char *mode;
+{
+    gz_statep state;
+    z_size_t len;
+    int oflag;
+#ifdef O_CLOEXEC
+    int cloexec = 0;
+#endif
+#ifdef O_EXCL
+    int exclusive = 0;
+#endif
+
+    /* check input */
+    if (path == NULL)
+        return NULL;
+
+    /* allocate gzFile structure to return */
+    state = (gz_statep)malloc(sizeof(gz_state));
+    if (state == NULL)
+        return NULL;
+    state->size = 0;            /* no buffers allocated yet */
+    state->want = GZBUFSIZE;    /* requested buffer size */
+    state->msg = NULL;          /* no error message yet */
+
+    /* interpret mode */
+    state->mode = GZ_NONE;
+    state->level = Z_DEFAULT_COMPRESSION;
+    state->strategy = Z_DEFAULT_STRATEGY;
+    state->direct = 0;
+    while (*mode) {
+        if (*mode >= '0' && *mode <= '9')
+            state->level = *mode - '0';
+        else
+            switch (*mode) {
+            case 'r':
+                state->mode = GZ_READ;
+                break;
+#ifndef NO_GZCOMPRESS
+            case 'w':
+                state->mode = GZ_WRITE;
+                break;
+            case 'a':
+                state->mode = GZ_APPEND;
+                break;
+#endif
+            case '+':       /* can't read and write at the same time */
+                free(state);
+                return NULL;
+            case 'b':       /* ignore -- will request binary anyway */
+                break;
+#ifdef O_CLOEXEC
+            case 'e':
+                cloexec = 1;
+                break;
+#endif
+#ifdef O_EXCL
+            case 'x':
+                exclusive = 1;
+                break;
+#endif
+            case 'f':
+                state->strategy = Z_FILTERED;
+                break;
+            case 'h':
+                state->strategy = Z_HUFFMAN_ONLY;
+                break;
+            case 'R':
+                state->strategy = Z_RLE;
+                break;
+            case 'F':
+                state->strategy = Z_FIXED;
+                break;
+            case 'T':
+                state->direct = 1;
+                break;
+            default:        /* could consider as an error, but just ignore */
+                ;
+            }
+        mode++;
+    }
+
+    /* must provide an "r", "w", or "a" */
+    if (state->mode == GZ_NONE) {
+        free(state);
+        return NULL;
+    }
+
+    /* can't force transparent read */
+    if (state->mode == GZ_READ) {
+        if (state->direct) {
+            free(state);
+            return NULL;
+        }
+        state->direct = 1;      /* for empty file */
+    }
+
+    /* save the path name for error messages */
+#ifdef WIDECHAR
+    if (fd == -2) {
+        len = wcstombs(NULL, path, 0);
+        if (len == (z_size_t)-1)
+            len = 0;
+    }
+    else
+#endif
+        len = strlen((const char *)path);
+    state->path = (char *)malloc(len + 1);
+    if (state->path == NULL) {
+        free(state);
+        return NULL;
+    }
+#ifdef WIDECHAR
+    if (fd == -2)
+        if (len)
+            wcstombs(state->path, path, len + 1);
+        else
+            *(state->path) = 0;
+    else
+#endif
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+        (void)snprintf(state->path, len + 1, "%s", (const char *)path);
+#else
+        strcpy(state->path, path);
+#endif
+
+    /* compute the flags for open() */
+    oflag =
+#ifdef O_LARGEFILE
+        O_LARGEFILE |
+#endif
+#ifdef O_BINARY
+        O_BINARY |
+#endif
+#ifdef O_CLOEXEC
+        (cloexec ? O_CLOEXEC : 0) |
+#endif
+        (state->mode == GZ_READ ?
+         O_RDONLY :
+         (O_WRONLY | O_CREAT |
+#ifdef O_EXCL
+          (exclusive ? O_EXCL : 0) |
+#endif
+          (state->mode == GZ_WRITE ?
+           O_TRUNC :
+           O_APPEND)));
+
+    /* open the file with the appropriate flags (or just use fd) */
+    state->fd = fd > -1 ? fd : (
+#ifdef WIDECHAR
+        fd == -2 ? _wopen(path, oflag, 0666) :
+#endif
+        open((const char *)path, oflag, 0666));
+    if (state->fd == -1) {
+        free(state->path);
+        free(state);
+        return NULL;
+    }
+    if (state->mode == GZ_APPEND) {
+        LSEEK(state->fd, 0, SEEK_END);  /* so gzoffset() is correct */
+        state->mode = GZ_WRITE;         /* simplify later checks */
+    }
+
+    /* save the current position for rewinding (only if reading) */
+    if (state->mode == GZ_READ) {
+        state->start = LSEEK(state->fd, 0, SEEK_CUR);
+        if (state->start == -1) state->start = 0;
+    }
+
+    /* initialize stream */
+    gz_reset(state);
+
+    /* return stream */
+    return (gzFile)state;
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzopen(path, mode)
+    const char *path;
+    const char *mode;
+{
+    return gz_open(path, -1, mode);
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzopen64(path, mode)
+    const char *path;
+    const char *mode;
+{
+    return gz_open(path, -1, mode);
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzdopen(fd, mode)
+    int fd;
+    const char *mode;
+{
+    char *path;         /* identifier for error messages */
+    gzFile gz;
+
+    if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
+        return NULL;
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+    (void)snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd);
+#else
+    sprintf(path, "<fd:%d>", fd);   /* for debugging */
+#endif
+    gz = gz_open(path, fd, mode);
+    free(path);
+    return gz;
+}
+
+/* -- see zlib.h -- */
+#ifdef WIDECHAR
+gzFile ZEXPORT gzopen_w(path, mode)
+    const wchar_t *path;
+    const char *mode;
+{
+    return gz_open(path, -2, mode);
+}
+#endif
+
+/* -- see zlib.h -- */
+int ZEXPORT gzbuffer(file, size)
+    gzFile file;
+    unsigned size;
+{
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return -1;
+
+    /* make sure we haven't already allocated memory */
+    if (state->size != 0)
+        return -1;
+
+    /* check and set requested size */
+    if ((size << 1) < size)
+        return -1;              /* need to be able to double it */
+    if (size < 2)
+        size = 2;               /* need two bytes to check magic header */
+    state->want = size;
+    return 0;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzrewind(file)
+    gzFile file;
+{
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+
+    /* check that we're reading and that there's no error */
+    if (state->mode != GZ_READ ||
+            (state->err != Z_OK && state->err != Z_BUF_ERROR))
+        return -1;
+
+    /* back up and start over */
+    if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
+        return -1;
+    gz_reset(state);
+    return 0;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gzseek64(file, offset, whence)
+    gzFile file;
+    z_off64_t offset;
+    int whence;
+{
+    unsigned n;
+    z_off64_t ret;
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return -1;
+
+    /* check that there's no error */
+    if (state->err != Z_OK && state->err != Z_BUF_ERROR)
+        return -1;
+
+    /* can only seek from start or relative to current position */
+    if (whence != SEEK_SET && whence != SEEK_CUR)
+        return -1;
+
+    /* normalize offset to a SEEK_CUR specification */
+    if (whence == SEEK_SET)
+        offset -= state->x.pos;
+    else if (state->seek)
+        offset += state->skip;
+    state->seek = 0;
+
+    /* if within raw area while reading, just go there */
+    if (state->mode == GZ_READ && state->how == COPY &&
+            state->x.pos + offset >= 0) {
+        ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
+        if (ret == -1)
+            return -1;
+        state->x.have = 0;
+        state->eof = 0;
+        state->past = 0;
+        state->seek = 0;
+        gz_error(state, Z_OK, NULL);
+        state->strm.avail_in = 0;
+        state->x.pos += offset;
+        return state->x.pos;
+    }
+
+    /* calculate skip amount, rewinding if needed for back seek when reading */
+    if (offset < 0) {
+        if (state->mode != GZ_READ)         /* writing -- can't go backwards */
+            return -1;
+        offset += state->x.pos;
+        if (offset < 0)                     /* before start of file! */
+            return -1;
+        if (gzrewind(file) == -1)           /* rewind, then skip to offset */
+            return -1;
+    }
+
+    /* if reading, skip what's in output buffer (one less gzgetc() check) */
+    if (state->mode == GZ_READ) {
+        n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
+            (unsigned)offset : state->x.have;
+        state->x.have -= n;
+        state->x.next += n;
+        state->x.pos += n;
+        offset -= n;
+    }
+
+    /* request skip (if not zero) */
+    if (offset) {
+        state->seek = 1;
+        state->skip = offset;
+    }
+    return state->x.pos + offset;
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gzseek(file, offset, whence)
+    gzFile file;
+    z_off_t offset;
+    int whence;
+{
+    z_off64_t ret;
+
+    ret = gzseek64(file, (z_off64_t)offset, whence);
+    return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gztell64(file)
+    gzFile file;
+{
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return -1;
+
+    /* return position */
+    return state->x.pos + (state->seek ? state->skip : 0);
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gztell(file)
+    gzFile file;
+{
+    z_off64_t ret;
+
+    ret = gztell64(file);
+    return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gzoffset64(file)
+    gzFile file;
+{
+    z_off64_t offset;
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return -1;
+
+    /* compute and return effective offset in file */
+    offset = LSEEK(state->fd, 0, SEEK_CUR);
+    if (offset == -1)
+        return -1;
+    if (state->mode == GZ_READ)             /* reading */
+        offset -= state->strm.avail_in;     /* don't count buffered input */
+    return offset;
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gzoffset(file)
+    gzFile file;
+{
+    z_off64_t ret;
+
+    ret = gzoffset64(file);
+    return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzeof(file)
+    gzFile file;
+{
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return 0;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return 0;
+
+    /* return end-of-file state */
+    return state->mode == GZ_READ ? state->past : 0;
+}
+
+/* -- see zlib.h -- */
+const char * ZEXPORT gzerror(file, errnum)
+    gzFile file;
+    int *errnum;
+{
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return NULL;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return NULL;
+
+    /* return error information */
+    if (errnum != NULL)
+        *errnum = state->err;
+    return state->err == Z_MEM_ERROR ? "out of memory" :
+                                       (state->msg == NULL ? "" : state->msg);
+}
+
+/* -- see zlib.h -- */
+void ZEXPORT gzclearerr(file)
+    gzFile file;
+{
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return;
+
+    /* clear error and end-of-file */
+    if (state->mode == GZ_READ) {
+        state->eof = 0;
+        state->past = 0;
+    }
+    gz_error(state, Z_OK, NULL);
+}
+
+/* Create an error message in allocated memory and set state->err and
+   state->msg accordingly.  Free any previous error message already there.  Do
+   not try to free or allocate space if the error is Z_MEM_ERROR (out of
+   memory).  Simply save the error message as a static string.  If there is an
+   allocation failure constructing the error message, then convert the error to
+   out of memory. */
+void ZLIB_INTERNAL gz_error(state, err, msg)
+    gz_statep state;
+    int err;
+    const char *msg;
+{
+    /* free previously allocated message and clear */
+    if (state->msg != NULL) {
+        if (state->err != Z_MEM_ERROR)
+            free(state->msg);
+        state->msg = NULL;
+    }
+
+    /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
+    if (err != Z_OK && err != Z_BUF_ERROR)
+        state->x.have = 0;
+
+    /* set error code, and if no message, then done */
+    state->err = err;
+    if (msg == NULL)
+        return;
+
+    /* for an out of memory error, return literal string when requested */
+    if (err == Z_MEM_ERROR)
+        return;
+
+    /* construct error message with path */
+    if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
+            NULL) {
+        state->err = Z_MEM_ERROR;
+        return;
+    }
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+    (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
+                   "%s%s%s", state->path, ": ", msg);
+#else
+    strcpy(state->msg, state->path);
+    strcat(state->msg, ": ");
+    strcat(state->msg, msg);
+#endif
+}
+
+#ifndef INT_MAX
+/* portably return maximum value for an int (when limits.h presumed not
+   available) -- we need to do this to cover cases where 2's complement not
+   used, since C standard permits 1's complement and sign-bit representations,
+   otherwise we could just use ((unsigned)-1) >> 1 */
+unsigned ZLIB_INTERNAL gz_intmax()
+{
+    unsigned p, q;
+
+    p = 1;
+    do {
+        q = p;
+        p <<= 1;
+        p++;
+    } while (p > q);
+    return q >> 1;
+}
+#endif
Index: EcnlProtoTool/trunk/zlib-1.2.11/gzread.c
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/gzread.c	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/gzread.c	(revision 331)
@@ -0,0 +1,654 @@
+/* gzread.c -- zlib functions for reading gzip files
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+/* Local functions */
+local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
+local int gz_avail OF((gz_statep));
+local int gz_look OF((gz_statep));
+local int gz_decomp OF((gz_statep));
+local int gz_fetch OF((gz_statep));
+local int gz_skip OF((gz_statep, z_off64_t));
+local z_size_t gz_read OF((gz_statep, voidp, z_size_t));
+
+/* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from
+   state->fd, and update state->eof, state->err, and state->msg as appropriate.
+   This function needs to loop on read(), since read() is not guaranteed to
+   read the number of bytes requested, depending on the type of descriptor. */
+local int gz_load(state, buf, len, have)
+    gz_statep state;
+    unsigned char *buf;
+    unsigned len;
+    unsigned *have;
+{
+    int ret;
+    unsigned get, max = ((unsigned)-1 >> 2) + 1;
+
+    *have = 0;
+    do {
+        get = len - *have;
+        if (get > max)
+            get = max;
+        ret = read(state->fd, buf + *have, get);
+        if (ret <= 0)
+            break;
+        *have += (unsigned)ret;
+    } while (*have < len);
+    if (ret < 0) {
+        gz_error(state, Z_ERRNO, zstrerror());
+        return -1;
+    }
+    if (ret == 0)
+        state->eof = 1;
+    return 0;
+}
+
+/* Load up input buffer and set eof flag if last data loaded -- return -1 on
+   error, 0 otherwise.  Note that the eof flag is set when the end of the input
+   file is reached, even though there may be unused data in the buffer.  Once
+   that data has been used, no more attempts will be made to read the file.
+   If strm->avail_in != 0, then the current data is moved to the beginning of
+   the input buffer, and then the remainder of the buffer is loaded with the
+   available data from the input file. */
+local int gz_avail(state)
+    gz_statep state;
+{
+    unsigned got;
+    z_streamp strm = &(state->strm);
+
+    if (state->err != Z_OK && state->err != Z_BUF_ERROR)
+        return -1;
+    if (state->eof == 0) {
+        if (strm->avail_in) {       /* copy what's there to the start */
+            unsigned char *p = state->in;
+            unsigned const char *q = strm->next_in;
+            unsigned n = strm->avail_in;
+            do {
+                *p++ = *q++;
+            } while (--n);
+        }
+        if (gz_load(state, state->in + strm->avail_in,
+                    state->size - strm->avail_in, &got) == -1)
+            return -1;
+        strm->avail_in += got;
+        strm->next_in = state->in;
+    }
+    return 0;
+}
+
+/* Look for gzip header, set up for inflate or copy.  state->x.have must be 0.
+   If this is the first time in, allocate required memory.  state->how will be
+   left unchanged if there is no more input data available, will be set to COPY
+   if there is no gzip header and direct copying will be performed, or it will
+   be set to GZIP for decompression.  If direct copying, then leftover input
+   data from the input buffer will be copied to the output buffer.  In that
+   case, all further file reads will be directly to either the output buffer or
+   a user buffer.  If decompressing, the inflate state will be initialized.
+   gz_look() will return 0 on success or -1 on failure. */
+local int gz_look(state)
+    gz_statep state;
+{
+    z_streamp strm = &(state->strm);
+
+    /* allocate read buffers and inflate memory */
+    if (state->size == 0) {
+        /* allocate buffers */
+        state->in = (unsigned char *)malloc(state->want);
+        state->out = (unsigned char *)malloc(state->want << 1);
+        if (state->in == NULL || state->out == NULL) {
+            free(state->out);
+            free(state->in);
+            gz_error(state, Z_MEM_ERROR, "out of memory");
+            return -1;
+        }
+        state->size = state->want;
+
+        /* allocate inflate memory */
+        state->strm.zalloc = Z_NULL;
+        state->strm.zfree = Z_NULL;
+        state->strm.opaque = Z_NULL;
+        state->strm.avail_in = 0;
+        state->strm.next_in = Z_NULL;
+        if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) {    /* gunzip */
+            free(state->out);
+            free(state->in);
+            state->size = 0;
+            gz_error(state, Z_MEM_ERROR, "out of memory");
+            return -1;
+        }
+    }
+
+    /* get at least the magic bytes in the input buffer */
+    if (strm->avail_in < 2) {
+        if (gz_avail(state) == -1)
+            return -1;
+        if (strm->avail_in == 0)
+            return 0;
+    }
+
+    /* look for gzip magic bytes -- if there, do gzip decoding (note: there is
+       a logical dilemma here when considering the case of a partially written
+       gzip file, to wit, if a single 31 byte is written, then we cannot tell
+       whether this is a single-byte file, or just a partially written gzip
+       file -- for here we assume that if a gzip file is being written, then
+       the header will be written in a single operation, so that reading a
+       single byte is sufficient indication that it is not a gzip file) */
+    if (strm->avail_in > 1 &&
+            strm->next_in[0] == 31 && strm->next_in[1] == 139) {
+        inflateReset(strm);
+        state->how = GZIP;
+        state->direct = 0;
+        return 0;
+    }
+
+    /* no gzip header -- if we were decoding gzip before, then this is trailing
+       garbage.  Ignore the trailing garbage and finish. */
+    if (state->direct == 0) {
+        strm->avail_in = 0;
+        state->eof = 1;
+        state->x.have = 0;
+        return 0;
+    }
+
+    /* doing raw i/o, copy any leftover input to output -- this assumes that
+       the output buffer is larger than the input buffer, which also assures
+       space for gzungetc() */
+    state->x.next = state->out;
+    if (strm->avail_in) {
+        memcpy(state->x.next, strm->next_in, strm->avail_in);
+        state->x.have = strm->avail_in;
+        strm->avail_in = 0;
+    }
+    state->how = COPY;
+    state->direct = 1;
+    return 0;
+}
+
+/* Decompress from input to the provided next_out and avail_out in the state.
+   On return, state->x.have and state->x.next point to the just decompressed
+   data.  If the gzip stream completes, state->how is reset to LOOK to look for
+   the next gzip stream or raw data, once state->x.have is depleted.  Returns 0
+   on success, -1 on failure. */
+local int gz_decomp(state)
+    gz_statep state;
+{
+    int ret = Z_OK;
+    unsigned had;
+    z_streamp strm = &(state->strm);
+
+    /* fill output buffer up to end of deflate stream */
+    had = strm->avail_out;
+    do {
+        /* get more input for inflate() */
+        if (strm->avail_in == 0 && gz_avail(state) == -1)
+            return -1;
+        if (strm->avail_in == 0) {
+            gz_error(state, Z_BUF_ERROR, "unexpected end of file");
+            break;
+        }
+
+        /* decompress and handle errors */
+        ret = inflate(strm, Z_NO_FLUSH);
+        if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
+            gz_error(state, Z_STREAM_ERROR,
+                     "internal error: inflate stream corrupt");
+            return -1;
+        }
+        if (ret == Z_MEM_ERROR) {
+            gz_error(state, Z_MEM_ERROR, "out of memory");
+            return -1;
+        }
+        if (ret == Z_DATA_ERROR) {              /* deflate stream invalid */
+            gz_error(state, Z_DATA_ERROR,
+                     strm->msg == NULL ? "compressed data error" : strm->msg);
+            return -1;
+        }
+    } while (strm->avail_out && ret != Z_STREAM_END);
+
+    /* update available output */
+    state->x.have = had - strm->avail_out;
+    state->x.next = strm->next_out - state->x.have;
+
+    /* if the gzip stream completed successfully, look for another */
+    if (ret == Z_STREAM_END)
+        state->how = LOOK;
+
+    /* good decompression */
+    return 0;
+}
+
+/* Fetch data and put it in the output buffer.  Assumes state->x.have is 0.
+   Data is either copied from the input file or decompressed from the input
+   file depending on state->how.  If state->how is LOOK, then a gzip header is
+   looked for to determine whether to copy or decompress.  Returns -1 on error,
+   otherwise 0.  gz_fetch() will leave state->how as COPY or GZIP unless the
+   end of the input file has been reached and all data has been processed.  */
+local int gz_fetch(state)
+    gz_statep state;
+{
+    z_streamp strm = &(state->strm);
+
+    do {
+        switch(state->how) {
+        case LOOK:      /* -> LOOK, COPY (only if never GZIP), or GZIP */
+            if (gz_look(state) == -1)
+                return -1;
+            if (state->how == LOOK)
+                return 0;
+            break;
+        case COPY:      /* -> COPY */
+            if (gz_load(state, state->out, state->size << 1, &(state->x.have))
+                    == -1)
+                return -1;
+            state->x.next = state->out;
+            return 0;
+        case GZIP:      /* -> GZIP or LOOK (if end of gzip stream) */
+            strm->avail_out = state->size << 1;
+            strm->next_out = state->out;
+            if (gz_decomp(state) == -1)
+                return -1;
+        }
+    } while (state->x.have == 0 && (!state->eof || strm->avail_in));
+    return 0;
+}
+
+/* Skip len uncompressed bytes of output.  Return -1 on error, 0 on success. */
+local int gz_skip(state, len)
+    gz_statep state;
+    z_off64_t len;
+{
+    unsigned n;
+
+    /* skip over len bytes or reach end-of-file, whichever comes first */
+    while (len)
+        /* skip over whatever is in output buffer */
+        if (state->x.have) {
+            n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
+                (unsigned)len : state->x.have;
+            state->x.have -= n;
+            state->x.next += n;
+            state->x.pos += n;
+            len -= n;
+        }
+
+        /* output buffer empty -- return if we're at the end of the input */
+        else if (state->eof && state->strm.avail_in == 0)
+            break;
+
+        /* need more data to skip -- load up output buffer */
+        else {
+            /* get more output, looking for header if required */
+            if (gz_fetch(state) == -1)
+                return -1;
+        }
+    return 0;
+}
+
+/* Read len bytes into buf from file, or less than len up to the end of the
+   input.  Return the number of bytes read.  If zero is returned, either the
+   end of file was reached, or there was an error.  state->err must be
+   consulted in that case to determine which. */
+local z_size_t gz_read(state, buf, len)
+    gz_statep state;
+    voidp buf;
+    z_size_t len;
+{
+    z_size_t got;
+    unsigned n;
+
+    /* if len is zero, avoid unnecessary operations */
+    if (len == 0)
+        return 0;
+
+    /* process a skip request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_skip(state, state->skip) == -1)
+            return 0;
+    }
+
+    /* get len bytes to buf, or less than len if at the end */
+    got = 0;
+    do {
+        /* set n to the maximum amount of len that fits in an unsigned int */
+        n = -1;
+        if (n > len)
+            n = len;
+
+        /* first just try copying data from the output buffer */
+        if (state->x.have) {
+            if (state->x.have < n)
+                n = state->x.have;
+            memcpy(buf, state->x.next, n);
+            state->x.next += n;
+            state->x.have -= n;
+        }
+
+        /* output buffer empty -- return if we're at the end of the input */
+        else if (state->eof && state->strm.avail_in == 0) {
+            state->past = 1;        /* tried to read past end */
+            break;
+        }
+
+        /* need output data -- for small len or new stream load up our output
+           buffer */
+        else if (state->how == LOOK || n < (state->size << 1)) {
+            /* get more output, looking for header if required */
+            if (gz_fetch(state) == -1)
+                return 0;
+            continue;       /* no progress yet -- go back to copy above */
+            /* the copy above assures that we will leave with space in the
+               output buffer, allowing at least one gzungetc() to succeed */
+        }
+
+        /* large len -- read directly into user buffer */
+        else if (state->how == COPY) {      /* read directly */
+            if (gz_load(state, (unsigned char *)buf, n, &n) == -1)
+                return 0;
+        }
+
+        /* large len -- decompress directly into user buffer */
+        else {  /* state->how == GZIP */
+            state->strm.avail_out = n;
+            state->strm.next_out = (unsigned char *)buf;
+            if (gz_decomp(state) == -1)
+                return 0;
+            n = state->x.have;
+            state->x.have = 0;
+        }
+
+        /* update progress */
+        len -= n;
+        buf = (char *)buf + n;
+        got += n;
+        state->x.pos += n;
+    } while (len);
+
+    /* return number of bytes read into user buffer */
+    return got;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzread(file, buf, len)
+    gzFile file;
+    voidp buf;
+    unsigned len;
+{
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+
+    /* check that we're reading and that there's no (serious) error */
+    if (state->mode != GZ_READ ||
+            (state->err != Z_OK && state->err != Z_BUF_ERROR))
+        return -1;
+
+    /* since an int is returned, make sure len fits in one, otherwise return
+       with an error (this avoids a flaw in the interface) */
+    if ((int)len < 0) {
+        gz_error(state, Z_STREAM_ERROR, "request does not fit in an int");
+        return -1;
+    }
+
+    /* read len or fewer bytes to buf */
+    len = gz_read(state, buf, len);
+
+    /* check for an error */
+    if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR)
+        return -1;
+
+    /* return the number of bytes read (this is assured to fit in an int) */
+    return (int)len;
+}
+
+/* -- see zlib.h -- */
+z_size_t ZEXPORT gzfread(buf, size, nitems, file)
+    voidp buf;
+    z_size_t size;
+    z_size_t nitems;
+    gzFile file;
+{
+    z_size_t len;
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return 0;
+    state = (gz_statep)file;
+
+    /* check that we're reading and that there's no (serious) error */
+    if (state->mode != GZ_READ ||
+            (state->err != Z_OK && state->err != Z_BUF_ERROR))
+        return 0;
+
+    /* compute bytes to read -- error on overflow */
+    len = nitems * size;
+    if (size && len / size != nitems) {
+        gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
+        return 0;
+    }
+
+    /* read len or fewer bytes to buf, return the number of full items read */
+    return len ? gz_read(state, buf, len) / size : 0;
+}
+
+/* -- see zlib.h -- */
+#ifdef Z_PREFIX_SET
+#  undef z_gzgetc
+#else
+#  undef gzgetc
+#endif
+int ZEXPORT gzgetc(file)
+    gzFile file;
+{
+    int ret;
+    unsigned char buf[1];
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+
+    /* check that we're reading and that there's no (serious) error */
+    if (state->mode != GZ_READ ||
+        (state->err != Z_OK && state->err != Z_BUF_ERROR))
+        return -1;
+
+    /* try output buffer (no need to check for skip request) */
+    if (state->x.have) {
+        state->x.have--;
+        state->x.pos++;
+        return *(state->x.next)++;
+    }
+
+    /* nothing there -- try gz_read() */
+    ret = gz_read(state, buf, 1);
+    return ret < 1 ? -1 : buf[0];
+}
+
+int ZEXPORT gzgetc_(file)
+gzFile file;
+{
+    return gzgetc(file);
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzungetc(c, file)
+    int c;
+    gzFile file;
+{
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+
+    /* check that we're reading and that there's no (serious) error */
+    if (state->mode != GZ_READ ||
+        (state->err != Z_OK && state->err != Z_BUF_ERROR))
+        return -1;
+
+    /* process a skip request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_skip(state, state->skip) == -1)
+            return -1;
+    }
+
+    /* can't push EOF */
+    if (c < 0)
+        return -1;
+
+    /* if output buffer empty, put byte at end (allows more pushing) */
+    if (state->x.have == 0) {
+        state->x.have = 1;
+        state->x.next = state->out + (state->size << 1) - 1;
+        state->x.next[0] = (unsigned char)c;
+        state->x.pos--;
+        state->past = 0;
+        return c;
+    }
+
+    /* if no room, give up (must have already done a gzungetc()) */
+    if (state->x.have == (state->size << 1)) {
+        gz_error(state, Z_DATA_ERROR, "out of room to push characters");
+        return -1;
+    }
+
+    /* slide output data if needed and insert byte before existing data */
+    if (state->x.next == state->out) {
+        unsigned char *src = state->out + state->x.have;
+        unsigned char *dest = state->out + (state->size << 1);
+        while (src > state->out)
+            *--dest = *--src;
+        state->x.next = dest;
+    }
+    state->x.have++;
+    state->x.next--;
+    state->x.next[0] = (unsigned char)c;
+    state->x.pos--;
+    state->past = 0;
+    return c;
+}
+
+/* -- see zlib.h -- */
+char * ZEXPORT gzgets(file, buf, len)
+    gzFile file;
+    char *buf;
+    int len;
+{
+    unsigned left, n;
+    char *str;
+    unsigned char *eol;
+    gz_statep state;
+
+    /* check parameters and get internal structure */
+    if (file == NULL || buf == NULL || len < 1)
+        return NULL;
+    state = (gz_statep)file;
+
+    /* check that we're reading and that there's no (serious) error */
+    if (state->mode != GZ_READ ||
+        (state->err != Z_OK && state->err != Z_BUF_ERROR))
+        return NULL;
+
+    /* process a skip request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_skip(state, state->skip) == -1)
+            return NULL;
+    }
+
+    /* copy output bytes up to new line or len - 1, whichever comes first --
+       append a terminating zero to the string (we don't check for a zero in
+       the contents, let the user worry about that) */
+    str = buf;
+    left = (unsigned)len - 1;
+    if (left) do {
+        /* assure that something is in the output buffer */
+        if (state->x.have == 0 && gz_fetch(state) == -1)
+            return NULL;                /* error */
+        if (state->x.have == 0) {       /* end of file */
+            state->past = 1;            /* read past end */
+            break;                      /* return what we have */
+        }
+
+        /* look for end-of-line in current output buffer */
+        n = state->x.have > left ? left : state->x.have;
+        eol = (unsigned char *)memchr(state->x.next, '\n', n);
+        if (eol != NULL)
+            n = (unsigned)(eol - state->x.next) + 1;
+
+        /* copy through end-of-line, or remainder if not found */
+        memcpy(buf, state->x.next, n);
+        state->x.have -= n;
+        state->x.next += n;
+        state->x.pos += n;
+        left -= n;
+        buf += n;
+    } while (left && eol == NULL);
+
+    /* return terminated string, or if nothing, end of file */
+    if (buf == str)
+        return NULL;
+    buf[0] = 0;
+    return str;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzdirect(file)
+    gzFile file;
+{
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return 0;
+    state = (gz_statep)file;
+
+    /* if the state is not known, but we can find out, then do so (this is
+       mainly for right after a gzopen() or gzdopen()) */
+    if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
+        (void)gz_look(state);
+
+    /* return 1 if transparent, 0 if processing a gzip stream */
+    return state->direct;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzclose_r(file)
+    gzFile file;
+{
+    int ret, err;
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return Z_STREAM_ERROR;
+    state = (gz_statep)file;
+
+    /* check that we're reading */
+    if (state->mode != GZ_READ)
+        return Z_STREAM_ERROR;
+
+    /* free memory and close file */
+    if (state->size) {
+        inflateEnd(&(state->strm));
+        free(state->out);
+        free(state->in);
+    }
+    err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
+    gz_error(state, Z_OK, NULL);
+    free(state->path);
+    ret = close(state->fd);
+    free(state);
+    return ret ? Z_ERRNO : err;
+}
Index: EcnlProtoTool/trunk/zlib-1.2.11/gzwrite.c
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/gzwrite.c	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/gzwrite.c	(revision 331)
@@ -0,0 +1,665 @@
+/* gzwrite.c -- zlib functions for writing gzip files
+ * Copyright (C) 2004-2017 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+/* Local functions */
+local int gz_init OF((gz_statep));
+local int gz_comp OF((gz_statep, int));
+local int gz_zero OF((gz_statep, z_off64_t));
+local z_size_t gz_write OF((gz_statep, voidpc, z_size_t));
+
+/* Initialize state for writing a gzip file.  Mark initialization by setting
+   state->size to non-zero.  Return -1 on a memory allocation failure, or 0 on
+   success. */
+local int gz_init(state)
+    gz_statep state;
+{
+    int ret;
+    z_streamp strm = &(state->strm);
+
+    /* allocate input buffer (double size for gzprintf) */
+    state->in = (unsigned char *)malloc(state->want << 1);
+    if (state->in == NULL) {
+        gz_error(state, Z_MEM_ERROR, "out of memory");
+        return -1;
+    }
+
+    /* only need output buffer and deflate state if compressing */
+    if (!state->direct) {
+        /* allocate output buffer */
+        state->out = (unsigned char *)malloc(state->want);
+        if (state->out == NULL) {
+            free(state->in);
+            gz_error(state, Z_MEM_ERROR, "out of memory");
+            return -1;
+        }
+
+        /* allocate deflate memory, set up for gzip compression */
+        strm->zalloc = Z_NULL;
+        strm->zfree = Z_NULL;
+        strm->opaque = Z_NULL;
+        ret = deflateInit2(strm, state->level, Z_DEFLATED,
+                           MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
+        if (ret != Z_OK) {
+            free(state->out);
+            free(state->in);
+            gz_error(state, Z_MEM_ERROR, "out of memory");
+            return -1;
+        }
+        strm->next_in = NULL;
+    }
+
+    /* mark state as initialized */
+    state->size = state->want;
+
+    /* initialize write buffer if compressing */
+    if (!state->direct) {
+        strm->avail_out = state->size;
+        strm->next_out = state->out;
+        state->x.next = strm->next_out;
+    }
+    return 0;
+}
+
+/* Compress whatever is at avail_in and next_in and write to the output file.
+   Return -1 if there is an error writing to the output file or if gz_init()
+   fails to allocate memory, otherwise 0.  flush is assumed to be a valid
+   deflate() flush value.  If flush is Z_FINISH, then the deflate() state is
+   reset to start a new gzip stream.  If gz->direct is true, then simply write
+   to the output file without compressing, and ignore flush. */
+local int gz_comp(state, flush)
+    gz_statep state;
+    int flush;
+{
+    int ret, writ;
+    unsigned have, put, max = ((unsigned)-1 >> 2) + 1;
+    z_streamp strm = &(state->strm);
+
+    /* allocate memory if this is the first time through */
+    if (state->size == 0 && gz_init(state) == -1)
+        return -1;
+
+    /* write directly if requested */
+    if (state->direct) {
+        while (strm->avail_in) {
+            put = strm->avail_in > max ? max : strm->avail_in;
+            writ = write(state->fd, strm->next_in, put);
+            if (writ < 0) {
+                gz_error(state, Z_ERRNO, zstrerror());
+                return -1;
+            }
+            strm->avail_in -= (unsigned)writ;
+            strm->next_in += writ;
+        }
+        return 0;
+    }
+
+    /* run deflate() on provided input until it produces no more output */
+    ret = Z_OK;
+    do {
+        /* write out current buffer contents if full, or if flushing, but if
+           doing Z_FINISH then don't write until we get to Z_STREAM_END */
+        if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
+            (flush != Z_FINISH || ret == Z_STREAM_END))) {
+            while (strm->next_out > state->x.next) {
+                put = strm->next_out - state->x.next > (int)max ? max :
+                      (unsigned)(strm->next_out - state->x.next);
+                writ = write(state->fd, state->x.next, put);
+                if (writ < 0) {
+                    gz_error(state, Z_ERRNO, zstrerror());
+                    return -1;
+                }
+                state->x.next += writ;
+            }
+            if (strm->avail_out == 0) {
+                strm->avail_out = state->size;
+                strm->next_out = state->out;
+                state->x.next = state->out;
+            }
+        }
+
+        /* compress */
+        have = strm->avail_out;
+        ret = deflate(strm, flush);
+        if (ret == Z_STREAM_ERROR) {
+            gz_error(state, Z_STREAM_ERROR,
+                      "internal error: deflate stream corrupt");
+            return -1;
+        }
+        have -= strm->avail_out;
+    } while (have);
+
+    /* if that completed a deflate stream, allow another to start */
+    if (flush == Z_FINISH)
+        deflateReset(strm);
+
+    /* all done, no errors */
+    return 0;
+}
+
+/* Compress len zeros to output.  Return -1 on a write error or memory
+   allocation failure by gz_comp(), or 0 on success. */
+local int gz_zero(state, len)
+    gz_statep state;
+    z_off64_t len;
+{
+    int first;
+    unsigned n;
+    z_streamp strm = &(state->strm);
+
+    /* consume whatever's left in the input buffer */
+    if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+        return -1;
+
+    /* compress len zeros (len guaranteed > 0) */
+    first = 1;
+    while (len) {
+        n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
+            (unsigned)len : state->size;
+        if (first) {
+            memset(state->in, 0, n);
+            first = 0;
+        }
+        strm->avail_in = n;
+        strm->next_in = state->in;
+        state->x.pos += n;
+        if (gz_comp(state, Z_NO_FLUSH) == -1)
+            return -1;
+        len -= n;
+    }
+    return 0;
+}
+
+/* Write len bytes from buf to file.  Return the number of bytes written.  If
+   the returned value is less than len, then there was an error. */
+local z_size_t gz_write(state, buf, len)
+    gz_statep state;
+    voidpc buf;
+    z_size_t len;
+{
+    z_size_t put = len;
+
+    /* if len is zero, avoid unnecessary operations */
+    if (len == 0)
+        return 0;
+
+    /* allocate memory if this is the first time through */
+    if (state->size == 0 && gz_init(state) == -1)
+        return 0;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_zero(state, state->skip) == -1)
+            return 0;
+    }
+
+    /* for small len, copy to input buffer, otherwise compress directly */
+    if (len < state->size) {
+        /* copy to input buffer, compress when full */
+        do {
+            unsigned have, copy;
+
+            if (state->strm.avail_in == 0)
+                state->strm.next_in = state->in;
+            have = (unsigned)((state->strm.next_in + state->strm.avail_in) -
+                              state->in);
+            copy = state->size - have;
+            if (copy > len)
+                copy = len;
+            memcpy(state->in + have, buf, copy);
+            state->strm.avail_in += copy;
+            state->x.pos += copy;
+            buf = (const char *)buf + copy;
+            len -= copy;
+            if (len && gz_comp(state, Z_NO_FLUSH) == -1)
+                return 0;
+        } while (len);
+    }
+    else {
+        /* consume whatever's left in the input buffer */
+        if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+            return 0;
+
+        /* directly compress user buffer to file */
+        state->strm.next_in = (z_const Bytef *)buf;
+        do {
+            unsigned n = (unsigned)-1;
+            if (n > len)
+                n = len;
+            state->strm.avail_in = n;
+            state->x.pos += n;
+            if (gz_comp(state, Z_NO_FLUSH) == -1)
+                return 0;
+            len -= n;
+        } while (len);
+    }
+
+    /* input was all buffered or compressed */
+    return put;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzwrite(file, buf, len)
+    gzFile file;
+    voidpc buf;
+    unsigned len;
+{
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return 0;
+    state = (gz_statep)file;
+
+    /* check that we're writing and that there's no error */
+    if (state->mode != GZ_WRITE || state->err != Z_OK)
+        return 0;
+
+    /* since an int is returned, make sure len fits in one, otherwise return
+       with an error (this avoids a flaw in the interface) */
+    if ((int)len < 0) {
+        gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
+        return 0;
+    }
+
+    /* write len bytes from buf (the return value will fit in an int) */
+    return (int)gz_write(state, buf, len);
+}
+
+/* -- see zlib.h -- */
+z_size_t ZEXPORT gzfwrite(buf, size, nitems, file)
+    voidpc buf;
+    z_size_t size;
+    z_size_t nitems;
+    gzFile file;
+{
+    z_size_t len;
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return 0;
+    state = (gz_statep)file;
+
+    /* check that we're writing and that there's no error */
+    if (state->mode != GZ_WRITE || state->err != Z_OK)
+        return 0;
+
+    /* compute bytes to read -- error on overflow */
+    len = nitems * size;
+    if (size && len / size != nitems) {
+        gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
+        return 0;
+    }
+
+    /* write len bytes to buf, return the number of full items written */
+    return len ? gz_write(state, buf, len) / size : 0;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzputc(file, c)
+    gzFile file;
+    int c;
+{
+    unsigned have;
+    unsigned char buf[1];
+    gz_statep state;
+    z_streamp strm;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    strm = &(state->strm);
+
+    /* check that we're writing and that there's no error */
+    if (state->mode != GZ_WRITE || state->err != Z_OK)
+        return -1;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_zero(state, state->skip) == -1)
+            return -1;
+    }
+
+    /* try writing to input buffer for speed (state->size == 0 if buffer not
+       initialized) */
+    if (state->size) {
+        if (strm->avail_in == 0)
+            strm->next_in = state->in;
+        have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
+        if (have < state->size) {
+            state->in[have] = (unsigned char)c;
+            strm->avail_in++;
+            state->x.pos++;
+            return c & 0xff;
+        }
+    }
+
+    /* no room in buffer or not initialized, use gz_write() */
+    buf[0] = (unsigned char)c;
+    if (gz_write(state, buf, 1) != 1)
+        return -1;
+    return c & 0xff;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzputs(file, str)
+    gzFile file;
+    const char *str;
+{
+    int ret;
+    z_size_t len;
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+
+    /* check that we're writing and that there's no error */
+    if (state->mode != GZ_WRITE || state->err != Z_OK)
+        return -1;
+
+    /* write string */
+    len = strlen(str);
+    ret = gz_write(state, str, len);
+    return ret == 0 && len != 0 ? -1 : ret;
+}
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#include <stdarg.h>
+
+/* -- see zlib.h -- */
+int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
+{
+    int len;
+    unsigned left;
+    char *next;
+    gz_statep state;
+    z_streamp strm;
+
+    /* get internal structure */
+    if (file == NULL)
+        return Z_STREAM_ERROR;
+    state = (gz_statep)file;
+    strm = &(state->strm);
+
+    /* check that we're writing and that there's no error */
+    if (state->mode != GZ_WRITE || state->err != Z_OK)
+        return Z_STREAM_ERROR;
+
+    /* make sure we have some buffer space */
+    if (state->size == 0 && gz_init(state) == -1)
+        return state->err;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_zero(state, state->skip) == -1)
+            return state->err;
+    }
+
+    /* do the printf() into the input buffer, put length in len -- the input
+       buffer is double-sized just for this function, so there is guaranteed to
+       be state->size bytes available after the current contents */
+    if (strm->avail_in == 0)
+        strm->next_in = state->in;
+    next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in);
+    next[state->size - 1] = 0;
+#ifdef NO_vsnprintf
+#  ifdef HAS_vsprintf_void
+    (void)vsprintf(next, format, va);
+    for (len = 0; len < state->size; len++)
+        if (next[len] == 0) break;
+#  else
+    len = vsprintf(next, format, va);
+#  endif
+#else
+#  ifdef HAS_vsnprintf_void
+    (void)vsnprintf(next, state->size, format, va);
+    len = strlen(next);
+#  else
+    len = vsnprintf(next, state->size, format, va);
+#  endif
+#endif
+
+    /* check that printf() results fit in buffer */
+    if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0)
+        return 0;
+
+    /* update buffer and position, compress first half if past that */
+    strm->avail_in += (unsigned)len;
+    state->x.pos += len;
+    if (strm->avail_in >= state->size) {
+        left = strm->avail_in - state->size;
+        strm->avail_in = state->size;
+        if (gz_comp(state, Z_NO_FLUSH) == -1)
+            return state->err;
+        memcpy(state->in, state->in + state->size, left);
+        strm->next_in = state->in;
+        strm->avail_in = left;
+    }
+    return len;
+}
+
+int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
+{
+    va_list va;
+    int ret;
+
+    va_start(va, format);
+    ret = gzvprintf(file, format, va);
+    va_end(va);
+    return ret;
+}
+
+#else /* !STDC && !Z_HAVE_STDARG_H */
+
+/* -- see zlib.h -- */
+int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+                       a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
+    gzFile file;
+    const char *format;
+    int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+        a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
+{
+    unsigned len, left;
+    char *next;
+    gz_statep state;
+    z_streamp strm;
+
+    /* get internal structure */
+    if (file == NULL)
+        return Z_STREAM_ERROR;
+    state = (gz_statep)file;
+    strm = &(state->strm);
+
+    /* check that can really pass pointer in ints */
+    if (sizeof(int) != sizeof(void *))
+        return Z_STREAM_ERROR;
+
+    /* check that we're writing and that there's no error */
+    if (state->mode != GZ_WRITE || state->err != Z_OK)
+        return Z_STREAM_ERROR;
+
+    /* make sure we have some buffer space */
+    if (state->size == 0 && gz_init(state) == -1)
+        return state->error;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_zero(state, state->skip) == -1)
+            return state->error;
+    }
+
+    /* do the printf() into the input buffer, put length in len -- the input
+       buffer is double-sized just for this function, so there is guaranteed to
+       be state->size bytes available after the current contents */
+    if (strm->avail_in == 0)
+        strm->next_in = state->in;
+    next = (char *)(strm->next_in + strm->avail_in);
+    next[state->size - 1] = 0;
+#ifdef NO_snprintf
+#  ifdef HAS_sprintf_void
+    sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12,
+            a13, a14, a15, a16, a17, a18, a19, a20);
+    for (len = 0; len < size; len++)
+        if (next[len] == 0)
+            break;
+#  else
+    len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11,
+                  a12, a13, a14, a15, a16, a17, a18, a19, a20);
+#  endif
+#else
+#  ifdef HAS_snprintf_void
+    snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9,
+             a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+    len = strlen(next);
+#  else
+    len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8,
+                   a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+#  endif
+#endif
+
+    /* check that printf() results fit in buffer */
+    if (len == 0 || len >= state->size || next[state->size - 1] != 0)
+        return 0;
+
+    /* update buffer and position, compress first half if past that */
+    strm->avail_in += len;
+    state->x.pos += len;
+    if (strm->avail_in >= state->size) {
+        left = strm->avail_in - state->size;
+        strm->avail_in = state->size;
+        if (gz_comp(state, Z_NO_FLUSH) == -1)
+            return state->err;
+        memcpy(state->in, state->in + state->size, left);
+        strm->next_in = state->in;
+        strm->avail_in = left;
+    }
+    return (int)len;
+}
+
+#endif
+
+/* -- see zlib.h -- */
+int ZEXPORT gzflush(file, flush)
+    gzFile file;
+    int flush;
+{
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return Z_STREAM_ERROR;
+    state = (gz_statep)file;
+
+    /* check that we're writing and that there's no error */
+    if (state->mode != GZ_WRITE || state->err != Z_OK)
+        return Z_STREAM_ERROR;
+
+    /* check flush parameter */
+    if (flush < 0 || flush > Z_FINISH)
+        return Z_STREAM_ERROR;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_zero(state, state->skip) == -1)
+            return state->err;
+    }
+
+    /* compress remaining data with requested flush */
+    (void)gz_comp(state, flush);
+    return state->err;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzsetparams(file, level, strategy)
+    gzFile file;
+    int level;
+    int strategy;
+{
+    gz_statep state;
+    z_streamp strm;
+
+    /* get internal structure */
+    if (file == NULL)
+        return Z_STREAM_ERROR;
+    state = (gz_statep)file;
+    strm = &(state->strm);
+
+    /* check that we're writing and that there's no error */
+    if (state->mode != GZ_WRITE || state->err != Z_OK)
+        return Z_STREAM_ERROR;
+
+    /* if no change is requested, then do nothing */
+    if (level == state->level && strategy == state->strategy)
+        return Z_OK;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_zero(state, state->skip) == -1)
+            return state->err;
+    }
+
+    /* change compression parameters for subsequent input */
+    if (state->size) {
+        /* flush previous input with previous parameters before changing */
+        if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1)
+            return state->err;
+        deflateParams(strm, level, strategy);
+    }
+    state->level = level;
+    state->strategy = strategy;
+    return Z_OK;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzclose_w(file)
+    gzFile file;
+{
+    int ret = Z_OK;
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return Z_STREAM_ERROR;
+    state = (gz_statep)file;
+
+    /* check that we're writing */
+    if (state->mode != GZ_WRITE)
+        return Z_STREAM_ERROR;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_zero(state, state->skip) == -1)
+            ret = state->err;
+    }
+
+    /* flush, free memory, and close file */
+    if (gz_comp(state, Z_FINISH) == -1)
+        ret = state->err;
+    if (state->size) {
+        if (!state->direct) {
+            (void)deflateEnd(&(state->strm));
+            free(state->out);
+        }
+        free(state->in);
+    }
+    gz_error(state, Z_OK, NULL);
+    free(state->path);
+    if (close(state->fd) == -1)
+        ret = Z_ERRNO;
+    free(state);
+    return ret;
+}
Index: EcnlProtoTool/trunk/zlib-1.2.11/infback.c
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/infback.c	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/infback.c	(revision 331)
@@ -0,0 +1,640 @@
+/* infback.c -- inflate using a call-back interface
+ * Copyright (C) 1995-2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+   This code is largely copied from inflate.c.  Normally either infback.o or
+   inflate.o would be linked into an application--not both.  The interface
+   with inffast.c is retained so that optimized assembler-coded versions of
+   inflate_fast() can be used with either inflate.c or infback.c.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+
+/*
+   strm provides memory allocation functions in zalloc and zfree, or
+   Z_NULL to use the library memory allocation functions.
+
+   windowBits is in the range 8..15, and window is a user-supplied
+   window and output buffer that is 2**windowBits bytes.
+ */
+int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
+z_streamp strm;
+int windowBits;
+unsigned char FAR *window;
+const char *version;
+int stream_size;
+{
+    struct inflate_state FAR *state;
+
+    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+        stream_size != (int)(sizeof(z_stream)))
+        return Z_VERSION_ERROR;
+    if (strm == Z_NULL || window == Z_NULL ||
+        windowBits < 8 || windowBits > 15)
+        return Z_STREAM_ERROR;
+    strm->msg = Z_NULL;                 /* in case we return an error */
+    if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+        return Z_STREAM_ERROR;
+#else
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+#endif
+    }
+    if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+        return Z_STREAM_ERROR;
+#else
+    strm->zfree = zcfree;
+#endif
+    state = (struct inflate_state FAR *)ZALLOC(strm, 1,
+                                               sizeof(struct inflate_state));
+    if (state == Z_NULL) return Z_MEM_ERROR;
+    Tracev((stderr, "inflate: allocated\n"));
+    strm->state = (struct internal_state FAR *)state;
+    state->dmax = 32768U;
+    state->wbits = (uInt)windowBits;
+    state->wsize = 1U << windowBits;
+    state->window = window;
+    state->wnext = 0;
+    state->whave = 0;
+    return Z_OK;
+}
+
+/*
+   Return state with length and distance decoding tables and index sizes set to
+   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
+   If BUILDFIXED is defined, then instead this routine builds the tables the
+   first time it's called, and returns those tables the first time and
+   thereafter.  This reduces the size of the code by about 2K bytes, in
+   exchange for a little execution time.  However, BUILDFIXED should not be
+   used for threaded applications, since the rewriting of the tables and virgin
+   may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+    static int virgin = 1;
+    static code *lenfix, *distfix;
+    static code fixed[544];
+
+    /* build fixed huffman tables if first call (may not be thread safe) */
+    if (virgin) {
+        unsigned sym, bits;
+        static code *next;
+
+        /* literal/length table */
+        sym = 0;
+        while (sym < 144) state->lens[sym++] = 8;
+        while (sym < 256) state->lens[sym++] = 9;
+        while (sym < 280) state->lens[sym++] = 7;
+        while (sym < 288) state->lens[sym++] = 8;
+        next = fixed;
+        lenfix = next;
+        bits = 9;
+        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+        /* distance table */
+        sym = 0;
+        while (sym < 32) state->lens[sym++] = 5;
+        distfix = next;
+        bits = 5;
+        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+        /* do this just once */
+        virgin = 0;
+    }
+#else /* !BUILDFIXED */
+#   include "inffixed.h"
+#endif /* BUILDFIXED */
+    state->lencode = lenfix;
+    state->lenbits = 9;
+    state->distcode = distfix;
+    state->distbits = 5;
+}
+
+/* Macros for inflateBack(): */
+
+/* Load returned state from inflate_fast() */
+#define LOAD() \
+    do { \
+        put = strm->next_out; \
+        left = strm->avail_out; \
+        next = strm->next_in; \
+        have = strm->avail_in; \
+        hold = state->hold; \
+        bits = state->bits; \
+    } while (0)
+
+/* Set state from registers for inflate_fast() */
+#define RESTORE() \
+    do { \
+        strm->next_out = put; \
+        strm->avail_out = left; \
+        strm->next_in = next; \
+        strm->avail_in = have; \
+        state->hold = hold; \
+        state->bits = bits; \
+    } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+    do { \
+        hold = 0; \
+        bits = 0; \
+    } while (0)
+
+/* Assure that some input is available.  If input is requested, but denied,
+   then return a Z_BUF_ERROR from inflateBack(). */
+#define PULL() \
+    do { \
+        if (have == 0) { \
+            have = in(in_desc, &next); \
+            if (have == 0) { \
+                next = Z_NULL; \
+                ret = Z_BUF_ERROR; \
+                goto inf_leave; \
+            } \
+        } \
+    } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflateBack()
+   with an error if there is no input available. */
+#define PULLBYTE() \
+    do { \
+        PULL(); \
+        have--; \
+        hold += (unsigned long)(*next++) << bits; \
+        bits += 8; \
+    } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator.  If there is
+   not enough available input to do that, then return from inflateBack() with
+   an error. */
+#define NEEDBITS(n) \
+    do { \
+        while (bits < (unsigned)(n)) \
+            PULLBYTE(); \
+    } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+    ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+    do { \
+        hold >>= (n); \
+        bits -= (unsigned)(n); \
+    } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+    do { \
+        hold >>= bits & 7; \
+        bits -= bits & 7; \
+    } while (0)
+
+/* Assure that some output space is available, by writing out the window
+   if it's full.  If the write fails, return from inflateBack() with a
+   Z_BUF_ERROR. */
+#define ROOM() \
+    do { \
+        if (left == 0) { \
+            put = state->window; \
+            left = state->wsize; \
+            state->whave = left; \
+            if (out(out_desc, put, left)) { \
+                ret = Z_BUF_ERROR; \
+                goto inf_leave; \
+            } \
+        } \
+    } while (0)
+
+/*
+   strm provides the memory allocation functions and window buffer on input,
+   and provides information on the unused input on return.  For Z_DATA_ERROR
+   returns, strm will also provide an error message.
+
+   in() and out() are the call-back input and output functions.  When
+   inflateBack() needs more input, it calls in().  When inflateBack() has
+   filled the window with output, or when it completes with data in the
+   window, it calls out() to write out the data.  The application must not
+   change the provided input until in() is called again or inflateBack()
+   returns.  The application must not change the window/output buffer until
+   inflateBack() returns.
+
+   in() and out() are called with a descriptor parameter provided in the
+   inflateBack() call.  This parameter can be a structure that provides the
+   information required to do the read or write, as well as accumulated
+   information on the input and output such as totals and check values.
+
+   in() should return zero on failure.  out() should return non-zero on
+   failure.  If either in() or out() fails, than inflateBack() returns a
+   Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it
+   was in() or out() that caused in the error.  Otherwise,  inflateBack()
+   returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
+   error, or Z_MEM_ERROR if it could not allocate memory for the state.
+   inflateBack() can also return Z_STREAM_ERROR if the input parameters
+   are not correct, i.e. strm is Z_NULL or the state was not initialized.
+ */
+int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
+z_streamp strm;
+in_func in;
+void FAR *in_desc;
+out_func out;
+void FAR *out_desc;
+{
+    struct inflate_state FAR *state;
+    z_const unsigned char FAR *next;    /* next input */
+    unsigned char FAR *put;     /* next output */
+    unsigned have, left;        /* available input and output */
+    unsigned long hold;         /* bit buffer */
+    unsigned bits;              /* bits in bit buffer */
+    unsigned copy;              /* number of stored or match bytes to copy */
+    unsigned char FAR *from;    /* where to copy match bytes from */
+    code here;                  /* current decoding table entry */
+    code last;                  /* parent table entry */
+    unsigned len;               /* length to copy for repeats, bits to drop */
+    int ret;                    /* return code */
+    static const unsigned short order[19] = /* permutation of code lengths */
+        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+    /* Check that the strm exists and that the state was initialized */
+    if (strm == Z_NULL || strm->state == Z_NULL)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* Reset the state */
+    strm->msg = Z_NULL;
+    state->mode = TYPE;
+    state->last = 0;
+    state->whave = 0;
+    next = strm->next_in;
+    have = next != Z_NULL ? strm->avail_in : 0;
+    hold = 0;
+    bits = 0;
+    put = state->window;
+    left = state->wsize;
+
+    /* Inflate until end of block marked as last */
+    for (;;)
+        switch (state->mode) {
+        case TYPE:
+            /* determine and dispatch block type */
+            if (state->last) {
+                BYTEBITS();
+                state->mode = DONE;
+                break;
+            }
+            NEEDBITS(3);
+            state->last = BITS(1);
+            DROPBITS(1);
+            switch (BITS(2)) {
+            case 0:                             /* stored block */
+                Tracev((stderr, "inflate:     stored block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = STORED;
+                break;
+            case 1:                             /* fixed block */
+                fixedtables(state);
+                Tracev((stderr, "inflate:     fixed codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = LEN;              /* decode codes */
+                break;
+            case 2:                             /* dynamic block */
+                Tracev((stderr, "inflate:     dynamic codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = TABLE;
+                break;
+            case 3:
+                strm->msg = (char *)"invalid block type";
+                state->mode = BAD;
+            }
+            DROPBITS(2);
+            break;
+
+        case STORED:
+            /* get and verify stored block length */
+            BYTEBITS();                         /* go to byte boundary */
+            NEEDBITS(32);
+            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+                strm->msg = (char *)"invalid stored block lengths";
+                state->mode = BAD;
+                break;
+            }
+            state->length = (unsigned)hold & 0xffff;
+            Tracev((stderr, "inflate:       stored length %u\n",
+                    state->length));
+            INITBITS();
+
+            /* copy stored block from input to output */
+            while (state->length != 0) {
+                copy = state->length;
+                PULL();
+                ROOM();
+                if (copy > have) copy = have;
+                if (copy > left) copy = left;
+                zmemcpy(put, next, copy);
+                have -= copy;
+                next += copy;
+                left -= copy;
+                put += copy;
+                state->length -= copy;
+            }
+            Tracev((stderr, "inflate:       stored end\n"));
+            state->mode = TYPE;
+            break;
+
+        case TABLE:
+            /* get dynamic table entries descriptor */
+            NEEDBITS(14);
+            state->nlen = BITS(5) + 257;
+            DROPBITS(5);
+            state->ndist = BITS(5) + 1;
+            DROPBITS(5);
+            state->ncode = BITS(4) + 4;
+            DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+            if (state->nlen > 286 || state->ndist > 30) {
+                strm->msg = (char *)"too many length or distance symbols";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            Tracev((stderr, "inflate:       table sizes ok\n"));
+
+            /* get code length code lengths (not a typo) */
+            state->have = 0;
+            while (state->have < state->ncode) {
+                NEEDBITS(3);
+                state->lens[order[state->have++]] = (unsigned short)BITS(3);
+                DROPBITS(3);
+            }
+            while (state->have < 19)
+                state->lens[order[state->have++]] = 0;
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 7;
+            ret = inflate_table(CODES, state->lens, 19, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid code lengths set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       code lengths ok\n"));
+
+            /* get length and distance code code lengths */
+            state->have = 0;
+            while (state->have < state->nlen + state->ndist) {
+                for (;;) {
+                    here = state->lencode[BITS(state->lenbits)];
+                    if ((unsigned)(here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                if (here.val < 16) {
+                    DROPBITS(here.bits);
+                    state->lens[state->have++] = here.val;
+                }
+                else {
+                    if (here.val == 16) {
+                        NEEDBITS(here.bits + 2);
+                        DROPBITS(here.bits);
+                        if (state->have == 0) {
+                            strm->msg = (char *)"invalid bit length repeat";
+                            state->mode = BAD;
+                            break;
+                        }
+                        len = (unsigned)(state->lens[state->have - 1]);
+                        copy = 3 + BITS(2);
+                        DROPBITS(2);
+                    }
+                    else if (here.val == 17) {
+                        NEEDBITS(here.bits + 3);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 3 + BITS(3);
+                        DROPBITS(3);
+                    }
+                    else {
+                        NEEDBITS(here.bits + 7);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 11 + BITS(7);
+                        DROPBITS(7);
+                    }
+                    if (state->have + copy > state->nlen + state->ndist) {
+                        strm->msg = (char *)"invalid bit length repeat";
+                        state->mode = BAD;
+                        break;
+                    }
+                    while (copy--)
+                        state->lens[state->have++] = (unsigned short)len;
+                }
+            }
+
+            /* handle error breaks in while */
+            if (state->mode == BAD) break;
+
+            /* check for end-of-block code (better have one) */
+            if (state->lens[256] == 0) {
+                strm->msg = (char *)"invalid code -- missing end-of-block";
+                state->mode = BAD;
+                break;
+            }
+
+            /* build code tables -- note: do not change the lenbits or distbits
+               values here (9 and 6) without reading the comments in inftrees.h
+               concerning the ENOUGH constants, which depend on those values */
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 9;
+            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid literal/lengths set";
+                state->mode = BAD;
+                break;
+            }
+            state->distcode = (code const FAR *)(state->next);
+            state->distbits = 6;
+            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+                            &(state->next), &(state->distbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid distances set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       codes ok\n"));
+            state->mode = LEN;
+
+        case LEN:
+            /* use inflate_fast() if we have enough input and output */
+            if (have >= 6 && left >= 258) {
+                RESTORE();
+                if (state->whave < state->wsize)
+                    state->whave = state->wsize - left;
+                inflate_fast(strm, state->wsize);
+                LOAD();
+                break;
+            }
+
+            /* get a literal, length, or end-of-block code */
+            for (;;) {
+                here = state->lencode[BITS(state->lenbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if (here.op && (here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = state->lencode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(here.bits);
+            state->length = (unsigned)here.val;
+
+            /* process literal */
+            if (here.op == 0) {
+                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+                        "inflate:         literal '%c'\n" :
+                        "inflate:         literal 0x%02x\n", here.val));
+                ROOM();
+                *put++ = (unsigned char)(state->length);
+                left--;
+                state->mode = LEN;
+                break;
+            }
+
+            /* process end of block */
+            if (here.op & 32) {
+                Tracevv((stderr, "inflate:         end of block\n"));
+                state->mode = TYPE;
+                break;
+            }
+
+            /* invalid code */
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid literal/length code";
+                state->mode = BAD;
+                break;
+            }
+
+            /* length code -- get extra bits, if any */
+            state->extra = (unsigned)(here.op) & 15;
+            if (state->extra != 0) {
+                NEEDBITS(state->extra);
+                state->length += BITS(state->extra);
+                DROPBITS(state->extra);
+            }
+            Tracevv((stderr, "inflate:         length %u\n", state->length));
+
+            /* get distance code */
+            for (;;) {
+                here = state->distcode[BITS(state->distbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if ((here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = state->distcode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(here.bits);
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+            state->offset = (unsigned)here.val;
+
+            /* get distance extra bits, if any */
+            state->extra = (unsigned)(here.op) & 15;
+            if (state->extra != 0) {
+                NEEDBITS(state->extra);
+                state->offset += BITS(state->extra);
+                DROPBITS(state->extra);
+            }
+            if (state->offset > state->wsize - (state->whave < state->wsize ?
+                                                left : 0)) {
+                strm->msg = (char *)"invalid distance too far back";
+                state->mode = BAD;
+                break;
+            }
+            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
+
+            /* copy match from window to output */
+            do {
+                ROOM();
+                copy = state->wsize - state->offset;
+                if (copy < left) {
+                    from = put + copy;
+                    copy = left - copy;
+                }
+                else {
+                    from = put - state->offset;
+                    copy = left;
+                }
+                if (copy > state->length) copy = state->length;
+                state->length -= copy;
+                left -= copy;
+                do {
+                    *put++ = *from++;
+                } while (--copy);
+            } while (state->length != 0);
+            break;
+
+        case DONE:
+            /* inflate stream terminated properly -- write leftover output */
+            ret = Z_STREAM_END;
+            if (left < state->wsize) {
+                if (out(out_desc, state->window, state->wsize - left))
+                    ret = Z_BUF_ERROR;
+            }
+            goto inf_leave;
+
+        case BAD:
+            ret = Z_DATA_ERROR;
+            goto inf_leave;
+
+        default:                /* can't happen, but makes compilers happy */
+            ret = Z_STREAM_ERROR;
+            goto inf_leave;
+        }
+
+    /* Return unused input */
+  inf_leave:
+    strm->next_in = next;
+    strm->avail_in = have;
+    return ret;
+}
+
+int ZEXPORT inflateBackEnd(strm)
+z_streamp strm;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+    Tracev((stderr, "inflate: end\n"));
+    return Z_OK;
+}
Index: EcnlProtoTool/trunk/zlib-1.2.11/inffast.c
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/inffast.c	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/inffast.c	(revision 331)
@@ -0,0 +1,323 @@
+/* inffast.c -- fast decoding
+ * Copyright (C) 1995-2017 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifdef ASMINF
+#  pragma message("Assembler code may have bugs -- use at your own risk")
+#else
+
+/*
+   Decode literal, length, and distance codes and write out the resulting
+   literal and match bytes until either not enough input or output is
+   available, an end-of-block is encountered, or a data error is encountered.
+   When large enough input and output buffers are supplied to inflate(), for
+   example, a 16K input buffer and a 64K output buffer, more than 95% of the
+   inflate execution time is spent in this routine.
+
+   Entry assumptions:
+
+        state->mode == LEN
+        strm->avail_in >= 6
+        strm->avail_out >= 258
+        start >= strm->avail_out
+        state->bits < 8
+
+   On return, state->mode is one of:
+
+        LEN -- ran out of enough output space or enough available input
+        TYPE -- reached end of block code, inflate() to interpret next block
+        BAD -- error in block data
+
+   Notes:
+
+    - The maximum input bits used by a length/distance pair is 15 bits for the
+      length code, 5 bits for the length extra, 15 bits for the distance code,
+      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
+      Therefore if strm->avail_in >= 6, then there is enough input to avoid
+      checking for available input while decoding.
+
+    - The maximum bytes that a single length/distance pair can output is 258
+      bytes, which is the maximum length that can be coded.  inflate_fast()
+      requires strm->avail_out >= 258 for each loop to avoid checking for
+      output space.
+ */
+void ZLIB_INTERNAL inflate_fast(strm, start)
+z_streamp strm;
+unsigned start;         /* inflate()'s starting value for strm->avail_out */
+{
+    struct inflate_state FAR *state;
+    z_const unsigned char FAR *in;      /* local strm->next_in */
+    z_const unsigned char FAR *last;    /* have enough input while in < last */
+    unsigned char FAR *out;     /* local strm->next_out */
+    unsigned char FAR *beg;     /* inflate()'s initial strm->next_out */
+    unsigned char FAR *end;     /* while out < end, enough space available */
+#ifdef INFLATE_STRICT
+    unsigned dmax;              /* maximum distance from zlib header */
+#endif
+    unsigned wsize;             /* window size or zero if not using window */
+    unsigned whave;             /* valid bytes in the window */
+    unsigned wnext;             /* window write index */
+    unsigned char FAR *window;  /* allocated sliding window, if wsize != 0 */
+    unsigned long hold;         /* local strm->hold */
+    unsigned bits;              /* local strm->bits */
+    code const FAR *lcode;      /* local strm->lencode */
+    code const FAR *dcode;      /* local strm->distcode */
+    unsigned lmask;             /* mask for first level of length codes */
+    unsigned dmask;             /* mask for first level of distance codes */
+    code here;                  /* retrieved table entry */
+    unsigned op;                /* code bits, operation, extra bits, or */
+                                /*  window position, window bytes to copy */
+    unsigned len;               /* match length, unused bytes */
+    unsigned dist;              /* match distance */
+    unsigned char FAR *from;    /* where to copy match from */
+
+    /* copy state to local variables */
+    state = (struct inflate_state FAR *)strm->state;
+    in = strm->next_in;
+    last = in + (strm->avail_in - 5);
+    out = strm->next_out;
+    beg = out - (start - strm->avail_out);
+    end = out + (strm->avail_out - 257);
+#ifdef INFLATE_STRICT
+    dmax = state->dmax;
+#endif
+    wsize = state->wsize;
+    whave = state->whave;
+    wnext = state->wnext;
+    window = state->window;
+    hold = state->hold;
+    bits = state->bits;
+    lcode = state->lencode;
+    dcode = state->distcode;
+    lmask = (1U << state->lenbits) - 1;
+    dmask = (1U << state->distbits) - 1;
+
+    /* decode literals and length/distances until end-of-block or not enough
+       input data or output space */
+    do {
+        if (bits < 15) {
+            hold += (unsigned long)(*in++) << bits;
+            bits += 8;
+            hold += (unsigned long)(*in++) << bits;
+            bits += 8;
+        }
+        here = lcode[hold & lmask];
+      dolen:
+        op = (unsigned)(here.bits);
+        hold >>= op;
+        bits -= op;
+        op = (unsigned)(here.op);
+        if (op == 0) {                          /* literal */
+            Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+                    "inflate:         literal '%c'\n" :
+                    "inflate:         literal 0x%02x\n", here.val));
+            *out++ = (unsigned char)(here.val);
+        }
+        else if (op & 16) {                     /* length base */
+            len = (unsigned)(here.val);
+            op &= 15;                           /* number of extra bits */
+            if (op) {
+                if (bits < op) {
+                    hold += (unsigned long)(*in++) << bits;
+                    bits += 8;
+                }
+                len += (unsigned)hold & ((1U << op) - 1);
+                hold >>= op;
+                bits -= op;
+            }
+            Tracevv((stderr, "inflate:         length %u\n", len));
+            if (bits < 15) {
+                hold += (unsigned long)(*in++) << bits;
+                bits += 8;
+                hold += (unsigned long)(*in++) << bits;
+                bits += 8;
+            }
+            here = dcode[hold & dmask];
+          dodist:
+            op = (unsigned)(here.bits);
+            hold >>= op;
+            bits -= op;
+            op = (unsigned)(here.op);
+            if (op & 16) {                      /* distance base */
+                dist = (unsigned)(here.val);
+                op &= 15;                       /* number of extra bits */
+                if (bits < op) {
+                    hold += (unsigned long)(*in++) << bits;
+                    bits += 8;
+                    if (bits < op) {
+                        hold += (unsigned long)(*in++) << bits;
+                        bits += 8;
+                    }
+                }
+                dist += (unsigned)hold & ((1U << op) - 1);
+#ifdef INFLATE_STRICT
+                if (dist > dmax) {
+                    strm->msg = (char *)"invalid distance too far back";
+                    state->mode = BAD;
+                    break;
+                }
+#endif
+                hold >>= op;
+                bits -= op;
+                Tracevv((stderr, "inflate:         distance %u\n", dist));
+                op = (unsigned)(out - beg);     /* max distance in output */
+                if (dist > op) {                /* see if copy from window */
+                    op = dist - op;             /* distance back in window */
+                    if (op > whave) {
+                        if (state->sane) {
+                            strm->msg =
+                                (char *)"invalid distance too far back";
+                            state->mode = BAD;
+                            break;
+                        }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+                        if (len <= op - whave) {
+                            do {
+                                *out++ = 0;
+                            } while (--len);
+                            continue;
+                        }
+                        len -= op - whave;
+                        do {
+                            *out++ = 0;
+                        } while (--op > whave);
+                        if (op == 0) {
+                            from = out - dist;
+                            do {
+                                *out++ = *from++;
+                            } while (--len);
+                            continue;
+                        }
+#endif
+                    }
+                    from = window;
+                    if (wnext == 0) {           /* very common case */
+                        from += wsize - op;
+                        if (op < len) {         /* some from window */
+                            len -= op;
+                            do {
+                                *out++ = *from++;
+                            } while (--op);
+                            from = out - dist;  /* rest from output */
+                        }
+                    }
+                    else if (wnext < op) {      /* wrap around window */
+                        from += wsize + wnext - op;
+                        op -= wnext;
+                        if (op < len) {         /* some from end of window */
+                            len -= op;
+                            do {
+                                *out++ = *from++;
+                            } while (--op);
+                            from = window;
+                            if (wnext < len) {  /* some from start of window */
+                                op = wnext;
+                                len -= op;
+                                do {
+                                    *out++ = *from++;
+                                } while (--op);
+                                from = out - dist;      /* rest from output */
+                            }
+                        }
+                    }
+                    else {                      /* contiguous in window */
+                        from += wnext - op;
+                        if (op < len) {         /* some from window */
+                            len -= op;
+                            do {
+                                *out++ = *from++;
+                            } while (--op);
+                            from = out - dist;  /* rest from output */
+                        }
+                    }
+                    while (len > 2) {
+                        *out++ = *from++;
+                        *out++ = *from++;
+                        *out++ = *from++;
+                        len -= 3;
+                    }
+                    if (len) {
+                        *out++ = *from++;
+                        if (len > 1)
+                            *out++ = *from++;
+                    }
+                }
+                else {
+                    from = out - dist;          /* copy direct from output */
+                    do {                        /* minimum length is three */
+                        *out++ = *from++;
+                        *out++ = *from++;
+                        *out++ = *from++;
+                        len -= 3;
+                    } while (len > 2);
+                    if (len) {
+                        *out++ = *from++;
+                        if (len > 1)
+                            *out++ = *from++;
+                    }
+                }
+            }
+            else if ((op & 64) == 0) {          /* 2nd level distance code */
+                here = dcode[here.val + (hold & ((1U << op) - 1))];
+                goto dodist;
+            }
+            else {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+        }
+        else if ((op & 64) == 0) {              /* 2nd level length code */
+            here = lcode[here.val + (hold & ((1U << op) - 1))];
+            goto dolen;
+        }
+        else if (op & 32) {                     /* end-of-block */
+            Tracevv((stderr, "inflate:         end of block\n"));
+            state->mode = TYPE;
+            break;
+        }
+        else {
+            strm->msg = (char *)"invalid literal/length code";
+            state->mode = BAD;
+            break;
+        }
+    } while (in < last && out < end);
+
+    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+    len = bits >> 3;
+    in -= len;
+    bits -= len << 3;
+    hold &= (1U << bits) - 1;
+
+    /* update state and return */
+    strm->next_in = in;
+    strm->next_out = out;
+    strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
+    strm->avail_out = (unsigned)(out < end ?
+                                 257 + (end - out) : 257 - (out - end));
+    state->hold = hold;
+    state->bits = bits;
+    return;
+}
+
+/*
+   inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
+   - Using bit fields for code structure
+   - Different op definition to avoid & for extra bits (do & for table bits)
+   - Three separate decoding do-loops for direct, window, and wnext == 0
+   - Special case for distance > 1 copies to do overlapped load and store copy
+   - Explicit branch predictions (based on measured branch probabilities)
+   - Deferring match copy and interspersed it with decoding subsequent codes
+   - Swapping literal/length else
+   - Swapping window/direct else
+   - Larger unrolled copy loops (three is about right)
+   - Moving len -= 3 statement into middle of loop
+ */
+
+#endif /* !ASMINF */
Index: EcnlProtoTool/trunk/zlib-1.2.11/inffast.h
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/inffast.h	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/inffast.h	(revision 331)
@@ -0,0 +1,11 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2003, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
Index: EcnlProtoTool/trunk/zlib-1.2.11/inffixed.h
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/inffixed.h	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/inffixed.h	(revision 331)
@@ -0,0 +1,94 @@
+    /* inffixed.h -- table for decoding fixed codes
+     * Generated automatically by makefixed().
+     */
+
+    /* WARNING: this file should *not* be used by applications.
+       It is part of the implementation of this library and is
+       subject to change. Applications should only use zlib.h.
+     */
+
+    static const code lenfix[512] = {
+        {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
+        {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
+        {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
+        {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
+        {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
+        {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
+        {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
+        {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
+        {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
+        {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
+        {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
+        {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
+        {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
+        {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
+        {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
+        {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
+        {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
+        {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+        {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
+        {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
+        {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
+        {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
+        {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
+        {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
+        {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
+        {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
+        {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
+        {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
+        {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
+        {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
+        {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
+        {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
+        {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
+        {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
+        {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
+        {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
+        {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
+        {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
+        {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
+        {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
+        {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
+        {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
+        {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
+        {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
+        {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
+        {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
+        {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
+        {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+        {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
+        {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
+        {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
+        {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
+        {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
+        {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
+        {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
+        {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
+        {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
+        {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
+        {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
+        {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
+        {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
+        {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
+        {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
+        {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
+        {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
+        {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+        {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
+        {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
+        {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
+        {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
+        {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
+        {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
+        {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
+        {0,9,255}
+    };
+
+    static const code distfix[32] = {
+        {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
+        {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
+        {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
+        {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
+        {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
+        {22,5,193},{64,5,0}
+    };
Index: EcnlProtoTool/trunk/zlib-1.2.11/inflate.c
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/inflate.c	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/inflate.c	(revision 331)
@@ -0,0 +1,1561 @@
+/* inflate.c -- zlib decompression
+ * Copyright (C) 1995-2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * Change history:
+ *
+ * 1.2.beta0    24 Nov 2002
+ * - First version -- complete rewrite of inflate to simplify code, avoid
+ *   creation of window when not needed, minimize use of window when it is
+ *   needed, make inffast.c even faster, implement gzip decoding, and to
+ *   improve code readability and style over the previous zlib inflate code
+ *
+ * 1.2.beta1    25 Nov 2002
+ * - Use pointers for available input and output checking in inffast.c
+ * - Remove input and output counters in inffast.c
+ * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
+ * - Remove unnecessary second byte pull from length extra in inffast.c
+ * - Unroll direct copy to three copies per loop in inffast.c
+ *
+ * 1.2.beta2    4 Dec 2002
+ * - Change external routine names to reduce potential conflicts
+ * - Correct filename to inffixed.h for fixed tables in inflate.c
+ * - Make hbuf[] unsigned char to match parameter type in inflate.c
+ * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
+ *   to avoid negation problem on Alphas (64 bit) in inflate.c
+ *
+ * 1.2.beta3    22 Dec 2002
+ * - Add comments on state->bits assertion in inffast.c
+ * - Add comments on op field in inftrees.h
+ * - Fix bug in reuse of allocated window after inflateReset()
+ * - Remove bit fields--back to byte structure for speed
+ * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
+ * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
+ * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
+ * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
+ * - Use local copies of stream next and avail values, as well as local bit
+ *   buffer and bit count in inflate()--for speed when inflate_fast() not used
+ *
+ * 1.2.beta4    1 Jan 2003
+ * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
+ * - Move a comment on output buffer sizes from inffast.c to inflate.c
+ * - Add comments in inffast.c to introduce the inflate_fast() routine
+ * - Rearrange window copies in inflate_fast() for speed and simplification
+ * - Unroll last copy for window match in inflate_fast()
+ * - Use local copies of window variables in inflate_fast() for speed
+ * - Pull out common wnext == 0 case for speed in inflate_fast()
+ * - Make op and len in inflate_fast() unsigned for consistency
+ * - Add FAR to lcode and dcode declarations in inflate_fast()
+ * - Simplified bad distance check in inflate_fast()
+ * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
+ *   source file infback.c to provide a call-back interface to inflate for
+ *   programs like gzip and unzip -- uses window as output buffer to avoid
+ *   window copying
+ *
+ * 1.2.beta5    1 Jan 2003
+ * - Improved inflateBack() interface to allow the caller to provide initial
+ *   input in strm.
+ * - Fixed stored blocks bug in inflateBack()
+ *
+ * 1.2.beta6    4 Jan 2003
+ * - Added comments in inffast.c on effectiveness of POSTINC
+ * - Typecasting all around to reduce compiler warnings
+ * - Changed loops from while (1) or do {} while (1) to for (;;), again to
+ *   make compilers happy
+ * - Changed type of window in inflateBackInit() to unsigned char *
+ *
+ * 1.2.beta7    27 Jan 2003
+ * - Changed many types to unsigned or unsigned short to avoid warnings
+ * - Added inflateCopy() function
+ *
+ * 1.2.0        9 Mar 2003
+ * - Changed inflateBack() interface to provide separate opaque descriptors
+ *   for the in() and out() functions
+ * - Changed inflateBack() argument and in_func typedef to swap the length
+ *   and buffer address return values for the input function
+ * - Check next_in and next_out for Z_NULL on entry to inflate()
+ *
+ * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifdef MAKEFIXED
+#  ifndef BUILDFIXED
+#    define BUILDFIXED
+#  endif
+#endif
+
+/* function prototypes */
+local int inflateStateCheck OF((z_streamp strm));
+local void fixedtables OF((struct inflate_state FAR *state));
+local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
+                           unsigned copy));
+#ifdef BUILDFIXED
+   void makefixed OF((void));
+#endif
+local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
+                              unsigned len));
+
+local int inflateStateCheck(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+    if (strm == Z_NULL ||
+        strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
+        return 1;
+    state = (struct inflate_state FAR *)strm->state;
+    if (state == Z_NULL || state->strm != strm ||
+        state->mode < HEAD || state->mode > SYNC)
+        return 1;
+    return 0;
+}
+
+int ZEXPORT inflateResetKeep(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    strm->total_in = strm->total_out = state->total = 0;
+    strm->msg = Z_NULL;
+    if (state->wrap)        /* to support ill-conceived Java test suite */
+        strm->adler = state->wrap & 1;
+    state->mode = HEAD;
+    state->last = 0;
+    state->havedict = 0;
+    state->dmax = 32768U;
+    state->head = Z_NULL;
+    state->hold = 0;
+    state->bits = 0;
+    state->lencode = state->distcode = state->next = state->codes;
+    state->sane = 1;
+    state->back = -1;
+    Tracev((stderr, "inflate: reset\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateReset(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    state->wsize = 0;
+    state->whave = 0;
+    state->wnext = 0;
+    return inflateResetKeep(strm);
+}
+
+int ZEXPORT inflateReset2(strm, windowBits)
+z_streamp strm;
+int windowBits;
+{
+    int wrap;
+    struct inflate_state FAR *state;
+
+    /* get the state */
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* extract wrap request from windowBits parameter */
+    if (windowBits < 0) {
+        wrap = 0;
+        windowBits = -windowBits;
+    }
+    else {
+        wrap = (windowBits >> 4) + 5;
+#ifdef GUNZIP
+        if (windowBits < 48)
+            windowBits &= 15;
+#endif
+    }
+
+    /* set number of window bits, free window if different */
+    if (windowBits && (windowBits < 8 || windowBits > 15))
+        return Z_STREAM_ERROR;
+    if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
+        ZFREE(strm, state->window);
+        state->window = Z_NULL;
+    }
+
+    /* update state and reset the rest of it */
+    state->wrap = wrap;
+    state->wbits = (unsigned)windowBits;
+    return inflateReset(strm);
+}
+
+int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
+z_streamp strm;
+int windowBits;
+const char *version;
+int stream_size;
+{
+    int ret;
+    struct inflate_state FAR *state;
+
+    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+        stream_size != (int)(sizeof(z_stream)))
+        return Z_VERSION_ERROR;
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+    strm->msg = Z_NULL;                 /* in case we return an error */
+    if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+        return Z_STREAM_ERROR;
+#else
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+#endif
+    }
+    if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+        return Z_STREAM_ERROR;
+#else
+        strm->zfree = zcfree;
+#endif
+    state = (struct inflate_state FAR *)
+            ZALLOC(strm, 1, sizeof(struct inflate_state));
+    if (state == Z_NULL) return Z_MEM_ERROR;
+    Tracev((stderr, "inflate: allocated\n"));
+    strm->state = (struct internal_state FAR *)state;
+    state->strm = strm;
+    state->window = Z_NULL;
+    state->mode = HEAD;     /* to pass state test in inflateReset2() */
+    ret = inflateReset2(strm, windowBits);
+    if (ret != Z_OK) {
+        ZFREE(strm, state);
+        strm->state = Z_NULL;
+    }
+    return ret;
+}
+
+int ZEXPORT inflateInit_(strm, version, stream_size)
+z_streamp strm;
+const char *version;
+int stream_size;
+{
+    return inflateInit2_(strm, DEF_WBITS, version, stream_size);
+}
+
+int ZEXPORT inflatePrime(strm, bits, value)
+z_streamp strm;
+int bits;
+int value;
+{
+    struct inflate_state FAR *state;
+
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (bits < 0) {
+        state->hold = 0;
+        state->bits = 0;
+        return Z_OK;
+    }
+    if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR;
+    value &= (1L << bits) - 1;
+    state->hold += (unsigned)value << state->bits;
+    state->bits += (uInt)bits;
+    return Z_OK;
+}
+
+/*
+   Return state with length and distance decoding tables and index sizes set to
+   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
+   If BUILDFIXED is defined, then instead this routine builds the tables the
+   first time it's called, and returns those tables the first time and
+   thereafter.  This reduces the size of the code by about 2K bytes, in
+   exchange for a little execution time.  However, BUILDFIXED should not be
+   used for threaded applications, since the rewriting of the tables and virgin
+   may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+    static int virgin = 1;
+    static code *lenfix, *distfix;
+    static code fixed[544];
+
+    /* build fixed huffman tables if first call (may not be thread safe) */
+    if (virgin) {
+        unsigned sym, bits;
+        static code *next;
+
+        /* literal/length table */
+        sym = 0;
+        while (sym < 144) state->lens[sym++] = 8;
+        while (sym < 256) state->lens[sym++] = 9;
+        while (sym < 280) state->lens[sym++] = 7;
+        while (sym < 288) state->lens[sym++] = 8;
+        next = fixed;
+        lenfix = next;
+        bits = 9;
+        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+        /* distance table */
+        sym = 0;
+        while (sym < 32) state->lens[sym++] = 5;
+        distfix = next;
+        bits = 5;
+        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+        /* do this just once */
+        virgin = 0;
+    }
+#else /* !BUILDFIXED */
+#   include "inffixed.h"
+#endif /* BUILDFIXED */
+    state->lencode = lenfix;
+    state->lenbits = 9;
+    state->distcode = distfix;
+    state->distbits = 5;
+}
+
+#ifdef MAKEFIXED
+#include <stdio.h>
+
+/*
+   Write out the inffixed.h that is #include'd above.  Defining MAKEFIXED also
+   defines BUILDFIXED, so the tables are built on the fly.  makefixed() writes
+   those tables to stdout, which would be piped to inffixed.h.  A small program
+   can simply call makefixed to do this:
+
+    void makefixed(void);
+
+    int main(void)
+    {
+        makefixed();
+        return 0;
+    }
+
+   Then that can be linked with zlib built with MAKEFIXED defined and run:
+
+    a.out > inffixed.h
+ */
+void makefixed()
+{
+    unsigned low, size;
+    struct inflate_state state;
+
+    fixedtables(&state);
+    puts("    /* inffixed.h -- table for decoding fixed codes");
+    puts("     * Generated automatically by makefixed().");
+    puts("     */");
+    puts("");
+    puts("    /* WARNING: this file should *not* be used by applications.");
+    puts("       It is part of the implementation of this library and is");
+    puts("       subject to change. Applications should only use zlib.h.");
+    puts("     */");
+    puts("");
+    size = 1U << 9;
+    printf("    static const code lenfix[%u] = {", size);
+    low = 0;
+    for (;;) {
+        if ((low % 7) == 0) printf("\n        ");
+        printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
+               state.lencode[low].bits, state.lencode[low].val);
+        if (++low == size) break;
+        putchar(',');
+    }
+    puts("\n    };");
+    size = 1U << 5;
+    printf("\n    static const code distfix[%u] = {", size);
+    low = 0;
+    for (;;) {
+        if ((low % 6) == 0) printf("\n        ");
+        printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
+               state.distcode[low].val);
+        if (++low == size) break;
+        putchar(',');
+    }
+    puts("\n    };");
+}
+#endif /* MAKEFIXED */
+
+/*
+   Update the window with the last wsize (normally 32K) bytes written before
+   returning.  If window does not exist yet, create it.  This is only called
+   when a window is already in use, or when output has been written during this
+   inflate call, but the end of the deflate stream has not been reached yet.
+   It is also called to create a window for dictionary data when a dictionary
+   is loaded.
+
+   Providing output buffers larger than 32K to inflate() should provide a speed
+   advantage, since only the last 32K of output is copied to the sliding window
+   upon return from inflate(), and since all distances after the first 32K of
+   output will fall in the output data, making match copies simpler and faster.
+   The advantage may be dependent on the size of the processor's data caches.
+ */
+local int updatewindow(strm, end, copy)
+z_streamp strm;
+const Bytef *end;
+unsigned copy;
+{
+    struct inflate_state FAR *state;
+    unsigned dist;
+
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* if it hasn't been done already, allocate space for the window */
+    if (state->window == Z_NULL) {
+        state->window = (unsigned char FAR *)
+                        ZALLOC(strm, 1U << state->wbits,
+                               sizeof(unsigned char));
+        if (state->window == Z_NULL) return 1;
+    }
+
+    /* if window not in use yet, initialize */
+    if (state->wsize == 0) {
+        state->wsize = 1U << state->wbits;
+        state->wnext = 0;
+        state->whave = 0;
+    }
+
+    /* copy state->wsize or less output bytes into the circular window */
+    if (copy >= state->wsize) {
+        zmemcpy(state->window, end - state->wsize, state->wsize);
+        state->wnext = 0;
+        state->whave = state->wsize;
+    }
+    else {
+        dist = state->wsize - state->wnext;
+        if (dist > copy) dist = copy;
+        zmemcpy(state->window + state->wnext, end - copy, dist);
+        copy -= dist;
+        if (copy) {
+            zmemcpy(state->window, end - copy, copy);
+            state->wnext = copy;
+            state->whave = state->wsize;
+        }
+        else {
+            state->wnext += dist;
+            if (state->wnext == state->wsize) state->wnext = 0;
+            if (state->whave < state->wsize) state->whave += dist;
+        }
+    }
+    return 0;
+}
+
+/* Macros for inflate(): */
+
+/* check function to use adler32() for zlib or crc32() for gzip */
+#ifdef GUNZIP
+#  define UPDATE(check, buf, len) \
+    (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
+#else
+#  define UPDATE(check, buf, len) adler32(check, buf, len)
+#endif
+
+/* check macros for header crc */
+#ifdef GUNZIP
+#  define CRC2(check, word) \
+    do { \
+        hbuf[0] = (unsigned char)(word); \
+        hbuf[1] = (unsigned char)((word) >> 8); \
+        check = crc32(check, hbuf, 2); \
+    } while (0)
+
+#  define CRC4(check, word) \
+    do { \
+        hbuf[0] = (unsigned char)(word); \
+        hbuf[1] = (unsigned char)((word) >> 8); \
+        hbuf[2] = (unsigned char)((word) >> 16); \
+        hbuf[3] = (unsigned char)((word) >> 24); \
+        check = crc32(check, hbuf, 4); \
+    } while (0)
+#endif
+
+/* Load registers with state in inflate() for speed */
+#define LOAD() \
+    do { \
+        put = strm->next_out; \
+        left = strm->avail_out; \
+        next = strm->next_in; \
+        have = strm->avail_in; \
+        hold = state->hold; \
+        bits = state->bits; \
+    } while (0)
+
+/* Restore state from registers in inflate() */
+#define RESTORE() \
+    do { \
+        strm->next_out = put; \
+        strm->avail_out = left; \
+        strm->next_in = next; \
+        strm->avail_in = have; \
+        state->hold = hold; \
+        state->bits = bits; \
+    } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+    do { \
+        hold = 0; \
+        bits = 0; \
+    } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflate()
+   if there is no input available. */
+#define PULLBYTE() \
+    do { \
+        if (have == 0) goto inf_leave; \
+        have--; \
+        hold += (unsigned long)(*next++) << bits; \
+        bits += 8; \
+    } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator.  If there is
+   not enough available input to do that, then return from inflate(). */
+#define NEEDBITS(n) \
+    do { \
+        while (bits < (unsigned)(n)) \
+            PULLBYTE(); \
+    } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+    ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+    do { \
+        hold >>= (n); \
+        bits -= (unsigned)(n); \
+    } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+    do { \
+        hold >>= bits & 7; \
+        bits -= bits & 7; \
+    } while (0)
+
+/*
+   inflate() uses a state machine to process as much input data and generate as
+   much output data as possible before returning.  The state machine is
+   structured roughly as follows:
+
+    for (;;) switch (state) {
+    ...
+    case STATEn:
+        if (not enough input data or output space to make progress)
+            return;
+        ... make progress ...
+        state = STATEm;
+        break;
+    ...
+    }
+
+   so when inflate() is called again, the same case is attempted again, and
+   if the appropriate resources are provided, the machine proceeds to the
+   next state.  The NEEDBITS() macro is usually the way the state evaluates
+   whether it can proceed or should return.  NEEDBITS() does the return if
+   the requested bits are not available.  The typical use of the BITS macros
+   is:
+
+        NEEDBITS(n);
+        ... do something with BITS(n) ...
+        DROPBITS(n);
+
+   where NEEDBITS(n) either returns from inflate() if there isn't enough
+   input left to load n bits into the accumulator, or it continues.  BITS(n)
+   gives the low n bits in the accumulator.  When done, DROPBITS(n) drops
+   the low n bits off the accumulator.  INITBITS() clears the accumulator
+   and sets the number of available bits to zero.  BYTEBITS() discards just
+   enough bits to put the accumulator on a byte boundary.  After BYTEBITS()
+   and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
+
+   NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
+   if there is no input available.  The decoding of variable length codes uses
+   PULLBYTE() directly in order to pull just enough bytes to decode the next
+   code, and no more.
+
+   Some states loop until they get enough input, making sure that enough
+   state information is maintained to continue the loop where it left off
+   if NEEDBITS() returns in the loop.  For example, want, need, and keep
+   would all have to actually be part of the saved state in case NEEDBITS()
+   returns:
+
+    case STATEw:
+        while (want < need) {
+            NEEDBITS(n);
+            keep[want++] = BITS(n);
+            DROPBITS(n);
+        }
+        state = STATEx;
+    case STATEx:
+
+   As shown above, if the next state is also the next case, then the break
+   is omitted.
+
+   A state may also return if there is not enough output space available to
+   complete that state.  Those states are copying stored data, writing a
+   literal byte, and copying a matching string.
+
+   When returning, a "goto inf_leave" is used to update the total counters,
+   update the check value, and determine whether any progress has been made
+   during that inflate() call in order to return the proper return code.
+   Progress is defined as a change in either strm->avail_in or strm->avail_out.
+   When there is a window, goto inf_leave will update the window with the last
+   output written.  If a goto inf_leave occurs in the middle of decompression
+   and there is no window currently, goto inf_leave will create one and copy
+   output to the window for the next call of inflate().
+
+   In this implementation, the flush parameter of inflate() only affects the
+   return code (per zlib.h).  inflate() always writes as much as possible to
+   strm->next_out, given the space available and the provided input--the effect
+   documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers
+   the allocation of and copying into a sliding window until necessary, which
+   provides the effect documented in zlib.h for Z_FINISH when the entire input
+   stream available.  So the only thing the flush parameter actually does is:
+   when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it
+   will return Z_BUF_ERROR if it has not reached the end of the stream.
+ */
+
+int ZEXPORT inflate(strm, flush)
+z_streamp strm;
+int flush;
+{
+    struct inflate_state FAR *state;
+    z_const unsigned char FAR *next;    /* next input */
+    unsigned char FAR *put;     /* next output */
+    unsigned have, left;        /* available input and output */
+    unsigned long hold;         /* bit buffer */
+    unsigned bits;              /* bits in bit buffer */
+    unsigned in, out;           /* save starting available input and output */
+    unsigned copy;              /* number of stored or match bytes to copy */
+    unsigned char FAR *from;    /* where to copy match bytes from */
+    code here;                  /* current decoding table entry */
+    code last;                  /* parent table entry */
+    unsigned len;               /* length to copy for repeats, bits to drop */
+    int ret;                    /* return code */
+#ifdef GUNZIP
+    unsigned char hbuf[4];      /* buffer for gzip header crc calculation */
+#endif
+    static const unsigned short order[19] = /* permutation of code lengths */
+        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+    if (inflateStateCheck(strm) || strm->next_out == Z_NULL ||
+        (strm->next_in == Z_NULL && strm->avail_in != 0))
+        return Z_STREAM_ERROR;
+
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */
+    LOAD();
+    in = have;
+    out = left;
+    ret = Z_OK;
+    for (;;)
+        switch (state->mode) {
+        case HEAD:
+            if (state->wrap == 0) {
+                state->mode = TYPEDO;
+                break;
+            }
+            NEEDBITS(16);
+#ifdef GUNZIP
+            if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */
+                if (state->wbits == 0)
+                    state->wbits = 15;
+                state->check = crc32(0L, Z_NULL, 0);
+                CRC2(state->check, hold);
+                INITBITS();
+                state->mode = FLAGS;
+                break;
+            }
+            state->flags = 0;           /* expect zlib header */
+            if (state->head != Z_NULL)
+                state->head->done = -1;
+            if (!(state->wrap & 1) ||   /* check if zlib header allowed */
+#else
+            if (
+#endif
+                ((BITS(8) << 8) + (hold >> 8)) % 31) {
+                strm->msg = (char *)"incorrect header check";
+                state->mode = BAD;
+                break;
+            }
+            if (BITS(4) != Z_DEFLATED) {
+                strm->msg = (char *)"unknown compression method";
+                state->mode = BAD;
+                break;
+            }
+            DROPBITS(4);
+            len = BITS(4) + 8;
+            if (state->wbits == 0)
+                state->wbits = len;
+            if (len > 15 || len > state->wbits) {
+                strm->msg = (char *)"invalid window size";
+                state->mode = BAD;
+                break;
+            }
+            state->dmax = 1U << len;
+            Tracev((stderr, "inflate:   zlib header ok\n"));
+            strm->adler = state->check = adler32(0L, Z_NULL, 0);
+            state->mode = hold & 0x200 ? DICTID : TYPE;
+            INITBITS();
+            break;
+#ifdef GUNZIP
+        case FLAGS:
+            NEEDBITS(16);
+            state->flags = (int)(hold);
+            if ((state->flags & 0xff) != Z_DEFLATED) {
+                strm->msg = (char *)"unknown compression method";
+                state->mode = BAD;
+                break;
+            }
+            if (state->flags & 0xe000) {
+                strm->msg = (char *)"unknown header flags set";
+                state->mode = BAD;
+                break;
+            }
+            if (state->head != Z_NULL)
+                state->head->text = (int)((hold >> 8) & 1);
+            if ((state->flags & 0x0200) && (state->wrap & 4))
+                CRC2(state->check, hold);
+            INITBITS();
+            state->mode = TIME;
+        case TIME:
+            NEEDBITS(32);
+            if (state->head != Z_NULL)
+                state->head->time = hold;
+            if ((state->flags & 0x0200) && (state->wrap & 4))
+                CRC4(state->check, hold);
+            INITBITS();
+            state->mode = OS;
+        case OS:
+            NEEDBITS(16);
+            if (state->head != Z_NULL) {
+                state->head->xflags = (int)(hold & 0xff);
+                state->head->os = (int)(hold >> 8);
+            }
+            if ((state->flags & 0x0200) && (state->wrap & 4))
+                CRC2(state->check, hold);
+            INITBITS();
+            state->mode = EXLEN;
+        case EXLEN:
+            if (state->flags & 0x0400) {
+                NEEDBITS(16);
+                state->length = (unsigned)(hold);
+                if (state->head != Z_NULL)
+                    state->head->extra_len = (unsigned)hold;
+                if ((state->flags & 0x0200) && (state->wrap & 4))
+                    CRC2(state->check, hold);
+                INITBITS();
+            }
+            else if (state->head != Z_NULL)
+                state->head->extra = Z_NULL;
+            state->mode = EXTRA;
+        case EXTRA:
+            if (state->flags & 0x0400) {
+                copy = state->length;
+                if (copy > have) copy = have;
+                if (copy) {
+                    if (state->head != Z_NULL &&
+                        state->head->extra != Z_NULL) {
+                        len = state->head->extra_len - state->length;
+                        zmemcpy(state->head->extra + len, next,
+                                len + copy > state->head->extra_max ?
+                                state->head->extra_max - len : copy);
+                    }
+                    if ((state->flags & 0x0200) && (state->wrap & 4))
+                        state->check = crc32(state->check, next, copy);
+                    have -= copy;
+                    next += copy;
+                    state->length -= copy;
+                }
+                if (state->length) goto inf_leave;
+            }
+            state->length = 0;
+            state->mode = NAME;
+        case NAME:
+            if (state->flags & 0x0800) {
+                if (have == 0) goto inf_leave;
+                copy = 0;
+                do {
+                    len = (unsigned)(next[copy++]);
+                    if (state->head != Z_NULL &&
+                            state->head->name != Z_NULL &&
+                            state->length < state->head->name_max)
+                        state->head->name[state->length++] = (Bytef)len;
+                } while (len && copy < have);
+                if ((state->flags & 0x0200) && (state->wrap & 4))
+                    state->check = crc32(state->check, next, copy);
+                have -= copy;
+                next += copy;
+                if (len) goto inf_leave;
+            }
+            else if (state->head != Z_NULL)
+                state->head->name = Z_NULL;
+            state->length = 0;
+            state->mode = COMMENT;
+        case COMMENT:
+            if (state->flags & 0x1000) {
+                if (have == 0) goto inf_leave;
+                copy = 0;
+                do {
+                    len = (unsigned)(next[copy++]);
+                    if (state->head != Z_NULL &&
+                            state->head->comment != Z_NULL &&
+                            state->length < state->head->comm_max)
+                        state->head->comment[state->length++] = (Bytef)len;
+                } while (len && copy < have);
+                if ((state->flags & 0x0200) && (state->wrap & 4))
+                    state->check = crc32(state->check, next, copy);
+                have -= copy;
+                next += copy;
+                if (len) goto inf_leave;
+            }
+            else if (state->head != Z_NULL)
+                state->head->comment = Z_NULL;
+            state->mode = HCRC;
+        case HCRC:
+            if (state->flags & 0x0200) {
+                NEEDBITS(16);
+                if ((state->wrap & 4) && hold != (state->check & 0xffff)) {
+                    strm->msg = (char *)"header crc mismatch";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+            }
+            if (state->head != Z_NULL) {
+                state->head->hcrc = (int)((state->flags >> 9) & 1);
+                state->head->done = 1;
+            }
+            strm->adler = state->check = crc32(0L, Z_NULL, 0);
+            state->mode = TYPE;
+            break;
+#endif
+        case DICTID:
+            NEEDBITS(32);
+            strm->adler = state->check = ZSWAP32(hold);
+            INITBITS();
+            state->mode = DICT;
+        case DICT:
+            if (state->havedict == 0) {
+                RESTORE();
+                return Z_NEED_DICT;
+            }
+            strm->adler = state->check = adler32(0L, Z_NULL, 0);
+            state->mode = TYPE;
+        case TYPE:
+            if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
+        case TYPEDO:
+            if (state->last) {
+                BYTEBITS();
+                state->mode = CHECK;
+                break;
+            }
+            NEEDBITS(3);
+            state->last = BITS(1);
+            DROPBITS(1);
+            switch (BITS(2)) {
+            case 0:                             /* stored block */
+                Tracev((stderr, "inflate:     stored block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = STORED;
+                break;
+            case 1:                             /* fixed block */
+                fixedtables(state);
+                Tracev((stderr, "inflate:     fixed codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = LEN_;             /* decode codes */
+                if (flush == Z_TREES) {
+                    DROPBITS(2);
+                    goto inf_leave;
+                }
+                break;
+            case 2:                             /* dynamic block */
+                Tracev((stderr, "inflate:     dynamic codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = TABLE;
+                break;
+            case 3:
+                strm->msg = (char *)"invalid block type";
+                state->mode = BAD;
+            }
+            DROPBITS(2);
+            break;
+        case STORED:
+            BYTEBITS();                         /* go to byte boundary */
+            NEEDBITS(32);
+            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+                strm->msg = (char *)"invalid stored block lengths";
+                state->mode = BAD;
+                break;
+            }
+            state->length = (unsigned)hold & 0xffff;
+            Tracev((stderr, "inflate:       stored length %u\n",
+                    state->length));
+            INITBITS();
+            state->mode = COPY_;
+            if (flush == Z_TREES) goto inf_leave;
+        case COPY_:
+            state->mode = COPY;
+        case COPY:
+            copy = state->length;
+            if (copy) {
+                if (copy > have) copy = have;
+                if (copy > left) copy = left;
+                if (copy == 0) goto inf_leave;
+                zmemcpy(put, next, copy);
+                have -= copy;
+                next += copy;
+                left -= copy;
+                put += copy;
+                state->length -= copy;
+                break;
+            }
+            Tracev((stderr, "inflate:       stored end\n"));
+            state->mode = TYPE;
+            break;
+        case TABLE:
+            NEEDBITS(14);
+            state->nlen = BITS(5) + 257;
+            DROPBITS(5);
+            state->ndist = BITS(5) + 1;
+            DROPBITS(5);
+            state->ncode = BITS(4) + 4;
+            DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+            if (state->nlen > 286 || state->ndist > 30) {
+                strm->msg = (char *)"too many length or distance symbols";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            Tracev((stderr, "inflate:       table sizes ok\n"));
+            state->have = 0;
+            state->mode = LENLENS;
+        case LENLENS:
+            while (state->have < state->ncode) {
+                NEEDBITS(3);
+                state->lens[order[state->have++]] = (unsigned short)BITS(3);
+                DROPBITS(3);
+            }
+            while (state->have < 19)
+                state->lens[order[state->have++]] = 0;
+            state->next = state->codes;
+            state->lencode = (const code FAR *)(state->next);
+            state->lenbits = 7;
+            ret = inflate_table(CODES, state->lens, 19, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid code lengths set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       code lengths ok\n"));
+            state->have = 0;
+            state->mode = CODELENS;
+        case CODELENS:
+            while (state->have < state->nlen + state->ndist) {
+                for (;;) {
+                    here = state->lencode[BITS(state->lenbits)];
+                    if ((unsigned)(here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                if (here.val < 16) {
+                    DROPBITS(here.bits);
+                    state->lens[state->have++] = here.val;
+                }
+                else {
+                    if (here.val == 16) {
+                        NEEDBITS(here.bits + 2);
+                        DROPBITS(here.bits);
+                        if (state->have == 0) {
+                            strm->msg = (char *)"invalid bit length repeat";
+                            state->mode = BAD;
+                            break;
+                        }
+                        len = state->lens[state->have - 1];
+                        copy = 3 + BITS(2);
+                        DROPBITS(2);
+                    }
+                    else if (here.val == 17) {
+                        NEEDBITS(here.bits + 3);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 3 + BITS(3);
+                        DROPBITS(3);
+                    }
+                    else {
+                        NEEDBITS(here.bits + 7);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 11 + BITS(7);
+                        DROPBITS(7);
+                    }
+                    if (state->have + copy > state->nlen + state->ndist) {
+                        strm->msg = (char *)"invalid bit length repeat";
+                        state->mode = BAD;
+                        break;
+                    }
+                    while (copy--)
+                        state->lens[state->have++] = (unsigned short)len;
+                }
+            }
+
+            /* handle error breaks in while */
+            if (state->mode == BAD) break;
+
+            /* check for end-of-block code (better have one) */
+            if (state->lens[256] == 0) {
+                strm->msg = (char *)"invalid code -- missing end-of-block";
+                state->mode = BAD;
+                break;
+            }
+
+            /* build code tables -- note: do not change the lenbits or distbits
+               values here (9 and 6) without reading the comments in inftrees.h
+               concerning the ENOUGH constants, which depend on those values */
+            state->next = state->codes;
+            state->lencode = (const code FAR *)(state->next);
+            state->lenbits = 9;
+            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid literal/lengths set";
+                state->mode = BAD;
+                break;
+            }
+            state->distcode = (const code FAR *)(state->next);
+            state->distbits = 6;
+            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+                            &(state->next), &(state->distbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid distances set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       codes ok\n"));
+            state->mode = LEN_;
+            if (flush == Z_TREES) goto inf_leave;
+        case LEN_:
+            state->mode = LEN;
+        case LEN:
+            if (have >= 6 && left >= 258) {
+                RESTORE();
+                inflate_fast(strm, out);
+                LOAD();
+                if (state->mode == TYPE)
+                    state->back = -1;
+                break;
+            }
+            state->back = 0;
+            for (;;) {
+                here = state->lencode[BITS(state->lenbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if (here.op && (here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = state->lencode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+                state->back += last.bits;
+            }
+            DROPBITS(here.bits);
+            state->back += here.bits;
+            state->length = (unsigned)here.val;
+            if ((int)(here.op) == 0) {
+                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+                        "inflate:         literal '%c'\n" :
+                        "inflate:         literal 0x%02x\n", here.val));
+                state->mode = LIT;
+                break;
+            }
+            if (here.op & 32) {
+                Tracevv((stderr, "inflate:         end of block\n"));
+                state->back = -1;
+                state->mode = TYPE;
+                break;
+            }
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid literal/length code";
+                state->mode = BAD;
+                break;
+            }
+            state->extra = (unsigned)(here.op) & 15;
+            state->mode = LENEXT;
+        case LENEXT:
+            if (state->extra) {
+                NEEDBITS(state->extra);
+                state->length += BITS(state->extra);
+                DROPBITS(state->extra);
+                state->back += state->extra;
+            }
+            Tracevv((stderr, "inflate:         length %u\n", state->length));
+            state->was = state->length;
+            state->mode = DIST;
+        case DIST:
+            for (;;) {
+                here = state->distcode[BITS(state->distbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if ((here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = state->distcode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+                state->back += last.bits;
+            }
+            DROPBITS(here.bits);
+            state->back += here.bits;
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+            state->offset = (unsigned)here.val;
+            state->extra = (unsigned)(here.op) & 15;
+            state->mode = DISTEXT;
+        case DISTEXT:
+            if (state->extra) {
+                NEEDBITS(state->extra);
+                state->offset += BITS(state->extra);
+                DROPBITS(state->extra);
+                state->back += state->extra;
+            }
+#ifdef INFLATE_STRICT
+            if (state->offset > state->dmax) {
+                strm->msg = (char *)"invalid distance too far back";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
+            state->mode = MATCH;
+        case MATCH:
+            if (left == 0) goto inf_leave;
+            copy = out - left;
+            if (state->offset > copy) {         /* copy from window */
+                copy = state->offset - copy;
+                if (copy > state->whave) {
+                    if (state->sane) {
+                        strm->msg = (char *)"invalid distance too far back";
+                        state->mode = BAD;
+                        break;
+                    }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+                    Trace((stderr, "inflate.c too far\n"));
+                    copy -= state->whave;
+                    if (copy > state->length) copy = state->length;
+                    if (copy > left) copy = left;
+                    left -= copy;
+                    state->length -= copy;
+                    do {
+                        *put++ = 0;
+                    } while (--copy);
+                    if (state->length == 0) state->mode = LEN;
+                    break;
+#endif
+                }
+                if (copy > state->wnext) {
+                    copy -= state->wnext;
+                    from = state->window + (state->wsize - copy);
+                }
+                else
+                    from = state->window + (state->wnext - copy);
+                if (copy > state->length) copy = state->length;
+            }
+            else {                              /* copy from output */
+                from = put - state->offset;
+                copy = state->length;
+            }
+            if (copy > left) copy = left;
+            left -= copy;
+            state->length -= copy;
+            do {
+                *put++ = *from++;
+            } while (--copy);
+            if (state->length == 0) state->mode = LEN;
+            break;
+        case LIT:
+            if (left == 0) goto inf_leave;
+            *put++ = (unsigned char)(state->length);
+            left--;
+            state->mode = LEN;
+            break;
+        case CHECK:
+            if (state->wrap) {
+                NEEDBITS(32);
+                out -= left;
+                strm->total_out += out;
+                state->total += out;
+                if ((state->wrap & 4) && out)
+                    strm->adler = state->check =
+                        UPDATE(state->check, put - out, out);
+                out = left;
+                if ((state->wrap & 4) && (
+#ifdef GUNZIP
+                     state->flags ? hold :
+#endif
+                     ZSWAP32(hold)) != state->check) {
+                    strm->msg = (char *)"incorrect data check";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+                Tracev((stderr, "inflate:   check matches trailer\n"));
+            }
+#ifdef GUNZIP
+            state->mode = LENGTH;
+        case LENGTH:
+            if (state->wrap && state->flags) {
+                NEEDBITS(32);
+                if (hold != (state->total & 0xffffffffUL)) {
+                    strm->msg = (char *)"incorrect length check";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+                Tracev((stderr, "inflate:   length matches trailer\n"));
+            }
+#endif
+            state->mode = DONE;
+        case DONE:
+            ret = Z_STREAM_END;
+            goto inf_leave;
+        case BAD:
+            ret = Z_DATA_ERROR;
+            goto inf_leave;
+        case MEM:
+            return Z_MEM_ERROR;
+        case SYNC:
+        default:
+            return Z_STREAM_ERROR;
+        }
+
+    /*
+       Return from inflate(), updating the total counts and the check value.
+       If there was no progress during the inflate() call, return a buffer
+       error.  Call updatewindow() to create and/or update the window state.
+       Note: a memory error from inflate() is non-recoverable.
+     */
+  inf_leave:
+    RESTORE();
+    if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
+            (state->mode < CHECK || flush != Z_FINISH)))
+        if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
+            state->mode = MEM;
+            return Z_MEM_ERROR;
+        }
+    in -= strm->avail_in;
+    out -= strm->avail_out;
+    strm->total_in += in;
+    strm->total_out += out;
+    state->total += out;
+    if ((state->wrap & 4) && out)
+        strm->adler = state->check =
+            UPDATE(state->check, strm->next_out - out, out);
+    strm->data_type = (int)state->bits + (state->last ? 64 : 0) +
+                      (state->mode == TYPE ? 128 : 0) +
+                      (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
+    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
+        ret = Z_BUF_ERROR;
+    return ret;
+}
+
+int ZEXPORT inflateEnd(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+    if (inflateStateCheck(strm))
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->window != Z_NULL) ZFREE(strm, state->window);
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+    Tracev((stderr, "inflate: end\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+Bytef *dictionary;
+uInt *dictLength;
+{
+    struct inflate_state FAR *state;
+
+    /* check state */
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* copy dictionary */
+    if (state->whave && dictionary != Z_NULL) {
+        zmemcpy(dictionary, state->window + state->wnext,
+                state->whave - state->wnext);
+        zmemcpy(dictionary + state->whave - state->wnext,
+                state->window, state->wnext);
+    }
+    if (dictLength != Z_NULL)
+        *dictLength = state->whave;
+    return Z_OK;
+}
+
+int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+const Bytef *dictionary;
+uInt dictLength;
+{
+    struct inflate_state FAR *state;
+    unsigned long dictid;
+    int ret;
+
+    /* check state */
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->wrap != 0 && state->mode != DICT)
+        return Z_STREAM_ERROR;
+
+    /* check for correct dictionary identifier */
+    if (state->mode == DICT) {
+        dictid = adler32(0L, Z_NULL, 0);
+        dictid = adler32(dictid, dictionary, dictLength);
+        if (dictid != state->check)
+            return Z_DATA_ERROR;
+    }
+
+    /* copy dictionary to window using updatewindow(), which will amend the
+       existing dictionary if appropriate */
+    ret = updatewindow(strm, dictionary + dictLength, dictLength);
+    if (ret) {
+        state->mode = MEM;
+        return Z_MEM_ERROR;
+    }
+    state->havedict = 1;
+    Tracev((stderr, "inflate:   dictionary set\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateGetHeader(strm, head)
+z_streamp strm;
+gz_headerp head;
+{
+    struct inflate_state FAR *state;
+
+    /* check state */
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
+
+    /* save header structure */
+    state->head = head;
+    head->done = 0;
+    return Z_OK;
+}
+
+/*
+   Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff.  Return when found
+   or when out of input.  When called, *have is the number of pattern bytes
+   found in order so far, in 0..3.  On return *have is updated to the new
+   state.  If on return *have equals four, then the pattern was found and the
+   return value is how many bytes were read including the last byte of the
+   pattern.  If *have is less than four, then the pattern has not been found
+   yet and the return value is len.  In the latter case, syncsearch() can be
+   called again with more data and the *have state.  *have is initialized to
+   zero for the first call.
+ */
+local unsigned syncsearch(have, buf, len)
+unsigned FAR *have;
+const unsigned char FAR *buf;
+unsigned len;
+{
+    unsigned got;
+    unsigned next;
+
+    got = *have;
+    next = 0;
+    while (next < len && got < 4) {
+        if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
+            got++;
+        else if (buf[next])
+            got = 0;
+        else
+            got = 4 - got;
+        next++;
+    }
+    *have = got;
+    return next;
+}
+
+int ZEXPORT inflateSync(strm)
+z_streamp strm;
+{
+    unsigned len;               /* number of bytes to look at or looked at */
+    unsigned long in, out;      /* temporary to save total_in and total_out */
+    unsigned char buf[4];       /* to restore bit buffer to byte string */
+    struct inflate_state FAR *state;
+
+    /* check parameters */
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
+
+    /* if first time, start search in bit buffer */
+    if (state->mode != SYNC) {
+        state->mode = SYNC;
+        state->hold <<= state->bits & 7;
+        state->bits -= state->bits & 7;
+        len = 0;
+        while (state->bits >= 8) {
+            buf[len++] = (unsigned char)(state->hold);
+            state->hold >>= 8;
+            state->bits -= 8;
+        }
+        state->have = 0;
+        syncsearch(&(state->have), buf, len);
+    }
+
+    /* search available input */
+    len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
+    strm->avail_in -= len;
+    strm->next_in += len;
+    strm->total_in += len;
+
+    /* return no joy or set up to restart inflate() on a new block */
+    if (state->have != 4) return Z_DATA_ERROR;
+    in = strm->total_in;  out = strm->total_out;
+    inflateReset(strm);
+    strm->total_in = in;  strm->total_out = out;
+    state->mode = TYPE;
+    return Z_OK;
+}
+
+/*
+   Returns true if inflate is currently at the end of a block generated by
+   Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+   implementation to provide an additional safety check. PPP uses
+   Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
+   block. When decompressing, PPP checks that at the end of input packet,
+   inflate is waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    return state->mode == STORED && state->bits == 0;
+}
+
+int ZEXPORT inflateCopy(dest, source)
+z_streamp dest;
+z_streamp source;
+{
+    struct inflate_state FAR *state;
+    struct inflate_state FAR *copy;
+    unsigned char FAR *window;
+    unsigned wsize;
+
+    /* check input */
+    if (inflateStateCheck(source) || dest == Z_NULL)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)source->state;
+
+    /* allocate space */
+    copy = (struct inflate_state FAR *)
+           ZALLOC(source, 1, sizeof(struct inflate_state));
+    if (copy == Z_NULL) return Z_MEM_ERROR;
+    window = Z_NULL;
+    if (state->window != Z_NULL) {
+        window = (unsigned char FAR *)
+                 ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
+        if (window == Z_NULL) {
+            ZFREE(source, copy);
+            return Z_MEM_ERROR;
+        }
+    }
+
+    /* copy state */
+    zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
+    zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
+    copy->strm = dest;
+    if (state->lencode >= state->codes &&
+        state->lencode <= state->codes + ENOUGH - 1) {
+        copy->lencode = copy->codes + (state->lencode - state->codes);
+        copy->distcode = copy->codes + (state->distcode - state->codes);
+    }
+    copy->next = copy->codes + (state->next - state->codes);
+    if (window != Z_NULL) {
+        wsize = 1U << state->wbits;
+        zmemcpy(window, state->window, wsize);
+    }
+    copy->window = window;
+    dest->state = (struct internal_state FAR *)copy;
+    return Z_OK;
+}
+
+int ZEXPORT inflateUndermine(strm, subvert)
+z_streamp strm;
+int subvert;
+{
+    struct inflate_state FAR *state;
+
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+    state->sane = !subvert;
+    return Z_OK;
+#else
+    (void)subvert;
+    state->sane = 1;
+    return Z_DATA_ERROR;
+#endif
+}
+
+int ZEXPORT inflateValidate(strm, check)
+z_streamp strm;
+int check;
+{
+    struct inflate_state FAR *state;
+
+    if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (check)
+        state->wrap |= 4;
+    else
+        state->wrap &= ~4;
+    return Z_OK;
+}
+
+long ZEXPORT inflateMark(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (inflateStateCheck(strm))
+        return -(1L << 16);
+    state = (struct inflate_state FAR *)strm->state;
+    return (long)(((unsigned long)((long)state->back)) << 16) +
+        (state->mode == COPY ? state->length :
+            (state->mode == MATCH ? state->was - state->length : 0));
+}
+
+unsigned long ZEXPORT inflateCodesUsed(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+    if (inflateStateCheck(strm)) return (unsigned long)-1;
+    state = (struct inflate_state FAR *)strm->state;
+    return (unsigned long)(state->next - state->codes);
+}
Index: EcnlProtoTool/trunk/zlib-1.2.11/inflate.h
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/inflate.h	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/inflate.h	(revision 331)
@@ -0,0 +1,125 @@
+/* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+   trailer decoding by inflate().  NO_GZIP would be used to avoid linking in
+   the crc code when it is not needed.  For shared libraries, gzip decoding
+   should be left enabled. */
+#ifndef NO_GZIP
+#  define GUNZIP
+#endif
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+    HEAD = 16180,   /* i: waiting for magic header */
+    FLAGS,      /* i: waiting for method and flags (gzip) */
+    TIME,       /* i: waiting for modification time (gzip) */
+    OS,         /* i: waiting for extra flags and operating system (gzip) */
+    EXLEN,      /* i: waiting for extra length (gzip) */
+    EXTRA,      /* i: waiting for extra bytes (gzip) */
+    NAME,       /* i: waiting for end of file name (gzip) */
+    COMMENT,    /* i: waiting for end of comment (gzip) */
+    HCRC,       /* i: waiting for header crc (gzip) */
+    DICTID,     /* i: waiting for dictionary check value */
+    DICT,       /* waiting for inflateSetDictionary() call */
+        TYPE,       /* i: waiting for type bits, including last-flag bit */
+        TYPEDO,     /* i: same, but skip check to exit inflate on new block */
+        STORED,     /* i: waiting for stored size (length and complement) */
+        COPY_,      /* i/o: same as COPY below, but only first time in */
+        COPY,       /* i/o: waiting for input or output to copy stored block */
+        TABLE,      /* i: waiting for dynamic block table lengths */
+        LENLENS,    /* i: waiting for code length code lengths */
+        CODELENS,   /* i: waiting for length/lit and distance code lengths */
+            LEN_,       /* i: same as LEN below, but only first time in */
+            LEN,        /* i: waiting for length/lit/eob code */
+            LENEXT,     /* i: waiting for length extra bits */
+            DIST,       /* i: waiting for distance code */
+            DISTEXT,    /* i: waiting for distance extra bits */
+            MATCH,      /* o: waiting for output space to copy string */
+            LIT,        /* o: waiting for output space to write literal */
+    CHECK,      /* i: waiting for 32-bit check value */
+    LENGTH,     /* i: waiting for 32-bit length (gzip) */
+    DONE,       /* finished check, done -- remain here until reset */
+    BAD,        /* got a data error -- remain here until reset */
+    MEM,        /* got an inflate() memory error -- remain here until reset */
+    SYNC        /* looking for synchronization bytes to restart inflate() */
+} inflate_mode;
+
+/*
+    State transitions between above modes -
+
+    (most modes can go to BAD or MEM on error -- not shown for clarity)
+
+    Process header:
+        HEAD -> (gzip) or (zlib) or (raw)
+        (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->
+                  HCRC -> TYPE
+        (zlib) -> DICTID or TYPE
+        DICTID -> DICT -> TYPE
+        (raw) -> TYPEDO
+    Read deflate blocks:
+            TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK
+            STORED -> COPY_ -> COPY -> TYPE
+            TABLE -> LENLENS -> CODELENS -> LEN_
+            LEN_ -> LEN
+    Read deflate codes in fixed or dynamic block:
+                LEN -> LENEXT or LIT or TYPE
+                LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
+                LIT -> LEN
+    Process trailer:
+        CHECK -> LENGTH -> DONE
+ */
+
+/* State maintained between inflate() calls -- approximately 7K bytes, not
+   including the allocated sliding window, which is up to 32K bytes. */
+struct inflate_state {
+    z_streamp strm;             /* pointer back to this zlib stream */
+    inflate_mode mode;          /* current inflate mode */
+    int last;                   /* true if processing last block */
+    int wrap;                   /* bit 0 true for zlib, bit 1 true for gzip,
+                                   bit 2 true to validate check value */
+    int havedict;               /* true if dictionary provided */
+    int flags;                  /* gzip header method and flags (0 if zlib) */
+    unsigned dmax;              /* zlib header max distance (INFLATE_STRICT) */
+    unsigned long check;        /* protected copy of check value */
+    unsigned long total;        /* protected copy of output count */
+    gz_headerp head;            /* where to save gzip header information */
+        /* sliding window */
+    unsigned wbits;             /* log base 2 of requested window size */
+    unsigned wsize;             /* window size or zero if not using window */
+    unsigned whave;             /* valid bytes in the window */
+    unsigned wnext;             /* window write index */
+    unsigned char FAR *window;  /* allocated sliding window, if needed */
+        /* bit accumulator */
+    unsigned long hold;         /* input bit accumulator */
+    unsigned bits;              /* number of bits in "in" */
+        /* for string and stored block copying */
+    unsigned length;            /* literal or length of data to copy */
+    unsigned offset;            /* distance back to copy string from */
+        /* for table and code decoding */
+    unsigned extra;             /* extra bits needed */
+        /* fixed and dynamic code tables */
+    code const FAR *lencode;    /* starting table for length/literal codes */
+    code const FAR *distcode;   /* starting table for distance codes */
+    unsigned lenbits;           /* index bits for lencode */
+    unsigned distbits;          /* index bits for distcode */
+        /* dynamic table building */
+    unsigned ncode;             /* number of code length code lengths */
+    unsigned nlen;              /* number of length code lengths */
+    unsigned ndist;             /* number of distance code lengths */
+    unsigned have;              /* number of code lengths in lens[] */
+    code FAR *next;             /* next available space in codes[] */
+    unsigned short lens[320];   /* temporary storage for code lengths */
+    unsigned short work[288];   /* work area for code table building */
+    code codes[ENOUGH];         /* space for code tables */
+    int sane;                   /* if false, allow invalid distance too far */
+    int back;                   /* bits back of last unprocessed length/lit */
+    unsigned was;               /* initial length of match */
+};
Index: EcnlProtoTool/trunk/zlib-1.2.11/inftrees.c
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/inftrees.c	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/inftrees.c	(revision 331)
@@ -0,0 +1,304 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2017 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#define MAXBITS 15
+
+const char inflate_copyright[] =
+   " inflate 1.2.11 Copyright 1995-2017 Mark Adler ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/*
+   Build a set of tables to decode the provided canonical Huffman code.
+   The code lengths are lens[0..codes-1].  The result starts at *table,
+   whose indices are 0..2^bits-1.  work is a writable array of at least
+   lens shorts, which is used as a work area.  type is the type of code
+   to be generated, CODES, LENS, or DISTS.  On return, zero is success,
+   -1 is an invalid code, and +1 means that ENOUGH isn't enough.  table
+   on return points to the next available entry's address.  bits is the
+   requested root table index bits, and on return it is the actual root
+   table index bits.  It will differ if the request is greater than the
+   longest code or if it is less than the shortest code.
+ */
+int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)
+codetype type;
+unsigned short FAR *lens;
+unsigned codes;
+code FAR * FAR *table;
+unsigned FAR *bits;
+unsigned short FAR *work;
+{
+    unsigned len;               /* a code's length in bits */
+    unsigned sym;               /* index of code symbols */
+    unsigned min, max;          /* minimum and maximum code lengths */
+    unsigned root;              /* number of index bits for root table */
+    unsigned curr;              /* number of index bits for current table */
+    unsigned drop;              /* code bits to drop for sub-table */
+    int left;                   /* number of prefix codes available */
+    unsigned used;              /* code entries in table used */
+    unsigned huff;              /* Huffman code */
+    unsigned incr;              /* for incrementing code, index */
+    unsigned fill;              /* index for replicating entries */
+    unsigned low;               /* low bits for current root entry */
+    unsigned mask;              /* mask for low root bits */
+    code here;                  /* table entry for duplication */
+    code FAR *next;             /* next available space in table */
+    const unsigned short FAR *base;     /* base value table to use */
+    const unsigned short FAR *extra;    /* extra bits table to use */
+    unsigned match;             /* use base and extra for symbol >= match */
+    unsigned short count[MAXBITS+1];    /* number of codes of each length */
+    unsigned short offs[MAXBITS+1];     /* offsets in table for each length */
+    static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+    static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+        16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202};
+    static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+        8193, 12289, 16385, 24577, 0, 0};
+    static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
+        16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+        23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+        28, 28, 29, 29, 64, 64};
+
+    /*
+       Process a set of code lengths to create a canonical Huffman code.  The
+       code lengths are lens[0..codes-1].  Each length corresponds to the
+       symbols 0..codes-1.  The Huffman code is generated by first sorting the
+       symbols by length from short to long, and retaining the symbol order
+       for codes with equal lengths.  Then the code starts with all zero bits
+       for the first code of the shortest length, and the codes are integer
+       increments for the same length, and zeros are appended as the length
+       increases.  For the deflate format, these bits are stored backwards
+       from their more natural integer increment ordering, and so when the
+       decoding tables are built in the large loop below, the integer codes
+       are incremented backwards.
+
+       This routine assumes, but does not check, that all of the entries in
+       lens[] are in the range 0..MAXBITS.  The caller must assure this.
+       1..MAXBITS is interpreted as that code length.  zero means that that
+       symbol does not occur in this code.
+
+       The codes are sorted by computing a count of codes for each length,
+       creating from that a table of starting indices for each length in the
+       sorted table, and then entering the symbols in order in the sorted
+       table.  The sorted table is work[], with that space being provided by
+       the caller.
+
+       The length counts are used for other purposes as well, i.e. finding
+       the minimum and maximum length codes, determining if there are any
+       codes at all, checking for a valid set of lengths, and looking ahead
+       at length counts to determine sub-table sizes when building the
+       decoding tables.
+     */
+
+    /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+    for (len = 0; len <= MAXBITS; len++)
+        count[len] = 0;
+    for (sym = 0; sym < codes; sym++)
+        count[lens[sym]]++;
+
+    /* bound code lengths, force root to be within code lengths */
+    root = *bits;
+    for (max = MAXBITS; max >= 1; max--)
+        if (count[max] != 0) break;
+    if (root > max) root = max;
+    if (max == 0) {                     /* no symbols to code at all */
+        here.op = (unsigned char)64;    /* invalid code marker */
+        here.bits = (unsigned char)1;
+        here.val = (unsigned short)0;
+        *(*table)++ = here;             /* make a table to force an error */
+        *(*table)++ = here;
+        *bits = 1;
+        return 0;     /* no symbols, but wait for decoding to report error */
+    }
+    for (min = 1; min < max; min++)
+        if (count[min] != 0) break;
+    if (root < min) root = min;
+
+    /* check for an over-subscribed or incomplete set of lengths */
+    left = 1;
+    for (len = 1; len <= MAXBITS; len++) {
+        left <<= 1;
+        left -= count[len];
+        if (left < 0) return -1;        /* over-subscribed */
+    }
+    if (left > 0 && (type == CODES || max != 1))
+        return -1;                      /* incomplete set */
+
+    /* generate offsets into symbol table for each length for sorting */
+    offs[1] = 0;
+    for (len = 1; len < MAXBITS; len++)
+        offs[len + 1] = offs[len] + count[len];
+
+    /* sort symbols by length, by symbol order within each length */
+    for (sym = 0; sym < codes; sym++)
+        if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+
+    /*
+       Create and fill in decoding tables.  In this loop, the table being
+       filled is at next and has curr index bits.  The code being used is huff
+       with length len.  That code is converted to an index by dropping drop
+       bits off of the bottom.  For codes where len is less than drop + curr,
+       those top drop + curr - len bits are incremented through all values to
+       fill the table with replicated entries.
+
+       root is the number of index bits for the root table.  When len exceeds
+       root, sub-tables are created pointed to by the root entry with an index
+       of the low root bits of huff.  This is saved in low to check for when a
+       new sub-table should be started.  drop is zero when the root table is
+       being filled, and drop is root when sub-tables are being filled.
+
+       When a new sub-table is needed, it is necessary to look ahead in the
+       code lengths to determine what size sub-table is needed.  The length
+       counts are used for this, and so count[] is decremented as codes are
+       entered in the tables.
+
+       used keeps track of how many table entries have been allocated from the
+       provided *table space.  It is checked for LENS and DIST tables against
+       the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
+       the initial root table size constants.  See the comments in inftrees.h
+       for more information.
+
+       sym increments through all symbols, and the loop terminates when
+       all codes of length max, i.e. all codes, have been processed.  This
+       routine permits incomplete codes, so another loop after this one fills
+       in the rest of the decoding tables with invalid code markers.
+     */
+
+    /* set up for code type */
+    switch (type) {
+    case CODES:
+        base = extra = work;    /* dummy value--not used */
+        match = 20;
+        break;
+    case LENS:
+        base = lbase;
+        extra = lext;
+        match = 257;
+        break;
+    default:    /* DISTS */
+        base = dbase;
+        extra = dext;
+        match = 0;
+    }
+
+    /* initialize state for loop */
+    huff = 0;                   /* starting code */
+    sym = 0;                    /* starting code symbol */
+    len = min;                  /* starting code length */
+    next = *table;              /* current table to fill in */
+    curr = root;                /* current table index bits */
+    drop = 0;                   /* current bits to drop from code for index */
+    low = (unsigned)(-1);       /* trigger new sub-table when len > root */
+    used = 1U << root;          /* use root table entries */
+    mask = used - 1;            /* mask for comparing low */
+
+    /* check available table space */
+    if ((type == LENS && used > ENOUGH_LENS) ||
+        (type == DISTS && used > ENOUGH_DISTS))
+        return 1;
+
+    /* process all codes and make table entries */
+    for (;;) {
+        /* create table entry */
+        here.bits = (unsigned char)(len - drop);
+        if (work[sym] + 1U < match) {
+            here.op = (unsigned char)0;
+            here.val = work[sym];
+        }
+        else if (work[sym] >= match) {
+            here.op = (unsigned char)(extra[work[sym] - match]);
+            here.val = base[work[sym] - match];
+        }
+        else {
+            here.op = (unsigned char)(32 + 64);         /* end of block */
+            here.val = 0;
+        }
+
+        /* replicate for those indices with low len bits equal to huff */
+        incr = 1U << (len - drop);
+        fill = 1U << curr;
+        min = fill;                 /* save offset to next table */
+        do {
+            fill -= incr;
+            next[(huff >> drop) + fill] = here;
+        } while (fill != 0);
+
+        /* backwards increment the len-bit code huff */
+        incr = 1U << (len - 1);
+        while (huff & incr)
+            incr >>= 1;
+        if (incr != 0) {
+            huff &= incr - 1;
+            huff += incr;
+        }
+        else
+            huff = 0;
+
+        /* go to next symbol, update count, len */
+        sym++;
+        if (--(count[len]) == 0) {
+            if (len == max) break;
+            len = lens[work[sym]];
+        }
+
+        /* create new sub-table if needed */
+        if (len > root && (huff & mask) != low) {
+            /* if first time, transition to sub-tables */
+            if (drop == 0)
+                drop = root;
+
+            /* increment past last table */
+            next += min;            /* here min is 1 << curr */
+
+            /* determine length of next table */
+            curr = len - drop;
+            left = (int)(1 << curr);
+            while (curr + drop < max) {
+                left -= count[curr + drop];
+                if (left <= 0) break;
+                curr++;
+                left <<= 1;
+            }
+
+            /* check for enough space */
+            used += 1U << curr;
+            if ((type == LENS && used > ENOUGH_LENS) ||
+                (type == DISTS && used > ENOUGH_DISTS))
+                return 1;
+
+            /* point entry in root table to sub-table */
+            low = huff & mask;
+            (*table)[low].op = (unsigned char)curr;
+            (*table)[low].bits = (unsigned char)root;
+            (*table)[low].val = (unsigned short)(next - *table);
+        }
+    }
+
+    /* fill in remaining table entry if code is incomplete (guaranteed to have
+       at most one remaining entry, since if the code is incomplete, the
+       maximum code length that was allowed to get this far is one bit) */
+    if (huff != 0) {
+        here.op = (unsigned char)64;            /* invalid code marker */
+        here.bits = (unsigned char)(len - drop);
+        here.val = (unsigned short)0;
+        next[huff] = here;
+    }
+
+    /* set return parameters */
+    *table += used;
+    *bits = root;
+    return 0;
+}
Index: EcnlProtoTool/trunk/zlib-1.2.11/inftrees.h
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/inftrees.h	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/inftrees.h	(revision 331)
@@ -0,0 +1,62 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2005, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* Structure for decoding tables.  Each entry provides either the
+   information needed to do the operation requested by the code that
+   indexed that table entry, or it provides a pointer to another
+   table that indexes more bits of the code.  op indicates whether
+   the entry is a pointer to another table, a literal, a length or
+   distance, an end-of-block, or an invalid code.  For a table
+   pointer, the low four bits of op is the number of index bits of
+   that table.  For a length or distance, the low four bits of op
+   is the number of extra bits to get after the code.  bits is
+   the number of bits in this code or part of the code to drop off
+   of the bit buffer.  val is the actual byte to output in the case
+   of a literal, the base length or distance, or the offset from
+   the current table to the next table.  Each entry is four bytes. */
+typedef struct {
+    unsigned char op;           /* operation, extra bits, table bits */
+    unsigned char bits;         /* bits in this part of the code */
+    unsigned short val;         /* offset in table or code value */
+} code;
+
+/* op values as set by inflate_table():
+    00000000 - literal
+    0000tttt - table link, tttt != 0 is the number of table index bits
+    0001eeee - length or distance, eeee is the number of extra bits
+    01100000 - end of block
+    01000000 - invalid code
+ */
+
+/* Maximum size of the dynamic table.  The maximum number of code structures is
+   1444, which is the sum of 852 for literal/length codes and 592 for distance
+   codes.  These values were found by exhaustive searches using the program
+   examples/enough.c found in the zlib distribtution.  The arguments to that
+   program are the number of symbols, the initial root table size, and the
+   maximum bit length of a code.  "enough 286 9 15" for literal/length codes
+   returns returns 852, and "enough 30 6 15" for distance codes returns 592.
+   The initial root table size (9 or 6) is found in the fifth argument of the
+   inflate_table() calls in inflate.c and infback.c.  If the root table size is
+   changed, then these maximum sizes would be need to be recalculated and
+   updated. */
+#define ENOUGH_LENS 852
+#define ENOUGH_DISTS 592
+#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
+
+/* Type of code to build for inflate_table() */
+typedef enum {
+    CODES,
+    LENS,
+    DISTS
+} codetype;
+
+int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
+                             unsigned codes, code FAR * FAR *table,
+                             unsigned FAR *bits, unsigned short FAR *work));
Index: EcnlProtoTool/trunk/zlib-1.2.11/make_vms.com
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/make_vms.com	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/make_vms.com	(revision 331)
@@ -0,0 +1,867 @@
+$! make libz under VMS written by
+$! Martin P.J. Zinser
+$!
+$! In case of problems with the install you might contact me at
+$! zinser@zinser.no-ip.info(preferred) or
+$! martin.zinser@eurexchange.com (work)
+$!
+$! Make procedure history for Zlib
+$!
+$!------------------------------------------------------------------------------
+$! Version history
+$! 0.01 20060120 First version to receive a number
+$! 0.02 20061008 Adapt to new Makefile.in
+$! 0.03 20091224 Add support for large file check
+$! 0.04 20100110 Add new gzclose, gzlib, gzread, gzwrite
+$! 0.05 20100221 Exchange zlibdefs.h by zconf.h.in
+$! 0.06 20120111 Fix missing amiss_err, update zconf_h.in, fix new exmples
+$!               subdir path, update module search in makefile.in
+$! 0.07 20120115 Triggered by work done by Alexey Chupahin completly redesigned
+$!               shared image creation
+$! 0.08 20120219 Make it work on VAX again, pre-load missing symbols to shared
+$!               image
+$! 0.09 20120305 SMS.  P1 sets builder ("MMK", "MMS", " " (built-in)).
+$!               "" -> automatic, preference: MMK, MMS, built-in.
+$!
+$ on error then goto err_exit
+$!
+$ true  = 1
+$ false = 0
+$ tmpnam = "temp_" + f$getjpi("","pid")
+$ tt = tmpnam + ".txt"
+$ tc = tmpnam + ".c"
+$ th = tmpnam + ".h"
+$ define/nolog tconfig 'th'
+$ its_decc = false
+$ its_vaxc = false
+$ its_gnuc = false
+$ s_case   = False
+$!
+$! Setup variables holding "config" information
+$!
+$ Make    = "''p1'"
+$ name     = "Zlib"
+$ version  = "?.?.?"
+$ v_string = "ZLIB_VERSION"
+$ v_file   = "zlib.h"
+$ ccopt   = "/include = []"
+$ lopts   = ""
+$ dnsrl   = ""
+$ aconf_in_file = "zconf.h.in#zconf.h_in#zconf_h.in"
+$ conf_check_string = ""
+$ linkonly = false
+$ optfile  = name + ".opt"
+$ mapfile  = name + ".map"
+$ libdefs  = ""
+$ vax      = f$getsyi("HW_MODEL").lt.1024
+$ axp      = f$getsyi("HW_MODEL").ge.1024 .and. f$getsyi("HW_MODEL").lt.4096
+$ ia64     = f$getsyi("HW_MODEL").ge.4096
+$!
+$! 2012-03-05 SMS.
+$! Why is this needed?  And if it is needed, why not simply ".not. vax"?
+$!
+$!!! if axp .or. ia64 then  set proc/parse=extended
+$!
+$ whoami = f$parse(f$environment("Procedure"),,,,"NO_CONCEAL")
+$ mydef  = F$parse(whoami,,,"DEVICE")
+$ mydir  = f$parse(whoami,,,"DIRECTORY") - "]["
+$ myproc = f$parse(whoami,,,"Name") + f$parse(whoami,,,"type")
+$!
+$! Check for MMK/MMS
+$!
+$ if (Make .eqs. "")
+$ then
+$   If F$Search ("Sys$System:MMS.EXE") .nes. "" Then Make = "MMS"
+$   If F$Type (MMK) .eqs. "STRING" Then Make = "MMK"
+$ else
+$   Make = f$edit( Make, "trim")
+$ endif
+$!
+$ gosub find_version
+$!
+$  open/write topt tmp.opt
+$  open/write optf 'optfile'
+$!
+$ gosub check_opts
+$!
+$! Look for the compiler used
+$!
+$ gosub check_compiler
+$ close topt
+$ close optf
+$!
+$ if its_decc
+$ then
+$   ccopt = "/prefix=all" + ccopt
+$   if f$trnlnm("SYS") .eqs. ""
+$   then
+$     if axp
+$     then
+$       define sys sys$library:
+$     else
+$       ccopt = "/decc" + ccopt
+$       define sys decc$library_include:
+$     endif
+$   endif
+$!
+$! 2012-03-05 SMS.
+$! Why /NAMES = AS_IS?  Why not simply ".not. vax"?  And why not on VAX?
+$!
+$   if axp .or. ia64
+$   then
+$       ccopt = ccopt + "/name=as_is/opt=(inline=speed)"
+$       s_case = true
+$   endif
+$ endif
+$ if its_vaxc .or. its_gnuc
+$ then
+$    if f$trnlnm("SYS").eqs."" then define sys sys$library:
+$ endif
+$!
+$! Build a fake configure input header
+$!
+$ open/write conf_hin config.hin
+$ write conf_hin "#undef _LARGEFILE64_SOURCE"
+$ close conf_hin
+$!
+$!
+$ i = 0
+$FIND_ACONF:
+$ fname = f$element(i,"#",aconf_in_file)
+$ if fname .eqs. "#" then goto AMISS_ERR
+$ if f$search(fname) .eqs. ""
+$ then
+$   i = i + 1
+$   goto find_aconf
+$ endif
+$ open/read/err=aconf_err aconf_in 'fname'
+$ open/write aconf zconf.h
+$ACONF_LOOP:
+$ read/end_of_file=aconf_exit aconf_in line
+$ work = f$edit(line, "compress,trim")
+$ if f$extract(0,6,work) .nes. "#undef"
+$ then
+$   if f$extract(0,12,work) .nes. "#cmakedefine"
+$   then
+$       write aconf line
+$   endif
+$ else
+$   cdef = f$element(1," ",work)
+$   gosub check_config
+$ endif
+$ goto aconf_loop
+$ACONF_EXIT:
+$ write aconf ""
+$ write aconf "/* VMS specifics added by make_vms.com: */"
+$ write aconf "#define VMS 1"
+$ write aconf "#include <unistd.h>"
+$ write aconf "#include <unixio.h>"
+$ write aconf "#ifdef _LARGEFILE"
+$ write aconf "# define off64_t __off64_t"
+$ write aconf "# define fopen64 fopen"
+$ write aconf "# define fseeko64 fseeko"
+$ write aconf "# define lseek64 lseek"
+$ write aconf "# define ftello64 ftell"
+$ write aconf "#endif"
+$ write aconf "#if !defined( __VAX) && (__CRTL_VER >= 70312000)"
+$ write aconf "# define HAVE_VSNPRINTF"
+$ write aconf "#endif"
+$ close aconf_in
+$ close aconf
+$ if f$search("''th'") .nes. "" then delete 'th';*
+$! Build the thing plain or with mms
+$!
+$ write sys$output "Compiling Zlib sources ..."
+$ if make.eqs.""
+$ then
+$   if (f$search( "example.obj;*") .nes. "") then delete example.obj;*
+$   if (f$search( "minigzip.obj;*") .nes. "") then delete minigzip.obj;*
+$   CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" -
+                adler32.c zlib.h zconf.h
+$   CALL MAKE compress.OBJ "CC ''CCOPT' compress" -
+                compress.c zlib.h zconf.h
+$   CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" -
+                crc32.c zlib.h zconf.h
+$   CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" -
+                deflate.c deflate.h zutil.h zlib.h zconf.h
+$   CALL MAKE gzclose.OBJ "CC ''CCOPT' gzclose" -
+                gzclose.c zutil.h zlib.h zconf.h
+$   CALL MAKE gzlib.OBJ "CC ''CCOPT' gzlib" -
+                gzlib.c zutil.h zlib.h zconf.h
+$   CALL MAKE gzread.OBJ "CC ''CCOPT' gzread" -
+                gzread.c zutil.h zlib.h zconf.h
+$   CALL MAKE gzwrite.OBJ "CC ''CCOPT' gzwrite" -
+                gzwrite.c zutil.h zlib.h zconf.h
+$   CALL MAKE infback.OBJ "CC ''CCOPT' infback" -
+                infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h
+$   CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" -
+                inffast.c zutil.h zlib.h zconf.h inffast.h
+$   CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" -
+                inflate.c zutil.h zlib.h zconf.h infblock.h
+$   CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" -
+                inftrees.c zutil.h zlib.h zconf.h inftrees.h
+$   CALL MAKE trees.OBJ "CC ''CCOPT' trees" -
+                trees.c deflate.h zutil.h zlib.h zconf.h
+$   CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" -
+                uncompr.c zlib.h zconf.h
+$   CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" -
+                zutil.c zutil.h zlib.h zconf.h
+$   write sys$output "Building Zlib ..."
+$   CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ
+$   write sys$output "Building example..."
+$   CALL MAKE example.OBJ "CC ''CCOPT' [.test]example" -
+                [.test]example.c zlib.h zconf.h
+$   call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb
+$   write sys$output "Building minigzip..."
+$   CALL MAKE minigzip.OBJ "CC ''CCOPT' [.test]minigzip" -
+              [.test]minigzip.c zlib.h zconf.h
+$   call make minigzip.exe -
+              "LINK minigzip,libz.olb/lib" -
+              minigzip.obj libz.olb
+$ else
+$   gosub crea_mms
+$   write sys$output "Make ''name' ''version' with ''Make' "
+$   'make'
+$ endif
+$!
+$! Create shareable image
+$!
+$ gosub crea_olist
+$ write sys$output "Creating libzshr.exe"
+$ call map_2_shopt 'mapfile' 'optfile'
+$ LINK_'lopts'/SHARE=libzshr.exe modules.opt/opt,'optfile'/opt
+$ write sys$output "Zlib build completed"
+$ delete/nolog tmp.opt;*
+$ exit
+$AMISS_ERR:
+$ write sys$output "No source for config.hin found."
+$ write sys$output "Tried any of ''aconf_in_file'"
+$ goto err_exit
+$CC_ERR:
+$ write sys$output "C compiler required to build ''name'"
+$ goto err_exit
+$ERR_EXIT:
+$ set message/facil/ident/sever/text
+$ close/nolog optf
+$ close/nolog topt
+$ close/nolog aconf_in
+$ close/nolog aconf
+$ close/nolog out
+$ close/nolog min
+$ close/nolog mod
+$ close/nolog h_in
+$ write sys$output "Exiting..."
+$ exit 2
+$!
+$!
+$MAKE: SUBROUTINE   !SUBROUTINE TO CHECK DEPENDENCIES
+$ V = 'F$Verify(0)
+$! P1 = What we are trying to make
+$! P2 = Command to make it
+$! P3 - P8  What it depends on
+$
+$ If F$Search(P1) .Eqs. "" Then Goto Makeit
+$ Time = F$CvTime(F$File(P1,"RDT"))
+$arg=3
+$Loop:
+$       Argument = P'arg
+$       If Argument .Eqs. "" Then Goto Exit
+$       El=0
+$Loop2:
+$       File = F$Element(El," ",Argument)
+$       If File .Eqs. " " Then Goto Endl
+$       AFile = ""
+$Loop3:
+$       OFile = AFile
+$       AFile = F$Search(File)
+$       If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl
+$       If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit
+$       Goto Loop3
+$NextEL:
+$       El = El + 1
+$       Goto Loop2
+$EndL:
+$ arg=arg+1
+$ If arg .Le. 8 Then Goto Loop
+$ Goto Exit
+$
+$Makeit:
+$ VV=F$VERIFY(0)
+$ write sys$output P2
+$ 'P2
+$ VV='F$Verify(VV)
+$Exit:
+$ If V Then Set Verify
+$ENDSUBROUTINE
+$!------------------------------------------------------------------------------
+$!
+$! Check command line options and set symbols accordingly
+$!
+$!------------------------------------------------------------------------------
+$! Version history
+$! 0.01 20041206 First version to receive a number
+$! 0.02 20060126 Add new "HELP" target
+$ CHECK_OPTS:
+$ i = 1
+$ OPT_LOOP:
+$ if i .lt. 9
+$ then
+$   cparm = f$edit(p'i',"upcase")
+$!
+$! Check if parameter actually contains something
+$!
+$   if f$edit(cparm,"trim") .nes. ""
+$   then
+$     if cparm .eqs. "DEBUG"
+$     then
+$       ccopt = ccopt + "/noopt/deb"
+$       lopts = lopts + "/deb"
+$     endif
+$     if f$locate("CCOPT=",cparm) .lt. f$length(cparm)
+$     then
+$       start = f$locate("=",cparm) + 1
+$       len   = f$length(cparm) - start
+$       ccopt = ccopt + f$extract(start,len,cparm)
+$       if f$locate("AS_IS",f$edit(ccopt,"UPCASE")) .lt. f$length(ccopt) -
+          then s_case = true
+$     endif
+$     if cparm .eqs. "LINK" then linkonly = true
+$     if f$locate("LOPTS=",cparm) .lt. f$length(cparm)
+$     then
+$       start = f$locate("=",cparm) + 1
+$       len   = f$length(cparm) - start
+$       lopts = lopts + f$extract(start,len,cparm)
+$     endif
+$     if f$locate("CC=",cparm) .lt. f$length(cparm)
+$     then
+$       start  = f$locate("=",cparm) + 1
+$       len    = f$length(cparm) - start
+$       cc_com = f$extract(start,len,cparm)
+        if (cc_com .nes. "DECC") .and. -
+           (cc_com .nes. "VAXC") .and. -
+           (cc_com .nes. "GNUC")
+$       then
+$         write sys$output "Unsupported compiler choice ''cc_com' ignored"
+$         write sys$output "Use DECC, VAXC, or GNUC instead"
+$       else
+$         if cc_com .eqs. "DECC" then its_decc = true
+$         if cc_com .eqs. "VAXC" then its_vaxc = true
+$         if cc_com .eqs. "GNUC" then its_gnuc = true
+$       endif
+$     endif
+$     if f$locate("MAKE=",cparm) .lt. f$length(cparm)
+$     then
+$       start  = f$locate("=",cparm) + 1
+$       len    = f$length(cparm) - start
+$       mmks = f$extract(start,len,cparm)
+$       if (mmks .eqs. "MMK") .or. (mmks .eqs. "MMS")
+$       then
+$         make = mmks
+$       else
+$         write sys$output "Unsupported make choice ''mmks' ignored"
+$         write sys$output "Use MMK or MMS instead"
+$       endif
+$     endif
+$     if cparm .eqs. "HELP" then gosub bhelp
+$   endif
+$   i = i + 1
+$   goto opt_loop
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Look for the compiler used
+$!
+$! Version history
+$! 0.01 20040223 First version to receive a number
+$! 0.02 20040229 Save/set value of decc$no_rooted_search_lists
+$! 0.03 20060202 Extend handling of GNU C
+$! 0.04 20090402 Compaq -> hp
+$CHECK_COMPILER:
+$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc))
+$ then
+$   its_decc = (f$search("SYS$SYSTEM:DECC$COMPILER.EXE") .nes. "")
+$   its_vaxc = .not. its_decc .and. (F$Search("SYS$System:VAXC.Exe") .nes. "")
+$   its_gnuc = .not. (its_decc .or. its_vaxc) .and. (f$trnlnm("gnu_cc") .nes. "")
+$ endif
+$!
+$! Exit if no compiler available
+$!
+$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc))
+$ then goto CC_ERR
+$ else
+$   if its_decc
+$   then
+$     write sys$output "CC compiler check ... hp C"
+$     if f$trnlnm("decc$no_rooted_search_lists") .nes. ""
+$     then
+$       dnrsl = f$trnlnm("decc$no_rooted_search_lists")
+$     endif
+$     define/nolog decc$no_rooted_search_lists 1
+$   else
+$     if its_vaxc then write sys$output "CC compiler check ... VAX C"
+$     if its_gnuc
+$     then
+$         write sys$output "CC compiler check ... GNU C"
+$         if f$trnlnm(topt) then write topt "gnu_cc:[000000]gcclib.olb/lib"
+$         if f$trnlnm(optf) then write optf "gnu_cc:[000000]gcclib.olb/lib"
+$         cc = "gcc"
+$     endif
+$     if f$trnlnm(topt) then write topt "sys$share:vaxcrtl.exe/share"
+$     if f$trnlnm(optf) then write optf "sys$share:vaxcrtl.exe/share"
+$   endif
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! If MMS/MMK are available dump out the descrip.mms if required
+$!
+$CREA_MMS:
+$ write sys$output "Creating descrip.mms..."
+$ create descrip.mms
+$ open/append out descrip.mms
+$ copy sys$input: out
+$ deck
+# descrip.mms: MMS description file for building zlib on VMS
+# written by Martin P.J. Zinser
+# <zinser@zinser.no-ip.info or martin.zinser@eurexchange.com>
+
+OBJS = adler32.obj, compress.obj, crc32.obj, gzclose.obj, gzlib.obj\
+       gzread.obj, gzwrite.obj, uncompr.obj, infback.obj\
+       deflate.obj, trees.obj, zutil.obj, inflate.obj, \
+       inftrees.obj, inffast.obj
+
+$ eod
+$ write out "CFLAGS=", ccopt
+$ write out "LOPTS=", lopts
+$ write out "all : example.exe minigzip.exe libz.olb"
+$ copy sys$input: out
+$ deck
+        @ write sys$output " Example applications available"
+
+libz.olb : libz.olb($(OBJS))
+	@ write sys$output " libz available"
+
+example.exe : example.obj libz.olb
+              link $(LOPTS) example,libz.olb/lib
+
+minigzip.exe : minigzip.obj libz.olb
+              link $(LOPTS) minigzip,libz.olb/lib
+
+clean :
+	delete *.obj;*,libz.olb;*,*.opt;*,*.exe;*
+
+
+# Other dependencies.
+adler32.obj  : adler32.c zutil.h zlib.h zconf.h
+compress.obj : compress.c zlib.h zconf.h
+crc32.obj    : crc32.c zutil.h zlib.h zconf.h
+deflate.obj  : deflate.c deflate.h zutil.h zlib.h zconf.h
+example.obj  : [.test]example.c zlib.h zconf.h
+gzclose.obj  : gzclose.c zutil.h zlib.h zconf.h
+gzlib.obj    : gzlib.c zutil.h zlib.h zconf.h
+gzread.obj   : gzread.c zutil.h zlib.h zconf.h
+gzwrite.obj  : gzwrite.c zutil.h zlib.h zconf.h
+inffast.obj  : inffast.c zutil.h zlib.h zconf.h inftrees.h inffast.h
+inflate.obj  : inflate.c zutil.h zlib.h zconf.h
+inftrees.obj : inftrees.c zutil.h zlib.h zconf.h inftrees.h
+minigzip.obj : [.test]minigzip.c zlib.h zconf.h
+trees.obj    : trees.c deflate.h zutil.h zlib.h zconf.h
+uncompr.obj  : uncompr.c zlib.h zconf.h
+zutil.obj    : zutil.c zutil.h zlib.h zconf.h
+infback.obj  : infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h
+$ eod
+$ close out
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Read list of core library sources from makefile.in and create options
+$! needed to build shareable image
+$!
+$CREA_OLIST:
+$ open/read min makefile.in
+$ open/write mod modules.opt
+$ src_check_list = "OBJZ =#OBJG ="
+$MRLOOP:
+$ read/end=mrdone min rec
+$ i = 0
+$SRC_CHECK_LOOP:
+$ src_check = f$element(i, "#", src_check_list)
+$ i = i+1
+$ if src_check .eqs. "#" then goto mrloop
+$ if (f$extract(0,6,rec) .nes. src_check) then goto src_check_loop
+$ rec = rec - src_check
+$ gosub extra_filnam
+$ if (f$element(1,"\",rec) .eqs. "\") then goto mrloop
+$MRSLOOP:
+$ read/end=mrdone min rec
+$ gosub extra_filnam
+$ if (f$element(1,"\",rec) .nes. "\") then goto mrsloop
+$MRDONE:
+$ close min
+$ close mod
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Take record extracted in crea_olist and split it into single filenames
+$!
+$EXTRA_FILNAM:
+$ myrec = f$edit(rec - "\", "trim,compress")
+$ i = 0
+$FELOOP:
+$ srcfil = f$element(i," ", myrec)
+$ if (srcfil .nes. " ")
+$ then
+$   write mod f$parse(srcfil,,,"NAME"), ".obj"
+$   i = i + 1
+$   goto feloop
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Find current Zlib version number
+$!
+$FIND_VERSION:
+$ open/read h_in 'v_file'
+$hloop:
+$ read/end=hdone h_in rec
+$ rec = f$edit(rec,"TRIM")
+$ if (f$extract(0,1,rec) .nes. "#") then goto hloop
+$ rec = f$edit(rec - "#", "TRIM")
+$ if f$element(0," ",rec) .nes. "define" then goto hloop
+$ if f$element(1," ",rec) .eqs. v_string
+$ then
+$   version = 'f$element(2," ",rec)'
+$   goto hdone
+$ endif
+$ goto hloop
+$hdone:
+$ close h_in
+$ return
+$!------------------------------------------------------------------------------
+$!
+$CHECK_CONFIG:
+$!
+$ in_ldef = f$locate(cdef,libdefs)
+$ if (in_ldef .lt. f$length(libdefs))
+$ then
+$   write aconf "#define ''cdef' 1"
+$   libdefs = f$extract(0,in_ldef,libdefs) + -
+              f$extract(in_ldef + f$length(cdef) + 1, -
+                        f$length(libdefs) - in_ldef - f$length(cdef) - 1, -
+                        libdefs)
+$ else
+$   if (f$type('cdef') .eqs. "INTEGER")
+$   then
+$     write aconf "#define ''cdef' ", 'cdef'
+$   else
+$     if (f$type('cdef') .eqs. "STRING")
+$     then
+$       write aconf "#define ''cdef' ", """", '''cdef'', """"
+$     else
+$       gosub check_cc_def
+$     endif
+$   endif
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Check if this is a define relating to the properties of the C/C++
+$! compiler
+$!
+$ CHECK_CC_DEF:
+$ if (cdef .eqs. "_LARGEFILE64_SOURCE")
+$ then
+$   copy sys$input: 'tc'
+$   deck
+#include "tconfig"
+#define _LARGEFILE
+#include <stdio.h>
+
+int main(){
+FILE *fp;
+  fp = fopen("temp.txt","r");
+  fseeko(fp,1,SEEK_SET);
+  fclose(fp);
+}
+
+$   eod
+$   test_inv = false
+$   comm_h = false
+$   gosub cc_prop_check
+$   return
+$ endif
+$ write aconf "/* ", line, " */"
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Check for properties of C/C++ compiler
+$!
+$! Version history
+$! 0.01 20031020 First version to receive a number
+$! 0.02 20031022 Added logic for defines with value
+$! 0.03 20040309 Make sure local config file gets not deleted
+$! 0.04 20041230 Also write include for configure run
+$! 0.05 20050103 Add processing of "comment defines"
+$CC_PROP_CHECK:
+$ cc_prop = true
+$ is_need = false
+$ is_need = (f$extract(0,4,cdef) .eqs. "NEED") .or. (test_inv .eq. true)
+$ if f$search(th) .eqs. "" then create 'th'
+$ set message/nofac/noident/nosever/notext
+$ on error then continue
+$ cc 'tmpnam'
+$ if .not. ($status)  then cc_prop = false
+$ on error then continue
+$! The headers might lie about the capabilities of the RTL
+$ link 'tmpnam',tmp.opt/opt
+$ if .not. ($status)  then cc_prop = false
+$ set message/fac/ident/sever/text
+$ on error then goto err_exit
+$ delete/nolog 'tmpnam'.*;*/exclude='th'
+$ if (cc_prop .and. .not. is_need) .or. -
+     (.not. cc_prop .and. is_need)
+$ then
+$   write sys$output "Checking for ''cdef'... yes"
+$   if f$type('cdef_val'_yes) .nes. ""
+$   then
+$     if f$type('cdef_val'_yes) .eqs. "INTEGER" -
+         then call write_config f$fao("#define !AS !UL",cdef,'cdef_val'_yes)
+$     if f$type('cdef_val'_yes) .eqs. "STRING" -
+         then call write_config f$fao("#define !AS !AS",cdef,'cdef_val'_yes)
+$   else
+$     call write_config f$fao("#define !AS 1",cdef)
+$   endif
+$   if (cdef .eqs. "HAVE_FSEEKO") .or. (cdef .eqs. "_LARGE_FILES") .or. -
+       (cdef .eqs. "_LARGEFILE64_SOURCE") then -
+      call write_config f$string("#define _LARGEFILE 1")
+$ else
+$   write sys$output "Checking for ''cdef'... no"
+$   if (comm_h)
+$   then
+      call write_config f$fao("/* !AS */",line)
+$   else
+$     if f$type('cdef_val'_no) .nes. ""
+$     then
+$       if f$type('cdef_val'_no) .eqs. "INTEGER" -
+           then call write_config f$fao("#define !AS !UL",cdef,'cdef_val'_no)
+$       if f$type('cdef_val'_no) .eqs. "STRING" -
+           then call write_config f$fao("#define !AS !AS",cdef,'cdef_val'_no)
+$     else
+$       call write_config f$fao("#undef !AS",cdef)
+$     endif
+$   endif
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Check for properties of C/C++ compiler with multiple result values
+$!
+$! Version history
+$! 0.01 20040127 First version
+$! 0.02 20050103 Reconcile changes from cc_prop up to version 0.05
+$CC_MPROP_CHECK:
+$ cc_prop = true
+$ i    = 1
+$ idel = 1
+$ MT_LOOP:
+$ if f$type(result_'i') .eqs. "STRING"
+$ then
+$   set message/nofac/noident/nosever/notext
+$   on error then continue
+$   cc 'tmpnam'_'i'
+$   if .not. ($status)  then cc_prop = false
+$   on error then continue
+$! The headers might lie about the capabilities of the RTL
+$   link 'tmpnam'_'i',tmp.opt/opt
+$   if .not. ($status)  then cc_prop = false
+$   set message/fac/ident/sever/text
+$   on error then goto err_exit
+$   delete/nolog 'tmpnam'_'i'.*;*
+$   if (cc_prop)
+$   then
+$     write sys$output "Checking for ''cdef'... ", mdef_'i'
+$     if f$type(mdef_'i') .eqs. "INTEGER" -
+         then call write_config f$fao("#define !AS !UL",cdef,mdef_'i')
+$     if f$type('cdef_val'_yes) .eqs. "STRING" -
+         then call write_config f$fao("#define !AS !AS",cdef,mdef_'i')
+$     goto msym_clean
+$   else
+$     i = i + 1
+$     goto mt_loop
+$   endif
+$ endif
+$ write sys$output "Checking for ''cdef'... no"
+$ call write_config f$fao("#undef !AS",cdef)
+$ MSYM_CLEAN:
+$ if (idel .le. msym_max)
+$ then
+$   delete/sym mdef_'idel'
+$   idel = idel + 1
+$   goto msym_clean
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Write configuration to both permanent and temporary config file
+$!
+$! Version history
+$! 0.01 20031029 First version to receive a number
+$!
+$WRITE_CONFIG: SUBROUTINE
+$  write aconf 'p1'
+$  open/append confh 'th'
+$  write confh 'p1'
+$  close confh
+$ENDSUBROUTINE
+$!------------------------------------------------------------------------------
+$!
+$! Analyze the project map file and create the symbol vector for a shareable
+$! image from it
+$!
+$! Version history
+$! 0.01 20120128 First version
+$! 0.02 20120226 Add pre-load logic
+$!
+$ MAP_2_SHOPT: Subroutine
+$!
+$ SAY := "WRITE_ SYS$OUTPUT"
+$!
+$ IF F$SEARCH("''P1'") .EQS. ""
+$ THEN
+$    SAY "MAP_2_SHOPT-E-NOSUCHFILE:  Error, inputfile ''p1' not available"
+$    goto exit_m2s
+$ ENDIF
+$ IF "''P2'" .EQS. ""
+$ THEN
+$    SAY "MAP_2_SHOPT:  Error, no output file provided"
+$    goto exit_m2s
+$ ENDIF
+$!
+$ module1 = "deflate#deflateEnd#deflateInit_#deflateParams#deflateSetDictionary"
+$ module2 = "gzclose#gzerror#gzgetc#gzgets#gzopen#gzprintf#gzputc#gzputs#gzread"
+$ module3 = "gzseek#gztell#inflate#inflateEnd#inflateInit_#inflateSetDictionary"
+$ module4 = "inflateSync#uncompress#zlibVersion#compress"
+$ open/read map 'p1
+$ if axp .or. ia64
+$ then
+$     open/write aopt a.opt
+$     open/write bopt b.opt
+$     write aopt " CASE_SENSITIVE=YES"
+$     write bopt "SYMBOL_VECTOR= (-"
+$     mod_sym_num = 1
+$ MOD_SYM_LOOP:
+$     if f$type(module'mod_sym_num') .nes. ""
+$     then
+$         mod_in = 0
+$ MOD_SYM_IN:
+$         shared_proc = f$element(mod_in, "#", module'mod_sym_num')
+$         if shared_proc .nes. "#"
+$         then
+$             write aopt f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)",-
+        		       f$edit(shared_proc,"upcase"),shared_proc)
+$             write bopt f$fao("!AS=PROCEDURE,-",shared_proc)
+$             mod_in = mod_in + 1
+$             goto mod_sym_in
+$         endif
+$         mod_sym_num = mod_sym_num + 1
+$         goto mod_sym_loop
+$     endif
+$MAP_LOOP:
+$     read/end=map_end map line
+$     if (f$locate("{",line).lt. f$length(line)) .or. -
+         (f$locate("global:", line) .lt. f$length(line))
+$     then
+$         proc = true
+$         goto map_loop
+$     endif
+$     if f$locate("}",line).lt. f$length(line) then proc = false
+$     if f$locate("local:", line) .lt. f$length(line) then proc = false
+$     if proc
+$     then
+$         shared_proc = f$edit(line,"collapse")
+$         chop_semi = f$locate(";", shared_proc)
+$         if chop_semi .lt. f$length(shared_proc) then -
+              shared_proc = f$extract(0, chop_semi, shared_proc)
+$         write aopt f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)",-
+        			 f$edit(shared_proc,"upcase"),shared_proc)
+$         write bopt f$fao("!AS=PROCEDURE,-",shared_proc)
+$     endif
+$     goto map_loop
+$MAP_END:
+$     close/nolog aopt
+$     close/nolog bopt
+$     open/append libopt 'p2'
+$     open/read aopt a.opt
+$     open/read bopt b.opt
+$ALOOP:
+$     read/end=aloop_end aopt line
+$     write libopt line
+$     goto aloop
+$ALOOP_END:
+$     close/nolog aopt
+$     sv = ""
+$BLOOP:
+$     read/end=bloop_end bopt svn
+$     if (svn.nes."")
+$     then
+$        if (sv.nes."") then write libopt sv
+$        sv = svn
+$     endif
+$     goto bloop
+$BLOOP_END:
+$     write libopt f$extract(0,f$length(sv)-2,sv), "-"
+$     write libopt ")"
+$     close/nolog bopt
+$     delete/nolog/noconf a.opt;*,b.opt;*
+$ else
+$     if vax
+$     then
+$     open/append libopt 'p2'
+$     mod_sym_num = 1
+$ VMOD_SYM_LOOP:
+$     if f$type(module'mod_sym_num') .nes. ""
+$     then
+$         mod_in = 0
+$ VMOD_SYM_IN:
+$         shared_proc = f$element(mod_in, "#", module'mod_sym_num')
+$         if shared_proc .nes. "#"
+$         then
+$     	      write libopt f$fao("UNIVERSAL=!AS",-
+      	  			     f$edit(shared_proc,"upcase"))
+$             mod_in = mod_in + 1
+$             goto vmod_sym_in
+$         endif
+$         mod_sym_num = mod_sym_num + 1
+$         goto vmod_sym_loop
+$     endif
+$VMAP_LOOP:
+$     	  read/end=vmap_end map line
+$     	  if (f$locate("{",line).lt. f$length(line)) .or. -
+   	      (f$locate("global:", line) .lt. f$length(line))
+$     	  then
+$     	      proc = true
+$     	      goto vmap_loop
+$     	  endif
+$     	  if f$locate("}",line).lt. f$length(line) then proc = false
+$     	  if f$locate("local:", line) .lt. f$length(line) then proc = false
+$     	  if proc
+$     	  then
+$     	      shared_proc = f$edit(line,"collapse")
+$     	      chop_semi = f$locate(";", shared_proc)
+$     	      if chop_semi .lt. f$length(shared_proc) then -
+      	  	  shared_proc = f$extract(0, chop_semi, shared_proc)
+$     	      write libopt f$fao("UNIVERSAL=!AS",-
+      	  			     f$edit(shared_proc,"upcase"))
+$     	  endif
+$     	  goto vmap_loop
+$VMAP_END:
+$     else
+$         write sys$output "Unknown Architecture (Not VAX, AXP, or IA64)"
+$         write sys$output "No options file created"
+$     endif
+$ endif
+$ EXIT_M2S:
+$ close/nolog map
+$ close/nolog libopt
+$ endsubroutine
Index: EcnlProtoTool/trunk/zlib-1.2.11/test/example.c
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/test/example.c	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/test/example.c	(revision 331)
@@ -0,0 +1,602 @@
+/* example.c -- usage example of the zlib compression library
+ * Copyright (C) 1995-2006, 2011, 2016 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zlib.h"
+#include <stdio.h>
+
+#ifdef STDC
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+
+#if defined(VMS) || defined(RISCOS)
+#  define TESTFILE "foo-gz"
+#else
+#  define TESTFILE "foo.gz"
+#endif
+
+#define CHECK_ERR(err, msg) { \
+    if (err != Z_OK) { \
+        fprintf(stderr, "%s error: %d\n", msg, err); \
+        exit(1); \
+    } \
+}
+
+static z_const char hello[] = "hello, hello!";
+/* "hello world" would be more standard, but the repeated "hello"
+ * stresses the compression code better, sorry...
+ */
+
+static const char dictionary[] = "hello";
+static uLong dictId;    /* Adler32 value of the dictionary */
+
+void test_deflate       OF((Byte *compr, uLong comprLen));
+void test_inflate       OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+void test_large_deflate OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+void test_large_inflate OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+void test_flush         OF((Byte *compr, uLong *comprLen));
+void test_sync          OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+void test_dict_deflate  OF((Byte *compr, uLong comprLen));
+void test_dict_inflate  OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+int  main               OF((int argc, char *argv[]));
+
+
+#ifdef Z_SOLO
+
+void *myalloc OF((void *, unsigned, unsigned));
+void myfree OF((void *, void *));
+
+void *myalloc(q, n, m)
+    void *q;
+    unsigned n, m;
+{
+    (void)q;
+    return calloc(n, m);
+}
+
+void myfree(void *q, void *p)
+{
+    (void)q;
+    free(p);
+}
+
+static alloc_func zalloc = myalloc;
+static free_func zfree = myfree;
+
+#else /* !Z_SOLO */
+
+static alloc_func zalloc = (alloc_func)0;
+static free_func zfree = (free_func)0;
+
+void test_compress      OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+void test_gzio          OF((const char *fname,
+                            Byte *uncompr, uLong uncomprLen));
+
+/* ===========================================================================
+ * Test compress() and uncompress()
+ */
+void test_compress(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    uLong len = (uLong)strlen(hello)+1;
+
+    err = compress(compr, &comprLen, (const Bytef*)hello, len);
+    CHECK_ERR(err, "compress");
+
+    strcpy((char*)uncompr, "garbage");
+
+    err = uncompress(uncompr, &uncomprLen, compr, comprLen);
+    CHECK_ERR(err, "uncompress");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad uncompress\n");
+        exit(1);
+    } else {
+        printf("uncompress(): %s\n", (char *)uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Test read/write of .gz files
+ */
+void test_gzio(fname, uncompr, uncomprLen)
+    const char *fname; /* compressed file name */
+    Byte *uncompr;
+    uLong uncomprLen;
+{
+#ifdef NO_GZCOMPRESS
+    fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
+#else
+    int err;
+    int len = (int)strlen(hello)+1;
+    gzFile file;
+    z_off_t pos;
+
+    file = gzopen(fname, "wb");
+    if (file == NULL) {
+        fprintf(stderr, "gzopen error\n");
+        exit(1);
+    }
+    gzputc(file, 'h');
+    if (gzputs(file, "ello") != 4) {
+        fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
+        exit(1);
+    }
+    if (gzprintf(file, ", %s!", "hello") != 8) {
+        fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
+        exit(1);
+    }
+    gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
+    gzclose(file);
+
+    file = gzopen(fname, "rb");
+    if (file == NULL) {
+        fprintf(stderr, "gzopen error\n");
+        exit(1);
+    }
+    strcpy((char*)uncompr, "garbage");
+
+    if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
+        fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
+        exit(1);
+    }
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
+        exit(1);
+    } else {
+        printf("gzread(): %s\n", (char*)uncompr);
+    }
+
+    pos = gzseek(file, -8L, SEEK_CUR);
+    if (pos != 6 || gztell(file) != pos) {
+        fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
+                (long)pos, (long)gztell(file));
+        exit(1);
+    }
+
+    if (gzgetc(file) != ' ') {
+        fprintf(stderr, "gzgetc error\n");
+        exit(1);
+    }
+
+    if (gzungetc(' ', file) != ' ') {
+        fprintf(stderr, "gzungetc error\n");
+        exit(1);
+    }
+
+    gzgets(file, (char*)uncompr, (int)uncomprLen);
+    if (strlen((char*)uncompr) != 7) { /* " hello!" */
+        fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
+        exit(1);
+    }
+    if (strcmp((char*)uncompr, hello + 6)) {
+        fprintf(stderr, "bad gzgets after gzseek\n");
+        exit(1);
+    } else {
+        printf("gzgets() after gzseek: %s\n", (char*)uncompr);
+    }
+
+    gzclose(file);
+#endif
+}
+
+#endif /* Z_SOLO */
+
+/* ===========================================================================
+ * Test deflate() with small buffers
+ */
+void test_deflate(compr, comprLen)
+    Byte *compr;
+    uLong comprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+    uLong len = (uLong)strlen(hello)+1;
+
+    c_stream.zalloc = zalloc;
+    c_stream.zfree = zfree;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    c_stream.next_in  = (z_const unsigned char *)hello;
+    c_stream.next_out = compr;
+
+    while (c_stream.total_in != len && c_stream.total_out < comprLen) {
+        c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+        err = deflate(&c_stream, Z_NO_FLUSH);
+        CHECK_ERR(err, "deflate");
+    }
+    /* Finish the stream, still forcing small buffers: */
+    for (;;) {
+        c_stream.avail_out = 1;
+        err = deflate(&c_stream, Z_FINISH);
+        if (err == Z_STREAM_END) break;
+        CHECK_ERR(err, "deflate");
+    }
+
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with small buffers
+ */
+void test_inflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = zalloc;
+    d_stream.zfree = zfree;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = 0;
+    d_stream.next_out = uncompr;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
+        d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
+        err = inflate(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+        CHECK_ERR(err, "inflate");
+    }
+
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad inflate\n");
+        exit(1);
+    } else {
+        printf("inflate(): %s\n", (char *)uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Test deflate() with large buffers and dynamic change of compression level
+ */
+void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+
+    c_stream.zalloc = zalloc;
+    c_stream.zfree = zfree;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_BEST_SPEED);
+    CHECK_ERR(err, "deflateInit");
+
+    c_stream.next_out = compr;
+    c_stream.avail_out = (uInt)comprLen;
+
+    /* At this point, uncompr is still mostly zeroes, so it should compress
+     * very well:
+     */
+    c_stream.next_in = uncompr;
+    c_stream.avail_in = (uInt)uncomprLen;
+    err = deflate(&c_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "deflate");
+    if (c_stream.avail_in != 0) {
+        fprintf(stderr, "deflate not greedy\n");
+        exit(1);
+    }
+
+    /* Feed in already compressed data and switch to no compression: */
+    deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
+    c_stream.next_in = compr;
+    c_stream.avail_in = (uInt)comprLen/2;
+    err = deflate(&c_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "deflate");
+
+    /* Switch back to compressing mode: */
+    deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
+    c_stream.next_in = uncompr;
+    c_stream.avail_in = (uInt)uncomprLen;
+    err = deflate(&c_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "deflate");
+
+    err = deflate(&c_stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        fprintf(stderr, "deflate should report Z_STREAM_END\n");
+        exit(1);
+    }
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with large buffers
+ */
+void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = zalloc;
+    d_stream.zfree = zfree;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = (uInt)comprLen;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    for (;;) {
+        d_stream.next_out = uncompr;            /* discard the output */
+        d_stream.avail_out = (uInt)uncomprLen;
+        err = inflate(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+        CHECK_ERR(err, "large inflate");
+    }
+
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
+        fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
+        exit(1);
+    } else {
+        printf("large_inflate(): OK\n");
+    }
+}
+
+/* ===========================================================================
+ * Test deflate() with full flush
+ */
+void test_flush(compr, comprLen)
+    Byte *compr;
+    uLong *comprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+    uInt len = (uInt)strlen(hello)+1;
+
+    c_stream.zalloc = zalloc;
+    c_stream.zfree = zfree;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    c_stream.next_in  = (z_const unsigned char *)hello;
+    c_stream.next_out = compr;
+    c_stream.avail_in = 3;
+    c_stream.avail_out = (uInt)*comprLen;
+    err = deflate(&c_stream, Z_FULL_FLUSH);
+    CHECK_ERR(err, "deflate");
+
+    compr[3]++; /* force an error in first compressed block */
+    c_stream.avail_in = len - 3;
+
+    err = deflate(&c_stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        CHECK_ERR(err, "deflate");
+    }
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+
+    *comprLen = c_stream.total_out;
+}
+
+/* ===========================================================================
+ * Test inflateSync()
+ */
+void test_sync(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = zalloc;
+    d_stream.zfree = zfree;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = 2; /* just read the zlib header */
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    d_stream.next_out = uncompr;
+    d_stream.avail_out = (uInt)uncomprLen;
+
+    err = inflate(&d_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "inflate");
+
+    d_stream.avail_in = (uInt)comprLen-2;   /* read all compressed data */
+    err = inflateSync(&d_stream);           /* but skip the damaged part */
+    CHECK_ERR(err, "inflateSync");
+
+    err = inflate(&d_stream, Z_FINISH);
+    if (err != Z_DATA_ERROR) {
+        fprintf(stderr, "inflate should report DATA_ERROR\n");
+        /* Because of incorrect adler32 */
+        exit(1);
+    }
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    printf("after inflateSync(): hel%s\n", (char *)uncompr);
+}
+
+/* ===========================================================================
+ * Test deflate() with preset dictionary
+ */
+void test_dict_deflate(compr, comprLen)
+    Byte *compr;
+    uLong comprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+
+    c_stream.zalloc = zalloc;
+    c_stream.zfree = zfree;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    err = deflateSetDictionary(&c_stream,
+                (const Bytef*)dictionary, (int)sizeof(dictionary));
+    CHECK_ERR(err, "deflateSetDictionary");
+
+    dictId = c_stream.adler;
+    c_stream.next_out = compr;
+    c_stream.avail_out = (uInt)comprLen;
+
+    c_stream.next_in = (z_const unsigned char *)hello;
+    c_stream.avail_in = (uInt)strlen(hello)+1;
+
+    err = deflate(&c_stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        fprintf(stderr, "deflate should report Z_STREAM_END\n");
+        exit(1);
+    }
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with a preset dictionary
+ */
+void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = zalloc;
+    d_stream.zfree = zfree;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = (uInt)comprLen;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    d_stream.next_out = uncompr;
+    d_stream.avail_out = (uInt)uncomprLen;
+
+    for (;;) {
+        err = inflate(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+        if (err == Z_NEED_DICT) {
+            if (d_stream.adler != dictId) {
+                fprintf(stderr, "unexpected dictionary");
+                exit(1);
+            }
+            err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
+                                       (int)sizeof(dictionary));
+        }
+        CHECK_ERR(err, "inflate with dict");
+    }
+
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad inflate with dict\n");
+        exit(1);
+    } else {
+        printf("inflate with dictionary: %s\n", (char *)uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Usage:  example [output.gz  [input.gz]]
+ */
+
+int main(argc, argv)
+    int argc;
+    char *argv[];
+{
+    Byte *compr, *uncompr;
+    uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
+    uLong uncomprLen = comprLen;
+    static const char* myVersion = ZLIB_VERSION;
+
+    if (zlibVersion()[0] != myVersion[0]) {
+        fprintf(stderr, "incompatible zlib version\n");
+        exit(1);
+
+    } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
+        fprintf(stderr, "warning: different zlib version\n");
+    }
+
+    printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
+            ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
+
+    compr    = (Byte*)calloc((uInt)comprLen, 1);
+    uncompr  = (Byte*)calloc((uInt)uncomprLen, 1);
+    /* compr and uncompr are cleared to avoid reading uninitialized
+     * data and to ensure that uncompr compresses well.
+     */
+    if (compr == Z_NULL || uncompr == Z_NULL) {
+        printf("out of memory\n");
+        exit(1);
+    }
+
+#ifdef Z_SOLO
+    (void)argc;
+    (void)argv;
+#else
+    test_compress(compr, comprLen, uncompr, uncomprLen);
+
+    test_gzio((argc > 1 ? argv[1] : TESTFILE),
+              uncompr, uncomprLen);
+#endif
+
+    test_deflate(compr, comprLen);
+    test_inflate(compr, comprLen, uncompr, uncomprLen);
+
+    test_large_deflate(compr, comprLen, uncompr, uncomprLen);
+    test_large_inflate(compr, comprLen, uncompr, uncomprLen);
+
+    test_flush(compr, &comprLen);
+    test_sync(compr, comprLen, uncompr, uncomprLen);
+    comprLen = uncomprLen;
+
+    test_dict_deflate(compr, comprLen);
+    test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
+
+    free(compr);
+    free(uncompr);
+
+    return 0;
+}
Index: EcnlProtoTool/trunk/zlib-1.2.11/test/infcover.c
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/test/infcover.c	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/test/infcover.c	(revision 331)
@@ -0,0 +1,671 @@
+/* infcover.c -- test zlib's inflate routines with full code coverage
+ * Copyright (C) 2011, 2016 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* to use, do: ./configure --cover && make cover */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "zlib.h"
+
+/* get definition of internal structure so we can mess with it (see pull()),
+   and so we can call inflate_trees() (see cover5()) */
+#define ZLIB_INTERNAL
+#include "inftrees.h"
+#include "inflate.h"
+
+#define local static
+
+/* -- memory tracking routines -- */
+
+/*
+   These memory tracking routines are provided to zlib and track all of zlib's
+   allocations and deallocations, check for LIFO operations, keep a current
+   and high water mark of total bytes requested, optionally set a limit on the
+   total memory that can be allocated, and when done check for memory leaks.
+
+   They are used as follows:
+
+   z_stream strm;
+   mem_setup(&strm)         initializes the memory tracking and sets the
+                            zalloc, zfree, and opaque members of strm to use
+                            memory tracking for all zlib operations on strm
+   mem_limit(&strm, limit)  sets a limit on the total bytes requested -- a
+                            request that exceeds this limit will result in an
+                            allocation failure (returns NULL) -- setting the
+                            limit to zero means no limit, which is the default
+                            after mem_setup()
+   mem_used(&strm, "msg")   prints to stderr "msg" and the total bytes used
+   mem_high(&strm, "msg")   prints to stderr "msg" and the high water mark
+   mem_done(&strm, "msg")   ends memory tracking, releases all allocations
+                            for the tracking as well as leaked zlib blocks, if
+                            any.  If there was anything unusual, such as leaked
+                            blocks, non-FIFO frees, or frees of addresses not
+                            allocated, then "msg" and information about the
+                            problem is printed to stderr.  If everything is
+                            normal, nothing is printed. mem_done resets the
+                            strm members to Z_NULL to use the default memory
+                            allocation routines on the next zlib initialization
+                            using strm.
+ */
+
+/* these items are strung together in a linked list, one for each allocation */
+struct mem_item {
+    void *ptr;                  /* pointer to allocated memory */
+    size_t size;                /* requested size of allocation */
+    struct mem_item *next;      /* pointer to next item in list, or NULL */
+};
+
+/* this structure is at the root of the linked list, and tracks statistics */
+struct mem_zone {
+    struct mem_item *first;     /* pointer to first item in list, or NULL */
+    size_t total, highwater;    /* total allocations, and largest total */
+    size_t limit;               /* memory allocation limit, or 0 if no limit */
+    int notlifo, rogue;         /* counts of non-LIFO frees and rogue frees */
+};
+
+/* memory allocation routine to pass to zlib */
+local void *mem_alloc(void *mem, unsigned count, unsigned size)
+{
+    void *ptr;
+    struct mem_item *item;
+    struct mem_zone *zone = mem;
+    size_t len = count * (size_t)size;
+
+    /* induced allocation failure */
+    if (zone == NULL || (zone->limit && zone->total + len > zone->limit))
+        return NULL;
+
+    /* perform allocation using the standard library, fill memory with a
+       non-zero value to make sure that the code isn't depending on zeros */
+    ptr = malloc(len);
+    if (ptr == NULL)
+        return NULL;
+    memset(ptr, 0xa5, len);
+
+    /* create a new item for the list */
+    item = malloc(sizeof(struct mem_item));
+    if (item == NULL) {
+        free(ptr);
+        return NULL;
+    }
+    item->ptr = ptr;
+    item->size = len;
+
+    /* insert item at the beginning of the list */
+    item->next = zone->first;
+    zone->first = item;
+
+    /* update the statistics */
+    zone->total += item->size;
+    if (zone->total > zone->highwater)
+        zone->highwater = zone->total;
+
+    /* return the allocated memory */
+    return ptr;
+}
+
+/* memory free routine to pass to zlib */
+local void mem_free(void *mem, void *ptr)
+{
+    struct mem_item *item, *next;
+    struct mem_zone *zone = mem;
+
+    /* if no zone, just do a free */
+    if (zone == NULL) {
+        free(ptr);
+        return;
+    }
+
+    /* point next to the item that matches ptr, or NULL if not found -- remove
+       the item from the linked list if found */
+    next = zone->first;
+    if (next) {
+        if (next->ptr == ptr)
+            zone->first = next->next;   /* first one is it, remove from list */
+        else {
+            do {                        /* search the linked list */
+                item = next;
+                next = item->next;
+            } while (next != NULL && next->ptr != ptr);
+            if (next) {                 /* if found, remove from linked list */
+                item->next = next->next;
+                zone->notlifo++;        /* not a LIFO free */
+            }
+
+        }
+    }
+
+    /* if found, update the statistics and free the item */
+    if (next) {
+        zone->total -= next->size;
+        free(next);
+    }
+
+    /* if not found, update the rogue count */
+    else
+        zone->rogue++;
+
+    /* in any case, do the requested free with the standard library function */
+    free(ptr);
+}
+
+/* set up a controlled memory allocation space for monitoring, set the stream
+   parameters to the controlled routines, with opaque pointing to the space */
+local void mem_setup(z_stream *strm)
+{
+    struct mem_zone *zone;
+
+    zone = malloc(sizeof(struct mem_zone));
+    assert(zone != NULL);
+    zone->first = NULL;
+    zone->total = 0;
+    zone->highwater = 0;
+    zone->limit = 0;
+    zone->notlifo = 0;
+    zone->rogue = 0;
+    strm->opaque = zone;
+    strm->zalloc = mem_alloc;
+    strm->zfree = mem_free;
+}
+
+/* set a limit on the total memory allocation, or 0 to remove the limit */
+local void mem_limit(z_stream *strm, size_t limit)
+{
+    struct mem_zone *zone = strm->opaque;
+
+    zone->limit = limit;
+}
+
+/* show the current total requested allocations in bytes */
+local void mem_used(z_stream *strm, char *prefix)
+{
+    struct mem_zone *zone = strm->opaque;
+
+    fprintf(stderr, "%s: %lu allocated\n", prefix, zone->total);
+}
+
+/* show the high water allocation in bytes */
+local void mem_high(z_stream *strm, char *prefix)
+{
+    struct mem_zone *zone = strm->opaque;
+
+    fprintf(stderr, "%s: %lu high water mark\n", prefix, zone->highwater);
+}
+
+/* release the memory allocation zone -- if there are any surprises, notify */
+local void mem_done(z_stream *strm, char *prefix)
+{
+    int count = 0;
+    struct mem_item *item, *next;
+    struct mem_zone *zone = strm->opaque;
+
+    /* show high water mark */
+    mem_high(strm, prefix);
+
+    /* free leftover allocations and item structures, if any */
+    item = zone->first;
+    while (item != NULL) {
+        free(item->ptr);
+        next = item->next;
+        free(item);
+        item = next;
+        count++;
+    }
+
+    /* issue alerts about anything unexpected */
+    if (count || zone->total)
+        fprintf(stderr, "** %s: %lu bytes in %d blocks not freed\n",
+                prefix, zone->total, count);
+    if (zone->notlifo)
+        fprintf(stderr, "** %s: %d frees not LIFO\n", prefix, zone->notlifo);
+    if (zone->rogue)
+        fprintf(stderr, "** %s: %d frees not recognized\n",
+                prefix, zone->rogue);
+
+    /* free the zone and delete from the stream */
+    free(zone);
+    strm->opaque = Z_NULL;
+    strm->zalloc = Z_NULL;
+    strm->zfree = Z_NULL;
+}
+
+/* -- inflate test routines -- */
+
+/* Decode a hexadecimal string, set *len to length, in[] to the bytes.  This
+   decodes liberally, in that hex digits can be adjacent, in which case two in
+   a row writes a byte.  Or they can be delimited by any non-hex character,
+   where the delimiters are ignored except when a single hex digit is followed
+   by a delimiter, where that single digit writes a byte.  The returned data is
+   allocated and must eventually be freed.  NULL is returned if out of memory.
+   If the length is not needed, then len can be NULL. */
+local unsigned char *h2b(const char *hex, unsigned *len)
+{
+    unsigned char *in, *re;
+    unsigned next, val;
+
+    in = malloc((strlen(hex) + 1) >> 1);
+    if (in == NULL)
+        return NULL;
+    next = 0;
+    val = 1;
+    do {
+        if (*hex >= '0' && *hex <= '9')
+            val = (val << 4) + *hex - '0';
+        else if (*hex >= 'A' && *hex <= 'F')
+            val = (val << 4) + *hex - 'A' + 10;
+        else if (*hex >= 'a' && *hex <= 'f')
+            val = (val << 4) + *hex - 'a' + 10;
+        else if (val != 1 && val < 32)  /* one digit followed by delimiter */
+            val += 240;                 /* make it look like two digits */
+        if (val > 255) {                /* have two digits */
+            in[next++] = val & 0xff;    /* save the decoded byte */
+            val = 1;                    /* start over */
+        }
+    } while (*hex++);       /* go through the loop with the terminating null */
+    if (len != NULL)
+        *len = next;
+    re = realloc(in, next);
+    return re == NULL ? in : re;
+}
+
+/* generic inflate() run, where hex is the hexadecimal input data, what is the
+   text to include in an error message, step is how much input data to feed
+   inflate() on each call, or zero to feed it all, win is the window bits
+   parameter to inflateInit2(), len is the size of the output buffer, and err
+   is the error code expected from the first inflate() call (the second
+   inflate() call is expected to return Z_STREAM_END).  If win is 47, then
+   header information is collected with inflateGetHeader().  If a zlib stream
+   is looking for a dictionary, then an empty dictionary is provided.
+   inflate() is run until all of the input data is consumed. */
+local void inf(char *hex, char *what, unsigned step, int win, unsigned len,
+               int err)
+{
+    int ret;
+    unsigned have;
+    unsigned char *in, *out;
+    z_stream strm, copy;
+    gz_header head;
+
+    mem_setup(&strm);
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit2(&strm, win);
+    if (ret != Z_OK) {
+        mem_done(&strm, what);
+        return;
+    }
+    out = malloc(len);                          assert(out != NULL);
+    if (win == 47) {
+        head.extra = out;
+        head.extra_max = len;
+        head.name = out;
+        head.name_max = len;
+        head.comment = out;
+        head.comm_max = len;
+        ret = inflateGetHeader(&strm, &head);   assert(ret == Z_OK);
+    }
+    in = h2b(hex, &have);                       assert(in != NULL);
+    if (step == 0 || step > have)
+        step = have;
+    strm.avail_in = step;
+    have -= step;
+    strm.next_in = in;
+    do {
+        strm.avail_out = len;
+        strm.next_out = out;
+        ret = inflate(&strm, Z_NO_FLUSH);       assert(err == 9 || ret == err);
+        if (ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_NEED_DICT)
+            break;
+        if (ret == Z_NEED_DICT) {
+            ret = inflateSetDictionary(&strm, in, 1);
+                                                assert(ret == Z_DATA_ERROR);
+            mem_limit(&strm, 1);
+            ret = inflateSetDictionary(&strm, out, 0);
+                                                assert(ret == Z_MEM_ERROR);
+            mem_limit(&strm, 0);
+            ((struct inflate_state *)strm.state)->mode = DICT;
+            ret = inflateSetDictionary(&strm, out, 0);
+                                                assert(ret == Z_OK);
+            ret = inflate(&strm, Z_NO_FLUSH);   assert(ret == Z_BUF_ERROR);
+        }
+        ret = inflateCopy(&copy, &strm);        assert(ret == Z_OK);
+        ret = inflateEnd(&copy);                assert(ret == Z_OK);
+        err = 9;                        /* don't care next time around */
+        have += strm.avail_in;
+        strm.avail_in = step > have ? have : step;
+        have -= strm.avail_in;
+    } while (strm.avail_in);
+    free(in);
+    free(out);
+    ret = inflateReset2(&strm, -8);             assert(ret == Z_OK);
+    ret = inflateEnd(&strm);                    assert(ret == Z_OK);
+    mem_done(&strm, what);
+}
+
+/* cover all of the lines in inflate.c up to inflate() */
+local void cover_support(void)
+{
+    int ret;
+    z_stream strm;
+
+    mem_setup(&strm);
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit(&strm);                   assert(ret == Z_OK);
+    mem_used(&strm, "inflate init");
+    ret = inflatePrime(&strm, 5, 31);           assert(ret == Z_OK);
+    ret = inflatePrime(&strm, -1, 0);           assert(ret == Z_OK);
+    ret = inflateSetDictionary(&strm, Z_NULL, 0);
+                                                assert(ret == Z_STREAM_ERROR);
+    ret = inflateEnd(&strm);                    assert(ret == Z_OK);
+    mem_done(&strm, "prime");
+
+    inf("63 0", "force window allocation", 0, -15, 1, Z_OK);
+    inf("63 18 5", "force window replacement", 0, -8, 259, Z_OK);
+    inf("63 18 68 30 d0 0 0", "force split window update", 4, -8, 259, Z_OK);
+    inf("3 0", "use fixed blocks", 0, -15, 1, Z_STREAM_END);
+    inf("", "bad window size", 0, 1, 0, Z_STREAM_ERROR);
+
+    mem_setup(&strm);
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit_(&strm, ZLIB_VERSION - 1, (int)sizeof(z_stream));
+                                                assert(ret == Z_VERSION_ERROR);
+    mem_done(&strm, "wrong version");
+
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit(&strm);                   assert(ret == Z_OK);
+    ret = inflateEnd(&strm);                    assert(ret == Z_OK);
+    fputs("inflate built-in memory routines\n", stderr);
+}
+
+/* cover all inflate() header and trailer cases and code after inflate() */
+local void cover_wrap(void)
+{
+    int ret;
+    z_stream strm, copy;
+    unsigned char dict[257];
+
+    ret = inflate(Z_NULL, 0);                   assert(ret == Z_STREAM_ERROR);
+    ret = inflateEnd(Z_NULL);                   assert(ret == Z_STREAM_ERROR);
+    ret = inflateCopy(Z_NULL, Z_NULL);          assert(ret == Z_STREAM_ERROR);
+    fputs("inflate bad parameters\n", stderr);
+
+    inf("1f 8b 0 0", "bad gzip method", 0, 31, 0, Z_DATA_ERROR);
+    inf("1f 8b 8 80", "bad gzip flags", 0, 31, 0, Z_DATA_ERROR);
+    inf("77 85", "bad zlib method", 0, 15, 0, Z_DATA_ERROR);
+    inf("8 99", "set window size from header", 0, 0, 0, Z_OK);
+    inf("78 9c", "bad zlib window size", 0, 8, 0, Z_DATA_ERROR);
+    inf("78 9c 63 0 0 0 1 0 1", "check adler32", 0, 15, 1, Z_STREAM_END);
+    inf("1f 8b 8 1e 0 0 0 0 0 0 1 0 0 0 0 0 0", "bad header crc", 0, 47, 1,
+        Z_DATA_ERROR);
+    inf("1f 8b 8 2 0 0 0 0 0 0 1d 26 3 0 0 0 0 0 0 0 0 0", "check gzip length",
+        0, 47, 0, Z_STREAM_END);
+    inf("78 90", "bad zlib header check", 0, 47, 0, Z_DATA_ERROR);
+    inf("8 b8 0 0 0 1", "need dictionary", 0, 8, 0, Z_NEED_DICT);
+    inf("78 9c 63 0", "compute adler32", 0, 15, 1, Z_OK);
+
+    mem_setup(&strm);
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit2(&strm, -8);
+    strm.avail_in = 2;
+    strm.next_in = (void *)"\x63";
+    strm.avail_out = 1;
+    strm.next_out = (void *)&ret;
+    mem_limit(&strm, 1);
+    ret = inflate(&strm, Z_NO_FLUSH);           assert(ret == Z_MEM_ERROR);
+    ret = inflate(&strm, Z_NO_FLUSH);           assert(ret == Z_MEM_ERROR);
+    mem_limit(&strm, 0);
+    memset(dict, 0, 257);
+    ret = inflateSetDictionary(&strm, dict, 257);
+                                                assert(ret == Z_OK);
+    mem_limit(&strm, (sizeof(struct inflate_state) << 1) + 256);
+    ret = inflatePrime(&strm, 16, 0);           assert(ret == Z_OK);
+    strm.avail_in = 2;
+    strm.next_in = (void *)"\x80";
+    ret = inflateSync(&strm);                   assert(ret == Z_DATA_ERROR);
+    ret = inflate(&strm, Z_NO_FLUSH);           assert(ret == Z_STREAM_ERROR);
+    strm.avail_in = 4;
+    strm.next_in = (void *)"\0\0\xff\xff";
+    ret = inflateSync(&strm);                   assert(ret == Z_OK);
+    (void)inflateSyncPoint(&strm);
+    ret = inflateCopy(&copy, &strm);            assert(ret == Z_MEM_ERROR);
+    mem_limit(&strm, 0);
+    ret = inflateUndermine(&strm, 1);           assert(ret == Z_DATA_ERROR);
+    (void)inflateMark(&strm);
+    ret = inflateEnd(&strm);                    assert(ret == Z_OK);
+    mem_done(&strm, "miscellaneous, force memory errors");
+}
+
+/* input and output functions for inflateBack() */
+local unsigned pull(void *desc, unsigned char **buf)
+{
+    static unsigned int next = 0;
+    static unsigned char dat[] = {0x63, 0, 2, 0};
+    struct inflate_state *state;
+
+    if (desc == Z_NULL) {
+        next = 0;
+        return 0;   /* no input (already provided at next_in) */
+    }
+    state = (void *)((z_stream *)desc)->state;
+    if (state != Z_NULL)
+        state->mode = SYNC;     /* force an otherwise impossible situation */
+    return next < sizeof(dat) ? (*buf = dat + next++, 1) : 0;
+}
+
+local int push(void *desc, unsigned char *buf, unsigned len)
+{
+    buf += len;
+    return desc != Z_NULL;      /* force error if desc not null */
+}
+
+/* cover inflateBack() up to common deflate data cases and after those */
+local void cover_back(void)
+{
+    int ret;
+    z_stream strm;
+    unsigned char win[32768];
+
+    ret = inflateBackInit_(Z_NULL, 0, win, 0, 0);
+                                                assert(ret == Z_VERSION_ERROR);
+    ret = inflateBackInit(Z_NULL, 0, win);      assert(ret == Z_STREAM_ERROR);
+    ret = inflateBack(Z_NULL, Z_NULL, Z_NULL, Z_NULL, Z_NULL);
+                                                assert(ret == Z_STREAM_ERROR);
+    ret = inflateBackEnd(Z_NULL);               assert(ret == Z_STREAM_ERROR);
+    fputs("inflateBack bad parameters\n", stderr);
+
+    mem_setup(&strm);
+    ret = inflateBackInit(&strm, 15, win);      assert(ret == Z_OK);
+    strm.avail_in = 2;
+    strm.next_in = (void *)"\x03";
+    ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL);
+                                                assert(ret == Z_STREAM_END);
+        /* force output error */
+    strm.avail_in = 3;
+    strm.next_in = (void *)"\x63\x00";
+    ret = inflateBack(&strm, pull, Z_NULL, push, &strm);
+                                                assert(ret == Z_BUF_ERROR);
+        /* force mode error by mucking with state */
+    ret = inflateBack(&strm, pull, &strm, push, Z_NULL);
+                                                assert(ret == Z_STREAM_ERROR);
+    ret = inflateBackEnd(&strm);                assert(ret == Z_OK);
+    mem_done(&strm, "inflateBack bad state");
+
+    ret = inflateBackInit(&strm, 15, win);      assert(ret == Z_OK);
+    ret = inflateBackEnd(&strm);                assert(ret == Z_OK);
+    fputs("inflateBack built-in memory routines\n", stderr);
+}
+
+/* do a raw inflate of data in hexadecimal with both inflate and inflateBack */
+local int try(char *hex, char *id, int err)
+{
+    int ret;
+    unsigned len, size;
+    unsigned char *in, *out, *win;
+    char *prefix;
+    z_stream strm;
+
+    /* convert to hex */
+    in = h2b(hex, &len);
+    assert(in != NULL);
+
+    /* allocate work areas */
+    size = len << 3;
+    out = malloc(size);
+    assert(out != NULL);
+    win = malloc(32768);
+    assert(win != NULL);
+    prefix = malloc(strlen(id) + 6);
+    assert(prefix != NULL);
+
+    /* first with inflate */
+    strcpy(prefix, id);
+    strcat(prefix, "-late");
+    mem_setup(&strm);
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit2(&strm, err < 0 ? 47 : -15);
+    assert(ret == Z_OK);
+    strm.avail_in = len;
+    strm.next_in = in;
+    do {
+        strm.avail_out = size;
+        strm.next_out = out;
+        ret = inflate(&strm, Z_TREES);
+        assert(ret != Z_STREAM_ERROR && ret != Z_MEM_ERROR);
+        if (ret == Z_DATA_ERROR || ret == Z_NEED_DICT)
+            break;
+    } while (strm.avail_in || strm.avail_out == 0);
+    if (err) {
+        assert(ret == Z_DATA_ERROR);
+        assert(strcmp(id, strm.msg) == 0);
+    }
+    inflateEnd(&strm);
+    mem_done(&strm, prefix);
+
+    /* then with inflateBack */
+    if (err >= 0) {
+        strcpy(prefix, id);
+        strcat(prefix, "-back");
+        mem_setup(&strm);
+        ret = inflateBackInit(&strm, 15, win);
+        assert(ret == Z_OK);
+        strm.avail_in = len;
+        strm.next_in = in;
+        ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL);
+        assert(ret != Z_STREAM_ERROR);
+        if (err) {
+            assert(ret == Z_DATA_ERROR);
+            assert(strcmp(id, strm.msg) == 0);
+        }
+        inflateBackEnd(&strm);
+        mem_done(&strm, prefix);
+    }
+
+    /* clean up */
+    free(prefix);
+    free(win);
+    free(out);
+    free(in);
+    return ret;
+}
+
+/* cover deflate data cases in both inflate() and inflateBack() */
+local void cover_inflate(void)
+{
+    try("0 0 0 0 0", "invalid stored block lengths", 1);
+    try("3 0", "fixed", 0);
+    try("6", "invalid block type", 1);
+    try("1 1 0 fe ff 0", "stored", 0);
+    try("fc 0 0", "too many length or distance symbols", 1);
+    try("4 0 fe ff", "invalid code lengths set", 1);
+    try("4 0 24 49 0", "invalid bit length repeat", 1);
+    try("4 0 24 e9 ff ff", "invalid bit length repeat", 1);
+    try("4 0 24 e9 ff 6d", "invalid code -- missing end-of-block", 1);
+    try("4 80 49 92 24 49 92 24 71 ff ff 93 11 0",
+        "invalid literal/lengths set", 1);
+    try("4 80 49 92 24 49 92 24 f b4 ff ff c3 84", "invalid distances set", 1);
+    try("4 c0 81 8 0 0 0 0 20 7f eb b 0 0", "invalid literal/length code", 1);
+    try("2 7e ff ff", "invalid distance code", 1);
+    try("c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 1);
+
+    /* also trailer mismatch just in inflate() */
+    try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 1", "incorrect data check", -1);
+    try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1",
+        "incorrect length check", -1);
+    try("5 c0 21 d 0 0 0 80 b0 fe 6d 2f 91 6c", "pull 17", 0);
+    try("5 e0 81 91 24 cb b2 2c 49 e2 f 2e 8b 9a 47 56 9f fb fe ec d2 ff 1f",
+        "long code", 0);
+    try("ed c0 1 1 0 0 0 40 20 ff 57 1b 42 2c 4f", "length extra", 0);
+    try("ed cf c1 b1 2c 47 10 c4 30 fa 6f 35 1d 1 82 59 3d fb be 2e 2a fc f c",
+        "long distance and extra", 0);
+    try("ed c0 81 0 0 0 0 80 a0 fd a9 17 a9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "
+        "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6", "window end", 0);
+    inf("2 8 20 80 0 3 0", "inflate_fast TYPE return", 0, -15, 258,
+        Z_STREAM_END);
+    inf("63 18 5 40 c 0", "window wrap", 3, -8, 300, Z_OK);
+}
+
+/* cover remaining lines in inftrees.c */
+local void cover_trees(void)
+{
+    int ret;
+    unsigned bits;
+    unsigned short lens[16], work[16];
+    code *next, table[ENOUGH_DISTS];
+
+    /* we need to call inflate_table() directly in order to manifest not-
+       enough errors, since zlib insures that enough is always enough */
+    for (bits = 0; bits < 15; bits++)
+        lens[bits] = (unsigned short)(bits + 1);
+    lens[15] = 15;
+    next = table;
+    bits = 15;
+    ret = inflate_table(DISTS, lens, 16, &next, &bits, work);
+                                                assert(ret == 1);
+    next = table;
+    bits = 1;
+    ret = inflate_table(DISTS, lens, 16, &next, &bits, work);
+                                                assert(ret == 1);
+    fputs("inflate_table not enough errors\n", stderr);
+}
+
+/* cover remaining inffast.c decoding and window copying */
+local void cover_fast(void)
+{
+    inf("e5 e0 81 ad 6d cb b2 2c c9 01 1e 59 63 ae 7d ee fb 4d fd b5 35 41 68"
+        " ff 7f 0f 0 0 0", "fast length extra bits", 0, -8, 258, Z_DATA_ERROR);
+    inf("25 fd 81 b5 6d 59 b6 6a 49 ea af 35 6 34 eb 8c b9 f6 b9 1e ef 67 49"
+        " 50 fe ff ff 3f 0 0", "fast distance extra bits", 0, -8, 258,
+        Z_DATA_ERROR);
+    inf("3 7e 0 0 0 0 0", "fast invalid distance code", 0, -8, 258,
+        Z_DATA_ERROR);
+    inf("1b 7 0 0 0 0 0", "fast invalid literal/length code", 0, -8, 258,
+        Z_DATA_ERROR);
+    inf("d c7 1 ae eb 38 c 4 41 a0 87 72 de df fb 1f b8 36 b1 38 5d ff ff 0",
+        "fast 2nd level codes and too far back", 0, -8, 258, Z_DATA_ERROR);
+    inf("63 18 5 8c 10 8 0 0 0 0", "very common case", 0, -8, 259, Z_OK);
+    inf("63 60 60 18 c9 0 8 18 18 18 26 c0 28 0 29 0 0 0",
+        "contiguous and wrap around window", 6, -8, 259, Z_OK);
+    inf("63 0 3 0 0 0 0 0", "copy direct from output", 0, -8, 259,
+        Z_STREAM_END);
+}
+
+int main(void)
+{
+    fprintf(stderr, "%s\n", zlibVersion());
+    cover_support();
+    cover_wrap();
+    cover_back();
+    cover_inflate();
+    cover_trees();
+    cover_fast();
+    return 0;
+}
Index: EcnlProtoTool/trunk/zlib-1.2.11/test/minigzip.c
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/test/minigzip.c	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/test/minigzip.c	(revision 331)
@@ -0,0 +1,651 @@
+/* minigzip.c -- simulate gzip using the zlib compression library
+ * Copyright (C) 1995-2006, 2010, 2011, 2016 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * minigzip is a minimal implementation of the gzip utility. This is
+ * only an example of using zlib and isn't meant to replace the
+ * full-featured gzip. No attempt is made to deal with file systems
+ * limiting names to 14 or 8+3 characters, etc... Error checking is
+ * very limited. So use minigzip only for testing; use gzip for the
+ * real thing. On MSDOS, use only on file names without extension
+ * or in pipe mode.
+ */
+
+/* @(#) $Id$ */
+
+#include "zlib.h"
+#include <stdio.h>
+
+#ifdef STDC
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+
+#ifdef USE_MMAP
+#  include <sys/types.h>
+#  include <sys/mman.h>
+#  include <sys/stat.h>
+#endif
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
+#  include <fcntl.h>
+#  include <io.h>
+#  ifdef UNDER_CE
+#    include <stdlib.h>
+#  endif
+#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+#  define SET_BINARY_MODE(file)
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER < 1900
+#  define snprintf _snprintf
+#endif
+
+#ifdef VMS
+#  define unlink delete
+#  define GZ_SUFFIX "-gz"
+#endif
+#ifdef RISCOS
+#  define unlink remove
+#  define GZ_SUFFIX "-gz"
+#  define fileno(file) file->__file
+#endif
+#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+#  include <unix.h> /* for fileno */
+#endif
+
+#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
+#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
+  extern int unlink OF((const char *));
+#endif
+#endif
+
+#if defined(UNDER_CE)
+#  include <windows.h>
+#  define perror(s) pwinerror(s)
+
+/* Map the Windows error number in ERROR to a locale-dependent error
+   message string and return a pointer to it.  Typically, the values
+   for ERROR come from GetLastError.
+
+   The string pointed to shall not be modified by the application,
+   but may be overwritten by a subsequent call to strwinerror
+
+   The strwinerror function does not change the current setting
+   of GetLastError.  */
+
+static char *strwinerror (error)
+     DWORD error;
+{
+    static char buf[1024];
+
+    wchar_t *msgbuf;
+    DWORD lasterr = GetLastError();
+    DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+        | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+        NULL,
+        error,
+        0, /* Default language */
+        (LPVOID)&msgbuf,
+        0,
+        NULL);
+    if (chars != 0) {
+        /* If there is an \r\n appended, zap it.  */
+        if (chars >= 2
+            && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
+            chars -= 2;
+            msgbuf[chars] = 0;
+        }
+
+        if (chars > sizeof (buf) - 1) {
+            chars = sizeof (buf) - 1;
+            msgbuf[chars] = 0;
+        }
+
+        wcstombs(buf, msgbuf, chars + 1);
+        LocalFree(msgbuf);
+    }
+    else {
+        sprintf(buf, "unknown win32 error (%ld)", error);
+    }
+
+    SetLastError(lasterr);
+    return buf;
+}
+
+static void pwinerror (s)
+    const char *s;
+{
+    if (s && *s)
+        fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ()));
+    else
+        fprintf(stderr, "%s\n", strwinerror(GetLastError ()));
+}
+
+#endif /* UNDER_CE */
+
+#ifndef GZ_SUFFIX
+#  define GZ_SUFFIX ".gz"
+#endif
+#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
+
+#define BUFLEN      16384
+#define MAX_NAME_LEN 1024
+
+#ifdef MAXSEG_64K
+#  define local static
+   /* Needed for systems with limitation on stack size. */
+#else
+#  define local
+#endif
+
+#ifdef Z_SOLO
+/* for Z_SOLO, create simplified gz* functions using deflate and inflate */
+
+#if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)
+#  include <unistd.h>       /* for unlink() */
+#endif
+
+void *myalloc OF((void *, unsigned, unsigned));
+void myfree OF((void *, void *));
+
+void *myalloc(q, n, m)
+    void *q;
+    unsigned n, m;
+{
+    (void)q;
+    return calloc(n, m);
+}
+
+void myfree(q, p)
+    void *q, *p;
+{
+    (void)q;
+    free(p);
+}
+
+typedef struct gzFile_s {
+    FILE *file;
+    int write;
+    int err;
+    char *msg;
+    z_stream strm;
+} *gzFile;
+
+gzFile gzopen OF((const char *, const char *));
+gzFile gzdopen OF((int, const char *));
+gzFile gz_open OF((const char *, int, const char *));
+
+gzFile gzopen(path, mode)
+const char *path;
+const char *mode;
+{
+    return gz_open(path, -1, mode);
+}
+
+gzFile gzdopen(fd, mode)
+int fd;
+const char *mode;
+{
+    return gz_open(NULL, fd, mode);
+}
+
+gzFile gz_open(path, fd, mode)
+    const char *path;
+    int fd;
+    const char *mode;
+{
+    gzFile gz;
+    int ret;
+
+    gz = malloc(sizeof(struct gzFile_s));
+    if (gz == NULL)
+        return NULL;
+    gz->write = strchr(mode, 'w') != NULL;
+    gz->strm.zalloc = myalloc;
+    gz->strm.zfree = myfree;
+    gz->strm.opaque = Z_NULL;
+    if (gz->write)
+        ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0);
+    else {
+        gz->strm.next_in = 0;
+        gz->strm.avail_in = Z_NULL;
+        ret = inflateInit2(&(gz->strm), 15 + 16);
+    }
+    if (ret != Z_OK) {
+        free(gz);
+        return NULL;
+    }
+    gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") :
+                              fopen(path, gz->write ? "wb" : "rb");
+    if (gz->file == NULL) {
+        gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm));
+        free(gz);
+        return NULL;
+    }
+    gz->err = 0;
+    gz->msg = "";
+    return gz;
+}
+
+int gzwrite OF((gzFile, const void *, unsigned));
+
+int gzwrite(gz, buf, len)
+    gzFile gz;
+    const void *buf;
+    unsigned len;
+{
+    z_stream *strm;
+    unsigned char out[BUFLEN];
+
+    if (gz == NULL || !gz->write)
+        return 0;
+    strm = &(gz->strm);
+    strm->next_in = (void *)buf;
+    strm->avail_in = len;
+    do {
+        strm->next_out = out;
+        strm->avail_out = BUFLEN;
+        (void)deflate(strm, Z_NO_FLUSH);
+        fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
+    } while (strm->avail_out == 0);
+    return len;
+}
+
+int gzread OF((gzFile, void *, unsigned));
+
+int gzread(gz, buf, len)
+    gzFile gz;
+    void *buf;
+    unsigned len;
+{
+    int ret;
+    unsigned got;
+    unsigned char in[1];
+    z_stream *strm;
+
+    if (gz == NULL || gz->write)
+        return 0;
+    if (gz->err)
+        return 0;
+    strm = &(gz->strm);
+    strm->next_out = (void *)buf;
+    strm->avail_out = len;
+    do {
+        got = fread(in, 1, 1, gz->file);
+        if (got == 0)
+            break;
+        strm->next_in = in;
+        strm->avail_in = 1;
+        ret = inflate(strm, Z_NO_FLUSH);
+        if (ret == Z_DATA_ERROR) {
+            gz->err = Z_DATA_ERROR;
+            gz->msg = strm->msg;
+            return 0;
+        }
+        if (ret == Z_STREAM_END)
+            inflateReset(strm);
+    } while (strm->avail_out);
+    return len - strm->avail_out;
+}
+
+int gzclose OF((gzFile));
+
+int gzclose(gz)
+    gzFile gz;
+{
+    z_stream *strm;
+    unsigned char out[BUFLEN];
+
+    if (gz == NULL)
+        return Z_STREAM_ERROR;
+    strm = &(gz->strm);
+    if (gz->write) {
+        strm->next_in = Z_NULL;
+        strm->avail_in = 0;
+        do {
+            strm->next_out = out;
+            strm->avail_out = BUFLEN;
+            (void)deflate(strm, Z_FINISH);
+            fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
+        } while (strm->avail_out == 0);
+        deflateEnd(strm);
+    }
+    else
+        inflateEnd(strm);
+    fclose(gz->file);
+    free(gz);
+    return Z_OK;
+}
+
+const char *gzerror OF((gzFile, int *));
+
+const char *gzerror(gz, err)
+    gzFile gz;
+    int *err;
+{
+    *err = gz->err;
+    return gz->msg;
+}
+
+#endif
+
+static char *prog;
+
+void error            OF((const char *msg));
+void gz_compress      OF((FILE   *in, gzFile out));
+#ifdef USE_MMAP
+int  gz_compress_mmap OF((FILE   *in, gzFile out));
+#endif
+void gz_uncompress    OF((gzFile in, FILE   *out));
+void file_compress    OF((char  *file, char *mode));
+void file_uncompress  OF((char  *file));
+int  main             OF((int argc, char *argv[]));
+
+/* ===========================================================================
+ * Display error message and exit
+ */
+void error(msg)
+    const char *msg;
+{
+    fprintf(stderr, "%s: %s\n", prog, msg);
+    exit(1);
+}
+
+/* ===========================================================================
+ * Compress input to output then close both files.
+ */
+
+void gz_compress(in, out)
+    FILE   *in;
+    gzFile out;
+{
+    local char buf[BUFLEN];
+    int len;
+    int err;
+
+#ifdef USE_MMAP
+    /* Try first compressing with mmap. If mmap fails (minigzip used in a
+     * pipe), use the normal fread loop.
+     */
+    if (gz_compress_mmap(in, out) == Z_OK) return;
+#endif
+    for (;;) {
+        len = (int)fread(buf, 1, sizeof(buf), in);
+        if (ferror(in)) {
+            perror("fread");
+            exit(1);
+        }
+        if (len == 0) break;
+
+        if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
+    }
+    fclose(in);
+    if (gzclose(out) != Z_OK) error("failed gzclose");
+}
+
+#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
+
+/* Try compressing the input file at once using mmap. Return Z_OK if
+ * if success, Z_ERRNO otherwise.
+ */
+int gz_compress_mmap(in, out)
+    FILE   *in;
+    gzFile out;
+{
+    int len;
+    int err;
+    int ifd = fileno(in);
+    caddr_t buf;    /* mmap'ed buffer for the entire input file */
+    off_t buf_len;  /* length of the input file */
+    struct stat sb;
+
+    /* Determine the size of the file, needed for mmap: */
+    if (fstat(ifd, &sb) < 0) return Z_ERRNO;
+    buf_len = sb.st_size;
+    if (buf_len <= 0) return Z_ERRNO;
+
+    /* Now do the actual mmap: */
+    buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
+    if (buf == (caddr_t)(-1)) return Z_ERRNO;
+
+    /* Compress the whole file at once: */
+    len = gzwrite(out, (char *)buf, (unsigned)buf_len);
+
+    if (len != (int)buf_len) error(gzerror(out, &err));
+
+    munmap(buf, buf_len);
+    fclose(in);
+    if (gzclose(out) != Z_OK) error("failed gzclose");
+    return Z_OK;
+}
+#endif /* USE_MMAP */
+
+/* ===========================================================================
+ * Uncompress input to output then close both files.
+ */
+void gz_uncompress(in, out)
+    gzFile in;
+    FILE   *out;
+{
+    local char buf[BUFLEN];
+    int len;
+    int err;
+
+    for (;;) {
+        len = gzread(in, buf, sizeof(buf));
+        if (len < 0) error (gzerror(in, &err));
+        if (len == 0) break;
+
+        if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
+            error("failed fwrite");
+        }
+    }
+    if (fclose(out)) error("failed fclose");
+
+    if (gzclose(in) != Z_OK) error("failed gzclose");
+}
+
+
+/* ===========================================================================
+ * Compress the given file: create a corresponding .gz file and remove the
+ * original.
+ */
+void file_compress(file, mode)
+    char  *file;
+    char  *mode;
+{
+    local char outfile[MAX_NAME_LEN];
+    FILE  *in;
+    gzFile out;
+
+    if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
+        fprintf(stderr, "%s: filename too long\n", prog);
+        exit(1);
+    }
+
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+    snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX);
+#else
+    strcpy(outfile, file);
+    strcat(outfile, GZ_SUFFIX);
+#endif
+
+    in = fopen(file, "rb");
+    if (in == NULL) {
+        perror(file);
+        exit(1);
+    }
+    out = gzopen(outfile, mode);
+    if (out == NULL) {
+        fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
+        exit(1);
+    }
+    gz_compress(in, out);
+
+    unlink(file);
+}
+
+
+/* ===========================================================================
+ * Uncompress the given file and remove the original.
+ */
+void file_uncompress(file)
+    char  *file;
+{
+    local char buf[MAX_NAME_LEN];
+    char *infile, *outfile;
+    FILE  *out;
+    gzFile in;
+    unsigned len = strlen(file);
+
+    if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
+        fprintf(stderr, "%s: filename too long\n", prog);
+        exit(1);
+    }
+
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+    snprintf(buf, sizeof(buf), "%s", file);
+#else
+    strcpy(buf, file);
+#endif
+
+    if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
+        infile = file;
+        outfile = buf;
+        outfile[len-3] = '\0';
+    } else {
+        outfile = file;
+        infile = buf;
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+        snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX);
+#else
+        strcat(infile, GZ_SUFFIX);
+#endif
+    }
+    in = gzopen(infile, "rb");
+    if (in == NULL) {
+        fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
+        exit(1);
+    }
+    out = fopen(outfile, "wb");
+    if (out == NULL) {
+        perror(file);
+        exit(1);
+    }
+
+    gz_uncompress(in, out);
+
+    unlink(infile);
+}
+
+
+/* ===========================================================================
+ * Usage:  minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]
+ *   -c : write to standard output
+ *   -d : decompress
+ *   -f : compress with Z_FILTERED
+ *   -h : compress with Z_HUFFMAN_ONLY
+ *   -r : compress with Z_RLE
+ *   -1 to -9 : compression level
+ */
+
+int main(argc, argv)
+    int argc;
+    char *argv[];
+{
+    int copyout = 0;
+    int uncompr = 0;
+    gzFile file;
+    char *bname, outmode[20];
+
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+    snprintf(outmode, sizeof(outmode), "%s", "wb6 ");
+#else
+    strcpy(outmode, "wb6 ");
+#endif
+
+    prog = argv[0];
+    bname = strrchr(argv[0], '/');
+    if (bname)
+      bname++;
+    else
+      bname = argv[0];
+    argc--, argv++;
+
+    if (!strcmp(bname, "gunzip"))
+      uncompr = 1;
+    else if (!strcmp(bname, "zcat"))
+      copyout = uncompr = 1;
+
+    while (argc > 0) {
+      if (strcmp(*argv, "-c") == 0)
+        copyout = 1;
+      else if (strcmp(*argv, "-d") == 0)
+        uncompr = 1;
+      else if (strcmp(*argv, "-f") == 0)
+        outmode[3] = 'f';
+      else if (strcmp(*argv, "-h") == 0)
+        outmode[3] = 'h';
+      else if (strcmp(*argv, "-r") == 0)
+        outmode[3] = 'R';
+      else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
+               (*argv)[2] == 0)
+        outmode[2] = (*argv)[1];
+      else
+        break;
+      argc--, argv++;
+    }
+    if (outmode[3] == ' ')
+        outmode[3] = 0;
+    if (argc == 0) {
+        SET_BINARY_MODE(stdin);
+        SET_BINARY_MODE(stdout);
+        if (uncompr) {
+            file = gzdopen(fileno(stdin), "rb");
+            if (file == NULL) error("can't gzdopen stdin");
+            gz_uncompress(file, stdout);
+        } else {
+            file = gzdopen(fileno(stdout), outmode);
+            if (file == NULL) error("can't gzdopen stdout");
+            gz_compress(stdin, file);
+        }
+    } else {
+        if (copyout) {
+            SET_BINARY_MODE(stdout);
+        }
+        do {
+            if (uncompr) {
+                if (copyout) {
+                    file = gzopen(*argv, "rb");
+                    if (file == NULL)
+                        fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
+                    else
+                        gz_uncompress(file, stdout);
+                } else {
+                    file_uncompress(*argv);
+                }
+            } else {
+                if (copyout) {
+                    FILE * in = fopen(*argv, "rb");
+
+                    if (in == NULL) {
+                        perror(*argv);
+                    } else {
+                        file = gzdopen(fileno(stdout), outmode);
+                        if (file == NULL) error("can't gzdopen stdout");
+
+                        gz_compress(in, file);
+                    }
+
+                } else {
+                    file_compress(*argv, outmode);
+                }
+            }
+        } while (argv++, --argc);
+    }
+    return 0;
+}
Index: EcnlProtoTool/trunk/zlib-1.2.11/treebuild.xml
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/treebuild.xml	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/treebuild.xml	(revision 331)
@@ -0,0 +1,116 @@
+<?xml version="1.0" ?>
+<package name="zlib" version="1.2.11">
+    <library name="zlib" dlversion="1.2.11" dlname="z">
+	<property name="description"> zip compression library </property>
+	<property name="include-target-dir" value="$(@PACKAGE/install-includedir)" />
+
+	<!-- fixme: not implemented yet -->
+	<property name="compiler/c/inline" value="yes" />
+
+	<include-file name="zlib.h" scope="public" mode="644" />
+	<include-file name="zconf.h" scope="public" mode="644" />
+
+	<source name="adler32.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	</source>
+	<source name="compress.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	</source>
+	<source name="crc32.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="crc32.h" />
+	</source>
+	<source name="gzclose.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="gzguts.h" />
+	</source>
+	<source name="gzlib.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="gzguts.h" />
+	</source>
+	<source name="gzread.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="gzguts.h" />
+	</source>
+	<source name="gzwrite.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="gzguts.h" />
+	</source>
+	<source name="uncompr.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	</source>
+	<source name="deflate.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="zutil.h" />
+	    <depend name="deflate.h" />
+	</source>
+	<source name="trees.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="zutil.h" />
+	    <depend name="deflate.h" />
+	    <depend name="trees.h" />
+	</source>
+	<source name="zutil.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="zutil.h" />
+	</source>
+	<source name="inflate.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="zutil.h" />
+	    <depend name="inftrees.h" />
+	    <depend name="inflate.h" />
+	    <depend name="inffast.h" />
+	</source>
+	<source name="infback.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="zutil.h" />
+	    <depend name="inftrees.h" />
+	    <depend name="inflate.h" />
+	    <depend name="inffast.h" />
+	</source>
+	<source name="inftrees.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="zutil.h" />
+	    <depend name="inftrees.h" />
+	</source>
+	<source name="inffast.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="zutil.h" />
+	    <depend name="inftrees.h" />
+	    <depend name="inflate.h" />
+	    <depend name="inffast.h" />
+	</source>
+    </library>
+</package>
+
+<!--
+CFLAGS=-O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-g -DZLIB_DEBUG
+#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+#           -Wstrict-prototypes -Wmissing-prototypes
+
+# OBJA =
+# to use the asm code: make OBJA=match.o
+#
+match.o: match.S
+	$(CPP) match.S > _match.s
+	$(CC) -c _match.s
+	mv _match.o match.o
+	rm -f _match.s
+-->
Index: EcnlProtoTool/trunk/zlib-1.2.11/trees.c
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/trees.c	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/trees.c	(revision 331)
@@ -0,0 +1,1203 @@
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-2017 Jean-loup Gailly
+ * detect_data_type() function provided freely by Cosmin Truta, 2006
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process uses several Huffman trees. The more
+ *      common source values are represented by shorter bit sequences.
+ *
+ *      Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values).  The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ *      Storer, James A.
+ *          Data Compression:  Methods and Theory, pp. 49-50.
+ *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
+ *
+ *      Sedgewick, R.
+ *          Algorithms, p290.
+ *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $Id$ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef ZLIB_DEBUG
+#  include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6      16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10    17
+/* repeat a zero length 3-10 times  (3 bits of repeat count) */
+
+#define REPZ_11_138  18
+/* repeat a zero length 11-138 times  (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN  512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+#  include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+    const ct_data *static_tree;  /* static tree or NULL */
+    const intf *extra_bits;      /* extra bits for each code or NULL */
+    int     extra_base;          /* base index for extra_bits */
+    int     elems;               /* max number of elements in the tree */
+    int     max_length;          /* max bit length for the codes */
+};
+
+local const static_tree_desc  static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local const static_tree_desc  static_d_desc =
+{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
+
+local const static_tree_desc  static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block     OF((deflate_state *s));
+local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
+local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree     OF((deflate_state *s, tree_desc *desc));
+local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local int  build_bl_tree  OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+                              int blcodes));
+local void compress_block OF((deflate_state *s, const ct_data *ltree,
+                              const ct_data *dtree));
+local int  detect_data_type OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup      OF((deflate_state *s));
+local void bi_flush       OF((deflate_state *s));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef ZLIB_DEBUG
+#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+   /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* !ZLIB_DEBUG */
+#  define send_code(s, c, tree) \
+     { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+       send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+    put_byte(s, (uch)((w) & 0xff)); \
+    put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef ZLIB_DEBUG
+local void send_bits      OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+    deflate_state *s;
+    int value;  /* value to send */
+    int length; /* number of bits */
+{
+    Tracevv((stderr," l %2d v %4x ", length, value));
+    Assert(length > 0 && length <= 15, "invalid length");
+    s->bits_sent += (ulg)length;
+
+    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+     * unused bits in value.
+     */
+    if (s->bi_valid > (int)Buf_size - length) {
+        s->bi_buf |= (ush)value << s->bi_valid;
+        put_short(s, s->bi_buf);
+        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+        s->bi_valid += length - Buf_size;
+    } else {
+        s->bi_buf |= (ush)value << s->bi_valid;
+        s->bi_valid += length;
+    }
+}
+#else /* !ZLIB_DEBUG */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+  if (s->bi_valid > (int)Buf_size - len) {\
+    int val = (int)value;\
+    s->bi_buf |= (ush)val << s->bi_valid;\
+    put_short(s, s->bi_buf);\
+    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+    s->bi_valid += len - Buf_size;\
+  } else {\
+    s->bi_buf |= (ush)(value) << s->bi_valid;\
+    s->bi_valid += len;\
+  }\
+}
+#endif /* ZLIB_DEBUG */
+
+
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+    static int static_init_done = 0;
+    int n;        /* iterates over tree elements */
+    int bits;     /* bit counter */
+    int length;   /* length value */
+    int code;     /* code value */
+    int dist;     /* distance index */
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    if (static_init_done) return;
+
+    /* For some embedded targets, global variables are not initialized: */
+#ifdef NO_INIT_GLOBAL_POINTERS
+    static_l_desc.static_tree = static_ltree;
+    static_l_desc.extra_bits = extra_lbits;
+    static_d_desc.static_tree = static_dtree;
+    static_d_desc.extra_bits = extra_dbits;
+    static_bl_desc.extra_bits = extra_blbits;
+#endif
+
+    /* Initialize the mapping length (0..255) -> length code (0..28) */
+    length = 0;
+    for (code = 0; code < LENGTH_CODES-1; code++) {
+        base_length[code] = length;
+        for (n = 0; n < (1<<extra_lbits[code]); n++) {
+            _length_code[length++] = (uch)code;
+        }
+    }
+    Assert (length == 256, "tr_static_init: length != 256");
+    /* Note that the length 255 (match length 258) can be represented
+     * in two different ways: code 284 + 5 bits or code 285, so we
+     * overwrite length_code[255] to use the best encoding:
+     */
+    _length_code[length-1] = (uch)code;
+
+    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+    dist = 0;
+    for (code = 0 ; code < 16; code++) {
+        base_dist[code] = dist;
+        for (n = 0; n < (1<<extra_dbits[code]); n++) {
+            _dist_code[dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: dist != 256");
+    dist >>= 7; /* from now on, all distances are divided by 128 */
+    for ( ; code < D_CODES; code++) {
+        base_dist[code] = dist << 7;
+        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+            _dist_code[256 + dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+    /* Construct the codes of the static literal tree */
+    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+    n = 0;
+    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+    /* Codes 286 and 287 do not exist, but we must include them in the
+     * tree construction to get a canonical Huffman tree (longest code
+     * all ones)
+     */
+    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+    /* The static distance tree is trivial: */
+    for (n = 0; n < D_CODES; n++) {
+        static_dtree[n].Len = 5;
+        static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+    }
+    static_init_done = 1;
+
+#  ifdef GEN_TREES_H
+    gen_trees_header();
+#  endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+#  ifndef ZLIB_DEBUG
+#    include <stdio.h>
+#  endif
+
+#  define SEPARATOR(i, last, width) \
+      ((i) == (last)? "\n};\n\n" :    \
+       ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+    FILE *header = fopen("trees.h", "w");
+    int i;
+
+    Assert (header != NULL, "Can't open trees.h");
+    fprintf(header,
+            "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+    fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+    for (i = 0; i < L_CODES+2; i++) {
+        fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+                static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+    }
+
+    fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+        fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+                static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+    }
+
+    fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n");
+    for (i = 0; i < DIST_CODE_LEN; i++) {
+        fprintf(header, "%2u%s", _dist_code[i],
+                SEPARATOR(i, DIST_CODE_LEN-1, 20));
+    }
+
+    fprintf(header,
+        "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+    for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+        fprintf(header, "%2u%s", _length_code[i],
+                SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+    }
+
+    fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+    for (i = 0; i < LENGTH_CODES; i++) {
+        fprintf(header, "%1u%s", base_length[i],
+                SEPARATOR(i, LENGTH_CODES-1, 20));
+    }
+
+    fprintf(header, "local const int base_dist[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+        fprintf(header, "%5u%s", base_dist[i],
+                SEPARATOR(i, D_CODES-1, 10));
+    }
+
+    fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void ZLIB_INTERNAL _tr_init(s)
+    deflate_state *s;
+{
+    tr_static_init();
+
+    s->l_desc.dyn_tree = s->dyn_ltree;
+    s->l_desc.stat_desc = &static_l_desc;
+
+    s->d_desc.dyn_tree = s->dyn_dtree;
+    s->d_desc.stat_desc = &static_d_desc;
+
+    s->bl_desc.dyn_tree = s->bl_tree;
+    s->bl_desc.stat_desc = &static_bl_desc;
+
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+#ifdef ZLIB_DEBUG
+    s->compressed_len = 0L;
+    s->bits_sent = 0L;
+#endif
+
+    /* Initialize the first block of the first file: */
+    init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+    deflate_state *s;
+{
+    int n; /* iterates over tree elements */
+
+    /* Initialize the trees. */
+    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
+    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
+    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+    s->dyn_ltree[END_BLOCK].Freq = 1;
+    s->opt_len = s->static_len = 0L;
+    s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+    top = s->heap[SMALLEST]; \
+    s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+    pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+   (tree[n].Freq < tree[m].Freq || \
+   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+    deflate_state *s;
+    ct_data *tree;  /* the tree to restore */
+    int k;               /* node to move down */
+{
+    int v = s->heap[k];
+    int j = k << 1;  /* left son of k */
+    while (j <= s->heap_len) {
+        /* Set j to the smallest of the two sons: */
+        if (j < s->heap_len &&
+            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+            j++;
+        }
+        /* Exit if v is smaller than both sons */
+        if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+        /* Exchange v with the smallest son */
+        s->heap[k] = s->heap[j];  k = j;
+
+        /* And continue down the tree, setting j to the left son of k */
+        j <<= 1;
+    }
+    s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ *    above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ *     array bl_count contains the frequencies for each bit length.
+ *     The length opt_len is updated; static_len is also updated if stree is
+ *     not null.
+ */
+local void gen_bitlen(s, desc)
+    deflate_state *s;
+    tree_desc *desc;    /* the tree descriptor */
+{
+    ct_data *tree        = desc->dyn_tree;
+    int max_code         = desc->max_code;
+    const ct_data *stree = desc->stat_desc->static_tree;
+    const intf *extra    = desc->stat_desc->extra_bits;
+    int base             = desc->stat_desc->extra_base;
+    int max_length       = desc->stat_desc->max_length;
+    int h;              /* heap index */
+    int n, m;           /* iterate over the tree elements */
+    int bits;           /* bit length */
+    int xbits;          /* extra bits */
+    ush f;              /* frequency */
+    int overflow = 0;   /* number of elements with bit length too large */
+
+    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+    /* In a first pass, compute the optimal bit lengths (which may
+     * overflow in the case of the bit length tree).
+     */
+    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+        n = s->heap[h];
+        bits = tree[tree[n].Dad].Len + 1;
+        if (bits > max_length) bits = max_length, overflow++;
+        tree[n].Len = (ush)bits;
+        /* We overwrite tree[n].Dad which is no longer needed */
+
+        if (n > max_code) continue; /* not a leaf node */
+
+        s->bl_count[bits]++;
+        xbits = 0;
+        if (n >= base) xbits = extra[n-base];
+        f = tree[n].Freq;
+        s->opt_len += (ulg)f * (unsigned)(bits + xbits);
+        if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits);
+    }
+    if (overflow == 0) return;
+
+    Tracev((stderr,"\nbit length overflow\n"));
+    /* This happens for example on obj2 and pic of the Calgary corpus */
+
+    /* Find the first bit length which could increase: */
+    do {
+        bits = max_length-1;
+        while (s->bl_count[bits] == 0) bits--;
+        s->bl_count[bits]--;      /* move one leaf down the tree */
+        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+        s->bl_count[max_length]--;
+        /* The brother of the overflow item also moves one step up,
+         * but this does not affect bl_count[max_length]
+         */
+        overflow -= 2;
+    } while (overflow > 0);
+
+    /* Now recompute all bit lengths, scanning in increasing frequency.
+     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+     * lengths instead of fixing only the wrong ones. This idea is taken
+     * from 'ar' written by Haruhiko Okumura.)
+     */
+    for (bits = max_length; bits != 0; bits--) {
+        n = s->bl_count[bits];
+        while (n != 0) {
+            m = s->heap[--h];
+            if (m > max_code) continue;
+            if ((unsigned) tree[m].Len != (unsigned) bits) {
+                Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+                s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq;
+                tree[m].Len = (ush)bits;
+            }
+            n--;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ *     zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+    ct_data *tree;             /* the tree to decorate */
+    int max_code;              /* largest code with non zero frequency */
+    ushf *bl_count;            /* number of codes at each bit length */
+{
+    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+    unsigned code = 0;         /* running code value */
+    int bits;                  /* bit index */
+    int n;                     /* code index */
+
+    /* The distribution counts are first used to generate the code values
+     * without bit reversal.
+     */
+    for (bits = 1; bits <= MAX_BITS; bits++) {
+        code = (code + bl_count[bits-1]) << 1;
+        next_code[bits] = (ush)code;
+    }
+    /* Check that the bit counts in bl_count are consistent. The last code
+     * must be all ones.
+     */
+    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+            "inconsistent bit counts");
+    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+    for (n = 0;  n <= max_code; n++) {
+        int len = tree[n].Len;
+        if (len == 0) continue;
+        /* Now reverse the bits */
+        tree[n].Code = (ush)bi_reverse(next_code[len]++, len);
+
+        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+    }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ *     and corresponding code. The length opt_len is updated; static_len is
+ *     also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+    deflate_state *s;
+    tree_desc *desc; /* the tree descriptor */
+{
+    ct_data *tree         = desc->dyn_tree;
+    const ct_data *stree  = desc->stat_desc->static_tree;
+    int elems             = desc->stat_desc->elems;
+    int n, m;          /* iterate over heap elements */
+    int max_code = -1; /* largest code with non zero frequency */
+    int node;          /* new node being created */
+
+    /* Construct the initial heap, with least frequent element in
+     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+     * heap[0] is not used.
+     */
+    s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+    for (n = 0; n < elems; n++) {
+        if (tree[n].Freq != 0) {
+            s->heap[++(s->heap_len)] = max_code = n;
+            s->depth[n] = 0;
+        } else {
+            tree[n].Len = 0;
+        }
+    }
+
+    /* The pkzip format requires that at least one distance code exists,
+     * and that at least one bit should be sent even if there is only one
+     * possible code. So to avoid special checks later on we force at least
+     * two codes of non zero frequency.
+     */
+    while (s->heap_len < 2) {
+        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+        tree[node].Freq = 1;
+        s->depth[node] = 0;
+        s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+        /* node is 0 or 1 so it does not have extra bits */
+    }
+    desc->max_code = max_code;
+
+    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+     * establish sub-heaps of increasing lengths:
+     */
+    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+    /* Construct the Huffman tree by repeatedly combining the least two
+     * frequent nodes.
+     */
+    node = elems;              /* next internal node of the tree */
+    do {
+        pqremove(s, tree, n);  /* n = node of least frequency */
+        m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+        s->heap[--(s->heap_max)] = m;
+
+        /* Create a new node father of n and m */
+        tree[node].Freq = tree[n].Freq + tree[m].Freq;
+        s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
+                                s->depth[n] : s->depth[m]) + 1);
+        tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+        if (tree == s->bl_tree) {
+            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+        }
+#endif
+        /* and insert the new node in the heap */
+        s->heap[SMALLEST] = node++;
+        pqdownheap(s, tree, SMALLEST);
+
+    } while (s->heap_len >= 2);
+
+    s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+    /* At this point, the fields freq and dad are set. We can now
+     * generate the bit lengths.
+     */
+    gen_bitlen(s, (tree_desc *)desc);
+
+    /* The field len is now set, we can generate the bit codes */
+    gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree;   /* the tree to be scanned */
+    int max_code;    /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    if (nextlen == 0) max_count = 138, min_count = 3;
+    tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            s->bl_tree[curlen].Freq += count;
+        } else if (curlen != 0) {
+            if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+            s->bl_tree[REP_3_6].Freq++;
+        } else if (count <= 10) {
+            s->bl_tree[REPZ_3_10].Freq++;
+        } else {
+            s->bl_tree[REPZ_11_138].Freq++;
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree; /* the tree to be scanned */
+    int max_code;       /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    /* tree[max_code+1].Len = -1; */  /* guard already set */
+    if (nextlen == 0) max_count = 138, min_count = 3;
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+        } else if (curlen != 0) {
+            if (curlen != prevlen) {
+                send_code(s, curlen, s->bl_tree); count--;
+            }
+            Assert(count >= 3 && count <= 6, " 3_6?");
+            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+        } else if (count <= 10) {
+            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+        } else {
+            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+    deflate_state *s;
+{
+    int max_blindex;  /* index of last bit length code of non zero freq */
+
+    /* Determine the bit length frequencies for literal and distance trees */
+    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+    /* Build the bit length tree: */
+    build_tree(s, (tree_desc *)(&(s->bl_desc)));
+    /* opt_len now includes the length of the tree representations, except
+     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+     */
+
+    /* Determine the number of bit length codes to send. The pkzip format
+     * requires that at least 4 bit length codes be sent. (appnote.txt says
+     * 3 but the actual value used is 4.)
+     */
+    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+    }
+    /* Update opt_len to include the bit length tree and counts */
+    s->opt_len += 3*((ulg)max_blindex+1) + 5+5+4;
+    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+            s->opt_len, s->static_len));
+
+    return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+    deflate_state *s;
+    int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+    int rank;                    /* index in bl_order */
+
+    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+            "too many codes");
+    Tracev((stderr, "\nbl counts: "));
+    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+    send_bits(s, dcodes-1,   5);
+    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */
+    for (rank = 0; rank < blcodes; rank++) {
+        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+    }
+    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
+    deflate_state *s;
+    charf *buf;       /* input block */
+    ulg stored_len;   /* length of input block */
+    int last;         /* one if this is the last block for a file */
+{
+    send_bits(s, (STORED_BLOCK<<1)+last, 3);    /* send block type */
+    bi_windup(s);        /* align on byte boundary */
+    put_short(s, (ush)stored_len);
+    put_short(s, (ush)~stored_len);
+    zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len);
+    s->pending += stored_len;
+#ifdef ZLIB_DEBUG
+    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+    s->compressed_len += (stored_len + 4) << 3;
+    s->bits_sent += 2*16;
+    s->bits_sent += stored_len<<3;
+#endif
+}
+
+/* ===========================================================================
+ * Flush the bits in the bit buffer to pending output (leaves at most 7 bits)
+ */
+void ZLIB_INTERNAL _tr_flush_bits(s)
+    deflate_state *s;
+{
+    bi_flush(s);
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ */
+void ZLIB_INTERNAL _tr_align(s)
+    deflate_state *s;
+{
+    send_bits(s, STATIC_TREES<<1, 3);
+    send_code(s, END_BLOCK, static_ltree);
+#ifdef ZLIB_DEBUG
+    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+    bi_flush(s);
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and write out the encoded block.
+ */
+void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
+    deflate_state *s;
+    charf *buf;       /* input block, or NULL if too old */
+    ulg stored_len;   /* length of input block */
+    int last;         /* one if this is the last block for a file */
+{
+    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+    int max_blindex = 0;  /* index of last bit length code of non zero freq */
+
+    /* Build the Huffman trees unless a stored block is forced */
+    if (s->level > 0) {
+
+        /* Check if the file is binary or text */
+        if (s->strm->data_type == Z_UNKNOWN)
+            s->strm->data_type = detect_data_type(s);
+
+        /* Construct the literal and distance trees */
+        build_tree(s, (tree_desc *)(&(s->l_desc)));
+        Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+                s->static_len));
+
+        build_tree(s, (tree_desc *)(&(s->d_desc)));
+        Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+                s->static_len));
+        /* At this point, opt_len and static_len are the total bit lengths of
+         * the compressed block data, excluding the tree representations.
+         */
+
+        /* Build the bit length tree for the above two trees, and get the index
+         * in bl_order of the last bit length code to send.
+         */
+        max_blindex = build_bl_tree(s);
+
+        /* Determine the best encoding. Compute the block lengths in bytes. */
+        opt_lenb = (s->opt_len+3+7)>>3;
+        static_lenb = (s->static_len+3+7)>>3;
+
+        Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+                opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+                s->last_lit));
+
+        if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+    } else {
+        Assert(buf != (char*)0, "lost buf");
+        opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+    }
+
+#ifdef FORCE_STORED
+    if (buf != (char*)0) { /* force stored block */
+#else
+    if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+                       /* 4: two words for the lengths */
+#endif
+        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+         * Otherwise we can't have processed more than WSIZE input bytes since
+         * the last block flush, because compression would have been
+         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+         * transform a block into a stored block.
+         */
+        _tr_stored_block(s, buf, stored_len, last);
+
+#ifdef FORCE_STATIC
+    } else if (static_lenb >= 0) { /* force static trees */
+#else
+    } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
+#endif
+        send_bits(s, (STATIC_TREES<<1)+last, 3);
+        compress_block(s, (const ct_data *)static_ltree,
+                       (const ct_data *)static_dtree);
+#ifdef ZLIB_DEBUG
+        s->compressed_len += 3 + s->static_len;
+#endif
+    } else {
+        send_bits(s, (DYN_TREES<<1)+last, 3);
+        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+                       max_blindex+1);
+        compress_block(s, (const ct_data *)s->dyn_ltree,
+                       (const ct_data *)s->dyn_dtree);
+#ifdef ZLIB_DEBUG
+        s->compressed_len += 3 + s->opt_len;
+#endif
+    }
+    Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+    /* The above check is made mod 2^32, for files larger than 512 MB
+     * and uLong implemented on 32 bits.
+     */
+    init_block(s);
+
+    if (last) {
+        bi_windup(s);
+#ifdef ZLIB_DEBUG
+        s->compressed_len += 7;  /* align on byte boundary */
+#endif
+    }
+    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+           s->compressed_len-7*last));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int ZLIB_INTERNAL _tr_tally (s, dist, lc)
+    deflate_state *s;
+    unsigned dist;  /* distance of matched string */
+    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+    s->d_buf[s->last_lit] = (ush)dist;
+    s->l_buf[s->last_lit++] = (uch)lc;
+    if (dist == 0) {
+        /* lc is the unmatched char */
+        s->dyn_ltree[lc].Freq++;
+    } else {
+        s->matches++;
+        /* Here, lc is the match length - MIN_MATCH */
+        dist--;             /* dist = match distance - 1 */
+        Assert((ush)dist < (ush)MAX_DIST(s) &&
+               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+               (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
+
+        s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+        s->dyn_dtree[d_code(dist)].Freq++;
+    }
+
+#ifdef TRUNCATE_BLOCK
+    /* Try to guess if it is profitable to stop the current block here */
+    if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+        /* Compute an upper bound for the compressed length */
+        ulg out_length = (ulg)s->last_lit*8L;
+        ulg in_length = (ulg)((long)s->strstart - s->block_start);
+        int dcode;
+        for (dcode = 0; dcode < D_CODES; dcode++) {
+            out_length += (ulg)s->dyn_dtree[dcode].Freq *
+                (5L+extra_dbits[dcode]);
+        }
+        out_length >>= 3;
+        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+               s->last_lit, in_length, out_length,
+               100L - out_length*100L/in_length));
+        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+    }
+#endif
+    return (s->last_lit == s->lit_bufsize-1);
+    /* We avoid equality with lit_bufsize because of wraparound at 64K
+     * on 16 bit machines and because stored blocks are restricted to
+     * 64K-1 bytes.
+     */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+    deflate_state *s;
+    const ct_data *ltree; /* literal tree */
+    const ct_data *dtree; /* distance tree */
+{
+    unsigned dist;      /* distance of matched string */
+    int lc;             /* match length or unmatched char (if dist == 0) */
+    unsigned lx = 0;    /* running index in l_buf */
+    unsigned code;      /* the code to send */
+    int extra;          /* number of extra bits to send */
+
+    if (s->last_lit != 0) do {
+        dist = s->d_buf[lx];
+        lc = s->l_buf[lx++];
+        if (dist == 0) {
+            send_code(s, lc, ltree); /* send a literal byte */
+            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+        } else {
+            /* Here, lc is the match length - MIN_MATCH */
+            code = _length_code[lc];
+            send_code(s, code+LITERALS+1, ltree); /* send the length code */
+            extra = extra_lbits[code];
+            if (extra != 0) {
+                lc -= base_length[code];
+                send_bits(s, lc, extra);       /* send the extra length bits */
+            }
+            dist--; /* dist is now the match distance - 1 */
+            code = d_code(dist);
+            Assert (code < D_CODES, "bad d_code");
+
+            send_code(s, code, dtree);       /* send the distance code */
+            extra = extra_dbits[code];
+            if (extra != 0) {
+                dist -= (unsigned)base_dist[code];
+                send_bits(s, dist, extra);   /* send the extra distance bits */
+            }
+        } /* literal or match pair ? */
+
+        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+        Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
+               "pendingBuf overflow");
+
+    } while (lx < s->last_lit);
+
+    send_code(s, END_BLOCK, ltree);
+}
+
+/* ===========================================================================
+ * Check if the data type is TEXT or BINARY, using the following algorithm:
+ * - TEXT if the two conditions below are satisfied:
+ *    a) There are no non-portable control characters belonging to the
+ *       "black list" (0..6, 14..25, 28..31).
+ *    b) There is at least one printable character belonging to the
+ *       "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
+ * - BINARY otherwise.
+ * - The following partially-portable control characters form a
+ *   "gray list" that is ignored in this detection algorithm:
+ *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
+ * IN assertion: the fields Freq of dyn_ltree are set.
+ */
+local int detect_data_type(s)
+    deflate_state *s;
+{
+    /* black_mask is the bit mask of black-listed bytes
+     * set bits 0..6, 14..25, and 28..31
+     * 0xf3ffc07f = binary 11110011111111111100000001111111
+     */
+    unsigned long black_mask = 0xf3ffc07fUL;
+    int n;
+
+    /* Check for non-textual ("black-listed") bytes. */
+    for (n = 0; n <= 31; n++, black_mask >>= 1)
+        if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0))
+            return Z_BINARY;
+
+    /* Check for textual ("white-listed") bytes. */
+    if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
+            || s->dyn_ltree[13].Freq != 0)
+        return Z_TEXT;
+    for (n = 32; n < LITERALS; n++)
+        if (s->dyn_ltree[n].Freq != 0)
+            return Z_TEXT;
+
+    /* There are no "black-listed" or "white-listed" bytes:
+     * this stream either is empty or has tolerated ("gray-listed") bytes only.
+     */
+    return Z_BINARY;
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+    unsigned code; /* the value to invert */
+    int len;       /* its bit length */
+{
+    register unsigned res = 0;
+    do {
+        res |= code & 1;
+        code >>= 1, res <<= 1;
+    } while (--len > 0);
+    return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+    deflate_state *s;
+{
+    if (s->bi_valid == 16) {
+        put_short(s, s->bi_buf);
+        s->bi_buf = 0;
+        s->bi_valid = 0;
+    } else if (s->bi_valid >= 8) {
+        put_byte(s, (Byte)s->bi_buf);
+        s->bi_buf >>= 8;
+        s->bi_valid -= 8;
+    }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+    deflate_state *s;
+{
+    if (s->bi_valid > 8) {
+        put_short(s, s->bi_buf);
+    } else if (s->bi_valid > 0) {
+        put_byte(s, (Byte)s->bi_buf);
+    }
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+#ifdef ZLIB_DEBUG
+    s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
Index: EcnlProtoTool/trunk/zlib-1.2.11/trees.h
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/trees.h	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/trees.h	(revision 331)
@@ -0,0 +1,128 @@
+/* header created automatically with -DGEN_TREES_H */
+
+local const ct_data static_ltree[L_CODES+2] = {
+{{ 12},{  8}}, {{140},{  8}}, {{ 76},{  8}}, {{204},{  8}}, {{ 44},{  8}},
+{{172},{  8}}, {{108},{  8}}, {{236},{  8}}, {{ 28},{  8}}, {{156},{  8}},
+{{ 92},{  8}}, {{220},{  8}}, {{ 60},{  8}}, {{188},{  8}}, {{124},{  8}},
+{{252},{  8}}, {{  2},{  8}}, {{130},{  8}}, {{ 66},{  8}}, {{194},{  8}},
+{{ 34},{  8}}, {{162},{  8}}, {{ 98},{  8}}, {{226},{  8}}, {{ 18},{  8}},
+{{146},{  8}}, {{ 82},{  8}}, {{210},{  8}}, {{ 50},{  8}}, {{178},{  8}},
+{{114},{  8}}, {{242},{  8}}, {{ 10},{  8}}, {{138},{  8}}, {{ 74},{  8}},
+{{202},{  8}}, {{ 42},{  8}}, {{170},{  8}}, {{106},{  8}}, {{234},{  8}},
+{{ 26},{  8}}, {{154},{  8}}, {{ 90},{  8}}, {{218},{  8}}, {{ 58},{  8}},
+{{186},{  8}}, {{122},{  8}}, {{250},{  8}}, {{  6},{  8}}, {{134},{  8}},
+{{ 70},{  8}}, {{198},{  8}}, {{ 38},{  8}}, {{166},{  8}}, {{102},{  8}},
+{{230},{  8}}, {{ 22},{  8}}, {{150},{  8}}, {{ 86},{  8}}, {{214},{  8}},
+{{ 54},{  8}}, {{182},{  8}}, {{118},{  8}}, {{246},{  8}}, {{ 14},{  8}},
+{{142},{  8}}, {{ 78},{  8}}, {{206},{  8}}, {{ 46},{  8}}, {{174},{  8}},
+{{110},{  8}}, {{238},{  8}}, {{ 30},{  8}}, {{158},{  8}}, {{ 94},{  8}},
+{{222},{  8}}, {{ 62},{  8}}, {{190},{  8}}, {{126},{  8}}, {{254},{  8}},
+{{  1},{  8}}, {{129},{  8}}, {{ 65},{  8}}, {{193},{  8}}, {{ 33},{  8}},
+{{161},{  8}}, {{ 97},{  8}}, {{225},{  8}}, {{ 17},{  8}}, {{145},{  8}},
+{{ 81},{  8}}, {{209},{  8}}, {{ 49},{  8}}, {{177},{  8}}, {{113},{  8}},
+{{241},{  8}}, {{  9},{  8}}, {{137},{  8}}, {{ 73},{  8}}, {{201},{  8}},
+{{ 41},{  8}}, {{169},{  8}}, {{105},{  8}}, {{233},{  8}}, {{ 25},{  8}},
+{{153},{  8}}, {{ 89},{  8}}, {{217},{  8}}, {{ 57},{  8}}, {{185},{  8}},
+{{121},{  8}}, {{249},{  8}}, {{  5},{  8}}, {{133},{  8}}, {{ 69},{  8}},
+{{197},{  8}}, {{ 37},{  8}}, {{165},{  8}}, {{101},{  8}}, {{229},{  8}},
+{{ 21},{  8}}, {{149},{  8}}, {{ 85},{  8}}, {{213},{  8}}, {{ 53},{  8}},
+{{181},{  8}}, {{117},{  8}}, {{245},{  8}}, {{ 13},{  8}}, {{141},{  8}},
+{{ 77},{  8}}, {{205},{  8}}, {{ 45},{  8}}, {{173},{  8}}, {{109},{  8}},
+{{237},{  8}}, {{ 29},{  8}}, {{157},{  8}}, {{ 93},{  8}}, {{221},{  8}},
+{{ 61},{  8}}, {{189},{  8}}, {{125},{  8}}, {{253},{  8}}, {{ 19},{  9}},
+{{275},{  9}}, {{147},{  9}}, {{403},{  9}}, {{ 83},{  9}}, {{339},{  9}},
+{{211},{  9}}, {{467},{  9}}, {{ 51},{  9}}, {{307},{  9}}, {{179},{  9}},
+{{435},{  9}}, {{115},{  9}}, {{371},{  9}}, {{243},{  9}}, {{499},{  9}},
+{{ 11},{  9}}, {{267},{  9}}, {{139},{  9}}, {{395},{  9}}, {{ 75},{  9}},
+{{331},{  9}}, {{203},{  9}}, {{459},{  9}}, {{ 43},{  9}}, {{299},{  9}},
+{{171},{  9}}, {{427},{  9}}, {{107},{  9}}, {{363},{  9}}, {{235},{  9}},
+{{491},{  9}}, {{ 27},{  9}}, {{283},{  9}}, {{155},{  9}}, {{411},{  9}},
+{{ 91},{  9}}, {{347},{  9}}, {{219},{  9}}, {{475},{  9}}, {{ 59},{  9}},
+{{315},{  9}}, {{187},{  9}}, {{443},{  9}}, {{123},{  9}}, {{379},{  9}},
+{{251},{  9}}, {{507},{  9}}, {{  7},{  9}}, {{263},{  9}}, {{135},{  9}},
+{{391},{  9}}, {{ 71},{  9}}, {{327},{  9}}, {{199},{  9}}, {{455},{  9}},
+{{ 39},{  9}}, {{295},{  9}}, {{167},{  9}}, {{423},{  9}}, {{103},{  9}},
+{{359},{  9}}, {{231},{  9}}, {{487},{  9}}, {{ 23},{  9}}, {{279},{  9}},
+{{151},{  9}}, {{407},{  9}}, {{ 87},{  9}}, {{343},{  9}}, {{215},{  9}},
+{{471},{  9}}, {{ 55},{  9}}, {{311},{  9}}, {{183},{  9}}, {{439},{  9}},
+{{119},{  9}}, {{375},{  9}}, {{247},{  9}}, {{503},{  9}}, {{ 15},{  9}},
+{{271},{  9}}, {{143},{  9}}, {{399},{  9}}, {{ 79},{  9}}, {{335},{  9}},
+{{207},{  9}}, {{463},{  9}}, {{ 47},{  9}}, {{303},{  9}}, {{175},{  9}},
+{{431},{  9}}, {{111},{  9}}, {{367},{  9}}, {{239},{  9}}, {{495},{  9}},
+{{ 31},{  9}}, {{287},{  9}}, {{159},{  9}}, {{415},{  9}}, {{ 95},{  9}},
+{{351},{  9}}, {{223},{  9}}, {{479},{  9}}, {{ 63},{  9}}, {{319},{  9}},
+{{191},{  9}}, {{447},{  9}}, {{127},{  9}}, {{383},{  9}}, {{255},{  9}},
+{{511},{  9}}, {{  0},{  7}}, {{ 64},{  7}}, {{ 32},{  7}}, {{ 96},{  7}},
+{{ 16},{  7}}, {{ 80},{  7}}, {{ 48},{  7}}, {{112},{  7}}, {{  8},{  7}},
+{{ 72},{  7}}, {{ 40},{  7}}, {{104},{  7}}, {{ 24},{  7}}, {{ 88},{  7}},
+{{ 56},{  7}}, {{120},{  7}}, {{  4},{  7}}, {{ 68},{  7}}, {{ 36},{  7}},
+{{100},{  7}}, {{ 20},{  7}}, {{ 84},{  7}}, {{ 52},{  7}}, {{116},{  7}},
+{{  3},{  8}}, {{131},{  8}}, {{ 67},{  8}}, {{195},{  8}}, {{ 35},{  8}},
+{{163},{  8}}, {{ 99},{  8}}, {{227},{  8}}
+};
+
+local const ct_data static_dtree[D_CODES] = {
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
+};
+
+const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {
+ 0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,
+ 8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10,
+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  0,  0, 16, 17,
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+};
+
+const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {
+ 0,  1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 12,
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
+};
+
+local const int base_length[LENGTH_CODES] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+64, 80, 96, 112, 128, 160, 192, 224, 0
+};
+
+local const int base_dist[D_CODES] = {
+    0,     1,     2,     3,     4,     6,     8,    12,    16,    24,
+   32,    48,    64,    96,   128,   192,   256,   384,   512,   768,
+ 1024,  1536,  2048,  3072,  4096,  6144,  8192, 12288, 16384, 24576
+};
+
Index: EcnlProtoTool/trunk/zlib-1.2.11/uncompr.c
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/uncompr.c	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/uncompr.c	(revision 331)
@@ -0,0 +1,93 @@
+/* uncompr.c -- decompress a memory buffer
+ * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+     Decompresses the source buffer into the destination buffer.  *sourceLen is
+   the byte length of the source buffer. Upon entry, *destLen is the total size
+   of the destination buffer, which must be large enough to hold the entire
+   uncompressed data. (The size of the uncompressed data must have been saved
+   previously by the compressor and transmitted to the decompressor by some
+   mechanism outside the scope of this compression library.) Upon exit,
+   *destLen is the size of the decompressed data and *sourceLen is the number
+   of source bytes consumed. Upon return, source + *sourceLen points to the
+   first unused input byte.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer, or
+   Z_DATA_ERROR if the input data was corrupted, including if the input data is
+   an incomplete zlib stream.
+*/
+int ZEXPORT uncompress2 (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong *sourceLen;
+{
+    z_stream stream;
+    int err;
+    const uInt max = (uInt)-1;
+    uLong len, left;
+    Byte buf[1];    /* for detection of incomplete stream when *destLen == 0 */
+
+    len = *sourceLen;
+    if (*destLen) {
+        left = *destLen;
+        *destLen = 0;
+    }
+    else {
+        left = 1;
+        dest = buf;
+    }
+
+    stream.next_in = (z_const Bytef *)source;
+    stream.avail_in = 0;
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+    stream.opaque = (voidpf)0;
+
+    err = inflateInit(&stream);
+    if (err != Z_OK) return err;
+
+    stream.next_out = dest;
+    stream.avail_out = 0;
+
+    do {
+        if (stream.avail_out == 0) {
+            stream.avail_out = left > (uLong)max ? max : (uInt)left;
+            left -= stream.avail_out;
+        }
+        if (stream.avail_in == 0) {
+            stream.avail_in = len > (uLong)max ? max : (uInt)len;
+            len -= stream.avail_in;
+        }
+        err = inflate(&stream, Z_NO_FLUSH);
+    } while (err == Z_OK);
+
+    *sourceLen -= len + stream.avail_in;
+    if (dest != buf)
+        *destLen = stream.total_out;
+    else if (stream.total_out && err == Z_BUF_ERROR)
+        left = 1;
+
+    inflateEnd(&stream);
+    return err == Z_STREAM_END ? Z_OK :
+           err == Z_NEED_DICT ? Z_DATA_ERROR  :
+           err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR :
+           err;
+}
+
+int ZEXPORT uncompress (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+{
+    return uncompress2(dest, destLen, source, &sourceLen);
+}
Index: EcnlProtoTool/trunk/zlib-1.2.11/zconf.h
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/zconf.h	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/zconf.h	(revision 331)
@@ -0,0 +1,534 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */
+#  define Z_PREFIX_SET
+
+/* all linked symbols and init macros */
+#  define _dist_code            z__dist_code
+#  define _length_code          z__length_code
+#  define _tr_align             z__tr_align
+#  define _tr_flush_bits        z__tr_flush_bits
+#  define _tr_flush_block       z__tr_flush_block
+#  define _tr_init              z__tr_init
+#  define _tr_stored_block      z__tr_stored_block
+#  define _tr_tally             z__tr_tally
+#  define adler32               z_adler32
+#  define adler32_combine       z_adler32_combine
+#  define adler32_combine64     z_adler32_combine64
+#  define adler32_z             z_adler32_z
+#  ifndef Z_SOLO
+#    define compress              z_compress
+#    define compress2             z_compress2
+#    define compressBound         z_compressBound
+#  endif
+#  define crc32                 z_crc32
+#  define crc32_combine         z_crc32_combine
+#  define crc32_combine64       z_crc32_combine64
+#  define crc32_z               z_crc32_z
+#  define deflate               z_deflate
+#  define deflateBound          z_deflateBound
+#  define deflateCopy           z_deflateCopy
+#  define deflateEnd            z_deflateEnd
+#  define deflateGetDictionary  z_deflateGetDictionary
+#  define deflateInit           z_deflateInit
+#  define deflateInit2          z_deflateInit2
+#  define deflateInit2_         z_deflateInit2_
+#  define deflateInit_          z_deflateInit_
+#  define deflateParams         z_deflateParams
+#  define deflatePending        z_deflatePending
+#  define deflatePrime          z_deflatePrime
+#  define deflateReset          z_deflateReset
+#  define deflateResetKeep      z_deflateResetKeep
+#  define deflateSetDictionary  z_deflateSetDictionary
+#  define deflateSetHeader      z_deflateSetHeader
+#  define deflateTune           z_deflateTune
+#  define deflate_copyright     z_deflate_copyright
+#  define get_crc_table         z_get_crc_table
+#  ifndef Z_SOLO
+#    define gz_error              z_gz_error
+#    define gz_intmax             z_gz_intmax
+#    define gz_strwinerror        z_gz_strwinerror
+#    define gzbuffer              z_gzbuffer
+#    define gzclearerr            z_gzclearerr
+#    define gzclose               z_gzclose
+#    define gzclose_r             z_gzclose_r
+#    define gzclose_w             z_gzclose_w
+#    define gzdirect              z_gzdirect
+#    define gzdopen               z_gzdopen
+#    define gzeof                 z_gzeof
+#    define gzerror               z_gzerror
+#    define gzflush               z_gzflush
+#    define gzfread               z_gzfread
+#    define gzfwrite              z_gzfwrite
+#    define gzgetc                z_gzgetc
+#    define gzgetc_               z_gzgetc_
+#    define gzgets                z_gzgets
+#    define gzoffset              z_gzoffset
+#    define gzoffset64            z_gzoffset64
+#    define gzopen                z_gzopen
+#    define gzopen64              z_gzopen64
+#    ifdef _WIN32
+#      define gzopen_w              z_gzopen_w
+#    endif
+#    define gzprintf              z_gzprintf
+#    define gzputc                z_gzputc
+#    define gzputs                z_gzputs
+#    define gzread                z_gzread
+#    define gzrewind              z_gzrewind
+#    define gzseek                z_gzseek
+#    define gzseek64              z_gzseek64
+#    define gzsetparams           z_gzsetparams
+#    define gztell                z_gztell
+#    define gztell64              z_gztell64
+#    define gzungetc              z_gzungetc
+#    define gzvprintf             z_gzvprintf
+#    define gzwrite               z_gzwrite
+#  endif
+#  define inflate               z_inflate
+#  define inflateBack           z_inflateBack
+#  define inflateBackEnd        z_inflateBackEnd
+#  define inflateBackInit       z_inflateBackInit
+#  define inflateBackInit_      z_inflateBackInit_
+#  define inflateCodesUsed      z_inflateCodesUsed
+#  define inflateCopy           z_inflateCopy
+#  define inflateEnd            z_inflateEnd
+#  define inflateGetDictionary  z_inflateGetDictionary
+#  define inflateGetHeader      z_inflateGetHeader
+#  define inflateInit           z_inflateInit
+#  define inflateInit2          z_inflateInit2
+#  define inflateInit2_         z_inflateInit2_
+#  define inflateInit_          z_inflateInit_
+#  define inflateMark           z_inflateMark
+#  define inflatePrime          z_inflatePrime
+#  define inflateReset          z_inflateReset
+#  define inflateReset2         z_inflateReset2
+#  define inflateResetKeep      z_inflateResetKeep
+#  define inflateSetDictionary  z_inflateSetDictionary
+#  define inflateSync           z_inflateSync
+#  define inflateSyncPoint      z_inflateSyncPoint
+#  define inflateUndermine      z_inflateUndermine
+#  define inflateValidate       z_inflateValidate
+#  define inflate_copyright     z_inflate_copyright
+#  define inflate_fast          z_inflate_fast
+#  define inflate_table         z_inflate_table
+#  ifndef Z_SOLO
+#    define uncompress            z_uncompress
+#    define uncompress2           z_uncompress2
+#  endif
+#  define zError                z_zError
+#  ifndef Z_SOLO
+#    define zcalloc               z_zcalloc
+#    define zcfree                z_zcfree
+#  endif
+#  define zlibCompileFlags      z_zlibCompileFlags
+#  define zlibVersion           z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+#  define Byte                  z_Byte
+#  define Bytef                 z_Bytef
+#  define alloc_func            z_alloc_func
+#  define charf                 z_charf
+#  define free_func             z_free_func
+#  ifndef Z_SOLO
+#    define gzFile                z_gzFile
+#  endif
+#  define gz_header             z_gz_header
+#  define gz_headerp            z_gz_headerp
+#  define in_func               z_in_func
+#  define intf                  z_intf
+#  define out_func              z_out_func
+#  define uInt                  z_uInt
+#  define uIntf                 z_uIntf
+#  define uLong                 z_uLong
+#  define uLongf                z_uLongf
+#  define voidp                 z_voidp
+#  define voidpc                z_voidpc
+#  define voidpf                z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+#  define gz_header_s           z_gz_header_s
+#  define internal_state        z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#  ifndef STDC
+#    define STDC
+#  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const       /* note: need a more gentle solution here */
+#  endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+#  define z_const const
+#else
+#  define z_const
+#endif
+
+#ifdef Z_SOLO
+   typedef unsigned long z_size_t;
+#else
+#  define z_longlong long long
+#  if defined(NO_SIZE_T)
+     typedef unsigned NO_SIZE_T z_size_t;
+#  elif defined(STDC)
+#    include <stddef.h>
+     typedef size_t z_size_t;
+#  else
+     typedef unsigned long z_size_t;
+#  endif
+#  undef z_longlong
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus about 7 kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+#  if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#    define Z_ARG(args)  args
+#  else
+#    define Z_ARG(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
+#    else
+#      define ZEXPORTVA FAR CDECL
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
+#else
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
+#endif
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+#  include <limits.h>
+#  if (UINT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned
+#  elif (ULONG_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned long
+#  elif (USHRT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned short
+#  endif
+#endif
+
+#ifdef Z_U4
+   typedef Z_U4 z_crc_t;
+#else
+   typedef unsigned long z_crc_t;
+#endif
+
+#ifdef HAVE_UNISTD_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef HAVE_STDARG_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+#  ifndef Z_SOLO
+#    include <sys/types.h>      /* for off_t */
+#  endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifndef Z_SOLO
+#    include <stdarg.h>         /* for va_list */
+#  endif
+#endif
+
+#ifdef _WIN32
+#  ifndef Z_SOLO
+#    include <stddef.h>         /* for wchar_t */
+#  endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+#  undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+#  define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+#  if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+#    include <unistd.h>         /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+#    ifdef VMS
+#      include <unixio.h>       /* for off_t */
+#    endif
+#    ifndef z_off_t
+#      define z_off_t off_t
+#    endif
+#  endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+#  define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+#  define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+#  define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+#  define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+#  define z_off64_t off64_t
+#else
+#  if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+#    define z_off64_t __int64
+#  else
+#    define z_off64_t z_off_t
+#  endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+  #pragma map(deflateInit_,"DEIN")
+  #pragma map(deflateInit2_,"DEIN2")
+  #pragma map(deflateEnd,"DEEND")
+  #pragma map(deflateBound,"DEBND")
+  #pragma map(inflateInit_,"ININ")
+  #pragma map(inflateInit2_,"ININ2")
+  #pragma map(inflateEnd,"INEND")
+  #pragma map(inflateSync,"INSY")
+  #pragma map(inflateSetDictionary,"INSEDI")
+  #pragma map(compressBound,"CMBND")
+  #pragma map(inflate_table,"INTABL")
+  #pragma map(inflate_fast,"INFA")
+  #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
Index: EcnlProtoTool/trunk/zlib-1.2.11/zconf.h.cmakein
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/zconf.h.cmakein	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/zconf.h.cmakein	(revision 331)
@@ -0,0 +1,536 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+#cmakedefine Z_PREFIX
+#cmakedefine Z_HAVE_UNISTD_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */
+#  define Z_PREFIX_SET
+
+/* all linked symbols and init macros */
+#  define _dist_code            z__dist_code
+#  define _length_code          z__length_code
+#  define _tr_align             z__tr_align
+#  define _tr_flush_bits        z__tr_flush_bits
+#  define _tr_flush_block       z__tr_flush_block
+#  define _tr_init              z__tr_init
+#  define _tr_stored_block      z__tr_stored_block
+#  define _tr_tally             z__tr_tally
+#  define adler32               z_adler32
+#  define adler32_combine       z_adler32_combine
+#  define adler32_combine64     z_adler32_combine64
+#  define adler32_z             z_adler32_z
+#  ifndef Z_SOLO
+#    define compress              z_compress
+#    define compress2             z_compress2
+#    define compressBound         z_compressBound
+#  endif
+#  define crc32                 z_crc32
+#  define crc32_combine         z_crc32_combine
+#  define crc32_combine64       z_crc32_combine64
+#  define crc32_z               z_crc32_z
+#  define deflate               z_deflate
+#  define deflateBound          z_deflateBound
+#  define deflateCopy           z_deflateCopy
+#  define deflateEnd            z_deflateEnd
+#  define deflateGetDictionary  z_deflateGetDictionary
+#  define deflateInit           z_deflateInit
+#  define deflateInit2          z_deflateInit2
+#  define deflateInit2_         z_deflateInit2_
+#  define deflateInit_          z_deflateInit_
+#  define deflateParams         z_deflateParams
+#  define deflatePending        z_deflatePending
+#  define deflatePrime          z_deflatePrime
+#  define deflateReset          z_deflateReset
+#  define deflateResetKeep      z_deflateResetKeep
+#  define deflateSetDictionary  z_deflateSetDictionary
+#  define deflateSetHeader      z_deflateSetHeader
+#  define deflateTune           z_deflateTune
+#  define deflate_copyright     z_deflate_copyright
+#  define get_crc_table         z_get_crc_table
+#  ifndef Z_SOLO
+#    define gz_error              z_gz_error
+#    define gz_intmax             z_gz_intmax
+#    define gz_strwinerror        z_gz_strwinerror
+#    define gzbuffer              z_gzbuffer
+#    define gzclearerr            z_gzclearerr
+#    define gzclose               z_gzclose
+#    define gzclose_r             z_gzclose_r
+#    define gzclose_w             z_gzclose_w
+#    define gzdirect              z_gzdirect
+#    define gzdopen               z_gzdopen
+#    define gzeof                 z_gzeof
+#    define gzerror               z_gzerror
+#    define gzflush               z_gzflush
+#    define gzfread               z_gzfread
+#    define gzfwrite              z_gzfwrite
+#    define gzgetc                z_gzgetc
+#    define gzgetc_               z_gzgetc_
+#    define gzgets                z_gzgets
+#    define gzoffset              z_gzoffset
+#    define gzoffset64            z_gzoffset64
+#    define gzopen                z_gzopen
+#    define gzopen64              z_gzopen64
+#    ifdef _WIN32
+#      define gzopen_w              z_gzopen_w
+#    endif
+#    define gzprintf              z_gzprintf
+#    define gzputc                z_gzputc
+#    define gzputs                z_gzputs
+#    define gzread                z_gzread
+#    define gzrewind              z_gzrewind
+#    define gzseek                z_gzseek
+#    define gzseek64              z_gzseek64
+#    define gzsetparams           z_gzsetparams
+#    define gztell                z_gztell
+#    define gztell64              z_gztell64
+#    define gzungetc              z_gzungetc
+#    define gzvprintf             z_gzvprintf
+#    define gzwrite               z_gzwrite
+#  endif
+#  define inflate               z_inflate
+#  define inflateBack           z_inflateBack
+#  define inflateBackEnd        z_inflateBackEnd
+#  define inflateBackInit       z_inflateBackInit
+#  define inflateBackInit_      z_inflateBackInit_
+#  define inflateCodesUsed      z_inflateCodesUsed
+#  define inflateCopy           z_inflateCopy
+#  define inflateEnd            z_inflateEnd
+#  define inflateGetDictionary  z_inflateGetDictionary
+#  define inflateGetHeader      z_inflateGetHeader
+#  define inflateInit           z_inflateInit
+#  define inflateInit2          z_inflateInit2
+#  define inflateInit2_         z_inflateInit2_
+#  define inflateInit_          z_inflateInit_
+#  define inflateMark           z_inflateMark
+#  define inflatePrime          z_inflatePrime
+#  define inflateReset          z_inflateReset
+#  define inflateReset2         z_inflateReset2
+#  define inflateResetKeep      z_inflateResetKeep
+#  define inflateSetDictionary  z_inflateSetDictionary
+#  define inflateSync           z_inflateSync
+#  define inflateSyncPoint      z_inflateSyncPoint
+#  define inflateUndermine      z_inflateUndermine
+#  define inflateValidate       z_inflateValidate
+#  define inflate_copyright     z_inflate_copyright
+#  define inflate_fast          z_inflate_fast
+#  define inflate_table         z_inflate_table
+#  ifndef Z_SOLO
+#    define uncompress            z_uncompress
+#    define uncompress2           z_uncompress2
+#  endif
+#  define zError                z_zError
+#  ifndef Z_SOLO
+#    define zcalloc               z_zcalloc
+#    define zcfree                z_zcfree
+#  endif
+#  define zlibCompileFlags      z_zlibCompileFlags
+#  define zlibVersion           z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+#  define Byte                  z_Byte
+#  define Bytef                 z_Bytef
+#  define alloc_func            z_alloc_func
+#  define charf                 z_charf
+#  define free_func             z_free_func
+#  ifndef Z_SOLO
+#    define gzFile                z_gzFile
+#  endif
+#  define gz_header             z_gz_header
+#  define gz_headerp            z_gz_headerp
+#  define in_func               z_in_func
+#  define intf                  z_intf
+#  define out_func              z_out_func
+#  define uInt                  z_uInt
+#  define uIntf                 z_uIntf
+#  define uLong                 z_uLong
+#  define uLongf                z_uLongf
+#  define voidp                 z_voidp
+#  define voidpc                z_voidpc
+#  define voidpf                z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+#  define gz_header_s           z_gz_header_s
+#  define internal_state        z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#  ifndef STDC
+#    define STDC
+#  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const       /* note: need a more gentle solution here */
+#  endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+#  define z_const const
+#else
+#  define z_const
+#endif
+
+#ifdef Z_SOLO
+   typedef unsigned long z_size_t;
+#else
+#  define z_longlong long long
+#  if defined(NO_SIZE_T)
+     typedef unsigned NO_SIZE_T z_size_t;
+#  elif defined(STDC)
+#    include <stddef.h>
+     typedef size_t z_size_t;
+#  else
+     typedef unsigned long z_size_t;
+#  endif
+#  undef z_longlong
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus about 7 kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+#  if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#    define Z_ARG(args)  args
+#  else
+#    define Z_ARG(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
+#    else
+#      define ZEXPORTVA FAR CDECL
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
+#else
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
+#endif
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+#  include <limits.h>
+#  if (UINT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned
+#  elif (ULONG_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned long
+#  elif (USHRT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned short
+#  endif
+#endif
+
+#ifdef Z_U4
+   typedef Z_U4 z_crc_t;
+#else
+   typedef unsigned long z_crc_t;
+#endif
+
+#ifdef HAVE_UNISTD_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef HAVE_STDARG_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+#  ifndef Z_SOLO
+#    include <sys/types.h>      /* for off_t */
+#  endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifndef Z_SOLO
+#    include <stdarg.h>         /* for va_list */
+#  endif
+#endif
+
+#ifdef _WIN32
+#  ifndef Z_SOLO
+#    include <stddef.h>         /* for wchar_t */
+#  endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+#  undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+#  define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+#  if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+#    include <unistd.h>         /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+#    ifdef VMS
+#      include <unixio.h>       /* for off_t */
+#    endif
+#    ifndef z_off_t
+#      define z_off_t off_t
+#    endif
+#  endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+#  define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+#  define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+#  define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+#  define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+#  define z_off64_t off64_t
+#else
+#  if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+#    define z_off64_t __int64
+#  else
+#    define z_off64_t z_off_t
+#  endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+  #pragma map(deflateInit_,"DEIN")
+  #pragma map(deflateInit2_,"DEIN2")
+  #pragma map(deflateEnd,"DEEND")
+  #pragma map(deflateBound,"DEBND")
+  #pragma map(inflateInit_,"ININ")
+  #pragma map(inflateInit2_,"ININ2")
+  #pragma map(inflateEnd,"INEND")
+  #pragma map(inflateSync,"INSY")
+  #pragma map(inflateSetDictionary,"INSEDI")
+  #pragma map(compressBound,"CMBND")
+  #pragma map(inflate_table,"INTABL")
+  #pragma map(inflate_fast,"INFA")
+  #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
Index: EcnlProtoTool/trunk/zlib-1.2.11/zconf.h.in
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/zconf.h.in	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/zconf.h.in	(revision 331)
@@ -0,0 +1,534 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */
+#  define Z_PREFIX_SET
+
+/* all linked symbols and init macros */
+#  define _dist_code            z__dist_code
+#  define _length_code          z__length_code
+#  define _tr_align             z__tr_align
+#  define _tr_flush_bits        z__tr_flush_bits
+#  define _tr_flush_block       z__tr_flush_block
+#  define _tr_init              z__tr_init
+#  define _tr_stored_block      z__tr_stored_block
+#  define _tr_tally             z__tr_tally
+#  define adler32               z_adler32
+#  define adler32_combine       z_adler32_combine
+#  define adler32_combine64     z_adler32_combine64
+#  define adler32_z             z_adler32_z
+#  ifndef Z_SOLO
+#    define compress              z_compress
+#    define compress2             z_compress2
+#    define compressBound         z_compressBound
+#  endif
+#  define crc32                 z_crc32
+#  define crc32_combine         z_crc32_combine
+#  define crc32_combine64       z_crc32_combine64
+#  define crc32_z               z_crc32_z
+#  define deflate               z_deflate
+#  define deflateBound          z_deflateBound
+#  define deflateCopy           z_deflateCopy
+#  define deflateEnd            z_deflateEnd
+#  define deflateGetDictionary  z_deflateGetDictionary
+#  define deflateInit           z_deflateInit
+#  define deflateInit2          z_deflateInit2
+#  define deflateInit2_         z_deflateInit2_
+#  define deflateInit_          z_deflateInit_
+#  define deflateParams         z_deflateParams
+#  define deflatePending        z_deflatePending
+#  define deflatePrime          z_deflatePrime
+#  define deflateReset          z_deflateReset
+#  define deflateResetKeep      z_deflateResetKeep
+#  define deflateSetDictionary  z_deflateSetDictionary
+#  define deflateSetHeader      z_deflateSetHeader
+#  define deflateTune           z_deflateTune
+#  define deflate_copyright     z_deflate_copyright
+#  define get_crc_table         z_get_crc_table
+#  ifndef Z_SOLO
+#    define gz_error              z_gz_error
+#    define gz_intmax             z_gz_intmax
+#    define gz_strwinerror        z_gz_strwinerror
+#    define gzbuffer              z_gzbuffer
+#    define gzclearerr            z_gzclearerr
+#    define gzclose               z_gzclose
+#    define gzclose_r             z_gzclose_r
+#    define gzclose_w             z_gzclose_w
+#    define gzdirect              z_gzdirect
+#    define gzdopen               z_gzdopen
+#    define gzeof                 z_gzeof
+#    define gzerror               z_gzerror
+#    define gzflush               z_gzflush
+#    define gzfread               z_gzfread
+#    define gzfwrite              z_gzfwrite
+#    define gzgetc                z_gzgetc
+#    define gzgetc_               z_gzgetc_
+#    define gzgets                z_gzgets
+#    define gzoffset              z_gzoffset
+#    define gzoffset64            z_gzoffset64
+#    define gzopen                z_gzopen
+#    define gzopen64              z_gzopen64
+#    ifdef _WIN32
+#      define gzopen_w              z_gzopen_w
+#    endif
+#    define gzprintf              z_gzprintf
+#    define gzputc                z_gzputc
+#    define gzputs                z_gzputs
+#    define gzread                z_gzread
+#    define gzrewind              z_gzrewind
+#    define gzseek                z_gzseek
+#    define gzseek64              z_gzseek64
+#    define gzsetparams           z_gzsetparams
+#    define gztell                z_gztell
+#    define gztell64              z_gztell64
+#    define gzungetc              z_gzungetc
+#    define gzvprintf             z_gzvprintf
+#    define gzwrite               z_gzwrite
+#  endif
+#  define inflate               z_inflate
+#  define inflateBack           z_inflateBack
+#  define inflateBackEnd        z_inflateBackEnd
+#  define inflateBackInit       z_inflateBackInit
+#  define inflateBackInit_      z_inflateBackInit_
+#  define inflateCodesUsed      z_inflateCodesUsed
+#  define inflateCopy           z_inflateCopy
+#  define inflateEnd            z_inflateEnd
+#  define inflateGetDictionary  z_inflateGetDictionary
+#  define inflateGetHeader      z_inflateGetHeader
+#  define inflateInit           z_inflateInit
+#  define inflateInit2          z_inflateInit2
+#  define inflateInit2_         z_inflateInit2_
+#  define inflateInit_          z_inflateInit_
+#  define inflateMark           z_inflateMark
+#  define inflatePrime          z_inflatePrime
+#  define inflateReset          z_inflateReset
+#  define inflateReset2         z_inflateReset2
+#  define inflateResetKeep      z_inflateResetKeep
+#  define inflateSetDictionary  z_inflateSetDictionary
+#  define inflateSync           z_inflateSync
+#  define inflateSyncPoint      z_inflateSyncPoint
+#  define inflateUndermine      z_inflateUndermine
+#  define inflateValidate       z_inflateValidate
+#  define inflate_copyright     z_inflate_copyright
+#  define inflate_fast          z_inflate_fast
+#  define inflate_table         z_inflate_table
+#  ifndef Z_SOLO
+#    define uncompress            z_uncompress
+#    define uncompress2           z_uncompress2
+#  endif
+#  define zError                z_zError
+#  ifndef Z_SOLO
+#    define zcalloc               z_zcalloc
+#    define zcfree                z_zcfree
+#  endif
+#  define zlibCompileFlags      z_zlibCompileFlags
+#  define zlibVersion           z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+#  define Byte                  z_Byte
+#  define Bytef                 z_Bytef
+#  define alloc_func            z_alloc_func
+#  define charf                 z_charf
+#  define free_func             z_free_func
+#  ifndef Z_SOLO
+#    define gzFile                z_gzFile
+#  endif
+#  define gz_header             z_gz_header
+#  define gz_headerp            z_gz_headerp
+#  define in_func               z_in_func
+#  define intf                  z_intf
+#  define out_func              z_out_func
+#  define uInt                  z_uInt
+#  define uIntf                 z_uIntf
+#  define uLong                 z_uLong
+#  define uLongf                z_uLongf
+#  define voidp                 z_voidp
+#  define voidpc                z_voidpc
+#  define voidpf                z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+#  define gz_header_s           z_gz_header_s
+#  define internal_state        z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#  ifndef STDC
+#    define STDC
+#  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const       /* note: need a more gentle solution here */
+#  endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+#  define z_const const
+#else
+#  define z_const
+#endif
+
+#ifdef Z_SOLO
+   typedef unsigned long z_size_t;
+#else
+#  define z_longlong long long
+#  if defined(NO_SIZE_T)
+     typedef unsigned NO_SIZE_T z_size_t;
+#  elif defined(STDC)
+#    include <stddef.h>
+     typedef size_t z_size_t;
+#  else
+     typedef unsigned long z_size_t;
+#  endif
+#  undef z_longlong
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus about 7 kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+#  if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#    define Z_ARG(args)  args
+#  else
+#    define Z_ARG(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
+#    else
+#      define ZEXPORTVA FAR CDECL
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
+#else
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
+#endif
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+#  include <limits.h>
+#  if (UINT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned
+#  elif (ULONG_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned long
+#  elif (USHRT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned short
+#  endif
+#endif
+
+#ifdef Z_U4
+   typedef Z_U4 z_crc_t;
+#else
+   typedef unsigned long z_crc_t;
+#endif
+
+#ifdef HAVE_UNISTD_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef HAVE_STDARG_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+#  ifndef Z_SOLO
+#    include <sys/types.h>      /* for off_t */
+#  endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifndef Z_SOLO
+#    include <stdarg.h>         /* for va_list */
+#  endif
+#endif
+
+#ifdef _WIN32
+#  ifndef Z_SOLO
+#    include <stddef.h>         /* for wchar_t */
+#  endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+#  undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+#  define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+#  if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+#    include <unistd.h>         /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+#    ifdef VMS
+#      include <unixio.h>       /* for off_t */
+#    endif
+#    ifndef z_off_t
+#      define z_off_t off_t
+#    endif
+#  endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+#  define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+#  define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+#  define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+#  define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+#  define z_off64_t off64_t
+#else
+#  if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+#    define z_off64_t __int64
+#  else
+#    define z_off64_t z_off_t
+#  endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+  #pragma map(deflateInit_,"DEIN")
+  #pragma map(deflateInit2_,"DEIN2")
+  #pragma map(deflateEnd,"DEEND")
+  #pragma map(deflateBound,"DEBND")
+  #pragma map(inflateInit_,"ININ")
+  #pragma map(inflateInit2_,"ININ2")
+  #pragma map(inflateEnd,"INEND")
+  #pragma map(inflateSync,"INSY")
+  #pragma map(inflateSetDictionary,"INSEDI")
+  #pragma map(compressBound,"CMBND")
+  #pragma map(inflate_table,"INTABL")
+  #pragma map(inflate_fast,"INFA")
+  #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
Index: EcnlProtoTool/trunk/zlib-1.2.11/zlib.h
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/zlib.h	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/zlib.h	(revision 331)
@@ -0,0 +1,1912 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+  version 1.2.11, January 15th, 2017
+
+  Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
+
+  The data format used by the zlib library is described by RFCs (Request for
+  Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
+  (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.11"
+#define ZLIB_VERNUM 0x12b0
+#define ZLIB_VER_MAJOR 1
+#define ZLIB_VER_MINOR 2
+#define ZLIB_VER_REVISION 11
+#define ZLIB_VER_SUBREVISION 0
+
+/*
+    The 'zlib' compression library provides in-memory compression and
+  decompression functions, including integrity checks of the uncompressed data.
+  This version of the library supports only one compression method (deflation)
+  but other algorithms will be added later and will have the same stream
+  interface.
+
+    Compression can be done in a single step if the buffers are large enough,
+  or can be done by repeated calls of the compression function.  In the latter
+  case, the application must provide more input and/or consume the output
+  (providing more output space) before each call.
+
+    The compressed data format used by default by the in-memory functions is
+  the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+  around a deflate stream, which is itself documented in RFC 1951.
+
+    The library also supports reading and writing files in gzip (.gz) format
+  with an interface similar to that of stdio using the functions that start
+  with "gz".  The gzip format is different from the zlib format.  gzip is a
+  gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+    This library can optionally read and write gzip and raw deflate streams in
+  memory as well.
+
+    The zlib format was designed to be compact and fast for use in memory
+  and on communications channels.  The gzip format was designed for single-
+  file compression on file systems, has a larger header than zlib to maintain
+  directory information, and uses a different, slower check method than zlib.
+
+    The library does not install any signal handler.  The decoder checks
+  the consistency of the compressed data, so the library should never crash
+  even in the case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+    z_const Bytef *next_in;     /* next input byte */
+    uInt     avail_in;  /* number of bytes available at next_in */
+    uLong    total_in;  /* total number of input bytes read so far */
+
+    Bytef    *next_out; /* next output byte will go here */
+    uInt     avail_out; /* remaining free space at next_out */
+    uLong    total_out; /* total number of bytes output so far */
+
+    z_const char *msg;  /* last error message, NULL if no error */
+    struct internal_state FAR *state; /* not visible by applications */
+
+    alloc_func zalloc;  /* used to allocate the internal state */
+    free_func  zfree;   /* used to free the internal state */
+    voidpf     opaque;  /* private data object passed to zalloc and zfree */
+
+    int     data_type;  /* best guess about the data type: binary or text
+                           for deflate, or the decoding state for inflate */
+    uLong   adler;      /* Adler-32 or CRC-32 value of the uncompressed data */
+    uLong   reserved;   /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+     gzip header information passed to and from zlib routines.  See RFC 1952
+  for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+    int     text;       /* true if compressed data believed to be text */
+    uLong   time;       /* modification time */
+    int     xflags;     /* extra flags (not used when writing a gzip file) */
+    int     os;         /* operating system */
+    Bytef   *extra;     /* pointer to extra field or Z_NULL if none */
+    uInt    extra_len;  /* extra field length (valid if extra != Z_NULL) */
+    uInt    extra_max;  /* space at extra (only when reading header) */
+    Bytef   *name;      /* pointer to zero-terminated file name or Z_NULL */
+    uInt    name_max;   /* space at name (only when reading header) */
+    Bytef   *comment;   /* pointer to zero-terminated comment or Z_NULL */
+    uInt    comm_max;   /* space at comment (only when reading header) */
+    int     hcrc;       /* true if there was or will be a header crc */
+    int     done;       /* true when done reading gzip header (not used
+                           when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+     The application must update next_in and avail_in when avail_in has dropped
+   to zero.  It must update next_out and avail_out when avail_out has dropped
+   to zero.  The application must initialize zalloc, zfree and opaque before
+   calling the init function.  All other fields are set by the compression
+   library and must not be updated by the application.
+
+     The opaque value provided by the application will be passed as the first
+   parameter for calls of zalloc and zfree.  This can be useful for custom
+   memory management.  The compression library attaches no meaning to the
+   opaque value.
+
+     zalloc must return Z_NULL if there is not enough memory for the object.
+   If zlib is used in a multi-threaded application, zalloc and zfree must be
+   thread safe.  In that case, zlib is thread-safe.  When zalloc and zfree are
+   Z_NULL on entry to the initialization function, they are set to internal
+   routines that use the standard library functions malloc() and free().
+
+     On 16-bit systems, the functions zalloc and zfree must be able to allocate
+   exactly 65536 bytes, but will not be required to allocate more than this if
+   the symbol MAXSEG_64K is defined (see zconf.h).  WARNING: On MSDOS, pointers
+   returned by zalloc for objects of exactly 65536 bytes *must* have their
+   offset normalized to zero.  The default allocation function provided by this
+   library ensures this (see zutil.c).  To reduce memory requirements and avoid
+   any allocation of 64K objects, at the expense of compression ratio, compile
+   the library with -DMAX_WBITS=14 (see zconf.h).
+
+     The fields total_in and total_out can be used for statistics or progress
+   reports.  After compression, total_in holds the total size of the
+   uncompressed data and may be saved for use by the decompressor (particularly
+   if the decompressor wants to decompress everything in a single step).
+*/
+
+                        /* constants */
+
+#define Z_NO_FLUSH      0
+#define Z_PARTIAL_FLUSH 1
+#define Z_SYNC_FLUSH    2
+#define Z_FULL_FLUSH    3
+#define Z_FINISH        4
+#define Z_BLOCK         5
+#define Z_TREES         6
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK            0
+#define Z_STREAM_END    1
+#define Z_NEED_DICT     2
+#define Z_ERRNO        (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR   (-3)
+#define Z_MEM_ERROR    (-4)
+#define Z_BUF_ERROR    (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION         0
+#define Z_BEST_SPEED             1
+#define Z_BEST_COMPRESSION       9
+#define Z_DEFAULT_COMPRESSION  (-1)
+/* compression levels */
+
+#define Z_FILTERED            1
+#define Z_HUFFMAN_ONLY        2
+#define Z_RLE                 3
+#define Z_FIXED               4
+#define Z_DEFAULT_STRATEGY    0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY   0
+#define Z_TEXT     1
+#define Z_ASCII    Z_TEXT   /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN  2
+/* Possible values of the data_type field for deflate() */
+
+#define Z_DEFLATED   8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+
+                        /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+   If the first character differs, the library code actually used is not
+   compatible with the zlib.h header file used by the application.  This check
+   is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+     Initializes the internal stream state for compression.  The fields
+   zalloc, zfree and opaque must be initialized before by the caller.  If
+   zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
+   allocation functions.
+
+     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+   1 gives best speed, 9 gives best compression, 0 gives no compression at all
+   (the input data is simply copied a block at a time).  Z_DEFAULT_COMPRESSION
+   requests a default compromise between speed and compression (currently
+   equivalent to level 6).
+
+     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if level is not a valid compression level, or
+   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+   with the version assumed by the caller (ZLIB_VERSION).  msg is set to null
+   if there is no error message.  deflateInit does not perform any compression:
+   this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+    deflate compresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full.  It may introduce
+  some output latency (reading input without producing any output) except when
+  forced to flush.
+
+    The detailed semantics are as follows.  deflate performs one or both of the
+  following actions:
+
+  - Compress more input starting at next_in and update next_in and avail_in
+    accordingly.  If not all input can be processed (because there is not
+    enough room in the output buffer), next_in and avail_in are updated and
+    processing will resume at this point for the next call of deflate().
+
+  - Generate more output starting at next_out and update next_out and avail_out
+    accordingly.  This action is forced if the parameter flush is non zero.
+    Forcing flush frequently degrades the compression ratio, so this parameter
+    should be set only when necessary.  Some output may be provided even if
+    flush is zero.
+
+    Before the call of deflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming more
+  output, and updating avail_in or avail_out accordingly; avail_out should
+  never be zero before the call.  The application can consume the compressed
+  output when it wants, for example when the output buffer is full (avail_out
+  == 0), or after each call of deflate().  If deflate returns Z_OK and with
+  zero avail_out, it must be called again after making room in the output
+  buffer because there might be more output pending. See deflatePending(),
+  which can be used if desired to determine whether or not there is more ouput
+  in that case.
+
+    Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+  decide how much data to accumulate before producing output, in order to
+  maximize compression.
+
+    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+  flushed to the output buffer and the output is aligned on a byte boundary, so
+  that the decompressor can get all input data available so far.  (In
+  particular avail_in is zero after the call if enough output space has been
+  provided before the call.) Flushing may degrade compression for some
+  compression algorithms and so it should be used only when necessary.  This
+  completes the current deflate block and follows it with an empty stored block
+  that is three bits plus filler bits to the next byte, followed by four bytes
+  (00 00 ff ff).
+
+    If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
+  output buffer, but the output is not aligned to a byte boundary.  All of the
+  input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
+  This completes the current deflate block and follows it with an empty fixed
+  codes block that is 10 bits long.  This assures that enough bytes are output
+  in order for the decompressor to finish the block before the empty fixed
+  codes block.
+
+    If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
+  for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
+  seven bits of the current block are held to be written as the next byte after
+  the next deflate block is completed.  In this case, the decompressor may not
+  be provided enough bits at this point in order to complete decompression of
+  the data provided so far to the compressor.  It may need to wait for the next
+  block to be emitted.  This is for advanced applications that need to control
+  the emission of deflate blocks.
+
+    If flush is set to Z_FULL_FLUSH, all output is flushed as with
+  Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+  restart from this point if previous compressed data has been damaged or if
+  random access is desired.  Using Z_FULL_FLUSH too often can seriously degrade
+  compression.
+
+    If deflate returns with avail_out == 0, this function must be called again
+  with the same value of the flush parameter and more output space (updated
+  avail_out), until the flush is complete (deflate returns with non-zero
+  avail_out).  In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+  avail_out is greater than six to avoid repeated flush markers due to
+  avail_out == 0 on return.
+
+    If the parameter flush is set to Z_FINISH, pending input is processed,
+  pending output is flushed and deflate returns with Z_STREAM_END if there was
+  enough output space.  If deflate returns with Z_OK or Z_BUF_ERROR, this
+  function must be called again with Z_FINISH and more output space (updated
+  avail_out) but no more input data, until it returns with Z_STREAM_END or an
+  error.  After deflate has returned Z_STREAM_END, the only possible operations
+  on the stream are deflateReset or deflateEnd.
+
+    Z_FINISH can be used in the first deflate call after deflateInit if all the
+  compression is to be done in a single step.  In order to complete in one
+  call, avail_out must be at least the value returned by deflateBound (see
+  below).  Then deflate is guaranteed to return Z_STREAM_END.  If not enough
+  output space is provided, deflate will not return Z_STREAM_END, and it must
+  be called again as described above.
+
+    deflate() sets strm->adler to the Adler-32 checksum of all input read
+  so far (that is, total_in bytes).  If a gzip stream is being generated, then
+  strm->adler will be the CRC-32 checksum of the input read so far.  (See
+  deflateInit2 below.)
+
+    deflate() may update strm->data_type if it can make a good guess about
+  the input data type (Z_BINARY or Z_TEXT).  If in doubt, the data is
+  considered binary.  This field is only for information purposes and does not
+  affect the compression algorithm in any manner.
+
+    deflate() returns Z_OK if some progress has been made (more input
+  processed or more output produced), Z_STREAM_END if all input has been
+  consumed and all output has been produced (only when flush is set to
+  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+  if next_in or next_out was Z_NULL or the state was inadvertently written over
+  by the application), or Z_BUF_ERROR if no progress is possible (for example
+  avail_in or avail_out was zero).  Note that Z_BUF_ERROR is not fatal, and
+  deflate() can be called again with more input and more output space to
+  continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any pending
+   output.
+
+     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+   prematurely (some input or output was discarded).  In the error case, msg
+   may be set but then points to a static string (which must not be
+   deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+     Initializes the internal stream state for decompression.  The fields
+   next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+   the caller.  In the current version of inflate, the provided input is not
+   read or consumed.  The allocation of a sliding window will be deferred to
+   the first call of inflate (if the decompression does not complete on the
+   first call).  If zalloc and zfree are set to Z_NULL, inflateInit updates
+   them to use default allocation functions.
+
+     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+   invalid, such as a null pointer to the structure.  msg is set to null if
+   there is no error message.  inflateInit does not perform any decompression.
+   Actual decompression will be done by inflate().  So next_in, and avail_in,
+   next_out, and avail_out are unused and unchanged.  The current
+   implementation of inflateInit() does not process any header information --
+   that is deferred until inflate() is called.
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+    inflate decompresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full.  It may introduce
+  some output latency (reading input without producing any output) except when
+  forced to flush.
+
+  The detailed semantics are as follows.  inflate performs one or both of the
+  following actions:
+
+  - Decompress more input starting at next_in and update next_in and avail_in
+    accordingly.  If not all input can be processed (because there is not
+    enough room in the output buffer), then next_in and avail_in are updated
+    accordingly, and processing will resume at this point for the next call of
+    inflate().
+
+  - Generate more output starting at next_out and update next_out and avail_out
+    accordingly.  inflate() provides as much output as possible, until there is
+    no more input data or no more space in the output buffer (see below about
+    the flush parameter).
+
+    Before the call of inflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming more
+  output, and updating the next_* and avail_* values accordingly.  If the
+  caller of inflate() does not provide both available input and available
+  output space, it is possible that there will be no progress made.  The
+  application can consume the uncompressed output when it wants, for example
+  when the output buffer is full (avail_out == 0), or after each call of
+  inflate().  If inflate returns Z_OK and with zero avail_out, it must be
+  called again after making room in the output buffer because there might be
+  more output pending.
+
+    The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
+  Z_BLOCK, or Z_TREES.  Z_SYNC_FLUSH requests that inflate() flush as much
+  output as possible to the output buffer.  Z_BLOCK requests that inflate()
+  stop if and when it gets to the next deflate block boundary.  When decoding
+  the zlib or gzip format, this will cause inflate() to return immediately
+  after the header and before the first block.  When doing a raw inflate,
+  inflate() will go ahead and process the first block, and will return when it
+  gets to the end of that block, or when it runs out of data.
+
+    The Z_BLOCK option assists in appending to or combining deflate streams.
+  To assist in this, on return inflate() always sets strm->data_type to the
+  number of unused bits in the last byte taken from strm->next_in, plus 64 if
+  inflate() is currently decoding the last block in the deflate stream, plus
+  128 if inflate() returned immediately after decoding an end-of-block code or
+  decoding the complete header up to just before the first byte of the deflate
+  stream.  The end-of-block will not be indicated until all of the uncompressed
+  data from that block has been written to strm->next_out.  The number of
+  unused bits may in general be greater than seven, except when bit 7 of
+  data_type is set, in which case the number of unused bits will be less than
+  eight.  data_type is set as noted here every time inflate() returns for all
+  flush options, and so can be used to determine the amount of currently
+  consumed input in bits.
+
+    The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
+  end of each deflate block header is reached, before any actual data in that
+  block is decoded.  This allows the caller to determine the length of the
+  deflate block header for later use in random access within a deflate block.
+  256 is added to the value of strm->data_type when inflate() returns
+  immediately after reaching the end of the deflate block header.
+
+    inflate() should normally be called until it returns Z_STREAM_END or an
+  error.  However if all decompression is to be performed in a single step (a
+  single call of inflate), the parameter flush should be set to Z_FINISH.  In
+  this case all pending input is processed and all pending output is flushed;
+  avail_out must be large enough to hold all of the uncompressed data for the
+  operation to complete.  (The size of the uncompressed data may have been
+  saved by the compressor for this purpose.)  The use of Z_FINISH is not
+  required to perform an inflation in one step.  However it may be used to
+  inform inflate that a faster approach can be used for the single inflate()
+  call.  Z_FINISH also informs inflate to not maintain a sliding window if the
+  stream completes, which reduces inflate's memory footprint.  If the stream
+  does not complete, either because not all of the stream is provided or not
+  enough output space is provided, then a sliding window will be allocated and
+  inflate() can be called again to continue the operation as if Z_NO_FLUSH had
+  been used.
+
+     In this implementation, inflate() always flushes as much output as
+  possible to the output buffer, and always uses the faster approach on the
+  first call.  So the effects of the flush parameter in this implementation are
+  on the return value of inflate() as noted below, when inflate() returns early
+  when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
+  memory for a sliding window when Z_FINISH is used.
+
+     If a preset dictionary is needed after this call (see inflateSetDictionary
+  below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
+  chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+  strm->adler to the Adler-32 checksum of all output produced so far (that is,
+  total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+  below.  At the end of the stream, inflate() checks that its computed Adler-32
+  checksum is equal to that saved by the compressor and returns Z_STREAM_END
+  only if the checksum is correct.
+
+    inflate() can decompress and check either zlib-wrapped or gzip-wrapped
+  deflate data.  The header type is detected automatically, if requested when
+  initializing with inflateInit2().  Any information contained in the gzip
+  header is not retained unless inflateGetHeader() is used.  When processing
+  gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
+  produced so far.  The CRC-32 is checked against the gzip trailer, as is the
+  uncompressed length, modulo 2^32.
+
+    inflate() returns Z_OK if some progress has been made (more input processed
+  or more output produced), Z_STREAM_END if the end of the compressed data has
+  been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+  corrupted (input stream not conforming to the zlib format or incorrect check
+  value, in which case strm->msg points to a string with a more specific
+  error), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+  next_in or next_out was Z_NULL, or the state was inadvertently written over
+  by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR
+  if no progress was possible or if there was not enough room in the output
+  buffer when Z_FINISH is used.  Note that Z_BUF_ERROR is not fatal, and
+  inflate() can be called again with more input and more output space to
+  continue decompressing.  If Z_DATA_ERROR is returned, the application may
+  then call inflateSync() to look for a good compression block if a partial
+  recovery of the data is to be attempted.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any pending
+   output.
+
+     inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state
+   was inconsistent.
+*/
+
+
+                        /* Advanced functions */
+
+/*
+    The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+                                     int  level,
+                                     int  method,
+                                     int  windowBits,
+                                     int  memLevel,
+                                     int  strategy));
+
+     This is another version of deflateInit with more compression options.  The
+   fields next_in, zalloc, zfree and opaque must be initialized before by the
+   caller.
+
+     The method parameter is the compression method.  It must be Z_DEFLATED in
+   this version of the library.
+
+     The windowBits parameter is the base two logarithm of the window size
+   (the size of the history buffer).  It should be in the range 8..15 for this
+   version of the library.  Larger values of this parameter result in better
+   compression at the expense of memory usage.  The default value is 15 if
+   deflateInit is used instead.
+
+     For the current implementation of deflate(), a windowBits value of 8 (a
+   window size of 256 bytes) is not supported.  As a result, a request for 8
+   will result in 9 (a 512-byte window).  In that case, providing 8 to
+   inflateInit2() will result in an error when the zlib header with 9 is
+   checked against the initialization of inflate().  The remedy is to not use 8
+   with deflateInit2() with this initialization, or at least in that case use 9
+   with inflateInit2().
+
+     windowBits can also be -8..-15 for raw deflate.  In this case, -windowBits
+   determines the window size.  deflate() will then generate raw deflate data
+   with no zlib header or trailer, and will not compute a check value.
+
+     windowBits can also be greater than 15 for optional gzip encoding.  Add
+   16 to windowBits to write a simple gzip header and trailer around the
+   compressed data instead of a zlib wrapper.  The gzip header will have no
+   file name, no extra data, no comment, no modification time (set to zero), no
+   header crc, and the operating system will be set to the appropriate value,
+   if the operating system was determined at compile time.  If a gzip stream is
+   being written, strm->adler is a CRC-32 instead of an Adler-32.
+
+     For raw deflate or gzip encoding, a request for a 256-byte window is
+   rejected as invalid, since only the zlib header provides a means of
+   transmitting the window size to the decompressor.
+
+     The memLevel parameter specifies how much memory should be allocated
+   for the internal compression state.  memLevel=1 uses minimum memory but is
+   slow and reduces compression ratio; memLevel=9 uses maximum memory for
+   optimal speed.  The default value is 8.  See zconf.h for total memory usage
+   as a function of windowBits and memLevel.
+
+     The strategy parameter is used to tune the compression algorithm.  Use the
+   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+   filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+   string match), or Z_RLE to limit match distances to one (run-length
+   encoding).  Filtered data consists mostly of small values with a somewhat
+   random distribution.  In this case, the compression algorithm is tuned to
+   compress them better.  The effect of Z_FILTERED is to force more Huffman
+   coding and less string matching; it is somewhat intermediate between
+   Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY.  Z_RLE is designed to be almost as
+   fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data.  The
+   strategy parameter only affects the compression ratio but not the
+   correctness of the compressed output even if it is not set appropriately.
+   Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
+   decoder for special applications.
+
+     deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid
+   method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is
+   incompatible with the version assumed by the caller (ZLIB_VERSION).  msg is
+   set to null if there is no error message.  deflateInit2 does not perform any
+   compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the compression dictionary from the given byte sequence
+   without producing any compressed output.  When using the zlib format, this
+   function must be called immediately after deflateInit, deflateInit2 or
+   deflateReset, and before any call of deflate.  When doing raw deflate, this
+   function must be called either before any call of deflate, or immediately
+   after the completion of a deflate block, i.e. after all input has been
+   consumed and all output has been delivered when using any of the flush
+   options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH.  The
+   compressor and decompressor must use exactly the same dictionary (see
+   inflateSetDictionary).
+
+     The dictionary should consist of strings (byte sequences) that are likely
+   to be encountered later in the data to be compressed, with the most commonly
+   used strings preferably put towards the end of the dictionary.  Using a
+   dictionary is most useful when the data to be compressed is short and can be
+   predicted with good accuracy; the data can then be compressed better than
+   with the default empty dictionary.
+
+     Depending on the size of the compression data structures selected by
+   deflateInit or deflateInit2, a part of the dictionary may in effect be
+   discarded, for example if the dictionary is larger than the window size
+   provided in deflateInit or deflateInit2.  Thus the strings most likely to be
+   useful should be put at the end of the dictionary, not at the front.  In
+   addition, the current implementation of deflate will use at most the window
+   size minus 262 bytes of the provided dictionary.
+
+     Upon return of this function, strm->adler is set to the Adler-32 value
+   of the dictionary; the decompressor may later use this value to determine
+   which dictionary has been used by the compressor.  (The Adler-32 value
+   applies to the whole dictionary even if only a subset of the dictionary is
+   actually used by the compressor.) If a raw deflate was requested, then the
+   Adler-32 value is not computed and strm->adler is not set.
+
+     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+   parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is
+   inconsistent (for example if deflate has already been called for this stream
+   or if not at a block boundary for raw deflate).  deflateSetDictionary does
+   not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm,
+                                             Bytef *dictionary,
+                                             uInt  *dictLength));
+/*
+     Returns the sliding dictionary being maintained by deflate.  dictLength is
+   set to the number of bytes in the dictionary, and that many bytes are copied
+   to dictionary.  dictionary must have enough space, where 32768 bytes is
+   always enough.  If deflateGetDictionary() is called with dictionary equal to
+   Z_NULL, then only the dictionary length is returned, and nothing is copied.
+   Similary, if dictLength is Z_NULL, then it is not set.
+
+     deflateGetDictionary() may return a length less than the window size, even
+   when more than the window size in input has been provided. It may return up
+   to 258 bytes less in that case, due to how zlib's implementation of deflate
+   manages the sliding window and lookahead for matches, where matches can be
+   up to 258 bytes long. If the application needs the last window-size bytes of
+   input, then that would need to be saved by the application outside of zlib.
+
+     deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
+   stream state is inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when several compression strategies will be
+   tried, for example when there are several ways of pre-processing the input
+   data with a filter.  The streams that will be discarded should then be freed
+   by calling deflateEnd.  Note that deflateCopy duplicates the internal
+   compression state which can be quite large, so this strategy is slow and can
+   consume lots of memory.
+
+     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being Z_NULL).  msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to deflateEnd followed by deflateInit, but
+   does not free and reallocate the internal compression state.  The stream
+   will leave the compression level and any other attributes that may have been
+   set unchanged.
+
+     deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+                                      int level,
+                                      int strategy));
+/*
+     Dynamically update the compression level and compression strategy.  The
+   interpretation of level and strategy is as in deflateInit2().  This can be
+   used to switch between compression and straight copy of the input data, or
+   to switch to a different kind of input data requiring a different strategy.
+   If the compression approach (which is a function of the level) or the
+   strategy is changed, and if any input has been consumed in a previous
+   deflate() call, then the input available so far is compressed with the old
+   level and strategy using deflate(strm, Z_BLOCK).  There are three approaches
+   for the compression levels 0, 1..3, and 4..9 respectively.  The new level
+   and strategy will take effect at the next call of deflate().
+
+     If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does
+   not have enough output space to complete, then the parameter change will not
+   take effect.  In this case, deflateParams() can be called again with the
+   same parameters and more output space to try again.
+
+     In order to assure a change in the parameters on the first try, the
+   deflate stream should be flushed using deflate() with Z_BLOCK or other flush
+   request until strm.avail_out is not zero, before calling deflateParams().
+   Then no more input data should be provided before the deflateParams() call.
+   If this is done, the old level and strategy will be applied to the data
+   compressed before deflateParams(), and the new level and strategy will be
+   applied to the the data compressed after deflateParams().
+
+     deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream
+   state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if
+   there was not enough output space to complete the compression of the
+   available input data before a change in the strategy or approach.  Note that
+   in the case of a Z_BUF_ERROR, the parameters are not changed.  A return
+   value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be
+   retried with more output space.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+                                    int good_length,
+                                    int max_lazy,
+                                    int nice_length,
+                                    int max_chain));
+/*
+     Fine tune deflate's internal compression parameters.  This should only be
+   used by someone who understands the algorithm used by zlib's deflate for
+   searching for the best matching string, and even then only by the most
+   fanatic optimizer trying to squeeze out the last compressed bit for their
+   specific input data.  Read the deflate.c source code for the meaning of the
+   max_lazy, good_length, nice_length, and max_chain parameters.
+
+     deflateTune() can be called after deflateInit() or deflateInit2(), and
+   returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+                                       uLong sourceLen));
+/*
+     deflateBound() returns an upper bound on the compressed size after
+   deflation of sourceLen bytes.  It must be called after deflateInit() or
+   deflateInit2(), and after deflateSetHeader(), if used.  This would be used
+   to allocate an output buffer for deflation in a single pass, and so would be
+   called before deflate().  If that first deflate() call is provided the
+   sourceLen input bytes, an output buffer allocated to the size returned by
+   deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
+   to return Z_STREAM_END.  Note that it is possible for the compressed size to
+   be larger than the value returned by deflateBound() if flush options other
+   than Z_FINISH or Z_NO_FLUSH are used.
+*/
+
+ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
+                                       unsigned *pending,
+                                       int *bits));
+/*
+     deflatePending() returns the number of bytes and bits of output that have
+   been generated, but not yet provided in the available output.  The bytes not
+   provided would be due to the available output space having being consumed.
+   The number of bits of output not provided are between 0 and 7, where they
+   await more bits to join them in order to fill out a full byte.  If pending
+   or bits are Z_NULL, then those values are not set.
+
+     deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+ */
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     deflatePrime() inserts bits in the deflate output stream.  The intent
+   is that this function is used to start off the deflate output with the bits
+   leftover from a previous deflate stream when appending to it.  As such, this
+   function can only be used for raw deflate, and must be used before the first
+   deflate() call after a deflateInit2() or deflateReset().  bits must be less
+   than or equal to 16, and that many of the least significant bits of value
+   will be inserted in the output.
+
+     deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
+   room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
+   source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+     deflateSetHeader() provides gzip header information for when a gzip
+   stream is requested by deflateInit2().  deflateSetHeader() may be called
+   after deflateInit2() or deflateReset() and before the first call of
+   deflate().  The text, time, os, extra field, name, and comment information
+   in the provided gz_header structure are written to the gzip header (xflag is
+   ignored -- the extra flags are set according to the compression level).  The
+   caller must assure that, if not Z_NULL, name and comment are terminated with
+   a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+   available there.  If hcrc is true, a gzip header crc is included.  Note that
+   the current versions of the command-line version of gzip (up through version
+   1.3.x) do not support header crc's, and will report that it is a "multi-part
+   gzip file" and give up.
+
+     If deflateSetHeader is not used, the default gzip header has text false,
+   the time set to zero, and os set to 255, with no extra, name, or comment
+   fields.  The gzip header is returned to the default state by deflateReset().
+
+     deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+                                     int  windowBits));
+
+     This is another version of inflateInit with an extra parameter.  The
+   fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+   before by the caller.
+
+     The windowBits parameter is the base two logarithm of the maximum window
+   size (the size of the history buffer).  It should be in the range 8..15 for
+   this version of the library.  The default value is 15 if inflateInit is used
+   instead.  windowBits must be greater than or equal to the windowBits value
+   provided to deflateInit2() while compressing, or it must be equal to 15 if
+   deflateInit2() was not used.  If a compressed stream with a larger window
+   size is given as input, inflate() will return with the error code
+   Z_DATA_ERROR instead of trying to allocate a larger window.
+
+     windowBits can also be zero to request that inflate use the window size in
+   the zlib header of the compressed stream.
+
+     windowBits can also be -8..-15 for raw inflate.  In this case, -windowBits
+   determines the window size.  inflate() will then process raw deflate data,
+   not looking for a zlib or gzip header, not generating a check value, and not
+   looking for any check values for comparison at the end of the stream.  This
+   is for use with other formats that use the deflate compressed data format
+   such as zip.  Those formats provide their own check values.  If a custom
+   format is developed using the raw deflate format for compressed data, it is
+   recommended that a check value such as an Adler-32 or a CRC-32 be applied to
+   the uncompressed data as is done in the zlib, gzip, and zip formats.  For
+   most applications, the zlib format should be used as is.  Note that comments
+   above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+     windowBits can also be greater than 15 for optional gzip decoding.  Add
+   32 to windowBits to enable zlib and gzip decoding with automatic header
+   detection, or add 16 to decode only the gzip format (the zlib format will
+   return a Z_DATA_ERROR).  If a gzip stream is being decoded, strm->adler is a
+   CRC-32 instead of an Adler-32.  Unlike the gunzip utility and gzread() (see
+   below), inflate() will not automatically decode concatenated gzip streams.
+   inflate() will return Z_STREAM_END at the end of the gzip stream.  The state
+   would need to be reset to continue decoding a subsequent gzip stream.
+
+     inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+   invalid, such as a null pointer to the structure.  msg is set to null if
+   there is no error message.  inflateInit2 does not perform any decompression
+   apart from possibly reading the zlib header if present: actual decompression
+   will be done by inflate().  (So next_in and avail_in may be modified, but
+   next_out and avail_out are unused and unchanged.) The current implementation
+   of inflateInit2() does not process any header information -- that is
+   deferred until inflate() is called.
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the decompression dictionary from the given uncompressed byte
+   sequence.  This function must be called immediately after a call of inflate,
+   if that call returned Z_NEED_DICT.  The dictionary chosen by the compressor
+   can be determined from the Adler-32 value returned by that call of inflate.
+   The compressor and decompressor must use exactly the same dictionary (see
+   deflateSetDictionary).  For raw inflate, this function can be called at any
+   time to set the dictionary.  If the provided dictionary is smaller than the
+   window and there is already data in the window, then the provided dictionary
+   will amend what's there.  The application must insure that the dictionary
+   that was used for compression is provided.
+
+     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+   parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is
+   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+   expected one (incorrect Adler-32 value).  inflateSetDictionary does not
+   perform any decompression: this will be done by subsequent calls of
+   inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
+                                             Bytef *dictionary,
+                                             uInt  *dictLength));
+/*
+     Returns the sliding dictionary being maintained by inflate.  dictLength is
+   set to the number of bytes in the dictionary, and that many bytes are copied
+   to dictionary.  dictionary must have enough space, where 32768 bytes is
+   always enough.  If inflateGetDictionary() is called with dictionary equal to
+   Z_NULL, then only the dictionary length is returned, and nothing is copied.
+   Similary, if dictLength is Z_NULL, then it is not set.
+
+     inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
+   stream state is inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+     Skips invalid compressed data until a possible full flush point (see above
+   for the description of deflate with Z_FULL_FLUSH) can be found, or until all
+   available input is skipped.  No output is provided.
+
+     inflateSync searches for a 00 00 FF FF pattern in the compressed data.
+   All full flush points have this pattern, but not all occurrences of this
+   pattern are full flush points.
+
+     inflateSync returns Z_OK if a possible full flush point has been found,
+   Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
+   has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
+   In the success case, the application may save the current current value of
+   total_in which indicates where valid compressed data was found.  In the
+   error case, the application may repeatedly call inflateSync, providing more
+   input each time, until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when randomly accessing a large stream.  The
+   first pass through the stream can periodically record the inflate state,
+   allowing restarting inflate at those points when randomly accessing the
+   stream.
+
+     inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being Z_NULL).  msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to inflateEnd followed by inflateInit,
+   but does not free and reallocate the internal decompression state.  The
+   stream will keep attributes that may have been set by inflateInit2.
+
+     inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
+                                      int windowBits));
+/*
+     This function is the same as inflateReset, but it also permits changing
+   the wrap and window size requests.  The windowBits parameter is interpreted
+   the same as it is for inflateInit2.  If the window size is changed, then the
+   memory allocated for the window is freed, and the window will be reallocated
+   by inflate() if needed.
+
+     inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL), or if
+   the windowBits parameter is invalid.
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     This function inserts bits in the inflate input stream.  The intent is
+   that this function is used to start inflating at a bit position in the
+   middle of a byte.  The provided bits will be used before any bytes are used
+   from next_in.  This function should only be used with raw inflate, and
+   should be used before the first inflate() call after inflateInit2() or
+   inflateReset().  bits must be less than or equal to 16, and that many of the
+   least significant bits of value will be inserted in the input.
+
+     If bits is negative, then the input stream bit buffer is emptied.  Then
+   inflatePrime() can be called again to put bits in the buffer.  This is used
+   to clear out bits leftover after feeding inflate a block description prior
+   to feeding inflate codes.
+
+     inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
+/*
+     This function returns two values, one in the lower 16 bits of the return
+   value, and the other in the remaining upper bits, obtained by shifting the
+   return value down 16 bits.  If the upper value is -1 and the lower value is
+   zero, then inflate() is currently decoding information outside of a block.
+   If the upper value is -1 and the lower value is non-zero, then inflate is in
+   the middle of a stored block, with the lower value equaling the number of
+   bytes from the input remaining to copy.  If the upper value is not -1, then
+   it is the number of bits back from the current bit position in the input of
+   the code (literal or length/distance pair) currently being processed.  In
+   that case the lower value is the number of bytes already emitted for that
+   code.
+
+     A code is being processed if inflate is waiting for more input to complete
+   decoding of the code, or if it has completed decoding but is waiting for
+   more output space to write the literal or match data.
+
+     inflateMark() is used to mark locations in the input data for random
+   access, which may be at bit positions, and to note those cases where the
+   output of a code may span boundaries of random access blocks.  The current
+   location in the input stream can be determined from avail_in and data_type
+   as noted in the description for the Z_BLOCK flush parameter for inflate.
+
+     inflateMark returns the value noted above, or -65536 if the provided
+   source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+     inflateGetHeader() requests that gzip header information be stored in the
+   provided gz_header structure.  inflateGetHeader() may be called after
+   inflateInit2() or inflateReset(), and before the first call of inflate().
+   As inflate() processes the gzip stream, head->done is zero until the header
+   is completed, at which time head->done is set to one.  If a zlib stream is
+   being decoded, then head->done is set to -1 to indicate that there will be
+   no gzip header information forthcoming.  Note that Z_BLOCK or Z_TREES can be
+   used to force inflate() to return immediately after header processing is
+   complete and before any actual data is decompressed.
+
+     The text, time, xflags, and os fields are filled in with the gzip header
+   contents.  hcrc is set to true if there is a header CRC.  (The header CRC
+   was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+   contains the maximum number of bytes to write to extra.  Once done is true,
+   extra_len contains the actual extra field length, and extra contains the
+   extra field, or that field truncated if extra_max is less than extra_len.
+   If name is not Z_NULL, then up to name_max characters are written there,
+   terminated with a zero unless the length is greater than name_max.  If
+   comment is not Z_NULL, then up to comm_max characters are written there,
+   terminated with a zero unless the length is greater than comm_max.  When any
+   of extra, name, or comment are not Z_NULL and the respective field is not
+   present in the header, then that field is set to Z_NULL to signal its
+   absence.  This allows the use of deflateSetHeader() with the returned
+   structure to duplicate the header.  However if those fields are set to
+   allocated memory, then the application will need to save those pointers
+   elsewhere so that they can be eventually freed.
+
+     If inflateGetHeader is not used, then the header information is simply
+   discarded.  The header is always checked for validity, including the header
+   CRC if present.  inflateReset() will reset the process to discard the header
+   information.  The application would need to call inflateGetHeader() again to
+   retrieve the header from the next gzip stream.
+
+     inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+                                        unsigned char FAR *window));
+
+     Initialize the internal stream state for decompression using inflateBack()
+   calls.  The fields zalloc, zfree and opaque in strm must be initialized
+   before the call.  If zalloc and zfree are Z_NULL, then the default library-
+   derived memory allocation routines are used.  windowBits is the base two
+   logarithm of the window size, in the range 8..15.  window is a caller
+   supplied buffer of that size.  Except for special applications where it is
+   assured that deflate was used with small window sizes, windowBits must be 15
+   and a 32K byte window must be supplied to be able to decompress general
+   deflate streams.
+
+     See inflateBack() for the usage of these routines.
+
+     inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+   the parameters are invalid, Z_MEM_ERROR if the internal state could not be
+   allocated, or Z_VERSION_ERROR if the version of the library does not match
+   the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *,
+                                z_const unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+                                    in_func in, void FAR *in_desc,
+                                    out_func out, void FAR *out_desc));
+/*
+     inflateBack() does a raw inflate with a single call using a call-back
+   interface for input and output.  This is potentially more efficient than
+   inflate() for file i/o applications, in that it avoids copying between the
+   output and the sliding window by simply making the window itself the output
+   buffer.  inflate() can be faster on modern CPUs when used with large
+   buffers.  inflateBack() trusts the application to not change the output
+   buffer passed by the output function, at least until inflateBack() returns.
+
+     inflateBackInit() must be called first to allocate the internal state
+   and to initialize the state with the user-provided window buffer.
+   inflateBack() may then be used multiple times to inflate a complete, raw
+   deflate stream with each call.  inflateBackEnd() is then called to free the
+   allocated state.
+
+     A raw deflate stream is one with no zlib or gzip header or trailer.
+   This routine would normally be used in a utility that reads zip or gzip
+   files and writes out uncompressed files.  The utility would decode the
+   header and process the trailer on its own, hence this routine expects only
+   the raw deflate stream to decompress.  This is different from the default
+   behavior of inflate(), which expects a zlib header and trailer around the
+   deflate stream.
+
+     inflateBack() uses two subroutines supplied by the caller that are then
+   called by inflateBack() for input and output.  inflateBack() calls those
+   routines until it reads a complete deflate stream and writes out all of the
+   uncompressed data, or until it encounters an error.  The function's
+   parameters and return types are defined above in the in_func and out_func
+   typedefs.  inflateBack() will call in(in_desc, &buf) which should return the
+   number of bytes of provided input, and a pointer to that input in buf.  If
+   there is no input available, in() must return zero -- buf is ignored in that
+   case -- and inflateBack() will return a buffer error.  inflateBack() will
+   call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1].
+   out() should return zero on success, or non-zero on failure.  If out()
+   returns non-zero, inflateBack() will return with an error.  Neither in() nor
+   out() are permitted to change the contents of the window provided to
+   inflateBackInit(), which is also the buffer that out() uses to write from.
+   The length written by out() will be at most the window size.  Any non-zero
+   amount of input may be provided by in().
+
+     For convenience, inflateBack() can be provided input on the first call by
+   setting strm->next_in and strm->avail_in.  If that input is exhausted, then
+   in() will be called.  Therefore strm->next_in must be initialized before
+   calling inflateBack().  If strm->next_in is Z_NULL, then in() will be called
+   immediately for input.  If strm->next_in is not Z_NULL, then strm->avail_in
+   must also be initialized, and then if strm->avail_in is not zero, input will
+   initially be taken from strm->next_in[0 ..  strm->avail_in - 1].
+
+     The in_desc and out_desc parameters of inflateBack() is passed as the
+   first parameter of in() and out() respectively when they are called.  These
+   descriptors can be optionally used to pass any information that the caller-
+   supplied in() and out() functions need to do their job.
+
+     On return, inflateBack() will set strm->next_in and strm->avail_in to
+   pass back any unused input that was provided by the last in() call.  The
+   return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+   if in() or out() returned an error, Z_DATA_ERROR if there was a format error
+   in the deflate stream (in which case strm->msg is set to indicate the nature
+   of the error), or Z_STREAM_ERROR if the stream was not properly initialized.
+   In the case of Z_BUF_ERROR, an input or output error can be distinguished
+   using strm->next_in which will be Z_NULL only if in() returned an error.  If
+   strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning
+   non-zero.  (in() will always be called before out(), so strm->next_in is
+   assured to be defined if out() returns non-zero.)  Note that inflateBack()
+   cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+     All memory allocated by inflateBackInit() is freed.
+
+     inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+   state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+    Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+     1.0: size of uInt
+     3.2: size of uLong
+     5.4: size of voidpf (pointer)
+     7.6: size of z_off_t
+
+    Compiler, assembler, and debug options:
+     8: ZLIB_DEBUG
+     9: ASMV or ASMINF -- use ASM code
+     10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+     11: 0 (reserved)
+
+    One-time table building (smaller code, but not thread-safe if true):
+     12: BUILDFIXED -- build static block decoding tables when needed
+     13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+     14,15: 0 (reserved)
+
+    Library content (indicates missing functionality):
+     16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+                          deflate code when not needed)
+     17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+                    and decode gzip streams (to avoid linking crc code)
+     18-19: 0 (reserved)
+
+    Operation variations (changes in library functionality):
+     20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+     21: FASTEST -- deflate algorithm with only one, lowest compression level
+     22,23: 0 (reserved)
+
+    The sprintf variant used by gzprintf (zero is best):
+     24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+     25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+     26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+    Remainder:
+     27-31: 0 (reserved)
+ */
+
+#ifndef Z_SOLO
+
+                        /* utility functions */
+
+/*
+     The following utility functions are implemented on top of the basic
+   stream-oriented functions.  To simplify the interface, some default options
+   are assumed (compression level and memory usage, standard memory allocation
+   functions).  The source code of these utility functions can be modified if
+   you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
+                                 const Bytef *source, uLong sourceLen));
+/*
+     Compresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer.  Upon entry, destLen is the total size
+   of the destination buffer, which must be at least the value returned by
+   compressBound(sourceLen).  Upon exit, destLen is the actual size of the
+   compressed data.  compress() is equivalent to compress2() with a level
+   parameter of Z_DEFAULT_COMPRESSION.
+
+     compress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
+                                  const Bytef *source, uLong sourceLen,
+                                  int level));
+/*
+     Compresses the source buffer into the destination buffer.  The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer.  Upon entry, destLen is the total size of the
+   destination buffer, which must be at least the value returned by
+   compressBound(sourceLen).  Upon exit, destLen is the actual size of the
+   compressed data.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+     compressBound() returns an upper bound on the compressed size after
+   compress() or compress2() on sourceLen bytes.  It would be used before a
+   compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
+                                   const Bytef *source, uLong sourceLen));
+/*
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer.  Upon entry, destLen is the total size
+   of the destination buffer, which must be large enough to hold the entire
+   uncompressed data.  (The size of the uncompressed data must have been saved
+   previously by the compressor and transmitted to the decompressor by some
+   mechanism outside the scope of this compression library.) Upon exit, destLen
+   is the actual size of the uncompressed data.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.  In
+   the case where there is not enough room, uncompress() will fill the output
+   buffer with the uncompressed data up to that point.
+*/
+
+ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest,   uLongf *destLen,
+                                    const Bytef *source, uLong *sourceLen));
+/*
+     Same as uncompress, except that sourceLen is a pointer, where the
+   length of the source is *sourceLen.  On return, *sourceLen is the number of
+   source bytes consumed.
+*/
+
+                        /* gzip file access functions */
+
+/*
+     This library supports reading and writing files in gzip (.gz) format with
+   an interface similar to that of stdio, using the functions that start with
+   "gz".  The gzip format is different from the zlib format.  gzip is a gzip
+   wrapper, documented in RFC 1952, wrapped around a deflate stream.
+*/
+
+typedef struct gzFile_s *gzFile;    /* semi-opaque gzip file descriptor */
+
+/*
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+
+     Opens a gzip (.gz) file for reading or writing.  The mode parameter is as
+   in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
+   a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
+   compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
+   for fixed code compression as in "wb9F".  (See the description of
+   deflateInit2 for more information about the strategy parameter.)  'T' will
+   request transparent writing or appending with no compression and not using
+   the gzip format.
+
+     "a" can be used instead of "w" to request that the gzip stream that will
+   be written be appended to the file.  "+" will result in an error, since
+   reading and writing to the same gzip file is not supported.  The addition of
+   "x" when writing will create the file exclusively, which fails if the file
+   already exists.  On systems that support it, the addition of "e" when
+   reading or writing will set the flag to close the file on an execve() call.
+
+     These functions, as well as gzip, will read and decode a sequence of gzip
+   streams in a file.  The append function of gzopen() can be used to create
+   such a file.  (Also see gzflush() for another way to do this.)  When
+   appending, gzopen does not test whether the file begins with a gzip stream,
+   nor does it look for the end of the gzip streams to begin appending.  gzopen
+   will simply append a gzip stream to the existing file.
+
+     gzopen can be used to read a file which is not in gzip format; in this
+   case gzread will directly read from the file without decompression.  When
+   reading, this will be detected automatically by looking for the magic two-
+   byte gzip header.
+
+     gzopen returns NULL if the file could not be opened, if there was
+   insufficient memory to allocate the gzFile state, or if an invalid mode was
+   specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
+   errno can be checked to determine if the reason gzopen failed was that the
+   file could not be opened.
+*/
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+     gzdopen associates a gzFile with the file descriptor fd.  File descriptors
+   are obtained from calls like open, dup, creat, pipe or fileno (if the file
+   has been previously opened with fopen).  The mode parameter is as in gzopen.
+
+     The next call of gzclose on the returned gzFile will also close the file
+   descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
+   fd.  If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
+   mode);.  The duplicated descriptor should be saved to avoid a leak, since
+   gzdopen does not close fd if it fails.  If you are using fileno() to get the
+   file descriptor from a FILE *, then you will have to use dup() to avoid
+   double-close()ing the file descriptor.  Both gzclose() and fclose() will
+   close the associated file descriptor, so they need to have different file
+   descriptors.
+
+     gzdopen returns NULL if there was insufficient memory to allocate the
+   gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
+   provided, or '+' was provided), or if fd is -1.  The file descriptor is not
+   used until the next gz* read, write, seek, or close operation, so gzdopen
+   will not detect if fd is invalid (unless fd is -1).
+*/
+
+ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
+/*
+     Set the internal buffer size used by this library's functions.  The
+   default buffer size is 8192 bytes.  This function must be called after
+   gzopen() or gzdopen(), and before any other calls that read or write the
+   file.  The buffer memory allocation is always deferred to the first read or
+   write.  Three times that size in buffer space is allocated.  A larger buffer
+   size of, for example, 64K or 128K bytes will noticeably increase the speed
+   of decompression (reading).
+
+     The new buffer size also affects the maximum length for gzprintf().
+
+     gzbuffer() returns 0 on success, or -1 on failure, such as being called
+   too late.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+     Dynamically update the compression level or strategy.  See the description
+   of deflateInit2 for the meaning of these parameters.  Previously provided
+   data is flushed before the parameter change.
+
+     gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not
+   opened for writing, Z_ERRNO if there is an error writing the flushed data,
+   or Z_MEM_ERROR if there is a memory allocation error.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+     Reads the given number of uncompressed bytes from the compressed file.  If
+   the input file is not in gzip format, gzread copies the given number of
+   bytes into the buffer directly from the file.
+
+     After reaching the end of a gzip stream in the input, gzread will continue
+   to read, looking for another gzip stream.  Any number of gzip streams may be
+   concatenated in the input file, and will all be decompressed by gzread().
+   If something other than a gzip stream is encountered after a gzip stream,
+   that remaining trailing garbage is ignored (and no error is returned).
+
+     gzread can be used to read a gzip file that is being concurrently written.
+   Upon reaching the end of the input, gzread will return with the available
+   data.  If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
+   gzclearerr can be used to clear the end of file indicator in order to permit
+   gzread to be tried again.  Z_OK indicates that a gzip stream was completed
+   on the last gzread.  Z_BUF_ERROR indicates that the input file ended in the
+   middle of a gzip stream.  Note that gzread does not return -1 in the event
+   of an incomplete gzip stream.  This error is deferred until gzclose(), which
+   will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
+   stream.  Alternatively, gzerror can be used before gzclose to detect this
+   case.
+
+     gzread returns the number of uncompressed bytes actually read, less than
+   len for end of file, or -1 for error.  If len is too large to fit in an int,
+   then nothing is read, -1 is returned, and the error state is set to
+   Z_STREAM_ERROR.
+*/
+
+ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems,
+                                     gzFile file));
+/*
+     Read up to nitems items of size size from file to buf, otherwise operating
+   as gzread() does.  This duplicates the interface of stdio's fread(), with
+   size_t request and return types.  If the library defines size_t, then
+   z_size_t is identical to size_t.  If not, then z_size_t is an unsigned
+   integer type that can contain a pointer.
+
+     gzfread() returns the number of full items read of size size, or zero if
+   the end of the file was reached and a full item could not be read, or if
+   there was an error.  gzerror() must be consulted if zero is returned in
+   order to determine if there was an error.  If the multiplication of size and
+   nitems overflows, i.e. the product does not fit in a z_size_t, then nothing
+   is read, zero is returned, and the error state is set to Z_STREAM_ERROR.
+
+     In the event that the end of file is reached and only a partial item is
+   available at the end, i.e. the remaining uncompressed data length is not a
+   multiple of size, then the final partial item is nevetheless read into buf
+   and the end-of-file flag is set.  The length of the partial item read is not
+   provided, but could be inferred from the result of gztell().  This behavior
+   is the same as the behavior of fread() implementations in common libraries,
+   but it prevents the direct use of gzfread() to read a concurrently written
+   file, reseting and retrying on end-of-file, when size is not 1.
+*/
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+                                voidpc buf, unsigned len));
+/*
+     Writes the given number of uncompressed bytes into the compressed file.
+   gzwrite returns the number of uncompressed bytes written or 0 in case of
+   error.
+*/
+
+ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size,
+                                      z_size_t nitems, gzFile file));
+/*
+     gzfwrite() writes nitems items of size size from buf to file, duplicating
+   the interface of stdio's fwrite(), with size_t request and return types.  If
+   the library defines size_t, then z_size_t is identical to size_t.  If not,
+   then z_size_t is an unsigned integer type that can contain a pointer.
+
+     gzfwrite() returns the number of full items written of size size, or zero
+   if there was an error.  If the multiplication of size and nitems overflows,
+   i.e. the product does not fit in a z_size_t, then nothing is written, zero
+   is returned, and the error state is set to Z_STREAM_ERROR.
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
+/*
+     Converts, formats, and writes the arguments to the compressed file under
+   control of the format string, as in fprintf.  gzprintf returns the number of
+   uncompressed bytes actually written, or a negative zlib error code in case
+   of error.  The number of uncompressed bytes written is limited to 8191, or
+   one less than the buffer size given to gzbuffer().  The caller should assure
+   that this limit is not exceeded.  If it is exceeded, then gzprintf() will
+   return an error (0) with nothing written.  In this case, there may also be a
+   buffer overflow with unpredictable consequences, which is possible only if
+   zlib was compiled with the insecure functions sprintf() or vsprintf()
+   because the secure snprintf() or vsnprintf() functions were not available.
+   This can be determined using zlibCompileFlags().
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+     Writes the given null-terminated string to the compressed file, excluding
+   the terminating null character.
+
+     gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+     Reads bytes from the compressed file until len-1 characters are read, or a
+   newline character is read and transferred to buf, or an end-of-file
+   condition is encountered.  If any characters are read or if len == 1, the
+   string is terminated with a null character.  If no characters are read due
+   to an end-of-file or len < 1, then the buffer is left untouched.
+
+     gzgets returns buf which is a null-terminated string, or it returns NULL
+   for end-of-file or in case of error.  If there was an error, the contents at
+   buf are indeterminate.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+     Writes c, converted to an unsigned char, into the compressed file.  gzputc
+   returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+     Reads one byte from the compressed file.  gzgetc returns this byte or -1
+   in case of end of file or error.  This is implemented as a macro for speed.
+   As such, it does not do all of the checking the other functions do.  I.e.
+   it does not check to see if file is NULL, nor whether the structure file
+   points to has been clobbered or not.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+     Push one character back onto the stream to be read as the first character
+   on the next read.  At least one character of push-back is allowed.
+   gzungetc() returns the character pushed, or -1 on failure.  gzungetc() will
+   fail if c is -1, and may fail if a character has been pushed but not read
+   yet.  If gzungetc is used immediately after gzopen or gzdopen, at least the
+   output buffer size of pushed characters is allowed.  (See gzbuffer above.)
+   The pushed character will be discarded if the stream is repositioned with
+   gzseek() or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+     Flushes all pending output into the compressed file.  The parameter flush
+   is as in the deflate() function.  The return value is the zlib error number
+   (see function gzerror below).  gzflush is only permitted when writing.
+
+     If the flush parameter is Z_FINISH, the remaining data is written and the
+   gzip stream is completed in the output.  If gzwrite() is called again, a new
+   gzip stream will be started in the output.  gzread() is able to read such
+   concatenated gzip streams.
+
+     gzflush should be called only when strictly necessary because it will
+   degrade compression if called too often.
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+                                   z_off_t offset, int whence));
+
+     Sets the starting position for the next gzread or gzwrite on the given
+   compressed file.  The offset represents a number of bytes in the
+   uncompressed data stream.  The whence parameter is defined as in lseek(2);
+   the value SEEK_END is not supported.
+
+     If the file is opened for reading, this function is emulated but can be
+   extremely slow.  If the file is opened for writing, only forward seeks are
+   supported; gzseek then compresses a sequence of zeroes up to the new
+   starting position.
+
+     gzseek returns the resulting offset location as measured in bytes from
+   the beginning of the uncompressed stream, or -1 in case of error, in
+   particular if the file is opened for writing and the new starting position
+   would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
+/*
+     Rewinds the given file. This function is supported only for reading.
+
+     gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
+
+     Returns the starting position for the next gzread or gzwrite on the given
+   compressed file.  This position represents a number of bytes in the
+   uncompressed data stream, and is zero when starting, even if appending or
+   reading a gzip stream from the middle of a file using gzdopen().
+
+     gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
+
+     Returns the current offset in the file being read or written.  This offset
+   includes the count of bytes that precede the gzip stream, for example when
+   appending or when using gzdopen() for reading.  When reading, the offset
+   does not include as yet unused buffered input.  This information can be used
+   for a progress indicator.  On error, gzoffset() returns -1.
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+     Returns true (1) if the end-of-file indicator has been set while reading,
+   false (0) otherwise.  Note that the end-of-file indicator is set only if the
+   read tried to go past the end of the input, but came up short.  Therefore,
+   just like feof(), gzeof() may return false even if there is no more data to
+   read, in the event that the last read request was for the exact number of
+   bytes remaining in the input file.  This will happen if the input file size
+   is an exact multiple of the buffer size.
+
+     If gzeof() returns true, then the read functions will return no more data,
+   unless the end-of-file indicator is reset by gzclearerr() and the input file
+   has grown since the previous end of file was detected.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+     Returns true (1) if file is being copied directly while reading, or false
+   (0) if file is a gzip stream being decompressed.
+
+     If the input file is empty, gzdirect() will return true, since the input
+   does not contain a gzip stream.
+
+     If gzdirect() is used immediately after gzopen() or gzdopen() it will
+   cause buffers to be allocated to allow reading the file to determine if it
+   is a gzip file.  Therefore if gzbuffer() is used, it should be called before
+   gzdirect().
+
+     When writing, gzdirect() returns true (1) if transparent writing was
+   requested ("wT" for the gzopen() mode), or false (0) otherwise.  (Note:
+   gzdirect() is not needed when writing.  Transparent writing must be
+   explicitly requested, so the application already knows the answer.  When
+   linking statically, using gzdirect() will include all of the zlib code for
+   gzip file reading and decompression, which may not be desired.)
+*/
+
+ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
+/*
+     Flushes all pending output if necessary, closes the compressed file and
+   deallocates the (de)compression state.  Note that once file is closed, you
+   cannot call gzerror with file, since its structures have been deallocated.
+   gzclose must not be called more than once on the same file, just as free
+   must not be called more than once on the same allocation.
+
+     gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
+   file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
+   last read ended in the middle of a gzip stream, or Z_OK on success.
+*/
+
+ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
+ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
+/*
+     Same as gzclose(), but gzclose_r() is only for use when reading, and
+   gzclose_w() is only for use when writing or appending.  The advantage to
+   using these instead of gzclose() is that they avoid linking in zlib
+   compression or decompression code that is not used when only reading or only
+   writing respectively.  If gzclose() is used, then both compression and
+   decompression code will be included the application when linking to a static
+   zlib library.
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+     Returns the error message for the last error which occurred on the given
+   compressed file.  errnum is set to zlib error number.  If an error occurred
+   in the file system and not in the compression library, errnum is set to
+   Z_ERRNO and the application may consult errno to get the exact error code.
+
+     The application must not modify the returned string.  Future calls to
+   this function may invalidate the previously returned string.  If file is
+   closed, then the string previously returned by gzerror will no longer be
+   available.
+
+     gzerror() should be used to distinguish errors from end-of-file for those
+   functions above that do not distinguish those cases in their return values.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+     Clears the error and end-of-file flags for file.  This is analogous to the
+   clearerr() function in stdio.  This is useful for continuing to read a gzip
+   file that is being written concurrently.
+*/
+
+#endif /* !Z_SOLO */
+
+                        /* checksum functions */
+
+/*
+     These functions are not related to compression but are exported
+   anyway because they might be useful in applications using the compression
+   library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+   return the updated checksum.  If buf is Z_NULL, this function returns the
+   required initial value for the checksum.
+
+     An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed
+   much faster.
+
+   Usage example:
+
+     uLong adler = adler32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       adler = adler32(adler, buffer, length);
+     }
+     if (adler != original_adler) error();
+*/
+
+ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf,
+                                    z_size_t len));
+/*
+     Same as adler32(), but with a size_t length.
+*/
+
+/*
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+                                          z_off_t len2));
+
+     Combine two Adler-32 checksums into one.  For two sequences of bytes, seq1
+   and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+   each, adler1 and adler2.  adler32_combine() returns the Adler-32 checksum of
+   seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.  Note
+   that the z_off_t type (like off_t) is a signed integer.  If len2 is
+   negative, the result has no meaning or utility.
+*/
+
+ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
+/*
+     Update a running CRC-32 with the bytes buf[0..len-1] and return the
+   updated CRC-32.  If buf is Z_NULL, this function returns the required
+   initial value for the crc.  Pre- and post-conditioning (one's complement) is
+   performed within this function so it shouldn't be done by the application.
+
+   Usage example:
+
+     uLong crc = crc32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       crc = crc32(crc, buffer, length);
+     }
+     if (crc != original_crc) error();
+*/
+
+ZEXTERN uLong ZEXPORT crc32_z OF((uLong adler, const Bytef *buf,
+                                  z_size_t len));
+/*
+     Same as crc32(), but with a size_t length.
+*/
+
+/*
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+     Combine two CRC-32 check values into one.  For two sequences of bytes,
+   seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+   calculated for each, crc1 and crc2.  crc32_combine() returns the CRC-32
+   check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+   len2.
+*/
+
+
+                        /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
+                                      int windowBits, int memLevel,
+                                      int strategy, const char *version,
+                                      int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
+                                      const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+                                         unsigned char FAR *window,
+                                         const char *version,
+                                         int stream_size));
+#ifdef Z_PREFIX_SET
+#  define z_deflateInit(strm, level) \
+          deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
+#  define z_inflateInit(strm) \
+          inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
+#  define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+          deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+                        (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
+#  define z_inflateInit2(strm, windowBits) \
+          inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+                        (int)sizeof(z_stream))
+#  define z_inflateBackInit(strm, windowBits, window) \
+          inflateBackInit_((strm), (windowBits), (window), \
+                           ZLIB_VERSION, (int)sizeof(z_stream))
+#else
+#  define deflateInit(strm, level) \
+          deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
+#  define inflateInit(strm) \
+          inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
+#  define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+          deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+                        (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
+#  define inflateInit2(strm, windowBits) \
+          inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+                        (int)sizeof(z_stream))
+#  define inflateBackInit(strm, windowBits, window) \
+          inflateBackInit_((strm), (windowBits), (window), \
+                           ZLIB_VERSION, (int)sizeof(z_stream))
+#endif
+
+#ifndef Z_SOLO
+
+/* gzgetc() macro and its supporting function and exposed data structure.  Note
+ * that the real internal state is much larger than the exposed structure.
+ * This abbreviated structure exposes just enough for the gzgetc() macro.  The
+ * user should not mess with these exposed elements, since their names or
+ * behavior could change in the future, perhaps even capriciously.  They can
+ * only be used by the gzgetc() macro.  You have been warned.
+ */
+struct gzFile_s {
+    unsigned have;
+    unsigned char *next;
+    z_off64_t pos;
+};
+ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file));  /* backward compatibility */
+#ifdef Z_PREFIX_SET
+#  undef z_gzgetc
+#  define z_gzgetc(g) \
+          ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g))
+#else
+#  define gzgetc(g) \
+          ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g))
+#endif
+
+/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
+ * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
+ * both are true, the application gets the *64 functions, and the regular
+ * functions are changed to 64 bits) -- in case these are set on systems
+ * without large file support, _LFS64_LARGEFILE must also be true
+ */
+#ifdef Z_LARGE64
+   ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+   ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+   ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+   ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+   ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
+   ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
+#endif
+
+#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
+#  ifdef Z_PREFIX_SET
+#    define z_gzopen z_gzopen64
+#    define z_gzseek z_gzseek64
+#    define z_gztell z_gztell64
+#    define z_gzoffset z_gzoffset64
+#    define z_adler32_combine z_adler32_combine64
+#    define z_crc32_combine z_crc32_combine64
+#  else
+#    define gzopen gzopen64
+#    define gzseek gzseek64
+#    define gztell gztell64
+#    define gzoffset gzoffset64
+#    define adler32_combine adler32_combine64
+#    define crc32_combine crc32_combine64
+#  endif
+#  ifndef Z_LARGE64
+     ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+     ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
+     ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
+     ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
+     ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+     ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+#  endif
+#else
+   ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
+   ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
+   ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
+   ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
+   ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+   ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+#endif
+
+#else /* Z_SOLO */
+
+   ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+   ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+
+#endif /* !Z_SOLO */
+
+/* undocumented functions */
+ZEXTERN const char   * ZEXPORT zError           OF((int));
+ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp));
+ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table    OF((void));
+ZEXTERN int            ZEXPORT inflateUndermine OF((z_streamp, int));
+ZEXTERN int            ZEXPORT inflateValidate OF((z_streamp, int));
+ZEXTERN unsigned long  ZEXPORT inflateCodesUsed OF ((z_streamp));
+ZEXTERN int            ZEXPORT inflateResetKeep OF((z_streamp));
+ZEXTERN int            ZEXPORT deflateResetKeep OF((z_streamp));
+#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(Z_SOLO)
+ZEXTERN gzFile         ZEXPORT gzopen_w OF((const wchar_t *path,
+                                            const char *mode));
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifndef Z_SOLO
+ZEXTERN int            ZEXPORTVA gzvprintf Z_ARG((gzFile file,
+                                                  const char *format,
+                                                  va_list va));
+#  endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
Index: EcnlProtoTool/trunk/zlib-1.2.11/zlib.map
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/zlib.map	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/zlib.map	(revision 331)
@@ -0,0 +1,94 @@
+ZLIB_1.2.0 {
+  global:
+    compressBound;
+    deflateBound;
+    inflateBack;
+    inflateBackEnd;
+    inflateBackInit_;
+    inflateCopy;
+  local:
+    deflate_copyright;
+    inflate_copyright;
+    inflate_fast;
+    inflate_table;
+    zcalloc;
+    zcfree;
+    z_errmsg;
+    gz_error;
+    gz_intmax;
+    _*;
+};
+
+ZLIB_1.2.0.2 {
+    gzclearerr;
+    gzungetc;
+    zlibCompileFlags;
+} ZLIB_1.2.0;
+
+ZLIB_1.2.0.8 {
+    deflatePrime;
+} ZLIB_1.2.0.2;
+
+ZLIB_1.2.2 {
+    adler32_combine;
+    crc32_combine;
+    deflateSetHeader;
+    inflateGetHeader;
+} ZLIB_1.2.0.8;
+
+ZLIB_1.2.2.3 {
+    deflateTune;
+    gzdirect;
+} ZLIB_1.2.2;
+
+ZLIB_1.2.2.4 {
+    inflatePrime;
+} ZLIB_1.2.2.3;
+
+ZLIB_1.2.3.3 {
+    adler32_combine64;
+    crc32_combine64;
+    gzopen64;
+    gzseek64;
+    gztell64;
+    inflateUndermine;
+} ZLIB_1.2.2.4;
+
+ZLIB_1.2.3.4 {
+    inflateReset2;
+    inflateMark;
+} ZLIB_1.2.3.3;
+
+ZLIB_1.2.3.5 {
+    gzbuffer;
+    gzoffset;
+    gzoffset64;
+    gzclose_r;
+    gzclose_w;
+} ZLIB_1.2.3.4;
+
+ZLIB_1.2.5.1 {
+    deflatePending;
+} ZLIB_1.2.3.5;
+
+ZLIB_1.2.5.2 {
+    deflateResetKeep;
+    gzgetc_;
+    inflateResetKeep;
+} ZLIB_1.2.5.1;
+
+ZLIB_1.2.7.1 {
+    inflateGetDictionary;
+    gzvprintf;
+} ZLIB_1.2.5.2;
+
+ZLIB_1.2.9 {
+    inflateCodesUsed;
+    inflateValidate;
+    uncompress2;
+    gzfread;
+    gzfwrite;
+    deflateGetDictionary;
+    adler32_z;
+    crc32_z;
+} ZLIB_1.2.7.1;
Index: EcnlProtoTool/trunk/zlib-1.2.11/zlib.pc.cmakein
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/zlib.pc.cmakein	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/zlib.pc.cmakein	(revision 331)
@@ -0,0 +1,13 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=@CMAKE_INSTALL_PREFIX@
+libdir=@INSTALL_LIB_DIR@
+sharedlibdir=@INSTALL_LIB_DIR@
+includedir=@INSTALL_INC_DIR@
+
+Name: zlib
+Description: zlib compression library
+Version: @VERSION@
+
+Requires:
+Libs: -L${libdir} -L${sharedlibdir} -lz
+Cflags: -I${includedir}
Index: EcnlProtoTool/trunk/zlib-1.2.11/zlib.pc.in
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/zlib.pc.in	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/zlib.pc.in	(revision 331)
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+sharedlibdir=@sharedlibdir@
+includedir=@includedir@
+
+Name: zlib
+Description: zlib compression library
+Version: @VERSION@
+
+Requires:
+Libs: -L${libdir} -L${sharedlibdir} -lz
+Cflags: -I${includedir}
Index: EcnlProtoTool/trunk/zlib-1.2.11/zlib2ansi
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/zlib2ansi	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/zlib2ansi	(revision 331)
@@ -0,0 +1,152 @@
+#!/usr/bin/perl
+
+# Transform K&R C function definitions into ANSI equivalent.
+#
+# Author: Paul Marquess
+# Version: 1.0
+# Date: 3 October 2006
+
+# TODO
+#
+# Asumes no function pointer parameters. unless they are typedefed.
+# Assumes no literal strings that look like function definitions
+# Assumes functions start at the beginning of a line
+
+use strict;
+use warnings;
+
+local $/;
+$_ = <>;
+
+my $sp = qr{ \s* (?: /\* .*? \*/ )? \s* }x; # assume no nested comments
+
+my $d1    = qr{ $sp (?: [\w\*\s]+ $sp)* $sp \w+ $sp [\[\]\s]* $sp }x ;
+my $decl  = qr{ $sp (?: \w+ $sp )+ $d1 }xo ;
+my $dList = qr{ $sp $decl (?: $sp , $d1 )* $sp ; $sp }xo ;
+
+
+while (s/^
+            (                  # Start $1
+                (              #   Start $2
+                    .*?        #     Minimal eat content
+                    ( ^ \w [\w\s\*]+ )    #     $3 -- function name
+                    \s*        #     optional whitespace
+                )              # $2 - Matched up to before parameter list
+
+                \( \s*         # Literal "(" + optional whitespace
+                ( [^\)]+ )     # $4 - one or more anythings except ")"
+                \s* \)         # optional whitespace surrounding a Literal ")"
+
+                ( (?: $dList )+ ) # $5
+
+                $sp ^ {        # literal "{" at start of line
+            )                  # Remember to $1
+        //xsom
+      )
+{
+    my $all = $1 ;
+    my $prefix = $2;
+    my $param_list = $4 ;
+    my $params = $5;
+
+    StripComments($params);
+    StripComments($param_list);
+    $param_list =~ s/^\s+//;
+    $param_list =~ s/\s+$//;
+
+    my $i = 0 ;
+    my %pList = map { $_ => $i++ }
+                split /\s*,\s*/, $param_list;
+    my $pMatch = '(\b' . join('|', keys %pList) . '\b)\W*$' ;
+
+    my @params = split /\s*;\s*/, $params;
+    my @outParams = ();
+    foreach my $p (@params)
+    {
+        if ($p =~ /,/)
+        {
+            my @bits = split /\s*,\s*/, $p;
+            my $first = shift @bits;
+            $first =~ s/^\s*//;
+            push @outParams, $first;
+            $first =~ /^(\w+\s*)/;
+            my $type = $1 ;
+            push @outParams, map { $type . $_ } @bits;
+        }
+        else
+        {
+            $p =~ s/^\s+//;
+            push @outParams, $p;
+        }
+    }
+
+
+    my %tmp = map { /$pMatch/;  $_ => $pList{$1}  }
+              @outParams ;
+
+    @outParams = map  { "    $_" }
+                 sort { $tmp{$a} <=> $tmp{$b} }
+                 @outParams ;
+
+    print $prefix ;
+    print "(\n" . join(",\n", @outParams) . ")\n";
+    print "{" ;
+
+}
+
+# Output any trailing code.
+print ;
+exit 0;
+
+
+sub StripComments
+{
+
+  no warnings;
+
+  # Strip C & C++ coments
+  # From the perlfaq
+  $_[0] =~
+
+    s{
+       /\*         ##  Start of /* ... */ comment
+       [^*]*\*+    ##  Non-* followed by 1-or-more *'s
+       (
+         [^/*][^*]*\*+
+       )*          ##  0-or-more things which don't start with /
+                   ##    but do end with '*'
+       /           ##  End of /* ... */ comment
+
+     |         ##     OR  C++ Comment
+       //          ## Start of C++ comment //
+       [^\n]*      ## followed by 0-or-more non end of line characters
+
+     |         ##     OR  various things which aren't comments:
+
+       (
+         "           ##  Start of " ... " string
+         (
+           \\.           ##  Escaped char
+         |               ##    OR
+           [^"\\]        ##  Non "\
+         )*
+         "           ##  End of " ... " string
+
+       |         ##     OR
+
+         '           ##  Start of ' ... ' string
+         (
+           \\.           ##  Escaped char
+         |               ##    OR
+           [^'\\]        ##  Non '\
+         )*
+         '           ##  End of ' ... ' string
+
+       |         ##     OR
+
+         .           ##  Anything other char
+         [^/"'\\]*   ##  Chars which doesn't start a comment, string or escape
+       )
+     }{$2}gxs;
+
+}
Index: EcnlProtoTool/trunk/zlib-1.2.11/zutil.c
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/zutil.c	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/zutil.c	(revision 331)
@@ -0,0 +1,325 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2017 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+#ifndef Z_SOLO
+#  include "gzguts.h"
+#endif
+
+z_const char * const z_errmsg[10] = {
+    (z_const char *)"need dictionary",     /* Z_NEED_DICT       2  */
+    (z_const char *)"stream end",          /* Z_STREAM_END      1  */
+    (z_const char *)"",                    /* Z_OK              0  */
+    (z_const char *)"file error",          /* Z_ERRNO         (-1) */
+    (z_const char *)"stream error",        /* Z_STREAM_ERROR  (-2) */
+    (z_const char *)"data error",          /* Z_DATA_ERROR    (-3) */
+    (z_const char *)"insufficient memory", /* Z_MEM_ERROR     (-4) */
+    (z_const char *)"buffer error",        /* Z_BUF_ERROR     (-5) */
+    (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */
+    (z_const char *)""
+};
+
+
+const char * ZEXPORT zlibVersion()
+{
+    return ZLIB_VERSION;
+}
+
+uLong ZEXPORT zlibCompileFlags()
+{
+    uLong flags;
+
+    flags = 0;
+    switch ((int)(sizeof(uInt))) {
+    case 2:     break;
+    case 4:     flags += 1;     break;
+    case 8:     flags += 2;     break;
+    default:    flags += 3;
+    }
+    switch ((int)(sizeof(uLong))) {
+    case 2:     break;
+    case 4:     flags += 1 << 2;        break;
+    case 8:     flags += 2 << 2;        break;
+    default:    flags += 3 << 2;
+    }
+    switch ((int)(sizeof(voidpf))) {
+    case 2:     break;
+    case 4:     flags += 1 << 4;        break;
+    case 8:     flags += 2 << 4;        break;
+    default:    flags += 3 << 4;
+    }
+    switch ((int)(sizeof(z_off_t))) {
+    case 2:     break;
+    case 4:     flags += 1 << 6;        break;
+    case 8:     flags += 2 << 6;        break;
+    default:    flags += 3 << 6;
+    }
+#ifdef ZLIB_DEBUG
+    flags += 1 << 8;
+#endif
+#if defined(ASMV) || defined(ASMINF)
+    flags += 1 << 9;
+#endif
+#ifdef ZLIB_WINAPI
+    flags += 1 << 10;
+#endif
+#ifdef BUILDFIXED
+    flags += 1 << 12;
+#endif
+#ifdef DYNAMIC_CRC_TABLE
+    flags += 1 << 13;
+#endif
+#ifdef NO_GZCOMPRESS
+    flags += 1L << 16;
+#endif
+#ifdef NO_GZIP
+    flags += 1L << 17;
+#endif
+#ifdef PKZIP_BUG_WORKAROUND
+    flags += 1L << 20;
+#endif
+#ifdef FASTEST
+    flags += 1L << 21;
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifdef NO_vsnprintf
+    flags += 1L << 25;
+#    ifdef HAS_vsprintf_void
+    flags += 1L << 26;
+#    endif
+#  else
+#    ifdef HAS_vsnprintf_void
+    flags += 1L << 26;
+#    endif
+#  endif
+#else
+    flags += 1L << 24;
+#  ifdef NO_snprintf
+    flags += 1L << 25;
+#    ifdef HAS_sprintf_void
+    flags += 1L << 26;
+#    endif
+#  else
+#    ifdef HAS_snprintf_void
+    flags += 1L << 26;
+#    endif
+#  endif
+#endif
+    return flags;
+}
+
+#ifdef ZLIB_DEBUG
+#include <stdlib.h>
+#  ifndef verbose
+#    define verbose 0
+#  endif
+int ZLIB_INTERNAL z_verbose = verbose;
+
+void ZLIB_INTERNAL z_error (m)
+    char *m;
+{
+    fprintf(stderr, "%s\n", m);
+    exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+    int err;
+{
+    return ERR_MSG(err);
+}
+
+#if defined(_WIN32_WCE)
+    /* The Microsoft C Run-Time Library for Windows CE doesn't have
+     * errno.  We define it as a global variable to simplify porting.
+     * Its value is always 0 and should not be used.
+     */
+    int errno = 0;
+#endif
+
+#ifndef HAVE_MEMCPY
+
+void ZLIB_INTERNAL zmemcpy(dest, source, len)
+    Bytef* dest;
+    const Bytef* source;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = *source++; /* ??? to be unrolled */
+    } while (--len != 0);
+}
+
+int ZLIB_INTERNAL zmemcmp(s1, s2, len)
+    const Bytef* s1;
+    const Bytef* s2;
+    uInt  len;
+{
+    uInt j;
+
+    for (j = 0; j < len; j++) {
+        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+    }
+    return 0;
+}
+
+void ZLIB_INTERNAL zmemzero(dest, len)
+    Bytef* dest;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = 0;  /* ??? to be unrolled */
+    } while (--len != 0);
+}
+#endif
+
+#ifndef Z_SOLO
+
+#ifdef SYS16BIT
+
+#ifdef __TURBOC__
+/* Turbo C in 16-bit mode */
+
+#  define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+    voidpf org_ptr;
+    voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+    voidpf buf;
+    ulg bsize = (ulg)items*size;
+
+    (void)opaque;
+
+    /* If we allocate less than 65520 bytes, we assume that farmalloc
+     * will return a usable pointer which doesn't have to be normalized.
+     */
+    if (bsize < 65520L) {
+        buf = farmalloc(bsize);
+        if (*(ush*)&buf != 0) return buf;
+    } else {
+        buf = farmalloc(bsize + 16L);
+    }
+    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+    table[next_ptr].org_ptr = buf;
+
+    /* Normalize the pointer to seg:0 */
+    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+    *(ush*)&buf = 0;
+    table[next_ptr++].new_ptr = buf;
+    return buf;
+}
+
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
+{
+    int n;
+
+    (void)opaque;
+
+    if (*(ush*)&ptr != 0) { /* object < 64K */
+        farfree(ptr);
+        return;
+    }
+    /* Find the original pointer */
+    for (n = 0; n < next_ptr; n++) {
+        if (ptr != table[n].new_ptr) continue;
+
+        farfree(table[n].org_ptr);
+        while (++n < next_ptr) {
+            table[n-1] = table[n];
+        }
+        next_ptr--;
+        return;
+    }
+    Assert(0, "zcfree: ptr not found");
+}
+
+#endif /* __TURBOC__ */
+
+
+#ifdef M_I86
+/* Microsoft C in 16-bit mode */
+
+#  define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+#  define _halloc  halloc
+#  define _hfree   hfree
+#endif
+
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
+{
+    (void)opaque;
+    return _halloc((long)items, size);
+}
+
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
+{
+    (void)opaque;
+    _hfree(ptr);
+}
+
+#endif /* M_I86 */
+
+#endif /* SYS16BIT */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp  malloc OF((uInt size));
+extern voidp  calloc OF((uInt items, uInt size));
+extern void   free   OF((voidpf ptr));
+#endif
+
+voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
+    voidpf opaque;
+    unsigned items;
+    unsigned size;
+{
+    (void)opaque;
+    return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
+                              (voidpf)calloc(items, size);
+}
+
+void ZLIB_INTERNAL zcfree (opaque, ptr)
+    voidpf opaque;
+    voidpf ptr;
+{
+    (void)opaque;
+    free(ptr);
+}
+
+#endif /* MY_ZCALLOC */
+
+#endif /* !Z_SOLO */
Index: EcnlProtoTool/trunk/zlib-1.2.11/zutil.h
===================================================================
--- EcnlProtoTool/trunk/zlib-1.2.11/zutil.h	(revision 331)
+++ EcnlProtoTool/trunk/zlib-1.2.11/zutil.h	(revision 331)
@@ -0,0 +1,271 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZUTIL_H
+#define ZUTIL_H
+
+#ifdef HAVE_HIDDEN
+#  define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+#  define ZLIB_INTERNAL
+#endif
+
+#include "zlib.h"
+
+#if defined(STDC) && !defined(Z_SOLO)
+#  if !(defined(_WIN32_WCE) && defined(_MSC_VER))
+#    include <stddef.h>
+#  endif
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+
+#ifdef Z_SOLO
+   typedef long ptrdiff_t;  /* guess -- will be caught if guess is wrong */
+#endif
+
+#ifndef local
+#  define local static
+#endif
+/* since "static" is used to mean two completely different things in C, we
+   define "local" for the non-static meaning of "static", for readability
+   (compile with -Dlocal if your debugger can't find static symbols) */
+
+typedef unsigned char  uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long  ulg;
+
+extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+  return (strm->msg = ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+        /* common constants */
+
+#ifndef DEF_WBITS
+#  define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES    2
+/* The three kinds of block type */
+
+#define MIN_MATCH  3
+#define MAX_MATCH  258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+        /* target dependencies */
+
+#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
+#  define OS_CODE  0x00
+#  ifndef Z_SOLO
+#    if defined(__TURBOC__) || defined(__BORLANDC__)
+#      if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+         /* Allow compilation with ANSI keywords only enabled */
+         void _Cdecl farfree( void *block );
+         void *_Cdecl farmalloc( unsigned long nbytes );
+#      else
+#        include <alloc.h>
+#      endif
+#    else /* MSC or DJGPP */
+#      include <malloc.h>
+#    endif
+#  endif
+#endif
+
+#ifdef AMIGA
+#  define OS_CODE  1
+#endif
+
+#if defined(VAXC) || defined(VMS)
+#  define OS_CODE  2
+#  define F_OPEN(name, mode) \
+     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#ifdef __370__
+#  if __TARGET_LIB__ < 0x20000000
+#    define OS_CODE 4
+#  elif __TARGET_LIB__ < 0x40000000
+#    define OS_CODE 11
+#  else
+#    define OS_CODE 8
+#  endif
+#endif
+
+#if defined(ATARI) || defined(atarist)
+#  define OS_CODE  5
+#endif
+
+#ifdef OS2
+#  define OS_CODE  6
+#  if defined(M_I86) && !defined(Z_SOLO)
+#    include <malloc.h>
+#  endif
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+#  define OS_CODE  7
+#  ifndef Z_SOLO
+#    if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+#      include <unix.h> /* for fdopen */
+#    else
+#      ifndef fdopen
+#        define fdopen(fd,mode) NULL /* No fdopen() */
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __acorn
+#  define OS_CODE 13
+#endif
+
+#if defined(WIN32) && !defined(__CYGWIN__)
+#  define OS_CODE  10
+#endif
+
+#ifdef _BEOS_
+#  define OS_CODE  16
+#endif
+
+#ifdef __TOS_OS400__
+#  define OS_CODE 18
+#endif
+
+#ifdef __APPLE__
+#  define OS_CODE 19
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+#  define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
+#  if defined(_WIN32_WCE)
+#    define fdopen(fd,mode) NULL /* No fdopen() */
+#    ifndef _PTRDIFF_T_DEFINED
+       typedef int ptrdiff_t;
+#      define _PTRDIFF_T_DEFINED
+#    endif
+#  else
+#    define fdopen(fd,type)  _fdopen(fd,type)
+#  endif
+#endif
+
+#if defined(__BORLANDC__) && !defined(MSDOS)
+  #pragma warn -8004
+  #pragma warn -8008
+  #pragma warn -8066
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_WIN32) && \
+    (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
+    ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+    ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+#endif
+
+        /* common defaults */
+
+#ifndef OS_CODE
+#  define OS_CODE  3     /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+#  define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+         /* functions */
+
+#if defined(pyr) || defined(Z_SOLO)
+#  define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+  * You may have to use the same strategy for Borland C (untested).
+  * The __SC__ check is for Symantec.
+  */
+#  define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+#  define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+#    define zmemcpy _fmemcpy
+#    define zmemcmp _fmemcmp
+#    define zmemzero(dest, len) _fmemset(dest, 0, len)
+#  else
+#    define zmemcpy memcpy
+#    define zmemcmp memcmp
+#    define zmemzero(dest, len) memset(dest, 0, len)
+#  endif
+#else
+   void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+   int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+   void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef ZLIB_DEBUG
+#  include <stdio.h>
+   extern int ZLIB_INTERNAL z_verbose;
+   extern void ZLIB_INTERNAL z_error OF((char *m));
+#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+#  define Trace(x) {if (z_verbose>=0) fprintf x ;}
+#  define Tracev(x) {if (z_verbose>0) fprintf x ;}
+#  define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+#ifndef Z_SOLO
+   voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
+                                    unsigned size));
+   void ZLIB_INTERNAL zcfree  OF((voidpf opaque, voidpf ptr));
+#endif
+
+#define ZALLOC(strm, items, size) \
+           (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+/* Reverse the bytes in a 32-bit value */
+#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+                    (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
+#endif /* ZUTIL_H */
